[
  {
    "path": ".circleci/README.md",
    "content": "## CircleCI integration\n\n### Docker images\n\nThe docker images are built locally on the developer machine:\n\n```sh\ncd .circleci/docker/\n\ndocker build -t ethereum/solidity-buildpack-deps:ubuntu2404-<revision> -f Dockerfile.ubuntu2404 .\ndocker push ethereum/solidity-buildpack-deps:ubuntu2404-<revision>\n```\n\nThe current revisions per docker image are stored in [circle ci pipeline parameters](https://github.com/CircleCI-Public/api-preview-docs/blob/master/docs/pipeline-parameters.md#pipeline-parameters) called `<image-desc>-docker-image-rev` (e.g., `ubuntu-2404-docker-image-rev`). Please update the value assigned to the parameter(s) corresponding to the docker image(s) being updated at the time of the update. Please verify that the value assigned to the parameter matches the revision part of the docker image tag (`<revision>` in the docker build/push snippet shown above). Otherwise, the docker image used by circle ci and the one actually pushed to docker hub will differ.\n\nOnce the docker image has been built and pushed to Docker Hub, you can find it at:\n\n    https://hub.docker.com/r/ethereum/solidity-buildpack-deps:ubuntu2404-<revision>\n\nwhere the image tag reflects the target OS and revision to build Solidity and run its tests on.\n\n### Testing docker images locally\n\n```sh\ncd solidity\n# Mounts your local solidity directory in docker container for testing\ndocker run -v `pwd`:/src/solidity -ti ethereum/solidity-buildpack-deps:ubuntu2404-<revision> /bin/bash\ncd /src/solidity\n<commands_to_test_build_with_new_docker_image>\n```\n"
  },
  {
    "path": ".circleci/cln-asan.supp",
    "content": "leak:*libcln*\n"
  },
  {
    "path": ".circleci/compare_bytecode_reports.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n#------------------------------------------------------------------------------\n# Compares bytecode reports generated by prepare_report.py/.js.\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2023 solidity contributors.\n#------------------------------------------------------------------------------\n\nno_cli_platforms=(\n    emscripten\n)\nnative_platforms=(\n    ubuntu2004-static\n    ubuntu_arm\n    ubuntu\n    osx\n    osx_intel\n    windows\n)\ninterfaces=(\n    cli\n    standard-json\n)\n\nfor preset in \"$@\"; do\n    report_files=()\n    for platform in \"${no_cli_platforms[@]}\"; do\n        report_files+=(\"bytecode-report-${platform}-${preset}.txt\")\n    done\n    for platform in \"${native_platforms[@]}\"; do\n        for interface in \"${interfaces[@]}\"; do\n            report_files+=(\"bytecode-report-${platform}-${interface}-${preset}.txt\")\n        done\n    done\n\n    echo \"Reports to compare:\"\n    printf -- \"- %s\\n\" \"${report_files[@]}\"\n\n    if ! diff --brief --report-identical-files --from-file \"${report_files[@]}\"; then\n        diff --unified=0 --report-identical-files --from-file \"${report_files[@]}\" | head --lines 50\n        zip \"bytecode-reports-${preset}.zip\" \"${report_files[@]}\"\n        exit 1\n    fi\ndone\n"
  },
  {
    "path": ".circleci/config.yml",
    "content": "# vim:ts=2:sw=2:et\n# --------------------------------------------------------------------------\n#   Prefixes used in order to keep CircleCI workflow overview more readable:\n#     - b: build\n#     - t: test\n#     - ubu: ubuntu\n#     - ems: Emscripten\nversion: 2.1\nparameters:\n  ubuntu-2004-docker-image:\n    type: string\n    # ghcr.io/argotorg/solidity-buildpack-deps:ubuntu2004-26\n    default: \"ghcr.io/argotorg/solidity-buildpack-deps@sha256:1f387a77be889f65a2a25986a5c5eccc88cec23fabe6aeaf351790751145c81e\"\n  ubuntu-2404-docker-image:\n    type: string\n    # ghcr.io/argotorg/solidity-buildpack-deps:ubuntu2404-7\n    default: \"ghcr.io/argotorg/solidity-buildpack-deps@sha256:e52bd8fbb38908f203c6866e39562548faf26e5b7a5174f9860b44aae2b8f0cd\"\n  ubuntu-2404-arm-docker-image:\n    type: string\n    # ghcr.io/argotorg/solidity-buildpack-deps:ubuntu2404.arm-3\n    default: \"ghcr.io/argotorg/solidity-buildpack-deps@sha256:1e6dbf9a9173f2645449281a1e11918a95ca6dc04e59aa9d70824cffc44697ed\"\n  ubuntu-2404-clang-docker-image:\n    type: string\n    # ghcr.io/argotorg/solidity-buildpack-deps:ubuntu2404.clang-8\n    default: \"ghcr.io/argotorg/solidity-buildpack-deps@sha256:e283c8ec6a59c76565c89b856d8019af2fa5beb96f27d3064fc4dda42bf3524d\"\n  ubuntu-clang-ossfuzz-docker-image:\n    type: string\n    # ghcr.io/argotorg/solidity-buildpack-deps:ubuntu.clang.ossfuzz-13\n    default: \"ghcr.io/argotorg/solidity-buildpack-deps@sha256:2acb5d6f254ece25a96096f26960b5fe114eb86ceca92312cd20d59c096bf6e4\"\n  emscripten-docker-image:\n    type: string\n    # NOTE: Please remember to update the `scripts/build_emscripten.sh` whenever the hash of this image changes.\n    # ghcr.io/argotorg/solidity-buildpack-deps:emscripten-22\n    default: \"ghcr.io/argotorg/solidity-buildpack-deps@sha256:b9c953144d82cca5553f65626bc43b8af456dbc8966f8732ff9522f33ca8d722\"\n  evm-version:\n    type: string\n    default: osaka\n\norbs:\n  win: circleci/windows@2.2.0\n\ncommands:\n  matrix_notify_unless_pr:\n    description: \"Posts a notification to the solidity-dev room on Matrix (if not running on a PR).\"\n    parameters:\n      event:\n        type: enum\n        enum: [\"failure\", \"success\", \"release\"]\n      condition:\n        type: string\n    steps:\n      - run:\n          name: \"Matrix notification\"\n          when: << parameters.condition >>\n          command: scripts/ci/notification/matrix_notification.sh << parameters.event >>\n\n  matrix_notify_failure_unless_pr:\n    description: \"Posts a failure notification to the main room on Matrix (if not running on a PR).\"\n    steps:\n      - matrix_notify_unless_pr:\n          event: failure\n          condition: on_fail\n\n  matrix_notify_success_unless_pr:\n    description: \"Posts a success notification to the main room on Matrix (if not running on a PR).\"\n    steps:\n      - matrix_notify_unless_pr:\n          event: success\n          condition: on_success\n\n  matrix_notify_release_unless_pr:\n    description: \"Posts a release notification to the main room on Matrix (if not running on a PR).\"\n    steps:\n      - matrix_notify_unless_pr:\n          event: release\n          condition: on_success\n\n  restore_ccache_if_allowed:\n    description: \"Restore ccache unless on a tag or a skipped branch.\"\n    parameters:\n      skip_branches_regex:\n        description: \"Regex of branches that should skip restoring the cache.\"\n        type: string\n        default: \"^(develop|breaking)$\"\n    steps:\n      # Tags always skip ccache. Selected branches intentionally start from scratch.\n      - when:\n          condition:\n            and:\n              - equal: [\"\", << pipeline.git.tag >>]\n              - not:\n                  matches:\n                    pattern: \"<< parameters.skip_branches_regex >>\"\n                    value: << pipeline.git.branch >>\n          steps:\n            - restore_cache:\n                keys:\n                  # Reuse cache produced on develop (prefix match; restores the most recent).\n                  - v1-ccache-{{ .Environment.CIRCLE_JOB }}-develop-\n\n  save_ccache_if_develop:\n    description: \"Save a fresh ccache only on the develop branch.\"\n    steps:\n      # On `develop` we always generate a fresh cache by never restoring and by saving under a unique key.\n      - when:\n          condition:\n            equal: [\"develop\", << pipeline.git.branch >>]\n          steps:\n            - save_cache:\n                key: v1-ccache-{{ .Environment.CIRCLE_JOB }}-develop-{{ .Revision }}\n                paths:\n                  - ~/.ccache\n  run_with_ccache_unless_tag:\n    description: \"Run a command with ccache enabled unless building a tag.\"\n    parameters:\n      command:\n        type: string\n      step_name:\n        type: string\n    steps:\n      - when:\n          condition:\n            equal: [\"\", << pipeline.git.tag >>]\n          steps:\n            - run:\n                name: << parameters.step_name >> (ccache)\n                command: << parameters.command >>\n      - when:\n          condition:\n            not:\n              equal: [\"\", << pipeline.git.tag >>]\n          steps:\n            - run:\n                name: << parameters.step_name >> (no ccache)\n                command: CCACHE_DISABLE=1 << parameters.command >>\n\n  prepare_bytecode_report:\n    description: \"Generate bytecode report and upload it as an artifact.\"\n    parameters:\n      label:\n        type: string\n      binary_type:\n        type: enum\n        enum:\n          - solcjs\n          - native\n          - osx_intel\n      binary_path:\n        type: string\n      preset:\n        type: string\n    steps:\n      - run:\n          name: Generate bytecode reports for the selected preset\n          command: |\n            .circleci/parallel_bytecode_report.sh \\\n                \"<< parameters.label >>\" \\\n                \"<< parameters.binary_type >>\" \\\n                \"${PWD}/<< parameters.binary_path >>\" \\\n                \"<< parameters.preset >>\"\n      - store_artifacts:\n          path: bytecode-report-<< parameters.label >>-standard-json-<< parameters.preset >>.txt\n      - store_artifacts:\n          path: bytecode-report-<< parameters.label >>-cli-<< parameters.preset >>.txt\n      - store_artifacts:\n          path: bytecode-report-<< parameters.label >>-<< parameters.preset >>.txt\n      - persist_to_workspace:\n          root: .\n          paths:\n            - bytecode-report-<< parameters.label >>*.txt\n      - matrix_notify_failure_unless_pr\n\n  install_python3:\n    description: \"Install python3 and given packages.\"\n    parameters:\n      packages:\n        description: \"List of extra Python packages to be installed (separated by space).\"\n        type: string\n        default: \"\"\n    steps:\n      - run:\n          name: Install python and dependencies\n          command: |\n            sudo apt update\n            sudo apt install python3 python3-pip --assume-yes --no-install-recommends\n            if [[ \"<< parameters.packages >>\" != \"\" ]]\n            then\n              echo \"Installing additional packages...\"\n              python3 -m pip install --user --break-system-packages << parameters.packages >>\n            fi\n\n  install_foundry:\n    description: \"Install Foundry.\"\n    parameters:\n      version:\n        type: string\n        default: \"stable\"\n      install_path:\n        type: string\n        default: /home/circleci/bin\n    steps:\n      - run:\n          name: Setup Foundry environment variables\n          command: |\n            FOUNDRY_REPO=\"foundry-rs/foundry\"\n            FOUNDRY_VERSION=\"<< parameters.version >>\"\n            RELEASE_URL=\"https://github.com/${FOUNDRY_REPO}/releases/download/${FOUNDRY_VERSION}\"\n            echo \"export FOUNDRY_VERSION=${FOUNDRY_VERSION}\" >> \"$BASH_ENV\"\n            echo \"export RELEASE_URL=${RELEASE_URL}\" >> \"$BASH_ENV\"\n            ATTESTATION_URL=$(curl --silent --location --fail \"${RELEASE_URL}/foundry_${FOUNDRY_VERSION}_linux_amd64.attestation.txt\") || {\n              echo \"Failed to fetch attestation file\"\n              exit 1\n            }\n            ATTESTATION_JSON=$(curl --silent --location --fail --header \"Accept: application/json\" \"${ATTESTATION_URL}\") || {\n              echo \"Failed to fetch attestation JSON\"\n              exit 1\n            }\n            RELEASE_SHA=$(echo \"${ATTESTATION_JSON}\" | jq --raw-output '.payload.attestation.sourceRepositoryDigest')\n            if [[ -z \"$RELEASE_SHA\" || \"$RELEASE_SHA\" == \"null\" ]]; then\n              echo \"Failed to extract release SHA from attestation\"\n              exit 1\n            fi\n            echo \"${RELEASE_SHA}\" > /tmp/workspace/foundry-release-sha\n            # Extract forge checksum from the attestation\n            EXPECTED_FORGE_CHECKSUM=$(echo \"${ATTESTATION_JSON}\" | jq --raw-output '.payload.attestation.subjects[] | select(.subjectName==\"forge\") | .subjectDigest' | sed 's/sha256://')\n            if [[ -z \"$EXPECTED_FORGE_CHECKSUM\" || \"$EXPECTED_FORGE_CHECKSUM\" == \"null\" ]]; then\n              echo \"Failed to extract forge checksum from attestation\"\n              exit 1\n            fi\n            echo \"export EXPECTED_FORGE_CHECKSUM=${EXPECTED_FORGE_CHECKSUM}\" >> \"$BASH_ENV\"\n      - restore_cache:\n          keys:\n            - foundry-v1-<< parameters.version >>-{{ arch }}-{{ checksum \"/tmp/workspace/foundry-release-sha\" }}\n      # WARNING! If you edit anything between here and save_cache, remember to invalidate the cache manually.\n      - run:\n          name: Install foundry\n          command: |\n            if forge --version 2> /dev/null; then\n              echo \"Foundry already cached, skipping install\"\n            else\n              curl --fail --location --output /tmp/foundry.tar.gz \"${RELEASE_URL}/foundry_${FOUNDRY_VERSION}_linux_amd64.tar.gz\"\n              cd \"<< parameters.install_path >>\"\n              tar --extract --gzip --file /tmp/foundry.tar.gz --one-top-level\n              # TODO: Use `gh attestation verify foundry/forge --owner foundry-rs` for signature verification.\n              # Current approach only verifies checksum without validating the signature.\n              # https://docs.github.com/en/actions/how-tos/secure-your-work/use-artifact-attestations/use-artifact-attestations#verifying-an-artifact-attestation-for-binaries\n              ACTUAL=$(sha256sum foundry/forge | cut --delimiter=' ' --fields=1)\n              if [[ \"$EXPECTED_FORGE_CHECKSUM\" != \"$ACTUAL\" ]]; then\n                echo \"Checksum mismatch: expected $EXPECTED_FORGE_CHECKSUM, got $ACTUAL\"\n                exit 1\n              fi\n              ln --symbolic --force foundry/{forge,anvil,cast,chisel} .\n            fi\n      - save_cache:\n          key: foundry-v1-<< parameters.version >>-{{ arch }}-{{ checksum \"/tmp/workspace/foundry-release-sha\" }}\n          paths:\n            - << parameters.install_path >>\n\n  # --------------------------------------------------------------------------\n  # Build Commands\n\n  setup_prerelease:\n    steps:\n      - run:\n          name: Store prerelease suffix\n          command: |\n            \"scripts/prerelease_suffix.sh\" nightly \"$CIRCLE_TAG\" > prerelease.txt\n\n  install_and_check_minimum_requirements:\n    parameters:\n      compiler:\n        description: \"Compiler to check: gcc or clang\"\n        type: enum\n        enum:\n          - gcc\n          - clang\n    steps:\n      - run:\n          name: Install and check minimum requirements\n          command: scripts/ci/install_and_check_minimum_requirements.sh \"--<< parameters.compiler >>\"\n\n  run_build:\n    steps:\n      - restore_ccache_if_allowed\n      # WARNING! If you edit anything between here and save_cache, remember to invalidate the cache manually by bumping the version\n      - run_with_ccache_unless_tag:\n          step_name: Build\n          command: scripts/ci/build.sh\n      - save_ccache_if_develop\n\n  run_build_ossfuzz:\n    steps:\n      - restore_ccache_if_allowed\n      # WARNING! If you edit anything between here and save_cache, remember to invalidate the cache manually by bumping the version\n      - run_with_ccache_unless_tag:\n          step_name: Build_ossfuzz\n          command: scripts/ci/build_ossfuzz.sh\n      - save_ccache_if_develop\n\n  run_proofs:\n    steps:\n      - run:\n          name: Correctness proofs for optimization rules\n          command: scripts/run_proofs.sh\n\n  run_soltest:\n    steps:\n      - run:\n          name: soltest\n          no_output_timeout: 30m\n          command: .circleci/soltest.sh\n\n  run_soltest_all:\n    parameters:\n      # NOTE: If not specified, soltest_all.sh will use the default values as specified in the script.\n      # In other words, it will execute for all EVM versions that are not marked as low priority.\n      evm_versions:\n        description: \"List of EVM versions (separated by space).\"\n        type: string\n        default: \"\"\n    steps:\n      - run:\n          name: soltest_all\n          no_output_timeout: 30m\n          command: .circleci/soltest_all.sh \"<< parameters.evm_versions >>\"\n\n  run_cmdline_tests:\n    steps:\n      - run:\n          name: command line tests\n          no_output_timeout: 30m\n          command: .circleci/parallel_cli_tests.py\n\n  run_docs_pragma_min_version:\n    steps:\n      - run:\n         name: docs pragma version check\n         command: scripts/docs_version_pragma_check.sh\n\n  # --------------------------------------------------------------------------\n  # Artifact Commands\n\n  store_artifacts_solc:\n    description: Store compiled solc executable as artifact\n    steps:\n      - store_artifacts:\n          path: build/solc/solc\n          destination: solc\n\n  store_artifacts_yul_phaser:\n    steps:\n      - store_artifacts:\n          path: build/tools/yul-phaser\n          destination: yul-phaser\n\n  persist_executables_to_workspace:\n    description: Persist compiled target executables to workspace\n    steps:\n      - persist_to_workspace:\n          root: build\n          paths:\n            - solc/solc\n            - test/soltest\n            - test/tools/solfuzzer\n\n  persist_executables_to_workspace_arm:\n    description: Persist compiled target executables to workspace on Linux arm64\n    steps:\n      - persist_to_workspace:\n          root: build\n          paths:\n            - solc/solc-static-linux-arm\n            - test/soltest-linux-arm\n            - test/tools/solfuzzer-linux-arm\n\n  persist_executables_to_workspace_osx:\n    description: Persist compiled target executables to workspace on macOS\n    steps:\n      - persist_to_workspace:\n          root: .\n          paths:\n            - build/solc/solc\n            - build/test/soltest\n            - build/test/tools/solfuzzer\n\n  persist_ossfuzz_executables_to_workspace:\n    description: Persist compiled OSSFUZZ executables to workspace\n    steps:\n      - persist_to_workspace:\n          root: build\n          paths:\n            - test/tools/ossfuzz/abiv2_proto_ossfuzz\n            - test/tools/ossfuzz/abiv2_isabelle_ossfuzz\n            - test/tools/ossfuzz/const_opt_ossfuzz\n            - test/tools/ossfuzz/solc_mutator_ossfuzz\n            - test/tools/ossfuzz/solc_ossfuzz\n            - test/tools/ossfuzz/stack_reuse_codegen_ossfuzz\n            - test/tools/ossfuzz/strictasm_assembly_ossfuzz\n            - test/tools/ossfuzz/strictasm_diff_ossfuzz\n            - test/tools/ossfuzz/strictasm_opt_ossfuzz\n            - test/tools/ossfuzz/yul_proto_diff_ossfuzz\n            - test/tools/ossfuzz/yul_proto_diff_custom_mutate_ossfuzz\n            - test/tools/ossfuzz/yul_proto_ossfuzz\n            - test/tools/ossfuzz/sol_proto_ossfuzz\n\n  store_artifacts_test_results:\n    description: Store test output dir as artifact\n    steps:\n      - store_artifacts:\n          path: test_results/\n          destination: test_results/\n\n  # --------------------------------------------------------------------------\n  # Complex Build Commands\n\n  soltest:\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      # NOTE: Different build jobs produce different soltest executables (release/debug,\n      # clang/gcc, windows/linux/macos, etc.). The executable used by these steps comes from the\n      # attached workspace and we only see the items added to the workspace by jobs we depend on.\n      - run_soltest\n      - store_test_results:\n          path: test_results/\n      - store_artifacts_test_results\n      - matrix_notify_failure_unless_pr\n\n  test_lsp:\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - run:\n          name: Executing solc LSP test suite\n          command: test/lsp.py build/solc/solc --non-interactive\n      - matrix_notify_failure_unless_pr\n\n  build:\n    steps:\n      - checkout\n      - run_build\n      - store_artifacts_solc\n      - store_artifacts_yul_phaser\n      - persist_executables_to_workspace\n      - matrix_notify_failure_unless_pr\n\n  soltest_all:\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - run_soltest_all\n      - store_test_results:\n          path: test_results/\n      - store_artifacts_test_results\n      - matrix_notify_failure_unless_pr\n\n  cmdline_tests:\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - run_cmdline_tests\n      - store_test_results:\n          path: test_results/\n      - store_artifacts_test_results\n      - matrix_notify_failure_unless_pr\n\n  install_dependencies_osx:\n    # An extra cache key is used to only save the flag that communicates whether the cache exists.\n    # if this flag was set (the cache exist) we remove all files located in /usr/local & /opt/homebrew.\n    # With this simple trick restoring the cache is much faster. Otherwise CircleCI is generating\n    # warning messages if a file from the cache is overwriting an already existing file on disk.\n    # Restoring the cache is much faster if we remove all potentially conflicting files beforehand.\n    steps:\n      - restore_cache:\n          keys:\n            - macos-dependencies-cached-{{ arch }}-{{ checksum \".circleci/osx_install_dependencies.sh\" }}\n      - run:\n          name: Installing dependencies / Restoring dependency cache\n          command: |\n            if [[ -f ~/macos-dependencies-cached ]]; then\n              echo \"Dependency flag exists. Removing /usr/local/, /opt/homebrew/, and /opt/boost. These directories will be restored from cache.\"\n\n              # CircleCI is providing the circleci cli tools via some kind of symlink magic.\n              # So we just save the original symlinks and restore them later.\n              circleci_binary_path=$(command -v circleci)\n              circleci_agent_binary_path=$(command -v circleci-agent)\n              cp \"${circleci_binary_path}\" /tmp/circleci\n              cp \"${circleci_agent_binary_path}\" /tmp/circleci-agent\n\n              # Homebrew is installed in /usr/local on intel macs, but in /opt/homebrew on apple silicon.\n              if [[ -d /opt/homebrew ]]; then\n                sudo rm -rf /opt/homebrew\n                sudo mkdir -p /opt/homebrew/bin\n                sudo chmod 777 /opt/{homebrew,homebrew/bin}\n              fi\n              # under macos /usr/local itself is read-only, so we just remove its sub-directories.\n              sudo rm -rf /usr/local/*\n              sudo mkdir -p /usr/local/bin\n              sudo chmod 777 /usr/{local,local/bin}\n\n              sudo rm -rf /opt/boost\n              sudo mkdir -p /opt/boost\n              sudo chmod 777 /opt/boost\n\n              mv /tmp/circleci \"${circleci_binary_path}\"\n              mv /tmp/circleci-agent \"${circleci_agent_binary_path}\"\n            fi\n      - restore_cache:\n          keys:\n            - macos-dependencies-{{ arch }}-{{ checksum \".circleci/osx_install_dependencies.sh\" }}\n      # DO NOT EDIT between here and save_cache, but rather edit ./circleci/osx_install_dependencies.sh\n      # WARNING! If you do edit anything here instead, remember to invalidate the cache manually.\n      - run:\n          name: Install build dependencies\n          command: .circleci/osx_install_dependencies.sh\n      - run:\n          name: Mark dependencies as cached\n          command: touch ~/macos-dependencies-cached\n      - save_cache:\n          key: macos-dependencies-{{ arch }}-{{ checksum \".circleci/osx_install_dependencies.sh\" }}\n          paths:\n            # Homebrew is installed in /usr/local on intel macs, but in /opt/homebrew on apple silicon.\n            - /usr/local\n            - /opt/homebrew\n            - /opt/boost\n      - save_cache:\n          key: macos-dependencies-cached-{{ arch }}-{{ checksum \".circleci/osx_install_dependencies.sh\" }}\n          paths:\n            - ~/macos-dependencies-cached\n\ndefaults:\n\n  # --------------------------------------------------------------------------\n  # Matrix templates\n\n  - bytecode_compare_env_presets: &bytecode_compare_env_presets\n      PRESETS:\n        legacy-optimize\n        legacy-no-optimize\n        via-ir-optimize\n        via-ir-no-optimize\n\n  - bytecode_compare_preset_matrix: &bytecode_compare_preset_matrix\n      parameters:\n        preset:\n          # NOTE: Keep in sync with preset list in bytecode_compare_env_presets\n          - legacy-optimize\n          - legacy-no-optimize\n          - via-ir-optimize\n          - via-ir-no-optimize\n\n  # --------------------------------------------------------------------------\n  # --------------------------------------------------------------------------\n  # Base Image Templates\n\n  - base_archlinux: &base_archlinux\n      docker:\n        - image: archlinux:base\n      environment: &base_archlinux_env\n        TERM: xterm\n        MAKEFLAGS: -j 3\n        CPUs: 3\n\n  - base_archlinux_large: &base_archlinux_large\n      <<: *base_archlinux\n      resource_class: large\n      environment: &base_archlinux_large_env\n        <<: *base_archlinux_env\n        MAKEFLAGS: -j 5\n        CPUs: 5\n\n  - base_cimg_small: &base_cimg_small\n      docker:\n        - image: cimg/base:current\n      resource_class: small\n      environment: &base_cimg_small_env\n        TERM: xterm\n        MAKEFLAGS: -j 2\n        CPUs: 2\n\n  - base_ems_large: &base_ems_large\n      docker:\n        - image: << pipeline.parameters.emscripten-docker-image >>\n      resource_class: large\n      environment: &base_ems_large_env\n        TERM: xterm\n        MAKEFLAGS: -j 5\n        CPUs: 5\n\n  - base_node_small: &base_node_small\n      docker:\n        - image: cimg/node:current\n      resource_class: small\n      environment: &base_node_small_env\n        TERM: xterm\n        MAKEFLAGS: -j 2\n        CPUs: 2\n\n  - base_osx: &base_osx\n      macos:\n        xcode: 15.4.0\n      resource_class: m4pro.medium\n      environment: &base_osx_env\n        TERM: xterm\n        MAKEFLAGS: -j8\n        CPUs: 8\n\n  - base_ubuntu_clang: &base_ubuntu_clang\n      docker:\n        - image: << pipeline.parameters.ubuntu-clang-ossfuzz-docker-image >>\n      environment: &base_ubuntu_clang_env\n        TERM: xterm\n        MAKEFLAGS: -j 3\n        CPUs: 3\n\n  - base_ubuntu_clang_small: &base_ubuntu_clang_small\n      <<: *base_ubuntu_clang\n      resource_class: small\n      environment: &base_ubuntu_clang_small_env\n        <<: *base_ubuntu_clang_env\n        MAKEFLAGS: -j 2\n        CPUs: 2\n\n  - base_ubuntu_clang_large: &base_ubuntu_clang_large\n      <<: *base_ubuntu_clang\n      resource_class: large\n      environment: &base_ubuntu_clang_small_env\n        <<: *base_ubuntu_clang_env\n        MAKEFLAGS: -j 5\n        CPUs: 5\n\n  - base_ubuntu2004: &base_ubuntu2004\n      docker:\n        - image: << pipeline.parameters.ubuntu-2004-docker-image >>\n      environment: &base_ubuntu2004_env\n        TERM: xterm\n        MAKEFLAGS: -j 3\n        CPUs: 3\n\n  - base_ubuntu2004_small: &base_ubuntu2004_small\n      <<: *base_ubuntu2004\n      resource_class: small\n      environment: &base_ubuntu2004_small_env\n        <<: *base_ubuntu2004_env\n        MAKEFLAGS: -j 2\n        CPUs: 2\n\n  - base_ubuntu2004_xlarge: &base_ubuntu2004_xlarge\n      <<: *base_ubuntu2004\n      resource_class: xlarge\n      environment: &base_ubuntu2004_xlarge_env\n        <<: *base_ubuntu2004_env\n        MAKEFLAGS: -j 10\n        CPUs: 10\n\n  - base_ubuntu2404: &base_ubuntu2404\n      docker:\n        - image: << pipeline.parameters.ubuntu-2404-docker-image >>\n      environment: &base_ubuntu2404_env\n        TERM: xterm\n        MAKEFLAGS: -j 3\n        CPUs: 3\n\n  - base_ubuntu2404_clang: &base_ubuntu2404_clang\n      docker:\n        - image: << pipeline.parameters.ubuntu-2404-clang-docker-image >>\n      environment: &base_ubuntu2404_clang_env\n        TERM: xterm\n        CC: clang\n        CXX: clang++\n        MAKEFLAGS: -j 3\n        CPUs: 3\n\n  - base_ubuntu2404_clang_large: &base_ubuntu2404_clang_large\n      <<: *base_ubuntu2404_clang\n      resource_class: large\n      environment: &base_ubuntu2404_clang_large_env\n        <<: *base_ubuntu2404_clang_env\n        MAKEFLAGS: -j 5\n        CPUs: 5\n\n  - base_ubuntu2404_small: &base_ubuntu2404_small\n      <<: *base_ubuntu2404\n      resource_class: small\n      environment: &base_ubuntu2404_small_env\n        <<: *base_ubuntu2404_env\n        MAKEFLAGS: -j 2\n        CPUs: 2\n\n  - base_ubuntu2404_large: &base_ubuntu2404_large\n      <<: *base_ubuntu2404\n      resource_class: large\n      environment: &base_ubuntu2404_large_env\n        <<: *base_ubuntu2404_env\n        MAKEFLAGS: -j 5\n        CPUs: 5\n\n  - base_ubuntu2404_arm_medium: &base_ubuntu2404_arm_medium\n      docker:\n        - image: << pipeline.parameters.ubuntu-2404-arm-docker-image >>\n      resource_class: arm.medium\n      environment: &base_ubuntu2404_arm_medium_env\n        TERM: xterm\n        MAKEFLAGS: -j 2\n        CPUs: 2\n\n  - base_ubuntu2404_arm_large: &base_ubuntu2404_arm_large\n      docker:\n        - image: << pipeline.parameters.ubuntu-2404-arm-docker-image >>\n      resource_class: arm.large\n      environment: &base_ubuntu2404_arm_large_env\n        TERM: xterm\n        MAKEFLAGS: -j 7\n        CPUs: 7\n\n  - base_ubuntu2404_xlarge: &base_ubuntu2404_xlarge\n      <<: *base_ubuntu2404\n      resource_class: xlarge\n      environment: &base_ubuntu2404_xlarge_env\n        <<: *base_ubuntu2404_env\n        MAKEFLAGS: -j 10\n        CPUs: 10\n\n  - base_win: &base_win\n      executor:\n        name: win/default\n        shell: bash.exe\n\n  - base_win_large: &base_win_large\n      executor:\n        name: win/default\n        size: large\n        shell: bash.exe\n\n  # --------------------------------------------------------------------------\n  # Workflow Templates\n\n  - on_all_tags_and_branches: &on_all_tags_and_branches\n      filters:\n        tags:\n          only: /.*/\n\n  - on_version_tags: &on_version_tags\n      filters:\n        tags:\n          only: /^v.*/\n        branches:\n          ignore: /.*/\n\n  - on_develop: &on_develop\n      filters:\n        branches:\n          only:\n            - develop\n\n  - requires_nothing: &requires_nothing\n      <<: *on_all_tags_and_branches\n\n  - requires_b_ubu: &requires_b_ubu\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_ubu\n\n  - requires_b_ubu_clang: &requires_b_ubu_clang\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_ubu_clang\n\n  - requires_b_ubu_force_release: &requires_b_ubu_force_release\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_ubu_force_release\n\n  - requires_b_ubu_static: &requires_b_ubu_static\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_ubu_static\n\n  - requires_b_ubu_static_arm: &requires_b_ubu_static_arm\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_ubu_static_arm\n\n  - requires_b_archlinux: &requires_b_archlinux\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_archlinux\n\n  - requires_b_osx: &requires_b_osx\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_osx\n\n  - requires_b_ubu_asan: &requires_b_ubu_asan\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_ubu_asan\n\n  - requires_b_ubu_asan_clang: &requires_b_ubu_asan_clang\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_ubu_asan_clang\n\n  - requires_b_ubu_ubsan_clang: &requires_b_ubu_ubsan_clang\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_ubu_ubsan_clang\n\n  - requires_b_ems: &requires_b_ems\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_ems\n\n  - requires_b_ubu_ossfuzz: &requires_b_ubu_ossfuzz\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_ubu_ossfuzz\n\n  - requires_b_win: &requires_b_win\n      <<: *on_all_tags_and_branches\n      requires:\n        - b_win\n\n  # --------------------------------------------------------------------------\n  # Parameterized Job Templates\n\n  # Separate compile-only runs of those external tests where a full run takes much longer.\n  # Also see https://github.com/argotorg/solidity/pull/14234 for why we excluded those\n  # external tests from the nightly jobs.\n  - job_ems_compile_ext_colony: &job_ems_compile_ext_colony\n      <<: *requires_b_ems\n      name: t_ems_compile_ext_colony\n      project: colony\n      binary_type: solcjs\n      compile_only: 1\n      image: cimg/node:14.20\n      python2: true\n\n  - job_native_compile_ext_gnosis: &job_native_compile_ext_gnosis\n      <<: *requires_b_ubu_static\n      name: t_native_compile_ext_gnosis\n      project: gnosis\n      binary_type: native\n      # NOTE: We are disabling the gnosis test suite due to version discrepancies that are difficult to fix.\n      #        Check again after (and if) https://github.com/safe-global/safe-contracts/pull/644 is merged.\n      compile_only: 1\n      image: cimg/node:18.16\n\n  - job_native_test_ext_zeppelin: &job_native_test_ext_zeppelin\n      <<: *requires_b_ubu_static\n      name: t_native_test_ext_zeppelin\n      project: zeppelin\n      binary_type: native\n      image: cimg/node:lts\n      resource_class: large\n\n  - job_native_test_ext_ens: &job_native_test_ext_ens\n      <<: *requires_b_ubu_static\n      name: t_native_test_ext_ens\n      project: ens\n      binary_type: native\n      image: cimg/node:lts\n\n  - job_native_compile_ext_trident: &job_native_compile_ext_trident\n      <<: *requires_b_ubu_static\n      name: t_native_compile_ext_trident\n      project: trident\n      binary_type: native\n      # NOTE: test suite disabled due to dependence on a specific version of Hardhat\n      # which does not support shanghai EVM.\n      compile_only: 1\n      image: cimg/node:18.16\n\n  - job_native_compile_ext_euler: &job_native_compile_ext_euler\n      <<: *requires_b_ubu_static\n      name: t_native_compile_ext_euler\n      project: euler\n      binary_type: native\n      resource_class: medium\n\n  - job_native_test_ext_yield_liquidator: &job_native_test_ext_yield_liquidator\n      <<: *requires_b_ubu_static\n      name: t_native_test_ext_yield_liquidator\n      project: yield-liquidator\n      binary_type: native\n      image: cimg/node:18.16\n\n  - job_native_compile_ext_bleeps: &job_native_compile_ext_bleeps\n      <<: *requires_b_ubu_static\n      name: t_native_compile_ext_bleeps\n      project: bleeps\n      binary_type: native\n      # NOTE: test suite disabled due to dependence on a specific version of Hardhat\n      # which does not support shanghai EVM.\n      compile_only: 1\n      resource_class: medium\n\n  - job_native_compile_ext_pool_together: &job_native_compile_ext_pool_together\n      <<: *requires_b_ubu_static\n      name: t_native_compile_ext_pool_together\n      project: pool-together\n      binary_type: native\n      # NOTE: test suite disabled due to dependence on a specific version of Hardhat\n      # which does not support shanghai EVM.\n      compile_only: 1\n      image: cimg/node:lts\n\n  - job_native_test_ext_uniswap: &job_native_test_ext_uniswap\n      <<: *requires_b_ubu_static\n      name: t_native_test_ext_uniswap\n      project: uniswap\n      binary_type: native\n      image: cimg/node:lts\n      resource_class: large # Tests run out of memory on a smaller machine\n\n  - job_native_test_ext_prb_math: &job_native_test_ext_prb_math\n      <<: *requires_b_ubu_static\n      name: t_native_test_ext_prb_math\n      project: prb-math\n      binary_type: native\n      image: cimg/rust:1.74.0-node\n      resource_class: large # Tests run out of memory on a smaller machine\n\n  - job_native_test_ext_elementfi: &job_native_test_ext_elementfi\n      <<: *requires_b_ubu_static\n      name: t_native_test_ext_elementfi\n      project: elementfi\n      binary_type: native\n      image: cimg/node:lts\n      resource_class: medium\n\n  - job_native_test_ext_brink: &job_native_test_ext_brink\n      <<: *requires_b_ubu_static\n      name: t_native_test_ext_brink\n      project: brink\n      binary_type: native\n      image: cimg/node:lts\n\n  - job_native_compile_ext_chainlink: &job_native_compile_ext_chainlink\n      <<: *requires_b_ubu_static\n      name: t_native_compile_ext_chainlink\n      project: chainlink\n      binary_type: native\n      # NOTE: test suite disabled due to dependence on a specific version of Hardhat\n      # which does not support shanghai EVM.\n      compile_only: 1\n      image: cimg/node:16.20\n      resource_class: large # Tests run out of memory on a smaller machine\n\n  - job_native_compile_ext_gp2: &job_native_compile_ext_gp2\n      <<: *requires_b_ubu_static\n      name: t_native_compile_ext_gp2\n      project: gp2\n      binary_type: native\n      # NOTE: test suite disabled due to constant failures.\n      compile_only: 1\n      image: cimg/node:lts\n\n  - job_b_ubu_asan_clang: &job_b_ubu_asan_clang\n      <<: *on_all_tags_and_branches\n      name: b_ubu_asan_clang\n      cmake_options: -DSANITIZE=address\n\n  - job_b_ubu_ubsan_clang: &job_b_ubu_ubsan_clang\n      <<: *on_all_tags_and_branches\n      name: b_ubu_ubsan_clang\n      cmake_options: -DSANITIZE=undefined\n\n# -----------------------------------------------------------------------------------------------\njobs:\n\n  chk_spelling:\n    <<: *base_ubuntu2404_small\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - run:\n          name: Install dependencies\n          command: |\n            pip install --user codespell\n      - run:\n          name: Check spelling\n          command: ~/.local/bin/codespell\n      - matrix_notify_failure_unless_pr\n\n  chk_docs_examples:\n    <<: *base_node_small\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - run:\n          name: JS deps\n          command: sudo npm install -g solhint\n      - run:\n          name: Test Docs examples\n          command: test/docsCodeStyle.sh\n      - matrix_notify_failure_unless_pr\n\n  chk_coding_style:\n    <<: *base_cimg_small\n    steps:\n      - checkout\n      - run:\n          name: Install shellcheck\n          command: |\n            sudo apt -q update\n            sudo apt install -y shellcheck\n      - run:\n          name: Check for C++ coding style\n          command: scripts/check_style.sh\n      - run:\n          name: checking shell scripts\n          command: scripts/chk_shellscripts/chk_shellscripts.sh\n      - run:\n          name: Check for broken symlinks\n          command: scripts/check_symlinks.sh\n      - matrix_notify_failure_unless_pr\n\n  chk_errorcodes:\n    <<: *base_ubuntu2404_small\n    steps:\n      - checkout\n      - run:\n          name: Check for error codes\n          command: scripts/error_codes.py --check\n      - matrix_notify_failure_unless_pr\n\n  chk_pylint:\n    <<: *base_ubuntu2404_small\n    steps:\n      - install_python3:\n          packages: pyyaml jsonschema pytest\n      - checkout\n      - run: pylint --version\n      - run:\n          name: Linting Python Scripts\n          command: scripts/pylint_all.py\n      - matrix_notify_failure_unless_pr\n\n  chk_antlr_grammar:\n    <<: *base_cimg_small\n    steps:\n      - checkout\n      - run:\n          name: Install Java\n          command: |\n            sudo apt -q update\n            sudo apt install -y openjdk-17-jdk\n      - run:\n          name: Run tests\n          command: scripts/test_antlr_grammar.sh\n      - matrix_notify_failure_unless_pr\n\n  chk_buglist:\n    <<: *base_node_small\n    steps:\n      - checkout\n      - run:\n          name: JS deps\n          command: |\n            npm install download\n            npm install JSONPath\n            npm install mktemp\n      - run:\n          name: Test buglist\n          command: test/buglistTests.js\n      - matrix_notify_failure_unless_pr\n\n  chk_proofs:\n    <<: *base_ubuntu2404_small\n    steps:\n      - checkout\n      - run_proofs\n      - matrix_notify_failure_unless_pr\n\n  chk_docs_pragma_min_version:\n    <<: *base_ubuntu2404_small\n    steps:\n      - checkout\n      - run_docs_pragma_min_version\n      - matrix_notify_failure_unless_pr\n\n  t_ubu_pyscripts:\n    <<: *base_ubuntu2404_small\n    steps:\n      - checkout\n      - run:\n          name: Python unit tests\n          command: python3 test/pyscriptTests.py\n      - run:\n          name: Smoke test for gas_diff_stats.py\n          command: scripts/gas_diff_stats.py\n      - matrix_notify_failure_unless_pr\n\n  t_win_pyscripts:\n    <<: *base_win\n    steps:\n      - run: git config --global core.autocrlf false\n      - checkout\n      - run:\n          name: Install dependencies\n          command: python -m pip install --user requests parsec tabulate\n      - run:\n          name: Python unit tests\n          command: python.exe test/pyscriptTests.py\n      - matrix_notify_failure_unless_pr\n\n  b_ubu: &b_ubu\n    # this runs 2x faster on xlarge but takes 4x more resources (compared to medium).\n    # Enough other jobs depend on it that it's worth it though.\n    <<: *base_ubuntu2404_xlarge\n    steps:\n      - build\n      - run: cat prerelease.txt\n\n  # x64 ASAN build, for testing for memory related bugs\n  b_ubu_asan: &b_ubu_asan\n    # Runs slightly faster on large and xlarge but we only run it nightly so efficiency matters more.\n    <<: *base_ubuntu2404\n    environment:\n      <<: *base_ubuntu2404_env\n      # NOTE: Sanitizers may alter the intermediate code, potentially causing false warnings.\n      # As a result, treating warnings as errors in instrumented builds can lead to build failures due to these false positives.\n      # Therefore, we disable pedantic builds in such cases.\n      # See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562#c27\n      CMAKE_OPTIONS: -DSANITIZE=address -DPEDANTIC=OFF\n      CMAKE_BUILD_TYPE: Release\n      # Set the number of jobs to two instead of the default three, so that we do not run out of memory\n      MAKEFLAGS: -j 2\n    steps:\n      - build\n\n  b_ubu_clang: &b_ubu_clang\n    <<: *base_ubuntu2404_clang_large\n    environment:\n      <<: *base_ubuntu2404_clang_large_env\n      MAKEFLAGS: -j 10\n    steps:\n      - build\n\n  b_ubu_san_clang:\n    # This runs a bit faster on large and xlarge but on nightly efficiency matters more.\n    parameters:\n      cmake_options:\n        type: string\n    <<: *base_ubuntu2404_clang\n    environment:\n      <<: *base_ubuntu2404_clang_env\n      # NOTE: Disabled pedantic builds to avoid false positives, see b_ubu_asan for a more detailed explanation.\n      CMAKE_OPTIONS: -DPEDANTIC=OFF << parameters.cmake_options >>\n    steps:\n      - build\n\n  b_ubu_force_release: &b_ubu_force_release\n    <<: *b_ubu\n    environment:\n      <<: *base_ubuntu2404_xlarge_env\n      FORCE_RELEASE: ON\n\n  b_ubu_static:\n    # We temporarily keep building static release binaries on ubuntu 20.04\n    # to avoid glibc incompatibilities.\n    # See: https://github.com/argotorg/solidity/issues/13954\n    # On large runs 2x faster than on medium. 3x on xlarge.\n    <<: *base_ubuntu2404_xlarge\n    environment:\n      <<: *base_ubuntu2404_xlarge_env\n      CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DSOLC_LINK_STATIC=ON\n    steps:\n      - checkout\n      - run_build\n      - run:\n          name: strip binary\n          command: strip build/solc/solc\n      - store_artifacts:\n          path: build/solc/solc\n          destination: solc-static-linux\n      - run: mv build/solc/solc build/solc/solc-static-linux\n      - persist_to_workspace:\n          root: build\n          paths:\n            - solc/solc-static-linux\n      - matrix_notify_failure_unless_pr\n\n  b_ubu_static_arm: &b_ubu_static_arm\n    <<: *base_ubuntu2404_arm_large\n    environment:\n      <<: *base_ubuntu2404_arm_large_env\n      CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DSOLC_LINK_STATIC=ON\n    steps:\n      - checkout\n      - run_build\n      - run:\n          name: strip binary\n          command: strip build/solc/solc\n      - store_artifacts:\n          path: build/solc/solc\n          destination: solc-static-linux-arm\n      - run: mv build/solc/solc build/solc/solc-static-linux-arm\n      - run: mv build/test/soltest build/test/soltest-linux-arm\n      - run: mv build/test/tools/solfuzzer build/test/tools/solfuzzer-linux-arm\n      - persist_executables_to_workspace_arm\n      - matrix_notify_failure_unless_pr\n\n  b_ubu_min_req:\n    <<: *base_ubuntu2404_large\n    steps:\n      - checkout\n      - install_and_check_minimum_requirements:\n          compiler: gcc\n      - run_build\n      - store_artifacts_solc\n      - persist_executables_to_workspace\n      - matrix_notify_failure_unless_pr\n      - build\n\n  b_ubu_min_req_clang:\n    <<: *base_ubuntu2404_clang_large\n    environment:\n      <<: *base_ubuntu2404_clang_large_env\n      MAKEFLAGS: -j 10\n    steps:\n      - checkout\n      - install_and_check_minimum_requirements:\n          compiler: clang\n      - run_build\n      - matrix_notify_failure_unless_pr\n\n  t_ubu_min_req_soltest:\n    <<: *base_ubuntu2404_large\n    parallelism: 20\n    environment:\n      <<: *base_ubuntu2404_large_env\n      EVM: << pipeline.parameters.evm-version >>\n      EOF_VERSION: 0\n      OPTIMIZE: 0\n    steps:\n      - soltest\n\n  b_ubu_ossfuzz: &b_ubu_ossfuzz\n    <<: *base_ubuntu_clang_large\n    steps:\n      - checkout\n      - setup_prerelease\n      - run_build_ossfuzz\n      - persist_ossfuzz_executables_to_workspace\n      - matrix_notify_failure_unless_pr\n\n  t_ubu_ossfuzz: &t_ubu_ossfuzz\n    <<: *base_ubuntu_clang_small\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - run:\n          name: Regression tests\n          command: |\n            git clone https://github.com/argotorg/solidity-fuzzing-corpus /tmp/solidity-fuzzing-corpus\n            mkdir -p test_results\n            scripts/regressions.py -o test_results\n      - store_test_results:\n          path: test_results/\n      - store_artifacts_test_results\n\n  b_archlinux:\n    <<: *base_archlinux_large\n    environment:\n      <<: *base_archlinux_large_env\n    steps:\n      - run:\n          name: Install build dependencies\n          command: |\n            pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake ccache git openssh tar\n      - checkout\n      - run_build\n      - store_artifacts_solc\n      - persist_executables_to_workspace\n      - matrix_notify_failure_unless_pr\n\n  b_osx:\n    <<: *base_osx\n    environment:\n      <<: *base_osx_env\n      CMAKE_BUILD_TYPE: Release\n      # boost root configured to the prefix used in `osx_install_dependencies.sh`\n      CMAKE_OPTIONS: -DCMAKE_OSX_ARCHITECTURES:STRING=x86_64;arm64 -DBoost_ROOT=/opt/boost\n    steps:\n      - checkout\n      - install_dependencies_osx\n      - run_build\n      - store_artifacts_solc\n      - store_artifacts_yul_phaser\n      - persist_executables_to_workspace_osx\n      - matrix_notify_failure_unless_pr\n\n  t_osx_soltest: &t_osx_soltest\n    <<: *base_osx\n    environment:\n      <<: *base_osx_env\n      EVM: << pipeline.parameters.evm-version >>\n      EOF_VERSION: 0\n      OPTIMIZE: 0\n    steps:\n      - checkout\n      - install_dependencies_osx\n      - attach_workspace:\n          at: .\n      - run_soltest\n      - store_test_results:\n          path: test_results/\n      - store_artifacts_test_results\n      - matrix_notify_failure_unless_pr\n\n  t_osx_cli:\n    <<: *base_osx\n    parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py\n    steps:\n      - checkout\n      - install_dependencies_osx\n      - attach_workspace:\n          at: .\n      - run_cmdline_tests\n      - store_artifacts_test_results\n      - matrix_notify_failure_unless_pr\n\n  b_ems:\n    <<: *base_ems_large\n    environment:\n      <<: *base_ems_large_env\n      MAKEFLAGS: -j 10\n    steps:\n      - checkout\n      - restore_ccache_if_allowed\n      # WARNING! If you edit anything between here and save_cache, remember to invalidate the cache manually by bumping the version\n      - run_with_ccache_unless_tag:\n          step_name: Build\n          command: scripts/ci/build_emscripten.sh\n      - save_ccache_if_develop\n      - store_artifacts:\n          path: upload/soljson.js\n          destination: soljson.js\n      - run: mkdir -p workspace\n      - run: cp upload/soljson.js workspace/soljson.js\n      - run: scripts/get_version.sh > workspace/version.txt\n      - persist_to_workspace:\n          root: workspace\n          paths:\n            - soljson.js\n            - version.txt\n      - matrix_notify_failure_unless_pr\n\n  b_docs:\n    <<: *base_ubuntu2404_small\n    steps:\n      - checkout\n      - setup_prerelease\n      - run:\n          name: Install build system dependencies\n          command: |\n            apt-get update\n            apt-get install --quiet=2 --no-install-recommends python3-dev libcairo2-dev pkg-config\n      - run:\n          name: Build documentation\n          command: docs/docs.sh\n      - store_artifacts:\n          path: docs/_build/html/\n          destination: docs-html\n      - matrix_notify_failure_unless_pr\n\n  t_ubu_soltest: &t_ubu_soltest\n    <<: *base_ubuntu2404_large\n    parallelism: 20\n    environment:\n      <<: *base_ubuntu2404_large_env\n      EVM: << pipeline.parameters.evm-version >>\n      EOF_VERSION: 0\n      OPTIMIZE: 0\n    steps:\n      - soltest\n\n  t_ubu_arm_soltest: &t_ubu_arm_soltest\n    <<: *base_ubuntu2404_arm_medium\n    parallelism: 20\n    environment:\n      <<: *base_ubuntu2404_arm_medium_env\n      EVM: << pipeline.parameters.evm-version >>\n      EOF_VERSION: 0\n      OPTIMIZE: 0\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - run:\n          name: Create symbolic link with expected soltest binary name\n          command: |\n            ln --symbolic --relative build/test/soltest-linux-arm build/test/soltest\n      - run_soltest\n      - store_test_results:\n          path: test_results/\n      - store_artifacts_test_results\n      - matrix_notify_failure_unless_pr\n\n  t_ubu_soltest_low_priority_evm_versions: &t_ubu_soltest_low_priority_evm_versions\n    <<: *base_ubuntu2404_large\n    parallelism: 50\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - run_soltest_all:\n          # We test most EVM versions on every PR. The ones below are the exceptions.\n          #\n          # We do not test these at all. We were never doing that and no point starting now since\n          # they are deprecated anyway:\n          # - tangerineWhistle\n          # - spuriousDragon\n          #\n          # These have a low chance of breaking so we only run them in nightly to save credits:\n          # - byzantium: deprecated, if it breaks, homestead likely will as well\n          # - petersburg: no changes compared to constantinople\n          # - prague: no changes compared to cancun\n          evm_versions: byzantium petersburg prague\n      - store_test_results:\n          path: test_results/\n      - store_artifacts_test_results\n      - matrix_notify_failure_unless_pr\n\n  t_ubu_lsp: &t_ubu_lsp\n    <<: *base_ubuntu2404_small\n    steps:\n      - test_lsp\n\n  t_archlinux_soltest: &t_archlinux_soltest\n    <<: *base_archlinux\n    parallelism: 20\n    environment:\n      <<: *base_archlinux_env\n      EVM: << pipeline.parameters.evm-version >>\n      EOF_VERSION: 0\n      OPTIMIZE: 0\n      # For Archlinux we do not have prebuilt docker images and we would need to build evmone from source,\n      # thus we forgo semantics tests to speed things up.\n      SOLTEST_FLAGS: --no-semantic-tests --no-smt\n    steps:\n      - run:\n          name: Install runtime dependencies\n          command: |\n            pacman --noconfirm -Syu --noprogressbar --needed z3 git\n      - soltest\n\n  t_ubu_clang_soltest: &t_ubu_clang_soltest\n    <<: *base_ubuntu2404_clang\n    parallelism: 20\n    environment:\n      <<: *base_ubuntu2404_clang_env\n      EVM: << pipeline.parameters.evm-version >>\n      EOF_VERSION: 0\n      OPTIMIZE: 0\n      # The high parallelism in this job is causing the SMT tests to run out of memory,\n      # so disabling for now.\n      SOLTEST_FLAGS: --no-smt\n    steps:\n      - soltest\n\n  t_ubu_force_release_soltest_all: &t_ubu_force_release_soltest_all\n    <<: *base_ubuntu2404_large\n    parallelism: 50\n    steps:\n      - soltest_all\n\n  t_ubu_cli: &t_ubu_cli\n    <<: *base_ubuntu2404_small\n    parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py\n    steps:\n      - cmdline_tests\n\n  t_ubu_arm_cli: &t_ubu_arm_cli\n    <<: *base_ubuntu2404_arm_medium\n    parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - run:\n          name: Create symbolic link with expected solc and solfuzzer binaries name\n          command: |\n            ln --symbolic --relative build/solc/solc-static-linux-arm build/solc/solc\n            ln --symbolic --relative build/test/tools/solfuzzer-linux-arm build/test/tools/solfuzzer\n      - run_cmdline_tests\n      - store_test_results:\n          path: test_results/\n      - store_artifacts_test_results\n      - matrix_notify_failure_unless_pr\n\n  t_ubu_force_release_cli: &t_ubu_force_release_cli\n    <<: *t_ubu_cli\n\n  t_ubu_locale:\n    <<: *base_ubuntu2404_small\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - run: test/localeTest.sh build/solc/solc\n      - matrix_notify_failure_unless_pr\n\n  t_ubu_asan_cli:\n    # Runs slightly faster on medium but we only run it nightly so efficiency matters more.\n    <<: *base_ubuntu2404\n    parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py\n    environment:\n      <<: *base_ubuntu2404_env\n      ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2\n      # Suppress CLN memory leak.\n      # See: https://github.com/argotorg/solidity/issues/13891 for details.\n      LSAN_OPTIONS: suppressions=/root/project/.circleci/cln-asan.supp:print_suppressions=0\n    steps:\n      - cmdline_tests\n\n  t_ubu_asan_soltest:\n    <<: *base_ubuntu2404\n    parallelism: 20\n    environment:\n      <<: *base_ubuntu2404_env\n      EVM: << pipeline.parameters.evm-version >>\n      EOF_VERSION: 0\n      OPTIMIZE: 0\n      SOLTEST_FLAGS: --no-smt\n      ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2\n      # Suppress CLN memory leak.\n      # See: https://github.com/argotorg/solidity/issues/13891 for details.\n      LSAN_OPTIONS: suppressions=/root/project/.circleci/cln-asan.supp\n    steps:\n      - soltest\n\n  t_ubu_asan_clang_soltest:\n    <<: *base_ubuntu2404_clang\n    parallelism: 20\n    environment:\n      <<: *base_ubuntu2404_clang_env\n      EVM: << pipeline.parameters.evm-version >>\n      EOF_VERSION: 0\n      OPTIMIZE: 0\n      SOLTEST_FLAGS: --no-smt\n      ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2\n    steps:\n      - soltest\n\n  t_ubu_ubsan_clang_soltest:\n    <<: *base_ubuntu2404_clang\n    parallelism: 20\n    environment:\n      <<: *base_ubuntu2404_clang_env\n      EVM: << pipeline.parameters.evm-version >>\n      EOF_VERSION: 0\n      SOLTEST_FLAGS: --no-smt\n    steps:\n      - soltest\n\n  t_ubu_ubsan_clang_cli:\n    <<: *base_ubuntu2404_clang\n    parallelism: 8 # Should match number of tests in .circleci/parallel_cli_tests.py\n    steps:\n      - cmdline_tests\n\n  t_ems_solcjs:\n    # Unlike other t_ems jobs this one actually runs 2x faster on medium (compared to small).\n    <<: *base_ubuntu2404\n    steps:\n      - checkout\n      - attach_workspace:\n          at: /tmp/workspace\n      - run:\n          name: Install test dependencies\n          command: |\n            apt-get update\n            apt-get install -qqy --no-install-recommends nodejs npm\n      - run:\n          name: Test solcjs\n          no_output_timeout: 30m\n          command: |\n            node --version\n            npm --version\n            test/externalTests/solc-js/solc-js.sh /tmp/workspace/soljson.js $(cat /tmp/workspace/version.txt)\n      - matrix_notify_failure_unless_pr\n\n  t_ems_ext_edr:\n    # Runs out of memory on the small instance\n    <<: *base_ubuntu2404\n    docker:\n      - image: cimg/rust:1.79.0-node\n    environment:\n      <<: *base_ubuntu2404_env\n      EDR_TESTS_SOLC_PATH: /tmp/workspace/soljson.js\n    steps:\n      - checkout\n      - attach_workspace:\n          at: /tmp/workspace\n      - run:\n          name: Ensure pnpm is installed if npm is present\n          command: sudo npm install -g pnpm\n      - run:\n          name: Retrieve EDR latest release tag\n          command: |\n            # Make authenticated requests when the Github token is available\n            if [[ -n \"$GITHUB_READ_TOKEN\" ]]; then\n              EXTRA_HEADERS=(--header \"Authorization: Bearer ${GITHUB_READ_TOKEN}\")\n            fi\n            EDR_LATEST_RELEASE_TAG=$(\n              curl \\\n                --silent \\\n                --location \\\n                --fail \\\n                --show-error \\\n                \"${EXTRA_HEADERS[@]}\" \\\n                https://api.github.com/repos/nomicfoundation/edr/releases/latest \\\n                | jq --raw-output .tag_name \\\n            )\n            echo \"export EDR_LATEST_RELEASE_TAG='${EDR_LATEST_RELEASE_TAG}'\" >> \"$BASH_ENV\"\n      - run: git clone --depth 1 https://github.com/nomicfoundation/edr.git --branch \"$EDR_LATEST_RELEASE_TAG\"\n      - run:\n          name: Install dependencies\n          command: |\n            cd edr\n            pnpm install --no-frozen-lockfile\n      - run:\n          name: Run hardhat-tests in EDR repo\n          command: |\n            EDR_TESTS_SOLC_VERSION=$(scripts/get_version.sh)\n            export EDR_TESTS_SOLC_VERSION\n\n            cd edr/hardhat-tests\n            pnpm test\n      - matrix_notify_failure_unless_pr\n\n  t_ext:\n    parameters:\n      project:\n        type: string\n      binary_type:\n        type: enum\n        enum:\n          - solcjs\n          - native\n      compile_only:\n        type: integer\n        default: 0\n      image:\n        type: string\n        default: cimg/node:current\n      resource_class:\n        type: string\n        default: small\n      python2:\n        type: boolean\n        default: false\n    docker:\n      - image: << parameters.image >>\n    resource_class: << parameters.resource_class >>\n    # NOTE: Each external test runs up to 6 independent settings presets. If parallelism is higher than\n    # actual preset count, some runs will exit immediately. If it's lower, some runs will get more than one preset.\n    parallelism: 6\n    environment:\n      TERM: xterm\n      COMPILE_ONLY: << parameters.compile_only >>\n    steps:\n      - checkout\n      - attach_workspace:\n          at: /tmp/workspace\n      - install_foundry\n      - run:\n          name: Ensure pnpm is installed if npm is present\n          command: |\n            if command -v npm &> /dev/null; then\n              sudo npm install -g pnpm\n            fi\n      - when:\n          condition: << parameters.python2 >>\n          steps:\n            - run:\n                name: Install Python 2 and make it the default\n                command: |\n                  sudo apt update\n                  # python is used by node-gyp to build native modules (needed for Colony).\n                  # In the 14.x image node-gyp still requires Python 2.\n                  sudo apt install python2 --assume-yes --no-install-recommends\n                  sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 1\n      - when:\n          condition:\n            equal: [<< parameters.binary_type >>, \"solcjs\"]\n          steps:\n            - run:\n                name: External << parameters.project >> tests (<< parameters.binary_type >>)\n                command: |\n                  test/external_tests.py test --solc-binary-type \"<< parameters.binary_type >>\" --solc-binary-path /tmp/workspace/soljson.js --run \"<< parameters.project >>\"\n      - when:\n          condition:\n            equal: [<< parameters.binary_type >>, \"native\"]\n          steps:\n            - run:\n                name: External << parameters.project >> tests (<< parameters.binary_type >>)\n                command: |\n                  test/external_tests.py test --solc-binary-type \"<< parameters.binary_type >>\" --solc-binary-path /tmp/workspace/solc/solc-static-linux --run \"<< parameters.project >>\"\n      - store_artifacts:\n          path: reports/externalTests/\n      # persist_to_workspace fails if the directory does not exist and the test script will create\n      # it only if it actually has benchmark results.\n      - run: mkdir -p reports/externalTests/\n      - persist_to_workspace:\n          root: .\n          paths:\n            - reports/externalTests/\n      - matrix_notify_failure_unless_pr\n\n  t_ethdebug_output_validity:\n    <<: *base_node_small\n    steps:\n      - checkout\n      - attach_workspace:\n          at: /tmp/workspace\n      - install_python3:\n            packages: pyyaml jsonschema pytest\n      - run:\n          name: Ethdebug validity tests\n          command: |\n            pytest test/ethdebugSchemaTests --solc-binary-path=/tmp/workspace/solc/solc-static-linux -v\n\n  c_ext_benchmarks:\n    <<: *base_node_small\n    steps:\n      - install_python3:\n          packages: requests\n      - checkout\n      - attach_workspace:\n          at: .\n      - run:\n          name: Combine benchmark reports\n          command: cat reports/externalTests/benchmark-*.json | scripts/externalTests/merge_benchmarks.sh > reports/externalTests/all-benchmarks.json\n      - run:\n          name: Summarize reports\n          command: cat reports/externalTests/all-benchmarks.json | scripts/externalTests/summarize_benchmarks.sh > reports/externalTests/summarized-benchmarks.json\n      - store_artifacts:\n          path: reports/externalTests/all-benchmarks.json\n      - store_artifacts:\n          path: reports/externalTests/summarized-benchmarks.json\n      - run:\n          name: Check CircleCI token presence; Skip remaining steps if the token is not present.\n          command: |\n            # NOTE: download_benchmarks.py requires CIRCLECI_TOKEN environment variable to be set to\n            # a valid CircleCI API token to download the benchmark artifacts.\n            if [[ -z \"$CIRCLECI_TOKEN\" ]]; then\n              echo \"Skipping download benchmarks...\"\n              circleci-agent step halt\n            fi\n      - run:\n          name: Download reports from base branch\n          command: |\n            if [[ $CIRCLE_PULL_REQUEST != \"\" ]]; then\n              mkdir reports/externalTests/base-branch/\n              cd reports/externalTests/base-branch/\n\n              pr_id=$(echo \"$CIRCLE_PULL_REQUEST\" | sed 's|\\(.*\\)\\/||')\n              scripts_dir=../../../scripts\n\n              # Our main goal here is to provide new benchmarks, the diff is optional. When benchmarks from\n              # the previous run are not available for whatever reason, we still succeed and just skip the diff.\n              # download_benchmarks.py exits with status 2 in that case.\n              if \"${scripts_dir}/externalTests/download_benchmarks.py\" --base-of-pr \"$pr_id\" || [[ $? == 2 ]]; then\n                echo 'export SKIP_BENCHMARK_DIFF=true' >> $BASH_ENV\n              fi\n            fi\n      - run:\n          name: Diff benchmarks\n          command: |\n            if [[ $CIRCLE_PULL_REQUEST != \"\" && $SKIP_BENCHMARK_DIFF != \"true\" ]]; then\n              cd reports/externalTests/\n              mkdir diff/\n              scripts_dir=../../scripts\n\n              \"${scripts_dir}/externalTests/benchmark_diff.py\" table \\\n                --output-format markdown \\\n                --style humanized \\\n                base-branch/summarized-benchmarks-*.json \\\n                summarized-benchmarks.json > diff/benchmark-diff-summarized-table-markdown-humanized.md\n              \"${scripts_dir}/externalTests/benchmark_diff.py\" table \\\n                --output-format markdown \\\n                --style absolute \\\n                base-branch/summarized-benchmarks-*.json \\\n                summarized-benchmarks.json > diff/benchmark-diff-summarized-table-markdown-absolute.md\n              \"${scripts_dir}/externalTests/benchmark_diff.py\" inplace \\\n                --style absolute \\\n                base-branch/summarized-benchmarks-*.json \\\n                summarized-benchmarks.json > diff/benchmark-diff-summarized-inplace-absolute.md\n              \"${scripts_dir}/externalTests/benchmark_diff.py\" inplace \\\n                --style absolute \\\n                base-branch/all-benchmarks-*.json \\\n                all-benchmarks.json > diff/benchmark-diff-all-table-inplace-absolute.md\n            fi\n      - store_artifacts:\n          path: reports/externalTests/diff/\n      - store_artifacts:\n          path: reports/externalTests/base-branch/\n\n  b_win: &b_win\n    <<: *base_win_large\n    steps:\n      # NOTE: Not disabling git's core.autocrlf here because we want to build using the typical Windows config.\n      - checkout\n      - restore_cache:\n          keys:\n            - dependencies-win-{{ arch }}-{{ checksum \"scripts/install_deps.ps1\" }}\n      # DO NOT EDIT between here and save_cache, but rather edit .\\scripts\\install_deps.ps1\n      # WARNING! If you do edit anything here instead, remember to invalidate the cache manually.\n      - run:\n          name: \"Installing dependencies\"\n          command: .\\scripts\\install_deps.ps1\n          shell: powershell.exe\n      - save_cache:\n          key: dependencies-win-{{ arch }}-{{ checksum \"scripts/install_deps.ps1\" }}\n          paths:\n            - .\\deps\n      - restore_ccache_if_allowed\n      # WARNING! If you edit anything between here and save_cache, remember to invalidate the cache manually by bumping the version\n      - run_with_ccache_unless_tag:\n          step_name: \"Building solidity\"\n          command: scripts/ci/build_win.sh\n      - save_ccache_if_develop\n      - run:\n          name: \"Run solc.exe to make sure build was successful.\"\n          command: .\\build\\solc\\Release\\solc.exe --version\n          shell: powershell.exe\n      - store_artifacts:\n          path: upload/\n      - persist_to_workspace:\n          root: build\n          paths:\n            - .\\solc\\*\\solc.exe\n            - .\\test\\*\\soltest.exe\n      - matrix_notify_failure_unless_pr\n\n  t_win_soltest: &t_win_soltest\n    <<: *base_win\n    steps:\n      # NOTE: Git's default core.autocrlf is fine for running soltest. We get additional coverage\n      # for files using CRLF that way.\n      - checkout\n      - attach_workspace:\n          at: build\n      - run:\n          name: \"Install evmone\"\n          command: scripts/install_evmone.ps1\n          shell: powershell.exe\n      - run:\n          name: \"Run soltest\"\n          command: .circleci/soltest.ps1\n          shell: powershell.exe\n      - run:\n          name: Install LSP test dependencies\n          command: python -m pip install --user numpy deepdiff colorama\n      - run:\n          name: Executing solc LSP test suite\n          command: python test/lsp.py build\\solc\\Release\\solc.exe --non-interactive\n          shell: powershell.exe\n      - store_test_results:\n          path: test_results/\n      - store_artifacts_test_results\n      - matrix_notify_failure_unless_pr\n\n  # Note: b_bytecode_ubu_static is required because b_ubu_static and b_ubu\n  # are currently built on different Ubuntu base images.\n  # It can be safely removed once we move both to the same Ubuntu version.\n  b_bytecode_ubu_static:\n    parameters:\n      preset:\n        type: string\n    <<: *base_ubuntu2004_small\n    parallelism: 2 # For prepare_bytecode_report\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - prepare_bytecode_report:\n          label: \"ubuntu2004-static\"\n          binary_type: native\n          binary_path: \"build/solc/solc-static-linux\"\n          preset: \"<< parameters.preset >>\"\n\n  b_bytecode_ubu:\n    parameters:\n      preset:\n        type: string\n    <<: *base_ubuntu2404_small\n    parallelism: 2 # For prepare_bytecode_report\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - prepare_bytecode_report:\n          label: \"ubuntu\"\n          binary_type: native\n          binary_path: \"build/solc/solc\"\n          preset: \"<< parameters.preset >>\"\n\n  b_bytecode_osx:\n    parameters:\n      preset:\n        type: string\n    <<: *base_osx\n    parallelism: 2 # For prepare_bytecode_report\n    steps:\n      - checkout\n      - attach_workspace:\n          at: .\n      - prepare_bytecode_report:\n          label: \"osx\"\n          binary_type: native\n          binary_path: \"build/solc/solc\"\n          preset: \"<< parameters.preset >>\"\n\n  b_bytecode_osx_intel:\n    parameters:\n      preset:\n        type: string\n    <<: *base_osx\n    parallelism: 2 # For prepare_bytecode_report\n    steps:\n      - checkout\n      - attach_workspace:\n          at: .\n      - prepare_bytecode_report:\n          label: \"osx_intel\"\n          binary_type: osx_intel\n          binary_path: \"build/solc/solc\"\n          preset: \"<< parameters.preset >>\"\n\n  b_bytecode_win:\n    parameters:\n      preset:\n        type: string\n    <<: *base_win\n    parallelism: 2 # For prepare_bytecode_report\n    steps:\n      # NOTE: For bytecode generation we need the input files to be byte-for-byte identical on all\n      # platforms so line ending conversions must absolutely be disabled.\n      - run: git config --global core.autocrlf false\n      - checkout\n      - run:\n          name: Force install python3.12\n          command: choco install python312 --pre --force\n      - run:\n          name: Create a symlink for python3\n          command: ln -s /c/ProgramData/chocolatey/bin/python3.12 /c/ProgramData/chocolatey/bin/python3\n      - attach_workspace:\n          at: build\n      - prepare_bytecode_report:\n          label: \"windows\"\n          binary_type: native\n          binary_path: \"build/solc/Release/solc.exe\"\n          preset: \"<< parameters.preset >>\"\n\n  b_bytecode_ubu_arm:\n    parameters:\n      preset:\n        type: string\n    <<: *base_ubuntu2404_arm_medium\n    parallelism: 2 # For prepare_bytecode_report\n    steps:\n      - checkout\n      - attach_workspace:\n          at: build\n      - prepare_bytecode_report:\n          label: \"ubuntu_arm\"\n          binary_type: native\n          binary_path: \"build/solc/solc-static-linux-arm\"\n          preset: \"<< parameters.preset >>\"\n\n  b_bytecode_ems:\n    parameters:\n      preset:\n        type: string\n    <<: *base_node_small\n    steps:\n      - checkout\n      - attach_workspace:\n          at: emscripten_build/libsolc\n      - prepare_bytecode_report:\n          label: \"emscripten\"\n          binary_type: solcjs\n          binary_path: \"emscripten_build/libsolc/soljson.js\"\n          preset: \"<< parameters.preset >>\"\n\n  t_bytecode_compare:\n    <<: *base_ubuntu2404_small\n    environment:\n      <<: *base_ubuntu2404_small_env\n      <<: *bytecode_compare_env_presets\n    steps:\n      - checkout\n      - attach_workspace:\n          at: .\n      - run: .circleci/compare_bytecode_reports.sh $PRESETS\n      - store_artifacts:\n          # NOTE: store_artifacts does not support the 'when' attribute.\n          # Fortunately when the artifact does not exist it just says \"No artifact files found\" and ignores it.\n          path: bytecode-reports-*.zip\n      - matrix_notify_failure_unless_pr\n\n  c_release_binaries:\n    <<: *base_ubuntu2404\n    steps:\n      - checkout\n      - attach_workspace:\n          at: workspace\n      - run:\n          name: Gather and rename binaries from dependent jobs\n          command: |\n            mkdir github/\n            cp workspace/solc/solc-static-linux     github/solc-static-linux\n            cp workspace/solc/solc-static-linux-arm github/solc-static-linux-arm\n            cp workspace/build/solc/solc            github/solc-macos\n            cp workspace/solc/Release/solc.exe      github/solc-windows.exe\n            cp workspace/soljson.js                 github/soljson.js\n\n            cd github/\n            tar --create --file ../github-binaries.tar *\n      - store_artifacts:\n          path: github-binaries.tar\n      - run:\n          name: Rename binaries to solc-bin naming convention\n          command: |\n            full_version=$(\n              github/solc-static-linux --version |\n              sed -En 's/^Version: ([0-9.]+.*\\+commit\\.[0-9a-f]+(\\.mod)?).*$/\\1/p'\n            )\n\n            mkdir -p solc-bin/{linux-amd64,linux-arm64,macosx-amd64,windows-amd64,bin}\n\n            mv github/solc-static-linux-arm \"solc-bin/linux-arm64/solc-linux-arm64-v${full_version}\"\n            mv github/solc-static-linux     \"solc-bin/linux-amd64/solc-linux-amd64-v${full_version}\"\n            mv github/solc-macos            \"solc-bin/macosx-amd64/solc-macosx-amd64-v${full_version}\"\n            mv github/solc-windows.exe      \"solc-bin/windows-amd64/solc-windows-amd64-v${full_version}.exe\"\n            mv github/soljson.js            \"solc-bin/bin/soljson-v${full_version}.js\"\n\n            cd solc-bin/\n            tar --create --file ../solc-bin-binaries.tar *\n      - store_artifacts:\n          path: solc-bin-binaries.tar\n      - matrix_notify_failure_unless_pr\n      - matrix_notify_release_unless_pr\n\n  c_source_tarball:\n    <<: *base_ubuntu2404_small\n    steps:\n      - checkout\n      - setup_prerelease\n      - run: scripts/create_source_tarball.sh\n      - store_artifacts:\n          path: upload/\n      - matrix_notify_failure_unless_pr\n      - matrix_notify_release_unless_pr\n\n  b_alpine_docker:\n    <<: *base_cimg_small\n    steps:\n      - setup_remote_docker:\n          # Always build from scratch to use current packages.\n          # This job is only meant to run nightly so build time is not an issue.\n          docker_layer_caching: false\n      - checkout\n      - run:\n          name: Disable partial clone and fetch all objects\n          command: |\n            git config remote.origin.promisor false\n            git config --unset remote.origin.partialclonefilter\n            git fetch --refetch origin\n      - run:\n          name: Build and tag the container\n          command: scripts/docker_deploy_manual.sh develop \"file://$PWD\" --no-push\n      - run:\n          name: Smoke test\n          command: docker run --pull=never ghcr.io/argotorg/solc:build-alpine --version\n      - matrix_notify_failure_unless_pr\n\nworkflows:\n  version: 2\n\n  main:\n    jobs:\n      # basic checks\n      - chk_spelling: *requires_nothing\n      - chk_coding_style: *requires_nothing\n      # DISABLED FOR 0.6.0 - chk_docs_examples: *requires_nothing\n      - chk_buglist: *requires_nothing\n      - chk_proofs: *requires_nothing\n      - chk_pylint: *requires_nothing\n      - chk_errorcodes: *requires_nothing\n      - chk_antlr_grammar: *requires_nothing\n      - chk_docs_pragma_min_version: *requires_nothing\n      - t_ubu_pyscripts: *requires_nothing\n      - t_win_pyscripts: *requires_nothing\n\n      # build-only\n      - b_docs: *requires_nothing\n      - b_ubu_ossfuzz: *requires_nothing\n\n      # build and test with minimum supported versions of dependencies\n      - b_ubu_min_req_clang: *requires_nothing\n      - b_ubu_min_req: *requires_nothing\n      - t_ubu_min_req_soltest:\n          <<: *on_all_tags_and_branches\n          requires:\n            - b_ubu_min_req\n\n      # OS/X build and tests\n      - b_osx: *requires_nothing\n      - t_osx_cli: *requires_b_osx\n      - t_osx_soltest: *requires_b_osx\n\n      # ArchLinux build and tests\n      - b_archlinux: *requires_nothing\n      - t_archlinux_soltest: *requires_b_archlinux\n\n      # Static build\n      - b_ubu_static: *requires_nothing\n      - b_ubu_static_arm: *requires_nothing\n\n      # Ubuntu build and tests\n      - b_ubu: *requires_nothing\n      - t_ubu_cli: *requires_b_ubu\n      - t_ubu_arm_cli: *requires_b_ubu_static_arm\n      - t_ubu_locale: *requires_b_ubu\n      - t_ubu_soltest: *requires_b_ubu\n      - t_ubu_arm_soltest: *requires_b_ubu_static_arm\n      - b_ubu_clang: *requires_nothing\n      - t_ubu_clang_soltest: *requires_b_ubu_clang\n      - t_ubu_lsp: *requires_b_ubu\n\n      # Ubuntu fake release build and tests\n      - b_ubu_force_release: *requires_nothing\n      - t_ubu_force_release_cli: *requires_b_ubu_force_release\n      - t_ubu_force_release_soltest_all: *requires_b_ubu_force_release\n\n      # Emscripten build and tests that take 15 minutes or less\n      - b_ems: *requires_nothing\n      - t_ems_solcjs: *requires_b_ems\n      - t_ems_ext_edr: *requires_b_ems\n\n      - t_ext: *job_ems_compile_ext_colony\n\n      - t_ext: *job_native_compile_ext_gnosis\n      - t_ext: *job_native_test_ext_zeppelin\n      - t_ext: *job_native_test_ext_ens\n      - t_ext: *job_native_test_ext_yield_liquidator\n      - t_ext: *job_native_test_ext_uniswap\n      - t_ext: *job_native_test_ext_prb_math\n      - t_ext: *job_native_test_ext_elementfi\n      - t_ext: *job_native_test_ext_brink\n      - t_ext: *job_native_compile_ext_gp2\n      - t_ext: *job_native_compile_ext_euler\n      - t_ext: *job_native_compile_ext_pool_together\n      # TODO: Dropping the external tests below since they are based on old forks and\n      # fail after update the default evm version to cancun.\n      #- t_ext: *job_native_compile_ext_trident\n      #- t_ext: *job_native_compile_ext_chainlink\n      #- t_ext: *job_native_compile_ext_bleeps\n\n      - t_ethdebug_output_validity:\n          <<: *requires_b_ubu_static\n\n      - c_ext_benchmarks:\n          <<: *requires_nothing\n          requires:\n            - t_ems_compile_ext_colony\n            - t_native_compile_ext_gnosis\n            - t_native_test_ext_zeppelin\n            - t_native_test_ext_ens\n            - t_native_test_ext_yield_liquidator\n            - t_native_test_ext_uniswap\n            - t_native_test_ext_elementfi\n            - t_native_test_ext_brink\n            - t_native_compile_ext_gp2\n            # TODO: Dropping prb-math from the benchmarks since it is not implemented yet\n            # in the new Foundry external testing infrastructure.\n            # - t_native_test_ext_prb_math\n            - t_native_compile_ext_euler\n            - t_native_compile_ext_pool_together\n            # TODO: Dropping the external tests below since they are based on old forks and\n            # fail after update the default evm version to cancun.\n            #- t_native_compile_ext_trident\n            #- t_native_compile_ext_chainlink\n            #- t_native_compile_ext_bleeps\n\n      # Windows build and tests\n      - b_win: *requires_nothing\n      - t_win_soltest: *requires_b_win\n\n      # Bytecode comparison:\n      - b_bytecode_ubu_static:\n          <<: *on_all_tags_and_branches\n          matrix: *bytecode_compare_preset_matrix\n          requires:\n            - b_ubu_static\n      - b_bytecode_ubu:\n          <<: *on_all_tags_and_branches\n          matrix: *bytecode_compare_preset_matrix\n          requires:\n            - b_ubu\n      - b_bytecode_ubu_arm:\n          <<: *on_all_tags_and_branches\n          matrix: *bytecode_compare_preset_matrix\n          requires:\n            - b_ubu_static_arm\n      - b_bytecode_win:\n          <<: *on_all_tags_and_branches\n          matrix: *bytecode_compare_preset_matrix\n          requires:\n            - b_win\n      - b_bytecode_osx:\n          <<: *on_all_tags_and_branches\n          matrix: *bytecode_compare_preset_matrix\n          requires:\n            - b_osx\n      - b_bytecode_osx_intel:\n          <<: *on_all_tags_and_branches\n          matrix: *bytecode_compare_preset_matrix\n          requires:\n            - b_osx\n      - b_bytecode_ems:\n          <<: *on_all_tags_and_branches\n          matrix: *bytecode_compare_preset_matrix\n          requires:\n            - b_ems\n      - t_bytecode_compare:\n          <<: *on_all_tags_and_branches\n          requires:\n            - b_bytecode_ubu_static\n            - b_bytecode_ubu\n            - b_bytecode_ubu_arm\n            - b_bytecode_win\n            - b_bytecode_osx\n            - b_bytecode_osx_intel\n            - b_bytecode_ems\n\n      # Final artifacts\n      - c_release_binaries:\n          <<: *on_version_tags\n          requires:\n            - b_ubu_static_arm\n            - b_ubu_static\n            - b_osx\n            - b_win\n            - b_ems\n      - c_source_tarball: *requires_nothing\n\n  nightly:\n\n    triggers:\n      - schedule:\n          cron: \"0 0 * * *\"\n          <<: *on_develop\n\n    jobs:\n      # ASan build and tests\n      - b_ubu_asan: *requires_nothing\n      - b_ubu_san_clang: *job_b_ubu_asan_clang\n      - t_ubu_asan_soltest: *requires_b_ubu_asan\n      - t_ubu_asan_clang_soltest: *requires_b_ubu_asan_clang\n      - t_ubu_asan_cli: *requires_b_ubu_asan\n\n      # UBSan build and tests\n      - b_ubu_san_clang: *job_b_ubu_ubsan_clang\n      - t_ubu_ubsan_clang_soltest: *requires_b_ubu_ubsan_clang\n      - t_ubu_ubsan_clang_cli: *requires_b_ubu_ubsan_clang\n\n      # Deprecated EVM versions tests\n      - b_ubu: *requires_nothing\n      - t_ubu_soltest_low_priority_evm_versions: *requires_b_ubu\n\n      # Build in a Docker container (on Alpine Linux)\n      - b_alpine_docker: *requires_nothing\n\n  nightly-ossfuzz:\n\n    triggers:\n      - schedule:\n          cron: \"0 0 * * *\"\n          <<: *on_develop\n\n    jobs:\n      # OSSFUZZ builds and (regression) tests\n      - b_ubu_ossfuzz: *requires_nothing\n      - t_ubu_ossfuzz: *requires_b_ubu_ossfuzz\n"
  },
  {
    "path": ".circleci/osx_install_dependencies.sh",
    "content": "#! /bin/bash\n#------------------------------------------------------------------------------\n# Bash script to install osx dependencies\n#\n# The documentation for solidity is hosted at:\n#\n#     https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016-2019 solidity contributors.\n# ------------------------------------------------------------------------------\n\n# note that the following directories may be cached by circleci:\n# - /usr/local\n# - /opt/homebrew\n\nset -eu\n\nfunction validate_checksum {\n  local package=\"$1\"\n  local expected_checksum=\"$2\"\n\n  local actual_checksum\n  actual_checksum=$(sha256sum \"$package\")\n  if [[ $actual_checksum != \"${expected_checksum}  ${package}\" ]]\n  then\n    >&2 echo \"ERROR: Wrong checksum for package $package.\"\n    >&2 echo \"Actual:   $actual_checksum\"\n    >&2 echo \"Expected: $expected_checksum\"\n    exit 1\n  fi\n}\n\nif [ ! -f /usr/local/lib/libz3.a ] # if this file does not exists (cache was not restored), rebuild dependencies\nthen\n  brew update\n  brew upgrade\n  brew install cmake\n  brew install ccache\n  brew install wget\n  brew install coreutils\n  brew install diffutils\n  brew install grep\n  # JRE is required to run eldarica solver\n  brew install openjdk@11\n  brew install unzip\n\n  # boost\n  boost_version=\"1.84.0\"\n  boost_package=\"boost_${boost_version//./_}.tar.bz2\"\n  boost_dir=\"boost_${boost_version//./_}\"\n  wget \"https://archives.boost.io/release/$boost_version/source/$boost_package\"\n  tar xf \"$boost_package\"\n  rm \"$boost_package\"\n  cd \"$boost_dir\"\n  ./bootstrap.sh --with-toolset=clang --with-libraries=thread,system,filesystem,program_options,serialization,test\n  # the default number of jobs that b2 is taking, is the number of detected available CPU threads.\n  # install boost to /opt/boost, to use it in CMake, specify Boost_ROOT\n  sudo ./b2 -a address-model=64 architecture=arm+x86 --prefix=/opt/boost install\n  cd ..\n  sudo rm -rf \"$boost_dir\"\n\n  # eldarica\n  eldarica_version=\"2.1\"\n  wget \"https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip\" -O /tmp/eld_binaries.zip\n  validate_checksum /tmp/eld_binaries.zip 0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c\n  unzip /tmp/eld_binaries.zip -d /tmp\n  sudo mv /tmp/eldarica/{eld,eld-client,target,eldEnv} /usr/local/bin\n  rm -rf /tmp/{eldarica,eld_binaries.zip}\n\n  #cvc5\n  cvc5_version=\"1.2.0\"\n  cvc5_archive_name=\"cvc5-macOS-arm64-static\"\n  wget \"https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip\" -O /tmp/cvc5.zip\n  validate_checksum /tmp/cvc5.zip 57d2d4855af3f3865110a254e415098b4e150a655f297010e27eb292f48f7da7\n  sudo unzip -j /tmp/cvc5.zip \"${cvc5_archive_name}/bin/cvc5\" -d /usr/local/bin\n  rm -f /tmp/cvc5.zip\n\n  # z3\n  z3_version=\"4.13.3\"\n  z3_dir=\"z3-z3-$z3_version\"\n  z3_package=\"z3-$z3_version.tar.gz\"\n  wget \"https://github.com/Z3Prover/z3/archive/refs/tags/$z3_package\"\n  validate_checksum \"$z3_package\" f59c9cf600ea57fb64ffeffbffd0f2d2b896854f339e846f48f069d23bc14ba0\n  tar xf \"$z3_package\"\n  rm \"$z3_package\"\n  cd \"$z3_dir\"\n  mkdir build\n  cd build\n  cmake -DCMAKE_OSX_ARCHITECTURES:STRING=\"x86_64;arm64\" -DZ3_BUILD_LIBZ3_SHARED=false ..\n  make -j \"$(nproc)\"\n  sudo make install\n  cd ../..\n  rm -rf \"$z3_dir\"\n\n  # evmone\n  evmone_version=\"0.16.0\"\n  evmone_package=\"evmone-${evmone_version}-darwin-arm64.tar.gz\"\n  wget \"https://github.com/ipsilon/evmone/releases/download/v${evmone_version}/${evmone_package}\"\n  validate_checksum \"$evmone_package\" d26bcf7ada6c712b669ee70cbd8b534f80dadb6207fa15e15d1517d2b6823aa8\n  sudo tar xzpf \"$evmone_package\" -C /usr/local\n  rm \"$evmone_package\"\nfi\n"
  },
  {
    "path": ".circleci/parallel_bytecode_report.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n#------------------------------------------------------------------------------\n# Splits all test source code into multiple files, generates bytecode and metadata\n# for each file and combines it into a single report.txt file.\n#\n# The script is meant to be executed in CI on all supported platforms. All generated\n# reports must be identical for a given compiler version.\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2023 solidity contributors.\n#------------------------------------------------------------------------------\n\n(( $# == 4 )) || { >&2 echo \"Wrong number of arguments.\"; exit 1; }\nlabel=\"$1\"\nbinary_type=\"$2\"\nbinary_path=\"$3\" # This path must be absolute\npreset=\"$4\"\n\n[[ $binary_type == native || $binary_type == \"osx_intel\" || $binary_type == solcjs ]] || { >&2 echo \"Invalid binary type: ${binary_type}\"; exit 1; }\n\n# NOTE: Locale affects the order of the globbed files.\nexport LC_ALL=C\n\nmkdir test-cases/\ncd test-cases/\n\necho \"Preparing input files\"\npython3 ../scripts/isolate_tests.py ../test/\n\nif [[ $binary_type == native || $binary_type == \"osx_intel\" ]]; then\n    interface=$(echo -e \"standard-json\\ncli\" | circleci tests split)\n    echo \"Selected interface: ${interface}\"\n\n    echo \"Generating bytecode reports\"\n    python3 ../scripts/bytecodecompare/prepare_report.py \\\n        \"$binary_path\" \\\n        --interface \"$interface\" \\\n        --preset \"$preset\" \\\n        --execution-arch \"$binary_type\" \\\n        --report-file \"../bytecode-report-${label}-${interface}-${preset}.txt\"\nelse\n    echo \"Installing solc-js\"\n    git clone --depth 1 https://github.com/argotorg/solc-js.git solc-js\n    cp \"$binary_path\" solc-js/soljson.js\n\n    cd solc-js/\n    npm install\n    npm run build\n\n    cd ..\n    npm install ./solc-js/dist\n\n    cp ../scripts/bytecodecompare/prepare_report.js .\n\n    echo \"Generating bytecode reports\"\n    # shellcheck disable=SC2035\n    ./prepare_report.js \\\n        --preset \"$preset\" \\\n        *.sol --report-file \"../bytecode-report-${label}-${preset}.txt\"\nfi\n"
  },
  {
    "path": ".circleci/parallel_cli_tests.py",
    "content": "#!/usr/bin/env python3\n\nimport subprocess\nimport sys\n\n# Slowest CLI tests, whose execution takes time on the order of minutes (as of June 2023).\n# When adding/removing items here, remember to update `parallelism` value in jobs that run this script.\n# TODO: We should switch to time-based splitting but that requires JUnit XML report support in cmdlineTests.sh.\ntests_to_run_in_parallel = [\n    '~ast_import_export',                   # ~7 min\n    '~evmasm_import_export',                # ~5 min\n    '~ast_export_with_stop_after_parsing',  # ~4 min\n    '~soljson_via_fuzzer',                  # ~3 min\n    '~via_ir_equivalence',                  # ~1 min\n    '~compilation_tests',                   # ~1 min\n    '~documentation_examples',              # ~1 min\n    '*',                                    # This item represents all the remaining tests\n]\n\n# Ask CircleCI to select a subset of tests for this parallel execution.\n# If `parallelism` in CI config is set correctly, we should get just one but we can handle any split.\nselected_tests = subprocess.check_output(\n    ['circleci', 'tests', 'split'],\n    input='\\n'.join(tests_to_run_in_parallel),\n    encoding='ascii',\n).strip().split('\\n')\nselected_tests = set(selected_tests) - {''}\nexcluded_tests = set(tests_to_run_in_parallel) - selected_tests\nassert selected_tests.issubset(set(tests_to_run_in_parallel))\n\nif len(selected_tests) == 0:\n    print(\"No tests to run.\")\n    sys.exit(0)\n\nif '*' in selected_tests:\n    filters = [arg for test_name in excluded_tests for arg in ['--exclude', test_name]]\nelse:\n    filters = list(selected_tests)\n\ntry:\n    subprocess.run(\n        ['test/cmdlineTests.sh'] + filters,\n        stdin=sys.stdin,\n        stdout=sys.stdout,\n        stderr=sys.stderr,\n        check=True,\n    )\nexcept subprocess.CalledProcessError as exception:\n    sys.exit(exception)\n"
  },
  {
    "path": ".circleci/soltest.ps1",
    "content": "$ErrorActionPreference = \"Stop\"\n\ncd \"$PSScriptRoot\\..\"\n\n.\\build\\solc\\Release\\solc.exe --version\nif ( -not $? ) { throw \"Cannot execute solc --version.\" }\n\nmkdir test_results\n.\\build\\test\\Release\\soltest.exe --color_output=no --show_progress=yes --logger=JUNIT,error,test_results/result.xml --logger=HRF,error,stdout -- --no-smt\nif ( -not $? ) { throw \"Unoptimized soltest run failed.\" }\n.\\build\\test\\Release\\soltest.exe --color_output=no --show_progress=yes --logger=JUNIT,error,test_results/result_opt.xml --logger=HRF,error,stdout -- --optimize --no-smt\nif ( -not $? ) { throw \"Optimized soltest run failed.\" }\n"
  },
  {
    "path": ".circleci/soltest.sh",
    "content": "#!/usr/bin/env bash\n#------------------------------------------------------------------------------\n# Bash script to execute the Solidity tests by CircleCI.\n#\n# The documentation for solidity is hosted at:\n#\n#     https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# Configuration Environment Variables:\n#\n#     EVM=version_string      Specifies EVM version to compile for (such as homestead, etc)\n#     OPTIMIZE=1              Enables backend optimizer\n#     ABI_ENCODER_V1=1        Forcibly enables ABI coder version 1\n#     SOLTEST_FLAGS=<flags>   Appends <flags> to default SOLTEST_ARGS\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016-2019 solidity contributors.\n# ------------------------------------------------------------------------------\nset -e\n\nOPTIMIZE=${OPTIMIZE:-\"0\"}\nEVM=${EVM:-\"invalid\"}\nEOF_VERSION=${EOF_VERSION:-0}\nCPUs=${CPUs:-3}\nREPODIR=\"$(realpath \"$(dirname \"$0\")/..\")\"\n\nIFS=\" \" read -r -a BOOST_TEST_ARGS <<< \"$BOOST_TEST_ARGS\"\nIFS=\" \" read -r -a SOLTEST_FLAGS <<< \"$SOLTEST_FLAGS\"\n\n# TODO: [EOF] These won't pass on EOF yet. Reenable them when the implementation is complete.\nEOF_EXCLUDES=(\n    --run_test='!yulStackLayout/literal_loop'\n)\n\n# shellcheck source=scripts/common.sh\nsource \"${REPODIR}/scripts/common.sh\"\n# Test result output directory (CircleCI is reading test results from here)\nmkdir -p test_results\n\n# in case we run with ASAN enabled, we must increase stack size.\nulimit -s 16384\n\nget_logfile_basename() {\n    local run=\"$1\"\n    local filename=\"${EVM}\"\n    test \"${OPTIMIZE}\" = \"1\" && filename=\"${filename}_opt\"\n    test \"${ABI_ENCODER_V1}\" = \"1\" && filename=\"${filename}_abiv1\"\n    (( EOF_VERSION != 0 )) && filename=\"${filename}_eofv${EOF_VERSION}\"\n    filename=\"${filename}_${run}\"\n\n    echo -ne \"${filename}\"\n}\n\n[ -z \"$CIRCLE_NODE_TOTAL\" ] || [ \"$CIRCLE_NODE_TOTAL\" = 0 ] && CIRCLE_NODE_TOTAL=1\n[ -z \"$CIRCLE_NODE_INDEX\" ] && CIRCLE_NODE_INDEX=0\n[ -z \"$INDEX_SHIFT\" ] && INDEX_SHIFT=0\n\n# Multiply by a prime number to get better spread, just in case\n# long-running test cases are next to each other.\nCIRCLE_NODE_INDEX=$(((CIRCLE_NODE_INDEX + 23 * INDEX_SHIFT) % CIRCLE_NODE_TOTAL))\n\nPIDs=()\nfor run in $(seq 0 $((CPUs - 1)))\ndo\n    BOOST_TEST_ARGS_RUN=(\n        \"--color_output=no\"\n        \"--show_progress=yes\"\n        \"--logger=JUNIT,error,test_results/$(get_logfile_basename \"$((CPUs * CIRCLE_NODE_INDEX + run))\").xml\"\n        \"--logger=HRF,error,stdout\"\n        \"${BOOST_TEST_ARGS[@]}\"\n    )\n    (( EOF_VERSION != 0 )) && BOOST_TEST_ARGS_RUN+=(\"${EOF_EXCLUDES[@]}\")\n    SOLTEST_ARGS=(\"--evm-version=$EVM\" \"${SOLTEST_FLAGS[@]}\")\n\n    test \"${OPTIMIZE}\" = \"1\" && SOLTEST_ARGS+=(--optimize)\n    test \"${ABI_ENCODER_V1}\" = \"1\" && SOLTEST_ARGS+=(--abiencoderv1)\n    (( EOF_VERSION != 0 )) && SOLTEST_ARGS+=(--eof-version \"$EOF_VERSION\")\n\n    BATCH_ARGS=(\"--batches\" \"$((CPUs * CIRCLE_NODE_TOTAL))\" \"--selected-batch\" \"$((CPUs * CIRCLE_NODE_INDEX + run))\")\n\n    echo \"Running ${REPODIR}/build/test/soltest ${BOOST_TEST_ARGS_RUN[*]} -- ${SOLTEST_ARGS[*]}\"\n\n    \"${REPODIR}/build/test/soltest\" -l test_suite \"${BOOST_TEST_ARGS_RUN[@]}\" -- \"${SOLTEST_ARGS[@]}\" \"${BATCH_ARGS[@]}\" &\n    PIDs+=($!)\ndone\n\n# wait for individual processes to get their exit status\nfor pid in \"${PIDs[@]}\"\ndo\n    wait \"$pid\"\ndone\n"
  },
  {
    "path": ".circleci/soltest_all.sh",
    "content": "#! /bin/bash\n#------------------------------------------------------------------------------\n# Bash script to execute the Solidity tests by CircleCI.\n#\n# The documentation for solidity is hosted at:\n#\n#     https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016-2019 solidity contributors.\n# ------------------------------------------------------------------------------\nset -e\n\nREPODIR=\"$(realpath \"$(dirname \"$0\")\"/..)\"\n\n# shellcheck source=scripts/common.sh\nsource \"${REPODIR}/scripts/common.sh\"\n\nDEFAULT_EVM_VALUES=(\n    homestead\n    constantinople\n    istanbul\n    berlin\n    london\n    paris\n    shanghai\n    cancun\n    osaka\n)\nEVMS_WITH_EOF=(osaka)\n\n# Deserialize the EVM_VALUES array if it was provided as argument or\n# set EVM_VALUES to the default values.\nIFS=\" \" read -ra EVM_VALUES <<< \"${1:-${DEFAULT_EVM_VALUES[@]}}\"\n\nDEFAULT_EVM=osaka\nOPTIMIZE_VALUES=(0 1)\n# TODO: EOF is marked as experimental in evmone. Reenable when proper handling for that is added here.\nEOF_VERSIONS=(0)\n\n# Run for ABI encoder v1, without SMTChecker tests.\nEVM=\"${DEFAULT_EVM}\" \\\nOPTIMIZE=1 \\\nABI_ENCODER_V1=1 \\\nBOOST_TEST_ARGS=\"-t !smtCheckerTests\" \\\n\"${REPODIR}/.circleci/soltest.sh\"\n\n# We shift the batch index so that long-running tests\n# do not always run in the same executor for all EVM versions\nINDEX_SHIFT=0\nfor OPTIMIZE in \"${OPTIMIZE_VALUES[@]}\"\ndo\n    for EVM in \"${EVM_VALUES[@]}\"\n    do\n        for EOF_VERSION in \"${EOF_VERSIONS[@]}\"\n        do\n            if (( EOF_VERSION > 0 )) && [[ ! \" ${EVMS_WITH_EOF[*]} \" == *\" $EVM \"* ]]; then\n                continue\n            fi\n\n            ENFORCE_GAS_ARGS=\"\"\n            [ \"${EVM}\" = \"${DEFAULT_EVM}\" ] && ENFORCE_GAS_ARGS=\"--enforce-gas-cost\"\n            # Run SMTChecker tests only when OPTIMIZE == 0\n            DISABLE_SMTCHECKER=\"\"\n            [ \"${OPTIMIZE}\" != \"0\" ] && DISABLE_SMTCHECKER=\"-t !smtCheckerTests\"\n\n            EVM=\"$EVM\" \\\n            EOF_VERSION=\"$EOF_VERSION\" \\\n            OPTIMIZE=\"$OPTIMIZE\" \\\n            SOLTEST_FLAGS=\"$SOLTEST_FLAGS $ENFORCE_GAS_ARGS\" \\\n            BOOST_TEST_ARGS=\"-t !@nooptions $DISABLE_SMTCHECKER\" \\\n            INDEX_SHIFT=\"$INDEX_SHIFT\" \\\n            \"${REPODIR}/.circleci/soltest.sh\"\n\n            INDEX_SHIFT=$((INDEX_SHIFT + 1))\n        done\n    done\ndone\n"
  },
  {
    "path": ".clang-format",
    "content": "# Formatting approximately used in Solidity's C++\n#\n# See https://clang.llvm.org/docs/ClangFormatStyleOptions.html\n# For an online formatter to test settings, see\n# https://zed0.co.uk/clang-format-configurator/\n# Note that clang-format cannot express the style that closing parentheses\n# behave similar to closing curly braces in a multi-line setting in that\n# they have to be on a line of their own at the same indentation level\n# as the opening part (aka \"dangling parenthesis\", see https://reviews.llvm.org/D33029).\n\nLanguage: Cpp\nBasedOnStyle: LLVM\nAccessModifierOffset: -4\nAlignAfterOpenBracket: AlwaysBreak\nAlignEscapedNewlines: Left\nAlwaysBreakAfterReturnType: None\nAlwaysBreakTemplateDeclarations: Yes\nBinPackArguments: false\nBinPackParameters: false\nBreakBeforeBinaryOperators: All\nBreakBeforeBraces: Allman\nColumnLimit: 120\nContinuationIndentWidth: 4\nFixNamespaceComments: false\nIndentWidth: 4\nKeepEmptyLinesAtTheStartOfBlocks: false\nMaxEmptyLinesToKeep: 2\nPenaltyBreakBeforeFirstCallParameter: 2000\nPointerAlignment: Left\nSpaceAfterCStyleCast: true\nSpaceAfterTemplateKeyword: false\nSpaceBeforeCtorInitializerColon: false\nSpaceBeforeInheritanceColon: false\nSpaceBeforeParens: ControlStatements\nSpaceBeforeRangeBasedForLoopColon: false\nTabWidth: 4\nUseTab: Always\n\n# Local Variables:\n# mode: yaml\n# End:\n"
  },
  {
    "path": ".codespellrc",
    "content": "[codespell]\nskip = .git,deps,LICENSE,*.enc,Dockerfile*,codespell_whitelist.txt,codespell_ignored_lines.txt\nignore-words = scripts/codespell_whitelist.txt\nexclude-file = scripts/codespell_ignored_lines.txt\n"
  },
  {
    "path": ".dockerignore",
    "content": "# out-of-tree builds usually go here. This helps improving performance of uploading\n# the build context to the docker image build server\n/build\n\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.{cpp,h}]\nindent_style = tab\nindent_size = 4\n\n[*.{py,rst,sh,yml}]\nindent_style = space\nindent_size = 4\n\n[*.{sol,yul}]\nindent_style = space\nindent_size = 4\n\n[*.{txt,cmake,json}]\nindent_style = tab\nindent_size = 4\n"
  },
  {
    "path": ".gitattributes",
    "content": "*.sol linguist-language=Solidity\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "/docs/style-guide.rst @fulldecent\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug Report\nabout: Problems, deficiencies, inaccuracies or crashes discovered on Solidity.\ntitle: ''\nlabels: 'bug :bug:'\nassignees: ''\n\n---\n\n<!--## Prerequisites\n\n- First, many thanks for taking part in the community. We really appreciate that.\n- We realize there is a lot of information requested here. We ask only that you do your best to provide as much information as possible so we can better help you.\n- Support questions are better asked in one of the following locations:\n    - [Solidity chat](https://gitter.im/ethereum/solidity)\n    - [Stack Overflow](https://ethereum.stackexchange.com/)\n- Ensure the issue isn't already reported.\n- The issue should be reproducible with the latest solidity version; however, this isn't a hard requirement and being reproducible with an older version is sufficient.\n-->\n\n## Description\n\n<!--Please shortly describe the bug you have found, and what you expect instead.-->\n\n## Environment\n\n- Compiler version:\n- Compilation pipeline (legacy, IR, EOF):\n- Target EVM version (as per compiler settings):\n- Framework/IDE (e.g. Foundry, Hardhat, Remix):\n- EVM execution environment / backend / blockchain client:\n- Operating system:\n\n## Steps to Reproduce\n\n<!--\nPlease provide a *minimal* source code example to trigger the bug you have found.\nPlease also mention any command-line flags that are necessary for triggering the bug.\nProvide as much information as necessary to reproduce the bug.\n\n```solidity\n// Some *minimal* Solidity source code to reproduce the bug.\n// ...\n```\n-->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Initiate a language design or feedback discussion\n    url: https://forum.soliditylang.org\n    about: Open a thread on the Solidity forum.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/documentation_issue.md",
    "content": "---\nname: Documentation Issue\nabout: Corrections, improvements or requests for new content on Solidity's documentation.\ntitle: ''\nlabels: 'documentation :book:'\nassignees: ''\n\n---\n\n## Page\n\n<!--Please link directly to the page which you think has a problem.-->\n\n## Abstract\n\n<!--Please describe in detail what is wrong.-->\n\n## Pull request\n\n<!--Please link to your pull request which resolves this issue.-->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature Request\nabout: Ideas, comments or messages asking for a particular functionality to be added\n  to Solidity.\ntitle: ''\nlabels: feature\nassignees: ''\n\n---\n\n<!--## Prerequisites\n\n- First, many thanks for taking part in the community. We really appreciate that.\n- We realize there is a lot of data requested here. We ask only that you do your best to provide as much information as possible so we can better help you.\n- Support questions are better asked in one of the following locations:\n    - [Solidity chat](https://gitter.im/ethereum/solidity)\n    - [Stack Overflow](https://ethereum.stackexchange.com/)\n- Ensure the issue isn't already reported (check `feature` and `language design` labels).\n- If you feel uncertain about your feature request, perhaps it's better to open a language design or feedback forum thread via the issue selector, or by going to the forum directly.\n    - [Solidity forum](https://forum.soliditylang.org/)\n-->\n\n## Abstract\n\n<!--Please describe by example what problem you see in the current Solidity language and reason about it.-->\n\n## Motivation\n\n<!--In this section you describe how you propose to address the problem you described earlier, including by giving one or more exemplary source code snippets for demonstration.-->\n\n## Specification\n\n<!--The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow any developer to implement the functionality.-->\n\n## Backwards Compatibility\n\n<!--\nAll language changes that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity.\n\nPlease describe how you propose to deal with these incompatibilities.\n-->\n"
  },
  {
    "path": ".github/workflows/buildpack-deps.yml",
    "content": "name: buildpack-deps\n\npermissions:\n  packages: write\n  pull-requests: write\n\non:\n  pull_request:\n    branches: [ develop ]\n    paths:\n      - 'scripts/docker/buildpack-deps/Dockerfile.emscripten'\n      - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz'\n      - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404'\n      - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang'\n      - 'scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.arm'\n\njobs:\n  buildpack-deps:\n    runs-on: ${{ matrix.runs-on }}\n\n    env:\n      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      DOCKER_REPOSITORY: ghcr.io/argotorg/solidity-buildpack-deps\n      IMAGE_NAME: buildpack-deps\n\n    strategy:\n      fail-fast: false\n      matrix:\n        include:\n          - image_variant: emscripten\n            runs-on: ubuntu-latest\n          - image_variant: ubuntu.clang.ossfuzz\n            runs-on: ubuntu-latest\n          - image_variant: ubuntu2404\n            runs-on: ubuntu-latest\n          - image_variant: ubuntu2404.clang\n            runs-on: ubuntu-latest\n          - image_variant: ubuntu2404.arm\n            runs-on: ubuntu-24.04-arm\n\n    steps:\n      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0\n        with:\n          fetch-depth: 0\n\n      - name: Log in to GitHub Container Registry\n        uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Upgrade ${{ env.IMAGE_NAME }}-${{ matrix.image_variant }}\n        run: |\n          scripts/ci/docker_upgrade.sh ${{ env.IMAGE_NAME }} ${{ matrix.image_variant }} ${{ env.DOCKER_REPOSITORY }}\n\n      - name: comment PR\n        if: \"env.DOCKER_IMAGE\"\n        uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1\n        with:\n          message: \"`${{ env.DOCKER_IMAGE }} ${{ env.DOCKER_REPO_DIGEST }}`.\"\n"
  },
  {
    "path": ".github/workflows/stale.yml",
    "content": "name: Check stale pull requests\n\non:\n  workflow_dispatch:\n  schedule:\n    - cron: '0 12 * * *'\n\npermissions:\n  pull-requests: write\n\nenv:\n  # NOTE: We set the parameters below to -1, so issues will never be marked as stale or closed automatically.\n  BEFORE_ISSUE_STALE: -1\n  BEFORE_ISSUE_CLOSE: -1\n  BEFORE_PR_STALE: 14\n  BEFORE_PR_CLOSE: 7\n\njobs:\n  stale:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0\n        with:\n          debug-only: false\n          days-before-issue-stale: ${{ env.BEFORE_ISSUE_STALE }}\n          days-before-issue-close: ${{ env.BEFORE_ISSUE_CLOSE }}\n          ascending: true\n          stale-pr-message: |\n            This pull request is stale because it has been open for ${{ env.BEFORE_PR_STALE }} days with no activity.\n            It will be closed in ${{ env.BEFORE_PR_CLOSE }} days unless the `stale` label is removed.\n          close-pr-message: |\n            This pull request was closed due to a lack of activity for ${{ env.BEFORE_PR_CLOSE }} days after it was stale.\n          stale-pr-label: stale\n          close-pr-label: closed-due-inactivity\n          days-before-pr-stale: ${{ env.BEFORE_PR_STALE }}\n          days-before-pr-close: ${{ env.BEFORE_PR_CLOSE }}\n          exempt-pr-labels: 'external contribution :star:,roadmap,epic'\n          exempt-draft-pr: false\n          exempt-all-milestones: true\n          remove-stale-when-updated: true\n          operations-per-run: 256\n"
  },
  {
    "path": ".github/workflows/welcome-external-pr.yml",
    "content": "name: External contributor greeter\n\non:\n  pull_request_target:\n    types:\n      - opened\n\npermissions:\n  pull-requests: write\n  contents: read\n\nenv:\n  DRY_RUN: false\n\njobs:\n  comment-external-pr:\n    runs-on: ubuntu-latest\n    steps:\n      # Note: this step requires that the INTERNAL_CONTRIBUTORS environment variable\n      # is already defined in the repository with the current json list of internal contributors.\n      - name: Comment on external contribution PR\n        if: \"!contains(fromJSON(vars.INTERNAL_CONTRIBUTORS), github.event.pull_request.user.login)\"\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          PR: ${{ github.event.pull_request.html_url }}\n        run: |\n          echo \"Commenting in a newly submitted or reopened external PR: $PR\"\n          if [[ $DRY_RUN == 'false' ]]; then\n            gh pr edit \"$PR\" --add-label \"external contribution :star:\"\n            comment_body=(\n              \"Thank you for your contribution to the Solidity compiler! A team member will follow up shortly.\"\n              \"\\n\\n\"\n              \"If you haven't read our [contributing guidelines](https://docs.soliditylang.org/en/latest/contributing.html) and our \"\n              \"[review checklist](https://github.com/argotorg/solidity/blob/develop/ReviewChecklist.md) before, \"\n              \"please do it now, this makes the reviewing process and accepting your contribution smoother.\"\n              \"\\n\\n\"\n              \"If you have any questions or need our help, feel free to post them in the PR or talk to us directly on the \"\n              \"[#solidity-dev](https://matrix.to/#/#ethereum_solidity-dev:gitter.im) channel on Matrix.\"\n            )\n            gh pr comment $PR --body \"$(IFS='' ; echo -e \"${comment_body[*]}\")\"\n          fi\n"
  },
  {
    "path": ".gitignore",
    "content": "/commit_hash.txt\n/prerelease.txt\n\n# Compiled Object files\n*.slo\n*.lo\n*.o\n*.obj\n*.pyc\n__pycache__/\n\n# Precompiled Headers\n*.gch\n*.pch\n\n# Compiled Dynamic libraries\n*.so\n*.dylib\n*.dll\n\n# Compiled Static libraries\n*.lai\n*.la\n*.a\n*.lib\n\n# ignore git mergetool backup files\n*.orig\n\n# Executables\n*.exe\n*.out\n*.app\n\n# Build directory\n/cmake-build-*/\n/build*/\nemscripten_build/\n/docs/_build/\n/docs/_static/robots.txt\n/deps/\n\n# Reports and benchmarks\n/reports/\n/benchmarks/\n\n# vim stuff\n[._]*.sw[a-p]\n[._]sw[a-p]\n\n# emacs stuff\n*~\n\n# IDE files\n/.idea/\n/.vscode/\n/browse.VC.db\n/CMakeLists.txt.user\n/CMakeSettings.json\n/.vs\n/.cproject\n/.project\n\n# OS specific local files\n.DS_Store\nThumbs.db\n\n# AI tooling\n/.claude/\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"deps/nlohmann-json\"]\n\tpath = deps/nlohmann-json\n\turl = https://github.com/nlohmann/json.git\n[submodule \"deps/range-v3\"]\n\tpath = deps/range-v3\n\turl = https://github.com/ericniebler/range-v3.git\n[submodule \"deps/fmtlib\"]\n\tpath = deps/fmtlib\n\turl = https://github.com/fmtlib/fmt.git\n"
  },
  {
    "path": ".readthedocs.yml",
    "content": "version: 2\n\nbuild:\n  os: ubuntu-24.04\n  tools:\n    python: \"3.13\"\n\nsphinx:\n  builder: html\n  configuration: docs/conf.py\n\nformats:\n  - pdf\n  - epub\n\npython:\n  install:\n    - requirements: docs/requirements.txt\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.13.0)\n\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\nset(ETH_CMAKE_DIR   \"${CMAKE_CURRENT_LIST_DIR}/cmake\"   CACHE PATH \"The path to the cmake directory\")\nlist(APPEND CMAKE_MODULE_PATH ${ETH_CMAKE_DIR})\n\n# Set the build type, if none was specified.\nif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)\n\tif(EXISTS \"${PROJECT_SOURCE_DIR}/.git\")\n\t\tset(DEFAULT_BUILD_TYPE \"RelWithDebInfo\")\n\telse()\n\t\tset(DEFAULT_BUILD_TYPE \"Release\")\n\tendif()\n\tset(CMAKE_BUILD_TYPE \"${DEFAULT_BUILD_TYPE}\" CACHE STRING \"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel\" FORCE)\n\tset_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS \"Debug\" \"Release\" \"RelWithDebInfo\" \"MinSizeRel\")\nendif()\n\ninclude(EthToolchains)\n\n# Set cmake_policies\ninclude(EthPolicy)\neth_policy()\n\n# project name and version should be set after cmake_policy CMP0048\nset(PROJECT_VERSION \"0.8.35\")\n# OSX target needed in order to support std::visit\nset(CMAKE_OSX_DEPLOYMENT_TARGET \"10.14\")\nproject(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX)\n\ninclude(TestBigEndian)\nTEST_BIG_ENDIAN(IS_BIG_ENDIAN)\nif (IS_BIG_ENDIAN)\n\tmessage(FATAL_ERROR \"${PROJECT_NAME} currently does not support big endian systems.\")\nendif()\n\noption(SOLC_LINK_STATIC \"Link solc executable statically on supported platforms\" OFF)\noption(SOLC_STATIC_STDLIBS \"Link solc against static versions of libgcc and libstdc++ on supported platforms\" OFF)\noption(STRICT_Z3_VERSION \"Require the exact version of Z3 solver expected by our test suite.\" ON)\noption(PEDANTIC \"Enable extra warnings and pedantic build flags. Treat all warnings as errors.\" ON)\noption(PROFILE_OPTIMIZER_STEPS \"Output performance metrics for the optimiser steps.\" OFF)\noption(\n\tIGNORE_VENDORED_DEPENDENCIES\n\t\"Ignore libraries provided as submodules of the repository and allow CMake to look for \\\nthem in the typical locations, including system-wide dirs.\"\n\tOFF\n)\noption(\n\tONLY_BUILD_SOLIDITY_LIBRARIES\n\t\"Only build library targets that can be statically linked against. Do not build executables or tests.\"\n\tOFF\n)\nmark_as_advanced(PROFILE_OPTIMIZER_STEPS)\nmark_as_advanced(IGNORE_VENDORED_DEPENDENCIES)\nmark_as_advanced(ONLY_BUILD_SOLIDITY_LIBRARIES)\n\n# Setup cccache.\ninclude(EthCcache)\n\n# Let's find our dependencies\ninclude(EthDependencies)\nif (NOT IGNORE_VENDORED_DEPENDENCIES)\n  include(fmtlib)\n  include(nlohmann-json)\n  include(range-v3)\nelse ()\n  message(WARNING \"-- Ignoring vendored dependencies. Will use installed versions if found. Versions may differ from the ones the compiler was tested with. Make sure to run the test suite and thoroughly test the resulting binaries before using them in production.\")\n  find_package(fmt REQUIRED)\n  find_package(nlohmann_json REQUIRED)\n  find_package(range-v3 REQUIRED)\nendif()\n\nfind_package(Threads)\n\nif(NOT PEDANTIC)\n  message(WARNING \"-- Pedantic build flags turned off. Warnings will not make compilation fail. This is NOT recommended in development builds.\")\nendif()\n\nif (PROFILE_OPTIMIZER_STEPS)\n    add_definitions(-DPROFILE_OPTIMIZER_STEPS)\nendif()\n\n# Figure out what compiler and system are we using\ninclude(EthCompilerSettings)\n\n# Include utils\ninclude(EthUtils)\n\n# Create license.h from LICENSE.txt and template\n# Converting to char array is required due to MSVC's string size limit.\nfile(READ ${PROJECT_SOURCE_DIR}/LICENSE.txt LICENSE_TEXT HEX)\nstring(REGEX MATCHALL \"..\" LICENSE_TEXT \"${LICENSE_TEXT}\")\nstring(REGEX REPLACE \";\" \",\\n\\t0x\" LICENSE_TEXT \"${LICENSE_TEXT}\")\nset(LICENSE_TEXT \"0x${LICENSE_TEXT}\")\n\nconfigure_file(\"${PROJECT_SOURCE_DIR}/cmake/templates/license.h.in\" include/license.h)\n\ninclude(EthOptions)\nconfigure_project(TESTS)\n\nif(EMSCRIPTEN)\n    set(TESTED_Z3_VERSION \"4.13.3\")\n    set(MINIMUM_Z3_VERSION \"4.8.16\")\n    find_package(Z3)\n    if (${Z3_FOUND})\n      add_definitions(-DEMSCRIPTEN_BUILD)\n      if (${STRICT_Z3_VERSION})\n        if (NOT (\"${Z3_VERSION_STRING}\" VERSION_EQUAL ${TESTED_Z3_VERSION}))\n          message(\n            FATAL_ERROR\n            \"SMTChecker tests require Z3 ${TESTED_Z3_VERSION} for all tests to pass.\\n\"\n          )\n        endif()\n      else()\n        if (\"${Z3_VERSION_STRING}\" VERSION_LESS ${MINIMUM_Z3_VERSION})\n          message(\n            FATAL_ERROR\n            \"Solidity requires Z3 ${MINIMUM_Z3_VERSION} or newer.\"\n          )\n        endif()\n      endif()\n    else()\n        message(FATAL_ERROR \"Solidity requires Z3 for emscripten build.\")\n    endif()\nendif()\n\nadd_subdirectory(libsolutil)\nadd_subdirectory(liblangutil)\nadd_subdirectory(libsmtutil)\nadd_subdirectory(libevmasm)\nadd_subdirectory(libyul)\nadd_subdirectory(libsolidity)\nadd_subdirectory(libsolc)\nadd_subdirectory(libstdlib)\n\nif (NOT ONLY_BUILD_SOLIDITY_LIBRARIES)\n\tadd_subdirectory(tools)\n\n\tif (NOT EMSCRIPTEN)\n\t\tadd_subdirectory(solc)\n\tendif()\n\n\tif (TESTS AND NOT EMSCRIPTEN)\n\t\tadd_subdirectory(test)\n\tendif()\nendif()\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to make participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, sex characteristics, gender identity and expression,\nlevel of experience, education, socioeconomic status, nationality, personal\nappearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\n  advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at solidity@ethereum.org.\nTo report an issue involving the Solidity team please email José Pedro Cabrita at zepedro@ethereum.org.\nAll complaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html\n\n[homepage]: https://www.contributor-covenant.org\n"
  },
  {
    "path": "CODING_STYLE.md",
    "content": "## 0. Formatting\n\n**GOLDEN RULE**: Follow the style of the existing code when you make changes.\n\n1. Use tabs for leading indentation:\n   - tab stops are every 4 characters (only relevant for line length).\n   - one indentation level -> exactly one byte (i.e. a tab character) in the source file.\n2. Line widths:\n   - Lines should be at most 99 characters wide to make diff views readable and reduce merge conflicts.\n   - Lines of comments should be formatted according to ease of viewing, but simplicity is to be preferred over beauty.\n3. Single-statement blocks should not have braces, unless required for clarity.\n4. Never place condition bodies on same line as condition.\n5. Space between keyword and opening parenthesis, but not following opening parenthesis or before final parenthesis.\n6. No spaces for unary operators, `->` or `.`.\n7. No space before `:` but one after it, except in the ternary operator: one on both sides.\n8. Add spaces around all other operators.\n9. Braces, when used, always have their own lines and are at same indentation level as \"parent\" scope.\n10. If lines are broken, a list of elements enclosed with parentheses (of any kind) and separated by a separator (of any kind) are formatted such that there is exactly one element per line, followed by the separator, the opening parenthesis is on the first line, followed by a line break and the closing parenthesis is on a line of its own unindented). See example below.\n\nYes:\n```cpp\nif (a == b[i])\n    printf(\"Hello\\n\"); // NOTE spaces used instead of tab here for clarity - first byte should be '\\t'.\nfoo->bar(\n    someLongVariableName,\n    anotherLongVariableName,\n    anotherLongVariableName,\n    anotherLongVariableName,\n    anotherLongVariableName\n);\ncout <<\n    \"some very long string that contains completely irrelevant \" <<\n    \"text that talks about this and that and contains the words \" <<\n    \"\\\"lorem\\\" and \\\"ipsum\\\"\" <<\n    endl;\n```\n\nNo:\n```cpp\nif( a==b[ i ] ) { printf (\"Hello\\n\"); }\nfoo->bar(someLongVariableName,\n         anotherLongVariableName,\n         anotherLongVariableName,\n         anotherLongVariableName,\n         anotherLongVariableName);\ncout << \"some very long string that contains completely irrelevant text that talks about this and that and contains the words \\\"lorem\\\" and \\\"ipsum\\\"\" << endl;\n```\n\nTo set indentation and tab width settings uniformly, the repository contains an [EditorConfig](https://editorconfig.org/) [`.editorconfig`](https://github.com/argotorg/solidity/blob/develop/.editorconfig) file, which describes some of the styles used and which is recognized by many IDE's and editors.\n\n## 1. Namespaces\n\n1. No `using namespace` declarations in header files.\n2. `using namespace solidity;` and other project local namespaces is fine in cpp files, and generally encouraged.\n3. Avoid `using namespace` at file level for third party libraries, such as boost, ranges, etc.\n4. All symbols should be declared in a namespace except for final applications.\n5. Use anonymous namespaces for helpers whose scope is a cpp file only.\n6. Preprocessor symbols should be prefixed with the namespace in all-caps and an underscore.\n\nOnly in the header:\n```cpp\n#include <cassert>\nnamespace myNamespace\n{\nstd::tuple<float, float> meanAndSigma(std::vector<float> const& _v);\n}\n```\n\n## 2. Preprocessor\n\n1. File comment is always at top, and includes:\n   - Copyright\n   - License (e.g. see COPYING)\n2. Never use `#ifdef`/`#define`/`#endif` file guards. Prefer `#pragma` once as first line below file comment.\n3. Prefer static constexpr variables to value macros.\n4. Prefer inline constexpr functions to function macros.\n5. Split complex macro on multiple lines with `\\`.\n\n## 3. Capitalization\n\n**GOLDEN RULE**: Preprocessor: `ALL_CAPS`; C++: `camelCase`.\n\n1. Use camelCase for splitting words in names, except where obviously extending STL/boost functionality in which case follow those naming conventions.\n2. The following entities' first alpha is upper case:\n   - Type names\n   - Template parameters\n   - Enum members\n   - static const variables that form an external API.\n3. All preprocessor symbols (macros, macro arguments) in full uppercase with underscore word separation.\n\nAll other entities' first alpha is lower case.\n\n## 4. Variable prefixes\n\n1. Leading underscore \"_\" to parameter names:\n   - Exception: \"o_parameterName\" when it is used exclusively for output. See 6(f).\n   - Exception: \"io_parameterName\" when it is used for both input and output. See 6(f).\n2. Leading \"g_\" to global (non-const) variables.\n3. Leading \"s_\" to static (non-const, non-global) variables.\n\n## 5. Assertions\n\nUse `solAssert` and `solUnimplementedAssert` generously to check assumptions that span across different parts of the code base, for example before dereferencing a pointer.\n\n## 6. Declarations\n\n1. {Typename} + {qualifiers} + {name}.\n2. Only one per line.\n3. Associate */& with type, not variable (at ends with parser, but more readable, and safe if in conjunction with (b)).\n4. Favour declarations close to use; do not habitually declare at top of scope ala C.\n5. 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.\n6. If a function returns multiple values, use std::tuple (std::pair acceptable) or better introduce a struct type. Do not use */& arguments.\n7. 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.\n8. Never use a macro where adequate non-preprocessor C++ can be written.\n9. Only use `auto` if the type is very long and rather irrelevant.\n10. Do not pass bools: prefer enumerations instead.\n11. Prefer enum class to straight enum.\n12. Always initialize POD variables, even if their value is overwritten later.\n\nYes:\n```cpp\nenum class Accuracy\n{\n\tApproximate,\n\tExact\n};\nstruct MeanSigma\n{\n\tfloat mean = 0.0f;\n\tfloat standardDeviation = 1.0f;\n};\ndouble const d = 0;\nint i = 0;\nint j = 0;\nchar* s = nullptr;\nMeanAndSigma ms meanAndSigma(std::vector<float> const& _v, Accuracy _a);\nDerived* x = dynamic_cast<Derived*>(base);\nfor (auto i = x->begin(); i != x->end(); ++i) {}\n```\n\nNo:\n```cpp\nconst double d = 0;\nint i, j;\nchar *s;\nfloat meanAndSigma(std::vector<float> _v, float* _sigma, bool _approximate);\nDerived* x(dynamic_cast<Derived*>(base));\nfor (map<ComplexTypeOne, ComplexTypeTwo>::iterator i = l.begin(); i != l.end(); ++l) {}\n```\n\n## 7. Structs & classes\n\n1. Structs to be used when all members public and no virtual functions:\n   - In this case, members should be named naturally and not prefixed with `m_`.\n2. Classes to be used in all other circumstances.\n\n## 8. Members\n\n1. One member per line only.\n2. Private, non-static, non-const fields prefixed with `m_`.\n3. Avoid public fields, except in structs.\n4. Use override, final and const as much as possible.\n5. No implementations with the class declaration, except:\n   - template or force-inline method (though prefer implementation at bottom of header file).\n   - one-line implementation (in which case include it in same line as declaration).\n6. For a property `foo`\n   - Member: `m_foo`\n   - Getter: `foo()` [ also: for booleans, `isFoo()` ]\n   - Setter: `setFoo()`\n\n## 9. Naming\n\n1. Avoid unpronounceable names.\n2. Names should be shortened only if they are extremely common, but shortening should be generally avoided\n3. Avoid prefixes of initials (e.g. do not use `IMyInterface`, `CMyImplementation`)\n4. Find short, memorable & (at least semi-) descriptive names for commonly used classes or name-fragments:\n   - A dictionary and thesaurus are your friends;\n   - Spell correctly;\n   - Think carefully about the class's purpose;\n   - Imagine it as an isolated component to try to decontextualise it when considering its name;\n   - Don't be trapped into naming it (purely) in terms of its implementation.\n\n## 10. Type definitions\n\n1. Prefer `using` to `typedef`. e.g. `using ints = std::vector<int>;` rather than typedef `std::vector<int> ints;`\n2. Generally avoid shortening a standard form that already includes all important information:\n   - e.g. stick to `shared_ptr<X>` rather than shortening to `ptr<X>`.\n3. Where there are exceptions to this (due to excessive use and clear meaning), note the change prominently and use it consistently:\n   - e.g. `using Guard = std::lock_guard<std::mutex>;` ///< Guard is used throughout the codebase since it is clear in meaning and used commonly.\n4. In general expressions should be roughly as important/semantically meaningful as the space they occupy.\n5. Avoid introducing aliases for types unless they are very complicated. Consider the number of items a brain can keep track of at the same time.\n\n## 11. Commenting\n\n1. Comments should be doxygen-compilable, using @notation rather than \\notation.\n2. Document the interface, not the implementation:\n   - Documentation should be able to remain completely unchanged, even if the method is reimplemented;\n   - Comment in terms of the method properties and intended alteration to class state (or what aspects of the state it reports);\n   - Be careful to scrutinise documentation that extends only to intended purpose and usage;\n   - Reject documentation that is simply an English transaction of the implementation.\n3. Avoid in-code comments. Instead, try to extract blocks of functionality into functions. This often already eliminates the need for an in-code comment.\n\n## 12. Include Headers\n\n1. Includes should go in increasing order of generality (`libsolidity` -> `libevmasm` -> `libsolutil` -> `boost` -> `STL`).\n2. The corresponding `.h` file should be the first include in the respective `.cpp` file.\n3. Insert empty lines between blocks of include files.\n\nExample:\n```cpp\n#include <libsolidity/codegen/ExpressionCompiler.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/codegen/CompilerContext.h>\n#include <libsolidity/codegen/CompilerUtils.h>\n#include <libsolidity/codegen/LValue.h>\n\n#include <libevmasm/GasMeter.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/SHA3.h>\n\n#include <boost/range/adaptor/reversed.hpp>\n#include <boost/algorithm/string/replace.hpp>\n\n#include <utility>\n#include <numeric>\n```\n\nSee [this issue](https://stackoverflow.com/questions/614302/c-header-order/614333#614333 \"C header order\") for the reason: this makes it easier to find missing includes in header files.\n\n## 13. Recommended reading\n\n- Herb Sutter and Bjarne Stroustrup:\n  - [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)\n\n- Herb Sutter and Andrei Alexandrescu:\n  - \"C++ Coding Standards: 101 Rules, Guidelines, and Best Practices\"\n\n- Scott Meyers:\n  - \"Effective C++: 55 Specific Ways to Improve Your Programs and Designs (3rd Edition)\"\n  - \"More Effective C++: 35 New Ways to Improve Your Programs and Designs\"\n  - \"Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14\"\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contribution Guidelines\n\nPlease see our contribution guidelines in [the Solidity documentation](https://docs.soliditylang.org/en/latest/contributing.html).\n\nThank you for your help!\n"
  },
  {
    "path": "Changelog.md",
    "content": "### 0.8.35 (unreleased)\n\nLanguage Features:\n* General: Add a builtin that computes the base slot of a storage namespace using the `erc7201` formula from ERC-7201.\n\nCompiler Features:\n* Commandline Interface: Disallow selecting the deprecated assembly input mode that was only accessible via `--assemble` instead of treating it as equivalent to `--strict-assembly`.\n* Commandline Interface: Introduce `--experimental` flag required for enabling the experimental mode.\n* General: Introduce the SSA CFG codegen (experimental).\n* General: Restrict the existing experimental features (`generic-solidity`, `lsp`, `ethdebug`, `eof`, `evm`, `ast-import`, `evmasm-import`, `ir-ast`, `ssa-cfg`) to experimental mode.\n* Metadata: Store the state of the experimental mode in JSON and CBOR metadata. In CBOR this broadens the meaning of the existing `experimental` field, which used to indicate only the presence of certain experimental pragmas in the source.\n* Standard JSON Interface: Introduce `settings.experimental` setting required for enabling the experimental mode.\n* Yul Optimizer: Improve performance of control flow side effects collector and function references resolver.\n\nBugfixes:\n* Yul: Fix incorrect serialization of Yul object names containing double quotes and escape sequences, producing output that could not be parsed as valid Yul.\n* Yul EVM Code Transform: Improve stack shuffler performance by fixing a BFS deduplication issue.\n\n\n### 0.8.34 (2026-02-18)\n\nImportant Bugfixes:\n* Yul IR Code Generation: Fix a bug that could result in clearing a storage variable instead of a transient storage variable at the same position in the layout (and vice-versa).\n\n\nCompiler Features:\n* Yul Optimizer: Remove redundant prerequisite steps from the default optimizer sequence.\n\n\n### 0.8.33 (2025-12-18)\n\nBugfixes:\n* TypeChecker: Fix internal error when accessing getters of constant variables.\n\n\n### 0.8.32 (2025-12-18)\n\nImportant Bugfixes:\n* Code Generator: Fix a bug in clearing/copying of arrays that straddle the end of storage, potentially resulting in assignment/initialization/`delete`/`push()`/`pop()` skipping some or all of the intended storage writes.\n\n\nBugfixes:\n* Codegen: Fix internal compiler error when emitting events via module member access.\n* TypeChecker: Fix error and event selectors not being considered compile-time constant.\n* TypeChecker: Fix `string.concat` and `bytes.concat` with constant arguments not being considered compile-time constant.\n\n\n### 0.8.31 (2025-12-03)\n\nLanguage Features:\n* Custom Storage Layout: Allow using `constant` state variables in the base slot expression.\n* DocString Parser: Warn about deprecation of inline assembly special comment `memory-safe-assembly`.\n* Syntax Checker: Warn about deprecation of ABI coder v1.\n* Syntax Checker: Warn about deprecation of virtual modifiers.\n* Type Checker: Warn about deprecation of `send` and `transfer` functions on instances of `address`.\n* Type Checker: Warn about deprecation of comparisons between variables of contract types.\n* Yul: Introduce builtin `clz(x)` for counting the number of leading zero bits in a 256-bit word.\n\n\nCompiler Features:\n* ethdebug: Experimental support for instructions and source locations under EOF.\n* EVM: Set default EVM Version to `osaka`.\n\n\nBugfixes:\n* Assembler: Fix not using a fixed-width type for IDs being assigned to subassemblies nested more than one level away, resulting in inconsistent `--asm-json` output between target architectures.\n* Yul Optimizer: Fix edge case in which invalid Yul code is produced by ExpressionSimplifier due to expressions being substituted that contain out-of-scope variables.\n\n\nBuild System:\n* Enable Linux arm64 binaries for testing and releases.\n* Ubuntu PPA Packages: Discontinue the PPA as a binary distribution channel.\n* Update minimum version requirements of Boost to 1.83.0 for non-windows builds and of GCC and Clang to 13.3 and 18.1.3, respectively. Fixes infinite recursion on `boost::rational` comparison affecting compiler binaries built with GCC<14.0 and Boost<1.75.\n\n\n### 0.8.30 (2025-05-07)\n\nCompiler Features:\n* EVM: Set default EVM Version to `prague`.\n* NatSpec: Capture Natspec documentation of `enum` values in the AST.\n\n\nBugfixes:\n* SMTChecker: Do not consider loop conditions as constant-condition verification target as this could cause incorrect reports and internal compiler errors.\n* SMTChecker: Fix incorrect analysis when only a subset of contracts is selected with `--model-checker-contracts`.\n* SMTChecker: Fix internal compiler error when string literal is used to initialize user-defined type based on fixed bytes.\n\n\n### 0.8.29 (2025-03-12)\n\nLanguage Features:\n * Allow relocating contract storage to an arbitrary location.\n\n\nCompiler Features:\n * Error Reporting: Errors reported during code generation now point at the location of the contract when more fine-grained location is not available.\n * ethdebug: Experimental support for instructions and source locations.\n * EVM: Support for the EVM version \"Osaka\".\n * EVM Assembly Import: Allow enabling opcode-based optimizer.\n * General: The experimental EOF backend implements a subset of EOF sufficient to compile arbitrary high-level Solidity syntax via IR with optimization enabled.\n * SMTChecker: Support ``block.blobbasefee`` and ``blobhash``.\n * SMTChecker: The option ``--model-checker-print-query`` no longer requires ``--model-checker-solvers smtlib2``.\n * SMTChecker: Z3 is now a runtime dependency, not a build dependency (except for emscripten build).\n * Yul Parser: Make name clash with a builtin a non-fatal error.\n\n\nBugfixes:\n * Commandline Interface: Report StackTooDeep errors in compiler mode as proper errors instead of printing diagnostic information meant for internal compiler errors.\n * Error Reporting: Fix error locations not being shown for source files with empty names.\n * General: Fix internal compiler error when requesting IR AST outputs for interfaces and abstract contracts.\n * Metadata: Fix custom cleanup sequence missing from metadata when other optimizer settings have default values.\n * SMTChecker: Fix internal compiler error when analyzing overflowing expressions or bitwise negation of unsigned types involving constants.\n * SMTChecker: Fix reporting on targets that are safe in the context of one contract but unsafe in the context of another contract.\n * SMTChecker: Fix SMT logic error when analyzing cross-contract getter call with BMC.\n * SMTChecker: Fix SMT logic error when contract deployment involves string literal to fixed bytes conversion.\n * SMTChecker: Fix SMT logic error when external call has extra effectless parentheses.\n * SMTChecker: Fix SMT logic error when initializing a fixed-sized-bytes array using string literals.\n * SMTChecker: Fix SMT logic error when translating invariants involving array store and select operations.\n * SMTChecker: Fix wrong encoding of string literals as arguments of ``ecrecover`` precompile.\n * Standard JSON Interface: Fix ``generatedSources`` and ``sourceMap`` being generated internally even when not requested.\n * TypeChecker: Fix spurious compilation errors due to incorrect computation of contract storage size which erroneously included transient storage variables.\n * Yul: Fix internal compiler error when a code generation error should be reported instead.\n * Yul Optimizer: Fix failing debug assertion due to dereferencing of an empty ``optional`` value.\n\n\nBuild system:\n * Linux release builds are fully static again and no longer depend on ``glibc``.\n * Switch from C++17 to C++20 as the target standard.\n\n\nSolc-Js:\n * The wrapper now requires at least nodejs v12.\n\n### 0.8.28 (2024-10-09)\n\nLanguage Features:\n * Transient storage state variables of value types are now fully supported.\n\n\nCompiler Features:\n * General: Generate JSON representations of Yul ASTs only on demand to reduce memory usage.\n * Standard JSON Interface: Bytecode or IR can now be requested for a subset of all contracts without triggering unnecessary code generation for other contracts.\n\n\nBugfixes:\n * SMTChecker: Fix SMT logic error when assigning to an array of addresses.\n * Yul AST: Fix shifted native source locations when debug info selection included code snippets.\n\n\nBuild system:\n* Removed ``USE_LD_GOLD`` option and default to use the compiler default linker. For custom linkers, ``CMAKE_CXX_FLAGS`` can be used.\n\n\n### 0.8.27 (2024-09-04)\n\nLanguage Features:\n * Accept declarations of state variables with ``transient`` data location (parser support only, no code generation yet).\n * Make ``require(bool, Error)`` available when using the legacy pipeline.\n * Yul: Parsing rules for source location comments have been relaxed: Whitespace between the location components as well as single-quoted code snippets are now allowed.\n\n\nCompiler Features:\n * Commandline Interface: Add ``--transient-storage-layout`` output.\n * Commandline Interface: Allow the use of ``--asm-json`` output option in assembler mode to export EVM assembly of the contracts in JSON format.\n * Commandline Interface: Do not perform IR optimization when only unoptimized IR is requested.\n * Constant Optimizer: Uses ``PUSH0`` if supported by the selected evm version.\n * Error Reporting: Unimplemented features are now properly reported as errors instead of being handled as if they were bugs.\n * EVM: Support for the EVM version \"Prague\".\n * Peephole Optimizer: ``PUSH0``, when supported, is duplicated explicitly instead of using ``DUP1``.\n * Peephole Optimizer: Remove identical code snippets that terminate the control flow if they occur one after another.\n * SMTChecker: Add CHC engine check for underflow and overflow in unary minus operation.\n * SMTChecker: Replace CVC4 as a possible BMC backend with cvc5.\n * Standard JSON Interface: Add ``transientStorageLayout`` output.\n * Standard JSON Interface: Do not perform IR optimization when only unoptimized IR is requested.\n * Yul: Drop the deprecated typed Yul dialect that was only accessible via ``--yul`` in the CLI.\n * Yul: The presence of types in untyped Yul dialects is now a parser error.\n * Yul Optimizer: Caching of optimized IR to speed up optimization of contracts with bytecode dependencies.\n * Yul Optimizer: The optimizer now treats some previously unrecognized identical literals as identical.\n\n\nBugfixes:\n * Assembler: Fix ICE caused by imprecise calculation of required size of tags in bytecode when code size is above 255.\n * Parser: Fix spuriously emitted parser error for unary plus operations when used as binary operator in some cases.\n * SMTChecker: Fix error that reports invalid number of verified checks for BMC and CHC engines.\n * SMTChecker: Fix formatting of unary minus expressions in invariants.\n * SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine.\n * SMTChecker: Fix SMT logic error when assigning to an array of contracts or functions.\n * Standard JSON Interface: For Yul input, properly produce output artifacts in case of warnings.\n * TypeChecker: Fix segfault when assigning nested tuple to tuple.\n * Yul IR Code Generation: Deterministic order of Yul subobjects.\n * Yul Optimizer: Fix Yul source locations always referring to unoptimized source, even in optimized outputs.\n * Yul Optimizer: Fix warnings being generated twice when there are no errors.\n * Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``.\n * Yul Parser: Fix segfault when parsing very long location comments.\n\nBuild System:\n * Change build system to use git submodules for some dependencies (nlohmann-json, fmtlib & range-v3).\n\n### 0.8.26 (2024-05-21)\n\nLanguage Features:\n * Introduce a new overload ``require(bool, Error)`` that allows usage of ``require`` functions with custom errors. This feature is available in the ``via-ir`` pipeline only.\n\n\nCompiler Features:\n * SMTChecker: Create balance check verification target for CHC engine.\n * Yul IR Code Generation: Cheaper code for reverting with errors of a small static encoding size.\n * Yul Optimizer: New, faster default optimizer step sequence.\n\n\nBugfixes:\n * Commandline Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``--yul-optimizations`` sequence.\n * SMTChecker: Fix false positive when comparing hashes of same array or string literals.\n * SMTChecker: Fix internal error on mapping access caused by too strong requirements on sort compatibility of the index and mapping domain.\n * SMTChecker: Fix internal error when using an empty tuple in a conditional operator.\n * SMTChecker: Fix internal error when using bitwise operators with an array element as argument.\n * Standard JSON Interface: Fix ICE when the optimizer is disabled and an empty/blank string is used for ``optimizerSteps`` sequence.\n * StaticAnalyzer: Only raise a compile time error for division and modulo by zero when it's between literals.\n * TypeChecker: Fix compiler crash when the left-hand side of an assignment was a parenthesized non-tuple expression of a tuple type.\n * Yul Optimizer: Fix optimizer executing each repeating part of the step sequence at least twice, even if the code size already became stable after the first iteration.\n * Yul Optimizer: Fix the order of assignments generated by ``SSATransform`` being dependent on AST IDs, sometimes resulting in different (but equivalent) bytecode when unrelated files were added to the compilation pipeline.\n\n\nBuild System:\n* Replace internal JSON library jsoncpp with nlohmann::json.\n\n\n### 0.8.25 (2024-03-14)\n\nCompiler Features:\n * Code Generator: Use ``MCOPY`` instead of ``MLOAD``/``MSTORE`` loop when copying byte arrays.\n * EVM: Set default EVM version to ``cancun``.\n * Yul Analyzer: Emit transient storage warning only for the first occurrence of ``tstore``.\n\n\nBugfixes:\n * Assembler: Prevent incorrect calculation of tag sizes.\n * Commandline Interface: Do not run IR pipeline when ``--via-ir`` is used but no output that depends on the IR is requested.\n * EVM Assembly Import: Fix handling of missing source locations during import.\n * SMTChecker: Ensure query is properly flushed to a file before calling solver when using SMT-LIB interface.\n * SMTChecker: Fix internal error caused by not respecting the sign of an integer type when constructing zero-value SMT expressions.\n * SMTChecker: Run Eldarica only when explicitly requested with `--model-checker-solvers eld`, even when it is present on the system.\n\n### 0.8.24 (2024-01-25)\n\nLanguage Features:\n * Introduce global ``block.blobbasefee`` for retrieving the blob base fee of the current block.\n * Introduce global function ``blobhash(uint)`` for retrieving versioned hashes of blobs, akin to the homonymous Yul builtin.\n * Yul: Introduce builtin ``blobbasefee()`` for retrieving the blob base fee of the current block.\n * Yul: Introduce builtin ``blobhash()`` for retrieving versioned hashes of blobs associated with the transaction.\n * Yul: Introduce builtin ``mcopy()`` for cheaply copying data between memory areas.\n * Yul: Introduce builtins ``tload()`` and ``tstore()`` for transient storage access.\n\n\nCompiler Features:\n * EVM: Support for the EVM Version \"Cancun\".\n * SMTChecker: Support `bytes.concat` except when string literals are passed as arguments.\n * SMTChecker: Print a message that function parameter name was used instead of a concrete value in a counterexample when the concrete value found by the solver is too long to print.\n * Standard JSON Interface: Add experimental support to import EVM assembly in the format used by ``--asm-json``.\n * TypeChecker: Comparison of internal function pointers now yields a warning, as it can produce unexpected results with the legacy pipeline enabled.\n\n\nBugfixes:\n * AST import: Fix bug when importing inline assembly with empty ``let`` variable declaration.\n\n\n### 0.8.23 (2023-11-08)\n\nImportant Bugfixes:\n * Optimizer: Fix block deduplicator bug which led to blocks which are identical apart from the contents of ``verbatim`` instructions to be treated as equivalent and thus collapsed into a single one.\n\n\nCompiler Features:\n * Commandline Interface: An empty ``--yul-optimizations`` sequence can now be always provided.\n * Standard JSON Interface: An empty ``optimizerSteps`` sequence can now always be provided.\n\n\n### 0.8.22 (2023-10-25)\n\nLanguage Features:\n * Allow defining events at file level.\n\n\nCompiler Features:\n * Code Generator: Remove redundant overflow checks of certain ``for`` loops when the counter variable cannot overflow.\n * Commandline Interface: Add ``--no-import-callback`` option that prevents the compiler from loading source files not given explicitly on the CLI or in Standard JSON input.\n * Commandline Interface: Add an experimental ``--import-asm-json`` option that can import EVM assembly in the format used by ``--asm-json``.\n * Commandline Interface: Use proper severity and coloring also for error messages produced outside of the compilation pipeline.\n * EVM: Deprecate support for \"homestead\", \"tangerineWhistle\", \"spuriousDragon\" and \"byzantium\" EVM versions.\n * Parser: Remove the experimental error recovery mode (``--error-recovery`` / ``settings.parserErrorRecovery``).\n * SMTChecker: Support user-defined operators.\n * Yul Optimizer: If ``PUSH0`` is supported, favor zero literals over storing zero values in variables.\n * Yul Optimizer: Run the ``Rematerializer`` and ``UnusedPruner`` steps at the end of the default clean-up sequence.\n\n\nBugfixes:\n * AST: Fix wrong initial ID for Yul nodes in the AST.\n * Code Generator: Fix output from via-IR code generator being dependent on which files were discovered by import callback. In some cases, a different AST ID assignment would alter the order of functions in internal dispatch, resulting in superficially different but semantically equivalent bytecode.\n * NatSpec: Fix internal error when requesting userdoc or devdoc for a contract that emits an event defined in a foreign contract or interface.\n * SMTChecker: Fix encoding error that causes loops to unroll after completion.\n * SMTChecker: Fix inconsistency on constant condition checks when ``while`` or ``for`` loops are unrolled before the condition check.\n * Yul Optimizer: Fix replacement decisions during CSE being affected by Yul variable names generated by the compiler, resulting in different (but equivalent) bytecode in some situations.\n\n\n### 0.8.21 (2023-07-19)\n\nImportant Bugfixes:\n * Code Generator: Always generate code for the expression in ``<expression>.selector`` in the legacy code generation pipeline.\n * Yul Optimizer: Fix ``FullInliner`` step (``i``) not preserving the evaluation order of arguments passed into inlined functions in code that is not in expression-split form (i.e. when using a custom optimizer sequence in which the step not preceded by ``ExpressionSplitter`` (``x``)).\n\n\nLanguage Features:\n * Allow qualified access to events from other contracts.\n * Relax restrictions on initialization of immutable variables. Reads and writes may now happen at any point at construction time outside of functions and modifiers. Explicit initialization is no longer mandatory.\n\n\nCompiler Features:\n * Commandline Interface: Add ``--ast-compact-json`` output in assembler mode.\n * Commandline Interface: Add ``--ir-ast-json`` and ``--ir-optimized-ast-json`` outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR.\n * Commandline Interface: Respect ``--optimize-yul`` and ``--no-optimize-yul`` in compiler mode and accept them in assembler mode as well. ``--optimize --no-optimize-yul`` combination now allows enabling EVM assembly optimizer without enabling Yul optimizer.\n * EWasm: Remove EWasm backend.\n * Parser: Introduce ``pragma experimental solidity``, which will enable an experimental language mode that in particular has no stability guarantees between non-breaking releases and is not suited for production use.\n * SMTChecker: Add ``--model-checker-print-query`` CLI option and ``settings.modelChecker.printQuery`` JSON option to output the SMTChecker queries in the SMTLIB2 format. This requires using ``smtlib2`` solver only.\n * Standard JSON Interface: Add ``ast`` file-level output for Yul input.\n * Standard JSON Interface: Add ``irAst`` and ``irOptimizedAst`` contract-level outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR.\n * Yul Optimizer: Remove experimental ``ReasoningBasedSimplifier`` optimization step.\n * Yul Optimizer: Stack-to-memory mover is now enabled by default whenever possible for via IR code generation and pure Yul compilation.\n\n\nBugfixes:\n * Code Generator: Disallow complex expressions whose results are types, built-ins, modules or some unassignable functions. The legacy code generation pipeline would not actually evaluate them, discarding any side-effects they might have.\n * Code Generator: Fix not entirely deterministic order of functions in unoptimized Yul output. The choice of C++ compiler in some cases would result in different (but equivalent) bytecode (especially from native binaries vs emscripten binaries).\n * Commandline Interface: Fix internal error when using ``--stop-after parsing`` and requesting some of the outputs that require full analysis or compilation.\n * Commandline Interface: It is no longer possible to specify both ``--optimize-yul`` and ``--no-optimize-yul`` at the same time.\n * SMTChecker: Fix encoding of side-effects inside ``if`` and ``ternary conditional``statements in the BMC engine.\n * SMTChecker: Fix false negative when a verification target can be violated only by trusted external call from another public function.\n * SMTChecker: Fix generation of invalid SMT-LIB2 scripts in BMC engine with trusted mode for external calls when CHC engine times out.\n * SMTChecker: Fix internal error caused by incorrectly classifying external function call using function pointer as a public getter.\n * SMTChecker: Fix internal error caused by using external identifier to encode member access to functions that take an internal function as a parameter.\n * Standard JSON Interface: Fix an incomplete AST being returned when analysis is interrupted by certain kinds of fatal errors.\n * Type Checker: Disallow using certain unassignable function types in complex expressions.\n * Type Checker: Function declaration types referring to different declarations are no longer convertible to each other.\n * Yul Optimizer: Ensure that the assignment of memory slots for variables moved to memory does not depend on AST IDs that may depend on whether additional files are included during compilation.\n * Yul Optimizer: Fix ``FullInliner`` step not ignoring code that is not in expression-split form.\n * Yul Optimizer: Fix optimized IR being unnecessarily passed through the Yul optimizer again before bytecode generation.\n\n\nAST Changes:\n * AST: Add the ``experimentalSolidity`` field to the ``SourceUnit`` nodes, which indicate whether the experimental parsing mode has been enabled via ``pragma experimental solidity``.\n\n\n### 0.8.20 (2023-05-10)\n\nCompiler Features:\n * Assembler: Use ``push0`` for placing ``0`` on the stack for EVM versions starting from \"Shanghai\". This decreases the deployment and runtime costs.\n * EVM: Set default EVM version to \"Shanghai\".\n * EVM: Support for the EVM Version \"Shanghai\".\n * NatSpec: Add support for NatSpec documentation in ``enum`` definitions.\n * NatSpec: Add support for NatSpec documentation in ``struct`` definitions.\n * NatSpec: Include NatSpec from events that are emitted by a contract but defined outside of it in userdoc and devdoc output.\n * Optimizer: Re-implement simplified version of ``UnusedAssignEliminator`` and ``UnusedStoreEliminator``. It can correctly remove some unused assignments in deeply nested loops that were ignored by the old version.\n * Parser: Unary plus is no longer recognized as a unary operator in the AST and triggers an error at the parsing stage (rather than later during the analysis).\n * SMTChecker: Add CLI option ``--model-checker-bmc-loop-iterations`` and a JSON option ``settings.modelChecker.bmcLoopIterations`` that specify how many loop iterations the BMC engine should unroll. Note that false negatives are possible when unrolling loops. This is due to the possibility that bmc loop iteration setting is less than actual number of iterations needed to complete a loop.\n * SMTChecker: Group all messages about unsupported language features in a single warning. The CLI option ``--model-checker-show-unsupported`` and the JSON option ``settings.modelChecker.showUnsupported`` can be enabled to show the full list.\n * SMTChecker: Properties that are proved safe are now reported explicitly at the end of analysis. By default, only the number of safe properties is shown. The CLI option ``--model-checker-show-proved-safe`` and the JSON option ``settings.modelChecker.showProvedSafe`` can be enabled to show the full list of safe properties.\n * Standard JSON Interface: Add experimental support for importing ASTs via Standard JSON.\n * Yul EVM Code Transform: If available, use ``push0`` instead of ``codesize`` to produce an arbitrary value on stack in order to create equal stack heights between branches.\n\n\nBugfixes:\n * ABI: Include events in the ABI that are emitted by a contract but defined outside of it.\n * Immutables: Disallow initialization of immutables in try/catch statements.\n * SMTChecker: Fix false positives in ternary operators that contain verification targets in its branches, directly or indirectly.\n\n\nAST Changes:\n * AST: Add the ``internalFunctionIDs`` field to the AST nodes of contracts containing IDs of functions that may be called via the internal dispatch. The field is a map from function AST IDs to internal dispatch function IDs. These IDs are always generated, but they are only used in via-IR code generation.\n * AST: Add the ``usedEvents`` field to ``ContractDefinition`` which contains the AST IDs of all events emitted by the contract as well as all events defined and inherited by the contract.\n\n\n### 0.8.19 (2023-02-22)\n\nLanguage Features:\n * Allow defining custom operators for user-defined value types via ``using {f as +} for T global`` syntax.\n\n\nCompiler Features:\n * SMTChecker: New trusted mode that assumes that any compile-time available code is the actual used code even in external calls. This can be used via the CLI option ``--model-checker-ext-calls trusted`` or the JSON field ``settings.modelChecker.extCalls: \"trusted\"``.\n\n\nBugfixes:\n * Assembler: Avoid duplicating subassembly bytecode where possible.\n * Code Generator: Avoid including references to the deployed label of referenced functions if they are called right away.\n * ContractLevelChecker: Properly distinguish the case of missing base constructor arguments from having an unimplemented base function.\n * SMTChecker: Fix internal error caused by unhandled ``z3`` expressions that come from the solver when bitwise operators are used.\n * SMTChecker: Fix internal error when using the custom NatSpec annotation to abstract free functions.\n * TypeChecker: Also allow external library functions in ``using for``.\n\n\nAST Changes:\n * AST: Add ``function`` field to ``UnaryOperation`` and ``BinaryOperation`` AST nodes. ``functionList`` in ``UsingForDirective`` AST nodes will now contain ``operator`` and ``definition`` members instead of ``function`` when the list entry defines an operator.\n\n\n### 0.8.18 (2023-02-01)\n\nLanguage Features:\n * Allow named parameters in mapping types.\n\n\nCompiler Features:\n * Commandline Interface: Add ``--no-cbor-metadata`` that skips CBOR metadata from getting appended at the end of the bytecode.\n * Commandline Interface: Return exit code ``2`` on uncaught exceptions.\n * EVM: Deprecate ``block.difficulty`` and disallow ``difficulty()`` in inline assembly for EVM versions >= paris. The change is due to the renaming introduced by [EIP-4399](https://eips.ethereum.org/EIPS/eip-4399).\n * EVM: Introduce ``block.prevrandao`` in Solidity and ``prevrandao()`` in inline assembly for EVM versions >= paris.\n * EVM: Set the default EVM version to \"Paris\".\n * EVM: Support for the EVM version \"Paris\".\n * Language Server: Add basic document hover support.\n * Natspec: Add event Natspec inheritance for devdoc.\n * Optimizer: Added optimization rule ``and(shl(X, Y), shl(X, Z)) => shl(X, and(Y, Z))``.\n * Parser: More detailed error messages about invalid version pragmas.\n * SMTChecker: Make ``z3`` the default solver for the BMC and CHC engines instead of all solvers.\n * SMTChecker: Support Eldarica as a Horn solver for the CHC engine when using the CLI option ``--model-checker-solvers eld``. The binary ``eld`` must be available in the system.\n * Solidity Upgrade Tool: Remove ``solidity-upgrade`` tool.\n * Standard JSON: Add a boolean field ``settings.metadata.appendCBOR`` that skips CBOR metadata from getting appended at the end of the bytecode.\n * TypeChecker: Warn when using deprecated builtin ``selfdestruct``.\n * Yul EVM Code Transform: Generate more optimal code for user-defined functions that always terminate a transaction. No return labels will be pushed for calls to functions that always terminate.\n * Yul Optimizer: Allow replacing the previously hard-coded cleanup sequence by specifying custom steps after a colon delimiter (``:``) in the sequence string.\n * Yul Optimizer: Eliminate ``keccak256`` calls if the value was already calculated by a previous call and can be reused.\n\n\nBugfixes:\n * Parser: Disallow several ``indexed`` attributes for the same event parameter.\n * Parser: Disallow usage of the ``indexed`` attribute for modifier parameters.\n * SMTChecker: Fix display error for negative integers that are one more than powers of two.\n * SMTChecker: Fix internal error on chain assignments using static fully specified state variables.\n * SMTChecker: Fix internal error on multiple wrong SMTChecker natspec entries.\n * SMTChecker: Fix internal error when a public library function is called internally.\n * SMTChecker: Fix internal error when deleting struct member of function type.\n * SMTChecker: Fix internal error when using user-defined types as mapping indices or struct members.\n * SMTChecker: Improved readability for large integers that are powers of two or almost powers of two in error messages.\n * TypeChecker: Fix bug where private library functions could be attached with ``using for`` outside of their declaration scope.\n * Yul Optimizer: Hash hex and decimal literals according to their value instead of their representation, improving the detection of equivalent functions.\n\n\n### 0.8.17 (2022-09-08)\n\nImportant Bugfixes:\n * Yul Optimizer: Prevent the incorrect removal of storage writes before calls to Yul functions that conditionally terminate the external EVM call.\n\n\nCompiler Features:\n * Code Generator: More efficient overflow checks for multiplication.\n * Language Server: Analyze all files in a project by default (can be customized by setting ``'file-load-strategy'`` to ``'directly-opened-and-on-import'`` in LSP settings object).\n * Yul Optimizer: Simplify the starting offset of zero-length operations to zero.\n\n\nBugfixes:\n * Type Checker: Fix internal compiler error on tuple assignments with invalid left-hand side.\n * Yul IR Code Generation: Fix internal compiler error when accessing the ``.slot`` member of a mapping through a storage reference in inline assembly.\n\n\nBuild System:\n * Allow disabling pedantic warnings and do not treat warnings as errors during compiler build when ``-DPEDANTIC=OFF`` flag is passed to CMake.\n * Update emscripten to version 3.1.19.\n\n\n### 0.8.16 (2022-08-08)\n\nImportant Bugfixes:\n * Code Generation: Fix data corruption that affected ABI-encoding of calldata values represented by tuples: structs at any nesting level; argument lists of external functions, events and errors; return value lists of external functions. The 32 leading bytes of the first dynamically-encoded value in the tuple would get zeroed when the last component contained a statically-encoded array.\n\n\nCompiler Features:\n * Code Generator: More efficient code for checked addition and subtraction.\n * TypeChecker: Support using library constants in initializers of other constants.\n * Yul IR Code Generation: Improved copy routines for arrays with packed storage layout.\n * Yul Optimizer: Add rule to convert ``mod(add(X, Y), A)`` into ``addmod(X, Y, A)``, if ``A`` is a power of two.\n * Yul Optimizer: Add rule to convert ``mod(mul(X, Y), A)`` into ``mulmod(X, Y, A)``, if ``A`` is a power of two.\n\n\nBugfixes:\n * Commandline Interface: Disallow the following options outside of the compiler mode: ``--via-ir``,``--metadata-literal``, ``--metadata-hash``, ``--model-checker-show-unproved``, ``--model-checker-div-mod-no-slacks``, ``--model-checker-engine``, ``--model-checker-invariants``, ``--model-checker-solvers``, ``--model-checker-timeout``, ``--model-checker-contracts``, ``--model-checker-targets``.\n * Type Checker: Fix compiler crash on tuple assignments involving certain patterns with unary tuples on the left-hand side.\n * Type Checker: Fix compiler crash when ``abi.encodeCall`` received a tuple expression instead of an inline tuple.\n * Type Checker: Fix null dereference in ``abi.encodeCall`` type checking of free function.\n\n\n### 0.8.15 (2022-06-15)\n\nImportant Bugfixes:\n * Code Generation: Avoid writing dirty bytes to storage when copying ``bytes`` arrays.\n * Yul Optimizer: Keep all memory side-effects of inline assembly blocks.\n\n\nLanguage Features:\n * Add `E.selector` for a non-anonymous event `E` to access the 32-byte selector topic.\n\n\nCompiler Features:\n * Language Server: Add rudimentary support for semantic highlighting.\n * Language Server: Adds support for configuring ``include-paths`` JSON settings object that can be passed during LSP configuration stage.\n * Language Server: Always add ``{project_root}/node_modules`` to include search paths.\n * Type Checker: Warn about assignments involving multiple pushes to storage ``bytes`` that may invalidate references.\n * Yul Optimizer: Improve inlining heuristics for via IR code generation and pure Yul compilation.\n\nBugfixes:\n * ABI Encoder: When encoding an empty string coming from storage do not add a superfluous empty slot for data.\n * Common Subexpression Eliminator: Process assembly items in chunks with maximum size of 2000. It helps to avoid extremely time-consuming searches during code optimization.\n * DocString Parser: Fix ICE caused by an immutable struct with mapping.\n * Yul IR Code Generation: More robust cleanup in corner cases during memory to storage copies.\n * Yul Optimizer: Do not remove ``returndatacopy`` in cases in which it might perform out-of-bounds reads that unconditionally revert as out-of-gas. Previously, any ``returndatacopy`` that wrote to memory that was never read from was removed without accounting for the out-of-bounds condition.\n\n\n### 0.8.14 (2022-05-17)\n\nImportant Bugfixes:\n * ABI Encoder: When ABI-encoding values from calldata that contain nested arrays, correctly validate the nested array length against ``calldatasize()`` in all cases.\n * Override Checker: Allow changing data location for parameters only when overriding external functions.\n\n\nCompiler Features:\n * Assembly-Json Exporter: Include source list in `sourceList` field.\n * Commandline Interface: Option ``--pretty-json`` works also with the following options: ``--abi``, ``--asm-json``, ``--ast-compact-json``, ``--devdoc``, ``--storage-layout``, ``--userdoc``.\n * Language Server: Allow full filesystem access to language server.\n * Peephole Optimizer: Remove operations without side effects before simple terminations.\n * SMTChecker: Support ``abi.encodeCall`` taking into account the called selector.\n\n\nBugfixes:\n * Assembly-Json Exporter: Fix assembly json export to store jump types of operations in `jumpType` field instead of `value`.\n * SMTChecker: Fix ABI compatibility with z3 >=4.8.16.\n * SMTChecker: Fix bug when z3 is selected but not available at runtime.\n * Type Checker: Properly check restrictions of ``using ... global`` in conjunction with libraries.\n * TypeChecker: Convert parameters of function type to how they would be called for ``abi.encodeCall``.\n\n\n### 0.8.13 (2022-03-16)\n\nImportant Bugfixes:\n * Code Generator: Correctly encode literals used in ``abi.encodeCall`` in place of fixed bytes arguments.\n\n\nLanguage Features:\n * General: Allow annotating inline assembly as memory-safe to allow optimizations and stack limit evasion that rely on respecting Solidity's memory model.\n * General: ``using M for Type;`` is allowed at file level and ``M`` can now also be a brace-enclosed list of free functions or library functions.\n * General: ``using ... for T global;`` is allowed at file level where the user-defined type ``T`` has been defined, resulting in the effect of the statement being available everywhere ``T`` is available.\n\n\nCompiler Features:\n * Commandline Interface: Allow the use of ``--via-ir`` in place of ``--experimental-via-ir``.\n * Compilation via Yul IR is no longer marked as experimental.\n * JSON-AST: Added selector field for errors and events.\n * Language Server: Implements goto-definition.\n * Peephole Optimizer: Optimize comparisons in front of conditional jumps and conditional jumps across a single unconditional jump.\n * Yul EVM Code Transform: Avoid unnecessary ``pop``s on terminating control flow.\n * Yul IR Code Generation: When the result of an external call is statically-sized, ignore any returndata past the size expected by the compiler.\n * Yul Optimizer: Remove ``sstore`` and ``mstore`` operations that are never read from.\n\n\nBugfixes:\n * General: Fix internal error for locales with unusual capitalization rules. Locale set in the environment is now completely ignored.\n * Type Checker: Fix incorrect type checker errors when importing overloaded functions.\n * Yul IR Code Generation: Optimize embedded creation code with correct settings. This fixes potential mismatches between the constructor code of a contract compiled in isolation and the bytecode in ``type(C).creationCode``, resp. the bytecode used for ``new C(...)``.\n\n\n### 0.8.12 (2022-02-16)\n\nLanguage Features:\n * General: Add equality-comparison operators for external function types.\n * General: Support ``ContractName.functionName`` for ``abi.encodeCall``, in addition to external function pointers.\n\n\nCompiler Features:\n * Commandline Interface: Event and error signatures are also returned when using ``--hashes``.\n * Yul Optimizer: Remove ``mstore`` and ``sstore`` operations if the slot already contains the same value.\n * Yul: Emit immutable references for pure yul code when requested.\n\n\n\nBugfixes:\n * Antlr Grammar: Allow builtin names in ``yulPath`` to support ``.address`` in function pointers.\n * Code Generator: Fix internal error when accessing the members of external functions occupying more than two stack slots.\n * Code Generator: Fix internal error when doing an explicit conversion from ``string calldata`` to ``bytes``.\n * Control Flow Graph: Perform proper virtual lookup for modifiers for uninitialized variable and unreachable code analysis.\n * General: ``string.concat`` now properly takes strings as arguments and returns ``string memory``. It was accidentally introduced as a copy of ``bytes.concat`` before.\n * Immutables: Fix wrong error when the constructor of a base contract uses ``return`` and the derived contract contains immutable variables.\n * Inheritance: Consider functions in all ancestors during override analysis.\n * IR Generator: Add missing cleanup during the conversion of fixed bytes types to smaller fixed bytes types.\n * IR Generator: Add missing cleanup for indexed event arguments of value type.\n * IR Generator: Fix internal error when copying reference types in calldata and storage to struct or array members in memory.\n * IR Generator: Fix IR syntax error when copying storage arrays of structs containing functions.\n * Natspec: Fix internal error when overriding a struct getter with a Natspec-documented return value and the name in the struct is different.\n * Type Checker: Fix internal error when a constant variable declaration forward references a struct.\n * Yul EVM Code Transform: Improved stack shuffling in corner cases.\n\n\nSolc-Js:\n * The wrapper now requires at least nodejs v10.\n * The code has been ported to TypeScript.\n\n\nBuild System:\n * Emscripten builds store the embedded WebAssembly binary in LZ4 compressed format and transparently decompress on loading.\n\n\n### 0.8.11 (2021-12-20)\n\nLanguage Features:\n * General: New builtin function ``abi.encodeCall(functionPointer, (arg1, arg2, ...))`` that type-checks the arguments and returns the ABI-encoded function call data.\n\n\nCompiler Features:\n * Commandline Interface: Add ``--lsp`` option to get ``solc`` to act as a Language Server (LSP) communicating over stdio.\n\n\nBugfixes:\n * Code Generator: Fix a crash when using ``@use-src`` and compiling from Yul to ewasm.\n * SMTChecker: Fix internal error when an unsafe target is solved more than once and the counterexample messages are different.\n * SMTChecker: Fix soundness of assigned storage/memory local pointers that were not erasing enough knowledge.\n * Fix internal error when a function has a calldata struct argument with an internal type inside.\n * IR Generator: Fix IR syntax error when copying storage arrays of functions.\n\n\n### 0.8.10 (2021-11-09)\n\nLanguage Features:\n * Inline Assembly: Support ``.address`` and ``.selector`` on external function pointers to access their address and function selector.\n\n\nCompiler Features:\n * Code Generator: Skip existence check for external contract if return data is expected. In this case, the ABI decoder will revert if the contract does not exist.\n * Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``.\n * Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code.\n * Commandline Interface: Support ``--asm``, ``--bin``, ``--ir-optimized``, ``--ewasm`` and ``--ewasm-ir`` output selection options in assembler mode.\n * Commandline Interface: Use different colors when printing errors, warnings and infos.\n * JSON AST: Set absolute paths of imports earlier, in the ``parsing`` stage.\n * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions.\n * SMTChecker: Report contract invariants and reentrancy properties. This can be enabled via the CLI option ``--model-checker-invariants`` or the Standard JSON option ``settings.modelChecker.invariants``.\n * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``.\n * Standard JSON: Add ``settings.debug.debugInfo`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code.\n * Yul EVM Code Transform: Switch to new optimized code transform when compiling via Yul with enabled optimizer.\n * Yul Optimizer: Take control-flow side-effects of user-defined functions into account in various optimizer steps.\n\n\nBugfixes:\n * Code Generator: Fix constructor source mappings for immutables.\n * Commandline Interface: Disallow ``--error-recovery`` option outside of the compiler mode.\n * Commandline Interface: Don't return zero exit code when writing linked files to disk fails.\n * Commandline Interface: Fix extra newline character being appended to sources passed through standard input, affecting their hashes.\n * Commandline Interface: Report output selection options unsupported by the selected input mode instead of ignoring them.\n * Commandline Interface: When linking only accept exact matches for library names passed to the ``--libraries`` option. Library names not prefixed with a file name used to match any library with that name.\n * SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``).\n * SMTChecker: Fix internal error in the CHC engine when passing gas in the function options.\n * TypeChecker: Fix internal error when using arrays and structs with user defined value types before declaration.\n * TypeChecker: Fix internal error when using user defined value types in public library functions.\n * TypeChecker: Improved error message for constant variables with (nested) mapping types.\n * Yul Assembler: Fix internal error when function names are not unique.\n * Yul IR Generator: Do not output empty switches/if-bodies for empty contracts.\n\n\nImportant Bugfixes in Experimental Features:\n * Yul IR Generator: Changes to function return variables referenced in modifier invocation arguments were not properly forwarded if there was more than one return variable.\n\n\nBuild System:\n * Pass linker-only emscripten options only when linking.\n * Remove obsolete compatibility workaround for emscripten builds.\n * Update emscripten to version 2.0.33.\n\n\n### 0.8.9 (2021-09-29)\n\nImportant Bugfixes:\n * Immutables: Properly perform sign extension on signed immutables.\n * User Defined Value Type: Fix storage layout of user defined value types for underlying types shorter than 32 bytes.\n\n\nBugfixes:\n * AST: Export ``canonicalName`` for ``UserDefinedValueTypeDefinition`` and ``ContractDefinition``.\n\n\n\n### 0.8.8 (2021-09-27)\n\nLanguage Features:\n * Inheritance: A function that overrides only a single interface function does not require the ``override`` specifier.\n * Type System: Support ``type(E).min`` and ``type(E).max`` for enums.\n * User Defined Value Type: allows creating a zero cost abstraction over a value type with stricter type requirements.\n\n\nCompiler Features:\n * Commandline Interface: Add ``--include-path`` option for specifying extra directories that may contain importable code (e.g. packaged third-party libraries).\n * Commandline Interface: Do not implicitly run evm bytecode generation unless needed for the requested output.\n * Commandline Interface: Normalize paths specified on the command line and make them relative for files located inside base path and/or include paths.\n * Immutable variables can be read at construction time once they are initialized.\n * SMTChecker: Add constraints to better correlate ``address(this).balance`` and ``msg.value``.\n * SMTChecker: Support constants via modules.\n * SMTChecker: Support low level ``call`` as external calls to unknown code.\n * SMTChecker: Support the ``value`` option for external function calls.\n * SMTChecker: Support user defined value types.\n\n\nBugfixes:\n * Code Generator: Fix ICE on assigning to calldata structs and statically-sized calldata arrays in inline assembly.\n * Code Generator: Use stable source order for ABI functions.\n * Commandline Interface: Disallow the ``--experimental-via-ir`` option in Standard JSON, Assembler and Linker modes.\n * Commandline Interface: Fix resolution of paths whitelisted with ``--allowed-paths`` or implicitly due to base path, remappings and files being compiled. Correctly handle paths that do not match imports exactly due to being relative, non-normalized or empty.\n * Commandline Interface: Report optimizer options as invalid in Standard JSON and linker modes instead of ignoring them.\n * Name Resolver: Fix that when importing an aliased symbol using ``import {AliasedName} from \"a.sol\"`` it would use the original name of the symbol and not the aliased one.\n * Opcode Optimizer: Prevent the optimizer from running multiple times to avoid potential bytecode differences for referenced code.\n * Parser: Properly check for multiple SPDX license identifiers next to each other and validate them.\n * SMTChecker: Fix BMC's constraints regarding internal functions.\n * SMTChecker: Fix false negative caused by ``push`` on storage array references returned by internal functions.\n * SMTChecker: Fix false positive in external calls from constructors.\n * SMTChecker: Fix internal error on some multi-source uses of ``abi.*``, cryptographic functions and constants.\n * Standard JSON: Fix non-fatal errors in Yul mode being discarded if followed by a fatal error.\n * Type Checker: Correct wrong error message in inline assembly complaining about ``.slot`` or ``.offset`` not valid when actually ``.length`` was used.\n * Type Checker: Disallow modifier declarations and definitions in interfaces.\n * Yul Optimizer: Fix a crash in LoadResolver, when ``keccak256`` has particular non-identifier arguments.\n\n\n\n### 0.8.7 (2021-08-11)\n\nLanguage Features:\n * Introduce global ``block.basefee`` for retrieving the base fee of the current block.\n * Yul: Introduce builtin ``basefee()`` for retrieving the base fee of the current block.\n\n\nCompiler Features:\n * AssemblyStack: Also run opcode-based optimizer when compiling Yul code.\n * Commandline Interface: option ``--pretty-json`` works also with ``--standard--json``.\n * EVM: Set the default EVM version to \"London\".\n * SMTChecker: Do not check underflow and overflow by default.\n * SMTChecker: Unproved targets are hidden by default, and the SMTChecker only states how many unproved targets there are. They can be listed using the command line option ``--model-checker-show-unproved`` or the JSON option ``settings.modelChecker.showUnproved``.\n * SMTChecker: new setting to enable/disable encoding of division and modulo with slack variables. The command line option is ``--model-checker-div-mod-slacks`` and the JSON option is ``settings.modelChecker.divModWithSlacks``.\n * Yul EVM Code Transform: Also pop unused argument slots for functions without return variables (under the same restrictions as for functions with return variables).\n * Yul EVM Code Transform: Do not reuse stack slots that immediately become unreachable.\n * Yul Optimizer: Move function arguments and return variables to memory with the experimental Stack Limit Evader (which is not enabled by default).\n\n\nBugfixes:\n * Code Generator: Fix crash when passing an empty string literal to ``bytes.concat()``.\n * Code Generator: Fix internal compiler error when calling functions bound to calldata structs and arrays.\n * Code Generator: Fix internal compiler error when passing a 32-byte hex literal or a zero literal to ``bytes.concat()`` by disallowing such literals.\n * Commandline Interface: Apply ``--optimizer-runs`` option in assembly / yul mode.\n * Commandline Interface: Fix crash when a directory path is passed to ``--standard-json``.\n * Commandline Interface: Read JSON from standard input when ``--standard-json`` gets ``-`` as a file name.\n * Standard JSON: Include source location for errors in files with empty name.\n * Type Checker: Fix internal error and prevent static calls to unimplemented modifiers.\n * Yul Code Generator: Fix internal compiler error when using a long literal with bitwise negation.\n * Yul Code Generator: Fix source location references for calls to builtin functions.\n * Yul Parser: Fix source location references for ``if`` statements.\n\n\n### 0.8.6 (2021-06-22)\n\nLanguage Features:\n * Yul: Special meaning of ``\".metadata\"`` data object in Yul object.\n\n\nBugfixes:\n * Control Flow Graph: Fix incorrectly reported unreachable code.\n * Solc-Js: When running ``solcjs`` without the ``--optimize`` flag, use ``settings.optimizer.enabled=false`` in Standard JSON instead of omitting the key.\n * Standard JSON: Omitting ``settings.optimizer.enabled`` was not equivalent to setting it to ``false``. It meant disabling also the peephole optimizer and jumpdest remover which by default still run with ``enabled=false``.\n\n\n### 0.8.5 (2021-06-10)\n\nLanguage Features:\n * Allowing conversion from ``bytes`` and ``bytes`` slices to ``bytes1``/.../``bytes32``.\n * Yul: Add ``verbatim`` builtin function to inject arbitrary bytecode.\n\n\nCompiler Features:\n * Code Generator: Insert helper functions for panic codes instead of inlining unconditionally. This can reduce costs if many panics (checks) are inserted, but can increase costs where few panics are used.\n * EVM: Set the default EVM version to \"Berlin\".\n * SMTChecker: Function definitions can be annotated with the custom Natspec tag ``custom:smtchecker abstract-function-nondet`` to be abstracted by a nondeterministic value when called.\n * Standard JSON / combined JSON: New artifact \"functionDebugData\" that contains bytecode offsets of entry points of functions and potentially more information in the future.\n * Yul Optimizer: Evaluate ``keccak256(a, c)``, when the value at memory location ``a`` is known at compile time and ``c`` is a constant ``<= 32``.\n\n\nBugfixes:\n * AST: Do not output value of Yul literal if it is not a valid UTF-8 string.\n * Code Generator: Fix internal error when function arrays are assigned to storage variables and the function types can be implicitly converted but are not identical.\n * Code Generator: Fix internal error when super would have to skip an unimplemented function in the virtual resolution order.\n * Control Flow Graph: Assume unimplemented modifiers use a placeholder.\n * Control Flow Graph: Take internal calls to functions that always revert into account for reporting unused or unassigned variables.\n * Function Call Graph: Fix internal error connected with circular constant references.\n * Name Resolver: Do not issue shadowing warning if the shadowing name is not directly accessible.\n * Natspec: Allow multiple ``@return`` tags on public state variable documentation.\n * SMTChecker: Fix internal error on conversion from ``bytes`` to ``fixed bytes``.\n * SMTChecker: Fix internal error on external calls from the constructor.\n * SMTChecker: Fix internal error on struct constructor with fixed bytes member initialized with string literal.\n * Source Locations: Properly set source location of scoped blocks.\n * Standard JSON: Properly allow the ``inliner`` setting under ``settings.optimizer.details``.\n * Type Checker: Fix internal compiler error related to having mapping types in constructor parameter for abstract contracts.\n * Type Checker: Fix internal compiler error when attempting to use an invalid external function type on pre-byzantium EVMs.\n * Type Checker: Fix internal compiler error when overriding receive ether function with one having different parameters during inheritance.\n * Type Checker: Make errors about (nested) mapping type in event or error parameter into fatal type errors.\n * Type Checker: Fix internal compiler error when overriding an implemented modifier with an unimplemented one.\n\n\nAST Changes:\n * Add member `hexValue` for Yul string and hex literals.\n\n\n\n### 0.8.4 (2021-04-21)\n\nImportant Bugfixes:\n * ABI Decoder V2: For two-dimensional arrays and specially crafted data in memory, the result of ``abi.decode`` can depend on data elsewhere in memory. Calldata decoding is not affected.\n\n\nLanguage Features:\n * Assembly / Yul: Allow hex string literals.\n * Possibility to use ``bytes.concat`` with variable number of ``bytes`` and ``bytesNN`` arguments which behaves as a restricted version of `abi.encodePacked` with a more descriptive name.\n * Support custom errors via the ``error`` keyword and introduce the ``revert`` statement.\n\n\nCompiler Features:\n * Analysis: Properly detect circular references to the bytecode of other contracts across all function calls.\n * Commandline Interface: Model checker option ``--model-checker-targets`` also accepts ``outOfBounds``.\n * Commandline Interface: New model checker option ``--model-checker-contracts`` allows users to select which contracts should be analyzed as the most derived.\n * Low-Level Inliner: Inline ordinary jumps to small blocks and jumps to small blocks that terminate.\n * NatSpec: Allow ``@notice`` tag on non-public state variables and local variable declarations. The documentation will only be part of the AST, under the field ``documentation``.\n * SMTChecker: Deprecate ``pragma experimental SMTChecker;`` and set default model checker engine to ``none``.\n * SMTChecker: Report local variables in CHC counterexamples.\n * SMTChecker: Report out of bounds index access for arrays and fixed bytes.\n * SMTChecker: Support file level functions and constants.\n * Standard JSON: Model checker option ``settings.modelChecker.targets`` also accepts ``outOfBounds``.\n * Standard JSON: Model checker option ``settings.modelChecker.targets`` takes an array of string targets instead of string of comma separated targets.\n * Standard JSON: New model checker option ``settings.modelChecker.contracts`` allows users to select which contracts should be analyzed as the most derived.\n * Yul EVM Code Transform: Stack Optimization: Reuse slots of unused function arguments and defer allocating stack slots for return variables until after expression statements and assignments that do not reference them.\n * Yul Optimizer: Added a new step FunctionSpecializer, that specializes a function with its literal arguments.\n\n\nBugfixes:\n * Antlr Grammar: Fix parsing of import paths involving properly distinguishing between empty and non-empty string literals in general.\n * AST Output: Fix ``kind`` field of ``ModifierInvocation`` for base constructor calls.\n * Commandline interface: Fix internal error when printing AST and using ``--base-path`` or ``file://`` prefix in imports.\n * Commandline interface: Fix standard input bypassing allowed path checks.\n * Natspec: Fix internal error related to the `@returns` documentation for a public state variable overriding a function.\n * SMTChecker: Fix false positive and false negative on ``push`` as LHS of a compound assignment.\n * SMTChecker: Fix false positive in contracts that cannot be deployed.\n * SMTChecker: Fix internal error on public getter returning dynamic data on older EVM versions where these are not available.\n * SMTChecker: Fix internal error on try-catch with function call in catch block.\n * Type Checker: Fix missing error when events are used without an emit statement.\n\n\nAST Changes:\n * New property for ``ContractDefinition`` nodes: ``usedErrors`` lists AST IDs of all errors used by the contract (even if defined outside).\n\n\n\n### 0.8.3 (2021-03-23)\n\nImportant Bugfixes:\n * Optimizer: Fix bug on incorrect caching of Keccak-256 hashes.\n\nCompiler Features:\n * Command Line Interface: Drop experimental support for ``--machine evm15``.\n * Optimizer: Try to move ``and`` with constant inside ``or`` to improve storage writes of small types.\n * Optimizer: Replace multiplications and divisions with powers of two by shifts.\n\nBugfixes:\n * AST Import: For constructors, a public visibility is ignored during importing.\n * Error Reporter: Fix handling of carriage return.\n * SMTChecker: Fix internal error in BMC on resolving virtual functions inside branches.\n * SMTChecker: Fix internal error on ``array.pop`` nested inside 1-tuple.\n * SMTChecker: Fix internal error on ``FixedBytes`` constant initialized with string literal.\n * SMTChecker: Fix internal error on array slices.\n * SMTChecker: Fix internal error on calling public getter on a state variable of type array (possibly nested) of structs.\n * SMTChecker: Fix internal error on pushing to ``string`` casted to ``bytes``.\n * SMTChecker: Fix bug in virtual functions called by constructors.\n\nAST Changes:\n * ModifierInvocation: Add ``kind`` field which can be ``modifierInvocation`` or ``baseConstructorSpecifier``.\n\n\n### 0.8.2 (2021-03-02)\n\nCompiler Features:\n * AST: Export NatSpec comments above each statement as their documentation.\n * Inline Assembly: Do not warn anymore about variables or functions being shadowed by EVM opcodes.\n * NatSpec: Provide source locations for parsing errors.\n * Optimizer: Simple inlining when jumping to small blocks that jump again after a few side-effect free opcodes.\n * NatSpec: Allow and export all tags that start with ``@custom:``.\n\n\nBugfixes:\n * AST: Added ``referencedDeclaration`` for enum members.\n * Code Generator: Fix internal error when functions are passed as parameters of other callables, when the function types can be implicitly converted, but not identical.\n * Parser: Properly parse ``.address`` in some situations.\n * SMTChecker: Fix missing type constraints on block and transaction variables in the deployment phase.\n * Type Checker: Fix internal error when override specifier is not a contract.\n * Type Checker: Make function-hash collision errors into fatal type errors.\n\n\nAST Changes:\n * Adds ``nameLocation`` to declarations to represent the exact location of the symbolic name.\n * Removed the redundant function type \"bytearraypush\" - replaced by \"arraypush\".\n * Support field ``documentation`` to hold NatSpec comments above each statement.\n\n\n### 0.8.1 (2021-01-27)\n\nLanguage Features:\n * Possibility to use ``catch Panic(uint code)`` to catch a panic failure from an external call.\n\nCompiler Features:\n * Code Generator: Reduce the cost of ``<address>.code.length`` by using ``extcodesize`` directly.\n * Command Line Interface: Allow ``=`` as separator between library name and address in ``--libraries`` commandline option.\n * Command Line Interface: New option ``--model-checker-targets`` allows specifying which targets should be checked. The valid options are ``all``, ``constantCondition``, ``underflow``, ``overflow``, ``divByZero``, ``balance``, ``assert``, ``popEmptyArray``, where the default is ``all``. Multiple targets can be chosen at the same time, separated by a comma without spaces: ``underflow,overflow,assert``.\n * Command Line Interface: Only accept library addresses with a prefix of ``0x`` in ``--libraries`` commandline option.\n * Optimizer: Add rule to replace ``iszero(sub(x,y))`` by ``eq(x,y)``.\n * Parser: Report meaningful error if parsing a version pragma failed.\n * SMTChecker: Output internal and trusted external function calls in a counterexample's transaction trace.\n * SMTChecker: Show ``msg.value`` in counterexample transaction traces when greater than 0.\n * SMTChecker: Show contract name in counterexample function call.\n * SMTChecker: Support ABI functions as uninterpreted functions.\n * SMTChecker: Support try/catch statements.\n * SMTChecker: Synthesize untrusted functions called externally.\n * SMTChecker: Use checked arithmetic by default and support ``unchecked`` blocks.\n * Standard JSON: New option ``modelCheckerSettings.targets`` allows specifying which targets should be checked. The valid options are ``all``, ``constantCondition``, ``underflow``, ``overflow``, ``divByZero``, ``balance``, ``assert``, ``popEmptyArray``, where the default is ``all``. Multiple targets can be chosen at the same time, separated by a comma without spaces: ``underflow,overflow,assert``.\n\nBugfixes:\n * Code Generator: Fix length check when decoding malformed error data in catch clause.\n * Control Flow Graph: Fix missing error caused by read from/write to uninitialized variables.\n * SMTChecker: Fix false negatives in overriding modifiers and functions.\n * SMTChecker: Fix false negatives in the presence of inline assembly.\n * SMTChecker: Fix false negatives when analyzing external function calls.\n * SMTChecker: Fix internal error on ``block.chainid``.\n * SMTChecker: Fix internal error on pushing string literal to ``bytes`` array.\n * SMTChecker: Fix missing type constraints for block variables.\n * Type Checker: Fix infinite loop when accessing circular constants from inline assembly.\n * Type Checker: Fix internal error caused by constant structs containing mappings.\n * Type System: Disallow implicit conversion from ``uintN`` to ``intM`` when ``M > N``, and by extension, explicit conversion between the same types is also disallowed.\n\nBuild System:\n * Update the soljson.js build to emscripten 2.0.12 and boost 1.75.0.\n\n\n### 0.8.0 (2020-12-16)\n\nBreaking Changes:\n * Code Generator: All arithmetic is checked by default. These checks can be disabled using ``unchecked { ... }``.\n * Code Generator: Cause a panic if a byte array in storage is accessed whose length is encoded incorrectly.\n * Code Generator: Use ``revert`` with error signature ``Panic(uint256)`` and error codes instead of invalid opcode on failing assertions.\n * Command Line Interface: JSON fields `abi`, `devdoc`, `userdoc` and `storage-layout` are now sub-objects rather than strings.\n * Command Line Interface: Remove the ``--old-reporter`` option.\n * Command Line Interface: Remove the legacy ``--ast-json`` option. Only the ``--ast-compact-json`` option is supported now.\n * General: Enable ABI coder v2 by default.\n * General: Remove global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4``.\n * Parser: Exponentiation is right associative. ``a**b**c`` is parsed as ``a**(b**c)``.\n * Scanner: Remove support for the ``\\b``, ``\\f``, and ``\\v`` escape sequences.\n * Standard JSON: Remove the ``legacyAST`` option.\n * Type Checker: Function call options can only be given once.\n * Type System: Declarations with the name ``this``, ``super`` and ``_`` are disallowed, with the exception of public functions and events.\n * Type System: Disallow ``msg.data`` in ``receive()`` function.\n * Type System: Disallow ``type(super)``.\n * Type System: Disallow enums with more than 256 members.\n * Type System: Disallow explicit conversions from negative literals and literals larger than ``type(uint160).max`` to ``address`` type.\n * Type System: Disallow the ``byte`` type. It was an alias to ``bytes1``.\n * Type System: Explicit conversion to ``address`` type always returns a non-payable ``address`` type. In particular, ``address(u)``, ``address(b)``, ``address(c)`` and ``address(this)`` have the type ``address`` instead of ``address payable`` (Here ``u``, ``b``, and ``c`` are arbitrary variables of type ``uint160``, ``bytes20`` and contract type respectively.)\n * Type System: Explicit conversions between two types are disallowed if it changes more than one of sign, width or kind at the same time.\n * Type System: Explicit conversions from literals to enums are only allowed if the value fits in the enum.\n * Type System: Explicit conversions from literals to integer type is as strict as implicit conversions.\n * Type System: Introduce ``address(...).code`` to retrieve the code as ``bytes memory``. The size can be obtained via ``address(...).code.length``, but it will currently always include copying the code.\n * Type System: Introduce ``block.chainid`` for retrieving the current chain id.\n * Type System: Support ``address(...).codehash`` to retrieve the codehash of an account.\n * Type System: The global variables ``tx.origin`` and ``msg.sender`` have type ``address`` instead of ``address payable``.\n * Type System: Unary negation can only be used on signed integers, not on unsigned integers.\n * View Pure Checker: Mark ``chainid`` as view.\n * Yul: Disallow the use of reserved identifiers, such as EVM instructions, even if they are not available in the given dialect / EVM version.\n * Yul: The ``assignimmutable`` builtin in the \"EVM with objects\" dialect takes the base offset of the code to modify as an additional argument.\n\nLanguage Features:\n * Super constructors can now be called using the member notation e.g. ``M.C(123)``.\n\nBugfixes:\n * Type Checker: Perform proper truncating integer arithmetic when using constants in array length expressions.\n\nAST Changes:\n * New AST Node ``IdentifierPath`` replacing in many places the ``UserDefinedTypeName``.\n * New AST Node ``UncheckedBlock`` used for ``unchecked { ... }``.\n\n### 0.7.6 (2020-12-16)\n\nLanguage Features:\n * Code generator: Support conversion from calldata slices to memory and storage arrays.\n * Code generator: Support copying dynamically encoded structs from calldata to memory.\n * Code generator: Support copying of nested arrays from calldata to memory.\n * Scanner: Generate a parser error when comments or unicode strings contain an unbalanced or underflowing set of unicode direction override markers (LRO, RLO, LRE, RLE, PDF).\n * The fallback function can now also have a single ``calldata`` argument (equaling ``msg.data``) and return ``bytes memory`` (which will not be ABI-encoded but returned as-is).\n * Wasm backend: Add ``i32.select`` and ``i64.select`` instructions.\n\nCompiler Features:\n * Build System: Optionally support dynamic loading of Z3 and use that mechanism for Linux release builds.\n * Code Generator: Avoid memory allocation for default value if it is not used.\n * SMTChecker: Apply constant evaluation on binary arithmetic expressions.\n * SMTChecker: Create underflow and overflow verification targets for increment/decrement in the CHC engine.\n * SMTChecker: Report struct values in counterexamples from CHC engine.\n * SMTChecker: Support early returns in the CHC engine.\n * SMTChecker: Support getters.\n * SMTChecker: Support named arguments in function calls.\n * SMTChecker: Support struct constructor.\n * Standard-Json: Move the recently introduced ``modelCheckerSettings`` key to ``settings.modelChecker``.\n * Standard-Json: Properly filter the requested output artifacts.\n\nBugfixes:\n * Code generator: Do not pad empty string literals with a single 32-byte zero field in the ABI coder v1.\n * NatSpec: Fix segfault when inheriting return parameter documentation for modifiers with no parameters.\n * SMTChecker: Fix cast string literals to byte arrays.\n * SMTChecker: Fix internal compiler error when doing bitwise compound assignment with string literals.\n * SMTChecker: Fix internal error when trying to generate counterexamples with old z3.\n * SMTChecker: Fix segmentation fault that could occur on certain SMT-enabled sources when no SMT solver was available.\n * SMTChecker: Fix internal error when ``bytes.push()`` is used as the LHS of an assignment.\n * Type Checker: ``super`` is not available in libraries.\n * Type Checker: Disallow leading zeroes in sized-types (e.g. ``bytes000032``), but allow them to be treated as identifiers.\n * Yul Optimizer: Fix a bug in NameSimplifier where a new name created by NameSimplifier could also be created by NameDispenser.\n * Yul Optimizer: Removed NameSimplifier from optimization steps available to users.\n\n### 0.7.5 (2020-11-18)\n\nLanguage Features:\n * Ability to select the abi coder using ``pragma abicoder v1`` and ``pragma abicoder v2``.\n * Inline Assembly: Use ``.offset`` and ``.length`` for calldata variables of dynamic array type to access their calldata offset and length (number of elements). Both of them can also be assigned to.\n * Immutable variables with literal number values are considered pure.\n\nCompiler Features:\n * Assembler: Perform linking in assembly mode when library addresses are provided.\n * Command Line Interface: New option ``--experimental-via-ir`` allows switching compilation process to go through the Yul intermediate representation. This is highly experimental and is used for development purposes.\n * Command Line Interface: New option ``--model-checker-timeout`` sets a timeout in milliseconds for each individual query performed by the SMTChecker.\n * Command Line Interface: Report error if file could not be read in ``--standard-json`` mode.\n * Command Line interface: Report proper error for each output file which could not be written. Previously an exception was thrown, and execution aborted, on the first error.\n * SMTChecker: Add division by zero checks in the CHC engine.\n * SMTChecker: More precise analysis of external calls using ``this``.\n * SMTChecker: Support ``selector`` for expressions with value known at compile-time.\n * Standard JSON: New option ``modelCheckerSettings.timeout`` sets a timeout in milliseconds for each individual query performed by the SMTChecker.\n * Standard JSON: New option ``settings.viaIR`` allows the same switch as ``--experimental-via-ir`` on the commandline.\n\n\nBugfixes:\n * Code generator: Fix missing creation dependency tracking for abstract contracts.\n * Command Line Interface: Fix write error when the directory passed to ``--output-dir`` ends with a slash.\n * Command Line Interface: Reject duplicate libraries in ``--libraries`` option instead of arbitrarily choosing one.\n * NatSpec: Fix internal error when inheriting return parameter documentation but the parameter names differ between base and inherited.\n * SMTChecker: Fix CHC false positives when branches are used inside modifiers.\n * SMTChecker: Fix false negative in modifier applied multiple times.\n * SMTChecker: Fix incorrect counterexamples reported by the CHC engine.\n * SMTChecker: Fix internal error in the BMC engine when inherited contract from a different source unit has private state variables.\n * SMTChecker: Fix internal error on conversion from string literal to byte.\n * SMTChecker: Fix internal error when ``array.push()`` is used as the LHS of an assignment.\n * SMTChecker: Fix internal error when assigning state variable via contract's name.\n * SMTChecker: Fix internal error when using tuples of rational literals inside the conditional operator.\n * SMTChecker: Fix lack of reporting potential violations when using only the CHC engine.\n * Standard JSON: Fix library addresses specified in ``libraries`` being used for linking even if the file names do not match.\n\nAST Changes:\n * New member ``suffix`` for inline assembly identifiers. Currently supported values are ``\"slot\"``, ``\"offset\"`` and ``\"length\"`` to access the components of a Solidity variable.\n\n\n### 0.7.4 (2020-10-19)\n\nImportant Bugfixes:\n * Code Generator: Fix data corruption bug when copying empty byte arrays from memory or calldata to storage.\n\n\nLanguage Features:\n * Constants can be defined at file level.\n\n\nCompiler Features:\n * Command Line Interface: New option ``--model-checker-engine`` allows to choose a specific SMTChecker engine. Options are ``all`` (default), ``bmc``, ``chc`` and ``none``.\n * Control Flow Graph: Print warning for non-empty functions with unnamed return parameters that are not assigned a value in all code paths.\n * SMTChecker: Support ``keccak256``, ``sha256``, ``ripemd160`` and ``ecrecover`` in the CHC engine.\n * SMTChecker: Support inline arrays.\n * SMTChecker: Support variables ``block``, ``msg`` and ``tx`` in the CHC engine.\n * Standard JSON: New option ``modelCheckerSettings.engine`` allows to choose a specific SMTChecker engine. Options are ``all`` (default), ``bmc``, ``chc`` and ``none``.\n\n\nBugfixes:\n * Code generator: Fix ``ABIEncoderV2`` pragma from the current module affecting inherited functions and applied modifiers.\n * Code generator: Fix internal compiler error when referencing members via module name but not using the reference.\n * Code generator: Fix internal error on returning structs containing mappings from library function.\n * Code generator: Use revert instead of invalid opcode for out-of-bounds array index access in getter.\n * Contract Level Checker: Add missing check against inheriting functions with ABIEncoderV2 return types in ABIEncoderV1 contracts.\n * Name Resolver: Fix shadowing/same-name warnings for later declarations.\n * Type Checker: Allow arrays of contract types as type expressions and as arguments for ``abi.decode``.\n * Type Checker: Disallow invalid use of library names as type name.\n * Type Checker: Fix internal compiler error caused by storage parameters with nested mappings in libraries.\n\n\n### 0.7.3 (2020-10-07)\n\nImportant Bugfixes:\n * Code Generator: Properly cleanup after copying dynamic-array to storage for packed types.\n\nCompiler Features:\n * Code generator: Implemented events with function type as one of its indexed parameters.\n * General: Option to stop compilation after parsing stage. Can be used with ``solc --stop-after parsing``\n * Optimizer: Optimize ``exp`` when base is ``-1``.\n * SMTChecker: Support ``addmod`` and ``mulmod``.\n * SMTChecker: Support array slices.\n * SMTChecker: Support type conversions.\n\n\nBugfixes:\n * Fixed internal compiler errors for certain contracts involving the ``new`` expression.\n * JSON AST: Fix internal error when using ``--ast-json`` on a function with memory arguments in ABIEncoderV2 contracts.\n * Type Checker: Add missing checks for calls using types incompatible with ABIEncoderV1 in modules where ABIEncoderV2 is not enabled.\n * Type Checker: Fix internal compiler error when calling `.push(<arg>)` for a storage array with a nested mapping.\n\n\n### 0.7.2 (2020-09-28)\n\nImportant Bugfixes:\n * Type Checker: Disallow two or more free functions with identical name (potentially imported and aliased) and parameter types.\n\nCompiler Features:\n * Export compiler-generated utility sources via standard-json or combined-json.\n * Optimizer: Optimize ``exp`` when base is 0, 1 or 2.\n * SMTChecker: Keep knowledge about string literals, even through assignment, and thus support the ``.length`` property properly.\n * SMTChecker: Support ``address`` type conversion with literals, e.g. ``address(0)``.\n * SMTChecker: Support ``revert()``.\n * SMTChecker: Support ``type(T).min``, ``type(T).max``, and ``type(I).interfaceId``.\n * SMTChecker: Support compound and, or, and xor operators.\n * SMTChecker: Support events and low-level logs.\n * SMTChecker: Support fixed bytes index access.\n * SMTChecker: Support memory allocation, e.g. ``new bytes(123)``.\n * SMTChecker: Support shifts.\n * SMTChecker: Support structs.\n * Type Checker: Explain why oversized hex string literals can not be explicitly converted to a shorter ``bytesNN`` type.\n * Type Checker: More detailed error messages why implicit conversions fail.\n * Type Checker: Report position of first invalid UTF-8 sequence in ``unicode\"\"`` literals.\n * Yul IR Generator: Report source locations related to unimplemented features.\n * Yul Optimizer: Inline into functions further down in the call graph first.\n * Yul Optimizer: Prune unused parameters in functions.\n * Yul Optimizer: Try to simplify function names.\n\n\nBugfixes:\n * Code generator: Fix internal error on stripping dynamic types from return parameters on EVM versions without ``RETURNDATACOPY``.\n * Type Checker: Add missing check against nested dynamic arrays in ABI encoding functions when ABIEncoderV2 is disabled.\n * Type Checker: Correct the error message for invalid named parameter in a call to refer to the right argument.\n * Type Checker: Disallow ``virtual`` for modifiers in libraries.\n * Name Resolver: Correct the warning for homonymous, but not shadowing declarations.\n * Type system: Fix internal error on implicit conversion of contract instance to the type of its ``super``.\n * Type system: Fix internal error on implicit conversion of string literal to a calldata string.\n * Type system: Fix named parameters in overloaded function and event calls being matched incorrectly if the order differs from the declaration.\n * ViewPureChecker: Prevent visibility check on constructors.\n\n\n### 0.7.1 (2020-09-02)\n\nLanguage Features:\n * Allow function definitions outside of contracts, behaving much like internal library functions.\n * Code generator: Implementing copying structs from calldata to storage.\n\nCompiler Features:\n * SMTChecker: Add underflow and overflow as verification conditions in the CHC engine.\n * SMTChecker: Support bitwise or, xor and not operators.\n * SMTChecker: Support conditional operator.\n * Standard JSON Interface: Do not run EVM bytecode code generation, if only Yul IR or EWasm output is requested.\n * Yul Optimizer: LoopInvariantCodeMotion can move reading operations outside for-loops as long as the affected area is not modified inside the loop.\n * Yul: Report error when using non-string literals for ``datasize()``, ``dataoffset()``, ``linkersymbol()``, ``loadimmutable()``, ``setimmutable()``.\n\nBugfixes:\n * AST: Remove ``null`` member values also when the compiler is used in standard-json-mode.\n * General: Allow `type(Contract).name` for abstract contracts and interfaces.\n * Immutables: Disallow assigning immutables more than once during their declaration.\n * Immutables: Properly treat complex assignment and increment/decrement as both reading and writing and thus disallow it everywhere for immutable variables.\n * Optimizer: Keep side-effects of ``x`` in ``byte(a, shr(b, x))`` even if the constants ``a`` and ``b`` would make the expression zero unconditionally. This optimizer rule is very hard if not impossible to trigger in a way that it can result in invalid code, though.\n * References Resolver: Fix internal bug when using constructor for library.\n * Scanner: Fix bug where whitespace would be allowed within the ``->`` token (e.g. ``function f() -   > x {}`` becomes invalid in inline assembly and Yul).\n * SMTChecker: Fix internal error in BMC function inlining.\n * SMTChecker: Fix internal error on array implicit conversion.\n * SMTChecker: Fix internal error on fixed bytes index access.\n * SMTChecker: Fix internal error on lvalue unary operators with tuples.\n * SMTChecker: Fix internal error on tuple assignment.\n * SMTChecker: Fix internal error on tuples of one element that have tuple type.\n * SMTChecker: Fix internal error when using imported code.\n * SMTChecker: Fix soundness of array ``pop``.\n * Type Checker: Disallow ``using for`` directive inside interfaces.\n * Type Checker: Disallow signed literals as exponent in exponentiation operator.\n * Type Checker: Disallow structs containing nested mapping in memory as parameters for library functions.\n * Yul Optimizer: Ensure that Yul keywords are not mistakenly used by the NameDispenser and VarNameCleaners. The bug would manifest as uncompilable code.\n * Yul Optimizer: Make function inlining order more resilient to whether or not unrelated source files are present.\n\n\n### 0.7.0 (2020-07-28)\n\nBreaking changes:\n * Inline Assembly: Disallow ``.`` in user-defined function and variable names.\n * Inline Assembly: Slot and offset of storage pointer variable ``x`` are accessed via ``x.slot`` and ``x.offset`` instead of ``x_slot`` and ``x_offset``.\n * JSON AST: Mark hex string literals with ``kind: \"hexString\"``.\n * JSON AST: Remove members with ``null`` value from JSON output.\n * Parser: Disallow ``gwei`` as identifier.\n * Parser: Disallow dot syntax for ``value`` and ``gas``.\n * Parser: Disallow non-printable characters in string literals.\n * Parser: Introduce Unicode string literals: ``unicode\"😃\"``.\n * Parser: NatSpec comments on variables are only allowed for public state variables.\n * Parser: Remove the ``finney`` and ``szabo`` denominations.\n * Parser: Remove the identifier ``now`` (replaced by ``block.timestamp``).\n * Reference Resolver: ``using A for B`` only affects the contract it is mentioned in and not all derived contracts\n * Type Checker: Disallow ``virtual`` for library functions.\n * Type Checker: Disallow assignments to state variables that contain nested mappings.\n * Type checker: Disallow events with same name and parameter types in inheritance hierarchy.\n * Type Checker: Disallow shifts by signed types.\n * Type Checker: Disallow structs and arrays in memory or calldata if they contain nested mappings.\n * Type Checker: Exponentiation and shifts of literals by non-literals will always use ``uint256`` or ``int256`` as a type.\n * Yul: Disallow consecutive and trailing dots in identifiers. Leading dots were already disallowed.\n * Yul: Disallow EVM instruction `pc()`.\n\n\nLanguage Features:\n * Inheritance: Allow overrides to have stricter state mutability: ``view`` can override ``nonpayable`` and ``pure`` can override ``view``.\n * Parser: Deprecate visibility for constructors.\n * State mutability: Do not issue recommendation for stricter mutability for virtual functions but do issue it for functions that override.\n\n\nCompiler Features:\n * SMTChecker: Report multi-transaction counterexamples including the function calls that initiate the transactions. This does not include concrete values for reference types and reentrant calls.\n * Variable declarations using the ``var`` keyword are not recognized anymore.\n\n\nBugfixes:\n * Immutables: Fix internal compiler error when immutables are not assigned.\n * Inheritance: Disallow public state variables overwriting ``pure`` functions.\n * NatSpec: Constructors and functions have consistent userdoc output.\n * SMTChecker: Fix internal error when assigning to a 1-tuple.\n * SMTChecker: Fix internal error when tuples have extra effectless parenthesis.\n * State Mutability: Constant public state variables are considered ``pure`` functions.\n * Type Checker: Fixing deduction issues on function types when function call has named arguments.\n\n\n### 0.6.12 (2020-07-22)\n\nLanguage Features:\n * NatSpec: Implement tag ``@inheritdoc`` to copy documentation from a specific base contract.\n * Wasm backend: Add ``i32.ctz``, ``i64.ctz``, ``i32.popcnt``, and ``i64.popcnt``.\n\n\nCompiler Features:\n * Code Generator: Avoid double cleanup when copying to memory.\n * Code Generator: Evaluate ``keccak256`` of string literals at compile-time.\n * Optimizer: Add rule to remove shifts inside the byte opcode.\n * Peephole Optimizer: Add rule to remove swap after dup.\n * Peephole Optimizer: Remove unnecessary masking of tags.\n * Yul EVM Code Transform: Free stack slots directly after visiting the right-hand-side of variable declarations instead of at the end of the statement only.\n\n\nBugfixes:\n * SMTChecker: Fix error in events with indices of type static array.\n * SMTChecker: Fix internal error in sequential storage array pushes (``push().push()``).\n * SMTChecker: Fix internal error when using bitwise operators on fixed bytes type.\n * SMTChecker: Fix internal error when using compound bitwise operator assignments on array indices inside branches.\n * Type Checker: Fix internal compiler error related to oversized types.\n * Type Checker: Fix overload resolution in combination with ``{value: ...}``.\n\n\nBuild System:\n * Update internal dependency of jsoncpp to 1.9.3.\n\n\n### 0.6.11 (2020-07-07)\n\n\nLanguage Features:\n * General: Add unit denomination ``gwei``\n * Yul: Support ``linkersymbol`` builtin in standalone assembly mode to refer to library addresses.\n * Yul: Support using string literals exceeding 32 bytes as literal arguments for builtins.\n\n\nCompiler Features:\n * NatSpec: Add fields ``kind`` and ``version`` to the JSON output.\n * NatSpec: Inherit tags from unique base functions if derived function does not provide any.\n * Commandline Interface: Prevent some incompatible commandline options from being used together.\n * NatSpec: Support NatSpec comments on events.\n * Yul Optimizer: Store knowledge about storage / memory after ``a := sload(x)`` / ``a := mload(x)``.\n * SMTChecker: Support external calls to unknown code.\n * Source Maps: Also tag jumps into and out of Yul functions as jumps into and out of functions.\n\n\nBugfixes:\n * NatSpec: Do not consider ``////`` and ``/***`` as NatSpec comments.\n * Type Checker: Disallow constructor parameters with ``calldata`` data location.\n * Type Checker: Do not disallow assigning to calldata variables.\n * Type Checker: Fix internal error related to ``using for`` applied to non-libraries.\n * Wasm backend: Fix code generation for for-loops with pre statements.\n * Wasm backend: Properly support both ``i32.drop`` and ``i64.drop``, and remove ``drop``.\n * Yul: Disallow the same variable to occur multiple times on the left-hand side of an assignment.\n * Yul: Fix source location of variable multi-assignment.\n\n\n### 0.6.10 (2020-06-11)\n\nImportant Bugfixes:\n * Fixed a bug related to internal library functions with ``calldata`` parameters called via ``using for``.\n\n\nCompiler Features:\n * Commandline Interface: Re-group help screen.\n * Output compilation error codes in standard-json and when using ``--error-codes``.\n * Yul: Raise warning for switch statements that only have a default and no other cases.\n\n\nBugfixes:\n * SMTChecker: Fix internal error when encoding tuples of tuples.\n * SMTChecker: Fix aliasing soundness after pushing to an array pointer.\n * Type system: Fix internal compiler error on calling externally a function that returns variables with calldata location.\n * Type system: Fix bug where a bound function was not found if ``using for`` is applied to explicit reference types.\n\n\n### 0.6.9 (2020-06-04)\n\nLanguage Features:\n * Permit calldata location for all variables.\n * NatSpec: Support NatSpec comments on state variables.\n * Yul: EVM instruction `pc()` is marked deprecated and will be removed in the next breaking release.\n\n\nCompiler Features:\n * Build system: Update the soljson.js build to emscripten 1.39.15 and boost 1.73.0 and include Z3 for integrated SMTChecker support without the callback mechanism.\n * Build system: Switch the emscripten build from the fastcomp backend to the upstream backend.\n * Code Generator: Do not introduce new internal source references for small compiler routines.\n * Commandline Interface: Adds new option ``--base-path PATH`` to use the given path as the root of the source tree (defaults to the root of the filesystem).\n * SMTChecker: Support array ``length``.\n * SMTChecker: Support array ``push`` and ``pop``.\n * SMTChecker: General support to BitVectors and the bitwise ``and`` operator.\n\n\nBugfixes:\n * Code Generator: Trigger proper unimplemented errors on certain array copy operations.\n * Commandline Interface: Fix internal error when using ``--assemble`` or ``--yul`` options with ``--machine ewasm`` but without specifying ``--yul-dialect``.\n * NatSpec: DocString block is terminated when encountering an empty line.\n * Optimizer: Fixed a bug in BlockDeDuplicator.\n * Scanner: Fix bug when two empty NatSpec comments lead to scanning past EOL.\n * SMTChecker: Fix internal error on try/catch clauses with parameters.\n * SMTChecker: Fix internal error when applying arithmetic operators to fixed point variables.\n * SMTChecker: Fix internal error when assigning to index access inside branches.\n * SMTChecker: Fix internal error when short circuiting Boolean expressions with function calls in state variable initialization.\n * Type Checker: Disallow assignments to storage variables of type ``mapping``.\n * Type Checker: Disallow inline arrays of non-nameable types.\n * Type Checker: Disallow usage of override with non-public state variables.\n * Type Checker: Fix internal compiler error when accessing members of array slices.\n * Type Checker: Fix internal compiler error when forward referencing non-literal constants from inline assembly.\n * Type Checker: Fix internal compiler error when trying to decode too large static arrays.\n * Type Checker: Fix wrong compiler error when referencing an overridden function without calling it.\n\n\n### 0.6.8 (2020-05-14)\n\nImportant Bugfixes:\n * Add missing callvalue check to the creation code of a contract that does not define a constructor but has a base that does define a constructor.\n * Disallow array slices of arrays with dynamically encoded base types.\n * String literals containing backslash characters can no longer cause incorrect code to be generated when passed directly to function calls or encoding functions when ABIEncoderV2 is active.\n\n\nLanguage Features:\n * Implemented ``type(T).min`` and ``type(T).max`` for every integer type ``T`` that returns the smallest and largest value representable by the type.\n\n\nCompiler Features:\n * Commandline Interface: Don't ignore `--yul-optimizations` in assembly mode.\n * Allow using abi encoding functions for calldata array slices without explicit casts.\n * Wasm binary output: Implement ``br`` and ``br_if``.\n\n\nBugfixes:\n * ABI: Skip ``private`` or ``internal`` constructors.\n * Fixed an \"Assembly Exception in Bytecode\" error where requested functions were generated twice.\n * Natspec: Fixed a bug that ignored ``@return`` tag when no other developer-documentation tags were present.\n * Type Checker: Checks if a literal exponent in the ``**`` operation is too large or fractional.\n * Type Checker: Disallow accessing ``runtimeCode`` for contract types that contain immutable state variables.\n * Yul Assembler: Fix source location of variable declarations without value.\n\n\n### 0.6.7 (2020-05-04)\n\nLanguage Features:\n * Add support for EIP 165 interface identifiers with `type(I).interfaceId`.\n * Allow virtual modifiers inside abstract contracts to have empty body.\n\n\nCompiler Features:\n * Optimizer: Simplify repeated AND and OR operations.\n * Standard Json Input: Support the prefix ``file://`` in the field ``urls``.\n * Add option to specify optimization steps to be performed by Yul optimizer with `--yul-optimizations` in the commandline interface or `optimizer.details.yulDetails.optimizerSteps` in standard-json.\n\nBugfixes:\n * SMTChecker: Fix internal error when fixed points are used.\n * SMTChecker: Fix internal error when using array slices.\n * Type Checker: Disallow ``virtual`` and ``override`` for constructors.\n * Type Checker: Fix several internal errors by performing size and recursiveness checks of types before the full type checking.\n * Type Checker: Fix internal error when assigning to empty tuples.\n * Type Checker: Fix internal error when applying unary operators to tuples with empty components.\n * Type Checker: Perform recursiveness check on structs declared at the file level.\n\nBuild System:\n * soltest.sh: ``SOLIDITY_BUILD_DIR`` is no longer relative to ``REPO_ROOT`` to allow for build directories outside of the source tree.\n\n\n\n### 0.6.6 (2020-04-09)\n\nImportant Bugfixes:\n * Fix tuple assignments with components occupying multiple stack slots and different stack size on left- and right-hand-side.\n\n\nBugfixes:\n * AST export: Export `immutable` property in the field `mutability`.\n * SMTChecker: Fix internal error in the CHC engine when calling inherited functions internally.\n * Type Checker: Error when trying to encode functions with call options gas and value set.\n\n\n\n### 0.6.5 (2020-04-06)\n\nImportant Bugfixes:\n * Code Generator: Restrict the length of dynamic memory arrays to 64 bits during creation at runtime fixing a possible overflow.\n\n\nLanguage Features:\n * Allow local storage variables to be declared without initialization, as long as they are assigned before they are accessed.\n * State variables can be marked ``immutable`` which causes them to be read-only, but assignable in the constructor. The value will be stored directly in the code.\n\n\nCompiler Features:\n * Commandline Interface: Enable output of storage layout with `--storage-layout`.\n * Metadata: Added support for IPFS hashes of large files that need to be split in multiple chunks.\n\n\nBugfixes:\n * Inheritance: Allow public state variables to override functions with dynamic memory types in their return values.\n * Inline Assembly: Fix internal error when accessing invalid constant variables.\n * Inline Assembly: Fix internal error when accessing functions.\n * JSON AST: Always add pointer suffix for memory reference types.\n * Reference Resolver: Fix internal error when accessing invalid struct members.\n * Type Checker: Fix internal errors when assigning nested tuples.\n\n\n### 0.6.4 (2020-03-10)\n\nLanguage Features:\n * General: Deprecated `value(...)` and `gas(...)` in favor of `{value: ...}` and `{gas: ...}`\n * Inline Assembly: Allow assigning to `_slot` of local storage variable pointers.\n * Inline Assembly: Perform control flow analysis on inline assembly. Allows storage returns to be set in assembly only.\n\n\nCompiler Features:\n * AssemblyStack: Support for source locations (source mappings) and thus debugging Yul sources.\n * Commandline Interface: Enable output of experimental optimized IR via ``--ir-optimized``.\n\n\nBugfixes:\n * Inheritance: Fix incorrect error on calling unimplemented base functions.\n * Reference Resolver: Fix scoping issue following try/catch statements.\n * Standard-JSON-Interface: Fix a bug related to empty filenames and imports.\n * SMTChecker: Fix internal errors when analysing tuples.\n * Yul AST Import: correctly import blocks as statements, switch statements and string literals.\n\n### 0.6.3 (2020-02-18)\n\nLanguage Features:\n * Allow contract types and enums as keys for mappings.\n * Allow function selectors to be used as compile-time constants.\n * Report source locations for structured documentation errors.\n\n\nCompiler Features:\n * AST: Add a new node for doxygen-style, structured documentation that can be received by contract, function, event and modifier definitions.\n * Code Generator: Use ``calldatacopy`` instead of ``codecopy`` to zero out memory past input.\n * Debug: Provide reason strings for compiler-generated internal reverts when using the ``--revert-strings`` option or the ``settings.debug.revertStrings`` setting on ``debug`` mode.\n * Yul Optimizer: Prune functions that call each other but are otherwise unreferenced.\n * SMTChecker: CHC support to internal function calls.\n\n\nBugfixes:\n * Assembly: Added missing `source` field to legacy assembly json output to complete the source reference.\n * Parser: Fix an internal error for ``abstract`` without ``contract``.\n * Type Checker: Make invalid calls to uncallable types fatal errors instead of regular.\n\n\n### 0.6.2 (2020-01-27)\n\nLanguage Features:\n * Allow accessing external functions via contract and interface names to obtain their selector.\n * Allow interfaces to inherit from other interfaces\n * Allow gas and value to be set in external function calls using ``c.f{gas: 10000, value: 4 ether}()``.\n * Allow specifying the ``salt`` for contract creations and thus the ``create2`` opcode using ``new C{salt: 0x1234, value: 1 ether}(arg1, arg2)``.\n * Inline Assembly: Support literals ``true`` and ``false``.\n\n\nCompiler Features:\n * LLL: The LLL compiler has been removed.\n * General: Raise warning if runtime bytecode exceeds 24576 bytes (a limit introduced in Spurious Dragon).\n * General: Support compiling starting from an imported AST. Among others, this can be used for mutation testing.\n * Yul Optimizer: Apply penalty when trying to rematerialize into loops.\n\n\nBugfixes:\n * Commandline interface: Only activate yul optimizer if ``--optimize`` is given.\n * Fixes internal compiler error on explicitly calling unimplemented base functions.\n\n\nBuild System:\n * Switch to building soljson.js with an embedded base64-encoded wasm binary.\n\n\n### 0.6.1 (2020-01-02)\n\nBugfixes:\n * Yul Optimizer: Fix bug in redundant assignment remover in combination with break and continue statements.\n\n\n### 0.6.0 (2019-12-17)\n\nBreaking changes:\n * ABI: Remove the deprecated ``constant`` and ``payable`` fields.\n * ABI: The ``type`` field is now required and no longer specified to default to ``function``.\n * AST: Inline assembly is exported as structured JSON instead of plain string.\n * C API (``libsolc``): Introduce context parameter to both ``solidity_compile`` and the callback.\n * C API (``libsolc``): The provided callback now takes two parameters, kind and data. The callback can then be used for multiple purposes, such has file imports and SMT queries.\n * C API (``libsolc``): ``solidity_free`` was renamed to ``solidity_reset``. Functions ``solidity_alloc`` and ``solidity_free`` were added.\n * C API (``libsolc``): ``solidity_compile`` now returns a string that must be explicitly freed via ``solidity_free()``\n * Commandline Interface: Remove the text-based AST printer (``--ast``).\n * Commandline Interface: Switch to the new error reporter by default. ``--old-reporter`` falls back to the deprecated old error reporter.\n * Commandline Interface: Add option to disable or choose hash method between IPFS and Swarm for the bytecode metadata.\n * General: Disallow explicit conversions from external function types to ``address`` and add a member called ``address`` to them as replacement.\n * General: Enable Yul optimizer as part of standard optimization.\n * General: New reserved keywords: ``override``, ``receive``, and ``virtual``.\n * General: ``private`` cannot be used together with ``virtual``.\n * General: Split unnamed fallback functions into two cases defined using ``fallback()`` and ``receive()``.\n * Inheritance: State variable shadowing is now disallowed.\n * Inline Assembly: Only strict inline assembly is allowed.\n * Inline Assembly: Variable declarations cannot shadow declarations outside the assembly block.\n * JSON AST: Replace ``superFunction`` attribute by ``baseFunctions``.\n * Natspec JSON Interface: Properly support multiple ``@return`` statements in ``@dev`` documentation and enforce named return parameters to be mentioned documentation.\n * Source mappings: Add \"modifier depth\" as a fifth field in the source mappings.\n * Standard JSON Interface: Add option to disable or choose hash method between IPFS and Swarm for the bytecode metadata.\n * Syntax: ``push(element)`` for dynamic storage arrays do not return the new length anymore.\n * Syntax: Abstract contracts need to be marked explicitly as abstract by using the ``abstract`` keyword.\n * Syntax: ``length`` member of arrays is now always read-only, even for storage arrays.\n * Type Checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base.\n\nLanguage Features:\n * Allow explicit conversions from ``address`` to ``address payable`` via ``payable(...)``.\n * Allow global enums and structs.\n * Allow public variables to override external functions.\n * Allow underscores as delimiters in hex strings.\n * Allow to react on failing external calls using ``try`` and ``catch``.\n * Introduce syntax for array slices and implement them for dynamic calldata arrays.\n * Introduce ``push()`` for dynamic storage arrays. It returns a reference to the newly allocated element, if applicable.\n * Introduce ``virtual`` and ``override`` keywords.\n * Modify ``push(element)`` for dynamic storage arrays such that it does not return the new length anymore.\n * Yul: Introduce ``leave`` statement that exits the current function.\n * JSON AST: Add the function selector of each externally-visible FunctionDefinition to the AST JSON export.\n\nCompiler Features:\n * Allow revert strings to be stripped from the binary using the ``--revert-strings`` option or the ``settings.debug.revertStrings`` setting.\n * ABIEncoderV2: Do not warn about enabled ABIEncoderV2 anymore (the pragma is still needed, though).\n\n\n### 0.5.17 (2020-03-17)\n\nBugfixes:\n * Type Checker: Disallow overriding of private functions.\n\n\n### 0.5.16 (2020-01-02)\n\nBackported Bugfixes:\n * Yul Optimizer: Fix bug in redundant assignment remover in combination with break and continue statements.\n\n\n### 0.5.15 (2019-12-17)\n\nBugfixes:\n * Yul Optimizer: Fix incorrect redundant load optimization crossing user-defined functions that contain for-loops with memory / storage writes.\n\n### 0.5.14 (2019-12-09)\n\nLanguage Features:\n * Allow to obtain the selector of public or external library functions via a member ``.selector``.\n * Inline Assembly: Support constants that reference other constants.\n * Parser: Allow splitting hexadecimal and regular string literals into multiple parts.\n\n\nCompiler Features:\n * Commandline Interface: Allow translation from yul / strict assembly to EWasm using ``solc --yul --yul-dialect evm --machine ewasm``\n * Set the default EVM version to \"Istanbul\".\n * SMTChecker: Add support to constructors including constructor inheritance.\n * Yul: When compiling via Yul, string literals from the Solidity code are kept as string literals if every character is safely printable.\n * Yul Optimizer: Perform loop-invariant code motion.\n\n\nBugfixes:\n * SMTChecker: Fix internal error when using ``abi.decode``.\n * SMTChecker: Fix internal error when using arrays or mappings of functions.\n * SMTChecker: Fix internal error in array of structs type.\n * Version Checker: ``^0`` should match ``0.5.0``, but no prerelease.\n * Yul: Consider infinite loops and recursion to be not removable.\n\n\nBuild System:\n * Update to emscripten version 1.39.3.\n\n\n### 0.5.13 (2019-11-14)\n\nLanguage Features:\n * Allow to obtain the address of a linked library with ``address(LibraryName)``.\n\n\nCompiler Features:\n * Code Generator: Use SELFBALANCE opcode for ``address(this).balance`` if using Istanbul EVM.\n * EWasm: Experimental EWasm binary output via ``--ewasm`` and as documented in standard-json.\n * SMTChecker: Add break/continue support to the CHC engine.\n * SMTChecker: Support assignments to multi-dimensional arrays and mappings.\n * SMTChecker: Support inheritance and function overriding.\n * Standard JSON Interface: Output the storage layout of a contract when artifact ``storageLayout`` is requested.\n * TypeChecker: List possible candidates when overload resolution fails.\n * TypeChecker: Disallow variables of library types.\n\nBugfixes:\n * Code Generator: Fixed a faulty assert that would wrongly trigger for array sizes exceeding unsigned integer.\n * SMTChecker: Fix internal error when accessing indices of fixed bytes.\n * SMTChecker: Fix internal error when using function pointers as arguments.\n * SMTChecker: Fix internal error when implicitly converting string literals to fixed bytes.\n * Type Checker: Disallow constructor of the same class to be used as modifier.\n * Type Checker: Treat magic variables as unknown identifiers in inline assembly.\n * Code Generator: Fix internal error when trying to convert ``super`` to a different type\n\n\n### 0.5.12 (2019-10-01)\n\nLanguage Features:\n * Type Checker: Allow assignment to external function arguments except for reference types.\n\n\nCompiler Features:\n * ABI Output: Change sorting order of functions from selector to kind, name.\n * Optimizer: Add rule that replaces the BYTE opcode by 0 if the first argument is larger than 31.\n * SMTChecker: Add loop support to the CHC engine.\n * Yul Optimizer: Take side-effect-freeness of user-defined functions into account.\n * Yul Optimizer: Remove redundant mload/sload operations.\n * Yul Optimizer: Use the fact that branch conditions have certain value inside the branch.\n\n\nBugfixes:\n * Code Generator: Fix internal error when popping a dynamic storage array of mappings.\n * Name Resolver: Fix wrong source location when warning on shadowed aliases in import declarations.\n * Scanner: Fix multi-line natspec comment parsing with triple slashes when file is encoded with CRLF instead of LF.\n * Type System: Fix arrays of recursive structs.\n * Yul Optimizer: Fix reordering bug in connection with shifted one and mul/div-instructions in for loop conditions.\n\n\n### 0.5.11 (2019-08-12)\n\n\nLanguage Features:\n * Inline Assembly: Support direct constants of value type in inline assembly.\n\nCompiler Features:\n * ABI: Additional internal type info in the field ``internalType``.\n * eWasm: Highly experimental eWasm output using ``--ewasm`` in the commandline interface or output selection of ``ewasm.wast`` in standard-json.\n * Metadata: Update the swarm hash to the current specification, changes ``bzzr0`` to ``bzzr1`` and urls to use ``bzz-raw://``.\n * Standard JSON Interface: Compile only selected sources and contracts.\n * Standard JSON Interface: Provide secondary error locations (e.g. the source position of other conflicting declarations).\n * SMTChecker: Do not erase knowledge about storage pointers if another storage pointer is assigned.\n * SMTChecker: Support string literal type.\n * SMTChecker: New Horn-based algorithm that proves assertions via multi-transaction contract invariants.\n * Standard JSON Interface: Provide AST even on errors if ``--error-recovery`` commandline switch or StandardCompiler `settings.parserErrorRecovery` is true.\n * Yul Optimizer: Do not inline function if it would result in expressions being duplicated that are not cheap.\n\n\nBugfixes:\n * ABI decoder: Ensure that decoded arrays always point to distinct memory locations.\n * Code Generator: Treat dynamically encoded but statically sized arrays and structs in calldata properly.\n * SMTChecker: Fix internal error when inlining functions that contain tuple expressions.\n * SMTChecker: Fix pointer knowledge erasing in loops.\n * SMTChecker: Fix internal error when using compound bitwise assignment operators inside branches.\n * SMTChecker: Fix internal error when inlining a function that returns a tuple containing an unsupported type inside a branch.\n * SMTChecker: Fix internal error when inlining functions that use state variables and belong to a different source.\n * SMTChecker: Fix internal error when reporting counterexamples concerning state variables from different source files.\n * SMTChecker: Fix SMT sort mismatch when using string literals.\n * View/Pure Checker: Properly detect state variable access through base class.\n * Yul Analyzer: Check availability of data objects already in analysis phase.\n * Yul Optimizer: Fix an issue where memory-accessing code was removed even though ``msize`` was used in the program.\n\n\n### 0.5.10 (2019-06-25)\n\nImportant Bugfixes:\n * ABIEncoderV2: Fix incorrect abi encoding of storage array of data type that occupy multiple storage slots\n * Code Generator: Properly zero out higher order bits in elements of an array of negative numbers when assigning to storage and converting the type at the same time.\n\n\nCompiler Features:\n * Commandline Interface: Experimental parser error recovery via the ``--error-recovery`` commandline switch or StandardCompiler `settings.parserErrorRecovery` boolean.\n * Optimizer: Add rule to simplify ``SUB(~0, X)`` to ``NOT(X)``.\n * Yul Optimizer: Make the optimizer work for all dialects of Yul including eWasm.\n\n\nBugfixes:\n * Type Checker: Set state mutability of the function type members ``gas`` and ``value`` to pure (while their return type inherits state mutability from the function type).\n * Yul / Inline Assembly Parser: Disallow trailing commas in function call arguments.\n\n\nBuild System:\n * Attempt to use stock Z3 cmake files to find Z3 and only fall back to manual discovery.\n * CMake: use imported targets for boost.\n * Emscripten build: upgrade to boost 1.70.\n * Generate a cmake error for gcc versions older than 5.0.\n\n\n\n### 0.5.9 (2019-05-28)\n\nLanguage Features:\n * Inline Assembly: Revert change introduced in 0.5.7: The ``callvalue()`` instruction does not require ``payable`` anymore.\n * Static Analyzer: Disallow libraries calling themselves externally.\n\n\nCompiler Features:\n * Assembler: Encode the compiler version in the deployed bytecode.\n * Code Generator: Fix handling of structs of dynamic size as constructor parameters.\n * Inline Assembly: Disallow the combination of ``msize()`` and the Yul optimizer.\n * Metadata: Add IPFS hashes of source files.\n * Optimizer: Add rule to simplify SHL/SHR combinations.\n * Optimizer: Add rules for multiplication and division by left-shifted one.\n * SMTChecker: Support inherited state variables.\n * SMTChecker: Support tuples and function calls with multiple return values.\n * SMTChecker: Support ``delete``.\n * SMTChecker: Inline external function calls to ``this``.\n * Yul Optimizer: Simplify single-run ``for`` loops to ``if`` statements.\n * Yul Optimizer: Optimize representation of numbers.\n * Yul Optimizer: Do not inline recursive functions.\n * Yul Optimizer: Do not remove instructions that affect ``msize()`` if ``msize()`` is used.\n\nBugfixes:\n * Code Generator: Explicitly turn uninitialized internal function pointers into invalid functions when loaded from storage.\n * Code Generator: Fix assertion failure when assigning structs containing array of mapping.\n * Compiler Internals: Reset the Yul string repository before each compilation, freeing up memory.\n * SMTChecker: Fix bad cast in base constructor modifier.\n * SMTChecker: Fix internal error when visiting state variable inherited from base class.\n * SMTChecker: Fix internal error in fixed point operations.\n * SMTChecker: Fix internal error in assignment to unsupported type.\n * SMTChecker: Fix internal error in branching when inlining function calls that modify local variables.\n\n\n### 0.5.8 (2019-04-30)\n\nImportant Bugfixes:\n * Code Generator: Fix initialization routine of uninitialized internal function pointers in constructor context.\n * Yul Optimizer: Fix SSA transform for multi-assignments.\n\n\nLanguage Features:\n * ABIEncoderV2: Implement encoding of calldata arrays and structs.\n * Code Generation: Implement copying recursive structs from storage to memory.\n * Yul: Disallow function definitions inside for-loop init blocks.\n\n\nCompiler Features:\n * ABI Decoder: Raise a runtime error on dirty inputs when using the experimental decoder.\n * Optimizer: Add rule for shifts by constants larger than 255 for Constantinople.\n * Optimizer: Add rule to simplify certain ANDs and SHL combinations\n * SMTChecker: Support arithmetic compound assignment operators.\n * SMTChecker: Support unary increment and decrement for array and mapping access.\n * SMTChecker: Show unsupported warning for inline assembly blocks.\n * SMTChecker: Support mod.\n * SMTChecker: Support ``contract`` type.\n * SMTChecker: Support ``this`` as address.\n * SMTChecker: Support address members.\n * Standard JSON Interface: Metadata settings now re-produce the original ``\"useLiteralContent\"`` setting from the compilation input.\n * Yul: Adds break and continue keywords to for-loop syntax.\n * Yul: Support ``.`` as part of identifiers.\n * Yul Optimizer: Adds steps for detecting and removing of dead code.\n * Yul Code Generator: Directly jump over a series of function definitions (instead of jumping over each one)\n\n\nBugfixes:\n * SMTChecker: Implement Boolean short-circuiting.\n * SMTChecker: SSA control-flow did not take into account state variables that were modified inside inlined functions that were called inside branches.\n * Type System: Use correct type name for contracts in event parameters when used in libraries. This affected code generation.\n * Type System: Allow direct call to base class functions that have overloads.\n * Type System: Warn about shadowing builtin variables if user variables are named ``this`` or ``super``.\n * Yul: Properly register functions and disallow shadowing between function variables and variables in the outside scope.\n\n\nBuild System:\n * Soltest: Add commandline option `--test` / `-t` to isoltest which takes a string that allows filtering unit tests.\n * soltest.sh: allow environment variable ``SOLIDITY_BUILD_DIR`` to specify build folder and add ``--help`` usage.\n\n\n### 0.5.7 (2019-03-26)\n\nImportant Bugfixes:\n * ABIEncoderV2: Fix bugs related to loading short value types from storage when encoding an array or struct from storage.\n * ABIEncoderV2: Fix buffer overflow problem when encoding packed array from storage.\n * Optimizer: Fix wrong ordering of arguments in byte optimization rule for constants.\n\n\nLanguage Features:\n * Function calls with named arguments now work with overloaded functions.\n\n\nCompiler Features:\n * Inline Assembly: Issue error when using ``callvalue()`` inside nonpayable function (in the same way that ``msg.value`` already does).\n * Standard JSON Interface: Support \"Yul\" as input language.\n * SMTChecker: Show callstack together with model if applicable.\n * SMTChecker: Support modifiers.\n * Yul Optimizer: Enable stack allocation optimization by default if Yul optimizer is active (disable in ``yulDetails``).\n\n\nBugfixes:\n * Code Generator: Defensively pad memory for ``type(Contract).name`` to multiples of 32.\n * Type System: Detect and disallow internal function pointers as parameters for public/external library functions, even when they are nested/wrapped in structs, arrays or other types.\n * Yul Optimizer: Properly determine whether a variable can be eliminated during stack compression pass.\n * Yul / Inline Assembly Parser: Disallow more than one case statement with the same label inside a switch based on the label's integer value.\n\n\nBuild System:\n * Install scripts: Fix boost repository URL for CentOS 6.\n * Soltest: Fix hex string update in soltest.\n\n\n### 0.5.6 (2019-03-13)\n\nImportant Bugfixes:\n * Yul Optimizer: Fix visitation order bug for the structural simplifier.\n * Optimizer: Fix overflow in optimization rule that simplifies double shift by constant.\n\nLanguage Features:\n * Allow calldata arrays with dynamically encoded base types with ABIEncoderV2.\n * Allow dynamically encoded calldata structs with ABIEncoderV2.\n\n\nCompiler Features:\n * Optimizer: Add rules for ``lt``-comparisons with constants.\n * Peephole Optimizer: Remove double ``iszero`` before ``jumpi``.\n * SMTChecker: Support enums without typecast.\n * SMTChecker: Support one-dimensional arrays.\n * Type Checker: Provide better error messages for some literal conversions.\n * Yul Optimizer: Add rule to remove empty default switch cases.\n * Yul Optimizer: Add rule to remove empty cases if no default exists.\n * Yul Optimizer: Add rule to replace a switch with no cases with ``pop(expression)``.\n\n\nBugfixes:\n * JSON ABI: Json description of library ABIs no longer contains functions with internal types like storage structs.\n * SMTChecker: Fix internal compiler error when contract contains too large rational number.\n * Type system: Detect if a contract's base uses types that require the experimental abi encoder while the contract still uses the old encoder.\n\n\nBuild System:\n * Soltest: Add support for arrays in function signatures.\n * Soltest: Add support for struct arrays in function signatures.\n * Soltest: Add support for left-aligned, unpadded hex string literals.\n\n### 0.5.5 (2019-03-05)\n\nLanguage Features:\n * Add support for getters of mappings with ``string`` or ``bytes`` key types.\n * Meta programming: Provide access to the name of contracts via ``type(C).name``.\n\n\nCompiler Features:\n * Support ``petersburg`` as ``evmVersion`` and set as default.\n * Commandline Interface: Option to activate the experimental yul optimizer using ``-optimize-yul``.\n * Inline Assembly: Consider ``extcodehash`` as part of Constantinople.\n * Inline Assembly: Instructions unavailable to the currently configured EVM are errors now.\n * SMTChecker: Do not report underflow/overflow if they always revert. This removes false positives when using ``SafeMath``.\n * Standard JSON Interface: Allow retrieving metadata without triggering bytecode generation.\n * Standard JSON Interface: Provide fine-grained control over the optimizer via the settings.\n * Static Analyzer: Warn about expressions with custom types when they have no effect.\n * Optimizer: Add new rules with constants including ``LT``, ``GT``, ``AND`` and ``BYTE``.\n * Optimizer: Add rule for shifts with constants for Constantinople.\n * Optimizer: Combine multiple shifts with constant shift-by values into one.\n * Optimizer: Do not mask with 160-bits after ``CREATE`` and ``CREATE2`` as they are guaranteed to return an address or 0.\n * Optimizer: Support shifts in the constant optimiser for Constantinople.\n * Yul Optimizer: Add rule to replace switch statements with literals by matching case body.\n\n\nBugfixes:\n * ABIEncoderV2: Fix internal error related to bare delegatecall.\n * ABIEncoderV2: Fix internal error related to ecrecover.\n * ABIEncoderV2: Fix internal error related to mappings as library parameters.\n * ABIEncoderV2: Fix invalid signature for events containing structs emitted in libraries.\n * Inline Assembly: Proper error message for missing variables.\n * Optimizer: Fix internal error related to unused tag removal across assemblies. This never generated any invalid code.\n * SMTChecker: Fix crash related to statically-sized arrays.\n * TypeChecker: Fix internal error and disallow index access on contracts and libraries.\n * Yul: Properly detect name clashes with functions before their declaration.\n * Yul: Take built-in functions into account in the compilability checker.\n * Yul Optimizer: Properly take reassignments to variables in sub-expressions into account when replacing in the ExpressionSimplifier.\n\n\nBuild System:\n * Soltest: Add support for left-aligned, padded hex literals.\n * Soltest: Add support for right-aligned, padded boolean literals.\n\n### 0.5.4 (2019-02-12)\n\nLanguage Features:\n * Allow calldata structs without dynamically encoded members with ABIEncoderV2.\n\n\nCompiler Features:\n * ABIEncoderV2: Implement packed encoding.\n * C API (``libsolc`` / raw ``soljson.js``): Introduce ``solidity_free`` method which releases all internal buffers to save memory.\n * Commandline Interface: Adds new option ``--new-reporter`` for improved diagnostics formatting\n   along with ``--color`` and ``--no-color`` for colorized output to be forced (or explicitly disabled).\n\n\nBugfixes:\n * Code Generator: Defensively pad allocation of creationCode and runtimeCode to multiples of 32 bytes.\n * Commandline Interface: Allow yul optimizer only for strict assembly.\n * Parser: Disallow empty import statements.\n * Type Checker: Disallow mappings with data locations other than ``storage``.\n * Type Checker: Fix internal error when a struct array index does not fit into a uint256.\n * Type System: Properly report packed encoded size for arrays and structs (mostly unused until now).\n\n\nBuild System:\n * Add support for continuous fuzzing via Google oss-fuzz\n * SMT: If using Z3, require version 4.6.0 or newer.\n * Soltest: Add parser that is used in the file-based unit test environment.\n * Ubuntu PPA Packages: Use CVC4 as SMT solver instead of Z3\n\n\n### 0.5.3 (2019-01-22)\n\nLanguage Features:\n * Provide access to creation and runtime code of contracts via ``type(C).creationCode`` / ``type(C).runtimeCode``.\n\n\nCompiler Features:\n * Control Flow Graph: Warn about unreachable code.\n * SMTChecker: Support basic typecasts without truncation.\n * SMTChecker: Support external function calls and erase all knowledge regarding storage variables and references.\n\n\nBugfixes:\n * Emscripten: Split simplification rule initialization up further to work around issues with soljson.js in some browsers.\n * Type Checker: Disallow calldata structs until implemented.\n * Type Checker: Return type error if fixed point encoding is attempted instead of throwing ``UnimplementedFeatureError``.\n * Yul: Check that arguments to ``dataoffset`` and ``datasize`` are literals at parse time and properly take this into account in the optimizer.\n * Yul: Parse number literals for detecting duplicate switch cases.\n * Yul: Require switch cases to have the same type.\n\n\nBuild System:\n * Emscripten: Upgrade to emscripten 1.38.8 on travis and circleci.\n\n\n### 0.5.2 (2018-12-19)\n\nLanguage Features:\n * Control Flow Graph: Detect every access to uninitialized storage pointers.\n\n\nCompiler Features:\n * Inline Assembly: Improve error messages around invalid function argument count.\n * Code Generator: Only check callvalue once if all functions are non-payable.\n * Code Generator: Use codecopy for string constants more aggressively.\n * Code Generator: Use binary search for dispatch function if more efficient. The size/speed tradeoff can be tuned using ``--optimize-runs``.\n * SMTChecker: Support mathematical and cryptographic functions in an uninterpreted way.\n * SMTChecker: Support one-dimensional mappings.\n * Standard JSON Interface: Disallow unknown keys in standard JSON input.\n * Standard JSON Interface: Only run code generation if it has been requested. This could lead to unsupported feature errors only being reported at the point where you request bytecode.\n * Static Analyzer: Do not warn about unused variables or state mutability for functions with an empty body.\n * Type Checker: Add an additional reason to be displayed when type conversion fails.\n * Yul: Support object access via ``datasize``, ``dataoffset`` and ``datacopy`` in standalone assembly mode.\n\n\nBugfixes:\n * Standard JSON Interface: Report specific error message for json input errors instead of internal compiler error.\n\n\nBuild System:\n * Replace the trusty PPA build by a static build on cosmic that is used for the trusty package instead.\n * Remove support for Visual Studio 2015.\n\n\n### 0.5.1 (2018-12-03)\n\nLanguage Features:\n * Allow mapping type for parameters and return variables of public and external library functions.\n * Allow public functions to override external functions.\n\nCompiler Features:\n * Code generator: Do not perform redundant double cleanup on unsigned integers when loading from calldata.\n * Commandline interface: Experimental ``--optimize`` option for assembly mode (``--strict-assembly`` and ``--yul``).\n * SMTChecker: SMTLib2 queries and responses passed via standard JSON compiler interface.\n * SMTChecker: Support ``msg``, ``tx`` and ``block`` member variables.\n * SMTChecker: Support ``gasleft()`` and ``blockhash()`` functions.\n * SMTChecker: Support internal bound function calls.\n * Yul: Support Yul objects in ``--assemble``, ``--strict-assembly`` and ``--yul`` commandline options.\n\nBugfixes:\n * Assembly output: Do not mix in/out jump annotations with arguments.\n * Commandline interface: Fix crash when using ``--ast`` on empty runtime code.\n * Code Generator: Annotate jump from calldata decoder to function as \"jump in\".\n * Code Generator: Fix internal error related to state variables of function type access via base contract name.\n * Optimizer: Fix nondeterminism bug related to the boost version and constants representation. The bug only resulted in less optimal but still correct code because the generated routine is always verified to be correct.\n * Type Checker: Properly detect different return types when overriding an external interface function with a public contract function.\n * Type Checker: Disallow struct return types for getters of public state variables unless the new ABI encoder is active.\n * Type Checker: Fix internal compiler error when a field of a struct used as a parameter in a function type has a non-existent type.\n * Type Checker: Disallow functions ``sha3`` and ``suicide`` also without a function call.\n * Type Checker: Fix internal compiler error with ``super`` when base contract function is not implemented.\n * Type Checker: Fixed internal error when trying to create abstract contract in some cases.\n * Type Checker: Fixed internal error related to double declaration of events.\n * Type Checker: Disallow inline arrays of mapping type.\n * Type Checker: Consider abstract function to be implemented by public state variable.\n\nBuild System:\n * CMake: LLL is not built anymore by default. Must configure it with CMake as `-DLLL=ON`.\n * Docker: Includes both Scratch and Alpine images.\n * Emscripten: Upgrade to Emscripten SDK 1.37.21 and boost 1.67.\n\nSolc-Js:\n * Fix handling of standard-json in the commandline executable.\n * Remove support of nodejs 4.\n\n\n### 0.5.0 (2018-11-13)\n\nHow to update your code:\n * Change every ``.call()`` to a ``.call(\"\")`` and every ``.call(signature, a, b, c)`` to use ``.call(abi.encodeWithSignature(signature, a, b, c))`` (the last one only works for value types).\n * Change every ``keccak256(a, b, c)`` to ``keccak256(abi.encodePacked(a, b, c))``.\n * Add ``public`` to every function and ``external`` to every fallback or interface function that does not specify its visibility already.\n * Make your fallback functions ``external``.\n * Explicitly state the data location for all variables of struct, array or mapping types (including function parameters), e.g. change ``uint[] x = m_x`` to ``uint[] storage x = m_x``. Note that ``external`` functions require parameters with a data location of ``calldata``.\n * Explicitly convert values of contract type to addresses before using an ``address`` member. Example: if ``c`` is a contract, change ``c.transfer(...)`` to ``address(c).transfer(...)``.\n * Declare variables and especially function arguments as ``address payable``, if you want to call ``transfer`` on them.\n\nBreaking Changes:\n * ABI Encoder: Properly pad data from calldata (``msg.data`` and external function parameters). Use ``abi.encodePacked`` for unpadded encoding.\n * C API (``libsolc`` / raw ``soljson.js``): Removed the ``version``, ``license``, ``compileSingle``, ``compileJSON``, ``compileJSONCallback`` methods\n   and replaced them with the ``solidity_license``, ``solidity_version`` and ``solidity_compile`` methods.\n * Code Generator: Signed right shift uses proper arithmetic shift, i.e. rounding towards negative infinity. Warning: this may silently change the semantics of existing code!\n * Code Generator: Revert at runtime if calldata is too short or points out of bounds. This is done inside the ``ABI decoder`` and therefore also applies to ``abi.decode()``.\n * Code Generator: Use ``STATICCALL`` for ``pure`` and ``view`` functions. This was already the case in the experimental 0.5.0 mode.\n * Commandline interface: Remove obsolete ``--formal`` option.\n * Commandline interface: Rename the ``--julia`` option to ``--yul``.\n * Commandline interface: Require ``-`` if standard input is used as source.\n * Commandline interface: Use hash of library name for link placeholder instead of name itself.\n * Compiler interface: Disallow remappings with empty prefix.\n * Control Flow Analyzer: Consider mappings as well when checking for uninitialized return values.\n * Control Flow Analyzer: Turn warning about returning uninitialized storage pointers into an error.\n * General: ``continue`` in a ``do...while`` loop jumps to the condition (it used to jump to the loop body). Warning: this may silently change the semantics of existing code.\n * General: Disallow declaring empty structs.\n * General: Disallow raw ``callcode`` (was already deprecated in 0.4.12). It is still possible to use it via inline assembly.\n * General: Disallow ``var`` keyword.\n * General: Disallow ``sha3`` and ``suicide`` aliases.\n * General: Disallow the ``throw`` statement. This was already the case in the experimental 0.5.0 mode.\n * General: Disallow the ``years`` unit denomination (was already deprecated in 0.4.24)\n * General: Introduce ``emit`` as a keyword instead of parsing it as identifier.\n * General: New keywords: ``calldata`` and ``constructor``\n * General: New reserved keywords: ``alias``, ``apply``, ``auto``, ``copyof``, ``define``, ``immutable``,\n   ``implements``, ``macro``, ``mutable``, ``override``, ``partial``, ``promise``, ``reference``, ``sealed``,\n   ``sizeof``, ``supports``, ``typedef`` and ``unchecked``.\n * General: Remove assembly instruction aliases ``sha3`` and ``suicide``\n * General: C99-style scoping rules are enforced now. This was already the case in the experimental 0.5.0 mode.\n * General: Disallow combining hex numbers with unit denominations (e.g. ``0x1e wei``). This was already the case in the experimental 0.5.0 mode.\n * JSON AST: Remove ``constant`` and ``payable`` fields (the information is encoded in the ``stateMutability`` field).\n * JSON AST: Replace the ``isConstructor`` field by a new ``kind`` field, which can be ``constructor``, ``fallback`` or ``function``.\n * Interface: Remove \"clone contract\" feature. The ``--clone-bin`` and ``--combined-json clone-bin`` commandline options are not available anymore.\n * Name Resolver: Do not exclude public state variables when looking for conflicting declarations.\n * Optimizer: Remove the no-op ``PUSH1 0 NOT AND`` sequence.\n * Parser: Disallow trailing dots that are not followed by a number.\n * Parser: Remove ``constant`` as function state mutability modifier.\n * Parser: Disallow uppercase X in hex number literals\n * Type Checker: Disallow assignments between tuples with different numbers of components. This was already the case in the experimental 0.5.0 mode.\n * Type Checker: Disallow values for constants that are not compile-time constants. This was already the case in the experimental 0.5.0 mode.\n * Type Checker: Disallow arithmetic operations for boolean variables.\n * Type Checker: Disallow tight packing of literals. This was already the case in the experimental 0.5.0 mode.\n * Type Checker: Disallow calling base constructors without parentheses. This was already the case in the experimental 0.5.0 mode.\n * Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size.\n * Type Checker: Disallow conversions between unrelated contract types. Explicit conversion via ``address`` can still achieve it.\n * Type Checker: Disallow empty return statements for functions with one or more return values.\n * Type Checker: Disallow empty tuple components. This was partly already the case in the experimental 0.5.0 mode.\n * Type Checker: Disallow multi-variable declarations with mismatching number of values. This was already the case in the experimental 0.5.0 mode.\n * Type Checker: Disallow specifying base constructor arguments multiple times in the same inheritance hierarchy. This was already the case in the experimental 0.5.0 mode.\n * Type Checker: Disallow calling constructor with wrong argument count. This was already the case in the experimental 0.5.0 mode.\n * Type Checker: Disallow uninitialized storage variables. This was already the case in the experimental 0.5.0 mode.\n * Type Checker: Detecting cyclic dependencies in variables and structs is limited in recursion to 256.\n * Type Checker: Require explicit data location for all variables, including function parameters. This was partly already the case in the experimental 0.5.0 mode.\n * Type Checker: Only accept a single ``bytes`` type for ``.call()`` (and family), ``keccak256()``, ``sha256()`` and ``ripemd160()``.\n * Type Checker: Fallback function must be external. This was already the case in the experimental 0.5.0 mode.\n * Type Checker: Interface functions must be declared external. This was already the case in the experimental 0.5.0 mode.\n * Type Checker: Address members are not included in contract types anymore. An explicit conversion is now required before invoking an ``address`` member from a contract.\n * Type Checker: Disallow \"loose assembly\" syntax entirely. This means that jump labels, jumps and non-functional instructions cannot be used anymore.\n * Type System: Disallow explicit and implicit conversions from decimal literals to ``bytesXX`` types.\n * Type System: Disallow explicit and implicit conversions from hex literals to ``bytesXX`` types of different size.\n * Type System: Distinguish between payable and non-payable address types.\n * View Pure Checker: Disallow ``msg.value`` in (or introducing it via a modifier to) a non-payable function.\n * Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/solidity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible.\n * References Resolver: Turn missing storage locations into an error. This was already the case in the experimental 0.5.0 mode.\n * Syntax Checker: Disallow functions without implementation to use modifiers. This was already the case in the experimental 0.5.0 mode.\n * Syntax Checker: Named return values in function types are an error.\n * Syntax Checker: Strictly require visibility specifier for functions. This was already the case in the experimental 0.5.0 mode.\n * Syntax Checker: Disallow unary ``+``. This was already the case in the experimental 0.5.0 mode.\n * Syntax Checker: Disallow single statement variable declaration inside if/while/for bodies that are not blocks.\n * View Pure Checker: Strictly enforce state mutability. This was already the case in the experimental 0.5.0 mode.\n\nLanguage Features:\n * General: Add ``staticcall`` to ``address``.\n * General: Allow appending ``calldata`` keyword to types, to explicitly specify data location for arguments of external functions.\n * General: Support ``pop()`` for storage arrays.\n * General: Scoping rules now follow the C99-style.\n * General: Allow ``enum``s in interfaces.\n * General: Allow ``mapping`` storage pointers as arguments and return values in all internal functions.\n * General: Allow ``struct``s in interfaces.\n * General: Provide access to the ABI decoder through ``abi.decode(bytes memory data, (...))``.\n * General: Disallow zero length for fixed-size arrays.\n * Parser: Accept the ``address payable`` type during parsing.\n\nCompiler Features:\n * Build System: Support for Mojave version of macOS added.\n * Code Generator: ``CREATE2`` instruction has been updated to match EIP1014 (aka \"Skinny CREATE2\"). It also is accepted as part of Constantinople.\n * Code Generator: ``EXTCODEHASH`` instruction has been added based on EIP1052.\n * Type Checker: Nicer error message when trying to reference overloaded identifiers in inline assembly.\n * Type Checker: Show named argument in case of error.\n * Type System: IntegerType is split into IntegerType and AddressType internally.\n * Tests: Determine transaction status during IPC calls.\n * Code Generator: Allocate and free local variables according to their scope.\n * Removed ``pragma experimental \"v0.5.0\";``.\n * Syntax Checker: Improved error message for lookup in function types.\n * Name Resolver: Updated name suggestion look up function to take into account length of the identifier: 1: no search, 2-3: at most one change, 4-: at most two changes\n * SMTChecker: Support calls to internal functions that return none or a single value.\n\nBugfixes:\n * Build System: Support versions of CVC4 linked against CLN instead of GMP. In case of compilation issues due to the experimental SMT solver support, the solvers can be disabled when configuring the project with CMake using ``-DUSE_CVC4=OFF`` or ``-DUSE_Z3=OFF``.\n * Tests: Fix chain parameters to make ipc tests work with newer versions of cpp-ethereum.\n * Code Generator: Fix allocation of byte arrays (zeroed out too much memory).\n * Code Generator: Properly handle negative number literals in ABIEncoderV2.\n * Code Generator: Do not crash on using a length of zero for multidimensional fixed-size arrays.\n * Commandline Interface: Correctly handle paths with backslashes on windows.\n * Control Flow Analyzer: Ignore unimplemented functions when detecting uninitialized storage pointer returns.\n * Fix NatSpec json output for `@notice` and `@dev` tags on contract definitions.\n * Optimizer: Correctly estimate gas costs of constants for special cases.\n * Optimizer: Fix simplification rule initialization bug that appeared on some emscripten platforms.\n * References Resolver: Do not crash on using ``_slot`` and ``_offset`` suffixes on their own.\n * References Resolver: Enforce ``storage`` as data location for mappings.\n * References Resolver: Properly handle invalid references used together with ``_slot`` and ``_offset``.\n * References Resolver: Report error instead of assertion fail when FunctionType has an undeclared type as parameter.\n * References Resolver: Fix high CPU usage when using large variable names issue. Only suggest similar name if identifiers shorter than 80 characters.\n * Type Checker: Default data location for type conversions (e.g. from literals) is memory and not storage.\n * Type Checker: Disallow assignments to mappings within tuple assignments as well.\n * Type Checker: Disallow packed encoding of arrays of structs.\n * Type Checker: Allow assignments to local variables of mapping types.\n * Type Checker: Consider fixed size arrays when checking for recursive structs.\n * Type Checker: Fix crashes in erroneous tuple assignments in which the type of the right hand side cannot be determined.\n * Type Checker: Fix freeze for negative fixed-point literals very close to ``0``, such as ``-1e-100``.\n * Type Checker: Dynamic types as key for public mappings return error instead of assertion fail.\n * Type Checker: Fix internal error when array index value is too large.\n * Type Checker: Fix internal error when fixed-size array is too large to be encoded.\n * Type Checker: Fix internal error for array type conversions.\n * Type Checker: Fix internal error when array index is not an unsigned.\n * Type System: Allow arbitrary exponents for literals with a mantissa of zero.\n * Parser: Fix incorrect source location for nameless parameters.\n * Command Line Interface: Fix internal error when compiling stdin with no content and --ast option.\n\n\n### 0.4.26 (2019-04-29)\n\nImportant Bugfixes:\n * Code Generator: Fix initialization routine of uninitialized internal function pointers in constructor context.\n * Type System: Use correct type name for contracts in event parameters when used in libraries. This affected code generation.\n\nBugfixes:\n * ABIEncoderV2: Refuse to generate code that is known to be potentially buggy.\n * General: Split rule list such that JavaScript environments with small stacks can use the compiler.\n\nNote: The above changes are not included in 0.5.0, because they were backported.\n\n\n### 0.4.25 (2018-09-12)\n\nImportant Bugfixes:\n * Code Generator: Properly perform cleanup for exponentiation and non-256 bit types.\n * Type Checker: Report error when using indexed structs in events with experimental ABIEncoderV2. This used to log wrong values.\n * Type Checker: Report error when using structs in events without experimental ABIEncoderV2. This used to crash or log the wrong values.\n * Parser: Consider all unicode line terminators (LF, VF, FF, CR, NEL, LS, PS) for single-line comments\n   and string literals. They are invalid in strings and will end comments.\n * Parser: Disallow unterminated multi-line comments at the end of input.\n * Parser: Treat ``/** /`` as unterminated multi-line comment.\n\n### 0.4.24 (2018-05-16)\n\nLanguage Features:\n * Code Generator: Use native shift instructions on target Constantinople.\n * General: Allow multiple variables to be declared as part of a tuple assignment, e.g. ``(uint a, uint b) = ...``.\n * General: Remove deprecated ``constant`` as function state modifier from documentation and tests (but still leave it as a valid feature).\n * Type Checker: Deprecate the ``years`` unit denomination and raise a warning for it (or an error as experimental 0.5.0 feature).\n * Type Checker: Make literals (without explicit type casting) an error for tight packing as experimental 0.5.0 feature.\n * Type Checker: Warn about wildcard tuple assignments (this will turn into an error with version 0.5.0).\n * Type Checker: Warn when ``keccak256``, ``sha256`` and ``ripemd160`` are not used with a single bytes argument (suggest to use ``abi.encodePacked(...)``). This will turn into an error with version 0.5.0.\n\nCompiler Features:\n * Build System: Update internal dependency of jsoncpp to 1.8.4, which introduces more strictness and reduces memory usage.\n * Control Flow Graph: Add Control Flow Graph as analysis structure.\n * Control Flow Graph: Warn about returning uninitialized storage pointers.\n * Gas Estimator: Only explore paths with higher gas costs. This reduces accuracy but greatly improves the speed of gas estimation.\n * Optimizer: Remove unnecessary masking of the result of known short instructions (``ADDRESS``, ``CALLER``, ``ORIGIN`` and ``COINBASE``).\n * Parser: Display nicer error messages by showing the actual tokens and not internal names.\n * Parser: Use the entire location of the token instead of only its starting position as source location for parser errors.\n * SMT Checker: Support state variables of integer and bool type.\n\nBugfixes:\n * Code Generator: Fix ``revert`` with reason coming from a state or local string variable.\n * Type Checker: Show proper error when trying to ``emit`` a non-event.\n * Type Checker: Warn about empty tuple components (this will turn into an error with version 0.5.0).\n * Type Checker: The ABI encoding functions are pure and thus can be used for constants.\n\n### 0.4.23 (2018-04-19)\n\nFeatures:\n * Build system: Support Ubuntu Bionic.\n * SMTChecker: Integration with CVC4 SMT solver\n * Syntax Checker: Warn about functions named \"constructor\".\n\nBugfixes:\n * Type Checker: Improve error message for failed function overload resolution.\n * Type Checker: Do not complain about new-style constructor and fallback function to have the same name.\n * Type Checker: Detect multiple constructor declarations in the new syntax and old syntax.\n * Type Checker: Explicit conversion of ``bytesXX`` to ``contract`` is properly disallowed.\n\n### 0.4.22 (2018-04-16)\n\nFeatures:\n * Code Generator: Initialize arrays without using ``msize()``.\n * Code Generator: More specialized and thus optimized implementation for ``x.push(...)``\n * Commandline interface: Error when missing or inaccessible file detected. Suppress it with the ``--ignore-missing`` flag.\n * Constant Evaluator: Fix evaluation of single element tuples.\n * General: Add encoding routines ``abi.encodePacked``, ``abi.encode``, ``abi.encodeWithSelector`` and ``abi.encodeWithSignature``.\n * General: Add global function ``gasleft()`` and deprecate ``msg.gas``.\n * General: Add global function ``blockhash(uint)`` and deprecate ``block.hash(uint)``.\n * General: Allow providing reason string for ``revert()`` and ``require()``.\n * General: Introduce new constructor syntax using the ``constructor`` keyword as experimental 0.5.0 feature.\n * General: Limit the number of errors output in a single run to 256.\n * General: Support accessing dynamic return data in post-byzantium EVMs.\n * General: Allow underscores in numeric and hex literals to separate thousands and quads.\n * Inheritance: Error when using empty parentheses for base class constructors that require arguments as experimental 0.5.0 feature.\n * Inheritance: Error when using no parentheses in modifier-style constructor calls as experimental 0.5.0 feature.\n * Interfaces: Allow overriding external functions in interfaces with public in an implementing contract.\n * Optimizer: Optimize ``SHL`` and ``SHR`` only involving constants (Constantinople only).\n * Optimizer: Remove useless ``SWAP1`` instruction preceding a commutative instruction (such as ``ADD``, ``MUL``, etc).\n * Optimizer: Replace comparison operators (``LT``, ``GT``, etc) with opposites if preceded by ``SWAP1``, e.g. ``SWAP1 LT`` is replaced with ``GT``.\n * Optimizer: Optimize across ``mload`` if ``msize()`` is not used.\n * Static Analyzer: Error on duplicated super constructor calls as experimental 0.5.0 feature.\n * Syntax Checker: Issue warning for empty structs (or error as experimental 0.5.0 feature).\n * Syntax Checker: Warn about modifiers on functions without implementation (this will turn into an error with version 0.5.0).\n * Syntax Tests: Add source locations to syntax test expectations.\n * Type Checker: Improve documentation and warnings for accessing contract members inherited from ``address``.\n\nBugfixes:\n * Code Generator: Allow ``block.blockhash`` without being called.\n * Code Generator: Do not include internal functions in the runtime bytecode which are only referenced in the constructor.\n * Code Generator: Properly skip unneeded storage array cleanup when not reducing length.\n * Code Generator: Bugfix in modifier lookup in libraries.\n * Code Generator: Implement packed encoding of external function types.\n * Code Generator: Treat empty base constructor argument list as not provided.\n * Code Generator: Properly force-clean bytesXX types for shortening conversions.\n * Commandline interface: Fix error messages for imported files that do not exist.\n * Commandline interface: Support ``--evm-version constantinople`` properly.\n * DocString Parser: Fix error message for empty descriptions.\n * Gas Estimator: Correctly ignore costs of fallback function for other functions.\n * JSON AST: Remove storage qualifier for type name strings.\n * Parser: Fix internal compiler error when parsing ``var`` declaration without identifier.\n * Parser: Fix parsing of getters for function type variables.\n * Standard JSON: Support ``constantinople`` as ``evmVersion`` properly.\n * Static Analyzer: Fix non-deterministic order of unused variable warnings.\n * Static Analyzer: Invalid arithmetic with constant expressions causes errors.\n * Type Checker: Fix detection of recursive structs.\n * Type Checker: Fix asymmetry bug when comparing with literal numbers.\n * Type System: Improve error message when attempting to shift by a fractional amount.\n * Type System: Make external library functions accessible.\n * Type System: Prevent encoding of weird types.\n * Type System: Restrict rational numbers to 4096 bits.\n\n### 0.4.21 (2018-03-07)\n\nFeatures:\n * Code Generator: Assert that ``k != 0`` for ``mulmod(a, b, k)`` and ``addmod(a, b, k)`` as experimental 0.5.0 feature.\n * Code Generator: Do not retain any gas in calls (except if EVM version is set to homestead).\n * Code Generator: Use ``STATICCALL`` opcode for calling ``view`` and ``pure`` functions as experimental 0.5.0 feature.\n * General: C99/C++-style scoping rules (instead of JavaScript function scoping) take effect as experimental v0.5.0 feature.\n * General: Improved messaging when error spans multiple lines of a sourcefile\n * General: Support and recommend using ``emit EventName();`` to call events explicitly.\n * Inline Assembly: Enforce strict mode as experimental 0.5.0 feature.\n * Interface: Provide ability to select target EVM version (homestead or byzantium, with byzantium being the default).\n * Standard JSON: Reject badly formatted invalid JSON inputs.\n * Type Checker: Disallow uninitialized storage pointers as experimental 0.5.0 feature.\n * Syntax Analyser: Do not warn about experimental features if they do not concern code generation.\n * Syntax Analyser: Do not warn about ``pragma experimental \"v0.5.0\"`` and do not set the experimental flag in the bytecode for this.\n * Syntax Checker: Mark ``throw`` as an error as experimental 0.5.0 feature.\n * Syntax Checker: Issue error if no visibility is specified on contract functions as experimental 0.5.0 feature.\n * Syntax Checker: Issue warning when using overloads of ``address`` on contract instances.\n * Type Checker: disallow combining hex numbers and unit denominations as experimental 0.5.0 feature.\n\nBugfixes:\n * Assembly: Raise error on oversized number literals in assembly.\n * JSON-AST: Add \"documentation\" property to function, event and modifier definition.\n * Resolver: Properly determine shadowing for imports with aliases.\n * Standalone Assembly: Do not ignore input after closing brace of top level block.\n * Standard JSON: Catch errors properly when invalid \"sources\" are passed.\n * Standard JSON: Ensure that library addresses supplied are of correct length and hex prefixed.\n * Type Checker: Properly detect which array and struct types are unsupported by the old ABI encoder.\n * Type Checker: Properly warn when using ``_offset`` and ``_slot`` for constants in inline assembly.\n * Commandline interface: throw error if option is unknown\n\n### 0.4.20 (2018-02-14)\n\nFeatures:\n * Code Generator: Prevent non-view functions in libraries from being called\n   directly (as opposed to via delegatecall).\n * Commandline interface: Support strict mode of assembly (disallowing jumps,\n   instructional opcodes, etc) with the ``--strict-assembly`` switch.\n * Inline Assembly: Issue warning for using jump labels (already existed for jump instructions).\n * Inline Assembly: Support some restricted tokens (return, byte, address) as identifiers in Iulia mode.\n * Optimiser: Replace ``x % 2**i`` by ``x & (2**i-1)``.\n * Resolver: Continue resolving references after the first error.\n * Resolver: Suggest alternative identifiers if a given identifier is not found.\n * SMT Checker: Take if-else branch conditions into account in the SMT encoding of the program\n   variables.\n * Syntax Checker: Deprecate the ``var`` keyword (and mark it an error as experimental 0.5.0 feature).\n * Type Checker: Allow `this.f.selector` to be a pure expression.\n * Type Checker: Issue warning for using ``public`` visibility for interface functions.\n * Type Checker: Limit the number of warnings raised for creating abstract contracts.\n\nBugfixes:\n * Error Output: Truncate huge number literals in the middle to avoid output blow-up.\n * Parser: Disallow event declarations with no parameter list.\n * Standard JSON: Populate the ``sourceLocation`` field in the error list.\n * Standard JSON: Properly support contract and library file names containing a colon (such as URLs).\n * Type Checker: Suggest the experimental ABI encoder if using ``struct``s as function parameters\n   (instead of an internal compiler error).\n * Type Checker: Improve error message for wrong struct initialization.\n\n### 0.4.19 (2017-11-30)\n\nFeatures:\n * Code Generator: New ABI decoder which supports structs and arbitrarily nested\n   arrays and checks input size (activate using ``pragma experimental ABIEncoderV2;``).\n * General: Allow constant variables to be used as array length.\n * Inline Assembly: ``if`` statement.\n * Standard JSON: Support the ``outputSelection`` field for selective compilation of target artifacts.\n * Syntax Checker: Turn the usage of ``callcode`` into an error as experimental 0.5.0 feature.\n * Type Checker: Improve address checksum warning.\n * Type Checker: More detailed errors for invalid array lengths (such as division by zero).\n\nBugfixes:\n\n### 0.4.18 (2017-10-18)\n\nFeatures:\n * Code Generator: Always use all available gas for calls as experimental 0.5.0 feature\n   (previously, some amount was retained in order to work in pre-Tangerine-Whistle\n   EVM versions)\n * Parser: Better error message for unexpected trailing comma in parameter lists.\n * Standard JSON: Support the ``outputSelection`` field for selective compilation of supplied sources.\n * Syntax Checker: Unary ``+`` is now a syntax error as experimental 0.5.0 feature.\n * Type Checker: Disallow non-pure constant state variables as experimental 0.5.0 feature.\n * Type Checker: Do not add members of ``address`` to contracts as experimental 0.5.0 feature.\n * Type Checker: Force interface functions to be external as experimental 0.5.0 feature.\n * Type Checker: Require ``storage`` or ``memory`` keyword for local variables as experimental 0.5.0 feature.\n * Compiler Interface: Better formatted error message for long source snippets\n\nBugfixes:\n * Code Generator: Allocate one byte per memory byte array element instead of 32.\n * Code Generator: Do not accept data with less than four bytes (truncated function\n   signature) for regular function calls - fallback function is invoked instead.\n * Optimizer: Remove unused stack computation results.\n * Parser: Fix source location of VariableDeclarationStatement.\n * Type Checker: Allow ``gas`` in view functions.\n * Type Checker: Do not mark event parameters as shadowing state variables.\n * Type Checker: Prevent duplicate event declarations.\n * Type Checker: Properly check array length and don't rely on an assertion in code generation.\n * Type Checker: Properly support overwriting members inherited from ``address`` in a contract\n   (such as ``balance``, ``transfer``, etc.)\n * Type Checker: Validate each number literal in tuple expressions even if they are not assigned from.\n\n### 0.4.17 (2017-09-21)\n\nFeatures:\n * Assembly Parser: Support multiple assignment (``x, y := f()``).\n * Code Generator: Keep a single copy of encoding functions when using the experimental \"ABIEncoderV2\".\n * Code Generator: Partial support for passing ``structs`` as arguments and return parameters (requires ``pragma experimental ABIEncoderV2;`` for now).\n * General: Support ``pragma experimental \"v0.5.0\";`` to activate upcoming breaking changes.\n * General: Added ``.selector`` member on external function types to retrieve their signature.\n * Optimizer: Add new optimization step to remove unused ``JUMPDEST``s.\n * Static Analyzer: Warn when using deprecated builtins ``sha3`` and ``suicide``\n   (replaced by ``keccak256`` and ``selfdestruct``, introduced in 0.4.2 and 0.2.0, respectively).\n * Syntax Checker: Warn if no visibility is specified on contract functions.\n * Type Checker: Display helpful warning for unused function arguments/return parameters.\n * Type Checker: Do not show the same error multiple times for events.\n * Type Checker: Greatly reduce the number of duplicate errors shown for duplicate constructors and functions.\n * Type Checker: Warn on using literals as tight packing parameters in ``keccak256``, ``sha3``, ``sha256`` and ``ripemd160``.\n * Type Checker: Enforce ``view`` and ``pure``.\n * Type Checker: Enforce ``view`` / ``constant`` with error as experimental 0.5.0 feature.\n * Type Checker: Enforce fallback functions to be ``external`` as experimental 0.5.0 feature.\n\nBugfixes:\n * ABI JSON: Include all overloaded events.\n * Parser: Crash fix related to parseTypeName.\n * Type Checker: Allow constant byte arrays.\n\n### 0.4.16 (2017-08-24)\n\nFeatures:\n * ABI JSON: Include new field ``stateMutability`` with values ``pure``, ``view``,\n   ``nonpayable`` and ``payable``.\n * Analyzer: Experimental partial support for Z3 SMT checker (\"SMTChecker\").\n * Build System: Shared libraries (``libsolutil``, ``libevmasm``, ``libsolidity``\n   and ``liblll``) are no longer produced during the build process.\n * Code generator: Experimental new implementation of ABI encoder that can\n   encode arbitrarily nested arrays (\"ABIEncoderV2\")\n * Metadata: Store experimental flag in metadata CBOR.\n * Parser: Display previous visibility specifier in error if multiple are found.\n * Parser: Introduce ``pure`` and ``view`` keyword for functions,\n   ``constant`` remains an alias for ``view`` and pureness is not enforced yet,\n   so use with care.\n * Static Analyzer: Warn about large storage structures.\n * Syntax Checker: Support ``pragma experimental <feature>;`` to turn on\n   experimental features.\n * Type Checker: More detailed error message for invalid overrides.\n * Type Checker: Warn about shifting a literal.\n\nBugfixes:\n * Assembly Parser: Be more strict about number literals.\n * Assembly Parser: Limit maximum recursion depth.\n * Parser: Enforce commas between array and tuple elements.\n * Parser: Limit maximum recursion depth.\n * Type Checker: Crash fix related to ``using``.\n * Type Checker: Disallow constructors in libraries.\n * Type Checker: Reject the creation of interface contracts using the ``new`` statement.\n\n### 0.4.15 (2017-08-08)\n\nFeatures:\n * Type Checker: Show unimplemented function if trying to instantiate an abstract class.\n\nBugfixes:\n * Code Generator: ``.delegatecall()`` should always return execution outcome.\n * Code Generator: Provide \"new account gas\" for low-level ``callcode`` and ``delegatecall``.\n * Type Checker: Constructors must be implemented if declared.\n * Type Checker: Disallow the ``.gas()`` modifier on ``ecrecover``, ``sha256`` and ``ripemd160``.\n * Type Checker: Do not mark overloaded functions as shadowing other functions.\n * Type Checker: Internal library functions must be implemented if declared.\n\n### 0.4.14 (2017-07-31)\n\nFeatures:\n * C API (``jsonCompiler``): Export the ``license`` method.\n * Code Generator: Optimise the fallback function, by removing a useless jump.\n * Inline Assembly: Show useful error message if trying to access calldata variables.\n * Inline Assembly: Support variable declaration without initial value (defaults to 0).\n * Metadata: Only include files which were used to compile the given contract.\n * Type Checker: Disallow value transfers to contracts without a payable fallback function.\n * Type Checker: Include types in explicit conversion error message.\n * Type Checker: Raise proper error for arrays too large for ABI encoding.\n * Type checker: Warn if using ``this`` in a constructor.\n * Type checker: Warn when existing symbols, including builtins, are overwritten.\n\nBugfixes:\n * Code Generator: Properly clear return memory area for ecrecover.\n * Type Checker: Fix crash for some assignment to non-lvalue.\n * Type Checker: Fix invalid \"specify storage keyword\" warning for reference members of structs.\n * Type Checker: Mark modifiers as internal.\n * Type Checker: Re-allow multiple mentions of the same modifier per function.\n\n\n### 0.4.13 (2017-07-06)\n\nFeatures:\n * Syntax Checker: Deprecated \"throw\" in favour of require(), assert() and revert().\n * Type Checker: Warn if a local storage reference variable does not explicitly use the keyword ``storage``.\n\nBugfixes:\n * Code Generator: Correctly unregister modifier variables.\n * Compiler Interface: Only output AST if analysis was successful.\n * Error Output: Do not omit the error type.\n\n### 0.4.12 (2017-07-03)\n\nFeatures:\n * Assembly: Add ``CREATE2`` (EIP86), ``STATICCALL`` (EIP214), ``RETURNDATASIZE`` and ``RETURNDATACOPY`` (EIP211) instructions.\n * Assembly: Display auxiliary data in the assembly output.\n * Assembly: Renamed ``SHA3`` to ``KECCAK256``.\n * AST: export all attributes to JSON format.\n * C API (``jsonCompiler``): Use the Standard JSON I/O internally.\n * Code Generator: Added the Whiskers template system.\n * Inline Assembly: ``for`` and ``switch`` statements.\n * Inline Assembly: Function definitions and function calls.\n * Inline Assembly: Introduce ``keccak256`` as an opcode. ``sha3`` is still a valid alias.\n * Inline Assembly: Present proper error message when not supplying enough arguments to a functional\n   instruction.\n * Inline Assembly: Warn when instructions shadow Solidity variables.\n * Inline Assembly: Warn when using ``jump``s.\n * Remove obsolete Why3 output.\n * Type Checker: Enforce strict UTF-8 validation.\n * Type Checker: Warn about copies in storage that might overwrite unexpectedly.\n * Type Checker: Warn about type inference from literal numbers.\n * Static Analyzer: Warn about deprecation of ``callcode``.\n\nBugfixes:\n * Assembly: mark ``MLOAD`` to have side effects in the optimiser.\n * Code Generator: Fix ABI encoding of empty literal string.\n * Code Generator: Fix negative stack size checks.\n * Code generator: Use ``REVERT`` instead of ``INVALID`` for generated input validation routines.\n * Inline Assembly: Enforce function arguments when parsing functional instructions.\n * Optimizer: Disallow optimizations involving ``MLOAD`` because it changes ``MSIZE``.\n * Static Analyzer: Unused variable warnings no longer issued for variables used inside inline assembly.\n * Type Checker: Fix address literals not being treated as compile-time constants.\n * Type Checker: Fixed crash concerning non-callable types.\n * Type Checker: Fixed segfault with constant function parameters\n * Type Checker: Disallow comparisons between mapping and non-internal function types.\n * Type Checker: Disallow invoking the same modifier multiple times.\n * Type Checker: Do not treat strings that look like addresses as addresses.\n * Type Checker: Support valid, but incorrectly rejected UTF-8 sequences.\n\n### 0.4.11 (2017-05-03)\n\nFeatures:\n * Implement the Standard JSON Input / Output API\n * Support ``interface`` contracts.\n * C API (``jsonCompiler``): Add the ``compileStandard()`` method to process a Standard JSON I/O.\n * Commandline interface: Add the ``--standard-json`` parameter to process a Standard JSON I/O.\n * Commandline interface: Support ``--allow-paths`` to define trusted import paths. Note: the\n   path(s) of the supplied source file(s) is always trusted.\n * Inline Assembly: Storage variable access using ``_slot`` and ``_offset`` suffixes.\n * Inline Assembly: Disallow blocks with unbalanced stack.\n * Static analyzer: Warn about statements without effects.\n * Static analyzer: Warn about unused local variables, parameters, and return parameters.\n * Syntax checker: issue deprecation warning for unary '+'\n\nBugfixes:\n * Assembly output: Implement missing AssemblyItem types.\n * Compiler interface: Fix a bug where source indexes could be inconsistent between Solidity compiled\n   with different compilers (clang vs. gcc) or compiler settings. The bug was visible in AST\n   and source mappings.\n * Gas Estimator: Reflect the most recent fee schedule.\n * Type system: Contract inheriting from base with unimplemented constructor should be abstract.\n * Optimizer: Number representation bug in the constant optimizer fixed.\n\n### 0.4.10 (2017-03-15)\n\nFeatures:\n * Add ``assert(condition)``, which throws if condition is false (meant for internal errors).\n * Add ``require(condition)``, which throws if condition is false (meant for invalid input).\n * Commandline interface: Do not overwrite files unless forced.\n * Introduce ``.transfer(value)`` for sending Ether.\n * Code generator: Support ``revert()`` to abort with rolling back, but not consuming all gas.\n * Inline assembly: Support ``revert`` (EIP140) as an opcode.\n * Parser: Support scientific notation in numbers (e.g. ``2e8`` and ``200e-2``).\n * Type system: Support explicit conversion of external function to address.\n * Type system: Warn if base of exponentiation is literal (result type might be unexpected).\n * Type system: Warn if constant state variables are not compile-time constants.\n\nBugfixes:\n * Commandline interface: Always escape filenames (replace ``/``, ``:`` and ``.`` with ``_``).\n * Commandline interface: Do not try creating paths ``.`` and ``..``.\n * Commandline interface: Allow long library names.\n * Parser: Disallow octal literals.\n * Type system: Fix a crash caused by continuing on fatal errors in the code.\n * Type system: Disallow compound assignment for tuples.\n * Type system: Detect cyclic dependencies between constants.\n * Type system: Disallow arrays with negative length.\n * Type system: Fix a crash related to invalid binary operators.\n * Type system: Disallow ``var`` declaration with empty tuple type.\n * Type system: Correctly convert function argument types to pointers for member functions.\n * Type system: Move privateness of constructor into AST itself.\n * Inline assembly: Charge one stack slot for non-value types during analysis.\n * Assembly output: Print source location before the operation it refers to instead of after.\n * Optimizer: Stop trying to optimize tricky constants after a while.\n\n### 0.4.9 (2017-01-31)\n\nFeatures:\n * Compiler interface: Contracts and libraries can be referenced with a ``file:`` prefix to make them unique.\n * Compiler interface: Report source location for \"stack too deep\" errors.\n * AST: Use deterministic node identifiers.\n * Inline assembly: introduce ``invalid`` (EIP141) as an opcode.\n * Type system: Introduce type identifier strings.\n * Type checker: Warn about invalid checksum for addresses and deduce type from valid ones.\n * Metadata: Do not include platform in the version number.\n * Metadata: Add option to store sources as literal content.\n * Code generator: Extract array utils into low-level functions.\n * Code generator: Internal errors (array out of bounds, etc.) now cause a reversion by using an invalid\n   instruction (0xfe - EIP141) instead of an invalid jump. Invalid jump is still kept for explicit throws.\n\nBugfixes:\n * Code generator: Allow recursive structs.\n * Inline assembly: Disallow variables named like opcodes.\n * Type checker: Allow multiple events of the same name (but with different arities or argument types)\n * Natspec parser: Fix error with ``@param`` parsing and whitespace.\n\n### 0.4.8 (2017-01-13)\n\nFeatures:\n * Optimiser: Performance improvements.\n * Output: Print assembly in new standardized Solidity assembly format.\n\nBugfixes:\n * Remappings: Prefer longer context over longer prefix.\n * Type checker, code generator: enable access to events of base contracts' names.\n * Imports: ``import \".dir/a\"`` is not a relative path.  Relative paths begin with directory ``.`` or ``..``.\n * Type checker, disallow inheritances of different kinds (e.g. a function and a modifier) of members of the same name\n\n### 0.4.7 (2016-12-15)\n\nFeatures:\n * Bitshift operators.\n * Type checker: Warn when ``msg.value`` is used in non-payable function.\n * Code generator: Inject the Swarm hash of a metadata file into the bytecode.\n * Code generator: Replace expensive memcpy precompile by simple assembly loop.\n * Optimizer: Some dead code elimination.\n\nBugfixes:\n * Code generator: throw if calling the identity precompile failed during memory (array) copying.\n * Type checker: string literals that are not valid UTF-8 cannot be converted to string type\n * Code generator: any non-zero value given as a boolean argument is now converted into 1.\n * AST Json Converter: replace ``VariableDefinitionStatement`` nodes with ``VariableDeclarationStatement``\n * AST Json Converter: fix the camel case in ``ElementaryTypeNameExpression``\n * AST Json Converter: replace ``public`` field with ``visibility`` in the function definition nodes\n\n### 0.4.6 (2016-11-22)\n\nBugfixes:\n * Optimizer: Knowledge about state was not correctly cleared for JUMPDESTs (introduced in 0.4.5)\n\n### 0.4.5 (2016-11-21)\n\nFeatures:\n * Function types\n * Do-while loops: support for a ``do <block> while (<expr>);`` control structure\n * Inline assembly: support ``invalidJumpLabel`` as a jump label.\n * Type checker: now more eagerly searches for a common type of an inline array with mixed types\n * Code generator: generates a runtime error when an out-of-range value is converted into an enum type.\n\nBugfixes:\n\n * Inline assembly: calculate stack height warning correctly even when local variables are used.\n * Code generator: check for value transfer in non-payable constructors.\n * Parser: disallow empty enum definitions.\n * Type checker: disallow conversion between different enum types.\n * Interface JSON: do not include trailing new line.\n\n### 0.4.4 (2016-10-31)\n\nBugfixes:\n * Type checker: forbid signed exponential that led to an incorrect use of EXP opcode.\n * Code generator: properly clean higher order bytes before storing in storage.\n\n### 0.4.3 (2016-10-25)\n\nFeatures:\n\n * Inline assembly: support both ``suicide`` and ``selfdestruct`` opcodes\n   (note: ``suicide`` is deprecated).\n * Inline assembly: issue warning if stack is not balanced after block.\n * Include ``keccak256()`` as an alias to ``sha3()``.\n * Support shifting constant numbers.\n\nBugfixes:\n * Commandline interface: Disallow unknown options in ``solc``.\n * Name resolver: Allow inheritance of ``enum`` definitions.\n * Type checker: Proper type checking for bound functions.\n * Type checker: fixed crash related to invalid fixed point constants\n * Type checker: fixed crash related to invalid literal numbers.\n * Type checker: ``super.x`` does not look up ``x`` in the current contract.\n * Code generator: expect zero stack increase after ``super`` as an expression.\n * Code generator: fix an internal compiler error for ``L.Foo`` for ``enum Foo`` defined in library ``L``.\n * Code generator: allow inheritance of ``enum`` definitions.\n * Inline assembly: support the ``address`` opcode.\n * Inline assembly: fix parsing of assignment after a label.\n * Inline assembly: external variables of unsupported type (such as ``this``, ``super``, etc.)\n   are properly detected as unusable.\n * Inline assembly: support variables within modifiers.\n * Optimizer: fix related to stale knowledge about SHA3 operations\n\n### 0.4.2 (2016-09-17)\n\nBugfixes:\n\n * Code Generator: Fix library functions being called from payable functions.\n * Type Checker: Fixed a crash about invalid array types.\n * Code Generator: Fixed a call gas bug that became visible after\n   version 0.4.0 for calls where the output is larger than the input.\n\n### 0.4.1 (2016-09-09)\n\n * Build System: Fixes to allow library compilation.\n\n### 0.4.0 (2016-09-08)\n\nThis release deliberately breaks backwards compatibility mostly to\nenforce some safety features. The most important change is that you have\nto explicitly specify if functions can receive ether via the ``payable``\nmodifier. Furthermore, more situations cause exceptions to be thrown.\n\nMinimal changes to be made for upgrade:\n - Add ``payable`` to all functions that want to receive Ether\n   (including the constructor and the fallback function).\n - Change ``_`` to ``_;`` in modifiers.\n - Add version pragma to each file: ``pragma solidity ^0.4.0;``\n\nBreaking Changes:\n\n * Source files have to specify the compiler version they are\n   compatible with using e.g. ``pragma solidity ^0.4.0;`` or\n   ``pragma solidity >=0.4.0 <0.4.8;``\n * Functions that want to receive Ether have to specify the\n   new ``payable`` modifier (otherwise they throw).\n * Contracts that want to receive Ether with a plain \"send\"\n   have to implement a fallback function with the ``payable``\n   modifier. Contracts now throw if no payable fallback\n   function is defined and no function matches the signature.\n * Failing contract creation through \"new\" throws.\n * Division / modulus by zero throws.\n * Function call throws if target contract does not have code\n * Modifiers are required to contain ``_`` (use ``if (false) _`` as a workaround if needed).\n * Modifiers: return does not skip part in modifier after ``_``.\n * Placeholder statement `_` in modifier now requires explicit `;`.\n * ``ecrecover`` now returns zero if the input is malformed (it previously returned garbage).\n * The ``constant`` keyword cannot be used for constructors or the fallback function.\n * Removed ``--interface`` (Solidity interface) output option\n * JSON AST: General cleanup, renamed many nodes to match their C++ names.\n * JSON output: ``srcmap-runtime`` renamed to ``srcmapRuntime``.\n * Moved (and reworked) standard library contracts from inside the compiler to github.com/ethereum/solidity/std\n   (``import \"std\";`` or ``import owned;`` do not work anymore).\n * Confusing and undocumented keyword ``after`` was removed.\n * New reserved words: ``abstract``, ``hex``, ``interface``, ``payable``, ``pure``, ``static``, ``view``.\n\nFeatures:\n\n * Hexadecimal string literals: ``hex\"ab1248fe\"``\n * Internal: Inline assembly usable by the code generator.\n * Commandline interface: Using ``-`` as filename allows reading from stdin.\n * Interface JSON: Fallback function is now part of the ABI.\n * Interface: Version string now *SemVer* compatible.\n * Code generator: Do not provide \"new account gas\" if we know the called account exists.\n\nBugfixes:\n\n * JSON AST: Nodes were added at wrong parent\n * Why3 translator: Crash fix for exponentiation\n * Commandline Interface: linking libraries with underscores in their name.\n * Type Checker: Fallback function cannot return data anymore.\n * Code Generator: Fix crash when ``sha3()`` was used on unsupported types.\n * Code Generator: Manually set gas stipend for ``.send(0)``.\n\nLots of changes to the documentation mainly by voluntary external contributors.\n\n### 0.3.6 (2016-08-10)\n\nFeatures:\n\n * Formal verification: Take external effects on a contract into account.\n * Type Checker: Warning about unused return value of low-level calls and send.\n * Output: Source location and node id as part of AST output\n * Output: Source location mappings for bytecode\n * Output: Formal verification as part of json compiler output.\n\nBugfixes:\n\n * Commandline Interface: Do not crash if input is taken from stdin.\n * Scanner: Correctly support unicode escape codes in strings.\n * JSON output: Fix error about relative / absolute source file names.\n * JSON output: Fix error about invalid utf8 strings.\n * Code Generator: Dynamic allocation of empty array caused infinite loop.\n * Code Generator: Correctly calculate gas requirements for memcpy precompile.\n * Optimizer: Clear known state if two code paths are joined.\n\n### 0.3.5 (2016-06-10)\n\nFeatures:\n\n * Context-dependent path remappings (different modules can use the same library in different versions)\n\nBugfixes:\n\n * Type Checking: Dynamic return types were removed when fetching data from external calls, now they are replaced by an \"unusable\" type.\n * Type Checking: Overrides by constructors were considered making a function non-abstract.\n\n### 0.3.4 (2016-05-31)\n\nNo change outside documentation.\n\n### 0.3.3 (2016-05-27)\n\n * Allow internal library functions to be called (by \"inlining\")\n * Fractional/rational constants (only usable with fixed point types, which are still in progress)\n * Inline assembly has access to internal functions (as jump labels)\n * Running `solc` without arguments on a terminal will print help.\n * Bugfix: Remove some non-determinism in code generation.\n * Bugfix: Corrected usage of not / bnot / iszero in inline assembly\n * Bugfix: Correctly clean bytesNN types before comparison\n\n### 0.3.2 (2016-04-18)\n\n * Bugfix: Inline assembly parser: `byte` opcode was unusable\n * Bugfix: Error reporting: tokens for variably-sized types were not converted to string properly\n * Bugfix: Dynamic arrays of structs were not deleted correctly.\n * Bugfix: Static arrays in constructor parameter list were not decoded correctly.\n\n### 0.3.1 (2016-03-31)\n\n * Inline assembly\n * Bugfix: Code generation: array access with narrow types did not clean higher order bits\n * Bugfix: Error reporting: error reporting with unknown source location caused a crash\n\n### 0.3.0 (2016-03-11)\n\nBREAKING CHANGES:\n\n * Added new keywords `assembly`, `foreign`, `fixed`, `ufixed`, `fixedNxM`, `ufixedNxM` (for various values of M and N), `timestamp`\n * Number constant division does not round to integer, but to a fixed point type (e.g. `1 / 2 != 1`, but `1 / 2 == 0.5`).\n * Library calls now default to use DELEGATECALL (e.g. called library functions see the same value as the calling function for `msg.value` and `msg.sender`).\n * `<address>.delegatecall` as a low-level calling interface\n\nBugfixes:\n * Fixed a bug in the optimizer that resulted in comparisons being wrong.\n\n\n### 0.2.2 (2016-02-17)\n\n * Index access for types `bytes1`, ..., `bytes32` (only read access for now).\n * Bugfix: Type checker crash for wrong number of base constructor parameters.\n\n### 0.2.1 (2016-01-30)\n\n * Inline arrays, i.e. `var y = [1,x,f()];` if there is a common type for `1`, `x` and `f()`. Note that the result is always a fixed-length memory array and conversion to dynamic-length memory arrays is not yet possible.\n * Import similar to ECMAScript6 import (`import \"abc.sol\" as d` and `import {x, y} from \"abc.sol\"`).\n * Commandline compiler solc automatically resolves missing imports and allows for \"include directories\".\n * Conditional: `x ? y : z`\n * Bugfix: Fixed several bugs where the optimizer generated invalid code.\n * Bugfix: Enums and structs were not accessible to other contracts.\n * Bugfix: Fixed segfault connected to function parameter types, appeared during gas estimation.\n * Bugfix: Type checker crash for wrong number of base constructor parameters.\n * Bugfix: Allow function overloads with different array types.\n * Bugfix: Allow assignments of type `(x) = 7`.\n * Bugfix: Type `uint176` was not available.\n * Bugfix: Fixed crash during type checking concerning constructor calls.\n * Bugfix: Fixed crash during code generation concerning invalid accessors for struct types.\n * Bugfix: Fixed crash during code generating concerning computing a hash of a struct type.\n\n### 0.2.0 (2015-12-02)\n\n * **Breaking Change**: `new ContractName.value(10)()` has to be written as `(new ContractName).value(10)()`\n * Added `selfdestruct` as an alias for `suicide`.\n * Allocation of memory arrays using `new`.\n * Binding library functions to types via `using x for y`\n * `addmod` and `mulmod` (modular addition and modular multiplication with arbitrary intermediate precision)\n * Bugfix: Constructor arguments of fixed array type were not read correctly.\n * Bugfix: Memory allocation of structs containing arrays or strings.\n * Bugfix: Data location for explicit memory parameters in libraries was set to storage.\n\n### 0.1.7 (2015-11-17)\n\n * Improved error messages for unexpected tokens.\n * Proof-of-concept transcompilation to why3 for formal verification of contracts.\n * Bugfix: Arrays (also strings) as indexed parameters of events.\n * Bugfix: Writing to elements of `bytes` or `string` overwrite others.\n * Bugfix: \"Successor block not found\" on Windows.\n * Bugfix: Using string literals in tuples.\n * Bugfix: Cope with invalid commit hash in version for libraries.\n * Bugfix: Some test framework fixes on windows.\n\n### 0.1.6 (2015-10-16)\n\n * `.push()` for dynamic storage arrays.\n * Tuple expressions (`(1,2,3)` or `return (1,2,3);`)\n * Declaration and assignment of multiple variables (`var (x,y,) = (1,2,3,4,5);` or `var (x,y) = f();`)\n * Destructuring assignment (`(x,y,) = (1,2,3)`)\n * Bugfix: Internal error about usage of library function with invalid types.\n * Bugfix: Correctly parse `Library.structType a` at statement level.\n * Bugfix: Correctly report source locations of parenthesized expressions (as part of \"tuple\" story).\n\n### 0.1.5 (2015-10-07)\n\n * Breaking change in storage encoding: Encode short byte arrays and strings together with their length in storage.\n * Report warnings\n * Allow storage reference types for public library functions.\n * Access to types declared in other contracts and libraries via `.`.\n * Version stamp at beginning of runtime bytecode of libraries.\n * Bugfix: Problem with initialized string state variables and dynamic data in constructor.\n * Bugfix: Resolve dependencies concerning `new` automatically.\n * Bugfix: Allow four indexed arguments for anonymous events.\n * Bugfix: Detect too large integer constants in functions that accept arbitrary parameters.\n\n### 0.1.4 (2015-09-30)\n\n * Bugfix: Returning fixed-size arrays.\n * Bugfix: combined-json output of solc.\n * Bugfix: Accessing fixed-size array return values.\n * Bugfix: Disallow assignment from literal strings to storage pointers.\n * Refactoring: Move type checking into its own module.\n\n### 0.1.3 (2015-09-25)\n\n * `throw` statement.\n * Libraries that contain functions which are called via CALLCODE.\n * Linker stage for compiler to insert other contract's addresses (used for libraries).\n * Compiler option to output runtime part of contracts.\n * Compile-time out of bounds check for access to fixed-size arrays by integer constants.\n * Version string includes libevmasm/libethereum's version (contains the optimizer).\n * Bugfix: Accessors for constant public state variables.\n * Bugfix: Propagate exceptions in clone contracts.\n * Bugfix: Empty single-line comments are now treated properly.\n * Bugfix: Properly check the number of indexed arguments for events.\n * Bugfix: Strings in struct constructors.\n\n### 0.1.2 (2015-08-20)\n\n * Improved commandline interface.\n * Explicit conversion between `bytes` and `string`.\n * Bugfix: Value transfer used in clone contracts.\n * Bugfix: Problem with strings as mapping keys.\n * Bugfix: Prevent usage of some operators.\n\n### 0.1.1 (2015-08-04)\n\n * Strings can be used as mapping keys.\n * Clone contracts.\n * Mapping members are skipped for structs in memory.\n * Use only a single stack slot for storage references.\n * Improved error message for wrong argument count. (#2456)\n * Bugfix: Fix comparison between `bytesXX` types. (#2087)\n * Bugfix: Do not allow floats for integer literals. (#2078)\n * Bugfix: Some problem with many local variables. (#2478)\n * Bugfix: Correctly initialise `string` and `bytes` state variables.\n * Bugfix: Correctly compute gas requirements for callcode.\n\n### 0.1.0 (2015-07-10)\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n\n"
  },
  {
    "path": "README.md",
    "content": "# The Solidity Contract-Oriented Programming Language\n\n[![Matrix Chat](https://img.shields.io/badge/Matrix%20-chat-brightgreen?style=plastic&logo=matrix)](https://matrix.to/#/#ethereum_solidity:gitter.im)\n[![Gitter Chat](https://img.shields.io/badge/Gitter%20-chat-brightgreen?style=plastic&logo=gitter)](https://gitter.im/ethereum/solidity)\n[![Solidity Forum](https://img.shields.io/badge/Solidity_Forum%20-discuss-brightgreen?style=plastic&logo=discourse)](https://forum.soliditylang.org/)\n[![X Follow](https://img.shields.io/twitter/follow/solidity_lang?style=plastic&logo=x)](https://X.com/solidity_lang)\n[![Mastodon Follow](https://img.shields.io/mastodon/follow/000335908?domain=https%3A%2F%2Ffosstodon.org%2F&logo=mastodon&style=plastic)](https://fosstodon.org/@solidity)\n\nYou can talk to us on Gitter and Matrix, tweet at us on X (previously Twitter) or create a new topic in the Solidity forum. Questions, feedback, and suggestions are welcome!\n\nSolidity is a statically-typed, contract-oriented, high-level language for implementing smart contracts on the Ethereum platform.\n\nFor a good overview and starting point, please check out the official [Solidity Language Portal](https://soliditylang.org).\n\n## Table of Contents\n\n- [Background](#background)\n- [Build and Install](#build-and-install)\n- [Example](#example)\n- [Documentation](#documentation)\n- [Development](#development)\n- [Maintainers](#maintainers)\n- [License](#license)\n- [Security](#security)\n\n## Background\n\nSolidity is a statically-typed curly-braces programming language designed for developing smart contracts\nthat run on the Ethereum Virtual Machine. Smart contracts are programs that are executed inside a peer-to-peer\nnetwork where nobody has special authority over the execution, and thus they allow anyone to implement tokens of value,\nownership, voting, and other kinds of logic.\n\nWhen deploying contracts, you should use the latest released version of\nSolidity. This is because breaking changes, as well as new features and bug fixes, are\nintroduced regularly. We currently use a 0.x version\nnumber [to indicate this fast pace of change](https://semver.org/#spec-item-4).\n\n## Build and Install\n\nInstructions about how to build and install the Solidity compiler can be\nfound in the [Solidity documentation](https://docs.soliditylang.org/en/latest/installing-solidity.html#building-from-source).\n\n\n## Example\n\nA \"Hello World\" program in Solidity is of even less use than in other languages, but still:\n\n```solidity\n// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\ncontract HelloWorld {\n    function helloWorld() external pure returns (string memory) {\n        return \"Hello, World!\";\n    }\n}\n```\n\nTo get started with Solidity, you can use [Remix](https://remix.ethereum.org/), which is a\nbrowser-based IDE. Here are some example contracts:\n\n1. [Voting](https://docs.soliditylang.org/en/latest/solidity-by-example.html#voting)\n2. [Blind Auction](https://docs.soliditylang.org/en/latest/solidity-by-example.html#blind-auction)\n3. [Safe remote purchase](https://docs.soliditylang.org/en/latest/solidity-by-example.html#safe-remote-purchase)\n4. [Micropayment Channel](https://docs.soliditylang.org/en/latest/solidity-by-example.html#micropayment-channel)\n\n## Documentation\n\nThe Solidity documentation is hosted using [Read the Docs](https://docs.soliditylang.org).\n\n## Development\n\nSolidity is still under development. Contributions are always welcome!\nPlease follow the\n[Developer's Guide](https://docs.soliditylang.org/en/latest/contributing.html)\nif you want to help.\n\nYou can find our current feature and bug priorities for forthcoming\nreleases in the [projects section](https://github.com/argotorg/solidity/projects).\n\n## Maintainers\nThe Solidity programming language and compiler are open-source community projects governed by a core team.\nThe core team is sponsored by the [Ethereum Foundation](https://ethereum.foundation/).\n\n## License\nSolidity is licensed under [GNU General Public License v3.0](LICENSE.txt).\n\nSome third-party code has its [own licensing terms](cmake/templates/license.h.in).\n\n## Security\n\nThe security policy may be [found here](SECURITY.md).\n"
  },
  {
    "path": "ReleaseChecklist.md",
    "content": "# Checklist for making a Solidity release\n\n## Requirements\n- GitHub account with access to [solidity](https://github.com/argotorg/solidity), [solc-js](https://github.com/argotorg/solc-js),\n      [solc-bin](https://github.com/argotorg/solc-bin), [solidity-website](https://github.com/argotorg/solidity-website).\n- Personal Access Token (PAT) with `write:packages` scope to access Github's container registry.\n    You can generate one by visiting https://github.com/settings/tokens/new?scopes=write:packages.\n- Ubuntu/Debian dependencies of the Docker script: `docker-buildx`.\n- [npm Registry](https://www.npmjs.com) account added as a collaborator for the [`solc` package](https://www.npmjs.com/package/solc).\n- Access to the [solidity_lang Twitter account](https://twitter.com/solidity_lang).\n- [Reddit](https://www.reddit.com) account that is at least 10 days old with a minimum of 20 comment karma (`/r/ethereum` requirements).\n\n## Full release\n\n### Pre-flight checks\nAt least a day before the release:\n- [ ] Run `make linkcheck` from within `docs/` and fix any broken links it finds.\n      Ignore false positives caused by `href` anchors and dummy links not meant to work.\n      **Note**: In order to run the link check, make sure you've built the docs first via `docs.sh`.\n- [ ] Double-check that [the most recent docs builds at readthedocs](https://readthedocs.org/projects/solidity/builds/) succeeded.\n- [ ] Make sure that all merged PRs that should have changelog entries do have them.\n- [ ] 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:\n     - [ ] `solc-js`\n     - [ ] `solc-bin` (make sure the bytecode comparison check did run)\n- [ ] Verify that the release tarball of `solc-js` works.\n      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.\n- [ ] Review [Learning from Past Releases](https://notes.argot.org/@solidity-release-mistakes) to make sure you don't repeat the same mistakes.\n\n### Drafts\nAt least a day before the release:\n- [ ] Create a draft PR to sort the changelog.\n- [ ] Create draft PRs to bump version in `solidity` and `solc-js`.\n      **Note**: The `solc-js` PR won't pass CI checks yet because it depends on the soljson binary from `solc-bin`.\n- [ ] Create a draft of the release on github.\n- [ ] Create a draft PR to update soliditylang.org.\n- [ ] Create drafts of blog posts.\n- [ ] Prepare drafts of Twitter, Reddit and Solidity Forum announcements.\n\n### Website/Blog Updates\n- [ ] Create a post on [solidity-website](https://github.com/argotorg/solidity-website/tree/main/src/posts) in the `Releases` category and explain some of the new features or concepts.\n- [ ] Create a post on [solidity-website](https://github.com/argotorg/solidity-website/tree/main/src/posts) in the `Security Alerts` category in case of important bug(s).\n- [ ] Update the release information section [in the source of soliditylang.org](https://github.com/argotorg/solidity-website/blob/main/src/pages/index.tsx).\n- [ ] Get the PR(s) for the above reviewed and approved **before the release starts**, but don't merge them yet.\n\n### Changelog\n- [ ] Ensure that all changelog entries are correctly classified as language or compiler features.\n- [ ] Sort the changelog entries alphabetically and correct any errors you notice. Commit it.\n- [ ] Update the changelog to include a release date.\n- [ ] Run `scripts/update_bugs_by_version.py` to regenerate `bugs_by_version.json` from the changelog and `bugs.json`.\n      Make sure that the resulting `bugs_by_version.json` has a new, empty entry for the new version.\n- [ ] Commit changes, create a pull request and wait for the tests. Then merge it.\n- [ ] Copy the changelog into the release blog post.\n\n### Create the Release\n- [ ] Create a [release on GitHub](https://github.com/argotorg/solidity/releases/new).\n      Set the target to the `develop` branch and the tag to the new version, e.g. `v0.8.5`.\n      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.**`.\n      Do not publish it yet - click the `Save draft` button instead.\n- [ ] Thank voluntary contributors in the GitHub release notes.\n      Use `scripts/list_contributors.sh v<previous version>` to get initial list of names.\n      Remove different variants of the same name manually before using the output.\n- [ ] Check that all tests on the latest commit on `develop` are green.\n- [ ] Click the `Publish release` button on the release page, creating the tag.\n      **Important: Must not be done before all the PRs, including changelog cleanup and date, are merged.**\n- [ ] Wait for the CI runs on the tag itself.\n\n### Upload Release Artifacts and Publish Binaries\n- [ ] Take the source tarball (`solidity_x.x.x.tar.gz`) from `c_source_tarball` run of the tagged commit on Circle CI and upload it to the release page.\n- [ ] Take the `github-binaries.tar` tarball from `c_release_binaries` run of the tagged commit on Circle CI and add all binaries from it to the release page.\n      Make sure it contains five binaries: `solc-windows.exe`, `solc-macos`, `solc-static-linux`, `solc-static-linux-arm`, and `soljson.js`.\n- [ ] Take the `solc-bin-binaries.tar` tarball from `c_release_binaries` run of the tagged commit on Circle CI and add all binaries from it to solc-bin.\n- [ ] Run `npm install` if you've got a clean checkout of the solc-bin repo.\n- [ ] 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/`.\n- [ ] Create a pull request in solc-bin and merge.\n\n### Homebrew and MacOS\n- [ ] 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).\n\n### Docker\n- [ ] Make sure `docker-buildx` is installed.\n- [ ] Run `echo $GHCR_TOKEN | docker login ghcr.io --username $GH_USERNAME --password-stdin` where `$GH_USERNAME` is your GitHub username and `$GHCR_TOKEN` is a PAT with `write:packages` scope.\n- [ ] Run `./scripts/docker_deploy_manual.sh v$VERSION`.\n\n### Release solc-js\n- [ ] Wait until solc-bin was properly deployed. You can test this via remix - a test run through remix is advisable anyway.\n- [ ] Increment the version number, create a pull request for that, merge it after tests succeeded.\n- [ ] Create a tag using `git tag --annotate v$VERSION` and push it with `git push --tags`.\n- [ ] Wait for the CI runs on the tag itself.\n- [ ] Take the `solc-x.y.z.tgz` artifact from `build-package` run on the tagged commit on Circle CI.\n      Inspect the tarball to ensure that it contains an up-to-date compiler binary (`soljson.js`).\n- [ ] Run `npm publish solc-x.y.z.tgz` to publish the newly created tarball.\n\n### Documentation\n- [ ] Make sure the documentation for the new release has been published successfully.\n      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.\n- [ ] Remove \"still in progress\" warning from the [release notes](https://github.com/argotorg/solidity/releases).\n\n### Comms\n- [ ] Merge the blog posts and website updates prepared for the release.\n- [ ] Verify that the link to the blog post in [release notes](https://github.com/argotorg/solidity/releases) is not broken.\n- [ ] Announce on [Twitter](https://twitter.com/solidity_lang), including links to the release and the blog post.\n- [ ] Announce on [Fosstodon](https://fosstodon.org/@solidity/), including links to the release and the blog post.\n- [ ] Share the announcement on Reddit in [`/r/ethdev`](https://reddit.com/r/ethdev/), cross-posted to [`/r/ethereum`](https://reddit.com/r/ethereum/).\n- [ ] Share the announcement on the [Solidity forum](https://forum.soliditylang.org) in the `Announcements` category.\n- [ ] Share the announcement on [`#solidity` channel on Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im).\n- [ ] Share the announcement on [`#solc-tooling`](https://matrix.to/#/#solc-tooling:matrix.org).\n\n### Post-release\n- [ ] Create a commit to increase the version number on `develop` in `CMakeLists.txt` and add a new skeleton changelog entry.\n- [ ] If anything went wrong this time, mention it in [Learning from Past Releases](https://notes.argot.org/@solidity-release-mistakes).\n- [ ] Bump vendored dependencies.\n- [ ] Lean back, wait for bug reports and repeat from step 1 :).\n\n## Prerelease\n- [ ] Check that all tests on the latest commit on `develop` or `breaking` branch (whichever was chosen for the prerelease) are green.\n- [ ] Create a [release on GitHub](https://github.com/argotorg/solidity/releases/new).\n    - Set the target to the `develop` or `breaking` branch and the tag to the new version with a prerelease suffix, e.g. `v0.8.5-pre.6`.\n        Version matches the next release (`develop`) or the next breaking release (`breaking`).\n        The prerelease number in the suffix is 1-based, sequential, resets after a full release and is counted separately for `develop` and `breaking`.\n    - 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.**`.\n    - Include the current, incomplete changelog.\n    - Check the `Set as a pre-release` box.\n    - Click the `Publish release` button on the release page, creating the tag.\n- [ ] Wait for the CI runs on the tag itself.\n- [ ] Take the source tarball (`solidity_x.x.x-pre.N.tar.gz`) from `c_source_tarball` run of the tagged commit on Circle CI and upload it to the release page.\n- [ ] Take the `github-binaries.tar` tarball from `c_release_binaries` run of the tagged commit on Circle CI and add all binaries from it to the release page.\n      Make sure it contains five binaries: `solc-windows.exe`, `solc-macos`, `solc-static-linux`, `solc-static-linux-arm` and `soljson.js`.\n- [ ] Take the `solc-bin-binaries.tar` tarball from `c_release_binaries` run of the tagged commit on Circle CI and add all binaries from it to solc-bin.\n- [ ] Run `npm install` if you've got a clean checkout of the solc-bin repo.\n- [ ] 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/`.\n- [ ] Create a pull request in solc-bin and merge.\n- [ ] Remove \"still in progress\" warning from the [release notes](https://github.com/argotorg/solidity/releases).\n- [ ] Mention it on [Twitter](https://twitter.com/solidity_lang).\n- [ ] Mention it on [Fosstodon](https://fosstodon.org/@solidity/).\n- [ ] Mention it on [`#solidity` channel on Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im).\n- [ ] Mention it on [`#solc-tooling`](https://matrix.to/#/#solc-tooling:matrix.org).\n- [ ] If anything went wrong this time, mention it in [Learning from Past Releases](https://notes.argot.org/@solidity-release-mistakes).\n- [ ] Lean back, wait for bug reports and repeat from step 1 :).\n"
  },
  {
    "path": "ReviewChecklist.md",
    "content": "# PR Review Checklist\nThe Solidity compiler is a critical piece of infrastructure in the Ethereum ecosystem.\nFor this reason, our review process is quite strict and all PRs have to fulfill certain quality\nexpectations and guidelines.\nThe list below is meant to reduce the workload on the core team by helping contributors self-identify\nand solve common issues before they are pointed out in the review.\nIt is also meant to serve as a final checklist for reviewers to go through before approving a PR.\n\n## Before You Submit a PR\n- [ ] **Do you have any other open PRs?**\n    Work on a PR is not done until it is merged or closed.\n    Our reviewing capacity is limited, so we require that external contributors work on **no more than one PR at a time**.\n    - If your PR is not getting reviewed, feel free to bring it to our attention on the [#solidity-dev](https://gitter.im/ethereum/solidity-dev) channel.\n    - Unless they were requested, we are going to close any excess PRs, leaving only the earliest one open.\n        You may reopen them, one at a time, when your current PR is done.\n- [ ] **Is the issue ready to be worked on?**\n    - If the issue does not have a desirability label (`nice to have`, `should have`,\n        `must have eventually`, `must have`, `roadmap`) we have not yet decided whether to implement it.\n    - If the issue has the `needs design` label, we have not yet decided how it should be implemented.\n    - `good first issue candidate` means that the issue will potentially be a `good first issue`\n        eventually but at the moment it is not yet ready to be worked on.\n- [ ] **Is this a breaking change?** Breaking changes should be based on the `breaking` branch rather than on the `develop` branch.\n- [ ] **Does the PR actually address the issue?**\n    - [ ] Mention the issue number in the PR description.\n        If the PR solves it completely, use the `Fixes #<issue number>` form so that Github will close the issue automatically.\n    - [ ] Do not include the issue number in the PR title, branch name or commit description.\n- [ ] When submitting a PR from a fork **create a branch and give it a descriptive name.**\n    E.g. `fix-array-abi-encoding-bug`.\n    Do not submit PRs directly from the `develop` branch of your fork since it makes rebasing and fetching new changes harder.\n- [ ] **Does the PR depend on other PRs?**\n    - [ ] If the PR has dependencies, mention them in bold in the description.\n    - [ ] Avoid basing PRs from forks on branches other than `develop` or `breaking` because\n        GitHub closes them when the base branch gets merged.\n        Do this only for PRs created directly in the main repo.\n- [ ] **Does the PR update test expectations to match the modified code?** If not, your PR will not pass some of the `_soltest_`,  jobs in CI.\n    In many cases the expectations can be updated automatically:\n    - `cmdlineTests.sh --update` for command-line tests.\n    - `isoltest --enforce-gas-cost --accept-updates` for soltest-based tests.\n        - If your PR affects gas costs, an extra run of `isoltest --enforce-gas-cost --optimize --accept-updates` is needed to update gas expectations with optimizer enabled.\n    - Review updated files before committing them.\n        **Are expectations correct and do updated tests still serve their purpose?**\n\n## Abandoned PRs\n- [ ] **Is the submitter still responsive?**\n    - If the PR had no activity from the submitter in the last 2 weeks (despite receiving reviews and our prompts) we consider it abandoned.\n- [ ] **Is the abandoned PR easy to finish or relevant?**\n    - Apply the `takeover` label if the PR can be finished without significant effort or is something that actually needs to be done right now.\n        Otherwise close it.\n        It can still be taken over later or reopened by the submitter but until then we should not be getting sidetracked by it.\n\n## Light Review\nBefore an in-depth review, it is recommended to give new PRs a quick, superficial review, which\nis not meant to provide complete and detailed feedback, but instead give the submitter a rough idea\nif the PR is even on the right track and let them solve the obvious problems on their own.\n\nLight review should focus on the following three areas:\n- [ ] **Are there any obvious mistakes?** Style issues, bad practices, easy to identify bugs, etc.\n- [ ] **Is there anything missing?** Tests (of the right kind), documentation, etc. Does it address the whole issue?\n- [ ] **Is it the right solution?** Are there better ways to do this? Is the change even necessary?\n\nIf the answers above are \"Yes, Yes, No\", thank the contributor for their effort and **close the PR**.\n\n## Coding Style and Good Practices\n- [ ] Does the PR follow our [coding style](CODING_STYLE.md)?\n\n### Reliability\n- [ ] **Use assertions liberally.** If you are certain your assumption will not be broken, prove it with `solAssert()`.\n- [ ] **Validate inputs and handle errors**. Note that assertions are **not** validation.\n\n### Readability\n- [ ] **Choose good names.**\n    - [ ] Is the name straightforward to understand?\n        Do you feel the need to jump back to the definition and remind yourself what it was whenever you see it?\n    - [ ] Is the name unambiguous in the context where it is used?\n    - [ ] Avoid abbreviations.\n- [ ] **Source files, classes and public functions should have docstrings.**\n- [ ] **Avoid code duplication.** But not fanatically. Minimal amounts of duplication are acceptable if it aids readability.\n- [ ] **Do not leave dead or commented-out code behind.** You can still see old code in history.\n      If you really have a good reason to do it, always leave a comment explaining what it is and why it is there.\n- [ ] **Mark hacks as such.** If you have to leave behind a temporary workaround, make\n    sure to include a comment that explains why and in what circumstances it can be removed.\n    Preferably link to an issue you reported upstream.\n- [ ] **Avoid obvious comments.**\n- [ ] **Do include comments when the reader may need extra context to understand the code.**\n\n### Commits and PRs\n- [ ] **Avoid hiding functional changes inside refactors.**\n    E.g. when fixing a small bug, or changing user-visible behavior, put the change in a separate commit.\n    Do not mix it with another change that renames things or reformats the code around, making the fix itself hard to identify.\n- [ ] **Whenever possible, split off refactors or unrelated changes into separate PRs.**\n    Smaller PRs are easier and quicker to review.\n    Splitting off refactors helps focus on the main point of the PR.\n\n### Common Pitfalls\nThe following points are all covered by the coding style but come up so often that it is worth singling them out here:\n- [ ] **Always initialize value types in the definition,** even if you are sure you will assign them later.\n- [ ] **Use \"east const\" style.** I.e. `T const*`, not `const T *`.\n- [ ] **Keep indentation consistent.** See our [`.editorconfig`](.editorconfig).\n    - [ ] Tabs for C++. But use them for indentation only. Any whitespace later on the line must consist of spaces.\n    - [ ] 4 spaces for most other file types.\n- [ ] **Use `auto` sparingly.** Only use it when the actual type is very long and complicated or when it is\n    already used elsewhere in the same expression.\n- [ ] **Indent braces and parentheses in a way that makes nesting clear.**\n- [ ] **Use `using namespace` only in `.cpp` files.** Use it for `std` and our own modules.\n    Avoid unnecessary `std::` prefix in `.cpp` files (except for `std::move` and `std::forward`).\n- [ ] **Use range-based loops and destructuring.**\n- [ ] **Include any headers you use directly,** even if they are implicitly included through other headers.\n\n## Documentation\n- [ ] **Does the PR update relevant documentation?**\n\n### Documentation Style and Good Practices\n- [ ] **Use double backticks in RST (``` ``x`` ```). Prefer single backticks in Markdown (`` `x` ``),**\n    but note that double backticks are valid too and we use them in some cases for legacy reasons.\n- [ ] **Always start a new sentence on a new line.**\n    This way you do not have to rewrap the surrounding text when you rewrite the sentence.\n    This also makes changes actually easier to spot in the diff.\n\n## Testing\n\n### What to Test\n- [ ] **Is newly added code adequately covered by tests?** Have you considered all the important corner cases?\n- If it is a bugfix:\n    - [ ] **The PR must include tests that reproduce the bug.**\n    - [ ] **Are there gaps in test coverage of the buggy feature?** Fill them by adding more tests.\n    - [ ] **Try to break it.** Can you think of any similar features that could also be buggy?\n        Play with the repro and include prominent variants as separate test cases, even if they don't trigger a bug.\n- [ ] **Positive cases (code that compiles) should have a semantic test.**\n- [ ] **Negative cases (code with compilation errors) should have a syntax test.**\n- [ ] **Avoid mixing positive and negative cases in the same syntax test.**\n    If the test produces an error, we stop at the analysis stage and we will not detect\n    problems that only occur in code generation, optimizer or assembler.\n    - [ ] If you have to do it, at least mark positive cases inside the file with a short comment.\n        - This way, when the test is updated, it is easier to verify that these cases still do not trigger an error.\n- [ ] New syntax: **does it have an [`ASTJSON`](test/libsolidity/ASTJSON/) test?**\n- [ ] New CLI or StandardJSON option:\n    - [ ] **Does it have a [command-line test](test/cmdlineTests/)?**\n    - [ ] **Is the option listed for every input mode in [`CommandLineParser` tests](test/solc/CommandLineParser.cpp)?**\n- [ ] **Did you consider interactions with other language features?**\n    - [ ] Are all types covered? Structs? Enums? Contracts/libraries/interfaces? User-defined value types?\n        Value types: integers, fixed bytes, `address`, `address payable`, `bool`? Function pointers?\n        Static and dynamic arrays? `string` and `bytes`? Mappings?\n        Values of types that cannot be named: literals, tuples, array slices, storage references?\n    - [ ] If it accepts a function, does it also accept an event or an error? These have function types but are not functions.\n    - [ ] If it affects free functions, what about internal library functions?\n    - [ ] Attached library functions? Functions attached with `using for`?\n    - [ ] Possible combinations of `storage`, `memory`, `calldata`, `immutable`, `constant`?\n        Remember that internal functions can take `storage` arguments.\n    - [ ] Does it work at construction time as well? What if you store it at construction time and read after deployment?\n    - [ ] What about importing it from a different module or inheriting it?\n    - [ ] Have you tested it with the ternary operator?\n\n### Test Style and Good Practices\n- [ ] **Make test case file names long and specific enough** so that it is easy to guess what is inside.\n    When checking if we have the case already covered the name is usually the only clue we see.\n    - [ ] Place them in the right subdirectory.\n    - [ ] **Avoid simply appending numbers to the name to distinguish similar cases.**\n        Coming up with good names is hard but figuring out if any of hundreds of tests with names that\n        match your search actually fits your case is even harder.\n- [ ] **Do not include version pragma and the SPDX comment in semantic and syntax test cases**.\n    In other test types include them if necessary to suppress warnings.\n- [ ] **If you have to use a version pragma, avoid hard-coding version.** Use `pragma solidity *`.\n- [ ] **When writing StandardJSON command-line tests, use `urls` instead of `content`** and put\n    the Solidity or Yul code in a separate file.\n\n## Compiler-specific\n- [ ] **Are error messages sensible and understandable to users?**\n- [ ] **Are error codes consistent?**\n    - [ ] Avoid randomly changing or reassigning error codes.\n    - [ ] Avoid defining separate codes for trivial variants of the same issue.\n        Make it easy for tools to consistently refer to the same error with the same code.\n- [ ] **Error messages should end with a full stop.**\n- [ ] **Prefer Ranges v3 to Boost where possible.**\n\n## Take a Step Back\n- [ ] **Do you fully understand what the PR does and why?**\n- [ ] **Are you confident that the code works and does not break unrelated functionality?**\n- [ ] **Is this a reasonable way to achieve the goal stated in the issue?**\n- [ ] **Is the code simple?** Does the PR achieve its objective at the cost of significant\n    complexity that may be a source of future bugs?\n- [ ] **Is the code efficient?** Does the PR introduce any major performance bottlenecks?\n- [ ] **Does the PR introduce any breaking changes beyond what was agreed in the issue?**\n\n## Final Checks Before Merging\n- [ ] **Is the PR rebased on top of the `develop` branch** (or `breaking` if it is a breaking change)?\n- [ ] **Did all CI checks pass?**\n    - Note that we have a few jobs that tend to randomly fail due to outside factors, especially external tests (with `_ext_` in the name).\n        If these fail, rebase on latest `develop` (or `breaking`) and try rerunning them.\n        Note also that not all of these checks are required for the PR to be merged.\n- [ ] If the change is visible to users, **does the PR have a [changelog](Changelog.md) entry?**\n    - [ ] Is the changelog entry in the right section?\n        Make sure to move it up if there was a release recently.\n- [ ] **Is commit history simple and understandable?**\n    - [ ] Each commit should be a self-contained, logical step leading the goal of the PR, without going back and forth.\n        In particular, review fixups should be squashed into the commits they fix.\n    - [ ] Do not include any merge commits in your branch. Please use rebase to keep up to date with the base branch.\n- [ ] **Is the PR properly labeled?**\n    - Use `external contribution` label to mark PRs not coming from the core team.\n    - If the PR depends on other PRs, use `has dependencies` and set the base branch accordingly.\n    - Labels like `documentation` or `optimizer` are helpful for filtering PRs.\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\nThe Solidity team and community take all security bugs in Solidity seriously.\nWe appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions.\n\n## Scope\n\nBugs in the Solidity repository are in scope.\nBugs in third-party dependencies e.g., jsoncpp, boost etc. are not in scope unless they result in a Solidity specific bug.\n\nOnly bugs that have a demonstrable security impact on smart contracts are in scope.\nFor example, a Solidity program whose optimization is incorrect (e.g., leads to an incorrect output) qualifies as a security bug.\nPlease note that the [rules][2] of the [Ethereum bounty program][1] have precedence over this security policy.\n\n## Supported Versions\n\nAs a general rule, only the latest release gets security updates.\nExceptions may be made when the current breaking release is relatively new, e.g. less than three months old.\nIf you are reporting a bug, please state clearly the Solidity version(s) it affects.\n\nExample 1: Assuming the current release is `0.6.3` and a security bug has been found in it that affects both `0.5.x` and `0.6.x` trees, we may not only patch `0.6.3` (the bug-fix release numbered `0.6.4`) but `0.5.x` as well (the bug-fix release numbered `0.5.(x+1)`).\n\nExample 2: Assuming the current release is `0.6.25` and a security bug has been found in it, we may only patch `0.6.25` (in the bug-fix release numbered `0.6.26`) even if the bug affects a previous tree such as `0.5.x`.\n\n## Reporting a Vulnerability\n\nTo report a vulnerability, please follow the instructions stated in the [Ethereum bounty program][1].\n\nIn the bug report, please include all details necessary to reproduce the vulnerability such as:\n\n- Input program that triggers the bug\n- Compiler version affected\n- Target EVM version\n- Framework/IDE if applicable\n- EVM execution environment/client if applicable\n- Operating system\n\nPlease include steps to reproduce the bug you have found in as much detail as possible.\n\nOnce we have received your bug report, we will try to reproduce it and provide a more detailed response.\nOnce the reported bug has been successfully reproduced, the Solidity team will work on a fix.\n\nThe Solidity team maintains the following JSON-formatted lists of patched security vulnerabilities:\n\n- [Summary of known security vulnerabilities][3]\n- [List of security vulnerabilities affecting a specific version of the compiler][4].\n\n\n[1]: https://bounty.ethereum.org/\n[2]: https://bounty.ethereum.org/#rules\n[3]: https://docs.soliditylang.org/en/develop/bugs.html\n[4]: https://github.com/argotorg/solidity/blob/develop/docs/bugs_by_version.json\n"
  },
  {
    "path": "cmake/EthBuildInfo.cmake",
    "content": "function(create_build_info NAME)\n\n\t# Set build platform; to be written to BuildInfo.h\n\tset(ETH_BUILD_OS \"${CMAKE_SYSTEM_NAME}\")\n\n\tif (CMAKE_COMPILER_IS_MINGW)\n\t\tset(ETH_BUILD_COMPILER \"mingw\")\n\telseif (CMAKE_COMPILER_IS_MSYS)\n\t\tset(ETH_BUILD_COMPILER \"msys\")\n\telseif (CMAKE_COMPILER_IS_GNUCXX)\n\t\tset(ETH_BUILD_COMPILER \"g++\")\n\telseif (\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"MSVC\")\n\t\tset(ETH_BUILD_COMPILER \"msvc\")\n\telseif (\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"Clang\")\n\t\tset(ETH_BUILD_COMPILER \"clang\")\n\telseif (\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"AppleClang\")\n\t\tset(ETH_BUILD_COMPILER \"appleclang\")\n\telse ()\n\t\tset(ETH_BUILD_COMPILER \"unknown\")\n\tendif ()\n\n\tset(ETH_BUILD_PLATFORM \"${ETH_BUILD_OS}.${ETH_BUILD_COMPILER}\")\n\n\t#cmake build type may be not speCified when using msvc\n\tif (CMAKE_BUILD_TYPE)\n\t\tset(_cmake_build_type ${CMAKE_BUILD_TYPE})\n\telse()\n\t\tset(_cmake_build_type \"${CMAKE_CFG_INTDIR}\")\n\tendif()\n\n\t# Generate header file containing useful build information\n\tadd_custom_target(${NAME}_BuildInfo.h ALL\n\t\tWORKING_DIRECTORY ${PROJECT_SOURCE_DIR}\n\t\tCOMMAND ${CMAKE_COMMAND} -DETH_SOURCE_DIR=${PROJECT_SOURCE_DIR} -DETH_BUILDINFO_IN=${ETH_CMAKE_DIR}/templates/BuildInfo.h.in -DETH_DST_DIR=${PROJECT_BINARY_DIR}/include/${PROJECT_NAME} -DETH_CMAKE_DIR=${ETH_CMAKE_DIR}\n\t\t-DETH_BUILD_TYPE=\"${_cmake_build_type}\"\n\t\t-DETH_BUILD_OS=\"${ETH_BUILD_OS}\"\n\t\t-DETH_BUILD_COMPILER=\"${ETH_BUILD_COMPILER}\"\n\t\t-DETH_BUILD_PLATFORM=\"${ETH_BUILD_PLATFORM}\"\n\t\t-DPROJECT_VERSION=\"${PROJECT_VERSION}\"\n\t\t-DPROJECT_VERSION_MAJOR=\"${PROJECT_VERSION_MAJOR}\"\n\t\t-DPROJECT_VERSION_MINOR=\"${PROJECT_VERSION_MINOR}\"\n\t\t-DPROJECT_VERSION_PATCH=\"${PROJECT_VERSION_PATCH}\"\n\t\t-P \"${ETH_SCRIPTS_DIR}/buildinfo.cmake\"\n\t\t)\n\tinclude_directories(\"${PROJECT_BINARY_DIR}/include\")\nendfunction()\n"
  },
  {
    "path": "cmake/EthCcache.cmake",
    "content": "# Setup ccache.\n#\n# The ccache is auto-enabled if the tool is found.\n# To disable set -DCCACHE=OFF option.\nif(NOT DEFINED CMAKE_CXX_COMPILER_LAUNCHER)\n  find_program(CCACHE ccache DOC \"ccache tool path; set to OFF to disable\")\n  if(CCACHE)\n    set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE})\n    if(COMMAND cotire)\n      # Change ccache config to meet cotire requirements.\n      set(ENV{CCACHE_SLOPPINESS} pch_defines,time_macros)\n    endif()\n    message(STATUS \"[ccache] Enabled: ${CCACHE}\")\n  endif()\nendif()\n"
  },
  {
    "path": "cmake/EthCheckCXXCompilerFlag.cmake",
    "content": "include(CheckCXXCompilerFlag)\n\n# Adds CXX compiler flag if the flag is supported by the compiler.\n#\n# This is effectively a combination of CMake's check_cxx_compiler_flag()\n# and add_compile_options():\n#\n#    if(check_cxx_compiler_flag(flag))\n#        add_compile_options(flag)\n#\nfunction(eth_add_cxx_compiler_flag_if_supported FLAG)\n  # Remove leading - or / from the flag name.\n  string(REGEX REPLACE \"^[-/]\" \"\" name ${FLAG})\n  # Deletes any ':' because it's invalid variable names.\n  string(REGEX REPLACE \":\" \"\" name ${name})\n  check_cxx_compiler_flag(${FLAG} ${name})\n  if(${name})\n    add_compile_options(${FLAG})\n  endif()\n\n  # If the optional argument passed, store the result there.\n  if(ARGV1)\n    set(${ARGV1} ${name} PARENT_SCOPE)\n  endif()\nendfunction()\n"
  },
  {
    "path": "cmake/EthCompilerSettings.cmake",
    "content": "#------------------------------------------------------------------------------\n# EthCompilerSettings.cmake\n#\n# CMake file for cpp-ethereum project which specifies our compiler settings\n# for each supported platform and build configuration.\n#\n# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org\n#\n# Copyright (c) 2014-2016 cpp-ethereum contributors.\n#------------------------------------------------------------------------------\n\n# Clang seeks to be command-line compatible with GCC as much as possible, so\n# most of our compiler settings are common between GCC and Clang.\n#\n# These settings then end up spanning all POSIX platforms (Linux, OS X, BSD, etc)\n\ninclude(EthCheckCXXCompilerFlag)\n\nif(NOT EMSCRIPTEN)\n\teth_add_cxx_compiler_flag_if_supported(-fstack-protector-strong have_stack_protector_strong_support)\n\tif(NOT have_stack_protector_strong_support)\n\t\teth_add_cxx_compiler_flag_if_supported(-fstack-protector)\n\tendif()\nendif()\n\nif(PEDANTIC)\n\teth_add_cxx_compiler_flag_if_supported(-Wimplicit-fallthrough)\nendif()\n\n# Prevent the path of the source directory from ending up in the binary via __FILE__ macros.\neth_add_cxx_compiler_flag_if_supported(\"-fmacro-prefix-map=${PROJECT_SOURCE_DIR}=/solidity\")\n\n# -Wpessimizing-move warns when a call to std::move would prevent copy elision\n# if the argument was not wrapped in a call.  This happens when moving a local\n# variable in a return statement when the variable is the same type as the\n# return type or using a move to create a new object from a temporary object.\nif(PEDANTIC)\n\teth_add_cxx_compiler_flag_if_supported(-Wpessimizing-move)\nendif()\n\n# -Wredundant-move warns when an implicit move would already be made, so the\n# std::move call is not needed, such as when moving a local variable in a return\n# that is different from the return type.\nif(PEDANTIC)\n\teth_add_cxx_compiler_flag_if_supported(-Wredundant-move)\nendif()\n\nif ((\"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"GNU\") OR (\"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"Clang\"))\n\t# Enables all the warnings about constructions that some users consider questionable,\n\t# and that are easy to avoid.  Also enable some extra warning flags that are not\n\t# enabled by -Wall.   Finally, treat at warnings-as-errors, which forces developers\n\t# to fix warnings as they arise, so they don't accumulate \"to be fixed later\".\n\tif(PEDANTIC)\n\t\tadd_compile_options(-Wall)\n\t\tadd_compile_options(-Wextra)\n\t\tadd_compile_options(-Werror)\n\t\tadd_compile_options(-pedantic)\n\t\tadd_compile_options(-Wmissing-declarations)\n\t\tadd_compile_options(-Wno-unknown-pragmas)\n\t\tadd_compile_options(-Wimplicit-fallthrough)\n\t\tadd_compile_options(-Wsign-conversion)\n\t\tadd_compile_options(-Wconversion)\n\n\t\tcheck_cxx_compiler_flag(-Wextra-semi WEXTRA_SEMI)\n\t\tif(WEXTRA_SEMI)\n\t\t\tadd_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wextra-semi>)\n\t\tendif()\n\t\t# See https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=6b927b1297e66e26e62e722bf15c921dcbbd25b9\n\t\tcheck_cxx_compiler_flag(-Wno-dangling-reference WNO_DANGLING_REFERENCE)\n\t\tif (WNO_DANGLING_REFERENCE)\n            add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-dangling-reference>)\n\t\tendif()\n\n\n\t\teth_add_cxx_compiler_flag_if_supported(-Wfinal-dtor-non-final-class)\n\t\teth_add_cxx_compiler_flag_if_supported(-Wnewline-eof)\n\t\teth_add_cxx_compiler_flag_if_supported(-Wsuggest-destructor-override)\n\t\teth_add_cxx_compiler_flag_if_supported(-Wduplicated-cond)\n\t\teth_add_cxx_compiler_flag_if_supported(-Wduplicate-enum)\n\t\teth_add_cxx_compiler_flag_if_supported(-Wlogical-op)\n\t\teth_add_cxx_compiler_flag_if_supported(-Wno-unknown-attributes)\n\tendif()\n\n\t# Configuration-specific compiler settings.\n\tset(CMAKE_CXX_FLAGS_DEBUG          \"-O0 -g3 -DETH_DEBUG\")\n\tset(CMAKE_CXX_FLAGS_MINSIZEREL     \"-Os -DNDEBUG\")\n\tset(CMAKE_CXX_FLAGS_RELEASE        \"-O3 -DNDEBUG\")\n\tset(CMAKE_CXX_FLAGS_RELWITHDEBINFO \"-O2 -g3\")\n\n\t# Additional GCC-specific compiler settings.\n\tif (\"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"GNU\")\n\t\t# Check that we've got GCC 11.0 or newer.\n\t\tif (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0))\n\t\t\tmessage(FATAL_ERROR \"${PROJECT_NAME} requires g++ 11.0 or greater.\")\n\t\tendif ()\n\n\t\t# GCC 12 emits warnings for string concatenations with operator+ under O3\n\t\t# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105651\n\t\tif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.0)\n\t\t\tadd_compile_options(-Wno-error=restrict)\n\t\tendif ()\n\n\t\t# Use fancy colors in the compiler diagnostics\n\t\tadd_compile_options(-fdiagnostics-color)\n\n\t# Additional Clang-specific compiler settings.\n\telseif (\"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"Clang\")\n\t\t# Check that we've got clang 14.0 or newer.\n\t\tif (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 14.0))\n\t\t\tmessage(FATAL_ERROR \"${PROJECT_NAME} requires clang++ 14.0 or greater.\")\n\t\tendif ()\n\n\t\t# use std::invoke_result, superseding std::result_of which has been removed in c++20\n\t\tadd_compile_definitions(BOOST_ASIO_HAS_STD_INVOKE_RESULT)\n\t\tif (\"${CMAKE_SYSTEM_NAME}\" MATCHES \"Darwin\")\n\t\t\t# Set stack size to 32MB - by default Apple's clang defines a stack size of 8MB.\n\t\t\t# Normally 16MB is enough to run all tests, but it will exceed the stack, if -DSANITIZE=address is used.\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -Wl,-stack_size -Wl,0x2000000\")\n\n\t\t\t# Boost libraries use visibility=hidden to reduce unnecessary DWARF entries.\n\t\t\t# Unless we match visibility, ld will give a warning message like:\n\t\t\t#   ld: warning: direct access in function 'boost::filesystem... from file ...\n\t\t\t#   means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.\n\t\t\tset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fvisibility=hidden\")\n\t\tendif()\n\n\t\t# Some Linux-specific Clang settings.  We don't want these for OS X.\n\t\tif (\"${CMAKE_SYSTEM_NAME}\" MATCHES \"Linux\")\n\t\t\t# Use fancy colors in the compiler diagnostics\n\t\t\tadd_compile_options(-fcolor-diagnostics)\n\n\t\t\t# See \"How to silence unused command line argument error with clang without disabling it?\"\n\t\t\t# When using -Werror with clang, it transforms \"warning: argument unused during compilation\" messages\n\t\t\t# into errors, which makes sense.\n\t\t\t# http://stackoverflow.com/questions/21617158/how-to-silence-unused-command-line-argument-error-with-clang-without-disabling-i\n\t\t\tadd_compile_options(-Qunused-arguments)\n\t\telseif(EMSCRIPTEN)\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} --memory-init-file 0\")\n\t\t\t# Leave only exported symbols as public and aggressively remove others\n\t\t\tset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections -fvisibility=hidden\")\n\t\t\t# Optimisation level\n\t\t\tset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -O3\")\n\t\t\t# Re-enable exception catching (optimisations above -O1 disable it)\n\t\t\tset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0\")\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0\")\n\t\t\t# Remove any code related to exit (such as atexit)\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s EXIT_RUNTIME=0\")\n\t\t\t# Remove any code related to filesystem access\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s FILESYSTEM=0\")\n\t\t\t# Allow memory growth, but disable some optimisations\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1\")\n\t\t\t# Disable eval()\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s DYNAMIC_EXECUTION=0\")\n\t\t\t# Disable greedy exception catcher\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s NODEJS_CATCH_EXIT=0\")\n\t\t\t# Abort if linking results in any undefined symbols\n\t\t\t# Note: this is on by default in the CMake Emscripten module which we aren't using\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1\")\n\t\t\t# Disallow deprecated emscripten build options.\n\t\t\tset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -s STRICT=1\")\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s STRICT=1\")\n\t\t\t# Export the Emscripten-generated auxiliary methods which are needed by solc-js.\n\t\t\t# Which methods of libsolc itself are exported is specified in libsolc/CMakeLists.txt.\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS=['cwrap','addFunction','removeFunction','UTF8ToString','lengthBytesUTF8','stringToUTF8','setValue']\")\n\t\t\t# Build for webassembly target.\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s WASM=1\")\n\t\t\t# Set webassembly build to synchronous loading.\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s WASM_ASYNC_COMPILATION=0\")\n\t\t\t# Allow new functions to be added to the wasm module via addFunction.\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_TABLE_GROWTH=1\")\n\t\t\t# Disable warnings about not being pure asm.js due to memory growth.\n\t\t\tset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wno-almost-asm\")\n\t\t\t# Increase stack size from 5MB to 16MB to prevent stack overflow issues.\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_STACK=16mb\")\n\t\t\t# Increase memory size from 16MB to 32MB since the stack size is now 16MB.\n\t\t\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s INITIAL_MEMORY=32mb\")\n\t\tendif()\n\tendif()\n\n# The major alternative compiler to GCC/Clang is Microsoft's Visual C++ compiler, only available on Windows.\nelseif (DEFINED MSVC)\n\t# Remove NDEBUG from RELWITHDEBINFO (to enable asserts)\n\t# CMAKE_CXX_FLAGS_RELWITHDEBINFO for GCC/Clang does not include NDEBUG\n\tstring(REPLACE \"/DNDEBUG\" \" \" CMAKE_CXX_FLAGS_RELWITHDEBINFO \"${CMAKE_CXX_FLAGS_RELWITHDEBINFO}\")\n\n\tadd_compile_options(/MP)                              # enable parallel compilation\n\tadd_compile_options(/EHsc)                            # specify Exception Handling Model in msvc\n\tif(PEDANTIC)\n\t\tadd_compile_options(/WX)                          # enable warnings-as-errors\n\tendif()\n\tadd_compile_options(/wd4068)                          # disable unknown pragma warning (4068)\n\tadd_compile_options(/wd4996)                          # disable unsafe function warning (4996)\n\tadd_compile_options(/wd4503)                          # disable decorated name length exceeded, name was truncated (4503)\n\tadd_compile_options(/wd4267)                          # disable conversion from 'size_t' to 'type', possible loss of data (4267)\n\tadd_compile_options(/wd4180)                          # disable qualifier applied to function type has no meaning; ignored (4180)\n\tadd_compile_options(/wd4290)                          # disable C++ exception specification ignored except to indicate a function is not __declspec(nothrow) (4290)\n\tadd_compile_options(/wd4244)                          # disable conversion from 'type1' to 'type2', possible loss of data (4244)\n\tadd_compile_options(/wd4800)                          # disable forcing value to bool 'true' or 'false' (performance warning) (4800)\n\tadd_compile_options(-D_WIN32_WINNT=0x0600)            # declare Windows Vista API requirement\n\tadd_compile_options(-DNOMINMAX)                       # undefine windows.h MAX && MIN macros cause it cause conflicts with std::min && std::max functions\n\tadd_compile_options(/utf-8)                           # enable utf-8 encoding (solves warning 4819)\n\tadd_compile_options(-DBOOST_REGEX_NO_LIB)             # disable automatic boost::regex library selection\n\tadd_compile_options(-D_REGEX_MAX_STACK_COUNT=200000L) # increase std::regex recursion depth limit\n\tadd_compile_options(/permissive-)                     # specify standards conformance mode to the compiler\n\n\t# disable empty object file warning\n\tset(CMAKE_STATIC_LINKER_FLAGS \"${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221\")\n\t# warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification\n\t# warning LNK4099: pdb was not found with lib\n\t# stack size 16MB\n\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} /ignore:4099,4075 /STACK:16777216\")\n\n# If you don't have GCC, Clang or VC++ then you are on your own.  Good luck!\nelse ()\n\tmessage(WARNING \"Your compiler is not tested, if you run into any issues, we'd welcome any patches.\")\nendif ()\n\nif (SANITIZE)\n\t# Perform case-insensitive string compare\n\tstring(TOLOWER \"${SANITIZE}\" sanitizer)\n\t# -fno-omit-frame-pointer gives more informative stack trace in case of an error\n\t# -fsanitize-address-use-after-scope throws an error when a variable is used beyond its scope\n\tif (sanitizer STREQUAL \"address\")\n\t\tset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize-address-use-after-scope\")\n\telseif (sanitizer STREQUAL \"undefined\")\n\t\t# The following flags not used by fuzzer but used by us may create problems, so consider\n\t\t# disabling them: alignment, pointer-overflow.\n\t\t# The following flag is not used by us to reduce terminal noise\n\t\t# i.e., warnings printed on stderr: unsigned-integer-overflow\n\t\t# Note: The C++ standard does not officially consider unsigned integer overflows\n\t\t# to be undefined behavior since they are implementation independent.\n\t\t# Flags are alphabetically sorted and are for clang v10.0\n\t\tlist(APPEND undefinedSanitizerChecks\n\t\t\talignment\n\t\t\tarray-bounds\n\t\t\tbool\n\t\t\tbuiltin\n\t\t\tenum\n\t\t\tfloat-divide-by-zero\n\t\t\tfunction\n\t\t\tinteger-divide-by-zero\n\t\t\tnull\n\t\t\tobject-size\n\t\t\tpointer-overflow\n\t\t\treturn\n\t\t\treturns-nonnull-attribute\n\t\t\tshift\n\t\t\tsigned-integer-overflow\n\t\t\tunreachable\n\t\t\tvla-bound\n\t\t\tvptr\n\t\t)\n\t\tlist(JOIN undefinedSanitizerChecks \",\" sanitizerChecks)\n\t\tset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fsanitize=${sanitizerChecks} -fno-sanitize-recover=${sanitizerChecks}\")\n\tendif()\nendif()\n\n# Code coverage support.\n# Copied from Cable:\n# https://github.com/ethereum/cable/blob/v0.2.4/CableCompilerSettings.cmake#L118-L132\noption(COVERAGE \"Build with code coverage support\" OFF)\nif(COVERAGE)\n\t# Set the linker flags first, they are required to properly test the compiler flag.\n\tset(CMAKE_SHARED_LINKER_FLAGS \"--coverage ${CMAKE_SHARED_LINKER_FLAGS}\")\n\tset(CMAKE_EXE_LINKER_FLAGS \"--coverage ${CMAKE_EXE_LINKER_FLAGS}\")\n\n\tset(CMAKE_REQUIRED_LIBRARIES \"--coverage ${CMAKE_REQUIRED_LIBRARIES}\")\n\tcheck_cxx_compiler_flag(--coverage have_coverage)\n\tstring(REPLACE \"--coverage \" \"\" CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})\n\tif(NOT have_coverage)\n\t\tmessage(FATAL_ERROR \"Coverage not supported\")\n\tendif()\n\tadd_compile_options(-g --coverage)\nendif()\n"
  },
  {
    "path": "cmake/EthDependencies.cmake",
    "content": "# all dependencies that are not directly included in the cpp-ethereum distribution are defined here\n# for this to work, download the dependency via the cmake script in extdep or install them manually!\n\nif (DEFINED MSVC)\n\t# by defining CMAKE_PREFIX_PATH variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ...\n\t# this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory\n\n\tif (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.0)\n\t\tset (ETH_DEPENDENCY_INSTALL_DIR \"${CMAKE_CURRENT_LIST_DIR}/../extdep/install/windows/x64\")\n\telse()\n\t\tget_filename_component(DEPS_DIR \"${CMAKE_CURRENT_LIST_DIR}/../deps/install\" ABSOLUTE)\n\t\tset(ETH_DEPENDENCY_INSTALL_DIR\n\t\t\t\"${DEPS_DIR}/x64\"                 # Old location for deps.\n\t\t\t\"${DEPS_DIR}/win64\"               # New location for deps.\n\t\t\t\"${DEPS_DIR}/win64/Release/share\" # LLVM shared cmake files.\n\t\t)\n\tendif()\n\tset (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR} ${CMAKE_PREFIX_PATH})\nendif()\n\n# custom cmake scripts\nset(ETH_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR})\nset(ETH_SCRIPTS_DIR ${ETH_CMAKE_DIR}/scripts)\n\n## use multithreaded boost libraries, with -mt suffix\nset(Boost_USE_MULTITHREADED ON)\noption(Boost_USE_STATIC_LIBS \"Link Boost statically\" ON)\nif (WIN32)\n\toption(Boost_USE_STATIC_RUNTIME \"Link Boost against static C++ runtime libraries\" ON)\nendif()\n\nset(BOOST_COMPONENTS \"filesystem;unit_test_framework;program_options\")\n\n# CMake >= 3.30 should not use the vendored boost\nif(POLICY CMP0167)\n\tcmake_policy(SET CMP0167 NEW)\nendif()\nif (WIN32)\n\t# Boost 1.77 fixes a bug that causes crashes on Windows for some relative paths in --allow-paths.\n\t# See https://github.com/boostorg/filesystem/issues/201\n\tfind_package(Boost 1.77.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS})\nelse()\n\t# Boost 1.65 is the first to also provide boost::get for rvalue-references (#5787).\n\t# Boost 1.67 moved container_hash into is own module.\n\t# Boost 1.69 boost::system is header-only and no longer needs to be fetched as component\n\t# Boost 1.70 comes with its own BoostConfig.cmake and is the new (non-deprecated) behavior\n\t# Boost 1.75 fixes infinite recursion on `boost::rational` comparison with GCC<14.0 under C++20\n\t# Boost 1.83 is the version that comes with Ubuntu 24.04.\n\tfind_package(Boost 1.83.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS})\nendif()\n\n# If cmake is older than boost and boost is older than 1.70,\n# find_package does not define imported targets, so we have to\n# define them manually.\n\nif (NOT TARGET Boost::boost) # header only target\n\tadd_library(Boost::boost INTERFACE IMPORTED)\n\tset_property(TARGET Boost::boost APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIRS})\nendif()\nmessage(STATUS \"Found Boost ${Boost_VERSION} headers in ${Boost_INCLUDE_DIRS}\")\n\nforeach (BOOST_COMPONENT IN LISTS BOOST_COMPONENTS)\n\tif (NOT TARGET Boost::${BOOST_COMPONENT})\n\t\tadd_library(Boost::${BOOST_COMPONENT} UNKNOWN IMPORTED)\n\t\tstring(TOUPPER ${BOOST_COMPONENT} BOOST_COMPONENT_UPPER)\n\t\tset_property(TARGET Boost::${BOOST_COMPONENT} PROPERTY IMPORTED_LOCATION ${Boost_${BOOST_COMPONENT_UPPER}_LIBRARY})\n\t\tset_property(TARGET Boost::${BOOST_COMPONENT} PROPERTY INTERFACE_LINK_LIBRARIES ${Boost_${BOOST_COMPONENT_UPPER}_LIBRARIES})\n\t\tset_property(TARGET Boost::${BOOST_COMPONENT} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIRS})\n\tendif()\n\tget_property(LOCATION TARGET Boost::${BOOST_COMPONENT} PROPERTY IMPORTED_LOCATION)\n\tmessage(STATUS \"Found Boost::${BOOST_COMPONENT} at ${LOCATION}\")\nendforeach()\n"
  },
  {
    "path": "cmake/EthOptions.cmake",
    "content": "# CMAKE macros to set default CMAKE options and to show the\n# resulting configuration.\n\nmacro(configure_project)\n\tset(NAME ${PROJECT_NAME})\n\n\t# features\n\teth_default_option(COVERAGE OFF)\n\teth_default_option(OSSFUZZ OFF)\n\n\t# components\n\teth_default_option(TESTS ON)\n\teth_default_option(TOOLS ON)\n\n\t# Define a matching property name of each of the \"features\".\n\tforeach(FEATURE ${ARGN})\n\t\tset(SUPPORT_${FEATURE} TRUE)\n\tendforeach()\n\n\tinclude(EthBuildInfo)\n\tcreate_build_info(${NAME})\n\tprint_config(${NAME})\nendmacro()\n\nmacro(print_config NAME)\n\tmessage(\"\")\n\tmessage(\"------------------------------------------------------------------------\")\n\tmessage(\"-- Configuring ${NAME} ${PROJECT_VERSION}\")\n\tmessage(\"------------------------------------------------------------------------\")\n\tmessage(\"--                  CMake Version                            ${CMAKE_VERSION}\")\n\tmessage(\"-- CMAKE_BUILD_TYPE Build type                               ${CMAKE_BUILD_TYPE}\")\n\tmessage(\"-- TARGET_PLATFORM  Target platform                          ${CMAKE_SYSTEM_NAME}\")\n\tmessage(\"--------------------------------------------------------------- features\")\n\tmessage(\"-- COVERAGE         Coverage support                         ${COVERAGE}\")\n\tmessage(\"------------------------------------------------------------- components\")\nif (SUPPORT_TESTS)\n\tmessage(\"-- TESTS            Build tests                              ${TESTS}\")\nendif()\nif (SUPPORT_TOOLS)\n\tmessage(\"-- TOOLS            Build tools                              ${TOOLS}\")\nendif()\n\tmessage(\"------------------------------------------------------------------ flags\")\n\tmessage(\"-- OSSFUZZ                                                   ${OSSFUZZ}\")\n\tmessage(\"------------------------------------------------------------------------\")\n\tmessage(\"\")\nendmacro()\n"
  },
  {
    "path": "cmake/EthPolicy.cmake",
    "content": "# it must be a macro cause policies have scopes\n# http://www.cmake.org/cmake/help/v3.0/command/cmake_policy.html\nmacro (eth_policy)\n\t# link_directories() treats paths relative to the source dir.\n\tcmake_policy(SET CMP0015 NEW)\n\n\t# Avoid warnings in CMake 3.0.2:\n\tcmake_policy(SET CMP0042 NEW)\n\tcmake_policy(SET CMP0043 NEW)\n\n\t# allow VERSION argument in project()\n\tcmake_policy(SET CMP0048 NEW)\n\n\tif (POLICY CMP0054)\n\t\t# do not interpret if() arguments as variables!\n\t\tcmake_policy(SET CMP0054 NEW)\n\tendif()\n\n\tif (POLICY CMP0091)\n\t\t# Allow selecting MSVC runtime library using CMAKE_MSVC_RUNTIME_LIBRARY.\n\t\tcmake_policy(SET CMP0091 NEW)\n\tendif()\n\n\t# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24:\n\tif (CMAKE_VERSION VERSION_GREATER_EQUAL \"3.24.0\")\n\t\tcmake_policy(SET CMP0135 NEW)\n\tendif()\n\n\tif(POLICY CMP0115)\n\t\t# Require explicit extensions for source files, do not guess.\n\t\t# The extra calls to GetFileAttributesW significantly slow down cmake on Windows.\n\t\t# https://gitlab.kitware.com/cmake/cmake/-/issues/23154\n\t\tcmake_policy(SET CMP0115 NEW)\n\tendif()\nendmacro()\n"
  },
  {
    "path": "cmake/EthToolchains.cmake",
    "content": "# Require C++20.\nif (NOT DEFINED CMAKE_CXX_STANDARD)\n  set(CMAKE_CXX_STANDARD 20) # This requires at least CMake 3.12 to accept this C++20 flag.\nendif ()\nset(CMAKE_CXX_STANDARD_REQUIRED TRUE)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\nif(NOT CMAKE_TOOLCHAIN_FILE)\n  # Use default toolchain file if none is provided.\n  set(\n      CMAKE_TOOLCHAIN_FILE\n      \"${CMAKE_CURRENT_LIST_DIR}/toolchains/default.cmake\"\n      CACHE FILEPATH \"The CMake toolchain file\"\n  )\nendif()\n"
  },
  {
    "path": "cmake/EthUtils.cmake",
    "content": "#\n# renames the file if it is different from its destination\ninclude(CMakeParseArguments)\n#\nmacro(replace_if_different SOURCE DST)\n\tset(extra_macro_args ${ARGN})\n\tset(options CREATE)\n\tset(one_value_args)\n\tset(multi_value_args)\n\tcmake_parse_arguments(REPLACE_IF_DIFFERENT \"${options}\" \"${one_value_args}\" \"${multi_value_args}\" \"${extra_macro_args}\")\n\n\tif (REPLACE_IF_DIFFERENT_CREATE AND (NOT (EXISTS \"${DST}\")))\n\t\tfile(WRITE \"${DST}\" \"\")\n\tendif()\n\n\texecute_process(COMMAND ${CMAKE_COMMAND} -E compare_files \"${SOURCE}\" \"${DST}\" RESULT_VARIABLE DIFFERENT OUTPUT_QUIET ERROR_QUIET)\n\n\tif (DIFFERENT)\n\t\texecute_process(COMMAND ${CMAKE_COMMAND} -E rename \"${SOURCE}\" \"${DST}\")\n\telse()\n\t\texecute_process(COMMAND ${CMAKE_COMMAND} -E remove \"${SOURCE}\")\n\tendif()\nendmacro()\n\nmacro(eth_default_option O DEF)\n\tif (DEFINED ${O})\n\t\tif (${${O}})\n\t\t\tset(${O} ON)\n\t\telse ()\n\t\t\tset(${O} OFF)\n\t\tendif()\n\telse ()\n\t\tset(${O} ${DEF})\n\tendif()\nendmacro()\n\nfunction(detect_stray_source_files FILELIST DIRECTORY)\n\tif(CMAKE_VERSION VERSION_LESS 3.12)\n\t\tfile(GLOB sources RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\" \"${DIRECTORY}/*.cpp\" \"${DIRECTORY}/*.h\")\n\telse()\n\t\tfile(GLOB sources RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\" CONFIGURE_DEPENDS \"${DIRECTORY}/*.cpp\" \"${DIRECTORY}/*.h\")\n\tendif()\n\tforeach(path IN LISTS FILELIST)\n\t\tlist(REMOVE_ITEM sources ${path})\n\tendforeach()\n\tlist(LENGTH sources leftover_sources)\n\tif (leftover_sources)\n\t\tmessage(SEND_ERROR \"The following source files are present but are not compiled: ${sources}\")\n\tendif()\nendfunction(detect_stray_source_files)\n\n# CreateExportedFunctionsForEMSDK(OUTPUT_VARIABLE Symbol1 Symbol2 ... SymbolN)\nfunction(CreateExportedFunctionsForEMSDK OUTPUT_VARIABLE)\n\tlist(TRANSFORM ARGN PREPEND \"\\\"_\")\n\tlist(TRANSFORM ARGN APPEND \"\\\"\")\n\tlist(JOIN ARGN \",\" ARGN)\n\tset(${OUTPUT_VARIABLE} \"[${ARGN}]\" PARENT_SCOPE)\nendfunction()\n"
  },
  {
    "path": "cmake/FindCLN.cmake",
    "content": "find_library(CLN_LIBRARY NAMES cln)\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(CLN DEFAULT_MSG CLN_LIBRARY)\n\nif(CLN_FOUND AND NOT TARGET CLN::CLN)\n    add_library(CLN::CLN UNKNOWN IMPORTED)\n    set_property(TARGET CLN::CLN PROPERTY IMPORTED_LOCATION ${CLN_LIBRARY})\nendif()\n"
  },
  {
    "path": "cmake/FindGMP.cmake",
    "content": "find_library(GMP_LIBRARY NAMES gmp)\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(GMP DEFAULT_MSG GMP_LIBRARY)\n\nif(GMP_FOUND AND NOT TARGET GMP::GMP)\n    add_library(GMP::GMP UNKNOWN IMPORTED)\n    set_property(TARGET GMP::GMP PROPERTY IMPORTED_LOCATION ${GMP_LIBRARY})\nendif()\n"
  },
  {
    "path": "cmake/FindZ3.cmake",
    "content": "# Save and clear Z3_FIND_VERSION, since the\n# Z3 config module cannot handle version requirements.\nset(Z3_FIND_VERSION_ORIG ${Z3_FIND_VERSION})\nset(Z3_FIND_VERSION)\n# Try to find Z3 using its stock cmake files.\nfind_package(Z3 QUIET CONFIG)\n# Restore Z3_FIND_VERSION for find_package_handle_standard_args.\nset(Z3_FIND_VERSION ${Z3_FIND_VERSION_ORIG})\nset(Z3_FIND_VERSION_ORIG)\n\ninclude(FindPackageHandleStandardArgs)\n\nif (Z3_FOUND)\n    set(Z3_VERSION ${Z3_VERSION_STRING})\n    find_package_handle_standard_args(Z3 CONFIG_MODE)\nelse()\n    find_path(Z3_INCLUDE_DIR NAMES z3++.h PATH_SUFFIXES z3)\n    find_library(Z3_LIBRARY NAMES z3)\n    find_program(Z3_EXECUTABLE z3 PATH_SUFFIXES bin)\n\n    if(Z3_INCLUDE_DIR AND Z3_LIBRARY)\n        if(Z3_EXECUTABLE)\n            execute_process (COMMAND ${Z3_EXECUTABLE} -version\n                OUTPUT_VARIABLE libz3_version_str\n                ERROR_QUIET\n                OUTPUT_STRIP_TRAILING_WHITESPACE)\n\n            string(REGEX REPLACE \"^Z3 version ([0-9.]+).*\" \"\\\\1\"\n                   Z3_VERSION_STRING \"${libz3_version_str}\")\n            unset(libz3_version_str)\n        else()\n            message(WARNING \"Could not determine the version of z3, since the z3 executable was not found.\")\n            set(Z3_VERSION_STRING \"0.0.0\")\n        endif()\n    endif()\n    mark_as_advanced(Z3_VERSION_STRING z3_DIR)\n\n    find_package_handle_standard_args(Z3\n        REQUIRED_VARS Z3_LIBRARY Z3_INCLUDE_DIR\n        VERSION_VAR Z3_VERSION_STRING)\n\n    if (NOT TARGET z3::libz3)\n        add_library(z3::libz3 UNKNOWN IMPORTED)\n        set_property(TARGET z3::libz3 PROPERTY IMPORTED_LOCATION ${Z3_LIBRARY})\n        set_property(TARGET z3::libz3 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Z3_INCLUDE_DIR})\n    endif()\nendif()\n"
  },
  {
    "path": "cmake/fmtlib.cmake",
    "content": "include(${CMAKE_SOURCE_DIR}/cmake/submodules.cmake)\ninitialize_submodule(fmtlib)\n\nset(FMT_SYSTEM_HEADERS ON)\nadd_subdirectory(\n\t${CMAKE_SOURCE_DIR}/deps/fmtlib\n\tEXCLUDE_FROM_ALL\n)\n\n"
  },
  {
    "path": "cmake/nlohmann-json.cmake",
    "content": "include(${CMAKE_SOURCE_DIR}/cmake/submodules.cmake)\ninitialize_submodule(nlohmann-json)\n\nset(JSON_Install OFF CACHE INTERNAL \"\")\nadd_subdirectory(\n\t${CMAKE_SOURCE_DIR}/deps/nlohmann-json\n\tEXCLUDE_FROM_ALL\n)\n\n"
  },
  {
    "path": "cmake/range-v3.cmake",
    "content": "include(${CMAKE_SOURCE_DIR}/cmake/submodules.cmake)\ninitialize_submodule(range-v3)\n\nadd_library(range-v3 INTERFACE IMPORTED)\nset_target_properties(range-v3 PROPERTIES\n\tINTERFACE_COMPILE_OPTIONS \"\\$<\\$<CXX_COMPILER_ID:MSVC>:/permissive->\"\n\tINTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/deps/range-v3/include\n\tINTERFACE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/deps/range-v3/include\n)\nadd_dependencies(range-v3 range-v3-project)\n\n"
  },
  {
    "path": "cmake/scripts/buildinfo.cmake",
    "content": "# generates BuildInfo.h\n#\n# this module expects\n# ETH_SOURCE_DIR - main CMAKE_SOURCE_DIR\n# ETH_DST_DIR - main CMAKE_BINARY_DIR\n# ETH_BUILD_TYPE\n# ETH_BUILD_PLATFORM\n#\n# example usage:\n# cmake -DETH_SOURCE_DIR=. -DETH_DST_DIR=build -DETH_BUILD_TYPE=Debug -DETH_BUILD_PLATFORM=Darwin.appleclang -P scripts/buildinfo.cmake\n#\n# Its main output variables are SOL_VERSION_BUILDINFO and SOL_VERSION_PRERELEASE\n\nif (NOT ETH_BUILD_TYPE)\n\tset(ETH_BUILD_TYPE \"unknown\")\nendif()\n\nif (NOT ETH_BUILD_PLATFORM)\n\tset(ETH_BUILD_PLATFORM \"unknown\")\nendif()\n\n# Logic here: If prerelease.txt exists but is empty, it is a non-pre release.\n# If it does not exist, create our own prerelease string\nif (EXISTS ${ETH_SOURCE_DIR}/prerelease.txt)\n\tfile(READ ${ETH_SOURCE_DIR}/prerelease.txt SOL_VERSION_PRERELEASE)\n\tstring(STRIP \"${SOL_VERSION_PRERELEASE}\" SOL_VERSION_PRERELEASE)\nelse()\n\tstring(TIMESTAMP SOL_VERSION_PRERELEASE \"develop.%Y.%m.%d\" UTC)\n\tstring(REPLACE .0 . SOL_VERSION_PRERELEASE \"${SOL_VERSION_PRERELEASE}\")\nendif()\n\nif (EXISTS ${ETH_SOURCE_DIR}/commit_hash.txt)\n\tfile(READ ${ETH_SOURCE_DIR}/commit_hash.txt SOL_COMMIT_HASH)\n\tstring(STRIP ${SOL_COMMIT_HASH} SOL_COMMIT_HASH)\nelse()\n\texecute_process(\n\t\tCOMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} rev-parse --short=8 HEAD\n\t\tOUTPUT_VARIABLE SOL_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET\n\t)\n\texecute_process(\n\t\tCOMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} diff HEAD --shortstat\n\t\tOUTPUT_VARIABLE SOL_LOCAL_CHANGES OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET\n\t)\nendif()\n\nif (SOL_COMMIT_HASH)\n\tstring(STRIP ${SOL_COMMIT_HASH} SOL_COMMIT_HASH)\n\tstring(SUBSTRING ${SOL_COMMIT_HASH} 0 8 SOL_COMMIT_HASH)\nendif()\n\nif (NOT SOL_COMMIT_HASH)\n\tmessage(FATAL_ERROR \"Unable to determine commit hash. Either compile from within git repository or \"\n\t\t\"supply a file called commit_hash.txt\")\nendif()\nif (NOT SOL_COMMIT_HASH MATCHES [a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9])\n    message(FATAL_ERROR \"Malformed commit hash \\\"${SOL_COMMIT_HASH}\\\". It has to consist of exactly 8 hex digits.\")\nendif()\n\nif (SOL_COMMIT_HASH AND SOL_LOCAL_CHANGES)\n\tset(SOL_COMMIT_HASH \"${SOL_COMMIT_HASH}.mod\")\nendif()\n\nset(SOL_VERSION_COMMIT \"commit.${SOL_COMMIT_HASH}\")\nset(SOL_VERSION_PLATFORM ETH_BUILD_PLATFORM)\nset(SOL_VERSION_BUILDINFO \"commit.${SOL_COMMIT_HASH}.${ETH_BUILD_PLATFORM}\")\n\nset(TMPFILE \"${ETH_DST_DIR}/BuildInfo.h.tmp\")\nset(OUTFILE \"${ETH_DST_DIR}/BuildInfo.h\")\n\nconfigure_file(\"${ETH_BUILDINFO_IN}\" \"${TMPFILE}\")\n\ninclude(\"${ETH_CMAKE_DIR}/EthUtils.cmake\")\nreplace_if_different(\"${TMPFILE}\" \"${OUTFILE}\" CREATE)\n\n"
  },
  {
    "path": "cmake/submodules.cmake",
    "content": "macro(initialize_submodule SUBMODULE_PATH)\n\tif(NOT IGNORE_VENDORED_DEPENDENCIES)\n\t\tfile(GLOB submodule_contents \"${CMAKE_SOURCE_DIR}/deps/${SUBMODULE_PATH}/*\")\n\n\t\tif(submodule_contents)\n\t\t\tmessage(STATUS \"git submodule '${SUBMODULE_PATH}' seem to be already initialized: nothing to do.\")\n\t\telse()\n\t\t\tmessage(STATUS \"git submodule '${SUBMODULE_PATH}' seem not to be initialized: implicitly executing 'git submodule update --init '${CMAKE_SOURCE_DIR}/deps/${SUBMODULE_PATH}'.\")\n\t\t\tfind_package(Git)\n\t\t\tif(NOT Git_FOUND)\n\t\t\t\tmessage(FATAL_ERROR \"Failed to initialize submodules: 'git' command not found.\")\n\t\t\tendif()\n\t\t\texecute_process(\n\t\t\t\t\tCOMMAND git submodule update --init ${CMAKE_SOURCE_DIR}/deps/${SUBMODULE_PATH}\n\t\t\t\t\tWORKING_DIRECTORY ${CMAKE_SOURCE_DIR}\n\t\t\t\t\tRESULT_VARIABLE result\n\t\t\t)\n\t\t\tif(NOT result EQUAL 0)\n\t\t\t\tmessage(FATAL_ERROR \"Failed to initialize submodules: 'git submodule update --init' failed.\")\n\t\t\tendif()\n\t\tendif()\n\tendif()\nendmacro()\n"
  },
  {
    "path": "cmake/templates/BuildInfo.h.in",
    "content": "#pragma once\n\n#define ETH_PROJECT_VERSION \"@PROJECT_VERSION@\"\n#define ETH_PROJECT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@\n#define ETH_PROJECT_VERSION_MINOR @PROJECT_VERSION_MINOR@\n#define ETH_PROJECT_VERSION_PATCH @PROJECT_VERSION_PATCH@\n#define SOL_COMMIT_HASH \"@SOL_COMMIT_HASH@\"\n#define ETH_BUILD_TYPE \"@ETH_BUILD_TYPE@\"\n#define ETH_BUILD_OS \"@ETH_BUILD_OS@\"\n#define ETH_BUILD_COMPILER \"@ETH_BUILD_COMPILER@\"\n#define ETH_BUILD_PLATFORM \"@ETH_BUILD_PLATFORM@\"\n#define SOL_VERSION_PRERELEASE \"@SOL_VERSION_PRERELEASE@\"\n#define SOL_VERSION_BUILDINFO \"@SOL_VERSION_BUILDINFO@\"\n#define SOL_VERSION_COMMIT \"@SOL_VERSION_COMMIT@\"\n#define SOL_VERSION_PLATFORM \"@SOL_VERSION_PLATFORM@\"\n"
  },
  {
    "path": "cmake/templates/license.h.in",
    "content": "#pragma once\n\n#include <string>\n\nstatic std::string const otherLicenses{R\"(Most of the code is licensed under GPLv3 (see below), the license for individual\nparts and dependencies are as follows:\n\nlibkeccak-tiny:\n  The file libsolutil/Keccak256.cpp incorporates libkeccak-tiny.\n\n  A single-file implementation of SHA-3 and SHAKE implemented by David Leon Gil\n  License: CC0, attribution kindly requested. Blame taken too, but not liability.\n\nnlohmann-json:\n  The source code of nlohmann-json is licensed under the following\n  conditions:\n\n  The class is licensed under the MIT License:\n\n  Copyright © 2013-2022 Niels Lohmann\n\n  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:\n\n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n  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.\n\n  The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the MIT License (see above). Copyright © 2008-2009 Björn Hoehrmann bjoern@hoehrmann.de\n\n  The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the MIT License (see above). Copyright © 2009 Florian Loitsch\n\n  The class contains a copy of Hedley from Evan Nemerson which is licensed as CC0-1.0.\n\npicosha2:\n  The file libsolutil/picosha2.h is imported.\n\n  Copyright (C) 2017 okdshin\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE.\n\nrange-v3:\n  The range-v3 library is licensed under the following conditions:\n\n  ========================================================\n  Boost Software License - Version 1.0 - August 17th, 2003\n  ========================================================\n\n  Permission is hereby granted, free of charge, to any person or organization\n  obtaining a copy of the software and accompanying documentation covered by\n  this license (the \"Software\") to use, reproduce, display, distribute,\n  execute, and transmit the Software, and to prepare derivative works of the\n  Software, and to permit third-parties to whom the Software is furnished to\n  do so, all subject to the following:\n\n  The copyright notices in the Software and this entire statement, including\n  the above license grant, this restriction and the following disclaimer,\n  must be included in all copies of the Software, in whole or in part, and\n  all derivative works of the Software, unless such copies or derivative\n  works are solely in the form of machine-executable object code generated by\n  a source language processor.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\n  SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\n  FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\n  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n  DEALINGS IN THE SOFTWARE.\n\n  ==============================================================================\n  libc++ License\n  ==============================================================================\n\n  The libc++ library is dual licensed under both the University of Illinois\n  \"BSD-Like\" license and the MIT license.  As a user of this code you may choose\n  to use it under either license.  As a contributor, you agree to allow your code\n  to be used under both.\n\n  Full text of the relevant licenses is included below.\n\n  ==============================================================================\n\n  University of Illinois/NCSA\n  Open Source License\n\n  Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\n  http://llvm.org/svn/llvm-project/libcxx/trunk/CREDITS.TXT\n\n  All rights reserved.\n\n  Developed by:\n\n      LLVM Team\n\n      University of Illinois at Urbana-Champaign\n\n      http://llvm.org\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy of\n  this software and associated documentation files (the \"Software\"), to deal with\n  the Software without restriction, including without limitation the rights to\n  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n  of the Software, and to permit persons to whom the Software is furnished to do\n  so, subject to the following conditions:\n\n      * Redistributions of source code must retain the above copyright notice,\n        this list of conditions and the following disclaimers.\n\n      * Redistributions in binary form must reproduce the above copyright notice,\n        this list of conditions and the following disclaimers in the\n        documentation and/or other materials provided with the distribution.\n\n      * Neither the names of the LLVM Team, University of Illinois at\n        Urbana-Champaign, nor the names of its contributors may be used to\n        endorse or promote products derived from this Software without specific\n        prior written permission.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\n  CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE\n  SOFTWARE.\n\n  ==============================================================================\n\n  Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\n    http://llvm.org/svn/llvm-project/libcxx/trunk/CREDITS.TXT\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE.\n\n  ==============================================================================\n  Stepanov and McJones, \"Elements of Programming\" license\n  ==============================================================================\n\n  // Copyright (c) 2009 Alexander Stepanov and Paul McJones\n  //\n  // Permission to use, copy, modify, distribute and sell this software\n  // and its documentation for any purpose is hereby granted without\n  // fee, provided that the above copyright notice appear in all copies\n  // and that both that copyright notice and this permission notice\n  // appear in supporting documentation. The authors make no\n  // representations about the suitability of this software for any\n  // purpose. It is provided \"as is\" without express or implied\n  // warranty.\n  //\n  // Algorithms from\n  // Elements of Programming\n  // by Alexander Stepanov and Paul McJones\n  // Addison-Wesley Professional, 2009\n\n  ==============================================================================\n  SGI C++ Standard Template Library license\n  ==============================================================================\n\n  // Copyright (c) 1994\n  // Hewlett-Packard Company\n  //\n  // Permission to use, copy, modify, distribute and sell this software\n  // and its documentation for any purpose is hereby granted without fee,\n  // provided that the above copyright notice appear in all copies and\n  // that both that copyright notice and this permission notice appear\n  // in supporting documentation.  Hewlett-Packard Company makes no\n  // representations about the suitability of this software for any\n  // purpose.  It is provided \"as is\" without express or implied warranty.\n  //\n  // Copyright (c) 1996\n  // Silicon Graphics Computer Systems, Inc.\n  //\n  // Permission to use, copy, modify, distribute and sell this software\n  // and its documentation for any purpose is hereby granted without fee,\n  // provided that the above copyright notice appear in all copies and\n  // that both that copyright notice and this permission notice appear\n  // in supporting documentation.  Silicon Graphics makes no\n  // representations about the suitability of this software for any\n  // purpose.  It is provided \"as is\" without express or implied warranty.\n  //\n\nscanner/token:\n  The liblangutil/{CharStream,Scanner,Token}.{h,cpp} files are derived from\n  code originating from the V8 project licensed under the following terms:\n\n  Copyright 2006-2012, the V8 project authors. All rights reserved.\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are\n  met:\n\n      * Redistributions of source code must retain the above copyright\n        notice, this list of conditions and the following disclaimer.\n      * Redistributions in binary form must reproduce the above\n        copyright notice, this list of conditions and the following\n        disclaimer in the documentation and/or other materials provided\n        with the distribution.\n      * Neither the name of Google Inc. nor the names of its\n        contributors may be used to endorse or promote products derived\n        from this software without specific prior written permission.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nevmc:\n  The code in test/evmc is licensed under the Apache License version 2:\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\nmini-lz4:\n  The file scripts/ci/mini-lz4.js is derived from the emscripten adaptation of\n  node-lz4 and licensed under the following terms:\n\n  Copyright (c) 2012 Pierre Curto\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE.\n\nbase64:\n  The file scripts/ci/base64DecToArr.js is derived from a code example\n  in the MDN Web Docs, which permits use under CC0 terms:\n\n  Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/\n\nZ3:\n  The Z3 library is licensed under the following terms:\n\n  Copyright (c) Microsoft Corporation\n  All rights reserved.\n  MIT License\n\n  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:\n\n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n  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.\n\n\nAll other code is licensed under GPL version 3:\n\n)\"};\n\nstatic char const licenseText[] = {\n\t@LICENSE_TEXT@, 0\n};\n"
  },
  {
    "path": "cmake/toolchains/default.cmake",
    "content": ""
  },
  {
    "path": "cmake/toolchains/libfuzzer.cmake",
    "content": "# Inherit default options\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/default.cmake\")\n# Build fuzzing binaries\nset(OSSFUZZ ON CACHE BOOL \"Enable fuzzer build\" FORCE)\n# Use libfuzzer as the fuzzing back-end\nset(LIB_FUZZING_ENGINE \"-fsanitize=fuzzer\" CACHE STRING \"Use libfuzzer back-end\" FORCE)\n# clang/libfuzzer specific flags for UBSan instrumentation\n# uses the more memory-efficient gold, which allows us to stay with the \"large\" resource class without OOM errors\nset(CMAKE_CXX_FLAGS \"-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -I /usr/local/include/c++/v1 -fsanitize=undefined -fsanitize=fuzzer-no-link -fuse-ld=gold -stdlib=libc++\" CACHE STRING \"Custom compilation flags\" FORCE)\n# Link statically against boost libraries\nset(BOOST_FOUND ON CACHE BOOL \"\" FORCE)\nset(Boost_USE_STATIC_LIBS ON CACHE BOOL \"Link against static Boost libraries\" FORCE)\nset(Boost_USE_STATIC_RUNTIME ON CACHE BOOL \"Link against static Boost runtime library\" FORCE)\n"
  },
  {
    "path": "cmake/toolchains/ossfuzz.cmake",
    "content": "# Inherit default options\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/default.cmake\")\n# Disable Z3.\nset(USE_Z3 OFF CACHE BOOL \"Disable Z3\" FORCE)\n# Enable fuzzers\nset(OSSFUZZ ON CACHE BOOL \"Enable fuzzer build\" FORCE)\nset(LIB_FUZZING_ENGINE $ENV{LIB_FUZZING_ENGINE} CACHE STRING \"Use fuzzer back-end defined by environment variable\" FORCE)\n# Link statically against boost libraries\nset(BOOST_FOUND ON CACHE BOOL \"\" FORCE)\nset(Boost_USE_STATIC_LIBS ON CACHE BOOL \"Link against static Boost libraries\" FORCE)\nset(Boost_USE_STATIC_RUNTIME ON CACHE BOOL \"Link against static Boost runtime library\" FORCE)\n"
  },
  {
    "path": "docs/050-breaking-changes.rst",
    "content": "********************************\nSolidity v0.5.0 Breaking Changes\n********************************\n\nThis section highlights the main breaking changes introduced in Solidity\nversion 0.5.0, along with the reasoning behind the changes and how to update\naffected code.\nFor the full list check\n`the release changelog <https://github.com/argotorg/solidity/releases/tag/v0.5.0>`_.\n\n.. note::\n   Contracts compiled with Solidity v0.5.0 can still interface with contracts\n   and even libraries compiled with older versions without recompiling or\n   redeploying them.  Changing the interfaces to include data locations and\n   visibility and mutability specifiers suffices. See the\n   :ref:`Interoperability With Older Contracts <interoperability>` section below.\n\nSemantic Only Changes\n=====================\n\nThis section lists the changes that are semantic-only, thus potentially\nhiding new and different behavior in existing code.\n\n* Signed right shift now uses proper arithmetic shift, i.e. rounding towards\n  negative infinity, instead of rounding towards zero.  Signed and unsigned\n  shift will have dedicated opcodes in Constantinople, and are emulated by\n  Solidity for the moment.\n\n* The ``continue`` statement in a ``do...while`` loop now jumps to the\n  condition, which is the common behavior in such cases. It used to jump to the\n  loop body. Thus, if the condition is false, the loop terminates.\n\n* The functions ``.call()``, ``.delegatecall()`` and ``.staticcall()`` do not\n  pad anymore when given a single ``bytes`` parameter.\n\n* Pure and view functions are now called using the opcode ``STATICCALL``\n  instead of ``CALL`` if the EVM version is Byzantium or later. This\n  disallows state changes on the EVM level.\n\n* The ABI encoder now properly pads byte arrays and strings from calldata\n  (``msg.data`` and external function parameters) when used in external\n  function calls and in ``abi.encode``. For unpadded encoding, use\n  ``abi.encodePacked``.\n\n* The ABI decoder reverts in the beginning of functions and in\n  ``abi.decode()`` if passed calldata is too short or points out of bounds.\n  Note that dirty higher order bits are still simply ignored.\n\n* Forward all available gas with external function calls starting from\n  Tangerine Whistle.\n\nSemantic and Syntactic Changes\n==============================\n\nThis section highlights changes that affect syntax and semantics.\n\n* The functions ``.call()``, ``.delegatecall()``, ``staticcall()``,\n  ``keccak256()``, ``sha256()`` and ``ripemd160()`` now accept only a single\n  ``bytes`` argument. Moreover, the argument is not padded. This was changed to\n  make more explicit and clear how the arguments are concatenated. Change every\n  ``.call()`` (and family) to a ``.call(\"\")`` and every ``.call(signature, a,\n  b, c)`` to use ``.call(abi.encodeWithSignature(signature, a, b, c))`` (the\n  last one only works for value types).  Change every ``keccak256(a, b, c)`` to\n  ``keccak256(abi.encodePacked(a, b, c))``. Even though it is not a breaking\n  change, it is suggested that developers change\n  ``x.call(bytes4(keccak256(\"f(uint256)\")), a, b)`` to\n  ``x.call(abi.encodeWithSignature(\"f(uint256)\", a, b))``.\n\n* Functions ``.call()``, ``.delegatecall()`` and ``.staticcall()`` now return\n  ``(bool, bytes memory)`` to provide access to the return data.  Change\n  ``bool success = otherContract.call(\"f\")`` to ``(bool success, bytes memory\n  data) = otherContract.call(\"f\")``.\n\n* Solidity now implements C99-style scoping rules for function local\n  variables, that is, variables can only be used after they have been\n  declared and only in the same or nested scopes. Variables declared in the\n  initialization block of a ``for`` loop are valid at any point inside the\n  loop.\n\nExplicitness Requirements\n=========================\n\nThis section lists changes where the code now needs to be more explicit.\nFor most of the topics the compiler will provide suggestions.\n\n* Explicit function visibility is now mandatory.  Add ``public`` to every\n  function and constructor, and ``external`` to every fallback or interface\n  function that does not specify its visibility already.\n\n* Explicit data location for all variables of struct, array or mapping types is\n  now mandatory. This is also applied to function parameters and return\n  variables.  For example, change ``uint[] x = z`` to ``uint[] storage x =\n  z``, and ``function f(uint[][] x)`` to ``function f(uint[][] memory x)``\n  where ``memory`` is the data location and might be replaced by ``storage`` or\n  ``calldata`` accordingly.  Note that ``external`` functions require\n  parameters with a data location of ``calldata``.\n\n* Contract types do not include ``address`` members anymore in\n  order to separate the namespaces.  Therefore, it is now necessary to\n  explicitly convert values of contract type to addresses before using an\n  ``address`` member.  Example: if ``c`` is a contract, change\n  ``c.transfer(...)`` to ``address(c).transfer(...)``,\n  and ``c.balance`` to ``address(c).balance``.\n\n* Explicit conversions between unrelated contract types are now disallowed. You can only\n  convert from a contract type to one of its base or ancestor types. If you are sure that\n  a contract is compatible with the contract type you want to convert to, although it does not\n  inherit from it, you can work around this by converting to ``address`` first.\n  Example: if ``A`` and ``B`` are contract types, ``B`` does not inherit from ``A`` and\n  ``b`` is a contract of type ``B``, you can still convert ``b`` to type ``A`` using ``A(address(b))``.\n  Note that you still need to watch out for matching payable fallback functions, as explained below.\n\n* The ``address`` type  was split into ``address`` and ``address payable``,\n  where only ``address payable`` provides the ``transfer`` function.  An\n  ``address payable`` can be directly converted to an ``address``, but the\n  other way around is not allowed. Converting ``address`` to ``address\n  payable`` is possible via conversion through ``uint160``. If ``c`` is a\n  contract, ``address(c)`` results in ``address payable`` only if ``c`` has a\n  payable fallback function. If you use the :ref:`withdraw pattern<withdrawal_pattern>`,\n  you most likely do not have to change your code because ``transfer``\n  is only used on ``msg.sender`` instead of stored addresses and ``msg.sender``\n  is an ``address payable``.\n\n* Conversions between ``bytesX`` and ``uintY`` of different size are now\n  disallowed due to ``bytesX`` padding on the right and ``uintY`` padding on\n  the left which may cause unexpected conversion results.  The size must now be\n  adjusted within the type before the conversion.  For example, you can convert\n  a ``bytes4`` (4 bytes) to a ``uint64`` (8 bytes) by first converting the\n  ``bytes4`` variable to ``bytes8`` and then to ``uint64``. You get the\n  opposite padding when converting through ``uint32``. Before v0.5.0 any\n  conversion between ``bytesX`` and ``uintY`` would go through ``uint8X``. For\n  example ``uint8(bytes3(0x291807))`` would be converted to ``uint8(uint24(bytes3(0x291807)))``\n  (the result is ``0x07``).\n\n* Using ``msg.value`` in non-payable functions (or introducing it via a\n  modifier) is disallowed as a security feature. Turn the function into\n  ``payable`` or create a new internal function for the program logic that\n  uses ``msg.value``.\n\n* For clarity reasons, the command-line interface now requires ``-`` if the\n  standard input is used as source.\n\nDeprecated Elements\n===================\n\nThis section lists changes that deprecate prior features or syntax.  Note that\nmany of these changes were already enabled in the experimental mode\n``v0.5.0``.\n\nCommand-line and JSON Interfaces\n--------------------------------\n\n* The command-line option ``--formal`` (used to generate Why3 output for\n  further formal verification) was deprecated and is now removed.  A new\n  formal verification module, the SMTChecker, is enabled via ``pragma\n  experimental SMTChecker;``.\n\n* The command-line option ``--julia`` was renamed to ``--yul`` due to the\n  renaming of the intermediate language ``Julia`` to ``Yul``.\n\n* The ``--clone-bin`` and ``--combined-json clone-bin`` command-line options\n  were removed.\n\n* Remappings with empty prefix are disallowed.\n\n* The JSON AST fields ``constant`` and ``payable`` were removed. The\n  information is now present in the ``stateMutability`` field.\n\n* The JSON AST field ``isConstructor`` of the ``FunctionDefinition``\n  node was replaced by a field called ``kind`` which can have the\n  value ``\"constructor\"``, ``\"fallback\"`` or ``\"function\"``.\n\n* In unlinked binary hex files, library address placeholders are now\n  the first 36 hex characters of the keccak256 hash of the fully qualified\n  library name, surrounded by ``$...$``. Previously,\n  just the fully qualified library name was used.\n  This reduces the chances of collisions, especially when long paths are used.\n  Binary files now also contain a list of mappings from these placeholders\n  to the fully qualified names.\n\nConstructors\n------------\n\n* Constructors must now be defined using the ``constructor`` keyword.\n\n* Calling base constructors without parentheses is now disallowed.\n\n* Specifying base constructor arguments multiple times in the same inheritance\n  hierarchy is now disallowed.\n\n* Calling a constructor with arguments but with wrong argument count is now\n  disallowed.  If you only want to specify an inheritance relation without\n  giving arguments, do not provide parentheses at all.\n\nFunctions\n---------\n\n* Function ``callcode`` is now disallowed (in favor of ``delegatecall``). It\n  is still possible to use it via inline assembly.\n\n* ``suicide`` is now disallowed (in favor of ``selfdestruct``).\n\n* ``sha3`` is now disallowed (in favor of ``keccak256``).\n\n* ``throw`` is now disallowed (in favor of ``revert``, ``require`` and\n  ``assert``).\n\nConversions\n-----------\n\n* Explicit and implicit conversions from decimal literals to ``bytesXX`` types\n  is now disallowed.\n\n* Explicit and implicit conversions from hex literals to ``bytesXX`` types\n  of different size is now disallowed.\n\nLiterals and Suffixes\n---------------------\n\n* The unit denomination ``years`` is now disallowed due to complications and\n  confusions about leap years.\n\n* Trailing dots that are not followed by a number are now disallowed.\n\n* Combining hex numbers with unit denominations (e.g. ``0x1e wei``) is now\n  disallowed.\n\n* The prefix ``0X`` for hex numbers is disallowed, only ``0x`` is possible.\n\nVariables\n---------\n\n* Declaring empty structs is now disallowed for clarity.\n\n* The ``var`` keyword is now disallowed to favor explicitness.\n\n* Assignments between tuples with different number of components is now\n  disallowed.\n\n* Values for constants that are not compile-time constants are disallowed.\n\n* Multi-variable declarations with mismatching number of values are now\n  disallowed.\n\n* Uninitialized storage variables are now disallowed.\n\n* Empty tuple components are now disallowed.\n\n* Detecting cyclic dependencies in variables and structs is limited in\n  recursion to 256.\n\n* Fixed-size arrays with a length of zero are now disallowed.\n\nSyntax\n------\n\n* Using ``constant`` as function state mutability modifier is now disallowed.\n\n* Boolean expressions cannot use arithmetic operations.\n\n* The unary ``+`` operator is now disallowed.\n\n* Literals cannot anymore be used with ``abi.encodePacked`` without prior\n  conversion to an explicit type.\n\n* Empty return statements for functions with one or more return values are now\n  disallowed.\n\n* The \"loose assembly\" syntax is now disallowed entirely, that is, jump labels,\n  jumps and non-functional instructions cannot be used anymore. Use the new\n  ``while``, ``switch`` and ``if`` constructs instead.\n\n* Functions without implementation cannot use modifiers anymore.\n\n* Function types with named return values are now disallowed.\n\n* Single statement variable declarations inside if/while/for bodies that are\n  not blocks are now disallowed.\n\n* New keywords: ``calldata`` and ``constructor``.\n\n* New reserved keywords: ``alias``, ``apply``, ``auto``, ``copyof``,\n  ``define``, ``immutable``, ``implements``, ``macro``, ``mutable``,\n  ``override``, ``partial``, ``promise``, ``reference``, ``sealed``,\n  ``sizeof``, ``supports``, ``typedef`` and ``unchecked``.\n\n.. _interoperability:\n\nInteroperability With Older Contracts\n=====================================\n\nIt is still possible to interface with contracts written for Solidity versions prior to\nv0.5.0 (or the other way around) by defining interfaces for them.\nConsider you have the following pre-0.5.0 contract already deployed:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.4.25;\n    // This will report a warning until version 0.4.25 of the compiler\n    // This will not compile after 0.5.0\n    contract OldContract {\n        function someOldFunction(uint8 a) {\n            //...\n        }\n        function anotherOldFunction() constant returns (bool) {\n            //...\n        }\n        // ...\n    }\n\nThis will no longer compile with Solidity v0.5.0. However, you can define a compatible interface for it:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.0 <0.9.0;\n    interface OldContract {\n        function someOldFunction(uint8 a) external;\n        function anotherOldFunction() external returns (bool);\n    }\n\nNote that we did not declare ``anotherOldFunction`` to be ``view``, despite it being declared ``constant`` in the original\ncontract. This is due to the fact that starting with Solidity v0.5.0 ``staticcall`` is used to call ``view`` functions.\nPrior to v0.5.0 the ``constant`` keyword was not enforced, so calling a function declared ``constant`` with ``staticcall``\nmay still revert, since the ``constant`` function may still attempt to modify storage. Consequently, when defining an\ninterface for older contracts, you should only use ``view`` in place of ``constant`` in case you are absolutely sure that\nthe function will work with ``staticcall``.\n\nGiven the interface defined above, you can now easily use the already deployed pre-0.5.0 contract:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.0 <0.9.0;\n\n    interface OldContract {\n        function someOldFunction(uint8 a) external;\n        function anotherOldFunction() external returns (bool);\n    }\n\n    contract NewContract {\n        function doSomething(OldContract a) public returns (bool) {\n            a.someOldFunction(0x42);\n            return a.anotherOldFunction();\n        }\n    }\n\nSimilarly, pre-0.5.0 libraries can be used by defining the functions of the library without implementation and\nsupplying the address of the pre-0.5.0 library during linking (see :ref:`commandline-compiler` for how to use the\ncommandline compiler for linking):\n\n.. code-block:: solidity\n\n    // This will not compile after 0.6.0\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.5.0;\n\n    library OldLibrary {\n        function someFunction(uint8 a) public returns(bool);\n    }\n\n    contract NewContract {\n        function f(uint8 a) public returns (bool) {\n            return OldLibrary.someFunction(a);\n        }\n    }\n\n\nExample\n=======\n\nThe following example shows a contract and its updated version for Solidity\nv0.5.0 with some of the changes listed in this section.\n\nOld version:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.4.25;\n    // This will not compile after 0.5.0\n\n    contract OtherContract {\n        uint x;\n        function f(uint y) external {\n            x = y;\n        }\n        function() payable external {}\n    }\n\n    contract Old {\n        OtherContract other;\n        uint myNumber;\n\n        // Function mutability not provided, not an error.\n        function someInteger() internal returns (uint) { return 2; }\n\n        // Function visibility not provided, not an error.\n        // Function mutability not provided, not an error.\n        function f(uint x) returns (bytes) {\n            // Var is fine in this version.\n            var z = someInteger();\n            x += z;\n            // Throw is fine in this version.\n            if (x > 100)\n                throw;\n            bytes memory b = new bytes(x);\n            y = -3 >> 1;\n            // y == -1 (wrong, should be -2)\n            do {\n                x += 1;\n                if (x > 10) continue;\n                // 'Continue' causes an infinite loop.\n            } while (x < 11);\n            // Call returns only a Bool.\n            bool success = address(other).call(\"f\");\n            if (!success)\n                revert();\n            else {\n                // Local variables could be declared after their use.\n                int y;\n            }\n            return b;\n        }\n\n        // No need for an explicit data location for 'arr'\n        function g(uint[] arr, bytes8 x, OtherContract otherContract) public {\n            otherContract.transfer(1 ether);\n\n            // Since uint32 (4 bytes) is smaller than bytes8 (8 bytes),\n            // the first 4 bytes of x will be lost. This might lead to\n            // unexpected behavior since bytesX are right padded.\n            uint32 y = uint32(x);\n            myNumber += y + msg.value;\n        }\n    }\n\nNew version:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.5.0;\n    // This will not compile after 0.6.0\n\n    contract OtherContract {\n        uint x;\n        function f(uint y) external {\n            x = y;\n        }\n        function() payable external {}\n    }\n\n    contract New {\n        OtherContract other;\n        uint myNumber;\n\n        // Function mutability must be specified.\n        function someInteger() internal pure returns (uint) { return 2; }\n\n        // Function visibility must be specified.\n        // Function mutability must be specified.\n        function f(uint x) public returns (bytes memory) {\n            // The type must now be explicitly given.\n            uint z = someInteger();\n            x += z;\n            // Throw is now disallowed.\n            require(x <= 100);\n            int y = -3 >> 1;\n            require(y == -2);\n            do {\n                x += 1;\n                if (x > 10) continue;\n                // 'Continue' jumps to the condition below.\n            } while (x < 11);\n\n            // Call returns (bool, bytes).\n            // Data location must be specified.\n            (bool success, bytes memory data) = address(other).call(\"f\");\n            if (!success)\n                revert();\n            return data;\n        }\n\n        using AddressMakePayable for address;\n        // Data location for 'arr' must be specified\n        function g(uint[] memory /* arr */, bytes8 x, OtherContract otherContract, address unknownContract) public payable {\n            // 'otherContract.transfer' is not provided.\n            // Since the code of 'OtherContract' is known and has the fallback\n            // function, address(otherContract) has type 'address payable'.\n            address(otherContract).transfer(1 ether);\n\n            // 'unknownContract.transfer' is not provided.\n            // 'address(unknownContract).transfer' is not provided\n            // since 'address(unknownContract)' is not 'address payable'.\n            // If the function takes an 'address' which you want to send\n            // funds to, you can convert it to 'address payable' via 'uint160'.\n            // Note: This is not recommended and the explicit type\n            // 'address payable' should be used whenever possible.\n            // To increase clarity, we suggest the use of a library for\n            // the conversion (provided after the contract in this example).\n            address payable addr = unknownContract.makePayable();\n            require(addr.send(1 ether));\n\n            // Since uint32 (4 bytes) is smaller than bytes8 (8 bytes),\n            // the conversion is not allowed.\n            // We need to convert to a common size first:\n            bytes4 x4 = bytes4(x); // Padding happens on the right\n            uint32 y = uint32(x4); // Conversion is consistent\n            // 'msg.value' cannot be used in a 'non-payable' function.\n            // We need to make the function payable\n            myNumber += y + msg.value;\n        }\n    }\n\n    // We can define a library for explicitly converting ``address``\n    // to ``address payable`` as a workaround.\n    library AddressMakePayable {\n        function makePayable(address x) internal pure returns (address payable) {\n            return address(uint160(x));\n        }\n    }\n"
  },
  {
    "path": "docs/060-breaking-changes.rst",
    "content": "********************************\nSolidity v0.6.0 Breaking Changes\n********************************\n\nThis section highlights the main breaking changes introduced in Solidity\nversion 0.6.0, along with the reasoning behind the changes and how to update\naffected code.\nFor the full list check\n`the release changelog <https://github.com/argotorg/solidity/releases/tag/v0.6.0>`_.\n\n\nChanges the Compiler Might not Warn About\n=========================================\n\nThis section lists changes where the behavior of your code might\nchange without the compiler telling you about it.\n\n* The resulting type of an exponentiation is the type of the base. It used to be the smallest type\n  that can hold both the type of the base and the type of the exponent, as with symmetric\n  operations. Additionally, signed types are allowed for the base of the exponentiation.\n\n\nExplicitness Requirements\n=========================\n\nThis section lists changes where the code now needs to be more explicit,\nbut the semantics do not change.\nFor most of the topics the compiler will provide suggestions.\n\n* Functions can now only be overridden when they are either marked with the\n  ``virtual`` keyword or defined in an interface. Functions without\n  implementation outside an interface have to be marked ``virtual``.\n  When overriding a function or modifier, the new keyword ``override``\n  must be used. When overriding a function or modifier defined in multiple\n  parallel bases, all bases must be listed in parentheses after the keyword\n  like so: ``override(Base1, Base2)``.\n\n* Member-access to ``length`` of arrays is now always read-only, even for storage arrays. It is no\n  longer possible to resize storage arrays by assigning a new value to their length. Use ``push()``,\n  ``push(value)`` or ``pop()`` instead, or assign a full array, which will of course overwrite the existing content.\n  The reason behind this is to prevent storage collisions of gigantic\n  storage arrays.\n\n* The new keyword ``abstract`` can be used to mark contracts as abstract. It has to be used\n  if a contract does not implement all its functions. Abstract contracts cannot be created using the ``new`` operator,\n  and it is not possible to generate bytecode for them during compilation.\n\n* Libraries have to implement all their functions, not only the internal ones.\n\n* The names of variables declared in inline assembly may no longer end in ``_slot`` or ``_offset``.\n\n* Variable declarations in inline assembly may no longer shadow any declaration outside the inline assembly block.\n  If the name contains a dot, its prefix up to the dot may not conflict with any declaration outside the inline\n  assembly block.\n\n* In inline assembly, opcodes that do not take arguments are now represented as \"built-in functions\" instead of standalone identifiers. So ``gas`` is now ``gas()``.\n\n* State variable shadowing is now disallowed.  A derived contract can only\n  declare a state variable ``x``, if there is no visible state variable with\n  the same name in any of its bases.\n\n\nSemantic and Syntactic Changes\n==============================\n\nThis section lists changes where you have to modify your code\nand it does something else afterwards.\n\n* Conversions from external function types to ``address`` are now disallowed. Instead external\n  function types have a member called ``address``, similar to the existing ``selector`` member.\n\n* The function ``push(value)`` for dynamic storage arrays does not return the new length anymore (it returns nothing).\n\n* The unnamed function commonly referred to as \"fallback function\" was split up into a new\n  fallback function that is defined using the ``fallback`` keyword and a receive ether function\n  defined using the ``receive`` keyword.\n\n  * If present, the receive ether function is called whenever the call data is empty (whether\n    or not ether is received). This function is implicitly ``payable``.\n\n  * The new fallback function is called when no other function matches (if the receive ether\n    function does not exist then this includes calls with empty call data).\n    You can make this function ``payable`` or not. If it is not ``payable`` then transactions\n    not matching any other function which send value will revert. You should only need to\n    implement the new fallback function if you are following an upgrade or proxy pattern.\n\n\nNew Features\n============\n\nThis section lists things that were not possible prior to Solidity 0.6.0\nor were more difficult to achieve.\n\n* The :ref:`try/catch statement <try-catch>` allows you to react on failed external calls.\n* ``struct`` and ``enum`` types can be declared at file level.\n* Array slices can be used for calldata arrays, for example ``abi.decode(msg.data[4:], (uint, uint))``\n  is a low-level way to decode the function call payload.\n* Natspec supports multiple return parameters in developer documentation, enforcing the same naming check as ``@param``.\n* Yul and Inline Assembly have a new statement called ``leave`` that exits the current function.\n* Conversions from ``address`` to ``address payable`` are now possible via ``payable(x)``, where\n  ``x`` must be of type ``address``.\n\n\nInterface Changes\n=================\n\nThis section lists changes that are unrelated to the language itself, but that have an effect on the interfaces of\nthe compiler. These may change the way how you use the compiler on the command-line, how you use its programmable\ninterface, or how you analyze the output produced by it.\n\nNew Error Reporter\n~~~~~~~~~~~~~~~~~~\n\nA new error reporter was introduced, which aims at producing more accessible error messages on the command-line.\nIt is enabled by default, but passing ``--old-reporter`` falls back to the deprecated old error reporter.\n\nMetadata Hash Options\n~~~~~~~~~~~~~~~~~~~~~\n\nThe compiler now appends the `IPFS <https://ipfs.io/>`_ hash of the metadata file to the end of the bytecode by default\n(for details, see documentation on :doc:`contract metadata <metadata>`). Before 0.6.0, the compiler appended the\n`Swarm <https://www.ethswarm.org/>`_ hash by default, and in order to still support this behavior,\nthe new command-line option ``--metadata-hash`` was introduced. It allows you to select the hash to be produced and\nappended, by passing either ``ipfs`` or ``swarm`` as value to the ``--metadata-hash`` command-line option.\nPassing the value ``none`` completely removes the hash.\n\nThese changes can also be used via the :ref:`Standard JSON Interface<compiler-api>` and effect the metadata JSON generated by the compiler.\n\nThe recommended way to read the metadata is to read the last two bytes to determine the length of the CBOR encoding\nand perform a proper decoding on that data block as explained in the :ref:`metadata section<encoding-of-the-metadata-hash-in-the-bytecode>`.\n\nYul Optimizer\n~~~~~~~~~~~~~\n\nTogether with the legacy bytecode optimizer, the :doc:`Yul <yul>` optimizer is now enabled by default when you call the compiler\nwith ``--optimize``. It can be disabled by calling the compiler with ``--no-optimize-yul``.\nThis mostly affects code that uses ABI coder v2.\n\nC API Changes\n~~~~~~~~~~~~~\n\nThe client code that uses the C API of ``libsolc`` is now in control of the memory used by the compiler. To make\nthis change consistent, ``solidity_free`` was renamed to ``solidity_reset``, the functions ``solidity_alloc`` and\n``solidity_free`` were added and ``solidity_compile`` now returns a string that must be explicitly freed via\n``solidity_free()``.\n\n\nHow to update your code\n=======================\n\nThis section gives detailed instructions on how to update prior code for every breaking change.\n\n* Change ``address(f)`` to ``f.address`` for ``f`` being of external function type.\n\n* Replace ``function () external [payable] { ... }`` by either ``receive() external payable { ... }``,\n  ``fallback() external [payable] { ... }`` or both. Prefer\n  using a ``receive`` function only, whenever possible.\n\n* Change ``uint length = array.push(value)`` to ``array.push(value);``. The new length can be\n  accessed via ``array.length``.\n\n* Change ``array.length++`` to ``array.push()`` to increase, and use ``pop()`` to decrease\n  the length of a storage array.\n\n* For every named return parameter in a function's ``@dev`` documentation define a ``@return``\n  entry which contains the parameter's name as the first word. E.g. if you have function ``f()`` defined\n  like ``function f() public returns (uint value)`` and a ``@dev`` annotating it, document its return\n  parameters like so: ``@return value The return value.``. You can mix named and un-named return parameters\n  documentation so long as the notices are in the order they appear in the tuple return type.\n\n* Choose unique identifiers for variable declarations in inline assembly that do not conflict\n  with declarations outside the inline assembly block.\n\n* Add ``virtual`` to every non-interface function you intend to override. Add ``virtual``\n  to all functions without implementation outside interfaces. For single inheritance, add\n  ``override`` to every overriding function. For multiple inheritance, add ``override(A, B, ..)``,\n  where you list all contracts that define the overridden function in the parentheses. When\n  multiple bases define the same function, the inheriting contract must override all conflicting functions.\n\n* In inline assembly, add ``()`` to all opcodes that do not otherwise accept an argument.\n  For example, change ``pc`` to ``pc()``, and ``gas`` to ``gas()``.\n"
  },
  {
    "path": "docs/070-breaking-changes.rst",
    "content": "********************************\nSolidity v0.7.0 Breaking Changes\n********************************\n\nThis section highlights the main breaking changes introduced in Solidity\nversion 0.7.0, along with the reasoning behind the changes and how to update\naffected code.\nFor the full list check\n`the release changelog <https://github.com/argotorg/solidity/releases/tag/v0.7.0>`_.\n\n\nSilent Changes of the Semantics\n===============================\n\n* Exponentiation and shifts of literals by non-literals (e.g. ``1 << x`` or ``2 ** x``)\n  will always use either the type ``uint256`` (for non-negative literals) or\n  ``int256`` (for negative literals) to perform the operation.\n  Previously, the operation was performed in the type of the shift amount / the\n  exponent which can be misleading.\n\n\nChanges to the Syntax\n=====================\n\n* In external function and contract creation calls, Ether and gas is now specified using a new syntax:\n  ``x.f{gas: 10000, value: 2 ether}(arg1, arg2)``.\n  The old syntax -- ``x.f.gas(10000).value(2 ether)(arg1, arg2)`` -- will cause an error.\n\n* The global variable ``now`` is deprecated, ``block.timestamp`` should be used instead.\n  The single identifier ``now`` is too generic for a global variable and could give the impression\n  that it changes during transaction processing, whereas ``block.timestamp`` correctly\n  reflects the fact that it is just a property of the block.\n\n* NatSpec comments on variables are only allowed for public state variables and not\n  for local or internal variables.\n\n* The token ``gwei`` is a keyword now (used to specify, e.g. ``2 gwei`` as a number)\n  and cannot be used as an identifier.\n\n* String literals now can only contain printable ASCII characters and this also includes a variety of\n  escape sequences, such as hexadecimal (``\\xff``) and unicode escapes (``\\u20ac``).\n\n* Unicode string literals are supported now to accommodate valid UTF-8 sequences. They are identified\n  with the ``unicode`` prefix: ``unicode\"Hello 😃\"``.\n\n* State Mutability: The state mutability of functions can now be restricted during inheritance:\n  Functions with default state mutability can be overridden by ``pure`` and ``view`` functions\n  while ``view`` functions can be overridden by ``pure`` functions.\n  At the same time, public state variables are considered ``view`` and even ``pure``\n  if they are constants.\n\n\n\nInline Assembly\n---------------\n\n* Disallow ``.`` in user-defined function and variable names in inline assembly.\n  It is still valid if you use Solidity in Yul-only mode.\n\n* Slot and offset of storage pointer variable ``x`` are accessed via ``x.slot``\n  and ``x.offset`` instead of ``x_slot`` and ``x_offset``.\n\nRemoval of Unused or Unsafe Features\n====================================\n\nMappings outside Storage\n------------------------\n\n* If a struct or array contains a mapping, it can only be used in storage.\n  Previously, mapping members were silently skipped in memory, which\n  is confusing and error-prone.\n\n* Assignments to structs or arrays in storage does not work if they contain\n  mappings.\n  Previously, mappings were silently skipped during the copy operation, which\n  is misleading and error-prone.\n\nFunctions and Events\n--------------------\n\n* Visibility (``public`` / ``internal``) is not needed for constructors anymore:\n  To prevent a contract from being created, it can be marked ``abstract``.\n  This makes the visibility concept for constructors obsolete.\n\n* Type Checker: Disallow ``virtual`` for library functions:\n  Since libraries cannot be inherited from, library functions should not be virtual.\n\n* Multiple events with the same name and parameter types in the same\n  inheritance hierarchy are disallowed.\n\n* ``using A for B`` only affects the contract it is mentioned in.\n  Previously, the effect was inherited. Now, you have to repeat the ``using``\n  statement in all derived contracts that make use of the feature.\n\nExpressions\n-----------\n\n* Shifts by signed types are disallowed.\n  Previously, shifts by negative amounts were allowed, but reverted at runtime.\n\n* The ``finney`` and ``szabo`` denominations are removed.\n  They are rarely used and do not make the actual amount readily visible. Instead, explicit\n  values like ``1e20`` or the very common ``gwei`` can be used.\n\nDeclarations\n------------\n\n* The keyword ``var`` cannot be used anymore.\n  Previously, this keyword would parse but result in a type error and\n  a suggestion about which type to use. Now, it results in a parser error.\n\nInterface Changes\n=================\n\n* JSON AST: Mark hex string literals with ``kind: \"hexString\"``.\n* JSON AST: Members with value ``null`` are removed from JSON output.\n* NatSpec: Constructors and functions have consistent userdoc output.\n\n\nHow to update your code\n=======================\n\nThis section gives detailed instructions on how to update prior code for every breaking change.\n\n* Change ``x.f.value(...)()`` to ``x.f{value: ...}()``. Similarly ``(new C).value(...)()`` to\n  ``new C{value: ...}()`` and ``x.f.gas(...).value(...)()`` to ``x.f{gas: ..., value: ...}()``.\n* Change ``now`` to ``block.timestamp``.\n* Change types of right operand in shift operators to unsigned types. For example change ``x >> (256 - y)`` to\n  ``x >> uint(256 - y)``.\n* Repeat the ``using A for B`` statements in all derived contracts if needed.\n* Remove the ``public`` keyword from every constructor.\n* Remove the ``internal`` keyword from every constructor and add ``abstract`` to the contract (if not already present).\n* Change ``_slot`` and ``_offset`` suffixes in inline assembly to ``.slot`` and ``.offset``, respectively.\n"
  },
  {
    "path": "docs/080-breaking-changes.rst",
    "content": "********************************\nSolidity v0.8.0 Breaking Changes\n********************************\n\nThis section highlights the main breaking changes introduced in Solidity\nversion 0.8.0.\nFor the full list check\n`the release changelog <https://github.com/argotorg/solidity/releases/tag/v0.8.0>`_.\n\nSilent Changes of the Semantics\n===============================\n\nThis section lists changes where existing code changes its behavior without\nthe compiler notifying you about it.\n\n* Arithmetic operations revert on underflow and overflow. You can use ``unchecked { ... }`` to use\n  the previous wrapping behavior.\n\n  Checks for overflow are very common, so we made them the default to increase readability of code,\n  even if it comes at a slight increase of gas costs.\n\n* ABI coder v2 is activated by default.\n\n  You can choose to use the old behavior using ``pragma abicoder v1;``.\n  The pragma ``pragma experimental ABIEncoderV2;`` is still valid, but it is deprecated and has no effect.\n  If you want to be explicit, please use ``pragma abicoder v2;`` instead.\n\n  Note that ABI coder v2 supports more types than v1 and performs more sanity checks on the inputs.\n  ABI coder v2 makes some function calls more expensive and it can also make contract calls\n  revert that did not revert with ABI coder v1 when they contain data that does not conform to the\n  parameter types.\n\n* Exponentiation is right associative, i.e., the expression ``a**b**c`` is parsed as ``a**(b**c)``.\n  Before 0.8.0, it was parsed as ``(a**b)**c``.\n\n  This is the common way to parse the exponentiation operator.\n\n* Failing assertions and other internal checks like division by zero or arithmetic overflow do\n  not use the invalid opcode but instead the revert opcode.\n  More specifically, they will use error data equal to a function call to ``Panic(uint256)`` with an error code specific\n  to the circumstances.\n\n  This will save gas on errors while it still allows static analysis tools to distinguish\n  these situations from a revert on invalid input, like a failing ``require``.\n\n* If a byte array in storage is accessed whose length is encoded incorrectly, a panic is caused.\n  A contract cannot get into this situation unless inline assembly is used to modify the raw representation of storage byte arrays.\n\n* If constants are used in array length expressions, previous versions of Solidity would use arbitrary precision\n  in all branches of the evaluation tree. Now, if constant variables are used as intermediate expressions,\n  their values will be properly rounded in the same way as when they are used in run-time expressions.\n\n* The type ``byte`` has been removed. It was an alias of ``bytes1``.\n\nNew Restrictions\n================\n\nThis section lists changes that might cause existing contracts to not compile anymore.\n\n* There are new restrictions related to explicit conversions of literals. The previous behavior in\n  the following cases was likely ambiguous:\n\n  1. Explicit conversions from negative literals and literals larger than ``type(uint160).max`` to\n     ``address`` are disallowed.\n  2. Explicit conversions between literals and an integer type ``T`` are only allowed if the literal\n     lies between ``type(T).min`` and ``type(T).max``. In particular, replace usages of ``uint(-1)``\n     with ``type(uint).max``.\n  3. Explicit conversions between literals and enums are only allowed if the literal can\n     represent a value in the enum.\n  4. Explicit conversions between literals and ``address`` type (e.g. ``address(literal)``) have the\n     type ``address`` instead of ``address payable``. One can get a payable address type by using an\n     explicit conversion, i.e., ``payable(literal)``.\n\n* :ref:`Address literals<address_literals>` have the type ``address`` instead of ``address\n  payable``. They can be converted to ``address payable`` by using an explicit conversion, e.g.\n  ``payable(0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF)``.\n\n* There are new restrictions on explicit type conversions. The conversion is only allowed when there\n  is at most one change in sign, width or type-category (``int``, ``address``, ``bytesNN``, etc.).\n  To perform multiple changes, use multiple conversions.\n\n  Let us use the notation ``T(S)`` to denote the explicit conversion ``T(x)``, where, ``T`` and\n  ``S`` are types, and ``x`` is any arbitrary variable of type ``S``. An example of such a\n  disallowed conversion would be ``uint16(int8)`` since it changes both width (8 bits to 16 bits)\n  and sign (signed integer to unsigned integer). In order to do the conversion, one has to go\n  through an intermediate type. In the previous example, this would be ``uint16(uint8(int8))`` or\n  ``uint16(int16(int8))``. Note that the two ways to convert will produce different results e.g.,\n  for ``-1``. The following are some examples of conversions that are disallowed by this rule.\n\n  - ``address(uint)`` and ``uint(address)``: converting both type-category and width. Replace this by\n    ``address(uint160(uint))`` and ``uint(uint160(address))`` respectively.\n  - ``payable(uint160)``, ``payable(bytes20)`` and ``payable(integer-literal)``: converting both\n    type-category and state-mutability. Replace this by ``payable(address(uint160))``,\n    ``payable(address(bytes20))`` and ``payable(address(integer-literal))`` respectively. Note that\n    ``payable(0)`` is valid and is an exception to the rule.\n  - ``int80(bytes10)`` and ``bytes10(int80)``: converting both type-category and sign. Replace this by\n    ``int80(uint80(bytes10))`` and ``bytes10(uint80(int80)`` respectively.\n  - ``Contract(uint)``: converting both type-category and width. Replace this by\n    ``Contract(address(uint160(uint)))``.\n\n  These conversions were disallowed to avoid ambiguity. For example, in the expression ``uint16 x =\n  uint16(int8(-1))``, the value of ``x`` would depend on whether the sign or the width conversion\n  was applied first.\n\n* Function call options can only be given once, i.e. ``c.f{gas: 10000}{value: 1}()`` is invalid and has to be changed to ``c.f{gas: 10000, value: 1}()``.\n\n* The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed.\n\n  These are low-level functions that were largely unused. Their behavior can be accessed from inline assembly.\n\n* ``enum`` definitions cannot contain more than 256 members.\n\n  This will make it safe to assume that the underlying type in the ABI is always ``uint8``.\n\n* Declarations with the name ``this``, ``super`` and ``_`` are disallowed, with the exception of\n  public functions and events. The exception is to make it possible to declare interfaces of contracts\n  implemented in languages other than Solidity that do permit such function names.\n\n* Remove support for the ``\\b``, ``\\f``, and ``\\v`` escape sequences in code.\n  They can still be inserted via hexadecimal escapes, e.g. ``\\x08``, ``\\x0c``, and ``\\x0b``, respectively.\n\n* The global variables ``tx.origin`` and ``msg.sender`` have the type ``address`` instead of\n  ``address payable``. One can convert them into ``address payable`` by using an explicit\n  conversion, i.e., ``payable(tx.origin)`` or ``payable(msg.sender)``.\n\n  This change was done since the compiler cannot determine whether or not these addresses\n  are payable or not, so it now requires an explicit conversion to make this requirement visible.\n\n* Explicit conversion into ``address`` type always returns a non-payable ``address`` type. In\n  particular, the following explicit conversions have the type ``address`` instead of ``address\n  payable``:\n\n  - ``address(u)`` where ``u`` is a variable of type ``uint160``. One can convert ``u``\n    into the type ``address payable`` by using two explicit conversions, i.e.,\n    ``payable(address(u))``.\n  - ``address(b)`` where ``b`` is a variable of type ``bytes20``. One can convert ``b``\n    into the type ``address payable`` by using two explicit conversions, i.e.,\n    ``payable(address(b))``.\n  - ``address(c)`` where ``c`` is a contract. Previously, the return type of this\n    conversion depended on whether the contract can receive Ether (either by having a receive\n    function or a payable fallback function). The conversion ``payable(c)`` has the type ``address\n    payable`` and is only allowed when the contract ``c`` can receive Ether. In general, one can\n    always convert ``c`` into the type ``address payable`` by using the following explicit\n    conversion: ``payable(address(c))``. Note that ``address(this)`` falls under the same category\n    as ``address(c)`` and the same rules apply for it.\n\n* The ``chainid`` builtin in inline assembly is now considered ``view`` instead of ``pure``.\n\n* Unary negation cannot be used on unsigned integers anymore, only on signed integers.\n\nInterface Changes\n=================\n\n* The output of ``--combined-json`` has changed: JSON fields ``abi``, ``devdoc``, ``userdoc`` and\n  ``storage-layout`` are sub-objects now. Before 0.8.0 they used to be serialised as strings.\n\n* The \"legacy AST\" has been removed (``--ast-json`` on the commandline interface and ``legacyAST`` for standard JSON).\n  Use the \"compact AST\" (``--ast-compact-json`` resp. ``AST``) as replacement.\n\n* The old error reporter (``--old-reporter``) has been removed.\n\n\nHow to update your code\n=======================\n\n- If you rely on wrapping arithmetic, surround each operation with ``unchecked { ... }``.\n- Optional: If you use SafeMath or a similar library, change ``x.add(y)`` to ``x + y``, ``x.mul(y)`` to ``x * y`` etc.\n- Add ``pragma abicoder v1;`` if you want to stay with the old ABI coder.\n- Optionally remove ``pragma experimental ABIEncoderV2`` or ``pragma abicoder v2`` since it is redundant.\n- Change ``byte`` to ``bytes1``.\n- Add intermediate explicit type conversions if required.\n- Combine ``c.f{gas: 10000}{value: 1}()`` to ``c.f{gas: 10000, value: 1}()``.\n- Change ``msg.sender.transfer(x)`` to ``payable(msg.sender).transfer(x)`` or use a stored variable of ``address payable`` type.\n- Change ``x**y**z`` to ``(x**y)**z``.\n- Use inline assembly as a replacement for ``log0``, ..., ``log4``.\n- Negate unsigned integers by subtracting them from the maximum value of the type and adding 1 (e.g. ``type(uint256).max - x + 1``, while ensuring that ``x`` is not zero)\n"
  },
  {
    "path": "docs/Makefile",
    "content": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nPAPER         =\nBUILDDIR      = _build\n\n# User-friendly check for sphinx-build\nifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)\n$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)\nendif\n\n# Internal variables.\nPAPEROPT_a4     = -D latex_paper_size=a4\nPAPEROPT_letter = -D latex_paper_size=letter\nALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n# the i18n builder cannot share the environment and doctrees with the others\nI18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n\n.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext\n\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@echo \"  html       to make standalone HTML files\"\n\t@echo \"  dirhtml    to make HTML files named index.html in directories\"\n\t@echo \"  singlehtml to make a single large HTML file\"\n\t@echo \"  pickle     to make pickle files\"\n\t@echo \"  json       to make JSON files\"\n\t@echo \"  htmlhelp   to make HTML files and a HTML help project\"\n\t@echo \"  qthelp     to make HTML files and a qthelp project\"\n\t@echo \"  devhelp    to make HTML files and a Devhelp project\"\n\t@echo \"  epub       to make an epub\"\n\t@echo \"  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\"\n\t@echo \"  latexpdf   to make LaTeX files and run them through pdflatex\"\n\t@echo \"  text       to make text files\"\n\t@echo \"  man        to make manual pages\"\n\t@echo \"  texinfo    to make Texinfo files\"\n\t@echo \"  info       to make Texinfo files and run them through makeinfo\"\n\t@echo \"  gettext    to make PO message catalogs\"\n\t@echo \"  changes    to make an overview of all changed/added/deprecated items\"\n\t@echo \"  xml        to make Docutils-native XML files\"\n\t@echo \"  pseudoxml  to make pseudoxml-XML files for display purposes\"\n\t@echo \"  linkcheck  to check all external links for integrity\"\n\t@echo \"  doctest    to run all doctests embedded in the documentation (if enabled)\"\n\nclean:\n\trm -rf $(BUILDDIR)/*\n\nhtml:\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/html.\"\n\ndirhtml:\n\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/dirhtml.\"\n\nsinglehtml:\n\t$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml\n\t@echo\n\t@echo \"Build finished. The HTML page is in $(BUILDDIR)/singlehtml.\"\n\npickle:\n\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle\n\t@echo\n\t@echo \"Build finished; now you can process the pickle files.\"\n\njson:\n\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json\n\t@echo\n\t@echo \"Build finished; now you can process the JSON files.\"\n\nhtmlhelp:\n\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp\n\t@echo\n\t@echo \"Build finished; now you can run HTML Help Workshop with the\" \\\n\t      \".hhp project file in $(BUILDDIR)/htmlhelp.\"\n\nqthelp:\n\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp\n\t@echo\n\t@echo \"Build finished; now you can run \"qcollectiongenerator\" with the\" \\\n\t      \".qhcp project file in $(BUILDDIR)/qthelp, like this:\"\n\t@echo \"# qcollectiongenerator $(BUILDDIR)/qthelp/Solidity.qhcp\"\n\t@echo \"To view the help file:\"\n\t@echo \"# assistant -collectionFile $(BUILDDIR)/qthelp/Solidity.qhc\"\n\ndevhelp:\n\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp\n\t@echo\n\t@echo \"Build finished.\"\n\t@echo \"To view the help file:\"\n\t@echo \"# mkdir -p $$HOME/.local/share/devhelp/Solidity\"\n\t@echo \"# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Solidity\"\n\t@echo \"# devhelp\"\n\nepub:\n\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub\n\t@echo\n\t@echo \"Build finished. The epub file is in $(BUILDDIR)/epub.\"\n\nlatex:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo\n\t@echo \"Build finished; the LaTeX files are in $(BUILDDIR)/latex.\"\n\t@echo \"Run \\`make' in that directory to run these through (pdf)latex\" \\\n\t      \"(use \\`make latexpdf' here to do that automatically).\"\n\nlatexpdf:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through pdflatex...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\ntext:\n\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text\n\t@echo\n\t@echo \"Build finished. The text files are in $(BUILDDIR)/text.\"\n\nman:\n\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man\n\t@echo\n\t@echo \"Build finished. The manual pages are in $(BUILDDIR)/man.\"\n\ntexinfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo\n\t@echo \"Build finished. The Texinfo files are in $(BUILDDIR)/texinfo.\"\n\t@echo \"Run \\`make' in that directory to run these through makeinfo\" \\\n\t      \"(use \\`make info' here to do that automatically).\"\n\ninfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo \"Running Texinfo files through makeinfo...\"\n\tmake -C $(BUILDDIR)/texinfo info\n\t@echo \"makeinfo finished; the Info files are in $(BUILDDIR)/texinfo.\"\n\ngettext:\n\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale\n\t@echo\n\t@echo \"Build finished. The message catalogs are in $(BUILDDIR)/locale.\"\n\nchanges:\n\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes\n\t@echo\n\t@echo \"The overview file is in $(BUILDDIR)/changes.\"\n\nlinkcheck:\n\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck\n\t@echo\n\t@echo \"Link check complete; look for any errors in the above output \" \\\n\t      \"or in $(BUILDDIR)/linkcheck/output.txt.\"\n\ndoctest:\n\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest\n\t@echo \"Testing of doctests in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/doctest/output.txt.\"\n\nxml:\n\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml\n\t@echo\n\t@echo \"Build finished. The XML files are in $(BUILDDIR)/xml.\"\n\npseudoxml:\n\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml\n\t@echo\n\t@echo \"Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml.\"\n"
  },
  {
    "path": "docs/README.md",
    "content": "# Solidity Language Docs\n\n## Local environment setup\n\n1. Install python https://www.python.org/downloads/\n1. Install sphinx (the tool used to generate the docs) https://www.sphinx-doc.org/en/master/usage/installation.html\n\nGo to `/docs` and run `./docs.sh` to install dependencies and build the project:\n\n```sh\ncd docs\n./docs.sh\n```\n\nThat will output the generated htmls under _build/\n\n## Serve environment\n\n```py\npython3 -m http.server -d _build/html --cgi 8080\n```\n\nVisit dev server at http://localhost:8080\n"
  },
  {
    "path": "docs/_static/css/custom-dark.css",
    "content": "\n\n/* DARK MODE STYLING */\n\n/* code directives */\n\n:root[style*=dark] .method dt,\n:root[style*=dark] .class dt,\n:root[style*=dark] .data dt,\n:root[style*=dark] .attribute dt,\n:root[style*=dark] .function dt,\n:root[style*=dark] .classmethod dt,\n:root[style*=dark] .exception dt,\n:root[style*=dark] .descclassname,\n:root[style*=dark] .descname {\n  background-color: #2d2d2d !important;\n}\n\n:root[style*=dark] .rst-content dl:not(.docutils) dt {\n  background-color: #0008;\n  border-top: solid 3px #fff2;\n  border-left: solid 3px #fff2;\n}\n\n:root[style*=dark] em.property {\n  color: #888888;\n}\n\n\n/* tables */\n\n:root[style*=dark] .rst-content table.docutils td {\n  border: 0px;\n}\n\n:root[style*=dark] .rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td {\n  background-color: #0002;\n}\n\n:root[style*=dark] .rst-content pre {\n  background: none;\n}\n\n/* inlined code highlights */\n\n:root[style*=dark] .xref,\n:root[style*=dark] .py-meth {\n  color: #aaddff !important;\n  font-weight: normal !important;\n}\n\n/* highlight color search text */\n\n:root[style*=dark] .rst-content .highlighted {\n  background: #ff5722;\n  box-shadow: 0 0 0 2px #f0978b;\n}\n\n/* notes, warnings, hints */\n\n:root[style*=dark] .hint .admonition-title {\n  background: #2aa87c !important;\n}\n\n:root[style*=dark] .warning .admonition-title {\n  background: #cc4444 !important;\n}\n\n:root[style*=dark] .admonition-title {\n  background: #3a7ca8 !important;\n}\n\n:root[style*=dark] .admonition,\n:root[style*=dark] .note {\n  background-color: #0008 !important;\n}\n\n\n/* table of contents */\n\n:root[style*=dark] .sidebar {\n  background-color: #191919 !important;\n}\n\n:root[style*=dark] .sidebar-title {\n  background-color: #2b2b2b !important;\n}\n\n:root[style*=dark] .wy-menu-vertical code.docutils.literal.notranslate {\n  background: none !important;\n  border: none !important;\n}\n\n\n:root[style*=dark] .toc-backref {\n  color: grey !important;\n}\n\n:root[style*=dark] .highlight {\n  background: #0008;\n  color: #f8f8f2\n}\n\n:root[style*=dark] .highlight .c {\n  color: #888\n}\n\n\n/* Comment */\n\n:root[style*=dark] .highlight .err {\n  color: #960050;\n  background-color: #1e0010\n}\n\n\n/* Error */\n\n:root[style*=dark] .highlight .k {\n  color: #66d9ef\n}\n\n\n/* Keyword */\n\n:root[style*=dark] .highlight .l {\n  color: #ae81ff\n}\n\n\n/* Literal */\n\n:root[style*=dark] .highlight .n {\n  color: #f8f8f2\n}\n\n\n/* Name */\n\n:root[style*=dark] .highlight .o {\n  color: #f92672\n}\n\n\n/* Operator */\n\n:root[style*=dark] .highlight .p {\n  color: #f8f8f2\n}\n\n\n/* Punctuation */\n\n:root[style*=dark] .highlight .ch {\n  color: #888\n}\n\n\n/* Comment.Hashbang */\n\n:root[style*=dark] .highlight .cm {\n  color: #888\n}\n\n\n/* Comment.Multiline */\n\n:root[style*=dark] .highlight .cp {\n  color: #888\n}\n\n\n/* Comment.Preproc */\n\n:root[style*=dark] .highlight .cpf {\n  color: #888\n}\n\n\n/* Comment.PreprocFile */\n\n:root[style*=dark] .highlight .c1 {\n  color: #888\n}\n\n\n/* Comment.Single */\n\n:root[style*=dark] .highlight .cs {\n  color: #888\n}\n\n\n/* Comment.Special */\n\n:root[style*=dark] .highlight .gd {\n  color: #f92672\n}\n\n\n/* Generic.Deleted */\n\n:root[style*=dark] .highlight .ge {\n  font-style: italic\n}\n\n\n/* Generic.Emph */\n\n:root[style*=dark] .highlight .gi {\n  color: #a6e22e\n}\n\n\n/* Generic.Inserted */\n\n:root[style*=dark] .highlight .gs {\n  font-weight: bold\n}\n\n\n/* Generic.Strong */\n\n:root[style*=dark] .highlight .gu {\n  color: #888\n}\n\n\n/* Generic.Subheading */\n\n:root[style*=dark] .highlight .kc {\n  color: #66d9ef\n}\n\n\n/* Keyword.Constant */\n\n:root[style*=dark] .highlight .kd {\n  color: #66d9ef\n}\n\n\n/* Keyword.Declaration */\n\n:root[style*=dark] .highlight .kn {\n  color: #f92672\n}\n\n\n/* Keyword.Namespace */\n\n:root[style*=dark] .highlight .kp {\n  color: #66d9ef\n}\n\n\n/* Keyword.Pseudo */\n\n:root[style*=dark] .highlight .kr {\n  color: #66d9ef\n}\n\n\n/* Keyword.Reserved */\n\n:root[style*=dark] .highlight .kt {\n  color: #66d9ef\n}\n\n\n/* Keyword.Type */\n\n:root[style*=dark] .highlight .ld {\n  color: #e6db74\n}\n\n\n/* Literal.Date */\n\n:root[style*=dark] .highlight .m {\n  color: #ae81ff\n}\n\n\n/* Literal.Number */\n\n:root[style*=dark] .highlight .s {\n  color: #e6db74\n}\n\n\n/* Literal.String */\n\n:root[style*=dark] .highlight .na {\n  color: #a6e22e\n}\n\n\n/* Name.Attribute */\n\n:root[style*=dark] .highlight .nb {\n  color: #f8f8f2\n}\n\n\n/* Name.Builtin */\n\n:root[style*=dark] .highlight .nc {\n  color: #a6e22e\n}\n\n\n/* Name.Class */\n\n:root[style*=dark] .highlight .no {\n  color: #66d9ef\n}\n\n\n/* Name.Constant */\n\n:root[style*=dark] .highlight .nd {\n  color: #a6e22e\n}\n\n\n/* Name.Decorator */\n\n:root[style*=dark] .highlight .ni {\n  color: #f8f8f2\n}\n\n\n/* Name.Entity */\n\n:root[style*=dark] .highlight .ne {\n  color: #a6e22e\n}\n\n\n/* Name.Exception */\n\n:root[style*=dark] .highlight .nf {\n  color: #a6e22e\n}\n\n\n/* Name.Function */\n\n:root[style*=dark] .highlight .nl {\n  color: #f8f8f2\n}\n\n\n/* Name.Label */\n\n:root[style*=dark] .highlight .nn {\n  color: #f8f8f2\n}\n\n\n/* Name.Namespace */\n\n:root[style*=dark] .highlight .nx {\n  color: #a6e22e\n}\n\n\n/* Name.Other */\n\n:root[style*=dark] .highlight .py {\n  color: #f8f8f2\n}\n\n\n/* Name.Property */\n\n:root[style*=dark] .highlight .nt {\n  color: #f92672\n}\n\n\n/* Name.Tag */\n\n:root[style*=dark] .highlight .nv {\n  color: #f8f8f2\n}\n\n\n/* Name.Variable */\n\n:root[style*=dark] .highlight .ow {\n  color: #f92672\n}\n\n\n/* Operator.Word */\n\n:root[style*=dark] .highlight .w {\n  color: #f8f8f2\n}\n\n\n/* Text.Whitespace */\n\n:root[style*=dark] .highlight .mb {\n  color: #ae81ff\n}\n\n\n/* Literal.Number.Bin */\n\n:root[style*=dark] .highlight .mf {\n  color: #ae81ff\n}\n\n\n/* Literal.Number.Float */\n\n:root[style*=dark] .highlight .mh {\n  color: #ae81ff\n}\n\n\n/* Literal.Number.Hex */\n\n:root[style*=dark] .highlight .mi {\n  color: #ae81ff\n}\n\n\n/* Literal.Number.Integer */\n\n:root[style*=dark] .highlight .mo {\n  color: #ae81ff\n}\n\n\n/* Literal.Number.Oct */\n\n:root[style*=dark] .highlight .sa {\n  color: #e6db74\n}\n\n\n/* Literal.String.Affix */\n\n:root[style*=dark] .highlight .sb {\n  color: #e6db74\n}\n\n\n/* Literal.String.Backtick */\n\n:root[style*=dark] .highlight .sc {\n  color: #e6db74\n}\n\n\n/* Literal.String.Char */\n\n:root[style*=dark] .highlight .dl {\n  color: #e6db74\n}\n\n\n/* Literal.String.Delimiter */\n\n:root[style*=dark] .highlight .sd {\n  color: #e6db74\n}\n\n\n/* Literal.String.Doc */\n\n:root[style*=dark] .highlight .s2 {\n  color: #e6db74\n}\n\n\n/* Literal.String.Double */\n\n:root[style*=dark] .highlight .se {\n  color: #ae81ff\n}\n\n\n/* Literal.String.Escape */\n\n:root[style*=dark] .highlight .sh {\n  color: #e6db74\n}\n\n\n/* Literal.String.Heredoc */\n\n:root[style*=dark] .highlight .si {\n  color: #e6db74\n}\n\n\n/* Literal.String.Interpol */\n\n:root[style*=dark] .highlight .sx {\n  color: #e6db74\n}\n\n\n/* Literal.String.Other */\n\n:root[style*=dark] .highlight .sr {\n  color: #e6db74\n}\n\n\n/* Literal.String.Regex */\n\n:root[style*=dark] .highlight .s1 {\n  color: #e6db74\n}\n\n\n/* Literal.String.Single */\n\n:root[style*=dark] .highlight .ss {\n  color: #e6db74\n}\n\n\n/* Literal.String.Symbol */\n\n:root[style*=dark] .highlight .bp {\n  color: #f8f8f2\n}\n\n\n/* Name.Builtin.Pseudo */\n\n:root[style*=dark] .highlight .fm {\n  color: #a6e22e\n}\n\n\n/* Name.Function.Magic */\n\n:root[style*=dark] .highlight .vc {\n  color: #f8f8f2\n}\n\n\n/* Name.Variable.Class */\n\n:root[style*=dark] .highlight .vg {\n  color: #f8f8f2\n}\n\n\n/* Name.Variable.Global */\n\n:root[style*=dark] .highlight .vi {\n  color: #f8f8f2\n}\n\n\n/* Name.Variable.Instance */\n\n:root[style*=dark] .highlight .vm {\n  color: #f8f8f2\n}\n\n\n/* Name.Variable.Magic */\n\n:root[style*=dark] .highlight .il {\n  color: #ae81ff\n}\n\n\n/* Grammar */\n\n:root[style*=dark] .railroad-diagram {\n  fill: white;\n}\n\n:root[style*=dark] .railroad-diagram path {\n  stroke: white;\n}\n\n:root[style*=dark] .railroad-diagram rect {\n  stroke: white;\n}\n\n:root[style*=dark] .sig-name {\n  background-color: transparent !important;\n}\n"
  },
  {
    "path": "docs/_static/css/custom.css",
    "content": "/* ROOT DECLARATIONS */\n:root {\n    /* Text */\n    --color-a: #2B247C;\n    --color-b: #672AC8;\n    --color-c: #5554D9;\n    --color-d: #9F94E8;\n    --color-e: #AEC0F1;\n    --color-f: #E6E3EC;\n    /* Background */\n\n    --white: #FAF8FF;\n    --black: #110C4E;\n    --menu-bg: #2B247C06;\n    --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n\n    --navHeight: 4.5rem;\n    --sideWidth: 300px;\n    --maxWidth: 80rem;\n    --desktopInlinePadding: 2rem;\n    --mobileInlinePadding: 1rem;\n    --currentVersionHeight: 45px;\n\n    text-rendering: geometricPrecision;\n    -webkit-font-smoothing: antialiased;\n}\n\na,\nbutton {\n    border-radius: 0;\n}\n\n:root[style*=dark] {\n    --color-a: #E6E3EC !important;\n    --color-b: #AEC0F1 !important;\n    --color-c: #9F94E8 !important;\n    --color-d: #5554D9 !important;\n    --color-e: #672AC8 !important;\n    --color-f: #2B247C !important;\n\n    --white: #110C4E !important;\n    --black: #FAF8FF !important;\n    --menu-bg: #E6E3EC06 !important;\n}\n\nhtml,\nbody,\n.unified-header::before,\n.wy-nav-side,\n.rst-versions,\ncode,\ndiv,\ninput[type=text],\na,\n.wy-grid-for-nav {\n    transition: background 150ms ease-in-out;\n}\n\nhtml,\nbody,\n.wy-grid-for-nav {\n    background-color: var(--color-f) !important;\n}\n\nbody {\n    font-family: \"Overpass\", sans-serif;\n}\n\na {\n    color: var(--color-c);\n}\n\na, section {\n    scroll-margin-top: calc(var(--navHeight) + 2rem);\n}\n\nhr {\n    margin-block: 2rem;\n    border-color: var(--color-d) !important;\n}\n\n\n/* HEADER STYLES */\nh1 {\n    font-family: 'Overpass', sans-serif;\n    font-weight: 700;\n    font-size: 44px;\n    color: var(--color-a) !important;\n    line-height: 1.1;\n    text-wrap: balance;\n    margin-top: 4rem;\n    margin-bottom: 1.5rem;\n}\n\nsection:first-of-type h1:first-of-type {\n    font-family: 'Overpass Mono', monospace;\n    font-size: 48px;\n    margin-top: 3rem;\n    margin-bottom: 5rem;\n}\n\nh2 {\n    font-family: 'Overpass', sans-serif;\n    font-weight: 700;\n    font-size: 38px;\n    color: var(--color-a) !important;\n    line-height: 46px;\n    text-wrap: balance;\n    margin-top: 4rem;\n    margin-bottom: 1.5rem;\n}\n\n*:not([role=navigation])>p[role=heading]>span,\nh3 {\n    font-family: 'Overpass', sans-serif;\n    font-weight: 700;\n    font-size: 32px;\n    color: var(--color-a) !important;\n    line-height: 46px;\n    text-wrap: balance;\n    margin-top: 4rem;\n    margin-bottom: 1.5rem;\n}\n\nh4 {\n    font-family: 'Overpass', sans-serif;\n    font-weight: 700;\n    font-size: 32px;\n    color: var(--color-a) !important;\n    line-height: 46px;\n    text-wrap: balance;\n    margin-top: 3rem;\n    margin-bottom: 1.5rem;\n}\n\nh5 {\n    font-family: 'Overpass', sans-serif;\n    font-weight: 700;\n    font-size: 18px;\n    color: var(--color-a) !important;\n    line-height: 1.4;\n    text-wrap: balance;\n}\n\nh6 {\n    font-family: 'Overpass', sans-serif;\n    font-weight: 700;\n    font-size: 16px;\n    color: var(--color-a) !important;\n    line-height: 1.4;\n    text-wrap: balance;\n}\n\nspan.pre,\npre {\n    /* css-3 */\n    white-space: pre-wrap;\n    /* Mozilla, since 1999 */\n    white-space: -moz-pre-wrap;\n    /* Opera 4-6 */\n    white-space: -pre-wrap;\n    /* Opera 7 */\n    white-space: -o-pre-wrap;\n    word-wrap: break-word;\n    font-family: 'Overpass Mono', monospace;\n}\n\nsmall,\nsmall * {\n    font-size: 12px;\n}\n\n.wy-table-responsive table td,\n.wy-table-responsive table th {\n    white-space: normal;\n}\n\n.rst-content table.docutils td {\n    vertical-align: top;\n}\n\n/* links */\n.rst-content .highlighted {\n    background: #eac545;\n}\n\n/* code block highlights */\n.rst-content pre {\n    background: #fafafa;\n}\n\n/* project version (displayed under project logo) */\n.wy-side-nav-search>div.version {\n    color: var(--color-b);\n    margin-top: 0;\n    margin-bottom: 0.5rem;\n    text-align: start;\n}\n\n/* Link to Remix IDE shown next to code snippets */\n.rst-content p.remix-link-container {\n    display: block;\n    text-align: right;\n    margin: 0;\n    line-height: 1em;\n}\n\n.rst-content .remix-link-container a.remix-link {\n    font-size: 0.7em;\n    padding: 0.1em 0.5em;\n    background: transparent;\n    color: var(--color-a) !important;\n    border: 1px solid var(--color-a);\n    text-decoration: none;\n}\n\n.rst-content div.highlight-solidity,\n.rst-content div.highlight-yul {\n    margin-top: 0;\n}\n\n/* CUSTOMIZATION UPDATES */\n\n.wy-nav-content-wrap,\n.wy-nav-content {\n    background: transparent !important;\n}\n\n.wy-side-nav-search {\n    background-color: transparent !important;\n    color: var(--color-a) !important;\n    box-shadow: 0 4px 4px 0 var(--color-a);\n    border-bottom: 1px solid var(--color-d) !important;\n}\n\n.wy-side-nav-search svg {\n    color: var(--color-a) !important;\n}\n\n.wy-nav-top {\n    background-color: transparent !important;\n    color: var(--color-a) !important;\n}\n\n.wy-nav-top a {\n    color: var(--color-a) !important;\n}\n\n.wy-breadcrumbs a.icon-home:before {\n    content: \"Documentation\";\n    font-family: \"Overpass\", sans-serif;\n}\n\n.rst-content table.docutils thead {\n    color: var(--color-a);\n}\n\ncode.docutils.literal.notranslate {\n    padding: 2px 4px;\n    font-size: 0.875em;\n    font-family: \"Overpass Mono\", monospace;\n    background: var(--white);\n    color: var(--color-c);\n    border: 0px;\n}\n\ndt code.docutils.literal.notranslate {\n    background: none;\n}\n\n.wy-nav-content {\n    color: var(--color-a);\n}\n\n/* .rst-content a:not(:visited) { */\n/* color: var(--color-b) !important; */\n/* } */\n\n.rst-content a:visited {\n    color: var(--color-c) !important;\n}\n\n.rst-content a {\n    text-decoration: underline;\n}\n\n.rst-content a:where(:focus, :focus-visible, :hover) {\n    color: var(--color-d) !important;\n}\n\n.wy-side-scroll a {\n    color: var(--color-a);\n    background: transparent;\n    font-size: 1rem;\n    line-height: 125%;\n}\n\n.wy-menu-vertical li.current a,\n.wy-menu-vertical li.current li a,\n.wy-menu-vertical li.current li a code {\n    border: none;\n    color: var(--color-a);\n}\n\nul.current ul,\n.wy-menu-vertical li.current a:hover,\n.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,\n.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,\n.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,\n.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,\n.wy-menu-vertical li.current {\n    background: var(--menu-bg) !important;\n}\n\n.wy-menu.wy-menu-vertical>ul {\n    margin-bottom: 3rem;\n}\n\n.wy-menu.wy-menu-vertical>p {\n    color: var(--color-c);\n}\n\n.wy-menu-vertical li.on a,\n.wy-menu-vertical li.current>a {\n    background: var(--menu-bg) !important;\n    border-bottom: 0px !important;\n    border-top: 0px !important;\n}\n\n.btn {\n    border-radius: 0;\n    text-decoration: none !important;\n}\n\n.wy-breadcrumbs-aside a,\n.wy-breadcrumbs-aside a:visited,\na.fa.fa-github,\na.fa.fa-github:visited,\na.fa.fa-github:not(:visited),\na.btn.btn-neutral:visited,\na.btn.btn-neutral:not(:visited),\na.btn.btn-neutral {\n    background: transparent !important;\n    color: var(--color-a) !important;\n    border: 2px solid var(--color-a) !important;\n    text-decoration: none;\n}\n\n.rst-content .remix-link-container a.remix-link:hover,\n.wy-breadcrumbs-aside a:hover,\na.fa.fa-github:hover,\na.btn.btn-neutral:hover {\n    background: var(--white) !important;\n    color: var(--color-b) !important;\n    border-color: var(--color-b) !important;\n}\n\nfooter .rst-footer-buttons {\n    display: flex;\n    justify-content: center;\n    gap: 2rem;\n}\n\n/**\n * Customization for the unified layout\n */\n\n/* Site wrapper, and two children: header and rest */\n.unified-wrapper {\n    position: relative;\n    display: flex;\n    flex-direction: column;\n    inset: 0;\n    max-width: var(--maxWidth);\n    margin-inline: auto;\n}\n\n/* Site header */\n.unified-header {\n    position: fixed;\n    top: 0;\n    inset-inline: 0;\n    z-index: 99999;\n    display: flex;\n    align-items: center;\n    box-shadow: var(--shadow);\n}\n\n.unified-header .inner-header {\n    display: flex;\n    margin-inline: auto;\n    width: 100%;\n    max-width: var(--maxWidth);\n    align-items: center;\n    justify-content: space-between;\n    padding-inline: var(--desktopInlinePadding);\n    padding-block: 1rem;\n}\n\n.unified-header::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    opacity: 95%;\n    background: var(--color-f);\n    z-index: -1;\n    backdrop-filter: blur(3px);\n}\n\n.unified-header .home-link {\n    display: block;\n    text-decoration: none;\n    width: 25px;\n    height: 40px;\n}\n\n.unified-header .home-link:hover .solidity-logo {\n    transform: scale(1.1);\n    transition: transform 100ms ease-in-out;\n}\n\n.unified-header img.solidity-logo {\n    transform: scale(1);\n    transition: transform 100ms ease-in-out;\n    width: 100%;\n    height: 100%;\n}\n\n.unified-header .nav-bar {\n    display: flex;\n    align-items: center;\n    justify-content: flex-end;\n}\n\n.unified-header .nav-bar .nav-button-container {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 0.5rem;\n}\n\n.unified-header .nav-link {\n    display: inline-block;\n    padding-inline: 8px;\n    padding-block: 4px;\n    font-size: 14px;\n    font-family: 'Overpass Mono', monospace;\n    text-decoration: none;\n    color: var(--color-a);\n    letter-spacing: -0.02em;\n    font-weight: 400;\n    box-sizing: content-box;\n    border-bottom: 1px solid transparent;\n    white-space: nowrap;\n}\n\n.unified-header .nav-link.active {\n    background: var(--white);\n}\n\n.unified-header .nav-link:hover {\n    color: var(--color-c);\n    border-bottom: 1px solid var(--color-c);\n}\n\n/* Rest: Flex-row, with two children: side bar, and content */\n.unified-wrapper .wy-grid-for-nav {\n    position: relative !important;\n    display: flex;\n    margin-inline: auto;\n}\n\n/* First child: Side bar */\n.unified-wrapper .wy-grid-for-nav nav.wy-nav-side {\n    position: fixed;\n    display: flex;\n    flex-direction: column;\n    background: var(--color-f);\n    color: var(--color-a);\n    padding-bottom: unset !important;\n    z-index: 10 !important;\n    min-height: unset !important;\n    width: var(--sideWidth) !important;\n    top: var(--navHeight);\n    bottom: 0;\n    left: auto;\n    overflow: auto;\n}\n\n.unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll {\n    position: static !important;\n    width: unset !important;\n    overflow: unset !important;\n    height: unset !important;\n    padding-bottom: 2rem;\n}\n\n.unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll .wy-side-nav-search {\n    margin: 0 !important;\n    width: var(--sideWidth) !important;\n}\n\n.wy-nav-side,\n.wy-side-scroll,\n.wy-side-nav-search,\n.my-menu {\n    width: 100% !important;\n}\n\n.wy-nav-side input[type=text] {\n    font-family: \"Overpass\", sans-serif;\n    border-radius: 0;\n    border-color: var(--color-d);\n    background: var(--white);\n    box-shadow: none;\n    color: var(--color-a);\n}\n\n.wy-nav-side input[type=text]::placeholder {\n    font-family: \"Overpass\", sans-serif;\n    color: var(--color-e);\n    font-size: 16px;\n    position: relative;\n    top: 4px;\n}\n\n/* Second child: Content */\n.unified-wrapper .wy-grid-for-nav .wy-nav-content {\n    width: 100%;\n    max-width: unset !important; /* override */\n    padding-inline: var(--desktopInlinePadding);\n    margin-inline-start: var(--sideWidth);\n    margin-top: var(--navHeight);\n}\n\n.unified-wrapper .wy-grid-for-nav .wy-nav-content .rst-content {\n    max-width: min(70ch, calc(100vw -  2 * var(--desktopInlinePadding) - var(--sideWidth)));\n    margin-inline: auto;\n}\n\n.unified-wrapper.menu-open .backdrop {\n    opacity: 0.5;\n}\n\n.unified-wrapper .wy-nav-side,\n.unified-wrapper .rst-versions {\n    left: auto;\n\n}\n\n.unified-wrapper .backdrop {\n    opacity: 0;\n    transition: opacity 200ms ease-in-out;\n}\n\n@media (max-width: 768px) {\n    h2 {\n        margin-top: 3rem;\n        margin-bottom: 1rem;\n    }\n\n    h3 {\n        margin-top: 3rem;\n        margin-bottom: 1rem;\n    }\n\n    h4 {\n        margin-top: 2rem;\n        margin-bottom: 1rem;\n    }\n\n    /* Menu closed styles */\n    .unified-header .nav-link {\n        display: none;\n    }\n\n    .unified-header .inner-header {\n        padding-inline: var(--mobileInlinePadding);\n    }\n\n    .unified-wrapper .wy-grid-for-nav nav.wy-nav-side {\n        transform: translateX(-100%);\n        transition: transform 200ms ease-in-out;\n    }\n\n    /* Menu open styles */\n    .unified-wrapper.menu-open nav.wy-nav-side {\n        transform: translateX(0);\n        transition: transform 200ms ease-in-out;\n    }\n\n    .unified-wrapper.menu-open .rst-versions {\n        position: sticky;\n        bottom: 0;\n        width: 100%;\n    }\n\n    .unified-wrapper.menu-open .backdrop {\n        display: block;\n        position: fixed;\n        inset: 0;\n        opacity: 1;\n        transition: opacity 200ms ease-in-out;\n        z-index: 5;\n        background: #0006;\n    }\n\n    a.skip-to-content {\n        display: none;\n    }\n\n    .wy-nav-content {\n        margin-inline-start: 0 !important;\n    }\n\n    .rst-content {\n        max-width: 100% !important;\n    }\n\n    .wy-side-scroll {\n        padding-bottom: 0 !important;\n    }\n}\n\nul.search .context {\n    color: var(--color-a) !important;\n}\n\n.rst-versions {\n    background: var(--color-f);\n}\n\n.rst-versions.shift-up {\n    height: unset !important;\n    max-height: unset !important;\n    overflow-y: unset !important;\n}\n\n.rst-content dl:not(.docutils) dt {\n    color: var(--color-a);\n    background-color: #fff8;\n    border-top: solid 3px #0002;\n    border-inline-start: solid 3px #0002;\n    padding: 2px 6px;\n}\n\n.rst-versions .rst-current-version {\n    border-color: var(--color-d) !important;\n}\n\n.rst-current-version *,\n.rst-current-version .fa:before,\n.rst-current-version .fa-element {\n    color: var(--color-b) !important;\n}\n\n.rst-current-version dt,\n.rst-current-version dd,\n.rst-current-version dd a,\n.rst-other-versions dl:last-of-type dt,\n.rst-other-versions dl:last-of-type dd,\n.rst-other-versions dl:last-of-type dd a {\n    font-size: 14px !important;\n}\n\n.rst-other-versions {\n    background: var(--white) !important;\n    color: var(--color-a) !important;\n    max-height: calc(100vh - var(--navHeight) - var(--currentVersionHeight));\n    overflow-y: scroll;\n}\n\n.rst-other-versions a {\n    text-decoration: underline;\n    color: var(--color-c) !important;\n}\n\n.rst-other-versions dt {\n    color: var(--color-a) !important;\n}\n\n.rst-other-versions dl {\n    margin-bottom: 1.5rem !important;\n}\n\n.rst-other-versions dl:last-of-type {\n    margin-top: 2rem !important;\n}\n\n/* Bottom Search */\n.wy-nav-side input[type=text],\n.rst-other-versions dl:last-of-type dd {\n    width: 100%;\n}\n\n.rst-other-versions dl:last-of-type dt {\n    color: var(--color-b) !important;\n}\n\n.rst-other-versions dl:last-of-type div[style*=padding],\n.rst-other-versions dl dd:first-of-type a {\n    padding-inline-start: 0 !important;\n}\n\nbutton.toctree-expand {\n    color: var(--black) !important;\n}\n\n/* Light/dark color mode toggle 🌓 */\nbutton.color-toggle {\n    display: inline-flex;\n    appearance: none;\n    -webkit-box-align: center;\n    align-items: center;\n    -webkit-box-pack: center;\n    justify-content: center;\n    user-select: none;\n    outline: none;\n    height: 28px;\n    width: 28px;\n    background: none;\n    border: none;\n    padding: 6px;\n    margin: 6px;\n    transition-duration: 200ms;\n    transition-property: background-color,\n        color,\n        fill,\n        stroke,\n        opacity;\n}\n\nbutton.color-toggle:focus-visible {\n    outline: 2px solid var(--color-c);\n    color: var(--color-c);\n}\n\nbutton.color-toggle:hover {\n    color: var(--color-c);\n    background: #0002;\n}\n\nbutton.color-toggle .color-toggle-icon {\n    width: 100%;\n    height: 100%;\n    margin: 0;\n    display: inline-block;\n    line-height: 1em;\n    -webkit-flex-shrink: 0;\n    -ms-flex-negative: 0;\n    flex-shrink: 0;\n    vertical-align: middle;\n    /* color: var(--color-a); */\n}\n\n\nbutton.mobile-menu-button {\n    display: none;\n}\n\n@media (max-width: 768px) {\n    nav.wy-nav-top {\n        display: none;\n    }\n\n    button.mobile-menu-button {\n        display: flex;\n    }\n}\n\n\n.hidden {\n    display: none;\n}\n\n#search-results .search li:first-child,\n#search-results .search li {\n    border-color: var(--color-d);\n}\n\n#search-results .search li:last-child {\n    border: 0px;\n}\n\n.forum-link::after {\n    content: ' ↗';\n    font-size: 14px;\n    font-family: 'Overpass Mono', monospace;\n}\n\n.wy-breadcrumbs>li {\n    padding-top: 8px;\n}\n\n.wy-breadcrumbs-aside a {\n    padding: 0.5rem 0.75rem;\n    font-size: 12px;\n    font-family: \"'Overpass'\", sans-serif;\n    font-weight: 700;\n}\n\na.skip-to-content:visited,\na.skip-to-content:not(:visited),\na.skip-to-content {\n    display: block;\n    pointer-events: none;\n    width: fit-content;\n    opacity: 0;\n    transition: opacity 200ms ease-in-out;\n    padding: 2px 4px;\n    font-size: 14px;\n    margin-inline-end: auto;\n    margin-inline-start: 1.5rem;\n    color: var(--color-a);\n    white-space: nowrap;\n}\n\na.skip-to-content:focus {\n    opacity: 1;\n    transition: opacity 200ms ease-in-out;\n}\n\n#content {\n    scroll-margin-top: 6rem;\n    scroll-behavior: smooth;\n}\n"
  },
  {
    "path": "docs/_static/css/fonts.css",
    "content": "@import url(\"https://fonts.cdnfonts.com/css/overpass\");\n@import url(\"https://fonts.cdnfonts.com/css/overpass-mono\");"
  },
  {
    "path": "docs/_static/css/pygments.css",
    "content": "pre {\n  line-height: 125%;\n}\n\ntd.linenos .normal {\n  color: inherit;\n  background-color: transparent;\n  padding-left: 5px;\n  padding-right: 5px;\n}\n\nspan.linenos {\n  color: inherit;\n  background-color: transparent;\n  padding-left: 5px;\n  padding-right: 5px;\n}\n\ntd.linenos .special {\n  color: #000000;\n  background-color: #ffffc0;\n  padding-left: 5px;\n  padding-right: 5px;\n}\n\nspan.linenos.special {\n  color: #000000;\n  background-color: #ffffc0;\n  padding-left: 5px;\n  padding-right: 5px;\n}\n\n.highlight .hll {\n  background-color: #ffffcc\n}\n\n.highlight {\n  background: #eeffcc;\n}\n\n.highlight .c {\n  color: #408090;\n  font-style: italic\n}\n\n/* Comment */\n.highlight .err {\n  border: 1px solid #FF0000\n}\n\n/* Error */\n.highlight .k {\n  color: #007020;\n  font-weight: bold\n}\n\n/* Keyword */\n.highlight .o {\n  color: #666666\n}\n\n/* Operator */\n.highlight .ch {\n  color: #408090;\n  font-style: italic\n}\n\n/* Comment.Hashbang */\n.highlight .cm {\n  color: #408090;\n  font-style: italic\n}\n\n/* Comment.Multiline */\n.highlight .cp {\n  color: #007020\n}\n\n/* Comment.Preproc */\n.highlight .cpf {\n  color: #408090;\n  font-style: italic\n}\n\n/* Comment.PreprocFile */\n.highlight .c1 {\n  color: #408090;\n  font-style: italic\n}\n\n/* Comment.Single */\n.highlight .cs {\n  color: #408090;\n  background-color: #fff0f0\n}\n\n/* Comment.Special */\n.highlight .gd {\n  color: #A00000\n}\n\n/* Generic.Deleted */\n.highlight .ge {\n  font-style: italic\n}\n\n/* Generic.Emph */\n.highlight .gr {\n  color: #FF0000\n}\n\n/* Generic.Error */\n.highlight .gh {\n  color: #000080;\n  font-weight: bold\n}\n\n/* Generic.Heading */\n.highlight .gi {\n  color: #00A000\n}\n\n/* Generic.Inserted */\n.highlight .go {\n  color: #333333\n}\n\n/* Generic.Output */\n.highlight .gp {\n  color: #c65d09;\n  font-weight: bold\n}\n\n/* Generic.Prompt */\n.highlight .gs {\n  font-weight: bold\n}\n\n/* Generic.Strong */\n.highlight .gu {\n  color: #800080;\n  font-weight: bold\n}\n\n/* Generic.Subheading */\n.highlight .gt {\n  color: #0044DD\n}\n\n/* Generic.Traceback */\n.highlight .kc {\n  color: #007020;\n  font-weight: bold\n}\n\n/* Keyword.Constant */\n.highlight .kd {\n  color: #007020;\n  font-weight: bold\n}\n\n/* Keyword.Declaration */\n.highlight .kn {\n  color: #007020;\n  font-weight: bold\n}\n\n/* Keyword.Namespace */\n.highlight .kp {\n  color: #007020\n}\n\n/* Keyword.Pseudo */\n.highlight .kr {\n  color: #007020;\n  font-weight: bold\n}\n\n/* Keyword.Reserved */\n.highlight .kt {\n  color: #902000\n}\n\n/* Keyword.Type */\n.highlight .m {\n  color: #208050\n}\n\n/* Literal.Number */\n.highlight .s {\n  color: #4070a0\n}\n\n/* Literal.String */\n.highlight .na {\n  color: #4070a0\n}\n\n/* Name.Attribute */\n.highlight .nb {\n  color: #007020\n}\n\n/* Name.Builtin */\n.highlight .nc {\n  color: #0e84b5;\n  font-weight: bold\n}\n\n/* Name.Class */\n.highlight .no {\n  color: #60add5\n}\n\n/* Name.Constant */\n.highlight .nd {\n  color: #555555;\n  font-weight: bold\n}\n\n/* Name.Decorator */\n.highlight .ni {\n  color: #d55537;\n  font-weight: bold\n}\n\n/* Name.Entity */\n.highlight .ne {\n  color: #007020\n}\n\n/* Name.Exception */\n.highlight .nf {\n  color: #06287e\n}\n\n/* Name.Function */\n.highlight .nl {\n  color: #002070;\n  font-weight: bold\n}\n\n/* Name.Label */\n.highlight .nn {\n  color: #0e84b5;\n  font-weight: bold\n}\n\n/* Name.Namespace */\n.highlight .nt {\n  color: #062873;\n  font-weight: bold\n}\n\n/* Name.Tag */\n.highlight .nv {\n  color: #bb60d5\n}\n\n/* Name.Variable */\n.highlight .ow {\n  color: #007020;\n  font-weight: bold\n}\n\n/* Operator.Word */\n.highlight .w {\n  color: #bbbbbb\n}\n\n/* Text.Whitespace */\n.highlight .mb {\n  color: #208050\n}\n\n/* Literal.Number.Bin */\n.highlight .mf {\n  color: #208050\n}\n\n/* Literal.Number.Float */\n.highlight .mh {\n  color: #208050\n}\n\n/* Literal.Number.Hex */\n.highlight .mi {\n  color: #208050\n}\n\n/* Literal.Number.Integer */\n.highlight .mo {\n  color: #208050\n}\n\n/* Literal.Number.Oct */\n.highlight .sa {\n  color: #4070a0\n}\n\n/* Literal.String.Affix */\n.highlight .sb {\n  color: #4070a0\n}\n\n/* Literal.String.Backtick */\n.highlight .sc {\n  color: #4070a0\n}\n\n/* Literal.String.Char */\n.highlight .dl {\n  color: #4070a0\n}\n\n/* Literal.String.Delimiter */\n.highlight .sd {\n  color: #4070a0;\n  font-style: italic\n}\n\n/* Literal.String.Doc */\n.highlight .s2 {\n  color: #4070a0\n}\n\n/* Literal.String.Double */\n.highlight .se {\n  color: #4070a0;\n  font-weight: bold\n}\n\n/* Literal.String.Escape */\n.highlight .sh {\n  color: #4070a0\n}\n\n/* Literal.String.Heredoc */\n.highlight .si {\n  color: #70a0d0;\n  font-style: italic\n}\n\n/* Literal.String.Interpol */\n.highlight .sx {\n  color: #c65d09\n}\n\n/* Literal.String.Other */\n.highlight .sr {\n  color: #235388\n}\n\n/* Literal.String.Regex */\n.highlight .s1 {\n  color: #4070a0\n}\n\n/* Literal.String.Single */\n.highlight .ss {\n  color: #517918\n}\n\n/* Literal.String.Symbol */\n.highlight .bp {\n  color: #007020\n}\n\n/* Name.Builtin.Pseudo */\n.highlight .fm {\n  color: #06287e\n}\n\n/* Name.Function.Magic */\n.highlight .vc {\n  color: #bb60d5\n}\n\n/* Name.Variable.Class */\n.highlight .vg {\n  color: #bb60d5\n}\n\n/* Name.Variable.Global */\n.highlight .vi {\n  color: #bb60d5\n}\n\n/* Name.Variable.Instance */\n.highlight .vm {\n  color: #bb60d5\n}\n\n/* Name.Variable.Magic */\n.highlight .il {\n  color: #208050\n}\n\n/* Literal.Number.Integer.Long */"
  },
  {
    "path": "docs/_static/css/toggle.css",
    "content": "input[type=checkbox] {\n    visibility: hidden;\n    height: 0;\n    width: 0;\n    margin: 0;\n}\n\n.rst-versions .rst-current-version {\n    padding: 10px;\n    display: flex;\n    justify-content: space-between;\n    background-color: var(--color-f);\n    border-top: 1px solid var(--color-c);\n}\n\n.fa-caret-down,\n.fa-book {\n    color: var(--color-a) !important;\n}\n\n.rst-versions .rst-current-version .fa-book,\n.rst-versions .rst-current-version .fa-v,\n.rst-versions .rst-current-version .fa-caret-down {\n    height: 24px;\n    line-height: 24px;\n    vertical-align: middle;\n}\n\n.rst-versions .rst-current-version .fa-element {\n    width: 80px;\n    text-align: center;\n}\n\n.rst-versions .rst-current-version .fa-book {\n    text-align: left;\n}\n\n.rst-versions .rst-current-version .fa-v {\n    color: #27AE60;\n    text-align: right;\n}\n\nlabel {\n    margin: 0 auto;\n    display: inline-block;\n    justify-content: center;\n    align-items: right;\n    border-radius: 100px;\n    position: relative;\n    cursor: pointer;\n    text-indent: -9999px;\n    width: 50px;\n    height: 21px;\n    background: #000;\n}\n\nlabel:after {\n    border-radius: 50%;\n    position: absolute;\n    content: '';\n    background: #fff;\n    width: 15px;\n    height: 15px;\n    top: 3px;\n    left: 3px;\n    transition: ease-in-out 200ms;\n}\n\ninput:checked+label {\n    background: #3a7ca8;\n}\n\ninput:checked+label:after {\n    left: calc(100% - 5px);\n    transform: translateX(-100%);\n}\n\nhtml.transition,\nhtml.transition *,\nhtml.transition *:before,\nhtml.transition *:after {\n    transition: ease-in-out 200ms !important;\n    transition-delay: 0 !important;\n}\n\n.wy-menu-vertical a:hover {\n    background-color: #0002;\n}\n\nbody {\n    font-weight: 300;\n    letter-spacing: 0.5px;\n}"
  },
  {
    "path": "docs/_static/js/constants.js",
    "content": "// Site URL\nconst SITE_URL = \"https://docs.soliditylang.org\"\nconst { origin, pathname } = location;\nconst pathSplit = pathname.split(\"/\");\nconst rootPath = origin.includes(SITE_URL) && pathSplit.length > 3 ? pathSplit.splice(1, 2).join(\"/\") : ''\nconst ROOT_URL = `${origin}/${rootPath}`;\n\n// Color mode constants\nconst [DARK, LIGHT] = [\"dark\", \"light\"];\nconst LIGHT_LOGO_PATH = `${ROOT_URL}/_static/img/logo.svg`;\nconst DARK_LOGO_PATH = `${ROOT_URL}/_static/img/logo-dark.svg`;\nconst SUN_ICON_PATH = `${ROOT_URL}/_static/img/sun.svg`;\nconst MOON_ICON_PATH = `${ROOT_URL}/_static/img/moon.svg`;\nconst LIGHT_HAMBURGER_PATH = `${ROOT_URL}/_static/img/hamburger-light.svg`;\nconst DARK_HAMBURGER_PATH = `${ROOT_URL}/_static/img/hamburger-dark.svg`;\nconst COLOR_TOGGLE_ICON_CLASS = \"color-toggle-icon\";\nconst SOLIDITY_LOGO_CLASS = \"solidity-logo\";\nconst LS_COLOR_SCHEME = \"color-scheme\";\n\n// Solidity navigation constants\nconst SOLIDITY_HOME_URL = \"https://soliditylang.org\";\nconst BLOG_URL = `${SOLIDITY_HOME_URL}/blog`;\nconst DOCS_URL = \"/\";\nconst USE_CASES_PATH = `${SOLIDITY_HOME_URL}/use-cases`;\nconst CONTRIBUTE_PATH = `/en/latest/contributing.html`;\nconst ABOUT_PATH = `${SOLIDITY_HOME_URL}/about`;\nconst FORUM_URL = \"https://forum.soliditylang.org/\";\nconst NAV_LINKS = [\n  { name: window.NAV_LINKS.blog, href: BLOG_URL },\n  { name: window.NAV_LINKS.documentation, href: DOCS_URL },\n  { name: window.NAV_LINKS.use_cases, href: USE_CASES_PATH },\n  { name: window.NAV_LINKS.contribute, href: CONTRIBUTE_PATH },\n  { name: window.NAV_LINKS.about, href: ABOUT_PATH },\n  { name: window.NAV_LINKS.forum, href: FORUM_URL },\n];\n\nconst MOBILE_MENU_TOGGLE_CLASS = \"shift\";\nconst WRAPPER_CLASS = \"unified-wrapper\";\n"
  },
  {
    "path": "docs/_static/js/initialize.js",
    "content": "const getLogoSrc = (isDark) => (isDark ? DARK_LOGO_PATH : LIGHT_LOGO_PATH);\n\nconst getModeIconSrc = (isDark) => (isDark ? SUN_ICON_PATH : MOON_ICON_PATH);\n\nconst getMenuIconSrc = (isDark) =>\n  isDark ? DARK_HAMBURGER_PATH : LIGHT_HAMBURGER_PATH;\n\nfunction addFooterNote() {\n  const contentInfo = document.querySelector(\"div[role=contentinfo]\");\n  const footerNote = document.createElement(\"p\");\n  footerNote.classList.add(\"footer-note\");\n  footerNote.innerHTML =\n    'Customized with ❤️ by the <a href=\"https://ethereum.org/\" target=\"_blank\">ethereum.org</a> team.';\n  contentInfo.parentNode.insertBefore(footerNote, contentInfo.nextSibling);\n}\n\nfunction rearrangeDom() {\n  const bodyDivs = document.querySelectorAll(\"body>div\");\n  bodyDivs.forEach((div) => div.remove());\n  const wrapperDiv = document.createElement(\"div\");\n  wrapperDiv.classList.add(WRAPPER_CLASS);\n  bodyDivs.forEach((div) => wrapperDiv.appendChild(div));\n  document.body.prepend(wrapperDiv);\n\n  const rstVersions = document.querySelector(\".rst-versions\");\n  const wyNavSide = document.querySelector(\"nav.wy-nav-side\");\n  // NOTE: Since RTD migration to addons, `.rst-versions` is no longer present in the DOM.\n  // The following code is kept for compatibility with older versions.\n  // See: https://github.com/readthedocs/readthedocs.org/issues/11474\n  if (rstVersions && wyNavSide) {\n    rstVersions.remove();\n    wyNavSide.appendChild(rstVersions);\n  }\n  const backdrop = document.createElement(\"div\");\n  backdrop.classList.add(\"backdrop\");\n  wrapperDiv.appendChild(backdrop);\n\n  const content = document.querySelector(\".wy-nav-content\");\n  if (content) {\n    content.id = \"content\";\n    document.querySelector(\"section.wy-nav-content-wrap\")?.remove();\n    document.querySelector(\".wy-grid-for-nav\")?.appendChild(content);\n  }\n}\n\nfunction buildHeader() {\n  const isDarkMode = localStorage.getItem(LS_COLOR_SCHEME) == DARK;\n\n  const header = document.createElement(\"div\");\n  header.classList.add(\"unified-header\");\n  document.querySelector(`.${WRAPPER_CLASS}`).prepend(header);\n\n  const innerHeader = document.createElement(\"div\");\n  innerHeader.classList.add(\"inner-header\");\n  header.appendChild(innerHeader);\n\n  const homeLink = document.createElement(\"a\");\n  homeLink.classList.add(\"home-link\");\n  homeLink.href = SOLIDITY_HOME_URL;\n  homeLink.ariaLabel = \"Solidity home\";\n  innerHeader.appendChild(homeLink);\n\n  const logo = document.createElement(\"img\");\n  logo.classList.add(SOLIDITY_LOGO_CLASS);\n  logo.src = getLogoSrc(isDarkMode);\n  logo.alt = \"Solidity logo\";\n  homeLink.appendChild(logo);\n\n  const skipToContent = document.createElement(\"a\");\n  skipToContent.classList.add(\"skip-to-content\");\n  skipToContent.href = \"#content\";\n  skipToContent.innerText = \"{skip to content}\";\n  innerHeader.appendChild(skipToContent);\n\n  const navBar = document.createElement(\"nav\");\n  navBar.classList.add(\"nav-bar\");\n  innerHeader.appendChild(navBar);\n\n  const linkElements = NAV_LINKS.map(({ name, href }) => {\n    const link = document.createElement(\"a\");\n    link.classList.add(\"nav-link\");\n    link.setAttribute(\"key\", name);\n    link.setAttribute(\"href\", href);\n    link.setAttribute(\"aria-label\", name);\n    if (href === FORUM_URL) {\n      link.classList.add(\"forum-link\");\n      link.setAttribute(\"target\", \"_blank\");\n      link.setAttribute(\"rel\", \"noopener noreferrer\");\n    }\n    link.innerText = name;\n    return link;\n  });\n  linkElements.forEach((link) => navBar.appendChild(link));\n\n  // Flex wrapper for color mode and mobile menu buttons\n  const navButtonContainer = document.createElement(\"div\");\n  navButtonContainer.classList.add(\"nav-button-container\");\n  navBar.appendChild(navButtonContainer);\n\n  // Build color toggle\n  const toggleIcon = document.createElement(\"img\");\n  toggleIcon.classList.add(COLOR_TOGGLE_ICON_CLASS);\n  toggleIcon.src = getModeIconSrc(isDarkMode);\n  toggleIcon.alt = \"Color mode toggle icon\";\n  toggleIcon.setAttribute(\"aria-hidden\", \"true\");\n  toggleIcon.setAttribute(\"key\", \"toggle icon\");\n  const colorModeButton = document.createElement(\"button\");\n  colorModeButton.classList.add(\"color-toggle\");\n  colorModeButton.setAttribute(\"type\", \"button\");\n  colorModeButton.setAttribute(\"aria-label\", \"Toggle light dark mode\");\n  colorModeButton.setAttribute(\"key\", \"color mode button\");\n  colorModeButton.addEventListener(\"click\", toggleColorMode);\n  colorModeButton.appendChild(toggleIcon);\n  navButtonContainer.appendChild(colorModeButton);\n\n  // Build mobile hamburger menu\n  const menuIcon = document.createElement(\"img\");\n  menuIcon.classList.add(COLOR_TOGGLE_ICON_CLASS);\n  menuIcon.src = getMenuIconSrc(isDarkMode);\n  menuIcon.alt = \"Toggle menu\";\n  menuIcon.setAttribute(\"aria-hidden\", \"true\");\n  menuIcon.setAttribute(\"key\", \"menu icon\");\n  const menuButton = document.createElement(\"button\");\n  menuButton.classList.add(\"color-toggle\");\n  menuButton.classList.add(\"mobile-menu-button\");\n  menuButton.setAttribute(\"type\", \"button\");\n  menuButton.setAttribute(\"aria-label\", \"Toggle menu\");\n  menuButton.setAttribute(\"key\", \"menu button\");\n  menuButton.addEventListener(\"click\", toggleMenu);\n  menuButton.appendChild(menuIcon);\n  navButtonContainer.appendChild(menuButton);\n}\n\nconst updateActiveNavLink = () => {\n  const navLinks = document.querySelectorAll(\".unified-header .nav-link\");\n  navLinks.forEach((link) => {\n    const href = link.getAttribute(\"href\");\n    if (document.documentURI.includes(\"contributing.html\")) {\n      link.classList[href.includes(\"contributing.html\") ? \"add\" : \"remove\"](\n        \"active\"\n      );\n    } else {\n      link.classList[document.documentURI.includes(href) ? \"add\" : \"remove\"](\n        \"active\"\n      );\n    }\n  });\n};\n\ndocument.addEventListener(\"locationchange\", updateActiveNavLink);\n\nfunction updateGitHubEditPath() {\n  // Replaces the version number in the GitHub edit path with \"develop\" if it exists.\n  // This is to ensure that the edit path always points to the `develop` branch instead of the specific version branch.\n  // Note that it will fail silently if the anchor element is not found, i.e. the page is not editable or\n  // if the sphinx_rtd_theme is updated to a version that changes the anchor element.\n  // See: https://github.com/readthedocs/sphinx_rtd_theme/blob/a1c2147b17cbf0e57b7d7a6450ad4d9a5ff362cf/sphinx_rtd_theme/breadcrumbs.html#L35\n  // TODO: We should consider a more robust way to handle this in the future.\n  const gitHubEditAnchor = document.querySelector(\".wy-breadcrumbs-aside > a\");\n  if (!gitHubEditAnchor) return;\n\n  const url = new URL(gitHubEditAnchor.href);\n  const split = url.pathname.split(\"/\");\n  const versionIndex = split.indexOf(\"blob\") + 1;\n  split[versionIndex] = \"develop\";\n  url.pathname = split.join(\"/\");\n  gitHubEditAnchor.setAttribute(\"href\", url.toString());\n  gitHubEditAnchor.setAttribute(\"target\", \"_blank\");\n  gitHubEditAnchor.setAttribute(\"rel\", \"noopener noreferrer\");\n}\n\nfunction initialize() {\n  // Rearrange DOM elements for styling\n  rearrangeDom();\n\n  // Check localStorage for existing color scheme preference\n  var prefersDark = localStorage.getItem(LS_COLOR_SCHEME) == DARK;\n  // Check link for search param \"color\"... it may be \"light\" or \"dark\"\n  var urlParams = new URLSearchParams(window.location.search);\n  if (urlParams.size > 0) {\n    // This is used for color mode continuity between the main Solidity Lang site and the docs\n    var colorSchemeParam = urlParams.get(\"color\");\n    // If present, overwrite prefersDark accordingly\n    if (colorSchemeParam) {\n      prefersDark = colorSchemeParam == DARK;\n    }\n\n    // Remove \"color\" search param from URL\n    const { location, title } = document;\n    const { pathname, origin, search, hash } = location;\n    const newSearchParams = new URLSearchParams(search);\n    newSearchParams.delete(\"color\");\n    const sanitizedSearch =\n      newSearchParams.size < 1 ? \"\" : \"?\" + newSearchParams.toString();\n    window.history.replaceState(\n      origin,\n      title,\n      pathname + sanitizedSearch + hash\n    );\n  }\n\n  // In case none existed, establish localStorage color scheme preference\n  var mode = prefersDark ? DARK : LIGHT;\n  localStorage.setItem(LS_COLOR_SCHEME, mode);\n\n  // Select the root element and set the style attribute to denote color-scheme attribute\n  document\n    .querySelector(\":root\")\n    .setAttribute(\"style\", `--color-scheme: ${mode}`);\n\n  // NOTE: Since RTD migration to addons, the elements below are no longer present in the DOM.\n  // The following code is kept for compatibility with older versions.\n  // Remove old input and RTD logo anchor element\n  document.querySelector(\"input[name=mode]\")?.remove();\n  document.querySelector(\"label[for=switch]\")?.remove();\n  document.querySelector(\".wy-side-nav-search > a\")?.remove();\n\n  // Add footer note\n  addFooterNote();\n\n  // Build header\n  buildHeader();\n\n  // Close menu\n  toggleMenu({ force: false });\n\n  // Update active nav link\n  updateActiveNavLink();\n\n  // Update GitHub edit path to direct to `develop` branch\n  updateGitHubEditPath();\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", initialize);\n\nconst handleClick = (e) => {\n  if (e.target.closest(\".backdrop\")) {\n    toggleMenu({ force: false });\n  }\n\n  if (e.target.closest(\"a\")) {\n    const target = e.target.closest(\"a\");\n    const href = target.getAttribute(\"href\");\n    if (href.includes(SOLIDITY_HOME_URL)) {\n      const url = new URL(href);\n      const params = new URLSearchParams(url.search);\n      params.set(\"color\", localStorage.getItem(LS_COLOR_SCHEME));\n      url.search = params.toString();\n      target.setAttribute(\"href\", url.toString());\n    }\n  }\n};\ndocument.addEventListener(\"click\", handleClick);\n\nconst handleKeyDown = (e) => {\n  if (e.metaKey && e.key === \"k\") {\n    document.querySelector(\"#rtd-search-form input\")?.focus();\n  } else if (e.key === \"Escape\") {\n    toggleMenu({ force: false });\n  }\n  if (e.metaKey && e.code === \"Backslash\") {\n    toggleColorMode();\n  }\n};\ndocument.addEventListener(\"keydown\", handleKeyDown);\n"
  },
  {
    "path": "docs/_static/js/toggle.js",
    "content": "function toggleColorMode() {\n  // Check localStorage for previous color scheme preference, assign the opposite\n  var newMode = localStorage.getItem(LS_COLOR_SCHEME) == DARK ? LIGHT : DARK;\n\n  // Update localStorage with new color scheme preference\n  localStorage.setItem(LS_COLOR_SCHEME, newMode);\n\n  // Update the root element with the new color scheme preference\n  document\n    .querySelector(\":root\")\n    .setAttribute(\"style\", `--color-scheme: ${newMode}`);\n\n  // Update logo\n  document\n    .querySelector(`img.${SOLIDITY_LOGO_CLASS}`)\n    .setAttribute(\"src\", newMode === LIGHT ? LIGHT_LOGO_PATH : DARK_LOGO_PATH);\n\n  // Update color mode toggle icon\n  document\n    .querySelector(`img.${COLOR_TOGGLE_ICON_CLASS}`)\n    .setAttribute(\"src\", newMode === LIGHT ? MOON_ICON_PATH : SUN_ICON_PATH);\n\n  // Update hamburger menu icon color\n  document\n    .querySelector(\"button.mobile-menu-button img\")\n    .setAttribute(\n      \"src\",\n      newMode === LIGHT ? LIGHT_HAMBURGER_PATH : DARK_HAMBURGER_PATH\n    );\n}\n\nfunction toggleMenu(options = {}) {\n  const handleClassToggle = ({ classList }, className) => {\n    if (typeof options.force !== \"undefined\") {\n      classList.toggle(className, options.force);\n    } else {\n      classList.toggle(className);\n    }\n  };\n  document\n    .querySelectorAll('[data-toggle=\"rst-versions\"]')\n    .forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS));\n  document\n    .querySelectorAll('[data-toggle=\"wy-nav-shift\"]')\n    .forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS));\n  handleClassToggle(document.querySelector(`.${WRAPPER_CLASS}`), \"menu-open\");\n}\n"
  },
  {
    "path": "docs/_templates/footer.html",
    "content": "{% extends \"!footer.html\" %}\n\n{% block extrafooter %}\n    <p>\n        <a href=\"{{ pathto('credits-and-attribution') }}\">Credits and attribution</a>.\n    </p>\n{% endblock %}\n"
  },
  {
    "path": "docs/_templates/layout.html",
    "content": "{% extends \"!layout.html\" %}\n\n{% block scripts %}\n    <script>\n        window.NAV_LINKS = {\n            blog: \"{{ _('Blog') }}\",\n            documentation: \"{{ _('Documentation') }}\",\n            use_cases: \"{{ _('Use cases') }}\",\n            contribute: \"{{ _('Contribute') }}\",\n            about: \"{{ _('About') }}\",\n            forum: \"{{ _('Forum') }}\"\n        };\n    </script>\n    {{ super() }}\n{% endblock %}\n\n{% block menu %}\n    {{ super() }}\n    <ul>\n        <li>\n            <a href=\"{{ pathto('genindex') }}\">Keyword Index</a>\n        </li>\n    </ul>\n{% endblock %}\n"
  },
  {
    "path": "docs/_templates/versions.html",
    "content": "{# Add rst-badge after rst-versions for small badge style. #}\n<div class=\"rst-versions\" data-toggle=\"rst-versions\" role=\"note\" aria-label=\"versions\">\n    <span class=\"rst-current-version\" data-toggle=\"rst-current-version\">\n    <span class=\"fa fa-book fa-element\"> RTD </span>\n\n    <span class=\"fa fa-element\">\n    <input class=\"container_toggle\" type=\"checkbox\" id=\"switch\" name=\"mode\">\n    <label for=\"switch\"></label>\n    </span>\n\n    <span class=\"fa fa-v fa-element\"> v: {{ current_version }} <span class=\"fa fa-caret-down\"></span></span>\n\n    </span>\n    <div class=\"rst-other-versions\">\n        <dl>\n            <dt>{{ _('Downloads') }}</dt> {% for type, url in downloads %}\n            <dd><a href=\"{{ url }}\">{{ type }}</a></dd>\n            {% endfor %}\n        </dl>\n        <dl>\n            <dt>{{ _('Versions') }}</dt> {% for slug, url in versions %}\n            <dd><a href=\"{{ url }}\">{{ slug }}</a></dd>\n            {% endfor %}\n        </dl>\n        <dl>\n            {# Translators: The phrase \"Read the Docs\" is not translated #}\n            <dt>{{ _('On Read the Docs') }}</dt>\n            <dd>\n                <a href=\"//{{ PRODUCTION_DOMAIN }}/projects/{{ slug }}/?fromdocs={{ slug }}\">{{ _('Project Home') }}</a>\n            </dd>\n            <dd>\n                <a href=\"//{{ PRODUCTION_DOMAIN }}/builds/{{ slug }}/?fromdocs={{ slug }}\">{{ _('Builds') }}</a>\n            </dd>\n        </dl>\n    </div>\n</div>\n"
  },
  {
    "path": "docs/abi-spec.rst",
    "content": ".. index:: abi, application binary interface\n\n.. _ABI:\n\n**************************\nContract ABI Specification\n**************************\n\nBasic Design\n============\n\nThe Contract Application Binary Interface (ABI) is the standard way to interact with contracts in the Ethereum ecosystem, both\nfrom outside the blockchain and for contract-to-contract interaction. Data is encoded according to its type,\nas described in this specification. The encoding is not self describing and thus requires a schema in order to decode.\n\nWe assume that the interface functions of a contract are strongly typed, known at compilation time and static.\nWe assume that all contracts will have the interface definitions of any contracts they call available at compile-time.\n\nThis specification does not address contracts whose interface is dynamic or otherwise known only at run-time. Also, the ABI specification for libraries is :ref:`slightly different <library-selectors>`.\n\n.. _abi_function_selector:\n.. index:: ! selector; of a function\n\nFunction Selector\n=================\n\nThe first four bytes of the call data for a function call specifies the function to be called. It is the\nfirst (left, high-order in big-endian) four bytes of the Keccak-256 hash of the signature of\nthe function. The signature is defined as the canonical expression of the basic prototype without data\nlocation specifier, i.e.\nthe function name with the parenthesised list of parameter types. Parameter types are split by a single\ncomma — no spaces are used.\n\n.. note::\n    The return type of a function is not part of this signature. In\n    :ref:`Solidity's function overloading <overload-function>` return types are not considered.\n    The reason is to keep function call resolution context-independent.\n    The :ref:`JSON description of the ABI<abi_json>` however contains both inputs and outputs.\n\nArgument Encoding\n=================\n\nStarting from the fifth byte, the encoded arguments follow. This encoding is also used in\nother places, e.g. the return values and also event arguments are encoded in the same way,\nwithout the four bytes specifying the function.\n\nTypes\n=====\n\nNote that the library ABIs can take types different than below e.g. for non-storage structs. See :ref:`library selectors <library-selectors>` for details.\n\nThe following elementary types exist:\n\n- ``uint<M>``: unsigned integer type of ``M`` bits, ``0 < M <= 256``, ``M % 8 == 0``. e.g. ``uint32``, ``uint8``, ``uint256``.\n\n- ``int<M>``: two's complement signed integer type of ``M`` bits, ``0 < M <= 256``, ``M % 8 == 0``.\n\n- ``address``: equivalent to ``uint160``, except for the assumed interpretation and language typing.\n  For computing the function selector, ``address`` is used.\n\n- ``uint``, ``int``: synonyms for ``uint256``, ``int256`` respectively. For computing the function\n  selector, ``uint256`` and ``int256`` have to be used.\n\n- ``bool``: equivalent to ``uint8`` restricted to the values 0 and 1. For computing the function selector, ``bool`` is used.\n\n- ``fixed<M>x<N>``: signed fixed-point decimal number of ``M`` bits, ``8 <= M <= 256``,\n  ``M % 8 == 0``, and ``0 < N <= 80``, which denotes the value ``v`` as ``v / (10 ** N)``.\n\n- ``ufixed<M>x<N>``: unsigned variant of ``fixed<M>x<N>``.\n\n- ``fixed``, ``ufixed``: synonyms for ``fixed128x18``, ``ufixed128x18`` respectively. For\n  computing the function selector, ``fixed128x18`` and ``ufixed128x18`` have to be used.\n\n- ``bytes<M>``: binary type of ``M`` bytes, ``0 < M <= 32``.\n\n- ``function``: an address (20 bytes) followed by a function selector (4 bytes). Encoded identical to ``bytes24``.\n\nThe following (fixed-size) array type exists:\n\n- ``<type>[M]``: a fixed-length array of ``M`` elements, ``M >= 0``, of the given type.\n\n  .. note::\n\n      While this ABI specification can express fixed-length arrays with zero elements, they're not supported by the compiler.\n\nThe following non-fixed-size types exist:\n\n- ``bytes``: dynamic sized byte sequence.\n\n- ``string``: dynamic sized unicode string assumed to be UTF-8 encoded.\n\n- ``<type>[]``: a variable-length array of elements of the given type.\n\nTypes can be combined to a tuple by enclosing them inside parentheses, separated by commas:\n\n- ``(T1,T2,...,Tn)``: tuple consisting of the types ``T1``, ..., ``Tn``, ``n >= 0``\n\nIt is possible to form tuples of tuples, arrays of tuples and so on. It is also possible to form zero-tuples (where ``n == 0``).\n\nMapping Solidity to ABI types\n-----------------------------\n\nSolidity supports all the types presented above with the same names with the\nexception of tuples. On the other hand, some Solidity types are not supported\nby the ABI. The following table shows on the left column Solidity types that\nare not part of the ABI, and on the right column the ABI types that represent\nthem.\n\n+-------------------------------+-----------------------------------------------------------------------------+\n|      Solidity                 |                                           ABI                               |\n+===============================+=============================================================================+\n|:ref:`address payable<address>`|``address``                                                                  |\n+-------------------------------+-----------------------------------------------------------------------------+\n|:ref:`contract<contracts>`     |``address``                                                                  |\n+-------------------------------+-----------------------------------------------------------------------------+\n|:ref:`enum<enums>`             |``uint8``                                                                    |\n+-------------------------------+-----------------------------------------------------------------------------+\n|:ref:`user defined value types |its underlying value type                                                    |\n|<user-defined-value-types>`    |                                                                             |\n+-------------------------------+-----------------------------------------------------------------------------+\n|:ref:`struct<structs>`         |``tuple``                                                                    |\n+-------------------------------+-----------------------------------------------------------------------------+\n\n.. warning::\n    Before version ``0.8.0`` enums could have more than 256 members and were represented by the\n    smallest integer type just big enough to hold the value of any member.\n\nDesign Criteria for the Encoding\n================================\n\nThe encoding is designed to have the following properties, which are especially useful if some arguments are nested arrays:\n\n1. The number of reads necessary to access a value is at most the depth of the value\n   inside the argument array structure, i.e. four reads are needed to retrieve ``a_i[k][l][r]``. In a\n   previous version of the ABI, the number of reads scaled linearly with the total number of dynamic\n   parameters in the worst case.\n\n2. The data of a variable or an array element is not interleaved with other data and it is\n   relocatable, i.e. it only uses relative \"addresses\".\n\n\nFormal Specification of the Encoding\n====================================\n\nWe distinguish static and dynamic types. Static types are encoded in-place and dynamic types are\nencoded at a separately allocated location after the current block.\n\n**Definition:** The following types are called \"dynamic\":\n\n* ``bytes``\n* ``string``\n* ``T[]`` for any ``T``\n* ``T[k]`` for any dynamic ``T`` and any ``k >= 0``\n* ``(T1,...,Tk)`` if ``Ti`` is dynamic for some ``1 <= i <= k``\n\nAll other types are called \"static\".\n\n**Definition:** ``len(a)`` is the number of bytes in a binary string ``a``.\nThe type of ``len(a)`` is assumed to be ``uint256``.\n\nWe define ``enc``, the actual encoding, as a mapping of values of the ABI types to binary strings such\nthat ``len(enc(X))`` depends on the value of ``X`` if and only if the type of ``X`` is dynamic.\n\n**Definition:** For any ABI value ``X``, we recursively define ``enc(X)``, depending\non the type of ``X`` being\n\n- ``(T1,...,Tk)`` for ``k >= 0`` and any types ``T1``, ..., ``Tk``\n\n  ``enc(X) = head(X(1)) ... head(X(k)) tail(X(1)) ... tail(X(k))``\n\n  where ``X = (X(1), ..., X(k))`` and\n  ``head`` and ``tail`` are defined for ``Ti`` as follows:\n\n  if ``Ti`` is static:\n\n    ``head(X(i)) = enc(X(i))`` and ``tail(X(i)) = \"\"`` (the empty string)\n\n  otherwise, i.e. if ``Ti`` is dynamic:\n\n    ``head(X(i)) = enc(len( head(X(1)) ... head(X(k)) tail(X(1)) ... tail(X(i-1)) ))``\n    ``tail(X(i)) = enc(X(i))``\n\n  Note that in the dynamic case, ``head(X(i))`` is well-defined since the lengths of\n  the head parts only depend on the types and not the values. The value of ``head(X(i))`` is the offset\n  of the beginning of ``tail(X(i))`` relative to the start of ``enc(X)``.\n\n- ``T[k]`` for any ``T`` and ``k``:\n\n  ``enc(X) = enc((X[0], ..., X[k-1]))``\n\n  i.e. it is encoded as if it were a tuple with ``k`` elements\n  of the same type.\n\n- ``T[]`` where ``X`` has ``k`` elements (``k`` is assumed to be of type ``uint256``):\n\n  ``enc(X) = enc(k) enc((X[0], ..., X[k-1]))``\n\n  i.e. it is encoded as if it were a tuple with ``k`` elements of the same type (resp. an array of static size ``k``), prefixed with\n  the number of elements.\n\n- ``bytes``, of length ``k`` (which is assumed to be of type ``uint256``):\n\n  ``enc(X) = enc(k) pad_right(X)``, i.e. the number of bytes is encoded as a\n  ``uint256`` followed by the actual value of ``X`` as a byte sequence, followed by\n  the minimum number of zero-bytes such that ``len(enc(X))`` is a multiple of 32.\n\n- ``string``:\n\n  ``enc(X) = enc(enc_utf8(X))``, i.e. ``X`` is UTF-8 encoded and this value is interpreted\n  as of ``bytes`` type and encoded further. Note that the length used in this subsequent\n  encoding is the number of bytes of the UTF-8 encoded string, not its number of characters.\n\n- ``uint<M>``: ``enc(X)`` is the big-endian encoding of ``X``, padded on the higher-order\n  (left) side with zero-bytes such that the length is 32 bytes.\n- ``address``: as in the ``uint160`` case\n- ``int<M>``: ``enc(X)`` is the big-endian two's complement encoding of ``X``, padded on the higher-order (left) side with ``0xff`` bytes for negative ``X`` and with zero-bytes for non-negative ``X`` such that the length is 32 bytes.\n- ``bool``: as in the ``uint8`` case, where ``1`` is used for ``true`` and ``0`` for ``false``\n- ``fixed<M>x<N>``: ``enc(X)`` is ``enc(X * 10**N)`` where ``X * 10**N`` is interpreted as a ``int256``.\n- ``fixed``: as in the ``fixed128x18`` case\n- ``ufixed<M>x<N>``: ``enc(X)`` is ``enc(X * 10**N)`` where ``X * 10**N`` is interpreted as a ``uint256``.\n- ``ufixed``: as in the ``ufixed128x18`` case\n- ``bytes<M>``: ``enc(X)`` is the sequence of bytes in ``X`` padded with trailing zero-bytes to a length of 32 bytes.\n\nNote that for any ``X``, ``len(enc(X))`` is a multiple of 32.\n\nFunction Selector and Argument Encoding\n=======================================\n\nAll in all, a call to the function ``f`` with parameters ``a_1, ..., a_n`` is encoded as\n\n  ``function_selector(f) enc((a_1, ..., a_n))``\n\nand the return values ``v_1, ..., v_k`` of ``f`` are encoded as\n\n  ``enc((v_1, ..., v_k))``\n\ni.e. the values are combined into a tuple and encoded.\n\nExamples\n========\n\nGiven the contract:\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract Foo {\n        function bar(bytes3[2] memory) public pure {}\n        function baz(uint32 x, bool y) public pure returns (bool r) { r = x > 32 || y; }\n        function sam(bytes memory, bool, uint[] memory) public pure {}\n    }\n\n\nThus, for our ``Foo`` example, if we wanted to call ``bar`` with the argument ``[\"abc\", \"def\"]``, we would pass 68 bytes total, broken down into:\n\n- ``0xfce353f6``: the Method ID. This is derived from the signature ``bar(bytes3[2])``.\n- ``0x6162630000000000000000000000000000000000000000000000000000000000``: the first part of the first\n  parameter, a ``bytes3`` value ``\"abc\"`` (left-aligned).\n- ``0x6465660000000000000000000000000000000000000000000000000000000000``: the second part of the first\n  parameter, a ``bytes3`` value ``\"def\"`` (left-aligned).\n\nIn total:\n\n.. code-block:: none\n\n    0xfce353f661626300000000000000000000000000000000000000000000000000000000006465660000000000000000000000000000000000000000000000000000000000\n\nIf we wanted to call ``baz`` with the parameters ``69`` and\n``true``, we would pass 68 bytes total, which can be broken down into:\n\n- ``0xcdcd77c0``: the Method ID. This is derived as the first 4 bytes of the Keccak hash of\n  the ASCII form of the signature ``baz(uint32,bool)``.\n- ``0x0000000000000000000000000000000000000000000000000000000000000045``: the first parameter,\n  a uint32 value ``69`` padded to 32 bytes\n- ``0x0000000000000000000000000000000000000000000000000000000000000001``: the second parameter - boolean\n  ``true``, padded to 32 bytes\n\nIn total:\n\n.. code-block:: none\n\n    0xcdcd77c000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000001\n\nIt returns a single ``bool``. If, for example, it were to return ``false``, its output would be\nthe single byte array ``0x0000000000000000000000000000000000000000000000000000000000000000``, a single bool.\n\nIf we wanted to call ``sam`` with the arguments ``\"dave\"``, ``true`` and ``[1,2,3]``, we would\npass 292 bytes total, broken down into:\n\n- ``0xa5643bf2``: the Method ID. This is derived from the signature ``sam(bytes,bool,uint256[])``. Note that ``uint`` is replaced with its canonical representation ``uint256``.\n- ``0x0000000000000000000000000000000000000000000000000000000000000060``: the location of the data part of the first parameter (dynamic type), measured in bytes from the start of the arguments block. In this case, ``0x60``.\n- ``0x0000000000000000000000000000000000000000000000000000000000000001``: the second parameter: boolean true.\n- ``0x00000000000000000000000000000000000000000000000000000000000000a0``: the location of the data part of the third parameter (dynamic type), measured in bytes. In this case, ``0xa0``.\n- ``0x0000000000000000000000000000000000000000000000000000000000000004``: the data part of the first argument, it starts with the length of the byte array in elements, in this case, 4.\n- ``0x6461766500000000000000000000000000000000000000000000000000000000``: the contents of the first argument: the UTF-8 (equal to ASCII in this case) encoding of ``\"dave\"``, padded on the right to 32 bytes.\n- ``0x0000000000000000000000000000000000000000000000000000000000000003``: the data part of the third argument, it starts with the length of the array in elements, in this case, 3.\n- ``0x0000000000000000000000000000000000000000000000000000000000000001``: the first entry of the third parameter.\n- ``0x0000000000000000000000000000000000000000000000000000000000000002``: the second entry of the third parameter.\n- ``0x0000000000000000000000000000000000000000000000000000000000000003``: the third entry of the third parameter.\n\nIn total:\n\n.. code-block:: none\n\n    0xa5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003\n\nUse of Dynamic Types\n====================\n\nA call to a function with the signature ``f(uint256,uint32[],bytes10,bytes)`` with values\n``(0x123, [0x456, 0x789], \"1234567890\", \"Hello, world!\")`` is encoded in the following way:\n\nWe take the first four bytes of ``keccak(\"f(uint256,uint32[],bytes10,bytes)\")``, i.e. ``0x8be65246``.\nThen we encode the head parts of all four arguments. For the static types ``uint256`` and ``bytes10``,\nthese are directly the values we want to pass, whereas for the dynamic types ``uint32[]`` and ``bytes``,\nwe use the offset in bytes to the start of their data area, measured from the start of the value\nencoding (i.e. not counting the first four bytes containing the hash of the function signature). These are:\n\n- ``0x0000000000000000000000000000000000000000000000000000000000000123`` (``0x123`` padded to 32 bytes)\n- ``0x0000000000000000000000000000000000000000000000000000000000000080`` (offset to start of data part of second parameter, 4*32 bytes, exactly the size of the head part)\n- ``0x3132333435363738393000000000000000000000000000000000000000000000`` (``\"1234567890\"`` padded to 32 bytes on the right)\n- ``0x00000000000000000000000000000000000000000000000000000000000000e0`` (offset to start of data part of fourth parameter = offset to start of data part of first dynamic parameter + size of data part of first dynamic parameter = 4\\*32 + 3\\*32 (see below))\n\nAfter this, the data part of the first dynamic argument, ``[0x456, 0x789]`` follows:\n\n- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (number of elements of the array, 2)\n- ``0x0000000000000000000000000000000000000000000000000000000000000456`` (first element)\n- ``0x0000000000000000000000000000000000000000000000000000000000000789`` (second element)\n\nFinally, we encode the data part of the second dynamic argument, ``\"Hello, world!\"``:\n\n- ``0x000000000000000000000000000000000000000000000000000000000000000d`` (number of elements (bytes in this case): 13)\n- ``0x48656c6c6f2c20776f726c642100000000000000000000000000000000000000`` (``\"Hello, world!\"`` padded to 32 bytes on the right)\n\nAll together, the encoding is (newline after function selector and each 32-bytes for clarity):\n\n.. code-block:: none\n\n    0x8be65246\n      0000000000000000000000000000000000000000000000000000000000000123\n      0000000000000000000000000000000000000000000000000000000000000080\n      3132333435363738393000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000000000000000e0\n      0000000000000000000000000000000000000000000000000000000000000002\n      0000000000000000000000000000000000000000000000000000000000000456\n      0000000000000000000000000000000000000000000000000000000000000789\n      000000000000000000000000000000000000000000000000000000000000000d\n      48656c6c6f2c20776f726c642100000000000000000000000000000000000000\n\nLet us apply the same principle to encode the data for a function with a signature ``g(uint256[][],string[])``\nwith values ``([[1, 2], [3]], [\"one\", \"two\", \"three\"])`` but start from the most atomic parts of the encoding:\n\nFirst we encode the length and data of the first embedded dynamic array ``[1, 2]`` of the first root array ``[[1, 2], [3]]``:\n\n- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (number of elements in the first array, 2; the elements themselves are ``1`` and ``2``)\n- ``0x0000000000000000000000000000000000000000000000000000000000000001`` (first element)\n- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (second element)\n\nThen we encode the length and data of the second embedded dynamic array ``[3]`` of the first root array ``[[1, 2], [3]]``:\n\n- ``0x0000000000000000000000000000000000000000000000000000000000000001`` (number of elements in the second array, 1; the element is ``3``)\n- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (first element)\n\nThen we need to find the offsets ``a`` and ``b`` for their respective dynamic arrays ``[1, 2]`` and ``[3]``.\nTo calculate the offsets we can take a look at the encoded data of the first root array ``[[1, 2], [3]]``\nenumerating each line in the encoding:\n\n.. code-block:: none\n\n    0 - a                                                                - offset of [1, 2]\n    1 - b                                                                - offset of [3]\n    2 - 0000000000000000000000000000000000000000000000000000000000000002 - count for [1, 2]\n    3 - 0000000000000000000000000000000000000000000000000000000000000001 - encoding of 1\n    4 - 0000000000000000000000000000000000000000000000000000000000000002 - encoding of 2\n    5 - 0000000000000000000000000000000000000000000000000000000000000001 - count for [3]\n    6 - 0000000000000000000000000000000000000000000000000000000000000003 - encoding of 3\n\nOffset ``a`` points to the start of the content of the array ``[1, 2]`` which is line\n2 (64 bytes); thus ``a = 0x0000000000000000000000000000000000000000000000000000000000000040``.\n\nOffset ``b`` points to the start of the content of the array ``[3]`` which is line 5 (160 bytes);\nthus ``b = 0x00000000000000000000000000000000000000000000000000000000000000a0``.\n\n\nThen we encode the embedded strings of the second root array:\n\n- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of characters in word ``\"one\"``)\n- ``0x6f6e650000000000000000000000000000000000000000000000000000000000`` (utf8 representation of word ``\"one\"``)\n- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of characters in word ``\"two\"``)\n- ``0x74776f0000000000000000000000000000000000000000000000000000000000`` (utf8 representation of word ``\"two\"``)\n- ``0x0000000000000000000000000000000000000000000000000000000000000005`` (number of characters in word ``\"three\"``)\n- ``0x7468726565000000000000000000000000000000000000000000000000000000`` (utf8 representation of word ``\"three\"``)\n\nIn parallel to the first root array, since strings are dynamic elements we need to find their offsets ``c``, ``d`` and ``e``:\n\n.. code-block:: none\n\n    0 - c                                                                - offset for \"one\"\n    1 - d                                                                - offset for \"two\"\n    2 - e                                                                - offset for \"three\"\n    3 - 0000000000000000000000000000000000000000000000000000000000000003 - count for \"one\"\n    4 - 6f6e650000000000000000000000000000000000000000000000000000000000 - encoding of \"one\"\n    5 - 0000000000000000000000000000000000000000000000000000000000000003 - count for \"two\"\n    6 - 74776f0000000000000000000000000000000000000000000000000000000000 - encoding of \"two\"\n    7 - 0000000000000000000000000000000000000000000000000000000000000005 - count for \"three\"\n    8 - 7468726565000000000000000000000000000000000000000000000000000000 - encoding of \"three\"\n\nOffset ``c`` points to the start of the content of the string ``\"one\"`` which is line 3 (96 bytes);\nthus ``c = 0x0000000000000000000000000000000000000000000000000000000000000060``.\n\nOffset ``d`` points to the start of the content of the string ``\"two\"`` which is line 5 (160 bytes);\nthus ``d = 0x00000000000000000000000000000000000000000000000000000000000000a0``.\n\nOffset ``e`` points to the start of the content of the string ``\"three\"`` which is line 7 (224 bytes);\nthus ``e = 0x00000000000000000000000000000000000000000000000000000000000000e0``.\n\n\nNote that the encodings of the embedded elements of the root arrays are not dependent on each other\nand have the same encodings for a function with a signature ``g(string[],uint256[][])``.\n\nThen we encode the length of the first root array:\n\n- ``0x0000000000000000000000000000000000000000000000000000000000000002`` (number of elements in the first root array, 2; the elements themselves are ``[1, 2]``  and ``[3]``)\n\nThen we encode the length of the second root array:\n\n- ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of strings in the second root array, 3; the strings themselves are ``\"one\"``, ``\"two\"`` and ``\"three\"``)\n\nFinally we find the offsets ``f`` and ``g`` for their respective root dynamic arrays ``[[1, 2], [3]]`` and\n``[\"one\", \"two\", \"three\"]``, and assemble parts in the correct order:\n\n.. code-block:: none\n\n    0x2289b18c                                                            - function signature\n     0 - f                                                                - offset of [[1, 2], [3]]\n     1 - g                                                                - offset of [\"one\", \"two\", \"three\"]\n     2 - 0000000000000000000000000000000000000000000000000000000000000002 - count for [[1, 2], [3]]\n     3 - 0000000000000000000000000000000000000000000000000000000000000040 - offset of [1, 2]\n     4 - 00000000000000000000000000000000000000000000000000000000000000a0 - offset of [3]\n     5 - 0000000000000000000000000000000000000000000000000000000000000002 - count for [1, 2]\n     6 - 0000000000000000000000000000000000000000000000000000000000000001 - encoding of 1\n     7 - 0000000000000000000000000000000000000000000000000000000000000002 - encoding of 2\n     8 - 0000000000000000000000000000000000000000000000000000000000000001 - count for [3]\n     9 - 0000000000000000000000000000000000000000000000000000000000000003 - encoding of 3\n    10 - 0000000000000000000000000000000000000000000000000000000000000003 - count for [\"one\", \"two\", \"three\"]\n    11 - 0000000000000000000000000000000000000000000000000000000000000060 - offset for \"one\"\n    12 - 00000000000000000000000000000000000000000000000000000000000000a0 - offset for \"two\"\n    13 - 00000000000000000000000000000000000000000000000000000000000000e0 - offset for \"three\"\n    14 - 0000000000000000000000000000000000000000000000000000000000000003 - count for \"one\"\n    15 - 6f6e650000000000000000000000000000000000000000000000000000000000 - encoding of \"one\"\n    16 - 0000000000000000000000000000000000000000000000000000000000000003 - count for \"two\"\n    17 - 74776f0000000000000000000000000000000000000000000000000000000000 - encoding of \"two\"\n    18 - 0000000000000000000000000000000000000000000000000000000000000005 - count for \"three\"\n    19 - 7468726565000000000000000000000000000000000000000000000000000000 - encoding of \"three\"\n\nOffset ``f`` points to the start of the content of the array ``[[1, 2], [3]]`` which is line 2 (64 bytes);\nthus ``f = 0x0000000000000000000000000000000000000000000000000000000000000040``.\n\nOffset ``g`` points to the start of the content of the array ``[\"one\", \"two\", \"three\"]`` which is line 10 (320 bytes);\nthus ``g = 0x0000000000000000000000000000000000000000000000000000000000000140``.\n\n.. _abi_events:\n\nEvents\n======\n\nEvents are an abstraction of the Ethereum logging/event-watching protocol. Log entries provide the contract's\naddress, a series of up to four topics and some arbitrary length binary data. Events leverage the existing function\nABI in order to interpret this (together with an interface spec) as a properly typed structure.\n\nGiven an event name and series of event parameters, we split them into two sub-series: those which are indexed and\nthose which are not.\nThose which are indexed, which may number up to 3 (for non-anonymous events) or 4 (for anonymous ones), are used\nalongside the Keccak hash of the event signature to form the topics of the log entry.\nThose which are not indexed form the byte array of the event.\n\nIn effect, a log entry using this ABI is described as:\n\n- ``address``: the address of the contract (intrinsically provided by Ethereum);\n- ``topics[0]``: ``keccak(EVENT_NAME+\"(\"+EVENT_ARGS.map(canonical_type_of).join(\",\")+\")\")`` (``canonical_type_of``\n  is a function that simply returns the canonical type of a given argument, e.g. for ``uint indexed foo``, it would\n  return ``uint256``). This value is only present in ``topics[0]`` if the event is not declared as ``anonymous``;\n- ``topics[n]``: ``abi_encode(EVENT_INDEXED_ARGS[n - 1])`` if the event is not declared as ``anonymous``\n  or ``abi_encode(EVENT_INDEXED_ARGS[n])`` if it is (``EVENT_INDEXED_ARGS`` is the series of ``EVENT_ARGS`` that\n  are indexed);\n- ``data``: ABI encoding of ``EVENT_NON_INDEXED_ARGS`` (``EVENT_NON_INDEXED_ARGS`` is the series of ``EVENT_ARGS``\n  that are not indexed, ``abi_encode`` is the ABI encoding function used for returning a series of typed values\n  from a function, as described above).\n\nFor all types of length at most 32 bytes, the ``EVENT_INDEXED_ARGS`` array contains\nthe value directly, padded or sign-extended (for signed integers) to 32 bytes, just as for regular ABI encoding.\nHowever, for all \"complex\" types or types of dynamic length, including all arrays, ``string``, ``bytes`` and structs,\n``EVENT_INDEXED_ARGS`` will contain the *Keccak hash* of a special in-place encoded value\n(see :ref:`indexed_event_encoding`), rather than the encoded value directly.\nThis allows applications to efficiently query for values of dynamic-length types\n(by setting the hash of the encoded value as the topic), but leaves applications unable\nto decode indexed values they have not queried for. For dynamic-length types,\napplication developers face a trade-off between fast search for predetermined values\n(if the argument is indexed) and legibility of arbitrary values (which requires that\nthe arguments not be indexed). Developers may overcome this tradeoff and achieve both\nefficient search and arbitrary legibility by defining events with two arguments — one\nindexed, one not — intended to hold the same value.\n\n.. _abi_errors:\n.. index:: error, selector; of an error\n\nErrors\n======\n\nIn case of a failure inside a contract, the contract can use a special opcode to abort execution and revert\nall state changes. In addition to these effects, descriptive data can be returned to the caller.\nThis descriptive data is the encoding of an error and its arguments in the same way as data for a function\ncall.\n\nAs an example, let us consider the following contract whose ``transfer`` function always\nreverts with a custom error of \"insufficient balance\":\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.4;\n\n    contract TestToken {\n        error InsufficientBalance(uint256 available, uint256 required);\n        function transfer(address /*to*/, uint amount) public pure {\n            revert InsufficientBalance(0, amount);\n        }\n    }\n\nThe return data would be encoded in the same way as the function call\n``InsufficientBalance(0, amount)`` to the function ``InsufficientBalance(uint256,uint256)``,\ni.e. ``0xcf479181``, ``uint256(0)``, ``uint256(amount)``.\n\nThe error selectors ``0x00000000`` and ``0xffffffff`` are reserved for future use.\n\n.. warning::\n    Never trust error data.\n    The error data by default bubbles up through the chain of external calls, which\n    means that a contract may receive an error not defined in any of the contracts\n    it calls directly.\n    Furthermore, any contract can fake any error by returning data that matches\n    an error signature, even if the error is not defined anywhere.\n\n.. _abi_json:\n\nJSON\n====\n\nThe JSON format for a contract's interface is given by an array of function, event and error descriptions.\nA function description is a JSON object with the fields:\n\n- ``type``: ``\"function\"``, ``\"constructor\"``, ``\"receive\"`` (the :ref:`\"receive Ether\" function <receive-ether-function>`) or ``\"fallback\"`` (the :ref:`\"default\" function <fallback-function>`);\n- ``name``: the name of the function;\n- ``inputs``: an array of objects, each of which contains:\n\n  * ``name``: the name of the parameter.\n  * ``type``: the canonical type of the parameter (more below).\n  * ``components``: used for tuple types (more below).\n\n- ``outputs``: an array of objects similar to ``inputs``.\n- ``stateMutability``: a string with one of the following values: ``pure`` (:ref:`specified to not read\n  blockchain state <pure-functions>`), ``view`` (:ref:`specified to not modify the blockchain\n  state <view-functions>`), ``nonpayable`` (function does not accept Ether - the default) and ``payable`` (function accepts Ether).\n\nConstructor, receive, and fallback never have ``name`` or ``outputs``. Receive and fallback do not have ``inputs`` either.\n\n.. note::\n    Sending non-zero Ether to non-payable function will revert the transaction.\n\n.. note::\n    The state mutability ``nonpayable`` is reflected in Solidity by not specifying\n    a state mutability modifier at all.\n\nAn event description is a JSON object with fairly similar fields:\n\n- ``type``: always ``\"event\"``\n- ``name``: the name of the event.\n- ``inputs``: an array of objects, each of which contains:\n\n  * ``name``: the name of the parameter.\n  * ``type``: the canonical type of the parameter (more below).\n  * ``components``: used for tuple types (more below).\n  * ``indexed``: ``true`` if the field is part of the log's topics, ``false`` if it is one of the log's data segments.\n\n- ``anonymous``: ``true`` if the event was declared as ``anonymous``.\n\nErrors look as follows:\n\n- ``type``: always ``\"error\"``\n- ``name``: the name of the error.\n- ``inputs``: an array of objects, each of which contains:\n\n  * ``name``: the name of the parameter.\n  * ``type``: the canonical type of the parameter (more below).\n  * ``components``: used for tuple types (more below).\n\n.. note::\n  There can be multiple errors with the same name and even with identical signature\n  in the JSON array; for example, if the errors originate from different\n  files in the smart contract or are referenced from another smart contract.\n  For the ABI, only the name of the error itself is relevant and not where it is\n  defined.\n\n\nFor example,\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.4;\n\n\n    contract Test {\n        constructor() { b = hex\"12345678901234567890123456789012\"; }\n        event Event(uint indexed a, bytes32 b);\n        event Event2(uint indexed a, bytes32 b);\n        error InsufficientBalance(uint256 available, uint256 required);\n        function foo(uint a) public { emit Event(a, b); }\n        bytes32 b;\n    }\n\nwould result in the JSON:\n\n.. code-block:: json\n\n    [{\n    \"type\":\"error\",\n    \"inputs\": [{\"name\":\"available\",\"type\":\"uint256\"},{\"name\":\"required\",\"type\":\"uint256\"}],\n    \"name\":\"InsufficientBalance\"\n    }, {\n    \"type\":\"event\",\n    \"inputs\": [{\"name\":\"a\",\"type\":\"uint256\",\"indexed\":true},{\"name\":\"b\",\"type\":\"bytes32\",\"indexed\":false}],\n    \"name\":\"Event\"\n    }, {\n    \"type\":\"event\",\n    \"inputs\": [{\"name\":\"a\",\"type\":\"uint256\",\"indexed\":true},{\"name\":\"b\",\"type\":\"bytes32\",\"indexed\":false}],\n    \"name\":\"Event2\"\n    }, {\n    \"type\":\"function\",\n    \"inputs\": [{\"name\":\"a\",\"type\":\"uint256\"}],\n    \"name\":\"foo\",\n    \"outputs\": []\n    }]\n\nHandling tuple types\n--------------------\n\nDespite the fact that names are intentionally not part of the ABI encoding, they do make a lot of sense to be included\nin the JSON to enable displaying it to the end user. The structure is nested in the following way:\n\nAn object with members ``name``, ``type`` and potentially ``components`` describes a typed variable.\nThe canonical type is determined until a tuple type is reached and the string description up\nto that point is stored in ``type`` prefix with the word ``tuple``, i.e. it will be ``tuple`` followed by\na sequence of ``[]`` and ``[k]`` with\nintegers ``k``. The components of the tuple are then stored in the member ``components``,\nwhich is of an array type and has the same structure as the top-level object except that\n``indexed`` is not allowed there.\n\nAs an example, the code\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.5 <0.9.0;\n    pragma abicoder v2;\n\n    contract Test {\n        struct S { uint a; uint[] b; T[] c; }\n        struct T { uint x; uint y; }\n        function f(S memory, T memory, uint) public pure {}\n        function g() public pure returns (S memory, T memory, uint) {}\n    }\n\nwould result in the JSON:\n\n.. code-block:: json\n\n    [\n      {\n        \"name\": \"f\",\n        \"type\": \"function\",\n        \"inputs\": [\n          {\n            \"name\": \"s\",\n            \"type\": \"tuple\",\n            \"components\": [\n              {\n                \"name\": \"a\",\n                \"type\": \"uint256\"\n              },\n              {\n                \"name\": \"b\",\n                \"type\": \"uint256[]\"\n              },\n              {\n                \"name\": \"c\",\n                \"type\": \"tuple[]\",\n                \"components\": [\n                  {\n                    \"name\": \"x\",\n                    \"type\": \"uint256\"\n                  },\n                  {\n                    \"name\": \"y\",\n                    \"type\": \"uint256\"\n                  }\n                ]\n              }\n            ]\n          },\n          {\n            \"name\": \"t\",\n            \"type\": \"tuple\",\n            \"components\": [\n              {\n                \"name\": \"x\",\n                \"type\": \"uint256\"\n              },\n              {\n                \"name\": \"y\",\n                \"type\": \"uint256\"\n              }\n            ]\n          },\n          {\n            \"name\": \"a\",\n            \"type\": \"uint256\"\n          }\n        ],\n        \"outputs\": []\n      }\n    ]\n\n.. _abi_packed_mode:\n\nStrict Encoding Mode\n====================\n\nStrict encoding mode is the mode that leads to exactly the same encoding as defined in the formal specification above.\nThis means that offsets have to be as small as possible while still not creating overlaps in the data areas, and thus no gaps are\nallowed.\n\nUsually, ABI decoders are written in a straightforward way by just following offset pointers, but some decoders\nmight enforce strict mode. The Solidity ABI decoder currently does not enforce strict mode, but the encoder\nalways creates data in strict mode.\n\nNon-standard Packed Mode\n========================\n\nThrough ``abi.encodePacked()``, Solidity supports a non-standard packed mode where:\n\n- types shorter than 32 bytes are concatenated directly, without padding or sign extension\n- dynamic types are encoded in-place and without the length.\n- array elements are padded, but still encoded in-place\n\nFurthermore, structs as well as nested arrays are not supported.\n\nAs an example, the encoding of ``int16(-1), bytes1(0x42), uint16(0x03), string(\"Hello, world!\")`` results in:\n\n.. code-block:: none\n\n    0xffff42000348656c6c6f2c20776f726c6421\n      ^^^^                                 int16(-1)\n          ^^                               bytes1(0x42)\n            ^^^^                           uint16(0x03)\n                ^^^^^^^^^^^^^^^^^^^^^^^^^^ string(\"Hello, world!\") without a length field\n\nMore specifically:\n\n- During the encoding, everything is encoded in-place. This means that there is\n  no distinction between head and tail, as in the ABI encoding, and the length\n  of an array is not encoded.\n- The direct arguments of ``abi.encodePacked`` are encoded without padding,\n  as long as they are not arrays (or ``string`` or ``bytes``).\n- The encoding of an array is the concatenation of the\n  encoding of its elements **with** padding.\n- Dynamically-sized types like ``string``, ``bytes`` or ``uint[]`` are encoded\n  without their length field.\n- The encoding of ``string`` or ``bytes`` does not apply padding at the end,\n  unless it is part of an array or struct (then it is padded to a multiple of\n  32 bytes).\n\nIn general, the encoding is ambiguous as soon as there are two dynamically-sized elements,\nbecause of the missing length field.\n\nIf padding is needed, explicit type conversions can be used: ``abi.encodePacked(uint16(0x12)) == hex\"0012\"``.\n\nSince packed encoding is not used when calling functions, there is no special support\nfor prepending a function selector. Since the encoding is ambiguous, there is no decoding function.\n\n.. warning::\n\n    If you use ``keccak256(abi.encodePacked(a, b))`` and both ``a`` and ``b`` are dynamic types,\n    it is easy to craft collisions in the hash value by moving parts of ``a`` into ``b`` and\n    vice-versa. More specifically, ``abi.encodePacked(\"a\", \"bc\") == abi.encodePacked(\"ab\", \"c\")``.\n    If you use ``abi.encodePacked`` for signatures, authentication or data integrity, make\n    sure to always use the same types and check that at most one of them is dynamic.\n    Unless there is a compelling reason, ``abi.encode`` should be preferred.\n\n\n.. _indexed_event_encoding:\n\nEncoding of Indexed Event Parameters\n====================================\n\nIndexed event parameters that are not value types, i.e. arrays and structs are not\nstored directly but instead a Keccak-256 hash of an encoding is stored. This encoding\nis defined as follows:\n\n- the encoding of a ``bytes`` and ``string`` value is just the string contents\n  without any padding or length prefix.\n- the encoding of a struct is the concatenation of the encoding of its members,\n  always padded to a multiple of 32 bytes (even ``bytes`` and ``string``).\n- the encoding of an array (both dynamically- and statically-sized) is\n  the concatenation of the encoding of its elements, always padded to a multiple\n  of 32 bytes (even ``bytes`` and ``string``) and without any length prefix\n\nIn the above, as usual, a negative number is padded by sign extension and not zero padded.\n``bytesNN`` types are padded on the right while ``uintNN`` / ``intNN`` are padded on the left.\n\n.. warning::\n\n    The encoding of a struct is ambiguous if it contains more than one dynamically-sized\n    array. Because of that, always re-check the event data and do not rely on the search result\n    based on the indexed parameters alone.\n"
  },
  {
    "path": "docs/analysing-compilation-output.rst",
    "content": ".. index:: analyse, asm\n\n#############################\nAnalysing the Compiler Output\n#############################\n\nIt is often useful to look at the assembly code generated by the compiler. The generated binary,\ni.e., the output of ``solc --bin contract.sol``, is generally difficult to read. It is recommended\nto use the flag ``--asm`` to analyse the assembly output. Even for large contracts, looking at a\nvisual diff of the assembly before and after a change is often very enlightening.\n\nConsider the following contract (named, say ``contract.sol``):\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.0 <0.9.0;\n    contract C {\n        function one() public pure returns (uint) {\n            return 1;\n        }\n    }\n\nThe following would be the output of ``solc --asm contract.sol``\n\n.. code-block:: none\n\n    ======= contract.sol:C =======\n    EVM assembly:\n        /* \"contract.sol\":0:86  contract C {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      0x00\n      dup1\n      revert\n    tag_1:\n      pop\n      dataSize(sub_0)\n      dup1\n      dataOffset(sub_0)\n      0x00\n      codecopy\n      0x00\n      return\n    stop\n\n    sub_0: assembly {\n            /* \"contract.sol\":0:86  contract C {... */\n          mstore(0x40, 0x80)\n          callvalue\n          dup1\n          iszero\n          tag_1\n          jumpi\n          0x00\n          dup1\n          revert\n        tag_1:\n          pop\n          jumpi(tag_2, lt(calldatasize, 0x04))\n          shr(0xe0, calldataload(0x00))\n          dup1\n          0x901717d1\n          eq\n          tag_3\n          jumpi\n        tag_2:\n          0x00\n          dup1\n          revert\n            /* \"contract.sol\":17:84  function one() public pure returns (uint) {... */\n        tag_3:\n          tag_4\n          tag_5\n          jump\t// in\n        tag_4:\n          mload(0x40)\n          tag_6\n          swap2\n          swap1\n          tag_7\n          jump\t// in\n        tag_6:\n          mload(0x40)\n          dup1\n          swap2\n          sub\n          swap1\n          return\n        tag_5:\n            /* \"contract.sol\":53:57  uint */\n          0x00\n            /* \"contract.sol\":76:77  1 */\n          0x01\n            /* \"contract.sol\":69:77  return 1 */\n          swap1\n          pop\n            /* \"contract.sol\":17:84  function one() public pure returns (uint) {... */\n          swap1\n          jump\t// out\n            /* \"#utility.yul\":7:125   */\n        tag_10:\n            /* \"#utility.yul\":94:118   */\n          tag_12\n            /* \"#utility.yul\":112:117   */\n          dup2\n            /* \"#utility.yul\":94:118   */\n          tag_13\n          jump\t// in\n        tag_12:\n            /* \"#utility.yul\":89:92   */\n          dup3\n            /* \"#utility.yul\":82:119   */\n          mstore\n            /* \"#utility.yul\":72:125   */\n          pop\n          pop\n          jump\t// out\n            /* \"#utility.yul\":131:353   */\n        tag_7:\n          0x00\n            /* \"#utility.yul\":262:264   */\n          0x20\n            /* \"#utility.yul\":251:260   */\n          dup3\n            /* \"#utility.yul\":247:265   */\n          add\n            /* \"#utility.yul\":239:265   */\n          swap1\n          pop\n            /* \"#utility.yul\":275:346   */\n          tag_15\n            /* \"#utility.yul\":343:344   */\n          0x00\n            /* \"#utility.yul\":332:341   */\n          dup4\n            /* \"#utility.yul\":328:345   */\n          add\n            /* \"#utility.yul\":319:325   */\n          dup5\n            /* \"#utility.yul\":275:346   */\n          tag_10\n          jump\t// in\n        tag_15:\n            /* \"#utility.yul\":229:353   */\n          swap3\n          swap2\n          pop\n          pop\n          jump\t// out\n            /* \"#utility.yul\":359:436   */\n        tag_13:\n          0x00\n            /* \"#utility.yul\":425:430   */\n          dup2\n            /* \"#utility.yul\":414:430   */\n          swap1\n          pop\n            /* \"#utility.yul\":404:436   */\n          swap2\n          swap1\n          pop\n          jump\t// out\n\n        auxdata: 0xa2646970667358221220a5874f19737ddd4c5d77ace1619e5160c67b3d4bedac75fce908fed32d98899864736f6c637827302e382e342d646576656c6f702e323032312e332e33302b636f6d6d69742e65613065363933380058\n    }\n\nAlternatively, the above output can also be obtained from `Remix <https://remix.ethereum.org/>`_,\nunder the option \"Compilation Details\" after compiling a contract.\n\nNotice that the ``asm`` output starts with the creation / constructor code. The deploy code is\nprovided as part of the sub object (in the above example, it is part of the sub-object ``sub_0``).\nThe ``auxdata`` field corresponds to the contract :ref:`metadata\n<encoding-of-the-metadata-hash-in-the-bytecode>`. The comments in the assembly output point to the\nsource location. Note that ``#utility.yul`` is an internally generated file of utility functions\nthat can be obtained using the flags ``--combined-json\ngenerated-sources,generated-sources-runtime``.\n\nSimilarly, the optimized assembly can be obtained with the command: ``solc --optimize --asm\ncontract.sol``. Often times, it is interesting to see if two different sources in Solidity result in\nthe same optimized code. For example, to see if the expressions ``(a * b) / c``, ``a * b / c``\ngenerates the same bytecode. This can be easily done by taking a ``diff`` of the corresponding\nassembly output, after potentially stripping comments that reference the source locations.\n\n.. note::\n\n   The ``--asm`` output is not designed to be machine readable. Therefore, there may be breaking\n   changes on the output between minor versions of solc.\n"
  },
  {
    "path": "docs/assembly.rst",
    "content": ".. _inline-assembly:\n\n###############\nInline Assembly\n###############\n\n.. index:: ! assembly, ! asm, ! evmasm\n\n\nYou can interleave Solidity statements with inline assembly in a language close\nto the one of the Ethereum Virtual Machine. This gives you more fine-grained control,\nwhich is especially useful when you are enhancing the language by writing libraries or\noptimizing gas usage.\n\nThe language used for inline assembly in Solidity is called :ref:`Yul <yul>`\nand it is documented in its own section. This section will only cover\nhow the inline assembly code can interface with the surrounding Solidity code.\n\n\n.. warning::\n    Inline assembly is a way to access the Ethereum Virtual Machine\n    at a low level. This bypasses several important safety\n    features and checks of Solidity. You should only use it for\n    tasks that need it, and only if you are confident with using it.\n\n\nAn inline assembly block is marked by ``assembly { ... }``, where the code inside\nthe curly braces is code in the :ref:`Yul <yul>` language.\n\nThe inline assembly code can access local Solidity variables as explained below.\n\nDifferent inline assembly blocks share no namespace, i.e. it is not possible\nto call a Yul function or access a Yul variable defined in a different inline assembly block.\n\nExample\n-------\n\nThe following example provides library code to access the code of another contract and\nload it into a ``bytes`` variable. This is possible with \"plain Solidity\" too, by using\n``<address>.code``. But the point here is that reusable assembly libraries can enhance the\nSolidity language without a compiler change.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    library GetCode {\n        function at(address addr) public view returns (bytes memory code) {\n            assembly {\n                // retrieve the size of the code, this needs assembly\n                let size := extcodesize(addr)\n                // allocate output byte array - this could also be done without assembly\n                // by using code = new bytes(size)\n                code := mload(0x40)\n                // new \"memory end\" including padding\n                mstore(0x40, add(code, and(add(add(size, 0x20), 0x1f), not(0x1f))))\n                // store length in memory\n                mstore(code, size)\n                // actually retrieve the code, this needs assembly\n                extcodecopy(addr, add(code, 0x20), 0, size)\n            }\n        }\n    }\n\nInline assembly is also beneficial in cases where the optimizer fails to produce\nefficient code, for example:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n\n    library VectorSum {\n        // This function is less efficient because the optimizer currently fails to\n        // remove the bounds checks in array access.\n        function sumSolidity(uint[] memory data) public pure returns (uint sum) {\n            for (uint i = 0; i < data.length; ++i)\n                sum += data[i];\n        }\n\n        // We know that we only access the array in bounds, so we can avoid the check.\n        // 0x20 needs to be added to an array because the first slot contains the\n        // array length.\n        function sumAsm(uint[] memory data) public pure returns (uint sum) {\n            for (uint i = 0; i < data.length; ++i) {\n                assembly {\n                    sum := add(sum, mload(add(add(data, 0x20), mul(i, 0x20))))\n                }\n            }\n        }\n\n        // Same as above, but accomplish the entire code within inline assembly.\n        function sumPureAsm(uint[] memory data) public pure returns (uint sum) {\n            assembly {\n                // Load the length (first 32 bytes)\n                let len := mload(data)\n\n                // Skip over the length field.\n                //\n                // Keep temporary variable so it can be incremented in place.\n                //\n                // NOTE: incrementing data would result in an unusable\n                //       data variable after this assembly block\n                let dataElementLocation := add(data, 0x20)\n\n                // Iterate until the bound is not met.\n                for\n                    { let end := add(dataElementLocation, mul(len, 0x20)) }\n                    lt(dataElementLocation, end)\n                    { dataElementLocation := add(dataElementLocation, 0x20) }\n                {\n                    sum := add(sum, mload(dataElementLocation))\n                }\n            }\n        }\n    }\n\n.. index:: selector; of a function\n\nAccess to External Variables, Functions and Libraries\n-----------------------------------------------------\n\nYou can access Solidity variables and other identifiers by using their name.\n\nLocal variables of value type are directly usable in inline assembly.\nThey can both be read and assigned to.\n\nLocal variables that refer to memory evaluate to the address of the variable in memory, not the value itself.\nSuch variables can also be assigned to, but note that an assignment will only change the pointer and not the data\nand that it is your responsibility to respect Solidity's memory management.\nSee :ref:`Conventions in Solidity <conventions-in-solidity>`.\n\nSimilarly, local variables that refer to statically-sized calldata arrays or calldata structs\nevaluate to the address of the variable in calldata, not the value itself.\nThe variable can also be assigned a new offset, but note that no validation is performed to ensure that\nthe variable will not point beyond ``calldatasize()``.\n\nFor external function pointers the address and the function selector can be\naccessed using ``x.address`` and ``x.selector``.\nThe selector consists of four right-aligned bytes.\nBoth values can be assigned to. For example:\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.10 <0.9.0;\n\n    contract C {\n        // Assigns a new selector and address to the return variable @fun\n        function combineToFunctionPointer(address newAddress, uint newSelector) public pure returns (function() external fun) {\n            assembly {\n                fun.selector := newSelector\n                fun.address  := newAddress\n            }\n        }\n    }\n\nFor dynamic calldata arrays, you can access\ntheir calldata offset (in bytes) and length (number of elements) using ``x.offset`` and ``x.length``.\nBoth expressions can also be assigned to, but as for the static case, no validation will be performed\nto ensure that the resulting data area is within the bounds of ``calldatasize()``.\n\nFor local storage variables or state variables (including transient storage) a single Yul identifier\nis not sufficient, since they do not necessarily occupy a single full storage slot.\nTherefore, their \"address\" is composed of a slot and a byte-offset\ninside that slot. To retrieve the slot pointed to by the variable ``x``, you\nuse ``x.slot``, and to retrieve the byte-offset you use ``x.offset``.\nUsing ``x`` itself will result in an error.\n\nYou can also assign to the ``.slot`` part of a local storage variable pointer.\nFor these (structs, arrays or mappings), the ``.offset`` part is always zero.\nIt is not possible to assign to the ``.slot`` or ``.offset`` part of a state variable,\nthough.\n\nLocal Solidity variables are available for assignments, for example:\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.28 <0.9.0;\n\n    // This will report a warning\n    contract C {\n        bool transient a;\n        uint b;\n        function f(uint x) public returns (uint r) {\n            assembly {\n                // We ignore the storage slot offset, we know it is zero\n                // in this special case.\n                r := mul(x, sload(b.slot))\n                tstore(a.slot, true)\n            }\n        }\n    }\n\n.. warning::\n    If you access variables of a type that spans less than 256 bits\n    (for example ``uint64``, ``address``, or ``bytes16``),\n    you cannot make any assumptions about bits not part of the\n    encoding of the type. Especially, do not assume them to be zero.\n    To be safe, always clear the data properly before you use it\n    in a context where this is important:\n    ``uint32 x = f(); assembly { x := and(x, 0xffffffff) /* now use x */ }``\n    To clean signed types, you can use the ``signextend`` opcode:\n    ``assembly { signextend(<num_bytes_of_x_minus_one>, x) }``\n\n\nSince Solidity 0.6.0, the name of an inline assembly variable may not\nshadow any declaration visible in the scope of the inline assembly block\n(including variable, contract and function declarations).\n\nSince Solidity 0.7.0, variables and functions declared inside the\ninline assembly block may not contain ``.``, but using ``.`` is\nvalid to access Solidity variables from outside the inline assembly block.\nHowever, it is still valid to use dots if you use Solidity in Yul-only mode.\n\nThings to Avoid\n---------------\n\nInline assembly might have a quite high-level look, but it actually is extremely\nlow-level. Function calls, loops, ifs and switches are converted by simple\nrewriting rules and after that, the only thing the assembler does for you is re-arranging\nfunctional-style opcodes, counting stack height for\nvariable access and removing stack slots for assembly-local variables when the end\nof their block is reached.\n\n.. _conventions-in-solidity:\n\nConventions in Solidity\n-----------------------\n\n.. _assembly-typed-variables:\n\nValues of Typed Variables\n=========================\n\nIn contrast to EVM assembly, Solidity has types which are narrower than 256 bits,\ne.g. ``uint24``. For efficiency, most arithmetic operations ignore the fact that\ntypes can be shorter than 256\nbits, and the higher-order bits are cleaned when necessary,\ni.e., shortly before they are written to memory or before comparisons are performed.\nThis means that if you access such a variable\nfrom within inline assembly, you might have to manually clean the higher-order bits\nfirst.\n\n.. _assembly-memory-management:\n\nMemory Management\n=================\n\nSolidity manages memory in the following way. There is a \"free memory pointer\"\nat position ``0x40`` in memory. If you want to allocate memory, use the memory\nstarting from where this pointer points at and update it.\nThere is no guarantee that the memory has not been used before and thus\nyou cannot assume that its contents are zero bytes.\nThere is no built-in mechanism to release or free allocated memory.\nSolidity does not guarantee and does not require that the values in memory\nare placed at positions aligned to a multiple of any value.\nHere is an assembly snippet you can use for allocating memory that follows the process outlined above:\n\n.. code-block:: yul\n\n    function allocate(length) -> pos {\n      pos := mload(0x40)\n      mstore(0x40, add(pos, length))\n    }\n\nThe first 64 bytes of memory can be used as \"scratch space\" for short-term\nallocation. The 32 bytes after the free memory pointer (i.e., starting at ``0x60``)\nare meant to be zero permanently and is used as the initial value for\nempty dynamic memory arrays.\nThis means that the allocatable memory starts at ``0x80``, which is the initial value\nof the free memory pointer.\n\nElements in memory arrays in Solidity always occupy multiples of 32 bytes (this is\neven true for ``bytes1[]``, but not for ``bytes`` and ``string``). Multi-dimensional memory\narrays are pointers to memory arrays. The length of a dynamic array is stored at the\nfirst slot of the array and followed by the array elements.\n\n.. warning::\n    Statically-sized memory arrays do not have a length field, but it might be added later\n    to allow better convertibility between statically and dynamically-sized arrays; so,\n    do not rely on this.\n\nMemory Safety\n=============\n\nWithout the use of inline assembly, the compiler can rely on memory to remain in a well-defined\nstate at all times. This is especially relevant for :ref:`the new code generation pipeline via Yul IR <ir-breaking-changes>`:\nthis code generation path can move local variables from stack to memory to avoid stack-too-deep errors and\nperform additional memory optimizations, if it can rely on certain assumptions about memory use.\n\nWhile we recommend to always respect Solidity's memory model, inline assembly allows you to use memory\nin an incompatible way. Therefore, moving stack variables to memory and additional memory optimizations are,\nby default, globally disabled in the presence of any inline assembly block that contains a memory operation\nor assigns to Solidity variables in memory.\n\nHowever, you can specifically annotate an assembly block to indicate that it in fact respects Solidity's memory\nmodel as follows:\n\n.. code-block:: solidity\n\n    assembly (\"memory-safe\") {\n        ...\n    }\n\nIn particular, a memory-safe assembly block may only access the following memory ranges:\n\n- Memory allocated by yourself using a mechanism like the ``allocate`` function described above.\n- Memory allocated by Solidity, e.g. memory within the bounds of a memory array you reference.\n- The scratch space between memory offset 0 and 64 mentioned above.\n- Temporary memory that is located *after* the value of the free memory pointer at the beginning of the assembly block,\n  i.e. memory that is \"allocated\" at the free memory pointer without updating the free memory pointer.\n\nFurthermore, if the assembly block assigns to Solidity variables in memory, you need to assure that accesses to\nthe Solidity variables only access these memory ranges.\n\nSince this is mainly about the optimizer, these restrictions still need to be followed, even if the assembly block\nreverts or terminates. As an example, the following assembly snippet is not memory safe, because the value of\n``returndatasize()`` may exceed the 64 byte scratch space:\n\n.. code-block:: solidity\n\n    assembly {\n      returndatacopy(0, 0, returndatasize())\n      revert(0, returndatasize())\n    }\n\nOn the other hand, the following code *is* memory safe, because memory beyond the location pointed to by the\nfree memory pointer can safely be used as temporary scratch space:\n\n.. code-block:: solidity\n\n    assembly (\"memory-safe\") {\n      let p := mload(0x40)\n      returndatacopy(p, 0, returndatasize())\n      revert(p, returndatasize())\n    }\n\nNote that you do not need to update the free memory pointer if there is no following allocation,\nbut you can only use memory starting from the current offset given by the free memory pointer.\n\nIf the memory operations use a length of zero, it is also fine to just use any offset (not only if it falls into the scratch space):\n\n.. code-block:: solidity\n\n    assembly (\"memory-safe\") {\n      revert(0, 0)\n    }\n\nNote that not only memory operations in inline assembly itself can be memory-unsafe, but also assignments to\nSolidity variables of reference type in memory. For example the following is not memory-safe:\n\n.. code-block:: solidity\n\n    bytes memory x;\n    assembly {\n      x := 0x40\n    }\n    x[0x20] = 0x42;\n\nInline assembly that neither involves any operations that access memory nor assigns to any Solidity variables\nin memory is automatically considered memory-safe and does not need to be annotated.\n\n.. warning::\n    It is your responsibility to make sure that the assembly actually satisfies the memory model. If you annotate\n    an assembly block as memory-safe, but violate one of the memory assumptions, this **will** lead to incorrect and\n    undefined behavior that cannot easily be discovered by testing.\n\nIn case you are developing a library that is meant to be compatible across multiple versions\nof Solidity, you can use a special comment to annotate an assembly block as memory-safe:\n\n.. code-block:: solidity\n\n    /// @solidity memory-safe-assembly\n    assembly {\n        ...\n    }\n\n.. warning::\n    The ``memory-safe-assembly`` special comment is deprecated and scheduled for removal.\n    In new code targeting recent compilers, use the assembly block annotation.\n\nAdvanced Safe Use of Memory\n---------------------------\n\nBeyond the strict definition of memory-safety given above, there are cases in which you may want to use more than 64 bytes\nof scratch space starting at memory offset ``0``. If you are careful, it can be admissible to use memory up to (and not\nincluding) offset ``0x80`` and still safely declare the assembly block as ``memory-safe``.\nThis is admissible under either of the following conditions:\n\n- By the end of the assembly block, the free memory pointer at offset ``0x40`` is restored to a sane value (i.e. it is either\n  restored to its original value or an increment of it due to a manual memory allocation), and the memory word at offset ``0x60``\n  is restored to a value of zero.\n\n- The assembly block terminates, i.e. execution can never return to high-level Solidity code. This is the case, for example,\n  if your assembly block unconditionally ends in calling the ``revert`` opcode.\n\nFurthermore, you need to be aware that the default-value of dynamic arrays in Solidity point to memory offset ``0x60``, so\nfor the duration of temporarily changing the value at memory offset ``0x60``, you can no longer rely on getting accurate\nlength values when reading dynamic arrays, until you restore the zero value at ``0x60``. To be more precise, we only guarantee\nsafety when overwriting the zero pointer, if the remainder of the assembly snippet does not interact with the memory of\nhigh-level Solidity objects (including by reading from offsets previously stored in variables).\n"
  },
  {
    "path": "docs/brand-guide.rst",
    "content": "####################\nSolidity Brand Guide\n####################\n\nThis brand guide features information on Solidity's brand policy and\nlogo usage guidelines.\n\nThe Solidity Brand\n==================\n\nThe Solidity programming language is an open-source, community project\ngoverned by a core team. The core team is sponsored by the `Ethereum\nFoundation <https://ethereum.foundation/>`_.\n\nThis document aims to provide information about how to best use the\nSolidity brand name and logo.\n\nWe encourage you to read this document carefully before using the\nbrand name or the logo. Your cooperation is highly appreciated!\n\nSolidity Brand Name\n===================\n\n\"Solidity\" should be used to refer to the Solidity programming language\nsolely.\n\nPlease do not use \"Solidity\":\n\n- To refer to any other programming language.\n\n- In a way that is misleading or may imply association of unrelated\n  modules, tools, documentation, or other resources with the Solidity\n  programming language.\n\n- In ways that confuse the community as to whether the Solidity\n  programming language is open-source and free to use.\n\nSolidity Logo License\n=====================\n\n.. image:: https://i.creativecommons.org/l/by/4.0/88x31.png\n  :width: 88\n  :alt: Creative Commons License\n\nThe Solidity logo is distributed and licensed under a `Creative Commons\nAttribution 4.0 International License <https://creativecommons.org/licenses/by/4.0/>`_.\n\nThis is the most permissive Creative Commons license and allows reuse\nand modifications for any purpose.\n\nYou are free to:\n\n- **Share** — Copy and redistribute the material in any medium or format.\n\n- **Adapt** — Remix, transform, and build upon the material for any\n  purpose, even commercially.\n\nUnder the following terms:\n\n- **Attribution** — You must give appropriate credit, provide a link to\n  the license, and indicate if changes were made. You may do so in any\n  reasonable manner, but not in any way that suggests that the Solidity\n  core team endorses you or your use.\n\nWhen using the Solidity logo, please respect the Solidity logo guidelines.\n\nSolidity Logo Guidelines\n========================\n\n.. image:: solidity_logo.svg\n  :width: 256\n\n*(Right click on the logo to download it.)*\n\nPlease do not:\n\n- Change the ratio of the logo (do not stretch it or cut it).\n\n- Change the colors of the logo, unless it is absolutely necessary.\n\nCredits\n=======\n\nThis document was, in parts, derived from the `Python Software\nFoundation Trademark Usage Policy <https://www.python.org/psf/trademarks/>`_\nand the `Rust Media Guide <https://www.rust-lang.org/policies/media-guide>`_.\n"
  },
  {
    "path": "docs/bugs.json",
    "content": "[\n    {\n        \"uid\": \"SOL-2026-1\",\n        \"name\": \"TransientStorageClearingHelperCollision\",\n        \"summary\": \"Clearing both storage and transient storage variables in the same contract may result in only one of these locations being cleared.\",\n        \"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.\",\n        \"link\": \"https://blog.soliditylang.org/2026/02/18/transient-storage-clearing-helper-collision-bug/\",\n        \"introduced\": \"0.8.28\",\n        \"fixed\": \"0.8.34\",\n        \"severity\": \"high\",\n        \"conditions\": {\n            \"viaIR\": true,\n            \"evmVersion\": \">=cancun\"\n        }\n    },\n    {\n        \"uid\": \"SOL-2025-1\",\n        \"name\": \"LostStorageArrayWriteOnSlotOverflow\",\n        \"summary\": \"Operations that involve clearing or copying from arrays that straddle the end of storage could result in silent data retention.\",\n        \"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, <array>.pop() and <array>.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).\",\n        \"link\": \"https://blog.soliditylang.org/2025/12/18/lost-storage-array-write-on-slot-overflow-bug/\",\n        \"introduced\": \"0.1.0\",\n        \"fixed\": \"0.8.32\",\n        \"severity\": \"low\"\n    },\n    {\n        \"uid\": \"SOL-2023-3\",\n        \"name\": \"VerbatimInvalidDeduplication\",\n        \"summary\": \"All ``verbatim`` blocks are considered identical by deduplicator and can incorrectly be unified when surrounded by identical opcodes.\",\n        \"description\": \"The block deduplicator is a step of the opcode-based optimizer which identifies equivalent assembly blocks and merges them into a single one. However, when blocks contained ``verbatim``, their comparison was performed incorrectly, leading to the collapse of assembly blocks which are identical except for the contents of the ``verbatim`` items. Since ``verbatim`` is only available in Yul, compilation of Solidity sources is not affected.\",\n        \"link\": \"https://blog.soliditylang.org/2023/11/08/verbatim-invalid-deduplication-bug/\",\n        \"introduced\": \"0.8.5\",\n        \"fixed\": \"0.8.23\",\n        \"severity\": \"low\"\n    },\n    {\n        \"uid\": \"SOL-2023-2\",\n        \"name\": \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n        \"summary\": \"Optimizer sequences containing FullInliner do not preserve the evaluation order of arguments of inlined function calls in code that is not in expression-split form.\",\n        \"description\": \"Function call arguments in Yul are evaluated right to left. This order matters when the argument expressions have side-effects, and changing it may change contract behavior. FullInliner is an optimizer step that can replace a function call with the body of that function. The transformation involves assigning argument expressions to temporary variables, which imposes an explicit evaluation order. FullInliner was written with the assumption that this order does not necessarily have to match usual argument evaluation order because the argument expressions have no side-effects. In most circumstances this assumption is true because the default optimization step sequence contains the ExpressionSplitter step. ExpressionSplitter ensures that the code is in *expression-split form*, which means that function calls cannot appear nested inside expressions, and all function call arguments have to be variables. The assumption is, however, not guaranteed to be true in general. Version 0.6.7 introduced a setting allowing users to specify an arbitrary optimization step sequence, making it possible for the FullInliner to actually encounter argument expressions with side-effects, which can result in behavior differences between optimized and unoptimized bytecode. Contracts compiled without optimization or with the default optimization sequence are not affected. To trigger the bug the user has to explicitly choose compiler settings that contain a sequence with FullInliner step not preceded by ExpressionSplitter.\",\n        \"link\": \"https://blog.soliditylang.org/2023/07/19/full-inliner-non-expression-split-argument-evaluation-order-bug/\",\n        \"introduced\": \"0.6.7\",\n        \"fixed\": \"0.8.21\",\n        \"severity\": \"low\",\n        \"conditions\": {\n            \"yulOptimizer\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2023-1\",\n        \"name\": \"MissingSideEffectsOnSelectorAccess\",\n        \"summary\": \"Accessing the ``.selector`` member on complex expressions leaves the expression unevaluated in the legacy code generation.\",\n        \"description\": \"When accessing the ``.selector`` member on an expression with side-effects, like an assignment, a function call or a conditional, the expression would not be evaluated in the legacy code generation. This would happen in expressions where the functions used in the expression were all known at compilation time, regardless of whether the whole expression could be evaluated at compilation time or not. Note that the code generated by the IR pipeline was unaffected and would behave as expected.\",\n        \"link\": \"https://blog.soliditylang.org/2023/07/19/missing-side-effects-on-selector-access-bug/\",\n        \"introduced\": \"0.6.2\",\n        \"fixed\": \"0.8.21\",\n        \"severity\": \"low\",\n        \"conditions\": {\n            \"viaIR\": false\n        }\n    },\n    {\n        \"uid\": \"SOL-2022-7\",\n        \"name\": \"StorageWriteRemovalBeforeConditionalTermination\",\n        \"summary\": \"Calling functions that conditionally terminate the external EVM call using the assembly statements ``return(...)`` or ``stop()`` may result in incorrect removals of prior storage writes.\",\n        \"description\": \"A call to a Yul function that conditionally terminates the external EVM call could result in prior storage writes being incorrectly removed by the Yul optimizer. This used to happen in cases in which it would have been valid to remove the store, if the Yul function in question never actually terminated the external call, and the control flow always returned back to the caller instead. Conditional termination within the same Yul block instead of within a called function was not affected. In Solidity with optimized via-IR code generation, any storage write before a function conditionally calling ``return(...)`` or ``stop()`` in inline assembly, may have been incorrectly removed, whenever it would have been valid to remove the write without the ``return(...)`` or ``stop()``. In optimized legacy code generation, only inline assembly that did not refer to any Solidity variables and that involved conditionally-terminating user-defined assembly functions could be affected.\",\n        \"link\": \"https://blog.soliditylang.org/2022/09/08/storage-write-removal-before-conditional-termination/\",\n        \"introduced\": \"0.8.13\",\n        \"fixed\": \"0.8.17\",\n        \"severity\": \"medium/high\",\n        \"conditions\": {\n            \"yulOptimizer\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2022-6\",\n        \"name\": \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n        \"summary\": \"ABI-encoding a tuple with a statically-sized calldata array in the last component would corrupt 32 leading bytes of its first dynamically encoded component.\",\n        \"description\": \"When ABI-encoding a statically-sized calldata array, the compiler always pads the data area to a multiple of 32-bytes and ensures that the padding bytes are zeroed. In some cases, this cleanup used to be performed by always writing exactly 32 bytes, regardless of how many needed to be zeroed. This was done with the assumption that the data that would eventually occupy the area past the end of the array had not yet been written, because the encoder processes tuple components in the order they were given. While this assumption is mostly true, there is an important corner case: dynamically encoded tuple components are stored separately from the statically-sized ones in an area called the *tail* of the encoding and the tail immediately follows the *head*, which is where the statically-sized components are placed. The aforementioned cleanup, if performed for the last component of the head would cross into the tail and overwrite up to 32 bytes of the first component stored there with zeros. The only array type for which the cleanup could actually result in an overwrite were arrays with ``uint256`` or ``bytes32`` as the base element type and in this case the size of the corrupted area was always exactly 32 bytes. The problem affected tuples at any nesting level. This included also structs, which are encoded as tuples in the ABI. Note also that lists of parameters and return values of functions, events and errors are encoded as tuples.\",\n        \"link\": \"https://blog.soliditylang.org/2022/08/08/calldata-tuple-reencoding-head-overflow-bug/\",\n        \"introduced\": \"0.5.8\",\n        \"fixed\": \"0.8.16\",\n        \"severity\": \"medium\",\n        \"conditions\": {\n            \"ABIEncoderV2\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2022-5\",\n        \"name\": \"DirtyBytesArrayToStorage\",\n        \"summary\": \"Copying ``bytes`` arrays from memory or calldata to storage may result in dirty storage values.\",\n        \"description\": \"Copying ``bytes`` arrays from memory or calldata to storage is done in chunks of 32 bytes even if the length is not a multiple of 32. Thereby, extra bytes past the end of the array may be copied from calldata or memory to storage. These dirty bytes may then become observable after a ``.push()`` without arguments to the bytes array in storage, i.e. such a push will not result in a zero value at the end of the array as expected. This bug only affects the legacy code generation pipeline, the new code generation pipeline via IR is not affected.\",\n        \"link\": \"https://blog.soliditylang.org/2022/06/15/dirty-bytes-array-to-storage-bug/\",\n        \"introduced\": \"0.0.1\",\n        \"fixed\": \"0.8.15\",\n        \"severity\": \"low\"\n    },\n    {\n        \"uid\": \"SOL-2022-4\",\n        \"name\": \"InlineAssemblyMemorySideEffects\",\n        \"summary\": \"The Yul optimizer may incorrectly remove memory writes from inline assembly blocks, that do not access solidity variables.\",\n        \"description\": \"The Yul optimizer considers all memory writes in the outermost Yul block that are never read from as unused and removes them. This is valid when that Yul block is the entire Yul program, which is always the case for the Yul code generated by the new via-IR pipeline. Inline assembly blocks are never optimized in isolation when using that pipeline. Instead they are optimized as a part of the whole Yul input. However, the legacy code generation pipeline (which is still the default) runs the Yul optimizer individually on an inline assembly block if the block does not refer to any local variables defined in the surrounding Solidity code. Consequently, memory writes in such inline assembly blocks are removed as well, if the written memory is never read from in the same assembly block, even if the written memory is accessed later, for example by a subsequent inline assembly block.\",\n        \"link\": \"https://blog.soliditylang.org/2022/06/15/inline-assembly-memory-side-effects-bug/\",\n        \"introduced\": \"0.8.13\",\n        \"fixed\": \"0.8.15\",\n        \"severity\": \"medium\",\n        \"conditions\": {\n            \"yulOptimizer\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2022-3\",\n        \"name\": \"DataLocationChangeInInternalOverride\",\n        \"summary\": \"It was possible to change the data location of the parameters or return variables from ``calldata`` to ``memory`` and vice-versa while overriding internal and public functions. This caused invalid code to be generated when calling such a function internally through virtual function calls.\",\n        \"description\": \"When calling external functions, it is irrelevant if the data location of the parameters is ``calldata`` or ``memory``, the encoding of the data does not change. Because of that, changing the data location when overriding external functions is allowed. The compiler incorrectly also allowed a change in the data location for overriding public and internal functions. Since public functions can be called internally as well as externally, this causes invalid code to be generated when such an incorrectly overridden function is called internally through the base contract. The caller provides a memory pointer, but the called function interprets it as a calldata pointer or vice-versa.\",\n        \"link\": \"https://blog.soliditylang.org/2022/05/17/data-location-inheritance-bug/\",\n        \"introduced\": \"0.6.9\",\n        \"fixed\": \"0.8.14\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2022-2\",\n        \"name\": \"NestedCalldataArrayAbiReencodingSizeValidation\",\n        \"summary\": \"ABI-reencoding of nested dynamic calldata arrays did not always perform proper size checks against the size of calldata and could read beyond ``calldatasize()``.\",\n        \"description\": \"Calldata validation for nested dynamic types is deferred until the first access to the nested values. Such an access may for example be a copy to memory or an index or member access to the outer type. While in most such accesses calldata validation correctly checks that the data area of the nested array is completely contained in the passed calldata (i.e. in the range [0, calldatasize()]), this check may not be performed, when ABI encoding such nested types again directly from calldata. For instance, this can happen, if a value in calldata with a nested dynamic array is passed to an external call, used in ``abi.encode`` or emitted as event. In such cases, if the data area of the nested array extends beyond ``calldatasize()``, ABI encoding it did not revert, but continued reading values from beyond ``calldatasize()`` (i.e. zero values).\",\n        \"link\": \"https://blog.soliditylang.org/2022/05/17/calldata-reencode-size-check-bug/\",\n        \"introduced\": \"0.5.8\",\n        \"fixed\": \"0.8.14\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2022-1\",\n        \"name\": \"AbiEncodeCallLiteralAsFixedBytesBug\",\n        \"summary\": \"Literals used for a fixed length bytes parameter in ``abi.encodeCall`` were encoded incorrectly.\",\n        \"description\": \"For the encoding, the compiler only considered the types of the expressions in the second argument of ``abi.encodeCall`` itself, but not the parameter types of the function given as first argument. In almost all cases the abi encoding of the type of the expression matches the abi encoding of the parameter type of the given function. This is because the type checker ensures the expression is implicitly convertible to the respective parameter type. However this is not true for number literals used for fixed bytes types shorter than 32 bytes, nor for string literals used for any fixed bytes type. Number literals were encoded as numbers instead of being shifted to become left-aligned. String literals were encoded as dynamically sized memory strings instead of being converted to a left-aligned bytes value.\",\n        \"link\": \"https://blog.soliditylang.org/2022/03/16/encodecall-bug/\",\n        \"introduced\": \"0.8.11\",\n        \"fixed\": \"0.8.13\",\n        \"severity\": \"very low\"\n\n    },\n    {\n        \"uid\": \"SOL-2021-4\",\n        \"name\": \"UserDefinedValueTypesBug\",\n        \"summary\": \"User defined value types with underlying type shorter than 32 bytes used incorrect storage layout and wasted storage\",\n        \"description\": \"The compiler did not correctly compute the storage layout of user defined value types based on types that are shorter than 32 bytes. It would always use a full storage slot for these types, even if the underlying type was shorter. This was wasteful and might have problems with tooling or contract upgrades.\",\n        \"link\": \"https://blog.soliditylang.org/2021/09/29/user-defined-value-types-bug/\",\n        \"introduced\": \"0.8.8\",\n        \"fixed\": \"0.8.9\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2021-3\",\n        \"name\": \"SignedImmutables\",\n        \"summary\": \"Immutable variables of signed integer type shorter than 256 bits can lead to values with invalid higher order bits if inline assembly is used.\",\n        \"description\": \"When immutable variables of signed integer type shorter than 256 bits are read, their higher order bits were unconditionally set to zero. The correct operation would be to sign-extend the value, i.e. set the higher order bits to one if the sign bit is one. This sign-extension is performed by Solidity just prior to when it matters, i.e. when a value is stored in memory, when it is compared or when a division is performed. Because of that, to our knowledge, the only way to access the value in its unclean state is by reading it through inline assembly.\",\n        \"link\": \"https://blog.soliditylang.org/2021/09/29/signed-immutables-bug/\",\n        \"introduced\": \"0.6.5\",\n        \"fixed\": \"0.8.9\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2021-2\",\n        \"name\": \"ABIDecodeTwoDimensionalArrayMemory\",\n        \"summary\": \"If used on memory byte arrays, result of the function ``abi.decode`` can depend on the contents of memory outside of the actual byte array that is decoded.\",\n        \"description\": \"The ABI specification uses pointers to data areas for everything that is dynamically-sized. When decoding data from memory (instead of calldata), the ABI decoder did not properly validate some of these pointers. More specifically, it was possible to use large values for the pointers inside arrays such that computing the offset resulted in an undetected overflow. This could lead to these pointers targeting areas in memory outside of the actual area to be decoded. This way, it was possible for ``abi.decode`` to return different values for the same encoded byte array.\",\n        \"link\": \"https://blog.soliditylang.org/2021/04/21/decoding-from-memory-bug/\",\n        \"introduced\": \"0.4.16\",\n        \"fixed\": \"0.8.4\",\n        \"conditions\": {\n            \"ABIEncoderV2\": true\n        },\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2021-1\",\n        \"name\": \"KeccakCaching\",\n        \"summary\": \"The bytecode optimizer incorrectly reused previously evaluated Keccak-256 hashes. You are unlikely to be affected if you do not compute Keccak-256 hashes in inline assembly.\",\n        \"description\": \"Solidity's bytecode optimizer has a step that can compute Keccak-256 hashes, if the contents of the memory are known during compilation time. This step also has a mechanism to determine that two Keccak-256 hashes are equal even if the values in memory are not known during compile time. This mechanism had a bug where Keccak-256 of the same memory content, but different sizes were considered equal. More specifically, ``keccak256(mpos1, length1)`` and ``keccak256(mpos2, length2)`` in some cases were considered equal if ``length1`` and ``length2``, when rounded up to nearest multiple of 32 were the same, and when the memory contents at ``mpos1`` and ``mpos2`` can be deduced to be equal. You maybe affected if you compute multiple Keccak-256 hashes of the same content, but with different lengths inside inline assembly. You are unaffected if your code uses ``keccak256`` with a length that is not a compile-time constant or if it is always a multiple of 32.\",\n        \"link\": \"https://blog.soliditylang.org/2021/03/23/keccak-optimizer-bug/\",\n        \"fixed\": \"0.8.3\",\n        \"conditions\": {\n            \"optimizer\": true\n        },\n        \"severity\": \"medium\"\n    },\n    {\n        \"uid\": \"SOL-2020-11\",\n        \"name\": \"EmptyByteArrayCopy\",\n        \"summary\": \"Copying an empty byte array (or string) from memory or calldata to storage can result in data corruption if the target array's length is increased subsequently without storing new data.\",\n        \"description\": \"The routine that copies byte arrays from memory or calldata to storage stores unrelated data from after the source array in the storage slot if the source array is empty. If the storage array's length is subsequently increased either by using ``.push()`` or by assigning to its ``.length`` attribute (only before 0.6.0), the newly created byte array elements will not be zero-initialized, but contain the unrelated data. You are not affected if you do not assign to ``.length`` and do not use ``.push()`` on byte arrays, or only use ``.push(<arg>)`` or manually initialize the new elements.\",\n        \"link\": \"https://blog.soliditylang.org/2020/10/19/empty-byte-array-copy-bug/\",\n        \"fixed\": \"0.7.4\",\n        \"severity\": \"medium\"\n    },\n    {\n        \"uid\": \"SOL-2020-10\",\n        \"name\": \"DynamicArrayCleanup\",\n        \"summary\": \"When assigning a dynamically-sized array with types of size at most 16 bytes in storage causing the assigned array to shrink, some parts of deleted slots were not zeroed out.\",\n        \"description\": \"Consider a dynamically-sized array in storage whose base-type is small enough such that multiple values can be packed into a single slot, such as `uint128[]`. Let us define its length to be `l`. When this array gets assigned from another array with a smaller length, say `m`, the slots between elements `m` and `l` have to be cleaned by zeroing them out. However, this cleaning was not performed properly. Specifically, after the slot corresponding to `m`, only the first packed value was cleaned up. If this array gets resized to a length larger than `m`, the indices corresponding to the unclean parts of the slot contained the original value, instead of 0. The resizing here is performed by assigning to the array `length`, by a `push()` or via inline assembly. You are not affected if you are only using `.push(<arg>)` or if you assign a value (even zero) to the new elements after increasing the length of the array.\",\n        \"link\": \"https://blog.soliditylang.org/2020/10/07/solidity-dynamic-array-cleanup-bug/\",\n        \"fixed\": \"0.7.3\",\n        \"severity\": \"medium\"\n    },\n    {\n        \"uid\": \"SOL-2020-9\",\n        \"name\": \"FreeFunctionRedefinition\",\n        \"summary\": \"The compiler does not flag an error when two or more free functions with the same name and parameter types are defined in a source unit or when an imported free function alias shadows another free function with a different name but identical parameter types.\",\n        \"description\": \"In contrast to functions defined inside contracts, free functions with identical names and parameter types did not create an error. Both definition of free functions with identical name and parameter types and an imported free function with an alias that shadows another function with a different name but identical parameter types were permitted due to which a call to either the multiply defined free function or the imported free function alias within a contract led to the execution of that free function which was defined first within the source unit. Subsequently defined identical free function definitions were silently ignored and their code generation was skipped.\",\n        \"introduced\": \"0.7.1\",\n        \"fixed\": \"0.7.2\",\n        \"severity\": \"low\"\n    },\n    {\n        \"uid\": \"SOL-2020-8\",\n        \"name\": \"UsingForCalldata\",\n        \"summary\": \"Function calls to internal library functions with calldata parameters called via ``using for`` can result in invalid data being read.\",\n        \"description\": \"Function calls to internal library functions using the ``using for`` mechanism copied all calldata parameters to memory first and passed them on like that, regardless of whether it was an internal or an external call. Due to that, the called function would receive a memory pointer that is interpreted as a calldata pointer. Since dynamically sized arrays are passed using two stack slots for calldata, but only one for memory, this can lead to stack corruption. An affected library call will consider the JUMPDEST to which it is supposed to return as part of its arguments and will instead jump out to whatever was on the stack before the call.\",\n        \"introduced\": \"0.6.9\",\n        \"fixed\": \"0.6.10\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2020-7\",\n        \"name\": \"MissingEscapingInFormatting\",\n        \"summary\": \"String literals containing double backslash characters passed directly to external or encoding function calls can lead to a different string being used when ABIEncoderV2 is enabled.\",\n        \"description\": \"When ABIEncoderV2 is enabled, string literals passed directly to encoding functions or external function calls are stored as strings in the intermediate code. Characters outside the printable range are handled correctly, but backslashes are not escaped in this procedure. This leads to double backslashes being reduced to single backslashes and consequently re-interpreted as escapes potentially resulting in a different string being encoded.\",\n        \"introduced\": \"0.5.14\",\n        \"fixed\": \"0.6.8\",\n        \"severity\": \"very low\",\n        \"conditions\": {\n            \"ABIEncoderV2\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2020-6\",\n        \"name\": \"ArraySliceDynamicallyEncodedBaseType\",\n        \"summary\": \"Accessing array slices of arrays with dynamically encoded base types (e.g. multi-dimensional arrays) can result in invalid data being read.\",\n        \"description\": \"For arrays with dynamically sized base types, index range accesses that use a start expression that is non-zero will result in invalid array slices. Any index access to such array slices will result in data being read from incorrect calldata offsets. Array slices are only supported for dynamic calldata types and all problematic type require ABIEncoderV2 to be enabled.\",\n        \"introduced\": \"0.6.0\",\n        \"fixed\": \"0.6.8\",\n        \"severity\": \"very low\",\n        \"conditions\": {\n            \"ABIEncoderV2\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2020-5\",\n        \"name\": \"ImplicitConstructorCallvalueCheck\",\n        \"summary\": \"The creation code of a contract that does not define a constructor but has a base that does define a constructor did not revert for calls with non-zero value.\",\n        \"description\": \"Starting from Solidity 0.4.5 the creation code of contracts without explicit payable constructor is supposed to contain a callvalue check that results in contract creation reverting, if non-zero value is passed. However, this check was missing in case no explicit constructor was defined in a contract at all, but the contract has a base that does define a constructor. In these cases it is possible to send value in a contract creation transaction or using inline assembly without revert, even though the creation code is supposed to be non-payable.\",\n        \"introduced\": \"0.4.5\",\n        \"fixed\": \"0.6.8\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2020-4\",\n        \"name\": \"TupleAssignmentMultiStackSlotComponents\",\n        \"summary\": \"Tuple assignments with components that occupy several stack slots, i.e. nested tuples, pointers to external functions or references to dynamically sized calldata arrays, can result in invalid values.\",\n        \"description\": \"Tuple assignments did not correctly account for tuple components that occupy multiple stack slots in case the number of stack slots differs between left-hand-side and right-hand-side. This can either happen in the presence of nested tuples or if the right-hand-side contains external function pointers or references to dynamic calldata arrays, while the left-hand-side contains an omission.\",\n        \"introduced\": \"0.1.6\",\n        \"fixed\": \"0.6.6\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2020-3\",\n        \"name\": \"MemoryArrayCreationOverflow\",\n        \"summary\": \"The creation of very large memory arrays can result in overlapping memory regions and thus memory corruption.\",\n        \"description\": \"No runtime overflow checks were performed for the length of memory arrays during creation. In cases for which the memory size of an array in bytes, i.e. the array length times 32, is larger than 2^256-1, the memory allocation will overflow, potentially resulting in overlapping memory areas. The length of the array is still stored correctly, so copying or iterating over such an array will result in out-of-gas.\",\n        \"link\": \"https://blog.soliditylang.org/2020/04/06/memory-creation-overflow-bug/\",\n        \"introduced\": \"0.2.0\",\n        \"fixed\": \"0.6.5\",\n        \"severity\": \"low\"\n    },\n    {\n        \"uid\": \"SOL-2020-1\",\n        \"name\": \"YulOptimizerRedundantAssignmentBreakContinue\",\n        \"summary\": \"The Yul optimizer can remove essential assignments to variables declared inside for loops when Yul's continue or break statement is used. You are unlikely to be affected if you do not use inline assembly with for loops and continue and break statements.\",\n        \"description\": \"The Yul optimizer has a stage that removes assignments to variables that are overwritten again or are not used in all following control-flow branches. This logic incorrectly removes such assignments to variables declared inside a for loop if they can be removed in a control-flow branch that ends with ``break`` or ``continue`` even though they cannot be removed in other control-flow branches. Variables declared outside of the respective for loop are not affected.\",\n        \"introduced\": \"0.6.0\",\n        \"fixed\": \"0.6.1\",\n        \"severity\": \"medium\",\n        \"conditions\": {\n            \"yulOptimizer\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2020-2\",\n        \"name\": \"privateCanBeOverridden\",\n        \"summary\": \"Private methods can be overridden by inheriting contracts.\",\n        \"description\": \"While private methods of base contracts are not visible and cannot be called directly from the derived contract, it is still possible to declare a function of the same name and type and thus change the behaviour of the base contract's function.\",\n        \"introduced\": \"0.3.0\",\n        \"fixed\": \"0.5.17\",\n        \"severity\": \"low\"\n    },\n    {\n        \"uid\": \"SOL-2020-1\",\n        \"name\": \"YulOptimizerRedundantAssignmentBreakContinue0.5\",\n        \"summary\": \"The Yul optimizer can remove essential assignments to variables declared inside for loops when Yul's continue or break statement is used. You are unlikely to be affected if you do not use inline assembly with for loops and continue and break statements.\",\n        \"description\": \"The Yul optimizer has a stage that removes assignments to variables that are overwritten again or are not used in all following control-flow branches. This logic incorrectly removes such assignments to variables declared inside a for loop if they can be removed in a control-flow branch that ends with ``break`` or ``continue`` even though they cannot be removed in other control-flow branches. Variables declared outside of the respective for loop are not affected.\",\n        \"introduced\": \"0.5.8\",\n        \"fixed\": \"0.5.16\",\n        \"severity\": \"low\",\n        \"conditions\": {\n            \"yulOptimizer\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2019-10\",\n        \"name\": \"ABIEncoderV2LoopYulOptimizer\",\n        \"summary\": \"If both the experimental ABIEncoderV2 and the experimental Yul optimizer are activated, one component of the Yul optimizer may reuse data in memory that has been changed in the meantime.\",\n        \"description\": \"The Yul optimizer incorrectly replaces ``mload`` and ``sload`` calls with values that have been previously written to the load location (and potentially changed in the meantime) if all of the following conditions are met: (1) there is a matching ``mstore`` or ``sstore`` call before; (2) the contents of memory or storage is only changed in a function that is called (directly or indirectly) in between the first store and the load call; (3) called function contains a for loop where the same memory location is changed in the condition or the post or body block. When used in Solidity mode, this can only happen if the experimental ABIEncoderV2 is activated and the experimental Yul optimizer has been activated manually in addition to the regular optimizer in the compiler settings.\",\n        \"introduced\": \"0.5.14\",\n        \"fixed\": \"0.5.15\",\n        \"severity\": \"low\",\n        \"conditions\": {\n            \"ABIEncoderV2\": true,\n            \"optimizer\": true,\n            \"yulOptimizer\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2019-9\",\n        \"name\": \"ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers\",\n        \"summary\": \"Reading from calldata structs that contain dynamically encoded, but statically-sized members can result in incorrect values.\",\n        \"description\": \"When a calldata struct contains a dynamically encoded, but statically-sized member, the offsets for all subsequent struct members are calculated incorrectly. All reads from such members will result in invalid values. Only calldata structs are affected, i.e. this occurs in external functions with such structs as argument. Using affected structs in storage or memory or as arguments to public functions on the other hand works correctly.\",\n        \"introduced\": \"0.5.6\",\n        \"fixed\": \"0.5.11\",\n        \"severity\": \"low\",\n        \"conditions\": {\n            \"ABIEncoderV2\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2019-8\",\n        \"name\": \"SignedArrayStorageCopy\",\n        \"summary\": \"Assigning an array of signed integers to a storage array of different type can lead to data corruption in that array.\",\n        \"description\": \"In two's complement, negative integers have their higher order bits set. In order to fit into a shared storage slot, these have to be set to zero. When a conversion is done at the same time, the bits to set to zero were incorrectly determined from the source and not the target type. This means that such copy operations can lead to incorrect values being stored.\",\n        \"link\": \"https://blog.soliditylang.org/2019/06/25/solidity-storage-array-bugs/\",\n        \"introduced\": \"0.4.7\",\n        \"fixed\": \"0.5.10\",\n        \"severity\": \"low/medium\"\n    },\n    {\n        \"uid\": \"SOL-2019-7\",\n        \"name\": \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n        \"summary\": \"Storage arrays containing structs or other statically-sized arrays are not read properly when directly encoded in external function calls or in abi.encode*.\",\n        \"description\": \"When storage arrays whose elements occupy more than a single storage slot are directly encoded in external function calls or using abi.encode*, their elements are read in an overlapping manner, i.e. the element pointer is not properly advanced between reads. This is not a problem when the storage data is first copied to a memory variable or if the storage array only contains value types or dynamically-sized arrays.\",\n        \"link\": \"https://blog.soliditylang.org/2019/06/25/solidity-storage-array-bugs/\",\n        \"introduced\": \"0.4.16\",\n        \"fixed\": \"0.5.10\",\n        \"severity\": \"low\",\n        \"conditions\": {\n            \"ABIEncoderV2\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2019-6\",\n        \"name\": \"DynamicConstructorArgumentsClippedABIV2\",\n        \"summary\": \"A contract's constructor that takes structs or arrays that contain dynamically-sized arrays reverts or decodes to invalid data.\",\n        \"description\": \"During construction of a contract, constructor parameters are copied from the code section to memory for decoding. The amount of bytes to copy was calculated incorrectly in case all parameters are statically-sized but contain dynamically-sized arrays as struct members or inner arrays. Such types are only available if ABIEncoderV2 is activated.\",\n        \"introduced\": \"0.4.16\",\n        \"fixed\": \"0.5.9\",\n        \"severity\": \"very low\",\n        \"conditions\": {\n            \"ABIEncoderV2\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2019-5\",\n        \"name\": \"UninitializedFunctionPointerInConstructor\",\n        \"summary\": \"Calling uninitialized internal function pointers created in the constructor does not always revert and can cause unexpected behaviour.\",\n        \"description\": \"Uninitialized internal function pointers point to a special piece of code that causes a revert when called. Jump target positions are different during construction and after deployment, but the code for setting this special jump target only considered the situation after deployment.\",\n        \"introduced\": \"0.5.0\",\n        \"fixed\": \"0.5.8\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2019-5\",\n        \"name\": \"UninitializedFunctionPointerInConstructor_0.4.x\",\n        \"summary\": \"Calling uninitialized internal function pointers created in the constructor does not always revert and can cause unexpected behaviour.\",\n        \"description\": \"Uninitialized internal function pointers point to a special piece of code that causes a revert when called. Jump target positions are different during construction and after deployment, but the code for setting this special jump target only considered the situation after deployment.\",\n        \"introduced\": \"0.4.5\",\n        \"fixed\": \"0.4.26\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2019-4\",\n        \"name\": \"IncorrectEventSignatureInLibraries\",\n        \"summary\": \"Contract types used in events in libraries cause an incorrect event signature hash\",\n        \"description\": \"Instead of using the type `address` in the hashed signature, the actual contract name was used, leading to a wrong hash in the logs.\",\n        \"introduced\": \"0.5.0\",\n        \"fixed\": \"0.5.8\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2019-4\",\n        \"name\": \"IncorrectEventSignatureInLibraries_0.4.x\",\n        \"summary\": \"Contract types used in events in libraries cause an incorrect event signature hash\",\n        \"description\": \"Instead of using the type `address` in the hashed signature, the actual contract name was used, leading to a wrong hash in the logs.\",\n        \"introduced\": \"0.3.0\",\n        \"fixed\": \"0.4.26\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2019-3\",\n        \"name\": \"ABIEncoderV2PackedStorage\",\n        \"summary\": \"Storage structs and arrays with types shorter than 32 bytes can cause data corruption if encoded directly from storage using the experimental ABIEncoderV2.\",\n        \"description\": \"Elements of structs and arrays that are shorter than 32 bytes are not properly decoded from storage when encoded directly (i.e. not via a memory type) using ABIEncoderV2. This can cause corruption in the values themselves but can also overwrite other parts of the encoded data.\",\n        \"link\": \"https://blog.soliditylang.org/2019/03/26/solidity-optimizer-and-abiencoderv2-bug/\",\n        \"introduced\": \"0.5.0\",\n        \"fixed\": \"0.5.7\",\n        \"severity\": \"low\",\n        \"conditions\": {\n            \"ABIEncoderV2\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2019-3\",\n        \"name\": \"ABIEncoderV2PackedStorage_0.4.x\",\n        \"summary\": \"Storage structs and arrays with types shorter than 32 bytes can cause data corruption if encoded directly from storage using the experimental ABIEncoderV2.\",\n        \"description\": \"Elements of structs and arrays that are shorter than 32 bytes are not properly decoded from storage when encoded directly (i.e. not via a memory type) using ABIEncoderV2. This can cause corruption in the values themselves but can also overwrite other parts of the encoded data.\",\n        \"link\": \"https://blog.soliditylang.org/2019/03/26/solidity-optimizer-and-abiencoderv2-bug/\",\n        \"introduced\": \"0.4.19\",\n        \"fixed\": \"0.4.26\",\n        \"severity\": \"low\",\n        \"conditions\": {\n            \"ABIEncoderV2\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2019-2\",\n        \"name\": \"IncorrectByteInstructionOptimization\",\n        \"summary\": \"The optimizer incorrectly handles byte opcodes whose second argument is 31 or a constant expression that evaluates to 31. This can result in unexpected values.\",\n        \"description\": \"The optimizer incorrectly handles byte opcodes that use the constant 31 as second argument. This can happen when performing index access on bytesNN types with a compile-time constant value (not index) of 31 or when using the byte opcode in inline assembly.\",\n        \"link\": \"https://blog.soliditylang.org/2019/03/26/solidity-optimizer-and-abiencoderv2-bug/\",\n        \"introduced\": \"0.5.5\",\n        \"fixed\": \"0.5.7\",\n        \"severity\": \"very low\",\n        \"conditions\": {\n            \"optimizer\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2019-1\",\n        \"name\": \"DoubleShiftSizeOverflow\",\n        \"summary\": \"Double bitwise shifts by large constants whose sum overflows 256 bits can result in unexpected values.\",\n        \"description\": \"Nested logical shift operations whose total shift size is 2**256 or more are incorrectly optimized. This only applies to shifts by numbers of bits that are compile-time constant expressions.\",\n        \"link\": \"https://blog.soliditylang.org/2019/03/26/solidity-optimizer-and-abiencoderv2-bug/\",\n        \"introduced\": \"0.5.5\",\n        \"fixed\": \"0.5.6\",\n        \"severity\": \"low\",\n        \"conditions\": {\n            \"optimizer\": true,\n            \"evmVersion\": \">=constantinople\"\n        }\n    },\n    {\n        \"uid\": \"SOL-2018-4\",\n        \"name\": \"ExpExponentCleanup\",\n        \"summary\": \"Using the ** operator with an exponent of type shorter than 256 bits can result in unexpected values.\",\n        \"description\": \"Higher order bits in the exponent are not properly cleaned before the EXP opcode is applied if the type of the exponent expression is smaller than 256 bits and not smaller than the type of the base. In that case, the result might be larger than expected if the exponent is assumed to lie within the value range of the type. Literal numbers as exponents are unaffected as are exponents or bases of type uint256.\",\n        \"link\": \"https://blog.soliditylang.org/2018/09/13/solidity-bugfix-release/\",\n        \"fixed\": \"0.4.25\",\n        \"severity\": \"medium/high\",\n        \"check\": {\"regex-source\": \"[^/]\\\\*\\\\* *[^/0-9 ]\"}\n    },\n    {\n        \"uid\": \"SOL-2018-3\",\n        \"name\": \"EventStructWrongData\",\n        \"summary\": \"Using structs in events logged wrong data.\",\n        \"description\": \"If a struct is used in an event, the address of the struct is logged instead of the actual data.\",\n        \"link\": \"https://blog.soliditylang.org/2018/09/13/solidity-bugfix-release/\",\n        \"introduced\": \"0.4.17\",\n        \"fixed\": \"0.4.25\",\n        \"severity\": \"very low\",\n        \"check\": {\"ast-compact-json-path\": \"$..[?(@.nodeType === 'EventDefinition')]..[?(@.nodeType === 'UserDefinedTypeName' && @.typeDescriptions.typeString.startsWith('struct'))]\"}\n    },\n    {\n        \"uid\": \"SOL-2018-2\",\n        \"name\": \"NestedArrayFunctionCallDecoder\",\n        \"summary\": \"Calling functions that return multi-dimensional fixed-size arrays can result in memory corruption.\",\n        \"description\": \"If Solidity code calls a function that returns a multi-dimensional fixed-size array, array elements are incorrectly interpreted as memory pointers and thus can cause memory corruption if the return values are accessed. Calling functions with multi-dimensional fixed-size arrays is unaffected as is returning fixed-size arrays from function calls. The regular expression only checks if such functions are present, not if they are called, which is required for the contract to be affected.\",\n        \"link\": \"https://blog.soliditylang.org/2018/09/13/solidity-bugfix-release/\",\n        \"introduced\": \"0.1.4\",\n        \"fixed\": \"0.4.22\",\n        \"severity\": \"medium\",\n        \"check\": {\"regex-source\": \"returns[^;{]*\\\\[\\\\s*[^\\\\] \\\\t\\\\r\\\\n\\\\v\\\\f][^\\\\]]*\\\\]\\\\s*\\\\[\\\\s*[^\\\\] \\\\t\\\\r\\\\n\\\\v\\\\f][^\\\\]]*\\\\][^{;]*[;{]\"}\n    },\n    {\n        \"uid\": \"SOL-2018-1\",\n        \"name\": \"OneOfTwoConstructorsSkipped\",\n        \"summary\": \"If a contract has both a new-style constructor (using the constructor keyword) and an old-style constructor (a function with the same name as the contract) at the same time, one of them will be ignored.\",\n        \"description\": \"If a contract has both a new-style constructor (using the constructor keyword) and an old-style constructor (a function with the same name as the contract) at the same time, one of them will be ignored. There will be a compiler warning about the old-style constructor, so contracts only using new-style constructors are fine.\",\n        \"introduced\": \"0.4.22\",\n        \"fixed\": \"0.4.23\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2017-5\",\n        \"name\": \"ZeroFunctionSelector\",\n        \"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.\",\n        \"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.\",\n        \"fixed\": \"0.4.18\",\n        \"severity\": \"very low\"\n    },\n    {\n        \"uid\": \"SOL-2017-4\",\n        \"name\": \"DelegateCallReturnValue\",\n        \"summary\": \"The low-level .delegatecall() does not return the execution outcome, but converts the value returned by the functioned called to a boolean instead.\",\n        \"description\": \"The return value of the low-level .delegatecall() function is taken from a position in memory, where the call data or the return data resides. This value is interpreted as a boolean and put onto the stack. This means if the called function returns at least 32 zero bytes, .delegatecall() returns false even if the call was successful.\",\n        \"introduced\": \"0.3.0\",\n        \"fixed\": \"0.4.15\",\n        \"severity\": \"low\"\n    },\n    {\n        \"uid\": \"SOL-2017-3\",\n        \"name\": \"ECRecoverMalformedInput\",\n        \"summary\": \"The ecrecover() builtin can return garbage for malformed input.\",\n        \"description\": \"The ecrecover precompile does not properly signal failure for malformed input (especially in the 'v' argument) and thus the Solidity function can return data that was previously present in the return area in memory.\",\n        \"fixed\": \"0.4.14\",\n        \"severity\": \"medium\"\n    },\n    {\n        \"uid\": \"SOL-2017-2\",\n        \"name\": \"SkipEmptyStringLiteral\",\n        \"summary\": \"If \\\"\\\" is used in a function call, the following function arguments will not be correctly passed to the function.\",\n        \"description\": \"If the empty string literal \\\"\\\" is used as an argument in a function call, it is skipped by the encoder. This has the effect that the encoding of all arguments following this is shifted left by 32 bytes and thus the function call data is corrupted.\",\n        \"fixed\": \"0.4.12\",\n        \"severity\": \"low\"\n    },\n    {\n        \"uid\": \"SOL-2017-1\",\n        \"name\": \"ConstantOptimizerSubtraction\",\n        \"summary\": \"In some situations, the optimizer replaces certain numbers in the code with routines that compute different numbers.\",\n        \"description\": \"The optimizer tries to represent any number in the bytecode by routines that compute them with less gas. For some special numbers, an incorrect routine is generated. This could allow an attacker to e.g. trick victims about a specific amount of ether, or function calls to call different functions (or none at all).\",\n        \"link\": \"https://blog.soliditylang.org/2017/05/03/solidity-optimizer-bug/\",\n        \"fixed\": \"0.4.11\",\n        \"severity\": \"low\",\n        \"conditions\": {\n            \"optimizer\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2016-11\",\n        \"name\": \"IdentityPrecompileReturnIgnored\",\n        \"summary\": \"Failure of the identity precompile was ignored.\",\n        \"description\": \"Calls to the identity contract, which is used for copying memory, ignored its return value. On the public chain, calls to the identity precompile can be made in a way that they never fail, but this might be different on private chains.\",\n        \"severity\": \"low\",\n        \"fixed\": \"0.4.7\"\n    },\n    {\n        \"uid\": \"SOL-2016-10\",\n        \"name\": \"OptimizerStateKnowledgeNotResetForJumpdest\",\n        \"summary\": \"The optimizer did not properly reset its internal state at jump destinations, which could lead to data corruption.\",\n        \"description\": \"The optimizer performs symbolic execution at certain stages. At jump destinations, multiple code paths join and thus it has to compute a common state from the incoming edges. Computing this common state was simplified to just use the empty state, but this implementation was not done properly. This bug can cause data corruption.\",\n        \"severity\": \"medium\",\n        \"introduced\": \"0.4.5\",\n        \"fixed\": \"0.4.6\",\n        \"conditions\": {\n            \"optimizer\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2016-9\",\n        \"name\": \"HighOrderByteCleanStorage\",\n        \"summary\": \"For short types, the high order bytes were not cleaned properly and could overwrite existing data.\",\n        \"description\": \"Types shorter than 32 bytes are packed together into the same 32 byte storage slot, but storage writes always write 32 bytes. For some types, the higher order bytes were not cleaned properly, which made it sometimes possible to overwrite a variable in storage when writing to another one.\",\n        \"link\": \"https://blog.soliditylang.org/2016/11/01/security-alert-solidity-variables-can-overwritten-storage/\",\n        \"severity\": \"high\",\n        \"introduced\": \"0.1.6\",\n        \"fixed\": \"0.4.4\"\n    },\n    {\n        \"uid\": \"SOL-2016-8\",\n        \"name\": \"OptimizerStaleKnowledgeAboutSHA3\",\n        \"summary\": \"The optimizer did not properly reset its knowledge about SHA3 operations resulting in some hashes (also used for storage variable positions) not being calculated correctly.\",\n        \"description\": \"The optimizer performs symbolic execution in order to save re-evaluating expressions whose value is already known. This knowledge was not properly reset across control flow paths and thus the optimizer sometimes thought that the result of a SHA3 operation is already present on the stack. This could result in data corruption by accessing the wrong storage slot.\",\n        \"severity\": \"medium\",\n        \"fixed\": \"0.4.3\",\n        \"conditions\": {\n            \"optimizer\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2016-7\",\n        \"name\": \"LibrariesNotCallableFromPayableFunctions\",\n        \"summary\": \"Library functions threw an exception when called from a call that received Ether.\",\n        \"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.\",\n        \"severity\": \"low\",\n        \"introduced\": \"0.4.0\",\n        \"fixed\": \"0.4.2\"\n    },\n    {\n        \"uid\": \"SOL-2016-6\",\n        \"name\": \"SendFailsForZeroEther\",\n        \"summary\": \"The send function did not provide enough gas to the recipient if no Ether was sent with it.\",\n        \"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.\",\n        \"severity\": \"low\",\n        \"fixed\": \"0.4.0\"\n    },\n    {\n        \"uid\": \"SOL-2016-5\",\n        \"name\": \"DynamicAllocationInfiniteLoop\",\n        \"summary\": \"Dynamic allocation of an empty memory array caused an infinite loop and thus an exception.\",\n        \"description\": \"Memory arrays can be created provided a length. If this length is zero, code was generated that did not terminate and thus consumed all gas.\",\n        \"severity\": \"low\",\n        \"fixed\": \"0.3.6\"\n    },\n    {\n        \"uid\": \"SOL-2016-4\",\n        \"name\": \"OptimizerClearStateOnCodePathJoin\",\n        \"summary\": \"The optimizer did not properly reset its internal state at jump destinations, which could lead to data corruption.\",\n        \"description\": \"The optimizer performs symbolic execution at certain stages. At jump destinations, multiple code paths join and thus it has to compute a common state from the incoming edges. Computing this common state was not done correctly. This bug can cause data corruption, but it is probably quite hard to use for targeted attacks.\",\n        \"severity\": \"low\",\n        \"fixed\": \"0.3.6\",\n        \"conditions\": {\n            \"optimizer\": true\n        }\n    },\n    {\n        \"uid\": \"SOL-2016-3\",\n        \"name\": \"CleanBytesHigherOrderBits\",\n        \"summary\": \"The higher order bits of short bytesNN types were not cleaned before comparison.\",\n        \"description\": \"Two variables of type bytesNN were considered different if their higher order bits, which are not part of the actual value, were different. An attacker might use this to reach seemingly unreachable code paths by providing incorrectly formatted input data.\",\n        \"severity\": \"medium/high\",\n        \"fixed\": \"0.3.3\"\n    },\n    {\n        \"uid\": \"SOL-2016-2\",\n        \"name\": \"ArrayAccessCleanHigherOrderBits\",\n        \"summary\": \"Access to array elements for arrays of types with less than 32 bytes did not correctly clean the higher order bits, causing corruption in other array elements.\",\n        \"description\": \"Multiple elements of an array of values that are shorter than 17 bytes are packed into the same storage slot. Writing to a single element of such an array did not properly clean the higher order bytes and thus could lead to data corruption.\",\n        \"severity\": \"medium/high\",\n        \"fixed\": \"0.3.1\"\n    },\n    {\n        \"uid\": \"SOL-2016-1\",\n        \"name\": \"AncientCompiler\",\n        \"summary\": \"This compiler version is ancient and might contain several undocumented or undiscovered bugs.\",\n        \"description\": \"The list of bugs is only kept for compiler versions starting from 0.3.0, so older versions might contain undocumented bugs.\",\n        \"severity\": \"high\",\n        \"fixed\": \"0.3.0\"\n    }\n]\n"
  },
  {
    "path": "docs/bugs.rst",
    "content": ".. index:: Bugs\n\n.. _known_bugs:\n\n##################\nList of Known Bugs\n##################\n\nBelow, you can find a JSON-formatted list of some of the known security-relevant bugs in the\nSolidity compiler. The file itself is hosted in the `GitHub repository\n<https://github.com/argotorg/solidity/blob/develop/docs/bugs.json>`_.\nThe list stretches back as far as version 0.3.0, bugs known to be present only\nin versions preceding that are not listed.\n\nThere is another file called `bugs_by_version.json\n<https://github.com/argotorg/solidity/blob/develop/docs/bugs_by_version.json>`_,\nwhich can be used to check which bugs affect a specific version of the compiler.\n\nContract source verification tools and also other tools interacting with\ncontracts should consult this list according to the following criteria:\n\n- It is mildly suspicious if a contract was compiled with a nightly\n  compiler version instead of a released version. This list does not keep\n  track of unreleased or nightly versions.\n- It is also mildly suspicious if a contract was compiled with a version that was\n  not the most recent at the time the contract was created. For contracts\n  created from other contracts, you have to follow the creation chain\n  back to a transaction and use the date of that transaction as creation date.\n- It is highly suspicious if a contract was compiled with a compiler that\n  contains a known bug and the contract was created at a time where a newer\n  compiler version containing a fix was already released.\n\nThe JSON file of known bugs below is an array of objects, one for each bug,\nwith the following keys:\n\nuid\n    Unique identifier given to the bug in the form of ``SOL-<year>-<number>``.\n    It is possible that multiple entries exists with the same uid. This means\n    multiple version ranges are affected by the same bug.\nname\n    Unique name given to the bug\nsummary\n    Short description of the bug\ndescription\n    Detailed description of the bug\nlink\n    URL of a website with more detailed information, optional\nintroduced\n    The first published compiler version that contained the bug, optional\nfixed\n    The first published compiler version that did not contain the bug anymore\npublish\n    The date at which the bug became known publicly, optional\nseverity\n    Severity of the bug: very low, low, medium, high. Takes into account\n    discoverability in contract tests, likelihood of occurrence and\n    potential damage by exploits.\nconditions\n    Conditions that have to be met to trigger the bug. The following\n    keys can be used:\n    ``optimizer``, Boolean value which\n    means that the optimizer has to be switched on to enable the bug.\n    ``evmVersion``, a string that indicates which EVM version compiler\n    settings trigger the bug. The string can contain comparison\n    operators. For example, ``\">=constantinople\"`` means that the bug\n    is present when the EVM version is set to ``constantinople`` or\n    later.\n    If no conditions are given, assume that the bug is present.\ncheck\n    This field contains different checks that report whether the smart contract\n    contains the bug or not. The first type of check are JavaScript regular\n    expressions that are to be matched against the source code (\"source-regex\")\n    if the bug is present.  If there is no match, then the bug is very likely\n    not present. If there is a match, the bug might be present.  For improved\n    accuracy, the checks should be applied to the source code after stripping\n    comments.\n    The second type of check are patterns to be checked on the compact AST of\n    the Solidity program (\"ast-compact-json-path\"). The specified search query\n    is a `JsonPath <https://github.com/json-path/JsonPath>`_ expression.\n    If at least one path of the Solidity AST matches the query, the bug is\n    likely present.\n\n.. literalinclude:: bugs.json\n   :language: js\n"
  },
  {
    "path": "docs/bugs_by_version.json",
    "content": "{\n    \"0.1.0\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ExpExponentCleanup\",\n            \"ZeroFunctionSelector\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\",\n            \"AncientCompiler\"\n        ],\n        \"released\": \"2015-07-10\"\n    },\n    \"0.1.1\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ExpExponentCleanup\",\n            \"ZeroFunctionSelector\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\",\n            \"AncientCompiler\"\n        ],\n        \"released\": \"2015-08-04\"\n    },\n    \"0.1.2\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ExpExponentCleanup\",\n            \"ZeroFunctionSelector\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\",\n            \"AncientCompiler\"\n        ],\n        \"released\": \"2015-08-20\"\n    },\n    \"0.1.3\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ExpExponentCleanup\",\n            \"ZeroFunctionSelector\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\",\n            \"AncientCompiler\"\n        ],\n        \"released\": \"2015-09-25\"\n    },\n    \"0.1.4\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\",\n            \"AncientCompiler\"\n        ],\n        \"released\": \"2015-09-30\"\n    },\n    \"0.1.5\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\",\n            \"AncientCompiler\"\n        ],\n        \"released\": \"2015-10-07\"\n    },\n    \"0.1.6\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\",\n            \"AncientCompiler\"\n        ],\n        \"released\": \"2015-10-16\"\n    },\n    \"0.1.7\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\",\n            \"AncientCompiler\"\n        ],\n        \"released\": \"2015-11-17\"\n    },\n    \"0.2.0\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\",\n            \"AncientCompiler\"\n        ],\n        \"released\": \"2015-12-02\"\n    },\n    \"0.2.1\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\",\n            \"AncientCompiler\"\n        ],\n        \"released\": \"2016-01-30\"\n    },\n    \"0.2.2\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\",\n            \"AncientCompiler\"\n        ],\n        \"released\": \"2016-02-17\"\n    },\n    \"0.3.0\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\",\n            \"ArrayAccessCleanHigherOrderBits\"\n        ],\n        \"released\": \"2016-03-11\"\n    },\n    \"0.3.1\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\"\n        ],\n        \"released\": \"2016-03-31\"\n    },\n    \"0.3.2\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\",\n            \"CleanBytesHigherOrderBits\"\n        ],\n        \"released\": \"2016-04-18\"\n    },\n    \"0.3.3\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\"\n        ],\n        \"released\": \"2016-05-27\"\n    },\n    \"0.3.4\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\"\n        ],\n        \"released\": \"2016-05-31\"\n    },\n    \"0.3.5\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\",\n            \"DynamicAllocationInfiniteLoop\",\n            \"OptimizerClearStateOnCodePathJoin\"\n        ],\n        \"released\": \"2016-06-10\"\n    },\n    \"0.3.6\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"SendFailsForZeroEther\"\n        ],\n        \"released\": \"2016-08-10\"\n    },\n    \"0.4.0\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"LibrariesNotCallableFromPayableFunctions\"\n        ],\n        \"released\": \"2016-09-08\"\n    },\n    \"0.4.1\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\",\n            \"LibrariesNotCallableFromPayableFunctions\"\n        ],\n        \"released\": \"2016-09-09\"\n    },\n    \"0.4.10\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\"\n        ],\n        \"released\": \"2017-03-15\"\n    },\n    \"0.4.11\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\"\n        ],\n        \"released\": \"2017-05-03\"\n    },\n    \"0.4.12\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\"\n        ],\n        \"released\": \"2017-07-03\"\n    },\n    \"0.4.13\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\"\n        ],\n        \"released\": \"2017-07-06\"\n    },\n    \"0.4.14\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\"\n        ],\n        \"released\": \"2017-07-31\"\n    },\n    \"0.4.15\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\"\n        ],\n        \"released\": \"2017-08-08\"\n    },\n    \"0.4.16\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\"\n        ],\n        \"released\": \"2017-08-24\"\n    },\n    \"0.4.17\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"EventStructWrongData\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\"\n        ],\n        \"released\": \"2017-09-21\"\n    },\n    \"0.4.18\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"EventStructWrongData\",\n            \"NestedArrayFunctionCallDecoder\"\n        ],\n        \"released\": \"2017-10-18\"\n    },\n    \"0.4.19\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ABIEncoderV2PackedStorage_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"EventStructWrongData\",\n            \"NestedArrayFunctionCallDecoder\"\n        ],\n        \"released\": \"2017-11-30\"\n    },\n    \"0.4.2\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\",\n            \"OptimizerStaleKnowledgeAboutSHA3\"\n        ],\n        \"released\": \"2016-09-17\"\n    },\n    \"0.4.20\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ABIEncoderV2PackedStorage_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"EventStructWrongData\",\n            \"NestedArrayFunctionCallDecoder\"\n        ],\n        \"released\": \"2018-02-14\"\n    },\n    \"0.4.21\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ABIEncoderV2PackedStorage_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"EventStructWrongData\",\n            \"NestedArrayFunctionCallDecoder\"\n        ],\n        \"released\": \"2018-03-07\"\n    },\n    \"0.4.22\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ABIEncoderV2PackedStorage_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"EventStructWrongData\",\n            \"OneOfTwoConstructorsSkipped\"\n        ],\n        \"released\": \"2018-04-16\"\n    },\n    \"0.4.23\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ABIEncoderV2PackedStorage_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"EventStructWrongData\"\n        ],\n        \"released\": \"2018-04-19\"\n    },\n    \"0.4.24\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ABIEncoderV2PackedStorage_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"EventStructWrongData\"\n        ],\n        \"released\": \"2018-05-16\"\n    },\n    \"0.4.25\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ABIEncoderV2PackedStorage_0.4.x\"\n        ],\n        \"released\": \"2018-09-12\"\n    },\n    \"0.4.26\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\"\n        ],\n        \"released\": \"2019-04-29\"\n    },\n    \"0.4.3\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"HighOrderByteCleanStorage\"\n        ],\n        \"released\": \"2016-10-25\"\n    },\n    \"0.4.4\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\"\n        ],\n        \"released\": \"2016-10-31\"\n    },\n    \"0.4.5\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\",\n            \"OptimizerStateKnowledgeNotResetForJumpdest\"\n        ],\n        \"released\": \"2016-11-21\"\n    },\n    \"0.4.6\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\",\n            \"IdentityPrecompileReturnIgnored\"\n        ],\n        \"released\": \"2016-11-22\"\n    },\n    \"0.4.7\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\"\n        ],\n        \"released\": \"2016-12-15\"\n    },\n    \"0.4.8\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\"\n        ],\n        \"released\": \"2017-01-13\"\n    },\n    \"0.4.9\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"UninitializedFunctionPointerInConstructor_0.4.x\",\n            \"IncorrectEventSignatureInLibraries_0.4.x\",\n            \"ExpExponentCleanup\",\n            \"NestedArrayFunctionCallDecoder\",\n            \"ZeroFunctionSelector\",\n            \"DelegateCallReturnValue\",\n            \"ECRecoverMalformedInput\",\n            \"SkipEmptyStringLiteral\",\n            \"ConstantOptimizerSubtraction\"\n        ],\n        \"released\": \"2017-01-31\"\n    },\n    \"0.5.0\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor\",\n            \"IncorrectEventSignatureInLibraries\",\n            \"ABIEncoderV2PackedStorage\"\n        ],\n        \"released\": \"2018-11-13\"\n    },\n    \"0.5.1\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor\",\n            \"IncorrectEventSignatureInLibraries\",\n            \"ABIEncoderV2PackedStorage\"\n        ],\n        \"released\": \"2018-12-03\"\n    },\n    \"0.5.10\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"YulOptimizerRedundantAssignmentBreakContinue0.5\",\n            \"ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers\"\n        ],\n        \"released\": \"2019-06-25\"\n    },\n    \"0.5.11\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"YulOptimizerRedundantAssignmentBreakContinue0.5\"\n        ],\n        \"released\": \"2019-08-12\"\n    },\n    \"0.5.12\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"YulOptimizerRedundantAssignmentBreakContinue0.5\"\n        ],\n        \"released\": \"2019-10-01\"\n    },\n    \"0.5.13\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"YulOptimizerRedundantAssignmentBreakContinue0.5\"\n        ],\n        \"released\": \"2019-11-14\"\n    },\n    \"0.5.14\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"YulOptimizerRedundantAssignmentBreakContinue0.5\",\n            \"ABIEncoderV2LoopYulOptimizer\"\n        ],\n        \"released\": \"2019-12-09\"\n    },\n    \"0.5.15\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"YulOptimizerRedundantAssignmentBreakContinue0.5\"\n        ],\n        \"released\": \"2019-12-17\"\n    },\n    \"0.5.16\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\"\n        ],\n        \"released\": \"2020-01-02\"\n    },\n    \"0.5.17\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\"\n        ],\n        \"released\": \"2020-03-17\"\n    },\n    \"0.5.2\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor\",\n            \"IncorrectEventSignatureInLibraries\",\n            \"ABIEncoderV2PackedStorage\"\n        ],\n        \"released\": \"2018-12-19\"\n    },\n    \"0.5.3\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor\",\n            \"IncorrectEventSignatureInLibraries\",\n            \"ABIEncoderV2PackedStorage\"\n        ],\n        \"released\": \"2019-01-22\"\n    },\n    \"0.5.4\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor\",\n            \"IncorrectEventSignatureInLibraries\",\n            \"ABIEncoderV2PackedStorage\"\n        ],\n        \"released\": \"2019-02-12\"\n    },\n    \"0.5.5\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor\",\n            \"IncorrectEventSignatureInLibraries\",\n            \"ABIEncoderV2PackedStorage\",\n            \"IncorrectByteInstructionOptimization\",\n            \"DoubleShiftSizeOverflow\"\n        ],\n        \"released\": \"2019-03-05\"\n    },\n    \"0.5.6\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor\",\n            \"IncorrectEventSignatureInLibraries\",\n            \"ABIEncoderV2PackedStorage\",\n            \"IncorrectByteInstructionOptimization\"\n        ],\n        \"released\": \"2019-03-13\"\n    },\n    \"0.5.7\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"DirtyBytesArrayToStorage\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\",\n            \"UninitializedFunctionPointerInConstructor\",\n            \"IncorrectEventSignatureInLibraries\"\n        ],\n        \"released\": \"2019-03-26\"\n    },\n    \"0.5.8\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"YulOptimizerRedundantAssignmentBreakContinue0.5\",\n            \"ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\",\n            \"DynamicConstructorArgumentsClippedABIV2\"\n        ],\n        \"released\": \"2019-04-30\"\n    },\n    \"0.5.9\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"privateCanBeOverridden\",\n            \"YulOptimizerRedundantAssignmentBreakContinue0.5\",\n            \"ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers\",\n            \"SignedArrayStorageCopy\",\n            \"ABIEncoderV2StorageArrayWithMultiSlotElement\"\n        ],\n        \"released\": \"2019-05-28\"\n    },\n    \"0.6.0\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ArraySliceDynamicallyEncodedBaseType\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\",\n            \"YulOptimizerRedundantAssignmentBreakContinue\"\n        ],\n        \"released\": \"2019-12-17\"\n    },\n    \"0.6.1\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ArraySliceDynamicallyEncodedBaseType\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\"\n        ],\n        \"released\": \"2020-01-02\"\n    },\n    \"0.6.10\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\"\n        ],\n        \"released\": \"2020-06-11\"\n    },\n    \"0.6.11\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\"\n        ],\n        \"released\": \"2020-07-07\"\n    },\n    \"0.6.12\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\"\n        ],\n        \"released\": \"2020-07-22\"\n    },\n    \"0.6.2\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ArraySliceDynamicallyEncodedBaseType\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\"\n        ],\n        \"released\": \"2020-01-27\"\n    },\n    \"0.6.3\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ArraySliceDynamicallyEncodedBaseType\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\"\n        ],\n        \"released\": \"2020-02-18\"\n    },\n    \"0.6.4\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ArraySliceDynamicallyEncodedBaseType\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\",\n            \"MemoryArrayCreationOverflow\"\n        ],\n        \"released\": \"2020-03-10\"\n    },\n    \"0.6.5\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ArraySliceDynamicallyEncodedBaseType\",\n            \"ImplicitConstructorCallvalueCheck\",\n            \"TupleAssignmentMultiStackSlotComponents\"\n        ],\n        \"released\": \"2020-04-06\"\n    },\n    \"0.6.6\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ArraySliceDynamicallyEncodedBaseType\",\n            \"ImplicitConstructorCallvalueCheck\"\n        ],\n        \"released\": \"2020-04-09\"\n    },\n    \"0.6.7\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"MissingEscapingInFormatting\",\n            \"ArraySliceDynamicallyEncodedBaseType\",\n            \"ImplicitConstructorCallvalueCheck\"\n        ],\n        \"released\": \"2020-05-04\"\n    },\n    \"0.6.8\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\"\n        ],\n        \"released\": \"2020-05-14\"\n    },\n    \"0.6.9\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"UsingForCalldata\"\n        ],\n        \"released\": \"2020-06-04\"\n    },\n    \"0.7.0\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\"\n        ],\n        \"released\": \"2020-07-28\"\n    },\n    \"0.7.1\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\",\n            \"FreeFunctionRedefinition\"\n        ],\n        \"released\": \"2020-09-02\"\n    },\n    \"0.7.2\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\",\n            \"DynamicArrayCleanup\"\n        ],\n        \"released\": \"2020-09-28\"\n    },\n    \"0.7.3\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\",\n            \"EmptyByteArrayCopy\"\n        ],\n        \"released\": \"2020-10-07\"\n    },\n    \"0.7.4\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\"\n        ],\n        \"released\": \"2020-10-19\"\n    },\n    \"0.7.5\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\"\n        ],\n        \"released\": \"2020-11-18\"\n    },\n    \"0.7.6\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\"\n        ],\n        \"released\": \"2020-12-16\"\n    },\n    \"0.8.0\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\"\n        ],\n        \"released\": \"2020-12-16\"\n    },\n    \"0.8.1\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\"\n        ],\n        \"released\": \"2021-01-27\"\n    },\n    \"0.8.10\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\"\n        ],\n        \"released\": \"2021-11-09\"\n    },\n    \"0.8.11\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"AbiEncodeCallLiteralAsFixedBytesBug\"\n        ],\n        \"released\": \"2021-12-20\"\n    },\n    \"0.8.12\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"AbiEncodeCallLiteralAsFixedBytesBug\"\n        ],\n        \"released\": \"2022-02-16\"\n    },\n    \"0.8.13\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"StorageWriteRemovalBeforeConditionalTermination\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"InlineAssemblyMemorySideEffects\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\"\n        ],\n        \"released\": \"2022-03-16\"\n    },\n    \"0.8.14\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"StorageWriteRemovalBeforeConditionalTermination\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"InlineAssemblyMemorySideEffects\"\n        ],\n        \"released\": \"2022-05-17\"\n    },\n    \"0.8.15\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"StorageWriteRemovalBeforeConditionalTermination\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\"\n        ],\n        \"released\": \"2022-06-15\"\n    },\n    \"0.8.16\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"StorageWriteRemovalBeforeConditionalTermination\"\n        ],\n        \"released\": \"2022-08-08\"\n    },\n    \"0.8.17\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\"\n        ],\n        \"released\": \"2022-09-08\"\n    },\n    \"0.8.18\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\"\n        ],\n        \"released\": \"2023-02-01\"\n    },\n    \"0.8.19\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\"\n        ],\n        \"released\": \"2023-02-22\"\n    },\n    \"0.8.2\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\",\n            \"KeccakCaching\"\n        ],\n        \"released\": \"2021-03-02\"\n    },\n    \"0.8.20\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\"\n        ],\n        \"released\": \"2023-05-10\"\n    },\n    \"0.8.21\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\"\n        ],\n        \"released\": \"2023-07-19\"\n    },\n    \"0.8.22\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\"\n        ],\n        \"released\": \"2023-10-25\"\n    },\n    \"0.8.23\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\"\n        ],\n        \"released\": \"2023-11-08\"\n    },\n    \"0.8.24\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\"\n        ],\n        \"released\": \"2024-01-25\"\n    },\n    \"0.8.25\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\"\n        ],\n        \"released\": \"2024-03-14\"\n    },\n    \"0.8.26\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\"\n        ],\n        \"released\": \"2024-05-21\"\n    },\n    \"0.8.27\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\"\n        ],\n        \"released\": \"2024-09-04\"\n    },\n    \"0.8.28\": {\n        \"bugs\": [\n            \"TransientStorageClearingHelperCollision\",\n            \"LostStorageArrayWriteOnSlotOverflow\"\n        ],\n        \"released\": \"2024-10-09\"\n    },\n    \"0.8.29\": {\n        \"bugs\": [\n            \"TransientStorageClearingHelperCollision\",\n            \"LostStorageArrayWriteOnSlotOverflow\"\n        ],\n        \"released\": \"2025-03-12\"\n    },\n    \"0.8.3\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\",\n            \"ABIDecodeTwoDimensionalArrayMemory\"\n        ],\n        \"released\": \"2021-03-23\"\n    },\n    \"0.8.30\": {\n        \"bugs\": [\n            \"TransientStorageClearingHelperCollision\",\n            \"LostStorageArrayWriteOnSlotOverflow\"\n        ],\n        \"released\": \"2025-05-07\"\n    },\n    \"0.8.31\": {\n        \"bugs\": [\n            \"TransientStorageClearingHelperCollision\",\n            \"LostStorageArrayWriteOnSlotOverflow\"\n        ],\n        \"released\": \"2025-12-03\"\n    },\n    \"0.8.32\": {\n        \"bugs\": [\n            \"TransientStorageClearingHelperCollision\"\n        ],\n        \"released\": \"2025-12-18\"\n    },\n    \"0.8.33\": {\n        \"bugs\": [\n            \"TransientStorageClearingHelperCollision\"\n        ],\n        \"released\": \"2025-12-18\"\n    },\n    \"0.8.34\": {\n        \"bugs\": [],\n        \"released\": \"2026-02-18\"\n    },\n    \"0.8.4\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\"\n        ],\n        \"released\": \"2021-04-21\"\n    },\n    \"0.8.5\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\"\n        ],\n        \"released\": \"2021-06-10\"\n    },\n    \"0.8.6\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\"\n        ],\n        \"released\": \"2021-06-22\"\n    },\n    \"0.8.7\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"SignedImmutables\"\n        ],\n        \"released\": \"2021-08-11\"\n    },\n    \"0.8.8\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\",\n            \"UserDefinedValueTypesBug\",\n            \"SignedImmutables\"\n        ],\n        \"released\": \"2021-09-27\"\n    },\n    \"0.8.9\": {\n        \"bugs\": [\n            \"LostStorageArrayWriteOnSlotOverflow\",\n            \"VerbatimInvalidDeduplication\",\n            \"FullInlinerNonExpressionSplitArgumentEvaluationOrder\",\n            \"MissingSideEffectsOnSelectorAccess\",\n            \"AbiReencodingHeadOverflowWithStaticArrayCleanup\",\n            \"DirtyBytesArrayToStorage\",\n            \"DataLocationChangeInInternalOverride\",\n            \"NestedCalldataArrayAbiReencodingSizeValidation\"\n        ],\n        \"released\": \"2021-09-29\"\n    }\n}"
  },
  {
    "path": "docs/cheatsheet.rst",
    "content": "**********\nCheatsheet\n**********\n\n.. index:: operator;precedence\n\nOrder of Precedence of Operators\n================================\n\n.. include:: types/operator-precedence-table.rst\n\n.. index:: abi;decode, abi;encode, abi;encodePacked, abi;encodeWithSelector, abi;encodeCall, abi;encodeWithSignature\n\nABI Encoding and Decoding Functions\n===================================\n\n- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: :ref:`ABI <ABI>`-decodes\n  the provided data. The types are given in parentheses as second argument.\n  Example: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))``\n- ``abi.encode(...) returns (bytes memory)``: :ref:`ABI <ABI>`-encodes the given arguments\n- ``abi.encodePacked(...) returns (bytes memory)``: Performs :ref:`packed encoding <abi_packed_mode>` of\n  the given arguments. Note that this encoding can be ambiguous!\n- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: :ref:`ABI <ABI>`-encodes\n  the given arguments starting from the second and prepends the given four-byte selector\n- ``abi.encodeCall(function functionPointer, (...)) returns (bytes memory)``: ABI-encodes a call to ``functionPointer`` with the arguments found in the\n  tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, ...)``\n- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent\n  to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)``\n\n.. index:: bytes;concat, string;concat\n\nMembers of ``bytes`` and  ``string``\n====================================\n\n- ``bytes.concat(...) returns (bytes memory)``: :ref:`Concatenates variable number of\n  arguments to one byte array<bytes-concat>`\n\n- ``string.concat(...) returns (string memory)``: :ref:`Concatenates variable number of\n  arguments to one string array<string-concat>`\n\n.. index:: address;balance, address;codehash, address;send, address;code, address;transfer\n\nMembers of ``address``\n======================\n\n- ``<address>.balance`` (``uint256``): balance of the :ref:`address` in Wei\n- ``<address>.code`` (``bytes memory``): code at the :ref:`address` (can be empty)\n- ``<address>.codehash`` (``bytes32``): the codehash of the :ref:`address`\n- ``<address>.call(bytes memory) returns (bool, bytes memory)``: issue low-level ``CALL`` with the given payload,\n  returns success condition and return data\n- ``<address>.delegatecall(bytes memory) returns (bool, bytes memory)``: issue low-level ``DELEGATECALL`` with the given payload,\n  returns success condition and return data\n- ``<address>.staticcall(bytes memory) returns (bool, bytes memory)``: issue low-level ``STATICCALL`` with the given payload,\n  returns success condition and return data\n- ``<address payable>.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`,\n  returns ``false`` on failure (deprecated)\n- ``<address payable>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure (deprecated)\n\n.. index:: blockhash, blobhash, block, block;basefee, block;blobbasefee, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp\n.. index:: gasleft, msg;data, msg;sender, msg;sig, msg;value, tx;gasprice, tx;origin\n\nBlock and Transaction Properties\n================================\n\n- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks\n- ``blobhash(uint index) returns (bytes32)``: versioned hash of the ``index``-th blob associated with the current transaction.\n  A versioned hash consists of a single byte representing the version (currently ``0x01``), followed by the last 31 bytes\n  of the SHA256 hash of the KZG commitment (`EIP-4844 <https://eips.ethereum.org/EIPS/eip-4844>`_).\n  Returns zero if no blob with the given index exists.\n- ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_)\n- ``block.blobbasefee`` (``uint``): current block's blob base fee (`EIP-7516 <https://eips.ethereum.org/EIPS/eip-7516>`_ and `EIP-4844 <https://eips.ethereum.org/EIPS/eip-4844>`_)\n- ``block.chainid`` (``uint``): current chain id\n- ``block.coinbase`` (``address payable``): current block miner's address\n- ``block.difficulty`` (``uint``): current block difficulty (``EVM < Paris``). For other EVM versions it behaves as a deprecated alias for ``block.prevrandao`` that will be removed in the next breaking release\n- ``block.gaslimit`` (``uint``): current block gaslimit\n- ``block.number`` (``uint``): current block number\n- ``block.prevrandao`` (``uint``): random number provided by the beacon chain (``EVM >= Paris``) (see `EIP-4399 <https://eips.ethereum.org/EIPS/eip-4399>`_ )\n- ``block.timestamp`` (``uint``): current block timestamp in seconds since Unix epoch\n- ``gasleft() returns (uint256)``: remaining gas\n- ``msg.data`` (``bytes``): complete calldata\n- ``msg.sender`` (``address``): sender of the message (current call)\n- ``msg.sig`` (``bytes4``): first four bytes of the calldata (i.e. function identifier)\n- ``msg.value`` (``uint``): number of wei sent with the message\n- ``tx.gasprice`` (``uint``): gas price of the transaction\n- ``tx.origin`` (``address``): sender of the transaction (full call chain)\n\n.. index:: assert, require, revert\n\nValidations and Assertions\n==========================\n\n- ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error)\n- ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use\n  for malformed input or error in external component)\n- ``require(bool condition, string memory message)``: abort execution and revert state changes if\n  condition is ``false`` (use for malformed input or error in external component). Also provide error message.\n- ``revert()``: abort execution and revert state changes\n- ``revert(string memory message)``: abort execution and revert state changes providing an explanatory string\n\n.. index:: cryptography, keccak256, sha256, ripemd160, ecrecover, addmod, mulmod, erc7201\n\nMathematical and Cryptographic Functions\n========================================\n\n- ``keccak256(bytes memory) returns (bytes32)``: compute the Keccak-256 hash of the input\n- ``sha256(bytes memory) returns (bytes32)``: compute the SHA-256 hash of the input\n- ``ripemd160(bytes memory) returns (bytes20)``: compute the RIPEMD-160 hash of the input\n- ``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``: recover address associated with\n  the public key from elliptic curve signature, return zero on error\n- ``addmod(uint x, uint y, uint k) returns (uint)``: compute ``(x + y) % k`` where the addition is performed with\n  arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.\n- ``mulmod(uint x, uint y, uint k) returns (uint)``: compute ``(x * y) % k`` where the multiplication is performed\n  with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.\n- ``erc7201(string memory id) returns (uint)``: compute the base slot of an ``erc7201`` storage namespace.\n  Can be used in compile time context.\n\n.. index:: this, super, selfdestruct\n\nContract-related\n================\n\n- ``this`` (current contract's type): the current contract, explicitly convertible to ``address`` or ``address payable``\n- ``super``: a contract one level higher in the inheritance hierarchy\n- ``selfdestruct(address payable recipient)``: send all funds to the given address and (only on EVMs before Cancun or when invoked within the transaction creating the contract) destroy the contract.\n\n.. index:: type;name, type;creationCode, type;runtimeCode, type;interfaceId, type;min, type;max\n\nType Information\n================\n\n- ``type(C).name`` (``string``): the name of the contract\n- ``type(C).creationCode`` (``bytes memory``): creation bytecode of the given contract, see :ref:`Type Information<meta-type>`.\n- ``type(C).runtimeCode`` (``bytes memory``): runtime bytecode of the given contract, see :ref:`Type Information<meta-type>`.\n- ``type(I).interfaceId`` (``bytes4``): value containing the EIP-165 interface identifier of the given interface, see :ref:`Type Information<meta-type>`.\n- ``type(T).min`` (``T``): the minimum value representable by the integer type ``T``, see :ref:`Type Information<meta-type>`.\n- ``type(T).max`` (``T``): the maximum value representable by the integer type ``T``, see :ref:`Type Information<meta-type>`.\n\n\n.. index:: visibility, public, private, external, internal\n\nFunction Visibility Specifiers\n==============================\n\n.. code-block:: solidity\n    :force:\n\n    function myFunction() <visibility specifier> returns (bool) {\n        return true;\n    }\n\n- ``public``: visible externally and internally (creates a :ref:`getter function<getter-functions>` for storage/state variables)\n- ``private``: only visible in the current contract\n- ``external``: only visible externally (only for functions) - i.e. can only be message-called (via ``this.func``)\n- ``internal``: only visible internally\n\n\n.. index:: modifiers, pure, view, payable, constant, anonymous, indexed\n\nModifiers\n=========\n\n- ``pure`` for functions: Disallows modification or access of state.\n- ``view`` for functions: Disallows modification of state.\n- ``payable`` for functions: Allows them to receive Ether together with a call.\n- ``constant`` for state variables: Disallows assignment (except initialization), does not occupy storage slot.\n- ``immutable`` for state variables: Allows assignment at construction time and is constant when deployed. Is stored in code.\n- ``anonymous`` for events: Does not store event signature as topic.\n- ``indexed`` for event parameters: Stores the parameter as topic.\n- ``virtual`` for functions and modifiers: Allows the function's or modifier's\n  behavior to be changed in derived contracts.\n- ``override``: States that this function, modifier or public state variable changes\n  the behavior of a function or modifier in a base contract.\n\n"
  },
  {
    "path": "docs/common-patterns.rst",
    "content": "###############\nCommon Patterns\n###############\n\n.. index:: withdrawal\n\n.. _withdrawal_pattern:\n\n*************************\nWithdrawal from Contracts\n*************************\n\nThe recommended method of sending funds after an effect\nis using the withdrawal pattern. Although the most intuitive\nmethod of sending Ether, as a result of an effect, is a\ndirect ``transfer`` call, this is not recommended as it\nintroduces a potential security risk. You may read\nmore about this on the :ref:`security_considerations` page.\n\nThe following is an example of the withdrawal pattern in practice in\na contract where the goal is to send the most of some compensation, e.g. Ether, to the\ncontract in order to become the \"richest\", inspired by\n`King of the Ether <https://www.kingoftheether.com/>`_.\n\nIn the following contract, if you are no longer the richest,\nyou receive the funds of the person who is now the richest.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.4;\n\n    contract WithdrawalContract {\n        address public richest;\n        uint public mostSent;\n\n        mapping(address => uint) pendingWithdrawals;\n\n        /// The amount of Ether sent was not higher than\n        /// the currently highest amount.\n        error NotEnoughEther();\n\n        constructor() payable {\n            richest = msg.sender;\n            mostSent = msg.value;\n        }\n\n        function becomeRichest() public payable {\n            if (msg.value <= mostSent) revert NotEnoughEther();\n            pendingWithdrawals[richest] += msg.value;\n            richest = msg.sender;\n            mostSent = msg.value;\n        }\n\n        function withdraw() public {\n            uint amount = pendingWithdrawals[msg.sender];\n            // Remember to zero the pending refund before\n            // sending to prevent reentrancy attacks\n            pendingWithdrawals[msg.sender] = 0;\n            (bool success, ) = payable(msg.sender).call{value: amount}(\"\");\n            require(success);\n        }\n    }\n\nThis is as opposed to the more intuitive sending pattern:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.4;\n\n    contract SendContract {\n        address payable public richest;\n        uint public mostSent;\n\n        /// The amount of Ether sent was not higher than\n        /// the currently highest amount.\n        error NotEnoughEther();\n\n        constructor() payable {\n            richest = payable(msg.sender);\n            mostSent = msg.value;\n        }\n\n        function becomeRichest() public payable {\n            if (msg.value <= mostSent) revert NotEnoughEther();\n            // This line can cause problems (explained below).\n            (bool success, ) = richest.call{value: msg.value}(\"\");\n            require(success);\n            richest = payable(msg.sender);\n            mostSent = msg.value;\n        }\n    }\n\nNotice that, in this example, an attacker could trap the\ncontract into an unusable state by causing ``richest`` to be\nthe address of a contract that has a receive or fallback function\nwhich fails (e.g. by using ``revert()`` or by just\nconsuming more than the 2300 gas stipend transferred to them). That way,\nwhenever ``transfer`` is called to deliver funds to the\n\"poisoned\" contract, it will fail and thus also ``becomeRichest``\nwill fail, with the contract being stuck forever.\n\nIn contrast, if you use the \"withdraw\" pattern from the first example,\nthe attacker can only cause his or her own withdraw to fail and not the\nrest of the contract's workings.\n\n.. index:: access;restricting\n\n******************\nRestricting Access\n******************\n\nRestricting access is a common pattern for contracts.\nNote that you can never restrict any human or computer\nfrom reading the content of your transactions or\nyour contract's state. You can make it a bit harder\nby using encryption, but if your contract is supposed\nto read the data, so will everyone else.\n\nYou can restrict read access to your contract's state\nby **other contracts**. That is actually the default\nunless you declare your state variables ``public``.\n\nFurthermore, you can restrict who can make modifications\nto your contract's state or call your contract's\nfunctions and this is what this section is about.\n\n.. index:: function;modifier\n\nThe use of **function modifiers** makes these\nrestrictions highly readable.\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.4;\n\n    contract AccessRestriction {\n        // These will be assigned at the construction\n        // phase, where `msg.sender` is the account\n        // creating this contract.\n        address public owner = msg.sender;\n        uint public creationTime = block.timestamp;\n\n        // Now follows a list of errors that\n        // this contract can generate together\n        // with a textual explanation in special\n        // comments.\n\n        /// Sender not authorized for this\n        /// operation.\n        error Unauthorized();\n\n        /// Function called too early.\n        error TooEarly();\n\n        /// Not enough Ether sent with function call.\n        error NotEnoughEther();\n\n        // Modifiers can be used to change\n        // the body of a function.\n        // If this modifier is used, it will\n        // prepend a check that only passes\n        // if the function is called from\n        // a certain address.\n        modifier onlyBy(address account)\n        {\n            if (msg.sender != account)\n                revert Unauthorized();\n            // Do not forget the \"_;\"! It will\n            // be replaced by the actual function\n            // body when the modifier is used.\n            _;\n        }\n\n        /// Make `newOwner` the new owner of this\n        /// contract.\n        function changeOwner(address newOwner)\n            public\n            onlyBy(owner)\n        {\n            owner = newOwner;\n        }\n\n        modifier onlyAfter(uint time) {\n            if (block.timestamp < time)\n                revert TooEarly();\n            _;\n        }\n\n        /// Erase ownership information.\n        /// May only be called 6 weeks after\n        /// the contract has been created.\n        function disown()\n            public\n            onlyBy(owner)\n            onlyAfter(creationTime + 6 weeks)\n        {\n            delete owner;\n        }\n\n        // This modifier requires a certain\n        // fee being associated with a function call.\n        // If the caller sent too much, he or she is\n        // refunded, but only after the function body.\n        // This was dangerous before Solidity version 0.4.0,\n        // where it was possible to skip the part after `_;`.\n        modifier costs(uint amount) {\n            if (msg.value < amount)\n                revert NotEnoughEther();\n\n            _;\n            if (msg.value > amount) {\n                (bool success, ) = payable(msg.sender).call{value: msg.value - amount}(\"\");\n                require(success);\n            }\n        }\n\n        function forceOwnerChange(address newOwner)\n            public\n            payable\n            costs(200 ether)\n        {\n            owner = newOwner;\n            // just some example condition\n            if (uint160(owner) & 0 == 1)\n                // This did not refund for Solidity\n                // before version 0.4.0.\n                return;\n            // refund overpaid fees\n        }\n    }\n\nA more specialised way in which access to function\ncalls can be restricted will be discussed\nin the next example.\n\n.. index:: state machine\n\n*************\nState Machine\n*************\n\nContracts often act as a state machine, which means\nthat they have certain **stages** in which they behave\ndifferently or in which different functions can\nbe called. A function call often ends a stage\nand transitions the contract into the next stage\n(especially if the contract models **interaction**).\nIt is also common that some stages are automatically\nreached at a certain point in **time**.\n\nAn example for this is a blind auction contract which\nstarts in the stage \"accepting blinded bids\", then\ntransitions to \"revealing bids\" which is ended by\n\"determine auction outcome\".\n\n.. index:: function;modifier\n\nFunction modifiers can be used in this situation\nto model the states and guard against\nincorrect usage of the contract.\n\nExample\n=======\n\nIn the following example,\nthe modifier ``atStage`` ensures that the function can\nonly be called at a certain stage.\n\nAutomatic timed transitions\nare handled by the modifier ``timedTransitions``, which\nshould be used for all functions.\n\n.. note::\n    **Modifier Order Matters**.\n    If atStage is combined\n    with timedTransitions, make sure that you mention\n    it after the latter, so that the new stage is\n    taken into account.\n\nFinally, the modifier ``transitionNext`` can be used\nto automatically go to the next stage when the\nfunction finishes.\n\n.. note::\n    **Modifier May be Skipped**.\n    This only applies to Solidity before version 0.4.0:\n    Since modifiers are applied by simply replacing\n    code and not by using a function call,\n    the code in the transitionNext modifier\n    can be skipped if the function itself uses\n    return. If you want to do that, make sure\n    to call nextStage manually from those functions.\n    Starting with version 0.4.0, modifier code\n    will run even if the function explicitly returns.\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.4;\n\n    contract StateMachine {\n        enum Stages {\n            AcceptingBlindedBids,\n            RevealBids,\n            AnotherStage,\n            AreWeDoneYet,\n            Finished\n        }\n        /// Function cannot be called at this time.\n        error FunctionInvalidAtThisStage();\n\n        // This is the current stage.\n        Stages public stage = Stages.AcceptingBlindedBids;\n\n        uint public creationTime = block.timestamp;\n\n        modifier atStage(Stages stage_) {\n            if (stage != stage_)\n                revert FunctionInvalidAtThisStage();\n            _;\n        }\n\n        function nextStage() internal {\n            stage = Stages(uint(stage) + 1);\n        }\n\n        // Perform timed transitions. Be sure to mention\n        // this modifier first, otherwise the guards\n        // will not take the new stage into account.\n        modifier timedTransitions() {\n            if (stage == Stages.AcceptingBlindedBids &&\n                        block.timestamp >= creationTime + 10 days)\n                nextStage();\n            if (stage == Stages.RevealBids &&\n                    block.timestamp >= creationTime + 12 days)\n                nextStage();\n            // The other stages transition by transaction\n            _;\n        }\n\n        // Order of the modifiers matters here!\n        function bid()\n            public\n            payable\n            timedTransitions\n            atStage(Stages.AcceptingBlindedBids)\n        {\n            // We will not implement that here\n        }\n\n        function reveal()\n            public\n            timedTransitions\n            atStage(Stages.RevealBids)\n        {\n        }\n\n        // This modifier goes to the next stage\n        // after the function is done.\n        modifier transitionNext()\n        {\n            _;\n            nextStage();\n        }\n\n        function g()\n            public\n            timedTransitions\n            atStage(Stages.AnotherStage)\n            transitionNext\n        {\n        }\n\n        function h()\n            public\n            timedTransitions\n            atStage(Stages.AreWeDoneYet)\n            transitionNext\n        {\n        }\n\n        function i()\n            public\n            timedTransitions\n            atStage(Stages.Finished)\n        {\n        }\n    }\n"
  },
  {
    "path": "docs/conf.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n#\n# Solidity documentation build configuration file, created by\n# sphinx-quickstart on Mon Dec  7 12:32:57 2015.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\nimport sys\nimport os\nimport re\n\nfrom pygments_lexer_solidity import SolidityLexer, YulLexer\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n\nROOT_PATH = os.path.dirname(os.path.realpath(__file__))\n\nsys.path.insert(0, os.path.join(ROOT_PATH, 'ext'))\n\ndef setup(sphinx):\n    sphinx.add_lexer('Solidity', SolidityLexer)\n    sphinx.add_lexer('Yul', YulLexer)\n\n    sphinx.add_css_file('css/fonts.css')\n    sphinx.add_css_file('css/custom.css')\n    sphinx.add_css_file('css/custom-dark.css')\n    sphinx.add_css_file('css/pygments.css')\n\n# -- RTD GitHub configuration ---------------------------------------------\n\n# Taken from:\n# https://github.com/readthedocs/readthedocs.org/blob/e366e7fc8649fbcf1b6d06ecc12c5f7766144c46/readthedocs/projects/constants.py#L350\nGITHUB_REGEXS = [\n    re.compile(r\"github.com/(.+)/(.+)(?:\\.git){1}$\"),\n    # This must come before the one without a / to make sure we don't capture the /\n    re.compile(r\"github.com/(.+)/(.+)/\"),\n    re.compile(r\"github.com/(.+)/(.+)\"),\n    re.compile(r\"github.com:(.+)/(.+)\\.git$\"),\n]\n\n# Taken and adapted from:\n# https://github.com/readthedocs/readthedocs.org/blob/e366e7fc8649fbcf1b6d06ecc12c5f7766144c46/readthedocs/builds/utils.py#L24\ndef get_github_username_repo(url):\n    if \"github\" in url:\n        for regex in GITHUB_REGEXS:\n            match = regex.search(url)\n            if match:\n                return match.groups()\n    return (None, None)\n\ndisplay_github = False\n# NOTE: RTD_DISPLAY_GITHUB, RTD_GITHUB_USER and RTD_GITHUB_REPO are set in the RTD project settings\ngithub_user = os.getenv(\"RTD_GITHUB_USER\")\ngithub_repo = os.getenv(\"RTD_GITHUB_REPO\")\n\nif github_user and github_repo:\n    display_github = True\nelse:\n    git_clone_url = os.getenv(\"READTHEDOCS_GIT_CLONE_URL\")\n    if git_clone_url:\n        github_user, github_repo = get_github_username_repo(git_clone_url)\n        if github_user and github_repo:\n            display_github = True\n\ndisplay_github_env = os.getenv(\"RTD_DISPLAY_GITHUB\")\nif display_github_env:\n    display_github = display_github_env.lower() == \"true\"\n\nhtml_context = {\n    \"display_github\": display_github,\n    \"github_user\": github_user,\n    \"github_repo\": github_repo,\n    \"github_version\": os.getenv(\"READTHEDOCS_VERSION\", \"develop\"),\n    \"conf_py_path\": \"/docs/\",\n}\n\n# -- General configuration ------------------------------------------------\n# If your documentation needs a minimal Sphinx version, state it here.\n#needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx_syntax',\n    'html_extra_template_renderer',\n    'remix_code_links',\n    'sphinx.ext.imgconverter',\n]\n\nsyntax_base_path = 'grammar'\n# generate link anchors compatible with Sphinx-A4Doc’s naming\nsyntax_a4doc_compat_links = True\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix of source filenames.\nsource_suffix = '.rst'\n\n# The encoding of source files.\n#source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = 'Solidity'\nproject_copyright = '2016-2025, The Solidity Authors'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nwith open('../CMakeLists.txt', 'r', encoding='utf8') as f:\n    version = re.search('PROJECT_VERSION \"([^\"]+)\"', f.read()).group(1)\n# The full version, including alpha/beta/rc tags.\nif os.path.isfile('../prerelease.txt') and os.path.getsize('../prerelease.txt') == 0:\n    release = version\nelif os.path.isfile('../prerelease.txt'):\n    with open('../prerelease.txt', 'r', encoding='utf8') as prerelease_file:\n        release = version + '-' + prerelease_file.read()\nelse:\n    release = version + '-develop'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#language = None\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#today = ''\n# Else, today_fmt is used as the format for a strftime call.\n#today_fmt = '%B %d, %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\nexclude_patterns = ['_build', 'contracts', 'types', 'examples', 'grammar']\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\nhighlight_language = 'Solidity'\n\n# A list of ignored prefixes for module index sorting.\n#modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n#keep_warnings = False\n\nsuppress_warnings = [\n    # Suppress sphinx-syntax warnings, in particular `diagram descriptions can't have custom resolver_data`\n    'sphinx_syntax',\n]\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\nhtml_theme = 'sphinx_rtd_theme'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\nhtml_theme_options = {\n    'logo_only': True,\n    'version_selector': True,\n    'language_selector': True,\n}\n\n# Add any paths that contain custom themes here, relative to this directory.\n#html_theme_path = []\n\n# The name for this set of Sphinx documents.  If None, it defaults to\n# \"<project> v<release> documentation\".\n#html_title = None\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\n# html_logo = \"logo.svg\"\n\n# The name of an image file (within the static path) to use as favicon of the\n# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\nhtml_favicon = \"_static/img/favicon.ico\"\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\nhtml_css_files = [\"css/toggle.css\"]\n\nhtml_js_files = [\"js/constants.js\", \"js/initialize.js\", \"js/toggle.js\"]\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\nhtml_extra_path = [\"_static/css\"]\n\n# List of templates of static files to be included in the HTML output.\n# Keys represent paths to input files and values are dicts containing:\n# - target: The path where the rendered template should be placed.\n# - context: A dictionary listing variables that can be used inside the template.\n# All paths must be absolute.\n# Rendered templates are automatically added to html_extra_path setting.\nhtml_extra_templates = {\n    os.path.join(ROOT_PATH, \"robots.txt.template\"): {\n        'target': os.path.join(ROOT_PATH, \"_static/robots.txt\"),\n        'context': {'LATEST_VERSION': version},\n    }\n}\n\n# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,\n# using the given strftime format.\n#html_last_updated_fmt = '%b %d, %Y'\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#html_additional_pages = {}\n\n# If false, no module index is generated.\n#html_domain_indices = True\n\n# If false, no index is generated.\n#html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\n#html_split_index = False\n\n# If true, links to the reST sources are added to the pages.\n#html_show_sourcelink = True\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\nhtml_show_sphinx = False\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n#html_file_suffix = None\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'Soliditydoc'\n\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n# The paper size ('letterpaper' or 'a4paper').\n#'papersize': 'letterpaper',\n\n# The font size ('10pt', '11pt' or '12pt').\n#'pointsize': '10pt',\n\n# Additional stuff for the LaTeX preamble.\n#'preamble': '',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n    ('index', 'solidity.tex', 'Solidity Documentation', 'Ethereum', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\n#latex_logo = None\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#latex_use_parts = False\n\n# If true, show page references after internal links.\n#latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#latex_appendices = []\n\n# If false, no module index is generated.\n#latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n]\n\n# If true, show URL addresses after external links.\n#man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n]\n\n# Documents to append as an appendix to all manuals.\n#texinfo_appendices = []\n\n# If false, no module index is generated.\n#texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#texinfo_no_detailmenu = False\n"
  },
  {
    "path": "docs/contracts/abstract-contracts.rst",
    "content": ".. index:: ! contract;abstract, ! abstract contract\n\n.. _abstract-contract:\n\n******************\nAbstract Contracts\n******************\n\nContracts must be marked as abstract when at least one of their functions is not implemented or when\nthey do not provide arguments for all of their base contract constructors.\nEven if this is not the case, a contract may still be marked abstract, such as when you do not intend\nfor the contract to be created directly. Abstract contracts are similar to :ref:`interfaces` but an\ninterface is more limited in what it can declare.\n\nAn abstract contract is declared using the ``abstract`` keyword as shown in the following example.\nNote that this contract needs to be defined as abstract, because the function ``utterance()`` is declared,\nbut no implementation was provided (no implementation body ``{ }`` was given).\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    abstract contract Feline {\n        function utterance() public virtual returns (bytes32);\n    }\n\nSuch abstract contracts can not be instantiated directly. This is also true, if an abstract contract itself does implement\nall defined functions. The usage of an abstract contract as a base class is shown in the following example:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    abstract contract Feline {\n        function utterance() public pure virtual returns (bytes32);\n    }\n\n    contract Cat is Feline {\n        function utterance() public pure override returns (bytes32) { return \"miaow\"; }\n    }\n\nIf a contract inherits from an abstract contract and does not implement all non-implemented\nfunctions by overriding, it needs to be marked as abstract as well.\n\nNote that a function without implementation is different from\na :ref:`Function Type <function_types>` even though their syntax looks very similar.\n\nExample of function without implementation (a function declaration):\n\n.. code-block:: solidity\n\n    function foo(address) external returns (address);\n\nExample of a declaration of a variable whose type is a function type:\n\n.. code-block:: solidity\n\n    function(address) external returns (address) foo;\n\nAbstract contracts decouple the definition of a contract from its\nimplementation providing better extensibility and self-documentation and\nfacilitating patterns like the `Template method <https://en.wikipedia.org/wiki/Template_method_pattern>`_ and removing code duplication.\nAbstract contracts are useful in the same way that defining methods\nin an interface is useful. It is a way for the designer of the\nabstract contract to say \"any child of mine must implement this method\".\n\n.. note::\n\n  Abstract contracts cannot override an implemented virtual function with an\n  unimplemented one.\n"
  },
  {
    "path": "docs/contracts/constant-state-variables.rst",
    "content": ".. index:: ! constant\n\n.. _constants:\n\n**************************************\nConstant and Immutable State Variables\n**************************************\n\nState variables can be declared as ``constant`` or ``immutable``.\nIn both cases, the variables cannot be modified after the contract has been constructed.\nFor ``constant`` variables, the value has to be fixed at compile-time, while\nfor ``immutable``, it can still be assigned at construction time.\n\nIt is also possible to define ``constant`` variables at the file level.\n\nEvery occurrence of such a variable in the source is replaced by its underlying value\nand the compiler does not reserve a storage slot for it.\nIt cannot be assigned a slot in transient storage using the ``transient`` keyword either.\n\nCompared to regular state variables, the gas costs of constant and immutable variables\nare much lower. For a constant variable, the expression assigned to it is copied to\nall the places where it is accessed and also re-evaluated each time. This allows for local\noptimizations. Immutable variables are evaluated once at construction time and their value\nis copied to all the places in the code where they are accessed. For these values,\n32 bytes are reserved, even if they would fit in fewer bytes. Due to this, constant values\ncan sometimes be cheaper than immutable values.\n\nNot all types for constants and immutables are implemented at this time. The only supported types are\n:ref:`strings <strings>` (only for constants) and :ref:`value types <value-types>`.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.21;\n\n    uint constant X = 32**22 + 8;\n\n    contract C {\n        string constant TEXT = \"abc\";\n        bytes32 constant MY_HASH = keccak256(\"abc\");\n        uint immutable decimals = 18;\n        uint immutable maxBalance;\n        address immutable owner = msg.sender;\n\n        constructor(uint decimals_, address ref) {\n            if (decimals_ != 0)\n                // Immutables are only immutable when deployed.\n                // At construction time they can be assigned to any number of times.\n                decimals = decimals_;\n\n            // Assignments to immutables can even access the environment.\n            maxBalance = ref.balance;\n        }\n\n        function isBalanceTooHigh(address other) public view returns (bool) {\n            return other.balance > maxBalance;\n        }\n    }\n\n\nConstant\n========\n\nFor ``constant`` variables, the value has to be a constant at compile time and it has to be\nassigned where the variable is declared. Any expression\nthat accesses storage, blockchain data (e.g. ``block.timestamp``, ``address(this).balance`` or\n``block.number``) or\nexecution data (``msg.value`` or ``gasleft()``) or makes calls to external contracts is disallowed. Expressions\nthat might have a side-effect on memory allocation are allowed, but those that\nmight have a side-effect on other memory objects are not. The built-in functions\n``keccak256``, ``sha256``, ``ripemd160``, ``ecrecover``, ``addmod`` and ``mulmod``\nare allowed (even though, with the exception of ``keccak256``, they do call external contracts).\n\nThe reason behind allowing side-effects on the memory allocator is that it\nshould be possible to construct complex objects like e.g. lookup-tables.\nThis feature is not yet fully usable.\n\nImmutable\n=========\n\nVariables declared as ``immutable`` are a bit less restricted than those\ndeclared as ``constant``: Immutable variables can be assigned a\nvalue at construction time.\nThe value can be changed at any time before deployment and then it becomes permanent.\n\nOne additional restriction is that immutables can only be assigned to inside expressions for which\nthere is no possibility of being executed after creation.\nThis excludes all modifier definitions and functions other than constructors.\n\nThere are no restrictions on reading immutable variables.\nThe read is even allowed to happen before the variable is written to for the first time because variables in\nSolidity always have a well-defined initial value.\nFor this reason it is also allowed to never explicitly assign a value to an immutable.\n\n.. warning::\n    When accessing immutables at construction time, please keep the :ref:`initialization order\n    <state-variable-initialization-order>` in mind.\n    Even if you provide an explicit initializer, some expressions may end up being evaluated before\n    that initializer, especially when they are at a different level in inheritance hierarchy.\n\n.. note::\n    Before Solidity 0.8.21 initialization of immutable variables was more restrictive.\n    Such variables had to be initialized exactly once at construction time and could not be read\n    before then.\n\nThe contract creation code generated by the compiler will modify the\ncontract's runtime code before it is returned by replacing all references\nto immutables with the values assigned to them. This is important if\nyou are comparing the\nruntime code generated by the compiler with the one actually stored in the\nblockchain. The compiler outputs where these immutables are located in the deployed bytecode\nin the ``immutableReferences`` field of the :ref:`compiler JSON standard output <compiler-api>`.\n"
  },
  {
    "path": "docs/contracts/creating-contracts.rst",
    "content": ".. index:: ! contract;creation, constructor\n\n******************\nCreating Contracts\n******************\n\nContracts can be created \"from outside\" via Ethereum transactions or from within Solidity contracts.\n\nIDEs, such as `Remix <https://remix.ethereum.org/>`_, make the creation process seamless using UI elements.\n\nOne way to create contracts programmatically on Ethereum is via the JavaScript API `web3.js <https://github.com/web3/web3.js>`_.\nIt has a function called `web3.eth.Contract <https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html#new-contract>`_\nto facilitate contract creation.\n\nWhen a contract is created, its :ref:`constructor <constructor>` (a function declared with\nthe ``constructor`` keyword) is executed once.\n\nA constructor is optional. Only one constructor is allowed, which means\noverloading is not supported.\n\nAfter the constructor has executed, the final code of the contract is stored on the\nblockchain. This code includes all public and external functions and all functions\nthat are reachable from there through function calls. The deployed code does not\ninclude the constructor code or internal functions only called from the constructor.\n\n.. index:: constructor;arguments\n\nInternally, constructor arguments are passed :ref:`ABI encoded <ABI>` after the code of\nthe contract itself, but you do not have to care about this if you use ``web3.js``.\n\nIf a contract wants to create another contract, the source code\n(and the binary) of the created contract has to be known to the creator.\nThis means that cyclic creation dependencies are impossible.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.22 <0.9.0;\n\n\n    contract OwnedToken {\n        // `TokenCreator` is a contract type that is defined below.\n        // It is fine to reference it as long as it is not used\n        // to create a new contract.\n        TokenCreator creator;\n        address owner;\n        bytes32 name;\n\n        // This is the constructor which registers the\n        // creator and the assigned name.\n        constructor(bytes32 name_) {\n            // State variables are accessed via their name\n            // and not via e.g. `this.owner`. Functions can\n            // be accessed directly or through `this.f`,\n            // but the latter provides an external view\n            // to the function. Especially in the constructor,\n            // you should not access functions externally,\n            // because the function does not exist yet.\n            // See the next section for details.\n            owner = msg.sender;\n\n            // We perform an explicit type conversion from `address`\n            // to `TokenCreator` and assume that the type of\n            // the calling contract is `TokenCreator`, there is\n            // no real way to verify that.\n            // This does not create a new contract.\n            creator = TokenCreator(msg.sender);\n            name = name_;\n        }\n\n        function changeName(bytes32 newName) public {\n            // Only the creator can alter the name.\n            // We compare the contract based on its\n            // address which can be retrieved by\n            // explicit conversion to address.\n            if (msg.sender == address(creator))\n                name = newName;\n        }\n\n        function transfer(address newOwner) public {\n            // Only the current owner can transfer the token.\n            if (msg.sender != owner) return;\n\n            // We ask the creator contract if the transfer\n            // should proceed by using a function of the\n            // `TokenCreator` contract defined below. If\n            // the call fails (e.g. due to out-of-gas),\n            // the execution also fails here.\n            if (creator.isTokenTransferOK(owner, newOwner))\n                owner = newOwner;\n        }\n    }\n\n\n    contract TokenCreator {\n        function createToken(bytes32 name)\n            public\n            returns (OwnedToken tokenAddress)\n        {\n            // Create a new `Token` contract and return its address.\n            // From the JavaScript side, the return type\n            // of this function is `address`, as this is\n            // the closest type available in the ABI.\n            return new OwnedToken(name);\n        }\n\n        function changeName(OwnedToken tokenAddress, bytes32 name) public {\n            // Again, the external type of `tokenAddress` is\n            // simply `address`.\n            tokenAddress.changeName(name);\n        }\n\n        // Perform checks to determine if transferring a token to the\n        // `OwnedToken` contract should proceed\n        function isTokenTransferOK(address currentOwner, address newOwner)\n            public\n            pure\n            returns (bool ok)\n        {\n            // Check an arbitrary condition to see if transfer should proceed\n            return keccak256(abi.encodePacked(currentOwner, newOwner))[0] == 0x7f;\n        }\n    }\n"
  },
  {
    "path": "docs/contracts/custom-storage-layout.rst",
    "content": ".. index:: ! custom storage layout, ! storage layout specifier, ! layout at, ! base slot\n\n.. _custom-storage-layout:\n\n*********************\nCustom Storage Layout\n*********************\n\nA contract can define an arbitrary location for its storage using the ``layout`` specifier.\nThe contract's state variables, including those inherited from base contracts,\nstart from the specified base slot instead of the default slot zero.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.29;\n\n    contract C layout at 0xAAAA + 0x11 {\n        uint[3] x; // Occupies slots 0xAABB..0xAABD\n    }\n\nAs the above example shows, the specifier uses the ``layout at <base-slot-expression>`` syntax\nand is located in the header of a contract definition.\n\nThe layout specifier can be placed either before or after the inheritance specifier, and can appear at most once.\nThe ``base-slot-expression`` must be an :ref:`integer literal<rational_literals>` expression\nthat can be evaluated at compilation time and yields a value in the range of ``uint256``.\nThe use of constants initialized using such expressions and\nthe :ref:`built-in function erc7201<mathematical-and-cryptographic-functions>` is also allowed.\n\nA custom layout cannot make contract's storage \"wrap around\".\nIf the selected base slot would push the static variables past the end of storage,\nthe compiler will issue an error.\nNote that the data areas of dynamic arrays and mappings are not affected by this check because\ntheir layout is not linear.\nRegardless of the base slot used, their locations are calculated in a way that always puts them\nwithin the range of ``uint256`` and their sizes are not known at compilation time.\n\nWhile there are no other limits placed on the base slot, it is recommended to avoid locations that are\ntoo close to the end of the address space.\nLeaving too little space may complicate contract upgrades or cause problems for contracts that store\nadditional values past their allocated space using inline assembly.\n\nThe storage layout can only be specified for the topmost contract of an inheritance tree, and\naffects locations of all the storage variables in all the contracts in that tree.\nVariables are laid out according to the order of their definitions and the\npositions of their contracts in the :ref:`linearized inheritance hierarchy<multi-inheritance>`\nand a custom base slot preserves their relative positions, shifting them all by the same amount.\n\nThe storage layout cannot be specified for abstract contracts, interfaces and libraries.\nAlso, it is important to note that it does *not* affect transient state variables.\n\nFor details about storage layout and the effect of the layout specifier on it see\n:ref:`layout of storage variables<storage-inplace-encoding>`.\n\n.. warning::\n    The identifiers ``layout`` and ``at`` are not yet reserved as keywords in the language.\n    It is strongly recommended to avoid using them since they will become reserved in a future\n    breaking release.\n"
  },
  {
    "path": "docs/contracts/errors.rst",
    "content": ".. index:: ! error, revert, require, ! selector; of an error\n.. _errors:\n\n*************\nCustom Errors\n*************\n\nErrors in Solidity provide a convenient and gas-efficient way to explain to the\nuser why an operation failed. They can be defined inside and outside of contracts (including interfaces and libraries).\n\nThey have to be used together with the :ref:`revert statement <revert-statement>`\nor the :ref:`require function <assert-and-require-statements>`.\nIn the case of ``revert`` statements, or ``require`` calls where the condition is evaluated to be false,\nall changes in the current call are reverted, and the error data passed back to the caller.\n\nThe example below shows custom error usage with the ``revert`` statement in function ``transferWithRevertError``,\nas well as the newer approach with ``require`` in function ``transferWithRequireError``.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.27;\n\n    /// Insufficient balance for transfer. Needed `required` but only\n    /// `available` available.\n    /// @param available balance available.\n    /// @param required requested amount to transfer.\n    error InsufficientBalance(uint256 available, uint256 required);\n\n    contract TestToken {\n        mapping(address => uint) balance;\n        function transferWithRevertError(address to, uint256 amount) public {\n            if (amount > balance[msg.sender])\n                revert InsufficientBalance({\n                    available: balance[msg.sender],\n                    required: amount\n                });\n            balance[msg.sender] -= amount;\n            balance[to] += amount;\n        }\n        function transferWithRequireError(address to, uint256 amount) public {\n            require(amount <= balance[msg.sender], InsufficientBalance(balance[msg.sender], amount));\n            balance[msg.sender] -= amount;\n            balance[to] += amount;\n        }\n        // ...\n    }\n\nAnother important detail to mention when it comes to using ``require`` with custom errors, is that memory\nallocation for the error-based revert reason will only happen in the reverting case, which, along with\noptimization of constants and string literals makes this about as gas-efficient as the\n``if (!condition) revert CustomError(args)`` pattern.\n\nErrors cannot be overloaded or overridden but are inherited.\nThe same error can be defined in multiple places as long as the scopes are distinct.\nInstances of errors can only be created using ``revert`` statements, or as the second argument to ``require`` functions.\n\nThe error creates data that is then passed to the caller with the revert operation\nto either return to the off-chain component or catch it in a :ref:`try/catch statement <try-catch>`.\nNote that an error can only be caught when coming from an external call,\nreverts happening in internal calls or inside the same function cannot be caught.\n\nIf you do not provide any parameters, the error only needs four bytes of\ndata and you can use :ref:`NatSpec <natspec>` as above\nto further explain the reasons behind the error, which is not stored on chain.\nThis makes this a very cheap and convenient error-reporting feature at the same time.\n\nMore specifically, an error instance is ABI-encoded in the same way as\na function call to a function of the same name and types would be\nand then used as the return data in the ``revert`` opcode.\nThis means that the data consists of a 4-byte selector followed by :ref:`ABI-encoded<abi>` data.\nThe selector consists of the first four bytes of the keccak256-hash of the signature of the error type.\n\n.. note::\n    It is possible for a contract to revert\n    with different errors of the same name or even with errors defined in different places\n    that are indistinguishable by the caller. For the outside, i.e. the ABI,\n    only the name of the error is relevant, not the contract or file where it is defined.\n\nThe statement ``require(condition, \"description\");`` would be equivalent to\n``if (!condition) revert Error(\"description\")`` if you could define ``error Error(string)``.\nNote, however, that ``Error`` is a built-in type and cannot be defined in user-supplied code.\n\nSimilarly, a failing ``assert`` or similar conditions will revert with an error\nof the built-in type ``Panic(uint256)``.\n\n.. note::\n    Error data should only be used to give an indication of failure, but\n    not as a means for control-flow. The reason is that the revert data\n    of inner calls is propagated back through the chain of external calls\n    by default. This means that an inner call\n    can \"forge\" revert data that looks like it could have come from the\n    contract that called it.\n\nMembers of Errors\n=================\n\n- ``error.selector``: A ``bytes4`` value containing the error selector.\n"
  },
  {
    "path": "docs/contracts/events.rst",
    "content": ".. index:: ! event, ! event; anonymous, ! event; indexed, ! event; topic\n\n.. _events:\n\n******\nEvents\n******\n\nSolidity events give an abstraction on top of the EVM's logging functionality.\nApplications can subscribe and listen to these events through the RPC interface of an Ethereum client.\n\nEvents can be defined at file level or as inheritable members of contracts (including interfaces and libraries).\nWhen you call them, they cause the\narguments to be stored in the transaction's log - a special data structure\nin the blockchain. These logs are associated with the address of the contract that emitted them,\nare incorporated into the blockchain, and stay there as long as a block is\naccessible (forever as of now, but this might\nchange in the future). The Log and its event data are not accessible from within\ncontracts (not even from the contract that created them).\n\nIt is possible to request a Merkle proof for logs, so if\nan external entity supplies a contract with such a proof, it can check\nthat the log actually exists inside the blockchain. You have to supply block headers\nbecause the contract can only see the last 256 block hashes.\n\nYou can add the attribute ``indexed`` to up to three parameters which adds them\nto a special data structure known as :ref:`\"topics\" <abi_events>` instead of\nthe data part of the log.\nA topic can only hold a single word (32 bytes) so if you use a :ref:`reference type\n<reference-types>` for an indexed argument, the Keccak-256 hash of the value is stored\nas a topic instead.\n\nAll parameters without the ``indexed`` attribute are :ref:`ABI-encoded <ABI>`\ninto the data part of the log.\n\nTopics allow you to search for events, for example when filtering a sequence of\nblocks for certain events. You can also filter events by the address of the\ncontract that emitted the event.\n\nFor example, the code below uses the web3.js ``subscribe(\"logs\")``\n`method <https://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html#subscribe-logs>`_ to filter\nlogs that match a topic with a certain address value:\n\n.. code-block:: javascript\n\n    var options = {\n        fromBlock: 0,\n        address: web3.eth.defaultAccount,\n        topics: [\"0x0000000000000000000000000000000000000000000000000000000000000000\", null, null]\n    };\n    web3.eth.subscribe('logs', options, function (error, result) {\n        if (!error)\n            console.log(result);\n    })\n        .on(\"data\", function (log) {\n            console.log(log);\n        })\n        .on(\"changed\", function (log) {\n    });\n\n\nThe hash of the signature of the event is one of the topics, except if you\ndeclared the event with the ``anonymous`` specifier. This means that it is\nnot possible to filter for specific anonymous events by name, you can\nonly filter by the contract address. The advantage of anonymous events\nis that they are cheaper to deploy and call. It also allows you to declare\nfour indexed arguments rather than three.\n\n.. note::\n    Since the transaction log only stores the event data and not the type,\n    you have to know the type of the event, including which parameter is\n    indexed and if the event is anonymous in order to correctly interpret\n    the data.\n    In particular, it is possible to \"fake\" the signature of another event\n    using an anonymous event.\n\n.. index:: ! selector; of an event\n\nMembers of Events\n=================\n\n- ``event.selector``: For non-anonymous events, this is a ``bytes32`` value\n  containing the ``keccak256`` hash of the event signature, as used in the default topic.\n\n\nExample\n=======\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.21 <0.9.0;\n\n    contract ClientReceipt {\n        event Deposit(\n            address indexed from,\n            bytes32 indexed id,\n            uint value\n        );\n\n        function deposit(bytes32 id) public payable {\n            // Events are emitted using `emit`, followed by\n            // the name of the event and the arguments\n            // (if any) in parentheses. Any such invocation\n            // (even deeply nested) can be detected from\n            // the JavaScript API by filtering for `Deposit`.\n            emit Deposit(msg.sender, id, msg.value);\n        }\n    }\n\nThe use in the JavaScript API is as follows:\n\n.. code-block:: javascript\n\n    var abi = /* abi as generated by the compiler */;\n    var ClientReceipt = web3.eth.contract(abi);\n    var clientReceipt = ClientReceipt.at(\"0x1234...ab67\" /* address */);\n\n    var depositEvent = clientReceipt.Deposit();\n\n    // watch for changes\n    depositEvent.watch(function(error, result){\n        // result contains non-indexed arguments and topics\n        // given to the `Deposit` call.\n        if (!error)\n            console.log(result);\n    });\n\n\n    // Or pass a callback to start watching immediately\n    var depositEvent = clientReceipt.Deposit(function(error, result) {\n        if (!error)\n            console.log(result);\n    });\n\nThe output of the above looks like the following (trimmed):\n\n.. code-block:: json\n\n    {\n       \"returnValues\": {\n           \"from\": \"0x1111…FFFFCCCC\",\n           \"id\": \"0x50…sd5adb20\",\n           \"value\": \"0x420042\"\n       },\n       \"raw\": {\n           \"data\": \"0x7f…91385\",\n           \"topics\": [\"0xfd4…b4ead7\", \"0x7f…1a91385\"]\n       }\n    }\n\nAdditional Resources for Understanding Events\n=============================================\n\n- `JavaScript documentation <https://github.com/web3/web3.js/blob/1.x/docs/web3-eth-contract.rst#events>`_\n- `Example usage of events <https://github.com/ethchange/smart-exchange/blob/master/lib/contracts/SmartExchange.sol>`_\n- `How to access them in js <https://github.com/ethchange/smart-exchange/blob/master/lib/exchange_transactions.js>`_\n"
  },
  {
    "path": "docs/contracts/function-modifiers.rst",
    "content": ".. index:: ! function;modifier\n\n.. _modifiers:\n\n******************\nFunction Modifiers\n******************\n\nModifiers can be used to change the behavior of functions in a declarative way.\nFor example,\nyou can use a modifier to automatically check a condition prior to executing the function.\n\nModifiers are\ninheritable properties of contracts and may be overridden by derived contracts, but only\nif they are marked ``virtual``. For details, please see\n:ref:`Modifier Overriding <modifier-overriding>`.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.1 <0.9.0;\n\n    contract owned {\n        constructor() { owner = payable(msg.sender); }\n        address payable owner;\n\n        // This contract only defines a modifier but does not use\n        // it: it will be used in derived contracts.\n        // The function body is inserted where the special symbol\n        // `_;` in the definition of a modifier appears.\n        // This means that if the owner calls this function, the\n        // function is executed and otherwise, an exception is\n        // thrown.\n        modifier onlyOwner {\n            require(\n                msg.sender == owner,\n                \"Only owner can call this function.\"\n            );\n            _;\n        }\n    }\n\n    contract priced {\n        // Modifiers can receive arguments:\n        modifier costs(uint price) {\n            if (msg.value >= price) {\n                _;\n            }\n        }\n    }\n\n    contract Register is priced, owned {\n        mapping(address => bool) registeredAddresses;\n        uint price;\n\n        constructor(uint initialPrice) { price = initialPrice; }\n\n        // It is important to also provide the\n        // `payable` keyword here, otherwise the function will\n        // automatically reject all Ether sent to it.\n        function register() public payable costs(price) {\n            registeredAddresses[msg.sender] = true;\n        }\n\n        // This contract inherits the `onlyOwner` modifier from\n        // the `owned` contract. As a result, calls to `changePrice` will\n        // only take effect if they are made by the stored owner.\n        function changePrice(uint price_) public onlyOwner {\n            price = price_;\n        }\n    }\n\n    contract Mutex {\n        bool locked;\n        modifier noReentrancy() {\n            require(\n                !locked,\n                \"Reentrant call.\"\n            );\n            locked = true;\n            _;\n            locked = false;\n        }\n\n        /// This function is protected by a mutex, which means that\n        /// reentrant calls from within `msg.sender.call` cannot call `f` again.\n        /// The `return 7` statement assigns 7 to the return value but still\n        /// executes the statement `locked = false` in the modifier.\n        function f() public noReentrancy returns (uint) {\n            (bool success,) = msg.sender.call(\"\");\n            require(success);\n            return 7;\n        }\n    }\n\nIf you want to access a modifier ``m`` defined in a contract ``C``, you can use ``C.m`` to\nreference it without virtual lookup. It is only possible to use modifiers defined in the current\ncontract or its base contracts. Modifiers can also be defined in libraries but their use is\nlimited to functions of the same library.\n\nMultiple modifiers are applied to a function by specifying them in a\nwhitespace-separated list and are evaluated in the order presented.\n\nModifiers cannot implicitly access or change the arguments and return values of functions they modify.\nTheir values can only be passed to them explicitly at the point of invocation.\n\nIn function modifiers, it is necessary to specify when you want the function to which the modifier is\napplied to be run. The placeholder statement (denoted by a single underscore character ``_``) is used to\ndenote where the body of the function being modified should be inserted. Note that the\nplaceholder operator is different from using underscores as leading or trailing characters in variable\nnames, which is a stylistic choice.\n\nExplicit returns from a modifier or function body only leave the current\nmodifier or function body. Return variables are assigned and\ncontrol flow continues after the ``_`` in the preceding modifier.\n\n.. warning::\n    In an earlier version of Solidity, ``return`` statements in functions\n    having modifiers behaved differently.\n\nAn explicit return from a modifier with ``return;`` does not affect the values returned by the function.\nThe modifier can, however, choose not to execute the function body at all and in that case the return\nvariables are set to their :ref:`default values<default-value>` just as if the function had an empty\nbody.\n\nThe ``_`` symbol can appear in the modifier multiple times. Each occurrence is replaced with\nthe function body, and the function returns the return value of the final occurrence.\n\nArbitrary expressions are allowed for modifier arguments and in this context,\nall symbols visible from the function are visible in the modifier. Symbols\nintroduced in the modifier are not visible in the function (as they might\nchange by overriding).\n"
  },
  {
    "path": "docs/contracts/functions.rst",
    "content": ".. index:: ! functions, ! function;free\n\n.. _functions:\n\n*********\nFunctions\n*********\n\nFunctions can be defined inside and outside of contracts.\n\nFunctions outside of a contract, also called \"free functions\", always have implicit ``internal``\n:ref:`visibility<visibility-and-getters>`. Their code is included in all contracts\nthat call them, similar to internal library functions.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.1 <0.9.0;\n\n    function sum(uint[] memory arr) pure returns (uint s) {\n        for (uint i = 0; i < arr.length; i++)\n            s += arr[i];\n    }\n\n    contract ArrayExample {\n        bool found;\n        function f(uint[] memory arr) public {\n            // This calls the free function internally.\n            // The compiler will add its code to the contract.\n            uint s = sum(arr);\n            require(s >= 10);\n            found = true;\n        }\n    }\n\n.. note::\n    Functions defined outside a contract are still always executed\n    in the context of a contract.\n    They still can call other contracts, send them Ether and destroy the contract that called them,\n    among other things. The main difference to functions defined inside a contract\n    is that free functions do not have direct access to the variable ``this``, storage variables and functions\n    not in their scope.\n\n.. _function-parameters-return-variables:\n\nFunction Parameters and Return Variables\n========================================\n\nFunctions take typed parameters as input and may, unlike in many other\nlanguages, also return an arbitrary number of values as output.\n\nFunction Parameters\n-------------------\n\nFunction parameters are declared the same way as variables, and the name of\nunused parameters can be omitted.\n\nFor example, if you want your contract to accept one kind of external call\nwith two integers, you would use something like the following:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract Simple {\n        uint sum;\n        function taker(uint a, uint b) public {\n            sum = a + b;\n        }\n    }\n\nFunction parameters can be used as any other local variable and they can also be assigned to.\n\n.. index:: return array, return string, array, string, array of strings, dynamic array, variably sized array, return struct, struct\n\nReturn Variables\n----------------\n\nFunction return variables are declared with the same syntax after the\n``returns`` keyword.\n\nFor example, suppose you want to return two results: the sum and the product of\ntwo integers passed as function parameters, then you use something like:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract Simple {\n        function arithmetic(uint a, uint b)\n            public\n            pure\n            returns (uint sum, uint product)\n        {\n            sum = a + b;\n            product = a * b;\n        }\n    }\n\nThe names of return variables can be omitted.\nReturn variables can be used as any other local variable and they\nare initialized with their :ref:`default value <default-value>` and have that\nvalue until they are (re-)assigned.\n\nYou can either explicitly assign to return variables and\nthen leave the function as above,\nor you can provide return values\n(either a single or :ref:`multiple ones<multi-return>`) directly with the ``return``\nstatement:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract Simple {\n        function arithmetic(uint a, uint b)\n            public\n            pure\n            returns (uint sum, uint product)\n        {\n            return (a + b, a * b);\n        }\n    }\n\nIf you use an early ``return`` to leave a function that has return variables,\nyou must provide return values together with the return statement.\n\n.. note::\n    You cannot return some types from non-internal functions.\n    This includes the types listed below and any composite types that recursively contain them:\n\n    - mappings,\n    - internal function types,\n    - reference types with location set to ``storage``,\n    - multi-dimensional arrays (applies only to :ref:`ABI coder v1 <abi_coder>`),\n    - structs (applies only to :ref:`ABI coder v1 <abi_coder>`).\n\n    This restriction does not apply to library functions because of their different :ref:`internal ABI <library-selectors>`.\n\n.. _multi-return:\n\nReturning Multiple Values\n-------------------------\n\nWhen a function has multiple return types, the statement ``return (v0, v1, ..., vn)`` can be used to return multiple values.\nThe number of components must be the same as the number of return variables\nand their types have to match, potentially after an :ref:`implicit conversion <types-conversion-elementary-types>`.\n\n.. _state-mutability:\n\nState Mutability\n================\n\n.. index:: ! view function, function;view\n\n.. _view-functions:\n\nView Functions\n--------------\n\nFunctions can be declared ``view`` in which case they promise not to modify the state.\n\n.. note::\n  If the compiler's EVM target is Byzantium or newer (default) the opcode\n  ``STATICCALL`` is used when ``view`` functions are called, which enforces the state\n  to stay unmodified as part of the EVM execution. For library ``view`` functions\n  ``DELEGATECALL`` is used, because there is no combined ``DELEGATECALL`` and ``STATICCALL``.\n  This means library ``view`` functions do not have run-time checks that prevent state\n  modifications. This should not impact security negatively because library code is\n  usually known at compile-time and the static checker performs compile-time checks.\n\nThe following statements are considered modifying the state:\n\n#. Writing to state variables (storage and transient storage).\n#. :ref:`Emitting events <events>`.\n#. :ref:`Creating other contracts <creating-contracts>`.\n#. Using ``selfdestruct``.\n#. Sending Ether via calls.\n#. Calling any function not marked ``view`` or ``pure``.\n#. Using low-level calls.\n#. Using inline assembly that contains certain opcodes.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.0 <0.9.0;\n\n    contract C {\n        function f(uint a, uint b) public view returns (uint) {\n            return a * (b + 42) + block.timestamp;\n        }\n    }\n\n.. note::\n  ``constant`` on functions used to be an alias to ``view``, but this was dropped in version 0.5.0.\n\n.. note::\n  Getter methods are automatically marked ``view``.\n\n.. note::\n  Prior to version 0.5.0, the compiler did not use the ``STATICCALL`` opcode\n  for ``view`` functions.\n  This enabled state modifications in ``view`` functions through the use of\n  invalid explicit type conversions.\n  By using  ``STATICCALL`` for ``view`` functions, modifications to the\n  state are prevented on the level of the EVM.\n\n.. index:: ! pure function, function;pure\n\n.. _pure-functions:\n\nPure Functions\n--------------\n\nFunctions can be declared ``pure`` in which case they promise not to read from or modify the state.\nIn particular, it should be possible to evaluate a ``pure`` function at compile-time given\nonly its inputs and ``msg.data``, but without any knowledge of the current blockchain state.\nThis means that reading from ``immutable`` variables can be a non-pure operation.\n\n.. note::\n  If the compiler's EVM target is Byzantium or newer (default) the opcode ``STATICCALL`` is used,\n  which does not guarantee that the state is not read, but at least that it is not modified.\n\nIn addition to the list of state modifying statements explained above, the following are considered reading from the state:\n\n#. Reading from state variables (storage and transient storage).\n#. Accessing ``address(this).balance`` or ``<address>.balance``.\n#. Accessing any of the members of ``block``, ``tx``, ``msg`` (with the exception of ``msg.sig`` and ``msg.data``).\n#. Calling any function not marked ``pure``.\n#. Using inline assembly that contains certain opcodes.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.0 <0.9.0;\n\n    contract C {\n        function f(uint a, uint b) public pure returns (uint) {\n            return a * (b + 42);\n        }\n    }\n\nPure functions are able to use the ``revert()`` and ``require()`` functions to revert\npotential state changes when an :ref:`error occurs <assert-and-require>`.\n\nReverting a state change is not considered a \"state modification\", as only changes to the\nstate made previously in code that did not have the ``view`` or ``pure`` restriction\nare reverted and that code has the option to catch the ``revert`` and not pass it on.\n\nThis behavior is also in line with the ``STATICCALL`` opcode.\n\n.. warning::\n  It is not possible to prevent functions from reading the state at the level\n  of the EVM, it is only possible to prevent them from writing to the state\n  (i.e. only ``view`` can be enforced at the EVM level, ``pure`` can not).\n\n.. note::\n  Prior to version 0.5.0, the compiler did not use the ``STATICCALL`` opcode\n  for ``pure`` functions.\n  This enabled state modifications in ``pure`` functions through the use of\n  invalid explicit type conversions.\n  By using  ``STATICCALL`` for ``pure`` functions, modifications to the\n  state are prevented on the level of the EVM.\n\n.. note::\n  Prior to version 0.4.17 the compiler did not enforce that ``pure`` is not reading the state.\n  It is a compile-time type check, which can be circumvented by doing invalid explicit conversions\n  between contract types, because the compiler can verify that the type of the contract does\n  not do state-changing operations, but it cannot check that the contract that will be called\n  at runtime is actually of that type.\n\n.. _special-functions:\n\nSpecial Functions\n=================\n\n.. index:: ! receive ether function, function;receive, ! receive\n\n.. _receive-ether-function:\n\nReceive Ether Function\n----------------------\n\nA contract can have at most one ``receive`` function, declared using\n``receive() external payable { ... }``\n(without the ``function`` keyword).\nThis function cannot have arguments, cannot return anything and must have\n``external`` visibility and ``payable`` state mutability.\nIt can be virtual, can override and can have modifiers.\n\nThe receive function is executed on a\ncall to the contract with empty calldata. This is the function that is executed\non plain Ether transfers (e.g. via ``.send()`` or ``.transfer()``). If no such\nfunction exists, but a payable :ref:`fallback function <fallback-function>`\nexists, the fallback function will be called on a plain Ether transfer. If\nneither a receive Ether nor a payable fallback function is present, the\ncontract cannot receive Ether through a transaction that does not represent a payable function call and throws an\nexception.\n\nIn the worst case, the ``receive`` function can only rely on 2300 gas being\navailable (for example when ``send`` or ``transfer`` is used), leaving little\nroom to perform other operations except basic logging. The following operations\nwill consume more gas than the 2300 gas stipend:\n\n- Writing to storage\n- Creating a contract\n- Calling an external function which consumes a large amount of gas\n- Sending Ether\n\n.. warning::\n    ``send()`` and ``transfer()`` are deprecated and scheduled for removal.\n    See the section on :ref:`send <send-address-member>` and :ref:`transfer <balance-transfer-address-members>` for more information.\n\n.. warning::\n    When Ether is sent directly to a contract (without a function call, i.e. sender uses ``send`` or ``transfer``)\n    but the receiving contract does not define a receive Ether function or a payable fallback function,\n    an exception will be thrown, sending back the Ether (this was different\n    before Solidity v0.4.0). If you want your contract to receive Ether,\n    you have to implement a receive Ether function (using payable fallback functions for receiving Ether is\n    not recommended, since the fallback is invoked and would not fail for interface confusions\n    on the part of the sender).\n\n.. warning::\n    A contract without a receive Ether function can receive Ether as a\n    recipient of a *coinbase transaction* (aka *miner block reward*)\n    or as a destination of a ``selfdestruct``.\n\n    A contract cannot react to such Ether transfers and thus also\n    cannot reject them. This is a design choice of the EVM and\n    Solidity cannot work around it.\n\n    It also means that ``address(this).balance`` can be higher\n    than the sum of some manual accounting implemented in a\n    contract (i.e. having a counter updated in the receive Ether function).\n\nBelow you can see an example of a Sink contract that uses function ``receive``.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    // This contract keeps all Ether sent to it with no way\n    // to get it back.\n    contract Sink {\n        event Received(address, uint);\n        receive() external payable {\n            emit Received(msg.sender, msg.value);\n        }\n    }\n\n.. index:: ! fallback function, function;fallback\n\n.. _fallback-function:\n\nFallback Function\n-----------------\n\nA contract can have at most one ``fallback`` function, declared using either ``fallback () external [payable]``\nor ``fallback (bytes calldata input) external [payable] returns (bytes memory output)``\n(both without the ``function`` keyword).\nThis function must have ``external`` visibility. A fallback function can be virtual, can override\nand can have modifiers.\n\nThe fallback function is executed on a call to the contract if none of the other\nfunctions match the given function signature, or if no data was supplied at\nall and there is no :ref:`receive Ether function <receive-ether-function>`.\nThe fallback function always receives data, but in order to also receive Ether\nit must be marked ``payable``.\n\nIf the version with parameters is used, ``input`` will contain the full data sent to the contract\n(equal to ``msg.data``) and can return data in ``output``. The returned data will not be\nABI-encoded. Instead it will be returned without modifications (not even padding).\n\nIn the worst case, if a payable fallback function is also used in\nplace of a receive function, it can only rely on 2300 gas being\navailable (see :ref:`receive Ether function <receive-ether-function>`\nfor a brief description of the implications of this).\n\nLike any function, the fallback function can execute complex\noperations as long as there is enough gas passed on to it.\n\n.. warning::\n    A ``payable`` fallback function is also executed for\n    plain Ether transfers, if no :ref:`receive Ether function <receive-ether-function>`\n    is present. It is recommended to always define a receive Ether\n    function as well, if you define a payable fallback function\n    to distinguish Ether transfers from interface confusions.\n\n.. note::\n    If you want to decode the input data, you can check the first four bytes\n    for the function selector and then\n    you can use ``abi.decode`` together with the array slice syntax to\n    decode ABI-encoded data:\n    ``(c, d) = abi.decode(input[4:], (uint256, uint256));``\n    Note that this should only be used as a last resort and\n    proper functions should be used instead.\n\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.2 <0.9.0;\n\n    contract Test {\n        uint x;\n        // This function is called for all messages sent to\n        // this contract (there is no other function).\n        // Sending Ether to this contract will cause an exception,\n        // because the fallback function does not have the `payable`\n        // modifier.\n        fallback() external { x = 1; }\n    }\n\n    contract TestPayable {\n        uint x;\n        uint y;\n        // This function is called for all messages sent to\n        // this contract, except plain Ether transfers\n        // (there is no other function except the receive function).\n        // Any call with non-empty calldata to this contract will execute\n        // the fallback function (even if Ether is sent along with the call).\n        fallback() external payable { x = 1; y = msg.value; }\n\n        // This function is called for plain Ether transfers, i.e.\n        // for every call with empty calldata.\n        receive() external payable { x = 2; y = msg.value; }\n    }\n\n    contract Caller {\n        function callTest(Test test) public returns (bool) {\n            (bool success,) = address(test).call(abi.encodeWithSignature(\"nonExistingFunction()\"));\n            require(success);\n            // results in test.x becoming == 1.\n\n            // address(test) will not allow to call ``send`` directly, since ``test`` has no payable\n            // fallback function.\n            // It has to be converted to the ``address payable`` type to even allow calling ``send`` on it.\n            address payable testPayable = payable(address(test));\n\n            // If someone sends Ether to that contract,\n            // the transfer will fail, i.e. this returns false here.\n            // This will report a warning (deprecation)\n            return testPayable.send(2 ether);\n        }\n\n        function callTestPayable(TestPayable test) public returns (bool) {\n            (bool success,) = address(test).call(abi.encodeWithSignature(\"nonExistingFunction()\"));\n            require(success);\n            // results in test.x becoming == 1 and test.y becoming 0.\n            (success,) = address(test).call{value: 1}(abi.encodeWithSignature(\"nonExistingFunction()\"));\n            require(success);\n            // results in test.x becoming == 1 and test.y becoming 1.\n\n            // If someone sends Ether to that contract, the receive function in TestPayable will be called.\n            // Since that function writes to storage, it takes more gas than is available with a\n            // simple ``send`` or ``transfer``. Because of that, we have to use a low-level call.\n            (success,) = address(test).call{value: 2 ether}(\"\");\n            require(success);\n            // results in test.x becoming == 2 and test.y becoming 2 ether.\n\n            return true;\n        }\n    }\n\n.. index:: ! overload\n\n.. _overload-function:\n\nFunction Overloading\n====================\n\nA contract can have multiple functions of the same name but with different parameter\ntypes.\nThis process is called \"overloading\" and also applies to inherited functions.\nThe following example shows overloading of the function\n``f`` in the scope of contract ``A``.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract A {\n        function f(uint value) public pure returns (uint out) {\n            out = value;\n        }\n\n        function f(uint value, bool really) public pure returns (uint out) {\n            if (really)\n                out = value;\n        }\n    }\n\nOverloaded functions are also present in the external interface. It is an error if two\nexternally visible functions differ by their Solidity types but not by their external types.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    // This will not compile\n    contract A {\n        function f(B value) public pure returns (B out) {\n            out = value;\n        }\n\n        function f(address value) public pure returns (address out) {\n            out = value;\n        }\n    }\n\n    contract B {\n    }\n\n\nBoth ``f`` function overloads above end up accepting the address type for the ABI although\nthey are considered different inside Solidity.\n\nOverload resolution and Argument matching\n-----------------------------------------\n\nOverloaded functions are selected by matching the function declarations in the current scope\nto the arguments supplied in the function call. Functions are selected as overload candidates\nif all arguments can be implicitly converted to the expected types. If there is not exactly one\ncandidate, resolution fails.\n\n.. note::\n    Return parameters are not taken into account for overload resolution.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract A {\n        function f(uint8 val) public pure returns (uint8 out) {\n            out = val;\n        }\n\n        function f(uint256 val) public pure returns (uint256 out) {\n            out = val;\n        }\n    }\n\nCalling ``f(50)`` would create a type error since ``50`` can be implicitly converted both to ``uint8``\nand ``uint256`` types. On another hand ``f(256)`` would resolve to ``f(uint256)`` overload as ``256`` cannot be implicitly\nconverted to ``uint8``.\n"
  },
  {
    "path": "docs/contracts/inheritance.rst",
    "content": ".. index:: ! inheritance, ! base class, ! contract;base, ! deriving\n\n***********\nInheritance\n***********\n\nSolidity supports multiple inheritance including polymorphism.\n\nPolymorphism means that a function call (internal and external)\nalways executes the function of the same name (and parameter types)\nin the most derived contract in the inheritance hierarchy.\nThis has to be explicitly enabled on each function in the\nhierarchy using the ``virtual`` and ``override`` keywords.\nSee :ref:`Function Overriding <function-overriding>` for more details.\n\nIt is possible to call functions further up in the inheritance\nhierarchy internally by explicitly specifying the contract\nusing ``ContractName.functionName()`` or using ``super.functionName()``\nif you want to call the function one level higher up in\nthe flattened inheritance hierarchy (see below).\n\nWhen a contract inherits from other contracts, only a single\ncontract is created on the blockchain, and the code from all the base contracts\nis compiled into the created contract. This means that all internal calls\nto functions of base contracts also just use internal function calls\n(``super.f(..)`` will use JUMP and not a message call).\n\nState variable shadowing is considered as an error.  A derived contract can\nonly declare a state variable ``x``, if there is no visible state variable\nwith the same name in any of its bases.\n\nThe general inheritance system is very similar to\n`Python's <https://docs.python.org/3/tutorial/classes.html#inheritance>`_,\nespecially concerning multiple inheritance, but there are also\nsome :ref:`differences <multi-inheritance>`.\n\nDetails are given in the following example.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    contract Owned {\n        address payable owner;\n        constructor() { owner = payable(msg.sender); }\n    }\n\n    // Use `is` to derive from another contract. Derived\n    // contracts can access all non-private members including\n    // internal functions and state variables. These cannot be\n    // accessed externally via `this`, though.\n    contract Emittable is Owned {\n        event Emitted();\n\n        // The keyword `virtual` means that the function can change\n        // its behavior in derived classes (\"overriding\").\n        function emitEvent() virtual public {\n            if (msg.sender == owner)\n                emit Emitted();\n        }\n    }\n\n    // These abstract contracts are only provided to make the\n    // interface known to the compiler. Note the function\n    // without body. If a contract does not implement all\n    // functions it can only be used as an interface.\n    abstract contract Config {\n        function lookup(uint id) public virtual returns (address adr);\n    }\n\n    abstract contract NameReg {\n        function register(bytes32 name) public virtual;\n        function unregister() public virtual;\n    }\n\n    // Multiple inheritance is possible. Note that `Owned` is\n    // also a base class of `Emittable`, yet there is only a single\n    // instance of `Owned` (as for virtual inheritance in C++).\n    contract Named is Owned, Emittable {\n        constructor(bytes32 name) {\n            Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);\n            NameReg(config.lookup(1)).register(name);\n        }\n\n        // Functions can be overridden by another function with the same name and\n        // the same number/types of inputs. If the overriding function has different\n        // types of output parameters, that causes an error.\n        // Both local and message-based function calls take these overrides\n        // into account.\n        // If you want the function to override, you need to use the\n        // `override` keyword. You need to specify the `virtual` keyword again\n        // if you want this function to be overridden again.\n        function emitEvent() public virtual override {\n            if (msg.sender == owner) {\n                Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);\n                NameReg(config.lookup(1)).unregister();\n                // It is still possible to call a specific\n                // overridden function.\n                Emittable.emitEvent();\n            }\n        }\n    }\n\n\n    // If a constructor takes an argument, it needs to be\n    // provided in the header or modifier-invocation-style at\n    // the constructor of the derived contract (see below).\n    contract PriceFeed is Owned, Emittable, Named(\"GoldFeed\") {\n        uint info;\n\n        function updateInfo(uint newInfo) public {\n            if (msg.sender == owner) info = newInfo;\n        }\n\n        // Here, we only specify `override` and not `virtual`.\n        // This means that contracts deriving from `PriceFeed`\n        // cannot change the behavior of `emitEvent` anymore.\n        function emitEvent() public override(Emittable, Named) { Named.emitEvent(); }\n        function get() public view returns(uint r) { return info; }\n    }\n\nNote that above, we call ``Emittable.emitEvent()`` to \"forward\" the\nemit event request. The way this is done is problematic, as\nseen in the following example:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    contract Owned {\n        address payable owner;\n        constructor() { owner = payable(msg.sender); }\n    }\n\n    contract Emittable is Owned {\n        event Emitted();\n\n        function emitEvent() virtual public {\n            if (msg.sender == owner) {\n                emit Emitted();\n            }\n        }\n    }\n\n    contract Base1 is Emittable {\n        event Base1Emitted();\n        function emitEvent() public virtual override {\n            /* Here, we emit an event to simulate some Base1 logic */\n            emit Base1Emitted();\n            Emittable.emitEvent();\n        }\n    }\n\n    contract Base2 is Emittable {\n        event Base2Emitted();\n        function emitEvent() public virtual override {\n            /* Here, we emit an event to simulate some Base2 logic */\n            emit Base2Emitted();\n            Emittable.emitEvent();\n        }\n    }\n\n    contract Final is Base1, Base2 {\n        event FinalEmitted();\n        function emitEvent() public override(Base1, Base2) {\n            /* Here, we emit an event to simulate some Final logic */\n            emit FinalEmitted();\n            Base2.emitEvent();\n        }\n    }\n\nA call to ``Final.emitEvent()`` will call ``Base2.emitEvent`` because we specify it\nexplicitly in the final override, but this function will bypass\n``Base1.emitEvent``, resulting in the following sequence of events:\n``FinalEmitted -> Base2Emitted -> Emitted``, instead of the expected sequence:\n``FinalEmitted -> Base2Emitted -> Base1Emitted -> Emitted``.\nThe way around this is to use ``super``:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    contract Owned {\n        address payable owner;\n        constructor() { owner = payable(msg.sender); }\n    }\n\n    contract Emittable is Owned {\n        event Emitted();\n\n        function emitEvent() virtual public {\n            if (msg.sender == owner) {\n                emit Emitted();\n            }\n        }\n    }\n\n    contract Base1 is Emittable {\n        event Base1Emitted();\n        function emitEvent() public virtual override {\n            /* Here, we emit an event to simulate some Base1 logic */\n            emit Base1Emitted();\n            super.emitEvent();\n        }\n    }\n\n\n    contract Base2 is Emittable {\n        event Base2Emitted();\n        function emitEvent() public virtual override {\n            /* Here, we emit an event to simulate some Base2 logic */\n            emit Base2Emitted();\n            super.emitEvent();\n        }\n    }\n\n    contract Final is Base1, Base2 {\n        event FinalEmitted();\n        function emitEvent() public override(Base1, Base2) {\n            /* Here, we emit an event to simulate some Final logic */\n            emit FinalEmitted();\n            super.emitEvent();\n        }\n    }\n\nIf ``Final`` calls a function of ``super``, it does not simply\ncall this function on one of its base contracts.  Rather, it\ncalls this function on the next base contract in the final\ninheritance graph, so it will call ``Base1.emitEvent()`` (note that\nthe final inheritance sequence is -- starting with the most\nderived contract: Final, Base2, Base1, Emittable, Owned).\nThe actual function that is called when using super is\nnot known in the context of the class where it is used,\nalthough its type is known. This is similar for ordinary\nvirtual method lookup.\n\n.. index:: ! overriding;function\n\n.. _function-overriding:\n\nFunction Overriding\n===================\n\nBase functions can be overridden by inheriting contracts to change their\nbehavior if they are marked as ``virtual``. The overriding function must then\nuse the ``override`` keyword in the function header.\nThe overriding function may only change the visibility of the overridden function from ``external`` to ``public``.\nThe mutability may be changed to a more strict one following the order:\n``nonpayable`` can be overridden by ``view`` and ``pure``. ``view`` can be overridden by ``pure``.\n``payable`` is an exception and cannot be changed to any other mutability.\n\nThe following example demonstrates changing mutability and visibility:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    contract Base\n    {\n        function foo() virtual external view {}\n    }\n\n    contract Middle is Base {}\n\n    contract Inherited is Middle\n    {\n        function foo() override public pure {}\n    }\n\nFor multiple inheritance, the most derived base contracts that define the same\nfunction must be specified explicitly after the ``override`` keyword.\nIn other words, you have to specify all base contracts that define the same function\nand have not yet been overridden by another base contract (on some path through the inheritance graph).\nAdditionally, if a contract inherits the same function from multiple (unrelated)\nbases, it has to explicitly override it:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    contract Base1\n    {\n        function foo() virtual public {}\n    }\n\n    contract Base2\n    {\n        function foo() virtual public {}\n    }\n\n    contract Inherited is Base1, Base2\n    {\n        // Derives from multiple bases defining foo(), so we must explicitly\n        // override it\n        function foo() public override(Base1, Base2) {}\n    }\n\nAn explicit override specifier is not required if\nthe function is defined in a common base contract\nor if there is a unique function in a common base contract\nthat already overrides all other functions.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    contract A { function f() public pure{} }\n    contract B is A {}\n    contract C is A {}\n    // No explicit override required\n    contract D is B, C {}\n\nMore formally, it is not required to override a function (directly or\nindirectly) inherited from multiple bases if there is a base contract\nthat is part of all override paths for the signature, and (1) that\nbase implements the function and no paths from the current contract\nto the base mentions a function with that signature or (2) that base\ndoes not implement the function and there is at most one mention of\nthe function in all paths from the current contract to that base.\n\nIn this sense, an override path for a signature is a path through\nthe inheritance graph that starts at the contract under consideration\nand ends at a contract mentioning a function with that signature\nthat does not override.\n\nIf you do not mark a function that overrides as ``virtual``, derived\ncontracts can no longer change the behavior of that function.\n\n.. note::\n\n  Functions with the ``private`` visibility cannot be ``virtual``.\n\n.. note::\n\n  Functions without implementation have to be marked ``virtual``\n  outside of interfaces. In interfaces, all functions are\n  automatically considered ``virtual``.\n\n.. note::\n\n  Starting from Solidity 0.8.8, the ``override`` keyword is not\n  required when overriding an interface function, except for the\n  case where the function is defined in multiple bases.\n\n\nPublic state variables can override external functions if the\nparameter and return types of the function matches the getter function\nof the variable:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    contract A\n    {\n        function f() external view virtual returns(uint) { return 5; }\n    }\n\n    contract B is A\n    {\n        uint public override f;\n    }\n\n.. note::\n\n  While public state variables can override external functions, they themselves cannot\n  be overridden.\n\n.. index:: ! overriding;modifier\n\n.. _modifier-overriding:\n\nModifier Overriding (deprecated)\n================================\n\nFunction modifiers can override each other. This works in the same way as\n:ref:`function overriding <function-overriding>` (except that there is no overloading for modifiers). The\n``virtual`` keyword must be used on the overridden modifier\nand the ``override`` keyword must be used in the overriding modifier:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    contract Base\n    {\n        // This will report a warning (deprecation)\n        modifier foo() virtual {_;}\n    }\n\n    contract Inherited is Base\n    {\n        modifier foo() override {_;}\n    }\n\n\nIn case of multiple inheritance, all direct base contracts must be specified\nexplicitly:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    contract Base1\n    {\n        // This will report a warning (deprecation)\n        modifier foo() virtual {_;}\n    }\n\n    contract Base2\n    {\n        // This will report a warning (deprecation)\n        modifier foo() virtual {_;}\n    }\n\n    contract Inherited is Base1, Base2\n    {\n        modifier foo() override(Base1, Base2) {_;}\n    }\n\n.. warning::\n    ``virtual`` modifiers are deprecated and scheduled for removal.\n\n\n.. index:: ! constructor\n\n.. _constructor:\n\nConstructors\n============\n\nA constructor is an optional function declared with the ``constructor`` keyword\nwhich is executed upon contract creation, and where you can run contract\ninitialization code.\n\nBefore the constructor code is executed, state variables are initialised to\ntheir specified value if you initialise them inline, or their :ref:`default value<default-value>` if you do not.\n\nAfter the constructor has run, the final code of the contract is deployed\nto the blockchain. The deployment of\nthe code costs additional gas linear to the length of the code.\nThis code includes all functions that are part of the public interface\nand all functions that are reachable from there through function calls.\nIt does not include the constructor code or internal functions that are\nonly called from the constructor.\n\nIf there is no\nconstructor, the contract will assume the default constructor, which is\nequivalent to ``constructor() {}``. For example:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    abstract contract A {\n        uint public a;\n\n        constructor(uint a_) {\n            a = a_;\n        }\n    }\n\n    contract B is A(1) {\n        constructor() {}\n    }\n\nYou can use internal parameters in a constructor (for example storage pointers). In this case,\nthe contract has to be marked :ref:`abstract <abstract-contract>`, because these parameters\ncannot be assigned valid values from outside but only through the constructors of derived contracts.\n\n.. warning::\n    Prior to version 0.4.22, constructors were defined as functions with the same name as the contract.\n    This syntax was deprecated and is not allowed anymore in version 0.5.0.\n\n.. warning::\n    Prior to version 0.7.0, you had to specify the visibility of constructors as either\n    ``internal`` or ``public``.\n\n\n.. index:: ! base;constructor, inheritance list, contract;abstract, abstract contract\n\nArguments for Base Constructors\n===============================\n\nThe constructors of all the base contracts will be called following the\nlinearization rules explained below. If the base constructors have arguments,\nderived contracts need to specify all of them. This can be done in two ways:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    contract Base {\n        uint x;\n        constructor(uint x_) { x = x_; }\n    }\n\n    // Either directly specify in the inheritance list...\n    contract Derived1 is Base(7) {\n        constructor() {}\n    }\n\n    // or through a \"modifier\" of the derived constructor...\n    contract Derived2 is Base {\n        constructor(uint y) Base(y * y) {}\n    }\n\n    // or declare abstract...\n    abstract contract Derived3 is Base {\n    }\n\n    // and have the next concrete derived contract initialize it.\n    contract DerivedFromDerived is Derived3 {\n        constructor() Base(10 + 10) {}\n    }\n\nOne way is directly in the inheritance list (``is Base(7)``).  The other is in\nthe way a modifier is invoked as part of\nthe derived constructor (``Base(y * y)``). The first way to\ndo it is more convenient if the constructor argument is a\nconstant and defines the behavior of the contract or\ndescribes it. The second way has to be used if the\nconstructor arguments of the base depend on those of the\nderived contract. Arguments have to be given either in the\ninheritance list or in modifier-style in the derived constructor.\nSpecifying arguments in both places is an error.\n\nIf a derived contract does not specify the arguments to all of its base\ncontracts' constructors, it must be declared abstract. In that case, when\nanother contract derives from it, that other contract's inheritance list\nor constructor must provide the necessary parameters\nfor all base classes that haven't had their parameters specified (otherwise,\nthat other contract must be declared abstract as well). For example, in the above\ncode snippet, see ``Derived3`` and ``DerivedFromDerived``.\n\n.. index:: ! inheritance;multiple, ! linearization, ! C3 linearization\n\n.. _multi-inheritance:\n\nMultiple Inheritance and Linearization\n======================================\n\nLanguages that allow multiple inheritance have to deal with\nseveral problems.  One is the `Diamond Problem <https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem>`_.\nSolidity is similar to Python in that it uses C3 Linearization\nto force a specific order in the directed acyclic graph (DAG) of base classes. This\nresults in the desirable property of monotonicity but\ndisallows some inheritance graphs. Especially, the order in\nwhich the base classes are given in the ``is`` directive is\nimportant: You have to list the direct base contracts\nin the order from \"most base-like\" to \"most derived\".\nNote that this order is the reverse of the one used in Python.\n\nAnother simplifying way to explain this is that when a function is called that\nis defined multiple times in different contracts, the given bases\nare searched from right to left (left to right in Python) in a depth-first manner,\nstopping at the first match. If a base contract has already been searched, it is skipped.\n\nIn the following code, Solidity will give the\nerror \"Linearization of inheritance graph impossible\".\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract X {}\n    contract A is X {}\n    // This will not compile\n    contract C is A, X {}\n\nThe reason for this is that ``C`` requests ``X`` to override ``A``\n(by specifying ``A, X`` in this order), but ``A`` itself\nrequests to override ``X``, which is a contradiction that\ncannot be resolved.\n\nDue to the fact that you have to explicitly override a function\nthat is inherited from multiple bases without a unique override,\nC3 linearization is not too important in practice.\n\nOne area where inheritance linearization is especially important and perhaps not as clear is when there are multiple constructors in the inheritance hierarchy. The constructors will always be executed in the linearized order, regardless of the order in which their arguments are provided in the inheriting contract's constructor.  For example:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    contract Base1 {\n        constructor() {}\n    }\n\n    contract Base2 {\n        constructor() {}\n    }\n\n    // Constructors are executed in the following order:\n    //  1 - Base1\n    //  2 - Base2\n    //  3 - Derived1\n    contract Derived1 is Base1, Base2 {\n        constructor() Base1() Base2() {}\n    }\n\n    // Constructors are executed in the following order:\n    //  1 - Base2\n    //  2 - Base1\n    //  3 - Derived2\n    contract Derived2 is Base2, Base1 {\n        constructor() Base2() Base1() {}\n    }\n\n    // Constructors are still executed in the following order:\n    //  1 - Base2\n    //  2 - Base1\n    //  3 - Derived3\n    contract Derived3 is Base2, Base1 {\n        constructor() Base1() Base2() {}\n    }\n\n\nInheriting Different Kinds of Members of the Same Name\n======================================================\n\nThe only situations where, due to inheritance, a contract may contain multiple definitions sharing\nthe same name are:\n\n- Overloading of functions.\n- Overriding of virtual functions.\n- Overriding of external virtual functions by state variable getters.\n- Overriding of virtual modifiers.\n- Overloading of events.\n"
  },
  {
    "path": "docs/contracts/interfaces.rst",
    "content": ".. index:: ! contract;interface, ! interface contract\n\n.. _interfaces:\n\n**********\nInterfaces\n**********\n\nInterfaces are similar to abstract contracts, but they cannot have any functions implemented.\nThere are further restrictions:\n\n- They cannot inherit from other contracts, but they can inherit from other interfaces.\n- All declared functions must be external in the interface, even if they are public in the contract.\n- They cannot declare a constructor.\n- They cannot declare state variables.\n- They cannot declare modifiers.\n\nSome of these restrictions might be lifted in the future.\n\nInterfaces are basically limited to what the Contract ABI can represent, and the conversion between the ABI and\nan interface should be possible without any information loss.\n\nInterfaces are denoted by their own keyword:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.2 <0.9.0;\n\n    interface Token {\n        enum TokenType { Fungible, NonFungible }\n        struct Coin { string obverse; string reverse; }\n        function transfer(address recipient, uint amount) external;\n    }\n\nContracts can inherit interfaces as they would inherit other contracts.\n\nAll functions declared in interfaces are implicitly ``virtual`` and any\nfunctions that override them do not need the ``override`` keyword.\nThis does not automatically mean that an overriding function can be overridden again -\nthis is only possible if the overriding function is marked ``virtual``.\n\nInterfaces can inherit from other interfaces. This has the same rules as normal\ninheritance.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.2 <0.9.0;\n\n    interface ParentA {\n        function test() external returns (uint256);\n    }\n\n    interface ParentB {\n        function test() external returns (uint256);\n    }\n\n    interface SubInterface is ParentA, ParentB {\n        // Must redefine test in order to assert that the parent\n        // meanings are compatible.\n        function test() external override(ParentA, ParentB) returns (uint256);\n    }\n\nTypes defined inside interfaces and other contract-like structures\ncan be accessed from other contracts: ``Token.TokenType`` or ``Token.Coin``.\n\n.. warning::\n\n    Interfaces have supported ``enum`` types since :doc:`Solidity version 0.5.0 <050-breaking-changes>`, make\n    sure the pragma version specifies this version as a minimum.\n"
  },
  {
    "path": "docs/contracts/libraries.rst",
    "content": ".. index:: ! library, callcode, delegatecall\n\n.. _libraries:\n\n*********\nLibraries\n*********\n\nLibraries are similar to contracts, but their purpose is that they are deployed\nonly once at a specific address and their code is reused using the ``DELEGATECALL``\n(``CALLCODE`` until Homestead)\nfeature of the EVM. This means that if library functions are called, their code\nis executed in the context of the calling contract, i.e. ``this`` points to the\ncalling contract, and especially the storage from the calling contract can be\naccessed. As a library is an isolated piece of source code, it can only access\nstate variables of the calling contract if they are explicitly supplied (it\nwould have no way to name them, otherwise). Library functions can only be\ncalled directly (i.e. without the use of ``DELEGATECALL``) if they do not modify\nthe state (i.e. if they are ``view`` or ``pure`` functions),\nbecause libraries are assumed to be stateless. In particular, it is\nnot possible to destroy a library.\n\n.. note::\n    Until version 0.4.20, it was possible to destroy libraries by\n    circumventing Solidity's type system. Starting from that version,\n    libraries contain a :ref:`mechanism<call-protection>` that\n    disallows state-modifying functions\n    to be called directly (i.e. without ``DELEGATECALL``).\n\nLibraries can be seen as implicit base contracts of the contracts that use them.\nThey will not be explicitly visible in the inheritance hierarchy, but calls\nto library functions look just like calls to functions of explicit base\ncontracts (using qualified access like ``L.f()``).\nOf course, calls to internal functions\nuse the internal calling convention, which means that all internal types\ncan be passed and types :ref:`stored in memory <data-location>` will be passed by reference and not copied.\nTo realize this in the EVM, the code of internal library functions\nthat are called from a contract\nand all functions called from therein will at compile time be included in the calling\ncontract, and a regular ``JUMP`` call will be used instead of a ``DELEGATECALL``.\n\n.. note::\n    The inheritance analogy breaks down when it comes to public functions.\n    Calling a public library function with ``L.f()`` results in an external call (``DELEGATECALL``\n    to be precise).\n    In contrast, ``A.f()`` is an internal call when ``A`` is a base contract of the current contract.\n\n.. index:: using for, set\n\nThe following example illustrates how to use libraries (but using a manual method,\nbe sure to check out :ref:`using for <using-for>` for a\nmore advanced example to implement a set).\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n\n    // We define a new struct datatype that will be used to\n    // hold its data in the calling contract.\n    struct Data {\n        mapping(uint => bool) flags;\n    }\n\n    library Set {\n        // Note that the first parameter is of type \"storage\n        // reference\" and thus only its storage address and not\n        // its contents is passed as part of the call.  This is a\n        // special feature of library functions.  It is idiomatic\n        // to call the first parameter `self`, if the function can\n        // be seen as a method of that object.\n        function insert(Data storage self, uint value)\n            public\n            returns (bool)\n        {\n            if (self.flags[value])\n                return false; // already there\n            self.flags[value] = true;\n            return true;\n        }\n\n        function remove(Data storage self, uint value)\n            public\n            returns (bool)\n        {\n            if (!self.flags[value])\n                return false; // not there\n            self.flags[value] = false;\n            return true;\n        }\n\n        function contains(Data storage self, uint value)\n            public\n            view\n            returns (bool)\n        {\n            return self.flags[value];\n        }\n    }\n\n\n    contract C {\n        Data knownValues;\n\n        function register(uint value) public {\n            // The library functions can be called without a\n            // specific instance of the library, since the\n            // \"instance\" will be the current contract.\n            require(Set.insert(knownValues, value));\n        }\n        // In this contract, we can also directly access knownValues.flags, if we want.\n    }\n\nOf course, you do not have to follow this way to use\nlibraries: they can also be used without defining struct\ndata types. Functions also work without any storage\nreference parameters, and they can have multiple storage reference\nparameters and in any position.\n\nThe calls to ``Set.contains``, ``Set.insert`` and ``Set.remove``\nare all compiled as calls (``DELEGATECALL``) to an external\ncontract/library. If you use libraries, be aware that an\nactual external function call is performed.\n``msg.sender``, ``msg.value`` and ``this`` will retain their values\nin this call, though (prior to Homestead, because of the use of ``CALLCODE``, ``msg.sender`` and\n``msg.value`` changed, though).\n\nThe following example shows how to use :ref:`types stored in memory <data-location>` and\ninternal functions in libraries in order to implement\ncustom types without the overhead of external function calls:\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.0;\n\n    struct bigint {\n        uint[] limbs;\n    }\n\n    library BigInt {\n        function fromUint(uint x) internal pure returns (bigint memory r) {\n            r.limbs = new uint[](1);\n            r.limbs[0] = x;\n        }\n\n        function add(bigint memory a, bigint memory b) internal pure returns (bigint memory r) {\n            r.limbs = new uint[](max(a.limbs.length, b.limbs.length));\n            uint carry = 0;\n            for (uint i = 0; i < r.limbs.length; ++i) {\n                uint limbA = limb(a, i);\n                uint limbB = limb(b, i);\n                unchecked {\n                    r.limbs[i] = limbA + limbB + carry;\n\n                    if (limbA + limbB < limbA || (limbA + limbB == type(uint).max && carry > 0))\n                        carry = 1;\n                    else\n                        carry = 0;\n                }\n            }\n            if (carry > 0) {\n                // too bad, we have to add a limb\n                uint[] memory newLimbs = new uint[](r.limbs.length + 1);\n                uint i;\n                for (i = 0; i < r.limbs.length; ++i)\n                    newLimbs[i] = r.limbs[i];\n                newLimbs[i] = carry;\n                r.limbs = newLimbs;\n            }\n        }\n\n        function limb(bigint memory a, uint index) internal pure returns (uint) {\n            return index < a.limbs.length ? a.limbs[index] : 0;\n        }\n\n        function max(uint a, uint b) private pure returns (uint) {\n            return a > b ? a : b;\n        }\n    }\n\n    contract C {\n        using BigInt for bigint;\n\n        function f() public pure {\n            bigint memory x = BigInt.fromUint(7);\n            bigint memory y = BigInt.fromUint(type(uint).max);\n            bigint memory z = x.add(y);\n            assert(z.limb(1) > 0);\n        }\n    }\n\nIt is possible to obtain the address of a library by converting\nthe library type to the ``address`` type, i.e. using ``address(LibraryName)``.\n\nAs the compiler does not know the address where the library will be deployed, the compiled hex code\nwill contain placeholders of the form ``__$30bbc0abd4d6364515865950d3e0d10953$__`` `(format was different <v0.5.0) <https://docs.soliditylang.org/en/v0.4.26/contracts.html#libraries>`_. The placeholder\nis a 34 character prefix of the hex encoding of the keccak256 hash of the fully qualified library\nname, which would be for example ``libraries/bigint.sol:BigInt`` if the library was stored in a file\ncalled ``bigint.sol`` in a ``libraries/`` directory. Such bytecode is incomplete and should not be\ndeployed. Placeholders need to be replaced with actual addresses. You can do that by either passing\nthem to the compiler when the library is being compiled or by using the linker to update an already\ncompiled binary. See :ref:`library-linking` for information on how to use the commandline compiler\nfor linking.\n\nIn comparison to contracts, libraries are restricted in the following ways:\n\n- they cannot have state variables\n- they cannot inherit nor be inherited\n- they cannot receive Ether\n- they cannot be destroyed\n\n(These might be lifted at a later point.)\n\n.. _library-selectors:\n.. index:: ! selector; of a library function\n\nFunction Signatures and Selectors in Libraries\n==============================================\n\nWhile external calls to public or external library functions are possible, the calling convention for such calls\nis considered to be internal to Solidity and not the same as specified for the regular :ref:`contract ABI<ABI>`.\nExternal library functions support more argument types than external contract functions, for example recursive structs\nand storage pointers. For that reason, the function signatures used to compute the 4-byte selector are computed\nfollowing an internal naming schema and arguments of types not supported in the contract ABI use an internal encoding.\n\nThe following identifiers are used for the types in the signatures:\n\n- Value types, non-storage ``string`` and non-storage ``bytes`` use the same identifiers as in the contract ABI.\n- Non-storage array types follow the same convention as in the contract ABI, i.e. ``<type>[]`` for dynamic arrays and\n  ``<type>[M]`` for fixed-size arrays of ``M`` elements.\n- Non-storage structs are referred to by their fully qualified name, i.e. ``C.S`` for ``contract C { struct S { ... } }``.\n- Storage pointer mappings use ``mapping(<keyType> => <valueType>) storage`` where ``<keyType>`` and ``<valueType>`` are\n  the identifiers for the key and value types of the mapping, respectively.\n- Other storage pointer types use the type identifier of their corresponding non-storage type, but append a single space\n  followed by ``storage`` to it.\n\nThe argument encoding is the same as for the regular contract ABI, except for storage pointers, which are encoded as a\n``uint256`` value referring to the storage slot to which they point.\n\nSimilarly to the contract ABI, the selector consists of the first four bytes of the Keccak256-hash of the signature.\nIts value can be obtained from Solidity using the ``.selector`` member as follows:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.14 <0.9.0;\n\n    library L {\n        function f(uint256) external {}\n    }\n\n    contract C {\n        function g() public pure returns (bytes4) {\n            return L.f.selector;\n        }\n    }\n\n\n\n.. _call-protection:\n\nCall Protection For Libraries\n=============================\n\nAs mentioned in the introduction, if a library's code is executed\nusing a ``CALL`` instead of a ``DELEGATECALL`` or ``CALLCODE``,\nit will revert unless a ``view`` or ``pure`` function is called.\n\nThe EVM does not provide a direct way for a contract to detect\nwhether it was called using ``CALL`` or not, but a contract\ncan use the ``ADDRESS`` opcode to find out \"where\" it is\ncurrently running. The generated code compares this address\nto the address used at construction time to determine the mode\nof calling.\n\nMore specifically, the runtime code of a library always starts\nwith a push instruction, which is a zero of 20 bytes at\ncompilation time. When the deploy code runs, this constant\nis replaced in memory by the current address and this\nmodified code is stored in the contract. At runtime,\nthis causes the deploy time address to be the first\nconstant to be pushed onto the stack and the dispatcher\ncode compares the current address against this constant\nfor any non-view and non-pure function.\n\nThis means that the actual code stored on chain for a library\nis different from the code reported by the compiler as\n``deployedBytecode``.\n"
  },
  {
    "path": "docs/contracts/transient-storage.rst",
    "content": ".. index:: ! transient storage, ! transient, tstore, tload\n\n.. _transient-storage:\n\n*****************\nTransient Storage\n*****************\n\nTransient storage is another data location besides memory, storage, calldata\n(and return-data and code) which was introduced alongside its respective opcodes\n``TSTORE`` and ``TLOAD`` by `EIP-1153 <https://eips.ethereum.org/EIPS/eip-1153>`_.\nThis new data location behaves as a key-value store similar to storage with the main\ndifference being that data in transient storage is not permanent, but is scoped to\nthe current transaction only, after which it will be reset to zero.\nSince the content of transient storage has very limited lifetime and size,\nit does not need to be stored permanently as a part of state\nand the associated gas costs are much lower than in case of storage.\nEVM version ``cancun`` or newer is required for transient storage to be available.\n\nTransient storage variables cannot be initialized in place, i.e., they cannot be assigned\nto upon declaration, since the value would be cleared at the end of the creation transaction,\nrendering the initialization ineffective.\nTransient variables will be :ref:`default value<default-value>` initialized depending on\ntheir underlying type.\n``constant`` and ``immutable`` variables conflict with transient storage, since\ntheir values are either inlined or directly stored in code.\n\nTransient storage variables have completely independent address space from storage,\nso that the order of transient state variables does not affect the layout of storage\nstate variables and vice-versa.\nThey do need distinct names though because all state variables share the same namespace.\nIt is also important to note that the values in transient storage are packed in the\nsame fashion as those in persistent storage.\nSee :ref:`Storage Layout <storage-inplace-encoding>` for more information.\n\nBesides that, transient variables can have visibility as well and ``public`` ones will\nhave a getter function generated automatically as usual.\n\nNote that, currently, such use of ``transient`` as a data location is only allowed for\n:ref:`value type <value-types>` state variable declarations.\nReference types, such as arrays, mappings and structs, as well as local or parameter\nvariables are not yet supported.\n\nAn expected canonical use case for transient storage is cheaper reentrancy locks,\nwhich can be readily implemented with the opcodes as showcased next.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.28;\n\n    contract Generosity {\n        mapping(address => bool) sentGifts;\n        bool transient locked;\n\n        modifier nonReentrant {\n            require(!locked, \"Reentrancy attempt\");\n            locked = true;\n            _;\n            // Unlocks the guard, making the pattern composable.\n            // After the function exits, it can be called again, even in the same transaction.\n            locked = false;\n        }\n\n        function claimGift() nonReentrant public {\n            require(address(this).balance >= 1 ether);\n            require(!sentGifts[msg.sender]);\n            (bool success, ) = msg.sender.call{value: 1 ether}(\"\");\n            require(success);\n\n            // In a reentrant function, doing this last would open up the vulnerability\n            sentGifts[msg.sender] = true;\n        }\n    }\n\nTransient storage is private to the contract that owns it, in the same way as persistent storage.\nOnly owning contract frames may access their transient storage, and when they do, all the frames access the same transient store.\n\nTransient storage is part of the EVM state and is subject to the same mutability enforcements\nas persistent storage. As such, any read access to it is not ``pure`` and writing access is not ``view``.\n\nIf the ``TSTORE`` opcode is called within the context of a ``STATICCALL``,\nit will result in an exception instead of performing the modification.\n``TLOAD`` is allowed within the context of a ``STATICCALL``.\n\nWhen transient storage is used in the context of ``DELEGATECALL`` or ``CALLCODE``,\nthen the owning contract of the transient storage is the contract that issued ``DELEGATECALL``\nor ``CALLCODE`` instruction (the caller) as with persistent storage.\nWhen transient storage is used in the context of ``CALL`` or ``STATICCALL``,\nthen the owning contract of the transient storage is the contract that is the target\nof the ``CALL`` or ``STATICCALL`` instruction (the callee).\n\n.. note::\n    In the case of ``DELEGATECALL``, since references to transient storage variables\n    are currently not supported, it is not possible to pass those into library calls.\n    In libraries, access to transient storage is only possible using inline assembly.\n\nIf a frame reverts, all writes to transient storage that took place between entry\nto the frame and the return are reverted, including those that took place in inner calls.\nThe caller of an external call may employ a ``try ... catch`` block to prevent reverts\nbubbling up from the inner calls.\n\n*********************************************************************\nComposability of Smart Contracts and the Caveats of Transient Storage\n*********************************************************************\n\nGiven the caveats mentioned in the specification of EIP-1153,\nin order to preserve the composability of your smart contract,\nutmost care is recommended for more advanced use cases of transient storage.\n\nFor smart contracts, composability is a very important design principle to achieve self-contained behaviour,\nsuch that multiple calls into individual smart contracts can be composed to more complex applications.\nSo far the EVM largely guaranteed composable behaviour, since multiple calls into a smart contract\nwithin a complex transaction are virtually indistinguishable from multiple calls to the contract\nstretched over several transactions. However, transient storage allows a violation of this principle,\nand incorrect use may lead to complex bugs that only surface when used across several calls.\n\nLet's illustrate the problem with a simple example:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.28;\n\n    contract MulService {\n        uint transient multiplier;\n        function setMultiplier(uint mul) external {\n            multiplier = mul;\n        }\n\n        function multiply(uint value) external view returns (uint) {\n            return value * multiplier;\n        }\n    }\n\nand  a sequence of external calls:\n\n.. code-block:: solidity\n\n    setMultiplier(42);\n    multiply(1);\n    multiply(2);\n\nIf the example used memory or storage to store the multiplier, it would be fully composable.\nIt would not matter whether you split the sequence into separate transactions or grouped them in some way.\nYou would always get the same result: after ``multiplier`` is set to ``42``, the subsequent calls\nwould return ``42`` and ``84`` respectively.\nThis enables use cases such as batching calls from multiple transactions\ntogether to reduce gas costs.\nTransient storage potentially breaks such use cases since composability can no longer be taken for granted.\nIn the example, if the calls are not executed in the same transaction, then ``multiplier``\nis reset and the next calls to function ``multiply`` would always return ``0``.\n\nAs another example, since transient storage is constructed as a relatively cheap key-value store,\na smart contract author may be tempted to use transient storage as a replacement for in-memory mappings\nwithout keeping track of the modified keys in the mapping and thereby without clearing the mapping\nat the end of the call.\nThis, however, can easily lead to unexpected behaviour in complex transactions,\nin which values set by a previous call into the contract within the same transaction remain.\n\nThe use of transient storage for reentrancy locks that are cleared at the end of the call frame\ninto the contract, is safe.\nHowever, be sure to resist the temptation to save the 100 gas used for resetting the\nreentrancy lock, since failing to do so, will restrict your contract to only one call\nwithin a transaction, preventing its use in complex composed transactions,\nwhich have been a cornerstone for complex applications on chain.\n\nIt is recommend to generally always clear transient storage completely at the end of a call\ninto your smart contract to avoid these kinds of issues and to simplify\nthe analysis of the behaviour of your contract within complex transactions.\nCheck the `Security Considerations section of EIP-1153 <https://eips.ethereum.org/EIPS/eip-1153#security-considerations>`_\nfor further details."
  },
  {
    "path": "docs/contracts/using-for.rst",
    "content": ".. index:: ! using for, library, ! operator;user-defined, function;free\n\n.. _using-for:\n\n*********\nUsing For\n*********\n\nThe directive ``using A for B`` can be used to attach\nfunctions (``A``) as operators to user-defined value types\nor as member functions to any type (``B``).\nThe member functions receive the object they are called on\nas their first parameter (like the ``self`` variable in Python).\nThe operator functions receive operands as parameters.\n\nIt is valid either at file level or inside a contract,\nat contract level.\n\nThe first part, ``A``, can be one of:\n\n- A list of functions, optionally with an operator name assigned (e.g.\n  ``using {f, g as +, h, L.t} for uint``).\n  If no operator is specified, the function can be either a library function or a free function and\n  is attached to the type as a member function.\n  Otherwise it must be a free function and it becomes the definition of that operator on the type.\n- The name of a library (e.g. ``using L for uint``) -\n  all non-private functions of the library are attached to the type\n  as member functions\n\nAt file level, the second part, ``B``, has to be an explicit type (without data location specifier).\nInside contracts, you can also use ``*`` in place of the type (e.g. ``using L for *;``),\nwhich has the effect that all functions of the library ``L``\nare attached to *all* types.\n\nIf you specify a library, *all* non-private functions in the library get attached,\neven those where the type of the first parameter does not\nmatch the type of the object. The type is checked at the\npoint the function is called and function overload\nresolution is performed.\n\nIf you use a list of functions (e.g. ``using {f, g, h, L.t} for uint``),\nthen the type (``uint``) has to be implicitly convertible to the\nfirst parameter of each of these functions. This check is\nperformed even if none of these functions are called.\nNote that private library functions can only be specified when ``using for`` is inside a library.\n\nIf you define an operator (e.g. ``using {f as +} for T``), then the type (``T``) must be a\n:ref:`user-defined value type <user-defined-value-types>` and the definition must be a ``pure`` function.\nOperator definitions must be global.\nThe following operators can be defined this way:\n\n+------------+----------+---------------------------------------------+\n| Category   | Operator | Possible signatures                         |\n+============+==========+=============================================+\n| Bitwise    | ``&``    | ``function (T, T) pure returns (T)``        |\n|            +----------+---------------------------------------------+\n|            | ``|``    | ``function (T, T) pure returns (T)``        |\n|            +----------+---------------------------------------------+\n|            | ``^``    | ``function (T, T) pure returns (T)``        |\n|            +----------+---------------------------------------------+\n|            | ``~``    | ``function (T) pure returns (T)``           |\n+------------+----------+---------------------------------------------+\n| Arithmetic | ``+``    | ``function (T, T) pure returns (T)``        |\n|            +----------+---------------------------------------------+\n|            | ``-``    | ``function (T, T) pure returns (T)``        |\n|            +          +---------------------------------------------+\n|            |          | ``function (T) pure returns (T)``           |\n|            +----------+---------------------------------------------+\n|            | ``*``    | ``function (T, T) pure returns (T)``        |\n|            +----------+---------------------------------------------+\n|            | ``/``    | ``function (T, T) pure returns (T)``        |\n|            +----------+---------------------------------------------+\n|            | ``%``    | ``function (T, T) pure returns (T)``        |\n+------------+----------+---------------------------------------------+\n| Comparison | ``==``   | ``function (T, T) pure returns (bool)``     |\n|            +----------+---------------------------------------------+\n|            | ``!=``   | ``function (T, T) pure returns (bool)``     |\n|            +----------+---------------------------------------------+\n|            | ``<``    | ``function (T, T) pure returns (bool)``     |\n|            +----------+---------------------------------------------+\n|            | ``<=``   | ``function (T, T) pure returns (bool)``     |\n|            +----------+---------------------------------------------+\n|            | ``>``    | ``function (T, T) pure returns (bool)``     |\n|            +----------+---------------------------------------------+\n|            | ``>=``   | ``function (T, T) pure returns (bool)``     |\n+------------+----------+---------------------------------------------+\n\nNote that unary and binary ``-`` need separate definitions.\nThe compiler will choose the right definition based on how the operator is invoked.\n\nThe ``using A for B;`` directive is active only within the current\nscope (either the contract or the current module/source unit),\nincluding within all of its functions, and has no effect\noutside of the contract or module in which it is used.\n\nWhen the directive is used at file level and applied to a\nuser-defined type which was defined at file level in the same file,\nthe word ``global`` can be added at the end. This will have the\neffect that the functions and operators are attached to the type everywhere\nthe type is available (including other files), not only in the\nscope of the using statement.\n\nLet us rewrite the set example from the\n:ref:`libraries` section in this way, using file-level functions\ninstead of library functions.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.13;\n\n    struct Data { mapping(uint => bool) flags; }\n    // Now we attach functions to the type.\n    // The attached functions can be used throughout the rest of the module.\n    // If you import the module, you have to\n    // repeat the using directive there, for example as\n    //   import \"flags.sol\" as Flags;\n    //   using {Flags.insert, Flags.remove, Flags.contains}\n    //     for Flags.Data;\n    using {insert, remove, contains} for Data;\n\n    function insert(Data storage self, uint value)\n        returns (bool)\n    {\n        if (self.flags[value])\n            return false; // already there\n        self.flags[value] = true;\n        return true;\n    }\n\n    function remove(Data storage self, uint value)\n        returns (bool)\n    {\n        if (!self.flags[value])\n            return false; // not there\n        self.flags[value] = false;\n        return true;\n    }\n\n    function contains(Data storage self, uint value)\n        view\n        returns (bool)\n    {\n        return self.flags[value];\n    }\n\n\n    contract C {\n        Data knownValues;\n\n        function register(uint value) public {\n            // Here, all variables of type Data have\n            // corresponding member functions.\n            // The following function call is identical to\n            // `Set.insert(knownValues, value)`\n            require(knownValues.insert(value));\n        }\n    }\n\nIt is also possible to extend built-in types in that way.\nIn this example, we will use a library.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.13;\n\n    library Search {\n        function indexOf(uint[] storage self, uint value)\n            public\n            view\n            returns (uint)\n        {\n            for (uint i = 0; i < self.length; i++)\n                if (self[i] == value) return i;\n            return type(uint).max;\n        }\n    }\n    using Search for uint[];\n\n    contract C {\n        uint[] data;\n\n        function append(uint value) public {\n            data.push(value);\n        }\n\n        function replace(uint from, uint to) public {\n            // This performs the library function call\n            uint index = data.indexOf(from);\n            if (index == type(uint).max)\n                data.push(to);\n            else\n                data[index] = to;\n        }\n    }\n\nNote that all external library calls are actual EVM function calls. This means that\nif you pass memory or value types, a copy will be performed, even in case of the\n``self`` variable. The only situation where no copy will be performed\nis when storage reference variables are used or when internal library\nfunctions are called.\n\nAnother example shows how to define a custom operator for a user-defined type:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.19;\n\n    type UFixed16x2 is uint16;\n\n    using {\n        add as +,\n        div as /\n    } for UFixed16x2 global;\n\n    uint32 constant SCALE = 100;\n\n    function add(UFixed16x2 a, UFixed16x2 b) pure returns (UFixed16x2) {\n        return UFixed16x2.wrap(UFixed16x2.unwrap(a) + UFixed16x2.unwrap(b));\n    }\n\n    function div(UFixed16x2 a, UFixed16x2 b) pure returns (UFixed16x2) {\n        uint32 a32 = UFixed16x2.unwrap(a);\n        uint32 b32 = UFixed16x2.unwrap(b);\n        uint32 result32 = a32 * SCALE / b32;\n        require(result32 <= type(uint16).max, \"Divide overflow\");\n        return UFixed16x2.wrap(uint16(a32 * SCALE / b32));\n    }\n\n    contract Math {\n        function avg(UFixed16x2 a, UFixed16x2 b) public pure returns (UFixed16x2) {\n            return (a + b) / UFixed16x2.wrap(200);\n        }\n    }\n"
  },
  {
    "path": "docs/contracts/visibility-and-getters.rst",
    "content": ".. index:: ! visibility, external, public, private, internal\n\n.. |visibility-caveat| replace:: Making something ``private`` or ``internal`` only prevents other contracts from reading or modifying the information, but it will still be visible to the whole world outside of the blockchain.\n\n.. _visibility-and-getters:\n\n**********************\nVisibility and Getters\n**********************\n\nState Variable Visibility\n=========================\n\n``public``\n    Public state variables differ from internal ones only in that the compiler automatically generates\n    :ref:`getter functions<getter-functions>` for them, which allows other contracts to read their values.\n    When used within the same contract, the external access (e.g. ``this.x``) invokes the getter\n    while internal access (e.g. ``x``) gets the variable value directly from storage.\n    Setter functions are not generated so other contracts cannot directly modify their values.\n\n``internal``\n    Internal state variables can only be accessed from within the contract they are defined in\n    and in derived contracts.\n    They cannot be accessed externally.\n    This is the default visibility level for state variables.\n\n``private``\n    Private state variables are like internal ones but they are not visible in derived contracts.\n\n.. warning::\n    |visibility-caveat|\n\nFunction Visibility\n===================\n\nSolidity knows two kinds of function calls: external ones that do create an actual EVM message call and internal ones that do not.\nFurthermore, internal functions can be made inaccessible to derived contracts.\nThis gives rise to four types of visibility for functions.\n\n``external``\n    External functions are part of the contract interface,\n    which means they can be called from other contracts and\n    via transactions. An external function ``f`` cannot be called\n    internally (i.e. ``f()`` does not work, but ``this.f()`` works).\n\n``public``\n    Public functions are part of the contract interface\n    and can be either called internally or via message calls.\n\n``internal``\n    Internal functions can only be accessed from within the current contract\n    or contracts deriving from it.\n    They cannot be accessed externally.\n    Since they are not exposed to the outside through the contract's ABI, they can take parameters of internal types like mappings or storage references.\n\n``private``\n    Private functions are like internal ones but they are not visible in derived contracts.\n\n.. warning::\n    |visibility-caveat|\n\nThe visibility specifier is given after the type for\nstate variables and between parameter list and\nreturn parameter list for functions.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract C {\n        function f(uint a) private pure returns (uint b) { return a + 1; }\n        function setData(uint a) internal { data = a; }\n        uint public data;\n    }\n\nIn the following example, ``D``, can call ``c.getData()`` to retrieve the value of\n``data`` in state storage, but is not able to call ``f``. Contract ``E`` is derived from\n``C`` and, thus, can call ``compute``.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract C {\n        uint private data;\n\n        function f(uint a) private pure returns(uint b) { return a + 1; }\n        function setData(uint a) public { data = a; }\n        function getData() public view returns(uint) { return data; }\n        function compute(uint a, uint b) internal pure returns (uint) { return a + b; }\n    }\n\n    // This will not compile\n    contract D {\n        function readData() public {\n            C c = new C();\n            uint local = c.f(7); // error: member `f` is not visible\n            c.setData(3);\n            local = c.getData();\n            local = c.compute(3, 5); // error: member `compute` is not visible\n        }\n    }\n\n    contract E is C {\n        function g() public {\n            C c = new C();\n            uint val = compute(3, 5); // access to internal member (from derived to parent contract)\n        }\n    }\n\n.. index:: ! getter;function, ! function;getter\n.. _getter-functions:\n\nGetter Functions\n================\n\nThe compiler automatically creates getter functions for\nall **public** state variables. For the contract given below, the compiler will\ngenerate a function called ``data`` that does not take any\narguments and returns a ``uint``, the value of the state\nvariable ``data``. State variables can be initialized\nwhen they are declared.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract C {\n        uint public data = 42;\n    }\n\n    contract Caller {\n        C c = new C();\n        function f() public view returns (uint) {\n            return c.data();\n        }\n    }\n\nThe getter functions have external visibility. If the\nsymbol is accessed internally (i.e. without ``this.``),\nit evaluates to a state variable.  If it is accessed externally\n(i.e. with ``this.``), it evaluates to a function.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract C {\n        uint public data;\n        function x() public returns (uint) {\n            data = 3; // internal access\n            return this.data(); // external access\n        }\n    }\n\nIf you have a ``public`` state variable of array type, then you can only retrieve\nsingle elements of the array via the generated getter function. This mechanism\nexists to avoid high gas costs when returning an entire array. You can use\narguments to specify which individual element to return, for example\n``myArray(0)``. If you want to return an entire array in one call, then you need\nto write a function, for example:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract arrayExample {\n        // public state variable\n        uint[] public myArray;\n\n        // Getter function generated by the compiler\n        /*\n        function myArray(uint i) public view returns (uint) {\n            return myArray[i];\n        }\n        */\n\n        // function that returns entire array\n        function getArray() public view returns (uint[] memory) {\n            return myArray;\n        }\n    }\n\nNow you can use ``getArray()`` to retrieve the entire array, instead of\n``myArray(i)``, which returns a single element per call.\n\nThe next example is more complex:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract Complex {\n        struct Data {\n            uint a;\n            bytes3 b;\n            mapping(uint => uint) map;\n            uint[3] c;\n            uint[] d;\n            bytes e;\n        }\n        mapping(uint => mapping(bool => Data[])) public data;\n    }\n\nIt generates a function of the following form. The mapping and arrays (with the\nexception of byte arrays) in the struct are omitted because there is no good way\nto select individual struct members or provide a key for the mapping:\n\n.. code-block:: solidity\n\n    function data(uint arg1, bool arg2, uint arg3)\n        public\n        returns (uint a, bytes3 b, bytes memory e)\n    {\n        a = data[arg1][arg2][arg3].a;\n        b = data[arg1][arg2][arg3].b;\n        e = data[arg1][arg2][arg3].e;\n    }\n"
  },
  {
    "path": "docs/contracts.rst",
    "content": ".. index:: ! contract\n\n.. _contracts:\n\n##########\nContracts\n##########\n\nContracts in Solidity are similar to classes in object-oriented languages. They\ncontain persistent data in state variables, and functions that can modify these\nvariables. Calling a function on a different contract (instance) will perform\nan EVM function call and thus switch the context such that state variables\nin the calling contract are\ninaccessible. A contract and its functions need to be called for anything to happen.\nThere is no \"cron\" concept in Ethereum to call a function at a particular event automatically.\n\n.. include:: contracts/creating-contracts.rst\n\n.. include:: contracts/visibility-and-getters.rst\n\n.. include:: contracts/function-modifiers.rst\n\n.. include:: contracts/transient-storage.rst\n\n.. include:: contracts/constant-state-variables.rst\n.. include:: contracts/custom-storage-layout.rst\n.. include:: contracts/functions.rst\n\n.. include:: contracts/events.rst\n.. include:: contracts/errors.rst\n\n.. include:: contracts/inheritance.rst\n\n.. include:: contracts/abstract-contracts.rst\n.. include:: contracts/interfaces.rst\n\n.. include:: contracts/libraries.rst\n\n.. include:: contracts/using-for.rst"
  },
  {
    "path": "docs/contributing.rst",
    "content": "############\nContributing\n############\n\nHelp is always welcome and there are plenty of options to contribute to Solidity.\n\nIn particular, we appreciate support in the following areas:\n\n* Reporting issues.\n* Fixing and responding to `Solidity's GitHub issues\n  <https://github.com/argotorg/solidity/issues>`_, especially those tagged as\n  `\"good first issue\" <https://github.com/argotorg/solidity/labels/good%20first%20issue>`_ which are\n  meant as introductory issues for external contributors.\n* Improving the documentation.\n* `Translating <https://github.com/solidity-docs>`_ the documentation into more languages.\n* Responding to questions from other users on `StackExchange\n  <https://ethereum.stackexchange.com>`_ and the `Solidity Gitter Chat\n  <https://gitter.im/ethereum/solidity>`_.\n* Getting involved in the language design process by proposing language changes or new features in the `Solidity forum <https://forum.soliditylang.org/>`_ and providing feedback.\n\nTo get started, you can try :ref:`building-from-source` in order to familiarize\nyourself with the components of Solidity and the build process. Also, it may be\nuseful to become well-versed at writing smart-contracts in Solidity.\n\nPlease note that this project is released with a `Contributor Code of Conduct <https://raw.githubusercontent.com/ethereum/solidity/develop/CODE_OF_CONDUCT.md>`_. By participating in this project — in the issues, pull requests, or Gitter channels — you agree to abide by its terms.\n\nTeam Calls\n==========\n\nIf you have issues or pull requests to discuss, or are interested in hearing what\nthe team and contributors are working on, you can join our public team call:\n\n- Wednesdays at 3PM CET/CEST.\n\nThe call takes place on `Jitsi <https://meet.solidity.org>`_.\n\nNew topics can be freely added to the `agenda <https://notes.argot.org/@solidity-design-call-agenda>`_\nand will be scheduled for discussion on the nearest call.\n\nHow to Report Issues\n====================\n\nTo report an issue, please use the\n`GitHub issues tracker <https://github.com/argotorg/solidity/issues>`_. When\nreporting issues, please mention the following details:\n\n* Solidity version.\n* Source code (if applicable).\n* Operating system.\n* Steps to reproduce the issue.\n* Actual vs. expected behavior.\n\nReducing the source code that caused the issue to a bare minimum is always\nvery helpful, and sometimes even clarifies a misunderstanding.\n\nFor technical discussions about language design, a post in the\n`Solidity forum <https://forum.soliditylang.org/>`_ is the correct place (see :ref:`solidity_language_design`).\n\nWorkflow for Pull Requests\n==========================\n\nIn order to contribute, please fork off of the ``develop`` branch and make your\nchanges there. Your commit messages should detail *why* you made your change\nin addition to *what* you did (unless it is a tiny change).\n\nIf you need to pull in any changes from ``develop`` after making your fork (for\nexample, to resolve potential merge conflicts), please avoid using ``git merge``\nand instead, ``git rebase`` your branch. This will help us review your change\nmore easily.\n\nAdditionally, if you are writing a new feature, please ensure you add appropriate\ntest cases under ``test/`` (see below).\n\nHowever, if you are making a larger change, please consult with the `Solidity Development Gitter channel\n<https://gitter.im/ethereum/solidity-dev>`_ (different from the one mentioned above — this one is\nfocused on compiler and language development instead of language usage) first.\n\nNew features and bugfixes should be added to the ``Changelog.md`` file: please\nfollow the style of previous entries, when applicable.\n\nFinally, please make sure you respect the `coding style\n<https://github.com/argotorg/solidity/blob/develop/CODING_STYLE.md>`_\nfor this project. Also, even though we do CI testing, please test your code and\nensure that it builds locally before submitting a pull request.\n\nWe highly recommend going through our `review checklist <https://github.com/argotorg/solidity/blob/develop/ReviewChecklist.md>`_ before submitting the pull request.\nWe thoroughly review every PR and will help you get it right, but there are many common problems that can be easily avoided, making the review much smoother.\n\nThank you for your help!\n\nRunning the Compiler Tests\n==========================\n\nPrerequisites\n-------------\n\nFor running all compiler tests you may want to optionally install a few\ndependencies (`evmone <https://github.com/ipsilon/evmone/releases>`_,\n`z3 <https://github.com/Z3Prover/z3>`_, `Eldarica <https://github.com/uuverifiers/eldarica/>`_,\n`cvc5 <https://github.com/cvc5/cvc5>`).\n\nOn macOS systems, some of the testing scripts expect GNU coreutils to be installed.\nThis can be easiest accomplished using Homebrew: ``brew install coreutils``.\n\nOn Windows systems, make sure that you have a privilege to create symlinks,\notherwise several tests may fail.\nAdministrators should have that privilege, but you may also\n`grant it to other users <https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/create-symbolic-links#policy-management>`_\nor\n`enable Developer Mode <https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development>`_.\n\nRunning the Tests\n-----------------\n\nSolidity includes different types of tests, most of them bundled into the\n`Boost C++ Test Framework <https://www.boost.org/doc/libs/release/libs/test/doc/html/index.html>`_ application ``soltest``.\nRunning ``build/test/soltest`` or its wrapper ``scripts/soltest.sh`` is sufficient for most changes.\n\nThe ``./scripts/tests.sh`` script executes most Solidity tests automatically,\nincluding those bundled into the `Boost C++ Test Framework <https://www.boost.org/doc/libs/release/libs/test/doc/html/index.html>`_\napplication ``soltest`` (or its wrapper ``scripts/soltest.sh``), as well as command-line tests and\ncompilation tests.\n\nThe test system automatically tries to discover the location of\nthe `evmone <https://github.com/ipsilon/evmone/releases>`_ for running the semantic tests.\n\nThe ``evmone`` library must be located in the ``deps`` or ``deps/lib`` directory relative to the\ncurrent working directory, to its parent or its parent's parent. Alternatively, an explicit location\nfor the ``evmone`` shared object can be specified via the ``ETH_EVMONE`` environment variable.\n\n``evmone`` is needed mainly for running semantic and gas tests.\nIf you do not have it installed, you can skip these tests by passing the ``--no-semantic-tests``\nflag to ``scripts/soltest.sh``.\n\nThe ``evmone`` library should end with the file name\nextension ``.so`` on Linux, ``.dll`` on Windows systems and ``.dylib`` on macOS.\n\nFor running SMT tests, the ``z3`` executable must be present in ``PATH``.\nA few SMT tests use ``Eldarica`` instead of ``z3``.\nThese require its executable (``eld``) to be present in ``PATH`` for the tests to pass.\nHowever, if ``Eldarica`` is not found, these tests will be automatically skipped.\n\nIf ``z3`` is not present on your system, you should disable the\nSMT tests by exporting ``SMT_FLAGS=--no-smt`` before running ``./scripts/tests.sh`` or\nrunning ``./scripts/soltest.sh --no-smt``.\nThese tests are ``libsolidity/smtCheckerTests``.\n\n.. note::\n\n    To get a list of all unit tests run by Soltest, run ``./build/test/soltest --list_content=HRF``.\n\nFor quicker results you can run a subset of, or specific tests.\n\nTo run a subset of tests, you can use filters:\n``./scripts/soltest.sh -t TestSuite/TestName``,\nwhere ``TestName`` can be a wildcard ``*``.\n\nOr, for example, to run all the tests for the yul disambiguator:\n``./scripts/soltest.sh -t \"yulOptimizerTests/disambiguator/*\" --no-smt``.\n\n``./build/test/soltest --help`` has extensive help on all of the options available.\n\nSee especially:\n\n- `show_progress (-p) <https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/show_progress.html>`_ to show test completion,\n- `run_test (-t) <https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/run_test.html>`_ to run specific tests cases, and\n- `report-level (-r) <https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/report_level.html>`_ give a more detailed report.\n\n.. note::\n\n    Those working in a Windows environment wanting to run the above basic sets\n    without z3. Using Git Bash, you use: ``./build/test/Release/soltest.exe -- --no-smt``.\n    If you are running this in plain Command Prompt, use ``.\\build\\test\\Release\\soltest.exe -- --no-smt``.\n\nIf you want to debug using GDB, make sure you build differently than the \"usual\".\nFor example, you could run the following command in your ``build`` folder:\n\n.. code-block:: bash\n\n   cmake -DCMAKE_BUILD_TYPE=Debug ..\n   make\n\nThis creates symbols so that when you debug a test using the ``--debug`` flag,\nyou have access to functions and variables in which you can break or print with.\n\nThe CI runs additional tests (including ``solc-js`` and testing third party Solidity\nframeworks) that require compiling the Emscripten target.\n\nWriting and Running Syntax Tests\n--------------------------------\n\nSyntax tests check that the compiler generates the correct error messages for invalid code\nand properly accepts valid code.\nThey are stored in individual files inside the ``tests/libsolidity/syntaxTests`` folder.\nThese files must contain annotations, stating the expected result(s) of the respective test.\nThe test suite compiles and checks them against the given expectations.\n\nFor example: ``./test/libsolidity/syntaxTests/double_stateVariable_declaration.sol``\n\n.. code-block:: solidity\n\n    contract test {\n        uint256 variable;\n        uint128 variable;\n    }\n    // ----\n    // DeclarationError: (36-52): Identifier already declared.\n\nA syntax test must contain at least the contract under test itself, followed by the separator ``// ----``. The comments that follow the separator are used to describe the\nexpected compiler errors or warnings. The number range denotes the location in the source where the error occurred.\nIf you want the contract to compile without any errors or warning you can leave\nout the separator and the comments that follow it.\n\nIn the above example, the state variable ``variable`` was declared twice, which is not allowed. This results in a ``DeclarationError`` stating that the identifier was already declared.\n\nThe ``isoltest`` tool is used for these tests and you can find it under ``./build/test/tools/``. It is an interactive tool which allows\nediting of failing contracts using your preferred text editor. Let's try to break this test by removing the second declaration of ``variable``:\n\n.. code-block:: solidity\n\n    contract test {\n        uint256 variable;\n    }\n    // ----\n    // DeclarationError: (36-52): Identifier already declared.\n\nRunning ``./build/test/tools/isoltest`` again results in a test failure:\n\n.. code-block:: text\n\n    syntaxTests/double_stateVariable_declaration.sol: FAIL\n        Contract:\n            contract test {\n                uint256 variable;\n            }\n\n        Expected result:\n            DeclarationError: (36-52): Identifier already declared.\n        Obtained result:\n            Success\n\n\n``isoltest`` prints the expected result next to the obtained result, and also\nprovides a way to edit, update or skip the current contract file, or quit the application.\n\nIt offers several options for failing tests:\n\n- ``edit``: ``isoltest`` tries to open the contract in an editor so you can adjust it. It either uses the editor given on the command-line (as ``isoltest --editor /path/to/editor``), in the environment variable ``EDITOR`` or just ``/usr/bin/editor`` (in that order).\n- ``update``: Updates the expectations for contract under test. This updates the annotations by removing unmet expectations and adding missing expectations. The test is then run again.\n- ``skip``: Skips the execution of this particular test.\n- ``quit``: Quits ``isoltest``.\n\nAll of these options apply to the current contract, except ``quit`` which stops the entire testing process.\n\nAutomatically updating the test above changes it to\n\n.. code-block:: solidity\n\n    contract test {\n        uint256 variable;\n    }\n    // ----\n\nand re-run the test. It now passes again:\n\n.. code-block:: text\n\n    Re-running test case...\n    syntaxTests/double_stateVariable_declaration.sol: OK\n\n\n.. note::\n\n    Choose a name for the contract file that explains what it tests, e.g. ``double_variable_declaration.sol``.\n    Do not put more than one contract into a single file, unless you are testing inheritance or cross-contract calls.\n    Each file should test one aspect of your new feature.\n\nCommand-line Tests\n------------------\n\nOur suite of end-to-end command-line tests checks the behaviour of the compiler binary as a whole\nin various scenarios.\nThese tests are located in `test/cmdlineTests/ <https://github.com/argotorg/solidity/tree/develop/test/cmdlineTests>`_,\none per subdirectory, and can be executed using the ``cmdlineTests.sh`` script.\n\nBy default the script runs all available tests.\nYou can also provide one or more `file name patterns <https://www.gnu.org/software/bash/manual/bash.html#Filename-Expansion>`_,\nin which case only the tests matching at least one pattern will be executed.\nIt is also possible to exclude files matching a specific pattern by prefixing it with ``--exclude``.\n\nBy default the script assumes that a ``solc`` binary is available inside the ``build/`` subdirectory\ninside the working copy.\nIf you build the compiler outside of the source tree, you can use the ``SOLIDITY_BUILD_DIR`` environment\nvariable to specify a different location for the build directory.\n\nExample:\n\n.. code-block:: bash\n\n    export SOLIDITY_BUILD_DIR=~/solidity/build/\n    test/cmdlineTests.sh \"standard_*\" \"*_yul_*\" --exclude \"standard_yul_*\"\n\nThe commands above will run tests from directories starting with ``test/cmdlineTests/standard_`` and\nsubdirectories of ``test/cmdlineTests/`` that have ``_yul_`` somewhere in the name,\nbut no test whose name starts with ``standard_yul_`` will be executed.\nIt will also assume that the file ``solidity/build/solc/solc`` inside your home directory is the\ncompiler binary (unless you are on Windows -- then ``solidity/build/solc/Release/solc.exe``).\n\nThere are several kinds of command-line tests:\n\n- *Standard JSON test*: contains at least an ``input.json`` file.\n  In general may contain:\n\n    - ``input.json``: input file to be passed to the ``--standard-json`` option on the command line.\n    - ``output.json``: expected Standard JSON output.\n    - ``args``: extra command-line arguments passed to ``solc``.\n\n- *CLI test*: contains at least an ``input.*`` file (other than ``input.json``).\n  In general may contain:\n\n    - ``input.*``: a single input file, whose name will be supplied to ``solc`` on the command line.\n      Usually ``input.sol`` or ``input.yul``.\n    - ``args``: extra command-line arguments passed to ``solc``.\n    - ``stdin``: content to be passed to ``solc`` via standard input.\n    - ``output``: expected content of the standard output.\n    - ``err``: expected content of the standard error output.\n    - ``exit``: expected exit code. If not provided, zero is expected.\n\n- *Script test*: contains a ``test.*`` file.\n  In general may contain:\n\n    - ``test.*``: a single script to run, usually ``test.sh`` or ``test.py``.\n      The script must be executable.\n\nRunning the Fuzzer via AFL\n==========================\n\nFuzzing is a technique that runs programs on more or less random inputs to find exceptional execution\nstates (segmentation faults, exceptions, etc). Modern fuzzers are clever and run a directed search\ninside the input. We have a specialized binary called ``solfuzzer`` which takes source code as input\nand fails whenever it encounters an internal compiler error, segmentation fault or similar, but\ndoes not fail if e.g., the code contains an error. This way, fuzzing tools can find internal problems in the compiler.\n\nWe mainly use `AFL <https://lcamtuf.coredump.cx/afl/>`_ for fuzzing. You need to download and\ninstall the AFL packages from your repositories (afl, afl-clang) or build them manually.\nNext, build Solidity (or just the ``solfuzzer`` binary) with AFL as your compiler:\n\n.. code-block:: bash\n\n    cd build\n    # if needed\n    make clean\n    cmake .. -DCMAKE_C_COMPILER=path/to/afl-gcc -DCMAKE_CXX_COMPILER=path/to/afl-g++\n    make solfuzzer\n\nAt this stage, you should be able to see a message similar to the following:\n\n.. code-block:: text\n\n    Scanning dependencies of target solfuzzer\n    [ 98%] Building CXX object test/tools/CMakeFiles/solfuzzer.dir/fuzzer.cpp.o\n    afl-cc 2.52b by <lcamtuf@google.com>\n    afl-as 2.52b by <lcamtuf@google.com>\n    [+] Instrumented 1949 locations (64-bit, non-hardened mode, ratio 100%).\n    [100%] Linking CXX executable solfuzzer\n\nIf the instrumentation messages did not appear, try switching the cmake flags pointing to AFL's clang binaries:\n\n.. code-block:: bash\n\n    # if previously failed\n    make clean\n    cmake .. -DCMAKE_C_COMPILER=path/to/afl-clang -DCMAKE_CXX_COMPILER=path/to/afl-clang++\n    make solfuzzer\n\nOtherwise, upon execution the fuzzer halts with an error saying binary is not instrumented:\n\n.. code-block:: text\n\n    afl-fuzz 2.52b by <lcamtuf@google.com>\n    ... (truncated messages)\n    [*] Validating target binary...\n\n    [-] Looks like the target binary is not instrumented! The fuzzer depends on\n        compile-time instrumentation to isolate interesting test cases while\n        mutating the input data. For more information, and for tips on how to\n        instrument binaries, please see /usr/share/doc/afl-doc/docs/README.\n\n        When source code is not available, you may be able to leverage QEMU\n        mode support. Consult the README for tips on how to enable this.\n        (It is also possible to use afl-fuzz as a traditional, \"dumb\" fuzzer.\n        For that, you can use the -n option - but expect much worse results.)\n\n    [-] PROGRAM ABORT : No instrumentation detected\n             Location : check_binary(), afl-fuzz.c:6920\n\n\nNext, you need some example source files. This makes it much easier for the fuzzer\nto find errors. You can either copy some files from the syntax tests or extract test files\nfrom the documentation or the other tests:\n\n.. code-block:: bash\n\n    mkdir /tmp/test_cases\n    cd /tmp/test_cases\n    # extract from tests:\n    path/to/solidity/scripts/isolate_tests.py path/to/solidity/test/libsolidity/SolidityEndToEndTest.cpp\n    # extract from documentation:\n    path/to/solidity/scripts/isolate_tests.py path/to/solidity/docs\n\nThe AFL documentation states that the corpus (the initial input files) should not be\ntoo large. The files themselves should not be larger than 1 kB and there should be\nat most one input file per functionality, so better start with a small number of.\nThere is also a tool called ``afl-cmin`` that can trim input files\nthat result in similar behavior of the binary.\n\nNow run the fuzzer (the ``-m`` extends the size of memory to 60 MB):\n\n.. code-block:: bash\n\n    afl-fuzz -m 60 -i /tmp/test_cases -o /tmp/fuzzer_reports -- /path/to/solfuzzer\n\nThe fuzzer creates source files that lead to failures in ``/tmp/fuzzer_reports``.\nOften it finds many similar source files that produce the same error. You can\nuse the tool ``scripts/uniqueErrors.sh`` to filter out the unique errors.\n\nWhiskers\n========\n\n*Whiskers* is a string templating system similar to `Mustache <https://mustache.github.io>`_. It is used by the\ncompiler in various places to aid readability, and thus maintainability and verifiability, of the code.\n\nThe syntax comes with a substantial difference to Mustache. The template markers ``{{`` and ``}}`` are\nreplaced by ``<`` and ``>`` in order to aid parsing and avoid conflicts with :ref:`yul`\n(The symbols ``<`` and ``>`` are invalid in inline assembly, while ``{`` and ``}`` are used to delimit blocks).\nAnother limitation is that lists are only resolved one depth and they do not recurse. This may change in the future.\n\nA rough specification is the following:\n\nAny occurrence of ``<name>`` is replaced by the string-value of the supplied variable ``name`` without any\nescaping and without iterated replacements. An area can be delimited by ``<#name>...</name>``. It is replaced\nby as many concatenations of its contents as there were sets of variables supplied to the template system,\neach time replacing any ``<inner>`` items by their respective value. Top-level variables can also be used\ninside such areas.\n\nThere are also conditionals of the form ``<?name>...<!name>...</name>``, where template replacements\ncontinue recursively either in the first or the second segment depending on the value of the boolean\nparameter ``name``. If ``<?+name>...<!+name>...</+name>`` is used, then the check is whether\nthe string parameter ``name`` is non-empty.\n\n.. _documentation-style:\n\nDocumentation Style Guide\n=========================\n\nIn the following section you find style recommendations specifically focusing on documentation\ncontributions to Solidity.\n\nEnglish Language\n----------------\n\nUse International English, unless using project or brand names. Try to reduce the usage of\nlocal slang and references, making your language as clear to all readers as possible.\nBelow are some references to help:\n\n* `Simplified technical English <https://en.wikipedia.org/wiki/Simplified_Technical_English>`_\n* `International English <https://en.wikipedia.org/wiki/International_English>`_\n\n.. note::\n\n    While the official Solidity documentation is written in English, there are community contributed :ref:`translations`\n    in other languages available. Please refer to the `translation guide <https://github.com/solidity-docs#solidity-documentation-translation-guide>`_\n    for information on how to contribute to the community translations.\n\nTitle Case for Headings\n-----------------------\n\nUse `title case <https://titlecase.com>`_ for headings. This means capitalise all principal words in\ntitles, but not articles, conjunctions, and prepositions unless they start the\ntitle.\n\nFor example, the following are all correct:\n\n* Title Case for Headings.\n* For Headings Use Title Case.\n* Local and State Variable Names.\n* Order of Layout.\n\nExpand Contractions\n-------------------\n\nUse expanded contractions for words, for example:\n\n* \"Do not\" instead of \"Don't\".\n* \"Can not\" instead of \"Can't\".\n\nActive and Passive Voice\n------------------------\n\nActive voice is typically recommended for tutorial style documentation as it\nhelps the reader understand who or what is performing a task. However, as the\nSolidity documentation is a mixture of tutorials and reference content, passive\nvoice is sometimes more applicable.\n\nAs a summary:\n\n* Use passive voice for technical reference, for example language definition and internals of the Ethereum VM.\n* Use active voice when describing recommendations on how to apply an aspect of Solidity.\n\nFor example, the below is in passive voice as it specifies an aspect of Solidity:\n\n  Functions can be declared ``pure`` in which case they promise not to read\n  from or modify the state.\n\nFor example, the below is in active voice as it discusses an application of Solidity:\n\n  When invoking the compiler, you can specify how to discover the first element\n  of a path, and also path prefix remappings.\n\nCommon Terms\n------------\n\n* \"Function parameters\" and \"return variables\", not input and output parameters.\n\nCode Examples\n-------------\n\nA CI process tests all code block formatted code examples that begin with ``pragma solidity``, ``contract``, ``library``\nor ``interface`` using the ``./test/cmdlineTests.sh`` script when you create a PR. If you are adding new code examples,\nensure they work and pass tests before creating the PR.\n\nEnsure that all code examples begin with a ``pragma`` version that spans the largest where the contract code is valid.\nFor example ``pragma solidity >=0.4.0 <0.9.0;``.\n\nRunning Documentation Tests\n---------------------------\n\nMake sure your contributions pass our documentation tests by running ``./docs/docs.sh`` that installs dependencies\nneeded for documentation and checks for any problems such as broken links or syntax issues.\n\n.. _solidity_language_design:\n\nSolidity Language Design\n========================\n\nTo actively get involved in the language design process and to share your ideas concerning the future of Solidity,\nplease join the `Solidity forum <https://forum.soliditylang.org/>`_.\n\nThe Solidity forum serves as the place to propose and discuss new language features and their implementation in\nthe early stages of ideation or modifications of existing features.\n\nAs soon as proposals get more tangible, their\nimplementation will also be discussed in the `Solidity GitHub repository <https://github.com/argotorg/solidity>`_\nin the form of issues.\n\nIn addition to the forum and issue discussions, we regularly host language design discussion calls in which selected\ntopics, issues or feature implementations are debated in detail. The invitation to those calls is shared via the forum.\n\nWe are also sharing feedback surveys and other content that is relevant to language design in the forum.\n\nIf you want to know where the team is standing in terms of implementing new features, you can follow the implementation status in the `Solidity GitHub project <https://github.com/orgs/argotorg/projects/38>`_.\nIssues in the design backlog need further specification and will either be discussed in a language design call or in a regular team call. You can\nsee the upcoming changes for the next breaking release by changing from the default branch (`develop`) to the `breaking branch <https://github.com/argotorg/solidity/tree/breaking>`_.\n\nFor ad-hoc cases and questions, you can reach out to us via the `Solidity-dev Gitter channel <https://gitter.im/ethereum/solidity-dev>`_ — a\ndedicated chatroom for conversations around the Solidity compiler and language development.\n\nWe are happy to hear your thoughts on how we can improve the language design process to be even more collaborative and transparent.\n"
  },
  {
    "path": "docs/control-structures.rst",
    "content": "##################################\nExpressions and Control Structures\n##################################\n\n.. index:: ! parameter, parameter;input, parameter;output, function parameter, parameter;function, return variable, variable;return, return\n\n\n.. index:: if, else, while, do/while, for, break, continue, return, switch, goto\n\nControl Structures\n===================\n\nMost of the control structures known from curly-braces languages are available in Solidity:\n\nThere is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, with\nthe usual semantics known from C or JavaScript.\n\nSolidity also supports exception handling in the form of ``try``/``catch``-statements,\nbut only for :ref:`external function calls <external-function-calls>` and\ncontract creation calls. Errors can be created using the :ref:`revert statement <revert-statement>`.\n\nParentheses can *not* be omitted for conditionals, but curly braces can be omitted\naround single-statement bodies.\n\nNote that there is no type conversion from non-boolean to boolean types as\nthere is in C and JavaScript, so ``if (1) { ... }`` is *not* valid\nSolidity.\n\n.. index:: ! function;call, function;internal, function;external\n\n.. _function-calls:\n\nFunction Calls\n==============\n\n.. _internal-function-calls:\n\nInternal Function Calls\n-----------------------\n\nFunctions of the current contract can be called directly (\"internally\"), also recursively, as seen in\nthis nonsensical example:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.22 <0.9.0;\n\n    // This will report a warning\n    contract C {\n        function g(uint a) public pure returns (uint ret) { return a + f(); }\n        function f() internal pure returns (uint ret) { return g(7) + f(); }\n    }\n\nThese function calls are translated into simple jumps inside the EVM. This has\nthe effect that the current memory is not cleared, i.e. passing memory references\nto internally-called functions is very efficient. Only functions of the same\ncontract instance can be called internally.\n\nYou should still avoid excessive recursion, as every internal function call\nuses up at least one stack slot and there are only 1024 slots available.\n\n.. _external-function-calls:\n\nExternal Function Calls\n-----------------------\n\nFunctions can also be called using the ``this.g(8);`` and ``c.g(2);`` notation, where\n``c`` is a contract instance and ``g`` is a function belonging to ``c``.\nCalling the function ``g`` via either way results in it being called \"externally\", using a\nmessage call and not directly via jumps.\nPlease note that function calls on ``this`` cannot be used in the constructor,\nas the actual contract has not been created yet.\n\nFunctions of other contracts have to be called externally. For an external call,\nall function arguments have to be copied to memory.\n\n.. note::\n    A function call from one contract to another does not create its own transaction,\n    it is a message call as part of the overall transaction.\n\nWhen calling functions of other contracts, you can specify the amount of Wei or\ngas sent with the call with the special options ``{value: 10, gas: 10000}``.\nNote that it is discouraged to specify gas values explicitly, since the gas costs\nof opcodes can change in the future. Any Wei you send to the contract is added\nto the total balance of that contract:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.2 <0.9.0;\n\n    contract InfoFeed {\n        function info() public payable returns (uint ret) { return 42; }\n    }\n\n    contract Consumer {\n        InfoFeed feed;\n        function setFeed(InfoFeed addr) public { feed = addr; }\n        function callFeed() public { feed.info{value: 10, gas: 800}(); }\n    }\n\nYou need to use the modifier ``payable`` with the ``info`` function because\notherwise, the ``value`` option would not be available.\n\n.. warning::\n  Be careful that ``feed.info{value: 10, gas: 800}`` only locally sets the\n  ``value`` and amount of ``gas`` sent with the function call, and the\n  parentheses at the end perform the actual call. So\n  ``feed.info{value: 10, gas: 800}`` does not call the function and\n  the ``value`` and ``gas`` settings are lost, only\n  ``feed.info{value: 10, gas: 800}()`` performs the function call.\n\n.. warning::\n    Due to the fact that the EVM considers a call to a non-existing contract to\n    always succeed, Solidity uses the ``extcodesize`` opcode to check that\n    the contract that is about to be called actually exists (it contains code)\n    and causes an exception if it does not. This check is skipped if the return\n    data will be decoded after the call and thus the ABI decoder will catch the\n    case of a non-existing contract.\n\n    This check is not performed in case of :ref:`low-level calls <address_related>` which\n    operate on addresses rather than contract instances.\n\n.. warning::\n    Be careful when using high-level calls to\n    :ref:`precompiled contracts <precompiledContracts>`,\n    since the compiler considers them non-existing according to the\n    above logic even though they execute code and can return data.\n\n.. note::\n    Since the version 0.8.10, the compiler does not check ``extcodesize`` on\n    high-level external calls if return data is expected, because an empty code\n    will be unable to return data, and the ABI decoder will revert.\n    As a consequence, this allows high-level external calls to precompiled\n    contracts, since they can return data despite having no code\n    associated with their addresses.\n\n    Read about :ref:`precompiled contracts <precompiledContracts>` and\n    :ref:`low-level calls <address_related>`\n    for more information.\n\nFunction calls also cause exceptions if the called contract itself\nthrows an exception or goes out of gas.\n\n.. warning::\n    Any interaction with another contract imposes a potential danger, especially\n    if the source code of the contract is not known in advance. The\n    current contract hands over control to the called contract and that may potentially\n    do just about anything. Even if the called contract inherits from a known parent contract,\n    the inheriting contract is only required to have a correct interface. The\n    implementation of the contract, however, can be completely arbitrary and thus,\n    pose a danger. In addition, be prepared in case it calls into other contracts of\n    your system or even back into the calling contract before the first\n    call returns. This means\n    that the called contract can change state variables of the calling contract\n    via its functions. Write your functions in a way that, for example, calls to\n    external functions happen after any changes to state variables in your contract\n    so your contract is not vulnerable to a reentrancy exploit.\n\n.. note::\n    Before Solidity 0.6.2, the recommended way to specify the value and gas was to\n    use ``f.value(x).gas(g)()``. This was deprecated in Solidity 0.6.2 and is no\n    longer possible since Solidity 0.7.0.\n\nFunction Calls with Named Parameters\n------------------------------------\n\nFunction call arguments can be given by name, in any order,\nif they are enclosed in ``{ }`` as can be seen in the following\nexample. The argument list has to coincide by name with the list of\nparameters from the function declaration, but can be in arbitrary order.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract C {\n        mapping(uint => uint) data;\n\n        function f() public {\n            set({value: 2, key: 3});\n        }\n\n        function set(uint key, uint value) public {\n            data[key] = value;\n        }\n    }\n\nOmitted Names in Function Definitions\n-------------------------------------\n\nThe names of parameters and return values in the function declaration can be omitted.\nThose items with omitted names will still be present on the stack, but they are\ninaccessible by name. An omitted return value name\ncan still return a value to the caller by use of the ``return`` statement.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.22 <0.9.0;\n\n    contract C {\n        // omitted name for parameter\n        function func(uint k, uint) public pure returns(uint) {\n            return k;\n        }\n    }\n\n\n.. index:: ! new, contracts;creating\n\n.. _creating-contracts:\n\nCreating Contracts via ``new``\n==============================\n\nA contract can create other contracts using the ``new`` keyword. The full\ncode of the contract being created has to be known when the creating contract\nis compiled so recursive creation-dependencies are not possible.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n    contract D {\n        uint public x;\n        constructor(uint a) payable {\n            x = a;\n        }\n    }\n\n    contract C {\n        D d = new D(4); // will be executed as part of C's constructor\n\n        function createD(uint arg) public {\n            D newD = new D(arg);\n            newD.x();\n        }\n\n        function createAndEndowD(uint arg, uint amount) public payable {\n            // Send ether along with the creation\n            D newD = new D{value: amount}(arg);\n            newD.x();\n        }\n    }\n\nAs seen in the example, it is possible to send Ether while creating\nan instance of ``D`` using the ``value`` option, but it is not possible\nto limit the amount of gas.\nIf the creation fails (due to out-of-stack, not enough balance or other problems),\nan exception is thrown.\n\n.. _salted-contract-creations:\n\nSalted contract creations / create2\n-----------------------------------\n\nWhen creating a contract, the address of the contract is computed from\nthe address of the creating contract and a counter that is increased with\neach contract creation.\n\nIf you specify the option ``salt`` (a bytes32 value), then contract creation will\nuse a different mechanism to come up with the address of the new contract:\n\nIt will compute the address from the address of the creating contract,\nthe given salt value, the (creation) bytecode of the created contract and the constructor\narguments.\n\nIn particular, the counter (\"nonce\") is not used. This allows for more flexibility\nin creating contracts: You are able to derive the address of the\nnew contract before it is created. Furthermore, you can rely on this address\nalso in case the creating\ncontracts creates other contracts in the meantime.\n\nThe main use-case here is contracts that act as judges for off-chain interactions,\nwhich only need to be created if there is a dispute.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n    contract D {\n        uint public x;\n        constructor(uint a) {\n            x = a;\n        }\n    }\n\n    contract C {\n        function createDSalted(bytes32 salt, uint arg) public {\n            // This complicated expression just tells you how the address\n            // can be pre-computed. It is just there for illustration.\n            // You actually only need ``new D{salt: salt}(arg)``.\n            address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(\n                bytes1(0xff),\n                address(this),\n                salt,\n                keccak256(abi.encodePacked(\n                    type(D).creationCode,\n                    abi.encode(arg)\n                ))\n            )))));\n\n            D d = new D{salt: salt}(arg);\n            require(address(d) == predictedAddress);\n        }\n    }\n\n.. warning::\n    There are some peculiarities in relation to salted creation. A contract can be\n    re-created at the same address after having been destroyed. Yet, it is possible\n    for that newly created contract to have a different deployed bytecode even\n    though the creation bytecode has been the same (which is a requirement because\n    otherwise the address would change). This is due to the fact that the constructor\n    can query external state that might have changed between the two creations\n    and incorporate that into the deployed bytecode before it is stored.\n\n\nOrder of Evaluation of Expressions\n==================================\n\nThe evaluation order of expressions is not specified (more formally, the order\nin which the children of one node in the expression tree are evaluated is not\nspecified, but they are of course evaluated before the node itself). It is only\nguaranteed that statements are executed in order and short-circuiting for\nboolean expressions is done.\n\n.. index:: ! assignment\n\nAssignment\n==========\n\n.. index:: ! assignment;destructuring\n\nDestructuring Assignments and Returning Multiple Values\n-------------------------------------------------------\n\nSolidity internally allows tuple types, i.e. a list of objects\nof potentially different types whose number is a constant at\ncompile-time. Those tuples can be used to return multiple values at the same time.\nThese can then either be assigned to newly declared variables\nor to pre-existing variables (or LValues in general).\n\nTuples are not proper types in Solidity, they can only be used to form syntactic\ngroupings of expressions.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.0 <0.9.0;\n\n    contract C {\n        uint index;\n\n        function f() public pure returns (uint, bool, uint) {\n            return (7, true, 2);\n        }\n\n        function g() public {\n            // Variables declared with type and assigned from the returned tuple,\n            // not all elements have to be specified (but the number must match).\n            (uint x, , uint y) = f();\n            // Common trick to swap values -- does not work for non-value storage types.\n            (x, y) = (y, x);\n            // Components can be left out (also for variable declarations).\n            (index, , ) = f(); // Sets the index to 7\n        }\n    }\n\nIt is not possible to mix variable declarations and non-declaration assignments,\ni.e. the following is not valid: ``(x, uint y) = (1, 2);``\n\n.. note::\n    Prior to version 0.5.0 it was possible to assign to tuples of smaller size, either\n    filling up on the left or on the right side (which ever was empty). This is\n    now disallowed, so both sides have to have the same number of components.\n\n.. warning::\n    Be careful when assigning to multiple variables at the same time when\n    reference types are involved, because it could lead to unexpected\n    copying behavior.\n\nComplications for Arrays and Structs\n------------------------------------\n\nThe semantics of assignments are more complicated for non-value types like arrays and structs,\nincluding ``bytes`` and ``string``, see :ref:`Data location and assignment behavior <data-location-assignment>` for details.\n\nIn the example below the call to ``g(x)`` has no effect on ``x`` because it creates\nan independent copy of the storage value in memory. However, ``h(x)`` successfully modifies ``x``\nbecause only a reference and not a copy is passed.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.22 <0.9.0;\n\n    contract C {\n        uint[20] x;\n\n        function f() public {\n            g(x);\n            h(x);\n        }\n\n        function g(uint[20] memory y) internal pure {\n            y[2] = 3;\n        }\n\n        function h(uint[20] storage y) internal {\n            y[3] = 4;\n        }\n    }\n\n.. index:: ! scoping, declarations, default value\n\n.. _default-value:\n\nScoping and Declarations\n========================\n\nA variable which is declared will have an initial default\nvalue whose byte-representation is all zeros.\nThe \"default values\" of variables are the typical \"zero-state\"\nof whatever the type is. For example, the default value for a ``bool``\nis ``false``. The default value for the ``uint`` or ``int``\ntypes is ``0``. For statically-sized arrays and ``bytes1`` to\n``bytes32``, each individual\nelement will be initialized to the default value corresponding\nto its type. For dynamically-sized arrays, ``bytes``\nand ``string``, the default value is an empty array or string.\nFor the ``enum`` type, the default value is its first member.\n\nScoping in Solidity follows the widespread scoping rules of C99\n(and many other languages): Variables are visible from the point right after their declaration\nuntil the end of the smallest ``{ }``-block that contains the declaration.\nAs an exception to this rule, variables declared in the\ninitialization part of a for-loop are only visible until the end of the for-loop.\n\nVariables that are parameter-like (function parameters, modifier parameters,\ncatch parameters, ...) are visible inside the code block that follows -\nthe body of the function/modifier for a function and modifier parameter and the catch block\nfor a catch parameter.\n\nVariables and other items declared outside of a code block, for example functions, contracts,\nuser-defined types, etc., are visible even before they were declared. This means you can\nuse state variables before they are declared and call functions recursively.\n\nAs a consequence, the following examples will compile without warnings, since\nthe two variables have the same name but disjoint scopes.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.0 <0.9.0;\n    contract C {\n        function minimalScoping() pure public {\n            {\n                uint same;\n                same = 1;\n            }\n\n            {\n                uint same;\n                same = 3;\n            }\n        }\n    }\n\nAs a special example of the C99 scoping rules, note that in the following,\nthe first assignment to ``x`` will actually assign the outer and not the inner variable.\nIn any case, you will get a warning about the outer variable being shadowed.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.0 <0.9.0;\n    // This will report a warning\n    contract C {\n        function f() pure public returns (uint) {\n            uint x = 1;\n            {\n                x = 2; // this will assign to the outer variable\n                uint x;\n            }\n            return x; // x has value 2\n        }\n    }\n\n.. warning::\n    Before version 0.5.0 Solidity followed the same scoping rules as\n    JavaScript, that is, a variable declared anywhere within a function would be in scope\n    for the entire function, regardless where it was declared. The following example shows a code snippet that used\n    to compile but leads to an error starting from version 0.5.0.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.0 <0.9.0;\n    // This will not compile\n    contract C {\n        function f() pure public returns (uint) {\n            x = 2;\n            uint x;\n            return x;\n        }\n    }\n\n\n.. index:: ! safe math, safemath, checked, unchecked\n.. _unchecked:\n\nChecked or Unchecked Arithmetic\n===============================\n\nAn overflow or underflow is the situation where the resulting value of an arithmetic operation,\nwhen executed on an unrestricted integer, falls outside the range of the result type.\n\nPrior to Solidity 0.8.0, arithmetic operations would always wrap in case of\nunder- or overflow leading to widespread use of libraries that introduce\nadditional checks.\n\nSince Solidity 0.8.0, all arithmetic operations revert on over- and underflow by default,\nthus making the use of these libraries unnecessary.\n\nTo obtain the previous behavior, an ``unchecked`` block can be used:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.0;\n    contract C {\n        function f(uint a, uint b) pure public returns (uint) {\n            // This subtraction will wrap on underflow.\n            unchecked { return a - b; }\n        }\n        function g(uint a, uint b) pure public returns (uint) {\n            // This subtraction will revert on underflow.\n            return a - b;\n        }\n    }\n\nThe call to ``f(2, 3)`` will return ``2**256-1``, while ``g(2, 3)`` will cause\na failing assertion.\n\nThe ``unchecked`` block can be used everywhere inside a block, but not as a replacement\nfor a block. It also cannot be nested.\n\nThe setting only affects the statements that are syntactically inside the block.\nFunctions called from within an ``unchecked`` block do not inherit the property.\n\n.. note::\n    To avoid ambiguity, you cannot use ``_;`` inside an ``unchecked`` block.\n\nThe following operators will cause a failing assertion on overflow or underflow\nand will wrap without an error if used inside an unchecked block:\n\n``++``, ``--``, ``+``, binary ``-``, unary ``-``, ``*``, ``/``, ``%``, ``**``\n\n``+=``, ``-=``, ``*=``, ``/=``, ``%=``\n\n.. warning::\n    It is not possible to disable the check for division by zero\n    or modulo by zero using the ``unchecked`` block.\n\n.. note::\n   Bitwise operators do not perform overflow or underflow checks.\n   This is particularly visible when using bitwise shifts (``<<``, ``>>``, ``<<=``, ``>>=``) in\n   place of integer division and multiplication by a power of 2.\n   For example ``type(uint256).max << 3`` does not revert even though ``type(uint256).max * 8`` would.\n\n.. note::\n    The second statement in ``int x = type(int).min; -x;`` will result in an overflow\n    because the negative range can hold one more value than the positive range.\n\nExplicit type conversions will always truncate and never cause a failing assertion\nwith the exception of a conversion from an integer to an enum type.\n\n.. index:: ! exception, ! throw, ! assert, ! require, ! revert, ! errors\n\n.. _assert-and-require:\n\nError handling: Assert, Require, Revert and Exceptions\n======================================================\n\nSolidity uses state-reverting exceptions to handle errors.\nSuch an exception undoes all changes made to the\nstate in the current call (and all its sub-calls) and\nflags an error to the caller.\n\nWhen exceptions happen in a sub-call, they \"bubble up\" (i.e.,\nexceptions are rethrown) automatically unless they are caught in\na ``try/catch`` statement. Exceptions to this rule are ``send``\nand the low-level functions ``call``, ``delegatecall`` and\n``staticcall``: they return ``false`` as their first return value in case\nof an exception instead of \"bubbling up\".\n\n.. warning::\n    The low-level functions ``call``, ``delegatecall`` and\n    ``staticcall`` return ``true`` as their first return value\n    if the account called is non-existent, as part of the design\n    of the EVM. Account existence must be checked prior to calling if needed.\n\nExceptions can contain error data that is passed back to the caller\nin the form of :ref:`error instances <errors>`.\nThe built-in errors ``Error(string)`` and ``Panic(uint256)`` are\nused by special functions, as explained below. ``Error`` is used for \"regular\" error conditions\nwhile ``Panic`` is used for errors that should not be present in bug-free code.\n\n.. _assert-and-require-statements:\n\nPanic via ``assert`` and Error via ``require``\n----------------------------------------------\n\nThe convenience functions ``assert`` and ``require`` can be used to check for conditions and throw an exception\nif the condition is not met.\n\nThe ``assert`` function creates an error of type ``Panic(uint256)``.\nThe same error is created by the compiler in certain situations as listed below.\n\nAssert should only be used to test for internal\nerrors, and to check invariants. Properly functioning code should\nnever create a Panic, not even on invalid external input.\nIf this happens, then there\nis a bug in your contract which you should fix. Language analysis\ntools can evaluate your contract to identify the conditions and\nfunction calls which will cause a Panic.\n\nA Panic exception is generated in the following situations.\nThe error code supplied with the error data indicates the kind of panic.\n\n#. 0x00: Used for generic compiler inserted panics.\n#. 0x01: If you call ``assert`` with an argument that evaluates to false.\n#. 0x11: If an arithmetic operation results in underflow or overflow outside of an ``unchecked { ... }`` block.\n#. 0x12; If you divide or modulo by zero (e.g. ``5 / 0`` or ``23 % 0``).\n#. 0x21: If you convert a value that is too big or negative into an enum type.\n#. 0x22: If you access a storage byte array that is incorrectly encoded.\n#. 0x31: If you call ``.pop()`` on an empty array.\n#. 0x32: If you access an array, ``bytesN`` or an array slice at an out-of-bounds or negative index (i.e. ``x[i]`` where ``i >= x.length`` or ``i < 0``).\n#. 0x41: If you allocate too much memory or create an array that is too large.\n#. 0x51: If you call a zero-initialized variable of internal function type.\n\nThe ``require`` function provides three overloads:\n\n1. ``require(bool)`` which will revert without any data (not even an error selector).\n2. ``require(bool, string)`` which will revert with an ``Error(string)``.\n3. ``require(bool, error)`` which will revert with the custom, user supplied error provided as the second argument.\n\n.. note::\n    ``require`` arguments are evaluated unconditionally, so take special care to make sure that\n    they are not expressions with unexpected side-effects.\n    For example, in ``require(condition, CustomError(f()));`` and ``require(condition, f());``,\n    function ``f()`` will be called regardless of whether the supplied condition is ``true`` or ``false``.\n\nAn ``Error(string)`` exception (or an exception without data) is generated\nby the compiler in the following situations:\n\n#. Calling ``require(x)`` where ``x`` evaluates to ``false``.\n#. If you use ``revert()`` or ``revert(\"description\")``.\n#. If you perform an external function call targeting a contract that contains no code.\n#. If your contract receives Ether via a public function without\n   ``payable`` modifier (including the constructor and the fallback function).\n#. If your contract receives Ether via a public getter function.\n\nFor the following cases, the error data from the external call\n(if provided) is forwarded. This means that it can either cause\nan ``Error`` or a ``Panic`` (or whatever else was given):\n\n#. If a ``.transfer()`` fails.\n#. If you call a function via a message call but it does not finish\n   properly (i.e., it runs out of gas, has no matching function, or\n   throws an exception itself), except when a low level operation\n   ``call``, ``send``, ``delegatecall``, ``callcode`` or ``staticcall``\n   is used. The low level operations never throw exceptions but\n   indicate failures by returning ``false``.\n#. If you create a contract using the ``new`` keyword but the contract\n   creation :ref:`does not finish properly<creating-contracts>`.\n\nYou can optionally provide a message string or a custom error to ``require``, but not to ``assert``.\n\n.. note::\n    If you do not provide a string or custom error argument to ``require``, it will revert\n    with empty error data, not even including the error selector.\n\n\nThe following example shows how you can use ``require`` to check conditions on inputs\nand ``assert`` for internal error checking.\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.2 <0.9.0;\n\n    contract Sharer {\n        function sendHalf(address payable addr) public payable returns (uint balance) {\n            require(msg.value % 2 == 0, \"Even value required.\");\n            uint balanceBeforeTransfer = address(this).balance;\n            (bool success, ) = addr.call{value: msg.value / 2}(\"\");\n            require(success);\n            // Since require will stop execution and revert if success is false,\n            // there should be no way for us to still have half of the Ether.\n            assert(address(this).balance == balanceBeforeTransfer - msg.value / 2);\n            return address(this).balance;\n        }\n    }\n\nInternally, Solidity performs a revert operation (instruction\n``0xfd``). This causes\nthe EVM to revert all changes made to the state. The reason for reverting\nis that there is no safe way to continue execution, because an expected effect\ndid not occur. Because we want to keep the atomicity of transactions, the\nsafest action is to revert all changes and make the whole transaction\n(or at least call) without effect.\n\nIn both cases, the caller can react on such failures using ``try``/``catch``, but\nthe changes in the callee will always be reverted.\n\n.. note::\n\n    Panic exceptions used to use the ``invalid`` opcode before Solidity 0.8.0,\n    which consumed all gas available to the call.\n    Exceptions that use ``require`` used to consume all gas until before the Metropolis release.\n\n.. _revert-statement:\n\n``revert``\n----------\n\nA direct revert can be triggered using the ``revert`` statement and the ``revert`` function.\n\nThe ``revert`` statement takes a custom error as direct argument without parentheses:\n\n    revert CustomError(arg1, arg2);\n\nFor backward-compatibility reasons, there is also the ``revert()`` function, which uses parentheses\nand accepts a string:\n\n    revert();\n    revert(\"description\");\n\nThe error data will be passed back to the caller and can be caught there.\nUsing ``revert()`` causes a revert without any error data while ``revert(\"description\")``\nwill create an ``Error(string)`` error.\n\nUsing a custom error instance will usually be much cheaper than a string description,\nbecause you can use the name of the error to describe it, which is encoded in only\nfour bytes. A longer description can be supplied via NatSpec which does not incur\nany costs.\n\nThe following example shows how to use an error string and a custom error instance\ntogether with ``revert`` and the equivalent ``require``:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.4;\n\n    contract VendingMachine {\n        address owner;\n        error Unauthorized();\n        function buy(uint amount) public payable {\n            if (amount > msg.value / 2 ether)\n                revert(\"Not enough Ether provided.\");\n            // Alternative way to do it:\n            require(\n                amount <= msg.value / 2 ether,\n                \"Not enough Ether provided.\"\n            );\n            // Perform the purchase.\n        }\n        function withdraw() public {\n            if (msg.sender != owner)\n                revert Unauthorized();\n\n            (bool success, ) = payable(msg.sender).call{value: address(this).balance}(\"\");\n            require(success);\n        }\n    }\n\nThe two ways ``if (!condition) revert(...);`` and ``require(condition, ...);`` are\nequivalent as long as the arguments to ``revert`` and ``require`` do not have side-effects,\nfor example if they are just strings.\n\n.. note::\n    The ``require`` function is evaluated just as any other function.\n    This means that all arguments are evaluated before the function itself is executed.\n    In particular, in ``require(condition, f())`` the function ``f`` is executed even if\n    ``condition`` is true.\n\nThe provided string is :ref:`abi-encoded <ABI>` as if it were a call to a function ``Error(string)``.\nIn the above example, ``revert(\"Not enough Ether provided.\");`` returns the following hexadecimal as error return data:\n\n.. code::\n\n    0x08c379a0                                                         // Function selector for Error(string)\n    0x0000000000000000000000000000000000000000000000000000000000000020 // Data offset\n    0x000000000000000000000000000000000000000000000000000000000000001a // String length\n    0x4e6f7420656e6f7567682045746865722070726f76696465642e000000000000 // String data\n\nThe provided message can be retrieved by the caller using ``try``/``catch`` as shown below.\n\n.. note::\n    There used to be a keyword called ``throw`` with the same semantics as ``revert()`` which\n    was deprecated in version 0.4.13 and removed in version 0.5.0.\n\n\n.. _try-catch:\n\n``try``/``catch``\n-----------------\n\nA failure in an external call can be caught using a try/catch statement, as follows:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.1;\n\n    interface DataFeed { function getData(address token) external returns (uint value); }\n\n    contract FeedConsumer {\n        DataFeed feed;\n        uint errorCount;\n        function rate(address token) public returns (uint value, bool success) {\n            // Permanently disable the mechanism if there are\n            // more than 10 errors.\n            require(errorCount < 10);\n            try feed.getData(token) returns (uint v) {\n                return (v, true);\n            } catch Error(string memory /*reason*/) {\n                // This is executed in case\n                // revert was called inside getData\n                // and a reason string was provided.\n                errorCount++;\n                return (0, false);\n            } catch Panic(uint /*errorCode*/) {\n                // This is executed in case of a panic,\n                // i.e. a serious error like division by zero\n                // or overflow. The error code can be used\n                // to determine the kind of error.\n                errorCount++;\n                return (0, false);\n            } catch (bytes memory /*lowLevelData*/) {\n                // This is executed in case revert() was used.\n                errorCount++;\n                return (0, false);\n            }\n        }\n    }\n\nThe ``try`` keyword has to be followed by an expression representing an external function call\nor a contract creation (``new ContractName()``).\nErrors inside the expression are not caught (for example if it is a complex expression\nthat also involves internal function calls), only a revert happening inside the external\ncall itself. The ``returns`` part (which is optional) that follows declares return variables\nmatching the types returned by the external call. In case there was no error,\nthese variables are assigned and the contract's execution continues inside the\nfirst success block. If the end of the success block is reached, execution continues after the ``catch`` blocks.\n\nSolidity supports different kinds of catch blocks depending on the\ntype of error:\n\n- ``catch Error(string memory reason) { ... }``: This catch clause is executed if the error was caused by ``revert(\"reasonString\")`` or\n  ``require(false, \"reasonString\")`` (or an internal error that causes such an\n  exception).\n\n- ``catch Panic(uint errorCode) { ... }``: If the error was caused by a panic, i.e. by a failing ``assert``, division by zero,\n  invalid array access, arithmetic overflow and others, this catch clause will be run.\n\n- ``catch (bytes memory lowLevelData) { ... }``: This clause is executed if the error signature\n  does not match any other clause, if there was an error while decoding the error\n  message, or\n  if no error data was provided with the exception.\n  The declared variable provides access to the low-level error data in that case.\n\n- ``catch { ... }``: If you are not interested in the error data, you can just use\n  ``catch { ... }`` (even as the only catch clause) instead of the previous clause.\n\n\nIt is planned to support other types of error data in the future.\nThe strings ``Error`` and ``Panic`` are currently parsed as is and are not treated as identifiers.\n\nIn order to catch all error cases, you have to have at least the clause\n``catch { ...}`` or the clause ``catch (bytes memory lowLevelData) { ... }``.\n\nThe variables declared in the ``returns`` and the ``catch`` clause are only\nin scope in the block that follows.\n\n.. note::\n\n    If an error happens during the decoding of the return data\n    inside a try/catch-statement, this causes an exception in the currently\n    executing contract and because of that, it is not caught in the catch clause.\n    If there is an error during decoding of ``catch Error(string memory reason)``\n    and there is a low-level catch clause, this error is caught there.\n\n.. note::\n\n    If execution reaches a catch-block, then the state-changing effects of\n    the external call have been reverted. If execution reaches\n    the success block, the effects were not reverted.\n    If the effects have been reverted, then execution either continues\n    in a catch block or the execution of the try/catch statement itself\n    reverts (for example due to decoding failures as noted above or\n    due to not providing a low-level catch clause).\n\n.. note::\n    The reason behind a failed call can be manifold. Do not assume that\n    the error message is coming directly from the called contract:\n    The error might have happened deeper down in the call chain and the\n    called contract just forwarded it. Also, it could be due to an\n    out-of-gas situation and not a deliberate error condition:\n    The caller always retains at least 1/64th of the gas in a call and thus\n    even if the called contract goes out of gas, the caller still\n    has some gas left.\n"
  },
  {
    "path": "docs/credits-and-attribution.rst",
    "content": ".. This page is meant to be linked to from the footer.\n\n:orphan:\n\n#######################\nCredits and Attribution\n#######################\n\nWebsite icons\n=============\n\n.. |icon-share-solid| image:: _static/img/solid-share-arrow.svg\n.. _share icon: https://fontawesome.com/v5.15/icons/share?style=solid\n.. _Font Awesome Free License: https://fontawesome.com/license/free\n\n+-------------------------+-----------------------------------------------------------------------+\n| Icon                    | Attribution                                                           |\n+=========================+=======================================================================+\n| |icon-share-solid|      | - Source: `share icon`_ from Font Awesome 5.15.0.                     |\n|                         | - License: `Font Awesome Free License`_ (CC BY 4.0).                  |\n+-------------------------+-----------------------------------------------------------------------+\n"
  },
  {
    "path": "docs/docs.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Bash script to build the Solidity Sphinx documentation locally.\n#\n# The documentation for solidity is hosted at:\n#\n#     https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -euo pipefail\n\nscript_dir=\"$(dirname \"$0\")\"\n\ncd \"${script_dir}\"\n# TODO `--ignore-installed` now fixes an issue where pip tries to uninstall a Debian installed package, but is unable to\n# TODO since Debian has decided to not use the RECORD file, which then breaks pip.\n# TODO https://github.com/pypa/pip/issues/11631 and https://bugs.launchpad.net/ubuntu/+source/wheel/+bug/2063151\npip3 install -r requirements.txt --ignore-installed --upgrade --upgrade-strategy eager\nsphinx-build -nW -b html -d _build/doctrees . _build/html\n"
  },
  {
    "path": "docs/examples/blind-auction.rst",
    "content": ".. index:: auction;blind, auction;open, blind auction, open auction\n\n*************\nBlind Auction\n*************\n\nIn this section, we will show how easy it is to create a completely blind\nauction contract on Ethereum.  We will start with an open auction where\neveryone can see the bids that are made and then extend this contract into a\nblind auction where it is not possible to see the actual bid until the bidding\nperiod ends.\n\n.. _simple_auction:\n\nSimple Open Auction\n===================\n\nThe general idea of the following simple auction contract is that everyone can\nsend their bids during a bidding period. The bids already include sending some compensation,\ne.g. Ether, in order to bind the bidders to their bid. If the highest bid is\nraised, the previous highest bidder gets their Ether back.  After the end of\nthe bidding period, the contract has to be called manually for the beneficiary\nto receive their Ether - contracts cannot activate themselves.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.4;\n    contract SimpleAuction {\n        // Parameters of the auction. Times are either\n        // absolute unix timestamps (seconds since 1970-01-01)\n        // or time periods in seconds.\n        address payable public beneficiary;\n        uint public auctionEndTime;\n\n        // Current state of the auction.\n        address public highestBidder;\n        uint public highestBid;\n\n        // Allowed withdrawals of previous bids\n        mapping(address => uint) pendingReturns;\n\n        // Set to true at the end, disallows any change.\n        // By default initialized to `false`.\n        bool ended;\n\n        // Events that will be emitted on changes.\n        event HighestBidIncreased(address bidder, uint amount);\n        event AuctionEnded(address winner, uint amount);\n\n        // Errors that describe failures.\n\n        // The triple-slash comments are so-called natspec\n        // comments. They will be shown when the user\n        // is asked to confirm a transaction or\n        // when an error is displayed.\n\n        /// The auction has already ended.\n        error AuctionAlreadyEnded();\n        /// There is already a higher or equal bid.\n        error BidNotHighEnough(uint highestBid);\n        /// The auction has not ended yet.\n        error AuctionNotYetEnded();\n        /// The function auctionEnd has already been called.\n        error AuctionEndAlreadyCalled();\n\n        /// Create a simple auction with `biddingTime`\n        /// seconds bidding time on behalf of the\n        /// beneficiary address `beneficiaryAddress`.\n        constructor(\n            uint biddingTime,\n            address payable beneficiaryAddress\n        ) {\n            beneficiary = beneficiaryAddress;\n            auctionEndTime = block.timestamp + biddingTime;\n        }\n\n        /// Bid on the auction with the value sent\n        /// together with this transaction.\n        /// The value will only be refunded if the\n        /// auction is not won.\n        function bid() external payable {\n            // No arguments are necessary, all\n            // information is already part of\n            // the transaction. The keyword payable\n            // is required for the function to\n            // be able to receive Ether.\n\n            // Revert the call if the bidding\n            // period is over.\n            if (block.timestamp > auctionEndTime)\n                revert AuctionAlreadyEnded();\n\n            // If the bid is not higher, send the\n            // Ether back (the revert statement\n            // will revert all changes in this\n            // function execution including\n            // it having received the Ether).\n            if (msg.value <= highestBid)\n                revert BidNotHighEnough(highestBid);\n\n            if (highestBid != 0) {\n                // Sending back the Ether by simply using\n                // highestBidder.send(highestBid) is a security risk\n                // because it could execute an untrusted contract.\n                // It is always safer to let the recipients\n                // withdraw their Ether themselves.\n                pendingReturns[highestBidder] += highestBid;\n            }\n            highestBidder = msg.sender;\n            highestBid = msg.value;\n            emit HighestBidIncreased(msg.sender, msg.value);\n        }\n\n        /// Withdraw a bid that was overbid.\n        function withdraw() external returns (bool) {\n            uint amount = pendingReturns[msg.sender];\n            if (amount > 0) {\n                // It is important to set this to zero because the recipient\n                // can call this function again as part of the receiving call\n                // before `call` returns.\n                pendingReturns[msg.sender] = 0;\n\n                // msg.sender is not of type `address payable` and must be\n                // explicitly converted using `payable(msg.sender)` in order\n                // use the member function `call()`.\n                (bool success, ) = payable(msg.sender).call{value: amount}(\"\");\n                if (!success) {\n                    // No need to call throw here, just reset the amount owing\n                    pendingReturns[msg.sender] = amount;\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        /// End the auction and send the highest bid\n        /// to the beneficiary.\n        function auctionEnd() external {\n            // It is a good guideline to structure functions that interact\n            // with other contracts (i.e. they call functions or send Ether)\n            // into three phases:\n            // 1. checking conditions\n            // 2. performing actions (potentially changing conditions)\n            // 3. interacting with other contracts\n            // If these phases are mixed up, the other contract could call\n            // back into the current contract and modify the state or cause\n            // effects (ether payout) to be performed multiple times.\n            // If functions called internally include interaction with external\n            // contracts, they also have to be considered interaction with\n            // external contracts.\n\n            // 1. Conditions\n            if (block.timestamp < auctionEndTime)\n                revert AuctionNotYetEnded();\n            if (ended)\n                revert AuctionEndAlreadyCalled();\n\n            // 2. Effects\n            ended = true;\n            emit AuctionEnded(highestBidder, highestBid);\n\n            // 3. Interaction\n            (bool success, ) = beneficiary.call{value: highestBid}(\"\");\n            require(success);\n        }\n    }\n\nBlind Auction\n=============\n\nThe previous open auction is extended to a blind auction in the following. The\nadvantage of a blind auction is that there is no time pressure towards the end\nof the bidding period. Creating a blind auction on a transparent computing\nplatform might sound like a contradiction, but cryptography comes to the\nrescue.\n\nDuring the **bidding period**, a bidder does not actually send their bid, but\nonly a hashed version of it.  Since it is currently considered practically\nimpossible to find two (sufficiently long) values whose hash values are equal,\nthe bidder commits to the bid by that.  After the end of the bidding period,\nthe bidders have to reveal their bids: They send their values unencrypted, and\nthe contract checks that the hash value is the same as the one provided during\nthe bidding period.\n\nAnother challenge is how to make the auction **binding and blind** at the same\ntime: The only way to prevent the bidder from just not sending the Ether after\nthey won the auction is to make them send it together with the bid. Since value\ntransfers cannot be blinded in Ethereum, anyone can see the value.\n\nThe following contract solves this problem by accepting any value that is\nlarger than the highest bid. Since this can of course only be checked during\nthe reveal phase, some bids might be **invalid**, and this is on purpose (it\neven provides an explicit flag to place invalid bids with high-value\ntransfers): Bidders can confuse competition by placing several high or low\ninvalid bids.\n\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.4;\n    contract BlindAuction {\n        struct Bid {\n            bytes32 blindedBid;\n            uint deposit;\n        }\n\n        address payable public beneficiary;\n        uint public biddingEnd;\n        uint public revealEnd;\n        bool public ended;\n\n        mapping(address => Bid[]) public bids;\n\n        address public highestBidder;\n        uint public highestBid;\n\n        // Allowed withdrawals of previous bids\n        mapping(address => uint) pendingReturns;\n\n        event AuctionEnded(address winner, uint highestBid);\n\n        // Errors that describe failures.\n\n        /// The function has been called too early.\n        /// Try again at `time`.\n        error TooEarly(uint time);\n        /// The function has been called too late.\n        /// It cannot be called after `time`.\n        error TooLate(uint time);\n        /// The function auctionEnd has already been called.\n        error AuctionEndAlreadyCalled();\n\n        // Modifiers are a convenient way to validate inputs to\n        // functions. `onlyBefore` is applied to `bid` below:\n        // The new function body is the modifier's body where\n        // `_` is replaced by the old function body.\n        modifier onlyBefore(uint time) {\n            if (block.timestamp >= time) revert TooLate(time);\n            _;\n        }\n        modifier onlyAfter(uint time) {\n            if (block.timestamp <= time) revert TooEarly(time);\n            _;\n        }\n\n        constructor(\n            uint biddingTime,\n            uint revealTime,\n            address payable beneficiaryAddress\n        ) {\n            beneficiary = beneficiaryAddress;\n            biddingEnd = block.timestamp + biddingTime;\n            revealEnd = biddingEnd + revealTime;\n        }\n\n        /// Place a blinded bid with `blindedBid` =\n        /// keccak256(abi.encodePacked(value, fake, secret)).\n        /// The sent ether is only refunded if the bid is correctly\n        /// revealed in the revealing phase. The bid is valid if the\n        /// ether sent together with the bid is at least \"value\" and\n        /// \"fake\" is not true. Setting \"fake\" to true and sending\n        /// not the exact amount are ways to hide the real bid but\n        /// still make the required deposit. The same address can\n        /// place multiple bids.\n        function bid(bytes32 blindedBid)\n            external\n            payable\n            onlyBefore(biddingEnd)\n        {\n            bids[msg.sender].push(Bid({\n                blindedBid: blindedBid,\n                deposit: msg.value\n            }));\n        }\n\n        /// Reveal your blinded bids. You will get a refund for all\n        /// correctly blinded invalid bids and for all bids except for\n        /// the totally highest.\n        function reveal(\n            uint[] calldata values,\n            bool[] calldata fakes,\n            bytes32[] calldata secrets\n        )\n            external\n            onlyAfter(biddingEnd)\n            onlyBefore(revealEnd)\n        {\n            uint length = bids[msg.sender].length;\n            require(values.length == length);\n            require(fakes.length == length);\n            require(secrets.length == length);\n\n            uint refund;\n            for (uint i = 0; i < length; i++) {\n                Bid storage bidToCheck = bids[msg.sender][i];\n                (uint value, bool fake, bytes32 secret) =\n                        (values[i], fakes[i], secrets[i]);\n                if (bidToCheck.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) {\n                    // Bid was not actually revealed.\n                    // Do not refund deposit.\n                    continue;\n                }\n                refund += bidToCheck.deposit;\n                if (!fake && bidToCheck.deposit >= value) {\n                    if (placeBid(msg.sender, value))\n                        refund -= value;\n                }\n                // Make it impossible for the sender to re-claim\n                // the same deposit.\n                bidToCheck.blindedBid = bytes32(0);\n            }\n            (bool success, ) = payable(msg.sender).call{value: refund}(\"\");\n            require(success);\n        }\n\n        /// Withdraw a bid that was overbid.\n        function withdraw() external {\n            uint amount = pendingReturns[msg.sender];\n            if (amount > 0) {\n                // It is important to set this to zero because the recipient\n                // can call this function again as part of the receiving call\n                // before `call` returns (see the remark above about\n                // conditions -> effects -> interaction).\n                pendingReturns[msg.sender] = 0;\n\n                (bool success, ) = payable(msg.sender).call{value: amount}(\"\");\n                require(success);\n            }\n        }\n\n        /// End the auction and send the highest bid\n        /// to the beneficiary.\n        function auctionEnd()\n            external\n            onlyAfter(revealEnd)\n        {\n            if (ended) revert AuctionEndAlreadyCalled();\n            emit AuctionEnded(highestBidder, highestBid);\n            ended = true;\n            (bool success, ) = beneficiary.call{value: highestBid}(\"\");\n            require(success);\n        }\n\n        // This is an \"internal\" function which means that it\n        // can only be called from the contract itself (or from\n        // derived contracts).\n        function placeBid(address bidder, uint value) internal\n                returns (bool success)\n        {\n            if (value <= highestBid) {\n                return false;\n            }\n            if (highestBidder != address(0)) {\n                // Refund the previously highest bidder.\n                pendingReturns[highestBidder] += highestBid;\n            }\n            highestBid = value;\n            highestBidder = bidder;\n            return true;\n        }\n    }\n"
  },
  {
    "path": "docs/examples/micropayment.rst",
    "content": "********************\nMicropayment Channel\n********************\n\nIn this section, we will learn how to build an example implementation\nof a payment channel. It uses cryptographic signatures to make\nrepeated transfers of Ether between the same parties secure, instantaneous, and\nwithout transaction fees. For the example, we need to understand how to\nsign and verify signatures, and setup the payment channel.\n\nCreating and verifying signatures\n=================================\n\nImagine Alice wants to send some Ether to Bob, i.e.\nAlice is the sender and Bob is the recipient.\n\nAlice only needs to send cryptographically signed messages off-chain\n(e.g. via email) to Bob and it is similar to writing checks.\n\nAlice and Bob use signatures to authorize transactions, which is possible with smart contracts on Ethereum.\nAlice will build a simple smart contract that lets her transmit Ether, but instead of calling a function herself\nto initiate a payment, she will let Bob do that, and therefore pay the transaction fee.\n\nThe contract will work as follows:\n\n    1. Alice deploys the ``ReceiverPays`` contract, attaching enough Ether to cover the payments that will be made.\n    2. Alice authorizes a payment by signing a message with her private key.\n    3. Alice sends the cryptographically signed message to Bob. The message does not need to be kept secret\n       (explained later), and the mechanism for sending it does not matter.\n    4. Bob claims his payment by presenting the signed message to the smart contract, it verifies the\n       authenticity of the message and then releases the funds.\n\nCreating the signature\n----------------------\n\nAlice does not need to interact with the Ethereum network\nto sign the transaction, the process is completely offline.\nIn this tutorial, we will sign messages in the browser\nusing `web3.js <https://github.com/web3/web3.js>`_ and\n`MetaMask <https://metamask.io>`_, using the method described in `EIP-712 <https://github.com/ethereum/EIPs/pull/712>`_,\nas it provides a number of other security benefits.\n\n.. code-block:: javascript\n\n    /// Hashing first makes things easier\n    var hash = web3.utils.sha3(\"message to sign\");\n    web3.eth.personal.sign(hash, web3.eth.defaultAccount, function () { console.log(\"Signed\"); });\n\n.. note::\n  The ``web3.eth.personal.sign`` prepends the length of the\n  message to the signed data. Since we hash first, the message\n  will always be exactly 32 bytes long, and thus this length\n  prefix is always the same.\n\nWhat to Sign\n------------\n\nFor a contract that fulfills payments, the signed message must include:\n\n    1. The recipient's address.\n    2. The amount to be transferred.\n    3. Protection against replay attacks.\n\nA replay attack is when a signed message is reused to claim\nauthorization for a second action. To avoid replay attacks\nwe use the same technique as in Ethereum transactions themselves,\na so-called nonce, which is the number of transactions sent by\nan account. The smart contract checks if a nonce is used multiple times.\n\nAnother type of replay attack can occur when the owner\ndeploys a ``ReceiverPays`` smart contract, makes some\npayments, and then destroys the contract. Later, they decide\nto deploy the ``RecipientPays`` smart contract again, but the\nnew contract does not know the nonces used in the previous\ndeployment, so the attacker can use the old messages again.\n\nAlice can protect against this attack by including the\ncontract's address in the message, and only messages containing\nthe contract's address itself will be accepted. You can find\nan example of this in the first two lines of the ``claimPayment()``\nfunction of the full contract at the end of this section.\n\nFurthermore, instead of destroying the contract by calling ``selfdestruct``,\nwhich is currently deprecated, we will disable the contract's functionalities by freezing it,\nresulting in the reversion of any call after it being frozen.\n\nPacking arguments\n-----------------\n\nNow that we have identified what information to include in the signed message,\nwe are ready to put the message together, hash it, and sign it. For simplicity,\nwe concatenate the data. The `ethereumjs-abi <https://github.com/ethereumjs/ethereumjs-abi>`_\nlibrary provides a function called ``soliditySHA3`` that mimics the behavior of\nSolidity's ``keccak256`` function applied to arguments encoded using ``abi.encodePacked``.\nHere is a JavaScript function that creates the proper signature for the ``ReceiverPays`` example:\n\n.. code-block:: javascript\n\n    // recipient is the address that should be paid.\n    // amount, in wei, specifies how much ether should be sent.\n    // nonce can be any unique number to prevent replay attacks\n    // contractAddress is used to prevent cross-contract replay attacks\n    function signPayment(recipient, amount, nonce, contractAddress, callback) {\n        var hash = \"0x\" + abi.soliditySHA3(\n            [\"address\", \"uint256\", \"uint256\", \"address\"],\n            [recipient, amount, nonce, contractAddress]\n        ).toString(\"hex\");\n\n        web3.eth.personal.sign(hash, web3.eth.defaultAccount, callback);\n    }\n\nRecovering the Message Signer in Solidity\n-----------------------------------------\n\nIn general, ECDSA signatures consist of two parameters,\n``r`` and ``s``. Signatures in Ethereum include a third\nparameter called ``v``, that you can use to verify which\naccount's private key was used to sign the message, and\nthe transaction's sender. Solidity provides a built-in\nfunction :ref:`ecrecover <mathematical-and-cryptographic-functions>` that\naccepts a message along with the ``r``, ``s`` and ``v`` parameters\nand returns the address that was used to sign the message.\n\nExtracting the Signature Parameters\n-----------------------------------\n\nSignatures produced by web3.js are the concatenation of ``r``,\n``s`` and ``v``, so the first step is to split these parameters\napart. You can do this on the client-side, but doing it inside\nthe smart contract means you only need to send one signature\nparameter rather than three. Splitting apart a byte array into\nits constituent parts is a mess, so we use\n:doc:`inline assembly <assembly>` to do the job in the ``splitSignature``\nfunction (the third function in the full contract at the end of this section).\n\nComputing the Message Hash\n--------------------------\n\nThe smart contract needs to know exactly what parameters were signed, and so it\nmust recreate the message from the parameters and use that for signature verification.\nThe functions ``prefixed`` and ``recoverSigner`` do this in the ``claimPayment`` function.\n\nThe full contract\n-----------------\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    contract Owned {\n        address payable owner;\n        constructor() {\n            owner = payable(msg.sender);\n        }\n    }\n\n    contract Freezable is Owned {\n        bool private _frozen = false;\n\n        modifier notFrozen() {\n            require(!_frozen, \"Inactive Contract.\");\n            _;\n        }\n\n        function freeze() internal {\n            if (msg.sender == owner)\n                _frozen = true;\n        }\n    }\n\n    contract ReceiverPays is Freezable {\n        mapping(uint256 => bool) usedNonces;\n\n        constructor() payable {}\n\n        function claimPayment(uint256 amount, uint256 nonce, bytes memory signature)\n            external\n            notFrozen\n        {\n            require(!usedNonces[nonce]);\n            usedNonces[nonce] = true;\n\n            // this recreates the message that was signed on the client\n            bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this)));\n            require(recoverSigner(message, signature) == owner);\n            (bool success, ) = payable(msg.sender).call{value: amount}(\"\");\n            require(success);\n        }\n\n        /// freeze the contract and reclaim the leftover funds.\n        function shutdown()\n            external\n            notFrozen\n        {\n            require(msg.sender == owner);\n            freeze();\n            (bool success, ) = payable(msg.sender).call{value: address(this).balance}(\"\");\n            require(success);\n        }\n\n        /// signature methods.\n        function splitSignature(bytes memory sig)\n            internal\n            pure\n            returns (uint8 v, bytes32 r, bytes32 s)\n        {\n            require(sig.length == 65);\n\n            assembly {\n                // first 32 bytes, after the length prefix.\n                r := mload(add(sig, 32))\n                // second 32 bytes.\n                s := mload(add(sig, 64))\n                // final byte (first byte of the next 32 bytes).\n                v := byte(0, mload(add(sig, 96)))\n            }\n\n            return (v, r, s);\n        }\n\n        function recoverSigner(bytes32 message, bytes memory sig)\n            internal\n            pure\n            returns (address)\n        {\n            (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig);\n            return ecrecover(message, v, r, s);\n        }\n\n        /// builds a prefixed hash to mimic the behavior of eth_sign.\n        function prefixed(bytes32 hash) internal pure returns (bytes32) {\n            return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n        }\n    }\n\n\nWriting a Simple Payment Channel\n================================\n\nAlice now builds a simple but complete implementation of a payment\nchannel. Payment channels use cryptographic signatures to make\nrepeated transfers of Ether securely, instantaneously, and without transaction fees.\n\nWhat is a Payment Channel?\n--------------------------\n\nPayment channels allow participants to make repeated transfers of Ether\nwithout using transactions. This means that you can avoid the delays and\nfees associated with transactions. We are going to explore a simple\nunidirectional payment channel between two parties (Alice and Bob). It involves three steps:\n\n    1. Alice funds a smart contract with Ether. This \"opens\" the payment channel.\n    2. Alice signs messages that specify how much of that Ether is owed to the recipient. This step is repeated for each payment.\n    3. Bob \"closes\" the payment channel, withdrawing his portion of the Ether and sending the remainder back to the sender.\n\n.. note::\n  Only steps 1 and 3 require Ethereum transactions, step 2 means that the sender\n  transmits a cryptographically signed message to the recipient via off chain\n  methods (e.g. email). This means only two transactions are required to support\n  any number of transfers.\n\nBob is guaranteed to receive his funds because the smart contract escrows the\nEther and honours a valid signed message. The smart contract also enforces a\ntimeout, so Alice is guaranteed to eventually recover her funds even if the\nrecipient refuses to close the channel. It is up to the participants in a payment\nchannel to decide how long to keep it open. For a short-lived transaction,\nsuch as paying an internet café for each minute of network access, the payment\nchannel may be kept open for a limited duration. On the other hand, for a\nrecurring payment, such as paying an employee an hourly wage, the payment channel\nmay be kept open for several months or years.\n\nOpening the Payment Channel\n---------------------------\n\nTo open the payment channel, Alice deploys the smart contract, attaching\nthe Ether to be escrowed and specifying the intended recipient and a\nmaximum duration for the channel to exist. This is the ``constructor``\nin the ``SimplePaymentChannel`` contract, at the end of this section.\n\nMaking Payments\n---------------\n\nAlice makes payments by sending signed messages to Bob.\nThis step is performed entirely outside of the Ethereum network.\nMessages are cryptographically signed by the sender and then transmitted directly to the recipient.\n\nEach message includes the following information:\n\n    * The smart contract's address, used to prevent cross-contract replay attacks.\n    * The total amount of Ether that is owed to the recipient so far.\n\nA payment channel is closed just once, at the end of a series of transfers.\nBecause of this, only one of the messages sent is redeemed. This is why\neach message specifies a cumulative total amount of Ether owed, rather than the\namount of the individual micropayment. The recipient will naturally choose to\nredeem the most recent message because that is the one with the highest total.\nThe nonce per-message is not needed anymore, because the smart contract only\nhonours a single message. The address of the smart contract is still used\nto prevent a message intended for one payment channel from being used for a different channel.\n\nHere is the modified JavaScript code to cryptographically sign a message from the previous section:\n\n.. code-block:: javascript\n\n    function constructPaymentMessage(contractAddress, amount) {\n        return abi.soliditySHA3(\n            [\"address\", \"uint256\"],\n            [contractAddress, amount]\n        );\n    }\n\n    function signMessage(message, callback) {\n        web3.eth.personal.sign(\n            \"0x\" + message.toString(\"hex\"),\n            web3.eth.defaultAccount,\n            callback\n        );\n    }\n\n    // contractAddress is used to prevent cross-contract replay attacks.\n    // amount, in wei, specifies how much Ether should be sent.\n\n    function signPayment(contractAddress, amount, callback) {\n        var message = constructPaymentMessage(contractAddress, amount);\n        signMessage(message, callback);\n    }\n\n\nClosing the Payment Channel\n---------------------------\n\nWhen Bob is ready to receive his funds, it is time to\nclose the payment channel by calling a ``close`` function on the smart contract.\nClosing the channel pays the recipient the Ether they are owed and\ndeactivates the contract by freezing it, sending any remaining Ether back to Alice. To\nclose the channel, Bob needs to provide a message signed by Alice.\n\nThe smart contract must verify that the message contains a valid signature from the sender.\nThe process for doing this verification is the same as the process the recipient uses.\nThe Solidity functions ``isValidSignature`` and ``recoverSigner`` work just like their\nJavaScript counterparts in the previous section, with the latter function borrowed from the ``ReceiverPays`` contract.\n\nOnly the payment channel recipient can call the ``close`` function,\nwho naturally passes the most recent payment message because that message\ncarries the highest total owed. If the sender were allowed to call this function,\nthey could provide a message with a lower amount and cheat the recipient out of what they are owed.\n\nThe function verifies the signed message matches the given parameters.\nIf everything checks out, the recipient is sent their portion of the Ether,\nand the sender is sent the remaining funds via a ``transfer``.\nYou can see the ``close`` function in the full contract.\n\nChannel Expiration\n-------------------\n\nBob can close the payment channel at any time, but if they fail to do so,\nAlice needs a way to recover her escrowed funds. An *expiration* time was set\nat the time of contract deployment. Once that time is reached, Alice can call\n``claimTimeout`` to recover her funds. You can see the ``claimTimeout`` function in the full contract.\n\nAfter this function is called, Bob can no longer receive any Ether,\nso it is important that Bob closes the channel before the expiration is reached.\n\nThe full contract\n-----------------\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    contract Frozeable {\n        bool private _frozen = false;\n\n        modifier notFrozen() {\n            require(!_frozen, \"Inactive Contract.\");\n            _;\n        }\n\n        function freeze() internal {\n            _frozen = true;\n        }\n    }\n\n    contract SimplePaymentChannel is Frozeable {\n        address payable public sender;    // The account sending payments.\n        address payable public recipient; // The account receiving the payments.\n        uint256 public expiration;        // Timeout in case the recipient never closes.\n\n        constructor (address payable recipientAddress, uint256 duration)\n            payable\n        {\n            sender = payable(msg.sender);\n            recipient = recipientAddress;\n            expiration = block.timestamp + duration;\n        }\n\n        /// the recipient can close the channel at any time by presenting a\n        /// signed amount from the sender. the recipient will be sent that amount,\n        /// and the remainder will go back to the sender\n        function close(uint256 amount, bytes memory signature)\n            external\n            notFrozen\n        {\n            require(msg.sender == recipient);\n            require(isValidSignature(amount, signature));\n\n            freeze();\n            (bool success, ) = recipient.call{value: amount}(\"\");\n            require(success);\n            (success, ) = sender.call{value: address(this).balance}(\"\");\n            require(success);\n        }\n\n        /// the sender can extend the expiration at any time\n        function extend(uint256 newExpiration)\n            external\n            notFrozen\n        {\n            require(msg.sender == sender);\n            require(newExpiration > expiration);\n\n            expiration = newExpiration;\n        }\n\n        /// if the timeout is reached without the recipient closing the channel,\n        /// then the Ether is released back to the sender.\n        function claimTimeout()\n            external\n            notFrozen\n        {\n            require(block.timestamp >= expiration);\n            freeze();\n            (bool success, ) = sender.call{value: address(this).balance}(\"\");\n            require(success);\n        }\n\n        function isValidSignature(uint256 amount, bytes memory signature)\n            internal\n            view\n            returns (bool)\n        {\n            bytes32 message = prefixed(keccak256(abi.encodePacked(this, amount)));\n            // check that the signature is from the payment sender\n            return recoverSigner(message, signature) == sender;\n        }\n\n        /// All functions below this are just taken from the chapter\n        /// 'creating and verifying signatures' chapter.\n        function splitSignature(bytes memory sig)\n            internal\n            pure\n            returns (uint8 v, bytes32 r, bytes32 s)\n        {\n            require(sig.length == 65);\n\n            assembly {\n                // first 32 bytes, after the length prefix\n                r := mload(add(sig, 32))\n                // second 32 bytes\n                s := mload(add(sig, 64))\n                // final byte (first byte of the next 32 bytes)\n                v := byte(0, mload(add(sig, 96)))\n            }\n            return (v, r, s);\n        }\n\n        function recoverSigner(bytes32 message, bytes memory sig)\n            internal\n            pure\n            returns (address)\n        {\n            (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig);\n            return ecrecover(message, v, r, s);\n        }\n\n        /// builds a prefixed hash to mimic the behavior of eth_sign.\n        function prefixed(bytes32 hash) internal pure returns (bytes32) {\n            return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n        }\n    }\n\n\n.. note::\n  The function ``splitSignature`` does not use all security\n  checks. A real implementation should use a more rigorously tested library,\n  such as openzeppelin's `version  <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol>`_ of this code.\n\nVerifying Payments\n------------------\n\nUnlike in the previous section, messages in a payment channel aren't\nredeemed right away. The recipient keeps track of the latest message and\nredeems it when it's time to close the payment channel. This means it's\ncritical that the recipient perform their own verification of each message.\nOtherwise there is no guarantee that the recipient will be able to get paid\nin the end.\n\nThe recipient should verify each message using the following process:\n\n    1. Verify that the contract address in the message matches the payment channel.\n    2. Verify that the new total is the expected amount.\n    3. Verify that the new total does not exceed the amount of Ether escrowed.\n    4. Verify that the signature is valid and comes from the payment channel sender.\n\nWe'll use the `ethereumjs-util <https://github.com/ethereumjs/ethereumjs-util>`_\nlibrary to write this verification. The final step can be done a number of ways,\nand we use JavaScript. The following code borrows the ``constructPaymentMessage`` function from the signing **JavaScript code** above:\n\n.. code-block:: javascript\n\n    // this mimics the prefixing behavior of the eth_sign JSON-RPC method.\n    function prefixed(hash) {\n        return ethereumjs.ABI.soliditySHA3(\n            [\"string\", \"bytes32\"],\n            [\"\\x19Ethereum Signed Message:\\n32\", hash]\n        );\n    }\n\n    function recoverSigner(message, signature) {\n        var split = ethereumjs.Util.fromRpcSig(signature);\n        var publicKey = ethereumjs.Util.ecrecover(message, split.v, split.r, split.s);\n        var signer = ethereumjs.Util.pubToAddress(publicKey).toString(\"hex\");\n        return signer;\n    }\n\n    function isValidSignature(contractAddress, amount, signature, expectedSigner) {\n        var message = prefixed(constructPaymentMessage(contractAddress, amount));\n        var signer = recoverSigner(message, signature);\n        return signer.toLowerCase() ==\n            ethereumjs.Util.stripHexPrefix(expectedSigner).toLowerCase();\n    }\n"
  },
  {
    "path": "docs/examples/modular.rst",
    "content": ".. index:: contract;modular, modular contract\n\n*****************\nModular Contracts\n*****************\n\nA modular approach to building your contracts helps you reduce the complexity\nand improve the readability which will help to identify bugs and vulnerabilities\nduring development and code review.\nIf you specify and control the behavior of each module in isolation, the\ninteractions you have to consider are only those between the module specifications\nand not every other moving part of the contract.\nIn the example below, the contract uses the ``move`` method\nof the ``Balances`` :ref:`library <libraries>` to check that balances sent between\naddresses match what you expect. In this way, the ``Balances`` library\nprovides an isolated component that properly tracks balances of accounts.\nIt is easy to verify that the ``Balances`` library never produces negative balances or overflows\nand the sum of all balances is an invariant across the lifetime of the contract.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.0 <0.9.0;\n\n    library Balances {\n        function move(mapping(address => uint256) storage balances, address from, address to, uint amount) internal {\n            require(balances[from] >= amount);\n            require(balances[to] + amount >= balances[to]);\n            balances[from] -= amount;\n            balances[to] += amount;\n        }\n    }\n\n    contract Token {\n        mapping(address => uint256) balances;\n        using Balances for *;\n        mapping(address => mapping(address => uint256)) allowed;\n\n        event Transfer(address from, address to, uint amount);\n        event Approval(address owner, address spender, uint amount);\n\n        function transfer(address to, uint amount) external returns (bool success) {\n            balances.move(msg.sender, to, amount);\n            emit Transfer(msg.sender, to, amount);\n            return true;\n\n        }\n\n        function transferFrom(address from, address to, uint amount) external returns (bool success) {\n            require(allowed[from][msg.sender] >= amount);\n            allowed[from][msg.sender] -= amount;\n            balances.move(from, to, amount);\n            emit Transfer(from, to, amount);\n            return true;\n        }\n\n        function approve(address spender, uint tokens) external returns (bool success) {\n            require(allowed[msg.sender][spender] == 0, \"\");\n            allowed[msg.sender][spender] = tokens;\n            emit Approval(msg.sender, spender, tokens);\n            return true;\n        }\n\n        function balanceOf(address tokenOwner) external view returns (uint balance) {\n            return balances[tokenOwner];\n        }\n    }\n"
  },
  {
    "path": "docs/examples/safe-remote.rst",
    "content": ".. index:: purchase, remote purchase, escrow\n\n********************\nSafe Remote Purchase\n********************\n\nPurchasing goods remotely currently requires multiple parties that need to trust each other.\nThe simplest configuration involves a seller and a buyer. The buyer would like to receive\nan item from the seller and the seller would like to get some compensation, e.g. Ether,\nin return. The problematic part is the shipment here: There is no way to determine for\nsure that the item arrived at the buyer.\n\nThere are multiple ways to solve this problem, but all fall short in one or the other way.\nIn the following example, both parties have to put twice the value of the item into the\ncontract as escrow. As soon as this happened, the Ether will stay locked inside\nthe contract until the buyer confirms that they received the item. After that,\nthe buyer is returned the value (half of their deposit) and the seller gets three\ntimes the value (their deposit plus the value). The idea behind\nthis is that both parties have an incentive to resolve the situation or otherwise\ntheir Ether is locked forever.\n\nThis contract of course does not solve the problem, but gives an overview of how\nyou can use state machine-like constructs inside a contract.\n\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.4;\n    contract Purchase {\n        uint public value;\n        address payable public seller;\n        address payable public buyer;\n\n        enum State { Created, Locked, Release, Inactive }\n        // The state variable has a default value of the first member, `State.created`\n        State public state;\n\n        modifier condition(bool condition_) {\n            require(condition_);\n            _;\n        }\n\n        /// Only the buyer can call this function.\n        error OnlyBuyer();\n        /// Only the seller can call this function.\n        error OnlySeller();\n        /// The function cannot be called at the current state.\n        error InvalidState();\n        /// The provided value has to be even.\n        error ValueNotEven();\n\n        modifier onlyBuyer() {\n            if (msg.sender != buyer)\n                revert OnlyBuyer();\n            _;\n        }\n\n        modifier onlySeller() {\n            if (msg.sender != seller)\n                revert OnlySeller();\n            _;\n        }\n\n        modifier inState(State state_) {\n            if (state != state_)\n                revert InvalidState();\n            _;\n        }\n\n        event Aborted();\n        event PurchaseConfirmed();\n        event ItemReceived();\n        event SellerRefunded();\n\n        // Ensure that `msg.value` is an even number.\n        // Division will truncate if it is an odd number.\n        // Check via multiplication that it wasn't an odd number.\n        constructor() payable {\n            seller = payable(msg.sender);\n            value = msg.value / 2;\n            if ((2 * value) != msg.value)\n                revert ValueNotEven();\n        }\n\n        /// Abort the purchase and reclaim the ether.\n        /// Can only be called by the seller before\n        /// the contract is locked.\n        function abort()\n            external\n            onlySeller\n            inState(State.Created)\n        {\n            emit Aborted();\n            state = State.Inactive;\n            // We use call here directly. It is\n            // reentrancy-safe, because it is the\n            // last call in this function and we\n            // already changed the state.\n            (bool success, ) = seller.call{value: address(this).balance}(\"\");\n            require(success);\n        }\n\n        /// Confirm the purchase as buyer.\n        /// Transaction has to include `2 * value` ether.\n        /// The ether will be locked until confirmReceived\n        /// is called.\n        function confirmPurchase()\n            external\n            inState(State.Created)\n            condition(msg.value == (2 * value))\n            payable\n        {\n            emit PurchaseConfirmed();\n            buyer = payable(msg.sender);\n            state = State.Locked;\n        }\n\n        /// Confirm that you (the buyer) received the item.\n        /// This will release the locked ether.\n        function confirmReceived()\n            external\n            onlyBuyer\n            inState(State.Locked)\n        {\n            emit ItemReceived();\n            // It is important to change the state first because\n            // otherwise, the contracts called using `call` below\n            // can call in again here.\n            state = State.Release;\n\n            (bool success, ) = buyer.call{value: value}(\"\");\n            require(success);\n        }\n\n        /// This function refunds the seller, i.e.\n        /// pays back the locked funds of the seller.\n        function refundSeller()\n            external\n            onlySeller\n            inState(State.Release)\n        {\n            emit SellerRefunded();\n            // It is important to change the state first because\n            // otherwise, the contracts called using `call` below\n            // can call in again here.\n            state = State.Inactive;\n\n            (bool success, ) = seller.call{value: 3 * value}(\"\");\n            require(success);\n        }\n    }\n"
  },
  {
    "path": "docs/examples/voting.rst",
    "content": ".. index:: voting, ballot\n\n.. _voting:\n\n******\nVoting\n******\n\nThe following contract is quite complex, but showcases\na lot of Solidity's features. It implements a voting\ncontract. Of course, the main problems of electronic\nvoting is how to assign voting rights to the correct\npersons and how to prevent manipulation. We will not\nsolve all problems here, but at least we will show\nhow delegated voting can be done so that vote counting\nis **automatic and completely transparent** at the\nsame time.\n\nThe idea is to create one contract per ballot,\nproviding a short name for each option.\nThen the creator of the contract who serves as\nchairperson will give the right to vote to each\naddress individually.\n\nThe persons behind the addresses can then choose\nto either vote themselves or to delegate their\nvote to a person they trust.\n\nAt the end of the voting time, ``winningProposal()``\nwill return the proposal with the largest number\nof votes.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n    /// @title Voting with delegation.\n    contract Ballot {\n        // This declares a new complex type which will\n        // be used for variables later.\n        // It will represent a single voter.\n        struct Voter {\n            uint weight; // weight is accumulated by delegation\n            bool voted;  // if true, that person already voted\n            address delegate; // person delegated to\n            uint vote;   // index of the voted proposal\n        }\n\n        // This is a type for a single proposal.\n        struct Proposal {\n            bytes32 name;   // short name (up to 32 bytes)\n            uint voteCount; // number of accumulated votes\n        }\n\n        address public chairperson;\n\n        // This declares a state variable that\n        // stores a `Voter` struct for each possible address.\n        mapping(address => Voter) public voters;\n\n        // A dynamically-sized array of `Proposal` structs.\n        Proposal[] public proposals;\n\n        /// Create a new ballot to choose one of `proposalNames`.\n        constructor(bytes32[] memory proposalNames) {\n            chairperson = msg.sender;\n            voters[chairperson].weight = 1;\n\n            // For each of the provided proposal names,\n            // create a new proposal object and add it\n            // to the end of the array.\n            for (uint i = 0; i < proposalNames.length; i++) {\n                // `Proposal({...})` creates a temporary\n                // Proposal object and `proposals.push(...)`\n                // appends it to the end of `proposals`.\n                proposals.push(Proposal({\n                    name: proposalNames[i],\n                    voteCount: 0\n                }));\n            }\n        }\n\n        // Give `voter` the right to vote on this ballot.\n        // May only be called by `chairperson`.\n        function giveRightToVote(address voter) external {\n            // If the first argument of `require` evaluates\n            // to `false`, execution terminates and all\n            // changes to the state and to Ether balances\n            // are reverted.\n            // This used to consume all gas in old EVM versions, but\n            // not anymore.\n            // It is often a good idea to use `require` to check if\n            // functions are called correctly.\n            // As a second argument, you can also provide an\n            // explanation about what went wrong.\n            require(\n                msg.sender == chairperson,\n                \"Only chairperson can give right to vote.\"\n            );\n            require(\n                !voters[voter].voted,\n                \"The voter already voted.\"\n            );\n            require(voters[voter].weight == 0);\n            voters[voter].weight = 1;\n        }\n\n        /// Delegate your vote to the voter `to`.\n        function delegate(address to) external {\n            // assigns reference\n            Voter storage sender = voters[msg.sender];\n            require(sender.weight != 0, \"You have no right to vote\");\n            require(!sender.voted, \"You already voted.\");\n\n            require(to != msg.sender, \"Self-delegation is disallowed.\");\n\n            // Forward the delegation as long as\n            // `to` also delegated.\n            // In general, such loops are very dangerous,\n            // because if they run too long, they might\n            // need more gas than is available in a block.\n            // In this case, the delegation will not be executed,\n            // but in other situations, such loops might\n            // cause a contract to get \"stuck\" completely.\n            while (voters[to].delegate != address(0)) {\n                to = voters[to].delegate;\n\n                // We found a loop in the delegation, not allowed.\n                require(to != msg.sender, \"Found loop in delegation.\");\n            }\n\n            Voter storage delegate_ = voters[to];\n\n            // Voters cannot delegate to accounts that cannot vote.\n            require(delegate_.weight >= 1);\n\n            // Since `sender` is a reference, this\n            // modifies `voters[msg.sender]`.\n            sender.voted = true;\n            sender.delegate = to;\n\n            if (delegate_.voted) {\n                // If the delegate already voted,\n                // directly add to the number of votes\n                proposals[delegate_.vote].voteCount += sender.weight;\n            } else {\n                // If the delegate did not vote yet,\n                // add to her weight.\n                delegate_.weight += sender.weight;\n            }\n        }\n\n        /// Give your vote (including votes delegated to you)\n        /// to proposal `proposals[proposal].name`.\n        function vote(uint proposal) external {\n            Voter storage sender = voters[msg.sender];\n            require(sender.weight != 0, \"Has no right to vote\");\n            require(!sender.voted, \"Already voted.\");\n            sender.voted = true;\n            sender.vote = proposal;\n\n            // If `proposal` is out of the range of the array,\n            // this will throw automatically and revert all\n            // changes.\n            proposals[proposal].voteCount += sender.weight;\n        }\n\n        /// @dev Computes the winning proposal taking all\n        /// previous votes into account.\n        function winningProposal() public view\n                returns (uint winningProposal_)\n        {\n            uint winningVoteCount = 0;\n            for (uint p = 0; p < proposals.length; p++) {\n                if (proposals[p].voteCount > winningVoteCount) {\n                    winningVoteCount = proposals[p].voteCount;\n                    winningProposal_ = p;\n                }\n            }\n        }\n\n        // Calls winningProposal() function to get the index\n        // of the winner contained in the proposals array and then\n        // returns the name of the winner\n        function winnerName() external view\n                returns (bytes32 winnerName_)\n        {\n            winnerName_ = proposals[winningProposal()].name;\n        }\n    }\n\n\nPossible Improvements\n=====================\n\nCurrently, many transactions are needed to\nassign the rights to vote to all participants.\nMoreover, if two or more proposals have the same\nnumber of votes, ``winningProposal()`` is not able\nto register a tie. Can you think of a way to fix these issues?"
  },
  {
    "path": "docs/ext/html_extra_template_renderer.py",
    "content": "import os.path\n\n\ndef render_html_extra_templates(app):\n    if app.builder.format != 'html':\n        # Non-HTML builders do not provide .templates.render_string(). Note that a HTML\n        # builder is still used also when building some other formats like json or epub.\n        return\n\n    for input_path, template_config in app.config.html_extra_templates.items():\n        # Requiring absolute paths simplifies the implementation.\n        if not os.path.isabs(input_path):\n            raise RuntimeError(f\"Template input path is not absolute: {input_path}\")\n        if not os.path.isabs(template_config['target']):\n            raise RuntimeError(f\"Template target path is not absolute: {template_config['target']}\")\n\n        with open(input_path, 'r', encoding='utf8') as input_file:\n            # This runs Jinja2, which supports rendering {{ }} tags among other things.\n            rendered_template = app.builder.templates.render_string(\n                input_file.read(),\n                template_config['context'],\n            )\n\n        with open(template_config['target'], 'w', encoding='utf8') as target_file:\n            target_file.write(rendered_template)\n\n        app.config.html_extra_path.append(template_config['target'])\n\n\ndef setup(app):\n    app.add_config_value('html_extra_templates', default={}, rebuild='', types=dict)\n\n    # Register a handler for the env-before-read-docs event. Any event that's fired before static\n    # files get copied would do.\n    app.connect(\n        'env-before-read-docs',\n        lambda app, env, docnames: render_html_extra_templates(app)\n    )\n\n    return {\n        # NOTE: Need to access _raw_config here because setup() runs before app.config is ready.\n        'version': app.config._raw_config['version'],  # pylint: disable=protected-access\n        'parallel_read_safe': True,\n        'parallel_write_safe': True,\n    }\n"
  },
  {
    "path": "docs/ext/remix_code_links.py",
    "content": "import base64\nimport docutils  # pragma pylint: disable=import-error\n\nfrom sphinx.util import logging  # pragma pylint: disable=import-error\n\n# NOTE: 2000 should generally be safe for all browsers, while 8000 for most of them.\nMAX_SAFE_URL_LENGTH = 10000\n\nlogger = logging.getLogger(__name__)\n\n\ndef insert_node_before(child, new_sibling):\n    assert child in child.parent.children\n\n    for position, node in enumerate(child.parent.children):\n        if node == child:\n            child.parent.insert(position, new_sibling)\n            break\n\n\ndef remix_code_url(source_code, language, solidity_version):\n    # NOTE: base64 encoded data may contain +, = and / characters. Remix seems to handle them just\n    # fine without any escaping.\n    base64_encoded_source = base64.b64encode(source_code.encode('utf-8')).decode('ascii')\n    return f\"https://remix.ethereum.org/?#language={language}&version={solidity_version}&code={base64_encoded_source}\"\n\n\ndef build_remix_link_node(url):\n    reference_node = docutils.nodes.reference('', 'open in Remix', internal=False, refuri=url, target='_blank')\n    reference_node['classes'].append('remix-link')\n\n    paragraph_node = docutils.nodes.paragraph()\n    paragraph_node['classes'].append('remix-link-container')\n    paragraph_node.append(reference_node)\n    return paragraph_node\n\n\ndef insert_remix_link(app, doctree, solidity_version):\n    if app.builder.format != 'html' or app.builder.name == 'epub':\n        return\n\n    for literal_block_node in doctree.traverse(docutils.nodes.literal_block):\n        assert 'language' in literal_block_node.attributes\n        language = literal_block_node.attributes['language'].lower()\n        if language not in ['solidity', 'yul']:\n            continue\n\n        text_nodes = list(literal_block_node.traverse(docutils.nodes.Text))\n        assert len(text_nodes) == 1\n\n        remix_url = remix_code_url(text_nodes[0], language, solidity_version)\n        url_length = len(remix_url.encode('utf-8'))\n        if url_length > MAX_SAFE_URL_LENGTH:\n            logger.warning(\n                \"Remix URL generated from the code snippet exceeds the maximum safe URL length \"\n                \" (%d > %d bytes).\",\n                url_length,\n                MAX_SAFE_URL_LENGTH,\n                location=(literal_block_node.source, literal_block_node.line),\n            )\n\n        insert_node_before(literal_block_node, build_remix_link_node(remix_url))\n\n\ndef setup(app):\n    # NOTE: Need to access _raw_config here because setup() runs before app.config is ready.\n    solidity_version = app.config._raw_config['version']  # pylint: disable=protected-access\n\n    app.connect(\n        'doctree-resolved',\n        lambda app, doctree, docname: insert_remix_link(app, doctree, solidity_version)\n    )\n\n    return {\n        'version': solidity_version,\n        'parallel_read_safe': True,\n        'parallel_write_safe': True,\n    }\n"
  },
  {
    "path": "docs/grammar/SolidityLexer.g4",
    "content": "lexer grammar SolidityLexer;\n\n/**\n * Keywords reserved for future use in Solidity.\n */\nReservedKeywords:\n\t'after' | 'alias' | 'apply' | 'auto' | 'byte' | 'case' | 'copyof' | 'default' | 'define' | 'final'\n\t| 'implements' | 'in' | 'inline' | 'let' | 'macro' | 'match' | 'mutable' | 'null' | 'of'\n\t| 'partial' | 'promise' | 'reference' | 'relocatable' | 'sealed' | 'sizeof' | 'static'\n\t| 'supports' | 'switch' | 'typedef' | 'typeof' | 'var';\n\nAbstract: 'abstract';\nAddress: 'address';\nAnonymous: 'anonymous';\nAs: 'as';\nAssembly: 'assembly' -> pushMode(AssemblyBlockMode);\nAt: 'at'; // not a real keyword\nBool: 'bool';\nBreak: 'break';\nBytes: 'bytes';\nCalldata: 'calldata';\nCatch: 'catch';\nConstant: 'constant';\nConstructor: 'constructor';\nContinue: 'continue';\nContract: 'contract';\nDelete: 'delete';\nDo: 'do';\nElse: 'else';\nEmit: 'emit';\nEnum: 'enum';\nError: 'error'; // not a real keyword\nEvent: 'event';\nExternal: 'external';\nFallback: 'fallback';\nFalse: 'false';\nFixed: 'fixed' | ('fixed' [1-9][0-9]* 'x' [1-9][0-9]*);\n/**\n * Bytes types of fixed length.\n */\nFixedBytes:\n\t'bytes1' | 'bytes2' | 'bytes3' | 'bytes4' | 'bytes5' | 'bytes6' | 'bytes7' | 'bytes8' |\n\t'bytes9' | 'bytes10' | 'bytes11' | 'bytes12' | 'bytes13' | 'bytes14' | 'bytes15' | 'bytes16' |\n\t'bytes17' | 'bytes18' | 'bytes19' | 'bytes20' | 'bytes21' | 'bytes22' | 'bytes23' | 'bytes24' |\n\t'bytes25' | 'bytes26' | 'bytes27' | 'bytes28' | 'bytes29' | 'bytes30' | 'bytes31' | 'bytes32';\nFor: 'for';\nFrom: 'from'; // not a real keyword\nFunction: 'function';\nGlobal: 'global'; // not a real keyword\nHex: 'hex';\nIf: 'if';\nImmutable: 'immutable';\nImport: 'import';\nIndexed: 'indexed';\nInterface: 'interface';\nInternal: 'internal';\nIs: 'is';\nLayout: 'layout'; // not a real keyword\nLibrary: 'library';\nMapping: 'mapping';\nMemory: 'memory';\nModifier: 'modifier';\nNew: 'new';\n/**\n * Unit denomination for numbers.\n */\nSubDenomination: 'wei' | 'gwei' | 'ether' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years';\nOverride: 'override';\nPayable: 'payable';\nPragma: 'pragma' -> pushMode(PragmaMode);\nPrivate: 'private';\nPublic: 'public';\nPure: 'pure';\nReceive: 'receive';\nReturn: 'return';\nReturns: 'returns';\nRevert: 'revert'; // not a real keyword\n/**\n * Sized signed integer types.\n * int is an alias of int256.\n */\nSignedIntegerType:\n\t'int' | 'int8' | 'int16' | 'int24' | 'int32' | 'int40' | 'int48' | 'int56' | 'int64' |\n\t'int72' | 'int80' | 'int88' | 'int96' | 'int104' | 'int112' | 'int120' | 'int128' |\n\t'int136' | 'int144' | 'int152' | 'int160' | 'int168' | 'int176' | 'int184' | 'int192' |\n\t'int200' | 'int208' | 'int216' | 'int224' | 'int232' | 'int240' | 'int248' | 'int256';\nStorage: 'storage';\nString: 'string';\nStruct: 'struct';\nTransient: 'transient';  // not a real keyword\nTrue: 'true';\nTry: 'try';\nType: 'type';\nUfixed: 'ufixed' | ('ufixed' [1-9][0-9]+ 'x' [1-9][0-9]+);\nUnchecked: 'unchecked';\nUnicode: 'unicode';\n/**\n * Sized unsigned integer types.\n * uint is an alias of uint256.\n */\nUnsignedIntegerType:\n\t'uint' | 'uint8' | 'uint16' | 'uint24' | 'uint32' | 'uint40' | 'uint48' | 'uint56' | 'uint64' |\n\t'uint72' | 'uint80' | 'uint88' | 'uint96' | 'uint104' | 'uint112' | 'uint120' | 'uint128' |\n\t'uint136' | 'uint144' | 'uint152' | 'uint160' | 'uint168' | 'uint176' | 'uint184' | 'uint192' |\n\t'uint200' | 'uint208' | 'uint216' | 'uint224' | 'uint232' | 'uint240' | 'uint248' | 'uint256';\nUsing: 'using';\nView: 'view';\nVirtual: 'virtual';\nWhile: 'while';\n\nLParen: '(';\nRParen: ')';\nLBrack: '[';\nRBrack: ']';\nLBrace: '{';\nRBrace: '}';\nColon: ':';\nSemicolon: ';';\nPeriod: '.';\nConditional: '?';\nDoubleArrow: '=>';\nRightArrow: '->';\n\nAssign: '=';\nAssignBitOr: '|=';\nAssignBitXor: '^=';\nAssignBitAnd: '&=';\nAssignShl: '<<=';\nAssignSar: '>>=';\nAssignShr: '>>>=';\nAssignAdd: '+=';\nAssignSub: '-=';\nAssignMul: '*=';\nAssignDiv: '/=';\nAssignMod: '%=';\n\nComma: ',';\nOr: '||';\nAnd: '&&';\nBitOr: '|';\nBitXor: '^';\nBitAnd: '&';\nShl: '<<';\nSar: '>>';\nShr: '>>>';\nAdd: '+';\nSub: '-';\nMul: '*';\nDiv: '/';\nMod: '%';\nExp: '**';\n\nEqual: '==';\nNotEqual: '!=';\nLessThan: '<';\nGreaterThan: '>';\nLessThanOrEqual: '<=';\nGreaterThanOrEqual: '>=';\nNot: '!';\nBitNot: '~';\nInc: '++';\nDec: '--';\n//@doc:inline\nDoubleQuote: '\"';\n//@doc:inline\nSingleQuote: '\\'';\n\n/**\n * A non-empty quoted string literal restricted to printable characters.\n */\nNonEmptyStringLiteral: '\"' DoubleQuotedStringCharacter+ '\"' | '\\'' SingleQuotedStringCharacter+ '\\'';\n/**\n * An empty string literal\n */\nEmptyStringLiteral: '\"' '\"' | '\\'' '\\'';\n\n// Note that this will also be used for Yul string literals.\n//@doc:inline\nfragment DoubleQuotedStringCharacter: DoubleQuotedPrintable | EscapeSequence;\n// Note that this will also be used for Yul string literals.\n//@doc:inline\nfragment SingleQuotedStringCharacter: SingleQuotedPrintable | EscapeSequence;\n/**\n * Any printable character except single quote or back slash.\n */\nfragment SingleQuotedPrintable: [\\u0020-\\u0026\\u0028-\\u005B\\u005D-\\u007E];\n/**\n * Any printable character except double quote or back slash.\n */\nfragment DoubleQuotedPrintable: [\\u0020-\\u0021\\u0023-\\u005B\\u005D-\\u007E];\n/**\n  * Escape sequence.\n  * Apart from common single character escape sequences, line breaks can be escaped\n  * as well as four hex digit unicode escapes \\\\uXXXX and two digit hex escape sequences \\\\xXX are allowed.\n  */\nfragment EscapeSequence:\n\t'\\\\' (\n\t\t['\"\\\\nrt\\n\\r]\n\t\t| 'u' HexCharacter HexCharacter HexCharacter HexCharacter\n\t\t| 'x' HexCharacter HexCharacter\n\t);\n/**\n * A single quoted string literal allowing arbitrary unicode characters.\n */\nUnicodeStringLiteral: 'unicode' (('\"' DoubleQuotedUnicodeStringCharacter* '\"') | ('\\'' SingleQuotedUnicodeStringCharacter* '\\''));\n//@doc:inline\nfragment DoubleQuotedUnicodeStringCharacter: ~[\"\\r\\n\\\\] | EscapeSequence;\n//@doc:inline\nfragment SingleQuotedUnicodeStringCharacter: ~['\\r\\n\\\\] | EscapeSequence;\n\n// Note that this will also be used for Yul hex string literals.\n/**\n * Hex strings need to consist of an even number of hex digits that may be grouped using underscores.\n */\nHexString: 'hex' (('\"' EvenHexDigits? '\"') | ('\\'' EvenHexDigits? '\\''));\n/**\n * Hex numbers consist of a prefix and an arbitrary number of hex digits that may be delimited by underscores.\n */\nHexNumber: '0' 'x' HexDigits;\n//@doc:inline\nfragment HexDigits: HexCharacter ('_'? HexCharacter)*;\n//@doc:inline\nfragment EvenHexDigits: HexCharacter HexCharacter ('_'? HexCharacter HexCharacter)*;\n//@doc:inline\nfragment HexCharacter: [0-9A-Fa-f];\n\n/**\n * Scanned but not used by any rule, i.e, disallowed.\n * solc parser considers number starting with '0', not immediately followed by '.' or 'x' as\n * octal, even if non octal digits '8' and '9' are present.\n */\nOctalNumber: '0' DecimalDigits ('.' DecimalDigits)?;\n\n\n/**\n * A decimal number literal consists of decimal digits that may be delimited by underscores and\n * an optional positive or negative exponent.\n * If the digits contain a decimal point, the literal has fixed point type.\n */\nDecimalNumber: (DecimalDigits | (DecimalDigits? '.' DecimalDigits)) ([eE] '-'? DecimalDigits)?;\n//@doc:inline\nfragment DecimalDigits: [0-9] ('_'? [0-9])* ;\n\n\n/**\n * This is needed to avoid successfully parsing a number followed by a string with no whitespace between.\n */\nDecimalNumberFollowedByIdentifier: DecimalNumber Identifier;\n\n\n/**\n * An identifier in solidity has to start with a letter, a dollar-sign or an underscore and\n * may additionally contain numbers after the first symbol.\n */\nIdentifier: IdentifierStart IdentifierPart*;\n//@doc:inline\nfragment IdentifierStart: [a-zA-Z$_];\n//@doc:inline\nfragment IdentifierPart: [a-zA-Z0-9$_];\n\nWS: [ \\t\\r\\n\\u000C]+ -> skip ;\nCOMMENT: '/*' .*? '*/' -> channel(HIDDEN) ;\nLINE_COMMENT: '//' ~[\\r\\n]* -> channel(HIDDEN);\n\nmode AssemblyBlockMode;\n\n//@doc:inline\nAssemblyDialect: '\"evmasm\"';\nAssemblyLBrace: '{' -> popMode, pushMode(YulMode);\n\nAssemblyFlagString: '\"' DoubleQuotedStringCharacter+ '\"';\n\nAssemblyBlockLParen: '(';\nAssemblyBlockRParen: ')';\nAssemblyBlockComma: ',';\n\nAssemblyBlockWS: [ \\t\\r\\n\\u000C]+ -> skip ;\nAssemblyBlockCOMMENT: '/*' .*? '*/' -> channel(HIDDEN) ;\nAssemblyBlockLINE_COMMENT: '//' ~[\\r\\n]* -> channel(HIDDEN) ;\n\nmode YulMode;\n\nYulBreak: 'break';\nYulCase: 'case';\nYulContinue: 'continue';\nYulDefault: 'default';\nYulFalse: 'false';\nYulFor: 'for';\nYulFunction: 'function';\nYulIf: 'if';\nYulLeave: 'leave';\nYulLet: 'let';\nYulSwitch: 'switch';\nYulTrue: 'true';\nYulHex: 'hex';\n\n/**\n * Builtin functions in the EVM Yul dialect.\n */\nYulEVMBuiltin:\n\t'stop' | 'add' | 'sub' | 'mul' | 'div' | 'sdiv' | 'mod' | 'smod' | 'exp' | 'not'\n\t| 'lt' | 'gt' | 'slt' | 'sgt' | 'eq' | 'iszero' | 'and' | 'or' | 'xor' | 'byte'\n\t| 'shl' | 'shr' | 'sar' | 'clz' | 'addmod' | 'mulmod' | 'signextend' | 'keccak256'\n\t| 'pop' | 'mload' | 'mstore' | 'mstore8' | 'sload' | 'sstore' | 'tload' | 'tstore'| 'msize' | 'gas'\n\t| 'address' | 'balance' | 'selfbalance' | 'caller' | 'callvalue' | 'calldataload'\n\t| 'calldatasize' | 'calldatacopy' | 'extcodesize' | 'extcodecopy' | 'returndatasize'\n\t| 'returndatacopy' | 'mcopy' | 'extcodehash' | 'create' | 'create2' | 'call' | 'callcode'\n\t| 'delegatecall' | 'staticcall' | 'return' | 'revert' | 'selfdestruct' | 'invalid'\n\t| 'log0' | 'log1' | 'log2' | 'log3' | 'log4' | 'chainid' | 'origin' | 'gasprice'\n\t| 'blockhash' | 'blobhash' | 'coinbase' | 'timestamp' | 'number' | 'difficulty'\n\t| 'prevrandao' | 'gaslimit' | 'basefee' | 'blobbasefee';\n\nYulLBrace: '{' -> pushMode(YulMode);\nYulRBrace: '}' -> popMode;\nYulLParen: '(';\nYulRParen: ')';\nYulAssign: ':=';\nYulPeriod: '.';\nYulComma: ',';\nYulArrow: '->';\n\n/**\n * Yul identifiers consist of letters, dollar signs, underscores and numbers, but may not start with a number.\n * In inline assembly there cannot be dots in user-defined identifiers. Instead see yulPath for expressions\n * consisting of identifiers with dots.\n */\nYulIdentifier: YulIdentifierStart YulIdentifierPart*;\n//@doc:inline\nfragment YulIdentifierStart: [a-zA-Z$_];\n//@doc:inline\nfragment YulIdentifierPart: [a-zA-Z0-9$_];\n/**\n * Hex literals in Yul consist of a prefix and one or more hexadecimal digits.\n */\nYulHexNumber: '0' 'x' [0-9a-fA-F]+;\n/**\n * Decimal literals in Yul may be zero or any sequence of decimal digits without leading zeroes.\n */\nYulDecimalNumber: '0' | ([1-9] [0-9]*);\n/**\n * String literals in Yul consist of one or more double-quoted or single-quoted strings\n * that may contain escape sequences and printable characters except unescaped line breaks or\n * unescaped double-quotes or single-quotes, respectively.\n */\nYulStringLiteral:\n\t'\"' DoubleQuotedStringCharacter* '\"'\n\t| '\\'' SingleQuotedStringCharacter* '\\'';\n//@doc:inline\nYulHexStringLiteral: HexString;\n\nYulWS: [ \\t\\r\\n\\u000C]+ -> skip ;\nYulCOMMENT: '/*' .*? '*/' -> channel(HIDDEN) ;\nYulLINE_COMMENT: '//' ~[\\r\\n]* -> channel(HIDDEN) ;\n\nmode PragmaMode;\n\n/**\n * Pragma token. Can contain any kind of symbol except a semicolon.\n * Note that currently the solidity parser only allows a subset of this.\n */\n//@doc:name pragma-token\n//@doc:no-diagram\nPragmaToken: ~[;]+;\nPragmaSemicolon: ';' -> popMode;\n\nPragmaWS: [ \\t\\r\\n\\u000C]+ -> skip ;\nPragmaCOMMENT: '/*' .*? '*/' -> channel(HIDDEN) ;\nPragmaLINE_COMMENT: '//' ~[\\r\\n]* -> channel(HIDDEN) ;\n"
  },
  {
    "path": "docs/grammar/SolidityParser.g4",
    "content": "/**\n * Solidity is a statically typed, contract-oriented, high-level language for implementing smart contracts on the Ethereum platform.\n */\nparser grammar SolidityParser;\n\noptions { tokenVocab=SolidityLexer; }\n\n/**\n * On top level, Solidity allows pragmas, import directives, and\n * definitions of contracts, interfaces, libraries, structs, enums and constants.\n */\nsourceUnit: (\n\tpragmaDirective\n\t| importDirective\n\t| usingDirective\n\t| contractDefinition\n\t| interfaceDefinition\n\t| libraryDefinition\n\t| functionDefinition\n\t| constantVariableDeclaration\n\t| structDefinition\n\t| enumDefinition\n\t| userDefinedValueTypeDefinition\n\t| errorDefinition\n\t| eventDefinition\n)* EOF;\n\n//@doc: inline\npragmaDirective: Pragma PragmaToken+ PragmaSemicolon;\n\n/**\n * Import directives import identifiers from different files.\n */\nimportDirective:\n\tImport (\n\t\t(path (As unitAlias=identifier)?)\n\t\t| (symbolAliases From path)\n\t\t| (Mul As unitAlias=identifier From path)\n\t) Semicolon;\n//@doc: inline\n//@doc:name aliases\nimportAliases: symbol=identifier (As alias=identifier)?;\n/**\n * Path of a file to be imported.\n */\npath: NonEmptyStringLiteral;\n/**\n * List of aliases for symbols to be imported.\n */\nsymbolAliases: LBrace aliases+=importAliases (Comma aliases+=importAliases)* RBrace;\n\n/**\n * Top-level definition of a contract.\n */\ncontractDefinition\nlocals [boolean layoutSet=false, boolean inheritanceSet=false]\n:\n\tAbstract? Contract name=identifier\n\t(\n\t\t{!$layoutSet}? Layout At expression {$layoutSet = true;}\n\t\t| {!$inheritanceSet}? inheritanceSpecifierList {$inheritanceSet = true;}\n\t)*\n\tLBrace contractBodyElement* RBrace;\n/**\n * Top-level definition of an interface.\n */\ninterfaceDefinition:\n\tInterface name=identifier\n\tinheritanceSpecifierList?\n\tLBrace contractBodyElement* RBrace;\n/**\n * Top-level definition of a library.\n */\nlibraryDefinition: Library name=identifier LBrace contractBodyElement* RBrace;\n\n//@doc:inline\ninheritanceSpecifierList:\n\tIs inheritanceSpecifiers+=inheritanceSpecifier\n\t(Comma inheritanceSpecifiers+=inheritanceSpecifier)*?;\n/**\n * Inheritance specifier for contracts and interfaces.\n * Can optionally supply base constructor arguments.\n */\ninheritanceSpecifier: name=identifierPath arguments=callArgumentList?;\n\n/**\n * Declarations that can be used in contracts, interfaces and libraries.\n *\n * Note that interfaces and libraries may not contain constructors, interfaces may not contain state variables\n * and libraries may not contain fallback, receive functions nor non-constant state variables.\n */\ncontractBodyElement:\n\tconstructorDefinition\n\t| functionDefinition\n\t| modifierDefinition\n\t| fallbackFunctionDefinition\n\t| receiveFunctionDefinition\n\t| structDefinition\n\t| enumDefinition\n\t| userDefinedValueTypeDefinition\n\t| stateVariableDeclaration\n\t| eventDefinition\n\t| errorDefinition\n\t| usingDirective;\n//@doc:inline\nnamedArgument: name=identifier Colon value=expression;\n/**\n * Arguments when calling a function or a similar callable object.\n * The arguments are either given as comma separated list or as map of named arguments.\n */\ncallArgumentList: LParen ((expression (Comma expression)*)? | LBrace (namedArgument (Comma namedArgument)*)? RBrace) RParen;\n/**\n * Qualified name.\n */\nidentifierPath: identifier (Period identifier)*;\n\n/**\n * Call to a modifier. If the modifier takes no arguments, the argument list can be skipped entirely\n * (including opening and closing parentheses).\n */\nmodifierInvocation: identifierPath callArgumentList?;\n/**\n * Visibility for functions and function types.\n */\nvisibility: Internal | External | Private | Public;\n/**\n * A list of parameters, such as function arguments or return values.\n */\nparameterList: parameters+=parameterDeclaration (Comma parameters+=parameterDeclaration)*;\n//@doc:inline\nparameterDeclaration: type=typeName location=dataLocation? name=identifier?;\n/**\n * Definition of a constructor.\n * Must always supply an implementation.\n * Note that specifying internal or public visibility is deprecated.\n */\nconstructorDefinition\nlocals[boolean payableSet = false, boolean visibilitySet = false]\n:\n\tConstructor LParen (arguments=parameterList)? RParen\n\t(\n\t\tmodifierInvocation\n\t\t| {!$payableSet}? Payable {$payableSet = true;}\n\t\t| {!$visibilitySet}? Internal {$visibilitySet = true;}\n\t\t| {!$visibilitySet}? Public {$visibilitySet = true;}\n\t)*\n\tbody=block;\n\n/**\n * State mutability for function types.\n * The default mutability 'non-payable' is assumed if no mutability is specified.\n */\nstateMutability: Pure | View | Payable;\n/**\n * An override specifier used for functions, modifiers or state variables.\n * In cases where there are ambiguous declarations in several base contracts being overridden,\n * a complete list of base contracts has to be given.\n */\noverrideSpecifier: Override (LParen overrides+=identifierPath (Comma overrides+=identifierPath)* RParen)?;\n/**\n * The definition of contract, library, interface or free functions.\n * Depending on the context in which the function is defined, further restrictions may apply,\n * e.g. functions in interfaces have to be unimplemented, i.e. may not contain a body block.\n */\nfunctionDefinition\nlocals[\n\tboolean visibilitySet = false,\n\tboolean mutabilitySet = false,\n\tboolean virtualSet = false,\n\tboolean overrideSpecifierSet = false,\n]\n:\n\tFunction (identifier | Fallback | Receive)\n\tLParen (arguments=parameterList)? RParen\n\t(\n\t\t{!$visibilitySet}? visibility {$visibilitySet = true;}\n\t\t| {!$mutabilitySet}? stateMutability {$mutabilitySet = true;}\n\t\t| modifierInvocation\n\t\t| {!$virtualSet}? Virtual {$virtualSet = true;}\n\t\t| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}\n\t )*\n\t(Returns LParen returnParameters=parameterList RParen)?\n\t(Semicolon | body=block);\n\n/**\n * The definition of a modifier.\n * Note that within the body block of a modifier, the underscore cannot be used as identifier,\n * but is used as placeholder statement for the body of a function to which the modifier is applied.\n */\nmodifierDefinition\nlocals[\n\tboolean virtualSet = false,\n\tboolean overrideSpecifierSet = false\n]\n:\n\tModifier name=identifier\n\t(LParen (arguments=parameterList)? RParen)?\n\t(\n\t\t{!$virtualSet}? Virtual {$virtualSet = true;}\n\t\t| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}\n\t)*\n\t(Semicolon | body=block);\n\n/**\n * Definition of the special fallback function.\n */\nfallbackFunctionDefinition\nlocals[\n\tboolean visibilitySet = false,\n\tboolean mutabilitySet = false,\n\tboolean virtualSet = false,\n\tboolean overrideSpecifierSet = false,\n\tboolean hasParameters = false\n]\n:\n\tkind=Fallback LParen (parameterList { $hasParameters = true; } )? RParen\n\t(\n\t\t{!$visibilitySet}? External {$visibilitySet = true;}\n\t\t| {!$mutabilitySet}? stateMutability {$mutabilitySet = true;}\n\t\t| modifierInvocation\n\t\t| {!$virtualSet}? Virtual {$virtualSet = true;}\n\t\t| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}\n\t)*\n\t( {$hasParameters}? Returns LParen returnParameters=parameterList RParen | {!$hasParameters}? )\n\t(Semicolon | body=block);\n\n/**\n * Definition of the special receive function.\n */\nreceiveFunctionDefinition\nlocals[\n\tboolean visibilitySet = false,\n\tboolean mutabilitySet = false,\n\tboolean virtualSet = false,\n\tboolean overrideSpecifierSet = false\n]\n:\n\tkind=Receive LParen RParen\n\t(\n\t\t{!$visibilitySet}? External {$visibilitySet = true;}\n\t\t| {!$mutabilitySet}? Payable {$mutabilitySet = true;}\n\t\t| modifierInvocation\n\t\t| {!$virtualSet}? Virtual {$virtualSet = true;}\n\t\t| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}\n\t )*\n\t(Semicolon | body=block);\n\n/**\n * Definition of a struct. Can occur at top-level within a source unit or within a contract, library or interface.\n */\nstructDefinition: Struct name=identifier LBrace members=structMember+ RBrace;\n/**\n * The declaration of a named struct member.\n */\nstructMember: type=typeName name=identifier Semicolon;\n/**\n * Definition of an enum. Can occur at top-level within a source unit or within a contract, library or interface.\n */\nenumDefinition: Enum name=identifier LBrace enumValues+=identifier (Comma enumValues+=identifier)* RBrace;\n/**\n * Definition of a user defined value type. Can occur at top-level within a source unit or within a contract, library or interface.\n */\nuserDefinedValueTypeDefinition:\n\tType name=identifier Is elementaryTypeName[true] Semicolon;\n\n/**\n * The declaration of a state variable.\n */\nstateVariableDeclaration\nlocals [boolean constantnessSet = false, boolean visibilitySet = false, boolean overrideSpecifierSet = false, boolean locationSet = false]\n:\n\ttype=typeName\n\t(\n\t\t{!$visibilitySet}? Public {$visibilitySet = true;}\n\t\t| {!$visibilitySet}? Private {$visibilitySet = true;}\n\t\t| {!$visibilitySet}? Internal {$visibilitySet = true;}\n\t\t| {!$constantnessSet}? Constant {$constantnessSet = true;}\n\t\t| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}\n\t\t| {!$constantnessSet}? Immutable {$constantnessSet = true;}\n\t\t| {!$locationSet}? Transient {$locationSet = true;}\n\t)*\n\tname=identifier\n\t(Assign initialValue=expression)?\n\tSemicolon;\n\n/**\n * The declaration of a constant variable.\n */\nconstantVariableDeclaration\n:\n\ttype=typeName\n\tConstant\n\tname=identifier\n\tAssign initialValue=expression\n\tSemicolon;\n\n/**\n * Parameter of an event.\n */\neventParameter: type=typeName Indexed? name=identifier?;\n/**\n * Definition of an event. Can occur in contracts, libraries or interfaces.\n */\neventDefinition:\n\tEvent name=identifier\n\tLParen (parameters+=eventParameter (Comma parameters+=eventParameter)*)? RParen\n\tAnonymous?\n\tSemicolon;\n\n/**\n * Parameter of an error.\n */\nerrorParameter: type=typeName name=identifier?;\n/**\n * Definition of an error.\n */\nerrorDefinition:\n\tError name=identifier\n\tLParen (parameters+=errorParameter (Comma parameters+=errorParameter)*)? RParen\n\tSemicolon;\n\n/**\n * Operators that users are allowed to implement for some types with `using for`.\n */\nuserDefinableOperator:\n\tBitAnd\n\t| BitNot\n\t| BitOr\n\t| BitXor\n\t| Add\n\t| Div\n\t| Mod\n\t| Mul\n\t| Sub\n\t| Equal\n\t| GreaterThan\n\t| GreaterThanOrEqual\n\t| LessThan\n\t| LessThanOrEqual\n\t| NotEqual;\n\n/**\n * Using directive to attach library functions and free functions to types.\n * Can occur within contracts and libraries and at the file level.\n */\nusingDirective:\n  Using (\n    identifierPath\n    | (LBrace usingAliases (Comma usingAliases)* RBrace)\n  ) For (Mul | typeName) Global? Semicolon;\n\nusingAliases: identifierPath (As userDefinableOperator)?;\n\n/**\n * A type name can be an elementary type, a function type, a mapping type, a user-defined type\n * (e.g. a contract or struct) or an array type.\n */\ntypeName: elementaryTypeName[true] | functionTypeName | mappingType | identifierPath | typeName LBrack expression? RBrack;\nelementaryTypeName[boolean allowAddressPayable]: Address | {$allowAddressPayable}? Address Payable | Bool | String | Bytes | SignedIntegerType | UnsignedIntegerType | FixedBytes | Fixed | Ufixed;\nfunctionTypeName\nlocals [boolean visibilitySet = false, boolean mutabilitySet = false]\n:\n\tFunction LParen (arguments=parameterList)? RParen\n\t(\n\t\t{!$visibilitySet}? visibility {$visibilitySet = true;}\n\t\t| {!$mutabilitySet}? stateMutability {$mutabilitySet = true;}\n\t)*\n\t(Returns LParen returnParameters=parameterList RParen)?;\n\n/**\n * The declaration of a single variable.\n */\nvariableDeclaration: type=typeName location=dataLocation? name=identifier;\ndataLocation: Memory | Storage | Calldata;\n\n/**\n * Complex expression.\n * Can be an index access, an index range access, a member access, a function call (with optional function call options),\n * a type conversion, an unary or binary expression, a comparison or assignment, a ternary expression,\n * a new-expression (i.e. a contract creation or the allocation of a dynamic memory array),\n * a tuple, an inline array or a primary expression (i.e. an identifier, literal or type name).\n */\nexpression:\n\texpression LBrack index=expression? RBrack # IndexAccess\n\t| expression LBrack startIndex=expression? Colon endIndex=expression? RBrack # IndexRangeAccess\n\t| expression Period (identifier | Address) # MemberAccess\n\t| expression LBrace (namedArgument (Comma namedArgument)*) RBrace # FunctionCallOptions\n\t| expression callArgumentList # FunctionCall\n\t| Payable callArgumentList # PayableConversion\n\t| Type LParen typeName RParen # MetaType\n\t| (Inc | Dec | Not | BitNot | Delete | Sub) expression # UnaryPrefixOperation\n\t| expression (Inc | Dec) # UnarySuffixOperation\n\t|<assoc=right> expression Exp expression # ExpOperation\n\t| expression (Mul | Div | Mod) expression # MulDivModOperation\n\t| expression (Add | Sub) expression # AddSubOperation\n\t| expression (Shl | Sar | Shr) expression # ShiftOperation\n\t| expression BitAnd expression # BitAndOperation\n\t| expression BitXor expression # BitXorOperation\n\t| expression BitOr expression # BitOrOperation\n\t| expression (LessThan | GreaterThan | LessThanOrEqual | GreaterThanOrEqual) expression # OrderComparison\n\t| expression (Equal | NotEqual) expression # EqualityComparison\n\t| expression And expression # AndOperation\n\t| expression Or expression # OrOperation\n\t|<assoc=right> expression Conditional expression Colon expression # Conditional\n\t|<assoc=right> expression assignOp expression # Assignment\n\t| New typeName # NewExpr\n\t| tupleExpression # Tuple\n\t| inlineArrayExpression # InlineArray\n\t| (\n\t\tidentifier\n\t\t| literal\n\t\t| literalWithSubDenomination\n\t\t| elementaryTypeName[false]\n\t  ) # PrimaryExpression\n;\n\n//@doc:inline\nassignOp: Assign | AssignBitOr | AssignBitXor | AssignBitAnd | AssignShl | AssignSar | AssignShr | AssignAdd | AssignSub | AssignMul | AssignDiv | AssignMod;\ntupleExpression: LParen (expression? ( Comma expression?)* ) RParen;\n/**\n * An inline array expression denotes a statically sized array of the common type of the contained expressions.\n */\ninlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack;\n\n/**\n * Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers.\n */\nidentifier: Identifier | From | Error | Revert | Global | Transient | Layout | At;\n\nliteral: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral;\n\nliteralWithSubDenomination: numberLiteral SubDenomination;\n\nbooleanLiteral: True | False;\n/**\n * A full string literal consists of either one or several consecutive quoted strings.\n */\nstringLiteral: (NonEmptyStringLiteral | EmptyStringLiteral)+;\n/**\n * A full hex string literal that consists of either one or several consecutive hex strings.\n */\nhexStringLiteral: HexString+;\n/**\n * A full unicode string literal that consists of either one or several consecutive unicode strings.\n */\nunicodeStringLiteral: UnicodeStringLiteral+;\n\n/**\n * Number literals can be decimal or hexadecimal numbers with an optional unit.\n */\nnumberLiteral: DecimalNumber | HexNumber;\n\n/**\n * A curly-braced block of statements. Opens its own scope.\n */\nblock:\n\tLBrace ( statement | uncheckedBlock )* RBrace;\n\nuncheckedBlock: Unchecked block;\n\nstatement:\n\tblock\n\t| simpleStatement\n\t| ifStatement\n\t| forStatement\n\t| whileStatement\n\t| doWhileStatement\n\t| continueStatement\n\t| breakStatement\n\t| tryStatement\n\t| returnStatement\n\t| emitStatement\n\t| revertStatement\n\t| assemblyStatement\n;\n\n//@doc:inline\nsimpleStatement: variableDeclarationStatement | expressionStatement;\n/**\n * If statement with optional else part.\n */\nifStatement: If LParen expression RParen statement (Else statement)?;\n/**\n * For statement with optional init, condition and post-loop part.\n */\nforStatement: For LParen (simpleStatement | Semicolon) (expressionStatement | Semicolon) expression? RParen statement;\nwhileStatement: While LParen expression RParen statement;\ndoWhileStatement: Do statement While LParen expression RParen Semicolon;\n/**\n * A continue statement. Only allowed inside for, while or do-while loops.\n */\ncontinueStatement: Continue Semicolon;\n/**\n * A break statement. Only allowed inside for, while or do-while loops.\n */\nbreakStatement: Break Semicolon;\n/**\n * A try statement. The contained expression needs to be an external function call or a contract creation.\n */\ntryStatement: Try expression (Returns LParen returnParameters=parameterList RParen)? block catchClause+;\n/**\n * The catch clause of a try statement.\n */\ncatchClause: Catch (identifier? LParen (arguments=parameterList) RParen)? block;\n\nreturnStatement: Return expression? Semicolon;\n/**\n * An emit statement. The contained expression needs to refer to an event.\n */\nemitStatement: Emit expression callArgumentList Semicolon;\n/**\n * A revert statement. The contained expression needs to refer to an error.\n */\nrevertStatement: Revert expression callArgumentList Semicolon;\n/**\n * An inline assembly block.\n * The contents of an inline assembly block use a separate scanner/lexer, i.e. the set of keywords and\n * allowed identifiers is different inside an inline assembly block.\n */\nassemblyStatement: Assembly AssemblyDialect? assemblyFlags? AssemblyLBrace yulStatement* YulRBrace;\n\n/**\n * Assembly flags.\n * Comma-separated list of double-quoted strings as flags.\n */\nassemblyFlags: AssemblyBlockLParen AssemblyFlagString (AssemblyBlockComma AssemblyFlagString)* AssemblyBlockRParen;\n\n//@doc:inline\nvariableDeclarationList: variableDeclarations+=variableDeclaration (Comma variableDeclarations+=variableDeclaration)*;\n/**\n * A tuple of variable names to be used in variable declarations.\n * May contain empty fields.\n */\nvariableDeclarationTuple:\n\tLParen\n\t\t(Comma* variableDeclarations+=variableDeclaration)\n\t\t(Comma (variableDeclarations+=variableDeclaration)?)*\n\tRParen;\n/**\n * A variable declaration statement.\n * A single variable may be declared without initial value, whereas a tuple of variables can only be\n * declared with initial value.\n */\nvariableDeclarationStatement: ((variableDeclaration (Assign expression)?) | (variableDeclarationTuple Assign expression)) Semicolon;\nexpressionStatement: expression Semicolon;\n\nmappingType: Mapping LParen key=mappingKeyType name=identifier? DoubleArrow value=typeName name=identifier? RParen;\n/**\n * Only elementary types or user defined types are viable as mapping keys.\n */\nmappingKeyType: elementaryTypeName[false] | identifierPath;\n\n/**\n * A Yul statement within an inline assembly block.\n * continue and break statements are only valid within for loops.\n * leave statements are only valid within function bodies.\n */\nyulStatement:\n\tyulBlock\n\t| yulVariableDeclaration\n\t| yulAssignment\n\t| yulFunctionCall\n\t| yulIfStatement\n\t| yulForStatement\n\t| yulSwitchStatement\n\t| YulLeave\n\t| YulBreak\n\t| YulContinue\n\t| yulFunctionDefinition;\n\nyulBlock: YulLBrace yulStatement* YulRBrace;\n\n/**\n * The declaration of one or more Yul variables with optional initial value.\n * If multiple variables are declared, only a function call is a valid initial value.\n */\nyulVariableDeclaration:\n\t(YulLet variables+=YulIdentifier (YulAssign yulExpression)?)\n\t| (YulLet variables+=YulIdentifier (YulComma variables+=YulIdentifier)* (YulAssign yulFunctionCall)?);\n\n/**\n * Any expression can be assigned to a single Yul variable, whereas\n * multi-assignments require a function call on the right-hand side.\n */\nyulAssignment: yulPath YulAssign yulExpression | (yulPath (YulComma yulPath)+) YulAssign yulFunctionCall;\n\nyulIfStatement: YulIf cond=yulExpression body=yulBlock;\n\nyulForStatement: YulFor init=yulBlock cond=yulExpression post=yulBlock body=yulBlock;\n\n//@doc:inline\nyulSwitchCase: YulCase yulLiteral yulBlock;\n/**\n * A Yul switch statement can consist of only a default-case (deprecated) or\n * one or more non-default cases optionally followed by a default-case.\n */\nyulSwitchStatement:\n\tYulSwitch yulExpression\n\t(\n\t\t(yulSwitchCase+ (YulDefault yulBlock)?)\n\t\t| (YulDefault yulBlock)\n\t);\n\nyulFunctionDefinition:\n\tYulFunction YulIdentifier\n\tYulLParen (arguments+=YulIdentifier (YulComma arguments+=YulIdentifier)*)? YulRParen\n\t(YulArrow returnParameters+=YulIdentifier (YulComma returnParameters+=YulIdentifier)*)?\n\tbody=yulBlock;\n\n/**\n * While only identifiers without dots can be declared within inline assembly,\n * paths containing dots can refer to declarations outside the inline assembly block.\n */\nyulPath: YulIdentifier (YulPeriod (YulIdentifier | YulEVMBuiltin))*;\n/**\n * A call to a function with return values can only occur as right-hand side of an assignment or\n * a variable declaration.\n */\nyulFunctionCall: (YulIdentifier | YulEVMBuiltin) YulLParen (yulExpression (YulComma yulExpression)*)? YulRParen;\nyulBoolean: YulTrue | YulFalse;\nyulLiteral: YulDecimalNumber | YulStringLiteral | YulHexNumber | yulBoolean | YulHexStringLiteral;\nyulExpression: yulPath | yulFunctionCall | yulLiteral;\n"
  },
  {
    "path": "docs/grammar.rst",
    "content": "****************\nLanguage Grammar\n****************\n\n.. syntax:autogrammar:: SolidityParser.g4\n   :root-rule: SolidityParser.sourceUnit\n   :undocumented:\n   :cc-to-dash:\n\n.. syntax:autogrammar:: SolidityLexer.g4\n   :root-rule: SolidityParser.sourceUnit\n   :fragments:\n   :cc-to-dash:"
  },
  {
    "path": "docs/index.rst",
    "content": "Solidity\n========\n\nSolidity is an object-oriented, high-level language for implementing smart contracts.\nSmart contracts are programs that govern the behavior of accounts within the Ethereum state.\n\nSolidity is a `curly-bracket language <https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Curly_bracket_languages>`_ designed to target the Ethereum Virtual Machine (EVM).\nIt is influenced by C++, Python, and JavaScript.\nYou can find more details about which languages Solidity has been inspired by in the :doc:`language influences <language-influences>` section.\n\nSolidity is statically typed, supports inheritance, libraries, and complex user-defined types, among other features.\n\nWith Solidity, you can create contracts for uses such as voting, crowdfunding, blind auctions, and multi-signature wallets.\n\nWhen deploying contracts, you should use the latest released version of Solidity.\nApart from exceptional cases, only the latest version receives\n`security fixes <https://github.com/argotorg/solidity/security/policy#supported-versions>`_.\nFurthermore, breaking changes, as well as new features, are introduced regularly.\nWe currently use a 0.y.z version number `to indicate this fast pace of change <https://semver.org/#spec-item-4>`_.\n\n.. warning::\n\n  Solidity recently released the 0.8.x version that introduced a lot of breaking changes.\n  Make sure you read :doc:`the full list <080-breaking-changes>`.\n\nIdeas for improving Solidity or this documentation are always welcome,\nread our :doc:`contributors guide <contributing>` for more details.\n\n.. Hint::\n\n  You can download this documentation as PDF, HTML or Epub\n  by clicking on the versions flyout menu in the bottom-right corner and selecting the preferred download format.\n\n\nGetting Started\n---------------\n\n**1. Understand the Smart Contract Basics**\n\nIf you are new to the concept of smart contracts, we recommend you to get started by digging into the \"Introduction to Smart Contracts\" section, which covers the following:\n\n* :ref:`A simple example smart contract <simple-smart-contract>` written in Solidity.\n* :ref:`Blockchain Basics <blockchain-basics>`.\n* :ref:`The Ethereum Virtual Machine <the-ethereum-virtual-machine>`.\n\n**2. Get to Know Solidity**\n\nOnce you are accustomed to the basics, we recommend you read the :doc:`\"Solidity by Example\" <solidity-by-example>`\nand “Language Description” sections to understand the core concepts of the language.\n\n**3. Install the Solidity Compiler**\n\nThere are various ways to install the Solidity compiler,\nsimply choose your preferred option and follow the steps outlined on the :ref:`installation page <installing-solidity>`.\n\n.. hint::\n  You can try out code examples directly in your browser with the\n  `Remix IDE <https://remix.ethereum.org>`_.\n  Remix is a web browser-based IDE that allows you to write, deploy and administer Solidity smart contracts,\n  without the need to install Solidity locally.\n\n.. warning::\n    As humans write software, it can have bugs.\n    Therefore, you should follow established software development best practices when writing your smart contracts.\n    This includes code review, testing, audits, and correctness proofs.\n    Smart contract users are sometimes more confident with code than their authors,\n    and blockchains and smart contracts have their own unique issues to watch out for,\n    so before working on production code, make sure you read the :ref:`security_considerations` section.\n\n**4. Learn More**\n\nIf you want to learn more about building decentralized applications on Ethereum,\nthe `Ethereum Developer Resources <https://ethereum.org/en/developers/>`_ can help you with further general documentation around Ethereum,\nand a wide selection of tutorials, tools, and development frameworks.\n\nIf you have any questions, you can try searching for answers or asking on the\n`Ethereum StackExchange <https://ethereum.stackexchange.com/>`_,\nor our `Gitter channel <https://gitter.im/ethereum/solidity>`_.\n\n.. _translations:\n\nTranslations\n------------\n\nCommunity contributors help translate this documentation into several languages.\nNote that they have varying degrees of completeness and up-to-dateness.\nThe English version stands as a reference.\n\nYou can switch between languages by clicking on the flyout menu in the bottom-right corner\nand selecting the preferred language.\n\n* `Chinese <https://docs.soliditylang.org/zh-cn/latest/>`_\n* `French <https://docs.soliditylang.org/fr/latest/>`_\n* `Indonesian <https://github.com/solidity-docs/id-indonesian>`_\n* `Japanese <https://github.com/solidity-docs/ja-japanese>`_\n* `Korean <https://github.com/solidity-docs/ko-korean>`_\n* `Persian <https://github.com/solidity-docs/fa-persian>`_\n* `Russian <https://github.com/solidity-docs/ru-russian>`_\n* `Spanish <https://github.com/solidity-docs/es-spanish>`_\n* `Turkish <https://docs.soliditylang.org/tr/latest/>`_\n\n.. note::\n\n   We set up a GitHub organization and translation workflow to help streamline the community efforts.\n   Please refer to the translation guide in the `solidity-docs org <https://github.com/solidity-docs>`_\n   for information on how to start a new language or contribute to the community translations.\n\nContents\n========\n\n:ref:`Keyword Index <genindex>`, :ref:`Search Page <search>`\n\n.. toctree::\n   :maxdepth: 2\n   :caption: Basics\n\n   introduction-to-smart-contracts.rst\n   solidity-by-example.rst\n   installing-solidity.rst\n\n.. toctree::\n   :maxdepth: 2\n   :caption: Language Description\n\n   layout-of-source-files.rst\n   structure-of-a-contract.rst\n   types.rst\n   units-and-global-variables.rst\n   control-structures.rst\n   contracts.rst\n   assembly.rst\n   cheatsheet.rst\n   grammar.rst\n\n.. toctree::\n   :maxdepth: 2\n   :caption: Compiler\n\n   using-the-compiler.rst\n   analysing-compilation-output.rst\n   ir-breaking-changes.rst\n\n.. toctree::\n   :maxdepth: 2\n   :caption: Internals\n\n   internals/layout_in_storage.rst\n   internals/layout_in_memory.rst\n   internals/layout_in_calldata.rst\n   internals/variable_cleanup.rst\n   internals/source_mappings.rst\n   internals/optimizer.rst\n   metadata.rst\n   abi-spec.rst\n\n.. toctree::\n   :maxdepth: 2\n   :caption: Advisory content\n\n   security-considerations.rst\n   bugs.rst\n   050-breaking-changes.rst\n   060-breaking-changes.rst\n   070-breaking-changes.rst\n   080-breaking-changes.rst\n\n.. toctree::\n   :maxdepth: 2\n   :caption: Additional Material\n\n   natspec-format.rst\n   smtchecker.rst\n   yul.rst\n   path-resolution.rst\n\n.. toctree::\n   :maxdepth: 2\n   :caption: Resources\n\n   style-guide.rst\n   common-patterns.rst\n   resources.rst\n   contributing.rst\n   language-influences.rst\n   brand-guide.rst\n"
  },
  {
    "path": "docs/installing-solidity.rst",
    "content": ".. index:: ! installing\n\n.. _installing-solidity:\n\n################################\nInstalling the Solidity Compiler\n################################\n\nVersioning\n==========\n\nSolidity versions follow `Semantic Versioning <https://semver.org>`_. In\naddition, patch-level releases with major release 0 (i.e. 0.x.y) will not\ncontain breaking changes. That means code that compiles with version 0.x.y\ncan be expected to compile with 0.x.z where z > y.\n\nIn addition to releases, we provide **prereleases** and **nightly development builds** to make it\neasy for developers to try out upcoming features and provide early feedback.\nNote that such builds contain bleeding-edge code from the development branch and are not guaranteed\nto be of the same quality as full releases.\nDespite our best efforts, they might contain undocumented and/or broken changes that will not\nbecome a part of an actual release. They are not meant for production use.\n\nWhen deploying contracts, you should use the latest released version of Solidity. This\nis because breaking changes, as well as new features and bug fixes are introduced regularly.\nWe currently use a 0.x version number `to indicate this fast pace of change <https://semver.org/#spec-item-4>`_.\n\nRemix\n=====\n\n*We recommend Remix for small contracts and for quickly learning Solidity.*\n\n`Access Remix online <https://remix.ethereum.org/>`_, you do not need to install anything.\nIf you want to use it without connection to the Internet, download Remix Desktop from `the releases page <https://github.com/remix-project-org/remix-desktop/releases/>`_.\nRemix is also a convenient option for testing nightly builds\nwithout installing multiple Solidity versions.\n\nFurther options on this page detail installing command-line Solidity compiler software\non your computer. Choose a command-line compiler if you are working on a larger contract\nor if you require more compilation options.\n\n.. _solcjs:\n\nnpm / Node.js\n=============\n\nUse ``npm`` for a convenient and portable way to install ``solcjs``, a Solidity compiler. The\n``solcjs`` program has fewer features than the ways to access the compiler described\nfurther down this page. The\n:ref:`commandline-compiler` documentation assumes you are using\nthe full-featured compiler, ``solc``. The usage of ``solcjs`` is documented inside its own\n`repository <https://github.com/argotorg/solc-js>`_.\n\nNote: The solc-js project is derived from the C++\n``solc`` by using Emscripten, which means that both use the same compiler source code.\n``solc-js`` can be used in JavaScript projects directly (such as Remix).\nPlease refer to the solc-js repository for instructions.\n\n.. code-block:: bash\n\n    npm install --global solc\n\n.. note::\n\n    The command-line executable is named ``solcjs``.\n\n    The command-line options of ``solcjs`` are not compatible with ``solc`` and tools (such as ``geth``)\n    expecting the behavior of ``solc`` will not work with ``solcjs``.\n\nDocker\n======\n\nDocker images of Solidity builds are available using the `solc <https://github.com/argotorg/solidity/pkgs/container/solc>`_ image from the argotorg organization on ghcr.io.\nUse the ``stable`` tag for the latest released version, and ``nightly`` for potentially unstable changes in the ``develop`` branch.\n\nThe Docker image runs the compiler executable so that you can pass all compiler arguments to it.\nFor example, the command below pulls the stable version of the ``solc`` image (if you do not have it already),\nand runs it in a new container, passing the ``--help`` argument.\n\n.. code-block:: bash\n\n    docker run ghcr.io/argotorg/solc:stable --help\n\n.. note::\n\n    Specific compiler versions are supported as the Docker image tag such as ``ghcr.io/argotorg/solc:0.8.23``.\n    We will be passing the ``stable`` tag here instead of specific version tag to ensure that users get\n    the latest version by default and avoid the issue of an out-of-date version.\n\nTo use the Docker image to compile Solidity files on the host machine, mount a\nlocal folder for input and output, and specify the contract to compile. For example:\n\n.. code-block:: bash\n\n    docker run \\\n        --volume \"/tmp/some/local/path/:/sources/\" \\\n        ghcr.io/argotorg/solc:stable \\\n            /sources/Contract.sol \\\n            --abi \\\n            --bin \\\n            --output-dir /sources/output/\n\nYou can also use the standard JSON interface (which is recommended when using the compiler with tooling).\nWhen using this interface, it is not necessary to mount any directories as long as the JSON input is\nself-contained (i.e. it does not refer to any external files that would have to be\n:ref:`loaded by the import callback <initial-vfs-content-standard-json-with-import-callback>`).\n\n.. code-block:: bash\n\n    docker run ghcr.io/argotorg/solc:stable --standard-json < input.json > output.json\n\nLinux Packages\n==============\n\nWe provide :ref:`standalone binaries <static-binaries>` of the compiler that should run on most\ndistributions without any additional installation steps.\n\nUbuntu packages for versions up to 0.8.30 are available in the\n`ethereum/ethereum PPA <https://launchpad.net/~ethereum/+archive/ubuntu/ethereum>`_.\nHowever, we have discontinued this distribution method and future versions will not be added there.\n\nSome Linux distributions provide their own packages.\nThese packages are not directly maintained by us but usually kept up-to-date by the respective\npackage maintainers.\n\nUnofficial, community-maintained scripts for building and installing the compiler are also\navailable for some distributions:\n\n- Arch Linux / (AUR):\n\n    - `solidity <https://aur.archlinux.org/packages/solidity>`_ (builds from source),\n    - `solidity-bin <https://aur.archlinux.org/packages/solidity-bin>`_ (uses our standalone binaries).\n\n- Nix:\n\n    - `solc.nix <https://github.com/hellwolf/solc.nix>`_ (builds from source).\n\n.. note::\n\n    Please be aware that these scripts are produced and maintained by users and not vetted in any\n    way by the distro maintainers.\n    Exercise caution when using them.\n\nThere is also a `snap package <https://snapcraft.io/solc>`_, however, it is **currently unmaintained**.\nIt is installable in all the `supported Linux distros <https://snapcraft.io/docs/reference/administration/distribution-support/>`_. To\ninstall the latest stable version of solc:\n\n.. code-block:: bash\n\n    sudo snap install solc\n\nIf you want to help testing the latest development version of Solidity\nwith the most recent changes, please use the following:\n\n.. code-block:: bash\n\n    sudo snap install solc --edge\n\n.. note::\n\n    The ``solc`` snap uses strict confinement. This is the most secure mode for snap packages\n    but it comes with limitations, like accessing only the files in your ``/home`` and ``/media`` directories.\n    For more information, go to `Demystifying Snap Confinement <https://snapcraft.io/blog/demystifying-snap-confinement>`_.\n\n\nmacOS Packages\n==============\n\nWe distribute the Solidity compiler through Homebrew\nas a build-from-source version. Pre-built bottles are\ncurrently not supported.\n\n.. code-block:: bash\n\n    brew update\n    brew upgrade\n    brew tap ethereum/ethereum\n    brew install solidity\n\nTo install the most recent 0.4.x / 0.5.x version of Solidity you can also use ``brew install solidity@4``\nand ``brew install solidity@5``, respectively.\n\nIf you need a specific version of Solidity you can install a\nHomebrew formula directly from Github.\n\nView\n`solidity.rb commits on GitHub <https://github.com/ethereum/homebrew-ethereum/commits/master/solidity.rb>`_.\n\nCopy the commit hash of the version you want and check it out on your machine.\n\n.. code-block:: bash\n\n    git clone https://github.com/ethereum/homebrew-ethereum.git\n    cd homebrew-ethereum\n    git checkout <your-hash-goes-here>\n\nInstall it using ``brew``:\n\n.. code-block:: bash\n\n    brew unlink solidity\n    # eg. Install 0.4.8\n    brew install solidity.rb\n\n.. _static-binaries:\n\nStatic Binaries\n===============\n\nWe maintain a repository containing static builds of past and current compiler versions for all\nsupported platforms at `solc-bin`_. This is also the location where you can find the nightly builds.\n\nThe repository is not only a quick and easy way for end users to get binaries ready to be used\nout-of-the-box but it is also meant to be friendly to third-party tools:\n\n- The content is mirrored to https://binaries.soliditylang.org where it can be easily downloaded over\n  HTTPS without any authentication, rate limiting or the need to use git.\n- Content is served with correct ``Content-Type`` headers and lenient CORS configuration so that it\n  can be directly loaded by tools running in the browser.\n- Binaries do not require installation or unpacking (exception for older Windows builds\n  bundled with necessary DLLs).\n- We strive for a high level of backward-compatibility. Files, once added, are not removed or moved\n  without providing a symlink/redirect at the old location. They are also never modified\n  in place and should always match the original checksum. The only exception would be broken or\n  unusable files with the potential to cause more harm than good if left as is.\n- Files are served over both HTTP and HTTPS. As long as you obtain the file list in a secure way\n  (via git, HTTPS, IPFS or just have it cached locally) and verify hashes of the binaries\n  after downloading them, you do not have to use HTTPS for the binaries themselves.\n\nThe same binaries are in most cases available on the `Solidity release page on GitHub`_. The\ndifference is that we do not generally update old releases on the GitHub release page. This means\nthat we do not rename them if the naming convention changes and we do not add builds for platforms\nthat were not supported at the time of release. This only happens in ``solc-bin``.\n\nThe ``solc-bin`` repository contains several top-level directories, each representing a single platform.\nEach one includes a ``list.json`` file listing the available binaries. For example in\n``emscripten-wasm32/list.json`` you will find the following information about version 0.7.4:\n\n.. code-block:: json\n\n    {\n      \"path\": \"solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js\",\n      \"version\": \"0.7.4\",\n      \"build\": \"commit.3f05b770\",\n      \"longVersion\": \"0.7.4+commit.3f05b770\",\n      \"keccak256\": \"0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3\",\n      \"sha256\": \"0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2\",\n      \"urls\": [\n        \"dweb:/ipfs/QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS\"\n      ]\n    }\n\nThis means that:\n\n- You can find the binary in the same directory under the name\n  `solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js <https://github.com/argotorg/solc-bin/blob/gh-pages/emscripten-wasm32/solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js>`_.\n  Note that the file might be a symlink, and you will need to resolve it yourself if you are not using\n  git to download it or your file system does not support symlinks.\n- The binary is also mirrored at https://binaries.soliditylang.org/emscripten-wasm32/solc-emscripten-wasm32-v0.7.4+commit.3f05b770.js.\n  In this case git is not necessary and symlinks are resolved transparently, either by serving a copy\n  of the file or returning a HTTP redirect.\n- The file is also available on IPFS at `QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS`_.\n  Please, be aware that the order of items in the ``urls`` array is not predetermined or guaranteed and users should not rely on it.\n- You can verify the integrity of the binary by comparing its keccak256 hash to\n  ``0x300330ecd127756b824aa13e843cb1f43c473cb22eaf3750d5fb9c99279af8c3``.  The hash can be computed\n  on the command-line using ``keccak256sum`` utility provided by `sha3sum`_ or `keccak256() function\n  from ethereumjs-util`_ in JavaScript.\n- You can also verify the integrity of the binary by comparing its sha256 hash to\n  ``0x2b55ed5fec4d9625b6c7b3ab1abd2b7fb7dd2a9c68543bf0323db2c7e2d55af2``.\n\n.. warning::\n\n   Due to the strong backwards compatibility requirement the repository contains some legacy elements\n   but you should avoid using them when writing new tools:\n\n   - Use ``emscripten-wasm32/`` (with a fallback to ``emscripten-asmjs/``) instead of ``bin/`` if\n     you want the best performance. Until version 0.6.1 we only provided asm.js binaries.\n     Starting with 0.6.2 we switched to `WebAssembly builds`_ with much better performance. We have\n     rebuilt the older versions for wasm but the original asm.js files remain in ``bin/``.\n     The new ones had to be placed in a separate directory to avoid name clashes.\n   - Use ``emscripten-asmjs/`` and ``emscripten-wasm32/`` instead of ``bin/`` and ``wasm/`` directories\n     if you want to be sure whether you are downloading a wasm or an asm.js binary.\n   - Use ``list.json`` instead of ``list.js`` and ``list.txt``. The JSON list format contains all\n     the information from the old ones and more.\n\n.. warning::\n   - The solc-bin.ethereum.org domain is no longer supported. Going forward,\n     we recommend any tools which are still using it as the source of Solidity binaries\n     to switch to binaries.soliditylang.org.\n\n.. warning::\n\n    The binaries are also available at https://argotorg.github.io/solc-bin/ but this page\n    stopped being updated just after the release of version 0.7.2, will not receive any new releases\n    or nightly builds for any platform and does not serve the new directory structure, including\n    non-emscripten builds.\n\n    If you are using it, please switch to https://binaries.soliditylang.org, which is a drop-in\n    replacement. This allows us to make changes to the underlying hosting in a transparent way and\n    minimize disruption. Unlike the ``argotorg.github.io`` domain, which we do not have any control\n    over, ``binaries.soliditylang.org`` is guaranteed to work and maintain the same URL structure\n    in the long-term.\n\n.. _IPFS: https://ipfs.io\n.. _solc-bin: https://github.com/argotorg/solc-bin/\n.. _Solidity release page on GitHub: https://github.com/argotorg/solidity/releases\n.. _sha3sum: https://github.com/maandree/sha3sum\n.. _keccak256() function from ethereumjs-util: https://github.com/ethereumjs/ethereumjs-util/blob/master/docs/modules/_hash_.md#const-keccak256\n.. _WebAssembly builds: https://emscripten.org/docs/compiling/WebAssembly.html\n.. _QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS: https://gateway.ipfs.io/ipfs/QmTLs5MuLEWXQkths41HiACoXDiH8zxyqBHGFDRSzVE5CS\n\n.. _building-from-source:\n\nBuilding from Source\n====================\nPrerequisites - All Operating Systems\n-------------------------------------\n\nThe following are dependencies for all builds of Solidity:\n\n.. Note: This has to be kept in sync with `scripts/ci/install_and_check_minimum_requirements.sh`.\n\n+-----------------------------------+-------------------------------------------------------+\n| Software                          | Notes                                                 |\n+===================================+=======================================================+\n| `CMake`_ (version 3.21.3+ on      | Cross-platform build file generator.                  |\n| Windows, 3.13+ otherwise)         |                                                       |\n+-----------------------------------+-------------------------------------------------------+\n| `Boost`_ (version 1.77+ on        | C++ libraries.                                        |\n| Windows, 1.83+ otherwise)         |                                                       |\n+-----------------------------------+-------------------------------------------------------+\n| `Git`_                            | Command-line tool for retrieving source code.         |\n+-----------------------------------+-------------------------------------------------------+\n| `z3`_ (version 4.8.16+, Optional) | For use with SMT checker.                             |\n+-----------------------------------+-------------------------------------------------------+\n\n.. _Git: https://git-scm.com/download\n.. _Boost: https://www.boost.org\n.. _CMake: https://cmake.org/download/\n.. _z3: https://github.com/Z3Prover/z3\n\n.. note::\n    Solidity versions prior to 0.5.10 can fail to correctly link against Boost versions 1.70+.\n    A possible workaround is to temporarily rename ``<Boost install path>/lib/cmake/Boost-1.70.0``\n    prior to running the cmake command to configure Solidity.\n\n    Starting from 0.5.10 linking against Boost 1.70+ should work without manual intervention.\n\n.. note::\n    The default build configuration requires a specific Z3 version (the latest one at the time the\n    code was last updated). Changes introduced between Z3 releases often result in slightly different\n    (but still valid) results being returned. Our SMT tests do not account for these differences and\n    will likely fail with a different version than the one they were written for. This does not mean\n    that a build using a different version is faulty. If you pass ``-DSTRICT_Z3_VERSION=OFF`` option\n    to CMake, you can build with any version that satisfies the requirement given in the table above.\n    If you do this, however, please remember to pass the ``--no-smt`` option to ``scripts/tests.sh``\n    to skip the SMT tests.\n\n.. note::\n    By default the build is performed in *pedantic mode*, which enables extra warnings and tells the\n    compiler to treat all warnings as errors.\n    This forces developers to fix warnings as they arise, so they do not accumulate \"to be fixed later\".\n    If you are only interested in creating a release build and do not intend to modify the source code\n    to deal with such warnings, you can pass ``-DPEDANTIC=OFF`` option to CMake to disable this mode.\n    Doing this is not recommended for general use but may be necessary when using a toolchain we are\n    not testing with or trying to build an older version with newer tools.\n    If you encounter such warnings, please consider\n    `reporting them <https://github.com/argotorg/solidity/issues/new>`_.\n\nMinimum Compiler Versions\n^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe following C++ compilers and their minimum versions can build the Solidity codebase:\n\n.. Note: Minimum versions for GCC and Clang are based on availability in Ubuntu 24.04.\n\n- `GCC <https://gcc.gnu.org>`_, version 13.3+\n- `Clang <https://clang.llvm.org/>`_, version 18.1.3+\n- `MSVC <https://visualstudio.microsoft.com/vs/>`_, version 2019+\n\nPrerequisites - macOS\n---------------------\n\nFor macOS builds, ensure that you have the latest version of\n`Xcode installed <https://developer.apple.com/xcode/resources/>`_.\nThis contains the `Clang C++ compiler <https://en.wikipedia.org/wiki/Clang>`_, the\n`Xcode IDE <https://en.wikipedia.org/wiki/Xcode>`_ and other Apple development\ntools that are required for building C++ applications on OS X.\nIf you are installing Xcode for the first time, or have just installed a new\nversion then you will need to agree to the license before you can do\ncommand-line builds:\n\n.. code-block:: bash\n\n    sudo xcodebuild -license accept\n\nOur OS X build script uses `the Homebrew <https://brew.sh>`_\npackage manager for installing external dependencies.\nHere's how to `uninstall Homebrew\n<https://docs.brew.sh/FAQ#how-do-i-uninstall-homebrew>`_,\nif you ever want to start again from scratch.\n\nPrerequisites - Windows\n-----------------------\n\nYou need to install the following dependencies for Windows builds of Solidity:\n\n+-----------------------------------+-------------------------------------------------------+\n| Software                          | Notes                                                 |\n+===================================+=======================================================+\n| `Visual Studio 2019 Build Tools`_ | C++ compiler                                          |\n+-----------------------------------+-------------------------------------------------------+\n| `Visual Studio 2019`_  (Optional) | C++ compiler and dev environment.                     |\n+-----------------------------------+-------------------------------------------------------+\n| `Boost`_ (version 1.77+)          | C++ libraries.                                        |\n+-----------------------------------+-------------------------------------------------------+\n\nIf you already have one IDE and only need the compiler and libraries,\nyou could install Visual Studio 2019 Build Tools.\n\nVisual Studio 2019 provides both IDE and necessary compiler and libraries.\nSo if you have not got an IDE and prefer to develop Solidity, Visual Studio 2019\nmay be a choice for you to get everything setup easily.\n\nHere is the list of components that should be installed\nin Visual Studio 2019 Build Tools or Visual Studio 2019:\n\n* Visual Studio C++ core features\n* VC++ 2019 v141 toolset (x86,x64)\n* Windows Universal CRT SDK\n* Windows 8.1 SDK\n* C++/CLI support\n\n.. _Visual Studio 2019: https://www.visualstudio.com/vs/\n.. _Visual Studio 2019 Build Tools: https://visualstudio.microsoft.com/vs/older-downloads/#visual-studio-2019-and-other-products\n\nWe have a helper script which you can use to install all required external dependencies:\n\n.. code-block:: bat\n\n    scripts\\install_deps.ps1\n\nThis will install ``boost`` and ``cmake`` to the ``deps`` subdirectory.\n\nClone the Repository\n--------------------\n\nTo clone the source code, execute the following command:\n\n.. code-block:: bash\n\n    git clone --recursive https://github.com/argotorg/solidity.git\n    cd solidity\n\nIf you want to help develop Solidity,\nyou should fork Solidity and add your personal fork as a second remote:\n\n.. code-block:: bash\n\n    git remote add personal git@github.com:[username]/solidity.git\n\n.. note::\n    This method will result in a pre-release build leading to e.g. a flag\n    being set in each bytecode produced by such a compiler.\n    If you want to re-build a released Solidity compiler, then\n    please use the source tarball on the GitHub release page:\n\n    https://github.com/argotorg/solidity/releases/download/v0.X.Y/solidity_0.X.Y.tar.gz\n\n    (not the \"Source code\" provided by GitHub).\n\nCommand-Line Build\n------------------\n\n**Be sure to install External Dependencies (see above) before build.**\n\nSolidity project uses CMake to configure the build.\nYou might want to install `ccache`_ to speed up repeated builds.\nCMake will pick it up automatically.\nBuilding Solidity is quite similar on Linux, macOS and other Unices:\n\n.. _ccache: https://ccache.dev/\n\n.. code-block:: bash\n\n    mkdir build\n    cd build\n    cmake .. && make\n\nor even easier on Linux and macOS, you can run:\n\n.. code-block:: bash\n\n    #note: this will install binaries solc and soltest at usr/local/bin\n    ./scripts/build.sh\n\n.. warning::\n\n    BSD builds should work, but are untested by the Solidity team.\n\nAnd for Windows:\n\n.. code-block:: bash\n\n    mkdir build\n    cd build\n    cmake -G \"Visual Studio 16 2019\" ..\n\nIn case you want to use the version of boost installed by ``scripts\\install_deps.ps1``, you will\nadditionally need to pass ``-DBoost_ROOT=\"deps/boost\" -DBoost_INCLUDE_DIR=\"deps/boost/include\"`` and ``-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded``\nas arguments to the call to ``cmake``.\n\nThis should result in the creation of **solidity.sln** in that build directory.\nDouble-clicking on that file should result in Visual Studio firing up.  We suggest building\n**Release** configuration, but all others work.\n\nAlternatively, you can build for Windows on the command-line, like so:\n\n.. code-block:: bash\n\n    cmake --build . --config Release\n\nCMake Options\n=============\n\nIf you are interested what CMake options are available run ``cmake .. -LH``.\n\n.. _smt_solvers_build:\n\nSMT Solvers\n-----------\nSolidity can optionally use SMT solvers, namely ``z3``, ``cvc5`` and ``Eldarica``,\nbut their presence is checked only at runtime, they are not needed for the build to succeed.\n\n.. note::\n\n    The emscripten builds require Z3 and will statically link against it instead.\n\nThe Version String in Detail\n============================\n\nThe Solidity version string contains four parts:\n\n- the version number\n- pre-release tag, usually set to ``develop.YYYY.MM.DD``, ``pre.N`` or ``nightly.YYYY.MM.DD``\n- commit in the format of ``commit.GITHASH``\n- platform, which has an arbitrary number of items, containing details about the platform and compiler\n\nIf there are local modifications, the commit will be postfixed with ``.mod``.\n\nThese parts are combined as required by SemVer, where the Solidity pre-release tag equals to the SemVer pre-release\nand the Solidity commit and platform combined make up the SemVer build metadata.\n\nExamples:\n\n- release: ``0.4.8+commit.60cc1668.Emscripten.clang``\n- pre-release: ``0.4.9-pre.3+commit.fb60450bc.Emscripten.clang``\n- nightly build: ``0.4.9-nightly.2017.1.17+commit.6ecb4aa3.Emscripten.clang``\n\nImportant Information About Versioning\n======================================\n\nAfter a release is made, the patch version level is bumped, because we assume that only\npatch level changes follow. When changes are merged, the version should be bumped according\nto SemVer and the severity of the change. Finally, a release is always made with the version\nof the current build, but without the ``prerelease`` specifier.\n\nExample:\n\n1. The 0.4.0 release is made.\n2. Nightly builds and preerelases have a version of 0.4.1 from now on.\n3. Non-breaking changes are introduced --> no change in version.\n4. A breaking change is introduced --> version is bumped to 0.5.0.\n5. The 0.5.0 release is made.\n\nThis behavior works well with the :ref:`version pragma <version_pragma>`.\n"
  },
  {
    "path": "docs/internals/layout_in_calldata.rst",
    "content": "\n.. index: calldata layout\n\n*******************\nLayout of Call Data\n*******************\n\nThe input data for a function call is assumed to be in the format defined by the :ref:`ABI\nspecification <ABI>`. Among others, the ABI specification requires arguments to be padded to multiples of 32\nbytes. The internal function calls use a different convention.\n\nArguments for the constructor of a contract are directly appended at the end of the\ncontract's code, also in ABI encoding. The constructor will access them through a hard-coded offset, and\nnot by using the ``codesize`` opcode, since this of course changes when appending\ndata to the code.\n\n"
  },
  {
    "path": "docs/internals/layout_in_memory.rst",
    "content": "\n.. index: memory layout\n\n****************\nLayout in Memory\n****************\n\nSolidity reserves four 32-byte slots, with specific byte ranges (inclusive of endpoints) being used as follows:\n\n- ``0x00`` - ``0x3f`` (64 bytes): scratch space for hashing methods\n- ``0x40`` - ``0x5f`` (32 bytes): currently allocated memory size (aka. free memory pointer)\n- ``0x60`` - ``0x7f`` (32 bytes): zero slot\n\nScratch space can be used between statements (i.e. within inline assembly). The zero slot\nis used as initial value for dynamic memory arrays and should never be written to\n(the free memory pointer points to ``0x80`` initially).\n\nSolidity always places new objects at the free memory pointer and\nmemory is never freed (this might change in the future).\n\nElements in memory arrays in Solidity always occupy multiples of 32 bytes (this\nis even true for ``bytes1[]``, but not for ``bytes`` and ``string``).\nMulti-dimensional memory arrays are pointers to memory arrays. The length of a\ndynamic array is stored at the first slot of the array and followed by the array\nelements.\n\n.. warning::\n  There are some operations in Solidity that need a temporary memory area\n  larger than 64 bytes and therefore will not fit into the scratch space.\n  They will be placed where the free memory points to, but given their\n  short lifetime, the pointer is not updated. The memory may or may not\n  be zeroed out. Because of this, one should not expect the free memory\n  to point to zeroed out memory.\n\n  While it may seem like a good idea to use ``msize`` to arrive at a\n  definitely zeroed out memory area, using such a pointer non-temporarily\n  without updating the free memory pointer can have unexpected results.\n\n\nDifferences to Layout in Storage\n================================\n\nAs described above the layout in memory is different from the layout in\n:ref:`storage<storage-inplace-encoding>`. Below there are some examples.\n\nExample for Difference in Arrays\n--------------------------------\n\nThe following array occupies 32 bytes (1 slot) in storage, but 128\nbytes (4 items with 32 bytes each) in memory.\n\n.. code-block:: solidity\n\n    uint8[4] a;\n\n\n\nExample for Difference in Struct Layout\n---------------------------------------\n\nThe following struct occupies 96 bytes (3 slots of 32 bytes) in storage,\nbut 128 bytes (4 items with 32 bytes each) in memory.\n\n\n.. code-block:: solidity\n\n    struct S {\n        uint a;\n        uint b;\n        uint8 c;\n        uint8 d;\n    }\n"
  },
  {
    "path": "docs/internals/layout_in_storage.rst",
    "content": ".. index:: storage, state variable, mapping, transient storage\n\n**********************************************************\nLayout of State Variables in Storage and Transient Storage\n**********************************************************\n\n.. _storage-inplace-encoding:\n\n.. note::\n    The rules described in this section apply for both storage and transient storage data locations.\n    The layouts are completely independent and don't interfere with each other's variable locations.\n    Thus storage and transient storage state variables can be safely interleaved without any side effects.\n    Only value types are supported for transient storage.\n\nState variables of contracts are stored in storage in a compact way such\nthat multiple values sometimes use the same storage slot.\nExcept for dynamically-sized arrays and mappings (see below), data is stored\ncontiguously item after item starting with the first state variable,\nwhich is stored in slot ``0``. For each variable,\na size in bytes is determined according to its type.\nMultiple, contiguous items that need less than 32 bytes are packed into a single\nstorage slot if possible, according to the following rules:\n\n- The first item in a storage slot is stored lower-order aligned.\n- Value types use only as many bytes as are necessary to store them.\n- If a value type does not fit the remaining part of a storage slot, it is stored in the next storage slot.\n- Structs and array data always start a new slot and their items are packed tightly according to these rules.\n- Items following struct or array data always start a new storage slot.\n\nFor contracts that use inheritance, the ordering of state variables is determined by the\nC3-linearized order of contracts starting with the most base-ward contract. If allowed\nby the above rules, state variables from different contracts do share the same storage slot.\n\nThe elements of structs and arrays are stored after each other, just as if they were given\nas individual values.\n\nIf a contract specifies a :ref:`custom storage layout<custom-storage-layout>`, the slots assigned\nto static storage variables are shifted according the value defined as the layout base.\nLocations of dynamic arrays and mappings are also indirectly affected by this due to shifting\nof the static slots they are based on.\nThe custom layout is specified in the most derived contract and, following the order explained\nabove, starting from the most base-ward contract's variables, all storage slots are adjusted.\n\nIn the following example, contract ``C`` inherits from contracts ``A`` and ``B`` and also\nspecifies a custom storage base slot.\nThe result is that all storage variable slots of the inheritance tree are adjusted according to\nthe value specified by ``C``.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.29;\n\n    struct S {\n        int32 x;\n        bool y;\n    }\n\n    contract A {\n        uint a;\n        uint128 transient b;\n        uint constant c = 10;\n        uint immutable d = 12;\n    }\n\n    contract B {\n        uint8[] e;\n        mapping(uint => S) f;\n        uint16 g;\n        uint16 h;\n        bytes16 transient i;\n        S s;\n        int8 k;\n    }\n\n    contract C is A, B layout at 42 {\n        bytes21 l;\n        uint8[10] m;\n        bytes5[8] n;\n        bytes5 o;\n    }\n\nIn the example, the storage layout starts with the inherited\nstate variable ``a`` stored directly inside the base slot (slot ``42``).\nTransient, constant and immutable variables are stored in separate\nlocations, and thus, ``b``, ``i``, ``c`` and ``d`` have no effect on the storage layout.\nThen we get to the dynamic array ``e`` and mapping ``f``.\nThey both reserve a whole slot whose address will be used to :ref:`calculate<storage-hashed-encoding>`\nthe location where their data is actually stored.\nThe slot cannot be shared with any other variable, because the resulting addresses must be unique.\nThe next two variables, ``g`` and ``h``, need 2 bytes each and can be packed together into\nslot ``45``, at offsets ``0`` and ``2`` respectively.\nSince ``s`` is a struct, its two members are packed contiguously, each taking up 5 bytes.\nEven though they both would still fit in slot ``45``, structs and arrays always start a new slot.\nTherefore, ``s`` is placed in slot ``46`` and the next variable, ``k``, in slot ``47``.\nBase contracts, on the other hand, can share slots with derived ones, so ``l`` does not require an new one.\nThen variable ``m``, which is an array of 10 items, gets into slot ``48`` and takes up 10 bytes.\n``n`` is an array as well, but due to the size of its items, cannot fill its first slot perfectly\nand spills over to the next one.\nFinally, variable ``o`` ends up in slot ``51``, even though it is of the same type as items of ``n``.\nAs explained before, variables after structs and arrays always start a new slot.\n\nPutting it all together, the storage and transient storage layouts of contract ``C`` can be illustrated as follows:\n\n- Storage:\n  ::\n\n      42 [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]\n      43 [eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee]\n      44 [ffffffffffffffffffffffffffffffff]\n      45 [                            hhgg]\n      46 [                           yxxxx]\n      47 [          lllllllllllllllllllllk]\n      48 [                      mmmmmmmmmm]\n      49 [  nnnnnnnnnnnnnnnnnnnnnnnnnnnnnn]\n      50 [                      nnnnnnnnnn]\n      51 [                           ooooo]\n\n- Transient storage:\n  ::\n\n      00 [iiiiiiiiiiiiiiiibbbbbbbbbbbbbbbb]\n\nNote that the storage specifier affects ``A`` and ``B`` only as a part of ``C``'s inheritance hierarchy.\nWhen deployed independently, their storage starts at ``0``:\n\n- Storage layout of ``A``:\n  ::\n\n      00 [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]\n\n- Storage layout of ``B``:\n  ::\n\n      00 [eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee]\n      01 [ffffffffffffffffffffffffffffffff]\n      02 [                            hhgg]\n      03 [                           yxxxx]\n      04 [                               k]\n\n.. warning::\n    When using elements that are smaller than 32 bytes, your contract's gas usage may be higher.\n    This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller\n    than that, the EVM must use more operations in order to reduce the size of the element from 32\n    bytes to the desired size.\n\n    It might be beneficial to use reduced-size types if you are dealing with storage values\n    because the compiler will pack multiple elements into one storage slot, and thus, combine\n    multiple reads or writes into a single operation.\n    If you are not reading or writing all the values in a slot at the same time, this can\n    have the opposite effect, though: When one value is written to a multi-value storage\n    slot, the storage slot has to be read first and then\n    combined with the new value such that other data in the same slot is not destroyed.\n\n    When dealing with function arguments or memory\n    values, there is no inherent benefit because the compiler does not pack these values.\n\n    Finally, in order to allow the EVM to optimize for this, ensure that you try to order your\n    storage variables and ``struct`` members such that they can be packed tightly. For example,\n    declaring your storage variables in the order of ``uint128, uint128, uint256`` instead of\n    ``uint128, uint256, uint128``, as the former will only take up two slots of storage whereas the\n    latter will take up three.\n\n.. note::\n     The layout of state variables in storage is considered to be part of the external interface\n     of Solidity due to the fact that storage pointers can be passed to libraries. This means that\n     any change to the rules outlined in this section is considered a breaking change\n     of the language and due to its critical nature should be considered very carefully before\n     being executed. In the event of such a breaking change, we would want to release a\n     compatibility mode in which the compiler would generate bytecode supporting the old layout.\n\n\nMappings and Dynamic Arrays\n===========================\n\n.. _storage-hashed-encoding:\n\nDue to their unpredictable size, mappings and dynamically-sized array types cannot be stored\n\"in between\" the state variables preceding and following them.\nInstead, they are considered to occupy only 32 bytes with regards to the\n:ref:`rules above <storage-inplace-encoding>` and the elements they contain are stored starting at a different\nstorage slot that is computed using a Keccak-256 hash.\n\nAssume the storage location of the mapping or array ends up being a slot ``p``\nafter applying :ref:`the storage layout rules <storage-inplace-encoding>`.\nFor dynamic arrays,\nthis slot stores the number of elements in the array (byte arrays and\nstrings are an exception, see :ref:`below <bytes-and-string>`).\nFor mappings, the slot stays empty, but it is still needed to ensure that even if there are\ntwo mappings next to each other, their content ends up at different storage locations.\n\nArray data is located starting at ``keccak256(p)`` and it is laid out in the same way as\nstatically-sized array data would: One element after the other, potentially sharing\nstorage slots if the elements are not longer than 16 bytes. Dynamic arrays of dynamic arrays apply this\nrule recursively. The location of element ``x[i][j]``, where the type of ``x`` is ``uint24[][]``, is\ncomputed as follows (again, assuming ``x`` itself is stored at slot ``p``):\nThe slot is ``keccak256(keccak256(p) + i) + floor(j / floor(256 / 24))`` and\nthe element can be obtained from the slot data ``v`` using ``(v >> ((j % floor(256 / 24)) * 24)) & type(uint24).max``.\n\nThe value corresponding to a mapping key ``k`` is located at ``keccak256(h(k) . p)``\nwhere ``.`` is concatenation and ``h`` is a function that is applied to the key depending on its type:\n\n- for value types, ``h`` pads the value to 32 bytes in the same way as when storing the value in memory.\n- for strings and byte arrays, ``h(k)`` is just the unpadded data.\n\nIf the mapping value is a\nnon-value type, the computed slot marks the start of the data. If the value is of struct type,\nfor example, you have to add an offset corresponding to the struct member to reach the member.\n\nAs an example, consider the following contract:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n\n    contract C {\n        struct S { uint16 a; uint16 b; uint256 c; }\n        uint x;\n        mapping(uint => mapping(uint => S)) data;\n    }\n\nLet us compute the storage location of ``data[4][9].c``.\nThe position of the mapping itself is ``1`` (the variable ``x`` with 32 bytes precedes it).\nThis means ``data[4]`` is stored at ``keccak256(uint256(4) . uint256(1))``. The type of ``data[4]`` is\nagain a mapping and the data for ``data[4][9]`` starts at slot\n``keccak256(uint256(9) . keccak256(uint256(4) . uint256(1)))``.\nThe slot offset of the member ``c`` inside the struct ``S`` is ``1`` because ``a`` and ``b`` are packed\nin a single slot. This means the slot for\n``data[4][9].c`` is ``keccak256(uint256(9) . keccak256(uint256(4) . uint256(1))) + 1``.\nThe type of the value is ``uint256``, so it uses a single slot.\n\n\n.. _bytes-and-string:\n\n``bytes`` and ``string``\n------------------------\n\n``bytes`` and ``string`` are encoded identically.\nIn general, the encoding is similar to ``bytes1[]``, in the sense that there is a slot for the array itself and\na data area that is computed using a ``keccak256`` hash of that slot's position.\nHowever, for short values (shorter than 32 bytes) the array elements are stored together with the length in the same slot.\n\nIn particular: if the data is at most ``31`` bytes long, the elements are stored\nin the higher-order bytes (left aligned) and the lowest-order byte stores the value ``length * 2``.\nFor byte arrays that store data which is ``32`` or more bytes long, the main slot ``p`` stores ``length * 2 + 1`` and the data is\nstored as usual in ``keccak256(p)``. This means that you can distinguish a short array from a long array\nby checking if the lowest bit is set: short (not set) and long (set).\n\n.. note::\n  Handling invalidly encoded slots is currently not supported but may be added in the future.\n  If you are compiling via IR, reading an invalidly encoded slot results in a ``Panic(0x22)`` error.\n\nJSON Output\n===========\n\n.. _storage-layout-top-level:\n\nThe storage (or transient storage) layout of a contract can be requested via\nthe :ref:`standard JSON interface <compiler-api>`.  The output is a JSON object containing two keys,\n``storage`` and ``types``.  The ``storage`` object is an array where each\nelement has the following form:\n\n\n.. code-block:: json\n\n\n    {\n        \"astId\": 2,\n        \"contract\": \"fileA:A\",\n        \"label\": \"x\",\n        \"offset\": 0,\n        \"slot\": \"0\",\n        \"type\": \"t_uint256\"\n    }\n\nThe example above is the storage layout of ``contract A { uint x; }`` from source unit ``fileA``\nand\n\n- ``astId`` is the id of the AST node of the state variable's declaration\n- ``contract`` is the name of the contract including its path as prefix\n- ``label`` is the name of the state variable\n- ``offset`` is the offset in bytes within the storage slot according to the encoding\n- ``slot`` is the storage slot where the state variable resides or starts. This\n  number may be very large and therefore its JSON value is represented as a\n  string.\n- ``type`` is an identifier used as key to the variable's type information (described in the following)\n\nThe given ``type``, in this case ``t_uint256`` represents an element in\n``types``, which has the form:\n\n\n.. code-block:: json\n\n    {\n        \"encoding\": \"inplace\",\n        \"label\": \"uint256\",\n        \"numberOfBytes\": \"32\",\n    }\n\nwhere\n\n- ``encoding`` how the data is encoded in storage, where the possible values are:\n\n  - ``inplace``: data is laid out contiguously in storage (see :ref:`above <storage-inplace-encoding>`).\n  - ``mapping``: Keccak-256 hash-based method (see :ref:`above <storage-hashed-encoding>`).\n  - ``dynamic_array``: Keccak-256 hash-based method (see :ref:`above <storage-hashed-encoding>`).\n  - ``bytes``: single slot or Keccak-256 hash-based depending on the data size (see :ref:`above <bytes-and-string>`).\n\n- ``label`` is the canonical type name.\n- ``numberOfBytes`` is the number of used bytes (as a decimal string).\n  Note that if ``numberOfBytes > 32`` this means that more than one slot is used.\n\nSome types have extra information besides the four above. Mappings contain\nits ``key`` and ``value`` types (again referencing an entry in this mapping\nof types), arrays have its ``base`` type, and structs list their ``members`` in\nthe same format as the top-level ``storage`` (see :ref:`above\n<storage-layout-top-level>`).\n\n.. note::\n  The JSON output format of a contract's storage layout is still considered experimental\n  and is subject to change in non-breaking releases of Solidity.\n\nThe following example shows a contract and both its storage and transient storage layout,\ncontaining value and reference types, types that are encoded packed, and nested types.\n\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.28;\n    contract A {\n        struct S {\n            uint128 a;\n            uint128 b;\n            uint[2] staticArray;\n            uint[] dynArray;\n        }\n\n        uint x;\n        uint transient y;\n        uint w;\n        uint transient z;\n\n        S s;\n        address addr;\n        address transient taddr;\n        mapping(uint => mapping(address => bool)) map;\n        uint[] array;\n        string s1;\n        bytes b1;\n    }\n\nStorage Layout\n--------------\n\n.. code-block:: json\n\n    {\n      \"storage\": [\n        {\n          \"astId\": 15,\n          \"contract\": \"fileA:A\",\n          \"label\": \"x\",\n          \"offset\": 0,\n          \"slot\": \"0\",\n          \"type\": \"t_uint256\"\n        },\n        {\n          \"astId\": 19,\n          \"contract\": \"fileA:A\",\n          \"label\": \"w\",\n          \"offset\": 0,\n          \"slot\": \"1\",\n          \"type\": \"t_uint256\"\n        },\n        {\n          \"astId\": 24,\n          \"contract\": \"fileA:A\",\n          \"label\": \"s\",\n          \"offset\": 0,\n          \"slot\": \"2\",\n          \"type\": \"t_struct(S)13_storage\"\n        },\n        {\n          \"astId\": 26,\n          \"contract\": \"fileA:A\",\n          \"label\": \"addr\",\n          \"offset\": 0,\n          \"slot\": \"6\",\n          \"type\": \"t_address\"\n        },\n        {\n          \"astId\": 34,\n          \"contract\": \"fileA:A\",\n          \"label\": \"map\",\n          \"offset\": 0,\n          \"slot\": \"7\",\n          \"type\": \"t_mapping(t_uint256,t_mapping(t_address,t_bool))\"\n        },\n        {\n          \"astId\": 37,\n          \"contract\": \"fileA:A\",\n          \"label\": \"array\",\n          \"offset\": 0,\n          \"slot\": \"8\",\n          \"type\": \"t_array(t_uint256)dyn_storage\"\n        },\n        {\n          \"astId\": 39,\n          \"contract\": \"fileA:A\",\n          \"label\": \"s1\",\n          \"offset\": 0,\n          \"slot\": \"9\",\n          \"type\": \"t_string_storage\"\n        },\n        {\n          \"astId\": 41,\n          \"contract\": \"fileA:A\",\n          \"label\": \"b1\",\n          \"offset\": 0,\n          \"slot\": \"10\",\n          \"type\": \"t_bytes_storage\"\n        }\n      ],\n      \"types\": {\n        \"t_address\": {\n          \"encoding\": \"inplace\",\n          \"label\": \"address\",\n          \"numberOfBytes\": \"20\"\n        },\n        \"t_array(t_uint256)2_storage\": {\n          \"base\": \"t_uint256\",\n          \"encoding\": \"inplace\",\n          \"label\": \"uint256[2]\",\n          \"numberOfBytes\": \"64\"\n        },\n        \"t_array(t_uint256)dyn_storage\": {\n          \"base\": \"t_uint256\",\n          \"encoding\": \"dynamic_array\",\n          \"label\": \"uint256[]\",\n          \"numberOfBytes\": \"32\"\n        },\n        \"t_bool\": {\n          \"encoding\": \"inplace\",\n          \"label\": \"bool\",\n          \"numberOfBytes\": \"1\"\n        },\n        \"t_bytes_storage\": {\n          \"encoding\": \"bytes\",\n          \"label\": \"bytes\",\n          \"numberOfBytes\": \"32\"\n        },\n        \"t_mapping(t_address,t_bool)\": {\n          \"encoding\": \"mapping\",\n          \"key\": \"t_address\",\n          \"label\": \"mapping(address => bool)\",\n          \"numberOfBytes\": \"32\",\n          \"value\": \"t_bool\"\n        },\n        \"t_mapping(t_uint256,t_mapping(t_address,t_bool))\": {\n          \"encoding\": \"mapping\",\n          \"key\": \"t_uint256\",\n          \"label\": \"mapping(uint256 => mapping(address => bool))\",\n          \"numberOfBytes\": \"32\",\n          \"value\": \"t_mapping(t_address,t_bool)\"\n        },\n        \"t_string_storage\": {\n          \"encoding\": \"bytes\",\n          \"label\": \"string\",\n          \"numberOfBytes\": \"32\"\n        },\n        \"t_struct(S)13_storage\": {\n          \"encoding\": \"inplace\",\n          \"label\": \"struct A.S\",\n          \"members\": [\n            {\n              \"astId\": 3,\n              \"contract\": \"fileA:A\",\n              \"label\": \"a\",\n              \"offset\": 0,\n              \"slot\": \"0\",\n              \"type\": \"t_uint128\"\n            },\n            {\n              \"astId\": 5,\n              \"contract\": \"fileA:A\",\n              \"label\": \"b\",\n              \"offset\": 16,\n              \"slot\": \"0\",\n              \"type\": \"t_uint128\"\n            },\n            {\n              \"astId\": 9,\n              \"contract\": \"fileA:A\",\n              \"label\": \"staticArray\",\n              \"offset\": 0,\n              \"slot\": \"1\",\n              \"type\": \"t_array(t_uint256)2_storage\"\n            },\n            {\n              \"astId\": 12,\n              \"contract\": \"fileA:A\",\n              \"label\": \"dynArray\",\n              \"offset\": 0,\n              \"slot\": \"3\",\n              \"type\": \"t_array(t_uint256)dyn_storage\"\n            }\n          ],\n          \"numberOfBytes\": \"128\"\n        },\n        \"t_uint128\": {\n          \"encoding\": \"inplace\",\n          \"label\": \"uint128\",\n          \"numberOfBytes\": \"16\"\n        },\n        \"t_uint256\": {\n          \"encoding\": \"inplace\",\n          \"label\": \"uint256\",\n          \"numberOfBytes\": \"32\"\n        }\n      }\n    }\n\nTransient Storage Layout\n------------------------\n\n.. code-block:: json\n\n    {\n      \"storage\": [\n        {\n          \"astId\": 17,\n          \"contract\": \"fileA:A\",\n          \"label\": \"y\",\n          \"offset\": 0,\n          \"slot\": \"0\",\n          \"type\": \"t_uint256\"\n        },\n        {\n          \"astId\": 21,\n          \"contract\": \"fileA:A\",\n          \"label\": \"z\",\n          \"offset\": 0,\n          \"slot\": \"1\",\n          \"type\": \"t_uint256\"\n        },\n        {\n          \"astId\": 28,\n          \"contract\": \"fileA:A\",\n          \"label\": \"taddr\",\n          \"offset\": 0,\n          \"slot\": \"2\",\n          \"type\": \"t_address\"\n        }\n      ],\n      \"types\": {\n        \"t_address\": {\n          \"encoding\": \"inplace\",\n          \"label\": \"address\",\n          \"numberOfBytes\": \"20\"\n        },\n        \"t_uint256\": {\n          \"encoding\": \"inplace\",\n          \"label\": \"uint256\",\n          \"numberOfBytes\": \"32\"\n        }\n      }\n    }\n"
  },
  {
    "path": "docs/internals/optimizer.rst",
    "content": ".. index:: optimizer, optimiser, common subexpression elimination, constant propagation\n.. _optimizer:\n\n*************\nThe Optimizer\n*************\n\nThe Solidity compiler involves optimizations at three different levels (in order of execution):\n\n- Optimizations during code generation based on a direct analysis of Solidity code.\n- Optimizing transformations on the Yul IR code.\n- Optimizations at the opcode level.\n\nThe opcode-based optimizer applies a set of `simplification rules <https://github.com/argotorg/solidity/blob/develop/libevmasm/RuleList.h>`_\nto opcodes. It also combines equal code sets and removes unused code.\n\nThe Yul-based optimizer is much more powerful, because it can work across function\ncalls. For example, arbitrary jumps are not possible in Yul, so it is\npossible to compute the side-effects of each function. Consider two function calls,\nwhere the first does not modify storage and the second does modify storage.\nIf their arguments and return values do not depend on each other, we can reorder\nthe function calls. Similarly, if a function is\nside-effect free and its result is multiplied by zero, you can remove the function\ncall completely.\n\nThe codegen-based optimizer affects the initial low-level code produced from the Solidity input.\nIn the legacy pipeline, the bytecode is generated immediately and most of the optimizations of this\nkind are implicit and not configurable, the only exception being an optimization which changes the\norder of literals in binary operations.\nThe IR-based pipeline takes a different approach and produces Yul IR closely matching the structure\nof the Solidity code, with nearly all optimizations deferred to the Yul optimizer module.\nIn that case codegen-level optimization is done only in very limited cases which are difficult to\nhandle in Yul IR, but are straightforward with the high-level information from analysis phase at hand.\nAn example of such an optimization is the bypass of checked arithmetic when incrementing the counter\nin certain idiomatic ``for`` loops.\n\nCurrently, the parameter ``--optimize`` activates the opcode-based optimizer for the\ngenerated bytecode and the Yul optimizer for the Yul code generated internally, for example for ABI coder v2.\nOne can use ``solc --ir-optimized --optimize`` to produce an\noptimized Yul IR for a Solidity source. Similarly, one can use ``solc --strict-assembly --optimize``\nfor a stand-alone Yul mode.\n\n.. note::\n    Some optimizer steps, such as, for example, the `peephole optimizer <https://en.wikipedia.org/wiki/Peephole_optimization>`_\n    and the :ref:`unchecked loop increment optimizer <unchecked-loop-optimizer>` are always\n    enabled by default and can only be turned off via the :ref:`Standard JSON <compiler-api>`.\n\n.. note::\n    An empty optimizer sequence, i.e ``:``, is accepted even without ``--optimize`` in order to fully disable\n    the user-supplied portion of the Yul :ref:`optimizer sequence <selecting-optimizations>`, as by default,\n    even when the optimizer is not turned on, the :ref:`unused pruner <unused-pruner>` step will be run.\n\nYou can find more details on both optimizer modules and their optimization steps below.\n\nBenefits of Optimizing Solidity Code\n====================================\n\nOverall, the optimizer tries to simplify complicated expressions, which reduces both code\nsize and execution cost, i.e., it can reduce gas needed for contract deployment as well as for external calls made to the contract.\nIt also specializes or inlines functions. Especially\nfunction inlining is an operation that can cause much bigger code, but it is\noften done because it results in opportunities for more simplifications.\n\n\nDifferences between Optimized and Non-Optimized Code\n====================================================\n\nGenerally, the most visible difference is that constant expressions are evaluated at compile time.\nWhen it comes to the ASM output, one can also notice a reduction of equivalent or duplicate\ncode blocks (compare the output of the flags ``--asm`` and ``--asm --optimize``). However,\nwhen it comes to the Yul/intermediate-representation, there can be significant\ndifferences, for example, functions may be inlined, combined, or rewritten to eliminate\nredundancies, etc. (compare the output between the flags ``--ir`` and\n``--optimize --ir-optimized``).\n\n.. _optimizer-parameter-runs:\n\nOptimizer Parameter Runs\n========================\n\nThe number of runs (``--optimize-runs``) specifies roughly how often each opcode of the\ndeployed code will be executed across the life-time of the contract. This means it is a\ntrade-off parameter between code size (deploy cost) and code execution cost (cost after deployment).\nA \"runs\" parameter of \"1\" will produce short but expensive code. In contrast, a larger \"runs\"\nparameter will produce longer but more gas efficient code. The maximum value of the parameter\nis ``2**32-1``.\n\n.. note::\n\n    A common misconception is that this parameter specifies the number of iterations of the optimizer.\n    This is not true: The optimizer will always run as many times as it can still improve the code.\n\nOpcode-Based Optimizer Module\n=============================\n\nThe opcode-based optimizer module operates on assembly code. It splits the\nsequence of instructions into basic blocks at ``JUMPs`` and ``JUMPDESTs``.\nInside these blocks, the optimizer analyzes the instructions and records every modification to the stack,\nmemory, or storage as an expression which consists of an instruction and\na list of arguments which are pointers to other expressions.\n\nAdditionally, the opcode-based optimizer\nuses a component called \"CommonSubexpressionEliminator\" that, amongst other\ntasks, finds expressions that are always equal (on every input) and combines\nthem into an expression class. It first tries to find each new\nexpression in a list of already known expressions. If no such matches are found,\nit simplifies the expression according to rules like\n``constant + constant = sum_of_constants`` or ``X * 1 = X``. Since this is\na recursive process, we can also apply the latter rule if the second factor\nis a more complex expression which we know always evaluates to one.\n\nCertain optimizer steps symbolically track the storage and memory locations. For example, this\ninformation is used to compute Keccak-256 hashes that can be evaluated during compile time. Consider\nthe sequence:\n\n.. code-block:: none\n\n    PUSH 32\n    PUSH 0\n    CALLDATALOAD\n    PUSH 100\n    DUP2\n    MSTORE\n    KECCAK256\n\nor the equivalent Yul\n\n.. code-block:: yul\n\n    let x := calldataload(0)\n    mstore(x, 100)\n    let value := keccak256(x, 32)\n\nIn this case, the optimizer tracks the value at a memory location ``calldataload(0)`` and then\nrealizes that the Keccak-256 hash can be evaluated at compile time. This only works if there is no\nother instruction that modifies memory between the ``mstore`` and ``keccak256``. So if there is an\ninstruction that writes to memory (or storage), then we need to erase the knowledge of the current\nmemory (or storage). There is, however, an exception to this erasing, when we can easily see that\nthe instruction doesn't write to a certain location.\n\nFor example,\n\n.. code-block:: yul\n\n    let x := calldataload(0)\n    mstore(x, 100)\n    // Current knowledge memory location x -> 100\n    let y := add(x, 32)\n    // Does not clear the knowledge that x -> 100, since y does not write to [x, x + 32)\n    mstore(y, 200)\n    // This Keccak-256 can now be evaluated\n    let value := keccak256(x, 32)\n\nTherefore, modifications to storage and memory locations, of say location ``l``, must erase\nknowledge about storage or memory locations which may be equal to ``l``. More specifically, for\nstorage, the optimizer has to erase all knowledge of symbolic locations, that may be equal to ``l``\nand for memory, the optimizer has to erase all knowledge of symbolic locations that may not be at\nleast 32 bytes away. If ``m`` denotes an arbitrary location, then this decision on erasure is done\nby computing the value ``sub(l, m)``. For storage, if this value evaluates to a literal that is\nnon-zero, then the knowledge about ``m`` will be kept. For memory, if the value evaluates to a\nliteral that is between ``32`` and ``2**256 - 32``, then the knowledge about ``m`` will be kept. In\nall other cases, the knowledge about ``m`` will be erased.\n\nAfter this process, we know which expressions have to be on the stack at\nthe end, and have a list of modifications to memory and storage. This information\nis stored together with the basic blocks and is used to link them. Furthermore,\nknowledge about the stack, storage and memory configuration is forwarded to\nthe next block(s).\n\nIf we know the targets of all ``JUMP`` and ``JUMPI`` instructions,\nwe can build a complete control flow graph of the program. If there is only\none target we do not know (this can happen as in principle, jump targets can\nbe computed from inputs), we have to erase all knowledge about the input state\nof a block as it can be the target of the unknown ``JUMP``. If the opcode-based\noptimizer module finds a ``JUMPI`` whose condition evaluates to a constant, it transforms it\nto an unconditional jump.\n\nAs the last step, the code in each block is re-generated. The optimizer creates\na dependency graph from the expressions on the stack at the end of the block,\nand it drops every operation that is not part of this graph. It generates code\nthat applies the modifications to memory and storage in the order they were\nmade in the original code (dropping modifications which were found not to be\nneeded). Finally, it generates all values that are required to be on the\nstack in the correct place.\n\nThese steps are applied to each basic block and the newly generated code\nis used as replacement if it is smaller. If a basic block is split at a\n``JUMPI`` and during the analysis, the condition evaluates to a constant,\nthe ``JUMPI`` is replaced based on the value of the constant. Thus code like\n\n.. code-block:: solidity\n\n    uint x = 7;\n    data[7] = 9;\n    if (data[x] != x + 2) // this condition is never true\n      return 2;\n    else\n      return 1;\n\nsimplifies to this:\n\n.. code-block:: solidity\n\n    data[7] = 9;\n    return 1;\n\nSimple Inlining\n---------------\n\nSince Solidity version 0.8.2, there is another optimizer step that replaces certain\njumps to blocks containing \"simple\" instructions ending with a \"jump\" by a copy of these instructions.\nThis corresponds to inlining of simple, small Solidity or Yul functions. In particular, the sequence\n``PUSHTAG(tag) JUMP`` may be replaced, whenever the ``JUMP`` is marked as jump \"into\" a\nfunction and behind ``tag`` there is a basic block (as described above for the\n\"CommonSubexpressionEliminator\") that ends in another ``JUMP`` which is marked as a jump\n\"out of\" a function.\n\nIn particular, consider the following prototypical example of assembly generated for a\ncall to an internal Solidity function:\n\n.. code-block:: text\n\n      tag_return\n      tag_f\n      jump      // in\n    tag_return:\n      ...opcodes after call to f...\n\n    tag_f:\n      ...body of function f...\n      jump      // out\n\nAs long as the body of the function is a continuous basic block, the \"Inliner\" can replace ``tag_f jump`` by\nthe block at ``tag_f`` resulting in:\n\n.. code-block:: text\n\n      tag_return\n      ...body of function f...\n      jump\n    tag_return:\n      ...opcodes after call to f...\n\n    tag_f:\n      ...body of function f...\n      jump      // out\n\nNow ideally, the other optimizer steps described above will result in the return tag push being moved\ntowards the remaining jump resulting in:\n\n.. code-block:: text\n\n      ...body of function f...\n      tag_return\n      jump\n    tag_return:\n      ...opcodes after call to f...\n\n    tag_f:\n      ...body of function f...\n      jump      // out\n\nIn this situation the \"PeepholeOptimizer\" will remove the return jump. Ideally, all of this can be done\nfor all references to ``tag_f`` leaving it unused, s.t. it can be removed, yielding:\n\n.. code-block:: text\n\n    ...body of function f...\n    ...opcodes after call to f...\n\nSo the call to function ``f`` is inlined and the original definition of ``f`` can be removed.\n\nInlining like this is attempted, whenever a heuristics suggests that inlining is cheaper over the lifetime of a\ncontract than not inlining. This heuristics depends on the size of the function body, the\nnumber of other references to its tag (approximating the number of calls to the function) and\nthe expected number of executions of the contract (the global optimizer parameter \"runs\").\n\n\nYul-Based Optimizer Module\n==========================\n\nThe Yul-based optimizer consists of several stages and components that all transform\nthe AST in a semantically equivalent way. The goal is to end up either with code\nthat is shorter or at least only marginally longer but will allow further\noptimization steps.\n\n.. warning::\n\n    Since the optimizer is under heavy development, the information here might be outdated.\n    If you rely on a certain functionality, please reach out to the team directly.\n\nThe optimizer currently follows a purely greedy strategy and does not do any\nbacktracking.\n\nAll components of the Yul-based optimizer module are explained below.\nThe following transformation steps are the main components:\n\n- SSATransform\n- CommonSubexpressionEliminator\n- ExpressionSimplifier\n- UnusedAssignEliminator\n- FullInliner\n\n.. _optimizer-steps:\n\nOptimizer Steps\n---------------\n\nThis is a list of all steps the Yul-based optimizer sorted alphabetically. You can find more information\non the individual steps and their sequence below.\n\n============ ===============================\nAbbreviation Full name\n============ ===============================\n``f``        :ref:`block-flattener`\n``l``        :ref:`circular-references-pruner`\n``c``        :ref:`common-subexpression-eliminator`\n``C``        :ref:`conditional-simplifier`\n``U``        :ref:`conditional-unsimplifier`\n``n``        :ref:`control-flow-simplifier`\n``D``        :ref:`dead-code-eliminator`\n``E``        :ref:`equal-store-eliminator`\n``v``        :ref:`equivalent-function-combiner`\n``e``        :ref:`expression-inliner`\n``j``        :ref:`expression-joiner`\n``s``        :ref:`expression-simplifier`\n``x``        :ref:`expression-splitter`\n``I``        :ref:`for-loop-condition-into-body`\n``O``        :ref:`for-loop-condition-out-of-body`\n``o``        :ref:`for-loop-init-rewriter`\n``i``        :ref:`full-inliner`\n``g``        :ref:`function-grouper`\n``h``        :ref:`function-hoister`\n``F``        :ref:`function-specializer`\n``T``        :ref:`literal-rematerialiser`\n``L``        :ref:`load-resolver`\n``M``        :ref:`loop-invariant-code-motion`\n``m``        :ref:`rematerialiser`\n``V``        :ref:`ssa-reverser`\n``a``        :ref:`ssa-transform`\n``t``        :ref:`structural-simplifier`\n``r``        :ref:`unused-assign-eliminator`\n``p``        :ref:`unused-function-parameter-pruner`\n``S``        :ref:`unused-store-eliminator`\n``u``        :ref:`unused-pruner`\n``d``        :ref:`var-decl-initializer`\n============ ===============================\n\nSome steps depend on properties ensured by ``BlockFlattener``, ``FunctionGrouper``, ``ForLoopInitRewriter``.\nFor this reason the Yul optimizer always applies them before applying any steps supplied by the user.\n\n.. _selecting-optimizations:\n\nSelecting Optimizations\n-----------------------\n\nBy default the optimizer applies its predefined sequence of optimization steps to the generated assembly.\nYou can override this sequence and supply your own using the ``--yul-optimizations`` option:\n\n.. code-block:: bash\n\n    solc --optimize --ir-optimized --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul:fDnTOcmu'\n\nThe order of steps is significant and affects the quality of the output.\nMoreover, applying a step may uncover new optimization opportunities for others that were already applied,\nso repeating steps is often beneficial.\n\nThe sequence inside ``[...]`` will be applied multiple times in a loop until the Yul code\nremains unchanged or until the maximum number of rounds (currently 12) has been reached.\nBrackets (``[]``) may be used multiple times in a sequence, but can not be nested.\n\nAn important thing to note, is that there are some hardcoded steps that are always run before and after the\nuser-supplied sequence, or the default sequence if one was not supplied by the user.\n\nThe cleanup sequence delimiter ``:`` is optional, and is used to supply a custom cleanup sequence\nin order to replace the default one. If omitted, the optimizer will simply apply the default cleanup\nsequence. In addition, the delimiter may be placed at the beginning of the user-supplied sequence,\nwhich will result in the optimization sequence being empty, whereas conversely, if placed at the end of\nthe sequence, will be treated as an empty cleanup sequence.\n\nPreprocessing\n-------------\n\nThe preprocessing components perform transformations to get the program\ninto a certain normal form that is easier to work with. This normal\nform is kept during the rest of the optimization process.\n\n.. _disambiguator:\n\nDisambiguator\n^^^^^^^^^^^^^\n\nThe disambiguator takes an AST and returns a fresh copy where all identifiers have\nunique names in the input AST. This is a prerequisite for all other optimizer stages.\nOne of the benefits is that identifier lookup does not need to take scopes into account\nwhich simplifies the analysis needed for other steps.\n\nAll subsequent stages have the property that all names stay unique. This means if\na new identifier needs to be introduced, a new unique name is generated.\n\n.. _function-hoister:\n\nFunctionHoister\n^^^^^^^^^^^^^^^\n\nThe function hoister moves all function definitions to the end of the topmost block. This is\na semantically equivalent transformation as long as it is performed after the\ndisambiguation stage. The reason is that moving a definition to a higher-level block cannot decrease\nits visibility and it is impossible to reference variables defined in a different function.\n\nThe benefit of this stage is that function definitions can be looked up more easily\nand functions can be optimized in isolation without having to traverse the AST completely.\n\n.. _function-grouper:\n\nFunctionGrouper\n^^^^^^^^^^^^^^^\n\nThe function grouper has to be applied after the Disambiguator and the FunctionHoister.\nIts effect is that all topmost elements that are not function definitions are moved\ninto a single block which is the first statement of the root block.\n\nAfter this step, a program has the following normal form:\n\n.. code-block:: text\n\n    { I F... }\n\nWhere ``I`` is a (potentially empty) block that does not contain any function definitions (not even recursively)\nand ``F`` is a list of function definitions such that no function contains a function definition.\n\nThe benefit of this stage is that we always know where the list of functions begins.\n\n.. _for-loop-condition-into-body:\n\nForLoopConditionIntoBody\n^^^^^^^^^^^^^^^^^^^^^^^^\n\nThis transformation moves the loop-iteration condition of a ``for`` loop into loop body.\nWe need this transformation because :ref:`expression-splitter` will not\napply to iteration condition expressions (the ``C`` in the following example).\n\n.. code-block:: text\n\n    for { Init... } C { Post... } {\n        Body...\n    }\n\nis transformed to\n\n.. code-block:: text\n\n    for { Init... } 1 { Post... } {\n        if iszero(C) { break }\n        Body...\n    }\n\nThis transformation can also be useful when paired with LoopInvariantCodeMotion, since\ninvariants in the loop-invariant conditions can then be taken outside the loop.\n\n.. _for-loop-init-rewriter:\n\nForLoopInitRewriter\n^^^^^^^^^^^^^^^^^^^\n\nThis transformation moves the initialization part of a ``for`` loop to before\nthe loop:\n\n.. code-block:: text\n\n    for { Init... } C { Post... } {\n        Body...\n    }\n\nis transformed to\n\n.. code-block:: text\n\n    Init...\n    for {} C { Post... } {\n        Body...\n    }\n\nThis eases the rest of the optimization process because we can ignore\nthe complicated scoping rules of the ``for`` loop initialization block.\n\n.. _var-decl-initializer:\n\nVarDeclInitializer\n^^^^^^^^^^^^^^^^^^\nThis step rewrites variable declarations so that all of them are initialized.\nDeclarations like ``let x, y`` are split into multiple declaration statements.\n\nOnly supports initializing with the zero literal for now.\n\nPseudo-SSA Transformation\n-------------------------\n\nThe purpose of this components is to get the program into a longer form,\nso that other components can more easily work with it. The final representation\nwill be similar to a static-single-assignment (SSA) form, with the difference\nthat it does not make use of explicit \"phi\" functions which combines the values\nfrom different branches of control flow because such a feature does not exist\nin the Yul language. Instead, when control flow merges, if a variable is re-assigned\nin one of the branches, a new SSA variable is declared to hold its current value,\nso that the following expressions still only need to reference SSA variables.\n\nAn example transformation is the following:\n\n.. code-block:: yul\n\n    {\n        let a := calldataload(0)\n        let b := calldataload(0x20)\n        if gt(a, 0) {\n            b := mul(b, 0x20)\n        }\n        a := add(a, 1)\n        sstore(a, add(b, 0x20))\n    }\n\n\nWhen all the following transformation steps are applied, the program will look\nas follows:\n\n.. code-block:: yul\n\n    {\n        let _1 := 0\n        let a_9 := calldataload(_1)\n        let a := a_9\n        let _2 := 0x20\n        let b_10 := calldataload(_2)\n        let b := b_10\n        let _3 := 0\n        let _4 := gt(a_9, _3)\n        if _4\n        {\n            let _5 := 0x20\n            let b_11 := mul(b_10, _5)\n            b := b_11\n        }\n        let b_12 := b\n        let _6 := 1\n        let a_13 := add(a_9, _6)\n        let _7 := 0x20\n        let _8 := add(b_12, _7)\n        sstore(a_13, _8)\n    }\n\nNote that the only variable that is re-assigned in this snippet is ``b``.\nThis re-assignment cannot be avoided because ``b`` has different values\ndepending on the control flow. All other variables never change their\nvalue once they are defined. The advantage of this property is that\nvariables can be freely moved around and references to them\ncan be exchanged by their initial value (and vice-versa),\nas long as these values are still valid in the new context.\n\nOf course, the code here is far from being optimized. To the contrary, it is much\nlonger. The hope is that this code will be easier to work with and furthermore,\nthere are optimizer steps that undo these changes and make the code more\ncompact again at the end.\n\n.. _expression-splitter:\n\nExpressionSplitter\n^^^^^^^^^^^^^^^^^^\n\nThe expression splitter turns expressions like ``add(mload(0x123), mul(mload(0x456), 0x20))``\ninto a sequence of declarations of unique variables that are assigned sub-expressions\nof that expression so that each function call has only variables\nas arguments.\n\nThe above would be transformed into\n\n.. code-block:: yul\n\n    {\n        let _1 := 0x20\n        let _2 := 0x456\n        let _3 := mload(_2)\n        let _4 := mul(_3, _1)\n        let _5 := 0x123\n        let _6 := mload(_5)\n        let z := add(_6, _4)\n    }\n\nNote that this transformation does not change the order of opcodes or function calls.\n\nIt is not applied to loop iteration-condition, because the loop control flow does not allow\nthis \"outlining\" of the inner expressions in all cases. We can sidestep this limitation by applying\n:ref:`for-loop-condition-into-body` to move the iteration condition into loop body.\n\nThe final program should be in an *expression-split form*, where (with the exception of loop conditions)\nfunction calls cannot appear nested inside expressions\nand all function call arguments have to be variables.\n\nThe benefits of this form are that it is much easier to re-order the sequence of opcodes\nand it is also easier to perform function call inlining. Furthermore, it is simpler\nto replace individual parts of expressions or re-organize the \"expression tree\".\nThe drawback is that such code is much harder to read for humans.\n\n.. _ssa-transform:\n\nSSATransform\n^^^^^^^^^^^^\n\nThis stage tries to replace repeated assignments to\nexisting variables by declarations of new variables as much as\npossible.\nThe reassignments are still there, but all references to the\nreassigned variables are replaced by the newly declared variables.\n\nExample:\n\n.. code-block:: yul\n\n    {\n        let a := 1\n        mstore(a, 2)\n        a := 3\n    }\n\nis transformed to\n\n.. code-block:: yul\n\n    {\n        let a_1 := 1\n        let a := a_1\n        mstore(a_1, 2)\n        let a_3 := 3\n        a := a_3\n    }\n\nExact semantics:\n\nFor any variable ``a`` that is assigned to somewhere in the code\n(variables that are declared with value and never re-assigned\nare not modified) perform the following transforms:\n\n- replace ``let a := v`` by ``let a_i := v   let a := a_i``\n- replace ``a := v`` by ``let a_i := v   a := a_i`` where ``i`` is a number such that ``a_i`` is yet unused.\n\nFurthermore, always record the current value of ``i`` used for ``a`` and replace each\nreference to ``a`` by ``a_i``.\nThe current value mapping is cleared for a variable ``a`` at the end of each block\nin which it was assigned to and at the end of the ``for`` loop init block if it is assigned\ninside the ``for`` loop body or post block.\nIf a variable's value is cleared according to the rule above and the variable is declared outside\nthe block, a new SSA variable will be created at the location where control flow joins,\nthis includes the beginning of loop post/body block and the location right after\n``if``/``switch``/``for``/block statement.\n\nAfter this stage, the UnusedAssignEliminator is recommended to remove the unnecessary\nintermediate assignments.\n\nThis stage provides best results if the ExpressionSplitter and the CommonSubexpressionEliminator\nare run right before it, because then it does not generate excessive amounts of variables.\nOn the other hand, the CommonSubexpressionEliminator could be more efficient if run after the\nSSA transform.\n\n.. _unused-assign-eliminator:\n\nUnusedAssignEliminator\n^^^^^^^^^^^^^^^^^^^^^^\n\nThe SSA transform always generates an assignment of the form ``a := a_i``, even though\nthese might be unnecessary in many cases, like the following example:\n\n.. code-block:: yul\n\n    {\n        let a := 1\n        a := mload(a)\n        a := sload(a)\n        sstore(a, 1)\n    }\n\nThe SSA transform converts this snippet to the following:\n\n.. code-block:: yul\n\n    {\n        let a_1 := 1\n        let a := a_1\n        let a_2 := mload(a_1)\n        a := a_2\n        let a_3 := sload(a_2)\n        a := a_3\n        sstore(a_3, 1)\n    }\n\nThe UnusedAssignEliminator removes all the three assignments to ``a``, because\nthe value of ``a`` is not used and thus turn this\nsnippet into strict SSA form:\n\n.. code-block:: yul\n\n    {\n        let a_1 := 1\n        let a_2 := mload(a_1)\n        let a_3 := sload(a_2)\n        sstore(a_3, 1)\n    }\n\nOf course the intricate parts of determining whether an assignment is unused or not\nare connected to joining control flow.\n\nThe component works as follows in detail:\n\nThe AST is traversed twice: in an information gathering step and in the\nactual removal step. During information gathering, we maintain a\nmapping from assignment statements to the three states\n\"unused\", \"undecided\" and \"used\" which signifies whether the assigned\nvalue will be used later by a reference to the variable.\n\nWhen an assignment is visited, it is added to the mapping in the \"undecided\" state\n(see remark about ``for`` loops below) and every other assignment to the same variable\nthat is still in the \"undecided\" state is changed to \"unused\".\nWhen a variable is referenced, the state of any assignment to that variable still\nin the \"undecided\" state is changed to \"used\".\n\nAt points where control flow splits, a copy\nof the mapping is handed over to each branch. At points where control flow\njoins, the two mappings coming from the two branches are combined in the following way:\nStatements that are only in one mapping or have the same state are used unchanged.\nConflicting values are resolved in the following way:\n\n- \"unused\", \"undecided\" -> \"undecided\"\n- \"unused\", \"used\" -> \"used\"\n- \"undecided\", \"used\" -> \"used\"\n\nFor ``for`` loops, the condition, body and post-part are visited twice, taking\nthe joining control-flow at the condition into account.\nIn other words, we create three control flow paths: Zero runs of the loop,\none run and two runs and then combine them at the end.\n\nSimulating a third run or even more is unnecessary, which can be seen as follows:\n\nA state of an assignment at the beginning of the iteration will deterministically\nresult in a state of that assignment at the end of the iteration. Let this\nstate mapping function be called ``f``. The combination of the three different\nstates ``unused``, ``undecided`` and ``used`` as explained above is the ``max``\noperation where ``unused = 0``, ``undecided = 1`` and ``used = 2``.\n\nThe proper way would be to compute\n\n.. code-block:: none\n\n    max(s, f(s), f(f(s)), f(f(f(s))), ...)\n\nas state after the loop. Since ``f`` just has a range of three different values,\niterating it has to reach a cycle after at most three iterations,\nand thus ``f(f(f(s)))`` has to equal one of ``s``, ``f(s)``, or ``f(f(s))``\nand thus\n\n.. code-block:: none\n\n    max(s, f(s), f(f(s))) = max(s, f(s), f(f(s)), f(f(f(s))), ...)\n\nIn summary, running the loop at most twice is enough because there are only three\ndifferent states.\n\nFor ``switch`` statements that have a default case, there is no control-flow\npart that skips the ``switch``.\n\nWhen a variable goes out of scope, all statements still in the \"undecided\"\nstate are changed to \"unused\", unless the variable is the return\nparameter of a function - there, the state changes to \"used\".\n\nIn the second traversal, all assignments that are in the \"unused\" state are removed.\n\nThis step is usually run right after the SSA transform to complete\nthe generation of the pseudo-SSA.\n\nTools\n-----\n\nMovability\n^^^^^^^^^^\n\nMovability is a property of an expression. It roughly means that the expression\nis side-effect free and its evaluation only depends on the values of variables\nand the call-constant state of the environment. Most expressions are movable.\nThe following parts make an expression non-movable:\n\n- function calls (might be relaxed in the future if all statements in the function are movable)\n- opcodes that (can) have side-effects (like ``call`` or ``selfdestruct``)\n- opcodes that read or write memory, storage or external state information\n- opcodes that depend on the current PC, memory size or returndata size\n\nDataflowAnalyzer\n^^^^^^^^^^^^^^^^\n\nThe DataflowAnalyzer is not an optimizer step itself but is used as a tool\nby other components. While traversing the AST, it tracks the current value of\neach variable, as long as that value is a movable expression.\nIt records the variables that are part of the expression\nthat is currently assigned to each other variable. Upon each assignment to\na variable ``a``, the current stored value of ``a`` is updated and\nall stored values of all variables ``b`` are cleared whenever ``a`` is part\nof the currently stored expression for ``b``.\n\nAt control-flow joins, knowledge about variables is cleared if they have or would be assigned\nin any of the control-flow paths. For instance, upon entering a\n``for`` loop, all variables are cleared that will be assigned during the\nbody or the post block.\n\nExpression-Scale Simplifications\n--------------------------------\n\nThese simplification passes change expressions and replace them by equivalent\nand hopefully simpler expressions.\n\n.. _common-subexpression-eliminator:\n\nCommonSubexpressionEliminator\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThis step uses the DataflowAnalyzer and replaces subexpressions that\nsyntactically match the current value of a variable by a reference to\nthat variable. This is an equivalence transform because such subexpressions have\nto be movable.\n\nAll subexpressions that are identifiers themselves are replaced by their\ncurrent value if the value is an identifier.\n\nThe combination of the two rules above allow to compute a local value\nnumbering, which means that if two variables have the same\nvalue, one of them will always be unused. The UnusedPruner or the\nUnusedAssignEliminator will then be able to fully eliminate such\nvariables.\n\nThis step is especially efficient if the ExpressionSplitter is run\nbefore. If the code is in pseudo-SSA form,\nthe values of variables are available for a longer time and thus we\nhave a higher chance of expressions to be replaceable.\n\nThe ExpressionSimplifier will be able to perform better replacements\nif the CommonSubexpressionEliminator was run right before it.\n\n.. _expression-simplifier:\n\nExpressionSimplifier\n^^^^^^^^^^^^^^^^^^^^\n\nThe ExpressionSimplifier uses the DataflowAnalyzer and makes use\nof a list of equivalence transforms on expressions like ``X + 0 -> X``\nto simplify the code.\n\nIt tries to match patterns like ``X + 0`` on each subexpression.\nDuring the matching procedure, it resolves variables to their currently\nassigned expressions to be able to match more deeply nested patterns\neven when the code is in pseudo-SSA form.\n\nSome of the patterns like ``X - X -> 0`` can only be applied as long\nas the expression ``X`` is movable, because otherwise it would remove its potential side-effects.\nSince variable references are always movable, even if their current\nvalue might not be, the ExpressionSimplifier is again more powerful\nin split or pseudo-SSA form.\n\n.. _literal-rematerialiser:\n\nLiteralRematerialiser\n^^^^^^^^^^^^^^^^^^^^^\n\nTo be documented.\n\n.. _load-resolver:\n\nLoadResolver\n^^^^^^^^^^^^\n\nOptimisation stage that replaces expressions of type ``sload(x)`` and ``mload(x)`` by the value\ncurrently stored in storage resp. memory, if known.\n\nWorks best if the code is in SSA form.\n\nPrerequisites: Disambiguator, ForLoopInitRewriter.\n\nStatement-Scale Simplifications\n-------------------------------\n\n.. _circular-references-pruner:\n\nCircularReferencesPruner\n^^^^^^^^^^^^^^^^^^^^^^^^\n\nThis stage removes functions that call each other but are\nneither externally referenced nor referenced from the outermost context.\n\n.. _conditional-simplifier:\n\nConditionalSimplifier\n^^^^^^^^^^^^^^^^^^^^^\n\nThe ConditionalSimplifier inserts assignments to condition variables if the value can be determined\nfrom the control-flow.\n\nDestroys SSA form.\n\nCurrently, this tool is very limited, mostly because we do not yet have support\nfor boolean types. Since conditions only check for expressions being nonzero,\nwe cannot assign a specific value.\n\nCurrent features:\n\n- ``switch`` cases: insert ``<condition> := <caseLabel>``\n- after ``if`` statement with terminating control-flow, insert ``<condition> := 0``\n\nFuture features:\n\n- allow replacements by ``1``\n- take termination of user-defined functions into account\n\nWorks best with SSA form and if dead code removal has run before.\n\nPrerequisite: Disambiguator.\n\n.. _conditional-unsimplifier:\n\nConditionalUnsimplifier\n^^^^^^^^^^^^^^^^^^^^^^^\n\nReverse of ConditionalSimplifier.\n\n.. _control-flow-simplifier:\n\nControlFlowSimplifier\n^^^^^^^^^^^^^^^^^^^^^\n\nSimplifies several control-flow structures:\n\n- replace ``if`` with empty body with ``pop(condition)``\n- remove empty default ``switch`` case\n- remove empty ``switch`` case if no default case exists\n- replace ``switch`` with no cases with ``pop(expression)``\n- turn ``switch`` with single case into ``if``\n- replace ``switch`` with only default case with ``pop(expression)`` and body\n- replace ``switch`` with const expr with matching case body\n- replace ``for`` with terminating control flow and without other ``break``/``continue`` by ``if``\n- remove ``leave`` at the end of a function.\n\nNone of these operations depend on the data flow. The StructuralSimplifier\nperforms similar tasks that do depend on data flow.\n\nThe ControlFlowSimplifier does record the presence or absence of ``break``\nand ``continue`` statements during its traversal.\n\nPrerequisite: Disambiguator, FunctionHoister, ForLoopInitRewriter.\n\nImportant: Introduces EVM opcodes and thus can only be used on EVM code for now.\n\n.. _dead-code-eliminator:\n\nDeadCodeEliminator\n^^^^^^^^^^^^^^^^^^\n\nThis optimization stage removes unreachable code.\n\nUnreachable code is any code within a block which is preceded by a\n``leave``, ``return``, ``invalid``, ``break``, ``continue``, ``selfdestruct``, ``revert`` or by\na call to a user-defined function that recurses infinitely.\n\nFunction definitions are retained as they might be called by earlier\ncode and thus are considered reachable.\n\nBecause variables declared in a ``for`` loop's init block have their scope extended to the loop body,\nwe require ForLoopInitRewriter to run before this step.\n\nPrerequisites: ForLoopInitRewriter, FunctionHoister, FunctionGrouper.\n\n.. _equal-store-eliminator:\n\nEqualStoreEliminator\n^^^^^^^^^^^^^^^^^^^^\n\nThis steps removes ``mstore(k, v)`` and ``sstore(k, v)`` calls if\nthere was a previous call to ``mstore(k, v)`` / ``sstore(k, v)``,\nno other store in between and the values of ``k`` and ``v`` did not change.\n\nThis simple step is effective if run after the SSATransform and the\nCommonSubexpressionEliminator, because SSA will make sure that the variables\nwill not change and the CommonSubexpressionEliminator reuses exactly the same\nvariable if the value is known to be the same.\n\nPrerequisites: Disambiguator, ForLoopInitRewriter.\n\n.. _unused-pruner:\n\nUnusedPruner\n^^^^^^^^^^^^\n\nThis step removes the definitions of all functions that are never referenced.\n\nIt also removes declarations of variables that are never referenced.\nIf a declaration assigns a value that is not movable, the expression is retained,\nbut its value is discarded.\n\nAll movable expression statements (expressions that are not assigned) are removed.\n\n.. _structural-simplifier:\n\nStructuralSimplifier\n^^^^^^^^^^^^^^^^^^^^\n\nThis is a general step that performs various kinds of simplifications on\na structural level:\n\n- replace ``if`` statement with empty body by ``pop(condition)``\n- replace ``if`` statement with true condition by its body\n- remove ``if`` statement with false condition\n- turn ``switch`` with single case into ``if``\n- replace ``switch`` with only default case by ``pop(expression)`` and body\n- replace ``switch`` with literal expression by matching case body\n- replace ``for`` loop with false condition by its initialization part\n\nThis component uses the DataflowAnalyzer.\n\n.. _block-flattener:\n\nBlockFlattener\n^^^^^^^^^^^^^^\n\nThis stage eliminates nested blocks by inserting the statements in the\ninner block at the appropriate place in the outer block. It depends on the\nFunctionGrouper and does not flatten the outermost block to keep the form\nproduced by the FunctionGrouper.\n\n.. code-block:: yul\n\n    {\n        {\n            let x := 2\n            {\n                let y := 3\n                mstore(x, y)\n            }\n        }\n    }\n\nis transformed to\n\n.. code-block:: yul\n\n    {\n        {\n            let x := 2\n            let y := 3\n            mstore(x, y)\n        }\n    }\n\nAs long as the code is disambiguated, this does not cause a problem because\nthe scopes of variables can only grow.\n\n.. _loop-invariant-code-motion:\n\nLoopInvariantCodeMotion\n^^^^^^^^^^^^^^^^^^^^^^^\nThis optimization moves movable SSA variable declarations outside the loop.\n\nOnly statements at the top level in a loop's body or post block are considered, i.e variable\ndeclarations inside conditional branches will not be moved out of the loop.\n\nExpressionSplitter and SSATransform should be run upfront to obtain better results.\n\nPrerequisites: Disambiguator, ForLoopInitRewriter, FunctionHoister.\n\n\nFunction-Level Optimizations\n----------------------------\n\n.. _function-specializer:\n\nFunctionSpecializer\n^^^^^^^^^^^^^^^^^^^\n\nThis step specializes the function with its literal arguments.\n\nIf a function, say, ``function f(a, b) { sstore (a, b) }``, is called with literal arguments, for\nexample, ``f(x, 5)``, where ``x`` is an identifier, it could be specialized by creating a new\nfunction ``f_1`` that takes only one argument, i.e.,\n\n.. code-block:: yul\n\n    function f_1(a_1) {\n        let b_1 := 5\n        sstore(a_1, b_1)\n    }\n\nOther optimization steps will be able to make more simplifications to the function. The\noptimization step is mainly useful for functions that would not be inlined.\n\nPrerequisites: Disambiguator, FunctionHoister.\n\nLiteralRematerialiser is recommended as a prerequisite, even though it's not required for\ncorrectness.\n\n.. _unused-function-parameter-pruner:\n\nUnusedFunctionParameterPruner\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThis step removes unused parameters in a function.\n\nIf a parameter is unused, like ``c`` and ``y`` in, ``function f(a,b,c) -> x, y { x := div(a,b) }``, we\nremove the parameter and create a new \"linking\" function as follows:\n\n.. code-block:: yul\n\n    function f(a,b) -> x { x := div(a,b) }\n    function f2(a,b,c) -> x, y { x := f(a,b) }\n\nand replace all references to ``f`` by ``f2``.\nThe inliner should be run afterwards to make sure that all references to ``f2`` are replaced by\n``f``.\n\nPrerequisites: Disambiguator, FunctionHoister, LiteralRematerialiser.\n\nThe step LiteralRematerialiser is not required for correctness. It helps deal with cases such as:\n``function f(x) -> y { revert(y, y} }`` where the literal ``y`` will be replaced by its value ``0``,\nallowing us to rewrite the function.\n\n.. index:: ! UnusedStoreEliminator\n.. _unused-store-eliminator:\n\nUnusedStoreEliminator\n^^^^^^^^^^^^^^^^^^^^^\n\nOptimizer component that removes redundant ``sstore`` and memory store statements.\nIn case of an ``sstore``, if all outgoing code paths revert (due to an explicit ``revert()``, ``invalid()``, or infinite recursion) or\nlead to another ``sstore`` for which the optimizer can tell that it will overwrite the first store, the statement will be removed.\nHowever, if there is a read operation between the initial ``sstore`` and the revert, or the overwriting ``sstore``, the statement\nwill not be removed.\nSuch read operations include: external calls, user-defined functions with any storage access, and ``sload`` of a slot that cannot be\nproven to differ from the slot written by the initial ``sstore``.\n\nFor example, the following code\n\n.. code-block:: yul\n\n    {\n        let c := calldataload(0)\n        sstore(c, 1)\n        if c {\n            sstore(c, 2)\n        }\n        sstore(c, 3)\n    }\n\nwill be transformed into the code below after the UnusedStoreEliminator step is run\n\n.. code-block:: yul\n\n    {\n        let c := calldataload(0)\n        if c { }\n        sstore(c, 3)\n    }\n\nFor memory store operations, things are generally simpler, at least in the outermost Yul block as all such\nstatements will be removed if they are never read from in any code path.\nAt function analysis level, however, the approach is similar to ``sstore``, as we do not know whether the memory location will\nbe read once we leave the function's scope, so the statement will be removed only if all code paths lead to a memory overwrite.\n\nBest run in SSA form.\n\nPrerequisites: Disambiguator, ForLoopInitRewriter.\n\n.. _equivalent-function-combiner:\n\nEquivalentFunctionCombiner\n^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIf two functions are syntactically equivalent, while allowing variable\nrenaming but not any re-ordering, then any reference to one of the\nfunctions is replaced by the other.\n\n\nThe actual removal of the function is performed by the UnusedPruner.\n\nFunction Inlining\n-----------------\n\n.. _expression-inliner:\n\nExpressionInliner\n^^^^^^^^^^^^^^^^^\n\nThis component of the optimizer performs restricted function inlining by inlining functions that can be\ninlined inside functional expressions, i.e. functions that:\n\n- return a single value.\n- have a body like ``r := <functional expression>``.\n- neither reference themselves nor ``r`` in the right hand side.\n\nFurthermore, for all parameters, all of the following need to be true:\n\n- The argument is movable.\n- The parameter is either referenced less than twice in the function body, or the argument is rather cheap\n  (\"cost\" of at most 1, like a constant up to ``0xff``).\n\nExample: The function to be inlined has the form of ``function f(...) -> r { r := E }`` where\n``E`` is an expression that does not reference ``r`` and all arguments in the function call are movable expressions.\n\nThe result of this inlining is always a single expression.\n\nThis component can only be used on sources with unique names.\n\n.. _full-inliner:\n\nFullInliner\n^^^^^^^^^^^\n\nThe FullInliner replaces certain calls of certain functions\nby the function's body. This is not very helpful in most cases, because\nit just increases the code size but does not have a benefit. Furthermore,\ncode is usually very expensive and we would often rather have shorter\ncode than more efficient code. In some cases, though, inlining a function\ncan have positive effects on subsequent optimizer steps. This is the case\nif one of the function arguments is a constant, for example.\n\nDuring inlining, a heuristic is used to tell if the function call\nshould be inlined or not.\nThe current heuristic does not inline into \"large\" functions unless\nthe called function is tiny. Functions that are only used once\nare inlined, as well as medium-sized functions, while function\ncalls with constant arguments allow slightly larger functions.\n\n\nIn the future, we may include a backtracking component\nthat, instead of inlining a function right away, only specializes it,\nwhich means that a copy of the function is generated where\na certain parameter is always replaced by a constant. After that,\nwe can run the optimizer on this specialized function. If it\nresults in heavy gains, the specialized function is kept,\notherwise the original function is used instead.\n\nFunctionHoister and ExpressionSplitter are recommended as prerequisites since they make the step\nmore efficient, but are not required for correctness.\nIn particular, function calls with other function calls as arguments are not inlined, but running\nExpressionSplitter beforehand ensures that there are no such calls in the input.\n\nCleanup\n-------\n\nThe cleanup is performed at the end of the optimizer run. It tries\nto combine split expressions into deeply nested ones again and also\nimproves the \"compilability\" for stack machines by eliminating\nvariables as much as possible.\n\n.. _expression-joiner:\n\nExpressionJoiner\n^^^^^^^^^^^^^^^^\n\nThis is the opposite operation of the ExpressionSplitter. It turns a sequence of\nvariable declarations that have exactly one reference into a complex expression.\nThis stage fully preserves the order of function calls and opcode executions.\nIt does not make use of any information concerning the commutativity of the opcodes;\nif moving the value of a variable to its place of use would change the order\nof any function call or opcode execution, the transformation is not performed.\n\nNote that the component will not move the assigned value of a variable assignment\nor a variable that is referenced more than once.\n\nThe snippet ``let x := add(0, 2) let y := mul(x, mload(2))`` is not transformed,\nbecause it would cause the order of the call to the opcodes ``add`` and\n``mload`` to be swapped - even though this would not make a difference\nbecause ``add`` is movable.\n\nWhen reordering opcodes like that, variable references and literals are ignored.\nBecause of that, the snippet ``let x := add(0, 2) let y := mul(x, 3)`` is\ntransformed to ``let y := mul(add(0, 2), 3)``, even though the ``add`` opcode\nwould be executed after the evaluation of the literal ``3``.\n\n.. _ssa-reverser:\n\nSSAReverser\n^^^^^^^^^^^\n\nThis is a tiny step that helps in reversing the effects of the SSATransform\nif it is combined with the CommonSubexpressionEliminator and the\nUnusedPruner.\n\nThe SSA form we generate is detrimental to code generation\nbecause it produces many local variables. It would\nbe better to just reuse existing variables with assignments instead of\nfresh variable declarations.\n\nThe SSATransform rewrites\n\n.. code-block:: yul\n\n    let a := calldataload(0)\n    mstore(a, 1)\n\nto\n\n.. code-block:: yul\n\n    let a_1 := calldataload(0)\n    let a := a_1\n    mstore(a_1, 1)\n    let a_2 := calldataload(0x20)\n    a := a_2\n\nThe problem is that instead of ``a``, the variable ``a_1`` is used\nwhenever ``a`` was referenced. The SSATransform changes statements\nof this form by just swapping out the declaration and the assignment. The above\nsnippet is turned into\n\n.. code-block:: yul\n\n    let a := calldataload(0)\n    let a_1 := a\n    mstore(a_1, 1)\n    a := calldataload(0x20)\n    let a_2 := a\n\nThis is a very simple equivalence transform, but when we now run the\nCommonSubexpressionEliminator, it will replace all occurrences of ``a_1``\nby ``a`` (until ``a`` is re-assigned). The UnusedPruner will then\neliminate the variable ``a_1`` altogether and thus fully reverse the\nSSATransform.\n\n.. _stack-compressor:\n\nStackCompressor\n^^^^^^^^^^^^^^^\n\nOne problem that makes code generation for the Ethereum Virtual Machine\nhard is the fact that there is a hard limit of 16 slots for reaching\ndown the expression stack. This more or less translates to a limit\nof 16 local variables. The stack compressor takes Yul code and\ncompiles it to EVM bytecode. Whenever the stack difference is too\nlarge, it records the function this happened in.\n\nFor each function that caused such a problem, the Rematerialiser\nis called with a special request to aggressively eliminate specific\nvariables sorted by the cost of their values.\n\nOn failure, this procedure is repeated multiple times.\n\n.. _rematerialiser:\n\nRematerialiser\n^^^^^^^^^^^^^^\n\nThe rematerialisation stage tries to replace variable references by the expression that\nwas last assigned to the variable. This is of course only beneficial if this expression\nis comparatively cheap to evaluate. Furthermore, it is only semantically equivalent if\nthe value of the expression did not change between the point of assignment and the\npoint of use. The main benefit of this stage is that it can save stack slots if it\nleads to a variable being eliminated completely (see below), but it can also\nsave a ``DUP`` opcode on the EVM if the expression is very cheap.\n\nThe Rematerialiser uses the DataflowAnalyzer to track the current values of variables,\nwhich are always movable.\nIf the value is very cheap or the variable was explicitly requested to be eliminated,\nthe variable reference is replaced by its current value.\n\n.. _for-loop-condition-out-of-body:\n\nForLoopConditionOutOfBody\n^^^^^^^^^^^^^^^^^^^^^^^^^\n\nReverses the transformation of ForLoopConditionIntoBody.\n\nFor any movable ``c``, it turns\n\n.. code-block:: none\n\n    for { ... } 1 { ... } {\n    if iszero(c) { break }\n    ...\n    }\n\ninto\n\n.. code-block:: none\n\n    for { ... } c { ... } {\n    ...\n    }\n\nand it turns\n\n.. code-block:: none\n\n    for { ... } 1 { ... } {\n    if c { break }\n    ...\n    }\n\ninto\n\n.. code-block:: none\n\n    for { ... } iszero(c) { ... } {\n    ...\n    }\n\nThe LiteralRematerialiser should be run before this step.\n\nCodegen-Based Optimizer Module\n==============================\n\nCurrently, the codegen-based optimizer module provides two optimizations.\n\nThe first one, available in the legacy code generator, moves literals to the right side of\ncommutative binary operators, which helps exploit their associativity.\n\nThe other one, available in the IR-based code generator, enables the use of unchecked arithmetic\nwhen generating code for incrementing the counter variable of certain idiomatic ``for`` loops.\nThis avoids wasting gas by identifying some conditions that guarantee that the counter variable\ncannot overflow.\nThis eliminates the need to use a verbose unchecked arithmetic block inside the loop body to\nincrement the counter variable.\n\n.. _unchecked-loop-optimizer:\n\nUnchecked Loop Increment\n------------------------\n\nIntroduced in Solidity ``0.8.22``, the overflow check optimization step is concerned with identifying\nthe conditions under which the ``for`` loop counter can be safely incremented\nwithout overflow checks.\n\nThis optimization is **only** applied to ``for`` loops of the general form:\n\n.. code-block:: solidity\n\n    for (uint i = X; i < Y; ++i) {\n        // variable i is not modified in the loop body\n    }\n\nThe condition and the fact that the counter variable is only ever incremented\nguarantee that it never overflows.\nThe precise requirements for the loop to be eligible for the optimization are as follows:\n\n- The loop condition is a comparison of the form ``i < Y``, for a local counter variable ``i``\n  (called the \"loop counter\" hereon) and an expression ``Y``.\n- The built-in operator ``<`` is necessarily used in the loop condition and is the only operator\n  that triggers the optimization. ``<=`` and the like are intentionally excluded. Additionally,\n  user-defined operators are **not** eligible.\n- The loop expression is a prefix or postfix increment of the counter variable, i.e, ``i++`` or ``++i``.\n- The loop counter is a local variable of a built-in integer type.\n- The loop counter is **not** modified by the loop body or by the expression used as the loop condition.\n- The comparison is performed on the same type as the loop counter, meaning that the type of the\n  right-hand-side expression is implicitly convertible to the type of the counter, such that the latter\n  is not implicitly widened before the comparison.\n\nTo clarify the last condition, consider the following example:\n\n.. code-block:: solidity\n\n    for (uint8 i = 0; i < uint16(1000); i++) {\n        // ...\n    }\n\nIn this case, the counter ``i`` has its type implicitly converted from ``uint8``\nto ``uint16`` before the comparison and the condition is in fact never false, so\nthe overflow check for the increment cannot be removed.\n"
  },
  {
    "path": "docs/internals/source_mappings.rst",
    "content": ".. index:: source mappings\n\n***************\nSource Mappings\n***************\n\nAs part of the AST output, the compiler provides the range of the source\ncode that is represented by the respective node in the AST. This can be\nused for various purposes ranging from static analysis tools that report\nerrors based on the AST and debugging tools that highlight local variables\nand their uses.\n\nFurthermore, the compiler can also generate a mapping from the bytecode\nto the range in the source code that generated the instruction. This is again\nimportant for static analysis tools that operate on bytecode level and\nfor displaying the current position in the source code inside a debugger\nor for breakpoint handling. This mapping also contains other information,\nlike the jump type and the modifier depth (see below).\n\nBoth kinds of source mappings use integer identifiers to refer to source files.\nThe identifier of a source file is stored in\n``output['sources'][sourceName]['id']`` where ``output`` is the output of the\nstandard-json compiler interface parsed as JSON.\nFor some utility routines, the compiler generates \"internal\" source files\nthat are not part of the original input but are referenced from the source\nmappings. These source files together with their identifiers can be\nobtained via ``output['contracts'][sourceName][contractName]['evm']['bytecode']['generatedSources']``.\n\n.. note::\n    In the case of instructions that are not associated with any particular source file,\n    the source mapping assigns an integer identifier of ``-1``. This may happen for\n    bytecode sections stemming from compiler-generated inline assembly statements.\n\nThe source mappings inside the AST use the following\nnotation:\n\n``s:l:f``\n\nWhere ``s`` is the byte-offset to the start of the range in the source file,\n``l`` is the length of the source range in bytes and ``f`` is the source\nindex mentioned above.\n\nThe encoding in the source mapping for the bytecode is more complicated:\nIt is a list of ``s:l:f:j:m`` separated by ``;``. Each of these\nelements corresponds to an instruction, i.e. you cannot use the byte offset\nbut have to use the instruction offset (push instructions are longer than a single byte).\nThe fields ``s``, ``l`` and ``f`` are as above. ``j`` can be either\n``i``, ``o`` or ``-`` signifying whether a jump instruction goes into a\nfunction, returns from a function or is a regular jump as part of e.g. a loop.\nThe last field, ``m``, is an integer that denotes the \"modifier depth\". This depth\nis increased whenever the placeholder statement (``_``) is entered in a modifier\nand decreased when it is left again. This allows debuggers to track tricky cases\nlike the same modifier being used twice or multiple placeholder statements being\nused in a single modifier.\n\nIn order to compress these source mappings especially for bytecode, the\nfollowing rules are used:\n\n- If a field is empty, the value of the preceding element is used.\n- If a ``:`` is missing, all following fields are considered empty.\n\nThis means the following source mappings represent the same information:\n\n``1:2:1;1:9:1;2:1:2;2:1:2;2:1:2``\n\n``1:2:1;:9;2:1:2;;``\n\nImportant to note is that when the :ref:`verbatim <yul-verbatim>` builtin is used,\nthe source mappings will be invalid: The builtin is considered a single\ninstruction instead of potentially multiple.\n"
  },
  {
    "path": "docs/internals/variable_cleanup.rst",
    "content": ".. index: variable cleanup\n\n*********************\nCleaning Up Variables\n*********************\n\nUltimately, all values in the EVM are stored in 256 bit words.\nThus, in some cases, when the type of a value has less than 256 bits,\nit is necessary to clean the remaining bits.\nThe Solidity compiler is designed to do such cleaning before any operations\nthat might be adversely affected by the potential garbage in the remaining bits.\nFor example, before writing a value to  memory, the remaining bits need\nto be cleared because the memory contents can be used for computing\nhashes or sent as the data of a message call.  Similarly, before\nstoring a value in the storage, the remaining bits need to be cleaned\nbecause otherwise the garbled value can be observed.\n\nNote that access via inline assembly is not considered such an operation:\nIf you use inline assembly to access Solidity variables\nshorter than 256 bits, the compiler does not guarantee that\nthe value is properly cleaned up.\n\nMoreover, we do not clean the bits if the immediately\nfollowing operation is not affected.  For instance, since any non-zero\nvalue is considered ``true`` by ``JUMPI`` instruction, we do not clean\nthe boolean values before they are used as the condition for\n``JUMPI``.\n\nIn addition to the design principle above, the Solidity compiler\ncleans input data when it is loaded onto the stack.\n\nThe following table describes the cleaning rules applied to different types,\nwhere ``higher bits`` refers to the remaining bits in case the type has less than 256 bits.\n\n+---------------+---------------+-------------------------+\n|Type           |Valid Values   |Cleanup of Invalid Values|\n+===============+===============+=========================+\n|enum of n      |0 until n - 1  |throws exception         |\n|members        |               |                         |\n+---------------+---------------+-------------------------+\n|bool           |0 or 1         |results in 1             |\n+---------------+---------------+-------------------------+\n|signed integers|higher bits    |currently silently       |\n|               |set to the     |signextends to a valid   |\n|               |sign bit       |value, i.e. all higher   |\n|               |               |bits are set to the sign |\n|               |               |bit; may throw an        |\n|               |               |exception in the future  |\n+---------------+---------------+-------------------------+\n|unsigned       |higher bits    |currently silently masks |\n|integers       |zeroed         |to a valid value, i.e.   |\n|               |               |all higher bits are set  |\n|               |               |to zero; may throw an    |\n|               |               |exception in the future  |\n+---------------+---------------+-------------------------+\n\nNote that valid and invalid values are dependent on their type size.\nConsider ``uint8``, the unsigned 8-bit type, which has the following valid values:\n\n.. code-block:: none\n\n    0000...0000 0000 0000\n    0000...0000 0000 0001\n    0000...0000 0000 0010\n    ....\n    0000...0000 1111 1111\n\nAny invalid value will have the higher bits set to zero:\n\n.. code-block:: none\n\n    0101...1101 0010 1010   invalid value\n    0000...0000 0010 1010   cleaned value\n\nFor ``int8``, the signed 8-bit type, the valid values are:\n\nNegative\n\n.. code-block:: none\n\n    1111...1111 1111 1111\n    1111...1111 1111 1110\n    ....\n    1111...1111 1000 0000\n\nPositive\n\n.. code-block:: none\n\n    0000...0000 0000 0000\n    0000...0000 0000 0001\n    0000...0000 0000 0010\n    ....\n    0000...0000 0111 1111\n\nThe compiler will ``signextend`` the sign bit, which is 1 for negative and 0 for\npositive values, overwriting the higher bits:\n\nNegative\n\n.. code-block:: none\n\n    0010...1010 1111 1111   invalid value\n    1111...1111 1111 1111   cleaned value\n\nPositive\n\n.. code-block:: none\n\n    1101...0101 0000 0100   invalid value\n    0000...0000 0000 0100   cleaned value\n"
  },
  {
    "path": "docs/introduction-to-smart-contracts.rst",
    "content": "###############################\nIntroduction to Smart Contracts\n###############################\n\n.. _simple-smart-contract:\n\n***********************\nA Simple Smart Contract\n***********************\n\nLet us begin with a basic example that sets the value of a variable and exposes\nit for other contracts to access. It is fine if you do not understand\neverything right now, we will go into more details later.\n\nStorage Example\n===============\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract SimpleStorage {\n        uint storedData;\n\n        function set(uint x) public {\n            storedData = x;\n        }\n\n        function get() public view returns (uint) {\n            return storedData;\n        }\n    }\n\nThe first line tells you that the source code is licensed under the\nGPL version 3.0. Machine-readable license specifiers are important\nin a setting where publishing the source code is the default.\n\nThe next line specifies that the source code is written for\nSolidity version 0.4.16, or a newer version of the language up to, but not including version 0.9.0.\nThis is to ensure that the contract is not compilable with a new (breaking) compiler version, where it could behave differently.\n:ref:`Pragmas<pragma>` are common instructions for compilers about how to treat the\nsource code (e.g. `pragma once <https://en.wikipedia.org/wiki/Pragma_once>`_).\n\nA contract in the sense of Solidity is a collection of code (its *functions*) and\ndata (its *state*) that resides at a specific address on the Ethereum\nblockchain. The line ``uint storedData;`` declares a state variable called ``storedData`` of\ntype ``uint`` (*u*\\nsigned *int*\\eger of *256* bits). You can think of it as a single slot\nin a database that you can query and alter by calling functions of the\ncode that manages the database. In this example, the contract defines the\nfunctions ``set`` and ``get`` that can be used to modify\nor retrieve the value of the variable.\n\nTo access a member (like a state variable) of the current contract, you do not typically add the ``this.`` prefix,\nyou just access it directly via its name.\nUnlike in some other languages, omitting it is not just a matter of style,\nit results in a completely different way to access the member, but more on this later.\n\nThis contract does not do much yet apart from (due to the infrastructure\nbuilt by Ethereum) allowing anyone to store a single number that is accessible by\nanyone in the world without a (feasible) way to prevent you from publishing\nthis number. Anyone could call ``set`` again with a different value\nand overwrite your number, but the number is still stored in the history\nof the blockchain. Later, you will see how you can impose access restrictions\nso that only you can alter the number.\n\n.. warning::\n    Be careful with using Unicode text, as similar looking (or even identical) characters can\n    have different code points and as such are encoded as a different byte array.\n\n.. note::\n    All identifiers (contract names, function names and variable names) are restricted to\n    the ASCII character set. It is possible to store UTF-8 encoded data in string variables.\n\n.. index:: ! subcurrency\n\nSubcurrency Example\n===================\n\nThe following contract implements the simplest form of a\ncryptocurrency. The contract allows only its creator to create new coins (different issuance schemes are possible).\nAnyone can send coins to each other without a need for\nregistering with a username and password, all you need is an Ethereum keypair.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.26;\n\n    // This will only compile via IR\n    contract Coin {\n        // The keyword \"public\" makes variables\n        // accessible from other contracts\n        address public minter;\n        mapping(address => uint) public balances;\n\n        // Events allow clients to react to specific\n        // contract changes you declare\n        event Sent(address from, address to, uint amount);\n\n        // Constructor code is only run when the contract\n        // is created\n        constructor() {\n            minter = msg.sender;\n        }\n\n        // Sends an amount of newly created coins to an address\n        // Can only be called by the contract creator\n        function mint(address receiver, uint amount) public {\n            require(msg.sender == minter);\n            balances[receiver] += amount;\n        }\n\n        // Errors allow you to provide information about\n        // why an operation failed. They are returned\n        // to the caller of the function.\n        error InsufficientBalance(uint requested, uint available);\n\n        // Sends an amount of existing coins\n        // from any caller to an address\n        function send(address receiver, uint amount) public {\n            require(amount <= balances[msg.sender], InsufficientBalance(amount, balances[msg.sender]));\n            balances[msg.sender] -= amount;\n            balances[receiver] += amount;\n            emit Sent(msg.sender, receiver, amount);\n        }\n    }\n\nThis contract introduces some new concepts, let us go through them one by one.\n\nThe line ``address public minter;`` declares a state variable of type :ref:`address<address>`.\nThe ``address`` type is a 160-bit value that does not allow any arithmetic operations.\nIt is suitable for storing addresses of contracts, or a hash of the public half\nof a keypair belonging to :ref:`externally-owned accounts<accounts>`.\n\nThe keyword ``public`` automatically generates a function that allows you to access the current value of the state\nvariable from outside of the contract. Without this keyword, other contracts have no way to access the variable.\nThe code of the function generated by the compiler is equivalent\nto the following (ignore ``external`` and ``view`` for now):\n\n.. code-block:: solidity\n\n    function minter() external view returns (address) { return minter; }\n\nYou could add a function like the above yourself, but you would have a function and state variable with the same name.\nYou do not need to do this, the compiler figures it out for you.\n\n.. index:: mapping\n\nThe next line, ``mapping(address => uint) public balances;`` also\ncreates a public state variable, but it is a more complex datatype.\nThe :ref:`mapping <mapping-types>` type maps addresses to :ref:`unsigned integers <integers>`.\n\nMappings can be seen as `hash tables <https://en.wikipedia.org/wiki/Hash_table>`_ which are\nvirtually initialized such that every possible key exists from the start and is mapped to a\nvalue whose byte-representation is all zeros. However, it is neither possible to obtain a list of all keys of\na mapping, nor a list of all values. Record what you\nadded to the mapping, or use it in a context where this is not needed. Or\neven better, keep a list, or use a more suitable data type.\n\nThe :ref:`getter function<getter-functions>` created by the ``public`` keyword\nis more complex in the case of a mapping. It looks like the\nfollowing:\n\n.. code-block:: solidity\n\n    function balances(address account) external view returns (uint) {\n        return balances[account];\n    }\n\nYou can use this function to query the balance of a single account.\n\n.. index:: event\n\nThe line ``event Sent(address from, address to, uint amount);`` declares\nan :ref:`\"event\" <events>`, which is emitted in the last line of the function\n``send``. Ethereum clients such as web applications can\nlisten for these events emitted on the blockchain without much\ncost. As soon as it is emitted, the listener receives the\narguments ``from``, ``to`` and ``amount``, which makes it possible to track\ntransactions.\n\nTo listen for this event, you could use the following\nJavaScript code, which uses `web3.js <https://github.com/web3/web3.js/>`_ to create the ``Coin`` contract object,\nand any user interface calls the automatically generated ``balances`` function from above:\n\n.. code-block:: javascript\n\n    Coin.Sent().watch({}, '', function(error, result) {\n        if (!error) {\n            console.log(\"Coin transfer: \" + result.args.amount +\n                \" coins were sent from \" + result.args.from +\n                \" to \" + result.args.to + \".\");\n            console.log(\"Balances now:\\n\" +\n                \"Sender: \" + Coin.balances.call(result.args.from) +\n                \"Receiver: \" + Coin.balances.call(result.args.to));\n        }\n    })\n\n.. index:: coin\n\nThe :ref:`constructor<constructor>` is a special function that is executed during the creation of the contract and\ncannot be called afterwards. In this case, it permanently stores the address of the person creating the\ncontract. The ``msg`` variable (together with ``tx`` and ``block``) is a\n:ref:`special global variable <special-variables-functions>` that\ncontains properties which allow access to the blockchain. ``msg.sender`` is\nalways the address where the current (external) function call came from.\n\nThe functions that make up the contract, and that users and contracts can call are ``mint`` and ``send``.\n\nThe ``mint`` function sends an amount of newly created coins to another address. The :ref:`require\n<assert-and-require>` function call defines conditions that reverts all changes if not met. In this\nexample, ``require(msg.sender == minter);`` ensures that only the creator of the contract can call\n``mint``. In general, the creator can mint as many tokens as they like, but at some point, this will\nlead to a phenomenon called \"overflow\". Note that because of the default :ref:`Checked arithmetic\n<unchecked>`, the transaction would revert if the expression ``balances[receiver] += amount;``\noverflows, i.e., when ``balances[receiver] + amount`` in arbitrary precision arithmetic is larger\nthan the maximum value of ``uint`` (``2**256 - 1``). This is also true for the statement\n``balances[receiver] += amount;`` in the function ``send``.\n\n:ref:`Errors <errors>` allow you to provide more information to the caller about\nwhy a condition or operation failed. Errors are used together with the\n:ref:`revert statement <revert-statement>`. The ``revert`` statement unconditionally\naborts and reverts all changes, much like the :ref:`require function <assert-and-require-statements>`.\nBoth approaches allow you to provide the name of an error and additional data which will be supplied to the caller\n(and eventually to the front-end application or block explorer) so that\na failure can more easily be debugged or reacted upon.\n\nThe ``send`` function can be used by anyone (who already\nhas some of these coins) to send coins to anyone else. If the sender does not have\nenough coins to send, the ``if`` condition evaluates to true. As a result, the ``revert`` will cause the operation to fail\nwhile providing the sender with error details using the ``InsufficientBalance`` error.\n\n.. note::\n    If you use\n    this contract to send coins to an address, you will not see anything when you\n    look at that address on a blockchain explorer, because the record that you sent\n    coins and the changed balances are only stored in the data storage of this\n    particular coin contract. By using events, you can create\n    a \"blockchain explorer\" that tracks transactions and balances of your new coin,\n    but you have to inspect the coin contract address and not the addresses of the\n    coin owners.\n\n.. _blockchain-basics:\n\n*****************\nBlockchain Basics\n*****************\n\nBlockchains as a concept are not too hard to understand for programmers. The reason is that\nmost of the complications (mining, `hashing <https://en.wikipedia.org/wiki/Cryptographic_hash_function>`_,\n`elliptic-curve cryptography <https://en.wikipedia.org/wiki/Elliptic_curve_cryptography>`_,\n`peer-to-peer networks <https://en.wikipedia.org/wiki/Peer-to-peer>`_, etc.)\nare just there to provide a certain set of features and promises for the platform. Once you accept these\nfeatures as given, you do not have to worry about the underlying technology - or do you have\nto know how Amazon's AWS works internally in order to use it?\n\n.. index:: transaction\n\nTransactions\n============\n\nA blockchain is a globally shared, transactional database.\nThis means that everyone can read entries in the database just by participating in the network.\nIf you want to change something in the database, you have to create a so-called transaction\nwhich has to be accepted by all others.\nThe word transaction implies that the change you want to make (assume you want to change\ntwo values at the same time) is either not done at all or completely applied. Furthermore,\nwhile your transaction is being applied to the database, no other transaction can alter it.\n\nAs an example, imagine a table that lists the balances of all accounts in an\nelectronic currency. If a transfer from one account to another is requested,\nthe transactional nature of the database ensures that if the amount is\nsubtracted from one account, it is always added to the other account. If due\nto whatever reason, adding the amount to the target account is not possible,\nthe source account is also not modified.\n\nFurthermore, a transaction is always cryptographically signed by the sender (creator).\nThis makes it straightforward to guard access to specific modifications of the\ndatabase. In the example of the electronic currency, a simple check ensures that\nonly the person holding the keys to the account can transfer some compensation, e.g. Ether, from it.\n\n.. index:: ! block\n\nBlocks\n======\n\nOne major obstacle to overcome is what (in Bitcoin terms) is called a \"double-spend attack\":\nWhat happens if two transactions exist in the network that both want to empty an account?\nOnly one of the transactions can be valid, typically the one that is accepted first.\nThe problem is that \"first\" is not an objective term in a peer-to-peer network.\n\nThe abstract answer to this is that you do not have to care. A globally accepted order of the transactions\nwill be selected for you, solving the conflict. The transactions will be bundled into what is called a \"block\"\nand then they will be executed and distributed among all participating nodes.\nIf two transactions contradict each other, the one that ends up being second will\nbe rejected and not become part of the block.\n\nThese blocks form a linear sequence in time, and that is where the word \"blockchain\" derives from.\nBlocks are added to the chain at regular intervals, although these intervals may be subject to change in the future.\nFor the most up-to-date information, it is recommended to monitor the network, for example, on `Etherscan <https://etherscan.io/chart/blocktime>`_.\n\nAs part of the \"order selection mechanism\", which is called `attestation <https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/attestations/>`_, it may happen that\nblocks are reverted from time to time, but only at the \"tip\" of the chain. The more\nblocks are added on top of a particular block, the less likely this block will be reverted. So it might be that your transactions\nare reverted and even removed from the blockchain, but the longer you wait, the less\nlikely it will be.\n\n.. note::\n    Transactions are not guaranteed to be included in the next block or any specific future block,\n    since it is not up to the submitter of a transaction, but up to the miners to determine in which block the transaction is included.\n\n    If you want to schedule future calls of your contract, you can use\n    a smart contract automation tool or an oracle service.\n\n.. _the-ethereum-virtual-machine:\n\n.. index:: !evm, ! ethereum virtual machine\n\n****************************\nThe Ethereum Virtual Machine\n****************************\n\nOverview\n========\n\nThe Ethereum Virtual Machine or EVM is the runtime environment\nfor smart contracts in Ethereum. It is not only sandboxed but\nactually completely isolated, which means that code running\ninside the EVM has no access to network, filesystem or other processes.\nSmart contracts even have limited access to other smart contracts.\n\n.. index:: ! account, address, storage, balance\n\n.. _accounts:\n\nAccounts\n========\n\nThere are two kinds of accounts in Ethereum which share the same\naddress space: **Externally-owned accounts** that are controlled by\npublic-private key pairs (i.e. humans) and **contract accounts** which are\ncontrolled by the code stored together with the account.\n\nThe address of an externally-owned account is determined from\nthe public key while the address of a contract is\ndetermined at the time the contract is created\n(it is derived from the creator address and the number\nof transactions sent from that address, the so-called \"nonce\").\n\nRegardless of whether or not the account stores code, the two types are\ntreated equally by the EVM.\n\nEvery account has a persistent key-value store mapping 256-bit words to 256-bit\nwords called **storage**.\n\nFurthermore, every account has a **balance** in\nEther (in \"Wei\" to be exact, ``1 ether`` is ``10**18 wei``) which can be modified by sending transactions that\ninclude Ether.\n\n.. index:: ! transaction\n\nTransactions\n============\n\nA transaction is a message that is sent from one account to another\naccount (which might be the same or empty, see below).\nIt can include binary data (which is called \"payload\") and Ether.\n\nIf the target account contains code, that code is executed and\nthe payload is provided as input data.\n\nIf the target account is not set (the transaction does not have\na recipient or the recipient is set to ``null``), the transaction\ncreates a **new contract**.\nAs already mentioned, the address of that contract is not\nthe zero address but an address derived from the sender and\nits number of transactions sent (the \"nonce\"). The payload\nof such a contract creation transaction is taken to be\nEVM bytecode and executed. The output data of this execution is\npermanently stored as the code of the contract.\nThis means that in order to create a contract, you do not\nsend the actual code of the contract, but in fact code that\nreturns that code when executed.\n\n.. note::\n  While a contract is being created, its code is still empty.\n  Because of that, you should not call back into the\n  contract under construction until its constructor has\n  finished executing.\n\n.. index:: ! gas, ! gas price\n\nGas\n===\n\nUpon creation, each transaction is charged with a certain amount of **gas**\nthat has to be paid for by the originator of the transaction (``tx.origin``).\nWhile the EVM executes the\ntransaction, the gas is gradually depleted according to specific rules.\nIf the gas is used up at any point (i.e. it would be negative),\nan out-of-gas exception is triggered, which ends execution and reverts all modifications\nmade to the state in the current call frame.\n\nThis mechanism incentivizes economical use of EVM execution time\nand also compensates EVM executors (i.e. miners / stakers) for their work.\nSince each block has a maximum amount of gas, it also limits the amount\nof work needed to validate a block.\n\nThe **gas price** is a value set by the originator of the transaction, who\nhas to pay ``gas_price * gas`` up front to the EVM executor.\nIf some gas is left after execution, it is refunded to the transaction originator.\nIn case of an exception that reverts changes, already used up gas is not refunded.\n\nSince EVM executors can choose to include a transaction or not,\ntransaction senders cannot abuse the system by setting a low gas price.\n\n.. index:: ! storage, ! memory, ! stack, ! transient storage\n\n.. _locations:\n\nStorage, Transient Storage, Memory and the Stack\n================================================\n\nThe Ethereum Virtual Machine has different areas where it can store data with the most\nprominent being storage, transient storage, memory and the stack.\n\nEach account has a data area called **storage**, which is persistent between function calls\nand transactions.\nStorage is a key-value store that maps 256-bit words to 256-bit words.\nIt is not possible to enumerate storage from within a contract, it is\ncomparatively costly to read, and even more to initialise and modify storage. Because of this cost,\nyou should minimize what you store in persistent storage to what the contract needs to run.\nStore data like derived calculations, caching, and aggregates outside of the contract.\nA contract can neither read nor write to any storage apart from its own.\n\nSimilar to storage, there is another data area called **transient storage**,\nwhere the main difference is that it is reset at the end of each transaction.\nThe values stored in this data location persist only across function calls originating\nfrom the first call of the transaction.\nWhen the transaction ends, the transient storage is reset and the values stored there\nbecome unavailable to calls in subsequent transactions.\nDespite this, the cost of reading and writing to transient storage is significantly lower than for storage.\n\nThe third data area is called **memory**, of which a contract obtains\na freshly cleared instance for each message call. Memory is linear and can be\naddressed at byte level, but reads are limited to a width of 256 bits, while writes\ncan be either 8 bits or 256 bits wide. Memory is expanded by a word (256-bit), when\naccessing (either reading or writing) a previously untouched memory word (i.e. any offset\nwithin a word). At the time of expansion, the cost in gas must be paid. Memory is more\ncostly the larger it grows (it scales quadratically).\n\nThe EVM is not a register machine but a stack machine, so all\ncomputations are performed on a data area called the **stack**. It has a maximum size of\n1024 elements and contains words of 256 bits. Access to the stack is\nlimited to the top end in the following way:\nIt is possible to copy one of\nthe topmost 16 elements to the top of the stack or swap the\ntopmost element with one of the 16 elements below it.\nAll other operations take the topmost two (or one, or more, depending on\nthe operation) elements from the stack and push the result onto the stack.\nOf course it is possible to move stack elements to storage or memory\nin order to get deeper access to the stack,\nbut it is not possible to just access arbitrary elements deeper in the stack\nwithout first removing the top of the stack.\n\nCalldata, Returndata and Code\n=============================\n\nThere are also other data areas which are not as apparent as those discussed previously.\nHowever, they are routinely used during the execution of smart contract transactions.\n\nThe calldata region is the data sent to a transaction as part of a smart contract transaction.\nFor example, when creating a contract, calldata would be the constructor code of the new contract.\nThe parameters of external functions are always initially stored in calldata in an ABI-encoded form\nand only then decoded into the location specified in their declaration.\nIf declared as ``memory``, the compiler will eagerly decode them into memory at the beginning of the function,\nwhile marking them as ``calldata`` means that this will be done lazily, only when accessed.\nValue types and ``storage`` pointers are decoded directly onto the stack.\n\nThe returndata is the way a smart contract can return a value after a call.\nIn general, external Solidity functions use the ``return`` keyword to ABI-encode values into the returndata area.\n\nThe code is the region where the EVM instructions of a smart contract are stored.\nCode is the bytes read, interpreted, and executed by the EVM during smart contract execution.\nInstruction data stored in the code is persistent as part of a contract account state field.\nImmutable and constant variables are stored in the code region.\nAll references to immutables are replaced with the values assigned to them.\nA similar process is performed for constants which have their expressions inlined\nin the places where they are referenced in the smart contract code.\n\n.. index:: ! instruction\n\nInstruction Set\n===============\n\nThe instruction set of the EVM is kept minimal in order to avoid\nincorrect or inconsistent implementations which could cause consensus problems.\nAll instructions operate on the basic data type, 256-bit words or on slices of memory\n(or other byte arrays).\nThe usual arithmetic, bit, logical and comparison operations are present.\nConditional and unconditional jumps are possible. Furthermore,\ncontracts can access relevant properties of the current block\nlike its number and timestamp.\n\nFor a complete list, please see the :ref:`list of opcodes <opcodes>` as part of the inline\nassembly documentation.\n\n.. index:: ! message call, function;call\n\nMessage Calls\n=============\n\nContracts can call other contracts or send Ether to non-contract\naccounts by the means of message calls. Message calls are similar\nto transactions, in that they have a source, a target, data payload,\nEther, gas and return data. In fact, every transaction consists of\na top-level message call which in turn can create further message calls.\n\nA contract can decide how much of its remaining **gas** should be sent\nwith the inner message call and how much it wants to retain.\nIf an out-of-gas exception happens in the inner call (or any\nother exception), this will be signaled by an error value put onto the stack.\nIn this case, only the gas sent together with the call is used up.\nIn Solidity, the calling contract causes a manual exception by default in\nsuch situations, so that exceptions \"bubble up\" the call stack.\n\nAs already said, the called contract (which can be the same as the caller)\nwill receive a freshly cleared instance of memory and has access to the\ncall payload - which will be provided in a separate area called the **calldata**.\nAfter it has finished execution, it can return data which will be stored at\na location in the caller's memory preallocated by the caller.\nAll such calls are fully synchronous.\n\nCalls are **limited** to a depth of 1024, which means that for more complex\noperations, loops should be preferred over recursive calls. Furthermore,\nonly 63/64th of the gas can be forwarded in a message call, which causes a\ndepth limit of a little less than 1000 in practice.\n\n.. _delegatecall:\n.. index:: delegatecall, library\n\nDelegatecall and Libraries\n==========================\n\nThere exists a special variant of a message call, named **delegatecall**\nwhich is identical to a message call apart from the fact that\nthe code at the target address is executed in the context (i.e. at the address) of the calling\ncontract and ``msg.sender`` and ``msg.value`` do not change their values.\n\nThis means that a contract can dynamically load code from a different\naddress at runtime. Storage, current address and balance still\nrefer to the calling contract, only the code is taken from the called address.\n\nThis makes it possible to implement the \"library\" feature in Solidity:\nReusable library code that can be applied to a contract's storage, e.g. in\norder to implement a complex data structure.\n\n.. index:: log\n\nLogs\n====\n\nIt is possible to store data in a specially indexed data structure\nthat maps all the way up to the block level. This feature called **logs**\nis used by Solidity in order to implement :ref:`events <events>`.\nContracts cannot access log data after it has been created, but they\ncan be efficiently accessed from outside the blockchain.\nSince some part of the log data is stored in `bloom filters <https://en.wikipedia.org/wiki/Bloom_filter>`_, it is\npossible to search for this data in an efficient and cryptographically\nsecure way, so network peers that do not download the whole blockchain\n(so-called \"light clients\") can still find these logs.\n\n.. index:: contract creation\n\nCreate\n======\n\nContracts can even create other contracts using a special opcode (i.e.\nthey do not simply call the zero address as a transaction would). The only difference between\nthese **create calls** and normal message calls is that the payload data is\nexecuted and the result stored as code and the caller / creator\nreceives the address of the new contract on the stack.\n\n.. index:: ! selfdestruct, deactivate\n\nDeactivate and Self-destruct\n============================\n\nThe only way to remove code from the blockchain is when a contract at that\naddress performs the ``selfdestruct`` operation. The remaining Ether stored\nat that address is sent to a designated target and then the storage and code\nis removed from the state. Removing the contract in theory sounds like a good\nidea, but it is potentially dangerous, as if someone sends Ether to removed\ncontracts, the Ether is forever lost.\n\n.. warning::\n    From ``EVM >= Cancun`` onwards, ``selfdestruct`` will **only** send all Ether in the account to the given recipient and not destroy the contract.\n    However, when ``selfdestruct`` is called in the same transaction that creates the contract calling it,\n    the behaviour of ``selfdestruct`` before Cancun hardfork (i.e., ``EVM <= Shanghai``) is preserved and will destroy the current contract,\n    deleting any data, including storage keys, code and the account itself.\n    See `EIP-6780 <https://eips.ethereum.org/EIPS/eip-6780>`_ for more details.\n\n    The new behaviour is the result of a network-wide change that affects all contracts present on\n    the Ethereum mainnet and testnets.\n    It is important to note that this change is dependent on the EVM version of the chain on which\n    the contract is deployed.\n    The ``--evm-version`` setting used when compiling the contract has no bearing on it.\n\n    Also, note that the ``selfdestruct`` opcode has been deprecated in Solidity version 0.8.18,\n    as recommended by `EIP-6049 <https://eips.ethereum.org/EIPS/eip-6049>`_.\n    The deprecation is still in effect and the compiler will still emit warnings on its use.\n    Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account.\n    Future changes to the EVM might further reduce the functionality of the opcode.\n\n.. warning::\n    Even if a contract is removed by ``selfdestruct``, it is still part of the\n    history of the blockchain and probably retained by most Ethereum nodes.\n    So using ``selfdestruct`` is not the same as deleting data from a hard disk.\n\n.. note::\n    Even if a contract's code does not contain a call to ``selfdestruct``,\n    it can still perform that operation using ``delegatecall`` or ``callcode``.\n\nIf you want to deactivate your contracts, you should instead **disable** them\nby changing some internal state which causes all functions to revert. This\nmakes it impossible to use the contract, as it returns Ether immediately.\n\n\n.. index:: ! precompiled contracts, ! precompiles, ! contract;precompiled\n\n.. _precompiledContracts:\n\nPrecompiled Contracts\n=====================\n\nThere is a small set of contract addresses that are special:\nThe address range between ``1`` and (including) ``0x0a`` contains\n\"precompiled contracts\" that can be called as any other contract\nbut their behavior (and their gas consumption) is not defined\nby EVM code stored at that address (they do not contain code)\nbut instead is implemented in the EVM execution environment itself.\n\nDifferent EVM-compatible chains might use a different set of\nprecompiled contracts. It might also be possible that new\nprecompiled contracts are added to the Ethereum main chain in the future,\nbut you can reasonably expect them to always be in the range between\n``1`` and ``0xffff`` (inclusive).\n"
  },
  {
    "path": "docs/ir-breaking-changes.rst",
    "content": "\n.. index: ir breaking changes\n\n.. _ir-breaking-changes:\n\n*********************************\nSolidity IR-based Codegen Changes\n*********************************\n\nSolidity can generate EVM bytecode in two different ways:\nEither directly from Solidity to EVM opcodes (\"old codegen\") or through\nan intermediate representation (\"IR\") in Yul (\"new codegen\" or \"IR-based codegen\").\n\nThe IR-based code generator was introduced with an aim to not only allow\ncode generation to be more transparent and auditable but also\nto enable more powerful optimization passes that span across functions.\n\nYou can enable it on the command-line using ``--via-ir``\nor with the option ``{\"viaIR\": true}`` in standard-json and we\nencourage everyone to try it out!\n\nFor several reasons, there are tiny semantic differences between the old\nand the IR-based code generator, mostly in areas where we would not\nexpect people to rely on this behavior anyway.\nThis section highlights the main differences between the old and the IR-based codegen.\n\nSemantic Only Changes\n=====================\n\nThis section lists the changes that are semantic-only, thus potentially\nhiding new and different behavior in existing code.\n\n.. _state-variable-initialization-order:\n\n- The order of state variable initialization has changed in case of inheritance.\n\n  The order used to be:\n\n  - All state variables are zero-initialized at the beginning.\n  - Evaluate base constructor arguments from most derived to most base contract.\n  - Initialize all state variables in the whole inheritance hierarchy from most base to most derived.\n  - Run the constructor, if present, for all contracts in the linearized hierarchy from most base to most derived.\n\n  New order:\n\n  - All state variables are zero-initialized at the beginning.\n  - Evaluate base constructor arguments from most derived to most base contract.\n  - For every contract in order from most base to most derived in the linearized hierarchy:\n\n      1. Initialize state variables.\n      2. Run the constructor (if present).\n\n  This causes differences in contracts where the initial value of a state\n  variable relies on the result of the constructor in another contract:\n\n  .. code-block:: solidity\n\n      // SPDX-License-Identifier: GPL-3.0\n      pragma solidity >=0.7.1;\n\n      contract A {\n          uint x;\n          constructor() {\n              x = 42;\n          }\n          function f() public view returns(uint256) {\n              return x;\n          }\n      }\n      contract B is A {\n          uint public y = f();\n      }\n\n  Previously, ``y`` would be set to 0. This is due to the fact that we would first initialize state variables: First, ``x`` is set to 0, and when initializing ``y``, ``f()`` would return 0 causing ``y`` to be 0 as well.\n  With the new rules, ``y`` will be set to 42. We first initialize ``x`` to 0, then call A's constructor which sets ``x`` to 42. Finally, when initializing ``y``, ``f()`` returns 42 causing ``y`` to be 42.\n\n- When storage structs are deleted, every storage slot that contains\n  a member of the struct is set to zero entirely. Formerly, padding space\n  was left untouched.\n  Consequently, if the padding space within a struct is used to store data\n  (e.g. in the context of a contract upgrade), you have to be aware that\n  ``delete`` will now also clear the added member (while it wouldn't\n  have been cleared in the past).\n\n  .. code-block:: solidity\n\n      // SPDX-License-Identifier: GPL-3.0\n      pragma solidity >=0.7.1;\n\n      contract C {\n          struct S {\n              uint64 y;\n              uint64 z;\n          }\n          S s;\n          function f() public {\n              // ...\n              delete s;\n              // s occupies only first 16 bytes of the 32 bytes slot\n              // delete will write zero to the full slot\n          }\n      }\n\n  We have the same behavior for implicit delete, for example when array of structs is shortened.\n\n- Function modifiers are implemented in a slightly different way regarding function parameters and return variables.\n  This especially has an effect if the placeholder ``_;`` is evaluated multiple times in a modifier.\n  In the old code generator, each function parameter and return variable has a fixed slot on the stack.\n  If the function is run multiple times because ``_;`` is used multiple times or used in a loop, then a\n  change to the function parameter's or return variable's value is visible in the next execution of the function.\n  The new code generator implements modifiers using actual functions and passes function parameters on.\n  This means that multiple evaluations of a function's body will get the same values for the parameters,\n  and the effect on return variables is that they are reset to their default (zero) value for each\n  execution.\n\n  .. code-block:: solidity\n\n      // SPDX-License-Identifier: GPL-3.0\n      pragma solidity >=0.7.0;\n      contract C {\n          function f(uint a) public pure mod() returns (uint r) {\n              r = a++;\n          }\n          modifier mod() { _; _; }\n      }\n\n  If you execute ``f(0)`` in the old code generator, it will return ``1``, while\n  it will return ``0`` when using the new code generator.\n\n  .. code-block:: solidity\n\n      // SPDX-License-Identifier: GPL-3.0\n      pragma solidity >=0.7.1 <0.9.0;\n\n      contract C {\n          bool active = true;\n          modifier mod()\n          {\n              _;\n              active = false;\n              _;\n          }\n          function foo() external mod() returns (uint ret)\n          {\n              if (active)\n                  ret = 1; // Same as ``return 1``\n          }\n      }\n\n  The function ``C.foo()`` returns the following values:\n\n  - Old code generator: ``1`` as the return variable is initialized to ``0`` only once before the first ``_;``\n    evaluation and then overwritten by the ``return 1;``. It is not initialized again for the second ``_;``\n    evaluation and ``foo()`` does not explicitly assign it either (due to ``active == false``), thus it keeps\n    its first value.\n  - New code generator: ``0`` as all parameters, including return parameters, will be re-initialized before\n    each ``_;`` evaluation.\n\n  .. index:: ! evaluation order; expression\n\n- For the old code generator, the evaluation order of expressions is unspecified.\n  For the new code generator, we try to evaluate in source order (left to right), but do not guarantee it.\n  This can lead to semantic differences.\n\n  For example:\n\n  .. code-block:: solidity\n\n      // SPDX-License-Identifier: GPL-3.0\n      pragma solidity >=0.8.1;\n      contract C {\n          function preincr_u8(uint8 a) public pure returns (uint8) {\n              return ++a + a;\n          }\n      }\n\n  The function ``preincr_u8(1)`` returns the following values:\n\n  - Old code generator: ``3`` (``1 + 2``) but the return value is unspecified in general\n  - New code generator: ``4`` (``2 + 2``) but the return value is not guaranteed\n\n  .. index:: ! evaluation order; function arguments\n\n  On the other hand, function argument expressions are evaluated in the same order\n  by both code generators with the exception of the global functions ``addmod`` and ``mulmod``.\n  For example:\n\n  .. code-block:: solidity\n\n      // SPDX-License-Identifier: GPL-3.0\n      pragma solidity >=0.8.1;\n      contract C {\n          function add(uint8 a, uint8 b) public pure returns (uint8) {\n              return a + b;\n          }\n          function g(uint8 a, uint8 b) public pure returns (uint8) {\n              return add(++a + ++b, a + b);\n          }\n      }\n\n  The function ``g(1, 2)`` returns the following values:\n\n  - Old code generator: ``10`` (``add(2 + 3, 2 + 3)``) but the return value is unspecified in general\n  - New code generator: ``10`` but the return value is not guaranteed\n\n  The arguments to the global functions ``addmod`` and ``mulmod`` are evaluated right-to-left by the old code generator\n  and left-to-right by the new code generator.\n  For example:\n\n  .. code-block:: solidity\n\n      // SPDX-License-Identifier: GPL-3.0\n      pragma solidity >=0.8.1;\n      contract C {\n          function f() public pure returns (uint256 aMod, uint256 mMod) {\n              uint256 x = 3;\n              // Old code gen: add/mulmod(5, 4, 3)\n              // New code gen: add/mulmod(4, 5, 5)\n              aMod = addmod(++x, ++x, x);\n              mMod = mulmod(++x, ++x, x);\n          }\n      }\n\n  The function ``f()`` returns the following values:\n\n  - Old code generator: ``aMod = 0`` and ``mMod = 2``\n  - New code generator: ``aMod = 4`` and ``mMod = 0``\n\n- The new code generator imposes a hard limit of ``type(uint64).max``\n  (``0xffffffffffffffff``) for the free memory pointer. Allocations that would\n  increase its value beyond this limit revert. The old code generator does not\n  have this limit.\n\n  For example:\n\n  .. code-block:: solidity\n      :force:\n\n      // SPDX-License-Identifier: GPL-3.0\n      pragma solidity >0.8.0;\n      contract C {\n          function f() public {\n              uint[] memory arr;\n              // allocation size: 576460752303423481\n              // assumes freeMemPtr points to 0x80 initially\n              uint solYulMaxAllocationBeforeMemPtrOverflow = (type(uint64).max - 0x80 - 31) / 32;\n              // freeMemPtr overflows UINT64_MAX\n              arr = new uint[](solYulMaxAllocationBeforeMemPtrOverflow);\n          }\n      }\n\n  The function ``f()`` behaves as follows:\n\n  - Old code generator: runs out of gas while zeroing the array contents after the large memory allocation\n  - New code generator: reverts due to free memory pointer overflow (does not run out of gas)\n\n\nInternals\n=========\n\n.. _internal-function-pointers-in-ir:\n\nInternal function pointers\n--------------------------\n\n.. index:: function pointers\n\nThe old code generator uses code offsets or tags for values of internal function pointers. This is especially complicated since\nthese offsets are different at construction time and after deployment and the values can cross this border via storage.\nBecause of that, both offsets are encoded at construction time into the same value (into different bytes).\n\nIn the new code generator, function pointers use internal IDs that are allocated in sequence. Since calls via jumps are not possible,\ncalls through function pointers always have to use an internal dispatch function that uses the ``switch`` statement to select\nthe right function.\n\nThe ID ``0`` is reserved for uninitialized function pointers which then cause a panic in the dispatch function when called.\n\nIn the old code generator, internal function pointers are initialized with a special function that always causes a panic.\nThis causes a storage write at construction time for internal function pointers in storage.\n\n.. note::\n    The compiler is free to omit internal functions that are never explicitly referenced by name.\n    As a consequence, assigning to a function type variable in inline assembly does not guarantee\n    that the assigned value will be included in the internal dispatch.\n    The function must also be explicitly referenced elsewhere in the code.\n\nCleanup\n-------\n\n.. index:: cleanup, dirty bits\n\nThe old code generator only performs cleanup before an operation whose result could be affected by the values of the dirty bits.\nThe new code generator performs cleanup after any operation that can result in dirty bits.\nThe hope is that the optimizer will be powerful enough to eliminate redundant cleanup operations.\n\nFor example:\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.1;\n    contract C {\n        function f(uint8 a) public pure returns (uint r1, uint r2)\n        {\n            a = ~a;\n            assembly {\n                r1 := a\n            }\n            r2 = a;\n        }\n    }\n\nThe function ``f(1)`` returns the following values:\n\n- Old code generator: (``fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe``, ``00000000000000000000000000000000000000000000000000000000000000fe``)\n- New code generator: (``00000000000000000000000000000000000000000000000000000000000000fe``, ``00000000000000000000000000000000000000000000000000000000000000fe``)\n\nNote that, unlike the new code generator, the old code generator does not perform a cleanup after the bit-not assignment (``a = ~a``).\nThis results in different values being assigned (within the inline assembly block) to return value ``r1`` between the old and new code generators.\nHowever, both code generators perform a cleanup before the new value of ``a`` is assigned to ``r2``.\n"
  },
  {
    "path": "docs/language-influences.rst",
    "content": "###################\nLanguage Influences\n###################\n\nSolidity is a `curly-bracket language <https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Curly_bracket_languages>`_\nthat has been influenced and inspired by several well-known programming languages.\n\nSolidity is most profoundly influenced by C++, but also borrowed concepts from languages like\nPython, JavaScript, and others.\n\nThe influence from C++ can be seen in the syntax for variable declarations, for loops, the concept\nof overloading functions, implicit and explicit type conversions and many other details.\n\nIn the early days of the language, Solidity used to be partly influenced by JavaScript.\nThis was due to function-level scoping of variables and the use of the keyword ``var``.\nThe JavaScript influence was reduced starting from version 0.4.0.\nNow, the main remaining similarity to JavaScript is that functions are defined using the keyword\n``function``. Solidity also supports import syntax and semantics that\nare similar to those available in JavaScript. Besides those points, Solidity looks like\nmost other curly-bracket languages and has no major JavaScript influence anymore.\n\nAnother influence to Solidity was Python. Solidity's modifiers were added trying to model\nPython's decorators with a much more restricted functionality. Furthermore, multiple inheritance, C3 linearization,\nand the ``super`` keyword are taken from Python as well as the general assignment and copy semantics of value\nand reference types.\n"
  },
  {
    "path": "docs/layout-of-source-files.rst",
    "content": "********************************\nLayout of a Solidity Source File\n********************************\n\nSource files can contain an arbitrary number of\n:ref:`contract definitions<contract_structure>`, import_ ,\n:ref:`pragma<pragma>` and :ref:`using for<using-for>` directives and\n:ref:`struct<structs>`, :ref:`enum<enums>`, :ref:`function<functions>`, :ref:`error<errors>`\nand :ref:`constant variable<constants>` definitions.\n\n.. index:: ! license, spdx\n\nSPDX License Identifier\n=======================\n\nTrust in smart contracts can be better established if their source code\nis available. Since making source code available always touches on legal problems\nwith regards to copyright, the Solidity compiler encourages the use\nof machine-readable `SPDX license identifiers <https://spdx.org>`_.\nEvery source file should start with a comment indicating its license:\n\n``// SPDX-License-Identifier: MIT``\n\nThe compiler does not validate that the license is part of the\n`list allowed by SPDX <https://spdx.org/licenses/>`_, but\nit does include the supplied string in the :ref:`bytecode metadata <metadata>`.\n\nIf you do not want to specify a license or if the source code is\nnot open-source, please use the special value ``UNLICENSED``.\nNote that ``UNLICENSED`` (no usage allowed, not present in SPDX license list)\nis different from ``UNLICENSE`` (grants all rights to everyone).\nSolidity follows `the npm recommendation <https://docs.npmjs.com/cli/v7/configuring-npm/package-json#license>`_.\n\nSupplying this comment of course does not free you from other\nobligations related to licensing like having to mention\na specific license header in each source file or the\noriginal copyright holder.\n\nThe comment is recognized by the compiler anywhere in the file at the\nfile level, but it is recommended to put it at the top of the file.\n\nMore information about how to use SPDX license identifiers\ncan be found at the `SPDX website <https://spdx.dev/learn/handling-license-info/#how>`_.\n\n\n.. index:: ! pragma\n\n.. _pragma:\n\nPragmas\n=======\n\nThe ``pragma`` keyword is used to enable certain compiler features\nor checks. A pragma directive is always local to a source file, so\nyou have to add the pragma to all your files if you want to enable it\nin your whole project. If you :ref:`import<import>` another file, the pragma\nfrom that file does *not* automatically apply to the importing file.\n\n.. index:: ! pragma;version\n\n.. _version_pragma:\n\nVersion Pragma\n--------------\n\nSource files can (and should) be annotated with a version pragma to reject\ncompilation with future compiler versions that might introduce incompatible\nchanges. We try to keep these to an absolute minimum and\nintroduce them in a way that changes in semantics also require changes\nin the syntax, but this is not always possible. Because of this, it is always\na good idea to read through the changelog at least for releases that contain\nbreaking changes. These releases always have versions of the form\n``0.x.0`` or ``x.0.0``.\n\nThe version pragma is used as follows: ``pragma solidity ^0.5.2;``\n\nA source file with the line above does not compile with a compiler earlier than version 0.5.2,\nand it also does not work on a compiler starting from version 0.6.0 (this\nsecond condition is added by using ``^``). Because\nthere will be no breaking changes until version ``0.6.0``, you can\nbe sure that your code compiles the way you intended. The exact version of the\ncompiler is not fixed, so that bugfix releases are still possible.\n\nIt is possible to specify more complex rules for the compiler version,\nthese follow the same syntax used by `npm <https://docs.npmjs.com/cli/v6/using-npm/semver>`_.\n\n.. note::\n  Using the version pragma *does not* change the version of the compiler.\n  It also *does not* enable or disable features of the compiler. It just\n  instructs the compiler to check whether its version matches the one\n  required by the pragma. If it does not match, the compiler issues\n  an error.\n\n.. index:: ! ABI coder, ! pragma; abicoder, pragma; ABIEncoderV2\n.. _abi_coder:\n\nABI Coder Pragma\n----------------\n\nBy using ``pragma abicoder v1`` or ``pragma abicoder v2`` you can\nselect between the two implementations of the ABI encoder and decoder.\n\nThe new ABI coder (v2) is able to encode and decode arbitrarily nested\narrays and structs. Apart from supporting more types, it involves more extensive\nvalidation and safety checks, which may result in higher gas costs, but also heightened\nsecurity.\nIt is considered non-experimental as of Solidity 0.6.0 and it is enabled by default starting\nwith Solidity 0.8.0. The old ABI coder can still be selected using ``pragma abicoder v1;``.\n\n.. warning::\n  The ABI coder v1 is deprecated and scheduled for removal.\n  Use ABI coder v2 instead.\n\nThe set of types supported by the new encoder is a strict superset of\nthe ones supported by the old one. Contracts that use it can interact with ones\nthat do not without limitations. The reverse is possible only as long as the\nnon-``abicoder v2`` contract does not try to make calls that would require\ndecoding types only supported by the new encoder. The compiler can detect this\nand will issue an error. Simply enabling ``abicoder v2`` for your contract is\nenough to make the error go away.\n\n.. note::\n  This pragma applies to all the code defined in the file where it is activated,\n  regardless of where that code ends up eventually. This means that a contract\n  whose source file is selected to compile with ABI coder v1\n  can still contain code that uses the new encoder\n  by inheriting it from another contract. This is allowed if the new types are only\n  used internally and not in external function signatures.\n\n.. note::\n  Up to Solidity 0.7.4, it was possible to select the ABI coder v2\n  by using ``pragma experimental ABIEncoderV2``, but it was not possible\n  to explicitly select coder v1 because it was the default.\n\n.. index:: ! pragma; experimental\n.. _experimental_pragma:\n\nExperimental Pragma\n-------------------\n\nThe second pragma is the experimental pragma. It can be used to enable\nfeatures of the compiler or language that are not yet enabled by default.\nThe following experimental pragmas are currently supported:\n\n.. index:: ! pragma; ABIEncoderV2\n\nABIEncoderV2\n~~~~~~~~~~~~\n\nBecause the ABI coder v2 is not considered experimental anymore,\nit can be selected via ``pragma abicoder v2`` (please see above)\nsince Solidity 0.7.4.\n\n.. index:: ! pragma; SMTChecker\n.. _smt_checker:\n\nSMTChecker\n~~~~~~~~~~\n\nIf you use ``pragma experimental SMTChecker;``, then you get additional\n:ref:`safety warnings<formal_verification>` which are obtained by querying an\nSMT solver.\nThe component does not yet support all features of the Solidity language and\nlikely outputs many warnings. In case it reports unsupported features, the\nanalysis may not be fully sound.\n\n.. note::\n\n    The ``SMTChecker`` pragma is deprecated and will be removed.\n    To enable SMTChecker, simply select :ref:`select an engine<smtchecker_engines>` when invoking the compiler.\n\n.. index:: source file, ! import, module, source unit\n\n.. _import:\n\nImporting other Source Files\n============================\n\nSyntax and Semantics\n--------------------\n\nSolidity supports import statements to help modularise your code that\nare similar to those available in JavaScript\n(from ES6 on). However, Solidity does not support the concept of\na `default export <https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export#description>`_.\n\nAt a global level, you can use import statements of the following form:\n\n.. code-block:: solidity\n\n    import \"filename\";\n\nThe ``filename`` part is called an *import path*.\nThis statement imports all global symbols from \"filename\" (and symbols imported there) into the\ncurrent global scope (different than in ES6 but backwards-compatible for Solidity).\nThis form is not recommended for use, because it unpredictably pollutes the namespace.\nIf you add new top-level items inside \"filename\", they automatically\nappear in all files that import like this from \"filename\". It is better to import specific\nsymbols explicitly.\n\nThe following example creates a new global symbol ``symbolName`` whose members are all\nthe global symbols from ``\"filename\"``:\n\n.. code-block:: solidity\n\n    import * as symbolName from \"filename\";\n\nwhich results in all global symbols being available in the format ``symbolName.symbol``.\n\nA variant of this syntax that is not part of ES6, but possibly useful is:\n\n.. code-block:: solidity\n\n  import \"filename\" as symbolName;\n\nwhich is equivalent to ``import * as symbolName from \"filename\";``.\n\nIf there is a naming collision, you can rename symbols while importing. For example,\nthe code below creates new global symbols ``alias`` and ``symbol2`` which reference\n``symbol1`` and ``symbol2`` from inside ``\"filename\"``, respectively.\n\n.. code-block:: solidity\n\n    import {symbol1 as alias, symbol2} from \"filename\";\n\n.. index:: virtual filesystem, source unit name, import; path, filesystem path, import callback, Remix IDE\n\nImport Paths\n------------\n\nIn order to be able to support reproducible builds on all platforms, the Solidity compiler has to\nabstract away the details of the filesystem where source files are stored.\nFor this reason import paths do not refer directly to files in the host filesystem.\nInstead the compiler maintains an internal database (*virtual filesystem* or *VFS* for short) where\neach source unit is assigned a unique *source unit name* which is an opaque and unstructured identifier.\nThe import path specified in an import statement is translated into a source unit name and used to\nfind the corresponding source unit in this database.\n\nUsing the :ref:`Standard JSON <compiler-api>` API it is possible to directly provide the names and\ncontent of all the source files as a part of the compiler input.\nIn this case source unit names are truly arbitrary.\nIf, however, you want the compiler to automatically find and load source code into the VFS, your\nsource unit names need to be structured in a way that makes it possible for an :ref:`import callback\n<import-callback>` to locate them.\nWhen using the command-line compiler the default import callback supports only loading source code\nfrom the host filesystem, which means that your source unit names must be paths.\nSome environments provide custom callbacks that are more versatile.\nFor example the `Remix IDE <https://remix.ethereum.org/>`_ provides one that\nlets you `import files from HTTP, IPFS and Swarm URLs or refer directly to packages in NPM registry\n<https://remix-ide.readthedocs.io/en/latest/import.html>`_.\n\nFor a complete description of the virtual filesystem and the path resolution logic used by the\ncompiler see :ref:`Path Resolution <path-resolution>`.\n\n.. index:: ! comment, natspec\n\nComments\n========\n\nSingle-line comments (``//``) and multi-line comments (``/*...*/``) are possible.\n\n.. code-block:: solidity\n\n    // This is a single-line comment.\n\n    /*\n    This is a\n    multi-line comment.\n    */\n\n.. note::\n  A single-line comment is terminated by any unicode line terminator\n  (LF, VF, FF, CR, NEL, LS or PS) in UTF-8 encoding. The terminator is still part of\n  the source code after the comment, so if it is not an ASCII symbol\n  (these are NEL, LS and PS), it will lead to a parser error.\n\nAdditionally, there is another type of comment called a NatSpec comment,\nwhich is detailed in the :ref:`style guide<style_guide_natspec>`. They are written with a\ntriple slash (``///``) or a double asterisk block (``/** ... */``) and\nthey should be used directly above function declarations or statements.\n"
  },
  {
    "path": "docs/make.bat",
    "content": "@ECHO OFF\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-build\n)\nset BUILDDIR=_build\nset ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .\nset I18NSPHINXOPTS=%SPHINXOPTS% .\nif NOT \"%PAPER%\" == \"\" (\n\tset ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%\n\tset I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%\n)\n\nif \"%1\" == \"\" goto help\n\nif \"%1\" == \"help\" (\n\t:help\n\techo.Please use `make ^<target^>` where ^<target^> is one of\n\techo.  html       to make standalone HTML files\n\techo.  dirhtml    to make HTML files named index.html in directories\n\techo.  singlehtml to make a single large HTML file\n\techo.  pickle     to make pickle files\n\techo.  json       to make JSON files\n\techo.  htmlhelp   to make HTML files and a HTML help project\n\techo.  qthelp     to make HTML files and a qthelp project\n\techo.  devhelp    to make HTML files and a Devhelp project\n\techo.  epub       to make an epub\n\techo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\n\techo.  latexpdf   to make LaTeX files and run them through pdflatex\n\techo.  text       to make text files\n\techo.  man        to make manual pages\n\techo.  texinfo    to make Texinfo files\n\techo.  gettext    to make PO message catalogs\n\techo.  changes    to make an overview over all changed/added/deprecated items\n\techo.  xml        to make Docutils-native XML files\n\techo.  pseudoxml  to make pseudoxml-XML files for display purposes\n\techo.  linkcheck  to check all external links for integrity\n\techo.  doctest    to run all doctests embedded in the documentation if enabled\n\tgoto end\n)\n\nif \"%1\" == \"clean\" (\n\tfor /d %%i in (%BUILDDIR%\\*) do rmdir /q /s %%i\n\tdel /q /s %BUILDDIR%\\*\n\tgoto end\n)\n\n\n%SPHINXBUILD% 2> nul\nif errorlevel 9009 (\n\techo.\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\n\techo.installed, then set the SPHINXBUILD environment variable to point\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\n\techo.may add the Sphinx directory to PATH.\n\techo.\n\techo.If you don't have Sphinx installed, grab it from\n\techo.http://sphinx-doc.org/\n\texit /b 1\n)\n\nif \"%1\" == \"html\" (\n\t%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/html.\n\tgoto end\n)\n\nif \"%1\" == \"dirhtml\" (\n\t%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.\n\tgoto end\n)\n\nif \"%1\" == \"singlehtml\" (\n\t%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.\n\tgoto end\n)\n\nif \"%1\" == \"pickle\" (\n\t%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can process the pickle files.\n\tgoto end\n)\n\nif \"%1\" == \"json\" (\n\t%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can process the JSON files.\n\tgoto end\n)\n\nif \"%1\" == \"htmlhelp\" (\n\t%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can run HTML Help Workshop with the ^\n.hhp project file in %BUILDDIR%/htmlhelp.\n\tgoto end\n)\n\nif \"%1\" == \"qthelp\" (\n\t%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can run \"qcollectiongenerator\" with the ^\n.qhcp project file in %BUILDDIR%/qthelp, like this:\n\techo.^> qcollectiongenerator %BUILDDIR%\\qthelp\\Solidity.qhcp\n\techo.To view the help file:\n\techo.^> assistant -collectionFile %BUILDDIR%\\qthelp\\Solidity.ghc\n\tgoto end\n)\n\nif \"%1\" == \"devhelp\" (\n\t%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished.\n\tgoto end\n)\n\nif \"%1\" == \"epub\" (\n\t%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The epub file is in %BUILDDIR%/epub.\n\tgoto end\n)\n\nif \"%1\" == \"latex\" (\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; the LaTeX files are in %BUILDDIR%/latex.\n\tgoto end\n)\n\nif \"%1\" == \"latexpdf\" (\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\n\tcd %BUILDDIR%/latex\n\tmake all-pdf\n\tcd %BUILDDIR%/..\n\techo.\n\techo.Build finished; the PDF files are in %BUILDDIR%/latex.\n\tgoto end\n)\n\nif \"%1\" == \"text\" (\n\t%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The text files are in %BUILDDIR%/text.\n\tgoto end\n)\n\nif \"%1\" == \"man\" (\n\t%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The manual pages are in %BUILDDIR%/man.\n\tgoto end\n)\n\nif \"%1\" == \"texinfo\" (\n\t%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.\n\tgoto end\n)\n\nif \"%1\" == \"gettext\" (\n\t%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The message catalogs are in %BUILDDIR%/locale.\n\tgoto end\n)\n\nif \"%1\" == \"changes\" (\n\t%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.The overview file is in %BUILDDIR%/changes.\n\tgoto end\n)\n\nif \"%1\" == \"linkcheck\" (\n\t%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Link check complete; look for any errors in the above output ^\nor in %BUILDDIR%/linkcheck/output.txt.\n\tgoto end\n)\n\nif \"%1\" == \"doctest\" (\n\t%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Testing of doctests in the sources finished, look at the ^\nresults in %BUILDDIR%/doctest/output.txt.\n\tgoto end\n)\n\nif \"%1\" == \"xml\" (\n\t%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The XML files are in %BUILDDIR%/xml.\n\tgoto end\n)\n\nif \"%1\" == \"pseudoxml\" (\n\t%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.\n\tgoto end\n)\n\n:end\n"
  },
  {
    "path": "docs/metadata.rst",
    "content": ".. _metadata:\n\n#################\nContract Metadata\n#################\n\n.. index:: metadata, contract verification\n\nThe Solidity compiler automatically generates a JSON file.\nThe file contains two kinds of information about the compiled contract:\n\n- How to interact with the contract: ABI, and NatSpec documentation.\n- How to reproduce the compilation and verify a deployed contract:\n  compiler version, compiler settings, and source files used.\n\nThe compiler appends by default the IPFS hash of the metadata file to the end\nof the runtime bytecode (not necessarily the creation bytecode) of each contract,\nso that, if published, you can retrieve the file in an authenticated way without\nhaving to resort to a centralized data provider. The other available options are\nthe Swarm hash and not appending the metadata hash to the bytecode. These can be\nconfigured via the :ref:`Standard JSON Interface<compiler-api>`.\n\nYou have to publish the metadata file to IPFS, Swarm, or another service so\nthat others can access it. You create the file by using the ``solc --metadata``\ncommand together with the ``--output-dir`` parameter. Without the parameter,\nthe metadata will be written to standard output.\nThe metadata contains IPFS and Swarm references to the source code, so you have to\nupload all source files in addition to the metadata file. For IPFS, the hash contained\nin the CID returned by ``ipfs add`` (not the direct sha2-256 hash of the file)\nshall match with the one contained in the bytecode.\n\nThe metadata file has the following format. The example below is presented in a\nhuman-readable way. Properly formatted metadata should use quotes correctly,\nreduce whitespace to a minimum, and sort the keys of all objects in alphabetical order\nto arrive at a canonical formatting. Comments are not permitted and are used here only for\nexplanatory purposes.\n\n.. code-block:: javascript\n\n    {\n      // Required: Details about the compiler, contents are specific\n      // to the language.\n      \"compiler\": {\n        // Optional: Hash of the compiler binary which produced this output\n        \"keccak256\": \"0x123...\",\n        // Required for Solidity: Version of the compiler\n        \"version\": \"0.8.2+commit.661d1103\"\n      },\n      // Required: Source code language, basically selects a \"sub-version\"\n      // of the specification\n      \"language\": \"Solidity\",\n      // Required: Generated information about the contract.\n      \"output\": {\n        // Required: ABI definition of the contract. See \"Contract ABI Specification\"\n        \"abi\": [/* ... */],\n        // Required: NatSpec developer documentation of the contract. See https://docs.soliditylang.org/en/latest/natspec-format.html for details.\n        \"devdoc\": {\n          // Contents of the @author NatSpec field of the contract\n          \"author\": \"John Doe\",\n          // Contents of the @dev NatSpec field of the contract\n          \"details\": \"Interface of the ERC20 standard as defined in the EIP. See https://eips.ethereum.org/EIPS/eip-20 for details\",\n          \"errors\": {\n            \"MintToZeroAddress()\" : {\n              \"details\": \"Cannot mint to zero address\"\n            }\n          },\n          \"events\": {\n            \"Transfer(address,address,uint256)\": {\n              \"details\": \"Emitted when `value` tokens are moved from one account (`from`) toanother (`to`).\",\n              \"params\": {\n                \"from\": \"The sender address\",\n                \"to\": \"The receiver address\",\n                \"value\": \"The token amount\"\n              }\n            }\n          },\n          \"kind\": \"dev\",\n          \"methods\": {\n            \"transfer(address,uint256)\": {\n              // Contents of the @dev NatSpec field of the method\n              \"details\": \"Returns a boolean value indicating whether the operation succeeded. Must be called by the token holder address\",\n              // Contents of the @param NatSpec fields of the method\n              \"params\": {\n                \"_value\": \"The amount tokens to be transferred\",\n                \"_to\": \"The receiver address\"\n              },\n              // Contents of the @return NatSpec field.\n              \"returns\": {\n                // Return var name (here \"success\") if exists. \"_0\" as key if return var is unnamed\n                \"success\": \"a boolean value indicating whether the operation succeeded\"\n              }\n            }\n          },\n          \"stateVariables\": {\n            \"owner\": {\n              // Contents of the @dev NatSpec field of the state variable\n              \"details\": \"Must be set during contract creation. Can then only be changed by the owner\"\n            }\n          },\n          // Contents of the @title NatSpec field of the contract\n          \"title\": \"MyERC20: an example ERC20\",\n          \"version\": 1 // NatSpec version\n        },\n        // Required: NatSpec user documentation of the contract. See \"NatSpec Format\"\n        \"userdoc\": {\n          \"errors\": {\n            \"ApprovalCallerNotOwnerNorApproved()\": [\n              {\n                \"notice\": \"The caller must own the token or be an approved operator.\"\n              }\n            ]\n          },\n          \"events\": {\n            \"Transfer(address,address,uint256)\": {\n              \"notice\": \"`_value` tokens have been moved from `from` to `to`\"\n            }\n          },\n          \"kind\": \"user\",\n          \"methods\": {\n            \"transfer(address,uint256)\": {\n              \"notice\": \"Transfers `_value` tokens to address `_to`\"\n            }\n          },\n          \"version\": 1 // NatSpec version\n        }\n      },\n      // Required: Compiler settings.\n      // Reflects the settings in the JSON input during compilation, except:\n      // - Different format: \"libraries\" field\n      // - Added field in metadata.settings: \"compilationTarget\"\n      // - Not in metadata.settings: \"stopAfter\", \"debug.debugInfo\", \"outputSelection\"\n      // See the standard JSON input's \"settings\" field docs for the rest.\n      \"settings\": {\n        // Required for Solidity: File path and the name of the contract or library this\n        // metadata is created for. This field is not present in the standard JSON input settings.\n        \"compilationTarget\": {\n          \"myDirectory/myFile.sol\": \"MyContract\"\n        },\n        // Optional (false if omitted): Indicates whether experimental mode has been enabled.\n        // Always matches the value of the `experimental` flag in CBOR metadata.\n        // Note that experimental mode being enabled does not necessarily mean that any\n        // experimental features were actually used, or if they were, that those features\n        // affected the bytecode.\n        \"experimental\": true,\n        // Required for Solidity: Addresses for libraries used.\n        // Note that metadata has a different format for \"libraries\" field than the standard JSON input.\n        // metadata format = { \"MyLib.sol:MyLib\": \"0x123123...\" }\n        // standard JSON input format = { \"MyLib.sol\": { \"MyLib\": \"0x123123...\" } }\n        \"libraries\": {\n          \"MyLib.sol:MyLib\": \"0x123123...\"\n        },\n        // ...\n        // ...\n        // ...\n        // The rest of the fields and their defaults same as in std JSON input.\n      },\n      // Required: Compilation source files/source units, keys are file paths\n      \"sources\": {\n        \"settable\": {\n          // Required (unless \"url\" is used): literal contents of the source file\n          \"content\": \"contract settable is owned { uint256 private x = 0; function set(uint256 _x) public { if (msg.sender == owner) x = _x; } }\",\n          // Required: keccak256 hash of the source file\n          \"keccak256\": \"0x234...\"\n        },\n        \"myDirectory/myFile.sol\": {\n          // Required: keccak256 hash of the source file\n          \"keccak256\": \"0x123...\",\n          // Optional: SPDX license identifier as given in the source file\n          \"license\": \"MIT\",\n          // Required (unless \"content\" is used, see above): Sorted URL(s)\n          // to the source file, protocol is more or less arbitrary, but an\n          // IPFS URL is recommended\n          \"urls\": [ \"bzz-raw://7d7a...\", \"dweb:/ipfs/QmN...\" ]\n        }\n      },\n      // Required: The version of the metadata format\n      \"version\": 1\n    }\n\n.. warning::\n  Since the bytecode of the resulting contract contains the metadata hash by default, any\n  change to the metadata might result in a change of the bytecode. This includes\n  changes to a filename or path, and since the metadata includes a hash of all the\n  sources used, a single whitespace change results in different metadata, and\n  different bytecode.\n\n.. note::\n    The ABI definition above has no fixed order. It can change with compiler versions.\n    Starting from Solidity version 0.5.12, though, the array maintains a certain\n    order.\n\n.. _encoding-of-the-metadata-hash-in-the-bytecode:\n\nEncoding of the Metadata Hash in the Bytecode\n=============================================\n\nThe compiler currently by default appends the\n`IPFS hash (in CID v0) <https://docs.ipfs.tech/concepts/content-addressing/#version-0-v0>`_\nof the canonical metadata file and the compiler version to the end of the bytecode.\nOptionally, a Swarm hash instead of the IPFS, or an experimental flag is used.\nBelow are all the possible fields:\n\n.. code-block:: javascript\n\n    {\n      // Present if \"bytecodeHash\" was \"ipfs\" in compiler settings\n      \"ipfs\": \"<metadata hash>\",\n      // Present if \"bytecodeHash\" was \"bzzr1\" in compiler settings\n      \"bzzr1\": \"<metadata hash>\",\n      // Previous versions were using \"bzzr0\" instead of \"bzzr1\"\n      \"bzzr0\": \"<metadata hash>\",\n      // Present if experimental mode has been enabled either via \"--experimental\" flag or\n      // \"settings.experimental\" option in Standard JSON\n      \"experimental\": true,\n      \"solc\": \"<compiler version>\"\n    }\n\nBecause we might support other ways to retrieve the\nmetadata file in the future, this information is stored\n`CBOR <https://tools.ietf.org/html/rfc7049>`_-encoded. The last two bytes in the bytecode\nindicate the length of the CBOR encoded information. By looking at this length, the\nrelevant part of the bytecode can be decoded with a CBOR decoder.\n\nCheck the `Metadata Playground <https://playground.sourcify.dev/>`_ to see it in action.\n\nWhereas release builds of solc use a 3 byte encoding of the version as shown\nabove (one byte each for major, minor and patch version number), pre-release builds\nwill instead use a complete version string including commit hash and build date.\n\nThe commandline flag ``--no-cbor-metadata`` can be used to skip metadata\nfrom getting appended at the end of the deployed bytecode. Equivalently, the\nboolean field ``settings.metadata.appendCBOR`` in Standard JSON input can be set to false.\n\n.. note::\n  The CBOR mapping can also contain other keys, so it is better to fully\n  decode the data by looking at the end of the bytecode for the CBOR length,\n  and to use a proper CBOR parser. Do not rely on it starting with ``0xa264``\n  or ``0xa2 0x64 'i' 'p' 'f' 's'``.\n\nUsage for Automatic Interface Generation and NatSpec\n====================================================\n\nThe metadata is used in the following way: A component that wants to interact\nwith a contract (e.g. a wallet) retrieves the code of the contract.\nIt decodes the CBOR encoded section containing the IPFS/Swarm hash of the\nmetadata file. With that hash, the metadata file is retrieved. That file\nis JSON-decoded into a structure like above.\n\nThe component can then use the ABI to automatically generate a rudimentary\nuser interface for the contract.\n\nFurthermore, the wallet can use the NatSpec user documentation to display a\nhuman-readable confirmation message to the user whenever they interact with\nthe contract, together with requesting authorization for the transaction signature.\n\nFor additional information, read :doc:`Ethereum Natural Language Specification (NatSpec) format <natspec-format>`.\n\nUsage for Source Code Verification\n==================================\n\nIf pinned/published, it is possible to retrieve the metadata of the contract from IPFS/Swarm.\nThe metadata file also contains the URLs or the IPFS hashes of the source files, as well as\nthe compilation settings, i.e. everything needed to reproduce a compilation.\n\nWith this information it is then possible to verify the source code of a contract by\nreproducing the compilation, and comparing the bytecode from the compilation with\nthe bytecode of the deployed contract.\n\nThis automatically verifies the metadata since its hash is part of the bytecode, as well\nas the source codes, because their hashes are part of the metadata. Any change in the files\nor settings would result in a different metadata hash. The metadata here serves\nas a fingerprint of the whole compilation.\n\n`Sourcify <https://sourcify.dev>`_ makes use of this feature for \"full/perfect verification\",\nas well as pinning the files publicly on IPFS to be accessed with the metadata hash.\n"
  },
  {
    "path": "docs/natspec-format.rst",
    "content": ".. _natspec:\n\n##############\nNatSpec Format\n##############\n\nSolidity contracts can use a special form of comments to provide rich\ndocumentation for functions, return variables and more. This special form is\nnamed the Ethereum Natural Language Specification Format (NatSpec).\n\n.. note::\n\n  NatSpec was inspired by `Doxygen <https://en.wikipedia.org/wiki/Doxygen>`_.\n  While it uses Doxygen-style comments and tags, there is no intention to keep\n  strict compatibility with Doxygen. Please carefully examine the supported tags\n  listed below.\n\nThis documentation is segmented into developer-focused messages and end-user-facing\nmessages. These messages may be shown to the end user (the human) at the\ntime that they will interact with the contract (i.e. sign a transaction).\n\nIt is recommended that Solidity contracts are fully annotated using NatSpec for\nall public interfaces (everything in the ABI).\n\nNatSpec includes the formatting for comments that the smart contract author will\nuse, and which are understood by the Solidity compiler. Also detailed below is\noutput of the Solidity compiler, which extracts these comments into a machine-readable\nformat.\n\nNatSpec may also include annotations used by third-party tools. These are most likely\naccomplished via the ``@custom:<name>`` tag, and a good use case is analysis and verification\ntools.\n\n.. _header-doc-example:\n\nDocumentation Example\n=====================\n\nDocumentation is inserted above each ``contract``, ``interface``, ``library``,\n``function``, ``enum``, ``enum`` value and ``event`` using the Doxygen notation format.\nA ``public`` state variable is equivalent to a ``function``\nfor the purposes of NatSpec.\n\n-  For Solidity you may choose ``///`` for single or multi-line\n   comments, or ``/**`` and ending with ``*/``.\n\n-  For Vyper, use ``\"\"\"`` indented to the inner contents with bare\n   comments. See the `Vyper\n   documentation <https://docs.vyperlang.org/en/latest/natspec.html>`__.\n\nThe following example shows a contract and a function using all available tags.\n\n.. note::\n\n  The Solidity compiler only interprets tags if they are external or\n  public. You are welcome to use similar comments for your internal and\n  private functions, but those will not be parsed.\n\n  This may change in the future.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.2 < 0.9.0;\n\n    /// @title A simulator for trees\n    /// @author Larry A. Gardner\n    /// @notice You can use this contract for only the most basic simulation\n    /// @dev All function calls are currently implemented without side effects\n    /// @custom:experimental This is an experimental contract.\n    contract Tree {\n        /// @notice Calculate tree age in years, rounded up, for live trees\n        /// @dev The Alexandr N. Tetearing algorithm could increase precision\n        /// @param rings The number of rings from dendrochronological sample\n        /// @return Age in years, rounded up for partial years\n        /// @return Name of the tree\n        function age(uint256 rings) external virtual pure returns (uint256, string memory) {\n            return (rings + 1, \"tree\");\n        }\n\n        /// @notice Returns the amount of leaves the tree has.\n        /// @dev Returns only a fixed number.\n        function leaves() external virtual pure returns(uint256) {\n            return 2;\n        }\n    }\n\n    contract Plant {\n        function leaves() external virtual pure returns(uint256) {\n            return 3;\n        }\n    }\n\n    contract KumquatTree is Tree, Plant {\n        function age(uint256 rings) external override pure returns (uint256, string memory) {\n            return (rings + 2, \"Kumquat\");\n        }\n\n        /// Return the amount of leaves that this specific kind of tree has\n        /// @inheritdoc Tree\n        function leaves() external override(Tree, Plant) pure returns(uint256) {\n            return 3;\n        }\n    }\n\n.. _header-tags:\n\nTags\n====\n\nAll tags are optional. The following table explains the purpose of each\nNatSpec tag and where it may be used. As a special case, if no tags are\nused then the Solidity compiler will interpret a ``///`` or ``/**`` comment\nin the same way as if it were tagged with ``@notice``.\n\n=============== ====================================================================================== =============================\nTag                                                                                                    Context\n=============== ====================================================================================== =============================\n``@title``      A title that should describe the contract/interface                                    contract, library, interface, struct, enum, enum values\n``@author``     The name of the author                                                                 contract, library, interface, struct, enum, enum values\n``@notice``     Explain to an end user what this does                                                  contract, library, interface, function, public state variable, event, struct, enum, enum values error\n``@dev``        Explain to a developer any extra details                                               contract, library, interface, function, state variable, event, struct, enum, enum values, error\n``@param``      Documents a parameter just like in Doxygen (must be followed by parameter name)        function, event, enum values, error\n``@return``     Documents the return variables of a contract's function                                function, enum, enum values, public state variable\n``@inheritdoc`` Copies all missing tags from the base function (must be followed by the contract name) function, enum, enum values, public state variable\n``@custom:...`` Custom tag, semantics is application-defined                                           everywhere\n=============== ====================================================================================== =============================\n\nIf your function returns multiple values, like ``(int quotient, int remainder)``\nthen use multiple ``@return`` statements in the same format as the ``@param`` statements.\n\nCustom tags start with ``@custom:`` and must be followed by one or more lowercase letters or hyphens.\nIt cannot start with a hyphen however. They can be used everywhere and are part of the developer documentation.\n\n.. _header-dynamic:\n\nDynamic expressions\n-------------------\n\nThe Solidity compiler will pass through NatSpec documentation from your Solidity\nsource code to the JSON output as described in this guide. The consumer of this\nJSON output, for example the end-user client software, may present this to the end-user directly or it may apply some pre-processing.\n\nFor example, some client software will render:\n\n.. code:: Solidity\n\n   /// @notice This function will multiply `a` by 7\n\nto the end-user as:\n\n.. code:: text\n\n    This function will multiply 10 by 7\n\nif a function is being called and the input ``a`` is assigned a value of 10.\n\n.. _header-inheritance:\n\nInheritance Notes\n-----------------\n\nFunctions without NatSpec will automatically inherit the documentation of their\nbase function. Exceptions to this are:\n\n* When the parameter names are different.\n* When there is more than one base function.\n* When there is an explicit ``@inheritdoc`` tag which specifies which contract should be used to inherit.\n\n.. _header-output:\n\nDocumentation Output\n====================\n\nWhen parsed by the compiler, documentation such as the one from the\nabove example will produce two different JSON files. One is meant to be\nconsumed by the end user as a notice when a function is executed and the\nother to be used by the developer.\n\nIf the above contract is saved as ``ex1.sol`` then you can generate the\ndocumentation using:\n\n.. code-block:: shell\n\n   solc --userdoc --devdoc ex1.sol\n\nAnd the output is below.\n\n.. note::\n    Starting Solidity version 0.6.11 the NatSpec output also contains a ``version`` and a ``kind`` field.\n    Currently the ``version`` is set to ``1`` and ``kind`` must be one of ``user`` or ``dev``.\n    In the future it is possible that new versions will be introduced, deprecating older ones.\n\n.. _header-user-doc:\n\nUser Documentation\n------------------\n\nThe above documentation will produce the following user documentation\nJSON file as output for the ``Tree`` contract:\n\n.. code-block:: json\n\n    {\n      \"version\" : 1,\n      \"kind\" : \"user\",\n      \"methods\" :\n      {\n        \"age(uint256)\" :\n        {\n          \"notice\" : \"Calculate tree age in years, rounded up, for live trees\"\n        },\n        \"leaves()\" :\n        {\n            \"notice\" : \"Returns the amount of leaves the tree has.\"\n        }\n      },\n      \"notice\" : \"You can use this contract for only the most basic simulation\"\n    }\n\nNote that the key by which to find the methods is the function's\ncanonical signature as defined in the :ref:`Contract\nABI <abi_function_selector>` and not simply the function's\nname.\n\n.. _header-developer-doc:\n\nDeveloper Documentation\n-----------------------\n\nApart from the user documentation file, a developer documentation JSON\nfile should also be produced and should look like this:\n\n.. code-block:: json\n\n    {\n      \"version\" : 1,\n      \"kind\" : \"dev\",\n      \"author\" : \"Larry A. Gardner\",\n      \"details\" : \"All function calls are currently implemented without side effects\",\n      \"custom:experimental\" : \"This is an experimental contract.\",\n      \"methods\" :\n      {\n        \"age(uint256)\" :\n        {\n          \"details\" : \"The Alexandr N. Tetearing algorithm could increase precision\",\n          \"params\" :\n          {\n            \"rings\" : \"The number of rings from dendrochronological sample\"\n          },\n          \"returns\" : {\n            \"_0\" : \"Age in years, rounded up for partial years\",\n            \"_1\" : \"Name of the tree\"\n          }\n        },\n        \"leaves()\" :\n        {\n            \"details\" : \"Returns only a fixed number.\"\n        }\n      },\n      \"title\" : \"A simulator for trees\"\n    }\n"
  },
  {
    "path": "docs/path-resolution.rst",
    "content": ".. _path-resolution:\n\n**********************\nImport Path Resolution\n**********************\n\nIn order to be able to support reproducible builds on all platforms, the Solidity compiler has to\nabstract away the details of the filesystem where source files are stored.\nPaths used in imports must work the same way everywhere while the command-line interface must be\nable to work with platform-specific paths to provide good user experience.\nThis section aims to explain in detail how Solidity reconciles these requirements.\n\n.. index:: ! virtual filesystem, ! VFS, ! source unit name\n.. _virtual-filesystem:\n\nVirtual Filesystem\n==================\n\nThe compiler maintains an internal database (*virtual filesystem* or *VFS* for short) where each\nsource unit is assigned a unique *source unit name* which is an opaque and unstructured identifier.\nWhen you use the :ref:`import statement <import>`, you specify an *import path* that references a\nsource unit name.\n\n.. index:: ! import callback, ! Host Filesystem Loader, ! --no-import-callback\n.. _import-callback:\n\nImport Callback\n---------------\n\nThe VFS is initially populated only with files the compiler has received as input.\nAdditional files can be loaded during compilation using an *import callback*, which is different\ndepending on the type of compiler you use (see below).\nIf the compiler does not find any source unit name matching the import path in the VFS, it invokes\nthe callback, which is responsible for obtaining the source code to be placed under that name.\nAn import callback is free to interpret source unit names in an arbitrary way, not just as paths.\nIf there is no callback available when one is needed or if it fails to locate the source code,\ncompilation fails.\n\nBy default, the command-line compiler provides the *Host Filesystem Loader* - a rudimentary callback\nthat interprets a source unit name as a path in the local filesystem.\nThis callback can be disabled using the ``--no-import-callback`` command-line option.\nThe `JavaScript interface <https://github.com/argotorg/solc-js>`_ does not provide any by default,\nbut one can be provided by the user.\nThis mechanism can be used to obtain source code from locations other than the local filesystem\n(which may not even be accessible, e.g. when the compiler is running in a browser).\nFor example the `Remix IDE <https://remix.ethereum.org/>`_ provides a versatile callback that\nlets you `import files from HTTP, IPFS and Swarm URLs or refer directly to packages in NPM registry\n<https://remix-ide.readthedocs.io/en/latest/import.html>`_.\n\n.. note::\n\n    Host Filesystem Loader's file lookup is platform-dependent.\n    For example backslashes in a source unit name can be interpreted as directory separators or not\n    and the lookup can be case-sensitive or not, depending on the underlying platform.\n\n    For portability it is recommended to avoid using import paths that will work correctly only\n    with a specific import callback or only on one platform.\n    For example you should always use forward slashes since they work as path separators also on\n    platforms that support backslashes.\n\nInitial Content of the Virtual Filesystem\n-----------------------------------------\n\nThe initial content of the VFS depends on how you invoke the compiler:\n\n#. **solc / command-line interface**\n\n   When you compile a file using the command-line interface of the compiler, you provide one or\n   more paths to files containing Solidity code:\n\n   .. code-block:: bash\n\n       solc contract.sol /usr/local/dapp-bin/token.sol\n\n   The source unit name of a file loaded this way is constructed by converting its path to a\n   canonical form and, if possible, making it relative to either the base path or one of the\n   include paths.\n   See :ref:`CLI Path Normalization and Stripping <cli-path-normalization-and-stripping>` for\n   a detailed description of this process.\n\n   .. index:: standard JSON\n\n#. **Standard JSON**\n\n   When using the :ref:`Standard JSON <compiler-api>` API (via either the `JavaScript interface\n   <https://github.com/argotorg/solc-js>`_ or the ``--standard-json`` command-line option)\n   you provide input in JSON format, containing, among other things, the content of all your source\n   files:\n\n   .. code-block:: json\n\n       {\n           \"language\": \"Solidity\",\n           \"sources\": {\n               \"contract.sol\": {\n                   \"content\": \"import \\\"./util.sol\\\";\\ncontract C {}\"\n               },\n               \"util.sol\": {\n                   \"content\": \"library Util {}\"\n               },\n               \"/usr/local/dapp-bin/token.sol\": {\n                   \"content\": \"contract Token {}\"\n               }\n           },\n           \"settings\": {\"outputSelection\": {\"*\": { \"*\": [\"metadata\", \"evm.bytecode\"]}}}\n       }\n\n   The ``sources`` dictionary becomes the initial content of the virtual filesystem and its keys\n   are used as source unit names.\n\n   .. _initial-vfs-content-standard-json-with-import-callback:\n\n#. **Standard JSON (via import callback)**\n\n   With Standard JSON it is also possible to tell the compiler to use the import callback to obtain\n   the source code:\n\n   .. code-block:: json\n\n       {\n           \"language\": \"Solidity\",\n           \"sources\": {\n               \"/usr/local/dapp-bin/token.sol\": {\n                   \"urls\": [\n                       \"/projects/mytoken.sol\",\n                       \"https://example.com/projects/mytoken.sol\"\n                   ]\n               }\n           },\n           \"settings\": {\"outputSelection\": {\"*\": { \"*\": [\"metadata\", \"evm.bytecode\"]}}}\n       }\n\n   If an import callback is available, the compiler will give it the strings specified in\n   ``urls`` one by one, until one is loaded successfully or the end of the list is reached.\n\n   The source unit names are determined the same way as when using ``content`` - they are keys of\n   the ``sources`` dictionary and the content of ``urls`` does not affect them in any way.\n\n   .. index:: standard input, stdin, <stdin>\n\n#. **Standard input**\n\n   On the command-line it is also possible to provide the source by sending it to compiler's\n   standard input:\n\n   .. code-block:: bash\n\n       echo 'import \"./util.sol\"; contract C {}' | solc -\n\n   ``-`` used as one of the arguments instructs the compiler to place the content of the standard\n   input in the virtual filesystem under a special source unit name: ``<stdin>``.\n\nOnce the VFS is initialized, additional files can still be added to it only through the import\ncallback.\n\n.. index:: ! import; path\n\nImports\n=======\n\nThe import statement specifies an *import path*.\nBased on how the import path is specified, we can divide imports into two categories:\n\n- :ref:`Direct imports <direct-imports>`, where you specify the full source unit name directly.\n- :ref:`Relative imports <relative-imports>`, where you specify a path starting with ``./`` or ``../``\n  to be combined with the source unit name of the importing file.\n\n\n.. code-block:: solidity\n    :caption: contracts/contract.sol\n\n    import \"./math/math.sol\";\n    import \"contracts/tokens/token.sol\";\n\nIn the above ``./math/math.sol`` and ``contracts/tokens/token.sol`` are import paths while the\nsource unit names they translate to are ``contracts/math/math.sol`` and ``contracts/tokens/token.sol``\nrespectively.\n\n.. index:: ! direct import, import; direct\n.. _direct-imports:\n\nDirect Imports\n--------------\n\nAn import that does not start with ``./`` or ``../`` is a *direct import*.\n\n.. code-block:: solidity\n\n    import \"/project/lib/util.sol\";         // source unit name: /project/lib/util.sol\n    import \"lib/util.sol\";                  // source unit name: lib/util.sol\n    import \"@openzeppelin/address.sol\";     // source unit name: @openzeppelin/address.sol\n    import \"https://example.com/token.sol\"; // source unit name: https://example.com/token.sol\n\nAfter applying any :ref:`import remappings <import-remapping>` the import path simply becomes the\nsource unit name.\n\n.. note::\n\n    A source unit name is just an identifier and even if its value happens to look like a path, it\n    is not subject to the normalization rules you would typically expect in a shell.\n    Any ``/./`` or ``/../`` segments or sequences of multiple slashes remain a part of it.\n    When the source is provided via Standard JSON interface it is entirely possible to associate\n    different content with source unit names that would refer to the same file on disk.\n\nWhen the source is not available in the virtual filesystem, the compiler passes the source unit name\nto the import callback.\nThe Host Filesystem Loader will attempt to use it as a path and look up the file on disk.\nAt this point the platform-specific normalization rules kick in and names that were considered\ndifferent in the VFS may actually result in the same file being loaded.\nFor example ``/project/lib/math.sol`` and ``/project/lib/../lib///math.sol`` are considered\ncompletely different in the VFS even though they refer to the same file on disk.\n\n.. note::\n\n    Even if an import callback ends up loading source code for two different source unit names from\n    the same file on disk, the compiler will still see them as separate source units.\n    It is the source unit name that matters, not the physical location of the code.\n\n.. index:: ! relative import, ! import; relative\n.. _relative-imports:\n\nRelative Imports\n----------------\n\nAn import starting with ``./`` or ``../`` is a *relative import*.\nSuch imports specify a path relative to the source unit name of the importing source unit:\n\n.. code-block:: solidity\n    :caption: /project/lib/math.sol\n\n    import \"./util.sol\" as util;    // source unit name: /project/lib/util.sol\n    import \"../token.sol\" as token; // source unit name: /project/token.sol\n\n.. code-block:: solidity\n    :caption: lib/math.sol\n\n    import \"./util.sol\" as util;    // source unit name: lib/util.sol\n    import \"../token.sol\" as token; // source unit name: token.sol\n\n.. note::\n\n    Relative imports **always** start with ``./`` or ``../`` so ``import \"util.sol\"``, unlike\n    ``import \"./util.sol\"``, is a direct import.\n    While both paths would be considered relative in the host filesystem, ``util.sol`` is actually\n    absolute in the VFS.\n\nLet us define a *path segment* as any non-empty part of the path that does not contain a separator\nand is bounded by two path separators.\nA separator is a forward slash or the beginning/end of the string.\nFor example in ``./abc/..//`` there are three path segments: ``.``, ``abc`` and ``..``.\n\nThe compiler resolves the import into a source unit name based on the import path, in the following way:\n\n#. We start with the source unit name of the importing source unit.\n#. The last path segment with preceding slashes is removed from the resolved name.\n#. Then, for every segment in the import path, starting from the leftmost one:\n\n    - If the segment is ``.``, it is skipped.\n    - If the segment is ``..``, the last path segment with preceding slashes is removed from the resolved name.\n    - Otherwise, the segment (preceded by a single slash if the resolved name is not empty), is appended to the resolved name.\n\nThe removal of the last path segment with preceding slashes is understood to\nwork as follows:\n\n1. Everything past the last slash is removed (i.e. ``a/b//c.sol`` becomes ``a/b//``).\n2. All trailing slashes are removed (i.e. ``a/b//`` becomes ``a/b``).\n\nNote that the process normalizes the part of the resolved source unit name that comes from the import path according\nto the usual rules for UNIX paths, i.e. all ``.`` and ``..`` are removed and multiple slashes are\nsquashed into a single one.\nOn the other hand, the part that comes from the source unit name of the importing module remains unnormalized.\nThis ensures that the ``protocol://`` part does not turn into ``protocol:/`` if the importing file\nis identified with a URL.\n\nIf your import paths are already normalized, you can expect the above algorithm to produce very\nintuitive results.\nHere are some examples of what you can expect if they are not:\n\n.. code-block:: solidity\n    :caption: lib/src/../contract.sol\n\n    import \"./util/./util.sol\";         // source unit name: lib/src/../util/util.sol\n    import \"./util//util.sol\";          // source unit name: lib/src/../util/util.sol\n    import \"../util/../array/util.sol\"; // source unit name: lib/src/array/util.sol\n    import \"../.././../util.sol\";       // source unit name: util.sol\n    import \"../../.././../util.sol\";    // source unit name: util.sol\n\n.. note::\n\n    The use of relative imports containing leading ``..`` segments is not recommended.\n    The same effect can be achieved in a more reliable way by using direct imports with\n    :ref:`base path and include paths <base-and-include-paths>`.\n\n.. index:: ! base path, ! --base-path, ! include paths, ! --include-path\n.. _base-and-include-paths:\n\nBase Path and Include Paths\n===========================\n\nThe base path and include paths represent directories that the Host Filesystem Loader will load files from.\nWhen a source unit name is passed to the loader, it prepends the base path to it and performs a\nfilesystem lookup.\nIf the lookup does not succeed, the same is done with all directories on the include path list.\n\nIt is recommended to set the base path to the root directory of your project and use include paths to\nspecify additional locations that may contain libraries your project depends on.\nThis lets you import from these libraries in a uniform way, no matter where they are located in the\nfilesystem relative to your project.\nFor example, if you use npm to install packages and your contract imports\n``@openzeppelin/contracts/utils/Strings.sol``, you can use these options to tell the compiler that\nthe library can be found in one of the npm package directories:\n\n.. code-block:: bash\n\n    solc contract.sol \\\n        --base-path . \\\n        --include-path node_modules/ \\\n        --include-path /usr/local/lib/node_modules/\n\nYour contract will compile (with the same exact metadata) no matter whether you install the library\nin the local or global package directory or even directly under your project root.\n\nBy default the base path is empty, which leaves the source unit name unchanged.\nWhen the source unit name is a relative path, this results in the file being looked up in the\ndirectory the compiler has been invoked from.\nIt is also the only value that results in absolute paths in source unit names being actually\ninterpreted as absolute paths on disk.\nIf the base path itself is relative, it is interpreted as relative to the current working directory\nof the compiler.\n\n.. note::\n\n    Include paths cannot have empty values and must be used together with a non-empty base path.\n\n.. note::\n\n    Include paths and base path can overlap as long as it does not make import resolution ambiguous.\n    For example, you can specify a directory inside base path as an include directory or have an\n    include directory that is a subdirectory of another include directory.\n    The compiler will only issue an error if the source unit name passed to the Host Filesystem\n    Loader represents an existing path when combined with multiple include paths or an include path\n    and base path.\n\n.. _cli-path-normalization-and-stripping:\n\nCLI Path Normalization and Stripping\n------------------------------------\n\nOn the command-line the compiler behaves just as you would expect from any other program:\nit accepts paths in a format native to the platform and relative paths are relative to the current\nworking directory.\nThe source unit names assigned to files whose paths are specified on the command-line, however,\nshould not change just because the project is being compiled on a different platform or because the\ncompiler happens to have been invoked from a different directory.\nTo achieve this, paths to source files coming from the command-line must be converted to a canonical\nform, and, if possible, made relative to the base path or one of the include paths.\n\nThe normalization rules are as follows:\n\n- If a path is relative, it is made absolute by prepending the current working directory to it.\n- Internal ``.`` and ``..`` segments are collapsed.\n- Platform-specific path separators are replaced with forward slashes.\n- Sequences of multiple consecutive path separators are squashed into a single separator (unless\n  they are the leading slashes of an `UNC path <https://en.wikipedia.org/wiki/Path_(computing)#UNC>`_).\n- If the path includes a root name (e.g. a drive letter on Windows) and the root is the same as the\n  root of the current working directory, the root is replaced with ``/``.\n- Symbolic links in the path are **not** resolved.\n\n  - The only exception is the path to the current working directory prepended to relative paths in\n    the process of making them absolute.\n    On some platforms the working directory is reported always with symbolic links resolved so for\n    consistency the compiler resolves them everywhere.\n\n- The original case of the path is preserved even if the filesystem is case-insensitive but\n  `case-preserving <https://en.wikipedia.org/wiki/Case_preservation>`_ and the actual case on\n  disk is different.\n\n.. note::\n\n    There are situations where paths cannot be made platform-independent.\n    For example on Windows the compiler can avoid using drive letters by referring to the root\n    directory of the current drive as ``/`` but drive letters are still necessary for paths leading\n    to other drives.\n    You can avoid such situations by ensuring that all the files are available within a single\n    directory tree on the same drive.\n\nAfter normalization the compiler attempts to make the source file path relative.\nIt tries the base path first and then the include paths in the order they were given.\nIf the base path is empty or not specified, it is treated as if it was equal to the path to the\ncurrent working directory (with all symbolic links resolved).\nThe result is accepted only if the normalized directory path is the exact prefix of the normalized\nfile path.\nOtherwise the file path remains absolute.\nThis makes the conversion unambiguous and ensures that the relative path does not start with ``../``.\nThe resulting file path becomes the source unit name.\n\n.. note::\n\n    The relative path produced by stripping must remain unique within the base path and include paths.\n    For example the compiler will issue an error for the following command if both\n    ``/project/contract.sol`` and ``/lib/contract.sol`` exist:\n\n    .. code-block:: bash\n\n        solc /project/contract.sol --base-path /project --include-path /lib\n\n.. note::\n\n    Prior to version 0.8.8, CLI path stripping was not performed and the only normalization applied\n    was the conversion of path separators.\n    When working with older versions of the compiler it is recommended to invoke the compiler from\n    the base path and to only use relative paths on the command-line.\n\n.. index:: ! allowed paths, ! --allow-paths, remapping; target\n.. _allowed-paths:\n\nAllowed Paths\n=============\n\nAs a security measure, the Host Filesystem Loader will refuse to load files from outside of a few\nlocations that are considered safe by default:\n\n- Outside of Standard JSON mode:\n\n  - The directories containing input files listed on the command-line.\n  - The directories used as :ref:`remapping <import-remapping>` targets.\n    If the target is not a directory (i.e does not end with ``/``, ``/.`` or ``/..``) the directory\n    containing the target is used instead.\n  - Base path and include paths.\n\n- In Standard JSON mode:\n\n  - Base path and include paths.\n\nAdditional directories can be whitelisted using the ``--allow-paths`` option.\nThe option accepts a comma-separated list of paths:\n\n.. code-block:: bash\n\n    cd /home/user/project/\n    solc token/contract.sol \\\n        lib/util.sol=libs/util.sol \\\n        --base-path=token/ \\\n        --include-path=/lib/ \\\n        --allow-paths=../utils/,/tmp/libraries\n\nWhen the compiler is invoked with the command shown above, the Host Filesystem Loader will allow\nimporting files from the following directories:\n\n- ``/home/user/project/token/`` (because ``token/`` contains the input file and also because it is\n  the base path),\n- ``/lib/`` (because ``/lib/`` is one of the include paths),\n- ``/home/user/project/libs/`` (because ``libs/`` is a directory containing a remapping target),\n- ``/home/user/utils/`` (because of ``../utils/`` passed to ``--allow-paths``),\n- ``/tmp/libraries/`` (because of ``/tmp/libraries`` passed to ``--allow-paths``),\n\n.. note::\n\n    The working directory of the compiler is one of the paths allowed by default only if it\n    happens to be the base path (or the base path is not specified or has an empty value).\n\n.. note::\n\n    The compiler does not check if allowed paths actually exist and whether they are directories.\n    Non-existent or empty paths are simply ignored.\n    If an allowed path matches a file rather than a directory, the file is considered whitelisted, too.\n\n.. note::\n\n    Allowed paths are case-sensitive even if the filesystem is not.\n    The case must exactly match the one used in your imports.\n    For example ``--allow-paths tokens`` will not match ``import \"Tokens/IERC20.sol\"``.\n\n.. warning::\n\n    Files and directories only reachable through symbolic links from allowed directories are not\n    automatically whitelisted.\n    For example if ``token/contract.sol`` in the example above was actually a symlink pointing at\n    ``/etc/passwd`` the compiler would refuse to load it unless ``/etc/`` was one of the allowed\n    paths too.\n\n.. index:: ! remapping; import, ! import; remapping, ! remapping; context, ! remapping; prefix, ! remapping; target\n.. _import-remapping:\n\nImport Remapping\n================\n\nImport remapping allows you to redirect imports to a different location in the virtual filesystem.\nThe mechanism works by changing the translation between import paths and source unit names.\nFor example you can set up a remapping so that any import from the virtual directory\n``github.com/ethereum/dapp-bin/library/`` would be seen as an import from ``dapp-bin/library/`` instead.\n\nYou can limit the scope of a remapping by specifying a *context*.\nThis allows creating remappings that apply only to imports located in a specific library or a specific file.\nWithout a context a remapping is applied to every matching import in all the files in the virtual\nfilesystem.\n\nImport remappings have the form of ``context:prefix=target``:\n\n- ``context`` must match the beginning of the source unit name of the file containing the import.\n- ``prefix`` must match the beginning of the source unit name resulting from the import.\n- ``target`` is the value the prefix is replaced with.\n\nFor example, if you clone https://github.com/ethereum/dapp-bin/ locally to ``/project/dapp-bin``\nand run the compiler with:\n\n.. code-block:: bash\n\n    solc github.com/ethereum/dapp-bin/=dapp-bin/ --base-path /project source.sol\n\nyou can use the following in your source file:\n\n.. code-block:: solidity\n\n    import \"github.com/ethereum/dapp-bin/library/math.sol\"; // source unit name: dapp-bin/library/math.sol\n\nThe compiler will look for the file in the VFS under ``dapp-bin/library/math.sol``.\nIf the file is not available there, the source unit name will be passed to the Host Filesystem\nLoader, which will then look in ``/project/dapp-bin/library/math.sol``.\n\n.. warning::\n\n    Information about remappings is stored in contract metadata.\n    Since the binary produced by the compiler has a hash of the metadata embedded in it, any\n    modification to the remappings will result in different bytecode.\n\n    For this reason you should be careful not to include any local information in remapping targets.\n    For example if your library is located in ``/home/user/packages/mymath/math.sol``, a remapping\n    like ``@math/=/home/user/packages/mymath/`` would result in your home directory being included in\n    the metadata.\n    To be able to reproduce the same bytecode with such a remapping on a different machine, you\n    would need to recreate parts of your local directory structure in the VFS and (if you rely on\n    Host Filesystem Loader) also in the host filesystem.\n\n    To avoid having your local directory structure embedded in the metadata, it is recommended to\n    designate the directories containing libraries as *include paths* instead.\n    For example, in the example above ``--include-path /home/user/packages/`` would let you use\n    imports starting with ``mymath/``.\n    Unlike remapping, the option on its own will not make ``mymath`` appear as ``@math`` but this\n    can be achieved by creating a symbolic link or renaming the package subdirectory.\n\nAs a more complex example, suppose you rely on a module that uses an old version of dapp-bin that\nyou checked out to ``/project/dapp-bin_old``, then you can run:\n\n.. code-block:: bash\n\n    solc module1:github.com/ethereum/dapp-bin/=dapp-bin/ \\\n         module2:github.com/ethereum/dapp-bin/=dapp-bin_old/ \\\n         --base-path /project \\\n         source.sol\n\nThis means that all imports in ``module2`` point to the old version but imports in ``module1``\npoint to the new version.\n\nHere are the detailed rules governing the behavior of remappings:\n\n#. **Remappings only affect the translation between import paths and source unit names.**\n\n   Source unit names added to the VFS in any other way cannot be remapped.\n   For example the paths you specify on the command-line and the ones in ``sources.urls`` in\n   Standard JSON are not affected.\n\n   .. code-block:: bash\n\n       solc /project/=/contracts/ /project/contract.sol # source unit name: /project/contract.sol\n\n   In the example above the compiler will load the source code from ``/project/contract.sol`` and\n   place it under that exact source unit name in the VFS, not under ``/contract/contract.sol``.\n\n#. **Context and prefix must match source unit names, not import paths.**\n\n   - This means that you cannot remap ``./`` or ``../`` directly since they are replaced during\n     the translation to source unit name but you can remap the part of the name they are replaced\n     with:\n\n     .. code-block:: bash\n\n         solc ./=a/ /project/=b/ /project/contract.sol # source unit name: /project/contract.sol\n\n     .. code-block:: solidity\n         :caption: /project/contract.sol\n\n         import \"./util.sol\" as util; // source unit name: b/util.sol\n\n   - You cannot remap base path or any other part of the path that is only added internally by an\n     import callback:\n\n     .. code-block:: bash\n\n         solc /project/=/contracts/ /project/contract.sol --base-path /project # source unit name: contract.sol\n\n     .. code-block:: solidity\n         :caption: /project/contract.sol\n\n         import \"util.sol\" as util; // source unit name: util.sol\n\n#. **Target is inserted directly into the source unit name and does not necessarily have to be a valid path.**\n\n   - It can be anything as long as the import callback can handle it.\n     In case of the Host Filesystem Loader this includes also relative paths.\n     When using the JavaScript interface you can even use URLs and abstract identifiers if\n     your callback can handle them.\n\n   - Remapping happens after relative imports have already been resolved into source unit names.\n     This means that targets starting with ``./`` and ``../`` have no special meaning and are\n     relative to the base path rather than to the location of the source file.\n\n   - Remapping targets are not normalized so ``@root/=./a/b//`` will remap ``@root/contract.sol``\n     to ``./a/b//contract.sol`` and not ``a/b/contract.sol``.\n\n   - If the target does not end with a slash, the compiler will not add one automatically:\n\n     .. code-block:: bash\n\n         solc /project/=/contracts /project/contract.sol # source unit name: /project/contract.sol\n\n     .. code-block:: solidity\n         :caption: /project/contract.sol\n\n         import \"/project/util.sol\" as util; // source unit name: /contractsutil.sol\n\n#. **Context and prefix are patterns and matches must be exact.**\n\n   - ``a//b=c`` will not match ``a/b``.\n   - source unit names are not normalized so ``a/b=c`` will not match ``a//b`` either.\n   - Parts of file and directory names can match as well.\n     ``/newProject/con:/new=old`` will match ``/newProject/contract.sol`` and remap it to\n     ``oldProject/contract.sol``.\n\n#. **At most one remapping is applied to a single import.**\n\n   - If multiple remappings match the same source unit name, the one with the longest matching context is chosen.\n   - If contexts are identical, the one with the longest matching prefix is chosen.\n   - If contexts and prefixes are identical, the one specified last wins.\n   - Remappings do not work on other remappings. For example ``a=b b=c c=d`` will not result in ``a``\n     being remapped to ``d``.\n\n#. **Prefix cannot be empty but context and target are optional.**\n\n   - If ``target`` is the empty string, ``prefix`` is simply removed from import paths.\n   - Empty ``context`` means that the remapping applies to all imports in all source units.\n\n.. index:: Remix IDE, file://\n\nUsing URLs in imports\n=====================\n\nMost URL prefixes such as ``https://`` or ``data://`` have no special meaning in import paths.\nThe only exception is ``file://`` which is stripped from source unit names by the Host Filesystem\nLoader.\n\nWhen compiling locally you can use import remapping to replace the protocol and domain part with a\nlocal path:\n\n.. code-block:: bash\n\n    solc :https://github.com/ethereum/dapp-bin=/usr/local/dapp-bin contract.sol\n\nNote the leading ``:``, which is necessary when the remapping context is empty.\nOtherwise the ``https:`` part would be interpreted by the compiler as the context.\n"
  },
  {
    "path": "docs/requirements.txt",
    "content": "# Older versions of sphinx-rtd-theme do not work with never docutils but have a bug in the dependency\n# which could result in it being installed anyway and the style (especially bullet points) being broken.\n# See https://github.com/readthedocs/sphinx_rtd_theme/issues/1115\n# theme >=3.0.0 removes the display_version option in favor of version_selector and language_selector\n# Use rtd theme version that supports sphinx>=8.0\nsphinx_rtd_theme>=3.0.0\n\npygments-lexer-solidity>=0.7.0\nsphinx-syntax>=1.0.1\n\n# Sphinx version constraints for sphinx-syntax compatibility\nsphinx>=8.0.0, <9.0.0\n"
  },
  {
    "path": "docs/resources.rst",
    "content": "#########\nResources\n#########\n\nGeneral Resources\n=================\n\n* `Ethereum.org Developers page <https://ethereum.org/en/developers/>`_\n* `Ethereum StackExchange <https://ethereum.stackexchange.com/>`_\n* `Solidity website <https://soliditylang.org/>`_\n* `Solidity changelog <https://github.com/argotorg/solidity/blob/develop/Changelog.md>`_\n* `Solidity codebase on GitHub <https://github.com/argotorg/solidity/>`_\n* `Solidity language users chat <https://matrix.to/#/#ethereum_solidity:gitter.im>`_\n* `Solidity compiler developers chat <https://matrix.to/#/#ethereum_solidity-dev:gitter.im>`_\n* `awesome-solidity <https://github.com/bkrem/awesome-solidity>`_\n* `Solidity by Example <https://solidity-by-example.org/>`_\n* `Solidity documentation community translations <https://github.com/solidity-docs>`_\n* `Solidity and Smart Contract Glossary <https://www.cyfrin.io/glossary>`_\n\nIntegrated (Ethereum) Development Environments\n==============================================\n\n* `Ape <https://docs.apeworx.io/ape>`_\n        A Python-based web3 development tool for compiling, testing, and interacting with smart contracts.\n\n* `Brownie <https://eth-brownie.readthedocs.io/en/stable/>`_\n        A Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine.\n        💡 Note: As per the official docs, Brownie is no longer actively maintained.\n        Future releases may come sporadically - or never at all.\n        Check out Ape Framework (first in list) for all your python Ethereum development needs.\n\n* `Dapp <https://dapp.tools/>`_\n        Tool for building, testing and deploying smart contracts from the command-line.\n\n* `Foundry <https://github.com/foundry-rs/foundry>`_\n        Fast, portable and modular toolkit for Ethereum application development written in Rust.\n\n* `Hardhat <https://hardhat.org/>`_\n        Ethereum development environment with local Ethereum network, debugging features and plugin ecosystem.\n\n* `Remix <https://remix.ethereum.org/>`_\n        Browser-based IDE with integrated compiler and Solidity runtime environment without server-side components.\n\n* `Truffle <https://trufflesuite.com/truffle/>`_\n        Ethereum development framework.\n        💡 Note: Consensys announced the sunset of Truffle on September 21, 2023.\n        Current users may check out the migration path and available product support `here.\n        <https://consensys.io/blog/consensys-announces-the-sunset-of-truffle-and-ganache-and-new-hardhat>`_\n\nEditor Integrations\n===================\n\n* Emacs\n\n    * `Emacs Solidity <https://github.com/ethereum/emacs-solidity/>`_\n        Plugin for the Emacs editor providing syntax highlighting and compilation error reporting.\n\n* IntelliJ\n\n    * `IntelliJ IDEA plugin <https://plugins.jetbrains.com/plugin/9475-solidity/>`_\n        Solidity plugin for IntelliJ IDEA (and all other JetBrains IDEs).\n\n* Sublime Text\n\n    * `Package for SublimeText - Solidity language syntax <https://packagecontrol.io/packages/Ethereum/>`_\n        Solidity syntax highlighting for SublimeText editor.\n\n* Vim\n\n    * `Vim Solidity by Thesis <https://github.com/thesis/vim-solidity/>`_\n        Syntax highlighting for Solidity in Vim.\n\n    * `Vim Solidity by TovarishFin <https://github.com/TovarishFin/vim-solidity>`_\n        Vim syntax file for Solidity.\n\n    * `Vim Syntastic <https://github.com/vim-syntastic/syntastic>`_\n        Plugin for the Vim editor providing compile checking.\n\n* Visual Studio Code (VS Code)\n\n    * `Aderyn Visual Studio Code extension <https://marketplace.visualstudio.com/items?itemName=Cyfrin.aderyn>`_\n        Solidity Smart contract analyzer designed to help find vulnerabilities. It supports projects built with Hardhat, Foundry, or any custom framework.\n\n    * `Ethereum Remix Visual Studio Code extension <https://github.com/ethereum/remix-vscode>`_\n        Ethereum Remix extension pack for VS Code\n        💡 Note: As per the official repository, this extension has been removed from the VSCODE marketplace and will be replaced by a dedicated stand-alone desktop application.\n\n    * `Solidity Visual Studio Code extension, by Juan Blanco <https://juan.blanco.ws/solidity-contracts-in-visual-studio-code/>`_\n        Solidity plugin for Microsoft Visual Studio Code that includes syntax highlighting and the Solidity compiler.\n\n    * `Solidity Visual Studio Code extension, by Nomic Foundation <https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity>`_\n        Solidity and Hardhat support by the Hardhat team, including: syntax highlighting, jump to definition, renames, quick fixes and inline solc warnings and errors.\n\n    * `Solidity Visual Auditor extension <https://marketplace.visualstudio.com/items?itemName=tintinweb.solidity-visual-auditor>`_\n        Adds security centric syntax and semantic highlighting to Visual Studio Code.\n\n    * `Truffle for VS Code <https://marketplace.visualstudio.com/items?itemName=trufflesuite-csi.truffle-vscode>`_\n        Build, debug and deploy smart contracts on Ethereum and EVM-compatible blockchains.\n        💡 Note: This extension has built-in support for the Truffle Suite which is being sunset.\n        For information on ongoing support, migration options and FAQs, visit the `Consensys blog.\n        <https://consensys.io/blog/consensys-announces-the-sunset-of-truffle-and-ganache-and-new-hardhat>`_\n\nSolidity Tools\n==============\n\n* `ABI to Solidity interface converter <https://gist.github.com/chriseth/8f533d133fa0c15b0d6eaf3ec502c82b>`_\n    A script for generating contract interfaces from the ABI of a smart contract.\n\n* `abi-to-sol <https://github.com/gnidan/abi-to-sol>`_\n    Tool to generate Solidity interface source from a given ABI JSON.\n\n* `Aderyn <https://github.com/Cyfrin/aderyn>`_\n    Command Line Tool that helps find vulnerabilities in Solidity smart contracts. It supports projects built with Hardhat, Foundry, or any custom framework.\n\n* `Doxity <https://github.com/DigixGlobal/doxity>`_\n    Documentation Generator for Solidity.\n\n* `ethdebug <https://github.com/ethdebug/format>`_\n    A standard debugging data format for smart contracts on Ethereum-compatible networks.\n\n* `Ethlint <https://github.com/duaraghav8/Ethlint>`_\n    Linter to identify and fix style and security issues in Solidity.\n\n* `evmdis <https://github.com/Arachnid/evmdis>`_\n    EVM Disassembler that performs static analysis on the bytecode to provide a higher level of abstraction than raw EVM operations.\n\n* `EVM Lab <https://github.com/ethereum/evmlab/>`_\n    A collection of tools to interact with the EVM. The package includes a VM, Etherchain API, and a trace-viewer with gas cost display.\n\n* `hevm <https://github.com/dapphub/dapptools/tree/master/src/hevm#readme>`_\n    EVM debugger and symbolic execution engine.\n\n* `leafleth <https://github.com/clemlak/leafleth>`_\n    A documentation generator for Solidity smart-contracts.\n\n* `Scaffold-ETH 2 <https://github.com/scaffold-eth/scaffold-eth-2>`_\n    Forkable Ethereum development stack focused on fast product iterations.\n\n* `Slippy <https://github.com/fvictorio/slippy>`_\n    A simple and powerful linter for Solidity.\n\n* `sol2uml <https://www.npmjs.com/package/sol2uml>`_\n    Unified Modeling Language (UML) class diagram generator for Solidity contracts.\n\n* `solc-select <https://github.com/crytic/solc-select>`_\n    A script to quickly switch between Solidity compiler versions.\n\n* `Solidity prettier plugin <https://github.com/prettier-solidity/prettier-plugin-solidity>`_\n    A Prettier Plugin for Solidity.\n\n* `Solidity REPL <https://github.com/raineorshine/solidity-repl>`_\n    Try Solidity instantly with a command-line Solidity console.\n\n* `solgraph <https://github.com/raineorshine/solgraph>`_\n    Visualize Solidity control flow and highlight potential security vulnerabilities.\n\n* `Solhint <https://github.com/protofire/solhint>`_\n    Solidity linter that provides security, style guide and best practice rules for smart contract validation.\n\n* `Sourcify <https://sourcify.dev/>`_\n    Decentralized automated contract verification service and public repository of contract metadata.\n\n* `Sūrya <https://github.com/ConsenSys/surya/>`_\n    Utility tool for smart contract systems, offering a number of visual outputs and information about the contracts' structure. Also supports querying the function call graph.\n\n* `Universal Mutator <https://github.com/agroce/universalmutator>`_\n    A tool for mutation generation, with configurable rules and support for Solidity and Vyper.\n\n* `Wake <https://github.com/Ackee-Blockchain/wake>`_\n    A Python-based Solidity development and testing framework with built-in vulnerability detectors.\n\nThird-Party Solidity Parsers and Grammars\n=========================================\n\n* `Solidity Parser for JavaScript <https://github.com/solidity-parser/parser>`_\n    A Solidity parser for JS built on top of a robust ANTLR4 grammar.\n"
  },
  {
    "path": "docs/robots.txt.template",
    "content": "User-Agent: *\nSitemap: http://docs.soliditylang.org/sitemap.xml\nHost: docs.soliditylang.org\n\nAllow: /en/latest/\nAllow: /en/v0.7.6/\nAllow: /en/v{{ LATEST_VERSION }}/\nAllow: /_/downloads/en/latest/\nAllow: /_/downloads/en/0.7.6/\nAllow: /_/downloads/en/{{ LATEST_VERSION }}/\n\n# Prevent documentation for the development branches and older Solidity\n# versions from showing up in search results.\nDisallow: /en/*\nDisallow: /_/downloads/en/*\n"
  },
  {
    "path": "docs/security-considerations.rst",
    "content": ".. _security_considerations:\n\n#######################\nSecurity Considerations\n#######################\n\nWhile it is usually quite easy to build software that works as expected,\nit is much harder to check that nobody can use it in a way that was **not** anticipated.\n\nIn Solidity, this is even more important because you can use smart contracts to handle tokens or,\npossibly, even more valuable things.\nFurthermore, every execution of a smart contract happens in public and,\nin addition to that, the source code is often available.\n\nOf course, you always have to consider how much is at stake:\nYou can compare a smart contract with a web service that is open to the public\n(and thus, also to malicious actors) and perhaps even open-source.\nIf you only store your grocery list on that web service, you might not have to take too much care,\nbut if you manage your bank account using that web service, you should be more careful.\n\nThis section will list some pitfalls and general security recommendations\nbut can, of course, never be complete.\nAlso, keep in mind that even if your smart contract code is bug-free,\nthe compiler or the platform itself might have a bug.\nA list of some publicly known security-relevant bugs of the compiler can be found\nin the :ref:`list of known bugs<known_bugs>`, which is also machine-readable.\nNote that there is a `Bug Bounty Program <https://ethereum.org/en/bug-bounty/>`_\nthat covers the code generator of the Solidity compiler.\n\nAs always, with open-source documentation,\nplease help us extend this section (especially, some examples would not hurt)!\n\nNOTE: In addition to the list below, you can find more security recommendations and best practices\n`in Guy Lando's knowledge list <https://github.com/guylando/KnowledgeLists/blob/master/EthereumSmartContracts.md>`_ and\n`the Consensys GitHub repo <https://consensys.github.io/smart-contract-best-practices/>`_.\n\n********\nPitfalls\n********\n\nPrivate Information and Randomness\n==================================\n\nEverything you use in a smart contract is publicly visible,\neven local variables and state variables marked ``private``.\n\nUsing random numbers in smart contracts is quite tricky if you do not want block builders to be able to cheat.\n\nReentrancy\n==========\n\nAny interaction from a contract (A) with another contract (B)\nand any transfer of Ether hands over control to that contract (B).\nThis makes it possible for B to call back into A before this interaction is completed.\nTo give an example, the following code contains a bug (it is just a snippet and not a complete contract):\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    // THIS CONTRACT CONTAINS A BUG - DO NOT USE\n    contract Fund {\n        /// @dev Mapping of ether shares of the contract.\n        mapping(address => uint) shares;\n        /// Withdraw your share.\n        function withdraw() public {\n        // This will report a warning (deprecation)\n            if (payable(msg.sender).send(shares[msg.sender]))\n                shares[msg.sender] = 0;\n        }\n    }\n\nThe problem is not too serious here because of the limited gas as part of ``send``,\nbut it still exposes a weakness:\nEther transfer can always include code execution,\nso the recipient could be a contract that calls back into ``withdraw``.\nThis would let it get multiple refunds and, basically, retrieve all the Ether in the contract.\nIn particular, the following contract will allow an attacker to refund multiple times\nas it uses ``call`` which does not limit the amount of gas that is forwarded by default:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.2 <0.9.0;\n\n    // THIS CONTRACT CONTAINS A BUG - DO NOT USE\n    contract Fund {\n        /// @dev Mapping of ether shares of the contract.\n        mapping(address => uint) shares;\n        /// Withdraw your share.\n        function withdraw() public {\n            (bool success,) = msg.sender.call{value: shares[msg.sender]}(\"\");\n            if (success)\n                shares[msg.sender] = 0;\n        }\n    }\n\nTo avoid reentrancy, you can use the Checks-Effects-Interactions pattern as demonstrated below:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.2 <0.9.0;\n\n    contract Fund {\n        /// @dev Mapping of ether shares of the contract.\n        mapping(address => uint) shares;\n        /// Withdraw your share.\n        function withdraw() public {\n            uint share = shares[msg.sender];\n            shares[msg.sender] = 0;\n            (bool success, ) = payable(msg.sender).call{value: share}(\"\");\n            require(success);\n        }\n    }\n\nThe Checks-Effects-Interactions pattern ensures that all code paths through a contract\ncomplete all required checks of the supplied parameters before modifying the contract's state (Checks);\nonly then it makes any changes to the state (Effects);\nit may make calls to functions in other contracts\n*after* all planned state changes have been written to storage (Interactions).\nThis is a common foolproof way to prevent *reentrancy attacks*,\nwhere an externally called malicious contract can double-spend an allowance,\ndouble-withdraw a balance, among other things,\nby using logic that calls back into the original contract before it has finalized its transaction.\n\nNote that reentrancy is not only an effect of Ether transfer\nbut of any function call on another contract.\nFurthermore, you also have to take multi-contract situations into account.\nA called contract could modify the state of another contract you depend on.\n\nGas Limit and Loops\n===================\n\nLoops that do not have a fixed number of iterations, for example,\nloops that depend on storage values, have to be used carefully:\nDue to the block gas limit, transactions can only consume a certain amount of gas.\nEither explicitly or just due to normal operation,\nthe number of iterations in a loop can grow beyond the block gas limit\nwhich can cause the complete contract to be stalled at a certain point.\nThis may not apply to ``view`` functions that are only executed to read data from the blockchain.\nStill, such functions may be called by other contracts as part of on-chain operations and stall those.\nPlease be explicit about such cases in the documentation of your contracts.\n\nSending and Receiving Ether\n===========================\n\n- Neither contracts nor \"externally-owned accounts\" are currently able to prevent someone from sending them Ether.\n  Contracts can react on and reject a regular transfer, but there are ways to move Ether without creating a message call.\n  One way is to simply \"mine to\" the contract address and the second way is using ``selfdestruct(x)``.\n\n- If a contract receives Ether (without a function being called), either the :ref:`receive Ether <receive-ether-function>`\n  or the :ref:`fallback <fallback-function>` function is executed.\n  If it does not have a ``receive`` nor a ``fallback`` function, the Ether will be rejected (by throwing an exception).\n  During the execution of one of these functions, the contract can only rely on the \"gas stipend\" it is passed (2300 gas)\n  being available to it at that time.\n  This stipend is not enough to modify storage (do not take this for granted though, the stipend might change with future hard forks).\n  To be sure that your contract can receive Ether in that way, check the gas requirements of the receive and fallback functions\n  (for example in the \"details\" section in Remix).\n\n- There is a way to forward more gas to the receiving contract using ``addr.call{value: x}(\"\")``.\n  This is essentially the same as ``addr.transfer(x)``, only that it forwards all remaining gas,\n  subject to additional limits imposed by some EVM versions (such as the `63/64th rule <https://eips.ethereum.org/EIPS/eip-150>`_\n  introduced by ``tangerineWhistle``), and opens up the ability for the recipient to perform more expensive actions\n  (and it returns a failure code instead of automatically propagating the error).\n  This might include calling back into the sending contract or other state changes you might not have thought of.\n  So it allows for great flexibility for honest users but also for malicious actors.\n\n- Use the most precise units to represent the Wei amount as possible, as you lose any that is rounded due to a lack of precision.\n\n- If you want to send Ether using ``address.transfer``, there are certain details to be aware of:\n\n  1. If the recipient is a contract, it causes its receive or fallback function\n     to be executed which can, in turn, call back the sending contract.\n  2. Sending Ether can fail due to the call depth going above 1024. Since the\n     caller is in total control of the call depth, they can force the\n     transfer to fail; take this possibility into account or use ``send`` and\n     make sure to always check its return value. Better yet, write your\n     contract using a pattern where the recipient can withdraw Ether instead.\n  3. Sending Ether can also fail because the execution of the recipient\n     contract requires more than the allotted amount of gas (explicitly by\n     using :ref:`require <assert-and-require>`, :ref:`assert <assert-and-require>`,\n     :ref:`revert <assert-and-require>` or because the\n     operation is too expensive) - it \"runs out of gas\" (OOG).  If you\n     use ``transfer`` or ``send`` with a return value check, this might\n     provide a means for the recipient to block progress in the sending\n     contract. Again, the best practice here is to use a :ref:`\"withdraw\"\n     pattern instead of a \"send\" pattern <withdrawal_pattern>`.\n\nCall Stack Depth\n================\n\nExternal function calls can fail at any time\nbecause they exceed the maximum call stack size limit of 1024.\nIn such situations, Solidity throws an exception.\nMalicious actors might be able to force the call stack to a high value\nbefore they interact with your contract.\nNote that, since `Tangerine Whistle <https://eips.ethereum.org/EIPS/eip-608>`_ hardfork,\nthe `63/64 rule <https://eips.ethereum.org/EIPS/eip-150>`_ makes call stack depth attack impractical.\nAlso note that the call stack and the expression stack are unrelated,\neven though both have a size limit of 1024 stack slots.\n\nNote that ``.send()`` does **not** throw an exception if the call stack is depleted\nbut rather returns ``false`` in that case.\nThe low-level functions ``.call()``, ``.delegatecall()`` and ``.staticcall()`` behave in the same way.\n\nAuthorized Proxies\n==================\n\nIf your contract can act as a proxy, i.e. if it can call arbitrary contracts with user-supplied data,\nthen the user can essentially assume the identity of the proxy contract.\nEven if you have other protective measures in place, it is best to build your contract system such\nthat the proxy does not have any permissions (not even for itself).\nIf needed, you can accomplish that using a second proxy:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.0;\n    contract ProxyWithMoreFunctionality {\n        PermissionlessProxy proxy;\n\n        function callOther(address addr, bytes memory payload) public\n                returns (bool, bytes memory) {\n            return proxy.callOther(addr, payload);\n        }\n        // Other functions and other functionality\n    }\n\n    // This is the full contract, it has no other functionality and\n    // requires no privileges to work.\n    contract PermissionlessProxy {\n        function callOther(address addr, bytes memory payload) public\n                returns (bool, bytes memory) {\n            return addr.call(payload);\n        }\n    }\n\ntx.origin\n=========\n\nNever use ``tx.origin`` for authorization.\nLet's say you have a wallet contract like this:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n    // THIS CONTRACT CONTAINS A BUG - DO NOT USE\n    contract TxUserWallet {\n        address owner;\n\n        constructor() {\n            owner = msg.sender;\n        }\n\n        function transferTo(address payable dest, uint amount) public {\n            // THE BUG IS RIGHT HERE, you must use msg.sender instead of tx.origin\n            require(tx.origin == owner);\n            // This will report a warning (deprecation)\n            dest.transfer(amount);\n        }\n    }\n\nNow someone tricks you into sending Ether to the address of this attack wallet:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n    interface TxUserWallet {\n        function transferTo(address payable dest, uint amount) external;\n    }\n\n    contract TxAttackWallet {\n        address payable owner;\n\n        constructor() {\n            owner = payable(msg.sender);\n        }\n\n        receive() external payable {\n            TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance);\n        }\n    }\n\nIf your wallet had checked ``msg.sender`` for authorization, it would get the address of the attack wallet,\ninstead of the owner's address.\nBut by checking ``tx.origin``, it gets the original address that kicked off the transaction,\nwhich is still the owner's address.\nThe attack wallet instantly drains all your funds.\n\n.. _underflow-overflow:\n\nTwo's Complement / Underflows / Overflows\n=========================================\n\nAs in many programming languages, Solidity's integer types are not actually integers.\nThey resemble integers when the values are small, but cannot represent arbitrarily large numbers.\n\nThe following code causes an overflow because the result of the addition is too large\nto be stored in the type ``uint8``:\n\n.. code-block:: solidity\n\n  uint8 x = 255;\n  uint8 y = 1;\n  return x + y;\n\nSolidity has two modes in which it deals with these overflows: Checked and Unchecked or \"wrapping\" mode.\n\nThe default checked mode will detect overflows and cause a failing assertion. You can disable this check\nusing ``unchecked { ... }``, causing the overflow to be silently ignored. The above code would return\n``0`` if wrapped in ``unchecked { ... }``.\n\nEven in checked mode, do not assume you are protected from overflow bugs.\nIn this mode, overflows will always revert. If it is not possible to avoid the\noverflow, this can lead to a smart contract being stuck in a certain state.\n\nIn general, read about the limits of two's complement representation, which even has some\nmore special edge cases for signed numbers.\n\nTry to use ``require`` to limit the size of inputs to a reasonable range and use the\n:ref:`SMT checker<smt_checker>` to find potential overflows.\n\n.. _clearing-mappings:\n\nClearing Mappings\n=================\n\nThe Solidity type ``mapping`` (see :ref:`mapping-types`) is a storage-only key-value data structure\nthat does not keep track of the keys that were assigned a non-zero value.\nBecause of that, cleaning a mapping without extra information about the written keys is not possible.\nIf a ``mapping`` is used as the base type of a dynamic storage array,\ndeleting or popping the array will have no effect over the ``mapping`` elements.\nThe same happens, for example, if a ``mapping`` is used as the type of a member field of a ``struct``\nthat is the base type of a dynamic storage array.\nThe ``mapping`` is also ignored in assignments of structs or arrays containing a ``mapping``.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    contract Map {\n        mapping(uint => uint)[] array;\n\n        function allocate(uint newMaps) public {\n            for (uint i = 0; i < newMaps; i++)\n                array.push();\n        }\n\n        function writeMap(uint map, uint key, uint value) public {\n            array[map][key] = value;\n        }\n\n        function readMap(uint map, uint key) public view returns (uint) {\n            return array[map][key];\n        }\n\n        function eraseMaps() public {\n            delete array;\n        }\n    }\n\nConsider the example above and the following sequence of calls: ``allocate(10)``, ``writeMap(4, 128, 256)``.\nAt this point, calling ``readMap(4, 128)`` returns 256.\nIf we call ``eraseMaps``, the length of the state variable ``array`` is zeroed,\nbut since its ``mapping`` elements cannot be zeroed, their information stays alive in the contract's storage.\nAfter deleting ``array``, calling ``allocate(5)`` allows us to access ``array[4]`` again,\nand calling ``readMap(4, 128)`` returns 256 even without another call to ``writeMap``.\n\nIf your ``mapping`` information must be deleted, consider using a library similar to\n`iterable mapping <https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol>`_,\nallowing you to traverse the keys and delete their values in the appropriate ``mapping``.\n\nInternal Function Pointers in Upgradeable Contracts\n===================================================\n\nUpdating the code of your contract may :ref:`invalidate the values of variables of internal function\ntypes<function-type-value-stability-across-contract-updates>`.\nConsider such values ephemeral and avoid storing them in state variables.\nIf you do, you must ensure that they never persist across code updates and are never used by\nother contracts having access to the same storage space as a result of a delegatecall or account\nabstraction.\n\nMinor Details\n=============\n\n- Types that do not occupy the full 32 bytes might contain \"dirty higher order bits\".\n  This is especially important if you access ``msg.data`` - it poses a malleability risk:\n  You can craft transactions that call a function ``f(uint8 x)``\n  with a raw byte argument of ``0xff000001`` and with ``0x00000001``.\n  Both are fed to the contract and both will look like the number ``1`` as far as ``x`` is concerned,\n  but ``msg.data`` will be different, so if you use ``keccak256(msg.data)`` for anything,\n  you will get different results.\n\n***************\nRecommendations\n***************\n\nTake Warnings Seriously\n=======================\n\nIf the compiler warns you about something, you should change it.\nEven if you do not think that this particular warning has security implications,\nthere might be another issue buried beneath it.\nAny compiler warning we issue can be silenced by slight changes to the code.\n\nAlways use the latest version of the compiler to be notified about all recently introduced warnings.\n\nMessages of type ``info``, issued by the compiler, are not dangerous\nand simply represent extra suggestions and optional information\nthat the compiler thinks might be useful to the user.\n\nRestrict the Amount of Ether\n============================\n\nRestrict the amount of Ether (or other tokens) that can be stored in a smart contract.\nIf your source code, the compiler or the platform has a bug, these funds may be lost.\nIf you want to limit your loss, limit the amount of Ether.\n\nKeep it Small and Modular\n=========================\n\nKeep your contracts small and easily understandable.\nSingle out unrelated functionality in other contracts or into libraries.\nGeneral recommendations about the source code quality of course apply:\nLimit the amount of local variables, the length of functions and so on.\nDocument your functions so that others can see what your intention was\nand whether it is different than what the code does.\n\nUse the Checks-Effects-Interactions Pattern\n===========================================\n\nMost functions will first perform some checks and they should be done first\n(who called the function, are the arguments in range, did they send enough Ether,\ndoes the person have tokens, etc.).\n\nAs the second step, if all checks passed, effects to the state variables of the current contract should be made.\nInteraction with other contracts should be the very last step in any function.\n\nEarly contracts delayed some effects and waited for external function calls to return in a non-error state.\nThis is often a serious mistake because of the reentrancy problem explained above.\n\nNote that, also, calls to known contracts might in turn cause calls to\nunknown contracts, so it is probably better to just always apply this pattern.\n\nInclude a Fail-Safe Mode\n========================\n\nWhile making your system fully decentralized will remove any intermediary,\nit might be a good idea, especially for new code, to include some kind of fail-safe mechanism:\n\nYou can add a function in your smart contract that performs some self-checks like \"Has any Ether leaked?\",\n\"Is the sum of the tokens equal to the balance of the contract?\" or similar things.\nKeep in mind that you cannot use too much gas for that,\nso help through off-chain computations might be needed there.\n\nIf the self-check fails, the contract automatically switches into some kind of \"failsafe\" mode,\nwhich, for example, disables most of the features,\nhands over control to a fixed and trusted third party\nor just converts the contract into a simple \"give me back my Ether\" contract.\n\nAsk for Peer Review\n===================\n\nThe more people examine a piece of code, the more issues are found.\nAsking people to review your code also helps as a cross-check to find out\nwhether your code is easy to understand -\na very important criterion for good smart contracts.\n"
  },
  {
    "path": "docs/smtchecker.rst",
    "content": ".. _formal_verification:\n\n##################################\nSMTChecker and Formal Verification\n##################################\n\nUsing formal verification it is possible to perform an automated mathematical\nproof that your source code fulfills a certain formal specification.\nThe specification is still formal (just as the source code), but usually much\nsimpler.\n\nNote that formal verification itself can only help you understand the\ndifference between what you did (the specification) and how you did it\n(the actual implementation). You still need to check whether the specification\nis what you wanted and that you did not miss any unintended effects of it.\n\nSolidity implements a formal verification approach based on\n`SMT (Satisfiability Modulo Theories) <https://en.wikipedia.org/wiki/Satisfiability_modulo_theories>`_ and\n`Horn <https://en.wikipedia.org/wiki/Horn-satisfiability>`_ solving.\nThe SMTChecker module automatically tries to prove that the code satisfies the\nspecification given by ``require`` and ``assert`` statements. That is, it considers\n``require`` statements as assumptions and tries to prove that the conditions\ninside ``assert`` statements are always true.  If an assertion failure is\nfound, a counterexample may be given to the user showing how the assertion can\nbe violated. If no warning is given by the SMTChecker for a property,\nit means that the property is safe.\n\nThe other verification targets that the SMTChecker checks at compile time are:\n\n- Arithmetic underflow and overflow.\n- Division by zero.\n- Trivial conditions and unreachable code.\n- Popping an empty array.\n- Out of bounds index access.\n- Insufficient funds for a transfer.\n\nAll the targets above are automatically checked by default if all engines are\nenabled, except underflow and overflow for Solidity >=0.8.7.\n\nThe potential warnings that the SMTChecker reports are:\n\n- ``<failing  property> happens here.``. This means that the SMTChecker proved that a certain property fails. A counterexample may be given, however in complex situations it may also not show a counterexample. This result may also be a false positive in certain cases, when the SMT encoding adds abstractions for Solidity code that is either hard or impossible to express.\n- ``<failing property> might happen here``. This means that the solver could not prove either case within the given timeout. Since the result is unknown, the SMTChecker reports the potential failure for soundness. This may be solved by increasing the query timeout, but the problem might also simply be too hard for the engine to solve.\n\nTo enable the SMTChecker, you must select :ref:`which engine should run<smtchecker_engines>`,\nwhere the default is no engine. Selecting the engine enables the SMTChecker on all files.\n\n.. note::\n\n    Prior to Solidity 0.8.4, the default way to enable the SMTChecker was via\n    ``pragma experimental SMTChecker;`` and only the contracts containing the\n    pragma would be analyzed. That pragma has been deprecated, and although it\n    still enables the SMTChecker for backwards compatibility, it will be removed\n    in Solidity 0.9.0. Note also that now using the pragma even in a single file\n    enables the SMTChecker for all files.\n\n.. note::\n\n    The lack of warnings for a verification target represents an undisputed\n    mathematical proof of correctness, assuming no bugs in the SMTChecker and\n    the underlying solver. Keep in mind that these problems are\n    *very hard* and sometimes *impossible* to solve automatically in the\n    general case.  Therefore, several properties might not be solved or might\n    lead to false positives for large contracts. Every proven property should\n    be seen as an important achievement. For advanced users, see :ref:`SMTChecker Tuning <smtchecker_options>`\n    to learn a few options that might help proving more complex\n    properties.\n\n********\nTutorial\n********\n\nOverflow\n========\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    contract Overflow {\n        uint immutable x;\n        uint immutable y;\n\n        function add(uint x_, uint y_) internal pure returns (uint) {\n            return x_ + y_;\n        }\n\n        constructor(uint x_, uint y_) {\n            (x, y) = (x_, y_);\n        }\n\n        function stateAdd() public view returns (uint) {\n            return add(x, y);\n        }\n    }\n\nThe contract above shows an overflow check example.\nThe SMTChecker does not check underflow and overflow by default for Solidity >=0.8.7,\nso we need to use the command-line option ``--model-checker-targets \"underflow,overflow\"``\nor the JSON option ``settings.modelChecker.targets = [\"underflow\", \"overflow\"]``.\nSee :ref:`this section for targets configuration<smtchecker_targets>`.\nHere, it reports the following:\n\n.. code-block:: text\n\n    Warning: CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n    Counterexample:\n    x = 1, y = 115792089237316195423570985008687907853269984665640564039457584007913129639935\n     = 0\n\n    Transaction trace:\n    Overflow.constructor(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935)\n    State: x = 1, y = 115792089237316195423570985008687907853269984665640564039457584007913129639935\n    Overflow.stateAdd()\n        Overflow.add(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935) -- internal call\n     --> o.sol:9:20:\n      |\n    9 |             return x_ + y_;\n      |                    ^^^^^^^\n\nIf we add ``require`` statements that filter out overflow cases,\nthe SMTChecker proves that no overflow is reachable (by not reporting warnings):\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    contract Overflow {\n        uint immutable x;\n        uint immutable y;\n\n        function add(uint x_, uint y_) internal pure returns (uint) {\n            return x_ + y_;\n        }\n\n        constructor(uint x_, uint y_) {\n            (x, y) = (x_, y_);\n        }\n\n        function stateAdd() public view returns (uint) {\n            require(x < type(uint128).max);\n            require(y < type(uint128).max);\n            return add(x, y);\n        }\n    }\n\n\nAssert\n======\n\nAn assertion represents an invariant in your code: a property that must be true\n*for all transactions, including all input and storage values*, otherwise there is a bug.\n\nThe code below defines a function ``f`` that guarantees no overflow.\nFunction ``inv`` defines the specification that ``f`` is monotonically increasing:\nfor every possible pair ``(a, b)``, if ``b > a`` then ``f(b) > f(a)``.\nSince ``f`` is indeed monotonically increasing, the SMTChecker proves that our\nproperty is correct. You are encouraged to play with the property and the function\ndefinition to see what results come out!\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    contract Monotonic {\n        function f(uint x) internal pure returns (uint) {\n            require(x < type(uint128).max);\n            return x * 42;\n        }\n\n        function inv(uint a, uint b) public pure {\n            require(b > a);\n            assert(f(b) > f(a));\n        }\n    }\n\nWe can also add assertions inside loops to verify more complicated properties.\nThe following code searches for the maximum element of an unrestricted array of\nnumbers, and asserts the property that the found element must be greater or\nequal every element in the array.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    contract Max {\n        function max(uint[] memory a) public pure returns (uint) {\n            uint m = 0;\n            for (uint i = 0; i < a.length; ++i)\n                if (a[i] > m)\n                    m = a[i];\n\n            for (uint i = 0; i < a.length; ++i)\n                assert(m >= a[i]);\n\n            return m;\n        }\n    }\n\nNote that in this example the SMTChecker will automatically try to prove three properties:\n\n1. ``++i`` in the first loop does not overflow.\n2. ``++i`` in the second loop does not overflow.\n3. The assertion is always true.\n\n.. note::\n\n    The properties involve loops, which makes it *much much* harder than the previous\n    examples, so beware of loops!\n\nAll the properties are correctly proven safe. Feel free to change the\nproperties and/or add restrictions on the array to see different results.\nFor example, changing the code to\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    contract Max {\n        function max(uint[] memory a) public pure returns (uint) {\n            require(a.length >= 5);\n            uint m = 0;\n            for (uint i = 0; i < a.length; ++i)\n                if (a[i] > m)\n                    m = a[i];\n\n            for (uint i = 0; i < a.length; ++i)\n                assert(m > a[i]);\n\n            return m;\n        }\n    }\n\ngives us:\n\n.. code-block:: text\n\n    Warning: CHC: Assertion violation happens here.\n    Counterexample:\n\n    a = [0, 0, 0, 0, 0]\n     = 0\n\n    Transaction trace:\n    Test.constructor()\n    Test.max([0, 0, 0, 0, 0])\n      --> max.sol:14:4:\n       |\n    14 |            assert(m > a[i]);\n\n\nState Properties\n================\n\nSo far the examples only demonstrated the use of the SMTChecker over pure code,\nproving properties about specific operations or algorithms.\nA common type of properties in smart contracts are properties that involve the\nstate of the contract. Multiple transactions might be needed to make an assertion\nfail for such a property.\n\nAs an example, consider a 2D grid where both axis have coordinates in the range (-2^127, 2^127 - 1).\nLet us place a robot at position (0, 0). The robot can only move diagonally, one step at a time,\nand cannot move outside the grid. The robot's state machine can be represented by the smart contract\nbelow.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    contract Robot {\n        int x = 0;\n        int y = 0;\n\n        modifier wall {\n            require(x > type(int128).min && x < type(int128).max);\n            require(y > type(int128).min && y < type(int128).max);\n            _;\n        }\n\n        function moveLeftUp() wall public {\n            --x;\n            ++y;\n        }\n\n        function moveLeftDown() wall public {\n            --x;\n            --y;\n        }\n\n        function moveRightUp() wall public {\n            ++x;\n            ++y;\n        }\n\n        function moveRightDown() wall public {\n            ++x;\n            --y;\n        }\n\n        function inv() public view {\n            assert((x + y) % 2 == 0);\n        }\n    }\n\nFunction ``inv`` represents an invariant of the state machine that ``x + y``\nmust be even.\nThe SMTChecker manages to prove that regardless how many commands we give the\nrobot, even if infinitely many, the invariant can *never* fail. The interested\nreader may want to prove that fact manually as well.  Hint: this invariant is\ninductive.\n\nWe can also trick the SMTChecker into giving us a path to a certain position we\nthink might be reachable.  We can add the property that (2, 4) is *not*\nreachable, by adding the following function.\n\n.. code-block:: solidity\n\n    function reach_2_4() public view {\n        assert(!(x == 2 && y == 4));\n    }\n\nThis property is false, and while proving that the property is false,\nthe SMTChecker tells us exactly *how* to reach (2, 4):\n\n.. code-block:: text\n\n    Warning: CHC: Assertion violation happens here.\n    Counterexample:\n    x = 2, y = 4\n\n    Transaction trace:\n    Robot.constructor()\n    State: x = 0, y = 0\n    Robot.moveLeftUp()\n    State: x = (- 1), y = 1\n    Robot.moveRightUp()\n    State: x = 0, y = 2\n    Robot.moveRightUp()\n    State: x = 1, y = 3\n    Robot.moveRightUp()\n    State: x = 2, y = 4\n    Robot.reach_2_4()\n      --> r.sol:35:4:\n       |\n    35 |            assert(!(x == 2 && y == 4));\n       |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nNote that the path above is not necessarily deterministic, as there are\nother paths that could reach (2, 4). The choice of which path is shown\nmight change depending on the used solver, its version, or just randomly.\n\nExternal Calls and Reentrancy\n=============================\n\nEvery external call is treated as a call to unknown code by the SMTChecker.\nThe reasoning behind that is that even if the code of the called contract is\navailable at compile time, there is no guarantee that the deployed contract\nwill indeed be the same as the contract where the interface came from at\ncompile time.\n\nIn some cases, it is possible to automatically infer properties over state\nvariables that are still true even if the externally called code can do\nanything, including reenter the caller contract.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    interface Unknown {\n        function run() external;\n    }\n\n    contract Mutex {\n        uint x;\n        bool lock;\n\n        Unknown immutable unknown;\n\n        constructor(Unknown u) {\n            require(address(u) != address(0));\n            unknown = u;\n        }\n\n        modifier mutex {\n            require(!lock);\n            lock = true;\n            _;\n            lock = false;\n        }\n\n        function set(uint x_) mutex public {\n            x = x_;\n        }\n\n        function run() mutex public {\n            uint xPre = x;\n            unknown.run();\n            assert(xPre == x);\n        }\n    }\n\nThe example above shows a contract that uses a mutex flag to forbid reentrancy.\nThe solver is able to infer that when ``unknown.run()`` is called, the contract\nis already \"locked\", so it would not be possible to change the value of ``x``,\nregardless of what the unknown called code does.\n\nIf we \"forget\" to use the ``mutex`` modifier on function ``set``, the\nSMTChecker is able to synthesize the behavior of the externally called code so\nthat the assertion fails:\n\n.. code-block:: text\n\n    Warning: CHC: Assertion violation happens here.\n    Counterexample:\n    x = 1, lock = true, unknown = 1\n\n    Transaction trace:\n    Mutex.constructor(1)\n    State: x = 0, lock = false, unknown = 1\n    Mutex.run()\n        unknown.run() -- untrusted external call, synthesized as:\n            Mutex.set(1) -- reentrant call\n      --> m.sol:32:3:\n       |\n    32 | \t\tassert(xPre == x);\n       | \t\t^^^^^^^^^^^^^^^^^\n\n\n.. _smtchecker_options:\n\n*****************************\nSMTChecker Options and Tuning\n*****************************\n\nTimeout\n=======\n\nThe SMTChecker uses a hardcoded resource limit (``rlimit``) chosen per solver,\nwhich is not precisely related to time. We chose the ``rlimit`` option as the default\nbecause it gives more determinism guarantees than time inside the solver.\n\nThis options translates roughly to \"a few seconds timeout\" per query. Of course many properties\nare very complex and need a lot of time to be solved, where determinism does not matter.\nIf the SMTChecker does not manage to solve the contract properties with the default ``rlimit``,\na timeout can be given in milliseconds via the CLI option ``--model-checker-timeout <time>`` or\nthe JSON option ``settings.modelChecker.timeout=<time>``, where 0 means no timeout.\n\n.. _smtchecker_targets:\n\nVerification Targets\n====================\n\nThe types of verification targets created by the SMTChecker can also be\ncustomized via the CLI option ``--model-checker-target <targets>`` or the JSON\noption ``settings.modelChecker.targets=<targets>``.\nIn the CLI case, ``<targets>`` is a no-space-comma-separated list of one or\nmore verification targets, and an array of one or more targets as strings in\nthe JSON input.\nThe keywords that represent the targets are:\n\n- Assertions: ``assert``.\n- Arithmetic underflow: ``underflow``.\n- Arithmetic overflow: ``overflow``.\n- Division by zero: ``divByZero``.\n- Trivial conditions and unreachable code: ``constantCondition``.\n- Popping an empty array: ``popEmptyArray``.\n- Out of bounds array/fixed bytes index access: ``outOfBounds``.\n- Insufficient funds for a transfer: ``balance``.\n- All of the above: ``default`` (CLI only).\n\nA common subset of targets might be, for example:\n``--model-checker-targets assert,overflow``.\n\nAll targets are checked by default, except underflow and overflow for Solidity >=0.8.7.\n\nThere is no precise heuristic on how and when to split verification targets,\nbut it can be useful especially when dealing with large contracts.\n\nProved Targets\n==============\n\nIf there are any proved targets, the SMTChecker issues one warning per engine stating\nhow many targets were proved. If the user wishes to see all the specific\nproved targets, the CLI option ``--model-checker-show-proved-safe`` and\nthe JSON option ``settings.modelChecker.showProvedSafe = true`` can be used.\n\nUnproved Targets\n================\n\nIf there are any unproved targets, the SMTChecker issues one warning stating\nhow many unproved targets there are. If the user wishes to see all the specific\nunproved targets, the CLI option ``--model-checker-show-unproved`` and\nthe JSON option ``settings.modelChecker.showUnproved = true`` can be used.\n\nUnsupported Language Features\n=============================\n\nCertain Solidity language features are not completely supported by the SMT\nencoding that the SMTChecker applies, for example assembly blocks.\nThe unsupported construct is abstracted via overapproximation to preserve\nsoundness, meaning any properties reported safe are safe even though this\nfeature is unsupported.\nHowever such abstraction may cause false positives when the target properties\ndepend on the precise behavior of the unsupported feature.\nIf the encoder encounters such cases it will by default report a generic warning\nstating how many unsupported features it has seen.\nIf the user wishes to see all the specific unsupported features, the CLI option\n``--model-checker-show-unsupported`` and the JSON option\n``settings.modelChecker.showUnsupported = true`` can be used, where their default\nvalue is ``false``.\n\nVerified Contracts\n==================\n\nBy default all the deployable contracts in the given sources are analyzed separately as\nthe one that will be deployed. This means that if a contract has many direct\nand indirect inheritance parents, all of them will be analyzed on their own,\neven though only the most derived will be accessed directly on the blockchain.\nThis causes an unnecessary burden on the SMTChecker and the solver.  To aid\ncases like this, users can specify which contracts should be analyzed as the\ndeployed one. The parent contracts are of course still analyzed, but only in\nthe context of the most derived contract, reducing the complexity of the\nencoding and generated queries. Note that abstract contracts are by default\nnot analyzed as the most derived by the SMTChecker.\n\nThe chosen contracts can be given via a comma-separated list (whitespace is not\nallowed) of <source>:<contract> pairs in the CLI:\n``--model-checker-contracts \"<source1.sol:contract1>,<source2.sol:contract2>,<source2.sol:contract3>\"``,\nand via the object ``settings.modelChecker.contracts`` in the :ref:`JSON input<compiler-api>`,\nwhich has the following form:\n\n.. code-block:: json\n\n    \"contracts\": {\n        \"source1.sol\": [\"contract1\"],\n        \"source2.sol\": [\"contract2\", \"contract3\"]\n    }\n\nTrusted External Calls\n======================\n\nBy default, the SMTChecker does not assume that compile-time available code\nis the same as the runtime code for external calls. Take the following contracts\nas an example:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    contract Ext {\n        uint public x;\n        function setX(uint _x) public { x = _x; }\n    }\n    contract MyContract {\n        function callExt(Ext _e) public {\n            _e.setX(42);\n            assert(_e.x() == 42);\n        }\n    }\n\nWhen ``MyContract.callExt`` is called, an address is given as the argument.\nAt deployment time, we cannot know for sure that address ``_e`` actually\ncontains a deployment of contract ``Ext``.\nTherefore, the SMTChecker will warn that the assertion above can be violated,\nwhich is true, if ``_e`` contains another contract than ``Ext``.\n\nHowever, it can be useful to treat these external calls as trusted, for example,\nto test that different implementations of an interface conform to the same property.\nThis means assuming that address ``_e`` indeed was deployed as contract ``Ext``.\nThis mode can be enabled via the CLI option ``--model-checker-ext-calls=trusted``\nor the JSON field ``settings.modelChecker.extCalls: \"trusted\"``.\n\nPlease be aware that enabling this mode can make the SMTChecker analysis much more\ncomputationally costly.\n\nAn important part of this mode is that it is applied to contract types and high\nlevel external calls to contracts, and not low level calls such as ``call`` and\n``delegatecall``. The storage of an address is stored per contract type, and\nthe SMTChecker assumes that an externally called contract has the type of the\ncaller expression.  Therefore, casting an ``address`` or a contract to\ndifferent contract types will yield different storage values and can give\nunsound results if the assumptions are inconsistent, such as the example below:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    contract D {\n        constructor(uint _x) { x = _x; }\n        uint public x;\n        function setX(uint _x) public { x = _x; }\n    }\n\n    contract E {\n        constructor() { x = 2; }\n        uint public x;\n        function setX(uint _x) public { x = _x; }\n    }\n\n    contract C {\n        function f() public {\n            address d = address(new D(42));\n\n            // `d` was deployed as `D`, so its `x` should be 42 now.\n            assert(D(d).x() == 42); // should hold\n            assert(D(d).x() == 43); // should fail\n\n            // E and D have the same interface, so the following\n            // call would also work at runtime.\n            // However, the change to `E(d)` is not reflected in `D(d)`.\n            E(d).setX(1024);\n\n            // Reading from `D(d)` now will show old values.\n            // The assertion below should fail at runtime,\n            // but succeeds in this mode's analysis (unsound).\n            assert(D(d).x() == 42);\n            // The assertion below should succeed at runtime,\n            // but fails in this mode's analysis (false positive).\n            assert(D(d).x() == 1024);\n        }\n    }\n\nDue to the above, make sure that the trusted external calls to a certain\nvariable of ``address`` or ``contract`` type always have the same caller\nexpression type.\n\nIt is also helpful to cast the called contract's variable as the type of the\nmost derived type in case of inheritance.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    interface Token {\n        function balanceOf(address _a) external view returns (uint);\n        function transfer(address _to, uint _amt) external;\n    }\n\n    contract TokenCorrect is Token {\n        mapping (address => uint) balance;\n        constructor(address _a, uint _b) {\n            balance[_a] = _b;\n        }\n        function balanceOf(address _a) public view override returns (uint) {\n            return balance[_a];\n        }\n        function transfer(address _to, uint _amt) public override {\n            require(balance[msg.sender] >= _amt);\n            balance[msg.sender] -= _amt;\n            balance[_to] += _amt;\n        }\n    }\n\n    contract Test {\n        function property_transfer(address _token, address _to, uint _amt) public {\n            require(_to != address(this));\n\n            TokenCorrect t = TokenCorrect(_token);\n\n            uint xPre = t.balanceOf(address(this));\n            require(xPre >= _amt);\n            uint yPre = t.balanceOf(_to);\n\n            t.transfer(_to, _amt);\n            uint xPost = t.balanceOf(address(this));\n            uint yPost = t.balanceOf(_to);\n\n            assert(xPost == xPre - _amt);\n            assert(yPost == yPre + _amt);\n        }\n    }\n\nNote that in function ``property_transfer``, the external calls are\nperformed on variable ``t``.\n\nAnother caveat of this mode are calls to state variables of contract type\noutside the analyzed contract. In the code below, even though ``B`` deploys\n``A``, it is also possible for the address stored in ``B.a`` to be called by\nanyone outside of ``B`` in between transactions to ``B`` itself. To reflect the\npossible changes to ``B.a``, the encoding allows an unbounded number of calls\nto be made to ``B.a`` externally. The encoding will keep track of ``B.a``'s\nstorage, therefore assertion (2) should hold. However, currently the encoding\nallows such calls to be made from ``B`` conceptually, therefore assertion (3)\nfails.  Making the encoding stronger logically is an extension of the trusted\nmode and is under development. Note that the encoding does not keep track of\nstorage for ``address`` variables, therefore if ``B.a`` had type ``address``\nthe encoding would assume that its storage does not change in between\ntransactions to ``B``.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    contract A {\n        uint public x;\n        address immutable public owner;\n        constructor() {\n            owner = msg.sender;\n        }\n        function setX(uint _x) public {\n            require(msg.sender == owner);\n            x = _x;\n        }\n    }\n\n    contract B {\n        A a;\n        constructor() {\n            a = new A();\n            assert(a.x() == 0); // (1) should hold\n        }\n        function g() public view {\n            assert(a.owner() == address(this)); // (2) should hold\n            assert(a.x() == 0); // (3) should hold, but fails due to a false positive\n        }\n    }\n\nReported Inferred Inductive Invariants\n======================================\n\nFor properties that were proved safe with the CHC engine,\nthe SMTChecker can retrieve inductive invariants that were inferred by the Horn\nsolver as part of the proof.\nCurrently only two types of invariants can be reported to the user:\n\n- Contract Invariants: these are properties over the contract's state variables\n  that are true before and after every possible transaction that the contract may ever run. For example, ``x >= y``, where ``x`` and ``y`` are a contract's state variables.\n- Reentrancy Properties: they represent the behavior of the contract\n  in the presence of external calls to unknown code. These properties can express a relation\n  between the value of the state variables before and after the external call, where the external call is free to do anything, including making reentrant calls to the analyzed contract. Primed variables represent the state variables' values after said external call. Example: ``lock -> x = x'``.\n\nThe user can choose the type of invariants to be reported using the CLI option ``--model-checker-invariants \"contract,reentrancy\"`` or as an array in the field ``settings.modelChecker.invariants`` in the :ref:`JSON input<compiler-api>`.\nBy default the SMTChecker does not report invariants.\n\nDivision and Modulo With Slack Variables\n========================================\n\nSpacer, the default Horn solver used by the SMTChecker, often dislikes division\nand modulo operations inside Horn rules. Because of that, by default the\nSolidity division and modulo operations are encoded using the constraint\n``a = b * d + m`` where ``d = a / b`` and ``m = a % b``.\nHowever, other solvers, such as Eldarica, prefer the syntactically precise operations.\nThe command-line flag ``--model-checker-div-mod-no-slacks`` and the JSON option\n``settings.modelChecker.divModNoSlacks`` can be used to toggle the encoding\ndepending on the used solver preferences.\n\nNatspec Function Abstraction\n============================\n\nCertain functions including common math methods such as ``pow``\nand ``sqrt`` may be too complex to be analyzed in a fully automated way.\nThese functions can be annotated with Natspec tags that indicate to the\nSMTChecker that these functions should be abstracted. This means that the\nbody of the function is not used, and when called, the function will:\n\n- Return a nondeterministic value, and either keep the state variables unchanged if the abstracted function is view/pure, or also set the state variables to nondeterministic values otherwise. This can be used via the annotation ``/// @custom:smtchecker abstract-function-nondet``.\n- Act as an uninterpreted function. This means that the semantics of the function (given by the body) are ignored, and the only property this function has is that given the same input it guarantees the same output. This is currently under development and will be available via the annotation ``/// @custom:smtchecker abstract-function-uf``.\n\n.. _smtchecker_engines:\n\nModel Checking Engines\n======================\n\nThe SMTChecker module implements two different reasoning engines, a Bounded\nModel Checker (BMC) and a system of Constrained Horn Clauses (CHC).  Both\nengines are currently under development, and have different characteristics.\nThe engines are independent and every property warning states from which engine\nit came. Note that all the examples above with counterexamples were\nreported by CHC, the more powerful engine.\n\nBy default both engines are used, where CHC runs first, and every property that\nwas not proven is passed over to BMC. You can choose a specific engine via the CLI\noption ``--model-checker-engine {all,bmc,chc,none}`` or the JSON option\n``settings.modelChecker.engine={all,bmc,chc,none}``.\n\nBounded Model Checker (BMC)\n---------------------------\n\nThe BMC engine analyzes functions in isolation, that is, it does not take the\noverall behavior of the contract over multiple transactions into account when\nanalyzing each function.  Loops are also ignored in this engine at the moment.\nInternal function calls are inlined as long as they are not recursive, directly\nor indirectly. External function calls are inlined if possible. Knowledge\nthat is potentially affected by reentrancy is erased.\n\nThe characteristics above make BMC prone to reporting false positives,\nbut it is also lightweight and should be able to quickly find small local bugs.\n\nConstrained Horn Clauses (CHC)\n------------------------------\n\nA contract's Control Flow Graph (CFG) is modelled as a system of\nHorn clauses, where the life cycle of the contract is represented by a loop\nthat can visit every public/external function non-deterministically. This way,\nthe behavior of the entire contract over an unbounded number of transactions\nis taken into account when analyzing any function. Loops are fully supported\nby this engine. Internal function calls are supported, and external function\ncalls assume the called code is unknown and can do anything.\n\nThe CHC engine is much more powerful than BMC in terms of what it can prove,\nand might require more computing resources.\n\nSMT and Horn solvers\n====================\n\nThe two engines detailed above use automated theorem provers as their logical\nbackends.  BMC uses an SMT solver, whereas CHC uses a Horn solver. Often the\nsame tool can act as both, as seen in `z3 <https://github.com/Z3Prover/z3>`_,\nwhich is primarily an SMT solver and makes `Spacer\n<https://spacer.bitbucket.io/>`_ available as a Horn solver, and `Eldarica\n<https://github.com/uuverifiers/eldarica>`_ which does both.\n\nThe user can choose which solvers should be used, if available, via the CLI\noption ``--model-checker-solvers {all,cvc5,eld,smtlib2,z3}`` or the JSON option\n``settings.modelChecker.solvers=[smtlib2,z3]``, where:\n\n- ``cvc5`` is used via its binary which must be installed in the system. Only BMC uses ``cvc5``.\n- ``eld`` is used via its binary which must be installed in the system. Only CHC uses ``eld``, and only if ``z3`` is not enabled.\n- ``smtlib2`` outputs SMT/Horn queries in the `smtlib2 <http://smtlib.cs.uiowa.edu/>`_ format.\n  These can be used together with the compiler's `callback mechanism <https://github.com/argotorg/solc-js>`_ so that\n  any solver binary from the system can be employed to synchronously return the results of the queries to the compiler.\n  This can be used by both BMC and CHC depending on which solvers are called.\n- ``z3`` is available statically in ``soljson.js`` (from Solidity 0.6.9), that is, the JavaScript binary of the compiler. Otherwise it is used via its binary which must be installed in the system.\n\n.. note::\n  z3 version 4.8.16 broke ABI compatibility with previous versions and cannot\n  be used with solc <=0.8.13. If you are using z3 >=4.8.16 please use solc\n  >=0.8.14, and conversely, only use older z3 with older solc releases.\n  We also recommend using the latest z3 release which is what SMTChecker also does.\n\nSince both BMC and CHC use ``z3``, and ``z3`` is available in a greater variety\nof environments, including in the browser, most users will almost never need to be\nconcerned about this option. More advanced users might apply this option to try\nalternative solvers on more complex problems.\n\nPlease note that certain combinations of chosen engine and solver will lead to\nthe SMTChecker doing nothing, for example choosing CHC and ``cvc5``.\n\n*******************************\nAbstraction and False Positives\n*******************************\n\nThe SMTChecker implements abstractions in an incomplete and sound way: If a bug\nis reported, it might be a false positive introduced by abstractions (due to\nerasing knowledge or using a non-precise type). If it determines that a\nverification target is safe, it is indeed safe, that is, there are no false\nnegatives (unless there is a bug in the SMTChecker).\n\nIf a target cannot be proven you can try to help the solver by using the tuning\noptions in the previous section.\nIf you are sure of a false positive, adding ``require`` statements in the code\nwith more information may also give some more power to the solver.\n\nSMT Encoding and Types\n======================\n\nThe SMTChecker encoding tries to be as precise as possible, mapping Solidity types\nand expressions to their closest `SMT-LIB <http://smtlib.cs.uiowa.edu/>`_\nrepresentation, as shown in the table below.\n\n+-----------------------+--------------------------------+-----------------------------+\n|Solidity type          |SMT sort                        |Theories                     |\n+=======================+================================+=============================+\n|Boolean                |Bool                            |Bool                         |\n+-----------------------+--------------------------------+-----------------------------+\n|intN, uintN, address,  |Integer                         |LIA, NIA                     |\n|bytesN, enum, contract |                                |                             |\n+-----------------------+--------------------------------+-----------------------------+\n|array, mapping, bytes, |Tuple                           |Datatypes, Arrays, LIA       |\n|string                 |(Array elements, Integer length)|                             |\n+-----------------------+--------------------------------+-----------------------------+\n|struct                 |Tuple                           |Datatypes                    |\n+-----------------------+--------------------------------+-----------------------------+\n|other types            |Integer                         |LIA                          |\n+-----------------------+--------------------------------+-----------------------------+\n\nTypes that are not yet supported are abstracted by a single 256-bit unsigned\ninteger, where their unsupported operations are ignored.\n\nFor more details on how the SMT encoding works internally, see the paper\n`SMT-based Verification of Solidity Smart Contracts <https://github.com/chriseth/solidity_isola/blob/master/main.pdf>`_.\n\nFunction Calls\n==============\n\nIn the BMC engine, function calls to the same contract (or base contracts) are\ninlined when possible, that is, when their implementation is available.  Calls\nto functions in other contracts are not inlined even if their code is\navailable, since we cannot guarantee that the actual deployed code is the same.\n\nThe CHC engine creates nonlinear Horn clauses that use summaries of the called\nfunctions to support internal function calls. External function calls are treated\nas calls to unknown code, including potential reentrant calls.\n\nComplex pure functions are abstracted by an uninterpreted function (UF) over\nthe arguments.\n\n+-----------------------------------+--------------------------------------+\n|Functions                          |BMC/CHC behavior                      |\n+===================================+======================================+\n|``assert``                         |Verification target.                  |\n+-----------------------------------+--------------------------------------+\n|``require``                        |Assumption.                           |\n+-----------------------------------+--------------------------------------+\n|internal call                      |BMC: Inline function call.            |\n|                                   |CHC: Function summaries.              |\n+-----------------------------------+--------------------------------------+\n|external call to known code        |BMC: Inline function call or          |\n|                                   |erase knowledge about state variables |\n|                                   |and local storage references.         |\n|                                   |CHC: Assume called code is unknown.   |\n|                                   |Try to infer invariants that hold     |\n|                                   |after the call returns.               |\n+-----------------------------------+--------------------------------------+\n|Storage array push/pop             |Supported precisely.                  |\n|                                   |Checks whether it is popping an       |\n|                                   |empty array.                          |\n+-----------------------------------+--------------------------------------+\n|ABI functions                      |Abstracted with UF.                   |\n+-----------------------------------+--------------------------------------+\n|``addmod``, ``mulmod``             |Supported precisely.                  |\n+-----------------------------------+--------------------------------------+\n|``gasleft``, ``blobhash``,         |Abstracted with UF.                   |\n|``blockhash``, ``keccak256``,      |                                      |\n|``ecrecover``, ``ripemd160``       |                                      |\n+-----------------------------------+--------------------------------------+\n|pure functions without             |Abstracted with UF                    |\n|implementation (external or        |                                      |\n|complex)                           |                                      |\n+-----------------------------------+--------------------------------------+\n|external functions without         |BMC: Erase state knowledge and assume |\n|implementation                     |result is nondeterministic.           |\n|                                   |CHC: Nondeterministic summary.        |\n|                                   |Try to infer invariants that hold     |\n|                                   |after the call returns.               |\n+-----------------------------------+--------------------------------------+\n|transfer                           |BMC: Checks whether the contract's    |\n|                                   |balance is sufficient.                |\n|                                   |CHC: does not yet perform the check.  |\n+-----------------------------------+--------------------------------------+\n|others                             |Currently unsupported                 |\n+-----------------------------------+--------------------------------------+\n\nUsing abstraction means loss of precise knowledge, but in many cases it does\nnot mean loss of proving power.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    contract Recover\n    {\n        function f(\n            bytes32 hash,\n            uint8 v1, uint8 v2,\n            bytes32 r1, bytes32 r2,\n            bytes32 s1, bytes32 s2\n        ) public pure returns (address) {\n            address a1 = ecrecover(hash, v1, r1, s1);\n            require(v1 == v2);\n            require(r1 == r2);\n            require(s1 == s2);\n            address a2 = ecrecover(hash, v2, r2, s2);\n            assert(a1 == a2);\n            return a1;\n        }\n    }\n\nIn the example above, the SMTChecker is not expressive enough to actually\ncompute ``ecrecover``, but by modelling the function calls as uninterpreted\nfunctions we know that the return value is the same when called on equivalent\nparameters. This is enough to prove that the assertion above is always true.\n\nAbstracting a function call with an UF can be done for functions known to be\ndeterministic, and can be easily done for pure functions.  It is however\ndifficult to do this with general external functions, since they might depend\non state variables.\n\nReference Types and Aliasing\n============================\n\nSolidity implements aliasing for reference types with the same :ref:`data\nlocation<data-location>`.\nThat means one variable may be modified through a reference to the same data\narea.\nThe SMTChecker does not keep track of which references refer to the same data.\nThis implies that whenever a local reference or state variable of reference\ntype is assigned, all knowledge regarding variables of the same type and data\nlocation is erased.\nIf the type is nested, the knowledge removal also includes all the prefix base\ntypes.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0;\n\n    contract Aliasing\n    {\n        uint[] array1;\n        uint[][] array2;\n        function f(\n            uint[] memory a,\n            uint[] memory b,\n            uint[][] memory c,\n            uint[] storage d\n        ) internal {\n            array1[0] = 42;\n            a[0] = 2;\n            c[0][0] = 2;\n            b[0] = 1;\n            // Erasing knowledge about memory references should not\n            // erase knowledge about state variables.\n            assert(array1[0] == 42);\n            // However, an assignment to a storage reference will erase\n            // storage knowledge accordingly.\n            d[0] = 2;\n            // Fails as false positive because of the assignment above.\n            assert(array1[0] == 42);\n            // Fails because `a == b` is possible.\n            assert(a[0] == 2);\n            // Fails because `c[i] == b` is possible.\n            assert(c[0][0] == 2);\n            assert(d[0] == 2);\n            assert(b[0] == 1);\n        }\n        function g(\n            uint[] memory a,\n            uint[] memory b,\n            uint[][] memory c,\n            uint x\n        ) public {\n            f(a, b, c, array2[x]);\n        }\n    }\n\nAfter the assignment to ``b[0]``, we need to clear knowledge about ``a`` since\nit has the same type (``uint[]``) and data location (memory).  We also need to\nclear knowledge about ``c``, since its base type is also a ``uint[]`` located\nin memory. This implies that some ``c[i]`` could refer to the same data as\n``b`` or ``a``.\n\nNotice that we do not clear knowledge about ``array`` and ``d`` because they\nare located in storage, even though they also have type ``uint[]``.  However,\nif ``d`` was assigned, we would need to clear knowledge about ``array`` and\nvice-versa.\n\nContract Balance\n================\n\nA contract may be deployed with funds sent to it, if ``msg.value`` > 0 in the\ndeployment transaction.\nHowever, the contract's address may already have funds before deployment,\nwhich are kept by the contract.\nTherefore, the SMTChecker assumes that ``address(this).balance >= msg.value``\nin the constructor in order to be consistent with the EVM rules.\nThe contract's balance may also increase without triggering any calls to the\ncontract, if\n\n- ``selfdestruct`` is executed by another contract with the analyzed contract\n  as the target of the remaining funds,\n- the contract is the coinbase (i.e., ``block.coinbase``) of some block.\n\nTo model this properly, the SMTChecker assumes that at every new transaction\nthe contract's balance may grow by at least ``msg.value``.\n\n**********************\nReal World Assumptions\n**********************\n\nSome scenarios can be expressed in Solidity and the EVM, but are expected to\nnever occur in practice.\nOne of such cases is the length of a dynamic storage array overflowing during a\npush: If the ``push`` operation is applied to an array of length 2^256 - 1, its\nlength silently overflows.\nHowever, this is unlikely to happen in practice, since the operations required\nto grow the array to that point would take billions of years to execute.\nAnother similar assumption taken by the SMTChecker is that an address' balance\ncan never overflow.\n\nA similar idea was presented in `EIP-1985 <https://eips.ethereum.org/EIPS/eip-1985>`_.\n"
  },
  {
    "path": "docs/solidity-by-example.rst",
    "content": "###################\nSolidity by Example\n###################\n\n.. include:: examples/voting.rst\n\n.. include:: examples/blind-auction.rst\n\n.. include:: examples/safe-remote.rst\n\n.. include:: examples/micropayment.rst\n\n.. include:: examples/modular.rst"
  },
  {
    "path": "docs/structure-of-a-contract.rst",
    "content": ".. index:: contract, state variable, function, event, struct, enum, function;modifier\n\n.. _contract_structure:\n\n***********************\nStructure of a Contract\n***********************\n\nContracts in Solidity are similar to classes in object-oriented languages.\nEach contract can contain declarations of :ref:`structure-state-variables`, :ref:`structure-functions`,\n:ref:`structure-function-modifiers`, :ref:`structure-events`, :ref:`structure-errors`, :ref:`structure-struct-types` and :ref:`structure-enum-types`.\nFurthermore, contracts can inherit from other contracts.\n\nThere are also special kinds of contracts called :ref:`libraries<libraries>` and :ref:`interfaces<interfaces>`.\n\nThe section about :ref:`contracts<contracts>` contains more details than this section,\nwhich serves to provide a quick overview.\n\n.. _structure-state-variables:\n\nState Variables\n===============\n\nState variables are variables whose values are either permanently stored in contract\nstorage or, alternatively, temporarily stored in transient storage which is cleaned at\nthe end of each transaction.\nSee :ref:`data locations <locations>` for more details.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract SimpleStorage {\n        uint storedData; // State variable\n        // ...\n    }\n\nSee the :ref:`types` section for valid state variable types and\n:ref:`visibility-and-getters` for possible choices for\nvisibility.\n\n.. _structure-functions:\n\nFunctions\n=========\n\nFunctions are the executable units of code. Functions are usually\ndefined inside a contract, but they can also be defined outside of\ncontracts.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.1 <0.9.0;\n\n    contract SimpleAuction {\n        function bid() public payable { // Function\n            // ...\n        }\n    }\n\n    // Helper function defined outside of a contract\n    function helper(uint x) pure returns (uint) {\n        return x * 2;\n    }\n\n:ref:`function-calls` can happen internally or externally\nand have different levels of :ref:`visibility<visibility-and-getters>`\ntowards other contracts. :ref:`Functions<functions>` accept :ref:`parameters and return variables<function-parameters-return-variables>` to pass parameters\nand values between them.\n\n.. _structure-function-modifiers:\n\nFunction Modifiers\n==================\n\nFunction modifiers can be used to amend the semantics of functions in a declarative way\n(see :ref:`modifiers` in the contracts section).\n\nOverloading, that is, having the same modifier name with different parameters,\nis not possible.\n\nLike functions, modifiers can be :ref:`overridden <modifier-overriding>`.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.22 <0.9.0;\n\n    contract Purchase {\n        address public seller;\n\n        modifier onlySeller() { // Modifier\n            require(\n                msg.sender == seller,\n                \"Only seller can call this.\"\n            );\n            _;\n        }\n\n        function abort() public view onlySeller { // Modifier usage\n            // ...\n        }\n    }\n\n.. _structure-events:\n\nEvents\n======\n\nEvents are convenience interfaces with the EVM logging facilities.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.22;\n\n    event HighestBidIncreased(address bidder, uint amount); // Event\n\n    contract SimpleAuction {\n        function bid() public payable {\n            // ...\n            emit HighestBidIncreased(msg.sender, msg.value); // Triggering event\n        }\n    }\n\nSee :ref:`events` in contracts section for information on how events are declared\nand can be used from within a dapp.\n\n.. _structure-errors:\n\nErrors\n======\n\nErrors allow you to define descriptive names and data for failure situations.\nErrors can be used in :ref:`revert statements <revert-statement>`.\nIn comparison to string descriptions, errors are much cheaper and allow you\nto encode additional data. You can use NatSpec to describe the error to\nthe user.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.4;\n\n    /// Not enough funds for transfer. Requested `requested`,\n    /// but only `available` available.\n    error NotEnoughFunds(uint requested, uint available);\n\n    contract Token {\n        mapping(address => uint) balances;\n        function transfer(address to, uint amount) public {\n            uint balance = balances[msg.sender];\n            if (balance < amount)\n                revert NotEnoughFunds(amount, balance);\n            balances[msg.sender] -= amount;\n            balances[to] += amount;\n            // ...\n        }\n    }\n\nSee :ref:`errors` in the contracts section for more information.\n\n.. _structure-struct-types:\n\nStruct Types\n=============\n\nStructs are custom defined types that can group several variables (see\n:ref:`structs` in types section).\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract Ballot {\n        struct Voter { // Struct\n            uint weight;\n            bool voted;\n            address delegate;\n            uint vote;\n        }\n    }\n\n.. _structure-enum-types:\n\nEnum Types\n==========\n\nEnums can be used to create custom types with a finite set of 'constant values' (see\n:ref:`enums` in types section).\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract Purchase {\n        enum State { Created, Locked, Inactive } // Enum\n    }\n"
  },
  {
    "path": "docs/style-guide.rst",
    "content": ".. index:: style, coding style\n\n#############\nStyle Guide\n#############\n\n************\nIntroduction\n************\n\nThis guide is intended to provide coding conventions for writing Solidity code.\nThis guide should be thought of as an evolving document that will change over\ntime as useful conventions are found and old conventions are rendered obsolete.\n\nMany projects will implement their own style guides.  In the event of\nconflicts, project specific style guides take precedence.\n\nThe structure and many of the recommendations within this style guide were\ntaken from Python's\n`pep8 style guide <https://peps.python.org/pep-0008/>`_.\n\nThe goal of this guide is *not* to be the right way or the best way to write\nSolidity code.  The goal of this guide is *consistency*.  A quote from Python's\n`pep8 <https://peps.python.org/pep-0008/#a-foolish-consistency-is-the-hobgoblin-of-little-minds>`_\ncaptures this concept well.\n\n.. note::\n\n    A style guide is about consistency. Consistency with this style guide is important. Consistency within a project is more important. Consistency within one module or function is most important.\n\n    But most importantly: **know when to be inconsistent** -- sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best. And do not hesitate to ask!\n\n\n***********\nCode Layout\n***********\n\n\nIndentation\n===========\n\nUse 4 spaces per indentation level.\n\nTabs or Spaces\n==============\n\nSpaces are the preferred indentation method.\n\nMixing tabs and spaces should be avoided.\n\nBlank Lines\n===========\n\nSurround top level declarations in Solidity source with two blank lines.\n\nYes:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract A {\n        // ...\n    }\n\n\n    contract B {\n        // ...\n    }\n\n\n    contract C {\n        // ...\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract A {\n        // ...\n    }\n    contract B {\n        // ...\n    }\n\n    contract C {\n        // ...\n    }\n\nWithin a contract surround function declarations with a single blank line.\n\nBlank lines may be omitted between groups of related one-liners (such as stub functions for an abstract contract)\n\nYes:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    abstract contract A {\n        function spam() public virtual pure;\n        function ham() public virtual pure;\n    }\n\n\n    contract B is A {\n        function spam() public pure override {\n            // ...\n        }\n\n        function ham() public pure override {\n            // ...\n        }\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    abstract contract A {\n        function spam() virtual pure public;\n        function ham() public virtual pure;\n    }\n\n\n    contract B is A {\n        function spam() public pure override {\n            // ...\n        }\n        function ham() public pure override {\n            // ...\n        }\n    }\n\n.. _maximum_line_length:\n\nMaximum Line Length\n===================\n\nMaximum suggested line length is 120 characters.\n\nWrapped lines should conform to the following guidelines.\n\n1. The first argument should not be attached to the opening parenthesis.\n2. One, and only one, indent should be used.\n3. Each argument should fall on its own line.\n4. The terminating element, :code:`);`, should be placed on the final line by itself.\n\nFunction Calls\n\nYes:\n\n.. code-block:: solidity\n\n    thisFunctionCallIsReallyLong(\n        longArgument1,\n        longArgument2,\n        longArgument3\n    );\n\nNo:\n\n.. code-block:: solidity\n\n    thisFunctionCallIsReallyLong(longArgument1,\n                                  longArgument2,\n                                  longArgument3\n    );\n\n    thisFunctionCallIsReallyLong(longArgument1,\n        longArgument2,\n        longArgument3\n    );\n\n    thisFunctionCallIsReallyLong(\n        longArgument1, longArgument2,\n        longArgument3\n    );\n\n    thisFunctionCallIsReallyLong(\n    longArgument1,\n    longArgument2,\n    longArgument3\n    );\n\n    thisFunctionCallIsReallyLong(\n        longArgument1,\n        longArgument2,\n        longArgument3);\n\nAssignment Statements\n\nYes:\n\n.. code-block:: solidity\n\n    thisIsALongNestedMapping[being][set][toSomeValue] = someFunction(\n        argument1,\n        argument2,\n        argument3,\n        argument4\n    );\n\nNo:\n\n.. code-block:: solidity\n\n    thisIsALongNestedMapping[being][set][toSomeValue] = someFunction(argument1,\n                                                                       argument2,\n                                                                       argument3,\n                                                                       argument4);\n\nEvent Definitions and Event Emitters\n\nYes:\n\n.. code-block:: solidity\n\n    event LongAndLotsOfArgs(\n        address sender,\n        address recipient,\n        uint256 publicKey,\n        uint256 amount,\n        bytes32[] options\n    );\n\n    emit LongAndLotsOfArgs(\n        sender,\n        recipient,\n        publicKey,\n        amount,\n        options\n    );\n\nNo:\n\n.. code-block:: solidity\n\n    event LongAndLotsOfArgs(address sender,\n                            address recipient,\n                            uint256 publicKey,\n                            uint256 amount,\n                            bytes32[] options);\n\n    emit LongAndLotsOfArgs(sender,\n                      recipient,\n                      publicKey,\n                      amount,\n                      options);\n\nSource File Encoding\n====================\n\nUTF-8 or ASCII encoding is preferred.\n\nImports\n=======\n\nImport statements should always be placed at the top of the file.\n\nYes:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    import \"./Owned.sol\";\n\n    contract A {\n        // ...\n    }\n\n\n    contract B is Owned {\n        // ...\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract A {\n        // ...\n    }\n\n\n    import \"./Owned.sol\";\n\n\n    contract B is Owned {\n        // ...\n    }\n\nOrder of Functions\n==================\n\nOrdering helps readers identify which functions they can call and to find the constructor and fallback definitions easier.\n\nFunctions should be grouped according to their visibility and ordered:\n\n- constructor\n- receive function (if exists)\n- fallback function (if exists)\n- external\n- public\n- internal\n- private\n\nWithin a grouping, place the ``view`` and ``pure`` functions last.\n\nYes:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n    contract A {\n        constructor() {\n            // ...\n        }\n\n        receive() external payable {\n            // ...\n        }\n\n        fallback() external {\n            // ...\n        }\n\n        // External functions\n        // ...\n\n        // External functions that are view\n        // ...\n\n        // External functions that are pure\n        // ...\n\n        // Public functions\n        // ...\n\n        // Internal functions\n        // ...\n\n        // Private functions\n        // ...\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n    contract A {\n\n        // External functions\n        // ...\n\n        fallback() external {\n            // ...\n        }\n        receive() external payable {\n            // ...\n        }\n\n        // Private functions\n        // ...\n\n        // Public functions\n        // ...\n\n        constructor() {\n            // ...\n        }\n\n        // Internal functions\n        // ...\n    }\n\nWhitespace in Expressions\n=========================\n\nAvoid extraneous whitespace in the following  situations:\n\nImmediately inside parenthesis, brackets or braces, with the exception of single line function declarations.\n\nYes:\n\n.. code-block:: solidity\n\n    spam(ham[1], Coin({name: \"ham\"}));\n\nNo:\n\n.. code-block:: solidity\n\n    spam( ham[ 1 ], Coin( { name: \"ham\" } ) );\n\nException:\n\n.. code-block:: solidity\n\n    function singleLine() public { spam(); }\n\nImmediately before a comma, semicolon:\n\nYes:\n\n.. code-block:: solidity\n\n    function spam(uint i, Coin coin) public;\n\nNo:\n\n.. code-block:: solidity\n\n    function spam(uint i , Coin coin) public ;\n\nMore than one space around an assignment or other operator to align with another:\n\nYes:\n\n.. code-block:: solidity\n\n    x = 1;\n    y = 2;\n    longVariable = 3;\n\nNo:\n\n.. code-block:: solidity\n\n    x            = 1;\n    y            = 2;\n    longVariable = 3;\n\nDo not include a whitespace in the receive and fallback functions:\n\nYes:\n\n.. code-block:: solidity\n\n    receive() external payable {\n        ...\n    }\n\n    fallback() external {\n        ...\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    receive () external payable {\n        ...\n    }\n\n    fallback () external {\n        ...\n    }\n\n\nControl Structures\n==================\n\nThe braces denoting the body of a contract, library, functions and structs\nshould:\n\n* open on the same line as the declaration\n* close on their own line at the same indentation level as the beginning of the\n  declaration.\n* The opening brace should be preceded by a single space.\n\nYes:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract Coin {\n        struct Bank {\n            address owner;\n            uint balance;\n        }\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract Coin\n    {\n        struct Bank {\n            address owner;\n            uint balance;\n        }\n    }\n\nThe same recommendations apply to the control structures ``if``, ``else``, ``while``,\nand ``for``.\n\nAdditionally there should be a single space between the control structures\n``if``, ``while``, and ``for`` and the parenthetic block representing the\nconditional, as well as a single space between the conditional parenthetic\nblock and the opening brace.\n\nYes:\n\n.. code-block:: solidity\n\n    if (...) {\n        ...\n    }\n\n    for (...) {\n        ...\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    if (...)\n    {\n        ...\n    }\n\n    while(...){\n    }\n\n    for (...) {\n        ...;}\n\nFor control structures whose body contains a single statement, omitting the\nbraces is ok *if* the statement is contained on a single line.\n\nYes:\n\n.. code-block:: solidity\n\n    if (x < 10)\n        x += 1;\n\nNo:\n\n.. code-block:: solidity\n\n    if (x < 10)\n        someArray.push(Coin({\n            name: 'spam',\n            value: 42\n        }));\n\nFor ``if`` blocks which have an ``else`` or ``else if`` clause, the ``else`` should be\nplaced on the same line as the ``if``'s closing brace. This is an exception compared\nto the rules of other block-like structures.\n\nYes:\n\n.. code-block:: solidity\n\n    if (x < 3) {\n        x += 1;\n    } else if (x > 7) {\n        x -= 1;\n    } else {\n        x = 5;\n    }\n\n\n    if (x < 3)\n        x += 1;\n    else\n        x -= 1;\n\nNo:\n\n.. code-block:: solidity\n\n    if (x < 3) {\n        x += 1;\n    }\n    else {\n        x -= 1;\n    }\n\nFunction Declaration\n====================\n\nFor short function declarations, it is recommended for the opening brace of the\nfunction body to be kept on the same line as the function declaration.\n\nThe closing brace should be at the same indentation level as the function\ndeclaration.\n\nThe opening brace should be preceded by a single space.\n\nYes:\n\n.. code-block:: solidity\n\n    function increment(uint x) public pure returns (uint) {\n        return x + 1;\n    }\n\n    function increment(uint x) public pure onlyOwner returns (uint) {\n        return x + 1;\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    function increment(uint x) public pure returns (uint)\n    {\n        return x + 1;\n    }\n\n    function increment(uint x) public pure returns (uint){\n        return x + 1;\n    }\n\n    function increment(uint x) public pure returns (uint) {\n        return x + 1;\n        }\n\n    function increment(uint x) public pure returns (uint) {\n        return x + 1;}\n\nThe modifier order for a function should be:\n\n1. Visibility\n2. Mutability\n3. Virtual\n4. Override\n5. Custom modifiers\n\nYes:\n\n.. code-block:: solidity\n\n    function balance(uint from) public view override returns (uint)  {\n        return balanceOf[from];\n    }\n\n    function increment(uint x) public pure onlyOwner returns (uint) {\n        return x + 1;\n    }\n\n\nNo:\n\n.. code-block:: solidity\n\n    function balance(uint from) public override view returns (uint)  {\n        return balanceOf[from];\n    }\n\n    function increment(uint x) onlyOwner public pure returns (uint) {\n        return x + 1;\n    }\n\nFor long function declarations, it is recommended to drop each argument onto\nits own line at the same indentation level as the function body.  The closing\nparenthesis and opening bracket should be placed on their own line as well at\nthe same indentation level as the function declaration.\n\nYes:\n\n.. code-block:: solidity\n\n    function thisFunctionHasLotsOfArguments(\n        address a,\n        address b,\n        address c,\n        address d,\n        address e,\n        address f\n    )\n        public\n    {\n        doSomething();\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    function thisFunctionHasLotsOfArguments(address a, address b, address c,\n        address d, address e, address f) public {\n        doSomething();\n    }\n\n    function thisFunctionHasLotsOfArguments(address a,\n                                            address b,\n                                            address c,\n                                            address d,\n                                            address e,\n                                            address f) public {\n        doSomething();\n    }\n\n    function thisFunctionHasLotsOfArguments(\n        address a,\n        address b,\n        address c,\n        address d,\n        address e,\n        address f) public {\n        doSomething();\n    }\n\nIf a long function declaration has modifiers, then each modifier should be\ndropped to its own line.\n\nYes:\n\n.. code-block:: solidity\n\n    function thisFunctionNameIsReallyLong(address x, address y, address z)\n        public\n        onlyOwner\n        priced\n        returns (address)\n    {\n        doSomething();\n    }\n\n    function thisFunctionNameIsReallyLong(\n        address x,\n        address y,\n        address z\n    )\n        public\n        onlyOwner\n        priced\n        returns (address)\n    {\n        doSomething();\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    function thisFunctionNameIsReallyLong(address x, address y, address z)\n                                          public\n                                          onlyOwner\n                                          priced\n                                          returns (address) {\n        doSomething();\n    }\n\n    function thisFunctionNameIsReallyLong(address x, address y, address z)\n        public onlyOwner priced returns (address)\n    {\n        doSomething();\n    }\n\n    function thisFunctionNameIsReallyLong(address x, address y, address z)\n        public\n        onlyOwner\n        priced\n        returns (address) {\n        doSomething();\n    }\n\nMultiline output parameters and return statements should follow the same style recommended for wrapping long lines found in the :ref:`Maximum Line Length <maximum_line_length>` section.\n\nYes:\n\n.. code-block:: solidity\n\n    function thisFunctionNameIsReallyLong(\n        address a,\n        address b,\n        address c\n    )\n        public\n        returns (\n            address someAddressName,\n            uint256 LongArgument,\n            uint256 Argument\n        )\n    {\n        doSomething()\n\n        return (\n            veryLongReturnArg1,\n            veryLongReturnArg2,\n            veryLongReturnArg3\n        );\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    function thisFunctionNameIsReallyLong(\n        address a,\n        address b,\n        address c\n    )\n        public\n        returns (address someAddressName,\n                 uint256 LongArgument,\n                 uint256 Argument)\n    {\n        doSomething()\n\n        return (veryLongReturnArg1,\n                veryLongReturnArg1,\n                veryLongReturnArg1);\n    }\n\nFor constructor functions on inherited contracts whose bases require arguments,\nit is recommended to drop the base constructors onto new lines in the same\nmanner as modifiers if the function declaration is long or hard to read.\n\nYes:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n    // Base contracts just to make this compile\n    contract B {\n        constructor(uint) {\n        }\n    }\n\n\n    contract C {\n        constructor(uint, uint) {\n        }\n    }\n\n\n    contract D {\n        constructor(uint) {\n        }\n    }\n\n\n    contract A is B, C, D {\n        uint x;\n\n        constructor(uint param1, uint param2, uint param3, uint param4, uint param5)\n            B(param1)\n            C(param2, param3)\n            D(param4)\n        {\n            // do something with param5\n            x = param5;\n        }\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    // Base contracts just to make this compile\n    contract B {\n        constructor(uint) {\n        }\n    }\n\n\n    contract C {\n        constructor(uint, uint) {\n        }\n    }\n\n\n    contract D {\n        constructor(uint) {\n        }\n    }\n\n\n    contract A is B, C, D {\n        uint x;\n\n        constructor(uint param1, uint param2, uint param3, uint param4, uint param5)\n        B(param1)\n        C(param2, param3)\n        D(param4) {\n            x = param5;\n        }\n    }\n\n\n    contract X is B, C, D {\n        uint x;\n\n        constructor(uint param1, uint param2, uint param3, uint param4, uint param5)\n            B(param1)\n            C(param2, param3)\n            D(param4) {\n                x = param5;\n            }\n    }\n\n\nWhen declaring short functions with a single statement, it is permissible to do it on a single line.\n\nPermissible:\n\n.. code-block:: solidity\n\n    function shortFunction() public { doSomething(); }\n\nThese guidelines for function declarations are intended to improve readability.\nAuthors should use their best judgment as this guide does not try to cover all\npossible permutations for function declarations.\n\nMappings\n========\n\nIn variable declarations, do not separate the keyword ``mapping`` from its\ntype by a space. Do not separate any nested ``mapping`` keyword from its type by\nwhitespace.\n\nYes:\n\n.. code-block:: solidity\n\n    mapping(uint => uint) map;\n    mapping(address => bool) registeredAddresses;\n    mapping(uint => mapping(bool => Data[])) public data;\n    mapping(uint => mapping(uint => s)) data;\n\nNo:\n\n.. code-block:: solidity\n\n    mapping (uint => uint) map;\n    mapping( address => bool ) registeredAddresses;\n    mapping (uint => mapping (bool => Data[])) public data;\n    mapping(uint => mapping (uint => s)) data;\n\nVariable Declarations\n=====================\n\nDeclarations of array variables should not have a space between the type and\nthe brackets.\n\nYes:\n\n.. code-block:: solidity\n\n    uint[] x;\n\nNo:\n\n.. code-block:: solidity\n\n    uint [] x;\n\n\nOther Recommendations\n=====================\n\n* Strings should be quoted with double-quotes instead of single-quotes.\n\nYes:\n\n.. code-block:: solidity\n\n    str = \"foo\";\n    str = \"Hamlet says, 'To be or not to be...'\";\n\nNo:\n\n.. code-block:: solidity\n\n    str = 'bar';\n    str = '\"Be yourself; everyone else is already taken.\" -Oscar Wilde';\n\n* Surround operators with a single space on either side.\n\nYes:\n\n.. code-block:: solidity\n    :force:\n\n    x = 3;\n    x = 100 / 10;\n    x += 3 + 4;\n    x |= y && z;\n\nNo:\n\n.. code-block:: solidity\n    :force:\n\n    x=3;\n    x = 100/10;\n    x += 3+4;\n    x |= y&&z;\n\n* Operators with a higher priority than others can exclude surrounding\n  whitespace in order to denote precedence.  This is meant to allow for\n  improved readability for complex statements. You should always use the same\n  amount of whitespace on either side of an operator:\n\nYes:\n\n.. code-block:: solidity\n\n    x = 2**3 + 5;\n    x = 2*y + 3*z;\n    x = (a+b) * (a-b);\n\nNo:\n\n.. code-block:: solidity\n\n    x = 2** 3 + 5;\n    x = y+z;\n    x +=1;\n\n***************\nOrder of Layout\n***************\n\nContract elements should be laid out in the following order:\n\n1. Pragma statements\n2. Import statements\n3. Events\n4. Errors\n5. Interfaces\n6. Libraries\n7. Contracts\n\nInside each contract, library or interface, use the following order:\n\n1. Type declarations\n2. State variables\n3. Events\n4. Errors\n5. Modifiers\n6. Functions\n\n.. note::\n\n    It might be clearer to declare types close to their use in events or state\n    variables.\n\nYes:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.4 <0.9.0;\n\n    abstract contract Math {\n        error DivideByZero();\n        function divide(int256 numerator, int256 denominator) public virtual returns (uint256);\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.4 <0.9.0;\n\n    abstract contract Math {\n        function divide(int256 numerator, int256 denominator) public virtual returns (uint256);\n        error DivideByZero();\n    }\n\n\n******************\nNaming Conventions\n******************\n\nNaming conventions are powerful when adopted and used broadly.  The use of\ndifferent conventions can convey significant *meta* information that would\notherwise not be immediately available.\n\nThe naming recommendations given here are intended to improve the readability,\nand thus they are not rules, but rather guidelines to try and help convey the\nmost information through the names of things.\n\nLastly, consistency within a codebase should always supersede any conventions\noutlined in this document.\n\n\nNaming Styles\n=============\n\nTo avoid confusion, the following names will be used to refer to different\nnaming styles.\n\n* ``b`` (single lowercase letter)\n* ``B`` (single uppercase letter)\n* ``lowercase``\n* ``UPPERCASE``\n* ``UPPER_CASE_WITH_UNDERSCORES``\n* ``CapitalizedWords`` (or CapWords)\n* ``mixedCase`` (differs from CapitalizedWords by initial lowercase character!)\n\n.. note:: When using initialisms in CapWords, capitalize all the letters of the initialisms. Thus HTTPServerError is better than HttpServerError. When using initialisms in mixedCase, capitalize all the letters of the initialisms, except keep the first one lower case if it is the beginning of the name. Thus xmlHTTPRequest is better than XMLHTTPRequest.\n\n\nNames to Avoid\n==============\n\n* ``l`` - Lowercase letter el\n* ``O`` - Uppercase letter oh\n* ``I`` - Uppercase letter eye\n\nNever use any of these for single letter variable names.  They are often\nindistinguishable from the numerals one and zero.\n\n\nContract and Library Names\n==========================\n\n* Contracts and libraries should be named using the CapWords style. Examples: ``SimpleToken``, ``SmartBank``, ``CertificateHashRepository``, ``Player``, ``Congress``, ``Owned``.\n* Contract and library names should also match their filenames.\n* If a contract file includes multiple contracts and/or libraries, then the filename should match the *core contract*. This is not recommended however if it can be avoided.\n\nAs shown in the example below, if the contract name is ``Congress`` and the library name is ``Owned``, then their associated filenames should be ``Congress.sol`` and ``Owned.sol``.\n\nYes:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    // Owned.sol\n    contract Owned {\n        address public owner;\n\n        modifier onlyOwner {\n            require(msg.sender == owner);\n            _;\n        }\n\n        constructor() {\n            owner = msg.sender;\n        }\n\n        function transferOwnership(address newOwner) public onlyOwner {\n            owner = newOwner;\n        }\n    }\n\nand in ``Congress.sol``:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    import \"./Owned.sol\";\n\n\n    contract Congress is Owned, TokenRecipient {\n        //...\n    }\n\nNo:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.7.0 <0.9.0;\n\n    // owned.sol\n    contract owned {\n        address public owner;\n\n        modifier onlyOwner {\n            require(msg.sender == owner);\n            _;\n        }\n\n        constructor() {\n            owner = msg.sender;\n        }\n\n        function transferOwnership(address newOwner) public onlyOwner {\n            owner = newOwner;\n        }\n    }\n\nand in ``Congress.sol``:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.7.0;\n\n\n    import \"./owned.sol\";\n\n\n    contract Congress is owned, tokenRecipient {\n        //...\n    }\n\nStruct Names\n==========================\n\nStructs should be named using the CapWords style. Examples: ``MyCoin``, ``Position``, ``PositionXY``.\n\n\nEvent Names\n===========\n\nEvents should be named using the CapWords style. Examples: ``Deposit``, ``Transfer``, ``Approval``, ``BeforeTransfer``, ``AfterTransfer``.\n\n\nFunction Names\n==============\n\nFunctions should use mixedCase. Examples: ``getBalance``, ``transfer``, ``verifyOwner``, ``addMember``, ``changeOwner``.\n\n\nFunction Argument Names\n=======================\n\nFunction arguments should use mixedCase. Examples: ``initialSupply``, ``account``, ``recipientAddress``, ``senderAddress``, ``newOwner``.\n\nWhen writing library functions that operate on a custom struct, the struct\nshould be the first argument and should always be named ``self``.\n\n\nLocal and State Variable Names\n==============================\n\nUse mixedCase. Examples: ``totalSupply``, ``remainingSupply``, ``balancesOf``, ``creatorAddress``, ``isPreSale``, ``tokenExchangeRate``.\n\n\nConstants\n=========\n\nConstants should be named with all capital letters with underscores separating\nwords. Examples: ``MAX_BLOCKS``, ``TOKEN_NAME``, ``TOKEN_TICKER``, ``CONTRACT_VERSION``.\n\n\nModifier Names\n==============\n\nUse mixedCase. Examples: ``onlyBy``, ``onlyAfter``, ``onlyDuringThePreSale``.\n\n\nEnums\n=====\n\nEnums, in the style of simple type declarations, should be named using the CapWords style. Examples: ``TokenGroup``, ``Frame``, ``HashStyle``, ``CharacterLocation``.\n\n\nAvoiding Naming Collisions\n==========================\n\n* ``singleTrailingUnderscore_``\n\nThis convention is suggested when the desired name collides with that of\nan existing state variable, function, built-in or otherwise reserved name.\n\nUnderscore Prefix for Non-external Functions and Variables\n==========================================================\n\n* ``_singleLeadingUnderscore``\n\nThis convention is suggested for non-external functions and state variables (``private`` or ``internal``). State variables without a specified visibility are ``internal`` by default.\n\nWhen designing a smart contract, the public-facing API (functions that can be called by any account)\nis an important consideration.\nLeading underscores allow you to immediately recognize the intent of such functions,\nbut more importantly, if you change a function from non-external to external (including ``public``)\nand rename it accordingly, this forces you to review every call site while renaming.\nThis can be an important manual check against unintended external functions\nand a common source of security vulnerabilities (avoid find-replace-all tooling for this change).\n\n.. _style_guide_natspec:\n\n*******\nNatSpec\n*******\n\nSolidity contracts can also contain NatSpec comments. They are written with a\ntriple slash (``///``) or a double asterisk block (``/** ... */``) and\nthey should be used directly above function declarations or statements.\n\nFor example, the contract from :ref:`a simple smart contract <simple-smart-contract>` with the comments\nadded looks like the one below:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    /// @author The Solidity Team\n    /// @title A simple storage example\n    contract SimpleStorage {\n        uint storedData;\n\n        /// Store `x`.\n        /// @param x the new value to store\n        /// @dev stores the number in the state variable `storedData`\n        function set(uint x) public {\n            storedData = x;\n        }\n\n        /// Return the stored value.\n        /// @dev retrieves the value of the state variable `storedData`\n        /// @return the stored value\n        function get() public view returns (uint) {\n            return storedData;\n        }\n    }\n\nIt is recommended that Solidity contracts are fully annotated using :ref:`NatSpec <natspec>` for all public interfaces (everything in the ABI).\n\nPlease see the section about :ref:`NatSpec <natspec>` for a detailed explanation.\n"
  },
  {
    "path": "docs/types/conversion.rst",
    "content": ".. index:: ! type;conversion, ! cast\n\n.. _types-conversion-elementary-types:\n\nConversions between Elementary Types\n====================================\n\nImplicit Conversions\n--------------------\n\nAn implicit type conversion is automatically applied by the compiler in some cases\nduring assignments, when passing arguments to functions and when applying operators.\nIn general, an implicit conversion between value-types is possible if it makes\nsense semantically and no information is lost.\n\nFor example, ``uint8`` is convertible to\n``uint16`` and ``int128`` to ``int256``, but ``int8`` is not convertible to ``uint256``,\nbecause ``uint256`` cannot hold values such as ``-1``.\n\nIf an operator is applied to different types, the compiler tries to implicitly\nconvert one of the operands to the type of the other (the same is true for assignments).\nThis means that operations are always performed in the type of one of the operands.\n\nFor more details about which implicit conversions are possible,\nplease consult the sections about the types themselves.\n\nIn the example below, ``y`` and ``z``, the operands of the addition,\ndo not have the same type, but ``uint8`` can\nbe implicitly converted to ``uint16`` and not vice-versa. Because of that,\n``y`` is converted to the type of ``z`` before the addition is performed\nin the ``uint16`` type. The resulting type of the expression ``y + z`` is ``uint16``.\nBecause it is assigned to a variable of type ``uint32`` another implicit conversion\nis performed after the addition.\n\n.. code-block:: solidity\n\n    uint8 y;\n    uint16 z;\n    uint32 x = y + z;\n\n\nExplicit Conversions\n--------------------\n\nIf the compiler does not allow implicit conversion but you are confident a conversion will work,\nan explicit type conversion is sometimes possible. This may\nresult in unexpected behavior and allows you to bypass some security\nfeatures of the compiler, so be sure to test that the\nresult is what you want and expect!\n\nTake the following example that converts a negative ``int`` to a ``uint``:\n\n.. code-block:: solidity\n\n    int  y = -3;\n    uint x = uint(y);\n\nAt the end of this code snippet, ``x`` will have the value ``0xfffff..fd`` (64 hex\ncharacters), which is -3 in the two's complement representation of 256 bits.\n\nIf an integer is explicitly converted to a smaller type, higher-order bits are\ncut off:\n\n.. code-block:: solidity\n\n    uint32 a = 0x12345678;\n    uint16 b = uint16(a); // b will be 0x5678 now\n\nIf an integer is explicitly converted to a larger type, it is padded on the left (i.e., at the higher order end).\nThe result of the conversion will compare equal to the original integer:\n\n.. code-block:: solidity\n\n    uint16 a = 0x1234;\n    uint32 b = uint32(a); // b will be 0x00001234 now\n    assert(a == b);\n\nFixed-size bytes types behave differently during conversions. They can be thought of as\nsequences of individual bytes and converting to a smaller type will cut off the\nsequence:\n\n.. code-block:: solidity\n\n    bytes2 a = 0x1234;\n    bytes1 b = bytes1(a); // b will be 0x12\n\nIf a fixed-size bytes type is explicitly converted to a larger type, it is padded on\nthe right. Accessing the byte at a fixed index will result in the same value before and\nafter the conversion (if the index is still in range):\n\n.. code-block:: solidity\n\n    bytes2 a = 0x1234;\n    bytes4 b = bytes4(a); // b will be 0x12340000\n    assert(a[0] == b[0]);\n    assert(a[1] == b[1]);\n\nSince integers and fixed-size byte arrays behave differently when truncating or\npadding, explicit conversions between integers and fixed-size byte arrays are only allowed,\nif both have the same size. If you want to convert between integers and fixed-size byte arrays of\ndifferent size, you have to use intermediate conversions that make the desired truncation and padding\nrules explicit:\n\n.. code-block:: solidity\n\n    bytes2 a = 0x1234;\n    uint32 b = uint16(a); // b will be 0x00001234\n    uint32 c = uint32(bytes4(a)); // c will be 0x12340000\n    uint8 d = uint8(uint16(a)); // d will be 0x34\n    uint8 e = uint8(bytes1(a)); // e will be 0x12\n\n``bytes`` arrays and ``bytes`` calldata slices can be converted explicitly to fixed bytes types (``bytes1``/.../``bytes32``).\nIn case the array is longer than the target fixed bytes type, truncation at the end will happen.\nIf the array is shorter than the target type, it will be padded with zeros at the end.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.5;\n\n    contract C {\n        bytes s = \"abcdefgh\";\n        function f(bytes calldata c, bytes memory m) public view returns (bytes16, bytes3) {\n            require(c.length == 16, \"\");\n            bytes16 b = bytes16(m);  // if length of m is greater than 16, truncation will happen\n            b = bytes16(s);  // padded on the right, so result is \"abcdefgh\\0\\0\\0\\0\\0\\0\\0\\0\"\n            bytes3 b1 = bytes3(s); // truncated, b1 equals to \"abc\"\n            b = bytes16(c[:8]);  // also padded with zeros\n            return (b, b1);\n        }\n    }\n\n.. index:: ! literal;conversion, literal;rational, literal;hexadecimal number\n.. _types-conversion-literals:\n\nConversions between Literals and Elementary Types\n=================================================\n\nInteger Types\n-------------\n\nDecimal and hexadecimal number literals can be implicitly converted to any integer type\nthat is large enough to represent it without truncation:\n\n.. code-block:: solidity\n\n    uint8 a = 12; // fine\n    uint32 b = 1234; // fine\n    uint16 c = 0x123456; // fails, since it would have to truncate to 0x3456\n\n.. note::\n    Prior to version 0.8.0, any decimal or hexadecimal number literals could be explicitly\n    converted to an integer type. From 0.8.0, such explicit conversions are as strict as implicit\n    conversions, i.e., they are only allowed if the literal fits in the resulting range.\n\n.. index:: literal;string, literal;hexadecimal\n\nFixed-Size Byte Arrays\n----------------------\n\nDecimal number literals cannot be implicitly converted to fixed-size byte arrays. Hexadecimal\nnumber literals can be, but only if the number of hex digits exactly fits the size of the bytes\ntype. As an exception both decimal and hexadecimal literals which have a value of zero can be\nconverted to any fixed-size bytes type:\n\n.. code-block:: solidity\n\n    bytes2 a = 54321; // not allowed\n    bytes2 b = 0x12; // not allowed\n    bytes2 c = 0x123; // not allowed\n    bytes2 d = 0x1234; // fine\n    bytes2 e = 0x0012; // fine\n    bytes4 f = 0; // fine\n    bytes4 g = 0x0; // fine\n\nString literals and hex string literals can be implicitly converted to fixed-size byte arrays,\nif their number of characters is less than or equal to the size of the bytes type:\n\n.. code-block:: solidity\n\n    bytes2 a = hex\"1234\"; // fine\n    bytes2 b = \"xy\"; // fine\n    bytes2 c = hex\"12\"; // fine\n    bytes2 e = \"x\"; // fine\n    bytes2 f = \"xyz\"; // not allowed\n\n.. index:: literal;address\n\nAddresses\n---------\n\nAs described in :ref:`address_literals`, hex literals of the correct size that pass the checksum\ntest are of ``address`` type. No other literals can be implicitly converted to the ``address`` type.\n\nExplicit conversions to ``address`` are allowed only from ``bytes20`` and ``uint160``.\n\nAn ``address a`` can be converted explicitly to ``address payable`` via ``payable(a)``.\n\n.. note::\n    Prior to version 0.8.0, it was possible to explicitly convert from any integer type (of any size, signed or unsigned) to  ``address`` or ``address payable``.\n    Starting with 0.8.0 only conversion from ``uint160`` is allowed.\n"
  },
  {
    "path": "docs/types/mapping-types.rst",
    "content": ".. index:: !mapping\n.. _mapping-types:\n\nMapping Types\n=============\n\nMapping types use the syntax ``mapping(KeyType KeyName? => ValueType ValueName?)`` and variables of\nmapping type are declared using the syntax ``mapping(KeyType KeyName? => ValueType ValueName?)\nVariableName``. The ``KeyType`` can be any built-in value type, ``bytes``, ``string``, or any\ncontract or enum type. Other user-defined or complex types, such as mappings, structs or array types\nare not allowed. ``ValueType`` can be any type, including mappings, arrays and structs. ``KeyName``\nand ``ValueName`` are optional (so ``mapping(KeyType => ValueType)`` works as well) and can be any\nvalid identifier that is not a type.\n\nYou can think of mappings as `hash tables <https://en.wikipedia.org/wiki/Hash_table>`_, which are virtually initialised\nsuch that every possible key exists and is mapped to a value whose\nbyte-representation is all zeros, a type's :ref:`default value <default-value>`.\nThe similarity ends there, the key data is not stored in a\nmapping, only its ``keccak256`` hash is used to look up the value.\n\nBecause of this, mappings do not have a length or a concept of a key or\nvalue being set, and therefore cannot be erased without extra information\nregarding the assigned keys (see :ref:`clearing-mappings`).\n\nMappings can only have a data location of ``storage`` and thus\nare allowed for state variables, as storage reference types\nin functions, or as parameters for library functions.\nThey cannot be used as parameters or return parameters\nof contract functions that are publicly visible.\nThese restrictions are also true for arrays and structs that contain mappings.\n\nYou can mark state variables of mapping type as ``public`` and Solidity creates a\n:ref:`getter <visibility-and-getters>` for you. The ``KeyType`` becomes a parameter\nwith name ``KeyName`` (if specified) for the getter.\nIf ``ValueType`` is a value type or a struct, the getter returns ``ValueType`` with\nname ``ValueName`` (if specified).\nIf ``ValueType`` is an array or a mapping, the getter has one parameter for\neach ``KeyType``, recursively.\n\nIn the example below, the ``MappingExample`` contract defines a public ``balances``\nmapping, with the key type an ``address``, and a value type a ``uint``, mapping\nan Ethereum address to an unsigned integer value. As ``uint`` is a value type, the getter\nreturns a value that matches the type, which you can see in the ``MappingUser``\ncontract that returns the value at the specified address.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract MappingExample {\n        mapping(address => uint) public balances;\n\n        function update(uint newBalance) public {\n            balances[msg.sender] = newBalance;\n        }\n    }\n\n    contract MappingUser {\n        function f() public returns (uint) {\n            MappingExample m = new MappingExample();\n            m.update(100);\n            return m.balances(address(this));\n        }\n    }\n\nThe example below is a simplified version of an\n`ERC20 token <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol>`_.\n``_allowances`` is an example of a mapping type inside another mapping type.\n\nIn the example below, the optional ``KeyName`` and ``ValueName`` are provided for the mapping.\nIt does not affect any contract functionality or bytecode, it only sets the ``name`` field\nfor the inputs and outputs in the ABI for the mapping's getter.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.18;\n\n    contract MappingExampleWithNames {\n        mapping(address user => uint balance) public balances;\n\n        function update(uint newBalance) public {\n            balances[msg.sender] = newBalance;\n        }\n    }\n\n\nThe example below uses ``_allowances`` to record the amount someone else is allowed to withdraw from your account.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.22 <0.9.0;\n\n    contract MappingExample {\n\n        mapping(address => uint256) private _balances;\n        mapping(address => mapping(address => uint256)) private _allowances;\n\n        event Transfer(address indexed from, address indexed to, uint256 value);\n        event Approval(address indexed owner, address indexed spender, uint256 value);\n\n        function allowance(address owner, address spender) public view returns (uint256) {\n            return _allowances[owner][spender];\n        }\n\n        function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {\n            require(_allowances[sender][msg.sender] >= amount, \"ERC20: Allowance not high enough.\");\n            _allowances[sender][msg.sender] -= amount;\n            _transfer(sender, recipient, amount);\n            return true;\n        }\n\n        function approve(address spender, uint256 amount) public returns (bool) {\n            require(spender != address(0), \"ERC20: approve to the zero address\");\n\n            _allowances[msg.sender][spender] = amount;\n            emit Approval(msg.sender, spender, amount);\n            return true;\n        }\n\n        function _transfer(address sender, address recipient, uint256 amount) internal {\n            require(sender != address(0), \"ERC20: transfer from the zero address\");\n            require(recipient != address(0), \"ERC20: transfer to the zero address\");\n            require(_balances[sender] >= amount, \"ERC20: Not enough funds.\");\n\n            _balances[sender] -= amount;\n            _balances[recipient] += amount;\n            emit Transfer(sender, recipient, amount);\n        }\n    }\n\n\n.. index:: !iterable mappings\n.. _iterable-mappings:\n\nIterable Mappings\n-----------------\n\nYou cannot iterate over mappings, i.e. you cannot enumerate their keys.\nIt is possible, though, to implement a data structure on\ntop of them and iterate over that. For example, the code below implements an\n``IterableMapping`` library that the ``User`` contract then adds data to, and\nthe ``sum`` function iterates over to sum all the values.\n\n.. code-block:: solidity\n    :force:\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.8;\n\n    struct IndexValue { uint keyIndex; uint value; }\n    struct KeyFlag { uint key; bool deleted; }\n\n    struct itmap {\n        mapping(uint => IndexValue) data;\n        KeyFlag[] keys;\n        uint size;\n    }\n\n    type Iterator is uint;\n\n    library IterableMapping {\n        function insert(itmap storage self, uint key, uint value) internal returns (bool replaced) {\n            uint keyIndex = self.data[key].keyIndex;\n            self.data[key].value = value;\n            if (keyIndex > 0)\n                return true;\n            else {\n                keyIndex = self.keys.length;\n                self.keys.push();\n                self.data[key].keyIndex = keyIndex + 1;\n                self.keys[keyIndex].key = key;\n                self.size++;\n                return false;\n            }\n        }\n\n        function remove(itmap storage self, uint key) internal returns (bool success) {\n            uint keyIndex = self.data[key].keyIndex;\n            if (keyIndex == 0)\n                return false;\n            delete self.data[key];\n            self.keys[keyIndex - 1].deleted = true;\n            self.size --;\n        }\n\n        function contains(itmap storage self, uint key) internal view returns (bool) {\n            return self.data[key].keyIndex > 0;\n        }\n\n        function iterateStart(itmap storage self) internal view returns (Iterator) {\n            return iteratorSkipDeleted(self, 0);\n        }\n\n        function iterateValid(itmap storage self, Iterator iterator) internal view returns (bool) {\n            return Iterator.unwrap(iterator) < self.keys.length;\n        }\n\n        function iterateNext(itmap storage self, Iterator iterator) internal view returns (Iterator) {\n            return iteratorSkipDeleted(self, Iterator.unwrap(iterator) + 1);\n        }\n\n        function iterateGet(itmap storage self, Iterator iterator) internal view returns (uint key, uint value) {\n            uint keyIndex = Iterator.unwrap(iterator);\n            key = self.keys[keyIndex].key;\n            value = self.data[key].value;\n        }\n\n        function iteratorSkipDeleted(itmap storage self, uint keyIndex) private view returns (Iterator) {\n            while (keyIndex < self.keys.length && self.keys[keyIndex].deleted)\n                keyIndex++;\n            return Iterator.wrap(keyIndex);\n        }\n    }\n\n    // How to use it\n    contract User {\n        // Just a struct holding our data.\n        itmap data;\n        // Apply library functions to the data type.\n        using IterableMapping for itmap;\n\n        // Insert something\n        function insert(uint k, uint v) public returns (uint size) {\n            // This calls IterableMapping.insert(data, k, v)\n            data.insert(k, v);\n            // We can still access members of the struct,\n            // but we should take care not to mess with them.\n            return data.size;\n        }\n\n        // Computes the sum of all stored data.\n        function sum() public view returns (uint s) {\n            for (\n                Iterator i = data.iterateStart();\n                data.iterateValid(i);\n                i = data.iterateNext(i)\n            ) {\n                (, uint value) = data.iterateGet(i);\n                s += value;\n            }\n        }\n    }\n"
  },
  {
    "path": "docs/types/operator-precedence-table.rst",
    "content": "The following is the order of precedence for operators, listed in order of evaluation.\n\n+------------+-------------------------------------+--------------------------------------------+\n| Precedence | Description                         | Operator                                   |\n+============+=====================================+============================================+\n| *1*        | Postfix increment and decrement     | ``++``, ``--``                             |\n+            +-------------------------------------+--------------------------------------------+\n|            | New expression                      | ``new <typename>``                         |\n+            +-------------------------------------+--------------------------------------------+\n|            | Array subscripting                  | ``<array>[<index>]``                       |\n+            +-------------------------------------+--------------------------------------------+\n|            | Member access                       | ``<object>.<member>``                      |\n+            +-------------------------------------+--------------------------------------------+\n|            | Function-like call                  | ``<func>(<args...>)``                      |\n+            +-------------------------------------+--------------------------------------------+\n|            | Parentheses                         | ``(<statement>)``                          |\n+------------+-------------------------------------+--------------------------------------------+\n| *2*        | Prefix increment and decrement      | ``++``, ``--``                             |\n+            +-------------------------------------+--------------------------------------------+\n|            | Unary minus                         | ``-``                                      |\n+            +-------------------------------------+--------------------------------------------+\n|            | Unary operations                    | ``delete``                                 |\n+            +-------------------------------------+--------------------------------------------+\n|            | Logical NOT                         | ``!``                                      |\n+            +-------------------------------------+--------------------------------------------+\n|            | Bitwise NOT                         | ``~``                                      |\n+------------+-------------------------------------+--------------------------------------------+\n| *3*        | Exponentiation                      | ``**``                                     |\n+------------+-------------------------------------+--------------------------------------------+\n| *4*        | Multiplication, division and modulo | ``*``, ``/``, ``%``                        |\n+------------+-------------------------------------+--------------------------------------------+\n| *5*        | Addition and subtraction            | ``+``, ``-``                               |\n+------------+-------------------------------------+--------------------------------------------+\n| *6*        | Bitwise shift operators             | ``<<``, ``>>``                             |\n+------------+-------------------------------------+--------------------------------------------+\n| *7*        | Bitwise AND                         | ``&``                                      |\n+------------+-------------------------------------+--------------------------------------------+\n| *8*        | Bitwise XOR                         | ``^``                                      |\n+------------+-------------------------------------+--------------------------------------------+\n| *9*        | Bitwise OR                          | ``|``                                      |\n+------------+-------------------------------------+--------------------------------------------+\n| *10*       | Inequality operators                | ``<``, ``>``, ``<=``, ``>=``               |\n+------------+-------------------------------------+--------------------------------------------+\n| *11*       | Equality operators                  | ``==``, ``!=``                             |\n+------------+-------------------------------------+--------------------------------------------+\n| *12*       | Logical AND                         | ``&&``                                     |\n+------------+-------------------------------------+--------------------------------------------+\n| *13*       | Logical OR                          | ``||``                                     |\n+------------+-------------------------------------+--------------------------------------------+\n| *14*       | Ternary operator                    | ``<conditional> ? <if-true> : <if-false>`` |\n+            +-------------------------------------+--------------------------------------------+\n|            | Assignment operators                | ``=``, ``|=``, ``^=``, ``&=``, ``<<=``,    |\n|            |                                     | ``>>=``, ``+=``, ``-=``, ``*=``, ``/=``,   |\n|            |                                     | ``%=``                                     |\n+------------+-------------------------------------+--------------------------------------------+\n| *15*       | Comma operator                      | ``,``                                      |\n+------------+-------------------------------------+--------------------------------------------+\n"
  },
  {
    "path": "docs/types/operators.rst",
    "content": ".. index:: ! operator\n\nOperators\n=========\n\nArithmetic and bit operators can be applied even if the two operands do not have the same type.\nFor example, you can compute ``y = x + z``, where ``x`` is a ``uint8`` and ``z`` has\nthe type ``uint32``. In these cases, the following mechanism will be used to determine\nthe type in which the operation is computed (this is important in case of overflow)\nand the type of the operator's result:\n\n1. If the type of the right operand can be implicitly converted to the type of the left\n   operand, use the type of the left operand,\n2. if the type of the left operand can be implicitly converted to the type of the right\n   operand, use the type of the right operand,\n3. otherwise, the operation is not allowed.\n\nIn case one of the operands is a :ref:`literal number <rational_literals>` it is first converted to its\n\"mobile type\", which is the smallest type that can hold the value\n(unsigned types of the same bit-width are considered \"smaller\" than the signed types).\nIf both are literal numbers, the operation is computed with effectively unlimited precision in\nthat the expression is evaluated to whatever precision is necessary so that none is lost\nwhen the result is used with a non-literal type.\n\nThe operator's result type is the same as the type the operation is performed in,\nexcept for comparison operators where the result is always ``bool``.\n\nThe operators ``**`` (exponentiation), ``<<``  and ``>>`` use the type of the\nleft operand for the operation and the result.\n\nTernary Operator\n----------------\nThe ternary operator is used in expressions of the form ``<expression> ? <trueExpression> : <falseExpression>``.\nIt evaluates one of the latter two given expressions depending upon the result of the evaluation of the main ``<expression>``.\nIf ``<expression>`` evaluates to ``true``, then ``<trueExpression>`` will be evaluated, otherwise ``<falseExpression>`` is evaluated.\n\nThe result of the ternary operator does not have a rational number type, even if all of its operands are rational number literals.\nThe result type is determined from the types of the two operands in the same way as above, converting to their mobile type first if required.\n\nAs a consequence, ``255 + (true ? 1 : 0)`` will revert due to arithmetic overflow.\nThe reason is that ``(true ? 1 : 0)`` is of ``uint8`` type, which forces the addition to be performed in ``uint8`` as well,\nand 256 exceeds the range allowed for this type.\n\nAnother consequence is that an expression like ``1.5 + 1.5`` is valid but ``1.5 + (true ? 1.5 : 2.5)`` is not.\nThis is because the former is a rational expression evaluated in unlimited precision and only its final value matters.\nThe latter involves a conversion of a fractional rational number to an integer, which is currently disallowed.\n\n.. index:: assignment, lvalue, ! compound operators\n\nCompound and Increment/Decrement Operators\n------------------------------------------\n\nIf ``a`` is an LValue (i.e. a variable or something that can be assigned to), the\nfollowing operators are available as shorthands:\n\n``a += e`` is equivalent to ``a = a + e``. The operators ``-=``, ``*=``, ``/=``, ``%=``,\n``|=``, ``&=``, ``^=``, ``<<=`` and ``>>=`` are defined accordingly. ``a++`` and ``a--`` are equivalent\nto ``a += 1`` / ``a -= 1`` but the expression itself still has the previous value\nof ``a``. In contrast, ``--a`` and ``++a`` have the same effect on ``a`` but\nreturn the value after the change.\n\n.. index:: !delete\n\n.. _delete:\n\ndelete\n------\n\n``delete a`` assigns the initial value for the type to ``a``. I.e. for integers it is\nequivalent to ``a = 0``, but it can also be used on arrays, where it assigns a dynamic\narray of length zero or a static array of the same length with all elements set to their\ninitial value. ``delete a[x]`` deletes the item at index ``x`` of the array and leaves\nall other elements and the length of the array untouched. This especially means that it leaves\na gap in the array. If you plan to remove items, a :ref:`mapping <mapping-types>` is probably a better choice.\n\nFor structs, it assigns a struct with all members reset. In other words,\nthe value of ``a`` after ``delete a`` is the same as if ``a`` would be declared\nwithout assignment, with the following caveat:\n\n``delete`` has no effect on mappings (as the keys of mappings may be arbitrary and\nare generally unknown). So if you delete a struct, it will reset all members that\nare not mappings and also recurse into the members unless they are mappings.\nHowever, individual keys and what they map to can be deleted: If ``a`` is a\nmapping, then ``delete a[x]`` will delete the value stored at ``x``.\n\nIt is important to note that ``delete a`` really behaves like an\nassignment to ``a``, i.e. it stores a new object in ``a``.\nThis distinction is visible when ``a`` is reference variable: It\nwill only reset ``a`` itself, not the\nvalue it referred to previously.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    contract DeleteExample {\n        uint data;\n        uint[] dataArray;\n\n        function f() public {\n            uint x = data;\n            delete x; // sets x to 0, does not affect data\n            delete data; // sets data to 0, does not affect x\n            uint[] storage y = dataArray;\n            delete dataArray; // this sets dataArray.length to zero, but as uint[] is a complex object, also\n            // y is affected which is an alias to the storage object\n            // On the other hand: \"delete y\" is not valid, as assignments to local variables\n            // referencing storage objects can only be made from existing storage objects.\n            assert(y.length == 0);\n        }\n    }\n\n.. index:: ! operator; precedence\n.. _order:\n\nOrder of Precedence of Operators\n--------------------------------\n\n.. include:: types/operator-precedence-table.rst\n"
  },
  {
    "path": "docs/types/reference-types.rst",
    "content": ".. index:: ! type;reference, ! reference type, storage, memory, location, array, struct\n\n.. _reference-types:\n\nReference Types\n===============\n\nValues of reference type can be modified through multiple different names.\nContrast this with value types where you get an independent copy whenever\na variable of value type is used. Because of that, reference types have to be handled\nmore carefully than value types. Currently, reference types comprise structs,\narrays and mappings. If you use a reference type, you always have to explicitly\nprovide the data area where the type is stored: ``memory`` (whose lifetime is limited\nto an external function call), ``storage`` (the location where the state variables\nare stored, where the lifetime is limited to the lifetime of a contract)\nor ``calldata`` (special data location that contains the function arguments).\n\nAn assignment or type conversion that changes the data location will always incur an automatic copy operation,\nwhile assignments inside the same data location only copy in some cases for storage types.\n\n.. _data-location:\n\nData location\n-------------\n\nEvery reference type has an additional\nannotation, the \"data location\", about where it is stored. There are three data locations:\n``memory``, ``storage`` and ``calldata``. Calldata is a non-modifiable,\nnon-persistent area where function arguments are stored, and behaves mostly like memory.\n\n.. note::\n    ``transient`` is not yet supported as a data location for reference types.\n\n.. note::\n    If you can, try to use ``calldata`` as data location because it will avoid copies and\n    also makes sure that the data cannot be modified. Arrays and structs with ``calldata``\n    data location can also be returned from functions, but it is not possible to\n    allocate such types.\n\n.. note::\n    Arrays and structs with ``calldata`` location declared in a function body\n    or as its return parameters must be assigned before being used or returned.\n    There are certain cases in which non-trivial control flow is used and the compiler\n    can't properly detect the initialization.\n    A common workaround in such cases is to assign the affected variable to itself before\n    the correct initialization takes place.\n\n.. note::\n    Prior to version 0.6.9 data location for reference-type arguments was limited to\n    ``calldata`` in external functions, ``memory`` in public functions and either\n    ``memory`` or ``storage`` in internal and private ones.\n    Now ``memory`` and ``calldata`` are allowed in all functions regardless of their visibility.\n\n.. note::\n    Constructor parameters cannot use ``calldata`` as their data location.\n\n.. note::\n    Prior to version 0.5.0 the data location could be omitted, and would default to different locations\n    depending on the kind of variable, function type, etc., but all complex types must now give an explicit\n    data location.\n\n.. _data-location-assignment:\n\nData location and assignment behavior\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nData locations are not only relevant for persistency of data, but also for the semantics of assignments:\n\n* Assignments between ``storage`` and ``memory`` (or from ``calldata``)\n  always create an independent copy.\n* Assignments from ``memory`` to ``memory`` only create references. This means\n  that changes to one memory variable are also visible in all other memory\n  variables that refer to the same data.\n* Assignments from ``storage`` to a **local** storage variable also only\n  assign a reference.\n* All other assignments to ``storage`` always copy. Examples for this\n  case are assignments to state variables or to members of local\n  variables of storage struct type, even if the local variable\n  itself is just a reference.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.5.0 <0.9.0;\n\n    contract C {\n        // The data location of x is storage.\n        // This is the only place where the\n        // data location can be omitted.\n        uint[] x;\n\n        // The data location of memoryArray is memory.\n        function f(uint[] memory memoryArray) public {\n            x = memoryArray; // works, copies the whole array to storage\n            uint[] storage y = x; // works, assigns a pointer, data location of y is storage\n            y[7]; // fine, returns the 8th element\n            y.pop(); // fine, modifies x through y\n            delete x; // fine, clears the array, also modifies y\n            // The following does not work; it would need to create a new temporary /\n            // unnamed array in storage, but storage is \"statically\" allocated:\n            // y = memoryArray;\n            // Similarly, \"delete y\" is not valid, as assignments to local variables\n            // referencing storage objects can only be made from existing storage objects.\n            // It would \"reset\" the pointer, but there is no sensible location it could point to.\n            // For more details see the documentation of the \"delete\" operator.\n            // delete y;\n            g(x); // calls g, handing over a reference to x\n            h(x); // calls h and creates an independent, temporary copy in memory\n        }\n\n        function g(uint[] storage) internal pure {}\n        function h(uint[] memory) public pure {}\n    }\n\n.. index:: ! array\n\n.. _arrays:\n\nArrays\n------\n\nArrays can have a compile-time fixed size, or they can have a dynamic size.\n\nThe type of an array of fixed size ``k`` and element type ``T`` is written as ``T[k]``,\nand an array of dynamic size as ``T[]``.\n\nFor example, an array of 5 dynamic arrays of ``uint`` is written as\n``uint[][5]``. The notation is reversed compared to some other languages. In\nSolidity, ``X[3]`` is always an array containing three elements of type ``X``,\neven if ``X`` is itself an array. This is not the case in other languages such\nas C.\n\nIndices are zero-based, and access is in the opposite direction of the\ndeclaration.\n\nFor example, if you have a variable ``uint[][5] memory x``, you access the\nseventh ``uint`` in the third dynamic array using ``x[2][6]``, and to access the\nthird dynamic array, use ``x[2]``. Again,\nif you have an array ``T[5] a`` for a type ``T`` that can also be an array,\nthen ``a[2]`` always has type ``T``.\n\nArray elements can be of any type, including mapping or struct. The general\nrestrictions for types apply, in that mappings can only be stored in the\n``storage`` data location and publicly-visible functions need parameters that are :ref:`ABI types <ABI>`.\n\nIt is possible to mark state variable arrays ``public`` and have Solidity create a :ref:`getter <visibility-and-getters>`.\nThe numeric index becomes a required parameter for the getter.\n\nAccessing an array past its end causes a failing assertion. Methods ``.push()`` and ``.push(value)`` can be used\nto append a new element at the end of a dynamically-sized array, where ``.push()`` appends a zero-initialized element and returns\na reference to it.\n\n.. note::\n    Dynamically-sized arrays can only be resized in storage.\n    In memory, such arrays can be of arbitrary size but the size cannot be changed once an array is allocated.\n\n.. index:: ! string, ! bytes\n\n.. _strings:\n\n.. _bytes:\n\n``bytes`` and ``string`` as Arrays\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nVariables of type ``bytes`` and ``string`` are special arrays. The ``bytes`` type is similar to ``bytes1[]``,\nbut it is packed tightly in calldata and memory. ``string`` is equal to ``bytes`` but does not allow\nlength or index access.\n\nSolidity does not have string manipulation functions, but there are\nthird-party string libraries. You can also compare two strings by their keccak256-hash using\n``keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2))`` and\nconcatenate two strings using ``string.concat(s1, s2)``.\n\nYou should use ``bytes`` over ``bytes1[]`` because it is cheaper,\nsince using ``bytes1[]`` in ``memory`` adds 31 padding bytes between the elements. Note that in ``storage``, the\npadding is absent due to tight packing, see :ref:`bytes and string <bytes-and-string>`. As a general rule,\nuse ``bytes`` for arbitrary-length raw byte data and ``string`` for arbitrary-length\nstring (UTF-8) data. If you can limit the length to a certain number of bytes,\nalways use one of the value types ``bytes1`` to ``bytes32`` because they are much cheaper.\n\n.. note::\n    If you want to access the byte-representation of a string ``s``, use\n    ``bytes(s).length`` / ``bytes(s)[7] = 'x';``. Keep in mind\n    that you are accessing the low-level bytes of the UTF-8 representation,\n    and not the individual characters.\n\n.. index:: ! bytes-concat, ! string-concat\n\n.. _bytes-concat:\n.. _string-concat:\n\nThe functions ``bytes.concat`` and ``string.concat``\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nYou can concatenate an arbitrary number of ``string`` values using ``string.concat``.\nThe function returns a single ``string memory`` array that contains the contents of the arguments without padding.\nIf you want to use parameters of other types that are not implicitly convertible to ``string``, you need to convert them to ``string`` first.\n\nAnalogously, the ``bytes.concat`` function can concatenate an arbitrary number of ``bytes`` or ``bytes1 ... bytes32`` values.\nThe function returns a single ``bytes memory`` array that contains the contents of the arguments without padding.\nIf you want to use string parameters or other types that are not implicitly convertible to ``bytes``, you need to convert them to ``bytes`` or ``bytes1``/.../``bytes32`` first.\n\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.12;\n\n    contract C {\n        string s = \"Storage\";\n        function f(bytes calldata bc, string memory sm, bytes16 b) public view {\n            string memory concatString = string.concat(s, string(bc), \"Literal\", sm);\n            assert((bytes(s).length + bc.length + 7 + bytes(sm).length) == bytes(concatString).length);\n\n            bytes memory concatBytes = bytes.concat(bytes(s), bc, bc[:2], \"Literal\", bytes(sm), b);\n            assert((bytes(s).length + bc.length + 2 + 7 + bytes(sm).length + b.length) == concatBytes.length);\n        }\n    }\n\nIf you call ``string.concat`` or ``bytes.concat`` without arguments they return an empty array.\n\n.. index:: ! array;allocating, new\n\nAllocating Memory Arrays\n^^^^^^^^^^^^^^^^^^^^^^^^\n\nMemory arrays with dynamic length can be created using the ``new`` operator.\nAs opposed to storage arrays, it is **not** possible to resize memory arrays (e.g.\nthe ``.push`` member functions are not available).\nYou either have to calculate the required size in advance\nor create a new memory array and copy every element.\n\nAs all variables in Solidity, the elements of newly allocated arrays are always initialized\nwith the :ref:`default value<default-value>`.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract C {\n        function f(uint len) public pure {\n            uint[] memory a = new uint[](7);\n            bytes memory b = new bytes(len);\n            assert(a.length == 7);\n            assert(b.length == len);\n            a[6] = 8;\n        }\n    }\n\n.. index:: ! literal;array, ! inline;arrays\n\nArray Literals\n^^^^^^^^^^^^^^\n\nAn array literal is a comma-separated list of one or more expressions, enclosed\nin square brackets (``[...]``). For example ``[1, a, f(3)]``. The type of the\narray literal is determined as follows:\n\nIt is always a statically-sized memory array whose length is the\nnumber of expressions.\n\nThe base type of the array is the type of the first expression on the list such that all\nother expressions can be implicitly converted to it. It is a type error\nif this is not possible.\n\nIt is not enough that there is a type all the elements can be converted to. One of the elements\nhas to be of that type.\n\nIn the example below, the type of ``[1, 2, 3]`` is\n``uint8[3] memory``, because the type of each of these constants is ``uint8``. If\nyou want the result to be a ``uint[3] memory`` type, you need to convert\nthe first element to ``uint``.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract C {\n        function f() public pure {\n            g([uint(1), 2, 3]);\n        }\n        function g(uint[3] memory) public pure {\n            // ...\n        }\n    }\n\nThe array literal ``[1, -1]`` is invalid because the type of the first expression\nis ``uint8`` while the type of the second is ``int8`` and they cannot be implicitly\nconverted to each other. To make it work, you can use ``[int8(1), -1]``, for example.\n\nSince fixed-size memory arrays of different type cannot be converted into each other\n(even if the base types can), you always have to specify a common base type explicitly\nif you want to use two-dimensional array literals:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract C {\n        function f() public pure returns (uint24[2][4] memory) {\n            uint24[2][4] memory x = [[uint24(0x1), 1], [0xffffff, 2], [uint24(0xff), 3], [uint24(0xffff), 4]];\n            // The following does not work, because some of the inner arrays are not of the right type.\n            // uint[2][4] memory x = [[0x1, 1], [0xffffff, 2], [0xff, 3], [0xffff, 4]];\n            return x;\n        }\n    }\n\nFixed size memory arrays cannot be assigned to dynamically-sized\nmemory arrays, i.e. the following is not possible:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.0 <0.9.0;\n\n    // This will not compile.\n    contract C {\n        function f() public {\n            // The next line creates a type error because uint[3] memory\n            // cannot be converted to uint[] memory.\n            uint[] memory x = [uint(1), 3, 4];\n        }\n    }\n\nIt is planned to remove this restriction in the future, but it creates some\ncomplications because of how arrays are passed in the ABI.\n\nIf you want to initialize dynamically-sized arrays, you have to assign the\nindividual elements:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    contract C {\n        function f() public pure {\n            uint[] memory x = new uint[](3);\n            x[0] = 1;\n            x[1] = 3;\n            x[2] = 4;\n        }\n    }\n\n.. index:: ! array;length, length, push, pop, !array;push, !array;pop\n\n.. _array-members:\n\nArray Members\n^^^^^^^^^^^^^\n\n**length**:\n    Arrays have a ``length`` member that contains their number of elements.\n    The length of memory arrays is fixed (but dynamic, i.e. it can depend on\n    runtime parameters) once they are created.\n**push()**:\n     Dynamic storage arrays and ``bytes`` (not ``string``) have a member function\n     called ``push()`` that you can use to append a zero-initialised element at the end of the array.\n     It returns a reference to the element, so that it can be used like\n     ``x.push().t = 2`` or ``x.push() = b``.\n**push(x)**:\n     Dynamic storage arrays and ``bytes`` (not ``string``) have a member function\n     called ``push(x)`` that you can use to append a given element at the end of the array.\n     The function returns nothing.\n**pop()**:\n     Dynamic storage arrays and ``bytes`` (not ``string``) have a member\n     function called ``pop()`` that you can use to remove an element from the\n     end of the array. This also implicitly calls :ref:`delete<delete>` on the removed element. The function returns nothing.\n\n.. note::\n    Increasing the length of a storage array by calling ``push()``\n    has constant gas costs because storage is zero-initialised,\n    while decreasing the length by calling ``pop()`` has a\n    cost that depends on the \"size\" of the element being removed.\n    If that element is an array, it can be very costly, because\n    it includes explicitly clearing the removed\n    elements similar to calling :ref:`delete<delete>` on them.\n\n.. note::\n    To use arrays of arrays in external (instead of public) functions, you need to\n    activate ABI coder v2.\n\n.. note::\n    In EVM versions before Byzantium, it was not possible to access\n    dynamic arrays returned from function calls. If you call functions\n    that return dynamic arrays, make sure to use an EVM that is set to\n    Byzantium mode.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.0 <0.9.0;\n\n    contract ArrayContract {\n        uint[2**20] aLotOfIntegers;\n        // Note that the following is not a pair of dynamic arrays but a\n        // dynamic array of pairs (i.e. of fixed size arrays of length two).\n        // In Solidity, T[k] and T[] are always arrays with elements of type T,\n        // even if T itself is an array.\n        // Because of that, bool[2][] is a dynamic array of elements\n        // that are bool[2]. This is different from other languages, like C.\n        // Data location for all state variables is storage.\n        bool[2][] pairsOfFlags;\n\n        // newPairs is stored in memory\n        function setAllFlagPairs(bool[2][] memory newPairs) public {\n            // assignment to a storage array performs a copy of ``newPairs`` and\n            // replaces the complete array ``pairsOfFlags``.\n            pairsOfFlags = newPairs;\n        }\n\n        struct StructType {\n            uint[] contents;\n            uint moreInfo;\n        }\n        StructType s;\n\n        function f(uint[] memory c) public {\n            // stores a reference to ``s`` in ``g``\n            StructType storage g = s;\n            // also changes ``s.moreInfo``.\n            g.moreInfo = 2;\n            // assigns a copy because ``g.contents``\n            // is not a local variable, but a member of\n            // a local variable.\n            g.contents = c;\n        }\n\n        function setFlagPair(uint index, bool flagA, bool flagB) public {\n            // access to a non-existing index will throw an exception\n            pairsOfFlags[index][0] = flagA;\n            pairsOfFlags[index][1] = flagB;\n        }\n\n        function changeFlagArraySize(uint newSize) public {\n            // using push and pop is the only way to change the\n            // length of an array\n            if (newSize < pairsOfFlags.length) {\n                while (pairsOfFlags.length > newSize)\n                    pairsOfFlags.pop();\n            } else if (newSize > pairsOfFlags.length) {\n                while (pairsOfFlags.length < newSize)\n                    pairsOfFlags.push();\n            }\n        }\n\n        function clear() public {\n            // these clear the arrays completely\n            delete pairsOfFlags;\n            delete aLotOfIntegers;\n            // identical effect here\n            pairsOfFlags = new bool[2][](0);\n        }\n\n        bytes byteData;\n\n        function byteArrays(bytes memory data) public {\n            // byte arrays (\"bytes\") are different as they are stored without padding,\n            // but can be treated identical to \"uint8[]\"\n            byteData = data;\n            for (uint i = 0; i < 7; i++)\n                byteData.push();\n            byteData[3] = 0x08;\n            delete byteData[2];\n        }\n\n        function addFlag(bool[2] memory flag) public returns (uint) {\n            pairsOfFlags.push(flag);\n            return pairsOfFlags.length;\n        }\n\n        function createMemoryArray(uint size) public pure returns (bytes memory) {\n            // Dynamic memory arrays are created using `new`:\n            uint[2][] memory arrayOfPairs = new uint[2][](size);\n\n            // Inline arrays are always statically-sized and if you only\n            // use literals, you have to provide at least one type.\n            arrayOfPairs[0] = [uint(1), 2];\n\n            // Create a dynamic byte array:\n            bytes memory b = new bytes(200);\n            for (uint i = 0; i < b.length; i++)\n                b[i] = bytes1(uint8(i));\n            return b;\n        }\n    }\n\n.. index:: ! array;dangling storage references\n\nDangling References to Storage Array Elements\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWhen working with storage arrays, you need to take care to avoid dangling references.\nA dangling reference is a reference that points to something that no longer exists or has been\nmoved without updating the reference. A dangling reference can for example occur, if you store a\nreference to an array element in a local variable and then ``.pop()`` from the containing array:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0 <0.9.0;\n\n    contract C {\n        uint[][] s;\n\n        function f() public {\n            // Stores a pointer to the last array element of s.\n            uint[] storage ptr = s[s.length - 1];\n            // Removes the last array element of s.\n            s.pop();\n            // Writes to the array element that is no longer within the array.\n            ptr.push(0x42);\n            // Adding a new element to ``s`` now will not add an empty array, but\n            // will result in an array of length 1 with ``0x42`` as element.\n            s.push();\n            assert(s[s.length - 1][0] == 0x42);\n        }\n    }\n\nThe write in ``ptr.push(0x42)`` will **not** revert, despite the fact that ``ptr`` no\nlonger refers to a valid element of ``s``. Since the compiler assumes that unused storage\nis always zeroed, a subsequent ``s.push()`` will not explicitly write zeroes to storage,\nso the last element of ``s`` after that ``push()`` will have length ``1`` and contain\n``0x42`` as its first element.\n\nNote that Solidity does not allow to declare references to value types in storage. These kinds\nof explicit dangling references are restricted to nested reference types. However, dangling references\ncan also occur temporarily when using complex expressions in tuple assignments:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0 <0.9.0;\n\n    contract C {\n        uint[] s;\n        uint[] t;\n        constructor() {\n            // Push some initial values to the storage arrays.\n            s.push(0x07);\n            t.push(0x03);\n        }\n\n        function g() internal returns (uint[] storage) {\n            s.pop();\n            return t;\n        }\n\n        function f() public returns (uint[] memory) {\n            // The following will first evaluate ``s.push()`` to a reference to a new element\n            // at index 1. Afterwards, the call to ``g`` pops this new element, resulting in\n            // the left-most tuple element to become a dangling reference. The assignment still\n            // takes place and will write outside the data area of ``s``.\n            (s.push(), g()[0]) = (0x42, 0x17);\n            // A subsequent push to ``s`` will reveal the value written by the previous\n            // statement, i.e. the last element of ``s`` at the end of this function will have\n            // the value ``0x42``.\n            s.push();\n            return s;\n        }\n    }\n\nIt is always safer to only assign to storage once per statement and to avoid\ncomplex expressions on the left-hand-side of an assignment.\n\nYou need to take particular care when dealing with references to elements of\n``bytes`` arrays, since a ``.push()`` on a bytes array may switch :ref:`from short\nto long layout in storage<bytes-and-string>`.\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.0 <0.9.0;\n\n    // This will report a warning\n    contract C {\n        bytes x = \"012345678901234567890123456789\";\n\n        function test() external returns(uint) {\n            (x.push(), x.push()) = (0x01, 0x02);\n            return x.length;\n        }\n    }\n\nHere, when the first ``x.push()`` is evaluated, ``x`` is still stored in short\nlayout, thereby ``x.push()`` returns a reference to an element in the first storage slot of\n``x``. However, the second ``x.push()`` switches the bytes array to large layout.\nNow the element that ``x.push()`` referred to is in the data area of the array while\nthe reference still points at its original location, which is now a part of the length field\nand the assignment will effectively garble the length of ``x``.\nTo be safe, only enlarge bytes arrays by at most one element during a single\nassignment and do not simultaneously index-access the array in the same statement.\n\nWhile the above describes the behavior of dangling storage references in the\ncurrent version of the compiler, any code with dangling references should be\nconsidered to have *undefined behavior*. In particular, this means that\nany future version of the compiler may change the behavior of code that\ninvolves dangling references.\n\nBe sure to avoid dangling references in your code!\n\n.. index:: ! array;slice\n\n.. _array-slices:\n\nArray Slices\n------------\n\n\nArray slices are a view on a contiguous portion of an array.\nThey are written as ``x[start:end]``, where ``start`` and\n``end`` are expressions resulting in a uint256 type (or\nimplicitly convertible to it). The first element of the\nslice is ``x[start]`` and the last element is ``x[end - 1]``.\n\nIf ``start`` is greater than ``end`` or if ``end`` is greater\nthan the length of the array, an exception is thrown.\n\nBoth ``start`` and ``end`` are optional: ``start`` defaults\nto ``0`` and ``end`` defaults to the length of the array.\n\nArray slices do not have any members. They are implicitly\nconvertible to arrays of their underlying type\nand support index access. Index access is not absolute\nin the underlying array, but relative to the start of\nthe slice.\n\nArray slices do not have a type name which means\nno variable can have an array slices as type,\nthey only exist in intermediate expressions.\n\n.. note::\n    As of now, array slices are only implemented for calldata arrays.\n\nArray slices are useful to ABI-decode secondary data passed in function parameters:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.8.5 <0.9.0;\n    contract Proxy {\n        /// @dev Address of the client contract managed by proxy i.e., this contract\n        address client;\n\n        constructor(address client_) {\n            client = client_;\n        }\n\n        /// Forward call to \"setOwner(address)\" that is implemented by client\n        /// after doing basic validation on the address argument.\n        function forward(bytes calldata payload) external {\n            bytes4 sig = bytes4(payload[:4]);\n            // Due to truncating behavior, bytes4(payload) performs identically.\n            // bytes4 sig = bytes4(payload);\n            if (sig == bytes4(keccak256(\"setOwner(address)\"))) {\n                address owner = abi.decode(payload[4:], (address));\n                require(owner != address(0), \"Address of owner cannot be zero.\");\n            }\n            (bool status,) = client.delegatecall(payload);\n            require(status, \"Forwarded call failed.\");\n        }\n    }\n\n\n\n.. index:: ! struct, ! type;struct\n\n.. _structs:\n\nStructs\n-------\n\nSolidity provides a way to define new types in the form of structs, which is\nshown in the following example:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.2 <0.9.0;\n\n    // Defines a new type with two fields.\n    // Declaring a struct outside of a contract allows\n    // it to be shared by multiple contracts.\n    // Here, this is not really needed.\n    struct Funder {\n        address addr;\n        uint amount;\n    }\n\n    contract CrowdFunding {\n        // Structs can also be defined inside contracts, which makes them\n        // visible only there and in derived contracts.\n        struct Campaign {\n            address payable beneficiary;\n            uint fundingGoal;\n            uint numFunders;\n            uint amount;\n            mapping(uint => Funder) funders;\n        }\n\n        uint numCampaigns;\n        mapping(uint => Campaign) campaigns;\n\n        function newCampaign(address payable beneficiary, uint goal) public returns (uint campaignID) {\n            campaignID = numCampaigns++; // campaignID is return variable\n            // We cannot use \"campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0)\"\n            // because the right hand side creates a memory-struct \"Campaign\" that contains a mapping.\n            Campaign storage c = campaigns[campaignID];\n            c.beneficiary = beneficiary;\n            c.fundingGoal = goal;\n        }\n\n        function contribute(uint campaignID) public payable {\n            Campaign storage c = campaigns[campaignID];\n            // Creates a new temporary memory struct, initialised with the given values\n            // and copies it over to storage.\n            // Note that you can also use Funder(msg.sender, msg.value) to initialise.\n            c.funders[c.numFunders++] = Funder({addr: msg.sender, amount: msg.value});\n            c.amount += msg.value;\n        }\n\n        function checkGoalReached(uint campaignID) public returns (bool reached) {\n            Campaign storage c = campaigns[campaignID];\n            if (c.amount < c.fundingGoal)\n                return false;\n            uint amount = c.amount;\n            c.amount = 0;\n            (bool success, ) = c.beneficiary.call{value: amount}(\"\");\n            return success;\n        }\n    }\n\nThe contract does not provide the full functionality of a crowdfunding\ncontract, but it contains the basic concepts necessary to understand structs.\nStruct types can be used inside mappings and arrays and they can themselves\ncontain mappings and arrays.\n\nIt is not possible for a struct to contain a member of its own type,\nalthough the struct itself can be the value type of a mapping member\nor it can contain a dynamically-sized array of its type.\nThis restriction is necessary, as the size of the struct has to be finite.\n\nNote how in all the functions, a struct type is assigned to a local variable\nwith data location ``storage``.\nThis does not copy the struct but only stores a reference so that assignments to\nmembers of the local variable actually write to the state.\n\nOf course, you can also directly access the members of the struct without\nassigning it to a local variable, as in\n``campaigns[campaignID].amount = 0``.\n\n.. note::\n    Until Solidity 0.7.0, memory-structs containing members of storage-only types (e.g. mappings)\n    were allowed and assignments like ``campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0)``\n    in the example above would work and just silently skip those members.\n"
  },
  {
    "path": "docs/types/value-types.rst",
    "content": ".. index:: ! value type, ! type;value\n.. _value-types:\n\nValue Types\n===========\n\nThe following are called value types because their variables will always be passed by value, i.e. they are always copied when they\nare used as function arguments or in assignments.\n\nUnlike :ref:`reference types <reference-types>`, value type declarations do not\nspecify a data location since they are small enough to be stored on the stack.\nThe only exception is :ref:`state variables <structure-state-variables>`.\nThose are by default located in storage, but can also be marked as\n:ref:`transient <transient-storage>`, :ref:`constant or immutable <constants>`.\n\n.. index:: ! bool, ! true, ! false\n\nBooleans\n--------\n\n``bool``: The possible values are constants ``true`` and ``false``.\n\nOperators:\n\n*  ``!`` (logical negation)\n*  ``&&`` (logical conjunction, \"and\")\n*  ``||`` (logical disjunction, \"or\")\n*  ``==`` (equality)\n*  ``!=`` (inequality)\n\nThe operators ``||`` and ``&&`` apply the common short-circuiting rules. This means that in the expression ``f(x) || g(y)``, if ``f(x)`` evaluates to ``true``, ``g(y)`` will not be evaluated even if it may have side-effects.\n\n.. index:: ! uint, ! int, ! integer\n.. _integers:\n\nIntegers\n--------\n\n``int`` / ``uint``: Signed and unsigned integers of various sizes. Keywords ``uint8`` to ``uint256`` in steps of ``8`` (unsigned of 8 up to 256 bits) and ``int8`` to ``int256``. ``uint`` and ``int`` are aliases for ``uint256`` and ``int256``, respectively.\n\nOperators:\n\n* Comparisons: ``<=``, ``<``, ``==``, ``!=``, ``>=``, ``>`` (evaluate to ``bool``)\n* Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation)\n* Shift operators: ``<<`` (left shift), ``>>`` (right shift)\n* Arithmetic operators: ``+``, ``-``, unary ``-`` (only for signed integers), ``*``, ``/``, ``%`` (modulo), ``**`` (exponentiation)\n\nFor an integer type ``X``, you can use ``type(X).min`` and ``type(X).max`` to\naccess the minimum and maximum value representable by the type.\n\n.. warning::\n\n  Integers in Solidity are restricted to a certain range. For example, with ``uint32``, this is ``0`` up to ``2**32 - 1``.\n  There are two modes in which arithmetic is performed on these types: The \"wrapping\" or \"unchecked\" mode and the \"checked\" mode.\n  By default, arithmetic is always \"checked\", meaning that if an operation's result falls outside the value range\n  of the type, the call is reverted through a :ref:`failing assertion<assert-and-require>`. You can switch to \"unchecked\" mode\n  using ``unchecked { ... }``. More details can be found in the section about :ref:`unchecked <unchecked>`.\n\nComparisons\n^^^^^^^^^^^\n\nThe value of a comparison is the one obtained by comparing the integer value.\n\nBit operations\n^^^^^^^^^^^^^^\n\nBit operations are performed on the two's complement representation of the number.\nThis means that, for example ``~int256(0) == int256(-1)``.\n\nShifts\n^^^^^^\n\nThe result of a shift operation has the type of the left operand, truncating the result to match the type.\nThe right operand must be of unsigned type, trying to shift by a signed type will produce a compilation error.\n\nShifts can be \"simulated\" using multiplication by powers of two in the following way. Note that the truncation\nto the type of the left operand is always performed at the end, but not mentioned explicitly.\n\n- ``x << y`` is equivalent to the mathematical expression ``x * 2**y``.\n- ``x >> y`` is equivalent to the mathematical expression ``x / 2**y``, rounded towards negative infinity.\n\n.. warning::\n    Before version ``0.5.0`` a right shift ``x >> y`` for negative ``x`` was equivalent to\n    the mathematical expression ``x / 2**y`` rounded towards zero,\n    i.e., right shifts used rounding up (towards zero) instead of rounding down (towards negative infinity).\n\n.. note::\n    Overflow checks are never performed for shift operations as they are done for arithmetic operations.\n    Instead, the result is always truncated.\n\nAddition, Subtraction and Multiplication\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAddition, subtraction and multiplication have the usual semantics, with two different\nmodes in regard to over- and underflow:\n\nBy default, all arithmetic is checked for under- or overflow, but this can be disabled\nusing the :ref:`unchecked block<unchecked>`, resulting in wrapping arithmetic. More details\ncan be found in that section.\n\nThe expression ``-x`` is equivalent to ``(T(0) - x)`` where\n``T`` is the type of ``x``. It can only be applied to signed types.\nThe value of ``-x`` can be\npositive if ``x`` is negative. There is another caveat also resulting\nfrom two's complement representation:\n\nIf you have ``int x = type(int).min;``, then ``-x`` does not fit the positive range.\nThis means that ``unchecked { assert(-x == x); }`` works, and the expression ``-x``\nwhen used in checked mode will result in a failing assertion.\n\nDivision\n^^^^^^^^\n\nSince the type of the result of an operation is always the type of one of\nthe operands, division on integers always results in an integer.\nIn Solidity, division rounds towards zero. This means that ``int256(-5) / int256(2) == int256(-2)``.\n\nNote that in contrast, division on :ref:`literals<rational_literals>` results in fractional values\nof arbitrary precision.\n\n.. note::\n  Division by zero causes a :ref:`Panic error<assert-and-require>`. This check can **not** be disabled through ``unchecked { ... }``.\n\n.. note::\n  The expression ``type(int).min / (-1)`` is the only case where division causes an overflow.\n  In checked arithmetic mode, this will cause a failing assertion, while in wrapping\n  mode, the value will be ``type(int).min``.\n\nModulo\n^^^^^^\n\nThe modulo operation ``a % n`` yields the remainder ``r`` after the division of the operand ``a``\nby the operand ``n``, where ``q = int(a / n)`` and ``r = a - (n * q)``. This means that modulo\nresults in the same sign as its left operand (or zero) and ``a % n == -(-a % n)`` holds for negative ``a``:\n\n* ``int256(5) % int256(2) == int256(1)``\n* ``int256(5) % int256(-2) == int256(1)``\n* ``int256(-5) % int256(2) == int256(-1)``\n* ``int256(-5) % int256(-2) == int256(-1)``\n\n.. note::\n  Modulo with zero causes a :ref:`Panic error<assert-and-require>`. This check can **not** be disabled through ``unchecked { ... }``.\n\nExponentiation\n^^^^^^^^^^^^^^\n\nExponentiation is only available for unsigned types in the exponent. The resulting type\nof an exponentiation is always equal to the type of the base. Please take care that it is\nlarge enough to hold the result and prepare for potential assertion failures or wrapping behavior.\n\n.. note::\n  In checked mode, exponentiation only uses the comparatively cheap ``exp`` opcode for small bases.\n  For the cases of ``x**3``, the expression ``x*x*x`` might be cheaper.\n  In any case, gas cost tests and the use of the optimizer are advisable.\n\n.. note::\n  Note that ``0**0`` is defined by the EVM as ``1``.\n\n.. index:: ! ufixed, ! fixed, ! fixed point number\n\nFixed Point Numbers\n-------------------\n\n.. warning::\n    Fixed point numbers are not fully supported by Solidity yet. They can be declared, but\n    cannot be assigned to or from.\n\n``fixed`` / ``ufixed``: Signed and unsigned fixed point number of various sizes. Keywords ``ufixedMxN`` and ``fixedMxN``, where ``M`` represents the number of bits taken by\nthe type and ``N`` represents how many decimal points are available. ``M`` must be divisible by 8 and goes from 8 to 256 bits. ``N`` must be between 0 and 80, inclusive.\n``ufixed`` and ``fixed`` are aliases for ``ufixed128x18`` and ``fixed128x18``, respectively.\n\nOperators:\n\n* Comparisons: ``<=``, ``<``, ``==``, ``!=``, ``>=``, ``>`` (evaluate to ``bool``)\n* Arithmetic operators: ``+``, ``-``, unary ``-``, ``*``, ``/``, ``%`` (modulo)\n\n.. note::\n    The main difference between floating point (``float`` and ``double`` in many languages, more precisely IEEE 754 numbers) and fixed point numbers is\n    that the number of bits used for the integer and the fractional part (the part after the decimal dot) is flexible in the former, while it is strictly\n    defined in the latter. Generally, in floating point almost the entire space is used to represent the number, while only a small number of bits define\n    where the decimal point is.\n\n.. index:: address, balance, send, call, delegatecall, staticcall, transfer\n\n.. _address:\n\nAddress\n-------\n\nThe address type comes in two largely identical flavors:\n\n- ``address``: Holds a 20 byte value (size of an Ethereum address).\n- ``address payable``: Same as ``address``, but with the additional members ``transfer`` and ``send``.\n\nThe idea behind this distinction is that ``address payable`` is an address you can send Ether to,\nwhile you are not supposed to send Ether to a plain ``address``, for example because it might be a smart contract\nthat was not built to accept Ether.\n\nType conversions:\n\nImplicit conversions from ``address payable`` to ``address`` are allowed, whereas conversions from ``address`` to ``address payable``\nmust be explicit via ``payable(<address>)``.\n\nExplicit conversions to and from ``address`` are allowed for ``uint160``, integer literals,\n``bytes20`` and contract types.\n\nOnly expressions of type ``address`` and contract type can be converted to the type ``address\npayable`` via the explicit conversion ``payable(...)``. For contract-type, this conversion is only\nallowed if the contract can receive Ether, i.e., the contract either has a :ref:`receive\n<receive-ether-function>` or a payable fallback function. Note that ``payable(0)`` is valid and is\nan exception to this rule.\n\n.. note::\n    If you need a variable of type ``address`` and plan to send Ether to it, then\n    declare its type as ``address payable`` to make this requirement visible. Also,\n    try to make this distinction or conversion as early as possible.\n\n    The distinction between ``address`` and ``address payable`` was introduced in version 0.5.0.\n    Also starting from that version, contracts are not implicitly convertible to the ``address`` type, but can still be explicitly converted to\n    ``address`` or to ``address payable``, if they have a receive or payable fallback function.\n\n\nOperators:\n\n* ``<=``, ``<``, ``==``, ``!=``, ``>=`` and ``>``\n\n.. warning::\n    If you convert a type that uses a larger byte size to an ``address``, for example ``bytes32``, then the ``address`` is truncated.\n    To reduce conversion ambiguity, starting with version 0.4.24, the compiler will force you to make the truncation explicit in the conversion.\n    Take for example the 32-byte value ``0x111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFFCCCC``.\n\n    You can use ``address(bytes20(b))``, which results in ``0x111122223333444455556666777788889999aAaa``,\n    or you can use ``address(uint160(uint256(b)))``, which results in ``0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc``.\n\n.. note::\n    Mixed-case hexadecimal numbers conforming to `EIP-55 <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md>`_ are automatically treated as literals of the ``address`` type. See :ref:`Address Literals<address_literals>`.\n\n.. _members-of-addresses:\n\nMembers of Addresses\n^^^^^^^^^^^^^^^^^^^^\n\nFor a quick reference of all members of address, see :ref:`address_related`.\n\n.. _balance-transfer-address-members:\n\n* ``balance`` and ``transfer``\n\n    It is possible to query the balance of an address using the property ``balance``\n    and to send Ether (in units of wei) to a payable address using the ``transfer`` function:\n\n    .. code-block:: solidity\n        :force:\n\n        address payable x = payable(0x123);\n        address myAddress = address(this);\n        if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);\n\n    The ``transfer`` function fails if the balance of the current contract is not large enough\n    or if the Ether transfer is rejected by the receiving account. The ``transfer`` function\n    reverts on failure.\n\n    .. note::\n        If ``x`` is a contract address, its code (more specifically: its :ref:`receive-ether-function`, if present, or otherwise its :ref:`fallback-function`, if present) will be executed together with the ``transfer`` call (this is a feature of the EVM and cannot be prevented). If that execution runs out of gas or fails in any way, the Ether transfer will be reverted and the current contract will stop with an exception.\n\n    .. warning::\n        ``transfer`` is deprecated and scheduled for removal.\n        Simple ether transfers can still be performed using the :ref:`call function <address_call_functions>`\n        with with an optionally provided maximum amount of gas and empty payload, i.e., ``call{value: <amount>}(\"\")``.\n        By default this forwards all the remaining gas, subject to additional limits imposed by some EVM versions\n        (such as the `63/64th rule <https://eips.ethereum.org/EIPS/eip-150>`_ introduced by ``tangerineWhistle``).\n        As with any external call, the ``gas`` call option can be used to set a lower limit.\n\n        While it is possible to recreate the functionality by explicitly setting the limit to the value of the stipend (2300 gas),\n        this value no longer holds its original meaning due to changing opcode costs.\n        It is recommended to use different means to protect against reentrancy.\n\n.. _send-address-member:\n\n* ``send``\n\n    ``send`` is the low-level counterpart of ``transfer``. If the execution fails, the current contract will not stop with an exception, but ``send`` will return ``false``.\n\n    .. warning::\n        There are some dangers in using ``send``: The transfer fails if the call stack depth is at 1024\n        (this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order\n        to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:\n        use a pattern where the recipient withdraws the Ether.\n\n    .. warning::\n        ``send`` is deprecated and scheduled for removal.\n        Simple ether transfers can still be performed using the :ref:`call function <address_call_functions>`\n        with with an optionally provided maximum amount of gas and empty payload, i.e., ``call{value: <amount>}(\"\")``.\n        By default this forwards all the remaining gas, subject to additional limits imposed by some EVM versions\n        (such as the `63/64th rule <https://eips.ethereum.org/EIPS/eip-150>`_ introduced by ``tangerineWhistle``).\n        As with any external call, the ``gas`` call option can be used to set a lower limit.\n\n        While it is possible to recreate the functionality by explicitly setting the limit to the value of the stipend (2300 gas),\n        this value no longer holds its original meaning due to changing opcode costs.\n        It is recommended to use different means to protect against reentrancy.\n\n.. _address_call_functions:\n\n* ``call``, ``delegatecall`` and ``staticcall``\n\n    In order to interface with contracts that do not adhere to the ABI,\n    or to get more direct control over the encoding,\n    the functions ``call``, ``delegatecall`` and ``staticcall`` are provided.\n    They all take a single ``bytes memory`` parameter and\n    return the success condition (as a ``bool``) and the returned data\n    (``bytes memory``).\n    The functions ``abi.encode``, ``abi.encodePacked``, ``abi.encodeWithSelector``\n    and ``abi.encodeWithSignature`` can be used to encode structured data.\n\n    Example:\n\n    .. code-block:: solidity\n\n        bytes memory payload = abi.encodeWithSignature(\"register(string)\", \"MyName\");\n        (bool success, bytes memory returnData) = address(nameReg).call(payload);\n        require(success);\n\n    .. warning::\n        All these functions are low-level functions and should be used with care.\n        Specifically, any unknown contract might be malicious and if you call it, you\n        hand over control to that contract which could in turn call back into\n        your contract, so be prepared for changes to your state variables\n        when the call returns. The regular way to interact with other contracts\n        is to call a function on a contract object (``x.f()``).\n\n    .. note::\n        Previous versions of Solidity allowed these functions to receive\n        arbitrary arguments and would also handle a first argument of type\n        ``bytes4`` differently. These edge cases were removed in version 0.5.0.\n\n    It is possible to adjust the supplied gas with the ``gas`` modifier:\n\n    .. code-block:: solidity\n\n        address(nameReg).call{gas: 1000000}(abi.encodeWithSignature(\"register(string)\", \"MyName\"));\n\n    Similarly, the supplied Ether value can be controlled too:\n\n    .. code-block:: solidity\n\n        address(nameReg).call{value: 1 ether}(abi.encodeWithSignature(\"register(string)\", \"MyName\"));\n\n    Lastly, these modifiers can be combined. Their order does not matter:\n\n    .. code-block:: solidity\n\n        address(nameReg).call{gas: 1000000, value: 1 ether}(abi.encodeWithSignature(\"register(string)\", \"MyName\"));\n\n    In a similar way, the function ``delegatecall`` can be used: the difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of ``delegatecall`` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for delegatecall to be used.\n\n    .. note::\n        Prior to homestead, only a limited variant called ``callcode`` was available that did not provide access to the original ``msg.sender`` and ``msg.value`` values. This function was removed in version 0.5.0.\n\n    Since byzantium ``staticcall`` can be used as well. This is basically the same as ``call``, but will revert if the called function modifies the state in any way.\n\n    All three functions ``call``, ``delegatecall`` and ``staticcall`` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity.\n\n    The ``gas`` option is available on all three methods, while the ``value`` option is only available\n    on ``call``.\n\n    .. note::\n        It is best to avoid relying on hardcoded gas values in your smart contract code,\n        regardless of whether state is read from or written to, as this can have many pitfalls.\n        Also, access to gas might change in the future.\n\n* ``code`` and ``codehash``\n\n    You can query the deployed code for any smart contract. Use ``.code`` to get the EVM bytecode as a\n    ``bytes memory``, which might be empty. Use ``.codehash`` to get the Keccak-256 hash of that code\n    (as a ``bytes32``). Note that ``addr.codehash`` is cheaper than using ``keccak256(addr.code)``.\n\n    .. warning::\n        The output of ``addr.codehash`` may be ``0`` if the account associated with ``addr`` is empty or non-existent\n        (i.e., it has no code, zero balance, and zero nonce as defined by `EIP-161 <https://eips.ethereum.org/EIPS/eip-161>`_).\n        If the account has no code but a non-zero balance or nonce, then ``addr.codehash`` will output the Keccak-256 hash of empty data\n        (i.e., ``keccak256(\"\")`` which is equal to ``c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470``), as defined by\n        `EIP-1052 <https://eips.ethereum.org/EIPS/eip-1052>`_.\n\n    .. note::\n        All contracts can be converted to ``address`` type, so it is possible to query the balance of the\n        current contract using ``address(this).balance``.\n\n.. index:: ! contract type, ! type; contract\n\n.. _contract_types:\n\nContract Types\n--------------\n\nEvery :ref:`contract<contracts>` defines its own type.\nYou can implicitly convert contracts to contracts they inherit from.\nContracts can be explicitly converted to and from the ``address`` type.\n\nExplicit conversion to and from the ``address payable`` type is only possible\nif the contract type has a receive or payable fallback function.  The conversion is still\nperformed using ``address(x)``. If the contract type does not have a receive or payable\nfallback function, the conversion to ``address payable`` can be done using\n``payable(address(x))``.\nYou can find more information in the section about\nthe :ref:`address type<address>`.\n\n.. note::\n    Before version 0.5.0, contracts directly derived from the address type\n    and there was no distinction between ``address`` and ``address payable``.\n\nIf you declare a local variable of contract type (``MyContract c``), you can call\nfunctions on that contract. Take care to assign it from somewhere that is the\nsame contract type.\n\nYou can also instantiate contracts (which means they are newly created). You\ncan find more details in the :ref:`'Contracts via new'<creating-contracts>`\nsection.\n\nThe data representation of a contract is identical to that of the ``address``\ntype and this type is also used in the :ref:`ABI<ABI>`.\n\nContracts do not support any operators.\n\nThe members of contract types are the external functions of the contract\nincluding any state variables marked as ``public``.\n\nFor a contract ``C`` you can use ``type(C)`` to access\n:ref:`type information<meta-type>` about the contract.\n\n.. index:: byte array, bytes32\n\nFixed-size byte arrays\n----------------------\n\nThe value types ``bytes1``, ``bytes2``, ``bytes3``, ..., ``bytes32``\nhold a sequence of bytes from one to up to 32.\n\nOperators:\n\n* Comparisons: ``<=``, ``<``, ``==``, ``!=``, ``>=``, ``>`` (evaluate to ``bool``)\n* Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation)\n* Shift operators: ``<<`` (left shift), ``>>`` (right shift)\n* Index access: If ``x`` is of type ``bytesI``, then ``x[k]`` for ``0 <= k < I`` returns the ``k`` th byte (read-only).\n\nThe shifting operator works with unsigned integer type as right operand (but\nreturns the type of the left operand), which denotes the number of bits to shift by.\nShifting by a signed type will produce a compilation error.\n\nMembers:\n\n* ``.length`` yields the fixed length of the byte array (read-only).\n\n.. note::\n    The type ``bytes1[]`` is an array of bytes, but due to padding rules, it wastes\n    31 bytes of space for each element (except in storage). It is better to use the ``bytes``\n    type instead.\n\n.. note::\n    Prior to version 0.8.0, ``byte`` used to be an alias for ``bytes1``.\n\n.. index:: address, ! literal;address\n\n.. _address_literals:\n\nAddress Literals\n----------------\n\nHexadecimal literals that pass the address checksum test, for example\n``0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF`` are of ``address`` type.\nHexadecimal literals that are between 39 and 41 digits\nlong and do not pass the checksum test produce\nan error. You can prepend (for integer types) or append (for bytesNN types) zeros to remove the error.\n\n.. note::\n    The mixed-case address checksum format is defined in `EIP-55 <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md>`_.\n\n.. index:: integer, rational number, ! literal;rational\n\n.. _rational_literals:\n\nRational and Integer Literals\n-----------------------------\n\nInteger literals are formed from a sequence of digits in the range 0-9.\nThey are interpreted as decimals. For example, ``69`` means sixty nine.\nOctal literals do not exist in Solidity and leading zeros are invalid.\n\nDecimal fractional literals are formed by a ``.`` with at least one number after the decimal point.\nExamples include ``.1`` and ``1.3`` (but not ``1.``).\n\nScientific notation in the form of ``2e10`` is also supported, where the\nmantissa can be fractional but the exponent has to be an integer.\nThe literal ``MeE`` is equivalent to ``M * 10**E``.\nExamples include ``2e10``, ``-2e10``, ``2e-10``, ``2.5e1``.\n\nUnderscores can be used to separate the digits of a numeric literal to aid readability.\nFor example, decimal ``123_000``, hexadecimal ``0x2eff_abde``, scientific decimal notation ``1_2e345_678`` are all valid.\nUnderscores are only allowed between two digits and only one consecutive underscore is allowed.\nThere is no additional semantic meaning added to a number literal containing underscores,\nthe underscores are ignored.\n\nNumber literal expressions retain arbitrary precision until they are converted to a non-literal type (i.e. by\nusing them together with anything other than a number literal expression (like boolean literals) or by explicit conversion).\nThis means that computations do not overflow and divisions do not truncate\nin number literal expressions.\n\nFor example, ``(2**800 + 1) - 2**800`` results in the constant ``1`` (of type ``uint8``)\nalthough intermediate results would not even fit the machine word size. Furthermore, ``.5 * 8`` results\nin the integer ``4`` (although non-integers were used in between).\n\n.. warning::\n    While most operators produce a literal expression when applied to literals, there are certain operators that do not follow this pattern:\n\n    - Ternary operator (``... ? ... : ...``),\n    - Array subscript (``<array>[<index>]``).\n\n    You might expect expressions like ``255 + (true ? 1 : 0)`` or ``255 + [1, 2, 3][0]`` to be equivalent to using the literal 256\n    directly, but in fact they are computed within the type ``uint8`` and can overflow.\n\nAny operator that can be applied to integers can also be applied to number literal expressions as\nlong as the operands are integers. If any of the two is fractional, bit operations are disallowed\nand exponentiation is disallowed if the exponent is fractional (because that might result in\na non-rational number).\n\nShifts and exponentiation with literal numbers as left (or base) operand and integer types\nas the right (exponent) operand are always performed\nin the ``uint256`` (for non-negative literals) or ``int256`` (for a negative literals) type,\nregardless of the type of the right (exponent) operand.\n\n.. warning::\n    Division on integer literals used to truncate in Solidity prior to version 0.4.0, but it now converts into a rational number, i.e. ``5 / 2`` is not equal to ``2``, but to ``2.5``.\n\n.. note::\n    Solidity has a number literal type for each rational number.\n    Integer literals and rational number literals belong to number literal types.\n    Moreover, all number literal expressions (i.e. the expressions that\n    contain only number literals and operators) belong to number literal\n    types.  So the number literal expressions ``1 + 2`` and ``2 + 1`` both\n    belong to the same number literal type for the rational number three.\n\n\n.. note::\n    Number literal expressions are converted into a non-literal type as soon as they are used with non-literal\n    expressions. Disregarding types, the value of the expression assigned to ``b``\n    below evaluates to an integer. Because ``a`` is of type ``uint128``, the\n    expression ``2.5 + a`` has to have a proper type, though. Since there is no common type\n    for the type of ``2.5`` and ``uint128``, the Solidity compiler does not accept\n    this code.\n\n.. code-block:: solidity\n\n    uint128 a = 1;\n    uint128 b = 2.5 + a + 0.5;\n\n.. index:: ! literal;string, string\n.. _string_literals:\n\nString Literals and Types\n-------------------------\n\nString literals are written with either double or single-quotes (``\"foo\"`` or ``'bar'``), and they can also be split into multiple consecutive parts (``\"foo\" \"bar\"`` is equivalent to ``\"foobar\"``) which can be helpful when dealing with long strings.  They do not imply trailing zeroes as in C; ``\"foo\"`` represents three bytes, not four.  As with integer literals, their type can vary, but they are implicitly convertible to ``bytes1``, ..., ``bytes32``, if they fit, to ``bytes`` and to ``string``.\n\nFor example, with ``bytes32 samevar = \"stringliteral\"`` the string literal is interpreted in its raw byte form when assigned to a ``bytes32`` type.\n\nString literals can only contain printable ASCII characters, which means the characters between and including 0x20 .. 0x7E.\n\nAdditionally, string literals also support the following escape characters:\n\n- ``\\<newline>`` (escapes an actual newline)\n- ``\\\\`` (backslash)\n- ``\\'`` (single quote)\n- ``\\\"`` (double quote)\n- ``\\n`` (newline)\n- ``\\r`` (carriage return)\n- ``\\t`` (tab)\n- ``\\xNN`` (hex escape, see below)\n- ``\\uNNNN`` (unicode escape, see below)\n\n``\\xNN`` takes a hex value and inserts the appropriate byte, while ``\\uNNNN`` takes a Unicode codepoint and inserts an UTF-8 sequence.\n\n.. note::\n\n    Until version 0.8.0 there were three additional escape sequences: ``\\b``, ``\\f`` and ``\\v``.\n    They are commonly available in other languages but rarely needed in practice.\n    If you do need them, they can still be inserted via hexadecimal escapes, i.e. ``\\x08``, ``\\x0c``\n    and ``\\x0b``, respectively, just as any other ASCII character.\n\nThe string in the following example has a length of ten bytes.\nIt starts with a newline byte, followed by a double quote, a single\nquote a backslash character and then (without separator) the\ncharacter sequence ``abcdef``.\n\n.. code-block:: solidity\n    :force:\n\n    \"\\n\\\"\\'\\\\abc\\\n    def\"\n\nAny Unicode line terminator which is not a newline (i.e. LF, VF, FF, CR, NEL, LS, PS) is considered to\nterminate the string literal. Newline only terminates the string literal if it is not preceded by a ``\\``.\n\n.. index:: ! literal;unicode\n\nUnicode Literals\n----------------\n\nWhile regular string literals can only contain ASCII, Unicode literals – prefixed with the keyword ``unicode`` – can contain any valid UTF-8 sequence.\nThey also support the very same escape sequences as regular string literals.\n\n.. code-block:: solidity\n\n    string memory a = unicode\"Hello 😃\";\n\n.. index:: ! literal;hexadecimal, bytes\n\nHexadecimal Literals\n--------------------\n\nHexadecimal literals are prefixed with the keyword ``hex`` and are enclosed in double\nor single-quotes (``hex\"001122FF\"``, ``hex'0011_22_FF'``). Their content must be\nhexadecimal digits which can optionally use a single underscore as separator between\nbyte boundaries. The value of the literal will be the binary representation\nof the hexadecimal sequence.\n\nMultiple hexadecimal literals separated by whitespace are concatenated into a single literal:\n``hex\"00112233\" hex\"44556677\"`` is equivalent to ``hex\"0011223344556677\"``\n\nHexadecimal literals in some ways behave like :ref:`string literals <string_literals>` but are not\nimplicitly convertible to the ``string`` type.\n\n.. index:: enum\n\n.. _enums:\n\nEnums\n-----\n\nEnums are one way to create a user-defined type in Solidity. They are explicitly convertible\nto and from all integer types but implicit conversion is not allowed.  The explicit conversion\nfrom integer checks at runtime that the value lies inside the range of the enum and causes a\n:ref:`Panic error<assert-and-require>` otherwise.\nEnums require at least one member, and its default value when declared is the first member.\nEnums cannot have more than 256 members.\n\nThe data representation is the same as for enums in C: The options are represented by\nsubsequent unsigned integer values starting from ``0``.\n\nUsing ``type(NameOfEnum).min`` and ``type(NameOfEnum).max`` you can get the\nsmallest and respectively largest value of the given enum.\n\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.8;\n\n    contract test {\n        enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }\n        ActionChoices choice;\n        ActionChoices constant defaultChoice = ActionChoices.GoStraight;\n\n        function setGoStraight() public {\n            choice = ActionChoices.GoStraight;\n        }\n\n        // Since enum types are not part of the ABI, the signature of \"getChoice\"\n        // will automatically be changed to \"getChoice() returns (uint8)\"\n        // for all matters external to Solidity.\n        function getChoice() public view returns (ActionChoices) {\n            return choice;\n        }\n\n        function getDefaultChoice() public pure returns (uint) {\n            return uint(defaultChoice);\n        }\n\n        function getLargestValue() public pure returns (ActionChoices) {\n            return type(ActionChoices).max;\n        }\n\n        function getSmallestValue() public pure returns (ActionChoices) {\n            return type(ActionChoices).min;\n        }\n    }\n\n.. note::\n    Enums can also be declared on the file level, outside of contract or library definitions.\n\n.. index:: ! user defined value type, custom type\n\n.. _user-defined-value-types:\n\nUser-defined Value Types\n------------------------\n\nA user-defined value type allows creating a zero cost abstraction over an elementary value type.\nThis is similar to an alias, but with stricter type requirements.\n\nA user-defined value type is defined using ``type C is V``, where ``C`` is the name of the newly\nintroduced type and ``V`` has to be a built-in value type (the \"underlying type\"). The function\n``C.wrap`` is used to convert from the underlying type to the custom type. Similarly, the\nfunction ``C.unwrap`` is used to convert from the custom type to the underlying type.\n\nThe type ``C`` does not have any operators or attached member functions. In particular, even the\noperator ``==`` is not defined. Explicit and implicit conversions to and from other types are\ndisallowed.\n\nThe data-representation of values of such types are inherited from the underlying type\nand the underlying type is also used in the ABI.\n\nThe following example illustrates a custom type ``UFixed256x18`` representing a decimal fixed point\ntype with 18 decimals and a minimal library to do arithmetic operations on the type.\n\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity ^0.8.8;\n\n    // Represent a 18 decimal, 256 bit wide fixed point type using a user-defined value type.\n    type UFixed256x18 is uint256;\n\n    /// A minimal library to do fixed point operations on UFixed256x18.\n    library FixedMath {\n        uint constant multiplier = 10**18;\n\n        /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked\n        /// arithmetic on uint256.\n        function add(UFixed256x18 a, UFixed256x18 b) internal pure returns (UFixed256x18) {\n            return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n        }\n        /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked\n        /// arithmetic on uint256.\n        function mul(UFixed256x18 a, uint256 b) internal pure returns (UFixed256x18) {\n            return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n        }\n        /// Take the floor of a UFixed256x18 number.\n        /// @return the largest integer that does not exceed `a`.\n        function floor(UFixed256x18 a) internal pure returns (uint256) {\n            return UFixed256x18.unwrap(a) / multiplier;\n        }\n        /// Turns a uint256 into a UFixed256x18 of the same value.\n        /// Reverts if the integer is too large.\n        function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n            return UFixed256x18.wrap(a * multiplier);\n        }\n    }\n\nNotice how ``UFixed256x18.wrap`` and ``FixedMath.toUFixed256x18`` have the same signature but\nperform two very different operations: The ``UFixed256x18.wrap`` function returns a ``UFixed256x18``\nthat has the same data representation as the input, whereas ``toUFixed256x18`` returns a\n``UFixed256x18`` that has the same numerical value.\n\n.. index:: ! function type, ! type; function\n\n.. _function_types:\n\nFunction Types\n--------------\n\nFunction types are the types of functions. Variables of a function type\ncan be assigned from functions and function parameters of function type\ncan be used to pass functions to and return functions from function calls.\nFunction types come in two flavours - *internal* and *external* functions:\n\nInternal functions can only be called inside the current contract (more specifically,\ninside the current code unit, which also includes internal library functions\nand inherited functions) because they cannot be executed outside of the\ncontext of the current contract. Calling an internal function is realized\nby jumping to its entry label, just like when calling a function of the current\ncontract internally.\n\nExternal functions consist of an address and a function signature and they can\nbe passed via and returned from external function calls.\n\nNote that public functions of the current contract can be used both as an\ninternal and as an external function. To use ``f`` as an internal function,\njust use ``f``, if you want to use its external form, use ``this.f``.\n\nIf a function type variable is not initialised, calling it results\nin a :ref:`Panic error<assert-and-require>`. The same happens if you call a function after using ``delete``\non it.\n\n.. note::\n    Lambda or inline functions are planned but not yet supported.\n\nDeclaration syntax\n^^^^^^^^^^^^^^^^^^\n\nFunction types are notated as follows:\n\n.. code-block:: solidity\n    :force:\n\n    function (<parameter types>) {internal|external} [pure|view|payable] [returns (<return types>)]\n\nIn contrast to the parameter types, the return types cannot be empty - if the\nfunction type should not return anything, the whole ``returns (<return types>)``\npart has to be omitted.\n\nBy default, function types are internal, so the ``internal`` keyword can be\nomitted. Note that this only applies to function types. Visibility has\nto be specified explicitly for functions defined in contracts, they\ndo not have a default.\n\nConversions\n^^^^^^^^^^^\n\nA function type ``A`` is implicitly convertible to a function type ``B`` if and only if\ntheir parameter types are identical, their return types are identical,\ntheir internal/external property is identical and the state mutability of ``A``\nis more restrictive than the state mutability of ``B``. In particular:\n\n- ``pure`` functions can be converted to ``view`` and ``non-payable`` functions\n- ``view`` functions can be converted to ``non-payable`` functions\n- ``payable`` functions can be converted to ``non-payable`` functions\n\nNo other conversions between function types are possible.\n\nThe rule about ``payable`` and ``non-payable`` might be a little\nconfusing, but in essence, if a function is ``payable``, this means that it\nalso accepts a payment of zero Ether, so it also is ``non-payable``.\nOn the other hand, a ``non-payable`` function will reject Ether sent to it,\nso ``non-payable`` functions cannot be converted to ``payable`` functions.\nTo clarify, rejecting ether is more restrictive than not rejecting ether.\nThis means you can override a payable function with a non-payable but not the\nother way around.\n\nAdditionally, When you define a ``non-payable`` function pointer,\nthe compiler does not enforce that the pointed function will actually reject ether.\nInstead, it enforces that the function pointer is never used to send ether.\nWhich makes it possible to assign a ``payable`` function pointer to a ``non-payable``\nfunction pointer ensuring both types behave the same way, i.e, both cannot be used\nto send ether.\n\nIf external function types are used outside of the context of Solidity,\nthey are treated as the ``function`` type, which encodes the address\nfollowed by the function identifier together in a single ``bytes24`` type.\n\nA function of an internal type can be assigned to a variable of an internal function type regardless\nof where it is defined.\nThis includes private, internal and public functions of both contracts and libraries as well as free\nfunctions.\nExternal function types, on the other hand, are only compatible with public and external contract\nfunctions.\n\n.. note::\n    External functions with ``calldata`` parameters are incompatible with external function types with ``calldata`` parameters.\n    They are compatible with the corresponding types with ``memory`` parameters instead.\n    For example, there is no function that can be pointed at by a value of type ``function (string calldata) external`` while\n    ``function (string memory) external`` can point at both ``function f(string memory) external {}`` and\n    ``function g(string calldata) external {}``.\n    This is because for both locations the arguments are passed to the function in the same way.\n    The caller cannot pass its calldata directly to an external function and always ABI-encodes the arguments into memory.\n    Marking the parameters as ``calldata`` only affects the implementation of the external function and is\n    meaningless in a function pointer on the caller's side.\n\n.. warning::\n    Comparison of internal function pointers can have unexpected results in the legacy pipeline with the optimizer enabled,\n    as it can collapse identical functions into one, which will then lead to said function pointers comparing as equal instead of not.\n    Such comparisons are not advised, and will lead to the compiler issuing a warning, until the next breaking release (0.9.0),\n    when the warning will be upgraded to an error, thereby making such comparisons disallowed.\n\nLibraries are excluded because they require a ``delegatecall`` and use :ref:`a different ABI\nconvention for their selectors <library-selectors>`.\nFunctions declared in interfaces do not have definitions so pointing at them does not make sense either.\n\nMembers\n^^^^^^^\n\nExternal (or public) functions have the following members:\n\n* ``.address`` returns the address of the contract of the function.\n* ``.selector`` returns the :ref:`ABI function selector <abi_function_selector>`\n\n.. note::\n  External (or public) functions used to have the additional members\n  ``.gas(uint)`` and ``.value(uint)``. These were deprecated in Solidity 0.6.2\n  and removed in Solidity 0.7.0. Instead use ``{gas: ...}`` and ``{value: ...}``\n  to specify the amount of gas or the amount of wei sent to a function,\n  respectively. See :ref:`External Function Calls <external-function-calls>` for\n  more information.\n\n.. _function-type-value-stability-across-contract-updates:\n\nValue stability across contract updates\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAn important aspect to consider when using values of function types is whether the value will\nremain valid if the underlying code changes.\n\nThe state of the blockchain is not completely immutable and there are multiple ways to place\ndifferent code under the same address:\n\n- Directly deploying different code using :ref:`salted contract creation<salted-contract-creations>`.\n- Delegating to a different contract via :ref:`DELEGATECALL<delegatecall>`\n  (upgradeable code behind a proxy contract is a common example of this).\n- Account abstraction as defined by `EIP-7702 <https://eips.ethereum.org/EIPS/eip-7702>`_.\n\nExternal function types can be considered as stable as contract's ABI, which makes them very portable.\nTheir ABI representation always consists of a contract address and a function selector and it is\nperfectly safe to store them long-term or pass them between contracts.\nWhile it is possible for the referenced function to change or disappear, a direct external call\nwould be affected the same way, so there is no additional risk in such use.\n\nIn case of internal functions, however, the value is an identifier that is strongly tied to\ncontract's bytecode.\nThe actual representation of the identifier is an implementation detail and may change between\ncompiler versions or even :ref:`between different backends<internal-function-pointers-in-ir>`.\nValues assigned under a given representation are deterministic (i.e. guaranteed to remain the same\nas long as the source code is the same) but are easily affected by changes such as adding, removing\nor reordering of functions.\nThe compiler is also free to remove internal functions that are never used, which may affect other identifiers.\nSome representations, e.g. one where identifiers are simply jump targets, may be affected by\nvirtually any change, even one completely unrelated to internal functions.\n\nTo counter this, the language limits the use of internal function types outside of the context in\nwhich they are valid.\nThis is why internal function types cannot be used as parameters of external functions (or in any\nother way that is exposed in contract's ABI).\nHowever, there are still situations where it is up to the user to decide whether their use is safe or not.\nFor example long-term storage of such values in state variables is discouraged, but may be safe if\nthe contract code is never going to be updated.\nIt is also always possible to side-step any safeguards by using inline assembly.\nSuch use always needs careful consideration.\n\n.. note::\n    The removal of unused internal functions only takes into account explicit references to\n    such functions by name.\n    Implicit references, such as assigning a new value to a function type variable in inline assembly\n    may still lead to the removal of the function if it is not also referenced explicitly elsewhere\n    in the source.\n\nExamples\n^^^^^^^^\n\nExample that shows how to use the members:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.6.4 <0.9.0;\n\n    contract Example {\n        function f() public payable returns (bytes4) {\n            assert(this.f.address == address(this));\n            return this.f.selector;\n        }\n\n        function g() public {\n            this.f{gas: 10, value: 800}();\n        }\n    }\n\nExample that shows how to use internal function types:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.16 <0.9.0;\n\n    library ArrayUtils {\n        // internal functions can be used in internal library functions because\n        // they will be part of the same code context\n        function map(uint[] memory self, function (uint) pure returns (uint) f)\n            internal\n            pure\n            returns (uint[] memory r)\n        {\n            r = new uint[](self.length);\n            for (uint i = 0; i < self.length; i++) {\n                r[i] = f(self[i]);\n            }\n        }\n\n        function reduce(\n            uint[] memory self,\n            function (uint, uint) pure returns (uint) f\n        )\n            internal\n            pure\n            returns (uint r)\n        {\n            r = self[0];\n            for (uint i = 1; i < self.length; i++) {\n                r = f(r, self[i]);\n            }\n        }\n\n        function range(uint length) internal pure returns (uint[] memory r) {\n            r = new uint[](length);\n            for (uint i = 0; i < r.length; i++) {\n                r[i] = i;\n            }\n        }\n    }\n\n\n    contract Pyramid {\n        using ArrayUtils for *;\n\n        function pyramid(uint l) public pure returns (uint) {\n            return ArrayUtils.range(l).map(square).reduce(sum);\n        }\n\n        function square(uint x) internal pure returns (uint) {\n            return x * x;\n        }\n\n        function sum(uint x, uint y) internal pure returns (uint) {\n            return x + y;\n        }\n    }\n\nAnother example that uses external function types:\n\n.. code-block:: solidity\n\n    // SPDX-License-Identifier: GPL-3.0\n    pragma solidity >=0.4.22 <0.9.0;\n\n\n    contract Oracle {\n        struct Request {\n            bytes data;\n            function(uint) external callback;\n        }\n\n        Request[] private requests;\n        event NewRequest(uint);\n\n        function query(bytes memory data, function(uint) external callback) public {\n            requests.push(Request(data, callback));\n            emit NewRequest(requests.length - 1);\n        }\n\n        function reply(uint requestID, uint response) public {\n            // Here goes the check that the reply comes from a trusted source\n            requests[requestID].callback(response);\n        }\n    }\n\n\n    contract OracleUser {\n        Oracle constant private ORACLE_CONST = Oracle(address(0x00000000219ab540356cBB839Cbe05303d7705Fa)); // known contract\n        uint private exchangeRate;\n\n        function buySomething() public {\n            ORACLE_CONST.query(\"USD\", this.oracleResponse);\n        }\n\n        function oracleResponse(uint response) public {\n            require(\n                msg.sender == address(ORACLE_CONST),\n                \"Only oracle can call this.\"\n            );\n            exchangeRate = response;\n        }\n    }\n"
  },
  {
    "path": "docs/types.rst",
    "content": ".. index:: type\n\n.. _types:\n\n*****\nTypes\n*****\n\nSolidity is a statically typed language, which means that the type of each\nvariable (state and local) needs to be specified.\nSolidity provides several elementary types which can be combined to form complex types.\n\nIn addition, types can interact with each other in expressions containing\noperators. For a quick reference of the various operators, see :ref:`order`.\n\nThe concept of \"undefined\" or \"null\" values does not exist in Solidity, but newly\ndeclared variables always have a :ref:`default value<default-value>` dependent\non its type. To handle any unexpected values, you should use the :ref:`revert function<assert-and-require>` to revert the whole transaction, or return a\ntuple with a second ``bool`` value denoting success.\n\n.. include:: types/value-types.rst\n\n.. include:: types/reference-types.rst\n\n.. include:: types/mapping-types.rst\n\n.. include:: types/operators.rst\n\n.. include:: types/conversion.rst\n"
  },
  {
    "path": "docs/units-and-global-variables.rst",
    "content": ".. index:: ! denomination\n\n**************************************\nUnits and Globally Available Variables\n**************************************\n\n.. index:: ! wei, ! finney, ! szabo, ! gwei, ! ether, ! denomination;ether\n\nEther Units\n===========\n\nA literal number can take a suffix of ``wei``, ``gwei`` or ``ether`` to specify a subdenomination of Ether, where Ether numbers without a postfix are assumed to be Wei.\n\n.. code-block:: solidity\n    :force:\n\n    assert(1 wei == 1);\n    assert(1 gwei == 1e9);\n    assert(1 ether == 1e18);\n\nThe only effect of the subdenomination suffix is a multiplication by a power of ten.\n\n.. note::\n    The denominations ``finney`` and ``szabo`` have been removed in version 0.7.0.\n\n.. index:: ! seconds, ! minutes, ! hours, ! days, ! weeks, ! years, ! denomination;time\n\nTime Units\n==========\n\nSuffixes like ``seconds``, ``minutes``, ``hours``, ``days`` and ``weeks``\nafter literal numbers can be used to specify units of time where seconds are the base\nunit and units are considered naively in the following way:\n\n* ``1 == 1 seconds``\n* ``1 minutes == 60 seconds``\n* ``1 hours == 60 minutes``\n* ``1 days == 24 hours``\n* ``1 weeks == 7 days``\n\nTake care if you perform calendar calculations using these units, because\nnot every year equals 365 days and not even every day has 24 hours\nbecause of `leap seconds <https://en.wikipedia.org/wiki/Leap_second>`_.\nDue to the fact that leap seconds cannot be predicted, an exact calendar\nlibrary has to be updated by an external oracle.\n\n.. note::\n    The suffix ``years`` has been removed in version 0.5.0 due to the reasons above.\n\nThese suffixes cannot be applied to variables. For example, if you want to\ninterpret a function parameter in days, you can in the following way:\n\n.. code-block:: solidity\n\n    function f(uint start, uint daysAfter) public {\n        if (block.timestamp >= start + daysAfter * 1 days) {\n            // ...\n        }\n    }\n\n.. _special-variables-functions:\n\nSpecial Variables and Functions\n===============================\n\nThere are special variables and functions which always exist in the global\nnamespace and are mainly used to provide information about the blockchain\nor are general-use utility functions.\n\n.. index:: abi, block, coinbase, difficulty, prevrandao, encode, number, block;number, timestamp, block;timestamp, block;basefee, block;blobbasefee, msg, data, gas, sender, value, gas price, origin\n\n\nBlock and Transaction Properties\n--------------------------------\n\n- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block when ``blocknumber`` is one of the 256 most recent blocks; otherwise returns zero\n- ``blobhash(uint index) returns (bytes32)``: versioned hash of the ``index``-th blob associated with the current transaction.\n  A versioned hash consists of a single byte representing the version (currently ``0x01``), followed by the last 31 bytes\n  of the SHA256 hash of the KZG commitment (`EIP-4844 <https://eips.ethereum.org/EIPS/eip-4844>`_).\n  Returns zero if no blob with the given index exists.\n- ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_)\n- ``block.blobbasefee`` (``uint``): current block's blob base fee (`EIP-7516 <https://eips.ethereum.org/EIPS/eip-7516>`_ and `EIP-4844 <https://eips.ethereum.org/EIPS/eip-4844>`_)\n- ``block.chainid`` (``uint``): current chain id\n- ``block.coinbase`` (``address payable``): current block miner's address\n- ``block.difficulty`` (``uint``): current block difficulty (``EVM < Paris``). For other EVM versions it behaves as a deprecated alias for ``block.prevrandao`` (`EIP-4399 <https://eips.ethereum.org/EIPS/eip-4399>`_ )\n- ``block.gaslimit`` (``uint``): current block gaslimit\n- ``block.number`` (``uint``): current block number\n- ``block.prevrandao`` (``uint``): random number provided by the beacon chain (``EVM >= Paris``)\n- ``block.timestamp`` (``uint``): current block timestamp as seconds since unix epoch\n- ``gasleft() returns (uint256)``: remaining gas\n- ``msg.data`` (``bytes calldata``): complete calldata\n- ``msg.sender`` (``address``): sender of the message (current call)\n- ``msg.sig`` (``bytes4``): first four bytes of the calldata (i.e. function identifier)\n- ``msg.value`` (``uint``): number of wei sent with the message\n- ``tx.gasprice`` (``uint``): gas price of the transaction\n- ``tx.origin`` (``address``): sender of the transaction (full call chain)\n\n.. note::\n    The values of all members of ``msg``, including ``msg.sender`` and\n    ``msg.value`` can change for every **external** function call.\n    This includes calls to library functions.\n\n.. note::\n    When contracts are evaluated off-chain rather than in context of a transaction included in a\n    block, you should not assume that ``block.*`` and ``tx.*`` refer to values from any specific\n    block or transaction. These values are provided by the EVM implementation that executes the\n    contract and can be arbitrary.\n\n.. note::\n    Do not rely on ``block.timestamp`` or ``blockhash`` as a source of randomness,\n    unless you know what you are doing.\n\n    Both the timestamp and the block hash can be influenced by miners to some degree.\n    Bad actors in the mining community can for example run a casino payout function on a chosen hash\n    and just retry a different hash if they did not receive any compensation, e.g. Ether.\n\n    The current block timestamp must be strictly larger than the timestamp of the last block,\n    but the only guarantee is that it will be somewhere between the timestamps of two\n    consecutive blocks in the canonical chain.\n\n.. note::\n    The block hashes are not available for all blocks for scalability reasons.\n    You can only access the hashes of the most recent 256 blocks, all other\n    values will be zero.\n\n.. note::\n    The function ``blockhash`` was previously known as ``block.blockhash``, which was deprecated in\n    version 0.4.22 and removed in version 0.5.0.\n\n.. note::\n    The function ``gasleft`` was previously known as ``msg.gas``, which was deprecated in\n    version 0.4.21 and removed in version 0.5.0.\n\n.. note::\n    In version 0.7.0, the alias ``now`` (for ``block.timestamp``) was removed.\n\n.. index:: abi, encoding, packed\n\nABI Encoding and Decoding Functions\n-----------------------------------\n\n- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: ABI-decodes the given data, while the types are given in parentheses as second argument. Example: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))``\n- ``abi.encode(...) returns (bytes memory)``: ABI-encodes the given arguments\n- ``abi.encodePacked(...) returns (bytes memory)``: Performs :ref:`packed encoding <abi_packed_mode>` of the given arguments. Note that packed encoding can be ambiguous!\n- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: ABI-encodes the given arguments starting from the second and prepends the given four-byte selector\n- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)``\n- ``abi.encodeCall(function functionPointer, (...)) returns (bytes memory)``: ABI-encodes a call to ``functionPointer`` with the arguments found in the tuple. Performs a full type-check, ensuring the types match the function signature. Result equals ``abi.encodeWithSelector(functionPointer.selector, (...))``\n\n.. note::\n    These encoding functions can be used to craft data for external function calls without actually\n    calling an external function. Furthermore, ``keccak256(abi.encodePacked(a, b))`` is a way\n    to compute the hash of structured data (although be aware that it is possible to\n    craft a \"hash collision\" using different function parameter types).\n\nSee the documentation about the :ref:`ABI <ABI>` and the\n:ref:`tightly packed encoding <abi_packed_mode>` for details about the encoding.\n\n.. index:: bytes members\n\nMembers of bytes\n----------------\n\n- ``bytes.concat(...) returns (bytes memory)``: :ref:`Concatenates variable number of bytes and bytes1, ..., bytes32 arguments to one byte array<bytes-concat>`\n\n.. index:: string members\n\nMembers of string\n-----------------\n\n- ``string.concat(...) returns (string memory)``: :ref:`Concatenates variable number of string arguments to one string array<string-concat>`\n\n\n.. index:: assert, revert, require\n\nError Handling\n--------------\n\nSee the dedicated section on :ref:`assert and require<assert-and-require>` for\nmore details on error handling and when to use which function.\n\n``assert(bool condition)``\n    causes a Panic error and thus state change reversion if the condition is not met - to be used for internal errors.\n\n``require(bool condition)``\n    reverts if the condition is not met - to be used for errors in inputs or external components.\n\n``require(bool condition, string memory message)``\n    reverts if the condition is not met - to be used for errors in inputs or external components. Also provides an error message.\n\n``revert()``\n    abort execution and revert state changes\n\n``revert(string memory reason)``\n    abort execution and revert state changes, providing an explanatory string\n\n.. index:: keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, erc7201,\n\n.. _mathematical-and-cryptographic-functions:\n\nMathematical and Cryptographic Functions\n----------------------------------------\n\n``addmod(uint x, uint y, uint k) returns (uint)``\n    compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.\n\n``mulmod(uint x, uint y, uint k) returns (uint)``\n    compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0.\n\n``keccak256(bytes memory) returns (bytes32)``\n    compute the Keccak-256 hash of the input\n\n.. note::\n\n    There used to be an alias for ``keccak256`` called ``sha3``, which was removed in version 0.5.0.\n\n``sha256(bytes memory) returns (bytes32)``\n    compute the SHA-256 hash of the input\n\n``ripemd160(bytes memory) returns (bytes20)``\n    compute RIPEMD-160 hash of the input\n\n``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``\n    recover the address associated with the public key from elliptic curve signature or return zero on error.\n    The function parameters correspond to ECDSA values of the signature:\n\n    * ``r`` = first 32 bytes of signature\n    * ``s`` = second 32 bytes of signature\n    * ``v`` = final 1 byte of signature\n\n    ``ecrecover`` returns an ``address``, and not an ``address payable``. See :ref:`address payable<address>` for\n    conversion, in case you need to transfer funds to the recovered address.\n\n    For further details, read `example usage <https://ethereum.stackexchange.com/questions/1777/workflow-on-signing-a-string-with-private-key-followed-by-signature-verificatio>`_.\n\n.. warning::\n\n    If you use ``ecrecover``, be aware that a valid signature can be turned into a different valid signature without\n    requiring knowledge of the corresponding private key. In the Homestead hard fork, this issue was fixed\n    for _transaction_ signatures (see `EIP-2 <https://eips.ethereum.org/EIPS/eip-2#specification>`_), but\n    the ecrecover function remained unchanged.\n\n    This is usually not a problem unless you require signatures to be unique or use them to identify items.\n    OpenZeppelin has an `ECDSA helper library <https://docs.openzeppelin.com/contracts/4.x/api/utils#ECDSA>`_ that you can use as a wrapper for ``ecrecover`` without this issue.\n\n.. note::\n\n    When running ``sha256``, ``ripemd160`` or ``ecrecover`` on a *private blockchain*, you might encounter Out-of-Gas. This is because these functions are implemented as \"precompiled contracts\" and only really exist after they receive the first message (although their contract code is hardcoded). Messages to non-existing contracts are more expensive and thus the execution might run into an Out-of-Gas error. A workaround for this problem is to first send Wei (1 for example) to each of the contracts before you use them in your actual contracts. This is not an issue on the main or test net.\n\n``erc7201(string memory id) returns (uint)``\n    compute the base slot of a storage namespace of a given ``id`` according to the ``erc7201`` formula defined by `ERC-7201<https://eips.ethereum.org/EIPS/eip-7201>`.\n    The formula is equivalent to ``keccak256(keccak256(id) - 1) & ~0xff``.\n    The builtin accepts arbitrary strings, including ones containing whitespace.\n    The function can be used in compile-time context.\n\n.. index:: balance, codehash, send, transfer, call, callcode, delegatecall, staticcall\n\n.. _address_related:\n\nMembers of Address Types\n------------------------\nThese members are explained in more detail in the section on :ref:`members of address <members-of-addresses>`.\n\n``<address>.balance`` (``uint256``)\n    balance of the :ref:`address` in Wei\n\n``<address>.code`` (``bytes memory``)\n    code at the :ref:`address` (can be empty)\n\n``<address>.codehash`` (``bytes32``)\n    the codehash of the :ref:`address`\n\n``<address payable>.transfer(uint256 amount)``\n    send given amount of Wei to :ref:`address`, reverts on failure, forwards 2300 gas stipend, not adjustable\n\n``<address payable>.send(uint256 amount) returns (bool)``\n    send given amount of Wei to :ref:`address`, returns ``false`` on failure, forwards 2300 gas stipend, not adjustable\n\n.. warning::\n    ``send()`` and ``transfer()`` are deprecated and scheduled for removal.\n    See the section on :ref:`send <send-address-member>` and :ref:`transfer <balance-transfer-address-members>` for more information.\n\n``<address>.call(bytes memory) returns (bool, bytes memory)``\n    issue low-level ``CALL`` with the given payload, returns success condition and return data,\n    forwards all available gas (subject to additional limits imposed by some EVM versions), adjustable\n\n``<address>.delegatecall(bytes memory) returns (bool, bytes memory)``\n    issue low-level ``DELEGATECALL`` with the given payload, returns success condition and return data,\n    forwards all available gas (subject to additional limits imposed by some EVM versions), adjustable\n\n``<address>.staticcall(bytes memory) returns (bool, bytes memory)``\n    issue low-level ``STATICCALL`` with the given payload, returns success condition and return data,\n    forwards all available gas (subject to additional limits imposed by some EVM versions), adjustable\n\nFor more information, see the section on :ref:`address`.\n\n.. warning::\n    You should avoid using ``.call()`` whenever possible when executing another contract function as it bypasses type checking,\n    function existence check, and argument packing.\n\n.. warning::\n    There are some dangers in using ``send``: The transfer fails if the call stack depth is at 1024\n    (this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order\n    to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:\n    Use a pattern where the recipient withdraws the Ether.\n\n.. warning::\n    Due to the fact that the EVM considers a call to a non-existing contract to always succeed,\n    Solidity includes an extra check using the ``extcodesize`` opcode when performing external calls.\n    This ensures that the contract that is about to be called either actually exists (it contains code)\n    or an exception is raised.\n\n    The low-level calls which operate on addresses rather than contract instances (i.e. ``.call()``,\n    ``.delegatecall()``, ``.staticcall()``, ``.send()`` and ``.transfer()``) **do not** include this\n    check, which makes them cheaper in terms of gas but also less safe.\n\n.. note::\n   Prior to version 0.5.0, Solidity allowed address members to be accessed by a contract instance, for example ``this.balance``.\n   This is now forbidden and an explicit conversion to address must be done: ``address(this).balance``.\n\n.. note::\n   If state variables are accessed via a low-level delegatecall, the storage layout of the two contracts\n   must align in order for the called contract to correctly access the storage variables of the calling contract by name.\n   This is of course not the case if storage pointers are passed as function arguments as in the case for\n   the high-level libraries.\n\n.. note::\n    Prior to version 0.5.0, ``.call``, ``.delegatecall`` and ``.staticcall`` only returned the\n    success condition and not the return data.\n\n.. note::\n    Prior to version 0.5.0, there was a member called ``callcode`` with similar but slightly different\n    semantics than ``delegatecall``.\n\n\n.. index:: this, selfdestruct, super\n\nContract-related\n----------------\n\n``this`` (current contract's type)\n    The current contract, explicitly convertible to :ref:`address`\n\n``super``\n    A contract one level higher in the inheritance hierarchy\n\n``selfdestruct(address payable recipient)``\n    Destroy the current contract, sending its funds to the given :ref:`address`\n    and end execution.\n    Note that ``selfdestruct`` has some peculiarities inherited from the EVM:\n\n    - the receiving contract's receive function is not executed.\n    - the contract is only really destroyed at the end of the transaction and ``revert`` s might \"undo\" the destruction.\n\nFurthermore, all functions of the current contract are callable directly including the current function.\n\n.. warning::\n    From ``EVM >= Cancun`` onwards, ``selfdestruct`` will **only** send all Ether in the account to the given recipient and not destroy the contract.\n    However, when ``selfdestruct`` is called in the same transaction that creates the contract calling it,\n    the behaviour of ``selfdestruct`` before Cancun hardfork (i.e., ``EVM <= Shanghai``) is preserved and will destroy the current contract,\n    deleting any data, including storage keys, code and the account itself.\n    See `EIP-6780 <https://eips.ethereum.org/EIPS/eip-6780>`_ for more details.\n\n    The new behaviour is the result of a network-wide change that affects all contracts present on\n    the Ethereum mainnet and testnets.\n    It is important to note that this change is dependent on the EVM version of the chain on which\n    the contract is deployed.\n    The ``--evm-version`` setting used when compiling the contract has no bearing on it.\n\n    Also, note that the ``selfdestruct`` opcode has been deprecated in Solidity version 0.8.18,\n    as recommended by `EIP-6049 <https://eips.ethereum.org/EIPS/eip-6049>`_.\n    The deprecation is still in effect and the compiler will still emit warnings on its use.\n    Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account.\n    Future changes to the EVM might further reduce the functionality of the opcode.\n\n.. note::\n    Prior to version 0.5.0, there was a function called ``suicide`` with the same\n    semantics as ``selfdestruct``.\n\n.. index:: type, creationCode, runtimeCode\n\n.. _meta-type:\n\nType Information\n----------------\n\nThe expression ``type(X)`` can be used to retrieve information about the type\n``X``. Currently, there is limited support for this feature (``X`` can be either\na contract or an integer type) but it might be expanded in the future.\n\nThe following properties are available for a contract type ``C``:\n\n``type(C).name``\n    The name of the contract.\n\n``type(C).creationCode``\n    Memory byte array that contains the creation bytecode of the contract.\n    This can be used in inline assembly to build custom creation routines,\n    especially by using the ``create2`` opcode.\n    This property can **not** be accessed in the contract itself or any\n    derived contract. It causes the bytecode to be included in the bytecode\n    of the call site and thus circular references like that are not possible.\n\n``type(C).runtimeCode``\n    Memory byte array that contains the runtime bytecode of the contract.\n    This is the code that is usually deployed by the constructor of ``C``.\n    If ``C`` has a constructor that uses inline assembly, this might be\n    different from the actually deployed bytecode. Also note that libraries\n    modify their runtime bytecode at time of deployment to guard against\n    regular calls.\n    The same restrictions as with ``.creationCode`` also apply for this\n    property.\n\nIn addition to the properties above, the following properties are available\nfor an interface type ``I``:\n\n``type(I).interfaceId``\n    A ``bytes4`` value containing the `EIP-165 <https://eips.ethereum.org/EIPS/eip-165>`_\n    interface identifier of the given interface ``I``. This identifier is defined as the ``XOR`` of all\n    function selectors defined within the interface itself - excluding all inherited functions.\n\nThe following properties are available for an integer type ``T``:\n\n``type(T).min``\n    The smallest value representable by type ``T``.\n\n``type(T).max``\n    The largest value representable by type ``T``.\n\nReserved Keywords\n=================\n\nThese keywords are reserved in Solidity. They might become part of the syntax in the future:\n\n``after``, ``alias``, ``apply``, ``auto``, ``byte``, ``case``, ``copyof``, ``default``,\n``define``, ``final``, ``implements``, ``in``, ``inline``, ``let``, ``macro``, ``match``,\n``mutable``, ``null``, ``of``, ``partial``, ``promise``, ``reference``, ``relocatable``,\n``sealed``, ``sizeof``, ``static``, ``supports``, ``switch``, ``typedef``, ``typeof``,\n``var``.\n"
  },
  {
    "path": "docs/using-the-compiler.rst",
    "content": "******************\nUsing the Compiler\n******************\n\n.. index:: ! commandline compiler, compiler;commandline, ! solc\n\n.. _commandline-compiler:\n\nUsing the Commandline Compiler\n******************************\n\n.. note::\n    This section does not apply to :ref:`solcjs <solcjs>`, not even if it is used in commandline mode.\n\nBasic Usage\n-----------\n\nOne of the build targets of the Solidity repository is ``solc``, the Solidity commandline compiler.\nUsing ``solc --help`` provides you with an explanation of all options. The compiler can produce various outputs, ranging from simple binaries and assembly over an abstract syntax tree (parse tree) to estimations of gas usage.\nIf you only want to compile a single file, you run it as ``solc --bin sourceFile.sol`` and it will print the binary. If you want to get some of the more advanced output variants of ``solc``, it is probably better to tell it to output everything to separate files using ``solc -o outputDirectory --bin --ast-compact-json --asm sourceFile.sol``.\n\nOptimizer Options\n-----------------\n\nBefore you deploy your contract, activate the optimizer when compiling using ``solc --optimize --bin sourceFile.sol``.\nBy default, the optimizer will optimize the contract assuming it is called 200 times across its lifetime\n(more specifically, it assumes each opcode is executed around 200 times).\nIf you want the initial contract deployment to be cheaper and the later function executions to be more expensive,\nset it to ``--optimize-runs=1``. If you expect many transactions and do not care for higher deployment cost and\noutput size, set ``--optimize-runs`` to a high number.\nThis parameter has effects on the following (this might change in the future):\n\n- the size of the binary search in the function dispatch routine\n- the way constants like large numbers or strings are stored\n\n.. index:: allowed paths, --allow-paths, base path, --base-path, include paths, --include-path\n\nBase Path and Import Remapping\n------------------------------\n\nThe commandline compiler will automatically read imported files from the filesystem, but\nit is also possible to provide :ref:`path redirects <import-remapping>` using ``prefix=path`` in the following way:\n\n.. code-block:: bash\n\n    solc github.com/ethereum/dapp-bin/=/usr/local/lib/dapp-bin/ file.sol\n\nThis essentially instructs the compiler to search for anything starting with\n``github.com/ethereum/dapp-bin/`` under ``/usr/local/lib/dapp-bin``.\n\nWhen accessing the filesystem to search for imports, :ref:`paths that do not start with ./\nor ../ <direct-imports>` are treated as relative to the directories specified using\n``--base-path`` and ``--include-path`` options (or the current working directory if base path is not specified).\nFurthermore, the part of the path added via these options will not appear in the contract metadata.\n\nFor security reasons the compiler has :ref:`restrictions on what directories it can access <allowed-paths>`.\nDirectories of source files specified on the command-line and target paths of\nremappings are automatically allowed to be accessed by the file reader, but everything\nelse is rejected by default.\nAdditional paths (and their subdirectories) can be allowed via the\n``--allow-paths /sample/path,/another/sample/path`` switch.\nEverything inside the path specified via ``--base-path`` is always allowed.\n\nThe above is only a simplification of how the compiler handles import paths.\nFor a detailed explanation with examples and discussion of corner cases please refer to the section on\n:ref:`path resolution <path-resolution>`.\n\n.. index:: ! linker, ! --link, ! --libraries\n.. _library-linking:\n\nLibrary Linking\n---------------\n\nIf your contracts use :ref:`libraries <libraries>`, you will notice that the bytecode contains substrings of the form ``__$53aea86b7d70b31448b230b20ae141a537$__`` `(format was different <v0.5.0) <https://docs.soliditylang.org/en/v0.4.26/contracts.html#libraries>`_. These are placeholders for the actual library addresses.\nThe placeholder is a 34 character prefix of the hex encoding of the keccak256 hash of the fully qualified library name.\nThe bytecode file will also contain lines of the form ``// <placeholder> -> <fq library name>`` at the end to help\nidentify which libraries the placeholders represent. Note that the fully qualified library name\nis the path of its source file and the library name separated by ``:``.\nYou can use ``solc`` as a linker meaning that it will insert the library addresses for you at those points:\n\nEither add ``--libraries \"file.sol:Math=0x1234567890123456789012345678901234567890 file.sol:Heap=0xabCD567890123456789012345678901234567890\"`` to your command to provide an address for each library (use commas or spaces as separators) or store the string in a file (one library per line) and run ``solc`` using ``--libraries fileName``.\n\n.. note::\n    Starting Solidity 0.8.1 accepts ``=`` as separator between library and address, and ``:`` as a separator is deprecated. It will be removed in the future. Currently ``--libraries \"file.sol:Math:0x1234567890123456789012345678901234567890 file.sol:Heap:0xabCD567890123456789012345678901234567890\"`` will work too.\n\n.. index:: --standard-json, --base-path\n\nIf ``solc`` is called with the option ``--standard-json``, it will expect a JSON input (as explained below) on the standard input, and return a JSON output on the standard output. This is the recommended interface for more complex and especially automated uses. The process will always terminate in a \"success\" state and report any errors via the JSON output.\nThe option ``--base-path`` is also processed in standard-json mode.\n\nIf ``solc`` is called with the option ``--link``, all input files are interpreted to be unlinked binaries (hex-encoded) in the ``__$53aea86b7d70b31448b230b20ae141a537$__``-format given above and are linked in-place (if the input is read from stdin, it is written to stdout). All options except ``--libraries`` are ignored (including ``-o``) in this case.\n\n.. warning::\n    Manually linking libraries on the generated bytecode is discouraged because it does not update\n    contract metadata. Since metadata contains a list of libraries specified at the time of\n    compilation and bytecode contains a metadata hash, you will get different binaries, depending\n    on when linking is performed.\n\n    You should ask the compiler to link the libraries at the time a contract is compiled by either\n    using the ``--libraries`` option of ``solc`` or the ``libraries`` key if you use the\n    standard-JSON interface to the compiler.\n\n.. note::\n    The library placeholder used to be the fully qualified name of the library itself\n    instead of the hash of it. This format is still supported by ``solc --link`` but\n    the compiler will no longer output it. This change was made to reduce\n    the likelihood of a collision between libraries, since only the first 36 characters\n    of the fully qualified library name could be used.\n\n.. _evm-version:\n.. index:: ! EVM version, compile target\n\nSetting the EVM Version to Target\n*********************************\n\nWhen you compile your contract code you can specify the Ethereum virtual machine\nversion to compile for to avoid particular features or behaviors.\n\n.. warning::\n\n   Compiling for the wrong EVM version can result in wrong, strange and failing\n   behavior. Please ensure, especially if running a private chain, that you\n   use matching EVM versions.\n\nOn the command-line, you can select the EVM version as follows:\n\n.. code-block:: shell\n\n  solc --evm-version <VERSION> contract.sol\n\nIn the :ref:`standard JSON interface <compiler-api>`, use the ``\"evmVersion\"``\nkey in the ``\"settings\"`` field:\n\n.. code-block:: javascript\n\n    {\n      \"sources\": {/* ... */},\n      \"settings\": {\n        \"optimizer\": {/* ... */},\n        \"evmVersion\": \"<VERSION>\"\n      }\n    }\n\nTarget Options\n--------------\n\nBelow is a list of target EVM versions and the compiler-relevant changes introduced\nat each version. Backward compatibility is not guaranteed between each version.\n\n- ``homestead`` (*support deprecated*)\n   - (oldest version)\n- ``tangerineWhistle`` (*support deprecated*)\n   - Gas cost for access to other accounts increased, relevant for gas estimation and the optimizer.\n   - All gas sent by default for external calls, previously a certain amount had to be retained.\n- ``spuriousDragon`` (*support deprecated*)\n   - Gas cost for the ``exp`` opcode increased, relevant for gas estimation and the optimizer.\n- ``byzantium`` (*support deprecated*)\n   - Opcodes ``returndatacopy``, ``returndatasize`` and ``staticcall`` are available in assembly.\n   - The ``staticcall`` opcode is used when calling non-library view or pure functions, which prevents the functions from modifying state at the EVM level, i.e., even applies when you use invalid type conversions.\n   - It is possible to access dynamic data returned from function calls.\n   - ``revert`` opcode introduced, which means that ``revert()`` will not waste gas.\n- ``constantinople``\n   - Opcodes ``create2``, ``extcodehash``, ``shl``, ``shr`` and ``sar`` are available in assembly.\n   - Shifting operators use shifting opcodes and thus need less gas.\n- ``petersburg``\n   - The compiler behaves the same way as with constantinople.\n- ``istanbul``\n   - Opcodes ``chainid`` and ``selfbalance`` are available in assembly.\n- ``berlin``\n   - Gas costs for ``SLOAD``, ``*CALL``, ``BALANCE``, ``EXT*`` and ``SELFDESTRUCT`` increased. The\n     compiler assumes cold gas costs for such operations. This is relevant for gas estimation and\n     the optimizer.\n- ``london``\n   - The block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_) can be accessed via the global ``block.basefee`` or ``basefee()`` in inline assembly.\n- ``paris``\n   - Introduces ``prevrandao()`` and ``block.prevrandao``, and changes the semantics of the now deprecated ``block.difficulty``, disallowing ``difficulty()`` in inline assembly (see `EIP-4399 <https://eips.ethereum.org/EIPS/eip-4399>`_).\n- ``shanghai``\n   - Smaller code size and gas savings due to the introduction of ``push0`` (see `EIP-3855 <https://eips.ethereum.org/EIPS/eip-3855>`_).\n- ``cancun``\n   - The block's blob base fee (`EIP-7516 <https://eips.ethereum.org/EIPS/eip-7516>`_ and `EIP-4844 <https://eips.ethereum.org/EIPS/eip-4844>`_) can be accessed via the global ``block.blobbasefee`` or ``blobbasefee()`` in inline assembly.\n   - Introduces ``blobhash()`` in inline assembly and a corresponding global function to retrieve versioned hashes of blobs associated with the transaction (see `EIP-4844 <https://eips.ethereum.org/EIPS/eip-4844>`_).\n   - Opcode ``mcopy`` is available in assembly (see `EIP-5656 <https://eips.ethereum.org/EIPS/eip-5656>`_).\n   - Opcodes ``tstore`` and ``tload`` are available in assembly (see `EIP-1153 <https://eips.ethereum.org/EIPS/eip-1153>`_).\n- ``prague``\n- ``osaka`` (**default**)\n   - ``clz`` builtin function is available in inline assembly. (`EIP-7939 <https://eips.ethereum.org/EIPS/eip-7939>`_)\n\n.. index:: ! standard JSON, ! --standard-json\n.. _compiler-api:\n\nCompiler Input and Output JSON Description\n******************************************\n\nThe recommended way to interface with the Solidity compiler especially for\nmore complex and automated setups is the so-called JSON-input-output interface.\nThe same interface is provided by all distributions of the compiler.\n\nThe fields are generally subject to change,\nsome are optional (as noted), but we try to only make backwards compatible changes.\n\nThe compiler API expects a JSON formatted input and outputs the compilation result in a JSON formatted output.\nThe standard error output is not used and the process will always terminate in a \"success\" state, even\nif there were errors. Errors are always reported as part of the JSON output.\n\nThe following subsections describe the format through an example.\nComments are of course not permitted and used here only for explanatory purposes.\n\nInput Description\n-----------------\n\n.. code-block:: javascript\n\n    {\n      // Required: Source code language. Currently supported are \"Solidity\", \"Yul\", \"SolidityAST\" (experimental), \"EVMAssembly\" (experimental).\n      \"language\": \"Solidity\",\n      // Required\n      \"sources\":\n      {\n        // The keys here are the \"global\" names of the source files,\n        // imports can use other files via remappings (see below).\n        \"myFile.sol\":\n        {\n          // Optional: keccak256 hash of the source file\n          // It is used to verify the retrieved content if imported via URLs.\n          \"keccak256\": \"0x123...\",\n          // Required (unless \"content\" is used, see below): URL(s) to the source file.\n          // URL(s) should be imported in this order and the result checked against the\n          // keccak256 hash (if available). If the hash doesn't match or none of the\n          // URL(s) result in success, an error should be raised.\n          // Using the commandline interface only filesystem paths are supported.\n          // With the JavaScript interface the URL will be passed to the user-supplied\n          // read callback, so any URL supported by the callback can be used.\n          \"urls\":\n          [\n            \"bzzr://56ab...\",\n            \"ipfs://Qma...\",\n            \"/tmp/path/to/file.sol\"\n            // If files are used, their directories should be added to the command-line via\n            // `--allow-paths <path>`.\n          ]\n        },\n        \"settable\":\n        {\n          // Optional: keccak256 hash of the source file\n          \"keccak256\": \"0x234...\",\n          // Required (unless \"urls\" is used): literal contents of the source file\n          \"content\": \"contract settable is owned { uint256 private x = 0; function set(uint256 _x) public { if (msg.sender == owner) x = _x; } }\"\n        },\n        \"myFile.sol_json.ast\":\n        {\n          // If language is set to \"SolidityAST\", an AST needs to be supplied under the \"ast\" key\n          // and there can be only one source file present.\n          // The format is the same as used by the `ast` output.\n          // Note that importing ASTs is experimental and in particular that:\n          // - importing invalid ASTs can produce undefined results and\n          // - no proper error reporting is available on invalid ASTs.\n          // Furthermore, note that the AST import only consumes the fields of the AST as\n          // produced by the compiler in \"stopAfter\": \"parsing\" mode and then re-performs\n          // analysis, so any analysis-based annotations of the AST are ignored upon import.\n          \"ast\": { ... }\n        },\n        \"myFile_evm.json\":\n        {\n          // If language is set to \"EVMAssembly\", an EVM Assembly JSON object needs to be supplied\n          // under the \"assemblyJson\" key and there can be only one source file present.\n          // The format is the same as used by the `evm.legacyAssembly` output or `--asm-json`\n          // output on the command line.\n          // Note that importing EVM assembly is experimental.\n          \"assemblyJson\":\n          {\n            \".code\": [ ... ],\n            \".data\": { ... }, // optional\n            \"sourceList\": [ ... ] // optional (if no `source` node was defined in any `.code` object)\n          }\n        }\n      },\n      // Optional\n      \"settings\":\n      {\n        // Optional: Stop compilation after the given stage. Currently only \"parsing\" is valid here\n        \"stopAfter\": \"parsing\",\n        // Optional: List of remappings\n        \"remappings\": [ \":g=/dir\" ],\n        // Optional: Experimental mode toggle (Default: false)\n        // Makes it possible to use experimental features (but does not enable any such feature by itself).\n        // The use of this mode is recorded in contract metadata.\n        \"experimental\": true,\n        // Optional: Optimizer settings\n        \"optimizer\": {\n          // Turn on the optimizer. Optional. Default: false.\n          // NOTE: The state of the optimizer is fully determined by the 'details' dict and this setting\n          // only affects its defaults - when enabled, all components default to being enabled.\n          // The opposite is not true - there are several components that always default to being\n          // enabled an can only be explicitly disabled via 'details'.\n          // WARNING: Before version 0.8.6 omitting this setting was not equivalent to setting\n          // it to false and would result in all components being disabled instead.\n          // WARNING: Enabling optimizations for EVMAssembly input is allowed but not necessary under normal\n          // circumstances. It forces the opcode-based optimizer to run again and can produce bytecode that\n          // is not reproducible from metadata.\n          \"enabled\": true,\n          // Optimize for how many times you intend to run the code. Optional. Default: 200.\n          // Lower values will optimize more for initial deployment cost, higher\n          // values will optimize more for high-frequency usage.\n          \"runs\": 200,\n          // State of all optimizer components. Optional.\n          // Default values are determined by whether the optimizer is enabled or not.\n          // Note that the 'enabled' setting only affects the defaults here and has no effect when\n          // all values are provided explicitly.\n          \"details\": {\n            // Peephole optimizer (opcode-based). Optional. Default: true.\n            // Default for EVMAssembly input: false when optimization is not enabled.\n            // NOTE: Always runs (even with optimization disabled) except for EVMAssembly input or when explicitly turned off here.\n            \"peephole\": true,\n            // Inliner (opcode-based). Optional. Default: true when optimization is enabled.\n            \"inliner\": false,\n            // Unused JUMPDEST remover (opcode-based). Optional. Default: true.\n            // Default for EVMAssembly input: false when optimization is not enabled.\n            // NOTE: Always runs (even with optimization disabled) except for EVMAssembly input or when explicitly turned off here.\n            \"jumpdestRemover\": true,\n            // Literal reordering (codegen-based). Optional. Default: true when optimization is enabled.\n            // Moves literals to the right of commutative binary operators during code generation, helping exploit associativity.\n            \"orderLiterals\": false,\n            // Block deduplicator (opcode-based). Optional. Default: true when optimization is enabled.\n            // Unifies assembly code blocks that share content.\n            \"deduplicate\": false,\n            // Common subexpression elimination (opcode-based). Optional. Default: true when optimization is enabled.\n            // This is the most complicated step but can also provide the largest gain.\n            \"cse\": false,\n            // Constant optimizer (opcode-based). Optional. Default: true when optimization is enabled.\n            // Tries to find better representations of literal numbers and strings, that satisfy the\n            // size/cost trade-off determined by the 'runs' setting.\n            \"constantOptimizer\": false,\n            // Unchecked loop increment (codegen-based). Optional. Default: true.\n            // Use unchecked arithmetic when incrementing the counter of 'for' loops under certain circumstances.\n            // NOTE: Always runs (even with optimization disabled) unless explicitly turned off here.\n            \"simpleCounterForLoopUncheckedIncrement\": true,\n            // Yul optimizer. Optional. Default: true when optimization is enabled.\n            // Used to optimize the IR produced by the Yul IR-based pipeline as well as inline assembly\n            // and utility Yul code generated by the compiler.\n            // NOTE: Before Solidity 0.6.0 the default was false.\n            \"yul\": false,\n            // Tuning options for the Yul optimizer. Optional.\n            \"yulDetails\": {\n              // Improve allocation of stack slots for variables, can free up stack slots early.\n              // Optional. Default: true if Yul optimizer is enabled.\n              \"stackAllocation\": true,\n              // Optimization step sequence.\n              // The general form of the value is \"<main sequence>:<cleanup sequence>\".\n              // The setting is optional and when omitted, default values are used for both sequences.\n              // If the value does not contain the ':' delimiter, it is interpreted as the main\n              // sequence and the default is used for the cleanup sequence.\n              // To make one of the sequences empty, the delimiter must be present at the first or last position.\n              // In particular if the whole value consists only of the delimiter, both sequences are empty.\n              // Note that there are several hard-coded steps that always run, even when both sequences are empty.\n              // For more information see \"The Optimizer > Selecting Optimizations\".\n              \"optimizerSteps\": \"dfDvulfnTUtnIf...\"\n            }\n          }\n        },\n        // Version of the EVM to compile for (optional).\n        // Affects type checking and code generation. Can be homestead,\n        // tangerineWhistle, spuriousDragon, byzantium, constantinople,\n        // petersburg, istanbul, berlin, london, paris, shanghai, cancun, prague or osaka (default).\n        \"evmVersion\": \"osaka\",\n        // EVM Object Format version to compile for (optional, experimental).\n        // Currently the only valid value is 1. If not specified, legacy non-EOF bytecode will be generated.\n        // Requires `evmVersion` >= osaka.\n        \"eofVersion\": null,\n        // Optional: Change compilation pipeline to go through the Yul intermediate representation.\n        // This is false by default.\n        \"viaIR\": true,\n        // Optional: Turn on SSA CFG-based code generation via the IR (experimental).\n        // Implies viaIR: true. This is false by default.\n        \"viaSSACFG\": false,\n        // Optional: Debugging settings\n        \"debug\": {\n          // How to treat revert (and require) reason strings. Settings are\n          // \"default\", \"strip\", \"debug\" and \"verboseDebug\".\n          // \"default\" does not inject compiler-generated revert strings and keeps user-supplied ones.\n          // \"strip\" removes all revert strings (if possible, i.e. if literals are used) keeping side-effects\n          // \"debug\" injects strings for compiler-generated internal reverts, implemented for ABI encoders V1 and V2 for now.\n          // \"verboseDebug\" even appends further information to user-supplied revert strings (not yet implemented)\n          \"revertStrings\": \"default\",\n          // Optional: How much extra debug information to include in comments in the produced EVM\n          // assembly and Yul code. Available components are:\n          // - `location`: Annotations of the form `@src <index>:<start>:<end>` indicating the\n          //    location of the corresponding element in the original Solidity file, where:\n          //     - `<index>` is the file index matching the `@use-src` annotation,\n          //     - `<start>` is the index of the first byte at that location,\n          //     - `<end>` is the index of the first byte after that location.\n          // - `snippet`: A single-line code snippet from the location indicated by `@src`.\n          //     The snippet is quoted and follows the corresponding `@src` annotation.\n          // - `ast-id`: Annotations of the form `@ast-id <id>` over elements that can be mapped back to a definition in the original Solidity file.\n          //   `<id>` is a node ID in the Solidity AST ('ast' output).\n          // - `ethdebug`: Ethdebug annotations (experimental).\n          // - `*`: Wildcard value that can be used to request all non-experimental components.\n          \"debugInfo\": [\"location\", \"snippet\", \"ast-id\", \"ethdebug\"]\n        },\n        // Metadata settings (optional)\n        \"metadata\": {\n          // The CBOR metadata is appended at the end of the bytecode by default.\n          // Setting this to false omits the metadata from the runtime and deploy time code.\n          \"appendCBOR\": true,\n          // Use only literal content and not URLs (false by default)\n          \"useLiteralContent\": true,\n          // Use the given hash method for the metadata hash that is appended to the bytecode.\n          // The metadata hash can be removed from the bytecode via option \"none\".\n          // The other options are \"ipfs\" and \"bzzr1\".\n          // If the option is omitted, \"ipfs\" is used by default.\n          \"bytecodeHash\": \"ipfs\"\n        },\n        // Addresses of the libraries. If not all libraries are given here,\n        // it can result in unlinked objects whose output data is different.\n        \"libraries\": {\n          // The top level key is the name of the source file where the library is used.\n          // If remappings are used, this source file should match the global path\n          // after remappings were applied.\n          // If this key is an empty string, that refers to a global level.\n          \"myFile.sol\": {\n            \"MyLib\": \"0x123123...\"\n          }\n        },\n        // The following can be used to select desired outputs based\n        // on file and contract names.\n        // If this field is omitted, then the compiler loads and does type checking,\n        // but will not generate any outputs apart from errors.\n        // The first level key is the file name and the second level key is the contract name.\n        // An empty contract name is used for outputs that are not tied to a contract\n        // but to the whole source file like the AST.\n        // A star as contract name refers to all contracts in the file.\n        // Similarly, a star as a file name matches all files.\n        // To select all outputs the compiler can possibly generate, with the exclusion of\n        // Yul intermediate representation outputs, use\n        // \"outputSelection: { \"*\": { \"*\": [ \"*\" ], \"\": [ \"*\" ] } }\"\n        // but note that this might slow down the compilation process needlessly.\n        //\n        // The available output types are as follows:\n        //\n        // File level (needs empty string as contract name):\n        //   ast - AST of all source files\n        //\n        // Contract level (needs the contract name or \"*\"):\n        //   abi - ABI\n        //   devdoc - Developer documentation (natspec)\n        //   userdoc - User documentation (natspec)\n        //   metadata - Metadata\n        //   ir - Yul intermediate representation of the code before optimization\n        //   irAst - AST of Yul intermediate representation of the code before optimization (experimental)\n        //   irOptimized - Intermediate representation after optimization\n        //   irOptimizedAst - AST of intermediate representation after optimization (experimental)\n        //   storageLayout - Slots, offsets and types of the contract's state variables in storage\n        //   transientStorageLayout - Slots, offsets and types of the contract's state variables in transient storage\n        //   evm.assembly - New assembly format\n        //   evm.legacyAssembly - Old-style assembly format in JSON\n        //   evm.bytecode.ethdebug - Debug information in ethdebug format (ethdebug/format/program schema). Can only be requested when compiling via IR. (experimental)\n        //   evm.deployedBytecode.ethdebug - Like evm.bytecode.ethdebug, but for the runtime part of the contract (experimental)\n        //   evm.bytecode.functionDebugData - Debugging information at function level\n        //   evm.bytecode.object - Bytecode object\n        //   evm.bytecode.opcodes - Opcodes list\n        //   evm.bytecode.sourceMap - Source mapping (useful for debugging)\n        //   evm.bytecode.linkReferences - Link references (if unlinked object)\n        //   evm.bytecode.generatedSources - Sources generated by the compiler\n        //   evm.deployedBytecode* - Deployed bytecode (has all the options that evm.bytecode has)\n        //   evm.deployedBytecode.immutableReferences - Map from AST ids to bytecode ranges that reference immutables\n        //   evm.methodIdentifiers - The list of function hashes\n        //   evm.gasEstimates - Function gas estimates\n        //   yulCFGJson - Control Flow Graph (CFG) of the Single Static Assignment (SSA) form of the contract (experimental)\n        //\n        // Note that using `evm`, `evm.bytecode`, etc. will select every\n        // target part of that output. Additionally, `*` can be used as a wildcard to request everything.\n        //\n        \"outputSelection\": {\n          \"*\": {\n            \"*\": [\n              \"metadata\", \"evm.bytecode\" // Enable the metadata and bytecode outputs of every single contract.\n              , \"evm.bytecode.sourceMap\" // Enable the source map output of every single contract.\n            ],\n            \"\": [\n              \"ast\" // Enable the AST output of every single file.\n            ]\n          },\n          // Enable the abi and opcodes output of MyContract defined in file def.\n          \"def\": {\n            \"MyContract\": [ \"abi\", \"evm.bytecode.opcodes\" ]\n          }\n        },\n        // The modelChecker object is experimental and subject to changes.\n        \"modelChecker\":\n        {\n          // Chose which contracts should be analyzed as the deployed one.\n          \"contracts\":\n          {\n            \"source1.sol\": [\"contract1\"],\n            \"source2.sol\": [\"contract2\", \"contract3\"]\n          },\n          // Choose how division and modulo operations should be encoded.\n          // When using `false` they are replaced by multiplication with slack\n          // variables. This is the default.\n          // Using `true` here is recommended if you are using the CHC engine\n          // and not using Spacer as the Horn solver (using Eldarica, for example).\n          // See the Formal Verification section for a more detailed explanation of this option.\n          \"divModNoSlacks\": false,\n          // Choose which model checker engine to use: all (default), bmc, chc, none.\n          \"engine\": \"chc\",\n          // Choose whether external calls should be considered trusted in case the\n          // code of the called function is available at compile-time.\n          // For details see the SMTChecker section.\n          \"extCalls\": \"trusted\",\n          // Choose which types of invariants should be reported to the user: contract, reentrancy.\n          \"invariants\": [\"contract\", \"reentrancy\"],\n          // Choose whether to output all proved targets. The default is `false`.\n          \"showProvedSafe\": true,\n          // Choose whether to output all unproved targets. The default is `false`.\n          \"showUnproved\": true,\n          // Choose whether to output all unsupported language features. The default is `false`.\n          \"showUnsupported\": true,\n          // Choose which solvers should be used, if available.\n          // See the Formal Verification section for the solvers description.\n          \"solvers\": [\"cvc5\", \"smtlib2\", \"z3\"],\n          // Choose which targets should be checked: constantCondition,\n          // underflow, overflow, divByZero, balance, assert, popEmptyArray, outOfBounds.\n          // If the option is not given all targets are checked by default,\n          // except underflow/overflow for Solidity >=0.8.7.\n          // See the Formal Verification section for the targets description.\n          \"targets\": [\"underflow\", \"overflow\", \"assert\"],\n          // Timeout for each SMT query in milliseconds.\n          // If this option is not given, the SMTChecker will use a deterministic\n          // resource limit by default.\n          // A given timeout of 0 means no resource/time restrictions for any query.\n          \"timeout\": 20000\n        }\n      }\n    }\n\n\nOutput Description\n------------------\n\n.. code-block:: javascript\n\n    {\n      // Optional: not present if no errors/warnings/infos were encountered\n      \"errors\": [\n        {\n          // Optional: Location within the source file.\n          \"sourceLocation\": {\n            \"file\": \"sourceFile.sol\",\n            \"start\": 0,\n            \"end\": 100\n          },\n          // Optional: Further locations (e.g. places of conflicting declarations)\n          \"secondarySourceLocations\": [\n            {\n              \"file\": \"sourceFile.sol\",\n              \"start\": 64,\n              \"end\": 92,\n              \"message\": \"Other declaration is here:\"\n            }\n          ],\n          // Mandatory: Error type, such as \"TypeError\", \"InternalCompilerError\", \"Exception\", etc.\n          // See below for complete list of types.\n          \"type\": \"TypeError\",\n          // Mandatory: Component where the error originated, such as \"general\" etc.\n          \"component\": \"general\",\n          // Mandatory (\"error\", \"warning\" or \"info\", but please note that this may be extended in the future)\n          \"severity\": \"error\",\n          // Optional: unique code for the cause of the error\n          \"errorCode\": \"3141\",\n          // Mandatory\n          \"message\": \"Invalid keyword\",\n          // Optional: the message formatted with source location\n          \"formattedMessage\": \"sourceFile.sol:100: Invalid keyword\"\n        }\n      ],\n      // This contains the file-level outputs.\n      // It can be limited/filtered by the outputSelection settings.\n      \"sources\": {\n        \"sourceFile.sol\": {\n          // Identifier of the source (used in source maps)\n          \"id\": 1,\n          // The AST object\n          \"ast\": {}\n        }\n      },\n      // This contains the contract-level outputs.\n      // It can be limited/filtered by the outputSelection settings.\n      \"contracts\": {\n        \"sourceFile.sol\": {\n          // If the language used has no contract names, this field should equal to an empty string.\n          \"ContractName\": {\n            // The Ethereum Contract ABI. If empty, it is represented as an empty array.\n            // See https://docs.soliditylang.org/en/develop/abi-spec.html\n            \"abi\": [],\n            // See the Metadata Output documentation (serialised JSON string)\n            \"metadata\": \"{/* ... */}\",\n            // User documentation (natspec)\n            \"userdoc\": {},\n            // Developer documentation (natspec)\n            \"devdoc\": {},\n            // Intermediate representation before optimization (string)\n            \"ir\": \"\",\n            // AST of intermediate representation before optimization\n            \"irAst\":  {/* ... */},\n            // Intermediate representation after optimization (string)\n            \"irOptimized\": \"\",\n            // AST of intermediate representation after optimization\n            \"irOptimizedAst\": {/* ... */},\n            // See the Storage Layout documentation.\n            \"storageLayout\": {\"storage\": [/* ... */], \"types\": {/* ... */} },\n            // See the Storage Layout documentation.\n            \"transientStorageLayout\": {\"storage\": [/* ... */], \"types\": {/* ... */} },\n            // EVM-related outputs\n            \"evm\": {\n              // Assembly (string)\n              \"assembly\": \"\",\n              // Old-style assembly (object)\n              \"legacyAssembly\": {},\n              // Bytecode and related details.\n              \"bytecode\": {\n                // Ethdebug output (experimental)\n                \"ethdebug\": {/* ... */},\n                // Debugging data at the level of functions.\n                \"functionDebugData\": {\n                  // Now follows a set of functions including compiler-internal and\n                  // user-defined function. The set does not have to be complete.\n                  \"@mint_13\": { // Internal name of the function\n                    \"entryPoint\": 128, // Byte offset into the bytecode where the function starts (optional)\n                    \"id\": 13, // AST ID of the function definition or null for compiler-internal functions (optional)\n                    \"parameterSlots\": 2, // Number of EVM stack slots for the function parameters (optional)\n                    \"returnSlots\": 1 // Number of EVM stack slots for the return values (optional)\n                  }\n                },\n                // The bytecode as a hex string.\n                \"object\": \"00fe\",\n                // Opcodes list (string)\n                \"opcodes\": \"\",\n                // The source mapping as a string. See the source mapping definition.\n                \"sourceMap\": \"\",\n                // Array of sources generated by the compiler. Currently only\n                // contains a single Yul file.\n                \"generatedSources\": [{\n                  // Yul AST\n                  \"ast\": {/* ... */},\n                  // Source file in its text form (may contain comments)\n                  \"contents\":\"{ function abi_decode(start, end) -> data { data := calldataload(start) } }\",\n                  // Source file ID, used for source references, same \"namespace\" as the Solidity source files\n                  \"id\": 2,\n                  \"language\": \"Yul\",\n                  \"name\": \"#utility.yul\"\n                }],\n                // If given, this is an unlinked object.\n                \"linkReferences\": {\n                  \"libraryFile.sol\": {\n                    // Byte offsets into the bytecode.\n                    // Linking replaces the 20 bytes located there.\n                    \"Library1\": [\n                      { \"start\": 0, \"length\": 20 },\n                      { \"start\": 200, \"length\": 20 }\n                    ]\n                  }\n                }\n              },\n              \"deployedBytecode\": {\n                // Ethdebug output (experimental)\n                \"ethdebug\": {/* ... */},\n                /* ..., */ // The same layout as above.\n                \"immutableReferences\": {\n                  // There are two references to the immutable with AST ID 3, both 32 bytes long. One is\n                  // at bytecode offset 42, the other at bytecode offset 80.\n                  \"3\": [{ \"start\": 42, \"length\": 32 }, { \"start\": 80, \"length\": 32 }]\n                }\n              },\n              // The list of function hashes\n              \"methodIdentifiers\": {\n                \"delegate(address)\": \"5c19a95c\"\n              },\n              // Function gas estimates\n              \"gasEstimates\": {\n                \"creation\": {\n                  \"codeDepositCost\": \"420000\",\n                  \"executionCost\": \"infinite\",\n                  \"totalCost\": \"infinite\"\n                },\n                \"external\": {\n                  \"delegate(address)\": \"25000\"\n                },\n                \"internal\": {\n                  \"heavyLifting()\": \"infinite\"\n                }\n              },\n              // Yul CFG representation of the SSA form (experimental)\n              \"yulCFGJson\": {/* ... */}\n            }\n          }\n        }\n      },\n      // Global Ethdebug output (experimental)\n      \"ethdebug\": {/* ... */ }\n    }\n\n\nError Types\n~~~~~~~~~~~\n\n1. ``JSONError``: JSON input doesn't conform to the required format, e.g. input is not a JSON object, the language is not supported, etc.\n2. ``IOError``: IO and import processing errors, such as unresolvable URL or hash mismatch in supplied sources.\n3. ``ParserError``: Source code doesn't conform to the language rules.\n4. ``DocstringParsingError``: The NatSpec tags in the comment block cannot be parsed.\n5. ``SyntaxError``: Syntactical error, such as ``continue`` is used outside of a ``for`` loop.\n6. ``DeclarationError``: Invalid, unresolvable or clashing identifier names. e.g. ``Identifier not found``\n7. ``TypeError``: Error within the type system, such as invalid type conversions, invalid assignments, etc.\n8. ``UnimplementedFeatureError``: Feature is not supported by the compiler, but is expected to be supported in future versions.\n9. ``InternalCompilerError``: Internal bug triggered in the compiler - this should be reported as an issue.\n10. ``Exception``: Unknown failure during compilation - this should be reported as an issue.\n11. ``CompilerError``: Invalid use of the compiler stack - this should be reported as an issue.\n12. ``FatalError``: Fatal error not processed correctly - this should be reported as an issue.\n13. ``YulException``: Error during Yul code generation - this should be reported as an issue.\n14. ``Warning``: A warning, which didn't stop the compilation, but should be addressed if possible.\n15. ``Info``: Information that the compiler thinks the user might find useful, but is not dangerous and does not necessarily need to be addressed.\n\n.. index:: ! Experimental mode, ! --experimental\n.. _experimental-mode:\n\nExperimental Mode\n*****************\n\nSome language and compiler features included in stable releases are not themselves considered stable.\nThey are sparsely documented, if at all, often not adequately tested, and thus not yet intended for production use.\nIn many cases it is possible to develop a big feature incrementally, with each iteration being already stable.\nSometimes, however, it is preferable to start with a prototype and stabilize it over multiple releases, while receiving feedback from users.\nTo prevent accidental use, such features can be only accessed by enabling the experimental mode.\n\nThere are no backwards compatibility guarantees for experimental features.\nThey are subject to change in breaking ways in non-breaking releases of the compiler.\nOnly major changes affecting them are recorded in the changelog.\n\nTo enable the experimental mode, use the ``--experimental`` flag on the command line,\nor the analogous ``settings.experimental`` boolean setting in the Standard JSON input.\n\nNote that the use of this mode is recorded in the metadata:\n\n- ``experimental`` flag in CBOR metadata is set to ``true``,\n- ``settings.experimental`` in JSON metadata is set to ``true``,\n\n.. note::\n    Prior to version 0.8.34, most of the experimental features were usable without any extra safeguards.\n    Some were gated behind ``pragma experimental``, but this was not done consistently.\n    The information about them was also only recorded in CBOR metadata and even then not always.\n    The main goal of the experimental mode is to systematize this and make users fully aware when relying on features which are unfinished or not production-ready.\n\nThe table below details all currently available experimental features.\n\n+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+\n| Feature               | ID                       | Affects bytecode | Flag/pragma                                                       |\n+=======================+==========================+==================+===================================================================+\n| AST import            | ``ast-import``           | yes              | ``--import-ast``                                                  |\n+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+\n| LSP                   | ``lsp``                  | no               | ``--lsp``                                                         |\n+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+\n| EVM Assembly import   | ``evmasm-import``        | yes              | ``--import-asm-json``                                             |\n+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+\n| Generic Solidity      | ``generic-solidity``     | yes              | ``pragma experimental solidity``                                  |\n+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+\n| IR AST                | ``ir-ast``               | no               | ``--ir-ast-json``, ``--ir-optimized-ast-json``                    |\n+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+\n| EOF                   | ``eof``                  | yes              | ``--experimental-eof-version``                                    |\n+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+\n| Non-mainnet EVMs      | ``evm``                  | yes              | ``--evm-version <version name>``                                  |\n+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+\n| Ethdebug              | ``ethdebug``             | no               | ``--ethdebug``, ``--ethdebug-runtime``, ``--debug-info ethdebug`` |\n+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+\n|                       |                          | no               | ``--yul-cfg-json``                                                |\n| SSA CFG               + ``ssa-cfg``              +------------------+-------------------------------------------------------------------+\n|                       |                          | yes              | ``--via-ssa-cfg``                                                 |\n+-----------------------+--------------------------+------------------+-------------------------------------------------------------------+\n"
  },
  {
    "path": "docs/yul.rst",
    "content": ".. _yul:\n\n###\nYul\n###\n\n.. index:: ! assembly, ! asm, ! evmasm, ! yul, julia, iulia\n\nYul (previously also called JULIA or IULIA) is an intermediate language that can be\ncompiled to bytecode for different backends.\n\nIt can be used in stand-alone mode and for \"inline assembly\" inside Solidity.\nThe compiler uses Yul as an intermediate language in the IR-based code generator (\"new codegen\" or \"IR-based codegen\").\nYul is a good target for high-level optimisation stages that can benefit all target platforms equally.\n\nMotivation and High-level Description\n=====================================\n\nThe design of Yul tries to achieve several goals:\n\n1. Programs written in Yul should be readable, even if the code is generated by a compiler from Solidity or another high-level language.\n2. Control flow should be easy to understand to help in manual inspection, formal verification and optimization.\n3. The translation from Yul to bytecode should be as straightforward as possible.\n4. Yul should be suitable for whole-program optimization.\n\nIn order to achieve the first and second goal, Yul provides high-level constructs\nlike ``for`` loops, ``if`` and ``switch`` statements and function calls. These should\nbe sufficient for adequately representing the control flow for assembly programs.\nTherefore, no explicit statements for ``SWAP``, ``DUP``, ``JUMPDEST``, ``JUMP`` and ``JUMPI``\nare provided, because the first two obfuscate the data flow\nand the last two obfuscate control flow. Furthermore, functional statements of\nthe form ``mul(add(x, y), 7)`` are preferred over pure opcode statements like\n``7 y x add mul`` because in the first form, it is much easier to see which\noperand is used for which opcode.\n\nEven though it was designed for stack machines, Yul does not expose the complexity of the stack itself.\nThe programmer or auditor should not have to worry about the stack.\n\nThe third goal is achieved by compiling the\nhigher level constructs to bytecode in a very regular way.\nThe only non-local operation performed\nby the assembler is name lookup of user-defined identifiers (functions, variables, ...)\nand cleanup of local variables from the stack.\n\nTo avoid confusions between concepts like values and references,\nYul is statically typed. At the same time, there is a default type\n(usually the integer word of the target machine) that can always\nbe omitted to help readability.\n\nTo keep the language simple and flexible, Yul does not have\nany built-in operations, functions or types in its pure form.\nThese are added together with their semantics when specifying a dialect of Yul,\nwhich allows specializing Yul to the requirements of different\ntarget platforms and feature sets.\n\nCurrently, there is only one specified dialect of Yul. This dialect uses\nthe EVM opcodes as builtin functions\n(see below) and defines only the type ``u256``, which is the native 256-bit\ntype of the EVM. Because of that, we will not provide types in the examples below.\n\n\nSimple Example\n==============\n\nThe following example program is written in the EVM dialect and computes exponentiation.\nIt can be compiled using ``solc --strict-assembly``. The builtin functions\n``mul`` and ``div`` compute product and division, respectively.\n\n.. code-block:: yul\n\n    {\n        function power(base, exponent) -> result\n        {\n            switch exponent\n            case 0 { result := 1 }\n            case 1 { result := base }\n            default\n            {\n                result := power(mul(base, base), div(exponent, 2))\n                switch mod(exponent, 2)\n                    case 1 { result := mul(base, result) }\n            }\n        }\n    }\n\nIt is also possible to implement the same function using a for-loop\ninstead of with recursion. Here, ``lt(a, b)`` computes whether ``a`` is less than ``b``.\n\n.. code-block:: yul\n\n    {\n        function power(base, exponent) -> result\n        {\n            result := 1\n            for { let i := 0 } lt(i, exponent) { i := add(i, 1) }\n            {\n                result := mul(result, base)\n            }\n        }\n    }\n\nAt the :ref:`end of the section <erc20yul>`, a complete implementation of\nthe ERC-20 standard can be found.\n\n\n\nStand-Alone Usage\n=================\n\nYou can use Yul in its stand-alone form in the EVM dialect using the Solidity compiler.\nThis will use the :ref:`Yul object notation <yul-object>` so that it is possible to refer\nto code as data to deploy contracts. This Yul mode is available for the commandline compiler\n(use ``--strict-assembly``) and for the :ref:`standard-json interface <compiler-api>`:\n\n.. code-block:: json\n\n    {\n        \"language\": \"Yul\",\n        \"sources\": { \"input.yul\": { \"content\": \"{ sstore(0, 1) }\" } },\n        \"settings\": {\n            \"outputSelection\": { \"*\": { \"*\": [\"*\"], \"\": [ \"*\" ] } },\n            \"optimizer\": { \"enabled\": true, \"details\": { \"yul\": true } }\n        }\n    }\n\n.. warning::\n\n    Yul is in active development and bytecode generation is only fully implemented for the EVM dialect of Yul\n    with EVM 1.0 as target.\n\n\nInformal Description of Yul\n===========================\n\nIn the following, we will talk about each individual aspect\nof the Yul language. In examples, we will use the default EVM dialect.\n\nSyntax\n------\n\nYul parses comments, literals and identifiers in the same way as Solidity,\nso you can e.g. use ``//`` and ``/* */`` to denote comments.\nThere is one exception: Identifiers in Yul can contain dots: ``.``.\n\nYul can specify \"objects\" that consist of code, data and sub-objects.\nPlease see :ref:`Yul Objects <yul-object>` below for details on that.\nIn this section, we are only concerned with the code part of such an object.\nThis code part always consists of a curly-braces\ndelimited block. Most tools support specifying just a code block\nwhere an object is expected.\n\nInside a code block, the following elements can be used\n(see the later sections for more details):\n\n- literals, e.g. ``0x123``, ``42`` or ``\"abc\"`` (strings up to 32 characters)\n- calls to builtin functions, e.g. ``add(1, mload(0))``\n- variable declarations, e.g. ``let x := 7``, ``let x := add(y, 3)`` or ``let x`` (initial value of 0 is assigned)\n- identifiers (variables), e.g. ``add(3, x)``\n- assignments, e.g. ``x := add(y, 3)``\n- blocks where local variables are scoped inside, e.g. ``{ let x := 3 { let y := add(x, 1) } }``\n- if statements, e.g. ``if lt(a, b) { sstore(0, 1) }``\n- switch statements, e.g. ``switch mload(0) case 0 { revert() } default { mstore(0, 1) }``\n- for loops, e.g. ``for { let i := 0} lt(i, 10) { i := add(i, 1) } { mstore(i, 7) }``\n- function definitions, e.g. ``function f(a, b) -> c { c := add(a, b) }``\n\nMultiple syntactical elements can follow each other simply separated by\nwhitespace, i.e. there is no terminating ``;`` or newline required.\n\n.. index:: ! literal;in Yul\n\nLiterals\n--------\n\nAs literals, you can use:\n\n- Integer constants in decimal or hexadecimal notation.\n\n- ASCII strings (e.g. ``\"abc\"``), which may contain hex escapes ``\\xNN`` and Unicode escapes ``\\uNNNN`` where ``N`` are hexadecimal digits.\n\n- Hex strings (e.g. ``hex\"616263\"``).\n\nIn the EVM dialect of Yul, literals represent 256-bit words as follows:\n\n- Decimal or hexadecimal constants must be less than ``2**256``.\n  They represent the 256-bit word with that value as an unsigned integer in big endian encoding.\n\n- An ASCII string is first viewed as a byte sequence, by viewing\n  a non-escape ASCII character as a single byte whose value is the ASCII code,\n  an escape ``\\xNN`` as single byte with that value, and\n  an escape ``\\uNNNN`` as the UTF-8 sequence of bytes for that code point.\n  The byte sequence must not exceed 32 bytes.\n  The byte sequence is padded with zeros on the right to reach 32 bytes in length;\n  in other words, the string is stored left-aligned.\n  The padded byte sequence represents a 256-bit word whose most significant 8 bits are the ones from the first byte,\n  i.e. the bytes are interpreted in big endian form.\n\n- A hex string is first viewed as a byte sequence, by viewing\n  each pair of contiguous hex digits as a byte.\n  The byte sequence must not exceed 32 bytes (i.e. 64 hex digits), and is treated as above.\n\nWhen compiling for the EVM, this will be translated into an\nappropriate ``PUSHi`` instruction. In the following example,\n``3`` and ``2`` are added resulting in 5 and then the\nbitwise ``and`` with the string \"abc\" is computed.\nThe final value is assigned to a local variable called ``x``.\n\nThe 32-byte limit above does not apply to string literals passed to builtin functions that require\nliteral arguments (e.g. ``setimmutable`` or ``loadimmutable``). Those strings never end up in the\ngenerated bytecode.\n\n.. code-block:: yul\n\n    let x := and(\"abc\", add(3, 2))\n\nUnless it is the default type, the type of a literal\nhas to be specified after a colon:\n\n.. code-block:: yul\n\n    // This will not compile (u32 and u256 type not implemented yet)\n    let x := and(\"abc\":u32, add(3:u256, 2:u256))\n\n\nFunction Calls\n--------------\n\nBoth built-in and user-defined functions (see below) can be called\nin the same way as shown in the previous example.\nIf the function returns a single value, it can be directly used\ninside an expression again. If it returns multiple values,\nthey have to be assigned to local variables.\n\n.. code-block:: yul\n\n    function f(x, y) -> a, b { /* ... */ }\n    mstore(0x80, add(mload(0x80), 3))\n    // Here, the user-defined function `f` returns two values.\n    let x, y := f(1, mload(0))\n\nFor built-in functions of the EVM, functional expressions\ncan be directly translated to a stream of opcodes:\nYou just read the expression from right to left to obtain the\nopcodes. In the case of the second line in the example, this\nis ``PUSH1 3 PUSH1 0x80 MLOAD ADD PUSH1 0x80 MSTORE``.\n\nFor calls to user-defined functions, the arguments are also\nput on the stack from right to left and this is the order\nin which argument lists are evaluated. The return values,\nthough, are expected on the stack from left to right,\ni.e. in this example, ``y`` is on top of the stack and ``x``\nis below it.\n\nVariable Declarations\n---------------------\n\nYou can use the ``let`` keyword to declare variables.\nA variable is only visible inside the\n``{...}``-block it was defined in. When compiling to the EVM,\na new stack slot is created that is reserved\nfor the variable and automatically removed again when the end of the block\nis reached. You can provide an initial value for the variable.\nIf you do not provide a value, the variable will be initialized to zero.\n\nSince variables are stored on the stack, they do not directly\ninfluence memory or storage, but they can be used as pointers\nto memory or storage locations in the built-in functions\n``mstore``, ``mload``, ``sstore`` and ``sload``.\nFuture dialects might introduce specific types for such pointers.\n\nWhen a variable is referenced, its current value is copied.\nFor the EVM, this translates to a ``DUP`` instruction.\n\n.. code-block:: yul\n\n    {\n        let zero := 0\n        let v := calldataload(zero)\n        {\n            let y := add(sload(v), 1)\n            v := y\n        } // y is \"deallocated\" here\n        sstore(v, zero)\n    } // v and zero are \"deallocated\" here\n\n\nIf the declared variable should have a type different from the default type,\nyou denote that following a colon. You can also declare multiple\nvariables in one statement when you assign from a function call\nthat returns multiple values.\n\n.. code-block:: yul\n\n    // This will not compile (u32 and u256 type not implemented yet)\n    {\n        let zero:u32 := 0:u32\n        let v:u256, t:u32 := f()\n        let x, y := g()\n    }\n\nDepending on the optimiser settings, the compiler can free the stack slots\nalready after the variable has been used for\nthe last time, even though it is still in scope.\n\n\nAssignments\n-----------\n\nVariables can be assigned to after their definition using the\n``:=`` operator. It is possible to assign multiple\nvariables at the same time. For this, the number and types of the\nvalues have to match.\nIf you want to assign the values returned from a function that has\nmultiple return parameters, you have to provide multiple variables.\nThe same variable may not occur multiple times on the left-hand side of\nan assignment, e.g. ``x, x := f()`` is invalid.\n\n.. code-block:: yul\n\n    let v := 0\n    // re-assign v\n    v := 2\n    let t := add(v, 2)\n    function f() -> a, b { }\n    // assign multiple values\n    v, t := f()\n\n\nIf\n--\n\nThe if statement can be used for conditionally executing code.\nNo \"else\" block can be defined. Consider using \"switch\" instead (see below) if\nyou need multiple alternatives.\n\n.. code-block:: yul\n\n    if lt(calldatasize(), 4) { revert(0, 0) }\n\nThe curly braces for the body are required.\n\nSwitch\n------\n\nYou can use a switch statement as an extended version of the if statement.\nIt takes the value of an expression and compares it to several literal constants.\nThe branch corresponding to the matching constant is taken.\nContrary to other programming languages, for safety reasons, control flow does\nnot continue from one case to the next. There can be a fallback or default\ncase called ``default`` which is taken if none of the literal constants matches.\n\n.. code-block:: yul\n\n    {\n        let x := 0\n        switch calldataload(4)\n        case 0 {\n            x := calldataload(0x24)\n        }\n        default {\n            x := calldataload(0x44)\n        }\n        sstore(0, div(x, 2))\n    }\n\nThe list of cases is not enclosed by curly braces, but the body of a\ncase does require them.\n\nLoops\n-----\n\nYul supports for-loops which consist of\na header containing an initializing part, a condition, a post-iteration\npart and a body. The condition has to be an expression, while\nthe other three are blocks. If the initializing part\ndeclares any variables at the top level, the scope of these variables extends to all other\nparts of the loop.\n\nThe ``break`` and ``continue`` statements can be used in the body to exit the loop\nor skip to the post-part, respectively.\n\nThe following example computes the sum of an area in memory.\n\n.. code-block:: yul\n\n    {\n        let x := 0\n        for { let i := 0 } lt(i, 0x100) { i := add(i, 0x20) } {\n            x := add(x, mload(i))\n        }\n    }\n\nFor loops can also be used as a replacement for while loops:\nSimply leave the initialization and post-iteration parts empty.\n\n.. code-block:: yul\n\n    {\n        let x := 0\n        let i := 0\n        for { } lt(i, 0x100) { } {     // while(i < 0x100)\n            x := add(x, mload(i))\n            i := add(i, 0x20)\n        }\n    }\n\nFunction Declarations\n---------------------\n\nYul allows the definition of functions. These should not be confused with functions\nin Solidity since they are never part of an external interface of a contract and\nare part of a namespace separate from the one for Solidity functions.\n\nFor the EVM, Yul functions take their\narguments (and a return PC) from the stack and also put the results onto the\nstack. User-defined functions and built-in functions are called in exactly the same way.\n\nFunctions can be defined anywhere and are visible in the block they are\ndeclared in. Inside a function, you cannot access local variables\ndefined outside of that function.\n\nFunctions declare parameters and return variables, similar to Solidity.\nTo return a value, you assign it to the return variable(s).\n\nIf you call a function that returns multiple values, you have to assign\nthem to multiple variables using ``a, b := f(x)`` or ``let a, b := f(x)``.\n\nThe ``leave`` statement can be used to exit the current function. It\nworks like the ``return`` statement in other languages just that it does\nnot take a value to return, it just exits the functions and the function\nwill return whatever values are currently assigned to the return variable(s).\n\nNote that the EVM dialect has a built-in function called ``return`` that\nquits the full execution context (internal message call) and not just\nthe current yul function.\n\nThe following example implements the power function by square-and-multiply.\n\n.. code-block:: yul\n\n    {\n        function power(base, exponent) -> result {\n            switch exponent\n            case 0 { result := 1 }\n            case 1 { result := base }\n            default {\n                result := power(mul(base, base), div(exponent, 2))\n                switch mod(exponent, 2)\n                    case 1 { result := mul(base, result) }\n            }\n        }\n    }\n\nSpecification of Yul\n====================\n\nThis chapter describes Yul code formally. Yul code is usually placed inside Yul objects,\nwhich are explained in their own chapter.\n\n.. code-block:: none\n\n    Block = '{' Statement* '}'\n    Statement =\n        Block |\n        FunctionDefinition |\n        VariableDeclaration |\n        Assignment |\n        If |\n        Expression |\n        Switch |\n        ForLoop |\n        BreakContinue |\n        Leave\n    FunctionDefinition =\n        'function' Identifier '(' TypedIdentifierList? ')'\n        ( '->' TypedIdentifierList )? Block\n    VariableDeclaration =\n        'let' TypedIdentifierList ( ':=' Expression )?\n    Assignment =\n        IdentifierList ':=' Expression\n    Expression =\n        FunctionCall | Identifier | Literal\n    If =\n        'if' Expression Block\n    Switch =\n        'switch' Expression ( Case+ Default? | Default )\n    Case =\n        'case' Literal Block\n    Default =\n        'default' Block\n    ForLoop =\n        'for' Block Expression Block Block\n    BreakContinue =\n        'break' | 'continue'\n    Leave = 'leave'\n    FunctionCall =\n        Identifier '(' ( Expression ( ',' Expression )* )? ')'\n    Identifier = [a-zA-Z_$] [a-zA-Z_$0-9.]*\n    IdentifierList = Identifier ( ',' Identifier)*\n    TypeName = Identifier\n    TypedIdentifierList = Identifier ( ':' TypeName )? ( ',' Identifier ( ':' TypeName )? )*\n    Literal =\n        (NumberLiteral | StringLiteral | TrueLiteral | FalseLiteral) ( ':' TypeName )?\n    NumberLiteral = HexNumber | DecimalNumber\n    StringLiteral = '\"' ([^\"\\r\\n\\\\] | '\\\\' .)* '\"'\n    TrueLiteral = 'true'\n    FalseLiteral = 'false'\n    HexNumber = '0x' [0-9a-fA-F]+\n    DecimalNumber = [0-9]+\n\n\nRestrictions on the Grammar\n---------------------------\n\nApart from those directly imposed by the grammar, the following\nrestrictions apply:\n\nSwitches must have at least one case (including the default case).\nAll case values need to have the same type and distinct values.\nIf all possible values of the expression type are covered, a default case is\nnot allowed (i.e. a switch with a ``bool`` expression that has both a\ntrue and a false case do not allow a default case).\n\nEvery expression evaluates to zero or more values. Identifiers and Literals\nevaluate to exactly\none value and function calls evaluate to a number of values equal to the\nnumber of return variables of the function called.\n\nIn variable declarations and assignments, the right-hand-side expression\n(if present) has to evaluate to a number of values equal to the number of\nvariables on the left-hand-side.\nThis is the only situation where an expression evaluating\nto more than one value is allowed.\nThe same variable name cannot occur more than once in the left-hand-side of\nan assignment or variable declaration.\n\nExpressions that are also statements (i.e. at the block level) have to\nevaluate to zero values.\n\nIn all other situations, expressions have to evaluate to exactly one value.\n\nA ``continue`` or ``break`` statement can only be used inside the body of a for-loop, as follows.\nConsider the innermost loop that contains the statement.\nThe loop and the statement must be in the same function, or both must be at the top level.\nThe statement must be in the loop's body block;\nit cannot be in the loop's initialization block or update block.\nIt is worth emphasizing that this restriction applies just\nto the innermost loop that contains the ``continue`` or ``break`` statement:\nthis innermost loop, and therefore the ``continue`` or ``break`` statement,\nmay appear anywhere in an outer loop, possibly in an outer loop's initialization block or update block.\nFor example, the following is legal,\nbecause the ``break`` occurs in the body block of the inner loop,\ndespite also occurring in the update block of the outer loop:\n\n.. code-block:: yul\n\n    for {} true { for {} true {} { break } }\n    {\n    }\n\nThe condition part of the for-loop has to evaluate to exactly one value.\n\nThe ``leave`` statement can only be used inside a function.\n\nFunctions cannot be defined anywhere inside for loop init blocks.\n\nLiterals cannot be larger than their type. The largest type defined is 256-bit wide.\n\nDuring assignments and function calls, the types of the respective values have to match.\nThere is no implicit type conversion. Type conversion in general can only be achieved\nif the dialect provides an appropriate built-in function that takes a value of one\ntype and returns a value of a different type.\n\nScoping Rules\n-------------\n\nScopes in Yul are tied to Blocks (exceptions are functions and the for loop\nas explained below) and all declarations\n(``FunctionDefinition``, ``VariableDeclaration``)\nintroduce new identifiers into these scopes.\n\nIdentifiers are visible in\nthe block they are defined in (including all sub-nodes and sub-blocks):\nFunctions are visible in the whole block (even before their definitions) while\nvariables are only visible starting from the statement after the ``VariableDeclaration``.\n\nIn particular,\nvariables cannot be referenced in the right hand side of their own variable\ndeclaration.\nFunctions can be referenced already before their declaration (if they are visible).\n\nAs an exception to the general scoping rule, the scope of the \"init\" part of the for-loop\n(the first block) extends across all other parts of the for loop.\nThis means that variables (and functions) declared in the init part (but not inside a\nblock inside the init part) are visible in all other parts of the for-loop.\n\nIdentifiers declared in the other parts of the for loop respect the regular\nsyntactical scoping rules.\n\nThis means a for-loop of the form ``for { I... } C { P... } { B... }`` is equivalent\nto ``{ I... for {} C { P... } { B... } }``.\n\nThe parameters and return parameters of functions are visible in the\nfunction body and their names have to be distinct.\n\nInside functions, it is not possible to reference a variable that was declared\noutside of that function.\n\nShadowing is disallowed, i.e. you cannot declare an identifier at a point\nwhere another identifier with the same name is also visible, even if it is\nnot possible to reference it because it was declared outside the current function.\n\nFormal Specification\n--------------------\n\nWe formally specify Yul by providing an evaluation function E overloaded\non the various nodes of the AST. As builtin functions can have side effects,\nE takes two state objects and the AST node and returns two new\nstate objects and a variable number of other values.\nThe two state objects are the global state object\n(which in the context of the EVM is the memory, storage and state of the\nblockchain) and the local state object (the state of local variables, i.e. a\nsegment of the stack in the EVM).\n\nIf the AST node is a statement, E returns the two state objects and a \"mode\",\nwhich is used for the ``break``, ``continue`` and ``leave`` statements.\nIf the AST node is an expression, E returns the two state objects and\nas many values as the expression evaluates to.\n\n\nThe exact nature of the global state is unspecified for this high level\ndescription. The local state ``L`` is a mapping of identifiers ``i`` to values ``v``,\ndenoted as ``L[i] = v``.\n\nFor an identifier ``v``, let ``$v`` be the name of the identifier.\n\nWe will use a destructuring notation for the AST nodes.\n\n.. code-block:: none\n\n    E(G, L, <{St1, ..., Stn}>: Block) =\n        let G1, L1, mode = E(G, L, St1, ..., Stn)\n        let L2 be a restriction of L1 to the identifiers of L\n        G1, L2, mode\n    E(G, L, St1, ..., Stn: Statement) =\n        if n is zero:\n            G, L, regular\n        else:\n            let G1, L1, mode = E(G, L, St1)\n            if mode is regular then\n                E(G1, L1, St2, ..., Stn)\n            otherwise\n                G1, L1, mode\n    E(G, L, FunctionDefinition) =\n        G, L, regular\n    E(G, L, <let var_1, ..., var_n := rhs>: VariableDeclaration) =\n        E(G, L, <var_1, ..., var_n := rhs>: Assignment)\n    E(G, L, <let var_1, ..., var_n>: VariableDeclaration) =\n        let L1 be a copy of L where L1[$var_i] = 0 for i = 1, ..., n\n        G, L1, regular\n    E(G, L, <var_1, ..., var_n := rhs>: Assignment) =\n        let G1, L1, v1, ..., vn = E(G, L, rhs)\n        let L2 be a copy of L1 where L2[$var_i] = vi for i = 1, ..., n\n        G1, L2, regular\n    E(G, L, <for { i1, ..., in } condition post body>: ForLoop) =\n        if n >= 1:\n            let G1, L1, mode = E(G, L, i1, ..., in)\n            // mode has to be regular or leave due to the syntactic restrictions\n            if mode is leave then\n                G1, L1 restricted to variables of L, leave\n            otherwise\n                let G2, L2, mode = E(G1, L1, for {} condition post body)\n                G2, L2 restricted to variables of L, mode\n        else:\n            let G1, L1, v = E(G, L, condition)\n            if v is false:\n                G1, L1, regular\n            else:\n                let G2, L2, mode = E(G1, L, body)\n                if mode is break:\n                    G2, L2, regular\n                otherwise if mode is leave:\n                    G2, L2, leave\n                else:\n                    G3, L3, mode = E(G2, L2, post)\n                    if mode is leave:\n                        G3, L3, leave\n                    otherwise\n                        E(G3, L3, for {} condition post body)\n    E(G, L, break: BreakContinue) =\n        G, L, break\n    E(G, L, continue: BreakContinue) =\n        G, L, continue\n    E(G, L, leave: Leave) =\n        G, L, leave\n    E(G, L, <if condition body>: If) =\n        let G0, L0, v = E(G, L, condition)\n        if v is true:\n            E(G0, L0, body)\n        else:\n            G0, L0, regular\n    E(G, L, <switch condition case l1:t1 st1 ... case ln:tn stn>: Switch) =\n        E(G, L, switch condition case l1:t1 st1 ... case ln:tn stn default {})\n    E(G, L, <switch condition case l1:t1 st1 ... case ln:tn stn default st'>: Switch) =\n        let G0, L0, v = E(G, L, condition)\n        // i = 1 .. n\n        // Evaluate literals, context doesn't matter\n        let _, _, v1 = E(G0, L0, l1)\n        ...\n        let _, _, vn = E(G0, L0, ln)\n        if there exists smallest i such that vi = v:\n            E(G0, L0, sti)\n        else:\n            E(G0, L0, st')\n\n    E(G, L, <name>: Identifier) =\n        G, L, L[$name]\n    E(G, L, <fname(arg1, ..., argn)>: FunctionCall) =\n        G1, L1, vn = E(G, L, argn)\n        ...\n        G(n-1), L(n-1), v2 = E(G(n-2), L(n-2), arg2)\n        Gn, Ln, v1 = E(G(n-1), L(n-1), arg1)\n        Let <function fname (param1, ..., paramn) -> ret1, ..., retm block>\n        be the function of name $fname visible at the point of the call.\n        Let L' be a new local state such that\n        L'[$parami] = vi and L'[$reti] = 0 for all i.\n        Let G'', L'', mode = E(Gn, L', block)\n        G'', Ln, L''[$ret1], ..., L''[$retm]\n    E(G, L, l: StringLiteral) = G, L, str(l),\n        where str is the string evaluation function,\n        which for the EVM dialect is defined in the section 'Literals' above\n    E(G, L, n: HexNumber) = G, L, hex(n)\n        where hex is the hexadecimal evaluation function,\n        which turns a sequence of hexadecimal digits into their big endian value\n    E(G, L, n: DecimalNumber) = G, L, dec(n),\n        where dec is the decimal evaluation function,\n        which turns a sequence of decimal digits into their big endian value\n\n.. _opcodes:\n\nEVM Dialect\n-----------\n\nThe default dialect of Yul currently is the EVM dialect for the currently selected version of the EVM.\nThe only type available in this dialect\nis ``u256``, the 256-bit native type of the Ethereum Virtual Machine.\nSince it is the default type of this dialect, it can be omitted.\n\nThe following table lists all builtin functions\n(depending on the EVM version) and provides a short description of the\nsemantics of the function / opcode.\nThis document does not want to be a full description of the Ethereum virtual machine.\nPlease refer to a different document if you are interested in the precise semantics.\n\nOpcodes marked with ``-`` do not return a result and all others return exactly one value.\nOpcodes marked with ``F``, ``H``, ``B``, ``C``, ``I``, ``L``, ``P``, ``N`` and ``O`` are present since\nFrontier, Homestead, Byzantium, Constantinople, Istanbul, London, Paris, Cancun or Osaka respectively.\n\nIn the following, ``mem[a...b)`` signifies the bytes of memory starting at position ``a`` up to\nbut not including position ``b``, ``storage[p]`` signifies the storage contents at slot ``p``, and\nsimilarly, ``transientStorage[p]`` signifies the transient storage contents at slot ``p``.\n\nSince Yul manages local variables and control-flow,\nopcodes that interfere with these features are not available. This includes\nthe ``dup`` and ``swap`` instructions as well as ``jump`` instructions, labels and the ``push`` instructions.\n\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| Instruction             |     |   | Explanation                                                     |\n+=========================+=====+===+=================================================================+\n| stop()                  | `-` | F | stop execution, identical to return(0, 0)                       |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| add(x, y)               |     | F | x + y                                                           |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| sub(x, y)               |     | F | x - y                                                           |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| mul(x, y)               |     | F | x * y                                                           |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| div(x, y)               |     | F | x / y or 0 if y == 0                                            |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| sdiv(x, y)              |     | F | x / y, for signed numbers in two's complement, 0 if y == 0      |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| mod(x, y)               |     | F | x % y, 0 if y == 0                                              |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| smod(x, y)              |     | F | x % y, for signed numbers in two's complement, 0 if y == 0      |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| exp(x, y)               |     | F | x to the power of y                                             |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| not(x)                  |     | F | bitwise \"not\" of x (every bit of x is negated)                  |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| lt(x, y)                |     | F | 1 if x < y, 0 otherwise                                         |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| gt(x, y)                |     | F | 1 if x > y, 0 otherwise                                         |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| slt(x, y)               |     | F | 1 if x < y, 0 otherwise, for signed numbers in two's complement |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| sgt(x, y)               |     | F | 1 if x > y, 0 otherwise, for signed numbers in two's complement |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| eq(x, y)                |     | F | 1 if x == y, 0 otherwise                                        |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| iszero(x)               |     | F | 1 if x == 0, 0 otherwise                                        |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| and(x, y)               |     | F | bitwise \"and\" of x and y                                        |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| or(x, y)                |     | F | bitwise \"or\" of x and y                                         |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| xor(x, y)               |     | F | bitwise \"xor\" of x and y                                        |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| byte(n, x)              |     | F | nth byte of x, where the most significant byte is the 0th byte  |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| shl(x, y)               |     | C | logical shift left y by x bits                                  |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| shr(x, y)               |     | C | logical shift right y by x bits                                 |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| sar(x, y)               |     | C | signed arithmetic shift right y by x bits                       |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| clz(x)                  |     | O | number of leading zero bits of x, 256 if x == 0                 |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| addmod(x, y, m)         |     | F | (x + y) % m with arbitrary precision arithmetic, 0 if m == 0    |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| mulmod(x, y, m)         |     | F | (x * y) % m with arbitrary precision arithmetic, 0 if m == 0    |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| signextend(i, x)        |     | F | sign extend from (i*8+7)th bit counting from least significant  |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| keccak256(p, n)         |     | F | keccak(mem[p...(p+n)))                                          |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| pop(x)                  | `-` | F | discard value x                                                 |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| mload(p)                |     | F | mem[p...(p+32))                                                 |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| mstore(p, v)            | `-` | F | mem[p...(p+32)) := v                                            |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| mstore8(p, v)           | `-` | F | mem[p] := v & 0xff (only modifies a single byte)                |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| sload(p)                |     | F | storage[p]                                                      |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| sstore(p, v)            | `-` | F | storage[p] := v                                                 |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| tload(p)                |     | N | transientStorage[p]                                             |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| tstore(p, v)            | `-` | N | transientStorage[p] := v                                        |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| msize()                 |     | F | size of memory, i.e. largest accessed memory index              |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| gas()                   |     | F | gas still available to execution                                |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| address()               |     | F | address of the current contract / execution context             |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| balance(a)              |     | F | wei balance at address a                                        |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| selfbalance()           |     | I | equivalent to balance(address()), but cheaper                   |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| caller()                |     | F | call sender (excluding ``delegatecall``)                        |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| callvalue()             |     | F | wei sent together with the current call                         |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| calldataload(p)         |     | F | call data starting from position p (32 bytes)                   |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| calldatasize()          |     | F | size of call data in bytes                                      |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| calldatacopy(t, f, s)   | `-` | F | copy s bytes from calldata at position f to mem at position t   |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| codesize()              |     | F | size of the code of the current contract / execution context    |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| codecopy(t, f, s)       | `-` | F | copy s bytes from code at position f to mem at position t       |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| extcodesize(a)          |     | F | size of the code at address a                                   |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| extcodecopy(a, t, f, s) | `-` | F | like codecopy(t, f, s) but take code at address a               |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| returndatasize()        |     | B | size of the last returndata                                     |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| returndatacopy(t, f, s) | `-` | B | copy s bytes from returndata at position f to mem at position t |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| mcopy(t, f, s)          | `-` | N | copy s bytes from mem at position f to mem at position t        |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| extcodehash(a)          |     | C | code hash of address a                                          |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| create(v, p, n)         |     | F | create new contract with code mem[p...(p+n)) and send v wei     |\n|                         |     |   | and return the new address; returns 0 on error                  |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| create2(v, p, n, s)     |     | C | create new contract with code mem[p...(p+n)) at address         |\n|                         |     |   | keccak256(0xff . this . s . keccak256(mem[p...(p+n)))           |\n|                         |     |   | and send v wei and return the new address, where ``0xff`` is a  |\n|                         |     |   | 1 byte value, ``this`` is the current contract's address        |\n|                         |     |   | as a 20 byte value and ``s`` is a big-endian 256-bit value;     |\n|                         |     |   | returns 0 on error                                              |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| call(g, a, v, in,       |     | F | call contract at address a with input mem[in...(in+insize))     |\n| insize, out, outsize)   |     |   | providing g gas and v wei and output area                       |\n|                         |     |   | mem[out...(out+outsize)) returning 0 on error (eg. out of gas)  |\n|                         |     |   | and 1 on success                                                |\n|                         |     |   | :ref:`See more <yul-call-return-area>`                          |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| callcode(g, a, v, in,   |     | F | identical to ``call`` but only use the code from a and stay     |\n| insize, out, outsize)   |     |   | in the context of the current contract otherwise                |\n|                         |     |   | :ref:`See more <yul-call-return-area>`                          |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| delegatecall(g, a, in,  |     | H | identical to ``callcode`` but also keep ``caller``              |\n| insize, out, outsize)   |     |   | and ``callvalue``                                               |\n|                         |     |   | :ref:`See more <yul-call-return-area>`                          |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| staticcall(g, a, in,    |     | B | identical to ``call(g, a, 0, in, insize, out, outsize)`` but do |\n| insize, out, outsize)   |     |   | not allow state modifications                                   |\n|                         |     |   | :ref:`See more <yul-call-return-area>`                          |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| return(p, s)            | `-` | F | end execution, return data mem[p...(p+s))                       |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| revert(p, s)            | `-` | B | end execution, revert state changes, return data mem[p...(p+s)) |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| selfdestruct(a)         | `-` | F | end execution, destroy current contract and send funds to a     |\n|                         |     |   | (deprecated)                                                    |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| invalid()               | `-` | F | end execution with invalid instruction                          |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| log0(p, s)              | `-` | F | log data mem[p...(p+s))                                         |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| log1(p, s, t1)          | `-` | F | log data mem[p...(p+s)) with topic t1                           |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| log2(p, s, t1, t2)      | `-` | F | log data mem[p...(p+s)) with topics t1, t2                      |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| log3(p, s, t1, t2, t3)  | `-` | F | log data mem[p...(p+s)) with topics t1, t2, t3                  |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| log4(p, s, t1, t2, t3,  | `-` | F | log data mem[p...(p+s)) with topics t1, t2, t3, t4              |\n| t4)                     |     |   |                                                                 |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| chainid()               |     | I | ID of the executing chain (EIP-1344)                            |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| basefee()               |     | L | current block's base fee (EIP-3198 and EIP-1559)                |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| blobbasefee()           |     | N | current block's blob base fee (EIP-7516 and EIP-4844)           |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| origin()                |     | F | transaction sender                                              |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| gasprice()              |     | F | gas price of the transaction                                    |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| blockhash(b)            |     | F | hash of block nr b - only for last 256 blocks excluding current |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| blobhash(i)             |     | N | versioned hash of transaction's i-th blob, 0 if blob does not   |\n|                         |     |   | exist                                                           |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| coinbase()              |     | F | current mining beneficiary                                      |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| timestamp()             |     | F | timestamp of the current block in seconds since the epoch       |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| number()                |     | F | current block number                                            |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| difficulty()            |     | F | difficulty of the current block (see note below)                |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| prevrandao()            |     | P | randomness provided by the beacon chain (see note below)        |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n| gaslimit()              |     | F | block gas limit of the current block                            |\n+-------------------------+-----+---+-----------------------------------------------------------------+\n\n.. _yul-call-return-area:\n\n.. note::\n  The ``call*`` instructions use the ``out`` and ``outsize`` parameters to define an area in memory where\n  the return or failure data is placed. This area is written to depending on how many bytes the called contract returns.\n  If it returns more data, only the first ``outsize`` bytes are written. You can access the rest of the data\n  using the ``returndatacopy`` opcode. If it returns less data, then the remaining bytes are not touched at all.\n  You need to use the ``returndatasize`` opcode to check which part of this memory area contains the return data.\n  The remaining bytes will retain their values as of before the call.\n\n.. note::\n  The ``difficulty()`` instruction is disallowed in EVM version >= Paris.\n  With the Paris network upgrade the semantics of the instruction that was previously called\n  ``difficulty`` have been changed and the instruction was renamed to ``prevrandao``.\n  It can now return arbitrary values in the full 256-bit range, whereas the highest recorded\n  difficulty value within Ethash was ~54 bits.\n  This change is described in `EIP-4399 <https://eips.ethereum.org/EIPS/eip-4399>`_.\n  Please note that irrelevant to which EVM version is selected in the compiler, the semantics of\n  instructions depend on the final chain of deployment.\n\n.. warning::\n    From version 0.8.18 and up, the use of ``selfdestruct`` in both Solidity and Yul will trigger a\n    deprecation warning, since the ``SELFDESTRUCT`` opcode will eventually undergo breaking changes in behavior\n    as stated in `EIP-6049 <https://eips.ethereum.org/EIPS/eip-6049>`_.\n\nIn some internal dialects, there are additional functions:\n\ndatasize, dataoffset, datacopy\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe functions ``datasize(x)``, ``dataoffset(x)`` and ``datacopy(t, f, l)``\nare used to access other parts of a Yul object.\n\n``datasize`` and ``dataoffset`` can only take string literals (the names of other objects)\nas arguments and return the size and offset in the data area, respectively.\nFor the EVM, the ``datacopy`` function is equivalent to ``codecopy``.\n\n\nsetimmutable, loadimmutable\n^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe functions ``setimmutable(offset, \"name\", value)`` and ``loadimmutable(\"name\")`` are\nused for the immutable mechanism in Solidity and do not nicely map to pure Yul.\nThe call to ``setimmutable(offset, \"name\", value)`` assumes that the runtime code of the contract\ncontaining the given named immutable was copied to memory at offset ``offset`` and will write ``value`` to all\npositions in memory (relative to ``offset``) that contain the placeholder that was generated for calls\nto ``loadimmutable(\"name\")`` in the runtime code.\n\n\nlinkersymbol\n^^^^^^^^^^^^\nThe function ``linkersymbol(\"library_id\")`` is a placeholder for an address literal to be substituted\nby the linker.\nIts first and only argument must be a string literal and uniquely represents the address to be inserted.\nIdentifiers can be arbitrary but when the compiler produces Yul code from Solidity sources,\nit uses a library name qualified with the name of the source unit that defines that library.\nTo link the code with a particular library address, the same identifier must be provided to the\n``--libraries`` option on the command-line.\n\nFor example this code\n\n.. code-block:: yul\n\n    let a := linkersymbol(\"file.sol:Math\")\n\nis equivalent to\n\n.. code-block:: yul\n\n    let a := 0x1234567890123456789012345678901234567890\n\nwhen the linker is invoked with ``--libraries \"file.sol:Math=0x1234567890123456789012345678901234567890``\noption.\n\nSee :ref:`Using the Commandline Compiler <commandline-compiler>` for details about the Solidity linker.\n\nmemoryguard\n^^^^^^^^^^^\n\nThis function is available in the EVM dialect with objects. The caller of\n``let ptr := memoryguard(size)`` (where ``size`` has to be a literal number)\npromises that they only use memory in either the range ``[0, size)`` or the\nunbounded range starting at ``ptr``.\n\nSince the presence of a ``memoryguard`` call indicates that all memory access\nadheres to this restriction, it allows the optimizer to perform additional\noptimization steps, for example the stack limit evader, which attempts to move\nstack variables that would otherwise be unreachable to memory.\n\nThe Yul optimizer promises to only use the memory range ``[size, ptr)`` for its purposes.\nIf the optimizer does not need to reserve any memory, it holds that ``ptr == size``.\n\n``memoryguard`` can be called multiple times, but needs to have the same literal as argument\nwithin one Yul subobject. If at least one ``memoryguard`` call is found in a subobject,\nthe additional optimiser steps will be run on it.\n\n\n.. _yul-verbatim:\n\nverbatim\n^^^^^^^^\n\nThe set of ``verbatim...`` builtin functions lets you create bytecode for opcodes\nthat are not known to the Yul compiler. It also allows you to create\nbytecode sequences that will not be modified by the optimizer.\n\nThe functions are ``verbatim_<n>i_<m>o(\"<data>\", ...)``, where\n\n- ``n`` is a decimal between 0 and 99 that specifies the number of input stack slots / variables\n- ``m`` is a decimal between 0 and 99 that specifies the number of output stack slots / variables\n- ``data`` is a string literal that contains the sequence of bytes\n\nIf you for example want to define a function that multiplies the input\nby two, without the optimizer touching the constant two, you can use\n\n.. code-block:: yul\n\n    let x := calldataload(0)\n    let double := verbatim_1i_1o(hex\"600202\", x)\n\nThis code will result in a ``dup1`` opcode to retrieve ``x``\n(the optimizer might directly reuse result of the\n``calldataload`` opcode, though)\ndirectly followed by ``600202``. The code is assumed to\nconsume the copied value of ``x`` and produce the result\non the top of the stack. The compiler then generates code\nto allocate a stack slot for ``double`` and store the result there.\n\nAs with all opcodes, the arguments are arranged on the stack\nwith the leftmost argument on the top, while the return values\nare assumed to be laid out such that the rightmost variable is\nat the top of the stack.\n\nSince ``verbatim`` can be used to generate arbitrary opcodes\nor even opcodes unknown to the Solidity compiler, care has to be taken\nwhen using ``verbatim`` together with the optimizer. Even when the\noptimizer is switched off, the code generator has to determine\nthe stack layout, which means that e.g. using ``verbatim`` to modify\nthe stack height can lead to undefined behavior.\n\nThe following is a non-exhaustive list of restrictions on\nverbatim bytecode that are not checked by\nthe compiler. Violations of these restrictions can result in\nundefined behavior.\n\n- Control-flow should not jump into or out of verbatim blocks,\n  but it can jump within the same verbatim block. In particular,\n  reverting or returning from the block is *not* allowed.\n- Stack contents apart from the input and output parameters\n  should not be accessed.\n- The stack height difference should be exactly ``m - n``\n  (output slots minus input slots).\n- Verbatim bytecode cannot make any assumptions about the\n  surrounding bytecode. All required parameters have to be\n  passed in as stack variables.\n\nThe optimizer does not analyze verbatim bytecode and always\nassumes that it modifies all aspects of state and thus can only\ndo very few optimizations across ``verbatim`` function calls.\n\nThe optimizer treats verbatim bytecode as an opaque block of code.\nIt will not split it but might move, duplicate\nor combine it with identical verbatim bytecode blocks.\nIf a verbatim bytecode block is unreachable by the control-flow,\nit can be removed.\n\n\n.. warning::\n\n    During discussions about whether or not EVM improvements\n    might break existing smart contracts, features inside ``verbatim``\n    cannot receive the same consideration as those used by the Solidity\n    compiler itself.\n\n.. note::\n\n    To avoid confusion, all identifiers starting with the string ``verbatim`` are reserved\n    and cannot be used for user-defined identifiers.\n\n.. _yul-object:\n\nSpecification of Yul Object\n===========================\n\nYul objects are used to group named code and data sections.\nThe functions ``datasize``, ``dataoffset`` and ``datacopy``\ncan be used to access these sections from within code.\nHex strings can be used to specify data in hex encoding,\nregular strings in native encoding. For code,\n``datacopy`` will access its assembled binary representation.\n\n.. code-block:: none\n\n    Object = 'object' StringLiteral '{' Code ( Object | Data )* '}'\n    Code = 'code' Block\n    Data = 'data' StringLiteral ( HexLiteral | StringLiteral )\n    HexLiteral = 'hex' ('\"' ([0-9a-fA-F]{2})* '\"' | '\\'' ([0-9a-fA-F]{2})* '\\'')\n    StringLiteral = '\"' ([^\"\\r\\n\\\\] | '\\\\' .)* '\"'\n\nAbove, ``Block`` refers to ``Block`` in the Yul code grammar explained in the previous chapter.\n\n.. note::\n\n    An object with a name that ends in ``_deployed`` is treated as deployed code by the Yul optimizer.\n    The only consequence of this is a different gas cost heuristic in the optimizer.\n\n.. note::\n\n    Data objects or sub-objects whose names contain a ``.`` can be defined\n    but it is not possible to access them through ``datasize``,\n    ``dataoffset`` or ``datacopy`` because ``.`` is used as a separator\n    to access objects inside another object.\n\n.. note::\n\n    The data object called ``\".metadata\"`` has a special meaning:\n    It cannot be accessed from code and is always appended to the very end of the\n    bytecode, regardless of its position in the object.\n\n    Other data objects with special significance might be added in the\n    future, but their names will always start with a ``.``.\n\n\nAn example Yul Object is shown below:\n\n.. code-block:: yul\n\n    // A contract consists of a single object with sub-objects representing\n    // the code to be deployed or other contracts it can create.\n    // The single \"code\" node is the executable code of the object.\n    // Every (other) named object or data section is serialized and\n    // made accessible to the special built-in functions datacopy / dataoffset / datasize\n    // The current object, sub-objects and data items inside the current object\n    // are in scope.\n    object \"Contract1\" {\n        // This is the constructor code of the contract.\n        code {\n            function allocate(size) -> ptr {\n                ptr := mload(0x40)\n                // Note that Solidity generated IR code reserves memory offset ``0x60`` as well, but a pure Yul object is free to use memory as it chooses.\n                if iszero(ptr) { ptr := 0x60 }\n                mstore(0x40, add(ptr, size))\n            }\n\n            // first create \"Contract2\"\n            let size := datasize(\"Contract2\")\n            let offset := allocate(size)\n            // This will turn into codecopy for EVM\n            datacopy(offset, dataoffset(\"Contract2\"), size)\n            // constructor parameter is a single number 0x1234\n            mstore(add(offset, size), 0x1234)\n            pop(create(0, offset, add(size, 32)))\n\n            // now return the runtime object (the currently\n            // executing code is the constructor code)\n            size := datasize(\"Contract1_deployed\")\n            offset := allocate(size)\n            // This will turn into a codecopy for EVM\n            datacopy(offset, dataoffset(\"Contract1_deployed\"), size)\n            return(offset, size)\n        }\n\n        data \"Table2\" hex\"4123\"\n\n        object \"Contract1_deployed\" {\n            code {\n                function allocate(size) -> ptr {\n                    ptr := mload(0x40)\n                    // Note that Solidity generated IR code reserves memory offset ``0x60`` as well, but a pure Yul object is free to use memory as it chooses.\n                    if iszero(ptr) { ptr := 0x60 }\n                    mstore(0x40, add(ptr, size))\n                }\n\n                // runtime code\n\n                mstore(0, \"Hello, World!\")\n                return(0, 0x20)\n            }\n        }\n\n        // Embedded object. Use case is that the outside is a factory contract,\n        // and Contract2 is the code to be created by the factory\n        object \"Contract2\" {\n            code {\n                // code here ...\n            }\n\n            object \"Contract2_deployed\" {\n                code {\n                    // code here ...\n                }\n            }\n\n            data \"Table1\" hex\"4123\"\n        }\n    }\n\nYul Optimizer\n=============\n\nThe Yul optimizer operates on Yul code and uses the same language for input, output and\nintermediate states. This allows for easy debugging and verification of the optimizer.\n\nPlease refer to the general :ref:`optimizer documentation <optimizer>`\nfor more details about the different optimization stages and how to use the optimizer.\n\nIf you want to use Solidity in stand-alone Yul mode, you activate the optimizer using ``--optimize``\nand optionally specify the :ref:`expected number of contract executions <optimizer-parameter-runs>` with\n``--optimize-runs``:\n\n.. code-block:: sh\n\n    solc --strict-assembly --optimize --optimize-runs 200\n\nIn Solidity mode, the Yul optimizer is activated together with the regular optimizer.\n\n.. _optimization-step-sequence:\n\nOptimization Step Sequence\n--------------------------\n\nDetailed information regarding the optimization sequence as well as a list of abbreviations is\navailable in the :ref:`optimizer docs <optimizer-steps>`.\n\n.. _erc20yul:\n\nComplete ERC20 Example\n======================\n\n.. code-block:: yul\n\n    object \"Token\" {\n        code {\n            // Store the creator in slot zero.\n            sstore(0, caller())\n\n            // Deploy the contract\n            datacopy(0, dataoffset(\"runtime\"), datasize(\"runtime\"))\n            return(0, datasize(\"runtime\"))\n        }\n        object \"runtime\" {\n            code {\n                // Protection against sending Ether\n                require(iszero(callvalue()))\n\n                // Dispatcher\n                switch selector()\n                case 0x70a08231 /* \"balanceOf(address)\" */ {\n                    returnUint(balanceOf(decodeAsAddress(0)))\n                }\n                case 0x18160ddd /* \"totalSupply()\" */ {\n                    returnUint(totalSupply())\n                }\n                case 0xa9059cbb /* \"transfer(address,uint256)\" */ {\n                    transfer(decodeAsAddress(0), decodeAsUint(1))\n                    returnTrue()\n                }\n                case 0x23b872dd /* \"transferFrom(address,address,uint256)\" */ {\n                    transferFrom(decodeAsAddress(0), decodeAsAddress(1), decodeAsUint(2))\n                    returnTrue()\n                }\n                case 0x095ea7b3 /* \"approve(address,uint256)\" */ {\n                    approve(decodeAsAddress(0), decodeAsUint(1))\n                    returnTrue()\n                }\n                case 0xdd62ed3e /* \"allowance(address,address)\" */ {\n                    returnUint(allowance(decodeAsAddress(0), decodeAsAddress(1)))\n                }\n                case 0x40c10f19 /* \"mint(address,uint256)\" */ {\n                    mint(decodeAsAddress(0), decodeAsUint(1))\n                    returnTrue()\n                }\n                default {\n                    revert(0, 0)\n                }\n\n                function mint(account, amount) {\n                    require(calledByOwner())\n\n                    mintTokens(amount)\n                    addToBalance(account, amount)\n                    emitTransfer(0, account, amount)\n                }\n                function transfer(to, amount) {\n                    executeTransfer(caller(), to, amount)\n                }\n                function approve(spender, amount) {\n                    revertIfZeroAddress(spender)\n                    setAllowance(caller(), spender, amount)\n                    emitApproval(caller(), spender, amount)\n                }\n                function transferFrom(from, to, amount) {\n                    decreaseAllowanceBy(from, caller(), amount)\n                    executeTransfer(from, to, amount)\n                }\n\n                function executeTransfer(from, to, amount) {\n                    revertIfZeroAddress(to)\n                    deductFromBalance(from, amount)\n                    addToBalance(to, amount)\n                    emitTransfer(from, to, amount)\n                }\n\n\n                /* ---------- calldata decoding functions ----------- */\n                function selector() -> s {\n                    s := div(calldataload(0), 0x100000000000000000000000000000000000000000000000000000000)\n                }\n\n                function decodeAsAddress(offset) -> v {\n                    v := decodeAsUint(offset)\n                    if iszero(iszero(and(v, not(0xffffffffffffffffffffffffffffffffffffffff)))) {\n                        revert(0, 0)\n                    }\n                }\n                function decodeAsUint(offset) -> v {\n                    let pos := add(4, mul(offset, 0x20))\n                    if lt(calldatasize(), add(pos, 0x20)) {\n                        revert(0, 0)\n                    }\n                    v := calldataload(pos)\n                }\n                /* ---------- calldata encoding functions ---------- */\n                function returnUint(v) {\n                    mstore(0, v)\n                    return(0, 0x20)\n                }\n                function returnTrue() {\n                    returnUint(1)\n                }\n\n                /* -------- events ---------- */\n                function emitTransfer(from, to, amount) {\n                    let signatureHash := 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\n                    emitEvent(signatureHash, from, to, amount)\n                }\n                function emitApproval(from, spender, amount) {\n                    let signatureHash := 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925\n                    emitEvent(signatureHash, from, spender, amount)\n                }\n                function emitEvent(signatureHash, indexed1, indexed2, nonIndexed) {\n                    mstore(0, nonIndexed)\n                    log3(0, 0x20, signatureHash, indexed1, indexed2)\n                }\n\n                /* -------- storage layout ---------- */\n                function ownerPos() -> p { p := 0 }\n                function totalSupplyPos() -> p { p := 1 }\n                function accountToStorageOffset(account) -> offset {\n                    offset := add(0x1000, account)\n                }\n                function allowanceStorageOffset(account, spender) -> offset {\n                    offset := accountToStorageOffset(account)\n                    mstore(0, offset)\n                    mstore(0x20, spender)\n                    offset := keccak256(0, 0x40)\n                }\n\n                /* -------- storage access ---------- */\n                function owner() -> o {\n                    o := sload(ownerPos())\n                }\n                function totalSupply() -> supply {\n                    supply := sload(totalSupplyPos())\n                }\n                function mintTokens(amount) {\n                    sstore(totalSupplyPos(), safeAdd(totalSupply(), amount))\n                }\n                function balanceOf(account) -> bal {\n                    bal := sload(accountToStorageOffset(account))\n                }\n                function addToBalance(account, amount) {\n                    let offset := accountToStorageOffset(account)\n                    sstore(offset, safeAdd(sload(offset), amount))\n                }\n                function deductFromBalance(account, amount) {\n                    let offset := accountToStorageOffset(account)\n                    let bal := sload(offset)\n                    require(lte(amount, bal))\n                    sstore(offset, sub(bal, amount))\n                }\n                function allowance(account, spender) -> amount {\n                    amount := sload(allowanceStorageOffset(account, spender))\n                }\n                function setAllowance(account, spender, amount) {\n                    sstore(allowanceStorageOffset(account, spender), amount)\n                }\n                function decreaseAllowanceBy(account, spender, amount) {\n                    let offset := allowanceStorageOffset(account, spender)\n                    let currentAllowance := sload(offset)\n                    require(lte(amount, currentAllowance))\n                    sstore(offset, sub(currentAllowance, amount))\n                }\n\n                /* ---------- utility functions ---------- */\n                function lte(a, b) -> r {\n                    r := iszero(gt(a, b))\n                }\n                function gte(a, b) -> r {\n                    r := iszero(lt(a, b))\n                }\n                function safeAdd(a, b) -> r {\n                    r := add(a, b)\n                    if or(lt(r, a), lt(r, b)) { revert(0, 0) }\n                }\n                function calledByOwner() -> cbo {\n                    cbo := eq(owner(), caller())\n                }\n                function revertIfZeroAddress(addr) {\n                    require(addr)\n                }\n                function require(condition) {\n                    if iszero(condition) { revert(0, 0) }\n                }\n            }\n        }\n    }\n"
  },
  {
    "path": "funding.json",
    "content": "{\n  \"opRetro\": {\n    \"projectId\": \"0xcc8d03e014e121d10602eeff729b755d5dc6a317df0d6302c8a9d3b5424aaba8\"\n  }\n}\n"
  },
  {
    "path": "libevmasm/AbstractAssemblyStack.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libevmasm/LinkerObject.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/JSON.h>\n\n#include <string>\n#include <vector>\n\nnamespace solidity::evmasm\n{\n\nclass AbstractAssemblyStack\n{\npublic:\n\tvirtual ~AbstractAssemblyStack() {}\n\n\tvirtual LinkerObject const& object(std::string const& _contractName) const = 0;\n\tvirtual LinkerObject const& runtimeObject(std::string const& _contractName) const = 0;\n\n\tvirtual std::string const* sourceMapping(std::string const& _contractName) const = 0;\n\tvirtual std::string const* runtimeSourceMapping(std::string const& _contractName) const = 0;\n\n\tvirtual Json ethdebug(std::string const& _contractName) const = 0;\n\tvirtual Json ethdebugRuntime(std::string const& _contractName) const = 0;\n\tvirtual Json ethdebug() const = 0;\n\n\tvirtual Json assemblyJSON(std::string const& _contractName) const = 0;\n\tvirtual std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const = 0;\n\n\tvirtual std::string const filesystemFriendlyName(std::string const& _contractName) const = 0;\n\n\tvirtual std::vector<std::string> contractNames() const = 0;\n\tvirtual std::vector<std::string> sourceNames() const = 0;\n\n\tvirtual bool compilationSuccessful() const = 0;\n};\n\n} // namespace solidity::evmasm\n"
  },
  {
    "path": "libevmasm/Assembly.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file Assembly.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <libevmasm/Assembly.h>\n\n#include <libevmasm/CommonSubexpressionEliminator.h>\n#include <libevmasm/ControlFlowGraph.h>\n#include <libevmasm/PeepholeOptimiser.h>\n#include <libevmasm/Inliner.h>\n#include <libevmasm/JumpdestRemover.h>\n#include <libevmasm/BlockDeduplicator.h>\n#include <libevmasm/ConstantOptimiser.h>\n\n#include <liblangutil/CharStream.h>\n#include <liblangutil/Exceptions.h>\n\n#include <libsolutil/JSON.h>\n#include <libsolutil/StringUtils.h>\n\n#include <fmt/format.h>\n\n#include <range/v3/algorithm/any_of.hpp>\n#include <range/v3/algorithm/find_if.hpp>\n#include <range/v3/view/drop_exactly.hpp>\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/map.hpp>\n\n#include <fstream>\n#include <limits>\n#include <iterator>\n#include <stack>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\n\nnamespace\n{\n\n/// Produces instruction location info in RAII style. When an assembly instruction is added to the bytecode,\n/// this class can be instantiated in that scope. It will record the current bytecode size (before addition)\n/// and, at destruction time, record the new bytecode size. This information is then added to an external\n/// instruction locations vector.\n/// If the instruction decomposes into multiple individual evm instructions, `emit` can be\n/// called for all but the last one (which will be emitted by the destructor).\nclass InstructionLocationEmitter\n{\npublic:\n\tInstructionLocationEmitter(\n\t\tstd::vector<LinkerObject::InstructionLocation>& _instructionLocations,\n\t\tbytes const& _bytecode,\n\t\tsize_t const _assemblyItemIndex\n\t):\n\t\tm_instructionLocations(_instructionLocations),\n\t\tm_bytecode(_bytecode),\n\t\tm_assemblyItemIndex(_assemblyItemIndex),\n\t\tm_instructionLocationStart(_bytecode.size())\n\t{}\n\n\t~InstructionLocationEmitter()\n\t{\n\t\temit();\n\t}\n\n\tvoid emit()\n\t{\n\t\tauto const end = m_bytecode.size();\n\t\tm_instructionLocations.push_back(LinkerObject::InstructionLocation{\n\t\t\t.start = m_instructionLocationStart,\n\t\t\t.end = end,\n\t\t\t.assemblyItemIndex = m_assemblyItemIndex\n\t\t});\n\t\tm_instructionLocationStart = end;\n\t}\n\nprivate:\n\tstd::vector<LinkerObject::InstructionLocation>& m_instructionLocations;\n\tbytes const& m_bytecode;\n\tsize_t const m_assemblyItemIndex{};\n\tsize_t m_instructionLocationStart{};\n};\n\n}\n\nstd::map<std::string, std::shared_ptr<std::string const>> Assembly::s_sharedSourceNames;\n\nAssemblyItem const& Assembly::append(AssemblyItem _i)\n{\n\tassertThrow(m_deposit >= 0, AssemblyException, \"Stack underflow.\");\n\tm_deposit += static_cast<int>(_i.deposit());\n\tsolAssert(m_currentCodeSection < m_codeSections.size());\n\tauto& currentItems = m_codeSections.at(m_currentCodeSection).items;\n\tcurrentItems.emplace_back(std::move(_i));\n\tif (!currentItems.back().location().isValid() && m_currentSourceLocation.isValid())\n\t\tcurrentItems.back().setLocation(m_currentSourceLocation);\n\tcurrentItems.back().m_modifierDepth = m_currentModifierDepth;\n\treturn currentItems.back();\n}\n\nunsigned Assembly::codeSize(unsigned subTagSize) const\n{\n\tfor (unsigned tagSize = subTagSize; true; ++tagSize)\n\t{\n\t\tsize_t ret = 1;\n\t\tfor (auto const& i: m_data)\n\t\t\tret += i.second.size();\n\n\t\tfor (auto const& codeSection: m_codeSections)\n\t\t\tfor (AssemblyItem const& i: codeSection.items)\n\t\t\t\tret += i.bytesRequired(tagSize, m_evmVersion, Precision::Precise);\n\t\tif (numberEncodingSize(ret) <= tagSize)\n\t\t\treturn static_cast<unsigned>(ret);\n\t}\n}\n\nvoid Assembly::importAssemblyItemsFromJSON(Json const& _code, std::vector<std::string> const& _sourceList)\n{\n\t// Assembly constructor creates first code section with proper type and empty `items`\n\tsolAssert(m_codeSections.size() == 1);\n\tsolAssert(m_codeSections[0].items.empty());\n\t// TODO: Add support for EOF and more than one code sections.\n\tsolUnimplementedAssert(!m_eofVersion.has_value(), \"Assembly import for EOF is not yet implemented.\");\n\tsolRequire(_code.is_array(), AssemblyImportException, \"Supplied JSON is not an array.\");\n\tfor (auto jsonItemIter = std::begin(_code); jsonItemIter != std::end(_code); ++jsonItemIter)\n\t{\n\t\tAssemblyItem const& newItem = m_codeSections[0].items.emplace_back(createAssemblyItemFromJSON(*jsonItemIter, _sourceList));\n\t\tif (newItem == Instruction::JUMPDEST)\n\t\t\tsolThrow(AssemblyImportException, \"JUMPDEST instruction without a tag\");\n\t\telse if (newItem.type() == AssemblyItemType::Tag)\n\t\t{\n\t\t\t++jsonItemIter;\n\t\t\tif (jsonItemIter != std::end(_code) && createAssemblyItemFromJSON(*jsonItemIter, _sourceList) != Instruction::JUMPDEST)\n\t\t\t\tsolThrow(AssemblyImportException, \"JUMPDEST expected after tag.\");\n\t\t}\n\t}\n}\n\nAssemblyItem Assembly::createAssemblyItemFromJSON(Json const& _json, std::vector<std::string> const& _sourceList)\n{\n\tsolRequire(_json.is_object(), AssemblyImportException, \"Supplied JSON is not an object.\");\n\tstatic std::set<std::string> const validMembers{\"name\", \"begin\", \"end\", \"source\", \"value\", \"modifierDepth\", \"jumpType\"};\n\tfor (auto const& [member, _]: _json.items())\n\t\tsolRequire(\n\t\t\tvalidMembers.count(member),\n\t\t\tAssemblyImportException,\n\t\t\tfmt::format(\n\t\t\t\t\"Unknown member '{}'. Valid members are: {}.\",\n\t\t\t\tmember,\n\t\t\t\tsolidity::util::joinHumanReadable(validMembers, \", \")\n\t\t\t)\n\t\t);\n\tsolRequire(isOfType<std::string>(_json[\"name\"]), AssemblyImportException, \"Member 'name' missing or not of type string.\");\n\tsolRequire(isOfTypeIfExists<int>(_json, \"begin\"), AssemblyImportException, \"Optional member 'begin' not of type int.\");\n\tsolRequire(isOfTypeIfExists<int>(_json, \"end\"), AssemblyImportException, \"Optional member 'end' not of type int.\");\n\tsolRequire(isOfTypeIfExists<int>(_json, \"source\"), AssemblyImportException, \"Optional member 'source' not of type int.\");\n\tsolRequire(isOfTypeIfExists<std::string>(_json, \"value\"), AssemblyImportException, \"Optional member 'value' not of type string.\");\n\tsolRequire(isOfTypeIfExists<int>(_json, \"modifierDepth\"), AssemblyImportException, \"Optional member 'modifierDepth' not of type int.\");\n\tsolRequire(isOfTypeIfExists<std::string>(_json, \"jumpType\"), AssemblyImportException, \"Optional member 'jumpType' not of type string.\");\n\n\tstd::string name = get<std::string>(_json[\"name\"]);\n\tsolRequire(!name.empty(), AssemblyImportException, \"Member 'name' is empty.\");\n\n\tSourceLocation location;\n\tif (_json.contains(\"begin\"))\n\t\tlocation.start = get<int>(_json[\"begin\"]);\n\tif (_json.contains(\"end\"))\n\t\tlocation.end = get<int>(_json[\"end\"]);\n\tint srcIndex = getOrDefault<int>(_json, \"source\", -1);\n\tsize_t modifierDepth = static_cast<size_t>(getOrDefault<int>(_json, \"modifierDepth\", 0));\n\tstd::string value = getOrDefault<std::string>(_json, \"value\", \"\");\n\tstd::string jumpType = getOrDefault<std::string>(_json, \"jumpType\", \"\");\n\n\tauto updateUsedTags = [&](u256 const& data)\n\t{\n\t\tm_usedTags = std::max(m_usedTags, static_cast<unsigned>(data) + 1);\n\t\treturn data;\n\t};\n\n\tauto storeImmutableHash = [&](std::string const& _immutableName) -> h256\n\t{\n\t\th256 hash(util::keccak256(_immutableName));\n\t\tsolAssert(m_immutables.count(hash) == 0 || m_immutables[hash] == _immutableName);\n\t\tm_immutables[hash] = _immutableName;\n\t\treturn hash;\n\t};\n\n\tauto storeLibraryHash = [&](std::string const& _libraryName) -> h256\n\t{\n\t\th256 hash(util::keccak256(_libraryName));\n\t\tsolAssert(m_libraries.count(hash) == 0 || m_libraries[hash] == _libraryName);\n\t\tm_libraries[hash] = _libraryName;\n\t\treturn hash;\n\t};\n\n\tauto requireValueDefinedForInstruction = [&](std::string const& _name, std::string const& _value)\n\t{\n\t\tsolRequire(\n\t\t\t!_value.empty(),\n\t\t\tAssemblyImportException,\n\t\t\t\"Member 'value' is missing for instruction '\" + _name + \"', but the instruction needs a value.\"\n\t\t);\n\t};\n\n\tauto requireValueUndefinedForInstruction = [&](std::string const& _name, std::string const& _value)\n\t{\n\t\tsolRequire(\n\t\t\t_value.empty(),\n\t\t\tAssemblyImportException,\n\t\t\t\"Member 'value' defined for instruction '\" + _name + \"', but the instruction does not need a value.\"\n\t\t);\n\t};\n\n\tsolRequire(srcIndex >= -1 && srcIndex < static_cast<int>(_sourceList.size()), AssemblyImportException, \"Source index out of bounds.\");\n\tif (srcIndex != -1)\n\t\tlocation.sourceName = sharedSourceName(_sourceList[static_cast<size_t>(srcIndex)]);\n\n\tAssemblyItem result(0);\n\n\tif (c_instructions.count(name))\n\t{\n\t\tAssemblyItem item{c_instructions.at(name), langutil::DebugData::create(location)};\n\t\tif (!jumpType.empty())\n\t\t{\n\t\t\tif (item.instruction() == Instruction::JUMP || item.instruction() == Instruction::JUMPI)\n\t\t\t{\n\t\t\t\tstd::optional<AssemblyItem::JumpType> parsedJumpType = AssemblyItem::parseJumpType(jumpType);\n\t\t\t\tif (!parsedJumpType.has_value())\n\t\t\t\t\tsolThrow(AssemblyImportException, \"Invalid jump type.\");\n\t\t\t\titem.setJumpType(parsedJumpType.value());\n\t\t\t}\n\t\t\telse\n\t\t\t\tsolThrow(\n\t\t\t\t\tAssemblyImportException,\n\t\t\t\t\t\"Member 'jumpType' set on instruction different from JUMP or JUMPI (was set on instruction '\" + name + \"')\"\n\t\t\t\t);\n\t\t}\n\t\trequireValueUndefinedForInstruction(name, value);\n\t\tresult = item;\n\t}\n\telse\n\t{\n\t\tsolRequire(\n\t\t\tjumpType.empty(),\n\t\t\tAssemblyImportException,\n\t\t\t\"Member 'jumpType' set on instruction different from JUMP or JUMPI (was set on instruction '\" + name + \"')\"\n\t\t);\n\t\tif (name == \"PUSH\")\n\t\t{\n\t\t\trequireValueDefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::Push, u256(\"0x\" + value)};\n\t\t}\n\t\telse if (name == \"PUSH [ErrorTag]\")\n\t\t{\n\t\t\trequireValueUndefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::PushTag, 0};\n\t\t}\n\t\telse if (name == \"PUSH [tag]\")\n\t\t{\n\t\t\trequireValueDefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::PushTag, updateUsedTags(u256(value))};\n\t\t}\n\t\telse if (name == \"PUSH [$]\")\n\t\t{\n\t\t\trequireValueDefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::PushSub, u256(\"0x\" + value)};\n\t\t}\n\t\telse if (name == \"PUSH #[$]\")\n\t\t{\n\t\t\trequireValueDefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::PushSubSize, u256(\"0x\" + value)};\n\t\t}\n\t\telse if (name == \"PUSHSIZE\")\n\t\t{\n\t\t\trequireValueUndefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::PushProgramSize, 0};\n\t\t}\n\t\telse if (name == \"PUSHLIB\")\n\t\t{\n\t\t\trequireValueDefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::PushLibraryAddress, storeLibraryHash(value)};\n\t\t}\n\t\telse if (name == \"PUSHDEPLOYADDRESS\")\n\t\t{\n\t\t\trequireValueUndefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::PushDeployTimeAddress, 0};\n\t\t}\n\t\telse if (name == \"PUSHIMMUTABLE\")\n\t\t{\n\t\t\trequireValueDefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::PushImmutable, storeImmutableHash(value)};\n\t\t}\n\t\telse if (name == \"ASSIGNIMMUTABLE\")\n\t\t{\n\t\t\trequireValueDefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::AssignImmutable, storeImmutableHash(value)};\n\t\t}\n\t\telse if (name == \"tag\")\n\t\t{\n\t\t\trequireValueDefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::Tag, updateUsedTags(u256(value))};\n\t\t}\n\t\telse if (name == \"PUSH data\")\n\t\t{\n\t\t\trequireValueDefinedForInstruction(name, value);\n\t\t\tresult = {AssemblyItemType::PushData, u256(\"0x\" + value)};\n\t\t}\n\t\telse if (name == \"VERBATIM\")\n\t\t{\n\t\t\trequireValueDefinedForInstruction(name, value);\n\t\t\tAssemblyItem item(fromHex(value), 0, 0);\n\t\t\tresult = item;\n\t\t}\n\t\telse\n\t\t\tsolThrow(AssemblyImportException, \"Invalid opcode (\" + name + \")\");\n\t}\n\tresult.setLocation(location);\n\tresult.m_modifierDepth = modifierDepth;\n\treturn result;\n}\n\nnamespace\n{\n\nstd::string locationFromSources(StringMap const& _sourceCodes, SourceLocation const& _location)\n{\n\tif (!_location.hasText() || _sourceCodes.empty())\n\t\treturn {};\n\n\tauto it = _sourceCodes.find(*_location.sourceName);\n\tif (it == _sourceCodes.end())\n\t\treturn {};\n\n\treturn CharStream::singleLineSnippet(it->second, _location);\n}\n\nclass Functionalizer\n{\npublic:\n\tFunctionalizer (std::ostream& _out, std::string const& _prefix, StringMap const& _sourceCodes, Assembly const& _assembly):\n\t\tm_out(_out), m_prefix(_prefix), m_sourceCodes(_sourceCodes), m_assembly(_assembly)\n\t{}\n\n\tvoid feed(AssemblyItem const& _item, DebugInfoSelection const& _debugInfoSelection)\n\t{\n\t\tif (_item.location().isValid() && _item.location() != m_location)\n\t\t{\n\t\t\tflush();\n\t\t\tm_location = _item.location();\n\t\t\tprintLocation(_debugInfoSelection);\n\t\t}\n\n\t\tstd::string expression = _item.toAssemblyText(m_assembly);\n\n\t\tif (!(\n\t\t\t_item.canBeFunctional() &&\n\t\t\t_item.returnValues() <= 1 &&\n\t\t\t_item.arguments() <= m_pending.size()\n\t\t))\n\t\t{\n\t\t\tflush();\n\t\t\tm_out << m_prefix << (_item.type() == Tag ? \"\" : \"  \") << expression << std::endl;\n\t\t\treturn;\n\t\t}\n\t\tif (_item.arguments() > 0)\n\t\t{\n\t\t\texpression += \"(\";\n\t\t\tfor (size_t i = 0; i < _item.arguments(); ++i)\n\t\t\t{\n\t\t\t\texpression += m_pending.back();\n\t\t\t\tm_pending.pop_back();\n\t\t\t\tif (i + 1 < _item.arguments())\n\t\t\t\t\texpression += \", \";\n\t\t\t}\n\t\t\texpression += \")\";\n\t\t}\n\n\t\tm_pending.push_back(expression);\n\t\tif (_item.returnValues() != 1)\n\t\t\tflush();\n\t}\n\n\tvoid flush()\n\t{\n\t\tfor (std::string const& expression: m_pending)\n\t\t\tm_out << m_prefix << \"  \" << expression << std::endl;\n\t\tm_pending.clear();\n\t}\n\n\tvoid printLocation(DebugInfoSelection const& _debugInfoSelection)\n\t{\n\t\tif (!m_location.isValid() || (!_debugInfoSelection.location && !_debugInfoSelection.snippet))\n\t\t\treturn;\n\n\t\tm_out << m_prefix << \"    /*\";\n\n\t\tif (_debugInfoSelection.location)\n\t\t{\n\t\t\tif (m_location.sourceName)\n\t\t\t\tm_out << \" \" + escapeAndQuoteString(*m_location.sourceName);\n\t\t\tif (m_location.hasText())\n\t\t\t\tm_out << \":\" << std::to_string(m_location.start) + \":\" + std::to_string(m_location.end);\n\t\t}\n\n\t\tif (_debugInfoSelection.snippet)\n\t\t{\n\t\t\tif (_debugInfoSelection.location)\n\t\t\t\tm_out << \"  \";\n\n\t\t\tm_out << locationFromSources(m_sourceCodes, m_location);\n\t\t}\n\n\t\tm_out << \" */\" << std::endl;\n\t}\n\nprivate:\n\tstrings m_pending;\n\tSourceLocation m_location;\n\n\tstd::ostream& m_out;\n\tstd::string const& m_prefix;\n\tStringMap const& m_sourceCodes;\n\tAssembly const& m_assembly;\n};\n\n}\n\nvoid Assembly::assemblyStream(\n\tstd::ostream& _out,\n\tDebugInfoSelection const& _debugInfoSelection,\n\tstd::string const& _prefix,\n\tStringMap const& _sourceCodes\n) const\n{\n\tFunctionalizer f(_out, _prefix, _sourceCodes, *this);\n\n\tfor (auto const& i: m_codeSections.front().items)\n\t\tf.feed(i, _debugInfoSelection);\n\tf.flush();\n\n\tfor (size_t i = 1; i < m_codeSections.size(); ++i)\n\t{\n\t\t_out << std::endl << _prefix << \"code_section_\" << i << \": assembly {\\n\";\n\t\tFunctionalizer codeSectionF(_out, _prefix + \"    \", _sourceCodes, *this);\n\t\tfor (auto const& item: m_codeSections[i].items)\n\t\t\tcodeSectionF.feed(item, _debugInfoSelection);\n\t\tcodeSectionF.flush();\n\t\t_out << _prefix << \"}\" << std::endl;\n\t}\n\n\tif (!m_data.empty() || !m_subs.empty())\n\t{\n\t\t_out << _prefix << \"stop\" << std::endl;\n\t\tfor (auto const& i: m_data)\n\t\t\tif (u256(i.first) >= m_subs.size())\n\t\t\t\t_out << _prefix << \"data_\" << toHex(u256(i.first)) << \" \" << util::toHex(i.second) << std::endl;\n\n\t\tfor (size_t i = 0; i < m_subs.size(); ++i)\n\t\t{\n\t\t\t_out << std::endl << _prefix << \"sub_\" << i << \": assembly {\\n\";\n\t\t\tm_subs[i]->assemblyStream(_out, _debugInfoSelection, _prefix + \"    \", _sourceCodes);\n\t\t\t_out << _prefix << \"}\" << std::endl;\n\t\t}\n\t}\n\n\tif (m_auxiliaryData.size() > 0)\n\t\t_out << std::endl << _prefix << \"auxdata: 0x\" << util::toHex(m_auxiliaryData) << std::endl;\n}\n\nstd::string Assembly::assemblyString(\n\tDebugInfoSelection const& _debugInfoSelection,\n\tStringMap const& _sourceCodes\n) const\n{\n\tstd::ostringstream tmp;\n\tassemblyStream(tmp, _debugInfoSelection, \"\", _sourceCodes);\n\treturn (_debugInfoSelection.ethdebug ? \"/// ethdebug: enabled\\n\" : \"\") + tmp.str();\n}\n\nJson Assembly::assemblyJSON(std::map<std::string, unsigned> const& _sourceIndices, bool _includeSourceList) const\n{\n\tJson root;\n\troot[\".code\"] = Json::array();\n\tJson& code = root[\".code\"];\n\t// TODO: support EOF\n\tsolUnimplementedAssert(!m_eofVersion.has_value(), \"Assembly output for EOF is not yet implemented.\");\n\tsolAssert(m_codeSections.size() == 1);\n\tfor (AssemblyItem const& item: m_codeSections.front().items)\n\t{\n\t\tint sourceIndex = -1;\n\t\tif (item.location().sourceName)\n\t\t{\n\t\t\tauto iter = _sourceIndices.find(*item.location().sourceName);\n\t\t\tif (iter != _sourceIndices.end())\n\t\t\t\tsourceIndex = static_cast<int>(iter->second);\n\t\t}\n\n\t\tauto [name, data] = item.nameAndData(m_evmVersion);\n\t\tJson jsonItem;\n\t\tjsonItem[\"name\"] = name;\n\t\tjsonItem[\"begin\"] = item.location().start;\n\t\tjsonItem[\"end\"] = item.location().end;\n\t\tif (item.m_modifierDepth != 0)\n\t\t\tjsonItem[\"modifierDepth\"] = static_cast<int>(item.m_modifierDepth);\n\t\tstd::string jumpType = item.getJumpTypeAsString();\n\t\tif (!jumpType.empty())\n\t\t\tjsonItem[\"jumpType\"] = jumpType;\n\t\tif (name == \"PUSHLIB\")\n\t\t\tdata = m_libraries.at(h256(data));\n\t\telse if (name == \"PUSHIMMUTABLE\" || name == \"ASSIGNIMMUTABLE\")\n\t\t\tdata = m_immutables.at(h256(data));\n\t\tif (!data.empty())\n\t\t\tjsonItem[\"value\"] = data;\n\t\tjsonItem[\"source\"] = sourceIndex;\n\t\tcode.emplace_back(std::move(jsonItem));\n\n\t\tif (item.type() == AssemblyItemType::Tag)\n\t\t{\n\t\t\tJson jumpdest;\n\t\t\tjumpdest[\"name\"] = \"JUMPDEST\";\n\t\t\tjumpdest[\"begin\"] = item.location().start;\n\t\t\tjumpdest[\"end\"] = item.location().end;\n\t\t\tjumpdest[\"source\"] = sourceIndex;\n\t\t\tif (item.m_modifierDepth != 0)\n\t\t\t\tjumpdest[\"modifierDepth\"] = static_cast<int>(item.m_modifierDepth);\n\t\t\tcode.emplace_back(std::move(jumpdest));\n\t\t}\n\t}\n\tif (_includeSourceList)\n\t{\n\t\troot[\"sourceList\"] = Json::array();\n\t\tJson& jsonSourceList = root[\"sourceList\"];\n\t\tunsigned maxSourceIndex = 0;\n\t\tfor (auto const& [sourceName, sourceIndex]: _sourceIndices)\n\t\t{\n\t\t\tmaxSourceIndex = std::max(sourceIndex, maxSourceIndex);\n\t\t\tjsonSourceList[sourceIndex] = sourceName;\n\t\t}\n\t\tsolAssert(maxSourceIndex + 1 >= _sourceIndices.size());\n\t\tsolRequire(\n\t\t\t_sourceIndices.size() == 0 || _sourceIndices.size() == maxSourceIndex + 1,\n\t\t\tAssemblyImportException,\n\t\t\t\"The 'sourceList' array contains invalid 'null' item.\"\n\t\t);\n\t}\n\n\tif (!m_data.empty() || !m_subs.empty())\n\t{\n\t\troot[\".data\"] = Json::object();\n\t\tJson& data = root[\".data\"];\n\t\tfor (auto const& i: m_data)\n\t\t\tif (u256(i.first) >= m_subs.size())\n\t\t\t\tdata[util::toHex(toBigEndian((u256)i.first), util::HexPrefix::DontAdd, util::HexCase::Upper)] = util::toHex(i.second);\n\n\t\tfor (size_t i = 0; i < m_subs.size(); ++i)\n\t\t{\n\t\t\tstd::stringstream hexStr;\n\t\t\thexStr << std::hex << i;\n\t\t\tdata[hexStr.str()] = m_subs[i]->assemblyJSON(_sourceIndices, /*_includeSourceList = */false);\n\t\t}\n\t}\n\n\tif (!m_auxiliaryData.empty())\n\t\troot[\".auxdata\"] = util::toHex(m_auxiliaryData);\n\n\treturn root;\n}\n\nstd::pair<std::shared_ptr<Assembly>, std::vector<std::string>> Assembly::fromJSON(\n\tJson const& _json,\n\tstd::vector<std::string> const& _sourceList,\n\tsize_t _level,\n\tstd::optional<uint8_t> _eofVersion\n)\n{\n\tsolRequire(_json.is_object(), AssemblyImportException, \"Supplied JSON is not an object.\");\n\tstatic std::set<std::string> const validMembers{\".code\", \".data\", \".auxdata\", \"sourceList\"};\n\tfor (auto const& [attribute, _]: _json.items())\n\t\tsolRequire(validMembers.count(attribute), AssemblyImportException, \"Unknown attribute '\" + attribute + \"'.\");\n\n\tif (_level == 0)\n\t{\n\t\tif (_json.contains(\"sourceList\"))\n\t\t{\n\t\t\tsolRequire(_json[\"sourceList\"].is_array(), AssemblyImportException, \"Optional member 'sourceList' is not an array.\");\n\t\t\tfor (Json const& sourceName: _json[\"sourceList\"])\n\t\t\t{\n\t\t\t\tsolRequire(!sourceName.is_null(), AssemblyImportException, \"The 'sourceList' array contains invalid 'null' item.\");\n\t\t\t\tsolRequire(\n\t\t\t\t\tsourceName.is_string(),\n\t\t\t\t\tAssemblyImportException,\n\t\t\t\t\t\"The 'sourceList' array contains an item that is not a string.\"\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t\tsolRequire(\n\t\t\t!_json.contains(\"sourceList\"),\n\t\t\tAssemblyImportException,\n\t\t\t\"Member 'sourceList' may only be present in the root JSON object.\"\n\t\t);\n\n\tauto result = std::make_shared<Assembly>(EVMVersion{}, _level == 0 /* _creation */, _eofVersion, \"\" /* _name */);\n\tstd::vector<std::string> parsedSourceList;\n\tif (_json.contains(\"sourceList\"))\n\t{\n\t\tsolAssert(_level == 0);\n\t\tsolAssert(_sourceList.empty());\n\t\tfor (Json const& sourceName: _json[\"sourceList\"])\n\t\t{\n\t\t\tsolRequire(\n\t\t\t\tstd::find(parsedSourceList.begin(), parsedSourceList.end(), sourceName.get<std::string>()) == parsedSourceList.end(),\n\t\t\t\tAssemblyImportException,\n\t\t\t\t\"Items in 'sourceList' array are not unique.\"\n\t\t\t);\n\t\t\tparsedSourceList.emplace_back(sourceName.get<std::string>());\n\t\t}\n\t}\n\n\tsolRequire(_json.contains(\".code\"), AssemblyImportException, \"Member '.code' is missing.\");\n\tsolRequire(_json[\".code\"].is_array(), AssemblyImportException, \"Member '.code' is not an array.\");\n\tfor (Json const& codeItem: _json[\".code\"])\n\t\tsolRequire(codeItem.is_object(), AssemblyImportException, \"The '.code' array contains an item that is not an object.\");\n\n\tresult->importAssemblyItemsFromJSON(_json[\".code\"], _level == 0 ? parsedSourceList : _sourceList);\n\n\tif (_json.contains(\".auxdata\"))\n\t{\n\t\tsolRequire(_json[\".auxdata\"].is_string(), AssemblyImportException, \"Optional member '.auxdata' is not a string.\");\n\t\tresult->m_auxiliaryData = fromHex(_json[\".auxdata\"].get<std::string>());\n\t\tsolRequire(!result->m_auxiliaryData.empty(), AssemblyImportException, \"Optional member '.auxdata' is not a valid hexadecimal string.\");\n\t}\n\n\tif (_json.contains(\".data\"))\n\t{\n\t\tsolRequire(_json[\".data\"].is_object(), AssemblyImportException, \"Optional member '.data' is not an object.\");\n\t\tJson const& data = _json[\".data\"];\n\t\tstd::map<size_t, std::shared_ptr<Assembly>> subAssemblies;\n\t\tfor (auto const& [key, value] : data.items())\n\t\t{\n\t\t\tif (value.is_string())\n\t\t\t{\n\t\t\t\tsolRequire(\n\t\t\t\t\tvalue.get<std::string>().empty() || !fromHex(value.get<std::string>()).empty(),\n\t\t\t\t\tAssemblyImportException,\n\t\t\t\t\t\"The value for key '\" + key + \"' inside '.data' is not a valid hexadecimal string.\"\n\t\t\t\t);\n\t\t\t\tresult->m_data[h256(fromHex(key))] = fromHex(value.get<std::string>());\n\t\t\t}\n\t\t\telse if (value.is_object())\n\t\t\t{\n\t\t\t\tsize_t index{};\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\t// Using signed variant because stoul() still accepts negative numbers and\n\t\t\t\t\t// just lets them wrap around.\n\t\t\t\t\tint parsedDataItemID = std::stoi(key, nullptr, 16);\n\t\t\t\t\tsolRequire(parsedDataItemID >= 0, AssemblyImportException, \"The key '\" + key + \"' inside '.data' is out of the supported integer range.\");\n\t\t\t\t\tindex = static_cast<size_t>(parsedDataItemID);\n\t\t\t\t}\n\t\t\t\tcatch (std::invalid_argument const&)\n\t\t\t\t{\n\t\t\t\t\tsolThrow(AssemblyImportException, \"The key '\" + key + \"' inside '.data' is not an integer.\");\n\t\t\t\t}\n\t\t\t\tcatch (std::out_of_range const&)\n\t\t\t\t{\n\t\t\t\t\tsolThrow(AssemblyImportException, \"The key '\" + key + \"' inside '.data' is out of the supported integer range.\");\n\t\t\t\t}\n\n\t\t\t\tauto [subAssembly, emptySourceList] = Assembly::fromJSON(value, _level == 0 ? parsedSourceList : _sourceList, _level + 1, _eofVersion);\n\t\t\t\tsolAssert(subAssembly);\n\t\t\t\tsolAssert(emptySourceList.empty());\n\t\t\t\tsolAssert(subAssemblies.count(index) == 0);\n\t\t\t\tsubAssemblies[index] = subAssembly;\n\t\t\t}\n\t\t\telse\n\t\t\t\tsolThrow(AssemblyImportException, \"The value of key '\" + key + \"' inside '.data' is neither a hex string nor an object.\");\n\t\t}\n\n\t\tif (!subAssemblies.empty())\n\t\t\tsolRequire(\n\t\t\t\tranges::max(subAssemblies | ranges::views::keys) == subAssemblies.size() - 1,\n\t\t\t\tAssemblyImportException,\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"Invalid subassembly indices in '.data'. Not all numbers between 0 and {} are present.\",\n\t\t\t\t\tsubAssemblies.size() - 1\n\t\t\t\t)\n\t\t\t);\n\n\t\tresult->m_subs = subAssemblies | ranges::views::values | ranges::to<std::vector>;\n\t}\n\n\tif (_level == 0)\n\t\tresult->encodeAllPossibleSubPathsInAssemblyTree();\n\n\treturn std::make_pair(result, _level == 0 ? parsedSourceList : std::vector<std::string>{});\n}\n\nvoid Assembly::encodeAllPossibleSubPathsInAssemblyTree(std::vector<SubAssemblyID> _pathFromRoot, std::vector<Assembly*> _assembliesOnPath)\n{\n\t_assembliesOnPath.push_back(this);\n\tfor (_pathFromRoot.push_back(SubAssemblyID{0}); _pathFromRoot.back().value < m_subs.size(); ++_pathFromRoot.back().value)\n\t{\n\t\tfor (size_t distanceFromRoot = 0; distanceFromRoot < _assembliesOnPath.size(); ++distanceFromRoot)\n\t\t\t_assembliesOnPath[distanceFromRoot]->encodeSubPath(\n\t\t\t\t_pathFromRoot | ranges::views::drop_exactly(distanceFromRoot) | ranges::to<std::vector>\n\t\t\t);\n\n\t\tm_subs[_pathFromRoot.back().asIndex()]->encodeAllPossibleSubPathsInAssemblyTree(_pathFromRoot, _assembliesOnPath);\n\t}\n}\n\nstd::shared_ptr<std::string const> Assembly::sharedSourceName(std::string const& _name) const\n{\n\tif (s_sharedSourceNames.find(_name) == s_sharedSourceNames.end())\n\t\ts_sharedSourceNames[_name] = std::make_shared<std::string>(_name);\n\n\treturn s_sharedSourceNames[_name];\n}\n\nAssemblyItem Assembly::namedTag(std::string const& _name, size_t _params, size_t _returns, std::optional<uint64_t> _sourceID)\n{\n\tassertThrow(!_name.empty(), AssemblyException, \"Empty named tag.\");\n\tif (m_namedTags.count(_name))\n\t{\n\t\tassertThrow(m_namedTags.at(_name).params == _params, AssemblyException, \"\");\n\t\tassertThrow(m_namedTags.at(_name).returns == _returns, AssemblyException, \"\");\n\t\tassertThrow(m_namedTags.at(_name).sourceID == _sourceID, AssemblyException, \"\");\n\t}\n\telse\n\t\tm_namedTags[_name] = {static_cast<size_t>(newTag().data()), _sourceID, _params, _returns};\n\treturn AssemblyItem{Tag, m_namedTags.at(_name).id};\n}\n\nAssemblyItem Assembly::newFunctionCall(uint16_t _functionID) const\n{\n\tsolAssert(_functionID < m_codeSections.size(), \"Call to undeclared function.\");\n\tsolAssert(_functionID > 0, \"Cannot call section 0\");\n\tauto const& section = m_codeSections.at(_functionID);\n\tif (section.nonReturning)\n\t\treturn AssemblyItem::jumpToFunction(_functionID, section.inputs, section.outputs);\n\telse\n\t\treturn AssemblyItem::functionCall(_functionID, section.inputs, section.outputs);\n}\n\nAssemblyItem Assembly::newFunctionReturn() const\n{\n\tsolAssert(m_currentCodeSection != 0, \"Appending function return without begin function.\");\n\treturn AssemblyItem::functionReturn();\n}\n\nuint16_t Assembly::createFunction(uint8_t _args, uint8_t _rets, bool _nonReturning)\n{\n\tsize_t functionID = m_codeSections.size();\n\tsolRequire(functionID < 1024, AssemblyException, \"Too many functions for EOF\");\n\tsolAssert(m_currentCodeSection == 0, \"Functions need to be declared from the main block.\");\n\tsolRequire(_rets <= 127, AssemblyException, \"Too many function returns.\");\n\tsolRequire(_args <= 127, AssemblyException, \"Too many function inputs.\");\n\tm_codeSections.emplace_back(CodeSection{_args, _rets, _nonReturning, {}});\n\treturn static_cast<uint16_t>(functionID);\n}\n\nvoid Assembly::beginFunction(uint16_t _functionID)\n{\n\tsolAssert(m_currentCodeSection == 0, \"Attempted to begin a function before ending the last one.\");\n\tsolAssert(_functionID != 0, \"Attempt to begin a function with id 0\");\n\tsolAssert(_functionID < m_codeSections.size(), \"Attempt to begin an undeclared function.\");\n\tauto& section = m_codeSections.at(_functionID);\n\tsolAssert(section.items.empty(), \"Function already defined.\");\n\tm_currentCodeSection = _functionID;\n}\nvoid Assembly::endFunction()\n{\n\tsolAssert(m_currentCodeSection != 0, \"End function without begin function.\");\n\tm_currentCodeSection = 0;\n}\n\nAssemblyItem Assembly::newPushLibraryAddress(std::string const& _identifier)\n{\n\th256 h(util::keccak256(_identifier));\n\tm_libraries[h] = _identifier;\n\treturn AssemblyItem{PushLibraryAddress, h};\n}\n\nAssemblyItem Assembly::newPushImmutable(std::string const& _identifier)\n{\n\th256 h(util::keccak256(_identifier));\n\tm_immutables[h] = _identifier;\n\treturn AssemblyItem{PushImmutable, h};\n}\n\nAssemblyItem Assembly::newImmutableAssignment(std::string const& _identifier)\n{\n\th256 h(util::keccak256(_identifier));\n\tm_immutables[h] = _identifier;\n\treturn AssemblyItem{AssignImmutable, h};\n}\n\nAssemblyItem Assembly::newAuxDataLoadN(size_t _offset) const\n{\n\treturn AssemblyItem{AuxDataLoadN, _offset};\n}\n\nAssemblyItem Assembly::newSwapN(size_t _depth) const\n{\n\treturn AssemblyItem::swapN(_depth);\n}\n\nAssemblyItem Assembly::newDupN(size_t _depth) const\n{\n\treturn AssemblyItem::dupN(_depth);\n}\n\nAssembly& Assembly::optimise(OptimiserSettings const& _settings)\n{\n\toptimiseInternal(_settings, {});\n\treturn *this;\n}\n\nstd::map<u256, u256> const& Assembly::optimiseInternal(\n\tOptimiserSettings const& _settings,\n\tstd::set<size_t> _tagsReferencedFromOutside\n)\n{\n\tif (m_tagReplacements)\n\t\treturn *m_tagReplacements;\n\n\t// Run optimisation for sub-assemblies.\n\t// TODO: verify and double-check this for EOF.\n\tfor (SubAssemblyID subID{0}; subID.value < m_subs.size(); ++subID.value)\n\t{\n\t\tOptimiserSettings settings = _settings;\n\t\tAssembly& sub = *m_subs[subID.asIndex()];\n\t\tstd::set<size_t> referencedTags;\n\t\tfor (auto& codeSection: m_codeSections)\n\t\t\treferencedTags += JumpdestRemover::referencedTags(codeSection.items, subID);\n\t\tstd::map<u256, u256> const& subTagReplacements = sub.optimiseInternal(\n\t\t\tsettings,\n\t\t\treferencedTags\n\t\t);\n\t\t// Apply the replacements (can be empty).\n\t\tfor (auto& codeSection: m_codeSections)\n\t\t\tBlockDeduplicator::applyTagReplacement(codeSection.items, subTagReplacements, subID);\n\t}\n\n\tstd::map<u256, u256> tagReplacements;\n\t// Iterate until no new optimisation possibilities are found.\n\tfor (unsigned count = 1; count > 0;)\n\t{\n\t\tcount = 0;\n\n\t\t// TODO: verify this for EOF.\n\t\tif (_settings.runInliner && !m_eofVersion.has_value())\n\t\t{\n\t\t\tsolAssert(m_codeSections.size() == 1);\n\t\t\tInliner{\n\t\t\t\tm_codeSections.front().items,\n\t\t\t\t_tagsReferencedFromOutside,\n\t\t\t\t_settings.expectedExecutionsPerDeployment,\n\t\t\t\tisCreation(),\n\t\t\t\tm_evmVersion\n\t\t\t}.optimise();\n\t\t}\n\t\t// TODO: verify this for EOF.\n\t\tif (_settings.runJumpdestRemover && !m_eofVersion.has_value())\n\t\t{\n\t\t\tfor (auto& codeSection: m_codeSections)\n\t\t\t{\n\t\t\t\tJumpdestRemover jumpdestOpt{codeSection.items};\n\t\t\t\tif (jumpdestOpt.optimise(_tagsReferencedFromOutside))\n\t\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\n\t\tif (_settings.runPeephole)\n\t\t{\n\t\t\tfor (auto& codeSection: m_codeSections)\n\t\t\t{\n\t\t\t\tPeepholeOptimiser peepOpt{codeSection.items, m_evmVersion};\n\t\t\t\twhile (peepOpt.optimise())\n\t\t\t\t{\n\t\t\t\t\tcount++;\n\t\t\t\t\tassertThrow(count < 64000, OptimizerException, \"Peephole optimizer seems to be stuck.\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// This only modifies PushTags, we have to run again to actually remove code.\n\t\t// TODO: implement for EOF.\n\t\tif (_settings.runDeduplicate && !m_eofVersion.has_value())\n\t\t\tfor (auto& section: m_codeSections)\n\t\t\t{\n\t\t\t\tBlockDeduplicator deduplicator{section.items};\n\t\t\t\tif (deduplicator.deduplicate())\n\t\t\t\t{\n\t\t\t\t\tfor (auto const& replacement: deduplicator.replacedTags())\n\t\t\t\t\t{\n\t\t\t\t\t\tassertThrow(\n\t\t\t\t\t\t\treplacement.first <= std::numeric_limits<size_t>::max() && replacement.second <= std::numeric_limits<size_t>::max(),\n\t\t\t\t\t\t\tOptimizerException,\n\t\t\t\t\t\t\t\"Invalid tag replacement.\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\tassertThrow(\n\t\t\t\t\t\t\t!tagReplacements.count(replacement.first),\n\t\t\t\t\t\t\tOptimizerException,\n\t\t\t\t\t\t\t\"Replacement already known.\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\ttagReplacements[replacement.first] = replacement.second;\n\t\t\t\t\t\tif (_tagsReferencedFromOutside.erase(static_cast<size_t>(replacement.first)))\n\t\t\t\t\t\t\t_tagsReferencedFromOutside.insert(static_cast<size_t>(replacement.second));\n\t\t\t\t\t}\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t// TODO: investigate for EOF\n\t\tif (_settings.runCSE && !m_eofVersion.has_value())\n\t\t{\n\t\t\t// Control flow graph optimization has been here before but is disabled because it\n\t\t\t// assumes we only jump to tags that are pushed. This is not the case anymore with\n\t\t\t// function types that can be stored in storage.\n\t\t\tAssemblyItems optimisedItems;\n\n\t\t\tsolAssert(m_codeSections.size() == 1);\n\t\t\tauto& items = m_codeSections.front().items;\n\t\t\tbool usesMSize = ranges::any_of(items, [](AssemblyItem const& _i) {\n\t\t\t\treturn _i == AssemblyItem{Instruction::MSIZE} || _i.type() == VerbatimBytecode;\n\t\t\t});\n\n\t\t\tauto iter = items.begin();\n\t\t\twhile (iter != items.end())\n\t\t\t{\n\t\t\t\tKnownState emptyState;\n\t\t\t\tCommonSubexpressionEliminator eliminator{emptyState, m_evmVersion};\n\t\t\t\tauto orig = iter;\n\t\t\t\titer = eliminator.feedItems(iter, items.end(), usesMSize);\n\t\t\t\tbool shouldReplace = false;\n\t\t\t\tAssemblyItems optimisedChunk;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\toptimisedChunk = eliminator.getOptimizedItems();\n\t\t\t\t\tshouldReplace = (optimisedChunk.size() < static_cast<size_t>(iter - orig));\n\t\t\t\t}\n\t\t\t\tcatch (StackTooDeepException const&)\n\t\t\t\t{\n\t\t\t\t\t// This might happen if the opcode reconstruction is not as efficient\n\t\t\t\t\t// as the hand-crafted code.\n\t\t\t\t}\n\t\t\t\tcatch (ItemNotAvailableException const&)\n\t\t\t\t{\n\t\t\t\t\t// This might happen if e.g. associativity and commutativity rules\n\t\t\t\t\t// reorganise the expression tree, but not all leaves are available.\n\t\t\t\t}\n\n\t\t\t\tif (shouldReplace)\n\t\t\t\t{\n\t\t\t\t\tcount++;\n\t\t\t\t\toptimisedItems += optimisedChunk;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tcopy(orig, iter, back_inserter(optimisedItems));\n\t\t\t}\n\t\t\tif (optimisedItems.size() < items.size())\n\t\t\t{\n\t\t\t\titems = std::move(optimisedItems);\n\t\t\t\tcount++;\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: investigate for EOF\n\tif (_settings.runConstantOptimiser && !m_eofVersion.has_value())\n\t\tConstantOptimisationMethod::optimiseConstants(\n\t\t\tisCreation(),\n\t\t\tisCreation() ? 1 : _settings.expectedExecutionsPerDeployment,\n\t\t\tm_evmVersion,\n\t\t\t*this\n\t\t);\n\n\tm_tagReplacements = std::move(tagReplacements);\n\treturn *m_tagReplacements;\n}\n\nnamespace\n{\ntemplate<typename ValueT>\nvoid setBigEndian(bytes& _dest, size_t _offset, size_t _size, ValueT _value)\n{\n\tassertThrow(numberEncodingSize(_value) <= _size, AssemblyException, \"\");\n\ttoBigEndian(_value, bytesRef(_dest.data() + _offset, _size));\n}\n\ntemplate<typename ValueT>\nvoid appendBigEndian(bytes& _dest, size_t _size, ValueT _value)\n{\n\t_dest.resize(_dest.size() + _size);\n\tsetBigEndian(_dest, _dest.size() - _size, _size, _value);\n}\n\ntemplate<typename ValueT>\nvoid setBigEndianUint16(bytes& _dest, size_t _offset, ValueT _value)\n{\n\tsetBigEndian(_dest, _offset, 2, _value);\n}\n\ntemplate<typename ValueT>\nvoid appendBigEndianUint16(bytes& _dest, ValueT _value)\n{\n\tstatic_assert(!std::numeric_limits<ValueT>::is_signed, \"only unsigned types or bigint supported\");\n\tassertThrow(_value <= 0xFFFF, AssemblyException, \"\");\n\tappendBigEndian(_dest, 2, static_cast<size_t>(_value));\n}\n\n// Calculates maximum stack height for given code section. According to EIP5450 https://eips.ethereum.org/EIPS/eip-5450\nuint16_t calculateMaxStackHeight(Assembly::CodeSection const& _section)\n{\n\tstatic auto constexpr UNVISITED = std::numeric_limits<size_t>::max();\n\n\tAssemblyItems const& items = _section.items;\n\tsolAssert(!items.empty());\n\tuint16_t overallMaxHeight = _section.inputs;\n\tstd::stack<size_t> worklist;\n\tstd::vector<size_t> maxStackHeights(items.size(), UNVISITED);\n\n\t// Init first item stack height to number of inputs to the code section\n\t// maxStackHeights stores stack height for an item before the item execution\n\tmaxStackHeights[0] = _section.inputs;\n\t// Push first item index to the worklist\n\tworklist.push(0u);\n\twhile (!worklist.empty())\n\t{\n\t\tsize_t idx = worklist.top();\n\t\tworklist.pop();\n\t\tAssemblyItem const& item = items[idx];\n\t\tsize_t stackHeightChange = item.deposit();\n\t\tsize_t currentMaxHeight = maxStackHeights[idx];\n\t\tsolAssert(currentMaxHeight != UNVISITED);\n\n\t\tstd::vector<size_t> successors;\n\n\t\t// Add next instruction to successors for non-control-flow-changing instructions\n\t\tif (\n\t\t\t!(item.hasInstruction() && SemanticInformation::terminatesControlFlow(item.instruction())) &&\n\t\t\titem.type() != RelativeJump &&\n\t\t\titem.type() != RetF &&\n\t\t\titem.type() != JumpF\n\t\t)\n\t\t{\n\t\t\tsolAssert(idx < items.size() - 1, \"No terminating instruction.\");\n\t\t\tsuccessors.emplace_back(idx + 1);\n\t\t}\n\n\t\t// Add jumps destinations to successors\n\t\t// TODO: Remember to add RJUMPV when it is supported.\n\t\tif (item.type() == RelativeJump || item.type() == ConditionalRelativeJump)\n\t\t{\n\t\t\tauto const tagIt = std::find(items.begin(), items.end(), item.tag());\n\t\t\tsolAssert(tagIt != items.end(), \"Tag not found.\");\n\t\t\tsuccessors.emplace_back(static_cast<size_t>(std::distance(items.begin(), tagIt)));\n\t\t\t// TODO: This assert fails until the code is not topologically sorted. Uncomment when sorting introduced.\n\t\t\t// If backward jump the successor must be already visited.\n\t\t\t// solAssert(idx <= successors.back() || maxStackHeights[successors.back()] != UNVISITED);\n\t\t}\n\n\t\tsolRequire(\n\t\t\tcurrentMaxHeight + stackHeightChange <= std::numeric_limits<uint16_t>::max(),\n\t\t\tAssemblyException,\n\t\t\t\"Stack overflow in EOF function.\"\n\t\t);\n\t\toverallMaxHeight = std::max(overallMaxHeight, static_cast<uint16_t>(currentMaxHeight + stackHeightChange));\n\t\tcurrentMaxHeight += stackHeightChange;\n\n\t\t// Set stack height for all instruction successors\n\t\tfor (size_t successor: successors)\n\t\t{\n\t\t\tsolAssert(successor < maxStackHeights.size());\n\t\t\t// Set stack height for newly visited\n\t\t\tif (maxStackHeights[successor] == UNVISITED)\n\t\t\t{\n\t\t\t\tmaxStackHeights[successor] = currentMaxHeight;\n\t\t\t\tworklist.push(successor);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsolAssert(successor < maxStackHeights.size());\n\t\t\t\t// For backward jump successor stack height must be equal\n\t\t\t\tif (successor < idx)\n\t\t\t\t\tsolAssert(maxStackHeights[successor] == currentMaxHeight, \"Stack height mismatch.\");\n\n\t\t\t\t// If successor stack height is smaller update it and recalculate\n\t\t\t\tif (currentMaxHeight > maxStackHeights[successor])\n\t\t\t\t{\n\t\t\t\t\tmaxStackHeights[successor] = currentMaxHeight;\n\t\t\t\t\tworklist.push(successor);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn overallMaxHeight;\n}\n}\n\nstd::tuple<bytes, std::vector<size_t>, size_t> Assembly::createEOFHeader(std::set<ContainerID> const& _referencedSubIds) const\n{\n\tbytes retBytecode;\n\tstd::vector<size_t> codeSectionSizePositions;\n\tsize_t dataSectionSizePosition;\n\n\tretBytecode.push_back(0xef);\n\tretBytecode.push_back(0x00);\n\tretBytecode.push_back(0x01);                                        // version 1\n\n\tretBytecode.push_back(0x01);                                        // kind=type\n\tappendBigEndianUint16(retBytecode, m_codeSections.size() * 4u);     // length of type section\n\n\tretBytecode.push_back(0x02);                                        // kind=code\n\tappendBigEndianUint16(retBytecode, m_codeSections.size());          // placeholder for number of code sections\n\n\tfor (auto const& codeSection: m_codeSections)\n\t{\n\t\t(void) codeSection;\n\t\tcodeSectionSizePositions.emplace_back(retBytecode.size());\n\t\tappendBigEndianUint16(retBytecode, 0u);                         // placeholder for length of code\n\t}\n\n\tif (!_referencedSubIds.empty())\n\t{\n\t\tretBytecode.push_back(0x03);\n\t\tappendBigEndianUint16(retBytecode, _referencedSubIds.size());\n\n\t\tfor (auto subId: _referencedSubIds)\n\t\t\tappendBigEndianUint16(retBytecode, m_subs[subId]->assemble().bytecode.size());\n\t}\n\n\tretBytecode.push_back(0x04);                                        // kind=data\n\tdataSectionSizePosition = retBytecode.size();\n\tappendBigEndianUint16(retBytecode, 0u);                             // length of data\n\n\tretBytecode.push_back(0x00);                                        // terminator\n\n\tfor (auto const& codeSection: m_codeSections)\n\t{\n\t\tretBytecode.push_back(codeSection.inputs);\n\t\t// According to EOF spec function output num equals 0x80 means non-returning function\n\t\tretBytecode.push_back(codeSection.nonReturning ? 0x80 : codeSection.outputs);\n\t\tappendBigEndianUint16(retBytecode, calculateMaxStackHeight(codeSection));\n\t}\n\n\treturn {retBytecode, codeSectionSizePositions, dataSectionSizePosition};\n}\n\nLinkerObject const& Assembly::assemble() const\n{\n\tsolRequire(!m_invalid, AssemblyException, \"Attempted to assemble invalid Assembly object.\");\n\t// Return the already assembled object, if present.\n\tif (!m_assembledObject.bytecode.empty())\n\t\treturn m_assembledObject;\n\n\t// Otherwise ensure the object is actually clear.\n\tsolRequire(m_assembledObject.linkReferences.empty(), AssemblyException, \"Unexpected link references.\");\n\n\tbool const eof = m_eofVersion.has_value();\n\tsolRequire(!eof || m_eofVersion == 1, AssemblyException, \"Invalid EOF version.\");\n\n\tif (!eof)\n\t\treturn assembleLegacy();\n\telse\n\t\treturn assembleEOF();\n}\n\n[[nodiscard]] bytes Assembly::assembleOperation(AssemblyItem const& _item) const\n{\n\t// solidity::evmasm::Instructions underlying type is uint8_t\n\t// TODO: Change to std::to_underlying since C++23\n\treturn {static_cast<uint8_t>(_item.instruction())};\n}\n\n[[nodiscard]] bytes Assembly::assemblePush(AssemblyItem const& _item) const\n{\n\tbytes ret;\n\tunsigned pushValueSize = numberEncodingSize(_item.data());\n\tif (pushValueSize == 0 && !m_evmVersion.hasPush0())\n\t\tpushValueSize = 1;\n\n\t// solidity::evmasm::Instructions underlying type is uint8_t\n\t// TODO: Change to std::to_underlying since C++23\n\tret.push_back(static_cast<uint8_t>(pushInstruction(pushValueSize)));\n\tif (pushValueSize > 0)\n\t\tappendBigEndian(ret, pushValueSize, _item.data());\n\n\treturn ret;\n}\n\n[[nodiscard]] std::pair<bytes, Assembly::LinkRef> Assembly::assemblePushLibraryAddress(AssemblyItem const& _item, size_t _pos) const\n{\n\treturn {\n\t\t// solidity::evmasm::Instructions underlying type is uint8_t\n\t\t// TODO: Change to std::to_underlying since C++23\n\t\tbytes(1, static_cast<uint8_t>(Instruction::PUSH20)) + bytes(20),\n\t\t{_pos + 1, m_libraries.at(_item.data())}\n\t};\n}\n\n[[nodiscard]] bytes Assembly::assembleVerbatimBytecode(AssemblyItem const& item) const\n{\n\treturn item.verbatimData();\n}\n\n[[nodiscard]] bytes Assembly::assemblePushDeployTimeAddress() const\n{\n\t// solidity::evmasm::Instructions underlying type is uint8_t\n\t// TODO: Change to std::to_underlying since C++23\n\treturn bytes(1, static_cast<uint8_t>(Instruction::PUSH20)) + bytes(20);\n}\n\n[[nodiscard]] bytes Assembly::assembleTag(AssemblyItem const& _item, size_t _pos, bool _addJumpDest) const\n{\n\tsolRequire(_item.data() != 0, AssemblyException, \"Invalid tag position.\");\n\tsolRequire(_item.splitForeignPushTag().first.empty(), AssemblyException, \"Foreign tag.\");\n\tsolRequire(_pos < 0xffffffffL, AssemblyException, \"Tag too large.\");\n\tsize_t tagId = static_cast<size_t>(_item.data());\n\tsolRequire(m_tagPositionsInBytecode[tagId] == std::numeric_limits<size_t>::max(), AssemblyException, \"Duplicate tag position.\");\n\tm_tagPositionsInBytecode[tagId] = _pos;\n\n\t// solidity::evmasm::Instructions underlying type is uint8_t\n\t// TODO: Change to std::to_underlying since C++23\n\treturn _addJumpDest ? bytes(1, static_cast<uint8_t>(Instruction::JUMPDEST)) : bytes();\n}\n\nLinkerObject const& Assembly::assembleLegacy() const\n{\n\tsolAssert(!m_eofVersion.has_value());\n\tsolAssert(!m_invalid);\n\t// Return the already assembled object, if present.\n\tif (!m_assembledObject.bytecode.empty())\n\t\treturn m_assembledObject;\n\t// Otherwise ensure the object is actually clear.\n\tsolAssert(m_assembledObject.linkReferences.empty());\n\n\tLinkerObject& ret = m_assembledObject;\n\n\tsize_t subTagSize = 1;\n\tstd::map<u256, LinkerObject::ImmutableRefs> immutableReferencesBySub;\n\tfor (auto const& sub: m_subs)\n\t{\n\t\tauto const& linkerObject = sub->assemble();\n\t\tif (!linkerObject.immutableReferences.empty())\n\t\t{\n\t\t\tassertThrow(\n\t\t\t\timmutableReferencesBySub.empty(),\n\t\t\t\tAssemblyException,\n\t\t\t\t\"More than one sub-assembly references immutables.\"\n\t\t\t);\n\t\t\timmutableReferencesBySub = linkerObject.immutableReferences;\n\t\t}\n\t\tfor (size_t tagPos: sub->m_tagPositionsInBytecode)\n\t\t\tif (tagPos != std::numeric_limits<size_t>::max() && numberEncodingSize(tagPos) > subTagSize)\n\t\t\t\tsubTagSize = numberEncodingSize(tagPos);\n\t}\n\n\tbool setsImmutables = false;\n\tbool pushesImmutables = false;\n\n\tassertThrow(m_codeSections.size() == 1, AssemblyException, \"Expected exactly one code section in non-EOF code.\");\n\tAssemblyItems const& items = m_codeSections.front().items;\n\n\tfor (auto const& item: items)\n\t\tif (item.type() == AssignImmutable)\n\t\t{\n\t\t\titem.setImmutableOccurrences(immutableReferencesBySub[item.data()].second.size());\n\t\t\tsetsImmutables = true;\n\t\t}\n\t\telse if (item.type() == PushImmutable)\n\t\t\tpushesImmutables = true;\n\tif (setsImmutables || pushesImmutables)\n\t\tassertThrow(\n\t\t\tsetsImmutables != pushesImmutables,\n\t\t\tAssemblyException,\n\t\t\t\"Cannot push and assign immutables in the same assembly subroutine.\"\n\t\t);\n\n\tunsigned bytesRequiredForCode = codeSize(static_cast<unsigned>(subTagSize));\n\tm_tagPositionsInBytecode = std::vector<size_t>(m_usedTags, std::numeric_limits<size_t>::max());\n\tunsigned bytesPerTag = numberEncodingSize(bytesRequiredForCode);\n\t// Adjust bytesPerTag for references to sub assemblies.\n\tfor (AssemblyItem const& item: items)\n\t\tif (item.type() == PushTag)\n\t\t{\n\t\t\tauto [subId, tagId] = item.splitForeignPushTag();\n\t\t\tif (subId.empty())\n\t\t\t\tcontinue;\n\t\t\tsolAssert(subId.value < m_subs.size(), \"Invalid sub id\");\n\t\t\tauto subTagPosition = m_subs[subId.asIndex()]->m_tagPositionsInBytecode.at(tagId);\n\t\t\tassertThrow(subTagPosition != std::numeric_limits<size_t>::max(), AssemblyException, \"Reference to tag without position.\");\n\t\t\tbytesPerTag = std::max(bytesPerTag, numberEncodingSize(subTagPosition));\n\t\t}\n\n\tunsigned bytesRequiredIncludingData = bytesRequiredForCode + 1 + static_cast<unsigned>(m_auxiliaryData.size());\n\tfor (auto const& sub: m_subs)\n\t\tbytesRequiredIncludingData += static_cast<unsigned>(sub->assemble().bytecode.size());\n\n\tunsigned bytesPerDataRef = numberEncodingSize(bytesRequiredIncludingData);\n\tret.bytecode.reserve(bytesRequiredIncludingData);\n\n\tTagRefs tagRefs;\n\tDataRefs dataRefs;\n\tSubAssemblyRefs subRefs;\n\tProgramSizeRefs sizeRefs;\n\tuint8_t tagPush = static_cast<uint8_t>(pushInstruction(bytesPerTag));\n\tuint8_t dataRefPush = static_cast<uint8_t>(pushInstruction(bytesPerDataRef));\n\n\tLinkerObject::CodeSectionLocation codeSectionLocation;\n\tcodeSectionLocation.instructionLocations.reserve(items.size());\n\tcodeSectionLocation.start = 0;\n\tfor (auto const& [assemblyItemIndex, item]: items | ranges::views::enumerate)\n\t{\n\t\t// collect instruction locations via side effects\n\t\tInstructionLocationEmitter instructionLocationEmitter(codeSectionLocation.instructionLocations, ret.bytecode, assemblyItemIndex);\n\t\t// store position of the invalid jump destination\n\t\tif (item.type() != Tag && m_tagPositionsInBytecode[0] == std::numeric_limits<size_t>::max())\n\t\t\tm_tagPositionsInBytecode[0] = ret.bytecode.size();\n\n\t\tswitch (item.type())\n\t\t{\n\t\tcase Operation:\n\t\t\tret.bytecode += assembleOperation(item);\n\t\t\tbreak;\n\t\tcase Push:\n\t\t\tret.bytecode += assemblePush(item);\n\t\t\tbreak;\n\t\tcase PushTag:\n\t\t\tret.bytecode.push_back(tagPush);\n\t\t\ttagRefs[ret.bytecode.size()] = item.splitForeignPushTag();\n\t\t\tret.bytecode.resize(ret.bytecode.size() + bytesPerTag);\n\t\t\tbreak;\n\t\tcase PushData:\n\t\t\tret.bytecode.push_back(dataRefPush);\n\t\t\tdataRefs.insert(std::make_pair(h256(item.data()), ret.bytecode.size()));\n\t\t\tret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef);\n\t\t\tbreak;\n\t\tcase PushSub:\n\t\t\tsolAssert(item.data() <= std::numeric_limits<SubAssemblyID::ValueType>::max());\n\t\t\tret.bytecode.push_back(dataRefPush);\n\t\t\tsubRefs.emplace(SubAssemblyID{item.data()}, ret.bytecode.size());\n\t\t\tret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef);\n\t\t\tbreak;\n\t\tcase PushSubSize:\n\t\t{\n\t\t\tsolAssert(item.data() <= std::numeric_limits<SubAssemblyID::ValueType>::max());\n\t\t\tauto s = subAssemblyById(SubAssemblyID{item.data()})->assemble().bytecode.size();\n\t\t\titem.setPushedValue(u256(s));\n\t\t\tunsigned b = std::max<unsigned>(1, numberEncodingSize(s));\n\t\t\tret.bytecode.push_back(static_cast<uint8_t>(pushInstruction(b)));\n\t\t\tret.bytecode.resize(ret.bytecode.size() + b);\n\t\t\tbytesRef byr(&ret.bytecode.back() + 1 - b, b);\n\t\t\ttoBigEndian(s, byr);\n\t\t\tbreak;\n\t\t}\n\t\tcase PushProgramSize:\n\t\t\tret.bytecode.push_back(dataRefPush);\n\t\t\tsizeRefs.push_back(static_cast<unsigned>(ret.bytecode.size()));\n\t\t\tret.bytecode.resize(ret.bytecode.size() + bytesPerDataRef);\n\t\t\tbreak;\n\t\tcase PushLibraryAddress:\n\t\t{\n\t\t\tauto const [bytecode, linkRef] = assemblePushLibraryAddress(item, ret.bytecode.size());\n\t\t\tret.bytecode += bytecode;\n\t\t\tret.linkReferences.insert(linkRef);\n\t\t\tbreak;\n\t\t}\n\t\tcase PushImmutable:\n\t\t\tret.bytecode.push_back(static_cast<uint8_t>(Instruction::PUSH32));\n\t\t\t// Maps keccak back to the \"identifier\" std::string of that immutable.\n\t\t\tret.immutableReferences[item.data()].first = m_immutables.at(item.data());\n\t\t\t// Record the bytecode offset of the PUSH32 argument.\n\t\t\tret.immutableReferences[item.data()].second.emplace_back(ret.bytecode.size());\n\t\t\t// Advance bytecode by 32 bytes (default initialized).\n\t\t\tret.bytecode.resize(ret.bytecode.size() + 32);\n\t\t\tbreak;\n\t\tcase VerbatimBytecode:\n\t\t\tret.bytecode += assembleVerbatimBytecode(item);\n\t\t\tbreak;\n\t\tcase AssignImmutable:\n\t\t{\n\t\t\t// Expect 2 elements on stack (source, dest_base)\n\t\t\tauto const& offsets = immutableReferencesBySub[item.data()].second;\n\t\t\tfor (size_t i = 0; i < offsets.size(); ++i)\n\t\t\t{\n\t\t\t\tif (i != offsets.size() - 1)\n\t\t\t\t{\n\t\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(Instruction::DUP2));\n\t\t\t\t\t// This item type decomposes into multiple evm instructions, so we manually call emit()\n\t\t\t\t\tinstructionLocationEmitter.emit();\n\t\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(Instruction::DUP2));\n\t\t\t\t\tinstructionLocationEmitter.emit();\n\t\t\t\t}\n\t\t\t\t// TODO: should we make use of the constant optimizer methods for pushing the offsets?\n\t\t\t\tbytes offsetBytes = toCompactBigEndian(u256(offsets[i]));\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(pushInstruction(static_cast<unsigned>(offsetBytes.size()))));\n\t\t\t\tret.bytecode += offsetBytes;\n\t\t\t\tinstructionLocationEmitter.emit();\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(Instruction::ADD));\n\t\t\t\tinstructionLocationEmitter.emit();\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(Instruction::MSTORE));\n\t\t\t\t// No emit needed here, it's taken care of by the destructor of instructionLocationEmitter.\n\t\t\t}\n\t\t\tif (offsets.empty())\n\t\t\t{\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(Instruction::POP));\n\t\t\t\tinstructionLocationEmitter.emit();\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(Instruction::POP));\n\t\t\t\t// no emit needed here, it's taken care of by the destructor of instructionLocationEmitter\n\t\t\t}\n\t\t\timmutableReferencesBySub.erase(item.data());\n\t\t\tbreak;\n\t\t}\n\t\tcase PushDeployTimeAddress:\n\t\t\tret.bytecode += assemblePushDeployTimeAddress();\n\t\t\tbreak;\n\t\tcase Tag:\n\t\t\tret.bytecode += assembleTag(item, ret.bytecode.size(), true);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tsolAssert(false, \"Unexpected opcode while assembling.\");\n\t\t}\n\t}\n\n\tcodeSectionLocation.end = ret.bytecode.size();\n\n\tret.codeSectionLocations.emplace_back(std::move(codeSectionLocation));\n\n\tif (!immutableReferencesBySub.empty())\n\t\tthrow\n\t\t\tlangutil::Error(\n\t\t\t\t1284_error,\n\t\t\t\tlangutil::Error::Type::CodeGenerationError,\n\t\t\t\t\"Some immutables were read from but never assigned, possibly because of optimization.\"\n\t\t\t);\n\n\tif (!m_subs.empty() || !m_data.empty() || !m_auxiliaryData.empty())\n\t\t// Append an INVALID here to help tests find miscompilation.\n\t\tret.bytecode.push_back(static_cast<uint8_t>(Instruction::INVALID));\n\n\tstd::map<LinkerObject, size_t> subAssemblyOffsets;\n\tfor (auto const& [subIdPath, bytecodeOffset]: subRefs)\n\t{\n\t\tLinkerObject subObject = subAssemblyById(subIdPath)->assemble();\n\t\tbytesRef r(ret.bytecode.data() + bytecodeOffset, bytesPerDataRef);\n\n\t\t// In order for de-duplication to kick in, not only must the bytecode be identical, but\n\t\t// link and immutables references as well.\n\t\tif (size_t* subAssemblyOffset = util::valueOrNullptr(subAssemblyOffsets, subObject))\n\t\t\ttoBigEndian(*subAssemblyOffset, r);\n\t\telse\n\t\t{\n\t\t\ttoBigEndian(ret.bytecode.size(), r);\n\t\t\tsubAssemblyOffsets[subObject] = ret.bytecode.size();\n\t\t\tret.bytecode += subObject.bytecode;\n\t\t}\n\t\tfor (auto const& ref: subObject.linkReferences)\n\t\t\tret.linkReferences[ref.first + subAssemblyOffsets[subObject]] = ref.second;\n\t}\n\tfor (auto const& i: tagRefs)\n\t{\n\t\tauto [subId, tagId] = i.second;\n\t\tsolAssert(subId.empty() || subId.value < m_subs.size(), \"Invalid sub id\");\n\t\tstd::vector<size_t> const& tagPositions =\n\t\t\tsubId.empty() ?\n\t\t\tm_tagPositionsInBytecode :\n\t\t\tm_subs[subId.asIndex()]->m_tagPositionsInBytecode;\n\t\tassertThrow(tagId < tagPositions.size(), AssemblyException, \"Reference to non-existing tag.\");\n\t\tsize_t pos = tagPositions[tagId];\n\t\tassertThrow(pos != std::numeric_limits<size_t>::max(), AssemblyException, \"Reference to tag without position.\");\n\t\tassertThrow(numberEncodingSize(pos) <= bytesPerTag, AssemblyException, \"Tag too large for reserved space.\");\n\t\tbytesRef r(ret.bytecode.data() + i.first, bytesPerTag);\n\t\ttoBigEndian(pos, r);\n\t}\n\tfor (auto const& [name, tagInfo]: m_namedTags)\n\t{\n\t\tsize_t position = m_tagPositionsInBytecode.at(tagInfo.id);\n\t\tstd::optional<size_t> tagIndex;\n\t\tfor (auto&& [index, item]: items | ranges::views::enumerate)\n\t\t\tif (item.type() == Tag && static_cast<size_t>(item.data()) == tagInfo.id)\n\t\t\t{\n\t\t\t\ttagIndex = index;\n\t\t\t\tbreak;\n\t\t\t}\n\t\tret.functionDebugData[name] = {\n\t\t\tposition == std::numeric_limits<size_t>::max() ? std::nullopt : std::optional<size_t>{position},\n\t\t\ttagIndex,\n\t\t\ttagInfo.sourceID,\n\t\t\ttagInfo.params,\n\t\t\ttagInfo.returns\n\t\t};\n\t}\n\n\tfor (auto const& dataItem: m_data)\n\t{\n\t\tauto references = dataRefs.equal_range(dataItem.first);\n\t\tif (references.first == references.second)\n\t\t\tcontinue;\n\t\tfor (auto ref = references.first; ref != references.second; ++ref)\n\t\t{\n\t\t\tbytesRef r(ret.bytecode.data() + ref->second, bytesPerDataRef);\n\t\t\ttoBigEndian(ret.bytecode.size(), r);\n\t\t}\n\t\tret.bytecode += dataItem.second;\n\t}\n\n\tret.bytecode += m_auxiliaryData;\n\n\tfor (unsigned pos: sizeRefs)\n\t{\n\t\tbytesRef r(ret.bytecode.data() + pos, bytesPerDataRef);\n\t\ttoBigEndian(ret.bytecode.size(), r);\n\t}\n\treturn ret;\n}\n\nstd::map<ContainerID, ContainerID> Assembly::findReferencedContainers() const\n{\n\tstd::set<ContainerID> referencedSubcontainersIds;\n\tsolAssert(m_subs.size() <= 0x100); // According to EOF spec\n\n\tfor (auto&& codeSection: m_codeSections)\n\t\tfor (AssemblyItem const& item: codeSection.items)\n\t\t\tif (item.type() == EOFCreate || item.type() == ReturnContract)\n\t\t\t{\n\t\t\t\tsolAssert(item.data() <= m_subs.size(), \"Invalid subcontainer index.\");\n\t\t\t\tauto const containerId = static_cast<ContainerID>(item.data());\n\t\t\t\treferencedSubcontainersIds.insert(containerId);\n\t\t\t}\n\n\tstd::map<ContainerID, ContainerID> replacements;\n\tuint8_t nUnreferenced = 0;\n\tfor (size_t i = 0; i < m_subs.size(); ++i)\n\t{\n\t\tsolAssert(i <= std::numeric_limits<ContainerID>::max());\n\t\tif (referencedSubcontainersIds.count(static_cast<ContainerID>(i)) > 0)\n\t\t\treplacements[static_cast<ContainerID>(i)] = static_cast<ContainerID>(i - nUnreferenced);\n\t\telse\n\t\t\tnUnreferenced++;\n\t}\n\n\treturn replacements;\n}\n\nstd::optional<uint16_t> Assembly::findMaxAuxDataLoadNOffset() const\n{\n\tstd::optional<unsigned> maxOffset = std::nullopt;\n\tfor (auto&& codeSection: m_codeSections)\n\t\tfor (AssemblyItem const& item: codeSection.items)\n\t\t\tif (item.type() == AuxDataLoadN)\n\t\t\t{\n\t\t\t\tsolAssert(item.data() <= std::numeric_limits<uint16_t>::max(), \"Invalid auxdataloadn index value.\");\n\t\t\t\tauto const offset = static_cast<unsigned>(item.data());\n\t\t\t\tif (!maxOffset.has_value() || offset > maxOffset.value())\n\t\t\t\t\tmaxOffset = offset;\n\n\t\t\t}\n\n\treturn maxOffset;\n}\n\nLinkerObject const& Assembly::assembleEOF() const\n{\n\tsolAssert(m_eofVersion.has_value() && m_eofVersion == 1);\n\tLinkerObject& ret = m_assembledObject;\n\n\tauto const subIdsReplacements = findReferencedContainers();\n\tauto const referencedSubIds = keys(subIdsReplacements);\n\n\tsolAssert(!m_codeSections.empty(), \"Expected at least one code section.\");\n\tsolAssert(\n\t\tm_codeSections.front().inputs == 0 && m_codeSections.front().outputs == 0 && m_codeSections.front().nonReturning,\n\t\t\"Expected the first code section to have zero inputs and be non-returning.\"\n\t);\n\n\tauto const maxAuxDataLoadNOffset = findMaxAuxDataLoadNOffset();\n\n\t// Insert EOF1 header.\n\tauto [headerBytecode, codeSectionSizePositions, dataSectionSizePosition] = createEOFHeader(referencedSubIds);\n\tret.bytecode = headerBytecode;\n\n\tm_tagPositionsInBytecode = std::vector<size_t>(m_usedTags, std::numeric_limits<size_t>::max());\n\tstd::map<size_t, uint16_t> dataSectionRef;\n\tstd::map<size_t, size_t> tagRef;\n\n\tfor (auto&& [codeSectionIndex, codeSection]: m_codeSections | ranges::views::enumerate)\n\t{\n\t\tauto const sectionStart = ret.bytecode.size();\n\n\t\tstd::vector<LinkerObject::InstructionLocation> instructionLocations;\n\t\tinstructionLocations.reserve(codeSection.items.size());\n\n\t\tsolAssert(!codeSection.items.empty(), \"Empty code section.\");\n\n\t\tfor (auto const& [assemblyItemIndex, item]: codeSection.items | ranges::views::enumerate)\n\t\t{\n\t\t\t// collect instruction locations via side effects\n\t\t\tInstructionLocationEmitter instructionLocationEmitter {instructionLocations, ret.bytecode, assemblyItemIndex};\n\n\t\t\t// store position of the invalid jump destination\n\t\t\tif (item.type() != Tag && m_tagPositionsInBytecode[0] == std::numeric_limits<size_t>::max())\n\t\t\t\tm_tagPositionsInBytecode[0] = ret.bytecode.size();\n\n\t\t\tswitch (item.type())\n\t\t\t{\n\t\t\tcase Operation:\n\t\t\t\tsolAssert(\n\t\t\t\t\titem.instruction() != Instruction::DATALOADN &&\n\t\t\t\t\titem.instruction() != Instruction::RETURNCONTRACT &&\n\t\t\t\t\titem.instruction() != Instruction::EOFCREATE &&\n\t\t\t\t\titem.instruction() != Instruction::RJUMP &&\n\t\t\t\t\titem.instruction() != Instruction::RJUMPI &&\n\t\t\t\t\titem.instruction() != Instruction::CALLF &&\n\t\t\t\t\titem.instruction() != Instruction::JUMPF &&\n\t\t\t\t\titem.instruction() != Instruction::RETF &&\n\t\t\t\t\titem.instruction() != Instruction::DUPN &&\n\t\t\t\t\titem.instruction() != Instruction::SWAPN\n\t\t\t\t);\n\t\t\t\tsolAssert(!(item.instruction() >= Instruction::PUSH0 && item.instruction() <= Instruction::PUSH32));\n\t\t\t\tret.bytecode += assembleOperation(item);\n\t\t\t\tbreak;\n\t\t\tcase Push:\n\t\t\t\tret.bytecode += assemblePush(item);\n\t\t\t\tbreak;\n\t\t\tcase PushLibraryAddress:\n\t\t\t{\n\t\t\t\tauto const [pushLibraryAddressBytecode, linkRef] = assemblePushLibraryAddress(item, ret.bytecode.size());\n\t\t\t\tret.bytecode += pushLibraryAddressBytecode;\n\t\t\t\tret.linkReferences.insert(linkRef);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase RelativeJump:\n\t\t\tcase ConditionalRelativeJump:\n\t\t\t{\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(item.instruction()));\n\t\t\t\ttagRef[ret.bytecode.size()] = item.relativeJumpTagID();\n\t\t\t\tappendBigEndianUint16(ret.bytecode, 0u);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase EOFCreate:\n\t\t\t{\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(Instruction::EOFCREATE));\n\t\t\t\tsolAssert(item.data() <= std::numeric_limits<ContainerID>::max());\n\t\t\t\tauto const containerID = static_cast<ContainerID>(item.data());\n\t\t\t\tsolAssert(subIdsReplacements.count(containerID) == 1);\n\t\t\t\tret.bytecode.push_back(subIdsReplacements.at(containerID));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ReturnContract:\n\t\t\t{\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(Instruction::RETURNCONTRACT));\n\t\t\t\tsolAssert(item.data() <= std::numeric_limits<ContainerID>::max());\n\t\t\t\tauto const containerID = static_cast<ContainerID>(item.data());\n\t\t\t\tsolAssert(subIdsReplacements.count(containerID) == 1);\n\t\t\t\tret.bytecode.push_back(subIdsReplacements.at(containerID));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase VerbatimBytecode:\n\t\t\t\tret.bytecode += assembleVerbatimBytecode(item);\n\t\t\t\tbreak;\n\t\t\tcase PushDeployTimeAddress:\n\t\t\t\tret.bytecode += assemblePushDeployTimeAddress();\n\t\t\t\tbreak;\n\t\t\tcase Tag:\n\t\t\t\tret.bytecode += assembleTag(item, ret.bytecode.size(), false);\n\t\t\t\tbreak;\n\t\t\tcase AuxDataLoadN:\n\t\t\t{\n\t\t\t\t// In findMaxAuxDataLoadNOffset we already verified that unsigned data value fits 2 bytes\n\t\t\t\tsolAssert(item.data() <= std::numeric_limits<uint16_t>::max(), \"Invalid auxdataloadn position.\");\n\t\t\t\tret.bytecode.push_back(uint8_t(Instruction::DATALOADN));\n\t\t\t\tdataSectionRef[ret.bytecode.size()] = static_cast<uint16_t>(item.data());\n\t\t\t\tappendBigEndianUint16(ret.bytecode, item.data());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CallF:\n\t\t\tcase JumpF:\n\t\t\t{\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(item.instruction()));\n\t\t\t\tsolAssert(item.data() <= std::numeric_limits<uint16_t>::max(), \"Invalid callf/jumpf index value.\");\n\t\t\t\tsize_t const index = static_cast<uint16_t>(item.data());\n\t\t\t\tsolAssert(index < m_codeSections.size());\n\t\t\t\tsolAssert(item.functionSignature().argsNum <= 127);\n\t\t\t\tsolAssert(item.functionSignature().retsNum <= 127);\n\t\t\t\tsolAssert(m_codeSections[index].inputs == item.functionSignature().argsNum);\n\t\t\t\tsolAssert(m_codeSections[index].outputs == item.functionSignature().retsNum);\n\t\t\t\t// If CallF the function cannot be non-returning.\n\t\t\t\tsolAssert(item.type() == JumpF || !m_codeSections[index].nonReturning);\n\t\t\t\tappendBigEndianUint16(ret.bytecode, item.data());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase RetF:\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(Instruction::RETF));\n\t\t\t\tbreak;\n\t\t\tcase SwapN:\n\t\t\tcase DupN:\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(item.instruction()));\n\t\t\t\tsolAssert(item.data() >= 1 && item.data() <= 256);\n\t\t\t\tret.bytecode.push_back(static_cast<uint8_t>(item.data() - 1));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tsolAssert(false, \"Unexpected opcode while assembling.\");\n\t\t\t}\n\t\t}\n\n\t\tif (ret.bytecode.size() - sectionStart > std::numeric_limits<uint16_t>::max())\n\t\t\t// TODO: Include source location. Note that origin locations we have in debug data are\n\t\t\t// not usable for error reporting when compiling pure Yul because they point at the optimized source.\n\t\t\tthrow Error(\n\t\t\t\t2202_error,\n\t\t\t\tError::Type::CodeGenerationError,\n\t\t\t\t\"Code section too large for EOF.\"\n\t\t\t);\n\t\tsetBigEndianUint16(ret.bytecode, codeSectionSizePositions[codeSectionIndex], ret.bytecode.size() - sectionStart);\n\n\t\tret.codeSectionLocations.push_back(LinkerObject::CodeSectionLocation{\n\t\t\t.start = sectionStart,\n\t\t\t.end = ret.bytecode.size(),\n\t\t\t.instructionLocations = std::move(instructionLocations)\n\t\t});\n\t}\n\n\tfor (auto const& [refPos, tagId]: tagRef)\n\t{\n\t\tsolAssert(tagId < m_tagPositionsInBytecode.size(), \"Reference to non-existing tag.\");\n\t\tsize_t tagPos = m_tagPositionsInBytecode[tagId];\n\t\tsolAssert(tagPos != std::numeric_limits<size_t>::max(), \"Reference to tag without position.\");\n\n\t\tptrdiff_t const relativeJumpOffset = static_cast<ptrdiff_t>(tagPos) - (static_cast<ptrdiff_t>(refPos) + 2);\n\t\t// This cannot happen in practice because we'll run into section size limit first.\n\t\tif (!(-0x8000 <= relativeJumpOffset && relativeJumpOffset <= 0x7FFF))\n\t\t\t// TODO: Include source location. Note that origin locations we have in debug data are\n\t\t\t// not usable for error reporting when compiling pure Yul because they point at the optimized source.\n\t\t\tthrow Error(\n\t\t\t\t2703_error,\n\t\t\t\tError::Type::CodeGenerationError,\n\t\t\t\t\"Relative jump too far\"\n\t\t\t);\n\t\tsolAssert(relativeJumpOffset < -2 || 0 <= relativeJumpOffset, \"Relative jump offset into immediate argument.\");\n\t\tsetBigEndianUint16(ret.bytecode, refPos, static_cast<size_t>(static_cast<uint16_t>(relativeJumpOffset)));\n\t}\n\n\tfor (auto i: referencedSubIds)\n\t{\n\t\tsize_t const subAssemblyPositionInParentObject = ret.bytecode.size();\n\t\tauto const& subAssemblyLinkerObject = m_subs[i]->assemble();\n\t\t// Append subassembly bytecode to the parent assembly result bytecode\n\t\tret.bytecode += subAssemblyLinkerObject.bytecode;\n\t\t// Add subassembly link references to parent linker object.\n\t\t// Offset accordingly to subassembly position in parent object bytecode\n\t\tfor (auto const& [subAssemblyLinkRefPosition, linkRef]: subAssemblyLinkerObject.linkReferences)\n\t\t\tret.linkReferences[subAssemblyPositionInParentObject + subAssemblyLinkRefPosition] = linkRef;\n\t}\n\n\t// TODO: Fill functionDebugData for EOF. It probably should be handled for new code section in the loop above.\n\tsolRequire(m_namedTags.empty(), AssemblyException, \"Named tags must be empty in EOF context.\");\n\n\tauto const dataStart = ret.bytecode.size();\n\n\tfor (auto const& dataItem: m_data)\n\t\tret.bytecode += dataItem.second;\n\n\tret.bytecode += m_auxiliaryData;\n\n\tauto const preDeployDataSectionSize = ret.bytecode.size() - dataStart;\n\t// DATALOADN loads 32 bytes from EOF data section zero padded if reading out of data bounds.\n\t// In our case we do not allow DATALOADN with offsets which reads out of data bounds.\n\tauto const staticAuxDataSize = maxAuxDataLoadNOffset.has_value() ? (*maxAuxDataLoadNOffset + 32u) : 0u;\n\tauto const preDeployAndStaticAuxDataSize = preDeployDataSectionSize + staticAuxDataSize;\n\n\tif (preDeployAndStaticAuxDataSize > std::numeric_limits<uint16_t>::max())\n\t\tthrow Error(\n\t\t\t3965_error,\n\t\t\tError::Type::CodeGenerationError,\n\t\t\t\"The highest accessed data offset exceeds the maximum possible size of the static auxdata section.\"\n\t\t);\n\n\t// If some data was already added to data section we need to update data section refs accordingly\n\tif (preDeployDataSectionSize > 0)\n\t\tfor (auto [refPosition, staticAuxDataOffset] : dataSectionRef)\n\t\t{\n\t\t\t// staticAuxDataOffset + preDeployDataSectionSize value is already verified to fit 2 bytes because\n\t\t\t// staticAuxDataOffset < staticAuxDataSize\n\t\t\tsetBigEndianUint16(ret.bytecode, refPosition, staticAuxDataOffset + preDeployDataSectionSize);\n\t\t}\n\n\tsetBigEndianUint16(ret.bytecode, dataSectionSizePosition, preDeployAndStaticAuxDataSize);\n\n\treturn ret;\n}\n\nstd::vector<SubAssemblyID> Assembly::decodeSubPath(SubAssemblyID _subObjectId) const\n{\n\tif (_subObjectId.value < m_subs.size())\n\t\treturn {_subObjectId};\n\n\tauto subIdPathIt = ranges::find_if(\n\t\tm_subPaths,\n\t\t[_subObjectId](auto const& subId) { return subId.second == _subObjectId; }\n\t);\n\n\tassertThrow(subIdPathIt != m_subPaths.end(), AssemblyException, \"\");\n\treturn subIdPathIt->first;\n}\n\nSubAssemblyID Assembly::encodeSubPath(std::vector<SubAssemblyID> const& _subPath)\n{\n\tassertThrow(!_subPath.empty(), AssemblyException, \"\");\n\tif (_subPath.size() == 1)\n\t{\n\t\tsolAssert(_subPath[0].value < m_subs.size());\n\t\treturn _subPath[0];\n\t}\n\n\tif (!m_subPaths.contains(_subPath))\n\t{\n\t\tSubAssemblyID const objectId{std::numeric_limits<SubAssemblyID::ValueType>::max() - m_subPaths.size()};\n\t\tsolAssert(objectId.value >= m_subs.size());\n\t\tm_subPaths[_subPath] = objectId;\n\t}\n\n\treturn m_subPaths[_subPath];\n}\n\nAssembly const* Assembly::subAssemblyById(SubAssemblyID const _subId) const\n{\n\tstd::vector<SubAssemblyID> subIDs = decodeSubPath(_subId);\n\tAssembly const* currentAssembly = this;\n\tfor (auto const& subID: subIDs)\n\t{\n\t\tcurrentAssembly = currentAssembly->m_subs.at(subID.asIndex()).get();\n\t\tassertThrow(currentAssembly, AssemblyException, \"\");\n\t}\n\n\tassertThrow(currentAssembly != this, AssemblyException, \"\");\n\treturn currentAssembly;\n}\n\nAssembly::OptimiserSettings Assembly::OptimiserSettings::translateSettings(frontend::OptimiserSettings const& _settings)\n{\n\t// Constructing it this way so that we notice changes in the fields.\n\tOptimiserSettings asmSettings{false,  false, false, false, false, false, 0};\n\tasmSettings.runInliner = _settings.runInliner;\n\tasmSettings.runJumpdestRemover = _settings.runJumpdestRemover;\n\tasmSettings.runPeephole = _settings.runPeephole;\n\tasmSettings.runDeduplicate = _settings.runDeduplicate;\n\tasmSettings.runCSE = _settings.runCSE;\n\tasmSettings.runConstantOptimiser = _settings.runConstantOptimiser;\n\tasmSettings.expectedExecutionsPerDeployment = _settings.expectedExecutionsPerDeployment;\n\treturn asmSettings;\n}\n"
  },
  {
    "path": "libevmasm/Assembly.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libevmasm/Instruction.h>\n#include <liblangutil/SourceLocation.h>\n#include <libevmasm/AssemblyItem.h>\n#include <libevmasm/LinkerObject.h>\n#include <libevmasm/Exceptions.h>\n#include <libevmasm/SubAssemblyID.h>\n\n#include <liblangutil/DebugInfoSelection.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/Assertions.h>\n#include <libsolutil/Keccak256.h>\n#include <libsolutil/JSON.h>\n\n#include <libsolidity/interface/OptimiserSettings.h>\n\n#include <iostream>\n#include <sstream>\n#include <memory>\n#include <map>\n#include <utility>\n\nnamespace solidity::evmasm\n{\n\nusing AssemblyPointer = std::shared_ptr<Assembly>;\n\nclass Assembly\n{\n\tusing TagRefs = std::map<size_t, std::pair<SubAssemblyID, size_t>>;\n\tusing DataRefs = std::multimap<util::h256, unsigned>;\n\tusing SubAssemblyRefs = std::multimap<SubAssemblyID, size_t>;\n\tusing ProgramSizeRefs = std::vector<unsigned>;\n\tusing LinkRef = std::pair<size_t, std::string>;\n\npublic:\n\tAssembly(langutil::EVMVersion _evmVersion, bool _creation, std::optional<uint8_t> _eofVersion, std::string _name):\n\t\tm_evmVersion(_evmVersion),\n\t\tm_creation(_creation),\n\t\tm_eofVersion(_eofVersion),\n\t\tm_name(std::move(_name))\n\t{\n\t\t// Code section number 0 has to be non-returning.\n\t\tm_codeSections.emplace_back(CodeSection{0, 0, true, {}});\n\t}\n\n\tstd::optional<uint8_t> eofVersion() const { return m_eofVersion; }\n\tbool supportsFunctions() const { return m_eofVersion.has_value(); }\n\tbool supportsRelativeJumps() const { return m_eofVersion.has_value(); }\n\tAssemblyItem newTag() { assertThrow(m_usedTags < 0xffffffff, AssemblyException, \"\"); return AssemblyItem(Tag, m_usedTags++); }\n\tAssemblyItem newPushTag() { assertThrow(m_usedTags < 0xffffffff, AssemblyException, \"\"); return AssemblyItem(PushTag, m_usedTags++); }\n\n\tAssemblyItem newFunctionCall(uint16_t _functionID) const;\n\tAssemblyItem newFunctionReturn() const;\n\tuint16_t createFunction(uint8_t _args, uint8_t _rets, bool _nonReturning);\n\tvoid beginFunction(uint16_t _functionID);\n\tvoid endFunction();\n\n\t/// Returns a tag identified by the given name. Creates it if it does not yet exist.\n\tAssemblyItem namedTag(std::string const& _name, size_t _params, size_t _returns, std::optional<uint64_t> _sourceID);\n\tAssemblyItem newData(bytes const& _data) { util::h256 h(util::keccak256(util::asString(_data))); m_data[h] = _data; return AssemblyItem(PushData, h); }\n\tbytes const& data(util::h256 const& _i) const { return m_data.at(_i); }\n\tAssemblyItem newSub(AssemblyPointer const& _sub) { m_subs.push_back(_sub); return AssemblyItem(PushSub, m_subs.size() - 1); }\n\tAssembly const& sub(SubAssemblyID const _sub) const\t{ return *m_subs.at(_sub.asIndex()); }\n\tAssembly& sub(SubAssemblyID const _sub) { return *m_subs.at(_sub.asIndex()); }\n\tsize_t numSubs() const { return m_subs.size(); }\n\tAssemblyItem newPushSubSize(u256 const& _subId) { return AssemblyItem(PushSubSize, _subId); }\n\tAssemblyItem newPushLibraryAddress(std::string const& _identifier);\n\tAssemblyItem newPushImmutable(std::string const& _identifier);\n\tAssemblyItem newImmutableAssignment(std::string const& _identifier);\n\tAssemblyItem newAuxDataLoadN(size_t offset) const;\n\tAssemblyItem newSwapN(size_t _depth) const;\n\tAssemblyItem newDupN(size_t _depth) const;\n\n\tAssemblyItem const& append(AssemblyItem _i);\n\tAssemblyItem const& append(bytes const& _data) { return append(newData(_data)); }\n\n\ttemplate <class T> Assembly& operator<<(T const& _d) { append(_d); return *this; }\n\n\t/// Pushes the final size of the current assembly itself. Use this when the code is modified\n\t/// after compilation and CODESIZE is not an option.\n\tvoid appendProgramSize() { append(AssemblyItem(PushProgramSize)); }\n\tvoid appendLibraryAddress(std::string const& _identifier) { append(newPushLibraryAddress(_identifier)); }\n\tvoid appendImmutable(std::string const& _identifier) { append(newPushImmutable(_identifier)); }\n\tvoid appendImmutableAssignment(std::string const& _identifier) { append(newImmutableAssignment(_identifier)); }\n\tvoid appendAuxDataLoadN(uint16_t _offset) { append(newAuxDataLoadN(_offset));}\n\tvoid appendSwapN(size_t _depth) { append(newSwapN(_depth)); }\n\tvoid appendDupN(size_t _depth) { append(newDupN(_depth)); }\n\n\tvoid appendVerbatim(bytes _data, size_t _arguments, size_t _returnVariables)\n\t{\n\t\tappend(AssemblyItem(std::move(_data), _arguments, _returnVariables));\n\t}\n\n\tAssemblyItem appendEOFCreate(ContainerID _containerId)\n\t{\n\t\tsolAssert(_containerId < m_subs.size(), \"EOF Create of undefined container.\");\n\t\treturn append(AssemblyItem::eofCreate(_containerId));\n\t}\n\tAssemblyItem appendReturnContract(ContainerID _containerId)\n\t{\n\t\tsolAssert(_containerId < m_subs.size(), \"Return undefined container ID.\");\n\t\treturn append(AssemblyItem::returnContract(_containerId));\n\t}\n\n\tAssemblyItem appendFunctionCall(uint16_t _functionID)\n\t{\n\t\treturn append(newFunctionCall(_functionID));\n\t}\n\n\tAssemblyItem appendFunctionReturn()\n\t{\n\t\tsolAssert(m_currentCodeSection != 0, \"Appending function return without begin function.\");\n\t\treturn append(newFunctionReturn());\n\t}\n\n\tAssemblyItem appendJump() { auto ret = append(newPushTag()); append(Instruction::JUMP); return ret; }\n\tAssemblyItem appendJumpI() { auto ret = append(newPushTag()); append(Instruction::JUMPI); return ret; }\n\tAssemblyItem appendJump(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(Instruction::JUMP); return ret; }\n\tAssemblyItem appendJumpI(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(Instruction::JUMPI); return ret; }\n\n\t/// Adds a subroutine to the code (in the data section) and pushes its size (via a tag)\n\t/// on the stack. @returns the pushsub assembly item.\n\tAssemblyItem appendSubroutine(AssemblyPointer const& _assembly) { auto sub = newSub(_assembly); append(newPushSubSize(size_t(sub.data()))); return sub; }\n\tvoid pushSubroutineSize(SubAssemblyID _subRoutine) { append(newPushSubSize(_subRoutine.value)); }\n\t/// Pushes the offset of the subroutine.\n\tvoid pushSubroutineOffset(SubAssemblyID _subRoutine) { append(AssemblyItem(PushSub, _subRoutine.value)); }\n\n\t/// Appends @a _data literally to the very end of the bytecode.\n\tvoid appendToAuxiliaryData(bytes const& _data) { m_auxiliaryData += _data; }\n\n\tint deposit() const { return m_deposit; }\n\tvoid adjustDeposit(int _adjustment) { m_deposit += _adjustment; solAssert(m_deposit >= 0); }\n\tvoid setDeposit(int _deposit) { m_deposit = _deposit; solAssert(m_deposit >= 0); }\n\tstd::string const& name() const { return m_name; }\n\n\t/// Changes the source location used for each appended item.\n\tvoid setSourceLocation(langutil::SourceLocation const& _location) { m_currentSourceLocation = _location; }\n\tlangutil::SourceLocation const& currentSourceLocation() const { return m_currentSourceLocation; }\n\tlangutil::EVMVersion const& evmVersion() const { return m_evmVersion; }\n\n\t/// Assembles the assembly into bytecode. The assembly should not be modified after this call, since the assembled version is cached.\n\tLinkerObject const& assemble() const;\n\n\tstruct OptimiserSettings\n\t{\n\t\tbool runInliner = false;\n\t\tbool runJumpdestRemover = false;\n\t\tbool runPeephole = false;\n\t\tbool runDeduplicate = false;\n\t\tbool runCSE = false;\n\t\tbool runConstantOptimiser = false;\n\t\t/// This specifies an estimate on how often each opcode in this assembly will be executed,\n\t\t/// i.e. use a small value to optimise for size and a large value to optimise for runtime gas usage.\n\t\tsize_t expectedExecutionsPerDeployment = frontend::OptimiserSettings{}.expectedExecutionsPerDeployment;\n\n\t\tstatic OptimiserSettings translateSettings(frontend::OptimiserSettings const& _settings);\n\t};\n\n\t/// Modify and return the current assembly such that creation and execution gas usage\n\t/// is optimised according to the settings in @a _settings.\n\tAssembly& optimise(OptimiserSettings const& _settings);\n\n\t/// Create a text representation of the assembly.\n\tstd::string assemblyString(\n\t\tlangutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),\n\t\tStringMap const& _sourceCodes = StringMap()\n\t) const;\n\tvoid assemblyStream(\n\t\tstd::ostream& _out,\n\t\tlangutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),\n\t\tstd::string const& _prefix = \"\",\n\t\tStringMap const& _sourceCodes = StringMap()\n\t) const;\n\n\t/// Create a JSON representation of the assembly.\n\tJson assemblyJSON(std::map<std::string, unsigned> const& _sourceIndices, bool _includeSourceList = true) const;\n\n\t/// Constructs an @a Assembly from the serialized JSON representation.\n\t/// @param _json JSON object containing assembly in the format produced by assemblyJSON().\n\t/// @param _sourceList List of source files the assembly was built from. When the JSON represents\n\t///     the root assembly, the function will read it from the 'sourceList' field and the parameter\n\t///     must be empty. It is only used to pass the list down to recursive calls.\n\t/// @param _level Nesting level of the current assembly in the assembly tree. The root is\n\t///     at level 0 and the value increases down the tree. Necessary to distinguish between creation\n\t///     and deployed objects.\n\t/// @returns Created @a Assembly and the source list read from the 'sourceList' field of the root\n\t///     assembly or an empty list (in recursive calls).\n\tstatic std::pair<std::shared_ptr<Assembly>, std::vector<std::string>> fromJSON(\n\t\tJson const& _json,\n\t\tstd::vector<std::string> const& _sourceList = {},\n\t\tsize_t _level = 0,\n\t\tstd::optional<uint8_t> _eofVersion = std::nullopt\n\t);\n\n\t/// Mark this assembly as invalid. Calling ``assemble`` on it will throw.\n\tvoid markAsInvalid() { m_invalid = true; }\n\n\tstd::vector<SubAssemblyID> decodeSubPath(SubAssemblyID _subObjectId) const;\n\tSubAssemblyID encodeSubPath(std::vector<SubAssemblyID> const& _subPath);\n\n\tbool isCreation() const { return m_creation; }\n\n\tstruct CodeSection\n\t{\n\t\tuint8_t inputs = 0;\n\t\t// Number of outputs needs to be set properly even for non-returning function.\n\t\t// It matters in case of stack height calculation of the function call instruction.\n\t\tuint8_t outputs = 0;\n\t\tbool nonReturning = false;\n\t\tAssemblyItems items{};\n\t};\n\n\tstd::vector<CodeSection>& codeSections()\n\t{\n\t\treturn m_codeSections;\n\t}\n\n\tstd::vector<CodeSection> const& codeSections() const\n\t{\n\t\treturn m_codeSections;\n\t}\n\nprotected:\n\t/// Does the same operations as @a optimise, but should only be applied to a sub and\n\t/// returns the replaced tags. Also takes an argument containing the tags of this assembly\n\t/// that are referenced in a super-assembly.\n\tstd::map<u256, u256> const& optimiseInternal(OptimiserSettings const& _settings, std::set<size_t> _tagsReferencedFromOutside);\n\n\t/// For EOF and legacy it calculates approximate size of \"pure\" code without data.\n\tunsigned codeSize(unsigned subTagSize) const;\n\n\t/// Add all assembly items from given JSON array. This function imports the items by iterating through\n\t/// the code array. This method only works on clean Assembly objects that don't have any items defined yet.\n\t/// @param _json JSON array that contains assembly items (e.g. json['.code'])\n\t/// @param _sourceList List of source names.\n\tvoid importAssemblyItemsFromJSON(Json const& _code, std::vector<std::string> const& _sourceList);\n\n\t/// Creates an AssemblyItem from a given JSON representation.\n\t/// @param _json JSON object that consists a single assembly item\n\t/// @param _sourceList List of source names.\n\t/// @returns AssemblyItem of _json argument.\n\tAssemblyItem createAssemblyItemFromJSON(Json const& _json, std::vector<std::string> const& _sourceList);\n\nprivate:\n\tbool m_invalid = false;\n\n\tAssembly const* subAssemblyById(SubAssemblyID _subId) const;\n\n\tvoid encodeAllPossibleSubPathsInAssemblyTree(std::vector<SubAssemblyID> _pathFromRoot = {}, std::vector<Assembly*> _assembliesOnPath = {});\n\n\tstd::shared_ptr<std::string const> sharedSourceName(std::string const& _name) const;\n\n\t/// Returns EOF header bytecode | code section sizes offsets | data section size offset\n\tstd::tuple<bytes, std::vector<size_t>, size_t> createEOFHeader(std::set<ContainerID> const& _referencedSubIds) const;\n\n\tLinkerObject const& assembleLegacy() const;\n\tLinkerObject const& assembleEOF() const;\n\n\t/// Returns map from m_subs to an index of subcontainer in the final EOF bytecode\n\tstd::map<ContainerID, ContainerID> findReferencedContainers() const;\n\t/// Returns max AuxDataLoadN offset for the assembly.\n\tstd::optional<uint16_t> findMaxAuxDataLoadNOffset() const;\n\n\t/// Assemble bytecode for AssemblyItem type.\n\t[[nodiscard]] bytes assembleOperation(AssemblyItem const& _item) const;\n\t[[nodiscard]] bytes assemblePush(AssemblyItem const& _item) const;\n\t[[nodiscard]] std::pair<bytes, Assembly::LinkRef> assemblePushLibraryAddress(AssemblyItem const& _item, size_t _pos) const;\n\t[[nodiscard]] bytes assembleVerbatimBytecode(AssemblyItem const& item) const;\n\t[[nodiscard]] bytes assemblePushDeployTimeAddress() const;\n\t[[nodiscard]] bytes assembleTag(AssemblyItem const& _item, size_t _pos, bool _addJumpDest) const;\n\nprotected:\n\t/// 0 is reserved for exception\n\tunsigned m_usedTags = 1;\n\n\tstruct NamedTagInfo\n\t{\n\t\tsize_t id;\n\t\tstd::optional<size_t> sourceID;\n\t\tsize_t params;\n\t\tsize_t returns;\n\t};\n\n\tstd::map<std::string, NamedTagInfo> m_namedTags;\n\tstd::map<util::h256, bytes> m_data;\n\t/// Data that is appended to the very end of the contract.\n\tbytes m_auxiliaryData;\n\tstd::vector<std::shared_ptr<Assembly>> m_subs;\n\tstd::vector<CodeSection> m_codeSections;\n\tuint16_t m_currentCodeSection = 0;\n\tstd::map<util::h256, std::string> m_strings;\n\tstd::map<util::h256, std::string> m_libraries; ///< Identifiers of libraries to be linked.\n\tstd::map<util::h256, std::string> m_immutables; ///< Identifiers of immutables.\n\n\t/// Map from a vector representing a path to a particular sub assembly to sub assembly id.\n\t/// This map is used only for sub-assemblies which are not direct sub-assemblies (where path is having more than one value).\n\t/// Nested/indirect SubAssemblyIDs are assigned negative unsigned 64 bit integers, i.e., the `i`th indirect\n\t/// index corresponds to `std::numeric_limits<std::uint64_t>::max() - i` in contrast to direct indices which occupy\n\t/// the non-negative half of the index space.\n\tstd::map<std::vector<SubAssemblyID>, SubAssemblyID> m_subPaths;\n\n\t/// Contains the tag replacements relevant for super-assemblies.\n\t/// If set, it means the optimizer has run and we will not run it again.\n\tstd::optional<std::map<u256, u256>> m_tagReplacements;\n\n\tmutable LinkerObject m_assembledObject;\n\tmutable std::vector<size_t> m_tagPositionsInBytecode;\n\n\tlangutil::EVMVersion m_evmVersion;\n\n\tint m_deposit = 0;\n\t/// True, if the assembly contains contract creation code.\n\tbool const m_creation = false;\n\tstd::optional<uint8_t> m_eofVersion;\n\t/// Internal name of the assembly object, only used with the Yul backend\n\t/// currently\n\tstd::string m_name;\n\tlangutil::SourceLocation m_currentSourceLocation;\n\n\t// FIXME: This being static means that the strings won't be freed when they're no longer needed\n\tstatic std::map<std::string, std::shared_ptr<std::string const>> s_sharedSourceNames;\n\npublic:\n\tsize_t m_currentModifierDepth = 0;\n};\n\ninline std::ostream& operator<<(std::ostream& _out, Assembly const& _a)\n{\n\t_a.assemblyStream(_out);\n\treturn _out;\n}\n\n}\n"
  },
  {
    "path": "libevmasm/AssemblyItem.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libevmasm/AssemblyItem.h>\n\n#include <libevmasm/Assembly.h>\n#include <libevmasm/SemanticInformation.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/Numeric.h>\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/FixedHash.h>\n#include <liblangutil/SourceLocation.h>\n\n#include <fstream>\n#include <limits>\n\nusing namespace std::literals;\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::langutil;\n\nstatic_assert(sizeof(size_t) <= 8, \"size_t must be at most 64-bits wide\");\n\nnamespace\n{\n\nstd::string toStringInHex(u256 _value)\n{\n\tstd::stringstream hexStr;\n\thexStr << std::uppercase << std::hex << _value;\n\treturn hexStr.str();\n}\n\n}\n\nAssemblyItem AssemblyItem::toSubAssemblyTag(SubAssemblyID _subId) const\n{\n\tassertThrow(data() < (u256(1) << 64), util::Exception, \"Tag already has subassembly set.\");\n\tassertThrow(m_type == PushTag || m_type == Tag, util::Exception, \"\");\n\tauto tag = static_cast<size_t>(u256(data()) & 0xffffffffffffffffULL);\n\tAssemblyItem r = *this;\n\tr.m_type = PushTag;\n\tr.setPushTagSubIdAndTag(_subId, tag);\n\treturn r;\n}\n\nstd::pair<SubAssemblyID, size_t> AssemblyItem::splitForeignPushTag() const\n{\n\tsolAssert(m_type == PushTag || m_type == Tag || m_type == RelativeJump || m_type == ConditionalRelativeJump);\n\tu256 combined = u256(data());\n\t// the combined u256 is 'dirty', so we can't use the conversion constructor of SubAssemblyID here\n\tSubAssemblyID const subID{static_cast<SubAssemblyID::ValueType>((combined >> 64) - 1)};\n\tsize_t tag = static_cast<size_t>(combined & 0xffffffffffffffffULL);\n\treturn std::make_pair(subID, tag);\n}\n\nsize_t AssemblyItem::relativeJumpTagID() const\n{\n\tsolAssert(m_type == RelativeJump || m_type == ConditionalRelativeJump);\n\tauto const [subId, tagId] = splitForeignPushTag();\n\tsolAssert(subId.empty(), \"Relative jump to sub\");\n\treturn tagId;\n}\n\nstd::pair<std::string, std::string> AssemblyItem::nameAndData(langutil::EVMVersion _evmVersion) const\n{\n\tswitch (type())\n\t{\n\tcase Operation:\n\tcase EOFCreate:\n\tcase ReturnContract:\n\tcase RelativeJump:\n\tcase ConditionalRelativeJump:\n\tcase CallF:\n\tcase JumpF:\n\tcase RetF:\n\t\treturn {instructionInfo(instruction(), _evmVersion).name, \"\"};\n\tcase SwapN:\n\tcase DupN:\n\t\treturn {instructionInfo(instruction(), _evmVersion).name, util::toString(static_cast<size_t>(data())) };\n\tcase Push:\n\t\treturn {\"PUSH\", toStringInHex(data())};\n\tcase PushTag:\n\t\tif (data() == 0)\n\t\t\treturn {\"PUSH [ErrorTag]\", \"\"};\n\t\telse\n\t\t\treturn {\"PUSH [tag]\", util::toString(data())};\n\tcase PushSub:\n\t\treturn {\"PUSH [$]\", toString(util::h256(data()))};\n\tcase PushSubSize:\n\t\treturn {\"PUSH #[$]\", toString(util::h256(data()))};\n\tcase PushProgramSize:\n\t\treturn {\"PUSHSIZE\", \"\"};\n\tcase PushLibraryAddress:\n\t\treturn {\"PUSHLIB\", toString(util::h256(data()))};\n\tcase PushDeployTimeAddress:\n\t\treturn {\"PUSHDEPLOYADDRESS\", \"\"};\n\tcase PushImmutable:\n\t\treturn {\"PUSHIMMUTABLE\", toString(util::h256(data()))};\n\tcase AssignImmutable:\n\t\treturn {\"ASSIGNIMMUTABLE\", toString(util::h256(data()))};\n\tcase Tag:\n\t\treturn {\"tag\", util::toString(data())};\n\tcase PushData:\n\t\treturn {\"PUSH data\", toStringInHex(data())};\n\tcase VerbatimBytecode:\n\t\treturn {\"VERBATIM\", util::toHex(verbatimData())};\n\tcase AuxDataLoadN:\n\t\treturn {\"AUXDATALOADN\", util::toString(data())};\n\tcase UndefinedItem:\n\t\tsolAssert(false);\n\t}\n\n\tutil::unreachable();\n}\n\nvoid AssemblyItem::setPushTagSubIdAndTag(SubAssemblyID _subId, size_t _tag)\n{\n\tsolAssert(m_type == PushTag || m_type == Tag || m_type == RelativeJump || m_type == ConditionalRelativeJump);\n\tsolAssert(!(m_type == RelativeJump || m_type == ConditionalRelativeJump) || _subId.empty());\n\tu256 data = _tag;\n\tif (!_subId.empty())\n\t\tdata |= (u256(_subId.value) + 1) << 64;\n\tsetData(data);\n}\n\nsize_t AssemblyItem::bytesRequired(size_t _addressLength, langutil::EVMVersion _evmVersion, Precision _precision) const\n{\n\tswitch (m_type)\n\t{\n\tcase Operation:\n\tcase Tag: // 1 byte for the JUMPDEST\n\tcase RetF:\n\t\treturn 1;\n\tcase Push:\n\t\treturn\n\t\t\t1 +\n\t\t\tstd::max<size_t>((_evmVersion.hasPush0() ? 0 : 1), numberEncodingSize(data()));\n\tcase PushSubSize:\n\tcase PushProgramSize:\n\t\treturn 1 + 4; // worst case: a 16MB program\n\tcase PushTag:\n\tcase PushData:\n\tcase PushSub:\n\t\treturn 1 + _addressLength;\n\tcase PushLibraryAddress:\n\tcase PushDeployTimeAddress:\n\t\treturn 1 + 20;\n\tcase PushImmutable:\n\t\treturn 1 + 32;\n\tcase AssignImmutable:\n\t{\n\t\tunsigned long immutableOccurrences = 0;\n\n\t\t// Skip exact immutables count if no precise count was requested\n\t\tif (_precision == Precision::Approximate)\n\t\t\timmutableOccurrences = 1; // Assume one immut. ref.\n\t\telse\n\t\t{\n\t\t\tsolAssert(m_immutableOccurrences, \"No immutable references. `bytesRequired()` called before assembly()?\");\n\t\t\timmutableOccurrences = m_immutableOccurrences.value();\n\t\t}\n\n\t\tif (immutableOccurrences != 0)\n\t\t\t// (DUP DUP PUSH <n> ADD MSTORE)* (PUSH <n> ADD MSTORE)\n\t\t\treturn (immutableOccurrences - 1) * (5 + 32) + (3 + 32);\n\t\telse\n\t\t\t// POP POP\n\t\t\treturn 2;\n\t}\n\tcase VerbatimBytecode:\n\t\treturn std::get<2>(*m_verbatimBytecode).size();\n\tcase RelativeJump:\n\tcase ConditionalRelativeJump:\n\tcase AuxDataLoadN:\n\tcase JumpF:\n\tcase CallF:\n\t\treturn 1 + 2;\n\tcase EOFCreate:\n\t\treturn 2;\n\tcase ReturnContract:\n\t\treturn 2;\n\tcase SwapN:\n\t\treturn 2;\n\tcase DupN:\n\t\treturn 2;\n\tcase UndefinedItem:\n\t\tsolAssert(false);\n\t}\n\n\tutil::unreachable();\n}\n\nsize_t AssemblyItem::arguments() const\n{\n\tif (type() == CallF || type() == JumpF)\n\t\treturn functionSignature().argsNum;\n\telse if (type() == SwapN)\n\t\treturn static_cast<size_t>(data()) + 1;\n\telse if (type() == DupN)\n\t\treturn static_cast<size_t>(data());\n\telse if (hasInstruction())\n\t{\n\t\tsolAssert(instruction() != Instruction::CALLF && instruction() != Instruction::JUMPF);\n\t\t// The latest EVMVersion is used here, since the InstructionInfo is assumed to be\n\t\t// the same across all EVM versions except for the instruction name.\n\t\treturn static_cast<size_t>(instructionInfo(instruction(), EVMVersion()).args);\n\t}\n\telse if (type() == VerbatimBytecode)\n\t\treturn std::get<0>(*m_verbatimBytecode);\n\telse if (type() == AssignImmutable)\n\t\treturn 2;\n\telse\n\t\treturn 0;\n}\n\nsize_t AssemblyItem::returnValues() const\n{\n\tswitch (m_type)\n\t{\n\tcase Operation:\n\tcase EOFCreate:\n\tcase ReturnContract:\n\tcase RelativeJump:\n\tcase ConditionalRelativeJump:\n\tcase RetF:\n\t\t// The latest EVMVersion is used here, since the InstructionInfo is assumed to be\n\t\t// the same across all EVM versions except for the instruction name.\n\t\treturn static_cast<size_t>(instructionInfo(instruction(), EVMVersion()).ret);\n\tcase SwapN:\n\tcase DupN:\n\t\treturn static_cast<size_t>(data()) + 1;\n\tcase Push:\n\tcase PushTag:\n\tcase PushData:\n\tcase PushSub:\n\tcase PushSubSize:\n\tcase PushProgramSize:\n\tcase PushLibraryAddress:\n\tcase PushImmutable:\n\tcase PushDeployTimeAddress:\n\t\treturn 1;\n\tcase Tag:\n\t\treturn 0;\n\tcase VerbatimBytecode:\n\t\treturn std::get<1>(*m_verbatimBytecode);\n\tcase AuxDataLoadN:\n\t\treturn 1;\n\tcase JumpF:\n\tcase CallF:\n\t\treturn functionSignature().retsNum;\n\tcase AssignImmutable:\n\tcase UndefinedItem:\n\t\tbreak;\n\t}\n\treturn 0;\n}\n\nbool AssemblyItem::canBeFunctional() const\n{\n\tif (m_jumpType != JumpType::Ordinary)\n\t\treturn false;\n\tswitch (m_type)\n\t{\n\tcase Operation:\n\tcase EOFCreate:\n\tcase ReturnContract:\n\tcase RelativeJump:\n\tcase ConditionalRelativeJump:\n\tcase CallF:\n\tcase JumpF:\n\tcase SwapN:\n\tcase DupN:\n\tcase RetF:\n\t\treturn !SemanticInformation::isDupInstruction(*this) && !SemanticInformation::isSwapInstruction(*this);\n\tcase Push:\n\tcase PushTag:\n\tcase PushData:\n\tcase PushSub:\n\tcase PushSubSize:\n\tcase PushProgramSize:\n\tcase PushLibraryAddress:\n\tcase PushDeployTimeAddress:\n\tcase PushImmutable:\n\tcase AuxDataLoadN:\n\t\treturn true;\n\tcase Tag:\n\t\treturn false;\n\tcase AssignImmutable:\n\tcase VerbatimBytecode:\n\tcase UndefinedItem:\n\t\tbreak;\n\t}\n\treturn false;\n}\n\nstd::string AssemblyItem::getJumpTypeAsString() const\n{\n\tswitch (m_jumpType)\n\t{\n\tcase JumpType::IntoFunction:\n\t\treturn \"[in]\";\n\tcase JumpType::OutOfFunction:\n\t\treturn \"[out]\";\n\tcase JumpType::Ordinary:\n\tdefault:\n\t\treturn \"\";\n\t}\n}\n\nstd::optional<AssemblyItem::JumpType> AssemblyItem::parseJumpType(std::string const& _jumpType)\n{\n\tif (_jumpType == \"[in]\")\n\t\treturn JumpType::IntoFunction;\n\telse if (_jumpType == \"[out]\")\n\t\treturn JumpType::OutOfFunction;\n\telse if (_jumpType.empty())\n\t\treturn JumpType::Ordinary;\n\n\treturn std::nullopt;\n}\n\nstd::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const\n{\n\tstd::string text;\n\tswitch (type())\n\t{\n\tcase Operation:\n\t{\n\t\tassertThrow(isValidInstruction(instruction()), AssemblyException, \"Invalid instruction.\");\n\t\ttext = util::toLower(instructionInfo(instruction(), _assembly.evmVersion()).name);\n\t\tbreak;\n\t}\n\tcase Push:\n\t\ttext = toHex(toCompactBigEndian(data(), 1), util::HexPrefix::Add);\n\t\tbreak;\n\tcase PushTag:\n\t{\n\t\tauto [sub, tag] = splitForeignPushTag();\n\t\tif (sub.empty())\n\t\t\ttext = std::string(\"tag_\") + std::to_string(tag);\n\t\telse\n\t\t\ttext = std::string(\"tag_\") + std::to_string(sub.value) + \"_\" + std::to_string(tag);\n\t\tbreak;\n\t}\n\tcase Tag:\n\t\tassertThrow(data() < 0x10000, AssemblyException, \"Declaration of sub-assembly tag.\");\n\t\ttext = std::string(\"tag_\") + std::to_string(static_cast<size_t>(data())) + \":\";\n\t\tbreak;\n\tcase PushData:\n\t\ttext = std::string(\"data_\") + toHex(data());\n\t\tbreak;\n\tcase PushSub:\n\tcase PushSubSize:\n\t{\n\t\tstd::vector<std::string> subPathComponents;\n\t\tfor (SubAssemblyID subPathComponentId: _assembly.decodeSubPath(SubAssemblyID{data()}))\n\t\t\tsubPathComponents.emplace_back(\"sub_\" + std::to_string(subPathComponentId.value));\n\t\ttext =\n\t\t\t(type() == PushSub ? \"dataOffset\"s : \"dataSize\"s) +\n\t\t\t\"(\" +\n\t\t\tsolidity::util::joinHumanReadable(subPathComponents, \".\") +\n\t\t\t\")\";\n\t\tbreak;\n\t}\n\tcase PushProgramSize:\n\t\ttext = std::string(\"bytecodeSize\");\n\t\tbreak;\n\tcase PushLibraryAddress:\n\t\ttext = std::string(\"linkerSymbol(\\\"\") + toHex(data()) + std::string(\"\\\")\");\n\t\tbreak;\n\tcase PushDeployTimeAddress:\n\t\ttext = std::string(\"deployTimeAddress()\");\n\t\tbreak;\n\tcase PushImmutable:\n\t\ttext = std::string(\"immutable(\\\"\") + \"0x\" + util::toHex(toCompactBigEndian(data(), 1)) + \"\\\")\";\n\t\tbreak;\n\tcase AssignImmutable:\n\t\ttext = std::string(\"assignImmutable(\\\"\") + \"0x\" + util::toHex(toCompactBigEndian(data(), 1)) + \"\\\")\";\n\t\tbreak;\n\tcase UndefinedItem:\n\t\tassertThrow(false, AssemblyException, \"Invalid assembly item.\");\n\t\tbreak;\n\tcase VerbatimBytecode:\n\t\ttext = std::string(\"verbatimbytecode_\") + util::toHex(std::get<2>(*m_verbatimBytecode));\n\t\tbreak;\n\tcase AuxDataLoadN:\n\t\tassertThrow(data() <= std::numeric_limits<size_t>::max(), AssemblyException, \"Invalid auxdataloadn argument.\");\n\t\ttext = \"auxdataloadn{\" +  std::to_string(static_cast<size_t>(data())) + \"}\";\n\t\tbreak;\n\tcase EOFCreate:\n\t\ttext = \"eofcreate{\" +  std::to_string(static_cast<size_t>(data())) + \"}\";\n\t\tbreak;\n\tcase ReturnContract:\n\t\ttext = \"returncontract{\" +  std::to_string(static_cast<size_t>(data())) + \"}\";\n\t\tbreak;\n\tcase RelativeJump:\n\t\ttext = \"rjump{\" + std::string(\"tag_\") + std::to_string(relativeJumpTagID()) + \"}\";\n\t\tbreak;\n\tcase ConditionalRelativeJump:\n\t\ttext = \"rjumpi{\" + std::string(\"tag_\") + std::to_string(relativeJumpTagID()) + \"}\";\n\t\tbreak;\n\tcase CallF:\n\t\ttext = \"callf{\" + std::string(\"code_section_\") +  std::to_string(static_cast<size_t>(data())) + \"}\";\n\t\tbreak;\n\tcase JumpF:\n\t\ttext = \"jumpf{\" + std::string(\"code_section_\") +  std::to_string(static_cast<size_t>(data())) + \"}\";\n\t\tbreak;\n\tcase RetF:\n\t\ttext = \"retf\";\n\t\tbreak;\n\tcase SwapN:\n\t\ttext = \"swapn{\" + std::to_string(static_cast<size_t>(data())) + \"}\";\n\t\tbreak;\n\tcase DupN:\n\t\ttext = \"dupn{\" + std::to_string(static_cast<size_t>(data())) + \"}\";\n\t\tbreak;\n\t}\n\tif (m_jumpType == JumpType::IntoFunction || m_jumpType == JumpType::OutOfFunction)\n\t{\n\t\ttext += \"\\t//\";\n\t\tif (m_jumpType == JumpType::IntoFunction)\n\t\t\ttext += \" in\";\n\t\telse\n\t\t\ttext += \" out\";\n\t}\n\treturn text;\n}\n\n// Note: This method is exclusively used for debugging.\nstd::ostream& solidity::evmasm::operator<<(std::ostream& _out, AssemblyItem const& _item)\n{\n\tswitch (_item.type())\n\t{\n\tcase Operation:\n\tcase EOFCreate:\n\tcase ReturnContract:\n\tcase RelativeJump:\n\tcase ConditionalRelativeJump:\n\tcase CallF:\n\tcase JumpF:\n\tcase RetF:\n\tcase SwapN:\n\tcase DupN:\n\t\t_out << \" \" << instructionInfo(_item.instruction(), EVMVersion()).name;\n\t\tif (_item.instruction() == Instruction::JUMP || _item.instruction() == Instruction::JUMPI)\n\t\t\t_out << \"\\t\" << _item.getJumpTypeAsString();\n\t\tbreak;\n\tcase Push:\n\t\t_out << \" PUSH \" << std::hex << _item.data() <<  std::dec;\n\t\tbreak;\n\tcase PushTag:\n\t{\n\t\tSubAssemblyID subId = _item.splitForeignPushTag().first;\n\t\tif (subId.empty())\n\t\t\t_out << \" PushTag \" << _item.splitForeignPushTag().second;\n\t\telse\n\t\t\t_out << \" PushTag \" << subId.value << \":\" << _item.splitForeignPushTag().second;\n\t\tbreak;\n\t}\n\tcase Tag:\n\t\t_out << \" Tag \" << _item.data();\n\t\tbreak;\n\tcase PushData:\n\t\t_out << \" PushData \" << std::hex << static_cast<unsigned>(_item.data()) <<  std::dec;\n\t\tbreak;\n\tcase PushSub:\n\t\t_out << \" PushSub \" << std::hex << static_cast<size_t>(_item.data()) <<  std::dec;\n\t\tbreak;\n\tcase PushSubSize:\n\t\t_out << \" PushSubSize \" << std::hex << static_cast<size_t>(_item.data()) <<  std::dec;\n\t\tbreak;\n\tcase PushProgramSize:\n\t\t_out << \" PushProgramSize\";\n\t\tbreak;\n\tcase PushLibraryAddress:\n\t{\n\t\tstd::string hash(util::h256((_item.data())).hex());\n\t\t_out << \" PushLibraryAddress \" << hash.substr(0, 8) + \"...\" + hash.substr(hash.length() - 8);\n\t\tbreak;\n\t}\n\tcase PushDeployTimeAddress:\n\t\t_out << \" PushDeployTimeAddress\";\n\t\tbreak;\n\tcase PushImmutable:\n\t\t_out << \" PushImmutable\";\n\t\tbreak;\n\tcase AssignImmutable:\n\t\t_out << \" AssignImmutable\";\n\t\tbreak;\n\tcase VerbatimBytecode:\n\t\t_out << \" Verbatim \" << util::toHex(_item.verbatimData());\n\t\tbreak;\n\tcase AuxDataLoadN:\n\t\t_out << \" AuxDataLoadN \" << util::toString(_item.data());\n\t\tbreak;\n\tcase UndefinedItem:\n\t\t_out << \" ???\";\n\t\tbreak;\n\t}\n\treturn _out;\n}\n\nsize_t AssemblyItem::opcodeCount() const noexcept\n{\n\tswitch (m_type)\n\t{\n\t\tcase AssemblyItemType::AssignImmutable:\n\t\t\t// Append empty items if this AssignImmutable was referenced more than once.\n\t\t\t// For n immutable occurrences the first (n - 1) occurrences will\n\t\t\t// generate 5 opcodes and the last will generate 3 opcodes,\n\t\t\t// because it is reusing the 2 top-most elements on the stack.\n\t\t\tsolAssert(m_immutableOccurrences, \"\");\n\n\t\t\tif (m_immutableOccurrences.value() != 0)\n\t\t\t\treturn (*m_immutableOccurrences - 1) * 5 + 3;\n\t\t\telse\n\t\t\t\treturn 2; // two POP's\n\t\tdefault:\n\t\t\treturn 1;\n\t}\n}\n\nstd::string AssemblyItem::computeSourceMapping(\n\tAssemblyItems const& _items,\n\tstd::map<std::string, unsigned> const& _sourceIndicesMap\n)\n{\n\tstd::string ret;\n\n\tint prevStart = -1;\n\tint prevLength = -1;\n\tint prevSourceIndex = -1;\n\tint prevModifierDepth = -1;\n\tchar prevJump = 0;\n\n\tfor (auto const& item: _items)\n\t{\n\t\tif (!ret.empty())\n\t\t\tret += \";\";\n\n\t\tSourceLocation const& location = item.location();\n\t\tint length = location.start != -1 && location.end != -1 ? location.end - location.start : -1;\n\t\tint sourceIndex =\n\t\t\t(location.sourceName && _sourceIndicesMap.count(*location.sourceName)) ?\n\t\t\tstatic_cast<int>(_sourceIndicesMap.at(*location.sourceName)) :\n\t\t\t-1;\n\t\tchar jump = '-';\n\t\tif (item.getJumpType() == evmasm::AssemblyItem::JumpType::IntoFunction || item.type() == CallF || item.type() == JumpF)\n\t\t\tjump = 'i';\n\t\telse if (item.getJumpType() == evmasm::AssemblyItem::JumpType::OutOfFunction || item.type() == RetF)\n\t\t\tjump = 'o';\n\t\tint modifierDepth = static_cast<int>(item.m_modifierDepth);\n\n\t\tunsigned components = 5;\n\t\tif (modifierDepth == prevModifierDepth)\n\t\t{\n\t\t\tcomponents--;\n\t\t\tif (jump == prevJump)\n\t\t\t{\n\t\t\t\tcomponents--;\n\t\t\t\tif (sourceIndex == prevSourceIndex)\n\t\t\t\t{\n\t\t\t\t\tcomponents--;\n\t\t\t\t\tif (length == prevLength)\n\t\t\t\t\t{\n\t\t\t\t\t\tcomponents--;\n\t\t\t\t\t\tif (location.start == prevStart)\n\t\t\t\t\t\t\tcomponents--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (components-- > 0)\n\t\t{\n\t\t\tif (location.start != prevStart)\n\t\t\t\tret += std::to_string(location.start);\n\t\t\tif (components-- > 0)\n\t\t\t{\n\t\t\t\tret += ':';\n\t\t\t\tif (length != prevLength)\n\t\t\t\t\tret += std::to_string(length);\n\t\t\t\tif (components-- > 0)\n\t\t\t\t{\n\t\t\t\t\tret += ':';\n\t\t\t\t\tif (sourceIndex != prevSourceIndex)\n\t\t\t\t\t\tret += std::to_string(sourceIndex);\n\t\t\t\t\tif (components-- > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tret += ':';\n\t\t\t\t\t\tif (jump != prevJump)\n\t\t\t\t\t\t\tret += jump;\n\t\t\t\t\t\tif (components-- > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tret += ':';\n\t\t\t\t\t\t\tif (modifierDepth != prevModifierDepth)\n\t\t\t\t\t\t\t\tret += std::to_string(modifierDepth);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (item.opcodeCount() > 1)\n\t\t\tret += std::string(item.opcodeCount() - 1, ';');\n\n\t\tprevStart = location.start;\n\t\tprevLength = length;\n\t\tprevSourceIndex = sourceIndex;\n\t\tprevJump = jump;\n\t\tprevModifierDepth = modifierDepth;\n\t}\n\treturn ret;\n}\n"
  },
  {
    "path": "libevmasm/AssemblyItem.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file AssemblyItem.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#pragma once\n\n#include <libevmasm/Instruction.h>\n#include <libevmasm/Exceptions.h>\n#include <libevmasm/SubAssemblyID.h>\n#include <liblangutil/DebugData.h>\n#include <liblangutil/Exceptions.h>\n#include <libsolutil/Common.h>\n#include <libsolutil/Numeric.h>\n#include <libsolutil/Assertions.h>\n#include <optional>\n#include <iostream>\n#include <sstream>\n\nnamespace solidity::evmasm\n{\n\nenum AssemblyItemType\n{\n\tUndefinedItem,\n\tOperation,\n\tPush,\n\tPushTag,\n\tPushSub,\n\tPushSubSize,\n\tPushProgramSize,\n\tTag,\n\tPushData,\n\tPushLibraryAddress, ///< Push a currently unknown address of another (library) contract.\n\tPushDeployTimeAddress, ///< Push an address to be filled at deploy time. Should not be touched by the optimizer.\n\tPushImmutable, ///< Push the currently unknown value of an immutable variable. The actual value will be filled in by the constructor.\n\tAssignImmutable, ///< Assigns the current value on the stack to an immutable variable. Only valid during creation code.\n\n\t/// Loads 32 bytes from static auxiliary data of EOF data section. The offset does *not* have to be always from the beginning\n\t/// of the data EOF section. More details here: https://github.com/ipsilon/eof/blob/main/spec/eof.md#data-section-lifecycle\n\tAuxDataLoadN,\n\tEOFCreate, ///< Creates new contract using subcontainer as initcode\n\tReturnContract, ///< Returns new container (with auxiliary data filled in) to be deployed\n\tRelativeJump, ///< Jumps to relative position accordingly to its argument\n\tConditionalRelativeJump, ///< Same as RelativeJump but takes condition from the stack\n\tCallF, ///< Jumps to a returning EOF function, adding a new frame to the return stack.\n\tJumpF, ///< Jumps to a returning or non-returning EOF function without changing the return stack.\n\tRetF, ///< Returns from an EOF function, removing a frame from the return stack.\n\tVerbatimBytecode, ///< Contains data that is inserted into the bytecode code section without modification.\n\tSwapN, ///< EOF SWAPN with immediate argument.\n\tDupN, ///< EOF DUPN with immediate argument.\n};\n\nenum class Precision { Precise , Approximate };\n\nclass Assembly;\nclass AssemblyItem;\nusing AssemblyItems = std::vector<AssemblyItem>;\nusing ContainerID = uint8_t;\n\nclass AssemblyItem\n{\npublic:\n\tenum class JumpType { Ordinary, IntoFunction, OutOfFunction };\n\n\tAssemblyItem(u256 _push, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()):\n\t\tAssemblyItem(Push, std::move(_push), std::move(_debugData)) { }\n\tAssemblyItem(Instruction _i, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()):\n\t\tm_type(Operation),\n\t\tm_instruction(_i),\n\t\tm_debugData(std::move(_debugData))\n\t{\n\t\tsolAssert(_i != Instruction::SWAPN, \"Construct via AssemblyItem::swapN\");\n\t\tsolAssert(_i != Instruction::DUPN, \"Construct via AssemblyItem::dupN\");\n\t}\n\tAssemblyItem(AssemblyItemType _type, u256 _data = 0, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()):\n\t\tm_type(_type),\n\t\tm_debugData(std::move(_debugData))\n\t{\n\t\tif (m_type == Operation)\n\t\t\tm_instruction = Instruction(uint8_t(_data));\n\t\telse\n\t\t\tm_data = std::make_shared<u256>(std::move(_data));\n\t}\n\n\texplicit AssemblyItem(AssemblyItemType _type, Instruction _instruction, u256 _data = 0, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create()):\n\t\tm_type(_type),\n\t\tm_instruction(_instruction),\n\t\tm_data(std::make_shared<u256>(std::move(_data))),\n\t\tm_debugData(std::move(_debugData))\n\t{}\n\n\texplicit AssemblyItem(bytes _verbatimData, size_t _arguments, size_t _returnVariables):\n\t\tm_type(VerbatimBytecode),\n\t\tm_verbatimBytecode{{_arguments, _returnVariables, std::move(_verbatimData)}},\n\t\tm_debugData{langutil::DebugData::create()}\n\t{}\n\n\tstatic AssemblyItem functionCall(uint16_t _functionID, uint8_t _args, uint8_t _rets, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create())\n\t{\n\t\t// TODO: Make this constructor this way that it's impossible to create it without setting functions signature.\n\t\t// It can be done by template constructor with Instruction as template parameter i.e. Same for JumpF below.\n\t\tAssemblyItem result(CallF, Instruction::CALLF, _functionID, _debugData);\n\t\tsolAssert(_args <= 127 && _rets <= 127);\n\t\tresult.m_functionSignature = {_args, _rets};\n\t\treturn result;\n\t}\n\tstatic AssemblyItem jumpToFunction(uint16_t _functionID, uint8_t _args, uint8_t _rets, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create())\n\t{\n\t\tAssemblyItem result(JumpF, Instruction::JUMPF, _functionID, _debugData);\n\t\tsolAssert(_args <= 127 && _rets <= 127);\n\t\tresult.m_functionSignature = {_args, _rets};\n\t\treturn result;\n\t}\n\tstatic AssemblyItem functionReturn(langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create())\n\t{\n\t\treturn AssemblyItem(RetF, Instruction::RETF, 0, std::move(_debugData));\n\t}\n\n\tstatic AssemblyItem eofCreate(ContainerID _containerID, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create())\n\t{\n\t\treturn AssemblyItem(EOFCreate, Instruction::EOFCREATE, _containerID, std::move(_debugData));\n\t}\n\tstatic AssemblyItem returnContract(ContainerID _containerID, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create())\n\t{\n\t\treturn AssemblyItem(ReturnContract, Instruction::RETURNCONTRACT, _containerID, std::move(_debugData));\n\t}\n\tstatic AssemblyItem relativeJumpTo(AssemblyItem _tag, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create())\n\t{\n\t\tsolAssert(_tag.type() == Tag);\n\t\treturn AssemblyItem(RelativeJump, Instruction::RJUMP, _tag.data(), _debugData);\n\t}\n\tstatic AssemblyItem conditionalRelativeJumpTo(AssemblyItem _tag, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create())\n\t{\n\t\tsolAssert(_tag.type() == Tag);\n\t\treturn AssemblyItem(ConditionalRelativeJump, Instruction::RJUMPI, _tag.data(), _debugData);\n\t}\n\tstatic AssemblyItem swapN(size_t _depth, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create())\n\t{\n\t\tsolAssert(_depth >= 1 && _depth <= 256);\n\t\treturn AssemblyItem(SwapN, Instruction::SWAPN, _depth, _debugData);\n\t}\n\tstatic AssemblyItem dupN(size_t _depth, langutil::DebugData::ConstPtr _debugData = langutil::DebugData::create())\n\t{\n\t\tsolAssert(_depth >= 1 && _depth <= 256);\n\t\treturn AssemblyItem(DupN, Instruction::DUPN, _depth, _debugData);\n\t}\n\n\tAssemblyItem(AssemblyItem const&) = default;\n\tAssemblyItem(AssemblyItem&&) = default;\n\tAssemblyItem& operator=(AssemblyItem const&) = default;\n\tAssemblyItem& operator=(AssemblyItem&&) = default;\n\n\tAssemblyItem tag() const { solAssert(m_type == PushTag || m_type == Tag || m_type == RelativeJump || m_type == ConditionalRelativeJump); return AssemblyItem(Tag, data()); }\n\tAssemblyItem pushTag() const { solAssert(m_type == PushTag || m_type == Tag || m_type == RelativeJump || m_type == ConditionalRelativeJump); return AssemblyItem(PushTag, data()); }\n\t/// Converts the tag to a subassembly tag. This has to be called in order to move a tag across assemblies.\n\t/// @param _subId the identifier of the subassembly the tag is taken from.\n\tAssemblyItem toSubAssemblyTag(SubAssemblyID _subId) const;\n\t/// @returns splits the data of the push tag into sub assembly id and actual tag id.\n\t/// The sub assembly id of non-foreign push tags is -1.\n\tstd::pair<SubAssemblyID, size_t> splitForeignPushTag() const;\n\t/// @returns relative jump target tag ID. Asserts that it is not foreign tag.\n\tsize_t relativeJumpTagID() const;\n\t/// Sets sub-assembly part and tag for a push tag.\n\tvoid setPushTagSubIdAndTag(SubAssemblyID _subId, size_t _tag);\n\n\tAssemblyItemType type() const { return m_type; }\n\tu256 const& data() const { solAssert(m_type != Operation && m_data != nullptr); return *m_data; }\n\tvoid setData(u256 const& _data) { assertThrow(m_type != Operation, util::Exception, \"\"); m_data = std::make_shared<u256>(_data); }\n\n\t/// This function is used in `Assembly::assemblyJSON`.\n\t/// It returns the name & data of the current assembly item.\n\t/// @param _evmVersion the EVM version.\n\t/// @returns a pair, where the first element is the json-assembly\n\t/// item name, where second element is the string representation\n\t/// of it's data.\n\tstd::pair<std::string, std::string> nameAndData(langutil::EVMVersion _evmVersion) const;\n\n\tbytes const& verbatimData() const { assertThrow(m_type == VerbatimBytecode, util::Exception, \"\"); return std::get<2>(*m_verbatimBytecode); }\n\n\t/// @returns true if the item has m_instruction properly set.\n\tbool hasInstruction() const\n\t{\n\t\tbool const shouldHaveInstruction =\n\t\t\tm_type == Operation ||\n\t\t\tm_type == EOFCreate ||\n\t\t\tm_type == ReturnContract ||\n\t\t\tm_type == RelativeJump ||\n\t\t\tm_type == ConditionalRelativeJump ||\n\t\t\tm_type == CallF ||\n\t\t\tm_type == JumpF ||\n\t\t\tm_type == RetF ||\n\t\t\tm_type == SwapN ||\n\t\t\tm_type == DupN;\n\t\tsolAssert(shouldHaveInstruction == m_instruction.has_value());\n\t\treturn shouldHaveInstruction;\n\t}\n\t/// @returns the instruction of this item (only valid if hasInstruction returns true)\n\tInstruction instruction() const\n\t{\n\t\tsolAssert(hasInstruction());\n\t\treturn *m_instruction;\n\t}\n\n\t/// @returns true if the type and data of the items are equal.\n\tbool operator==(AssemblyItem const& _other) const\n\t{\n\t\tif (type() != _other.type())\n\t\t\treturn false;\n\t\tif (type() == Operation)\n\t\t\treturn instruction() == _other.instruction();\n\t\telse if (type() == VerbatimBytecode)\n\t\t\treturn *m_verbatimBytecode == *_other.m_verbatimBytecode;\n\t\telse\n\t\t\treturn data() == _other.data();\n\t}\n\tbool operator!=(AssemblyItem const& _other) const { return !operator==(_other); }\n\t/// Less-than operator compatible with operator==.\n\tbool operator<(AssemblyItem const& _other) const\n\t{\n\t\tif (type() != _other.type())\n\t\t\treturn type() < _other.type();\n\t\telse if (type() == Operation)\n\t\t\treturn instruction() < _other.instruction();\n\t\telse if (type() == VerbatimBytecode)\n\t\t\treturn *m_verbatimBytecode < *_other.m_verbatimBytecode;\n\t\telse\n\t\t\treturn data() < _other.data();\n\t}\n\n\t/// Shortcut that avoids constructing an AssemblyItem just to perform the comparison.\n\tbool operator==(Instruction _instr) const\n\t{\n\t\treturn hasInstruction() && instruction() == _instr;\n\t}\n\tbool operator!=(Instruction _instr) const { return !operator==(_instr); }\n\n\tstatic std::string computeSourceMapping(\n\t\tAssemblyItems const& _items,\n\t\tstd::map<std::string, unsigned> const& _sourceIndicesMap\n\t);\n\n\t/// @returns an upper bound for the number of bytes required by this item, assuming that\n\t/// the value of a jump tag takes @a _addressLength bytes.\n\t/// @param _evmVersion the EVM version\n\t/// @param _precision Whether to return a precise count (which involves\n\t///                   counting immutable references which are only set after\n\t///                   a call to `assemble()`) or an approx. count.\n\tsize_t bytesRequired(size_t _addressLength, langutil::EVMVersion _evmVersion, Precision _precision = Precision::Precise) const;\n\tsize_t arguments() const;\n\tsize_t returnValues() const;\n\tsize_t deposit() const { return returnValues() - arguments(); }\n\n\t/// @returns true if the assembly item can be used in a functional context.\n\tbool canBeFunctional() const;\n\n\tvoid setLocation(langutil::SourceLocation const& _location)\n\t{\n\t\tsolAssert(m_debugData);\n\t\tm_debugData = langutil::DebugData::create(\n\t\t\t_location,\n\t\t\tm_debugData->originLocation,\n\t\t\tm_debugData->astID\n\t\t);\n\t}\n\n\tlangutil::SourceLocation const& location() const\n\t{\n\t\tsolAssert(m_debugData);\n\t\treturn m_debugData->nativeLocation;\n\t}\n\n\tvoid setDebugData(langutil::DebugData::ConstPtr _debugData)\n\t{\n\t\tsolAssert(_debugData);\n\t\tm_debugData = std::move(_debugData);\n\t}\n\n\tlangutil::DebugData::ConstPtr debugData() const { return m_debugData; }\n\n\tvoid setJumpType(JumpType _jumpType) { m_jumpType = _jumpType; }\n\tstatic std::optional<JumpType> parseJumpType(std::string const& _jumpType);\n\tJumpType getJumpType() const { return m_jumpType; }\n\tstd::string getJumpTypeAsString() const;\n\n\tvoid setPushedValue(u256 const& _value) const { m_pushedValue = std::make_shared<u256>(_value); }\n\tu256 const* pushedValue() const { return m_pushedValue.get(); }\n\n\tstd::string toAssemblyText(Assembly const& _assembly) const;\n\n\tsize_t m_modifierDepth = 0;\n\n\tvoid setImmutableOccurrences(size_t _n) const { m_immutableOccurrences = _n; }\n\n\tstruct FunctionSignature\n\t{\n\t\t/// Number of EOF function arguments. must be less than 128\n\t\tuint8_t argsNum;\n\t\t/// Number of EOF function return values. Must be less than 128.\n\t\tuint8_t retsNum;\n\t};\n\n\tFunctionSignature const& functionSignature() const\n\t{\n\t\tsolAssert(m_type == CallF || m_type == JumpF);\n\t\tsolAssert(m_functionSignature.has_value());\n\t\treturn *m_functionSignature;\n\t}\n\nprivate:\n\tsize_t opcodeCount() const noexcept;\n\n\tAssemblyItemType m_type;\n\tstd::optional<Instruction> m_instruction; ///< Only valid for item types that represent a specific opcode\n\tstd::shared_ptr<u256> m_data; ///< Only valid if m_type != Operation\n\tstd::optional<FunctionSignature> m_functionSignature; ///< Only valid if m_type == CallF or JumpF\n\t/// If m_type == VerbatimBytecode, this holds number of arguments, number of\n\t/// return variables and verbatim bytecode.\n\tstd::optional<std::tuple<size_t, size_t, bytes>> m_verbatimBytecode;\n\tlangutil::DebugData::ConstPtr m_debugData;\n\tJumpType m_jumpType = JumpType::Ordinary;\n\t/// Pushed value for operations with data to be determined during assembly stage,\n\t/// e.g. PushSubSize, PushTag, PushSub, etc.\n\tmutable std::shared_ptr<u256> m_pushedValue;\n\t/// Number of PushImmutable's with the same hash. Only used for AssignImmutable.\n\tmutable std::optional<size_t> m_immutableOccurrences;\n};\n\ninline size_t bytesRequired(AssemblyItems const& _items, size_t _addressLength, langutil::EVMVersion _evmVersion, Precision _precision = Precision::Precise)\n{\n\tsize_t size = 0;\n\tfor (AssemblyItem const& item: _items)\n\t\tsize += item.bytesRequired(_addressLength, _evmVersion, _precision);\n\treturn size;\n}\n\nstd::ostream& operator<<(std::ostream& _out, AssemblyItem const& _item);\ninline std::ostream& operator<<(std::ostream& _out, AssemblyItems const& _items)\n{\n\tfor (AssemblyItem const& item: _items)\n\t\t_out << item;\n\treturn _out;\n}\n\n}\n"
  },
  {
    "path": "libevmasm/BlockDeduplicator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file BlockDeduplicator.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Unifies basic blocks that share content.\n */\n\n#include <libevmasm/BlockDeduplicator.h>\n\n#include <libevmasm/AssemblyItem.h>\n#include <libevmasm/SemanticInformation.h>\n\n#include <functional>\n#include <set>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\n\n\nbool BlockDeduplicator::deduplicate()\n{\n\t// Compares indices based on the suffix that starts there, ignoring tags and stopping at\n\t// opcodes that stop the control flow.\n\n\t// Virtual tag that signifies \"the current block\" and which is used to optimise loops.\n\t// We abort if this virtual tag actually exists.\n\tAssemblyItem pushSelf{PushTag, u256(-4)};\n\tif (\n\t\tstd::count(m_items.cbegin(), m_items.cend(), pushSelf.tag()) ||\n\t\tstd::count(m_items.cbegin(), m_items.cend(), pushSelf.pushTag())\n\t)\n\t\treturn false;\n\n\tstd::function<bool(size_t, size_t)> comparator = [&](size_t _i, size_t _j)\n\t{\n\t\tif (_i == _j)\n\t\t\treturn false;\n\n\t\t// To compare recursive loops, we have to already unify PushTag opcodes of the\n\t\t// block's own tag.\n\t\tAssemblyItem pushFirstTag{pushSelf};\n\t\tAssemblyItem pushSecondTag{pushSelf};\n\n\t\tif (_i < m_items.size() && m_items.at(_i).type() == Tag)\n\t\t\tpushFirstTag = m_items.at(_i).pushTag();\n\t\tif (_j < m_items.size() && m_items.at(_j).type() == Tag)\n\t\t\tpushSecondTag = m_items.at(_j).pushTag();\n\n\t\tusing diff_type = BlockIterator::difference_type;\n\t\tBlockIterator first{m_items.begin() + diff_type(_i), m_items.end(), &pushFirstTag, &pushSelf};\n\t\tBlockIterator second{m_items.begin() + diff_type(_j), m_items.end(), &pushSecondTag, &pushSelf};\n\t\tBlockIterator end{m_items.end(), m_items.end()};\n\n\t\tif (first != end && (*first).type() == Tag)\n\t\t\t++first;\n\t\tif (second != end && (*second).type() == Tag)\n\t\t\t++second;\n\n\t\treturn std::lexicographical_compare(first, end, second, end);\n\t};\n\n\tsize_t iterations = 0;\n\tfor (; ; ++iterations)\n\t{\n\t\t//@todo this should probably be optimized.\n\t\tstd::set<size_t, std::function<bool(size_t, size_t)>> blocksSeen(comparator);\n\t\tfor (size_t i = 0; i < m_items.size(); ++i)\n\t\t{\n\t\t\tif (m_items.at(i).type() != Tag)\n\t\t\t\tcontinue;\n\t\t\tauto it = blocksSeen.find(i);\n\t\t\tif (it == blocksSeen.end())\n\t\t\t\tblocksSeen.insert(i);\n\t\t\telse\n\t\t\t\tm_replacedTags[m_items.at(i).data()] = m_items.at(*it).data();\n\t\t}\n\n\t\tif (!applyTagReplacement(m_items, m_replacedTags))\n\t\t\tbreak;\n\t}\n\treturn iterations > 0;\n}\n\nbool BlockDeduplicator::applyTagReplacement(\n\tAssemblyItems& _items,\n\tstd::map<u256, u256> const& _replacements,\n\tSubAssemblyID _subId\n)\n{\n\tbool changed = false;\n\tfor (AssemblyItem& item: _items)\n\t\tif (item.type() == PushTag || item.type() == RelativeJump || item.type() == ConditionalRelativeJump)\n\t\t{\n\t\t\tSubAssemblyID subId;\n\t\t\tsize_t tagId;\n\t\t\tstd::tie(subId, tagId) = item.splitForeignPushTag();\n\t\t\tif (subId != _subId)\n\t\t\t\tcontinue;\n\t\t\tauto it = _replacements.find(tagId);\n\t\t\t// Recursively look for the element replaced by tagId\n\t\t\tfor (auto _it = it; _it != _replacements.end(); _it = _replacements.find(_it->second))\n\t\t\t\tit = _it;\n\n\t\t\tif (it != _replacements.end())\n\t\t\t{\n\t\t\t\tchanged = true;\n\t\t\t\titem.setPushTagSubIdAndTag(subId, static_cast<size_t>(it->second));\n\t\t\t}\n\t\t}\n\treturn changed;\n}\n\nBlockDeduplicator::BlockIterator& BlockDeduplicator::BlockIterator::operator++()\n{\n\tif (it == end)\n\t\treturn *this;\n\tif (SemanticInformation::altersControlFlow(*it) && *it != AssemblyItem{Instruction::JUMPI} && it->type() != ConditionalRelativeJump)\n\t\tit = end;\n\telse\n\t{\n\t\t++it;\n\t\twhile (it != end && it->type() == Tag)\n\t\t\t++it;\n\t}\n\treturn *this;\n}\n\nAssemblyItem const& BlockDeduplicator::BlockIterator::operator*() const\n{\n\tif (replaceItem && replaceWith && *it == *replaceItem)\n\t\treturn *replaceWith;\n\telse\n\t\treturn *it;\n}\n"
  },
  {
    "path": "libevmasm/BlockDeduplicator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file BlockDeduplicator.h\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Unifies basic blocks that share content.\n */\n\n#pragma once\n\n#include <libevmasm/SubAssemblyID.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/Numeric.h>\n\n#include <cstddef>\n#include <vector>\n#include <functional>\n#include <map>\n\nnamespace solidity::evmasm\n{\n\nclass AssemblyItem;\nusing AssemblyItems = std::vector<AssemblyItem>;\n\n/**\n * Optimizer class to be used to unify blocks that share content.\n * Modifies the passed vector in place.\n */\nclass BlockDeduplicator\n{\npublic:\n\texplicit BlockDeduplicator(AssemblyItems& _items): m_items(_items) {}\n\t/// @returns true if something was changed\n\tbool deduplicate();\n\t/// @returns the tags that were replaced.\n\tstd::map<u256, u256> const& replacedTags() const { return m_replacedTags; }\n\n\t/// Replaces all PushTag operations inside @a _items that match a key in\n\t/// @a _replacements by the respective value. If @a _subID is not empty, only\n\t/// apply the replacement for foreign tags from this sub id.\n\t/// @returns true iff a replacement was performed.\n\tstatic bool applyTagReplacement(\n\t\tAssemblyItems& _items,\n\t\tstd::map<u256, u256> const& _replacements,\n\t\tSubAssemblyID _subID = {}\n\t);\n\nprivate:\n\t/// Iterator that skips tags and skips to the end if (all branches of) the control\n\t/// flow does not continue to the next instruction.\n\t/// If the arguments are supplied to the constructor, replaces items on the fly.\n\tstruct BlockIterator\n\t{\n\tpublic:\n\t\tusing iterator_category = std::forward_iterator_tag;\n\t\tusing value_type = AssemblyItem const;\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing pointer = AssemblyItem const*;\n\t\tusing reference = AssemblyItem const&;\n\t\tBlockIterator(\n\t\t\tAssemblyItems::const_iterator _it,\n\t\t\tAssemblyItems::const_iterator _end,\n\t\t\tAssemblyItem const* _replaceItem = nullptr,\n\t\t\tAssemblyItem const* _replaceWith = nullptr\n\t\t):\n\t\t\tit(_it), end(_end), replaceItem(_replaceItem), replaceWith(_replaceWith) {}\n\t\tBlockIterator& operator++();\n\t\tbool operator==(BlockIterator const& _other) const { return it == _other.it; }\n\t\tbool operator!=(BlockIterator const& _other) const { return it != _other.it; }\n\t\tAssemblyItem const& operator*() const;\n\t\tAssemblyItems::const_iterator it;\n\t\tAssemblyItems::const_iterator end;\n\t\tAssemblyItem const* replaceItem;\n\t\tAssemblyItem const* replaceWith;\n\t};\n\n\tstd::map<u256, u256> m_replacedTags;\n\tAssemblyItems& m_items;\n};\n\n}\n"
  },
  {
    "path": "libevmasm/CMakeLists.txt",
    "content": "set(sources\n\tAbstractAssemblyStack.h\n\tAssembly.cpp\n\tAssembly.h\n\tAssemblyItem.cpp\n\tAssemblyItem.h\n\tEthdebug.cpp\n\tEthdebug.h\n\tEthdebugSchema.cpp\n\tEthdebugSchema.h\n\tEVMAssemblyStack.cpp\n\tEVMAssemblyStack.h\n\tBlockDeduplicator.cpp\n\tBlockDeduplicator.h\n\tCommonSubexpressionEliminator.cpp\n\tCommonSubexpressionEliminator.h\n\tConstantOptimiser.cpp\n\tConstantOptimiser.h\n\tControlFlowGraph.cpp\n\tControlFlowGraph.h\n\tDisassemble.cpp\n\tDisassemble.h\n\tExceptions.h\n\tExpressionClasses.cpp\n\tExpressionClasses.h\n\tGasMeter.cpp\n\tGasMeter.h\n\tInliner.cpp\n\tInliner.h\n\tInstruction.cpp\n\tInstruction.h\n\tJumpdestRemover.cpp\n\tJumpdestRemover.h\n\tKnownState.cpp\n\tKnownState.h\n\tLinkerObject.cpp\n\tLinkerObject.h\n\tPathGasMeter.cpp\n\tPathGasMeter.h\n\tPeepholeOptimiser.cpp\n\tPeepholeOptimiser.h\n\tSemanticInformation.cpp\n\tSemanticInformation.h\n\tSimplificationRule.h\n\tSimplificationRules.cpp\n\tSimplificationRules.h\n\tSubAssemblyID.h\n)\n\nadd_library(evmasm ${sources})\ntarget_link_libraries(evmasm PUBLIC solutil fmt::fmt-header-only)\n"
  },
  {
    "path": "libevmasm/CommonSubexpressionEliminator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file CommonSubexpressionEliminator.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Optimizer step for common subexpression elimination and stack reorganisation.\n */\n\n#include <functional>\n#include <libsolutil/Keccak256.h>\n#include <libevmasm/CommonSubexpressionEliminator.h>\n#include <libevmasm/AssemblyItem.h>\n#include <libsolutil/StackTooDeepString.h>\n\n#include <range/v3/view/reverse.hpp>\n#include <utility>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::langutil;\n\nstd::vector<AssemblyItem> CommonSubexpressionEliminator::getOptimizedItems()\n{\n\toptimizeBreakingItem();\n\n\tKnownState nextInitialState = m_state;\n\tif (m_breakingItem)\n\t\tnextInitialState.feedItem(*m_breakingItem);\n\tKnownState nextState = nextInitialState;\n\n\tScopeGuard reset([&]()\n\t{\n\t\tm_breakingItem = nullptr;\n\t\tm_storeOperations.clear();\n\t\tm_initialState = std::move(nextInitialState);\n\t\tm_state = std::move(nextState);\n\t});\n\n\tstd::map<int, Id> initialStackContents;\n\tstd::map<int, Id> targetStackContents;\n\tint minHeight = m_state.stackHeight() + 1;\n\tif (!m_state.stackElements().empty())\n\t\tminHeight = std::min(minHeight, m_state.stackElements().begin()->first);\n\tfor (int height = minHeight; height <= m_initialState.stackHeight(); ++height)\n\t\tinitialStackContents[height] = m_initialState.stackElement(height, langutil::DebugData::create());\n\tfor (int height = minHeight; height <= m_state.stackHeight(); ++height)\n\t\ttargetStackContents[height] = m_state.stackElement(height, langutil::DebugData::create());\n\n\tAssemblyItems items = CSECodeGenerator(m_state.expressionClasses(), m_storeOperations, m_evmVersion).generateCode(\n\t\tm_initialState.sequenceNumber(),\n\t\tm_initialState.stackHeight(),\n\t\tinitialStackContents,\n\t\ttargetStackContents\n\t);\n\tif (m_breakingItem)\n\t\titems.push_back(*m_breakingItem);\n\n\treturn items;\n}\n\nvoid CommonSubexpressionEliminator::feedItem(AssemblyItem const& _item, bool _copyItem)\n{\n\tStoreOperation op = m_state.feedItem(_item, _copyItem);\n\tif (op.isValid())\n\t\tm_storeOperations.push_back(op);\n}\n\nvoid CommonSubexpressionEliminator::optimizeBreakingItem()\n{\n\tif (!m_breakingItem)\n\t\treturn;\n\n\tExpressionClasses& classes = m_state.expressionClasses();\n\tSourceLocation const& itemLocation = m_breakingItem->location();\n\tlangutil::DebugData::ConstPtr debugData{langutil::DebugData::create(itemLocation)};\n\tif (*m_breakingItem == AssemblyItem(Instruction::JUMPI))\n\t{\n\t\tAssemblyItem::JumpType jumpType = m_breakingItem->getJumpType();\n\n\t\tId condition = m_state.stackElement(m_state.stackHeight() - 1, debugData);\n\t\tif (classes.knownNonZero(condition))\n\t\t{\n\t\t\tfeedItem(AssemblyItem(Instruction::SWAP1, debugData), true);\n\t\t\tfeedItem(AssemblyItem(Instruction::POP, debugData), true);\n\n\t\t\tAssemblyItem item(Instruction::JUMP, debugData);\n\t\t\titem.setJumpType(jumpType);\n\t\t\tm_breakingItem = classes.storeItem(item);\n\t\t}\n\t\telse if (classes.knownZero(condition))\n\t\t{\n\t\t\tAssemblyItem it(Instruction::POP, debugData);\n\t\t\tfeedItem(it, true);\n\t\t\tfeedItem(it, true);\n\t\t\tm_breakingItem = nullptr;\n\t\t}\n\t}\n\telse if (*m_breakingItem == AssemblyItem(Instruction::RETURN))\n\t{\n\t\tId size = m_state.stackElement(m_state.stackHeight() - 1, debugData);\n\t\tif (classes.knownZero(size))\n\t\t{\n\t\t\tfeedItem(AssemblyItem(Instruction::POP, debugData), true);\n\t\t\tfeedItem(AssemblyItem(Instruction::POP, debugData), true);\n\t\t\tAssemblyItem item(Instruction::STOP, debugData);\n\t\t\tm_breakingItem = classes.storeItem(item);\n\t\t}\n\t}\n}\n\nCSECodeGenerator::CSECodeGenerator(\n\tExpressionClasses& _expressionClasses,\n\tstd::vector<CSECodeGenerator::StoreOperation> const& _storeOperations,\n\tlangutil::EVMVersion _evmVersion\n):\n\tm_expressionClasses(_expressionClasses),\n\tm_evmVersion(_evmVersion)\n{\n\tfor (auto const& store: _storeOperations)\n\t\tm_storeOperations[std::make_pair(store.target, store.slot)].push_back(store);\n}\n\nAssemblyItems CSECodeGenerator::generateCode(\n\tunsigned _initialSequenceNumber,\n\tint _initialStackHeight,\n\tstd::map<int, Id> const& _initialStack,\n\tstd::map<int, Id> const& _targetStackContents\n)\n{\n\tm_stackHeight = _initialStackHeight;\n\tm_stack = _initialStack;\n\tm_targetStack = _targetStackContents;\n\tfor (auto const& item: m_stack)\n\t\tm_classPositions[item.second].insert(item.first);\n\n\t// generate the dependency graph starting from final storage and memory writes and target stack contents\n\tfor (auto const& p: m_storeOperations)\n\t\taddDependencies(p.second.back().expression);\n\tfor (auto const& targetItem: m_targetStack)\n\t{\n\t\tm_finalClasses.insert(targetItem.second);\n\t\taddDependencies(targetItem.second);\n\t}\n\n\t// store all needed sequenced expressions\n\tstd::set<std::pair<unsigned, Id>> sequencedExpressions;\n\tfor (auto const& p: m_neededBy)\n\t\tfor (auto id: {p.first, p.second})\n\t\t\tif (unsigned seqNr = m_expressionClasses.representative(id).sequenceNumber)\n\t\t\t{\n\t\t\t\t// Invalid sequenced operation.\n\t\t\t\t// @todo quick fix for now. Proper fix needs to choose representative with higher\n\t\t\t\t// sequence number during dependency analysis.\n\t\t\t\tassertThrow(seqNr >= _initialSequenceNumber, StackTooDeepException, util::stackTooDeepString);\n\t\t\t\tsequencedExpressions.insert(std::make_pair(seqNr, id));\n\t\t\t}\n\n\t// Perform all operations on storage and memory in order, if they are needed.\n\tfor (auto const& seqAndId: sequencedExpressions)\n\t\tif (!m_classPositions.count(seqAndId.second))\n\t\t\tgenerateClassElement(seqAndId.second, true);\n\n\t// generate the target stack elements\n\tfor (auto const& targetItem: m_targetStack)\n\t{\n\t\tif (m_stack.count(targetItem.first) && m_stack.at(targetItem.first) == targetItem.second)\n\t\t\tcontinue; // already there\n\t\tgenerateClassElement(targetItem.second);\n\t\tassertThrow(!m_classPositions[targetItem.second].empty(), OptimizerException, \"\");\n\t\tif (m_classPositions[targetItem.second].count(targetItem.first))\n\t\t\tcontinue;\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\tif (m_expressionClasses.representative(targetItem.second).item)\n\t\t\tdebugData = m_expressionClasses.representative(targetItem.second).item->debugData();\n\t\tint position = classElementPosition(targetItem.second);\n\t\tif (position < targetItem.first)\n\t\t\t// it is already at its target, we need another copy\n\t\t\tappendDup(position, debugData);\n\t\telse\n\t\t\tappendOrRemoveSwap(position, debugData);\n\t\tappendOrRemoveSwap(targetItem.first, debugData);\n\t}\n\n\t// remove surplus elements\n\twhile (removeStackTopIfPossible())\n\t{\n\t\t// no-op\n\t}\n\n\t// check validity\n\tint finalHeight = 0;\n\tif (!m_targetStack.empty())\n\t\t// have target stack, so its height should be the final height\n\t\tfinalHeight = (--m_targetStack.end())->first;\n\telse if (!_initialStack.empty())\n\t\t// no target stack, only erase the initial stack\n\t\tfinalHeight = _initialStack.begin()->first - 1;\n\telse\n\t\t// neither initial no target stack, no change in height\n\t\tfinalHeight = _initialStackHeight;\n\tassertThrow(finalHeight == m_stackHeight, OptimizerException, \"Incorrect final stack height.\");\n\n\treturn m_generatedItems;\n}\n\nvoid CSECodeGenerator::addDependencies(Id _c)\n{\n\tif (m_classPositions.count(_c))\n\t\treturn; // it is already on the stack\n\tif (m_neededBy.find(_c) != m_neededBy.end())\n\t\treturn; // we already computed the dependencies for _c\n\tExpressionClasses::Expression expr = m_expressionClasses.representative(_c);\n\tassertThrow(expr.item, OptimizerException, \"\");\n\t// If this exception happens, we need to find a different way to generate the\n\t// compound expression.\n\tassertThrow(expr.item->type() != UndefinedItem, ItemNotAvailableException, \"Undefined item requested but not available.\");\n\tfor (Id argument: expr.arguments)\n\t{\n\t\taddDependencies(argument);\n\t\tm_neededBy.insert(std::make_pair(argument, _c));\n\t}\n\tif (expr.item && expr.item->type() == Operation && (\n\t\texpr.item->instruction() == Instruction::SLOAD ||\n\t\texpr.item->instruction() == Instruction::MLOAD ||\n\t\texpr.item->instruction() == Instruction::KECCAK256\n\t))\n\t{\n\t\t// this loads an unknown value from storage or memory and thus, in addition to its\n\t\t// arguments, depends on all store operations to addresses where we do not know that\n\t\t// they are different that occur before this load\n\t\tStoreOperation::Target target = expr.item->instruction() == Instruction::SLOAD ?\n\t\t\tStoreOperation::Storage : StoreOperation::Memory;\n\t\tId slotToLoadFrom = expr.arguments.at(0);\n\t\tfor (auto const& p: m_storeOperations)\n\t\t{\n\t\t\tif (p.first.first != target)\n\t\t\t\tcontinue;\n\t\t\tId slot = p.first.second;\n\t\t\tStoreOperations const& storeOps = p.second;\n\t\t\tif (storeOps.front().sequenceNumber > expr.sequenceNumber)\n\t\t\t\tcontinue;\n\t\t\tbool knownToBeIndependent = false;\n\t\t\tswitch (expr.item->instruction())\n\t\t\t{\n\t\t\tcase Instruction::SLOAD:\n\t\t\t\tknownToBeIndependent = m_expressionClasses.knownToBeDifferent(slot, slotToLoadFrom);\n\t\t\t\tbreak;\n\t\t\tcase Instruction::MLOAD:\n\t\t\t\tknownToBeIndependent = m_expressionClasses.knownToBeDifferentBy32(slot, slotToLoadFrom);\n\t\t\t\tbreak;\n\t\t\tcase Instruction::KECCAK256:\n\t\t\t{\n\t\t\t\tId length = expr.arguments.at(1);\n\t\t\t\tAssemblyItem offsetInstr(Instruction::SUB, expr.item->debugData());\n\t\t\t\tId offsetToStart = m_expressionClasses.find(offsetInstr, {slot, slotToLoadFrom});\n\t\t\t\tu256 const* o = m_expressionClasses.knownConstant(offsetToStart);\n\t\t\t\tu256 const* l = m_expressionClasses.knownConstant(length);\n\t\t\t\tif (l && *l == 0)\n\t\t\t\t\tknownToBeIndependent = true;\n\t\t\t\telse if (o)\n\t\t\t\t{\n\t\t\t\t\t// We could get problems here if both *o and *l are larger than 2**254\n\t\t\t\t\t// but it is probably ok for the optimizer to produce wrong code for such cases\n\t\t\t\t\t// which cannot be executed anyway because of the non-payable price.\n\t\t\t\t\tif (u2s(*o) <= -32)\n\t\t\t\t\t\tknownToBeIndependent = true;\n\t\t\t\t\telse if (l && u2s(*o) >= 0 && *o >= *l)\n\t\t\t\t\t\tknownToBeIndependent = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (knownToBeIndependent)\n\t\t\t\tcontinue;\n\n\t\t\t// note that store and load never have the same sequence number\n\t\t\tId latestStore = storeOps.front().expression;\n\t\t\tfor (auto it = ++storeOps.begin(); it != storeOps.end(); ++it)\n\t\t\t\tif (it->sequenceNumber < expr.sequenceNumber)\n\t\t\t\t\tlatestStore = it->expression;\n\t\t\taddDependencies(latestStore);\n\t\t\tm_neededBy.insert(std::make_pair(latestStore, _c));\n\t\t}\n\t}\n}\n\nvoid CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)\n{\n\tfor (auto const& it: m_classPositions)\n\t\tfor (int p: it.second)\n\t\t\tif (p > m_stackHeight)\n\t\t\t{\n\t\t\t\tassertThrow(false, OptimizerException, \"\");\n\t\t\t}\n\t// do some cleanup\n\tremoveStackTopIfPossible();\n\n\tif (m_classPositions.count(_c))\n\t{\n\t\tassertThrow(\n\t\t\t!m_classPositions[_c].empty(),\n\t\t\tOptimizerException,\n\t\t\t\"Element already removed but still needed.\"\n\t\t);\n\t\treturn;\n\t}\n\tExpressionClasses::Expression const& expr = m_expressionClasses.representative(_c);\n\tassertThrow(\n\t\t_allowSequenced || expr.sequenceNumber == 0,\n\t\tOptimizerException,\n\t\t\"Sequence constrained operation requested out of sequence.\"\n\t);\n\tassertThrow(expr.item, OptimizerException, \"Non-generated expression without item.\");\n\tassertThrow(\n\t\texpr.item->type() != UndefinedItem,\n\t\tOptimizerException,\n\t\t\"Undefined item requested but not available.\"\n\t);\n\tstd::vector<Id> const& arguments = expr.arguments;\n\tfor (Id arg: arguments | ranges::views::reverse)\n\t\tgenerateClassElement(arg);\n\n\tlangutil::DebugData::ConstPtr itemDebugData = expr.item->debugData();\n\t// The arguments are somewhere on the stack now, so it remains to move them at the correct place.\n\t// This is quite difficult as sometimes, the values also have to removed in this process\n\t// (if canBeRemoved() returns true) and the two arguments can be equal. For now, this is\n\t// implemented for every single case for combinations of up to two arguments manually.\n\tif (arguments.size() == 1)\n\t{\n\t\tif (canBeRemoved(arguments[0], _c))\n\t\t\tappendOrRemoveSwap(classElementPosition(arguments[0]), itemDebugData);\n\t\telse\n\t\t\tappendDup(classElementPosition(arguments[0]), itemDebugData);\n\t}\n\telse if (arguments.size() == 2)\n\t{\n\t\tif (canBeRemoved(arguments[1], _c))\n\t\t{\n\t\t\tappendOrRemoveSwap(classElementPosition(arguments[1]), itemDebugData);\n\t\t\tif (arguments[0] == arguments[1])\n\t\t\t\tappendDup(m_stackHeight, itemDebugData);\n\t\t\telse if (canBeRemoved(arguments[0], _c))\n\t\t\t{\n\t\t\t\tappendOrRemoveSwap(m_stackHeight - 1, itemDebugData);\n\t\t\t\tappendOrRemoveSwap(classElementPosition(arguments[0]), itemDebugData);\n\t\t\t}\n\t\t\telse\n\t\t\t\tappendDup(classElementPosition(arguments[0]), itemDebugData);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (arguments[0] == arguments[1])\n\t\t\t{\n\t\t\t\tappendDup(classElementPosition(arguments[0]), itemDebugData);\n\t\t\t\tappendDup(m_stackHeight, itemDebugData);\n\t\t\t}\n\t\t\telse if (canBeRemoved(arguments[0], _c))\n\t\t\t{\n\t\t\t\tappendOrRemoveSwap(classElementPosition(arguments[0]), itemDebugData);\n\t\t\t\tappendDup(classElementPosition(arguments[1]), itemDebugData);\n\t\t\t\tappendOrRemoveSwap(m_stackHeight - 1, itemDebugData);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tappendDup(classElementPosition(arguments[1]), itemDebugData);\n\t\t\t\tappendDup(classElementPosition(arguments[0]), itemDebugData);\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t\tassertThrow(\n\t\t\targuments.size() <= 2,\n\t\t\tOptimizerException,\n\t\t\t\"Opcodes with more than two arguments not implemented yet.\"\n\t\t);\n\tfor (size_t i = 0; i < arguments.size(); ++i)\n\t\tassertThrow(\n\t\t\tm_stack[m_stackHeight - static_cast<int>(i)] == arguments[i],\n\t\t\tOptimizerException,\n\t\t\t\"Expected arguments not present.\"\n\t\t);\n\n\twhile (SemanticInformation::isCommutativeOperation(*expr.item) &&\n\t\t\t!m_generatedItems.empty() &&\n\t\t\tm_generatedItems.back() == AssemblyItem(Instruction::SWAP1))\n\t\t// this will not append a swap but remove the one that is already there\n\t\tappendOrRemoveSwap(m_stackHeight - 1, itemDebugData);\n\tfor (size_t i = 0; i < arguments.size(); ++i)\n\t{\n\t\tm_classPositions[m_stack[m_stackHeight - static_cast<int>(i)]].erase(m_stackHeight - static_cast<int>(i));\n\t\tm_stack.erase(m_stackHeight - static_cast<int>(i));\n\t}\n\tappendItem(*expr.item);\n\tif (expr.item->type() != Operation || instructionInfo(expr.item->instruction(), m_evmVersion).ret == 1)\n\t{\n\t\tm_stack[m_stackHeight] = _c;\n\t\tm_classPositions[_c].insert(m_stackHeight);\n\t}\n\telse\n\t{\n\t\tassertThrow(\n\t\t\tinstructionInfo(expr.item->instruction(), m_evmVersion).ret == 0,\n\t\t\tOptimizerException,\n\t\t\t\"Invalid number of return values.\"\n\t\t);\n\t\tm_classPositions[_c]; // ensure it is created to mark the expression as generated\n\t}\n}\n\nint CSECodeGenerator::classElementPosition(Id _id) const\n{\n\tassertThrow(\n\t\tm_classPositions.count(_id) && !m_classPositions.at(_id).empty(),\n\t\tOptimizerException,\n\t\t\"Element requested but is not present.\"\n\t);\n\treturn *max_element(m_classPositions.at(_id).begin(), m_classPositions.at(_id).end());\n}\n\nbool CSECodeGenerator::canBeRemoved(Id _element, Id _result, int _fromPosition)\n{\n\t// Default for _fromPosition is the canonical position of the element.\n\tif (_fromPosition == c_invalidPosition)\n\t\t_fromPosition = classElementPosition(_element);\n\n\tbool haveCopy = m_classPositions.at(_element).size() > 1;\n\tif (m_finalClasses.count(_element))\n\t\t// It is part of the target stack. It can be removed if it is a copy that is not in the target position.\n\t\treturn haveCopy && (!m_targetStack.count(_fromPosition) || m_targetStack[_fromPosition] != _element);\n\telse if (!haveCopy)\n\t{\n\t\t// Can be removed unless it is needed by a class that has not been computed yet.\n\t\t// Note that m_classPositions also includes classes that were deleted in the meantime.\n\t\tauto range = m_neededBy.equal_range(_element);\n\t\tfor (auto it = range.first; it != range.second; ++it)\n\t\t\tif (it->second != _result && !m_classPositions.count(it->second))\n\t\t\t\treturn false;\n\t}\n\treturn true;\n}\n\nbool CSECodeGenerator::removeStackTopIfPossible()\n{\n\tif (m_stack.empty())\n\t\treturn false;\n\tassertThrow(m_stack.count(m_stackHeight) > 0, OptimizerException, \"\");\n\tId top = m_stack[m_stackHeight];\n\tif (!canBeRemoved(top, Id(-1), m_stackHeight))\n\t\treturn false;\n\tm_classPositions[m_stack[m_stackHeight]].erase(m_stackHeight);\n\tm_stack.erase(m_stackHeight);\n\tappendItem(AssemblyItem(Instruction::POP));\n\treturn true;\n}\n\nvoid CSECodeGenerator::appendDup(int _fromPosition, langutil::DebugData::ConstPtr _debugData)\n{\n\tassertThrow(_fromPosition != c_invalidPosition, OptimizerException, \"\");\n\tint reachableStackDepth = static_cast<int>(m_evmVersion.reachableStackDepth());\n\tint instructionNum = 1 + m_stackHeight - _fromPosition;\n\tassertThrow(instructionNum <= reachableStackDepth, StackTooDeepException, util::stackTooDeepString);\n\tassertThrow(1 <= instructionNum, OptimizerException, \"Invalid stack access.\");\n\tappendItem(AssemblyItem(dupInstruction(static_cast<unsigned>(instructionNum)), std::move(_debugData)));\n\tm_stack[m_stackHeight] = m_stack[_fromPosition];\n\tm_classPositions[m_stack[m_stackHeight]].insert(m_stackHeight);\n}\n\nvoid CSECodeGenerator::appendOrRemoveSwap(int _fromPosition, langutil::DebugData::ConstPtr _debugData)\n{\n\tassertThrow(_fromPosition != c_invalidPosition, OptimizerException, \"\");\n\tif (_fromPosition == m_stackHeight)\n\t\treturn;\n\tint reachableStackDepth = static_cast<int>(m_evmVersion.reachableStackDepth());\n\tint instructionNum = m_stackHeight - _fromPosition;\n\tassertThrow(instructionNum <= reachableStackDepth, StackTooDeepException, util::stackTooDeepString);\n\tassertThrow(1 <= instructionNum, OptimizerException, \"Invalid stack access.\");\n\tappendItem(AssemblyItem(swapInstruction(static_cast<unsigned>(instructionNum)), std::move(_debugData)));\n\n\tif (m_stack[m_stackHeight] != m_stack[_fromPosition])\n\t{\n\t\tm_classPositions[m_stack[m_stackHeight]].erase(m_stackHeight);\n\t\tm_classPositions[m_stack[m_stackHeight]].insert(_fromPosition);\n\t\tm_classPositions[m_stack[_fromPosition]].erase(_fromPosition);\n\t\tm_classPositions[m_stack[_fromPosition]].insert(m_stackHeight);\n\t\tstd::swap(m_stack[m_stackHeight], m_stack[_fromPosition]);\n\t}\n\tif (m_generatedItems.size() >= 2 &&\n\t\tSemanticInformation::isSwapInstruction(m_generatedItems.back()) &&\n\t\t*(m_generatedItems.end() - 2) == m_generatedItems.back())\n\t{\n\t\tm_generatedItems.pop_back();\n\t\tm_generatedItems.pop_back();\n\t}\n}\n\nvoid CSECodeGenerator::appendItem(AssemblyItem const& _item)\n{\n\tm_generatedItems.push_back(_item);\n\tm_stackHeight += static_cast<int>(_item.deposit());\n}\n"
  },
  {
    "path": "libevmasm/CommonSubexpressionEliminator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file CommonSubexpressionEliminator.h\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Optimizer step for common subexpression elimination and stack reorganisation.\n */\n\n#pragma once\n\n#include <map>\n#include <ostream>\n#include <set>\n#include <tuple>\n#include <unordered_map>\n#include <vector>\n#include <liblangutil/EVMVersion.h>\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/Exceptions.h>\n#include <libevmasm/ExpressionClasses.h>\n#include <libevmasm/SemanticInformation.h>\n#include <libevmasm/KnownState.h>\n\nnamespace langutil\n{\nstruct SourceLocation;\n}\n\nnamespace solidity::evmasm\n{\n\nclass AssemblyItem;\nusing AssemblyItems = std::vector<AssemblyItem>;\n\n/**\n * Optimizer step that performs common subexpression elimination and stack reorganisation,\n * i.e. it tries to infer equality among expressions and compute the values of two expressions\n * known to be equal only once.\n *\n * The general workings are that for each assembly item that is fed into the eliminator, an\n * equivalence class is derived from the operation and the equivalence class of its arguments.\n * DUPi, SWAPi and some arithmetic instructions are used to infer equivalences while these\n * classes are determined.\n *\n * When the list of optimized items is requested, they are generated in a bottom-up fashion,\n * adding code for equivalence classes that were not yet computed.\n */\nclass CommonSubexpressionEliminator\n{\npublic:\n\tusing Id = ExpressionClasses::Id;\n\tusing StoreOperation = KnownState::StoreOperation;\n\n\texplicit CommonSubexpressionEliminator(KnownState const& _state, langutil::EVMVersion _evmVersion):\n\t\tm_initialState(_state),\n\t\tm_state(_state),\n\t\tm_evmVersion(_evmVersion)\n\t{}\n\n\t/// Feeds AssemblyItems into the eliminator and @returns the iterator pointing at the first\n\t/// item that must be fed into a new instance of the eliminator.\n\t/// @param _msizeImportant if false, do not consider modification of MSIZE a side-effect\n\ttemplate <class AssemblyItemIterator>\n\tAssemblyItemIterator feedItems(AssemblyItemIterator _iterator, AssemblyItemIterator _end, bool _msizeImportant);\n\n\t/// @returns the resulting items after optimization.\n\tAssemblyItems getOptimizedItems();\n\nprivate:\n\t/// Feeds the item into the system for analysis.\n\tvoid feedItem(AssemblyItem const& _item, bool _copyItem = false);\n\n\t/// Tries to optimize the item that breaks the basic block at the end.\n\tvoid optimizeBreakingItem();\n\n\tKnownState m_initialState;\n\tKnownState m_state;\n\t/// Keeps information about which storage or memory slots were written to at which sequence\n\t/// number with what instruction.\n\tstd::vector<StoreOperation> m_storeOperations;\n\n\t/// The item that breaks the basic block, can be nullptr.\n\t/// It is usually appended to the block but can be optimized in some cases.\n\tAssemblyItem const* m_breakingItem = nullptr;\n\tlangutil::EVMVersion const m_evmVersion;\n};\n\n/**\n * Unit that generates code from current stack layout, target stack layout and information about\n * the equivalence classes.\n */\nclass CSECodeGenerator\n{\npublic:\n\tusing StoreOperation = CommonSubexpressionEliminator::StoreOperation;\n\tusing StoreOperations = std::vector<StoreOperation>;\n\tusing Id = ExpressionClasses::Id;\n\n\t/// Initializes the code generator with the given classes and store operations.\n\t/// The store operations have to be sorted by sequence number in ascending order.\n\tCSECodeGenerator(\n\t\tExpressionClasses& _expressionClasses,\n\t\tStoreOperations const& _storeOperations,\n\t\tlangutil::EVMVersion _evmVersion\n\t);\n\n\t/// @returns the assembly items generated from the given requirements\n\t/// @param _initialSequenceNumber starting sequence number, do not generate sequenced operations\n\t/// before this number.\n\t/// @param _initialStack current contents of the stack (up to stack height of zero)\n\t/// @param _targetStackContents final contents of the stack, by stack height relative to initial\n\t/// @note should only be called once on each object.\n\tAssemblyItems generateCode(\n\t\tunsigned _initialSequenceNumber,\n\t\tint _initialStackHeight,\n\t\tstd::map<int, Id> const& _initialStack,\n\t\tstd::map<int, Id> const& _targetStackContents\n\t);\n\nprivate:\n\t/// Recursively discovers all dependencies to @a m_requests.\n\tvoid addDependencies(Id _c);\n\n\t/// Produce code that generates the given element if it is not yet present.\n\t/// @param _allowSequenced indicates that sequence-constrained operations are allowed\n\tvoid generateClassElement(Id _c, bool _allowSequenced = false);\n\t/// @returns the position of the representative of the given id on the stack.\n\t/// @note throws an exception if it is not on the stack.\n\tint classElementPosition(Id _id) const;\n\n\t/// @returns true if the copy of @a _element can be removed from stack position _fromPosition\n\t/// - in general or, if given, while computing @a _result.\n\tbool canBeRemoved(Id _element, Id _result = Id(-1), int _fromPosition = c_invalidPosition);\n\n\t/// Appends code to remove the topmost stack element if it can be removed.\n\tbool removeStackTopIfPossible();\n\n\t/// Appends a dup instruction to m_generatedItems to retrieve the element at the given stack position.\n\tvoid appendDup(int _fromPosition,  langutil::DebugData::ConstPtr _debugData);\n\t/// Appends a swap instruction to m_generatedItems to retrieve the element at the given stack position.\n\t/// @note this might also remove the last item if it exactly the same swap instruction.\n\tvoid appendOrRemoveSwap(int _fromPosition,  langutil::DebugData::ConstPtr _debugData);\n\t/// Appends the given assembly item.\n\tvoid appendItem(AssemblyItem const& _item);\n\n\tstatic int const c_invalidPosition = -0x7fffffff;\n\n\tAssemblyItems m_generatedItems;\n\t/// Current height of the stack relative to the start.\n\tint m_stackHeight = 0;\n\t/// If (b, a) is in m_requests then b is needed to compute a.\n\tstd::unordered_multimap<Id, Id> m_neededBy;\n\t/// Current content of the stack.\n\tstd::map<int, Id> m_stack;\n\t/// Current positions of equivalence classes, equal to the empty set if already deleted.\n\tstd::unordered_map<Id, std::set<int>> m_classPositions;\n\n\t/// The actual equivalence class items and how to compute them.\n\tExpressionClasses& m_expressionClasses;\n\t/// Keeps information about which storage or memory slots were written to by which operations.\n\t/// The operations are sorted ascendingly by sequence number.\n\tstd::map<std::pair<StoreOperation::Target, Id>, StoreOperations> m_storeOperations;\n\t/// The set of equivalence classes that should be present on the stack at the end.\n\tstd::set<Id> m_finalClasses;\n\tstd::map<int, Id> m_targetStack;\n\tlangutil::EVMVersion const m_evmVersion;\n};\n\ntemplate <class AssemblyItemIterator>\nAssemblyItemIterator CommonSubexpressionEliminator::feedItems(\n\tAssemblyItemIterator _iterator,\n\tAssemblyItemIterator _end,\n\tbool _msizeImportant\n)\n{\n\tassertThrow(!m_breakingItem, OptimizerException, \"Invalid use of CommonSubexpressionEliminator.\");\n\tunsigned const maxChunkSize = 2000;\n\tunsigned chunkSize = 0;\n\tfor (\n\t\t;\n\t\t_iterator != _end && !SemanticInformation::breaksCSEAnalysisBlock(*_iterator, _msizeImportant) && chunkSize < maxChunkSize;\n\t\t++_iterator, ++chunkSize\n\t)\n\t\tfeedItem(*_iterator);\n\tif (_iterator != _end && chunkSize < maxChunkSize)\n\t\tm_breakingItem = &(*_iterator++);\n\treturn _iterator;\n}\n\n}\n"
  },
  {
    "path": "libevmasm/ConstantOptimiser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file ConstantOptimiser.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n */\n\n#include <libevmasm/ConstantOptimiser.h>\n#include <libevmasm/Assembly.h>\n#include <libevmasm/GasMeter.h>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\n\nunsigned ConstantOptimisationMethod::optimiseConstants(\n\tbool _isCreation,\n\tsize_t _runs,\n\tlangutil::EVMVersion _evmVersion,\n\tAssembly& _assembly\n)\n{\n\t// TODO: design the optimiser in a way this is not needed\n\tunsigned optimisations = 0;\n\tfor (auto& codeSection: _assembly.codeSections())\n\t{\n\t\tAssemblyItems& _items = codeSection.items;\n\n\t\tstd::map<AssemblyItem, size_t> pushes;\n\t\tfor (AssemblyItem const& item: _items)\n\t\t\tif (item.type() == Push)\n\t\t\t\tpushes[item]++;\n\t\tstd::map<u256, AssemblyItems> pendingReplacements;\n\t\tfor (auto it: pushes)\n\t\t{\n\t\t\tAssemblyItem const& item = it.first;\n\t\t\tif (item.data() < 0x100)\n\t\t\t\tcontinue;\n\t\t\tParams params;\n\t\t\tparams.multiplicity = it.second;\n\t\t\tparams.isCreation = _isCreation;\n\t\t\tparams.runs = _runs;\n\t\t\tparams.evmVersion = _evmVersion;\n\t\t\tLiteralMethod lit(params, item.data());\n\t\t\tbigint literalGas = lit.gasNeeded();\n\t\t\tCodeCopyMethod copy(params, item.data());\n\t\t\tbigint copyGas = copy.gasNeeded();\n\t\t\tComputeMethod compute(params, item.data());\n\t\t\tbigint computeGas = compute.gasNeeded();\n\t\t\tAssemblyItems replacement;\n\t\t\tif (copyGas < literalGas && copyGas < computeGas)\n\t\t\t{\n\t\t\t\treplacement = copy.execute(_assembly);\n\t\t\t\toptimisations++;\n\t\t\t}\n\t\t\telse if (computeGas < literalGas && computeGas <= copyGas)\n\t\t\t{\n\t\t\t\treplacement = compute.execute(_assembly);\n\t\t\t\toptimisations++;\n\t\t\t}\n\t\t\tif (!replacement.empty())\n\t\t\t\tpendingReplacements[item.data()] = replacement;\n\t\t}\n\t\tif (!pendingReplacements.empty())\n\t\t\treplaceConstants(_items, pendingReplacements);\n\t}\n\treturn optimisations;\n}\n\nbigint ConstantOptimisationMethod::simpleRunGas(AssemblyItems const& _items, langutil::EVMVersion _evmVersion)\n{\n\tbigint gas = 0;\n\tfor (AssemblyItem const& item: _items)\n\t\tif (item.type() == Push)\n\t\t\tgas += GasMeter::pushGas(item.data(), _evmVersion);\n\t\telse if (item.type() == Operation)\n\t\t{\n\t\t\tif (item.instruction() == Instruction::EXP)\n\t\t\t\tgas += GasCosts::expGas;\n\t\t\telse\n\t\t\t\tgas += GasMeter::runGas(item.instruction(), _evmVersion);\n\t\t}\n\treturn gas;\n}\n\nbigint ConstantOptimisationMethod::dataGas(bytes const& _data) const\n{\n\tassertThrow(_data.size() > 0, OptimizerException, \"Empty bytecode generated.\");\n\treturn bigint(GasMeter::dataGas(_data, m_params.isCreation, m_params.evmVersion));\n}\n\nsize_t ConstantOptimisationMethod::bytesRequired(AssemblyItems const& _items, langutil::EVMVersion _evmVersion)\n{\n\treturn evmasm::bytesRequired(_items, 3, _evmVersion, Precision::Approximate); // assume 3 byte addresses\n}\n\nvoid ConstantOptimisationMethod::replaceConstants(\n\tAssemblyItems& _items,\n\tstd::map<u256, AssemblyItems> const& _replacements\n)\n{\n\tAssemblyItems replaced;\n\tfor (AssemblyItem const& item: _items)\n\t{\n\t\tif (item.type() == Push)\n\t\t{\n\t\t\tauto it = _replacements.find(item.data());\n\t\t\tif (it != _replacements.end())\n\t\t\t{\n\t\t\t\treplaced += it->second;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\treplaced.push_back(item);\n\t}\n\t_items = std::move(replaced);\n}\n\nbigint LiteralMethod::gasNeeded() const\n{\n\treturn combineGas(\n\t\tsimpleRunGas({Instruction::PUSH1}, m_params.evmVersion),\n\t\t// PUSHX plus data\n\t\t(m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas) + dataGas(toCompactBigEndian(m_value, 1)),\n\t\t0\n\t);\n}\n\nAssemblyItems LiteralMethod::execute(Assembly&) const\n{\n\treturn {};\n}\n\nbigint CodeCopyMethod::gasNeeded() const\n{\n\treturn combineGas(\n\t\t// Run gas: we ignore memory increase costs\n\t\tsimpleRunGas(copyRoutine(), m_params.evmVersion) + GasCosts::copyGas,\n\t\t// Data gas for copy routines: Some bytes are zero, but we ignore them.\n\t\tbytesRequired(copyRoutine(), m_params.evmVersion) * (m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas),\n\t\t// Data gas for data itself\n\t\tdataGas(toBigEndian(m_value))\n\t);\n}\n\nAssemblyItems CodeCopyMethod::execute(Assembly& _assembly) const\n{\n\tbytes data = toBigEndian(m_value);\n\tassertThrow(data.size() == 32, OptimizerException, \"Invalid number encoding.\");\n\tAssemblyItem newPushData = _assembly.newData(data);\n\treturn copyRoutine(&newPushData);\n}\n\nAssemblyItems CodeCopyMethod::copyRoutine(AssemblyItem* _pushData) const\n{\n\tif (_pushData)\n\t\tassertThrow(_pushData->type() == PushData, OptimizerException, \"Invalid Assembly Item.\");\n\n\tAssemblyItem dataUsed = _pushData ? *_pushData : AssemblyItem(PushData, u256(1) << 16);\n\n\t// PUSH0 is cheaper than PUSHn/DUP/SWAP.\n\tif (m_params.evmVersion.hasPush0())\n\t{\n\t\t// This costs ~29 gas.\n\t\tAssemblyItems copyRoutine{\n\t\t\t// back up memory\n\t\t\t// mload(0)\n\t\t\tu256(0),\n\t\t\tInstruction::MLOAD,\n\n\t\t\t// codecopy(0, <offset>, 32)\n\t\t\tu256(32),\n\t\t\tdataUsed,\n\t\t\tu256(0),\n\t\t\tInstruction::CODECOPY,\n\n\t\t\t// mload(0)\n\t\t\tu256(0),\n\t\t\tInstruction::MLOAD,\n\n\t\t\t// restore original memory\n\t\t\t// mstore(0, x)\n\t\t\tInstruction::SWAP1,\n\t\t\tu256(0),\n\t\t\tInstruction::MSTORE\n\t\t};\n\t\treturn copyRoutine;\n\t}\n\telse\n\t{\n\t\t// This costs ~33 gas.\n\t\tAssemblyItems copyRoutine{\n\t\t\t// constant to be reused 3+ times\n\t\t\tu256(0),\n\n\t\t\t// back up memory\n\t\t\t// mload(0)\n\t\t\tInstruction::DUP1,\n\t\t\tInstruction::MLOAD,\n\n\t\t\t// codecopy(0, <offset>, 32)\n\t\t\tu256(32),\n\t\t\tdataUsed,\n\t\t\tInstruction::DUP4,\n\t\t\tInstruction::CODECOPY,\n\n\t\t\t// mload(0)\n\t\t\tInstruction::DUP2,\n\t\t\tInstruction::MLOAD,\n\n\t\t\t// restore original memory\n\t\t\t// mstore(0, x)\n\t\t\tInstruction::SWAP2,\n\t\t\tInstruction::MSTORE\n\t\t};\n\t\treturn copyRoutine;\n\t}\n}\n\nComputeMethod::ComputeMethod(Params const& _params, u256 const& _value):\n\tConstantOptimisationMethod(_params, _value)\n{\n\tm_routine = findRepresentation(m_value);\n\tassertThrow(\n\t\tcheckRepresentation(m_value, m_routine),\n\t\tOptimizerException,\n\t\t\"Invalid constant expression created.\"\n\t);\n}\nComputeMethod::~ComputeMethod() = default;\n\nAssemblyItems ComputeMethod::execute(Assembly&) const\n{\n\treturn m_routine;\n}\n\nAssemblyItems ComputeMethod::findRepresentation(u256 const& _value)\n{\n\tif (_value < 0x10000)\n\t\t// Very small value, not worth computing\n\t\treturn AssemblyItems{_value};\n\telse if (numberEncodingSize(~_value) < numberEncodingSize(_value))\n\t\t// Negated is shorter to represent\n\t\treturn findRepresentation(~_value) + AssemblyItems{Instruction::NOT};\n\telse\n\t{\n\t\t// Decompose value into a * 2**k + b where abs(b) << 2**k\n\t\t// Is not always better, try literal and decomposition method.\n\t\tAssemblyItems routine{u256(_value)};\n\t\tbigint bestGas = gasNeeded(routine);\n\t\tfor (unsigned bits = 255; bits > 8 && m_maxSteps > 0; --bits)\n\t\t{\n\t\t\tunsigned gapDetector = unsigned((_value >> (bits - 8)) & 0x1ff);\n\t\t\tif (gapDetector != 0xff && gapDetector != 0x100)\n\t\t\t\tcontinue;\n\n\t\t\tu256 powerOfTwo = u256(1) << bits;\n\t\t\tu256 upperPart = _value >> bits;\n\t\t\tbigint lowerPart = _value & (powerOfTwo - 1);\n\t\t\tif ((powerOfTwo - lowerPart) < lowerPart)\n\t\t\t{\n\t\t\t\tlowerPart = lowerPart - powerOfTwo; // make it negative\n\t\t\t\tupperPart++;\n\t\t\t}\n\t\t\tif (upperPart == 0)\n\t\t\t\tcontinue;\n\t\t\tif (abs(lowerPart) >= (powerOfTwo >> 8))\n\t\t\t\tcontinue;\n\n\t\t\tAssemblyItems newRoutine;\n\t\t\tif (lowerPart != 0)\n\t\t\t\tnewRoutine += findRepresentation(u256(abs(lowerPart)));\n\t\t\tif (m_params.evmVersion.hasBitwiseShifting())\n\t\t\t{\n\t\t\t\tnewRoutine += findRepresentation(upperPart);\n\t\t\t\tnewRoutine += AssemblyItems{u256(bits), Instruction::SHL};\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnewRoutine += AssemblyItems{u256(bits), u256(2), Instruction::EXP};\n\t\t\t\tif (upperPart != 1)\n\t\t\t\t\tnewRoutine += findRepresentation(upperPart) + AssemblyItems{Instruction::MUL};\n\t\t\t}\n\t\t\tif (lowerPart > 0)\n\t\t\t\tnewRoutine += AssemblyItems{Instruction::ADD};\n\t\t\telse if (lowerPart < 0)\n\t\t\t\tnewRoutine.push_back(Instruction::SUB);\n\n\t\t\tif (m_maxSteps > 0)\n\t\t\t\tm_maxSteps--;\n\t\t\tbigint newGas = gasNeeded(newRoutine);\n\t\t\tif (newGas < bestGas)\n\t\t\t{\n\t\t\t\tbestGas = std::move(newGas);\n\t\t\t\troutine = std::move(newRoutine);\n\t\t\t}\n\t\t}\n\t\treturn routine;\n\t}\n}\n\nbool ComputeMethod::checkRepresentation(u256 const& _value, AssemblyItems const& _routine) const\n{\n\t// This is a tiny EVM that can only evaluate some instructions.\n\tstd::vector<u256> stack;\n\tfor (AssemblyItem const& item: _routine)\n\t{\n\t\tswitch (item.type())\n\t\t{\n\t\tcase Operation:\n\t\t{\n\t\t\tif (stack.size() < item.arguments())\n\t\t\t\treturn false;\n\t\t\tu256* sp = &stack.back();\n\t\t\tswitch (item.instruction())\n\t\t\t{\n\t\t\tcase Instruction::MUL:\n\t\t\t\tsp[-1] = sp[0] * sp[-1];\n\t\t\t\tbreak;\n\t\t\tcase Instruction::EXP:\n\t\t\t\tif (sp[-1] > 0xff)\n\t\t\t\t\treturn false;\n\t\t\t\tsp[-1] = boost::multiprecision::pow(sp[0], unsigned(sp[-1]));\n\t\t\t\tbreak;\n\t\t\tcase Instruction::ADD:\n\t\t\t\tsp[-1] = sp[0] + sp[-1];\n\t\t\t\tbreak;\n\t\t\tcase Instruction::SUB:\n\t\t\t\tsp[-1] = sp[0] - sp[-1];\n\t\t\t\tbreak;\n\t\t\tcase Instruction::NOT:\n\t\t\t\tsp[0] = ~sp[0];\n\t\t\t\tbreak;\n\t\t\tcase Instruction::SHL:\n\t\t\t\tassertThrow(\n\t\t\t\t\tm_params.evmVersion.hasBitwiseShifting(),\n\t\t\t\t\tOptimizerException,\n\t\t\t\t\t\"Shift generated for invalid EVM version.\"\n\t\t\t\t);\n\t\t\t\tassertThrow(sp[0] <= u256(255), OptimizerException, \"Invalid shift generated.\");\n\t\t\t\tsp[-1] = u256(bigint(sp[-1]) << unsigned(sp[0]));\n\t\t\t\tbreak;\n\t\t\tcase Instruction::SHR:\n\t\t\t\tassertThrow(\n\t\t\t\t\tm_params.evmVersion.hasBitwiseShifting(),\n\t\t\t\t\tOptimizerException,\n\t\t\t\t\t\"Shift generated for invalid EVM version.\"\n\t\t\t\t);\n\t\t\t\tassertThrow(sp[0] <= u256(255), OptimizerException, \"Invalid shift generated.\");\n\t\t\t\tsp[-1] = sp[-1] >> unsigned(sp[0]);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tstack.resize(stack.size() + item.deposit());\n\t\t\tbreak;\n\t\t}\n\t\tcase Push:\n\t\t\tstack.push_back(item.data());\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn stack.size() == 1 && stack.front() == _value;\n}\n\nbigint ComputeMethod::gasNeeded(AssemblyItems const& _routine) const\n{\n\tauto numExps = static_cast<size_t>(count(_routine.begin(), _routine.end(), Instruction::EXP));\n\treturn combineGas(\n\t\tsimpleRunGas(_routine, m_params.evmVersion) + numExps * (GasCosts::expGas + GasCosts::expByteGas(m_params.evmVersion)),\n\t\t// Data gas for routine: Some bytes are zero, but we ignore them.\n\t\tbytesRequired(_routine, m_params.evmVersion) * (m_params.isCreation ? GasCosts::txDataNonZeroGas(m_params.evmVersion) : GasCosts::createDataGas),\n\t\t0\n\t);\n}\n"
  },
  {
    "path": "libevmasm/ConstantOptimiser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file ConstantOptimiser.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n */\n\n#pragma once\n\n#include <libevmasm/Exceptions.h>\n\n#include <liblangutil/EVMVersion.h>\n\n#include <libsolutil/Numeric.h>\n#include <libsolutil/Assertions.h>\n\n#include <vector>\n\nnamespace solidity::evmasm\n{\n\nclass AssemblyItem;\nusing AssemblyItems = std::vector<AssemblyItem>;\nclass Assembly;\n\n/**\n * Abstract base class for one way to change how constants are represented in the code.\n */\nclass ConstantOptimisationMethod\n{\npublic:\n\t/// Tries to optimised how constants are represented in the source code and modifies\n\t/// @a _assembly.\n\t/// @returns zero if no optimisations could be performed.\n\tstatic unsigned optimiseConstants(\n\t\tbool _isCreation,\n\t\tsize_t _runs,\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tAssembly& _assembly\n\t);\n\nprotected:\n\t/// This is the public API for the optimiser methods, but it doesn't need to be exposed to the caller.\n\n\tstruct Params\n\t{\n\t\tbool isCreation; ///< Whether this is called during contract creation or runtime.\n\t\tsize_t runs; ///< Estimated number of calls per opcode oven the lifetime of the contract.\n\t\tsize_t multiplicity; ///< Number of times the constant appears in the code.\n\t\tlangutil::EVMVersion evmVersion; ///< Version of the EVM\n\t};\n\n\texplicit ConstantOptimisationMethod(Params const& _params, u256 const& _value):\n\t\tm_params(_params), m_value(_value) {}\n\tvirtual ~ConstantOptimisationMethod() = default;\n\tvirtual bigint gasNeeded() const = 0;\n\t/// Executes the method, potentially appending to the assembly and returns a vector of\n\t/// assembly items the constant should be replaced with in one sweep.\n\t/// If the vector is empty, the constants will not be deleted.\n\tvirtual AssemblyItems execute(Assembly& _assembly) const = 0;\n\nprotected:\n\t/// @returns the run gas for the given items ignoring special gas costs\n\tstatic bigint simpleRunGas(AssemblyItems const& _items, langutil::EVMVersion _evmVersion);\n\t/// @returns the gas needed to store the given data literally\n\tbigint dataGas(bytes const& _data) const;\n\tstatic size_t bytesRequired(AssemblyItems const& _items, langutil::EVMVersion _evmVersion);\n\t/// @returns the combined estimated gas usage taking @a m_params into account.\n\tbigint combineGas(\n\t\tbigint const& _runGas,\n\t\tbigint const& _repeatedDataGas,\n\t\tbigint const& _uniqueDataGas\n\t) const\n\t{\n\t\t// _runGas is not multiplied by _multiplicity because the runs are \"per opcode\"\n\t\treturn m_params.runs * _runGas + m_params.multiplicity * _repeatedDataGas + _uniqueDataGas;\n\t}\n\n\t/// Replaces all constants i by the code given in @a _replacement[i].\n\tstatic void replaceConstants(AssemblyItems& _items, std::map<u256, AssemblyItems> const& _replacements);\n\n\tParams m_params;\n\tu256 const& m_value;\n};\n\n/**\n * Optimisation method that pushes the constant to the stack literally. This is the default method,\n * i.e. executing it does not alter the Assembly.\n */\nclass LiteralMethod: public ConstantOptimisationMethod\n{\npublic:\n\texplicit LiteralMethod(Params const& _params, u256 const& _value):\n\t\tConstantOptimisationMethod(_params, _value) {}\n\tbigint gasNeeded() const override;\n\tAssemblyItems execute(Assembly&) const override;\n};\n\n/**\n * Method that stores the data in the .data section of the code and copies it to the stack.\n */\nclass CodeCopyMethod: public ConstantOptimisationMethod\n{\npublic:\n\texplicit CodeCopyMethod(Params const& _params, u256 const& _value):\n\t\tConstantOptimisationMethod(_params, _value) {}\n\tbigint gasNeeded() const override;\n\tAssemblyItems execute(Assembly& _assembly) const override;\n\nprotected:\n\tAssemblyItems copyRoutine(AssemblyItem* _pushData = nullptr) const;\n};\n\n/**\n * Method that tries to compute the constant.\n */\nclass ComputeMethod: public ConstantOptimisationMethod\n{\npublic:\n\tComputeMethod(Params const& _params, u256 const& _value);\n\t~ComputeMethod() override;\n\n\tbigint gasNeeded() const override { return gasNeeded(m_routine); }\n\tAssemblyItems execute(Assembly&) const override;\n\nprotected:\n\t/// Tries to recursively find a way to compute @a _value.\n\tAssemblyItems findRepresentation(u256 const& _value);\n\t/// Recomputes the value from the calculated representation and checks for correctness.\n\tbool checkRepresentation(u256 const& _value, AssemblyItems const& _routine) const;\n\tbigint gasNeeded(AssemblyItems const& _routine) const;\n\n\t/// Counter for the complexity of optimization, will stop when it reaches zero.\n\tsize_t m_maxSteps = 10000;\n\tAssemblyItems m_routine;\n};\n\n}\n"
  },
  {
    "path": "libevmasm/ControlFlowGraph.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file ControlFlowGraph.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Control flow analysis for the optimizer.\n */\n\n#include <libevmasm/ControlFlowGraph.h>\n#include <map>\n#include <memory>\n#include <algorithm>\n#include <libevmasm/Exceptions.h>\n#include <libevmasm/AssemblyItem.h>\n#include <libevmasm/SemanticInformation.h>\n#include <libevmasm/KnownState.h>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\n\nBlockId::BlockId(u256 const& _id):\n\tm_id(unsigned(_id))\n{\n\tassertThrow( _id < initial().m_id, OptimizerException, \"Tag number too large.\");\n}\n\nBasicBlocks ControlFlowGraph::optimisedBlocks()\n{\n\tif (m_items.empty())\n\t\treturn BasicBlocks();\n\n\tfindLargestTag();\n\tsplitBlocks();\n\tresolveNextLinks();\n\tremoveUnusedBlocks();\n\tsetPrevLinks();\n\tgatherKnowledge();\n\n\treturn rebuildCode();\n}\n\nvoid ControlFlowGraph::findLargestTag()\n{\n\tm_lastUsedId = 0;\n\tfor (auto const& item: m_items)\n\t\tif (item.type() == Tag || item.type() == PushTag)\n\t\t{\n\t\t\t// Assert that it can be converted.\n\t\t\tBlockId(item.data());\n\t\t\tm_lastUsedId = std::max(unsigned(item.data()), m_lastUsedId);\n\t\t}\n}\n\nvoid ControlFlowGraph::splitBlocks()\n{\n\tm_blocks.clear();\n\tBlockId id = BlockId::initial();\n\tm_blocks[id].begin = 0;\n\tfor (size_t index = 0; index < m_items.size(); ++index)\n\t{\n\t\tAssemblyItem const& item = m_items.at(index);\n\t\tif (item.type() == Tag)\n\t\t{\n\t\t\tif (id)\n\t\t\t\tm_blocks[id].end = static_cast<unsigned>(index);\n\t\t\tid = BlockId::invalid();\n\t\t}\n\t\tif (!id)\n\t\t{\n\t\t\tid = item.type() == Tag ? BlockId(item.data()) : generateNewId();\n\t\t\tm_blocks[id].begin = static_cast<unsigned>(index);\n\t\t}\n\t\tif (item.type() == PushTag)\n\t\t\tm_blocks[id].pushedTags.emplace_back(item.data());\n\t\tif (SemanticInformation::altersControlFlow(item))\n\t\t{\n\t\t\tm_blocks[id].end = static_cast<unsigned>(index + 1);\n\t\t\tif (item == Instruction::JUMP)\n\t\t\t\tm_blocks[id].endType = BasicBlock::EndType::JUMP;\n\t\t\telse if (item == Instruction::JUMPI)\n\t\t\t\tm_blocks[id].endType = BasicBlock::EndType::JUMPI;\n\t\t\telse\n\t\t\t\tm_blocks[id].endType = BasicBlock::EndType::STOP;\n\t\t\tid = BlockId::invalid();\n\t\t}\n\t}\n\tif (id)\n\t{\n\t\tm_blocks[id].end = static_cast<unsigned>(m_items.size());\n\t\tif (m_blocks[id].endType == BasicBlock::EndType::HANDOVER)\n\t\t\tm_blocks[id].endType = BasicBlock::EndType::STOP;\n\t}\n}\n\nvoid ControlFlowGraph::resolveNextLinks()\n{\n\tstd::map<unsigned, BlockId> blockByBeginPos;\n\tfor (auto const& idAndBlock: m_blocks)\n\t\tif (idAndBlock.second.begin != idAndBlock.second.end)\n\t\t\tblockByBeginPos[idAndBlock.second.begin] = idAndBlock.first;\n\n\tfor (auto& idAndBlock: m_blocks)\n\t{\n\t\tBasicBlock& block = idAndBlock.second;\n\t\tswitch (block.endType)\n\t\t{\n\t\tcase BasicBlock::EndType::JUMPI:\n\t\tcase BasicBlock::EndType::HANDOVER:\n\t\t\tassertThrow(\n\t\t\t\tblockByBeginPos.count(block.end),\n\t\t\t\tOptimizerException,\n\t\t\t\t\"Successor block not found.\"\n\t\t\t);\n\t\t\tblock.next = blockByBeginPos.at(block.end);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nvoid ControlFlowGraph::removeUnusedBlocks()\n{\n\tstd::vector<BlockId> blocksToProcess{BlockId::initial()};\n\tstd::set<BlockId> neededBlocks{BlockId::initial()};\n\twhile (!blocksToProcess.empty())\n\t{\n\t\tBasicBlock const& block = m_blocks.at(blocksToProcess.back());\n\t\tblocksToProcess.pop_back();\n\t\tfor (BlockId tag: block.pushedTags)\n\t\t\tif (!neededBlocks.count(tag) && m_blocks.count(tag))\n\t\t\t{\n\t\t\t\tneededBlocks.insert(tag);\n\t\t\t\tblocksToProcess.push_back(tag);\n\t\t\t}\n\t\tif (block.next && !neededBlocks.count(block.next))\n\t\t{\n\t\t\tneededBlocks.insert(block.next);\n\t\t\tblocksToProcess.push_back(block.next);\n\t\t}\n\t}\n\tfor (auto it = m_blocks.begin(); it != m_blocks.end();)\n\t\tif (neededBlocks.count(it->first))\n\t\t\t++it;\n\t\telse\n\t\t\tm_blocks.erase(it++);\n}\n\nvoid ControlFlowGraph::setPrevLinks()\n{\n\tfor (auto& idAndBlock: m_blocks)\n\t{\n\t\tBasicBlock& block = idAndBlock.second;\n\t\tswitch (block.endType)\n\t\t{\n\t\tcase BasicBlock::EndType::JUMPI:\n\t\tcase BasicBlock::EndType::HANDOVER:\n\t\t\tassertThrow(\n\t\t\t\t!m_blocks.at(block.next).prev,\n\t\t\t\tOptimizerException,\n\t\t\t\t\"Successor already has predecessor.\"\n\t\t\t);\n\t\t\tm_blocks[block.next].prev = idAndBlock.first;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\t// If block ends with jump to not yet linked block, link them removing the jump\n\tfor (auto& idAndBlock: m_blocks)\n\t{\n\t\tBlockId blockId = idAndBlock.first;\n\t\tBasicBlock& block = idAndBlock.second;\n\t\tif (block.endType != BasicBlock::EndType::JUMP || block.end - block.begin < 2)\n\t\t\tcontinue;\n\t\tAssemblyItem const& push = m_items.at(block.end - 2);\n\t\tif (push.type() != PushTag)\n\t\t\tcontinue;\n\t\tBlockId nextId(push.data());\n\t\tif (m_blocks.count(nextId) && m_blocks.at(nextId).prev)\n\t\t\tcontinue;\n\t\tbool hasLoop = false;\n\t\tfor (BlockId id = nextId; id && m_blocks.count(id) && !hasLoop; id = m_blocks.at(id).next)\n\t\t\thasLoop = (id == blockId);\n\t\tif (hasLoop || !m_blocks.count(nextId))\n\t\t\tcontinue;\n\n\t\tm_blocks[nextId].prev = blockId;\n\t\tblock.next = nextId;\n\t\tblock.end -= 2;\n\t\tassertThrow(\n\t\t\t!block.pushedTags.empty() && block.pushedTags.back() == nextId,\n\t\t\tOptimizerException,\n\t\t\t\"Last pushed tag not at end of pushed list.\"\n\t\t);\n\t\tblock.pushedTags.pop_back();\n\t\tblock.endType = BasicBlock::EndType::HANDOVER;\n\t}\n}\n\nvoid ControlFlowGraph::gatherKnowledge()\n{\n\t// @todo actually we know that memory is filled with zeros at the beginning,\n\t// we could make use of that.\n\tKnownStatePointer emptyState = std::make_shared<KnownState>();\n\tbool unknownJumpEncountered = false;\n\n\tstruct WorkQueueItem {\n\t\tBlockId blockId;\n\t\tKnownStatePointer state;\n\t\tstd::set<BlockId> blocksSeen;\n\t};\n\n\tstd::vector<WorkQueueItem> workQueue{WorkQueueItem{BlockId::initial(), emptyState->copy(), std::set<BlockId>()}};\n\tauto addWorkQueueItem = [&](WorkQueueItem const& _currentItem, BlockId _to, KnownStatePointer const& _state)\n\t{\n\t\tWorkQueueItem item;\n\t\titem.blockId = _to;\n\t\titem.state = _state->copy();\n\t\titem.blocksSeen = _currentItem.blocksSeen;\n\t\titem.blocksSeen.insert(_currentItem.blockId);\n\t\tworkQueue.push_back(std::move(item));\n\t};\n\n\twhile (!workQueue.empty())\n\t{\n\t\tWorkQueueItem item = std::move(workQueue.back());\n\t\tworkQueue.pop_back();\n\t\t//@todo we might have to do something like incrementing the sequence number for each JUMPDEST\n\t\tassertThrow(!!item.blockId, OptimizerException, \"\");\n\t\tif (!m_blocks.count(item.blockId))\n\t\t\tcontinue; // too bad, we do not know the tag, probably an invalid jump\n\t\tBasicBlock& block = m_blocks.at(item.blockId);\n\t\tKnownStatePointer state = item.state;\n\t\tif (block.startState)\n\t\t{\n\t\t\t// We call reduceToCommonKnowledge even in the non-join setting to get the correct\n\t\t\t// sequence number\n\t\t\tif (!m_joinKnowledge)\n\t\t\t\tstate->reset();\n\t\t\tstate->reduceToCommonKnowledge(*block.startState, !item.blocksSeen.count(item.blockId));\n\t\t\tif (*state == *block.startState)\n\t\t\t\tcontinue;\n\t\t}\n\n\t\tblock.startState = state->copy();\n\n\t\t// Feed all items except for the final jump yet because it will erase the target tag.\n\t\tunsigned pc = block.begin;\n\t\twhile (pc < block.end && !SemanticInformation::altersControlFlow(m_items.at(pc)))\n\t\t\tstate->feedItem(m_items.at(pc++));\n\n\t\tif (\n\t\t\tblock.endType == BasicBlock::EndType::JUMP ||\n\t\t\tblock.endType == BasicBlock::EndType::JUMPI\n\t\t)\n\t\t{\n\t\t\tassertThrow(block.begin <= pc && pc == block.end - 1, OptimizerException, \"\");\n\t\t\t//@todo in the case of JUMPI, add knowledge about the condition to the state\n\t\t\t// (for both values of the condition)\n\t\t\tstd::set<u256> tags = state->tagsInExpression(\n\t\t\t\tstate->stackElement(state->stackHeight(), langutil::DebugData::create())\n\t\t\t);\n\t\t\tstate->feedItem(m_items.at(pc++));\n\n\t\t\tif (tags.empty())\n\t\t\t{\n\t\t\t\tif (!unknownJumpEncountered)\n\t\t\t\t{\n\t\t\t\t\t// We do not know the target of this jump, so we have to reset the states of all\n\t\t\t\t\t// JUMPDESTs.\n\t\t\t\t\tunknownJumpEncountered = true;\n\t\t\t\t\tfor (auto const& it: m_blocks)\n\t\t\t\t\t\tif (it.second.begin < it.second.end && m_items[it.second.begin].type() == Tag)\n\t\t\t\t\t\t\tworkQueue.push_back(WorkQueueItem{it.first, emptyState->copy(), std::set<BlockId>()});\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tfor (auto tag: tags)\n\t\t\t\t\taddWorkQueueItem(item, BlockId(tag), state);\n\t\t}\n\t\telse if (block.begin <= pc && pc < block.end)\n\t\t\tstate->feedItem(m_items.at(pc++));\n\t\tassertThrow(block.end <= block.begin || pc == block.end, OptimizerException, \"\");\n\n\t\tblock.endState = state;\n\n\t\tif (\n\t\t\tblock.endType == BasicBlock::EndType::HANDOVER ||\n\t\t\tblock.endType == BasicBlock::EndType::JUMPI\n\t\t)\n\t\t\taddWorkQueueItem(item, block.next, state);\n\t}\n\n\t// Remove all blocks we never visited here. This might happen because a tag is pushed but\n\t// never used for a JUMP.\n\t// Note that this invalidates some contents of pushedTags\n\tfor (auto it = m_blocks.begin(); it != m_blocks.end();)\n\t\tif (!it->second.startState)\n\t\t\tit = m_blocks.erase(it);\n\t\telse\n\t\t\tit++;\n}\n\nBasicBlocks ControlFlowGraph::rebuildCode()\n{\n\tstd::map<BlockId, unsigned> pushes;\n\tfor (auto& idAndBlock: m_blocks)\n\t\tfor (BlockId ref: idAndBlock.second.pushedTags)\n\t\t\tif (m_blocks.count(ref))\n\t\t\t\tpushes[ref]++;\n\n\tstd::set<BlockId> blocksToAdd;\n\tfor (auto it: m_blocks)\n\t\tblocksToAdd.insert(it.first);\n\tstd::set<BlockId> blocksAdded;\n\tBasicBlocks blocks;\n\n\tfor (\n\t\tBlockId blockId = BlockId::initial();\n\t\tblockId;\n\t\tblockId = blocksToAdd.empty() ? BlockId::invalid() : *blocksToAdd.begin()\n\t)\n\t{\n\t\tbool previousHandedOver = (blockId == BlockId::initial());\n\t\twhile (m_blocks.at(blockId).prev)\n\t\t\tblockId = m_blocks.at(blockId).prev;\n\t\tfor (; blockId; blockId = m_blocks.at(blockId).next)\n\t\t{\n\t\t\tBasicBlock& block = m_blocks.at(blockId);\n\t\t\tblocksToAdd.erase(blockId);\n\t\t\tblocksAdded.insert(blockId);\n\n\t\t\tif (block.begin == block.end)\n\t\t\t\tcontinue;\n\t\t\t// If block starts with unused tag, skip it.\n\t\t\tif (previousHandedOver && !pushes[blockId] && m_items[block.begin].type() == Tag)\n\t\t\t\t++block.begin;\n\t\t\tif (block.begin < block.end)\n\t\t\t{\n\t\t\t\tblocks.push_back(block);\n\t\t\t\tblocks.back().startState->clearTagUnions();\n\t\t\t\tblocks.back().endState->clearTagUnions();\n\t\t\t}\n\t\t\tpreviousHandedOver = (block.endType == BasicBlock::EndType::HANDOVER);\n\t\t}\n\t}\n\n\treturn blocks;\n}\n\nBlockId ControlFlowGraph::generateNewId()\n{\n\tBlockId id = BlockId(++m_lastUsedId);\n\tassertThrow(id < BlockId::initial(), OptimizerException, \"Out of block IDs.\");\n\treturn id;\n}\n"
  },
  {
    "path": "libevmasm/ControlFlowGraph.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file ControlFlowGraph.h\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Control flow analysis for the optimizer.\n */\n\n#pragma once\n\n#include <libsolutil/Common.h>\n#include <libsolutil/Assertions.h>\n#include <libevmasm/ExpressionClasses.h>\n\n#include <vector>\n#include <memory>\n#include <limits>\n\nnamespace solidity::evmasm\n{\n\nclass KnownState;\nusing KnownStatePointer = std::shared_ptr<KnownState>;\n\n/**\n * Identifier for a block, coincides with the tag number of an AssemblyItem but adds a special\n * ID for the initial block.\n */\nclass BlockId\n{\npublic:\n\tBlockId() { *this = invalid(); }\n\texplicit BlockId(unsigned _id): m_id(_id) {}\n\texplicit BlockId(u256 const& _id);\n\tstatic BlockId initial() { return BlockId(std::numeric_limits<unsigned>::max() - 1); }\n\tstatic BlockId invalid() { return BlockId(std::numeric_limits<unsigned>::max()); }\n\n\tbool operator==(BlockId const& _other) const { return m_id == _other.m_id; }\n\tbool operator!=(BlockId const& _other) const { return m_id != _other.m_id; }\n\tbool operator<(BlockId const& _other) const { return m_id < _other.m_id; }\n\texplicit operator bool() const { return *this != invalid(); }\n\nprivate:\n\tunsigned m_id;\n};\n\n/**\n * Control flow block inside which instruction counter is always incremented by one\n * (except for possibly the last instruction).\n */\nstruct BasicBlock\n{\n\t/// Start index into assembly item list.\n\tunsigned begin = 0;\n\t/// End index (excluded) inte assembly item list.\n\tunsigned end = 0;\n\t/// Tags pushed inside this block, with multiplicity.\n\tstd::vector<BlockId> pushedTags;\n\t/// ID of the block that always follows this one (either non-branching part of JUMPI or flow\n\t/// into new block), or BlockId::invalid() otherwise\n\tBlockId next = BlockId::invalid();\n\t/// ID of the block that has to precede this one (because control flows into it).\n\tBlockId prev = BlockId::invalid();\n\n\tenum class EndType { JUMP, JUMPI, STOP, HANDOVER };\n\tEndType endType = EndType::HANDOVER;\n\n\t/// Knowledge about the state when this block is entered. Intersection of all possible ways\n\t/// to enter this block.\n\tKnownStatePointer startState;\n\t/// Knowledge about the state at the end of this block.\n\tKnownStatePointer endState;\n};\n\nusing BasicBlocks = std::vector<BasicBlock>;\n\n/**\n * Control flow graph optimizer.\n * ASSUMES THAT WE ONLY JUMP TO TAGS THAT WERE PREVIOUSLY PUSHED. THIS IS NOT TRUE ANYMORE\n * NOW THAT FUNCTION TAGS CAN BE STORED IN STORAGE.\n */\nclass ControlFlowGraph\n{\npublic:\n\t/// Initializes the control flow graph.\n\t/// @a _items has to persist across the usage of this class.\n\t/// @a _joinKnowledge if true, reduces state knowledge to common base at the join of two paths\n\texplicit ControlFlowGraph(AssemblyItems const& _items, bool _joinKnowledge = true):\n\t\tm_items(_items),\n\t\tm_joinKnowledge(_joinKnowledge)\n\t{}\n\t/// @returns vector of basic blocks in the order they should be used in the final code.\n\t/// Should be called only once.\n\tBasicBlocks optimisedBlocks();\n\nprivate:\n\tvoid findLargestTag();\n\tvoid splitBlocks();\n\tvoid resolveNextLinks();\n\tvoid removeUnusedBlocks();\n\tvoid gatherKnowledge();\n\tvoid setPrevLinks();\n\tBasicBlocks rebuildCode();\n\n\tBlockId generateNewId();\n\n\tunsigned m_lastUsedId = 0;\n\tAssemblyItems const& m_items;\n\tbool m_joinKnowledge = true;\n\tstd::map<BlockId, BasicBlock> m_blocks;\n};\n\n\n}\n"
  },
  {
    "path": "libevmasm/Disassemble.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libevmasm/Disassemble.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/CommonIO.h>\n#include <functional>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::evmasm;\n\n\nvoid solidity::evmasm::eachInstruction(\n\tbytes const& _mem,\n\tlangutil::EVMVersion _evmVersion,\n\tstd::function<void(Instruction,u256 const&)> const& _onInstruction\n)\n{\n\tfor (auto it = _mem.begin(); it < _mem.end(); ++it)\n\t{\n\t\tInstruction const instr{*it};\n\t\tint additional = 0;\n\t\tif (isValidInstruction(instr))\n\t\t\tadditional = instructionInfo(instr, _evmVersion).additional;\n\n\t\tu256 data{};\n\n\t\t// fill the data with the additional data bytes from the instruction stream\n\t\twhile (additional > 0 && std::next(it) < _mem.end())\n\t\t{\n\t\t\tdata <<= 8;\n\t\t\tdata |= *++it;\n\t\t\t--additional;\n\t\t}\n\n\t\t// pad the remaining number of additional octets with zeros\n\t\tdata <<= 8 * additional;\n\n\t\t_onInstruction(instr, data);\n\t}\n}\n\nstd::string solidity::evmasm::disassemble(bytes const& _mem, langutil::EVMVersion _evmVersion, std::string const& _delimiter)\n{\n\tstd::stringstream ret;\n\teachInstruction(_mem, _evmVersion, [&](Instruction _instr, u256 const& _data) {\n\t\tif (!isValidInstruction(_instr))\n\t\t\tret << \"0x\" << std::uppercase << std::hex << static_cast<int>(_instr) << _delimiter;\n\t\telse\n\t\t{\n\t\t\tInstructionInfo info = instructionInfo(_instr, _evmVersion);\n\t\t\tret << info.name;\n\t\t\tif (info.additional)\n\t\t\t\tret << \" 0x\" << std::uppercase << std::hex << _data;\n\t\t\tret << _delimiter;\n\t\t}\n\t});\n\treturn ret.str();\n}\n"
  },
  {
    "path": "libevmasm/Disassemble.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/Common.h>\n#include <libsolutil/Numeric.h>\n\n#include <libevmasm/Instruction.h>\n\n#include <functional>\n#include <string>\n\nnamespace solidity::evmasm\n{\n\n/// Iterate through EVM code and call a function on each instruction.\nvoid eachInstruction(bytes const& _mem, langutil::EVMVersion _evmVersion, std::function<void(Instruction, u256 const&)> const& _onInstruction);\n\n/// Convert from EVM code to simple EVM assembly language.\nstd::string disassemble(bytes const& _mem, langutil::EVMVersion _evmVersion, std::string const& _delimiter = \" \");\n\n}\n"
  },
  {
    "path": "libevmasm/EVMAssemblyStack.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libevmasm/EVMAssemblyStack.h>\n\n#include <libsolutil/JSON.h>\n#include <liblangutil/Exceptions.h>\n#include <libsolidity/codegen/CompilerContext.h>\n\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/transform.hpp>\n\n#include <tuple>\n\nusing namespace solidity::util;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nnamespace solidity::evmasm\n{\n\nvoid EVMAssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string const& _source)\n{\n\tJson assemblyJson;\n\tsolRequire(jsonParseStrict(_source, assemblyJson), AssemblyImportException, \"Could not parse JSON file.\");\n\tanalyze(_sourceName, assemblyJson);\n}\n\nvoid EVMAssemblyStack::analyze(std::string const& _sourceName, Json const& _assemblyJson)\n{\n\tsolAssert(!m_evmAssembly);\n\tm_name = _sourceName;\n\tstd::tie(m_evmAssembly, m_sourceList) = evmasm::Assembly::fromJSON(_assemblyJson, {}, 0, m_eofVersion);\n\tsolRequire(m_evmAssembly != nullptr, AssemblyImportException, \"Could not create evm assembly object.\");\n}\n\nvoid EVMAssemblyStack::assemble()\n{\n\tsolAssert(m_evmAssembly);\n\tsolAssert(m_evmAssembly->isCreation());\n\tsolAssert(!m_evmRuntimeAssembly);\n\n\tm_evmAssembly->optimise(m_optimiserSettings);\n\tm_object = m_evmAssembly->assemble();\n\t// TODO: Check for EOF\n\tsolAssert(m_evmAssembly->codeSections().size() == 1);\n\tm_sourceMapping = AssemblyItem::computeSourceMapping(m_evmAssembly->codeSections().front().items, sourceIndices());\n\tif (m_evmAssembly->numSubs() > 0)\n\t{\n\t\tm_evmRuntimeAssembly = std::make_shared<evmasm::Assembly>(m_evmAssembly->sub(SubAssemblyID{0}));\n\t\tsolAssert(m_evmRuntimeAssembly && !m_evmRuntimeAssembly->isCreation());\n\t\t// TODO: Check for EOF\n\t\tsolAssert(m_evmRuntimeAssembly->codeSections().size() == 1);\n\t\tm_runtimeSourceMapping = AssemblyItem::computeSourceMapping(m_evmRuntimeAssembly->codeSections().front().items, sourceIndices());\n\t\tm_runtimeObject = m_evmRuntimeAssembly->assemble();\n\t}\n}\n\nLinkerObject const& EVMAssemblyStack::object(std::string const& _contractName) const\n{\n\tsolAssert(_contractName == m_name);\n\treturn object();\n}\n\nLinkerObject const& EVMAssemblyStack::runtimeObject(std::string const& _contractName) const\n{\n\tsolAssert(_contractName == m_name);\n\treturn runtimeObject();\n}\n\nstd::map<std::string, unsigned> EVMAssemblyStack::sourceIndices() const\n{\n\tsolAssert(m_evmAssembly);\n\treturn m_sourceList\n\t\t| ranges::views::enumerate\n\t\t| ranges::views::transform([](auto const& _source) { return std::make_pair(_source.second, _source.first); })\n\t\t| ranges::to<std::map<std::string, unsigned>>;\n}\n\nstd::string const* EVMAssemblyStack::sourceMapping(std::string const& _contractName) const\n{\n\tsolAssert(_contractName == m_name);\n\treturn &sourceMapping();\n}\n\nstd::string const* EVMAssemblyStack::runtimeSourceMapping(std::string const& _contractName) const\n{\n\tsolAssert(_contractName == m_name);\n\treturn &runtimeSourceMapping();\n}\n\nJson EVMAssemblyStack::ethdebug(std::string const& _contractName) const\n{\n\tsolAssert(_contractName == m_name);\n\tsolAssert(m_ethdebug != nullptr);\n\treturn *m_ethdebug;\n}\n\nJson EVMAssemblyStack::ethdebugRuntime(std::string const& _contractName) const\n{\n\tsolAssert(_contractName == m_name);\n\tsolAssert(m_ethdebugRuntime != nullptr);\n\treturn *m_ethdebugRuntime;\n}\n\nJson EVMAssemblyStack::ethdebug() const\n{\n\treturn {};\n}\n\nJson EVMAssemblyStack::assemblyJSON() const\n{\n\tsolAssert(m_evmAssembly);\n\treturn m_evmAssembly->assemblyJSON(sourceIndices());\n}\n\nJson EVMAssemblyStack::assemblyJSON(std::string const& _contractName) const\n{\n\tsolAssert(_contractName == m_name);\n\treturn assemblyJSON();\n}\n\nstd::string EVMAssemblyStack::assemblyString(StringMap const& _sourceCodes) const\n{\n\tsolAssert(m_evmAssembly);\n\treturn m_evmAssembly->assemblyString(m_debugInfoSelection, _sourceCodes);\n}\n\nstd::string EVMAssemblyStack::assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const\n{\n\tsolAssert(_contractName == m_name);\n\treturn assemblyString(_sourceCodes);\n}\n\nstd::string const EVMAssemblyStack::filesystemFriendlyName(std::string const& _contractName) const\n{\n\tsolAssert(_contractName == m_name);\n\treturn m_name;\n}\n\nstd::vector<std::string> EVMAssemblyStack::sourceNames() const\n{\n\treturn m_sourceList;\n}\n\n} // namespace solidity::evmasm\n"
  },
  {
    "path": "libevmasm/EVMAssemblyStack.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libevmasm/AbstractAssemblyStack.h>\n#include <libevmasm/Assembly.h>\n#include <libevmasm/LinkerObject.h>\n\n#include <libsolutil/JSON.h>\n\n#include <map>\n#include <string>\n#include <utility>\n\nnamespace solidity::evmasm\n{\n\nclass EVMAssemblyStack: public AbstractAssemblyStack\n{\npublic:\n\texplicit EVMAssemblyStack(\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tAssembly::OptimiserSettings _optimiserSettings\n\t):\n\t\tm_evmVersion(_evmVersion),\n\t\tm_eofVersion(_eofVersion),\n\t\tm_optimiserSettings(std::move(_optimiserSettings))\n\t{}\n\n\t/// Runs parsing and analysis steps.\n\t/// Multiple calls overwrite the previous state.\n\t/// @throws AssemblyImportException, if JSON could not be validated.\n\tvoid parseAndAnalyze(std::string const& _sourceName, std::string const& _source);\n\n\t/// Runs analysis steps.\n\t/// Multiple calls overwrite the previous state.\n\t/// @throws AssemblyImportException, if JSON could not be validated.\n\tvoid analyze(std::string const& _sourceName, Json const& _assemblyJson);\n\n\tvoid assemble();\n\n\tstd::string const& name() const { return m_name; }\n\n\tLinkerObject const& object() const { return m_object; }\n\tLinkerObject const& object(std::string const& _contractName) const override;\n\tLinkerObject const& runtimeObject() const { return m_runtimeObject; }\n\tLinkerObject const& runtimeObject(std::string const& _contractName) const override;\n\n\tstd::shared_ptr<evmasm::Assembly> const& evmAssembly() const { return m_evmAssembly; }\n\tstd::shared_ptr<evmasm::Assembly> const& evmRuntimeAssembly() const { return m_evmRuntimeAssembly; }\n\n\tstd::string const& sourceMapping() const { return m_sourceMapping; }\n\tstd::string const* sourceMapping(std::string const& _contractName) const override;\n\tstd::string const& runtimeSourceMapping() const { return m_runtimeSourceMapping; }\n\tstd::string const* runtimeSourceMapping(std::string const& _contractName) const override;\n\n\tJson ethdebug(std::string const& _contractName) const override;\n\tJson ethdebugRuntime(std::string const& _contractName) const override;\n\tJson ethdebug() const override;\n\n\tJson assemblyJSON() const;\n\tJson assemblyJSON(std::string const& _contractName) const override;\n\tstd::string assemblyString(StringMap const& _sourceCodes) const;\n\tstd::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const override;\n\n\tstd::string const filesystemFriendlyName(std::string const& _contractName) const override;\n\n\tstd::vector<std::string> contractNames() const override { return {m_name}; }\n\tstd::vector<std::string> sourceNames() const override;\n\tstd::map<std::string, unsigned> sourceIndices() const;\n\n\tbool compilationSuccessful() const override { return m_evmAssembly != nullptr; }\n\n\tvoid selectDebugInfo(langutil::DebugInfoSelection _debugInfoSelection)\n\t{\n\t\tm_debugInfoSelection = _debugInfoSelection;\n\t}\n\nprivate:\n\tlangutil::EVMVersion m_evmVersion;\n\tstd::optional<uint8_t> m_eofVersion;\n\tAssembly::OptimiserSettings m_optimiserSettings;\n\tstd::string m_name;\n\tstd::shared_ptr<evmasm::Assembly> m_evmAssembly;\n\tstd::shared_ptr<evmasm::Assembly> m_evmRuntimeAssembly;\n\tevmasm::LinkerObject m_object; ///< Deployment object (includes the runtime sub-object).\n\tevmasm::LinkerObject m_runtimeObject; ///< Runtime object.\n\tstd::vector<std::string> m_sourceList;\n\tlangutil::DebugInfoSelection m_debugInfoSelection = langutil::DebugInfoSelection::Default();\n\tstd::string m_sourceMapping;\n\tstd::string m_runtimeSourceMapping;\n\tstd::unique_ptr<Json> m_ethdebug;\n\tstd::unique_ptr<Json> m_ethdebugRuntime;\n};\n\n} // namespace solidity::evmasm\n"
  },
  {
    "path": "libevmasm/Ethdebug.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libevmasm/Ethdebug.h>\n\n#include <libevmasm/EthdebugSchema.h>\n\n#include <range/v3/algorithm/any_of.hpp>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::evmasm::ethdebug;\n\nnamespace\n{\n\nschema::program::Instruction::Operation instructionOperation(Assembly const& _assembly, LinkerObject const& _linkerObject, size_t const _start, size_t const _end)\n{\n\tsolAssert(_end <= _linkerObject.bytecode.size());\n\tsolAssert(_start < _end);\n\tschema::program::Instruction::Operation operation;\n\toperation.mnemonic = instructionInfo(static_cast<Instruction>(_linkerObject.bytecode[_start]), _assembly.evmVersion()).name;\n\tstatic size_t constexpr instructionSize = 1;\n\tif (_start + instructionSize < _end)\n\t{\n\t\tbytes const argumentData(\n\t\t\t_linkerObject.bytecode.begin() + static_cast<std::ptrdiff_t>(_start) + instructionSize,\n\t\t\t_linkerObject.bytecode.begin() + static_cast<std::ptrdiff_t>(_end)\n\t\t);\n\t\tsolAssert(!argumentData.empty());\n\t\toperation.arguments = {{schema::data::HexValue{argumentData}}};\n\t}\n\treturn operation;\n}\n\nschema::materials::SourceRange::Range locationRange(langutil::SourceLocation const& _location)\n{\n\treturn {\n\t\t.length = schema::data::Unsigned{_location.end - _location.start},\n\t\t.offset = schema::data::Unsigned{_location.start}\n\t};\n}\n\nschema::materials::Reference sourceReference(unsigned _sourceID)\n{\n\treturn {\n\t\t.id = schema::materials::ID{_sourceID},\n\t\t.type = std::nullopt\n\t};\n}\n\nstd::optional<schema::program::Context> instructionContext(Assembly::CodeSection const& _codeSection, size_t _assemblyItemIndex, unsigned _sourceID)\n{\n\tsolAssert(_assemblyItemIndex < _codeSection.items.size());\n\tlangutil::SourceLocation const& location = _codeSection.items.at(_assemblyItemIndex).location();\n\tif (!location.isValid())\n\t\treturn std::nullopt;\n\n\treturn schema::program::Context{\n\t\tschema::materials::SourceRange{\n\t\t\t.source = sourceReference(_sourceID),\n\t\t\t.range = locationRange(location)\n\t\t},\n\t\tstd::nullopt,\n\t\tstd::nullopt\n\t};\n}\n\nstd::vector<schema::program::Instruction> codeSectionInstructions(Assembly const& _assembly, LinkerObject const& _linkerObject, unsigned const _sourceID, size_t const _codeSectionIndex)\n{\n\tsolAssert(_codeSectionIndex < _linkerObject.codeSectionLocations.size());\n\tsolAssert(_codeSectionIndex < _assembly.codeSections().size());\n\tauto const& locations = _linkerObject.codeSectionLocations[_codeSectionIndex];\n\tauto const& codeSection = _assembly.codeSections().at(_codeSectionIndex);\n\n\tstd::vector<schema::program::Instruction> instructions;\n\tinstructions.reserve(codeSection.items.size());\n\n\tbool const codeSectionContainsVerbatim = ranges::any_of(\n\t\tcodeSection.items,\n\t\t[](auto const& _instruction) { return _instruction.type() == VerbatimBytecode; }\n\t);\n\tsolUnimplementedAssert(!codeSectionContainsVerbatim, \"Verbatim bytecode is currently not supported by ethdebug.\");\n\n\tfor (auto const& currentInstruction: locations.instructionLocations)\n\t{\n\t\tsize_t const start = currentInstruction.start;\n\t\tsize_t const end = currentInstruction.end;\n\n\t\t// some instructions do not contribute to the bytecode\n\t\tif (start == end)\n\t\t\tcontinue;\n\n\t\tinstructions.emplace_back(schema::program::Instruction{\n\t\t\t.offset = schema::data::Unsigned{start},\n\t\t\t.operation = instructionOperation(_assembly, _linkerObject, start, end),\n\t\t\t.context = instructionContext(codeSection, currentInstruction.assemblyItemIndex, _sourceID)\n\t\t});\n\t}\n\n\treturn instructions;\n}\n\nstd::vector<schema::program::Instruction> programInstructions(Assembly const& _assembly, LinkerObject const& _linkerObject, unsigned const _sourceID)\n{\n\tauto const numCodeSections = _assembly.codeSections().size();\n\tsolAssert(numCodeSections == _linkerObject.codeSectionLocations.size());\n\n\tstd::vector<schema::program::Instruction> instructionInfo;\n\tfor (size_t codeSectionIndex = 0; codeSectionIndex < numCodeSections; ++codeSectionIndex)\n\t\tinstructionInfo += codeSectionInstructions(_assembly, _linkerObject, _sourceID, codeSectionIndex);\n\treturn instructionInfo;\n}\n\n} // anonymous namespace\n\nJson ethdebug::program(std::string_view _name, unsigned _sourceID, Assembly const& _assembly, LinkerObject const& _linkerObject)\n{\n\treturn schema::Program{\n\t\t.compilation = std::nullopt,\n\t\t.contract = {\n\t\t\t.name = std::string{_name},\n\t\t\t.definition = {\n\t\t\t\t.source = {\n\t\t\t\t\t.id = {_sourceID},\n\t\t\t\t\t.type = std::nullopt\n\t\t\t\t},\n\t\t\t\t.range = std::nullopt\n\t\t\t}\n\t\t},\n\t\t.environment = _assembly.isCreation() ? schema::Program::Environment::CREATE : schema::Program::Environment::CALL,\n\t\t.context = std::nullopt,\n\t\t.instructions = programInstructions(_assembly, _linkerObject, _sourceID)\n\t};\n}\n\nJson ethdebug::resources(std::vector<std::string> const& _sources, std::string const& _version)\n{\n\tJson sources = Json::array();\n\tfor (size_t id = 0; id < _sources.size(); ++id)\n\t{\n\t\tJson source = Json::object();\n\t\tsource[\"id\"] = id;\n\t\tsource[\"path\"] = _sources[id];\n\t\tsources.push_back(source);\n\t}\n\tJson result = Json::object();\n\tresult[\"compilation\"] = Json::object();\n\tresult[\"compilation\"][\"compiler\"] = Json::object();\n\tresult[\"compilation\"][\"compiler\"][\"name\"] = \"solc\";\n\tresult[\"compilation\"][\"compiler\"][\"version\"] = _version;\n\tresult[\"compilation\"][\"sources\"] = sources;\n\treturn result;\n}\n"
  },
  {
    "path": "libevmasm/Ethdebug.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/JSON.h>\n\n#include <libevmasm/Assembly.h>\n#include <libevmasm/LinkerObject.h>\n\nnamespace solidity::evmasm::ethdebug\n{\n\n// returns ethdebug/format/program.\nJson program(std::string_view _name, unsigned _sourceID, Assembly const& _assembly, LinkerObject const& _linkerObject);\n\n// returns ethdebug/format/info/resources\nJson resources(std::vector<std::string> const& _sources, std::string const& _version);\n\n} // namespace solidity::evmasm::ethdebug\n"
  },
  {
    "path": "libevmasm/EthdebugSchema.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libevmasm/EthdebugSchema.h>\n\n#include <libsolutil/Numeric.h>\n#include <libsolutil/Visitor.h>\n\nusing namespace solidity;\nusing namespace solidity::evmasm::ethdebug;\n\nvoid schema::data::to_json(Json& _json, HexValue const& _hexValue)\n{\n\t_json = util::toHex(_hexValue.value, util::HexPrefix::Add);\n}\n\nvoid schema::data::to_json(Json& _json, Unsigned const& _unsigned)\n{\n\tstd::visit(util::GenericVisitor{\n\t\t[&](HexValue const& _hexValue) { _json = _hexValue; },\n\t\t[&](std::uint64_t const _value) { _json = _value; }\n\t}, _unsigned.value);\n}\n\nvoid schema::materials::to_json(Json& _json, ID const& _id)\n{\n\tstd::visit(util::GenericVisitor{\n\t\t[&](std::string const& _hexValue) { _json = _hexValue; },\n\t\t[&](std::uint64_t const _value) { _json = _value; }\n\t}, _id.value);\n}\n\nvoid schema::materials::to_json(Json& _json, Reference const& _source)\n{\n\t_json[\"id\"] = _source.id;\n\tif (_source.type)\n\t\t_json[\"type\"] = *_source.type == Reference::Type::Compilation ? \"compilation\" : \"source\";\n}\n\nvoid schema::materials::to_json(Json& _json, SourceRange::Range const& _range)\n{\n\t_json[\"length\"] = _range.length;\n\t_json[\"offset\"] = _range.offset;\n}\n\n\nvoid schema::materials::to_json(Json& _json, SourceRange const& _sourceRange)\n{\n\t_json[\"source\"] = _sourceRange.source;\n\tif (_sourceRange.range)\n\t\t_json[\"range\"] = *_sourceRange.range;\n}\n\nvoid schema::to_json(Json& _json, Program::Contract const& _contract)\n{\n\tif (_contract.name)\n\t\t_json[\"name\"] = *_contract.name;\n\t_json[\"definition\"] = _contract.definition;\n}\n\nvoid schema::program::to_json(Json& _json, Context::Variable const& _contextVariable)\n{\n\tauto const numProperties =\n\t\t_contextVariable.identifier.has_value() +\n\t\t_contextVariable.declaration.has_value();\n\tsolRequire(numProperties >= 1, EthdebugException, \"Context variable has no properties.\");\n\tif (_contextVariable.identifier)\n\t{\n\t\tsolRequire(!_contextVariable.identifier->empty(), EthdebugException, \"Variable identifier must not be empty.\");\n\t\t_json[\"identifier\"] = *_contextVariable.identifier;\n\t}\n\tif (_contextVariable.declaration)\n\t\t_json[\"declaration\"] = *_contextVariable.declaration;\n}\n\nvoid schema::program::to_json(Json& _json, Context const& _context)\n{\n\tsolRequire(_context.code.has_value() + _context.remark.has_value() + _context.variables.has_value() >= 1, EthdebugException, \"Context needs >=1 properties.\");\n\tif (_context.code)\n\t\t_json[\"code\"] = *_context.code;\n\tif (_context.variables)\n\t{\n\t\tsolRequire(!_context.variables->empty(), EthdebugException, \"Context variables must not be empty if provided.\");\n\t\t_json[\"variables\"] = *_context.variables;\n\t}\n\tif (_context.remark)\n\t\t_json[\"remark\"] = *_context.remark;\n}\n\nvoid schema::program::to_json(Json& _json, Instruction::Operation const& _operation)\n{\n\t_json = { {\"mnemonic\", _operation.mnemonic} };\n\tif (!_operation.arguments.empty())\n\t\t_json[\"arguments\"] = _operation.arguments;\n}\n\nvoid schema::program::to_json(Json& _json, Instruction const& _instruction)\n{\n\t_json[\"offset\"] = _instruction.offset;\n\tif (_instruction.operation)\n\t\t_json[\"operation\"] = *_instruction.operation;\n\tif (_instruction.context)\n\t\t_json[\"context\"] = *_instruction.context;\n}\n\nvoid schema::to_json(Json& _json, Program const& _program)\n{\n\tif (_program.compilation)\n\t\t_json[\"compilation\"] = *_program.compilation;\n\t_json[\"contract\"] = _program.contract;\n\t_json[\"environment\"] = _program.environment;\n\tif (_program.context)\n\t\t_json[\"context\"] = *_program.context;\n\t_json[\"instructions\"] = _program.instructions;\n}\n\nvoid schema::to_json(Json& _json, Program::Environment const& _environment)\n{\n\tswitch (_environment)\n\t{\n\tcase Program::Environment::CALL:\n\t\t_json = \"call\";\n\t\tbreak;\n\tcase Program::Environment::CREATE:\n\t\t_json = \"create\";\n\t\tbreak;\n\t}\n}\n"
  },
  {
    "path": "libevmasm/EthdebugSchema.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/Common.h>\n#include <libsolutil/JSON.h>\n\n#include <concepts>\n#include <optional>\n#include <variant>\n#include <vector>\n\nnamespace solidity::evmasm::ethdebug::schema\n{\n\nstruct EthdebugException: virtual util::Exception {};\n\nnamespace data\n{\n\nstruct HexValue\n{\n\tbytes value;\n};\n\nstruct Unsigned\n{\n\ttemplate<std::unsigned_integral T>\n\tUnsigned(T const _value)\n\t{\n\t\tsolRequire(static_cast<T>(_value) <= std::numeric_limits<std::uint64_t>::max(), EthdebugException, \"Too large value.\");\n\t\tvalue = static_cast<std::uint64_t>(_value);\n\t}\n\ttemplate<std::signed_integral T>\n\tUnsigned(T const _value)\n\t{\n\t\tsolRequire(_value >= 0, EthdebugException, \"NonNegativeValue got negative value.\");\n\t\tsolRequire(static_cast<std::make_unsigned_t<T>>(_value) <= std::numeric_limits<std::uint64_t>::max(), EthdebugException, \"Too large value.\");\n\t\tvalue = static_cast<std::uint64_t>(_value);\n\t}\n\tUnsigned(HexValue&& _value): value(std::move(_value)) {}\n\n\tstd::variant<std::uint64_t, HexValue> value;\n};\n\n}\n\nnamespace materials\n{\n\nstruct ID\n{\n\tstd::variant<std::string, std::uint64_t> value;\n};\n\nstruct Reference\n{\n\tenum class Type { Compilation, Source };\n\tID id;\n\tstd::optional<Type> type;\n};\n\nstruct SourceRange\n{\n\tstruct Range\n\t{\n\t\tdata::Unsigned length;\n\t\tdata::Unsigned offset;\n\t};\n\n\tReference source;\n\tstd::optional<Range> range;\n};\n\n}\n\nnamespace program\n{\n\nstruct Context\n{\n\tstruct Variable\n\t{\n\t\tstd::optional<std::string> identifier;\n\t\tstd::optional<materials::SourceRange> declaration;\n\t\t// TODO: type\n\t\t// TODO: pointer according to ethdebug/format/spec/pointer\n\t};\n\n\tstd::optional<materials::SourceRange> code;\n\tstd::optional<std::vector<Variable>> variables;\n\tstd::optional<std::string> remark;\n};\n\nstruct Instruction\n{\n\tstruct Operation\n\t{\n\t\tstd::string mnemonic;\n\t\tstd::vector<data::Unsigned> arguments;\n\t};\n\n\tdata::Unsigned offset;\n\tstd::optional<Operation> operation;\n\tstd::optional<Context> context;\n};\n\n}\n\nstruct Program\n{\n\tenum class Environment\n\t{\n\t\tCALL, CREATE\n\t};\n\n\tstruct Contract\n\t{\n\t\tstd::optional<std::string> name;\n\t\tmaterials::SourceRange definition;\n\t};\n\n\tstd::optional<materials::Reference> compilation;\n\tContract contract;\n\tEnvironment environment;\n\tstd::optional<program::Context> context;\n\tstd::vector<program::Instruction> instructions;\n};\n\nnamespace data\n{\nvoid to_json(Json& _json, HexValue const& _hexValue);\nvoid to_json(Json& _json, Unsigned const& _unsigned);\n}\n\nnamespace materials\n{\nvoid to_json(Json& _json, ID const& _id);\nvoid to_json(Json& _json, Reference const& _source);\nvoid to_json(Json& _json, SourceRange::Range const& _range);\nvoid to_json(Json& _json, SourceRange const& _sourceRange);\n}\n\nnamespace program\n{\nvoid to_json(Json& _json, Context::Variable const& _contextVariable);\nvoid to_json(Json& _json, Context const& _context);\nvoid to_json(Json& _json, Instruction::Operation const& _operation);\nvoid to_json(Json& _json, Instruction const& _instruction);\n}\n\nvoid to_json(Json& _json, Program::Contract const& _contract);\nvoid to_json(Json& _json, Program::Environment const& _environment);\nvoid to_json(Json& _json, Program const& _program);\n\n}\n"
  },
  {
    "path": "libevmasm/Exceptions.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file Exceptions.h\n * @author Christian <c@ethdev.com>\n * @date 2014\n */\n\n#pragma once\n\n#include <libsolutil/Exceptions.h>\n\nnamespace solidity::evmasm\n{\n\nstruct AssemblyException: virtual util::Exception {};\nstruct AssemblyImportException: virtual AssemblyException {};\nstruct OptimizerException: virtual AssemblyException {};\nstruct StackTooDeepException: virtual OptimizerException {};\nstruct ItemNotAvailableException: virtual OptimizerException {};\n\n}\n"
  },
  {
    "path": "libevmasm/ExpressionClasses.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file ExpressionClasses.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Container for equivalence classes of expressions for use in common subexpression elimination.\n */\n\n#include <libevmasm/ExpressionClasses.h>\n\n#include <libevmasm/Assembly.h>\n#include <libevmasm/CommonSubexpressionEliminator.h>\n#include <libevmasm/SimplificationRules.h>\n\n#include <boost/container_hash/hash.hpp>\n\n#include <functional>\n#include <limits>\n#include <tuple>\n#include <utility>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::langutil;\n\nbool ExpressionClasses::Expression::operator==(ExpressionClasses::Expression const& _other) const\n{\n\tassertThrow(!!item && !!_other.item, OptimizerException, \"\");\n\tauto type = item->type();\n\tauto otherType = _other.item->type();\n\tif (type != otherType)\n\t\treturn false;\n\telse if (type == Operation)\n\t{\n\t\tauto instr = item->instruction();\n\t\tauto otherInstr = _other.item->instruction();\n\t\treturn std::tie(instr, arguments, sequenceNumber) ==\n\t\t\tstd::tie(otherInstr, _other.arguments, _other.sequenceNumber);\n\t}\n\telse\n\t\treturn std::tie(item->data(), arguments, sequenceNumber) ==\n\t\t\tstd::tie(_other.item->data(), _other.arguments, _other.sequenceNumber);\n}\n\nsize_t ExpressionClasses::Expression::ExpressionHash::operator()(Expression const& _expression) const\n{\n\tassertThrow(!!_expression.item, OptimizerException, \"\");\n\tsize_t seed = 0;\n\tauto type = _expression.item->type();\n\tboost::hash_combine(seed, type);\n\n\tif (type == Operation)\n\t\tboost::hash_combine(seed, _expression.item->instruction());\n\telse\n\t\tboost::hash_combine(seed, _expression.item->data());\n\n\tboost::hash_range(seed, _expression.arguments.begin(), _expression.arguments.end());\n\tboost::hash_combine(seed, _expression.sequenceNumber);\n\n\treturn seed;\n}\n\nExpressionClasses::Id ExpressionClasses::find(\n\tAssemblyItem const& _item,\n\tIds const& _arguments,\n\tbool _copyItem,\n\tunsigned _sequenceNumber\n)\n{\n\tExpression exp;\n\texp.id = Id(-1);\n\texp.item = &_item;\n\texp.arguments = _arguments;\n\texp.sequenceNumber = _sequenceNumber;\n\n\tif (SemanticInformation::isCommutativeOperation(_item))\n\t\tsort(exp.arguments.begin(), exp.arguments.end());\n\n\tif (SemanticInformation::isDeterministic(_item))\n\t{\n\t\tauto it = m_expressions.find(exp);\n\t\tif (it != m_expressions.end())\n\t\t\treturn it->id;\n\t}\n\n\tif (_copyItem)\n\t\texp.item = storeItem(_item);\n\n\tExpressionClasses::Id id = tryToSimplify(exp);\n\tif (id < m_representatives.size())\n\t\texp.id = id;\n\telse\n\t{\n\t\texp.id = static_cast<Id>(m_representatives.size());\n\t\tm_representatives.push_back(exp);\n\t}\n\tm_expressions.insert(exp);\n\treturn exp.id;\n}\n\nvoid ExpressionClasses::forceEqual(\n\tExpressionClasses::Id _id,\n\tAssemblyItem const& _item,\n\tExpressionClasses::Ids const& _arguments,\n\tbool _copyItem\n)\n{\n\tExpression exp;\n\texp.id = _id;\n\texp.item = &_item;\n\texp.arguments = _arguments;\n\n\tif (SemanticInformation::isCommutativeOperation(_item))\n\t\tsort(exp.arguments.begin(), exp.arguments.end());\n\n\tif (_copyItem)\n\t\texp.item = storeItem(_item);\n\n\tm_expressions.insert(exp);\n}\n\nExpressionClasses::Id ExpressionClasses::newClass(langutil::DebugData::ConstPtr _debugData)\n{\n\tExpression exp;\n\texp.id = static_cast<Id>(m_representatives.size());\n\texp.item = storeItem(AssemblyItem(UndefinedItem, (u256(1) << 255) + exp.id, std::move(_debugData)));\n\tm_representatives.push_back(exp);\n\tm_expressions.insert(exp);\n\treturn exp.id;\n}\n\nbool ExpressionClasses::knownToBeDifferent(ExpressionClasses::Id _a, ExpressionClasses::Id _b)\n{\n\t// Try to simplify \"_a - _b\" and return true iff the value is a non-zero constant.\n\treturn knownNonZero(find(Instruction::SUB, {_a, _b}));\n}\n\nbool ExpressionClasses::knownToBeDifferentBy32(ExpressionClasses::Id _a, ExpressionClasses::Id _b)\n{\n\t// Try to simplify \"_a - _b\" and return true iff the value is at least 32 away from zero.\n\tu256 const* v = knownConstant(find(Instruction::SUB, {_a, _b}));\n\t// forbidden interval is [\"-31\", 31]\n\treturn v && *v + 31 > u256(62);\n}\n\nbool ExpressionClasses::knownZero(Id _c)\n{\n\treturn Pattern(u256(0)).matches(representative(_c), *this);\n}\n\nbool ExpressionClasses::knownNonZero(Id _c)\n{\n\treturn Pattern(u256(0)).matches(representative(find(Instruction::ISZERO, {_c})), *this);\n}\n\nu256 const* ExpressionClasses::knownConstant(Id _c)\n{\n\tstd::map<unsigned, Expression const*> matchGroups;\n\tPattern constant(Push);\n\tconstant.setMatchGroup(1, matchGroups);\n\tif (!constant.matches(representative(_c), *this))\n\t\treturn nullptr;\n\treturn &constant.d();\n}\n\nAssemblyItem const* ExpressionClasses::storeItem(AssemblyItem const& _item)\n{\n\tm_spareAssemblyItems.push_back(std::make_shared<AssemblyItem>(_item));\n\treturn m_spareAssemblyItems.back().get();\n}\n\nstd::string ExpressionClasses::fullDAGToString(ExpressionClasses::Id _id) const\n{\n\tExpression const& expr = representative(_id);\n\tstd::stringstream str;\n\tstr << std::dec << expr.id << \":\";\n\tif (expr.item)\n\t{\n\t\tstr << *expr.item << \"(\";\n\t\tfor (Id arg: expr.arguments)\n\t\t\tstr << fullDAGToString(arg) << \",\";\n\t\tstr << \")\";\n\t}\n\telse\n\t\tstr << \" UNIQUE\";\n\treturn str.str();\n}\n\nExpressionClasses::Id ExpressionClasses::tryToSimplify(Expression const& _expr)\n{\n\tstatic Rules rules;\n\tassertThrow(rules.isInitialized(), OptimizerException, \"Rule list not properly initialized.\");\n\n\tif (\n\t\t!_expr.item ||\n\t\t_expr.item->type() != Operation ||\n\t\t!SemanticInformation::isDeterministic(*_expr.item)\n\t)\n\t\treturn std::numeric_limits<unsigned>::max();\n\n\tif (auto match = rules.findFirstMatch(_expr, *this))\n\t{\n\t\t// Debug info\n\t\tif (false)\n\t\t{\n\t\t\tstd::cout << \"Simplifying \" << *_expr.item << \"(\";\n\t\t\tfor (Id arg: _expr.arguments)\n\t\t\t\tstd::cout << fullDAGToString(arg) << \", \";\n\t\t\tstd::cout << \")\" << std::endl;\n\t\t\tstd::cout << \"with rule \" << match->pattern.toString() << std::endl;\n\t\t\tstd::cout << \"to \" << match->action().toString() << std::endl;\n\t\t}\n\n\t\treturn rebuildExpression(ExpressionTemplate(match->action(), _expr.item->debugData()));\n\t}\n\n\treturn std::numeric_limits<unsigned>::max();\n}\n\nExpressionClasses::Id ExpressionClasses::rebuildExpression(ExpressionTemplate const& _template)\n{\n\tif (_template.hasId)\n\t\treturn _template.id;\n\n\tIds arguments;\n\tfor (ExpressionTemplate const& t: _template.arguments)\n\t\targuments.push_back(rebuildExpression(t));\n\treturn find(_template.item, arguments);\n}\n"
  },
  {
    "path": "libevmasm/ExpressionClasses.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file ExpressionClasses.h\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Container for equivalence classes of expressions for use in common subexpression elimination.\n */\n\n#pragma once\n\n#include <libevmasm/AssemblyItem.h>\n\n#include <libsolutil/Common.h>\n\n#include <memory>\n#include <unordered_set>\n#include <vector>\n\nnamespace solidity::langutil\n{\nstruct SourceLocation;\n}\n\nnamespace solidity::evmasm\n{\n\nclass Pattern;\nstruct ExpressionTemplate;\n\n/**\n * Collection of classes of equivalent expressions that can also determine the class of an expression.\n * Identifiers are contiguously assigned to new classes starting from zero.\n */\nclass ExpressionClasses\n{\npublic:\n\tusing Id = unsigned;\n\tusing Ids = std::vector<Id>;\n\n\tstruct Expression\n\t{\n\t\tId id;\n\t\tAssemblyItem const* item = nullptr;\n\t\tIds arguments;\n\t\t/// Storage modification sequence, only used for storage and memory operations.\n\t\tunsigned sequenceNumber = 0;\n\t\t/// Behaves as if this was a tuple of (item->type(), item->data(), arguments, sequenceNumber).\n\t\tbool operator==(Expression const& _other) const;\n\n\t\tstruct ExpressionHash\n\t\t{\n\t\t\tstd::size_t operator()(Expression const& _expression) const;\n\t\t};\n\t};\n\n\n\t/// Retrieves the id of the expression equivalence class resulting from the given item applied to the\n\t/// given classes, might also create a new one.\n\t/// @param _copyItem if true, copies the assembly item to an internal storage instead of just\n\t/// keeping a pointer.\n\t/// The @a _sequenceNumber indicates the current storage or memory access sequence.\n\tId find(\n\t\tAssemblyItem const& _item,\n\t\tIds const& _arguments = {},\n\t\tbool _copyItem = true,\n\t\tunsigned _sequenceNumber = 0\n\t);\n\t/// @returns the canonical representative of an expression class.\n\tExpression const& representative(Id _id) const { return m_representatives.at(_id); }\n\t/// @returns the number of classes.\n\tsize_t size() const { return m_representatives.size(); }\n\n\t/// Forces the given @a _item with @a _arguments to the class @a _id. This can be used to\n\t/// add prior knowledge e.g. about CALLDATA, but has to be used with caution. Will not work as\n\t/// expected if @a _item applied to @a _arguments already exists.\n\tvoid forceEqual(Id _id, AssemblyItem const& _item, Ids const& _arguments, bool _copyItem = true);\n\n\t/// @returns the id of a new class which is different to all other classes.\n\tId newClass(langutil::DebugData::ConstPtr _debugData);\n\n\t/// @returns true if the values of the given classes are known to be different (on every input).\n\t/// @note that this function might still return false for some different inputs.\n\tbool knownToBeDifferent(Id _a, Id _b);\n\t/// Similar to @a knownToBeDifferent but require that abs(_a - b) >= 32.\n\tbool knownToBeDifferentBy32(Id _a, Id _b);\n\t/// @returns true if the value of the given class is known to be zero.\n\t/// @note that this is not the negation of knownNonZero\n\tbool knownZero(Id _c);\n\t/// @returns true if the value of the given class is known to be nonzero.\n\t/// @note that this is not the negation of knownZero\n\tbool knownNonZero(Id _c);\n\t/// @returns a pointer to the value if the given class is known to be a constant,\n\t/// and a nullptr otherwise.\n\tu256 const* knownConstant(Id _c);\n\n\t/// Stores a copy of the given AssemblyItem and returns a pointer to the copy that is valid for\n\t/// the lifetime of the ExpressionClasses object.\n\tAssemblyItem const* storeItem(AssemblyItem const& _item);\n\n\tstd::string fullDAGToString(Id _id) const;\n\nprivate:\n\t/// Tries to simplify the given expression.\n\t/// @returns its class if it possible or Id(-1) otherwise.\n\tId tryToSimplify(Expression const& _expr);\n\n\t/// Rebuilds an expression from a (matched) pattern.\n\tId rebuildExpression(ExpressionTemplate const& _template);\n\n\tstd::vector<std::pair<Pattern, std::function<Pattern()>>> createRules() const;\n\n\t/// Expression equivalence class representatives - we only store one item of an equivalence.\n\tstd::vector<Expression> m_representatives;\n\t/// All expression ever encountered.\n\tstd::unordered_set<Expression, Expression::ExpressionHash> m_expressions;\n\tstd::vector<std::shared_ptr<AssemblyItem>> m_spareAssemblyItems;\n};\n\n}\n"
  },
  {
    "path": "libevmasm/GasMeter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libevmasm/GasMeter.h>\n\n#include <libevmasm/KnownState.h>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::evmasm;\n\nGasMeter::GasConsumption& GasMeter::GasConsumption::operator+=(GasConsumption const& _other)\n{\n\tif (_other.isInfinite && !isInfinite)\n\t\t*this = infinite();\n\tif (isInfinite)\n\t\treturn *this;\n\tbigint v = bigint(value) + _other.value;\n\tif (v > std::numeric_limits<u256>::max())\n\t\t*this = infinite();\n\telse\n\t\tvalue = u256(v);\n\treturn *this;\n}\n\nGasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _includeExternalCosts)\n{\n\tGasConsumption gas;\n\tswitch (_item.type())\n\t{\n\tcase Push:\n\t\tgas = pushGas(_item.data(), m_evmVersion);\n\t\tbreak;\n\tcase PushTag:\n\tcase PushData:\n\tcase PushSub:\n\tcase PushSubSize:\n\tcase PushProgramSize:\n\tcase PushLibraryAddress:\n\tcase PushDeployTimeAddress:\n\t\tgas = runGas(Instruction::PUSH1, m_evmVersion);\n\t\tbreak;\n\tcase Tag:\n\t\tgas = runGas(Instruction::JUMPDEST, m_evmVersion);\n\t\tbreak;\n\tcase Operation:\n\t{\n\t\tExpressionClasses& classes = m_state->expressionClasses();\n\t\tswitch (_item.instruction())\n\t\t{\n\t\tcase Instruction::SSTORE:\n\t\t{\n\t\t\tExpressionClasses::Id slot = m_state->relativeStackElement(0);\n\t\t\tExpressionClasses::Id value = m_state->relativeStackElement(-1);\n\t\t\tif (classes.knownZero(value) || (\n\t\t\t\tm_state->storageContent().count(slot) &&\n\t\t\t\tclasses.knownNonZero(m_state->storageContent().at(slot))\n\t\t\t))\n\t\t\t\tgas = GasCosts::totalSstoreResetGas(m_evmVersion); //@todo take refunds into account\n\t\t\telse\n\t\t\t\tgas = GasCosts::totalSstoreSetGas(m_evmVersion);\n\t\t\tbreak;\n\t\t}\n\t\tcase Instruction::SLOAD:\n\t\t\tgas = GasCosts::sloadGas(m_evmVersion);\n\t\t\tbreak;\n\t\tcase Instruction::RETURN:\n\t\tcase Instruction::REVERT:\n\t\t\tgas = runGas(_item.instruction(), m_evmVersion);\n\t\t\tgas += memoryGas(0, -1);\n\t\t\tbreak;\n\t\tcase Instruction::MLOAD:\n\t\tcase Instruction::MSTORE:\n\t\t\tgas = runGas(_item.instruction(), m_evmVersion);\n\t\t\tgas += memoryGas(classes.find(Instruction::ADD, {\n\t\t\t\tm_state->relativeStackElement(0),\n\t\t\t\tclasses.find(AssemblyItem(32))\n\t\t\t}));\n\t\t\tbreak;\n\t\tcase Instruction::MSTORE8:\n\t\t\tgas = runGas(_item.instruction(), m_evmVersion);\n\t\t\tgas += memoryGas(classes.find(Instruction::ADD, {\n\t\t\t\tm_state->relativeStackElement(0),\n\t\t\t\tclasses.find(AssemblyItem(1))\n\t\t\t}));\n\t\t\tbreak;\n\t\tcase Instruction::KECCAK256:\n\t\t\tgas = GasCosts::keccak256Gas;\n\t\t\tgas += memoryGas(0, -1);\n\t\t\tgas += wordGas(GasCosts::keccak256WordGas, m_state->relativeStackElement(-1));\n\t\t\tbreak;\n\t\tcase Instruction::CALLDATACOPY:\n\t\tcase Instruction::CODECOPY:\n\t\tcase Instruction::RETURNDATACOPY:\n\t\t\tgas = runGas(_item.instruction(), m_evmVersion);\n\t\t\tgas += memoryGas(0, -2);\n\t\t\tgas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-2));\n\t\t\tbreak;\n\t\tcase Instruction::MCOPY:\n\t\t{\n\t\t\tGasConsumption memoryGasFromRead = memoryGas(-1, -2);\n\t\t\tGasConsumption memoryGasFromWrite = memoryGas(0, -2);\n\n\t\t\tgas = runGas(_item.instruction(), m_evmVersion);\n\t\t\tgas += (memoryGasFromRead < memoryGasFromWrite ? memoryGasFromWrite : memoryGasFromRead);\n\t\t\tgas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-2));\n\t\t\tbreak;\n\t\t}\n\t\tcase Instruction::EXTCODESIZE:\n\t\t\tgas = GasCosts::extCodeGas(m_evmVersion);\n\t\t\tbreak;\n\t\tcase Instruction::EXTCODEHASH:\n\t\t\tgas = GasCosts::balanceGas(m_evmVersion);\n\t\t\tbreak;\n\t\tcase Instruction::EXTCODECOPY:\n\t\t\tgas = GasCosts::extCodeGas(m_evmVersion);\n\t\t\tgas += memoryGas(-1, -3);\n\t\t\tgas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-3));\n\t\t\tbreak;\n\t\tcase Instruction::LOG0:\n\t\tcase Instruction::LOG1:\n\t\tcase Instruction::LOG2:\n\t\tcase Instruction::LOG3:\n\t\tcase Instruction::LOG4:\n\t\t{\n\t\t\tgas = GasCosts::logGas + GasCosts::logTopicGas * getLogNumber(_item.instruction());\n\t\t\tgas += memoryGas(0, -1);\n\t\t\tif (u256 const* value = classes.knownConstant(m_state->relativeStackElement(-1)))\n\t\t\t\tgas += GasCosts::logDataGas * (*value);\n\t\t\telse\n\t\t\t\tgas = GasConsumption::infinite();\n\t\t\tbreak;\n\t\t}\n\t\tcase Instruction::CALL:\n\t\tcase Instruction::CALLCODE:\n\t\tcase Instruction::DELEGATECALL:\n\t\tcase Instruction::STATICCALL:\n\t\t{\n\t\t\tif (_includeExternalCosts)\n\t\t\t\t// We assume that we do not know the target contract and thus, the consumption is infinite.\n\t\t\t\tgas = GasConsumption::infinite();\n\t\t\telse\n\t\t\t{\n\t\t\t\tgas = GasCosts::callGas(m_evmVersion);\n\t\t\t\tif (u256 const* value = classes.knownConstant(m_state->relativeStackElement(0)))\n\t\t\t\t\tgas += (*value);\n\t\t\t\telse\n\t\t\t\t\tgas = GasConsumption::infinite();\n\t\t\t\tif (_item.instruction() == Instruction::CALL)\n\t\t\t\t\tgas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists.\n\t\t\t\tint valueSize = 1;\n\t\t\t\tif (_item.instruction() == Instruction::DELEGATECALL || _item.instruction() == Instruction::STATICCALL)\n\t\t\t\t\tvalueSize = 0;\n\t\t\t\telse if (!classes.knownZero(m_state->relativeStackElement(-1 - valueSize)))\n\t\t\t\t\tgas += GasCosts::callValueTransferGas;\n\t\t\t\tgas += memoryGas(-2 - valueSize, -3 - valueSize);\n\t\t\t\tgas += memoryGas(-4 - valueSize, -5 - valueSize);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase Instruction::SELFDESTRUCT:\n\t\t\tgas = GasCosts::selfdestructGas(m_evmVersion);\n\t\t\tgas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists.\n\t\t\tbreak;\n\t\tcase Instruction::CREATE:\n\t\tcase Instruction::CREATE2:\n\t\t\tif (_includeExternalCosts)\n\t\t\t\t// We assume that we do not know the target contract and thus, the consumption is infinite.\n\t\t\t\tgas = GasConsumption::infinite();\n\t\t\telse\n\t\t\t{\n\t\t\t\tgas = GasCosts::createGas;\n\t\t\t\tgas += memoryGas(-1, -2);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase Instruction::EXP:\n\t\t\tgas = GasCosts::expGas;\n\t\t\tif (u256 const* value = classes.knownConstant(m_state->relativeStackElement(-1)))\n\t\t\t{\n\t\t\t\tif (*value)\n\t\t\t\t{\n\t\t\t\t\t// Note: msb() counts from 0 and throws on 0 as input.\n\t\t\t\t\tunsigned const significantByteCount  = (static_cast<unsigned>(boost::multiprecision::msb(*value)) + 1u + 7u) / 8u;\n\t\t\t\t\tgas += GasCosts::expByteGas(m_evmVersion) * significantByteCount;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tgas += GasCosts::expByteGas(m_evmVersion) * 32;\n\t\t\tbreak;\n\t\tcase Instruction::BALANCE:\n\t\t\tgas = GasCosts::balanceGas(m_evmVersion);\n\t\t\tbreak;\n\t\tcase Instruction::CHAINID:\n\t\t\tgas = runGas(Instruction::CHAINID, m_evmVersion);\n\t\t\tbreak;\n\t\tcase Instruction::SELFBALANCE:\n\t\t\tgas = runGas(Instruction::SELFBALANCE, m_evmVersion);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tgas = runGas(_item.instruction(), m_evmVersion);\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\t}\n\tdefault:\n\t\tgas = GasConsumption::infinite();\n\t\tbreak;\n\t}\n\n\tm_state->feedItem(_item);\n\treturn gas;\n}\n\nGasMeter::GasConsumption GasMeter::wordGas(u256 const& _multiplier, ExpressionClasses::Id _value)\n{\n\tu256 const* value = m_state->expressionClasses().knownConstant(_value);\n\tif (!value)\n\t\treturn GasConsumption::infinite();\n\treturn GasConsumption(_multiplier * ((*value + 31) / 32));\n}\n\nGasMeter::GasConsumption GasMeter::memoryGas(ExpressionClasses::Id _position)\n{\n\tu256 const* value = m_state->expressionClasses().knownConstant(_position);\n\tif (!value)\n\t\treturn GasConsumption::infinite();\n\tif (*value < m_largestMemoryAccess)\n\t\treturn GasConsumption(0);\n\tu256 previous = m_largestMemoryAccess;\n\tm_largestMemoryAccess = *value;\n\tauto memGas = [=](u256 const& pos) -> u256\n\t{\n\t\tu256 size = (pos + 31) / 32;\n\t\treturn GasCosts::memoryGas * size + size * size / GasCosts::quadCoeffDiv;\n\t};\n\treturn memGas(*value) - memGas(previous);\n}\n\nGasMeter::GasConsumption GasMeter::memoryGas(int _stackPosOffset, int _stackPosSize)\n{\n\tExpressionClasses& classes = m_state->expressionClasses();\n\tif (classes.knownZero(m_state->relativeStackElement(_stackPosSize)))\n\t\treturn GasConsumption(0);\n\telse\n\t\treturn memoryGas(classes.find(Instruction::ADD, {\n\t\t\tm_state->relativeStackElement(_stackPosOffset),\n\t\t\tm_state->relativeStackElement(_stackPosSize)\n\t\t}));\n}\n\nnamespace\n{\nstd::optional<unsigned> gasCostForTier(Tier _tier)\n{\n\tswitch (_tier)\n\t{\n\tcase Tier::Zero:        return GasCosts::tier0Gas;\n\tcase Tier::Base:        return GasCosts::tier1Gas;\n\tcase Tier::RJump:       return GasCosts::tier1Gas;\n\tcase Tier::RJumpI:      return GasCosts::rjumpiGas;\n\tcase Tier::VeryLow:     return GasCosts::tier2Gas;\n\tcase Tier::RetF:        return GasCosts::tier2Gas;\n\tcase Tier::Low:         return GasCosts::tier3Gas;\n\tcase Tier::CallF:       return GasCosts::tier3Gas;\n\tcase Tier::JumpF:       return GasCosts::tier3Gas;\n\tcase Tier::Mid:         return GasCosts::tier4Gas;\n\tcase Tier::High:        return GasCosts::tier5Gas;\n\tcase Tier::BlockHash:   return GasCosts::tier6Gas;\n\tcase Tier::WarmAccess:  return GasCosts::warmStorageReadCost;\n\n\tcase Tier::Special:\n\tcase Tier::Invalid:\n\t\treturn std::nullopt;\n\t}\n\tutil::unreachable();\n}\n}\n\nunsigned GasMeter::runGas(Instruction _instruction, langutil::EVMVersion _evmVersion)\n{\n\tif (_instruction == Instruction::JUMPDEST)\n\t\treturn 1;\n\n\tif (auto gasCost = gasCostForTier(instructionInfo(_instruction, _evmVersion).gasPriceTier))\n\t\treturn *gasCost;\n\tsolAssert(false, \"Invalid gas tier for instruction \" + instructionInfo(_instruction, _evmVersion).name);\n}\n\nunsigned GasMeter::pushGas(u256 _value, langutil::EVMVersion _evmVersion)\n{\n\treturn runGas(\n\t\t(_evmVersion.hasPush0() && _value == u256(0)) ? Instruction::PUSH0 : Instruction::PUSH1,\n\t\t_evmVersion\n\t);\n}\n\nunsigned GasMeter::swapGas(size_t _depth, langutil::EVMVersion _evmVersion)\n{\n\tif (_depth <= 16)\n\t\treturn runGas(evmasm::swapInstruction(static_cast<unsigned>(_depth)), _evmVersion);\n\tauto gasCost = gasCostForTier(instructionInfo(evmasm::Instruction::SWAPN, _evmVersion).gasPriceTier);\n\tsolAssert(gasCost.has_value(), \"Expected gas cost for SWAPN to be defined.\");\n\treturn *gasCost;\n}\n\nunsigned GasMeter::dupGas(size_t _depth, langutil::EVMVersion _evmVersion)\n{\n\tif (_depth <= 16)\n\t\treturn runGas(evmasm::swapInstruction(static_cast<unsigned>(_depth)), _evmVersion);\n\tauto gasCost = gasCostForTier(instructionInfo(evmasm::Instruction::DUPN, _evmVersion).gasPriceTier);\n\tsolAssert(gasCost.has_value(), \"Expected gas cost for DUPN to be defined.\");\n\treturn *gasCost;\n}\n\nu256 GasMeter::dataGas(bytes const& _data, bool _inCreation, langutil::EVMVersion _evmVersion)\n{\n\tbigint gas = 0;\n\tif (_inCreation)\n\t{\n\t\tfor (auto b: _data)\n\t\t\tgas += (b != 0) ? GasCosts::txDataNonZeroGas(_evmVersion) : GasCosts::txDataZeroGas;\n\t}\n\telse\n\t\tgas = bigint(GasCosts::createDataGas) * _data.size();\n\tsolAssert(gas < bigint(u256(-1)), \"Gas cost exceeds 256 bits.\");\n\treturn u256(gas);\n}\n\n\nu256 GasMeter::dataGas(uint64_t _length, bool _inCreation, langutil::EVMVersion _evmVersion)\n{\n\tbigint gas = bigint(_length) * (_inCreation ? GasCosts::txDataNonZeroGas(_evmVersion) : GasCosts::createDataGas);\n\tsolAssert(gas < bigint(u256(-1)), \"Gas cost exceeds 256 bits.\");\n\treturn u256(gas);\n}\n"
  },
  {
    "path": "libevmasm/GasMeter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file GasMeter.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n *\n * Utilities for tracking gas costs.\n *\n * With respect to EIP-2929, we do not track warm accounts or storage slots and they are always\n * charged the worst-case, i.e., cold-access.\n */\n\n#pragma once\n\n#include <libevmasm/ExpressionClasses.h>\n#include <libevmasm/AssemblyItem.h>\n\n#include <liblangutil/EVMVersion.h>\n\n#include <ostream>\n#include <tuple>\n#include <utility>\n\nnamespace solidity::evmasm\n{\n\nclass KnownState;\n\nnamespace GasCosts\n{\n\t/// NOTE: The GAS_... constants referenced by comments are defined for each EVM version in the Execution Specs:\n\t/// https://ethereum.github.io/execution-specs/autoapi/ethereum/<evm version>/vm/gas/index.html\n\n\tstatic unsigned const stackLimit = 1024;\n\tstatic unsigned const tier0Gas = 0;                       // GAS_ZERO (in Execution Specs)\n\tstatic unsigned const tier1Gas = 2;                       // GAS_BASE\n\tstatic unsigned const tier2Gas = 3;                       // GAS_VERY_LOW\n\tstatic unsigned const tier3Gas = 5;                       // GAS_LOW / GAS_FAST_STEP\n\tstatic unsigned const tier4Gas = 8;                       // GAS_MID\n\tstatic unsigned const tier5Gas = 10;                      // GAS_HIGH\n\tstatic unsigned const tier6Gas = 20;                      // GAS_BLOCK_HASH\n\tstatic unsigned const expGas = 10;                        // GAS_EXPONENTIATION\n\tinline unsigned expByteGas(langutil::EVMVersion _evmVersion)\n\t{\n\t\treturn _evmVersion >= langutil::EVMVersion::spuriousDragon() ? 50 : 10; // GAS_EXPONENTIATION_PER_BYTE\n\t}\n\tstatic unsigned const keccak256Gas = 30;                  // GAS_KECCAK256\n\tstatic unsigned const keccak256WordGas = 6;               // GAS_KECCAK256_WORD\n\t/// Corresponds to ACCESS_LIST_ADDRESS_COST from EIP-2930\n\tstatic unsigned const accessListAddressCost = 2400;\n\t/// Corresponds to ACCESS_LIST_STORAGE_COST from EIP-2930\n\tstatic unsigned const accessListStorageKeyCost = 1900;\n\t/// Corresponds to COLD_SLOAD_COST from EIP-2929\n\tstatic unsigned const coldSloadCost = 2100;               // GAS_COLD_SLOAD\n\t/// Corresponds to COLD_ACCOUNT_ACCESS_COST from EIP-2929\n\tstatic unsigned const coldAccountAccessCost = 2600;       // GAS_COLD_ACCOUNT_ACCESS\n\t/// Corresponds to WARM_STORAGE_READ_COST from EIP-2929\n\tstatic unsigned const warmStorageReadCost = 100;          // GAS_WARM_ACCESS\n\tinline unsigned sloadGas(langutil::EVMVersion _evmVersion)\n\t{\n\t\tif (_evmVersion >= langutil::EVMVersion::berlin())\n\t\t\treturn coldSloadCost;\n\t\telse if (_evmVersion >= langutil::EVMVersion::istanbul())\n\t\t\treturn 800;\n\t\telse if (_evmVersion >= langutil::EVMVersion::tangerineWhistle())\n\t\t\treturn 200;\n\t\telse\n\t\t\treturn 50;\n\t}\n\t/// Corresponds to SSTORE_SET_GAS\n\tstatic unsigned const sstoreSetGas = 20000;               // GAS_STORAGE_SET\n\t/// Corresponds to SSTORE_RESET_GAS from EIP-2929\n\tstatic unsigned const sstoreResetGas = 5000 - coldSloadCost;\n\t/// Corresponds to SSTORE_CLEARS_SCHEDULE from EIP-2200\n\tinline static unsigned sstoreClearsSchedule(langutil::EVMVersion _evmVersion)\n\t{\n\t\t// Changes from EIP-3529\n\t\tif (_evmVersion >= langutil::EVMVersion::london())\n\t\t\treturn sstoreResetGas + accessListStorageKeyCost;\n\t\telse\n\t\t\treturn 15000;\n\t}\n\tinline static unsigned totalSstoreSetGas(langutil::EVMVersion _evmVersion)\n\t{\n\t\tif (_evmVersion >= langutil::EVMVersion::berlin())\n\t\t\treturn sstoreSetGas + coldSloadCost;\n\t\telse\n\t\t\treturn sstoreSetGas;\n\t}\n\t/// Corresponds to SSTORE_RESET_GAS from EIP-2929\n\t/// For Berlin, the maximum is SSTORE_RESET_GAS + COLD_SLOAD_COST = 5000\n\t/// For previous versions, it's a fixed 5000\n\tinline unsigned totalSstoreResetGas(langutil::EVMVersion _evmVersion)\n\t{\n\t\tif (_evmVersion >= langutil::EVMVersion::berlin())\n\t\t\treturn sstoreResetGas + coldSloadCost;\n\t\telse\n\t\t\treturn 5000;\n\t}\n\tinline unsigned extCodeGas(langutil::EVMVersion _evmVersion)\n\t{\n\t\tif (_evmVersion >= langutil::EVMVersion::berlin())\n\t\t\treturn coldAccountAccessCost;\n\t\telse if (_evmVersion >= langutil::EVMVersion::tangerineWhistle())\n\t\t\treturn 700;\n\t\telse\n\t\t\treturn 20;\n\t}\n\tinline unsigned balanceGas(langutil::EVMVersion _evmVersion)\n\t{\n\t\tif (_evmVersion >= langutil::EVMVersion::berlin())\n\t\t\treturn coldAccountAccessCost;\n\t\telse if (_evmVersion >= langutil::EVMVersion::istanbul())\n\t\t\treturn 700;\n\t\telse if (_evmVersion >= langutil::EVMVersion::tangerineWhistle())\n\t\t\treturn 400;\n\t\telse\n\t\t\treturn 20;\n\t}\n\tstatic unsigned const jumpdestGas = 1;                    // GAS_JUMPDEST\n\tstatic unsigned const logGas = 375;                       // GAS_LOG\n\tstatic unsigned const logDataGas = 8;                     // GAS_LOG_DATA\n\tstatic unsigned const logTopicGas = 375;                  // GAS_LOG_TOPIC\n\tstatic unsigned const createGas = 32000;                  // GAS_CREATE\n\tinline unsigned callGas(langutil::EVMVersion _evmVersion)\n\t{\n\t\tif (_evmVersion >= langutil::EVMVersion::berlin())\n\t\t\treturn coldAccountAccessCost;\n\t\telse if (_evmVersion >= langutil::EVMVersion::tangerineWhistle())\n\t\t\treturn 700;\n\t\telse\n\t\t\treturn 40;\n\t}\n\tstatic unsigned const callStipend = 2300;                  // GAS_CALL_STIPEND\n\tstatic unsigned const callValueTransferGas = 9000;         // GAS_CALL_VALUE\n\tstatic unsigned const callNewAccountGas = 25000;           // GAS_NEW_ACCOUNT / GAS_SELF_DESTRUCT_NEW_ACCOUNT\n\tinline unsigned selfdestructGas(langutil::EVMVersion _evmVersion) // GAS_SELF_DESTRUCT\n\t{\n\t\tif (_evmVersion >= langutil::EVMVersion::berlin())\n\t\t\treturn coldAccountAccessCost;\n\t\telse if (_evmVersion >= langutil::EVMVersion::tangerineWhistle())\n\t\t\treturn 5000;\n\t\telse\n\t\t\treturn 0;\n\t}\n\tinline unsigned selfdestructRefundGas(langutil::EVMVersion _evmVersion)\n\t{\n\t\t// Changes from EIP-3529\n\t\tif (_evmVersion >= langutil::EVMVersion::london())\n\t\t\treturn 0;\n\t\telse\n\t\t\treturn 24000;\n\t}\n\tstatic unsigned const memoryGas = 3;                       // GAS_MEMORY / GAS_COPY / GAS_RETURN_DATA_COPY\n\tstatic unsigned const quadCoeffDiv = 512;\n\tstatic unsigned const createDataGas = 200;                 // GAS_CODE_DEPOSIT\n\tstatic unsigned const txGas = 21000;\n\tstatic unsigned const txCreateGas = 53000;\n\tstatic unsigned const txDataZeroGas = 4;\n\tinline unsigned txDataNonZeroGas(langutil::EVMVersion _evmVersion)\n\t{\n\t\treturn _evmVersion >= langutil::EVMVersion::istanbul() ? 16 : 68;\n\t}\n\tstatic unsigned const copyGas = 3;\n\tstatic unsigned const rjumpiGas = 4;\n}\n\n/**\n * Class that helps computing the maximum gas consumption for instructions.\n * Has to be initialized with a certain known state that will be automatically updated for\n * each call to estimateMax. These calls have to supply strictly subsequent AssemblyItems.\n * A new gas meter has to be constructed (with a new state) for control flow changes.\n */\nclass GasMeter\n{\npublic:\n\tstruct GasConsumption\n\t{\n\t\tGasConsumption(unsigned _value = 0, bool _infinite = false): value(_value), isInfinite(_infinite) {}\n\t\tGasConsumption(u256 _value, bool _infinite = false): value(std::move(_value)), isInfinite(_infinite) {}\n\t\tstatic GasConsumption infinite() { return GasConsumption(0, true); }\n\n\t\tGasConsumption& operator+=(GasConsumption const& _other);\n\t\tGasConsumption operator+(GasConsumption const& _other) const\n\t\t{\n\t\t\tGasConsumption result = *this;\n\t\t\tresult += _other;\n\t\t\treturn result;\n\t\t}\n\t\tbool operator<(GasConsumption const& _other) const\n\t\t{\n\t\t\treturn std::make_pair(isInfinite, value) < std::make_pair(_other.isInfinite, _other.value);\n\t\t}\n\n\t\tu256 value;\n\t\tbool isInfinite;\n\t};\n\n\t/// Constructs a new gas meter given the current state.\n\tGasMeter(std::shared_ptr<KnownState>  _state, langutil::EVMVersion _evmVersion, u256  _largestMemoryAccess = 0):\n\t\tm_state(std::move(_state)), m_evmVersion(_evmVersion), m_largestMemoryAccess(std::move(_largestMemoryAccess)) {}\n\n\t/// @returns an upper bound on the gas consumed by the given instruction and updates\n\t/// the state.\n\t/// @param _includeExternalCosts if true, include costs caused by other contracts in calls.\n\tGasConsumption estimateMax(AssemblyItem const& _item, bool _includeExternalCosts = true);\n\n\tu256 const& largestMemoryAccess() const { return m_largestMemoryAccess; }\n\n\t/// @returns gas costs for simple instructions with constant gas costs (that do not\n\t/// change with EVM versions)\n\tstatic unsigned runGas(Instruction _instruction, langutil::EVMVersion _evmVersion);\n\n\t/// @returns gas costs for the cheapest push instructions for the given @a _value\n\t/// (may change depending on EVM version)\n\tstatic unsigned pushGas(u256 _value, langutil::EVMVersion _evmVersion);\n\n\t/// @returns gas costs for the cheapest swap instructions for the given @a _depth\n\t/// (may change depending on EVM version)\n\tstatic unsigned swapGas(size_t _depth, langutil::EVMVersion _evmVersion);\n\n\t/// @returns gas costs for the cheapest dup instructions for the given @a _depth\n\t/// (may change depending on EVM version)\n\tstatic unsigned dupGas(size_t _depth, langutil::EVMVersion _evmVersion);\n\n\t/// @returns the gas cost of the supplied data, depending whether it is in creation code, or not.\n\t/// In case of @a _inCreation, the data is only sent as a transaction and is not stored, whereas\n\t/// otherwise code will be stored and have to pay \"createDataGas\" cost.\n\tstatic u256 dataGas(bytes const& _data, bool _inCreation, langutil::EVMVersion _evmVersion);\n\n\t/// @returns the gas cost of non-zero data of the supplied length, depending whether it is in creation code, or not.\n\t/// In case of @a _inCreation, the data is only sent as a transaction and is not stored, whereas\n\t/// otherwise code will be stored and have to pay \"createDataGas\" cost.\n\tstatic u256 dataGas(uint64_t _length, bool _inCreation, langutil::EVMVersion _evmVersion);\n\nprivate:\n\t/// @returns _multiplier * (_value + 31) / 32, if _value is a known constant and infinite otherwise.\n\tGasConsumption wordGas(u256 const& _multiplier, ExpressionClasses::Id _value);\n\t/// @returns the gas needed to access the given memory position.\n\t/// @todo this assumes that memory was never accessed before and thus over-estimates gas usage.\n\tGasConsumption memoryGas(ExpressionClasses::Id _position);\n\t/// @returns the memory gas for accessing the memory at a specific offset for a number of bytes\n\t/// given as values on the stack at the given relative positions.\n\tGasConsumption memoryGas(int _stackPosOffset, int _stackPosSize);\n\n\tstd::shared_ptr<KnownState> m_state;\n\tlangutil::EVMVersion m_evmVersion;\n\t/// Largest point where memory was accessed since the creation of this object.\n\tu256 m_largestMemoryAccess;\n};\n\ninline std::ostream& operator<<(std::ostream& _str, GasMeter::GasConsumption const& _consumption)\n{\n\tif (_consumption.isInfinite)\n\t\treturn _str << \"[???]\";\n\telse\n\t\treturn _str << std::dec << _consumption.value;\n}\n\n}\n"
  },
  {
    "path": "libevmasm/Inliner.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file Inliner.cpp\n * Inlines small code snippets by replacing JUMP with a copy of the code jumped to.\n */\n\n#include <libevmasm/Inliner.h>\n\n#include <libevmasm/AssemblyItem.h>\n#include <libevmasm/GasMeter.h>\n#include <libevmasm/KnownState.h>\n#include <libevmasm/SemanticInformation.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <range/v3/numeric/accumulate.hpp>\n#include <range/v3/view/drop_last.hpp>\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/slice.hpp>\n#include <range/v3/view/transform.hpp>\n\n#include <optional>\n#include <limits>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\n\n\nnamespace\n{\n/// @returns an estimation of the runtime gas cost of the AssemblyItems in @a _itemRange.\ntemplate<typename RangeType>\nu256 executionCost(RangeType const& _itemRange, langutil::EVMVersion _evmVersion)\n{\n\tGasMeter gasMeter{std::make_shared<KnownState>(), _evmVersion};\n\tauto gasConsumption = ranges::accumulate(_itemRange | ranges::views::transform(\n\t\t[&gasMeter](auto const& _item) { return gasMeter.estimateMax(_item, false); }\n\t), GasMeter::GasConsumption());\n\tif (gasConsumption.isInfinite)\n\t\treturn std::numeric_limits<u256>::max();\n\telse\n\t\treturn gasConsumption.value;\n}\n/// @returns an estimation of the code size in bytes needed for the AssemblyItems in @a _itemRange.\ntemplate<typename RangeType>\nuint64_t codeSize(RangeType const& _itemRange, langutil::EVMVersion _evmVersion)\n{\n\treturn ranges::accumulate(_itemRange | ranges::views::transform(\n\t\t[&](auto const& _item) { return _item.bytesRequired(2, _evmVersion, Precision::Approximate); }\n\t), 0u);\n}\n/// @returns the tag id, if @a _item is a PushTag or Tag into the current subassembly, std::nullopt otherwise.\nstd::optional<size_t> getLocalTag(AssemblyItem const& _item)\n{\n\tif (_item.type() != PushTag && _item.type() != Tag)\n\t\treturn std::nullopt;\n\tauto [subId, tag] = _item.splitForeignPushTag();\n\tif (!subId.empty())\n\t\treturn std::nullopt;\n\treturn tag;\n}\n}\n\nbool Inliner::isInlineCandidate(size_t _tag, ranges::span<AssemblyItem const> _items) const\n{\n\tassertThrow(_items.size() > 0, OptimizerException, \"\");\n\n\tif (_items.back().type() != Operation)\n\t\treturn false;\n\tif (\n\t\t_items.back() != Instruction::JUMP &&\n\t\t!SemanticInformation::terminatesControlFlow(_items.back().instruction())\n\t)\n\t\treturn false;\n\n\t// Never inline tags that reference themselves.\n\tfor (AssemblyItem const& item: _items)\n\t\tif (item.type() == PushTag)\n\t\t\tif (getLocalTag(item) == _tag)\n\t\t\t\t\treturn false;\n\n\treturn true;\n}\n\nstd::map<size_t, Inliner::InlinableBlock> Inliner::determineInlinableBlocks(AssemblyItems const& _items) const\n{\n\tstd::map<size_t, ranges::span<AssemblyItem const>> inlinableBlockItems;\n\tstd::map<size_t, uint64_t> numPushTags;\n\tstd::optional<size_t> lastTag;\n\tfor (auto&& [index, item]: _items | ranges::views::enumerate)\n\t{\n\t\t// The number of PushTags approximates the number of calls to a block.\n\t\tif (item.type() == PushTag)\n\t\t\tif (std::optional<size_t> tag = getLocalTag(item))\n\t\t\t\t++numPushTags[*tag];\n\n\t\t// We can only inline blocks with straight control flow that end in a jump.\n\t\t// Using breaksCSEAnalysisBlock will hopefully allow the return jump to be optimized after inlining.\n\t\tif (lastTag && SemanticInformation::breaksCSEAnalysisBlock(item, false))\n\t\t{\n\t\t\tranges::span<AssemblyItem const> block = _items | ranges::views::slice(*lastTag + 1, index + 1);\n\t\t\tif (std::optional<size_t> tag = getLocalTag(_items[*lastTag]))\n\t\t\t\tif (isInlineCandidate(*tag, block))\n\t\t\t\t\tinlinableBlockItems[*tag] = block;\n\t\t\tlastTag.reset();\n\t\t}\n\n\t\tif (item.type() == Tag)\n\t\t{\n\t\t\tassertThrow(getLocalTag(item), OptimizerException, \"\");\n\t\t\tlastTag = index;\n\t\t}\n\t}\n\n\t// Store the number of PushTags alongside the assembly items and discard tags that are never pushed.\n\tstd::map<size_t, InlinableBlock> result;\n\tfor (auto&& [tag, items]: inlinableBlockItems)\n\t\tif (uint64_t const* numPushes = util::valueOrNullptr(numPushTags, tag))\n\t\t\tresult.emplace(tag, InlinableBlock{items, *numPushes});\n\treturn result;\n}\n\nbool Inliner::shouldInlineFullFunctionBody(size_t _tag, ranges::span<AssemblyItem const> _block, uint64_t _pushTagCount) const\n{\n\t// Accumulate size of the inline candidate block in bytes (without the return jump).\n\tuint64_t functionBodySize = codeSize(ranges::views::drop_last(_block, 1), m_evmVersion);\n\n\t// Use the number of push tags as approximation of the average number of calls to the function per run.\n\tuint64_t numberOfCalls = _pushTagCount;\n\t// Also use the number of push tags as approximation of the number of call sites to the function.\n\tuint64_t numberOfCallSites = _pushTagCount;\n\n\tstatic AssemblyItems const uninlinedCallSitePattern = {\n\t\tAssemblyItem{PushTag},\n\t\tAssemblyItem{PushTag},\n\t\tAssemblyItem{Instruction::JUMP},\n\t\tAssemblyItem{Tag}\n\t};\n\tstatic AssemblyItems const uninlinedFunctionPattern = {\n\t\tAssemblyItem{Tag},\n\t\t// Actual function body of size functionBodySize. Handled separately below.\n\t\tAssemblyItem{Instruction::JUMP}\n\t};\n\n\t// Both the call site and jump site pattern is executed for each call.\n\t// Since the function body has to be executed equally often both with and without inlining,\n\t// it can be ignored.\n\tbigint uninlinedExecutionCost = numberOfCalls * (\n\t\texecutionCost(uninlinedCallSitePattern, m_evmVersion) +\n\t\texecutionCost(uninlinedFunctionPattern, m_evmVersion)\n\t);\n\t// Each call site deposits the call site pattern, whereas the jump site pattern and the function itself are deposited once.\n\tbigint uninlinedDepositCost = GasMeter::dataGas(\n\t\tnumberOfCallSites * codeSize(uninlinedCallSitePattern, m_evmVersion) +\n\t\tcodeSize(uninlinedFunctionPattern, m_evmVersion) +\n\t\tfunctionBodySize,\n\t\tm_isCreation,\n\t\tm_evmVersion\n\t);\n\t// When inlining the execution cost beyond the actual function execution is zero,\n\t// but for each call site a copy of the function is deposited.\n\tbigint inlinedDepositCost = GasMeter::dataGas(\n\t\tnumberOfCallSites * functionBodySize,\n\t\tm_isCreation,\n\t\tm_evmVersion\n\t);\n\t// If the block is referenced from outside the current subassembly, the original function cannot be removed.\n\t// Note that the function also cannot always be removed, if it is not referenced from outside, but in that case\n\t// the heuristics is optimistic.\n\tif (m_tagsReferencedFromOutside.count(_tag))\n\t\tinlinedDepositCost += GasMeter::dataGas(\n\t\t\tcodeSize(uninlinedFunctionPattern, m_evmVersion) + functionBodySize,\n\t\t\tm_isCreation,\n\t\t\tm_evmVersion\n\t\t);\n\n\t// If the estimated runtime cost over the lifetime of the contract plus the deposit cost in the uninlined case\n\t// exceed the inlined deposit costs, it is beneficial to inline.\n\tif (bigint(m_runs) * uninlinedExecutionCost + uninlinedDepositCost > inlinedDepositCost)\n\t\treturn true;\n\n\treturn false;\n}\n\nstd::optional<AssemblyItem> Inliner::shouldInline(size_t _tag, AssemblyItem const& _jump, InlinableBlock const& _block) const\n{\n\tassertThrow(_jump == Instruction::JUMP, OptimizerException, \"\");\n\tAssemblyItem blockExit = _block.items.back();\n\n\tif (\n\t\t_jump.getJumpType() == AssemblyItem::JumpType::IntoFunction &&\n\t\tblockExit == Instruction::JUMP &&\n\t\tblockExit.getJumpType() == AssemblyItem::JumpType::OutOfFunction &&\n\t\tshouldInlineFullFunctionBody(_tag, _block.items, _block.pushTagCount)\n\t)\n\t{\n\t\tblockExit.setJumpType(AssemblyItem::JumpType::Ordinary);\n\t\treturn blockExit;\n\t}\n\n\t// Inline small blocks, if the jump to it is ordinary or the blockExit is a terminating instruction.\n\tif (\n\t\t_jump.getJumpType() == AssemblyItem::JumpType::Ordinary ||\n\t\tSemanticInformation::terminatesControlFlow(blockExit.instruction())\n\t)\n\t{\n\t\tstatic AssemblyItems const jumpPattern = {\n\t\t\tAssemblyItem{PushTag},\n\t\t\tAssemblyItem{Instruction::JUMP},\n\t\t};\n\t\tif (\n\t\t\tGasMeter::dataGas(codeSize(_block.items, m_evmVersion), m_isCreation, m_evmVersion) <=\n\t\t\tGasMeter::dataGas(codeSize(jumpPattern, m_evmVersion), m_isCreation, m_evmVersion)\n\t\t)\n\t\t\treturn blockExit;\n\t}\n\n\treturn std::nullopt;\n}\n\n\nvoid Inliner::optimise()\n{\n\tstd::map<size_t, InlinableBlock> inlinableBlocks = determineInlinableBlocks(m_items);\n\n\tif (inlinableBlocks.empty())\n\t\treturn;\n\n\tAssemblyItems newItems;\n\tfor (auto it = m_items.begin(); it != m_items.end(); ++it)\n\t{\n\t\tAssemblyItem const& item = *it;\n\t\tif (next(it) != m_items.end())\n\t\t{\n\t\t\tAssemblyItem const& nextItem = *next(it);\n\t\t\tif (item.type() == PushTag && nextItem == Instruction::JUMP)\n\t\t\t{\n\t\t\t\tif (std::optional<size_t> tag = getLocalTag(item))\n\t\t\t\t\tif (auto* inlinableBlock = util::valueOrNullptr(inlinableBlocks, *tag))\n\t\t\t\t\t\tif (auto exitItem = shouldInline(*tag, nextItem, *inlinableBlock))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnewItems += inlinableBlock->items | ranges::views::drop_last(1);\n\t\t\t\t\t\t\tnewItems.emplace_back(std::move(*exitItem));\n\n\t\t\t\t\t\t\t// We are removing one push tag to the block we inline.\n\t\t\t\t\t\t\t--inlinableBlock->pushTagCount;\n\t\t\t\t\t\t\t// We might increase the number of push tags to other blocks.\n\t\t\t\t\t\t\tfor (AssemblyItem const& inlinedItem: inlinableBlock->items)\n\t\t\t\t\t\t\t\tif (inlinedItem.type() == PushTag)\n\t\t\t\t\t\t\t\t\tif (std::optional<size_t> duplicatedTag = getLocalTag(inlinedItem))\n\t\t\t\t\t\t\t\t\t\tif (auto* block = util::valueOrNullptr(inlinableBlocks, *duplicatedTag))\n\t\t\t\t\t\t\t\t\t\t\t++block->pushTagCount;\n\n\t\t\t\t\t\t\t// Skip the original jump to the inlined tag and continue.\n\t\t\t\t\t\t\t++it;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tnewItems.emplace_back(item);\n\t}\n\n\tm_items = std::move(newItems);\n}\n"
  },
  {
    "path": "libevmasm/Inliner.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file Inliner.h\n * Inlines small code snippets by replacing JUMP with a copy of the code jumped to.\n */\n#pragma once\n\n#include <libsolutil/Common.h>\n#include <libevmasm/Assembly.h>\n#include <libevmasm/AssemblyItem.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <range/v3/view/span.hpp>\n#include <map>\n#include <set>\n#include <vector>\n\nnamespace solidity::evmasm\n{\n\nclass Inliner\n{\npublic:\n\texplicit Inliner(\n\t\tAssemblyItems& _items,\n\t\tstd::set<size_t> const& _tagsReferencedFromOutside,\n\t\tsize_t _runs,\n\t\tbool _isCreation,\n\t\tlangutil::EVMVersion _evmVersion\n\t):\n\tm_items(_items),\n\tm_tagsReferencedFromOutside(_tagsReferencedFromOutside),\n\tm_runs(_runs),\n\tm_isCreation(_isCreation),\n\tm_evmVersion(_evmVersion)\n\t{\n\t}\n\tvirtual ~Inliner() = default;\n\n\tvoid optimise();\n\nprivate:\n\tstruct InlinableBlock\n\t{\n\t\tranges::span<AssemblyItem const> items;\n\t\tuint64_t pushTagCount = 0;\n\t};\n\n\t/// @returns the exit item for the block to be inlined, if a particular jump to it should be inlined, otherwise nullopt.\n\tstd::optional<AssemblyItem> shouldInline(size_t _tag, AssemblyItem const& _jump, InlinableBlock const& _block) const;\n\t/// @returns true, if the full function at tag @a _tag with body @a _block that is referenced @a _pushTagCount times\n\t/// should be inlined, false otherwise. @a _block should start at the first instruction after the function entry tag\n\t/// up to and including the return jump.\n\tbool shouldInlineFullFunctionBody(size_t _tag, ranges::span<AssemblyItem const> _block, uint64_t _pushTagCount) const;\n\t/// @returns true, if the @a _items at @a _tag are a potential candidate for inlining.\n\tbool isInlineCandidate(size_t _tag, ranges::span<AssemblyItem const> _items) const;\n\t/// @returns a map from tags that can potentially be inlined to the inlinable item range behind that tag and the\n\t/// number of times the tag in question was referenced.\n\tstd::map<size_t, InlinableBlock> determineInlinableBlocks(AssemblyItems const& _items) const;\n\n\tAssemblyItems& m_items;\n\tstd::set<size_t> const& m_tagsReferencedFromOutside;\n\tsize_t const m_runs = Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment;\n\tbool const m_isCreation = false;\n\tlangutil::EVMVersion const m_evmVersion;\n};\n\n}\n"
  },
  {
    "path": "libevmasm/Instruction.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file Instruction.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <libevmasm/Instruction.h>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::evmasm;\n\nstd::map<std::string, Instruction, std::less<>> const solidity::evmasm::c_instructions =\n{\n\t{ \"STOP\", Instruction::STOP },\n\t{ \"ADD\", Instruction::ADD },\n\t{ \"SUB\", Instruction::SUB },\n\t{ \"MUL\", Instruction::MUL },\n\t{ \"DIV\", Instruction::DIV },\n\t{ \"SDIV\", Instruction::SDIV },\n\t{ \"MOD\", Instruction::MOD },\n\t{ \"SMOD\", Instruction::SMOD },\n\t{ \"EXP\", Instruction::EXP },\n\t{ \"NOT\", Instruction::NOT },\n\t{ \"LT\", Instruction::LT },\n\t{ \"GT\", Instruction::GT },\n\t{ \"SLT\", Instruction::SLT },\n\t{ \"SGT\", Instruction::SGT },\n\t{ \"EQ\", Instruction::EQ },\n\t{ \"ISZERO\", Instruction::ISZERO },\n\t{ \"AND\", Instruction::AND },\n\t{ \"OR\", Instruction::OR },\n\t{ \"XOR\", Instruction::XOR },\n\t{ \"BYTE\", Instruction::BYTE },\n\t{ \"SHL\", Instruction::SHL },\n\t{ \"SHR\", Instruction::SHR },\n\t{ \"SAR\", Instruction::SAR },\n\t{ \"CLZ\", Instruction::CLZ },\n\t{ \"ADDMOD\", Instruction::ADDMOD },\n\t{ \"MULMOD\", Instruction::MULMOD },\n\t{ \"SIGNEXTEND\", Instruction::SIGNEXTEND },\n\t{ \"KECCAK256\", Instruction::KECCAK256 },\n\t{ \"ADDRESS\", Instruction::ADDRESS },\n\t{ \"BALANCE\", Instruction::BALANCE },\n\t{ \"ORIGIN\", Instruction::ORIGIN },\n\t{ \"CALLER\", Instruction::CALLER },\n\t{ \"CALLVALUE\", Instruction::CALLVALUE },\n\t{ \"CALLDATALOAD\", Instruction::CALLDATALOAD },\n\t{ \"CALLDATASIZE\", Instruction::CALLDATASIZE },\n\t{ \"CALLDATACOPY\", Instruction::CALLDATACOPY },\n\t{ \"CODESIZE\", Instruction::CODESIZE },\n\t{ \"CODECOPY\", Instruction::CODECOPY },\n\t{ \"GASPRICE\", Instruction::GASPRICE },\n\t{ \"EXTCODESIZE\", Instruction::EXTCODESIZE },\n\t{ \"EXTCODECOPY\", Instruction::EXTCODECOPY },\n\t{ \"RETURNDATASIZE\", Instruction::RETURNDATASIZE },\n\t{ \"RETURNDATACOPY\", Instruction::RETURNDATACOPY },\n\t{ \"MCOPY\", Instruction::MCOPY },\n\t{ \"EXTCODEHASH\", Instruction::EXTCODEHASH },\n\t{ \"BLOCKHASH\", Instruction::BLOCKHASH },\n\t{ \"BLOBHASH\", Instruction::BLOBHASH },\n\t{ \"COINBASE\", Instruction::COINBASE },\n\t{ \"TIMESTAMP\", Instruction::TIMESTAMP },\n\t{ \"NUMBER\", Instruction::NUMBER },\n\t{ \"DIFFICULTY\", Instruction::PREVRANDAO },\n\t{ \"PREVRANDAO\", Instruction::PREVRANDAO },\n\t{ \"GASLIMIT\", Instruction::GASLIMIT },\n\t{ \"CHAINID\", Instruction::CHAINID },\n\t{ \"SELFBALANCE\", Instruction::SELFBALANCE },\n\t{ \"BASEFEE\", Instruction::BASEFEE },\n\t{ \"BLOBBASEFEE\", Instruction::BLOBBASEFEE },\n\t{ \"POP\", Instruction::POP },\n\t{ \"MLOAD\", Instruction::MLOAD },\n\t{ \"MSTORE\", Instruction::MSTORE },\n\t{ \"MSTORE8\", Instruction::MSTORE8 },\n\t{ \"SLOAD\", Instruction::SLOAD },\n\t{ \"SSTORE\", Instruction::SSTORE },\n\t{ \"TLOAD\", Instruction::TLOAD },\n\t{ \"TSTORE\", Instruction::TSTORE },\n\t{ \"JUMP\", Instruction::JUMP },\n\t{ \"JUMPI\", Instruction::JUMPI },\n\t{ \"PC\", Instruction::PC },\n\t{ \"MSIZE\", Instruction::MSIZE },\n\t{ \"GAS\", Instruction::GAS },\n\t{ \"JUMPDEST\", Instruction::JUMPDEST },\n\t{ \"PUSH0\", Instruction::PUSH0 },\n\t{ \"PUSH1\", Instruction::PUSH1 },\n\t{ \"PUSH2\", Instruction::PUSH2 },\n\t{ \"PUSH3\", Instruction::PUSH3 },\n\t{ \"PUSH4\", Instruction::PUSH4 },\n\t{ \"PUSH5\", Instruction::PUSH5 },\n\t{ \"PUSH6\", Instruction::PUSH6 },\n\t{ \"PUSH7\", Instruction::PUSH7 },\n\t{ \"PUSH8\", Instruction::PUSH8 },\n\t{ \"PUSH9\", Instruction::PUSH9 },\n\t{ \"PUSH10\", Instruction::PUSH10 },\n\t{ \"PUSH11\", Instruction::PUSH11 },\n\t{ \"PUSH12\", Instruction::PUSH12 },\n\t{ \"PUSH13\", Instruction::PUSH13 },\n\t{ \"PUSH14\", Instruction::PUSH14 },\n\t{ \"PUSH15\", Instruction::PUSH15 },\n\t{ \"PUSH16\", Instruction::PUSH16 },\n\t{ \"PUSH17\", Instruction::PUSH17 },\n\t{ \"PUSH18\", Instruction::PUSH18 },\n\t{ \"PUSH19\", Instruction::PUSH19 },\n\t{ \"PUSH20\", Instruction::PUSH20 },\n\t{ \"PUSH21\", Instruction::PUSH21 },\n\t{ \"PUSH22\", Instruction::PUSH22 },\n\t{ \"PUSH23\", Instruction::PUSH23 },\n\t{ \"PUSH24\", Instruction::PUSH24 },\n\t{ \"PUSH25\", Instruction::PUSH25 },\n\t{ \"PUSH26\", Instruction::PUSH26 },\n\t{ \"PUSH27\", Instruction::PUSH27 },\n\t{ \"PUSH28\", Instruction::PUSH28 },\n\t{ \"PUSH29\", Instruction::PUSH29 },\n\t{ \"PUSH30\", Instruction::PUSH30 },\n\t{ \"PUSH31\", Instruction::PUSH31 },\n\t{ \"PUSH32\", Instruction::PUSH32 },\n\t{ \"DUP1\", Instruction::DUP1 },\n\t{ \"DUP2\", Instruction::DUP2 },\n\t{ \"DUP3\", Instruction::DUP3 },\n\t{ \"DUP4\", Instruction::DUP4 },\n\t{ \"DUP5\", Instruction::DUP5 },\n\t{ \"DUP6\", Instruction::DUP6 },\n\t{ \"DUP7\", Instruction::DUP7 },\n\t{ \"DUP8\", Instruction::DUP8 },\n\t{ \"DUP9\", Instruction::DUP9 },\n\t{ \"DUP10\", Instruction::DUP10 },\n\t{ \"DUP11\", Instruction::DUP11 },\n\t{ \"DUP12\", Instruction::DUP12 },\n\t{ \"DUP13\", Instruction::DUP13 },\n\t{ \"DUP14\", Instruction::DUP14 },\n\t{ \"DUP15\", Instruction::DUP15 },\n\t{ \"DUP16\", Instruction::DUP16 },\n\t{ \"SWAP1\", Instruction::SWAP1 },\n\t{ \"SWAP2\", Instruction::SWAP2 },\n\t{ \"SWAP3\", Instruction::SWAP3 },\n\t{ \"SWAP4\", Instruction::SWAP4 },\n\t{ \"SWAP5\", Instruction::SWAP5 },\n\t{ \"SWAP6\", Instruction::SWAP6 },\n\t{ \"SWAP7\", Instruction::SWAP7 },\n\t{ \"SWAP8\", Instruction::SWAP8 },\n\t{ \"SWAP9\", Instruction::SWAP9 },\n\t{ \"SWAP10\", Instruction::SWAP10 },\n\t{ \"SWAP11\", Instruction::SWAP11 },\n\t{ \"SWAP12\", Instruction::SWAP12 },\n\t{ \"SWAP13\", Instruction::SWAP13 },\n\t{ \"SWAP14\", Instruction::SWAP14 },\n\t{ \"SWAP15\", Instruction::SWAP15 },\n\t{ \"SWAP16\", Instruction::SWAP16 },\n\t{ \"LOG0\", Instruction::LOG0 },\n\t{ \"LOG1\", Instruction::LOG1 },\n\t{ \"LOG2\", Instruction::LOG2 },\n\t{ \"LOG3\", Instruction::LOG3 },\n\t{ \"LOG4\", Instruction::LOG4 },\n\t{ \"DATALOADN\", Instruction::DATALOADN },\n\t{ \"CALLF\", Instruction::CALLF },\n\t{ \"RETF\", Instruction::RETF },\n\t{ \"JUMPF\", Instruction::JUMPF },\n\t{ \"DUPN\", Instruction::DUPN },\n\t{ \"SWAPN\", Instruction::SWAPN },\n\t{ \"RJUMP\", Instruction::RJUMP },\n\t{ \"RJUMPI\", Instruction::RJUMPI },\n\t{ \"EOFCREATE\", Instruction::EOFCREATE },\n\t{ \"RETURNCONTRACT\", Instruction::RETURNCONTRACT },\n\t{ \"CREATE\", Instruction::CREATE },\n\t{ \"CALL\", Instruction::CALL },\n\t{ \"CALLCODE\", Instruction::CALLCODE },\n\t{ \"STATICCALL\", Instruction::STATICCALL },\n\t{ \"RETURN\", Instruction::RETURN },\n\t{ \"DELEGATECALL\", Instruction::DELEGATECALL },\n\t{ \"EXTCALL\", Instruction::EXTCALL },\n\t{ \"EXTSTATICCALL\", Instruction::EXTSTATICCALL },\n\t{ \"EXTDELEGATECALL\", Instruction::EXTDELEGATECALL },\n\t{ \"CREATE2\", Instruction::CREATE2 },\n\t{ \"REVERT\", Instruction::REVERT },\n\t{ \"INVALID\", Instruction::INVALID },\n\t{ \"SELFDESTRUCT\", Instruction::SELFDESTRUCT }\n};\n\n/// @note InstructionInfo is assumed to be the same across all EVM versions except for the instruction name.\nstatic std::map<Instruction, InstructionInfo> const c_instructionInfo =\n{   //                                                Add Args Ret SideEffects GasPriceTier\n\t{Instruction::STOP,           {\"STOP\",            0,  0,   0,  true,       Tier::Zero}},\n\t{Instruction::ADD,            {\"ADD\",             0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::SUB,            {\"SUB\",             0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::MUL,            {\"MUL\",             0,  2,   1,  false,      Tier::Low}},\n\t{Instruction::DIV,            {\"DIV\",             0,  2,   1,  false,      Tier::Low}},\n\t{Instruction::SDIV,           {\"SDIV\",            0,  2,   1,  false,      Tier::Low}},\n\t{Instruction::MOD,            {\"MOD\",             0,  2,   1,  false,      Tier::Low}},\n\t{Instruction::SMOD,           {\"SMOD\",            0,  2,   1,  false,      Tier::Low}},\n\t{Instruction::EXP,            {\"EXP\",             0,  2,   1,  false,      Tier::Special}},\n\t{Instruction::NOT,            {\"NOT\",             0,  1,   1,  false,      Tier::VeryLow}},\n\t{Instruction::LT,             {\"LT\",              0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::GT,             {\"GT\",              0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::SLT,            {\"SLT\",             0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::SGT,            {\"SGT\",             0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::EQ,             {\"EQ\",              0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::ISZERO,         {\"ISZERO\",          0,  1,   1,  false,      Tier::VeryLow}},\n\t{Instruction::AND,            {\"AND\",             0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::OR,             {\"OR\",              0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::XOR,            {\"XOR\",             0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::BYTE,           {\"BYTE\",            0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::SHL,            {\"SHL\",             0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::SHR,            {\"SHR\",             0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::SAR,            {\"SAR\",             0,  2,   1,  false,      Tier::VeryLow}},\n\t{Instruction::CLZ,            {\"CLZ\",             0,  1,   1,  false,      Tier::Low}},\n\t{Instruction::ADDMOD,         {\"ADDMOD\",          0,  3,   1,  false,      Tier::Mid}},\n\t{Instruction::MULMOD,         {\"MULMOD\",          0,  3,   1,  false,      Tier::Mid}},\n\t{Instruction::SIGNEXTEND,     {\"SIGNEXTEND\",      0,  2,   1,  false,      Tier::Low}},\n\t{Instruction::KECCAK256,      {\"KECCAK256\",       0,  2,   1,  true,       Tier::Special}},\n\t{Instruction::ADDRESS,        {\"ADDRESS\",         0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::BALANCE,        {\"BALANCE\",         0,  1,   1,  false,      Tier::Special}},\n\t{Instruction::ORIGIN,         {\"ORIGIN\",          0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::CALLER,         {\"CALLER\",          0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::CALLVALUE,      {\"CALLVALUE\",       0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::CALLDATALOAD,   {\"CALLDATALOAD\",    0,  1,   1,  false,      Tier::VeryLow}},\n\t{Instruction::CALLDATASIZE,   {\"CALLDATASIZE\",    0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::CALLDATACOPY,   {\"CALLDATACOPY\",    0,  3,   0,  true,       Tier::VeryLow}},\n\t{Instruction::CODESIZE,       {\"CODESIZE\",        0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::CODECOPY,       {\"CODECOPY\",        0,  3,   0,  true,       Tier::VeryLow}},\n\t{Instruction::GASPRICE,       {\"GASPRICE\",        0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::EXTCODESIZE,    {\"EXTCODESIZE\",     0,  1,   1,  false,      Tier::Special}},\n\t{Instruction::EXTCODECOPY,    {\"EXTCODECOPY\",     0,  4,   0,  true,       Tier::Special}},\n\t{Instruction::RETURNDATASIZE, {\"RETURNDATASIZE\",  0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::RETURNDATACOPY, {\"RETURNDATACOPY\",  0,  3,   0,  true,       Tier::VeryLow}},\n\t{Instruction::MCOPY,          {\"MCOPY\",           0,  3,   0,  true,       Tier::VeryLow}},\n\t{Instruction::EXTCODEHASH,    {\"EXTCODEHASH\",     0,  1,   1,  false,      Tier::Special}},\n\t{Instruction::BLOCKHASH,      {\"BLOCKHASH\",       0,  1,   1,  false,      Tier::BlockHash}},\n\t{Instruction::BLOBHASH,       {\"BLOBHASH\",        0,  1,   1,  false,      Tier::VeryLow}},\n\t{Instruction::COINBASE,       {\"COINBASE\",        0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::TIMESTAMP,      {\"TIMESTAMP\",       0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::NUMBER,         {\"NUMBER\",          0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::PREVRANDAO,     {\"PREVRANDAO\",      0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::GASLIMIT,       {\"GASLIMIT\",        0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::CHAINID,        {\"CHAINID\",         0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::SELFBALANCE,    {\"SELFBALANCE\",     0,  0,   1,  false,      Tier::Low}},\n\t{Instruction::BASEFEE,        {\"BASEFEE\",         0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::BLOBBASEFEE,    {\"BLOBBASEFEE\",     0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::POP,            {\"POP\",             0,  1,   0,  false,      Tier::Base}},\n\t{Instruction::MLOAD,          {\"MLOAD\",           0,  1,   1,  true,       Tier::VeryLow}},\n\t{Instruction::MSTORE,         {\"MSTORE\",          0,  2,   0,  true,       Tier::VeryLow}},\n\t{Instruction::MSTORE8,        {\"MSTORE8\",         0,  2,   0,  true,       Tier::VeryLow}},\n\t{Instruction::SLOAD,          {\"SLOAD\",           0,  1,   1,  false,      Tier::Special}},\n\t{Instruction::SSTORE,         {\"SSTORE\",          0,  2,   0,  true,       Tier::Special}},\n\t{Instruction::TLOAD,          {\"TLOAD\",           0,  1,   1,  false,      Tier::WarmAccess}},\n\t{Instruction::TSTORE,         {\"TSTORE\",          0,  2,   0,  true,       Tier::WarmAccess}},\n\t{Instruction::JUMP,           {\"JUMP\",            0,  1,   0,  true,       Tier::Mid}},\n\t{Instruction::JUMPI,          {\"JUMPI\",           0,  2,   0,  true,       Tier::High}},\n\t{Instruction::PC,             {\"PC\",              0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::MSIZE,          {\"MSIZE\",           0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::GAS,            {\"GAS\",             0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::JUMPDEST,       {\"JUMPDEST\",        0,  0,   0,  true,       Tier::Special}},\n\t{Instruction::DATALOADN,      {\"DATALOADN\",       2,  0,   1,  true,       Tier::Low}},\n\t{Instruction::RJUMP,          {\"RJUMP\",           2,  0,   0,  true,       Tier::RJump}},\n\t{Instruction::RJUMPI,         {\"RJUMPI\",          2,  1,   0,  true,       Tier::RJumpI}},\n\t{Instruction::PUSH0,          {\"PUSH0\",           0,  0,   1,  false,      Tier::Base}},\n\t{Instruction::PUSH1,          {\"PUSH1\",           1,  0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH2,          {\"PUSH2\",           2,  0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH3,          {\"PUSH3\",           3,  0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH4,          {\"PUSH4\",           4,  0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH5,          {\"PUSH5\",           5,  0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH6,          {\"PUSH6\",           6,  0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH7,          {\"PUSH7\",           7,  0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH8,          {\"PUSH8\",           8,  0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH9,          {\"PUSH9\",           9,  0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH10,         {\"PUSH10\",          10, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH11,         {\"PUSH11\",          11, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH12,         {\"PUSH12\",          12, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH13,         {\"PUSH13\",          13, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH14,         {\"PUSH14\",          14, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH15,         {\"PUSH15\",          15, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH16,         {\"PUSH16\",          16, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH17,         {\"PUSH17\",          17, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH18,         {\"PUSH18\",          18, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH19,         {\"PUSH19\",          19, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH20,         {\"PUSH20\",          20, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH21,         {\"PUSH21\",          21, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH22,         {\"PUSH22\",          22, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH23,         {\"PUSH23\",          23, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH24,         {\"PUSH24\",          24, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH25,         {\"PUSH25\",          25, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH26,         {\"PUSH26\",          26, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH27,         {\"PUSH27\",          27, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH28,         {\"PUSH28\",          28, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH29,         {\"PUSH29\",          29, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH30,         {\"PUSH30\",          30, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH31,         {\"PUSH31\",          31, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::PUSH32,         {\"PUSH32\",          32, 0,   1,  false,      Tier::VeryLow}},\n\t{Instruction::DUP1,           {\"DUP1\",            0,  1,   2,  false,      Tier::VeryLow}},\n\t{Instruction::DUP2,           {\"DUP2\",            0,  2,   3,  false,      Tier::VeryLow}},\n\t{Instruction::DUP3,           {\"DUP3\",            0,  3,   4,  false,      Tier::VeryLow}},\n\t{Instruction::DUP4,           {\"DUP4\",            0,  4,   5,  false,      Tier::VeryLow}},\n\t{Instruction::DUP5,           {\"DUP5\",            0,  5,   6,  false,      Tier::VeryLow}},\n\t{Instruction::DUP6,           {\"DUP6\",            0,  6,   7,  false,      Tier::VeryLow}},\n\t{Instruction::DUP7,           {\"DUP7\",            0,  7,   8,  false,      Tier::VeryLow}},\n\t{Instruction::DUP8,           {\"DUP8\",            0,  8,   9,  false,      Tier::VeryLow}},\n\t{Instruction::DUP9,           {\"DUP9\",            0,  9,   10, false,      Tier::VeryLow}},\n\t{Instruction::DUP10,          {\"DUP10\",           0,  10,  11, false,      Tier::VeryLow}},\n\t{Instruction::DUP11,          {\"DUP11\",           0,  11,  12, false,      Tier::VeryLow}},\n\t{Instruction::DUP12,          {\"DUP12\",           0,  12,  13, false,      Tier::VeryLow}},\n\t{Instruction::DUP13,          {\"DUP13\",           0,  13,  14, false,      Tier::VeryLow}},\n\t{Instruction::DUP14,          {\"DUP14\",           0,  14,  15, false,      Tier::VeryLow}},\n\t{Instruction::DUP15,          {\"DUP15\",           0,  15,  16, false,      Tier::VeryLow}},\n\t{Instruction::DUP16,          {\"DUP16\",           0,  16,  17, false,      Tier::VeryLow}},\n\t{Instruction::SWAP1,          {\"SWAP1\",           0,  2,   2,  false,      Tier::VeryLow}},\n\t{Instruction::SWAP2,          {\"SWAP2\",           0,  3,   3,  false,      Tier::VeryLow}},\n\t{Instruction::SWAP3,          {\"SWAP3\",           0,  4,   4,  false,      Tier::VeryLow}},\n\t{Instruction::SWAP4,          {\"SWAP4\",           0,  5,   5,  false,      Tier::VeryLow}},\n\t{Instruction::SWAP5,          {\"SWAP5\",           0,  6,   6,  false,      Tier::VeryLow}},\n\t{Instruction::SWAP6,          {\"SWAP6\",           0,  7,   7,  false,      Tier::VeryLow}},\n\t{Instruction::SWAP7,          {\"SWAP7\",           0,  8,   8,  false,      Tier::VeryLow}},\n\t{Instruction::SWAP8,          {\"SWAP8\",           0,  9,   9,  false,      Tier::VeryLow}},\n\t{Instruction::SWAP9,          {\"SWAP9\",           0,  10,  10, false,      Tier::VeryLow}},\n\t{Instruction::SWAP10,         {\"SWAP10\",          0,  11,  11, false,      Tier::VeryLow}},\n\t{Instruction::SWAP11,         {\"SWAP11\",          0,  12,  12, false,      Tier::VeryLow}},\n\t{Instruction::SWAP12,         {\"SWAP12\",          0,  13,  13, false,      Tier::VeryLow}},\n\t{Instruction::SWAP13,         {\"SWAP13\",          0,  14,  14, false,      Tier::VeryLow}},\n\t{Instruction::SWAP14,         {\"SWAP14\",          0,  15,  15, false,      Tier::VeryLow}},\n\t{Instruction::SWAP15,         {\"SWAP15\",          0,  16,  16, false,      Tier::VeryLow}},\n\t{Instruction::SWAP16,         {\"SWAP16\",          0,  17,  17, false,      Tier::VeryLow}},\n\t{Instruction::LOG0,           {\"LOG0\",            0,  2,   0,  true,       Tier::Special}},\n\t{Instruction::LOG1,           {\"LOG1\",            0,  3,   0,  true,       Tier::Special}},\n\t{Instruction::LOG2,           {\"LOG2\",            0,  4,   0,  true,       Tier::Special}},\n\t{Instruction::LOG3,           {\"LOG3\",            0,  5,   0,  true,       Tier::Special}},\n\t{Instruction::LOG4,           {\"LOG4\",            0,  6,   0,  true,       Tier::Special}},\n\t{Instruction::RETF,           {\"RETF\",            0,  0,   0,  true,       Tier::RetF}},\n\t{Instruction::CALLF,          {\"CALLF\",           2,  0,   0,  true,       Tier::CallF}},\n\t{Instruction::JUMPF,          {\"JUMPF\",           2,  0,   0,  true,       Tier::JumpF}},\n\t{Instruction::SWAPN,          {\"SWAPN\",           1,  0,   0,  false,      Tier::VeryLow}},\n\t{Instruction::DUPN,           {\"DUPN\",            1,  0,   0,  false,      Tier::VeryLow}},\n\t{Instruction::EOFCREATE,      {\"EOFCREATE\",       1,  4,   1,  true,       Tier::Special}},\n\t{Instruction::RETURNCONTRACT, {\"RETURNCONTRACT\",  1,  2,   0,  true,       Tier::Special}},\n\t{Instruction::CREATE,         {\"CREATE\",          0,  3,   1,  true,       Tier::Special}},\n\t{Instruction::CALL,           {\"CALL\",            0,  7,   1,  true,       Tier::Special}},\n\t{Instruction::CALLCODE,       {\"CALLCODE\",        0,  7,   1,  true,       Tier::Special}},\n\t{Instruction::RETURN,         {\"RETURN\",          0,  2,   0,  true,       Tier::Zero}},\n\t{Instruction::DELEGATECALL,   {\"DELEGATECALL\",    0,  6,   1,  true,       Tier::Special}},\n\t{Instruction::STATICCALL,     {\"STATICCALL\",      0,  6,   1,  true,       Tier::Special}},\n\t{Instruction::EXTCALL,        {\"EXTCALL\",         0,  4,   1,  true,       Tier::Special}},\n\t{Instruction::EXTDELEGATECALL,{\"EXTDELEGATECALL\", 0,  3,   1,  true,       Tier::Special}},\n\t{Instruction::EXTSTATICCALL,  {\"EXTSTATICCALL\",   0,  3,   1,  true,       Tier::Special}},\n\t{Instruction::CREATE2,        {\"CREATE2\",         0,  4,   1,  true,       Tier::Special}},\n\t{Instruction::REVERT,         {\"REVERT\",          0,  2,   0,  true,       Tier::Zero}},\n\t{Instruction::INVALID,        {\"INVALID\",         0,  0,   0,  true,       Tier::Zero}},\n\t{Instruction::SELFDESTRUCT,   {\"SELFDESTRUCT\",    0,  1,   0,  true,       Tier::Special}}\n};\n\nInstructionInfo solidity::evmasm::instructionInfo(Instruction _inst, langutil::EVMVersion _evmVersion)\n{\n\ttry\n\t{\n\t\tif (_inst == Instruction::PREVRANDAO && _evmVersion < langutil::EVMVersion::paris())\n\t\t\treturn InstructionInfo({ \"DIFFICULTY\", 0, 0, 1, false, Tier::Base });\n\t\treturn c_instructionInfo.at(_inst);\n\t}\n\tcatch (...)\n\t{\n\t\treturn InstructionInfo({\"<INVALID_INSTRUCTION: \" + std::to_string(static_cast<unsigned>(_inst)) + \">\", 0, 0, 0, false, Tier::Invalid});\n\t}\n}\n\nbool solidity::evmasm::isValidInstruction(Instruction _inst)\n{\n\treturn !!c_instructionInfo.count(_inst);\n}\n"
  },
  {
    "path": "libevmasm/Instruction.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file Instruction.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#pragma once\n\n#include <libevmasm/Exceptions.h>\n#include <libsolutil/Common.h>\n#include <libsolutil/Assertions.h>\n#include <liblangutil/EVMVersion.h>\n#include <liblangutil/Exceptions.h>\n\nnamespace solidity::evmasm\n{\n\n/// Virtual machine bytecode instruction.\nenum class Instruction: uint8_t\n{\n\tSTOP = 0x00,              ///< halts execution\n\tADD,                      ///< addition operation\n\tMUL,                      ///< multiplication operation\n\tSUB,                      ///< subtraction operation\n\tDIV,                      ///< integer division operation\n\tSDIV,                     ///< signed integer division operation\n\tMOD,                      ///< modulo remainder operation\n\tSMOD,                     ///< signed modulo remainder operation\n\tADDMOD,                   ///< unsigned modular addition\n\tMULMOD,                   ///< unsigned modular multiplication\n\tEXP,                      ///< exponential operation\n\tSIGNEXTEND,               ///< extend length of signed integer\n\n\tLT = 0x10,                ///< less-than comparison\n\tGT,                       ///< greater-than comparison\n\tSLT,                      ///< signed less-than comparison\n\tSGT,                      ///< signed greater-than comparison\n\tEQ,                       ///< equality comparison\n\tISZERO,                   ///< simple not operator\n\tAND,                      ///< bitwise AND operation\n\tOR,                       ///< bitwise OR operation\n\tXOR,                      ///< bitwise XOR operation\n\tNOT,                      ///< bitwise NOT operation\n\tBYTE,                     ///< retrieve single byte from word\n\tSHL,                      ///< bitwise SHL operation\n\tSHR,                      ///< bitwise SHR operation\n\tSAR,                      ///< bitwise SAR operation\n\tCLZ,                      ///< count of leading zeros in binary representation\n\n\tKECCAK256 = 0x20,         ///< compute KECCAK-256 hash\n\n\tADDRESS = 0x30,           ///< get address of currently executing account\n\tBALANCE,                  ///< get balance of the given account\n\tORIGIN,                   ///< get execution origination address\n\tCALLER,                   ///< get caller address\n\tCALLVALUE,                ///< get deposited value by the instruction/transaction responsible for this execution\n\tCALLDATALOAD,             ///< get input data of current environment\n\tCALLDATASIZE,             ///< get size of input data in current environment\n\tCALLDATACOPY,             ///< copy input data in current environment to memory\n\tCODESIZE,                 ///< get size of code running in current environment\n\tCODECOPY,                 ///< copy code running in current environment to memory\n\tGASPRICE,                 ///< get price of gas in current environment\n\tEXTCODESIZE,              ///< get external code size (from another contract)\n\tEXTCODECOPY,              ///< copy external code (from another contract)\n\tRETURNDATASIZE = 0x3d,    ///< get size of return data buffer\n\tRETURNDATACOPY = 0x3e,    ///< copy return data in current environment to memory\n\tEXTCODEHASH = 0x3f,       ///< get external code hash (from another contract)\n\n\tBLOCKHASH = 0x40,         ///< get hash of most recent complete block\n\tCOINBASE,                 ///< get the block's coinbase address\n\tTIMESTAMP,                ///< get the block's timestamp\n\tNUMBER,                   ///< get the block's number\n\tPREVRANDAO,               ///< get randomness provided by the beacon chain\n\tGASLIMIT,                 ///< get the block's gas limit\n\tCHAINID,                  ///< get the config's chainid param\n\tSELFBALANCE,              ///< get balance of the current account\n\tBASEFEE,                  ///< get the block's basefee\n\tBLOBHASH = 0x49,          ///< get a versioned hash of one of the blobs associated with the transaction\n\tBLOBBASEFEE = 0x4a,       ///< get the block's blob basefee\n\n\tPOP = 0x50,               ///< remove item from stack\n\tMLOAD,                    ///< load word from memory\n\tMSTORE,                   ///< save word to memory\n\tMSTORE8,                  ///< save byte to memory\n\tSLOAD,                    ///< load word from storage\n\tSSTORE,                   ///< save word to storage\n\tJUMP,                     ///< alter the program counter\n\tJUMPI,                    ///< conditionally alter the program counter\n\tPC,                       ///< get the program counter\n\tMSIZE,                    ///< get the size of active memory\n\tGAS,                      ///< get the amount of available gas\n\tJUMPDEST,                 ///< set a potential jump destination\n\tTLOAD = 0x5c,             ///< load word from transient storage\n\tTSTORE = 0x5d,            ///< save word to transient storage\n\tMCOPY = 0x5e,             ///< copy between memory areas\n\n\tPUSH0 = 0x5f,             ///< place the value 0 on stack\n\tPUSH1 = 0x60,             ///< place 1 byte item on stack\n\tPUSH2,                    ///< place 2 byte item on stack\n\tPUSH3,                    ///< place 3 byte item on stack\n\tPUSH4,                    ///< place 4 byte item on stack\n\tPUSH5,                    ///< place 5 byte item on stack\n\tPUSH6,                    ///< place 6 byte item on stack\n\tPUSH7,                    ///< place 7 byte item on stack\n\tPUSH8,                    ///< place 8 byte item on stack\n\tPUSH9,                    ///< place 9 byte item on stack\n\tPUSH10,                   ///< place 10 byte item on stack\n\tPUSH11,                   ///< place 11 byte item on stack\n\tPUSH12,                   ///< place 12 byte item on stack\n\tPUSH13,                   ///< place 13 byte item on stack\n\tPUSH14,                   ///< place 14 byte item on stack\n\tPUSH15,                   ///< place 15 byte item on stack\n\tPUSH16,                   ///< place 16 byte item on stack\n\tPUSH17,                   ///< place 17 byte item on stack\n\tPUSH18,                   ///< place 18 byte item on stack\n\tPUSH19,                   ///< place 19 byte item on stack\n\tPUSH20,                   ///< place 20 byte item on stack\n\tPUSH21,                   ///< place 21 byte item on stack\n\tPUSH22,                   ///< place 22 byte item on stack\n\tPUSH23,                   ///< place 23 byte item on stack\n\tPUSH24,                   ///< place 24 byte item on stack\n\tPUSH25,                   ///< place 25 byte item on stack\n\tPUSH26,                   ///< place 26 byte item on stack\n\tPUSH27,                   ///< place 27 byte item on stack\n\tPUSH28,                   ///< place 28 byte item on stack\n\tPUSH29,                   ///< place 29 byte item on stack\n\tPUSH30,                   ///< place 30 byte item on stack\n\tPUSH31,                   ///< place 31 byte item on stack\n\tPUSH32,                   ///< place 32 byte item on stack\n\n\tDUP1 = 0x80,              ///< copies the highest item in the stack to the top of the stack\n\tDUP2,                     ///< copies the second highest item in the stack to the top of the stack\n\tDUP3,                     ///< copies the third highest item in the stack to the top of the stack\n\tDUP4,                     ///< copies the 4th highest item in the stack to the top of the stack\n\tDUP5,                     ///< copies the 5th highest item in the stack to the top of the stack\n\tDUP6,                     ///< copies the 6th highest item in the stack to the top of the stack\n\tDUP7,                     ///< copies the 7th highest item in the stack to the top of the stack\n\tDUP8,                     ///< copies the 8th highest item in the stack to the top of the stack\n\tDUP9,                     ///< copies the 9th highest item in the stack to the top of the stack\n\tDUP10,                    ///< copies the 10th highest item in the stack to the top of the stack\n\tDUP11,                    ///< copies the 11th highest item in the stack to the top of the stack\n\tDUP12,                    ///< copies the 12th highest item in the stack to the top of the stack\n\tDUP13,                    ///< copies the 13th highest item in the stack to the top of the stack\n\tDUP14,                    ///< copies the 14th highest item in the stack to the top of the stack\n\tDUP15,                    ///< copies the 15th highest item in the stack to the top of the stack\n\tDUP16,                    ///< copies the 16th highest item in the stack to the top of the stack\n\n\tSWAP1 = 0x90,             ///< swaps the highest and second highest value on the stack\n\tSWAP2,                    ///< swaps the highest and third highest value on the stack\n\tSWAP3,                    ///< swaps the highest and 4th highest value on the stack\n\tSWAP4,                    ///< swaps the highest and 5th highest value on the stack\n\tSWAP5,                    ///< swaps the highest and 6th highest value on the stack\n\tSWAP6,                    ///< swaps the highest and 7th highest value on the stack\n\tSWAP7,                    ///< swaps the highest and 8th highest value on the stack\n\tSWAP8,                    ///< swaps the highest and 9th highest value on the stack\n\tSWAP9,                    ///< swaps the highest and 10th highest value on the stack\n\tSWAP10,                   ///< swaps the highest and 11th highest value on the stack\n\tSWAP11,                   ///< swaps the highest and 12th highest value on the stack\n\tSWAP12,                   ///< swaps the highest and 13th highest value on the stack\n\tSWAP13,                   ///< swaps the highest and 14th highest value on the stack\n\tSWAP14,                   ///< swaps the highest and 15th highest value on the stack\n\tSWAP15,                   ///< swaps the highest and 16th highest value on the stack\n\tSWAP16,                   ///< swaps the highest and 17th highest value on the stack\n\n\tLOG0 = 0xa0,              ///< Makes a log entry; no topics.\n\tLOG1,                     ///< Makes a log entry; 1 topic.\n\tLOG2,                     ///< Makes a log entry; 2 topics.\n\tLOG3,                     ///< Makes a log entry; 3 topics.\n\tLOG4,                     ///< Makes a log entry; 4 topics.\n\n\tDATALOADN = 0xd1,         ///< load data from EOF data section\n\n\tRJUMP = 0xe0,             ///< relative jump\n\tRJUMPI = 0xe1,            ///< conditional relative jump\n\tCALLF = 0xe3,             ///< call function in a EOF code section\n\tRETF = 0xe4,              ///< return to caller from the code section of EOF container\n\tJUMPF = 0xe5,             ///< jump to a code section of EOF container without adding a new return stack frame.\n\tDUPN = 0xe6,              ///< copies a value at the stack depth given as immediate argument to the top of the stack\n\tSWAPN = 0xe7,             ///< swaps the highest value with a value at a stack depth given as immediate argument\n\tEOFCREATE = 0xec,         ///< create a new account with associated container code.\n\tRETURNCONTRACT = 0xee,    ///< return container to be deployed with axiliary data filled in.\n\tCREATE = 0xf0,            ///< create a new account with associated code\n\tCALL,                     ///< message-call into an account\n\tCALLCODE,                 ///< message-call with another account's code only\n\tRETURN,                   ///< halt execution returning output data\n\tDELEGATECALL,             ///< like CALLCODE but keeps caller's value and sender\n\tCREATE2 = 0xf5,           ///< create new account with associated code at address `sha3(0xff + sender + salt + init code) % 2**160`\n\tEXTCALL = 0xf8,           ///< EOF message-call into an account\n\tEXTDELEGATECALL = 0xf9,   ///< EOF delegate call\n\tSTATICCALL = 0xfa,        ///< like CALL but disallow state modifications\n\tEXTSTATICCALL = 0xfb,     ///< like EXTCALL but disallow state modifications\n\n\tREVERT = 0xfd,            ///< halt execution, revert state and return output data\n\tINVALID = 0xfe,           ///< invalid instruction for expressing runtime errors (e.g., division-by-zero)\n\tSELFDESTRUCT = 0xff       ///< halt execution and register account for later deletion\n};\n\n/// @returns true if the instruction is of the CALL opcode family\nconstexpr bool isCallInstruction(Instruction _inst) noexcept\n{\n\tswitch (_inst)\n\t{\n\t\tcase Instruction::CALL:\n\t\tcase Instruction::CALLCODE:\n\t\tcase Instruction::DELEGATECALL:\n\t\tcase Instruction::STATICCALL:\n\t\tcase Instruction::EXTCALL:\n\t\tcase Instruction::EXTSTATICCALL:\n\t\tcase Instruction::EXTDELEGATECALL:\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\n/// @returns true if the instruction is a PUSH\ninline bool isPushInstruction(Instruction _inst)\n{\n\treturn Instruction::PUSH0 <= _inst && _inst <= Instruction::PUSH32;\n}\n\n/// @returns true if the instruction is a LOG\ninline bool isLogInstruction(Instruction _inst)\n{\n\treturn Instruction::LOG0 <= _inst && _inst <= Instruction::LOG4;\n}\n\n/// @returns the number of PUSH Instruction _inst\ninline unsigned getPushNumber(Instruction _inst)\n{\n\treturn static_cast<uint8_t>(_inst) - unsigned(Instruction::PUSH0);\n}\n\n/// @returns the number of LOG Instruction _inst\ninline unsigned getLogNumber(Instruction _inst)\n{\n\treturn static_cast<uint8_t>(_inst) - unsigned(Instruction::LOG0);\n}\n\n/// @returns the PUSH<_number> instruction\ninline Instruction pushInstruction(unsigned _number)\n{\n\tsolAssert(_number <= 32);\n\treturn Instruction(unsigned(Instruction::PUSH0) + _number);\n}\n\n/// @returns the DUP<_number> instruction\ninline Instruction dupInstruction(unsigned _number)\n{\n\tsolAssert(1 <= _number && _number <= 16);\n\treturn Instruction(unsigned(Instruction::DUP1) + _number - 1);\n}\n\n/// @returns the SWAP<_number> instruction\ninline Instruction swapInstruction(unsigned _number)\n{\n\tsolAssert(1 <= _number && _number <= 16);\n\treturn Instruction(unsigned(Instruction::SWAP1) + _number - 1);\n}\n\n/// @returns the LOG<_number> instruction\ninline Instruction logInstruction(unsigned _number)\n{\n\tsolAssert(_number <= 4);\n\treturn Instruction(unsigned(Instruction::LOG0) + _number);\n}\n\n/// Gas price tiers representing static cost of an instruction.\n/// Opcodes whose cost is dynamic or depends on EVM version should use the `Special` tier and need\n/// dedicated logic in GasMeter (especially in estimateMax()).\n/// The tiers loosely follow opcode groups originally defined in the Yellow Paper.\nenum class Tier\n{\n\t// NOTE: Tiers should be ordered by cost, since we sometimes perform comparisons between them.\n\tZero = 0,   // 0, Zero\n\tBase,       // 2, Quick\n\tRJump,      // 2, RJump\n\tVeryLow,    // 3, Fastest\n\tRetF,       // 3,\n\tRJumpI,     // 4,\n\tLow,        // 5, Fast\n\tCallF,      // 5,\n\tJumpF,      // 5,\n\tMid,        // 8, Mid\n\tHigh,       // 10, Slow\n\tBlockHash,  // 20\n\tWarmAccess, // 100, Warm Access\n\tSpecial,    // multiparam or otherwise special\n\tInvalid,    // Invalid.\n};\n\n/// Information structure for a particular instruction.\nstruct InstructionInfo\n{\n\tstd::string name;   ///< The name of the instruction.\n\tint additional;     ///< Additional items required in memory for this instructions (only for PUSH).\n\tint args;           ///< Number of items required on the stack for this instruction (and, for the purposes of ret, the number taken from the stack).\n\tint ret;            ///< Number of items placed (back) on the stack by this instruction, assuming args items were removed.\n\tbool sideEffects;   ///< false if the only effect on the execution environment (apart from gas usage) is a change to a topmost segment of the stack\n\tTier gasPriceTier;  ///< Tier for gas pricing.\n};\n\n/// Information on all the instructions.\nInstructionInfo instructionInfo(Instruction _inst, langutil::EVMVersion _evmVersion);\n\n/// check whether instructions exists.\nbool isValidInstruction(Instruction _inst);\n\n/// Convert from string mnemonic to Instruction type.\nextern const std::map<std::string, Instruction, std::less<>> c_instructions;\n\n}\n"
  },
  {
    "path": "libevmasm/JumpdestRemover.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Alex Beregszaszi\n * Removes unused JUMPDESTs.\n */\n\n#include <libevmasm/JumpdestRemover.h>\n\n#include <libevmasm/AssemblyItem.h>\n\n#include <limits>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::evmasm;\n\nbool JumpdestRemover::optimise(std::set<size_t> const& _tagsReferencedFromOutside)\n{\n\tstd::set<size_t> references{referencedTags(m_items, SubAssemblyID{})};\n\treferences.insert(_tagsReferencedFromOutside.begin(), _tagsReferencedFromOutside.end());\n\n\tsize_t initialSize = m_items.size();\n\t/// Remove tags which are never referenced.\n\tauto pend = remove_if(\n\t\tm_items.begin(),\n\t\tm_items.end(),\n\t\t[&](AssemblyItem const& _item)\n\t\t{\n\t\t\tif (_item.type() != Tag)\n\t\t\t\treturn false;\n\t\t\tauto asmIdAndTag = _item.splitForeignPushTag();\n\t\t\tsolAssert(asmIdAndTag.first.empty(), \"Sub-assembly tag used as label.\");\n\t\t\tsize_t tag = asmIdAndTag.second;\n\t\t\treturn !references.count(tag);\n\t\t}\n\t);\n\tm_items.erase(pend, m_items.end());\n\treturn m_items.size() != initialSize;\n}\n\nstd::set<size_t> JumpdestRemover::referencedTags(AssemblyItems const& _items, SubAssemblyID _subId)\n{\n\tstd::set<size_t> ret;\n\tfor (auto const& item: _items)\n\t\tif (item.type() == PushTag || item.type() == RelativeJump || item.type() == ConditionalRelativeJump)\n\t\t{\n\t\t\tauto subAndTag = item.splitForeignPushTag();\n\t\t\tif (subAndTag.first == _subId)\n\t\t\t\tret.insert(subAndTag.second);\n\t\t}\n\treturn ret;\n}\n"
  },
  {
    "path": "libevmasm/JumpdestRemover.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Alex Beregszaszi\n * Removes unused JUMPDESTs.\n */\n#pragma once\n\n#include <libevmasm/SubAssemblyID.h>\n\n#include <vector>\n#include <cstddef>\n#include <set>\n\nnamespace solidity::evmasm\n{\nclass AssemblyItem;\nusing AssemblyItems = std::vector<AssemblyItem>;\n\nclass JumpdestRemover\n{\npublic:\n\texplicit JumpdestRemover(AssemblyItems& _items): m_items(_items) {}\n\n\tbool optimise(std::set<size_t> const& _tagsReferencedFromOutside);\n\n\t/// @returns a set of all tags from the given sub-assembly that are referenced\n\t/// from the given list of items.\n\tstatic std::set<size_t> referencedTags(AssemblyItems const& _items, SubAssemblyID _subId);\n\nprivate:\n\tAssemblyItems& m_items;\n};\n\n}\n"
  },
  {
    "path": "libevmasm/KnownState.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file KnownState.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Contains knowledge about the state of the virtual machine at a specific instruction.\n */\n\n#include <libevmasm/KnownState.h>\n#include <libevmasm/AssemblyItem.h>\n#include <libsolutil/Keccak256.h>\n\n#include <functional>\n#include <utility>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::langutil;\n\nstd::ostream& KnownState::stream(std::ostream& _out) const\n{\n\tauto streamExpressionClass = [this](std::ostream& _out, Id _id)\n\t{\n\t\tauto const& expr = m_expressionClasses->representative(_id);\n\t\t_out << \"  \" << std::dec << _id << \": \";\n\t\tif (!expr.item)\n\t\t\t_out << \" no item\";\n\t\telse if (expr.item->type() == UndefinedItem)\n\t\t\t_out << \" unknown \" << static_cast<int>(expr.item->data());\n\t\telse\n\t\t\t_out << *expr.item;\n\t\tif (expr.sequenceNumber)\n\t\t\t_out << \"@\" << std::dec << expr.sequenceNumber;\n\t\t_out << \"(\";\n\t\tfor (Id arg: expr.arguments)\n\t\t\t_out << std::dec << arg << \",\";\n\t\t_out << \")\" << std::endl;\n\t};\n\n\t_out << \"=== State ===\" << std::endl;\n\t_out << \"Stack height: \" << std::dec << m_stackHeight << std::endl;\n\t_out << \"Equivalence classes:\" << std::endl;\n\tfor (Id eqClass = 0; eqClass < m_expressionClasses->size(); ++eqClass)\n\t\tstreamExpressionClass(_out, eqClass);\n\n\t_out << \"Stack:\" << std::endl;\n\tfor (auto const& it: m_stackElements)\n\t{\n\t\t_out << \"  \" << std::dec << it.first << \": \";\n\t\tstreamExpressionClass(_out, it.second);\n\t}\n\t_out << \"Storage:\" << std::endl;\n\tfor (auto const& it: m_storageContent)\n\t{\n\t\t_out << \"  \";\n\t\tstreamExpressionClass(_out, it.first);\n\t\t_out << \": \";\n\t\tstreamExpressionClass(_out, it.second);\n\t}\n\t_out << \"Memory:\" << std::endl;\n\tfor (auto const& it: m_memoryContent)\n\t{\n\t\t_out << \"  \";\n\t\tstreamExpressionClass(_out, it.first);\n\t\t_out << \": \";\n\t\tstreamExpressionClass(_out, it.second);\n\t}\n\n\treturn _out;\n}\n\nKnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool _copyItem)\n{\n\tStoreOperation op;\n\tif (_item.type() == Tag)\n\t{\n\t\t// can be ignored\n\t}\n\telse if (_item.type() == AssignImmutable)\n\t{\n\t\t// Since AssignImmutable breaks blocks, it should be fine to only consider its changes to the stack, which\n\t\t// is the same as two POPs.\n\t\t// Note that the StoreOperation for POP is generic and _copyItem is ignored.\n\t\tfeedItem(AssemblyItem(Instruction::POP), _copyItem);\n\t\treturn feedItem(AssemblyItem(Instruction::POP), _copyItem);\n\t}\n\telse if (_item.type() == VerbatimBytecode)\n\t{\n\t\tm_sequenceNumber += 2;\n\t\tresetMemory();\n\t\tresetKnownKeccak256Hashes();\n\t\tresetStorage();\n\t\t// Consume all arguments and place unknown return values on the stack.\n\t\tm_stackElements.erase(\n\t\t\tm_stackElements.upper_bound(m_stackHeight - static_cast<int>(_item.arguments())),\n\t\t\tm_stackElements.end()\n\t\t);\n\t\tm_stackHeight += static_cast<int>(_item.deposit());\n\t\tfor (size_t i = 0; i < _item.returnValues(); ++i)\n\t\t\tsetStackElement(\n\t\t\t\tm_stackHeight - static_cast<int>(i),\n\t\t\t\tm_expressionClasses->newClass(_item.debugData())\n\t\t\t);\n\t}\n\telse if (_item.type() != Operation)\n\t{\n\t\tsolAssert(_item.deposit() == 1);\n\t\tif (_item.pushedValue())\n\t\t\t// only available after assembly stage, should not be used for optimisation\n\t\t\tsetStackElement(++m_stackHeight, m_expressionClasses->find(*_item.pushedValue()));\n\t\telse\n\t\t\tsetStackElement(++m_stackHeight, m_expressionClasses->find(_item, {}, _copyItem));\n\t}\n\telse\n\t{\n\t\tInstruction instruction = _item.instruction();\n\t\t// The latest EVMVersion is used here, since the InstructionInfo is assumed to be\n\t\t// the same across all EVM versions except for the instruction name.\n\t\tInstructionInfo info = instructionInfo(instruction, EVMVersion());\n\t\tif (SemanticInformation::isDupInstruction(_item))\n\t\t\tsetStackElement(\n\t\t\t\tm_stackHeight + 1,\n\t\t\t\tstackElement(\n\t\t\t\t\tm_stackHeight - (static_cast<int>(SemanticInformation::getDupNumber(_item)) - 1),\n\t\t\t\t\t_item.debugData()\n\t\t\t\t)\n\t\t\t);\n\t\telse if (SemanticInformation::isSwapInstruction(_item))\n\t\t\tswapStackElements(\n\t\t\t\tm_stackHeight,\n\t\t\t\tm_stackHeight - 1 - (static_cast<int>(SemanticInformation::getSwapNumber(_item)) - 1),\n\t\t\t\t_item.debugData()\n\t\t\t);\n\t\telse if (instruction != Instruction::POP)\n\t\t{\n\t\t\tstd::vector<Id> arguments(static_cast<size_t>(info.args));\n\t\t\tfor (size_t i = 0; i < static_cast<size_t>(info.args); ++i)\n\t\t\t\targuments[i] = stackElement(m_stackHeight - static_cast<int>(i), _item.debugData());\n\t\t\tswitch (_item.instruction())\n\t\t\t{\n\t\t\tcase Instruction::SSTORE:\n\t\t\t\top = storeInStorage(arguments[0], arguments[1], _item.debugData());\n\t\t\t\tbreak;\n\t\t\tcase Instruction::SLOAD:\n\t\t\t\tsetStackElement(\n\t\t\t\t\tm_stackHeight + static_cast<int>(_item.deposit()),\n\t\t\t\t\tloadFromStorage(arguments[0], _item.debugData())\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase Instruction::MSTORE:\n\t\t\t\top = storeInMemory(arguments[0], arguments[1], _item.debugData());\n\t\t\t\tbreak;\n\t\t\tcase Instruction::MLOAD:\n\t\t\t\tsetStackElement(\n\t\t\t\t\tm_stackHeight + static_cast<int>(_item.deposit()),\n\t\t\t\t\tloadFromMemory(arguments[0], _item.debugData())\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase Instruction::KECCAK256:\n\t\t\t\tsetStackElement(\n\t\t\t\t\tm_stackHeight + static_cast<int>(_item.deposit()),\n\t\t\t\t\tapplyKeccak256(arguments.at(0), arguments.at(1), _item.debugData())\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbool invMem =\n\t\t\t\t\tSemanticInformation::memory(_item.instruction()) == SemanticInformation::Write;\n\t\t\t\tbool invStor =\n\t\t\t\t\tSemanticInformation::storage(_item.instruction()) == SemanticInformation::Write;\n\t\t\t\t// We could be a bit more fine-grained here (CALL only invalidates part of\n\t\t\t\t// memory, etc), but we do not for now.\n\t\t\t\tif (invMem)\n\t\t\t\t{\n\t\t\t\t\tresetMemory();\n\t\t\t\t\tresetKnownKeccak256Hashes();\n\t\t\t\t}\n\t\t\t\tif (invStor)\n\t\t\t\t\tresetStorage();\n\t\t\t\tif (invMem || invStor)\n\t\t\t\t\tm_sequenceNumber += 2; // Increment by two because it can read and write\n\t\t\t\tsolAssert(info.ret <= 1);\n\t\t\t\tif (info.ret == 1)\n\t\t\t\t\tsetStackElement(\n\t\t\t\t\t\tm_stackHeight + static_cast<int>(_item.deposit()),\n\t\t\t\t\t\tm_expressionClasses->find(_item, arguments, _copyItem)\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tm_stackElements.erase(\n\t\t\tm_stackElements.upper_bound(m_stackHeight + static_cast<int>(_item.deposit())),\n\t\t\tm_stackElements.end()\n\t\t);\n\t\tm_stackHeight += static_cast<int>(_item.deposit());\n\t}\n\treturn op;\n}\n\n/// Helper function for KnownState::reduceToCommonKnowledge, removes everything from\n/// _this which is not in or not equal to the value in _other.\ntemplate <class Mapping> void intersect(Mapping& _this, Mapping const& _other)\n{\n\tfor (auto it = _this.begin(); it != _this.end();)\n\t\tif (_other.count(it->first) && _other.at(it->first) == it->second)\n\t\t\t++it;\n\t\telse\n\t\t\tit = _this.erase(it);\n}\n\nvoid KnownState::reduceToCommonKnowledge(KnownState const& _other, bool _combineSequenceNumbers)\n{\n\tint stackDiff = m_stackHeight - _other.m_stackHeight;\n\tfor (auto it = m_stackElements.begin(); it != m_stackElements.end();)\n\t\tif (_other.m_stackElements.count(it->first - stackDiff))\n\t\t{\n\t\t\tId other = _other.m_stackElements.at(it->first - stackDiff);\n\t\t\tif (it->second == other)\n\t\t\t\t++it;\n\t\t\telse\n\t\t\t{\n\t\t\t\tstd::set<u256> theseTags = tagsInExpression(it->second);\n\t\t\t\tstd::set<u256> otherTags = tagsInExpression(other);\n\t\t\t\tif (!theseTags.empty() && !otherTags.empty())\n\t\t\t\t{\n\t\t\t\t\ttheseTags.insert(otherTags.begin(), otherTags.end());\n\t\t\t\t\tit->second = tagUnion(theseTags);\n\t\t\t\t\t++it;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tit = m_stackElements.erase(it);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tit = m_stackElements.erase(it);\n\n\t// Use the smaller stack height. Essential to terminate in case of loops.\n\tif (m_stackHeight > _other.m_stackHeight)\n\t{\n\t\tstd::map<int, Id> shiftedStack;\n\t\tfor (auto const& stackElement: m_stackElements)\n\t\t\tshiftedStack[stackElement.first - stackDiff] = stackElement.second;\n\t\tm_stackElements = std::move(shiftedStack);\n\t\tm_stackHeight = _other.m_stackHeight;\n\t}\n\n\tintersect(m_storageContent, _other.m_storageContent);\n\tintersect(m_memoryContent, _other.m_memoryContent);\n\tif (_combineSequenceNumbers)\n\t\tm_sequenceNumber = std::max(m_sequenceNumber, _other.m_sequenceNumber);\n}\n\nbool KnownState::operator==(KnownState const& _other) const\n{\n\tif (m_storageContent != _other.m_storageContent || m_memoryContent != _other.m_memoryContent)\n\t\treturn false;\n\tint stackDiff = m_stackHeight - _other.m_stackHeight;\n\tauto thisIt = m_stackElements.cbegin();\n\tauto otherIt = _other.m_stackElements.cbegin();\n\tfor (; thisIt != m_stackElements.cend() && otherIt != _other.m_stackElements.cend(); ++thisIt, ++otherIt)\n\t\tif (thisIt->first - stackDiff != otherIt->first || thisIt->second != otherIt->second)\n\t\t\treturn false;\n\treturn (thisIt == m_stackElements.cend() && otherIt == _other.m_stackElements.cend());\n}\n\nExpressionClasses::Id KnownState::stackElement(int _stackHeight, langutil::DebugData::ConstPtr _debugData)\n{\n\tif (m_stackElements.count(_stackHeight))\n\t\treturn m_stackElements.at(_stackHeight);\n\t// Stack element not found (not assigned yet), create new unknown equivalence class.\n\treturn m_stackElements[_stackHeight] =\n\t\t\tm_expressionClasses->find(AssemblyItem(UndefinedItem, _stackHeight, std::move(_debugData)));\n}\n\nKnownState::Id KnownState::relativeStackElement(int _stackOffset, langutil::DebugData::ConstPtr _debugData)\n{\n\treturn stackElement(m_stackHeight + _stackOffset, std::move(_debugData));\n}\n\nvoid KnownState::clearTagUnions()\n{\n\tfor (auto it = m_stackElements.begin(); it != m_stackElements.end();)\n\t\tif (m_tagUnions.left.count(it->second))\n\t\t\tit = m_stackElements.erase(it);\n\t\telse\n\t\t\t++it;\n}\n\nvoid KnownState::setStackElement(int _stackHeight, Id _class)\n{\n\tm_stackElements[_stackHeight] = _class;\n}\n\nvoid KnownState::swapStackElements(\n\tint _stackHeightA,\n\tint _stackHeightB,\n\tlangutil::DebugData::ConstPtr _debugData\n)\n{\n\tassertThrow(_stackHeightA != _stackHeightB, OptimizerException, \"Swap on same stack elements.\");\n\t// ensure they are created\n\tstackElement(_stackHeightA, _debugData);\n\tstackElement(_stackHeightB, _debugData);\n\n\tstd::swap(m_stackElements[_stackHeightA], m_stackElements[_stackHeightB]);\n}\n\nKnownState::StoreOperation KnownState::storeInStorage(\n\tId _slot,\n\tId _value,\n\tlangutil::DebugData::ConstPtr _debugData\n)\n{\n\tif (m_storageContent.count(_slot) && m_storageContent[_slot] == _value)\n\t\t// do not execute the storage if we know that the value is already there\n\t\treturn StoreOperation();\n\tm_sequenceNumber++;\n\tdecltype(m_storageContent) storageContents;\n\t// Copy over all values (i.e. retain knowledge about them) where we know that this store\n\t// operation will not destroy the knowledge. Specifically, we copy storage locations we know\n\t// are different from _slot or locations where we know that the stored value is equal to _value.\n\tfor (auto const& storageItem: m_storageContent)\n\t\tif (m_expressionClasses->knownToBeDifferent(storageItem.first, _slot) || storageItem.second == _value)\n\t\t\tstorageContents.insert(storageItem);\n\tm_storageContent = std::move(storageContents);\n\n\tAssemblyItem item(Instruction::SSTORE, std::move(_debugData));\n\tId id = m_expressionClasses->find(item, {_slot, _value}, true, m_sequenceNumber);\n\tStoreOperation operation{StoreOperation::Storage, _slot, m_sequenceNumber, id};\n\tm_storageContent[_slot] = _value;\n\t// increment a second time so that we get unique sequence numbers for writes\n\tm_sequenceNumber++;\n\n\treturn operation;\n}\n\nExpressionClasses::Id KnownState::loadFromStorage(Id _slot, langutil::DebugData::ConstPtr _debugData)\n{\n\tif (m_storageContent.count(_slot))\n\t\treturn m_storageContent.at(_slot);\n\n\tAssemblyItem item(Instruction::SLOAD, std::move(_debugData));\n\treturn m_storageContent[_slot] = m_expressionClasses->find(item, {_slot}, true, m_sequenceNumber);\n}\n\nKnownState::StoreOperation KnownState::storeInMemory(Id _slot, Id _value, langutil::DebugData::ConstPtr _debugData)\n{\n\tif (m_memoryContent.count(_slot) && m_memoryContent[_slot] == _value)\n\t\t// do not execute the store if we know that the value is already there\n\t\treturn StoreOperation();\n\tm_sequenceNumber++;\n\tdecltype(m_memoryContent) memoryContents;\n\t// copy over values at points where we know that they are different from _slot by at least 32\n\tfor (auto const& memoryItem: m_memoryContent)\n\t\tif (m_expressionClasses->knownToBeDifferentBy32(memoryItem.first, _slot))\n\t\t\tmemoryContents.insert(memoryItem);\n\tm_memoryContent = std::move(memoryContents);\n\n\tAssemblyItem item(Instruction::MSTORE, std::move(_debugData));\n\tId id = m_expressionClasses->find(item, {_slot, _value}, true, m_sequenceNumber);\n\tStoreOperation operation{StoreOperation::Memory, _slot, m_sequenceNumber, id};\n\tm_memoryContent[_slot] = _value;\n\t// increment a second time so that we get unique sequence numbers for writes\n\tm_sequenceNumber++;\n\treturn operation;\n}\n\nExpressionClasses::Id KnownState::loadFromMemory(Id _slot, langutil::DebugData::ConstPtr _debugData)\n{\n\tif (m_memoryContent.count(_slot))\n\t\treturn m_memoryContent.at(_slot);\n\n\tAssemblyItem item(Instruction::MLOAD, std::move(_debugData));\n\treturn m_memoryContent[_slot] = m_expressionClasses->find(item, {_slot}, true, m_sequenceNumber);\n}\n\nKnownState::Id KnownState::applyKeccak256(\n\tId _start,\n\tId _length,\n\tlangutil::DebugData::ConstPtr _debugData\n)\n{\n\tAssemblyItem keccak256Item(Instruction::KECCAK256, _debugData);\n\t// Special logic if length is a short constant, otherwise we cannot tell.\n\tu256 const* l = m_expressionClasses->knownConstant(_length);\n\t// unknown or too large length\n\tif (!l || *l > 128)\n\t\treturn m_expressionClasses->find(keccak256Item, {_start, _length}, true, m_sequenceNumber);\n\tunsigned length = unsigned(*l);\n\tstd::vector<Id> arguments;\n\tfor (unsigned i = 0; i < length; i += 32)\n\t{\n\t\tId slot = m_expressionClasses->find(\n\t\t\tAssemblyItem(Instruction::ADD, _debugData),\n\t\t\t{_start, m_expressionClasses->find(u256(i))}\n\t\t);\n\t\targuments.push_back(loadFromMemory(slot, _debugData));\n\t}\n\tif (m_knownKeccak256Hashes.count({arguments, length}))\n\t\treturn m_knownKeccak256Hashes.at({arguments, length});\n\tId v;\n\t// If all arguments are known constants, compute the Keccak-256 here\n\tif (all_of(arguments.begin(), arguments.end(), [this](Id _a) { return !!m_expressionClasses->knownConstant(_a); }))\n\t{\n\t\tbytes data;\n\t\tfor (Id a: arguments)\n\t\t\tdata += toBigEndian(*m_expressionClasses->knownConstant(a));\n\t\tdata.resize(length);\n\t\tv = m_expressionClasses->find(AssemblyItem(u256(util::keccak256(data)), _debugData));\n\t}\n\telse\n\t\tv = m_expressionClasses->find(keccak256Item, {_start, _length}, true, m_sequenceNumber);\n\treturn m_knownKeccak256Hashes[{arguments, length}] = v;\n}\n\nstd::set<u256> KnownState::tagsInExpression(KnownState::Id _expressionId)\n{\n\tif (m_tagUnions.left.count(_expressionId))\n\t\treturn m_tagUnions.left.at(_expressionId);\n\t// Might be a tag, then return the set of itself.\n\tExpressionClasses::Expression expr = m_expressionClasses->representative(_expressionId);\n\tif (expr.item && expr.item->type() == PushTag)\n\t\treturn std::set<u256>({expr.item->data()});\n\telse\n\t\treturn std::set<u256>();\n}\n\nKnownState::Id KnownState::tagUnion(std::set<u256> _tags)\n{\n\tif (m_tagUnions.right.count(_tags))\n\t\treturn m_tagUnions.right.at(_tags);\n\telse\n\t{\n\t\tId id = m_expressionClasses->newClass(langutil::DebugData::create());\n\t\tm_tagUnions.right.insert(make_pair(_tags, id));\n\t\treturn id;\n\t}\n}\n"
  },
  {
    "path": "libevmasm/KnownState.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file KnownState.h\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Contains knowledge about the state of the virtual machine at a specific instruction.\n */\n\n#pragma once\n\n#if defined(__clang__)\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wredeclared-class-member\"\n#endif // defined(__clang__)\n\n// Disable warning about nodiscard. Could be a compiler bug, might be removed in the future.\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable: 4834)\n#endif\n\n#include <boost/bimap.hpp>\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n#if defined(__clang__)\n#pragma clang diagnostic pop\n#endif // defined(__clang__)\n\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/Exceptions.h>\n#include <libevmasm/ExpressionClasses.h>\n#include <libevmasm/SemanticInformation.h>\n\n#include <limits>\n#include <utility>\n#include <vector>\n#include <map>\n#include <set>\n#include <tuple>\n#include <memory>\n#include <ostream>\n\nnamespace solidity::langutil\n{\nstruct SourceLocation;\n}\n\nnamespace solidity::evmasm\n{\n\nclass AssemblyItem;\nusing AssemblyItems = std::vector<AssemblyItem>;\n\n/**\n * Class to infer and store knowledge about the state of the virtual machine at a specific\n * instruction.\n *\n * The general workings are that for each assembly item that is fed, an equivalence class is\n * derived from the operation and the equivalence class of its arguments. DUPi, SWAPi and some\n * arithmetic instructions are used to infer equivalences while these classes are determined.\n */\nclass KnownState\n{\npublic:\n\tusing Id = ExpressionClasses::Id;\n\tstruct StoreOperation\n\t{\n\t\tenum Target { Invalid, Memory, Storage };\n\n\t\tbool isValid() const { return target != Invalid; }\n\n\t\tTarget target{Invalid};\n\t\tId slot{std::numeric_limits<Id>::max()};\n\t\tunsigned sequenceNumber{std::numeric_limits<unsigned>::max()};\n\t\tId expression{std::numeric_limits<Id>::max()};\n\t};\n\n\texplicit KnownState(\n\t\tstd::shared_ptr<ExpressionClasses> _expressionClasses = std::make_shared<ExpressionClasses>()\n\t): m_expressionClasses(std::move(_expressionClasses))\n\t{\n\t}\n\n\t/// Streams debugging information to @a _out.\n\tstd::ostream& stream(std::ostream& _out) const;\n\n\t/// Feeds the item into the system for analysis.\n\t/// @returns a possible store operation\n\tStoreOperation feedItem(AssemblyItem const& _item, bool _copyItem = false);\n\n\t/// Resets any knowledge about storage.\n\tvoid resetStorage() { m_storageContent.clear(); }\n\t/// Resets any knowledge about memory.\n\tvoid resetMemory() { m_memoryContent.clear(); }\n\t/// Resets known Keccak-256 hashes\n\tvoid resetKnownKeccak256Hashes() { m_knownKeccak256Hashes.clear(); }\n\t/// Resets any knowledge about the current stack.\n\tvoid resetStack() { m_stackElements.clear(); m_stackHeight = 0; }\n\t/// Resets any knowledge.\n\tvoid reset() { resetStorage(); resetMemory(); resetKnownKeccak256Hashes(); resetStack(); }\n\n\tunsigned sequenceNumber() const { return m_sequenceNumber; }\n\n\t/// Replaces the state by the intersection with _other, i.e. only equal knowledge is retained.\n\t/// If the stack heighht is different, the smaller one is used and the stack is compared\n\t/// relatively.\n\t/// @param _combineSequenceNumbers if true, sets the sequence number to the maximum of both\n\tvoid reduceToCommonKnowledge(KnownState const& _other, bool _combineSequenceNumbers);\n\n\t/// @returns a shared pointer to a copy of this state.\n\tstd::shared_ptr<KnownState> copy() const { return std::make_shared<KnownState>(*this); }\n\n\t/// @returns true if the knowledge about the state of both objects is (known to be) equal.\n\tbool operator==(KnownState const& _other) const;\n\n\t/// Retrieves the current equivalence class for the given stack element (or generates a new\n\t/// one if it does not exist yet).\n\tId stackElement(int _stackHeight, langutil::DebugData::ConstPtr _debugData);\n\t/// @returns the stackElement relative to the current stack height.\n\tId relativeStackElement(int _stackOffset, langutil::DebugData::ConstPtr _debugData = {});\n\n\t/// @returns its set of tags if the given expression class is a known tag union; returns a set\n\t/// containing the tag if it is a PushTag expression and the empty set otherwise.\n\tstd::set<u256> tagsInExpression(Id _expressionId);\n\t/// During analysis, different tags on the stack are partially treated as the same class.\n\t/// This removes such classes not to confuse later analyzers.\n\tvoid clearTagUnions();\n\n\tint stackHeight() const { return m_stackHeight; }\n\tstd::map<int, Id> const& stackElements() const { return m_stackElements; }\n\tExpressionClasses& expressionClasses() const { return *m_expressionClasses; }\n\n\tstd::map<Id, Id> const& storageContent() const { return m_storageContent; }\n\nprivate:\n\t/// Assigns a new equivalence class to the next sequence number of the given stack element.\n\tvoid setStackElement(int _stackHeight, Id _class);\n\t/// Swaps the given stack elements in their next sequence number.\n\tvoid swapStackElements(int _stackHeightA, int _stackHeightB, langutil::DebugData::ConstPtr _debugData);\n\n\t/// Increments the sequence number, deletes all storage information that might be overwritten\n\t/// and stores the new value at the given slot.\n\t/// @returns the store operation, which might be invalid if storage was not modified\n\tStoreOperation storeInStorage(Id _slot, Id _value,langutil::DebugData::ConstPtr _debugData);\n\t/// Retrieves the current value at the given slot in storage or creates a new special sload class.\n\tId loadFromStorage(Id _slot, langutil::DebugData::ConstPtr _debugData);\n\t/// Increments the sequence number, deletes all memory information that might be overwritten\n\t/// and stores the new value at the given slot.\n\t/// @returns the store operation, which might be invalid if memory was not modified\n\tStoreOperation storeInMemory(Id _slot, Id _value, langutil::DebugData::ConstPtr _debugData);\n\t/// Retrieves the current value at the given slot in memory or creates a new special mload class.\n\tId loadFromMemory(Id _slot, langutil::DebugData::ConstPtr _debugData);\n\t/// Finds or creates a new expression that applies the Keccak-256 hash function to the contents in memory.\n\tId applyKeccak256(Id _start, Id _length, langutil::DebugData::ConstPtr _debugData);\n\n\t/// @returns a new or already used Id representing the given set of tags.\n\tId tagUnion(std::set<u256> _tags);\n\n\t/// Current stack height, can be negative.\n\tint m_stackHeight = 0;\n\t/// Current stack layout, mapping stack height -> equivalence class\n\tstd::map<int, Id> m_stackElements;\n\t/// Current sequence number, this is incremented with each modification to storage or memory.\n\tunsigned m_sequenceNumber = 1;\n\t/// Knowledge about storage content.\n\tstd::map<Id, Id> m_storageContent;\n\t/// Knowledge about memory content. Keys are memory addresses, note that the values overlap\n\t/// and are not contained here if they are not completely known.\n\tstd::map<Id, Id> m_memoryContent;\n\t/// Keeps record of all Keccak-256 hashes that are computed. The first parameter in the\n\t/// std::pair corresponds to memory content and the second parameter corresponds to the length\n\t/// that is accessed.\n\tstd::map<std::pair<std::vector<Id>, unsigned>, Id> m_knownKeccak256Hashes;\n\t/// Structure containing the classes of equivalent expressions.\n\tstd::shared_ptr<ExpressionClasses> m_expressionClasses;\n\t/// Container for unions of tags stored on the stack.\n\tboost::bimap<Id, std::set<u256>> m_tagUnions;\n};\n\n}\n"
  },
  {
    "path": "libevmasm/LinkerObject.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file LinkerObject.cpp\n * @author Christian R <c@ethdev.com>\n * @date 2015\n */\n\n#include <libevmasm/LinkerObject.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Keccak256.h>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::evmasm;\n\nvoid LinkerObject::append(LinkerObject const& _other)\n{\n\tfor (auto const& ref: _other.linkReferences)\n\t\tlinkReferences[ref.first + bytecode.size()] = ref.second;\n\tbytecode += _other.bytecode;\n}\n\nvoid LinkerObject::link(std::map<std::string, h160> const& _libraryAddresses)\n{\n\tstd::map<size_t, std::string> remainingRefs;\n\tfor (auto const& linkRef: linkReferences)\n\t\tif (h160 const* address = matchLibrary(linkRef.second, _libraryAddresses))\n\t\t\tcopy(address->data(), address->data() + 20, bytecode.begin() + std::vector<uint8_t>::difference_type(linkRef.first));\n\t\telse\n\t\t\tremainingRefs.insert(linkRef);\n\tlinkReferences.swap(remainingRefs);\n}\n\nstd::string LinkerObject::toHex() const\n{\n\tstd::string hex = solidity::util::toHex(bytecode);\n\tfor (auto const& ref: linkReferences)\n\t{\n\t\tsize_t pos = ref.first * 2;\n\t\tstd::string hash = libraryPlaceholder(ref.second);\n\t\thex[pos] = hex[pos + 1] = hex[pos + 38] = hex[pos + 39] = '_';\n\t\tfor (size_t i = 0; i < 36; ++i)\n\t\t\thex[pos + 2 + i] = hash.at(i);\n\t}\n\treturn hex;\n}\n\nstd::string LinkerObject::libraryPlaceholder(std::string const& _libraryName)\n{\n\treturn \"$\" + keccak256(_libraryName).hex().substr(0, 34) + \"$\";\n}\n\nh160 const*\nLinkerObject::matchLibrary(\n\tstd::string const& _linkRefName,\n\tstd::map<std::string, h160> const& _libraryAddresses\n)\n{\n\tauto it = _libraryAddresses.find(_linkRefName);\n\tif (it != _libraryAddresses.end())\n\t\treturn &it->second;\n\treturn nullptr;\n}\n\nbool LinkerObject::operator<(LinkerObject const& _other) const\n{\n\treturn tie(this->bytecode, this->linkReferences, this->immutableReferences) <\n\t\t\ttie(_other.bytecode, _other.linkReferences, _other.immutableReferences);\n}\n"
  },
  {
    "path": "libevmasm/LinkerObject.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file Assembly.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#pragma once\n\n#include <libsolutil/Common.h>\n#include <libsolutil/FixedHash.h>\n\nnamespace solidity::evmasm\n{\n\n/**\n * Binary object that potentially still needs to be linked (i.e. addresses of other contracts\n * need to be filled in).\n */\nstruct LinkerObject\n{\n\tusing ImmutableRefs = std::pair<std::string, std::vector<size_t>>;\n\t/// The bytecode.\n\tbytes bytecode;\n\n\t/// Map from offsets in bytecode to library identifiers. The addresses starting at those offsets\n\t/// need to be replaced by the actual addresses by the linker.\n\tstd::map<size_t, std::string> linkReferences;\n\n\t/// Map from hashes of the identifiers of immutable variables to the full identifier of the immutable and\n\t/// to a list of offsets into the bytecode that refer to their values.\n\tstd::map<u256, ImmutableRefs> immutableReferences;\n\n\tstruct InstructionLocation\n\t{\n\t\t/// Absolute position of instruction's opcode within the bytecode.\n\t\t/// The opcode takes up exactly one byte and is assumed to be followed by its immediate arguments.\n\t\tsize_t start{};\n\t\t/// Absolute position of the first byte past the end of the instruction, including potential immediate arguments.\n\t\tsize_t end{};\n\t\t/// Index of the AssemblyItem that produced the instruction within the Assembly.\n\t\t/// While items of most types generate a single instruction, in general it can be more than one.\n\t\tsize_t assemblyItemIndex{};\n\t};\n\tstruct CodeSectionLocation\n\t{\n\t\t/// Absolute position of the first byte belonging to the code section.\n\t\t/// Equal to instructionLocations[0].start if the code section is not empty.\n\t\tsize_t start{};\n\t\t/// Absolute position of the first byte past end of the code section.\n\t\t/// Greater or equal to start. Must be equal if instructionLocations is empty.\n\t\tsize_t end{};\n\t\t/// Descriptions of all instructions contained within the code section.\n\t\t/// The instructions are assumed to fill the whole section, without any gaps or duplicates.\n\t\t/// The areas between opcodes are assumed to contain their immediate arguments, of size appropriate for the opcode type.\n\t\t/// The arguments of the last instruction extend to the end of the section.\n\t\t/// The instructions must be ordered according to their positions (ascending).\n\t\tstd::vector<InstructionLocation> instructionLocations;\n\t};\n\t/// Descriptions of all code sections in the ascending order of their positions.\n\t/// There are no duplicates and the sections never overlap.\n\t/// Only sections belonging to the top-level assembly are included, even if the bytecode contains subassemblies.\n\tstd::vector<CodeSectionLocation> codeSectionLocations;\n\n\tstruct FunctionDebugData\n\t{\n\t\tstd::optional<size_t> bytecodeOffset;\n\t\tstd::optional<size_t> instructionIndex;\n\t\tstd::optional<size_t> sourceID;\n\t\tsize_t params = {};\n\t\tsize_t returns = {};\n\t};\n\n\t/// Bytecode offsets of named tags like function entry points.\n\tstd::map<std::string, FunctionDebugData> functionDebugData;\n\n\t/// Appends the bytecode of @a _other and incorporates its link references.\n\tvoid append(LinkerObject const& _other);\n\n\t/// Links the given libraries by replacing their uses in the code and removes them from the references.\n\tvoid link(std::map<std::string, util::h160> const& _libraryAddresses);\n\n\t/// @returns a hex representation of the bytecode of the given object, replacing unlinked\n\t/// addresses by placeholders. This output is lowercase.\n\tstd::string toHex() const;\n\n\t/// @returns a 36 character string that is used as a placeholder for the library\n\t/// address (enclosed by `__` on both sides). The placeholder is the hex representation\n\t/// of the first 18 bytes of the keccak-256 hash of @a _libraryName.\n\tstatic std::string libraryPlaceholder(std::string const& _libraryName);\n\n\tbool operator<(LinkerObject const& _other) const;\n\nprivate:\n\tstatic util::h160 const* matchLibrary(\n\t\tstd::string const& _linkRefName,\n\t\tstd::map<std::string, util::h160> const& _libraryAddresses\n\t);\n};\n\n}\n"
  },
  {
    "path": "libevmasm/PathGasMeter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file PathGasMeter.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n */\n\n#include <libevmasm/PathGasMeter.h>\n#include <libevmasm/KnownState.h>\n#include <libevmasm/SemanticInformation.h>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\n\nPathGasMeter::PathGasMeter(AssemblyItems const& _items, langutil::EVMVersion _evmVersion):\n\tm_items(_items), m_evmVersion(_evmVersion)\n{\n\tfor (size_t i = 0; i < m_items.size(); ++i)\n\t\tif (m_items[i].type() == Tag)\n\t\t\tm_tagPositions[m_items[i].data()] = i;\n}\n\nGasMeter::GasConsumption PathGasMeter::estimateMax(\n\tsize_t _startIndex,\n\tstd::shared_ptr<KnownState> const& _state\n)\n{\n\tauto path = std::make_unique<GasPath>();\n\tpath->index = _startIndex;\n\tpath->state = _state->copy();\n\tqueue(std::move(path));\n\n\tGasMeter::GasConsumption gas;\n\twhile (!m_queue.empty() && !gas.isInfinite)\n\t\tgas = std::max(gas, handleQueueItem());\n\treturn gas;\n}\n\nvoid PathGasMeter::queue(std::unique_ptr<GasPath>&& _newPath)\n{\n\tif (\n\t\tm_highestGasUsagePerJumpdest.count(_newPath->index) &&\n\t\t_newPath->gas < m_highestGasUsagePerJumpdest.at(_newPath->index)\n\t)\n\t\treturn;\n\tm_highestGasUsagePerJumpdest[_newPath->index] = _newPath->gas;\n\tm_queue[_newPath->index] = std::move(_newPath);\n}\n\nGasMeter::GasConsumption PathGasMeter::handleQueueItem()\n{\n\tassertThrow(!m_queue.empty(), OptimizerException, \"\");\n\n\tstd::unique_ptr<GasPath> path = std::move(m_queue.rbegin()->second);\n\tm_queue.erase(--m_queue.end());\n\n\tstd::shared_ptr<KnownState> state = path->state;\n\tGasMeter meter(state, m_evmVersion, path->largestMemoryAccess);\n\tExpressionClasses& classes = state->expressionClasses();\n\tGasMeter::GasConsumption gas = path->gas;\n\tsize_t index = path->index;\n\n\tif (index >= m_items.size() || (index > 0 && m_items.at(index).type() != Tag))\n\t\t// Invalid jump usually provokes an out-of-gas exception, but we want to give an upper\n\t\t// bound on the gas that is needed without changing the behaviour, so it is fine to\n\t\t// return the current gas value.\n\t\treturn gas;\n\n\tstd::set<u256> jumpTags;\n\tfor (; index < m_items.size() && !gas.isInfinite; ++index)\n\t{\n\t\tbool branchStops = false;\n\t\tjumpTags.clear();\n\t\tAssemblyItem const& item = m_items.at(index);\n\t\tif (item.type() == Tag || item == AssemblyItem(Instruction::JUMPDEST))\n\t\t{\n\t\t\t// Do not allow any backwards jump. This is quite restrictive but should work for\n\t\t\t// the simplest things.\n\t\t\tif (path->visitedJumpdests.count(index))\n\t\t\t\treturn GasMeter::GasConsumption::infinite();\n\t\t\tpath->visitedJumpdests.insert(index);\n\t\t}\n\t\telse if (item == AssemblyItem(Instruction::JUMP))\n\t\t{\n\t\t\tbranchStops = true;\n\t\t\tjumpTags = state->tagsInExpression(state->relativeStackElement(0));\n\t\t\tif (jumpTags.empty()) // unknown jump destination\n\t\t\t\treturn GasMeter::GasConsumption::infinite();\n\t\t}\n\t\telse if (item == AssemblyItem(Instruction::JUMPI))\n\t\t{\n\t\t\tExpressionClasses::Id condition = state->relativeStackElement(-1);\n\t\t\tif (classes.knownNonZero(condition) || !classes.knownZero(condition))\n\t\t\t{\n\t\t\t\tjumpTags = state->tagsInExpression(state->relativeStackElement(0));\n\t\t\t\tif (jumpTags.empty()) // unknown jump destination\n\t\t\t\t\treturn GasMeter::GasConsumption::infinite();\n\t\t\t}\n\t\t\tbranchStops = classes.knownNonZero(condition);\n\t\t}\n\t\telse if (SemanticInformation::altersControlFlow(item))\n\t\t\tbranchStops = true;\n\n\t\tgas += meter.estimateMax(item);\n\n\t\tfor (u256 const& tag: jumpTags)\n\t\t{\n\t\t\tauto newPath = std::make_unique<GasPath>();\n\t\t\tnewPath->index = m_items.size();\n\t\t\tif (m_tagPositions.count(tag))\n\t\t\t\tnewPath->index = m_tagPositions.at(tag);\n\t\t\tnewPath->gas = gas;\n\t\t\tnewPath->largestMemoryAccess = meter.largestMemoryAccess();\n\t\t\tnewPath->state = state->copy();\n\t\t\tnewPath->visitedJumpdests = path->visitedJumpdests;\n\t\t\tqueue(std::move(newPath));\n\t\t}\n\n\t\tif (branchStops)\n\t\t\tbreak;\n\t}\n\n\treturn gas;\n}\n"
  },
  {
    "path": "libevmasm/PathGasMeter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file PathGasMeter.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n */\n\n#pragma once\n\n#include <libevmasm/GasMeter.h>\n\n#include <liblangutil/EVMVersion.h>\n\n#include <set>\n#include <vector>\n#include <memory>\n\nnamespace solidity::evmasm\n{\n\nclass KnownState;\n\nstruct GasPath\n{\n\tsize_t index = 0;\n\tstd::shared_ptr<KnownState> state;\n\tu256 largestMemoryAccess;\n\tGasMeter::GasConsumption gas;\n\tstd::set<size_t> visitedJumpdests;\n};\n\n/**\n * Computes an upper bound on the gas usage of a computation starting at a certain position in\n * a list of AssemblyItems in a given state until the computation stops.\n * Can be used to estimate the gas usage of functions on any given input.\n */\nclass PathGasMeter\n{\npublic:\n\texplicit PathGasMeter(AssemblyItems const& _items, langutil::EVMVersion _evmVersion);\n\n\tGasMeter::GasConsumption estimateMax(size_t _startIndex, std::shared_ptr<KnownState> const& _state);\n\n\tstatic GasMeter::GasConsumption estimateMax(\n\t\tAssemblyItems const& _items,\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tsize_t _startIndex,\n\t\tstd::shared_ptr<KnownState> const& _state\n\t)\n\t{\n\t\treturn PathGasMeter(_items, _evmVersion).estimateMax(_startIndex, _state);\n\t}\n\nprivate:\n\t/// Adds a new path item to the queue, but only if we do not already have\n\t/// a higher gas usage at that point.\n\t/// This is not exact as different state might influence higher gas costs at a later\n\t/// point in time, but it greatly reduces computational overhead.\n\tvoid queue(std::unique_ptr<GasPath>&& _newPath);\n\tGasMeter::GasConsumption handleQueueItem();\n\n\t/// Map of jumpdest -> gas path, so not really a queue. We only have one queued up\n\t/// item per jumpdest, because of the behaviour of `queue` above.\n\tstd::map<size_t, std::unique_ptr<GasPath>> m_queue;\n\tstd::map<size_t, GasMeter::GasConsumption> m_highestGasUsagePerJumpdest;\n\tstd::map<u256, size_t> m_tagPositions;\n\tAssemblyItems const& m_items;\n\tlangutil::EVMVersion m_evmVersion;\n};\n\n}\n"
  },
  {
    "path": "libevmasm/PeepholeOptimiser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file PeepholeOptimiser.cpp\n * Performs local optimising code changes to assembly.\n */\n\n#include <libevmasm/PeepholeOptimiser.h>\n\n#include <libevmasm/AssemblyItem.h>\n#include <libevmasm/SemanticInformation.h>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\n\n// TODO: Extend this to use the tools from ExpressionClasses.cpp\n\nnamespace\n{\n\nstruct OptimiserState\n{\n\tAssemblyItems const& items;\n\tsize_t i;\n\tstd::back_insert_iterator<AssemblyItems> out;\n\tlangutil::EVMVersion evmVersion = langutil::EVMVersion();\n};\n\ntemplate<typename FunctionType>\nstruct FunctionParameterCount;\ntemplate<typename R, typename... Args>\nstruct FunctionParameterCount<R(Args...)>\n{\n\tstatic constexpr auto value = sizeof...(Args);\n};\n\ntemplate <class Method>\nstruct SimplePeepholeOptimizerMethod\n{\n\ttemplate <size_t... Indices>\n\tstatic bool applyRule(\n\t\tAssemblyItems::const_iterator _in,\n\t\tstd::back_insert_iterator<AssemblyItems> _out,\n\t\tstd::index_sequence<Indices...>\n\t)\n\t{\n\t\treturn Method::applySimple(_in[Indices]..., _out);\n\t}\n\tstatic bool apply(OptimiserState& _state)\n\t{\n\t\tstatic constexpr size_t WindowSize = FunctionParameterCount<decltype(Method::applySimple)>::value - 1;\n\t\tif (\n\t\t\t_state.i + WindowSize <= _state.items.size() &&\n\t\t\tapplyRule(_state.items.begin() + static_cast<ptrdiff_t>(_state.i), _state.out, std::make_index_sequence<WindowSize>{})\n\t\t)\n\t\t{\n\t\t\t_state.i += WindowSize;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nstruct Identity: SimplePeepholeOptimizerMethod<Identity>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _item,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\t*_out = _item;\n\t\treturn true;\n\t}\n};\n\nstruct PushPop: SimplePeepholeOptimizerMethod<PushPop>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _push,\n\t\tAssemblyItem const& _pop,\n\t\tstd::back_insert_iterator<AssemblyItems>\n\t)\n\t{\n\t\tauto t = _push.type();\n\t\treturn _pop == Instruction::POP && (\n\t\t\tSemanticInformation::isDupInstruction(_push) ||\n\t\t\tt == Push || t == PushTag || t == PushSub ||\n\t\t\tt == PushSubSize || t == PushProgramSize || t == PushData || t == PushLibraryAddress\n\t\t);\n\t}\n};\n\nstruct OpPop: SimplePeepholeOptimizerMethod<OpPop>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _op,\n\t\tAssemblyItem const& _pop,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (_pop == Instruction::POP && _op.type() == Operation)\n\t\t{\n\t\t\tInstruction instr = _op.instruction();\n\t\t\tauto const& info = instructionInfo(instr, langutil::EVMVersion());\n\t\t\tif (info.ret == 1 && !info.sideEffects)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < info.args; j++)\n\t\t\t\t\t*_out = {Instruction::POP, _op.debugData()};\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n};\n\nstruct OpStop: SimplePeepholeOptimizerMethod<OpStop>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _op,\n\t\tAssemblyItem const& _stop,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (_stop == Instruction::STOP)\n\t\t{\n\t\t\tif (_op.type() == Operation)\n\t\t\t{\n\t\t\t\tInstruction instr = _op.instruction();\n\t\t\t\tif (!instructionInfo(instr, langutil::EVMVersion()).sideEffects)\n\t\t\t\t{\n\t\t\t\t\t*_out = {Instruction::STOP, _op.debugData()};\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (_op.type() == Push)\n\t\t\t{\n\t\t\t\t*_out = {Instruction::STOP, _op.debugData()};\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n};\n\nstruct OpReturnRevert: SimplePeepholeOptimizerMethod<OpReturnRevert>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _op,\n\t\tAssemblyItem const& _push,\n\t\tAssemblyItem const& _pushOrDup,\n\t\tAssemblyItem const& _returnRevert,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t(_returnRevert == Instruction::RETURN || _returnRevert == Instruction::REVERT) &&\n\t\t\t_push.type() == Push &&\n\t\t\t(_pushOrDup.type() == Push || _pushOrDup == dupInstruction(1))\n\t\t)\n\t\t\tif (\n\t\t\t\t(_op.type() == Operation && !instructionInfo(_op.instruction(), langutil::EVMVersion()).sideEffects) ||\n\t\t\t\t_op.type() == Push\n\t\t\t)\n\t\t\t{\n\t\t\t\t\t*_out = _push;\n\t\t\t\t\t*_out = _pushOrDup;\n\t\t\t\t\t*_out = _returnRevert;\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\treturn false;\n\t}\n};\n\nstruct DoubleSwap: SimplePeepholeOptimizerMethod<DoubleSwap>\n{\n\tstatic size_t applySimple(\n\t\tAssemblyItem const& _s1,\n\t\tAssemblyItem const& _s2,\n\t\tstd::back_insert_iterator<AssemblyItems>\n\t)\n\t{\n\t\treturn _s1 == _s2 && SemanticInformation::isSwapInstruction(_s1);\n\t}\n};\n\nstruct DoublePush\n{\n\tstatic bool apply(OptimiserState& _state)\n\t{\n\t\tsize_t windowSize = 2;\n\t\tif (_state.i + windowSize > _state.items.size())\n\t\t\treturn false;\n\n\t\tauto push1 = _state.items.begin() + static_cast<ptrdiff_t>(_state.i);\n\t\tauto push2 = _state.items.begin() + static_cast<ptrdiff_t>(_state.i + 1);\n\t\tassertThrow(push1 != _state.items.end() && push2 != _state.items.end(), OptimizerException, \"\");\n\n\t\tif (\n\t\t\tpush1->type() == Push &&\n\t\t\tpush2->type() == Push &&\n\t\t\tpush1->data() == push2->data() &&\n\t\t\t(!_state.evmVersion.hasPush0() || push1->data() != 0)\n\t\t)\n\t\t{\n\t\t\t*_state.out = *push1;\n\t\t\t*_state.out = {Instruction::DUP1, push2->debugData()};\n\t\t\t_state.i += windowSize;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nstruct CommutativeSwap: SimplePeepholeOptimizerMethod<CommutativeSwap>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _swap,\n\t\tAssemblyItem const& _op,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\t// Remove SWAP1 if following instruction is commutative\n\t\tif (\n\t\t\t_swap == Instruction::SWAP1 &&\n\t\t\tSemanticInformation::isCommutativeOperation(_op)\n\t\t)\n\t\t{\n\t\t\t*_out = _op;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nstruct SwapComparison: SimplePeepholeOptimizerMethod<SwapComparison>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _swap,\n\t\tAssemblyItem const& _op,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tstatic std::map<Instruction, Instruction> const swappableOps{\n\t\t\t{ Instruction::LT, Instruction::GT },\n\t\t\t{ Instruction::GT, Instruction::LT },\n\t\t\t{ Instruction::SLT, Instruction::SGT },\n\t\t\t{ Instruction::SGT, Instruction::SLT }\n\t\t};\n\n\t\tif (\n\t\t\t_swap == Instruction::SWAP1 &&\n\t\t\t_op.type() == Operation &&\n\t\t\tswappableOps.count(_op.instruction())\n\t\t)\n\t\t{\n\t\t\t*_out = swappableOps.at(_op.instruction());\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\n/// Remove swapN after dupN\nstruct DupSwap: SimplePeepholeOptimizerMethod<DupSwap>\n{\n\tstatic size_t applySimple(\n\t\tAssemblyItem const& _dupN,\n\t\tAssemblyItem const& _swapN,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\tSemanticInformation::isDupInstruction(_dupN) &&\n\t\t\tSemanticInformation::isSwapInstruction(_swapN) &&\n\t\t\tSemanticInformation::getDupNumber(_dupN) == SemanticInformation::getSwapNumber(_swapN)\n\t\t)\n\t\t{\n\t\t\t*_out = _dupN;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\n\nstruct IsZeroIsZeroJumpI: SimplePeepholeOptimizerMethod<IsZeroIsZeroJumpI>\n{\n\tstatic size_t applySimple(\n\t\tAssemblyItem const& _iszero1,\n\t\tAssemblyItem const& _iszero2,\n\t\tAssemblyItem const& _pushTag,\n\t\tAssemblyItem const& _jumpi,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t_iszero1 == Instruction::ISZERO &&\n\t\t\t_iszero2 == Instruction::ISZERO &&\n\t\t\t_pushTag.type() == PushTag &&\n\t\t\t_jumpi == Instruction::JUMPI\n\t\t)\n\t\t{\n\t\t\t*_out = _pushTag;\n\t\t\t*_out = _jumpi;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nstruct IsZeroIsZeroRJumpI: SimplePeepholeOptimizerMethod<IsZeroIsZeroRJumpI>\n{\n\tstatic size_t applySimple(\n\t\tAssemblyItem const& _iszero1,\n\t\tAssemblyItem const& _iszero2,\n\t\tAssemblyItem const& _rjumpi,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t_iszero1 == Instruction::ISZERO &&\n\t\t\t_iszero2 == Instruction::ISZERO &&\n\t\t\t_rjumpi.type() == ConditionalRelativeJump\n\t\t)\n\t\t{\n\t\t\t*_out = _rjumpi;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nstruct EqIsZeroJumpI: SimplePeepholeOptimizerMethod<EqIsZeroJumpI>\n{\n\tstatic size_t applySimple(\n\t\tAssemblyItem const& _eq,\n\t\tAssemblyItem const& _iszero,\n\t\tAssemblyItem const& _pushTag,\n\t\tAssemblyItem const& _jumpi,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t_eq == Instruction::EQ &&\n\t\t\t_iszero == Instruction::ISZERO &&\n\t\t\t_pushTag.type() == PushTag &&\n\t\t\t_jumpi == Instruction::JUMPI\n\t\t)\n\t\t{\n\t\t\t*_out = AssemblyItem(Instruction::SUB, _eq.debugData());\n\t\t\t*_out = _pushTag;\n\t\t\t*_out = _jumpi;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nstruct EqIsZeroRJumpI: SimplePeepholeOptimizerMethod<EqIsZeroRJumpI>\n{\n\tstatic size_t applySimple(\n\t\tAssemblyItem const& _eq,\n\t\tAssemblyItem const& _iszero,\n\t\tAssemblyItem const& _rjumpi,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t_eq == Instruction::EQ &&\n\t\t\t_iszero == Instruction::ISZERO &&\n\t\t\t_rjumpi.type() == ConditionalRelativeJump\n\t\t)\n\t\t{\n\t\t\t*_out = AssemblyItem(Instruction::SUB, _eq.debugData());\n\t\t\t*_out = _rjumpi;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\n// push_tag_1 jumpi push_tag_2 jump tag_1: -> iszero push_tag_2 jumpi tag_1:\nstruct DoubleJump: SimplePeepholeOptimizerMethod<DoubleJump>\n{\n\tstatic size_t applySimple(\n\t\tAssemblyItem const& _pushTag1,\n\t\tAssemblyItem const& _jumpi,\n\t\tAssemblyItem const& _pushTag2,\n\t\tAssemblyItem const& _jump,\n\t\tAssemblyItem const& _tag1,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t_pushTag1.type() == PushTag &&\n\t\t\t_jumpi == Instruction::JUMPI &&\n\t\t\t_pushTag2.type() == PushTag &&\n\t\t\t_jump == Instruction::JUMP &&\n\t\t\t_tag1.type() == Tag &&\n\t\t\t_pushTag1.data() == _tag1.data()\n\t\t)\n\t\t{\n\t\t\t*_out = AssemblyItem(Instruction::ISZERO, _jumpi.debugData());\n\t\t\t*_out = _pushTag2;\n\t\t\t*_out = _jumpi;\n\t\t\t*_out = _tag1;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\n// rjumpi(tag_1) rjump(tag_2) tag_1: -> iszero rjumpi(tag_2) tag_1:\nstruct DoubleRJump: SimplePeepholeOptimizerMethod<DoubleRJump>\n{\n\tstatic size_t applySimple(\n\t\tAssemblyItem const& _rjumpi,\n\t\tAssemblyItem const& _rjump,\n\t\tAssemblyItem const& _tag1,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t_rjumpi.type() == ConditionalRelativeJump &&\n\t\t\t_rjump.type() == RelativeJump &&\n\t\t\t_tag1.type() == Tag &&\n\t\t\t_rjumpi.data() == _tag1.data()\n\t\t)\n\t\t{\n\t\t\t*_out = AssemblyItem(Instruction::ISZERO, _rjumpi.debugData());\n\t\t\t*_out = AssemblyItem::conditionalRelativeJumpTo(_rjump.tag(), _rjump.debugData());\n\t\t\t*_out = _tag1;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nstruct JumpToNext: SimplePeepholeOptimizerMethod<JumpToNext>\n{\n\tstatic size_t applySimple(\n\t\tAssemblyItem const& _pushTag,\n\t\tAssemblyItem const& _jump,\n\t\tAssemblyItem const& _tag,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t_pushTag.type() == PushTag &&\n\t\t\t(_jump == Instruction::JUMP || _jump == Instruction::JUMPI) &&\n\t\t\t_tag.type() == Tag &&\n\t\t\t_pushTag.data() == _tag.data()\n\t\t)\n\t\t{\n\t\t\tif (_jump == Instruction::JUMPI)\n\t\t\t\t*_out = AssemblyItem(Instruction::POP, _jump.debugData());\n\t\t\t*_out = _tag;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nstruct RJumpToNext: SimplePeepholeOptimizerMethod<RJumpToNext>\n{\n\tstatic size_t applySimple(\n\t\tAssemblyItem const& _rjump,\n\t\tAssemblyItem const& _tag,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t(_rjump.type() == ConditionalRelativeJump || _rjump.type() == RelativeJump) &&\n\t\t\t_tag.type() == Tag &&\n\t\t\t_rjump.data() == _tag.data()\n\t\t)\n\t\t{\n\t\t\tif (_rjump.type() == ConditionalRelativeJump)\n\t\t\t\t*_out = AssemblyItem(Instruction::POP, _rjump.debugData());\n\t\t\t*_out = _tag;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nstruct TagConjunctions: SimplePeepholeOptimizerMethod<TagConjunctions>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _pushTag,\n\t\tAssemblyItem const& _pushConstant,\n\t\tAssemblyItem const& _and,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (_and != Instruction::AND)\n\t\t\treturn false;\n\t\tif (\n\t\t\t_pushTag.type() == PushTag &&\n\t\t\t_pushConstant.type() == Push &&\n\t\t\t(_pushConstant.data() & u256(0xFFFFFFFF)) == u256(0xFFFFFFFF)\n\t\t)\n\t\t{\n\t\t\t*_out = _pushTag;\n\t\t\treturn true;\n\t\t}\n\t\telse if (\n\t\t\t// tag and constant are swapped\n\t\t\t_pushConstant.type() == PushTag &&\n\t\t\t_pushTag.type() == Push &&\n\t\t\t(_pushTag.data() & u256(0xFFFFFFFF)) == u256(0xFFFFFFFF)\n\t\t)\n\t\t{\n\t\t\t*_out = _pushConstant;\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nstruct TruthyAnd: SimplePeepholeOptimizerMethod<TruthyAnd>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _push,\n\t\tAssemblyItem const& _not,\n\t\tAssemblyItem const& _and,\n\t\tstd::back_insert_iterator<AssemblyItems>\n\t)\n\t{\n\t\treturn (\n\t\t\t_push.type() == Push && _push.data() == 0 &&\n\t\t\t_not == Instruction::NOT &&\n\t\t\t_and == Instruction::AND\n\t\t);\n\t}\n};\n\n/// Removes everything after an non-continuing instruction until the next Tag.\n/// Note: JUMPF can return but to the caller's parent call frame.\n/// So it won't continue from the next to the JUMPF instruction\nstruct UnreachableCode\n{\n\tstatic bool apply(OptimiserState& _state)\n\t{\n\t\tauto it = _state.items.begin() + static_cast<ptrdiff_t>(_state.i);\n\t\tauto end = _state.items.end();\n\t\tif (it == end)\n\t\t\treturn false;\n\n\t\tif (\n\t\t\tit[0] != Instruction::JUMP &&\n\t\t\tit[0] != Instruction::RETURN &&\n\t\t\tit[0] != Instruction::STOP &&\n\t\t\tit[0] != Instruction::INVALID &&\n\t\t\tit[0] != Instruction::SELFDESTRUCT &&\n\t\t\tit[0] != Instruction::REVERT &&\n\t\t\tit[0] != Instruction::RJUMP &&\n\t\t\tit[0] != Instruction::JUMPF &&\n\t\t\tit[0] != Instruction::RETF &&\n\t\t\tit[0] != Instruction::RETURNCONTRACT\n\t\t)\n\t\t\treturn false;\n\n\t\tptrdiff_t i = 1;\n\t\twhile (it + i != end && it[i].type() != Tag)\n\t\t\ti++;\n\t\tif (i > 1)\n\t\t{\n\t\t\t*_state.out = it[0];\n\t\t\t_state.i += static_cast<size_t>(i);\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nstruct DeduplicateNextTagSize3 : SimplePeepholeOptimizerMethod<DeduplicateNextTagSize3>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _precedingItem,\n\t\tAssemblyItem const& _itemA,\n\t\tAssemblyItem const& _itemB,\n\t\tAssemblyItem const& _breakingItem,\n\t\tAssemblyItem const& _tag,\n\t\tAssemblyItem const& _itemC,\n\t\tAssemblyItem const& _itemD,\n\t\tAssemblyItem const& _breakingItem2,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t_precedingItem.type() != Tag &&\n\t\t\t_itemA == _itemC &&\n\t\t\t_itemB == _itemD &&\n\t\t\t_breakingItem == _breakingItem2 &&\n\t\t\t_tag.type() == Tag &&\n\t\t\tSemanticInformation::terminatesControlFlow(_breakingItem)\n\t\t)\n\t\t{\n\t\t\t*_out = _precedingItem;\n\t\t\t*_out = _tag;\n\t\t\t*_out = _itemC;\n\t\t\t*_out = _itemD;\n\t\t\t*_out = _breakingItem2;\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n};\n\nstruct DeduplicateNextTagSize2 : SimplePeepholeOptimizerMethod<DeduplicateNextTagSize2>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _precedingItem,\n\t\tAssemblyItem const& _itemA,\n\t\tAssemblyItem const& _breakingItem,\n\t\tAssemblyItem const& _tag,\n\t\tAssemblyItem const& _itemC,\n\t\tAssemblyItem const& _breakingItem2,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t_precedingItem.type() != Tag &&\n\t\t\t_itemA == _itemC &&\n\t\t\t_breakingItem == _breakingItem2 &&\n\t\t\t_tag.type() == Tag &&\n\t\t\tSemanticInformation::terminatesControlFlow(_breakingItem)\n\t\t)\n\t\t{\n\t\t\t*_out = _precedingItem;\n\t\t\t*_out = _tag;\n\t\t\t*_out = _itemC;\n\t\t\t*_out = _breakingItem2;\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n};\n\nstruct DeduplicateNextTagSize1 : SimplePeepholeOptimizerMethod<DeduplicateNextTagSize1>\n{\n\tstatic bool applySimple(\n\t\tAssemblyItem const& _precedingItem,\n\t\tAssemblyItem const& _breakingItem,\n\t\tAssemblyItem const& _tag,\n\t\tAssemblyItem const& _breakingItem2,\n\t\tstd::back_insert_iterator<AssemblyItems> _out\n\t)\n\t{\n\t\tif (\n\t\t\t_precedingItem.type() != Tag &&\n\t\t\t_breakingItem == _breakingItem2 &&\n\t\t\t_tag.type() == Tag &&\n\t\t\tSemanticInformation::terminatesControlFlow(_breakingItem)\n\t\t)\n\t\t{\n\t\t\t*_out = _precedingItem;\n\t\t\t*_out = _tag;\n\t\t\t*_out = _breakingItem2;\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n};\n\ntemplate <typename... Method>\nvoid applyMethods(OptimiserState& _state)\n{\n\tbool continueWithNextMethod = true;\n\t((continueWithNextMethod && (continueWithNextMethod &= !Method::apply(_state))), ...);\n\tassertThrow(!continueWithNextMethod, OptimizerException, \"Peephole optimizer failed to apply identity.\");\n}\n\nsize_t numberOfPops(AssemblyItems const& _items)\n{\n\treturn static_cast<size_t>(std::count(_items.begin(), _items.end(), Instruction::POP));\n}\n\n}\n\nPeepholeOptimiser::PeepholeOptimiser(AssemblyItems& _items, langutil::EVMVersion const _evmVersion):\n\tm_items(_items),\n\tm_evmVersion(_evmVersion)\n{\n}\n\nbool PeepholeOptimiser::optimise()\n{\n\t// Avoid referencing immutables too early by using approx. counting in bytesRequired()\n\tauto const approx = evmasm::Precision::Approximate;\n\tOptimiserState state {m_items, 0, back_inserter(m_optimisedItems), m_evmVersion};\n\twhile (state.i < m_items.size())\n\t\tapplyMethods<\n\t\t\tPushPop,\n\t\t\tOpPop,\n\t\t\tOpStop,\n\t\t\tOpReturnRevert,\n\t\t\tDoublePush,\n\t\t\tDoubleSwap,\n\t\t\tCommutativeSwap,\n\t\t\tSwapComparison,\n\t\t\tDupSwap,\n\t\t\tIsZeroIsZeroJumpI,\n\t\t\tIsZeroIsZeroRJumpI, // EOF specific\n\t\t\tEqIsZeroJumpI,\n\t\t\tEqIsZeroRJumpI, // EOF specific\n\t\t\tDoubleJump,\n\t\t\tDoubleRJump, // EOF specific\n\t\t\tJumpToNext,\n\t\t\tRJumpToNext, // EOF specific\n\t\t\tUnreachableCode,\n\t\t\tDeduplicateNextTagSize3,\n\t\t\tDeduplicateNextTagSize2,\n\t\t\tDeduplicateNextTagSize1,\n\t\t\tTagConjunctions,\n\t\t\tTruthyAnd,\n\t\t\tIdentity\n\t\t>(state);\n\tif (m_optimisedItems.size() < m_items.size() || (\n\t\tm_optimisedItems.size() == m_items.size() && (\n\t\t\tevmasm::bytesRequired(m_optimisedItems, 3, m_evmVersion, approx) < evmasm::bytesRequired(m_items, 3, m_evmVersion, approx) ||\n\t\t\tnumberOfPops(m_optimisedItems) > numberOfPops(m_items)\n\t\t)\n\t))\n\t{\n\t\tm_items = std::move(m_optimisedItems);\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n"
  },
  {
    "path": "libevmasm/PeepholeOptimiser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file PeepholeOptimiser.h\n * Performs local optimising code changes to assembly.\n */\n#pragma once\n\n#include <vector>\n#include <cstddef>\n#include <iterator>\n\n#include <liblangutil/EVMVersion.h>\n\nnamespace solidity::evmasm\n{\nclass AssemblyItem;\nusing AssemblyItems = std::vector<AssemblyItem>;\n\nclass PeepholeOptimisationMethod\n{\npublic:\n\tvirtual ~PeepholeOptimisationMethod() = default;\n\tvirtual size_t windowSize() const;\n\tvirtual bool apply(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out);\n};\n\nclass PeepholeOptimiser\n{\npublic:\n\texplicit PeepholeOptimiser(AssemblyItems& _items, langutil::EVMVersion _evmVersion);\n\tvirtual ~PeepholeOptimiser() = default;\n\n\tbool optimise();\n\nprivate:\n\tAssemblyItems& m_items;\n\tAssemblyItems m_optimisedItems;\n\tlangutil::EVMVersion const m_evmVersion;\n};\n\n}\n"
  },
  {
    "path": "libevmasm/RuleList.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @date 2018\n * Templatized list of simplification rules.\n */\n\n#pragma once\n\n\n#include <libevmasm/Instruction.h>\n#include <libevmasm/SimplificationRule.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <boost/multiprecision/detail/min_max.hpp>\n\n#include <libyul/Dialect.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <vector>\n#include <functional>\n\nnamespace solidity::evmasm\n{\n\ntemplate <class S> S divWorkaround(S const& _a, S const& _b)\n{\n\treturn (S)(bigint(_a) / bigint(_b));\n}\n\ntemplate <class S> S modWorkaround(S const& _a, S const& _b)\n{\n\treturn (S)(bigint(_a) % bigint(_b));\n}\n\n// This works around a bug fixed with Boost 1.64.\n// https://www.boost.org/doc/libs/release/libs/multiprecision/doc/html/boost_multiprecision/map/hist.html#boost_multiprecision.map.hist.multiprecision_2_3_1_boost_1_64\ntemplate <class S> S shlWorkaround(S const& _x, unsigned _amount)\n{\n\treturn u256((bigint(_x) << _amount) & u256(-1));\n}\n\n/// @returns k if _x == 2**k, nullopt otherwise\ninline std::optional<size_t> binaryLogarithm(u256 const& _x)\n{\n\tif (_x == 0)\n\t\treturn std::nullopt;\n\tsize_t msb = boost::multiprecision::msb(_x);\n\treturn (u256(1) << msb) == _x ? std::make_optional(msb) : std::nullopt;\n}\n\n// simplificationRuleList below was split up into parts to prevent\n// stack overflows in the JavaScript optimizer for emscripten builds\n// that affected certain browser versions.\ntemplate <class Pattern>\nstd::vector<SimplificationRule<Pattern>> simplificationRuleListPart1(\n\tPattern A,\n\tPattern B,\n\tPattern C,\n\tPattern,\n\tPattern\n)\n{\n\tusing Word = typename Pattern::Word;\n\tusing Builtins = typename Pattern::Builtins;\n\treturn std::vector<SimplificationRule<Pattern>>{\n\t\t// arithmetic on constants\n\t\t{Builtins::ADD(A, B), [=]{ return A.d() + B.d(); }},\n\t\t{Builtins::MUL(A, B), [=]{ return A.d() * B.d(); }},\n\t\t{Builtins::SUB(A, B), [=]{ return A.d() - B.d(); }},\n\t\t{Builtins::DIV(A, B), [=]{ return B.d() == 0 ? 0 : divWorkaround(A.d(), B.d()); }},\n\t\t{Builtins::SDIV(A, B), [=]{ return B.d() == 0 ? 0 : s2u(divWorkaround(u2s(A.d()), u2s(B.d()))); }},\n\t\t{Builtins::MOD(A, B), [=]{ return B.d() == 0 ? 0 : modWorkaround(A.d(), B.d()); }},\n\t\t{Builtins::SMOD(A, B), [=]{ return B.d() == 0 ? 0 : s2u(modWorkaround(u2s(A.d()), u2s(B.d()))); }},\n\t\t{Builtins::EXP(A, B), [=]{ return Word(boost::multiprecision::powm(bigint(A.d()), bigint(B.d()), bigint(1) << Pattern::WordSize)); }},\n\t\t{Builtins::NOT(A), [=]{ return ~A.d(); }},\n\t\t{Builtins::LT(A, B), [=]() -> Word { return A.d() < B.d() ? 1 : 0; }},\n\t\t{Builtins::GT(A, B), [=]() -> Word { return A.d() > B.d() ? 1 : 0; }},\n\t\t{Builtins::SLT(A, B), [=]() -> Word { return u2s(A.d()) < u2s(B.d()) ? 1 : 0; }},\n\t\t{Builtins::SGT(A, B), [=]() -> Word { return u2s(A.d()) > u2s(B.d()) ? 1 : 0; }},\n\t\t{Builtins::EQ(A, B), [=]() -> Word { return A.d() == B.d() ? 1 : 0; }},\n\t\t{Builtins::ISZERO(A), [=]() -> Word { return A.d() == 0 ? 1 : 0; }},\n\t\t{Builtins::AND(A, B), [=]{ return A.d() & B.d(); }},\n\t\t{Builtins::OR(A, B), [=]{ return A.d() | B.d(); }},\n\t\t{Builtins::XOR(A, B), [=]{ return A.d() ^ B.d(); }},\n\t\t{Builtins::BYTE(A, B), [=]{\n\t\t\treturn\n\t\t\t\tA.d() >= Pattern::WordSize / 8 ?\n\t\t\t\t0 :\n\t\t\t\t(B.d() >> unsigned(8 * (Pattern::WordSize / 8 - 1 - A.d()))) & 0xff;\n\t\t}},\n\t\t{Builtins::ADDMOD(A, B, C), [=]{ return C.d() == 0 ? 0 : Word((bigint(A.d()) + bigint(B.d())) % C.d()); }},\n\t\t{Builtins::MULMOD(A, B, C), [=]{ return C.d() == 0 ? 0 : Word((bigint(A.d()) * bigint(B.d())) % C.d()); }},\n\t\t{Builtins::SIGNEXTEND(A, B), [=]() -> Word {\n\t\t\tif (A.d() >= Pattern::WordSize / 8 - 1)\n\t\t\t\treturn B.d();\n\t\t\tunsigned testBit = unsigned(A.d()) * 8 + 7;\n\t\t\tWord mask = (Word(1) << testBit) - 1;\n\t\t\treturn boost::multiprecision::bit_test(B.d(), testBit) ? B.d() | ~mask : B.d() & mask;\n\t\t}},\n\t\t{Builtins::SHL(A, B), [=]{\n\t\t\tif (A.d() >= Pattern::WordSize)\n\t\t\t\treturn Word(0);\n\t\t\treturn shlWorkaround(B.d(), unsigned(A.d()));\n\t\t}},\n\t\t{Builtins::SHR(A, B), [=]{\n\t\t\tif (A.d() >= Pattern::WordSize)\n\t\t\t\treturn Word(0);\n\t\t\treturn B.d() >> unsigned(A.d());\n\t\t}}\n\t};\n}\n\n\ntemplate <class Pattern>\nstd::vector<SimplificationRule<Pattern>> simplificationRuleListPart2(\n\tPattern,\n\tPattern,\n\tPattern,\n\tPattern X,\n\tPattern Y\n)\n{\n\tusing Word = typename Pattern::Word;\n\tusing Builtins = typename Pattern::Builtins;\n\treturn std::vector<SimplificationRule<Pattern>> {\n\t\t// invariants involving known constants\n\t\t{Builtins::ADD(X, 0), [=]{ return X; }},\n\t\t{Builtins::ADD(0, X), [=]{ return X; }},\n\t\t{Builtins::SUB(X, 0), [=]{ return X; }},\n\t\t{Builtins::SUB(~Word(0), X), [=]() -> Pattern { return Builtins::NOT(X); }},\n\t\t{Builtins::MUL(X, 0), [=]{ return Word(0); }},\n\t\t{Builtins::MUL(0, X), [=]{ return Word(0); }},\n\t\t{Builtins::MUL(X, 1), [=]{ return X; }},\n\t\t{Builtins::MUL(1, X), [=]{ return X; }},\n\t\t{Builtins::MUL(X, Word(-1)), [=]() -> Pattern { return Builtins::SUB(0, X); }},\n\t\t{Builtins::MUL(Word(-1), X), [=]() -> Pattern { return Builtins::SUB(0, X); }},\n\t\t{Builtins::DIV(X, 0), [=]{ return Word(0); }},\n\t\t{Builtins::DIV(0, X), [=]{ return Word(0); }},\n\t\t{Builtins::DIV(X, 1), [=]{ return X; }},\n\t\t{Builtins::SDIV(X, 0), [=]{ return Word(0); }},\n\t\t{Builtins::SDIV(0, X), [=]{ return Word(0); }},\n\t\t{Builtins::SDIV(X, 1), [=]{ return X; }},\n\t\t{Builtins::AND(X, ~Word(0)), [=]{ return X; }},\n\t\t{Builtins::AND(~Word(0), X), [=]{ return X; }},\n\t\t{Builtins::AND(X, 0), [=]{ return Word(0); }},\n\t\t{Builtins::AND(0, X), [=]{ return Word(0); }},\n\t\t{Builtins::OR(X, 0), [=]{ return X; }},\n\t\t{Builtins::OR(0, X), [=]{ return X; }},\n\t\t{Builtins::OR(X, ~Word(0)), [=]{ return ~Word(0); }},\n\t\t{Builtins::OR(~Word(0), X), [=]{ return ~Word(0); }},\n\t\t{Builtins::XOR(X, 0), [=]{ return X; }},\n\t\t{Builtins::XOR(0, X), [=]{ return X; }},\n\t\t{Builtins::MOD(X, 0), [=]{ return Word(0); }},\n\t\t{Builtins::MOD(0, X), [=]{ return Word(0); }},\n\t\t{Builtins::EQ(X, 0), [=]() -> Pattern { return Builtins::ISZERO(X); },},\n\t\t{Builtins::EQ(0, X), [=]() -> Pattern { return Builtins::ISZERO(X); },},\n\t\t{Builtins::SHL(0, X), [=]{ return X; }},\n\t\t{Builtins::SHR(0, X), [=]{ return X; }},\n\t\t{Builtins::SHL(X, 0), [=]{ return Word(0); }},\n\t\t{Builtins::SHR(X, 0), [=]{ return Word(0); }},\n\t\t{Builtins::GT(X, 0), [=]() -> Pattern { return Builtins::ISZERO(Builtins::ISZERO(X)); }},\n\t\t{Builtins::LT(0, X), [=]() -> Pattern { return Builtins::ISZERO(Builtins::ISZERO(X)); }},\n\t\t{Builtins::GT(X, ~Word(0)), [=]{ return Word(0); }},\n\t\t{Builtins::LT(~Word(0), X), [=]{ return Word(0); }},\n\t\t{Builtins::GT(0, X), [=]{ return Word(0); }},\n\t\t{Builtins::LT(X, 0), [=]{ return Word(0); }},\n\t\t{Builtins::AND(Builtins::BYTE(X, Y), Word(0xff)), [=]() -> Pattern { return Builtins::BYTE(X, Y); }},\n\t\t{Builtins::BYTE(Word(Pattern::WordSize / 8 - 1), X), [=]() -> Pattern { return Builtins::AND(X, Word(0xff)); }},\n\t};\n}\n\ntemplate <class Pattern>\nstd::vector<SimplificationRule<Pattern>> simplificationRuleListPart3(\n\tPattern,\n\tPattern,\n\tPattern,\n\tPattern X,\n\tPattern\n)\n{\n\tusing Word = typename Pattern::Word;\n\tusing Builtins = typename Pattern::Builtins;\n\treturn std::vector<SimplificationRule<Pattern>> {\n\t\t// operations involving an expression and itself\n\t\t{Builtins::AND(X, X), [=]{ return X; }},\n\t\t{Builtins::OR(X, X), [=]{ return X; }},\n\t\t{Builtins::XOR(X, X), [=]{ return Word(0); }},\n\t\t{Builtins::SUB(X, X), [=]{ return Word(0); }},\n\t\t{Builtins::EQ(X, X), [=]{ return Word(1); }},\n\t\t{Builtins::LT(X, X), [=]{ return Word(0); }},\n\t\t{Builtins::SLT(X, X), [=]{ return Word(0); }},\n\t\t{Builtins::GT(X, X), [=]{ return Word(0); }},\n\t\t{Builtins::SGT(X, X), [=]{ return Word(0); }},\n\t\t{Builtins::MOD(X, X), [=]{ return Word(0); }}\n\t};\n}\n\ntemplate <class Pattern>\nstd::vector<SimplificationRule<Pattern>> simplificationRuleListPart4(\n\tPattern,\n\tPattern,\n\tPattern,\n\tPattern X,\n\tPattern Y\n)\n{\n\tusing Word = typename Pattern::Word;\n\tusing Builtins = typename Pattern::Builtins;\n\treturn std::vector<SimplificationRule<Pattern>> {\n\t\t// logical instruction combinations\n\t\t{Builtins::NOT(Builtins::NOT(X)), [=]{ return X; }},\n\t\t{Builtins::XOR(X, Builtins::XOR(X, Y)), [=]{ return Y; }},\n\t\t{Builtins::XOR(X, Builtins::XOR(Y, X)), [=]{ return Y; }},\n\t\t{Builtins::XOR(Builtins::XOR(X, Y), X), [=]{ return Y; }},\n\t\t{Builtins::XOR(Builtins::XOR(Y, X), X), [=]{ return Y; }},\n\t\t{Builtins::OR(X, Builtins::AND(X, Y)), [=]{ return X; }},\n\t\t{Builtins::OR(X, Builtins::AND(Y, X)), [=]{ return X; }},\n\t\t{Builtins::OR(Builtins::AND(X, Y), X), [=]{ return X; }},\n\t\t{Builtins::OR(Builtins::AND(Y, X), X), [=]{ return X; }},\n\t\t{Builtins::AND(X, Builtins::OR(X, Y)), [=]{ return X; }},\n\t\t{Builtins::AND(X, Builtins::OR(Y, X)), [=]{ return X; }},\n\t\t{Builtins::AND(Builtins::OR(X, Y), X), [=]{ return X; }},\n\t\t{Builtins::AND(Builtins::OR(Y, X), X), [=]{ return X; }},\n\t\t{Builtins::AND(X, Builtins::NOT(X)), [=]{ return Word(0); }},\n\t\t{Builtins::AND(Builtins::NOT(X), X), [=]{ return Word(0); }},\n\t\t{Builtins::OR(X, Builtins::NOT(X)), [=]{ return ~Word(0); }},\n\t\t{Builtins::OR(Builtins::NOT(X), X), [=]{ return ~Word(0); }},\n\t};\n}\n\ntemplate <class Pattern>\nstd::vector<SimplificationRule<Pattern>> simplificationRuleListPart4_5(\n\tPattern A,\n\tPattern B,\n\tPattern,\n\tPattern X,\n\tPattern Y\n)\n{\n\tusing Builtins = typename Pattern::Builtins;\n\treturn std::vector<SimplificationRule<Pattern>>{\n\t\t// idempotent operations\n\t\t{Builtins::AND(Builtins::AND(X, Y), Y), [=]{ return Builtins::AND(X, Y); }},\n\t\t{Builtins::AND(Y, Builtins::AND(X, Y)), [=]{ return Builtins::AND(X, Y); }},\n\t\t{Builtins::AND(Builtins::AND(Y, X), Y), [=]{ return Builtins::AND(Y, X); }},\n\t\t{Builtins::AND(Y, Builtins::AND(Y, X)), [=]{ return Builtins::AND(Y, X); }},\n\t\t{Builtins::OR(Builtins::OR(X, Y), Y), [=]{ return Builtins::OR(X, Y); }},\n\t\t{Builtins::OR(Y, Builtins::OR(X, Y)), [=]{ return Builtins::OR(X, Y); }},\n\t\t{Builtins::OR(Builtins::OR(Y, X), Y), [=]{ return Builtins::OR(Y, X); }},\n\t\t{Builtins::OR(Y, Builtins::OR(Y, X)), [=]{ return Builtins::OR(Y, X); }},\n\t\t{Builtins::SIGNEXTEND(X, Builtins::SIGNEXTEND(X, Y)), [=]() { return Builtins::SIGNEXTEND(X, Y); }},\n\t\t{Builtins::SIGNEXTEND(A, Builtins::SIGNEXTEND(B, X)), [=]() {\n\t\t\treturn Builtins::SIGNEXTEND(A.d() < B.d() ? A.d() : B.d(), X);\n\t\t}},\n\t};\n}\n\ntemplate <class Pattern>\nstd::vector<SimplificationRule<Pattern>> simplificationRuleListPart5(\n\tbool _forYulOptimizer,\n\tPattern A,\n\tPattern B,\n\tPattern,\n\tPattern X,\n\tPattern Y\n)\n{\n\tusing Word = typename Pattern::Word;\n\tusing Builtins = typename Pattern::Builtins;\n\n\tstd::vector<SimplificationRule<Pattern>> rules;\n\n\t// The libevmasm optimizer does not support rules resulting in opcodes with more than two arguments.\n\tif (_forYulOptimizer)\n\t{\n\t\t// Replace MOD(MUL(X, Y), A) with MULMOD(X, Y, A) iff A=2**N\n\t\trules.push_back({\n\t\t\tBuiltins::MOD(Builtins::MUL(X, Y), A),\n\t\t\t[=]() -> Pattern { return Builtins::MULMOD(X, Y, A); },\n\t\t\t[=] {\n\t\t\t\treturn A.d() > 0 && ((A.d() & (A.d() - 1)) == 0);\n\t\t\t}\n\t\t});\n\n\t\t// Replace MOD(ADD(X, Y), A) with ADDMOD(X, Y, A) iff A=2**N\n\t\trules.push_back({\n\t\t\tBuiltins::MOD(Builtins::ADD(X, Y), A),\n\t\t\t[=]() -> Pattern { return Builtins::ADDMOD(X, Y, A); },\n\t\t\t[=] {\n\t\t\t\treturn A.d() > 0 && ((A.d() & (A.d() - 1)) == 0);\n\t\t\t}\n\t\t});\n\t}\n\n\t// Replace MOD X, <power-of-two> with AND X, <power-of-two> - 1\n\tfor (size_t i = 0; i < Pattern::WordSize; ++i)\n\t{\n\t\tWord value = Word(1) << i;\n\t\trules.push_back({\n\t\t\tBuiltins::MOD(X, value),\n\t\t\t[=]() -> Pattern { return Builtins::AND(X, value - 1); }\n\t\t});\n\t}\n\n\t// Replace SHL >=256, X with 0\n\trules.push_back({\n\t\tBuiltins::SHL(A, X),\n\t\t[=]() -> Pattern { return Word(0); },\n\t\t[=]() { return A.d() >= Pattern::WordSize; }\n\t});\n\n\t// Replace SHR >=256, X with 0\n\trules.push_back({\n\t\tBuiltins::SHR(A, X),\n\t\t[=]() -> Pattern { return Word(0); },\n\t\t[=]() { return A.d() >= Pattern::WordSize; }\n\t});\n\n\t// Replace BYTE(A, X), A >= 32 with 0\n\trules.push_back({\n\t\tBuiltins::BYTE(A, X),\n\t\t[=]() -> Pattern { return Word(0); },\n\t\t[=]() { return A.d() >= Pattern::WordSize / 8; }\n\t});\n\n\t// Replace SIGNEXTEND(A, X), A >= 31 with ID\n\trules.push_back({\n\t\tBuiltins::SIGNEXTEND(A, X),\n\t\t[=]() -> Pattern { return X; },\n\t\t[=]() { return A.d() >= Pattern::WordSize / 8 - 1; }\n\t});\n\trules.push_back({\n\t\tBuiltins::AND(A, Builtins::SIGNEXTEND(B, X)),\n\t\t[=]() -> Pattern { return Builtins::AND(A, X); },\n\t\t[=]() {\n\t\t\treturn\n\t\t\t\tB.d() < Pattern::WordSize / 8 - 1 &&\n\t\t\t\t(A.d() & ((u256(1) << static_cast<size_t>((B.d() + 1) * 8)) - 1)) == A.d();\n\t\t}\n\t});\n\trules.push_back({\n\t\tBuiltins::AND(Builtins::SIGNEXTEND(B, X), A),\n\t\t[=]() -> Pattern { return Builtins::AND(A, X); },\n\t\t[=]() {\n\t\t\treturn\n\t\t\t\tB.d() < Pattern::WordSize / 8 - 1 &&\n\t\t\t\t(A.d() & ((u256(1) << static_cast<size_t>((B.d() + 1) * 8)) - 1)) == A.d();\n\t\t}\n\t});\n\n\tfor (auto instr: {\n\t\tInstruction::ADDRESS,\n\t\tInstruction::CALLER,\n\t\tInstruction::ORIGIN,\n\t\tInstruction::COINBASE\n\t})\n\t{\n\t\tassertThrow(Pattern::WordSize > 160, OptimizerException, \"\");\n\t\tWord const mask = (Word(1) << 160) - 1;\n\t\trules.push_back({\n\t\t\tBuiltins::AND(Pattern{instr}, mask),\n\t\t\t[=]() -> Pattern { return {instr}; }\n\t\t});\n\t\trules.push_back({\n\t\t\tBuiltins::AND(mask, Pattern{instr}),\n\t\t\t[=]() -> Pattern { return {instr}; }\n\t\t});\n\t}\n\n\treturn rules;\n}\n\ntemplate <class Pattern>\nstd::vector<SimplificationRule<Pattern>> simplificationRuleListPart6(\n\tPattern,\n\tPattern,\n\tPattern,\n\tPattern X,\n\tPattern Y\n)\n{\n\tusing Builtins = typename Pattern::Builtins;\n\n\tstd::vector<SimplificationRule<Pattern>> rules;\n\t// Double negation of opcodes with boolean result\n\tfor (auto instr: {\n\t\tInstruction::EQ,\n\t\tInstruction::LT,\n\t\tInstruction::SLT,\n\t\tInstruction::GT,\n\t\tInstruction::SGT\n\t})\n\t{\n\t\ttypename Builtins::PatternGeneratorInstance op{instr};\n\t\trules.push_back({\n\t\t\tBuiltins::ISZERO(Builtins::ISZERO(op(X, Y))),\n\t\t\t[=]() -> Pattern { return op(X, Y); }\n\t\t});\n\t}\n\n\trules.push_back({\n\t\tBuiltins::ISZERO(Builtins::ISZERO(Builtins::ISZERO(X))),\n\t\t[=]() -> Pattern { return Builtins::ISZERO(X); }\n\t});\n\n\trules.push_back({\n\t\tBuiltins::ISZERO(Builtins::XOR(X, Y)),\n\t\t[=]() -> Pattern { return Builtins::EQ(X, Y); }\n\t});\n\n\trules.push_back({\n\t\tBuiltins::ISZERO(Builtins::SUB(X, Y)),\n\t\t[=]() -> Pattern { return Builtins::EQ(X, Y); }\n\t});\n\n\treturn rules;\n}\n\ntemplate <class Pattern>\nstd::vector<SimplificationRule<Pattern>> simplificationRuleListPart7(\n\tPattern A,\n\tPattern B,\n\tPattern,\n\tPattern X,\n\tPattern Y,\n\tPattern Z\n)\n{\n\tusing Word = typename Pattern::Word;\n\tusing Builtins = typename Pattern::Builtins;\n\n\tstd::vector<SimplificationRule<Pattern>> rules;\n\t// Associative operations\n\tfor (auto&& instrAndFunc: std::vector<std::pair<Instruction, std::function<Word(Word, Word)>>>{\n\t\t{Instruction::ADD, std::plus<Word>()},\n\t\t{Instruction::MUL, std::multiplies<Word>()},\n\t\t{Instruction::AND, std::bit_and<Word>()},\n\t\t{Instruction::OR, std::bit_or<Word>()},\n\t\t{Instruction::XOR, std::bit_xor<Word>()}\n\t})\n\t{\n\t\ttypename Builtins::PatternGeneratorInstance op{instrAndFunc.first};\n\t\tstd::function<Word(Word, Word)> fun = instrAndFunc.second;\n\t\t// Moving constants to the outside, order matters here - we first add rules\n\t\t// for constants and then for non-constants.\n\t\t// xa can be (X, A) or (A, X)\n\t\tfor (auto const& opXA: {op(X, A), op(A, X)})\n\t\t{\n\t\t\trules += std::vector<SimplificationRule<Pattern>>{{\n\t\t\t\t// (X+A)+B -> X+(A+B)\n\t\t\t\top(opXA, B),\n\t\t\t\t[=]() -> Pattern { return op(X, fun(A.d(), B.d())); }\n\t\t\t}, {\n\t\t\t\t// (X+A)+Y -> (X+Y)+A\n\t\t\t\top(opXA, Y),\n\t\t\t\t[=]() -> Pattern { return op(op(X, Y), A); }\n\t\t\t}, {\n\t\t\t\t// B+(X+A) -> X+(A+B)\n\t\t\t\top(B, opXA),\n\t\t\t\t[=]() -> Pattern { return op(X, fun(A.d(), B.d())); }\n\t\t\t}, {\n\t\t\t\t// Y+(X+A) -> (Y+X)+A\n\t\t\t\top(Y, opXA),\n\t\t\t\t[=]() -> Pattern { return op(op(Y, X), A); }\n\t\t\t}};\n\t\t}\n\t}\n\n\t// Combine two SHL by constant\n\trules.push_back({\n\t\t// SHL(B, SHL(A, X)) -> SHL(min(A+B, 256), X)\n\t\tBuiltins::SHL(B, Builtins::SHL(A, X)),\n\t\t[=]() -> Pattern {\n\t\t\tbigint sum = bigint(A.d()) + B.d();\n\t\t\tif (sum >= Pattern::WordSize)\n\t\t\t\treturn Builtins::AND(X, Word(0));\n\t\t\telse\n\t\t\t\treturn Builtins::SHL(Word(sum), X);\n\t\t}\n\t});\n\n\t// Combine two SHR by constant\n\trules.push_back({\n\t\t// SHR(B, SHR(A, X)) -> SHR(min(A+B, 256), X)\n\t\tBuiltins::SHR(B, Builtins::SHR(A, X)),\n\t\t[=]() -> Pattern {\n\t\t\tbigint sum = bigint(A.d()) + B.d();\n\t\t\tif (sum >= Pattern::WordSize)\n\t\t\t\treturn Builtins::AND(X, Word(0));\n\t\t\telse\n\t\t\t\treturn Builtins::SHR(Word(sum), X);\n\t\t}\n\t});\n\n\t// Combine SHL-SHR by constant\n\trules.push_back({\n\t\t// SHR(B, SHL(A, X)) -> AND(SH[L/R]([B - A / A - B], X), Mask)\n\t\tBuiltins::SHR(B, Builtins::SHL(A, X)),\n\t\t[=]() -> Pattern {\n\t\t\tWord mask = shlWorkaround(~Word(0), unsigned(A.d())) >> unsigned(B.d());\n\n\t\t\tif (A.d() > B.d())\n\t\t\t\treturn Builtins::AND(Builtins::SHL(A.d() - B.d(), X), mask);\n\t\t\telse if (B.d() > A.d())\n\t\t\t\treturn Builtins::AND(Builtins::SHR(B.d() - A.d(), X), mask);\n\t\t\telse\n\t\t\t\treturn Builtins::AND(X, mask);\n\t\t},\n\t\t[=] { return A.d() < Pattern::WordSize && B.d() < Pattern::WordSize; }\n\t});\n\n\t// Combine SHR-SHL by constant\n\trules.push_back({\n\t\t// SHL(B, SHR(A, X)) -> AND(SH[L/R]([B - A / A - B], X), Mask)\n\t\tBuiltins::SHL(B, Builtins::SHR(A, X)),\n\t\t[=]() -> Pattern {\n\t\t\tWord mask = shlWorkaround((~Word(0)) >> unsigned(A.d()), unsigned(B.d()));\n\n\t\t\tif (A.d() > B.d())\n\t\t\t\treturn Builtins::AND(Builtins::SHR(A.d() - B.d(), X), mask);\n\t\t\telse if (B.d() > A.d())\n\t\t\t\treturn Builtins::AND(Builtins::SHL(B.d() - A.d(), X), mask);\n\t\t\telse\n\t\t\t\treturn Builtins::AND(X, mask);\n\t\t},\n\t\t[=] { return A.d() < Pattern::WordSize && B.d() < Pattern::WordSize; }\n\t});\n\n\t// Move AND with constant across SHL and SHR by constant\n\tfor (auto instr: {Instruction::SHL, Instruction::SHR})\n\t{\n\t\ttypename Builtins::PatternGeneratorInstance shiftOp{instr};\n\t\tauto replacement = [=]() -> Pattern {\n\t\t\tWord mask =\n\t\t\t\tinstr == Instruction::SHL ?\n\t\t\t\tshlWorkaround(A.d(), unsigned(B.d())) :\n\t\t\t\tA.d() >> unsigned(B.d());\n\t\t\treturn Builtins::AND(shiftOp(B.d(), X), std::move(mask));\n\t\t};\n\t\trules.push_back({\n\t\t\t// SH[L/R](B, AND(X, A)) -> AND(SH[L/R](B, X), [ A << B / A >> B ])\n\t\t\tshiftOp(B, Builtins::AND(X, A)),\n\t\t\treplacement,\n\t\t\t[=] { return B.d() < Pattern::WordSize; }\n\t\t});\n\t\trules.push_back({\n\t\t\t// SH[L/R](B, AND(A, X)) -> AND(SH[L/R](B, X), [ A << B / A >> B ])\n\t\t\tshiftOp(B, Builtins::AND(A, X)),\n\t\t\treplacement,\n\t\t\t[=] { return B.d() < Pattern::WordSize; }\n\t\t});\n\t}\n\n\t// Combine alternating AND/OR/AND with constant,\n\t// AND(OR(AND(X, A), Y), B) -> OR(AND(X, A & B), AND(Y, B))\n\t// Many versions due to commutativity.\n\tfor (auto const& inner: {Builtins::AND(X, A), Builtins::AND(A, X)})\n\t\tfor (auto const& second: {Builtins::OR(inner, Y), Builtins::OR(Y, inner)})\n\t\t{\n\t\t\t// We might swap X and Y but this is not an issue anymore.\n\t\t\trules.push_back({\n\t\t\t\tBuiltins::AND(second, B),\n\t\t\t\t[=]() -> Pattern { return Builtins::OR(Builtins::AND(X, A.d() & B.d()), Builtins::AND(Y, B)); }\n\t\t\t});\n\t\t\trules.push_back({\n\t\t\t\tBuiltins::AND(B, second),\n\t\t\t\t[=]() -> Pattern { return Builtins::OR(Builtins::AND(X, A.d() & B.d()), Builtins::AND(Y, B)); }\n\t\t\t});\n\t\t}\n\n\trules.push_back({\n\t\t// MUL(X, SHL(Y, 1)) -> SHL(Y, X)\n\t\tBuiltins::MUL(X, Builtins::SHL(Y, Word(1))),\n\t\t[=]() -> Pattern {\n\t\t\treturn Builtins::SHL(Y, X);\n\t\t}\n\t});\n\trules.push_back({\n\t\t// MUL(SHL(X, 1), Y) -> SHL(X, Y)\n\t\tBuiltins::MUL(Builtins::SHL(X, Word(1)), Y),\n\t\t[=]() -> Pattern {\n\t\t\treturn Builtins::SHL(X, Y);\n\t\t}\n\t});\n\n\trules.push_back({\n\t\t// DIV(X, SHL(Y, 1)) -> SHR(Y, X)\n\t\tBuiltins::DIV(X, Builtins::SHL(Y, Word(1))),\n\t\t[=]() -> Pattern {\n\t\t\treturn Builtins::SHR(Y, X);\n\t\t}\n\t});\n\n\tstd::function<bool()> feasibilityFunction = [=]() {\n\t\tif (B.d() > Pattern::WordSize)\n\t\t\treturn false;\n\t\tunsigned bAsUint = static_cast<unsigned>(B.d());\n\t\treturn (A.d() & ((~Word(0)) >> bAsUint)) == ((~Word(0)) >> bAsUint);\n\t};\n\n\trules.push_back({\n\t\t// AND(A, SHR(B, X)) -> A & ((2^256-1) >> B) == ((2^256-1) >> B)\n\t\tBuiltins::AND(A, Builtins::SHR(B, X)),\n\t\t[=]() -> Pattern { return Builtins::SHR(B, X); },\n\t\tfeasibilityFunction\n\t});\n\n\trules.push_back({\n\t\t// AND(SHR(B, X), A) -> ((2^256-1) >> B) & A == ((2^256-1) >> B)\n\t\tBuiltins::AND(Builtins::SHR(B, X), A),\n\t\t[=]() -> Pattern { return Builtins::SHR(B, X); },\n\t\tfeasibilityFunction\n\t});\n\n\trules.push_back({\n\t\t// AND(SHL(Z, X), SHL(Z, Y)) -> SHL(Z, AND(X, Y))\n\t\tBuiltins::AND(Builtins::SHL(Z, X), Builtins::SHL(Z, Y)),\n\t\t[=]() -> Pattern { return Builtins::SHL(Z, Builtins::AND(X, Y)); }\n\t});\n\n\trules.push_back({\n\t\tBuiltins::BYTE(A, Builtins::SHL(B, X)),\n\t\t[=]() -> Pattern { return Builtins::BYTE(A.d() + B.d() / 8, X); },\n\t\t[=] { return B.d() % 8 == 0 && A.d() <= 32 && B.d() <= 256; }\n\t});\n\n\trules.push_back({\n\t\tBuiltins::BYTE(A, Builtins::SHR(B, X)),\n\t\t[=]() -> Pattern { return Word(0); },\n\t\t[=] { return A.d() < B.d() / 8; }\n\t});\n\n\trules.push_back({\n\t\tBuiltins::BYTE(A, Builtins::SHR(B, X)),\n\t\t[=]() -> Pattern { return Builtins::BYTE(A.d() - B.d() / 8, X); },\n\t\t[=] {\n\t\t\treturn B.d() % 8 == 0 && A.d() < Pattern::WordSize / 8 && B.d() <= Pattern::WordSize && A.d() >= B.d() / 8;\n\t\t}\n\t});\n\n\trules.push_back({\n\t\tBuiltins::SHL(A, Builtins::SIGNEXTEND(B, X)),\n\t\t[=]() -> Pattern { return Builtins::SIGNEXTEND((A.d() >> 3) + B.d(), Builtins::SHL(A, X)); },\n\t\t[=] { return (A.d() & 7) == 0 && A.d() <= Pattern::WordSize && B.d() <= Pattern::WordSize / 8; }\n\t});\n\n\trules.push_back({\n\t\tBuiltins::SIGNEXTEND(A, Builtins::SHR(B, X)),\n\t\t[=]() -> Pattern { return Builtins::SAR(B, X); },\n\t\t[=] {\n\t\t\treturn\n\t\t\t\tB.d() % 8 == 0 &&\n\t\t\t\tB.d() <= Pattern::WordSize &&\n\t\t\t\tA.d() <= Pattern::WordSize &&\n\t\t\t\t(Pattern::WordSize - B.d()) / 8 == A.d() + 1;\n\t\t}\n\t});\n\n\treturn rules;\n}\n\ntemplate <class Pattern>\nstd::vector<SimplificationRule<Pattern>> simplificationRuleListPart8(\n\tPattern A,\n\tPattern,\n\tPattern,\n\tPattern X,\n\tPattern Y\n)\n{\n\tusing Builtins = typename Pattern::Builtins;\n\tstd::vector<SimplificationRule<Pattern>> rules;\n\n\t// move constants across subtractions\n\trules += std::vector<SimplificationRule<Pattern>>{\n\t\t{\n\t\t\t// X - A -> X + (-A)\n\t\t\tBuiltins::SUB(X, A),\n\t\t\t[=]() -> Pattern { return Builtins::ADD(X, 0 - A.d()); }\n\t\t}, {\n\t\t\t// (X + A) - Y -> (X - Y) + A\n\t\t\tBuiltins::SUB(Builtins::ADD(X, A), Y),\n\t\t\t[=]() -> Pattern { return Builtins::ADD(Builtins::SUB(X, Y), A); }\n\t\t}, {\n\t\t\t// (A + X) - Y -> (X - Y) + A\n\t\t\tBuiltins::SUB(Builtins::ADD(A, X), Y),\n\t\t\t[=]() -> Pattern { return Builtins::ADD(Builtins::SUB(X, Y), A); }\n\t\t}, {\n\t\t\t// X - (Y + A) -> (X - Y) + (-A)\n\t\t\tBuiltins::SUB(X, Builtins::ADD(Y, A)),\n\t\t\t[=]() -> Pattern { return Builtins::ADD(Builtins::SUB(X, Y), 0 - A.d()); }\n\t\t}, {\n\t\t\t// X - (A + Y) -> (X - Y) + (-A)\n\t\t\tBuiltins::SUB(X, Builtins::ADD(A, Y)),\n\t\t\t[=]() -> Pattern { return Builtins::ADD(Builtins::SUB(X, Y), 0 - A.d()); }\n\t\t}, {\n\t\t\t// (X - A) - Y -> (X - Y) - A\n\t\t\tBuiltins::SUB(Builtins::SUB(X, A), Y),\n\t\t\t[=]() -> Pattern { return Builtins::SUB(Builtins::SUB(X, Y), A); }\n\t\t}, {\n\t\t\t// (A - X) - Y -> A - (X + Y)\n\t\t\tBuiltins::SUB(Builtins::SUB(A, X), Y),\n\t\t\t[=]() -> Pattern { return Builtins::SUB(A, Builtins::ADD(X, Y)); }\n\t\t}, {\n\t\t\t// X - (Y - A) -> (X - Y) + A\n\t\t\tBuiltins::SUB(X, Builtins::SUB(Y, A)),\n\t\t\t[=]() -> Pattern { return Builtins::ADD(Builtins::SUB(X, Y), A.d()); }\n\t\t}, {\n\t\t\t// X - (A - Y) -> (X + Y) + (-A)\n\t\t\tBuiltins::SUB(X, Builtins::SUB(A, Y)),\n\t\t\t[=]() -> Pattern { return Builtins::ADD(Builtins::ADD(X, Y), 0 - A.d()); }\n\t\t}\n\t};\n\treturn rules;\n}\n\ntemplate<class Pattern>\nstd::vector<SimplificationRule<Pattern>> evmRuleList(\n\tlangutil::EVMVersion _evmVersion,\n\tPattern A,\n\tPattern,\n\tPattern,\n\tPattern,\n\tPattern X,\n\tPattern,\n\tPattern\n)\n{\n\tusing Builtins = typename Pattern::Builtins;\n\tusing Word = typename Pattern::Word;\n\tstd::vector<SimplificationRule<Pattern>> rules;\n\n\tif (_evmVersion.hasSelfBalance())\n\t\trules.push_back({\n\t\t\tBuiltins::BALANCE(Instruction::ADDRESS),\n\t\t\t[]() -> Pattern { return Instruction::SELFBALANCE; }\n\t\t});\n\n\trules.emplace_back(\n\t\tBuiltins::EXP(0, X),\n\t\t[=]() -> Pattern { return Builtins::ISZERO(X); }\n\t);\n\trules.emplace_back(\n\t\tBuiltins::EXP(1, X),\n\t\t[=]() -> Pattern { return Word(1); }\n\t);\n\tif (_evmVersion.hasBitwiseShifting())\n\t{\n\t\trules.emplace_back(\n\t\t\tBuiltins::EXP(2, X),\n\t\t\t[=]() -> Pattern { return Builtins::SHL(X, 1); }\n\t\t);\n\t\trules.emplace_back(\n\t\t\tBuiltins::MUL(A, X),\n\t\t\t[=]() -> Pattern { return Builtins::SHL(u256(*binaryLogarithm(A.d())), X); },\n\t\t\t[=] { return binaryLogarithm(A.d()).has_value(); }\n\t\t);\n\t\trules.emplace_back(\n\t\t\tBuiltins::MUL(X, A),\n\t\t\t[=]() -> Pattern { return Builtins::SHL(u256(*binaryLogarithm(A.d())), X); },\n\t\t\t[=] { return binaryLogarithm(A.d()).has_value(); }\n\t\t);\n\t\trules.emplace_back(\n\t\t\tBuiltins::DIV(X, A),\n\t\t\t[=]() -> Pattern { return Builtins::SHR(u256(*binaryLogarithm(A.d())), X); },\n\t\t\t[=] { return binaryLogarithm(A.d()).has_value(); }\n\t\t);\n\t}\n\trules.emplace_back(\n\t\tBuiltins::EXP(Word(-1), X),\n\t\t[=]() -> Pattern\n\t\t{\n\t\t\treturn Builtins::SUB(\n\t\t\t\tBuiltins::ISZERO(Builtins::AND(X, Word(1))),\n\t\t\t\tBuiltins::AND(X, Word(1))\n\t\t\t);\n\t\t}\n\t);\n\n\treturn rules;\n}\n\n/// @returns a list of simplification rules given certain match placeholders.\n/// A, B and C should represent constants, W, X, Y, and Z arbitrary expressions.\n/// The simplifications should never change the order of evaluation of\n/// arbitrary operations.\ntemplate <class Pattern>\nstd::vector<SimplificationRule<Pattern>> simplificationRuleList(\n\tstd::optional<langutil::EVMVersion> _evmVersion,\n\tPattern A,\n\tPattern B,\n\tPattern C,\n\tPattern W,\n\tPattern X,\n\tPattern Y,\n\tPattern Z\n)\n{\n\tusing Word = typename Pattern::Word;\n\t// Some sanity checks\n\tassertThrow(Pattern::WordSize % 8 == 0, OptimizerException, \"\");\n\tassertThrow(Pattern::WordSize >= 8, OptimizerException, \"\");\n\tassertThrow(Pattern::WordSize <= 256, OptimizerException, \"\");\n\tassertThrow(Word(-1) == ~Word(0), OptimizerException, \"\");\n\tassertThrow(Word(-1) + 1 == Word(0), OptimizerException, \"\");\n\n\tstd::vector<SimplificationRule<Pattern>> rules;\n\trules += simplificationRuleListPart1(A, B, C, W, X);\n\trules += simplificationRuleListPart2(A, B, C, W, X);\n\trules += simplificationRuleListPart3(A, B, C, W, X);\n\trules += simplificationRuleListPart4(A, B, C, W, X);\n\trules += simplificationRuleListPart4_5(A, B, C, W, X);\n\trules += simplificationRuleListPart5(_evmVersion.has_value(), A, B, C, W, X);\n\trules += simplificationRuleListPart6(A, B, C, W, X);\n\trules += simplificationRuleListPart7(A, B, C, W, X, Y);\n\trules += simplificationRuleListPart8(A, B, C, W, X);\n\n\tif (_evmVersion.has_value())\n\t\trules += evmRuleList(*_evmVersion, A, B, C, W, X, Y, Z);\n\n\treturn rules;\n}\n\n}\n"
  },
  {
    "path": "libevmasm/SemanticInformation.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file SemanticInformation.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Helper to provide semantic information about assembly items.\n */\n\n#include <libevmasm/SemanticInformation.h>\n#include <libevmasm/AssemblyItem.h>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\n\nstd::vector<SemanticInformation::Operation> SemanticInformation::readWriteOperations(Instruction _instruction)\n{\n\tswitch (_instruction)\n\t{\n\tcase Instruction::SSTORE:\n\tcase Instruction::SLOAD:\n\t{\n\t\tassertThrow(memory(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tassertThrow(storage(_instruction) != Effect::None, OptimizerException, \"\");\n\t\tassertThrow(transientStorage(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tOperation op;\n\t\top.effect = storage(_instruction);\n\t\top.location = Location::Storage;\n\t\top.startParameter = 0;\n\t\t// We know that exactly one slot is affected.\n\t\top.lengthConstant = 1;\n\t\treturn {op};\n\t}\n\tcase Instruction::MSTORE:\n\tcase Instruction::MSTORE8:\n\tcase Instruction::MLOAD:\n\t{\n\t\tassertThrow(memory(_instruction) != Effect::None, OptimizerException, \"\");\n\t\tassertThrow(storage(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tassertThrow(transientStorage(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tOperation op;\n\t\top.effect = memory(_instruction);\n\t\top.location = Location::Memory;\n\t\top.startParameter = 0;\n\t\tif (_instruction == Instruction::MSTORE || _instruction == Instruction::MLOAD)\n\t\t\top.lengthConstant = 32;\n\t\telse if (_instruction == Instruction::MSTORE8)\n\t\t\top.lengthConstant = 1;\n\n\t\treturn {op};\n\t}\n\tcase Instruction::TSTORE:\n\tcase Instruction::TLOAD:\n\t{\n\t\tassertThrow(memory(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tassertThrow(storage(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tassertThrow(transientStorage(_instruction) != Effect::None, OptimizerException, \"\");\n\t\tOperation op;\n\t\top.effect = transientStorage(_instruction);\n\t\top.location = Location::TransientStorage;\n\t\top.startParameter = 0;\n\t\top.lengthConstant = 1;\n\t\treturn {op};\n\t}\n\tcase Instruction::REVERT:\n\tcase Instruction::RETURN:\n\tcase Instruction::KECCAK256:\n\tcase Instruction::LOG0:\n\tcase Instruction::LOG1:\n\tcase Instruction::LOG2:\n\tcase Instruction::LOG3:\n\tcase Instruction::LOG4:\n\t{\n\t\tassertThrow(storage(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tassertThrow(memory(_instruction) == Effect::Read, OptimizerException, \"\");\n\t\tassertThrow(transientStorage(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tOperation op;\n\t\top.effect = memory(_instruction);\n\t\top.location = Location::Memory;\n\t\top.startParameter = 0;\n\t\top.lengthParameter = 1;\n\t\treturn {op};\n\t}\n\tcase Instruction::EXTCODECOPY:\n\t{\n\t\tassertThrow(memory(_instruction) == Effect::Write, OptimizerException, \"\");\n\t\tassertThrow(storage(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tassertThrow(transientStorage(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tOperation op;\n\t\top.effect = memory(_instruction);\n\t\top.location = Location::Memory;\n\t\top.startParameter = 1;\n\t\top.lengthParameter = 3;\n\t\treturn {op};\n\t}\n\tcase Instruction::CODECOPY:\n\tcase Instruction::CALLDATACOPY:\n\tcase Instruction::RETURNDATACOPY:\n\t{\n\t\tassertThrow(memory(_instruction) == Effect::Write, OptimizerException, \"\");\n\t\tassertThrow(storage(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tassertThrow(transientStorage(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tOperation op;\n\t\top.effect = memory(_instruction);\n\t\top.location = Location::Memory;\n\t\top.startParameter = 0;\n\t\top.lengthParameter = 2;\n\t\treturn {op};\n\t}\n\tcase Instruction::MCOPY:\n\t{\n\t\tassertThrow(memory(_instruction) != Effect::None, OptimizerException, \"\");\n\t\tassertThrow(storage(_instruction) == Effect::None, OptimizerException, \"\");\n\t\tassertThrow(transientStorage(_instruction) == Effect::None, OptimizerException, \"\");\n\n\t\tOperation readOperation;\n\t\treadOperation.effect = Read;\n\t\treadOperation.location = Location::Memory;\n\t\treadOperation.startParameter = 1;\n\t\treadOperation.lengthParameter = 2;\n\n\t\tOperation writeOperation;\n\t\twriteOperation.effect = Write;\n\t\twriteOperation.location = Location::Memory;\n\t\twriteOperation.startParameter = 0;\n\t\twriteOperation.lengthParameter = 2;\n\n\t\treturn {readOperation, writeOperation};\n\t}\n\tcase Instruction::STATICCALL:\n\tcase Instruction::CALL:\n\tcase Instruction::CALLCODE:\n\tcase Instruction::DELEGATECALL:\n\t{\n\t\tsize_t paramCount = static_cast<size_t>(instructionInfo(_instruction, langutil::EVMVersion()).args);\n\t\tstd::vector<Operation> operations{\n\t\t\tOperation{Location::Memory, Effect::Read, paramCount - 4, paramCount - 3, {}},\n\t\t\tOperation{Location::Storage, Effect::Read, {}, {}, {}},\n\t\t\tOperation{Location::TransientStorage, Effect::Read, {}, {}, {}}\n\t\t};\n\t\tif (_instruction != Instruction::STATICCALL)\n\t\t{\n\t\t\toperations.emplace_back(Operation{Location::Storage, Effect::Write, {}, {}, {}});\n\t\t\toperations.emplace_back(Operation{Location::TransientStorage, Effect::Write, {}, {}, {}});\n\t\t}\n\t\toperations.emplace_back(Operation{\n\t\t\tLocation::Memory,\n\t\t\tEffect::Write,\n\t\t\tparamCount - 2,\n\t\t\t// Length is in paramCount - 1, but it is only a max length,\n\t\t\t// there is no guarantee that the full area is written to.\n\t\t\t{},\n\t\t\t{}\n\t\t});\n\t\treturn operations;\n\t}\n\tcase Instruction::EXTCALL:\n\tcase Instruction::EXTSTATICCALL:\n\tcase Instruction::EXTDELEGATECALL:\n\t{\n\t\tsize_t paramCount = static_cast<size_t>(instructionInfo(_instruction, langutil::EVMVersion()).args);\n\t\tsize_t const memoryStartParam = _instruction == Instruction::EXTCALL ? paramCount - 3 : paramCount - 2;\n\t\tsize_t const memoryLengthParam = _instruction == Instruction::EXTCALL ? paramCount - 2 : paramCount - 1;\n\t\tstd::vector<Operation> operations{\n\t\t\tOperation{Location::Memory, Effect::Read, memoryStartParam, memoryLengthParam, {}},\n\t\t\tOperation{Location::Storage, Effect::Read, {}, {}, {}},\n\t\t\tOperation{Location::TransientStorage, Effect::Read, {}, {}, {}}\n\t\t};\n\t\tif (_instruction == Instruction::EXTDELEGATECALL)\n\t\t{\n\t\t\toperations.emplace_back(Operation{Location::Storage, Effect::Write, {}, {}, {}});\n\t\t\toperations.emplace_back(Operation{Location::TransientStorage, Effect::Write, {}, {}, {}});\n\t\t}\n\n\t\treturn operations;\n\t}\n\tcase Instruction::CREATE:\n\tcase Instruction::CREATE2:\n\t\treturn std::vector<Operation>{\n\t\t\tOperation{\n\t\t\t\tLocation::Memory,\n\t\t\t\tEffect::Read,\n\t\t\t\t1,\n\t\t\t\t2,\n\t\t\t\t{}\n\t\t\t},\n\t\t\tOperation{Location::Storage, Effect::Read, {}, {}, {}},\n\t\t\tOperation{Location::Storage, Effect::Write, {}, {}, {}},\n\t\t\tOperation{Location::TransientStorage, Effect::Read, {}, {}, {}},\n\t\t\tOperation{Location::TransientStorage, Effect::Write, {}, {}, {}}\n\t\t};\n\tcase Instruction::EOFCREATE:\n\t\treturn std::vector<Operation>{\n\t\t\tOperation{\n\t\t\t\tLocation::Memory,\n\t\t\t\tEffect::Read,\n\t\t\t\t2,\n\t\t\t\t3,\n\t\t\t\t{}\n\t\t\t},\n\t\t\tOperation{Location::Storage, Effect::Read, {}, {}, {}},\n\t\t\tOperation{Location::Storage, Effect::Write, {}, {}, {}},\n\t\t\tOperation{Location::TransientStorage, Effect::Read, {}, {}, {}},\n\t\t\tOperation{Location::TransientStorage, Effect::Write, {}, {}, {}}\n\t\t};\n\tcase Instruction::RETURNCONTRACT:\n\t\treturn std::vector<Operation>{\n\t\t\tOperation{\n\t\t\t\tLocation::Memory,\n\t\t\t\tEffect::Read,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t\t{}\n\t\t\t},\n\t\t\tOperation{Location::Storage, Effect::Read, {}, {}, {}},\n\t\t\tOperation{Location::Storage, Effect::Write, {}, {}, {}},\n\t\t\tOperation{Location::TransientStorage, Effect::Read, {}, {}, {}},\n\t\t\tOperation{Location::TransientStorage, Effect::Write, {}, {}, {}}\n\t\t};\n\tcase Instruction::MSIZE:\n\t\t// This is just to satisfy the assert below.\n\t\treturn std::vector<Operation>{};\n\tdefault:\n\t\tassertThrow(storage(_instruction) == None && memory(_instruction) == None && transientStorage(_instruction) == None, AssemblyException, \"\");\n\t}\n\treturn {};\n}\n\nbool SemanticInformation::breaksCSEAnalysisBlock(AssemblyItem const& _item, bool _msizeImportant)\n{\n\tswitch (_item.type())\n\t{\n\tdefault:\n\tcase UndefinedItem:\n\tcase Tag:\n\tcase PushDeployTimeAddress:\n\tcase AssignImmutable:\n\tcase VerbatimBytecode:\n\tcase CallF:\n\tcase JumpF:\n\tcase RetF:\n\t\treturn true;\n\tcase Push:\n\tcase PushTag:\n\tcase PushSub:\n\tcase PushSubSize:\n\tcase PushProgramSize:\n\tcase PushData:\n\tcase PushLibraryAddress:\n\tcase PushImmutable:\n\t\treturn false;\n\tcase evmasm::Operation:\n\t{\n\t\tif (isSwapInstruction(_item) || isDupInstruction(_item))\n\t\t\treturn false;\n\t\tif (_item.instruction() == Instruction::GAS || _item.instruction() == Instruction::PC)\n\t\t\treturn true; // GAS and PC assume a specific order of opcodes\n\t\tif (_item.instruction() == Instruction::MSIZE)\n\t\t\treturn true; // msize is modified already by memory access, avoid that for now\n\t\tInstructionInfo info = instructionInfo(_item.instruction(), langutil::EVMVersion());\n\t\tif (_item.instruction() == Instruction::SSTORE)\n\t\t\treturn false;\n\t\tif (_item.instruction() == Instruction::MSTORE)\n\t\t\treturn false;\n\t\tif (!_msizeImportant && (\n\t\t\t_item.instruction() == Instruction::MLOAD ||\n\t\t\t_item.instruction() == Instruction::KECCAK256\n\t\t))\n\t\t\treturn false;\n\t\t//@todo: We do not handle the following memory instructions for now:\n\t\t// calldatacopy, codecopy, extcodecopy, mcopy, mstore8,\n\t\t// msize (note that msize also depends on memory read access)\n\n\t\t// the second requirement will be lifted once it is implemented\n\t\treturn info.sideEffects || info.args > 2;\n\t}\n\t}\n}\n\nbool SemanticInformation::isCommutativeOperation(AssemblyItem const& _item)\n{\n\tif (_item.type() != evmasm::Operation)\n\t\treturn false;\n\tswitch (_item.instruction())\n\t{\n\tcase Instruction::ADD:\n\tcase Instruction::MUL:\n\tcase Instruction::EQ:\n\tcase Instruction::AND:\n\tcase Instruction::OR:\n\tcase Instruction::XOR:\n\t\treturn true;\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nbool SemanticInformation::isDupInstruction(AssemblyItem const& _item)\n{\n\tif (_item.type() == evmasm::DupN)\n\t\treturn true;\n\tif (_item.type() != evmasm::Operation)\n\t\treturn false;\n\tauto inst = _item.instruction();\n\treturn Instruction::DUP1 <= inst && inst <= Instruction::DUP16;\n}\n\nbool SemanticInformation::isSwapInstruction(AssemblyItem const& _item)\n{\n\tif (_item.type() == evmasm::SwapN)\n\t\treturn true;\n\tif (_item.type() != evmasm::Operation)\n\t\treturn false;\n\tauto inst = _item.instruction();\n\treturn Instruction::SWAP1 <= inst && inst <= Instruction::SWAP16;\n}\n\nbool SemanticInformation::altersControlFlow(AssemblyItem const& _item)\n{\n\tif (!_item.hasInstruction())\n\t\treturn false;\n\n\tswitch (_item.instruction())\n\t{\n\t// note that CALL, CALLCODE and CREATE do not really alter the control flow, because we\n\t// continue on the next instruction\n\tcase Instruction::JUMP:\n\tcase Instruction::JUMPI:\n\tcase Instruction::RJUMP:\n\tcase Instruction::RJUMPI:\n\tcase Instruction::RETURN:\n\tcase Instruction::SELFDESTRUCT:\n\tcase Instruction::STOP:\n\tcase Instruction::INVALID:\n\tcase Instruction::REVERT:\n\tcase Instruction::RETURNCONTRACT:\n\tcase Instruction::CALLF:\n\tcase Instruction::JUMPF:\n\tcase Instruction::RETF:\n\t\treturn true;\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nbool SemanticInformation::terminatesControlFlow(AssemblyItem const& _item)\n{\n\tif (!_item.hasInstruction())\n\t\treturn false;\n\treturn terminatesControlFlow(_item.instruction());\n}\n\nbool SemanticInformation::terminatesControlFlow(Instruction _instruction)\n{\n\tswitch (_instruction)\n\t{\n\tcase Instruction::RETURN:\n\tcase Instruction::SELFDESTRUCT:\n\tcase Instruction::STOP:\n\tcase Instruction::INVALID:\n\tcase Instruction::REVERT:\n\tcase Instruction::RETURNCONTRACT:\n\t\treturn true;\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nbool SemanticInformation::reverts(Instruction _instruction)\n{\n\tswitch (_instruction)\n\t{\n\t\tcase Instruction::INVALID:\n\t\tcase Instruction::REVERT:\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nsize_t SemanticInformation::getDupNumber(AssemblyItem const& _item)\n{\n\tassertThrow(isDupInstruction(_item), OptimizerException, \"Not a DUP instruction.\");\n\tif (_item.type() == evmasm::DupN)\n\t\treturn static_cast<size_t>(_item.data());\n\tauto inst = _item.instruction();\n\treturn static_cast<uint8_t>(inst) - static_cast<size_t>(Instruction::DUP1) + 1;\n}\n\nsize_t SemanticInformation::getSwapNumber(AssemblyItem const& _item)\n{\n\tassertThrow(isSwapInstruction(_item), OptimizerException, \"Not a swap instruction.\");\n\tif (_item.type() == evmasm::SwapN)\n\t\treturn static_cast<size_t>(_item.data());\n\tauto inst = _item.instruction();\n\treturn static_cast<uint8_t>(inst) - static_cast<size_t>(Instruction::SWAP1) + 1;\n}\n\nbool SemanticInformation::isDeterministic(AssemblyItem const& _item)\n{\n\tassertThrow(_item.type() != VerbatimBytecode, AssemblyException, \"\");\n\n\tif (!_item.hasInstruction())\n\t\treturn true;\n\n\tswitch (_item.instruction())\n\t{\n\tcase Instruction::CALL:\n\tcase Instruction::CALLCODE:\n\tcase Instruction::DELEGATECALL:\n\tcase Instruction::STATICCALL:\n\tcase Instruction::EXTCALL:\n\tcase Instruction::EXTDELEGATECALL:\n\tcase Instruction::EXTSTATICCALL:\n\tcase Instruction::CREATE:\n\tcase Instruction::CREATE2:\n\tcase Instruction::GAS:\n\tcase Instruction::PC:\n\tcase Instruction::MSIZE: // depends on previous writes and reads, not only on content\n\tcase Instruction::BALANCE: // depends on previous calls\n\tcase Instruction::SELFBALANCE: // depends on previous calls\n\tcase Instruction::EXTCODESIZE:\n\tcase Instruction::EXTCODEHASH:\n\tcase Instruction::RETURNDATACOPY: // depends on previous calls\n\tcase Instruction::RETURNDATASIZE:\n\tcase Instruction::EOFCREATE:\n\tcase Instruction::CALLF:\n\tcase Instruction::JUMPF:\n\t\treturn false;\n\tdefault:\n\t\treturn true;\n\t}\n}\n\nbool SemanticInformation::movable(Instruction _instruction)\n{\n\t// These are not really functional.\n\tif (isDupInstruction(_instruction) || isSwapInstruction(_instruction))\n\t\treturn false;\n\tInstructionInfo info = instructionInfo(_instruction, langutil::EVMVersion());\n\tif (info.sideEffects)\n\t\treturn false;\n\tswitch (_instruction)\n\t{\n\tcase Instruction::KECCAK256:\n\tcase Instruction::BALANCE:\n\tcase Instruction::SELFBALANCE:\n\tcase Instruction::EXTCODESIZE:\n\tcase Instruction::EXTCODEHASH:\n\tcase Instruction::RETURNDATASIZE:\n\tcase Instruction::SLOAD:\n\tcase Instruction::TLOAD:\n\tcase Instruction::PC:\n\tcase Instruction::MSIZE:\n\tcase Instruction::GAS:\n\t\treturn false;\n\tdefault:\n\t\treturn true;\n\t}\n\treturn true;\n}\n\nbool SemanticInformation::canBeRemoved(Instruction _instruction)\n{\n\t// These are not really functional.\n\tassertThrow(!isDupInstruction(_instruction) && !isSwapInstruction(_instruction), AssemblyException, \"\");\n\n\treturn !instructionInfo(_instruction, langutil::EVMVersion()).sideEffects;\n}\n\nbool SemanticInformation::canBeRemovedIfNoMSize(Instruction _instruction)\n{\n\tif (_instruction == Instruction::KECCAK256 || _instruction == Instruction::MLOAD)\n\t\treturn true;\n\telse\n\t\treturn canBeRemoved(_instruction);\n}\n\nSemanticInformation::Effect SemanticInformation::memory(Instruction _instruction)\n{\n\tswitch (_instruction)\n\t{\n\tcase Instruction::CALLDATACOPY:\n\tcase Instruction::CODECOPY:\n\tcase Instruction::EXTCODECOPY:\n\tcase Instruction::RETURNDATACOPY:\n\tcase Instruction::MCOPY:\n\tcase Instruction::MSTORE:\n\tcase Instruction::MSTORE8:\n\tcase Instruction::CALL:\n\tcase Instruction::CALLCODE:\n\tcase Instruction::DELEGATECALL:\n\tcase Instruction::STATICCALL:\n\t\treturn SemanticInformation::Write;\n\n\tcase Instruction::CREATE:\n\tcase Instruction::CREATE2:\n\tcase Instruction::KECCAK256:\n\tcase Instruction::MLOAD:\n\tcase Instruction::MSIZE:\n\tcase Instruction::RETURN:\n\tcase Instruction::REVERT:\n\tcase Instruction::LOG0:\n\tcase Instruction::LOG1:\n\tcase Instruction::LOG2:\n\tcase Instruction::LOG3:\n\tcase Instruction::LOG4:\n\tcase Instruction::EOFCREATE:\n\tcase Instruction::RETURNCONTRACT:\n\tcase Instruction::EXTCALL:\n\tcase Instruction::EXTDELEGATECALL:\n\tcase Instruction::EXTSTATICCALL:\n\t\treturn SemanticInformation::Read;\n\n\tdefault:\n\t\treturn SemanticInformation::None;\n\t}\n}\n\nbool SemanticInformation::movableApartFromEffects(Instruction _instruction)\n{\n\tswitch (_instruction)\n\t{\n\tcase Instruction::EXTCODEHASH:\n\tcase Instruction::EXTCODESIZE:\n\tcase Instruction::RETURNDATASIZE:\n\tcase Instruction::BALANCE:\n\tcase Instruction::SELFBALANCE:\n\tcase Instruction::SLOAD:\n\tcase Instruction::TLOAD:\n\tcase Instruction::KECCAK256:\n\tcase Instruction::MLOAD:\n\t\treturn true;\n\n\tdefault:\n\t\treturn movable(_instruction);\n\t}\n}\n\nSemanticInformation::Effect SemanticInformation::storage(Instruction _instruction)\n{\n\tswitch (_instruction)\n\t{\n\tcase Instruction::CALL:\n\tcase Instruction::CALLCODE:\n\tcase Instruction::DELEGATECALL:\n\tcase Instruction::CREATE:\n\tcase Instruction::CREATE2:\n\tcase Instruction::SSTORE:\n\tcase Instruction::EOFCREATE:\n\tcase Instruction::RETURNCONTRACT:\n\tcase Instruction::EXTCALL:\n\tcase Instruction::EXTDELEGATECALL:\n\t\treturn SemanticInformation::Write;\n\n\tcase Instruction::SLOAD:\n\tcase Instruction::STATICCALL:\n\tcase Instruction::EXTSTATICCALL:\n\t\treturn SemanticInformation::Read;\n\n\tdefault:\n\t\treturn SemanticInformation::None;\n\t}\n}\n\nSemanticInformation::Effect SemanticInformation::transientStorage(Instruction _instruction)\n{\n\tswitch (_instruction)\n\t{\n\tcase Instruction::CALL:\n\tcase Instruction::CALLCODE:\n\tcase Instruction::DELEGATECALL:\n\tcase Instruction::CREATE:\n\tcase Instruction::CREATE2:\n\tcase Instruction::TSTORE:\n\tcase Instruction::EOFCREATE:\n\tcase Instruction::RETURNCONTRACT:\n\tcase Instruction::EXTCALL:\n\tcase Instruction::EXTDELEGATECALL:\n\t\treturn SemanticInformation::Write;\n\n\tcase Instruction::TLOAD:\n\tcase Instruction::STATICCALL:\n\tcase Instruction::EXTSTATICCALL:\n\t\treturn SemanticInformation::Read;\n\n\tdefault:\n\t\treturn SemanticInformation::None;\n\t}\n}\n\nSemanticInformation::Effect SemanticInformation::otherState(Instruction _instruction)\n{\n\tswitch (_instruction)\n\t{\n\tcase Instruction::CALL:\n\tcase Instruction::CALLCODE:\n\tcase Instruction::DELEGATECALL:\n\tcase Instruction::CREATE:\n\tcase Instruction::CREATE2:\n\tcase Instruction::EOFCREATE:\n\tcase Instruction::RETURNCONTRACT:\n\tcase Instruction::EXTCALL:\n\tcase Instruction::EXTDELEGATECALL:\n\tcase Instruction::SELFDESTRUCT:\n\tcase Instruction::EXTSTATICCALL:\n\tcase Instruction::STATICCALL: // because it can affect returndatasize\n\t\t// Strictly speaking, log0, .., log4 writes to the state, but the EVM cannot read it, so they\n\t\t// are just marked as having 'other side effects.'\n\t\treturn SemanticInformation::Write;\n\n\tcase Instruction::EXTCODESIZE:\n\tcase Instruction::EXTCODEHASH:\n\tcase Instruction::RETURNDATASIZE:\n\tcase Instruction::BALANCE:\n\tcase Instruction::SELFBALANCE:\n\tcase Instruction::RETURNDATACOPY:\n\tcase Instruction::EXTCODECOPY:\n\t\t// PC and GAS are specifically excluded here. Instructions such as CALLER, CALLVALUE,\n\t\t// ADDRESS are excluded because they cannot change during execution.\n\t\treturn SemanticInformation::Read;\n\n\tdefault:\n\t\treturn SemanticInformation::None;\n\t}\n}\n\nbool SemanticInformation::invalidInPureFunctions(Instruction _instruction)\n{\n\tswitch (_instruction)\n\t{\n\tcase Instruction::ADDRESS:\n\tcase Instruction::SELFBALANCE:\n\tcase Instruction::BALANCE:\n\tcase Instruction::ORIGIN:\n\tcase Instruction::CALLER:\n\tcase Instruction::CALLVALUE:\n\tcase Instruction::CHAINID:\n\tcase Instruction::BASEFEE:\n\tcase Instruction::BLOBBASEFEE:\n\tcase Instruction::GAS:\n\tcase Instruction::GASPRICE:\n\tcase Instruction::EXTCODESIZE:\n\tcase Instruction::EXTCODECOPY:\n\tcase Instruction::EXTCODEHASH:\n\tcase Instruction::BLOCKHASH:\n\tcase Instruction::BLOBHASH:\n\tcase Instruction::COINBASE:\n\tcase Instruction::TIMESTAMP:\n\tcase Instruction::NUMBER:\n\tcase Instruction::PREVRANDAO:\n\tcase Instruction::GASLIMIT:\n\tcase Instruction::EXTSTATICCALL:\n\tcase Instruction::STATICCALL:\n\tcase Instruction::SLOAD:\n\tcase Instruction::TLOAD:\n\t\treturn true;\n\tdefault:\n\t\tbreak;\n\t}\n\treturn invalidInViewFunctions(_instruction);\n}\n\nbool SemanticInformation::invalidInViewFunctions(Instruction _instruction)\n{\n\t// Relative jumps cannot jump out of the current code section of EOF so they are valid in view functions\n\t// (under the assumption that every Solidity function actually gets its own code section).\n\tswitch (_instruction)\n\t{\n\tcase Instruction::SSTORE:\n\tcase Instruction::TSTORE:\n\tcase Instruction::JUMP:\n\tcase Instruction::JUMPI:\n\tcase Instruction::LOG0:\n\tcase Instruction::LOG1:\n\tcase Instruction::LOG2:\n\tcase Instruction::LOG3:\n\tcase Instruction::LOG4:\n\tcase Instruction::CREATE:\n\tcase Instruction::CALL:\n\tcase Instruction::CALLCODE:\n\tcase Instruction::DELEGATECALL:\n\tcase Instruction::EXTCALL:\n\tcase Instruction::EXTDELEGATECALL:\n\t// According to EOF spec https://eips.ethereum.org/EIPS/eip-7620#eofcreate\n\tcase Instruction::EOFCREATE:\n\t// According to EOF spec https://eips.ethereum.org/EIPS/eip-7620#returncontract\n\tcase Instruction::RETURNCONTRACT:\n\tcase Instruction::CREATE2:\n\tcase Instruction::SELFDESTRUCT:\n\t\treturn true;\n\tdefault:\n\t\tbreak;\n\t}\n\treturn false;\n}\n"
  },
  {
    "path": "libevmasm/SemanticInformation.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file SemanticInformation.h\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Helper to provide semantic information about assembly items.\n */\n\n#pragma once\n\n#include <libevmasm/Instruction.h>\n\n#include <optional>\n#include <vector>\n\nnamespace solidity::evmasm\n{\n\nclass AssemblyItem;\n\n/**\n * Helper functions to provide context-independent information about assembly items.\n */\nstruct SemanticInformation\n{\n\t/// Corresponds to the effect that a YUL-builtin has on a generic data location (storage, memory,\n\t/// transient storage and other blockchain state).\n\tenum Effect\n\t{\n\t\tNone,\n\t\tRead,\n\t\tWrite\n\t};\n\n\tenum class Location { Storage, Memory, TransientStorage };\n\n\t/**\n\t * Represents a read or write operation from or to one of the data locations.\n\t */\n\tstruct Operation\n\t{\n\t\tLocation location;\n\t\tEffect effect;\n\t\t/// Start of affected area as an index into the parameters.\n\t\t/// Unknown if not provided.\n\t\tstd::optional<size_t> startParameter;\n\t\t/// Length of the affected area as an index into the parameters (if this is an opcode).\n\t\t/// Unknown if neither this nor lengthConstant is provided.\n\t\tstd::optional<size_t> lengthParameter;\n\t\t/// Length as a constant.\n\t\t/// Unknown if neither this nor lengthArgument is provided.\n\t\tstd::optional<size_t> lengthConstant;\n\t};\n\n\t/// @returns the sequence of read write operations performed by the instruction.\n\t/// Order matters.\n\t/// For external calls, there is just one unknown read and one unknown write operation,\n\t/// event though there might be multiple.\n\tstatic std::vector<Operation> readWriteOperations(Instruction _instruction);\n\n\t/// @returns true if the given items starts a new block for common subexpression analysis.\n\t/// @param _msizeImportant if false, consider an operation non-breaking if its only side-effect is that it modifies msize.\n\tstatic bool breaksCSEAnalysisBlock(AssemblyItem const& _item, bool _msizeImportant);\n\t/// @returns true if the item is a two-argument operation whose value does not depend on the\n\t/// order of its arguments.\n\tstatic bool isCommutativeOperation(AssemblyItem const& _item);\n\tstatic bool isDupInstruction(AssemblyItem const& _item);\n\tstatic bool isSwapInstruction(AssemblyItem const& _item);\n\tstatic bool altersControlFlow(AssemblyItem const& _item);\n\tstatic bool terminatesControlFlow(AssemblyItem const& _item);\n\tstatic bool terminatesControlFlow(Instruction _instruction);\n\tstatic bool reverts(Instruction _instruction);\n\t/// @returns the 1-based DUP depth a DUP AssembleItem @a _item\n\tstatic size_t getDupNumber(AssemblyItem const& _item);\n\t/// @returns the 1-based SWAP depth a DUP AssembleItem @a _item\n\tstatic size_t getSwapNumber(AssemblyItem const& _item);\n\t/// @returns false if the value put on the stack by _item depends on anything else than\n\t/// the information in the current block header, memory, storage, transient storage or stack.\n\tstatic bool isDeterministic(AssemblyItem const& _item);\n\t/// @returns true if the instruction can be moved or copied (together with its arguments)\n\t/// without altering the semantics. This means it cannot depend on storage, transient storage or memory,\n\t/// cannot have any side-effects, but it can depend on a call-constant state of the blockchain.\n\tstatic bool movable(Instruction _instruction);\n\t/// If true, the expressions in this code can be moved or copied (together with their arguments)\n\t/// across control flow branches and instructions as long as these instructions' 'effects' do\n\t/// not influence the 'effects' of the aforementioned expressions.\n\tstatic bool movableApartFromEffects(Instruction _instruction);\n\t/// @returns true if the instruction can be removed without changing the semantics.\n\t/// This does not mean that it has to be deterministic or retrieve information from\n\t/// somewhere else than purely the values of its arguments.\n\tstatic bool canBeRemoved(Instruction _instruction);\n\t/// @returns true if the instruction can be removed without changing the semantics.\n\t/// This does not mean that it has to be deterministic or retrieve information from\n\t/// somewhere else than purely the values of its arguments.\n\t/// If true, the instruction is still allowed to influence the value returned by the\n\t/// msize instruction.\n\tstatic bool canBeRemovedIfNoMSize(Instruction _instruction);\n\tstatic Effect memory(Instruction _instruction);\n\tstatic Effect storage(Instruction _instruction);\n\tstatic Effect transientStorage(Instruction _instruction);\n\tstatic Effect otherState(Instruction _instruction);\n\tstatic bool invalidInPureFunctions(Instruction _instruction);\n\tstatic bool invalidInViewFunctions(Instruction _instruction);\n};\n\n}\n"
  },
  {
    "path": "libevmasm/SimplificationRule.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Expression simplification pattern.\n */\n\n#pragma once\n\n#include <libevmasm/Instruction.h>\n#include <libsolutil/CommonData.h>\n#include <functional>\n\nnamespace solidity::evmasm\n{\n\n/**\n * Rule that contains a pattern, an action that can be applied\n * after the pattern has matched and optional condition to check if the\n * action should be applied.\n */\ntemplate <class Pattern>\nstruct SimplificationRule\n{\n\tSimplificationRule(\n\t\tPattern _pattern,\n\t\tstd::function<Pattern()> _action,\n\t\tstd::function<bool()> _feasible = {}\n\t):\n\t\tpattern(std::move(_pattern)),\n\t\taction(std::move(_action)),\n\t\tfeasible(std::move(_feasible))\n\t{}\n\n\tPattern pattern;\n\tstd::function<Pattern()> action;\n\tstd::function<bool()> feasible;\n};\n\ntemplate <typename Pattern>\nstruct EVMBuiltins\n{\n\tusing InstrType = Instruction;\n\n\ttemplate<Instruction inst>\n\tstruct PatternGenerator\n\t{\n\t\ttemplate<typename... Args> constexpr Pattern operator()(Args&&... _args) const\n\t\t{\n\t\t\treturn {inst, {std::forward<Args>(_args)...}};\n\t\t}\n\t};\n\n\tstruct PatternGeneratorInstance\n\t{\n\t\tInstruction instruction;\n\t\ttemplate<typename... Args> constexpr Pattern operator()(Args&&... _args) const\n\t\t{\n\t\t\treturn {instruction, {std::forward<Args>(_args)...}};\n\t\t}\n\t};\n\n\n\tstatic auto constexpr STOP = PatternGenerator<Instruction::STOP>{};\n\tstatic auto constexpr ADD = PatternGenerator<Instruction::ADD>{};\n\tstatic auto constexpr SUB = PatternGenerator<Instruction::SUB>{};\n\tstatic auto constexpr MUL = PatternGenerator<Instruction::MUL>{};\n\tstatic auto constexpr DIV = PatternGenerator<Instruction::DIV>{};\n\tstatic auto constexpr SDIV = PatternGenerator<Instruction::SDIV>{};\n\tstatic auto constexpr MOD = PatternGenerator<Instruction::MOD>{};\n\tstatic auto constexpr SMOD = PatternGenerator<Instruction::SMOD>{};\n\tstatic auto constexpr EXP = PatternGenerator<Instruction::EXP>{};\n\tstatic auto constexpr NOT = PatternGenerator<Instruction::NOT>{};\n\tstatic auto constexpr LT = PatternGenerator<Instruction::LT>{};\n\tstatic auto constexpr GT = PatternGenerator<Instruction::GT>{};\n\tstatic auto constexpr SLT = PatternGenerator<Instruction::SLT>{};\n\tstatic auto constexpr SGT = PatternGenerator<Instruction::SGT>{};\n\tstatic auto constexpr EQ = PatternGenerator<Instruction::EQ>{};\n\tstatic auto constexpr ISZERO = PatternGenerator<Instruction::ISZERO>{};\n\tstatic auto constexpr AND = PatternGenerator<Instruction::AND>{};\n\tstatic auto constexpr OR = PatternGenerator<Instruction::OR>{};\n\tstatic auto constexpr XOR = PatternGenerator<Instruction::XOR>{};\n\tstatic auto constexpr BYTE = PatternGenerator<Instruction::BYTE>{};\n\tstatic auto constexpr SHL = PatternGenerator<Instruction::SHL>{};\n\tstatic auto constexpr SHR = PatternGenerator<Instruction::SHR>{};\n\tstatic auto constexpr SAR = PatternGenerator<Instruction::SAR>{};\n\tstatic auto constexpr CLZ = PatternGenerator<Instruction::CLZ>{};\n\tstatic auto constexpr ADDMOD = PatternGenerator<Instruction::ADDMOD>{};\n\tstatic auto constexpr MULMOD = PatternGenerator<Instruction::MULMOD>{};\n\tstatic auto constexpr SIGNEXTEND = PatternGenerator<Instruction::SIGNEXTEND>{};\n\tstatic auto constexpr KECCAK256 = PatternGenerator<Instruction::KECCAK256>{};\n\tstatic auto constexpr ADDRESS = PatternGenerator<Instruction::ADDRESS>{};\n\tstatic auto constexpr BALANCE = PatternGenerator<Instruction::BALANCE>{};\n\tstatic auto constexpr ORIGIN = PatternGenerator<Instruction::ORIGIN>{};\n\tstatic auto constexpr CALLER = PatternGenerator<Instruction::CALLER>{};\n\tstatic auto constexpr CALLVALUE = PatternGenerator<Instruction::CALLVALUE>{};\n\tstatic auto constexpr CALLDATALOAD = PatternGenerator<Instruction::CALLDATALOAD>{};\n\tstatic auto constexpr CALLDATASIZE = PatternGenerator<Instruction::CALLDATASIZE>{};\n\tstatic auto constexpr CALLDATACOPY = PatternGenerator<Instruction::CALLDATACOPY>{};\n\tstatic auto constexpr CODESIZE = PatternGenerator<Instruction::CODESIZE>{};\n\tstatic auto constexpr CODECOPY = PatternGenerator<Instruction::CODECOPY>{};\n\tstatic auto constexpr GASPRICE = PatternGenerator<Instruction::GASPRICE>{};\n\tstatic auto constexpr EXTCODESIZE = PatternGenerator<Instruction::EXTCODESIZE>{};\n\tstatic auto constexpr EXTCODECOPY = PatternGenerator<Instruction::EXTCODECOPY>{};\n\tstatic auto constexpr RETURNDATASIZE = PatternGenerator<Instruction::RETURNDATASIZE>{};\n\tstatic auto constexpr RETURNDATACOPY = PatternGenerator<Instruction::RETURNDATACOPY>{};\n\tstatic auto constexpr MCOPY = PatternGenerator<Instruction::MCOPY>{};\n\tstatic auto constexpr EXTCODEHASH = PatternGenerator<Instruction::EXTCODEHASH>{};\n\tstatic auto constexpr BLOCKHASH = PatternGenerator<Instruction::BLOCKHASH>{};\n\tstatic auto constexpr BLOBHASH = PatternGenerator<Instruction::BLOBHASH>{};\n\tstatic auto constexpr COINBASE = PatternGenerator<Instruction::COINBASE>{};\n\tstatic auto constexpr TIMESTAMP = PatternGenerator<Instruction::TIMESTAMP>{};\n\tstatic auto constexpr NUMBER = PatternGenerator<Instruction::NUMBER>{};\n\tstatic auto constexpr PREVRANDAO = PatternGenerator<Instruction::PREVRANDAO>{};\n\tstatic auto constexpr GASLIMIT = PatternGenerator<Instruction::GASLIMIT>{};\n\tstatic auto constexpr CHAINID = PatternGenerator<Instruction::CHAINID>{};\n\tstatic auto constexpr SELFBALANCE = PatternGenerator<Instruction::SELFBALANCE>{};\n\tstatic auto constexpr BASEFEE = PatternGenerator<Instruction::BASEFEE>{};\n\tstatic auto constexpr BLOBBASEFEE = PatternGenerator<Instruction::BLOBBASEFEE>{};\n\tstatic auto constexpr POP = PatternGenerator<Instruction::POP>{};\n\tstatic auto constexpr MLOAD = PatternGenerator<Instruction::MLOAD>{};\n\tstatic auto constexpr MSTORE = PatternGenerator<Instruction::MSTORE>{};\n\tstatic auto constexpr MSTORE8 = PatternGenerator<Instruction::MSTORE8>{};\n\tstatic auto constexpr SLOAD = PatternGenerator<Instruction::SLOAD>{};\n\tstatic auto constexpr SSTORE = PatternGenerator<Instruction::SSTORE>{};\n\tstatic auto constexpr TLOAD = PatternGenerator<Instruction::TLOAD>{};\n\tstatic auto constexpr TSTORE = PatternGenerator<Instruction::TSTORE>{};\n\tstatic auto constexpr PC = PatternGenerator<Instruction::PC>{};\n\tstatic auto constexpr MSIZE = PatternGenerator<Instruction::MSIZE>{};\n\tstatic auto constexpr GAS = PatternGenerator<Instruction::GAS>{};\n\tstatic auto constexpr LOG0 = PatternGenerator<Instruction::LOG0>{};\n\tstatic auto constexpr LOG1 = PatternGenerator<Instruction::LOG1>{};\n\tstatic auto constexpr LOG2 = PatternGenerator<Instruction::LOG2>{};\n\tstatic auto constexpr LOG3 = PatternGenerator<Instruction::LOG3>{};\n\tstatic auto constexpr LOG4 = PatternGenerator<Instruction::LOG4>{};\n\tstatic auto constexpr CREATE = PatternGenerator<Instruction::CREATE>{};\n\tstatic auto constexpr CALL = PatternGenerator<Instruction::CALL>{};\n\tstatic auto constexpr CALLCODE = PatternGenerator<Instruction::CALLCODE>{};\n\tstatic auto constexpr STATICCALL = PatternGenerator<Instruction::STATICCALL>{};\n\tstatic auto constexpr RETURN = PatternGenerator<Instruction::RETURN>{};\n\tstatic auto constexpr DELEGATECALL = PatternGenerator<Instruction::DELEGATECALL>{};\n\tstatic auto constexpr CREATE2 = PatternGenerator<Instruction::CREATE2>{};\n\tstatic auto constexpr REVERT = PatternGenerator<Instruction::REVERT>{};\n\tstatic auto constexpr INVALID = PatternGenerator<Instruction::INVALID>{};\n\tstatic auto constexpr SELFDESTRUCT = PatternGenerator<Instruction::SELFDESTRUCT>{};\n};\n\n}\n"
  },
  {
    "path": "libevmasm/SimplificationRules.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file ExpressionClasses.cpp\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Container for equivalence classes of expressions for use in common subexpression elimination.\n */\n\n#include <libevmasm/SimplificationRules.h>\n\n#include <libevmasm/ExpressionClasses.h>\n#include <libevmasm/Assembly.h>\n#include <libevmasm/RuleList.h>\n#include <libsolutil/Assertions.h>\n\n#include <utility>\n#include <functional>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::langutil;\n\nSimplificationRule<Pattern> const* Rules::findFirstMatch(\n\tExpression const& _expr,\n\tExpressionClasses const& _classes\n)\n{\n\tresetMatchGroups();\n\n\tassertThrow(_expr.item, OptimizerException, \"\");\n\tfor (auto const& rule: m_rules[uint8_t(_expr.item->instruction())])\n\t{\n\t\tif (rule.pattern.matches(_expr, _classes))\n\t\t\tif (!rule.feasible || rule.feasible())\n\t\t\t\treturn &rule;\n\n\t\tresetMatchGroups();\n\t}\n\treturn nullptr;\n}\n\nbool Rules::isInitialized() const\n{\n\treturn !m_rules[uint8_t(Instruction::ADD)].empty();\n}\n\nvoid Rules::addRules(std::vector<SimplificationRule<Pattern>> const& _rules)\n{\n\tfor (auto const& r: _rules)\n\t\taddRule(r);\n}\n\nvoid Rules::addRule(SimplificationRule<Pattern> const& _rule)\n{\n\tm_rules[uint8_t(_rule.pattern.instruction())].push_back(_rule);\n}\n\nRules::Rules()\n{\n\t// Multiple occurrences of one of these inside one rule must match the same equivalence class.\n\t// Constants.\n\tPattern A(Push);\n\tPattern B(Push);\n\tPattern C(Push);\n\t// Anything.\n\tPattern W;\n\tPattern X;\n\tPattern Y;\n\tPattern Z;\n\tA.setMatchGroup(1, m_matchGroups);\n\tB.setMatchGroup(2, m_matchGroups);\n\tC.setMatchGroup(3, m_matchGroups);\n\tW.setMatchGroup(4, m_matchGroups);\n\tX.setMatchGroup(5, m_matchGroups);\n\tY.setMatchGroup(6, m_matchGroups);\n\tZ.setMatchGroup(7, m_matchGroups);\n\n\taddRules(simplificationRuleList(std::nullopt, A, B, C, W, X, Y, Z));\n\tassertThrow(isInitialized(), OptimizerException, \"Rule list not properly initialized.\");\n}\n\nPattern::Pattern(Instruction _instruction, std::initializer_list<Pattern> _arguments):\n\tm_type(Operation),\n\tm_instruction(_instruction),\n\tm_arguments(_arguments)\n{\n}\n\nvoid Pattern::setMatchGroup(unsigned _group, std::map<unsigned, Expression const*>& _matchGroups)\n{\n\tm_matchGroup = _group;\n\tm_matchGroups = &_matchGroups;\n}\n\nbool Pattern::matches(Expression const& _expr, ExpressionClasses const& _classes) const\n{\n\tif (!matchesBaseItem(_expr.item))\n\t\treturn false;\n\tif (m_matchGroup)\n\t{\n\t\tif (!m_matchGroups->count(m_matchGroup))\n\t\t\t(*m_matchGroups)[m_matchGroup] = &_expr;\n\t\telse if ((*m_matchGroups)[m_matchGroup]->id != _expr.id)\n\t\t\treturn false;\n\t}\n\tassertThrow(m_arguments.size() == 0 || _expr.arguments.size() == m_arguments.size(), OptimizerException, \"\");\n\tfor (size_t i = 0; i < m_arguments.size(); ++i)\n\t\tif (!m_arguments[i].matches(_classes.representative(_expr.arguments[i]), _classes))\n\t\t\treturn false;\n\treturn true;\n}\n\nAssemblyItem Pattern::toAssemblyItem(langutil::DebugData::ConstPtr _debugData) const\n{\n\tif (m_type == Operation)\n\t\treturn AssemblyItem(m_instruction, std::move(_debugData));\n\telse\n\t\treturn AssemblyItem(m_type, data(), std::move(_debugData));\n}\n\nstd::string Pattern::toString() const\n{\n\tstd::stringstream s;\n\tswitch (m_type)\n\t{\n\tcase Operation:\n\t\t// Note: This function is exclusively used for debugging.\n\t\ts << instructionInfo(m_instruction, EVMVersion()).name;\n\t\tbreak;\n\tcase Push:\n\t\tif (m_data)\n\t\t\ts << \"PUSH \" << std::hex << data();\n\t\telse\n\t\t\ts << \"PUSH \";\n\t\tbreak;\n\tcase UndefinedItem:\n\t\ts << \"ANY\";\n\t\tbreak;\n\tdefault:\n\t\tif (m_data)\n\t\t\ts << \"t=\" << std::dec << m_type << \" d=\" << std::hex << data();\n\t\telse\n\t\t\ts << \"t=\" << std::dec << m_type << \" d: nullptr\";\n\t\tbreak;\n\t}\n\tif (!m_requireDataMatch)\n\t\ts << \" ~\";\n\tif (m_matchGroup)\n\t\ts << \"[\" << std::dec << m_matchGroup << \"]\";\n\ts << \"(\";\n\tfor (Pattern const& p: m_arguments)\n\t\ts << p.toString() << \", \";\n\ts << \")\";\n\treturn s.str();\n}\n\nbool Pattern::matchesBaseItem(AssemblyItem const* _item) const\n{\n\tif (m_type == UndefinedItem)\n\t\treturn true;\n\tif (!_item)\n\t\treturn false;\n\tif (m_type != _item->type())\n\t\treturn false;\n\telse if (m_type == Operation)\n\t\treturn m_instruction == _item->instruction();\n\telse if (m_requireDataMatch)\n\t\treturn data() == _item->data();\n\treturn true;\n}\n\nPattern::Expression const& Pattern::matchGroupValue() const\n{\n\tassertThrow(m_matchGroup > 0, OptimizerException, \"\");\n\tassertThrow(!!m_matchGroups, OptimizerException, \"\");\n\tassertThrow((*m_matchGroups)[m_matchGroup], OptimizerException, \"\");\n\treturn *(*m_matchGroups)[m_matchGroup];\n}\n\nu256 const& Pattern::data() const\n{\n\tassertThrow(m_data, OptimizerException, \"\");\n\treturn *m_data;\n}\n\nExpressionTemplate::ExpressionTemplate(Pattern const& _pattern, langutil::DebugData::ConstPtr const& _debugData)\n{\n\tif (_pattern.matchGroup())\n\t{\n\t\thasId = true;\n\t\tid = _pattern.id();\n\t}\n\telse\n\t{\n\t\thasId = false;\n\t\titem = _pattern.toAssemblyItem(_debugData);\n\t}\n\tfor (auto const& arg: _pattern.arguments())\n\t\targuments.emplace_back(arg, _debugData);\n}\n\nstd::string ExpressionTemplate::toString() const\n{\n\tstd::stringstream s;\n\tif (hasId)\n\t\ts << id;\n\telse\n\t\ts << item;\n\ts << \"(\";\n\tfor (auto const& arg: arguments)\n\t\ts << arg.toString();\n\ts << \")\";\n\treturn s.str();\n}\n"
  },
  {
    "path": "libevmasm/SimplificationRules.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file SimplificationRules\n * @author Christian <chris@ethereum.org>\n * @date 2017\n * Module for applying replacement rules against Expressions.\n */\n\n#pragma once\n\n#include <libevmasm/ExpressionClasses.h>\n#include <libevmasm/SimplificationRule.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <functional>\n#include <vector>\n\nnamespace solidity::langutil\n{\nstruct SourceLocation;\n}\n\nnamespace solidity::evmasm\n{\n\nclass Pattern;\n\n/**\n * Container for all simplification rules.\n */\nclass Rules\n{\npublic:\n\t/// Noncopyable.\n\tRules(Rules const&) = delete;\n\tRules& operator=(Rules const&) = delete;\n\n\tusing Expression = ExpressionClasses::Expression;\n\n\tRules();\n\n\t/// @returns a pointer to the first matching pattern and sets the match\n\t/// groups accordingly.\n\tSimplificationRule<Pattern> const* findFirstMatch(\n\t\tExpression const& _expr,\n\t\tExpressionClasses const& _classes\n\t);\n\n\t/// Checks whether the rulelist is non-empty. This is usually enforced\n\t/// by the constructor, but we had some issues with static initialization.\n\tbool isInitialized() const;\n\nprivate:\n\tvoid addRules(std::vector<SimplificationRule<Pattern>> const& _rules);\n\tvoid addRule(SimplificationRule<Pattern> const& _rule);\n\n\tvoid resetMatchGroups() { m_matchGroups.clear(); }\n\n\tstd::map<unsigned, Expression const*> m_matchGroups;\n\t/// Pattern to match, replacement to be applied and flag indicating whether\n\t/// the replacement might remove some elements (except constants).\n\tstd::vector<SimplificationRule<Pattern>> m_rules[256];\n};\n\n/**\n * Pattern to match against an expression.\n * Also stores matched expressions to retrieve them later, for constructing new expressions using\n * ExpressionTemplate.\n */\nclass Pattern\n{\npublic:\n\tusing Expression = ExpressionClasses::Expression;\n\tusing Id = ExpressionClasses::Id;\n\n\tusing Builtins = evmasm::EVMBuiltins<Pattern>;\n\tstatic constexpr size_t WordSize = 256;\n\tusing Word = u256;\n\n\t// Matches a specific constant value.\n\tPattern(unsigned _value): Pattern(u256(_value)) {}\n\tPattern(int _value): Pattern(u256(_value)) {}\n\tPattern(long unsigned _value): Pattern(u256(_value)) {}\n\t// Matches a specific constant value.\n\tPattern(u256 const& _value): m_type(Push), m_requireDataMatch(true), m_data(std::make_shared<u256>(_value)) {}\n\t// Matches a specific assembly item type or anything if not given.\n\tPattern(AssemblyItemType _type = UndefinedItem): m_type(_type) {}\n\t// Matches a given instruction with given arguments\n\tPattern(Instruction _instruction, std::initializer_list<Pattern> _arguments = {});\n\t/// Sets this pattern to be part of the match group with the identifier @a _group.\n\t/// Inside one rule, all patterns in the same match group have to match expressions from the\n\t/// same expression equivalence class.\n\tvoid setMatchGroup(unsigned _group, std::map<unsigned, Expression const*>& _matchGroups);\n\tunsigned matchGroup() const { return m_matchGroup; }\n\tbool matches(Expression const& _expr, ExpressionClasses const& _classes) const;\n\n\tAssemblyItem toAssemblyItem(langutil::DebugData::ConstPtr _debugData) const;\n\tstd::vector<Pattern> arguments() const { return m_arguments; }\n\n\t/// @returns the id of the matched expression if this pattern is part of a match group.\n\tId id() const { return matchGroupValue().id; }\n\t/// @returns the data of the matched expression if this pattern is part of a match group.\n\tu256 const& d() const { return matchGroupValue().item->data(); }\n\n\tstd::string toString() const;\n\n\tAssemblyItemType type() const { return m_type; }\n\tInstruction instruction() const\n\t{\n\t\tassertThrow(type() == Operation, OptimizerException, \"\");\n\t\treturn m_instruction;\n\t}\n\nprivate:\n\tbool matchesBaseItem(AssemblyItem const* _item) const;\n\tExpression const& matchGroupValue() const;\n\tu256 const& data() const;\n\n\tAssemblyItemType m_type;\n\tbool m_requireDataMatch = false;\n\tInstruction m_instruction; ///< Only valid if m_type is Operation\n\tstd::shared_ptr<u256> m_data; ///< Only valid if m_type is not Operation\n\tstd::vector<Pattern> m_arguments;\n\tunsigned m_matchGroup = 0;\n\tstd::map<unsigned, Expression const*>* m_matchGroups = nullptr;\n};\n\n/**\n * Template for a new expression that can be built from matched patterns.\n */\nstruct ExpressionTemplate\n{\n\tusing Expression = ExpressionClasses::Expression;\n\tusing Id = ExpressionClasses::Id;\n\texplicit ExpressionTemplate(Pattern const& _pattern, langutil::DebugData::ConstPtr const& _debugData);\n\tstd::string toString() const;\n\tbool hasId = false;\n\t/// Id of the matched expression, if available.\n\tId id = Id(-1);\n\t// Otherwise, assembly item.\n\tAssemblyItem item = UndefinedItem;\n\tstd::vector<ExpressionTemplate> arguments;\n};\n\n}\n"
  },
  {
    "path": "libevmasm/SubAssemblyID.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/Numeric.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <compare>\n#include <cstddef>\n#include <cstdint>\n#include <limits>\n\nnamespace solidity::evmasm\n{\n\n/// Sub assembly ID representing class. Based on fixed-size 64-bit unsigned int.\n/// An empty / root state is reflected by a value that is set to max and can be queried via the `empty()` member\n/// function.\nstruct SubAssemblyID\n{\n\tusing ValueType = uint64_t;\n\tSubAssemblyID() = default;\n\tSubAssemblyID(ValueType const _value): value(_value) {}\n\texplicit SubAssemblyID(u256 const& _data)\n\t{\n\t\tsolAssert(_data <= std::numeric_limits<ValueType>::max());\n\t\tvalue = static_cast<ValueType>(_data);\n\t}\n\n\tsize_t asIndex() const\n\t{\n\t\tif constexpr(sizeof(ValueType) > sizeof(size_t))\n\t\t{\n\t\t\tsolAssert(value < std::numeric_limits<size_t>::max());\n\t\t\treturn static_cast<size_t>(value);\n\t\t}\n\t\treturn value;\n\t}\n\tbool empty() const { return value == std::numeric_limits<ValueType>::max(); }\n\tauto operator<=>(SubAssemblyID const&) const = default;\n\n\tValueType value = std::numeric_limits<ValueType>::max();\n};\n\n}\n"
  },
  {
    "path": "liblangutil/CMakeLists.txt",
    "content": "# Solidity Commons Library (Solidity related sharing bits between libsolidity and libyul)\nset(sources\n\tCommon.h\n\tCharStream.cpp\n\tCharStream.h\n\tDebugData.h\n\tDebugInfoSelection.cpp\n\tDebugInfoSelection.h\n\tErrorReporter.cpp\n\tErrorReporter.h\n\tEVMVersion.h\n\tEVMVersion.cpp\n\tExceptions.cpp\n\tExceptions.h\n\tParserBase.cpp\n\tParserBase.h\n\tScanner.cpp\n\tScanner.h\n\tCharStreamProvider.h\n\tSemVerHandler.cpp\n\tSemVerHandler.h\n\tSourceLocation.h\n\tSourceLocation.cpp\n\tSourceReferenceExtractor.cpp\n\tSourceReferenceExtractor.h\n\tSourceReferenceFormatter.cpp\n\tSourceReferenceFormatter.h\n\tToken.cpp\n\tToken.h\n\tUniqueErrorReporter.h\n)\n\nadd_library(langutil ${sources})\ntarget_link_libraries(langutil PUBLIC solutil fmt::fmt-header-only)\n"
  },
  {
    "path": "liblangutil/CharStream.cpp",
    "content": "/*\n * This file is part of solidity.\n *\n * solidity is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * solidity is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with solidity.  If not, see <http://www.gnu.org/licenses/>.\n *\n * This file is derived from the file \"scanner.cc\", which was part of the\n * V8 project. The original copyright header follows:\n *\n * Copyright 2006-2012, the V8 project authors. All rights reserved.\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * * Neither the name of Google Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n/**\n * Character stream / input file.\n */\n\n#include <liblangutil/CharStream.h>\n#include <liblangutil/Exceptions.h>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\n\nchar CharStream::advanceAndGet(size_t _chars)\n{\n\tif (isPastEndOfInput())\n\t\treturn 0;\n\tm_position += _chars;\n\tif (isPastEndOfInput())\n\t\treturn 0;\n\treturn m_source[m_position];\n}\n\nchar CharStream::rollback(size_t _amount)\n{\n\tsolAssert(m_position >= _amount, \"\");\n\tm_position -= _amount;\n\treturn get();\n}\n\nchar CharStream::setPosition(size_t _location)\n{\n\tsolAssert(_location <= m_source.size(), \"Attempting to set position past end of source.\");\n\tm_position = _location;\n\treturn get();\n}\n\nstd::string CharStream::lineAtPosition(int _position) const\n{\n\t// if _position points to \\n, it returns the line before the \\n\n\tusing size_type = std::string::size_type;\n\tsize_type searchStart = std::min<size_type>(m_source.size(), size_type(_position));\n\tif (searchStart > 0)\n\t\tsearchStart--;\n\tsize_type lineStart = m_source.rfind('\\n', searchStart);\n\tif (lineStart == std::string::npos)\n\t\tlineStart = 0;\n\telse\n\t\tlineStart++;\n\tstd::string line = m_source.substr(\n\t\tlineStart,\n\t\tstd::min(m_source.find('\\n', lineStart), m_source.size()) - lineStart\n\t);\n\tif (!line.empty() && line.back() == '\\r')\n\t\tline.pop_back();\n\treturn line;\n}\n\nLineColumn CharStream::translatePositionToLineColumn(int _position) const\n{\n\tusing size_type = std::string::size_type;\n\tusing diff_type = std::string::difference_type;\n\tsize_type searchPosition = std::min<size_type>(m_source.size(), size_type(_position));\n\tint lineNumber = static_cast<int>(count(m_source.begin(), m_source.begin() + diff_type(searchPosition), '\\n'));\n\tsize_type lineStart;\n\tif (searchPosition == 0)\n\t\tlineStart = 0;\n\telse\n\t{\n\t\tlineStart = m_source.rfind('\\n', searchPosition - 1);\n\t\tlineStart = lineStart == std::string::npos ? 0 : lineStart + 1;\n\t}\n\treturn LineColumn{lineNumber, static_cast<int>(searchPosition - lineStart)};\n}\n\nstd::string_view CharStream::text(SourceLocation const& _location) const\n{\n\tif (!_location.hasText())\n\t\treturn {};\n\tsolAssert(_location.sourceName && *_location.sourceName == m_name, \"\");\n\tsolAssert(static_cast<size_t>(_location.end) <= m_source.size(), \"\");\n\treturn std::string_view{m_source}.substr(\n\t\tstatic_cast<size_t>(_location.start),\n\t\tstatic_cast<size_t>(_location.end - _location.start)\n\t);\n}\n\nstd::string CharStream::singleLineSnippet(std::string const& _sourceCode, SourceLocation const& _location)\n{\n\tif (!_location.hasText())\n\t\treturn {};\n\n\tif (static_cast<size_t>(_location.start) >= _sourceCode.size())\n\t\treturn {};\n\n\tstd::string cut = _sourceCode.substr(static_cast<size_t>(_location.start), static_cast<size_t>(_location.end - _location.start));\n\tauto newLinePos = cut.find_first_of(\"\\n\\r\");\n\tif (newLinePos != std::string::npos)\n\t\tcut = cut.substr(0, newLinePos) + \"...\";\n\n\treturn cut;\n}\n\nstd::optional<int> CharStream::translateLineColumnToPosition(LineColumn const& _lineColumn) const\n{\n\treturn translateLineColumnToPosition(m_source, _lineColumn);\n}\n\nstd::optional<int> CharStream::translateLineColumnToPosition(std::string const& _text, LineColumn const& _input)\n{\n\tif (_input.line < 0)\n\t\treturn std::nullopt;\n\n\tsize_t offset = 0;\n\tfor (int i = 0; i < _input.line; i++)\n\t{\n\t\toffset = _text.find('\\n', offset);\n\t\tif (offset == _text.npos)\n\t\t\treturn std::nullopt;\n\t\toffset++; // Skip linefeed.\n\t}\n\n\tsize_t endOfLine = _text.find('\\n', offset);\n\tif (endOfLine == std::string::npos)\n\t\tendOfLine = _text.size();\n\n\tif (offset + static_cast<size_t>(_input.column) > endOfLine)\n\t\treturn std::nullopt;\n\treturn offset + static_cast<size_t>(_input.column);\n}\n\n"
  },
  {
    "path": "liblangutil/CharStream.h",
    "content": "/*\n * This file is part of solidity.\n *\n * solidity is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * solidity is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with solidity.  If not, see <http://www.gnu.org/licenses/>.\n *\n * This file is derived from the file \"scanner.h\", which was part of the\n * V8 project. The original copyright header follows:\n *\n * Copyright 2006-2012, the V8 project authors. All rights reserved.\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * * Neither the name of Google Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n/**\n * Character stream / input file.\n */\n\n#pragma once\n\n#include <cstdint>\n#include <optional>\n#include <string>\n#include <tuple>\n#include <utility>\n\nnamespace solidity::langutil\n{\n\nstruct SourceLocation;\nstruct LineColumn;\n\n/**\n * Bidirectional stream of characters.\n *\n * This CharStream is used by lexical analyzers as the source.\n */\nclass CharStream\n{\npublic:\n\tCharStream() = default;\n\tCharStream(std::string _source, std::string _name):\n\t\tm_source(std::move(_source)), m_name(std::move(_name)) {}\n\tCharStream(std::string _source, std::string _name, bool _importedFromAST):\n\t\tm_source(std::move(_source)),\n\t\tm_name(std::move(_name)),\n\t\tm_importedFromAST(_importedFromAST)\n\t{ }\n\n\tsize_t position() const { return m_position; }\n\tbool isPastEndOfInput(size_t _charsForward = 0) const { return (m_position + _charsForward) >= m_source.size(); }\n\tbool isImportedFromAST() const { return m_importedFromAST; }\n\n\tchar get(size_t _charsForward = 0) const { return m_source[m_position + _charsForward]; }\n\tchar advanceAndGet(size_t _chars = 1);\n\t/// Sets scanner position to @ _amount characters backwards in source text.\n\t/// @returns The character of the current location after update is returned.\n\tchar rollback(size_t _amount);\n\t/// Sets scanner position to @ _location if it refers a valid offset in m_source.\n\t/// If not, nothing is done.\n\t/// @returns The character of the current location after update is returned.\n\tchar setPosition(size_t _location);\n\n\tvoid reset() { m_position = 0; }\n\n\tstd::string const& source() const noexcept { return m_source; }\n\tstd::string const& name() const noexcept { return m_name; }\n\n\tsize_t size() const { return m_source.size(); }\n\n\t///@{\n\t///@name Error printing helper functions\n\t/// Functions that help pretty-printing parse errors\n\t/// Do only use in error cases, they are quite expensive.\n\tstd::string lineAtPosition(int _position) const;\n\tLineColumn translatePositionToLineColumn(int _position) const;\n\t///@}\n\n\t/// Translates a line:column to the absolute position.\n\tstd::optional<int> translateLineColumnToPosition(LineColumn const& _lineColumn) const;\n\n\t/// Translates a line:column to the absolute position for the given input text.\n\tstatic std::optional<int> translateLineColumnToPosition(std::string const& _text, LineColumn const& _input);\n\n\t/// Tests whether or not given octet sequence is present at the current position in stream.\n\t/// @returns true if the sequence could be found, false otherwise.\n\tbool prefixMatch(std::string_view _sequence)\n\t{\n\t\tif (isPastEndOfInput(_sequence.size()))\n\t\t\treturn false;\n\n\t\tfor (size_t i = 0; i < _sequence.size(); ++i)\n\t\t\tif (_sequence[i] != get(i))\n\t\t\t\treturn false;\n\n\t\treturn true;\n\t}\n\n\t/// @returns the substring of the source that the source location references.\n\t/// Returns an empty string view if the source location does not `hasText()`.\n\tstd::string_view text(SourceLocation const& _location) const;\n\n\t/// @returns the first line of the referenced source fragment. If the fragment is longer than\n\t/// one line, appends an ellipsis to indicate that.\n\tstd::string singleLineSnippet(SourceLocation const& _location) const\n\t{\n\t\treturn singleLineSnippet(m_source, _location);\n\t}\n\n\tstatic std::string singleLineSnippet(std::string const& _sourceCode, SourceLocation const& _location);\n\nprivate:\n\tstd::string m_source;\n\tstd::string m_name;\n\tbool m_importedFromAST{false};\n\tsize_t m_position{0};\n};\n\n}\n"
  },
  {
    "path": "liblangutil/CharStreamProvider.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Interface to retrieve the character stream by a source name.\n */\n\n#pragma once\n\n#include <liblangutil/CharStream.h>\n#include <liblangutil/Exceptions.h>\n\n#include <string>\n\nnamespace solidity::langutil\n{\n\n/**\n * Interface to retrieve a CharStream (source) from a source name.\n * Used especially for printing error information.\n */\nclass CharStreamProvider\n{\npublic:\n\tvirtual ~CharStreamProvider() = default;\n\tvirtual CharStream const& charStream(std::string const& _sourceName) const = 0;\n};\n\nclass SingletonCharStreamProvider: public CharStreamProvider\n{\npublic:\n\texplicit SingletonCharStreamProvider(CharStream const& _charStream):\n\t\tm_charStream(_charStream) {}\n\tCharStream const& charStream(std::string const& _sourceName) const override\n\t{\n\t\tsolAssert(m_charStream.name() == _sourceName, \"\");\n\t\treturn m_charStream;\n\t}\nprivate:\n\tCharStream const& m_charStream;\n};\n\n}\n"
  },
  {
    "path": "liblangutil/Common.h",
    "content": "/*\n\tThis file is part of solidity.\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#pragma once\n\nnamespace solidity::langutil\n{\n\ninline bool isDecimalDigit(char c)\n{\n\treturn '0' <= c && c <= '9';\n}\n\ninline bool isHexDigit(char c)\n{\n\treturn\n\t\tisDecimalDigit(c) ||\n\t\t('a' <= c && c <= 'f') ||\n\t\t('A' <= c && c <= 'F');\n}\n\ninline bool isWhiteSpace(char c)\n{\n\treturn c == ' ' || c == '\\n' || c == '\\t' || c == '\\r';\n}\n\ninline bool isIdentifierStart(char c)\n{\n\treturn c == '_' || c == '$' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');\n}\n\ninline bool isIdentifierPart(char c)\n{\n\treturn isIdentifierStart(c) || isDecimalDigit(c);\n}\n\ninline int hexValue(char c)\n{\n\tif (c >= '0' && c <= '9')\n\t\treturn c - '0';\n\telse if (c >= 'a' && c <= 'f')\n\t\treturn c - 'a' + 10;\n\telse if (c >= 'A' && c <= 'F')\n\t\treturn c - 'A' + 10;\n\telse return -1;\n}\n}\n"
  },
  {
    "path": "liblangutil/DebugData.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <liblangutil/SourceLocation.h>\n#include <optional>\n#include <memory>\n\nnamespace solidity::langutil\n{\n\nstruct DebugData\n{\n\ttypedef typename std::shared_ptr<DebugData const> ConstPtr;\n\n\texplicit DebugData(\n\t\tlangutil::SourceLocation _nativeLocation = {},\n\t\tlangutil::SourceLocation _originLocation = {},\n\t\tstd::optional<int64_t> _astID = {}\n\t):\n\t\tnativeLocation(std::move(_nativeLocation)),\n\t\toriginLocation(std::move(_originLocation)),\n\t\tastID(_astID)\n\t{}\n\n\tstatic DebugData::ConstPtr create(\n\t\tlangutil::SourceLocation _nativeLocation,\n\t\tlangutil::SourceLocation _originLocation = {},\n\t\tstd::optional<int64_t> _astID = {}\n\t)\n\t{\n\t\treturn std::make_shared<DebugData>(\n\t\t\tstd::move(_nativeLocation),\n\t\t\tstd::move(_originLocation),\n\t\t\t_astID\n\t\t);\n\t}\n\n\tstatic DebugData::ConstPtr create()\n\t{\n\t\tstatic DebugData::ConstPtr emptyDebugData = create({});\n\t\treturn emptyDebugData;\n\t}\n\n\t/// Location in the Yul code.\n\tlangutil::SourceLocation nativeLocation;\n\t/// Location in the original source that the Yul code was produced from.\n\t/// Optional. Only present if the Yul source contains location annotations.\n\tlangutil::SourceLocation originLocation;\n\t/// ID in the (Solidity) source AST.\n\tstd::optional<int64_t> astID;\n};\n\n} // namespace solidity::langutil\n"
  },
  {
    "path": "liblangutil/DebugInfoSelection.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <liblangutil/DebugInfoSelection.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <libsolutil/StringUtils.h>\n\n#include <boost/algorithm/string/trim.hpp>\n\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/map.hpp>\n#include <range/v3/view/split.hpp>\n\n#include <vector>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\n\nDebugInfoSelection const DebugInfoSelection::All(bool _value) noexcept\n{\n\tDebugInfoSelection result;\n\tfor (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)\n\t\tresult.*member = _value;\n\treturn result;\n}\n\nDebugInfoSelection const DebugInfoSelection::Only(bool DebugInfoSelection::* _member) noexcept\n{\n\tDebugInfoSelection result{};\n\tresult.*_member = true;\n\treturn result;\n}\n\nDebugInfoSelection const DebugInfoSelection::AllExcept(std::vector<bool DebugInfoSelection::*> const& _members) noexcept\n{\n\tDebugInfoSelection result = All();\n\tfor (bool DebugInfoSelection::* member: _members)\n\t\tresult.*member = false;\n\treturn result;\n}\n\nstd::optional<DebugInfoSelection> DebugInfoSelection::fromString(std::string_view _input)\n{\n\t// TODO: Make more stuff constexpr and make it a static_assert().\n\tsolAssert(componentMap().count(\"all\") == 0, \"\");\n\tsolAssert(componentMap().count(\"none\") == 0, \"\");\n\n\tif (_input == \"all\")\n\t\treturn AllExceptExperimental();\n\tif (_input == \"none\")\n\t\treturn None();\n\n\treturn fromComponents(_input | ranges::views::split(',') | ranges::to<std::vector<std::string>>);\n}\n\nstd::optional<DebugInfoSelection> DebugInfoSelection::fromComponents(\n\tstd::vector<std::string> const& _componentNames,\n\tbool _acceptWildcards\n)\n{\n\tsolAssert(componentMap().count(\"*\") == 0, \"\");\n\n\tDebugInfoSelection selection;\n\tfor (auto const& component: _componentNames)\n\t{\n\t\tif (component == \"*\")\n\t\t\treturn (_acceptWildcards ? std::make_optional(AllExceptExperimental()) : std::nullopt);\n\n\t\tif (!selection.enable(component))\n\t\t\treturn std::nullopt;\n\t}\n\n\treturn selection;\n}\n\nbool DebugInfoSelection::enable(std::string const& _component)\n{\n\tauto memberIt = componentMap().find(boost::trim_copy(_component));\n\tif (memberIt == componentMap().end())\n\t\treturn false;\n\n\tthis->*(memberIt->second) = true;\n\treturn true;\n}\n\nbool DebugInfoSelection::any() const noexcept\n{\n\tfor (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)\n\t\tif (this->*member)\n\t\t\treturn true;\n\n\treturn false;\n}\n\nbool DebugInfoSelection::all() const noexcept\n{\n\tfor (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)\n\t\tif (!(this->*member))\n\t\t\treturn false;\n\n\treturn true;\n}\n\nDebugInfoSelection& DebugInfoSelection::operator&=(DebugInfoSelection const& _other)\n{\n\tfor (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)\n\t\tthis->*member &= _other.*member;\n\treturn *this;\n}\n\nDebugInfoSelection& DebugInfoSelection::operator|=(DebugInfoSelection const& _other)\n{\n\tfor (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)\n\t\tthis->*member |= _other.*member;\n\treturn *this;\n}\n\nDebugInfoSelection DebugInfoSelection::operator&(DebugInfoSelection _other) const noexcept\n{\n\t_other &= *this;\n\treturn _other;\n}\n\nDebugInfoSelection DebugInfoSelection::operator|(DebugInfoSelection _other) const noexcept\n{\n\t_other |= *this;\n\treturn _other;\n}\n\nbool DebugInfoSelection::operator==(DebugInfoSelection const& _other) const noexcept\n{\n\tfor (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)\n\t\tif (this->*member != _other.*member)\n\t\t\treturn false;\n\treturn true;\n}\n\nstd::ostream& langutil::operator<<(std::ostream& _stream, DebugInfoSelection const& _selection)\n{\n\tstd::vector<std::string> selectedComponentNames;\n\tfor (auto const& [name, member]: _selection.componentMap())\n\t\tif (_selection.*member)\n\t\t\tselectedComponentNames.push_back(name);\n\n\treturn _stream << joinHumanReadable(selectedComponentNames, \",\");\n}\n"
  },
  {
    "path": "liblangutil/DebugInfoSelection.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Handles selections of debug info components.\n */\n\n#pragma once\n\n#include <map>\n#include <optional>\n#include <ostream>\n#include <string>\n#include <string_view>\n#include <vector>\n\nnamespace solidity::langutil\n{\n\n/**\n * Represents a set of flags corresponding to components of debug info selected for some purpose.\n *\n * Provides extra functionality for enumerating the components and serializing/deserializing the\n * selection to/from a comma-separated string.\n */\nstruct DebugInfoSelection\n{\n\tstatic DebugInfoSelection const All(bool _value = true) noexcept;\n\tstatic DebugInfoSelection const None() noexcept { return All(false); }\n\tstatic DebugInfoSelection const Only(bool DebugInfoSelection::* _member) noexcept;\n\tstatic DebugInfoSelection const Default() noexcept { return AllExceptExperimental(); }\n\tstatic DebugInfoSelection const AllExcept(std::vector<bool DebugInfoSelection::*> const& _members) noexcept;\n\tstatic DebugInfoSelection const AllExceptExperimental() noexcept { return AllExcept({&DebugInfoSelection::ethdebug}); }\n\n\tstatic std::optional<DebugInfoSelection> fromString(std::string_view _input);\n\tstatic std::optional<DebugInfoSelection> fromComponents(\n\t\tstd::vector<std::string> const& _componentNames,\n\t\tbool _acceptWildcards = false\n\t);\n\tbool enable(std::string const& _component);\n\n\tbool all() const noexcept;\n\tbool any() const noexcept;\n\tbool none() const noexcept { return !any(); }\n\tbool only(bool DebugInfoSelection::* _member) const noexcept { return *this == Only(_member); }\n\n\tDebugInfoSelection& operator&=(DebugInfoSelection const& _other);\n\tDebugInfoSelection& operator|=(DebugInfoSelection const& _other);\n\tDebugInfoSelection operator&(DebugInfoSelection _other) const noexcept;\n\tDebugInfoSelection operator|(DebugInfoSelection _other) const noexcept;\n\n\tbool operator!=(DebugInfoSelection const& _other) const noexcept { return !(*this == _other); }\n\tbool operator==(DebugInfoSelection const& _other) const noexcept;\n\n\tfriend std::ostream& operator<<(std::ostream& _stream, DebugInfoSelection const& _selection);\n\n\tstatic auto const& componentMap()\n\t{\n\t\tstatic std::map<std::string, bool DebugInfoSelection::*> const components = {\n\t\t\t{\"location\", &DebugInfoSelection::location},\n\t\t\t{\"snippet\", &DebugInfoSelection::snippet},\n\t\t\t{\"ast-id\", &DebugInfoSelection::astID},\n\t\t\t{\"ethdebug\", &DebugInfoSelection::ethdebug},\n\t\t};\n\t\treturn components;\n\t}\n\n\tstd::vector<std::string> selectedNames() const\n\t{\n\t\tstd::vector<std::string> result;\n\t\tfor (auto const& component: componentMap())\n\t\t\tif (this->*(component.second))\n\t\t\t\tresult.push_back(component.first);\n\t\treturn result;\n\t}\n\n\tbool location = false; ///< Include source location. E.g. `@src 3:50:100`\n\tbool snippet = false;  ///< Include source code snippet next to location. E.g. `@src 3:50:100 \"contract C {...\"`\n\tbool astID = false;    ///< Include ID of the Solidity AST node. E.g. `@ast-id 15`\n\tbool ethdebug = false; ///< Include ethdebug related debug information.\n};\n\nstd::ostream& operator<<(std::ostream& _stream, DebugInfoSelection const& _selection);\n\n}\n"
  },
  {
    "path": "liblangutil/EVMVersion.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * EVM versioning.\n */\n\n#include <liblangutil/EVMVersion.h>\n#include <libevmasm/Instruction.h>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::langutil;\n\nbool EVMVersion::hasOpcode(Instruction _opcode, std::optional<uint8_t> _eofVersion) const\n{\n\t// EOF version can be only defined since osaka\n\tassert(!_eofVersion.has_value() || *this >= EVMVersion::firstWithEOF());\n\n\tswitch (_opcode)\n\t{\n\tcase Instruction::RETURNDATACOPY:\n\tcase Instruction::RETURNDATASIZE:\n\t\treturn supportsReturndata();\n\tcase Instruction::STATICCALL:\n\t\treturn !_eofVersion.has_value() && hasStaticCall();\n\tcase Instruction::SHL:\n\tcase Instruction::SHR:\n\tcase Instruction::SAR:\n\t\treturn hasBitwiseShifting();\n\tcase Instruction::CLZ:\n\t\treturn hasCLZ();\n\tcase Instruction::CREATE2:\n\t\treturn !_eofVersion.has_value() && hasCreate2();\n\tcase Instruction::EXTCODEHASH:\n\t\treturn !_eofVersion.has_value() && hasExtCodeHash();\n\tcase Instruction::CHAINID:\n\t\treturn hasChainID();\n\tcase Instruction::SELFBALANCE:\n\t\treturn hasSelfBalance();\n\tcase Instruction::BASEFEE:\n\t\treturn hasBaseFee();\n\tcase Instruction::BLOBHASH:\n\t\treturn hasBlobHash();\n\tcase Instruction::BLOBBASEFEE:\n\t\treturn hasBlobBaseFee();\n\tcase Instruction::MCOPY:\n\t\treturn hasMcopy();\n\tcase Instruction::TSTORE:\n\tcase Instruction::TLOAD:\n\t\treturn supportsTransientStorage();\n\t// Instructions below are deprecated in EOF\n\tcase Instruction::CALL:\n\tcase Instruction::CALLCODE:\n\tcase Instruction::DELEGATECALL:\n\tcase Instruction::SELFDESTRUCT:\n\tcase Instruction::JUMP:\n\tcase Instruction::JUMPI:\n\tcase Instruction::PC:\n\tcase Instruction::CREATE:\n\tcase Instruction::CODESIZE:\n\tcase Instruction::CODECOPY:\n\tcase Instruction::EXTCODESIZE:\n\tcase Instruction::EXTCODECOPY:\n\tcase Instruction::GAS:\n\t\treturn !_eofVersion.has_value();\n\t// Instructions below available only in EOF\n\tcase Instruction::EOFCREATE:\n\tcase Instruction::RETURNCONTRACT:\n\tcase Instruction::DATALOADN:\n\tcase Instruction::RJUMP:\n\tcase Instruction::RJUMPI:\n\tcase Instruction::CALLF:\n\tcase Instruction::JUMPF:\n\tcase Instruction::DUPN:\n\tcase Instruction::SWAPN:\n\tcase Instruction::RETF:\n\tcase Instruction::EXTCALL:\n\tcase Instruction::EXTSTATICCALL:\n\tcase Instruction::EXTDELEGATECALL:\n\t\treturn _eofVersion.has_value();\n\tdefault:\n\t\treturn true;\n\t}\n}\n"
  },
  {
    "path": "liblangutil/EVMVersion.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * EVM versioning.\n */\n\n#pragma once\n\n#include <libsolutil/Assertions.h>\n\n#include <array>\n#include <cstddef>\n#include <cstdint>\n#include <optional>\n#include <string>\n\n\nnamespace solidity::evmasm\n{\n/// Virtual machine bytecode instruction. Forward declared from libevmasm/Instruction.h\nenum class Instruction: uint8_t;\n}\n\nnamespace solidity::langutil\n{\n\n/**\n * A version specifier of the EVM we want to compile to.\n * Defaults to the latest version deployed on Ethereum Mainnet at the time of compiler release.\n */\nclass EVMVersion\n{\npublic:\n\tEVMVersion() = default;\n\n\tstatic EVMVersion current() { return {currentVersion}; }\n\n\tstatic EVMVersion constexpr homestead() { return {Version::Homestead}; }\n\tstatic EVMVersion constexpr tangerineWhistle() { return {Version::TangerineWhistle}; }\n\tstatic EVMVersion constexpr spuriousDragon() { return {Version::SpuriousDragon}; }\n\tstatic EVMVersion constexpr byzantium() { return {Version::Byzantium}; }\n\tstatic EVMVersion constexpr constantinople() { return {Version::Constantinople}; }\n\tstatic EVMVersion constexpr petersburg() { return {Version::Petersburg}; }\n\tstatic EVMVersion constexpr istanbul() { return {Version::Istanbul}; }\n\tstatic EVMVersion constexpr berlin() { return {Version::Berlin}; }\n\tstatic EVMVersion constexpr london() { return {Version::London}; }\n\tstatic EVMVersion constexpr paris() { return {Version::Paris}; }\n\tstatic EVMVersion constexpr shanghai() { return {Version::Shanghai}; }\n\tstatic EVMVersion constexpr cancun() { return {Version::Cancun}; }\n\tstatic EVMVersion constexpr prague() { return {Version::Prague}; }\n\tstatic EVMVersion constexpr osaka() { return {Version::Osaka}; }\n\n\tstatic auto constexpr allVersions() {\n\t\treturn std::array{\n\t\t\thomestead(),\n\t\t\ttangerineWhistle(),\n\t\t\tspuriousDragon(),\n\t\t\tbyzantium(),\n\t\t\tconstantinople(),\n\t\t\tpetersburg(),\n\t\t\tistanbul(),\n\t\t\tberlin(),\n\t\t\tlondon(),\n\t\t\tparis(),\n\t\t\tshanghai(),\n\t\t\tcancun(),\n\t\t\tprague(),\n\t\t\tosaka(),\n\t\t};\n\t}\n\n\tstatic auto constexpr allEOFVersions()\n\t{\n\t\treturn std::array{\n\t\t\tstd::optional<uint8_t>(),\n\t\t\tstd::make_optional<uint8_t>(1)\n\t\t};\n\t}\n\n\tstatic std::optional<EVMVersion> fromString(std::string const& _version)\n\t{\n\t\tfor (auto const& v: allVersions())\n\t\t\tif (_version == v.name())\n\t\t\t\treturn v;\n\t\treturn std::nullopt;\n\t}\n\n\tstatic EVMVersion firstWithEOF() { return {Version::Osaka}; }\n\n\tbool isExperimental() const {\n\t\treturn m_version > currentVersion;\n\t}\n\n\tauto operator<=>(EVMVersion const&) const = default;\n\n\tstd::string name() const\n\t{\n\t\tswitch (m_version)\n\t\t{\n\t\tcase Version::Homestead: return \"homestead\";\n\t\tcase Version::TangerineWhistle: return \"tangerineWhistle\";\n\t\tcase Version::SpuriousDragon: return \"spuriousDragon\";\n\t\tcase Version::Byzantium: return \"byzantium\";\n\t\tcase Version::Constantinople: return \"constantinople\";\n\t\tcase Version::Petersburg: return \"petersburg\";\n\t\tcase Version::Istanbul: return \"istanbul\";\n\t\tcase Version::Berlin: return \"berlin\";\n\t\tcase Version::London: return \"london\";\n\t\tcase Version::Paris: return \"paris\";\n\t\tcase Version::Shanghai: return \"shanghai\";\n\t\tcase Version::Cancun: return \"cancun\";\n\t\tcase Version::Prague: return \"prague\";\n\t\tcase Version::Osaka: return \"osaka\";\n\t\t}\n\t\tutil::unreachable();\n\t}\n\n\t/// Has the RETURNDATACOPY and RETURNDATASIZE opcodes.\n\tbool supportsReturndata() const { return *this >= byzantium(); }\n\tbool hasStaticCall() const { return *this >= byzantium(); }\n\tbool hasBitwiseShifting() const { return *this >= constantinople(); }\n\tbool hasCLZ() const { return *this >= osaka(); }\n\tbool hasCreate2() const { return *this >= constantinople(); }\n\tbool hasExtCodeHash() const { return *this >= constantinople(); }\n\tbool hasChainID() const { return *this >= istanbul(); }\n\tbool hasSelfBalance() const { return *this >= istanbul(); }\n\tbool hasBaseFee() const { return *this >= london(); }\n\tbool hasBlobBaseFee() const { return *this >= cancun(); }\n\tbool hasPrevRandao() const { return *this >= paris(); }\n\tbool hasPush0() const { return *this >= shanghai(); }\n\tbool hasBlobHash() const { return *this >= cancun(); }\n\tbool hasMcopy() const { return *this >= cancun(); }\n\tbool supportsTransientStorage() const { return *this >= cancun(); }\n\tbool supportsEOF() const { return *this >= firstWithEOF(); }\n\tconstexpr size_t reachableStackDepth() const { return 16; }\n\n\tbool hasOpcode(evmasm::Instruction _opcode, std::optional<uint8_t> _eofVersion) const;\n\n\t/// Whether we have to retain the costs for the call opcode itself (false),\n\t/// or whether we can just forward easily all remaining gas (true).\n\tbool canOverchargeGasForCall() const { return *this >= tangerineWhistle(); }\n\nprivate:\n\tenum class Version {\n\t\tHomestead,\n\t\tTangerineWhistle,\n\t\tSpuriousDragon,\n\t\tByzantium,\n\t\tConstantinople,\n\t\tPetersburg,\n\t\tIstanbul,\n\t\tBerlin,\n\t\tLondon,\n\t\tParis,\n\t\tShanghai,\n\t\tCancun,\n\t\tPrague,\n\t\tOsaka,\n\t};\n\tstatic auto constexpr currentVersion = Version::Osaka;\n\n\tconstexpr EVMVersion(Version _version): m_version(_version) {}\n\n\tVersion m_version = currentVersion;\n};\n\n}\n"
  },
  {
    "path": "liblangutil/ErrorReporter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Rhett <roadriverrail@gmail.com>\n * @date 2017\n * Error helper class.\n */\n\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/SourceLocation.h>\n\n#include <libsolutil/Exceptions.h>\n\n#include <range/v3/algorithm/find_if.hpp>\n#include <memory>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\n\nErrorReporter& ErrorReporter::operator=(ErrorReporter const& _errorReporter)\n{\n\tif (&_errorReporter == this)\n\t\treturn *this;\n\tm_errorList = _errorReporter.m_errorList;\n\treturn *this;\n}\n\nvoid ErrorReporter::warning(ErrorId _error, std::string const& _description)\n{\n\terror(_error, Error::Type::Warning, SourceLocation(), _description);\n}\n\nvoid ErrorReporter::warning(\n\tErrorId _error,\n\tSourceLocation const& _location,\n\tstd::string const& _description\n)\n{\n\terror(_error, Error::Type::Warning, _location, _description);\n}\n\nvoid ErrorReporter::warning(\n\tErrorId _error,\n\tSourceLocation const& _location,\n\tstd::string const& _description,\n\tSecondarySourceLocation const& _secondaryLocation\n)\n{\n\terror(_error, Error::Type::Warning, _location, _secondaryLocation, _description);\n}\n\nvoid ErrorReporter::error(ErrorId _errorId, Error::Type _type, SourceLocation const& _location, std::string const& _description)\n{\n\tif (checkForExcessiveErrors(_type))\n\t\treturn;\n\n\tm_errorList.push_back(std::make_shared<Error>(_errorId, _type, _description, _location));\n}\n\nvoid ErrorReporter::error(ErrorId _errorId, Error::Type _type, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description)\n{\n\tif (checkForExcessiveErrors(_type))\n\t\treturn;\n\n\tm_errorList.push_back(std::make_shared<Error>(_errorId, _type, _description, _location, _secondaryLocation));\n}\n\nbool ErrorReporter::hasExcessiveErrors() const\n{\n\treturn m_errorCount > c_maxErrorsAllowed;\n}\n\nbool ErrorReporter::hasError(ErrorId _errorId) const\n{\n\tauto errorMatch = [&](std::shared_ptr<Error const> const& error) -> bool {\n\t\tsolAssert(error.get());\n\t\treturn error->errorId() == _errorId;\n\t};\n\n\treturn ranges::find_if(m_errorList, errorMatch) != ranges::end(m_errorList);\n}\n\nbool ErrorReporter::checkForExcessiveErrors(Error::Type _type)\n{\n\tif (_type == Error::Type::Warning)\n\t{\n\t\tm_warningCount++;\n\n\t\tif (m_warningCount == c_maxWarningsAllowed)\n\t\t\tm_errorList.push_back(std::make_shared<Error>(4591_error, Error::Type::Warning, \"There are more than 256 warnings. Ignoring the rest.\"));\n\n\t\tif (m_warningCount >= c_maxWarningsAllowed)\n\t\t\treturn true;\n\t}\n\telse if (_type == Error::Type::Info)\n\t{\n\t\tm_infoCount++;\n\n\t\tif (m_infoCount == c_maxInfosAllowed)\n\t\t\tm_errorList.push_back(std::make_shared<Error>(2833_error, Error::Type::Info, \"There are more than 256 infos. Ignoring the rest.\"));\n\n\t\tif (m_infoCount >= c_maxInfosAllowed)\n\t\t\treturn true;\n\t}\n\telse\n\t{\n\t\tm_errorCount++;\n\n\t\tif (m_errorCount > c_maxErrorsAllowed)\n\t\t{\n\t\t\tm_errorList.push_back(std::make_shared<Error>(4013_error, Error::Type::Warning, \"There are more than 256 errors. Aborting.\"));\n\t\t\tsolThrow(FatalError, \"There are more than 256 errors. Aborting.\");\n\t\t}\n\t}\n\n\treturn false;\n}\n\nvoid ErrorReporter::fatalError(ErrorId _error, Error::Type _type, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description)\n{\n\terror(_error, _type, _location, _secondaryLocation, _description);\n\tsolThrow(FatalError, _description);\n}\n\nvoid ErrorReporter::fatalError(ErrorId _error, Error::Type _type, SourceLocation const& _location, std::string const& _description)\n{\n\terror(_error, _type, _location, _description);\n\tsolThrow(FatalError, _description);\n}\n\nErrorList const& ErrorReporter::errors() const\n{\n\treturn m_errorList;\n}\n\nvoid ErrorReporter::clear()\n{\n\tm_errorList.clear();\n}\n\nvoid ErrorReporter::declarationError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description)\n{\n\terror(\n\t\t_error,\n\t\tError::Type::DeclarationError,\n\t\t_location,\n\t\t_secondaryLocation,\n\t\t_description\n\t);\n}\n\nvoid ErrorReporter::declarationError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\terror(\n\t\t_error,\n\t\tError::Type::DeclarationError,\n\t\t_location,\n\t\t_description\n\t);\n}\n\nvoid ErrorReporter::fatalDeclarationError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\tfatalError(\n\t\t_error,\n\t\tError::Type::DeclarationError,\n\t\t_location,\n\t\t_description);\n}\n\nvoid ErrorReporter::parserError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\terror(\n\t\t_error,\n\t\tError::Type::ParserError,\n\t\t_location,\n\t\t_description\n\t);\n}\n\nvoid ErrorReporter::parserError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description)\n{\n\terror(\n\t\t_error,\n\t\tError::Type::ParserError,\n\t\t_location,\n\t\t_secondaryLocation,\n\t\t_description\n\t);\n}\n\nvoid ErrorReporter::fatalParserError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\tfatalError(\n\t\t_error,\n\t\tError::Type::ParserError,\n\t\t_location,\n\t\t_description\n\t);\n}\n\nvoid ErrorReporter::syntaxError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\terror(\n\t\t_error,\n\t\tError::Type::SyntaxError,\n\t\t_location,\n\t\t_description\n\t);\n}\n\nvoid ErrorReporter::typeError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description)\n{\n\terror(\n\t\t_error,\n\t\tError::Type::TypeError,\n\t\t_location,\n\t\t_secondaryLocation,\n\t\t_description\n\t);\n}\n\nvoid ErrorReporter::typeError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\terror(\n\t\t_error,\n\t\tError::Type::TypeError,\n\t\t_location,\n\t\t_description\n\t);\n}\n\n\nvoid ErrorReporter::fatalTypeError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description)\n{\n\tfatalError(\n\t\t_error,\n\t\tError::Type::TypeError,\n\t\t_location,\n\t\t_secondaryLocation,\n\t\t_description\n\t);\n}\n\nvoid ErrorReporter::fatalTypeError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\tfatalError(\n\t\t_error,\n\t\tError::Type::TypeError,\n\t\t_location,\n\t\t_description\n\t);\n}\n\nvoid ErrorReporter::docstringParsingError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\terror(\n\t\t_error,\n\t\tError::Type::DocstringParsingError,\n\t\t_location,\n\t\t_description\n\t);\n}\n\nvoid ErrorReporter::unimplementedFeatureError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\terror(\n\t\t_error,\n\t\tError::Type::UnimplementedFeatureError,\n\t\t_location,\n\t\t_description\n\t);\n}\n\nvoid ErrorReporter::codeGenerationError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\terror(_error, Error::Type::CodeGenerationError, _location, _description);\n}\n\nvoid ErrorReporter::codeGenerationError(Error const& _error)\n{\n\tsolAssert(_error.type() == Error::Type::CodeGenerationError);\n\tsolAssert(_error.comment(), \"Errors must include a message for the user.\");\n\tsolUnimplementedAssert(!_error.secondarySourceLocation(), \"Secondary locations not supported yet.\");\n\tcodeGenerationError(\n\t\t_error.errorId(),\n\t\t_error.sourceLocation() ?  *_error.sourceLocation() : SourceLocation{},\n\t\t*_error.comment()\n\t);\n}\n\nvoid ErrorReporter::info(\n\tErrorId _error,\n\tSourceLocation const& _location,\n\tstd::string const& _description\n)\n{\n\terror(_error, Error::Type::Info, _location, _description);\n}\n\nvoid ErrorReporter::info(ErrorId _error, std::string const& _description)\n{\n\terror(_error, Error::Type::Info, SourceLocation(), _description);\n}\n"
  },
  {
    "path": "liblangutil/ErrorReporter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Rhett <roadriverrail@gmail.com>\n * @date 2017\n * Error reporting helper class.\n */\n\n#pragma once\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Exceptions.h>\n\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/SourceLocation.h>\n#include <libsolutil/StringUtils.h>\n\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/filter.hpp>\n\nnamespace solidity::langutil\n{\n\nclass ErrorReporter\n{\npublic:\n\n\texplicit ErrorReporter(ErrorList& _errors):\n\t\tm_errorList(_errors) { }\n\n\tErrorReporter(ErrorReporter const& _errorReporter) noexcept:\n\t\tm_errorList(_errorReporter.m_errorList) { }\n\n\tErrorReporter& operator=(ErrorReporter const& _errorReporter);\n\n\tvoid append(ErrorList const& _errorList)\n\t{\n\t\tm_errorList += _errorList;\n\t}\n\n\tvoid warning(ErrorId _error, std::string const& _description);\n\n\tvoid warning(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\tvoid warning(\n\t\tErrorId _error,\n\t\tSourceLocation const& _location,\n\t\tstd::string const& _description,\n\t\tSecondarySourceLocation const& _secondaryLocation\n\t);\n\n\tvoid info(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\tvoid error(\n\t\tErrorId _error,\n\t\tError::Type _type,\n\t\tSourceLocation const& _location,\n\t\tstd::string const& _description\n\t);\n\n\tvoid info(ErrorId _error, std::string const& _description);\n\n\tvoid declarationError(\n\t\tErrorId _error,\n\t\tSourceLocation const& _location,\n\t\tSecondarySourceLocation const& _secondaryLocation,\n\t\tstd::string const& _description\n\t);\n\n\tvoid declarationError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\tvoid fatalDeclarationError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\tvoid parserError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\tvoid parserError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description);\n\n\tvoid fatalParserError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\tvoid syntaxError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\tvoid typeError(\n\t\tErrorId _error,\n\t\tSourceLocation const& _location,\n\t\tSecondarySourceLocation const& _secondaryLocation = SecondarySourceLocation(),\n\t\tstd::string const& _description = std::string()\n\t);\n\n\tvoid typeError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\ttemplate <typename... Strings>\n\tvoid typeErrorConcatenateDescriptions(ErrorId _error, SourceLocation const& _location, Strings const&... _descriptions)\n\t{\n\t\tstd::initializer_list<std::string> const descs = { _descriptions... };\n\t\tsolAssert(descs.size() > 0, \"Need error descriptions!\");\n\n\t\tauto nonEmpty = [](std::string const& _s) { return !_s.empty(); };\n\t\tstd::string errorStr = util::joinHumanReadable(descs | ranges::views::filter(nonEmpty) | ranges::to_vector, \" \");\n\n\t\terror(_error, Error::Type::TypeError, _location, errorStr);\n\t}\n\n\tvoid fatalTypeError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\tvoid fatalTypeError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondLocation, std::string const& _description);\n\n\tvoid docstringParsingError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\tvoid unimplementedFeatureError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\tvoid codeGenerationError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\tvoid codeGenerationError(Error const& _error);\n\n\tErrorList const& errors() const;\n\n\tvoid clear();\n\n\t/// @returns true iff there is any error (ignores warnings and infos).\n\tbool hasErrors() const\n\t{\n\t\treturn m_errorCount > 0;\n\t}\n\n\t/// @returns true if there is any error, warning or info.\n\tbool hasErrorsWarningsOrInfos() const\n\t{\n\t\treturn m_errorCount + m_warningCount + m_infoCount > 0;\n\t}\n\n\t/// @returns the number of errors (ignores warnings and infos).\n\tunsigned errorCount() const\n\t{\n\t\treturn m_errorCount;\n\t}\n\n\t// @returns true if the maximum error count has been reached.\n\tbool hasExcessiveErrors() const;\n\n\t/// @returns true if there is at least one occurrence of error\n\tbool hasError(ErrorId _errorId) const;\n\n\tclass ErrorWatcher\n\t{\n\tpublic:\n\t\tErrorWatcher(ErrorReporter const& _errorReporter):\n\t\t\tm_errorReporter(_errorReporter),\n\t\t\tm_initialErrorCount(_errorReporter.errorCount())\n\t\t{}\n\t\tbool ok() const\n\t\t{\n\t\t\tsolAssert(m_initialErrorCount <= m_errorReporter.errorCount(), \"Unexpected error count.\");\n\t\t\treturn m_initialErrorCount == m_errorReporter.errorCount();\n\t\t}\n\tprivate:\n\t\tErrorReporter const& m_errorReporter;\n\t\tunsigned const m_initialErrorCount;\n\t};\n\n\tErrorWatcher errorWatcher() const\n\t{\n\t\treturn ErrorWatcher(*this);\n\t}\n\nprivate:\n\tvoid error(\n\t\tErrorId _error,\n\t\tError::Type _type,\n\t\tSourceLocation const& _location,\n\t\tSecondarySourceLocation const& _secondaryLocation,\n\t\tstd::string const& _description = std::string());\n\n\tvoid fatalError(\n\t\tErrorId _error,\n\t\tError::Type _type,\n\t\tSourceLocation const& _location,\n\t\tSecondarySourceLocation const& _secondaryLocation,\n\t\tstd::string const& _description = std::string());\n\n\tvoid fatalError(\n\t\tErrorId _error,\n\t\tError::Type _type,\n\t\tSourceLocation const& _location = SourceLocation(),\n\t\tstd::string const& _description = std::string());\n\n\t// @returns true if error shouldn't be stored\n\tbool checkForExcessiveErrors(Error::Type _type);\n\n\tErrorList& m_errorList;\n\n\tunsigned m_errorCount = 0;\n\tunsigned m_warningCount = 0;\n\tunsigned m_infoCount = 0;\n\n\tunsigned const c_maxWarningsAllowed = 256;\n\tunsigned const c_maxErrorsAllowed = 256;\n\tunsigned const c_maxInfosAllowed = 256;\n};\n\n}\n"
  },
  {
    "path": "liblangutil/Exceptions.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Liana <liana@ethdev.com>\n * @date 2015\n * Solidity exception hierarchy.\n */\n\n#include <liblangutil/Exceptions.h>\n\n#include <boost/algorithm/string/case_conv.hpp>\n#include <boost/algorithm/string/trim.hpp>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\n\nstd::map<Error::Type, std::string> const Error::m_errorTypeNames = {\n\t{Error::Type::IOError, \"IOError\"},\n\t{Error::Type::FatalError, \"FatalError\"},\n\t{Error::Type::JSONError, \"JSONError\"},\n\t{Error::Type::InternalCompilerError, \"InternalCompilerError\"},\n\t{Error::Type::CompilerError, \"CompilerError\"},\n\t{Error::Type::Exception, \"Exception\"},\n\t{Error::Type::CodeGenerationError, \"CodeGenerationError\"},\n\t{Error::Type::DeclarationError, \"DeclarationError\"},\n\t{Error::Type::DocstringParsingError, \"DocstringParsingError\"},\n\t{Error::Type::ParserError, \"ParserError\"},\n\t{Error::Type::SyntaxError, \"SyntaxError\"},\n\t{Error::Type::TypeError, \"TypeError\"},\n\t{Error::Type::UnimplementedFeatureError, \"UnimplementedFeatureError\"},\n\t{Error::Type::YulException, \"YulException\"},\n\t{Error::Type::SMTLogicException, \"SMTLogicException\"},\n\t{Error::Type::Warning, \"Warning\"},\n\t{Error::Type::Info, \"Info\"},\n};\n\nError::Error(\n\tErrorId _errorId, Error::Type _type,\n\tstd::string const& _description,\n\tSourceLocation const& _location,\n\tSecondarySourceLocation const& _secondaryLocation\n):\n\tm_errorId(_errorId),\n\tm_type(_type)\n{\n\tif (_location.isValid())\n\t\t*this << errinfo_sourceLocation(_location);\n\tif (!_secondaryLocation.infos.empty())\n\t\t*this << errinfo_secondarySourceLocation(_secondaryLocation);\n\tif (!_description.empty())\n\t\t*this << util::errinfo_comment(_description);\n}\n\nSourceLocation const* Error::sourceLocation() const noexcept\n{\n\treturn boost::get_error_info<errinfo_sourceLocation>(*this);\n}\n\nSecondarySourceLocation const* Error::secondarySourceLocation() const noexcept\n{\n\treturn boost::get_error_info<errinfo_secondarySourceLocation>(*this);\n}\n"
  },
  {
    "path": "liblangutil/Exceptions.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity exception hierarchy.\n */\n\n#pragma once\n\n#include <libsolutil/Exceptions.h>\n#include <libsolutil/Assertions.h>\n#include <libsolutil/CommonData.h>\n#include <liblangutil/SourceLocation.h>\n\n#include <boost/preprocessor/cat.hpp>\n#include <boost/preprocessor/facilities/empty.hpp>\n#include <boost/preprocessor/facilities/overload.hpp>\n#include <boost/algorithm/string/case_conv.hpp>\n\n#include <optional>\n#include <string>\n#include <utility>\n#include <variant>\n#include <vector>\n\nnamespace solidity::langutil\n{\nclass Error;\nusing ErrorList = std::vector<std::shared_ptr<Error const>>;\n\nstruct CompilerError: virtual util::Exception {};\nstruct StackTooDeepError: virtual CompilerError {};\nstruct InternalCompilerError: virtual util::Exception {};\nstruct FatalError: virtual util::Exception {};\nstruct UnimplementedFeatureError: virtual util::Exception {};\nstruct InvalidAstError: virtual util::Exception {};\n\n\n/// Assertion that throws an InternalCompilerError containing the given description if it is not met.\n#if !BOOST_PP_VARIADICS_MSVC\n#define solAssert(...) BOOST_PP_OVERLOAD(solAssert_,__VA_ARGS__)(__VA_ARGS__)\n#else\n#define solAssert(...) BOOST_PP_CAT(BOOST_PP_OVERLOAD(solAssert_,__VA_ARGS__)(__VA_ARGS__),BOOST_PP_EMPTY())\n#endif\n\n#define solAssert_1(CONDITION) \\\n\tsolAssert_2((CONDITION), \"\")\n\n#define solAssert_2(CONDITION, DESCRIPTION) \\\n\tassertThrowWithDefaultDescription( \\\n\t\t(CONDITION), \\\n\t\t::solidity::langutil::InternalCompilerError, \\\n\t\t(DESCRIPTION), \\\n\t\t\"Solidity assertion failed\" \\\n\t)\n\n\n/// Assertion that throws an UnimplementedFeatureError containing the given description if it is not met.\n#if !BOOST_PP_VARIADICS_MSVC\n#define solUnimplementedAssert(...) BOOST_PP_OVERLOAD(solUnimplementedAssert_,__VA_ARGS__)(__VA_ARGS__)\n#else\n#define solUnimplementedAssert(...) BOOST_PP_CAT(BOOST_PP_OVERLOAD(solUnimplementedAssert_,__VA_ARGS__)(__VA_ARGS__),BOOST_PP_EMPTY())\n#endif\n\n#define solUnimplementedAssert_1(CONDITION) \\\n\tsolUnimplementedAssert_2((CONDITION), \"\")\n\n#define solUnimplementedAssert_2(CONDITION, DESCRIPTION) \\\n\tassertThrowWithDefaultDescription( \\\n\t\t(CONDITION), \\\n\t\t::solidity::langutil::UnimplementedFeatureError, \\\n\t\t(DESCRIPTION), \\\n\t\t\"Unimplemented feature\" \\\n\t)\n\n\n/// Helper that unconditionally reports an unimplemented feature.\n#define solUnimplemented(DESCRIPTION) \\\n\tsolUnimplementedAssert(false, DESCRIPTION)\n\n\n/// Assertion that throws an InvalidAstError containing the given description if it is not met.\n#if !BOOST_PP_VARIADICS_MSVC\n#define astAssert(...) BOOST_PP_OVERLOAD(astAssert_,__VA_ARGS__)(__VA_ARGS__)\n#else\n#define astAssert(...) BOOST_PP_CAT(BOOST_PP_OVERLOAD(astAssert_,__VA_ARGS__)(__VA_ARGS__),BOOST_PP_EMPTY())\n#endif\n\n#define astAssert_1(CONDITION) \\\n\tastAssert_2(CONDITION, \"\")\n\n#define astAssert_2(CONDITION, DESCRIPTION) \\\n\tassertThrowWithDefaultDescription( \\\n\t\t(CONDITION), \\\n\t\t::solidity::langutil::InvalidAstError, \\\n\t\t(DESCRIPTION), \\\n\t\t\"AST assertion failed\" \\\n\t)\n\n\nusing errorSourceLocationInfo = std::pair<std::string, SourceLocation>;\n\nclass SecondarySourceLocation\n{\npublic:\n\tSecondarySourceLocation& append(std::string const& _errMsg, SourceLocation const& _sourceLocation)\n\t{\n\t\tinfos.emplace_back(_errMsg, _sourceLocation);\n\t\treturn *this;\n\t}\n\tSecondarySourceLocation& append(SecondarySourceLocation&& _other)\n\t{\n\t\tinfos += std::move(_other.infos);\n\t\treturn *this;\n\t}\n\n\t/// Limits the number of secondary source locations to 32 and appends a notice to the\n\t/// error message.\n\tvoid limitSize(std::string& _message)\n\t{\n\t\tsize_t occurrences = infos.size();\n\t\tif (occurrences > 32)\n\t\t{\n\t\t\tinfos.resize(32);\n\t\t\t_message += \" Truncated from \" + std::to_string(occurrences) + \" to the first 32 occurrences.\";\n\t\t}\n\t}\n\n\tstd::vector<errorSourceLocationInfo> infos;\n};\n\nusing errinfo_sourceLocation = boost::error_info<struct tag_sourceLocation, SourceLocation>;\nusing errinfo_secondarySourceLocation = boost::error_info<struct tag_secondarySourceLocation, SecondarySourceLocation>;\n\n/**\n * Unique identifiers are used to tag and track individual error cases.\n * They are passed as the first parameter of error reporting functions.\n * Suffix _error helps to find them in the sources.\n * The struct ErrorId prevents incidental calls like typeError(3141) instead of typeError(3141_error).\n * To create a new ID, one can add 0000_error and then run \"python ./scripts/error_codes.py --fix\"\n * from the root of the repo.\n */\nstruct ErrorId\n{\n\tunsigned long long error = 0;\n\tbool operator==(ErrorId const& _rhs) const { return error == _rhs.error; }\n\tbool operator!=(ErrorId const& _rhs) const { return !(*this == _rhs); }\n\tbool operator<(ErrorId const& _rhs) const { return error < _rhs.error; }\n};\nconstexpr ErrorId operator\"\"_error(unsigned long long _error) { return ErrorId{ _error }; }\n\nclass Error: virtual public util::Exception\n{\npublic:\n\tenum class Type\n\t{\n\t\tInfo,\n\t\tWarning,\n\t\tCodeGenerationError,\n\t\tDeclarationError,\n\t\tDocstringParsingError,\n\t\tParserError,\n\t\tTypeError,\n\t\tSyntaxError,\n\t\tIOError,\n\t\tFatalError,\n\t\tJSONError,\n\t\tInternalCompilerError,\n\t\tCompilerError,\n\t\tException,\n\t\tUnimplementedFeatureError,\n\t\tYulException,\n\t\tSMTLogicException,\n\t};\n\n\tenum class Severity\n\t{\n\t\t// NOTE: We rely on these being ordered from least to most severe.\n\t\tInfo,\n\t\tWarning,\n\t\tError,\n\t};\n\n\tError(\n\t\tErrorId _errorId,\n\t\tType _type,\n\t\tstd::string const& _description,\n\t\tSourceLocation const& _location = SourceLocation(),\n\t\tSecondarySourceLocation const& _secondaryLocation = SecondarySourceLocation()\n\t);\n\n\tErrorId errorId() const { return m_errorId; }\n\tType type() const { return m_type; }\n\tSeverity severity() const { return errorSeverity(m_type); }\n\n\tSourceLocation const* sourceLocation() const noexcept;\n\tSecondarySourceLocation const* secondarySourceLocation() const noexcept;\n\n\t/// helper functions\n\tstatic Error const* containsErrorOfType(ErrorList const& _list, Error::Type _type)\n\t{\n\t\tfor (auto e: _list)\n\t\t\tif (e->type() == _type)\n\t\t\t\treturn e.get();\n\t\treturn nullptr;\n\t}\n\n\tstatic constexpr Severity errorSeverity(Type _type)\n\t{\n\t\tswitch (_type)\n\t\t{\n\t\t\tcase Type::Info: return Severity::Info;\n\t\t\tcase Type::Warning: return Severity::Warning;\n\t\t\tdefault: return Severity::Error;\n\t\t}\n\t}\n\n\tstatic constexpr Severity errorSeverityOrType(std::variant<Error::Type, Error::Severity> _typeOrSeverity)\n\t{\n\t\tif (std::holds_alternative<Error::Type>(_typeOrSeverity))\n\t\t\treturn errorSeverity(std::get<Error::Type>(_typeOrSeverity));\n\t\treturn std::get<Error::Severity>(_typeOrSeverity);\n\t}\n\n\tstatic bool isError(Severity _severity)\n\t{\n\t\treturn _severity == Severity::Error;\n\t}\n\n\tstatic bool isError(Type _type)\n\t{\n\t\treturn isError(errorSeverity(_type));\n\t}\n\n\tstatic bool containsErrors(ErrorList const& _list)\n\t{\n\t\tfor (auto e: _list)\n\t\t\tif (isError(e->type()))\n\t\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\tstatic bool hasErrorsWarningsOrInfos(ErrorList const& _list)\n\t{\n\t\treturn !_list.empty();\n\t}\n\n\tstatic std::string formatErrorSeverity(Severity _severity)\n\t{\n\t\tswitch (_severity)\n\t\t{\n\t\tcase Severity::Info: return \"Info\";\n\t\tcase Severity::Warning: return \"Warning\";\n\t\tcase Severity::Error: return \"Error\";\n\t\t}\n\t\tutil::unreachable();\n\t}\n\n\tstatic std::string formatErrorType(Type _type)\n\t{\n\t\treturn m_errorTypeNames.at(_type);\n\t}\n\n\tstatic std::optional<Type> parseErrorType(std::string _name)\n\t{\n\t\tstatic std::map<std::string, Error::Type> const m_errorTypesByName = util::invertMap(m_errorTypeNames);\n\n\t\tif (m_errorTypesByName.count(_name) == 0)\n\t\t\treturn std::nullopt;\n\n\t\treturn m_errorTypesByName.at(_name);\n\t}\n\n\tstatic std::string formatTypeOrSeverity(std::variant<Error::Type, Error::Severity> _typeOrSeverity)\n\t{\n\t\tif (std::holds_alternative<Error::Type>(_typeOrSeverity))\n\t\t\treturn formatErrorType(std::get<Error::Type>(_typeOrSeverity));\n\t\treturn formatErrorSeverity(std::get<Error::Severity>(_typeOrSeverity));\n\t}\n\n\tstatic std::string formatErrorSeverityLowercase(Severity _severity)\n\t{\n\t\tstd::string severityValue = formatErrorSeverity(_severity);\n\t\tboost::algorithm::to_lower(severityValue);\n\t\treturn severityValue;\n\t}\n\nprivate:\n\tErrorId m_errorId;\n\tType m_type;\n\n\tstatic std::map<Type, std::string> const m_errorTypeNames;\n};\n\n}\n"
  },
  {
    "path": "liblangutil/ParserBase.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2016\n * Solidity parser shared functionality.\n */\n\n#include <liblangutil/ParserBase.h>\n#include <liblangutil/Scanner.h>\n#include <liblangutil/ErrorReporter.h>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\n\nSourceLocation ParserBase::currentLocation() const\n{\n\treturn m_scanner->currentLocation();\n}\n\nToken ParserBase::currentToken() const\n{\n\treturn m_scanner->currentToken();\n}\n\nToken ParserBase::peekNextToken() const\n{\n\treturn m_scanner->peekNextToken();\n}\n\nstd::string_view ParserBase::currentLiteral() const\n{\n\treturn m_scanner->currentLiteral();\n}\n\nToken ParserBase::advance()\n{\n\treturn m_scanner->next();\n}\n\nstd::string ParserBase::tokenName(Token _token)\n{\n\tif (_token == Token::Identifier)\n\t\treturn \"identifier\";\n\telse if (_token == Token::EOS)\n\t\treturn \"end of source\";\n\telse if (TokenTraits::isReservedKeyword(_token))\n\t\treturn \"reserved keyword '\" + TokenTraits::friendlyName(_token) + \"'\";\n\telse if (TokenTraits::isElementaryTypeName(_token)) //for the sake of accuracy in reporting\n\t{\n\t\tElementaryTypeNameToken elemTypeName = m_scanner->currentElementaryTypeNameToken();\n\t\treturn \"'\" + elemTypeName.toString() + \"'\";\n\t}\n\telse\n\t\treturn \"'\" + TokenTraits::friendlyName(_token) + \"'\";\n}\n\nvoid ParserBase::expectToken(Token _value, bool _advance)\n{\n\tToken tok = m_scanner->currentToken();\n\tif (tok != _value)\n\t\tfatalParserError(\n\t\t\t2314_error,\n\t\t\t\"Expected \" + ParserBase::tokenName(_value) + \" but got \" + tokenName(tok)\n\t\t);\n\tif (_advance)\n\t\tadvance();\n}\n\nvoid ParserBase::increaseRecursionDepth()\n{\n\tm_recursionDepth++;\n\tif (m_recursionDepth >= 1200)\n\t\tfatalParserError(7319_error, \"Maximum recursion depth reached during parsing.\");\n}\n\nvoid ParserBase::decreaseRecursionDepth()\n{\n\tsolAssert(m_recursionDepth > 0, \"\");\n\tm_recursionDepth--;\n}\n\nvoid ParserBase::parserWarning(ErrorId _error, std::string const& _description)\n{\n\tm_errorReporter.warning(_error, currentLocation(), _description);\n}\n\nvoid ParserBase::parserWarning(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\tm_errorReporter.warning(_error, _location, _description);\n}\n\nvoid ParserBase::parserError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\tm_errorReporter.parserError(_error, _location, _description);\n}\n\nvoid ParserBase::parserError(ErrorId _error, std::string const& _description)\n{\n\tparserError(_error, currentLocation(), _description);\n}\n\nvoid ParserBase::fatalParserError(ErrorId _error, std::string const& _description)\n{\n\tfatalParserError(_error, currentLocation(), _description);\n}\n\nvoid ParserBase::fatalParserError(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n{\n\tm_errorReporter.fatalParserError(_error, _location, _description);\n}\n"
  },
  {
    "path": "liblangutil/ParserBase.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2016\n * Solidity parser shared functionality.\n */\n\n#pragma once\n\n#include <liblangutil/Token.h>\n#include <memory>\n#include <string>\n\nnamespace solidity::langutil\n{\n\nclass ErrorReporter;\nclass Scanner;\nstruct SourceLocation;\nstruct ErrorId;\n\nclass ParserBase\n{\npublic:\n\texplicit ParserBase(ErrorReporter& errorReporter):\n\t\tm_errorReporter(errorReporter)\n\t{}\n\n\tvirtual ~ParserBase() = default;\n\nprotected:\n\t/// Utility class that creates an error and throws an exception if the\n\t/// recursion depth is too deep.\n\tclass RecursionGuard\n\t{\n\tpublic:\n\t\texplicit RecursionGuard(ParserBase& _parser): m_parser(_parser)\n\t\t{\n\t\t\tm_parser.increaseRecursionDepth();\n\t\t}\n\t\t~RecursionGuard() { m_parser.decreaseRecursionDepth(); }\n\tprivate:\n\t\tParserBase& m_parser;\n\t};\n\n\t/// Location of the current token\n\tvirtual SourceLocation currentLocation() const;\n\n\t///@{\n\t///@name Helper functions\n\t/// If current token value is not @a _value, throw exception otherwise advance token\n\t//  if @a _advance is true\n\tvoid expectToken(Token _value, bool _advance = true);\n\n\tToken currentToken() const;\n\tToken peekNextToken() const;\n\tstd::string tokenName(Token _token);\n\t/// Points to the current literal. The string view invalidates when the parser advances.\n\tstd::string_view currentLiteral() const;\n\tvirtual Token advance();\n\t///@}\n\n\t/// Increases the recursion depth and throws an exception if it is too deep.\n\tvoid increaseRecursionDepth();\n\tvoid decreaseRecursionDepth();\n\n\t/// Creates a @ref ParserError and annotates it with the current position and the\n\t/// given @a _description.\n\tvoid parserError(ErrorId _error, std::string const& _description);\n\tvoid parserError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\t/// Creates a @ref ParserWarning and annotates it with the current position and the\n\t/// given @a _description.\n\tvoid parserWarning(ErrorId _error, std::string const& _description);\n\tvoid parserWarning(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\t/// Creates a @ref ParserError and annotates it with the current position and the\n\t/// given @a _description. Throws the FatalError.\n\tvoid fatalParserError(ErrorId _error, std::string const& _description);\n\tvoid fatalParserError(ErrorId _error, SourceLocation const& _location, std::string const& _description);\n\n\tstd::shared_ptr<Scanner> m_scanner;\n\t/// The reference to the list of errors, warnings and infos to add errors/warnings/infos during parsing\n\tErrorReporter& m_errorReporter;\n\t/// Current recursion depth during parsing.\n\tsize_t m_recursionDepth = 0;\n};\n\n}\n"
  },
  {
    "path": "liblangutil/Scanner.cpp",
    "content": "/*\n * This file is part of solidity.\n *\n * solidity is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * solidity is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with solidity.  If not, see <http://www.gnu.org/licenses/>.\n *\n * This file is derived from the file \"scanner.cc\", which was part of the\n * V8 project. The original copyright header follows:\n *\n * Copyright 2006-2012, the V8 project authors. All rights reserved.\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * * Neither the name of Google Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity scanner.\n */\n\n#include <liblangutil/Common.h>\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/Scanner.h>\n\n#include <boost/algorithm/string/classification.hpp>\n\n#include <optional>\n#include <string_view>\n#include <tuple>\n#include <array>\n\n\nnamespace solidity::langutil\n{\n\nstd::string to_string(ScannerError _errorCode)\n{\n\tswitch (_errorCode)\n\t{\n\t\tcase ScannerError::NoError: return \"No error.\";\n\t\tcase ScannerError::IllegalToken: return \"Invalid token.\";\n\t\tcase ScannerError::IllegalHexString: return \"Expected even number of hex-nibbles.\";\n\t\tcase ScannerError::IllegalHexDigit: return \"Hexadecimal digit missing or invalid.\";\n\t\tcase ScannerError::IllegalCommentTerminator: return \"Expected multi-line comment-terminator.\";\n\t\tcase ScannerError::IllegalEscapeSequence: return \"Invalid escape sequence.\";\n\t\tcase ScannerError::UnicodeCharacterInNonUnicodeString: return \"Invalid character in string. If you are trying to use Unicode characters, use a unicode\\\"...\\\" string literal.\";\n\t\tcase ScannerError::IllegalCharacterInString: return \"Invalid character in string.\";\n\t\tcase ScannerError::IllegalStringEndQuote: return \"Expected string end-quote.\";\n\t\tcase ScannerError::IllegalNumberSeparator: return \"Invalid use of number separator '_'.\";\n\t\tcase ScannerError::IllegalExponent: return \"Invalid exponent.\";\n\t\tcase ScannerError::IllegalNumberEnd: return \"Identifier-start is not allowed at end of a number.\";\n\t\tcase ScannerError::OctalNotAllowed: return \"Octal numbers not allowed.\";\n\t\tcase ScannerError::DirectionalOverrideUnderflow: return \"Unicode direction override underflow in comment or string literal.\";\n\t\tcase ScannerError::DirectionalOverrideMismatch: return \"Mismatching directional override markers in comment or string literal.\";\n\t\tdefault:\n\t\t\tsolAssert(false, \"Unhandled case in to_string(ScannerError)\");\n\t\t\treturn \"\";\n\t}\n}\n\n\nstd::ostream& operator<<(std::ostream& os, ScannerError _errorCode)\n{\n\treturn os << to_string(_errorCode);\n}\n\n/// Scoped helper for literal recording. Automatically drops the literal\n/// if aborting the scanning before it's complete.\nenum LiteralType\n{\n\tLITERAL_TYPE_STRING,\n\tLITERAL_TYPE_NUMBER, // not really different from string type in behaviour\n\tLITERAL_TYPE_COMMENT\n};\n\nclass LiteralScope\n{\npublic:\n\texplicit LiteralScope(Scanner* _self, enum LiteralType _type):\n\t\tm_type(_type),\n\t\tm_scanner(_self),\n\t\tm_complete(false)\n\t{\n\t\tif (_type == LITERAL_TYPE_COMMENT)\n\t\t\tm_scanner->m_skippedComments[Scanner::NextNext].literal.clear();\n\t\telse\n\t\t\tm_scanner->m_tokens[Scanner::NextNext].literal.clear();\n\t}\n\t~LiteralScope()\n\t{\n\t\tif (!m_complete)\n\t\t{\n\t\t\tif (m_type == LITERAL_TYPE_COMMENT)\n\t\t\t\tm_scanner->m_skippedComments[Scanner::NextNext].literal.clear();\n\t\t\telse\n\t\t\t\tm_scanner->m_tokens[Scanner::NextNext].literal.clear();\n\t\t}\n\t}\n\tvoid complete() { m_complete = true; }\n\nprivate:\n\tenum LiteralType m_type;\n\tScanner* m_scanner;\n\tbool m_complete;\n};\n\nvoid Scanner::reset()\n{\n\tm_source.reset();\n\tm_kind = ScannerKind::Solidity;\n\tm_char = m_source.get();\n\tskipWhitespace();\n\tnext();\n\tnext();\n\tnext();\n}\n\nvoid Scanner::setPosition(size_t _offset)\n{\n\tm_char = m_source.setPosition(_offset);\n\tscanToken();\n\tnext();\n\tnext();\n}\n\nbool Scanner::scanHexByte(char& o_scannedByte)\n{\n\tchar x = 0;\n\tfor (size_t i = 0; i < 2; i++)\n\t{\n\t\tint d = hexValue(m_char);\n\t\tif (d < 0)\n\t\t{\n\t\t\trollback(i);\n\t\t\treturn false;\n\t\t}\n\t\tx = static_cast<char>(x * 16 + d);\n\t\tadvance();\n\t}\n\to_scannedByte = x;\n\treturn true;\n}\n\nstd::optional<unsigned> Scanner::scanUnicode()\n{\n\tunsigned x = 0;\n\tfor (size_t i = 0; i < 4; i++)\n\t{\n\t\tint d = hexValue(m_char);\n\t\tif (d < 0)\n\t\t{\n\t\t\trollback(i);\n\t\t\treturn {};\n\t\t}\n\t\tx = x * 16 + static_cast<unsigned>(d);\n\t\tadvance();\n\t}\n\treturn x;\n}\n\n// This supports codepoints between 0000 and FFFF.\nvoid Scanner::addUnicodeAsUTF8(unsigned codepoint)\n{\n\tif (codepoint <= 0x7f)\n\t\taddLiteralChar(char(codepoint));\n\telse if (codepoint <= 0x7ff)\n\t{\n\t\taddLiteralChar(char(0xc0u | (codepoint >> 6u)));\n\t\taddLiteralChar(char(0x80u | (codepoint & 0x3fu)));\n\t}\n\telse\n\t{\n\t\taddLiteralChar(char(0xe0u | (codepoint >> 12u)));\n\t\taddLiteralChar(char(0x80u | ((codepoint >> 6u) & 0x3fu)));\n\t\taddLiteralChar(char(0x80u | (codepoint & 0x3fu)));\n\t}\n}\n\nvoid Scanner::rescan()\n{\n\tsize_t rollbackTo = 0;\n\tif (m_skippedComments[Current].literal.empty())\n\t\trollbackTo = static_cast<size_t>(m_tokens[Current].location.start);\n\telse\n\t\trollbackTo = static_cast<size_t>(m_skippedComments[Current].location.start);\n\tm_char = m_source.rollback(m_source.position() - rollbackTo);\n\tnext();\n\tnext();\n\tnext();\n}\n\n// Ensure that tokens can be stored in a byte.\nBOOST_STATIC_ASSERT(TokenTraits::count() <= 0x100);\n\nToken Scanner::next()\n{\n\tm_tokens[Current] = std::move(m_tokens[Next]);\n\tm_tokens[Next] = std::move(m_tokens[NextNext]);\n\tm_skippedComments[Current] = std::move(m_skippedComments[Next]);\n\tm_skippedComments[Next] = std::move(m_skippedComments[NextNext]);\n\n\tscanToken();\n\n\treturn m_tokens[Current].token;\n}\n\nToken Scanner::selectToken(char _next, Token _then, Token _else)\n{\n\tadvance();\n\tif (m_char == _next)\n\t\treturn selectToken(_then);\n\telse\n\t\treturn _else;\n}\n\nbool Scanner::skipWhitespace()\n{\n\tsize_t const startPosition = sourcePos();\n\twhile (isWhiteSpace(m_char))\n\t\tadvance();\n\t// Return whether or not we skipped any characters.\n\treturn sourcePos() != startPosition;\n}\n\nbool Scanner::skipWhitespaceExceptUnicodeLinebreak()\n{\n\tsize_t const startPosition = sourcePos();\n\twhile (isWhiteSpace(m_char) && !isUnicodeLinebreak())\n\t\tadvance();\n\t// Return whether or not we skipped any characters.\n\treturn sourcePos() != startPosition;\n}\n\n\nnamespace\n{\n\n/// Tries to scan for an RLO/LRO/RLE/LRE/PDF and keeps track of script writing direction override depth.\n///\n/// @returns ScannerError::NoError in case of successful parsing and directional encodings are paired\n///          and error code in case the input's lexical parser state is invalid and this error should be reported\n///          to the user.\nstatic ScannerError validateBiDiMarkup(CharStream& _stream, size_t _startPosition)\n{\n\tstatic std::array<std::pair<std::string_view, int>, 5> constexpr directionalSequences{\n\t\tstd::pair<std::string_view, int>{\"\\xE2\\x80\\xAD\", 1}, // U+202D (LRO - Left-to-Right Override)\n\t\tstd::pair<std::string_view, int>{\"\\xE2\\x80\\xAE\", 1}, // U+202E (RLO - Right-to-Left Override)\n\t\tstd::pair<std::string_view, int>{\"\\xE2\\x80\\xAA\", 1}, // U+202A (LRE - Left-to-Right Embedding)\n\t\tstd::pair<std::string_view, int>{\"\\xE2\\x80\\xAB\", 1}, // U+202B (RLE - Right-to-Left Embedding)\n\t\tstd::pair<std::string_view, int>{\"\\xE2\\x80\\xAC\", -1} // U+202C (PDF - Pop Directional Formatting\n\t};\n\n\tsize_t endPosition = _stream.position();\n\t_stream.setPosition(_startPosition);\n\n\tint directionOverrideDepth = 0;\n\n\tfor (size_t currentPos = _startPosition; currentPos < endPosition; ++currentPos)\n\t{\n\t\t_stream.setPosition(currentPos);\n\n\t\tfor (auto const& [sequence, depthChange]: directionalSequences)\n\t\t\tif (_stream.prefixMatch(sequence))\n\t\t\t\tdirectionOverrideDepth += depthChange;\n\n\t\tif (directionOverrideDepth < 0)\n\t\t\treturn ScannerError::DirectionalOverrideUnderflow;\n\t}\n\n\t_stream.setPosition(endPosition);\n\n\treturn directionOverrideDepth > 0 ? ScannerError::DirectionalOverrideMismatch : ScannerError::NoError;\n}\n\n}\n\nToken Scanner::skipSingleLineComment()\n{\n\t// Line terminator is not part of the comment. If it is a\n\t// non-ascii line terminator, it will result in a parser error.\n\tsize_t startPosition = m_source.position();\n\twhile (!isUnicodeLinebreak())\n\t\tif (!advance())\n\t\t\tbreak;\n\n\tScannerError unicodeDirectionError = validateBiDiMarkup(m_source, startPosition);\n\tif (unicodeDirectionError != ScannerError::NoError)\n\t\treturn setError(unicodeDirectionError);\n\n\treturn Token::Whitespace;\n}\n\nbool Scanner::atEndOfLine() const\n{\n\treturn m_char == '\\n' || m_char == '\\r';\n}\n\nbool Scanner::tryScanEndOfLine()\n{\n\tif (m_char == '\\n')\n\t{\n\t\tadvance();\n\t\treturn true;\n\t}\n\n\tif (m_char == '\\r')\n\t{\n\t\tif (advance() && m_char == '\\n')\n\t\t\tadvance();\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nsize_t Scanner::scanSingleLineDocComment()\n{\n\tLiteralScope literal(this, LITERAL_TYPE_COMMENT);\n\tsize_t endPosition = m_source.position();\n\n\tskipWhitespaceExceptUnicodeLinebreak();\n\n\twhile (!isSourcePastEndOfInput())\n\t{\n\t\tendPosition = m_source.position();\n\t\tif (tryScanEndOfLine())\n\t\t{\n\t\t\t// Check if next line is also a single-line comment.\n\t\t\t// If any whitespaces were skipped, use source position before.\n\t\t\tif (!skipWhitespaceExceptUnicodeLinebreak())\n\t\t\t\tendPosition = m_source.position();\n\n\t\t\tif (!m_source.isPastEndOfInput(3) &&\n\t\t\t\tm_source.get(0) == '/' &&\n\t\t\t\tm_source.get(1) == '/' &&\n\t\t\t\tm_source.get(2) == '/')\n\t\t\t{\n\t\t\t\tif (!m_source.isPastEndOfInput(4) && m_source.get(3) == '/')\n\t\t\t\t\tbreak; // \"////\" is not a documentation comment\n\t\t\t\tm_char = m_source.advanceAndGet(3);\n\t\t\t\tif (atEndOfLine())\n\t\t\t\t\tcontinue;\n\t\t\t\taddCommentLiteralChar('\\n');\n\t\t\t}\n\t\t\telse\n\t\t\t\tbreak; // next line is not a documentation comment, we are done\n\t\t}\n\t\telse if (isUnicodeLinebreak())\n\t\t\t// Any line terminator that is not '\\n' is considered to end the\n\t\t\t// comment.\n\t\t\tbreak;\n\t\taddCommentLiteralChar(m_char);\n\t\tadvance();\n\t}\n\tliteral.complete();\n\treturn endPosition;\n}\n\nToken Scanner::skipMultiLineComment()\n{\n\tsize_t startPosition = m_source.position();\n\twhile (!isSourcePastEndOfInput())\n\t{\n\t\tchar prevChar = m_char;\n\t\tadvance();\n\n\t\t// If we have reached the end of the multi-line comment, we\n\t\t// consume the '/' and insert a whitespace. This way all\n\t\t// multi-line comments are treated as whitespace.\n\t\tif (prevChar == '*' && m_char == '/')\n\t\t{\n\t\t\tScannerError unicodeDirectionError = validateBiDiMarkup(m_source, startPosition);\n\t\t\tif (unicodeDirectionError != ScannerError::NoError)\n\t\t\t\treturn setError(unicodeDirectionError);\n\n\t\t\tm_char = ' ';\n\t\t\treturn Token::Whitespace;\n\t\t}\n\t}\n\t// Unterminated multi-line comment.\n\treturn setError(ScannerError::IllegalCommentTerminator);\n}\n\nToken Scanner::scanMultiLineDocComment()\n{\n\tLiteralScope literal(this, LITERAL_TYPE_COMMENT);\n\tbool endFound = false;\n\tbool charsAdded = false;\n\n\twhile (isWhiteSpace(m_char) && !atEndOfLine())\n\t\tadvance();\n\n\twhile (!isSourcePastEndOfInput())\n\t{\n\t\t// handle newlines in multiline comments\n\t\tif (atEndOfLine())\n\t\t{\n\t\t\tskipWhitespace();\n\t\t\tif (!m_source.isPastEndOfInput(1) && m_source.get(0) == '*' && m_source.get(1) == '*')\n\t\t\t{ // it is unknown if this leads to the end of the comment\n\t\t\t\taddCommentLiteralChar('*');\n\t\t\t\tadvance();\n\t\t\t}\n\t\t\telse if (!m_source.isPastEndOfInput(1) && m_source.get(0) == '*' && m_source.get(1) != '/')\n\t\t\t{ // skip first '*' in subsequent lines\n\t\t\t\tm_char = m_source.advanceAndGet(1);\n\t\t\t\tif (atEndOfLine()) // ignores empty lines\n\t\t\t\t\tcontinue;\n\t\t\t\tif (charsAdded)\n\t\t\t\t\taddCommentLiteralChar('\\n'); // corresponds to the end of previous line\n\t\t\t}\n\t\t\telse if (!m_source.isPastEndOfInput(1) && m_source.get(0) == '*' && m_source.get(1) == '/')\n\t\t\t{ // if after newline the comment ends, don't insert the newline\n\t\t\t\tm_char = m_source.advanceAndGet(2);\n\t\t\t\tendFound = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (charsAdded)\n\t\t\t\taddCommentLiteralChar('\\n');\n\t\t}\n\n\t\tif (!m_source.isPastEndOfInput(1) && m_source.get(0) == '*' && m_source.get(1) == '/')\n\t\t{\n\t\t\tm_char = m_source.advanceAndGet(2);\n\t\t\tendFound = true;\n\t\t\tbreak;\n\t\t}\n\t\taddCommentLiteralChar(m_char);\n\t\tcharsAdded = true;\n\t\tadvance();\n\t}\n\tliteral.complete();\n\tif (!endFound)\n\t\treturn setError(ScannerError::IllegalCommentTerminator);\n\telse\n\t\treturn Token::CommentLiteral;\n}\n\nToken Scanner::scanSlash()\n{\n\tint firstSlashPosition = static_cast<int>(sourcePos());\n\tadvance();\n\tif (m_char == '/')\n\t{\n\t\tif (!advance()) /* double slash comment directly before EOS */\n\t\t\treturn Token::Whitespace;\n\t\telse if (m_char == '/')\n\t\t{\n\t\t\tadvance(); //consume the last '/' at ///\n\n\t\t\t// \"////\"\n\t\t\tif (m_char == '/')\n\t\t\t\treturn skipSingleLineComment();\n\t\t\t// doxygen style /// comment\n\t\t\tm_skippedComments[NextNext].location.start = firstSlashPosition;\n\t\t\tm_skippedComments[NextNext].location.sourceName = m_sourceName;\n\t\t\tm_skippedComments[NextNext].token = Token::CommentLiteral;\n\t\t\tm_skippedComments[NextNext].location.end = static_cast<int>(scanSingleLineDocComment());\n\t\t\treturn Token::Whitespace;\n\t\t}\n\t\telse\n\t\t\treturn skipSingleLineComment();\n\t}\n\telse if (m_char == '*')\n\t{\n\t\t// doxygen style /** natspec comment\n\t\tif (!advance()) /* slash star comment before EOS */\n\t\t\treturn setError(ScannerError::IllegalCommentTerminator);\n\t\telse if (m_char == '*')\n\t\t{\n\t\t\tadvance(); //consume the last '*' at /**\n\n\t\t\t// \"/**/\"\n\t\t\tif (m_char == '/')\n\t\t\t{\n\t\t\t\tadvance(); //skip the closing slash\n\t\t\t\treturn Token::Whitespace;\n\t\t\t}\n\t\t\t// \"/***\"\n\t\t\tif (m_char == '*')\n\t\t\t\t// \"/***/\" may be interpreted as empty natspec or skipped; skipping is simpler\n\t\t\t\treturn skipMultiLineComment();\n\t\t\t// we actually have a multiline documentation comment\n\t\t\tm_skippedComments[NextNext].location.start = firstSlashPosition;\n\t\t\tm_skippedComments[NextNext].location.sourceName = m_sourceName;\n\t\t\tToken comment = scanMultiLineDocComment();\n\t\t\tm_skippedComments[NextNext].location.end = static_cast<int>(sourcePos());\n\t\t\tm_skippedComments[NextNext].token = comment;\n\t\t\tif (comment == Token::Illegal)\n\t\t\t\treturn Token::Illegal; // error already set\n\t\t\telse\n\t\t\t\treturn Token::Whitespace;\n\t\t}\n\t\telse\n\t\t\treturn skipMultiLineComment();\n\t}\n\telse if (m_char == '=')\n\t\treturn selectToken(Token::AssignDiv);\n\telse\n\t\treturn Token::Div;\n}\n\nvoid Scanner::scanToken()\n{\n\tm_tokens[NextNext] = {};\n\tm_skippedComments[NextNext] = {};\n\n\tToken token;\n\t// M and N are for the purposes of grabbing different type sizes\n\tunsigned m = 0;\n\tunsigned n = 0;\n\tdo\n\t{\n\t\t// Remember the position of the next token\n\t\tm_tokens[NextNext].location.start = static_cast<int>(sourcePos());\n\t\tswitch (m_char)\n\t\t{\n\t\tcase '\"':\n\t\tcase '\\'':\n\t\t\ttoken = scanString(false);\n\t\t\tbreak;\n\t\tcase '<':\n\t\t\t// < <= << <<=\n\t\t\tadvance();\n\t\t\tif (m_char == '=')\n\t\t\t\ttoken = selectToken(Token::LessThanOrEqual);\n\t\t\telse if (m_char == '<')\n\t\t\t\ttoken = selectToken('=', Token::AssignShl, Token::SHL);\n\t\t\telse\n\t\t\t\ttoken = Token::LessThan;\n\t\t\tbreak;\n\t\tcase '>':\n\t\t\t// > >= >> >>= >>> >>>=\n\t\t\tadvance();\n\t\t\tif (m_char == '=')\n\t\t\t\ttoken = selectToken(Token::GreaterThanOrEqual);\n\t\t\telse if (m_char == '>')\n\t\t\t{\n\t\t\t\t// >> >>= >>> >>>=\n\t\t\t\tadvance();\n\t\t\t\tif (m_char == '=')\n\t\t\t\t\ttoken = selectToken(Token::AssignSar);\n\t\t\t\telse if (m_char == '>')\n\t\t\t\t\ttoken = selectToken('=', Token::AssignShr, Token::SHR);\n\t\t\t\telse\n\t\t\t\t\ttoken = Token::SAR;\n\t\t\t}\n\t\t\telse\n\t\t\t\ttoken = Token::GreaterThan;\n\t\t\tbreak;\n\t\tcase '=':\n\t\t\t// = == =>\n\t\t\tadvance();\n\t\t\tif (m_char == '=')\n\t\t\t\ttoken = selectToken(Token::Equal);\n\t\t\telse if (m_char == '>')\n\t\t\t\ttoken = selectToken(Token::DoubleArrow);\n\t\t\telse\n\t\t\t\ttoken = Token::Assign;\n\t\t\tbreak;\n\t\tcase '!':\n\t\t\t// ! !=\n\t\t\tadvance();\n\t\t\tif (m_char == '=')\n\t\t\t\ttoken = selectToken(Token::NotEqual);\n\t\t\telse\n\t\t\t\ttoken = Token::Not;\n\t\t\tbreak;\n\t\tcase '+':\n\t\t\t// + ++ +=\n\t\t\tadvance();\n\t\t\tif (m_char == '+')\n\t\t\t\ttoken = selectToken(Token::Inc);\n\t\t\telse if (m_char == '=')\n\t\t\t\ttoken = selectToken(Token::AssignAdd);\n\t\t\telse\n\t\t\t\ttoken = Token::Add;\n\t\t\tbreak;\n\t\tcase '-':\n\t\t\t// - -- -= ->\n\t\t\tadvance();\n\t\t\tif (m_char == '-')\n\t\t\t\ttoken = selectToken(Token::Dec);\n\t\t\telse if (m_char == '=')\n\t\t\t\ttoken = selectToken(Token::AssignSub);\n\t\t\telse if (m_char == '>')\n\t\t\t\ttoken = selectToken(Token::RightArrow);\n\t\t\telse\n\t\t\t\ttoken = Token::Sub;\n\t\t\tbreak;\n\t\tcase '*':\n\t\t\t// * ** *=\n\t\t\tadvance();\n\t\t\tif (m_char == '*')\n\t\t\t\ttoken = selectToken(Token::Exp);\n\t\t\telse if (m_char == '=')\n\t\t\t\ttoken = selectToken(Token::AssignMul);\n\t\t\telse\n\t\t\t\ttoken = Token::Mul;\n\t\t\tbreak;\n\t\tcase '%':\n\t\t\t// % %=\n\t\t\ttoken = selectToken('=', Token::AssignMod, Token::Mod);\n\t\t\tbreak;\n\t\tcase '/':\n\t\t\t// /  // /* /=\n\t\t\ttoken = scanSlash();\n\t\t\tbreak;\n\t\tcase '&':\n\t\t\t// & && &=\n\t\t\tadvance();\n\t\t\tif (m_char == '&')\n\t\t\t\ttoken = selectToken(Token::And);\n\t\t\telse if (m_char == '=')\n\t\t\t\ttoken = selectToken(Token::AssignBitAnd);\n\t\t\telse\n\t\t\t\ttoken = Token::BitAnd;\n\t\t\tbreak;\n\t\tcase '|':\n\t\t\t// | || |=\n\t\t\tadvance();\n\t\t\tif (m_char == '|')\n\t\t\t\ttoken = selectToken(Token::Or);\n\t\t\telse if (m_char == '=')\n\t\t\t\ttoken = selectToken(Token::AssignBitOr);\n\t\t\telse\n\t\t\t\ttoken = Token::BitOr;\n\t\t\tbreak;\n\t\tcase '^':\n\t\t\t// ^ ^=\n\t\t\ttoken = selectToken('=', Token::AssignBitXor, Token::BitXor);\n\t\t\tbreak;\n\t\tcase '.':\n\t\t\t// . Number\n\t\t\tadvance();\n\t\t\tif (m_kind != ScannerKind::ExperimentalSolidity && isDecimalDigit(m_char))\n\t\t\t\ttoken = scanNumber('.');\n\t\t\telse\n\t\t\t\ttoken = Token::Period;\n\t\t\tbreak;\n\t\tcase ':':\n\t\t\t// : :=\n\t\t\tadvance();\n\t\t\tif (m_char == '=')\n\t\t\t\ttoken = selectToken(Token::AssemblyAssign);\n\t\t\telse\n\t\t\t\ttoken = Token::Colon;\n\t\t\tbreak;\n\t\tcase ';':\n\t\t\ttoken = selectToken(Token::Semicolon);\n\t\t\tbreak;\n\t\tcase ',':\n\t\t\ttoken = selectToken(Token::Comma);\n\t\t\tbreak;\n\t\tcase '(':\n\t\t\ttoken = selectToken(Token::LParen);\n\t\t\tbreak;\n\t\tcase ')':\n\t\t\ttoken = selectToken(Token::RParen);\n\t\t\tbreak;\n\t\tcase '[':\n\t\t\ttoken = selectToken(Token::LBrack);\n\t\t\tbreak;\n\t\tcase ']':\n\t\t\ttoken = selectToken(Token::RBrack);\n\t\t\tbreak;\n\t\tcase '{':\n\t\t\ttoken = selectToken(Token::LBrace);\n\t\t\tbreak;\n\t\tcase '}':\n\t\t\ttoken = selectToken(Token::RBrace);\n\t\t\tbreak;\n\t\tcase '?':\n\t\t\ttoken = selectToken(Token::Conditional);\n\t\t\tbreak;\n\t\tcase '~':\n\t\t\ttoken = selectToken(Token::BitNot);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (isIdentifierStart(m_char))\n\t\t\t{\n\t\t\t\tstd::tie(token, m, n) = scanIdentifierOrKeyword();\n\n\t\t\t\t// Special case for hexadecimal literals\n\t\t\t\tif (token == Token::Hex)\n\t\t\t\t{\n\t\t\t\t\t// reset\n\t\t\t\t\tm = 0;\n\t\t\t\t\tn = 0;\n\n\t\t\t\t\t// Special quoted hex string must follow\n\t\t\t\t\tif (m_char == '\"' || m_char == '\\'')\n\t\t\t\t\t\ttoken = scanHexString();\n\t\t\t\t\telse\n\t\t\t\t\t\ttoken = setError(ScannerError::IllegalToken);\n\t\t\t\t}\n\t\t\t\telse if (token == Token::Unicode && m_kind != ScannerKind::Yul)\n\t\t\t\t{\n\t\t\t\t\t// reset\n\t\t\t\t\tm = 0;\n\t\t\t\t\tn = 0;\n\n\t\t\t\t\t// Special quoted hex string must follow\n\t\t\t\t\tif (m_char == '\"' || m_char == '\\'')\n\t\t\t\t\t\ttoken = scanString(true);\n\t\t\t\t\telse\n\t\t\t\t\t\ttoken = setError(ScannerError::IllegalToken);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (isDecimalDigit(m_char))\n\t\t\t\ttoken = scanNumber();\n\t\t\telse if (skipWhitespace())\n\t\t\t\ttoken = Token::Whitespace;\n\t\t\telse if (isSourcePastEndOfInput())\n\t\t\t\ttoken = Token::EOS;\n\t\t\telse\n\t\t\t\ttoken = selectErrorToken(ScannerError::IllegalToken);\n\t\t\tbreak;\n\t\t}\n\t\t// Continue scanning for tokens as long as we're just skipping\n\t\t// whitespace.\n\t}\n\twhile (token == Token::Whitespace);\n\tm_tokens[NextNext].location.end = static_cast<int>(sourcePos());\n\tm_tokens[NextNext].location.sourceName = m_sourceName;\n\tm_tokens[NextNext].token = token;\n\tm_tokens[NextNext].extendedTokenInfo = std::make_tuple(m, n);\n}\n\nbool Scanner::scanEscape()\n{\n\tchar c = m_char;\n\n\t// Skip escaped newlines.\n\tif (tryScanEndOfLine())\n\t\treturn true;\n\tadvance();\n\n\tswitch (c)\n\t{\n\tcase '\\'':  // fall through\n\tcase '\"':  // fall through\n\tcase '\\\\':\n\t\tbreak;\n\tcase 'n':\n\t\tc = '\\n';\n\t\tbreak;\n\tcase 'r':\n\t\tc = '\\r';\n\t\tbreak;\n\tcase 't':\n\t\tc = '\\t';\n\t\tbreak;\n\tcase 'u':\n\t{\n\t\tif (auto const codepoint = scanUnicode(); codepoint.has_value())\n\t\t\taddUnicodeAsUTF8(*codepoint);\n\t\telse\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\tcase 'x':\n\t\tif (!scanHexByte(c))\n\t\t\treturn false;\n\t\tbreak;\n\tdefault:\n\t\treturn false;\n\t}\n\n\taddLiteralChar(c);\n\treturn true;\n}\n\nbool Scanner::isUnicodeLinebreak()\n{\n\tif (0x0a <= m_char && m_char <= 0x0d)\n\t\t// line feed, vertical tab, form feed, carriage return\n\t\treturn true;\n\tif (!m_source.isPastEndOfInput(1) && uint8_t(m_source.get(0)) == 0xc2 && uint8_t(m_source.get(1)) == 0x85)\n\t\t// NEL - U+0085, C2 85 in utf8\n\t\treturn true;\n\tif (!m_source.isPastEndOfInput(2) && uint8_t(m_source.get(0)) == 0xe2 && uint8_t(m_source.get(1)) == 0x80 && (\n\t\tuint8_t(m_source.get(2)) == 0xa8 || uint8_t(m_source.get(2)) == 0xa9\n\t))\n\t\t// LS - U+2028, E2 80 A8  in utf8\n\t\t// PS - U+2029, E2 80 A9  in utf8\n\t\treturn true;\n\treturn false;\n}\n\nToken Scanner::scanString(bool const _isUnicode)\n{\n\tsize_t startPosition = m_source.position();\n\tchar const quote = m_char;\n\tadvance();  // consume quote\n\tLiteralScope literal(this, LITERAL_TYPE_STRING);\n\t// for source location comments we allow multiline string literals\n\twhile (m_char != quote && !isSourcePastEndOfInput() && (!isUnicodeLinebreak() || m_kind == ScannerKind::SpecialComment))\n\t{\n\t\tchar c = m_char;\n\t\tadvance();\n\n\t\tif (m_kind == ScannerKind::SpecialComment)\n\t\t{\n\t\t\tif (c == '\\\\')\n\t\t\t{\n\t\t\t\tif (isSourcePastEndOfInput())\n\t\t\t\t\treturn setError(ScannerError::IllegalEscapeSequence);\n\t\t\t\tadvance();\n\t\t\t}\n\t\t\telse\n\t\t\t\taddLiteralChar(c);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (c == '\\\\')\n\t\t\t{\n\t\t\t\tif (isSourcePastEndOfInput() || !scanEscape())\n\t\t\t\t\treturn setError(ScannerError::IllegalEscapeSequence);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Report error on non-printable characters in string literals, however\n\t\t\t\t// allow anything for unicode string literals, because their validity will\n\t\t\t\t// be verified later (in the syntax checker).\n\t\t\t\t//\n\t\t\t\t// We are using a manual range and not isprint() to avoid\n\t\t\t\t// any potential complications with locale.\n\t\t\t\tif (!_isUnicode && (static_cast<unsigned>(c) <= 0x1f || static_cast<unsigned>(c) >= 0x7f))\n\t\t\t\t{\n\t\t\t\t\tif (m_kind == ScannerKind::Yul)\n\t\t\t\t\t\treturn setError(ScannerError::IllegalCharacterInString);\n\t\t\t\t\treturn setError(ScannerError::UnicodeCharacterInNonUnicodeString);\n\t\t\t\t}\n\t\t\t\taddLiteralChar(c);\n\t\t\t}\n\t\t}\n\n\t}\n\tif (m_char != quote)\n\t\treturn setError(ScannerError::IllegalStringEndQuote);\n\n\tif (_isUnicode)\n\t{\n\t\tScannerError unicodeDirectionError = validateBiDiMarkup(m_source, startPosition);\n\t\tif (unicodeDirectionError != ScannerError::NoError)\n\t\t\treturn setError(unicodeDirectionError);\n\t}\n\n\tliteral.complete();\n\tadvance();  // consume quote\n\treturn _isUnicode ? Token::UnicodeStringLiteral : Token::StringLiteral;\n}\n\nToken Scanner::scanHexString()\n{\n\tchar const quote = m_char;\n\tadvance();  // consume quote\n\tLiteralScope literal(this, LITERAL_TYPE_STRING);\n\tbool allowUnderscore = false;\n\twhile (m_char != quote && !isSourcePastEndOfInput())\n\t{\n\t\tchar c = m_char;\n\n\t\tif (scanHexByte(c))\n\t\t{\n\t\t\taddLiteralChar(c);\n\t\t\tallowUnderscore = true;\n\t\t}\n\t\telse if (c == '_')\n\t\t{\n\t\t\tadvance();\n\t\t\tif (!allowUnderscore || m_char == quote)\n\t\t\t\treturn setError(ScannerError::IllegalNumberSeparator);\n\t\t\tallowUnderscore = false;\n\t\t}\n\t\telse\n\t\t\treturn setError(ScannerError::IllegalHexString);\n\t}\n\n\tif (m_char != quote)\n\t\treturn setError(ScannerError::IllegalStringEndQuote);\n\n\tliteral.complete();\n\tadvance();  // consume quote\n\treturn Token::HexStringLiteral;\n}\n\n// Parse for regex [:digit:]+(_[:digit:]+)*\nvoid Scanner::scanDecimalDigits()\n{\n\t// MUST begin with a decimal digit.\n\tif (!isDecimalDigit(m_char))\n\t\treturn;\n\n\t// May continue with decimal digit or underscore for grouping.\n\tdo\n\t\taddLiteralCharAndAdvance();\n\twhile (!m_source.isPastEndOfInput() && (isDecimalDigit(m_char) || m_char == '_'));\n\n\t// Defer further validation of underscore to SyntaxChecker.\n}\n\nToken Scanner::scanNumber(char _charSeen)\n{\n\tenum { DECIMAL, HEX, BINARY } kind = DECIMAL;\n\tLiteralScope literal(this, LITERAL_TYPE_NUMBER);\n\tif (_charSeen == '.')\n\t{\n\t\t// we have already seen a decimal point of the float\n\t\taddLiteralChar('.');\n\t\tif (m_char == '_')\n\t\t\treturn setError(ScannerError::IllegalToken);\n\t\tscanDecimalDigits();  // we know we have at least one digit\n\t}\n\telse\n\t{\n\t\tsolAssert(_charSeen == 0, \"\");\n\t\t// if the first character is '0' we must check for octals and hex\n\t\tif (m_char == '0')\n\t\t{\n\t\t\taddLiteralCharAndAdvance();\n\t\t\t// either 0, 0exxx, 0Exxx, 0.xxx or a hex number\n\t\t\tif (m_char == 'x')\n\t\t\t{\n\t\t\t\t// hex number\n\t\t\t\tkind = HEX;\n\t\t\t\taddLiteralCharAndAdvance();\n\t\t\t\tif (!isHexDigit(m_char))\n\t\t\t\t\treturn setError(ScannerError::IllegalHexDigit); // we must have at least one hex digit after 'x'\n\n\t\t\t\twhile (isHexDigit(m_char) || m_char == '_') // We keep the underscores for later validation\n\t\t\t\t\taddLiteralCharAndAdvance();\n\t\t\t}\n\t\t\telse if (isDecimalDigit(m_char))\n\t\t\t\t// We do not allow octal numbers\n\t\t\t\treturn setError(ScannerError::OctalNotAllowed);\n\t\t}\n\t\t// Parse decimal digits and allow trailing fractional part.\n\t\tif (kind == DECIMAL)\n\t\t{\n\t\t\tscanDecimalDigits();  // optional\n\t\t\tif (m_char == '.')\n\t\t\t{\n\t\t\t\tif (!m_source.isPastEndOfInput(1) && m_source.get(1) == '_')\n\t\t\t\t{\n\t\t\t\t\t// Assume the input may be a floating point number with leading '_' in fraction part.\n\t\t\t\t\t// Recover by consuming it all but returning `Illegal` right away.\n\t\t\t\t\taddLiteralCharAndAdvance(); // '.'\n\t\t\t\t\taddLiteralCharAndAdvance(); // '_'\n\t\t\t\t\tscanDecimalDigits();\n\t\t\t\t}\n\t\t\t\tif (m_source.isPastEndOfInput() || !isDecimalDigit(m_source.get(1)))\n\t\t\t\t{\n\t\t\t\t\t// A '.' has to be followed by a number.\n\t\t\t\t\tliteral.complete();\n\t\t\t\t\treturn Token::Number;\n\t\t\t\t}\n\t\t\t\taddLiteralCharAndAdvance();\n\t\t\t\tscanDecimalDigits();\n\t\t\t}\n\t\t}\n\t}\n\t// scan exponent, if any\n\tif (m_char == 'e' || m_char == 'E')\n\t{\n\t\tsolAssert(kind != HEX, \"'e'/'E' must be scanned as part of the hex number\");\n\t\tif (kind != DECIMAL)\n\t\t\treturn setError(ScannerError::IllegalExponent);\n\t\telse if (!m_source.isPastEndOfInput(1) && m_source.get(1) == '_')\n\t\t{\n\t\t\t// Recover from wrongly placed underscore as delimiter in literal with scientific\n\t\t\t// notation by consuming until the end.\n\t\t\taddLiteralCharAndAdvance(); // 'e'\n\t\t\taddLiteralCharAndAdvance(); // '_'\n\t\t\tscanDecimalDigits();\n\t\t\tliteral.complete();\n\t\t\treturn Token::Number;\n\t\t}\n\t\t// scan exponent\n\t\taddLiteralCharAndAdvance(); // 'e' | 'E'\n\t\tif (m_char == '+' || m_char == '-')\n\t\t\taddLiteralCharAndAdvance();\n\t\tif (!isDecimalDigit(m_char)) // we must have at least one decimal digit after 'e'/'E'\n\t\t\treturn setError(ScannerError::IllegalExponent);\n\t\tscanDecimalDigits();\n\t}\n\t// The source character immediately following a numeric literal must\n\t// not be an identifier start or a decimal digit; see ECMA-262\n\t// section 7.8.3, page 17 (note that we read only one decimal digit\n\t// if the value is 0).\n\tif (isDecimalDigit(m_char) || isIdentifierStart(m_char))\n\t\treturn setError(ScannerError::IllegalNumberEnd);\n\tliteral.complete();\n\treturn Token::Number;\n}\n\nstd::tuple<Token, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()\n{\n\tsolAssert(isIdentifierStart(m_char), \"\");\n\tLiteralScope literal(this, LITERAL_TYPE_STRING);\n\taddLiteralCharAndAdvance();\n\t// Scan the rest of the identifier characters.\n\twhile (isIdentifierPart(m_char) || (m_char == '.' && m_kind == ScannerKind::Yul))\n\t\taddLiteralCharAndAdvance();\n\tliteral.complete();\n\n\tauto const token = TokenTraits::fromIdentifierOrKeyword(m_tokens[NextNext].literal);\n\tswitch (m_kind)\n\t{\n\tcase ScannerKind::SpecialComment:\n\t\t// there are no keywords in special comments\n\t\treturn std::make_tuple(Token::Identifier, 0, 0);\n\tcase ScannerKind::Solidity:\n\t\t// Turn experimental Solidity keywords that are not keywords in legacy Solidity into identifiers.\n\t\tif (TokenTraits::isExperimentalSolidityOnlyKeyword(std::get<0>(token)))\n\t\t\treturn std::make_tuple(Token::Identifier, 0, 0);\n\t\tbreak;\n\tcase ScannerKind::Yul:\n\t\t// Turn Solidity identifier into a Yul keyword\n\t\tif (m_tokens[NextNext].literal == \"leave\")\n\t\t\treturn std::make_tuple(Token::Leave, 0, 0);\n\t\t// Turn non-Yul keywords into identifiers.\n\t\tif (!TokenTraits::isYulKeyword(std::get<0>(token)))\n\t\t\treturn std::make_tuple(Token::Identifier, 0, 0);\n\t\tbreak;\n\tcase ScannerKind::ExperimentalSolidity:\n\t\t// Turn legacy Solidity keywords that are not keywords in experimental Solidity into identifiers.\n\t\tif (!TokenTraits::isExperimentalSolidityKeyword(std::get<0>(token)))\n\t\t\treturn std::make_tuple(Token::Identifier, 0, 0);\n\t\tbreak;\n\t}\n\treturn token;\n}\n\n} // namespace solidity::langutil\n"
  },
  {
    "path": "liblangutil/Scanner.h",
    "content": "/*\n * This file is part of solidity.\n *\n * solidity is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * solidity is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with solidity.  If not, see <http://www.gnu.org/licenses/>.\n *\n * This file is derived from the file \"scanner.h\", which was part of the\n * V8 project. The original copyright header follows:\n *\n * Copyright 2006-2012, the V8 project authors. All rights reserved.\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n *   notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n *   copyright notice, this list of conditions and the following\n *   disclaimer in the documentation and/or other materials provided\n *   with the distribution.\n * * Neither the name of Google Inc. nor the names of its\n *   contributors may be used to endorse or promote products derived\n *   from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity scanner.\n */\n\n#pragma once\n\n#include <liblangutil/Token.h>\n#include <liblangutil/CharStream.h>\n#include <liblangutil/SourceLocation.h>\n\n#include <optional>\n#include <iosfwd>\n\nnamespace solidity::langutil\n{\n\nenum class ScannerKind\n{\n\tSolidity,\n\tYul,\n\tExperimentalSolidity,\n\tSpecialComment\n};\n\nenum class ScannerError\n{\n\tNoError,\n\n\tIllegalToken,\n\tIllegalHexString,\n\tIllegalHexDigit,\n\tIllegalCommentTerminator,\n\tIllegalEscapeSequence,\n\tUnicodeCharacterInNonUnicodeString,\n\tIllegalCharacterInString,\n\tIllegalStringEndQuote,\n\tIllegalNumberSeparator,\n\tIllegalExponent,\n\tIllegalNumberEnd,\n\n\tDirectionalOverrideUnderflow,\n\tDirectionalOverrideMismatch,\n\n\tOctalNotAllowed,\n};\n\nstd::string to_string(ScannerError _errorCode);\nstd::ostream& operator<<(std::ostream& os, ScannerError _errorCode);\n\nclass Scanner\n{\n\tfriend class LiteralScope;\npublic:\n\texplicit Scanner(CharStream& _source, ScannerKind _kind = ScannerKind::Solidity):\n\t\tm_source(_source),\n\t\tm_sourceName{std::make_shared<std::string>(_source.name())}\n\t{\n\t\treset();\n\t\tif (_kind != ScannerKind::Solidity)\n\t\t\tsetScannerMode(_kind);\n\t}\n\n\t/// Resets scanner to the start of input.\n\tvoid reset();\n\n\t/// Changes the scanner mode.\n\tvoid setScannerMode(ScannerKind _kind)\n\t{\n\t\tm_kind = _kind;\n\n\t\t// Invalidate lookahead buffer.\n\t\trescan();\n\t}\n\n\tCharStream const& charStream() const noexcept { return m_source; }\n\n\t/// @returns the next token and advances input\n\tToken next();\n\n\t/// Set scanner to a specific offset. This is used in error recovery.\n\tvoid setPosition(size_t _offset);\n\n\t///@{\n\t///@name Information about the current token\n\n\t/// @returns the current token\n\tToken currentToken() const\n\t{\n\t\treturn m_tokens[Current].token;\n\t}\n\tElementaryTypeNameToken currentElementaryTypeNameToken() const\n\t{\n\t\tunsigned firstSize;\n\t\tunsigned secondSize;\n\t\tstd::tie(firstSize, secondSize) = m_tokens[Current].extendedTokenInfo;\n\t\treturn ElementaryTypeNameToken(m_tokens[Current].token, firstSize, secondSize);\n\t}\n\n\tSourceLocation currentLocation() const { return m_tokens[Current].location; }\n\tstd::string const& currentLiteral() const { return m_tokens[Current].literal; }\n\tstd::tuple<unsigned, unsigned> const& currentTokenInfo() const { return m_tokens[Current].extendedTokenInfo; }\n\n\t/// Retrieves the last error that occurred during lexical analysis.\n\t/// @note If no error occurred, the value is undefined.\n\tScannerError currentError() const noexcept { return m_tokens[Current].error; }\n\t///@}\n\n\t///@{\n\t///@name Information about the current comment token\n\n\tSourceLocation currentCommentLocation() const { return m_skippedComments[Current].location; }\n\tstd::string const& currentCommentLiteral() const { return m_skippedComments[Current].literal; }\n\t/// Called by the parser during FunctionDefinition parsing to clear the current comment\n\tvoid clearCurrentCommentLiteral() { m_skippedComments[Current].literal.clear(); }\n\n\tScannerKind scannerKind() const { return m_kind; }\n\n\t///@}\n\n\t///@{\n\t///@name Information about the next token\n\n\t/// @returns the next token without advancing input.\n\tToken peekNextToken() const { return m_tokens[Next].token; }\n\tSourceLocation peekLocation() const { return m_tokens[Next].location; }\n\tstd::string const& peekLiteral() const { return m_tokens[Next].literal; }\n\n\tToken peekNextNextToken() const { return m_tokens[NextNext].token; }\n\t///@}\n\nprivate:\n\n\tinline Token setError(ScannerError _error) noexcept\n\t{\n\t\tm_tokens[NextNext].error = _error;\n\t\treturn Token::Illegal;\n\t}\n\n\t/// Used for the current and look-ahead token and comments\n\tstruct TokenDesc\n\t{\n\t\tToken token;\n\t\tSourceLocation location;\n\t\tstd::string literal;\n\t\tScannerError error = ScannerError::NoError;\n\t\tstd::tuple<unsigned, unsigned> extendedTokenInfo;\n\t};\n\n\t///@{\n\t///@name Literal buffer support\n\tinline void addLiteralChar(char c) { m_tokens[NextNext].literal.push_back(c); }\n\tinline void addCommentLiteralChar(char c) { m_skippedComments[NextNext].literal.push_back(c); }\n\tinline void addLiteralCharAndAdvance() { addLiteralChar(m_char); advance(); }\n\tvoid addUnicodeAsUTF8(unsigned codepoint);\n\t///@}\n\n\tbool advance() { m_char = m_source.advanceAndGet(); return !m_source.isPastEndOfInput(); }\n\tvoid rollback(size_t _amount) { m_char = m_source.rollback(_amount); }\n\t/// Rolls back to the start of the current token and re-runs the scanner.\n\tvoid rescan();\n\n\tinline Token selectErrorToken(ScannerError _err) { advance(); return setError(_err); }\n\tinline Token selectToken(Token _tok) { advance(); return _tok; }\n\t/// If the next character is _next, advance and return _then, otherwise return _else.\n\tinline Token selectToken(char _next, Token _then, Token _else);\n\n\tbool scanHexByte(char& o_scannedByte);\n\tstd::optional<unsigned> scanUnicode();\n\n\t/// Scans a single Solidity token.\n\tvoid scanToken();\n\n\t/// Skips all whitespace and @returns true if something was skipped.\n\tbool skipWhitespace();\n\t/// Skips all whitespace that are neither '\\r' nor '\\n'.\n\tbool skipWhitespaceExceptUnicodeLinebreak();\n\tToken skipSingleLineComment();\n\tToken skipMultiLineComment();\n\n\t/// Tests if current source position is CR, LF or CRLF.\n\tbool atEndOfLine() const;\n\n\t/// Tries to consume CR, LF or CRLF line terminators and returns success or failure.\n\tbool tryScanEndOfLine();\n\n\tvoid scanDecimalDigits();\n\tToken scanNumber(char _charSeen = 0);\n\tstd::tuple<Token, unsigned, unsigned> scanIdentifierOrKeyword();\n\n\tToken scanString(bool const _isUnicode);\n\tToken scanHexString();\n\t/// Scans a single line comment and returns its corrected end position.\n\tsize_t scanSingleLineDocComment();\n\tToken scanMultiLineDocComment();\n\t/// Scans a slash '/' and depending on the characters returns the appropriate token\n\tToken scanSlash();\n\n\t/// Scans an escape-sequence which is part of a string and adds the\n\t/// decoded character to the current literal. Returns true if a pattern\n\t/// is scanned.\n\tbool scanEscape();\n\n\t/// @returns true iff we are currently positioned at a unicode line break.\n\tbool isUnicodeLinebreak();\n\n\t/// Return the current source position.\n\tsize_t sourcePos() const { return m_source.position(); }\n\tbool isSourcePastEndOfInput() const { return m_source.isPastEndOfInput(); }\n\n\tenum TokenIndex { Current, Next, NextNext };\n\n\tTokenDesc m_skippedComments[3] = {}; // desc for the current, next and nextnext skipped comment\n\tTokenDesc m_tokens[3] = {}; // desc for the current, next and nextnext token\n\n\tCharStream& m_source;\n\tstd::shared_ptr<std::string const> m_sourceName;\n\n\tScannerKind m_kind = ScannerKind::Solidity;\n\n\t/// one character look-ahead, equals 0 at end of input\n\tchar m_char;\n};\n\n}\n"
  },
  {
    "path": "liblangutil/SemVerHandler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <chris@ethereum.org>\n * @date 2016\n * Utilities to handle semantic versioning.\n */\n\n#include <liblangutil/SemVerHandler.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <functional>\n#include <limits>\n#include <fmt/format.h>\n\nusing namespace std::string_literals;\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\n\nSemVerMatchExpressionParser::SemVerMatchExpressionParser(std::vector<Token> _tokens, std::vector<std::string> _literals):\n\tm_tokens(std::move(_tokens)), m_literals(std::move(_literals))\n{\n\tsolAssert(m_tokens.size() == m_literals.size(), \"\");\n}\n\nSemVerVersion::SemVerVersion(std::string const& _versionString)\n{\n\tauto i = _versionString.begin();\n\tauto end = _versionString.end();\n\n\tfor (unsigned level = 0; level < 3; ++level)\n\t{\n\t\tunsigned v = 0;\n\t\tfor (; i != end && '0' <= *i && *i <= '9'; ++i)\n\t\t\tv = v * 10 + unsigned(*i - '0');\n\t\tnumbers[level] = v;\n\t\tif (level < 2)\n\t\t{\n\t\t\tif (i == end || *i != '.')\n\t\t\t\tsolThrow(SemVerError, \"Invalid versionString: \"s + _versionString);\n\t\t\telse\n\t\t\t\t++i;\n\t\t}\n\t}\n\tif (i != end && *i == '-')\n\t{\n\t\tauto prereleaseStart = ++i;\n\t\twhile (i != end && *i != '+') ++i;\n\t\tprerelease = std::string(prereleaseStart, i);\n\t}\n\tif (i != end && *i == '+')\n\t{\n\t\tauto buildStart = ++i;\n\t\twhile (i != end) ++i;\n\t\tbuild = std::string(buildStart, i);\n\t}\n\tif (i != end)\n\t\tsolThrow(SemVerError, \"Invalid versionString \"s + _versionString);\n}\n\nbool SemVerMatchExpression::MatchComponent::matches(SemVerVersion const& _version) const\n{\n\tif (prefix == Token::BitNot)\n\t{\n\t\tMatchComponent comp = *this;\n\n\t\tcomp.prefix = Token::GreaterThanOrEqual;\n\t\tif (!comp.matches(_version))\n\t\t\treturn false;\n\n\t\tif (levelsPresent >= 2)\n\t\t\tcomp.levelsPresent = 2;\n\t\telse\n\t\t\tcomp.levelsPresent = 1;\n\t\tcomp.prefix = Token::LessThanOrEqual;\n\t\treturn comp.matches(_version);\n\t}\n\telse if (prefix == Token::BitXor)\n\t{\n\t\tMatchComponent comp = *this;\n\n\t\tcomp.prefix = Token::GreaterThanOrEqual;\n\t\tif (!comp.matches(_version))\n\t\t\treturn false;\n\n\t\tif (comp.version.numbers[0] == 0 && comp.levelsPresent != 1)\n\t\t\tcomp.levelsPresent = 2;\n\t\telse\n\t\t\tcomp.levelsPresent = 1;\n\t\tcomp.prefix = Token::LessThanOrEqual;\n\t\treturn comp.matches(_version);\n\t}\n\telse\n\t{\n\t\tint cmp = 0;\n\t\tbool didCompare = false;\n\t\tfor (unsigned i = 0; i < levelsPresent && cmp == 0; i++)\n\t\t\tif (version.numbers[i] != std::numeric_limits<unsigned>::max())\n\t\t\t{\n\t\t\t\tdidCompare = true;\n\t\t\t\tcmp = static_cast<int>(_version.numbers[i]) - static_cast<int>(version.numbers[i]);\n\t\t\t}\n\n\t\tif (cmp == 0 && !_version.prerelease.empty() && didCompare)\n\t\t\tcmp = -1;\n\n\t\tswitch (prefix)\n\t\t{\n\t\tcase Token::Assign:\n\t\t\treturn cmp == 0;\n\t\tcase Token::LessThan:\n\t\t\treturn cmp < 0;\n\t\tcase Token::LessThanOrEqual:\n\t\t\treturn cmp <= 0;\n\t\tcase Token::GreaterThan:\n\t\t\treturn cmp > 0;\n\t\tcase Token::GreaterThanOrEqual:\n\t\t\treturn cmp >= 0;\n\t\tdefault:\n\t\t\tsolAssert(false, \"Invalid SemVer expression\");\n\t\t}\n\t\treturn false;\n\t}\n}\n\nbool SemVerMatchExpression::Conjunction::matches(SemVerVersion const& _version) const\n{\n\tfor (auto const& component: components)\n\t\tif (!component.matches(_version))\n\t\t\treturn false;\n\treturn true;\n}\n\nbool SemVerMatchExpression::matches(SemVerVersion const& _version) const\n{\n\tif (!isValid())\n\t\treturn false;\n\tfor (auto const& range: m_disjunction)\n\t\tif (range.matches(_version))\n\t\t\treturn true;\n\treturn false;\n}\n\nSemVerMatchExpression SemVerMatchExpressionParser::parse()\n{\n\treset();\n\n\tif (m_tokens.empty())\n\t\tsolThrow(SemVerError, \"Empty version pragma.\");\n\n\ttry\n\t{\n\t\twhile (true)\n\t\t{\n\t\t\tparseMatchExpression();\n\t\t\tif (m_pos >= m_tokens.size())\n\t\t\t\tbreak;\n\t\t\tif (currentToken() != Token::Or)\n\t\t\t{\n\t\t\t\tsolThrow(\n\t\t\t\t\tSemVerError,\n\t\t\t\t\t\"You can only combine version ranges using the || operator.\"\n\t\t\t\t);\n\t\t\t}\n\t\t\tnextToken();\n\t\t}\n\t}\n\tcatch (SemVerError const& e)\n\t{\n\t\treset();\n\t\tthrow e;\n\t}\n\n\treturn m_expression;\n}\n\n\nvoid SemVerMatchExpressionParser::reset()\n{\n\tm_expression = SemVerMatchExpression();\n\tm_pos = 0;\n\tm_posInside = 0;\n}\n\nvoid SemVerMatchExpressionParser::parseMatchExpression()\n{\n\t// component - component (range)\n\t// or component component* (conjunction)\n\n\tSemVerMatchExpression::Conjunction range;\n\trange.components.push_back(parseMatchComponent());\n\tif (currentToken() == Token::Sub)\n\t{\n\t\trange.components[0].prefix = Token::GreaterThanOrEqual;\n\t\tnextToken();\n\t\trange.components.push_back(parseMatchComponent());\n\t\trange.components[1].prefix = Token::LessThanOrEqual;\n\t}\n\telse\n\t\twhile (currentToken() != Token::Or && currentToken() != Token::Illegal)\n\t\t\trange.components.push_back(parseMatchComponent());\n\tm_expression.m_disjunction.push_back(range);\n}\n\nSemVerMatchExpression::MatchComponent SemVerMatchExpressionParser::parseMatchComponent()\n{\n\tSemVerMatchExpression::MatchComponent component;\n\tToken token = currentToken();\n\n\tswitch (token)\n\t{\n\tcase Token::BitXor:\n\tcase Token::BitNot:\n\tcase Token::LessThan:\n\tcase Token::LessThanOrEqual:\n\tcase Token::GreaterThan:\n\tcase Token::GreaterThanOrEqual:\n\tcase Token::Assign:\n\t\tcomponent.prefix = token;\n\t\tnextToken();\n\t\tbreak;\n\tdefault:\n\t\tcomponent.prefix = Token::Assign;\n\t}\n\n\tcomponent.levelsPresent = 0;\n\twhile (component.levelsPresent < 3)\n\t{\n\t\tcomponent.version.numbers[component.levelsPresent] = parseVersionPart();\n\t\tcomponent.levelsPresent++;\n\t\tif (currentChar() == '.')\n\t\t\tnextChar();\n\t\telse\n\t\t\tbreak;\n\t}\n\t// TODO we do not support pre and build version qualifiers for now in match expressions\n\t// (but we do support them in the actual versions)\n\treturn component;\n}\n\nunsigned SemVerMatchExpressionParser::parseVersionPart()\n{\n\tauto startPos = m_pos;\n\tchar c = currentChar();\n\tnextChar();\n\tif (c == 'x' || c == 'X' || c == '*')\n\t\treturn unsigned(-1);\n\telse if (c == '0')\n\t\treturn 0;\n\telse if ('1' <= c && c <= '9')\n\t{\n\t\tauto v = static_cast<unsigned>(c - '0');\n\t\t// If we skip to the next token, the current number is terminated.\n\t\twhile (m_pos == startPos && '0' <= currentChar() && currentChar() <= '9')\n\t\t{\n\t\t\tc = currentChar();\n\t\t\tif (v * 10 < v || v * 10 + static_cast<unsigned>(c - '0') < v * 10)\n\t\t\t\tsolThrow(SemVerError, \"Integer too large to be used in a version number.\");\n\t\t\tv = v * 10 + static_cast<unsigned>(c - '0');\n\t\t\tnextChar();\n\t\t}\n\t\treturn v;\n\t}\n\telse if (c == char(-1))\n\t\tsolThrow(SemVerError, \"Expected version number but reached end of pragma.\");\n\telse\n\t\tsolThrow(\n\t\t\tSemVerError, fmt::format(\n\t\t\t\t\"Expected the start of a version number but instead found character '{}'. \"\n\t\t\t\t\"Version number is invalid or the pragma is not terminated with a semicolon.\",\n\t\t\t\tc\n\t\t\t)\n\t\t);\n}\n\nchar SemVerMatchExpressionParser::currentChar() const\n{\n\tif (m_pos >= m_literals.size())\n\t\treturn char(-1);\n\tif (m_posInside >= m_literals[m_pos].size())\n\t\treturn char(-1);\n\treturn m_literals[m_pos][m_posInside];\n}\n\nchar SemVerMatchExpressionParser::nextChar()\n{\n\tif (m_pos < m_literals.size())\n\t{\n\t\tif (m_posInside + 1 >= m_literals[m_pos].size())\n\t\t\tnextToken();\n\t\telse\n\t\t\t++m_posInside;\n\t}\n\treturn currentChar();\n}\n\nToken SemVerMatchExpressionParser::currentToken() const\n{\n\tif (m_pos < m_tokens.size())\n\t\treturn m_tokens[m_pos];\n\telse\n\t\treturn Token::Illegal;\n}\n\nvoid SemVerMatchExpressionParser::nextToken()\n{\n\t++m_pos;\n\tm_posInside = 0;\n}\n"
  },
  {
    "path": "liblangutil/SemVerHandler.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <chris@ethereum.org>\n * @date 2016\n * Utilities to handle semantic versioning.\n */\n\n#pragma once\n\n#include <liblangutil/Token.h>\n#include <libsolutil/Assertions.h>\n#include <liblangutil/Exceptions.h>\n\n#include <string>\n#include <utility>\n#include <vector>\n\nnamespace solidity::langutil\n{\n\nstruct SemVerError: public util::Exception\n{\n\n};\n\n#undef major\n#undef minor\n\nstruct SemVerVersion\n{\n\tunsigned numbers[3];\n\tstd::string prerelease;\n\tstd::string build;\n\n\tunsigned major() const { return numbers[0]; }\n\tunsigned minor() const { return numbers[1]; }\n\tunsigned patch() const { return numbers[2]; }\n\n\tbool isPrerelease() const { return !prerelease.empty(); }\n\n\texplicit SemVerVersion(std::string const& _versionString = \"0.0.0\");\n};\n\nstruct SemVerMatchExpression\n{\n\tbool matches(SemVerVersion const& _version) const;\n\n\tbool isValid() const { return !m_disjunction.empty(); }\n\n\tstruct MatchComponent\n\t{\n\t\t/// Prefix from < > <= >= ~ ^\n\t\tToken prefix = Token::Illegal;\n\t\t/// Version, where unsigned(-1) in major, minor or patch denotes '*', 'x' or 'X'\n\t\tSemVerVersion version;\n\t\t/// Whether we have 1, 1.2 or 1.2.4\n\t\tunsigned levelsPresent = 1;\n\t\tbool matches(SemVerVersion const& _version) const;\n\t};\n\n\tstruct Conjunction\n\t{\n\t\tstd::vector<MatchComponent> components;\n\t\tbool matches(SemVerVersion const& _version) const;\n\t};\n\n\tstd::vector<Conjunction> m_disjunction;\n};\n\nclass SemVerMatchExpressionParser\n{\npublic:\n\tSemVerMatchExpressionParser(std::vector<Token> _tokens, std::vector<std::string> _literals);\n\n\t/// Returns an expression if it was parsable, or throws a SemVerError otherwise.\n\tSemVerMatchExpression parse();\n\nprivate:\n\tvoid reset();\n\n\tvoid parseMatchExpression();\n\tSemVerMatchExpression::MatchComponent parseMatchComponent();\n\tunsigned parseVersionPart();\n\n\tchar currentChar() const;\n\tchar nextChar();\n\tToken currentToken() const;\n\tvoid nextToken();\n\n\tstd::vector<Token> m_tokens;\n\tstd::vector<std::string> m_literals;\n\n\tunsigned m_pos = 0;\n\tunsigned m_posInside = 0;\n\n\tSemVerMatchExpression m_expression;\n};\n\n}\n"
  },
  {
    "path": "liblangutil/SourceLocation.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <liblangutil/Exceptions.h>\n\n#include <boost/algorithm/string/split.hpp>\n#include <boost/algorithm/string.hpp>\n\n#include <iostream>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\n\nSourceLocation solidity::langutil::parseSourceLocation(std::string const& _input, std::vector<std::shared_ptr<std::string const>> const& _sourceNames)\n{\n\t// Expected input: \"start:length:sourceindex\"\n\tenum SrcElem: size_t { Start, Length, Index };\n\n\tstd::vector<std::string> pos;\n\n\tboost::algorithm::split(pos, _input, boost::is_any_of(\":\"));\n\n\tsolAssert(pos.size() == 3, \"SourceLocation string must have 3 colon separated numeric fields.\");\n\tauto const sourceIndex = stoi(pos[Index]);\n\n\tastAssert(\n\t\tsourceIndex == -1 || (0 <= sourceIndex && static_cast<size_t>(sourceIndex) < _sourceNames.size()),\n\t\t\"'src'-field ill-formatted or src-index too high\"\n\t);\n\n\tint start = stoi(pos[Start]);\n\tint end = start + stoi(pos[Length]);\n\n\tSourceLocation result{start, end, {}};\n\tif (sourceIndex != -1)\n\t\tresult.sourceName = _sourceNames.at(static_cast<size_t>(sourceIndex));\n\treturn result;\n}\n\nstd::ostream& solidity::langutil::operator<<(std::ostream& _out, SourceLocation const& _location)\n{\n\tif (!_location.isValid())\n\t\treturn _out << \"NO_LOCATION_SPECIFIED\";\n\n\tif (_location.sourceName)\n\t\t_out << *_location.sourceName;\n\n\t_out << \"[\" << _location.start << \",\" << _location.end << \"]\";\n\n\treturn _out;\n}\n"
  },
  {
    "path": "liblangutil/SourceLocation.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Lefteris Karapetsas <lefteris@ethdev.com>\n * @date 2015\n * Represents a location in a source file\n */\n\n#pragma once\n\n#include <iosfwd>\n#include <memory>\n#include <string>\n#include <tuple>\n#include <vector>\n\nnamespace solidity::langutil\n{\n\n/**\n * Representation of an interval of source positions.\n * The interval includes start and excludes end.\n */\nstruct SourceLocation\n{\n\tbool operator==(SourceLocation const& _other) const\n\t{\n\t\treturn start == _other.start && end == _other.end && equalSources(_other);\n\t}\n\tbool operator!=(SourceLocation const& _other) const { return !operator==(_other); }\n\n\tbool operator<(SourceLocation const& _other) const\n\t{\n\t\tif (!sourceName || !_other.sourceName)\n\t\t\treturn std::make_tuple(int(!!sourceName), start, end) < std::make_tuple(int(!!_other.sourceName), _other.start, _other.end);\n\t\telse\n\t\t\treturn std::make_tuple(*sourceName, start, end) < std::make_tuple(*_other.sourceName, _other.start, _other.end);\n\t}\n\n\tbool contains(SourceLocation const& _other) const\n\t{\n\t\tif (!hasText() || !_other.hasText() || !equalSources(_other))\n\t\t\treturn false;\n\t\treturn start <= _other.start && _other.end <= end;\n\t}\n\n\tbool containsOffset(int _pos) const\n\t{\n\t\tif (!hasText() || _pos < 0)\n\t\t\treturn false;\n\t\treturn start <= _pos && _pos < end;\n\t}\n\n\tbool intersects(SourceLocation const& _other) const\n\t{\n\t\tif (!hasText() || !_other.hasText() || !equalSources(_other))\n\t\t\treturn false;\n\t\treturn _other.start < end && start < _other.end;\n\t}\n\n\tbool equalSources(SourceLocation const& _other) const\n\t{\n\t\tif (!!sourceName != !!_other.sourceName)\n\t\t\treturn false;\n\t\tif (sourceName && *sourceName != *_other.sourceName)\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\n\tbool isValid() const { return sourceName || start != -1 || end != -1; }\n\n\tbool hasText() const { return sourceName && 0 <= start && start <= end; }\n\n\t/// @returns the smallest SourceLocation that contains both @param _a and @param _b.\n\t/// Assumes that @param _a and @param _b refer to the same source (exception: if the source of either one\n\t/// is unset, the source of the other will be used for the result, even if that is unset as well).\n\t/// Invalid start and end positions (with value of -1) are ignored (if start or end are -1 for both @param _a and\n\t/// @param _b, then start resp. end of the result will be -1 as well).\n\tstatic SourceLocation smallestCovering(SourceLocation _a, SourceLocation const& _b)\n\t{\n\t\tif (!_a.sourceName)\n\t\t\t_a.sourceName = _b.sourceName;\n\n\t\tif (_a.start < 0)\n\t\t\t_a.start = _b.start;\n\t\telse if (_b.start >= 0 && _b.start < _a.start)\n\t\t\t_a.start = _b.start;\n\t\tif (_b.end > _a.end)\n\t\t\t_a.end = _b.end;\n\n\t\treturn _a;\n\t}\n\n\tint start = -1;\n\tint end = -1;\n\tstd::shared_ptr<std::string const> sourceName;\n};\n\nSourceLocation parseSourceLocation(\n\tstd::string const& _input,\n\tstd::vector<std::shared_ptr<std::string const>> const& _sourceNames\n);\n\n/// Stream output for Location (used e.g. in boost exceptions).\nstd::ostream& operator<<(std::ostream& _out, SourceLocation const& _location);\n\n\n/**\n * Alternative, line-column-based representation for source locations.\n * Both line and column are zero-based.\n * If used as a range, the second location is considered exclusive.\n * Negative values are invalid.\n */\nstruct LineColumn\n{\n\t/// Line value, can be between zero and number of `\\n` characters in the source file.\n\tint line = -1;\n\t/// Column value, can be between zero and number of characters in the line (inclusive).\n\tint column = -1;\n\n\tLineColumn() = default;\n\texplicit LineColumn(int _line, int _column): line(_line), column(_column) {}\n};\n\n\n}\n"
  },
  {
    "path": "liblangutil/SourceReferenceExtractor.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <liblangutil/SourceReferenceExtractor.h>\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/CharStreamProvider.h>\n#include <liblangutil/CharStream.h>\n\n#include <algorithm>\n#include <cmath>\n#include <variant>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\n\nSourceReferenceExtractor::Message SourceReferenceExtractor::extract(\n\tCharStreamProvider const& _charStreamProvider,\n\tutil::Exception const& _exception,\n\tstd::variant<Error::Type, Error::Severity> _typeOrSeverity\n)\n{\n\tSourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(_exception);\n\n\tstd::string const* message = boost::get_error_info<util::errinfo_comment>(_exception);\n\tSourceReference primary = extract(_charStreamProvider, location, message ? *message : \"\");\n\n\tstd::vector<SourceReference> secondary;\n\tauto secondaryLocation = boost::get_error_info<errinfo_secondarySourceLocation>(_exception);\n\tif (secondaryLocation && !secondaryLocation->infos.empty())\n\t\tfor (auto const& info: secondaryLocation->infos)\n\t\t\tsecondary.emplace_back(extract(_charStreamProvider, &info.second, info.first));\n\n\treturn Message{std::move(primary), _typeOrSeverity, std::move(secondary), std::nullopt};\n}\n\nSourceReferenceExtractor::Message SourceReferenceExtractor::extract(\n\tCharStreamProvider const& _charStreamProvider,\n\tError const& _error,\n\tstd::variant<Error::Type, Error::Severity> _typeOrSeverity\n)\n{\n\tMessage message = extract(_charStreamProvider, static_cast<util::Exception>(_error), _typeOrSeverity);\n\tmessage.errorId = _error.errorId();\n\treturn message;\n}\n\nSourceReference SourceReferenceExtractor::extract(\n\tCharStreamProvider const& _charStreamProvider,\n\tSourceLocation const* _location,\n\tstd::string message\n)\n{\n\tif (!_location || !_location->sourceName) // Nothing we can extract here\n\t\treturn SourceReference::MessageOnly(std::move(message));\n\n\tif (!_location->hasText()) // No source text, so we can only extract the source name\n\t\treturn SourceReference::MessageOnly(std::move(message), *_location->sourceName);\n\n\tCharStream const& charStream = _charStreamProvider.charStream(*_location->sourceName);\n\n\tLineColumn const interest = charStream.translatePositionToLineColumn(_location->start);\n\tLineColumn start = interest;\n\tLineColumn end = charStream.translatePositionToLineColumn(_location->end);\n\tbool const isMultiline = start.line != end.line;\n\n\tstd::string line = charStream.lineAtPosition(_location->start);\n\n\tint locationLength =\n\t\tisMultiline ?\n\t\t\tint(line.length()) - start.column :\n\t\t\tend.column - start.column;\n\n\tif (locationLength > 150)\n\t{\n\t\tauto const lhs = static_cast<size_t>(start.column) + 35;\n\t\tstd::string::size_type const rhs = (isMultiline ? line.length() : static_cast<size_t>(end.column)) - 35;\n\t\tline = line.substr(0, lhs) + \" ... \" + line.substr(rhs);\n\t\tend.column = start.column + 75;\n\t\tlocationLength = 75;\n\t}\n\n\tif (line.length() > 150)\n\t{\n\t\tint const len = static_cast<int>(line.length());\n\t\tline = line.substr(\n\t\t\tstatic_cast<size_t>(std::max(0, start.column - 35)),\n\t\t\tstatic_cast<size_t>(std::min(start.column, 35)) + static_cast<size_t>(\n\t\t\t\tstd::min(locationLength + 35, len - start.column)\n\t\t\t)\n\t\t);\n\t\tif (start.column + locationLength + 35 < len)\n\t\t\tline += \" ...\";\n\t\tif (start.column > 35)\n\t\t{\n\t\t\tline = \" ... \" + line;\n\t\t\tstart.column = 40;\n\t\t}\n\t\tend.column = start.column + static_cast<int>(locationLength);\n\t}\n\n\treturn SourceReference{\n\t\tstd::move(message),\n\t\t*_location->sourceName,\n\t\tinterest,\n\t\tisMultiline,\n\t\tline,\n\t\tstd::min(start.column, static_cast<int>(line.length())),\n\t\tstd::min(end.column, static_cast<int>(line.length()))\n\t};\n}\n"
  },
  {
    "path": "liblangutil/SourceReferenceExtractor.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <liblangutil/Exceptions.h>\n\n#include <iosfwd>\n#include <optional>\n#include <string>\n#include <tuple>\n#include <vector>\n#include <variant>\n\nnamespace solidity::langutil\n{\n\nclass CharStreamProvider;\n\nstruct SourceReference\n{\n\tstd::string message;      ///< A message that relates to this source reference (such as a warning, info or an error message).\n\tstd::string sourceName;   ///< Underlying source name (for example the filename).\n\tLineColumn position;      ///< Actual (error) position this source reference is surrounding.\n\tbool multiline = {false}; ///< Indicates whether the actual SourceReference is truncated to one line.\n\tstd::string text;         ///< Extracted source code text (potentially truncated if multiline or too long).\n\tint startColumn = {-1};   ///< Highlighting range-start of text field.\n\tint endColumn = {-1};     ///< Highlighting range-end of text field.\n\n\t/// Constructs a SourceReference containing a message only.\n\tstatic SourceReference MessageOnly(std::string _msg, std::string _sourceName = {})\n\t{\n\t\tSourceReference sref;\n\t\tsref.message = std::move(_msg);\n\t\tsref.sourceName = std::move(_sourceName);\n\t\treturn sref;\n\t}\n};\n\nnamespace SourceReferenceExtractor\n{\n\tstruct Message\n\t{\n\t\tSourceReference primary;\n\t\tstd::variant<Error::Type, Error::Severity> _typeOrSeverity;\n\t\tstd::vector<SourceReference> secondary;\n\t\tstd::optional<ErrorId> errorId;\n\t};\n\n\tMessage extract(\n\t\tCharStreamProvider const& _charStreamProvider,\n\t\tutil::Exception const& _exception,\n\t\tstd::variant<Error::Type, Error::Severity> _typeOrSeverity\n\t);\n\tMessage extract(\n\t\tCharStreamProvider const& _charStreamProvider,\n\t\tError const& _error,\n\t\tstd::variant<Error::Type, Error::Severity> _typeOrSeverity\n\t);\n\tMessage extract(CharStreamProvider const& _charStreamProvider, Error const& _error);\n\tSourceReference extract(CharStreamProvider const& _charStreamProvider, SourceLocation const* _location, std::string message = \"\");\n}\n\n}\n"
  },
  {
    "path": "liblangutil/SourceReferenceFormatter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Formatting functions for errors referencing positions and locations in the source.\n */\n\n#include <liblangutil/SourceReferenceFormatter.h>\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/CharStream.h>\n#include <liblangutil/CharStreamProvider.h>\n#include <libsolutil/UTF8.h>\n#include <iomanip>\n#include <string_view>\n#include <variant>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\nusing namespace solidity::util::formatting;\n\nnamespace\n{\n\nstd::string replaceNonTabs(std::string_view _utf8Input, char _filler)\n{\n\tstd::string output;\n\tfor (char const c: _utf8Input)\n\t\tif ((c & 0xc0) != 0x80)\n\t\t\toutput.push_back(c == '\\t' ? '\\t' : _filler);\n\treturn output;\n}\n\n}\n\nstd::string SourceReferenceFormatter::formatErrorInformation(Error const& _error, CharStream const& _charStream)\n{\n\treturn formatErrorInformation(\n\t\t_error,\n\t\tSingletonCharStreamProvider(_charStream)\n\t);\n}\n\nchar const* SourceReferenceFormatter::errorTextColor(Error::Severity _severity)\n{\n\tswitch (_severity)\n\t{\n\tcase Error::Severity::Error: return RED;\n\tcase Error::Severity::Warning: return YELLOW;\n\tcase Error::Severity::Info: return WHITE;\n\t}\n\tutil::unreachable();\n}\n\nchar const* SourceReferenceFormatter::errorHighlightColor(Error::Severity _severity)\n{\n\tswitch (_severity)\n\t{\n\tcase Error::Severity::Error: return RED_BACKGROUND;\n\tcase Error::Severity::Warning: return ORANGE_BACKGROUND_256;\n\tcase Error::Severity::Info: return GRAY_BACKGROUND;\n\t}\n\tutil::unreachable();\n}\n\nAnsiColorized SourceReferenceFormatter::normalColored() const\n{\n\treturn AnsiColorized(m_stream, m_colored, {WHITE});\n}\n\nAnsiColorized SourceReferenceFormatter::frameColored() const\n{\n\treturn AnsiColorized(m_stream, m_colored, {BOLD, BLUE});\n}\n\nAnsiColorized SourceReferenceFormatter::errorColored(std::ostream& _stream, bool _colored, Error::Severity _severity)\n{\n\treturn AnsiColorized(_stream, _colored, {BOLD, errorTextColor(_severity)});\n}\n\nAnsiColorized SourceReferenceFormatter::messageColored(std::ostream& _stream, bool _colored)\n{\n\treturn AnsiColorized(_stream, _colored, {BOLD, WHITE});\n}\n\nAnsiColorized SourceReferenceFormatter::secondaryColored() const\n{\n\treturn AnsiColorized(m_stream, m_colored, {BOLD, CYAN});\n}\n\nAnsiColorized SourceReferenceFormatter::highlightColored() const\n{\n\treturn AnsiColorized(m_stream, m_colored, {YELLOW});\n}\n\nAnsiColorized SourceReferenceFormatter::diagColored() const\n{\n\treturn AnsiColorized(m_stream, m_colored, {BOLD, YELLOW});\n}\n\nvoid SourceReferenceFormatter::printSourceLocation(SourceReference const& _ref)\n{\n\tif (_ref.position.line < 0)\n\t{\n\t\tif (_ref.sourceName.empty())\n\t\t\treturn; // Nothing we can print here\n\n\t\tframeColored() << \"-->\";\n\t\tm_stream << ' ' << _ref.sourceName << '\\n';\n\t\treturn; // No line available, nothing else to print\n\t}\n\n\tstd::string line = std::to_string(_ref.position.line + 1); // one-based line number as string\n\tstd::string leftpad = std::string(line.size(), ' ');\n\n\t// line 0: source name\n\tm_stream << leftpad;\n\tframeColored() << \"-->\";\n\tm_stream << ' ' << _ref.sourceName << ':' << line << ':' << (_ref.position.column + 1) << \":\\n\";\n\n\tstd::string_view text = _ref.text;\n\n\tif (m_charStreamProvider.charStream(_ref.sourceName).isImportedFromAST())\n\t\treturn;\n\n\tif (!_ref.multiline)\n\t{\n\t\tsize_t const locationLength = static_cast<size_t>(_ref.endColumn - _ref.startColumn);\n\n\t\t// line 1:\n\t\tm_stream << leftpad << ' ';\n\t\tframeColored() << '|';\n\t\tm_stream << '\\n';\n\n\t\t// line 2:\n\t\tframeColored() << line << \" |\";\n\n\t\tm_stream << ' ' << text.substr(0, static_cast<size_t>(_ref.startColumn));\n\t\thighlightColored() << text.substr(static_cast<size_t>(_ref.startColumn), locationLength);\n\t\tm_stream << text.substr(static_cast<size_t>(_ref.endColumn)) << '\\n';\n\n\t\t// line 3:\n\t\tm_stream << leftpad << ' ';\n\t\tframeColored() << '|';\n\n\t\tm_stream << ' ' << replaceNonTabs(text.substr(0, static_cast<size_t>(_ref.startColumn)), ' ');\n\t\tdiagColored() << (\n\t\t\tlocationLength == 0 ?\n\t\t\t\"^\" :\n\t\t\treplaceNonTabs(text.substr(static_cast<size_t>(_ref.startColumn), locationLength), '^')\n\t\t);\n\t\tm_stream << '\\n';\n\t}\n\telse\n\t{\n\t\t// line 1:\n\t\tm_stream << leftpad << ' ';\n\t\tframeColored() << '|';\n\t\tm_stream << '\\n';\n\n\t\t// line 2:\n\t\tframeColored() << line << \" |\";\n\t\tm_stream << ' ' << text.substr(0, static_cast<size_t>(_ref.startColumn));\n\t\thighlightColored() << text.substr(static_cast<size_t>(_ref.startColumn)) << '\\n';\n\n\t\t// line 3:\n\t\tm_stream << leftpad << ' ';\n\t\tframeColored() << '|';\n\t\tm_stream << ' ' << replaceNonTabs(text.substr(0, static_cast<size_t>(_ref.startColumn)), ' ');\n\t\tdiagColored() << \"^ (Relevant source part starts here and spans across multiple lines).\";\n\t\tm_stream << '\\n';\n\t}\n}\n\nvoid SourceReferenceFormatter::printPrimaryMessage(\n\tstd::ostream& _stream,\n\tstd::string _message,\n\tstd::variant<Error::Type, Error::Severity> _typeOrSeverity,\n\tstd::optional<ErrorId> _errorId,\n\tbool _colored,\n\tbool _withErrorIds\n)\n{\n\terrorColored(_stream, _colored, Error::errorSeverityOrType(_typeOrSeverity)) << Error::formatTypeOrSeverity(_typeOrSeverity);\n\n\tif (_withErrorIds && _errorId.has_value())\n\t\terrorColored(_stream, _colored, Error::errorSeverityOrType(_typeOrSeverity)) << \" (\" << _errorId.value().error << \")\";\n\n\tmessageColored(_stream, _colored) << \": \" << _message << '\\n';\n}\n\nvoid SourceReferenceFormatter::printExceptionInformation(SourceReferenceExtractor::Message const& _msg)\n{\n\tprintPrimaryMessage(m_stream, _msg.primary.message, _msg._typeOrSeverity, _msg.errorId, m_colored, m_withErrorIds);\n\tprintSourceLocation(_msg.primary);\n\n\tfor (auto const& secondary: _msg.secondary)\n\t{\n\t\tsecondaryColored() << \"Note\";\n\t\tmessageColored() << \":\" << (secondary.message.empty() ? \"\" : (\" \" + secondary.message)) << '\\n';\n\t\tprintSourceLocation(secondary);\n\t}\n\n\tm_stream << '\\n';\n}\n\nvoid SourceReferenceFormatter::printExceptionInformation(util::Exception const& _exception, Error::Type _type)\n{\n\tprintExceptionInformation(SourceReferenceExtractor::extract(m_charStreamProvider, _exception, _type));\n}\n\nvoid SourceReferenceFormatter::printExceptionInformation(util::Exception const& _exception, Error::Severity _severity)\n{\n\tprintExceptionInformation(SourceReferenceExtractor::extract(m_charStreamProvider, _exception, _severity));\n}\n\nvoid SourceReferenceFormatter::printErrorInformation(ErrorList const& _errors)\n{\n\tfor (auto const& error: _errors)\n\t\tprintErrorInformation(*error);\n}\n\nvoid SourceReferenceFormatter::printErrorInformation(Error const& _error)\n{\n\tSourceReferenceExtractor::Message message =\n\t\tSourceReferenceExtractor::extract(\n\t\t\tm_charStreamProvider,\n\t\t\t_error,\n\t\t\tError::errorSeverity(_error.type())\n\t\t);\n\tprintExceptionInformation(message);\n}\n"
  },
  {
    "path": "liblangutil/SourceReferenceFormatter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Formatting functions for errors referencing positions and locations in the source.\n */\n\n#pragma once\n\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/SourceReferenceExtractor.h>\n\n#include <libsolutil/AnsiColorized.h>\n\n#include <ostream>\n#include <sstream>\n#include <functional>\n\nnamespace solidity::langutil\n{\n\nclass CharStream;\nclass CharStreamProvider;\nstruct SourceLocation;\n\nclass SourceReferenceFormatter\n{\npublic:\n\tSourceReferenceFormatter(\n\t\tstd::ostream& _stream,\n\t\tCharStreamProvider const& _charStreamProvider,\n\t\tbool _colored,\n\t\tbool _withErrorIds\n\t):\n\t\tm_stream(_stream),\n\t\tm_charStreamProvider(_charStreamProvider),\n\t\tm_colored(_colored),\n\t\tm_withErrorIds(_withErrorIds)\n\t{}\n\n\t// WARNING: Use the xyzErrorInformation() variants over xyzExceptionInformation() when you\n\t// do have access to an Error instance. Error is implicitly convertible to util::Exception\n\t// but the conversion loses the error ID.\n\n\t/// Prints source location if it is given.\n\tvoid printSourceLocation(SourceReference const& _ref);\n\tvoid printExceptionInformation(SourceReferenceExtractor::Message const& _msg);\n\tvoid printExceptionInformation(util::Exception const& _exception, Error::Type _type);\n\tvoid printExceptionInformation(util::Exception const& _exception, Error::Severity _severity);\n\tvoid printErrorInformation(langutil::ErrorList const& _errors);\n\tvoid printErrorInformation(Error const& _error);\n\n\tstatic std::string formatExceptionInformation(\n\t\tutil::Exception const& _exception,\n\t\tError::Type _type,\n\t\tCharStreamProvider const& _charStreamProvider,\n\t\tbool _colored = false\n\t)\n\t{\n\t\tstd::ostringstream errorOutput;\n\t\tSourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, false /* _withErrorIds */);\n\t\tformatter.printExceptionInformation(_exception, _type);\n\t\treturn errorOutput.str();\n\t}\n\n\tstatic std::string formatExceptionInformation(\n\t\tutil::Exception const& _exception,\n\t\tError::Severity _severity,\n\t\tCharStreamProvider const& _charStreamProvider,\n\t\tbool _colored = false\n\t)\n\t{\n\t\tstd::ostringstream errorOutput;\n\t\tSourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, false /* _withErrorIds */);\n\t\tformatter.printExceptionInformation(_exception, _severity);\n\t\treturn errorOutput.str();\n\t}\n\n\tstatic std::string formatErrorInformation(\n\t\tError const& _error,\n\t\tCharStreamProvider const& _charStreamProvider,\n\t\tbool _colored = false,\n\t\tbool _withErrorIds = false\n\t)\n\t{\n\t\tstd::ostringstream errorOutput;\n\t\tSourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, _withErrorIds);\n\t\tformatter.printErrorInformation(_error);\n\t\treturn errorOutput.str();\n\t}\n\n\tstatic std::string formatErrorInformation(\n\t\tlangutil::ErrorList const& _errors,\n\t\tCharStreamProvider const& _charStreamProvider,\n\t\tbool _colored = false,\n\t\tbool _withErrorIds = false\n\t)\n\t{\n\t\tstd::ostringstream errorOutput;\n\t\tSourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, _withErrorIds);\n\t\tformatter.printErrorInformation(_errors);\n\t\treturn errorOutput.str();\n\t}\n\n\tstatic std::string formatErrorInformation(Error const& _error, CharStream const& _charStream);\n\n\tstatic void printPrimaryMessage(\n\t\tstd::ostream& _stream,\n\t\tstd::string _message,\n\t\tstd::variant<Error::Type, Error::Severity> _typeOrSeverity,\n\t\tstd::optional<ErrorId> _errorId = std::nullopt,\n\t\tbool _colored = false,\n\t\tbool _withErrorIds = false\n\t);\n\n\t/// The default text color for printing error messages of a given severity in the terminal.\n\t/// Assumes a dark background color.\n\tstatic char const* errorTextColor(Error::Severity _severity);\n\n\t/// The default background color for highlighting source fragments corresponding to an error\n\t/// of a given severity in the terminal. Assumes a light text color.\n\t/// @note This is *not* meant to be used for the same text in combination with @a errorTextColor().\n\t///       It's an alternative way to highlight it, while preserving the original text color.\n\tstatic char const* errorHighlightColor(Error::Severity _severity);\n\nprivate:\n\tutil::AnsiColorized normalColored() const;\n\tutil::AnsiColorized frameColored() const;\n\tutil::AnsiColorized errorColored(Error::Severity _severity) const { return errorColored(m_stream, m_colored, _severity); }\n\tutil::AnsiColorized messageColored() const { return messageColored(m_stream, m_colored); }\n\tutil::AnsiColorized secondaryColored() const;\n\tutil::AnsiColorized highlightColored() const;\n\tutil::AnsiColorized diagColored() const;\n\n\tstatic util::AnsiColorized errorColored(std::ostream& _stream, bool _colored, langutil::Error::Severity _severity);\n\tstatic util::AnsiColorized messageColored(std::ostream& _stream, bool _colored);\n\nprivate:\n\tstd::ostream& m_stream;\n\tCharStreamProvider const& m_charStreamProvider;\n\tbool m_colored;\n\tbool m_withErrorIds;\n};\n\n}\n"
  },
  {
    "path": "liblangutil/Token.cpp",
    "content": "// Copyright 2006-2012, the V8 project authors. All rights reserved.\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//    * Redistributions of source code must retain the above copyright\n//      notice, this list of conditions and the following disclaimer.\n//    * Redistributions in binary form must reproduce the above\n//      copyright notice, this list of conditions and the following\n//      disclaimer in the documentation and/or other materials provided\n//      with the distribution.\n//    * Neither the name of Google Inc. nor the names of its\n//      contributors may be used to endorse or promote products derived\n//      from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Modifications as part of solidity under the following license:\n//\n// solidity is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// solidity is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with solidity.  If not, see <http://www.gnu.org/licenses/>.\n\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/Token.h>\n#include <libsolutil/StringUtils.h>\n\n#include <map>\n\nnamespace solidity::langutil\n{\n\nToken TokenTraits::AssignmentToBinaryOp(Token op)\n{\n\tsolAssert(isAssignmentOp(op) && op != Token::Assign, \"\");\n\treturn static_cast<Token>(static_cast<int>(op) + (static_cast<int>(Token::BitOr) - static_cast<int>(Token::AssignBitOr)));\n}\n\nstd::string ElementaryTypeNameToken::toString(bool const& tokenValue) const\n{\n\tstd::string name = TokenTraits::toString(m_token);\n\tif (tokenValue || (firstNumber() == 0 && secondNumber() == 0))\n\t\treturn name;\n\tsolAssert(name.size() >= 3, \"Token name size should be greater than 3. Should not reach here.\");\n\tif (m_token == Token::FixedMxN || m_token == Token::UFixedMxN)\n\t\treturn name.substr(0, name.size() - 3) + std::to_string(m_firstNumber) + \"x\" + std::to_string(m_secondNumber);\n\telse\n\t\treturn name.substr(0, name.size() - 1) + std::to_string(m_firstNumber);\n}\n\nvoid ElementaryTypeNameToken::assertDetails(Token _baseType, unsigned const& _first, unsigned const& _second)\n{\n\tsolAssert(TokenTraits::isElementaryTypeName(_baseType), \"Expected elementary type name: \" + std::string(TokenTraits::toString(_baseType)));\n\tif (_baseType == Token::BytesM)\n\t{\n\t\tsolAssert(_second == 0, \"There should not be a second size argument to type bytesM.\");\n\t\tsolAssert(_first <= 32, \"No elementary type bytes\" + std::to_string(_first) + \".\");\n\t}\n\telse if (_baseType == Token::UIntM || _baseType == Token::IntM)\n\t{\n\t\tsolAssert(_second == 0, \"There should not be a second size argument to type \" + std::string(TokenTraits::toString(_baseType)) + \".\");\n\t\tsolAssert(\n\t\t\t_first <= 256 && _first % 8 == 0,\n\t\t\t\"No elementary type \" + std::string(TokenTraits::toString(_baseType)) + std::to_string(_first) + \".\"\n\t\t);\n\t}\n\telse if (_baseType == Token::UFixedMxN || _baseType == Token::FixedMxN)\n\t{\n\t\tsolAssert(\n\t\t\t_first >= 8 && _first <= 256 && _first % 8 == 0 && _second <= 80,\n\t\t\t\"No elementary type \" + std::string(TokenTraits::toString(_baseType)) + std::to_string(_first) + \"x\" + std::to_string(_second) + \".\"\n\t\t);\n\t}\n\telse\n\t\tsolAssert(_first == 0 && _second == 0, \"Unexpected size arguments\");\n\n\tm_token = _baseType;\n\tm_firstNumber = _first;\n\tm_secondNumber = _second;\n}\n\nnamespace TokenTraits\n{\nchar const* toString(Token tok)\n{\n\tswitch (tok)\n\t{\n#define T(name, string, precedence) case Token::name: return string;\n\t\tTOKEN_LIST(T, T)\n#undef T\n\t\tdefault: // Token::NUM_TOKENS:\n\t\t\treturn \"\";\n\t}\n}\n\nchar const* name(Token tok)\n{\n#define T(name, string, precedence) #name,\n\tstatic char const* const names[TokenTraits::count()] = { TOKEN_LIST(T, T) };\n#undef T\n\n\tsolAssert(static_cast<size_t>(tok) < TokenTraits::count(), \"\");\n\treturn names[static_cast<size_t>(tok)];\n}\n\nstd::string friendlyName(Token tok)\n{\n\tchar const* ret = toString(tok);\n\tif (ret)\n\t\treturn std::string(ret);\n\n\tret = name(tok);\n\tsolAssert(ret != nullptr, \"\");\n\treturn std::string(ret);\n}\n\n\nstatic Token keywordByName(std::string_view const _name)\n{\n\t// The following macros are used inside TOKEN_LIST and cause non-keyword tokens to be ignored\n\t// and keywords to be put inside the keywords variable.\n#define KEYWORD(name, string, precedence) {string, Token::name},\n#define TOKEN(name, string, precedence)\n\tstatic std::map<std::string, Token, std::less<>> const keywords({TOKEN_LIST(TOKEN, KEYWORD)});\n#undef KEYWORD\n#undef TOKEN\n\tauto it = keywords.find(_name);\n\treturn it == keywords.end() ? Token::Identifier : it->second;\n}\n\nbool isYulKeyword(std::string_view const _literal)\n{\n\treturn _literal == \"leave\" || isYulKeyword(keywordByName(_literal));\n}\n\nstd::tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(std::string const& _literal)\n{\n\t// Used for `bytesM`, `uintM`, `intM`, `fixedMxN`, `ufixedMxN`.\n\t// M/N must be shortest representation. M can never be 0. N can be zero.\n\tauto parseSize = [](std::string::const_iterator _begin, std::string::const_iterator _end) -> int\n\t{\n\t\t// No number.\n\t\tif (distance(_begin, _end) == 0)\n\t\t\treturn -1;\n\n\t\t// Disallow leading zero.\n\t\tif (distance(_begin, _end) > 1 && *_begin == '0')\n\t\t\treturn -1;\n\n\t\tint ret = 0;\n\t\tfor (auto it = _begin; it != _end; it++)\n\t\t{\n\t\t\tif (*it < '0' || *it > '9')\n\t\t\t\treturn -1;\n\t\t\t//  Overflow check. The largest acceptable value is 256 in the callers.\n\t\t\tif (ret >= 256)\n\t\t\t\treturn -1;\n\t\t\tret *= 10;\n\t\t\tret += *it - '0';\n\t\t}\n\t\treturn ret;\n\t};\n\n\tauto positionM = find_if(_literal.begin(), _literal.end(), util::isDigit);\n\tif (positionM != _literal.end())\n\t{\n\t\tstd::string baseType(_literal.begin(), positionM);\n\t\tauto positionX = find_if_not(positionM, _literal.end(), util::isDigit);\n\t\tint m = parseSize(positionM, positionX);\n\t\tToken keyword = keywordByName(baseType);\n\t\tif (keyword == Token::Bytes)\n\t\t{\n\t\t\tif (0 < m && m <= 32 && positionX == _literal.end())\n\t\t\t\treturn std::make_tuple(Token::BytesM, m, 0);\n\t\t}\n\t\telse if (keyword == Token::UInt || keyword == Token::Int)\n\t\t{\n\t\t\tif (0 < m && m <= 256 && m % 8 == 0 && positionX == _literal.end())\n\t\t\t{\n\t\t\t\tif (keyword == Token::UInt)\n\t\t\t\t\treturn std::make_tuple(Token::UIntM, m, 0);\n\t\t\t\telse\n\t\t\t\t\treturn std::make_tuple(Token::IntM, m, 0);\n\t\t\t}\n\t\t}\n\t\telse if (keyword == Token::UFixed || keyword == Token::Fixed)\n\t\t{\n\t\t\tif (\n\t\t\t\tpositionM < positionX &&\n\t\t\t\tpositionX < _literal.end() &&\n\t\t\t\t*positionX == 'x' &&\n\t\t\t\tall_of(positionX + 1, _literal.end(), util::isDigit)\n\t\t\t) {\n\t\t\t\tint n = parseSize(positionX + 1, _literal.end());\n\t\t\t\tif (\n\t\t\t\t\t8 <= m && m <= 256 && m % 8 == 0 &&\n\t\t\t\t\t0 <= n && n <= 80\n\t\t\t\t) {\n\t\t\t\t\tif (keyword == Token::UFixed)\n\t\t\t\t\t\treturn std::make_tuple(Token::UFixedMxN, m, n);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn std::make_tuple(Token::FixedMxN, m, n);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn std::make_tuple(Token::Identifier, 0, 0);\n\t}\n\n\treturn std::make_tuple(keywordByName(_literal), 0, 0);\n}\n\n}\n}\n"
  },
  {
    "path": "liblangutil/Token.h",
    "content": "// Copyright 2006-2012, the V8 project authors. All rights reserved.\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//    * Redistributions of source code must retain the above copyright\n//      notice, this list of conditions and the following disclaimer.\n//    * Redistributions in binary form must reproduce the above\n//      copyright notice, this list of conditions and the following\n//      disclaimer in the documentation and/or other materials provided\n//      with the distribution.\n//    * Neither the name of Google Inc. nor the names of its\n//      contributors may be used to endorse or promote products derived\n//      from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Modifications as part of solidity under the following license:\n//\n// solidity is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// solidity is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with solidity.  If not, see <http://www.gnu.org/licenses/>.\n\n#pragma once\n\n#include <cstdint>\n#include <iosfwd>\n#include <string>\n#include <tuple>\n\nnamespace solidity::langutil\n{\n\n// TOKEN_LIST takes a list of 3 macros M, all of which satisfy the\n// same signature M(name, string, precedence), where name is the\n// symbolic token name, string is the corresponding syntactic symbol\n// (or nullptr, for literals), and precedence is the precedence (or 0).\n// The parameters are invoked for token categories as follows:\n//\n//   T: Non-keyword tokens\n//   K: Keyword tokens\n\n// IGNORE_TOKEN is a convenience macro that can be supplied as\n// an argument (at any position) for a TOKEN_LIST call. It does\n// nothing with tokens belonging to the respective category.\n\n#define IGNORE_TOKEN(name, string, precedence)\n\n#define TOKEN_LIST(T, K)                                                \\\n\t/* End of source indicator. */                                      \\\n\tT(EOS, \"EOS\", 0)                                                    \\\n\t\\\n\t/* Punctuators (ECMA-262, section 7.7, page 15). */                 \\\n\tT(LParen, \"(\", 0)                                                   \\\n\tT(RParen, \")\", 0)                                                   \\\n\tT(LBrack, \"[\", 0)                                                   \\\n\tT(RBrack, \"]\", 0)                                                   \\\n\tT(LBrace, \"{\", 0)                                                   \\\n\tT(RBrace, \"}\", 0)                                                   \\\n\tT(Colon, \":\", 0)                                                    \\\n\tT(Semicolon, \";\", 0)                                                \\\n\tT(Period, \".\", 0)                                                   \\\n\tT(Conditional, \"?\", 3)                                              \\\n\tT(DoubleArrow, \"=>\", 0)                                             \\\n\tT(RightArrow, \"->\", 0)                                              \\\n\t\\\n\t/* Assignment operators. */                                         \\\n\t/* IsAssignmentOp() relies on this block of enum values being */    \\\n\t/* contiguous and sorted in the same order!*/                       \\\n\tT(Assign, \"=\", 2)                                                   \\\n\t/* The following have to be in exactly the same order as the simple binary operators*/ \\\n\tT(AssignBitOr, \"|=\", 2)                                           \\\n\tT(AssignBitXor, \"^=\", 2)                                          \\\n\tT(AssignBitAnd, \"&=\", 2)                                          \\\n\tT(AssignShl, \"<<=\", 2)                                            \\\n\tT(AssignSar, \">>=\", 2)                                            \\\n\tT(AssignShr, \">>>=\", 2)                                           \\\n\tT(AssignAdd, \"+=\", 2)                                             \\\n\tT(AssignSub, \"-=\", 2)                                             \\\n\tT(AssignMul, \"*=\", 2)                                             \\\n\tT(AssignDiv, \"/=\", 2)                                             \\\n\tT(AssignMod, \"%=\", 2)                                             \\\n\t\\\n\t/* Binary operators sorted by precedence. */                       \\\n\t/* IsBinaryOp() relies on this block of enum values */             \\\n\t/* being contiguous and sorted in the same order! */               \\\n\tT(Comma, \",\", 1)                                                   \\\n\tT(Or, \"||\", 4)                                                     \\\n\tT(And, \"&&\", 5)                                                    \\\n\tT(BitOr, \"|\", 8)                                                   \\\n\tT(BitXor, \"^\", 9)                                                  \\\n\tT(BitAnd, \"&\", 10)                                                 \\\n\tT(SHL, \"<<\", 11)                                                   \\\n\tT(SAR, \">>\", 11)                                                   \\\n\tT(SHR, \">>>\", 11)                                                  \\\n\tT(Add, \"+\", 12)                                                    \\\n\tT(Sub, \"-\", 12)                                                    \\\n\tT(Mul, \"*\", 13)                                                    \\\n\tT(Div, \"/\", 13)                                                    \\\n\tT(Mod, \"%\", 13)                                                    \\\n\tT(Exp, \"**\", 14)                                                   \\\n\t\\\n\t/* Compare operators sorted by precedence. */                      \\\n\t/* IsCompareOp() relies on this block of enum values */            \\\n\t/* being contiguous and sorted in the same order! */               \\\n\tT(Equal, \"==\", 6)                                                  \\\n\tT(NotEqual, \"!=\", 6)                                               \\\n\tT(LessThan, \"<\", 7)                                                \\\n\tT(GreaterThan, \">\", 7)                                             \\\n\tT(LessThanOrEqual, \"<=\", 7)                                        \\\n\tT(GreaterThanOrEqual, \">=\", 7)                                     \\\n\t\\\n\t/* Unary operators. */                                             \\\n\t/* IsUnaryOp() relies on this block of enum values */              \\\n\t/* being contiguous and sorted in the same order! */               \\\n\tT(Not, \"!\", 0)                                                     \\\n\tT(BitNot, \"~\", 0)                                                  \\\n\tT(Inc, \"++\", 0)                                                    \\\n\tT(Dec, \"--\", 0)                                                    \\\n\tK(Delete, \"delete\", 0)                                             \\\n\t\\\n\t/* Inline Assembly Operators */                                    \\\n\tT(AssemblyAssign, \":=\", 2)                                         \\\n\t/* Keywords */                                                     \\\n\tK(Abstract, \"abstract\", 0)                                         \\\n\tK(Anonymous, \"anonymous\", 0)                                       \\\n\tK(As, \"as\", 0)                                                     \\\n\tK(Assembly, \"assembly\", 0)                                         \\\n\tK(Break, \"break\", 0)                                               \\\n\tK(Catch, \"catch\", 0)                                               \\\n\tK(Constant, \"constant\", 0)                                         \\\n\tK(Constructor, \"constructor\", 0)                                   \\\n\tK(Continue, \"continue\", 0)                                         \\\n\tK(Contract, \"contract\", 0)                                         \\\n\tK(Do, \"do\", 0)                                                     \\\n\tK(Else, \"else\", 0)                                                 \\\n\tK(Enum, \"enum\", 0)                                                 \\\n\tK(Emit, \"emit\", 0)                                                 \\\n\tK(Event, \"event\", 0)                                               \\\n\tK(External, \"external\", 0)                                         \\\n\tK(Fallback, \"fallback\", 0)                                         \\\n\tK(For, \"for\", 0)                                                   \\\n\tK(Function, \"function\", 0)                                         \\\n\tK(Hex, \"hex\", 0)                                                   \\\n\tK(If, \"if\", 0)                                                     \\\n\tK(Indexed, \"indexed\", 0)                                           \\\n\tK(Interface, \"interface\", 0)                                       \\\n\tK(Internal, \"internal\", 0)                                         \\\n\tK(Immutable, \"immutable\", 0)                                       \\\n\tK(Import, \"import\", 0)                                             \\\n\tK(Is, \"is\", 0)                                                     \\\n\tK(Library, \"library\", 0)                                           \\\n\tK(Mapping, \"mapping\", 0)                                           \\\n\tK(Memory, \"memory\", 0)                                             \\\n\tK(Modifier, \"modifier\", 0)                                         \\\n\tK(New, \"new\", 0)                                                   \\\n\tK(Override, \"override\", 0)                                         \\\n\tK(Payable, \"payable\", 0)                                           \\\n\tK(Public, \"public\", 0)                                             \\\n\tK(Pragma, \"pragma\", 0)                                             \\\n\tK(Private, \"private\", 0)                                           \\\n\tK(Pure, \"pure\", 0)                                                 \\\n\tK(Receive, \"receive\", 0)                                           \\\n\tK(Return, \"return\", 0)                                             \\\n\tK(Returns, \"returns\", 0)                                           \\\n\tK(Storage, \"storage\", 0)                                           \\\n\tK(CallData, \"calldata\", 0)                                         \\\n\tK(Struct, \"struct\", 0)                                             \\\n\tK(Throw, \"throw\", 0)                                               \\\n\tK(Try, \"try\", 0)                                                   \\\n\tK(Type, \"type\", 0)                                                 \\\n\tK(Unchecked, \"unchecked\", 0)                                       \\\n\tK(Unicode, \"unicode\", 0)                                           \\\n\tK(Using, \"using\", 0)                                               \\\n\tK(View, \"view\", 0)                                                 \\\n\tK(Virtual, \"virtual\", 0)                                           \\\n\tK(While, \"while\", 0)                                               \\\n\t\\\n\t/* Ether subdenominations */                                       \\\n\tK(SubWei, \"wei\", 0)                                                \\\n\tK(SubGwei, \"gwei\", 0)                                              \\\n\tK(SubEther, \"ether\", 0)                                            \\\n\tK(SubSecond, \"seconds\", 0)                                         \\\n\tK(SubMinute, \"minutes\", 0)                                         \\\n\tK(SubHour, \"hours\", 0)                                             \\\n\tK(SubDay, \"days\", 0)                                               \\\n\tK(SubWeek, \"weeks\", 0)                                             \\\n\tK(SubYear, \"years\", 0)                                             \\\n\t/* type keywords*/                                                 \\\n\tK(Int, \"int\", 0)                                                   \\\n\tK(UInt, \"uint\", 0)                                                 \\\n\tK(Bytes, \"bytes\", 0)                                               \\\n\tK(String, \"string\", 0)                                             \\\n\tK(Address, \"address\", 0)                                           \\\n\tK(Bool, \"bool\", 0)                                                 \\\n\tK(Fixed, \"fixed\", 0)                                               \\\n\tK(UFixed, \"ufixed\", 0)                                             \\\n\tT(IntM, \"intM\", 0)                                                 \\\n\tT(UIntM, \"uintM\", 0)                                               \\\n\tT(BytesM, \"bytesM\", 0)                                             \\\n\tT(FixedMxN, \"fixedMxN\", 0)                                         \\\n\tT(UFixedMxN, \"ufixedMxN\", 0)                                       \\\n\tT(TypesEnd, nullptr, 0) /* used as type enum end marker */         \\\n\t\\\n\t/* Literals */                                                     \\\n\tK(TrueLiteral, \"true\", 0)                                          \\\n\tK(FalseLiteral, \"false\", 0)                                        \\\n\tT(Number, nullptr, 0)                                              \\\n\tT(StringLiteral, nullptr, 0)                                       \\\n\tT(UnicodeStringLiteral, nullptr, 0)                                \\\n\tT(HexStringLiteral, nullptr, 0)                                    \\\n\tT(CommentLiteral, nullptr, 0)                                      \\\n\t\\\n\t/* Identifiers (not keywords or future reserved words). */         \\\n\tT(Identifier, nullptr, 0)                                          \\\n\t\\\n\t/* Keywords reserved for future use. */                            \\\n\tK(After, \"after\", 0)                                               \\\n\tK(Alias, \"alias\", 0)                                               \\\n\tK(Apply, \"apply\", 0)                                               \\\n\tK(Auto, \"auto\", 0)                                                 \\\n\tK(Byte, \"byte\", 0)                                                 \\\n\tK(Case, \"case\", 0)                                                 \\\n\tK(CopyOf, \"copyof\", 0)                                             \\\n\tK(Default, \"default\", 0)                                           \\\n\tK(Define, \"define\", 0)                                             \\\n\tK(Final, \"final\", 0)                                               \\\n\tK(Implements, \"implements\", 0)                                     \\\n\tK(In, \"in\", 0)                                                     \\\n\tK(Inline, \"inline\", 0)                                             \\\n\tK(Let, \"let\", 0)                                                   \\\n\tK(Macro, \"macro\", 0)                                               \\\n\tK(Match, \"match\", 0)                                               \\\n\tK(Mutable, \"mutable\", 0)                                           \\\n\tK(NullLiteral, \"null\", 0)                                          \\\n\tK(Of, \"of\", 0)                                                     \\\n\tK(Partial, \"partial\", 0)                                           \\\n\tK(Promise, \"promise\", 0)                                           \\\n\tK(Reference, \"reference\", 0)                                       \\\n\tK(Relocatable, \"relocatable\", 0)                                   \\\n\tK(Sealed, \"sealed\", 0)                                             \\\n\tK(Sizeof, \"sizeof\", 0)                                             \\\n\tK(Static, \"static\", 0)                                             \\\n\tK(Supports, \"supports\", 0)                                         \\\n\tK(Switch, \"switch\", 0)                                             \\\n\tK(Typedef, \"typedef\", 0)                                           \\\n\tK(TypeOf, \"typeof\", 0)                                             \\\n\tK(Var, \"var\", 0)                                                   \\\n\t\\\n\t/* Yul-specific tokens, but not keywords. */                       \\\n\tT(Leave, \"leave\", 0)                                               \\\n\t\\\n\tT(NonExperimentalEnd, nullptr, 0) /* used as non-experimental enum end marker */ \\\n\t/* Experimental Solidity specific keywords. */                     \\\n\tK(Class, \"class\", 0)                                               \\\n\tK(Instantiation, \"instantiation\", 0)                               \\\n\tK(Integer, \"Integer\", 0)                                           \\\n\tK(Itself, \"itself\", 0)                                             \\\n\tK(StaticAssert, \"static_assert\", 0)                                \\\n\tK(Builtin, \"__builtin\", 0)                                         \\\n\tK(ForAll, \"forall\", 0)                                             \\\n\tT(ExperimentalEnd, nullptr, 0) /* used as experimental enum end marker */ \\\n\t\\\n\t/* Illegal token - not able to scan. */                            \\\n\tT(Illegal, \"ILLEGAL\", 0)                                           \\\n\t\\\n\t/* Scanner-internal use only. */                                   \\\n\tT(Whitespace, nullptr, 0)\n\n// All token values.\n// attention! msvc issue:\n// http://stackoverflow.com/questions/9567868/compile-errors-after-adding-v8-to-my-project-c2143-c2059\n// @todo: avoid TOKEN_LIST macro\nenum class Token : unsigned int {\n#define T(name, string, precedence) name,\n\tTOKEN_LIST(T, T)\n\tNUM_TOKENS\n#undef T\n};\n\nnamespace TokenTraits\n{\n\tconstexpr size_t count() { return static_cast<size_t>(Token::NUM_TOKENS); }\n\n\t// Predicates\n\tconstexpr bool isElementaryTypeName(Token _token) { return Token::Int <= _token && _token < Token::TypesEnd; }\n\tconstexpr bool isAssignmentOp(Token tok) { return Token::Assign <= tok && tok <= Token::AssignMod; }\n\tconstexpr bool isBinaryOp(Token op) { return Token::Comma <= op && op <= Token::Exp; }\n\tconstexpr bool isCommutativeOp(Token op) { return op == Token::BitOr || op == Token::BitXor || op == Token::BitAnd ||\n\t\top == Token::Add || op == Token::Mul || op == Token::Equal || op == Token::NotEqual; }\n\tconstexpr bool isArithmeticOp(Token op) { return Token::Add <= op && op <= Token::Exp; }\n\tconstexpr bool isCompareOp(Token op) { return Token::Equal <= op && op <= Token::GreaterThanOrEqual; }\n\n\tconstexpr bool isBitOp(Token op) { return (Token::BitOr <= op && op <= Token::BitAnd) || op == Token::BitNot; }\n\tconstexpr bool isBooleanOp(Token op) { return (Token::Or <= op && op <= Token::And) || op == Token::Not; }\n\tconstexpr bool isUnaryOp(Token op) { return (Token::Not <= op && op <= Token::Delete) || op == Token::Sub; }\n\tconstexpr bool isCountOp(Token op) { return op == Token::Inc || op == Token::Dec; }\n\tconstexpr bool isShiftOp(Token op) { return (Token::SHL <= op) && (op <= Token::SHR); }\n\tconstexpr bool isVariableVisibilitySpecifier(Token op) { return op == Token::Public || op == Token::Private || op == Token::Internal; }\n\tconstexpr bool isVisibilitySpecifier(Token op) { return isVariableVisibilitySpecifier(op) || op == Token::External; }\n\tconstexpr bool isLocationSpecifier(Token op) { return op == Token::Memory || op == Token::Storage || op == Token::CallData; }\n\n\tconstexpr bool isStateMutabilitySpecifier(Token op)\n\t{\n\t\treturn op == Token::Pure || op == Token::View || op == Token::Payable;\n\t}\n\n\tconstexpr bool isEtherSubdenomination(Token op) { return op >= Token::SubWei && op <= Token::SubEther; }\n\tconstexpr bool isTimeSubdenomination(Token op) { return op == Token::SubSecond || op == Token::SubMinute || op == Token::SubHour || op == Token::SubDay || op == Token::SubWeek || op == Token::SubYear; }\n\tconstexpr bool isReservedKeyword(Token op) { return (Token::After <= op && op <= Token::Var); }\n\n\tconstexpr bool isYulKeyword(Token tok)\n\t{\n\t\treturn tok == Token::Function || tok == Token::Let || tok == Token::If || tok == Token::Switch || tok == Token::Case ||\n\t\t\ttok == Token::Default || tok == Token::For || tok == Token::Break || tok == Token::Continue || tok == Token::Leave ||\n\t\t\ttok == Token::TrueLiteral || tok == Token::FalseLiteral || tok == Token::HexStringLiteral || tok == Token::Hex;\n\t}\n\n\tconstexpr bool isBuiltinTypeClassName(Token _token)\n\t{\n\t\treturn\n\t\t\t_token == Token::Integer ||\n\t\t\t(isBinaryOp(_token) && _token != Token::Comma) ||\n\t\t\tisCompareOp(_token) ||\n\t\t\tisUnaryOp(_token) ||\n\t\t\t(isAssignmentOp(_token) && _token != Token::Assign);\n\t}\n\n\tconstexpr bool isExperimentalSolidityKeyword(Token token)\n\t{\n\t\treturn\n\t\t\ttoken == Token::Assembly ||\n\t\t\ttoken == Token::Contract ||\n\t\t\ttoken == Token::External ||\n\t\t\ttoken == Token::Fallback ||\n\t\t\ttoken == Token::Pragma ||\n\t\t\ttoken == Token::Import ||\n\t\t\ttoken == Token::As ||\n\t\t\ttoken == Token::Function ||\n\t\t\ttoken == Token::Let ||\n\t\t\ttoken == Token::Return ||\n\t\t\ttoken == Token::Type ||\n\t\t\ttoken == Token::If ||\n\t\t\ttoken == Token::Else ||\n\t\t\ttoken == Token::Do ||\n\t\t\ttoken == Token::While ||\n\t\t\ttoken == Token::For ||\n\t\t\ttoken == Token::Continue ||\n\t\t\ttoken == Token::Break ||\n\t\t\t(token > Token::NonExperimentalEnd && token< Token::ExperimentalEnd);\n\t}\n\n\tconstexpr bool isExperimentalSolidityOnlyKeyword(Token _token)\n\t{\n\t\t// TODO: use token > Token::NonExperimentalEnd && token < Token::ExperimentalEnd\n\t\t// as soon as other experimental tokens are added. For now the comparison generates\n\t\t// a warning from clang because it is always false.\n\t\treturn _token > Token::NonExperimentalEnd && _token < Token::ExperimentalEnd;\n\t}\n\n\tbool isYulKeyword(std::string_view _literal);\n\n\tToken AssignmentToBinaryOp(Token op);\n\n\t// @returns the precedence > 0 for binary and compare\n\t// operators; returns 0 otherwise.\n\tconstexpr int precedence(Token tok)\n\t{\n\t\tint8_t constexpr precs[TokenTraits::count()] =\n\t\t{\n\t\t\t#define T(name, string, precedence) precedence,\n\t\t\tTOKEN_LIST(T, T)\n\t\t\t#undef T\n\t\t};\n\t\treturn precs[static_cast<size_t>(tok)];\n\t}\n\n\tconstexpr bool hasExpHighestPrecedence()\n\t{\n\t\tconstexpr int expPrecedence = TokenTraits::precedence(Token::Exp);\n\t\tstatic_assert(expPrecedence == 14, \"Exp precedence changed.\");\n\n\t\t#define T(name, string, precedence) ((Token::name == Token::Exp) || precedence < expPrecedence) &&\n\t\treturn\n\t\t\tTOKEN_LIST(T, T)\n\t\t\ttrue;\n\t\t#undef T\n\t}\n\n\tstd::tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(std::string const& _literal);\n\n\t// @returns a string corresponding to the C++ token name\n\t// (e.g. \"LT\" for the token LT).\n\tchar const* name(Token tok);\n\n\t// @returns a string corresponding to the JS token string\n\t// (.e., \"<\" for the token LT) or nullptr if the token doesn't\n\t// have a (unique) string (e.g. an IDENTIFIER).\n\tchar const* toString(Token tok);\n\n\tstd::string friendlyName(Token tok);\n}\n\ninline std::ostream& operator<<(std::ostream& os, Token token)\n{\n\tos << TokenTraits::friendlyName(token);\n\treturn os;\n}\n\nclass ElementaryTypeNameToken\n{\npublic:\n\tElementaryTypeNameToken(Token _token, unsigned const& _firstNumber, unsigned const& _secondNumber)\n\t{\n\t\tassertDetails(_token, _firstNumber, _secondNumber);\n\t}\n\n\tunsigned int firstNumber() const { return m_firstNumber; }\n\tunsigned int secondNumber() const { return m_secondNumber; }\n\tToken token() const { return m_token; }\n\n\t///if tokValue is set to true, then returns the actual token type name, otherwise, returns full type\n\tstd::string toString(bool const& tokenValue = false) const;\n\nprivate:\n\tToken m_token;\n\tunsigned int m_firstNumber;\n\tunsigned int m_secondNumber;\n\t/// throws if type is not properly sized\n\tvoid assertDetails(Token _baseType, unsigned const& _first, unsigned const& _second);\n};\n\n}\n"
  },
  {
    "path": "liblangutil/UniqueErrorReporter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/Exceptions.h>\n\nnamespace solidity::langutil\n{\n\n/*\n * Wrapper for ErrorReporter that removes duplicates.\n * Two errors are considered the same if their error ID and location are the same.\n */\nclass UniqueErrorReporter\n{\npublic:\n\tUniqueErrorReporter(): m_errorReporter(m_uniqueErrors) {}\n\n\tvoid append(UniqueErrorReporter const& _other)\n\t{\n\t\tm_errorReporter.append(_other.m_errorReporter.errors());\n\t}\n\n\tvoid warning(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n\t{\n\t\tif (!seen(_error, _location, _description))\n\t\t{\n\t\t\tm_errorReporter.warning(_error, _location, _description);\n\t\t\tmarkAsSeen(_error, _location, _description);\n\t\t}\n\t}\n\n\tvoid warning(\n\t\tErrorId _error,\n\t\tSourceLocation const& _location,\n\t\tstd::string const& _description,\n\t\tSecondarySourceLocation const& _secondaryLocation\n\t)\n\t{\n\t\tif (!seen(_error, _location, _description))\n\t\t{\n\t\t\tm_errorReporter.warning(_error, _location, _description, _secondaryLocation);\n\t\t\tmarkAsSeen(_error, _location, _description);\n\t\t}\n\t}\n\n\tvoid warning(ErrorId _error, std::string const& _description)\n\t{\n\t\tm_errorReporter.warning(_error, _description);\n\t}\n\n\tvoid info(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n\t{\n\t\tif (!seen(_error, _location, _description))\n\t\t{\n\t\t\tm_errorReporter.info(_error, _location, _description);\n\t\t\tmarkAsSeen(_error, _location, _description);\n\t\t}\n\t}\n\n\tvoid info(ErrorId _error, std::string const& _description)\n\t{\n\t\tm_errorReporter.info(_error, _description);\n\t}\n\n\tbool seen(ErrorId _error, SourceLocation const& _location, std::string const& _description) const\n\t{\n\t\tif (m_seenErrors.count({_error, _location}))\n\t\t{\n\t\t\tsolAssert(m_seenErrors.at({_error, _location}) == _description, \"\");\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tvoid markAsSeen(ErrorId _error, SourceLocation const& _location, std::string const& _description)\n\t{\n\t\tif (_location != SourceLocation{})\n\t\t\tm_seenErrors[{_error, _location}] = _description;\n\t}\n\n\tErrorList const& errors() const { return m_errorReporter.errors(); }\n\n\tvoid clear() { m_errorReporter.clear(); }\n\nprivate:\n\tErrorList m_uniqueErrors;\n\tErrorReporter m_errorReporter;\n\tstd::map<std::pair<ErrorId, SourceLocation>, std::string> m_seenErrors;\n};\n\n}\n"
  },
  {
    "path": "libsmtutil/BMCSolverInterface.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/SolverInterface.h>\n\nnamespace solidity::smtutil\n{\n\nclass BMCSolverInterface : public SolverInterface\n{\npublic:\n\texplicit BMCSolverInterface(std::optional<unsigned> _queryTimeout = {}): m_queryTimeout(_queryTimeout) {}\n\n\t~BMCSolverInterface() override = default;\n\tvirtual void reset() = 0;\n\n\tvirtual void push() = 0;\n\tvirtual void pop() = 0;\n\n\tvirtual void addAssertion(Expression const& _expr) = 0;\n\n\t/// Checks for satisfiability, evaluates the expressions if a model\n\t/// is available. Throws SMTSolverError on error.\n\tvirtual std::pair<CheckResult, std::vector<std::string>>\n\tcheck(std::vector<Expression> const& _expressionsToEvaluate) = 0;\n\n\t/// @returns a list of queries that the system was not able to respond to.\n\tvirtual std::vector<std::string> unhandledQueries() { return {}; }\n\nprotected:\n\tstd::optional<unsigned> m_queryTimeout;\n};\n\n}\n"
  },
  {
    "path": "libsmtutil/CHCSmtLib2Interface.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsmtutil/CHCSmtLib2Interface.h>\n\n#include <libsmtutil/SMTLib2Parser.h>\n\n#include <libsolutil/Keccak256.h>\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/Visitor.h>\n\n#include <boost/algorithm/string/join.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n\n#include <range/v3/algorithm/all_of.hpp>\n#include <range/v3/algorithm/sort.hpp>\n#include <range/v3/view.hpp>\n\n#include <array>\n#include <fstream>\n#include <iostream>\n#include <memory>\n#include <stdexcept>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::frontend;\nusing namespace solidity::smtutil;\n\nCHCSmtLib2Interface::CHCSmtLib2Interface(\n\tstd::map<h256, std::string> _queryResponses,\n\tReadCallback::Callback _smtCallback,\n\tstd::optional<unsigned> _queryTimeout\n):\n\tCHCSolverInterface(_queryTimeout),\n\tm_queryResponses(std::move(_queryResponses)),\n\tm_smtCallback(std::move(_smtCallback))\n{\n\treset();\n}\n\nvoid CHCSmtLib2Interface::reset()\n{\n\tm_unhandledQueries.clear();\n\tm_commands.clear();\n\tm_context.clear();\n\tcreateHeader();\n\tm_context.setTupleDeclarationCallback([&](TupleSort const& _tupleSort){\n\t\tm_commands.declareTuple(\n\t\t\t_tupleSort.name,\n\t\t\t_tupleSort.members,\n\t\t\t_tupleSort.components\n\t\t\t\t| ranges::views::transform([&](SortPointer const& _sort){ return m_context.toSmtLibSort(_sort); })\n\t\t\t\t| ranges::to<std::vector>()\n\t\t);\n\t});\n}\n\nvoid CHCSmtLib2Interface::registerRelation(Expression const& _expr)\n{\n\tsmtAssert(_expr.sort);\n\tsmtAssert(_expr.sort->kind == Kind::Function);\n\tif (m_context.isDeclared(_expr.name))\n\t\treturn;\n\tauto const& fSort = std::dynamic_pointer_cast<FunctionSort>(_expr.sort);\n\tsmtAssert(fSort->codomain);\n\tauto domain = toSmtLibSort(fSort->domain);\n\tstd::string codomain = toSmtLibSort(fSort->codomain);\n\tm_commands.declareFunction(_expr.name, domain, codomain);\n\tm_context.declare(_expr.name, _expr.sort);\n}\n\nvoid CHCSmtLib2Interface::addRule(Expression const& _expr, std::string const& /*_name*/)\n{\n\tm_commands.assertion(\"(forall\" + forall(_expr) + '\\n' + m_context.toSExpr(_expr) + \")\\n\");\n}\n\nCHCSolverInterface::QueryResult CHCSmtLib2Interface::query(Expression const& _block)\n{\n\tstd::string query = dumpQuery(_block);\n\ttry\n\t{\n\t\tstd::string response = querySolver(query);\n\n\t\tCheckResult result;\n\t\t// NOTE: Our internal semantics is UNSAT -> SAFE and SAT -> UNSAFE, which corresponds to usual SMT-based model checking\n\t\t// However, with CHC solvers, the meaning is flipped, UNSAT -> UNSAFE and SAT -> SAFE.\n\t\t// So we have to flip the answer.\n\t\tif (boost::starts_with(response, \"sat\"))\n\t\t\treturn {CheckResult::UNSATISFIABLE, invariantsFromSolverResponse(response), {}};\n\t\tif (boost::starts_with(response, \"unsat\"))\n\t\t\tresult = CheckResult::SATISFIABLE;\n\t\telse if (boost::starts_with(response, \"unknown\"))\n\t\t\tresult = CheckResult::UNKNOWN;\n\t\telse\n\t\t\tresult = CheckResult::ERROR;\n\t\treturn {result, {}, {}};\n\t}\n\tcatch(smtutil::SMTSolverInteractionError const&)\n\t{\n\t\treturn {CheckResult::ERROR, {}, {}};\n\t}\n\n}\n\nvoid CHCSmtLib2Interface::declareVariable(std::string const& _name, SortPointer const& _sort)\n{\n\tsmtAssert(_sort);\n\tif (!m_context.isDeclared(_name))\n\t\tm_context.declare(_name, _sort);\n}\n\nstd::string CHCSmtLib2Interface::toSmtLibSort(SortPointer const& _sort)\n{\n\treturn m_context.toSmtLibSort(_sort);\n}\n\nstd::vector<std::string> CHCSmtLib2Interface::toSmtLibSort(std::vector<SortPointer> const& _sorts)\n{\n\treturn applyMap(_sorts, [this](auto const& sort) { return toSmtLibSort(sort); });\n}\n\nstd::set<std::string> CHCSmtLib2Interface::collectVariableNames(Expression const& _expr) const\n{\n\tstd::set<std::string> names;\n\tauto dfs = [&](Expression const& _current, auto _recurse) -> void\n\t{\n\t\tif (_current.arguments.empty())\n\t\t{\n\t\t\tif (m_context.isDeclared(_current.name))\n\t\t\t\tnames.insert(_current.name);\n\t\t}\n\t\telse\n\t\t\tfor (auto const& arg: _current.arguments)\n\t\t\t\t_recurse(arg, _recurse);\n\t};\n\tdfs(_expr, dfs);\n\treturn names;\n}\n\nstd::string CHCSmtLib2Interface::forall(Expression const& _expr)\n{\n\tauto varNames = collectVariableNames(_expr);\n\tstd::string vars(\"(\");\n\tfor (auto const& name: varNames)\n\t{\n\t\tauto sort = m_context.getDeclaredSort(name);\n\t\tif (sort->kind != Kind::Function)\n\t\t\tvars += \" (\" + name + \" \" + toSmtLibSort(sort) + \")\";\n\t}\n\tvars += \")\";\n\treturn vars;\n}\n\nstd::string CHCSmtLib2Interface::querySolver(std::string const& _input)\n{\n\tutil::h256 inputHash = util::keccak256(_input);\n\tif (m_queryResponses.count(inputHash))\n\t\treturn m_queryResponses.at(inputHash);\n\n\tif (m_smtCallback)\n\t{\n\t\tauto result = m_smtCallback(ReadCallback::kindString(ReadCallback::Kind::SMTQuery), _input);\n\t\tif (result.success)\n\t\t\treturn result.responseOrErrorMessage;\n\t}\n\n\tm_unhandledQueries.push_back(_input);\n\treturn \"unknown\\n\";\n}\n\nstd::string CHCSmtLib2Interface::dumpQuery(Expression const& _expr)\n{\n\treturn m_commands.toString() + createQueryAssertion(_expr.name) + '\\n' + \"(check-sat)\" + '\\n';\n}\n\nvoid CHCSmtLib2Interface::createHeader()\n{\n\tif (m_queryTimeout)\n\t\tm_commands.setOption(\"timeout\", std::to_string(*m_queryTimeout));\n\tm_commands.setLogic(\"HORN\");\n}\n\nstd::string CHCSmtLib2Interface::createQueryAssertion(std::string _name) {\n\treturn \"(assert\\n(forall ((UNUSED Bool))\\n(=> \" + std::move(_name) + \" false)))\";\n}\n\nnamespace\n{\nbool isNumber(std::string const& _expr)\n{\n\treturn ranges::all_of(_expr, [](char c) { return isDigit(c) || c == '.'; });\n}\n\nbool isBitVectorHexConstant(std::string const& _string)\n{\n\tif (_string.substr(0, 2) != \"#x\")\n\t\treturn false;\n\tif (_string.find_first_not_of(\"0123456789abcdefABCDEF\", 2) != std::string::npos)\n\t\treturn false;\n\treturn true;\n}\n\nbool isBitVectorConstant(std::string const& _string)\n{\n\tif (_string.substr(0, 2) != \"#b\")\n\t\treturn false;\n\tif (_string.find_first_not_of(\"01\", 2) != std::string::npos)\n\t\treturn false;\n\treturn true;\n}\n}\n\nvoid CHCSmtLib2Interface::ScopedParser::addVariableDeclaration(std::string _name, solidity::smtutil::SortPointer _sort)\n{\n\tm_localVariables.emplace(std::move(_name), std::move(_sort));\n}\n\nstd::optional<SortPointer> CHCSmtLib2Interface::ScopedParser::lookupKnownTupleSort(std::string const& _name) const\n{\n\treturn m_context.getTupleType(_name);\n}\n\nSortPointer CHCSmtLib2Interface::ScopedParser::toSort(SMTLib2Expression const& _expr)\n{\n\tif (isAtom(_expr))\n\t{\n\t\tauto const& name = asAtom(_expr);\n\t\tif (name == \"Int\")\n\t\t\treturn SortProvider::sintSort;\n\t\tif (name == \"Bool\")\n\t\t\treturn SortProvider::boolSort;\n\t\tauto tupleSort = lookupKnownTupleSort(name);\n\t\tif (tupleSort)\n\t\t\treturn tupleSort.value();\n\t}\n\telse\n\t{\n\t\tauto const& args = asSubExpressions(_expr);\n\t\tif (asAtom(args[0]) == \"Array\")\n\t\t{\n\t\t\tsmtSolverInteractionRequire(args.size() == 3, \"Wrong format of Array sort in solver's response\");\n\t\t\tauto domainSort = toSort(args[1]);\n\t\t\tauto codomainSort = toSort(args[2]);\n\t\t\treturn std::make_shared<ArraySort>(std::move(domainSort), std::move(codomainSort));\n\t\t}\n\t\tif (args.size() == 3 && isAtom(args[0]) && asAtom(args[0]) == \"_\" && isAtom(args[1])\n\t\t\t&& asAtom(args[1]) == \"int2bv\")\n\t\t\treturn std::make_shared<BitVectorSort>(std::stoul(asAtom(args[2])));\n\t}\n\tsmtSolverInteractionRequire(false, \"Unknown sort encountered\");\n}\n\nsmtutil::Expression CHCSmtLib2Interface::ScopedParser::parseQuantifier(\n\tstd::string const& _quantifierName,\n\tstd::vector<SMTLib2Expression> const& _varList,\n\tSMTLib2Expression const& _coreExpression)\n{\n\tstd::vector<std::pair<std::string, SortPointer>> boundVariables;\n\tfor (auto const& sortedVar: _varList)\n\t{\n\t\tsmtSolverInteractionRequire(!isAtom(sortedVar), \"Wrong format of quantified expression in solver's response\");\n\t\tauto varSortPair = asSubExpressions(sortedVar);\n\t\tsmtSolverInteractionRequire(varSortPair.size() == 2, \"Wrong format of quantified expression in solver's response\");\n\t\tboundVariables.emplace_back(asAtom(varSortPair[0]), toSort(varSortPair[1]));\n\t}\n\tfor (auto const& [var, sort]: boundVariables)\n\t{\n\t\tsmtSolverInteractionRequire(m_localVariables.count(var) == 0, \"Quantifying over previously encountered variable\"); // TODO: deal with shadowing?\n\t\tm_localVariables.emplace(var, sort);\n\t}\n\tauto core = toSMTUtilExpression(_coreExpression);\n\tfor (auto const& [var, sort]: boundVariables)\n\t{\n\t\tsmtSolverInteractionRequire(m_localVariables.count(var) != 0, \"Error in processing quantified expression\");\n\t\tm_localVariables.erase(var);\n\t}\n\treturn Expression(_quantifierName, {core}, SortProvider::boolSort); // TODO: what about the bound variables?\n}\n\nsmtutil::Expression CHCSmtLib2Interface::ScopedParser::toSMTUtilExpression(SMTLib2Expression const& _expr)\n{\n\treturn std::visit(\n\t\tGenericVisitor{\n\t\t\t[&](std::string const& _atom)\n\t\t\t{\n\t\t\t\tif (_atom == \"true\" || _atom == \"false\")\n\t\t\t\t\treturn smtutil::Expression(_atom == \"true\");\n\t\t\t\telse if (isNumber(_atom))\n\t\t\t\t\treturn smtutil::Expression(_atom, {}, SortProvider::sintSort);\n\t\t\t\telse if (isBitVectorHexConstant(_atom))\n\t\t\t\t\treturn smtutil::Expression(_atom, {}, std::make_shared<BitVectorSort>((_atom.size() - 2) * 4));\n\t\t\t\telse if (isBitVectorConstant(_atom))\n\t\t\t\t\treturn smtutil::Expression(_atom, {}, std::make_shared<BitVectorSort>(_atom.size() - 2));\n\t\t\t\telse if (auto it = m_localVariables.find(_atom); it != m_localVariables.end())\n\t\t\t\t\treturn smtutil::Expression(_atom, {}, it->second);\n\t\t\t\telse if (m_context.isDeclared(_atom))\n\t\t\t\t\treturn smtutil::Expression(_atom, {}, m_context.getDeclaredSort(_atom));\n\t\t\t\telse if (auto maybeTupleType = m_context.getTupleType(_atom); maybeTupleType.has_value())\n\t\t\t\t{\n\t\t\t\t\t// 0-ary tuple type, can happen\n\t\t\t\t\treturn smtutil::Expression(_atom, {}, std::make_shared<TupleSort>(_atom, std::vector<std::string>{}, std::vector<SortPointer>{}));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tsmtSolverInteractionRequire(false, \"Unhandled atomic SMT expression\");\n\t\t\t},\n\t\t\t[&](std::vector<SMTLib2Expression> const& _subExpr)\n\t\t\t{\n\t\t\t\tSortPointer sort;\n\t\t\t\tstd::vector<smtutil::Expression> arguments;\n\t\t\t\tif (isAtom(_subExpr.front()))\n\t\t\t\t{\n\t\t\t\t\tstd::string const& op = asAtom(_subExpr.front());\n\t\t\t\t\tif (op == \"!\")\n\t\t\t\t\t{\n\t\t\t\t\t\t// named term, we ignore the name\n\t\t\t\t\t\tsmtSolverInteractionRequire(_subExpr.size() > 2, \"Wrong format of named SMT-LIB term\");\n\t\t\t\t\t\treturn toSMTUtilExpression(_subExpr[1]);\n\t\t\t\t\t}\n\t\t\t\t\tif (op == \"exists\" || op == \"forall\")\n\t\t\t\t\t{\n\t\t\t\t\t\tsmtSolverInteractionRequire(_subExpr.size() == 3, \"Wrong format of quantified expression\");\n\t\t\t\t\t\tsmtSolverInteractionRequire(!isAtom(_subExpr[1]), \"Wrong format of quantified expression\");\n\t\t\t\t\t\treturn parseQuantifier(op, asSubExpressions(_subExpr[1]), _subExpr[2]);\n\t\t\t\t\t}\n\t\t\t\t\tfor (size_t i = 1; i < _subExpr.size(); i++)\n\t\t\t\t\t\targuments.emplace_back(toSMTUtilExpression(_subExpr[i]));\n\t\t\t\t\tif (auto tupleSort = lookupKnownTupleSort(op); tupleSort)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto sortSort = std::make_shared<SortSort>(tupleSort.value());\n\t\t\t\t\t\treturn Expression::tuple_constructor(Expression(sortSort), arguments);\n\t\t\t\t\t}\n\t\t\t\t\tif (m_context.isDeclared(op))\n\t\t\t\t\t\treturn smtutil::Expression(op, std::move(arguments), m_context.getDeclaredSort(op));\n\t\t\t\t\tif (auto maybeTupleAccessor = m_context.getTupleAccessor(op); maybeTupleAccessor.has_value())\n\t\t\t\t\t{\n\t\t\t\t\t\tauto accessor = maybeTupleAccessor.value();\n\t\t\t\t\t\treturn smtutil::Expression(\"dt_accessor_\" + accessor.first, std::move(arguments), accessor.second);\n\t\t\t\t\t}\n\t\t\t\t\tif (op == \"select\")\n\t\t\t\t\t{\n\t\t\t\t\t\tsmtSolverInteractionRequire(arguments.size() == 2, \"Select has two arguments: array and index\");\n\t\t\t\t\t\treturn smtutil::Expression::select(arguments[0], arguments[1]);\n\t\t\t\t\t}\n\t\t\t\t\tif (op == \"store\")\n\t\t\t\t\t{\n\t\t\t\t\t\tsmtSolverInteractionRequire(arguments.size() == 3, \"Store has three arguments: array, index and element\");\n\t\t\t\t\t\treturn smtutil::Expression::store(arguments[0], arguments[1], arguments[2]);\n\t\t\t\t\t}\n\t\t\t\t\tif (op == \"bv2int\")\n\t\t\t\t\t{\n\t\t\t\t\t\tsmtSolverInteractionRequire(arguments.size() == 1, \"bv2int has one argument\");\n\t\t\t\t\t\treturn smtutil::Expression::bv2int(arguments[0]);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tstd::set<std::string> boolOperators{\"and\", \"or\", \"not\", \"=\", \"<\", \">\", \"<=\", \">=\", \"=>\"};\n\t\t\t\t\t\tsort = contains(boolOperators, op) ? SortProvider::boolSort : arguments.back().sort;\n\t\t\t\t\t\treturn smtutil::Expression(op, std::move(arguments), std::move(sort));\n\t\t\t\t\t}\n\t\t\t\t\tsmtSolverInteractionRequire(false, \"Unhandled case in expression conversion\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// check for const array\n\t\t\t\t\tif (_subExpr.size() == 2 and !isAtom(_subExpr[0]))\n\t\t\t\t\t{\n\t\t\t\t\t\tauto const& typeArgs = asSubExpressions(_subExpr.front());\n\t\t\t\t\t\tif (typeArgs.size() == 3 && typeArgs[0].toString() == \"as\"\n\t\t\t\t\t\t\t&& typeArgs[1].toString() == \"const\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tauto arraySort = toSort(typeArgs[2]);\n\t\t\t\t\t\t\tauto sortSort = std::make_shared<SortSort>(arraySort);\n\t\t\t\t\t\t\treturn smtutil::Expression::\n\t\t\t\t\t\t\t\tconst_array(Expression(sortSort), toSMTUtilExpression(_subExpr[1]));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeArgs.size() == 3 && typeArgs[0].toString() == \"_\"\n\t\t\t\t\t\t\t&& typeArgs[1].toString() == \"int2bv\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tauto bvSort = std::dynamic_pointer_cast<BitVectorSort>(toSort(_subExpr[0]));\n\t\t\t\t\t\t\tsmtSolverInteractionRequire(bvSort, \"Invalid format of bitvector sort\");\n\t\t\t\t\t\t\treturn smtutil::Expression::int2bv(toSMTUtilExpression(_subExpr[1]), bvSort->size);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeArgs.size() == 4 && typeArgs[0].toString() == \"_\"\n\t\t\t\t\t\t\t&& typeArgs[1].toString() == \"extract\")\n\t\t\t\t\t\t\treturn smtutil::Expression(\n\t\t\t\t\t\t\t\t\"extract\",\n\t\t\t\t\t\t\t\t{toSMTUtilExpression(typeArgs[2]), toSMTUtilExpression(typeArgs[3])},\n\t\t\t\t\t\t\t\tSortProvider::bitVectorSort // TODO: Compute bit size properly?\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tsmtSolverInteractionRequire(false, \"Unhandled case in expression conversion\");\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t_expr.data\n\t);\n}\n\n\nCHCSmtLib2Interface::Invariants CHCSmtLib2Interface::invariantsFromSolverResponse(std::string const& _response) const\n{\n\tstd::stringstream ss(_response);\n\tstd::string answer;\n\tss >> answer;\n\tsmtSolverInteractionRequire(answer == \"sat\", \"CHC model can only be extracted from sat answer\");\n\tSMTLib2Parser parser(ss);\n\tif (parser.isEOF())\n\t\treturn {};\n\tstd::vector<SMTLib2Expression> parsedOutput;\n\ttry\n\t{\n\t\twhile (!parser.isEOF())\n\t\t\tparsedOutput.push_back(parser.parseExpression());\n\t}\n\tcatch(SMTLib2Parser::ParsingException&)\n\t{\n\t\tsmtSolverInteractionRequire(false, \"Error during parsing CHC model\");\n\t}\n\tsmtSolverInteractionRequire(parser.isEOF(), \"Error during parsing CHC model\");\n\tsmtSolverInteractionRequire(!parsedOutput.empty(), \"Error during parsing CHC model\");\n\tauto& commands = parsedOutput.size() == 1 ? asSubExpressions(parsedOutput[0]) : parsedOutput;\n\tInvariants definitions;\n\tfor (auto& command: commands)\n\t{\n\t\tauto& args = asSubExpressions(command);\n\t\tsmtSolverInteractionRequire(args.size() == 5, \"Invalid format of CHC model\");\n\t\t// args[0] = \"define-fun\"\n\t\t// args[1] = predicate name\n\t\t// args[2] = formal arguments of the predicate\n\t\t// args[3] = return sort\n\t\t// args[4] = body of the predicate's interpretation\n\t\tsmtSolverInteractionRequire(isAtom(args[0]) && asAtom(args[0]) == \"define-fun\", \"Invalid format of CHC model\");\n\t\tsmtSolverInteractionRequire(isAtom(args[1]), \"Invalid format of CHC model\");\n\t\tsmtSolverInteractionRequire(!isAtom(args[2]), \"Invalid format of CHC model\");\n\t\tsmtSolverInteractionRequire(isAtom(args[3]) && asAtom(args[3]) == \"Bool\", \"Invalid format of CHC model\");\n\t\tauto& interpretation = args[4];\n\t\tinlineLetExpressions(interpretation);\n\t\tScopedParser scopedParser(m_context);\n\t\tauto const& formalArguments = asSubExpressions(args[2]);\n\t\tstd::vector<std::string> predicateArguments;\n\t\tfor (auto const& formalArgument: formalArguments)\n\t\t{\n\t\t\tsmtSolverInteractionRequire(!isAtom(formalArgument), \"Invalid format of CHC model\");\n\t\t\tauto const& nameSortPair = asSubExpressions(formalArgument);\n\t\t\tsmtSolverInteractionRequire(nameSortPair.size() == 2, \"Invalid format of CHC model\");\n\t\t\tsmtSolverInteractionRequire(isAtom(nameSortPair[0]), \"Invalid format of CHC model\");\n\t\t\tSortPointer varSort = scopedParser.toSort(nameSortPair[1]);\n\t\t\tscopedParser.addVariableDeclaration(asAtom(nameSortPair[0]), varSort);\n\t\t\tpredicateArguments.push_back(asAtom(nameSortPair[0]));\n\t\t}\n\n\t\tauto parsedInterpretation = scopedParser.toSMTUtilExpression(interpretation);\n\n\t\t// Hack to make invariants more stable across operating systems\n\t\tif (parsedInterpretation.name == \"and\" || parsedInterpretation.name == \"or\")\n\t\t\tranges::sort(parsedInterpretation.arguments, [](Expression const& first, Expression const& second) {\n\t\t\t\treturn first.name < second.name;\n\t\t\t});\n\n\t\tstd::string const& predicateName = asAtom(args[1]);\n\t\tsmtSolverInteractionRequire(!definitions.contains(predicateName), \"Predicates must be unique\");\n\t\tdefinitions.emplace(predicateName, InvariantInfo{parsedInterpretation, predicateArguments});\n\t}\n\treturn definitions;\n}\n\nnamespace\n{\n\nstruct LetBindings\n{\n\tusing BindingRecord = std::vector<SMTLib2Expression>;\n\tstd::unordered_map<std::string, BindingRecord> bindings;\n\tstd::vector<std::string> varNames;\n\tstd::vector<std::size_t> scopeBounds;\n\n\tbool has(std::string const& varName) { return bindings.find(varName) != bindings.end(); }\n\n\tSMTLib2Expression& operator[](std::string const& varName)\n\t{\n\t\tauto it = bindings.find(varName);\n\t\tsmtSolverInteractionRequire(it != bindings.end(), \"Error in processing let bindings\");\n\t\tsmtSolverInteractionRequire(!it->second.empty(), \"Error in processing let bindings\");\n\t\treturn it->second.back();\n\t}\n\n\tvoid pushScope() { scopeBounds.push_back(varNames.size()); }\n\n\tvoid popScope()\n\t{\n\t\tsmtSolverInteractionRequire(!scopeBounds.empty(), \"Error in processing let bindings\");\n\t\tauto bound = scopeBounds.back();\n\t\twhile (varNames.size() > bound)\n\t\t{\n\t\t\tauto const& varName = varNames.back();\n\t\t\tauto it = bindings.find(varName);\n\t\t\tsmtSolverInteractionRequire(it != bindings.end(), \"Error in processing let bindings\");\n\t\t\tauto& record = it->second;\n\t\t\trecord.pop_back();\n\t\t\tif (record.empty())\n\t\t\t\tbindings.erase(it);\n\t\t\tvarNames.pop_back();\n\t\t}\n\t\tscopeBounds.pop_back();\n\t}\n\n\tvoid addBinding(std::string name, SMTLib2Expression expression)\n\t{\n\t\tauto it = bindings.find(name);\n\t\tif (it == bindings.end())\n\t\t\tbindings.insert({name, {std::move(expression)}});\n\t\telse\n\t\t\tit->second.push_back(std::move(expression));\n\t\tvarNames.push_back(std::move(name));\n\t}\n};\n\nvoid inlineLetExpressions(SMTLib2Expression& _expr, LetBindings& _bindings)\n{\n\tif (isAtom(_expr))\n\t{\n\t\tauto const& atom = asAtom(_expr);\n\t\tif (_bindings.has(atom))\n\t\t\t_expr = _bindings[atom];\n\t\treturn;\n\t}\n\tauto& subexprs = asSubExpressions(_expr);\n\tsmtSolverInteractionRequire(!subexprs.empty(), \"Invalid let expression\");\n\tauto const& first = subexprs.at(0);\n\tif (isAtom(first) && asAtom(first) == \"let\")\n\t{\n\t\tsmtSolverInteractionRequire(subexprs.size() == 3, \"Invalid let expression\");\n\t\tsmtSolverInteractionRequire(!isAtom(subexprs[1]), \"Invalid let expression\");\n\t\tauto& bindingExpressions = asSubExpressions(subexprs[1]);\n\t\t// process new bindings\n\t\tstd::vector<std::pair<std::string, SMTLib2Expression>> newBindings;\n\t\tfor (auto& binding: bindingExpressions)\n\t\t{\n\t\t\tsmtSolverInteractionRequire(!isAtom(binding), \"Invalid let expression\");\n\t\t\tauto& bindingPair = asSubExpressions(binding);\n\t\t\tsmtSolverInteractionRequire(bindingPair.size() == 2, \"Invalid let expression\");\n\t\t\tsmtSolverInteractionRequire(isAtom(bindingPair.at(0)), \"Invalid let expression\");\n\t\t\tinlineLetExpressions(bindingPair.at(1), _bindings);\n\t\t\tnewBindings.emplace_back(asAtom(bindingPair.at(0)), bindingPair.at(1));\n\t\t}\n\t\t_bindings.pushScope();\n\t\tfor (auto&& [name, expr]: newBindings)\n\t\t\t_bindings.addBinding(std::move(name), std::move(expr));\n\n\t\tnewBindings.clear();\n\n\t\t// get new subexpression\n\t\tinlineLetExpressions(subexprs.at(2), _bindings);\n\t\t// remove the new bindings\n\t\t_bindings.popScope();\n\n\t\t// update the expression\n\t\tauto tmp = std::move(subexprs.at(2));\n\t\t_expr = std::move(tmp);\n\t\treturn;\n\t}\n\telse if (isAtom(first) && (asAtom(first) == \"forall\" || asAtom(first) == \"exists\"))\n\t{\n\t\t// A little hack to ensure quantified variables are not substituted because of some outer let definition:\n\t\t// We define the current binding of the variable to itself, before we recurse in to subterm\n\t\tsmtSolverInteractionRequire(subexprs.size() == 3, \"Invalid let expression\");\n\t\t_bindings.pushScope();\n\t\tfor (auto const& sortedVar: asSubExpressions(subexprs.at(1)))\n\t\t{\n\t\t\tauto const& varNameExpr = asSubExpressions(sortedVar).at(0);\n\t\t\t_bindings.addBinding(asAtom(varNameExpr), varNameExpr);\n\t\t}\n\t\tinlineLetExpressions(subexprs.at(2), _bindings);\n\t\t_bindings.popScope();\n\t\treturn;\n\t}\n\n\t// not a let expression, just process all arguments recursively\n\tfor (auto& subexpr: subexprs)\n\t\tinlineLetExpressions(subexpr, _bindings);\n}\n}\n\nvoid CHCSmtLib2Interface::inlineLetExpressions(SMTLib2Expression& expr)\n{\n\tLetBindings bindings;\n\t::inlineLetExpressions(expr, bindings);\n}\n"
  },
  {
    "path": "libsmtutil/CHCSmtLib2Interface.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n/**\n * Interface for solving Horn systems via smtlib2.\n */\n\n#pragma once\n\n#include <libsmtutil/CHCSolverInterface.h>\n\n#include <libsmtutil/SMTLib2Interface.h>\n#include <libsmtutil/SMTLib2Parser.h>\n\nnamespace solidity::smtutil\n{\n\nclass CHCSmtLib2Interface: public CHCSolverInterface\n{\npublic:\n\texplicit CHCSmtLib2Interface(\n\t\tstd::map<util::h256, std::string> _queryResponses = {},\n\t\tfrontend::ReadCallback::Callback _smtCallback = {},\n\t\tstd::optional<unsigned> _queryTimeout = {}\n\t);\n\n\tvoid reset();\n\n\tvoid registerRelation(Expression const& _expr) override;\n\n\tvoid addRule(Expression const& _expr, std::string const& _name) override;\n\n\t/// Takes a function application _expr and checks for reachability.\n\t/// @returns solving result, an invariant, and counterexample graph, if possible.\n\tQueryResult query(Expression const& _expr) override;\n\n\tvoid declareVariable(std::string const& _name, SortPointer const& _sort) override;\n\n\tstd::string dumpQuery(Expression const& _expr);\n\n\tstd::vector<std::string> unhandledQueries() const { return m_unhandledQueries; }\n\nprotected:\n\tclass ScopedParser\n\t{\n\tpublic:\n\t\tScopedParser(SMTLib2Context const& _context): m_context(_context) {}\n\n\t\tsmtutil::Expression toSMTUtilExpression(SMTLib2Expression const& _expr);\n\n\t\tSortPointer toSort(SMTLib2Expression const& _expr);\n\n\t\tvoid addVariableDeclaration(std::string _name, SortPointer _sort);\n\n\tprivate:\n\t\tstd::optional<SortPointer> lookupKnownTupleSort(std::string const& _name) const;\n\n\t\tsmtutil::Expression parseQuantifier(\n\t\t\tstd::string const& _quantifierName,\n\t\t\tstd::vector<SMTLib2Expression> const& _varList,\n\t\t\tSMTLib2Expression const& _coreExpression\n\t\t\t);\n\n\t\tSMTLib2Context const& m_context;\n\t\tstd::unordered_map<std::string, SortPointer> m_localVariables;\n\t};\n\n\t/* Modifies the passed expression by inlining all let subexpressions */\n\tstatic void inlineLetExpressions(SMTLib2Expression& _expr);\n\n\tstd::string toSmtLibSort(SortPointer const& _sort);\n\tstd::vector<std::string> toSmtLibSort(std::vector<SortPointer> const& _sort);\n\n\tstd::string forall(Expression const& _expr);\n\n\tstatic std::string createQueryAssertion(std::string _name);\n\tvoid createHeader();\n\n\t/// Communicates with the solver via the callback. Throws SMTSolverError on error.\n\tvirtual std::string querySolver(std::string const& _input);\n\n\t/// Translates CHC solver response with a model to our representation of invariants.\n\tInvariants invariantsFromSolverResponse(std::string const& _response) const;\n\n\tstd::set<std::string> collectVariableNames(Expression const& _expr) const;\n\n\tSMTLib2Commands m_commands;\n\tSMTLib2Context m_context;\n\n\tstd::map<util::h256, std::string> m_queryResponses;\n\tstd::vector<std::string> m_unhandledQueries;\n\n\tfrontend::ReadCallback::Callback m_smtCallback;\n};\n\n}\n"
  },
  {
    "path": "libsmtutil/CHCSolverInterface.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n/**\n * Interface for constrained Horn solvers.\n */\n\n#pragma once\n\n#include <libsmtutil/SolverInterface.h>\n\n#include <map>\n#include <unordered_map>\n#include <vector>\n\nnamespace solidity::smtutil\n{\n\nclass CHCSolverInterface : public SolverInterface\n{\npublic:\n\tCHCSolverInterface(std::optional<unsigned> _queryTimeout = {}): m_queryTimeout(_queryTimeout) {}\n\n\t/// Takes a function declaration as a relation.\n\tvirtual void registerRelation(Expression const& _expr) = 0;\n\n\t/// Takes an implication and adds as rule.\n\t/// Needs to bound all vars as universally quantified.\n\tvirtual void addRule(Expression const& _expr, std::string const& _name) = 0;\n\n\tusing CexNode = Expression;\n\tstruct CexGraph\n\t{\n\t\tstd::map<unsigned, CexNode> nodes;\n\t\tstd::map<unsigned, std::vector<unsigned>> edges;\n\t};\n\n\tstruct InvariantInfo\n\t{\n\t\t/// Predicate definition as SMT expression\n\t\tExpression expression;\n\t\t/// Names of the formal arguments of the predicate definition\n\t\tstd::vector<std::string> variableNames;\n\t};\n\t/// Maps predicate to its definition as given by the solver and the formal arguments of the predicate\n\tusing Invariants = std::unordered_map<std::string, InvariantInfo>;\n\tstruct QueryResult\n\t{\n\t\tCheckResult answer;\n\t\tInvariants invariants;\n\t\tCexGraph cex;\n\t};\n\t/// Takes a function application _expr and checks for reachability.\n\t/// @returns solving result, an invariant, and counterexample graph, if possible.\n\tvirtual QueryResult query(Expression const& _expr) = 0;\n\nprotected:\n\tstd::optional<unsigned> m_queryTimeout;\n};\n\n}\n"
  },
  {
    "path": "libsmtutil/CMakeLists.txt",
    "content": "set(sources\n\tCHCSmtLib2Interface.cpp\n\tCHCSmtLib2Interface.h\n\tExceptions.h\n\tSMTLib2Context.cpp\n\tSMTLib2Context.h\n\tSMTLib2Interface.cpp\n\tSMTLib2Interface.h\n\tSMTLib2Parser.cpp\n\tSMTLib2Parser.h\n\tSMTPortfolio.cpp\n\tSMTPortfolio.h\n\tSolverInterface.h\n\tSorts.cpp\n\tSorts.h\n\tHelpers.h\n)\n\n\nadd_library(smtutil ${sources})\ntarget_link_libraries(smtutil PUBLIC solutil Boost::boost)\n"
  },
  {
    "path": "libsmtutil/Exceptions.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/Assertions.h>\n#include <libsolutil/Exceptions.h>\n\n#include <boost/preprocessor/cat.hpp>\n#include <boost/preprocessor/facilities/empty.hpp>\n#include <boost/preprocessor/facilities/overload.hpp>\n\nnamespace solidity::smtutil\n{\n\nstruct SMTLogicError: virtual util::Exception {};\n\n/// Assertion that throws an SMTLogicError containing the given description if it is not met.\n#if !BOOST_PP_VARIADICS_MSVC\n#define smtAssert(...) BOOST_PP_OVERLOAD(smtAssert_,__VA_ARGS__)(__VA_ARGS__)\n#else\n#define smtAssert(...) BOOST_PP_CAT(BOOST_PP_OVERLOAD(smtAssert_,__VA_ARGS__)(__VA_ARGS__),BOOST_PP_EMPTY())\n#endif\n\n#define smtAssert_1(CONDITION) \\\n\tsmtAssert_2((CONDITION), \"\")\n\n#define smtAssert_2(CONDITION, DESCRIPTION) \\\n\tassertThrowWithDefaultDescription( \\\n\t\t(CONDITION), \\\n\t\t::solidity::smtutil::SMTLogicError, \\\n\t\t(DESCRIPTION), \\\n\t\t\"SMT assertion failed\" \\\n\t)\n\n\n// Error to indicate that some problem occurred during an interaction with external solver.\n// This could be a problem with calling the solver or unexpected situation during the processing of solver's response.\nstruct SMTSolverInteractionError: virtual util::Exception {};\n\n#define smtSolverInteractionRequire(CONDITION, DESCRIPTION) \\\n\tassertThrowWithDefaultDescription( \\\n\t\t(CONDITION), \\\n\t\t::solidity::smtutil::SMTSolverInteractionError, \\\n\t\t(DESCRIPTION), \\\n\t\t\"Encountered problem during interaction with a solver\" \\\n\t)\n}\n"
  },
  {
    "path": "libsmtutil/Helpers.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/SolverInterface.h>\n\nnamespace solidity::smtutil\n{\n\n/// Signed division in SMTLIB2 rounds differently than EVM.\n/// This does not check for division by zero!\ninline Expression signedDivisionEVM(Expression _left, Expression _right)\n{\n\treturn Expression::ite(\n\t\t_left >= 0,\n\t\tExpression::ite(_right >= 0, _left / _right, 0 - (_left / (0 - _right))),\n\t\tExpression::ite(_right >= 0, 0 - ((0 - _left) / _right), (0 - _left) / (0 - _right))\n\t);\n}\n\ninline Expression abs(Expression _value)\n{\n\treturn Expression::ite(_value >= 0, _value, 0 - _value);\n}\n\n/// Signed modulo in SMTLIB2 behaves differently with regards\n/// to the sign than EVM.\n/// This does not check for modulo by zero!\ninline Expression signedModuloEVM(Expression _left, Expression _right)\n{\n\treturn Expression::ite(\n\t\t_left >= 0,\n\t\t_left % _right,\n\t\tExpression::ite(\n\t\t\t(_left % _right) == 0,\n\t\t\t0,\n\t\t\t(_left % _right) - abs(_right)\n\t\t)\n\t);\n}\n\n}\n"
  },
  {
    "path": "libsmtutil/SMTLib2Context.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsmtutil/SMTLib2Context.h>\n\n#include <boost/functional/hash.hpp>\n\n#include <range/v3/algorithm/find_if.hpp>\n\nnamespace solidity::smtutil\n{\n\nstd::size_t SortPairHash::operator()(std::pair<SortId, SortId> const& _pair) const\n{\n\tstd::size_t seed = 0;\n\tboost::hash_combine(seed, _pair.first);\n\tboost::hash_combine(seed, _pair.second);\n\treturn seed;\n}\n\nSMTLib2Context::SMTLib2Context()\n{\n\tclear();\n}\n\nbool SMTLib2Context::isDeclared(std::string const& _name) const\n{\n\treturn m_functions.count(_name) > 0;\n}\n\nvoid SMTLib2Context::declare(std::string const& _name, SortPointer const& _sort)\n{\n\tauto [_, inserted] = m_functions.insert({_name, _sort});\n\tsmtAssert(inserted, \"Trying to redeclare SMT function!\");\n}\n\nSortPointer SMTLib2Context::getDeclaredSort(std::string const& _name) const\n{\n\tsmtAssert(isDeclared(_name));\n\treturn m_functions.at(_name);\n}\n\nvoid SMTLib2Context::clear() {\n\tm_functions.clear();\n\tm_knownTypes.clear();\n\tm_arraySorts.clear();\n\tm_tupleSorts.clear();\n\tm_bitVectorSorts.clear();\n\tm_callback = {};\n\tm_knownTypes.emplace_back(std::make_unique<SMTLibSort>(Kind::Bool, std::string(\"Bool\"), std::vector<SortId>{}, SortId{0u}));\n\tm_knownTypes.emplace_back(std::make_unique<SMTLibSort>(Kind::Int, std::string(\"Int\"), std::vector<SortId>{}, SortId{1u}));\n\tassert(m_boolSort == m_knownTypes[0]->id);\n\tassert(m_intSort == m_knownTypes[1]->id);\n}\n\nSortId SMTLib2Context::resolve(SortPointer const& _sort)\n{\n\tswitch (_sort->kind)\n\t{\n\tcase Kind::Int:\n\t\treturn m_intSort;\n\tcase Kind::Bool:\n\t\treturn m_boolSort;\n\tcase Kind::BitVector:\n\t\treturn resolveBitVectorSort(dynamic_cast<BitVectorSort const&>(*_sort));\n\tcase Kind::Array:\n\t\treturn resolveArraySort(dynamic_cast<ArraySort const&>(*_sort));\n\tcase Kind::Tuple:\n\t\treturn resolveTupleSort(dynamic_cast<TupleSort const&>(*_sort));\n\tdefault:\n\t\tsmtAssert(false, \"Invalid SMT sort\");\n\t}\n}\n\nSortPointer SMTLib2Context::unresolve(SortId _sortId) const\n{\n\tsmtAssert(_sortId < m_knownTypes.size());\n\tauto const& type = *m_knownTypes[_sortId];\n\tswitch (type.kind)\n\t{\n\tcase Kind::Int:\n\t\treturn SortProvider::sintSort;\n\tcase Kind::Bool:\n\t\treturn SortProvider::boolSort;\n\tcase Kind::BitVector:\n\t{\n\t\tauto it = ranges::find_if(m_bitVectorSorts, [&](auto const& entry) { return entry.second == _sortId; });\n\t\tsmtAssert(it != m_bitVectorSorts.end());\n\t\treturn std::make_shared<BitVectorSort>(it->first);\n\t}\n\tcase Kind::Array:\n\t{\n\t\tauto it = ranges::find_if(m_arraySorts, [&](auto const& entry) { return entry.second == _sortId; });\n\t\tsmtAssert(it != m_arraySorts.end());\n\t\treturn std::make_shared<ArraySort>(unresolve(it->first.first), unresolve(it->first.second));\n\t}\n\tcase Kind::Tuple:\n\t{\n\t\tauto const& tupleType = dynamic_cast<TupleType const&>(type);\n\t\tstd::vector<std::string> memberNames;\n\t\tstd::vector<SortPointer> memberTypes;\n\t\tfor (auto&& [name, sortId] : tupleType.accessors)\n\t\t{\n\t\t\tmemberNames.push_back(name);\n\t\t\tmemberTypes.push_back(unresolve(sortId));\n\t\t}\n\t\treturn std::make_shared<TupleSort>(tupleType.name, std::move(memberNames), std::move(memberTypes));\n\t}\n\tdefault:\n\t\tsmtAssert(false, \"Invalid SMT sort\");\n\t}\n}\n\nSortId SMTLib2Context::resolveBitVectorSort(BitVectorSort const& _sort)\n{\n\tauto size = _sort.size;\n\tauto it = m_bitVectorSorts.find(size);\n\tif (it == m_bitVectorSorts.end())\n\t{\n\t\tauto newId = static_cast<uint32_t>(m_knownTypes.size());\n\t\tm_knownTypes.emplace_back(std::make_unique<SMTLibSort>(Kind::BitVector, \"(_ BitVec \" + std::to_string(size) + ')', std::vector<SortId>{}, SortId{newId}));\n\t\tauto&& [newIt, inserted] = m_bitVectorSorts.emplace(size, SortId{newId});\n\t\tsmtAssert(inserted);\n\t\treturn newIt->second;\n\t}\n\treturn it->second;\n}\n\nSortId SMTLib2Context::resolveArraySort(ArraySort const& _sort)\n{\n\tsmtAssert(_sort.domain && _sort.range);\n\tauto domainSort = resolve(_sort.domain);\n\tauto rangeSort = resolve(_sort.range);\n\tauto pair = std::make_pair(domainSort, rangeSort);\n\tauto it = m_arraySorts.find(pair);\n\tif (it == m_arraySorts.end())\n\t{\n\t\tauto newId = static_cast<uint32_t>(m_knownTypes.size());\n\t\tm_knownTypes.emplace_back(std::make_unique<SMTLibSort>(Kind::Array, \"Array\", std::vector<SortId>{domainSort, rangeSort}, SortId{newId}));\n\t\tauto&& [newIt, inserted] = m_arraySorts.emplace(pair, SortId{newId});\n\t\tsmtAssert(inserted);\n\t\treturn newIt->second;\n\t}\n\treturn it->second;\n}\n\nSortId SMTLib2Context::resolveTupleSort(TupleSort const& _sort)\n{\n\tauto const& tupleName = _sort.name;\n\tauto it = m_tupleSorts.find(tupleName);\n\tif (it == m_tupleSorts.end())\n\t{\n\t\tstd::vector<std::pair<std::string, SortId>> accessors;\n\t\tsmtAssert(_sort.members.size() == _sort.components.size());\n\t\tfor (std::size_t i = 0u; i < _sort.members.size(); ++i)\n\t\t\taccessors.emplace_back(_sort.members[i], resolve(_sort.components[i]));\n\t\tauto newId = static_cast<uint32_t>(m_knownTypes.size());\n\t\tm_knownTypes.emplace_back(std::make_unique<TupleType>(tupleName, std::move(accessors), SortId{newId}));\n\t\tauto&& [newIt, inserted] = m_tupleSorts.emplace(tupleName, SortId{newId});\n\t\tsmtAssert(inserted);\n\t\tif (m_callback)\n\t\t\tm_callback(_sort);\n\t\treturn newIt->second;\n\t}\n\treturn it->second;\n}\n\nstd::string SMTLib2Context::toString(SortId _id)\n{\n\tauto const& sort = m_knownTypes.at(_id);\n\tswitch (sort->kind)\n\t{\n\tcase Kind::Int:\n\t\treturn \"Int\";\n\tcase Kind::Bool:\n\t\treturn \"Bool\";\n\tcase Kind::BitVector:\n\t\treturn dynamic_cast<SMTLibSort const&>(*sort).name;\n\tcase Kind::Array:\n\t{\n\t\tauto const& arraySort = dynamic_cast<SMTLibSort const&>(*sort);\n\t\tsmtAssert(arraySort.args.size() == 2);\n\t\treturn \"(Array \" + toString(arraySort.args.at(0)) + ' ' + toString(arraySort.args.at(1)) + ')';\n\t}\n\tcase Kind::Tuple:\n\t{\n\t\tauto const& tupleType = dynamic_cast<TupleType const&>(*sort);\n\t\treturn '|' + tupleType.name + '|';\n\t}\n\tdefault:\n\t\tsmtAssert(false, \"Invalid SMT sort\");\n\t}\n}\n\nstd::string SMTLib2Context::toSmtLibSort(solidity::smtutil::SortPointer const& _sort)\n{\n\treturn toString(resolve(_sort));\n}\n\nstd::string SMTLib2Context::toSExpr(Expression const& _expr)\n{\n\tif (_expr.arguments.empty())\n\t\treturn _expr.name;\n\n\tstd::string sexpr = \"(\";\n\tif (_expr.name == \"int2bv\")\n\t{\n\t\tsize_t size = std::stoul(_expr.arguments[1].name);\n\t\tauto arg = toSExpr(_expr.arguments.front());\n\t\tauto int2bv = \"(_ int2bv \" + std::to_string(size) + \")\";\n\t\t// Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed.\n\t\tsexpr += std::string(\"ite \") +\n\t\t\t\"(>= \" + arg + \" 0) \" +\n\t\t\t\"(\" + int2bv + \" \" + arg + \") \" +\n\t\t\t\"(bvneg (\" + int2bv + \" (- \" + arg + \")))\";\n\t}\n\telse if (_expr.name == \"bv2int\")\n\t{\n\t\tauto intSort = std::dynamic_pointer_cast<IntSort>(_expr.sort);\n\t\tsmtAssert(intSort, \"\");\n\n\t\tauto arg = toSExpr(_expr.arguments.front());\n\t\tauto nat = \"(bv2nat \" + arg + \")\";\n\n\t\tif (!intSort->isSigned)\n\t\t\treturn nat;\n\n\t\tauto bvSort = std::dynamic_pointer_cast<BitVectorSort>(_expr.arguments.front().sort);\n\t\tsmtAssert(bvSort, \"\");\n\t\tauto size = std::to_string(bvSort->size);\n\t\tauto pos = std::to_string(bvSort->size - 1);\n\n\t\t// Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed.\n\t\tsexpr += std::string(\"ite \") +\n\t\t\t\"(= ((_ extract \" + pos + \" \" + pos + \")\" + arg + \") #b0) \" +\n\t\t\tnat + \" \" +\n\t\t\t\"(- (bv2nat (bvneg \" + arg + \")))\";\n\t}\n\telse if (_expr.name == \"const_array\")\n\t{\n\t\tsmtAssert(_expr.arguments.size() == 2, \"\");\n\t\tauto sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments.at(0).sort);\n\t\tsmtAssert(sortSort, \"\");\n\t\tauto arraySort = std::dynamic_pointer_cast<ArraySort>(sortSort->inner);\n\t\tsmtAssert(arraySort, \"\");\n\t\tsexpr += \"(as const \" + toSmtLibSort(arraySort) + \") \";\n\t\tsexpr += toSExpr(_expr.arguments.at(1));\n\t}\n\telse if (_expr.name == \"tuple_get\")\n\t{\n\t\tsmtAssert(_expr.arguments.size() == 2, \"\");\n\t\tauto tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.arguments.at(0).sort);\n\t\tsize_t index = std::stoul(_expr.arguments.at(1).name);\n\t\tsmtAssert(index < tupleSort->members.size(), \"\");\n\t\tsexpr += \"|\" + tupleSort->members.at(index) + \"| \" + toSExpr(_expr.arguments.at(0));\n\t}\n\telse if (_expr.name == \"tuple_constructor\")\n\t{\n\t\tauto tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.sort);\n\t\tsmtAssert(tupleSort, \"\");\n\t\tsexpr += \"|\" + tupleSort->name + \"|\";\n\t\tfor (auto const& arg: _expr.arguments)\n\t\t\tsexpr += \" \" + toSExpr(arg);\n\t}\n\telse\n\t{\n\t\tsexpr += _expr.name;\n\t\tfor (auto const& arg: _expr.arguments)\n\t\t\tsexpr += \" \" + toSExpr(arg);\n\t}\n\tsexpr += \")\";\n\treturn sexpr;\n}\n\nstd::optional<SortPointer> SMTLib2Context::getTupleType(std::string const& _name) const\n{\n\tauto it = m_tupleSorts.find(_name);\n\treturn it == m_tupleSorts.end() ? std::nullopt : std::optional<SortPointer>(unresolve(it->second));\n}\n\nstd::optional<std::pair<std::string, SortPointer>> SMTLib2Context::getTupleAccessor(std::string const& _name) const\n{\n\tfor (auto&& [_, sortId] : m_tupleSorts)\n\t{\n\t\tauto const& type = m_knownTypes.at(sortId);\n\t\tsmtAssert(type->kind == Kind::Tuple);\n\t\tauto const& tupleType = dynamic_cast<TupleType const&>(*type);\n\t\tfor (auto&& [memberName, memberSort] : tupleType.accessors)\n\t\t\tif (memberName == _name)\n\t\t\t\treturn std::make_pair(memberName, unresolve(memberSort));\n\t}\n\treturn std::nullopt;\n}\n\nvoid SMTLib2Context::setTupleDeclarationCallback(TupleDeclarationCallback _callback)\n{\n\tm_callback = std::move(_callback);\n}\n} // namespace solidity::smtutil\n"
  },
  {
    "path": "libsmtutil/SMTLib2Context.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/SolverInterface.h>\n#include <libsmtutil/Sorts.h>\n\n#include <string>\n#include <unordered_map>\n#include <unordered_set>\n\nnamespace solidity::smtutil\n{\n\nusing SortId = uint32_t;\nstruct SortPairHash\n{\n\tstd::size_t operator()(std::pair<SortId, SortId> const& _pair) const;\n};\n\nstruct SMTLibType {\n\tKind const kind;\n\tSortId const id;\n\tSMTLibType(Kind _kind, SortId _id): kind(_kind), id(_id) {}\n\tvirtual ~SMTLibType() = default;\n};\n\nstruct SMTLibSort : public SMTLibType\n{\n\tstd::string const name;\n\tstd::vector<SortId> const args;\n\n\tSMTLibSort(\n\t\tKind _kind,\n\t\tstd::string_view _name,\n\t\tstd::vector<SortId> _args,\n\t\tSortId _id\n\t): SMTLibType(_kind, _id), name(_name), args(std::move(_args)) {}\n};\n\nstruct TupleType : public SMTLibType\n{\n\tstd::string const name;\n\tstd::vector<std::pair<std::string,SortId>> accessors;\n\n\tTupleType(std::string_view _name, std::vector<std::pair<std::string,SortId>> _accessors, SortId _id)\n\t: SMTLibType(Kind::Tuple, _id), name(_name), accessors(std::move(_accessors)) {}\n};\n\nclass SMTLib2Context\n{\npublic:\n\tusing TupleDeclarationCallback = std::function<void(TupleSort const&)>;\n\n\tSMTLib2Context();\n\tvoid clear();\n\n\tbool isDeclared(std::string const& _name) const;\n\tvoid declare(std::string const& _name, SortPointer const& _sort);\n\tSortPointer getDeclaredSort(std::string const& _name) const;\n\n\tSortId resolve(SortPointer const& _sort);\n\tSortPointer unresolve(SortId _sortId) const;\n\n\tstd::string toString(SortId _id);\n\n\tstd::string toSExpr(Expression const& _expr);\n\tstd::string toSmtLibSort(SortPointer const& _sort);\n\n\tstd::optional<SortPointer> getTupleType(std::string const& _name) const;\n\tstd::optional<std::pair<std::string, SortPointer>> getTupleAccessor(std::string const& _name) const;\n\n\tvoid setTupleDeclarationCallback(TupleDeclarationCallback _callback);\nprivate:\n\tSortId resolveBitVectorSort(BitVectorSort const& _sort);\n\tSortId resolveArraySort(ArraySort const& _sort);\n\tSortId resolveTupleSort(TupleSort const& _sort);\n\n\tusing functions_t = std::map<std::string, SortPointer>;\n\tfunctions_t m_functions; // Variables are uninterpreted constants = nullary functions\n\n\tSortId const m_boolSort{0u};\n\tSortId const m_intSort{1u};\n\tstd::vector<std::unique_ptr<SMTLibType>> m_knownTypes;\n\tstd::unordered_map<std::pair<SortId, SortId>, SortId, SortPairHash> m_arraySorts;\n\tstd::unordered_map<std::size_t, SortId> m_bitVectorSorts;\n\tstd::unordered_map<std::string, SortId> m_tupleSorts;\n\n\tTupleDeclarationCallback m_callback;\n};\n\n}\n\n"
  },
  {
    "path": "libsmtutil/SMTLib2Interface.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsmtutil/SMTLib2Interface.h>\n\n#include <libsmtutil/SMTLib2Parser.h>\n\n#include <libsolutil/Keccak256.h>\n\n#include <boost/algorithm/string/join.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n\n#include <range/v3/view/transform.hpp>\n#include <range/v3/view/zip.hpp>\n\n#include <array>\n#include <fstream>\n#include <iostream>\n#include <memory>\n#include <stdexcept>\n#include <string>\n#include <utility>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::frontend;\nusing namespace solidity::smtutil;\n\nSMTLib2Interface::SMTLib2Interface(\n\tstd::map<h256, std::string> _queryResponses,\n\tReadCallback::Callback _smtCallback,\n\tstd::optional<unsigned> _queryTimeout\n):\n\tBMCSolverInterface(_queryTimeout),\n\tm_queryResponses(std::move(_queryResponses)),\n\tm_smtCallback(std::move(_smtCallback))\n{\n\treset();\n}\n\nvoid SMTLib2Interface::reset()\n{\n\tm_commands.clear();\n\tm_context.clear();\n\tm_commands.setOption(\"produce-models\", \"true\");\n\tif (m_queryTimeout)\n\t\tm_commands.setOption(\"timeout\", std::to_string(*m_queryTimeout));\n\tm_commands.setLogic(\"ALL\");\n\tm_context.setTupleDeclarationCallback([&](TupleSort const& tupleSort){\n\t\tm_commands.declareTuple(\n\t\t\ttupleSort.name,\n\t\t\ttupleSort.members,\n\t\t\ttupleSort.components\n\t\t\t\t| ranges::views::transform([&](SortPointer const& sort){ return m_context.toSmtLibSort(sort); })\n\t\t\t\t| ranges::to<std::vector>()\n\t\t);\n\t});\n}\n\nvoid SMTLib2Interface::push()\n{\n\tm_commands.push();\n}\n\nvoid SMTLib2Interface::pop()\n{\n\tm_commands.pop();\n}\n\nvoid SMTLib2Interface::declareVariable(std::string const& _name, SortPointer const& _sort)\n{\n\tsmtAssert(_sort);\n\tif (_sort->kind == Kind::Function)\n\t\tdeclareFunction(_name, _sort);\n\telse if (!m_context.isDeclared(_name))\n\t{\n\t\tm_context.declare(_name, _sort);\n\t\tm_commands.declareVariable(_name, toSmtLibSort(_sort));\n\t}\n}\n\nvoid SMTLib2Interface::declareFunction(std::string const& _name, SortPointer const& _sort)\n{\n\tsmtAssert(_sort);\n\tsmtAssert(_sort->kind == Kind::Function);\n\tif (!m_context.isDeclared(_name))\n\t{\n\t\tauto const& fSort = std::dynamic_pointer_cast<FunctionSort>(_sort);\n\t\tauto domain = toSmtLibSort(fSort->domain);\n\t\tstd::string codomain = toSmtLibSort(fSort->codomain);\n\t\tm_context.declare(_name, _sort);\n\t\tm_commands.declareFunction(_name, domain, codomain);\n\t}\n}\n\nvoid SMTLib2Interface::addAssertion(Expression const& _expr)\n{\n\tm_commands.assertion(toSExpr(_expr));\n}\n\nnamespace\n{\nstd::vector<std::string> parseValuesFromResponse(std::string const& _response)\n{\n\tstd::stringstream ss(_response);\n\tstd::string answer;\n\tss >> answer;\n\tsmtSolverInteractionRequire(answer == \"sat\", \"SMT: Parsing model values only possible after sat answer\");\n\n\tstd::vector<SMTLib2Expression> parsedOutput;\n\tSMTLib2Parser parser(ss);\n\ttry\n\t{\n\t\twhile (!parser.isEOF())\n\t\t\tparsedOutput.push_back(parser.parseExpression());\n\t}\n\tcatch(SMTLib2Parser::ParsingException&)\n\t{\n\t\tsmtSolverInteractionRequire(false, \"Error during parsing SMT answer\");\n\t}\n\tsmtSolverInteractionRequire(parsedOutput.size() == 1, \"SMT: Expected model values as a single s-expression\");\n\tauto const& values = parsedOutput[0];\n\tsmtSolverInteractionRequire(!isAtom(values), \"Invalid format of values in SMT answer\");\n\tstd::vector<std::string> parsedValues;\n\tfor (auto const& nameValuePair: asSubExpressions(values))\n\t{\n\t\tsmtSolverInteractionRequire(!isAtom(nameValuePair), \"Invalid format of values in SMT answer\");\n\t\tsmtSolverInteractionRequire(asSubExpressions(nameValuePair).size() == 2, \"Invalid format of values in SMT answer\");\n\t\tauto const& value = asSubExpressions(nameValuePair)[1];\n\t\tparsedValues.push_back(value.toString());\n\t}\n\treturn parsedValues;\n}\n} // namespace\n\nstd::pair<CheckResult, std::vector<std::string>> SMTLib2Interface::check(std::vector<Expression> const& _expressionsToEvaluate)\n{\n\tstd::string response = querySolver(dumpQuery(_expressionsToEvaluate));\n\n\tCheckResult result;\n\t// TODO proper parsing\n\tif (boost::starts_with(response, \"sat\"))\n\t\tresult = CheckResult::SATISFIABLE;\n\telse if (boost::starts_with(response, \"unsat\"))\n\t\tresult = CheckResult::UNSATISFIABLE;\n\telse if (boost::starts_with(response, \"unknown\"))\n\t\tresult = CheckResult::UNKNOWN;\n\telse\n\t\tresult = CheckResult::ERROR;\n\n\tstd::vector<std::string> values;\n\tif (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty())\n\t\tvalues = parseValuesFromResponse(response);\n\treturn std::make_pair(result, values);\n}\n\nstd::string SMTLib2Interface::toSmtLibSort(SortPointer _sort)\n{\n\treturn m_context.toSmtLibSort(std::move(_sort));\n}\n\nstd::vector<std::string> SMTLib2Interface::toSmtLibSort(std::vector<SortPointer> const& _sorts)\n{\n\tstd::vector<std::string> ssorts;\n\tssorts.reserve(_sorts.size());\n\tfor (auto const& sort: _sorts)\n\t\tssorts.push_back(toSmtLibSort(sort));\n\treturn ssorts;\n}\n\nstd::string SMTLib2Interface::toSExpr(solidity::smtutil::Expression const& _expr)\n{\n\treturn m_context.toSExpr(_expr);\n}\n\nstd::string SMTLib2Interface::checkSatAndGetValuesCommand(std::vector<Expression> const& _expressionsToEvaluate)\n{\n\tstd::string command;\n\tif (_expressionsToEvaluate.empty())\n\t\tcommand = \"(check-sat)\\n\";\n\telse\n\t{\n\t\t// TODO make sure these are unique\n\t\tfor (size_t i = 0; i < _expressionsToEvaluate.size(); i++)\n\t\t{\n\t\t\tauto const& e = _expressionsToEvaluate.at(i);\n\t\t\tsmtAssert(e.sort->kind == Kind::Int || e.sort->kind == Kind::Bool, \"Invalid sort for expression to evaluate.\");\n\t\t\tcommand += \"(declare-const |EVALEXPR_\" + std::to_string(i) + \"| \" + (e.sort->kind == Kind::Int ? \"Int\" : \"Bool\") + \")\\n\";\n\t\t\tcommand += \"(assert (= |EVALEXPR_\" + std::to_string(i) + \"| \" + toSExpr(e) + \"))\\n\";\n\t\t}\n\t\tcommand += \"(check-sat)\\n\";\n\t\tcommand += \"(get-value (\";\n\t\tfor (size_t i = 0; i < _expressionsToEvaluate.size(); i++)\n\t\t\tcommand += \"|EVALEXPR_\" + std::to_string(i) + \"| \";\n\t\tcommand += \"))\\n\";\n\t}\n\n\treturn command;\n}\n\nstd::string SMTLib2Interface::querySolver(std::string const& _input)\n{\n\th256 inputHash = keccak256(_input);\n\tif (m_queryResponses.count(inputHash))\n\t\treturn m_queryResponses.at(inputHash);\n\tif (m_smtCallback)\n\t{\n\t\tsetupSmtCallback();\n\t\tauto result = m_smtCallback(ReadCallback::kindString(ReadCallback::Kind::SMTQuery), _input);\n\t\tif (result.success)\n\t\t\treturn result.responseOrErrorMessage;\n\t}\n\tm_unhandledQueries.push_back(_input);\n\treturn \"unknown\\n\";\n}\n\nstd::string SMTLib2Interface::dumpQuery(std::vector<Expression> const& _expressionsToEvaluate)\n{\n\treturn m_commands.toString() + '\\n' + checkSatAndGetValuesCommand(_expressionsToEvaluate);\n}\n\n\nvoid SMTLib2Commands::push() {\n\tm_frameLimits.push_back(m_commands.size());\n}\n\nvoid SMTLib2Commands::pop() {\n\tsmtAssert(!m_commands.empty());\n\tauto limit = m_frameLimits.back();\n\tm_frameLimits.pop_back();\n\twhile (m_commands.size() > limit)\n\t\tm_commands.pop_back();\n}\n\nstd::string SMTLib2Commands::toString() const {\n\treturn boost::algorithm::join(m_commands, \"\\n\");\n}\n\nvoid SMTLib2Commands::clear() {\n\tm_commands.clear();\n\tm_frameLimits.clear();\n}\n\nvoid SMTLib2Commands::assertion(std::string _expr) {\n\tm_commands.push_back(\"(assert \" + std::move(_expr) + ')');\n}\n\nvoid SMTLib2Commands::setOption(std::string _name, std::string _value)\n{\n\tm_commands.push_back(\"(set-option :\" + std::move(_name) + ' ' + std::move(_value) + ')');\n}\n\nvoid SMTLib2Commands::setLogic(std::string _logic)\n{\n\tm_commands.push_back(\"(set-logic \" + std::move(_logic) + ')');\n}\n\nvoid SMTLib2Commands::declareVariable(std::string _name, std::string _sort)\n{\n\tm_commands.push_back(\"(declare-fun |\" + std::move(_name) + \"| () \" + std::move(_sort) + ')');\n}\n\nvoid SMTLib2Commands::declareFunction(std::string const& _name, std::vector<std::string> const& _domain, std::string const& _codomain)\n{\n\tstd::stringstream ss;\n\tss << \"(declare-fun |\" << _name << \"| \" << '(' << boost::join(_domain, \" \")\n\t\t<< ')' << ' ' << _codomain << ')';\n\tm_commands.push_back(ss.str());\n}\n\nvoid SMTLib2Commands::declareTuple(\n\tstd::string const& _name,\n\tstd::vector<std::string> const& _memberNames,\n\tstd::vector<std::string> const& _memberSorts\n)\n{\n\tauto quotedName = '|' + _name + '|';\n\tstd::stringstream ss;\n\tss << \"(declare-datatypes ((\" << quotedName << \" 0)) (((\" << quotedName;\n\tfor (auto && [memberName, memberSort]: ranges::views::zip(_memberNames, _memberSorts))\n\t\tss << \" (|\" << memberName << \"| \" << memberSort << \")\";\n\tss << \"))))\";\n\tauto declaration = ss.str();\n\tm_commands.push_back(ss.str());\n}\n"
  },
  {
    "path": "libsmtutil/SMTLib2Interface.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/BMCSolverInterface.h>\n\n#include <libsmtutil/SMTLib2Context.h>\n\n#include <libsolidity/interface/ReadFile.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/FixedHash.h>\n\n#include <cstdio>\n#include <map>\n#include <set>\n#include <string>\n#include <vector>\n\nnamespace solidity::smtutil\n{\n\nclass SMTLib2Commands\n{\npublic:\n\tvoid push();\n\tvoid pop();\n\n\tvoid clear();\n\n\tvoid assertion(std::string _expr);\n\n\tvoid setOption(std::string _name, std::string _value);\n\n\tvoid setLogic(std::string _logic);\n\n\tvoid declareVariable(std::string _name, std::string _sort);\n\tvoid declareFunction(std::string const& _name, std::vector<std::string> const& _domain, std::string const& _codomain);\n\tvoid declareTuple(\n\t\tstd::string const& _name,\n\t\tstd::vector<std::string> const& _memberNames,\n\t\tstd::vector<std::string> const& _memberSorts\n\t);\n\n\t[[nodiscard]] std::string toString() const;\nprivate:\n\tstd::vector<std::string> m_commands;\n\tstd::vector<std::size_t> m_frameLimits;\n\n};\n\nclass SMTLib2Interface: public BMCSolverInterface\n{\npublic:\n\t/// Noncopyable.\n\tSMTLib2Interface(SMTLib2Interface const&) = delete;\n\tSMTLib2Interface& operator=(SMTLib2Interface const&) = delete;\n\n\texplicit SMTLib2Interface(\n\t\tstd::map<util::h256, std::string> _queryResponses = {},\n\t\tfrontend::ReadCallback::Callback _smtCallback = {},\n\t\tstd::optional<unsigned> _queryTimeout = {}\n\t);\n\n\tvoid reset() override;\n\n\tvoid push() override;\n\tvoid pop() override;\n\n\tvoid declareVariable(std::string const&, SortPointer const&) override;\n\n\tvoid addAssertion(Expression const& _expr) override;\n\tstd::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override;\n\n\tstd::vector<std::string> unhandledQueries() override { return m_unhandledQueries; }\n\n\t// Used by CHCSmtLib2Interface\n\tstd::string toSExpr(Expression const& _expr);\n\tstd::string toSmtLibSort(SortPointer _sort);\n\tstd::vector<std::string> toSmtLibSort(std::vector<SortPointer> const& _sort);\n\n\tstd::string dumpQuery(std::vector<Expression> const& _expressionsToEvaluate);\n\nprotected:\n\tvirtual void setupSmtCallback() {}\n\n\tvoid declareFunction(std::string const& _name, SortPointer const& _sort);\n\n\tstd::string checkSatAndGetValuesCommand(std::vector<Expression> const& _expressionsToEvaluate);\n\n\t/// Communicates with the solver via the callback. Throws SMTSolverError on error.\n\tvirtual std::string querySolver(std::string const& _input);\n\n\tSMTLib2Commands m_commands;\n\tSMTLib2Context m_context;\n\n\tstd::map<util::h256, std::string> m_queryResponses;\n\tstd::vector<std::string> m_unhandledQueries;\n\n\tfrontend::ReadCallback::Callback m_smtCallback;\n};\n\n}\n"
  },
  {
    "path": "libsmtutil/SMTLib2Parser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsmtutil/SMTLib2Parser.h>\n\n#include <liblangutil/Common.h>\n\n#include <libsolutil/Visitor.h>\n#include <libsolutil/StringUtils.h>\n\n\nusing namespace solidity::langutil;\nusing namespace solidity::smtutil;\n\nstd::string SMTLib2Expression::toString() const {\n\treturn std::visit(solidity::util::GenericVisitor{\n\t\t\t[](std::string const& _sv) { return _sv; },\n\t\t\t[](std::vector<SMTLib2Expression> const& _subExpr) {\n\t\t\t\tstd::vector<std::string> formatted;\n\t\t\t\tfor (auto const& item: _subExpr)\n\t\t\t\t\tformatted.emplace_back(item.toString());\n\t\t\t\treturn \"(\" + solidity::util::joinHumanReadable(formatted, \" \") + \")\";\n\t\t\t}\n\t}, data);\n}\n\nSMTLib2Expression SMTLib2Parser::parseExpression() {\n\tskipWhitespace();\n\tif (token() == '(')\n\t{\n\t\tadvance();\n\t\tskipWhitespace();\n\t\tstd::vector<SMTLib2Expression> subExpressions;\n\t\twhile (token() != 0 && token() != ')')\n\t\t{\n\t\t\tsubExpressions.emplace_back(parseExpression());\n\t\t\tskipWhitespace();\n\t\t}\n\t\tif (token() != ')')\n\t\t\tthrow ParsingException{};\n\t\t// Simulate whitespace because we do not want to read the next token since it might block.\n\t\tm_token = ' ';\n\t\treturn {std::move(subExpressions)};\n\t} else\n\t\treturn {parseToken()};\n}\n\nstd::string SMTLib2Parser::parseToken() {\n\tstd::string result;\n\n\tskipWhitespace();\n\tbool isPipe = token() == '|';\n\tif (isPipe)\n\t\tadvance();\n\twhile (token() != 0)\n\t{\n\t\tchar c = token();\n\t\tif (isPipe && c == '|')\n\t\t{\n\t\t\tadvance();\n\t\t\tbreak;\n\t\t} else if (!isPipe && (isWhiteSpace(c) || c == '(' || c == ')'))\n\t\t\tbreak;\n\t\tresult.push_back(c);\n\t\tadvance();\n\t}\n\treturn result;\n}\n\nvoid SMTLib2Parser::advance() {\n\tif (!m_input.good())\n\t\tthrow ParsingException{};\n\tm_token = static_cast<char>(m_input.get());\n\tif (token() == ';')\n\t\twhile (token() != '\\n' && token() != 0)\n\t\t\tm_token = static_cast<char>(m_input.get());\n}\n\nvoid SMTLib2Parser::skipWhitespace() {\n\twhile (isWhiteSpace(token()))\n\t\tadvance();\n}\n"
  },
  {
    "path": "libsmtutil/SMTLib2Parser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/Exceptions.h>\n\n#include <iostream>\n#include <string>\n#include <variant>\n#include <vector>\n\n/**\n * The following is a parser for SMT-LIB2 expressions developed originally by @chriseth as part of solsmt.\n */\n\nnamespace solidity::smtutil\n{\n\nstruct SMTLib2Expression {\n\tusing args_t = std::vector<SMTLib2Expression>;\n\tstd::variant<std::string, args_t> data;\n\n\t[[nodiscard]] std::string toString() const;\n};\n\ninline bool isAtom(SMTLib2Expression const& expr)\n{\n\treturn std::holds_alternative<std::string>(expr.data);\n}\n\ninline std::string const& asAtom(SMTLib2Expression const& expr)\n{\n\tsmtAssert(isAtom(expr));\n\treturn std::get<std::string>(expr.data);\n}\n\ninline auto const& asSubExpressions(SMTLib2Expression const& expr)\n{\n\tsmtAssert(!isAtom(expr));\n\treturn std::get<SMTLib2Expression::args_t>(expr.data);\n}\n\ninline auto& asSubExpressions(SMTLib2Expression& expr)\n{\n\tsmtAssert(!isAtom(expr));\n\treturn std::get<SMTLib2Expression::args_t>(expr.data);\n}\n\nclass SMTLib2Parser {\npublic:\n\tclass ParsingException {};\n\n\texplicit SMTLib2Parser(std::istream& _input) :\n\t\t\tm_input(_input),\n\t\t\tm_token(static_cast<char>(m_input.get())) {}\n\n\tSMTLib2Expression parseExpression();\n\n\tbool isEOF()\n\t{\n\t\tskipWhitespace();\n\t\treturn m_input.eof();\n\t}\n\nprivate:\n\tstd::string parseToken();\n\n\tvoid skipWhitespace();\n\n\t[[nodiscard]] char token() const\n\t{\n\t\treturn m_token;\n\t}\n\n\tvoid advance();\n\n\tstd::istream& m_input;\n\tchar m_token = 0;\n};\n}\n"
  },
  {
    "path": "libsmtutil/SMTPortfolio.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsmtutil/SMTPortfolio.h>\n\n#include <libsmtutil/SMTLib2Interface.h>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::frontend;\nusing namespace solidity::smtutil;\n\nSMTPortfolio::SMTPortfolio(\n\tstd::vector<std::unique_ptr<BMCSolverInterface>> _solvers,\n\tstd::optional<unsigned> _queryTimeout\n):\n\tBMCSolverInterface(_queryTimeout), m_solvers(std::move(_solvers))\n{}\n\n\nvoid SMTPortfolio::reset()\n{\n\tfor (auto const& s: m_solvers)\n\t\ts->reset();\n}\n\nvoid SMTPortfolio::push()\n{\n\tfor (auto const& s: m_solvers)\n\t\ts->push();\n}\n\nvoid SMTPortfolio::pop()\n{\n\tfor (auto const& s: m_solvers)\n\t\ts->pop();\n}\n\nvoid SMTPortfolio::declareVariable(std::string const& _name, SortPointer const& _sort)\n{\n\tsmtAssert(_sort, \"\");\n\tfor (auto const& s: m_solvers)\n\t\ts->declareVariable(_name, _sort);\n}\n\nvoid SMTPortfolio::addAssertion(Expression const& _expr)\n{\n\tfor (auto const& s: m_solvers)\n\t\ts->addAssertion(_expr);\n}\n\n/*\n * Broadcasts the SMT query to all solvers and returns a single result.\n * This comment explains how this result is decided.\n *\n * When a solver is queried, there are four possible answers:\n *   SATISFIABLE (SAT), UNSATISFIABLE (UNSAT), UNKNOWN, CONFLICTING, ERROR\n * We say that a solver _answered_ the query if it returns either:\n *   SAT or UNSAT\n * A solver did not answer the query if it returns either:\n *   UNKNOWN (it tried but couldn't solve it) or ERROR (crash, internal error, API error, etc).\n *\n * Ideally all solvers answer the query and agree on what the answer is\n * (all say SAT or all say UNSAT).\n *\n * The actual logic is as follows:\n * 1) If at least one solver answers the query, all the non-answer results are ignored.\n *   Here SAT/UNSAT is preferred over UNKNOWN since it's an actual answer, and over ERROR\n *   because one buggy solver/integration shouldn't break the portfolio.\n *\n * 2) If at least one solver answers SAT and at least one answers UNSAT, at least one of them is buggy\n * and the result is CONFLICTING.\n *   In the future if we have more than 2 solvers enabled we could go with the majority.\n *\n * 3) If NO solver answers the query:\n *   If at least one solver returned UNKNOWN (where the rest returned ERROR), the result is UNKNOWN.\n *   This is preferred over ERROR since the SMTChecker might decide to abstract the query\n *   when it is told that this is a hard query to solve.\n *\n *   If all solvers return ERROR, the result is ERROR.\n*/\nstd::pair<CheckResult, std::vector<std::string>> SMTPortfolio::check(std::vector<Expression> const& _expressionsToEvaluate)\n{\n\tCheckResult lastResult = CheckResult::ERROR;\n\tstd::vector<std::string> finalValues;\n\tfor (auto const& s: m_solvers)\n\t{\n\t\tCheckResult result;\n\t\tstd::vector<std::string> values;\n\t\ttie(result, values) = s->check(_expressionsToEvaluate);\n\t\tif (solverAnswered(result))\n\t\t{\n\t\t\tif (!solverAnswered(lastResult))\n\t\t\t{\n\t\t\t\tlastResult = result;\n\t\t\t\tfinalValues = std::move(values);\n\t\t\t}\n\t\t\telse if (lastResult != result)\n\t\t\t{\n\t\t\t\tlastResult = CheckResult::CONFLICTING;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse if (result == CheckResult::UNKNOWN && lastResult == CheckResult::ERROR)\n\t\t\tlastResult = result;\n\t}\n\treturn std::make_pair(lastResult, finalValues);\n}\n\nstd::vector<std::string> SMTPortfolio::unhandledQueries()\n{\n\t// This code assumes that the constructor guarantees that\n\t// SmtLib2Interface is in position 0, if enabled.\n\tif (!m_solvers.empty())\n\t\tif (auto smtlib2 = dynamic_cast<SMTLib2Interface*>(m_solvers.front().get()))\n\t\t\treturn smtlib2->unhandledQueries();\n\treturn {};\n}\n\nbool SMTPortfolio::solverAnswered(CheckResult result)\n{\n\treturn result == CheckResult::SATISFIABLE || result == CheckResult::UNSATISFIABLE;\n}\n\nstd::string SMTPortfolio::dumpQuery(std::vector<Expression> const& _expressionsToEvaluate)\n{\n\t// This code assumes that the constructor guarantees that\n\t// SmtLib2Interface is in position 0, if enabled.\n\tauto smtlib2 = dynamic_cast<SMTLib2Interface*>(m_solvers.front().get());\n\tsolAssert(smtlib2, \"Must use SMTLib2 solver to dump queries\");\n\treturn smtlib2->dumpQuery(_expressionsToEvaluate);\n}\n"
  },
  {
    "path": "libsmtutil/SMTPortfolio.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n\n#include <libsmtutil/BMCSolverInterface.h>\n\n#include <vector>\n\nnamespace solidity::smtutil\n{\n\n/**\n * The SMTPortfolio wraps all available solvers within a single interface,\n * propagating the functionalities to all solvers.\n * It also checks whether different solvers give conflicting answers\n * to SMT queries.\n */\nclass SMTPortfolio: public BMCSolverInterface\n{\npublic:\n\t/// Noncopyable.\n\tSMTPortfolio(SMTPortfolio const&) = delete;\n\tSMTPortfolio& operator=(SMTPortfolio const&) = delete;\n\n\tSMTPortfolio(std::vector<std::unique_ptr<BMCSolverInterface>> solvers, std::optional<unsigned> _queryTimeout);\n\n\tvoid reset() override;\n\n\tvoid push() override;\n\tvoid pop() override;\n\n\tvoid declareVariable(std::string const&, SortPointer const&) override;\n\n\tvoid addAssertion(Expression const& _expr) override;\n\n\tstd::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override;\n\n\tstd::vector<std::string> unhandledQueries() override;\n\tsize_t solvers() override { return m_solvers.size(); }\n\n\tstd::string dumpQuery(std::vector<Expression> const& _expressionsToEvaluate);\n\nprivate:\n\tstatic bool solverAnswered(CheckResult result);\n\n\tstd::vector<std::unique_ptr<BMCSolverInterface>> m_solvers;\n\n\tstd::vector<Expression> m_assertions;\n};\n\n}\n"
  },
  {
    "path": "libsmtutil/SolverInterface.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/Exceptions.h>\n#include <libsmtutil/Sorts.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/Numeric.h>\n#include <libsolutil/CommonData.h>\n\n#include <range/v3/algorithm/all_of.hpp>\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/split.hpp>\n\n#include <cstdio>\n#include <map>\n#include <memory>\n#include <optional>\n#include <set>\n#include <string>\n#include <vector>\n\nnamespace solidity::smtutil\n{\n\nstruct SMTSolverChoice\n{\n\tbool cvc5 = false;\n\tbool eld = false;\n\tbool smtlib2 = false;\n\tbool z3 = false;\n\n\tstatic constexpr SMTSolverChoice All() noexcept { return {true, true, true, true}; }\n\tstatic constexpr SMTSolverChoice CVC5() noexcept { return {true, false, false, false}; }\n\tstatic constexpr SMTSolverChoice ELD() noexcept { return {false, true, false, false}; }\n\tstatic constexpr SMTSolverChoice SMTLIB2() noexcept { return {false, false, true, false}; }\n\tstatic constexpr SMTSolverChoice Z3() noexcept { return {false, false, false, true}; }\n\tstatic constexpr SMTSolverChoice None() noexcept { return {false, false, false, false}; }\n\n\tstatic std::optional<SMTSolverChoice> fromString(std::string const& _solvers)\n\t{\n\t\tSMTSolverChoice solvers;\n\t\tfor (auto&& s: _solvers | ranges::views::split(',') | ranges::to<std::vector<std::string>>())\n\t\t\tif (!solvers.setSolver(s))\n\t\t\t\treturn {};\n\n\t\treturn solvers;\n\t}\n\n\tSMTSolverChoice& operator&=(SMTSolverChoice const& _other)\n\t{\n\t\tcvc5 &= _other.cvc5;\n\t\teld &= _other.eld;\n\t\tsmtlib2 &= _other.smtlib2;\n\t\tz3 &= _other.z3;\n\t\treturn *this;\n\t}\n\n\tSMTSolverChoice operator&(SMTSolverChoice _other) const noexcept\n\t{\n\t\t_other &= *this;\n\t\treturn _other;\n\t}\n\n\tbool operator!=(SMTSolverChoice const& _other) const noexcept { return !(*this == _other); }\n\n\tbool operator==(SMTSolverChoice const& _other) const noexcept\n\t{\n\t\treturn cvc5 == _other.cvc5 &&\n\t\t\teld == _other.eld &&\n\t\t\tsmtlib2 == _other.smtlib2 &&\n\t\t\tz3 == _other.z3;\n\t}\n\n\tbool setSolver(std::string const& _solver)\n\t{\n\t\tstatic std::set<std::string> const solvers{\"cvc5\", \"eld\", \"smtlib2\", \"z3\"};\n\t\tif (!solvers.count(_solver))\n\t\t\treturn false;\n\t\tif (_solver == \"cvc5\")\n\t\t\tcvc5 = true;\n\t\tif (_solver == \"eld\")\n\t\t\teld = true;\n\t\telse if (_solver == \"smtlib2\")\n\t\t\tsmtlib2 = true;\n\t\telse if (_solver == \"z3\")\n\t\t\tz3 = true;\n\t\treturn true;\n\t}\n\n\tbool none() const noexcept { return !some(); }\n\tbool some() const noexcept { return cvc5 || eld || smtlib2 || z3; }\n\tbool all() const noexcept { return cvc5 && eld && smtlib2 && z3; }\n};\n\nenum class CheckResult\n{\n\tSATISFIABLE, UNSATISFIABLE, UNKNOWN, CONFLICTING, ERROR\n};\n\n/// C++ representation of an SMTLIB2 expression.\nclass Expression\n{\n\tfriend class SolverInterface;\npublic:\n\texplicit Expression(bool _v): Expression(_v ? \"true\" : \"false\", Kind::Bool) {}\n\texplicit Expression(std::shared_ptr<SortSort> _sort, std::string _name = \"\"): Expression(std::move(_name), {}, _sort) {}\n\texplicit Expression(std::string _name, std::vector<Expression> _arguments, SortPointer _sort):\n\t\tname(std::move(_name)), arguments(std::move(_arguments)), sort(std::move(_sort)) {}\n\tExpression(size_t _number): Expression(std::to_string(_number), {}, SortProvider::uintSort) {}\n\tExpression(u256 const& _number): Expression(_number.str(), {}, SortProvider::uintSort) {}\n\tExpression(s256 const& _number): Expression(\n\t\t_number >= 0 ? _number.str() : \"-\",\n\t\t_number >= 0 ?\n\t\t\tstd::vector<Expression>{} :\n\t\t\tstd::vector<Expression>{Expression(size_t(0)), bigint(-_number)},\n\t\tSortProvider::sintSort\n\t) {}\n\tExpression(bigint const& _number): Expression(\n\t\t_number >= 0 ? _number.str() : \"-\",\n\t\t_number >= 0 ?\n\t\t\tstd::vector<Expression>{} :\n\t\t\tstd::vector<Expression>{Expression(size_t(0)), bigint(-_number)},\n\t\tSortProvider::sintSort\n\t) {}\n\n\tExpression(Expression const&) = default;\n\tExpression(Expression&&) = default;\n\tExpression& operator=(Expression const&) = default;\n\tExpression& operator=(Expression&&) = default;\n\n\tbool hasCorrectArity() const\n\t{\n\t\tif (name == \"tuple_constructor\")\n\t\t{\n\t\t\tauto tupleSort = std::dynamic_pointer_cast<TupleSort>(sort);\n\t\t\tsmtAssert(tupleSort, \"\");\n\t\t\treturn arguments.size() == tupleSort->components.size();\n\t\t}\n\n\t\tstatic std::map<std::string, unsigned> const operatorsArity{\n\t\t\t{\"ite\", 3},\n\t\t\t{\"not\", 1},\n\t\t\t{\"and\", 2},\n\t\t\t{\"or\", 2},\n\t\t\t{\"=>\", 2},\n\t\t\t{\"=\", 2},\n\t\t\t{\"<\", 2},\n\t\t\t{\"<=\", 2},\n\t\t\t{\">\", 2},\n\t\t\t{\">=\", 2},\n\t\t\t{\"+\", 2},\n\t\t\t{\"-\", 2},\n\t\t\t{\"*\", 2},\n\t\t\t{\"div\", 2},\n\t\t\t{\"mod\", 2},\n\t\t\t{\"bvnot\", 1},\n\t\t\t{\"bvand\", 2},\n\t\t\t{\"bvor\", 2},\n\t\t\t{\"bvxor\", 2},\n\t\t\t{\"bvshl\", 2},\n\t\t\t{\"bvlshr\", 2},\n\t\t\t{\"bvashr\", 2},\n\t\t\t{\"int2bv\", 2},\n\t\t\t{\"bv2int\", 1},\n\t\t\t{\"select\", 2},\n\t\t\t{\"store\", 3},\n\t\t\t{\"const_array\", 2},\n\t\t\t{\"tuple_get\", 2}\n\t\t};\n\t\treturn operatorsArity.count(name) && operatorsArity.at(name) == arguments.size();\n\t}\n\n\tstatic Expression ite(Expression _condition, Expression _trueValue, Expression _falseValue)\n\t{\n\t\tsmtAssert(areCompatible(*_trueValue.sort, *_falseValue.sort));\n\t\tSortPointer sort = _trueValue.sort;\n\t\treturn Expression(\"ite\", std::vector<Expression>{\n\t\t\tstd::move(_condition), std::move(_trueValue), std::move(_falseValue)\n\t\t}, std::move(sort));\n\t}\n\n\tstatic Expression implies(Expression _a, Expression _b)\n\t{\n\t\treturn Expression(\n\t\t\t\"=>\",\n\t\t\tstd::move(_a),\n\t\t\tstd::move(_b),\n\t\t\tKind::Bool\n\t\t);\n\t}\n\n\t/// select is the SMT representation of an array index access.\n\tstatic Expression select(Expression _array, Expression _index)\n\t{\n\t\tsmtAssert(_array.sort->kind == Kind::Array, \"\");\n\t\tstd::shared_ptr<ArraySort> arraySort = std::dynamic_pointer_cast<ArraySort>(_array.sort);\n\t\tsmtAssert(arraySort, \"\");\n\t\tsmtAssert(_index.sort, \"\");\n\t\tsmtAssert(areCompatible(*arraySort->domain, *_index.sort));\n\t\treturn Expression(\n\t\t\t\"select\",\n\t\t\tstd::vector<Expression>{std::move(_array), std::move(_index)},\n\t\t\tarraySort->range\n\t\t);\n\t}\n\n\t/// store is the SMT representation of an assignment to array index.\n\t/// The function is pure and returns the modified array.\n\tstatic Expression store(Expression _array, Expression _index, Expression _element)\n\t{\n\t\tauto arraySort = std::dynamic_pointer_cast<ArraySort>(_array.sort);\n\t\tsmtAssert(arraySort, \"\");\n\t\tsmtAssert(_index.sort, \"\");\n\t\tsmtAssert(_element.sort, \"\");\n\t\tsmtAssert(areCompatible(*arraySort->domain, *_index.sort));\n\t\tsmtAssert(areCompatible(*arraySort->range, *_element.sort));\n\t\treturn Expression(\n\t\t\t\"store\",\n\t\t\tstd::vector<Expression>{std::move(_array), std::move(_index), std::move(_element)},\n\t\t\tarraySort\n\t\t);\n\t}\n\n\tstatic Expression const_array(Expression _sort, Expression _value)\n\t{\n\t\tsmtAssert(_sort.sort->kind == Kind::Sort, \"\");\n\t\tauto sortSort = std::dynamic_pointer_cast<SortSort>(_sort.sort);\n\t\tauto arraySort = std::dynamic_pointer_cast<ArraySort>(sortSort->inner);\n\t\tsmtAssert(sortSort && arraySort, \"\");\n\t\tsmtAssert(_value.sort, \"\");\n\t\tsmtAssert(areCompatible(*arraySort->range, *_value.sort));\n\t\treturn Expression(\n\t\t\t\"const_array\",\n\t\t\tstd::vector<Expression>{std::move(_sort), std::move(_value)},\n\t\t\tarraySort\n\t\t);\n\t}\n\n\tstatic Expression tuple_get(Expression _tuple, size_t _index)\n\t{\n\t\tsmtAssert(_tuple.sort->kind == Kind::Tuple, \"\");\n\t\tstd::shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_tuple.sort);\n\t\tsmtAssert(tupleSort, \"\");\n\t\tsmtAssert(_index < tupleSort->components.size(), \"\");\n\t\treturn Expression(\n\t\t\t\"tuple_get\",\n\t\t\tstd::vector<Expression>{std::move(_tuple), Expression(_index)},\n\t\t\ttupleSort->components.at(_index)\n\t\t);\n\t}\n\n\tstatic Expression tuple_constructor(Expression _tuple, std::vector<Expression> _arguments)\n\t{\n\t\tsmtAssert(_tuple.sort->kind == Kind::Sort, \"\");\n\t\tauto sortSort = std::dynamic_pointer_cast<SortSort>(_tuple.sort);\n\t\tauto tupleSort = std::dynamic_pointer_cast<TupleSort>(sortSort->inner);\n\t\tsmtAssert(tupleSort, \"\");\n\t\tsmtAssert(_arguments.size() == tupleSort->components.size(), \"\");\n\t\treturn Expression(\n\t\t\t\"tuple_constructor\",\n\t\t\tstd::move(_arguments),\n\t\t\ttupleSort\n\t\t);\n\t}\n\n\tstatic Expression int2bv(Expression _n, size_t _size)\n\t{\n\t\tsmtAssert(_n.sort->kind == Kind::Int, \"\");\n\t\tstd::shared_ptr<IntSort> intSort = std::dynamic_pointer_cast<IntSort>(_n.sort);\n\t\tsmtAssert(intSort, \"\");\n\t\tsmtAssert(_size <= 256, \"\");\n\t\treturn Expression(\n\t\t\t\"int2bv\",\n\t\t\tstd::vector<Expression>{std::move(_n), Expression(_size)},\n\t\t\tstd::make_shared<BitVectorSort>(_size)\n\t\t);\n\t}\n\n\tstatic Expression bv2int(Expression _bv, bool _signed = false)\n\t{\n\t\tsmtAssert(_bv.sort->kind == Kind::BitVector, \"\");\n\t\tstd::shared_ptr<BitVectorSort> bvSort = std::dynamic_pointer_cast<BitVectorSort>(_bv.sort);\n\t\tsmtAssert(bvSort, \"\");\n\t\tsmtAssert(bvSort->size <= 256, \"\");\n\t\treturn Expression(\n\t\t\t\"bv2int\",\n\t\t\tstd::vector<Expression>{std::move(_bv)},\n\t\t\tSortProvider::intSort(_signed)\n\t\t);\n\t}\n\n\tstatic bool sameSort(std::vector<Expression> const& _args)\n\t{\n\t\tif (_args.empty())\n\t\t\treturn true;\n\n\t\tauto sort = _args.front().sort;\n\t\treturn ranges::all_of(\n\t\t\t_args,\n\t\t\t[&](auto const& _expr){ return _expr.sort->kind == sort->kind; }\n\t\t);\n\t}\n\n\tstatic Expression mkAnd(std::vector<Expression> _args)\n\t{\n\t\tsmtAssert(!_args.empty(), \"\");\n\t\tsmtAssert(sameSort(_args), \"\");\n\n\t\tauto sort = _args.front().sort;\n\t\tif (sort->kind == Kind::BitVector)\n\t\t\treturn Expression(\"bvand\", std::move(_args), sort);\n\n\t\tsmtAssert(sort->kind == Kind::Bool, \"\");\n\t\treturn Expression(\"and\", std::move(_args), Kind::Bool);\n\t}\n\n\tstatic Expression mkOr(std::vector<Expression> _args)\n\t{\n\t\tsmtAssert(!_args.empty(), \"\");\n\t\tsmtAssert(sameSort(_args), \"\");\n\n\t\tauto sort = _args.front().sort;\n\t\tif (sort->kind == Kind::BitVector)\n\t\t\treturn Expression(\"bvor\", std::move(_args), sort);\n\n\t\tsmtAssert(sort->kind == Kind::Bool, \"\");\n\t\treturn Expression(\"or\", std::move(_args), Kind::Bool);\n\t}\n\n\tstatic Expression mkPlus(std::vector<Expression> _args)\n\t{\n\t\tsmtAssert(!_args.empty(), \"\");\n\t\tsmtAssert(sameSort(_args), \"\");\n\n\t\tauto sort = _args.front().sort;\n\t\tsmtAssert(sort->kind == Kind::BitVector || sort->kind == Kind::Int, \"\");\n\t\treturn Expression(\"+\", std::move(_args), sort);\n\t}\n\n\tstatic Expression mkMul(std::vector<Expression> _args)\n\t{\n\t\tsmtAssert(!_args.empty(), \"\");\n\t\tsmtAssert(sameSort(_args), \"\");\n\n\t\tauto sort = _args.front().sort;\n\t\tsmtAssert(sort->kind == Kind::BitVector || sort->kind == Kind::Int, \"\");\n\t\treturn Expression(\"*\", std::move(_args), sort);\n\t}\n\n\tfriend Expression operator!(Expression _a)\n\t{\n\t\tif (_a.sort->kind == Kind::BitVector)\n\t\t\treturn ~_a;\n\t\treturn Expression(\"not\", std::move(_a), Kind::Bool);\n\t}\n\tfriend Expression operator&&(Expression _a, Expression _b)\n\t{\n\t\tif (_a.sort->kind == Kind::BitVector)\n\t\t{\n\t\t\tsmtAssert(_b.sort->kind == Kind::BitVector, \"\");\n\t\t\treturn _a & _b;\n\t\t}\n\t\treturn Expression(\"and\", std::move(_a), std::move(_b), Kind::Bool);\n\t}\n\tfriend Expression operator||(Expression _a, Expression _b)\n\t{\n\t\tif (_a.sort->kind == Kind::BitVector)\n\t\t{\n\t\t\tsmtAssert(_b.sort->kind == Kind::BitVector, \"\");\n\t\t\treturn _a | _b;\n\t\t}\n\t\treturn Expression(\"or\", std::move(_a), std::move(_b), Kind::Bool);\n\t}\n\tfriend Expression operator==(Expression _a, Expression _b)\n\t{\n\t\tsmtAssert(_a.sort->kind == _b.sort->kind, \"Trying to create an 'equal' expression with different sorts\");\n\t\treturn Expression(\"=\", std::move(_a), std::move(_b), Kind::Bool);\n\t}\n\tfriend Expression operator!=(Expression _a, Expression _b)\n\t{\n\t\treturn !(std::move(_a) == std::move(_b));\n\t}\n\tfriend Expression operator<(Expression _a, Expression _b)\n\t{\n\t\treturn Expression(\"<\", std::move(_a), std::move(_b), Kind::Bool);\n\t}\n\tfriend Expression operator<=(Expression _a, Expression _b)\n\t{\n\t\treturn Expression(\"<=\", std::move(_a), std::move(_b), Kind::Bool);\n\t}\n\tfriend Expression operator>(Expression _a, Expression _b)\n\t{\n\t\treturn Expression(\">\", std::move(_a), std::move(_b), Kind::Bool);\n\t}\n\tfriend Expression operator>=(Expression _a, Expression _b)\n\t{\n\t\treturn Expression(\">=\", std::move(_a), std::move(_b), Kind::Bool);\n\t}\n\tfriend Expression operator+(Expression _a, Expression _b)\n\t{\n\t\tauto intSort = _a.sort;\n\t\treturn Expression(\"+\", {std::move(_a), std::move(_b)}, intSort);\n\t}\n\tfriend Expression operator-(Expression _a, Expression _b)\n\t{\n\t\tauto intSort = _a.sort;\n\t\treturn Expression(\"-\", {std::move(_a), std::move(_b)}, intSort);\n\t}\n\tfriend Expression operator*(Expression _a, Expression _b)\n\t{\n\t\tauto intSort = _a.sort;\n\t\treturn Expression(\"*\", {std::move(_a), std::move(_b)}, intSort);\n\t}\n\tfriend Expression operator/(Expression _a, Expression _b)\n\t{\n\t\tauto intSort = _a.sort;\n\t\treturn Expression(\"div\", {std::move(_a), std::move(_b)}, intSort);\n\t}\n\tfriend Expression operator%(Expression _a, Expression _b)\n\t{\n\t\tauto intSort = _a.sort;\n\t\treturn Expression(\"mod\", {std::move(_a), std::move(_b)}, intSort);\n\t}\n\tfriend Expression operator~(Expression _a)\n\t{\n\t\tauto bvSort = _a.sort;\n\t\treturn Expression(\"bvnot\", {std::move(_a)}, bvSort);\n\t}\n\tfriend Expression operator&(Expression _a, Expression _b)\n\t{\n\t\tauto bvSort = _a.sort;\n\t\treturn Expression(\"bvand\", {std::move(_a), std::move(_b)}, bvSort);\n\t}\n\tfriend Expression operator|(Expression _a, Expression _b)\n\t{\n\t\tauto bvSort = _a.sort;\n\t\treturn Expression(\"bvor\", {std::move(_a), std::move(_b)}, bvSort);\n\t}\n\tfriend Expression operator^(Expression _a, Expression _b)\n\t{\n\t\tauto bvSort = _a.sort;\n\t\treturn Expression(\"bvxor\", {std::move(_a), std::move(_b)}, bvSort);\n\t}\n\tfriend Expression operator<<(Expression _a, Expression _b)\n\t{\n\t\tauto bvSort = _a.sort;\n\t\treturn Expression(\"bvshl\", {std::move(_a), std::move(_b)}, bvSort);\n\t}\n\tfriend Expression operator>>(Expression _a, Expression _b)\n\t{\n\t\tauto bvSort = _a.sort;\n\t\treturn Expression(\"bvlshr\", {std::move(_a), std::move(_b)}, bvSort);\n\t}\n\tstatic Expression ashr(Expression _a, Expression _b)\n\t{\n\t\tauto bvSort = _a.sort;\n\t\treturn Expression(\"bvashr\", {std::move(_a), std::move(_b)}, bvSort);\n\t}\n\tExpression operator()(std::vector<Expression> _arguments) const\n\t{\n\t\tsmtAssert(\n\t\t\tsort->kind == Kind::Function,\n\t\t\t\"Attempted function application to non-function.\"\n\t\t);\n\t\tauto fSort = dynamic_cast<FunctionSort const*>(sort.get());\n\t\tsmtAssert(fSort, \"\");\n\t\treturn Expression(name, std::move(_arguments), fSort->codomain);\n\t}\n\n\tstd::string name;\n\tstd::vector<Expression> arguments;\n\tSortPointer sort;\n\nprivate:\n\t/// Helper method for checking sort compatibility when creating expressions\n\t/// Signed and unsigned Int sorts are compatible even though they are not same\n\tstatic bool areCompatible(Sort const& s1, Sort const& s2)\n\t{\n\t\treturn s1.kind == Kind::Int ? s1.kind == s2.kind : s1 == s2;\n\t}\n\t/// Manual constructors, should only be used by SolverInterface and this class itself.\n\tExpression(std::string _name, std::vector<Expression> _arguments, Kind _kind):\n\t\tExpression(std::move(_name), std::move(_arguments), std::make_shared<Sort>(_kind)) {}\n\n\texplicit Expression(std::string _name, Kind _kind):\n\t\tExpression(std::move(_name), std::vector<Expression>{}, _kind) {}\n\tExpression(std::string _name, Expression _arg, Kind _kind):\n\t\tExpression(std::move(_name), std::vector<Expression>{std::move(_arg)}, _kind) {}\n\tExpression(std::string _name, Expression _arg1, Expression _arg2, Kind _kind):\n\t\tExpression(std::move(_name), std::vector<Expression>{std::move(_arg1), std::move(_arg2)}, _kind) {}\n};\n\nDEV_SIMPLE_EXCEPTION(SolverError);\n\nclass SolverInterface\n{\npublic:\n\tSolverInterface() = default;\n\n\tvirtual ~SolverInterface() = default;\n\n\tvirtual void declareVariable(std::string const& _name, SortPointer const& _sort) = 0;\n\tExpression newVariable(std::string _name, SortPointer const& _sort)\n\t{\n\t\t// Subclasses should do something here\n\t\tsmtAssert(_sort, \"\");\n\t\tdeclareVariable(_name, _sort);\n\t\treturn Expression(std::move(_name), {}, _sort);\n\t}\n\n\t/// @returns how many SMT solvers this interface has.\n\tvirtual size_t solvers() { return 1; }\n};\n\n}\n"
  },
  {
    "path": "libsmtutil/Sorts.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n\n#include <libsmtutil/Sorts.h>\n\nnamespace solidity::smtutil\n{\n\nstd::shared_ptr<Sort> const SortProvider::boolSort{std::make_shared<Sort>(Kind::Bool)};\nstd::shared_ptr<IntSort> const SortProvider::uintSort{std::make_shared<IntSort>(false)};\nstd::shared_ptr<IntSort> const SortProvider::sintSort{std::make_shared<IntSort>(true)};\n\nstd::shared_ptr<IntSort> SortProvider::intSort(bool _signed)\n{\n\tif (_signed)\n\t\treturn sintSort;\n\treturn uintSort;\n}\n\nstd::shared_ptr<BitVectorSort> const SortProvider::bitVectorSort{std::make_shared<BitVectorSort>(256)};\n\n}\n"
  },
  {
    "path": "libsmtutil/Sorts.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/Exceptions.h>\n\n#include <libsolutil/Common.h>\n\n#include <memory>\n#include <vector>\n\nnamespace solidity::smtutil\n{\n\nenum class Kind\n{\n\tInt,\n\tBool,\n\tBitVector,\n\tFunction,\n\tArray,\n\tSort,\n\tTuple\n};\n\nstruct Sort\n{\n\tSort(Kind _kind):\n\t\tkind(_kind) {}\n\tvirtual ~Sort() = default;\n\tvirtual bool operator==(Sort const& _other) const { return kind == _other.kind; }\n\n\tKind const kind;\n};\nusing SortPointer = std::shared_ptr<Sort>;\n\nstruct IntSort: public Sort\n{\n\tIntSort(bool _signed):\n\t\tSort(Kind::Int),\n\t\tisSigned(_signed)\n\t{}\n\n\tbool operator==(Sort const& _other) const override\n\t{\n\t\tif (!Sort::operator==(_other))\n\t\t\treturn false;\n\n\t\tauto otherIntSort = dynamic_cast<IntSort const*>(&_other);\n\t\tsmtAssert(otherIntSort);\n\t\treturn isSigned == otherIntSort->isSigned;\n\t}\n\n\tbool isSigned;\n};\n\nstruct BitVectorSort: public Sort\n{\n\tBitVectorSort(unsigned _size):\n\t\tSort(Kind::BitVector),\n\t\tsize(_size)\n\t{}\n\n\tbool operator==(Sort const& _other) const override\n\t{\n\t\tif (!Sort::operator==(_other))\n\t\t\treturn false;\n\n\t\tauto otherBitVectorSort = dynamic_cast<BitVectorSort const*>(&_other);\n\t\tsmtAssert(otherBitVectorSort);\n\t\treturn size == otherBitVectorSort->size;\n\t}\n\n\tunsigned size;\n};\n\nstruct FunctionSort: public Sort\n{\n\tFunctionSort(std::vector<SortPointer> _domain, SortPointer _codomain):\n\t\tSort(Kind::Function), domain(std::move(_domain)), codomain(std::move(_codomain)) {}\n\tbool operator==(Sort const& _other) const override\n\t{\n\t\tif (!Sort::operator==(_other))\n\t\t\treturn false;\n\t\tauto _otherFunction = dynamic_cast<FunctionSort const*>(&_other);\n\t\tsmtAssert(_otherFunction, \"\");\n\t\tif (domain.size() != _otherFunction->domain.size())\n\t\t\treturn false;\n\t\tif (!std::equal(\n\t\t\tdomain.begin(),\n\t\t\tdomain.end(),\n\t\t\t_otherFunction->domain.begin(),\n\t\t\t[&](SortPointer _a, SortPointer _b) { return *_a == *_b; }\n\t\t))\n\t\t\treturn false;\n\t\tsmtAssert(codomain, \"\");\n\t\tsmtAssert(_otherFunction->codomain, \"\");\n\t\treturn *codomain == *_otherFunction->codomain;\n\t}\n\n\tstd::vector<SortPointer> domain;\n\tSortPointer codomain;\n};\n\nstruct ArraySort: public Sort\n{\n\t/// _domain is the sort of the indices\n\t/// _range is the sort of the values\n\tArraySort(SortPointer _domain, SortPointer _range):\n\t\tSort(Kind::Array), domain(std::move(_domain)), range(std::move(_range)) {}\n\tbool operator==(Sort const& _other) const override\n\t{\n\t\tif (!Sort::operator==(_other))\n\t\t\treturn false;\n\t\tauto _otherArray = dynamic_cast<ArraySort const*>(&_other);\n\t\tsmtAssert(_otherArray, \"\");\n\t\tsmtAssert(_otherArray->domain, \"\");\n\t\tsmtAssert(_otherArray->range, \"\");\n\t\tsmtAssert(domain, \"\");\n\t\tsmtAssert(range, \"\");\n\t\treturn *domain == *_otherArray->domain && *range == *_otherArray->range;\n\t}\n\n\tSortPointer domain;\n\tSortPointer range;\n};\n\nstruct SortSort: public Sort\n{\n\tSortSort(SortPointer _inner): Sort(Kind::Sort), inner(std::move(_inner)) {}\n\tbool operator==(Sort const& _other) const override\n\t{\n\t\tif (!Sort::operator==(_other))\n\t\t\treturn false;\n\t\tauto _otherSort = dynamic_cast<SortSort const*>(&_other);\n\t\tsmtAssert(_otherSort, \"\");\n\t\tsmtAssert(_otherSort->inner, \"\");\n\t\tsmtAssert(inner, \"\");\n\t\treturn *inner == *_otherSort->inner;\n\t}\n\n\tSortPointer inner;\n};\n\nstruct TupleSort: public Sort\n{\n\tTupleSort(\n\t\tstd::string _name,\n\t\tstd::vector<std::string> _members,\n\t\tstd::vector<SortPointer> _components\n\t):\n\t\tSort(Kind::Tuple),\n\t\tname(std::move(_name)),\n\t\tmembers(std::move(_members)),\n\t\tcomponents(std::move(_components))\n\t{\n\t\tfor (size_t i = 0; i < members.size(); ++i)\n\t\t\tmemberToIndex[members.at(i)] = i;\n\t}\n\n\tSortPointer memberSort(std::string const& _member)\n\t{\n\t\treturn components.at(memberToIndex.at(_member));\n\t}\n\n\tbool operator==(Sort const& _other) const override\n\t{\n\t\tif (!Sort::operator==(_other))\n\t\t\treturn false;\n\t\tauto _otherTuple = dynamic_cast<TupleSort const*>(&_other);\n\t\tsmtAssert(_otherTuple, \"\");\n\t\tif (name != _otherTuple->name)\n\t\t\treturn false;\n\t\tif (members != _otherTuple->members)\n\t\t\treturn false;\n\t\tif (components.size() != _otherTuple->components.size())\n\t\t\treturn false;\n\t\tif (!std::equal(\n\t\t\tcomponents.begin(),\n\t\t\tcomponents.end(),\n\t\t\t_otherTuple->components.begin(),\n\t\t\t[&](SortPointer _a, SortPointer _b) { return *_a == *_b; }\n\t\t))\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\n\tstd::string const name;\n\tstd::vector<std::string> const members;\n\tstd::vector<SortPointer> const components;\n\tstd::map<std::string, size_t> memberToIndex;\n};\n\n\n/** Frequently used sorts.*/\nstruct SortProvider\n{\n\tstatic std::shared_ptr<Sort> const boolSort;\n\tstatic std::shared_ptr<IntSort> const uintSort;\n\tstatic std::shared_ptr<IntSort> const sintSort;\n\tstatic std::shared_ptr<IntSort> intSort(bool _signed = false);\n\tstatic std::shared_ptr<BitVectorSort> const bitVectorSort;\n};\n\n}\n"
  },
  {
    "path": "libsolc/CMakeLists.txt",
    "content": "if (EMSCRIPTEN)\n\tCreateExportedFunctionsForEMSDK(\n\t\tExportedFunctions\n\t\tsolidity_license\n\t\tsolidity_version\n\t\tsolidity_compile\n\t\tsolidity_alloc\n\t\tsolidity_free\n\t\tsolidity_reset\n\t)\n\t# Specify which functions to export in soljson.js.\n\t# Note that additional Emscripten-generated methods needed by solc-js are\n\t# defined to be exported in cmake/EthCompilerSettings.cmake.\n\tset(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -s EXPORTED_FUNCTIONS='${ExportedFunctions}'\")\n\tadd_executable(soljson libsolc.cpp libsolc.h)\n\ttarget_link_libraries(soljson PRIVATE solidity)\nelse()\n\tadd_library(libsolc libsolc.cpp libsolc.h)\n\tset_target_properties(libsolc PROPERTIES OUTPUT_NAME solc)\n\ttarget_link_libraries(libsolc PRIVATE solidity)\nendif()\n"
  },
  {
    "path": "libsolc/libsolc.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Public compiler API.\n */\n\n#include <libsolc/libsolc.h>\n#include <libsolidity/interface/StandardCompiler.h>\n#include <libsolidity/interface/Version.h>\n#include <libyul/YulName.h>\n\n#include <cstdlib>\n#include <list>\n#include <string>\n\n#include \"license.h\"\n\nusing namespace solidity;\nusing namespace solidity::util;\n\nusing solidity::frontend::ReadCallback;\nusing solidity::frontend::StandardCompiler;\n\nnamespace\n{\n\n// The std::strings in this list must not be resized after they have been added here (via solidity_alloc()), because\n// this may potentially change the pointer that was passed to the caller from solidity_alloc().\nstatic std::list<std::string> solidityAllocations;\n\n/// Find the equivalent to @p _data in the list of allocations of solidity_alloc(),\n/// removes it from the list and returns its value.\n///\n/// If any invalid argument is being passed, it is considered a programming error\n/// on the caller-side and hence, will call abort() then.\nstd::string takeOverAllocation(char const* _data)\n{\n\tfor (auto iter = begin(solidityAllocations); iter != end(solidityAllocations); ++iter)\n\t\tif (iter->data() == _data)\n\t\t{\n\t\t\tstd::string chunk = std::move(*iter);\n\t\t\tsolidityAllocations.erase(iter);\n\t\t\treturn chunk;\n\t\t}\n\n\tabort();\n}\n\n/// Resizes a std::string to the proper length based on the occurrence of a zero terminator.\nvoid truncateCString(std::string& _data)\n{\n\tsize_t pos = _data.find('\\0');\n\tif (pos != std::string::npos)\n\t\t_data.resize(pos);\n}\n\nReadCallback::Callback wrapReadCallback(CStyleReadFileCallback _readCallback, void* _readContext)\n{\n\tReadCallback::Callback readCallback;\n\tif (_readCallback)\n\t{\n\t\treadCallback = [=](std::string const& _kind, std::string const& _data)\n\t\t{\n\t\t\tchar* contents_c = nullptr;\n\t\t\tchar* error_c = nullptr;\n\t\t\t_readCallback(_readContext, _kind.data(), _data.data(), &contents_c, &error_c);\n\t\t\tReadCallback::Result result;\n\t\t\tresult.success = true;\n\t\t\tif (!contents_c && !error_c)\n\t\t\t{\n\t\t\t\tresult.success = false;\n\t\t\t\tresult.responseOrErrorMessage = \"Callback not supported.\";\n\t\t\t}\n\t\t\tif (contents_c)\n\t\t\t{\n\t\t\t\tresult.success = true;\n\t\t\t\tresult.responseOrErrorMessage = takeOverAllocation(contents_c);\n\t\t\t}\n\t\t\tif (error_c)\n\t\t\t{\n\t\t\t\tresult.success = false;\n\t\t\t\tresult.responseOrErrorMessage = takeOverAllocation(error_c);\n\t\t\t}\n\t\t\ttruncateCString(result.responseOrErrorMessage);\n\t\t\treturn result;\n\t\t};\n\t}\n\treturn readCallback;\n}\n\nstd::string compile(std::string _input, CStyleReadFileCallback _readCallback, void* _readContext)\n{\n\tStandardCompiler compiler(wrapReadCallback(_readCallback, _readContext));\n\treturn compiler.compile(std::move(_input));\n}\n\n}\n\nextern \"C\"\n{\nextern char const* solidity_license() noexcept\n{\n\tstatic std::string fullLicenseText = otherLicenses + licenseText;\n\treturn fullLicenseText.c_str();\n}\n\nextern char const* solidity_version() noexcept\n{\n\treturn frontend::VersionString.c_str();\n}\n\nextern char* solidity_compile(char const* _input, CStyleReadFileCallback _readCallback, void* _readContext) noexcept\n{\n\treturn solidityAllocations.emplace_back(compile(_input, _readCallback, _readContext)).data();\n}\n\nextern char* solidity_alloc(size_t _size) noexcept\n{\n\ttry\n\t{\n\t\treturn solidityAllocations.emplace_back(_size, '\\0').data();\n\t}\n\tcatch (...)\n\t{\n\t\t// most likely a std::bad_alloc(), if at all.\n\t\treturn nullptr;\n\t}\n}\n\nextern void solidity_free(char* _data) noexcept\n{\n\ttakeOverAllocation(_data);\n}\n\nextern void solidity_reset() noexcept\n{\n\t// This is called right before each compilation, but not at the end, so additional memory\n\t// can be freed here.\n\tyul::YulStringRepository::reset();\n\tsolidityAllocations.clear();\n}\n}\n"
  },
  {
    "path": "libsolc/libsolc.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Public compiler API.\n */\n\n#pragma once\n\n#include <stdbool.h>\n#include <stddef.h>\n\n#ifdef __cplusplus\n#define SOLC_NOEXCEPT noexcept\n#else\n#define SOLC_NOEXCEPT\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/// Callback used to retrieve additional source files or data.\n///\n/// @param _context The readContext passed to solidity_compile. Can be NULL.\n/// @param _kind The kind of callback (a string).\n/// @param _data The data for the callback (a string).\n/// @param o_contents A pointer to the contents of the file, if found. Allocated via solidity_alloc().\n/// @param o_error A pointer to an error message, if there is one.\n///\n/// The file (as well as error) contents that is to be allocated by the callback\n/// implementer must use the solidity_alloc() API to allocate its underlying\n/// storage. Ownership is then transferred to the compiler which will take care\n/// of the deallocation.\n///\n/// If the callback is not supported, *o_contents and *o_error must be set to NULL.\ntypedef void (*CStyleReadFileCallback)(void* _context, char const* _kind, char const* _data, char** o_contents, char** o_error);\n\n/// Returns the complete license document.\n///\n/// The pointer returned must NOT be freed by the caller.\nchar const* solidity_license() SOLC_NOEXCEPT;\n\n/// Returns the compiler version.\n///\n/// The pointer returned must NOT be freed by the caller.\nchar const* solidity_version() SOLC_NOEXCEPT;\n\n/// Allocates a chunk of memory of @p _size bytes.\n///\n/// Use this function inside callbacks to allocate data that is to be passed to\n/// the compiler. You may use solidity_free() or solidity_reset() to free this\n/// memory again but it is not required as the compiler takes ownership for any\n/// data passed to it via callbacks.\n///\n/// This function will return NULL if the requested memory region could not be allocated.\nchar* solidity_alloc(size_t _size) SOLC_NOEXCEPT;\n\n/// Explicitly frees the memory (@p _data) that was being allocated with solidity_alloc()\n/// or returned by a call to solidity_compile().\n///\n/// Important, this call will abort() in case of any invalid argument being passed to this call.\nvoid solidity_free(char* _data) SOLC_NOEXCEPT;\n\n/// Takes a \"Standard Input JSON\" and an optional callback (can be set to null). Returns\n/// a \"Standard Output JSON\". Both are to be UTF-8 encoded.\n///\n/// @param _input The input JSON to process.\n/// @param _readCallback The optional callback pointer. Can be NULL, but if not NULL,\n///                      it can be called by the compiler to request additional input.\n///                      Please see the documentation of the type for details.\n/// @param _readContext An optional context pointer passed to _readCallback. Can be NULL.\n///\n/// @returns A pointer to the result. The pointer returned must be freed by the caller using solidity_free() or solidity_reset().\nchar* solidity_compile(char const* _input, CStyleReadFileCallback _readCallback, void* _readContext) SOLC_NOEXCEPT;\n\n/// Frees up any allocated memory.\n///\n/// NOTE: the pointer returned by solidity_compile as well as any other pointer retrieved via solidity_alloc()\n/// is invalid after calling this!\nvoid solidity_reset() SOLC_NOEXCEPT;\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "libsolidity/CMakeLists.txt",
    "content": "# Until we have a clear separation, libyul has to be included here\nset(sources\n\tanalysis/ConstantEvaluator.cpp\n\tanalysis/ConstantEvaluator.h\n\tanalysis/ContractLevelChecker.cpp\n\tanalysis/ContractLevelChecker.h\n\tanalysis/ControlFlowAnalyzer.cpp\n\tanalysis/ControlFlowAnalyzer.h\n\tanalysis/ControlFlowBuilder.cpp\n\tanalysis/ControlFlowBuilder.h\n\tanalysis/ControlFlowGraph.cpp\n\tanalysis/ControlFlowGraph.h\n\tanalysis/ControlFlowRevertPruner.cpp\n\tanalysis/ControlFlowRevertPruner.h\n\tanalysis/DeclarationContainer.cpp\n\tanalysis/DeclarationContainer.h\n\tanalysis/DeclarationTypeChecker.cpp\n\tanalysis/DeclarationTypeChecker.h\n\tanalysis/DocStringAnalyser.cpp\n\tanalysis/DocStringAnalyser.h\n\tanalysis/DocStringTagParser.cpp\n\tanalysis/DocStringTagParser.h\n\tanalysis/FunctionCallGraph.cpp\n\tanalysis/FunctionCallGraph.h\n\tanalysis/ImmutableValidator.cpp\n\tanalysis/ImmutableValidator.h\n\tanalysis/GlobalContext.cpp\n\tanalysis/GlobalContext.h\n\tanalysis/NameAndTypeResolver.cpp\n\tanalysis/NameAndTypeResolver.h\n\tanalysis/OverrideChecker.cpp\n\tanalysis/OverrideChecker.h\n\tanalysis/PostTypeChecker.cpp\n\tanalysis/PostTypeChecker.h\n\tanalysis/PostTypeContractLevelChecker.cpp\n\tanalysis/PostTypeContractLevelChecker.h\n\tanalysis/ReferencesResolver.cpp\n\tanalysis/ReferencesResolver.h\n\tanalysis/Scoper.cpp\n\tanalysis/Scoper.h\n\tanalysis/StaticAnalyzer.cpp\n\tanalysis/StaticAnalyzer.h\n\tanalysis/SyntaxChecker.cpp\n\tanalysis/SyntaxChecker.h\n\tanalysis/TypeChecker.cpp\n\tanalysis/TypeChecker.h\n\tanalysis/ViewPureChecker.cpp\n\tanalysis/ViewPureChecker.h\n\tast/AST.cpp\n\tast/AST.h\n\tast/AST_accept.h\n\tast/ASTAnnotations.cpp\n\tast/ASTAnnotations.h\n\tast/ASTEnums.h\n\tast/ASTForward.h\n\tast/ASTJsonExporter.cpp\n\tast/ASTJsonExporter.h\n\tast/ASTUtils.cpp\n\tast/ASTUtils.h\n\tast/ASTJsonImporter.cpp\n\tast/ASTJsonImporter.h\n\tast/ASTVisitor.h\n\tast/CallGraph.cpp\n\tast/CallGraph.h\n\tast/ExperimentalFeatures.h\n\tast/UserDefinableOperators.h\n\tast/Types.cpp\n\tast/Types.h\n\tast/TypeProvider.cpp\n\tast/TypeProvider.h\n\tcodegen/ABIFunctions.cpp\n\tcodegen/ABIFunctions.h\n\tcodegen/ArrayUtils.cpp\n\tcodegen/ArrayUtils.h\n\tcodegen/Compiler.cpp\n\tcodegen/Compiler.h\n\tcodegen/CompilerContext.cpp\n\tcodegen/CompilerContext.h\n\tcodegen/CompilerUtils.cpp\n\tcodegen/CompilerUtils.h\n\tcodegen/ContractCompiler.cpp\n\tcodegen/ContractCompiler.h\n\tcodegen/ExpressionCompiler.cpp\n\tcodegen/ExpressionCompiler.h\n\tcodegen/LValue.cpp\n\tcodegen/LValue.h\n\tcodegen/MultiUseYulFunctionCollector.h\n\tcodegen/MultiUseYulFunctionCollector.cpp\n\tcodegen/ReturnInfo.h\n\tcodegen/ReturnInfo.cpp\n\tcodegen/YulUtilFunctions.h\n\tcodegen/YulUtilFunctions.cpp\n\tcodegen/ir/Common.cpp\n\tcodegen/ir/Common.h\n\tcodegen/ir/IRGenerator.cpp\n\tcodegen/ir/IRGenerator.h\n\tcodegen/ir/IRGeneratorForStatements.cpp\n\tcodegen/ir/IRGeneratorForStatements.h\n\tcodegen/ir/IRGenerationContext.cpp\n\tcodegen/ir/IRGenerationContext.h\n\tcodegen/ir/IRLValue.h\n\tcodegen/ir/IRVariable.cpp\n\tcodegen/ir/IRVariable.h\n\texperimental/analysis/Analysis.cpp\n\texperimental/analysis/Analysis.h\n\tformal/ArraySlicePredicate.cpp\n\tformal/ArraySlicePredicate.h\n\tformal/BMC.cpp\n\tformal/BMC.h\n\tformal/CHC.cpp\n\tformal/CHC.h\n\tformal/Cvc5SMTLib2Interface.cpp\n\tformal/Cvc5SMTLib2Interface.h\n\tformal/EldaricaCHCSmtLib2Interface.cpp\n\tformal/EldaricaCHCSmtLib2Interface.h\n\tformal/EncodingContext.cpp\n\tformal/EncodingContext.h\n\tformal/ExpressionFormatter.cpp\n\tformal/ExpressionFormatter.h\n\tformal/ModelChecker.cpp\n\tformal/ModelChecker.h\n\tformal/ModelCheckerSettings.cpp\n\tformal/ModelCheckerSettings.h\n\tformal/Predicate.cpp\n\tformal/Predicate.h\n\tformal/PredicateInstance.cpp\n\tformal/PredicateInstance.h\n\tformal/PredicateSort.cpp\n\tformal/PredicateSort.h\n\tformal/SMTEncoder.cpp\n\tformal/SMTEncoder.h\n\tformal/SSAVariable.cpp\n\tformal/SSAVariable.h\n\tformal/SymbolicState.cpp\n\tformal/SymbolicState.h\n\tformal/SymbolicTypes.cpp\n\tformal/SymbolicTypes.h\n\tformal/SymbolicVariables.cpp\n\tformal/SymbolicVariables.h\n\tformal/Z3CHCSmtLib2Interface.cpp\n\tformal/Z3CHCSmtLib2Interface.h\n\tformal/Z3SMTLib2Interface.cpp\n\tformal/Z3SMTLib2Interface.h\n\tinterface/ABI.cpp\n\tinterface/ABI.h\n\tinterface/CompilerStack.cpp\n\tinterface/CompilerStack.h\n\tinterface/DebugSettings.h\n\tinterface/FileReader.cpp\n\tinterface/FileReader.h\n\tinterface/ImportRemapper.cpp\n\tinterface/ImportRemapper.h\n\tinterface/GasEstimator.cpp\n\tinterface/GasEstimator.h\n\tinterface/Natspec.cpp\n\tinterface/Natspec.h\n\tinterface/OptimiserSettings.h\n\tinterface/ReadFile.h\n\tinterface/SMTSolverCommand.cpp\n\tinterface/SMTSolverCommand.h\n\tinterface/StandardCompiler.cpp\n\tinterface/StandardCompiler.h\n\tinterface/StorageLayout.cpp\n\tinterface/StorageLayout.h\n\tinterface/UniversalCallback.h\n\tinterface/Version.cpp\n\tinterface/Version.h\n\tlsp/DocumentHoverHandler.cpp\n\tlsp/DocumentHoverHandler.h\n\tlsp/FileRepository.cpp\n\tlsp/FileRepository.h\n\tlsp/GotoDefinition.cpp\n\tlsp/GotoDefinition.h\n\tlsp/RenameSymbol.cpp\n\tlsp/RenameSymbol.h\n\tlsp/HandlerBase.cpp\n\tlsp/HandlerBase.h\n\tlsp/LanguageServer.cpp\n\tlsp/LanguageServer.h\n\tlsp/SemanticTokensBuilder.cpp\n\tlsp/SemanticTokensBuilder.h\n\tlsp/Transport.cpp\n\tlsp/Transport.h\n\tlsp/Utils.cpp\n\tlsp/Utils.h\n\tparsing/DocStringParser.cpp\n\tparsing/DocStringParser.h\n\tparsing/Parser.cpp\n\tparsing/Parser.h\n\tparsing/Token.h\n\texperimental/analysis/Analysis.cpp\n\texperimental/analysis/Analysis.h\n\texperimental/analysis/DebugWarner.cpp\n\texperimental/analysis/DebugWarner.h\n\texperimental/analysis/FunctionDependencyAnalysis.cpp\n\texperimental/analysis/FunctionDependencyAnalysis.h\n\texperimental/analysis/TypeClassRegistration.cpp\n\texperimental/analysis/TypeClassRegistration.h\n\texperimental/analysis/TypeInference.cpp\n\texperimental/analysis/TypeInference.h\n\texperimental/analysis/TypeRegistration.cpp\n\texperimental/analysis/TypeRegistration.h\n\texperimental/analysis/SyntaxRestrictor.cpp\n\texperimental/analysis/SyntaxRestrictor.h\n\texperimental/ast/FunctionCallGraph.h\n\texperimental/ast/Type.cpp\n\texperimental/ast/Type.h\n\texperimental/ast/TypeSystem.cpp\n\texperimental/ast/TypeSystem.h\n\texperimental/ast/TypeSystemHelper.cpp\n\texperimental/ast/TypeSystemHelper.h\n\texperimental/codegen/Common.h\n\texperimental/codegen/Common.cpp\n\texperimental/codegen/IRGenerationContext.h\n\texperimental/codegen/IRGenerator.cpp\n\texperimental/codegen/IRGenerator.h\n\texperimental/codegen/IRGeneratorForStatements.cpp\n\texperimental/codegen/IRGeneratorForStatements.h\n)\n\nadd_library(solidity ${sources})\ntarget_link_libraries(solidity PUBLIC yul evmasm langutil smtutil solutil Boost::boost fmt::fmt-header-only Threads::Threads)\nif (EMSCRIPTEN)\n    if(NOT ${Z3_FOUND})\n            message(FATAL_ERROR \"Z3 library must be present for EMSCRIPTEN build\")\n    endif()\n    target_link_libraries(solidity PUBLIC z3::libz3)\nendif()\n"
  },
  {
    "path": "libsolidity/analysis/ConstantEvaluator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Evaluator for types of constant expressions.\n */\n\n#include <libsolidity/analysis/ConstantEvaluator.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <liblangutil/ErrorReporter.h>\n#include <libsolutil/Keccak256.h>\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/FixedHash.h>\n\n#include <limits>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\n\nusing TypedValue = ConstantEvaluator::TypedValue;\n\nnamespace\n{\n\n/// Check whether (_base ** _exp) fits into 4096 bits.\nbool fitsPrecisionExp(bigint const& _base, bigint const& _exp)\n{\n\tif (_base == 0)\n\t\treturn true;\n\n\tsolAssert(_base > 0, \"\");\n\n\tstd::size_t const bitsMax = 4096;\n\n\tstd::size_t mostSignificantBaseBit = static_cast<std::size_t>(boost::multiprecision::msb(_base));\n\tif (mostSignificantBaseBit == 0) // _base == 1\n\t\treturn true;\n\tif (mostSignificantBaseBit > bitsMax) // _base >= 2 ^ 4096\n\t\treturn false;\n\n\tbigint bitsNeeded = _exp * (mostSignificantBaseBit + 1);\n\n\treturn bitsNeeded <= bitsMax;\n}\n\n/// Checks whether _mantissa * (2 ** _expBase2) fits into 4096 bits.\nbool fitsPrecisionBase2(bigint const& _mantissa, uint32_t _expBase2)\n{\n\treturn fitsPrecisionBaseX(_mantissa, 1.0, _expBase2);\n}\n\n}\n\nstd::optional<rational> ConstantEvaluator::evaluateBinaryOperator(Token _operator, rational const& _left, rational const& _right)\n{\n\tbool fractional = _left.denominator() != 1 || _right.denominator() != 1;\n\tswitch (_operator)\n\t{\n\t//bit operations will only be enabled for integers and fixed types that resemble integers\n\tcase Token::BitOr:\n\t\tif (fractional)\n\t\t\treturn std::nullopt;\n\t\telse\n\t\t\treturn _left.numerator() | _right.numerator();\n\tcase Token::BitXor:\n\t\tif (fractional)\n\t\t\treturn std::nullopt;\n\t\telse\n\t\t\treturn _left.numerator() ^ _right.numerator();\n\tcase Token::BitAnd:\n\t\tif (fractional)\n\t\t\treturn std::nullopt;\n\t\telse\n\t\t\treturn _left.numerator() & _right.numerator();\n\tcase Token::Add: return _left + _right;\n\tcase Token::Sub: return _left - _right;\n\tcase Token::Mul: return _left * _right;\n\tcase Token::Div:\n\t\tif (_right == rational(0))\n\t\t\treturn std::nullopt;\n\t\telse\n\t\t\treturn _left / _right;\n\tcase Token::Mod:\n\t\tif (_right == rational(0))\n\t\t\treturn std::nullopt;\n\t\telse if (fractional)\n\t\t{\n\t\t\trational tempValue = _left / _right;\n\t\t\treturn _left - (tempValue.numerator() / tempValue.denominator()) * _right;\n\t\t}\n\t\telse\n\t\t\treturn _left.numerator() % _right.numerator();\n\t\tbreak;\n\tcase Token::Exp:\n\t{\n\t\tif (_right.denominator() != 1)\n\t\t\treturn std::nullopt;\n\t\tbigint const& exp = _right.numerator();\n\n\t\t// x ** 0 = 1\n\t\t// for 0, 1 and -1 the size of the exponent doesn't have to be restricted\n\t\tif (exp == 0)\n\t\t\treturn 1;\n\t\telse if (_left == 0 || _left == 1)\n\t\t\treturn _left;\n\t\telse if (_left == -1)\n\t\t{\n\t\t\tbigint isOdd = abs(exp) & bigint(1);\n\t\t\treturn 1 - 2 * isOdd.convert_to<int>();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (abs(exp) > std::numeric_limits<uint32_t>::max())\n\t\t\t\treturn std::nullopt; // This will need too much memory to represent.\n\n\t\t\tuint32_t absExp = bigint(abs(exp)).convert_to<uint32_t>();\n\n\t\t\tif (!fitsPrecisionExp(abs(_left.numerator()), absExp) || !fitsPrecisionExp(abs(_left.denominator()), absExp))\n\t\t\t\treturn std::nullopt;\n\n\t\t\tstatic auto const optimizedPow = [](bigint const& _base, uint32_t _exponent) -> bigint {\n\t\t\t\tif (_base == 1)\n\t\t\t\t\treturn 1;\n\t\t\t\telse if (_base == -1)\n\t\t\t\t\treturn 1 - 2 * static_cast<int>(_exponent & 1);\n\t\t\t\telse\n\t\t\t\t\treturn boost::multiprecision::pow(_base, _exponent);\n\t\t\t};\n\n\t\t\tbigint numerator = optimizedPow(_left.numerator(), absExp);\n\t\t\tbigint denominator = optimizedPow(_left.denominator(), absExp);\n\n\t\t\tif (exp >= 0)\n\t\t\t\treturn makeRational(numerator, denominator);\n\t\t\telse\n\t\t\t\t// invert\n\t\t\t\treturn makeRational(denominator, numerator);\n\t\t}\n\t\tbreak;\n\t}\n\tcase Token::SHL:\n\t{\n\t\tif (fractional)\n\t\t\treturn std::nullopt;\n\t\telse if (_right < 0)\n\t\t\treturn std::nullopt;\n\t\telse if (_right > std::numeric_limits<uint32_t>::max())\n\t\t\treturn std::nullopt;\n\t\tif (_left.numerator() == 0)\n\t\t\treturn 0;\n\t\telse\n\t\t{\n\t\t\tuint32_t exponent = _right.numerator().convert_to<uint32_t>();\n\t\t\tif (!fitsPrecisionBase2(abs(_left.numerator()), exponent))\n\t\t\t\treturn std::nullopt;\n\t\t\treturn _left.numerator() * boost::multiprecision::pow(bigint(2), exponent);\n\t\t}\n\t\tbreak;\n\t}\n\t// NOTE: we're using >> (SAR) to denote right shifting. The type of the LValue\n\t//       determines the resulting type and the type of shift (SAR or SHR).\n\tcase Token::SAR:\n\t{\n\t\tif (fractional)\n\t\t\treturn std::nullopt;\n\t\telse if (_right < 0)\n\t\t\treturn std::nullopt;\n\t\telse if (_right > std::numeric_limits<uint32_t>::max())\n\t\t\treturn std::nullopt;\n\t\tif (_left.numerator() == 0)\n\t\t\treturn 0;\n\t\telse\n\t\t{\n\t\t\tuint32_t exponent = _right.numerator().convert_to<uint32_t>();\n\t\t\tif (exponent > boost::multiprecision::msb(boost::multiprecision::abs(_left.numerator())))\n\t\t\t\treturn _left.numerator() < 0 ? -1 : 0;\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (_left.numerator() < 0)\n\t\t\t\t\t// Add 1 to the negative value before dividing to get a result that is strictly too large,\n\t\t\t\t\t// then subtract 1 afterwards to round towards negative infinity.\n\t\t\t\t\t// This is the same algorithm as used in ExpressionCompiler::appendShiftOperatorCode(...).\n\t\t\t\t\t// To see this note that for negative x, xor(x,all_ones) = (-x-1) and\n\t\t\t\t\t// therefore xor(div(xor(x,all_ones), exp(2, shift_amount)), all_ones) is\n\t\t\t\t\t// -(-x - 1) / 2^shift_amount - 1, which is the same as\n\t\t\t\t\t// (x + 1) / 2^shift_amount - 1.\n\t\t\t\t\treturn rational((_left.numerator() + 1) / boost::multiprecision::pow(bigint(2), exponent) - bigint(1), 1);\n\t\t\t\telse\n\t\t\t\t\treturn rational(_left.numerator() / boost::multiprecision::pow(bigint(2), exponent), 1);\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\tdefault:\n\t\treturn std::nullopt;\n\t}\n}\n\nstd::optional<rational> ConstantEvaluator::evaluateUnaryOperator(Token _operator, rational const& _input)\n{\n\tswitch (_operator)\n\t{\n\tcase Token::BitNot:\n\t\tif (_input.denominator() != 1)\n\t\t\treturn std::nullopt;\n\t\telse\n\t\t\treturn ~_input.numerator();\n\tcase Token::Sub:\n\t\treturn -_input;\n\tdefault:\n\t\treturn std::nullopt;\n\t}\n}\n\nnamespace\n{\n\nTypedValue convertType(rational const& _value, Type const& _type)\n{\n\tif (_type.category() == Type::Category::RationalNumber)\n\t\treturn TypedValue{TypeProvider::rationalNumber(_value), _value};\n\telse if (auto const* integerType = dynamic_cast<IntegerType const*>(&_type))\n\t{\n\t\tif (_value > integerType->maxValue() || _value < integerType->minValue())\n\t\t\treturn TypedValue{};\n\t\telse\n\t\t\treturn TypedValue{&_type, _value.numerator() / _value.denominator()};\n\t}\n\telse\n\t\treturn TypedValue{};\n}\n\nTypedValue convertType(std::string const& _value, Type const& _type)\n{\n\tif (\n\t\t_type.category() != Type::Category::StringLiteral &&\n\t\t_type.category() != Type::Category::Array\n\t)\n\t\treturn TypedValue{};\n\treturn TypedValue{&_type, _value};\n}\n\nTypedValue convertType(TypedValue const& _value, Type const& _type)\n{\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](std::string const& value) {\n\t\t\treturn convertType(value, _type);\n\t\t},\n\t\t[&](rational const& value) {\n\t\t\treturn convertType(value, _type);\n\t\t},\n\t\t[&](std::monostate const&) {\n\t\t\treturn TypedValue{};\n\t\t}\n\t}, _value.value);\n}\n\nTypedValue constantToTypedValue(Type const& _type)\n{\n\tif (_type.category() == Type::Category::RationalNumber)\n\t\treturn TypedValue{&_type, dynamic_cast<RationalNumberType const&>(_type).value()};\n\telse if (_type.category() == Type::Category::StringLiteral)\n\t\treturn TypedValue{&_type, dynamic_cast<StringLiteralType const&>(_type).value()};\n\n\treturn TypedValue{};\n}\n\n}\n\nTypedValue ConstantEvaluator::evaluate(\n\tlangutil::ErrorReporter& _errorReporter,\n\tExpression const& _expr\n)\n{\n\treturn ConstantEvaluator{_errorReporter}.evaluate(_expr);\n}\n\nTypedValue ConstantEvaluator::tryEvaluate(Expression const& _expr)\n{\n\tErrorList errorList;\n\tErrorReporter errorReporter(errorList);\n\ttry\n\t{\n\t\treturn ConstantEvaluator{errorReporter}.evaluate(_expr);\n\t}\n\tcatch (FatalError const&)\n\t{\n\t\treturn TypedValue{};\n\t}\n}\n\n\nTypedValue ConstantEvaluator::evaluate(ASTNode const& _node)\n{\n\tif (!m_values.count(&_node))\n\t{\n\t\tif (auto const* varDecl = dynamic_cast<VariableDeclaration const*>(&_node))\n\t\t{\n\t\t\tsolAssert(varDecl->isConstant(), \"\");\n\t\t\t// In some circumstances, we do not yet have a type for the variable.\n\t\t\tif (!varDecl->value() || !varDecl->type())\n\t\t\t\tm_values[&_node] = TypedValue{};\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_depth++;\n\t\t\t\tif (m_depth > 32)\n\t\t\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t\t\t5210_error,\n\t\t\t\t\t\tvarDecl->location(),\n\t\t\t\t\t\t\"Cyclic constant definition (or maximum recursion depth exhausted).\"\n\t\t\t\t\t);\n\t\t\t\tm_values[&_node] = convertType(evaluate(*varDecl->value()), *varDecl->type());\n\t\t\t\tm_depth--;\n\t\t\t}\n\t\t}\n\t\telse if (auto const* expression = dynamic_cast<Expression const*>(&_node))\n\t\t{\n\t\t\texpression->accept(*this);\n\t\t\tif (!m_values.count(&_node))\n\t\t\t\tm_values[&_node] = TypedValue{};\n\t\t}\n\t}\n\treturn m_values.at(&_node);\n}\n\nvoid ConstantEvaluator::endVisit(UnaryOperation const& _operation)\n{\n\tTypedValue value = evaluate(_operation.subExpression());\n\tif (!value.type)\n\t\treturn;\n\n\tType const* resultType = value.type->unaryOperatorResult(_operation.getOperator());\n\tif (!resultType)\n\t\treturn;\n\tvalue = convertType(value, *resultType);\n\tif (!std::holds_alternative<rational>(value.value))\n\t\treturn;\n\n\tif (std::optional<rational> result = evaluateUnaryOperator(_operation.getOperator(), std::get<rational>(value.value)))\n\t{\n\t\tTypedValue convertedValue = convertType(*result, *resultType);\n\t\tif (!convertedValue.type)\n\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t3667_error,\n\t\t\t\t_operation.location(),\n\t\t\t\t\"Arithmetic error when computing constant value.\"\n\t\t\t);\n\t\tm_values[&_operation] = convertedValue;\n\t}\n}\n\nvoid ConstantEvaluator::endVisit(BinaryOperation const& _operation)\n{\n\tTypedValue left = evaluate(_operation.leftExpression());\n\tTypedValue right = evaluate(_operation.rightExpression());\n\tif (!left.type || !right.type)\n\t\treturn;\n\n\t// If this is implemented in the future: Comparison operators have a \"binaryOperatorResult\"\n\t// that is non-bool, but the result has to be bool.\n\tif (TokenTraits::isCompareOp(_operation.getOperator()))\n\t\treturn;\n\n\tType const* resultType = left.type->binaryOperatorResult(_operation.getOperator(), right.type);\n\tif (!resultType)\n\t{\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t6020_error,\n\t\t\t_operation.location(),\n\t\t\t\"Operator \" +\n\t\t\tstd::string(TokenTraits::toString(_operation.getOperator())) +\n\t\t\t\" not compatible with types \" +\n\t\t\tleft.type->toString() +\n\t\t\t\" and \" +\n\t\t\tright.type->toString()\n\t\t\t);\n\t\treturn;\n\t}\n\n\tleft = convertType(left, *resultType);\n\tright = convertType(right, *resultType);\n\tif (\n\t\t!std::holds_alternative<rational>(left.value) ||\n\t\t!std::holds_alternative<rational>(right.value)\n\t)\n\t\treturn;\n\n\tif (std::optional<rational> value = evaluateBinaryOperator(\n\t\t_operation.getOperator(),\n\t\tstd::get<rational>(left.value),\n\t\tstd::get<rational>(right.value)\n\t))\n\t{\n\t\tTypedValue convertedValue = convertType(*value, *resultType);\n\t\tif (!convertedValue.type)\n\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t2643_error,\n\t\t\t\t_operation.location(),\n\t\t\t\t\"Arithmetic error when computing constant value.\"\n\t\t\t);\n\t\tm_values[&_operation] = convertedValue;\n\t}\n}\n\nvoid ConstantEvaluator::endVisit(Literal const& _literal)\n{\n\tif (Type const* literalType = TypeProvider::forLiteral(_literal))\n\t\tm_values[&_literal] = constantToTypedValue(*literalType);\n}\n\nvoid ConstantEvaluator::endVisit(Identifier const& _identifier)\n{\n\tVariableDeclaration const* variableDeclaration = dynamic_cast<VariableDeclaration const*>(_identifier.annotation().referencedDeclaration);\n\tif (variableDeclaration && variableDeclaration->isConstant())\n\t\tm_values[&_identifier] = evaluate(*variableDeclaration);\n}\n\nvoid ConstantEvaluator::endVisit(TupleExpression const& _tuple)\n{\n\tif (!_tuple.isInlineArray() && _tuple.components().size() == 1)\n\t\tm_values[&_tuple] = evaluate(*_tuple.components().front());\n}\n\nvoid ConstantEvaluator::endVisit(FunctionCall const& _functionCall)\n{\n\tauto const* builtinFunction = dynamic_cast<MagicVariableDeclaration const*>(ASTNode::referencedDeclaration(_functionCall.expression()));\n\tif (!builtinFunction)\n\t\treturn;\n\n\tauto const* functionType = builtinFunction->functionType(true);\n\tsolAssert(functionType);\n\tswitch (functionType->kind())\n\t{\n\t\tcase FunctionType::Kind::ERC7201:\n\t\t{\n\t\t\tsolAssert(_functionCall.arguments().size() == 1);\n\t\t\tauto stringArg = evaluate(*(_functionCall.arguments()[0].get()));\n\t\t\tif (!std::holds_alternative<std::string>(stringArg.value))\n\t\t\t\treturn;\n\n\t\t\th256 innerKeccak = keccak256(std::get<std::string>(stringArg.value));\n\t\t\th256 outerKeccak = keccak256(h256(u256(innerKeccak) - 1));\n\t\t\touterKeccak.data()[31] = 0;\n\t\t\tu256 slot = outerKeccak;\n\t\t\tsolAssert(functionType->returnParameterTypes().size() == 1);\n\t\t\tm_values[&_functionCall] = TypedValue{functionType->returnParameterTypes()[0], rational{slot}};\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n"
  },
  {
    "path": "libsolidity/analysis/ConstantEvaluator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Evaluator for types of constant expressions.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n\n#include <utility>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend\n{\n\nclass TypeChecker;\n\n/**\n * Small drop-in replacement for TypeChecker to evaluate simple expressions of integer constants.\n *\n * Note: This always use \"checked arithmetic\" in the sense that any over- or underflow\n * results in \"unknown\" value.\n */\nclass ConstantEvaluator: private ASTConstVisitor\n{\npublic:\n\tstruct TypedValue\n\t{\n\t\t// Type may be RationalType or IntegerType for value rational\n\t\tType const* type;\n\t\tstd::variant<std::monostate, rational, std::string> value;\n\t};\n\n\tstatic TypedValue evaluate(\n\t\tlangutil::ErrorReporter& _errorReporter,\n\t\tExpression const& _expr\n\t);\n\n\t/// Works the same as `evaluate` but swallows any errors that might occur in the evaluation and simply returns\n\t/// `TypedValue` containing `std::monostate` instead.\n\tstatic TypedValue tryEvaluate(Expression const& _expr);\n\n\t/// Performs arbitrary-precision evaluation of a binary operator. Returns nullopt on cases like\n\t/// division by zero or e.g. bit operators applied to fractional values.\n\tstatic std::optional<rational> evaluateBinaryOperator(Token _operator, rational const& _left, rational const&  _right);\n\n\t/// Performs arbitrary-precision evaluation of a unary operator. Returns nullopt on cases like\n\t/// bit operators applied to fractional values.\n\tstatic std::optional<rational> evaluateUnaryOperator(Token _operator, rational const& _input);\n\nprivate:\n\texplicit ConstantEvaluator(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}\n\n\tTypedValue evaluate(ASTNode const& _node);\n\n\tvoid endVisit(BinaryOperation const& _operation) override;\n\tvoid endVisit(UnaryOperation const& _operation) override;\n\tvoid endVisit(Literal const& _literal) override;\n\tvoid endVisit(Identifier const& _identifier) override;\n\tvoid endVisit(TupleExpression const& _tuple) override;\n\tvoid endVisit(FunctionCall const& _functionCall) override;\n\n\tlangutil::ErrorReporter& m_errorReporter;\n\t/// Current recursion depth.\n\tsize_t m_depth = 0;\n\t/// Values of sub-expressions and variable declarations.\n\tstd::map<ASTNode const*, TypedValue> m_values;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/ContractLevelChecker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that verifies overloads, abstract contracts, function clashes and others\n * checks at contract or function level.\n */\n\n#include <libsolidity/analysis/ContractLevelChecker.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTUtils.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/analysis/TypeChecker.h>\n#include <libsolutil/FunctionSelector.h>\n#include <liblangutil/ErrorReporter.h>\n\n#include <fmt/format.h>\n\n#include <range/v3/algorithm/find_if.hpp>\n#include <range/v3/view/reverse.hpp>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nnamespace\n{\n\ntemplate <class T, class B>\nbool hasEqualExternalCallableParameters(T const& _a, B const& _b)\n{\n\treturn FunctionType(_a).asExternallyCallableFunction(false)->hasEqualParameterTypes(\n\t\t*FunctionType(_b).asExternallyCallableFunction(false)\n\t);\n}\n\ntemplate<typename T>\nstd::map<ASTString, std::vector<T const*>> filterDeclarations(\n\tstd::map<ASTString, std::vector<Declaration const*>> const& _declarations)\n{\n\tstd::map<ASTString, std::vector<T const*>> filteredDeclarations;\n\tfor (auto const& [name, overloads]: _declarations)\n\t\tfor (auto const* declaration: overloads)\n\t\t\tif (auto typedDeclaration = dynamic_cast<T const*>(declaration))\n\t\t\t\tfilteredDeclarations[name].push_back(typedDeclaration);\n\treturn filteredDeclarations;\n}\n\n}\n\nbool ContractLevelChecker::check(SourceUnit const& _sourceUnit)\n{\n\tbool noErrors = true;\n\tfindDuplicateDefinitions(\n\t\tfilterDeclarations<FunctionDefinition>(*_sourceUnit.annotation().exportedSymbols)\n\t);\n\t// This check flags duplicate free events when free events become\n\t// a Solidity feature\n\tfindDuplicateDefinitions(\n\t\tfilterDeclarations<EventDefinition>(*_sourceUnit.annotation().exportedSymbols)\n\t);\n\tif (Error::containsErrors(m_errorReporter.errors()))\n\t\tnoErrors = false;\n\tfor (ASTPointer<ASTNode> const& node: _sourceUnit.nodes())\n\t\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))\n\t\t\tif (!check(*contract))\n\t\t\t\tnoErrors = false;\n\treturn noErrors;\n}\n\nbool ContractLevelChecker::check(ContractDefinition const& _contract)\n{\n\t_contract.annotation().unimplementedDeclarations = std::vector<Declaration const*>();\n\n\tcheckDuplicateFunctions(_contract);\n\tcheckDuplicateEvents(_contract);\n\tcheckReceiveFunction(_contract);\n\tm_overrideChecker.check(_contract);\n\tcheckBaseConstructorArguments(_contract);\n\tcheckAbstractDefinitions(_contract);\n\tcheckExternalTypeClashes(_contract);\n\tcheckHashCollisions(_contract);\n\tcheckLibraryRequirements(_contract);\n\tcheckBaseABICompatibility(_contract);\n\tcheckPayableFallbackWithoutReceive(_contract);\n\tcheckStorageSize(_contract);\n\tcheckStorageLayoutSpecifier(_contract);\n\n\treturn !Error::containsErrors(m_errorReporter.errors());\n}\n\nvoid ContractLevelChecker::checkStorageLayoutSpecifier(ContractDefinition const& _contract)\n{\n\tif (_contract.storageLayoutSpecifier())\n\t{\n\t\tsolAssert(!_contract.isLibrary() && !_contract.isInterface());\n\n\t\tif (_contract.abstract())\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t7587_error,\n\t\t\t\t_contract.storageLayoutSpecifier()->location(),\n\t\t\t\t\"Storage layout cannot be specified for abstract contracts.\"\n\t\t\t);\n\t}\n\n\tfor (auto const& baseContractSpecifier: _contract.baseContracts())\n\t{\n\t\tauto const* baseContract = dynamic_cast<ContractDefinition const*>(\n\t\t\tbaseContractSpecifier->name().annotation().referencedDeclaration\n\t\t);\n\n\t\tsolAssert(baseContract);\n\t\tif (baseContract->storageLayoutSpecifier())\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t8894_error,\n\t\t\t\tbaseContractSpecifier->location(),\n\t\t\t\tSecondarySourceLocation().append(\n\t\t\t\t\t\"Custom storage layout defined here:\",\n\t\t\t\t\tbaseContract->storageLayoutSpecifier()->location()\n\t\t\t\t),\n\t\t\t\t\"Cannot inherit from a contract with a custom storage layout.\"\n\t\t\t);\n\t}\n}\nvoid ContractLevelChecker::checkDuplicateFunctions(ContractDefinition const& _contract)\n{\n\t/// Checks that two functions with the same name defined in this contract have different\n\t/// argument types and that there is at most one constructor.\n\tstd::map<std::string, std::vector<FunctionDefinition const*>> functions;\n\tFunctionDefinition const* constructor = nullptr;\n\tFunctionDefinition const* fallback = nullptr;\n\tFunctionDefinition const* receive = nullptr;\n\tfor (FunctionDefinition const* function: _contract.definedFunctions())\n\t\tif (function->isConstructor())\n\t\t{\n\t\t\tif (constructor)\n\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t7997_error,\n\t\t\t\t\tfunction->location(),\n\t\t\t\t\tSecondarySourceLocation().append(\"Another declaration is here:\", constructor->location()),\n\t\t\t\t\t\"More than one constructor defined.\"\n\t\t\t\t);\n\t\t\tconstructor = function;\n\t\t}\n\t\telse if (function->isFallback())\n\t\t{\n\t\t\tif (fallback)\n\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t7301_error,\n\t\t\t\t\tfunction->location(),\n\t\t\t\t\tSecondarySourceLocation().append(\"Another declaration is here:\", fallback->location()),\n\t\t\t\t\t\"Only one fallback function is allowed.\"\n\t\t\t\t);\n\t\t\tfallback = function;\n\t\t}\n\t\telse if (function->isReceive())\n\t\t{\n\t\t\tif (receive)\n\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t4046_error,\n\t\t\t\t\tfunction->location(),\n\t\t\t\t\tSecondarySourceLocation().append(\"Another declaration is here:\", receive->location()),\n\t\t\t\t\t\"Only one receive function is allowed.\"\n\t\t\t\t);\n\t\t\treceive = function;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(!function->name().empty(), \"\");\n\t\t\tfunctions[function->name()].push_back(function);\n\t\t}\n\n\tfindDuplicateDefinitions(functions);\n}\n\nvoid ContractLevelChecker::checkDuplicateEvents(ContractDefinition const& _contract)\n{\n\t/// Checks that two events with the same name defined in this contract have different\n\t/// argument types\n\tstd::map<std::string, std::vector<EventDefinition const*>> events;\n\tfor (auto const* contract: _contract.annotation().linearizedBaseContracts)\n\t\tfor (EventDefinition const* event: contract->events())\n\t\t\tevents[event->name()].push_back(event);\n\n\tfindDuplicateDefinitions(events);\n}\n\nvoid ContractLevelChecker::checkReceiveFunction(ContractDefinition const& _contract)\n{\n\tfor (FunctionDefinition const* function: _contract.definedFunctions())\n\t{\n\t\tsolAssert(function, \"\");\n\t\tif (function->isReceive())\n\t\t{\n\t\t\tif (function->libraryFunction())\n\t\t\t\tm_errorReporter.declarationError(4549_error, function->location(), \"Libraries cannot have receive ether functions.\");\n\n\t\t\tif (function->stateMutability() != StateMutability::Payable)\n\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t7793_error,\n\t\t\t\t\tfunction->location(),\n\t\t\t\t\t\"Receive ether function must be payable, but is \\\"\" +\n\t\t\t\t\tstateMutabilityToString(function->stateMutability()) +\n\t\t\t\t\t\"\\\".\"\n\t\t\t\t);\n\t\t\tif (function->visibility() != Visibility::External)\n\t\t\t\tm_errorReporter.declarationError(4095_error, function->location(), \"Receive ether function must be defined as \\\"external\\\".\");\n\n\t\t\tif (!function->returnParameters().empty())\n\t\t\t\tm_errorReporter.fatalDeclarationError(6899_error, function->returnParameterList()->location(), \"Receive ether function cannot return values.\");\n\t\t\tif (!function->parameters().empty())\n\t\t\t\tm_errorReporter.fatalDeclarationError(6857_error, function->parameterList().location(), \"Receive ether function cannot take parameters.\");\n\t\t}\n\t}\n}\n\ntemplate <class T>\nvoid ContractLevelChecker::findDuplicateDefinitions(std::map<std::string, std::vector<T>> const& _definitions)\n{\n\tfor (auto const& it: _definitions)\n\t{\n\t\tstd::vector<T> const& overloads = it.second;\n\t\tstd::set<size_t> reported;\n\t\tfor (size_t i = 0; i < overloads.size() && !reported.count(i); ++i)\n\t\t{\n\t\t\tSecondarySourceLocation ssl;\n\n\t\t\tfor (size_t j = i + 1; j < overloads.size(); ++j)\n\t\t\t\tif (hasEqualExternalCallableParameters(*overloads[i], *overloads[j]))\n\t\t\t\t{\n\t\t\t\t\tsolAssert(\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tdynamic_cast<ContractDefinition const*>(overloads[i]->scope()) &&\n\t\t\t\t\t\t\tdynamic_cast<ContractDefinition const*>(overloads[j]->scope()) &&\n\t\t\t\t\t\t\toverloads[i]->name() == overloads[j]->name()\n\t\t\t\t\t\t) ||\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tdynamic_cast<SourceUnit const*>(overloads[i]->scope()) &&\n\t\t\t\t\t\t\tdynamic_cast<SourceUnit const*>(overloads[j]->scope())\n\t\t\t\t\t\t),\n\t\t\t\t\t\t\"Override is neither a namesake function/event in contract scope nor \"\n\t\t\t\t\t\t\"a free function/event (alias).\"\n\t\t\t\t\t);\n\t\t\t\t\tssl.append(\"Other declaration is here:\", overloads[j]->location());\n\t\t\t\t\treported.insert(j);\n\t\t\t\t}\n\n\t\t\tif (ssl.infos.size() > 0)\n\t\t\t{\n\t\t\t\tErrorId error;\n\t\t\t\tstd::string message;\n\t\t\t\tif constexpr (std::is_same_v<T, FunctionDefinition const*>)\n\t\t\t\t{\n\t\t\t\t\terror = 1686_error;\n\t\t\t\t\tmessage = \"Function with same name and parameter types defined twice.\";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tstatic_assert(std::is_same_v<T, EventDefinition const*>, \"Expected \\\"FunctionDefinition const*\\\" or \\\"EventDefinition const*\\\"\");\n\t\t\t\t\terror = 5883_error;\n\t\t\t\t\tmessage = \"Event with same name and parameter types defined twice.\";\n\t\t\t\t}\n\n\t\t\t\tssl.limitSize(message);\n\n\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\terror,\n\t\t\t\t\toverloads[i]->location(),\n\t\t\t\t\tssl,\n\t\t\t\t\tmessage\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid ContractLevelChecker::checkAbstractDefinitions(ContractDefinition const& _contract)\n{\n\t// Collects functions, static variable getters and modifiers. If they\n\t// override (unimplemented) base class ones, they are replaced.\n\tstd::set<OverrideProxy, OverrideProxy::CompareBySignature> proxies;\n\n\tauto registerProxy = [&proxies](OverrideProxy const& _overrideProxy)\n\t{\n\t\t// Overwrite an existing proxy, if it exists.\n\t\tif (!_overrideProxy.unimplemented())\n\t\t\tproxies.erase(_overrideProxy);\n\n\t\tproxies.insert(_overrideProxy);\n\t};\n\n\t// Search from base to derived, collect all functions and modifiers and\n\t// update proxies.\n\tfor (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts | ranges::views::reverse)\n\t{\n\t\tfor (VariableDeclaration const* v: contract->stateVariables())\n\t\t\tif (v->isPartOfExternalInterface())\n\t\t\t\tregisterProxy(OverrideProxy(v));\n\n\t\tfor (FunctionDefinition const* function: contract->definedFunctions())\n\t\t\tif (!function->isConstructor())\n\t\t\t\tregisterProxy(OverrideProxy(function));\n\n\t\tfor (ModifierDefinition const* modifier: contract->functionModifiers())\n\t\t\tregisterProxy(OverrideProxy(modifier));\n\t}\n\n\t// Set to not fully implemented if at least one flag is false.\n\tfor (auto const& proxy: proxies)\n\t\tif (proxy.unimplemented())\n\t\t\t_contract.annotation().unimplementedDeclarations->push_back(proxy.declaration());\n\n\tif (_contract.abstract())\n\t{\n\t\tif (_contract.contractKind() == ContractKind::Interface)\n\t\t\tm_errorReporter.typeError(9348_error, _contract.location(), \"Interfaces do not need the \\\"abstract\\\" keyword, they are abstract implicitly.\");\n\t\telse if (_contract.contractKind() == ContractKind::Library)\n\t\t\tm_errorReporter.typeError(9571_error, _contract.location(), \"Libraries cannot be abstract.\");\n\t\telse\n\t\t\tsolAssert(_contract.contractKind() == ContractKind::Contract, \"\");\n\t}\n\n\t// For libraries, we emit errors on function-level, so this is fine as long as we do\n\t// not have inheritance for libraries.\n\tif (\n\t\t_contract.contractKind() == ContractKind::Contract &&\n\t\t!_contract.abstract() &&\n\t\t!_contract.annotation().unimplementedDeclarations->empty()\n\t)\n\t{\n\t\tSecondarySourceLocation ssl;\n\t\tfor (auto declaration: *_contract.annotation().unimplementedDeclarations)\n\t\t\tssl.append(\"Missing implementation: \", declaration->location());\n\t\tm_errorReporter.typeError(\n\t\t\t3656_error,\n\t\t\t_contract.location(),\n\t\t\tssl,\n\t\t\t\"Contract \\\"\" + *_contract.annotation().canonicalName + \"\\\" should be marked as abstract.\"\n\t\t);\n\t}\n}\n\n\nvoid ContractLevelChecker::checkBaseConstructorArguments(ContractDefinition const& _contract)\n{\n\tstd::vector<ContractDefinition const*> const& bases = _contract.annotation().linearizedBaseContracts;\n\n\t// Determine the arguments that are used for the base constructors.\n\tfor (ContractDefinition const* contract: bases)\n\t{\n\t\tif (FunctionDefinition const* constructor = contract->constructor())\n\t\t\tfor (auto const& modifier: constructor->modifiers())\n\t\t\t\tif (auto baseContract = dynamic_cast<ContractDefinition const*>(\n\t\t\t\t\tmodifier->name().annotation().referencedDeclaration\n\t\t\t\t))\n\t\t\t\t{\n\t\t\t\t\tif (modifier->arguments())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (baseContract->constructor())\n\t\t\t\t\t\t\tannotateBaseConstructorArguments(_contract, baseContract->constructor(), modifier.get());\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t\t\t1563_error,\n\t\t\t\t\t\t\tmodifier->location(),\n\t\t\t\t\t\t\t\"Modifier-style base constructor call without arguments.\"\n\t\t\t\t\t\t);\n\t\t\t\t}\n\n\t\tfor (ASTPointer<InheritanceSpecifier> const& base: contract->baseContracts())\n\t\t{\n\t\t\tContractDefinition const* baseContract = dynamic_cast<ContractDefinition const*>(\n\t\t\t\tbase->name().annotation().referencedDeclaration\n\t\t\t);\n\t\t\tsolAssert(baseContract, \"\");\n\n\t\t\tif (baseContract->constructor() && base->arguments() && !base->arguments()->empty())\n\t\t\t\tannotateBaseConstructorArguments(_contract, baseContract->constructor(), base.get());\n\t\t}\n\t}\n\n\t// check that we get arguments for all base constructors that need it.\n\t// If not mark the contract as abstract (not fully implemented)\n\tif (_contract.contractKind() == ContractKind::Contract && !_contract.abstract())\n\t\tfor (ContractDefinition const* baseContract: bases)\n\t\t\tif (FunctionDefinition const* baseConstructor = baseContract->constructor())\n\t\t\t\tif (\n\t\t\t\t\tbaseContract != &_contract &&\n\t\t\t\t\t!baseConstructor->parameters().empty() &&\n\t\t\t\t\t_contract.annotation().baseConstructorArguments.count(baseConstructor) == 0\n\t\t\t\t)\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t3415_error,\n\t\t\t\t\t\t_contract.location(),\n\t\t\t\t\t\tSecondarySourceLocation{}.append(\n\t\t\t\t\t\t\t\"Base constructor parameters:\",\n\t\t\t\t\t\t\tbaseConstructor->parameterList().location()\n\t\t\t\t\t\t),\n\t\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\t\"No arguments passed to the base constructor. \"\n\t\t\t\t\t\t\t\"Specify the arguments or mark \\\"{}\\\" as abstract.\",\n\t\t\t\t\t\t\t*_contract.annotation().canonicalName\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n}\n\nvoid ContractLevelChecker::annotateBaseConstructorArguments(\n\tContractDefinition const& _currentContract,\n\tFunctionDefinition const* _baseConstructor,\n\tASTNode const* _argumentNode\n)\n{\n\tsolAssert(_baseConstructor, \"\");\n\tsolAssert(_argumentNode, \"\");\n\n\tauto insertionResult = _currentContract.annotation().baseConstructorArguments.insert(\n\t\tstd::make_pair(_baseConstructor, _argumentNode)\n\t);\n\tif (!insertionResult.second)\n\t{\n\t\tASTNode const* previousNode = insertionResult.first->second;\n\n\t\tSourceLocation const* mainLocation = nullptr;\n\t\tSecondarySourceLocation ssl;\n\n\t\tif (\n\t\t\t_currentContract.location().contains(previousNode->location()) ||\n\t\t\t_currentContract.location().contains(_argumentNode->location())\n\t\t)\n\t\t{\n\t\t\tmainLocation = &previousNode->location();\n\t\t\tssl.append(\"Second constructor call is here:\", _argumentNode->location());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmainLocation = &_currentContract.location();\n\t\t\tssl.append(\"First constructor call is here:\", _argumentNode->location());\n\t\t\tssl.append(\"Second constructor call is here:\", previousNode->location());\n\t\t}\n\n\t\tm_errorReporter.declarationError(\n\t\t\t3364_error,\n\t\t\t*mainLocation,\n\t\t\tssl,\n\t\t\t\"Base constructor arguments given twice.\"\n\t\t);\n\t}\n\n}\n\nvoid ContractLevelChecker::checkExternalTypeClashes(ContractDefinition const& _contract)\n{\n\tstd::map<std::string, std::vector<std::pair<Declaration const*, FunctionTypePointer>>> externalDeclarations;\n\tfor (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts)\n\t{\n\t\tfor (FunctionDefinition const* f: contract->definedFunctions())\n\t\t\tif (f->isPartOfExternalInterface())\n\t\t\t{\n\t\t\t\tauto functionType = TypeProvider::function(*f);\n\t\t\t\t// under non error circumstances this should be true\n\t\t\t\tif (functionType->interfaceFunctionType())\n\t\t\t\t\texternalDeclarations[functionType->externalSignature()].emplace_back(\n\t\t\t\t\t\tf, functionType->asExternallyCallableFunction(false)\n\t\t\t\t\t);\n\t\t\t}\n\t\tfor (VariableDeclaration const* v: contract->stateVariables())\n\t\t\tif (v->isPartOfExternalInterface())\n\t\t\t{\n\t\t\t\tauto functionType = TypeProvider::function(*v);\n\t\t\t\t// under non error circumstances this should be true\n\t\t\t\tif (functionType->interfaceFunctionType())\n\t\t\t\t\texternalDeclarations[functionType->externalSignature()].emplace_back(\n\t\t\t\t\t\tv, functionType->asExternallyCallableFunction(false)\n\t\t\t\t\t);\n\t\t\t}\n\t}\n\tfor (auto const& it: externalDeclarations)\n\t\tfor (size_t i = 0; i < it.second.size(); ++i)\n\t\t\tfor (size_t j = i + 1; j < it.second.size(); ++j)\n\t\t\t\tif (!it.second[i].second->hasEqualParameterTypes(*it.second[j].second))\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t9914_error,\n\t\t\t\t\t\tit.second[j].first->location(),\n\t\t\t\t\t\t\"Function overload clash during conversion to external types for arguments.\"\n\t\t\t\t\t);\n}\n\nvoid ContractLevelChecker::checkHashCollisions(ContractDefinition const& _contract)\n{\n\tstd::set<util::FixedHash<4>> hashes;\n\tfor (auto const& it: _contract.interfaceFunctionList())\n\t{\n\t\tutil::FixedHash<4> const& hash = it.first;\n\t\tif (hashes.count(hash))\n\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t1860_error,\n\t\t\t\t_contract.location(),\n\t\t\t\tstd::string(\"Function signature hash collision for \") + it.second->externalSignature()\n\t\t\t);\n\t\thashes.insert(hash);\n\t}\n}\n\nvoid ContractLevelChecker::checkLibraryRequirements(ContractDefinition const& _contract)\n{\n\tif (!_contract.isLibrary())\n\t\treturn;\n\n\tif (!_contract.baseContracts().empty())\n\t\tm_errorReporter.typeError(9469_error, _contract.location(), \"Library is not allowed to inherit.\");\n\n\tfor (auto const& var: _contract.stateVariables())\n\t\tif (!var->isConstant())\n\t\t\tm_errorReporter.typeError(9957_error, var->location(), \"Library cannot have non-constant state variables\");\n}\n\nvoid ContractLevelChecker::checkBaseABICompatibility(ContractDefinition const& _contract)\n{\n\tif (*_contract.sourceUnit().annotation().useABICoderV2)\n\t\treturn;\n\n\tif (_contract.isLibrary())\n\t{\n\t\tsolAssert(\n\t\t\t_contract.baseContracts().empty() || m_errorReporter.hasErrors(),\n\t\t\t\"Library is not allowed to inherit\"\n\t\t);\n\t\treturn;\n\t}\n\n\tSecondarySourceLocation errors;\n\n\t// interfaceFunctionList contains all inherited functions as well\n\tfor (auto const& func: _contract.interfaceFunctionList())\n\t{\n\t\tsolAssert(func.second->hasDeclaration(), \"Function has no declaration?!\");\n\n\t\tif (!*func.second->declaration().sourceUnit().annotation().useABICoderV2)\n\t\t\tcontinue;\n\n\t\tauto const& currentLoc = func.second->declaration().location();\n\n\t\tfor (Type const* paramType: func.second->parameterTypes() + func.second->returnParameterTypes())\n\t\t\tif (!TypeChecker::typeSupportedByOldABIEncoder(*paramType, false))\n\t\t\t{\n\t\t\t\terrors.append(\"Type only supported by ABIEncoderV2\", currentLoc);\n\t\t\t\tbreak;\n\t\t\t}\n\t}\n\n\tif (!errors.infos.empty())\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t6594_error,\n\t\t\t_contract.location(),\n\t\t\terrors,\n\t\t\tstd::string(\"Contract \\\"\") +\n\t\t\t_contract.name() +\n\t\t\t\"\\\" does not use ABI coder v2 but wants to inherit from a contract \" +\n\t\t\t\"which uses types that require it. \" +\n\t\t\t\"Use \\\"pragma abicoder v2;\\\" for the inheriting contract as well to enable the feature.\"\n\t\t);\n\n}\n\nvoid ContractLevelChecker::checkPayableFallbackWithoutReceive(ContractDefinition const& _contract)\n{\n\tif (auto const* fallback = _contract.fallbackFunction())\n\t\tif (fallback->isPayable() && !_contract.interfaceFunctionList().empty() && !_contract.receiveFunction())\n\t\t\tm_errorReporter.warning(\n\t\t\t\t3628_error,\n\t\t\t\t_contract.location(),\n\t\t\t\t\"This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function.\",\n\t\t\t\tSecondarySourceLocation{}.append(\"The payable fallback function is defined here.\", fallback->location())\n\t\t\t);\n}\n\nvoid ContractLevelChecker::checkStorageSize(ContractDefinition const& _contract)\n{\n\tusing enum VariableDeclaration::Location;\n\tfor (VariableDeclaration::Location location: {Unspecified, Transient})\n\t{\n\t\tbigint size = contractStorageSizeUpperBound(_contract, location);\n\t\tif (size >= bigint(1) << 256)\n\t\t{\n\t\t\tif (location == Unspecified)\n\t\t\t\tm_errorReporter.typeError(7676_error, _contract.location(), \"Contract requires too much storage.\");\n\t\t\telse\n\t\t\t\tm_errorReporter.typeError(5026_error, _contract.location(), \"Contract requires too much transient storage.\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "libsolidity/analysis/ContractLevelChecker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that verifies overloads, abstract contracts, function clashes and others\n * checks at contract or function level.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/analysis/OverrideChecker.h>\n#include <liblangutil/SourceLocation.h>\n#include <map>\n#include <functional>\n#include <set>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend\n{\n\n/**\n * Component that verifies overloads, abstract contracts, function clashes and others\n * checks at file, contract, or function level.\n */\nclass ContractLevelChecker\n{\npublic:\n\n\t/// @param _errorReporter provides the error logging functionality.\n\texplicit ContractLevelChecker(langutil::ErrorReporter& _errorReporter):\n\t\tm_overrideChecker{_errorReporter},\n\t\tm_errorReporter(_errorReporter)\n\t{}\n\n\t/// Performs checks on the given source ast.\n\t/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings\n\tbool check(SourceUnit const& _sourceUnit);\n\nprivate:\n\t/// Performs checks on the given contract.\n\t/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings\n\tbool check(ContractDefinition const& _contract);\n\t/// Checks that two functions defined in this contract with the same name have different\n\t/// arguments and that there is at most one constructor.\n\tvoid checkDuplicateFunctions(ContractDefinition const& _contract);\n\tvoid checkDuplicateEvents(ContractDefinition const& _contract);\n\tvoid checkReceiveFunction(ContractDefinition const& _contract);\n\ttemplate <class T>\n\tvoid findDuplicateDefinitions(std::map<std::string, std::vector<T>> const& _definitions);\n\t/// Checks for unimplemented functions and modifiers.\n\tvoid checkAbstractDefinitions(ContractDefinition const& _contract);\n\t/// Checks that the base constructor arguments are properly provided.\n\t/// Fills the list of unimplemented functions in _contract's annotations.\n\tvoid checkBaseConstructorArguments(ContractDefinition const& _contract);\n\tvoid annotateBaseConstructorArguments(\n\t\tContractDefinition const& _currentContract,\n\t\tFunctionDefinition const* _baseConstructor,\n\t\tASTNode const* _argumentNode\n\t);\n\t/// Checks that different functions with external visibility end up having different\n\t/// external argument types (i.e. different signature).\n\tvoid checkExternalTypeClashes(ContractDefinition const& _contract);\n\t/// Checks for hash collisions in external function signatures.\n\tvoid checkHashCollisions(ContractDefinition const& _contract);\n\t/// Checks that all requirements for a library are fulfilled if this is a library.\n\tvoid checkLibraryRequirements(ContractDefinition const& _contract);\n\t/// Checks base contracts for ABI compatibility\n\tvoid checkBaseABICompatibility(ContractDefinition const& _contract);\n\n\t/// Warns if the contract has a payable fallback, but no receive ether function.\n\tvoid checkPayableFallbackWithoutReceive(ContractDefinition const& _contract);\n\t/// Error if the contract requires too much storage or transient storage\n\tvoid checkStorageSize(ContractDefinition const& _contract);\n\t/// Checks if the storage layout specifier is properly assigned in the inheritance tree and not applied to an abstract contract\n\tvoid checkStorageLayoutSpecifier(ContractDefinition const& _contract);\n\n\tOverrideChecker m_overrideChecker;\n\tlangutil::ErrorReporter& m_errorReporter;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/ControlFlowAnalyzer.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/ControlFlowAnalyzer.h>\n\n#include <liblangutil/SourceLocation.h>\n#include <libsolutil/Algorithms.h>\n\n#include <range/v3/algorithm/sort.hpp>\n\n#include <functional>\n\nusing namespace std::placeholders;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\n\nbool ControlFlowAnalyzer::run()\n{\n\tfor (auto& [pair, flow]: m_cfg.allFunctionFlows())\n\t\tanalyze(*pair.function, pair.contract, *flow);\n\n\treturn !Error::containsErrors(m_errorReporter.errors());\n}\n\nvoid ControlFlowAnalyzer::analyze(FunctionDefinition const& _function, ContractDefinition const* _contract, FunctionFlow const& _flow)\n{\n\tif (!_function.isImplemented())\n\t\treturn;\n\n\tstd::optional<std::string> mostDerivedContractName;\n\n\t// The name of the most derived contract only required if it differs from\n\t// the functions contract\n\tif (_contract && _contract != _function.annotation().contract)\n\t\tmostDerivedContractName = _contract->name();\n\n\tcheckUninitializedAccess(\n\t\t_flow.entry,\n\t\t_flow.exit,\n\t\t_function.body().statements().empty(),\n\t\tmostDerivedContractName\n\t);\n\tcheckUnreachable(_flow.entry, _flow.exit, _flow.revert, _flow.transactionReturn);\n}\n\n\nvoid ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNode const* _exit, bool _emptyBody, std::optional<std::string> _contractName)\n{\n\tstruct NodeInfo\n\t{\n\t\tstd::set<VariableDeclaration const*> unassignedVariablesAtEntry;\n\t\tstd::set<VariableDeclaration const*> unassignedVariablesAtExit;\n\t\tstd::set<VariableOccurrence const*> uninitializedVariableAccesses;\n\t\t/// Propagate the information from another node to this node.\n\t\t/// To be used to propagate information from a node to its exit nodes.\n\t\t/// Returns true, if new variables were added and thus the current node has\n\t\t/// to be traversed again.\n\t\tbool propagateFrom(NodeInfo const& _entryNode)\n\t\t{\n\t\t\tsize_t previousUnassignedVariablesAtEntry = unassignedVariablesAtEntry.size();\n\t\t\tsize_t previousUninitializedVariableAccesses = uninitializedVariableAccesses.size();\n\t\t\tunassignedVariablesAtEntry += _entryNode.unassignedVariablesAtExit;\n\t\t\tuninitializedVariableAccesses += _entryNode.uninitializedVariableAccesses;\n\t\t\treturn\n\t\t\t\tunassignedVariablesAtEntry.size() > previousUnassignedVariablesAtEntry ||\n\t\t\t\tuninitializedVariableAccesses.size() > previousUninitializedVariableAccesses\n\t\t\t;\n\t\t}\n\t};\n\tstd::map<CFGNode const*, NodeInfo> nodeInfos;\n\tstd::set<CFGNode const*> nodesToTraverse;\n\tnodesToTraverse.insert(_entry);\n\n\t// Walk all paths starting from the nodes in ``nodesToTraverse`` until ``NodeInfo::propagateFrom``\n\t// returns false for all exits, i.e. until all paths have been walked with maximal sets of unassigned\n\t// variables and accesses.\n\twhile (!nodesToTraverse.empty())\n\t{\n\t\tCFGNode const* currentNode = *nodesToTraverse.begin();\n\t\tnodesToTraverse.erase(nodesToTraverse.begin());\n\n\t\tauto& nodeInfo = nodeInfos[currentNode];\n\t\tauto unassignedVariables = nodeInfo.unassignedVariablesAtEntry;\n\t\tfor (auto const& variableOccurrence: currentNode->variableOccurrences)\n\t\t{\n\t\t\tswitch (variableOccurrence.kind())\n\t\t\t{\n\t\t\t\tcase VariableOccurrence::Kind::Assignment:\n\t\t\t\t\tunassignedVariables.erase(&variableOccurrence.declaration());\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableOccurrence::Kind::InlineAssembly:\n\t\t\t\t\t// We consider all variables referenced in inline assembly as accessed.\n\t\t\t\t\t// So far any reference is enough, but we might want to actually analyze\n\t\t\t\t\t// the control flow in the assembly at some point.\n\t\t\t\tcase VariableOccurrence::Kind::Access:\n\t\t\t\tcase VariableOccurrence::Kind::Return:\n\t\t\t\t\tif (unassignedVariables.count(&variableOccurrence.declaration()))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Merely store the unassigned access. We do not generate an error right away, since this\n\t\t\t\t\t\t// path might still always revert. It is only an error if this is propagated to the exit\n\t\t\t\t\t\t// node of the function (i.e. there is a path with an uninitialized access).\n\t\t\t\t\t\tnodeInfo.uninitializedVariableAccesses.insert(&variableOccurrence);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableOccurrence::Kind::Declaration:\n\t\t\t\t\tunassignedVariables.insert(&variableOccurrence.declaration());\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tnodeInfo.unassignedVariablesAtExit = std::move(unassignedVariables);\n\n\t\t// Propagate changes to all exits and queue them for traversal, if needed.\n\t\tfor (auto const& exit: currentNode->exits)\n\t\t\tif (\n\t\t\t\tauto exists = util::valueOrNullptr(nodeInfos, exit);\n\t\t\t\tnodeInfos[exit].propagateFrom(nodeInfo) || !exists\n\t\t\t)\n\t\t\t\tnodesToTraverse.insert(exit);\n\t}\n\n\tauto const& exitInfo = nodeInfos[_exit];\n\tif (!exitInfo.uninitializedVariableAccesses.empty())\n\t{\n\t\tstd::vector<VariableOccurrence const*> uninitializedAccessesOrdered(\n\t\t\texitInfo.uninitializedVariableAccesses.begin(),\n\t\t\texitInfo.uninitializedVariableAccesses.end()\n\t\t);\n\t\tranges::sort(\n\t\t\tuninitializedAccessesOrdered,\n\t\t\t[](VariableOccurrence const* lhs, VariableOccurrence const* rhs) -> bool\n\t\t\t{\n\t\t\t\treturn *lhs < *rhs;\n\t\t\t}\n\t\t);\n\n\t\tfor (auto const* variableOccurrence: uninitializedAccessesOrdered)\n\t\t{\n\t\t\tVariableDeclaration const& varDecl = variableOccurrence->declaration();\n\n\t\t\tSecondarySourceLocation ssl;\n\t\t\tif (variableOccurrence->occurrence())\n\t\t\t\tssl.append(\"The variable was declared here.\", varDecl.location());\n\n\t\t\tbool isStorage = varDecl.type()->dataStoredIn(DataLocation::Storage);\n\t\t\tbool isCalldata = varDecl.type()->dataStoredIn(DataLocation::CallData);\n\t\t\tif (isStorage || isCalldata)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t3464_error,\n\t\t\t\t\tvariableOccurrence->occurrence() ?\n\t\t\t\t\t\t*variableOccurrence->occurrence() :\n\t\t\t\t\t\tvarDecl.location(),\n\t\t\t\t\tssl,\n\t\t\t\t\t\"This variable is of \" +\n\t\t\t\t\tstd::string(isStorage ? \"storage\" : \"calldata\") +\n\t\t\t\t\t\" pointer type and can be \" +\n\t\t\t\t\t(variableOccurrence->kind() == VariableOccurrence::Kind::Return ? \"returned\" : \"accessed\") +\n\t\t\t\t\t\" without prior assignment, which would lead to undefined behaviour.\"\n\t\t\t\t);\n\t\t\telse if (!_emptyBody && varDecl.name().empty())\n\t\t\t{\n\t\t\t\tif (!m_unassignedReturnVarsAlreadyWarnedFor.emplace(&varDecl).second)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t6321_error,\n\t\t\t\t\tvarDecl.location(),\n\t\t\t\t\t\"Unnamed return variable can remain unassigned\" +\n\t\t\t\t\t(\n\t\t\t\t\t\t_contractName.has_value() ?\n\t\t\t\t\t\t\" when the function is called when \\\"\" + _contractName.value() + \"\\\" is the most derived contract.\" :\n\t\t\t\t\t\t\".\"\n\t\t\t\t\t) +\n\t\t\t\t\t\" Add an explicit return with value to all non-reverting code paths or name the variable.\"\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid ControlFlowAnalyzer::checkUnreachable(CFGNode const* _entry, CFGNode const* _exit, CFGNode const* _revert, CFGNode const* _transactionReturn)\n{\n\t// collect all nodes reachable from the entry point\n\tstd::set<CFGNode const*> reachable = util::BreadthFirstSearch<CFGNode const*>{{_entry}}.run(\n\t\t[](CFGNode const* _node, auto&& _addChild) {\n\t\t\tfor (CFGNode const* exit: _node->exits)\n\t\t\t\t_addChild(exit);\n\t\t}\n\t).visited;\n\n\t// traverse all paths backwards from exit, revert and transaction return\n\t// and extract (valid) source locations of unreachable nodes into sorted set\n\tstd::set<SourceLocation> unreachable;\n\tutil::BreadthFirstSearch<CFGNode const*>{{_exit, _revert, _transactionReturn}}.run(\n\t\t[&](CFGNode const* _node, auto&& _addChild) {\n\t\t\tif (!reachable.count(_node) && _node->location.isValid())\n\t\t\t\tunreachable.insert(_node->location);\n\t\t\tfor (CFGNode const* entry: _node->entries)\n\t\t\t\t_addChild(entry);\n\t\t}\n\t);\n\n\tfor (auto it = unreachable.begin(); it != unreachable.end();)\n\t{\n\t\tSourceLocation location = *it++;\n\t\t// Extend the location, as long as the next location overlaps (unreachable is sorted).\n\t\tfor (; it != unreachable.end() && it->start <= location.end; ++it)\n\t\t\tlocation.end = std::max(location.end, it->end);\n\n\t\tif (m_unreachableLocationsAlreadyWarnedFor.emplace(location).second)\n\t\t\tm_errorReporter.warning(5740_error, location, \"Unreachable code.\");\n\t}\n}\n"
  },
  {
    "path": "libsolidity/analysis/ControlFlowAnalyzer.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/analysis/ControlFlowGraph.h>\n#include <liblangutil/ErrorReporter.h>\n#include <set>\n\nnamespace solidity::frontend\n{\n\nclass ControlFlowAnalyzer\n{\npublic:\n\texplicit ControlFlowAnalyzer(CFG const& _cfg, langutil::ErrorReporter& _errorReporter):\n\t\tm_cfg(_cfg), m_errorReporter(_errorReporter) {}\n\n\tbool run();\n\nprivate:\n\tvoid analyze(FunctionDefinition const& _function, ContractDefinition const* _contract, FunctionFlow const& _flow);\n\t/// Checks for uninitialized variable accesses in the control flow between @param _entry and @param _exit.\n\t/// @param _entry entry node\n\t/// @param _exit exit node\n\t/// @param _emptyBody whether the body of the function is empty (true) or not (false)\n\t/// @param _contractName name of the most derived contract, should be empty\n\t///        if the function is also defined in it\n\tvoid checkUninitializedAccess(CFGNode const* _entry, CFGNode const* _exit, bool _emptyBody, std::optional<std::string> _contractName = {});\n\t/// Checks for unreachable code, i.e. code ending in @param _exit, @param _revert or @param _transactionReturn\n\t/// that can not be reached from @param _entry.\n\tvoid checkUnreachable(CFGNode const* _entry, CFGNode const* _exit, CFGNode const* _revert, CFGNode const* _transactionReturn);\n\n\tCFG const& m_cfg;\n\tlangutil::ErrorReporter& m_errorReporter;\n\n\tstd::set<langutil::SourceLocation> m_unreachableLocationsAlreadyWarnedFor;\n\tstd::set<VariableDeclaration const*> m_unassignedReturnVarsAlreadyWarnedFor;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/ControlFlowBuilder.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/ControlFlowBuilder.h>\n#include <libsolidity/ast/ASTUtils.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n#include <libyul/backends/evm/EVMDialect.h>\n\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nControlFlowBuilder::ControlFlowBuilder(CFG::NodeContainer& _nodeContainer, FunctionFlow const& _functionFlow, ContractDefinition const* _contract):\n\tm_nodeContainer(_nodeContainer),\n\tm_currentNode(_functionFlow.entry),\n\tm_returnNode(_functionFlow.exit),\n\tm_revertNode(_functionFlow.revert),\n\tm_transactionReturnNode(_functionFlow.transactionReturn),\n\tm_contract(_contract)\n{\n}\n\n\nstd::unique_ptr<FunctionFlow> ControlFlowBuilder::createFunctionFlow(\n\tCFG::NodeContainer& _nodeContainer,\n\tFunctionDefinition const& _function,\n\tContractDefinition const* _contract\n)\n{\n\tauto functionFlow = std::make_unique<FunctionFlow>();\n\tfunctionFlow->entry = _nodeContainer.newNode();\n\tfunctionFlow->exit = _nodeContainer.newNode();\n\tfunctionFlow->revert = _nodeContainer.newNode();\n\tfunctionFlow->transactionReturn = _nodeContainer.newNode();\n\tControlFlowBuilder builder(_nodeContainer, *functionFlow, _contract);\n\tbuilder.appendControlFlow(_function);\n\n\treturn functionFlow;\n}\n\nbool ControlFlowBuilder::visit(BinaryOperation const& _operation)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\n\tswitch (_operation.getOperator())\n\t{\n\t\tcase Token::Or:\n\t\tcase Token::And:\n\t\t{\n\t\t\tvisitNode(_operation);\n\t\t\tsolAssert(*_operation.annotation().userDefinedFunction == nullptr);\n\t\t\tappendControlFlow(_operation.leftExpression());\n\n\t\t\tauto nodes = splitFlow<2>();\n\t\t\tnodes[0] = createFlow(nodes[0], _operation.rightExpression());\n\t\t\tmergeFlow(nodes, nodes[1]);\n\t\t\treturn false;\n\t\t}\n\t\tdefault:\n\t\t{\n\t\t\tif (*_operation.annotation().userDefinedFunction != nullptr)\n\t\t\t{\n\t\t\t\tvisitNode(_operation);\n\t\t\t\t_operation.leftExpression().accept(*this);\n\t\t\t\t_operation.rightExpression().accept(*this);\n\n\t\t\t\tm_currentNode->functionDefinition = *_operation.annotation().userDefinedFunction;\n\n\t\t\t\tauto nextNode = newLabel();\n\n\t\t\t\tconnect(m_currentNode, nextNode);\n\t\t\t\tm_currentNode = nextNode;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\treturn ASTConstVisitor::visit(_operation);\n}\n\nbool ControlFlowBuilder::visit(UnaryOperation const& _operation)\n{\n\tsolAssert(!!m_currentNode);\n\n\tif (*_operation.annotation().userDefinedFunction != nullptr)\n\t{\n\t\tvisitNode(_operation);\n\t\t_operation.subExpression().accept(*this);\n\t\tm_currentNode->functionDefinition = *_operation.annotation().userDefinedFunction;\n\n\t\tauto nextNode = newLabel();\n\n\t\tconnect(m_currentNode, nextNode);\n\t\tm_currentNode = nextNode;\n\t\treturn false;\n\t}\n\n\treturn ASTConstVisitor::visit(_operation);\n}\n\nbool ControlFlowBuilder::visit(Conditional const& _conditional)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tvisitNode(_conditional);\n\n\t_conditional.condition().accept(*this);\n\n\tauto nodes = splitFlow<2>();\n\n\tnodes[0] = createFlow(nodes[0], _conditional.trueExpression());\n\tnodes[1] = createFlow(nodes[1], _conditional.falseExpression());\n\n\tmergeFlow(nodes);\n\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(TryStatement const& _tryStatement)\n{\n\tappendControlFlow(_tryStatement.externalCall());\n\n\tauto nodes = splitFlow(_tryStatement.clauses().size());\n\tfor (size_t i = 0; i < _tryStatement.clauses().size(); ++i)\n\t\tnodes[i] = createFlow(nodes[i], _tryStatement.clauses()[i]->block());\n\tmergeFlow(nodes);\n\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(IfStatement const& _ifStatement)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tvisitNode(_ifStatement);\n\n\t_ifStatement.condition().accept(*this);\n\n\tauto nodes = splitFlow<2>();\n\tnodes[0] = createFlow(nodes[0], _ifStatement.trueStatement());\n\n\tif (_ifStatement.falseStatement())\n\t{\n\t\tnodes[1] = createFlow(nodes[1], *_ifStatement.falseStatement());\n\t\tmergeFlow(nodes);\n\t}\n\telse\n\t\tmergeFlow(nodes, nodes[1]);\n\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(ForStatement const& _forStatement)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tvisitNode(_forStatement);\n\n\tif (_forStatement.initializationExpression())\n\t\t_forStatement.initializationExpression()->accept(*this);\n\n\tauto condition = createLabelHere();\n\n\tif (_forStatement.condition())\n\t\tappendControlFlow(*_forStatement.condition());\n\n\tauto postPart = newLabel();\n\tauto nodes = splitFlow<2>();\n\tauto afterFor = nodes[1];\n\tm_currentNode = nodes[0];\n\n\t{\n\t\tBreakContinueScope scope(*this, afterFor, postPart);\n\t\tappendControlFlow(_forStatement.body());\n\t}\n\n\tplaceAndConnectLabel(postPart);\n\n\tif (auto expression = _forStatement.loopExpression())\n\t\tappendControlFlow(*expression);\n\n\tconnect(m_currentNode, condition);\n\tm_currentNode = afterFor;\n\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(WhileStatement const& _whileStatement)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tvisitNode(_whileStatement);\n\n\tif (_whileStatement.isDoWhile())\n\t{\n\t\tauto afterWhile = newLabel();\n\t\tauto whileBody = createLabelHere();\n\t\tauto condition = newLabel();\n\n\t\t{\n\t\t\tBreakContinueScope scope(*this, afterWhile, condition);\n\t\t\tappendControlFlow(_whileStatement.body());\n\t\t}\n\n\t\tplaceAndConnectLabel(condition);\n\t\tappendControlFlow(_whileStatement.condition());\n\n\t\tconnect(m_currentNode, whileBody);\n\t\tplaceAndConnectLabel(afterWhile);\n\t}\n\telse\n\t{\n\t\tauto whileCondition = createLabelHere();\n\n\t\tappendControlFlow(_whileStatement.condition());\n\n\t\tauto nodes = splitFlow<2>();\n\n\t\tauto whileBody = nodes[0];\n\t\tauto afterWhile = nodes[1];\n\n\t\tm_currentNode = whileBody;\n\t\t{\n\t\t\tBreakContinueScope scope(*this, afterWhile, whileCondition);\n\t\t\tappendControlFlow(_whileStatement.body());\n\t\t}\n\n\t\tconnect(m_currentNode, whileCondition);\n\n\t\tm_currentNode = afterWhile;\n\t}\n\n\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(Break const& _break)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tsolAssert(!!m_breakJump, \"\");\n\tvisitNode(_break);\n\tconnect(m_currentNode, m_breakJump);\n\tm_currentNode = newLabel();\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(Continue const& _continue)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tsolAssert(!!m_continueJump, \"\");\n\tvisitNode(_continue);\n\tconnect(m_currentNode, m_continueJump);\n\tm_currentNode = newLabel();\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(Throw const& _throw)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tsolAssert(!!m_revertNode, \"\");\n\tvisitNode(_throw);\n\tconnect(m_currentNode, m_revertNode);\n\tm_currentNode = newLabel();\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(RevertStatement const& _revert)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tsolAssert(!!m_revertNode, \"\");\n\tvisitNode(_revert);\n\tconnect(m_currentNode, m_revertNode);\n\tm_currentNode = newLabel();\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(PlaceholderStatement const&)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tsolAssert(!!m_placeholderEntry, \"\");\n\tsolAssert(!!m_placeholderExit, \"\");\n\n\tconnect(m_currentNode, m_placeholderEntry);\n\tm_currentNode = newLabel();\n\tconnect(m_placeholderExit, m_currentNode);\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(FunctionCall const& _functionCall)\n{\n\tsolAssert(!!m_revertNode, \"\");\n\tsolAssert(!!m_currentNode, \"\");\n\tsolAssert(!!_functionCall.expression().annotation().type, \"\");\n\n\tif (auto functionType = dynamic_cast<FunctionType const*>(_functionCall.expression().annotation().type))\n\t\tswitch (functionType->kind())\n\t\t{\n\t\t\tcase FunctionType::Kind::Revert:\n\t\t\t\tvisitNode(_functionCall);\n\t\t\t\t_functionCall.expression().accept(*this);\n\t\t\t\tASTNode::listAccept(_functionCall.arguments(), *this);\n\n\t\t\t\tconnect(m_currentNode, m_revertNode);\n\n\t\t\t\tm_currentNode = newLabel();\n\t\t\t\treturn false;\n\t\t\tcase FunctionType::Kind::Require:\n\t\t\tcase FunctionType::Kind::Assert:\n\t\t\t{\n\t\t\t\tvisitNode(_functionCall);\n\t\t\t\t_functionCall.expression().accept(*this);\n\t\t\t\tASTNode::listAccept(_functionCall.arguments(), *this);\n\n\t\t\t\tconnect(m_currentNode, m_revertNode);\n\n\t\t\t\tauto nextNode = newLabel();\n\n\t\t\t\tconnect(m_currentNode, nextNode);\n\t\t\t\tm_currentNode = nextNode;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tcase FunctionType::Kind::Internal:\n\t\t\t{\n\t\t\t\tvisitNode(_functionCall);\n\t\t\t\t_functionCall.expression().accept(*this);\n\t\t\t\tASTNode::listAccept(_functionCall.arguments(), *this);\n\n\t\t\t\tm_currentNode->functionDefinition = ASTNode::resolveFunctionCall(_functionCall, m_contract);\n\n\t\t\t\tauto nextNode = newLabel();\n\n\t\t\t\tconnect(m_currentNode, nextNode);\n\t\t\t\tm_currentNode = nextNode;\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\treturn ASTConstVisitor::visit(_functionCall);\n}\n\nbool ControlFlowBuilder::visit(ModifierInvocation const& _modifierInvocation)\n{\n\tsolAssert(m_contract, \"Free functions cannot have modifiers\");\n\n\tif (auto arguments = _modifierInvocation.arguments())\n\t\tfor (auto& argument: *arguments)\n\t\t\tappendControlFlow(*argument);\n\n\tauto modifierDefinition = dynamic_cast<ModifierDefinition const*>(\n\t\t_modifierInvocation.name().annotation().referencedDeclaration\n\t);\n\n\tif (!modifierDefinition)\n\t\treturn false;\n\n\tVirtualLookup const& requiredLookup = *_modifierInvocation.name().annotation().requiredLookup;\n\n\tif (requiredLookup == VirtualLookup::Virtual)\n\t\tmodifierDefinition = &modifierDefinition->resolveVirtual(*m_contract);\n\telse\n\t\tsolAssert(requiredLookup == VirtualLookup::Static);\n\n\tif (!modifierDefinition->isImplemented())\n\t\treturn false;\n\n\tsolAssert(!!m_returnNode, \"\");\n\n\tm_placeholderEntry = newLabel();\n\tm_placeholderExit = newLabel();\n\n\tappendControlFlow(*modifierDefinition);\n\tconnect(m_currentNode, m_returnNode);\n\n\tm_currentNode = m_placeholderEntry;\n\tm_returnNode = m_placeholderExit;\n\n\tm_placeholderEntry = nullptr;\n\tm_placeholderExit = nullptr;\n\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(FunctionDefinition const& _functionDefinition)\n{\n\tfor (auto const& parameter: _functionDefinition.parameters())\n\t\tappendControlFlow(*parameter);\n\n\tfor (auto const& returnParameter: _functionDefinition.returnParameters())\n\t{\n\t\tappendControlFlow(*returnParameter);\n\t\tm_returnNode->variableOccurrences.emplace_back(\n\t\t\t*returnParameter,\n\t\t\tVariableOccurrence::Kind::Return\n\t\t);\n\n\t}\n\n\tfor (auto const& modifierInvocation: _functionDefinition.modifiers())\n\t\tappendControlFlow(*modifierInvocation);\n\n\tappendControlFlow(_functionDefinition.body());\n\n\tconnect(m_currentNode, m_returnNode);\n\tm_currentNode = nullptr;\n\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(Return const& _return)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tsolAssert(!!m_returnNode, \"\");\n\tvisitNode(_return);\n\tif (_return.expression())\n\t{\n\t\tappendControlFlow(*_return.expression());\n\t\t// Returns with return expression are considered to be assignments to the return parameters.\n\t\tfor (auto returnParameter: _return.annotation().functionReturnParameters->parameters())\n\t\t\tm_currentNode->variableOccurrences.emplace_back(\n\t\t\t\t*returnParameter,\n\t\t\t\tVariableOccurrence::Kind::Assignment,\n\t\t\t\t_return.location()\n\t\t\t);\n\t}\n\tconnect(m_currentNode, m_returnNode);\n\tm_currentNode = newLabel();\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(FunctionTypeName const& _functionTypeName)\n{\n\tvisitNode(_functionTypeName);\n\t// Do not visit the parameters and return values of a function type name.\n\t// We do not want to consider them as variable declarations for the control flow graph.\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(InlineAssembly const& _inlineAssembly)\n{\n\tsolAssert(!!m_currentNode && !m_inlineAssembly, \"\");\n\n\tm_inlineAssembly = &_inlineAssembly;\n\t(*this)(_inlineAssembly.operations().root());\n\tm_inlineAssembly = nullptr;\n\n\treturn false;\n}\n\nvoid ControlFlowBuilder::visit(yul::Statement const& _statement)\n{\n\tsolAssert(m_currentNode && m_inlineAssembly, \"\");\n\tsolAssert(nativeLocationOf(_statement) == originLocationOf(_statement), \"\");\n\tm_currentNode->location = langutil::SourceLocation::smallestCovering(m_currentNode->location, nativeLocationOf(_statement));\n\tASTWalker::visit(_statement);\n}\n\nvoid ControlFlowBuilder::operator()(yul::If const& _if)\n{\n\tsolAssert(m_currentNode && m_inlineAssembly, \"\");\n\tvisit(*_if.condition);\n\n\tauto nodes = splitFlow<2>();\n\tm_currentNode = nodes[0];\n\t(*this)(_if.body);\n\tnodes[0] = m_currentNode;\n\tmergeFlow(nodes, nodes[1]);\n}\n\nvoid ControlFlowBuilder::operator()(yul::Switch const& _switch)\n{\n\tsolAssert(m_currentNode && m_inlineAssembly, \"\");\n\tvisit(*_switch.expression);\n\n\tauto beforeSwitch = m_currentNode;\n\n\tauto nodes = splitFlow(_switch.cases.size());\n\tfor (size_t i = 0u; i < _switch.cases.size(); ++i)\n\t{\n\t\tm_currentNode = nodes[i];\n\t\t(*this)(_switch.cases[i].body);\n\t\tnodes[i] = m_currentNode;\n\t}\n\tmergeFlow(nodes);\n\n\tif (!hasDefaultCase(_switch))\n\t\tconnect(beforeSwitch, m_currentNode);\n}\n\nvoid ControlFlowBuilder::operator()(yul::ForLoop const& _forLoop)\n{\n\tsolAssert(m_currentNode && m_inlineAssembly, \"\");\n\n\t(*this)(_forLoop.pre);\n\n\tauto condition = createLabelHere();\n\n\tif (_forLoop.condition)\n\t\tvisit(*_forLoop.condition);\n\n\tauto loopExpression = newLabel();\n\tauto nodes = splitFlow<2>();\n\tauto afterFor = nodes[1];\n\tm_currentNode = nodes[0];\n\n\t{\n\t\tBreakContinueScope scope(*this, afterFor, loopExpression);\n\t\t(*this)(_forLoop.body);\n\t}\n\n\tplaceAndConnectLabel(loopExpression);\n\n\t(*this)(_forLoop.post);\n\n\tconnect(m_currentNode, condition);\n\tm_currentNode = afterFor;\n}\n\nvoid ControlFlowBuilder::operator()(yul::Break const&)\n{\n\tsolAssert(m_currentNode && m_inlineAssembly, \"\");\n\tsolAssert(m_breakJump, \"\");\n\tconnect(m_currentNode, m_breakJump);\n\tm_currentNode = newLabel();\n}\n\nvoid ControlFlowBuilder::operator()(yul::Continue const&)\n{\n\tsolAssert(m_currentNode && m_inlineAssembly, \"\");\n\tsolAssert(m_continueJump, \"\");\n\tconnect(m_currentNode, m_continueJump);\n\tm_currentNode = newLabel();\n}\n\nvoid ControlFlowBuilder::operator()(yul::Identifier const& _identifier)\n{\n\tsolAssert(m_currentNode && m_inlineAssembly, \"\");\n\tauto const& externalReferences = m_inlineAssembly->annotation().externalReferences;\n\tif (externalReferences.count(&_identifier))\n\t\tif (auto const* declaration = dynamic_cast<VariableDeclaration const*>(externalReferences.at(&_identifier).declaration))\n\t\t{\n\t\t\tsolAssert(nativeLocationOf(_identifier) == originLocationOf(_identifier), \"\");\n\t\t\tm_currentNode->variableOccurrences.emplace_back(\n\t\t\t\t*declaration,\n\t\t\t\tVariableOccurrence::Kind::Access,\n\t\t\t\tnativeLocationOf(_identifier)\n\t\t\t);\n\t\t}\n}\n\nvoid ControlFlowBuilder::operator()(yul::Assignment const& _assignment)\n{\n\tsolAssert(m_currentNode && m_inlineAssembly, \"\");\n\tvisit(*_assignment.value);\n\tauto const& externalReferences = m_inlineAssembly->annotation().externalReferences;\n\tfor (auto const& variable: _assignment.variableNames)\n\t\tif (externalReferences.count(&variable))\n\t\t\tif (auto const* declaration = dynamic_cast<VariableDeclaration const*>(externalReferences.at(&variable).declaration))\n\t\t\t{\n\t\t\t\tsolAssert(nativeLocationOf(variable) == originLocationOf(variable), \"\");\n\t\t\t\tm_currentNode->variableOccurrences.emplace_back(\n\t\t\t\t\t*declaration,\n\t\t\t\t\tVariableOccurrence::Kind::Assignment,\n\t\t\t\t\tnativeLocationOf(variable)\n\t\t\t\t);\n\t\t\t}\n}\n\nvoid ControlFlowBuilder::operator()(yul::FunctionCall const& _functionCall)\n{\n\tusing namespace yul;\n\tsolAssert(m_currentNode && m_inlineAssembly, \"\");\n\tyul::ASTWalker::operator()(_functionCall);\n\n\tif (auto const* builtinFunction = resolveBuiltinFunction(_functionCall.functionName, m_inlineAssembly->dialect()))\n\t{\n\t\tif (builtinFunction->controlFlowSideEffects.canTerminate)\n\t\t\tconnect(m_currentNode, m_transactionReturnNode);\n\t\tif (builtinFunction->controlFlowSideEffects.canRevert)\n\t\t\tconnect(m_currentNode, m_revertNode);\n\t\tif (!builtinFunction->controlFlowSideEffects.canContinue)\n\t\t\tm_currentNode = newLabel();\n\t}\n}\n\nvoid ControlFlowBuilder::operator()(yul::FunctionDefinition const&)\n{\n\tsolAssert(m_currentNode && m_inlineAssembly, \"\");\n\t// External references cannot be accessed from within functions, so we can ignore their control flow.\n\t// TODO: we might still want to track if they always revert or return, though.\n}\n\nvoid ControlFlowBuilder::operator()(yul::Leave const&)\n{\n\t// This has to be implemented, if we ever decide to visit functions.\n\tsolUnimplemented(\"\");\n}\n\nbool ControlFlowBuilder::visit(VariableDeclaration const& _variableDeclaration)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tvisitNode(_variableDeclaration);\n\n\tm_currentNode->variableOccurrences.emplace_back(\n\t\t_variableDeclaration,\n\t\tVariableOccurrence::Kind::Declaration\n\t);\n\n\t// Handle declaration with immediate assignment.\n\tif (_variableDeclaration.value())\n\t\tm_currentNode->variableOccurrences.emplace_back(\n\t\t\t_variableDeclaration,\n\t\t\tVariableOccurrence::Kind::Assignment,\n\t\t\t_variableDeclaration.value()->location()\n\t\t);\n\t// Function arguments are considered to be immediately assigned as well (they are \"externally assigned\").\n\telse if (_variableDeclaration.isCallableOrCatchParameter() && !_variableDeclaration.isReturnParameter())\n\t\tm_currentNode->variableOccurrences.emplace_back(\n\t\t\t_variableDeclaration,\n\t\t\tVariableOccurrence::Kind::Assignment\n\t\t);\n\treturn true;\n}\n\nbool ControlFlowBuilder::visit(VariableDeclarationStatement const& _variableDeclarationStatement)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tvisitNode(_variableDeclarationStatement);\n\n\tfor (auto const& var: _variableDeclarationStatement.declarations())\n\t\tif (var)\n\t\t\tvar->accept(*this);\n\tif (_variableDeclarationStatement.initialValue())\n\t{\n\t\t_variableDeclarationStatement.initialValue()->accept(*this);\n\t\tfor (size_t i = 0; i < _variableDeclarationStatement.declarations().size(); i++)\n\t\t\tif (auto const& var = _variableDeclarationStatement.declarations()[i])\n\t\t\t{\n\t\t\t\tauto expression = _variableDeclarationStatement.initialValue();\n\t\t\t\tif (auto tupleExpression = dynamic_cast<TupleExpression const*>(expression))\n\t\t\t\t\tif (tupleExpression->components().size() > 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(tupleExpression->components().size() > i, \"\");\n\t\t\t\t\t\texpression = tupleExpression->components()[i].get();\n\t\t\t\t\t}\n\t\t\t\texpression = resolveOuterUnaryTuples(expression);\n\t\t\t\tm_currentNode->variableOccurrences.emplace_back(\n\t\t\t\t\t*var,\n\t\t\t\t\tVariableOccurrence::Kind::Assignment,\n\t\t\t\t\texpression ? std::make_optional(expression->location()) : std::optional<langutil::SourceLocation>{}\n\t\t\t\t);\n\t\t\t}\n\t}\n\treturn false;\n}\n\nbool ControlFlowBuilder::visit(Identifier const& _identifier)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tvisitNode(_identifier);\n\n\tif (auto const* variableDeclaration = dynamic_cast<VariableDeclaration const*>(_identifier.annotation().referencedDeclaration))\n\t\tm_currentNode->variableOccurrences.emplace_back(\n\t\t\t*variableDeclaration,\n\t\t\tstatic_cast<Expression const&>(_identifier).annotation().willBeWrittenTo ?\n\t\t\tVariableOccurrence::Kind::Assignment :\n\t\t\tVariableOccurrence::Kind::Access,\n\t\t\t_identifier.location()\n\t\t);\n\n\treturn true;\n}\n\nbool ControlFlowBuilder::visitNode(ASTNode const& _node)\n{\n\tsolAssert(!!m_currentNode, \"\");\n\tm_currentNode->location = langutil::SourceLocation::smallestCovering(m_currentNode->location, _node.location());\n\treturn true;\n}\n\nvoid ControlFlowBuilder::appendControlFlow(ASTNode const& _node)\n{\n\t_node.accept(*this);\n}\n\nCFGNode* ControlFlowBuilder::createFlow(CFGNode* _entry, ASTNode const& _node)\n{\n\tauto oldCurrentNode = m_currentNode;\n\tm_currentNode = _entry;\n\tappendControlFlow(_node);\n\tauto endNode = m_currentNode;\n\tm_currentNode = oldCurrentNode;\n\treturn endNode;\n}\n\nvoid ControlFlowBuilder::connect(CFGNode* _from, CFGNode* _to)\n{\n\tsolAssert(_from, \"\");\n\tsolAssert(_to, \"\");\n\t_from->exits.push_back(_to);\n\t_to->entries.push_back(_from);\n}\n\nCFGNode* ControlFlowBuilder::newLabel()\n{\n\treturn m_nodeContainer.newNode();\n}\n\nCFGNode* ControlFlowBuilder::createLabelHere()\n{\n\tauto label = m_nodeContainer.newNode();\n\tconnect(m_currentNode, label);\n\tm_currentNode = label;\n\treturn label;\n}\n\nvoid ControlFlowBuilder::placeAndConnectLabel(CFGNode* _node)\n{\n\tconnect(m_currentNode, _node);\n\tm_currentNode = _node;\n}\n\nControlFlowBuilder::BreakContinueScope::BreakContinueScope(\n\tControlFlowBuilder& _parser,\n\tCFGNode* _breakJump,\n\tCFGNode* _continueJump\n): m_parser(_parser), m_origBreakJump(_parser.m_breakJump), m_origContinueJump(_parser.m_continueJump)\n{\n\tm_parser.m_breakJump = _breakJump;\n\tm_parser.m_continueJump = _continueJump;\n}\n\nControlFlowBuilder::BreakContinueScope::~BreakContinueScope()\n{\n\tm_parser.m_breakJump = m_origBreakJump;\n\tm_parser.m_continueJump = m_origContinueJump;\n}\n"
  },
  {
    "path": "libsolidity/analysis/ControlFlowBuilder.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/analysis/ControlFlowGraph.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libyul/optimiser/ASTWalker.h>\n\n#include <array>\n#include <memory>\n\nnamespace solidity::frontend\n{\n\n/**\n * Helper class that builds the control flow of a function or modifier.\n */\nclass ControlFlowBuilder: private ASTConstVisitor, private yul::ASTWalker\n{\npublic:\n\tstatic std::unique_ptr<FunctionFlow> createFunctionFlow(\n\t\tCFG::NodeContainer& _nodeContainer,\n\t\tFunctionDefinition const& _function,\n\t\tContractDefinition const* _contract\n\t);\n\nprivate:\n\texplicit ControlFlowBuilder(\n\t\tCFG::NodeContainer& _nodeContainer,\n\t\tFunctionFlow const& _functionFlow,\n\t\tContractDefinition const* _contract\n\t);\n\n\t// Visits for constructing the control flow.\n\tbool visit(BinaryOperation const& _operation) override;\n\tbool visit(UnaryOperation const& _operation) override;\n\tbool visit(Conditional const& _conditional) override;\n\tbool visit(TryStatement const& _tryStatement) override;\n\tbool visit(IfStatement const& _ifStatement) override;\n\tbool visit(ForStatement const& _forStatement) override;\n\tbool visit(WhileStatement const& _whileStatement) override;\n\tbool visit(Break const&) override;\n\tbool visit(Continue const&) override;\n\tbool visit(Throw const&) override;\n\tbool visit(RevertStatement const&) override;\n\tbool visit(PlaceholderStatement const&) override;\n\tbool visit(FunctionCall const& _functionCall) override;\n\tbool visit(ModifierInvocation const& _modifierInvocation) override;\n\n\t// Visits for constructing the control flow as well as filling variable occurrences.\n\tbool visit(FunctionDefinition const& _functionDefinition) override;\n\tbool visit(Return const& _return) override;\n\n\t// Visits for filling variable occurrences.\n\tbool visit(FunctionTypeName const& _functionTypeName) override;\n\tbool visit(InlineAssembly const& _inlineAssembly) override;\n\tvoid visit(yul::Statement const& _statement) override;\n\tvoid operator()(yul::If const& _if) override;\n\tvoid operator()(yul::Switch const& _switch) override;\n\tvoid operator()(yul::ForLoop const& _for) override;\n\tvoid operator()(yul::Break const&) override;\n\tvoid operator()(yul::Continue const&) override;\n\tvoid operator()(yul::Identifier const& _identifier) override;\n\tvoid operator()(yul::Assignment const& _assignment) override;\n\tvoid operator()(yul::FunctionCall const& _functionCall) override;\n\tvoid operator()(yul::FunctionDefinition const& _functionDefinition) override;\n\tvoid operator()(yul::Leave const& _leaveStatement) override;\n\tbool visit(VariableDeclaration const& _variableDeclaration) override;\n\tbool visit(VariableDeclarationStatement const& _variableDeclarationStatement) override;\n\tbool visit(Identifier const& _identifier) override;\n\nprotected:\n\tbool visitNode(ASTNode const&) override;\n\nprivate:\n\tusing ASTConstVisitor::visit;\n\tusing yul::ASTWalker::visit;\n\tusing yul::ASTWalker::operator();\n\n\t/// Appends the control flow of @a _node to the current control flow.\n\tvoid appendControlFlow(ASTNode const& _node);\n\n\t/// Starts at @a _entry and parses the control flow of @a _node.\n\t/// @returns The node at which the parsed control flow ends.\n\t/// m_currentNode is not affected (it is saved and restored).\n\tCFGNode* createFlow(CFGNode* _entry, ASTNode const& _node);\n\n\t/// Creates an arc from @a _from to @a _to.\n\tstatic void connect(CFGNode* _from, CFGNode* _to);\n\n\t/// Splits the control flow starting at the current node into n paths.\n\t/// m_currentNode is set to nullptr and has to be set manually or\n\t/// using mergeFlow later.\n\ttemplate<size_t n>\n\tstd::array<CFGNode*, n> splitFlow()\n\t{\n\t\tstd::array<CFGNode*, n> result;\n\t\tfor (auto& node: result)\n\t\t{\n\t\t\tnode = m_nodeContainer.newNode();\n\t\t\tconnect(m_currentNode, node);\n\t\t}\n\t\tm_currentNode = nullptr;\n\t\treturn result;\n\t}\n\n\t/// Splits the control flow starting at the current node into @a _n paths.\n\t/// m_currentNode is set to nullptr and has to be set manually or\n\t/// using mergeFlow later.\n\tstd::vector<CFGNode*> splitFlow(size_t n)\n\t{\n\t\tstd::vector<CFGNode*> result(n);\n\t\tfor (auto& node: result)\n\t\t{\n\t\t\tnode = m_nodeContainer.newNode();\n\t\t\tconnect(m_currentNode, node);\n\t\t}\n\t\tm_currentNode = nullptr;\n\t\treturn result;\n\t}\n\n\t/// Merges the control flow of @a _nodes to @a _endNode.\n\t/// If @a _endNode is nullptr, a new node is created and used as end node.\n\t/// Sets the merge destination as current node.\n\t/// Note: @a _endNode may be one of the nodes in @a _nodes.\n\ttemplate<typename C>\n\tvoid mergeFlow(C const& _nodes, CFGNode* _endNode = nullptr)\n\t{\n\t\tCFGNode* mergeDestination = (_endNode == nullptr) ? m_nodeContainer.newNode() : _endNode;\n\t\tfor (auto& node: _nodes)\n\t\t\tif (node != mergeDestination)\n\t\t\t\tconnect(node, mergeDestination);\n\t\tm_currentNode = mergeDestination;\n\t}\n\n\tCFGNode* newLabel();\n\tCFGNode* createLabelHere();\n\tvoid placeAndConnectLabel(CFGNode* _node);\n\n\tCFG::NodeContainer& m_nodeContainer;\n\n\tCFGNode* m_currentNode = nullptr;\n\tCFGNode* m_returnNode = nullptr;\n\tCFGNode* m_revertNode = nullptr;\n\tCFGNode* m_transactionReturnNode = nullptr;\n\n\tContractDefinition const* m_contract = nullptr;\n\n\t/// The current jump destination of break Statements.\n\tCFGNode* m_breakJump = nullptr;\n\t/// The current jump destination of continue Statements.\n\tCFGNode* m_continueJump = nullptr;\n\n\tCFGNode* m_placeholderEntry = nullptr;\n\tCFGNode* m_placeholderExit = nullptr;\n\n\tInlineAssembly const* m_inlineAssembly = nullptr;\n\n\t/// Helper class that replaces the break and continue jump destinations for the\n\t/// current scope and restores the originals at the end of the scope.\n\tclass BreakContinueScope\n\t{\n\tpublic:\n\t\tBreakContinueScope(ControlFlowBuilder& _parser, CFGNode* _breakJump, CFGNode* _continueJump);\n\t\t~BreakContinueScope();\n\tprivate:\n\t\tControlFlowBuilder& m_parser;\n\t\tCFGNode* m_origBreakJump;\n\t\tCFGNode* m_origContinueJump;\n\t};\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/ControlFlowGraph.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/ControlFlowGraph.h>\n\n#include <libsolidity/analysis/ControlFlowBuilder.h>\n\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nbool CFG::constructFlow(ASTNode const& _astRoot)\n{\n\t_astRoot.accept(*this);\n\treturn !Error::containsErrors(m_errorReporter.errors());\n}\n\n\nbool CFG::visit(FunctionDefinition const& _function)\n{\n\tif (_function.isImplemented() && _function.isFree())\n\t\tm_functionControlFlow[{nullptr, &_function}] = ControlFlowBuilder::createFunctionFlow(\n\t\t\tm_nodeContainer,\n\t\t\t_function,\n\t\t\tnullptr /* _contract */\n\t\t);\n\treturn false;\n}\n\nbool CFG::visit(ContractDefinition const& _contract)\n{\n\tfor (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts)\n\t\tfor (FunctionDefinition const* function: contract->definedFunctions())\n\t\t\tif (function->isImplemented())\n\t\t\t\tm_functionControlFlow[{&_contract, function}] =\n\t\t\t\t\tControlFlowBuilder::createFunctionFlow(m_nodeContainer, *function, &_contract);\n\n\treturn true;\n}\n\nFunctionFlow const& CFG::functionFlow(FunctionDefinition const& _function, ContractDefinition const* _contract) const\n{\n\treturn *m_functionControlFlow.at({_contract, &_function});\n}\n\nCFGNode* CFG::NodeContainer::newNode()\n{\n\tm_nodes.emplace_back(std::make_unique<CFGNode>());\n\treturn m_nodes.back().get();\n}\n"
  },
  {
    "path": "libsolidity/analysis/ControlFlowGraph.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/EVMVersion.h>\n#include <liblangutil/SourceLocation.h>\n\n#include <map>\n#include <memory>\n#include <stack>\n#include <utility>\n#include <vector>\n\nnamespace solidity::frontend\n{\n\n/**\n * Occurrence of a variable in a block of control flow.\n * Stores the declaration of the referenced variable, the\n * kind of the occurrence and possibly the source location\n * at which it occurred.\n */\nclass VariableOccurrence\n{\npublic:\n\tenum class Kind\n\t{\n\t\tDeclaration,\n\t\tAccess,\n\t\tReturn,\n\t\tAssignment,\n\t\tInlineAssembly\n\t};\n\tVariableOccurrence(VariableDeclaration const& _declaration, Kind _kind, std::optional<langutil::SourceLocation>  _occurrence = {}):\n\t\tm_declaration(_declaration), m_occurrenceKind(_kind), m_occurrence(std::move(_occurrence))\n\t{\n\t}\n\n\t/// Defines a deterministic order on variable occurrences.\n\tbool operator<(VariableOccurrence const& _rhs) const\n\t{\n\t\tif (m_occurrence && _rhs.m_occurrence)\n\t\t{\n\t\t\tif (*m_occurrence < *_rhs.m_occurrence) return true;\n\t\t\tif (*_rhs.m_occurrence < *m_occurrence) return false;\n\t\t}\n\t\telse if (_rhs.m_occurrence)\n\t\t\treturn true;\n\t\telse if (m_occurrence)\n\t\t\treturn false;\n\n\t\tusing KindCompareType = std::underlying_type<VariableOccurrence::Kind>::type;\n\t\treturn\n\t\t\tstd::make_pair(m_declaration.id(), static_cast<KindCompareType>(m_occurrenceKind)) <\n\t\t\tstd::make_pair(_rhs.m_declaration.id(), static_cast<KindCompareType>(_rhs.m_occurrenceKind));\n\t}\n\n\tVariableDeclaration const& declaration() const { return m_declaration; }\n\tKind kind() const { return m_occurrenceKind; }\n\tstd::optional<langutil::SourceLocation> const& occurrence() const { return m_occurrence; }\nprivate:\n\t/// Declaration of the occurring variable.\n\tVariableDeclaration const& m_declaration;\n\t/// Kind of occurrence.\n\tKind m_occurrenceKind = Kind::Access;\n\t/// Source location at which the variable occurred, if available (may be nullptr).\n\tstd::optional<langutil::SourceLocation> m_occurrence;\n};\n\n/**\n * Node of the Control Flow Graph.\n * The control flow is a directed graph connecting control flow blocks.\n * An arc between two nodes indicates that the control flow can possibly\n * move from its start node to its end node during execution.\n */\nstruct CFGNode\n{\n\t/// Entry nodes. All CFG nodes from which control flow may move into this node.\n\tstd::vector<CFGNode*> entries;\n\t/// Exit nodes. All CFG nodes to which control flow may continue after this node.\n\tstd::vector<CFGNode*> exits;\n\t/// Resolved definition of the function called by this node\n\tFunctionDefinition const* functionDefinition = nullptr;\n\t/// Variable occurrences in the node.\n\tstd::vector<VariableOccurrence> variableOccurrences;\n\t// Source location of this control flow block.\n\tlangutil::SourceLocation location;\n};\n\n/** Describes the control flow of a function. */\nstruct FunctionFlow\n{\n\tvirtual ~FunctionFlow() = default;\n\n\t/// Entry node. Control flow of the function starts here.\n\t/// This node is empty and does not have any entries.\n\tCFGNode* entry = nullptr;\n\t/// Exit node. All non-reverting control flow of the function ends here.\n\t/// This node is empty and does not have any exits, but may have multiple entries\n\t/// (e.g. all return statements of the function).\n\tCFGNode* exit = nullptr;\n\t/// Revert node. Control flow of the function in case of revert.\n\t/// This node is empty and does not have any exits, but may have multiple entries\n\t/// (e.g. all assert, require, revert and throw statements).\n\tCFGNode* revert = nullptr;\n\t/// Transaction return node. Destination node for inline assembly \"return\" calls.\n\t/// This node is empty and does not have any exits, but may have multiple entries\n\t/// (e.g. all inline assembly return calls).\n\tCFGNode* transactionReturn = nullptr;\n};\n\nclass CFG: private ASTConstVisitor\n{\npublic:\n\tstruct FunctionContractTuple\n\t{\n\t\tContractDefinition const* contract = nullptr;\n\t\tFunctionDefinition const* function = nullptr;\n\n\t\t// Use AST ids for comparison to keep a deterministic order in the\n\t\t// containers using this struct\n\t\tbool operator<(FunctionContractTuple const& _other) const\n\t\t{\n\t\t\treturn\n\t\t\t\tstd::make_pair(contract ? contract->id() : -1, function->id()) <\n\t\t\t\tstd::make_pair(_other.contract ? _other.contract->id() : -1, _other.function->id());\n\t\t}\n\t};\n\texplicit CFG(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}\n\n\tbool constructFlow(ASTNode const& _astRoot);\n\n\tbool visit(FunctionDefinition const& _function) override;\n\tbool visit(ContractDefinition const& _contract) override;\n\n\t/// Get the function flow for the given function, using `_contract` as the\n\t/// most derived contract\n\t/// @param _function function to find the function flow for\n\t/// @param _contract most derived contract or nullptr for free functions\n\tFunctionFlow const& functionFlow(FunctionDefinition const& _function, ContractDefinition const* _contract = nullptr) const;\n\n\tstd::map<FunctionContractTuple, std::unique_ptr<FunctionFlow>> const& allFunctionFlows() const\n\t{\n\t\treturn m_functionControlFlow;\n\t}\n\n\tclass NodeContainer\n\t{\n\tpublic:\n\t\tCFGNode* newNode();\n\tprivate:\n\t\tstd::vector<std::unique_ptr<CFGNode>> m_nodes;\n\t};\nprivate:\n\tlangutil::ErrorReporter& m_errorReporter;\n\n\t/// Node container.\n\t/// All nodes allocated during the construction of the control flow graph\n\t/// are owned by the CFG class and stored in this container.\n\tNodeContainer m_nodeContainer;\n\n\tstd::map<FunctionContractTuple, std::unique_ptr<FunctionFlow>> m_functionControlFlow;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/ControlFlowRevertPruner.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/ControlFlowRevertPruner.h>\n\n#include <libsolutil/Algorithms.h>\n\n#include <range/v3/algorithm/remove.hpp>\n\n\nnamespace solidity::frontend\n{\n\nnamespace\n{\n\n/// Find the right scope for the called function: When calling a base function,\n/// we keep the most derived, but we use the called contract in case it is a\n/// library function or nullptr for a free function.\nContractDefinition const* findScopeContract(FunctionDefinition const& _function, ContractDefinition const* _callingContract)\n{\n\tif (auto const* functionContract = _function.annotation().contract)\n\t{\n\t\tif (_callingContract && _callingContract->derivesFrom(*functionContract))\n\t\t\treturn _callingContract;\n\t\telse\n\t\t\treturn functionContract;\n\t}\n\n\treturn nullptr;\n}\n}\n\nvoid ControlFlowRevertPruner::run()\n{\n\tfor (auto& [pair, flow]: m_cfg.allFunctionFlows())\n\t\tm_functions[pair] = RevertState::Unknown;\n\n\tfindRevertStates();\n\tmodifyFunctionFlows();\n}\n\nvoid ControlFlowRevertPruner::findRevertStates()\n{\n\tstd::set<CFG::FunctionContractTuple> pendingFunctions = util::keys(m_functions);\n\t// We interrupt the search whenever we encounter a call to a function with (yet) unknown\n\t// revert behaviour. The ``wakeUp`` data structure contains information about which\n\t// searches to restart once we know about the behaviour.\n\tstd::map<CFG::FunctionContractTuple, std::set<CFG::FunctionContractTuple>> wakeUp;\n\n\twhile (!pendingFunctions.empty())\n\t{\n\t\tCFG::FunctionContractTuple item = *pendingFunctions.begin();\n\t\tpendingFunctions.erase(pendingFunctions.begin());\n\n\t\tif (m_functions[item] != RevertState::Unknown)\n\t\t\tcontinue;\n\n\t\tbool foundExit = false;\n\t\tbool foundUnknown = false;\n\n\t\tFunctionFlow const& functionFlow = m_cfg.functionFlow(*item.function, item.contract);\n\n\t\tsolidity::util::BreadthFirstSearch<CFGNode*>{{functionFlow.entry}}.run(\n\t\t\t[&](CFGNode* _node, auto&& _addChild) {\n\t\t\t\tif (_node == functionFlow.exit)\n\t\t\t\t\tfoundExit = true;\n\n\t\t\t\tauto const* resolvedFunction = _node->functionDefinition;\n\t\t\t\tif (resolvedFunction && resolvedFunction->isImplemented())\n\t\t\t\t{\n\t\t\t\t\tCFG::FunctionContractTuple calledFunctionTuple{\n\t\t\t\t\t\tfindScopeContract(*resolvedFunction, item.contract),\n\t\t\t\t\t\tresolvedFunction\n\t\t\t\t\t};\n\t\t\t\t\tswitch (m_functions.at(calledFunctionTuple))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase RevertState::Unknown:\n\t\t\t\t\t\t\twakeUp[calledFunctionTuple].insert(item);\n\t\t\t\t\t\t\tfoundUnknown = true;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\tcase RevertState::AllPathsRevert:\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\tcase RevertState::HasNonRevertingPath:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (CFGNode* exit: _node->exits)\n\t\t\t\t\t_addChild(exit);\n\t\t\t}\n\t\t);\n\n\t\tauto& revertState = m_functions[item];\n\n\t\tif (foundExit)\n\t\t\trevertState = RevertState::HasNonRevertingPath;\n\t\telse if (!foundUnknown)\n\t\t\trevertState = RevertState::AllPathsRevert;\n\n\t\tif (revertState != RevertState::Unknown && wakeUp.count(item))\n\t\t{\n\t\t\t// Restart all searches blocked by this function.\n\t\t\tfor (CFG::FunctionContractTuple const& nextItem: wakeUp[item])\n\t\t\t\tif (m_functions.at(nextItem) == RevertState::Unknown)\n\t\t\t\t\tpendingFunctions.insert(nextItem);\n\t\t\twakeUp.erase(item);\n\t\t}\n\t}\n}\n\nvoid ControlFlowRevertPruner::modifyFunctionFlows()\n{\n\tfor (auto& item: m_functions)\n\t{\n\t\tFunctionFlow const& functionFlow = m_cfg.functionFlow(*item.first.function, item.first.contract);\n\t\tsolidity::util::BreadthFirstSearch<CFGNode*>{{functionFlow.entry}}.run(\n\t\t\t[&](CFGNode* _node, auto&& _addChild) {\n\t\t\t\tauto const* resolvedFunction = _node->functionDefinition;\n\t\t\t\tif (resolvedFunction && resolvedFunction->isImplemented())\n\t\t\t\t\tswitch (m_functions.at({findScopeContract(*resolvedFunction, item.first.contract), resolvedFunction}))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase RevertState::Unknown:\n\t\t\t\t\t\t\t[[fallthrough]];\n\t\t\t\t\t\tcase RevertState::AllPathsRevert:\n\t\t\t\t\t\t\t// If the revert states of the functions do not\n\t\t\t\t\t\t\t// change anymore, we treat all \"unknown\" states as\n\t\t\t\t\t\t\t// \"reverting\", since they can only be caused by\n\t\t\t\t\t\t\t// recursion.\n\t\t\t\t\t\t\tfor (CFGNode * node: _node->exits)\n\t\t\t\t\t\t\t\tranges::remove(node->entries, _node);\n\n\t\t\t\t\t\t\t_node->exits = {functionFlow.revert};\n\t\t\t\t\t\t\tfunctionFlow.revert->entries.push_back(_node);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\tfor (CFGNode* exit: _node->exits)\n\t\t\t\t\t_addChild(exit);\n\t\t});\n\t}\n}\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/ControlFlowRevertPruner.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/analysis/ControlFlowGraph.h>\n\n#include <libsolutil/Algorithms.h>\n\nnamespace solidity::frontend\n{\n\n/**\n * Analyses all function flows and recursively removes all exit edges from CFG\n * nodes that make function calls that will always revert.\n */\nclass ControlFlowRevertPruner\n{\npublic:\n\tControlFlowRevertPruner(CFG& _cfg): m_cfg(_cfg) {}\n\n\tvoid run();\nprivate:\n\t/// Possible revert states of a function call\n\tenum class RevertState\n\t{\n\t\tAllPathsRevert,\n\t\tHasNonRevertingPath,\n\t\tUnknown,\n\t};\n\n\t/// Identify revert states of all function flows\n\tvoid findRevertStates();\n\n\t/// Modify function flows so that edges with reverting function calls are removed\n\tvoid modifyFunctionFlows();\n\n\t/// Control Flow Graph object.\n\tCFG& m_cfg;\n\n\t/// function/contract pairs mapped to their according revert state\n\tstd::map<CFG::FunctionContractTuple, RevertState> m_functions;\n\n\tstd::map<\n\t\tstd::tuple<FunctionCall const*, ContractDefinition const*>,\n\t\tFunctionDefinition const*\n\t> m_resolveCache;\n\n};\n}\n"
  },
  {
    "path": "libsolidity/analysis/DeclarationContainer.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Scope - object that holds declaration of names.\n */\n\n#include <libsolidity/analysis/DeclarationContainer.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolutil/StringUtils.h>\n\n#include <range/v3/view/filter.hpp>\n#include <range/v3/range/conversion.hpp>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\n\nDeclaration const* DeclarationContainer::conflictingDeclaration(\n\tDeclaration const& _declaration,\n\tASTString const* _name\n) const\n{\n\tif (!_name)\n\t\t_name = &_declaration.name();\n\tsolAssert(!_name->empty(), \"\");\n\tstd::vector<Declaration const*> declarations;\n\tif (m_declarations.count(*_name))\n\t\tdeclarations += m_declarations.at(*_name);\n\tif (m_invisibleDeclarations.count(*_name))\n\t\tdeclarations += m_invisibleDeclarations.at(*_name);\n\n\tif (\n\t\tdynamic_cast<FunctionDefinition const*>(&_declaration) ||\n\t\tdynamic_cast<EventDefinition const*>(&_declaration) ||\n\t\tdynamic_cast<MagicVariableDeclaration const*>(&_declaration)\n\t)\n\t{\n\t\t// check that all other declarations are of the same kind (in which\n\t\t// case the type checker will ensure that the signatures are different)\n\t\tfor (Declaration const* declaration: declarations)\n\t\t{\n\t\t\tif (\n\t\t\t\tdynamic_cast<FunctionDefinition const*>(&_declaration) &&\n\t\t\t\t!dynamic_cast<FunctionDefinition const*>(declaration)\n\t\t\t)\n\t\t\t\treturn declaration;\n\t\t\tif (\n\t\t\t\tdynamic_cast<EventDefinition const*>(&_declaration) &&\n\t\t\t\t!dynamic_cast<EventDefinition const*>(declaration)\n\t\t\t)\n\t\t\t\treturn declaration;\n\t\t\tif (\n\t\t\t\tdynamic_cast<MagicVariableDeclaration const*>(&_declaration) &&\n\t\t\t\t!dynamic_cast<MagicVariableDeclaration const*>(declaration)\n\t\t\t)\n\t\t\t\treturn declaration;\n\t\t\t// Or, continue.\n\t\t}\n\t}\n\telse if (declarations.size() == 1 && declarations.front() == &_declaration)\n\t\treturn nullptr;\n\telse if (!declarations.empty())\n\t\treturn declarations.front();\n\n\treturn nullptr;\n}\n\nvoid DeclarationContainer::activateVariable(ASTString const& _name)\n{\n\tsolAssert(\n\t\tm_invisibleDeclarations.count(_name) && m_invisibleDeclarations.at(_name).size() == 1,\n\t\t\"Tried to activate a non-inactive variable or multiple inactive variables with the same name.\"\n\t);\n\tsolAssert(m_declarations.count(_name) == 0 || m_declarations.at(_name).empty(), \"\");\n\tm_declarations[_name].emplace_back(m_invisibleDeclarations.at(_name).front());\n\tm_invisibleDeclarations.erase(_name);\n}\n\nbool DeclarationContainer::isInvisible(ASTString const& _name) const\n{\n\treturn m_invisibleDeclarations.count(_name);\n}\n\nbool DeclarationContainer::registerDeclaration(\n\tDeclaration const& _declaration,\n\tASTString const* _name,\n\tlangutil::SourceLocation const* _location,\n\tbool _invisible,\n\tbool _update\n)\n{\n\tif (!_name)\n\t\t_name = &_declaration.name();\n\tif (_name->empty())\n\t\treturn true;\n\n\tif (_update)\n\t{\n\t\tsolAssert(!dynamic_cast<FunctionDefinition const*>(&_declaration), \"Attempt to update function definition.\");\n\t\tm_declarations.erase(*_name);\n\t\tm_invisibleDeclarations.erase(*_name);\n\t}\n\telse\n\t{\n\t\tif (conflictingDeclaration(_declaration, _name))\n\t\t\treturn false;\n\n\t\tif (m_enclosingContainer && _declaration.isVisibleAsUnqualifiedName())\n\t\t\tm_homonymCandidates.emplace_back(*_name, _location ? _location : &_declaration.location());\n\t}\n\n\tstd::vector<Declaration const*>& decls = _invisible ? m_invisibleDeclarations[*_name] : m_declarations[*_name];\n\tif (!util::contains(decls, &_declaration))\n\t\tdecls.push_back(&_declaration);\n\treturn true;\n}\n\nbool DeclarationContainer::registerDeclaration(\n\tDeclaration const& _declaration,\n\tbool _invisible,\n\tbool _update\n)\n{\n\treturn registerDeclaration(_declaration, nullptr, nullptr, _invisible, _update);\n}\n\nstd::vector<Declaration const*> DeclarationContainer::resolveName(\n\tASTString const& _name,\n\tResolvingSettings _settings\n) const\n{\n\tsolAssert(!_name.empty(), \"Attempt to resolve empty name.\");\n\tstd::vector<Declaration const*> result;\n\n\tif (m_declarations.count(_name))\n\t{\n\t\tif (_settings.onlyVisibleAsUnqualifiedNames)\n\t\t\tresult += m_declarations.at(_name) | ranges::views::filter(&Declaration::isVisibleAsUnqualifiedName) | ranges::to_vector;\n\t\telse\n\t\t\tresult += m_declarations.at(_name);\n\t}\n\n\tif (_settings.alsoInvisible && m_invisibleDeclarations.count(_name))\n\t{\n\t\tif (_settings.onlyVisibleAsUnqualifiedNames)\n\t\t\tresult += m_invisibleDeclarations.at(_name) | ranges::views::filter(&Declaration::isVisibleAsUnqualifiedName) | ranges::to_vector;\n\t\telse\n\t\t\tresult += m_invisibleDeclarations.at(_name);\n\t}\n\n\tif (result.empty() && _settings.recursive && m_enclosingContainer)\n\t\tresult = m_enclosingContainer->resolveName(_name, _settings);\n\n\treturn result;\n}\n\nstd::vector<ASTString> DeclarationContainer::similarNames(ASTString const& _name) const\n{\n\n\t// because the function below has quadratic runtime - it will not magically improve once a better algorithm is discovered ;)\n\t// since 80 is the suggested line length limit, we use 80^2 as length threshold\n\tstatic size_t const MAXIMUM_LENGTH_THRESHOLD = 80 * 80;\n\n\tstd::vector<ASTString> similar;\n\tsize_t maximumEditDistance = _name.size() > 3 ? 2 : _name.size() / 2;\n\tfor (auto const& declaration: m_declarations)\n\t{\n\t\tstd::string const& declarationName = declaration.first;\n\t\tif (util::stringWithinDistance(_name, declarationName, maximumEditDistance, MAXIMUM_LENGTH_THRESHOLD))\n\t\t\tsimilar.push_back(declarationName);\n\t}\n\tfor (auto const& declaration: m_invisibleDeclarations)\n\t{\n\t\tstd::string const& declarationName = declaration.first;\n\t\tif (util::stringWithinDistance(_name, declarationName, maximumEditDistance, MAXIMUM_LENGTH_THRESHOLD))\n\t\t\tsimilar.push_back(declarationName);\n\t}\n\n\tif (m_enclosingContainer)\n\t\tsimilar += m_enclosingContainer->similarNames(_name);\n\n\treturn similar;\n}\n\nvoid DeclarationContainer::populateHomonyms(std::back_insert_iterator<Homonyms> _it) const\n{\n\tfor (DeclarationContainer const* innerContainer: m_innerContainers)\n\t\tinnerContainer->populateHomonyms(_it);\n\n\tfor (auto [name, location]: m_homonymCandidates)\n\t{\n\t\tResolvingSettings settings;\n\t\tsettings.recursive = true;\n\t\tsettings.alsoInvisible = true;\n\t\tstd::vector<Declaration const*> const& declarations = m_enclosingContainer->resolveName(name, std::move(settings));\n\t\tif (!declarations.empty())\n\t\t\t_it = make_pair(location, declarations);\n\t}\n}\n"
  },
  {
    "path": "libsolidity/analysis/DeclarationContainer.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Scope - object that holds declaration of names.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTForward.h>\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/SourceLocation.h>\n\n#include <memory>\n\nnamespace solidity::frontend\n{\n\n/**\n * Settings for how the function DeclarationContainer::resolveName operates.\n */\nstruct ResolvingSettings\n{\n\t/// if true and there are no matching declarations in the current container,\n\t/// recursively searches the enclosing containers as well.\n\tbool recursive = false;\n\t/// if true, include invisible declaration in the results.\n\tbool alsoInvisible = false;\n\t/// if true, do not include declarations which can never actually be referenced using their\n\t/// name alone (without being qualified with the name of scope in which they are declared).\n\tbool onlyVisibleAsUnqualifiedNames = false;\n};\n\n\n/**\n * Container that stores mappings between names and declarations. It also contains a link to the\n * enclosing scope.\n */\nclass DeclarationContainer\n{\npublic:\n\tusing Homonyms = std::vector<std::pair<langutil::SourceLocation const*, std::vector<Declaration const*>>>;\n\n\tDeclarationContainer() = default;\n\texplicit DeclarationContainer(ASTNode const* _enclosingNode, DeclarationContainer* _enclosingContainer):\n\t\tm_enclosingNode(_enclosingNode),\n\t\tm_enclosingContainer(_enclosingContainer)\n\t{\n\t\tif (_enclosingContainer)\n\t\t\t_enclosingContainer->m_innerContainers.emplace_back(this);\n\t}\n\t/// Registers the declaration in the scope unless its name is already declared or the name is empty.\n\t/// @param _name the name to register, if nullptr the intrinsic name of @a _declaration is used.\n\t/// @param _location alternative location, used to point at homonymous declarations.\n\t/// @param _invisible if true, registers the declaration, reports name clashes but does not return it in @a resolveName.\n\t/// @param _update if true, replaces a potential declaration that is already present.\n\t/// @returns false if the name was already declared.\n\tbool registerDeclaration(Declaration const& _declaration, ASTString const* _name, langutil::SourceLocation const* _location, bool _invisible, bool _update);\n\tbool registerDeclaration(Declaration const& _declaration, bool _invisible, bool _update);\n\n\t/// Finds all declarations that in the current scope can be referred to using specified name.\n\t/// @param _name the name to look for.\n\t/// @param _settings see ResolvingSettings\n\tstd::vector<Declaration const*> resolveName(ASTString const& _name, ResolvingSettings _settings = ResolvingSettings{}) const;\n\tASTNode const* enclosingNode() const { return m_enclosingNode; }\n\tDeclarationContainer const* enclosingContainer() const { return m_enclosingContainer; }\n\tstd::map<ASTString, std::vector<Declaration const*>> const& declarations() const { return m_declarations; }\n\t/// @returns whether declaration is valid, and if not also returns previous declaration.\n\tDeclaration const* conflictingDeclaration(Declaration const& _declaration, ASTString const* _name = nullptr) const;\n\n\t/// Activates a previously inactive (invisible) variable. To be used in C99 scoping for\n\t/// VariableDeclarationStatements.\n\tvoid activateVariable(ASTString const& _name);\n\n\t/// @returns true if declaration is currently invisible.\n\tbool isInvisible(ASTString const& _name) const;\n\n\t/// @returns existing declaration names similar to @a _name.\n\t/// Searches this and all parent containers.\n\tstd::vector<ASTString> similarNames(ASTString const& _name) const;\n\n\t/// Populates a vector of (location, declaration) pairs, where location is a location of an inner-scope declaration,\n\t/// and declaration is the corresponding homonymous outer-scope declaration.\n\tvoid populateHomonyms(std::back_insert_iterator<Homonyms> _it) const;\n\nprivate:\n\tASTNode const* m_enclosingNode = nullptr;\n\tDeclarationContainer const* m_enclosingContainer = nullptr;\n\tstd::vector<DeclarationContainer const*> m_innerContainers;\n\tstd::map<ASTString, std::vector<Declaration const*>> m_declarations;\n\tstd::map<ASTString, std::vector<Declaration const*>> m_invisibleDeclarations;\n\t/// List of declarations (name and location) to check later for homonymity.\n\tstd::vector<std::pair<std::string, langutil::SourceLocation const*>> m_homonymCandidates;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/DeclarationTypeChecker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/DeclarationTypeChecker.h>\n\n#include <libsolidity/analysis/ConstantEvaluator.h>\n\n#include <libsolidity/ast/TypeProvider.h>\n\n#include <liblangutil/ErrorReporter.h>\n\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/view/transform.hpp>\n\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nbool DeclarationTypeChecker::visit(ElementaryTypeName const& _typeName)\n{\n\tif (_typeName.annotation().type)\n\t\treturn false;\n\n\t_typeName.annotation().type = TypeProvider::fromElementaryTypeName(_typeName.typeName());\n\tif (_typeName.stateMutability().has_value())\n\t{\n\t\t// for non-address types this was already caught by the parser\n\t\tsolAssert(_typeName.annotation().type->category() == Type::Category::Address, \"\");\n\t\tswitch (*_typeName.stateMutability())\n\t\t{\n\t\t\tcase StateMutability::Payable:\n\t\t\t\t_typeName.annotation().type = TypeProvider::payableAddress();\n\t\t\t\tbreak;\n\t\t\tcase StateMutability::NonPayable:\n\t\t\t\t_typeName.annotation().type = TypeProvider::address();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t2311_error,\n\t\t\t\t\t_typeName.location(),\n\t\t\t\t\t\"Address types can only be payable or non-payable.\"\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\treturn true;\n}\n\nbool DeclarationTypeChecker::visit(EnumDefinition const& _enum)\n{\n\tif (_enum.members().size() > 256)\n\t\tm_errorReporter.declarationError(\n\t\t\t1611_error,\n\t\t\t_enum.location(),\n\t\t\t\"Enum with more than 256 members is not allowed.\"\n\t\t);\n\n\treturn false;\n}\n\nbool DeclarationTypeChecker::visit(StructDefinition const& _struct)\n{\n\tif (_struct.annotation().recursive.has_value())\n\t{\n\t\tif (!m_currentStructsSeen.empty() && *_struct.annotation().recursive)\n\t\t\tm_recursiveStructSeen = true;\n\t\treturn false;\n\t}\n\n\tif (m_currentStructsSeen.count(&_struct))\n\t{\n\t\t_struct.annotation().recursive = true;\n\t\tm_recursiveStructSeen = true;\n\t\treturn false;\n\t}\n\n\tbool previousRecursiveStructSeen = m_recursiveStructSeen;\n\tbool hasRecursiveChild = false;\n\n\tm_currentStructsSeen.insert(&_struct);\n\n\tfor (auto const& member: _struct.members())\n\t{\n\t\tm_recursiveStructSeen = false;\n\t\tmember->accept(*this);\n\t\tsolAssert(member->annotation().type, \"\");\n\t\tif (m_recursiveStructSeen)\n\t\t\thasRecursiveChild = true;\n\t}\n\n\tif (!_struct.annotation().recursive.has_value())\n\t\t_struct.annotation().recursive = hasRecursiveChild;\n\tm_recursiveStructSeen = previousRecursiveStructSeen || *_struct.annotation().recursive;\n\tm_currentStructsSeen.erase(&_struct);\n\tif (m_currentStructsSeen.empty())\n\t\tm_recursiveStructSeen = false;\n\n\t// Check direct recursion, fatal error if detected.\n\tauto visitor = [&](StructDefinition const& _struct, auto& _cycleDetector, size_t _depth)\n\t{\n\t\tif (_depth >= 256)\n\t\t\tm_errorReporter.fatalDeclarationError(\n\t\t\t\t5651_error,\n\t\t\t\t_struct.location(),\n\t\t\t\t\"Struct definition exhausts cyclic dependency validator.\"\n\t\t\t);\n\n\t\tfor (ASTPointer<VariableDeclaration> const& member: _struct.members())\n\t\t{\n\t\t\tType const* memberType = member->annotation().type;\n\n\t\t\tif (auto arrayType = dynamic_cast<ArrayType const*>(memberType))\n\t\t\t\tmemberType = arrayType->finalBaseType(true);\n\n\t\t\tif (auto structType = dynamic_cast<StructType const*>(memberType))\n\t\t\t\tif (_cycleDetector.run(structType->structDefinition()))\n\t\t\t\t\treturn;\n\t\t}\n\t};\n\tif (util::CycleDetector<StructDefinition>(visitor).run(_struct))\n\t\tm_errorReporter.fatalTypeError(2046_error, _struct.location(), \"Recursive struct definition.\");\n\n\treturn false;\n}\n\nvoid DeclarationTypeChecker::endVisit(UserDefinedValueTypeDefinition const& _userDefined)\n{\n\tTypeName const* typeName = _userDefined.underlyingType();\n\tsolAssert(typeName, \"\");\n\tif (!dynamic_cast<ElementaryTypeName const*>(typeName))\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t8657_error,\n\t\t\ttypeName->location(),\n\t\t\t\"The underlying type for a user defined value type has to be an elementary value type.\"\n\t\t);\n\n\tType const* type = typeName->annotation().type;\n\tsolAssert(type, \"\");\n\tsolAssert(!dynamic_cast<UserDefinedValueType const*>(type), \"\");\n\tif (!type->isValueType())\n\t\tm_errorReporter.typeError(\n\t\t\t8129_error,\n\t\t\t_userDefined.location(),\n\t\t\t\"The underlying type of the user defined value type \\\"\" +\n\t\t\t_userDefined.name() +\n\t\t\t\"\\\" is not a value type.\"\n\t\t);\n}\n\nvoid DeclarationTypeChecker::endVisit(UserDefinedTypeName const& _typeName)\n{\n\tif (_typeName.annotation().type)\n\t\treturn;\n\n\tDeclaration const* declaration = _typeName.pathNode().annotation().referencedDeclaration;\n\tsolAssert(declaration, \"\");\n\n\tif (StructDefinition const* structDef = dynamic_cast<StructDefinition const*>(declaration))\n\t{\n\t\tif (!m_insideFunctionType && !m_currentStructsSeen.empty())\n\t\t\tstructDef->accept(*this);\n\t\t_typeName.annotation().type = TypeProvider::structType(*structDef, DataLocation::Storage);\n\t}\n\telse if (EnumDefinition const* enumDef = dynamic_cast<EnumDefinition const*>(declaration))\n\t\t_typeName.annotation().type = TypeProvider::enumType(*enumDef);\n\telse if (ContractDefinition const* contract = dynamic_cast<ContractDefinition const*>(declaration))\n\t\t_typeName.annotation().type = TypeProvider::contract(*contract);\n\telse if (auto userDefinedValueType = dynamic_cast<UserDefinedValueTypeDefinition const*>(declaration))\n\t\t_typeName.annotation().type = TypeProvider::userDefinedValueType(*userDefinedValueType);\n\telse\n\t{\n\t\t_typeName.annotation().type = TypeProvider::emptyTuple();\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t5172_error,\n\t\t\t_typeName.location(),\n\t\t\t\"Name has to refer to a user-defined type.\"\n\t\t);\n\t}\n}\n\nvoid DeclarationTypeChecker::endVisit(IdentifierPath const& _path)\n{\n\tDeclaration const* declaration = _path.annotation().referencedDeclaration;\n\tsolAssert(declaration, \"\");\n\n\tif (ContractDefinition const* contract = dynamic_cast<ContractDefinition const*>(declaration))\n\t\tif (contract->isLibrary())\n\t\t\tm_errorReporter.typeError(1130_error, _path.location(), \"Invalid use of a library name.\");\n}\n\nbool DeclarationTypeChecker::visit(FunctionTypeName const& _typeName)\n{\n\tif (_typeName.annotation().type)\n\t\treturn false;\n\n\tbool previousInsideFunctionType = m_insideFunctionType;\n\tm_insideFunctionType = true;\n\t_typeName.parameterTypeList()->accept(*this);\n\t_typeName.returnParameterTypeList()->accept(*this);\n\tm_insideFunctionType = previousInsideFunctionType;\n\n\tswitch (_typeName.visibility())\n\t{\n\t\tcase Visibility::Internal:\n\t\tcase Visibility::External:\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t6012_error,\n\t\t\t\t_typeName.location(),\n\t\t\t\t\"Invalid visibility, can only be \\\"external\\\" or \\\"internal\\\".\"\n\t\t\t);\n\t\t\treturn false;\n\t}\n\n\tif (_typeName.isPayable() && _typeName.visibility() != Visibility::External)\n\t{\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t7415_error,\n\t\t\t_typeName.location(),\n\t\t\t\"Only external function types can be payable.\"\n\t\t);\n\t\treturn false;\n\t}\n\t_typeName.annotation().type = TypeProvider::function(_typeName);\n\treturn false;\n}\n\nvoid DeclarationTypeChecker::endVisit(Mapping const& _mapping)\n{\n\tif (_mapping.annotation().type)\n\t\treturn;\n\n\tif (auto const* typeName = dynamic_cast<UserDefinedTypeName const*>(&_mapping.keyType()))\n\t\tswitch (typeName->annotation().type->category())\n\t\t{\n\t\t\tcase Type::Category::Enum:\n\t\t\tcase Type::Category::Contract:\n\t\t\tcase Type::Category::UserDefinedValueType:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t\t7804_error,\n\t\t\t\t\ttypeName->location(),\n\t\t\t\t\t\"Only elementary types, user defined value types, contract types or enums are allowed as mapping keys.\"\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\telse\n\t\tsolAssert(dynamic_cast<ElementaryTypeName const*>(&_mapping.keyType()), \"\");\n\n\tType const* keyType = _mapping.keyType().annotation().type;\n\tASTString keyName = _mapping.keyName();\n\n\tType const* valueType = _mapping.valueType().annotation().type;\n\tASTString valueName = _mapping.valueName();\n\n\t// Convert key type to memory.\n\tkeyType = TypeProvider::withLocationIfReference(DataLocation::Memory, keyType);\n\n\t// Convert value type to storage reference.\n\tvalueType = TypeProvider::withLocationIfReference(DataLocation::Storage, valueType);\n\t_mapping.annotation().type = TypeProvider::mapping(keyType, keyName, valueType, valueName);\n\n\t// Check if parameter names are conflicting.\n\tif (!keyName.empty())\n\t{\n\t\tauto childMappingType = dynamic_cast<MappingType const*>(valueType);\n\t\tASTString currentValueName = valueName;\n\t\tbool loop = true;\n\t\twhile (loop)\n\t\t{\n\t\t\tbool isError = false;\n\t\t\t// Value type is a mapping.\n\t\t\tif (childMappingType)\n\t\t\t{\n\t\t\t\t// Compare top mapping's key name with child mapping's key name.\n\t\t\t\tASTString childKeyName = childMappingType->keyName();\n\t\t\t\tif (keyName == childKeyName)\n\t\t\t\t\tisError = true;\n\n\t\t\t\tauto valueType = childMappingType->valueType();\n\t\t\t\tcurrentValueName = childMappingType->valueName();\n\t\t\t\tchildMappingType = dynamic_cast<MappingType const*>(valueType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Compare top mapping's key name with the value name.\n\t\t\t\tif (keyName == currentValueName)\n\t\t\t\t\tisError = true;\n\n\t\t\t\tloop = false; // We arrived at the end of mapping recursion.\n\t\t\t}\n\n\t\t\t// Report error.\n\t\t\tif (isError)\n\t\t\t{\n\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t1809_error,\n\t\t\t\t\t_mapping.location(),\n\t\t\t\t\t\"Conflicting parameter name \\\"\" + keyName + \"\\\" in mapping.\"\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid DeclarationTypeChecker::endVisit(ArrayTypeName const& _typeName)\n{\n\tif (_typeName.annotation().type)\n\t\treturn;\n\n\tType const* baseType = _typeName.baseType().annotation().type;\n\tif (!baseType)\n\t{\n\t\tsolAssert(m_errorReporter.hasErrors(), \"\");\n\t\treturn;\n\t}\n\n\tif (Expression const* length = _typeName.length())\n\t{\n\t\tstd::optional<rational> lengthValue;\n\t\tif (length->annotation().type && length->annotation().type->category() == Type::Category::RationalNumber)\n\t\t\tlengthValue = dynamic_cast<RationalNumberType const&>(*length->annotation().type).value();\n\t\telse if (ConstantEvaluator::TypedValue value = ConstantEvaluator::evaluate(m_errorReporter, *length);\n\t\t\tstd::holds_alternative<rational>(value.value)\n\t\t)\n\t\t\tlengthValue = std::get<rational>(value.value);\n\n\t\tif (!lengthValue)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t5462_error,\n\t\t\t\tlength->location(),\n\t\t\t\t\"Invalid array length, expected integer literal or constant expression.\"\n\t\t\t);\n\t\telse if (*lengthValue == 0)\n\t\t\tm_errorReporter.typeError(1406_error, length->location(), \"Array with zero length specified.\");\n\t\telse if (lengthValue->denominator() != 1)\n\t\t\tm_errorReporter.typeError(3208_error, length->location(), \"Array with fractional length specified.\");\n\t\telse if (*lengthValue < 0)\n\t\t\tm_errorReporter.typeError(3658_error, length->location(), \"Array with negative length specified.\");\n\t\telse if (lengthValue > TypeProvider::uint256()->max())\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t1847_error,\n\t\t\t\tlength->location(),\n\t\t\t\t\"Array length too large, maximum is 2**256 - 1.\"\n\t\t\t);\n\n\t\t_typeName.annotation().type = TypeProvider::array(\n\t\t\tDataLocation::Storage,\n\t\t\tbaseType,\n\t\t\tlengthValue ? u256(lengthValue->numerator()) : u256(0)\n\t\t);\n\t}\n\telse\n\t\t_typeName.annotation().type = TypeProvider::array(DataLocation::Storage, baseType);\n}\n\nvoid DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)\n{\n\tif (_variable.annotation().type)\n\t\treturn;\n\n\tif (_variable.isFileLevelVariable() && !_variable.isConstant())\n\t\tm_errorReporter.declarationError(\n\t\t\t8342_error,\n\t\t\t_variable.location(),\n\t\t\t\"Only constant variables are allowed at file level.\"\n\t\t);\n\tif (_variable.isConstant() && (!_variable.isStateVariable() && !_variable.isFileLevelVariable()))\n\t\tm_errorReporter.declarationError(\n\t\t\t1788_error,\n\t\t\t_variable.location(),\n\t\t\t\"The \\\"constant\\\" keyword can only be used for state variables or variables at file level.\"\n\t\t);\n\tif (_variable.immutable() && !_variable.isStateVariable())\n\t\tm_errorReporter.declarationError(\n\t\t\t8297_error,\n\t\t\t_variable.location(),\n\t\t\t\"The \\\"immutable\\\" keyword can only be used for state variables.\"\n\t\t);\n\n\tusing Location = VariableDeclaration::Location;\n\tLocation varLoc = _variable.referenceLocation();\n\tDataLocation typeLoc = DataLocation::Memory;\n\n\tif (varLoc == VariableDeclaration::Location::Transient && !m_evmVersion.supportsTransientStorage())\n\t\tm_errorReporter.declarationError(\n\t\t\t7985_error,\n\t\t\t_variable.location(),\n\t\t\t\"Transient storage is not supported by EVM versions older than cancun.\"\n\t\t);\n\n\tstd::set<Location> allowedDataLocations = _variable.allowedDataLocations();\n\tif (!allowedDataLocations.count(varLoc))\n\t{\n\t\tauto locationToString = [](VariableDeclaration::Location _location) -> std::string\n\t\t{\n\t\t\tswitch (_location)\n\t\t\t{\n\t\t\t\tcase Location::Memory: return \"\\\"memory\\\"\";\n\t\t\t\tcase Location::Storage: return \"\\\"storage\\\"\";\n\t\t\t\tcase Location::Transient: return \"\\\"transient\\\"\";\n\t\t\t\tcase Location::CallData: return \"\\\"calldata\\\"\";\n\t\t\t\tcase Location::Unspecified: return \"none\";\n\t\t\t}\n\t\t\treturn {};\n\t\t};\n\n\t\tstd::string errorString;\n\t\tif (!_variable.hasReferenceOrMappingType())\n\t\t\terrorString = \"Data location can only be specified for array, struct or mapping types\";\n\t\telse\n\t\t{\n\t\t\terrorString = \"Data location must be \" +\n\t\t\t\tutil::joinHumanReadable(\n\t\t\t\t\tallowedDataLocations | ranges::views::transform(locationToString),\n\t\t\t\t\t\", \",\n\t\t\t\t\t\" or \"\n\t\t\t\t);\n\t\t\tif (_variable.isConstructorParameter())\n\t\t\t\terrorString += \" for constructor parameter\";\n\t\t\telse if (_variable.isCallableOrCatchParameter())\n\t\t\t\terrorString +=\n\t\t\t\t\t\" for \" +\n\t\t\t\t\tstd::string(_variable.isReturnParameter() ? \"return \" : \"\") +\n\t\t\t\t\t\"parameter in\" +\n\t\t\t\t\tstd::string(_variable.isExternalCallableParameter() ? \" external\" : \"\") +\n\t\t\t\t\t\" function\";\n\t\t\telse\n\t\t\t\terrorString += \" for variable\";\n\t\t}\n\t\terrorString += \", but \" + locationToString(varLoc) + \" was given.\";\n\t\tm_errorReporter.typeError(6651_error, _variable.location(), errorString);\n\n\t\tsolAssert(!allowedDataLocations.empty(), \"\");\n\t\tvarLoc = *allowedDataLocations.begin();\n\t}\n\n\t// Find correct data location.\n\tif (_variable.isEventOrErrorParameter())\n\t{\n\t\tsolAssert(varLoc == Location::Unspecified, \"\");\n\t\ttypeLoc = DataLocation::Memory;\n\t}\n\telse if (_variable.isFileLevelVariable())\n\t{\n\t\tsolAssert(varLoc == Location::Unspecified, \"\");\n\t\ttypeLoc = DataLocation::Memory;\n\t}\n\telse if (_variable.isStateVariable())\n\t{\n\t\tswitch (varLoc)\n\t\t{\n\t\t\tcase Location::Unspecified:\n\t\t\t\ttypeLoc = (_variable.isConstant() || _variable.immutable()) ? DataLocation::Memory : DataLocation::Storage;\n\t\t\t\tbreak;\n\t\t\tcase Location::Transient:\n\t\t\t\tif (_variable.isConstant() || _variable.immutable())\n\t\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t\t2197_error,\n\t\t\t\t\t\t_variable.location(),\n\t\t\t\t\t\t\"Transient cannot be used as data location for constant or immutable variables.\"\n\t\t\t\t\t);\n\n\t\t\t\tif (_variable.value())\n\t\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t\t9825_error,\n\t\t\t\t\t\t_variable.location(),\n\t\t\t\t\t\t\"Initialization of transient storage state variables is not supported.\"\n\t\t\t\t\t);\n\n\t\t\t\ttypeLoc = DataLocation::Transient;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tsolAssert(false);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\telse if (\n\t\tdynamic_cast<StructDefinition const*>(_variable.scope()) ||\n\t\tdynamic_cast<EnumDefinition const*>(_variable.scope())\n\t)\n\t\t// The actual location will later be changed depending on how the type is used.\n\t\ttypeLoc = DataLocation::Storage;\n\telse\n\t\tswitch (varLoc)\n\t\t{\n\t\t\tcase Location::Memory:\n\t\t\t\ttypeLoc = DataLocation::Memory;\n\t\t\t\tbreak;\n\t\t\tcase Location::Storage:\n\t\t\t\ttypeLoc = DataLocation::Storage;\n\t\t\t\tbreak;\n\t\t\tcase Location::CallData:\n\t\t\t\ttypeLoc = DataLocation::CallData;\n\t\t\t\tbreak;\n\t\t\tcase Location::Transient:\n\t\t\t\tsolUnimplemented(\"Transient data location cannot be used in this kind of variable or parameter declaration.\");\n\t\t\t\tbreak;\n\t\t\tcase Location::Unspecified:\n\t\t\t\tsolAssert(!_variable.hasReferenceOrMappingType(), \"Data location not properly set.\");\n\t\t}\n\n\tType const* type = _variable.typeName().annotation().type;\n\tif (auto ref = dynamic_cast<ReferenceType const*>(type))\n\t{\n\t\tbool isPointer = !_variable.isStateVariable();\n\t\ttype = TypeProvider::withLocation(ref, typeLoc, isPointer);\n\t}\n\n\tif (_variable.isConstant() && !type->isValueType())\n\t{\n\t\tbool allowed = false;\n\t\tif (auto arrayType = dynamic_cast<ArrayType const*>(type))\n\t\t\tallowed = arrayType->isByteArrayOrString();\n\t\tif (!allowed)\n\t\t\tm_errorReporter.fatalTypeError(9259_error, _variable.location(), \"Only constants of value type and byte array type are implemented.\");\n\t}\n\n\tif (!type->isValueType())\n\t\tsolUnimplementedAssert(typeLoc != DataLocation::Transient, \"Transient data location is only supported for value types.\");\n\n\t_variable.annotation().type = type;\n}\n\nbool DeclarationTypeChecker::visit(UsingForDirective const& _usingFor)\n{\n\tif (_usingFor.usesBraces())\n\t{\n\t\tfor (ASTPointer<IdentifierPath> const& function: _usingFor.functionsOrLibrary())\n\t\t\tif (auto functionDefinition = dynamic_cast<FunctionDefinition const*>(function->annotation().referencedDeclaration))\n\t\t\t{\n\t\t\t\tif (!functionDefinition->isFree() && !(\n\t\t\t\t\tdynamic_cast<ContractDefinition const*>(functionDefinition->scope()) &&\n\t\t\t\t\tdynamic_cast<ContractDefinition const*>(functionDefinition->scope())->isLibrary()\n\t\t\t\t))\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t4167_error,\n\t\t\t\t\t\tfunction->location(),\n\t\t\t\t\t\t\"Only file-level functions and library functions can be attached to a type in a \\\"using\\\" statement\"\n\t\t\t\t\t);\n\t\t\t}\n\t\t\telse\n\t\t\t\tm_errorReporter.fatalTypeError(8187_error, function->location(), \"Expected function name.\" );\n\t}\n\telse\n\t{\n\t\tContractDefinition const* library = dynamic_cast<ContractDefinition const*>(\n\t\t\t_usingFor.functionsOrLibrary().front()->annotation().referencedDeclaration\n\t\t);\n\t\tif (!library || !library->isLibrary())\n\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t4357_error,\n\t\t\t\t_usingFor.functionsOrLibrary().front()->location(),\n\t\t\t\t\"Library name expected. If you want to attach a function, use '{...}'.\"\n\t\t\t);\n\t}\n\n\t// We do not visit _usingFor.functions() because it will lead to an error since\n\t// library names cannot be mentioned stand-alone.\n\n\tif (_usingFor.typeName())\n\t\t_usingFor.typeName()->accept(*this);\n\n\treturn false;\n}\n\nbool DeclarationTypeChecker::visit(InheritanceSpecifier const& _inheritanceSpecifier)\n{\n\tauto const* contract = dynamic_cast<ContractDefinition const*>(_inheritanceSpecifier.name().annotation().referencedDeclaration);\n\tsolAssert(contract, \"\");\n\tif (contract->isLibrary())\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t2571_error,\n\t\t\t_inheritanceSpecifier.name().location(),\n\t\t\t\"Libraries cannot be inherited from.\"\n\t\t);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nbool DeclarationTypeChecker::check(ASTNode const& _node)\n{\n\tauto watcher = m_errorReporter.errorWatcher();\n\t_node.accept(*this);\n\treturn watcher.ok();\n}\n"
  },
  {
    "path": "libsolidity/analysis/DeclarationTypeChecker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <list>\n#include <map>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend\n{\n\n/**\n * Assigns types to declarations.\n */\nclass DeclarationTypeChecker: private ASTConstVisitor\n{\npublic:\n\tDeclarationTypeChecker(\n\t\tlangutil::ErrorReporter& _errorReporter,\n\t\tlangutil::EVMVersion _evmVersion\n\t):\n\t\tm_errorReporter(_errorReporter),\n\t\tm_evmVersion(_evmVersion)\n\t{}\n\n\tbool check(ASTNode const& _contract);\n\nprivate:\n\n\tbool visit(ElementaryTypeName const& _typeName) override;\n\tvoid endVisit(UserDefinedTypeName const& _typeName) override;\n\tvoid endVisit(IdentifierPath const& _identifierPath) override;\n\tbool visit(FunctionTypeName const& _typeName) override;\n\tvoid endVisit(Mapping const& _mapping) override;\n\tvoid endVisit(ArrayTypeName const& _typeName) override;\n\tvoid endVisit(VariableDeclaration const& _variable) override;\n\tbool visit(EnumDefinition const& _enum) override;\n\tbool visit(StructDefinition const& _struct) override;\n\tvoid endVisit(UserDefinedValueTypeDefinition const& _userDefined) override;\n\tbool visit(UsingForDirective const& _usingForDirective) override;\n\tbool visit(InheritanceSpecifier const& _inheritanceSpecifier) override;\n\n\tlangutil::ErrorReporter& m_errorReporter;\n\tlangutil::EVMVersion m_evmVersion;\n\tbool m_insideFunctionType = false;\n\tbool m_recursiveStructSeen = false;\n\tstd::set<StructDefinition const*> m_currentStructsSeen;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/DocStringAnalyser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Parses and analyses the doc strings.\n * Stores the parsing results in the AST annotations and reports errors.\n */\n\n#include <libsolidity/analysis/DocStringAnalyser.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <liblangutil/ErrorReporter.h>\n\n#include <boost/algorithm/string.hpp>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nnamespace\n{\n\nvoid copyMissingTags(std::set<CallableDeclaration const*> const& _baseFunctions, StructurallyDocumentedAnnotation& _target, FunctionType const* _functionType = nullptr)\n{\n\t// Only copy if there is exactly one direct base function.\n\tif (_baseFunctions.size() != 1)\n\t\treturn;\n\n\tCallableDeclaration const& baseFunction = **_baseFunctions.begin();\n\n\tauto& sourceDoc = dynamic_cast<StructurallyDocumentedAnnotation const&>(baseFunction.annotation());\n\n\tfor (auto it = sourceDoc.docTags.begin(); it != sourceDoc.docTags.end();)\n\t{\n\t\tstd::string const& tag = it->first;\n\t\t// Don't copy tag \"inheritdoc\", custom tags or already existing tags\n\t\tif (tag == \"inheritdoc\" || _target.docTags.count(tag) || boost::starts_with(tag, \"custom\"))\n\t\t{\n\t\t\tit++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tsize_t n = 0;\n\t\t// Iterate over all values of the current tag (it's a multimap)\n\t\tfor (auto next = sourceDoc.docTags.upper_bound(tag); it != next; it++, n++)\n\t\t{\n\t\t\tDocTag content = it->second;\n\n\t\t\t// Update the parameter name for @return tags\n\t\t\tif (_functionType && tag == \"return\")\n\t\t\t{\n\t\t\t\tsize_t docParaNameEndPos = content.content.find_first_of(\" \\t\");\n\t\t\t\tstd::string const docParameterName = content.content.substr(0, docParaNameEndPos);\n\n\t\t\t\tif (\n\t\t\t\t\t_functionType->returnParameterNames().size() > n &&\n\t\t\t\t\tdocParameterName != _functionType->returnParameterNames().at(n)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tbool baseHasNoName =\n\t\t\t\t\t\tbaseFunction.returnParameterList() &&\n\t\t\t\t\t\tbaseFunction.returnParameters().size() > n &&\n\t\t\t\t\t\tbaseFunction.returnParameters().at(n)->name().empty();\n\n\t\t\t\t\tstd::string paramName = _functionType->returnParameterNames().at(n);\n\t\t\t\t\tcontent.content =\n\t\t\t\t\t\t(paramName.empty() ? \"\" : std::move(paramName) + \" \") + (\n\t\t\t\t\t\t\tstd::string::npos == docParaNameEndPos || baseHasNoName ?\n\t\t\t\t\t\t\tcontent.content :\n\t\t\t\t\t\t\tcontent.content.substr(docParaNameEndPos + 1)\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t_target.docTags.emplace(tag, content);\n\t\t}\n\t}\n}\n\nCallableDeclaration const* findBaseCallable(std::set<CallableDeclaration const*> const& _baseFunctions, int64_t _contractId)\n{\n\tfor (CallableDeclaration const* baseFuncCandidate: _baseFunctions)\n\t\tif (baseFuncCandidate->annotation().contract->id() == _contractId)\n\t\t\treturn baseFuncCandidate;\n\t\telse if (auto callable = findBaseCallable(baseFuncCandidate->annotation().baseFunctions, _contractId))\n\t\t\treturn callable;\n\n\treturn nullptr;\n}\n\nbool parameterNamesEqual(CallableDeclaration const& _a, CallableDeclaration const& _b)\n{\n\treturn boost::range::equal(_a.parameters(), _b.parameters(), [](auto const& pa, auto const& pb) { return pa->name() == pb->name(); });\n}\n\n}\n\nbool DocStringAnalyser::analyseDocStrings(SourceUnit const& _sourceUnit)\n{\n\tauto errorWatcher = m_errorReporter.errorWatcher();\n\t_sourceUnit.accept(*this);\n\treturn errorWatcher.ok();\n}\n\nbool DocStringAnalyser::visit(FunctionDefinition const& _function)\n{\n\tif (!_function.isConstructor())\n\t\thandleCallable(_function, _function, _function.annotation(), TypeProvider::function(_function));\n\treturn true;\n}\n\nbool DocStringAnalyser::visit(VariableDeclaration const& _variable)\n{\n\tif (!_variable.isStateVariable() && !_variable.isFileLevelVariable())\n\t\treturn false;\n\n\tauto const* getterType = TypeProvider::function(_variable);\n\n\tif (CallableDeclaration const* baseFunction = resolveInheritDoc(_variable.annotation().baseFunctions, _variable, _variable.annotation()))\n\t\tcopyMissingTags({baseFunction}, _variable.annotation(), getterType);\n\telse if (_variable.annotation().docTags.empty())\n\t\tcopyMissingTags(_variable.annotation().baseFunctions, _variable.annotation(), getterType);\n\n\treturn false;\n}\n\nbool DocStringAnalyser::visit(ModifierDefinition const& _modifier)\n{\n\thandleCallable(_modifier, _modifier, _modifier.annotation());\n\n\treturn true;\n}\n\nbool DocStringAnalyser::visit(EventDefinition const& _event)\n{\n\thandleCallable(_event, _event, _event.annotation());\n\n\treturn true;\n}\n\nbool DocStringAnalyser::visit(ErrorDefinition const& _error)\n{\n\thandleCallable(_error, _error, _error.annotation());\n\n\treturn true;\n}\n\nvoid DocStringAnalyser::handleCallable(\n\tCallableDeclaration const& _callable,\n\tStructurallyDocumented const& _node,\n\tStructurallyDocumentedAnnotation& _annotation,\n\tFunctionType const* _functionType\n)\n{\n\tif (CallableDeclaration const* baseFunction = resolveInheritDoc(_callable.annotation().baseFunctions, _node, _annotation))\n\t\tcopyMissingTags({baseFunction}, _annotation, _functionType);\n\telse if (\n\t\t_annotation.docTags.empty() &&\n\t\t_callable.annotation().baseFunctions.size() == 1 &&\n\t\tparameterNamesEqual(_callable, **_callable.annotation().baseFunctions.begin())\n\t)\n\t\tcopyMissingTags(_callable.annotation().baseFunctions, _annotation, _functionType);\n}\n\nCallableDeclaration const* DocStringAnalyser::resolveInheritDoc(\n\tstd::set<CallableDeclaration const*> const& _baseFuncs,\n\tStructurallyDocumented const& _node,\n\tStructurallyDocumentedAnnotation& _annotation\n)\n{\n\tif (_annotation.inheritdocReference == nullptr)\n\t\treturn nullptr;\n\n\tif (auto const callable = findBaseCallable(_baseFuncs, _annotation.inheritdocReference->id()))\n\t\treturn callable;\n\n\tm_errorReporter.docstringParsingError(\n\t\t4682_error,\n\t\t_node.documentation()->location(),\n\t\t\"Documentation tag @inheritdoc references contract \\\"\" +\n\t\t_annotation.inheritdocReference->name() +\n\t\t\"\\\", but the contract does not contain a function that is overridden by this function.\"\n\t);\n\n\treturn nullptr;\n}\n"
  },
  {
    "path": "libsolidity/analysis/DocStringAnalyser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend\n{\n\n/**\n * Analyses and validates the doc strings.\n * Stores the parsing results in the AST annotations and reports errors.\n */\nclass DocStringAnalyser: private ASTConstVisitor\n{\npublic:\n\tDocStringAnalyser(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}\n\tbool analyseDocStrings(SourceUnit const& _sourceUnit);\n\nprivate:\n\tbool visit(FunctionDefinition const& _function) override;\n\tbool visit(VariableDeclaration const& _variable) override;\n\tbool visit(ModifierDefinition const& _modifier) override;\n\tbool visit(EventDefinition const& _event) override;\n\tbool visit(ErrorDefinition const& _error) override;\n\n\tCallableDeclaration const* resolveInheritDoc(\n\t\tstd::set<CallableDeclaration const*> const& _baseFunctions,\n\t\tStructurallyDocumented const& _node,\n\t\tStructurallyDocumentedAnnotation& _annotation\n\t);\n\n\tvoid handleCallable(\n\t\tCallableDeclaration const& _callable,\n\t\tStructurallyDocumented const& _node,\n\t\tStructurallyDocumentedAnnotation& _annotation,\n\t\tFunctionType const* _functionType = nullptr\n\t);\n\n\tlangutil::ErrorReporter& m_errorReporter;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/DocStringTagParser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Parses and analyses the doc strings.\n * Stores the parsing results in the AST annotations and reports errors.\n */\n\n#include <libsolidity/analysis/DocStringTagParser.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/parsing/DocStringParser.h>\n#include <libsolidity/analysis/NameAndTypeResolver.h>\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/Common.h>\n\n#include <range/v3/algorithm/any_of.hpp>\n#include <range/v3/view/filter.hpp>\n\n#include <boost/algorithm/string.hpp>\n\n#include <regex>\n#include <string_view>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nbool DocStringTagParser::parseDocStrings(SourceUnit const& _sourceUnit)\n{\n\tauto errorWatcher = m_errorReporter.errorWatcher();\n\t_sourceUnit.accept(*this);\n\treturn errorWatcher.ok();\n}\n\nbool DocStringTagParser::validateDocStringsUsingTypes(SourceUnit const& _sourceUnit)\n{\n\tErrorReporter::ErrorWatcher errorWatcher = m_errorReporter.errorWatcher();\n\n\tSimpleASTVisitor visitReturns(\n\t\t[](ASTNode const&) { return true; },\n\t\t[&](ASTNode const& _node)\n\t\t{\n\t\t\tif (auto const* annotation = dynamic_cast<StructurallyDocumentedAnnotation const*>(&_node.annotation()))\n\t\t\t{\n\t\t\t\tauto const& documentationNode = dynamic_cast<StructurallyDocumented const&>(_node);\n\n\t\t\t\tsize_t returnTagsVisited = 0;\n\n\t\t\t\tfor (auto const& [tagName, tagValue]: annotation->docTags)\n\t\t\t\t\tif (tagName == \"return\")\n\t\t\t\t\t{\n\t\t\t\t\t\treturnTagsVisited++;\n\t\t\t\t\t\tstd::vector<std::string> returnParameterNames;\n\n\t\t\t\t\t\tif (auto const* varDecl = dynamic_cast<VariableDeclaration const*>(&_node))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!varDecl->isPublic())\n\t\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\t\t// FunctionType() requires the DeclarationTypeChecker to have run.\n\t\t\t\t\t\t\treturnParameterNames = FunctionType(*varDecl).returnParameterNames();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (auto const* function = dynamic_cast<FunctionDefinition const*>(&_node))\n\t\t\t\t\t\t\treturnParameterNames = FunctionType(*function).returnParameterNames();\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tstd::string content = tagValue.content;\n\t\t\t\t\t\tstd::string firstWord = content.substr(0, content.find_first_of(\" \\t\"));\n\n\t\t\t\t\t\tif (returnTagsVisited > returnParameterNames.size())\n\t\t\t\t\t\t\tm_errorReporter.docstringParsingError(\n\t\t\t\t\t\t\t\t2604_error,\n\t\t\t\t\t\t\t\tdocumentationNode.documentation()->location(),\n\t\t\t\t\t\t\t\t\"Documentation tag \\\"@\" + tagName + \" \" + content + \"\\\"\" +\n\t\t\t\t\t\t\t\t\" exceeds the number of return parameters.\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstd::string const& parameter = returnParameterNames.at(returnTagsVisited - 1);\n\t\t\t\t\t\t\tif (!parameter.empty() && parameter != firstWord)\n\t\t\t\t\t\t\t\tm_errorReporter.docstringParsingError(\n\t\t\t\t\t\t\t\t\t5856_error,\n\t\t\t\t\t\t\t\t\tdocumentationNode.documentation()->location(),\n\t\t\t\t\t\t\t\t\t\"Documentation tag \\\"@\" + tagName + \" \" + content + \"\\\"\" +\n\t\t\t\t\t\t\t\t\t\" does not contain the name of its return parameter.\"\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t}\n\t});\n\n\t_sourceUnit.accept(visitReturns);\n\treturn errorWatcher.ok();\n}\n\nbool DocStringTagParser::visit(ContractDefinition const& _contract)\n{\n\tstatic std::set<std::string> const validTags = std::set<std::string>{\"author\", \"title\", \"dev\", \"notice\"};\n\tparseDocStrings(_contract, _contract.annotation(), validTags, \"contracts\");\n\n\treturn true;\n}\n\nbool DocStringTagParser::visit(FunctionDefinition const& _function)\n{\n\tif (_function.isConstructor())\n\t\thandleConstructor(_function, _function, _function.annotation());\n\telse\n\t\thandleCallable(_function, _function, _function.annotation());\n\treturn true;\n}\n\nbool DocStringTagParser::visit(VariableDeclaration const& _variable)\n{\n\tif (_variable.isStateVariable())\n\t{\n\t\tif (_variable.isPublic())\n\t\t\tparseDocStrings(_variable, _variable.annotation(), {\"dev\", \"notice\", \"return\", \"inheritdoc\"}, \"public state variables\");\n\t\telse\n\t\t\tparseDocStrings(_variable, _variable.annotation(), {\"dev\", \"notice\", \"inheritdoc\"}, \"non-public state variables\");\n\t}\n\telse if (_variable.isFileLevelVariable())\n\t\tparseDocStrings(_variable, _variable.annotation(), {\"dev\"}, \"file-level variables\");\n\treturn false;\n}\n\nbool DocStringTagParser::visit(ModifierDefinition const& _modifier)\n{\n\thandleCallable(_modifier, _modifier, _modifier.annotation());\n\n\treturn true;\n}\n\nbool DocStringTagParser::visit(EventDefinition const& _event)\n{\n\thandleCallable(_event, _event, _event.annotation());\n\n\treturn true;\n}\n\nbool DocStringTagParser::visit(ErrorDefinition const& _error)\n{\n\thandleCallable(_error, _error, _error.annotation());\n\n\treturn true;\n}\n\nbool DocStringTagParser::visit(InlineAssembly const& _assembly)\n{\n\tif (!_assembly.documentation())\n\t\treturn true;\n\tStructuredDocumentation documentation{-1, _assembly.location(), _assembly.documentation()};\n\tErrorList errors;\n\tErrorReporter errorReporter{errors};\n\tauto docTags = DocStringParser{documentation, errorReporter}.parse();\n\n\tif (!errors.empty())\n\t{\n\t\tSecondarySourceLocation ssl;\n\t\tfor (auto const& error: errors)\n\t\t\tif (error->comment())\n\t\t\t\tssl.append(\n\t\t\t\t\t*error->comment(),\n\t\t\t\t\t_assembly.location()\n\t\t\t\t);\n\t\tm_errorReporter.warning(\n\t\t\t7828_error,\n\t\t\t_assembly.location(),\n\t\t\t\"Inline assembly has invalid NatSpec documentation.\",\n\t\t\tssl\n\t\t);\n\t}\n\n\tfor (auto const& [tagName, tagValue]: docTags)\n\t{\n\t\tif (tagName == \"solidity\")\n\t\t{\n\t\t\tstd::vector<std::string> values;\n\t\t\tboost::split(values, tagValue.content, isWhiteSpace);\n\n\t\t\tstd::set<std::string> valuesSeen;\n\t\t\tstd::set<std::string> duplicates;\n\t\t\tfor (auto const& value: values | ranges::views::filter(not_fn(&std::string::empty)))\n\t\t\t\tif (valuesSeen.insert(value).second)\n\t\t\t\t{\n\t\t\t\t\tif (value == \"memory-safe-assembly\")\n\t\t\t\t\t{\n\t\t\t\t\t\tif (_assembly.annotation().markedMemorySafe)\n\t\t\t\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t\t\t\t8544_error,\n\t\t\t\t\t\t\t\t_assembly.location(),\n\t\t\t\t\t\t\t\t\"Inline assembly marked as memory safe using both a NatSpec tag and an assembly block annotation. \"\n\t\t\t\t\t\t\t\t\"If you are not concerned with backwards compatibility, only use the assembly block annotation, \"\n\t\t\t\t\t\t\t\t\"otherwise only use the NatSpec tag.\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t_assembly.annotation().markedMemorySafe = true;\n\t\t\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t\t\t2424_error,\n\t\t\t\t\t\t\t_assembly.location(),\n\t\t\t\t\t\t\t\"Natspec memory-safe-assembly special comment for inline assembly is deprecated and \"\n\t\t\t\t\t\t\t\"scheduled for removal. \"\n\t\t\t\t\t\t\t\"Use the memory-safe block annotation instead.\"\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t\t\t8787_error,\n\t\t\t\t\t\t\t_assembly.location(),\n\t\t\t\t\t\t\t\"Unexpected value for @solidity tag in inline assembly: \" + value\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse if (duplicates.insert(value).second)\n\t\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t\t4377_error,\n\t\t\t\t\t\t_assembly.location(),\n\t\t\t\t\t\t\"Value for @solidity tag in inline assembly specified multiple times: \" + value\n\t\t\t\t\t);\n\t\t}\n\t\telse\n\t\t\tm_errorReporter.warning(\n\t\t\t\t6269_error,\n\t\t\t\t_assembly.location(),\n\t\t\t\t\"Unexpected NatSpec tag \\\"\" + tagName + \"\\\" with value \\\"\" + tagValue.content + \"\\\" in inline assembly.\"\n\t\t\t);\n\t}\n\n\treturn true;\n}\n\nvoid DocStringTagParser::checkParameters(\n\tCallableDeclaration const& _callable,\n\tStructurallyDocumented const& _node,\n\tStructurallyDocumentedAnnotation& _annotation\n)\n{\n\tstd::set<std::string> validParams;\n\tfor (auto const& p: _callable.parameters())\n\t\tvalidParams.insert(p->name());\n\tif (_callable.returnParameterList())\n\t\tfor (auto const& p: _callable.returnParameterList()->parameters())\n\t\t\tvalidParams.insert(p->name());\n\tauto paramRange = _annotation.docTags.equal_range(\"param\");\n\tfor (auto i = paramRange.first; i != paramRange.second; ++i)\n\t\tif (!validParams.count(i->second.paramName))\n\t\t\tm_errorReporter.docstringParsingError(\n\t\t\t\t3881_error,\n\t\t\t\t_node.documentation()->location(),\n\t\t\t\t\"Documented parameter \\\"\" +\n\t\t\t\ti->second.paramName +\n\t\t\t\t\"\\\" not found in the parameter list of the function.\"\n\t\t\t);\n}\n\nvoid DocStringTagParser::handleConstructor(\n\tCallableDeclaration const& _callable,\n\tStructurallyDocumented const& _node,\n\tStructurallyDocumentedAnnotation& _annotation\n)\n{\n\tstatic std::set<std::string> const validTags = std::set<std::string>{\"author\", \"dev\", \"notice\", \"param\"};\n\tparseDocStrings(_node, _annotation, validTags, \"constructor\");\n\tcheckParameters(_callable, _node, _annotation);\n}\n\nvoid DocStringTagParser::handleCallable(\n\tCallableDeclaration const& _callable,\n\tStructurallyDocumented const& _node,\n\tStructurallyDocumentedAnnotation& _annotation\n)\n{\n\tstatic std::set<std::string> const validEventTags = std::set<std::string>{\"dev\", \"notice\", \"return\", \"param\"};\n\tstatic std::set<std::string> const validErrorTags = std::set<std::string>{\"dev\", \"notice\", \"param\"};\n\tstatic std::set<std::string> const validModifierTags = std::set<std::string>{\"dev\", \"notice\", \"param\", \"inheritdoc\"};\n\tstatic std::set<std::string> const validTags = std::set<std::string>{\"dev\", \"notice\", \"return\", \"param\", \"inheritdoc\"};\n\n\tif (dynamic_cast<EventDefinition const*>(&_callable))\n\t\tparseDocStrings(_node, _annotation, validEventTags, \"events\");\n\telse if (dynamic_cast<ErrorDefinition const*>(&_callable))\n\t\tparseDocStrings(_node, _annotation, validErrorTags, \"errors\");\n\telse if (dynamic_cast<ModifierDefinition const*>(&_callable))\n\t\tparseDocStrings(_node, _annotation, validModifierTags, \"modifiers\");\n\telse\n\t\tparseDocStrings(_node, _annotation, validTags, \"functions\");\n\n\tcheckParameters(_callable, _node, _annotation);\n}\n\nvoid DocStringTagParser::parseDocStrings(\n\tStructurallyDocumented const& _node,\n\tStructurallyDocumentedAnnotation& _annotation,\n\tstd::set<std::string> const& _validTags,\n\tstd::string const& _nodeName\n)\n{\n\tif (!_node.documentation())\n\t\treturn;\n\n\t_annotation.docTags = DocStringParser{*_node.documentation(), m_errorReporter}.parse();\n\n\tfor (auto const& [tagName, tagValue]: _annotation.docTags)\n\t{\n\t\tstd::string_view static constexpr customPrefix(\"custom:\");\n\t\tif (tagName == \"custom\" || tagName == \"custom:\")\n\t\t\tm_errorReporter.docstringParsingError(\n\t\t\t\t6564_error,\n\t\t\t\t_node.documentation()->location(),\n\t\t\t\t\"Custom documentation tag must contain a chosen name, i.e. @custom:mytag.\"\n\t\t\t);\n\t\telse if (boost::starts_with(tagName, customPrefix) && tagName.size() > customPrefix.size())\n\t\t{\n\t\t\tstd::regex static const customRegex(\"^custom:[a-z][a-z-]*$\");\n\t\t\tif (!regex_match(tagName, customRegex))\n\t\t\t\tm_errorReporter.docstringParsingError(\n\t\t\t\t\t2968_error,\n\t\t\t\t\t_node.documentation()->location(),\n\t\t\t\t\t\"Invalid character in custom tag @\" + tagName + \". Only lowercase letters and \\\"-\\\" are permitted.\"\n\t\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\telse if (!_validTags.count(tagName))\n\t\t\tm_errorReporter.docstringParsingError(\n\t\t\t\t6546_error,\n\t\t\t\t_node.documentation()->location(),\n\t\t\t\t\"Documentation tag @\" + tagName + \" not valid for \" + _nodeName + \".\"\n\t\t\t);\n\t}\n}\n\n"
  },
  {
    "path": "libsolidity/analysis/DocStringTagParser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend\n{\n\n/**\n * Parses the doc tags and does basic validity checks.\n * Stores the parsing results in the AST annotations and reports errors.\n */\nclass DocStringTagParser: private ASTConstVisitor\n{\npublic:\n\texplicit DocStringTagParser(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}\n\tbool parseDocStrings(SourceUnit const& _sourceUnit);\n\t/// Validate the parsed doc strings, requires parseDocStrings() and the\n\t/// DeclarationTypeChecker to have run.\n\tbool validateDocStringsUsingTypes(SourceUnit const& _sourceUnit);\n\nprivate:\n\tbool visit(ContractDefinition const& _contract) override;\n\tbool visit(FunctionDefinition const& _function) override;\n\tbool visit(VariableDeclaration const& _variable) override;\n\tbool visit(ModifierDefinition const& _modifier) override;\n\tbool visit(EventDefinition const& _event) override;\n\tbool visit(ErrorDefinition const& _error) override;\n\tbool visit(InlineAssembly const& _assembly) override;\n\n\tvoid checkParameters(\n\t\tCallableDeclaration const& _callable,\n\t\tStructurallyDocumented const& _node,\n\t\tStructurallyDocumentedAnnotation& _annotation\n\t);\n\n\tvoid handleConstructor(\n\t\tCallableDeclaration const& _callable,\n\t\tStructurallyDocumented const& _node,\n\t\tStructurallyDocumentedAnnotation& _annotation\n\t);\n\n\tvoid handleCallable(\n\t\tCallableDeclaration const& _callable,\n\t\tStructurallyDocumented const& _node,\n\t\tStructurallyDocumentedAnnotation& _annotation\n\t);\n\n\tvoid parseDocStrings(\n\t\tStructurallyDocumented const& _node,\n\t\tStructurallyDocumentedAnnotation& _annotation,\n\t\tstd::set<std::string> const& _validTags,\n\t\tstd::string const& _nodeName\n\t);\n\n\tlangutil::ErrorReporter& m_errorReporter;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/FunctionCallGraph.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/FunctionCallGraph.h>\n\n#include <libsolutil/StringUtils.h>\n\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/reverse.hpp>\n#include <range/v3/view/transform.hpp>\n\nusing namespace solidity::frontend;\nusing namespace solidity::util;\n\nCallGraph FunctionCallGraphBuilder::buildCreationGraph(ContractDefinition const& _contract)\n{\n\tFunctionCallGraphBuilder builder(_contract);\n\tsolAssert(builder.m_currentNode == CallGraph::Node(CallGraph::SpecialNode::Entry), \"\");\n\n\t// Create graph for constructor, state vars, etc\n\tfor (ContractDefinition const* base: _contract.annotation().linearizedBaseContracts | ranges::views::reverse)\n\t{\n\t\t// The constructor and functions called in state variable initial assignments should have\n\t\t// an edge from Entry\n\t\tbuilder.m_currentNode = CallGraph::SpecialNode::Entry;\n\t\tfor (auto const* stateVar: base->stateVariables())\n\t\t\tif (!stateVar->isConstant())\n\t\t\t\tstateVar->accept(builder);\n\n\t\tif (base->constructor())\n\t\t{\n\t\t\tbuilder.functionReferenced(*base->constructor());\n\n\t\t\t// Constructors and functions called in state variable initializers have an edge either from\n\t\t\t// the previous class in linearized order or from Entry if there's no class before.\n\t\t\tbuilder.m_currentNode = base->constructor();\n\t\t}\n\n\t\t// Functions called from the inheritance specifier should have an edge from the constructor\n\t\t// for consistency with functions called from constructor modifiers.\n\t\tfor (auto const& inheritanceSpecifier: base->baseContracts())\n\t\t\tinheritanceSpecifier->accept(builder);\n\t}\n\n\tbuilder.m_currentNode = CallGraph::SpecialNode::Entry;\n\tbuilder.processQueue();\n\n\treturn std::move(builder.m_graph);\n}\n\nCallGraph FunctionCallGraphBuilder::buildDeployedGraph(\n\tContractDefinition const& _contract,\n\tCallGraph const& _creationGraph\n)\n{\n\tFunctionCallGraphBuilder builder(_contract);\n\tsolAssert(builder.m_currentNode == CallGraph::Node(CallGraph::SpecialNode::Entry), \"\");\n\n\tauto getSecondElement = [](auto const& _tuple){ return std::get<1>(_tuple); };\n\n\t// Create graph for all publicly reachable functions\n\tfor (FunctionTypePointer functionType: _contract.interfaceFunctionList() | ranges::views::transform(getSecondElement))\n\t{\n\t\tauto const* function = dynamic_cast<FunctionDefinition const*>(&functionType->declaration());\n\t\tauto const* variable = dynamic_cast<VariableDeclaration const*>(&functionType->declaration());\n\n\t\tif (function)\n\t\t\tbuilder.functionReferenced(*function);\n\t\telse\n\t\t\t// If it's not a function, it must be a getter of a public variable; we ignore those\n\t\t\tsolAssert(variable, \"\");\n\t}\n\n\tif (_contract.fallbackFunction())\n\t\tbuilder.functionReferenced(*_contract.fallbackFunction());\n\n\tif (_contract.receiveFunction())\n\t\tbuilder.functionReferenced(*_contract.receiveFunction());\n\n\t// All functions present in internal dispatch at creation time could potentially be pointers\n\t// assigned to state variables and as such may be reachable after deployment as well.\n\tbuilder.m_currentNode = CallGraph::SpecialNode::InternalDispatch;\n\tstd::set<CallGraph::Node, CallGraph::CompareByID> defaultNode;\n\tfor (CallGraph::Node const& dispatchTarget: util::valueOrDefault(_creationGraph.edges, CallGraph::SpecialNode::InternalDispatch, defaultNode))\n\t{\n\t\tsolAssert(!std::holds_alternative<CallGraph::SpecialNode>(dispatchTarget), \"\");\n\t\tsolAssert(std::get<CallableDeclaration const*>(dispatchTarget) != nullptr, \"\");\n\n\t\t// Visit the callable to add not only it but also everything it calls too\n\t\tbuilder.functionReferenced(*std::get<CallableDeclaration const*>(dispatchTarget), false);\n\t}\n\n\tbuilder.m_currentNode = CallGraph::SpecialNode::Entry;\n\tbuilder.processQueue();\n\n\treturn std::move(builder.m_graph);\n}\n\nbool FunctionCallGraphBuilder::visit(FunctionCall const& _functionCall)\n{\n\tif (*_functionCall.annotation().kind != FunctionCallKind::FunctionCall)\n\t\treturn true;\n\n\tauto const* functionType = dynamic_cast<FunctionType const*>(_functionCall.expression().annotation().type);\n\tsolAssert(functionType, \"\");\n\n\tif (functionType->kind() == FunctionType::Kind::Internal && !_functionCall.expression().annotation().calledDirectly)\n\t\t// If it's not a direct call, we don't really know which function will be called (it may even\n\t\t// change at runtime). All we can do is to add an edge to the dispatch which in turn has\n\t\t// edges to all functions could possibly be called.\n\t\tadd(m_currentNode, CallGraph::SpecialNode::InternalDispatch);\n\telse if (functionType->kind() == FunctionType::Kind::Error)\n\t\tm_graph.usedErrors.insert(&dynamic_cast<ErrorDefinition const&>(functionType->declaration()));\n\n\treturn true;\n}\n\nbool FunctionCallGraphBuilder::visit(EmitStatement const& _emitStatement)\n{\n\tauto const* functionType = dynamic_cast<FunctionType const*>(_emitStatement.eventCall().expression().annotation().type);\n\tsolAssert(functionType, \"\");\n\n\tm_graph.emittedEvents.insert(&dynamic_cast<EventDefinition const&>(functionType->declaration()));\n\n\treturn true;\n}\n\nbool FunctionCallGraphBuilder::visit(Identifier const& _identifier)\n{\n\tif (auto const* variable = dynamic_cast<VariableDeclaration const*>(_identifier.annotation().referencedDeclaration))\n\t{\n\t\tif (variable->isConstant())\n\t\t{\n\t\t\tsolAssert(variable->isStateVariable() || variable->isFileLevelVariable(), \"\");\n\t\t\tvariable->accept(*this);\n\t\t}\n\t}\n\telse if (auto const* callable = dynamic_cast<CallableDeclaration const*>(_identifier.annotation().referencedDeclaration))\n\t{\n\t\tsolAssert(*_identifier.annotation().requiredLookup == VirtualLookup::Virtual, \"\");\n\n\t\tauto funType = dynamic_cast<FunctionType const*>(_identifier.annotation().type);\n\n\t\t// For events kind() == Event, so we have an extra check here\n\t\tif (funType && funType->kind() == FunctionType::Kind::Internal)\n\t\t\tfunctionReferenced(callable->resolveVirtual(m_contract), _identifier.annotation().calledDirectly);\n\t}\n\n\treturn true;\n}\n\nbool FunctionCallGraphBuilder::visit(MemberAccess const& _memberAccess)\n{\n\tType const* exprType = _memberAccess.expression().annotation().type;\n\tASTString const& memberName = _memberAccess.memberName();\n\n\tif (auto magicType = dynamic_cast<MagicType const*>(exprType))\n\t\tif (magicType->kind() == MagicType::Kind::MetaType && (\n\t\t\tmemberName == \"creationCode\" || memberName == \"runtimeCode\"\n\t\t))\n\t\t{\n\t\t\tContractType const& accessedContractType = dynamic_cast<ContractType const&>(*magicType->typeArgument());\n\t\t\tm_graph.bytecodeDependency.emplace(&accessedContractType.contractDefinition(), &_memberAccess);\n\t\t}\n\n\tauto functionType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type);\n\tauto functionDef = dynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration);\n\tif (!functionType || !functionDef || functionType->kind() != FunctionType::Kind::Internal)\n\t\treturn true;\n\n\t// Super functions\n\tif (*_memberAccess.annotation().requiredLookup == VirtualLookup::Super)\n\t{\n\t\tif (auto const* typeType = dynamic_cast<TypeType const*>(exprType))\n\t\t\tif (auto const contractType = dynamic_cast<ContractType const*>(typeType->actualType()))\n\t\t\t{\n\t\t\t\tsolAssert(contractType->isSuper(), \"\");\n\t\t\t\tfunctionDef = &functionDef->resolveVirtual(\n\t\t\t\t\tm_contract,\n\t\t\t\t\tcontractType->contractDefinition().superContract(m_contract)\n\t\t\t\t);\n\t\t\t}\n\t}\n\telse\n\t\tsolAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Static, \"\");\n\n\tfunctionReferenced(*functionDef, _memberAccess.annotation().calledDirectly);\n\treturn true;\n}\n\nbool FunctionCallGraphBuilder::visit(BinaryOperation const& _binaryOperation)\n{\n\tif (*_binaryOperation.annotation().userDefinedFunction != nullptr)\n\t\tfunctionReferenced(**_binaryOperation.annotation().userDefinedFunction, true /* called directly */);\n\treturn true;\n}\n\nbool FunctionCallGraphBuilder::visit(UnaryOperation const& _unaryOperation)\n{\n\tif (*_unaryOperation.annotation().userDefinedFunction != nullptr)\n\t\tfunctionReferenced(**_unaryOperation.annotation().userDefinedFunction, true /* called directly */);\n\treturn true;\n}\n\nbool FunctionCallGraphBuilder::visit(ModifierInvocation const& _modifierInvocation)\n{\n\tif (auto const* modifier = dynamic_cast<ModifierDefinition const*>(_modifierInvocation.name().annotation().referencedDeclaration))\n\t{\n\t\tVirtualLookup const& requiredLookup = *_modifierInvocation.name().annotation().requiredLookup;\n\n\t\tif (requiredLookup == VirtualLookup::Virtual)\n\t\t\tfunctionReferenced(modifier->resolveVirtual(m_contract));\n\t\telse\n\t\t{\n\t\t\tsolAssert(requiredLookup == VirtualLookup::Static, \"\");\n\t\t\tfunctionReferenced(*modifier);\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool FunctionCallGraphBuilder::visit(NewExpression const& _newExpression)\n{\n\tif (ContractType const* contractType = dynamic_cast<ContractType const*>(_newExpression.typeName().annotation().type))\n\t\tm_graph.bytecodeDependency.emplace(&contractType->contractDefinition(), &_newExpression);\n\n\treturn true;\n}\n\nvoid FunctionCallGraphBuilder::enqueueCallable(CallableDeclaration const& _callable)\n{\n\tif (!m_graph.edges.count(&_callable))\n\t{\n\t\tm_visitQueue.push_back(&_callable);\n\n\t\t// Insert the callable to the graph (with no edges coming out of it) to mark it as visited.\n\t\tm_graph.edges.insert({CallGraph::Node(&_callable), {}});\n\t}\n}\n\nvoid FunctionCallGraphBuilder::processQueue()\n{\n\tsolAssert(m_currentNode == CallGraph::Node(CallGraph::SpecialNode::Entry), \"Visit queue is already being processed.\");\n\n\twhile (!m_visitQueue.empty())\n\t{\n\t\tm_currentNode = m_visitQueue.front();\n\t\tsolAssert(std::holds_alternative<CallableDeclaration const*>(m_currentNode), \"\");\n\n\t\tm_visitQueue.pop_front();\n\t\tstd::get<CallableDeclaration const*>(m_currentNode)->accept(*this);\n\t}\n\n\tm_currentNode = CallGraph::SpecialNode::Entry;\n}\n\nvoid FunctionCallGraphBuilder::add(CallGraph::Node _caller, CallGraph::Node _callee)\n{\n\tm_graph.edges[_caller].insert(_callee);\n}\n\nvoid FunctionCallGraphBuilder::functionReferenced(CallableDeclaration const& _callable, bool _calledDirectly)\n{\n\tif (_calledDirectly)\n\t{\n\t\tsolAssert(\n\t\t\tstd::holds_alternative<CallGraph::SpecialNode>(m_currentNode) || m_graph.edges.count(m_currentNode) > 0,\n\t\t\t\"Adding an edge from a node that has not been visited yet.\"\n\t\t);\n\n\t\tadd(m_currentNode, &_callable);\n\t}\n\telse\n\t\tadd(CallGraph::SpecialNode::InternalDispatch, &_callable);\n\n\tenqueueCallable(_callable);\n}\n\nstd::ostream& solidity::frontend::operator<<(std::ostream& _out, CallGraph::Node const& _node)\n{\n\tif (std::holds_alternative<CallGraph::SpecialNode>(_node))\n\t\tswitch (std::get<CallGraph::SpecialNode>(_node))\n\t\t{\n\t\tcase CallGraph::SpecialNode::InternalDispatch:\n\t\t\t_out << \"InternalDispatch\";\n\t\t\tbreak;\n\t\tcase CallGraph::SpecialNode::Entry:\n\t\t\t_out << \"Entry\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tsolAssert(false, \"Invalid SpecialNode type\");\n\t\t}\n\telse\n\t{\n\t\tsolAssert(std::holds_alternative<CallableDeclaration const*>(_node), \"\");\n\n\t\tauto const* callableDeclaration = std::get<CallableDeclaration const*>(_node);\n\t\tsolAssert(callableDeclaration, \"\");\n\n\t\tauto const* function = dynamic_cast<FunctionDefinition const *>(callableDeclaration);\n\t\tauto const* event = dynamic_cast<EventDefinition const *>(callableDeclaration);\n\t\tauto const* modifier = dynamic_cast<ModifierDefinition const *>(callableDeclaration);\n\n\t\tauto typeToString = [](auto const& _var) -> std::string { return _var->type()->toString(true); };\n\t\tstd::vector<std::string> parameters = callableDeclaration->parameters() | ranges::views::transform(typeToString) | ranges::to<std::vector<std::string>>();\n\n\t\tstd::string scopeName;\n\t\tif (!function || !function->isFree())\n\t\t{\n\t\t\tsolAssert(callableDeclaration->annotation().scope, \"\");\n\t\t\tauto const* parentContract = dynamic_cast<ContractDefinition const*>(callableDeclaration->annotation().scope);\n\t\t\tsolAssert(parentContract, \"\");\n\t\t\tscopeName = parentContract->name();\n\t\t}\n\n\t\tif (function && function->isFree())\n\t\t\t_out << \"function \" << function->name() << \"(\" << joinHumanReadable(parameters, \",\") << \")\";\n\t\telse if (function && function->isConstructor())\n\t\t\t_out << \"constructor of \" << scopeName;\n\t\telse if (function && function->isFallback())\n\t\t\t_out << \"fallback of \" << scopeName;\n\t\telse if (function && function->isReceive())\n\t\t\t_out << \"receive of \" << scopeName;\n\t\telse if (function)\n\t\t\t_out << \"function \" << scopeName << \".\" << function->name() << \"(\" << joinHumanReadable(parameters, \",\") << \")\";\n\t\telse if (event)\n\t\t\t_out << \"event \" << scopeName << \".\" << event->name() << \"(\" << joinHumanReadable(parameters, \",\") << \")\";\n\t\telse if (modifier)\n\t\t\t_out << \"modifier \" << scopeName << \".\" << modifier->name();\n\t\telse\n\t\t\tsolAssert(false, \"Unexpected AST node type in function call graph\");\n\t}\n\n\treturn _out;\n}\n"
  },
  {
    "path": "libsolidity/analysis/FunctionCallGraph.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/ast/CallGraph.h>\n\n#include <deque>\n#include <ostream>\n\nnamespace solidity::frontend\n{\n\n/**\n * Creates a function call graph for a contract at the granularity of Solidity functions and modifiers.\n * or after deployment. The graph does not preserve temporal relations between calls - edges\n * coming out of the same node show which calls were performed but not in what order.\n *\n * Includes the following special nodes:\n *  - Entry: represents a call from the outside of the contract.\n *    After deployment this is the node that connects to all the functions exposed through the\n *    external interface. At contract creation it connects to the constructors and variable\n *    initializers, which are not explicitly called from within another function.\n *  - InternalDispatch: Represents the internal dispatch function, which calls internal functions\n *    determined at runtime by values of variables and expressions. Functions that are not called\n *    right away get an edge from this node.\n *\n *  Nodes are a variant of either the enum SpecialNode or a CallableDeclaration which currently\n *  can be a function or a modifier. There are no nodes representing event calls. Instead all\n *  emitted events and created contracts are gathered in separate sets included in the graph just\n *  for that purpose.\n *\n *  Auto-generated getter functions for public state variables are ignored, but function calls\n *  inside initial assignments are included in the creation graph.\n *\n *  Only calls reachable from an Entry node are included in the graph. The map representing edges\n *  is also guaranteed to contain keys representing all the reachable functions and modifiers, even\n *  if they have no outgoing edges.\n */\nclass FunctionCallGraphBuilder: private ASTConstVisitor\n{\npublic:\n\tstatic CallGraph buildCreationGraph(ContractDefinition const& _contract);\n\tstatic CallGraph buildDeployedGraph(\n\t\tContractDefinition const& _contract,\n\t\tCallGraph const& _creationGraph\n\t);\n\nprivate:\n\tFunctionCallGraphBuilder(ContractDefinition const& _contract):\n\t\tm_contract(_contract)\n\t{}\n\n\tbool visit(FunctionCall const& _functionCall) override;\n\tbool visit(EmitStatement const& _emitStatement) override;\n\tbool visit(Identifier const& _identifier) override;\n\tbool visit(MemberAccess const& _memberAccess) override;\n\tbool visit(BinaryOperation const& _binaryOperation) override;\n\tbool visit(UnaryOperation const& _unaryOperation) override;\n\tbool visit(ModifierInvocation const& _modifierInvocation) override;\n\tbool visit(NewExpression const& _newExpression) override;\n\n\tvoid enqueueCallable(CallableDeclaration const& _callable);\n\tvoid processQueue();\n\n\tvoid add(CallGraph::Node _caller, CallGraph::Node _callee);\n\tvoid functionReferenced(CallableDeclaration const& _callable, bool _calledDirectly = true);\n\n\tCallGraph::Node m_currentNode = CallGraph::SpecialNode::Entry;\n\tContractDefinition const& m_contract;\n\tCallGraph m_graph;\n\tstd::deque<CallableDeclaration const*> m_visitQueue;\n};\n\nstd::ostream& operator<<(std::ostream& _out, CallGraph::Node const& _node);\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/GlobalContext.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @author Gav Wood <g@ethdev.com>\n * @date 2014\n * Container of the (implicit and explicit) global objects.\n */\n\n#include <libsolidity/analysis/GlobalContext.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/ast/Types.h>\n#include <memory>\n#include <unordered_map>\n\nnamespace solidity::frontend\n{\n\nnamespace\n{\n\n/// Magic variables get negative ids for easy differentiation\nint magicVariableToID(std::string const& _name)\n{\n\tstatic std::unordered_map<std::string, int> const magicVariables = {\n\t\t{\"abi\", -1},\n\t\t{\"addmod\", -2},\n\t\t{\"assert\", -3},\n\t\t{\"block\", -4},\n\t\t{\"blockhash\", -5},\n\t\t{\"ecrecover\", -6},\n\t\t{\"gasleft\", -7},\n\t\t{\"keccak256\", -8},\n\t\t{\"msg\", -15},\n\t\t{\"mulmod\", -16},\n\t\t{\"now\", -17},\n\t\t{\"require\", -18},\n\t\t{\"revert\", -19},\n\t\t{\"ripemd160\", -20},\n\t\t{\"selfdestruct\", -21},\n\t\t{\"sha256\", -22},\n\t\t{\"sha3\", -23},\n\t\t{\"suicide\", -24},\n\t\t{\"super\", -25},\n\t\t{\"tx\", -26},\n\t\t{\"type\", -27},\n\t\t{\"this\", -28},\n\t\t{\"blobhash\", -29},\n\t\t{\"erc7201\", -30}\n\t};\n\n\tif (auto id = magicVariables.find(_name); id != magicVariables.end())\n\t\treturn id->second;\n\tsolAssert(false, \"Unknown magic variable: \\\"\" + _name + \"\\\".\");\n}\n\ninline std::vector<std::shared_ptr<MagicVariableDeclaration const>> constructMagicVariables(langutil::EVMVersion _evmVersion)\n{\n\tstatic auto const magicVarDecl = [](std::string const& _name, Type const* _type) {\n\t\treturn std::make_shared<MagicVariableDeclaration>(magicVariableToID(_name), _name, _type);\n\t};\n\n\tstd::vector<std::shared_ptr<MagicVariableDeclaration const>> magicVariableDeclarations = {\n\t\tmagicVarDecl(\"abi\", TypeProvider::magic(MagicType::Kind::ABI)),\n\t\tmagicVarDecl(\"addmod\", TypeProvider::function(strings{\"uint256\", \"uint256\", \"uint256\"}, strings{\"uint256\"}, FunctionType::Kind::AddMod, StateMutability::Pure)),\n\t\tmagicVarDecl(\"assert\", TypeProvider::function(strings{\"bool\"}, strings{}, FunctionType::Kind::Assert, StateMutability::Pure)),\n\t\tmagicVarDecl(\"block\", TypeProvider::magic(MagicType::Kind::Block)),\n\t\tmagicVarDecl(\"blockhash\", TypeProvider::function(strings{\"uint256\"}, strings{\"bytes32\"}, FunctionType::Kind::BlockHash, StateMutability::View)),\n\t\tmagicVarDecl(\"ecrecover\", TypeProvider::function(strings{\"bytes32\", \"uint8\", \"bytes32\", \"bytes32\"}, strings{\"address\"}, FunctionType::Kind::ECRecover, StateMutability::Pure)),\n\t\tmagicVarDecl(\"erc7201\", TypeProvider::function(strings{\"string memory\"}, strings{\"uint256\"}, FunctionType::Kind::ERC7201, StateMutability::Pure)),\n\t\tmagicVarDecl(\"gasleft\", TypeProvider::function(strings(), strings{\"uint256\"}, FunctionType::Kind::GasLeft, StateMutability::View)),\n\t\tmagicVarDecl(\"keccak256\", TypeProvider::function(strings{\"bytes memory\"}, strings{\"bytes32\"}, FunctionType::Kind::KECCAK256, StateMutability::Pure)),\n\t\tmagicVarDecl(\"msg\", TypeProvider::magic(MagicType::Kind::Message)),\n\t\tmagicVarDecl(\"mulmod\", TypeProvider::function(strings{\"uint256\", \"uint256\", \"uint256\"}, strings{\"uint256\"}, FunctionType::Kind::MulMod, StateMutability::Pure)),\n\t\tmagicVarDecl(\"now\", TypeProvider::uint256()),\n\t\tmagicVarDecl(\"require\", TypeProvider::function(strings{\"bool\"}, strings{}, FunctionType::Kind::Require, StateMutability::Pure)),\n\t\tmagicVarDecl(\"require\", TypeProvider::function(strings{\"bool\", \"string memory\"}, strings{}, FunctionType::Kind::Require, StateMutability::Pure)),\n\t\tmagicVarDecl(\"require\", TypeProvider::function(TypePointers{TypeProvider::boolean(), TypeProvider::magic(MagicType::Kind::Error)}, TypePointers{}, strings{2, \"\"}, strings{}, FunctionType::Kind::Require, StateMutability::Pure)),\n\t\tmagicVarDecl(\"revert\", TypeProvider::function(strings(), strings(), FunctionType::Kind::Revert, StateMutability::Pure)),\n\t\tmagicVarDecl(\"revert\", TypeProvider::function(strings{\"string memory\"}, strings(), FunctionType::Kind::Revert, StateMutability::Pure)),\n\t\tmagicVarDecl(\"ripemd160\", TypeProvider::function(strings{\"bytes memory\"}, strings{\"bytes20\"}, FunctionType::Kind::RIPEMD160, StateMutability::Pure)),\n\t\tmagicVarDecl(\"selfdestruct\", TypeProvider::function(strings{\"address payable\"}, strings{}, FunctionType::Kind::Selfdestruct)),\n\t\tmagicVarDecl(\"sha256\", TypeProvider::function(strings{\"bytes memory\"}, strings{\"bytes32\"}, FunctionType::Kind::SHA256, StateMutability::Pure)),\n\t\tmagicVarDecl(\"sha3\", TypeProvider::function(strings{\"bytes memory\"}, strings{\"bytes32\"}, FunctionType::Kind::KECCAK256, StateMutability::Pure)),\n\t\tmagicVarDecl(\"suicide\", TypeProvider::function(strings{\"address payable\"}, strings{}, FunctionType::Kind::Selfdestruct)),\n\t\tmagicVarDecl(\"tx\", TypeProvider::magic(MagicType::Kind::Transaction)),\n\t\t// Accepts a MagicType that can be any contract type or an Integer type and returns a\n\t\t// MagicType. The TypeChecker handles the correctness of the input and output types.\n\t\tmagicVarDecl(\"type\", TypeProvider::function(\n\t\t\tstrings{},\n\t\t\tstrings{},\n\t\t\tFunctionType::Kind::MetaType,\n\t\t\tStateMutability::Pure,\n\t\t\tFunctionType::Options::withArbitraryParameters()\n\t\t)),\n\t};\n\n\tif (_evmVersion >= langutil::EVMVersion::cancun())\n\t\tmagicVariableDeclarations.push_back(\n\t\t\tmagicVarDecl(\"blobhash\", TypeProvider::function(strings{\"uint256\"}, strings{\"bytes32\"}, FunctionType::Kind::BlobHash, StateMutability::View))\n\t\t);\n\n\treturn magicVariableDeclarations;\n}\n\n}\n\nGlobalContext::GlobalContext(langutil::EVMVersion _evmVersion):\n\tm_magicVariables{constructMagicVariables(_evmVersion)}\n{\n}\n\nvoid GlobalContext::setCurrentContract(ContractDefinition const& _contract)\n{\n\tm_currentContract = &_contract;\n}\n\nstd::vector<Declaration const*> GlobalContext::declarations() const\n{\n\tstd::vector<Declaration const*> declarations;\n\tdeclarations.reserve(m_magicVariables.size());\n\tfor (ASTPointer<MagicVariableDeclaration const> const& variable: m_magicVariables)\n\t\tdeclarations.push_back(variable.get());\n\treturn declarations;\n}\n\nMagicVariableDeclaration const* GlobalContext::currentThis() const\n{\n\tif (!m_thisPointer[m_currentContract])\n\t{\n\t\tType const* type = TypeProvider::emptyTuple();\n\t\tif (m_currentContract)\n\t\t\ttype = TypeProvider::contract(*m_currentContract);\n\t\tm_thisPointer[m_currentContract] =\n\t\t\tstd::make_shared<MagicVariableDeclaration>(magicVariableToID(\"this\"), \"this\", type);\n\t}\n\treturn m_thisPointer[m_currentContract].get();\n}\n\nMagicVariableDeclaration const* GlobalContext::currentSuper() const\n{\n\tif (!m_superPointer[m_currentContract])\n\t{\n\t\tType const* type = TypeProvider::emptyTuple();\n\t\tif (m_currentContract)\n\t\t\ttype = TypeProvider::typeType(TypeProvider::contract(*m_currentContract, true));\n\t\tm_superPointer[m_currentContract] =\n\t\t\tstd::make_shared<MagicVariableDeclaration>(magicVariableToID(\"super\"), \"super\", type);\n\t}\n\treturn m_superPointer[m_currentContract].get();\n}\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/GlobalContext.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Container of the (implicit and explicit) global objects.\n */\n\n#pragma once\n\n#include <liblangutil/EVMVersion.h>\n#include <libsolidity/ast/ASTForward.h>\n#include <map>\n#include <memory>\n#include <string>\n#include <vector>\n\nnamespace solidity::frontend\n{\n\nclass Type; // forward\n\n/**\n * Container for all global objects which look like AST nodes, but are not part of the AST\n * that is currently being compiled.\n * @note must not be destroyed or moved during compilation as its objects can be referenced from\n * other objects.\n */\nclass GlobalContext\n{\npublic:\n\t/// Noncopyable.\n\tGlobalContext(GlobalContext const&) = delete;\n\tGlobalContext& operator=(GlobalContext const&) = delete;\n\n\tGlobalContext(langutil::EVMVersion _evmVersion);\n\tvoid setCurrentContract(ContractDefinition const& _contract);\n\tvoid resetCurrentContract() { m_currentContract = nullptr; }\n\tMagicVariableDeclaration const* currentThis() const;\n\tMagicVariableDeclaration const* currentSuper() const;\n\n\t/// @returns a vector of all implicit global declarations excluding \"this\".\n\tstd::vector<Declaration const*> declarations() const;\n\nprivate:\n\tstd::vector<std::shared_ptr<MagicVariableDeclaration const>> m_magicVariables;\n\tContractDefinition const* m_currentContract = nullptr;\n\tstd::map<ContractDefinition const*, std::shared_ptr<MagicVariableDeclaration const>> mutable m_thisPointer;\n\tstd::map<ContractDefinition const*, std::shared_ptr<MagicVariableDeclaration const>> mutable m_superPointer;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/ImmutableValidator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/ImmutableValidator.h>\n\n#include <range/v3/view/reverse.hpp>\n\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\n\nvoid ImmutableValidator::analyze()\n{\n\tauto linearizedContracts = m_mostDerivedContract.annotation().linearizedBaseContracts | ranges::views::reverse;\n\n\tfor (ContractDefinition const* contract: linearizedContracts)\n\t{\n\t\tfor (FunctionDefinition const* function: contract->definedFunctions())\n\t\t\tfunction->accept(*this);\n\n\t\tfor (ModifierDefinition const* modifier: contract->functionModifiers())\n\t\t\tmodifier->accept(*this);\n\t}\n}\n\nbool ImmutableValidator::visit(FunctionDefinition const& _functionDefinition)\n{\n\treturn !_functionDefinition.isConstructor();\n}\n\nvoid ImmutableValidator::endVisit(MemberAccess const& _memberAccess)\n{\n\tanalyseVariableReference(_memberAccess.annotation().referencedDeclaration, _memberAccess);\n}\n\nvoid ImmutableValidator::endVisit(Identifier const& _identifier)\n{\n\tanalyseVariableReference(_identifier.annotation().referencedDeclaration, _identifier);\n}\n\nvoid ImmutableValidator::analyseVariableReference(Declaration const* _reference, Expression const& _expression)\n{\n\tauto const* variable = dynamic_cast<VariableDeclaration const*>(_reference);\n\tif (!variable || !variable->isStateVariable() || !variable->immutable())\n\t\treturn;\n\n\t// If this is not an ordinary assignment, we write and read at the same time.\n\tif (_expression.annotation().willBeWrittenTo)\n\t\tm_errorReporter.typeError(\n\t\t\t1581_error,\n\t\t\t_expression.location(),\n\t\t\t\"Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.\"\n\t\t);\n}\n"
  },
  {
    "path": "libsolidity/analysis/ImmutableValidator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n#include <liblangutil/ErrorReporter.h>\n\nnamespace solidity::frontend\n{\n\n/**\n * Validates access and initialization of immutable variables:\n * must be directly initialized in a c'tor or inline\n*/\nclass ImmutableValidator: private ASTConstVisitor\n{\npublic:\n\tImmutableValidator(langutil::ErrorReporter& _errorReporter, ContractDefinition const& _contractDefinition):\n\t\tm_mostDerivedContract(_contractDefinition),\n\t\tm_errorReporter(_errorReporter)\n\t{ }\n\n\tvoid analyze();\n\nprivate:\n\tbool visit(FunctionDefinition const& _functionDefinition);\n\tvoid endVisit(MemberAccess const& _memberAccess);\n\tvoid endVisit(Identifier const& _identifier);\n\n\tvoid analyseVariableReference(Declaration const* _variableReference, Expression const& _expression);\n\n\tContractDefinition const& m_mostDerivedContract;\n\n\tlangutil::ErrorReporter& m_errorReporter;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/NameAndTypeResolver.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Parser part that determines the declarations corresponding to names and the types of expressions.\n */\n\n#include <libsolidity/analysis/NameAndTypeResolver.h>\n\n#include <libsolidity/analysis/TypeChecker.h>\n#include <libsolidity/ast/AST.h>\n#include <liblangutil/ErrorReporter.h>\n#include <libsolutil/StringUtils.h>\n#include <boost/algorithm/string.hpp>\n#include <unordered_set>\n\nusing namespace std::string_literals;\nusing namespace solidity::langutil;\n\nnamespace solidity::frontend\n{\n\nNameAndTypeResolver::NameAndTypeResolver(\n\tGlobalContext& _globalContext,\n\tlangutil::EVMVersion _evmVersion,\n\tErrorReporter& _errorReporter,\n\tbool _experimentalSolidity\n):\n\tm_evmVersion(_evmVersion),\n\tm_errorReporter(_errorReporter),\n\tm_globalContext(_globalContext),\n\tm_experimentalSolidity(_experimentalSolidity)\n{\n\tm_scopes[nullptr] = std::make_shared<DeclarationContainer>();\n\tfor (Declaration const* declaration: _globalContext.declarations())\n\t{\n\t\tsolAssert(m_scopes[nullptr]->registerDeclaration(*declaration, false, false), \"Unable to register global declaration.\");\n\t}\n}\n\nbool NameAndTypeResolver::registerDeclarations(SourceUnit& _sourceUnit, ASTNode const* _currentScope)\n{\n\t// The helper registers all declarations in m_scopes as a side-effect of its construction.\n\ttry\n\t{\n\t\tDeclarationRegistrationHelper registrar(m_scopes, _sourceUnit, m_errorReporter, m_globalContext, _currentScope);\n\t}\n\tcatch (FatalError const&)\n\t{\n\t\tif (!m_errorReporter.hasErrors())\n\t\t{\n\t\t\tstd::cerr << \"Unreported fatal error:\" << std::endl;\n\t\t\tstd::cerr << boost::current_exception_diagnostic_information() << std::endl;\n\t\t\tsolAssert(false, \"Unreported fatal error.\");\n\t\t}\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nbool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, std::map<std::string, SourceUnit const*> const& _sourceUnits)\n{\n\tDeclarationContainer& target = *m_scopes.at(&_sourceUnit);\n\tbool error = false;\n\tfor (auto const& node: _sourceUnit.nodes())\n\t\tif (auto imp = dynamic_cast<ImportDirective const*>(node.get()))\n\t\t{\n\t\t\tstd::string const& path = *imp->annotation().absolutePath;\n\t\t\t// The import resolution in CompilerStack enforces this.\n\t\t\tsolAssert(_sourceUnits.count(path), \"\");\n\t\t\tauto scope = m_scopes.find(_sourceUnits.at(path));\n\t\t\tsolAssert(scope != end(m_scopes), \"\");\n\t\t\tif (!imp->symbolAliases().empty())\n\t\t\t\tfor (auto const& alias: imp->symbolAliases())\n\t\t\t\t{\n\t\t\t\t\tauto declarations = scope->second->resolveName(alias.symbol->name());\n\t\t\t\t\tif (declarations.empty())\n\t\t\t\t\t{\n\t\t\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t\t\t2904_error,\n\t\t\t\t\t\t\timp->location(),\n\t\t\t\t\t\t\t\"Declaration \\\"\" +\n\t\t\t\t\t\t\talias.symbol->name() +\n\t\t\t\t\t\t\t\"\\\" not found in \\\"\" +\n\t\t\t\t\t\t\tpath +\n\t\t\t\t\t\t\t\"\\\" (referenced as \\\"\" +\n\t\t\t\t\t\t\timp->path() +\n\t\t\t\t\t\t\t\"\\\").\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\terror = true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tfor (Declaration const* declaration: declarations)\n\t\t\t\t\t\t\tif (!DeclarationRegistrationHelper::registerDeclaration(\n\t\t\t\t\t\t\t\ttarget,\n\t\t\t\t\t\t\t\t*declaration,\n\t\t\t\t\t\t\t\talias.alias ? alias.alias.get() : &alias.symbol->name(),\n\t\t\t\t\t\t\t\t&alias.location,\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\tm_errorReporter\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t\t\terror = true;\n\t\t\t\t}\n\t\t\telse if (imp->name().empty())\n\t\t\t\tfor (auto const& nameAndDeclaration: scope->second->declarations())\n\t\t\t\t\tfor (auto const& declaration: nameAndDeclaration.second)\n\t\t\t\t\t\tif (!DeclarationRegistrationHelper::registerDeclaration(\n\t\t\t\t\t\t\ttarget, *declaration, &nameAndDeclaration.first, &imp->location(), false, m_errorReporter\n\t\t\t\t\t\t))\n\t\t\t\t\t\t\terror =  true;\n\t\t}\n\t_sourceUnit.annotation().exportedSymbols = m_scopes[&_sourceUnit]->declarations();\n\treturn !error;\n}\n\nbool NameAndTypeResolver::resolveNamesAndTypes(SourceUnit& _source)\n{\n\ttry\n\t{\n\t\tfor (std::shared_ptr<ASTNode> const& node: _source.nodes())\n\t\t{\n\t\t\tsetScope(&_source);\n\t\t\tif (!resolveNamesAndTypesInternal(*node, true))\n\t\t\t\treturn false;\n\t\t}\n\t}\n\tcatch (FatalError const&)\n\t{\n\t\tif (!m_errorReporter.hasErrors())\n\t\t{\n\t\t\tstd::cerr << \"Unreported fatal error:\" << std::endl;\n\t\t\tstd::cerr << boost::current_exception_diagnostic_information() << std::endl;\n\t\t\tsolAssert(false, \"Unreported fatal error.\");\n\t\t}\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nbool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)\n{\n\ttry\n\t{\n\t\tm_scopes[nullptr]->registerDeclaration(_declaration, false, true);\n\t\tsolAssert(_declaration.scope() == nullptr, \"Updated declaration outside global scope.\");\n\t}\n\tcatch (FatalError const&)\n\t{\n\t\tif (!m_errorReporter.hasErrors())\n\t\t{\n\t\t\tstd::cerr << \"Unreported fatal error:\" << std::endl;\n\t\t\tstd::cerr << boost::current_exception_diagnostic_information() << std::endl;\n\t\t\tsolAssert(false, \"Unreported fatal error.\");\n\t\t}\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nvoid NameAndTypeResolver::activateVariable(std::string const& _name)\n{\n\tsolAssert(m_currentScope, \"\");\n\t// Scoped local variables are invisible before activation.\n\t// When a local variable is activated, its name is removed\n\t// from a scope's invisible variables.\n\t// This is used to avoid activation of variables of same name\n\t// in the same scope (an error is returned).\n\tif (m_currentScope->isInvisible(_name))\n\t\tm_currentScope->activateVariable(_name);\n}\n\nstd::vector<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _name, ASTNode const* _scope) const\n{\n\tauto iterator = m_scopes.find(_scope);\n\tif (iterator == end(m_scopes))\n\t\treturn std::vector<Declaration const*>({});\n\treturn iterator->second->resolveName(_name);\n}\n\nstd::vector<Declaration const*> NameAndTypeResolver::nameFromCurrentScope(ASTString const& _name, bool _includeInvisibles) const\n{\n\tResolvingSettings settings;\n\tsettings.recursive = true;\n\tsettings.alsoInvisible = _includeInvisibles;\n\treturn m_currentScope->resolveName(_name, std::move(settings));\n}\n\nDeclaration const* NameAndTypeResolver::pathFromCurrentScope(std::vector<ASTString> const& _path) const\n{\n\tif (auto declarations = pathFromCurrentScopeWithAllDeclarations(_path); !declarations.empty())\n\t\treturn declarations.back();\n\n\treturn nullptr;\n}\n\nstd::vector<Declaration const*> NameAndTypeResolver::pathFromCurrentScopeWithAllDeclarations(\n\tstd::vector<ASTString> const& _path,\n\tbool _includeInvisibles\n) const\n{\n\tsolAssert(!_path.empty(), \"\");\n\tstd::vector<Declaration const*> pathDeclarations;\n\n\tResolvingSettings settings;\n\tsettings.recursive = true;\n\tsettings.alsoInvisible = _includeInvisibles;\n\tsettings.onlyVisibleAsUnqualifiedNames = true;\n\tstd::vector<Declaration const*> candidates = m_currentScope->resolveName(_path.front(), settings);\n\n\t// inside the loop, use default settings, except for alsoInvisible\n\tsettings.recursive = false;\n\tsettings.onlyVisibleAsUnqualifiedNames = false;\n\n\tfor (size_t i = 1; i < _path.size() && candidates.size() == 1; i++)\n\t{\n\t\tif (!m_scopes.count(candidates.front()))\n\t\t\treturn {};\n\n\t\tpathDeclarations.push_back(candidates.front());\n\n\t\tcandidates = m_scopes.at(candidates.front())->resolveName(_path[i], settings);\n\t}\n\tif (candidates.size() == 1)\n\t{\n\t\tpathDeclarations.push_back(candidates.front());\n\t\treturn pathDeclarations;\n\t}\n\telse\n\t\treturn {};\n}\n\nvoid NameAndTypeResolver::warnHomonymDeclarations() const\n{\n\tDeclarationContainer::Homonyms homonyms;\n\tm_scopes.at(nullptr)->populateHomonyms(back_inserter(homonyms));\n\n\tfor (auto [innerLocation, outerDeclarations]: homonyms)\n\t{\n\t\tsolAssert(innerLocation && !outerDeclarations.empty(), \"\");\n\n\t\tbool magicShadowed = false;\n\t\tSecondarySourceLocation homonymousLocations;\n\t\tSecondarySourceLocation shadowedLocations;\n\t\tfor (Declaration const* outerDeclaration: outerDeclarations)\n\t\t{\n\t\t\tsolAssert(outerDeclaration, \"\");\n\t\t\tif (dynamic_cast<MagicVariableDeclaration const*>(outerDeclaration))\n\t\t\t\tmagicShadowed = true;\n\t\t\telse if (!outerDeclaration->isVisibleInContract())\n\t\t\t\thomonymousLocations.append(\"The other declaration is here:\", outerDeclaration->location());\n\t\t\telse\n\t\t\t\tshadowedLocations.append(\"The shadowed declaration is here:\", outerDeclaration->location());\n\t\t}\n\n\t\tif (magicShadowed)\n\t\t\tm_errorReporter.warning(\n\t\t\t\t2319_error,\n\t\t\t\t*innerLocation,\n\t\t\t\t\"This declaration shadows a builtin symbol.\"\n\t\t\t);\n\t\tif (!homonymousLocations.infos.empty())\n\t\t\tm_errorReporter.warning(\n\t\t\t\t8760_error,\n\t\t\t\t*innerLocation,\n\t\t\t\t\"This declaration has the same name as another declaration.\",\n\t\t\t\thomonymousLocations\n\t\t\t);\n\t\tif (!shadowedLocations.infos.empty())\n\t\t\tm_errorReporter.warning(\n\t\t\t\t2519_error,\n\t\t\t\t*innerLocation,\n\t\t\t\t\"This declaration shadows an existing declaration.\",\n\t\t\t\tshadowedLocations\n\t\t\t);\n\t}\n}\n\nvoid NameAndTypeResolver::setScope(ASTNode const* _node)\n{\n\tm_currentScope = m_scopes[_node].get();\n}\n\nbool NameAndTypeResolver::resolveNamesAndTypesInternal(ASTNode& _node, bool _resolveInsideCode)\n{\n\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(&_node))\n\t{\n\t\tbool success = true;\n\t\tsetScope(contract->scope());\n\t\tsolAssert(!!m_currentScope, \"\");\n\t\tsolAssert(_resolveInsideCode, \"\");\n\n\t\tm_globalContext.setCurrentContract(*contract);\n\t\tif (!contract->isLibrary())\n\t\t\tupdateDeclaration(*m_globalContext.currentSuper());\n\t\tupdateDeclaration(*m_globalContext.currentThis());\n\n\t\tfor (ASTPointer<InheritanceSpecifier> const& baseContract: contract->baseContracts())\n\t\t\tif (!resolveNamesAndTypesInternal(*baseContract, true))\n\t\t\t\tsuccess = false;\n\n\t\tif (StorageLayoutSpecifier* storageLayoutSpecifier = contract->storageLayoutSpecifier())\n\t\t\tif (!resolveNamesAndTypesInternal(*storageLayoutSpecifier, true))\n\t\t\t\tsuccess = false;\n\n\t\tsetScope(contract);\n\n\t\tif (success)\n\t\t{\n\t\t\tlinearizeBaseContracts(*contract);\n\t\t\tstd::vector<ContractDefinition const*> properBases(\n\t\t\t\t++contract->annotation().linearizedBaseContracts.begin(),\n\t\t\t\tcontract->annotation().linearizedBaseContracts.end()\n\t\t\t);\n\n\t\t\tfor (ContractDefinition const* base: properBases)\n\t\t\t\timportInheritedScope(*base);\n\t\t}\n\n\t\t// these can contain code, only resolve parameters for now\n\t\tfor (ASTPointer<ASTNode> const& node: contract->subNodes())\n\t\t{\n\t\t\tsetScope(contract);\n\t\t\tif (!resolveNamesAndTypesInternal(*node, false))\n\t\t\t\tsuccess = false;\n\t\t}\n\n\t\tif (!success)\n\t\t\treturn false;\n\n\t\tsetScope(contract);\n\n\t\t// now resolve references inside the code\n\t\tfor (ASTPointer<ASTNode> const& node: contract->subNodes())\n\t\t{\n\t\t\tsetScope(contract);\n\t\t\tif (!resolveNamesAndTypesInternal(*node, true))\n\t\t\t\tsuccess = false;\n\t\t}\n\n\t\t// make \"this\" and \"super\" invisible.\n\t\tm_scopes[nullptr]->registerDeclaration(*m_globalContext.currentThis(), true, true);\n\t\tm_scopes[nullptr]->registerDeclaration(*m_globalContext.currentSuper(), true, true);\n\t\tm_globalContext.resetCurrentContract();\n\n\t\treturn success;\n\t}\n\telse\n\t{\n\t\tif (m_scopes.count(&_node))\n\t\t\tsetScope(&_node);\n\t\treturn ReferencesResolver(m_errorReporter, *this, m_evmVersion, _resolveInsideCode).resolve(_node);\n\t}\n}\n\nvoid NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base)\n{\n\tauto iterator = m_scopes.find(&_base);\n\tsolAssert(iterator != end(m_scopes), \"\");\n\tfor (auto const& nameAndDeclaration: iterator->second->declarations())\n\t\tfor (auto const& declaration: nameAndDeclaration.second)\n\t\t\t// Import if it was declared in the base, is not the constructor and is visible in derived classes\n\t\t\tif (declaration->scope() == &_base && declaration->isVisibleInDerivedContracts())\n\t\t\t\tif (!m_currentScope->registerDeclaration(*declaration, false, false))\n\t\t\t\t{\n\t\t\t\t\tSourceLocation firstDeclarationLocation;\n\t\t\t\t\tSourceLocation secondDeclarationLocation;\n\t\t\t\t\tDeclaration const* conflictingDeclaration = m_currentScope->conflictingDeclaration(*declaration);\n\t\t\t\t\tsolAssert(conflictingDeclaration, \"\");\n\n\t\t\t\t\t// Usual shadowing is not an error\n\t\t\t\t\tif (\n\t\t\t\t\t\tdynamic_cast<ModifierDefinition const*>(declaration) &&\n\t\t\t\t\t\tdynamic_cast<ModifierDefinition const*>(conflictingDeclaration)\n\t\t\t\t\t)\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t// Public state variable can override functions\n\t\t\t\t\tif (auto varDecl = dynamic_cast<VariableDeclaration const*>(conflictingDeclaration))\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tdynamic_cast<FunctionDefinition const*>(declaration) &&\n\t\t\t\t\t\t\tvarDecl->isStateVariable() &&\n\t\t\t\t\t\t\tvarDecl->isPublic()\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tif (declaration->location().start < conflictingDeclaration->location().start)\n\t\t\t\t\t{\n\t\t\t\t\t\tfirstDeclarationLocation = declaration->location();\n\t\t\t\t\t\tsecondDeclarationLocation = conflictingDeclaration->location();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfirstDeclarationLocation = conflictingDeclaration->location();\n\t\t\t\t\t\tsecondDeclarationLocation = declaration->location();\n\t\t\t\t\t}\n\n\t\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t\t9097_error,\n\t\t\t\t\t\tsecondDeclarationLocation,\n\t\t\t\t\t\tSecondarySourceLocation().append(\"The previous declaration is here:\", firstDeclarationLocation),\n\t\t\t\t\t\t\"Identifier already declared.\"\n\t\t\t\t\t);\n\t\t\t\t}\n}\n\nvoid NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract)\n{\n\t// order in the lists is from derived to base\n\t// list of lists to linearize, the last element is the list of direct bases\n\tstd::list<std::list<ContractDefinition const*>> input(1, std::list<ContractDefinition const*>{});\n\tfor (ASTPointer<InheritanceSpecifier> const& baseSpecifier: _contract.baseContracts())\n\t{\n\t\tIdentifierPath const& baseName = baseSpecifier->name();\n\t\tauto base = dynamic_cast<ContractDefinition const*>(baseName.annotation().referencedDeclaration);\n\t\tif (!base)\n\t\t\tm_errorReporter.fatalTypeError(8758_error, baseName.location(), \"Contract expected.\");\n\t\t// \"push_front\" has the effect that bases mentioned later can overwrite members of bases\n\t\t// mentioned earlier\n\t\tinput.back().push_front(base);\n\t\tstd::vector<ContractDefinition const*> const& basesBases = base->annotation().linearizedBaseContracts;\n\t\tif (basesBases.empty())\n\t\t\tm_errorReporter.fatalTypeError(2449_error, baseName.location(), \"Definition of base has to precede definition of derived contract\");\n\t\tinput.push_front(std::list<ContractDefinition const*>(basesBases.begin(), basesBases.end()));\n\t}\n\tinput.back().push_front(&_contract);\n\tstd::vector<ContractDefinition const*> result = cThreeMerge(input);\n\tif (result.empty())\n\t\tm_errorReporter.fatalTypeError(5005_error, _contract.location(), \"Linearization of inheritance graph impossible\");\n\t_contract.annotation().linearizedBaseContracts = result;\n}\n\ntemplate <class T>\nstd::vector<T const*> NameAndTypeResolver::cThreeMerge(std::list<std::list<T const*>>& _toMerge)\n{\n\t// returns true iff _candidate appears only as last element of the lists\n\tauto appearsOnlyAtHead = [&](T const* _candidate) -> bool\n\t{\n\t\tfor (std::list<T const*> const& bases: _toMerge)\n\t\t{\n\t\t\tsolAssert(!bases.empty(), \"\");\n\t\t\tif (find(++bases.begin(), bases.end(), _candidate) != bases.end())\n\t\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t};\n\t// returns the next candidate to append to the linearized list or nullptr on failure\n\tauto nextCandidate = [&]() -> T const*\n\t{\n\t\tfor (std::list<T const*> const& bases: _toMerge)\n\t\t{\n\t\t\tsolAssert(!bases.empty(), \"\");\n\t\t\tif (appearsOnlyAtHead(bases.front()))\n\t\t\t\treturn bases.front();\n\t\t}\n\t\treturn nullptr;\n\t};\n\t// removes the given contract from all lists\n\tauto removeCandidate = [&](T const* _candidate)\n\t{\n\t\tfor (auto it = _toMerge.begin(); it != _toMerge.end();)\n\t\t{\n\t\t\tit->remove(_candidate);\n\t\t\tif (it->empty())\n\t\t\t\tit = _toMerge.erase(it);\n\t\t\telse\n\t\t\t\t++it;\n\t\t}\n\t};\n\n\t_toMerge.remove_if([](std::list<T const*> const& _bases) { return _bases.empty(); });\n\tstd::vector<T const*> result;\n\twhile (!_toMerge.empty())\n\t{\n\t\tT const* candidate = nextCandidate();\n\t\tif (!candidate)\n\t\t\treturn std::vector<T const*>();\n\t\tresult.push_back(candidate);\n\t\tremoveCandidate(candidate);\n\t}\n\treturn result;\n}\n\n\tstd::string NameAndTypeResolver::similarNameSuggestions(ASTString const& _name) const\n{\n\treturn util::quotedAlternativesList(m_currentScope->similarNames(_name));\n}\n\nDeclarationRegistrationHelper::DeclarationRegistrationHelper(\n\tstd::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& _scopes,\n\tASTNode& _astRoot,\n\tErrorReporter& _errorReporter,\n\tGlobalContext& _globalContext,\n\tASTNode const* _currentScope\n):\n\tm_scopes(_scopes),\n\tm_currentScope(_currentScope),\n\tm_errorReporter(_errorReporter),\n\tm_globalContext(_globalContext)\n{\n\t_astRoot.accept(*this);\n\tsolAssert(m_currentScope == _currentScope, \"Scopes not correctly closed.\");\n}\n\nbool DeclarationRegistrationHelper::registerDeclaration(\n\tDeclarationContainer& _container,\n\tDeclaration const& _declaration,\n\tstd::string const* _name,\n\tSourceLocation const* _errorLocation,\n\tbool _inactive,\n\tErrorReporter& _errorReporter\n)\n{\n\tif (!_errorLocation)\n\t\t_errorLocation = &_declaration.location();\n\n\tstd::string name = _name ? *_name : _declaration.name();\n\n\t// We use \"invisible\" for both inactive variables in blocks and for members invisible in contracts.\n\t// They cannot both be true at the same time.\n\tsolAssert(!(_inactive && !_declaration.isVisibleInContract()), \"\");\n\n\tstatic std::set<std::string> illegalNames{\"_\", \"super\", \"this\"};\n\n\tif (illegalNames.count(name))\n\t{\n\t\tauto isPublicFunctionOrEvent = [](Declaration const* _d) -> bool\n\t\t{\n\t\t\tif (auto functionDefinition = dynamic_cast<FunctionDefinition const*>(_d))\n\t\t\t{\n\t\t\t\tif (!functionDefinition->isFree() && functionDefinition->isPublic())\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (dynamic_cast<EventDefinition const*>(_d))\n\t\t\t\treturn true;\n\n\t\t\treturn false;\n\t\t};\n\n\t\t// We allow an exception for public functions or events.\n\t\tif (!isPublicFunctionOrEvent(&_declaration))\n\t\t\t_errorReporter.declarationError(\n\t\t\t\t3726_error,\n\t\t\t\t*_errorLocation,\n\t\t\t\t\"The name \\\"\" + name + \"\\\" is reserved.\"\n\t\t\t);\n\t}\n\n\tif (!_container.registerDeclaration(_declaration, _name, _errorLocation, !_declaration.isVisibleInContract() || _inactive, false))\n\t{\n\t\tSourceLocation firstDeclarationLocation;\n\t\tSourceLocation secondDeclarationLocation;\n\t\tDeclaration const* conflictingDeclaration = _container.conflictingDeclaration(_declaration, _name);\n\t\tsolAssert(conflictingDeclaration, \"\");\n\t\tbool const comparable =\n\t\t\t_errorLocation->sourceName &&\n\t\t\tconflictingDeclaration->location().sourceName &&\n\t\t\t*_errorLocation->sourceName == *conflictingDeclaration->location().sourceName;\n\t\tif (comparable && _errorLocation->start < conflictingDeclaration->location().start)\n\t\t{\n\t\t\tfirstDeclarationLocation = *_errorLocation;\n\t\t\tsecondDeclarationLocation = conflictingDeclaration->location();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfirstDeclarationLocation = conflictingDeclaration->location();\n\t\t\tsecondDeclarationLocation = *_errorLocation;\n\t\t}\n\n\t\t_errorReporter.declarationError(\n\t\t\t2333_error,\n\t\t\tsecondDeclarationLocation,\n\t\t\tSecondarySourceLocation().append(\"The previous declaration is here:\", firstDeclarationLocation),\n\t\t\t\"Identifier already declared.\"\n\t\t);\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool DeclarationRegistrationHelper::visit(SourceUnit& _sourceUnit)\n{\n\tif (!m_scopes[&_sourceUnit])\n\t\t// By importing, it is possible that the container already exists.\n\t\tm_scopes[&_sourceUnit] = std::make_shared<DeclarationContainer>(m_currentScope, m_scopes[m_currentScope].get());\n\treturn ASTVisitor::visit(_sourceUnit);\n}\n\nvoid DeclarationRegistrationHelper::endVisit(SourceUnit& _sourceUnit)\n{\n\tASTVisitor::endVisit(_sourceUnit);\n}\n\nbool DeclarationRegistrationHelper::visit(ImportDirective& _import)\n{\n\tSourceUnit const* importee = _import.annotation().sourceUnit;\n\tsolAssert(!!importee, \"\");\n\tif (!m_scopes[importee])\n\t\tm_scopes[importee] = std::make_shared<DeclarationContainer>(nullptr, m_scopes[nullptr].get());\n\tm_scopes[&_import] = m_scopes[importee];\n\tASTVisitor::visit(_import);\n\treturn false; // Do not recurse into child nodes (Identifier for symbolAliases)\n}\n\nbool DeclarationRegistrationHelper::visit(ContractDefinition& _contract)\n{\n\tm_globalContext.setCurrentContract(_contract);\n\tm_scopes[nullptr]->registerDeclaration(*m_globalContext.currentThis(), false, true);\n\tm_scopes[nullptr]->registerDeclaration(*m_globalContext.currentSuper(), false, true);\n\tm_currentContract = &_contract;\n\n\treturn ASTVisitor::visit(_contract);\n}\n\nvoid DeclarationRegistrationHelper::endVisit(ContractDefinition& _contract)\n{\n\t// make \"this\" and \"super\" invisible.\n\tm_scopes[nullptr]->registerDeclaration(*m_globalContext.currentThis(), true, true);\n\tm_scopes[nullptr]->registerDeclaration(*m_globalContext.currentSuper(), true, true);\n\tm_globalContext.resetCurrentContract();\n\tm_currentContract = nullptr;\n\tASTVisitor::endVisit(_contract);\n}\n\nvoid DeclarationRegistrationHelper::endVisit(VariableDeclarationStatement& _variableDeclarationStatement)\n{\n\t// Register the local variables with the function\n\t// This does not fit here perfectly, but it saves us another AST visit.\n\tsolAssert(m_currentFunction, \"Variable declaration without function.\");\n\tfor (ASTPointer<VariableDeclaration> const& var: _variableDeclarationStatement.declarations())\n\t\tif (var)\n\t\t\tm_currentFunction->addLocalVariable(*var);\n\tASTVisitor::endVisit(_variableDeclarationStatement);\n}\n\nbool DeclarationRegistrationHelper::visitNode(ASTNode& _node)\n{\n\tif (auto const* scopable = dynamic_cast<Scopable const*>(&_node))\n\t\tsolAssert(scopable->annotation().scope == m_currentScope, \"\");\n\n\tif (auto* declaration = dynamic_cast<Declaration*>(&_node))\n\t\tregisterDeclaration(*declaration);\n\n\tif (auto* annotation = dynamic_cast<TypeDeclarationAnnotation*>(&_node.annotation()))\n\t{\n\t\tstd::string canonicalName = dynamic_cast<Declaration const&>(_node).name();\n\t\tsolAssert(!canonicalName.empty(), \"\");\n\n\t\tfor (\n\t\t\tASTNode const* scope = m_currentScope;\n\t\t\tscope != nullptr;\n\t\t\tscope = m_scopes[scope]->enclosingNode()\n\t\t)\n\t\t\tif (auto decl = dynamic_cast<Declaration const*>(scope))\n\t\t\t{\n\t\t\t\tsolAssert(!decl->name().empty(), \"\");\n\t\t\t\tcanonicalName = decl->name() + \".\" + canonicalName;\n\t\t\t}\n\n\t\tannotation->canonicalName = canonicalName;\n\t}\n\n\tif (dynamic_cast<ScopeOpener const*>(&_node))\n\t\tenterNewSubScope(_node);\n\n\tif (auto* variableScope = dynamic_cast<VariableScope*>(&_node))\n\t\tm_currentFunction = variableScope;\n\n\treturn true;\n}\n\nvoid DeclarationRegistrationHelper::endVisitNode(ASTNode& _node)\n{\n\tif (dynamic_cast<ScopeOpener const*>(&_node))\n\t\tcloseCurrentScope();\n\tif (dynamic_cast<VariableScope*>(&_node))\n\t\tm_currentFunction = nullptr;\n}\n\nvoid DeclarationRegistrationHelper::enterNewSubScope(ASTNode& _subScope)\n{\n\tif (m_scopes.count(&_subScope))\n\t\t// Source units are the only AST nodes for which containers can be created from multiple places due to imports.\n\t\tsolAssert(dynamic_cast<SourceUnit const*>(&_subScope), \"Unexpected scope type.\");\n\telse\n\t{\n\t\tbool newlyAdded = m_scopes.emplace(\n\t\t\t&_subScope,\n\t\t\tstd::make_shared<DeclarationContainer>(m_currentScope, m_scopes[m_currentScope].get())\n\t\t).second;\n\t\tsolAssert(newlyAdded, \"Unable to add new scope.\");\n\t}\n\tm_currentScope = &_subScope;\n}\n\nvoid DeclarationRegistrationHelper::closeCurrentScope()\n{\n\tsolAssert(m_currentScope && m_scopes.count(m_currentScope), \"Closed non-existing scope.\");\n\tm_currentScope = m_scopes[m_currentScope]->enclosingNode();\n}\n\nvoid DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaration)\n{\n\tsolAssert(m_currentScope && m_scopes.count(m_currentScope), \"No current scope.\");\n\tsolAssert(m_currentScope == _declaration.scope(), \"Unexpected current scope.\");\n\n\t// Functions defined inside quantifiers should be visible in the scope containing the quantifier\n\t// TODO: Turn it into a more generic mechanism in the same vein as Scopable and ScopeOpener if\n\t// it turns out we need more special-casing here.\n\tauto const* quantifier = dynamic_cast<ForAllQuantifier const*>(m_currentScope);\n\tauto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(&_declaration);\n\tif (quantifier && functionDefinition)\n\t{\n\t\tsolAssert(quantifier->scope());\n\t\tsolAssert(\n\t\t\t// forall quantifiers cannot be used in block scope so the declaration is always active.\n\t\t\t!dynamic_cast<Block const*>(quantifier->scope()) &&\n\t\t\t!dynamic_cast<ForStatement const*>(quantifier->scope())\n\t\t);\n\n\t\t// NOTE: We're registering the function outside of its scope(). This will only affect\n\t\t// name lookups. A more general alternative would be to modify Scoper to simply assign it\n\t\t// that scope in the first place, but this would complicate the AST traversal here, which\n\t\t// currently assumes that scopes follow ScopeOpener nesting.\n\t\tregisterDeclaration(*m_scopes.at(quantifier->scope()), _declaration, nullptr, nullptr, false /* inactive */, m_errorReporter);\n\t}\n\telse\n\t{\n\t\t// Register declaration as inactive if we are in block scope.\n\t\tbool inactive =\n\t\t\t(dynamic_cast<Block const*>(m_currentScope) || dynamic_cast<ForStatement const*>(m_currentScope));\n\n\t\tregisterDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, inactive, m_errorReporter);\n\t}\n\n\tsolAssert(_declaration.annotation().scope == m_currentScope, \"\");\n\tsolAssert(_declaration.annotation().contract == m_currentContract, \"\");\n}\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/NameAndTypeResolver.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Parser part that determines the declarations corresponding to names and the types of expressions.\n */\n\n#pragma once\n\n#include <libsolidity/analysis/DeclarationContainer.h>\n#include <libsolidity/analysis/GlobalContext.h>\n#include <libsolidity/analysis/ReferencesResolver.h>\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <libsolidity/ast/ASTVisitor.h>\n\n#include <liblangutil/EVMVersion.h>\n\n#include <list>\n#include <map>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend\n{\n\n/**\n * Resolves name references, typenames and sets the (explicitly given) types for all variable\n * declarations.\n */\nclass NameAndTypeResolver\n{\npublic:\n\t/// Noncopyable.\n\tNameAndTypeResolver(NameAndTypeResolver const&) = delete;\n\tNameAndTypeResolver& operator=(NameAndTypeResolver const&) = delete;\n\n\t/// Creates the resolver with the given declarations added to the global scope.\n\t/// @param _scopes mapping of scopes to be used (usually default constructed), these\n\t/// are filled during the lifetime of this object.\n\tNameAndTypeResolver(\n\t\tGlobalContext& _globalContext,\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tlangutil::ErrorReporter& _errorReporter,\n\t\tbool _experimentalSolidity\n\t);\n\t/// Registers all declarations found in the AST node, usually a source unit.\n\t/// @returns false in case of error.\n\t/// @param _currentScope should be nullptr but can be used to inject new declarations into\n\t/// existing scopes, used by the snippets feature.\n\tbool registerDeclarations(SourceUnit& _sourceUnit, ASTNode const* _currentScope = nullptr);\n\t/// Applies the effect of import directives.\n\tbool performImports(SourceUnit& _sourceUnit, std::map<std::string, SourceUnit const*> const& _sourceUnits);\n\t/// Resolves all names and types referenced from the given Source Node.\n\t/// @returns false in case of error.\n\tbool resolveNamesAndTypes(SourceUnit& _source);\n\t/// Updates the given global declaration (used for \"this\"). Not to be used with declarations\n\t/// that create their own scope.\n\t/// @returns false in case of error.\n\tbool updateDeclaration(Declaration const& _declaration);\n\t/// Activates a previously inactive (invisible) variable. To be used in C99 scoping for\n\t/// VariableDeclarationStatements.\n\tvoid activateVariable(std::string const& _name);\n\n\t/// Resolves the given @a _name inside the scope @a _scope. If @a _scope is omitted,\n\t/// the global scope is used (i.e. the one containing only the pre-defined global variables).\n\t/// @returns a pointer to the declaration on success or nullptr on failure.\n\t/// SHOULD only be used for testing.\n\tstd::vector<Declaration const*> resolveName(ASTString const& _name, ASTNode const* _scope = nullptr) const;\n\n\t/// Resolves a name in the \"current\" scope, but also searches parent scopes.\n\t/// Should only be called during the initial resolving phase.\n\tstd::vector<Declaration const*> nameFromCurrentScope(ASTString const& _name, bool _includeInvisibles = false) const;\n\n\t/// Resolves a path starting from the \"current\" scope, but also searches parent scopes.\n\t/// Should only be called during the initial resolving phase.\n\t/// @note Returns a null pointer if any component in the path was not unique or not found.\n\tDeclaration const* pathFromCurrentScope(std::vector<ASTString> const& _path) const;\n\t/// Resolves a path starting from the \"current\" scope, but also searches parent scopes.\n\t/// Should only be called during the initial resolving phase.\n\t/// @note Returns an empty vector if any component in the path was non-unique or not found. Otherwise, all declarations along the path are returned.\n\tstd::vector<Declaration const*> pathFromCurrentScopeWithAllDeclarations(std::vector<ASTString> const& _path, bool _includeInvisibles = false) const;\n\n\t/// Generate and store warnings about declarations with the same name.\n\tvoid warnHomonymDeclarations() const;\n\n\t/// @returns a list of similar identifiers in the current and enclosing scopes. May return empty string if no suggestions.\n\tstd::string similarNameSuggestions(ASTString const& _name) const;\n\n\t/// Sets the current scope.\n\tvoid setScope(ASTNode const* _node);\n\n\tbool experimentalSolidity() const { return m_experimentalSolidity; }\nprivate:\n\t/// Internal version of @a resolveNamesAndTypes (called from there) throws exceptions on fatal errors.\n\tbool resolveNamesAndTypesInternal(ASTNode& _node, bool _resolveInsideCode = true);\n\n\t/// Imports all members declared directly in the given contract (i.e. does not import inherited members)\n\t/// into the current scope if they are not present already.\n\tvoid importInheritedScope(ContractDefinition const& _base);\n\n\t/// Computes \"C3-Linearization\" of base contracts and stores it inside the contract. Reports errors if any\n\tvoid linearizeBaseContracts(ContractDefinition& _contract);\n\t/// Computes the C3-merge of the given list of lists of bases.\n\t/// @returns the linearized vector or an empty vector if linearization is not possible.\n\ttemplate <class T>\n\tstatic std::vector<T const*> cThreeMerge(std::list<std::list<T const*>>& _toMerge);\n\n\t/// Maps nodes declaring a scope to scopes, i.e. ContractDefinition and FunctionDeclaration,\n\t/// where nullptr denotes the global scope. Note that structs are not scope since they do\n\t/// not contain code.\n\t/// Aliases (for example `import \"x\" as y;`) create multiple pointers to the same scope.\n\tstd::map<ASTNode const*, std::shared_ptr<DeclarationContainer>> m_scopes;\n\n\tlangutil::EVMVersion m_evmVersion;\n\tDeclarationContainer* m_currentScope = nullptr;\n\tlangutil::ErrorReporter& m_errorReporter;\n\tGlobalContext& m_globalContext;\n\tbool m_experimentalSolidity = false;\n};\n\n/**\n * Traverses the given AST upon construction and fills _scopes with all declarations inside the\n * AST.\n */\nclass DeclarationRegistrationHelper: private ASTVisitor\n{\npublic:\n\t/// Registers declarations in their scopes and creates new scopes as a side-effect\n\t/// of construction.\n\t/// @param _currentScope should be nullptr if we start at SourceUnit, but can be different\n\t/// to inject new declarations into an existing scope, used by snippets.\n\tDeclarationRegistrationHelper(\n\t\tstd::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& _scopes,\n\t\tASTNode& _astRoot,\n\t\tlangutil::ErrorReporter& _errorReporter,\n\t\tGlobalContext& _globalContext,\n\t\tASTNode const* _currentScope = nullptr\n\t);\n\n\tstatic bool registerDeclaration(\n\t\tDeclarationContainer& _container,\n\t\tDeclaration const& _declaration,\n\t\tstd::string const* _name,\n\t\tlangutil::SourceLocation const* _errorLocation,\n\t\tbool _inactive,\n\t\tlangutil::ErrorReporter& _errorReporter\n\t);\n\nprivate:\n\tbool visit(SourceUnit& _sourceUnit) override;\n\tvoid endVisit(SourceUnit& _sourceUnit) override;\n\tbool visit(ImportDirective& _import) override;\n\tbool visit(ContractDefinition& _contract) override;\n\tvoid endVisit(ContractDefinition& _contract) override;\n\tvoid endVisit(VariableDeclarationStatement& _variableDeclarationStatement) override;\n\n\tbool visitNode(ASTNode& _node) override;\n\tvoid endVisitNode(ASTNode& _node) override;\n\n\n\tvoid enterNewSubScope(ASTNode& _subScope);\n\tvoid closeCurrentScope();\n\tvoid registerDeclaration(Declaration& _declaration);\n\n\tstatic bool isOverloadedFunction(Declaration const& _declaration1, Declaration const& _declaration2);\n\n\tstd::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& m_scopes;\n\tASTNode const* m_currentScope = nullptr;\n\tVariableScope* m_currentFunction = nullptr;\n\tContractDefinition const* m_currentContract = nullptr;\n\tlangutil::ErrorReporter& m_errorReporter;\n\tGlobalContext& m_globalContext;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/OverrideChecker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that verifies overloads, abstract contracts, function clashes and others\n * checks at contract or function level.\n */\n\n#include <libsolidity/analysis/OverrideChecker.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/analysis/TypeChecker.h>\n#include <liblangutil/ErrorReporter.h>\n#include <libsolutil/Visitor.h>\n\n#include <boost/algorithm/string/predicate.hpp>\n\n\nusing namespace solidity;\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\n\nusing solidity::util::GenericVisitor;\nusing solidity::util::contains_if;\nusing solidity::util::joinHumanReadable;\n\nnamespace\n{\n\n// Helper struct to do a search by name\nstruct MatchByName\n{\n\tstd::string const& m_name;\n\tbool operator()(OverrideProxy const& _item)\n\t{\n\t\treturn _item.name() == m_name;\n\t}\n};\n\n/**\n * Construct the override graph for this signature.\n * Reserve node 0 for the current contract and node\n * 1 for an artificial top node to which all override paths\n * connect at the end.\n */\nstruct OverrideGraph\n{\n\tOverrideGraph(std::set<OverrideProxy> const& _baseCallables)\n\t{\n\t\tfor (auto const& baseFunction: _baseCallables)\n\t\t\taddEdge(0, visit(baseFunction));\n\t}\n\tstd::map<OverrideProxy, int> nodes;\n\tstd::map<int, OverrideProxy> nodeInv;\n\tstd::map<int, std::set<int>> edges;\n\tsize_t numNodes = 2;\n\tvoid addEdge(int _a, int _b)\n\t{\n\t\tedges[_a].insert(_b);\n\t\tedges[_b].insert(_a);\n\t}\nprivate:\n\t/// Completes the graph starting from @a _function and\n\t/// @returns the node ID.\n\tint visit(OverrideProxy const& _function)\n\t{\n\t\tauto it = nodes.find(_function);\n\t\tif (it != nodes.end())\n\t\t\treturn it->second;\n\t\tint currentNode = static_cast<int>(numNodes++);\n\t\tnodes[_function] = currentNode;\n\t\tnodeInv[currentNode] = _function;\n\n\t\tif (!_function.baseFunctions().empty())\n\t\t\tfor (auto const& baseFunction: _function.baseFunctions())\n\t\t\t\taddEdge(currentNode, visit(baseFunction));\n\t\telse\n\t\t\taddEdge(currentNode, 1);\n\n\t\treturn currentNode;\n\t}\n};\n\n/**\n * Detect cut vertices following https://en.wikipedia.org/wiki/Biconnected_component#Pseudocode\n * Can ignore the root node, since it is never a cut vertex in our case.\n */\nstruct CutVertexFinder\n{\n\tCutVertexFinder(OverrideGraph const& _graph): m_graph(_graph)\n\t{\n\t\trun();\n\t}\n\tstd::set<OverrideProxy> const& cutVertices() const { return m_cutVertices; }\n\nprivate:\n\tOverrideGraph const& m_graph;\n\n\tstd::vector<bool> m_visited = std::vector<bool>(m_graph.numNodes, false);\n\tstd::vector<int> m_depths = std::vector<int>(m_graph.numNodes, -1);\n\tstd::vector<int> m_low = std::vector<int>(m_graph.numNodes, -1);\n\tstd::vector<int> m_parent = std::vector<int>(m_graph.numNodes, -1);\n\tstd::set<OverrideProxy> m_cutVertices{};\n\n\tvoid run(size_t _u = 0, size_t _depth = 0)\n\t{\n\t\tm_visited.at(_u) = true;\n\t\tm_depths.at(_u) = m_low.at(_u) = static_cast<int>(_depth);\n\t\tfor (int const v: m_graph.edges.at(static_cast<int>(_u)))\n\t\t{\n\t\t\tauto const vInd = static_cast<size_t>(v);\n\t\t\tif (!m_visited.at(vInd))\n\t\t\t{\n\t\t\t\tm_parent[vInd] = static_cast<int>(_u);\n\t\t\t\trun(vInd, _depth + 1);\n\t\t\t\tif (m_low[vInd] >= m_depths[_u] && m_parent[_u] != -1)\n\t\t\t\t\tm_cutVertices.insert(m_graph.nodeInv.at(static_cast<int>(_u)));\n\t\t\t\tm_low[_u] = std::min(m_low[_u], m_low[vInd]);\n\t\t\t}\n\t\t\telse if (v != m_parent[_u])\n\t\t\t\tm_low[_u] = std::min(m_low[_u], m_depths[vInd]);\n\t\t}\n\t}\n};\n\nstd::vector<ContractDefinition const*> resolveDirectBaseContracts(ContractDefinition const& _contract)\n{\n\tstd::vector<ContractDefinition const*> resolvedContracts;\n\n\tfor (ASTPointer<InheritanceSpecifier> const& specifier: _contract.baseContracts())\n\t{\n\t\tDeclaration const* baseDecl =\n\t\t\tspecifier->name().annotation().referencedDeclaration;\n\t\tauto contract = dynamic_cast<ContractDefinition const*>(baseDecl);\n\t\tif (contract)\n\t\t\tresolvedContracts.emplace_back(contract);\n\t}\n\n\treturn resolvedContracts;\n}\n\nstd::vector<ASTPointer<IdentifierPath>> sortByContract(std::vector<ASTPointer<IdentifierPath>> const& _list)\n{\n\tauto sorted = _list;\n\n\tstable_sort(sorted.begin(), sorted.end(),\n\t\t[] (ASTPointer<IdentifierPath> _a, ASTPointer<IdentifierPath> _b) {\n\t\t\tif (!_a || !_b)\n\t\t\t\treturn _a < _b;\n\n\t\t\tDeclaration const* aDecl = _a->annotation().referencedDeclaration;\n\t\t\tDeclaration const* bDecl = _b->annotation().referencedDeclaration;\n\n\t\t\tif (!aDecl || !bDecl)\n\t\t\t\treturn aDecl < bDecl;\n\n\t\t\treturn aDecl->id() < bDecl->id();\n\t\t}\n\t);\n\n\treturn sorted;\n}\n\nOverrideProxy makeOverrideProxy(CallableDeclaration const& _callable)\n{\n\tif (auto const* fun = dynamic_cast<FunctionDefinition const*>(&_callable))\n\t\treturn OverrideProxy{fun};\n\telse if (auto const* mod = dynamic_cast<ModifierDefinition const*>(&_callable))\n\t\treturn OverrideProxy{mod};\n\telse\n\t\tsolAssert(false, \"Invalid call to makeOverrideProxy.\");\n\treturn {};\n}\n\n}\n\nbool OverrideProxy::operator<(OverrideProxy const& _other) const\n{\n\treturn id() < _other.id();\n}\n\nbool OverrideProxy::isVariable() const\n{\n\treturn std::holds_alternative<VariableDeclaration const*>(m_item);\n}\n\nbool OverrideProxy::isFunction() const\n{\n\treturn std::holds_alternative<FunctionDefinition const*>(m_item);\n}\n\nbool OverrideProxy::isModifier() const\n{\n\treturn std::holds_alternative<ModifierDefinition const*>(m_item);\n}\n\nbool OverrideProxy::CompareBySignature::operator()(OverrideProxy const& _a, OverrideProxy const& _b) const\n{\n\treturn _a.overrideComparator() < _b.overrideComparator();\n}\n\nsize_t OverrideProxy::id() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](auto const* _item) -> size_t { return static_cast<size_t>(_item->id()); }\n\t}, m_item);\n}\n\nstd::shared_ptr<OverrideSpecifier> OverrideProxy::overrides() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](auto const* _item) { return _item->overrides(); }\n\t}, m_item);\n}\n\nstd::set<OverrideProxy> OverrideProxy::baseFunctions() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](auto const* _item) -> std::set<OverrideProxy> {\n\t\t\tstd::set<OverrideProxy> ret;\n\t\t\tfor (auto const* f: _item->annotation().baseFunctions)\n\t\t\t\tret.insert(makeOverrideProxy(*f));\n\t\t\treturn ret;\n\t\t}\n\t}, m_item);\n}\n\nvoid OverrideProxy::storeBaseFunction(OverrideProxy const& _base) const\n{\n\tstd::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const* _item) {\n\t\t\t_item->annotation().baseFunctions.emplace(std::get<FunctionDefinition const*>(_base.m_item));\n\t\t},\n\t\t[&](ModifierDefinition const* _item) {\n\t\t\t_item->annotation().baseFunctions.emplace(std::get<ModifierDefinition const*>(_base.m_item));\n\t\t},\n\t\t[&](VariableDeclaration const* _item) {\n\t\t\t_item->annotation().baseFunctions.emplace(std::get<FunctionDefinition const*>(_base.m_item));\n\t\t}\n\t}, m_item);\n}\n\nstd::string const& OverrideProxy::name() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](auto const* _item) -> std::string const& { return _item->name(); }\n\t}, m_item);\n}\n\nContractDefinition const& OverrideProxy::contract() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](auto const* _item) -> ContractDefinition const& {\n\t\t\treturn dynamic_cast<ContractDefinition const&>(*_item->scope());\n\t\t}\n\t}, m_item);\n}\n\nstd::string const& OverrideProxy::contractName() const\n{\n\treturn contract().name();\n}\n\nVisibility OverrideProxy::visibility() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const* _item) { return _item->visibility(); },\n\t\t[&](ModifierDefinition const* _item) { return _item->visibility(); },\n\t\t[&](VariableDeclaration const*) { return Visibility::External; }\n\t}, m_item);\n}\n\nStateMutability OverrideProxy::stateMutability() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const* _item) { return _item->stateMutability(); },\n\t\t[&](ModifierDefinition const*) { solAssert(false, \"Requested state mutability from modifier.\"); return StateMutability{}; },\n\t\t[&](VariableDeclaration const* _var) { return _var->isConstant() ? StateMutability::Pure : StateMutability::View; }\n\t}, m_item);\n}\n\nbool OverrideProxy::virtualSemantics() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const* _item) { return _item->virtualSemantics(); },\n\t\t[&](ModifierDefinition const* _item) { return _item->virtualSemantics(); },\n\t\t[&](VariableDeclaration const*) { return false; }\n\t}, m_item);\n}\n\nToken OverrideProxy::functionKind() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const* _item) { return _item->kind(); },\n\t\t[&](ModifierDefinition const*) { return Token::Function; },\n\t\t[&](VariableDeclaration const*) { return Token::Function; }\n\t}, m_item);\n}\n\nFunctionType const* OverrideProxy::externalFunctionType() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const* _item) { return FunctionType(*_item).asExternallyCallableFunction(false); },\n\t\t[&](VariableDeclaration const* _item) { return FunctionType(*_item).asExternallyCallableFunction(false); },\n\t\t[&](ModifierDefinition const*) -> FunctionType const* { solAssert(false, \"Requested function type of modifier.\"); return nullptr; }\n\t}, m_item);\n}\n\nFunctionType const* OverrideProxy::originalFunctionType() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const* _item) { return TypeProvider::function(*_item); },\n\t\t[&](VariableDeclaration const*) -> FunctionType const* { solAssert(false, \"Requested specific function type of variable.\"); return nullptr; },\n\t\t[&](ModifierDefinition const*) -> FunctionType const* { solAssert(false, \"Requested specific function type of modifier.\"); return nullptr; }\n\t}, m_item);\n}\n\nModifierType const* OverrideProxy::modifierType() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const*) -> ModifierType const* { solAssert(false, \"Requested modifier type of function.\"); return nullptr; },\n\t\t[&](VariableDeclaration const*) -> ModifierType const* { solAssert(false, \"Requested modifier type of variable.\"); return nullptr; },\n\t\t[&](ModifierDefinition const* _modifier) -> ModifierType const* { return TypeProvider::modifier(*_modifier); }\n\t}, m_item);\n}\n\n\nDeclaration const* OverrideProxy::declaration() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const* _function) -> Declaration const* { return _function; },\n\t\t[&](VariableDeclaration const* _variable) -> Declaration const* { return _variable; },\n\t\t[&](ModifierDefinition const* _modifier) -> Declaration const* { return _modifier; }\n\t}, m_item);\n}\n\nSourceLocation const& OverrideProxy::location() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](auto const* _item) -> SourceLocation const& { return _item->location(); }\n\t}, m_item);\n}\n\nstd::string OverrideProxy::astNodeName() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const*) { return \"function\"; },\n\t\t[&](ModifierDefinition const*) { return \"modifier\"; },\n\t\t[&](VariableDeclaration const*) { return \"public state variable\"; },\n\t}, m_item);\n}\n\nstd::string OverrideProxy::astNodeNameCapitalized() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const*) { return \"Function\"; },\n\t\t[&](ModifierDefinition const*) { return \"Modifier\"; },\n\t\t[&](VariableDeclaration const*) { return \"Public state variable\"; },\n\t}, m_item);\n}\n\nstd::string OverrideProxy::distinguishingProperty() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const*) { return \"name and parameter types\"; },\n\t\t[&](ModifierDefinition const*) { return \"name\"; },\n\t\t[&](VariableDeclaration const*) { return \"name and parameter types\"; },\n\t}, m_item);\n}\n\nbool OverrideProxy::unimplemented() const\n{\n\treturn std::visit(GenericVisitor{\n\t\t[&](FunctionDefinition const* _item) { return !_item->isImplemented(); },\n\t\t[&](ModifierDefinition const* _item) { return !_item->isImplemented(); },\n\t\t[&](VariableDeclaration const*) { return false; }\n\t}, m_item);\n}\n\nbool OverrideProxy::OverrideComparator::operator<(OverrideComparator const& _other) const\n{\n\tif (name != _other.name)\n\t\treturn name < _other.name;\n\n\tif (!functionKind || !_other.functionKind)\n\t\treturn false;\n\n\tif (functionKind != _other.functionKind)\n\t\treturn *functionKind < *_other.functionKind;\n\n\t// Parameters do not matter for non-regular functions.\n\tif (functionKind != Token::Function)\n\t\treturn false;\n\n\tif (!parameterTypes || !_other.parameterTypes)\n\t\treturn false;\n\n\treturn boost::lexicographical_compare(*parameterTypes, *_other.parameterTypes);\n}\n\nOverrideProxy::OverrideComparator const& OverrideProxy::overrideComparator() const\n{\n\tif (!m_comparator)\n\t{\n\t\tm_comparator = std::make_shared<OverrideComparator>(std::visit(GenericVisitor{\n\t\t\t[&](FunctionDefinition const* _function)\n\t\t\t{\n\t\t\t\tstd::vector<std::string> paramTypes;\n\t\t\t\tfor (Type const* t: externalFunctionType()->parameterTypes())\n\t\t\t\t\tparamTypes.emplace_back(t->richIdentifier());\n\t\t\t\treturn OverrideComparator{\n\t\t\t\t\t_function->name(),\n\t\t\t\t\t_function->kind(),\n\t\t\t\t\tstd::move(paramTypes)\n\t\t\t\t};\n\t\t\t},\n\t\t\t[&](VariableDeclaration const* _var)\n\t\t\t{\n\t\t\t\tstd::vector<std::string> paramTypes;\n\t\t\t\tfor (Type const* t: externalFunctionType()->parameterTypes())\n\t\t\t\t\tparamTypes.emplace_back(t->richIdentifier());\n\t\t\t\treturn OverrideComparator{\n\t\t\t\t\t_var->name(),\n\t\t\t\t\tToken::Function,\n\t\t\t\t\tstd::move(paramTypes)\n\t\t\t\t};\n\t\t\t},\n\t\t\t[&](ModifierDefinition const* _mod)\n\t\t\t{\n\t\t\t\treturn OverrideComparator{\n\t\t\t\t\t_mod->name(),\n\t\t\t\t\t{},\n\t\t\t\t\t{}\n\t\t\t\t};\n\t\t\t}\n\t\t}, m_item));\n\t}\n\n\treturn *m_comparator;\n}\n\nbool OverrideChecker::CompareByID::operator()(ContractDefinition const* _a, ContractDefinition const* _b) const\n{\n\tif (!_a || !_b)\n\t\treturn _a < _b;\n\n\treturn _a->id() < _b->id();\n}\n\nvoid OverrideChecker::check(ContractDefinition const& _contract)\n{\n\tcheckIllegalOverrides(_contract);\n\tcheckAmbiguousOverrides(_contract);\n}\n\nvoid OverrideChecker::checkIllegalOverrides(ContractDefinition const& _contract)\n{\n\tOverrideProxyBySignatureMultiSet const& inheritedFuncs = inheritedFunctions(_contract);\n\tOverrideProxyBySignatureMultiSet const& inheritedMods = inheritedModifiers(_contract);\n\n\tfor (ModifierDefinition const* modifier: _contract.functionModifiers())\n\t{\n\t\tif (contains_if(inheritedFuncs, MatchByName{modifier->name()}))\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t5631_error,\n\t\t\t\tmodifier->location(),\n\t\t\t\t\"Override changes function or public state variable to modifier.\"\n\t\t\t);\n\n\t\tcheckOverrideList(OverrideProxy{modifier}, inheritedMods);\n\t}\n\n\tfor (FunctionDefinition const* function: _contract.definedFunctions())\n\t{\n\t\tif (function->isConstructor())\n\t\t\tcontinue;\n\n\t\tif (contains_if(inheritedMods, MatchByName{function->name()}))\n\t\t\tm_errorReporter.typeError(1469_error, function->location(), \"Override changes modifier to function.\");\n\n\t\tcheckOverrideList(OverrideProxy{function}, inheritedFuncs);\n\t}\n\tfor (auto const* stateVar: _contract.stateVariables())\n\t{\n\t\tif (!stateVar->isPublic())\n\t\t{\n\t\t\tif (stateVar->overrides())\n\t\t\t\tm_errorReporter.typeError(8022_error, stateVar->location(), \"Override can only be used with public state variables.\");\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (contains_if(inheritedMods, MatchByName{stateVar->name()}))\n\t\t\tm_errorReporter.typeError(1456_error, stateVar->location(), \"Override changes modifier to public state variable.\");\n\n\t\tcheckOverrideList(OverrideProxy{stateVar}, inheritedFuncs);\n\t}\n\n}\n\nvoid OverrideChecker::checkOverride(OverrideProxy const& _overriding, OverrideProxy const& _super)\n{\n\tsolAssert(_super.isModifier() == _overriding.isModifier(), \"\");\n\n\tif (_super.isFunction() || _super.isModifier())\n\t\t_overriding.storeBaseFunction(_super);\n\n\tif (_overriding.isModifier() && *_overriding.modifierType() != *_super.modifierType())\n\t\tm_errorReporter.typeError(\n\t\t\t1078_error,\n\t\t\t_overriding.location(),\n\t\t\t\"Override changes modifier signature.\"\n\t\t);\n\n\tif (!_overriding.overrides() && !(_super.isFunction() && _super.contract().isInterface()))\n\t\toverrideError(\n\t\t\t_overriding,\n\t\t\t_super,\n\t\t\t9456_error,\n\t\t\t\"Overriding \" + _overriding.astNodeName() + \" is missing \\\"override\\\" specifier.\",\n\t\t\t\"Overridden \" + _overriding.astNodeName() + \" is here:\"\n\t\t);\n\n\tif (_super.isVariable())\n\t\toverrideError(\n\t\t\t_super,\n\t\t\t_overriding,\n\t\t\t1452_error,\n\t\t\t\"Cannot override public state variable.\",\n\t\t\t\"Overriding \" + _overriding.astNodeName() + \" is here:\"\n\t\t);\n\telse if (!_super.virtualSemantics())\n\t\toverrideError(\n\t\t\t_super,\n\t\t\t_overriding,\n\t\t\t4334_error,\n\t\t\t\"Trying to override non-virtual \" + _super.astNodeName() + \". Did you forget to add \\\"virtual\\\"?\",\n\t\t\t\"Overriding \" + _overriding.astNodeName() + \" is here:\"\n\t\t);\n\n\tif (_overriding.isVariable())\n\t{\n\t\tif (_super.visibility() != Visibility::External)\n\t\t\toverrideError(\n\t\t\t\t_overriding,\n\t\t\t\t_super,\n\t\t\t\t5225_error,\n\t\t\t\t\"Public state variables can only override functions with external visibility.\",\n\t\t\t\t\"Overridden function is here:\"\n\t\t\t);\n\t\tsolAssert(_overriding.visibility() == Visibility::External, \"\");\n\t}\n\telse if (_overriding.visibility() != _super.visibility())\n\t{\n\t\t// Visibility change from external to public is fine.\n\t\t// Any other change is disallowed.\n\t\tif (!(\n\t\t\t_super.visibility() == Visibility::External &&\n\t\t\t_overriding.visibility() == Visibility::Public\n\t\t))\n\t\t\toverrideError(\n\t\t\t\t_overriding,\n\t\t\t\t_super,\n\t\t\t\t9098_error,\n\t\t\t\t\"Overriding \" + _overriding.astNodeName() + \" visibility differs.\",\n\t\t\t\t\"Overridden \" + _overriding.astNodeName() + \" is here:\"\n\t\t\t);\n\t}\n\n\tif (_overriding.unimplemented() && !_super.unimplemented())\n\t{\n\t\tsolAssert(!_overriding.isVariable() || !_overriding.unimplemented(), \"\");\n\t\toverrideError(\n\t\t\t_overriding,\n\t\t\t_super,\n\t\t\t4593_error,\n\t\t\t\"Overriding an implemented \" + _super.astNodeName() +\n\t\t\t\" with an unimplemented \" + _overriding.astNodeName() +\n\t\t\t\" is not allowed.\"\n\t\t);\n\t}\n\n\tif (_super.isFunction())\n\t{\n\t\tFunctionType const* functionType = _overriding.externalFunctionType();\n\t\tFunctionType const* superType = _super.externalFunctionType();\n\n\t\tbool returnTypesDifferAlready = false;\n\t\tif (_overriding.functionKind() != Token::Fallback)\n\t\t{\n\t\t\tsolAssert(functionType->hasEqualParameterTypes(*superType), \"Override doesn't have equal parameters!\");\n\n\t\t\tif (!functionType->hasEqualReturnTypes(*superType))\n\t\t\t{\n\t\t\t\treturnTypesDifferAlready = true;\n\t\t\t\toverrideError(\n\t\t\t\t\t_overriding,\n\t\t\t\t\t_super,\n\t\t\t\t\t4822_error,\n\t\t\t\t\t\"Overriding \" + _overriding.astNodeName() + \" return types differ.\",\n\t\t\t\t\t\"Overridden \" + _overriding.astNodeName() + \" is here:\"\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// The override proxy considers calldata and memory the same data location.\n\t\t// Here we do a more specific check:\n\t\t// Data locations of parameters and return variables have to match\n\t\t// unless we have a public function overriding an external one.\n\t\tif (\n\t\t\t_overriding.isFunction() &&\n\t\t\t!returnTypesDifferAlready &&\n\t\t\t_super.visibility() != Visibility::External &&\n\t\t\t_overriding.functionKind() != Token::Fallback\n\t\t)\n\t\t{\n\t\t\tif (!_overriding.originalFunctionType()->hasEqualParameterTypes(*_super.originalFunctionType()))\n\t\t\t\toverrideError(\n\t\t\t\t\t_overriding,\n\t\t\t\t\t_super,\n\t\t\t\t\t7723_error,\n\t\t\t\t\t\"Data locations of parameters have to be the same when overriding non-external functions, but they differ.\",\n\t\t\t\t\t\"Overridden \" + _overriding.astNodeName() + \" is here:\"\n\t\t\t\t);\n\t\t\tif (!_overriding.originalFunctionType()->hasEqualReturnTypes(*_super.originalFunctionType()))\n\t\t\t\toverrideError(\n\t\t\t\t\t_overriding,\n\t\t\t\t\t_super,\n\t\t\t\t\t1443_error,\n\t\t\t\t\t\"Data locations of return variables have to be the same when overriding non-external functions, but they differ.\",\n\t\t\t\t\t\"Overridden \" + _overriding.astNodeName() + \" is here:\"\n\t\t\t\t);\n\t\t}\n\n\t\t// Stricter mutability is always okay except when super is Payable\n\t\tif (\n\t\t\t(_overriding.isFunction() || _overriding.isVariable()) &&\n\t\t\t(\n\t\t\t\t_overriding.stateMutability() > _super.stateMutability() ||\n\t\t\t\t_super.stateMutability() == StateMutability::Payable\n\t\t\t) &&\n\t\t\t_overriding.stateMutability() != _super.stateMutability()\n\t\t)\n\t\t\toverrideError(\n\t\t\t\t_overriding,\n\t\t\t\t_super,\n\t\t\t\t6959_error,\n\t\t\t\t\"Overriding \" +\n\t\t\t\t_overriding.astNodeName() +\n\t\t\t\t\" changes state mutability from \\\"\" +\n\t\t\t\tstateMutabilityToString(_super.stateMutability()) +\n\t\t\t\t\"\\\" to \\\"\" +\n\t\t\t\tstateMutabilityToString(_overriding.stateMutability()) +\n\t\t\t\t\"\\\".\"\n\t\t\t);\n\t}\n}\n\nvoid OverrideChecker::overrideListError(\n\tOverrideProxy const& _item,\n\tstd::set<ContractDefinition const*, CompareByID> _secondary,\n\tErrorId _error,\n\tstd::string const& _message1,\n\tstd::string const& _message2\n)\n{\n\t// Using a set rather than a vector so the order is always the same\n\tstd::set<std::string> names;\n\tSecondarySourceLocation ssl;\n\tfor (Declaration const* c: _secondary)\n\t{\n\t\tssl.append(\"This contract: \", c->location());\n\t\tnames.insert(\"\\\"\" + c->name() + \"\\\"\");\n\t}\n\tstd::string contractSingularPlural = \"contract \";\n\tif (_secondary.size() > 1)\n\t\tcontractSingularPlural = \"contracts \";\n\n\tm_errorReporter.typeError(\n\t\t_error,\n\t\t_item.overrides() ? _item.overrides()->location() : _item.location(),\n\t\tssl,\n\t\t_message1 +\n\t\tcontractSingularPlural +\n\t\t_message2 +\n\t\tjoinHumanReadable(names, \", \", \" and \") +\n\t\t\".\"\n\t);\n}\n\nvoid OverrideChecker::overrideError(\n\tOverrideProxy const& _overriding,\n\tOverrideProxy const& _super,\n\tErrorId _error,\n\tstd::string const& _message,\n\tstd::optional<std::string> const& _secondaryMsg\n)\n{\n\tm_errorReporter.typeError(\n\t\t_error,\n\t\t_overriding.location(),\n\t\tSecondarySourceLocation().append(\n\t\t\t_secondaryMsg.value_or(\"Overridden \" + _super.astNodeName() + \" is here:\"),\n\t\t\t_super.location()\n\t\t),\n\t\t_message\n\t);\n}\n\nvoid OverrideChecker::checkAmbiguousOverrides(ContractDefinition const& _contract) const\n{\n\t{\n\t\t// Fetch inherited functions and sort them by signature.\n\t\t// We get at least one function per signature and direct base contract, which is\n\t\t// enough because we re-construct the inheritance graph later.\n\t\tOverrideProxyBySignatureMultiSet nonOverriddenFunctions = inheritedFunctions(_contract);\n\n\t\t// Remove all functions that match the signature of a function in the current contract.\n\t\tfor (FunctionDefinition const* f: _contract.definedFunctions())\n\t\t\tnonOverriddenFunctions.erase(OverrideProxy{f});\n\t\tfor (VariableDeclaration const* v: _contract.stateVariables())\n\t\t\tif (v->isPublic())\n\t\t\t\tnonOverriddenFunctions.erase(OverrideProxy{v});\n\n\t\t// Walk through the set of functions signature by signature.\n\t\tfor (auto it = nonOverriddenFunctions.cbegin(); it != nonOverriddenFunctions.cend();)\n\t\t{\n\t\t\tstd::set<OverrideProxy> baseFunctions;\n\t\t\tfor (auto nextSignature = nonOverriddenFunctions.upper_bound(*it); it != nextSignature; ++it)\n\t\t\t\tbaseFunctions.insert(*it);\n\n\t\t\tcheckAmbiguousOverridesInternal(std::move(baseFunctions), _contract.location());\n\t\t}\n\t}\n\n\t{\n\t\tOverrideProxyBySignatureMultiSet modifiers = inheritedModifiers(_contract);\n\t\tfor (ModifierDefinition const* mod: _contract.functionModifiers())\n\t\t\tmodifiers.erase(OverrideProxy{mod});\n\n\t\tfor (auto it = modifiers.cbegin(); it != modifiers.cend();)\n\t\t{\n\t\t\tstd::set<OverrideProxy> baseModifiers;\n\t\t\tfor (auto next = modifiers.upper_bound(*it); it != next; ++it)\n\t\t\t\tbaseModifiers.insert(*it);\n\n\t\t\tcheckAmbiguousOverridesInternal(std::move(baseModifiers), _contract.location());\n\t\t}\n\n\t}\n}\n\nvoid OverrideChecker::checkAmbiguousOverridesInternal(std::set<OverrideProxy> _baseCallables, SourceLocation const& _location) const\n{\n\tif (_baseCallables.size() <= 1)\n\t\treturn;\n\n\tOverrideGraph overrideGraph(_baseCallables);\n\tCutVertexFinder cutVertexFinder{overrideGraph};\n\n\t// Remove all base functions overridden by cut vertices (they don't need to be overridden).\n\tfor (OverrideProxy const& function: cutVertexFinder.cutVertices())\n\t{\n\t\tstd::set<OverrideProxy> toTraverse = function.baseFunctions();\n\t\twhile (!toTraverse.empty())\n\t\t{\n\t\t\tOverrideProxy base = *toTraverse.begin();\n\t\t\ttoTraverse.erase(toTraverse.begin());\n\t\t\t_baseCallables.erase(base);\n\t\t\tfor (OverrideProxy const& f: base.baseFunctions())\n\t\t\t\ttoTraverse.insert(f);\n\t\t}\n\t\t// Remove unimplemented base functions at the cut vertices itself as well.\n\t\tif (function.unimplemented())\n\t\t\t_baseCallables.erase(function);\n\t}\n\n\t// If more than one function is left, they have to be overridden.\n\tif (_baseCallables.size() <= 1)\n\t\treturn;\n\n\tSecondarySourceLocation ssl;\n\tfor (OverrideProxy const& baseFunction: _baseCallables)\n\t\tssl.append(\"Definition in \\\"\" + baseFunction.contractName() + \"\\\": \", baseFunction.location());\n\n\tstd::string callableName = _baseCallables.begin()->astNodeName();\n\tif (_baseCallables.begin()->isVariable())\n\t\tcallableName = \"function\";\n\tstd::string distinguishingProperty = _baseCallables.begin()->distinguishingProperty();\n\n\tbool foundVariable = false;\n\tfor (auto const& base: _baseCallables)\n\t\tif (base.isVariable())\n\t\t\tfoundVariable = true;\n\n\tstd::string message =\n\t\t\"Derived contract must override \" + callableName + \" \\\"\" +\n\t\t_baseCallables.begin()->name() +\n\t\t\"\\\". Two or more base classes define \" + callableName + \" with same \" + distinguishingProperty + \".\";\n\n\tif (foundVariable)\n\t\tmessage +=\n\t\t\t\" Since one of the bases defines a public state variable which cannot be overridden, \"\n\t\t\t\"you have to change the inheritance layout or the names of the functions.\";\n\n\tm_errorReporter.typeError(6480_error, _location, ssl, message);\n}\n\nstd::set<ContractDefinition const*, OverrideChecker::CompareByID> OverrideChecker::resolveOverrideList(OverrideSpecifier const& _overrides) const\n{\n\tstd::set<ContractDefinition const*, CompareByID> resolved;\n\n\tfor (ASTPointer<IdentifierPath> const& override: _overrides.overrides())\n\t{\n\t\tDeclaration const* decl  = override->annotation().referencedDeclaration;\n\t\tsolAssert(decl, \"Expected declaration to be resolved.\");\n\n\t\t// If it's not a contract it will be caught\n\t\t// in the reference resolver\n\t\tif (ContractDefinition const* contract = dynamic_cast<decltype(contract)>(decl))\n\t\t\tresolved.insert(contract);\n\t}\n\n\treturn resolved;\n}\n\nvoid OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySignatureMultiSet const& _inherited)\n{\n\tstd::set<ContractDefinition const*, CompareByID> specifiedContracts =\n\t\t_item.overrides() ?\n\t\tresolveOverrideList(*_item.overrides()) :\n\t\tdecltype(specifiedContracts){};\n\n\t// Check for duplicates in override list\n\tif (_item.overrides() && specifiedContracts.size() != _item.overrides()->overrides().size())\n\t{\n\t\t// Sort by contract id to find duplicate for error reporting\n\t\tstd::vector<ASTPointer<IdentifierPath>> list =\n\t\t\tsortByContract(_item.overrides()->overrides());\n\n\t\t// Find duplicates and output error\n\t\tfor (size_t i = 1; i < list.size(); i++)\n\t\t{\n\t\t\tDeclaration const* aDecl = list[i]->annotation().referencedDeclaration;\n\t\t\tDeclaration const* bDecl = list[i-1]->annotation().referencedDeclaration;\n\t\t\tif (!aDecl || !bDecl)\n\t\t\t\tcontinue;\n\n\t\t\tif (aDecl->id() == bDecl->id())\n\t\t\t{\n\t\t\t\tSecondarySourceLocation ssl;\n\t\t\t\tssl.append(\"First occurrence here: \", list[i-1]->location());\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t4520_error,\n\t\t\t\t\tlist[i]->location(),\n\t\t\t\t\tssl,\n\t\t\t\t\t\"Duplicate contract \\\"\" +\n\t\t\t\t\tjoinHumanReadable(list[i]->path(), \".\") +\n\t\t\t\t\t\"\\\" found in override list of \\\"\" +\n\t\t\t\t\t_item.name() +\n\t\t\t\t\t\"\\\".\"\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tstd::set<ContractDefinition const*, CompareByID> expectedContracts;\n\n\t// Build list of expected contracts\n\tfor (auto [begin, end] = _inherited.equal_range(_item); begin != end; begin++)\n\t{\n\t\t// Validate the override\n\t\tcheckOverride(_item, *begin);\n\n\t\texpectedContracts.insert(&begin->contract());\n\t}\n\n\tif (_item.overrides() && expectedContracts.empty())\n\t\tm_errorReporter.typeError(\n\t\t\t7792_error,\n\t\t\t_item.overrides()->location(),\n\t\t\t_item.astNodeNameCapitalized() + \" has override specified but does not override anything.\"\n\t\t);\n\n\tstd::set<ContractDefinition const*, CompareByID> missingContracts;\n\t// If we expect only one contract, no contract needs to be specified\n\tif (expectedContracts.size() > 1)\n\t\tmissingContracts = expectedContracts - specifiedContracts;\n\n\tif (!missingContracts.empty())\n\t\toverrideListError(\n\t\t\t_item,\n\t\t\tmissingContracts,\n\t\t\t4327_error,\n\t\t\t_item.astNodeNameCapitalized() + \" needs to specify overridden \",\n\t\t\t\"\"\n\t\t);\n\n\tauto surplusContracts = specifiedContracts - expectedContracts;\n\tif (!surplusContracts.empty())\n\t\toverrideListError(\n\t\t\t_item,\n\t\t\tsurplusContracts,\n\t\t\t2353_error,\n\t\t\t\"Invalid \",\n\t\t\t\"specified in override list: \"\n\t\t);\n}\n\nOverrideChecker::OverrideProxyBySignatureMultiSet const& OverrideChecker::inheritedFunctions(ContractDefinition const& _contract) const\n{\n\tif (!m_inheritedFunctions.count(&_contract))\n\t{\n\t\tOverrideProxyBySignatureMultiSet result;\n\n\t\tfor (auto const* base: resolveDirectBaseContracts(_contract))\n\t\t{\n\t\t\tstd::set<OverrideProxy, OverrideProxy::CompareBySignature> functionsInBase;\n\t\t\tfor (FunctionDefinition const* fun: base->definedFunctions())\n\t\t\t\tif (!fun->isConstructor())\n\t\t\t\t\tfunctionsInBase.emplace(OverrideProxy{fun});\n\t\t\tfor (VariableDeclaration const* var: base->stateVariables())\n\t\t\t\tif (var->isPublic())\n\t\t\t\t\tfunctionsInBase.emplace(OverrideProxy{var});\n\n\t\t\tresult += functionsInBase;\n\n\t\t\tfor (OverrideProxy const& func: inheritedFunctions(*base))\n\t\t\t\tif (!functionsInBase.count(func))\n\t\t\t\t\tresult.insert(func);\n\t\t}\n\n\t\tm_inheritedFunctions[&_contract] = result;\n\t}\n\n\treturn m_inheritedFunctions[&_contract];\n}\n\nOverrideChecker::OverrideProxyBySignatureMultiSet const& OverrideChecker::inheritedModifiers(ContractDefinition const& _contract) const\n{\n\tif (!m_inheritedModifiers.count(&_contract))\n\t{\n\t\tOverrideProxyBySignatureMultiSet result;\n\n\t\tfor (auto const* base: resolveDirectBaseContracts(_contract))\n\t\t{\n\t\t\tstd::set<OverrideProxy, OverrideProxy::CompareBySignature> modifiersInBase;\n\t\t\tfor (ModifierDefinition const* mod: base->functionModifiers())\n\t\t\t\tmodifiersInBase.emplace(OverrideProxy{mod});\n\n\t\t\tfor (OverrideProxy const& mod: inheritedModifiers(*base))\n\t\t\t\tmodifiersInBase.insert(mod);\n\n\t\t\tresult += modifiersInBase;\n\t\t}\n\n\t\tm_inheritedModifiers[&_contract] = result;\n\t}\n\n\treturn m_inheritedModifiers[&_contract];\n}\n"
  },
  {
    "path": "libsolidity/analysis/OverrideChecker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that verifies override properties.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/ASTEnums.h>\n#include <liblangutil/SourceLocation.h>\n#include <map>\n#include <functional>\n#include <set>\n#include <variant>\n#include <optional>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\nstruct ErrorId;\nstruct SourceLocation;\n}\n\nnamespace solidity::frontend\n{\nclass FunctionType;\nclass ModifierType;\n\n/**\n * Class that represents a function, public state variable or modifier\n * and helps with overload checking.\n * Regular comparison is performed based on AST node, while CompareBySignature\n * results in two elements being equal when they can override each\n * other.\n */\nclass OverrideProxy\n{\npublic:\n\tOverrideProxy() {}\n\texplicit OverrideProxy(FunctionDefinition const* _fun): m_item{_fun} {}\n\texplicit OverrideProxy(ModifierDefinition const* _mod): m_item{_mod} {}\n\texplicit OverrideProxy(VariableDeclaration const* _var): m_item{_var} {}\n\n\tbool operator<(OverrideProxy const& _other) const;\n\n\tstruct CompareBySignature\n\t{\n\t\tbool operator()(OverrideProxy const& _a, OverrideProxy const& _b) const;\n\t};\n\n\tbool isVariable() const;\n\tbool isFunction() const;\n\tbool isModifier() const;\n\n\tsize_t id() const;\n\tstd::shared_ptr<OverrideSpecifier> overrides() const;\n\tstd::set<OverrideProxy> baseFunctions() const;\n\t/// This stores the item in the list of base items.\n\tvoid storeBaseFunction(OverrideProxy const& _base) const;\n\n\tstd::string const& name() const;\n\tContractDefinition const& contract() const;\n\tstd::string const& contractName() const;\n\tVisibility visibility() const;\n\tStateMutability stateMutability() const;\n\tbool virtualSemantics() const;\n\n\t/// @returns receive / fallback / function (only the latter for modifiers and variables);\n\tlangutil::Token functionKind() const;\n\n\t/// @returns the externally callable function type\n\tFunctionType const* externalFunctionType() const;\n\t/// @returns the (unmodified) function type\n\tFunctionType const* originalFunctionType() const;\n\tModifierType const* modifierType() const;\n\n\tDeclaration const* declaration() const;\n\n\tlangutil::SourceLocation const& location() const;\n\n\tstd::string astNodeName() const;\n\tstd::string astNodeNameCapitalized() const;\n\tstd::string distinguishingProperty() const;\n\n\t/// @returns true if this AST elements supports the feature of being unimplemented\n\t/// and is actually not implemented.\n\tbool unimplemented() const;\n\n\t/**\n\t * Struct to help comparing override items about whether they override each other.\n\t * Compares functions based on their \"externally callable\" type.\n\t * Does not produce a total order.\n\t */\n\tstruct OverrideComparator\n\t{\n\t\tstd::string name;\n\t\tstd::optional<langutil::Token> functionKind;\n\t\tstd::optional<std::vector<std::string>> parameterTypes;\n\n\t\tbool operator<(OverrideComparator const& _other) const;\n\t};\n\n\t/// @returns a structure used to compare override items with regards to whether\n\t/// they override each other.\n\tOverrideComparator const& overrideComparator() const;\n\nprivate:\n\tstd::variant<\n\t\tFunctionDefinition const*,\n\t\tModifierDefinition const*,\n\t\tVariableDeclaration const*\n\t> m_item;\n\n\tstd::shared_ptr<OverrideComparator> mutable m_comparator;\n};\n\n\n/**\n * Component that verifies override properties.\n */\nclass OverrideChecker\n{\npublic:\n\tusing OverrideProxyBySignatureMultiSet = std::multiset<OverrideProxy, OverrideProxy::CompareBySignature>;\n\n\t/// @param _errorReporter provides the error logging functionality.\n\texplicit OverrideChecker(langutil::ErrorReporter& _errorReporter):\n\t\tm_errorReporter(_errorReporter)\n\t{}\n\n\tvoid check(ContractDefinition const& _contract);\n\n\tstruct CompareByID\n\t{\n\t\tbool operator()(ContractDefinition const* _a, ContractDefinition const* _b) const;\n\t};\n\n\t/// Returns all functions of bases (including public state variables) that have not yet been overwritten.\n\t/// May contain the same function multiple times when used with shared bases.\n\tOverrideProxyBySignatureMultiSet const& inheritedFunctions(ContractDefinition const& _contract) const;\n\tOverrideProxyBySignatureMultiSet const& inheritedModifiers(ContractDefinition const& _contract) const;\n\nprivate:\n\tvoid checkIllegalOverrides(ContractDefinition const& _contract);\n\t/// Performs various checks related to @a _overriding overriding @a _super like\n\t/// different return type, invalid visibility change, etc.\n\t/// Works on functions, modifiers and public state variables.\n\t/// Also stores @a _super as a base function of @a _function in its AST annotations.\n\tvoid checkOverride(OverrideProxy const& _overriding, OverrideProxy const& _super);\n\tvoid overrideListError(\n\t\tOverrideProxy const& _item,\n\t\tstd::set<ContractDefinition const*, CompareByID> _secondary,\n\t\tlangutil::ErrorId _error,\n\t\tstd::string const& _message1,\n\t\tstd::string const& _message2\n\t);\n\tvoid overrideError(\n\t\tOverrideProxy const& _overriding,\n\t\tOverrideProxy const& _super,\n\t\tlangutil::ErrorId _error,\n\t\tstd::string const& _message,\n\t\tstd::optional<std::string> const& _secondaryMsg = {}\n\t);\n\t/// Checks for functions in different base contracts which conflict with each\n\t/// other and thus need to be overridden explicitly.\n\tvoid checkAmbiguousOverrides(ContractDefinition const& _contract) const;\n\tvoid checkAmbiguousOverridesInternal(std::set<OverrideProxy> _baseCallables, langutil::SourceLocation const& _location) const;\n\t/// Resolves an override list of UserDefinedTypeNames to a list of contracts.\n\tstd::set<ContractDefinition const*, CompareByID> resolveOverrideList(OverrideSpecifier const& _overrides) const;\n\n\tvoid checkOverrideList(OverrideProxy _item, OverrideProxyBySignatureMultiSet const& _inherited);\n\n\tlangutil::ErrorReporter& m_errorReporter;\n\n\t/// Cache for inheritedFunctions().\n\tstd::map<ContractDefinition const*, OverrideProxyBySignatureMultiSet> mutable m_inheritedFunctions;\n\tstd::map<ContractDefinition const*, OverrideProxyBySignatureMultiSet> mutable m_inheritedModifiers;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/PostTypeChecker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/PostTypeChecker.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/interface/Version.h>\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/SemVerHandler.h>\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/FunctionSelector.h>\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/AST.h>\n\n#include <range/v3/algorithm/any_of.hpp>\n\n#include <memory>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nbool PostTypeChecker::check(ASTNode const& _astRoot)\n{\n\t_astRoot.accept(*this);\n\treturn !Error::containsErrors(m_errorReporter.errors());\n}\n\nbool PostTypeChecker::finalize()\n{\n\tfor (auto& checker: m_checkers)\n\t\tchecker->finalize();\n\treturn !Error::containsErrors(m_errorReporter.errors());\n}\n\nbool PostTypeChecker::visit(ContractDefinition const& _contractDefinition)\n{\n\treturn callVisit(_contractDefinition);\n}\n\nvoid PostTypeChecker::endVisit(ContractDefinition const& _contractDefinition)\n{\n\tcallEndVisit(_contractDefinition);\n}\n\nvoid PostTypeChecker::endVisit(OverrideSpecifier const& _overrideSpecifier)\n{\n\tcallEndVisit(_overrideSpecifier);\n}\n\nbool PostTypeChecker::visit(VariableDeclaration const& _variable)\n{\n\treturn callVisit(_variable);\n}\n\nvoid PostTypeChecker::endVisit(VariableDeclaration const& _variable)\n{\n\tcallEndVisit(_variable);\n}\n\nvoid PostTypeChecker::endVisit(ErrorDefinition const& _error)\n{\n\tcallEndVisit(_error);\n}\n\nbool PostTypeChecker::visit(EmitStatement const& _emit)\n{\n\treturn callVisit(_emit);\n}\n\nvoid PostTypeChecker::endVisit(EmitStatement const& _emit)\n{\n\tcallEndVisit(_emit);\n}\n\nbool PostTypeChecker::visit(RevertStatement const& _revert)\n{\n\treturn callVisit(_revert);\n}\n\nvoid PostTypeChecker::endVisit(RevertStatement const& _revert)\n{\n\tcallEndVisit(_revert);\n}\n\nbool PostTypeChecker::visit(FunctionCall const& _functionCall)\n{\n\treturn callVisit(_functionCall);\n}\n\nvoid PostTypeChecker::endVisit(FunctionCall const& _functionCall)\n{\n\tcallEndVisit(_functionCall);\n}\n\nbool PostTypeChecker::visit(Identifier const& _identifier)\n{\n\treturn callVisit(_identifier);\n}\n\nbool PostTypeChecker::visit(MemberAccess const& _memberAccess)\n{\n\treturn callVisit(_memberAccess);\n}\n\nbool PostTypeChecker::visit(StructDefinition const& _struct)\n{\n\treturn callVisit(_struct);\n}\n\nvoid PostTypeChecker::endVisit(StructDefinition const& _struct)\n{\n\tcallEndVisit(_struct);\n}\n\nbool PostTypeChecker::visit(ModifierInvocation const& _modifierInvocation)\n{\n\treturn callVisit(_modifierInvocation);\n}\n\nvoid PostTypeChecker::endVisit(ModifierInvocation const& _modifierInvocation)\n{\n\tcallEndVisit(_modifierInvocation);\n}\n\n\nbool PostTypeChecker::visit(ForStatement const& _forStatement)\n{\n\treturn callVisit(_forStatement);\n}\n\nvoid PostTypeChecker::endVisit(ForStatement const& _forStatement)\n{\n\tcallEndVisit(_forStatement);\n}\n\nnamespace\n{\nstruct ConstStateVarCircularReferenceChecker: public PostTypeChecker::Checker\n{\n\tConstStateVarCircularReferenceChecker(ErrorReporter& _errorReporter):\n\t\tChecker(_errorReporter) {}\n\n\tvoid finalize() override\n\t{\n\t\tsolAssert(!m_currentConstVariable, \"\");\n\t\tfor (auto declaration: m_constVariables)\n\t\t\tif (auto identifier = findCycle(*declaration))\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t6161_error,\n\t\t\t\t\tdeclaration->location(),\n\t\t\t\t\t\"The value of the constant \" + declaration->name() +\n\t\t\t\t\t\" has a cyclic dependency via \" + identifier->name() + \".\"\n\t\t\t\t);\n\t}\n\n\tbool visit(ContractDefinition const&) override\n\t{\n\t\tsolAssert(!m_currentConstVariable, \"\");\n\t\treturn true;\n\t}\n\n\tbool visit(VariableDeclaration const& _variable) override\n\t{\n\t\tif (_variable.isConstant())\n\t\t{\n\t\t\tsolAssert(!m_currentConstVariable, \"\");\n\t\t\tm_currentConstVariable = &_variable;\n\t\t\tm_constVariables.push_back(&_variable);\n\t\t}\n\t\treturn true;\n\t}\n\n\tvoid endVisit(VariableDeclaration const& _variable) override\n\t{\n\t\tif (_variable.isConstant())\n\t\t{\n\t\t\tsolAssert(m_currentConstVariable == &_variable, \"\");\n\t\t\tm_currentConstVariable = nullptr;\n\t\t}\n\t}\n\n\tbool visit(Identifier const& _identifier) override\n\t{\n\t\tif (m_currentConstVariable)\n\t\t\tif (auto var = dynamic_cast<VariableDeclaration const*>(_identifier.annotation().referencedDeclaration))\n\t\t\t\tif (var->isConstant())\n\t\t\t\t\tm_constVariableDependencies[m_currentConstVariable].insert(var);\n\t\treturn true;\n\t}\n\n\tbool visit(MemberAccess const& _memberAccess) override\n\t{\n\t\tif (m_currentConstVariable)\n\t\t\tif (auto var = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t\t\tif (var->isConstant())\n\t\t\t\t\tm_constVariableDependencies[m_currentConstVariable].insert(var);\n\t\treturn true;\n\t}\n\n\tVariableDeclaration const* findCycle(VariableDeclaration const& _startingFrom)\n\t{\n\t\tauto visitor = [&](VariableDeclaration const& _variable, util::CycleDetector<VariableDeclaration>& _cycleDetector, size_t _depth)\n\t\t{\n\t\t\tif (_depth >= 256)\n\t\t\t\tm_errorReporter.fatalDeclarationError(7380_error, _variable.location(), \"Variable definition exhausting cyclic dependency validator.\");\n\n\t\t\t// Iterating through the dependencies needs to be deterministic and thus cannot\n\t\t\t// depend on the memory layout.\n\t\t\t// Because of that, we sort by AST node id.\n\t\t\tstd::vector<VariableDeclaration const*> dependencies(\n\t\t\t\tm_constVariableDependencies[&_variable].begin(),\n\t\t\t\tm_constVariableDependencies[&_variable].end()\n\t\t\t);\n\t\t\tsort(dependencies.begin(), dependencies.end(), [](VariableDeclaration const* _a, VariableDeclaration const* _b) -> bool\n\t\t\t{\n\t\t\t\treturn _a->id() < _b->id();\n\t\t\t});\n\t\t\tfor (auto v: dependencies)\n\t\t\t\tif (_cycleDetector.run(*v))\n\t\t\t\t\treturn;\n\t\t};\n\t\treturn util::CycleDetector<VariableDeclaration>(visitor).run(_startingFrom);\n\t}\n\nprivate:\n\tVariableDeclaration const* m_currentConstVariable = nullptr;\n\tstd::map<VariableDeclaration const*, std::set<VariableDeclaration const*>> m_constVariableDependencies;\n\tstd::vector<VariableDeclaration const*> m_constVariables; ///< Required for determinism.\n};\n\nstruct OverrideSpecifierChecker: public PostTypeChecker::Checker\n{\n\tOverrideSpecifierChecker(ErrorReporter& _errorReporter):\n\t\tChecker(_errorReporter) {}\n\n\tvoid endVisit(OverrideSpecifier const& _overrideSpecifier) override\n\t{\n\t\tfor (ASTPointer<IdentifierPath> const& override: _overrideSpecifier.overrides())\n\t\t{\n\t\t\tDeclaration const* decl = override->annotation().referencedDeclaration;\n\t\t\tsolAssert(decl, \"Expected declaration to be resolved.\");\n\n\t\t\tif (dynamic_cast<ContractDefinition const*>(decl))\n\t\t\t\tcontinue;\n\n\t\t\tauto const* typeType = dynamic_cast<TypeType const*>(decl->type());\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t9301_error,\n\t\t\t\toverride->location(),\n\t\t\t\t\"Expected contract but got \" +\n\t\t\t\t(typeType ? typeType->actualType() : decl->type())->toString(true) +\n\t\t\t\t\".\"\n\t\t\t);\n\t\t}\n\t}\n};\n\nstruct ModifierContextChecker: public PostTypeChecker::Checker\n{\n\tModifierContextChecker(ErrorReporter& _errorReporter):\n\t\tChecker(_errorReporter) {}\n\n\tbool visit(ModifierInvocation const&) override\n\t{\n\t\tm_insideModifierInvocation = true;\n\n\t\treturn true;\n\t}\n\n\tvoid endVisit(ModifierInvocation const&) override\n\t{\n\t\tm_insideModifierInvocation = false;\n\t}\n\n\tbool visit(Identifier const& _identifier) override\n\t{\n\t\tif (m_insideModifierInvocation)\n\t\t\treturn true;\n\n\t\tif (ModifierType const* type = dynamic_cast<decltype(type)>(_identifier.annotation().type))\n\t\t{\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t3112_error,\n\t\t\t\t_identifier.location(),\n\t\t\t\t\"Modifier can only be referenced in function headers.\"\n\t\t\t);\n\t\t}\n\n\t\treturn false;\n\t}\nprivate:\n\t/// Flag indicating whether we are currently inside the invocation of a modifier\n\tbool m_insideModifierInvocation = false;\n};\n\n// TODO: this should either be split into separate emit and error checkers, or at least renamed to include require\nstruct EventOutsideEmitErrorOutsideRevertChecker: public PostTypeChecker::Checker\n{\n\tEventOutsideEmitErrorOutsideRevertChecker(ErrorReporter& _errorReporter):\n\t\tChecker(_errorReporter) {}\n\n\tbool visit(EmitStatement const& _emitStatement) override\n\t{\n\t\tm_currentStatement = &_emitStatement;\n\t\treturn true;\n\t}\n\n\tvoid endVisit(EmitStatement const&) override\n\t{\n\t\tm_currentStatement = nullptr;\n\t}\n\n\tbool visit(RevertStatement const& _revertStatement) override\n\t{\n\t\tm_currentStatement = &_revertStatement;\n\t\treturn true;\n\t}\n\n\tvoid endVisit(RevertStatement const&) override\n\t{\n\t\tm_currentStatement = nullptr;\n\t}\n\n\tbool visit(FunctionCall const& _functionCall) override\n\t{\n\t\tif (*_functionCall.annotation().kind == FunctionCallKind::FunctionCall)\n\t\t\tif (auto const* functionType = dynamic_cast<FunctionType const*>(_functionCall.expression().annotation().type))\n\t\t\t{\n\t\t\t\tif (functionType->kind() == FunctionType::Kind::Require)\n\t\t\t\t{\n\t\t\t\t\tsolAssert(!m_inRequire);\n\t\t\t\t\tm_inRequire = true;\n\t\t\t\t}\n\t\t\t\t// Check for event outside of emit statement\n\t\t\t\tif (!dynamic_cast<EmitStatement const*>(m_currentStatement) && functionType->kind() == FunctionType::Kind::Event)\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t3132_error,\n\t\t\t\t\t\t_functionCall.location(),\n\t\t\t\t\t\t\"Event invocations have to be prefixed by \\\"emit\\\".\"\n\t\t\t\t\t);\n\t\t\t\telse if (!dynamic_cast<RevertStatement const*>(m_currentStatement) && !m_inRequire && functionType->kind() == FunctionType::Kind::Error)\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t7757_error,\n\t\t\t\t\t\t_functionCall.location(),\n\t\t\t\t\t\t\"Errors can only be used with revert statements: \\\"revert MyError(args);\\\", or require functions: \\\"require(condition, MyError(args))\\\".\"\n\t\t\t\t\t);\n\t\t\t}\n\t\tm_currentStatement = nullptr;\n\n\t\treturn true;\n\t}\n\n\tvoid endVisit(FunctionCall const& _functionCall) override\n\t{\n\t\tif (*_functionCall.annotation().kind == FunctionCallKind::FunctionCall)\n\t\t\tif (auto const* functionType = dynamic_cast<FunctionType const*>(_functionCall.expression().annotation().type))\n\t\t\t\tif (functionType->kind() == FunctionType::Kind::Require)\n\t\t\t\t{\n\t\t\t\t\tsolAssert(m_inRequire);\n\t\t\t\t\tm_inRequire = false;\n\t\t\t\t}\n\t}\n\nprivate:\n\tStatement const* m_currentStatement = nullptr;\n\tbool m_inRequire = false;\n};\n\nstruct NoVariablesInInterfaceChecker: public PostTypeChecker::Checker\n{\n\tNoVariablesInInterfaceChecker(ErrorReporter& _errorReporter):\n\t\tChecker(_errorReporter)\n\t{}\n\n\tbool visit(VariableDeclaration const& _variable) override\n\t{\n\t\t// Forbid any variable declarations inside interfaces unless they are part of\n\t\t// * a function's input/output parameters,\n\t\t// * or inside of a struct definition.\n\t\tif (\n\t\t\tm_scope && m_scope->isInterface()\n\t\t\t&& !_variable.isCallableOrCatchParameter()\n\t\t\t&& !m_insideStruct\n\t\t)\n\t\t\tm_errorReporter.typeError(8274_error, _variable.location(), \"Variables cannot be declared in interfaces.\");\n\n\t\treturn true;\n\t}\n\n\tbool visit(ContractDefinition const& _contract) override\n\t{\n\t\tm_scope = &_contract;\n\t\treturn true;\n\t}\n\n\tvoid endVisit(ContractDefinition const&) override\n\t{\n\t\tm_scope = nullptr;\n\t}\n\n\tbool visit(StructDefinition const&) override\n\t{\n\t\tsolAssert(m_insideStruct >= 0, \"\");\n\t\tm_insideStruct++;\n\t\treturn true;\n\t}\n\n\tvoid endVisit(StructDefinition const&) override\n\t{\n\t\tm_insideStruct--;\n\t\tsolAssert(m_insideStruct >= 0, \"\");\n\t}\nprivate:\n\tContractDefinition const* m_scope = nullptr;\n\t/// Flag indicating whether we are currently inside a StructDefinition.\n\tint m_insideStruct = 0;\n};\n\nstruct ReservedErrorSelector: public PostTypeChecker::Checker\n{\n\tReservedErrorSelector(ErrorReporter& _errorReporter):\n\t\tChecker(_errorReporter)\n\t{}\n\n\tvoid endVisit(ErrorDefinition const& _error) override\n\t{\n\t\tif (_error.name() == \"Error\" || _error.name() == \"Panic\")\n\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t1855_error,\n\t\t\t\t_error.location(),\n\t\t\t\t\"The built-in errors \\\"Error\\\" and \\\"Panic\\\" cannot be re-defined.\"\n\t\t\t);\n\t\telse\n\t\t{\n\t\t\tuint32_t selector = util::selectorFromSignatureU32(_error.functionType(true)->externalSignature());\n\t\t\tif (selector == 0 || ~selector == 0)\n\t\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t\t2855_error,\n\t\t\t\t\t_error.location(),\n\t\t\t\t\t\"The selector 0x\" + util::toHex(toCompactBigEndian(selector, 4)) + \" is reserved. Please rename the error to avoid the collision.\"\n\t\t\t\t);\n\t\t}\n\t}\n};\n\nclass YulLValueChecker : public solidity::yul::ASTWalker\n{\npublic:\n\tYulLValueChecker(ASTString const& _identifierName): m_identifierName(_identifierName) {}\n\tbool willBeWrittenTo() const { return m_willBeWrittenTo; }\n\tusing solidity::yul::ASTWalker::operator();\n\tvoid operator()(solidity::yul::Assignment const& _assignment) override\n\t{\n\t\tif (m_willBeWrittenTo)\n\t\t\treturn;\n\n\t\tif (ranges::any_of(\n\t\t\t_assignment.variableNames,\n\t\t\t[&](auto const& yulIdentifier) { return yulIdentifier.name.str() == m_identifierName; }\n\t\t))\n\t\t\tm_willBeWrittenTo = true;\n\t}\nprivate:\n\tASTString const& m_identifierName;\n\tbool m_willBeWrittenTo = false;\n};\n\nclass LValueChecker: public ASTConstVisitor\n{\npublic:\n\tLValueChecker(Identifier const& _identifier):\n\t\tm_declaration(_identifier.annotation().referencedDeclaration)\n\t{}\n\tbool willBeWrittenTo() const { return m_willBeWrittenTo; }\n\tvoid endVisit(Identifier const& _identifier) override\n\t{\n\t\tif (m_willBeWrittenTo)\n\t\t\treturn;\n\n\t\tsolAssert(_identifier.annotation().referencedDeclaration);\n\t\tif (\n\t\t\t*_identifier.annotation().referencedDeclaration == *m_declaration &&\n\t\t\t_identifier.annotation().willBeWrittenTo\n\t\t)\n\t\t\tm_willBeWrittenTo = true;\n\t}\n\tvoid endVisit(InlineAssembly const& _inlineAssembly) override\n\t{\n\t\tif (m_willBeWrittenTo)\n\t\t\treturn;\n\n\t\tYulLValueChecker yulChecker{m_declaration->name()};\n\t\tyulChecker(_inlineAssembly.operations().root());\n\t\tm_willBeWrittenTo = yulChecker.willBeWrittenTo();\n\t}\nprivate:\n\tDeclaration const* m_declaration{};\n\tbool m_willBeWrittenTo = false;\n};\n\nstruct SimpleCounterForLoopChecker: public PostTypeChecker::Checker\n{\n\tSimpleCounterForLoopChecker(ErrorReporter& _errorReporter): Checker(_errorReporter) {}\n\tbool visit(ForStatement const& _forStatement) override\n\t{\n\t\t_forStatement.annotation().isSimpleCounterLoop = isSimpleCounterLoop(_forStatement);\n\t\treturn true;\n\t}\n\tbool isSimpleCounterLoop(ForStatement const& _forStatement) const\n\t{\n\t\tauto const* simpleCondition = dynamic_cast<BinaryOperation const*>(_forStatement.condition());\n\t\tif (!simpleCondition || simpleCondition->getOperator() != Token::LessThan || simpleCondition->userDefinedFunctionType())\n\t\t\treturn false;\n\t\tif (!_forStatement.loopExpression())\n\t\t\treturn false;\n\n\t\tauto const* simplePostExpression = dynamic_cast<UnaryOperation const*>(&_forStatement.loopExpression()->expression());\n\t\t// This matches both operators ++i and i++\n\t\tif (!simplePostExpression || simplePostExpression->getOperator() != Token::Inc || simplePostExpression->userDefinedFunctionType())\n\t\t\treturn false;\n\n\t\tauto const* lhsIdentifier = dynamic_cast<Identifier const*>(&simpleCondition->leftExpression());\n\t\tauto const* lhsIntegerType = dynamic_cast<IntegerType const*>(simpleCondition->leftExpression().annotation().type);\n\t\tauto const* commonIntegerType = dynamic_cast<IntegerType const*>(simpleCondition->annotation().commonType);\n\n\t\tif (!lhsIdentifier || !lhsIntegerType || !commonIntegerType || *lhsIntegerType != *commonIntegerType)\n\t\t\treturn false;\n\n\t\tauto const* incExpressionIdentifier = dynamic_cast<Identifier const*>(&simplePostExpression->subExpression());\n\t\tif (\n\t\t\t!incExpressionIdentifier ||\n\t\t\tincExpressionIdentifier->annotation().referencedDeclaration != lhsIdentifier->annotation().referencedDeclaration\n\t\t)\n\t\t\treturn false;\n\n\t\tsolAssert(incExpressionIdentifier->annotation().referencedDeclaration);\n\t\tif (\n\t\t\tauto const* incVariableDeclaration = dynamic_cast<VariableDeclaration const*>(\n\t\t\t\tincExpressionIdentifier->annotation().referencedDeclaration\n\t\t\t);\n\t\t\tincVariableDeclaration &&\n\t\t\t!incVariableDeclaration->isLocalVariable()\n\t\t)\n\t\t\treturn false;\n\n\t\tsolAssert(lhsIdentifier);\n\t\tLValueChecker lValueChecker{*lhsIdentifier};\n\t\tsimpleCondition->rightExpression().accept(lValueChecker);\n\t\tif (!lValueChecker.willBeWrittenTo())\n\t\t\t_forStatement.body().accept(lValueChecker);\n\n\t\treturn !lValueChecker.willBeWrittenTo();\n\t}\n};\n\n}\n\n\nPostTypeChecker::PostTypeChecker(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter)\n{\n\tm_checkers.push_back(std::make_shared<ConstStateVarCircularReferenceChecker>(_errorReporter));\n\tm_checkers.push_back(std::make_shared<OverrideSpecifierChecker>(_errorReporter));\n\tm_checkers.push_back(std::make_shared<ModifierContextChecker>(_errorReporter));\n\tm_checkers.push_back(std::make_shared<EventOutsideEmitErrorOutsideRevertChecker>(_errorReporter));\n\tm_checkers.push_back(std::make_shared<NoVariablesInInterfaceChecker>(_errorReporter));\n\tm_checkers.push_back(std::make_shared<ReservedErrorSelector>(_errorReporter));\n\tm_checkers.push_back(std::make_shared<SimpleCounterForLoopChecker>(_errorReporter));\n}\n"
  },
  {
    "path": "libsolidity/analysis/PostTypeChecker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/analysis/TypeChecker.h>\n#include <libsolidity/ast/Types.h>\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/ASTVisitor.h>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\nstruct SourceLocation;\n}\n\nnamespace solidity::frontend\n{\n\n/**\n * This module performs analyses on the AST that are done after type checking and assignments of types:\n *  - whether there are circular references in constant variables\n *  - whether override specifiers are actually contracts\n *  - whether a modifier is in a function header\n *  - whether an event is used outside of an emit statement\n *  - whether a variable is declared in a interface\n *  - whether an error uses a reserved signature\n *\n *  When adding a new checker, make sure a visitor that forwards calls that your\n *  checker uses exists in PostTypeChecker. Add missing ones.\n *\n *  The return value for the visit function of a checker is ignored, all nodes\n *  will always be visited.\n */\nclass PostTypeChecker: private ASTConstVisitor\n{\npublic:\n\tstruct Checker: public ASTConstVisitor\n\t{\n\t\tChecker(langutil::ErrorReporter& _errorReporter):\n\t\t\tm_errorReporter(_errorReporter) {}\n\n\t\t/// Called after all source units have been visited.\n\t\tvirtual void finalize() {}\n\tprotected:\n\t\tlangutil::ErrorReporter& m_errorReporter;\n\t};\n\n\t/// @param _errorReporter provides the error logging functionality.\n\tPostTypeChecker(langutil::ErrorReporter& _errorReporter);\n\n\tbool check(ASTNode const& _astRoot);\n\n\t/// Called after all source units have been visited.\n\tbool finalize();\n\nprivate:\n\tbool visit(ContractDefinition const& _contract) override;\n\tvoid endVisit(ContractDefinition const& _contract) override;\n\tvoid endVisit(OverrideSpecifier const& _overrideSpecifier) override;\n\n\tbool visit(VariableDeclaration const& _variable) override;\n\tvoid endVisit(VariableDeclaration const& _variable) override;\n\n\tvoid endVisit(ErrorDefinition const& _error) override;\n\n\tbool visit(EmitStatement const& _emit) override;\n\tvoid endVisit(EmitStatement const& _emit) override;\n\n\tbool visit(RevertStatement const& _revert) override;\n\tvoid endVisit(RevertStatement const& _revert) override;\n\n\tbool visit(FunctionCall const& _functionCall) override;\n\tvoid endVisit(FunctionCall const& _functionCall) override;\n\n\tbool visit(Identifier const& _identifier) override;\n\tbool visit(MemberAccess const& _identifier) override;\n\n\tbool visit(StructDefinition const& _struct) override;\n\tvoid endVisit(StructDefinition const& _struct) override;\n\n\tbool visit(ModifierInvocation const& _modifierInvocation) override;\n\tvoid endVisit(ModifierInvocation const& _modifierInvocation) override;\n\n\tbool visit(ForStatement const& _forStatement) override;\n\tvoid endVisit(ForStatement const& _forStatement) override;\n\n\ttemplate <class T>\n\tbool callVisit(T const& _node)\n\t{\n\t\tfor (auto& checker: m_checkers)\n\t\t\tchecker->visit(_node);\n\n\t\treturn true;\n\t}\n\n\ttemplate <class T>\n\tvoid callEndVisit(T const& _node)\n\t{\n\t\tfor (auto& checker: m_checkers)\n\t\t\tchecker->endVisit(_node);\n\t}\n\n\tlangutil::ErrorReporter& m_errorReporter;\n\n\tstd::vector<std::shared_ptr<Checker>> m_checkers;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/PostTypeContractLevelChecker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that verifies overloads, abstract contracts, function clashes and others\n * checks at contract or function level.\n */\n\n#include <libsolidity/analysis/PostTypeContractLevelChecker.h>\n\n#include <fmt/format.h>\n#include <libsolidity/analysis/ConstantEvaluator.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTUtils.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolutil/FunctionSelector.h>\n#include <liblangutil/ErrorReporter.h>\n\n#include <range/v3/action/reverse.hpp>\n\n#include <limits>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::util;\n\nbool PostTypeContractLevelChecker::check(SourceUnit const& _sourceUnit)\n{\n\tbool noErrors = true;\n\tfor (auto* contract: ASTNode::filteredNodes<ContractDefinition>(_sourceUnit.nodes()))\n\t\tif (!check(*contract))\n\t\t\tnoErrors = false;\n\treturn noErrors;\n}\n\nbool PostTypeContractLevelChecker::check(ContractDefinition const& _contract)\n{\n\tsolAssert(\n\t\t_contract.annotation().creationCallGraph.set() &&\n\t\t_contract.annotation().deployedCallGraph.set(),\n\t\t\"\"\n\t);\n\n\tstd::map<uint32_t, std::map<std::string, SourceLocation>> errorHashes;\n\tfor (ErrorDefinition const* error: _contract.interfaceErrors())\n\t{\n\t\tstd::string signature = error->functionType(true)->externalSignature();\n\t\tuint32_t hash = selectorFromSignatureU32(signature);\n\t\t// Fail if there is a different signature for the same hash.\n\t\tif (!errorHashes[hash].empty() && !errorHashes[hash].count(signature))\n\t\t{\n\t\t\tSourceLocation& otherLocation = errorHashes[hash].begin()->second;\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t4883_error,\n\t\t\t\terror->nameLocation(),\n\t\t\t\tSecondarySourceLocation{}.append(\"This error has a different signature but the same hash: \", otherLocation),\n\t\t\t\t\"Error signature hash collision for \" + error->functionType(true)->externalSignature()\n\t\t\t);\n\t\t}\n\t\telse\n\t\t\terrorHashes[hash][signature] = error->location();\n\t}\n\n\tif (_contract.storageLayoutSpecifier())\n\t\tcheckStorageLayoutSpecifier(_contract);\n\n\twarnStorageLayoutBaseNearStorageEnd(_contract);\n\n\treturn !Error::containsErrors(m_errorReporter.errors());\n}\n\nvoid PostTypeContractLevelChecker::checkStorageLayoutSpecifier(ContractDefinition const& _contract)\n{\n\tStorageLayoutSpecifier const* storageLayoutSpecifier = _contract.storageLayoutSpecifier();\n\tsolAssert(storageLayoutSpecifier);\n\tExpression const& baseSlotExpression = storageLayoutSpecifier->baseSlotExpression();\n\n\tif (!*baseSlotExpression.annotation().isPure)\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t1139_error,\n\t\t\tbaseSlotExpression.location(),\n\t\t\t\"The base slot of the storage layout must be a compile-time constant expression.\"\n\t\t);\n\t\treturn;\n\t}\n\n\tauto const* baseSlotExpressionType = type(baseSlotExpression);\n\tauto const* integerType = dynamic_cast<IntegerType const*>(baseSlotExpressionType);\n\tauto const* rationalType = dynamic_cast<RationalNumberType const*>(baseSlotExpressionType);\n\tif (\n\t\t!integerType &&\n\t\t!rationalType\n\t)\n\t{\n\t\tstd::string errorMsg = \"The base slot of the storage layout must evaluate to an integer\";\n\t\tif (dynamic_cast<AddressType const*>(baseSlotExpressionType))\n\t\t\terrorMsg += \" (the type is 'address' instead)\";\n\t\telse if (auto const* fixedBytesType = dynamic_cast<FixedBytesType const*>(baseSlotExpressionType))\n\t\t\terrorMsg += fmt::format(\n\t\t\t\t\" (the type is 'bytes{}' instead)\",\n\t\t\t\tfixedBytesType->numBytes()\n\t\t\t\t)\n\t\t\t;\n\t\telse if (auto const* userDefinedType = dynamic_cast<UserDefinedValueType const*>(baseSlotExpressionType))\n\t\t\terrorMsg += fmt::format(\n\t\t\t\t\" (the type is '{}' instead)\",\n\t\t\t\tuserDefinedType->canonicalName()\n\t\t\t\t)\n\t\t\t;\n\t\terrorMsg += \".\";\n\n\t\tm_errorReporter.typeError(\n\t\t\t1763_error,\n\t\t\tbaseSlotExpression.location(),\n\t\t\terrorMsg\n\t\t);\n\t\treturn;\n\t}\n\n\trational baseSlotRationalValue;\n\tif (integerType)\n\t{\n\t\tConstantEvaluator::TypedValue typedRational = ConstantEvaluator::evaluate(m_errorReporter, baseSlotExpression);\n\t\tsolAssert(!typedRational.type || dynamic_cast<IntegerType const*>(typedRational.type));\n\t\tif (!typedRational.type)\n\t\t{\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t1505_error,\n\t\t\t\tbaseSlotExpression.location(),\n\t\t\t\t\"The base slot expression contains elements that are not yet supported \"\n\t\t\t\t\"by the internal constant evaluator and therefore cannot be evaluated at compilation time.\"\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tsolAssert(std::holds_alternative<rational>(typedRational.value));\n\t\tbaseSlotRationalValue = std::get<rational>(typedRational.value);\n\t}\n\telse\n\t{\n\t\tsolAssert(rationalType);\n\t\tif (rationalType->isFractional())\n\t\t{\n\t\t\tm_errorReporter.typeError(\n\t\t\t\tErrorId{1763},\n\t\t\t\tbaseSlotExpression.location(),\n\t\t\t\t\"The base slot of the storage layout must evaluate to an integer.\"\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tbaseSlotRationalValue = rationalType->value();\n\t}\n\n\tsolAssert(baseSlotRationalValue.denominator() == 1);\n\tbigint baseSlot = baseSlotRationalValue.numerator();\n\tif (!(0 <= baseSlot && baseSlot <= std::numeric_limits<u256>::max()))\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t6753_error,\n\t\t\tbaseSlotExpression.location(),\n\t\t\tfmt::format(\n\t\t\t\t\"The base slot of the storage layout evaluates to {}, which is outside the range of type uint256.\",\n\t\t\t\tformatNumberReadable(baseSlot)\n\t\t\t)\n\t\t);\n\t\treturn;\n\t}\n\n\tif (!baseSlotExpressionType->isImplicitlyConvertibleTo(*TypeProvider::uint256()))\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t1481_error,\n\t\t\tbaseSlotExpression.location(),\n\t\t\tfmt::format(\n\t\t\t\t\"Base slot expression of type '{}' is not convertible to uint256.\",\n\t\t\t\tbaseSlotExpressionType->humanReadableName()\n\t\t\t)\n\t\t);\n\t\treturn;\n\t}\n\tstorageLayoutSpecifier->annotation().baseSlot = u256(baseSlot);\n\n\tbigint size = contractStorageSizeUpperBound(_contract, VariableDeclaration::Location::Unspecified);\n\tsolAssert(size < bigint(1) << 256);\n\tif (baseSlot + size >= bigint(1) << 256)\n\t\tm_errorReporter.typeError(\n\t\t\t5015_error,\n\t\t\tbaseSlotExpression.location(),\n\t\t\t\"Contract extends past the end of storage when this base slot value is specified.\"\n\t\t);\n}\n\nnamespace\n{\n\nVariableDeclaration const* findLastStorageVariable(ContractDefinition const& _contract)\n{\n\tfor (ContractDefinition const* baseContract: ranges::actions::reverse(_contract.annotation().linearizedBaseContracts))\n\t\tfor (VariableDeclaration const* stateVariable: ranges::actions::reverse(baseContract->stateVariables()))\n\t\t\tif (stateVariable->referenceLocation() == VariableDeclaration::Location::Unspecified)\n\t\t\t\treturn stateVariable;\n\n\treturn nullptr;\n}\n\n}\n\nvoid PostTypeContractLevelChecker::warnStorageLayoutBaseNearStorageEnd(ContractDefinition const& _contract)\n{\n\t// In case of most errors the warning is pointless. E.g. if we're already past storage end.\n\t// If the errors were in the layout specifier, we may not even be able to get values to validate.\n\tif (Error::containsErrors(m_errorReporter.errors()))\n\t\treturn;\n\n\tbigint storageSize = contractStorageSizeUpperBound(_contract, VariableDeclaration::Location::Unspecified);\n\tu256 baseSlot = layoutBaseForInheritanceHierarchy(_contract, DataLocation::Storage);\n\tsolAssert(baseSlot + storageSize <= std::numeric_limits<u256>::max());\n\n\tif (\n\t\tu256 slotsLeft = std::numeric_limits<u256>::max() - baseSlot - u256(storageSize);\n\t\tslotsLeft <= u256(1) << 64\n\t)\n\t{\n\t\tauto const& location = _contract.storageLayoutSpecifier() ?\n\t\t\t_contract.storageLayoutSpecifier()->location() :\n\t\t\t_contract.location();\n\n\t\tVariableDeclaration const* lastStorageVariable = findLastStorageVariable(_contract);\n\n\t\tauto errorID = 3495_error;\n\t\tstd::string errorMsg = \"This contract is very close to the end of storage. This limits its future upgradability.\";\n\t\tif (lastStorageVariable)\n\t\t\tm_errorReporter.warning(\n\t\t\t\terrorID,\n\t\t\t\tlocation,\n\t\t\t\terrorMsg,\n\t\t\t\tSecondarySourceLocation{}.append(\n\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\"There are {} storage slots between this state variable and the end of storage.\",\n\t\t\t\t\t\tformatNumberReadable(slotsLeft)\n\t\t\t\t\t),\n\t\t\t\t\tlastStorageVariable->location()\n\t\t\t\t)\n\t\t\t);\n\t\telse\n\t\t\tm_errorReporter.warning(errorID, location, errorMsg);\n\t}\n}\n"
  },
  {
    "path": "libsolidity/analysis/PostTypeContractLevelChecker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that verifies properties at contract level, after the type checker has run.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTForward.h>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend\n{\n\n/**\n * Component that verifies properties at contract level, after the type checker has run.\n */\nclass PostTypeContractLevelChecker\n{\npublic:\n\texplicit PostTypeContractLevelChecker(langutil::ErrorReporter& _errorReporter):\n\t\tm_errorReporter(_errorReporter)\n\t{}\n\n\t/// Performs checks on the given source ast.\n\t/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings\n\tbool check(SourceUnit const& _sourceUnit);\n\nprivate:\n\t/// Performs checks on the given contract.\n\t/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings\n\tbool check(ContractDefinition const& _contract);\n\n\tvoid checkStorageLayoutSpecifier(ContractDefinition const& _contract);\n\n\tvoid warnStorageLayoutBaseNearStorageEnd(ContractDefinition const& _contract);\n\n\tlangutil::ErrorReporter& m_errorReporter;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/ReferencesResolver.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Component that resolves type names to types and annotates the AST accordingly.\n */\n\n#include <libsolidity/analysis/ReferencesResolver.h>\n#include <libsolidity/analysis/NameAndTypeResolver.h>\n#include <libsolidity/ast/AST.h>\n\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/AST.h>\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/Exceptions.h>\n\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/CommonData.h>\n\n#include <boost/algorithm/string.hpp>\n#include <boost/algorithm/string/split.hpp>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\n\nbool ReferencesResolver::resolve(ASTNode const& _root)\n{\n\tauto errorWatcher = m_errorReporter.errorWatcher();\n\t_root.accept(*this);\n\treturn errorWatcher.ok();\n}\n\nbool ReferencesResolver::visit(Block const& _block)\n{\n\tif (!m_resolveInsideCode)\n\t\treturn false;\n\tm_resolver.setScope(&_block);\n\treturn true;\n}\n\nvoid ReferencesResolver::endVisit(Block const& _block)\n{\n\tif (!m_resolveInsideCode)\n\t\treturn;\n\n\tm_resolver.setScope(_block.scope());\n}\n\nbool ReferencesResolver::visit(TryCatchClause const& _tryCatchClause)\n{\n\tif (!m_resolveInsideCode)\n\t\treturn false;\n\tm_resolver.setScope(&_tryCatchClause);\n\treturn true;\n}\n\nvoid ReferencesResolver::endVisit(TryCatchClause const& _tryCatchClause)\n{\n\tif (!m_resolveInsideCode)\n\t\treturn;\n\n\tm_resolver.setScope(_tryCatchClause.scope());\n}\n\nbool ReferencesResolver::visit(ForStatement const& _for)\n{\n\tif (!m_resolveInsideCode)\n\t\treturn false;\n\tm_resolver.setScope(&_for);\n\treturn true;\n}\n\nvoid ReferencesResolver::endVisit(ForStatement const& _for)\n{\n\tif (!m_resolveInsideCode)\n\t\treturn;\n\tm_resolver.setScope(_for.scope());\n}\n\nvoid ReferencesResolver::endVisit(VariableDeclarationStatement const& _varDeclStatement)\n{\n\tif (!m_resolveInsideCode)\n\t\treturn;\n\tfor (auto const& var: _varDeclStatement.declarations())\n\t\tif (var)\n\t\t\tm_resolver.activateVariable(var->name());\n}\n\nbool ReferencesResolver::visit(VariableDeclaration const& _varDecl)\n{\n\tif (_varDecl.documentation())\n\t\tresolveInheritDoc(*_varDecl.documentation(), _varDecl.annotation());\n\n\tif (m_resolver.experimentalSolidity())\n\t{\n\t\tsolAssert(!_varDecl.hasTypeName());\n\t\tif (_varDecl.typeExpression())\n\t\t{\n\t\t\tScopedSaveAndRestore typeContext{m_typeContext, true};\n\t\t\t_varDecl.typeExpression()->accept(*this);\n\t\t}\n\t\tif (_varDecl.overrides())\n\t\t\t_varDecl.overrides()->accept(*this);\n\t\tif (_varDecl.value())\n\t\t\t_varDecl.value()->accept(*this);\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool ReferencesResolver::visit(Identifier const& _identifier)\n{\n\tauto declarations = m_resolver.nameFromCurrentScope(_identifier.name());\n\tif (declarations.empty())\n\t{\n\t\tif (m_resolver.experimentalSolidity() && m_typeContext)\n\t\t\treturn false;\n\t\tstd::string suggestions = m_resolver.similarNameSuggestions(_identifier.name());\n\t\tstd::string errorMessage = \"Undeclared identifier.\";\n\t\tif (!suggestions.empty())\n\t\t{\n\t\t\tif (\"\\\"\" + _identifier.name() + \"\\\"\" == suggestions)\n\t\t\t\terrorMessage += \" \" + std::move(suggestions) + \" is not (or not yet) visible at this point.\";\n\t\t\telse\n\t\t\t\terrorMessage += \" Did you mean \" + std::move(suggestions) + \"?\";\n\t\t}\n\t\tm_errorReporter.declarationError(7576_error, _identifier.location(), errorMessage);\n\t}\n\telse if (declarations.size() == 1)\n\t\t_identifier.annotation().referencedDeclaration = declarations.front();\n\telse\n\t\t_identifier.annotation().candidateDeclarations = declarations;\n\treturn false;\n}\n\nbool ReferencesResolver::visit(FunctionDefinition const& _functionDefinition)\n{\n\tm_functionDefinitions.push_back(&_functionDefinition);\n\n\tif (_functionDefinition.documentation())\n\t\tresolveInheritDoc(*_functionDefinition.documentation(), _functionDefinition.annotation());\n\n\treturn true;\n}\n\nvoid ReferencesResolver::endVisit(FunctionDefinition const&)\n{\n\tsolAssert(!m_functionDefinitions.empty(), \"\");\n\tm_functionDefinitions.pop_back();\n}\n\nbool ReferencesResolver::visit(ModifierDefinition const& _modifierDefinition)\n{\n\tm_functionDefinitions.push_back(nullptr);\n\n\tif (_modifierDefinition.documentation())\n\t\tresolveInheritDoc(*_modifierDefinition.documentation(), _modifierDefinition.annotation());\n\n\treturn true;\n}\n\nvoid ReferencesResolver::endVisit(ModifierDefinition const&)\n{\n\tsolAssert(!m_functionDefinitions.empty(), \"\");\n\tm_functionDefinitions.pop_back();\n}\n\nvoid ReferencesResolver::endVisit(IdentifierPath const& _path)\n{\n\t// Note that library/functions names in \"using {} for\" directive are resolved separately in visit(UsingForDirective)\n\tstd::vector<Declaration const*> declarations = m_resolver.pathFromCurrentScopeWithAllDeclarations(_path.path());\n\tif (declarations.empty())\n\t{\n\t\tm_errorReporter.fatalDeclarationError(7920_error, _path.location(), \"Identifier not found or not unique.\");\n\t\treturn;\n\t}\n\n\t_path.annotation().referencedDeclaration = declarations.back();\n\t_path.annotation().pathDeclarations = std::move(declarations);\n}\n\nbool ReferencesResolver::visit(UsingForDirective const& _usingFor)\n{\n\tfor (ASTPointer<IdentifierPath> const& path: _usingFor.functionsOrLibrary())\n\t{\n\t\t// _includeInvisibles is enabled here because external library functions are marked invisible.\n\t\t// As unintended side-effects other invisible names (eg.: super, this) may be returned as well.\n\t\t// DeclarationTypeChecker should detect and report such situations.\n\t\tstd::vector<Declaration const*> declarations = m_resolver.pathFromCurrentScopeWithAllDeclarations(path->path(), true /* _includeInvisibles */);\n\t\tif (declarations.empty())\n\t\t{\n\t\t\tstd::string libraryOrFunctionNameErrorMessage =\n\t\t\t\t_usingFor.usesBraces() ?\n\t\t\t\t\"Identifier is not a function name or not unique.\" :\n\t\t\t\t\"Identifier is not a library name.\";\n\t\t\tm_errorReporter.fatalDeclarationError(\n\t\t\t\t9589_error,\n\t\t\t\tpath->location(),\n\t\t\t\tlibraryOrFunctionNameErrorMessage\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\n\t\tpath->annotation().referencedDeclaration = declarations.back();\n\t\tpath->annotation().pathDeclarations = std::move(declarations);\n\t}\n\n\tif (_usingFor.typeName())\n\t\t_usingFor.typeName()->accept(*this);\n\n\treturn false;\n}\n\nbool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)\n{\n\tm_yulAnnotation = &_inlineAssembly.annotation();\n\t(*this)(_inlineAssembly.operations().root());\n\tm_yulAnnotation = nullptr;\n\n\treturn false;\n}\n\nbool ReferencesResolver::visit(Return const& _return)\n{\n\tsolAssert(!m_functionDefinitions.empty(), \"\");\n\t_return.annotation().function = m_functionDefinitions.back();\n\t_return.annotation().functionReturnParameters = m_functionDefinitions.back() ? m_functionDefinitions.back()->returnParameterList().get() : nullptr;\n\treturn true;\n}\n\nbool ReferencesResolver::visit(BinaryOperation const& _binaryOperation)\n{\n\tif (m_resolver.experimentalSolidity())\n\t{\n\t\t_binaryOperation.leftExpression().accept(*this);\n\t\tif (_binaryOperation.getOperator() == Token::Colon)\n\t\t{\n\t\t\tScopedSaveAndRestore typeContext(m_typeContext, !m_typeContext);\n\t\t\t_binaryOperation.rightExpression().accept(*this);\n\t\t}\n\t\telse\n\t\t\t_binaryOperation.rightExpression().accept(*this);\n\t\treturn false;\n\t}\n\telse\n\t\treturn ASTConstVisitor::visit(_binaryOperation);\n}\n\nvoid ReferencesResolver::operator()(yul::FunctionDefinition const& _function)\n{\n\tsolAssert(nativeLocationOf(_function) == originLocationOf(_function), \"\");\n\tvalidateYulIdentifierName(_function.name, nativeLocationOf(_function));\n\tfor (yul::NameWithDebugData const& varName: _function.parameters + _function.returnVariables)\n\t{\n\t\tsolAssert(nativeLocationOf(varName) == originLocationOf(varName), \"\");\n\t\tvalidateYulIdentifierName(varName.name, nativeLocationOf(varName));\n\t}\n\n\tbool wasInsideFunction = m_yulInsideFunction;\n\tm_yulInsideFunction = true;\n\tthis->operator()(_function.body);\n\tm_yulInsideFunction = wasInsideFunction;\n}\n\nvoid ReferencesResolver::operator()(yul::Identifier const& _identifier)\n{\n\tsolAssert(nativeLocationOf(_identifier) == originLocationOf(_identifier), \"\");\n\n\tif (m_resolver.experimentalSolidity())\n\t{\n\t\tstd::vector<std::string> splitName;\n\t\tboost::split(splitName, _identifier.name.str(), boost::is_any_of(\".\"));\n\t\tsolAssert(!splitName.empty());\n\t\tif (splitName.size() > 2)\n\t\t{\n\t\t\tm_errorReporter.declarationError(\n\t\t\t\t4955_error,\n\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\t\"Unsupported identifier in inline assembly.\"\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tstd::string name = splitName.front();\n\t\tauto declarations = m_resolver.nameFromCurrentScope(name);\n\t\tswitch (declarations.size())\n\t\t{\n\t\tcase 0:\n\t\t\tif (splitName.size() > 1)\n\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t7531_error,\n\t\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\t\t\"Unsupported identifier in inline assembly.\"\n\t\t\t\t);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tm_yulAnnotation->externalReferences[&_identifier].declaration = declarations.front();\n\t\t\tm_yulAnnotation->externalReferences[&_identifier].suffix = splitName.size() > 1 ? splitName.back() : \"\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tm_errorReporter.declarationError(\n\t\t\t\t5387_error,\n\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\t\"Multiple matching identifiers. Resolving overloaded identifiers is not supported.\"\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\treturn;\n\t}\n\n\tstatic std::set<std::string> suffixes{\"slot\", \"offset\", \"length\", \"address\", \"selector\"};\n\tstd::string suffix;\n\tfor (std::string const& s: suffixes)\n\t\tif (boost::algorithm::ends_with(_identifier.name.str(), \".\" + s))\n\t\t\tsuffix = s;\n\n\t// Could also use `pathFromCurrentScope`, split by '.'.\n\t// If we do that, suffix should only be set for when it has a special\n\t// meaning, not for normal identifierPaths.\n\tauto declarations = m_resolver.nameFromCurrentScope(_identifier.name.str());\n\tif (!suffix.empty())\n\t{\n\t\t// special mode to access storage variables\n\t\tif (!declarations.empty())\n\t\t\t// the special identifier exists itself, we should not allow that.\n\t\t\treturn;\n\t\tstd::string realName = _identifier.name.str().substr(0, _identifier.name.str().size() - suffix.size() - 1);\n\t\tsolAssert(!realName.empty(), \"Empty name.\");\n\t\tdeclarations = m_resolver.nameFromCurrentScope(realName);\n\t\tif (!declarations.empty())\n\t\t\t// To support proper path resolution, we have to use pathFromCurrentScope.\n\t\t\tsolAssert(!util::contains(realName, '.'), \"\");\n\t}\n\tif (declarations.size() > 1)\n\t{\n\t\tm_errorReporter.declarationError(\n\t\t\t4718_error,\n\t\t\tnativeLocationOf(_identifier),\n\t\t\t\"Multiple matching identifiers. Resolving overloaded identifiers is not supported.\"\n\t\t);\n\t\treturn;\n\t}\n\telse if (declarations.size() == 0)\n\t{\n\t\tif (\n\t\t\tboost::algorithm::ends_with(_identifier.name.str(), \"_slot\") ||\n\t\t\tboost::algorithm::ends_with(_identifier.name.str(), \"_offset\")\n\t\t)\n\t\t\tm_errorReporter.declarationError(\n\t\t\t\t9467_error,\n\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\t\"Identifier not found. Use \\\".slot\\\" and \\\".offset\\\" to access storage or transient storage variables.\"\n\t\t\t);\n\t\treturn;\n\t}\n\tif (auto var = dynamic_cast<VariableDeclaration const*>(declarations.front()))\n\t\tif (var->isLocalVariable() && m_yulInsideFunction)\n\t\t{\n\t\t\tm_errorReporter.declarationError(\n\t\t\t\t6578_error,\n\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\t\"Cannot access local Solidity variables from inside an inline assembly function.\"\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\tm_yulAnnotation->externalReferences[&_identifier].suffix = std::move(suffix);\n\tm_yulAnnotation->externalReferences[&_identifier].declaration = declarations.front();\n}\n\nvoid ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)\n{\n\tfor (auto const& identifier: _varDecl.variables)\n\t{\n\t\tsolAssert(nativeLocationOf(identifier) == originLocationOf(identifier), \"\");\n\t\tvalidateYulIdentifierName(identifier.name, nativeLocationOf(identifier));\n\n\t\tif (\n\t\t\tauto declarations = m_resolver.nameFromCurrentScope(identifier.name.str());\n\t\t\t!declarations.empty()\n\t\t)\n\t\t{\n\t\t\tSecondarySourceLocation ssl;\n\t\t\tfor (auto const* decl: declarations)\n\t\t\t\tssl.append(\"The shadowed declaration is here:\", decl->location());\n\t\t\tif (!ssl.infos.empty())\n\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t3859_error,\n\t\t\t\t\tnativeLocationOf(identifier),\n\t\t\t\t\tssl,\n\t\t\t\t\t\"This declaration shadows a declaration outside the inline assembly block.\"\n\t\t\t\t);\n\t\t}\n\t}\n\n\tif (_varDecl.value)\n\t\tvisit(*_varDecl.value);\n}\n\nvoid ReferencesResolver::resolveInheritDoc(StructuredDocumentation const& _documentation, StructurallyDocumentedAnnotation& _annotation)\n{\n\tswitch (_annotation.docTags.count(\"inheritdoc\"))\n\t{\n\tcase 0:\n\t\tbreak;\n\tcase 1:\n\t{\n\t\tstd::string const& name = _annotation.docTags.find(\"inheritdoc\")->second.content;\n\t\tif (name.empty())\n\t\t{\n\t\t\tm_errorReporter.docstringParsingError(\n\t\t\t\t1933_error,\n\t\t\t\t_documentation.location(),\n\t\t\t\t\"Expected contract name following documentation tag @inheritdoc.\"\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tstd::vector<std::string> path;\n\t\tboost::split(path, name, boost::is_any_of(\".\"));\n\t\tif (any_of(path.begin(), path.end(), [](auto& _str) { return _str.empty(); }))\n\t\t{\n\t\t\tm_errorReporter.docstringParsingError(\n\t\t\t\t5967_error,\n\t\t\t\t_documentation.location(),\n\t\t\t\t\"Documentation tag @inheritdoc reference \\\"\" +\n\t\t\t\tname +\n\t\t\t\t\"\\\" is malformed.\"\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tDeclaration const* result = m_resolver.pathFromCurrentScope(path);\n\n\t\tif (result == nullptr)\n\t\t{\n\t\t\tm_errorReporter.docstringParsingError(\n\t\t\t\t9397_error,\n\t\t\t\t_documentation.location(),\n\t\t\t\t\"Documentation tag @inheritdoc references inexistent contract \\\"\" +\n\t\t\t\tname +\n\t\t\t\t\"\\\".\"\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_annotation.inheritdocReference = dynamic_cast<ContractDefinition const*>(result);\n\n\t\t\tif (!_annotation.inheritdocReference)\n\t\t\t\tm_errorReporter.docstringParsingError(\n\t\t\t\t\t1430_error,\n\t\t\t\t\t_documentation.location(),\n\t\t\t\t\t\"Documentation tag @inheritdoc reference \\\"\" +\n\t\t\t\t\tname +\n\t\t\t\t\t\"\\\" is not a contract.\"\n\t\t\t\t);\n\t\t}\n\t\tbreak;\n\t}\n\tdefault:\n\t\tm_errorReporter.docstringParsingError(\n\t\t\t5142_error,\n\t\t\t_documentation.location(),\n\t\t\t\"Documentation tag @inheritdoc can only be given once.\"\n\t\t);\n\t\tbreak;\n\t}\n}\n\nvoid ReferencesResolver::validateYulIdentifierName(yul::YulName _name, SourceLocation const& _location)\n{\n\tif (util::contains(_name.str(), '.'))\n\t\tm_errorReporter.declarationError(\n\t\t\t3927_error,\n\t\t\t_location,\n\t\t\t\"User-defined identifiers in inline assembly cannot contain '.'.\"\n\t\t);\n\n\tif (std::set<std::string>{\"this\", \"super\", \"_\"}.count(_name.str()))\n\t\tm_errorReporter.declarationError(\n\t\t\t4113_error,\n\t\t\t_location,\n\t\t\t\"The identifier name \\\"\" + _name.str() + \"\\\" is reserved.\"\n\t\t);\n}\n"
  },
  {
    "path": "libsolidity/analysis/ReferencesResolver.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Component that resolves type names to types and annotates the AST accordingly.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <liblangutil/EVMVersion.h>\n#include <libyul/optimiser/ASTWalker.h>\n\n#include <list>\n#include <map>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\nstruct SourceLocation;\n}\n\nnamespace solidity::frontend\n{\n\nclass NameAndTypeResolver;\n\n/**\n * Resolves references to declarations (of variables and types) and also establishes the link\n * between a return statement and the return parameter list.\n */\nclass ReferencesResolver: private ASTConstVisitor, private yul::ASTWalker\n{\npublic:\n\tReferencesResolver(\n\t\tlangutil::ErrorReporter& _errorReporter,\n\t\tNameAndTypeResolver& _resolver,\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tbool _resolveInsideCode = false\n\t):\n\t\tm_errorReporter(_errorReporter),\n\t\tm_resolver(_resolver),\n\t\tm_evmVersion(_evmVersion),\n\t\tm_resolveInsideCode(_resolveInsideCode)\n\t{}\n\n\t/// @returns true if no errors during resolving and throws exceptions on fatal errors.\n\tbool resolve(ASTNode const& _root);\n\nprivate:\n\tusing yul::ASTWalker::visit;\n\tusing yul::ASTWalker::operator();\n\n\tbool visit(Block const& _block) override;\n\tvoid endVisit(Block const& _block) override;\n\tbool visit(TryCatchClause const& _tryCatchClause) override;\n\tvoid endVisit(TryCatchClause const& _tryCatchClause) override;\n\tbool visit(ForStatement const& _for) override;\n\tvoid endVisit(ForStatement const& _for) override;\n\tvoid endVisit(VariableDeclarationStatement const& _varDeclStatement) override;\n\tbool visit(VariableDeclaration const& _varDecl) override;\n\tbool visit(Identifier const& _identifier) override;\n\tbool visit(FunctionDefinition const& _functionDefinition) override;\n\tvoid endVisit(FunctionDefinition const& _functionDefinition) override;\n\tbool visit(ModifierDefinition const& _modifierDefinition) override;\n\tvoid endVisit(ModifierDefinition const& _modifierDefinition) override;\n\tvoid endVisit(IdentifierPath const& _path) override;\n\tbool visit(InlineAssembly const& _inlineAssembly) override;\n\tbool visit(Return const& _return) override;\n\tbool visit(UsingForDirective const& _usingFor) override;\n\tbool visit(BinaryOperation const& _binaryOperation) override;\n\n\tvoid operator()(yul::FunctionDefinition const& _function) override;\n\tvoid operator()(yul::Identifier const& _identifier) override;\n\tvoid operator()(yul::VariableDeclaration const& _varDecl) override;\n\n\tvoid resolveInheritDoc(StructuredDocumentation const& _documentation, StructurallyDocumentedAnnotation& _annotation);\n\n\t/// Checks if the name contains a '.'.\n\tvoid validateYulIdentifierName(yul::YulName _name, langutil::SourceLocation const& _location);\n\n\tlangutil::ErrorReporter& m_errorReporter;\n\tNameAndTypeResolver& m_resolver;\n\tlangutil::EVMVersion m_evmVersion;\n\t/// Stack of function definitions.\n\tstd::vector<FunctionDefinition const*> m_functionDefinitions;\n\tbool const m_resolveInsideCode;\n\n\tInlineAssemblyAnnotation* m_yulAnnotation = nullptr;\n\tbool m_yulInsideFunction = false;\n\tbool m_typeContext = false;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/Scoper.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/Scoper.h>\n\n#include <libsolidity/ast/AST.h>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\n\nvoid Scoper::assignScopes(ASTNode const& _astRoot)\n{\n\tScoper scoper;\n\t_astRoot.accept(scoper);\n}\n\nbool Scoper::visit(ContractDefinition const& _contract)\n{\n\tsolAssert(m_contract == nullptr, \"\");\n\tm_contract = &_contract;\n\treturn ASTConstVisitor::visit(_contract);\n}\n\nvoid Scoper::endVisit(ContractDefinition const& _contract)\n{\n\tsolAssert(m_contract == &_contract, \"\");\n\tm_contract = nullptr;\n\tASTConstVisitor::endVisit(_contract);\n}\n\nbool Scoper::visitNode(ASTNode const& _node)\n{\n\tif (auto const* scopable = dynamic_cast<Scopable const*>(&_node))\n\t{\n\t\tscopable->annotation().scope = m_scopes.empty() ? nullptr : m_scopes.back();\n\t\tscopable->annotation().contract = m_contract;\n\t}\n\tif (dynamic_cast<ScopeOpener const*>(&_node))\n\t\tm_scopes.push_back(&_node);\n\treturn true;\n}\n\nvoid Scoper::endVisitNode(ASTNode const& _node)\n{\n\tif (dynamic_cast<ScopeOpener const*>(&_node))\n\t\tm_scopes.pop_back();\n}\n"
  },
  {
    "path": "libsolidity/analysis/Scoper.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/ASTVisitor.h>\n\nnamespace solidity::frontend\n{\n\n/**\n * AST visitor that assigns syntactic scopes.\n */\nclass Scoper: private ASTConstVisitor\n{\npublic:\n\tstatic void assignScopes(ASTNode const& _astRoot);\n\nprivate:\n\tbool visit(ContractDefinition const& _contract) override;\n\tvoid endVisit(ContractDefinition const& _contract) override;\n\tbool visitNode(ASTNode const& _node) override;\n\tvoid endVisitNode(ASTNode const& _node) override;\n\n\tContractDefinition const* m_contract = nullptr;\n\tstd::vector<ASTNode const*> m_scopes;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/StaticAnalyzer.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Federico Bond <federicobond@gmail.com>\n * @date 2016\n * Static analyzer and checker.\n */\n\n#include <libsolidity/analysis/StaticAnalyzer.h>\n#include <libsolidity/analysis/ConstantEvaluator.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTUtils.h>\n#include <liblangutil/ErrorReporter.h>\n\n#include <range/v3/view/enumerate.hpp>\n\n#include <memory>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\n/**\n * Helper class that determines whether a contract's constructor uses inline assembly.\n */\nclass solidity::frontend::ConstructorUsesAssembly\n{\npublic:\n\t/// @returns true if and only if the contract's or any of its bases' constructors\n\t/// use inline assembly.\n\tbool check(ContractDefinition const& _contract)\n\t{\n\t\tfor (auto const* base: _contract.annotation().linearizedBaseContracts)\n\t\t\tif (checkInternal(*base))\n\t\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\nprivate:\n\tclass Checker: public ASTConstVisitor\n\t{\n\tpublic:\n\t\tChecker(FunctionDefinition const& _f) { _f.accept(*this); }\n\t\tbool visit(InlineAssembly const&) override { assemblySeen = true; return false; }\n\t\tbool assemblySeen = false;\n\t};\n\n\tbool checkInternal(ContractDefinition const& _contract)\n\t{\n\t\tif (!m_usesAssembly.count(&_contract))\n\t\t{\n\t\t\tbool usesAssembly = false;\n\t\t\tif (_contract.constructor())\n\t\t\t\tusesAssembly = Checker{*_contract.constructor()}.assemblySeen;\n\t\t\tm_usesAssembly[&_contract] = usesAssembly;\n\t\t}\n\t\treturn m_usesAssembly[&_contract];\n\t}\n\n\tstd::map<ContractDefinition const*, bool> m_usesAssembly;\n};\n\nStaticAnalyzer::StaticAnalyzer(ErrorReporter& _errorReporter):\n\tm_errorReporter(_errorReporter)\n{\n}\n\nStaticAnalyzer::~StaticAnalyzer()\n{\n}\n\nbool StaticAnalyzer::analyze(SourceUnit const& _sourceUnit)\n{\n\t_sourceUnit.accept(*this);\n\treturn !Error::containsErrors(m_errorReporter.errors());\n}\n\nbool StaticAnalyzer::visit(Assignment const& _assignment)\n{\n\tType const* lhsType = _assignment.leftHandSide().annotation().type;\n\tType const* rhsType = _assignment.rightHandSide().annotation().type;\n\tsolAssert(lhsType && rhsType, \"Both left and right hand side expressions in an assignment must have a type.\");\n\n\tif (dynamic_cast<TupleType const*>(lhsType) && dynamic_cast<TupleType const*>(rhsType))\n\t\tcheckDoubleStorageAssignment(_assignment);\n\n\treturn true;\n}\n\nbool StaticAnalyzer::visit(ContractDefinition const& _contract)\n{\n\tm_library = _contract.isLibrary();\n\tm_currentContract = &_contract;\n\treturn true;\n}\n\nvoid StaticAnalyzer::endVisit(ContractDefinition const&)\n{\n\tm_library = false;\n\tm_currentContract = nullptr;\n}\n\nbool StaticAnalyzer::visit(FunctionDefinition const& _function)\n{\n\tif (_function.isImplemented())\n\t\tm_currentFunction = &_function;\n\telse\n\t\tsolAssert(!m_currentFunction, \"\");\n\tsolAssert(m_localVarUseCount.empty(), \"\");\n\tm_constructor = _function.isConstructor();\n\treturn true;\n}\n\nvoid StaticAnalyzer::endVisit(FunctionDefinition const&)\n{\n\tif (m_currentFunction && !m_currentFunction->body().statements().empty())\n\t\tfor (auto const& var: m_localVarUseCount)\n\t\t\tif (var.second == 0)\n\t\t\t{\n\t\t\t\tif (var.first.second->isCallableOrCatchParameter())\n\t\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t\t5667_error,\n\t\t\t\t\t\tvar.first.second->location(),\n\t\t\t\t\t\t\"Unused \" +\n\t\t\t\t\t\tstd::string(var.first.second->isTryCatchParameter() ? \"try/catch\" : \"function\") +\n\t\t\t\t\t\t\" parameter. Remove or comment out the variable name to silence this warning.\"\n\t\t\t\t\t);\n\t\t\t\telse\n\t\t\t\t\tm_errorReporter.warning(2072_error, var.first.second->location(), \"Unused local variable.\");\n\t\t\t}\n\tm_localVarUseCount.clear();\n\tm_constructor = false;\n\tm_currentFunction = nullptr;\n}\n\nbool StaticAnalyzer::visit(Identifier const& _identifier)\n{\n\tif (m_currentFunction)\n\t\tif (auto var = dynamic_cast<VariableDeclaration const*>(_identifier.annotation().referencedDeclaration))\n\t\t{\n\t\t\tsolAssert(!var->name().empty(), \"\");\n\t\t\tif (var->isLocalVariable())\n\t\t\t\tm_localVarUseCount[std::make_pair(var->id(), var)] += 1;\n\t\t}\n\treturn true;\n}\n\nbool StaticAnalyzer::visit(VariableDeclaration const& _variable)\n{\n\tif (m_currentFunction)\n\t{\n\t\tsolAssert(_variable.isLocalVariable(), \"\");\n\t\tif (_variable.name() != \"\")\n\t\t\t// This is not a no-op, the entry might pre-exist.\n\t\t\tm_localVarUseCount[std::make_pair(_variable.id(), &_variable)] += 0;\n\t}\n\n\tif (_variable.isStateVariable() || _variable.referenceLocation() == VariableDeclaration::Location::Storage)\n\t\tif (auto varType = dynamic_cast<CompositeType const*>(_variable.annotation().type))\n\t\t\tfor (Type const* type: varType->fullDecomposition())\n\t\t\t\tif (type->storageSizeUpperBound() >= (bigint(1) << 64))\n\t\t\t\t{\n\t\t\t\t\tstd::string message = \"Type \" + type->toString(true) +\n\t\t\t\t\t\t\" covers a large part of storage and thus makes collisions likely.\"\n\t\t\t\t\t\t\" Either use mappings or dynamic arrays and allow their size to be increased only\"\n\t\t\t\t\t\t\" in small quantities per transaction.\";\n\t\t\t\t\tm_errorReporter.warning(7325_error, _variable.typeName().location(), message);\n\t\t\t\t}\n\n\treturn true;\n}\n\nbool StaticAnalyzer::visit(Return const& _return)\n{\n\t// If the return has an expression, it counts as\n\t// a \"use\" of the return parameters.\n\tif (m_currentFunction && _return.expression())\n\t\tfor (auto const& var: m_currentFunction->returnParameters())\n\t\t\tif (!var->name().empty())\n\t\t\t\tm_localVarUseCount[std::make_pair(var->id(), var.get())] += 1;\n\treturn true;\n}\n\nbool StaticAnalyzer::visit(ExpressionStatement const& _statement)\n{\n\tif (*_statement.expression().annotation().isPure)\n\t\tm_errorReporter.warning(\n\t\t\t6133_error,\n\t\t\t_statement.location(),\n\t\t\t\"Statement has no effect.\"\n\t\t);\n\n\treturn true;\n}\n\nbool StaticAnalyzer::visit(MemberAccess const& _memberAccess)\n{\n\tif (MagicType const* type = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type))\n\t{\n\t\tif (type->kind() == MagicType::Kind::Message && _memberAccess.memberName() == \"gas\")\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t1400_error,\n\t\t\t\t_memberAccess.location(),\n\t\t\t\t\"\\\"msg.gas\\\" has been deprecated in favor of \\\"gasleft()\\\"\"\n\t\t\t);\n\t\telse if (type->kind() == MagicType::Kind::Block && _memberAccess.memberName() == \"blockhash\")\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t8113_error,\n\t\t\t\t_memberAccess.location(),\n\t\t\t\t\"\\\"block.blockhash()\\\" has been deprecated in favor of \\\"blockhash()\\\"\"\n\t\t\t);\n\t\telse if (type->kind() == MagicType::Kind::MetaType && _memberAccess.memberName() == \"runtimeCode\")\n\t\t{\n\t\t\tif (!m_constructorUsesAssembly)\n\t\t\t\tm_constructorUsesAssembly = std::make_unique<ConstructorUsesAssembly>();\n\t\t\tContractType const& contract = dynamic_cast<ContractType const&>(*type->typeArgument());\n\t\t\tif (m_constructorUsesAssembly->check(contract.contractDefinition()))\n\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t6417_error,\n\t\t\t\t\t_memberAccess.location(),\n\t\t\t\t\t\"The constructor of the contract (or its base) uses inline assembly. \"\n\t\t\t\t\t\"Because of that, it might be that the deployed bytecode is different from type(...).runtimeCode.\"\n\t\t\t\t);\n\t\t}\n\t\telse if (\n\t\t\tm_currentFunction &&\n\t\t\tm_currentFunction->isReceive() &&\n\t\t\ttype->kind() == MagicType::Kind::Message &&\n\t\t\t_memberAccess.memberName() == \"data\"\n\t\t)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t7139_error,\n\t\t\t\t_memberAccess.location(),\n\t\t\t\tR\"(\"msg.data\" cannot be used inside of \"receive\" function.)\"\n\t\t\t);\n\t}\n\n\tif (_memberAccess.memberName() == \"callcode\")\n\t\tif (auto const* type = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type))\n\t\t\tif (type->kind() == FunctionType::Kind::BareCallCode)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t2256_error,\n\t\t\t\t\t_memberAccess.location(),\n\t\t\t\t\t\"\\\"callcode\\\" has been deprecated in favour of \\\"delegatecall\\\".\"\n\t\t\t\t);\n\n\tif (m_constructor)\n\t{\n\t\tauto const* expr = &_memberAccess.expression();\n\t\twhile (expr)\n\t\t{\n\t\t\tif (auto id = dynamic_cast<Identifier const*>(expr))\n\t\t\t{\n\t\t\t\tif (id->name() == \"this\")\n\t\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t\t5805_error,\n\t\t\t\t\t\tid->location(),\n\t\t\t\t\t\t\"\\\"this\\\" used in constructor. \"\n\t\t\t\t\t\t\"Note that external functions of a contract \"\n\t\t\t\t\t\t\"cannot be called while it is being constructed.\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (auto tuple = dynamic_cast<TupleExpression const*>(expr))\n\t\t\t{\n\t\t\t\tif (tuple->components().size() == 1)\n\t\t\t\t\texpr = tuple->components().front().get();\n\t\t\t\telse\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool StaticAnalyzer::visit(InlineAssembly const& _inlineAssembly)\n{\n\tif (!m_currentFunction)\n\t\treturn true;\n\n\tfor (auto const& ref: _inlineAssembly.annotation().externalReferences)\n\t{\n\t\tif (auto var = dynamic_cast<VariableDeclaration const*>(ref.second.declaration))\n\t\t{\n\t\t\tsolAssert(!var->name().empty(), \"\");\n\t\t\tif (var->isLocalVariable())\n\t\t\t\tm_localVarUseCount[std::make_pair(var->id(), var)] += 1;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nbool StaticAnalyzer::visit(BinaryOperation const& _operation)\n{\n\tif (\n\t\t*_operation.rightExpression().annotation().isPure &&\n\t\t(_operation.getOperator() == Token::Div || _operation.getOperator() == Token::Mod) &&\n\t\tConstantEvaluator::evaluate(m_errorReporter, _operation.leftExpression()).type\n\t)\n\t\tif (\n\t\t\tauto rhs = ConstantEvaluator::evaluate(m_errorReporter, _operation.rightExpression());\n\t\t\tstd::holds_alternative<rational>(rhs.value) &&\n\t\t\tstd::get<rational>(rhs.value) == 0\n\t\t)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t1211_error,\n\t\t\t\t_operation.location(),\n\t\t\t\t(_operation.getOperator() == Token::Div) ? \"Division by zero.\" : \"Modulo zero.\"\n\t\t\t);\n\n\treturn true;\n}\n\nbool StaticAnalyzer::visit(FunctionCall const& _functionCall)\n{\n\tif (*_functionCall.annotation().kind == FunctionCallKind::FunctionCall)\n\t{\n\t\tauto functionType = dynamic_cast<FunctionType const*>(_functionCall.expression().annotation().type);\n\t\tsolAssert(functionType, \"\");\n\t\tif (functionType->kind() == FunctionType::Kind::AddMod || functionType->kind() == FunctionType::Kind::MulMod)\n\t\t{\n\t\t\tsolAssert(_functionCall.arguments().size() == 3, \"\");\n\t\t\tif (*_functionCall.arguments()[2]->annotation().isPure)\n\t\t\t\tif (\n\t\t\t\t\tauto lastArg = ConstantEvaluator::evaluate(m_errorReporter, *(_functionCall.arguments())[2]);\n\t\t\t\t\tstd::holds_alternative<rational>(lastArg.value) &&\n\t\t\t\t\tstd::get<rational>(lastArg.value) == 0\n\t\t\t\t)\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t4195_error,\n\t\t\t\t\t\t_functionCall.location(),\n\t\t\t\t\t\t\"Arithmetic modulo zero.\"\n\t\t\t\t\t);\n\t\t}\n\t\tif (\n\t\t\tm_currentContract &&\n\t\t\tm_currentContract->isLibrary() &&\n\t\t\tfunctionType->kind() == FunctionType::Kind::DelegateCall &&\n\t\t\tfunctionType->declaration().scope() == m_currentContract\n\t\t)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t6700_error,\n\t\t\t\t_functionCall.location(),\n\t\t\t\tSecondarySourceLocation().append(\n\t\t\t\t\t\"The function declaration is here:\",\n\t\t\t\t\tfunctionType->declaration().scope()->location()\n\t\t\t\t),\n\t\t\t\t\"Libraries cannot call their own functions externally.\"\n\t\t\t);\n\t}\n\treturn true;\n}\n\nvoid StaticAnalyzer::checkDoubleStorageAssignment(Assignment const& _assignment)\n{\n\tsize_t storageToStorageCopies = 0;\n\tsize_t toStorageCopies = 0;\n\tsize_t storageByteArrayPushes = 0;\n\tsize_t storageByteAccesses = 0;\n\tauto count = [&](TupleExpression const& _lhs, TupleType const& _rhs, auto _recurse) -> void {\n\t\tTupleType const& lhsType = dynamic_cast<TupleType const&>(*type(_lhs));\n\t\tTupleExpression const* lhsResolved = dynamic_cast<TupleExpression const*>(resolveOuterUnaryTuples(&_lhs));\n\n\t\tsolAssert(lhsResolved && lhsResolved->components().size() == lhsType.components().size());\n\t\tif (lhsType.components().size() != _rhs.components().size())\n\t\t{\n\t\t\tsolAssert(m_errorReporter.hasErrors(), \"\");\n\t\t\treturn;\n\t\t}\n\n\t\tfor (auto&& [index, componentType]: lhsType.components() | ranges::views::enumerate)\n\t\t{\n\t\t\tif (ReferenceType const* ref = dynamic_cast<ReferenceType const*>(componentType))\n\t\t\t{\n\t\t\t\tif (ref->dataStoredIn(DataLocation::Storage) && !ref->isPointer())\n\t\t\t\t{\n\t\t\t\t\ttoStorageCopies++;\n\t\t\t\t\tif (_rhs.components()[index]->dataStoredIn(DataLocation::Storage))\n\t\t\t\t\t\tstorageToStorageCopies++;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (FixedBytesType const* bytesType = dynamic_cast<FixedBytesType const*>(componentType))\n\t\t\t{\n\t\t\t\tif (bytesType->numBytes() == 1)\n\t\t\t\t{\n\t\t\t\t\tif (FunctionCall const* lhsCall = dynamic_cast<FunctionCall const*>(resolveOuterUnaryTuples(lhsResolved->components().at(index).get())))\n\t\t\t\t\t{\n\t\t\t\t\t\tFunctionType const& callType = dynamic_cast<FunctionType const&>(*type(lhsCall->expression()));\n\t\t\t\t\t\tif (callType.kind() == FunctionType::Kind::ArrayPush)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tArrayType const& arrayType = dynamic_cast<ArrayType const&>(*callType.selfType());\n\t\t\t\t\t\t\tif (arrayType.isByteArray() && arrayType.dataStoredIn(DataLocation::Storage))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t++storageByteAccesses;\n\t\t\t\t\t\t\t\t++storageByteArrayPushes;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (IndexAccess const* indexAccess = dynamic_cast<IndexAccess const*>(resolveOuterUnaryTuples(lhsResolved->components().at(index).get())))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (ArrayType const* arrayType = dynamic_cast<ArrayType const*>(type(indexAccess->baseExpression())))\n\t\t\t\t\t\t\tif (arrayType->isByteArray() && arrayType->dataStoredIn(DataLocation::Storage))\n\t\t\t\t\t\t\t\t++storageByteAccesses;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (dynamic_cast<TupleType const*>(componentType))\n\t\t\t\tif (auto const* lhsNested = dynamic_cast<TupleExpression const*>(lhsResolved->components().at(index).get()))\n\t\t\t\t\tif (auto const* rhsNestedType = dynamic_cast<TupleType const*>(_rhs.components().at(index)))\n\t\t\t\t\t\t_recurse(\n\t\t\t\t\t\t\t*lhsNested,\n\t\t\t\t\t\t\t*rhsNestedType,\n\t\t\t\t\t\t\t_recurse\n\t\t\t\t\t\t);\n\t\t}\n\t};\n\n\tTupleExpression const* lhsTupleExpression = dynamic_cast<TupleExpression const*>(&_assignment.leftHandSide());\n\tif (!lhsTupleExpression)\n\t{\n\t\tsolAssert(m_errorReporter.hasErrors());\n\t\treturn;\n\t}\n\tcount(\n\t\t*lhsTupleExpression,\n\t\tdynamic_cast<TupleType const&>(*type(_assignment.rightHandSide())),\n\t\tcount\n\t);\n\n\tif (storageToStorageCopies >= 1 && toStorageCopies >= 2)\n\t\tm_errorReporter.warning(\n\t\t\t7238_error,\n\t\t\t_assignment.location(),\n\t\t\t\"This assignment performs two copies to storage. Since storage copies do not first \"\n\t\t\t\"copy to a temporary location, one of them might be overwritten before the second \"\n\t\t\t\"is executed and thus may have unexpected effects. It is safer to perform the copies \"\n\t\t\t\"separately or assign to storage pointers first.\"\n\t\t);\n\n\tif (storageByteArrayPushes >= 1 && storageByteAccesses >= 2)\n\t\tm_errorReporter.warning(\n\t\t\t7239_error,\n\t\t\t_assignment.location(),\n\t\t\t\"This assignment involves multiple accesses to a bytes array in storage while simultaneously enlarging it. \"\n\t\t\t\"When a bytes array is enlarged, it may transition from short storage layout to long storage layout, \"\n\t\t\t\"which invalidates all references to its elements. It is safer to only enlarge byte arrays in a single \"\n\t\t\t\"operation, one element at a time.\"\n\t\t);\n}\n"
  },
  {
    "path": "libsolidity/analysis/StaticAnalyzer.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Federico Bond <federicobond@gmail.com>\n * @date 2016\n * Static analyzer and checker.\n */\n\n#pragma once\n\n#include <libsolidity/analysis/TypeChecker.h>\n#include <libsolidity/ast/Types.h>\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/ASTVisitor.h>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend\n{\n\nclass ConstructorUsesAssembly;\n\n\n/**\n * The module that performs static analysis on the AST.\n * In this context, static analysis is anything that can produce warnings which can help\n * programmers write cleaner code. For every warning generated here, it has to be possible to write\n * equivalent code that does not generate the warning.\n */\nclass StaticAnalyzer: private ASTConstVisitor\n{\npublic:\n\t/// @param _errorReporter provides the error logging functionality.\n\texplicit StaticAnalyzer(langutil::ErrorReporter& _errorReporter);\n\t~StaticAnalyzer() override;\n\n\t/// Performs static analysis on the given source unit and all of its sub-nodes.\n\t/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings\n\tbool analyze(SourceUnit const& _sourceUnit);\n\nprivate:\n\n\tbool visit(ContractDefinition const& _contract) override;\n\tvoid endVisit(ContractDefinition const& _contract) override;\n\n\tbool visit(FunctionDefinition const& _function) override;\n\tvoid endVisit(FunctionDefinition const& _function) override;\n\n\tbool visit(Assignment const& _assignment) override;\n\tbool visit(ExpressionStatement const& _statement) override;\n\tbool visit(VariableDeclaration const& _variable) override;\n\tbool visit(Identifier const& _identifier) override;\n\tbool visit(Return const& _return) override;\n\tbool visit(MemberAccess const& _memberAccess) override;\n\tbool visit(InlineAssembly const& _inlineAssembly) override;\n\tbool visit(BinaryOperation const& _operation) override;\n\tbool visit(FunctionCall const& _functionCall) override;\n\n\t/// Checks (and warns) if a tuple assignment might cause unexpected overwrites in storage.\n\t/// Should only be called if the left hand side is tuple-typed.\n\tvoid checkDoubleStorageAssignment(Assignment const& _assignment);\n\n\tlangutil::ErrorReporter& m_errorReporter;\n\n\t/// Flag that indicates whether the current contract definition is a library.\n\tbool m_library = false;\n\n\t/// Number of uses of each (named) local variable in a function, counter is initialized with zero.\n\t/// Pairs of AST ids and pointers are used as keys to ensure a deterministic order\n\t/// when traversing.\n\tstd::map<std::pair<size_t, VariableDeclaration const*>, int> m_localVarUseCount;\n\n\t/// Cache that holds information about whether a contract's constructor\n\t/// uses inline assembly.\n\tstd::unique_ptr<ConstructorUsesAssembly> m_constructorUsesAssembly;\n\n\tFunctionDefinition const* m_currentFunction = nullptr;\n\n\t/// Flag that indicates a constructor.\n\tbool m_constructor = false;\n\n\t/// Current contract.\n\tContractDefinition const* m_currentContract = nullptr;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/SyntaxChecker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/SyntaxChecker.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ExperimentalFeatures.h>\n#include <libsolidity/interface/Version.h>\n\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/AST.h>\n\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/SemVerHandler.h>\n\n#include <libsolutil/UTF8.h>\n\n#include <string>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::util;\n\nbool SyntaxChecker::checkSyntax(ASTNode const& _astRoot)\n{\n\t_astRoot.accept(*this);\n\treturn !Error::containsErrors(m_errorReporter.errors());\n}\n\nbool SyntaxChecker::visit(SourceUnit const& _sourceUnit)\n{\n\tm_versionPragmaFound = false;\n\tm_sourceUnit = &_sourceUnit;\n\treturn true;\n}\n\nvoid SyntaxChecker::endVisit(SourceUnit const& _sourceUnit)\n{\n\tif (!m_versionPragmaFound)\n\t{\n\t\tstd::string errorString(\"Source file does not specify required compiler version!\");\n\t\tSemVerVersion recommendedVersion{std::string(VersionString)};\n\t\tif (!recommendedVersion.isPrerelease())\n\t\t\terrorString +=\n\t\t\t\t\" Consider adding \\\"pragma solidity ^\" +\n\t\t\t\tstd::to_string(recommendedVersion.major()) +\n\t\t\t\tstd::string(\".\") +\n\t\t\t\tstd::to_string(recommendedVersion.minor()) +\n\t\t\t\tstd::string(\".\") +\n\t\t\t\tstd::to_string(recommendedVersion.patch()) +\n\t\t\t\tstd::string(\";\\\"\");\n\n\t\t// when reporting the warning, print the source name only\n\t\tm_errorReporter.warning(3420_error, {-1, -1, _sourceUnit.location().sourceName}, errorString);\n\t}\n\tif (!m_sourceUnit->annotation().useABICoderV2.set())\n\t\tm_sourceUnit->annotation().useABICoderV2 = true;\n\tm_sourceUnit = nullptr;\n}\n\nbool SyntaxChecker::visit(PragmaDirective const& _pragma)\n{\n\tsolAssert(!_pragma.tokens().empty(), \"\");\n\tsolAssert(_pragma.tokens().size() == _pragma.literals().size(), \"\");\n\tif (_pragma.tokens()[0] != Token::Identifier)\n\t\tm_errorReporter.syntaxError(5226_error, _pragma.location(), \"Invalid pragma \\\"\" + _pragma.literals()[0] + \"\\\"\");\n\telse if (_pragma.literals()[0] == \"experimental\")\n\t{\n\t\tsolAssert(m_sourceUnit, \"\");\n\t\tstd::vector<std::string> literals(_pragma.literals().begin() + 1, _pragma.literals().end());\n\t\tif (literals.empty())\n\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t9679_error,\n\t\t\t\t_pragma.location(),\n\t\t\t\t\"Experimental feature name is missing.\"\n\t\t\t);\n\t\telse if (literals.size() > 1)\n\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t6022_error,\n\t\t\t\t_pragma.location(),\n\t\t\t\t\"Stray arguments.\"\n\t\t\t);\n\t\telse\n\t\t{\n\t\t\tstd::string const literal = literals[0];\n\t\t\tif (literal.empty())\n\t\t\t\tm_errorReporter.syntaxError(3250_error, _pragma.location(), \"Empty experimental feature name is invalid.\");\n\t\t\telse if (!ExperimentalFeatureNames.count(literal))\n\t\t\t\tm_errorReporter.syntaxError(8491_error, _pragma.location(), \"Unsupported experimental feature name.\");\n\t\t\telse if (m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeatureNames.at(literal)))\n\t\t\t\tm_errorReporter.syntaxError(1231_error, _pragma.location(), \"Duplicate experimental feature name.\");\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto feature = ExperimentalFeatureNames.at(literal);\n\t\t\t\tm_sourceUnit->annotation().experimentalFeatures.insert(feature);\n\t\t\t\tif (!ExperimentalFeatureWithoutWarning.count(feature))\n\t\t\t\t{\n\t\t\t\t\tif (!m_experimental)\n\t\t\t\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t\t\t\t2816_error,\n\t\t\t\t\t\t\t_pragma.location(),\n\t\t\t\t\t\t\t\"Experimental pragmas can only be used if experimental mode is enabled. To enable experimental mode, use the --experimental flag.\"\n\t\t\t\t\t\t);\n\t\t\t\t\telse\n\t\t\t\t\t\tm_errorReporter.warning(2264_error, _pragma.location(), \"Experimental features are turned on. Do not use experimental features on live deployments.\");\n\t\t\t\t}\n\n\t\t\t\tif (feature == ExperimentalFeature::ABIEncoderV2)\n\t\t\t\t{\n\t\t\t\t\tif (m_sourceUnit->annotation().useABICoderV2.set())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!*m_sourceUnit->annotation().useABICoderV2)\n\t\t\t\t\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t\t\t\t\t8273_error,\n\t\t\t\t\t\t\t\t_pragma.location(),\n\t\t\t\t\t\t\t\t\"ABI coder v1 has already been selected through \\\"pragma abicoder v1\\\".\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tm_sourceUnit->annotation().useABICoderV2 = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\telse if (_pragma.literals()[0] == \"abicoder\")\n\t{\n\t\tsolAssert(m_sourceUnit, \"\");\n\t\tif (\n\t\t\t_pragma.literals().size() != 2 ||\n\t\t\t!std::set<std::string>{\"v1\", \"v2\"}.count(_pragma.literals()[1])\n\t\t)\n\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t2745_error,\n\t\t\t\t_pragma.location(),\n\t\t\t\t\"Expected either \\\"pragma abicoder v1\\\" or \\\"pragma abicoder v2\\\".\"\n\t\t\t);\n\t\telse if (m_sourceUnit->annotation().useABICoderV2.set())\n\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t3845_error,\n\t\t\t\t_pragma.location(),\n\t\t\t\t\"ABI coder has already been selected for this source unit.\"\n\t\t\t);\n\t\telse\n\t\t\tm_sourceUnit->annotation().useABICoderV2 = (_pragma.literals()[1] == \"v2\");\n\n\t\tif (\n\t\t\t_pragma.literals().size() > 1 &&\n\t\t\t_pragma.literals()[1] == \"v1\"\n\t\t)\n\t\t\tm_errorReporter.warning(\n\t\t\t\t9511_error,\n\t\t\t\t_pragma.location(),\n\t\t\t\t\"ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\"\n\t\t\t);\n\t}\n\telse if (_pragma.literals()[0] == \"solidity\")\n\t{\n\t\ttry\n\t\t{\n\t\t\tstd::vector<Token> tokens(_pragma.tokens().begin() + 1, _pragma.tokens().end());\n\t\t\tstd::vector<std::string> literals(_pragma.literals().begin() + 1, _pragma.literals().end());\n\t\t\tSemVerMatchExpressionParser parser(tokens, literals);\n\t\t\tSemVerMatchExpression matchExpression = parser.parse();\n\t\t\tstatic SemVerVersion const currentVersion{std::string(VersionString)};\n\t\t\tsolAssert(matchExpression.matches(currentVersion));\n\t\t\tm_versionPragmaFound = true;\n\t\t}\n\t\tcatch (SemVerError const&)\n\t\t{\n\t\t\t// An unparsable version pragma is an unrecoverable fatal error in the parser.\n\t\t\tsolAssert(false);\n\t\t}\n\t}\n\telse\n\t\tm_errorReporter.syntaxError(4936_error, _pragma.location(), \"Unknown pragma \\\"\" + _pragma.literals()[0] + \"\\\"\");\n\n\treturn true;\n}\n\nbool SyntaxChecker::visit(ModifierDefinition const&)\n{\n\tm_placeholderFound = false;\n\treturn true;\n}\n\nvoid SyntaxChecker::endVisit(ModifierDefinition const& _modifier)\n{\n\tif (_modifier.isImplemented() && !m_placeholderFound)\n\t\tm_errorReporter.syntaxError(2883_error, _modifier.body().location(), \"Modifier body does not contain '_'.\");\n\n\tif (_modifier.markedVirtual())\n\t\tm_errorReporter.warning(\n\t\t\t8429_error,\n\t\t\t_modifier.location(),\n\t\t\t\"Virtual modifiers are deprecated and scheduled for removal.\"\n\t\t);\n\n\tm_placeholderFound = false;\n}\n\nvoid SyntaxChecker::checkSingleStatementVariableDeclaration(ASTNode const& _statement)\n{\n\tauto varDecl = dynamic_cast<VariableDeclarationStatement const*>(&_statement);\n\tif (varDecl)\n\t\tm_errorReporter.syntaxError(9079_error, _statement.location(), \"Variable declarations can only be used inside blocks.\");\n}\n\nbool SyntaxChecker::visit(IfStatement const& _ifStatement)\n{\n\tcheckSingleStatementVariableDeclaration(_ifStatement.trueStatement());\n\tif (Statement const* _statement = _ifStatement.falseStatement())\n\t\tcheckSingleStatementVariableDeclaration(*_statement);\n\treturn true;\n}\n\nbool SyntaxChecker::visit(WhileStatement const& _whileStatement)\n{\n\tm_inLoopDepth++;\n\tcheckSingleStatementVariableDeclaration(_whileStatement.body());\n\treturn true;\n}\n\nvoid SyntaxChecker::endVisit(WhileStatement const&)\n{\n\tm_inLoopDepth--;\n}\n\nbool SyntaxChecker::visit(ForStatement const& _forStatement)\n{\n\tm_inLoopDepth++;\n\tcheckSingleStatementVariableDeclaration(_forStatement.body());\n\treturn true;\n}\n\nvoid SyntaxChecker::endVisit(ForStatement const&)\n{\n\tm_inLoopDepth--;\n}\n\nbool SyntaxChecker::visit(Block const& _block)\n{\n\tif (_block.unchecked())\n\t{\n\t\tif (m_uncheckedArithmetic)\n\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t1941_error,\n\t\t\t\t_block.location(),\n\t\t\t\t\"\\\"unchecked\\\" blocks cannot be nested.\"\n\t\t\t);\n\n\t\tm_uncheckedArithmetic = true;\n\t}\n\treturn true;\n}\n\nvoid SyntaxChecker::endVisit(Block const& _block)\n{\n\tif (_block.unchecked())\n\t\tm_uncheckedArithmetic = false;\n}\n\nbool SyntaxChecker::visit(Continue const& _continueStatement)\n{\n\tif (m_inLoopDepth <= 0)\n\t\t// we're not in a for/while loop, report syntax error\n\t\tm_errorReporter.syntaxError(4123_error, _continueStatement.location(), \"\\\"continue\\\" has to be in a \\\"for\\\" or \\\"while\\\" loop.\");\n\treturn true;\n}\n\nbool SyntaxChecker::visit(Break const& _breakStatement)\n{\n\tif (m_inLoopDepth <= 0)\n\t\t// we're not in a for/while loop, report syntax error\n\t\tm_errorReporter.syntaxError(6102_error, _breakStatement.location(), \"\\\"break\\\" has to be in a \\\"for\\\" or \\\"while\\\" loop.\");\n\treturn true;\n}\n\nbool SyntaxChecker::visit(Throw const& _throwStatement)\n{\n\tm_errorReporter.syntaxError(\n\t\t4538_error,\n\t\t_throwStatement.location(),\n\t\t\"\\\"throw\\\" is deprecated in favour of \\\"revert()\\\", \\\"require()\\\" and \\\"assert()\\\".\"\n\t);\n\n\treturn true;\n}\n\nbool SyntaxChecker::visit(Literal const& _literal)\n{\n\tsize_t invalidSequence;\n\tif ((_literal.token() == Token::UnicodeStringLiteral) && !validateUTF8(_literal.value(), invalidSequence))\n\t\tm_errorReporter.syntaxError(\n\t\t\t8452_error,\n\t\t\t_literal.location(),\n\t\t\t\"Contains invalid UTF-8 sequence at position \" + toString(invalidSequence) + \".\"\n\t\t);\n\n\tif (_literal.token() != Token::Number)\n\t\treturn true;\n\n\tASTString const& value = _literal.value();\n\tsolAssert(!value.empty(), \"\");\n\n\t// Generic checks no matter what base this number literal is of:\n\tif (value.back() == '_')\n\t{\n\t\tm_errorReporter.syntaxError(2090_error, _literal.location(), \"Invalid use of underscores in number literal. No trailing underscores allowed.\");\n\t\treturn true;\n\t}\n\n\tif (value.find(\"__\") != ASTString::npos)\n\t{\n\t\tm_errorReporter.syntaxError(2990_error, _literal.location(), \"Invalid use of underscores in number literal. Only one consecutive underscore between digits is allowed.\");\n\t\treturn true;\n\t}\n\n\tif (!_literal.isHexNumber()) // decimal literal\n\t{\n\t\tif (value.find(\"._\") != ASTString::npos)\n\t\t\tm_errorReporter.syntaxError(3891_error, _literal.location(), \"Invalid use of underscores in number literal. No underscores in front of the fraction part allowed.\");\n\n\t\tif (value.find(\"_.\") != ASTString::npos)\n\t\t\tm_errorReporter.syntaxError(1023_error, _literal.location(), \"Invalid use of underscores in number literal. No underscores in front of the fraction part allowed.\");\n\n\t\tif (value.find(\"_e\") != ASTString::npos)\n\t\t\tm_errorReporter.syntaxError(6415_error, _literal.location(), \"Invalid use of underscores in number literal. No underscore at the end of the mantissa allowed.\");\n\n\t\tif (value.find(\"e_\") != ASTString::npos)\n\t\t\tm_errorReporter.syntaxError(6165_error, _literal.location(), \"Invalid use of underscores in number literal. No underscore in front of exponent allowed.\");\n\t}\n\n\treturn true;\n}\n\nbool SyntaxChecker::visit(UnaryOperation const& _operation)\n{\n\tsolAssert(_operation.getOperator() != Token::Add);\n\treturn true;\n}\n\nbool SyntaxChecker::visit(InlineAssembly const& _inlineAssembly)\n{\n\tif (_inlineAssembly.flags())\n\t\tfor (auto flag: *_inlineAssembly.flags())\n\t\t{\n\t\t\tif (*flag == \"memory-safe\")\n\t\t\t{\n\t\t\t\tif (_inlineAssembly.annotation().markedMemorySafe)\n\t\t\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t\t\t7026_error,\n\t\t\t\t\t\t_inlineAssembly.location(),\n\t\t\t\t\t\t\"Inline assembly marked memory-safe multiple times.\"\n\t\t\t\t\t);\n\t\t\t\t_inlineAssembly.annotation().markedMemorySafe = true;\n\t\t\t}\n\t\t\telse\n\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t4430_error,\n\t\t\t\t\t_inlineAssembly.location(),\n\t\t\t\t\t\"Unknown inline assembly flag: \\\"\" + *flag + \"\\\"\"\n\t\t\t\t);\n\t\t}\n\n\tif (!m_useYulOptimizer)\n\t\treturn false;\n\n\tif (yul::MSizeFinder::containsMSize(_inlineAssembly.dialect(), _inlineAssembly.operations().root()))\n\t\tm_errorReporter.syntaxError(\n\t\t\t6553_error,\n\t\t\t_inlineAssembly.location(),\n\t\t\t\"The msize instruction cannot be used when the Yul optimizer is activated because \"\n\t\t\t\"it can change its semantics. Either disable the Yul optimizer or do not use the instruction.\"\n\t\t);\n\n\treturn false;\n}\n\nbool SyntaxChecker::visit(PlaceholderStatement const& _placeholder)\n{\n\tif (m_uncheckedArithmetic)\n\t\tm_errorReporter.syntaxError(\n\t\t\t2573_error,\n\t\t\t_placeholder.location(),\n\t\t\t\"The placeholder statement \\\"_\\\" cannot be used inside an \\\"unchecked\\\" block.\"\n\t\t);\n\n\tm_placeholderFound = true;\n\treturn true;\n}\n\nbool SyntaxChecker::visit(ContractDefinition const& _contract)\n{\n\tm_currentContractKind = _contract.contractKind();\n\n\tASTString const& contractName = _contract.name();\n\tfor (FunctionDefinition const* function: _contract.definedFunctions())\n\t\tif (function->name() == contractName)\n\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t5796_error,\n\t\t\t\tfunction->location(),\n\t\t\t\t\"Functions are not allowed to have the same name as the contract. \"\n\t\t\t\t\"If you intend this to be a constructor, use \\\"constructor(...) { ... }\\\" to define it.\"\n\t\t\t);\n\treturn true;\n}\n\nvoid SyntaxChecker::endVisit(ContractDefinition const&)\n{\n\tm_currentContractKind = std::nullopt;\n}\n\nbool SyntaxChecker::visit(UsingForDirective const& _usingFor)\n{\n\tif (!_usingFor.usesBraces())\n\t\tsolAssert(\n\t\t\t_usingFor.functionsAndOperators().size() == 1 &&\n\t\t\t!std::get<1>(_usingFor.functionsAndOperators().front())\n\t\t);\n\n\tif (!m_currentContractKind && !_usingFor.typeName())\n\t\tm_errorReporter.syntaxError(\n\t\t\t8118_error,\n\t\t\t_usingFor.location(),\n\t\t\t\"The type has to be specified explicitly at file level (cannot use '*').\"\n\t\t);\n\telse if (_usingFor.usesBraces() && !_usingFor.typeName())\n\t\tm_errorReporter.syntaxError(\n\t\t\t3349_error,\n\t\t\t_usingFor.location(),\n\t\t\t\"The type has to be specified explicitly when attaching specific functions.\"\n\t\t);\n\tif (_usingFor.global() && !_usingFor.typeName())\n\t\tm_errorReporter.syntaxError(\n\t\t\t2854_error,\n\t\t\t_usingFor.location(),\n\t\t\t\"Can only globally attach functions to specific types.\"\n\t\t);\n\tif (_usingFor.global() && m_currentContractKind)\n\t\tm_errorReporter.syntaxError(\n\t\t\t3367_error,\n\t\t\t_usingFor.location(),\n\t\t\t\"\\\"global\\\" can only be used at file level.\"\n\t\t);\n\tif (m_currentContractKind == ContractKind::Interface)\n\t\tm_errorReporter.syntaxError(\n\t\t\t9088_error,\n\t\t\t_usingFor.location(),\n\t\t\t\"The \\\"using for\\\" directive is not allowed inside interfaces.\"\n\t\t);\n\n\treturn true;\n}\n\nbool SyntaxChecker::visit(FunctionDefinition const& _function)\n{\n\tif (m_sourceUnit && m_sourceUnit->experimentalSolidity())\n\t\t// Handled in experimental::SyntaxRestrictor instead.\n\t\treturn true;\n\n\tif (!_function.isFree() && !_function.isConstructor() && _function.noVisibilitySpecified())\n\t{\n\t\tstd::string suggestedVisibility =\n\t\t\t_function.isFallback() ||\n\t\t\t_function.isReceive() ||\n\t\t\tm_currentContractKind == ContractKind::Interface\n\t\t? \"external\" : \"public\";\n\t\tm_errorReporter.syntaxError(\n\t\t\t4937_error,\n\t\t\t_function.location(),\n\t\t\t\"No visibility specified. Did you intend to add \\\"\" + suggestedVisibility + \"\\\"?\"\n\t\t);\n\t}\n\telse if (_function.isFree())\n\t{\n\t\tif (!_function.noVisibilitySpecified())\n\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t4126_error,\n\t\t\t\t_function.location(),\n\t\t\t\t\"Free functions cannot have visibility.\"\n\t\t\t);\n\t\tif (!_function.isImplemented())\n\t\t\tm_errorReporter.typeError(4668_error, _function.location(), \"Free functions must be implemented.\");\n\t}\n\n\tif (m_currentContractKind == ContractKind::Interface && !_function.modifiers().empty())\n\t\tm_errorReporter.syntaxError(5842_error, _function.location(), \"Functions in interfaces cannot have modifiers.\");\n\telse if (!_function.isImplemented() && !_function.modifiers().empty())\n\t\tm_errorReporter.syntaxError(2668_error, _function.location(), \"Functions without implementation cannot have modifiers.\");\n\n\treturn true;\n}\n\nbool SyntaxChecker::visit(FunctionTypeName const& _node)\n{\n\tfor (auto const& decl: _node.parameterTypeList()->parameters())\n\t\tif (!decl->name().empty())\n\t\t\tm_errorReporter.warning(6162_error, decl->location(), \"Naming function type parameters is deprecated.\");\n\n\tfor (auto const& decl: _node.returnParameterTypeList()->parameters())\n\t\tif (!decl->name().empty())\n\t\t\tm_errorReporter.syntaxError(7304_error, decl->location(), \"Return parameters in function types may not be named.\");\n\n\treturn true;\n}\n\nbool SyntaxChecker::visit(StructDefinition const& _struct)\n{\n\tif (_struct.members().empty())\n\t\tm_errorReporter.syntaxError(5306_error, _struct.location(), \"Defining empty structs is disallowed.\");\n\n\treturn true;\n}\n\nbool SyntaxChecker::visitNode(ASTNode const& _node)\n{\n\tif (_node.experimentalSolidityOnly())\n\t{\n\t\tsolAssert(m_sourceUnit);\n\t\tsolAssert(m_sourceUnit->experimentalSolidity());\n\t}\n\treturn ASTConstVisitor::visitNode(_node);\n}\n"
  },
  {
    "path": "libsolidity/analysis/SyntaxChecker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/analysis/TypeChecker.h>\n#include <libsolidity/ast/Types.h>\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/ASTVisitor.h>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend\n{\n\n/**\n * The module that performs syntax analysis on the AST:\n *  - whether continue/break is in a for/while loop.\n *  - whether a modifier contains at least one '_'\n *  - issues deprecation warnings for unary '+'\n *  - issues deprecation warning for throw\n *  - whether the msize instruction is used and the Yul optimizer is enabled at the same time.\n *  - selection of the ABI coder through pragmas.\n */\nclass SyntaxChecker: private ASTConstVisitor\n{\npublic:\n\t/// @param _errorReporter provides the error logging functionality.\n\t/// @param _useYulOptimizer indicates whether Yul optimizer is enabled.\n\t/// @param _experimental indicates whether the experimental mode is enabled.\n\tSyntaxChecker(langutil::ErrorReporter& _errorReporter, bool _useYulOptimizer, bool _experimental):\n\t\tm_errorReporter(_errorReporter),\n\t\tm_useYulOptimizer(_useYulOptimizer),\n\t\tm_experimental(_experimental)\n\t{}\n\n\tbool checkSyntax(ASTNode const& _astRoot);\n\nprivate:\n\n\tbool visit(SourceUnit const& _sourceUnit) override;\n\tvoid endVisit(SourceUnit const& _sourceUnit) override;\n\tbool visit(PragmaDirective const& _pragma) override;\n\n\tbool visit(ModifierDefinition const& _modifier) override;\n\tvoid endVisit(ModifierDefinition const& _modifier) override;\n\n\t/// Reports an error if _statement is a VariableDeclarationStatement.\n\t/// Used by if/while/for to check for single statement variable declarations\n\t/// without a block.\n\tvoid checkSingleStatementVariableDeclaration(ASTNode const& _statement);\n\n\tbool visit(IfStatement const& _ifStatement) override;\n\tbool visit(WhileStatement const& _whileStatement) override;\n\tvoid endVisit(WhileStatement const& _whileStatement) override;\n\tbool visit(ForStatement const& _forStatement) override;\n\tvoid endVisit(ForStatement const& _forStatement) override;\n\n\tbool visit(Block const& _block) override;\n\tvoid endVisit(Block const& _block) override;\n\n\tbool visit(Continue const& _continueStatement) override;\n\tbool visit(Break const& _breakStatement) override;\n\n\tbool visit(Throw const& _throwStatement) override;\n\n\tbool visit(UnaryOperation const& _operation) override;\n\n\tbool visit(InlineAssembly const& _inlineAssembly) override;\n\n\tbool visit(PlaceholderStatement const& _placeholderStatement) override;\n\n\tbool visit(ContractDefinition const& _contract) override;\n\tvoid endVisit(ContractDefinition const& _contract) override;\n\n\tbool visit(UsingForDirective const& _usingFor) override;\n\n\tbool visit(FunctionDefinition const& _function) override;\n\tbool visit(FunctionTypeName const& _node) override;\n\n\tbool visit(StructDefinition const& _struct) override;\n\tbool visit(Literal const& _literal) override;\n\n\tbool visitNode(ASTNode const&) override;\n\n\tlangutil::ErrorReporter& m_errorReporter;\n\n\tbool m_useYulOptimizer = false;\n\n\t/// Flag that indicates whether a function modifier actually contains '_'.\n\tbool m_placeholderFound = false;\n\n\t/// Flag that indicates whether some version pragma was present.\n\tbool m_versionPragmaFound = false;\n\n\t/// Flag that indicates whether we are inside an unchecked block.\n\tbool m_uncheckedArithmetic = false;\n\n\t/// Flag that indicates whether the experimental mode is enabled.\n\tbool m_experimental = false;\n\n\tint m_inLoopDepth = 0;\n\tstd::optional<ContractKind> m_currentContractKind;\n\n\tSourceUnit const* m_sourceUnit = nullptr;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/TypeChecker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Type analyzer and checker.\n */\n\n#include <libsolidity/analysis/TypeChecker.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTUtils.h>\n#include <libsolidity/ast/UserDefinableOperators.h>\n#include <libsolidity/ast/TypeProvider.h>\n\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/AST.h>\n\n#include <liblangutil/ErrorReporter.h>\n\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/Views.h>\n#include <libsolutil/Visitor.h>\n\n#include <boost/algorithm/string/join.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n\n#include <fmt/format.h>\n\n#include <range/v3/algorithm/count_if.hpp>\n#include <range/v3/view/drop_exactly.hpp>\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/zip.hpp>\n\n#include <memory>\n#include <vector>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nbool TypeChecker::typeSupportedByOldABIEncoder(Type const& _type, bool _isLibraryCall)\n{\n\tif (_isLibraryCall && _type.dataStoredIn(DataLocation::Storage))\n\t\treturn true;\n\tif (_type.category() == Type::Category::Struct)\n\t\treturn false;\n\tif (_type.category() == Type::Category::Array)\n\t{\n\t\tauto const& arrayType = dynamic_cast<ArrayType const&>(_type);\n\t\tauto base = arrayType.baseType();\n\t\tif (!typeSupportedByOldABIEncoder(*base, _isLibraryCall) || (base->category() == Type::Category::Array && base->isDynamicallySized()))\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\nbool TypeChecker::checkTypeRequirements(SourceUnit const& _source)\n{\n\tm_currentSourceUnit = &_source;\n\t_source.accept(*this);\n\tm_currentSourceUnit = nullptr;\n\treturn !Error::containsErrors(m_errorReporter.errors());\n}\n\nbool TypeChecker::visit(ContractDefinition const& _contract)\n{\n\tm_currentContract = &_contract;\n\n\tASTNode::listAccept(_contract.baseContracts(), *this);\n\n\tif (StorageLayoutSpecifier const* layoutSpecifier = _contract.storageLayoutSpecifier())\n\t\tlayoutSpecifier->accept(*this);\n\n\tfor (auto const& n: _contract.subNodes())\n\t\tn->accept(*this);\n\n\tm_currentContract = nullptr;\n\n\treturn false;\n}\n\nTypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall const& _functionCall, bool _abiEncoderV2)\n{\n\tstd::vector<ASTPointer<Expression const>> arguments = _functionCall.arguments();\n\tif (arguments.size() != 2)\n\t\tm_errorReporter.typeError(\n\t\t\t5782_error,\n\t\t\t_functionCall.location(),\n\t\t\t\"This function takes two arguments, but \" +\n\t\t\ttoString(arguments.size()) +\n\t\t\t\" were provided.\"\n\t\t);\n\n\tif (arguments.size() >= 1)\n\t\tif (\n\t\t\t!type(*arguments.front())->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()) &&\n\t\t\t!type(*arguments.front())->isImplicitlyConvertibleTo(*TypeProvider::bytesCalldata())\n\t\t)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t1956_error,\n\t\t\t\targuments.front()->location(),\n\t\t\t\t\"The first argument to \\\"abi.decode\\\" must be implicitly convertible to \"\n\t\t\t\t\"bytes memory or bytes calldata, but is of type \" +\n\t\t\t\ttype(*arguments.front())->humanReadableName() +\n\t\t\t\t\".\"\n\t\t\t);\n\n\tif (arguments.size() < 2)\n\t\treturn {};\n\n\t// The following is a rather syntactic restriction, but we check it here anyway:\n\t// The second argument has to be a tuple expression containing type names.\n\tTupleExpression const* tupleExpression = dynamic_cast<TupleExpression const*>(arguments[1].get());\n\tif (!tupleExpression)\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t6444_error,\n\t\t\targuments[1]->location(),\n\t\t\t\"The second argument to \\\"abi.decode\\\" has to be a tuple of types.\"\n\t\t);\n\t\treturn {};\n\t}\n\n\tTypePointers components;\n\tfor (auto const& typeArgument: tupleExpression->components())\n\t{\n\t\tsolAssert(typeArgument, \"\");\n\t\tif (TypeType const* argTypeType = dynamic_cast<TypeType const*>(type(*typeArgument)))\n\t\t{\n\t\t\tType const* actualType = argTypeType->actualType();\n\t\t\tsolAssert(actualType, \"\");\n\t\t\t// We force memory because the parser currently cannot handle\n\t\t\t// data locations. Furthermore, storage can be a little dangerous and\n\t\t\t// calldata is not really implemented anyway.\n\t\t\tactualType = TypeProvider::withLocationIfReference(DataLocation::Memory, actualType);\n\t\t\t// We force address payable for address types.\n\t\t\tif (actualType->category() == Type::Category::Address)\n\t\t\t\tactualType = TypeProvider::payableAddress();\n\t\t\tsolAssert(\n\t\t\t\t!actualType->dataStoredIn(DataLocation::CallData) &&\n\t\t\t\t!actualType->dataStoredIn(DataLocation::Storage),\n\t\t\t\t\"\"\n\t\t\t);\n\t\t\tif (!actualType->fullEncodingType(false, _abiEncoderV2, false))\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t9611_error,\n\t\t\t\t\ttypeArgument->location(),\n\t\t\t\t\t\"Decoding type \" + actualType->humanReadableName() + \" not supported.\"\n\t\t\t\t);\n\n\t\t\tif (auto referenceType = dynamic_cast<ReferenceType const*>(actualType))\n\t\t\t{\n\t\t\t\tauto result = referenceType->validForLocation(referenceType->location());\n\t\t\t\tif (!result)\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t6118_error,\n\t\t\t\t\t\ttypeArgument->location(),\n\t\t\t\t\t\tresult.message()\n\t\t\t\t\t);\n\t\t\t}\n\n\t\t\tcomponents.push_back(actualType);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_errorReporter.typeError(1039_error, typeArgument->location(), \"Argument has to be a type name.\");\n\t\t\tcomponents.push_back(TypeProvider::emptyTuple());\n\t\t}\n\t}\n\treturn components;\n}\n\nTypePointers TypeChecker::typeCheckMetaTypeFunctionAndRetrieveReturnType(FunctionCall const& _functionCall)\n{\n\tstd::vector<ASTPointer<Expression const>> arguments = _functionCall.arguments();\n\tif (arguments.size() != 1)\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t8885_error,\n\t\t\t_functionCall.location(),\n\t\t\t\"This function takes one argument, but \" +\n\t\t\ttoString(arguments.size()) +\n\t\t\t\" were provided.\"\n\t\t);\n\tType const* firstArgType = type(*arguments.front());\n\n\tbool wrongType = false;\n\tif (firstArgType->category() == Type::Category::TypeType)\n\t{\n\t\tTypeType const* typeTypePtr = dynamic_cast<TypeType const*>(firstArgType);\n\t\tType::Category typeCategory = typeTypePtr->actualType()->category();\n\t\tif (auto const* contractType = dynamic_cast<ContractType const*>(typeTypePtr->actualType()))\n\t\t\twrongType = contractType->isSuper();\n\t\telse if (\n\t\t\ttypeCategory != Type::Category::Integer &&\n\t\t\ttypeCategory != Type::Category::Enum\n\t\t)\n\t\t\twrongType = true;\n\t}\n\telse\n\t\twrongType = true;\n\n\tif (wrongType)\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t4259_error,\n\t\t\targuments.front()->location(),\n\t\t\t\"Invalid type for argument in the function call. \"\n\t\t\t\"An enum type, contract type or an integer type is required, but \" +\n\t\t\ttype(*arguments.front())->humanReadableName() + \" provided.\"\n\t\t);\n\n\treturn {TypeProvider::meta(dynamic_cast<TypeType const&>(*firstArgType).actualType())};\n}\n\nbool TypeChecker::visit(ImportDirective const&)\n{\n\treturn false;\n}\n\nvoid TypeChecker::endVisit(InheritanceSpecifier const& _inheritance)\n{\n\tauto base = dynamic_cast<ContractDefinition const*>(&dereference(_inheritance.name()));\n\tsolAssert(base, \"Base contract not available.\");\n\tsolAssert(m_currentContract, \"\");\n\n\tif (m_currentContract->isInterface() && !base->isInterface())\n\t\tm_errorReporter.typeError(6536_error, _inheritance.location(), \"Interfaces can only inherit from other interfaces.\");\n\n\tauto const& arguments = _inheritance.arguments();\n\tTypePointers parameterTypes;\n\tif (!base->isInterface())\n\t\t// Interfaces do not have constructors, so there are zero parameters.\n\t\tparameterTypes = ContractType(*base).newExpressionType()->parameterTypes();\n\n\tif (arguments)\n\t{\n\t\tif (parameterTypes.size() != arguments->size())\n\t\t{\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t7927_error,\n\t\t\t\t_inheritance.location(),\n\t\t\t\t\"Wrong argument count for constructor call: \" +\n\t\t\t\ttoString(arguments->size()) +\n\t\t\t\t\" arguments given but expected \" +\n\t\t\t\ttoString(parameterTypes.size()) +\n\t\t\t\t(arguments->size() == 0 ? \". Remove parentheses if you do not want to provide arguments here.\" : \"\")\n\t\t\t);\n\t\t}\n\t\tfor (size_t i = 0; i < std::min(arguments->size(), parameterTypes.size()); ++i)\n\t\t{\n\t\t\tBoolResult result = type(*(*arguments)[i])->isImplicitlyConvertibleTo(*parameterTypes[i]);\n\t\t\tif (!result)\n\t\t\t\tm_errorReporter.typeErrorConcatenateDescriptions(\n\t\t\t\t\t9827_error,\n\t\t\t\t\t(*arguments)[i]->location(),\n\t\t\t\t\t\"Invalid type for argument in constructor call. \"\n\t\t\t\t\t\"Invalid implicit conversion from \" +\n\t\t\t\t\ttype(*(*arguments)[i])->humanReadableName() +\n\t\t\t\t\t\" to \" +\n\t\t\t\t\tparameterTypes[i]->humanReadableName() +\n\t\t\t\t\t\" requested.\",\n\t\t\t\t\tresult.message()\n\t\t\t\t);\n\t\t}\n\t}\n}\n\nvoid TypeChecker::endVisit(ModifierDefinition const& _modifier)\n{\n\tif (auto const* contractDef = dynamic_cast<ContractDefinition const*>(_modifier.scope()))\n\t{\n\t\tif (_modifier.virtualSemantics() && contractDef->isLibrary())\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t3275_error,\n\t\t\t\t_modifier.location(),\n\t\t\t\t\"Modifiers in a library cannot be virtual.\"\n\t\t\t);\n\n\t\tif (contractDef->isInterface())\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t6408_error,\n\t\t\t\t_modifier.location(),\n\t\t\t\t\"Modifiers cannot be defined or declared in interfaces.\"\n\t\t\t);\n\t}\n\n\tif (!_modifier.isImplemented() && !_modifier.virtualSemantics())\n\t\tm_errorReporter.typeError(8063_error, _modifier.location(), \"Modifiers without implementation must be marked virtual.\");\n}\n\nbool TypeChecker::visit(FunctionDefinition const& _function)\n{\n\tif (_function.markedVirtual())\n\t{\n\t\tif (_function.isFree())\n\t\t\tm_errorReporter.syntaxError(4493_error, _function.location(), \"Free functions cannot be virtual.\");\n\t\telse if (_function.isConstructor())\n\t\t\tm_errorReporter.typeError(7001_error, _function.location(), \"Constructors cannot be virtual.\");\n\t\telse if (_function.annotation().contract->isInterface())\n\t\t\tm_errorReporter.warning(5815_error, _function.location(), \"Interface functions are implicitly \\\"virtual\\\"\");\n\t\telse if (_function.visibility() == Visibility::Private)\n\t\t\tm_errorReporter.typeError(3942_error, _function.location(), \"\\\"virtual\\\" and \\\"private\\\" cannot be used together.\");\n\t\telse if (_function.libraryFunction())\n\t\t\tm_errorReporter.typeError(7801_error, _function.location(), \"Library functions cannot be \\\"virtual\\\".\");\n\t}\n\tif (_function.overrides() && _function.isFree())\n\t\tm_errorReporter.syntaxError(1750_error, _function.location(), \"Free functions cannot override.\");\n\n\tif (!_function.modifiers().empty() && _function.isFree())\n\t\tm_errorReporter.syntaxError(5811_error, _function.location(), \"Free functions cannot have modifiers.\");\n\n\tif (_function.isPayable())\n\t{\n\t\tif (_function.libraryFunction())\n\t\t\tm_errorReporter.typeError(7708_error, _function.location(), \"Library functions cannot be payable.\");\n\t\telse if (_function.isFree())\n\t\t\tm_errorReporter.typeError(9559_error, _function.location(), \"Free functions cannot be payable.\");\n\t\telse if (_function.isOrdinary() && !_function.isPartOfExternalInterface())\n\t\t\tm_errorReporter.typeError(5587_error, _function.location(), \"\\\"internal\\\" and \\\"private\\\" functions cannot be payable.\");\n\t}\n\n\tstd::vector<VariableDeclaration const*> internalParametersInConstructor;\n\n\tauto checkArgumentAndReturnParameter = [&](VariableDeclaration const& _var) {\n\t\tif (type(_var)->containsNestedMapping())\n\t\t\tif (_var.referenceLocation() == VariableDeclaration::Location::Storage)\n\t\t\t\tsolAssert(\n\t\t\t\t\t_function.libraryFunction() || _function.isConstructor() || !_function.isPublic(),\n\t\t\t\t\t\"Mapping types for parameters or return variables \"\n\t\t\t\t\t\"can only be used in internal or library functions.\"\n\t\t\t\t);\n\t\tbool functionIsExternallyVisible =\n\t\t\t(!_function.isConstructor() && _function.isPublic()) ||\n\t\t\t(_function.isConstructor() && !m_currentContract->abstract());\n\t\tif (\n\t\t\t_function.isConstructor() &&\n\t\t\t_var.referenceLocation() == VariableDeclaration::Location::Storage &&\n\t\t\t!m_currentContract->abstract()\n\t\t)\n\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t3644_error,\n\t\t\t\t_var.location(),\n\t\t\t\t\"This parameter has a type that can only be used internally. \"\n\t\t\t\t\"You can make the contract abstract to avoid this problem.\"\n\t\t\t);\n\t\telse if (functionIsExternallyVisible)\n\t\t{\n\t\t\tauto iType = type(_var)->interfaceType(_function.libraryFunction());\n\n\t\t\tif (!iType)\n\t\t\t{\n\t\t\t\tstd::string message = iType.message();\n\t\t\t\tsolAssert(!message.empty(), \"Expected detailed error message!\");\n\t\t\t\tif (_function.isConstructor())\n\t\t\t\t\tmessage += \" You can make the contract abstract to avoid this problem.\";\n\t\t\t\tm_errorReporter.fatalTypeError(4103_error, _var.location(), message);\n\t\t\t}\n\t\t\telse if (\n\t\t\t\t!useABICoderV2() &&\n\t\t\t\t!typeSupportedByOldABIEncoder(*type(_var), _function.libraryFunction())\n\t\t\t)\n\t\t\t{\n\t\t\t\tstd::string message =\n\t\t\t\t\t\"This type is only supported in ABI coder v2. \"\n\t\t\t\t\t\"Use \\\"pragma abicoder v2;\\\" to enable the feature.\";\n\t\t\t\tif (_function.isConstructor())\n\t\t\t\t\tmessage +=\n\t\t\t\t\t\t\" Alternatively, make the contract abstract and supply the \"\n\t\t\t\t\t\t\"constructor arguments from a derived contract.\";\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t4957_error,\n\t\t\t\t\t_var.location(),\n\t\t\t\t\tmessage\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t};\n\tfor (ASTPointer<VariableDeclaration> const& var: _function.parameters())\n\t{\n\t\tcheckArgumentAndReturnParameter(*var);\n\t\tvar->accept(*this);\n\t}\n\tfor (ASTPointer<VariableDeclaration> const& var: _function.returnParameters())\n\t{\n\t\tcheckArgumentAndReturnParameter(*var);\n\t\tvar->accept(*this);\n\t}\n\n\tstd::set<Declaration const*> modifiers;\n\tfor (ASTPointer<ModifierInvocation> const& modifier: _function.modifiers())\n\t{\n\t\tstd::vector<ContractDefinition const*> baseContracts;\n\t\tif (auto contract = dynamic_cast<ContractDefinition const*>(_function.scope()))\n\t\t{\n\t\t\tbaseContracts = contract->annotation().linearizedBaseContracts;\n\t\t\t// Delete first base which is just the main contract itself\n\t\t\tbaseContracts.erase(baseContracts.begin());\n\t\t}\n\n\t\tvisitManually(\n\t\t\t*modifier,\n\t\t\t_function.isConstructor() ? baseContracts : std::vector<ContractDefinition const*>()\n\t\t);\n\t\tDeclaration const* decl = &dereference(modifier->name());\n\t\tif (modifiers.count(decl))\n\t\t{\n\t\t\tif (dynamic_cast<ContractDefinition const*>(decl))\n\t\t\t\tm_errorReporter.declarationError(1697_error, modifier->location(), \"Base constructor already provided.\");\n\t\t}\n\t\telse\n\t\t\tmodifiers.insert(decl);\n\t}\n\n\tsolAssert(_function.isFree() == !m_currentContract, \"\");\n\tif (!m_currentContract)\n\t{\n\t\tsolAssert(!_function.isConstructor(), \"\");\n\t\tsolAssert(!_function.isFallback(), \"\");\n\t\tsolAssert(!_function.isReceive(), \"\");\n\t}\n\telse if (m_currentContract->isInterface())\n\t{\n\t\tif (_function.isImplemented())\n\t\t\tm_errorReporter.typeError(4726_error, _function.location(), \"Functions in interfaces cannot have an implementation.\");\n\n\t\tif (_function.isConstructor())\n\t\t\tm_errorReporter.typeError(6482_error, _function.location(), \"Constructor cannot be defined in interfaces.\");\n\t\telse if (_function.visibility() != Visibility::External)\n\t\t\tm_errorReporter.typeError(1560_error, _function.location(), \"Functions in interfaces must be declared external.\");\n\t}\n\telse if (m_currentContract->contractKind() == ContractKind::Library)\n\t\tif (_function.isConstructor())\n\t\t\tm_errorReporter.typeError(7634_error, _function.location(), \"Constructor cannot be defined in libraries.\");\n\n\tif (_function.isImplemented())\n\t\t_function.body().accept(*this);\n\telse if (_function.isConstructor())\n\t\tm_errorReporter.typeError(5700_error, _function.location(), \"Constructor must be implemented if declared.\");\n\telse if (_function.libraryFunction())\n\t\tm_errorReporter.typeError(9231_error, _function.location(), \"Library functions must be implemented if declared.\");\n\telse if (!_function.virtualSemantics())\n\t{\n\t\tif (_function.isFree())\n\t\t\tsolAssert(m_errorReporter.hasErrors(), \"\");\n\t\telse\n\t\t\tm_errorReporter.typeError(5424_error, _function.location(), \"Functions without implementation must be marked virtual.\");\n\t}\n\n\n\tif (_function.isFallback())\n\t\ttypeCheckFallbackFunction(_function);\n\telse if (_function.isConstructor())\n\t\ttypeCheckConstructor(_function);\n\n\treturn false;\n}\n\nbool TypeChecker::visit(VariableDeclaration const& _variable)\n{\n\t_variable.typeName().accept(*this);\n\n\t// type is filled either by ReferencesResolver directly from the type name or by\n\t// TypeChecker at the VariableDeclarationStatement level.\n\tType const* varType = _variable.annotation().type;\n\tsolAssert(!!varType, \"Variable type not provided.\");\n\n\tif (_variable.value())\n\t{\n\t\tif (_variable.isStateVariable() && varType->containsNestedMapping())\n\t\t{\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t6280_error,\n\t\t\t\t_variable.location(),\n\t\t\t\t\"Types in storage containing (nested) mappings cannot be assigned to.\"\n\t\t\t);\n\t\t\t_variable.value()->accept(*this);\n\t\t}\n\t\telse\n\t\t\texpectType(*_variable.value(), *varType);\n\t}\n\tif (_variable.isConstant())\n\t{\n\t\tif (!_variable.value())\n\t\t\tm_errorReporter.typeError(4266_error, _variable.location(), \"Uninitialized \\\"constant\\\" variable.\");\n\t\telse if (!*_variable.value()->annotation().isPure)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t8349_error,\n\t\t\t\t_variable.value()->location(),\n\t\t\t\t\"Initial value for constant variable has to be compile-time constant.\"\n\t\t\t);\n\t}\n\telse if (_variable.immutable())\n\t{\n\t\tif (!_variable.type()->isValueType())\n\t\t\tm_errorReporter.typeError(6377_error, _variable.location(), \"Immutable variables cannot have a non-value type.\");\n\t\tif (\n\t\t\tauto const* functionType = dynamic_cast<FunctionType const*>(_variable.type());\n\t\t\tfunctionType && functionType->kind() == FunctionType::Kind::External\n\t\t)\n\t\t\tm_errorReporter.typeError(3366_error, _variable.location(), \"Immutable variables of external function type are not yet supported.\");\n\t\tsolAssert(_variable.type()->sizeOnStack() == 1 || m_errorReporter.hasErrors(), \"\");\n\t}\n\n\tif (!_variable.isStateVariable())\n\t{\n\t\tif (\n\t\t\t_variable.referenceLocation() == VariableDeclaration::Location::CallData ||\n\t\t\t_variable.referenceLocation() == VariableDeclaration::Location::Memory\n\t\t)\n\t\t\tif (varType->containsNestedMapping())\n\t\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t\t4061_error,\n\t\t\t\t\t_variable.location(),\n\t\t\t\t\t\"Type \" + varType->humanReadableName() + \" is only valid in storage because it contains a (nested) mapping.\"\n\t\t\t\t);\n\t}\n\telse if (_variable.visibility() >= Visibility::Public)\n\t{\n\t\tFunctionType getter(_variable);\n\t\tif (!useABICoderV2())\n\t\t{\n\t\t\tstd::vector<std::string> unsupportedTypes;\n\t\t\tfor (auto const& param: getter.parameterTypes() + getter.returnParameterTypes())\n\t\t\t\tif (!typeSupportedByOldABIEncoder(*param, false /* isLibrary */))\n\t\t\t\t\tunsupportedTypes.emplace_back(param->humanReadableName());\n\t\t\tif (!unsupportedTypes.empty())\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t2763_error,\n\t\t\t\t\t_variable.location(),\n\t\t\t\t\t\"The following types are only supported for getters in ABI coder v2: \" +\n\t\t\t\t\tjoinHumanReadable(unsupportedTypes) +\n\t\t\t\t\t\". Either remove \\\"public\\\" or use \\\"pragma abicoder v2;\\\" to enable the feature.\"\n\t\t\t\t);\n\t\t}\n\t\tif (!getter.interfaceFunctionType())\n\t\t{\n\t\t\tsolAssert(getter.returnParameterNames().size() == getter.returnParameterTypes().size());\n\t\t\tsolAssert(getter.parameterNames().size() == getter.parameterTypes().size());\n\t\t\tif (getter.returnParameterTypes().empty() && getter.parameterTypes().empty())\n\t\t\t\tm_errorReporter.typeError(5359_error, _variable.location(), \"The struct has all its members omitted, therefore the getter cannot return any values.\");\n\t\t\telse\n\t\t\t\tm_errorReporter.typeError(6744_error, _variable.location(), \"Internal or recursive type is not allowed for public state variables.\");\n\t\t}\n\t}\n\n\tbool isStructMemberDeclaration = dynamic_cast<StructDefinition const*>(_variable.scope()) != nullptr;\n\tif (isStructMemberDeclaration)\n\t\treturn false;\n\n\tif (auto referenceType = dynamic_cast<ReferenceType const*>(varType))\n\t{\n\t\tBoolResult result = referenceType->validForLocation(referenceType->location());\n\t\tif (result)\n\t\t{\n\t\t\tbool isLibraryStorageParameter = (_variable.isLibraryFunctionParameter() && referenceType->location() == DataLocation::Storage);\n\t\t\t// We skip the calldata check for abstract contract constructors.\n\t\t\tbool isAbstractConstructorParam = _variable.isConstructorParameter() && m_currentContract && m_currentContract->abstract();\n\t\t\tbool callDataCheckRequired =\n\t\t\t\t!isAbstractConstructorParam &&\n\t\t\t\t(_variable.isConstructorParameter() || _variable.isPublicCallableParameter()) &&\n\t\t\t\t!isLibraryStorageParameter;\n\t\t\tif (callDataCheckRequired)\n\t\t\t{\n\t\t\t\tif (!referenceType->interfaceType(false))\n\t\t\t\t\tsolAssert(m_errorReporter.hasErrors(), \"\");\n\t\t\t\telse\n\t\t\t\t\tresult = referenceType->validForLocation(DataLocation::CallData);\n\t\t\t}\n\t\t}\n\t\tif (!result)\n\t\t{\n\t\t\tsolAssert(!result.message().empty(), \"Expected detailed error message\");\n\t\t\tm_errorReporter.typeError(1534_error, _variable.location(), result.message());\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nvoid TypeChecker::endVisit(StructDefinition const& _struct)\n{\n\tfor (auto const& member: _struct.members())\n\t\tsolAssert(\n\t\t\tmember->annotation().type &&\n\t\t\tmember->annotation().type->canBeStored(),\n\t\t\t\"Type cannot be used in struct.\"\n\t\t);\n}\n\nvoid TypeChecker::visitManually(\n\tModifierInvocation const& _modifier,\n\tstd::vector<ContractDefinition const*> const& _bases\n)\n{\n\tstd::vector<ASTPointer<Expression>> const& arguments =\n\t\t_modifier.arguments() ? *_modifier.arguments() : std::vector<ASTPointer<Expression>>();\n\tfor (ASTPointer<Expression> const& argument: arguments)\n\t\targument->accept(*this);\n\n\t_modifier.name().accept(*this);\n\n\tauto const* declaration = &dereference(_modifier.name());\n\tstd::vector<ASTPointer<VariableDeclaration>> emptyParameterList;\n\tstd::vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;\n\tif (auto modifierDecl = dynamic_cast<ModifierDefinition const*>(declaration))\n\t{\n\t\tparameters = &modifierDecl->parameters();\n\t\tif (auto const* modifierContract = dynamic_cast<ContractDefinition const*>(modifierDecl->scope()))\n\t\t\tif (m_currentContract)\n\t\t\t{\n\t\t\t\tif (!util::contains(m_currentContract->annotation().linearizedBaseContracts, modifierContract))\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t9428_error,\n\t\t\t\t\t\t_modifier.location(),\n\t\t\t\t\t\t\"Can only use modifiers defined in the current contract or in base contracts.\"\n\t\t\t\t\t);\n\t\t\t}\n\t\tif (\n\t\t\t*_modifier.name().annotation().requiredLookup == VirtualLookup::Static &&\n\t\t\t!modifierDecl->isImplemented()\n\t\t)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t1835_error,\n\t\t\t\t_modifier.location(),\n\t\t\t\t\"Cannot call unimplemented modifier. The modifier has no implementation in the referenced contract. Refer to it by its unqualified name if you want to call the implementation from the most derived contract.\"\n\t\t\t);\n\t}\n\telse\n\t\t// check parameters for Base constructors\n\t\tfor (ContractDefinition const* base: _bases)\n\t\t\tif (declaration == base)\n\t\t\t{\n\t\t\t\tif (auto referencedConstructor = base->constructor())\n\t\t\t\t\tparameters = &referencedConstructor->parameters();\n\t\t\t\telse\n\t\t\t\t\tparameters = &emptyParameterList;\n\t\t\t\tbreak;\n\t\t\t}\n\tif (!parameters)\n\t{\n\t\tm_errorReporter.typeError(4659_error, _modifier.location(), \"Referenced declaration is neither modifier nor base class.\");\n\t\treturn;\n\t}\n\tif (parameters->size() != arguments.size())\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t2973_error,\n\t\t\t_modifier.location(),\n\t\t\t\"Wrong argument count for modifier invocation: \" +\n\t\t\ttoString(arguments.size()) +\n\t\t\t\" arguments given but expected \" +\n\t\t\ttoString(parameters->size()) +\n\t\t\t\".\"\n\t\t);\n\t\treturn;\n\t}\n\tfor (size_t i = 0; i < arguments.size(); ++i)\n\t{\n\t\tBoolResult result = type(*arguments[i])->isImplicitlyConvertibleTo(*type(*(*parameters)[i]));\n\t\tif (!result)\n\t\t\tm_errorReporter.typeErrorConcatenateDescriptions(\n\t\t\t\t4649_error,\n\t\t\t\targuments[i]->location(),\n\t\t\t\t\"Invalid type for argument in modifier invocation. \"\n\t\t\t\t\"Invalid implicit conversion from \" +\n\t\t\t\ttype(*arguments[i])->humanReadableName() +\n\t\t\t\t\" to \" +\n\t\t\t\ttype(*(*parameters)[i])->humanReadableName() +\n\t\t\t\t\" requested.\",\n\t\t\t\tresult.message()\n\t\t\t);\n\t}\n}\n\nbool TypeChecker::visit(EventDefinition const& _eventDef)\n{\n\tsolAssert(_eventDef.visibility() > Visibility::Internal, \"\");\n\tcheckErrorAndEventParameters(_eventDef);\n\n\tauto numIndexed = ranges::count_if(\n\t\t_eventDef.parameters(),\n\t\t[](ASTPointer<VariableDeclaration> const& var) { return var->isIndexed(); }\n\t);\n\tif (_eventDef.isAnonymous() && numIndexed > 4)\n\t\tm_errorReporter.typeError(8598_error, _eventDef.location(), \"More than 4 indexed arguments for anonymous event.\");\n\telse if (!_eventDef.isAnonymous() && numIndexed > 3)\n\t\tm_errorReporter.typeError(7249_error, _eventDef.location(), \"More than 3 indexed arguments for event.\");\n\treturn true;\n}\n\nbool TypeChecker::visit(ErrorDefinition const& _errorDef)\n{\n\tsolAssert(_errorDef.visibility() > Visibility::Internal, \"\");\n\tcheckErrorAndEventParameters(_errorDef);\n\treturn true;\n}\n\nvoid TypeChecker::endVisit(FunctionTypeName const& _funType)\n{\n\tFunctionType const& fun = dynamic_cast<FunctionType const&>(*_funType.annotation().type);\n\tif (fun.kind() == FunctionType::Kind::External)\n\t{\n\t\tfor (auto const& t: _funType.parameterTypes() + _funType.returnParameterTypes())\n\t\t{\n\t\t\tsolAssert(t->annotation().type, \"Type not set for parameter.\");\n\t\t\tif (!t->annotation().type->interfaceType(false).get())\n\t\t\t\tm_errorReporter.fatalTypeError(2582_error, t->location(), \"Internal type cannot be used for external function type.\");\n\t\t}\n\t\tsolAssert(fun.interfaceType(false), \"External function type uses internal types.\");\n\t}\n}\n\nbool TypeChecker::visit(InlineAssembly const& _inlineAssembly)\n{\n\tbool lvalueAccessToMemoryVariable = false;\n\t// External references have already been resolved in a prior stage and stored in the annotation.\n\t// We run the resolve step again regardless.\n\tyul::ExternalIdentifierAccess::Resolver identifierAccess = [&](\n\t\tyul::Identifier const& _identifier,\n\t\tyul::IdentifierContext _context,\n\t\tbool\n\t) -> bool\n\t{\n\t\tif (_context == yul::IdentifierContext::NonExternal)\n\t\t{\n\t\t\t// Hack until we can disallow any shadowing: If we found an internal reference,\n\t\t\t// clear the external references, so that codegen does not use it.\n\t\t\t_inlineAssembly.annotation().externalReferences.erase(& _identifier);\n\t\t\treturn false;\n\t\t}\n\t\tauto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier);\n\t\tif (ref == _inlineAssembly.annotation().externalReferences.end())\n\t\t\treturn false;\n\t\tInlineAssemblyAnnotation::ExternalIdentifierInfo& identifierInfo = ref->second;\n\t\tDeclaration const* declaration = identifierInfo.declaration;\n\t\tsolAssert(!!declaration, \"\");\n\t\tif (auto var = dynamic_cast<VariableDeclaration const*>(declaration))\n\t\t{\n\t\t\tsolAssert(var->type(), \"Expected variable type!\");\n\t\t\tif (_context == yul::IdentifierContext::LValue && var->type()->dataStoredIn(DataLocation::Memory))\n\t\t\t\tlvalueAccessToMemoryVariable = true;\n\t\t\tif (var->immutable())\n\t\t\t{\n\t\t\t\tm_errorReporter.typeError(3773_error, nativeLocationOf(_identifier), \"Assembly access to immutable variables is not supported.\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (var->isConstant())\n\t\t\t{\n\t\t\t\tif (isConstantVariableRecursive(*var))\n\t\t\t\t{\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t3558_error,\n\t\t\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\t\t\t\"Constant variable is circular.\"\n\t\t\t\t\t);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tvar = rootConstVariableDeclaration(*var);\n\n\t\t\t\tif (var && !var->value())\n\t\t\t\t{\n\t\t\t\t\tm_errorReporter.typeError(3224_error, nativeLocationOf(_identifier), \"Constant has no value.\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (_context == yul::IdentifierContext::LValue)\n\t\t\t\t{\n\t\t\t\t\tm_errorReporter.typeError(6252_error, nativeLocationOf(_identifier), \"Constant variables cannot be assigned to.\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (identifierInfo.suffix == \"slot\" || identifierInfo.suffix == \"offset\")\n\t\t\t\t{\n\t\t\t\t\tm_errorReporter.typeError(6617_error, nativeLocationOf(_identifier), \"The suffixes .offset and .slot can only be used on non-constant storage or transient storage variables.\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (var && var->value() && !var->value()->annotation().type && !dynamic_cast<Literal const*>(var->value().get()))\n\t\t\t\t{\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t2249_error,\n\t\t\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\t\t\t\"Constant variables with non-literal values cannot be forward referenced from inline assembly.\"\n\t\t\t\t\t);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (!var || !type(*var)->isValueType() || (\n\t\t\t\t\t!dynamic_cast<Literal const*>(var->value().get()) &&\n\t\t\t\t\ttype(*var->value())->category() != Type::Category::RationalNumber\n\t\t\t\t))\n\t\t\t\t{\n\t\t\t\t\tm_errorReporter.typeError(7615_error, nativeLocationOf(_identifier), \"Only direct number constants and references to such constants are supported by inline assembly.\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsolAssert(!dynamic_cast<FixedPointType const*>(var->type()), \"FixedPointType not implemented.\");\n\n\t\t\tif (!identifierInfo.suffix.empty())\n\t\t\t{\n\t\t\t\tstd::string const& suffix = identifierInfo.suffix;\n\t\t\t\tsolAssert((std::set<std::string>{\"offset\", \"slot\", \"length\", \"selector\", \"address\"}).count(suffix), \"\");\n\t\t\t\tif (!var->isConstant() && (var->isStateVariable() || var->type()->dataStoredIn(DataLocation::Storage)))\n\t\t\t\t{\n\t\t\t\t\tif (suffix != \"slot\" && suffix != \"offset\")\n\t\t\t\t\t{\n\t\t\t\t\t\tm_errorReporter.typeError(4656_error, nativeLocationOf(_identifier), \"State variables only support \\\".slot\\\" and \\\".offset\\\".\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\telse if (_context == yul::IdentifierContext::LValue)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (var->isStateVariable())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tm_errorReporter.typeError(4713_error, nativeLocationOf(_identifier), \"State variables cannot be assigned to - you have to use \\\"sstore()\\\" or \\\"tstore()\\\".\");\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (suffix != \"slot\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tm_errorReporter.typeError(9739_error, nativeLocationOf(_identifier), \"Only .slot can be assigned to.\");\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (\n\t\t\t\t\tauto const* arrayType = dynamic_cast<ArrayType const*>(var->type());\n\t\t\t\t\tarrayType && arrayType->isDynamicallySized() && arrayType->dataStoredIn(DataLocation::CallData)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tif (suffix != \"offset\" && suffix != \"length\")\n\t\t\t\t\t{\n\t\t\t\t\t\tm_errorReporter.typeError(1536_error, nativeLocationOf(_identifier), \"Calldata variables only support \\\".offset\\\" and \\\".length\\\".\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (auto const* fpType = dynamic_cast<FunctionTypePointer>(var->type()))\n\t\t\t\t{\n\t\t\t\t\tif (suffix != \"selector\" && suffix != \"address\")\n\t\t\t\t\t{\n\t\t\t\t\t\tm_errorReporter.typeError(9272_error, nativeLocationOf(_identifier), \"Variables of type function pointer only support \\\".selector\\\" and \\\".address\\\".\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (fpType->kind() != FunctionType::Kind::External)\n\t\t\t\t\t{\n\t\t\t\t\t\tm_errorReporter.typeError(8533_error, nativeLocationOf(_identifier), \"Only Variables of type external function pointer support \\\".selector\\\" and \\\".address\\\".\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tm_errorReporter.typeError(3622_error, nativeLocationOf(_identifier), \"The suffix \\\".\" + suffix + \"\\\" is not supported by this variable or type.\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (!var->isConstant() && var->isStateVariable())\n\t\t\t{\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t1408_error,\n\t\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\t\t\"Only local variables are supported. To access state variables, use the \\\".slot\\\" and \\\".offset\\\" suffixes.\"\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (var->type()->dataStoredIn(DataLocation::Storage))\n\t\t\t{\n\t\t\t\tm_errorReporter.typeError(9068_error, nativeLocationOf(_identifier), \"You have to use the \\\".slot\\\" or \\\".offset\\\" suffix to access storage reference variables.\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (var->type()->sizeOnStack() != 1)\n\t\t\t{\n\t\t\t\tif (\n\t\t\t\t\tauto const* arrayType = dynamic_cast<ArrayType const*>(var->type());\n\t\t\t\t\tarrayType && arrayType->isDynamicallySized() && arrayType->dataStoredIn(DataLocation::CallData)\n\t\t\t\t)\n\t\t\t\t\tm_errorReporter.typeError(1397_error, nativeLocationOf(_identifier), \"Call data elements cannot be accessed directly. Use \\\".offset\\\" and \\\".length\\\" to access the calldata offset and length of this array and then use \\\"calldatacopy\\\".\");\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsolAssert(!var->type()->dataStoredIn(DataLocation::CallData), \"\");\n\t\t\t\t\tm_errorReporter.typeError(9857_error, nativeLocationOf(_identifier), \"Only types that use one stack slot are supported.\");\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse if (!identifierInfo.suffix.empty())\n\t\t{\n\t\t\tm_errorReporter.typeError(7944_error, nativeLocationOf(_identifier), \"The suffixes \\\".offset\\\", \\\".slot\\\" and \\\".length\\\" can only be used with variables.\");\n\t\t\treturn false;\n\t\t}\n\t\telse if (_context == yul::IdentifierContext::LValue)\n\t\t{\n\t\t\tif (dynamic_cast<MagicVariableDeclaration const*>(declaration))\n\t\t\t\treturn false;\n\n\t\t\tm_errorReporter.typeError(1990_error, nativeLocationOf(_identifier), \"Only local variables can be assigned to in inline assembly.\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif (_context == yul::IdentifierContext::RValue)\n\t\t{\n\t\t\tsolAssert(!!declaration->type(), \"Type of declaration required but not yet determined.\");\n\t\t\tif (dynamic_cast<FunctionDefinition const*>(declaration))\n\t\t\t{\n\t\t\t\tm_errorReporter.declarationError(2025_error, nativeLocationOf(_identifier), \"Access to functions is not allowed in inline assembly.\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (dynamic_cast<VariableDeclaration const*>(declaration))\n\t\t\t{\n\t\t\t}\n\t\t\telse if (auto contract = dynamic_cast<ContractDefinition const*>(declaration))\n\t\t\t{\n\t\t\t\tif (!contract->isLibrary())\n\t\t\t\t{\n\t\t\t\t\tm_errorReporter.typeError(4977_error, nativeLocationOf(_identifier), \"Expected a library.\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\tidentifierInfo.valueSize = 1;\n\t\treturn true;\n\t};\n\tsolAssert(!_inlineAssembly.annotation().analysisInfo, \"\");\n\t_inlineAssembly.annotation().analysisInfo = std::make_shared<yul::AsmAnalysisInfo>();\n\tyul::AsmAnalyzer analyzer(\n\t\t*_inlineAssembly.annotation().analysisInfo,\n\t\tm_errorReporter,\n\t\t_inlineAssembly.dialect(),\n\t\tidentifierAccess\n\t);\n\tif (!analyzer.analyze(_inlineAssembly.operations().root()))\n\t\tsolAssert(m_errorReporter.hasErrors());\n\t_inlineAssembly.annotation().hasMemoryEffects =\n\t\tlvalueAccessToMemoryVariable ||\n\t\t(analyzer.sideEffects().memory != yul::SideEffects::None);\n\treturn false;\n}\n\nbool TypeChecker::visit(IfStatement const& _ifStatement)\n{\n\texpectType(_ifStatement.condition(), *TypeProvider::boolean());\n\t_ifStatement.trueStatement().accept(*this);\n\tif (_ifStatement.falseStatement())\n\t\t_ifStatement.falseStatement()->accept(*this);\n\treturn false;\n}\n\nvoid TypeChecker::endVisit(TryStatement const& _tryStatement)\n{\n\tFunctionCall const* externalCall = dynamic_cast<FunctionCall const*>(&_tryStatement.externalCall());\n\tif (!externalCall || *externalCall->annotation().kind != FunctionCallKind::FunctionCall)\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t5347_error,\n\t\t\t_tryStatement.externalCall().location(),\n\t\t\t\"Try can only be used with external function calls and contract creation calls.\"\n\t\t);\n\t\treturn;\n\t}\n\n\tFunctionType const& functionType = dynamic_cast<FunctionType const&>(*externalCall->expression().annotation().type);\n\tif (\n\t\tfunctionType.kind() != FunctionType::Kind::External &&\n\t\tfunctionType.kind() != FunctionType::Kind::Creation &&\n\t\tfunctionType.kind() != FunctionType::Kind::DelegateCall\n\t)\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t2536_error,\n\t\t\t_tryStatement.externalCall().location(),\n\t\t\t\"Try can only be used with external function calls and contract creation calls.\"\n\t\t);\n\t\treturn;\n\t}\n\n\texternalCall->annotation().tryCall = true;\n\n\tsolAssert(_tryStatement.clauses().size() >= 2, \"\");\n\tsolAssert(_tryStatement.clauses().front(), \"\");\n\n\tTryCatchClause const& successClause = *_tryStatement.clauses().front();\n\tif (successClause.parameters())\n\t{\n\t\tTypePointers returnTypes =\n\t\t\tm_evmVersion.supportsReturndata() ?\n\t\t\tfunctionType.returnParameterTypes() :\n\t\t\tfunctionType.returnParameterTypesWithoutDynamicTypes();\n\t\tstd::vector<ASTPointer<VariableDeclaration>> const& parameters =\n\t\t\tsuccessClause.parameters()->parameters();\n\t\tif (returnTypes.size() != parameters.size())\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t2800_error,\n\t\t\t\tsuccessClause.location(),\n\t\t\t\t\"Function returns \" +\n\t\t\t\tstd::to_string(functionType.returnParameterTypes().size()) +\n\t\t\t\t\" values, but returns clause has \" +\n\t\t\t\tstd::to_string(parameters.size()) +\n\t\t\t\t\" variables.\"\n\t\t\t);\n\t\tfor (auto&& [parameter, returnType]: ranges::views::zip(parameters, returnTypes))\n\t\t{\n\t\t\tsolAssert(returnType, \"\");\n\t\t\tif (parameter && *parameter->annotation().type != *returnType)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t6509_error,\n\t\t\t\t\tparameter->location(),\n\t\t\t\t\t\"Invalid type, expected \" +\n\t\t\t\t\treturnType->humanReadableName() +\n\t\t\t\t\t\" but got \" +\n\t\t\t\t\tparameter->annotation().type->humanReadableName() +\n\t\t\t\t\t\".\"\n\t\t\t\t);\n\t\t}\n\t}\n\n\tTryCatchClause const* panicClause = nullptr;\n\tTryCatchClause const* errorClause = nullptr;\n\tTryCatchClause const* lowLevelClause = nullptr;\n\tfor (auto const& clause: _tryStatement.clauses() | ranges::views::drop_exactly(1) | views::dereferenceChecked)\n\t{\n\t\tif (clause.errorName() == \"\")\n\t\t{\n\t\t\tif (lowLevelClause)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t5320_error,\n\t\t\t\t\tclause.location(),\n\t\t\t\t\tSecondarySourceLocation{}.append(\"The first clause is here:\", lowLevelClause->location()),\n\t\t\t\t\t\"This try statement already has a low-level catch clause.\"\n\t\t\t\t);\n\t\t\tlowLevelClause = &clause;\n\t\t\tif (clause.parameters() && !clause.parameters()->parameters().empty())\n\t\t\t{\n\t\t\t\tif (\n\t\t\t\t\tclause.parameters()->parameters().size() != 1 ||\n\t\t\t\t\t*clause.parameters()->parameters().front()->type() != *TypeProvider::bytesMemory()\n\t\t\t\t)\n\t\t\t\t\tm_errorReporter.typeError(6231_error, clause.location(), \"Expected `catch (bytes memory ...) { ... }` or `catch { ... }`.\");\n\t\t\t\tif (!m_evmVersion.supportsReturndata())\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t9908_error,\n\t\t\t\t\t\tclause.location(),\n\t\t\t\t\t\t\"This catch clause type cannot be used on the selected EVM version (\" +\n\t\t\t\t\t\tm_evmVersion.name() +\n\t\t\t\t\t\t\"). You need at least a Byzantium-compatible EVM or use `catch { ... }`.\"\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\telse if (clause.errorName() == \"Error\" || clause.errorName() == \"Panic\")\n\t\t{\n\t\t\tif (!m_evmVersion.supportsReturndata())\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t1812_error,\n\t\t\t\t\tclause.location(),\n\t\t\t\t\t\"This catch clause type cannot be used on the selected EVM version (\" +\n\t\t\t\t\tm_evmVersion.name() +\n\t\t\t\t\t\"). You need at least a Byzantium-compatible EVM or use `catch { ... }`.\"\n\t\t\t\t);\n\n\t\t\tif (clause.errorName() == \"Error\")\n\t\t\t{\n\t\t\t\tif (errorClause)\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t1036_error,\n\t\t\t\t\t\tclause.location(),\n\t\t\t\t\t\tSecondarySourceLocation{}.append(\"The first clause is here:\", errorClause->location()),\n\t\t\t\t\t\t\"This try statement already has an \\\"Error\\\" catch clause.\"\n\t\t\t\t\t);\n\t\t\t\terrorClause = &clause;\n\t\t\t\tif (\n\t\t\t\t\t!clause.parameters() ||\n\t\t\t\t\tclause.parameters()->parameters().size() != 1 ||\n\t\t\t\t\t*clause.parameters()->parameters().front()->type() != *TypeProvider::stringMemory()\n\t\t\t\t)\n\t\t\t\t\tm_errorReporter.typeError(2943_error, clause.location(), \"Expected `catch Error(string memory ...) { ... }`.\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (panicClause)\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t6732_error,\n\t\t\t\t\t\tclause.location(),\n\t\t\t\t\t\tSecondarySourceLocation{}.append(\"The first clause is here:\", panicClause->location()),\n\t\t\t\t\t\t\"This try statement already has a \\\"Panic\\\" catch clause.\"\n\t\t\t\t\t);\n\t\t\t\tpanicClause = &clause;\n\t\t\t\tif (\n\t\t\t\t\t!clause.parameters() ||\n\t\t\t\t\tclause.parameters()->parameters().size() != 1 ||\n\t\t\t\t\t*clause.parameters()->parameters().front()->type() != *TypeProvider::uint256()\n\t\t\t\t)\n\t\t\t\t\tm_errorReporter.typeError(1271_error, clause.location(), \"Expected `catch Panic(uint ...) { ... }`.\");\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t3542_error,\n\t\t\t\tclause.location(),\n\t\t\t\t\"Invalid catch clause name. Expected either `catch (...)`, `catch Error(...)`, or `catch Panic(...)`.\"\n\t\t\t);\n\t}\n}\n\nbool TypeChecker::visit(WhileStatement const& _whileStatement)\n{\n\texpectType(_whileStatement.condition(), *TypeProvider::boolean());\n\t_whileStatement.body().accept(*this);\n\treturn false;\n}\n\nbool TypeChecker::visit(ForStatement const& _forStatement)\n{\n\tif (_forStatement.initializationExpression())\n\t\t_forStatement.initializationExpression()->accept(*this);\n\tif (_forStatement.condition())\n\t\texpectType(*_forStatement.condition(), *TypeProvider::boolean());\n\tif (_forStatement.loopExpression())\n\t\t_forStatement.loopExpression()->accept(*this);\n\t_forStatement.body().accept(*this);\n\treturn false;\n}\n\nvoid TypeChecker::endVisit(Return const& _return)\n{\n\tParameterList const* params = _return.annotation().functionReturnParameters;\n\tif (!_return.expression())\n\t{\n\t\tif (params && !params->parameters().empty())\n\t\t\tm_errorReporter.typeError(6777_error, _return.location(), \"Return arguments required.\");\n\t\treturn;\n\t}\n\tif (!params)\n\t{\n\t\tm_errorReporter.typeError(7552_error, _return.location(), \"Return arguments not allowed.\");\n\t\treturn;\n\t}\n\tTypePointers returnTypes;\n\tfor (auto const& var: params->parameters())\n\t\treturnTypes.push_back(type(*var));\n\tif (auto tupleType = dynamic_cast<TupleType const*>(type(*_return.expression())))\n\t{\n\t\tif (tupleType->components().size() != params->parameters().size())\n\t\t\tm_errorReporter.typeError(5132_error, _return.location(), \"Different number of arguments in return statement than in returns declaration.\");\n\t\telse\n\t\t{\n\t\t\tBoolResult result = tupleType->isImplicitlyConvertibleTo(TupleType(returnTypes));\n\t\t\tif (!result)\n\t\t\t\tm_errorReporter.typeErrorConcatenateDescriptions(\n\t\t\t\t\t5992_error,\n\t\t\t\t\t_return.expression()->location(),\n\t\t\t\t\t\"Return argument type \" +\n\t\t\t\t\ttype(*_return.expression())->humanReadableName() +\n\t\t\t\t\t\" is not implicitly convertible to expected type \" +\n\t\t\t\t\tTupleType(returnTypes).humanReadableName() + \".\",\n\t\t\t\t\tresult.message()\n\t\t\t\t);\n\t\t}\n\t}\n\telse if (params->parameters().size() != 1)\n\t\tm_errorReporter.typeError(8863_error, _return.location(), \"Different number of arguments in return statement than in returns declaration.\");\n\telse\n\t{\n\t\tType const* expected = type(*params->parameters().front());\n\t\tBoolResult result = type(*_return.expression())->isImplicitlyConvertibleTo(*expected);\n\t\tif (!result)\n\t\t\tm_errorReporter.typeErrorConcatenateDescriptions(\n\t\t\t\t6359_error,\n\t\t\t\t_return.expression()->location(),\n\t\t\t\t\"Return argument type \" +\n\t\t\t\ttype(*_return.expression())->humanReadableName() +\n\t\t\t\t\" is not implicitly convertible to expected type (type of first return variable) \" +\n\t\t\t\texpected->humanReadableName() + \".\",\n\t\t\t\tresult.message()\n\t\t\t);\n\t}\n}\n\nvoid TypeChecker::endVisit(EmitStatement const& _emit)\n{\n\tif (\n\t\t*_emit.eventCall().annotation().kind != FunctionCallKind::FunctionCall ||\n\t\ttype(_emit.eventCall().expression())->category() != Type::Category::Function ||\n\t\tdynamic_cast<FunctionType const&>(*type(_emit.eventCall().expression())).kind() != FunctionType::Kind::Event\n\t)\n\t\tm_errorReporter.typeError(9292_error, _emit.eventCall().expression().location(), \"Expression has to be an event invocation.\");\n}\n\nvoid TypeChecker::endVisit(RevertStatement const& _revert)\n{\n\tFunctionCall const& errorCall = _revert.errorCall();\n\tif (\n\t\t*errorCall.annotation().kind != FunctionCallKind::FunctionCall ||\n\t\ttype(errorCall.expression())->category() != Type::Category::Function ||\n\t\tdynamic_cast<FunctionType const&>(*type(errorCall.expression())).kind() != FunctionType::Kind::Error\n\t)\n\t\tm_errorReporter.typeError(1885_error, errorCall.expression().location(), \"Expression has to be an error.\");\n}\n\nvoid TypeChecker::endVisit(ArrayTypeName const& _typeName)\n{\n\tsolAssert(\n\t\t_typeName.baseType().annotation().type &&\n\t\t_typeName.baseType().annotation().type->storageBytes() != 0,\n\t\t\"Illegal base type of storage size zero for array.\"\n\t);\n}\n\nbool TypeChecker::visit(VariableDeclarationStatement const& _statement)\n{\n\tif (!_statement.initialValue())\n\t{\n\t\t// No initial value is only permitted for single variables with specified type.\n\t\t// This usually already results in a parser error.\n\t\tif (_statement.declarations().size() != 1 || !_statement.declarations().front())\n\t\t{\n\t\t\tsolAssert(m_errorReporter.hasErrors(), \"\");\n\n\t\t\t// It is okay to return here, as there are no named components on the\n\t\t\t// left-hand-side that could cause any damage later.\n\t\t\treturn false;\n\t\t}\n\n\t\tVariableDeclaration const& varDecl = *_statement.declarations().front();\n\t\tsolAssert(varDecl.annotation().type, \"\");\n\n\t\tif (dynamic_cast<MappingType const*>(type(varDecl)))\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t4182_error,\n\t\t\t\tvarDecl.location(),\n\t\t\t\t\"Uninitialized mapping. Mappings cannot be created dynamically, you have to assign them from a state variable.\"\n\t\t\t);\n\t\tvarDecl.accept(*this);\n\t\treturn false;\n\t}\n\n\t// Here we have an initial value and might have to derive some types before we can visit\n\t// the variable declaration(s).\n\n\t_statement.initialValue()->accept(*this);\n\tTypePointers valueTypes;\n\tif (auto tupleType = dynamic_cast<TupleType const*>(type(*_statement.initialValue())))\n\t\tvalueTypes = tupleType->components();\n\telse\n\t\tvalueTypes = TypePointers{type(*_statement.initialValue())};\n\n\tstd::vector<ASTPointer<VariableDeclaration>> const& variables = _statement.declarations();\n\tif (variables.empty())\n\t\t// We already have an error for this in the SyntaxChecker.\n\t\tsolAssert(m_errorReporter.hasErrors(), \"\");\n\telse if (valueTypes.size() != variables.size())\n\t\tm_errorReporter.typeError(\n\t\t\t7364_error,\n\t\t\t_statement.location(),\n\t\t\t\"Different number of components on the left hand side (\" +\n\t\t\ttoString(variables.size()) +\n\t\t\t\") than on the right hand side (\" +\n\t\t\ttoString(valueTypes.size()) +\n\t\t\t\").\"\n\t\t);\n\n\tfor (size_t i = 0; i < std::min(variables.size(), valueTypes.size()); ++i)\n\t{\n\t\tif (!variables[i])\n\t\t\tcontinue;\n\t\tVariableDeclaration const& var = *variables[i];\n\t\tsolAssert(!var.value(), \"Value has to be tied to statement.\");\n\t\tType const* valueComponentType = valueTypes[i];\n\t\tsolAssert(!!valueComponentType, \"\");\n\t\tsolAssert(var.annotation().type, \"\");\n\n\t\tvar.accept(*this);\n\t\tBoolResult result = valueComponentType->isImplicitlyConvertibleTo(*var.annotation().type);\n\t\tif (!result)\n\t\t{\n\t\t\tauto errorMsg = \"Type \" +\n\t\t\t\tvalueComponentType->humanReadableName() +\n\t\t\t\t\" is not implicitly convertible to expected type \" +\n\t\t\t\tvar.annotation().type->humanReadableName();\n\t\t\tif (\n\t\t\t\tvalueComponentType->category() == Type::Category::RationalNumber &&\n\t\t\t\tdynamic_cast<RationalNumberType const&>(*valueComponentType).isFractional() &&\n\t\t\t\tvalueComponentType->mobileType()\n\t\t\t)\n\t\t\t{\n\t\t\t\tif (var.annotation().type->operator==(*valueComponentType->mobileType()))\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t5107_error,\n\t\t\t\t\t\t_statement.location(),\n\t\t\t\t\t\terrorMsg + \", but it can be explicitly converted.\"\n\t\t\t\t\t);\n\t\t\t\telse\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t4486_error,\n\t\t\t\t\t\t_statement.location(),\n\t\t\t\t\t\terrorMsg +\n\t\t\t\t\t\t\". Try converting to type \" +\n\t\t\t\t\t\tvalueComponentType->mobileType()->humanReadableName() +\n\t\t\t\t\t\t\" or use an explicit conversion.\"\n\t\t\t\t\t);\n\t\t\t}\n\t\t\telse\n\t\t\t\tm_errorReporter.typeErrorConcatenateDescriptions(\n\t\t\t\t\t9574_error,\n\t\t\t\t\t_statement.location(),\n\t\t\t\t\terrorMsg + \".\",\n\t\t\t\t\tresult.message()\n\t\t\t\t);\n\t\t}\n\t}\n\n\tif (valueTypes.size() != variables.size())\n\t{\n\t\tsolAssert(m_errorReporter.hasErrors(), \"Should have errors!\");\n\t\tfor (auto const& var: variables)\n\t\t\tif (var && !var->annotation().type)\n\t\t\t\tsolThrow(FatalError, \"Type checker failed to determine types of all variables within the declaration.\");\n\t}\n\n\treturn false;\n}\n\nvoid TypeChecker::endVisit(ExpressionStatement const& _statement)\n{\n\tif (type(_statement.expression())->category() == Type::Category::RationalNumber)\n\t\tif (!dynamic_cast<RationalNumberType const&>(*type(_statement.expression())).mobileType())\n\t\t\tm_errorReporter.typeError(3757_error, _statement.expression().location(), \"Invalid rational number.\");\n\n\tif (auto call = dynamic_cast<FunctionCall const*>(&_statement.expression()))\n\t{\n\t\tif (auto callType = dynamic_cast<FunctionType const*>(type(call->expression())))\n\t\t{\n\t\t\tauto kind = callType->kind();\n\t\t\tif (\n\t\t\t\tkind == FunctionType::Kind::BareCall ||\n\t\t\t\tkind == FunctionType::Kind::BareCallCode ||\n\t\t\t\tkind == FunctionType::Kind::BareDelegateCall ||\n\t\t\t\tkind == FunctionType::Kind::BareStaticCall\n\t\t\t)\n\t\t\t\tm_errorReporter.warning(9302_error, _statement.location(), \"Return value of low-level calls not used.\");\n\t\t\telse if (kind == FunctionType::Kind::Send)\n\t\t\t\tm_errorReporter.warning(5878_error, _statement.location(), \"Failure condition of 'send' ignored. Consider using 'transfer' instead.\");\n\t\t}\n\t}\n}\n\nbool TypeChecker::visit(Conditional const& _conditional)\n{\n\texpectType(_conditional.condition(), *TypeProvider::boolean());\n\n\t_conditional.trueExpression().accept(*this);\n\t_conditional.falseExpression().accept(*this);\n\n\tType const* trueType = type(_conditional.trueExpression())->mobileType();\n\tType const* falseType = type(_conditional.falseExpression())->mobileType();\n\n\tType const* commonType = nullptr;\n\n\tif (!trueType)\n\t\tm_errorReporter.typeError(9717_error, _conditional.trueExpression().location(), \"Invalid mobile type in true expression.\");\n\telse\n\t\tcommonType = trueType;\n\n\tif (!falseType)\n\t\tm_errorReporter.typeError(3703_error, _conditional.falseExpression().location(), \"Invalid mobile type in false expression.\");\n\telse\n\t\tcommonType = falseType;\n\n\tif (!trueType && !falseType)\n\t\tsolThrow(FatalError, \"Both sides of the ternary expression have invalid types.\");\n\telse if (trueType && falseType)\n\t{\n\t\tcommonType = Type::commonType(trueType, falseType);\n\n\t\tif (!commonType)\n\t\t{\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t1080_error,\n\t\t\t\t\t_conditional.location(),\n\t\t\t\t\t\"True expression's type \" +\n\t\t\t\t\ttrueType->humanReadableName() +\n\t\t\t\t\t\" does not match false expression's type \" +\n\t\t\t\t\tfalseType->humanReadableName() +\n\t\t\t\t\t\".\"\n\t\t\t\t\t);\n\t\t\t// even we can't find a common type, we have to set a type here,\n\t\t\t// otherwise the upper statement will not be able to check the type.\n\t\t\tcommonType = trueType;\n\t\t}\n\t}\n\n\t_conditional.annotation().isConstant = false;\n\t_conditional.annotation().type = commonType;\n\t_conditional.annotation().isPure =\n\t\t*_conditional.condition().annotation().isPure &&\n\t\t*_conditional.trueExpression().annotation().isPure &&\n\t\t*_conditional.falseExpression().annotation().isPure;\n\n\t_conditional.annotation().isLValue = false;\n\n\tif (_conditional.annotation().willBeWrittenTo)\n\t\tm_errorReporter.typeError(\n\t\t\t2212_error,\n\t\t\t_conditional.location(),\n\t\t\t\"Conditional expression as left value is not supported yet.\"\n\t\t);\n\n\treturn false;\n}\n\nvoid TypeChecker::checkExpressionAssignment(Type const& _type, Expression const& _expression)\n{\n\tif (auto const* tupleExpression = dynamic_cast<TupleExpression const*>(&_expression))\n\t{\n\t\tif (tupleExpression->components().empty())\n\t\t\tm_errorReporter.typeError(5547_error, _expression.location(), \"Empty tuple on the left hand side.\");\n\n\t\tauto const* tupleType = dynamic_cast<TupleType const*>(&_type);\n\t\tauto const& types = tupleType && tupleExpression->components().size() != 1 ? tupleType->components() : std::vector<Type const*> { &_type };\n\n\t\tsolAssert(\n\t\t\ttupleExpression->components().size() == types.size() || m_errorReporter.hasErrors(),\n\t\t\t\"Array sizes don't match and no errors generated.\"\n\t\t);\n\n\t\tfor (size_t i = 0; i < std::min(tupleExpression->components().size(), types.size()); i++)\n\t\t\tif (types[i])\n\t\t\t{\n\t\t\t\tsolAssert(!!tupleExpression->components()[i], \"\");\n\t\t\t\tcheckExpressionAssignment(*types[i], *tupleExpression->components()[i]);\n\t\t\t}\n\t}\n\telse if (_type.nameable() && _type.containsNestedMapping())\n\t{\n\t\tbool isLocalOrReturn = false;\n\t\tif (auto const* identifier = dynamic_cast<Identifier const*>(&_expression))\n\t\t\tif (auto const* variableDeclaration = dynamic_cast<VariableDeclaration const*>(identifier->annotation().referencedDeclaration))\n\t\t\t\tif (variableDeclaration->isLocalOrReturn())\n\t\t\t\t\tisLocalOrReturn = true;\n\t\tif (!isLocalOrReturn)\n\t\t\tm_errorReporter.typeError(9214_error, _expression.location(), \"Types in storage containing (nested) mappings cannot be assigned to.\");\n\t}\n}\n\nbool TypeChecker::visit(Assignment const& _assignment)\n{\n\trequireLValue(_assignment.leftHandSide());\n\tType const* t = type(_assignment.leftHandSide());\n\t_assignment.annotation().type = t;\n\t_assignment.annotation().isPure = false;\n\t_assignment.annotation().isLValue = false;\n\t_assignment.annotation().isConstant = false;\n\n\tcheckExpressionAssignment(*t, _assignment.leftHandSide());\n\n\tif (TupleType const* tupleType = dynamic_cast<TupleType const*>(t))\n\t{\n\t\tif (_assignment.assignmentOperator() != Token::Assign)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t4289_error,\n\t\t\t\t_assignment.location(),\n\t\t\t\t\"Compound assignment is not allowed for tuple types.\"\n\t\t\t);\n\t\t// Sequenced assignments of tuples is not valid, make the result a \"void\" type.\n\t\t_assignment.annotation().type = TypeProvider::emptyTuple();\n\n\t\texpectType(_assignment.rightHandSide(), *tupleType);\n\t}\n\telse if (_assignment.assignmentOperator() == Token::Assign)\n\t\texpectType(_assignment.rightHandSide(), *t);\n\telse\n\t{\n\t\t// compound assignment\n\t\t_assignment.rightHandSide().accept(*this);\n\t\tType const* resultType = t->binaryOperatorResult(\n\t\t\tTokenTraits::AssignmentToBinaryOp(_assignment.assignmentOperator()),\n\t\t\ttype(_assignment.rightHandSide())\n\t\t);\n\t\tif (!resultType || *resultType != *t)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t7366_error,\n\t\t\t\t_assignment.location(),\n\t\t\t\t\"Operator \" +\n\t\t\t\tstd::string(TokenTraits::friendlyName(_assignment.assignmentOperator())) +\n\t\t\t\t\" not compatible with types \" +\n\t\t\t\tt->humanReadableName() +\n\t\t\t\t\" and \" +\n\t\t\t\ttype(_assignment.rightHandSide())->humanReadableName() +\n\t\t\t\t\".\"\n\t\t\t);\n\t}\n\treturn false;\n}\n\nbool TypeChecker::visit(TupleExpression const& _tuple)\n{\n\t_tuple.annotation().isConstant = false;\n\tstd::vector<ASTPointer<Expression>> const& components = _tuple.components();\n\tTypePointers types;\n\n\tif (_tuple.annotation().willBeWrittenTo)\n\t{\n\t\tif (_tuple.isInlineArray())\n\t\t\tm_errorReporter.fatalTypeError(3025_error, _tuple.location(), \"Inline array type cannot be declared as LValue.\");\n\t\tfor (auto const& component: components)\n\t\t\tif (component)\n\t\t\t{\n\t\t\t\trequireLValue(*component);\n\t\t\t\ttypes.push_back(type(*component));\n\t\t\t}\n\t\t\telse\n\t\t\t\ttypes.push_back(nullptr);\n\t\tif (components.size() == 1)\n\t\t\t_tuple.annotation().type = type(*components[0]);\n\t\telse\n\t\t\t_tuple.annotation().type = TypeProvider::tuple(std::move(types));\n\t\t// If some of the components are not LValues, the error is reported above.\n\t\t_tuple.annotation().isLValue = true;\n\t\t_tuple.annotation().isPure = false;\n\t}\n\telse\n\t{\n\t\tbool isPure = true;\n\t\tType const* inlineArrayType = nullptr;\n\n\t\tfor (size_t i = 0; i < components.size(); ++i)\n\t\t{\n\t\t\tif (!components[i])\n\t\t\t\tm_errorReporter.fatalTypeError(8381_error, _tuple.location(), \"Tuple component cannot be empty.\");\n\n\t\t\tcomponents[i]->accept(*this);\n\t\t\ttypes.push_back(type(*components[i]));\n\n\t\t\tif (types[i]->category() == Type::Category::Tuple)\n\t\t\t\tif (dynamic_cast<TupleType const&>(*types[i]).components().empty())\n\t\t\t\t{\n\t\t\t\t\tif (_tuple.isInlineArray())\n\t\t\t\t\t\tm_errorReporter.fatalTypeError(5604_error, components[i]->location(), \"Array component cannot be empty.\");\n\t\t\t\t\tm_errorReporter.typeError(6473_error, components[i]->location(), \"Tuple component cannot be empty.\");\n\t\t\t\t}\n\n\t\t\t// Note: code generation will visit each of the expression even if they are not assigned from.\n\t\t\tif (types[i]->category() == Type::Category::RationalNumber && components.size() > 1)\n\t\t\t\tif (!dynamic_cast<RationalNumberType const&>(*types[i]).mobileType())\n\t\t\t\t\tm_errorReporter.fatalTypeError(3390_error, components[i]->location(), \"Invalid rational number.\");\n\n\t\t\tif (_tuple.isInlineArray())\n\t\t\t{\n\t\t\t\tsolAssert(!!types[i], \"Inline array cannot have empty components\");\n\n\t\t\t\tif ((i == 0 || inlineArrayType) && !types[i]->mobileType())\n\t\t\t\t\tm_errorReporter.fatalTypeError(9563_error, components[i]->location(), \"Invalid mobile type.\");\n\n\t\t\t\tif (i == 0)\n\t\t\t\t\tinlineArrayType = types[i]->mobileType();\n\t\t\t\telse if (inlineArrayType)\n\t\t\t\t\tinlineArrayType = Type::commonType(inlineArrayType, types[i]);\n\t\t\t}\n\t\t\tif (!*components[i]->annotation().isPure)\n\t\t\t\tisPure = false;\n\t\t}\n\t\t_tuple.annotation().isPure = isPure;\n\t\tif (_tuple.isInlineArray())\n\t\t{\n\t\t\tif (!inlineArrayType)\n\t\t\t\tm_errorReporter.fatalTypeError(6378_error, _tuple.location(), \"Unable to deduce common type for array elements.\");\n\t\t\telse if (!inlineArrayType->nameable())\n\t\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t\t9656_error,\n\t\t\t\t\t_tuple.location(),\n\t\t\t\t\t\"Unable to deduce nameable type for array elements. Try adding explicit type conversion for the first element.\"\n\t\t\t\t);\n\t\t\telse if (inlineArrayType->containsNestedMapping())\n\t\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t\t1545_error,\n\t\t\t\t\t_tuple.location(),\n\t\t\t\t\t\"Type \" + inlineArrayType->humanReadableName() + \" is only valid in storage.\"\n\t\t\t\t);\n\n\t\t\t_tuple.annotation().type = TypeProvider::array(DataLocation::Memory, inlineArrayType, types.size());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (components.size() == 1)\n\t\t\t\t_tuple.annotation().type = type(*components[0]);\n\t\t\telse\n\t\t\t\t_tuple.annotation().type = TypeProvider::tuple(std::move(types));\n\t\t}\n\n\t\t_tuple.annotation().isLValue = false;\n\t}\n\treturn false;\n}\n\nbool TypeChecker::visit(UnaryOperation const& _operation)\n{\n\t// Inc, Dec, Add, Sub, Not, BitNot, Delete\n\tToken op = _operation.getOperator();\n\tbool const modifying = (op == Token::Inc || op == Token::Dec || op == Token::Delete);\n\tif (modifying)\n\t\trequireLValue(_operation.subExpression());\n\telse\n\t\t_operation.subExpression().accept(*this);\n\tType const* operandType = type(_operation.subExpression());\n\n\t// Check if the operator is built-in or user-defined.\n\tTypeResult builtinResult = operandType->unaryOperatorResult(op);\n\tstd::set<FunctionDefinition const*, ASTNode::CompareByID> matchingDefinitions = operandType->operatorDefinitions(\n\t\top,\n\t\t*currentDefinitionScope(),\n\t\ttrue // _unary\n\t);\n\n\t// Operator can't be both user-defined and built-in at the same time.\n\tsolAssert(!builtinResult || matchingDefinitions.empty());\n\n\t// By default use the type we'd expect from correct code. This way we can continue analysis\n\t// of other expressions in a sensible way in case of a non-fatal error.\n\tType const* resultType = operandType;\n\n\tFunctionDefinition const* operatorDefinition = nullptr;\n\tif (builtinResult)\n\t\tresultType = builtinResult;\n\telse if (!matchingDefinitions.empty())\n\t{\n\t\t// This is checked along with `using for` directive but the error is not fatal.\n\t\tif (matchingDefinitions.size() != 1)\n\t\t\tsolAssert(m_errorReporter.hasErrors());\n\n\t\toperatorDefinition = *matchingDefinitions.begin();\n\t}\n\telse\n\t{\n\t\tstd::string description = fmt::format(\n\t\t\t\"Built-in unary operator {} cannot be applied to type {}.\",\n\t\t\tTokenTraits::friendlyName(op),\n\t\t\toperandType->humanReadableName()\n\t\t);\n\t\tif (!builtinResult.message().empty())\n\t\t\tdescription += \" \" + builtinResult.message();\n\t\tif (operandType->typeDefinition() && util::contains(userDefinableOperators, op))\n\t\t\tdescription += \" No matching user-defined operator found.\";\n\n\t\tif (modifying)\n\t\t\t// Cannot just report the error, ignore the unary operator, and continue,\n\t\t\t// because the sub-expression was already processed with requireLValue()\n\t\t\tm_errorReporter.fatalTypeError(9767_error, _operation.location(), description);\n\t\telse\n\t\t\tm_errorReporter.typeError(4907_error, _operation.location(), description);\n\t}\n\n\t_operation.annotation().userDefinedFunction = operatorDefinition;\n\n\tif (operatorDefinition && !_operation.userDefinedFunctionType()->returnParameterTypes().empty())\n\t\t// Use the actual result type from operator definition. Ignore all values but the\n\t\t// first one - in valid code there will be only one anyway.\n\t\tresultType = _operation.userDefinedFunctionType()->returnParameterTypes()[0];\n\t_operation.annotation().type = resultType;\n\t_operation.annotation().isConstant = false;\n\t_operation.annotation().isPure =\n\t\t!modifying &&\n\t\t*_operation.subExpression().annotation().isPure &&\n\t\t(!_operation.userDefinedFunctionType() || _operation.userDefinedFunctionType()->isPure());\n\t_operation.annotation().isLValue = false;\n\n\treturn false;\n}\n\nvoid TypeChecker::endVisit(BinaryOperation const& _operation)\n{\n\tType const* leftType = type(_operation.leftExpression());\n\tType const* rightType = type(_operation.rightExpression());\n\n\t// Check if the operator is built-in or user-defined.\n\tTypeResult builtinResult = leftType->binaryOperatorResult(_operation.getOperator(), rightType);\n\tstd::set<FunctionDefinition const*, ASTNode::CompareByID> matchingDefinitions = leftType->operatorDefinitions(\n\t\t_operation.getOperator(),\n\t\t*currentDefinitionScope(),\n\t\tfalse // _unary\n\t);\n\n\t// Operator can't be both user-defined and built-in at the same time.\n\tsolAssert(!builtinResult || matchingDefinitions.empty());\n\n\tType const* commonType = nullptr;\n\tFunctionDefinition const* operatorDefinition = nullptr;\n\tif (builtinResult)\n\t\tcommonType = builtinResult.get();\n\telse if (!matchingDefinitions.empty())\n\t{\n\t\t// This is checked along with `using for` directive but the error is not fatal.\n\t\tif (matchingDefinitions.size() != 1)\n\t\t\tsolAssert(m_errorReporter.hasErrors());\n\n\t\toperatorDefinition = *matchingDefinitions.begin();\n\n\t\t// Set common type to the type used in the `using for` directive.\n\t\tcommonType = leftType;\n\t}\n\telse\n\t{\n\t\tstd::string description = fmt::format(\n\t\t\t\"Built-in binary operator {} cannot be applied to types {} and {}.\",\n\t\t\tTokenTraits::friendlyName(_operation.getOperator()),\n\t\t\tleftType->humanReadableName(),\n\t\t\trightType->humanReadableName()\n\t\t);\n\t\tif (!builtinResult.message().empty())\n\t\t\tdescription += \" \" + builtinResult.message();\n\t\tif (leftType->typeDefinition() && util::contains(userDefinableOperators, _operation.getOperator()))\n\t\t\tdescription += \" No matching user-defined operator found.\";\n\n\t\tm_errorReporter.typeError(2271_error, _operation.location(), description);\n\n\t\t// Set common type to something we'd expect from correct code just so that we can continue analysis.\n\t\tcommonType = leftType;\n\t}\n\n\t_operation.annotation().commonType = commonType;\n\t_operation.annotation().userDefinedFunction = operatorDefinition;\n\tFunctionType const* userDefinedFunctionType = _operation.userDefinedFunctionType();\n\n\t// By default use the type we'd expect from correct code. This way we can continue analysis\n\t// of other expressions in a sensible way in case of a non-fatal error.\n\tType const* resultType =\n\t\tTokenTraits::isCompareOp(_operation.getOperator()) ?\n\t\tTypeProvider::boolean() :\n\t\tcommonType;\n\n\tif (operatorDefinition)\n\t{\n\t\tTypePointers const& parameterTypes = userDefinedFunctionType->parameterTypes();\n\t\tTypePointers const& returnParameterTypes = userDefinedFunctionType->returnParameterTypes();\n\n\t\t// operatorDefinitions() filters out definitions with non-matching first argument.\n\t\tsolAssert(parameterTypes.size() == 2);\n\t\tsolAssert(parameterTypes[0] && *leftType == *parameterTypes[0]);\n\n\t\tif (*rightType != *parameterTypes[0])\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t5653_error,\n\t\t\t\t_operation.location(),\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"The type of the second operand of this user-defined binary operator {} \"\n\t\t\t\t\t\"does not match the type of the first operand, which is {}.\",\n\t\t\t\t\tTokenTraits::friendlyName(_operation.getOperator()),\n\t\t\t\t\tparameterTypes[0]->humanReadableName()\n\t\t\t\t)\n\t\t\t);\n\n\t\tif (!returnParameterTypes.empty())\n\t\t\t// Use the actual result type from operator definition. Ignore all values but the\n\t\t\t// first one - in valid code there will be only one anyway.\n\t\t\tresultType = returnParameterTypes[0];\n\t}\n\n\t_operation.annotation().type = resultType;\n\t_operation.annotation().isPure =\n\t\t*_operation.leftExpression().annotation().isPure &&\n\t\t*_operation.rightExpression().annotation().isPure &&\n\t\t(!userDefinedFunctionType || userDefinedFunctionType->isPure());\n\t_operation.annotation().isLValue = false;\n\t_operation.annotation().isConstant = false;\n\n\tif (_operation.getOperator() == Token::Equal || _operation.getOperator() == Token::NotEqual)\n\t{\n\t\tauto const* leftFunction = dynamic_cast<FunctionType const*>(leftType);\n\t\tauto const* rightFunction = dynamic_cast<FunctionType const*>(rightType);\n\t\tif (\n\t\t\tleftFunction &&\n\t\t\trightFunction &&\n\t\t\tleftFunction->kind() == FunctionType::Kind::Internal &&\n\t\t\trightFunction->kind() == FunctionType::Kind::Internal\n\t\t)\n\t\t{\n\t\t\tm_errorReporter.warning(\n\t\t\t\t3075_error,\n\t\t\t\t_operation.location(),\n\t\t\t\t\"Comparison of internal function pointers can yield unexpected results \"\n\t\t\t\t\"in the legacy pipeline with the optimizer enabled, and will be disallowed entirely \"\n\t\t\t\t\"in the next breaking release.\"\n\t\t\t);\n\t\t}\n\t}\n\n\tif (_operation.getOperator() == Token::Exp || _operation.getOperator() == Token::SHL)\n\t{\n\t\tstd::string operation = _operation.getOperator() == Token::Exp ? \"exponentiation\" : \"shift\";\n\t\tif (\n\t\t\tleftType->category() == Type::Category::RationalNumber &&\n\t\t\trightType->category() != Type::Category::RationalNumber\n\t\t)\n\t\t{\n\t\t\t// These rules are enforced by the binary operator, but assert them here too.\n\t\t\tif (auto type = dynamic_cast<IntegerType const*>(commonType))\n\t\t\t\tsolAssert(type->numBits() == 256, \"\");\n\t\t\tif (auto type = dynamic_cast<FixedPointType const*>(commonType))\n\t\t\t\tsolAssert(type->numBits() == 256, \"\");\n\t\t}\n\t\tif (\n\t\t\tcommonType->category() == Type::Category::Integer &&\n\t\t\trightType->category() == Type::Category::Integer &&\n\t\t\tdynamic_cast<IntegerType const&>(*commonType).numBits() <\n\t\t\tdynamic_cast<IntegerType const&>(*rightType).numBits()\n\t\t)\n\t\t\tm_errorReporter.warning(\n\t\t\t\t3149_error,\n\t\t\t\t_operation.location(),\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"The result type of the {} operation is equal to the type of the first operand ({}) \"\n\t\t\t\t\t\"ignoring the (larger) type of the second operand ({}) which might be unexpected. \"\n\t\t\t\t\t\"Silence this warning by either converting the first or the second operand to the type of the other.\",\n\t\t\t\t\toperation,\n\t\t\t\t\tcommonType->humanReadableName(),\n\t\t\t\t\trightType->humanReadableName()\n\t\t\t\t)\n\t\t\t);\n\t}\n\tif (\n\t\tTokenTraits::isCompareOp(_operation.getOperator()) &&\n\t\tcommonType->category() == Type::Category::Contract\n\t)\n\t\tm_errorReporter.warning(\n\t\t\t9170_error,\n\t\t\t_operation.location(),\n\t\t\t\"Comparison of variables of contract type is deprecated and scheduled for removal. \"\n\t\t\t\"Use an explicit cast to address type and compare the addresses instead.\"\n\t\t);\n}\n\nType const* TypeChecker::typeCheckTypeConversionAndRetrieveReturnType(\n\tFunctionCall const& _functionCall\n)\n{\n\tsolAssert(*_functionCall.annotation().kind == FunctionCallKind::TypeConversion, \"\");\n\tType const* expressionType = type(_functionCall.expression());\n\n\tstd::vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();\n\tbool const isPositionalCall = _functionCall.names().empty();\n\n\tType const* resultType = dynamic_cast<TypeType const&>(*expressionType).actualType();\n\tif (arguments.size() != 1)\n\t\tm_errorReporter.typeError(\n\t\t\t2558_error,\n\t\t\t_functionCall.location(),\n\t\t\t\"Exactly one argument expected for explicit type conversion.\"\n\t\t);\n\telse if (!isPositionalCall)\n\t\tm_errorReporter.typeError(\n\t\t\t5153_error,\n\t\t\t_functionCall.location(),\n\t\t\t\"Type conversion cannot allow named arguments.\"\n\t\t);\n\telse\n\t{\n\t\tType const* argType = type(*arguments.front());\n\t\t// Resulting data location is memory unless we are converting from a reference\n\t\t// type with a different data location.\n\t\t// (data location cannot yet be specified for type conversions)\n\t\tDataLocation dataLoc = DataLocation::Memory;\n\t\tif (auto argRefType = dynamic_cast<ReferenceType const*>(argType))\n\t\t\tdataLoc = argRefType->location();\n\t\tif (auto type = dynamic_cast<ReferenceType const*>(resultType))\n\t\t\tresultType = TypeProvider::withLocation(type, dataLoc, type->isPointer());\n\t\tBoolResult result = argType->isExplicitlyConvertibleTo(*resultType);\n\t\tif (result)\n\t\t{\n\t\t\tif (auto argArrayType = dynamic_cast<ArrayType const*>(argType))\n\t\t\t{\n\t\t\t\tif (auto resultArrayType = dynamic_cast<ArrayType const*>(resultType))\n\t\t\t\t\tsolAssert(\n\t\t\t\t\t\targArrayType->location() != DataLocation::Storage ||\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tresultArrayType->isPointer() ||\n\t\t\t\t\t\t\t\t(argArrayType->isByteArrayOrString() && resultArrayType->isByteArrayOrString())\n\t\t\t\t\t\t\t) &&\n\t\t\t\t\t\t\tresultArrayType->location() == DataLocation::Storage\n\t\t\t\t\t\t),\n\t\t\t\t\t\t\"Invalid explicit conversion to storage type.\"\n\t\t\t\t\t);\n\t\t\t\telse\n\t\t\t\t\tsolAssert(\n\t\t\t\t\t\targArrayType->isByteArray() && resultType->category() == Type::Category::FixedBytes,\n\t\t\t\t\t\t\"\"\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (\n\t\t\t\tresultType->category() == Type::Category::Contract &&\n\t\t\t\targType->category() == Type::Category::Address\n\t\t\t)\n\t\t\t{\n\t\t\t\tsolAssert(dynamic_cast<ContractType const*>(resultType)->isPayable(), \"\");\n\t\t\t\tsolAssert(\n\t\t\t\t\tdynamic_cast<AddressType const*>(argType)->stateMutability() <\n\t\t\t\t\t\tStateMutability::Payable,\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\t\t\t\tSecondarySourceLocation ssl;\n\t\t\t\tif (\n\t\t\t\t\tauto const* identifier = dynamic_cast<Identifier const*>(arguments.front().get())\n\t\t\t\t)\n\t\t\t\t\tif (\n\t\t\t\t\t\tauto const* variableDeclaration = dynamic_cast<VariableDeclaration const*>(\n\t\t\t\t\t\t\tidentifier->annotation().referencedDeclaration\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\t\tssl.append(\n\t\t\t\t\t\t\t\"Did you mean to declare this variable as \\\"address payable\\\"?\",\n\t\t\t\t\t\t\tvariableDeclaration->location()\n\t\t\t\t\t\t);\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t7398_error,\n\t\t\t\t\t_functionCall.location(),\n\t\t\t\t\tssl,\n\t\t\t\t\t\"Explicit type conversion not allowed from non-payable \\\"address\\\" to \\\"\" +\n\t\t\t\t\tresultType->humanReadableName() +\n\t\t\t\t\t\"\\\", which has a payable fallback function.\"\n\t\t\t\t);\n\t\t\t}\n\t\t\telse if (\n\t\t\t\tauto const* functionType = dynamic_cast<FunctionType const*>(argType);\n\t\t\t\tfunctionType &&\n\t\t\t\tfunctionType->kind() == FunctionType::Kind::External &&\n\t\t\t\tresultType->category() == Type::Category::Address\n\t\t\t)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t5030_error,\n\t\t\t\t\t_functionCall.location(),\n\t\t\t\t\t\"Explicit type conversion not allowed from \\\"\" +\n\t\t\t\t\targType->humanReadableName() +\n\t\t\t\t\t\"\\\" to \\\"\" +\n\t\t\t\t\tresultType->humanReadableName() +\n\t\t\t\t\t\"\\\". To obtain the address of the contract of the function, \" +\n\t\t\t\t\t\"you can use the .address member of the function.\"\n\t\t\t\t);\n\t\t\telse\n\t\t\t\tm_errorReporter.typeErrorConcatenateDescriptions(\n\t\t\t\t\t9640_error,\n\t\t\t\t\t_functionCall.location(),\n\t\t\t\t\t\"Explicit type conversion not allowed from \\\"\" +\n\t\t\t\t\targType->humanReadableName() +\n\t\t\t\t\t\"\\\" to \\\"\" +\n\t\t\t\t\tresultType->humanReadableName() +\n\t\t\t\t\t\"\\\".\",\n\t\t\t\t\tresult.message()\n\t\t\t\t);\n\t\t}\n\t}\n\treturn resultType;\n}\n\nvoid TypeChecker::typeCheckFunctionCall(\n\tFunctionCall const& _functionCall,\n\tFunctionTypePointer _functionType\n)\n{\n\t// Actual function call or struct constructor call.\n\n\tsolAssert(!!_functionType, \"\");\n\tsolAssert(_functionType->kind() != FunctionType::Kind::ABIDecode, \"\");\n\n\tif (_functionType->kind() == FunctionType::Kind::Declaration)\n\t{\n\t\tsolAssert(_functionType->declaration().annotation().contract, \"\");\n\t\tif (\n\t\t\tm_currentContract &&\n\t\t\tm_currentContract->derivesFrom(*_functionType->declaration().annotation().contract) &&\n\t\t\t!dynamic_cast<FunctionDefinition const&>(_functionType->declaration()).isImplemented()\n\t\t)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t7501_error,\n\t\t\t\t_functionCall.location(),\n\t\t\t\t\"Cannot call unimplemented base function.\"\n\t\t\t);\n\t\telse\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t3419_error,\n\t\t\t\t_functionCall.location(),\n\t\t\t\t\"Cannot call function via contract type name.\"\n\t\t\t);\n\t\treturn;\n\t}\n\n\t// Check for unsupported use of bare static call\n\tif (\n\t\t_functionType->kind() == FunctionType::Kind::BareStaticCall &&\n\t\t!m_evmVersion.hasStaticCall()\n\t)\n\t\tm_errorReporter.typeError(\n\t\t\t5052_error,\n\t\t\t_functionCall.location(),\n\t\t\t\"\\\"staticcall\\\" is not supported by the VM version.\"\n\t\t);\n\n\t// Perform standard function call type checking\n\ttypeCheckFunctionGeneralChecks(_functionCall, _functionType);\n}\n\nvoid TypeChecker::typeCheckFallbackFunction(FunctionDefinition const& _function)\n{\n\tsolAssert(_function.isFallback(), \"\");\n\n\tif (_function.libraryFunction())\n\t\tm_errorReporter.typeError(5982_error, _function.location(), \"Libraries cannot have fallback functions.\");\n\tif (_function.stateMutability() != StateMutability::NonPayable && _function.stateMutability() != StateMutability::Payable)\n\t\tm_errorReporter.typeError(\n\t\t\t4575_error,\n\t\t\t_function.location(),\n\t\t\t\"Fallback function must be payable or non-payable, but is \\\"\" +\n\t\t\tstateMutabilityToString(_function.stateMutability()) +\n\t\t\t\"\\\".\"\n\t\t);\n\tif (_function.visibility() != Visibility::External)\n\t\tm_errorReporter.typeError(1159_error, _function.location(), \"Fallback function must be defined as \\\"external\\\".\");\n\n\tif (!_function.returnParameters().empty() || !_function.parameters().empty())\n\t{\n\t\tif (\n\t\t\t_function.returnParameters().size() != 1 ||\n\t\t\t*type(*_function.returnParameters().front()) != *TypeProvider::bytesMemory() ||\n\t\t\t_function.parameters().size() != 1 ||\n\t\t\t*type(*_function.parameters().front()) != *TypeProvider::bytesCalldata()\n\t\t)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t5570_error,\n\t\t\t\t_function.returnParameterList()->location(),\n\t\t\t\t\"Fallback function either has to have the signature \\\"fallback()\\\" or \\\"fallback(bytes calldata) returns (bytes memory)\\\".\"\n\t\t\t);\n\t}\n}\n\nvoid TypeChecker::typeCheckConstructor(FunctionDefinition const& _function)\n{\n\tsolAssert(_function.isConstructor(), \"\");\n\tif (_function.overrides())\n\t\tm_errorReporter.typeError(1209_error, _function.location(), \"Constructors cannot override.\");\n\tif (!_function.returnParameters().empty())\n\t\tm_errorReporter.typeError(9712_error, _function.returnParameterList()->location(), \"Non-empty \\\"returns\\\" directive for constructor.\");\n\tif (_function.stateMutability() != StateMutability::NonPayable && _function.stateMutability() != StateMutability::Payable)\n\t\tm_errorReporter.typeError(\n\t\t\t1558_error,\n\t\t\t_function.location(),\n\t\t\t\"Constructor must be payable or non-payable, but is \\\"\" +\n\t\t\tstateMutabilityToString(_function.stateMutability()) +\n\t\t\t\"\\\".\"\n\t\t);\n\tif (!_function.noVisibilitySpecified())\n\t{\n\t\tauto const& contract = dynamic_cast<ContractDefinition const&>(*_function.scope());\n\t\tif (_function.visibility() != Visibility::Public && _function.visibility() != Visibility::Internal)\n\t\t\tm_errorReporter.typeError(9239_error, _function.location(), \"Constructor cannot have visibility.\");\n\t\telse if (_function.isPublic() && contract.abstract())\n\t\t\tm_errorReporter.declarationError(\n\t\t\t\t8295_error,\n\t\t\t\t_function.location(),\n\t\t\t\t\"Abstract contracts cannot have public constructors. Remove the \\\"public\\\" keyword to fix this.\"\n\t\t\t);\n\t\telse if (!_function.isPublic() && !contract.abstract())\n\t\t\tm_errorReporter.declarationError(\n\t\t\t\t1845_error,\n\t\t\t\t_function.location(),\n\t\t\t\t\"Non-abstract contracts cannot have internal constructors. Remove the \\\"internal\\\" keyword and make the contract abstract to fix this.\"\n\t\t\t);\n\t\telse\n\t\t\tm_errorReporter.warning(\n\t\t\t\t2462_error,\n\t\t\t\t_function.location(),\n\t\t\t\t\"Visibility for constructor is ignored. If you want the contract to be non-deployable, making it \\\"abstract\\\" is sufficient.\"\n\t\t\t);\n\t}\n}\n\nvoid TypeChecker::typeCheckABIEncodeFunctions(\n\tFunctionCall const& _functionCall,\n\tFunctionTypePointer _functionType\n)\n{\n\tsolAssert(!!_functionType, \"\");\n\tsolAssert(\n\t\t_functionType->kind() == FunctionType::Kind::ABIEncode ||\n\t\t_functionType->kind() == FunctionType::Kind::ABIEncodePacked ||\n\t\t_functionType->kind() == FunctionType::Kind::ABIEncodeWithSelector ||\n\t\t_functionType->kind() == FunctionType::Kind::ABIEncodeCall ||\n\t\t_functionType->kind() == FunctionType::Kind::ABIEncodeWithSignature,\n\t\t\"ABI function has unexpected FunctionType::Kind.\"\n\t);\n\tsolAssert(_functionType->takesArbitraryParameters(), \"ABI functions should be variadic.\");\n\n\tbool const isPacked = _functionType->kind() == FunctionType::Kind::ABIEncodePacked;\n\tsolAssert(_functionType->padArguments() != isPacked, \"ABI function with unexpected padding\");\n\n\tbool const abiEncoderV2 = useABICoderV2();\n\n\t// Check for named arguments\n\tif (!_functionCall.names().empty())\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t2627_error,\n\t\t\t_functionCall.location(),\n\t\t\t\"Named arguments cannot be used for functions that take arbitrary parameters.\"\n\t\t);\n\t\treturn;\n\t}\n\n\t// Perform standard function call type checking\n\ttypeCheckFunctionGeneralChecks(_functionCall, _functionType);\n\n\t// No further generic checks needed as we do a precise check for ABIEncodeCall\n\tif (_functionType->kind() == FunctionType::Kind::ABIEncodeCall)\n\t{\n\t\ttypeCheckABIEncodeCallFunction(_functionCall);\n\t\treturn;\n\t}\n\n\t// Check additional arguments for variadic functions\n\tstd::vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();\n\tfor (size_t i = 0; i < arguments.size(); ++i)\n\t{\n\t\tauto const& argType = type(*arguments[i]);\n\n\t\tif (argType->category() == Type::Category::RationalNumber)\n\t\t{\n\t\t\tauto const& rationalType = dynamic_cast<RationalNumberType const&>(*argType);\n\t\t\tif (rationalType.isFractional())\n\t\t\t{\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t6090_error,\n\t\t\t\t\targuments[i]->location(),\n\t\t\t\t\t\"Fractional numbers cannot yet be encoded.\"\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if (!argType->mobileType())\n\t\t\t{\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t8009_error,\n\t\t\t\t\targuments[i]->location(),\n\t\t\t\t\t\"Invalid rational number (too large or division by zero).\"\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if (isPacked)\n\t\t\t{\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t7279_error,\n\t\t\t\t\targuments[i]->location(),\n\t\t\t\t\t\"Cannot perform packed encoding for a literal.\"\n\t\t\t\t\t\" Please convert it to an explicit type first.\"\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (isPacked && !typeSupportedByOldABIEncoder(*argType, false /* isLibrary */))\n\t\t{\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t9578_error,\n\t\t\t\targuments[i]->location(),\n\t\t\t\t\"Type not supported in packed mode.\"\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!argType->fullEncodingType(false, abiEncoderV2, !_functionType->padArguments()))\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t2056_error,\n\t\t\t\targuments[i]->location(),\n\t\t\t\t\"This type cannot be encoded.\"\n\t\t\t);\n\t}\n}\n\nvoid TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCall)\n{\n\tstd::vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();\n\n\t// Expecting first argument to be the function pointer and second to be a tuple.\n\tif (arguments.size() != 2)\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t6219_error,\n\t\t\t_functionCall.location(),\n\t\t\t\"Expected two arguments: a function pointer followed by a tuple.\"\n\t\t);\n\t\treturn;\n\t}\n\n\tFunctionType const* externalFunctionType = nullptr;\n\tif (auto const functionPointerType = dynamic_cast<FunctionTypePointer>(type(*arguments.front())))\n\t{\n\t\t// this cannot be a library function, that is checked below\n\t\texternalFunctionType = functionPointerType->asExternallyCallableFunction(false);\n\t\tsolAssert(externalFunctionType->kind() == functionPointerType->kind());\n\t}\n\telse\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t5511_error,\n\t\t\targuments.front()->location(),\n\t\t\t\"Expected first argument to be a function pointer, not \\\"\" +\n\t\t\ttype(*arguments.front())->humanReadableName() +\n\t\t\t\"\\\".\"\n\t\t);\n\t\treturn;\n\t}\n\n\tif (\n\t\texternalFunctionType->kind() != FunctionType::Kind::External &&\n\t\texternalFunctionType->kind() != FunctionType::Kind::Declaration\n\t)\n\t{\n\t\tstd::string msg = \"Expected regular external function type, or external view on public function.\";\n\n\t\tswitch (externalFunctionType->kind())\n\t\t{\n\t\t\tcase FunctionType::Kind::Internal:\n\t\t\t\tmsg += \" Provided internal function.\";\n\t\t\t\tbreak;\n\t\t\tcase FunctionType::Kind::DelegateCall:\n\t\t\t\tmsg += \" Cannot use library functions for abi.encodeCall.\";\n\t\t\t\tbreak;\n\t\t\tcase FunctionType::Kind::Creation:\n\t\t\t\tmsg += \" Provided creation function.\";\n\t\t\t\tbreak;\n\t\t\tcase FunctionType::Kind::Event:\n\t\t\t\tmsg += \" Cannot use events for abi.encodeCall.\";\n\t\t\t\tbreak;\n\t\t\tcase FunctionType::Kind::Error:\n\t\t\t\tmsg += \" Cannot use errors for abi.encodeCall.\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tmsg += \" Cannot use special function.\";\n\t\t}\n\n\t\tSecondarySourceLocation ssl{};\n\n\t\tif (externalFunctionType->hasDeclaration())\n\t\t{\n\t\t\tssl.append(\"Function is declared here:\", externalFunctionType->declaration().location());\n\t\t\tif (\n\t\t\t\texternalFunctionType->declaration().visibility() == Visibility::Public &&\n\t\t\t\texternalFunctionType->declaration().scope() == m_currentContract\n\t\t\t)\n\t\t\t\tmsg += \" Did you forget to prefix \\\"this.\\\"?\";\n\t\t\telse if (\n\t\t\t\tm_currentContract &&\n\t\t\t\texternalFunctionType->declaration().scope() != m_currentContract &&\n\t\t\t\tutil::contains(\n\t\t\t\t\tm_currentContract->annotation().linearizedBaseContracts,\n\t\t\t\t\texternalFunctionType->declaration().scope()\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tmsg += \" Functions from base contracts have to be external.\";\n\t\t}\n\n\t\tm_errorReporter.typeError(3509_error, arguments[0]->location(), ssl, msg);\n\t\treturn;\n\t}\n\tsolAssert(!externalFunctionType->takesArbitraryParameters(), \"Function must have fixed parameters.\");\n\t// Tuples with only one component become that component\n\tstd::vector<ASTPointer<Expression const>> callArguments;\n\n\tauto const* tupleType = dynamic_cast<TupleType const*>(type(*arguments[1]));\n\tif (tupleType)\n\t{\n\t\tif (TupleExpression const* argumentTuple = dynamic_cast<TupleExpression const*>(arguments[1].get()))\n\t\t\tcallArguments = decltype(callArguments){argumentTuple->components().begin(), argumentTuple->components().end()};\n\t\telse\n\t\t{\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t9062_error,\n\t\t\t\targuments[1]->location(),\n\t\t\t\t\"Expected an inline tuple, not an expression of a tuple type.\"\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t}\n\telse\n\t\tcallArguments.push_back(arguments[1]);\n\n\tif (externalFunctionType->parameterTypes().size() != callArguments.size())\n\t{\n\t\tif (tupleType)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t7788_error,\n\t\t\t\t_functionCall.location(),\n\t\t\t\t\"Expected \" +\n\t\t\t\tstd::to_string(externalFunctionType->parameterTypes().size()) +\n\t\t\t\t\" instead of \" +\n\t\t\t\tstd::to_string(callArguments.size()) +\n\t\t\t\t\" components for the tuple parameter.\"\n\t\t\t);\n\t\telse\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t7515_error,\n\t\t\t\t_functionCall.location(),\n\t\t\t\t\"Expected a tuple with \" +\n\t\t\t\tstd::to_string(externalFunctionType->parameterTypes().size()) +\n\t\t\t\t\" components instead of a single non-tuple parameter.\"\n\t\t\t);\n\t}\n\n\t// Use min() to check as much as we can before failing fatally\n\tsize_t const numParameters = std::min(callArguments.size(), externalFunctionType->parameterTypes().size());\n\n\tfor (size_t i = 0; i < numParameters; i++)\n\t{\n\t\tType const& argType = *type(*callArguments[i]);\n\t\tBoolResult result = argType.isImplicitlyConvertibleTo(*externalFunctionType->parameterTypes()[i]);\n\t\tif (!result)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t5407_error,\n\t\t\t\tcallArguments[i]->location(),\n\t\t\t\t\"Cannot implicitly convert component at position \" +\n\t\t\t\tstd::to_string(i) +\n\t\t\t\t\" from \\\"\" +\n\t\t\t\targType.humanReadableName() +\n\t\t\t\t\"\\\" to \\\"\" +\n\t\t\t\texternalFunctionType->parameterTypes()[i]->humanReadableName() +\n\t\t\t\t\"\\\"\" +\n\t\t\t\t(result.message().empty() ?  \".\" : \": \" + result.message())\n\t\t\t);\n\t}\n}\n\n\nvoid TypeChecker::typeCheckStringConcatFunction(\n\tFunctionCall const& _functionCall,\n\tFunctionType const* _functionType\n)\n{\n\tsolAssert(_functionType);\n\tsolAssert(_functionType->kind() == FunctionType::Kind::StringConcat);\n\tsolAssert(_functionCall.names().empty());\n\n\ttypeCheckFunctionGeneralChecks(_functionCall, _functionType);\n\n\tfor (std::shared_ptr<Expression const> const& argument: _functionCall.arguments())\n\t{\n\t\tType const* argumentType = type(*argument);\n\t\tbool notConvertibleToString = !argumentType->isImplicitlyConvertibleTo(*TypeProvider::stringMemory());\n\n\t\tif (notConvertibleToString)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t9977_error,\n\t\t\t\targument->location(),\n\t\t\t\t\"Invalid type for argument in the string.concat function call. \"\n\t\t\t\t\"string type is required, but \" +\n\t\t\t\targumentType->identifier() + \" provided.\"\n\t\t\t);\n\t}\n}\n\nvoid TypeChecker::typeCheckBytesConcatFunction(\n\tFunctionCall const& _functionCall,\n\tFunctionType const* _functionType\n)\n{\n\tsolAssert(_functionType);\n\tsolAssert(_functionType->kind() == FunctionType::Kind::BytesConcat);\n\tsolAssert(_functionCall.names().empty());\n\n\ttypeCheckFunctionGeneralChecks(_functionCall, _functionType);\n\n\tfor (std::shared_ptr<Expression const> const& argument: _functionCall.arguments())\n\t{\n\t\tType const* argumentType = type(*argument);\n\t\tbool notConvertibleToBytes =\n\t\t\t!argumentType->isImplicitlyConvertibleTo(*TypeProvider::fixedBytes(32)) &&\n\t\t\t!argumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory());\n\t\tbool numberLiteral = (dynamic_cast<RationalNumberType const*>(argumentType) != nullptr);\n\n\t\tif (notConvertibleToBytes || numberLiteral)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t8015_error,\n\t\t\t\targument->location(),\n\t\t\t\t\"Invalid type for argument in the bytes.concat function call. \"\n\t\t\t\t\"bytes or fixed bytes type is required, but \" +\n\t\t\t\targumentType->humanReadableName() + \" provided.\"\n\t\t\t);\n\t}\n}\n\nvoid TypeChecker::typeCheckERC7201Builtin(FunctionCall const& _functionCall, FunctionType const* _functionType)\n{\n\t// erc7201 builtin accepts only 1 argument. Invalid cases with different number\n\t// of arguments are treated after by function `typeCheckFunctionGeneralChecks`\n\tif (_functionCall.arguments().size() > 0)\n\t{\n\t\tType const* argumentType = _functionCall.arguments()[0].get()->annotation().type;\n\t\tsolAssert(argumentType);\n\t\tauto const* arrayType = dynamic_cast<ArrayType const*>(argumentType);\n\n\t\tif (\n\t\t\t!dynamic_cast<StringLiteralType const*>(argumentType) &&\n\t\t\t(!arrayType || !arrayType->isString())\n\t\t)\n\t\t{\n\t\t\tstd::string errorMsg = \"The argument to erc7201 builtin must be a string.\";\n\t\t\tif (arrayType && arrayType->isByteArray())\n\t\t\t\terrorMsg += \" The supplied argument has type bytes.\";\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t6896_error,\n\t\t\t\t_functionCall.arguments()[0]->location(),\n\t\t\t\terrorMsg\n\t\t\t);\n\t\t}\n\t}\n\ttypeCheckFunctionGeneralChecks(_functionCall, _functionType);\n}\n\nvoid TypeChecker::typeCheckFunctionGeneralChecks(\n\tFunctionCall const& _functionCall,\n\tFunctionTypePointer _functionType\n)\n{\n\t// Actual function call or struct constructor call.\n\n\tsolAssert(!!_functionType, \"\");\n\tsolAssert(_functionType->kind() != FunctionType::Kind::ABIDecode, \"\");\n\n\tbool const isPositionalCall = _functionCall.names().empty();\n\tbool const isVariadic = _functionType->takesArbitraryParameters();\n\n\tauto functionCallKind = *_functionCall.annotation().kind;\n\n\tsolAssert(\n\t\t!isVariadic || functionCallKind == FunctionCallKind::FunctionCall,\n\t\t\"Struct constructor calls cannot be variadic.\"\n\t);\n\n\tTypePointers const& parameterTypes = _functionType->parameterTypes();\n\tstd::vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();\n\tstd::vector<ASTPointer<ASTString>> const& argumentNames = _functionCall.names();\n\n\t// Check number of passed in arguments\n\tif (\n\t\targuments.size() < parameterTypes.size() ||\n\t\t(!isVariadic && arguments.size() > parameterTypes.size())\n\t)\n\t{\n\t\tbool const isStructConstructorCall =\n\t\t\tfunctionCallKind == FunctionCallKind::StructConstructorCall;\n\n\t\tauto [errorId, description] = [&]() -> std::tuple<ErrorId, std::string> {\n\t\t\tstd::string msg = isVariadic ?\n\t\t\t\t\"Need at least \" +\n\t\t\t\ttoString(parameterTypes.size()) +\n\t\t\t\t\" arguments for \" +\n\t\t\t\tstd::string(isStructConstructorCall ? \"struct constructor\" : \"function call\") +\n\t\t\t\t\", but provided only \" +\n\t\t\t\ttoString(arguments.size()) +\n\t\t\t\t\".\"\n\t\t\t\t:\n\t\t\t\t\"Wrong argument count for \" +\n\t\t\t\tstd::string(isStructConstructorCall ? \"struct constructor\" : \"function call\") +\n\t\t\t\t\": \" +\n\t\t\t\ttoString(arguments.size()) +\n\t\t\t\t\" arguments given but \" +\n\t\t\t\tstd::string(isVariadic ? \"need at least \" : \"expected \") +\n\t\t\t\ttoString(parameterTypes.size()) +\n\t\t\t\t\".\";\n\n\t\t\tif (isStructConstructorCall)\n\t\t\t{\n\t\t\t\tsolAssert(!isVariadic, \"\");\n\t\t\t\treturn { 9755_error, msg };\n\t\t\t}\n\t\t\telse if (\n\t\t\t\t_functionType->kind() == FunctionType::Kind::BareCall ||\n\t\t\t\t_functionType->kind() == FunctionType::Kind::BareCallCode ||\n\t\t\t\t_functionType->kind() == FunctionType::Kind::BareDelegateCall ||\n\t\t\t\t_functionType->kind() == FunctionType::Kind::BareStaticCall\n\t\t\t)\n\t\t\t{\n\t\t\t\tsolAssert(!isVariadic, \"\");\n\t\t\t\tif (arguments.empty())\n\t\t\t\t\treturn {\n\t\t\t\t\t\t6138_error,\n\t\t\t\t\t\tmsg +\n\t\t\t\t\t\t\" This function requires a single bytes argument.\"\n\t\t\t\t\t\t\" Use \\\"\\\" as argument to provide empty calldata.\"\n\t\t\t\t\t};\n\t\t\t\telse\n\t\t\t\t\treturn {\n\t\t\t\t\t\t8922_error,\n\t\t\t\t\t\tmsg +\n\t\t\t\t\t\t\" This function requires a single bytes argument.\"\n\t\t\t\t\t\t\" If all your arguments are value types, you can use\"\n\t\t\t\t\t\t\" abi.encode(...) to properly generate it.\"\n\t\t\t\t\t};\n\t\t\t}\n\t\t\telse if (\n\t\t\t\t_functionType->kind() == FunctionType::Kind::KECCAK256 ||\n\t\t\t\t_functionType->kind() == FunctionType::Kind::SHA256 ||\n\t\t\t\t_functionType->kind() == FunctionType::Kind::RIPEMD160\n\t\t\t)\n\t\t\t{\n\t\t\t\tsolAssert(!isVariadic, \"\");\n\t\t\t\treturn {\n\t\t\t\t\t4323_error,\n\t\t\t\t\tmsg +\n\t\t\t\t\t\" This function requires a single bytes argument.\"\n\t\t\t\t\t\" Use abi.encodePacked(...) to obtain the pre-0.5.0\"\n\t\t\t\t\t\" behaviour or abi.encode(...) to use ABI encoding.\"\n\t\t\t\t};\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn { isVariadic ? 9308_error : 6160_error, msg };\n\t\t}();\n\n\t\tm_errorReporter.typeError(errorId, _functionCall.location(), description);\n\t\treturn;\n\t}\n\n\t// Parameter to argument map\n\tstd::vector<Expression const*> paramArgMap(parameterTypes.size());\n\n\t// Map parameters to arguments - trivially for positional calls, less so for named calls\n\tif (isPositionalCall)\n\t\tfor (size_t i = 0; i < paramArgMap.size(); ++i)\n\t\t\tparamArgMap[i] = arguments[i].get();\n\telse\n\t{\n\t\tauto const& parameterNames = _functionType->parameterNames();\n\n\t\tsolAssert(\n\t\t\tparameterNames.size() == argumentNames.size(),\n\t\t\t\"Unexpected parameter length mismatch!\"\n\t\t);\n\n\t\t// Check for duplicate argument names\n\t\t{\n\t\t\tbool duplication = false;\n\t\t\tfor (size_t i = 0; i < argumentNames.size(); i++)\n\t\t\t\tfor (size_t j = i + 1; j < argumentNames.size(); j++)\n\t\t\t\t\tif (*argumentNames[i] == *argumentNames[j])\n\t\t\t\t\t{\n\t\t\t\t\t\tduplication = true;\n\t\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t\t6995_error,\n\t\t\t\t\t\t\targuments[i]->location(),\n\t\t\t\t\t\t\t\"Duplicate named argument \\\"\" + *argumentNames[i] + \"\\\".\"\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\tif (duplication)\n\t\t\t\treturn;\n\t\t}\n\n\t\t// map parameter names to argument names\n\t\t{\n\t\t\tbool not_all_mapped = false;\n\n\t\t\tfor (size_t i = 0; i < argumentNames.size(); i++)\n\t\t\t{\n\t\t\t\tsize_t j;\n\t\t\t\tfor (j = 0; j < parameterNames.size(); j++)\n\t\t\t\t\tif (parameterNames[j] == *argumentNames[i])\n\t\t\t\t\t\tbreak;\n\n\t\t\t\tif (j < parameterNames.size())\n\t\t\t\t\tparamArgMap[j] = arguments[i].get();\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tnot_all_mapped = true;\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t4974_error,\n\t\t\t\t\t\t_functionCall.location(),\n\t\t\t\t\t\t\"Named argument \\\"\" +\n\t\t\t\t\t\t*argumentNames[i] +\n\t\t\t\t\t\t\"\\\" does not match function declaration.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (not_all_mapped)\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\t// Check for compatible types between arguments and parameters\n\tfor (size_t i = 0; i < paramArgMap.size(); ++i)\n\t{\n\t\tsolAssert(!!paramArgMap[i], \"unmapped parameter\");\n\t\tBoolResult result = type(*paramArgMap[i])->isImplicitlyConvertibleTo(*parameterTypes[i]);\n\t\tif (!result)\n\t\t{\n\t\t\tauto [errorId, description] = [&]() -> std::tuple<ErrorId, std::string> {\n\t\t\t\tstd::string msg =\n\t\t\t\t\t\"Invalid type for argument in function call. \"\n\t\t\t\t\t\"Invalid implicit conversion from \" +\n\t\t\t\t\ttype(*paramArgMap[i])->humanReadableName() +\n\t\t\t\t\t\" to \" +\n\t\t\t\t\tparameterTypes[i]->humanReadableName() +\n\t\t\t\t\t\" requested.\";\n\t\t\t\tif (!result.message().empty())\n\t\t\t\t\tmsg += \" \" + result.message();\n\t\t\t\tif (\n\t\t\t\t\t_functionType->kind() == FunctionType::Kind::BareCall ||\n\t\t\t\t\t_functionType->kind() == FunctionType::Kind::BareCallCode ||\n\t\t\t\t\t_functionType->kind() == FunctionType::Kind::BareDelegateCall ||\n\t\t\t\t\t_functionType->kind() == FunctionType::Kind::BareStaticCall\n\t\t\t\t)\n\t\t\t\t\treturn {\n\t\t\t\t\t\t8051_error,\n\t\t\t\t\t\tmsg +\n\t\t\t\t\t\t\" This function requires a single bytes argument.\"\n\t\t\t\t\t\t\" If all your arguments are value types, you can\"\n\t\t\t\t\t\t\" use abi.encode(...) to properly generate it.\"\n\t\t\t\t\t};\n\t\t\t\telse if (\n\t\t\t\t\t_functionType->kind() == FunctionType::Kind::KECCAK256 ||\n\t\t\t\t\t_functionType->kind() == FunctionType::Kind::SHA256 ||\n\t\t\t\t\t_functionType->kind() == FunctionType::Kind::RIPEMD160\n\t\t\t\t)\n\t\t\t\t\treturn {\n\t\t\t\t\t\t7556_error,\n\t\t\t\t\t\tmsg +\n\t\t\t\t\t\t\" This function requires a single bytes argument.\"\n\t\t\t\t\t\t\" Use abi.encodePacked(...) to obtain the pre-0.5.0\"\n\t\t\t\t\t\t\" behaviour or abi.encode(...) to use ABI encoding.\"\n\t\t\t\t\t};\n\t\t\t\telse\n\t\t\t\t\treturn { 9553_error, msg };\n\t\t\t}();\n\t\t\tm_errorReporter.typeError(errorId, paramArgMap[i]->location(), description);\n\t\t}\n\t}\n\n\tTypePointers const& returnParameterTypes = _functionType->returnParameterTypes();\n\tbool isLibraryCall = (_functionType->kind() == FunctionType::Kind::DelegateCall);\n\tbool callRequiresABIEncoding =\n\t\t// ABIEncode/ABIDecode calls not included because they should have been already validated\n\t\t// at this point and they have variadic arguments so they need special handling.\n\t\t_functionType->kind() == FunctionType::Kind::DelegateCall ||\n\t\t_functionType->kind() == FunctionType::Kind::External ||\n\t\t_functionType->kind() == FunctionType::Kind::Creation ||\n\t\t_functionType->kind() == FunctionType::Kind::Event ||\n\t\t_functionType->kind() == FunctionType::Kind::Error;\n\n\tif (callRequiresABIEncoding && !useABICoderV2())\n\t{\n\t\tsolAssert(!isVariadic, \"\");\n\t\tsolAssert(parameterTypes.size() == arguments.size(), \"\");\n\t\tsolAssert(!_functionType->isBareCall(), \"\");\n\t\tsolAssert(*_functionCall.annotation().kind == FunctionCallKind::FunctionCall, \"\");\n\n\t\tfor (size_t i = 0; i < parameterTypes.size(); ++i)\n\t\t{\n\t\t\tsolAssert(parameterTypes[i], \"\");\n\n\t\t\tif (!typeSupportedByOldABIEncoder(*parameterTypes[i], isLibraryCall))\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t2443_error,\n\t\t\t\t\tparamArgMap[i]->location(),\n\t\t\t\t\t\"The type of this parameter, \" + parameterTypes[i]->humanReadableName() + \", \"\n\t\t\t\t\t\"is only supported in ABI coder v2. \"\n\t\t\t\t\t\"Use \\\"pragma abicoder v2;\\\" to enable the feature.\"\n\t\t\t\t);\n\t\t}\n\n\t\tfor (size_t i = 0; i < returnParameterTypes.size(); ++i)\n\t\t{\n\t\t\tsolAssert(returnParameterTypes[i], \"\");\n\n\t\t\tif (!typeSupportedByOldABIEncoder(*returnParameterTypes[i], isLibraryCall))\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t2428_error,\n\t\t\t\t\t_functionCall.location(),\n\t\t\t\t\t\"The type of return parameter \" + toString(i + 1) + \", \" + returnParameterTypes[i]->humanReadableName() + \", \"\n\t\t\t\t\t\"is only supported in ABI coder v2. \"\n\t\t\t\t\t\"Use \\\"pragma abicoder v2;\\\" to enable the feature.\"\n\t\t\t\t);\n\t\t}\n\t}\n}\n\nbool TypeChecker::visit(FunctionCall const& _functionCall)\n{\n\tstd::vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();\n\tbool argumentsArePure = true;\n\n\t// We need to check arguments' type first as they will be needed for overload resolution.\n\tfor (ASTPointer<Expression const> const& argument: arguments)\n\t{\n\t\targument->accept(*this);\n\t\tif (!*argument->annotation().isPure)\n\t\t\targumentsArePure = false;\n\t}\n\n\t// Store argument types - and names if given - for overload resolution\n\t{\n\t\tFuncCallArguments funcCallArgs;\n\n\t\tfuncCallArgs.names = _functionCall.names();\n\n\t\tfor (ASTPointer<Expression const> const& argument: arguments)\n\t\t\tfuncCallArgs.types.push_back(type(*argument));\n\n\t\t_functionCall.expression().annotation().arguments = std::move(funcCallArgs);\n\t}\n\n\t_functionCall.expression().accept(*this);\n\n\tType const* expressionType = type(_functionCall.expression());\n\n\t// Determine function call kind and function type for this FunctionCall node\n\tFunctionCallAnnotation& funcCallAnno = _functionCall.annotation();\n\tFunctionTypePointer functionType = nullptr;\n\tfuncCallAnno.isConstant = false;\n\n\tbool isLValue = false;\n\n\t// Determine and assign function call kind, lvalue, purity and function type for this FunctionCall node\n\tswitch (expressionType->category())\n\t{\n\tcase Type::Category::Function:\n\t\tfunctionType = dynamic_cast<FunctionType const*>(expressionType);\n\t\tfuncCallAnno.kind = FunctionCallKind::FunctionCall;\n\n\t\tif (auto memberAccess = dynamic_cast<MemberAccess const*>(&_functionCall.expression()))\n\t\t{\n\t\t\tif (dynamic_cast<FunctionDefinition const*>(memberAccess->annotation().referencedDeclaration))\n\t\t\t\t_functionCall.expression().annotation().calledDirectly = true;\n\t\t}\n\t\telse if (auto identifier = dynamic_cast<Identifier const*>(&_functionCall.expression()))\n\t\t\tif (dynamic_cast<FunctionDefinition const*>(identifier->annotation().referencedDeclaration))\n\t\t\t\t_functionCall.expression().annotation().calledDirectly = true;\n\n\t\t// Purity for function calls also depends upon the callee and its FunctionType\n\t\tfuncCallAnno.isPure =\n\t\t\targumentsArePure &&\n\t\t\t*_functionCall.expression().annotation().isPure &&\n\t\t\tfunctionType->isPure();\n\n\t\tif (functionType->kind() == FunctionType::Kind::ArrayPush)\n\t\t\tisLValue = functionType->parameterTypes().empty();\n\n\t\tbreak;\n\n\tcase Type::Category::TypeType:\n\t{\n\t\t// Determine type for type conversion or struct construction expressions\n\t\tType const* actualType = dynamic_cast<TypeType const&>(*expressionType).actualType();\n\t\tsolAssert(!!actualType, \"\");\n\n\t\tif (actualType->category() == Type::Category::Struct)\n\t\t{\n\t\t\tif (actualType->containsNestedMapping())\n\t\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t\t9515_error,\n\t\t\t\t\t_functionCall.location(),\n\t\t\t\t\t\"Struct containing a (nested) mapping cannot be constructed.\"\n\t\t\t\t);\n\t\t\tfunctionType = dynamic_cast<StructType const&>(*actualType).constructorType();\n\t\t\tfuncCallAnno.kind = FunctionCallKind::StructConstructorCall;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (auto const* contractType = dynamic_cast<ContractType const*>(actualType))\n\t\t\t\tif (contractType->isSuper())\n\t\t\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t\t\t1744_error,\n\t\t\t\t\t\t_functionCall.location(),\n\t\t\t\t\t\t\"Cannot convert to the super type.\"\n\t\t\t\t\t);\n\t\t\tfuncCallAnno.kind = FunctionCallKind::TypeConversion;\n\t\t}\n\n\t\tfuncCallAnno.isPure = argumentsArePure;\n\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\tm_errorReporter.fatalTypeError(5704_error, _functionCall.location(), \"This expression is not callable.\");\n\t\t// Unreachable, because fatalTypeError throws. We don't set kind, but that's okay because the switch below\n\t\t// is never reached. And, even if it was, SetOnce would trigger an assertion violation and not UB.\n\t\tfuncCallAnno.isPure = argumentsArePure;\n\t\tbreak;\n\t}\n\n\tfuncCallAnno.isLValue = isLValue;\n\n\t// Determine return types\n\tswitch (*funcCallAnno.kind)\n\t{\n\tcase FunctionCallKind::TypeConversion:\n\t\tfuncCallAnno.type = typeCheckTypeConversionAndRetrieveReturnType(_functionCall);\n\t\tbreak;\n\n\tcase FunctionCallKind::StructConstructorCall: // fall-through\n\tcase FunctionCallKind::FunctionCall:\n\t{\n\t\tTypePointers returnTypes;\n\n\t\tswitch (functionType->kind())\n\t\t{\n\t\tcase FunctionType::Kind::ABIDecode:\n\t\t{\n\t\t\treturnTypes = typeCheckABIDecodeAndRetrieveReturnType(\n\t\t\t\t_functionCall,\n\t\t\t\tuseABICoderV2()\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::ABIEncode:\n\t\tcase FunctionType::Kind::ABIEncodePacked:\n\t\tcase FunctionType::Kind::ABIEncodeWithSelector:\n\t\tcase FunctionType::Kind::ABIEncodeWithSignature:\n\t\tcase FunctionType::Kind::ABIEncodeCall:\n\t\t{\n\t\t\ttypeCheckABIEncodeFunctions(_functionCall, functionType);\n\t\t\treturnTypes = functionType->returnParameterTypes();\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::MetaType:\n\t\t\treturnTypes = typeCheckMetaTypeFunctionAndRetrieveReturnType(_functionCall);\n\t\t\tbreak;\n\t\tcase FunctionType::Kind::BytesConcat:\n\t\t{\n\t\t\ttypeCheckBytesConcatFunction(_functionCall, functionType);\n\t\t\treturnTypes = functionType->returnParameterTypes();\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::StringConcat:\n\t\t{\n\t\t\ttypeCheckStringConcatFunction(_functionCall, functionType);\n\t\t\treturnTypes = functionType->returnParameterTypes();\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::Wrap:\n\t\tcase FunctionType::Kind::Unwrap:\n\t\t{\n\t\t\ttypeCheckFunctionGeneralChecks(_functionCall, functionType);\n\t\t\treturnTypes = functionType->returnParameterTypes();\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::ERC7201:\n\t\t\ttypeCheckERC7201Builtin(_functionCall, functionType);\n\t\t\treturnTypes = functionType->returnParameterTypes();\n\t\t\tbreak;\n\t\tdefault:\n\t\t{\n\t\t\ttypeCheckFunctionCall(_functionCall, functionType);\n\t\t\treturnTypes = m_evmVersion.supportsReturndata() ?\n\t\t\t\tfunctionType->returnParameterTypes() :\n\t\t\t\tfunctionType->returnParameterTypesWithoutDynamicTypes();\n\t\t\tbreak;\n\t\t}\n\t\t}\n\n\t\tfuncCallAnno.type = returnTypes.size() == 1 ?\n\t\t\tstd::move(returnTypes.front()) :\n\t\t\tTypeProvider::tuple(std::move(returnTypes));\n\n\t\tbreak;\n\t}\n\n\tdefault:\n\t\t// for non-callables, ensure error reported and annotate node to void function\n\t\tsolAssert(m_errorReporter.hasErrors(), \"\");\n\t\tfuncCallAnno.kind = FunctionCallKind::FunctionCall;\n\t\tfuncCallAnno.type = TypeProvider::emptyTuple();\n\t\tbreak;\n\t}\n\n\treturn false;\n}\n\nbool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions)\n{\n\tsolAssert(_functionCallOptions.options().size() == _functionCallOptions.names().size(), \"Lengths of name & value arrays differ!\");\n\n\t_functionCallOptions.expression().annotation().arguments = _functionCallOptions.annotation().arguments;\n\n\t_functionCallOptions.expression().accept(*this);\n\n\t_functionCallOptions.annotation().isPure = false;\n\t_functionCallOptions.annotation().isConstant = false;\n\t_functionCallOptions.annotation().isLValue = false;\n\n\tauto expressionFunctionType = dynamic_cast<FunctionType const*>(type(_functionCallOptions.expression()));\n\tif (!expressionFunctionType)\n\t{\n\t\tm_errorReporter.fatalTypeError(2622_error, _functionCallOptions.location(), \"Expected callable expression before call options.\");\n\t\treturn false;\n\t}\n\n\tbool setSalt = false;\n\tbool setValue = false;\n\tbool setGas = false;\n\n\tFunctionType::Kind kind = expressionFunctionType->kind();\n\tif (\n\t\tkind != FunctionType::Kind::Creation &&\n\t\tkind != FunctionType::Kind::External &&\n\t\tkind != FunctionType::Kind::BareCall &&\n\t\tkind != FunctionType::Kind::BareCallCode &&\n\t\tkind != FunctionType::Kind::BareDelegateCall &&\n\t\tkind != FunctionType::Kind::BareStaticCall\n\t)\n\t{\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t2193_error,\n\t\t\t_functionCallOptions.location(),\n\t\t\t\"Function call options can only be set on external function calls or contract creations.\"\n\t\t);\n\t\treturn false;\n\t}\n\n\tif (\n\t\texpressionFunctionType->valueSet() ||\n\t\texpressionFunctionType->gasSet() ||\n\t\texpressionFunctionType->saltSet()\n\t)\n\t\tm_errorReporter.typeError(\n\t\t\t1645_error,\n\t\t\t_functionCallOptions.location(),\n\t\t\t\"Function call options have already been set, you have to combine them into a single \"\n\t\t\t\"{...}-option.\"\n\t\t);\n\n\tauto setCheckOption = [&](bool& _option, std::string const& _name)\n\t{\n\t\tif (_option)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t9886_error,\n\t\t\t\t_functionCallOptions.location(),\n\t\t\t\t\"Duplicate option \\\"\" + std::move(_name) + \"\\\".\"\n\t\t\t);\n\n\t\t_option = true;\n\t};\n\n\tfor (size_t i = 0; i < _functionCallOptions.names().size(); ++i)\n\t{\n\t\tstd::string const& name = *(_functionCallOptions.names()[i]);\n\t\tif (name == \"salt\")\n\t\t{\n\t\t\tif (kind == FunctionType::Kind::Creation)\n\t\t\t{\n\t\t\t\tsetCheckOption(setSalt, \"salt\");\n\t\t\t\texpectType(*_functionCallOptions.options()[i], *TypeProvider::fixedBytes(32));\n\t\t\t}\n\t\t\telse\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t2721_error,\n\t\t\t\t\t_functionCallOptions.location(),\n\t\t\t\t\t\"Function call option \\\"salt\\\" can only be used with \\\"new\\\".\"\n\t\t\t\t);\n\t\t}\n\t\telse if (name == \"value\")\n\t\t{\n\t\t\tif (kind == FunctionType::Kind::BareDelegateCall)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t6189_error,\n\t\t\t\t\t_functionCallOptions.location(),\n\t\t\t\t\t\"Cannot set option \\\"value\\\" for delegatecall.\"\n\t\t\t\t);\n\t\t\telse if (kind == FunctionType::Kind::BareStaticCall)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t2842_error,\n\t\t\t\t\t_functionCallOptions.location(),\n\t\t\t\t\t\"Cannot set option \\\"value\\\" for staticcall.\"\n\t\t\t\t);\n\t\t\telse if (!expressionFunctionType->isPayable())\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t7006_error,\n\t\t\t\t\t_functionCallOptions.location(),\n\t\t\t\t\tkind == FunctionType::Kind::Creation ?\n\t\t\t\t\t\t\"Cannot set option \\\"value\\\", since the constructor of \" +\n\t\t\t\t\t\texpressionFunctionType->returnParameterTypes().front()->humanReadableName() +\n\t\t\t\t\t\t\" is not payable.\" :\n\t\t\t\t\t\t\"Cannot set option \\\"value\\\" on a non-payable function type.\"\n\t\t\t\t);\n\t\t\telse\n\t\t\t{\n\t\t\t\texpectType(*_functionCallOptions.options()[i], *TypeProvider::uint256());\n\n\t\t\t\tsetCheckOption(setValue, \"value\");\n\t\t\t}\n\t\t}\n\t\telse if (name == \"gas\")\n\t\t{\n\t\t\tif (kind == FunctionType::Kind::Creation)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t9903_error,\n\t\t\t\t\t_functionCallOptions.location(),\n\t\t\t\t\t\"Function call option \\\"gas\\\" cannot be used with \\\"new\\\".\"\n\t\t\t\t);\n\t\t\telse if (m_eofVersion.has_value())\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t3765_error,\n\t\t\t\t\t_functionCallOptions.location(),\n\t\t\t\t\t\"Function call option \\\"gas\\\" cannot be used when compiling to EOF.\"\n\t\t\t\t);\n\t\t\telse\n\t\t\t{\n\t\t\t\texpectType(*_functionCallOptions.options()[i], *TypeProvider::uint256());\n\n\t\t\t\tsetCheckOption(setGas, \"gas\");\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t9318_error,\n\t\t\t\t_functionCallOptions.location(),\n\t\t\t\t\"Unknown call option \\\"\" + name + \"\\\". Valid options are \\\"salt\\\", \\\"value\\\" and \\\"gas\\\".\"\n\t\t\t);\n\t}\n\n\tif (setSalt && !m_evmVersion.hasCreate2())\n\t\tm_errorReporter.typeError(\n\t\t\t5189_error,\n\t\t\t_functionCallOptions.location(),\n\t\t\t\"Unsupported call option \\\"salt\\\" (requires Constantinople-compatible VMs).\"\n\t\t);\n\n\t_functionCallOptions.annotation().type = expressionFunctionType->copyAndSetCallOptions(setGas, setValue, setSalt);\n\treturn false;\n}\n\nvoid TypeChecker::endVisit(NewExpression const& _newExpression)\n{\n\tType const* type = _newExpression.typeName().annotation().type;\n\tsolAssert(!!type, \"Type name not resolved.\");\n\n\t_newExpression.annotation().isConstant = false;\n\t_newExpression.annotation().isLValue = false;\n\n\tif (auto contractName = dynamic_cast<UserDefinedTypeName const*>(&_newExpression.typeName()))\n\t{\n\t\tauto contract = dynamic_cast<ContractDefinition const*>(&dereference(contractName->pathNode()));\n\n\t\tif (!contract)\n\t\t\tm_errorReporter.fatalTypeError(5540_error, _newExpression.location(), \"Identifier is not a contract.\");\n\t\tif (contract->isInterface())\n\t\t\tm_errorReporter.fatalTypeError(2971_error, _newExpression.location(), \"Cannot instantiate an interface.\");\n\t\tif (contract->abstract())\n\t\t\tm_errorReporter.typeError(4614_error, _newExpression.location(), \"Cannot instantiate an abstract contract.\");\n\n\t\t_newExpression.annotation().type = FunctionType::newExpressionType(*contract);\n\t\t_newExpression.annotation().isPure = false;\n\t}\n\telse if (type->category() == Type::Category::Array)\n\t{\n\t\tif (type->containsNestedMapping())\n\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t1164_error,\n\t\t\t\t_newExpression.typeName().location(),\n\t\t\t\t\"Array containing a (nested) mapping cannot be constructed in memory.\"\n\t\t\t);\n\t\tif (!type->isDynamicallySized())\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t3904_error,\n\t\t\t\t_newExpression.typeName().location(),\n\t\t\t\t\"Length has to be placed in parentheses after the array type for new expression.\"\n\t\t\t);\n\t\ttype = TypeProvider::withLocationIfReference(DataLocation::Memory, type);\n\t\t_newExpression.annotation().type = TypeProvider::function(\n\t\t\tTypePointers{TypeProvider::uint256()},\n\t\t\tTypePointers{type},\n\t\t\tstrings(1, \"\"),\n\t\t\tstrings(1, \"\"),\n\t\t\tFunctionType::Kind::ObjectCreation,\n\t\t\tStateMutability::Pure\n\t\t);\n\t\t_newExpression.annotation().isPure = true;\n\t}\n\telse\n\t{\n\t\t_newExpression.annotation().isPure = false;\n\t\tm_errorReporter.fatalTypeError(8807_error, _newExpression.location(), \"Contract or array type expected.\");\n\t}\n}\n\nbool TypeChecker::visit(MemberAccess const& _memberAccess)\n{\n\t_memberAccess.expression().accept(*this);\n\tType const* exprType = type(_memberAccess.expression());\n\tASTString const& memberName = _memberAccess.memberName();\n\n\tauto& annotation = _memberAccess.annotation();\n\n\t// Retrieve the types of the arguments if this is used to call a function.\n\tauto const& arguments = annotation.arguments;\n\tMemberList::MemberMap possibleMembers = exprType->members(currentDefinitionScope()).membersByName(memberName);\n\tsize_t const initialMemberCount = possibleMembers.size();\n\tif (initialMemberCount > 1 && arguments)\n\t{\n\t\t// do overload resolution\n\t\tfor (auto it = possibleMembers.begin(); it != possibleMembers.end();)\n\t\t\tif (\n\t\t\t\tit->type->category() == Type::Category::Function &&\n\t\t\t\t!dynamic_cast<FunctionType const&>(*it->type).canTakeArguments(*arguments, exprType)\n\t\t\t)\n\t\t\t\tit = possibleMembers.erase(it);\n\t\t\telse\n\t\t\t\t++it;\n\t}\n\n\tannotation.isConstant = false;\n\n\tif (possibleMembers.empty())\n\t{\n\t\tif (initialMemberCount == 0 && !dynamic_cast<ArraySliceType const*>(exprType))\n\t\t{\n\t\t\t// Try to see if the member was removed because it is only available for storage types.\n\t\t\tauto storageType = TypeProvider::withLocationIfReference(\n\t\t\t\tDataLocation::Storage,\n\t\t\t\texprType\n\t\t\t);\n\t\t\tif (!storageType->members(currentDefinitionScope()).membersByName(memberName).empty())\n\t\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t\t4994_error,\n\t\t\t\t\t_memberAccess.location(),\n\t\t\t\t\t\"Member \\\"\" + memberName + \"\\\" is not available in \" +\n\t\t\t\t\texprType->humanReadableName() +\n\t\t\t\t\t\" outside of storage.\"\n\t\t\t\t);\n\t\t}\n\n\t\tauto [errorId, description] = [&]() -> std::tuple<ErrorId, std::string> {\n\t\t\tstd::string errorMsg = \"Member \\\"\" + memberName + \"\\\" not found or not visible \"\n\t\t\t\t\"after argument-dependent lookup in \" + exprType->humanReadableName() + \".\";\n\n\t\t\tif (auto const* funType = dynamic_cast<FunctionType const*>(exprType))\n\t\t\t{\n\t\t\t\tTypePointers const& t = funType->returnParameterTypes();\n\n\t\t\t\tif (memberName == \"value\")\n\t\t\t\t{\n\t\t\t\t\tif (funType->kind() == FunctionType::Kind::Creation)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t8827_error,\n\t\t\t\t\t\t\t\"Constructor for \" + t.front()->humanReadableName() + \" must be payable for member \\\"value\\\" to be available.\"\n\t\t\t\t\t\t};\n\t\t\t\t\telse if (\n\t\t\t\t\t\tfunType->kind() == FunctionType::Kind::DelegateCall ||\n\t\t\t\t\t\tfunType->kind() == FunctionType::Kind::BareDelegateCall\n\t\t\t\t\t)\n\t\t\t\t\t\treturn { 8477_error, \"Member \\\"value\\\" is not allowed in delegated calls due to \\\"msg.value\\\" persisting.\" };\n\t\t\t\t\telse\n\t\t\t\t\t\treturn { 8820_error, \"Member \\\"value\\\" is only available for payable functions.\" };\n\t\t\t\t}\n\t\t\t\telse if (\n\t\t\t\t\tt.size() == 1 && (\n\t\t\t\t\t\tt.front()->category() == Type::Category::Struct ||\n\t\t\t\t\t\tt.front()->category() == Type::Category::Contract\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t\treturn { 6005_error, errorMsg + \" Did you intend to call the function?\" };\n\t\t\t}\n\t\t\telse if (exprType->category() == Type::Category::Contract)\n\t\t\t{\n\t\t\t\tfor (MemberList::Member const& addressMember: TypeProvider::payableAddress()->nativeMembers(nullptr))\n\t\t\t\t\tif (addressMember.name == memberName)\n\t\t\t\t\t{\n\t\t\t\t\t\tauto const* var = dynamic_cast<Identifier const*>(&_memberAccess.expression());\n\t\t\t\t\t\tstd::string varName = var ? var->name() : \"...\";\n\t\t\t\t\t\terrorMsg += \" Use \\\"address(\" + varName + \").\" + memberName + \"\\\" to access this address member.\";\n\t\t\t\t\t\treturn { 3125_error, errorMsg };\n\t\t\t\t\t}\n\t\t\t}\n\t\t\telse if (auto const* addressType = dynamic_cast<AddressType const*>(exprType))\n\t\t\t{\n\t\t\t\t// Trigger error when using send or transfer with a non-payable fallback function.\n\t\t\t\tif (memberName == \"send\" || memberName == \"transfer\")\n\t\t\t\t{\n\t\t\t\t\tsolAssert(\n\t\t\t\t\t\taddressType->stateMutability() != StateMutability::Payable,\n\t\t\t\t\t\t\"Expected address not-payable as members were not found\"\n\t\t\t\t\t);\n\n\t\t\t\t\treturn { 9862_error, \"\\\"send\\\" and \\\"transfer\\\" are only available for objects of type \\\"address payable\\\", not \\\"\" + exprType->humanReadableName() + \"\\\".\" };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { 9582_error, errorMsg };\n\t\t}();\n\n\t\tm_errorReporter.fatalTypeError(\n\t\t\terrorId,\n\t\t\t_memberAccess.location(),\n\t\t\tdescription\n\t\t);\n\t}\n\telse if (possibleMembers.size() > 1)\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t6675_error,\n\t\t\t_memberAccess.location(),\n\t\t\t\"Member \\\"\" + memberName + \"\\\" not unique \"\n\t\t\t\"after argument-dependent lookup in \" + exprType->humanReadableName() +\n\t\t\t(memberName == \"value\" ? \" - did you forget the \\\"payable\\\" modifier?\" : \".\")\n\t\t);\n\n\tannotation.referencedDeclaration = possibleMembers.front().declaration;\n\tannotation.type = possibleMembers.front().type;\n\n\tVirtualLookup requiredLookup = VirtualLookup::Static;\n\n\tif (auto funType = dynamic_cast<FunctionType const*>(annotation.type))\n\t{\n\t\tsolAssert(\n\t\t\t!funType->hasBoundFirstArgument() || exprType->isImplicitlyConvertibleTo(*funType->selfType()),\n\t\t\t\"Function \\\"\" + memberName + \"\\\" cannot be called on an object of type \" +\n\t\t\texprType->humanReadableName() + \" (expected \" + funType->selfType()->humanReadableName() + \").\"\n\t\t);\n\n\t\tif (\n\t\t\tdynamic_cast<FunctionType const*>(exprType) &&\n\t\t\t!annotation.referencedDeclaration &&\n\t\t\t(memberName == \"value\" || memberName == \"gas\")\n\t\t)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t1621_error,\n\t\t\t\t_memberAccess.location(),\n\t\t\t\t\"Using \\\".\" + memberName + \"(...)\\\" is deprecated. Use \\\"{\" + memberName + \": ...}\\\" instead.\"\n\t\t\t);\n\n\t\tif (\n\t\t\tfunType->kind() == FunctionType::Kind::ArrayPush &&\n\t\t\targuments.value().numArguments() != 0 &&\n\t\t\texprType->containsNestedMapping()\n\t\t)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t8871_error,\n\t\t\t\t_memberAccess.location(),\n\t\t\t\t\"Storage arrays with nested mappings do not support .push(<arg>).\"\n\t\t\t);\n\n\t\tif (!funType->hasBoundFirstArgument())\n\t\t\tif (auto typeType = dynamic_cast<TypeType const*>(exprType))\n\t\t\t{\n\t\t\t\tauto contractType = dynamic_cast<ContractType const*>(typeType->actualType());\n\t\t\t\tif (contractType && contractType->isSuper())\n\t\t\t\t\trequiredLookup = VirtualLookup::Super;\n\t\t\t}\n\n\t\tif (\n\t\t\tfunType->kind() == FunctionType::Kind::Send ||\n\t\t\tfunType->kind() == FunctionType::Kind::Transfer\n\t\t)\n\t\t\tm_errorReporter.warning(\n\t\t\t\t9207_error,\n\t\t\t\t_memberAccess.location(),\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"'{}' is deprecated and scheduled for removal. Use 'call{{value: <amount>}}(\\\"\\\")' instead.\",\n\t\t\t\t\tfunType->kind() == FunctionType::Kind::Send ? \"send\" : \"transfer\"\n\t\t\t\t)\n\t\t\t);\n\t}\n\n\tannotation.requiredLookup = requiredLookup;\n\n\tif (auto const* structType = dynamic_cast<StructType const*>(exprType))\n\t\tannotation.isLValue = !structType->dataStoredIn(DataLocation::CallData);\n\telse if (exprType->category() == Type::Category::Array)\n\t\tannotation.isLValue = false;\n\telse if (exprType->category() == Type::Category::FixedBytes)\n\t\tannotation.isLValue = false;\n\telse if (TypeType const* typeType = dynamic_cast<decltype(typeType)>(exprType))\n\t{\n\t\tif (ContractType const* contractType = dynamic_cast<decltype(contractType)>(typeType->actualType()))\n\t\t{\n\t\t\tannotation.isLValue = annotation.referencedDeclaration->isLValue();\n\t\t\tif (\n\t\t\t\tauto const* functionType = dynamic_cast<FunctionType const*>(annotation.type);\n\t\t\t\tfunctionType &&\n\t\t\t\tfunctionType->kind() == FunctionType::Kind::Declaration\n\t\t\t)\n\t\t\t\tannotation.isPure = *_memberAccess.expression().annotation().isPure;\n\t\t}\n\t\telse\n\t\t\tannotation.isLValue = false;\n\t}\n\telse if (exprType->category() == Type::Category::Module)\n\t{\n\t\tannotation.isPure = *_memberAccess.expression().annotation().isPure;\n\t\tannotation.isLValue = false;\n\t}\n\telse\n\t\tannotation.isLValue = false;\n\n\t// TODO some members might be pure, but for example `address(0x123).balance` is not pure\n\t// although every subexpression is, so leaving this limited for now.\n\tif (auto tt = dynamic_cast<TypeType const*>(exprType))\n\t{\n\t\tif (\n\t\t\ttt->actualType()->category() == Type::Category::Enum ||\n\t\t\ttt->actualType()->category() == Type::Category::UserDefinedValueType\n\t\t)\n\t\t\tannotation.isPure = true;\n\n\t\t// `concat` purity depends also on its arguments, but this is checked later, in visit(FunctionCall...)\n\t\t// This covers `bytes.concat` and `string.concat`.\n\t\tif (tt->actualType()->category() == Type::Category::Array)\n\t\t{\n\t\t\tif (\n\t\t\t\tauto const* funcType = dynamic_cast<FunctionType const*>(annotation.type);\n\t\t\t\tfuncType &&\n\t\t\t\t(\n\t\t\t\t\tfuncType->kind() == FunctionType::Kind::StringConcat ||\n\t\t\t\t\tfuncType->kind() == FunctionType::Kind::BytesConcat\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tannotation.isPure = true;\n\t\t}\n\t}\n\tif (\n\t\tauto const* functionType = dynamic_cast<FunctionType const*>(exprType);\n\t\tfunctionType &&\n\t\tfunctionType->hasDeclaration() &&\n\t\tmemberName == \"selector\"\n\t)\n\t{\n\t\tif (dynamic_cast<FunctionDefinition const*>(&functionType->declaration()))\n\t\t{\n\t\t\tif (auto const* parentAccess = dynamic_cast<MemberAccess const*>(&_memberAccess.expression()))\n\t\t\t{\n\t\t\t\tbool isPure = *parentAccess->expression().annotation().isPure;\n\t\t\t\t// Accessing a function selector using `super|this.f.selector`.\n\t\t\t\tif (auto const* exprInt = dynamic_cast<Identifier const*>(&parentAccess->expression()))\n\t\t\t\t\tif (exprInt->name() == \"this\" || exprInt->name() == \"super\")\n\t\t\t\t\t\tisPure = true;\n\n\t\t\t\tannotation.isPure = isPure;\n\t\t\t}\n\t\t}\n\t\t// In case of event or error definition the selector is always compile-time constant, as it can be\n\t\t// a keccak256 hash of the event signature or a function selector in case of an error.\n\t\telse if (\n\t\t\tdynamic_cast<EventDefinition const*>(&functionType->declaration()) ||\n\t\t\tdynamic_cast<ErrorDefinition const*>(&functionType->declaration())\n\t\t)\n\t\t\tannotation.isPure = true;\n\t}\n\n\tif (\n\t\tauto const* varDecl = dynamic_cast<VariableDeclaration const*>(annotation.referencedDeclaration);\n\t\t!annotation.isPure.set() &&\n\t\tvarDecl &&\n\t\tvarDecl->isConstant()\n\t)\n\t\tannotation.isPure = true;\n\n\tif (auto magicType = dynamic_cast<MagicType const*>(exprType))\n\t{\n\t\tif (magicType->kind() == MagicType::Kind::ABI)\n\t\t\tannotation.isPure = true;\n\t\telse if (magicType->kind() == MagicType::Kind::MetaType && (\n\t\t\tmemberName == \"creationCode\" || memberName == \"runtimeCode\"\n\t\t))\n\t\t{\n\t\t\tannotation.isPure = true;\n\t\t\tContractType const& accessedContractType = dynamic_cast<ContractType const&>(*magicType->typeArgument());\n\t\t\tsolAssert(!accessedContractType.isSuper(), \"\");\n\t\t\tif (\n\t\t\t\tmemberName == \"runtimeCode\" &&\n\t\t\t\t!accessedContractType.immutableVariables().empty()\n\t\t\t)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t9274_error,\n\t\t\t\t\t_memberAccess.location(),\n\t\t\t\t\t\"\\\"runtimeCode\\\" is not available for contracts containing immutable variables.\"\n\t\t\t\t);\n\t\t}\n\t\telse if (magicType->kind() == MagicType::Kind::MetaType && memberName == \"name\")\n\t\t\tannotation.isPure = true;\n\t\telse if (magicType->kind() == MagicType::Kind::MetaType && memberName == \"interfaceId\")\n\t\t\tannotation.isPure = true;\n\t\telse if (\n\t\t\tmagicType->kind() == MagicType::Kind::MetaType &&\n\t\t\t(memberName == \"min\" || memberName == \"max\")\n\t\t)\n\t\t\tannotation.isPure = true;\n\t\telse if (magicType->kind() == MagicType::Kind::Block)\n\t\t{\n\t\t\tif (memberName == \"chainid\" && !m_evmVersion.hasChainID())\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t3081_error,\n\t\t\t\t\t_memberAccess.location(),\n\t\t\t\t\t\"\\\"chainid\\\" is not supported by the VM version.\"\n\t\t\t\t);\n\t\t\telse if (memberName == \"basefee\" && !m_evmVersion.hasBaseFee())\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t5921_error,\n\t\t\t\t\t_memberAccess.location(),\n\t\t\t\t\t\"\\\"basefee\\\" is not supported by the VM version.\"\n\t\t\t\t);\n\t\t\telse if (memberName == \"blobbasefee\" && !m_evmVersion.hasBlobBaseFee())\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t1006_error,\n\t\t\t\t\t_memberAccess.location(),\n\t\t\t\t\t\"\\\"blobbasefee\\\" is not supported by the VM version.\"\n\t\t\t\t);\n\t\t\telse if (memberName == \"prevrandao\" && !m_evmVersion.hasPrevRandao())\n\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t9432_error,\n\t\t\t\t\t_memberAccess.location(),\n\t\t\t\t\t\"\\\"prevrandao\\\" is not supported by the VM version and will be treated as \\\"difficulty\\\".\"\n\t\t\t\t);\n\t\t\telse if (memberName == \"difficulty\" && m_evmVersion.hasPrevRandao())\n\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t8417_error,\n\t\t\t\t\t_memberAccess.location(),\n\t\t\t\t\t\"Since the VM version paris, \\\"difficulty\\\" was replaced by \\\"prevrandao\\\", which now returns a random number based on the beacon chain.\"\n\t\t\t\t);\n\t\t}\n\t}\n\n\tif (\n\t\t_memberAccess.expression().annotation().type->category() == Type::Category::Address &&\n\t\tmemberName == \"codehash\" &&\n\t\t!m_evmVersion.hasExtCodeHash()\n\t)\n\t\tm_errorReporter.typeError(\n\t\t\t7598_error,\n\t\t\t_memberAccess.location(),\n\t\t\t\"\\\"codehash\\\" is not supported by the VM version.\"\n\t\t);\n\n\tif (!annotation.isPure.set())\n\t\tannotation.isPure = false;\n\n\treturn false;\n}\n\nbool TypeChecker::visit(IndexAccess const& _access)\n{\n\t_access.annotation().isConstant = false;\n\t_access.baseExpression().accept(*this);\n\tType const* baseType = type(_access.baseExpression());\n\tType const* resultType = nullptr;\n\tbool isLValue = false;\n\tbool isPure = *_access.baseExpression().annotation().isPure;\n\tExpression const* index = _access.indexExpression();\n\tswitch (baseType->category())\n\t{\n\tcase Type::Category::ArraySlice:\n\t{\n\t\tauto const& arrayType = dynamic_cast<ArraySliceType const&>(*baseType).arrayType();\n\t\tif (arrayType.location() != DataLocation::CallData || !arrayType.isDynamicallySized())\n\t\t\tm_errorReporter.typeError(4802_error, _access.location(), \"Index access is only implemented for slices of dynamic calldata arrays.\");\n\t\tbaseType = &arrayType;\n\t\t[[fallthrough]];\n\t}\n\tcase Type::Category::Array:\n\t{\n\t\tArrayType const& actualType = dynamic_cast<ArrayType const&>(*baseType);\n\t\tif (!index)\n\t\t\tm_errorReporter.typeError(9689_error, _access.location(), \"Index expression cannot be omitted.\");\n\t\telse if (actualType.isString())\n\t\t{\n\t\t\tm_errorReporter.typeError(9961_error, _access.location(), \"Index access for string is not possible.\");\n\t\t\tindex->accept(*this);\n\t\t}\n\t\telse\n\t\t{\n\t\t\texpectType(*index, *TypeProvider::uint256());\n\t\t\tif (!m_errorReporter.hasErrors())\n\t\t\t\tif (auto numberType = dynamic_cast<RationalNumberType const*>(type(*index)))\n\t\t\t\t{\n\t\t\t\t\tsolAssert(!numberType->isFractional(), \"\");\n\t\t\t\t\tif (!actualType.isDynamicallySized() && actualType.length() <= numberType->literalValue(nullptr))\n\t\t\t\t\t\tm_errorReporter.typeError(3383_error, _access.location(), \"Out of bounds array access.\");\n\t\t\t\t}\n\t\t}\n\t\tresultType = actualType.baseType();\n\t\tisLValue = actualType.location() != DataLocation::CallData;\n\t\tbreak;\n\t}\n\tcase Type::Category::Mapping:\n\t{\n\t\tMappingType const& actualType = dynamic_cast<MappingType const&>(*baseType);\n\t\tif (!index)\n\t\t\tm_errorReporter.typeError(1267_error, _access.location(), \"Index expression cannot be omitted.\");\n\t\telse\n\t\t\texpectType(*index, *actualType.keyType());\n\t\tresultType = actualType.valueType();\n\t\tisLValue = true;\n\t\tbreak;\n\t}\n\tcase Type::Category::TypeType:\n\t{\n\t\tTypeType const& typeType = dynamic_cast<TypeType const&>(*baseType);\n\t\tif (auto const* contractType = dynamic_cast<ContractType const*>(typeType.actualType()))\n\t\t\tif (contractType->contractDefinition().isLibrary())\n\t\t\t\tm_errorReporter.typeError(2876_error, _access.location(), \"Index access for library types and arrays of libraries are not possible.\");\n\t\tif (!index)\n\t\t\tresultType = TypeProvider::typeType(TypeProvider::array(DataLocation::Memory, typeType.actualType()));\n\t\telse\n\t\t{\n\t\t\tu256 length = 1;\n\t\t\tif (expectType(*index, *TypeProvider::uint256()))\n\t\t\t{\n\t\t\t\tif (auto indexValue = dynamic_cast<RationalNumberType const*>(type(*index)))\n\t\t\t\t\tlength = indexValue->literalValue(nullptr);\n\t\t\t\telse\n\t\t\t\t\tm_errorReporter.fatalTypeError(3940_error, index->location(), \"Integer constant expected.\");\n\t\t\t}\n\t\t\telse\n\t\t\t\tsolAssert(m_errorReporter.hasErrors(), \"Expected errors as expectType returned false\");\n\n\t\t\tresultType = TypeProvider::typeType(TypeProvider::array(\n\t\t\t\tDataLocation::Memory,\n\t\t\t\ttypeType.actualType(),\n\t\t\t\tlength\n\t\t\t));\n\t\t}\n\t\tbreak;\n\t}\n\tcase Type::Category::FixedBytes:\n\t{\n\t\tFixedBytesType const& bytesType = dynamic_cast<FixedBytesType const&>(*baseType);\n\t\tif (!index)\n\t\t\tm_errorReporter.typeError(8830_error, _access.location(), \"Index expression cannot be omitted.\");\n\t\telse\n\t\t{\n\t\t\tif (!expectType(*index, *TypeProvider::uint256()))\n\t\t\t\tm_errorReporter.fatalTypeError(6318_error, _access.location(), \"Index expression cannot be represented as an unsigned integer.\");\n\t\t\tif (auto integerType = dynamic_cast<RationalNumberType const*>(type(*index)))\n\t\t\t\tif (bytesType.numBytes() <= integerType->literalValue(nullptr))\n\t\t\t\t\tm_errorReporter.typeError(1859_error, _access.location(), \"Out of bounds array access.\");\n\t\t}\n\t\tresultType = TypeProvider::fixedBytes(1);\n\t\tisLValue = false; // @todo this heavily depends on how it is embedded\n\t\tbreak;\n\t}\n\tdefault:\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t2614_error,\n\t\t\t_access.baseExpression().location(),\n\t\t\t\"Indexed expression has to be a type, mapping or array (is \" + baseType->humanReadableName() + \")\"\n\t\t);\n\t}\n\t_access.annotation().type = resultType;\n\t_access.annotation().isLValue = isLValue;\n\tif (index && !*index->annotation().isPure)\n\t\tisPure = false;\n\t_access.annotation().isPure = isPure;\n\n\treturn false;\n}\n\nbool TypeChecker::visit(IndexRangeAccess const& _access)\n{\n\t_access.annotation().isConstant = false;\n\t_access.baseExpression().accept(*this);\n\n\tbool isLValue = false; // TODO: set this correctly when implementing slices for memory and storage arrays\n\tbool isPure = *_access.baseExpression().annotation().isPure;\n\n\tif (Expression const* start = _access.startExpression())\n\t{\n\t\texpectType(*start, *TypeProvider::uint256());\n\t\tif (!*start->annotation().isPure)\n\t\t\tisPure = false;\n\t}\n\tif (Expression const* end = _access.endExpression())\n\t{\n\t\texpectType(*end, *TypeProvider::uint256());\n\t\tif (!*end->annotation().isPure)\n\t\t\tisPure = false;\n\t}\n\n\t_access.annotation().isLValue = isLValue;\n\t_access.annotation().isPure = isPure;\n\n\tType const* exprType = type(_access.baseExpression());\n\tif (exprType->category() == Type::Category::TypeType)\n\t{\n\t\tm_errorReporter.typeError(1760_error, _access.location(), \"Types cannot be sliced.\");\n\t\t_access.annotation().type = exprType;\n\t\treturn false;\n\t}\n\n\tArrayType const* arrayType = nullptr;\n\tif (auto const* arraySlice = dynamic_cast<ArraySliceType const*>(exprType))\n\t\tarrayType = &arraySlice->arrayType();\n\telse if (!(arrayType = dynamic_cast<ArrayType const*>(exprType)))\n\t\tm_errorReporter.fatalTypeError(4781_error, _access.location(), \"Index range access is only possible for arrays and array slices.\");\n\n\tif (arrayType->location() != DataLocation::CallData || !arrayType->isDynamicallySized())\n\t\tm_errorReporter.typeError(1227_error, _access.location(), \"Index range access is only supported for dynamic calldata arrays.\");\n\telse if (arrayType->baseType()->isDynamicallyEncoded())\n\t\tm_errorReporter.typeError(2148_error, _access.location(), \"Index range access is not supported for arrays with dynamically encoded base types.\");\n\t_access.annotation().type = TypeProvider::arraySlice(*arrayType);\n\n\treturn false;\n}\n\nstd::vector<Declaration const*> TypeChecker::cleanOverloadedDeclarations(\n\tIdentifier const& _identifier,\n\tstd::vector<Declaration const*> const& _candidates\n)\n{\n\tsolAssert(_candidates.size() > 1, \"\");\n\tstd::vector<Declaration const*> uniqueDeclarations;\n\n\tfor (Declaration const* declaration: _candidates)\n\t{\n\t\tsolAssert(declaration, \"\");\n\t\t// the declaration is functionDefinition, eventDefinition or a VariableDeclaration while declarations > 1\n\t\tsolAssert(\n\t\t\tdynamic_cast<FunctionDefinition const*>(declaration) ||\n\t\t\tdynamic_cast<EventDefinition const*>(declaration) ||\n\t\t\tdynamic_cast<VariableDeclaration const*>(declaration) ||\n\t\t\tdynamic_cast<MagicVariableDeclaration const*>(declaration),\n\t\t\t\"Found overloading involving something not a function, event or a (magic) variable.\"\n\t\t);\n\n\t\tFunctionTypePointer functionType {declaration->functionType(false)};\n\t\tif (!functionType)\n\t\t\tfunctionType = declaration->functionType(true);\n\t\tsolAssert(functionType, \"Failed to determine the function type of the overloaded.\");\n\n\t\tfor (Type const* parameter: functionType->parameterTypes() + functionType->returnParameterTypes())\n\t\t\tif (!parameter)\n\t\t\t\tm_errorReporter.fatalDeclarationError(3893_error, _identifier.location(), \"Function type can not be used in this context.\");\n\n\t\tif (uniqueDeclarations.end() == find_if(\n\t\t\tuniqueDeclarations.begin(),\n\t\t\tuniqueDeclarations.end(),\n\t\t\t[&](Declaration const* d)\n\t\t\t{\n\t\t\t\tFunctionType const* newFunctionType = d->functionType(false);\n\t\t\t\tif (!newFunctionType)\n\t\t\t\t\tnewFunctionType = d->functionType(true);\n\t\t\t\treturn newFunctionType && functionType->hasEqualParameterTypes(*newFunctionType);\n\t\t\t}\n\t\t))\n\t\t\tuniqueDeclarations.push_back(declaration);\n\t}\n\treturn uniqueDeclarations;\n}\n\nbool TypeChecker::visit(Identifier const& _identifier)\n{\n\tIdentifierAnnotation& annotation = _identifier.annotation();\n\n\tif (!annotation.referencedDeclaration)\n\t{\n\t\tannotation.overloadedDeclarations = cleanOverloadedDeclarations(_identifier, annotation.candidateDeclarations);\n\t\tif (annotation.overloadedDeclarations.empty())\n\t\t\tm_errorReporter.fatalTypeError(7593_error, _identifier.location(), \"No candidates for overload resolution found.\");\n\t\telse if (annotation.overloadedDeclarations.size() == 1)\n\t\t\tannotation.referencedDeclaration = *annotation.overloadedDeclarations.begin();\n\t\telse if (!annotation.arguments)\n\t\t{\n\t\t\t// The identifier should be a public state variable shadowing other functions\n\t\t\tstd::vector<Declaration const*> candidates;\n\n\t\t\tfor (Declaration const* declaration: annotation.overloadedDeclarations)\n\t\t\t{\n\t\t\t\tif (VariableDeclaration const* variableDeclaration = dynamic_cast<decltype(variableDeclaration)>(declaration))\n\t\t\t\t\tcandidates.push_back(declaration);\n\t\t\t}\n\t\t\tif (candidates.empty())\n\t\t\t\tm_errorReporter.fatalTypeError(2144_error, _identifier.location(), \"No matching declaration found after variable lookup.\");\n\t\t\telse if (candidates.size() == 1)\n\t\t\t\tannotation.referencedDeclaration = candidates.front();\n\t\t\telse\n\t\t\t\tm_errorReporter.fatalTypeError(7589_error, _identifier.location(), \"No unique declaration found after variable lookup.\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstd::vector<Declaration const*> candidates;\n\n\t\t\tfor (Declaration const* declaration: annotation.overloadedDeclarations)\n\t\t\t{\n\t\t\t\tFunctionTypePointer functionType = declaration->functionType(true);\n\t\t\t\tsolAssert(!!functionType, \"Requested type not present.\");\n\t\t\t\tif (functionType->canTakeArguments(*annotation.arguments))\n\t\t\t\t\tcandidates.push_back(declaration);\n\t\t\t}\n\t\t\tif (candidates.size() == 1)\n\t\t\t\tannotation.referencedDeclaration = candidates.front();\n\t\t\telse\n\t\t\t{\n\t\t\t\tSecondarySourceLocation ssl;\n\n\t\t\t\tfor (Declaration const* declaration: annotation.overloadedDeclarations)\n\t\t\t\t\tif (!declaration->location().isValid())\n\t\t\t\t\t{\n\t\t\t\t\t\t// Try to re-construct function definition\n\t\t\t\t\t\tstd::string description;\n\t\t\t\t\t\tfor (auto const& param: declaration->functionType(true)->parameterTypes())\n\t\t\t\t\t\t\tdescription += (description.empty() ? \"\" : \", \") + param->humanReadableName();\n\t\t\t\t\t\tdescription = \"function \" + _identifier.name() + \"(\" + description + \")\";\n\n\t\t\t\t\t\tssl.append(\"Candidate: \" + description, declaration->location());\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tssl.append(\"Candidate:\", declaration->location());\n\t\t\t\tif (candidates.empty())\n\t\t\t\t\tm_errorReporter.fatalTypeError(9322_error, _identifier.location(), ssl, \"No matching declaration found after argument-dependent lookup.\");\n\t\t\t\telse\n\t\t\t\t\tm_errorReporter.fatalTypeError(4487_error, _identifier.location(), ssl, \"No unique declaration found after argument-dependent lookup.\");\n\t\t\t}\n\t\t}\n\t}\n\tsolAssert(\n\t\t!!annotation.referencedDeclaration,\n\t\t\"Referenced declaration is null after overload resolution.\"\n\t);\n\tbool isConstant = false;\n\tannotation.isLValue = annotation.referencedDeclaration->isLValue();\n\tannotation.type = annotation.referencedDeclaration->type();\n\tsolAssert(annotation.type, \"Declaration referenced before type could be determined.\");\n\tif (auto variableDeclaration = dynamic_cast<VariableDeclaration const*>(annotation.referencedDeclaration))\n\t\tannotation.isPure = isConstant = variableDeclaration->isConstant();\n\telse if (dynamic_cast<MagicVariableDeclaration const*>(annotation.referencedDeclaration))\n\t\tannotation.isPure = dynamic_cast<FunctionType const*>(annotation.type);\n\telse if (dynamic_cast<TypeType const*>(annotation.type))\n\t\tannotation.isPure = true;\n\telse if (dynamic_cast<ModuleType const*>(annotation.type))\n\t\tannotation.isPure = true;\n\telse\n\t\tannotation.isPure = false;\n\n\tannotation.isConstant = isConstant;\n\n\tannotation.requiredLookup =\n\t\tdynamic_cast<CallableDeclaration const*>(annotation.referencedDeclaration) ?\n\t\tVirtualLookup::Virtual : VirtualLookup::Static;\n\n\t// Check for deprecated function names.\n\t// The check is done here for the case without an actual function call.\n\tif (FunctionType const* fType = dynamic_cast<FunctionType const*>(_identifier.annotation().type))\n\t{\n\t\tif (_identifier.name() == \"sha3\" && fType->kind() == FunctionType::Kind::KECCAK256)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t3557_error,\n\t\t\t\t_identifier.location(),\n\t\t\t\t\"\\\"sha3\\\" has been deprecated in favour of \\\"keccak256\\\".\"\n\t\t\t);\n\t\telse if (_identifier.name() == \"suicide\" && fType->kind() == FunctionType::Kind::Selfdestruct)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t8050_error,\n\t\t\t\t_identifier.location(),\n\t\t\t\t\"\\\"suicide\\\" has been deprecated in favour of \\\"selfdestruct\\\".\"\n\t\t\t);\n\t\telse if (_identifier.name() == \"selfdestruct\" && fType->kind() == FunctionType::Kind::Selfdestruct)\n\t\t\tm_errorReporter.warning(\n\t\t\t\t5159_error,\n\t\t\t\t_identifier.location(),\n\t\t\t\t\"\\\"selfdestruct\\\" has been deprecated. \"\n\t\t\t\t\"Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and \"\n\t\t\t\t\"data associated with an account and only transfers its Ether to the beneficiary, \"\n\t\t\t\t\"unless executed in the same transaction in which the contract was created (see EIP-6780). \"\n\t\t\t\t\"Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. \"\n\t\t\t\t\"Future changes to the EVM might further reduce the functionality of the opcode.\"\n\t\t\t);\n\t}\n\n\tif (\n\t\tMagicVariableDeclaration const* magicVar =\n\t\tdynamic_cast<MagicVariableDeclaration const*>(annotation.referencedDeclaration)\n\t)\n\t\tif (magicVar->type()->category() == Type::Category::Integer)\n\t\t{\n\t\t\tsolAssert(_identifier.name() == \"now\", \"\");\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t7359_error,\n\t\t\t\t_identifier.location(),\n\t\t\t\t\"\\\"now\\\" has been deprecated. Use \\\"block.timestamp\\\" instead.\"\n\t\t\t);\n\t\t}\n\n\treturn false;\n}\n\nvoid TypeChecker::endVisit(IdentifierPath const& _identifierPath)\n{\n\tif (\n\t\tdynamic_cast<CallableDeclaration const*>(_identifierPath.annotation().referencedDeclaration) &&\n\t\t_identifierPath.path().size() == 1\n\t)\n\t\t_identifierPath.annotation().requiredLookup = VirtualLookup::Virtual;\n\telse\n\t\t_identifierPath.annotation().requiredLookup = VirtualLookup::Static;\n}\n\nvoid TypeChecker::endVisit(UserDefinedTypeName const& _userDefinedTypeName)\n{\n\tif (!_userDefinedTypeName.annotation().type)\n\t\t_userDefinedTypeName.annotation().type = _userDefinedTypeName.pathNode().annotation().referencedDeclaration->type();\n}\n\nvoid TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr)\n{\n\t_expr.annotation().type = TypeProvider::typeType(TypeProvider::fromElementaryTypeName(_expr.type().typeName(), _expr.type().stateMutability()));\n\t_expr.annotation().isPure = true;\n\t_expr.annotation().isLValue = false;\n\t_expr.annotation().isConstant = false;\n}\n\nvoid TypeChecker::endVisit(Literal const& _literal)\n{\n\tif (_literal.looksLikeAddress())\n\t{\n\t\t// Assign type here if it even looks like an address. This prevents double errors for invalid addresses\n\t\t_literal.annotation().type = TypeProvider::address();\n\n\t\tstd::string msg;\n\t\tif (_literal.valueWithoutUnderscores().length() != 42) // \"0x\" + 40 hex digits\n\t\t\t// looksLikeAddress enforces that it is a hex literal starting with \"0x\"\n\t\t\tmsg =\n\t\t\t\t\"This looks like an address but is not exactly 40 hex digits. It is \" +\n\t\t\t\tstd::to_string(_literal.valueWithoutUnderscores().length() - 2) +\n\t\t\t\t\" hex digits.\";\n\t\telse if (!_literal.passesAddressChecksum())\n\t\t{\n\t\t\tmsg = \"This looks like an address but has an invalid checksum.\";\n\t\t\tif (!_literal.getChecksummedAddress().empty())\n\t\t\t\tmsg += \" Correct checksummed address: \\\"\" + _literal.getChecksummedAddress() + \"\\\".\";\n\t\t}\n\n\t\tif (!msg.empty())\n\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t9429_error,\n\t\t\t\t_literal.location(),\n\t\t\t\tmsg +\n\t\t\t\t\" If this is not used as an address, please prepend '00'. \" +\n\t\t\t\t\"For more information please see https://docs.soliditylang.org/en/develop/types.html#address-literals\"\n\t\t\t);\n\t}\n\n\tif (_literal.isHexNumber() && _literal.subDenomination() != Literal::SubDenomination::None)\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t5145_error,\n\t\t\t_literal.location(),\n\t\t\t\"Hexadecimal numbers cannot be used with unit denominations. \"\n\t\t\t\"You can use an expression of the form \\\"0x1234 * 1 days\\\" instead.\"\n\t\t);\n\n\tif (_literal.subDenomination() == Literal::SubDenomination::Year)\n\t\tm_errorReporter.typeError(\n\t\t\t4820_error,\n\t\t\t_literal.location(),\n\t\t\t\"Using \\\"years\\\" as a unit denomination is deprecated.\"\n\t\t);\n\n\tif (!_literal.annotation().type)\n\t\t_literal.annotation().type = TypeProvider::forLiteral(_literal);\n\n\tif (!_literal.annotation().type)\n\t\tm_errorReporter.fatalTypeError(2826_error, _literal.location(), \"Invalid literal value.\");\n\n\t_literal.annotation().isPure = true;\n\t_literal.annotation().isLValue = false;\n\t_literal.annotation().isConstant = false;\n}\n\nvoid TypeChecker::endVisit(UsingForDirective const& _usingFor)\n{\n\tif (_usingFor.global())\n\t{\n\t\tif (m_currentContract || !_usingFor.typeName())\n\t\t{\n\t\t\tsolAssert(m_errorReporter.hasErrors());\n\t\t\treturn;\n\t\t}\n\t\tType const* usingForType = _usingFor.typeName()->annotation().type;\n\t\tsolAssert(usingForType);\n\t\tif (Declaration const* typeDefinition = usingForType->typeDefinition())\n\t\t{\n\t\t\tif (typeDefinition->scope() != m_currentSourceUnit)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t4117_error,\n\t\t\t\t\t_usingFor.location(),\n\t\t\t\t\t\"Can only use \\\"global\\\" with types defined in the same source unit at file level.\"\n\t\t\t\t);\n\t\t}\n\t\telse\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t8841_error,\n\t\t\t\t_usingFor.location(),\n\t\t\t\t\"Can only use \\\"global\\\" with user-defined types.\"\n\t\t\t);\n\t}\n\n\tif (!_usingFor.usesBraces())\n\t{\n\t\tsolAssert(_usingFor.functionsOrLibrary().size() == 1);\n\t\tContractDefinition const* library = dynamic_cast<ContractDefinition const*>(\n\t\t\t_usingFor.functionsOrLibrary().front()->annotation().referencedDeclaration\n\t\t);\n\t\tsolAssert(library && library->isLibrary());\n\t\t// No type checking for libraries\n\t\treturn;\n\t}\n\n\tif (!_usingFor.typeName())\n\t{\n\t\tsolAssert(m_errorReporter.hasErrors());\n\t\treturn;\n\t}\n\n\tType const* usingForType = _usingFor.typeName()->annotation().type;\n\tsolAssert(usingForType);\n\n\tType const* normalizedType = TypeProvider::withLocationIfReference(\n\t\tDataLocation::Storage,\n\t\tusingForType\n\t);\n\tsolAssert(normalizedType);\n\n\tfor (auto const& [path, operator_]: _usingFor.functionsAndOperators())\n\t{\n\t\tsolAssert(path->annotation().referencedDeclaration);\n\t\tFunctionDefinition const& functionDefinition =\n\t\t\tdynamic_cast<FunctionDefinition const&>(*path->annotation().referencedDeclaration);\n\n\t\tFunctionType const* functionType = dynamic_cast<FunctionType const*>(\n\t\t\tfunctionDefinition.libraryFunction() ?\n\t\t\t\tfunctionDefinition.typeViaContractName() :\n\t\t\t\tfunctionDefinition.type()\n\t\t\t);\n\n\t\tsolAssert(functionType);\n\n\t\tif (functionDefinition.parameters().empty())\n\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t4731_error,\n\t\t\t\tpath->location(),\n\t\t\t\tSecondarySourceLocation().append(\n\t\t\t\t\t\"Function defined here:\",\n\t\t\t\t\tfunctionDefinition.location()\n\t\t\t\t),\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"The function \\\"{}\\\" does not have any parameters, and therefore cannot be attached to the type \\\"{}\\\".\",\n\t\t\t\t\tjoinHumanReadable(path->path(), \".\"),\n\t\t\t\t\tnormalizedType ? normalizedType->toString(true /* withoutDataLocation */) : \"*\"\n\t\t\t\t)\n\t\t\t);\n\n\t\tif (\n\t\t\tfunctionDefinition.visibility() == Visibility::Private &&\n\t\t\tfunctionDefinition.scope() != m_currentContract\n\t\t)\n\t\t{\n\t\t\tsolAssert(functionDefinition.libraryFunction());\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t6772_error,\n\t\t\t\tpath->location(),\n\t\t\t\tSecondarySourceLocation().append(\n\t\t\t\t\t\"Function defined here:\",\n\t\t\t\t\tfunctionDefinition.location()\n\t\t\t\t),\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"Function \\\"{}\\\" is private and therefore cannot be attached\"\n\t\t\t\t\t\" to a type outside of the library where it is defined.\",\n\t\t\t\t\tjoinHumanReadable(path->path(), \".\")\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tFunctionType const* functionTypeWithBoundFirstArgument = functionType->withBoundFirstArgument();\n\t\tsolAssert(functionTypeWithBoundFirstArgument && functionTypeWithBoundFirstArgument->selfType(), \"\");\n\t\tBoolResult result = normalizedType->isImplicitlyConvertibleTo(\n\t\t\t*TypeProvider::withLocationIfReference(DataLocation::Storage, functionTypeWithBoundFirstArgument->selfType())\n\t\t);\n\t\tif (!result && !operator_)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t3100_error,\n\t\t\t\tpath->location(),\n\t\t\t\tSecondarySourceLocation().append(\n\t\t\t\t\t\"Function defined here:\",\n\t\t\t\t\tfunctionDefinition.location()\n\t\t\t\t),\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"The function \\\"{}\\\" cannot be attached to the type \\\"{}\\\" because the type cannot \"\n\t\t\t\t\t\"be implicitly converted to the first argument of the function (\\\"{}\\\"){}\",\n\t\t\t\t\tjoinHumanReadable(path->path(), \".\"),\n\t\t\t\t\tusingForType->toString(true /* withoutDataLocation */),\n\t\t\t\t\tfunctionTypeWithBoundFirstArgument->selfType()->humanReadableName(),\n\t\t\t\t\tresult.message().empty() ? \".\" : \": \" +  result.message()\n\t\t\t\t)\n\t\t\t);\n\t\telse if (operator_.has_value())\n\t\t{\n\t\t\tif (!_usingFor.global())\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t3320_error,\n\t\t\t\t\tpath->location(),\n\t\t\t\t\t\"Operators can only be defined in a global 'using for' directive.\"\n\t\t\t\t);\n\n\t\t\tif (\n\t\t\t\tfunctionType->stateMutability() != StateMutability::Pure ||\n\t\t\t\t!functionDefinition.isFree()\n\t\t\t)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t7775_error,\n\t\t\t\t\tpath->location(),\n\t\t\t\t\tSecondarySourceLocation().append(\n\t\t\t\t\t\t\"Function defined as non-pure here:\",\n\t\t\t\t\t\tfunctionDefinition.location()\n\t\t\t\t\t),\n\t\t\t\t\t\"Only pure free functions can be used to define operators.\"\n\t\t\t\t);\n\n\t\t\tsolAssert(!functionType->hasBoundFirstArgument());\n\t\t\tTypePointers const& parameterTypes = functionType->parameterTypes();\n\t\t\tsize_t const parameterCount = parameterTypes.size();\n\t\t\tif (usingForType->category() != Type::Category::UserDefinedValueType)\n\t\t\t{\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t5332_error,\n\t\t\t\t\tpath->location(),\n\t\t\t\t\t\"Operators can only be implemented for user-defined value types.\"\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tsolAssert(usingForType->typeDefinition());\n\n\t\t\tbool identicalFirstTwoParameters = (parameterCount < 2 || *parameterTypes.at(0) == *parameterTypes.at(1));\n\t\t\tbool isUnaryOnlyOperator = (!TokenTraits::isBinaryOp(operator_.value()) && TokenTraits::isUnaryOp(operator_.value()));\n\t\t\tbool isBinaryOnlyOperator = (TokenTraits::isBinaryOp(operator_.value()) && !TokenTraits::isUnaryOp(operator_.value()));\n\t\t\tbool firstParameterMatchesUsingFor = parameterCount == 0 || *usingForType == *parameterTypes.front();\n\n\t\t\tstd::optional<std::string> wrongParametersMessage;\n\t\t\tif (isBinaryOnlyOperator && (parameterCount != 2 || !identicalFirstTwoParameters))\n\t\t\t\twrongParametersMessage = fmt::format(\"two parameters of type {} and the same data location\", usingForType->canonicalName());\n\t\t\telse if (isUnaryOnlyOperator && (parameterCount != 1 || !firstParameterMatchesUsingFor))\n\t\t\t\twrongParametersMessage = fmt::format(\"exactly one parameter of type {}\", usingForType->canonicalName());\n\t\t\telse if (parameterCount >= 3 || !firstParameterMatchesUsingFor || !identicalFirstTwoParameters)\n\t\t\t\twrongParametersMessage = fmt::format(\"one or two parameters of type {} and the same data location\", usingForType->canonicalName());\n\n\t\t\tif (wrongParametersMessage.has_value())\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t1884_error,\n\t\t\t\t\tfunctionDefinition.parameterList().location(),\n\t\t\t\t\tSecondarySourceLocation().append(\n\t\t\t\t\t\t\"Function was used to implement an operator here:\",\n\t\t\t\t\t\tpath->location()\n\t\t\t\t\t),\n\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\"Wrong parameters in operator definition. \"\n\t\t\t\t\t\t\"The function \\\"{}\\\" needs to have {} to be used for the operator {}.\",\n\t\t\t\t\t\tjoinHumanReadable(path->path(), \".\"),\n\t\t\t\t\t\twrongParametersMessage.value(),\n\t\t\t\t\t\tTokenTraits::friendlyName(operator_.value())\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\t// This case is separately validated for all attached functions and is a fatal error\n\t\t\tsolAssert(parameterCount != 0);\n\n\t\t\tTypePointers const& returnParameterTypes = functionType->returnParameterTypes();\n\t\t\tsize_t const returnParameterCount = returnParameterTypes.size();\n\n\t\t\tstd::optional<std::string> wrongReturnParametersMessage;\n\t\t\tif (!TokenTraits::isCompareOp(operator_.value()) && operator_.value() != Token::Not)\n\t\t\t{\n\t\t\t\tif (returnParameterCount != 1 || *usingForType != *returnParameterTypes.front())\n\t\t\t\t\twrongReturnParametersMessage = \"exactly one value of type \" + usingForType->canonicalName();\n\t\t\t\telse if (*returnParameterTypes.front() != *parameterTypes.front())\n\t\t\t\t\twrongReturnParametersMessage = \"a value of the same type and data location as its parameters\";\n\t\t\t}\n\t\t\telse if (returnParameterCount != 1 || *returnParameterTypes.front() != *TypeProvider::boolean())\n\t\t\t\twrongReturnParametersMessage = \"exactly one value of type bool\";\n\n\t\t\tsolAssert(functionDefinition.returnParameterList());\n\t\t\tif (wrongReturnParametersMessage.has_value())\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t7743_error,\n\t\t\t\t\tfunctionDefinition.returnParameterList()->location(),\n\t\t\t\t\tSecondarySourceLocation().append(\n\t\t\t\t\t\t\"Function was used to implement an operator here:\",\n\t\t\t\t\t\tpath->location()\n\t\t\t\t\t),\n\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\"Wrong return parameters in operator definition. \"\n\t\t\t\t\t\t\"The function \\\"{}\\\" needs to return {} to be used for the operator {}.\",\n\t\t\t\t\t\tjoinHumanReadable(path->path(), \".\"),\n\t\t\t\t\t\twrongReturnParametersMessage.value(),\n\t\t\t\t\t\tTokenTraits::friendlyName(operator_.value())\n\t\t\t\t\t)\n\t\t\t\t);\n\n\t\t\tif (parameterCount != 1 && parameterCount != 2)\n\t\t\t\tsolAssert(m_errorReporter.hasErrors());\n\t\t\telse\n\t\t\t{\n\t\t\t\t// TODO: This is pretty inefficient. For every operator binding we find, we're\n\t\t\t\t// traversing all bindings in all `using for` directives in the current scope.\n\t\t\t\tstd::set<FunctionDefinition const*, ASTNode::CompareByID> matchingDefinitions = usingForType->operatorDefinitions(\n\t\t\t\t\toperator_.value(),\n\t\t\t\t\t*currentDefinitionScope(),\n\t\t\t\t\tparameterCount == 1 // _unary\n\t\t\t\t);\n\n\t\t\t\tif (matchingDefinitions.size() >= 2)\n\t\t\t\t{\n\t\t\t\t\t// TODO: We should point at other places that bind the operator rather than at\n\t\t\t\t\t// the definitions they bind.\n\t\t\t\t\tSecondarySourceLocation secondaryLocation;\n\t\t\t\t\tfor (FunctionDefinition const* definition: matchingDefinitions)\n\t\t\t\t\t\tif (functionDefinition != *definition)\n\t\t\t\t\t\tsecondaryLocation.append(\"Conflicting definition:\", definition->location());\n\n\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t4705_error,\n\t\t\t\t\t\tpath->location(),\n\t\t\t\t\t\tsecondaryLocation,\n\t\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\t\"User-defined {} operator {} has more than one definition matching the operand type visible in the current scope.\",\n\t\t\t\t\t\t\tparameterCount == 1 ? \"unary\" : \"binary\",\n\t\t\t\t\t\t\tTokenTraits::friendlyName(operator_.value())\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid TypeChecker::checkErrorAndEventParameters(CallableDeclaration const& _callable)\n{\n\tstd::string kind = dynamic_cast<EventDefinition const*>(&_callable) ? \"event\" : \"error\";\n\tfor (ASTPointer<VariableDeclaration> const& var: _callable.parameters())\n\t{\n\t\tif (type(*var)->containsNestedMapping())\n\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t3448_error,\n\t\t\t\tvar->location(),\n\t\t\t\t\"Type containing a (nested) mapping is not allowed as \" + kind + \" parameter type.\"\n\t\t\t);\n\t\tif (!type(*var)->interfaceType(false))\n\t\t\tm_errorReporter.typeError(3417_error, var->location(), \"Internal or recursive type is not allowed as \" + kind + \" parameter type.\");\n\t\tif (\n\t\t\t!useABICoderV2() &&\n\t\t\t!typeSupportedByOldABIEncoder(*type(*var), false /* isLibrary */)\n\t\t)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t3061_error,\n\t\t\t\tvar->location(),\n\t\t\t\t\"This type is only supported in ABI coder v2. \"\n\t\t\t\t\"Use \\\"pragma abicoder v2;\\\" to enable the feature.\"\n\t\t\t);\n\t}\n}\n\nDeclaration const& TypeChecker::dereference(Identifier const& _identifier) const\n{\n\tsolAssert(!!_identifier.annotation().referencedDeclaration, \"Declaration not stored.\");\n\treturn *_identifier.annotation().referencedDeclaration;\n}\n\nDeclaration const& TypeChecker::dereference(IdentifierPath const& _path) const\n{\n\tsolAssert(!!_path.annotation().referencedDeclaration, \"Declaration not stored.\");\n\treturn *_path.annotation().referencedDeclaration;\n}\n\nbool TypeChecker::expectType(Expression const& _expression, Type const& _expectedType)\n{\n\t_expression.accept(*this);\n\tBoolResult result = type(_expression)->isImplicitlyConvertibleTo(_expectedType);\n\tif (!result)\n\t{\n\t\tauto errorMsg = \"Type \" +\n\t\t\ttype(_expression)->humanReadableName() +\n\t\t\t\" is not implicitly convertible to expected type \" +\n\t\t\t_expectedType.humanReadableName();\n\t\tif (\n\t\t\ttype(_expression)->category() == Type::Category::RationalNumber &&\n\t\t\tdynamic_cast<RationalNumberType const*>(type(_expression))->isFractional() &&\n\t\t\ttype(_expression)->mobileType()\n\t\t)\n\t\t{\n\t\t\tif (_expectedType.operator==(*type(_expression)->mobileType()))\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t4426_error,\n\t\t\t\t\t_expression.location(),\n\t\t\t\t\terrorMsg + \", but it can be explicitly converted.\"\n\t\t\t\t);\n\t\t\telse\n\t\t\t\tm_errorReporter.typeErrorConcatenateDescriptions(\n\t\t\t\t\t2326_error,\n\t\t\t\t\t_expression.location(),\n\t\t\t\t\terrorMsg +\n\t\t\t\t\t\". Try converting to type \" +\n\t\t\t\t\ttype(_expression)->mobileType()->humanReadableName() +\n\t\t\t\t\t\" or use an explicit conversion.\",\n\t\t\t\t\tresult.message()\n\t\t\t\t);\n\t\t}\n\t\telse\n\t\t\tm_errorReporter.typeErrorConcatenateDescriptions(\n\t\t\t\t7407_error,\n\t\t\t\t_expression.location(),\n\t\t\t\terrorMsg + \".\",\n\t\t\t\tresult.message()\n\t\t\t);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nvoid TypeChecker::requireLValue(Expression const& _expression)\n{\n\t_expression.annotation().willBeWrittenTo = true;\n\t_expression.accept(*this);\n\n\tif (*_expression.annotation().isLValue)\n\t\treturn;\n\n\tauto [errorId, description] = [&]() -> std::tuple<ErrorId, std::string> {\n\t\tif (*_expression.annotation().isConstant)\n\t\t\treturn { 6520_error, \"Cannot assign to a constant variable.\" };\n\n\t\tif (auto indexAccess = dynamic_cast<IndexAccess const*>(&_expression))\n\t\t{\n\t\t\tif (type(indexAccess->baseExpression())->category() == Type::Category::FixedBytes)\n\t\t\t\treturn { 4360_error, \"Single bytes in fixed bytes arrays cannot be modified.\" };\n\t\t\telse if (auto arrayType = dynamic_cast<ArrayType const*>(type(indexAccess->baseExpression())))\n\t\t\t\tif (arrayType->dataStoredIn(DataLocation::CallData))\n\t\t\t\t\treturn { 6182_error, \"Calldata arrays are read-only.\" };\n\t\t}\n\n\t\tif (auto memberAccess = dynamic_cast<MemberAccess const*>(&_expression))\n\t\t{\n\t\t\tif (auto structType = dynamic_cast<StructType const*>(type(memberAccess->expression())))\n\t\t\t{\n\t\t\t\tif (structType->dataStoredIn(DataLocation::CallData))\n\t\t\t\t\treturn { 4156_error, \"Calldata structs are read-only.\" };\n\t\t\t}\n\t\t\telse if (dynamic_cast<ArrayType const*>(type(memberAccess->expression())))\n\t\t\t\tif (memberAccess->memberName() == \"length\")\n\t\t\t\t\treturn { 7567_error, \"Member \\\"length\\\" is read-only and cannot be used to resize arrays.\" };\n\t\t}\n\n\t\tif (auto identifier = dynamic_cast<Identifier const*>(&_expression))\n\t\t\tif (auto varDecl = dynamic_cast<VariableDeclaration const*>(identifier->annotation().referencedDeclaration))\n\t\t\t\tif (varDecl->isExternalCallableParameter() && dynamic_cast<ReferenceType const*>(identifier->annotation().type))\n\t\t\t\t\treturn { 7128_error, \"External function arguments of reference type are read-only.\" };\n\n\t\treturn { 4247_error, \"Expression has to be an lvalue.\" };\n\t}();\n\n\tm_errorReporter.typeError(errorId, _expression.location(), description);\n}\n\nbool TypeChecker::useABICoderV2() const\n{\n\tsolAssert(m_currentSourceUnit, \"\");\n\tif (m_currentContract)\n\t\tsolAssert(m_currentSourceUnit == &m_currentContract->sourceUnit(), \"\");\n\treturn *m_currentSourceUnit->annotation().useABICoderV2;\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/TypeChecker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Type analyzer and checker.\n */\n\n#pragma once\n\n#include <liblangutil/EVMVersion.h>\n\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/ast/Types.h>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend\n{\n\n/**\n * The module that performs type analysis on the AST, checks the applicability of operations on\n * those types and stores errors for invalid operations.\n * Provides a way to retrieve the type of an AST node.\n */\nclass TypeChecker: private ASTConstVisitor\n{\npublic:\n\t/// @param _errorReporter provides the error logging functionality.\n\tTypeChecker(langutil::EVMVersion _evmVersion, std::optional<uint8_t> _eofVersion, langutil::ErrorReporter& _errorReporter):\n\t\tm_evmVersion(_evmVersion),\n\t\tm_eofVersion(_eofVersion),\n\t\tm_errorReporter(_errorReporter)\n\t{}\n\n\t/// Performs type checking on the given source and all of its sub-nodes.\n\t/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings\n\tbool checkTypeRequirements(SourceUnit const& _source);\n\n\tstatic bool typeSupportedByOldABIEncoder(Type const& _type, bool _isLibraryCall);\n\nprivate:\n\n\tbool visit(ContractDefinition const& _contract) override;\n\t// Checks whether the expression @arg _expression can be assigned from type @arg _type\n\t// and reports an error, if not.\n\tvoid checkExpressionAssignment(Type const& _type, Expression const& _expression);\n\n\t/// Performs type checks for ``abi.decode(bytes memory, (...))`` and returns the\n\t/// vector of return types (which is basically the second argument) if successful. It returns\n\t/// the empty vector on error.\n\tTypePointers typeCheckABIDecodeAndRetrieveReturnType(\n\t\tFunctionCall const& _functionCall,\n\t\tbool _abiEncoderV2\n\t);\n\n\tTypePointers typeCheckMetaTypeFunctionAndRetrieveReturnType(FunctionCall const& _functionCall);\n\n\t/// Performs type checks and determines result types for type conversion FunctionCall nodes.\n\tType const* typeCheckTypeConversionAndRetrieveReturnType(\n\t\tFunctionCall const& _functionCall\n\t);\n\n\t/// Performs type checks on function call and struct ctor FunctionCall nodes (except for kind ABIDecode).\n\tvoid typeCheckFunctionCall(\n\t\tFunctionCall const& _functionCall,\n\t\tFunctionTypePointer _functionType\n\t);\n\n\tvoid typeCheckFallbackFunction(FunctionDefinition const& _function);\n\tvoid typeCheckConstructor(FunctionDefinition const& _function);\n\n\t/// Performs general number and type checks of arguments against function call and struct ctor FunctionCall node parameters.\n\tvoid typeCheckFunctionGeneralChecks(\n\t\tFunctionCall const& _functionCall,\n\t\tFunctionTypePointer _functionType\n\t);\n\n\t/// Performs general checks and checks specific to ABI encode functions\n\tvoid typeCheckABIEncodeFunctions(\n\t\tFunctionCall const& _functionCall,\n\t\tFunctionTypePointer _functionType\n\t);\n\n\t/// Performs checks specific to the ABI encode functions of type ABIEncodeCall\n\tvoid typeCheckABIEncodeCallFunction(FunctionCall const& _functionCall);\n\n\t/// Performs general checks and checks specific to string concat function call\n\tvoid typeCheckStringConcatFunction(\n\t\tFunctionCall const& _functionCall,\n\t\tFunctionType const* _functionType\n\t);\n\n\t/// Performs general checks and checks specific to bytes concat function call\n\tvoid typeCheckBytesConcatFunction(\n\t\tFunctionCall const& _functionCall,\n\t\tFunctionType const* _functionType\n\t);\n\n\tvoid typeCheckERC7201Builtin(FunctionCall const& _functionCall, FunctionType const* _functionType);\n\n\tbool visit(ImportDirective const&) override;\n\n\tvoid endVisit(InheritanceSpecifier const& _inheritance) override;\n\tvoid endVisit(ModifierDefinition const& _modifier) override;\n\tbool visit(FunctionDefinition const& _function) override;\n\tvoid endVisit(ArrayTypeName const& _typeName) override;\n\tbool visit(VariableDeclaration const& _variable) override;\n\tvoid endVisit(StructDefinition const& _struct) override;\n\t/// We need to do this manually because we want to pass the bases of the current contract in\n\t/// case this is a base constructor call.\n\tvoid visitManually(ModifierInvocation const& _modifier, std::vector<ContractDefinition const*> const& _bases);\n\tbool visit(EventDefinition const& _eventDef) override;\n\tbool visit(ErrorDefinition const& _errorDef) override;\n\tvoid endVisit(FunctionTypeName const& _funType) override;\n\tbool visit(InlineAssembly const& _inlineAssembly) override;\n\tbool visit(IfStatement const& _ifStatement) override;\n\tvoid endVisit(TryStatement const& _tryStatement) override;\n\tbool visit(WhileStatement const& _whileStatement) override;\n\tbool visit(ForStatement const& _forStatement) override;\n\tvoid endVisit(Return const& _return) override;\n\tvoid endVisit(EmitStatement const& _emit) override;\n\tvoid endVisit(RevertStatement const& _revert) override;\n\tbool visit(VariableDeclarationStatement const& _variable) override;\n\tvoid endVisit(ExpressionStatement const& _statement) override;\n\tbool visit(Conditional const& _conditional) override;\n\tbool visit(Assignment const& _assignment) override;\n\tbool visit(TupleExpression const& _tuple) override;\n\tvoid endVisit(BinaryOperation const& _operation) override;\n\tbool visit(UnaryOperation const& _operation) override;\n\tbool visit(FunctionCall const& _functionCall) override;\n\tbool visit(FunctionCallOptions const& _functionCallOptions) override;\n\tvoid endVisit(NewExpression const& _newExpression) override;\n\tbool visit(MemberAccess const& _memberAccess) override;\n\tbool visit(IndexAccess const& _indexAccess) override;\n\tbool visit(IndexRangeAccess const& _indexRangeAccess) override;\n\tbool visit(Identifier const& _identifier) override;\n\tvoid endVisit(IdentifierPath const& _identifierPath) override;\n\tvoid endVisit(UserDefinedTypeName const& _userDefinedTypeName) override;\n\tvoid endVisit(ElementaryTypeNameExpression const& _expr) override;\n\tvoid endVisit(Literal const& _literal) override;\n\tvoid endVisit(UsingForDirective const& _usingForDirective) override;\n\n\tvoid checkErrorAndEventParameters(CallableDeclaration const& _callable);\n\n\t/// @returns the referenced declaration and throws on error.\n\tDeclaration const& dereference(Identifier const& _identifier) const;\n\t/// @returns the referenced declaration and throws on error.\n\tDeclaration const& dereference(IdentifierPath const& _path) const;\n\n\tstd::vector<Declaration const*> cleanOverloadedDeclarations(\n\t\tIdentifier const& _reference,\n\t\tstd::vector<Declaration const*> const& _candidates\n\t);\n\n\t/// Runs type checks on @a _expression to infer its type and then checks that it is implicitly\n\t/// convertible to @a _expectedType.\n\tbool expectType(Expression const& _expression, Type const& _expectedType);\n\t/// Runs type checks on @a _expression to infer its type and then checks that it is an LValue.\n\tvoid requireLValue(Expression const& _expression);\n\n\tbool useABICoderV2() const;\n\n\t/// @returns the current scope that can have function or type definitions.\n\t/// This is either a contract or a source unit.\n\tASTNode const* currentDefinitionScope() const\n\t{\n\t\tif (m_currentContract)\n\t\t\treturn m_currentContract;\n\t\telse\n\t\t\treturn m_currentSourceUnit;\n\t}\n\n\tSourceUnit const* m_currentSourceUnit = nullptr;\n\tContractDefinition const* m_currentContract = nullptr;\n\n\tlangutil::EVMVersion m_evmVersion;\n\tstd::optional<uint8_t> m_eofVersion;\n\n\tlangutil::ErrorReporter& m_errorReporter;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/analysis/ViewPureChecker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/ViewPureChecker.h>\n#include <libsolidity/ast/ExperimentalFeatures.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n#include <liblangutil/ErrorReporter.h>\n#include <libevmasm/SemanticInformation.h>\n\n#include <functional>\n#include <utility>\n#include <variant>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nnamespace\n{\n\nclass AssemblyViewPureChecker\n{\npublic:\n\texplicit AssemblyViewPureChecker(\n\t\tyul::Dialect const& _dialect,\n\t\tstd::function<void(StateMutability, SourceLocation const&)> _reportMutability\n\t):\n\t\tm_dialect(_dialect),\n\t\tm_reportMutability(std::move(_reportMutability)) {}\n\n\tvoid operator()(yul::Literal const&) {}\n\tvoid operator()(yul::Identifier const&) {}\n\tvoid operator()(yul::ExpressionStatement const& _expr)\n\t{\n\t\tstd::visit(*this, _expr.expression);\n\t}\n\tvoid operator()(yul::Assignment const& _assignment)\n\t{\n\t\tstd::visit(*this, *_assignment.value);\n\t}\n\tvoid operator()(yul::VariableDeclaration const& _varDecl)\n\t{\n\t\tif (_varDecl.value)\n\t\t\tstd::visit(*this, *_varDecl.value);\n\t}\n\tvoid operator()(yul::FunctionDefinition const& _funDef)\n\t{\n\t\t(*this)(_funDef.body);\n\t}\n\tvoid operator()(yul::FunctionCall const& _funCall)\n\t{\n\t\tif (yul::EVMDialect const* dialect = dynamic_cast<decltype(dialect)>(&m_dialect))\n\t\t\tif (yul::BuiltinFunctionForEVM const* builtin = resolveBuiltinFunctionForEVM(_funCall.functionName, *dialect))\n\t\t\t\tif (builtin->instruction)\n\t\t\t\t\tcheckInstruction(nativeLocationOf(_funCall), *builtin->instruction);\n\n\t\tfor (auto const& arg: _funCall.arguments)\n\t\t\tstd::visit(*this, arg);\n\t}\n\tvoid operator()(yul::If const& _if)\n\t{\n\t\tstd::visit(*this, *_if.condition);\n\t\t(*this)(_if.body);\n\t}\n\tvoid operator()(yul::Switch const& _switch)\n\t{\n\t\tstd::visit(*this, *_switch.expression);\n\t\tfor (auto const& _case: _switch.cases)\n\t\t{\n\t\t\tif (_case.value)\n\t\t\t\t(*this)(*_case.value);\n\t\t\t(*this)(_case.body);\n\t\t}\n\t}\n\tvoid operator()(yul::ForLoop const& _for)\n\t{\n\t\t(*this)(_for.pre);\n\t\tstd::visit(*this, *_for.condition);\n\t\t(*this)(_for.body);\n\t\t(*this)(_for.post);\n\t}\n\tvoid operator()(yul::Break const&)\n\t{\n\t}\n\tvoid operator()(yul::Continue const&)\n\t{\n\t}\n\tvoid operator()(yul::Leave const&)\n\t{\n\t}\n\tvoid operator()(yul::Block const& _block)\n\t{\n\t\tfor (auto const& s: _block.statements)\n\t\t\tstd::visit(*this, s);\n\t}\n\nprivate:\n\tvoid checkInstruction(SourceLocation _location, evmasm::Instruction _instruction)\n\t{\n\t\tif (evmasm::SemanticInformation::invalidInViewFunctions(_instruction))\n\t\t\tm_reportMutability(StateMutability::NonPayable, _location);\n\t\telse if (evmasm::SemanticInformation::invalidInPureFunctions(_instruction))\n\t\t\tm_reportMutability(StateMutability::View, _location);\n\t}\n\n\tyul::Dialect const& m_dialect;\n\tstd::function<void(StateMutability, SourceLocation const&)> m_reportMutability;\n};\n\n}\n\nbool ViewPureChecker::check()\n{\n\tfor (auto const& source: m_ast)\n\t\tsource->accept(*this);\n\n\treturn !m_errors;\n}\n\nbool ViewPureChecker::visit(ImportDirective const&)\n{\n\treturn false;\n}\n\nbool ViewPureChecker::visit(FunctionDefinition const& _funDef)\n{\n\tsolAssert(!m_currentFunction, \"\");\n\tm_currentFunction = &_funDef;\n\tm_bestMutabilityAndLocation = {StateMutability::Pure, _funDef.location()};\n\treturn true;\n}\n\nvoid ViewPureChecker::endVisit(FunctionDefinition const& _funDef)\n{\n\tsolAssert(m_currentFunction == &_funDef, \"\");\n\tif (\n\t\tm_bestMutabilityAndLocation.mutability < _funDef.stateMutability() &&\n\t\t_funDef.stateMutability() != StateMutability::Payable &&\n\t\t_funDef.isImplemented() &&\n\t\t!_funDef.body().statements().empty() &&\n\t\t!_funDef.isConstructor() &&\n\t\t!_funDef.isFallback() &&\n\t\t!_funDef.isReceive() &&\n\t\t!_funDef.virtualSemantics()\n\t)\n\t\tm_errorReporter.warning(\n\t\t\t2018_error,\n\t\t\t_funDef.location(),\n\t\t\t\"Function state mutability can be restricted to \" + stateMutabilityToString(m_bestMutabilityAndLocation.mutability)\n\t\t);\n\tm_currentFunction = nullptr;\n}\n\nbool ViewPureChecker::visit(ModifierDefinition const& _modifier)\n{\n\tsolAssert(m_currentFunction == nullptr, \"\");\n\tm_bestMutabilityAndLocation = {StateMutability::Pure, _modifier.location()};\n\treturn true;\n}\n\nvoid ViewPureChecker::endVisit(ModifierDefinition const& _modifierDef)\n{\n\tsolAssert(m_currentFunction == nullptr, \"\");\n\tm_inferredMutability[&_modifierDef] = std::move(m_bestMutabilityAndLocation);\n}\n\nvoid ViewPureChecker::endVisit(Identifier const& _identifier)\n{\n\tDeclaration const* declaration = _identifier.annotation().referencedDeclaration;\n\tsolAssert(declaration, \"\");\n\n\tStateMutability mutability = StateMutability::Pure;\n\n\tbool writes = _identifier.annotation().willBeWrittenTo;\n\tif (VariableDeclaration const* varDecl = dynamic_cast<VariableDeclaration const*>(declaration))\n\t{\n\t\tif (varDecl->immutable())\n\t\t{\n\t\t\t// Immutables that are assigned literals are pure.\n\t\t\tif (!(varDecl->value() && varDecl->value()->annotation().type->category() == Type::Category::RationalNumber))\n\t\t\t\tmutability = StateMutability::View;\n\t\t}\n\t\telse if (varDecl->isStateVariable() && !varDecl->isConstant())\n\t\t\tmutability = writes ? StateMutability::NonPayable : StateMutability::View;\n\t}\n\telse if (MagicVariableDeclaration const* magicVar = dynamic_cast<MagicVariableDeclaration const*>(declaration))\n\t{\n\t\tswitch (magicVar->type()->category())\n\t\t{\n\t\tcase Type::Category::Contract:\n\t\t\tsolAssert(_identifier.name() == \"this\", \"\");\n\t\t\tif (dynamic_cast<ContractType const*>(magicVar->type()))\n\t\t\t\t// reads the address\n\t\t\t\tmutability = StateMutability::View;\n\t\t\tbreak;\n\t\tcase Type::Category::Integer:\n\t\t\tsolAssert(_identifier.name() == \"now\", \"\");\n\t\t\tmutability = StateMutability::View;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treportMutability(mutability, _identifier.location());\n}\n\nvoid ViewPureChecker::endVisit(InlineAssembly const& _inlineAssembly)\n{\n\tAssemblyViewPureChecker{\n\t\t_inlineAssembly.dialect(),\n\t\t[&](StateMutability _mutability, SourceLocation const& _location) { reportMutability(_mutability, _location); }\n\t}(_inlineAssembly.operations().root());\n}\n\nvoid ViewPureChecker::reportMutability(\n\tStateMutability _mutability,\n\tSourceLocation const& _location,\n\tstd::optional<SourceLocation> const& _nestedLocation\n)\n{\n\tif (_mutability > m_bestMutabilityAndLocation.mutability)\n\t\tm_bestMutabilityAndLocation = MutabilityAndLocation{_mutability, _location};\n\tif (!m_currentFunction || _mutability <= m_currentFunction->stateMutability())\n\t\treturn;\n\n\t// Check for payable here, because any occurrence of `msg.value`\n\t// will set mutability to payable.\n\tif (_mutability == StateMutability::View || (\n\t\t_mutability == StateMutability::Payable &&\n\t\tm_currentFunction->stateMutability() == StateMutability::Pure\n\t))\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t2527_error,\n\t\t\t_location,\n\t\t\t\"Function declared as pure, but this expression (potentially) reads from the \"\n\t\t\t\"environment or state and thus requires \\\"view\\\".\"\n\t\t);\n\t\tm_errors = true;\n\t}\n\telse if (_mutability == StateMutability::NonPayable)\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t8961_error,\n\t\t\t_location,\n\t\t\t\"Function cannot be declared as \" +\n\t\t\tstateMutabilityToString(m_currentFunction->stateMutability()) +\n\t\t\t\" because this expression (potentially) modifies the state.\"\n\t\t);\n\t\tm_errors = true;\n\t}\n\telse if (_mutability == StateMutability::Payable)\n\t{\n\t\t// We do not warn for library functions because they cannot be payable anyway.\n\t\t// Also internal functions should be allowed to use `msg.value`.\n\t\tif ((m_currentFunction->isConstructor() || m_currentFunction->isPublic()) && !m_currentFunction->libraryFunction())\n\t\t{\n\t\t\tif (_nestedLocation)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t4006_error,\n\t\t\t\t\t_location,\n\t\t\t\t\tSecondarySourceLocation().append(\"\\\"msg.value\\\" or \\\"callvalue()\\\" appear here inside the modifier.\", *_nestedLocation),\n\t\t\t\t\tm_currentFunction->isConstructor()  ?\n\t\t\t\t\t\t\"This modifier uses \\\"msg.value\\\" or \\\"callvalue()\\\" and thus the constructor has to be payable.\"\n\t\t\t\t\t\t: \"This modifier uses \\\"msg.value\\\" or \\\"callvalue()\\\" and thus the function has to be payable or internal.\"\n\t\t\t\t);\n\t\t\telse\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t5887_error,\n\t\t\t\t\t_location,\n\t\t\t\t\tm_currentFunction->isConstructor()  ?\n\t\t\t\t\t\t\"\\\"msg.value\\\" and \\\"callvalue()\\\" can only be used in payable constructors. Make the constructor \\\"payable\\\" to avoid this error.\"\n\t\t\t\t\t\t: \"\\\"msg.value\\\" and \\\"callvalue()\\\" can only be used in payable public functions. Make the function \\\"payable\\\" or use an internal function to avoid this error.\"\n\t\t\t\t);\n\t\t\tm_errors = true;\n\t\t}\n\t}\n\telse\n\t\tsolAssert(false, \"\");\n\n\tsolAssert(\n\t\tm_currentFunction->stateMutability() == StateMutability::View ||\n\t\tm_currentFunction->stateMutability() == StateMutability::Pure ||\n\t\tm_currentFunction->stateMutability() == StateMutability::NonPayable,\n\t\t\"\"\n\t);\n}\n\nViewPureChecker::MutabilityAndLocation const& ViewPureChecker::modifierMutability(\n\tModifierDefinition const& _modifier\n)\n{\n\tif (!m_inferredMutability.count(&_modifier))\n\t{\n\t\tMutabilityAndLocation bestMutabilityAndLocation{};\n\t\tFunctionDefinition const* currentFunction = nullptr;\n\t\tstd::swap(bestMutabilityAndLocation, m_bestMutabilityAndLocation);\n\t\tstd::swap(currentFunction, m_currentFunction);\n\n\t\t_modifier.accept(*this);\n\n\t\tstd::swap(bestMutabilityAndLocation, m_bestMutabilityAndLocation);\n\t\tstd::swap(currentFunction, m_currentFunction);\n\t}\n\treturn m_inferredMutability.at(&_modifier);\n}\n\nvoid ViewPureChecker::reportFunctionCallMutability(StateMutability _mutability, langutil::SourceLocation const& _location)\n{\n\t// We only require \"nonpayable\" to call a payable function.\n\tif (_mutability == StateMutability::Payable)\n\t\t_mutability = StateMutability::NonPayable;\n\treportMutability(_mutability, _location);\n}\n\nvoid ViewPureChecker::endVisit(BinaryOperation const& _binaryOperation)\n{\n\tif (*_binaryOperation.annotation().userDefinedFunction != nullptr)\n\t\treportFunctionCallMutability((*_binaryOperation.annotation().userDefinedFunction)->stateMutability(), _binaryOperation.location());\n}\n\nvoid ViewPureChecker::endVisit(UnaryOperation const& _unaryOperation)\n{\n\tif (*_unaryOperation.annotation().userDefinedFunction != nullptr)\n\t\treportFunctionCallMutability((*_unaryOperation.annotation().userDefinedFunction)->stateMutability(), _unaryOperation.location());\n}\n\nvoid ViewPureChecker::endVisit(FunctionCall const& _functionCall)\n{\n\tif (*_functionCall.annotation().kind != FunctionCallKind::FunctionCall)\n\t\treturn;\n\n\treportFunctionCallMutability(\n\t\tdynamic_cast<FunctionType const&>(*_functionCall.expression().annotation().type).stateMutability(),\n\t\t_functionCall.location()\n\t);\n}\n\nbool ViewPureChecker::visit(MemberAccess const& _memberAccess)\n{\n\t// Catch the special case of `this.f.selector` which is a pure expression.\n\tASTString const& member = _memberAccess.memberName();\n\tif (\n\t\t_memberAccess.expression().annotation().type->category() == Type::Category::Function &&\n\t\tmember == \"selector\"\n\t)\n\t\tif (auto const* expr = dynamic_cast<MemberAccess const*>(&_memberAccess.expression()))\n\t\t\tif (auto const* exprInt = dynamic_cast<Identifier const*>(&expr->expression()))\n\t\t\t\tif (exprInt->name() == \"this\")\n\t\t\t\t\t// Do not continue visiting.\n\t\t\t\t\treturn false;\n\treturn true;\n}\n\nvoid ViewPureChecker::endVisit(MemberAccess const& _memberAccess)\n{\n\tStateMutability mutability = StateMutability::Pure;\n\tbool writes = _memberAccess.annotation().willBeWrittenTo;\n\n\tASTString const& member = _memberAccess.memberName();\n\tswitch (_memberAccess.expression().annotation().type->category())\n\t{\n\tcase Type::Category::Address:\n\t\tif (member == \"balance\" || member == \"code\" || member == \"codehash\")\n\t\t\tmutability = StateMutability::View;\n\t\tbreak;\n\tcase Type::Category::Magic:\n\t{\n\t\tusing MagicMember = std::pair<MagicType::Kind, std::string>;\n\t\tstd::set<MagicMember> static const pureMembers{\n\t\t\t{MagicType::Kind::ABI, \"decode\"},\n\t\t\t{MagicType::Kind::ABI, \"encode\"},\n\t\t\t{MagicType::Kind::ABI, \"encodePacked\"},\n\t\t\t{MagicType::Kind::ABI, \"encodeWithSelector\"},\n\t\t\t{MagicType::Kind::ABI, \"encodeCall\"},\n\t\t\t{MagicType::Kind::ABI, \"encodeWithSignature\"},\n\t\t\t{MagicType::Kind::Message, \"data\"},\n\t\t\t{MagicType::Kind::Message, \"sig\"},\n\t\t\t{MagicType::Kind::MetaType, \"creationCode\"},\n\t\t\t{MagicType::Kind::MetaType, \"runtimeCode\"},\n\t\t\t{MagicType::Kind::MetaType, \"name\"},\n\t\t\t{MagicType::Kind::MetaType, \"interfaceId\"},\n\t\t\t{MagicType::Kind::MetaType, \"min\"},\n\t\t\t{MagicType::Kind::MetaType, \"max\"},\n\t\t};\n\t\tstd::set<MagicMember> static const payableMembers{\n\t\t\t{MagicType::Kind::Message, \"value\"}\n\t\t};\n\n\t\tauto const& type = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type);\n\t\tMagicMember magicMember(type.kind(), member);\n\n\t\tif (!pureMembers.count(magicMember))\n\t\t\tmutability = StateMutability::View;\n\t\tif (payableMembers.count(magicMember))\n\t\t\tmutability = StateMutability::Payable;\n\t\tbreak;\n\t}\n\tcase Type::Category::Struct:\n\t{\n\t\tif (_memberAccess.expression().annotation().type->dataStoredIn(DataLocation::Storage))\n\t\t\tmutability = writes ? StateMutability::NonPayable : StateMutability::View;\n\t\tbreak;\n\t}\n\tcase Type::Category::Array:\n\t{\n\t\tauto const& type = dynamic_cast<ArrayType const&>(*_memberAccess.expression().annotation().type);\n\t\tif (member == \"length\" && type.isDynamicallySized() && type.dataStoredIn(DataLocation::Storage))\n\t\t\tmutability = StateMutability::View;\n\t\tbreak;\n\t}\n\tdefault:\n\t{\n\t\tif (VariableDeclaration const* varDecl = dynamic_cast<VariableDeclaration const*>(\n\t\t\t_memberAccess.annotation().referencedDeclaration\n\t\t))\n\t\t\tif (varDecl->isStateVariable() && !varDecl->isConstant())\n\t\t\t\tmutability = writes ? StateMutability::NonPayable : StateMutability::View;\n\t\tbreak;\n\t}\n\t}\n\treportMutability(mutability, _memberAccess.location());\n}\n\nvoid ViewPureChecker::endVisit(IndexAccess const& _indexAccess)\n{\n\tif (!_indexAccess.indexExpression())\n\t\tsolAssert(_indexAccess.annotation().type->category() == Type::Category::TypeType, \"\");\n\telse\n\t{\n\t\tbool writes = _indexAccess.annotation().willBeWrittenTo;\n\t\tif (_indexAccess.baseExpression().annotation().type->dataStoredIn(DataLocation::Storage))\n\t\t\treportMutability(writes ? StateMutability::NonPayable : StateMutability::View, _indexAccess.location());\n\t}\n}\n\nvoid ViewPureChecker::endVisit(IndexRangeAccess const& _indexRangeAccess)\n{\n\tbool writes = _indexRangeAccess.annotation().willBeWrittenTo;\n\tif (_indexRangeAccess.baseExpression().annotation().type->dataStoredIn(DataLocation::Storage))\n\t\treportMutability(writes ? StateMutability::NonPayable : StateMutability::View, _indexRangeAccess.location());\n}\n\nvoid ViewPureChecker::endVisit(ModifierInvocation const& _modifier)\n{\n\tif (ModifierDefinition const* mod = dynamic_cast<decltype(mod)>(_modifier.name().annotation().referencedDeclaration))\n\t{\n\t\tMutabilityAndLocation const& mutAndLocation = modifierMutability(*mod);\n\t\treportMutability(mutAndLocation.mutability, _modifier.location(), mutAndLocation.location);\n\t}\n\telse\n\t\tsolAssert(dynamic_cast<ContractDefinition const*>(_modifier.name().annotation().referencedDeclaration), \"\");\n}\n"
  },
  {
    "path": "libsolidity/analysis/ViewPureChecker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/ASTEnums.h>\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/ASTVisitor.h>\n\n#include <map>\n#include <memory>\n#include <optional>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\nstruct SourceLocation;\n}\n\nnamespace solidity::frontend\n{\n\nclass ViewPureChecker: private ASTConstVisitor\n{\npublic:\n\tViewPureChecker(std::vector<std::shared_ptr<ASTNode>> const& _ast, langutil::ErrorReporter& _errorReporter):\n\t\tm_ast(_ast), m_errorReporter(_errorReporter) {}\n\n\tbool check();\n\nprivate:\n\tstruct MutabilityAndLocation\n\t{\n\t\tStateMutability mutability;\n\t\tlangutil::SourceLocation location;\n\t};\n\n\tbool visit(ImportDirective const&) override;\n\n\tbool visit(FunctionDefinition const& _funDef) override;\n\tvoid endVisit(FunctionDefinition const& _funDef) override;\n\tvoid endVisit(BinaryOperation const& _binaryOperation) override;\n\tvoid endVisit(UnaryOperation const& _unaryOperation) override;\n\tbool visit(ModifierDefinition const& _modifierDef) override;\n\tvoid endVisit(ModifierDefinition const& _modifierDef) override;\n\tvoid endVisit(Identifier const& _identifier) override;\n\tbool visit(MemberAccess const& _memberAccess) override;\n\tvoid endVisit(MemberAccess const& _memberAccess) override;\n\tvoid endVisit(IndexAccess const& _indexAccess) override;\n\tvoid endVisit(IndexRangeAccess const& _indexAccess) override;\n\tvoid endVisit(ModifierInvocation const& _modifier) override;\n\tvoid endVisit(FunctionCall const& _functionCall) override;\n\tvoid endVisit(InlineAssembly const& _inlineAssembly) override;\n\n\t/// Called when an element of mutability @a _mutability is encountered.\n\t/// Creates appropriate warnings and errors and sets @a m_currentBestMutability.\n\tvoid reportMutability(\n\t\tStateMutability _mutability,\n\t\tlangutil::SourceLocation const& _location,\n\t\tstd::optional<langutil::SourceLocation> const& _nestedLocation = {}\n\t);\n\n\tvoid reportFunctionCallMutability(StateMutability _mutability, langutil::SourceLocation const& _location);\n\n\t/// Determines the mutability of modifier if not already cached.\n\tMutabilityAndLocation const& modifierMutability(ModifierDefinition const& _modifier);\n\n\tstd::vector<std::shared_ptr<ASTNode>> const& m_ast;\n\tlangutil::ErrorReporter& m_errorReporter;\n\n\tbool m_errors = false;\n\tMutabilityAndLocation m_bestMutabilityAndLocation = MutabilityAndLocation{StateMutability::Payable, langutil::SourceLocation()};\n\tFunctionDefinition const* m_currentFunction = nullptr;\n\tstd::map<ModifierDefinition const*, MutabilityAndLocation> m_inferredMutability;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/ast/AST.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity abstract syntax tree.\n */\n\n#include <libsolidity/ast/AST.h>\n\n#include <libsolidity/ast/CallGraph.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/ast/AST_accept.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolutil/FunctionSelector.h>\n#include <libsolutil/Keccak256.h>\n\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/tail.hpp>\n#include <range/v3/view/zip.hpp>\n\n#include <boost/algorithm/string.hpp>\n\n#include <functional>\n#include <utility>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\n\nnamespace\n{\nTryCatchClause const* findClause(std::vector<ASTPointer<TryCatchClause>> const& _clauses, std::optional<std::string> _errorName = {})\n{\n\tfor (auto const& clause: ranges::views::tail(_clauses))\n\t\tif (_errorName.has_value() ? clause->errorName() == _errorName : clause->errorName().empty())\n\t\t\treturn clause.get();\n\treturn nullptr;\n}\n}\n\nASTNode::ASTNode(int64_t _id, SourceLocation _location):\n\tm_id(static_cast<size_t>(_id)),\n\tm_location(std::move(_location))\n{\n}\n\nDeclaration const* ASTNode::referencedDeclaration(Expression const& _expression)\n{\n\tif (auto const* memberAccess = dynamic_cast<MemberAccess const*>(&_expression))\n\t\treturn memberAccess->annotation().referencedDeclaration;\n\telse if (auto const* identifierPath = dynamic_cast<IdentifierPath const*>(&_expression))\n\t\treturn identifierPath->annotation().referencedDeclaration;\n\telse if (auto const* identifier = dynamic_cast<Identifier const*>(&_expression))\n\t\treturn identifier->annotation().referencedDeclaration;\n\telse\n\t\treturn nullptr;\n}\n\nFunctionDefinition const* ASTNode::resolveFunctionCall(FunctionCall const& _functionCall, ContractDefinition const* _mostDerivedContract)\n{\n\tauto const* functionDef = dynamic_cast<FunctionDefinition const*>(\n\t\tASTNode::referencedDeclaration(_functionCall.expression())\n\t);\n\n\tif (!functionDef)\n\t\treturn nullptr;\n\n\tif (auto const* memberAccess = dynamic_cast<MemberAccess const*>(&_functionCall.expression()))\n\t{\n\t\tif (*memberAccess->annotation().requiredLookup == VirtualLookup::Super)\n\t\t{\n\t\t\tif (auto const typeType = dynamic_cast<TypeType const*>(memberAccess->expression().annotation().type))\n\t\t\t\tif (auto const contractType = dynamic_cast<ContractType const*>(typeType->actualType()))\n\t\t\t\t{\n\t\t\t\t\tsolAssert(_mostDerivedContract, \"\");\n\t\t\t\t\tsolAssert(contractType->isSuper(), \"\");\n\t\t\t\t\tContractDefinition const* superContract = contractType->contractDefinition().superContract(*_mostDerivedContract);\n\n\t\t\t\t\treturn &functionDef->resolveVirtual(\n\t\t\t\t\t\t*_mostDerivedContract,\n\t\t\t\t\t\tsuperContract\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t}\n\t\telse\n\t\t\tsolAssert(*memberAccess->annotation().requiredLookup == VirtualLookup::Static, \"\");\n\t}\n\telse if (auto const* identifier = dynamic_cast<Identifier const*>(&_functionCall.expression()))\n\t{\n\t\tsolAssert(*identifier->annotation().requiredLookup == VirtualLookup::Virtual, \"\");\n\t\tif (functionDef->virtualSemantics())\n\t\t{\n\t\t\tsolAssert(_mostDerivedContract, \"\");\n\t\t\treturn &functionDef->resolveVirtual(*_mostDerivedContract);\n\t\t}\n\t}\n\telse\n\t\tsolAssert(false, \"\");\n\n\treturn functionDef;\n}\n\nASTAnnotation& ASTNode::annotation() const\n{\n\tif (!m_annotation)\n\t\tm_annotation = std::make_unique<ASTAnnotation>();\n\treturn *m_annotation;\n}\n\nSourceUnitAnnotation& SourceUnit::annotation() const\n{\n\treturn initAnnotation<SourceUnitAnnotation>();\n}\n\nstd::set<SourceUnit const*> SourceUnit::referencedSourceUnits(bool _recurse, std::set<SourceUnit const*> _skipList) const\n{\n\tstd::set<SourceUnit const*> sourceUnits;\n\treferencedSourceUnits(sourceUnits, _recurse, _skipList);\n\treturn sourceUnits;\n}\n\nvoid SourceUnit::referencedSourceUnits(std::set<SourceUnit const*>& _referencedSourceUnits, bool _recurse, std::set<SourceUnit const*>& _skipList) const\n{\n\tfor (ImportDirective const* importDirective: filteredNodes<ImportDirective>(nodes()))\n\t{\n\t\tauto const& sourceUnit = importDirective->annotation().sourceUnit;\n\t\tauto [skipListIt, notOnSkipListYet] = _skipList.insert(sourceUnit);\n\t\tif (notOnSkipListYet)\n\t\t{\n\t\t\t_referencedSourceUnits.insert(sourceUnit);\n\t\t\tif (_recurse)\n\t\t\t\tsourceUnit->referencedSourceUnits(_referencedSourceUnits, true, _skipList);\n\t\t}\n\t}\n}\n\nImportAnnotation& ImportDirective::annotation() const\n{\n\treturn initAnnotation<ImportAnnotation>();\n}\n\nType const* ImportDirective::type() const\n{\n\tsolAssert(!!annotation().sourceUnit, \"\");\n\treturn TypeProvider::module(*annotation().sourceUnit);\n}\n\nbool ContractDefinition::derivesFrom(ContractDefinition const& _base) const\n{\n\treturn util::contains(annotation().linearizedBaseContracts, &_base);\n}\n\nstd::map<util::FixedHash<4>, FunctionTypePointer> ContractDefinition::interfaceFunctions(bool _includeInheritedFunctions) const\n{\n\tauto exportedFunctionList = interfaceFunctionList(_includeInheritedFunctions);\n\n\tstd::map<util::FixedHash<4>, FunctionTypePointer> exportedFunctions;\n\tfor (auto const& it: exportedFunctionList)\n\t\texportedFunctions.insert(it);\n\n\tsolAssert(\n\t\texportedFunctionList.size() == exportedFunctions.size(),\n\t\t\"Hash collision at Function Definition Hash calculation\"\n\t);\n\n\treturn exportedFunctions;\n}\n\nFunctionDefinition const* ContractDefinition::constructor() const\n{\n\tfor (FunctionDefinition const* f: definedFunctions())\n\t\tif (f->isConstructor())\n\t\t\treturn f;\n\treturn nullptr;\n}\n\nbool ContractDefinition::canBeDeployed() const\n{\n\treturn !abstract() && !isInterface();\n}\n\nFunctionDefinition const* ContractDefinition::fallbackFunction() const\n{\n\tfor (ContractDefinition const* contract: annotation().linearizedBaseContracts)\n\t\tfor (FunctionDefinition const* f: contract->definedFunctions())\n\t\t\tif (f->isFallback())\n\t\t\t\treturn f;\n\treturn nullptr;\n}\n\nFunctionDefinition const* ContractDefinition::receiveFunction() const\n{\n\tfor (ContractDefinition const* contract: annotation().linearizedBaseContracts)\n\t\tfor (FunctionDefinition const* f: contract->definedFunctions())\n\t\t\tif (f->isReceive())\n\t\t\t\treturn f;\n\treturn nullptr;\n}\n\nstd::vector<EventDefinition const*> const& ContractDefinition::definedInterfaceEvents() const\n{\n\treturn m_interfaceEvents.init([&]{\n\t\tstd::set<std::string> eventsSeen;\n\t\tstd::vector<EventDefinition const*> interfaceEvents;\n\n\t\tfor (ContractDefinition const* contract: annotation().linearizedBaseContracts)\n\t\t\tfor (EventDefinition const* e: contract->events())\n\t\t\t{\n\t\t\t\t/// NOTE: this requires the \"internal\" version of an Event,\n\t\t\t\t///       though here internal strictly refers to visibility,\n\t\t\t\t///       and not to function encoding (jump vs. call)\n\t\t\t\tFunctionType const* functionType = e->functionType(true);\n\t\t\t\tsolAssert(functionType, \"\");\n\t\t\t\tstd::string eventSignature = functionType->externalSignature();\n\t\t\t\tif (eventsSeen.count(eventSignature) == 0)\n\t\t\t\t{\n\t\t\t\t\teventsSeen.insert(eventSignature);\n\t\t\t\t\tinterfaceEvents.push_back(e);\n\t\t\t\t}\n\t\t\t}\n\t\treturn interfaceEvents;\n\t});\n}\n\nstd::vector<EventDefinition const*> const ContractDefinition::usedInterfaceEvents() const\n{\n\tsolAssert(annotation().creationCallGraph.set(), \"\");\n\n\treturn util::convertContainer<std::vector<EventDefinition const*>>(\n\t\t(*annotation().creationCallGraph)->emittedEvents +\n\t\t(*annotation().deployedCallGraph)->emittedEvents\n\t);\n}\n\nstd::vector<EventDefinition const*> ContractDefinition::interfaceEvents(bool _requireCallGraph) const\n{\n\tstd::set<EventDefinition const*, CompareByID> result;\n\tfor (ContractDefinition const* contract: annotation().linearizedBaseContracts)\n\t\tresult += contract->events();\n\tsolAssert(annotation().creationCallGraph.set() == annotation().deployedCallGraph.set());\n\tif (_requireCallGraph)\n\t\tsolAssert(annotation().creationCallGraph.set());\n\tif (annotation().creationCallGraph.set())\n\t\tresult += usedInterfaceEvents();\n\t// We could filter out all events that do not have an external interface\n\t// if _requireCallGraph is false.\n\treturn util::convertContainer<std::vector<EventDefinition const*>>(std::move(result));\n}\n\nstd::vector<ErrorDefinition const*> ContractDefinition::interfaceErrors(bool _requireCallGraph) const\n{\n\tstd::set<ErrorDefinition const*, CompareByID> result;\n\tfor (ContractDefinition const* contract: annotation().linearizedBaseContracts)\n\t\tresult += filteredNodes<ErrorDefinition>(contract->m_subNodes);\n\tsolAssert(annotation().creationCallGraph.set() == annotation().deployedCallGraph.set(), \"\");\n\tif (_requireCallGraph)\n\t\tsolAssert(annotation().creationCallGraph.set(), \"\");\n\tif (annotation().creationCallGraph.set())\n\t\tresult +=\n\t\t\t(*annotation().creationCallGraph)->usedErrors +\n\t\t\t(*annotation().deployedCallGraph)->usedErrors;\n\treturn util::convertContainer<std::vector<ErrorDefinition const*>>(std::move(result));\n}\n\nstd::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::interfaceFunctionList(bool _includeInheritedFunctions) const\n{\n\treturn m_interfaceFunctionList[_includeInheritedFunctions].init([&]{\n\t\tstd::set<std::string> signaturesSeen;\n\t\tstd::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>> interfaceFunctionList;\n\n\t\tfor (ContractDefinition const* contract: annotation().linearizedBaseContracts)\n\t\t{\n\t\t\tif (_includeInheritedFunctions == false && contract != this)\n\t\t\t\tcontinue;\n\t\t\tstd::vector<FunctionTypePointer> functions;\n\t\t\tfor (FunctionDefinition const* f: contract->definedFunctions())\n\t\t\t\tif (f->isPartOfExternalInterface())\n\t\t\t\t\tfunctions.push_back(TypeProvider::function(*f, FunctionType::Kind::External));\n\t\t\tfor (VariableDeclaration const* v: contract->stateVariables())\n\t\t\t\tif (v->isPartOfExternalInterface())\n\t\t\t\t\tfunctions.push_back(TypeProvider::function(*v));\n\t\t\tfor (FunctionTypePointer const& fun: functions)\n\t\t\t{\n\t\t\t\tif (!fun->interfaceFunctionType())\n\t\t\t\t\t// Fails hopefully because we already registered the error\n\t\t\t\t\tcontinue;\n\t\t\t\tstd::string functionSignature = fun->externalSignature();\n\t\t\t\tif (signaturesSeen.count(functionSignature) == 0)\n\t\t\t\t{\n\t\t\t\t\tsignaturesSeen.insert(functionSignature);\n\t\t\t\t\tinterfaceFunctionList.emplace_back(util::selectorFromSignatureH32(functionSignature), fun);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn interfaceFunctionList;\n\t});\n}\n\nuint32_t ContractDefinition::interfaceId() const\n{\n\tuint32_t result{0};\n\tfor (auto const& function: interfaceFunctionList(false))\n\t\tresult ^= fromBigEndian<uint32_t>(function.first.ref());\n\treturn result;\n}\n\nType const* ContractDefinition::type() const\n{\n\treturn TypeProvider::typeType(TypeProvider::contract(*this));\n}\n\nContractDefinitionAnnotation& ContractDefinition::annotation() const\n{\n\treturn initAnnotation<ContractDefinitionAnnotation>();\n}\n\nContractDefinition const* ContractDefinition::superContract(ContractDefinition const& _mostDerivedContract) const\n{\n\tauto const& hierarchy = _mostDerivedContract.annotation().linearizedBaseContracts;\n\tauto it = find(hierarchy.begin(), hierarchy.end(), this);\n\tsolAssert(it != hierarchy.end(), \"Base not found in inheritance hierarchy.\");\n\t++it;\n\tif (it == hierarchy.end())\n\t\treturn nullptr;\n\telse\n\t{\n\t\tsolAssert(*it != this, \"\");\n\t\treturn *it;\n\t}\n}\n\nFunctionDefinition const* ContractDefinition::nextConstructor(ContractDefinition const& _mostDerivedContract) const\n{\n\tContractDefinition const* next = superContract(_mostDerivedContract);\n\tif (next == nullptr)\n\t\treturn nullptr;\n\tfor (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)\n\t\tif (c == next || next == nullptr)\n\t\t{\n\t\t\tif (c->constructor())\n\t\t\t\treturn c->constructor();\n\t\t\tnext = nullptr;\n\t\t}\n\n\treturn nullptr;\n}\n\nstd::multimap<std::string, FunctionDefinition const*> const& ContractDefinition::definedFunctionsByName() const\n{\n\treturn m_definedFunctionsByName.init([&]{\n\t\tstd::multimap<std::string, FunctionDefinition const*> result;\n\t\tfor (FunctionDefinition const* fun: filteredNodes<FunctionDefinition>(m_subNodes))\n\t\t\tresult.insert({fun->name(), fun});\n\t\treturn result;\n\t});\n}\n\nStorageLayoutSpecifier::StorageLayoutSpecifier(\n\tint64_t _id,\n\tSourceLocation const& _location,\n\tASTPointer<Expression> _baseSlotExpression\n):\n\tASTNode(_id, _location),\n\tm_baseSlotExpression(_baseSlotExpression)\n{\n\tsolAssert(m_baseSlotExpression);\n\tsolAssert(_location.contains(m_baseSlotExpression->location()));\n}\n\nStorageLayoutSpecifierAnnotation& StorageLayoutSpecifier::annotation() const\n{\n\treturn initAnnotation<StorageLayoutSpecifierAnnotation>();\n}\n\nTypeNameAnnotation& TypeName::annotation() const\n{\n\treturn initAnnotation<TypeNameAnnotation>();\n}\n\nType const* UserDefinedValueTypeDefinition::type() const\n{\n\tsolAssert(m_underlyingType->annotation().type, \"\");\n\treturn TypeProvider::typeType(TypeProvider::userDefinedValueType(*this));\n}\n\nTypeDeclarationAnnotation& UserDefinedValueTypeDefinition::annotation() const\n{\n\treturn initAnnotation<TypeDeclarationAnnotation>();\n}\n\nstd::vector<std::pair<ASTPointer<IdentifierPath>, std::optional<Token>>> UsingForDirective::functionsAndOperators() const\n{\n\treturn ranges::zip_view(m_functionsOrLibrary, m_operators) | ranges::to<std::vector>;\n}\n\nType const* StructDefinition::type() const\n{\n\tsolAssert(annotation().recursive.has_value(), \"Requested struct type before DeclarationTypeChecker.\");\n\treturn TypeProvider::typeType(TypeProvider::structType(*this, DataLocation::Storage));\n}\n\nStructDeclarationAnnotation& StructDefinition::annotation() const\n{\n\treturn initAnnotation<StructDeclarationAnnotation>();\n}\n\nType const* EnumValue::type() const\n{\n\tauto parentDef = dynamic_cast<EnumDefinition const*>(scope());\n\tsolAssert(parentDef, \"Enclosing Scope of EnumValue was not set\");\n\treturn TypeProvider::enumType(*parentDef);\n}\n\nType const* EnumDefinition::type() const\n{\n\treturn TypeProvider::typeType(TypeProvider::enumType(*this));\n}\n\nTypeDeclarationAnnotation& EnumDefinition::annotation() const\n{\n\treturn initAnnotation<TypeDeclarationAnnotation>();\n}\n\nbool FunctionDefinition::libraryFunction() const\n{\n\tif (auto const* contractDef = dynamic_cast<ContractDefinition const*>(scope()))\n\t\treturn contractDef->isLibrary();\n\treturn false;\n}\n\nVisibility FunctionDefinition::defaultVisibility() const\n{\n\tsolAssert(!isConstructor(), \"\");\n\treturn isFree() ? Visibility::Internal : Declaration::defaultVisibility();\n}\n\nFunctionTypePointer FunctionDefinition::functionType(bool _internal) const\n{\n\tif (_internal)\n\t{\n\t\tswitch (visibility())\n\t\t{\n\t\tcase Visibility::Default:\n\t\t\tsolAssert(false, \"visibility() should not return Default\");\n\t\tcase Visibility::Private:\n\t\tcase Visibility::Internal:\n\t\tcase Visibility::Public:\n\t\t\treturn TypeProvider::function(*this, FunctionType::Kind::Internal);\n\t\tcase Visibility::External:\n\t\t\treturn {};\n\t\t}\n\t}\n\telse\n\t{\n\t\tswitch (visibility())\n\t\t{\n\t\tcase Visibility::Default:\n\t\t\tsolAssert(false, \"visibility() should not return Default\");\n\t\tcase Visibility::Private:\n\t\tcase Visibility::Internal:\n\t\t\treturn {};\n\t\tcase Visibility::Public:\n\t\tcase Visibility::External:\n\t\t\treturn TypeProvider::function(*this, FunctionType::Kind::External);\n\t\t}\n\t}\n\n\t// To make the compiler happy\n\treturn {};\n}\n\nType const* FunctionDefinition::type() const\n{\n\tsolAssert(visibility() != Visibility::External, \"\");\n\treturn TypeProvider::function(*this, FunctionType::Kind::Internal);\n}\n\nType const* FunctionDefinition::typeViaContractName() const\n{\n\tif (libraryFunction())\n\t{\n\t\tif (isPublic())\n\t\t\treturn FunctionType(*this).asExternallyCallableFunction(true);\n\t\telse\n\t\t\treturn TypeProvider::function(*this, FunctionType::Kind::Internal);\n\t}\n\telse\n\t\treturn TypeProvider::function(*this, FunctionType::Kind::Declaration);\n}\n\nstd::string FunctionDefinition::externalSignature() const\n{\n\treturn TypeProvider::function(*this)->externalSignature();\n}\n\nstd::string FunctionDefinition::externalIdentifierHex() const\n{\n\treturn TypeProvider::function(*this)->externalIdentifierHex();\n}\n\nFunctionDefinitionAnnotation& FunctionDefinition::annotation() const\n{\n\treturn initAnnotation<FunctionDefinitionAnnotation>();\n}\n\nFunctionDefinition const& FunctionDefinition::resolveVirtual(\n\tContractDefinition const& _mostDerivedContract,\n\tContractDefinition const* _searchStart\n) const\n{\n\tsolAssert(!isConstructor(), \"\");\n\tsolAssert(!name().empty(), \"\");\n\n\t// If we are not doing super-lookup and the function is not virtual, we can stop here.\n\tif (_searchStart == nullptr && !virtualSemantics())\n\t\treturn *this;\n\n\tsolAssert(!isFree(), \"\");\n\tsolAssert(isOrdinary(), \"\");\n\tsolAssert(!libraryFunction(), \"\");\n\n\t// We actually do not want the externally callable function here.\n\t// This is just to add an assertion since the comparison used to be less strict.\n\tFunctionType const* externalFunctionType = TypeProvider::function(*this)->asExternallyCallableFunction(false);\n\n\tbool foundSearchStart = (_searchStart == nullptr);\n\tfor (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)\n\t{\n\t\tif (!foundSearchStart && c != _searchStart)\n\t\t\tcontinue;\n\t\telse\n\t\t\tfoundSearchStart = true;\n\n\t\tfor (FunctionDefinition const* function: c->definedFunctions(name()))\n\t\t\tif (\n\t\t\t\t// With super lookup analysis guarantees that there is an implemented function in the chain.\n\t\t\t\t// With virtual lookup there are valid cases where returning an unimplemented one is fine.\n\t\t\t\t(function->isImplemented() || _searchStart == nullptr) &&\n\t\t\t\tFunctionType(*function).asExternallyCallableFunction(false)->hasEqualParameterTypes(*externalFunctionType)\n\t\t\t)\n\t\t\t{\n\t\t\t\tsolAssert(FunctionType(*function).hasEqualParameterTypes(*TypeProvider::function(*this)));\n\t\t\t\treturn *function;\n\t\t\t}\n\t}\n\n\tsolAssert(false, \"Virtual function \" + name() + \" not found.\");\n\treturn *this; // not reached\n}\n\nType const* ModifierDefinition::type() const\n{\n\treturn TypeProvider::modifier(*this);\n}\n\nModifierDefinitionAnnotation& ModifierDefinition::annotation() const\n{\n\treturn initAnnotation<ModifierDefinitionAnnotation>();\n}\n\nModifierDefinition const& ModifierDefinition::resolveVirtual(\n\tContractDefinition const& _mostDerivedContract,\n\tContractDefinition const* _searchStart\n) const\n{\n\t// Super is not possible with modifiers\n\tsolAssert(_searchStart == nullptr, \"Used super in connection with modifiers.\");\n\n\t// The modifier is not virtual, we can stop here.\n\tif (!virtualSemantics())\n\t\treturn *this;\n\n\tsolAssert(!dynamic_cast<ContractDefinition const&>(*scope()).isLibrary(), \"\");\n\n\tfor (ContractDefinition const* c: _mostDerivedContract.annotation().linearizedBaseContracts)\n\t\tfor (ModifierDefinition const* modifier: c->functionModifiers())\n\t\t\tif (modifier->name() == name())\n\t\t\t\treturn *modifier;\n\n\tsolAssert(false, \"Virtual modifier \" + name() + \" not found.\");\n\treturn *this; // not reached\n}\n\n\nType const* EventDefinition::type() const\n{\n\treturn TypeProvider::function(*this);\n}\n\nFunctionTypePointer EventDefinition::functionType(bool _internal) const\n{\n\tif (_internal)\n\t\treturn TypeProvider::function(*this);\n\telse\n\t\treturn nullptr;\n}\n\nEventDefinitionAnnotation& EventDefinition::annotation() const\n{\n\treturn initAnnotation<EventDefinitionAnnotation>();\n}\n\nType const* ErrorDefinition::type() const\n{\n\treturn TypeProvider::function(*this);\n}\n\nFunctionTypePointer ErrorDefinition::functionType(bool _internal) const\n{\n\tif (_internal)\n\t\treturn TypeProvider::function(*this);\n\telse\n\t\treturn nullptr;\n}\n\nErrorDefinitionAnnotation& ErrorDefinition::annotation() const\n{\n\treturn initAnnotation<ErrorDefinitionAnnotation>();\n}\n\nSourceUnit const& Scopable::sourceUnit() const\n{\n\tASTNode const* s = scope();\n\tsolAssert(s, \"\");\n\t// will not always be a declaration\n\twhile (dynamic_cast<Scopable const*>(s) && dynamic_cast<Scopable const*>(s)->scope())\n\t\ts = dynamic_cast<Scopable const*>(s)->scope();\n\treturn dynamic_cast<SourceUnit const&>(*s);\n}\n\nCallableDeclaration const* Scopable::functionOrModifierDefinition() const\n{\n\tASTNode const* s = scope();\n\tsolAssert(s, \"\");\n\twhile (dynamic_cast<Scopable const*>(s))\n\t{\n\t\tif (auto funDef = dynamic_cast<FunctionDefinition const*>(s))\n\t\t\treturn funDef;\n\t\tif (auto modDef = dynamic_cast<ModifierDefinition const*>(s))\n\t\t\treturn modDef;\n\t\ts = dynamic_cast<Scopable const*>(s)->scope();\n\t}\n\treturn nullptr;\n}\n\nstd::string Scopable::sourceUnitName() const\n{\n\treturn *sourceUnit().annotation().path;\n}\n\nbool Declaration::isEnumValue() const\n{\n\tsolAssert(scope(), \"\");\n\treturn dynamic_cast<EnumDefinition const*>(scope());\n}\n\nbool Declaration::isStructMember() const\n{\n\tsolAssert(scope(), \"\");\n\treturn dynamic_cast<StructDefinition const*>(scope());\n}\n\nbool Declaration::isEventOrErrorParameter() const\n{\n\tsolAssert(scope(), \"\");\n\treturn dynamic_cast<EventDefinition const*>(scope()) || dynamic_cast<ErrorDefinition const*>(scope());\n}\n\nbool Declaration::isVisibleAsUnqualifiedName() const\n{\n\tif (!scope())\n\t\treturn true;\n\tif (isStructMember() || isEnumValue() || isEventOrErrorParameter())\n\t\treturn false;\n\tif (auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(scope()))\n\t\tif (!functionDefinition->isImplemented())\n\t\t\treturn false; // parameter of a function without body\n\treturn true;\n}\n\nDeclarationAnnotation& Declaration::annotation() const\n{\n\treturn initAnnotation<DeclarationAnnotation>();\n}\n\nbool VariableDeclaration::isLValue() const\n{\n\t// Constant declared variables are Read-Only\n\treturn !isConstant();\n}\n\nbool VariableDeclaration::isLocalVariable() const\n{\n\tauto s = scope();\n\treturn\n\t\tdynamic_cast<FunctionTypeName const*>(s) ||\n\t\tdynamic_cast<CallableDeclaration const*>(s) ||\n\t\tdynamic_cast<Block const*>(s) ||\n\t\tdynamic_cast<TryCatchClause const*>(s) ||\n\t\tdynamic_cast<ForStatement const*>(s);\n}\n\nbool VariableDeclaration::isCallableOrCatchParameter() const\n{\n\tif (isReturnParameter() || isTryCatchParameter())\n\t\treturn true;\n\n\tstd::vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;\n\n\tif (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))\n\t\tparameters = &funTypeName->parameterTypes();\n\telse if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))\n\t\tparameters = &callable->parameters();\n\n\tif (parameters)\n\t\tfor (auto const& variable: *parameters)\n\t\t\tif (variable.get() == this)\n\t\t\t\treturn true;\n\treturn false;\n}\n\nbool VariableDeclaration::isLocalOrReturn() const\n{\n\treturn isReturnParameter() || (isLocalVariable() && !isCallableOrCatchParameter());\n}\n\nbool VariableDeclaration::isReturnParameter() const\n{\n\tstd::vector<ASTPointer<VariableDeclaration>> const* returnParameters = nullptr;\n\n\tif (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))\n\t\treturnParameters = &funTypeName->returnParameterTypes();\n\telse if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))\n\t\tif (callable->returnParameterList())\n\t\t\treturnParameters = &callable->returnParameterList()->parameters();\n\n\tif (returnParameters)\n\t\tfor (auto const& variable: *returnParameters)\n\t\t\tif (variable.get() == this)\n\t\t\t\treturn true;\n\treturn false;\n}\n\nbool VariableDeclaration::isTryCatchParameter() const\n{\n\treturn dynamic_cast<TryCatchClause const*>(scope());\n}\n\nbool VariableDeclaration::isExternalCallableParameter() const\n{\n\tif (!isCallableOrCatchParameter())\n\t\treturn false;\n\n\tif (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))\n\t\tif (callable->visibility() == Visibility::External)\n\t\t\treturn !isReturnParameter();\n\n\treturn false;\n}\n\nbool VariableDeclaration::isPublicCallableParameter() const\n{\n\tif (!isCallableOrCatchParameter())\n\t\treturn false;\n\n\tif (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))\n\t\tif (callable->visibility() == Visibility::Public)\n\t\t\treturn !isReturnParameter();\n\n\treturn false;\n}\n\nbool VariableDeclaration::isInternalCallableParameter() const\n{\n\tif (!isCallableOrCatchParameter())\n\t\treturn false;\n\n\tif (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))\n\t\treturn funTypeName->visibility() == Visibility::Internal;\n\telse if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))\n\t\treturn callable->visibility() <= Visibility::Internal;\n\treturn false;\n}\n\nbool VariableDeclaration::isConstructorParameter() const\n{\n\tif (!isCallableOrCatchParameter())\n\t\treturn false;\n\tif (auto const* function = dynamic_cast<FunctionDefinition const*>(scope()))\n\t\treturn function->isConstructor();\n\treturn false;\n}\n\nbool VariableDeclaration::isLibraryFunctionParameter() const\n{\n\tif (!isCallableOrCatchParameter())\n\t\treturn false;\n\tif (auto const* funDef = dynamic_cast<FunctionDefinition const*>(scope()))\n\t\treturn funDef->libraryFunction();\n\treturn false;\n}\n\nbool VariableDeclaration::hasReferenceOrMappingType() const\n{\n\tsolAssert(typeName().annotation().type, \"Can only be called after reference resolution\");\n\tType const* type = typeName().annotation().type;\n\treturn type->category() == Type::Category::Mapping || dynamic_cast<ReferenceType const*>(type);\n}\n\nbool VariableDeclaration::isStateVariable() const\n{\n\treturn dynamic_cast<ContractDefinition const*>(scope());\n}\n\nbool VariableDeclaration::isFileLevelVariable() const\n{\n\treturn dynamic_cast<SourceUnit const*>(scope());\n}\n\nstd::set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() const\n{\n\tusing Location = VariableDeclaration::Location;\n\n\tif (isStateVariable())\n\t\treturn std::set<Location>{Location::Unspecified, Location::Transient};\n\telse if (!hasReferenceOrMappingType() || isEventOrErrorParameter())\n\t\treturn std::set<Location>{ Location::Unspecified };\n\telse if (isCallableOrCatchParameter())\n\t{\n\t\tstd::set<Location> locations{ Location::Memory };\n\t\tif (\n\t\t\tisConstructorParameter() ||\n\t\t\tisInternalCallableParameter() ||\n\t\t\tisLibraryFunctionParameter()\n\t\t)\n\t\t\tlocations.insert(Location::Storage);\n\t\tif (!isTryCatchParameter() && !isConstructorParameter())\n\t\t\tlocations.insert(Location::CallData);\n\n\t\treturn locations;\n\t}\n\telse if (isLocalVariable())\n\t\t// Further restrictions will be imposed later on.\n\t\treturn std::set<Location>{ Location::Memory, Location::Storage, Location::CallData };\n\telse\n\t\t// Struct members etc.\n\t\treturn std::set<Location>{ Location::Unspecified };\n}\n\nstd::string VariableDeclaration::externalIdentifierHex() const\n{\n\tsolAssert(isStateVariable() && isPublic(), \"Can only be called for public state variables\");\n\treturn TypeProvider::function(*this)->externalIdentifierHex();\n}\n\nType const* VariableDeclaration::type() const\n{\n\treturn annotation().type;\n}\n\nFunctionTypePointer VariableDeclaration::functionType(bool _internal) const\n{\n\tif (_internal)\n\t\treturn nullptr;\n\tswitch (visibility())\n\t{\n\tcase Visibility::Default:\n\t\tsolAssert(false, \"visibility() should not return Default\");\n\tcase Visibility::Private:\n\tcase Visibility::Internal:\n\t\treturn nullptr;\n\tcase Visibility::Public:\n\tcase Visibility::External:\n\t\treturn TypeProvider::function(*this);\n\t}\n\n\t// To make the compiler happy\n\treturn nullptr;\n}\n\nVariableDeclarationAnnotation& VariableDeclaration::annotation() const\n{\n\treturn initAnnotation<VariableDeclarationAnnotation>();\n}\n\nStatementAnnotation& Statement::annotation() const\n{\n\treturn initAnnotation<StatementAnnotation>();\n}\n\nInlineAssemblyAnnotation& InlineAssembly::annotation() const\n{\n\treturn initAnnotation<InlineAssemblyAnnotation>();\n}\n\nBlockAnnotation& Block::annotation() const\n{\n\treturn initAnnotation<BlockAnnotation>();\n}\n\nTryCatchClauseAnnotation& TryCatchClause::annotation() const\n{\n\treturn initAnnotation<TryCatchClauseAnnotation>();\n}\n\nForStatementAnnotation& ForStatement::annotation() const\n{\n\treturn initAnnotation<ForStatementAnnotation>();\n}\n\nReturnAnnotation& Return::annotation() const\n{\n\treturn initAnnotation<ReturnAnnotation>();\n}\n\nExpressionAnnotation& Expression::annotation() const\n{\n\treturn initAnnotation<ExpressionAnnotation>();\n}\n\nMemberAccessAnnotation& MemberAccess::annotation() const\n{\n\treturn initAnnotation<MemberAccessAnnotation>();\n}\n\nOperationAnnotation& UnaryOperation::annotation() const\n{\n\treturn initAnnotation<OperationAnnotation>();\n}\n\nFunctionType const* UnaryOperation::userDefinedFunctionType() const\n{\n\tif (*annotation().userDefinedFunction == nullptr)\n\t\treturn nullptr;\n\n\tFunctionDefinition const* userDefinedFunction = *annotation().userDefinedFunction;\n\treturn dynamic_cast<FunctionType const*>(\n\t\tuserDefinedFunction->libraryFunction() ?\n\t\tuserDefinedFunction->typeViaContractName() :\n\t\tuserDefinedFunction->type()\n\t);\n}\n\nFunctionType const* BinaryOperation::userDefinedFunctionType() const\n{\n\tif (*annotation().userDefinedFunction == nullptr)\n\t\treturn nullptr;\n\n\tFunctionDefinition const* userDefinedFunction = *annotation().userDefinedFunction;\n\treturn dynamic_cast<FunctionType const*>(\n\t\tuserDefinedFunction->libraryFunction() ?\n\t\tuserDefinedFunction->typeViaContractName() :\n\t\tuserDefinedFunction->type()\n\t);\n}\n\nBinaryOperationAnnotation& BinaryOperation::annotation() const\n{\n\treturn initAnnotation<BinaryOperationAnnotation>();\n}\n\nFunctionCallAnnotation& FunctionCall::annotation() const\n{\n\treturn initAnnotation<FunctionCallAnnotation>();\n}\n\nstd::vector<ASTPointer<Expression const>> FunctionCall::sortedArguments() const\n{\n\t// normal arguments\n\tif (m_names.empty())\n\t\treturn arguments();\n\n\t// named arguments\n\tFunctionTypePointer functionType;\n\tif (*annotation().kind == FunctionCallKind::StructConstructorCall)\n\t{\n\t\tauto const& type = dynamic_cast<TypeType const&>(*m_expression->annotation().type);\n\t\tauto const& structType = dynamic_cast<StructType const&>(*type.actualType());\n\t\tfunctionType = structType.constructorType();\n\t}\n\telse\n\t\tfunctionType = dynamic_cast<FunctionType const*>(m_expression->annotation().type);\n\n\tstd::vector<ASTPointer<Expression const>> sorted;\n\tfor (auto const& parameterName: functionType->parameterNames())\n\t{\n\t\tbool found = false;\n\t\tfor (size_t j = 0; j < m_names.size() && !found; j++)\n\t\t\tif ((found = (parameterName == *m_names.at(j))))\n\t\t\t\t// we found the actual parameter position\n\t\t\t\tsorted.push_back(m_arguments.at(j));\n\t\tsolAssert(found, \"\");\n\t}\n\n\tif (!functionType->takesArbitraryParameters())\n\t{\n\t\tsolAssert(m_arguments.size() == functionType->parameterTypes().size(), \"\");\n\t\tsolAssert(m_arguments.size() == m_names.size(), \"\");\n\t\tsolAssert(m_arguments.size() == sorted.size(), \"\");\n\t}\n\n\treturn sorted;\n}\n\nIdentifierAnnotation& Identifier::annotation() const\n{\n\treturn initAnnotation<IdentifierAnnotation>();\n}\n\nASTString Literal::valueWithoutUnderscores() const\n{\n\treturn boost::erase_all_copy(value(), \"_\");\n}\n\nbool Literal::isHexNumber() const\n{\n\tif (token() != Token::Number)\n\t\treturn false;\n\treturn boost::starts_with(value(), \"0x\");\n}\n\nbool Literal::looksLikeAddress() const\n{\n\tif (subDenomination() != SubDenomination::None)\n\t\treturn false;\n\n\tif (!isHexNumber())\n\t\treturn false;\n\n\treturn abs(int(valueWithoutUnderscores().length()) - 42) <= 1;\n}\n\nbool Literal::passesAddressChecksum() const\n{\n\tsolAssert(isHexNumber(), \"Expected hex number\");\n\treturn util::passesAddressChecksum(valueWithoutUnderscores(), true);\n}\n\nstd::string Literal::getChecksummedAddress() const\n{\n\tsolAssert(isHexNumber(), \"Expected hex number\");\n\t/// Pad literal to be a proper hex address.\n\tstd::string address = valueWithoutUnderscores().substr(2);\n\tif (address.length() > 40)\n\t\treturn std::string();\n\taddress.insert(address.begin(), 40 - address.size(), '0');\n\treturn util::getChecksummedAddress(address);\n}\n\nTryCatchClause const* TryStatement::successClause() const\n{\n\tsolAssert(m_clauses.size() > 0, \"\");\n\treturn m_clauses[0].get();\n}\n\nTryCatchClause const* TryStatement::panicClause() const {\n\treturn findClause(m_clauses, \"Panic\");\n}\n\nTryCatchClause const* TryStatement::errorClause() const {\n\treturn findClause(m_clauses, \"Error\");\n}\n\nTryCatchClause const* TryStatement::fallbackClause() const {\n\treturn findClause(m_clauses);\n}\n\n/// Experimental Solidity nodes\n/// @{\nTypeClassDefinitionAnnotation& TypeClassDefinition::annotation() const\n{\n\treturn initAnnotation<TypeClassDefinitionAnnotation>();\n}\nTypeDeclarationAnnotation& TypeDefinition::annotation() const\n{\n\treturn initAnnotation<TypeDeclarationAnnotation>();\n}\n/// @}\n"
  },
  {
    "path": "libsolidity/ast/AST.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity abstract syntax tree.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/Types.h>\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <libsolidity/ast/ASTEnums.h>\n#include <libsolidity/parsing/Token.h>\n\n#include <liblangutil/SourceLocation.h>\n#include <libevmasm/Instruction.h>\n#include <libsolutil/FixedHash.h>\n#include <libsolutil/LazyInit.h>\n#include <libsolutil/Visitor.h>\n#include <libsolutil/JSON.h>\n\n#include <range/v3/view/subrange.hpp>\n#include <range/v3/view/map.hpp>\n\n#include <memory>\n#include <optional>\n#include <string>\n#include <utility>\n#include <vector>\n\nnamespace solidity::yul\n{\n// Forward-declaration to <yul/AST.h>\nclass AST;\nclass Dialect;\n}\n\nnamespace solidity::frontend\n{\n\nclass ASTVisitor;\nclass ASTConstVisitor;\n\n\n/**\n * The root (abstract) class of the AST inheritance tree.\n * It is possible to traverse all direct and indirect children of an AST node by calling\n * accept, providing an ASTVisitor.\n */\nclass ASTNode\n{\npublic:\n\t/// Noncopyable.\n\tASTNode(ASTNode const&) = delete;\n\tASTNode& operator=(ASTNode const&) = delete;\n\n\tusing CompareByID = frontend::ASTCompareByID<ASTNode>;\n\tusing SourceLocation = langutil::SourceLocation;\n\n\texplicit ASTNode(int64_t _id, SourceLocation _location);\n\tvirtual ~ASTNode() {}\n\n\t/// @returns an identifier of this AST node that is unique for a single compilation run.\n\tint64_t id() const { return int64_t(m_id); }\n\n\tvirtual void accept(ASTVisitor& _visitor) = 0;\n\tvirtual void accept(ASTConstVisitor& _visitor) const = 0;\n\ttemplate <class T>\n\tstatic void listAccept(std::vector<T> const& _list, ASTVisitor& _visitor)\n\t{\n\t\tfor (T const& element: _list)\n\t\t{\n\t\t\tsolAssert(element);\n\t\t\telement->accept(_visitor);\n\t\t}\n\t}\n\ttemplate <class T>\n\tstatic void listAccept(std::vector<T> const& _list, ASTConstVisitor& _visitor)\n\t{\n\t\tfor (T const& element: _list)\n\t\t{\n\t\t\tsolAssert(element);\n\t\t\telement->accept(_visitor);\n\t\t}\n\t}\n\n\t/// @returns a copy of the vector containing only the nodes which derive from T.\n\ttemplate <class T>\n\tstatic std::vector<T const*> filteredNodes(std::vector<ASTPointer<ASTNode>> const& _nodes);\n\n\t/// Extracts the referenced declaration from all nodes whose annotations support\n\t/// `referencedDeclaration`.\n\tstatic Declaration const* referencedDeclaration(Expression const& _expression);\n\t/// Performs potential super or virtual lookup for a function call based on the most derived contract.\n\tstatic FunctionDefinition const* resolveFunctionCall(FunctionCall const& _functionCall, ContractDefinition const* _mostDerivedContract);\n\n\t/// Returns the source code location of this node.\n\tSourceLocation const& location() const { return m_location; }\n\n\t///@todo make this const-safe by providing a different way to access the annotation\n\tvirtual ASTAnnotation& annotation() const;\n\n\t///@{\n\t///@name equality operators\n\t/// Equality relies on the fact that nodes cannot be copied.\n\tbool operator==(ASTNode const& _other) const { return this == &_other; }\n\tbool operator!=(ASTNode const& _other) const { return !operator==(_other); }\n\t///@}\n\n\tvirtual bool experimentalSolidityOnly() const { return false; }\n\nprotected:\n\tsize_t const m_id = 0;\n\n\ttemplate <class T>\n\tT& initAnnotation() const\n\t{\n\t\tif (!m_annotation)\n\t\t\tm_annotation = std::make_unique<T>();\n\t\treturn dynamic_cast<T&>(*m_annotation);\n\t}\n\nprivate:\n\t/// Annotation - is specialised in derived classes, is created upon request (because of polymorphism).\n\tmutable std::unique_ptr<ASTAnnotation> m_annotation;\n\tSourceLocation m_location;\n};\n\ntemplate <class T>\nstd::vector<T const*> ASTNode::filteredNodes(std::vector<ASTPointer<ASTNode>> const& _nodes)\n{\n\tstd::vector<T const*> ret;\n\tfor (auto const& n: _nodes)\n\t\tif (auto const* nt = dynamic_cast<T const*>(n.get()))\n\t\t\tret.push_back(nt);\n\treturn ret;\n}\n\n/**\n * Abstract marker class that specifies that this AST node opens a scope.\n */\nclass ScopeOpener\n{\npublic:\n\tvirtual ~ScopeOpener() = default;\n};\n\n/**\n * Source unit containing import directives and contract definitions.\n */\nclass SourceUnit: public ASTNode, public ScopeOpener\n{\npublic:\n\tSourceUnit(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tstd::optional<std::string> _licenseString,\n\t\tstd::vector<ASTPointer<ASTNode>> _nodes,\n\t\tbool _experimentalSolidity\n\t):\n\t\tASTNode(_id, _location),\n\t\tm_licenseString(std::move(_licenseString)),\n\t\tm_nodes(std::move(_nodes)),\n\t\tm_experimentalSolidity(_experimentalSolidity)\n\t{}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\tSourceUnitAnnotation& annotation() const override;\n\n\tstd::optional<std::string> const& licenseString() const { return m_licenseString; }\n\tstd::vector<ASTPointer<ASTNode>> nodes() const { return m_nodes; }\n\n\t/// @returns a set of referenced SourceUnits. Recursively if @a _recurse is true.\n\tstd::set<SourceUnit const*> referencedSourceUnits(bool _recurse = false, std::set<SourceUnit const*> _skipList = std::set<SourceUnit const*>()) const;\n\tbool experimentalSolidity() const { return m_experimentalSolidity; }\n\nprivate:\n\tvoid referencedSourceUnits(\n\t\tstd::set<SourceUnit const*>& _referencedSourceUnits,\n\t\tbool _recurse,\n\t\tstd::set<SourceUnit const*>& _skipList\n\t) const;\n\n\tstd::optional<std::string> m_licenseString;\n\tstd::vector<ASTPointer<ASTNode>> m_nodes;\n\tbool m_experimentalSolidity = false;\n};\n\n/**\n * Abstract class that is added to each AST node that is stored inside a scope\n * (including scopes).\n */\nclass Scopable\n{\npublic:\n\tvirtual ~Scopable() = default;\n\t/// @returns the scope this declaration resides in. Can be nullptr if it is the global scope.\n\t/// Available only after name and type resolution step.\n\tASTNode const* scope() const { return annotation().scope; }\n\n\t/// @returns the source unit this scopable is present in.\n\tSourceUnit const& sourceUnit() const;\n\n\t/// @returns the function or modifier definition this scopable is present in or nullptr.\n\tCallableDeclaration const* functionOrModifierDefinition() const;\n\n\t/// @returns the source name this scopable is present in.\n\t/// Can be combined with annotation().canonicalName (if present) to form a globally unique name.\n\tstd::string sourceUnitName() const;\n\n\tvirtual ScopableAnnotation& annotation() const = 0;\n};\n\n/**\n * Abstract AST class for a declaration (contract, function, struct, variable, import directive).\n */\nclass Declaration: public ASTNode, public Scopable\n{\npublic:\n\n\tstatic std::string visibilityToString(Visibility _visibility)\n\t{\n\t\tswitch (_visibility)\n\t\t{\n\t\tcase Visibility::Public:\n\t\t\treturn \"public\";\n\t\tcase Visibility::Internal:\n\t\t\treturn \"internal\";\n\t\tcase Visibility::Private:\n\t\t\treturn \"private\";\n\t\tcase Visibility::External:\n\t\t\treturn \"external\";\n\t\tdefault:\n\t\t\tsolAssert(false, \"Invalid visibility specifier.\");\n\t\t}\n\t\treturn std::string();\n\t}\n\n\tDeclaration(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> _name,\n\t\tSourceLocation _nameLocation,\n\t\tVisibility _visibility = Visibility::Default\n\t):\n\t\tASTNode(_id, _location), m_name(std::move(_name)), m_nameLocation(std::move(_nameLocation)), m_visibility(_visibility) {}\n\n\t/// @returns the declared name.\n\tASTString const& name() const { return *m_name; }\n\n\t/// @returns the location of the declared name itself or empty location if not available or unknown.\n\tSourceLocation const& nameLocation() const noexcept { return m_nameLocation; }\n\n\tbool noVisibilitySpecified() const { return m_visibility == Visibility::Default; }\n\tVisibility visibility() const { return m_visibility == Visibility::Default ? defaultVisibility() : m_visibility; }\n\tbool isPublic() const { return visibility() >= Visibility::Public; }\n\tvirtual bool isVisibleInContract() const { return visibility() != Visibility::External; }\n\tvirtual bool isVisibleInDerivedContracts() const { return isVisibleInContract() && visibility() >= Visibility::Internal; }\n\tbool isVisibleAsLibraryMember() const { return visibility() >= Visibility::Internal; }\n\tvirtual bool isVisibleViaContractTypeAccess() const { return false; }\n\n\tvirtual bool isLValue() const { return false; }\n\tvirtual bool isPartOfExternalInterface() const { return false; }\n\n\t/// @returns true if this is a declaration of an enum member.\n\tbool isEnumValue() const;\n\t/// @returns true if this is a declaration of a struct member.\n\tbool isStructMember() const;\n\t/// @returns true if this is a declaration of a parameter of an event.\n\tbool isEventOrErrorParameter() const;\n\n\t/// @returns false if the declaration can never be referenced without being qualified with a scope.\n\t/// Usually the name alone can be used to refer to the corresponding entity.\n\t/// But, for example, struct member names or enum member names always require a prefix.\n\t/// Another example is event parameter names, which do not participate in any proper scope.\n\tbool isVisibleAsUnqualifiedName() const;\n\n\t/// @returns the type of expressions referencing this declaration.\n\t/// This can only be called once types of variable declarations have already been resolved.\n\tvirtual Type const* type() const = 0;\n\n\t/// @returns the type for members of the containing contract type that refer to this declaration.\n\t/// This can only be called once types of variable declarations have already been resolved.\n\tvirtual Type const* typeViaContractName() const { return type(); }\n\n\t/// @param _internal false indicates external interface is concerned, true indicates internal interface is concerned.\n\t/// @returns null when it is not accessible as a function.\n\tvirtual FunctionTypePointer functionType(bool /*_internal*/) const { return {}; }\n\n\tDeclarationAnnotation& annotation() const override;\n\nprotected:\n\tvirtual Visibility defaultVisibility() const { return Visibility::Public; }\n\nprivate:\n\tASTPointer<ASTString> m_name;\n\tSourceLocation m_nameLocation;\n\tVisibility m_visibility;\n};\n\n/**\n * Pragma directive, only version requirements in the form `pragma solidity \"^0.4.0\";` are\n * supported for now.\n */\nclass PragmaDirective: public ASTNode\n{\npublic:\n\tPragmaDirective(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tstd::vector<Token> _tokens,\n\t\tstd::vector<ASTString> _literals\n\t): ASTNode(_id, _location), m_tokens(std::move(_tokens)), m_literals(std::move(_literals))\n\t{}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tstd::vector<Token> const& tokens() const { return m_tokens; }\n\tstd::vector<ASTString> const& literals() const { return m_literals; }\n\nprivate:\n\n\t/// Sequence of tokens following the \"pragma\" keyword.\n\tstd::vector<Token> m_tokens;\n\t/// Sequence of literals following the \"pragma\" keyword.\n\tstd::vector<ASTString> m_literals;\n};\n\n/**\n * Import directive for referencing other files / source objects.\n * Example: import \"abc.sol\" // imports all symbols of \"abc.sol\" into current scope\n * Source objects are identified by a string which can be a file name but does not have to be.\n * Other ways to use it:\n * import \"abc\" as x; // creates symbol \"x\" that contains all symbols in \"abc\"\n * import * as x from \"abc\"; // same as above\n * import {a as b, c} from \"abc\"; // creates new symbols \"b\" and \"c\" referencing \"a\" and \"c\" in \"abc\", respectively.\n */\nclass ImportDirective: public Declaration\n{\npublic:\n\tstruct SymbolAlias\n\t{\n\t\tASTPointer<Identifier> symbol;\n\t\tASTPointer<ASTString> alias;\n\t\tSourceLocation location;\n\t};\n\n\tusing SymbolAliasList = std::vector<SymbolAlias>;\n\n\tImportDirective(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> _path,\n\t\tASTPointer<ASTString> const& _unitAlias,\n\t\tSourceLocation _unitAliasLocation,\n\t\tSymbolAliasList _symbolAliases\n\t):\n\t\tDeclaration(_id, _location, _unitAlias, std::move(_unitAliasLocation)),\n\t\tm_path(std::move(_path)),\n\t\tm_symbolAliases(std::move(_symbolAliases))\n\t{ }\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tASTString const& path() const { return *m_path; }\n\tSymbolAliasList const& symbolAliases() const\n\t{\n\t\treturn m_symbolAliases;\n\t}\n\tImportAnnotation& annotation() const override;\n\n\tType const* type() const override;\n\nprivate:\n\tASTPointer<ASTString> m_path;\n\t/// The aliases for the specific symbols to import. If non-empty import the specific symbols.\n\t/// If the `alias` component is empty, import the identifier unchanged.\n\t/// If both m_unitAlias and m_symbolAlias are empty, import all symbols into the current scope.\n\tSymbolAliasList m_symbolAliases;\n};\n\n/**\n * Abstract class that is added to each AST node that can store local variables.\n * Local variables in functions are always added to functions, even though they are not\n * in scope for the whole function.\n */\nclass VariableScope\n{\npublic:\n\tvirtual ~VariableScope() = default;\n\tvoid addLocalVariable(VariableDeclaration const& _localVariable) { m_localVariables.push_back(&_localVariable); }\n\tstd::vector<VariableDeclaration const*> const& localVariables() const { return m_localVariables; }\n\nprivate:\n\tstd::vector<VariableDeclaration const*> m_localVariables;\n};\n\n/**\n * The doxygen-style, structured documentation class that represents an AST node.\n */\nclass StructuredDocumentation: public ASTNode\n{\npublic:\n\tStructuredDocumentation(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> _text\n\t): ASTNode(_id, _location), m_text(std::move(_text))\n\t{}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\t/// @return A shared pointer of an ASTString.\n\t/// Contains doxygen-style, structured documentation that is parsed later on.\n\tASTPointer<ASTString> const& text() const { return m_text; }\n\nprivate:\n\tASTPointer<ASTString> m_text;\n};\n\n/**\n * Abstract class that is added to each AST node that can receive documentation.\n */\nclass Documented\n{\npublic:\n\tvirtual ~Documented() = default;\n\texplicit Documented(ASTPointer<ASTString> _documentation): m_documentation(std::move(_documentation)) {}\n\n\t/// @return A shared pointer of an ASTString.\n\t/// Can contain a nullptr in which case indicates absence of documentation\n\tASTPointer<ASTString> const& documentation() const { return m_documentation; }\n\nprotected:\n\tASTPointer<ASTString> m_documentation;\n};\n\n/**\n * Abstract class that is added to each AST node that can receive a structured documentation.\n */\nclass StructurallyDocumented\n{\npublic:\n\tvirtual ~StructurallyDocumented() = default;\n\texplicit StructurallyDocumented(ASTPointer<StructuredDocumentation> _documentation): m_documentation(std::move(_documentation)) {}\n\n\t/// @return A shared pointer of a FormalDocumentation.\n\t/// Can contain a nullptr in which case indicates absence of documentation\n\tASTPointer<StructuredDocumentation> const& documentation() const { return m_documentation; }\n\nprotected:\n\tASTPointer<StructuredDocumentation> m_documentation;\n};\n\n\n/**\n * Abstract class that is added to AST nodes that can be marked as not being fully implemented\n */\nclass ImplementationOptional\n{\npublic:\n\tvirtual ~ImplementationOptional() = default;\n\texplicit ImplementationOptional(bool _implemented): m_implemented(_implemented) {}\n\n\t/// @return whether this node is fully implemented or not\n\tbool isImplemented() const { return m_implemented; }\n\nprotected:\n\tbool m_implemented;\n};\n\n/// @}\n\n/**\n * Definition of a contract or library. This is the only AST nodes where child nodes are not visited in\n * document order. It first visits all struct declarations, then all variable declarations and\n * finally all function declarations.\n */\nclass ContractDefinition: public Declaration, public StructurallyDocumented, public ScopeOpener\n{\npublic:\n\tContractDefinition(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _name,\n\t\tSourceLocation _nameLocation,\n\t\tASTPointer<StructuredDocumentation> const& _documentation,\n\t\tstd::vector<ASTPointer<InheritanceSpecifier>> _baseContracts,\n\t\tstd::vector<ASTPointer<ASTNode>> _subNodes,\n\t\tContractKind _contractKind = ContractKind::Contract,\n\t\tbool _abstract = false,\n\t\tASTPointer<StorageLayoutSpecifier> _storageLayoutSpecifier = nullptr\n\t):\n\t\tDeclaration(_id, _location, _name, std::move(_nameLocation)),\n\t\tStructurallyDocumented(_documentation),\n\t\tm_baseContracts(std::move(_baseContracts)),\n\t\tm_subNodes(std::move(_subNodes)),\n\t\tm_contractKind(_contractKind),\n\t\tm_abstract(_abstract),\n\t\tm_storageLayoutSpecifier(_storageLayoutSpecifier)\n\t{}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tstd::vector<ASTPointer<InheritanceSpecifier>> const& baseContracts() const { return m_baseContracts; }\n\tstd::vector<ASTPointer<ASTNode>> const& subNodes() const { return m_subNodes; }\n\tstd::vector<UsingForDirective const*> usingForDirectives() const { return filteredNodes<UsingForDirective>(m_subNodes); }\n\tstd::vector<StructDefinition const*> definedStructs() const { return filteredNodes<StructDefinition>(m_subNodes); }\n\tstd::vector<EnumDefinition const*> definedEnums() const { return filteredNodes<EnumDefinition>(m_subNodes); }\n\tstd::vector<VariableDeclaration const*> stateVariables() const { return filteredNodes<VariableDeclaration>(m_subNodes); }\n\tstd::vector<ModifierDefinition const*> functionModifiers() const { return filteredNodes<ModifierDefinition>(m_subNodes); }\n\tstd::vector<FunctionDefinition const*> definedFunctions() const { return filteredNodes<FunctionDefinition>(m_subNodes); }\n\t/// @returns a view<FunctionDefinition const*> of all functions\n\t/// defined in this contract of the given name (excluding inherited functions).\n\tauto definedFunctions(std::string const& _name) const\n\t{\n\t\tauto&& [b, e] = definedFunctionsByName().equal_range(_name);\n\t\treturn ranges::subrange<decltype(b)>(b, e) | ranges::views::values;\n\t}\n\tstd::vector<EventDefinition const*> events() const { return filteredNodes<EventDefinition>(m_subNodes); }\n\tstd::vector<EventDefinition const*> const& definedInterfaceEvents() const;\n\tstd::vector<EventDefinition const*> const usedInterfaceEvents() const;\n\t/// @return all events defined in this contract and its base contracts and all events\n\t/// that are emitted during the execution of the contract.\n\t/// @param _requireCallGraph if false, do not fail if the call graph has not been computed yet.\n\tstd::vector<EventDefinition const*> interfaceEvents(bool _requireCallGraph = true) const;\n\t/// @returns all errors defined in this contract or any base contract\n\t/// and all errors referenced during execution.\n\t/// @param _requireCallGraph if false, do not fail if the call graph has not been computed yet.\n\tstd::vector<ErrorDefinition const*> interfaceErrors(bool _requireCallGraph = true) const;\n\tbool isInterface() const { return m_contractKind == ContractKind::Interface; }\n\tbool isLibrary() const { return m_contractKind == ContractKind::Library; }\n\n\t/// @returns true, if the contract derives from @arg _base.\n\tbool derivesFrom(ContractDefinition const& _base) const;\n\n\t/// @returns a map of canonical function signatures to FunctionDefinitions\n\t/// as intended for use by the ABI.\n\tstd::map<util::FixedHash<4>, FunctionTypePointer> interfaceFunctions(bool _includeInheritedFunctions = true) const;\n\tstd::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>> const& interfaceFunctionList(bool _includeInheritedFunctions = true) const;\n\t/// @returns the EIP-165 compatible interface identifier. This will exclude inherited functions.\n\tuint32_t interfaceId() const;\n\n\t/// @returns a list of all declarations in this contract\n\tstd::vector<Declaration const*> declarations() const { return filteredNodes<Declaration>(m_subNodes); }\n\n\t/// Returns the constructor or nullptr if no constructor was specified.\n\tFunctionDefinition const* constructor() const;\n\t/// @returns true iff the contract can be deployed, i.e. is not abstract and has a\n\t/// public constructor.\n\t/// Should only be called after the type checker has run.\n\tbool canBeDeployed() const;\n\t/// Returns the fallback function or nullptr if no fallback function was specified.\n\tFunctionDefinition const* fallbackFunction() const;\n\n\t/// Returns the ether receiver function or nullptr if no receive function was specified.\n\tFunctionDefinition const* receiveFunction() const;\n\n\tstd::string fullyQualifiedName() const { return sourceUnitName() + \":\" + name(); }\n\n\tType const* type() const override;\n\n\tContractDefinitionAnnotation& annotation() const override;\n\n\tContractKind contractKind() const { return m_contractKind; }\n\n\tbool abstract() const { return m_abstract; }\n\n\tStorageLayoutSpecifier const* storageLayoutSpecifier() const { return m_storageLayoutSpecifier.get(); }\n\tStorageLayoutSpecifier* storageLayoutSpecifier() { return m_storageLayoutSpecifier.get(); }\n\n\tContractDefinition const* superContract(ContractDefinition const& _mostDerivedContract) const;\n\t/// @returns the next constructor in the inheritance hierarchy.\n\tFunctionDefinition const* nextConstructor(ContractDefinition const& _mostDerivedContract) const;\n\nprivate:\n\tstd::multimap<std::string, FunctionDefinition const*> const& definedFunctionsByName() const;\n\n\tstd::vector<ASTPointer<InheritanceSpecifier>> m_baseContracts;\n\tstd::vector<ASTPointer<ASTNode>> m_subNodes;\n\tContractKind m_contractKind;\n\tbool m_abstract{false};\n\tASTPointer<StorageLayoutSpecifier> m_storageLayoutSpecifier;\n\n\tutil::LazyInit<std::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>>> m_interfaceFunctionList[2];\n\tutil::LazyInit<std::vector<EventDefinition const*>> m_interfaceEvents;\n\tutil::LazyInit<std::multimap<std::string, FunctionDefinition const*>> m_definedFunctionsByName;\n};\n\n\nclass StorageLayoutSpecifier : public ASTNode\n{\npublic:\n\tStorageLayoutSpecifier(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<Expression> _baseSlotExpression\n\t);\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& baseSlotExpression() const { solAssert(m_baseSlotExpression); return *m_baseSlotExpression; }\n\tStorageLayoutSpecifierAnnotation& annotation() const override;\n\nprivate:\n\tASTPointer<Expression> m_baseSlotExpression;\n};\n\n/**\n * A sequence of identifiers separated by dots used outside the expression context. Inside the expression context, this is a sequence of Identifier and MemberAccess.\n */\nclass IdentifierPath: public ASTNode\n{\npublic:\n\tIdentifierPath(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tstd::vector<ASTString> _path,\n\t\tstd::vector<SourceLocation> _pathLocations\n\t):\n\t\tASTNode(_id, _location), m_path(std::move(_path)), m_pathLocations(std::move(_pathLocations))\n\t{\n\t\tsolAssert(m_pathLocations.size() == m_path.size());\n\t}\n\n\tstd::vector<ASTString> const& path() const { return m_path; }\n\tstd::vector<SourceLocation > const& pathLocations() const { return m_pathLocations; }\n\tIdentifierPathAnnotation& annotation() const override\n\t{\n\t\treturn initAnnotation<IdentifierPathAnnotation>();\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\nprivate:\n\tstd::vector<ASTString> m_path;\n\t// Corresponding locations for m_path. Array has same length and indices as m_path.\n\tstd::vector<SourceLocation> m_pathLocations;\n};\n\nclass InheritanceSpecifier: public ASTNode\n{\npublic:\n\tInheritanceSpecifier(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<IdentifierPath> _baseName,\n\t\tstd::unique_ptr<std::vector<ASTPointer<Expression>>> _arguments\n\t):\n\t\tASTNode(_id, _location), m_baseName(std::move(_baseName)), m_arguments(std::move(_arguments))\n\t{\n\t\tsolAssert(m_baseName != nullptr, \"Name cannot be null.\");\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tIdentifierPath const& name() const { return *m_baseName; }\n\t// Returns nullptr if no argument list was given (``C``).\n\t// If an argument list is given (``C(...)``), the arguments are returned\n\t// as a vector of expressions. Note that this vector can be empty (``C()``).\n\tstd::vector<ASTPointer<Expression>> const* arguments() const { return m_arguments.get(); }\n\nprivate:\n\tASTPointer<IdentifierPath> m_baseName;\n\tstd::unique_ptr<std::vector<ASTPointer<Expression>>> m_arguments;\n};\n\n/**\n * Using for directive:\n *\n * 1. `using LibraryName for T` attaches all functions from the library `LibraryName` to the type `T`.\n * 2. `using LibraryName for *` attaches to all types.\n * 3. `using {f1, f2, ..., fn} for T` attaches the functions `f1`, `f2`, ..., `fn`, respectively to `T`.\n * 4. `using {f1 as op1, f2 as op2, ..., fn as opn} for T` implements operator `opn` for type `T` with function `fn`.\n *\n * For version 3, T has to be implicitly convertible to the first parameter type of\n * all functions, and this is checked at the point of the using statement. For versions 1 and\n * 2, this check is only done when a function is called.\n *\n * For version 4, T has to be user-defined value type and the function must be pure.\n * All parameters and return value of all the functions have to be of type T.\n * This version can be combined with version 3 - a single directive may attach functions to the\n * type and define operators on it at the same time.\n *\n * Finally, `using {f1, f2, ..., fn} for T global` is also valid at file level, as long as T is\n * a user-defined type defined in the same file at file level. In this case, the methods are\n * attached to all objects of that type regardless of scope.\n */\nclass UsingForDirective: public ASTNode\n{\npublic:\n\tUsingForDirective(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tstd::vector<ASTPointer<IdentifierPath>> _functionsOrLibrary,\n\t\tstd::vector<std::optional<Token>> _operators,\n\t\tbool _usesBraces,\n\t\tASTPointer<TypeName> _typeName,\n\t\tbool _global\n\t):\n\t\tASTNode(_id, _location),\n\t\tm_functionsOrLibrary(std::move(_functionsOrLibrary)),\n\t\tm_operators(std::move(_operators)),\n\t\tm_usesBraces(_usesBraces),\n\t\tm_typeName(std::move(_typeName)),\n\t\tm_global{_global}\n\t{\n\t\tsolAssert(m_functionsOrLibrary.size() == m_operators.size());\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\t/// @returns the type name the library is attached to, null for `*`.\n\tTypeName const* typeName() const { return m_typeName.get(); }\n\n\t/// @returns a list of functions or the single library.\n\tstd::vector<ASTPointer<IdentifierPath>> const& functionsOrLibrary() const { return m_functionsOrLibrary; }\n\tstd::vector<std::pair<ASTPointer<IdentifierPath>, std::optional<Token>>> functionsAndOperators() const;\n\tbool usesBraces() const { return m_usesBraces; }\n\tbool global() const { return m_global; }\n\nprivate:\n\t/// Either the single library or a list of functions.\n\tstd::vector<ASTPointer<IdentifierPath>> m_functionsOrLibrary;\n\t/// Operators, the functions from @a m_functionsOrLibrary implement.\n\t/// A token if the corresponding element in m_functionsOrLibrary\n\t/// defines an operator, nullptr otherwise.\n\t/// Note that this vector size must be equal to m_functionsOrLibrary size.\n\tstd::vector<std::optional<Token>> m_operators;\n\tbool m_usesBraces;\n\tASTPointer<TypeName> m_typeName;\n\tbool m_global = false;\n};\n\nclass StructDefinition: public Declaration, public StructurallyDocumented, public ScopeOpener\n{\npublic:\n\tStructDefinition(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _name,\n\t\tSourceLocation _nameLocation,\n\t\tstd::vector<ASTPointer<VariableDeclaration>> _members,\n\t\tASTPointer<StructuredDocumentation> _documentation\n\t):\n\t\tDeclaration(_id, _location, _name, std::move(_nameLocation)),\n\t\tStructurallyDocumented(std::move(_documentation)),\n\t\tm_members(std::move(_members))\n\t{}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tstd::vector<ASTPointer<VariableDeclaration>> const& members() const { return m_members; }\n\n\tType const* type() const override;\n\n\tbool isVisibleInDerivedContracts() const override { return true; }\n\tbool isVisibleViaContractTypeAccess() const override { return true; }\n\n\tStructDeclarationAnnotation& annotation() const override;\n\nprivate:\n\tstd::vector<ASTPointer<VariableDeclaration>> m_members;\n};\n\nclass EnumDefinition: public Declaration, public StructurallyDocumented, public ScopeOpener\n{\npublic:\n\tEnumDefinition(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _name,\n\t\tSourceLocation _nameLocation,\n\t\tstd::vector<ASTPointer<EnumValue>> _members,\n\t\tASTPointer<StructuredDocumentation> _documentation\n\t):\n\t\tDeclaration(_id, _location, _name, std::move(_nameLocation)),\n\t\tStructurallyDocumented(std::move(_documentation)),\n\t\tm_members(std::move(_members))\n\t{}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tbool isVisibleInDerivedContracts() const override { return true; }\n\tbool isVisibleViaContractTypeAccess() const override { return true; }\n\n\tstd::vector<ASTPointer<EnumValue>> const& members() const { return m_members; }\n\n\tType const* type() const override;\n\n\tTypeDeclarationAnnotation& annotation() const override;\n\nprivate:\n\tstd::vector<ASTPointer<EnumValue>> m_members;\n};\n\n/**\n * Declaration of an Enum Value\n */\nclass EnumValue: public Declaration, public StructurallyDocumented\n{\npublic:\n\tEnumValue(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _name,\n\t\tASTPointer<StructuredDocumentation> _documentation\n\t):\n\t\tDeclaration(_id, _location, _name, _location),\n\t\tStructurallyDocumented(std::move(_documentation))\n\t{\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tType const* type() const override;\n};\n\n/**\n * User defined value types, i.e., custom types, for example, `type MyInt is int`. Allows creating a\n * zero cost abstraction over value type with stricter type requirements.\n */\nclass UserDefinedValueTypeDefinition: public Declaration\n{\npublic:\n\tUserDefinedValueTypeDefinition(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> _name,\n\t\tSourceLocation _nameLocation,\n\t\tASTPointer<TypeName> _underlyingType\n\t):\n\t\tDeclaration(_id, _location, _name, std::move(_nameLocation), Visibility::Default),\n\t\tm_underlyingType(std::move(_underlyingType))\n\t{\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tType const* type() const override;\n\n\tTypeDeclarationAnnotation& annotation() const override;\n\n\tTypeName const* underlyingType() const { return m_underlyingType.get(); }\n\tbool isVisibleViaContractTypeAccess() const override { return true; }\n\nprivate:\n\t/// The name of the underlying type\n\tASTPointer<TypeName> m_underlyingType;\n};\n\n/**\n * Parameter list, used as function parameter list, return list and for try and catch.\n * None of the parameters is allowed to contain mappings (not even recursively\n * inside structs).\n */\nclass ParameterList: public ASTNode\n{\npublic:\n\tParameterList(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tstd::vector<ASTPointer<VariableDeclaration>> _parameters\n\t):\n\t\tASTNode(_id, _location), m_parameters(std::move(_parameters)) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tstd::vector<ASTPointer<VariableDeclaration>> const& parameters() const { return m_parameters; }\n\nprivate:\n\tstd::vector<ASTPointer<VariableDeclaration>> m_parameters;\n};\n\n/**\n * Base class for all nodes that define function-like objects, i.e. FunctionDefinition,\n * EventDefinition, ErrorDefinition and ModifierDefinition.\n */\nclass CallableDeclaration: public Declaration, public VariableScope\n{\npublic:\n\tCallableDeclaration(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _name,\n\t\tSourceLocation _nameLocation,\n\t\tVisibility _visibility,\n\t\tASTPointer<ParameterList> _parameters,\n\t\tbool _isVirtual = false,\n\t\tASTPointer<OverrideSpecifier> _overrides = nullptr,\n\t\tASTPointer<ParameterList> _returnParameters = ASTPointer<ParameterList>()\n\t):\n\t\tDeclaration(_id, _location, _name, std::move(_nameLocation), _visibility),\n\t\tm_parameters(std::move(_parameters)),\n\t\tm_overrides(std::move(_overrides)),\n\t\tm_returnParameters(std::move(_returnParameters)),\n\t\tm_isVirtual(_isVirtual)\n\t{\n\t}\n\n\tstd::vector<ASTPointer<VariableDeclaration>> const& parameters() const { return m_parameters->parameters(); }\n\tASTPointer<OverrideSpecifier> const& overrides() const { return m_overrides; }\n\tstd::vector<ASTPointer<VariableDeclaration>> const& returnParameters() const { return m_returnParameters->parameters(); }\n\tParameterList const& parameterList() const { return *m_parameters; }\n\tASTPointer<ParameterList> const& returnParameterList() const { return m_returnParameters; }\n\tbool markedVirtual() const { return m_isVirtual; }\n\tvirtual bool virtualSemantics() const { return markedVirtual(); }\n\n\tCallableDeclarationAnnotation& annotation() const override = 0;\n\n\t/// Performs virtual or super function/modifier lookup:\n\t/// If @a _searchStart is nullptr, performs virtual function lookup, i.e.\n\t/// searches the inheritance hierarchy of @a _mostDerivedContract towards the base\n\t/// and returns the first function/modifier definition that\n\t/// is overwritten by this callable.\n\t/// If @a _searchStart is non-null, starts searching only from that contract, but\n\t/// still in the hierarchy of @a _mostDerivedContract.\n\tvirtual CallableDeclaration const& resolveVirtual(\n\t\tContractDefinition const& _mostDerivedContract,\n\t\tContractDefinition const* _searchStart = nullptr\n\t) const = 0;\n\nprotected:\n\tASTPointer<ParameterList> m_parameters;\n\tASTPointer<OverrideSpecifier> m_overrides;\n\tASTPointer<ParameterList> m_returnParameters;\n\tbool m_isVirtual = false;\n};\n\n/**\n * Function override specifier. Consists of a single override keyword\n * potentially followed by a parenthesized list of base contract names.\n */\nclass OverrideSpecifier: public ASTNode\n{\npublic:\n\tOverrideSpecifier(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tstd::vector<ASTPointer<IdentifierPath>> _overrides\n\t):\n\t\tASTNode(_id, _location),\n\t\tm_overrides(std::move(_overrides))\n\t{\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\t/// @returns the list of specific overrides, if any\n\tstd::vector<ASTPointer<IdentifierPath>> const& overrides() const { return m_overrides; }\n\nprotected:\n\tstd::vector<ASTPointer<IdentifierPath>> m_overrides;\n};\n\nclass FunctionDefinition: public CallableDeclaration, public StructurallyDocumented, public ImplementationOptional, public ScopeOpener\n{\npublic:\n\tFunctionDefinition(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _name,\n\t\tSourceLocation const& _nameLocation,\n\t\tVisibility _visibility,\n\t\tStateMutability _stateMutability,\n\t\tbool _free,\n\t\tToken _kind,\n\t\tbool _isVirtual,\n\t\tASTPointer<OverrideSpecifier> const& _overrides,\n\t\tASTPointer<StructuredDocumentation> const& _documentation,\n\t\tASTPointer<ParameterList> const& _parameters,\n\t\tstd::vector<ASTPointer<ModifierInvocation>> _modifiers,\n\t\tASTPointer<ParameterList> const& _returnParameters,\n\t\tASTPointer<Block> const& _body,\n\t\tASTPointer<Expression> const& _experimentalReturnExpression = {}\n\t):\n\t\tCallableDeclaration(_id, _location, _name, _nameLocation, _visibility, _parameters, _isVirtual, _overrides, _returnParameters),\n\t\tStructurallyDocumented(_documentation),\n\t\tImplementationOptional(_body != nullptr),\n\t\tm_stateMutability(_stateMutability),\n\t\tm_free(_free),\n\t\tm_kind(_kind),\n\t\tm_functionModifiers(std::move(_modifiers)),\n\t\tm_body(_body),\n\t\tm_experimentalReturnExpression(_experimentalReturnExpression)\n\t{\n\t\tsolAssert(_kind == Token::Constructor || _kind == Token::Function || _kind == Token::Fallback || _kind == Token::Receive, \"\");\n\t\tsolAssert(isOrdinary() == !name().empty(), \"\");\n\t\t// TODO: assert _returnParameters implies non-experimental _experimentalReturnExpression implies experimental\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tStateMutability stateMutability() const { return m_stateMutability; }\n\tbool libraryFunction() const;\n\tbool isOrdinary() const { return m_kind == Token::Function; }\n\tbool isConstructor() const { return m_kind == Token::Constructor; }\n\tbool isFallback() const { return m_kind == Token::Fallback; }\n\tbool isReceive() const { return m_kind == Token::Receive; }\n\tbool isFree() const { return m_free; }\n\tToken kind() const { return m_kind; }\n\tbool isPayable() const { return m_stateMutability == StateMutability::Payable; }\n\tstd::vector<ASTPointer<ModifierInvocation>> const& modifiers() const { return m_functionModifiers; }\n\tBlock const& body() const { solAssert(m_body, \"\"); return *m_body; }\n\tVisibility defaultVisibility() const override;\n\tbool isVisibleInContract() const override\n\t{\n\t\treturn isOrdinary() && Declaration::isVisibleInContract();\n\t}\n\tbool isVisibleViaContractTypeAccess() const override\n\t{\n\t\tsolAssert(!isFree(), \"\");\n\t\treturn isOrdinary() && visibility() >= Visibility::Public;\n\t}\n\tbool isPartOfExternalInterface() const override { return isOrdinary() && isPublic(); }\n\n\t/// @returns the external signature of the function\n\t/// That consists of the name of the function followed by the types of the\n\t/// arguments separated by commas all enclosed in parentheses without any spaces.\n\tstd::string externalSignature() const;\n\n\t/// @returns the external identifier of this function (the hash of the signature) as a hex string.\n\tstd::string externalIdentifierHex() const;\n\n\tType const* type() const override;\n\tType const* typeViaContractName() const override;\n\n\t/// @param _internal false indicates external interface is concerned, true indicates internal interface is concerned.\n\t/// @returns null when it is not accessible as a function.\n\tFunctionTypePointer functionType(bool /*_internal*/) const override;\n\n\tFunctionDefinitionAnnotation& annotation() const override;\n\n\tbool virtualSemantics() const override\n\t{\n\t\treturn\n\t\t\tCallableDeclaration::virtualSemantics() ||\n\t\t\t(annotation().contract && annotation().contract->isInterface());\n\t}\n\n\tFunctionDefinition const& resolveVirtual(\n\t\tContractDefinition const& _mostDerivedContract,\n\t\tContractDefinition const* _searchStart = nullptr\n\t) const override;\n\n\tExpression const* experimentalReturnExpression() const { return m_experimentalReturnExpression.get(); }\n\nprivate:\n\tStateMutability m_stateMutability;\n\tbool m_free;\n\tToken const m_kind;\n\tstd::vector<ASTPointer<ModifierInvocation>> m_functionModifiers;\n\tASTPointer<Block> m_body;\n\tASTPointer<Expression> m_experimentalReturnExpression;\n};\n\n/**\n * Declaration of a variable. This can be used in various places, e.g. in function parameter\n * lists, struct definitions and even function bodies.\n */\nclass VariableDeclaration: public Declaration, public StructurallyDocumented\n{\npublic:\n\tenum Location { Unspecified, Storage, Transient, Memory, CallData };\n\tenum class Mutability { Mutable, Immutable, Constant };\n\tstatic std::string mutabilityToString(Mutability _mutability)\n\t{\n\t\tswitch (_mutability)\n\t\t{\n\t\tcase Mutability::Mutable: return \"mutable\";\n\t\tcase Mutability::Immutable: return \"immutable\";\n\t\tcase Mutability::Constant: return \"constant\";\n\t\t}\n\t\treturn {};\n\t}\n\n\tVariableDeclaration(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<TypeName> _type,\n\t\tASTPointer<ASTString> const& _name,\n\t\tSourceLocation _nameLocation,\n\t\tASTPointer<Expression> _value,\n\t\tVisibility _visibility,\n\t\tASTPointer<StructuredDocumentation> const _documentation = nullptr,\n\t\tbool _isIndexed = false,\n\t\tMutability _mutability = Mutability::Mutable,\n\t\tASTPointer<OverrideSpecifier> _overrides = nullptr,\n\t\tLocation _referenceLocation = Location::Unspecified,\n\t\tASTPointer<Expression> _typeExpression = {}\n\t):\n\t\tDeclaration(_id, _location, _name, std::move(_nameLocation), _visibility),\n\t\tStructurallyDocumented(std::move(_documentation)),\n\t\tm_typeName(std::move(_type)),\n\t\tm_value(std::move(_value)),\n\t\tm_isIndexed(_isIndexed),\n\t\tm_mutability(_mutability),\n\t\tm_overrides(std::move(_overrides)),\n\t\tm_location(_referenceLocation),\n\t\tm_typeExpression(std::move(_typeExpression))\n\t{\n\t\t// TODO: consider still asserting unless we are in experimental solidity.\n\t\t// solAssert(m_typeName, \"\"); solAssert(!m_typeExpression, \"\");\n\t}\n\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tbool hasTypeName() const { return m_typeName != nullptr; }\n\tTypeName const& typeName() const { return *m_typeName; }\n\tASTPointer<Expression> const& value() const { return m_value; }\n\n\tbool isLValue() const override;\n\tbool isPartOfExternalInterface() const override { return isPublic(); }\n\n\t/// @returns true iff this variable is the parameter (or return parameter) of a function\n\t/// (or function type name or event) or declared inside a function body.\n\tbool isLocalVariable() const;\n\t/// @returns true if this variable is a parameter or return parameter of a function.\n\tbool isCallableOrCatchParameter() const;\n\t/// @returns true if this variable is a return parameter of a function.\n\tbool isReturnParameter() const;\n\t/// @returns true if this variable is a parameter of the success or failure clause\n\t/// of a try/catch statement.\n\tbool isTryCatchParameter() const;\n\t/// @returns true if this variable is a local variable or return parameter.\n\tbool isLocalOrReturn() const;\n\t/// @returns true if this variable is a parameter (not return parameter) of an external function.\n\t/// This excludes parameters of external function type names.\n\tbool isExternalCallableParameter() const;\n\t/// @returns true if this variable is a parameter (not return parameter) of a public function.\n\tbool isPublicCallableParameter() const;\n\t/// @returns true if this variable is a parameter or return parameter of an internal function\n\t/// or a function type of internal visibility.\n\tbool isInternalCallableParameter() const;\n\t/// @returns true if this variable is the parameter of a constructor.\n\tbool isConstructorParameter() const;\n\t/// @returns true iff this variable is a parameter(or return parameter of a library function\n\tbool isLibraryFunctionParameter() const;\n\t/// @returns true if the type of the variable is a reference or mapping type, i.e.\n\t/// array, struct or mapping. These types can take a data location (and often require it).\n\t/// Can only be called after reference resolution.\n\tbool hasReferenceOrMappingType() const;\n\tbool isStateVariable() const;\n\tbool isFileLevelVariable() const;\n\tbool isIndexed() const { return m_isIndexed; }\n\tMutability mutability() const { return m_mutability; }\n\tbool isConstant() const { return m_mutability == Mutability::Constant; }\n\tbool immutable() const { return m_mutability == Mutability::Immutable; }\n\tASTPointer<OverrideSpecifier> const& overrides() const { return m_overrides; }\n\tLocation referenceLocation() const { return m_location; }\n\t/// @returns a set of allowed storage locations for the variable.\n\tstd::set<Location> allowedDataLocations() const;\n\n\t/// @returns the external identifier of this variable (the hash of the signature) as a hex string (works only for public state variables).\n\tstd::string externalIdentifierHex() const;\n\n\tType const* type() const override;\n\n\t/// @param _internal false indicates external interface is concerned, true indicates internal interface is concerned.\n\t/// @returns null when it is not accessible as a function.\n\tFunctionTypePointer functionType(bool /*_internal*/) const override;\n\n\tASTPointer<Expression> const& typeExpression() const { return m_typeExpression; }\n\tVariableDeclarationAnnotation& annotation() const override;\n\nprotected:\n\tVisibility defaultVisibility() const override { return Visibility::Internal; }\n\nprivate:\n\tASTPointer<TypeName> m_typeName;\n\t/// Initially assigned value, can be missing. For local variables, this is stored inside\n\t/// VariableDeclarationStatement and not here.\n\tASTPointer<Expression> m_value;\n\tbool m_isIndexed = false; ///< Whether this is an indexed variable (used by events).\n\t/// Whether the variable is \"constant\", \"immutable\" or non-marked (mutable).\n\tMutability m_mutability = Mutability::Mutable;\n\tASTPointer<OverrideSpecifier> m_overrides; ///< Contains the override specifier node\n\tLocation m_location = Location::Unspecified; ///< Location of the variable if it is of reference type.\n\tASTPointer<Expression> m_typeExpression;\n};\n\n/**\n * Definition of a function modifier.\n */\nclass ModifierDefinition: public CallableDeclaration, public StructurallyDocumented, public ImplementationOptional, public ScopeOpener\n{\npublic:\n\tModifierDefinition(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _name,\n\t\tSourceLocation _nameLocation,\n\t\tASTPointer<StructuredDocumentation> const& _documentation,\n\t\tASTPointer<ParameterList> const& _parameters,\n\t\tbool _isVirtual,\n\t\tASTPointer<OverrideSpecifier> const& _overrides,\n\t\tASTPointer<Block> const& _body\n\t):\n\t\tCallableDeclaration(_id, _location, _name, std::move(_nameLocation), Visibility::Internal, _parameters, _isVirtual, _overrides),\n\t\tStructurallyDocumented(_documentation),\n\t\tImplementationOptional(_body != nullptr),\n\t\tm_body(_body)\n\t{\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tBlock const& body() const { solAssert(m_body, \"\"); return *m_body; }\n\n\tType const* type() const override;\n\n\tVisibility defaultVisibility() const override { return Visibility::Internal; }\n\n\tModifierDefinitionAnnotation& annotation() const override;\n\n\tModifierDefinition const& resolveVirtual(\n\t\tContractDefinition const& _mostDerivedContract,\n\t\tContractDefinition const* _searchStart = nullptr\n\t) const override;\n\n\nprivate:\n\tASTPointer<Block> m_body;\n};\n\n/**\n * Invocation/usage of a modifier in a function header or a base constructor call.\n */\nclass ModifierInvocation: public ASTNode\n{\npublic:\n\tModifierInvocation(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<IdentifierPath> _name,\n\t\tstd::unique_ptr<std::vector<ASTPointer<Expression>>> _arguments\n\t):\n\t\tASTNode(_id, _location), m_modifierName(std::move(_name)), m_arguments(std::move(_arguments))\n\t{\n\t\tsolAssert(m_modifierName != nullptr, \"Name cannot be null.\");\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tIdentifierPath& name() const { return *m_modifierName; }\n\t// Returns nullptr if no argument list was given (``mod``).\n\t// If an argument list is given (``mod(...)``), the arguments are returned\n\t// as a vector of expressions. Note that this vector can be empty (``mod()``).\n\tstd::vector<ASTPointer<Expression>> const* arguments() const { return m_arguments.get(); }\n\nprivate:\n\tASTPointer<IdentifierPath> m_modifierName;\n\tstd::unique_ptr<std::vector<ASTPointer<Expression>>> m_arguments;\n};\n\n/**\n * Definition of a (loggable) event.\n */\nclass EventDefinition: public CallableDeclaration, public StructurallyDocumented, public ScopeOpener\n{\npublic:\n\tEventDefinition(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _name,\n\t\tSourceLocation _nameLocation,\n\t\tASTPointer<StructuredDocumentation> const& _documentation,\n\t\tASTPointer<ParameterList> const& _parameters,\n\t\tbool _anonymous = false\n\t):\n\t\tCallableDeclaration(_id, _location, _name, std::move(_nameLocation), Visibility::Default, _parameters),\n\t\tStructurallyDocumented(_documentation),\n\t\tm_anonymous(_anonymous)\n\t{\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tbool isAnonymous() const { return m_anonymous; }\n\n\tType const* type() const override;\n\tFunctionTypePointer functionType(bool /*_internal*/) const override;\n\n\tbool isVisibleInDerivedContracts() const override { return true; }\n\tbool isVisibleViaContractTypeAccess() const override { return true; }\n\n\tEventDefinitionAnnotation& annotation() const override;\n\n\tCallableDeclaration const& resolveVirtual(\n\t\tContractDefinition const&,\n\t\tContractDefinition const*\n\t) const override\n\t{\n\t\treturn *this;\n\t}\n\nprivate:\n\tbool m_anonymous = false;\n};\n\n/**\n * Definition of an error type usable in ``revert(MyError(x))``, ``require(condition, MyError(x))``\n * and ``catch MyError(_x)``.\n */\nclass ErrorDefinition: public CallableDeclaration, public StructurallyDocumented, public ScopeOpener\n{\npublic:\n\tErrorDefinition(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _name,\n\t\tSourceLocation _nameLocation,\n\t\tASTPointer<StructuredDocumentation> const& _documentation,\n\t\tASTPointer<ParameterList> const& _parameters\n\t):\n\t\tCallableDeclaration(_id, _location, _name, std::move(_nameLocation), Visibility::Default, _parameters),\n\t\tStructurallyDocumented(_documentation)\n\t{\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tType const* type() const override;\n\n\tFunctionTypePointer functionType(bool _internal) const override;\n\n\tbool isVisibleInDerivedContracts() const override { return true; }\n\tbool isVisibleViaContractTypeAccess() const override { return true; }\n\n\tErrorDefinitionAnnotation& annotation() const override;\n\n\tCallableDeclaration const& resolveVirtual(\n\t\tContractDefinition const&,\n\t\tContractDefinition const*\n\t) const override\n\t{\n\t\treturn *this;\n\t}\n};\n\n/**\n * Pseudo AST node that is used as declaration for \"this\", \"msg\", \"tx\", \"block\" and the global\n * functions when such an identifier is encountered. Will never have a valid location in the source code\n */\nclass MagicVariableDeclaration: public Declaration\n{\npublic:\n\tMagicVariableDeclaration(int _id, ASTString const& _name, Type const* _type):\n\t\tDeclaration(_id, SourceLocation(), std::make_shared<ASTString>(_name), {}), m_type(_type) { }\n\n\tvoid accept(ASTVisitor&) override\n\t{\n\t\tsolAssert(false, \"MagicVariableDeclaration used inside real AST.\");\n\t}\n\tvoid accept(ASTConstVisitor&) const override\n\t{\n\t\tsolAssert(false, \"MagicVariableDeclaration used inside real AST.\");\n\t}\n\n\tFunctionType const* functionType(bool) const override\n\t{\n\t\tsolAssert(m_type->category() == Type::Category::Function, \"\");\n\t\treturn dynamic_cast<FunctionType const*>(m_type);\n\t}\n\tType const* type() const override { return m_type; }\n\nprivate:\n\tType const* m_type;\n};\n\n/// Types\n/// @{\n\n/**\n * Abstract base class of a type name, can be any built-in or user-defined type.\n */\nclass TypeName: public ASTNode\n{\nprotected:\n\texplicit TypeName(int64_t _id, SourceLocation const& _location): ASTNode(_id, _location) {}\n\npublic:\n\tTypeNameAnnotation& annotation() const override;\n};\n\n/**\n * Any pre-defined type name represented by a single keyword (and possibly a state mutability for address types),\n * i.e. it excludes mappings, contracts, functions, etc.\n */\nclass ElementaryTypeName: public TypeName\n{\npublic:\n\tElementaryTypeName(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tElementaryTypeNameToken const& _elem,\n\t\tstd::optional<StateMutability> _stateMutability = {}\n\t): TypeName(_id, _location), m_type(_elem), m_stateMutability(_stateMutability)\n\t{\n\t\tsolAssert(!_stateMutability.has_value() || _elem.token() == Token::Address, \"\");\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tElementaryTypeNameToken const& typeName() const { return m_type; }\n\n\tstd::optional<StateMutability> const& stateMutability() const { return m_stateMutability; }\n\nprivate:\n\tElementaryTypeNameToken m_type;\n\tstd::optional<StateMutability> m_stateMutability; ///< state mutability for address type\n};\n\n/**\n * Name referring to a user-defined type (i.e. a struct, contract, etc.).\n */\nclass UserDefinedTypeName: public TypeName\n{\npublic:\n\tUserDefinedTypeName(int64_t _id, SourceLocation const& _location, ASTPointer<IdentifierPath> _namePath):\n\t\tTypeName(_id, _location), m_namePath(std::move(_namePath))\n\t{\n\t\tsolAssert(m_namePath != nullptr, \"Name cannot be null.\");\n\t}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tstd::vector<ASTString> const& namePath() const { return m_namePath->path(); }\n\tIdentifierPath& pathNode() const { return *m_namePath; }\n\nprivate:\n\tASTPointer<IdentifierPath> m_namePath;\n};\n\n/**\n * A literal function type. Its source form is \"function (paramType1, paramType2) internal / external returns (retType1, retType2)\"\n */\nclass FunctionTypeName: public TypeName, public ScopeOpener\n{\npublic:\n\tFunctionTypeName(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ParameterList> _parameterTypes,\n\t\tASTPointer<ParameterList> _returnTypes,\n\t\tVisibility _visibility,\n\t\tStateMutability _stateMutability\n\t):\n\t\tTypeName(_id, _location), m_parameterTypes(std::move(_parameterTypes)), m_returnTypes(std::move(_returnTypes)),\n\t\tm_visibility(_visibility), m_stateMutability(_stateMutability)\n\t{}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tstd::vector<ASTPointer<VariableDeclaration>> const& parameterTypes() const { return m_parameterTypes->parameters(); }\n\tstd::vector<ASTPointer<VariableDeclaration>> const& returnParameterTypes() const { return m_returnTypes->parameters(); }\n\tASTPointer<ParameterList> const& parameterTypeList() const { return m_parameterTypes; }\n\tASTPointer<ParameterList> const& returnParameterTypeList() const { return m_returnTypes; }\n\n\tVisibility visibility() const\n\t{\n\t\treturn m_visibility == Visibility::Default ? Visibility::Internal : m_visibility;\n\t}\n\tStateMutability stateMutability() const { return m_stateMutability; }\n\tbool isPayable() const { return m_stateMutability == StateMutability::Payable; }\n\nprivate:\n\tASTPointer<ParameterList> m_parameterTypes;\n\tASTPointer<ParameterList> m_returnTypes;\n\tVisibility m_visibility;\n\tStateMutability m_stateMutability;\n};\n\n/**\n * A mapping type. Its source form is \"mapping('keyType' => 'valueType')\"\n */\nclass Mapping: public TypeName\n{\npublic:\n\tMapping(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<TypeName> _keyType,\n\t\tASTPointer<ASTString> _keyName,\n\t\tSourceLocation _keyNameLocation,\n\t\tASTPointer<TypeName> _valueType,\n\t\tASTPointer<ASTString> _valueName,\n\t\tSourceLocation _valueNameLocation\n\t):\n\t\tTypeName(_id, _location),\n\t\tm_keyType(std::move(_keyType)),\n\t\tm_keyName(std::move(_keyName)),\n\t\tm_keyNameLocation(std::move(_keyNameLocation)),\n\t\tm_valueType(std::move(_valueType)),\n\t\tm_valueName(std::move(_valueName)),\n\t\tm_valueNameLocation(std::move(_valueNameLocation))\n\t{}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tTypeName const& keyType() const { return *m_keyType; }\n\tASTString keyName() const { return *m_keyName; }\n\tSourceLocation keyNameLocation() const { return m_keyNameLocation; }\n\tTypeName const& valueType() const { return *m_valueType; }\n\tASTString valueName() const { return *m_valueName; }\n\tSourceLocation valueNameLocation() const { return m_valueNameLocation; }\n\nprivate:\n\tASTPointer<TypeName> m_keyType;\n\tASTPointer<ASTString> m_keyName;\n\tSourceLocation m_keyNameLocation;\n\tASTPointer<TypeName> m_valueType;\n\tASTPointer<ASTString> m_valueName;\n\tSourceLocation m_valueNameLocation;\n};\n\n/**\n * An array type, can be \"typename[]\" or \"typename[<expression>]\".\n */\nclass ArrayTypeName: public TypeName\n{\npublic:\n\tArrayTypeName(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<TypeName> _baseType,\n\t\tASTPointer<Expression> _length\n\t):\n\t\tTypeName(_id, _location), m_baseType(std::move(_baseType)), m_length(std::move(_length)) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tTypeName const& baseType() const { return *m_baseType; }\n\tExpression const* length() const { return m_length.get(); }\n\nprivate:\n\tASTPointer<TypeName> m_baseType;\n\tASTPointer<Expression> m_length; ///< Length of the array, might be empty.\n};\n\n/// @}\n\n/// Statements\n/// @{\n\n\n/**\n * Abstract base class for statements.\n */\nclass Statement: public ASTNode, public Documented\n{\npublic:\n\texplicit Statement(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString\n\t): ASTNode(_id, _location), Documented(_docString) {}\n\n\tStatementAnnotation& annotation() const override;\n};\n\n/**\n * Inline assembly.\n */\nclass InlineAssembly: public Statement\n{\npublic:\n\tInlineAssembly(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString,\n\t\tyul::Dialect const& _dialect,\n\t\tASTPointer<std::vector<ASTPointer<ASTString>>> _flags,\n\t\tstd::shared_ptr<yul::AST> _operations\n\t):\n\t\tStatement(_id, _location, _docString),\n\t\tm_dialect(_dialect),\n\t\tm_flags(std::move(_flags)),\n\t\tm_operations(std::move(_operations))\n\t{}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tyul::Dialect const& dialect() const { return m_dialect; }\n\tyul::AST const& operations() const { return *m_operations; }\n\tASTPointer<std::vector<ASTPointer<ASTString>>> const& flags() const { return m_flags; }\n\n\tInlineAssemblyAnnotation& annotation() const override;\n\nprivate:\n\tyul::Dialect const& m_dialect;\n\tASTPointer<std::vector<ASTPointer<ASTString>>> m_flags;\n\tstd::shared_ptr<yul::AST> m_operations;\n};\n\n/**\n * Brace-enclosed block containing zero or more statements.\n */\nclass Block: public Statement, public Scopable, public ScopeOpener\n{\npublic:\n\tBlock(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString,\n\t\tbool _unchecked,\n\t\tstd::vector<ASTPointer<Statement>> _statements\n\t):\n\t\tStatement(_id, _location, _docString),\n\t\tm_statements(std::move(_statements)),\n\t\tm_unchecked(_unchecked)\n\t{}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tstd::vector<ASTPointer<Statement>> const& statements() const { return m_statements; }\n\tbool unchecked() const { return m_unchecked; }\n\n\tBlockAnnotation& annotation() const override;\n\nprivate:\n\tstd::vector<ASTPointer<Statement>> m_statements;\n\tbool m_unchecked;\n};\n\n/**\n * Special placeholder statement denoted by \"_\" used in function modifiers. This is replaced by\n * the original function when the modifier is applied.\n */\nclass PlaceholderStatement: public Statement\n{\npublic:\n\texplicit PlaceholderStatement(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString\n\t): Statement(_id, _location, _docString) {}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n};\n\n/**\n * If-statement with an optional \"else\" part. Note that \"else if\" is modeled by having a new\n * if-statement as the false (else) body.\n */\nclass IfStatement: public Statement\n{\npublic:\n\tIfStatement(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString,\n\t\tASTPointer<Expression> _condition,\n\t\tASTPointer<Statement> _trueBody,\n\t\tASTPointer<Statement> _falseBody\n\t):\n\t\tStatement(_id, _location, _docString),\n\t\tm_condition(std::move(_condition)),\n\t\tm_trueBody(std::move(_trueBody)),\n\t\tm_falseBody(std::move(_falseBody))\n\t{}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& condition() const { return *m_condition; }\n\tStatement const& trueStatement() const { return *m_trueBody; }\n\t/// @returns the \"else\" part of the if statement or nullptr if there is no \"else\" part.\n\tStatement const* falseStatement() const { return m_falseBody.get(); }\n\nprivate:\n\tASTPointer<Expression> m_condition;\n\tASTPointer<Statement> m_trueBody;\n\tASTPointer<Statement> m_falseBody; ///< \"else\" part, optional\n};\n\n/**\n * Clause of a try-catch block. Includes both the successful case and the\n * unsuccessful cases.\n * Names are only allowed for the unsuccessful cases.\n */\nclass TryCatchClause: public ASTNode, public Scopable, public ScopeOpener\n{\npublic:\n\tTryCatchClause(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> _errorName,\n\t\tASTPointer<ParameterList> _parameters,\n\t\tASTPointer<Block> _block\n\t):\n\t\tASTNode(_id, _location),\n\t\tm_errorName(std::move(_errorName)),\n\t\tm_parameters(std::move(_parameters)),\n\t\tm_block(std::move(_block))\n\t{}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tASTString const& errorName() const { return *m_errorName; }\n\tParameterList const* parameters() const { return m_parameters.get(); }\n\tBlock const& block() const { return *m_block; }\n\n\tTryCatchClauseAnnotation& annotation() const override;\n\nprivate:\n\tASTPointer<ASTString> m_errorName;\n\tASTPointer<ParameterList> m_parameters;\n\tASTPointer<Block> m_block;\n};\n\n/**\n * Try-statement with a variable number of catch statements.\n * Syntax:\n * try <call> returns (uint x, uint y) {\n *   // success code\n * } catch Panic(uint errorCode) {\n *   // panic\n * } catch Error(string memory cause) {\n *   // error code, reason provided\n * } catch (bytes memory lowLevelData) {\n *   // error code, no reason provided or non-matching error signature.\n * }\n *\n * The last statement given above can also be specified as\n * } catch () {\n */\nclass TryStatement: public Statement\n{\npublic:\n\tTryStatement(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString,\n\t\tASTPointer<Expression> _externalCall,\n\t\tstd::vector<ASTPointer<TryCatchClause>> _clauses\n\t):\n\t\tStatement(_id, _location, _docString),\n\t\tm_externalCall(std::move(_externalCall)),\n\t\tm_clauses(std::move(_clauses))\n\t{}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& externalCall() const { return *m_externalCall; }\n\tstd::vector<ASTPointer<TryCatchClause>> const& clauses() const { return m_clauses; }\n\n\tTryCatchClause const* successClause() const;\n\tTryCatchClause const* panicClause() const;\n\tTryCatchClause const* errorClause() const;\n\tTryCatchClause const* fallbackClause() const;\n\nprivate:\n\tASTPointer<Expression> m_externalCall;\n\tstd::vector<ASTPointer<TryCatchClause>> m_clauses;\n};\n\n/**\n * Statement in which a break statement is legal (abstract class).\n */\nclass BreakableStatement: public Statement\n{\npublic:\n\texplicit BreakableStatement(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString\n\t): Statement(_id, _location, _docString) {}\n};\n\nclass WhileStatement: public BreakableStatement\n{\npublic:\n\tWhileStatement(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString,\n\t\tASTPointer<Expression> _condition,\n\t\tASTPointer<Statement> _body,\n\t\tbool _isDoWhile\n\t):\n\t\tBreakableStatement(_id, _location, _docString), m_condition(std::move(_condition)), m_body(std::move(_body)),\n\t\tm_isDoWhile(_isDoWhile) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& condition() const { return *m_condition; }\n\tStatement const& body() const { return *m_body; }\n\tbool isDoWhile() const { return m_isDoWhile; }\n\nprivate:\n\tASTPointer<Expression> m_condition;\n\tASTPointer<Statement> m_body;\n\tbool m_isDoWhile;\n};\n\n/**\n * For loop statement\n */\nclass ForStatement: public BreakableStatement, public Scopable, public ScopeOpener\n{\npublic:\n\tForStatement(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString,\n\t\tASTPointer<Statement> _initExpression,\n\t\tASTPointer<Expression> _conditionExpression,\n\t\tASTPointer<ExpressionStatement> _loopExpression,\n\t\tASTPointer<Statement> _body\n\t):\n\t\tBreakableStatement(_id, _location, _docString),\n\t\tm_initExpression(std::move(_initExpression)),\n\t\tm_condExpression(std::move(_conditionExpression)),\n\t\tm_loopExpression(std::move(_loopExpression)),\n\t\tm_body(std::move(_body))\n\t{}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tStatement const* initializationExpression() const { return m_initExpression.get(); }\n\tExpression const* condition() const { return m_condExpression.get(); }\n\tExpressionStatement const* loopExpression() const { return m_loopExpression.get(); }\n\tStatement const& body() const { return *m_body; }\n\n\tForStatementAnnotation& annotation() const override;\n\nprivate:\n\t/// For statement's initialization expression. for (XXX; ; ). Can be empty\n\tASTPointer<Statement> m_initExpression;\n\t/// For statement's condition expression. for (; XXX ; ). Can be empty\n\tASTPointer<Expression> m_condExpression;\n\t/// For statement's loop expression. for (;;XXX). Can be empty\n\tASTPointer<ExpressionStatement> m_loopExpression;\n\t/// The body of the loop\n\tASTPointer<Statement> m_body;\n};\n\nclass Continue: public Statement\n{\npublic:\n\texplicit Continue(int64_t _id, SourceLocation const& _location, ASTPointer<ASTString> const& _docString):\n\t\tStatement(_id, _location, _docString) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n};\n\nclass Break: public Statement\n{\npublic:\n\texplicit Break(int64_t _id, SourceLocation const& _location, ASTPointer<ASTString> const& _docString):\n\t\tStatement(_id, _location, _docString) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n};\n\nclass Return: public Statement\n{\npublic:\n\tReturn(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString,\n\t\tASTPointer<Expression> _expression\n\t): Statement(_id, _location, _docString), m_expression(std::move(_expression)) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const* expression() const { return m_expression.get(); }\n\n\tReturnAnnotation& annotation() const override;\n\nprivate:\n\tASTPointer<Expression> m_expression; ///< value to return, optional\n};\n\n/**\n * @brief The Throw statement to throw that triggers a solidity exception(jump to ErrorTag)\n */\nclass Throw: public Statement\n{\npublic:\n\texplicit Throw(int64_t _id, SourceLocation const& _location, ASTPointer<ASTString> const& _docString):\n\t\tStatement(_id, _location, _docString) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n};\n\n/**\n * The revert statement is used to revert state changes and return error data.\n */\nclass RevertStatement: public Statement\n{\npublic:\n\texplicit RevertStatement(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString,\n\t\tASTPointer<FunctionCall> _functionCall\n\t):\n\t\tStatement(_id, _location, _docString), m_errorCall(std::move(_functionCall))\n\t{\n\t\tsolAssert(m_errorCall, \"\");\n\t}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tFunctionCall const& errorCall() const { return *m_errorCall; }\n\nprivate:\n\tASTPointer<FunctionCall> m_errorCall;\n};\n\n/**\n * The emit statement is used to emit events: emit EventName(arg1, ..., argn)\n */\nclass EmitStatement: public Statement\n{\npublic:\n\texplicit EmitStatement(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString,\n\t\tASTPointer<FunctionCall> _functionCall\n\t):\n\t\tStatement(_id, _location, _docString), m_eventCall(std::move(_functionCall)) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tFunctionCall const& eventCall() const { return *m_eventCall; }\n\nprivate:\n\tASTPointer<FunctionCall> m_eventCall;\n};\n\n/**\n * Definition of one or more variables as a statement inside a function.\n * If multiple variables are declared, a value has to be assigned directly.\n * If only a single variable is declared, the value can be missing.\n * Examples:\n * uint[] memory a; uint a = 2;\n * (uint a, bytes32 b, ) = f(); (, uint a, , StructName storage x) = g();\n */\nclass VariableDeclarationStatement: public Statement\n{\npublic:\n\tVariableDeclarationStatement(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString,\n\t\tstd::vector<ASTPointer<VariableDeclaration>> _variables,\n\t\tASTPointer<Expression> _initialValue\n\t):\n\t\tStatement(_id, _location, _docString), m_variables(std::move(_variables)), m_initialValue(std::move(_initialValue)) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tstd::vector<ASTPointer<VariableDeclaration>> const& declarations() const { return m_variables; }\n\tExpression const* initialValue() const { return m_initialValue.get(); }\n\nprivate:\n\t/// List of variables, some of which can be empty pointers (unnamed components).\n\t/// Note that the ``m_value`` member of these is unused. Instead, ``m_initialValue``\n\t/// below is used, because the initial value can be a single expression assigned\n\t/// to all variables.\n\tstd::vector<ASTPointer<VariableDeclaration>> m_variables;\n\t/// The assigned expression / initial value.\n\tASTPointer<Expression> m_initialValue;\n};\n\n/**\n * A statement that contains only an expression (i.e. an assignment, function call, ...).\n */\nclass ExpressionStatement: public Statement\n{\npublic:\n\tExpressionStatement(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> const& _docString,\n\t\tASTPointer<Expression> _expression\n\t):\n\t\tStatement(_id, _location, _docString), m_expression(std::move(_expression)) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& expression() const { return *m_expression; }\n\nprivate:\n\tASTPointer<Expression> m_expression;\n};\n\n/// @}\n\n/// Expressions\n/// @{\n\n/**\n * An expression, i.e. something that has a value (which can also be of type \"void\" in case\n * of some function calls).\n * @abstract\n */\nclass Expression: public ASTNode\n{\npublic:\n\texplicit Expression(int64_t _id, SourceLocation const& _location): ASTNode(_id, _location) {}\n\n\tExpressionAnnotation& annotation() const override;\n};\n\nclass Conditional: public Expression\n{\npublic:\n\tConditional(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<Expression> _condition,\n\t\tASTPointer<Expression> _trueExpression,\n\t\tASTPointer<Expression> _falseExpression\n\t):\n\t\tExpression(_id, _location),\n\t\tm_condition(std::move(_condition)),\n\t\tm_trueExpression(std::move(_trueExpression)),\n\t\tm_falseExpression(std::move(_falseExpression))\n\t{}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& condition() const { return *m_condition; }\n\tExpression const& trueExpression() const { return *m_trueExpression; }\n\tExpression const& falseExpression() const { return *m_falseExpression; }\n\nprivate:\n\tASTPointer<Expression> m_condition;\n\tASTPointer<Expression> m_trueExpression;\n\tASTPointer<Expression> m_falseExpression;\n};\n\n/// Assignment, can also be a compound assignment.\n/// Examples: (a = 7 + 8) or (a *= 2)\nclass Assignment: public Expression\n{\npublic:\n\tAssignment(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<Expression> _leftHandSide,\n\t\tToken _assignmentOperator,\n\t\tASTPointer<Expression> _rightHandSide\n\t):\n\t\tExpression(_id, _location),\n\t\tm_leftHandSide(std::move(_leftHandSide)),\n\t\tm_assignmentOperator(_assignmentOperator),\n\t\tm_rightHandSide(std::move(_rightHandSide))\n\t{\n\t\tsolAssert(TokenTraits::isAssignmentOp(_assignmentOperator), \"\");\n\t}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& leftHandSide() const { return *m_leftHandSide; }\n\tToken assignmentOperator() const { return m_assignmentOperator; }\n\tExpression const& rightHandSide() const { return *m_rightHandSide; }\n\nprivate:\n\tASTPointer<Expression> m_leftHandSide;\n\tToken m_assignmentOperator;\n\tASTPointer<Expression> m_rightHandSide;\n};\n\n\n/**\n * Tuple, parenthesized expression, or bracketed expression.\n * Examples: (1, 2), (x,), (x), (), [1, 2],\n * Individual components might be empty shared pointers (as in the second example).\n * The respective types in lvalue context are: 2-tuple, 2-tuple (with wildcard), type of x, 0-tuple\n * Not in lvalue context: 2-tuple, _1_-tuple, type of x, 0-tuple.\n */\nclass TupleExpression: public Expression\n{\npublic:\n\tTupleExpression(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tstd::vector<ASTPointer<Expression>> _components,\n\t\tbool _isArray\n\t):\n\t\tExpression(_id, _location),\n\t\tm_components(std::move(_components)),\n\t\tm_isArray(_isArray) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tstd::vector<ASTPointer<Expression>> const& components() const { return m_components; }\n\tbool isInlineArray() const { return m_isArray; }\n\nprivate:\n\tstd::vector<ASTPointer<Expression>> m_components;\n\tbool m_isArray;\n};\n\n/**\n * Operation involving a unary operator, pre- or postfix.\n * Examples: ++i, delete x or !true\n */\nclass UnaryOperation: public Expression\n{\npublic:\n\tUnaryOperation(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tToken _operator,\n\t\tASTPointer<Expression> _subExpression,\n\t\tbool _isPrefix\n\t):\n\t\tExpression(_id, _location),\n\t\tm_operator(_operator),\n\t\tm_subExpression(std::move(_subExpression)),\n\t\tm_isPrefix(_isPrefix)\n\t{\n\t\tsolAssert(TokenTraits::isUnaryOp(_operator), \"\");\n\t}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tToken getOperator() const { return m_operator; }\n\tbool isPrefixOperation() const { return m_isPrefix; }\n\tExpression const& subExpression() const { return *m_subExpression; }\n\n\tFunctionType const* userDefinedFunctionType() const;\n\n\tOperationAnnotation& annotation() const override;\n\nprivate:\n\tToken m_operator;\n\tASTPointer<Expression> m_subExpression;\n\tbool m_isPrefix;\n};\n\n/**\n * Operation involving a binary operator.\n * Examples: 1 + 2, true && false or 1 <= 4\n */\nclass BinaryOperation: public Expression\n{\npublic:\n\tBinaryOperation(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<Expression> _left,\n\t\tToken _operator,\n\t\tASTPointer<Expression> _right\n\t):\n\t\tExpression(_id, _location), m_left(std::move(_left)), m_operator(_operator), m_right(std::move(_right))\n\t{\n\t\t// TODO: assert against colon for non-experimental solidity\n\t\tsolAssert(TokenTraits::isBinaryOp(_operator) || TokenTraits::isCompareOp(_operator) || _operator == Token::Colon || _operator == Token::RightArrow, \"\");\n\t}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& leftExpression() const { return *m_left; }\n\tExpression const& rightExpression() const { return *m_right; }\n\tToken getOperator() const { return m_operator; }\n\n\tFunctionType const* userDefinedFunctionType() const;\n\n\tBinaryOperationAnnotation& annotation() const override;\n\nprivate:\n\tASTPointer<Expression> m_left;\n\tToken m_operator;\n\tASTPointer<Expression> m_right;\n};\n\n/**\n * Can be ordinary function call, type cast or struct construction.\n */\nclass FunctionCall: public Expression\n{\npublic:\n\tFunctionCall(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<Expression> _expression,\n\t\tstd::vector<ASTPointer<Expression>> _arguments,\n\t\tstd::vector<ASTPointer<ASTString>> _names,\n\t\tstd::vector<SourceLocation> _nameLocations\n\t):\n\t\tExpression(_id, _location), m_expression(std::move(_expression)), m_arguments(std::move(_arguments)), m_names(std::move(_names)), m_nameLocations(std::move(_nameLocations))\n\t{\n\t\tsolAssert(m_nameLocations.size() == m_names.size());\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& expression() const { return *m_expression; }\n\t/// @returns the given arguments in the order they were written.\n\tstd::vector<ASTPointer<Expression const>> arguments() const { return {m_arguments.begin(), m_arguments.end()}; }\n\t/// @returns the given arguments sorted by how the called function takes them.\n\tstd::vector<ASTPointer<Expression const>> sortedArguments() const;\n\t/// @returns the list of given argument names if this is a named call,\n\t/// in the order they were written.\n\t/// If this is not a named call, this is empty.\n\tstd::vector<ASTPointer<ASTString>> const& names() const { return m_names; }\n\tstd::vector<SourceLocation> const& nameLocations() const { return m_nameLocations; }\n\n\tFunctionCallAnnotation& annotation() const override;\n\nprivate:\n\tASTPointer<Expression> m_expression;\n\tstd::vector<ASTPointer<Expression>> m_arguments;\n\tstd::vector<ASTPointer<ASTString>> m_names;\n\tstd::vector<SourceLocation> m_nameLocations;\n};\n\n/**\n * Expression that annotates a function call / a new expression with extra\n * options like gas, value, salt: new SomeContract{salt=123}(params)\n */\nclass FunctionCallOptions: public Expression\n{\npublic:\n\tFunctionCallOptions(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<Expression> _expression,\n\t\tstd::vector<ASTPointer<Expression>> _options,\n\t\tstd::vector<ASTPointer<ASTString>> _names\n\t):\n\t\tExpression(_id, _location), m_expression(std::move(_expression)), m_options(std::move(_options)), m_names(std::move(_names)) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& expression() const { return *m_expression; }\n\tstd::vector<ASTPointer<Expression const>> options() const { return {m_options.begin(), m_options.end()}; }\n\tstd::vector<ASTPointer<ASTString>> const& names() const { return m_names; }\n\nprivate:\n\tASTPointer<Expression> m_expression;\n\tstd::vector<ASTPointer<Expression>> m_options;\n\tstd::vector<ASTPointer<ASTString>> m_names;\n\n};\n\n/**\n * Expression that creates a new contract or memory-array,\n * e.g. the \"new SomeContract\" part in \"new SomeContract(1, 2)\".\n */\nclass NewExpression: public Expression\n{\npublic:\n\tNewExpression(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<TypeName> _typeName\n\t):\n\t\tExpression(_id, _location), m_typeName(std::move(_typeName)) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tTypeName const& typeName() const { return *m_typeName; }\n\nprivate:\n\tASTPointer<TypeName> m_typeName;\n};\n\n/**\n * Access to a member of an object. Example: x.name\n */\nclass MemberAccess: public Expression\n{\npublic:\n\tMemberAccess(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<Expression> _expression,\n\t\tASTPointer<ASTString> _memberName,\n\t\tSourceLocation _memberLocation\n\t):\n\t\tExpression(_id, _location),\n\t\tm_expression(std::move(_expression)),\n\t\tm_memberName(std::move(_memberName)),\n\t\tm_memberLocation(std::move(_memberLocation))\n\t{}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\tExpression const& expression() const { return *m_expression; }\n\tASTString const& memberName() const { return *m_memberName; }\n\tSourceLocation const& memberLocation() const { return m_memberLocation; }\n\n\tMemberAccessAnnotation& annotation() const override;\n\nprivate:\n\tASTPointer<Expression> m_expression;\n\tASTPointer<ASTString> m_memberName;\n\tSourceLocation m_memberLocation;\n};\n\n/**\n * Index access to an array or mapping. Example: a[2]\n */\nclass IndexAccess: public Expression\n{\npublic:\n\tIndexAccess(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<Expression> _base,\n\t\tASTPointer<Expression> _index\n\t):\n\t\tExpression(_id, _location), m_base(std::move(_base)), m_index(std::move(_index)) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& baseExpression() const { return *m_base; }\n\tExpression const* indexExpression() const { return m_index.get(); }\n\nprivate:\n\tASTPointer<Expression> m_base;\n\tASTPointer<Expression> m_index;\n};\n\n/**\n * Index range access to an array. Example: a[2:3]\n */\nclass IndexRangeAccess: public Expression\n{\npublic:\n\tIndexRangeAccess(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<Expression> _base,\n\t\tASTPointer<Expression> _start,\n\t\tASTPointer<Expression> _end\n\t):\n\t\tExpression(_id, _location), m_base(std::move(_base)), m_start(std::move(_start)), m_end(std::move(_end)) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tExpression const& baseExpression() const { return *m_base; }\n\tExpression const* startExpression() const { return m_start.get(); }\n\tExpression const* endExpression() const { return m_end.get(); }\n\nprivate:\n\tASTPointer<Expression> m_base;\n\tASTPointer<Expression> m_start;\n\tASTPointer<Expression> m_end;\n};\n\n/**\n * Primary expression, i.e. an expression that cannot be divided any further. Examples are literals\n * or variable references.\n */\nclass PrimaryExpression: public Expression\n{\npublic:\n\tPrimaryExpression(int64_t _id, SourceLocation const& _location): Expression(_id, _location) {}\n};\n\n/**\n * An identifier, i.e. a reference to a declaration by name like a variable or function.\n */\nclass Identifier: public PrimaryExpression\n{\npublic:\n\tIdentifier(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> _name\n\t):\n\t\tPrimaryExpression(_id, _location), m_name(std::move(_name)) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tASTString const& name() const { return *m_name; }\n\n\tIdentifierAnnotation& annotation() const override;\n\nprivate:\n\tASTPointer<ASTString> m_name;\n};\n\n/**\n * An elementary type name expression is used in expressions like \"a = uint32(2)\" to change the\n * type of an expression explicitly. Here, \"uint32\" is the elementary type name expression and\n * \"uint32(2)\" is a @ref FunctionCall.\n */\nclass ElementaryTypeNameExpression: public PrimaryExpression\n{\npublic:\n\tElementaryTypeNameExpression(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ElementaryTypeName> _type\n\t):\n\t\tPrimaryExpression(_id, _location),\n\t\tm_type(std::move(_type))\n\t{\n\t}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tElementaryTypeName const& type() const { return *m_type; }\n\nprivate:\n\tASTPointer<ElementaryTypeName> m_type;\n};\n\n/**\n * A literal string or number. @see ExpressionCompiler::endVisit() is used to actually parse its value.\n */\nclass Literal: public PrimaryExpression\n{\npublic:\n\tenum class SubDenomination\n\t{\n\t\tNone = static_cast<int>(Token::Illegal),\n\t\tWei = static_cast<int>(Token::SubWei),\n\t\tGwei = static_cast<int>(Token::SubGwei),\n\t\tEther = static_cast<int>(Token::SubEther),\n\t\tSecond = static_cast<int>(Token::SubSecond),\n\t\tMinute = static_cast<int>(Token::SubMinute),\n\t\tHour = static_cast<int>(Token::SubHour),\n\t\tDay = static_cast<int>(Token::SubDay),\n\t\tWeek = static_cast<int>(Token::SubWeek),\n\t\tYear = static_cast<int>(Token::SubYear)\n\t};\n\tLiteral(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tToken _token,\n\t\tASTPointer<ASTString> _value,\n\t\tSubDenomination _sub = SubDenomination::None\n\t):\n\t\tPrimaryExpression(_id, _location), m_token(_token), m_value(std::move(_value)), m_subDenomination(_sub) {}\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tToken token() const { return m_token; }\n\t/// @returns the non-parsed value of the literal\n\tASTString const& value() const { return *m_value; }\n\n\tASTString valueWithoutUnderscores() const;\n\n\tSubDenomination subDenomination() const { return m_subDenomination; }\n\n\t/// @returns true if this is a number with a hex prefix.\n\tbool isHexNumber() const;\n\n\t/// @returns true if this looks like a checksummed address.\n\tbool looksLikeAddress() const;\n\t/// @returns true if it passes the address checksum test.\n\tbool passesAddressChecksum() const;\n\t/// @returns the checksummed version of an address (or empty string if not valid)\n\tstd::string getChecksummedAddress() const;\n\nprivate:\n\tToken m_token;\n\tASTPointer<ASTString> m_value;\n\tSubDenomination m_subDenomination;\n};\n\n/// @}\n\n/// Experimental Solidity nodes\n/// @{\nclass TypeClassDefinition: public Declaration, public StructurallyDocumented, public ScopeOpener\n{\npublic:\n\tTypeClassDefinition(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<VariableDeclaration> _typeVariable,\n\t\tASTPointer<ASTString> const& _name,\n\t\tSourceLocation _nameLocation,\n\t\tASTPointer<StructuredDocumentation> const& _documentation,\n\t\tstd::vector<ASTPointer<ASTNode>> _subNodes\n\t):\n\t\tDeclaration(_id, _location, _name, std::move(_nameLocation)),\n\t\tStructurallyDocumented(_documentation),\n\t\tm_typeVariable(std::move(_typeVariable)),\n\t\tm_subNodes(std::move(_subNodes))\n\t{}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tVariableDeclaration const& typeVariable() const { return *m_typeVariable; }\n\tstd::vector<ASTPointer<ASTNode>> const& subNodes() const { return m_subNodes; }\n\n\tTypeClassDefinitionAnnotation& annotation() const override;\n\n\tType const* type() const override { solAssert(false, \"Requested type of experimental solidity node.\"); }\n\n\tbool experimentalSolidityOnly() const override { return true; }\n\nprivate:\n\tASTPointer<VariableDeclaration> m_typeVariable;\n\tstd::vector<ASTPointer<ASTNode>> m_subNodes;\n};\n\nclass TypeClassInstantiation: public ASTNode, public ScopeOpener\n{\npublic:\n\tTypeClassInstantiation(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<TypeName> _typeConstructor,\n\t\tASTPointer<ParameterList> _argumentSorts,\n\t\tASTPointer<TypeClassName> _class,\n\t\tstd::vector<ASTPointer<ASTNode>> _subNodes\n\t):\n\t\tASTNode(_id, _location),\n\t\tm_typeConstructor(std::move(_typeConstructor)),\n\t\tm_argumentSorts(std::move(_argumentSorts)),\n\t\tm_class(std::move(_class)),\n\t\tm_subNodes(std::move(_subNodes))\n\t{}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tTypeName const& typeConstructor() const { return *m_typeConstructor; }\n\tParameterList const* argumentSorts() const { return m_argumentSorts.get(); }\n\tTypeClassName const& typeClass() const { return *m_class; }\n\tstd::vector<ASTPointer<ASTNode>> const& subNodes() const { return m_subNodes; }\n\n\tbool experimentalSolidityOnly() const override { return true; }\n\nprivate:\n\tASTPointer<TypeName> m_typeConstructor;\n\tASTPointer<ParameterList> m_argumentSorts;\n\tASTPointer<TypeClassName> m_class;\n\tstd::vector<ASTPointer<ASTNode>> m_subNodes;\n};\n\nclass TypeDefinition: public Declaration, public ScopeOpener\n{\npublic:\n\tTypeDefinition(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tASTPointer<ASTString> _name,\n\t\tSourceLocation _nameLocation,\n\t\tASTPointer<ParameterList> _arguments,\n\t\tASTPointer<Expression> _typeExpression\n\t):\n\t\tDeclaration(_id, _location, _name, std::move(_nameLocation), Visibility::Default),\n\t\tm_arguments(std::move(_arguments)),\n\t\tm_typeExpression(std::move(_typeExpression))\n\t{\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tType const* type() const override { return nullptr; }\n\n\tTypeDeclarationAnnotation& annotation() const override;\n\n\tParameterList const* arguments() const { return m_arguments.get(); }\n\tExpression const* typeExpression() const { return m_typeExpression.get(); }\n\n\tbool experimentalSolidityOnly() const override { return true; }\n\nprivate:\n\tASTPointer<ParameterList> m_arguments;\n\tASTPointer<Expression> m_typeExpression;\n};\n\nclass TypeClassName: public ASTNode\n{\npublic:\n\tTypeClassName(\n\t\tint64_t _id,\n\t\tSourceLocation const& _location,\n\t\tstd::variant<Token, ASTPointer<IdentifierPath>> _name\n\t):\n\t\tASTNode(_id, _location),\n\t\tm_name(std::move(_name))\n\t{\n\t\tif (Token const* token = std::get_if<Token>(&_name))\n\t\t\tsolAssert(TokenTraits::isBuiltinTypeClassName(*token));\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tbool experimentalSolidityOnly() const override { return true; }\n\n\tstd::variant<Token, ASTPointer<IdentifierPath>> name() const { return m_name; }\n\nprivate:\n\tstd::variant<Token, ASTPointer<IdentifierPath>> m_name;\n};\n\nclass Builtin: public Expression\n{\npublic:\n\tBuiltin(\n\t\tint64_t _id,\n\t\tSourceLocation _location,\n\t\tASTPointer<ASTString> _nameParameter,\n\t\tSourceLocation _nameParameterLocation\n\t):\n\t\tExpression(_id, std::move(_location)),\n\t\tm_nameParameter(std::move(_nameParameter)),\n\t\tm_nameParameterLocation(std::move(_nameParameterLocation))\n\t{\n\t\tsolAssert(m_nameParameter);\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\n\tbool experimentalSolidityOnly() const override { return true; }\n\n\tASTString const& nameParameter() const { return *m_nameParameter; }\n\tSourceLocation const& nameParameterLocation() const { return m_nameParameterLocation; }\n\nprivate:\n\tASTPointer<ASTString> m_nameParameter;\n\tSourceLocation m_nameParameterLocation;\n};\n\n// TODO: NatSpec used on the quantifier should be recognized as applying to the function.\nclass ForAllQuantifier: public ASTNode, public Scopable, public ScopeOpener\n{\npublic:\n\tForAllQuantifier(\n\t\tint64_t _id,\n\t\tSourceLocation _location,\n\t\tASTPointer<ParameterList> _typeVariableDeclarations,\n\t\tASTPointer<FunctionDefinition> _quantifiedDeclaration\n\t):\n\t\tASTNode(_id, std::move(_location)),\n\t\tm_typeVariableDeclarations(std::move(_typeVariableDeclarations)),\n\t\tm_quantifiedDeclaration(std::move(_quantifiedDeclaration))\n\t{\n\t\tsolAssert(m_typeVariableDeclarations);\n\t\tsolAssert(m_quantifiedDeclaration);\n\t}\n\n\tvoid accept(ASTVisitor& _visitor) override;\n\tvoid accept(ASTConstVisitor& _visitor) const override;\n\tForAllQuantifierAnnotation& annotation() const override { return initAnnotation<ForAllQuantifierAnnotation>(); }\n\n\tbool experimentalSolidityOnly() const override { return true; }\n\n\tParameterList const& typeVariableDeclarations() const { return *m_typeVariableDeclarations; }\n\tFunctionDefinition const& quantifiedDeclaration() const { return *m_quantifiedDeclaration; }\n\nprivate:\n\tASTPointer<ParameterList> m_typeVariableDeclarations;\n\tASTPointer<FunctionDefinition> m_quantifiedDeclaration;\n};\n\n/// @}\n\n}\n"
  },
  {
    "path": "libsolidity/ast/ASTAnnotations.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Object containing the type and other annotations for the AST nodes.\n */\n\n#include <libsolidity/ast/ASTAnnotations.h>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\n\n"
  },
  {
    "path": "libsolidity/ast/ASTAnnotations.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Object containing the type and other annotations for the AST nodes.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/ASTEnums.h>\n#include <libsolidity/ast/ExperimentalFeatures.h>\n\n#include <libsolutil/Numeric.h>\n#include <libsolutil/SetOnce.h>\n\n#include <map>\n#include <memory>\n#include <optional>\n#include <set>\n#include <vector>\n\nnamespace solidity::yul\n{\nstruct AsmAnalysisInfo;\nstruct Identifier;\nclass Dialect;\n}\n\nnamespace solidity::frontend\n{\n\nclass Type;\nclass ArrayType;\n\nstruct CallGraph;\n\nstruct ASTAnnotation\n{\n\tASTAnnotation() = default;\n\n\tASTAnnotation(ASTAnnotation const&) = delete;\n\tASTAnnotation(ASTAnnotation&&) = delete;\n\n\tASTAnnotation& operator=(ASTAnnotation const&) = delete;\n\tASTAnnotation& operator=(ASTAnnotation&&) = delete;\n\n\tvirtual ~ASTAnnotation() = default;\n};\n\nstruct DocTag\n{\n\tstd::string content;    ///< The text content of the tag.\n\tstd::string paramName;  ///< Only used for @param, stores the parameter name.\n};\n\nstruct StructurallyDocumentedAnnotation\n{\n\tStructurallyDocumentedAnnotation() = default;\n\n\tStructurallyDocumentedAnnotation(StructurallyDocumentedAnnotation const&) = delete;\n\tStructurallyDocumentedAnnotation(StructurallyDocumentedAnnotation&&) = delete;\n\n\tStructurallyDocumentedAnnotation& operator=(StructurallyDocumentedAnnotation const&) = delete;\n\tStructurallyDocumentedAnnotation& operator=(StructurallyDocumentedAnnotation&&) = delete;\n\n\tvirtual ~StructurallyDocumentedAnnotation() = default;\n\n\t/// Mapping docstring tag name -> content.\n\tstd::multimap<std::string, DocTag> docTags;\n\t/// contract that @inheritdoc references if it exists\n\tContractDefinition const* inheritdocReference = nullptr;\n};\n\nstruct SourceUnitAnnotation: ASTAnnotation\n{\n\t/// The \"absolute\" (in the compiler sense) path of this source unit.\n\tutil::SetOnce<std::string> path;\n\t/// The exported symbols (all global symbols).\n\tutil::SetOnce<std::map<ASTString, std::vector<Declaration const*>>> exportedSymbols;\n\t/// Experimental features.\n\tstd::set<ExperimentalFeature> experimentalFeatures;\n\t/// Using the new ABI coder. Set to `false` if using ABI coder v1.\n\tutil::SetOnce<bool> useABICoderV2;\n};\n\nstruct ScopableAnnotation\n{\n\tScopableAnnotation() = default;\n\n\tScopableAnnotation(ScopableAnnotation const&) = delete;\n\tScopableAnnotation(ScopableAnnotation&&) = delete;\n\n\tScopableAnnotation& operator=(ScopableAnnotation const&) = delete;\n\tScopableAnnotation& operator=(ScopableAnnotation&&) = delete;\n\n\tvirtual ~ScopableAnnotation() = default;\n\n\t/// The scope this declaration resides in. Can be nullptr if it is the global scope.\n\t/// Filled by the Scoper.\n\tASTNode const* scope = nullptr;\n\t/// Pointer to the contract this declaration resides in. Can be nullptr if the current scope\n\t/// is not part of a contract. Filled by the Scoper.\n\tContractDefinition const* contract = nullptr;\n};\n\nstruct DeclarationAnnotation: ASTAnnotation, ScopableAnnotation\n{\n};\n\nstruct ImportAnnotation: DeclarationAnnotation\n{\n\t/// The absolute path of the source unit to import.\n\tutil::SetOnce<std::string> absolutePath;\n\t/// The actual source unit.\n\tSourceUnit const* sourceUnit = nullptr;\n};\n\nstruct TypeDeclarationAnnotation: DeclarationAnnotation\n{\n\t/// The name of this type, prefixed by proper namespaces if globally accessible.\n\tutil::SetOnce<std::string> canonicalName;\n};\n\nstruct StructDeclarationAnnotation: TypeDeclarationAnnotation\n{\n\t/// Whether the struct is recursive, i.e. if the struct (recursively) contains a member that involves a struct of the same\n\t/// type, either in a dynamic array, as member of another struct or inside a mapping.\n\t/// Only cases in which the recursive occurrence is within a dynamic array or a mapping are valid, while direct\n\t/// recursion immediately raises an error.\n\t/// Will be filled in by the DeclarationTypeChecker.\n\tstd::optional<bool> recursive;\n\t/// Whether the struct contains a mapping type, either directly or, indirectly inside another\n\t/// struct or an array.\n\tstd::optional<bool> containsNestedMapping;\n};\n\nstruct ContractDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocumentedAnnotation\n{\n\t/// List of functions and modifiers without a body. Can also contain functions from base classes.\n\tstd::optional<std::vector<Declaration const*>> unimplementedDeclarations;\n\t/// List of all (direct and indirect) base contracts in order from derived to\n\t/// base, including the contract itself.\n\tstd::vector<ContractDefinition const*> linearizedBaseContracts;\n\t/// Mapping containing the nodes that define the arguments for base constructors.\n\t/// These can either be inheritance specifiers or modifier invocations.\n\tstd::map<FunctionDefinition const*, ASTNode const*> baseConstructorArguments;\n\t/// A graph with edges representing calls between functions that may happen during contract construction.\n\tutil::SetOnce<std::shared_ptr<CallGraph const>> creationCallGraph;\n\t/// A graph with edges representing calls between functions that may happen in a deployed contract.\n\tutil::SetOnce<std::shared_ptr<CallGraph const>> deployedCallGraph;\n\n\t/// List of contracts whose bytecode is referenced by this contract, e.g. through \"new\".\n\t/// The Value represents the ast node that referenced the contract.\n\tstd::map<ContractDefinition const*, ASTNode const*, ASTCompareByID<ContractDefinition>> contractDependencies;\n\n\t// Per-contract map from function AST IDs to internal dispatch function IDs.\n\tstd::map<FunctionDefinition const*, uint64_t> internalFunctionIDs;\n};\n\nstruct StorageLayoutSpecifierAnnotation: ASTAnnotation\n{\n\t// The evaluated value of the expression specifying the contract storage layout base\n\tutil::SetOnce<u256> baseSlot;\n};\n\nstruct CallableDeclarationAnnotation: DeclarationAnnotation\n{\n\t/// The set of functions/modifiers/events this callable overrides.\n\tstd::set<CallableDeclaration const*> baseFunctions;\n};\n\nstruct FunctionDefinitionAnnotation: CallableDeclarationAnnotation, StructurallyDocumentedAnnotation\n{\n};\n\nstruct EventDefinitionAnnotation: CallableDeclarationAnnotation, StructurallyDocumentedAnnotation\n{\n};\n\nstruct ErrorDefinitionAnnotation: CallableDeclarationAnnotation, StructurallyDocumentedAnnotation\n{\n};\n\n\nstruct ModifierDefinitionAnnotation: CallableDeclarationAnnotation, StructurallyDocumentedAnnotation\n{\n};\n\nstruct VariableDeclarationAnnotation: DeclarationAnnotation, StructurallyDocumentedAnnotation\n{\n\t/// Type of variable (type of identifier referencing this variable).\n\tType const* type = nullptr;\n\t/// The set of functions this (public state) variable overrides.\n\tstd::set<CallableDeclaration const*> baseFunctions;\n};\n\nstruct StatementAnnotation: ASTAnnotation\n{\n};\n\nstruct InlineAssemblyAnnotation: StatementAnnotation\n{\n\tstruct ExternalIdentifierInfo\n\t{\n\t\tDeclaration const* declaration = nullptr;\n\t\t/// Suffix used, one of \"slot\", \"offset\", \"length\", \"address\", \"selector\" or empty.\n\t\tstd::string suffix;\n\t\tsize_t valueSize = size_t(-1);\n\t};\n\n\t/// Mapping containing resolved references to external identifiers and their value size\n\tstd::map<yul::Identifier const*, ExternalIdentifierInfo> externalReferences;\n\t/// Information generated during analysis phase.\n\tstd::shared_ptr<yul::AsmAnalysisInfo> analysisInfo;\n\t/// True, if the assembly block was annotated to be memory-safe.\n\tbool markedMemorySafe = false;\n\t/// True, if the assembly block involves any memory opcode or assigns to variables in memory.\n\tutil::SetOnce<bool> hasMemoryEffects;\n};\n\nstruct BlockAnnotation: StatementAnnotation, ScopableAnnotation\n{\n};\n\nstruct TryCatchClauseAnnotation: ASTAnnotation, ScopableAnnotation\n{\n};\n\nstruct ForStatementAnnotation: StatementAnnotation, ScopableAnnotation\n{\n\tutil::SetOnce<bool> isSimpleCounterLoop;\n};\n\nstruct ReturnAnnotation: StatementAnnotation\n{\n\t/// Reference to the return parameters of the function.\n\tParameterList const* functionReturnParameters = nullptr;\n\t/// Reference to the function containing the return statement.\n\tFunctionDefinition const* function = nullptr;\n};\n\nstruct TypeNameAnnotation: ASTAnnotation\n{\n\t/// Type declared by this type name, i.e. type of a variable where this type name is used.\n\t/// Set during reference resolution stage.\n\tType const* type = nullptr;\n};\n\nstruct IdentifierPathAnnotation: ASTAnnotation\n{\n\t/// Referenced declaration, set during reference resolution stage.\n\tDeclaration const* referencedDeclaration = nullptr;\n\t/// What kind of lookup needs to be done (static, virtual, super) find the declaration.\n\tutil::SetOnce<VirtualLookup> requiredLookup;\n\n\t/// Declaration of each path element.\n\tstd::vector<Declaration const*> pathDeclarations;\n};\n\nstruct ExpressionAnnotation: ASTAnnotation\n{\n\t/// Inferred type of the expression.\n\tType const* type = nullptr;\n\t/// Whether the expression is a constant variable\n\tutil::SetOnce<bool> isConstant;\n\t/// Whether the expression is pure, i.e. compile-time constant.\n\tutil::SetOnce<bool> isPure;\n\t/// Whether it is an LValue (i.e. something that can be assigned to).\n\tutil::SetOnce<bool> isLValue;\n\t/// Whether the expression is used in a context where the LValue is actually required.\n\tbool willBeWrittenTo = false;\n\n\t/// Types and - if given - names of arguments if the expr. is a function\n\t/// that is called, used for overload resolution\n\tstd::optional<FuncCallArguments> arguments;\n\n\t/// True if the expression consists solely of the name of the function and the function is called immediately\n\t/// instead of being stored or processed. The name may be qualified with the name of a contract, library\n\t/// module, etc., that clarifies the scope. For example: `m.L.f()`, where `m` is a module, `L` is a library\n\t/// and `f` is a function is a direct call. This means that the function to be called is known at compilation\n\t/// time and it's not necessary to rely on any runtime dispatch mechanism to resolve it.\n\t/// Note that even the simplest expressions, like `(f)()`, result in an indirect call even if they consist of\n\t/// values known at compilation time.\n\tbool calledDirectly = false;\n};\n\nstruct IdentifierAnnotation: ExpressionAnnotation\n{\n\t/// Referenced declaration, set at latest during overload resolution stage.\n\tDeclaration const* referencedDeclaration = nullptr;\n\t/// What kind of lookup needs to be done (static, virtual, super) find the declaration.\n\tutil::SetOnce<VirtualLookup> requiredLookup;\n\t/// List of possible declarations it could refer to (can contain duplicates).\n\tstd::vector<Declaration const*> candidateDeclarations;\n\t/// List of possible declarations it could refer to.\n\tstd::vector<Declaration const*> overloadedDeclarations;\n};\n\nstruct MemberAccessAnnotation: ExpressionAnnotation\n{\n\t/// Referenced declaration, set at latest during overload resolution stage.\n\tDeclaration const* referencedDeclaration = nullptr;\n\t/// What kind of lookup needs to be done (static, virtual, super) find the declaration.\n\tutil::SetOnce<VirtualLookup> requiredLookup;\n};\n\nstruct OperationAnnotation: ExpressionAnnotation\n{\n\tutil::SetOnce<FunctionDefinition const*> userDefinedFunction;\n};\n\nstruct BinaryOperationAnnotation: OperationAnnotation\n{\n\t/// The common type that is used for the operation, not necessarily the result type (which\n\t/// e.g. for comparisons is bool).\n\tType const* commonType = nullptr;\n};\n\nenum class FunctionCallKind\n{\n\tFunctionCall,\n\tTypeConversion,\n\tStructConstructorCall\n};\n\nstruct FunctionCallAnnotation: ExpressionAnnotation\n{\n\tutil::SetOnce<FunctionCallKind> kind;\n\t/// If true, this is the external call of a try statement.\n\tbool tryCall = false;\n};\n\n/// Experimental Solidity annotations.\n/// Used to integrate with name and type resolution.\n/// @{\nstruct TypeClassDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocumentedAnnotation\n{\n};\n\nstruct ForAllQuantifierAnnotation: StatementAnnotation, ScopableAnnotation\n{\n};\n/// @}\n\n}\n"
  },
  {
    "path": "libsolidity/ast/ASTEnums.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @date 2017\n * Enums for AST classes.\n */\n\n#pragma once\n\n#include <liblangutil/Exceptions.h>\n#include <libsolidity/ast/ASTForward.h>\n\n#include <string>\n\nnamespace solidity::frontend\n{\n\n/// Possible lookups for function resolving\nenum class VirtualLookup { Static, Virtual, Super };\n\n// How a function can mutate the EVM state.\nenum class StateMutability { Pure, View, NonPayable, Payable };\n\n/// Visibility ordered from restricted to unrestricted.\nenum class Visibility { Default, Private, Internal, Public, External };\n\nenum class Arithmetic { Checked, Wrapping };\n\ninline std::string stateMutabilityToString(StateMutability const& _stateMutability)\n{\n\tswitch (_stateMutability)\n\t{\n\tcase StateMutability::Pure:\n\t\treturn \"pure\";\n\tcase StateMutability::View:\n\t\treturn \"view\";\n\tcase StateMutability::NonPayable:\n\t\treturn \"nonpayable\";\n\tcase StateMutability::Payable:\n\t\treturn \"payable\";\n\tdefault:\n\t\tsolAssert(false, \"Unknown state mutability.\");\n\t}\n}\n\nclass Type;\n\n/// Container for function call parameter types & names\nstruct FuncCallArguments\n{\n\t/// Types of arguments\n\tstd::vector<Type const*> types;\n\t/// Names of the arguments if given, otherwise unset\n\tstd::vector<ASTPointer<ASTString>> names;\n\n\tsize_t numArguments() const { return types.size(); }\n\tsize_t numNames() const { return names.size(); }\n\tbool hasNamedArguments() const { return !names.empty(); }\n};\n\nenum class ContractKind { Interface, Contract, Library };\n\n}\n"
  },
  {
    "path": "libsolidity/ast/ASTForward.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Forward-declarations of AST classes.\n */\n\n#pragma once\n\n#include <memory>\n#include <string>\n#include <vector>\n\n// Forward-declare all AST node types and related enums.\n\nnamespace solidity::langutil\n{\nenum class Token : unsigned int;\n}\n\nnamespace solidity::frontend\n{\n\nclass ASTNode;\nclass ScopeOpener;\nclass SourceUnit;\nclass PragmaDirective;\nclass ImportDirective;\nclass Declaration;\nclass CallableDeclaration;\nclass OverrideSpecifier;\nclass ContractDefinition;\nclass InheritanceSpecifier;\nclass UsingForDirective;\nclass StructDefinition;\nclass EnumDefinition;\nclass EnumValue;\nclass UserDefinedValueTypeDefinition;\nclass ParameterList;\nclass FunctionDefinition;\nclass VariableDeclaration;\nclass ModifierDefinition;\nclass ModifierInvocation;\nclass EventDefinition;\nclass ErrorDefinition;\nclass MagicVariableDeclaration;\nclass TypeName;\nclass ElementaryTypeName;\nclass UserDefinedTypeName;\nclass FunctionTypeName;\nclass Mapping;\nclass ArrayTypeName;\nclass InlineAssembly;\nclass Statement;\nclass Block;\nclass PlaceholderStatement;\nclass IfStatement;\nclass TryCatchClause;\nclass TryStatement;\nclass BreakableStatement;\nclass WhileStatement;\nclass ForStatement;\nclass Continue;\nclass Break;\nclass Return;\nclass Throw;\nclass EmitStatement;\nclass VariableDeclarationStatement;\nclass ExpressionStatement;\nclass Expression;\nclass Conditional;\nclass Assignment;\nclass TupleExpression;\nclass UnaryOperation;\nclass BinaryOperation;\nclass FunctionCall;\nclass NewExpression;\nclass MemberAccess;\nclass IndexAccess;\nclass PrimaryExpression;\nclass Identifier;\nclass ElementaryTypeNameExpression;\nclass Literal;\nclass StructuredDocumentation;\nclass StorageLayoutSpecifier;\n\n/// Experimental Solidity nodes\n/// @{\nclass TypeClassDefinition;\nclass TypeClassInstantiation;\nclass TypeClassName;\nclass TypeDefinition;\nclass Builtin;\nclass ForAllQuantifier;\n/// @}\n\nclass VariableScope;\n\ntemplate <class T>\nstruct ASTCompareByID\n{\n\tusing is_transparent = void;\n\n\tbool operator()(T const* _lhs, T const* _rhs) const\n\t{\n\t\treturn _lhs->id() < _rhs->id();\n\t}\n\tbool operator()(T const* _lhs, int64_t _rhs) const\n\t{\n\t\treturn _lhs->id() < _rhs;\n\t}\n\tbool operator()(int64_t _lhs, T const* _rhs) const\n\t{\n\t\treturn _lhs < _rhs->id();\n\t}\n};\n\n// Used as pointers to AST nodes, to be replaced by more clever pointers, e.g. pointers which do\n// not do reference counting but point to a special memory area that is completely released\n// explicitly.\ntemplate <class T>\nusing ASTPointer = std::shared_ptr<T>;\n\nusing ASTString = std::string;\n\n}\n"
  },
  {
    "path": "libsolidity/ast/ASTJsonExporter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @date 2017\n * Converts the AST into json format\n */\n\n#include <libsolidity/ast/ASTJsonExporter.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n\n#include <libyul/AsmJsonConverter.h>\n#include <libyul/AST.h>\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <libsolutil/JSON.h>\n#include <libsolutil/UTF8.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Visitor.h>\n#include <libsolutil/Keccak256.h>\n\n#include <boost/algorithm/string/join.hpp>\n\n#include <utility>\n#include <vector>\n#include <algorithm>\n#include <limits>\n#include <type_traits>\n#include <range/v3/view/map.hpp>\n\nusing namespace std::string_literals;\nusing namespace solidity::langutil;\nusing namespace solidity;\n\nnamespace\n{\n\ntemplate<typename V, template<typename> typename C>\nvoid addIfSet(std::vector<std::pair<std::string, Json>>& _attributes, std::string const& _name, C<V> const& _value)\n{\n\tif constexpr (std::is_same_v<C<V>, solidity::util::SetOnce<V>>)\n\t{\n\t\tif (!_value.set())\n\t\t\treturn;\n\t}\n\telse if constexpr (std::is_same_v<C<V>, std::optional<V>>)\n\t{\n\t\tif (!_value.has_value())\n\t\t\treturn;\n\t}\n\n\t_attributes.emplace_back(_name, *_value);\n}\n\n}\n\nnamespace solidity::frontend\n{\n\nASTJsonExporter::ASTJsonExporter(CompilerStack::State _stackState, std::map<std::string, unsigned> _sourceIndices):\n\tm_stackState(_stackState),\n\tm_sourceIndices(std::move(_sourceIndices))\n{\n}\n\n\nvoid ASTJsonExporter::setJsonNode(\n\tASTNode const& _node,\n\tstd::string const& _nodeName,\n\tstd::initializer_list<std::pair<std::string, Json>>&& _attributes\n)\n{\n\tASTJsonExporter::setJsonNode(\n\t\t_node,\n\t\t_nodeName,\n\t\tstd::vector<std::pair<std::string, Json>>(std::move(_attributes))\n\t);\n}\n\nvoid ASTJsonExporter::setJsonNode(\n\tASTNode const& _node,\n\tstd::string const& _nodeType,\n\tstd::vector<std::pair<std::string, Json>>&& _attributes\n)\n{\n\tm_currentValue = Json::object();\n\tm_currentValue[\"id\"] = nodeId(_node);\n\tm_currentValue[\"src\"] = sourceLocationToString(_node.location());\n\tif (auto const* documented = dynamic_cast<Documented const*>(&_node))\n\t\tif (documented->documentation())\n\t\t\tm_currentValue[\"documentation\"] = *documented->documentation();\n\tm_currentValue[\"nodeType\"] = _nodeType;\n\tfor (auto& e: _attributes)\n\t\tm_currentValue[e.first] = std::move(e.second);\n}\n\nstd::optional<size_t> ASTJsonExporter::sourceIndexFromLocation(SourceLocation const& _location) const\n{\n\tif (_location.sourceName && m_sourceIndices.count(*_location.sourceName))\n\t\treturn m_sourceIndices.at(*_location.sourceName);\n\telse\n\t\treturn std::nullopt;\n}\n\nstd::string ASTJsonExporter::sourceLocationToString(SourceLocation const& _location) const\n{\n\tstd::optional<size_t> sourceIndexOpt = sourceIndexFromLocation(_location);\n\tint length = -1;\n\tif (_location.start >= 0 && _location.end >= 0)\n\t\tlength = _location.end - _location.start;\n\treturn std::to_string(_location.start) + \":\" + std::to_string(length) + \":\" + (sourceIndexOpt.has_value() ? std::to_string(sourceIndexOpt.value()) : \"-1\");\n}\n\nJson ASTJsonExporter::sourceLocationsToJson(std::vector<SourceLocation> const& _sourceLocations) const\n{\n\tJson locations = Json::array();\n\n\tfor (SourceLocation const& location: _sourceLocations)\n\t\tlocations.emplace_back(sourceLocationToString(location));\n\n\treturn locations;\n}\n\nstd::string ASTJsonExporter::namePathToString(std::vector<ASTString> const& _namePath)\n{\n\treturn boost::algorithm::join(_namePath, \".\"s);\n}\n\nJson ASTJsonExporter::typePointerToJson(Type const* _tp, bool _withoutDataLocation)\n{\n\tJson typeDescriptions;\n\ttypeDescriptions[\"typeString\"] = _tp ? Json(_tp->toString(_withoutDataLocation)) : Json();\n\ttypeDescriptions[\"typeIdentifier\"] = _tp ? Json(_tp->identifier()) : Json();\n\treturn typeDescriptions;\n\n}\nJson ASTJsonExporter::typePointerToJson(std::optional<FuncCallArguments> const& _tps)\n{\n\tif (_tps)\n\t{\n\t\tJson arguments = Json::array();\n\t\tfor (auto const& tp: _tps->types)\n\t\t\tappendMove(arguments, typePointerToJson(tp));\n\t\treturn arguments;\n\t}\n\telse\n\t\treturn Json();\n}\n\nvoid ASTJsonExporter::appendExpressionAttributes(\n\tstd::vector<std::pair<std::string, Json>>& _attributes,\n\tExpressionAnnotation const& _annotation\n)\n{\n\tstd::vector<std::pair<std::string, Json>> exprAttributes = {\n\t\tstd::make_pair(\"typeDescriptions\", typePointerToJson(_annotation.type)),\n\t\tstd::make_pair(\"argumentTypes\", typePointerToJson(_annotation.arguments))\n\t};\n\n\taddIfSet(exprAttributes, \"isLValue\", _annotation.isLValue);\n\taddIfSet(exprAttributes, \"isPure\", _annotation.isPure);\n\taddIfSet(exprAttributes, \"isConstant\", _annotation.isConstant);\n\n\tif (m_stackState > CompilerStack::State::ParsedAndImported)\n\t\texprAttributes.emplace_back(\"lValueRequested\", _annotation.willBeWrittenTo);\n\n\t_attributes += exprAttributes;\n}\n\nJson ASTJsonExporter::inlineAssemblyIdentifierToJson(std::pair<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const\n{\n\tJson tuple;\n\ttuple[\"src\"] = sourceLocationToString(nativeLocationOf(*_info.first));\n\ttuple[\"declaration\"] = idOrNull(_info.second.declaration);\n\ttuple[\"isSlot\"] = Json(_info.second.suffix == \"slot\");\n\ttuple[\"isOffset\"] = Json(_info.second.suffix == \"offset\");\n\n\tif (!_info.second.suffix.empty())\n\t\ttuple[\"suffix\"] = Json(_info.second.suffix);\n\n\ttuple[\"valueSize\"] = Json(static_cast<Json::number_integer_t>(_info.second.valueSize));\n\n\treturn tuple;\n}\n\nvoid ASTJsonExporter::print(std::ostream& _stream, ASTNode const& _node, util::JsonFormat const& _format)\n{\n\t_stream << util::jsonPrint(toJson(_node), _format);\n}\n\nJson ASTJsonExporter::toJson(ASTNode const& _node)\n{\n\t_node.accept(*this);\n\treturn util::removeNullMembers(std::move(m_currentValue));\n}\n\nJson ASTJsonExporter::toJson(ASTNode const* _node)\n{\n\tif (!_node)\n\t\treturn Json();\n\treturn toJson(*_node);\n}\n\nbool ASTJsonExporter::visit(SourceUnit const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"license\", _node.licenseString() ? Json(*_node.licenseString()) : Json()),\n\t\tstd::make_pair(\"nodes\", toJson(_node.nodes())),\n\t};\n\n\tif (_node.experimentalSolidity())\n\t\tattributes.emplace_back(\"experimentalSolidity\", Json(_node.experimentalSolidity()));\n\n\tif (_node.annotation().exportedSymbols.set())\n\t{\n\t\tJson exportedSymbols = Json::object();\n\t\tfor (auto const& sym: *_node.annotation().exportedSymbols)\n\t\t{\n\t\t\texportedSymbols[sym.first] = Json::array();\n\t\t\tfor (Declaration const* overload: sym.second)\n\t\t\t\texportedSymbols[sym.first].emplace_back(nodeId(*overload));\n\t\t}\n\n\t\tattributes.emplace_back(\"exportedSymbols\", exportedSymbols);\n\t};\n\n\taddIfSet(attributes, \"absolutePath\", _node.annotation().path);\n\n\tsetJsonNode(_node, \"SourceUnit\", std::move(attributes));\n\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(PragmaDirective const& _node)\n{\n\tJson literals = Json::array();\n\tfor (auto const& literal: _node.literals())\n\t\tliterals.emplace_back(literal);\n\tsetJsonNode(_node, \"PragmaDirective\", {\n\t\tstd::make_pair(\"literals\", std::move(literals))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(ImportDirective const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"file\", _node.path()),\n\t\tstd::make_pair(\"sourceUnit\", idOrNull(_node.annotation().sourceUnit)),\n\t\tstd::make_pair(\"scope\", idOrNull(_node.scope()))\n\t};\n\n\taddIfSet(attributes, \"absolutePath\", _node.annotation().absolutePath);\n\n\tattributes.emplace_back(\"unitAlias\", _node.name());\n\tattributes.emplace_back(\"nameLocation\", Json(sourceLocationToString(_node.nameLocation())));\n\n\tJson symbolAliases = Json::array();\n\tfor (auto const& symbolAlias: _node.symbolAliases())\n\t{\n\t\tJson tuple;\n\t\tsolAssert(symbolAlias.symbol, \"\");\n\t\ttuple[\"foreign\"] = toJson(*symbolAlias.symbol);\n\t\ttuple[\"local\"] =  symbolAlias.alias ? Json(*symbolAlias.alias) : Json();\n\t\ttuple[\"nameLocation\"] = sourceLocationToString(_node.nameLocation());\n\t\tsymbolAliases.emplace_back(tuple);\n\t}\n\tattributes.emplace_back(\"symbolAliases\", std::move(symbolAliases));\n\tsetJsonNode(_node, \"ImportDirective\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(StorageLayoutSpecifier const& _node)\n{\n\tsetJsonNode(_node, \"StorageLayoutSpecifier\", {\n\t\t{\"baseSlotExpression\", toJson(_node.baseSlotExpression())}\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(ContractDefinition const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"name\", _node.name()),\n\t\tstd::make_pair(\"nameLocation\", sourceLocationToString(_node.nameLocation())),\n\t\tstd::make_pair(\"documentation\", _node.documentation() ? toJson(*_node.documentation()) : Json()),\n\t\tstd::make_pair(\"contractKind\", contractKind(_node.contractKind())),\n\t\tstd::make_pair(\"abstract\", _node.abstract()),\n\t\tstd::make_pair(\"baseContracts\", toJson(_node.baseContracts())),\n\t\tstd::make_pair(\"contractDependencies\", getContainerIds(_node.annotation().contractDependencies | ranges::views::keys)),\n\t\t// Do not require call graph because the AST is also created for incorrect sources.\n\t\tstd::make_pair(\"usedEvents\", getContainerIds(_node.interfaceEvents(false))),\n\t\tstd::make_pair(\"usedErrors\", getContainerIds(_node.interfaceErrors(false))),\n\t\tstd::make_pair(\"nodes\", toJson(_node.subNodes())),\n\t\tstd::make_pair(\"scope\", idOrNull(_node.scope())),\n\t\tstd::make_pair(\"storageLayout\", toJson(_node.storageLayoutSpecifier()))\n\t};\n\taddIfSet(attributes, \"canonicalName\", _node.annotation().canonicalName);\n\n\tif (_node.annotation().unimplementedDeclarations.has_value())\n\t\tattributes.emplace_back(\"fullyImplemented\", _node.annotation().unimplementedDeclarations->empty());\n\tif (!_node.annotation().linearizedBaseContracts.empty())\n\t\tattributes.emplace_back(\"linearizedBaseContracts\", getContainerIds(_node.annotation().linearizedBaseContracts));\n\n\tif (!_node.annotation().internalFunctionIDs.empty())\n\t{\n\t\tJson internalFunctionIDs;\n\t\tfor (auto const& [functionDefinition, internalFunctionID]: _node.annotation().internalFunctionIDs)\n\t\t\tinternalFunctionIDs[std::to_string(functionDefinition->id())] = internalFunctionID;\n\t\tattributes.emplace_back(\"internalFunctionIDs\", std::move(internalFunctionIDs));\n\t}\n\n\tsetJsonNode(_node, \"ContractDefinition\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(IdentifierPath const& _node)\n{\n\tJson nameLocations = Json::array();\n\n\tfor (SourceLocation location: _node.pathLocations())\n\t\tnameLocations.emplace_back(sourceLocationToString(location));\n\n\tsetJsonNode(_node, \"IdentifierPath\", {\n\t\tstd::make_pair(\"name\", namePathToString(_node.path())),\n\t\tstd::make_pair(\"nameLocations\", nameLocations),\n\t\tstd::make_pair(\"referencedDeclaration\", idOrNull(_node.annotation().referencedDeclaration))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(InheritanceSpecifier const& _node)\n{\n\tsetJsonNode(_node, \"InheritanceSpecifier\", {\n\t\tstd::make_pair(\"baseName\", toJson(_node.name())),\n\t\tstd::make_pair(\"arguments\", _node.arguments() ? toJson(*_node.arguments()) : Json())\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(UsingForDirective const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"typeName\", _node.typeName() ? toJson(*_node.typeName()) : Json())\n\t};\n\n\tif (_node.usesBraces())\n\t{\n\t\tJson functionList = Json::array();\n\t\tfor (auto&& [function, op]: _node.functionsAndOperators())\n\t\t{\n\t\t\tJson functionNode;\n\t\t\tif (!op.has_value())\n\t\t\t\tfunctionNode[\"function\"] = toJson(*function);\n\t\t\telse\n\t\t\t{\n\t\t\t\tfunctionNode[\"definition\"] = toJson(*function);\n\t\t\t\tfunctionNode[\"operator\"] = std::string(TokenTraits::toString(*op));\n\t\t\t}\n\t\t\tfunctionList.emplace_back(std::move(functionNode));\n\t\t}\n\t\tattributes.emplace_back(\"functionList\", std::move(functionList));\n\t}\n\telse\n\t{\n\t\tauto const& functionAndOperators = _node.functionsAndOperators();\n\t\tsolAssert(_node.functionsAndOperators().size() == 1);\n\t\tsolAssert(!functionAndOperators.front().second.has_value());\n\t\tattributes.emplace_back(\"libraryName\", toJson(*(functionAndOperators.front().first)));\n\t}\n\tattributes.emplace_back(\"global\", _node.global());\n\n\tsetJsonNode(_node, \"UsingForDirective\", std::move(attributes));\n\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(StructDefinition const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"name\", _node.name()),\n\t\tstd::make_pair(\"nameLocation\", sourceLocationToString(_node.nameLocation())),\n\t\tstd::make_pair(\"documentation\", _node.documentation() ? toJson(*_node.documentation()) : Json()),\n\t\tstd::make_pair(\"visibility\", Declaration::visibilityToString(_node.visibility())),\n\t\tstd::make_pair(\"members\", toJson(_node.members())),\n\t\tstd::make_pair(\"scope\", idOrNull(_node.scope()))\n\t};\n\n\taddIfSet(attributes,\"canonicalName\", _node.annotation().canonicalName);\n\n\tsetJsonNode(_node, \"StructDefinition\", std::move(attributes));\n\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(EnumDefinition const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"name\", _node.name()),\n\t\tstd::make_pair(\"nameLocation\", sourceLocationToString(_node.nameLocation())),\n\t\tstd::make_pair(\"documentation\", _node.documentation() ? toJson(*_node.documentation()) : Json()),\n\t\tstd::make_pair(\"members\", toJson(_node.members()))\n\t};\n\n\taddIfSet(attributes,\"canonicalName\", _node.annotation().canonicalName);\n\n\tsetJsonNode(_node, \"EnumDefinition\", std::move(attributes));\n\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(EnumValue const& _node)\n{\n\tsetJsonNode(_node, \"EnumValue\", {\n\t\tstd::make_pair(\"name\", _node.name()),\n\t\tstd::make_pair(\"nameLocation\", sourceLocationToString(_node.nameLocation())),\n\t\tstd::make_pair(\"documentation\", toJson(_node.documentation().get())),\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(UserDefinedValueTypeDefinition const& _node)\n{\n\tsolAssert(_node.underlyingType(), \"\");\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"name\", _node.name()),\n\t\tstd::make_pair(\"nameLocation\", sourceLocationToString(_node.nameLocation())),\n\t\tstd::make_pair(\"underlyingType\", toJson(*_node.underlyingType()))\n\t};\n\taddIfSet(attributes, \"canonicalName\", _node.annotation().canonicalName);\n\n\tsetJsonNode(_node, \"UserDefinedValueTypeDefinition\", std::move(attributes));\n\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(ParameterList const& _node)\n{\n\tsetJsonNode(_node, \"ParameterList\", {\n\t\tstd::make_pair(\"parameters\", toJson(_node.parameters()))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(OverrideSpecifier const& _node)\n{\n\tsetJsonNode(_node, \"OverrideSpecifier\", {\n\t\tstd::make_pair(\"overrides\", toJson(_node.overrides()))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(FunctionDefinition const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"name\", _node.name()),\n\t\tstd::make_pair(\"nameLocation\", sourceLocationToString(_node.nameLocation())),\n\t\tstd::make_pair(\"documentation\", _node.documentation() ? toJson(*_node.documentation()) : Json()),\n\t\tstd::make_pair(\"kind\", _node.isFree() ? \"freeFunction\" : TokenTraits::toString(_node.kind())),\n\t\tstd::make_pair(\"stateMutability\", stateMutabilityToString(_node.stateMutability())),\n\t\tstd::make_pair(\"virtual\", _node.markedVirtual()),\n\t\tstd::make_pair(\"overrides\", _node.overrides() ? toJson(*_node.overrides()) : Json()),\n\t\tstd::make_pair(\"parameters\", toJson(_node.parameterList())),\n\t\tstd::make_pair(\"returnParameters\", toJson(*_node.returnParameterList())),\n\t\tstd::make_pair(\"modifiers\", toJson(_node.modifiers())),\n\t\tstd::make_pair(\"body\", _node.isImplemented() ? toJson(_node.body()) : Json()),\n\t\tstd::make_pair(\"implemented\", _node.isImplemented()),\n\t\tstd::make_pair(\"scope\", idOrNull(_node.scope()))\n\t};\n\n\tstd::optional<Visibility> visibility;\n\tif (_node.isConstructor())\n\t{\n\t\tif (_node.annotation().contract)\n\t\t\tvisibility = _node.annotation().contract->abstract() ? Visibility::Internal : Visibility::Public;\n\t}\n\telse\n\t\tvisibility = _node.visibility();\n\n\tif (visibility)\n\t\tattributes.emplace_back(\"visibility\", Declaration::visibilityToString(*visibility));\n\n\tif (_node.isPartOfExternalInterface() && m_stackState > CompilerStack::State::ParsedAndImported)\n\t\tattributes.emplace_back(\"functionSelector\", _node.externalIdentifierHex());\n\tif (!_node.annotation().baseFunctions.empty())\n\t\tattributes.emplace_back(std::make_pair(\"baseFunctions\", getContainerIds(_node.annotation().baseFunctions, true)));\n\n\tsetJsonNode(_node, \"FunctionDefinition\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(VariableDeclaration const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"name\", _node.name()),\n\t\tstd::make_pair(\"nameLocation\", sourceLocationToString(_node.nameLocation())),\n\t\tstd::make_pair(\"typeName\", toJson(_node.typeName())),\n\t\tstd::make_pair(\"constant\", _node.isConstant()),\n\t\tstd::make_pair(\"mutability\", VariableDeclaration::mutabilityToString(_node.mutability())),\n\t\tstd::make_pair(\"stateVariable\", _node.isStateVariable()),\n\t\tstd::make_pair(\"storageLocation\", location(_node.referenceLocation())),\n\t\tstd::make_pair(\"overrides\", _node.overrides() ? toJson(*_node.overrides()) : Json()),\n\t\tstd::make_pair(\"visibility\", Declaration::visibilityToString(_node.visibility())),\n\t\tstd::make_pair(\"value\", _node.value() ? toJson(*_node.value()) : Json()),\n\t\tstd::make_pair(\"scope\", idOrNull(_node.scope())),\n\t\tstd::make_pair(\"typeDescriptions\", typePointerToJson(_node.annotation().type, true))\n\t};\n\tif (_node.isStateVariable() && _node.isPublic())\n\t\tattributes.emplace_back(\"functionSelector\", _node.externalIdentifierHex());\n\tif (_node.isStateVariable() && _node.documentation())\n\t\tattributes.emplace_back(\"documentation\", toJson(*_node.documentation()));\n\tif (m_inEvent)\n\t\tattributes.emplace_back(\"indexed\", _node.isIndexed());\n\tif (!_node.annotation().baseFunctions.empty())\n\t\tattributes.emplace_back(std::make_pair(\"baseFunctions\", getContainerIds(_node.annotation().baseFunctions, true)));\n\tsetJsonNode(_node, \"VariableDeclaration\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(ModifierDefinition const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"name\", _node.name()),\n\t\tstd::make_pair(\"nameLocation\", sourceLocationToString(_node.nameLocation())),\n\t\tstd::make_pair(\"documentation\", _node.documentation() ? toJson(*_node.documentation()) : Json()),\n\t\tstd::make_pair(\"visibility\", Declaration::visibilityToString(_node.visibility())),\n\t\tstd::make_pair(\"parameters\", toJson(_node.parameterList())),\n\t\tstd::make_pair(\"virtual\", _node.markedVirtual()),\n\t\tstd::make_pair(\"overrides\", _node.overrides() ? toJson(*_node.overrides()) : Json()),\n\t\tstd::make_pair(\"body\", _node.isImplemented() ? toJson(_node.body()) : Json())\n\t};\n\tif (!_node.annotation().baseFunctions.empty())\n\t\tattributes.emplace_back(std::make_pair(\"baseModifiers\", getContainerIds(_node.annotation().baseFunctions, true)));\n\tsetJsonNode(_node, \"ModifierDefinition\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(ModifierInvocation const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes{\n\t\tstd::make_pair(\"modifierName\", toJson(_node.name())),\n\t\tstd::make_pair(\"arguments\", _node.arguments() ? toJson(*_node.arguments()) : Json())\n\t};\n\tif (Declaration const* declaration = _node.name().annotation().referencedDeclaration)\n\t{\n\t\tif (dynamic_cast<ModifierDefinition const*>(declaration))\n\t\t\tattributes.emplace_back(\"kind\", \"modifierInvocation\");\n\t\telse if (dynamic_cast<ContractDefinition const*>(declaration))\n\t\t\tattributes.emplace_back(\"kind\", \"baseConstructorSpecifier\");\n\t}\n\tsetJsonNode(_node, \"ModifierInvocation\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(EventDefinition const& _node)\n{\n\tm_inEvent = true;\n\tstd::vector<std::pair<std::string, Json>> _attributes = {\n\t\tstd::make_pair(\"name\", _node.name()),\n\t\tstd::make_pair(\"nameLocation\", sourceLocationToString(_node.nameLocation())),\n\t\tstd::make_pair(\"documentation\", _node.documentation() ? toJson(*_node.documentation()) : Json()),\n\t\tstd::make_pair(\"parameters\", toJson(_node.parameterList())),\n\t\tstd::make_pair(\"anonymous\", _node.isAnonymous())\n\t};\n\tif (m_stackState >= CompilerStack::State::AnalysisSuccessful)\n\t\t\t_attributes.emplace_back(\n\t\t\t\tstd::make_pair(\n\t\t\t\t\t\"eventSelector\",\n\t\t\t\t\ttoHex(u256(util::h256::Arith(util::keccak256(_node.functionType(true)->externalSignature()))))\n\t\t\t\t));\n\n\tsetJsonNode(_node, \"EventDefinition\", std::move(_attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(ErrorDefinition const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> _attributes = {\n\t\tstd::make_pair(\"name\", _node.name()),\n\t\tstd::make_pair(\"nameLocation\", sourceLocationToString(_node.nameLocation())),\n\t\tstd::make_pair(\"documentation\", _node.documentation() ? toJson(*_node.documentation()) : Json()),\n\t\tstd::make_pair(\"parameters\", toJson(_node.parameterList()))\n\t};\n\tif (m_stackState >= CompilerStack::State::AnalysisSuccessful)\n\t\t_attributes.emplace_back(std::make_pair(\"errorSelector\", _node.functionType(true)->externalIdentifierHex()));\n\n\tsetJsonNode(_node, \"ErrorDefinition\", std::move(_attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(ElementaryTypeName const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"name\", _node.typeName().toString()),\n\t\tstd::make_pair(\"typeDescriptions\", typePointerToJson(_node.annotation().type, true))\n\t};\n\n\tif (_node.stateMutability())\n\t\tattributes.emplace_back(std::make_pair(\"stateMutability\", stateMutabilityToString(*_node.stateMutability())));\n\n\tsetJsonNode(_node, \"ElementaryTypeName\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(UserDefinedTypeName const& _node)\n{\n\tsetJsonNode(_node, \"UserDefinedTypeName\", {\n\t\tstd::make_pair(\"pathNode\", toJson(_node.pathNode())),\n\t\tstd::make_pair(\"referencedDeclaration\", idOrNull(_node.pathNode().annotation().referencedDeclaration)),\n\t\tstd::make_pair(\"typeDescriptions\", typePointerToJson(_node.annotation().type, true))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(FunctionTypeName const& _node)\n{\n\tsetJsonNode(_node, \"FunctionTypeName\", {\n\t\tstd::make_pair(\"visibility\", Declaration::visibilityToString(_node.visibility())),\n\t\tstd::make_pair(\"stateMutability\", stateMutabilityToString(_node.stateMutability())),\n\t\tstd::make_pair(\"parameterTypes\", toJson(*_node.parameterTypeList())),\n\t\tstd::make_pair(\"returnParameterTypes\", toJson(*_node.returnParameterTypeList())),\n\t\tstd::make_pair(\"typeDescriptions\", typePointerToJson(_node.annotation().type, true))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(Mapping const& _node)\n{\n\tsetJsonNode(_node, \"Mapping\", {\n\t\tstd::make_pair(\"keyType\", toJson(_node.keyType())),\n\t\tstd::make_pair(\"keyName\", _node.keyName()),\n\t\tstd::make_pair(\"keyNameLocation\", sourceLocationToString(_node.keyNameLocation())),\n\t\tstd::make_pair(\"valueType\", toJson(_node.valueType())),\n\t\tstd::make_pair(\"valueName\", _node.valueName()),\n\t\tstd::make_pair(\"valueNameLocation\", sourceLocationToString(_node.valueNameLocation())),\n\t\tstd::make_pair(\"typeDescriptions\", typePointerToJson(_node.annotation().type, true))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(ArrayTypeName const& _node)\n{\n\tsetJsonNode(_node, \"ArrayTypeName\", {\n\t\tstd::make_pair(\"baseType\", toJson(_node.baseType())),\n\t\tstd::make_pair(\"length\", toJsonOrNull(_node.length())),\n\t\tstd::make_pair(\"typeDescriptions\", typePointerToJson(_node.annotation().type, true))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(InlineAssembly const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> externalReferences;\n\n\tfor (auto const& it: _node.annotation().externalReferences)\n\t\tif (it.first)\n\t\t\texternalReferences.emplace_back(std::make_pair(\n\t\t\t\tit.first->name.str(),\n\t\t\t\tinlineAssemblyIdentifierToJson(it)\n\t\t\t));\n\n\tJson externalReferencesJson = Json::array();\n\n\tstd::sort(externalReferences.begin(), externalReferences.end());\n\tfor (Json& it: externalReferences | ranges::views::values)\n\t\texternalReferencesJson.emplace_back(std::move(it));\n\n\tauto const& evmDialect = dynamic_cast<solidity::yul::EVMDialect const&>(_node.dialect());\n\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"AST\", Json(yul::AsmJsonConverter(evmDialect, sourceIndexFromLocation(_node.location()))(_node.operations().root()))),\n\t\tstd::make_pair(\"externalReferences\", std::move(externalReferencesJson)),\n\t\tstd::make_pair(\"evmVersion\", evmDialect.evmVersion().name())\n\t};\n\n\t// TODO: Add test in test/linsolidity/ASTJSON/assembly. This requires adding support for eofVersion in ASTJSONTest\n\tif (evmDialect.eofVersion())\n\t{\n\t\tsolAssert(*evmDialect.eofVersion() > 0);\n\t\tattributes.push_back(std::make_pair(\"eofVersion\", *evmDialect.eofVersion()));\n\t}\n\n\tif (_node.flags())\n\t{\n\t\tJson flags = Json::array();\n\t\tfor (auto const& flag: *_node.flags())\n\t\t\tif (flag)\n\t\t\t\tflags.emplace_back(*flag);\n\t\t\telse\n\t\t\t\tflags.emplace_back(Json());\n\t\tattributes.emplace_back(std::make_pair(\"flags\", std::move(flags)));\n\t}\n\tsetJsonNode(_node, \"InlineAssembly\", std::move(attributes));\n\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(Block const& _node)\n{\n\tsetJsonNode(_node, _node.unchecked() ? \"UncheckedBlock\" : \"Block\", {\n\t\tstd::make_pair(\"statements\", toJson(_node.statements()))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(PlaceholderStatement const& _node)\n{\n\tsetJsonNode(_node, \"PlaceholderStatement\", {});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(IfStatement const& _node)\n{\n\tsetJsonNode(_node, \"IfStatement\", {\n\t\tstd::make_pair(\"condition\", toJson(_node.condition())),\n\t\tstd::make_pair(\"trueBody\", toJson(_node.trueStatement())),\n\t\tstd::make_pair(\"falseBody\", toJsonOrNull(_node.falseStatement()))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(TryCatchClause const& _node)\n{\n\tsetJsonNode(_node, \"TryCatchClause\", {\n\t\tstd::make_pair(\"errorName\", _node.errorName()),\n\t\tstd::make_pair(\"parameters\", toJsonOrNull(_node.parameters())),\n\t\tstd::make_pair(\"block\", toJson(_node.block()))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(TryStatement const& _node)\n{\n\tsetJsonNode(_node, \"TryStatement\", {\n\t\tstd::make_pair(\"externalCall\", toJson(_node.externalCall())),\n\t\tstd::make_pair(\"clauses\", toJson(_node.clauses()))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(WhileStatement const& _node)\n{\n\tsetJsonNode(\n\t\t_node,\n\t\t_node.isDoWhile() ? \"DoWhileStatement\" : \"WhileStatement\",\n\t\t{\n\t\t\tstd::make_pair(\"condition\", toJson(_node.condition())),\n\t\t\tstd::make_pair(\"body\", toJson(_node.body()))\n\t\t}\n\t);\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(ForStatement const& _node)\n{\n\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"initializationExpression\", toJsonOrNull(_node.initializationExpression())),\n\t\tstd::make_pair(\"condition\", toJsonOrNull(_node.condition())),\n\t\tstd::make_pair(\"loopExpression\", toJsonOrNull(_node.loopExpression())),\n\t\tstd::make_pair(\"body\", toJson(_node.body()))\n\t};\n\n\tif (_node.annotation().isSimpleCounterLoop.set())\n\t\tattributes.emplace_back(\"isSimpleCounterLoop\", *_node.annotation().isSimpleCounterLoop);\n\n\tsetJsonNode(_node, \"ForStatement\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(Continue const& _node)\n{\n\tsetJsonNode(_node, \"Continue\", {});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(Break const& _node)\n{\n\tsetJsonNode(_node, \"Break\", {});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(Return const& _node)\n{\n\tsetJsonNode(_node, \"Return\", {\n\t\tstd::make_pair(\"expression\", toJsonOrNull(_node.expression())),\n\t\tstd::make_pair(\"functionReturnParameters\", idOrNull(_node.annotation().functionReturnParameters))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(Throw const& _node)\n{\n\tsetJsonNode(_node, \"Throw\", {});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(EmitStatement const& _node)\n{\n\tsetJsonNode(_node, \"EmitStatement\", {\n\t\tstd::make_pair(\"eventCall\", toJson(_node.eventCall()))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(RevertStatement const& _node)\n{\n\tsetJsonNode(_node, \"RevertStatement\", {\n\t\tstd::make_pair(\"errorCall\", toJson(_node.errorCall()))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(VariableDeclarationStatement const& _node)\n{\n\tJson varDecs = Json::array();\n\tfor (auto const& v: _node.declarations())\n\t\tappendMove(varDecs, idOrNull(v.get()));\n\tsetJsonNode(_node, \"VariableDeclarationStatement\", {\n\t\tstd::make_pair(\"assignments\", std::move(varDecs)),\n\t\tstd::make_pair(\"declarations\", toJson(_node.declarations())),\n\t\tstd::make_pair(\"initialValue\", toJsonOrNull(_node.initialValue()))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(ExpressionStatement const& _node)\n{\n\tsetJsonNode(_node, \"ExpressionStatement\", {\n\t\tstd::make_pair(\"expression\", toJson(_node.expression()))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(Conditional const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"condition\", toJson(_node.condition())),\n\t\tstd::make_pair(\"trueExpression\", toJson(_node.trueExpression())),\n\t\tstd::make_pair(\"falseExpression\", toJson(_node.falseExpression()))\n\t};\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"Conditional\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(Assignment const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"operator\", TokenTraits::toString(_node.assignmentOperator())),\n\t\tstd::make_pair(\"leftHandSide\", toJson(_node.leftHandSide())),\n\t\tstd::make_pair(\"rightHandSide\", toJson(_node.rightHandSide()))\n\t};\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"Assignment\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(TupleExpression const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"isInlineArray\", Json(_node.isInlineArray())),\n\t\tstd::make_pair(\"components\", toJson(_node.components())),\n\t};\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"TupleExpression\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(UnaryOperation const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"prefix\", _node.isPrefixOperation()),\n\t\tstd::make_pair(\"operator\", TokenTraits::toString(_node.getOperator())),\n\t\tstd::make_pair(\"subExpression\", toJson(_node.subExpression()))\n\t};\n\t// NOTE: This annotation is guaranteed to be set but only if we didn't stop at the parsing stage.\n\tif (_node.annotation().userDefinedFunction.set() && *_node.annotation().userDefinedFunction != nullptr)\n\t\tattributes.emplace_back(\"function\", nodeId(**_node.annotation().userDefinedFunction));\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"UnaryOperation\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(BinaryOperation const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"operator\", TokenTraits::toString(_node.getOperator())),\n\t\tstd::make_pair(\"leftExpression\", toJson(_node.leftExpression())),\n\t\tstd::make_pair(\"rightExpression\", toJson(_node.rightExpression())),\n\t\tstd::make_pair(\"commonType\", typePointerToJson(_node.annotation().commonType)),\n\t};\n\t// NOTE: This annotation is guaranteed to be set but only if we didn't stop at the parsing stage.\n\tif (_node.annotation().userDefinedFunction.set() && *_node.annotation().userDefinedFunction != nullptr)\n\t\tattributes.emplace_back(\"function\", nodeId(**_node.annotation().userDefinedFunction));\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"BinaryOperation\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(FunctionCall const& _node)\n{\n\tJson names = Json::array();\n\tfor (auto const& name: _node.names())\n\t\tnames.push_back(Json(*name));\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"expression\", toJson(_node.expression())),\n\t\tstd::make_pair(\"names\", std::move(names)),\n\t\tstd::make_pair(\"nameLocations\", sourceLocationsToJson(_node.nameLocations())),\n\t\tstd::make_pair(\"arguments\", toJson(_node.arguments())),\n\t\tstd::make_pair(\"tryCall\", _node.annotation().tryCall)\n\t};\n\n\tif (_node.annotation().kind.set())\n\t{\n\t\tFunctionCallKind nodeKind = *_node.annotation().kind;\n\t\tattributes.emplace_back(\"kind\", functionCallKind(nodeKind));\n\t}\n\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"FunctionCall\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(FunctionCallOptions const& _node)\n{\n\tJson names = Json::array();\n\tfor (auto const& name: _node.names())\n\t\tnames.emplace_back(Json(*name));\n\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"expression\", toJson(_node.expression())),\n\t\tstd::make_pair(\"names\", std::move(names)),\n\t\tstd::make_pair(\"options\", toJson(_node.options())),\n\t};\n\tappendExpressionAttributes(attributes, _node.annotation());\n\n\tsetJsonNode(_node, \"FunctionCallOptions\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(NewExpression const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"typeName\", toJson(_node.typeName()))\n\t};\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"NewExpression\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(MemberAccess const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"memberName\", _node.memberName()),\n\t\tstd::make_pair(\"memberLocation\", Json(sourceLocationToString(_node.memberLocation()))),\n\t\tstd::make_pair(\"expression\", toJson(_node.expression())),\n\t\tstd::make_pair(\"referencedDeclaration\", idOrNull(_node.annotation().referencedDeclaration)),\n\t};\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"MemberAccess\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(IndexAccess const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"baseExpression\", toJson(_node.baseExpression())),\n\t\tstd::make_pair(\"indexExpression\", toJsonOrNull(_node.indexExpression())),\n\t};\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"IndexAccess\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(IndexRangeAccess const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"baseExpression\", toJson(_node.baseExpression())),\n\t\tstd::make_pair(\"startExpression\", toJsonOrNull(_node.startExpression())),\n\t\tstd::make_pair(\"endExpression\", toJsonOrNull(_node.endExpression())),\n\t};\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"IndexRangeAccess\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(Identifier const& _node)\n{\n\tJson overloads = Json::array();\n\tfor (auto const& dec: _node.annotation().overloadedDeclarations)\n\t\toverloads.emplace_back(nodeId(*dec));\n\tsetJsonNode(_node, \"Identifier\", {\n\t\tstd::make_pair(\"name\", _node.name()),\n\t\tstd::make_pair(\"referencedDeclaration\", idOrNull(_node.annotation().referencedDeclaration)),\n\t\tstd::make_pair(\"overloadedDeclarations\", overloads),\n\t\tstd::make_pair(\"typeDescriptions\", typePointerToJson(_node.annotation().type)),\n\t\tstd::make_pair(\"argumentTypes\", typePointerToJson(_node.annotation().arguments))\n\t});\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(ElementaryTypeNameExpression const& _node)\n{\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"typeName\", toJson(_node.type()))\n\t};\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"ElementaryTypeNameExpression\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(Literal const& _node)\n{\n\tJson value = _node.value();\n\tif (!util::validateUTF8(_node.value()))\n\t\tvalue = Json();\n\tToken subdenomination = Token(_node.subDenomination());\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"kind\", literalTokenKind(_node.token())),\n\t\tstd::make_pair(\"value\", value),\n\t\tstd::make_pair(\"hexValue\", util::toHex(util::asBytes(_node.value()))),\n\t\tstd::make_pair(\n\t\t\t\"subdenomination\",\n\t\t\tsubdenomination == Token::Illegal ?\n\t\t\tJson() :\n\t\t\tJson(TokenTraits::toString(subdenomination))\n\t\t)\n\t};\n\tappendExpressionAttributes(attributes, _node.annotation());\n\tsetJsonNode(_node, \"Literal\", std::move(attributes));\n\treturn false;\n}\n\nbool ASTJsonExporter::visit(StructuredDocumentation const& _node)\n{\n\tJson text = *_node.text();\n\tstd::vector<std::pair<std::string, Json>> attributes = {\n\t\tstd::make_pair(\"text\", text)\n\t};\n\tsetJsonNode(_node, \"StructuredDocumentation\", std::move(attributes));\n\treturn false;\n}\n\nvoid ASTJsonExporter::endVisit(EventDefinition const&)\n{\n\tm_inEvent = false;\n}\n\nbool ASTJsonExporter::visitNode(ASTNode const& _node)\n{\n\tsolAssert(false, _node.experimentalSolidityOnly() ?\n\t\t\"Attempt to export an AST of experimental solidity.\" :\n\t\t\"Attempt to export an AST that contains unexpected nodes.\"\n\t);\n\treturn false;\n}\n\nstd::string ASTJsonExporter::location(VariableDeclaration::Location _location)\n{\n\tswitch (_location)\n\t{\n\tcase VariableDeclaration::Location::Unspecified:\n\t\treturn \"default\";\n\tcase VariableDeclaration::Location::Storage:\n\t\treturn \"storage\";\n\tcase VariableDeclaration::Location::Memory:\n\t\treturn \"memory\";\n\tcase VariableDeclaration::Location::CallData:\n\t\treturn \"calldata\";\n\tcase VariableDeclaration::Location::Transient:\n\t\treturn \"transient\";\n\t}\n\t// To make the compiler happy\n\treturn {};\n}\n\nstd::string ASTJsonExporter::contractKind(ContractKind _kind)\n{\n\tswitch (_kind)\n\t{\n\tcase ContractKind::Interface:\n\t\treturn \"interface\";\n\tcase ContractKind::Contract:\n\t\treturn \"contract\";\n\tcase ContractKind::Library:\n\t\treturn \"library\";\n\t}\n\n\t// To make the compiler happy\n\treturn {};\n}\n\nstd::string ASTJsonExporter::functionCallKind(FunctionCallKind _kind)\n{\n\tswitch (_kind)\n\t{\n\tcase FunctionCallKind::FunctionCall:\n\t\treturn \"functionCall\";\n\tcase FunctionCallKind::TypeConversion:\n\t\treturn \"typeConversion\";\n\tcase FunctionCallKind::StructConstructorCall:\n\t\treturn \"structConstructorCall\";\n\tdefault:\n\t\tsolAssert(false, \"Unknown kind of function call.\");\n\t}\n}\n\nstd::string ASTJsonExporter::literalTokenKind(Token _token)\n{\n\tswitch (_token)\n\t{\n\tcase Token::Number:\n\t\treturn \"number\";\n\tcase Token::StringLiteral:\n\t\treturn \"string\";\n\tcase Token::UnicodeStringLiteral:\n\t\treturn \"unicodeString\";\n\tcase Token::HexStringLiteral:\n\t\treturn \"hexString\";\n\tcase Token::TrueLiteral:\n\tcase Token::FalseLiteral:\n\t\treturn \"bool\";\n\tdefault:\n\t\tsolAssert(false, \"Unknown kind of literal token.\");\n\t}\n}\n\nstd::string ASTJsonExporter::type(Expression const& _expression)\n{\n\treturn _expression.annotation().type ? _expression.annotation().type->toString() : \"Unknown\";\n}\n\nstd::string ASTJsonExporter::type(VariableDeclaration const& _varDecl)\n{\n\treturn _varDecl.annotation().type ? _varDecl.annotation().type->toString() : \"Unknown\";\n}\n\n}\n"
  },
  {
    "path": "libsolidity/ast/ASTJsonExporter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Lefteris <lefteris@ethdev.com>\n * @date 2015\n * Converts the AST into json format\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/interface/CompilerStack.h>\n#include <liblangutil/Exceptions.h>\n\n#include <libsolutil/JSON.h>\n\n#include <algorithm>\n#include <optional>\n#include <ostream>\n#include <stack>\n#include <vector>\n\nnamespace solidity::langutil\n{\nstruct SourceLocation;\n}\n\nnamespace solidity::frontend\n{\n\n/**\n * Converter of the AST into JSON format\n */\nclass ASTJsonExporter: public ASTConstVisitor\n{\npublic:\n\t/// Create a converter to JSON for the given abstract syntax tree.\n\t/// @a _stackState state of the compiler stack to avoid outputting incomplete data\n\t/// @a _sourceIndices is used to abbreviate source names in source locations.\n\texplicit ASTJsonExporter(\n\t\tCompilerStack::State _stackState,\n\t\tstd::map<std::string, unsigned> _sourceIndices = std::map<std::string, unsigned>()\n\t);\n\t/// Output the json representation of the AST to _stream.\n\tvoid print(std::ostream& _stream, ASTNode const& _node, util::JsonFormat const& _format);\n\tJson toJson(ASTNode const& _node);\n\tJson toJson(ASTNode const* _node);\n\ttemplate <class T>\n\tJson toJson(std::vector<ASTPointer<T>> const& _nodes)\n\t{\n\t\tJson ret = Json::array();\n\t\tfor (auto const& n: _nodes)\n\t\t\tif (n)\n\t\t\t\tappendMove(ret, toJson(*n));\n\t\t\telse\n\t\t\t\tret.emplace_back(Json());\n\t\treturn ret;\n\t}\n\tbool visit(SourceUnit const& _node) override;\n\tbool visit(PragmaDirective const& _node) override;\n\tbool visit(ImportDirective const& _node) override;\n\tbool visit(ContractDefinition const& _node) override;\n\tbool visit(IdentifierPath const& _node) override;\n\tbool visit(InheritanceSpecifier const& _node) override;\n\tbool visit(UsingForDirective const& _node) override;\n\tbool visit(StructDefinition const& _node) override;\n\tbool visit(EnumDefinition const& _node) override;\n\tbool visit(EnumValue const& _node) override;\n\tbool visit(UserDefinedValueTypeDefinition const& _node) override;\n\tbool visit(ParameterList const& _node) override;\n\tbool visit(OverrideSpecifier const& _node) override;\n\tbool visit(FunctionDefinition const& _node) override;\n\tbool visit(VariableDeclaration const& _node) override;\n\tbool visit(ModifierDefinition const& _node) override;\n\tbool visit(ModifierInvocation const& _node) override;\n\tbool visit(EventDefinition const& _node) override;\n\tbool visit(ErrorDefinition const& _node) override;\n\tbool visit(ElementaryTypeName const& _node) override;\n\tbool visit(UserDefinedTypeName const& _node) override;\n\tbool visit(FunctionTypeName const& _node) override;\n\tbool visit(Mapping const& _node) override;\n\tbool visit(ArrayTypeName const& _node) override;\n\tbool visit(InlineAssembly const& _node) override;\n\tbool visit(Block const& _node) override;\n\tbool visit(PlaceholderStatement const& _node) override;\n\tbool visit(IfStatement const& _node) override;\n\tbool visit(TryCatchClause const& _node) override;\n\tbool visit(TryStatement const& _node) override;\n\tbool visit(WhileStatement const& _node) override;\n\tbool visit(ForStatement const& _node) override;\n\tbool visit(Continue const& _node) override;\n\tbool visit(Break const& _node) override;\n\tbool visit(Return const& _node) override;\n\tbool visit(Throw const& _node) override;\n\tbool visit(EmitStatement const& _node) override;\n\tbool visit(RevertStatement const& _node) override;\n\tbool visit(VariableDeclarationStatement const& _node) override;\n\tbool visit(ExpressionStatement const& _node) override;\n\tbool visit(Conditional const& _node) override;\n\tbool visit(Assignment const& _node) override;\n\tbool visit(TupleExpression const& _node) override;\n\tbool visit(UnaryOperation const& _node) override;\n\tbool visit(BinaryOperation const& _node) override;\n\tbool visit(FunctionCall const& _node) override;\n\tbool visit(FunctionCallOptions const& _node) override;\n\tbool visit(NewExpression const& _node) override;\n\tbool visit(MemberAccess const& _node) override;\n\tbool visit(IndexAccess const& _node) override;\n\tbool visit(IndexRangeAccess const& _node) override;\n\tbool visit(Identifier const& _node) override;\n\tbool visit(ElementaryTypeNameExpression const& _node) override;\n\tbool visit(Literal const& _node) override;\n\tbool visit(StructuredDocumentation const& _node) override;\n\tbool visit(StorageLayoutSpecifier const& _node) override;\n\n\tvoid endVisit(EventDefinition const&) override;\n\n\tbool visitNode(ASTNode const& _node) override;\nprivate:\n\tvoid setJsonNode(\n\t\tASTNode const& _node,\n\t\tstd::string const& _nodeName,\n\t\tstd::initializer_list<std::pair<std::string, Json>>&& _attributes\n\t);\n\tvoid setJsonNode(\n\t\tASTNode const& _node,\n\t\tstd::string const& _nodeName,\n\t\tstd::vector<std::pair<std::string, Json>>&& _attributes\n\t);\n\t/// Maps source location to an index, if source is valid and a mapping does exist, otherwise returns std::nullopt.\n\tstd::optional<size_t> sourceIndexFromLocation(langutil::SourceLocation const& _location) const;\n\tstd::string sourceLocationToString(langutil::SourceLocation const& _location) const;\n\tJson sourceLocationsToJson(std::vector<langutil::SourceLocation> const& _sourceLocations) const;\n\tstatic std::string namePathToString(std::vector<ASTString> const& _namePath);\n\tstatic Json idOrNull(ASTNode const* _pt)\n\t{\n\t\treturn _pt ? Json(nodeId(*_pt)) : Json();\n\t}\n\tJson toJsonOrNull(ASTNode const* _node)\n\t{\n\t\treturn _node ? toJson(*_node) : Json();\n\t}\n\tJson inlineAssemblyIdentifierToJson(std::pair<yul::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const;\n\tstatic std::string location(VariableDeclaration::Location _location);\n\tstatic std::string contractKind(ContractKind _kind);\n\tstatic std::string functionCallKind(FunctionCallKind _kind);\n\tstatic std::string literalTokenKind(Token _token);\n\tstatic std::string type(Expression const& _expression);\n\tstatic std::string type(VariableDeclaration const& _varDecl);\n\tstatic int64_t nodeId(ASTNode const& _node)\n\t{\n\t\treturn _node.id();\n\t}\n\ttemplate<class Container>\n\tstatic Json getContainerIds(Container const& _container, bool _order = false)\n\t{\n\t\tstd::vector<int64_t> tmp;\n\n\t\tfor (auto const& element: _container)\n\t\t{\n\t\t\tsolAssert(element, \"\");\n\t\t\ttmp.push_back(nodeId(*element));\n\t\t}\n\t\tif (_order)\n\t\t\tstd::sort(tmp.begin(), tmp.end());\n\n\t\tJson json = Json::array();\n\t\tfor (int64_t val: tmp)\n\t\t\tjson.emplace_back(val);\n\t\treturn json;\n\t}\n\tstatic Json typePointerToJson(Type const* _tp, bool _withoutDataLocation = false);\n\tstatic Json typePointerToJson(std::optional<FuncCallArguments> const& _tps);\n\tvoid appendExpressionAttributes(\n\t\tstd::vector<std::pair<std::string, Json>> &_attributes,\n\t\tExpressionAnnotation const& _annotation\n\t);\n\tstatic void appendMove(Json& _array, Json&& _value)\n\t{\n\t\tsolAssert(_array.is_array(), \"\");\n\t\t_array.emplace_back(std::move(_value));\n\t}\n\n\tCompilerStack::State m_stackState = CompilerStack::State::Empty; ///< Used to only access information that already exists\n\tbool m_inEvent = false; ///< whether we are currently inside an event or not\n\tJson m_currentValue;\n\tstd::map<std::string, unsigned> m_sourceIndices;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/ast/ASTJsonImporter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author julius <djudju@protonmail.com>\n * @date 2019\n *Component that imports an AST from json format to the internal format\n */\n\n#include <libsolidity/ast/ASTJsonImporter.h>\n#include <libsolidity/ast/UserDefinableOperators.h>\n\n#include <libyul/AsmJsonImporter.h>\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/Scanner.h>\n#include <liblangutil/SourceLocation.h>\n#include <liblangutil/Token.h>\n\n#include <boost/algorithm/string/split.hpp>\n#include <boost/algorithm/string.hpp>\n\n#include <range/v3/algorithm/find_if.hpp>\n\nnamespace solidity::frontend\n{\n\nusing SourceLocation = langutil::SourceLocation;\n\ntemplate<class T>\nASTPointer<T> ASTJsonImporter::nullOrCast(Json const& _json)\n{\n\tif (_json.is_null())\n\t\treturn nullptr;\n\telse\n\t\treturn std::dynamic_pointer_cast<T>(convertJsonToASTNode(_json));\n}\n\n\n// ============ public ===========================\n\nstd::map<std::string, ASTPointer<SourceUnit>> ASTJsonImporter::jsonToSourceUnit(std::map<std::string, Json> const& _sourceList)\n{\n\tfor (auto const& src: _sourceList)\n\t\tm_sourceNames.emplace_back(std::make_shared<std::string const>(src.first));\n\tfor (auto const& srcPair: _sourceList)\n\t{\n\t\tastAssert(!srcPair.second.is_null());\n\t\tastAssert(member(srcPair.second,\"nodeType\") == \"SourceUnit\", \"The 'nodeType' of the highest node must be 'SourceUnit'.\");\n\t\tm_sourceUnits[srcPair.first] = createSourceUnit(srcPair.second, srcPair.first);\n\t}\n\treturn m_sourceUnits;\n}\n\n// ============ private ===========================\n\n// =========== general creation functions ==============\ntemplate <typename T, typename... Args>\nASTPointer<T> ASTJsonImporter::createASTNode(Json const& _node, Args&&... _args)\n{\n\tstatic_assert(std::is_same_v<Json::number_unsigned_t, uint64_t>);\n\tastAssert(member(_node, \"id\").is_number_integer(), \"'id'-field must be 64bit integer.\");\n\n\tint64_t id = static_cast<Json::number_integer_t>(_node[\"id\"]);\n\n\tastAssert(m_usedIDs.insert(id).second, \"Found duplicate node ID!\");\n\n\tauto n = std::make_shared<T>(\n\t\tid,\n\t\tcreateSourceLocation(_node),\n\t\tstd::forward<Args>(_args)...\n\t);\n\treturn n;\n}\n\nSourceLocation const ASTJsonImporter::createSourceLocation(Json const& _node)\n{\n\tastAssert(member(_node, \"src\").is_string(), \"'src' must be a string\");\n\n\treturn solidity::langutil::parseSourceLocation(_node[\"src\"].get<std::string>(), m_sourceNames);\n}\n\nstd::optional<std::vector<SourceLocation>> ASTJsonImporter::createSourceLocations(Json const& _node) const\n{\n\tstd::vector<SourceLocation> locations;\n\n\tif (_node.contains(\"nameLocations\") && _node[\"nameLocations\"].is_array())\n\t{\n\t\tfor (auto const& val: _node[\"nameLocations\"])\n\t\t\tlocations.emplace_back(langutil::parseSourceLocation(val.get<std::string>(), m_sourceNames));\n\t\treturn locations;\n\t}\n\n\treturn std::nullopt;\n}\n\nSourceLocation ASTJsonImporter::createNameSourceLocation(Json const& _node)\n{\n\tastAssert(member(_node, \"nameLocation\").is_string(), \"'nameLocation' must be a string\");\n\n\treturn solidity::langutil::parseSourceLocation(_node[\"nameLocation\"].get<std::string>(), m_sourceNames);\n}\n\nSourceLocation ASTJsonImporter::createKeyNameSourceLocation(Json const& _node)\n{\n\tastAssert(member(_node, \"keyNameLocation\").is_string(), \"'keyNameLocation' must be a string\");\n\n\treturn solidity::langutil::parseSourceLocation(_node[\"keyNameLocation\"].get<std::string>(), m_sourceNames);\n}\n\nSourceLocation ASTJsonImporter::createValueNameSourceLocation(Json const& _node)\n{\n\tastAssert(member(_node, \"valueNameLocation\").is_string(), \"'valueNameLocation' must be a string\");\n\n\treturn solidity::langutil::parseSourceLocation(_node[\"valueNameLocation\"].get<std::string>(), m_sourceNames);\n}\n\ntemplate<class T>\nASTPointer<T> ASTJsonImporter::convertJsonToASTNode(Json const& _node)\n{\n\tASTPointer<T> ret = std::dynamic_pointer_cast<T>(convertJsonToASTNode(_node));\n\tastAssert(ret, \"cast of converted json-node must not be nullptr\");\n\treturn ret;\n}\n\n\nASTPointer<ASTNode> ASTJsonImporter::convertJsonToASTNode(Json const& _json)\n{\n\tastAssert(_json[\"nodeType\"].is_string() && _json.contains(\"id\"), \"JSON-Node needs to have 'nodeType' and 'id' fields.\");\n\tstd::string nodeType = _json[\"nodeType\"].get<std::string>();\n\tif (nodeType == \"PragmaDirective\")\n\t\treturn createPragmaDirective(_json);\n\tif (nodeType == \"ImportDirective\")\n\t\treturn createImportDirective(_json);\n\tif (nodeType == \"ContractDefinition\")\n\t\treturn createContractDefinition(_json);\n\tif (nodeType == \"IdentifierPath\")\n\t\treturn createIdentifierPath(_json);\n\tif (nodeType == \"InheritanceSpecifier\")\n\t\treturn createInheritanceSpecifier(_json);\n\tif (nodeType == \"UsingForDirective\")\n\t\treturn createUsingForDirective(_json);\n\tif (nodeType == \"StructDefinition\")\n\t\treturn createStructDefinition(_json);\n\tif (nodeType == \"EnumDefinition\")\n\t\treturn createEnumDefinition(_json);\n\tif (nodeType == \"EnumValue\")\n\t\treturn createEnumValue(_json);\n\tif (nodeType == \"UserDefinedValueTypeDefinition\")\n\t\treturn createUserDefinedValueTypeDefinition(_json);\n\tif (nodeType == \"ParameterList\")\n\t\treturn createParameterList(_json);\n\tif (nodeType == \"OverrideSpecifier\")\n\t\treturn createOverrideSpecifier(_json);\n\tif (nodeType == \"FunctionDefinition\")\n\t\treturn createFunctionDefinition(_json);\n\tif (nodeType == \"VariableDeclaration\")\n\t\treturn createVariableDeclaration(_json);\n\tif (nodeType == \"ModifierDefinition\")\n\t\treturn createModifierDefinition(_json);\n\tif (nodeType == \"ModifierInvocation\")\n\t\treturn createModifierInvocation(_json);\n\tif (nodeType == \"EventDefinition\")\n\t\treturn createEventDefinition(_json);\n\tif (nodeType == \"ErrorDefinition\")\n\t\treturn createErrorDefinition(_json);\n\tif (nodeType == \"ElementaryTypeName\")\n\t\treturn createElementaryTypeName(_json);\n\tif (nodeType == \"UserDefinedTypeName\")\n\t\treturn createUserDefinedTypeName(_json);\n\tif (nodeType == \"FunctionTypeName\")\n\t\treturn createFunctionTypeName(_json);\n\tif (nodeType == \"Mapping\")\n\t\treturn createMapping(_json);\n\tif (nodeType == \"ArrayTypeName\")\n\t\treturn createArrayTypeName(_json);\n\tif (nodeType == \"InlineAssembly\")\n\t\treturn createInlineAssembly(_json);\n\tif (nodeType == \"Block\")\n\t\treturn createBlock(_json, false);\n\tif (nodeType == \"UncheckedBlock\")\n\t\treturn createBlock(_json, true);\n\tif (nodeType == \"PlaceholderStatement\")\n\t\treturn createPlaceholderStatement(_json);\n\tif (nodeType == \"IfStatement\")\n\t\treturn createIfStatement(_json);\n\tif (nodeType == \"TryCatchClause\")\n\t\treturn createTryCatchClause(_json);\n\tif (nodeType == \"TryStatement\")\n\t\treturn createTryStatement(_json);\n\tif (nodeType == \"WhileStatement\")\n\t\treturn createWhileStatement(_json, false);\n\tif (nodeType == \"DoWhileStatement\")\n\t\treturn createWhileStatement(_json, true);\n\tif (nodeType == \"ForStatement\")\n\t\treturn createForStatement(_json);\n\tif (nodeType == \"Continue\")\n\t\treturn createContinue(_json);\n\tif (nodeType == \"Break\")\n\t\treturn createBreak(_json);\n\tif (nodeType == \"Return\")\n\t\treturn createReturn(_json);\n\tif (nodeType == \"EmitStatement\")\n\t\treturn createEmitStatement(_json);\n\tif (nodeType == \"RevertStatement\")\n\t\treturn createRevertStatement(_json);\n\tif (nodeType == \"Throw\")\n\t\treturn createThrow(_json);\n\tif (nodeType == \"VariableDeclarationStatement\")\n\t\treturn createVariableDeclarationStatement(_json);\n\tif (nodeType == \"ExpressionStatement\")\n\t\treturn createExpressionStatement(_json);\n\tif (nodeType == \"Conditional\")\n\t\treturn createConditional(_json);\n\tif (nodeType == \"Assignment\")\n\t\treturn createAssignment(_json);\n\tif (nodeType == \"TupleExpression\")\n\t\treturn createTupleExpression(_json);\n\tif (nodeType == \"UnaryOperation\")\n\t\treturn createUnaryOperation(_json);\n\tif (nodeType == \"BinaryOperation\")\n\t\treturn createBinaryOperation(_json);\n\tif (nodeType == \"FunctionCall\")\n\t\treturn createFunctionCall(_json);\n\tif (nodeType == \"FunctionCallOptions\")\n\t\treturn createFunctionCallOptions(_json);\n\tif (nodeType == \"NewExpression\")\n\t\treturn createNewExpression(_json);\n\tif (nodeType == \"MemberAccess\")\n\t\treturn createMemberAccess(_json);\n\tif (nodeType == \"IndexAccess\")\n\t\treturn createIndexAccess(_json);\n\tif (nodeType == \"IndexRangeAccess\")\n\t\treturn createIndexRangeAccess(_json);\n\tif (nodeType == \"Identifier\")\n\t\treturn createIdentifier(_json);\n\tif (nodeType == \"ElementaryTypeNameExpression\")\n\t\treturn createElementaryTypeNameExpression(_json);\n\tif (nodeType == \"Literal\")\n\t\treturn createLiteral(_json);\n\tif (nodeType == \"StructuredDocumentation\")\n\t\treturn createDocumentation(_json);\n\tif (nodeType == \"StorageLayoutSpecifier\")\n\t\treturn createStorageLayoutSpecifier(_json);\n\telse\n\t\tastAssert(false, \"Unknown type of ASTNode: \" + nodeType);\n\n\t// FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794)\n\tutil::unreachable();\n}\n\n// ============ functions to instantiate the AST-Nodes from Json-Nodes ==============\n\nASTPointer<SourceUnit> ASTJsonImporter::createSourceUnit(Json const& _node, std::string const& _srcName)\n{\n\tstd::optional<std::string> license;\n\tif (_node.contains(\"license\") && !_node[\"license\"].is_null())\n\t\tlicense = _node[\"license\"].get<std::string>();\n\n\tbool experimentalSolidity = false;\n\tif (_node.contains(\"experimentalSolidity\") && !_node[\"experimentalSolidity\"].is_null())\n\t\texperimentalSolidity = _node[\"experimentalSolidity\"].get<bool>();\n\n\tstd::vector<ASTPointer<ASTNode>> nodes;\n\tfor (auto& child: member(_node, \"nodes\"))\n\t\tnodes.emplace_back(convertJsonToASTNode(child));\n\n\tASTPointer<SourceUnit> tmp = createASTNode<SourceUnit>(_node, license, nodes, experimentalSolidity);\n\ttmp->annotation().path = _srcName;\n\treturn tmp;\n}\n\nASTPointer<PragmaDirective> ASTJsonImporter::createPragmaDirective(Json const& _node)\n{\n\tstd::vector<Token> tokens;\n\tstd::vector<ASTString> literals;\n\tfor (auto const& lit: member(_node, \"literals\"))\n\t{\n\t\tstd::string l = lit.get<std::string>();\n\t\tliterals.push_back(l);\n\t\ttokens.push_back(scanSingleToken(l));\n\t}\n\treturn createASTNode<PragmaDirective>(_node, tokens, literals);\n}\n\nASTPointer<ImportDirective> ASTJsonImporter::createImportDirective(Json const& _node)\n{\n\tASTPointer<ASTString> unitAlias = memberAsASTString(_node, \"unitAlias\");\n\tASTPointer<ASTString> path = memberAsASTString(_node, \"file\");\n\tImportDirective::SymbolAliasList symbolAliases;\n\n\tfor (auto& tuple: member(_node, \"symbolAliases\"))\n\t{\n\t\tastAssert(tuple[\"local\"].is_null() || tuple[\"local\"].is_string(), \"expected 'local' to be a string or null!\");\n\n\t\tsymbolAliases.push_back({\n\t\t\tcreateIdentifier(tuple[\"foreign\"]),\n\t\t\ttuple[\"local\"].is_null() ? nullptr : std::make_shared<ASTString>(tuple[\"local\"].get<std::string>()),\n\t\t\tcreateSourceLocation(tuple[\"foreign\"])}\n\t\t);\n\t}\n\tASTPointer<ImportDirective> tmp = createASTNode<ImportDirective>(\n\t\t_node,\n\t\tpath,\n\t\tunitAlias,\n\t\tcreateNameSourceLocation(_node),\n\t\tstd::move(symbolAliases)\n\t);\n\n\tastAssert(_node[\"absolutePath\"].is_string(), \"Expected 'absolutePath' to be a string!\");\n\n\ttmp->annotation().absolutePath = _node[\"absolutePath\"].get<std::string>();\n\treturn tmp;\n}\n\nASTPointer<ContractDefinition> ASTJsonImporter::createContractDefinition(Json const& _node)\n{\n\tastAssert(_node[\"name\"].is_string(), \"Expected 'name' to be a string!\");\n\n\tstd::vector<ASTPointer<InheritanceSpecifier>> baseContracts;\n\n\tfor (auto& base: _node[\"baseContracts\"])\n\t\tbaseContracts.push_back(createInheritanceSpecifier(base));\n\n\tstd::vector<ASTPointer<ASTNode>> subNodes;\n\n\tfor (auto& subnode: _node[\"nodes\"])\n\t\tsubNodes.push_back(convertJsonToASTNode(subnode));\n\n\treturn createASTNode<ContractDefinition>(\n\t\t_node,\n\t\tstd::make_shared<ASTString>(_node[\"name\"].get<std::string>()),\n\t\tcreateNameSourceLocation(_node),\n\t\t(_node.contains(\"documentation\") && !_node[\"documentation\"].is_null()) ? createDocumentation(member(_node, \"documentation\")) : nullptr,\n\t\tbaseContracts,\n\t\tsubNodes,\n\t\tcontractKind(_node),\n\t\tmemberAsBool(_node, \"abstract\"),\n\t\tnullOrCast<StorageLayoutSpecifier>(member(_node, \"storageLayout\"))\n\t);\n}\n\nASTPointer<StorageLayoutSpecifier> ASTJsonImporter::createStorageLayoutSpecifier(Json const& _node)\n{\n\tastAssert(_node.contains(\"baseSlotExpression\"), \"Expected field \\\"baseSlotExpression\\\" is missing.\");\n\treturn createASTNode<StorageLayoutSpecifier>(\n\t\t_node,\n\t\tconvertJsonToASTNode<Expression>(_node[\"baseSlotExpression\"])\n\t);\n}\n\nASTPointer<IdentifierPath> ASTJsonImporter::createIdentifierPath(Json const& _node)\n{\n\tastAssert(_node[\"name\"].is_string(), \"Expected 'name' to be a string!\");\n\n\tstd::vector<ASTString> namePath;\n\tstd::vector<SourceLocation> namePathLocations;\n\tstd::vector<std::string> strs;\n\tstd::string nameString = member(_node, \"name\").get<std::string>();\n\tboost::algorithm::split(strs, nameString, boost::is_any_of(\".\"));\n\tastAssert(!strs.empty(), \"Expected at least one element in IdentifierPath.\");\n\tfor (std::string s: strs)\n\t{\n\t\tastAssert(!s.empty(), \"Expected non-empty string for IdentifierPath element.\");\n\t\tnamePath.emplace_back(s);\n\t}\n\n\tif (_node.contains(\"nameLocations\") && _node[\"nameLocations\"].is_array())\n\t\tfor (auto const& val: _node[\"nameLocations\"])\n\t\t\tnamePathLocations.emplace_back(langutil::parseSourceLocation(val.get<std::string>(), m_sourceNames));\n\telse\n\t\tnamePathLocations.resize(namePath.size());\n\n\tastAssert(\n\t\tnamePath.size() == namePathLocations.size(),\n\t\t\"SourceLocations don't match name paths.\"\n\t);\n\n\treturn createASTNode<IdentifierPath>(\n\t\t_node,\n\t\tnamePath,\n\t\tnamePathLocations\n\t);\n}\n\nASTPointer<InheritanceSpecifier> ASTJsonImporter::createInheritanceSpecifier(Json const& _node)\n{\n\tstd::vector<ASTPointer<Expression>> arguments;\n\tfor (auto& arg: member(_node, \"arguments\"))\n\t\targuments.push_back(convertJsonToASTNode<Expression>(arg));\n\treturn createASTNode<InheritanceSpecifier>(\n\t\t_node,\n\t\tcreateIdentifierPath(member(_node, \"baseName\")),\n\t\tmember(_node, \"arguments\").is_null() ? nullptr : std::make_unique<std::vector<ASTPointer<Expression>>>(arguments)\n\t);\n}\n\nASTPointer<UsingForDirective> ASTJsonImporter::createUsingForDirective(Json const& _node)\n{\n\tstd::vector<ASTPointer<IdentifierPath>> functions;\n\tstd::vector<std::optional<Token>> operators;\n\tif (_node.contains(\"libraryName\"))\n\t{\n\t\tastAssert(!_node[\"libraryName\"].is_array());\n\t\tastAssert(!_node[\"libraryName\"].contains(\"operator\"));\n\t\tfunctions.emplace_back(createIdentifierPath(_node[\"libraryName\"]));\n\t\toperators.emplace_back(std::nullopt);\n\t}\n\telse if (_node.contains(\"functionList\"))\n\t\tfor (Json const& function: _node[\"functionList\"])\n\t\t{\n\t\t\tif (function.contains(\"function\"))\n\t\t\t{\n\t\t\t\tastAssert(!function.contains(\"operator\"));\n\t\t\t\tastAssert(!function.contains(\"definition\"));\n\n\t\t\t\tfunctions.emplace_back(createIdentifierPath(function[\"function\"]));\n\t\t\t\toperators.emplace_back(std::nullopt);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tastAssert(function.contains(\"operator\"));\n\t\t\t\tastAssert(function.contains(\"definition\"));\n\n\t\t\t\tToken const operatorName = scanSingleToken(function[\"operator\"]);\n\t\t\t\tastAssert(util::contains(frontend::userDefinableOperators, operatorName));\n\n\t\t\t\tfunctions.emplace_back(createIdentifierPath(function[\"definition\"]));\n\t\t\t\toperators.emplace_back(operatorName);\n\t\t\t}\n\t\t}\n\n\treturn createASTNode<UsingForDirective>(\n\t\t_node,\n\t\tstd::move(functions),\n\t\tstd::move(operators),\n\t\t!_node.contains(\"libraryName\"),\n\t\t(_node.contains(\"typeName\") && !_node[\"typeName\"].is_null()) ? convertJsonToASTNode<TypeName>(_node[\"typeName\"]) : nullptr,\n\t\tmemberAsBool(_node, \"global\")\n\t);\n}\n\nASTPointer<ASTNode> ASTJsonImporter::createStructDefinition(Json const& _node)\n{\n\tstd::vector<ASTPointer<VariableDeclaration>> members;\n\tfor (auto& member: _node[\"members\"])\n\t\tmembers.push_back(createVariableDeclaration(member));\n\treturn createASTNode<StructDefinition>(\n\t\t_node,\n\t\tmemberAsASTString(_node, \"name\"),\n\t\tcreateNameSourceLocation(_node),\n\t\tmembers,\n\t\t(_node.contains(\"documentation\") && !_node[\"documentation\"].is_null()) ? createDocumentation(member(_node, \"documentation\")) : nullptr\n\t);\n}\n\nASTPointer<EnumDefinition> ASTJsonImporter::createEnumDefinition(Json const& _node)\n{\n\tstd::vector<ASTPointer<EnumValue>> members;\n\tfor (auto& member: _node[\"members\"])\n\t\tmembers.push_back(createEnumValue(member));\n\treturn createASTNode<EnumDefinition>(\n\t\t_node,\n\t\tmemberAsASTString(_node, \"name\"),\n\t\tcreateNameSourceLocation(_node),\n\t\tmembers,\n\t\t(_node.contains(\"documentation\") && !_node[\"documentation\"].is_null()) ? createDocumentation(member(_node, \"documentation\")) : nullptr\n\t);\n}\n\nASTPointer<EnumValue> ASTJsonImporter::createEnumValue(Json const& _node)\n{\n\treturn createASTNode<EnumValue>(\n\t\t_node,\n\t\tmemberAsASTString(_node, \"name\"),\n\t\t_node.contains(\"documentation\") && !_node[\"documentation\"].is_null() ? createDocumentation(member(_node, \"documentation\")) : nullptr\n\t);\n}\n\nASTPointer<UserDefinedValueTypeDefinition> ASTJsonImporter::createUserDefinedValueTypeDefinition(Json const& _node)\n{\n\treturn createASTNode<UserDefinedValueTypeDefinition>(\n\t\t_node,\n\t\tmemberAsASTString(_node, \"name\"),\n\t\tcreateNameSourceLocation(_node),\n\t\tconvertJsonToASTNode<TypeName>(member(_node, \"underlyingType\"))\n\t);\n}\n\nASTPointer<ParameterList> ASTJsonImporter::createParameterList(Json const&  _node)\n{\n\tstd::vector<ASTPointer<VariableDeclaration>> parameters;\n\tfor (auto& param: _node[\"parameters\"])\n\t\tparameters.push_back(createVariableDeclaration(param));\n\treturn createASTNode<ParameterList>(\n\t\t_node,\n\t\tparameters\n\t);\n}\n\nASTPointer<OverrideSpecifier> ASTJsonImporter::createOverrideSpecifier(Json const&  _node)\n{\n\tstd::vector<ASTPointer<IdentifierPath>> overrides;\n\n\tif ( _node.contains(\"overrides\"))\n\t\tfor (auto& param: _node[\"overrides\"])\n\t\t\toverrides.push_back(createIdentifierPath(param));\n\n\treturn createASTNode<OverrideSpecifier>(\n\t\t_node,\n\t\toverrides\n\t);\n}\n\nASTPointer<FunctionDefinition> ASTJsonImporter::createFunctionDefinition(Json const&  _node)\n{\n\tastAssert(_node[\"kind\"].is_string(), \"Expected 'kind' to be a string!\");\n\n\tToken kind;\n\tbool freeFunction = false;\n\tstd::string kindStr = member(_node, \"kind\").get<std::string>();\n\n\tif (kindStr == \"constructor\")\n\t\tkind = Token::Constructor;\n\telse if (kindStr == \"function\")\n\t\tkind = Token::Function;\n\telse if (kindStr == \"fallback\")\n\t\tkind = Token::Fallback;\n\telse if (kindStr == \"receive\")\n\t\tkind = Token::Receive;\n\telse if (kindStr == \"freeFunction\")\n\t{\n\t\tkind = Token::Function;\n\t\tfreeFunction = true;\n\t}\n\telse\n\t\tastAssert(false, \"Expected 'kind' to be one of [constructor, function, fallback, receive]\");\n\n\tstd::vector<ASTPointer<ModifierInvocation>> modifiers;\n\tfor (auto& mod: member(_node, \"modifiers\"))\n\t\tmodifiers.push_back(createModifierInvocation(mod));\n\n\tVisibility vis = Visibility::Default;\n\t// Ignore public visibility for constructors\n\tif (kind == Token::Constructor)\n\t\tvis = (visibility(_node) == Visibility::Public) ? Visibility::Default : visibility(_node);\n\telse if (!freeFunction)\n\t\tvis = visibility(_node);\n\treturn createASTNode<FunctionDefinition>(\n\t\t_node,\n\t\tmemberAsASTString(_node, \"name\"),\n\t\tcreateNameSourceLocation(_node),\n\t\tvis,\n\t\tstateMutability(_node),\n\t\tfreeFunction,\n\t\tkind,\n\t\tmemberAsBool(_node, \"virtual\"),\n\t\t(_node.contains(\"overrides\") && !_node[\"overrides\"].is_null()) ? createOverrideSpecifier(member(_node, \"overrides\")) : nullptr,\n\t\t(_node.contains(\"documentation\") && !_node[\"documentation\"].is_null()) ?  createDocumentation(member(_node, \"documentation\")) : nullptr,\n\t\tcreateParameterList(member(_node, \"parameters\")),\n\t\tmodifiers,\n\t\tcreateParameterList(member(_node, \"returnParameters\")),\n\t\tmemberAsBool(_node, \"implemented\") ? createBlock(member(_node, \"body\"), false) : nullptr\n\t);\n}\n\nASTPointer<VariableDeclaration> ASTJsonImporter::createVariableDeclaration(Json const& _node)\n{\n\tastAssert(_node[\"name\"].is_string(), \"Expected 'name' to be a string!\");\n\n\tVariableDeclaration::Mutability mutability{};\n\tastAssert(member(_node, \"mutability\").is_string(), \"'mutability' expected to be string.\");\n\tstd::string const mutabilityStr = member(_node, \"mutability\").get<std::string>();\n\tif (mutabilityStr == \"constant\")\n\t{\n\t\tmutability = VariableDeclaration::Mutability::Constant;\n\t\tastAssert(memberAsBool(_node, \"constant\"));\n\t}\n\telse\n\t{\n\t\tastAssert(!memberAsBool(_node, \"constant\"));\n\t\tif (mutabilityStr == \"mutable\")\n\t\t\tmutability = VariableDeclaration::Mutability::Mutable;\n\t\telse if (mutabilityStr == \"immutable\")\n\t\t\tmutability = VariableDeclaration::Mutability::Immutable;\n\t\telse\n\t\t\tastAssert(false);\n\t}\n\n\treturn createASTNode<VariableDeclaration>(\n\t\t_node,\n\t\tnullOrCast<TypeName>(member(_node, \"typeName\")),\n\t\tstd::make_shared<ASTString>(member(_node, \"name\").get<std::string>()),\n\t\tcreateNameSourceLocation(_node),\n\t\tnullOrCast<Expression>(member(_node, \"value\")),\n\t\tvisibility(_node),\n\t\t(_node.contains(\"documentation\") && !_node[\"documentation\"].is_null()) ? createDocumentation(member(_node, \"documentation\")) : nullptr,\n\t\t(_node.contains(\"indexed\") && !_node[\"indexed\"].is_null()) ? memberAsBool(_node, \"indexed\") : false,\n\t\tmutability,\n\t\t(_node.contains(\"overrides\") && !_node[\"overrides\"].is_null()) ? createOverrideSpecifier(member(_node, \"overrides\")) : nullptr,\n\t\tlocation(_node)\n\t);\n}\n\nASTPointer<ModifierDefinition> ASTJsonImporter::createModifierDefinition(Json const&  _node)\n{\n\treturn createASTNode<ModifierDefinition>(\n\t\t_node,\n\t\tmemberAsASTString(_node, \"name\"),\n\t\tcreateNameSourceLocation(_node),\n\t\t(_node.contains(\"documentation\") && !_node[\"documentation\"].is_null()) ? createDocumentation(member(_node, \"documentation\")) : nullptr,\n\t\tcreateParameterList(member(_node, \"parameters\")),\n\t\tmemberAsBool(_node, \"virtual\"),\n\t\t(_node.contains(\"overrides\") && !_node[\"overrides\"].is_null()) ? createOverrideSpecifier(member(_node, \"overrides\")) : nullptr,\n\t\t(_node.contains(\"body\") && !_node[\"body\"].is_null()) ? createBlock(member(_node, \"body\"), false) : nullptr\n\t);\n}\n\nASTPointer<ModifierInvocation> ASTJsonImporter::createModifierInvocation(Json const&  _node)\n{\n\tstd::vector<ASTPointer<Expression>> arguments;\n\tfor (auto& arg: member(_node, \"arguments\"))\n\t\targuments.push_back(convertJsonToASTNode<Expression>(arg));\n\treturn createASTNode<ModifierInvocation>(\n\t\t_node,\n\t\tcreateIdentifierPath(member(_node, \"modifierName\")),\n\t\tmember(_node, \"arguments\").is_null() ? nullptr : std::make_unique<std::vector<ASTPointer<Expression>>>(arguments)\n\t);\n}\n\nASTPointer<EventDefinition> ASTJsonImporter::createEventDefinition(Json const&  _node)\n{\n\treturn createASTNode<EventDefinition>(\n\t\t_node,\n\t\tmemberAsASTString(_node, \"name\"),\n\t\tcreateNameSourceLocation(_node),\n\t\t(_node.contains(\"documentation\") && !_node[\"documentation\"].is_null()) ? createDocumentation(member(_node, \"documentation\")) : nullptr,\n\t\tcreateParameterList(member(_node, \"parameters\")),\n\t\tmemberAsBool(_node, \"anonymous\")\n\t);\n}\n\nASTPointer<ErrorDefinition> ASTJsonImporter::createErrorDefinition(Json const&  _node)\n{\n\treturn createASTNode<ErrorDefinition>(\n\t\t_node,\n\t\tmemberAsASTString(_node, \"name\"),\n\t\tcreateNameSourceLocation(_node),\n\t\t(_node.contains(\"documentation\") && !_node[\"documentation\"].is_null()) ? createDocumentation(member(_node, \"documentation\")) : nullptr,\n\t\tcreateParameterList(member(_node, \"parameters\"))\n\t);\n}\n\nASTPointer<ElementaryTypeName> ASTJsonImporter::createElementaryTypeName(Json const& _node)\n{\n\tunsigned short firstNum;\n\tunsigned short secondNum;\n\n\tastAssert(_node[\"name\"].is_string(), \"Expected 'name' to be a string!\");\n\n\tstd::string name = member(_node, \"name\").get<std::string>();\n\tToken token;\n\tstd::tie(token, firstNum, secondNum) = TokenTraits::fromIdentifierOrKeyword(name);\n\tElementaryTypeNameToken elem(token, firstNum,  secondNum);\n\n\tstd::optional<StateMutability> mutability = {};\n\tif (_node.contains(\"stateMutability\"))\n\t\tmutability = stateMutability(_node);\n\n\treturn createASTNode<ElementaryTypeName>(_node, elem, mutability);\n}\n\nASTPointer<UserDefinedTypeName> ASTJsonImporter::createUserDefinedTypeName(Json const& _node)\n{\n\treturn createASTNode<UserDefinedTypeName>(\n\t\t_node,\n\t\tcreateIdentifierPath(member(_node, \"pathNode\"))\n\t);\n}\n\nASTPointer<FunctionTypeName> ASTJsonImporter::createFunctionTypeName(Json const&  _node)\n{\n\treturn createASTNode<FunctionTypeName>(\n\t\t_node,\n\t\tcreateParameterList(member(_node, \"parameterTypes\")),\n\t\tcreateParameterList(member(_node, \"returnParameterTypes\")),\n\t\tvisibility(_node),\n\t\tstateMutability(_node)\n\t);\n}\n\nASTPointer<Mapping> ASTJsonImporter::createMapping(Json const&  _node)\n{\n\treturn createASTNode<Mapping>(\n\t\t_node,\n\t\tconvertJsonToASTNode<TypeName>(member(_node, \"keyType\")),\n\t\tmemberAsASTString(_node, \"keyName\"),\n\t\tcreateKeyNameSourceLocation(_node),\n\t\tconvertJsonToASTNode<TypeName>(member(_node, \"valueType\")),\n\t\tmemberAsASTString(_node, \"valueName\"),\n\t\tcreateValueNameSourceLocation(_node)\n\t);\n}\n\nASTPointer<ArrayTypeName> ASTJsonImporter::createArrayTypeName(Json const&  _node)\n{\n\treturn createASTNode<ArrayTypeName>(\n\t\t_node,\n\t\tconvertJsonToASTNode<TypeName>(member(_node, \"baseType\")),\n\t\tnullOrCast<Expression>(member(_node, \"length\"))\n\t);\n}\n\nASTPointer<InlineAssembly> ASTJsonImporter::createInlineAssembly(Json const& _node)\n{\n\tastAssert(_node[\"evmVersion\"].is_string(), \"Expected evmVersion to be a string!\");\n\tauto evmVersion = langutil::EVMVersion::fromString(_node[\"evmVersion\"].get<std::string>());\n\tastAssert(evmVersion.has_value(), \"Invalid EVM version!\");\n\tastAssert(m_evmVersion == evmVersion, \"Imported tree evm version differs from configured evm version!\");\n\n\t// TODO: Add test in test/linsolidity/ASTJSON/assembly. This requires adding support for eofVersion in ASTJSONTest\n\tstd::optional<uint8_t> eofVersion;\n\tif (auto const it = _node.find(\"eofVersion\"); it != _node.end())\n\t{\n\t\teofVersion = it->get<uint8_t>();\n\t\tastAssert(eofVersion > 0);\n\t}\n\tastAssert(m_eofVersion == eofVersion, \"Imported tree EOF version differs from configured EOF version!\");\n\n\tyul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(evmVersion.value(), eofVersion);\n\tASTPointer<std::vector<ASTPointer<ASTString>>> flags;\n\tif (_node.contains(\"flags\"))\n\t{\n\t\tflags = std::make_shared<std::vector<ASTPointer<ASTString>>>();\n\t\tJson const& flagsNode = _node[\"flags\"];\n\t\tastAssert(flagsNode.is_array(), \"Assembly flags must be an array.\");\n\t\tfor (auto const& flag: flagsNode)\n\t\t{\n\t\t\tastAssert(flag.is_string(), \"Assembly flag must be a string.\");\n\t\t\tflags->emplace_back(std::make_shared<ASTString>(flag.get<std::string>()));\n\t\t}\n\t}\n\tstd::shared_ptr<yul::AST> operations = std::make_shared<yul::AST>(\n\t\tyul::AsmJsonImporter(dialect, m_sourceNames).createAST(member(_node, \"AST\"))\n\t);\n\treturn createASTNode<InlineAssembly>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\"),\n\t\tdialect,\n\t\tstd::move(flags),\n\t\toperations\n\t);\n}\n\nASTPointer<Block> ASTJsonImporter::createBlock(Json const& _node, bool _unchecked)\n{\n\tstd::vector<ASTPointer<Statement>> statements;\n\tfor (auto& stat: member(_node, \"statements\"))\n\t\tstatements.push_back(convertJsonToASTNode<Statement>(stat));\n\treturn createASTNode<Block>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\"),\n\t\t_unchecked,\n\t\tstatements\n\t);\n}\n\nASTPointer<PlaceholderStatement> ASTJsonImporter::createPlaceholderStatement(Json const&  _node)\n{\n\treturn createASTNode<PlaceholderStatement>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\")\n\t);\n}\n\nASTPointer<IfStatement> ASTJsonImporter::createIfStatement(Json const&  _node)\n{\n\treturn createASTNode<IfStatement>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\"),\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"condition\")),\n\t\tconvertJsonToASTNode<Statement>(member(_node, \"trueBody\")),\n\t\tnullOrCast<Statement>(member(_node, \"falseBody\"))\n\t);\n}\n\nASTPointer<TryCatchClause> ASTJsonImporter::createTryCatchClause(Json const&  _node)\n{\n\treturn createASTNode<TryCatchClause>(\n\t\t_node,\n\t\tmemberAsASTString(_node, \"errorName\"),\n\t\tnullOrCast<ParameterList>(member(_node, \"parameters\")),\n\t\tconvertJsonToASTNode<Block>(member(_node, \"block\"))\n\t);\n}\n\nASTPointer<TryStatement> ASTJsonImporter::createTryStatement(Json const&  _node)\n{\n\tstd::vector<ASTPointer<TryCatchClause>> clauses;\n\n\tfor (auto& param: _node[\"clauses\"])\n\t\tclauses.emplace_back(createTryCatchClause(param));\n\n\treturn createASTNode<TryStatement>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\"),\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"externalCall\")),\n\t\tclauses\n\t);\n}\n\nASTPointer<WhileStatement> ASTJsonImporter::createWhileStatement(Json const&  _node, bool _isDoWhile=false)\n{\n\treturn createASTNode<WhileStatement>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\"),\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"condition\")),\n\t\tconvertJsonToASTNode<Statement>(member(_node, \"body\")),\n\t\t_isDoWhile\n\t);\n}\n\nASTPointer<ForStatement> ASTJsonImporter::createForStatement(Json const&  _node)\n{\n\treturn createASTNode<ForStatement>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\"),\n\t\tnullOrCast<Statement>(member(_node, \"initializationExpression\")),\n\t\tnullOrCast<Expression>(member(_node, \"condition\")),\n\t\tnullOrCast<ExpressionStatement>(member(_node, \"loopExpression\")),\n\t\tconvertJsonToASTNode<Statement>(member(_node, \"body\"))\n\t);\n}\n\nASTPointer<Continue> ASTJsonImporter::createContinue(Json const&  _node)\n{\n\treturn createASTNode<Continue>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\")\n\t);\n}\n\nASTPointer<Break> ASTJsonImporter::createBreak(Json const&  _node)\n{\n\treturn createASTNode<Break>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\")\n\t);\n}\n\nASTPointer<Return> ASTJsonImporter::createReturn(Json const&  _node)\n{\n\treturn createASTNode<Return>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\"),\n\t\tnullOrCast<Expression>(member(_node, \"expression\"))\n\t);\n}\n\nASTPointer<Throw> ASTJsonImporter::createThrow(Json const&  _node)\n{\n\treturn createASTNode<Throw>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\")\n\t);\n}\n\nASTPointer<EmitStatement> ASTJsonImporter::createEmitStatement(Json const&  _node)\n{\n\treturn createASTNode<EmitStatement>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\"),\n\t\tcreateFunctionCall(member(_node, \"eventCall\"))\n\t);\n}\n\nASTPointer<RevertStatement> ASTJsonImporter::createRevertStatement(Json const&  _node)\n{\n\treturn createASTNode<RevertStatement>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\"),\n\t\tcreateFunctionCall(member(_node, \"errorCall\"))\n\t);\n}\n\nASTPointer<VariableDeclarationStatement> ASTJsonImporter::createVariableDeclarationStatement(Json const& _node)\n{\n\tstd::vector<ASTPointer<VariableDeclaration>> variables;\n\tfor (auto& var: member(_node, \"declarations\"))\n\t\tvariables.push_back(var.is_null() ? nullptr : createVariableDeclaration(var)); //unnamed components are empty pointers\n\treturn createASTNode<VariableDeclarationStatement>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\"),\n\t\tvariables,\n\t\tnullOrCast<Expression>(member(_node, \"initialValue\"))\n\t);\n}\n\nASTPointer<ExpressionStatement> ASTJsonImporter::createExpressionStatement(Json const&  _node)\n{\n\treturn createASTNode<ExpressionStatement>(\n\t\t_node,\n\t\tnullOrASTString(_node, \"documentation\"),\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"expression\"))\n\t);\n}\n\nASTPointer<Conditional> ASTJsonImporter::createConditional(Json const&  _node)\n{\n\treturn createASTNode<Conditional>(\n\t\t_node,\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"condition\")),\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"trueExpression\")),\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"falseExpression\"))\n\t);\n}\n\nASTPointer<Assignment> ASTJsonImporter::createAssignment(Json const&  _node)\n{\n\treturn createASTNode<Assignment>(\n\t\t_node,\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"leftHandSide\")),\n\t\tscanSingleToken(member(_node, \"operator\")),\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"rightHandSide\"))\n\t);\n}\n\nASTPointer<TupleExpression> ASTJsonImporter::createTupleExpression(Json const&  _node)\n{\n\tstd::vector<ASTPointer<Expression>> components;\n\tfor (auto& comp: member(_node, \"components\"))\n\t\tcomponents.push_back(nullOrCast<Expression>(comp));\n\treturn createASTNode<TupleExpression>(\n\t\t_node,\n\t\tcomponents,\n\t\tmemberAsBool(_node, \"isInlineArray\")\n\t);\n}\n\nASTPointer<UnaryOperation> ASTJsonImporter::createUnaryOperation(Json const&  _node)\n{\n\treturn createASTNode<UnaryOperation>(\n\t\t_node,\n\t\tscanSingleToken(member(_node, \"operator\")),\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"subExpression\")),\n\t\tmemberAsBool(_node, \"prefix\")\n\t);\n}\n\nASTPointer<BinaryOperation> ASTJsonImporter::createBinaryOperation(Json const&  _node)\n{\n\treturn createASTNode<BinaryOperation>(\n\t\t_node,\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"leftExpression\")),\n\t\tscanSingleToken(member(_node, \"operator\")),\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"rightExpression\"))\n\t);\n}\n\nASTPointer<FunctionCall> ASTJsonImporter::createFunctionCall(Json const&  _node)\n{\n\tstd::vector<ASTPointer<Expression>> arguments;\n\tfor (auto& arg: member(_node, \"arguments\"))\n\t\targuments.push_back(convertJsonToASTNode<Expression>(arg));\n\tstd::vector<ASTPointer<ASTString>> names;\n\tfor (auto& name: member(_node, \"names\"))\n\t{\n\t\tastAssert(name.is_string(), \"Expected 'names' members to be strings!\");\n\t\tnames.push_back(std::make_shared<ASTString>(name.get<std::string>()));\n\t}\n\n\tstd::optional<std::vector<SourceLocation>> sourceLocations = createSourceLocations(_node);\n\n\treturn createASTNode<FunctionCall>(\n\t\t_node,\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"expression\")),\n\t\targuments,\n\t\tnames,\n\t\tsourceLocations ?\n\t\t\t*sourceLocations :\n\t\t\tstd::vector<SourceLocation>(names.size())\n\t);\n}\n\nASTPointer<FunctionCallOptions> ASTJsonImporter::createFunctionCallOptions(Json const&  _node)\n{\n\tstd::vector<ASTPointer<Expression>> options;\n\tfor (auto& option: member(_node, \"options\"))\n\t\toptions.push_back(convertJsonToASTNode<Expression>(option));\n\tstd::vector<ASTPointer<ASTString>> names;\n\tfor (auto& name: member(_node, \"names\"))\n\t{\n\t\tastAssert(name.is_string(), \"Expected 'names' members to be strings!\");\n\t\tnames.push_back(std::make_shared<ASTString>(name.get<std::string>()));\n\t}\n\n\treturn createASTNode<FunctionCallOptions>(\n\t\t_node,\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"expression\")),\n\t\toptions,\n\t\tnames\n\t);\n}\n\nASTPointer<NewExpression> ASTJsonImporter::createNewExpression(Json const&  _node)\n{\n\treturn createASTNode<NewExpression>(\n\t\t_node,\n\t\tconvertJsonToASTNode<TypeName>(member(_node, \"typeName\"))\n\t);\n}\n\nASTPointer<MemberAccess> ASTJsonImporter::createMemberAccess(Json const&  _node)\n{\n\tSourceLocation memberLocation;\n\tif (member(_node, \"memberLocation\").is_string())\n\t\tmemberLocation = solidity::langutil::parseSourceLocation(_node[\"memberLocation\"].get<std::string>(), m_sourceNames);\n\n\treturn createASTNode<MemberAccess>(\n\t\t_node,\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"expression\")),\n\t\tmemberAsASTString(_node, \"memberName\"),\n\t\tstd::move(memberLocation)\n\t);\n}\n\nASTPointer<IndexAccess> ASTJsonImporter::createIndexAccess(Json const& _node)\n{\n\treturn createASTNode<IndexAccess>(\n\t\t_node,\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"baseExpression\")),\n\t\tnullOrCast<Expression>(member(_node, \"indexExpression\"))\n\t);\n}\n\nASTPointer<IndexRangeAccess> ASTJsonImporter::createIndexRangeAccess(Json const& _node)\n{\n\treturn createASTNode<IndexRangeAccess>(\n\t\t_node,\n\t\tconvertJsonToASTNode<Expression>(member(_node, \"baseExpression\")),\n\t\tnullOrCast<Expression>(member(_node, \"startExpression\")),\n\t\tnullOrCast<Expression>(member(_node, \"endExpression\"))\n\t);\n}\n\nASTPointer<Identifier> ASTJsonImporter::createIdentifier(Json const& _node)\n{\n\treturn createASTNode<Identifier>(_node, memberAsASTString(_node, \"name\"));\n}\n\nASTPointer<ElementaryTypeNameExpression> ASTJsonImporter::createElementaryTypeNameExpression(Json const&  _node)\n{\n\treturn createASTNode<ElementaryTypeNameExpression>(\n\t\t_node,\n\t\tcreateElementaryTypeName(member(_node, \"typeName\"))\n\t);\n}\n\nASTPointer<ASTNode> ASTJsonImporter::createLiteral(Json const&  _node)\n{\n\tstatic std::string const valStr = \"value\";\n\tstatic std::string const hexValStr = \"hexValue\";\n\n\tastAssert(member(_node, valStr).is_string() || member(_node, hexValStr).is_string(), \"Literal-value is unset.\");\n\n\tASTPointer<ASTString> value = _node.contains(hexValStr) ?\n\t\tstd::make_shared<ASTString>(util::asString(util::fromHex(_node[hexValStr].get<std::string>()))) :\n\t\tstd::make_shared<ASTString>(_node[valStr].get<std::string>());\n\n\treturn createASTNode<Literal>(\n\t\t_node,\n\t\tliteralTokenKind(_node),\n\t\tvalue,\n\t\tmember(_node, \"subdenomination\").is_null() ? Literal::SubDenomination::None : subdenomination(_node)\n\t);\n}\n\nASTPointer<StructuredDocumentation> ASTJsonImporter::createDocumentation(Json const&  _node)\n{\n\tstatic std::string const textString = \"text\";\n\n\tastAssert(member(_node, textString).is_string(), \"'text' must be a string\");\n\n\treturn createASTNode<StructuredDocumentation>(\n\t\t_node,\n\t\tstd::make_shared<ASTString>(_node[textString].get<std::string>())\n\t);\n}\n\n// ===== helper functions ==========\n\nJson ASTJsonImporter::member(Json const& _node, std::string const& _name)\n{\n\tif (!_node.contains(_name))\n\t\treturn Json();\n\treturn _node[_name];\n}\n\nToken ASTJsonImporter::scanSingleToken(Json const& _node)\n{\n\tlangutil::CharStream charStream(_node.get<std::string>(), \"\");\n\tlangutil::Scanner scanner{charStream};\n\tastAssert(scanner.peekNextToken() == Token::EOS, \"Token string is too long.\");\n\treturn scanner.currentToken();\n}\n\nASTPointer<ASTString> ASTJsonImporter::nullOrASTString(Json const& _json, std::string const& _name)\n{\n\treturn (_json.contains(_name) && (_json[_name].is_string())) ? memberAsASTString(_json, _name) : nullptr;\n}\n\nASTPointer<ASTString> ASTJsonImporter::memberAsASTString(Json const& _node, std::string const& _name)\n{\n\tJson value = member(_node, _name);\n\tastAssert(value.is_string(), \"field \" + _name + \" must be of type string.\");\n\treturn std::make_shared<ASTString>(_node[_name].get<std::string>());\n}\n\nbool ASTJsonImporter::memberAsBool(Json const& _node, std::string const& _name)\n{\n\tJson value = member(_node, _name);\n\tastAssert(value.is_boolean(), \"field \" + _name + \" must be of type boolean.\");\n\treturn _node[_name].get<bool>();\n}\n\n\n// =========== JSON to definition helpers =======================\n\nContractKind ASTJsonImporter::contractKind(Json const& _node)\n{\n\tContractKind kind;\n\tastAssert(!member(_node, \"contractKind\").is_null(), \"'Contract-kind' can not be null.\");\n\tif (_node[\"contractKind\"].get<std::string>() == \"interface\")\n\t\tkind = ContractKind::Interface;\n\telse if (_node[\"contractKind\"].get<std::string>() == \"contract\")\n\t\tkind = ContractKind::Contract;\n\telse if (_node[\"contractKind\"].get<std::string>() == \"library\")\n\t\tkind = ContractKind::Library;\n\telse\n\t\tastAssert(false, \"Unknown ContractKind\");\n\treturn kind;\n}\n\nToken ASTJsonImporter::literalTokenKind(Json const& _node)\n{\n\tastAssert(member(_node, \"kind\").is_string(), \"Token-'kind' expected to be a string.\");\n\tToken tok;\n\tif (_node[\"kind\"].get<std::string>() == \"number\")\n\t\ttok = Token::Number;\n\telse if (_node[\"kind\"].get<std::string>() == \"string\")\n\t\ttok = Token::StringLiteral;\n\telse if (_node[\"kind\"].get<std::string>() == \"unicodeString\")\n\t\ttok = Token::UnicodeStringLiteral;\n\telse if (_node[\"kind\"].get<std::string>() == \"hexString\")\n\t\ttok = Token::HexStringLiteral;\n\telse if (_node[\"kind\"].get<std::string>() == \"bool\")\n\t\ttok = (member(_node, \"value\").get<std::string>() == \"true\") ? Token::TrueLiteral : Token::FalseLiteral;\n\telse\n\t\tastAssert(false, \"Unknown kind of literalString\");\n\treturn tok;\n}\n\nVisibility ASTJsonImporter::visibility(Json const& _node)\n{\n\tJson visibility = member(_node, \"visibility\");\n\tastAssert(visibility.is_string(), \"'visibility' expected to be a string.\");\n\n\tstd::string const visibilityStr = visibility.get<std::string>();\n\n\tif (visibilityStr == \"default\")\n\t\treturn Visibility::Default;\n\telse if (visibilityStr == \"private\")\n\t\treturn Visibility::Private;\n\telse if ( visibilityStr == \"internal\")\n\t\treturn Visibility::Internal;\n\telse if (visibilityStr == \"public\")\n\t\treturn Visibility::Public;\n\telse if (visibilityStr == \"external\")\n\t\treturn Visibility::External;\n\telse\n\t\tastAssert(false, \"Unknown visibility declaration\");\n\n\t// FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794)\n\tutil::unreachable();\n}\n\nVariableDeclaration::Location ASTJsonImporter::location(Json const& _node)\n{\n\tJson storageLoc = member(_node, \"storageLocation\");\n\tastAssert(storageLoc.is_string(), \"'storageLocation' expected to be a string.\");\n\n\tstd::string const storageLocStr = storageLoc.get<std::string>();\n\n\tif (storageLocStr == \"default\")\n\t\treturn VariableDeclaration::Location::Unspecified;\n\telse if (storageLocStr == \"storage\")\n\t\treturn VariableDeclaration::Location::Storage;\n\telse if (storageLocStr == \"memory\")\n\t\treturn VariableDeclaration::Location::Memory;\n\telse if (storageLocStr == \"calldata\")\n\t\treturn VariableDeclaration::Location::CallData;\n\telse if (storageLocStr == \"transient\")\n\t\treturn VariableDeclaration::Location::Transient;\n\telse\n\t\tastAssert(false, \"Unknown location declaration\");\n\n\t// FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794)\n\tutil::unreachable();\n}\n\nLiteral::SubDenomination ASTJsonImporter::subdenomination(Json const& _node)\n{\n\tJson subDen = member(_node, \"subdenomination\");\n\n\tif (subDen.is_null())\n\t\treturn Literal::SubDenomination::None;\n\n\tastAssert(subDen.is_string(), \"'subDenomination' expected to be string.\");\n\n\tstd::string const subDenStr = subDen.get<std::string>();\n\n\tif (subDenStr == \"wei\")\n\t\treturn Literal::SubDenomination::Wei;\n\telse if (subDenStr == \"gwei\")\n\t\treturn Literal::SubDenomination::Gwei;\n\telse if (subDenStr == \"ether\")\n\t\treturn Literal::SubDenomination::Ether;\n\telse if (subDenStr == \"seconds\")\n\t\treturn Literal::SubDenomination::Second;\n\telse if (subDenStr == \"minutes\")\n\t\treturn Literal::SubDenomination::Minute;\n\telse if (subDenStr == \"hours\")\n\t\treturn Literal::SubDenomination::Hour;\n\telse if (subDenStr == \"days\")\n\t\treturn Literal::SubDenomination::Day;\n\telse if (subDenStr == \"weeks\")\n\t\treturn Literal::SubDenomination::Week;\n\telse if (subDenStr == \"years\")\n\t\treturn Literal::SubDenomination::Year;\n\telse\n\t\tastAssert(false, \"Unknown subdenomination\");\n\n\t// FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794)\n\tutil::unreachable();\n}\n\nStateMutability ASTJsonImporter::stateMutability(Json const& _node)\n{\n\tastAssert(member(_node, \"stateMutability\").is_string(), \"StateMutability' expected to be string.\");\n\tstd::string const mutabilityStr = member(_node, \"stateMutability\").get<std::string>();\n\n\tif (mutabilityStr == \"pure\")\n\t\treturn StateMutability::Pure;\n\telse if (mutabilityStr == \"view\")\n\t\treturn StateMutability::View;\n\telse if (mutabilityStr == \"nonpayable\")\n\t\treturn StateMutability::NonPayable;\n\telse if (mutabilityStr == \"payable\")\n\t\treturn StateMutability::Payable;\n\telse\n\t\tastAssert(false, \"Unknown stateMutability\");\n\n\t// FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794)\n\tutil::unreachable();\n}\n\n}\n"
  },
  {
    "path": "libsolidity/ast/ASTJsonImporter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author julius <djudju@protonmail.com>\n * @date 2019\n * Converts the AST from JSON format to ASTNode\n */\n\n#pragma once\n\n#include <vector>\n#include <libsolutil/JSON.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <liblangutil/EVMVersion.h>\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/SourceLocation.h>\n\nnamespace solidity::frontend\n{\n\n/**\n * Component that imports an AST from json format to the internal format\n */\nclass ASTJsonImporter\n{\npublic:\n\tASTJsonImporter(langutil::EVMVersion _evmVersion, std::optional<uint8_t> _eofVersion)\n\t\t:m_evmVersion(_evmVersion), m_eofVersion(_eofVersion)\n\t{}\n\n\t/// Converts the AST from JSON-format to ASTPointer\n\t/// @a _sourceList used to provide source names for the ASTs\n\t/// @returns map of sourcenames to their respective ASTs\n\tstd::map<std::string, ASTPointer<SourceUnit>> jsonToSourceUnit(std::map<std::string, Json> const& _sourceList);\n\nprivate:\n\n\t// =========== general creation functions ==============\n\n\t/// Sets the source location and nodeID\n\t/// @returns the ASTNode Object class of the respective JSON node,\n\ttemplate <typename T, typename... Args>\n\tASTPointer<T> createASTNode(Json const& _node, Args&&... _args);\n\t/// @returns the sourceLocation-object created from the string in the JSON node\n\tlangutil::SourceLocation const createSourceLocation(Json const& _node);\n\tstd::optional<std::vector<langutil::SourceLocation>> createSourceLocations(Json const& _node) const;\n\t/// Creates an ASTNode for a given JSON-ast of unknown type\n\t/// @returns Pointer to a new created ASTNode\n\tASTPointer<ASTNode> convertJsonToASTNode(Json const& _ast);\n\t/// @returns a pointer to the more specific subclass of ASTNode\n\t/// as indicated by the nodeType field of the json\n\ttemplate<class T>\n\tASTPointer<T> convertJsonToASTNode(Json const& _node);\n\n\tlangutil::SourceLocation createNameSourceLocation(Json const& _node);\n\t/// @returns source location of a mapping key name\n\tlangutil::SourceLocation createKeyNameSourceLocation(Json const& _node);\n\t/// @returns source location of a mapping value name\n\tlangutil::SourceLocation createValueNameSourceLocation(Json const& _node);\n\n\t/// \\defgroup nodeCreators JSON to AST-Nodes\n\t///@{\n\tASTPointer<SourceUnit> createSourceUnit(Json const& _node, std::string const& _srcName);\n\tASTPointer<PragmaDirective> createPragmaDirective(Json const& _node);\n\tASTPointer<ImportDirective> createImportDirective(Json const& _node);\n\tASTPointer<ContractDefinition> createContractDefinition(Json const& _node);\n\tASTPointer<IdentifierPath> createIdentifierPath(Json const& _node);\n\tASTPointer<InheritanceSpecifier> createInheritanceSpecifier(Json const& _node);\n\tASTPointer<UsingForDirective> createUsingForDirective(Json const& _node);\n\tASTPointer<ASTNode> createStructDefinition(Json const& _node);\n\tASTPointer<EnumDefinition> createEnumDefinition(Json const& _node);\n\tASTPointer<EnumValue> createEnumValue(Json const& _node);\n\tASTPointer<UserDefinedValueTypeDefinition> createUserDefinedValueTypeDefinition(Json const& _node);\n\tASTPointer<ParameterList> createParameterList(Json const& _node);\n\tASTPointer<OverrideSpecifier> createOverrideSpecifier(Json const& _node);\n\tASTPointer<FunctionDefinition> createFunctionDefinition(Json const& _node);\n\tASTPointer<VariableDeclaration> createVariableDeclaration(Json const& _node);\n\tASTPointer<ModifierDefinition> createModifierDefinition(Json const& _node);\n\tASTPointer<ModifierInvocation> createModifierInvocation(Json const& _node);\n\tASTPointer<EventDefinition> createEventDefinition(Json const& _node);\n\tASTPointer<ErrorDefinition> createErrorDefinition(Json const& _node);\n\tASTPointer<ElementaryTypeName> createElementaryTypeName(Json const& _node);\n\tASTPointer<UserDefinedTypeName> createUserDefinedTypeName(Json const& _node);\n\tASTPointer<FunctionTypeName> createFunctionTypeName(Json const& _node);\n\tASTPointer<Mapping> createMapping(Json const& _node);\n\tASTPointer<ArrayTypeName> createArrayTypeName(Json const& _node);\n\tASTPointer<InlineAssembly> createInlineAssembly(Json const& _node);\n\tASTPointer<Block> createBlock(Json const& _node, bool _unchecked);\n\tASTPointer<PlaceholderStatement> createPlaceholderStatement(Json const& _node);\n\tASTPointer<IfStatement> createIfStatement(Json const& _node);\n\tASTPointer<TryCatchClause> createTryCatchClause(Json const& _node);\n\tASTPointer<TryStatement> createTryStatement(Json const& _node);\n\tASTPointer<WhileStatement> createWhileStatement(Json const& _node, bool _isDoWhile);\n\tASTPointer<ForStatement> createForStatement(Json const& _node);\n\tASTPointer<Continue> createContinue(Json const& _node);\n\tASTPointer<Break> createBreak(Json const& _node);\n\tASTPointer<Return> createReturn(Json const& _node);\n\tASTPointer<Throw> createThrow(Json const& _node);\n\tASTPointer<EmitStatement> createEmitStatement(Json const& _node);\n\tASTPointer<RevertStatement> createRevertStatement(Json const& _node);\n\tASTPointer<VariableDeclarationStatement> createVariableDeclarationStatement(Json const& _node);\n\tASTPointer<ExpressionStatement> createExpressionStatement(Json const& _node);\n\tASTPointer<Conditional> createConditional(Json const& _node);\n\tASTPointer<Assignment> createAssignment(Json const& _node);\n\tASTPointer<TupleExpression> createTupleExpression(Json const& _node);\n\tASTPointer<UnaryOperation> createUnaryOperation(Json const& _node);\n\tASTPointer<BinaryOperation> createBinaryOperation(Json const& _node);\n\tASTPointer<FunctionCall> createFunctionCall(Json const& _node);\n\tASTPointer<FunctionCallOptions> createFunctionCallOptions(Json const& _node);\n\tASTPointer<NewExpression> createNewExpression(Json const& _node);\n\tASTPointer<MemberAccess> createMemberAccess(Json const& _node);\n\tASTPointer<IndexAccess> createIndexAccess(Json const& _node);\n\tASTPointer<IndexRangeAccess> createIndexRangeAccess(Json const& _node);\n\tASTPointer<Identifier> createIdentifier(Json const& _node);\n\tASTPointer<ElementaryTypeNameExpression> createElementaryTypeNameExpression(Json const& _node);\n\tASTPointer<ASTNode> createLiteral(Json const& _node);\n\tASTPointer<StructuredDocumentation> createDocumentation(Json const& _node);\n\tASTPointer<StorageLayoutSpecifier> createStorageLayoutSpecifier(Json const& _node);\n\t///@}\n\n\t// =============== general helper functions ===================\n\t/// @returns the member of a given JSON object or null if member does not exist\n\tJson member(Json const& _node, std::string const& _name);\n\t/// @returns the appropriate TokenObject used in parsed Strings (pragma directive or operator)\n\tToken scanSingleToken(Json const& _node);\n\ttemplate<class T>\n\t///@returns nullptr or an ASTPointer cast to a specific Class\n\tASTPointer<T> nullOrCast(Json const& _json);\n\t/// @returns nullptr or ASTString, given an JSON string or an empty field\n\tASTPointer<ASTString> nullOrASTString(Json const& _json, std::string const& _name);\n\n\t// ============== JSON to definition helpers ===============\n\t/// \\defgroup typeHelpers Json to ast-datatype helpers\n\t/// {@\n\tASTPointer<ASTString> memberAsASTString(Json const& _node, std::string const& _name);\n\tbool memberAsBool(Json const& _node, std::string const& _name);\n\tVisibility visibility(Json const& _node);\n\tStateMutability stateMutability(Json const& _node);\n\tVariableDeclaration::Location location(Json const& _node);\n\tContractKind contractKind(Json const& _node);\n\tToken literalTokenKind(Json const& _node);\n\tLiteral::SubDenomination subdenomination(Json const& _node);\n\t///@}\n\n\t// =========== member variables ===============\n\t/// list of source names, order by source index\n\tstd::vector<std::shared_ptr<std::string const>> m_sourceNames;\n\t/// filepath to AST\n\tstd::map<std::string, ASTPointer<SourceUnit>> m_sourceUnits;\n\t/// IDs already used by the nodes\n\tstd::set<int64_t> m_usedIDs;\n\t/// Configured EVM version\n\tlangutil::EVMVersion m_evmVersion;\n\t/// Configured EOF version. Equals std::nullopt if non-EOF\n\tstd::optional<uint8_t> m_eofVersion;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/ast/ASTUtils.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/analysis/ConstantEvaluator.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTUtils.h>\n#include <libsolidity/ast/ASTVisitor.h>\n\n#include <libsolutil/Algorithms.h>\n\nnamespace solidity::frontend\n{\n\nASTNode const* locateInnermostASTNode(int _offsetInFile, SourceUnit const& _sourceUnit)\n{\n\tASTNode const* innermostMatch = nullptr;\n\tauto locator = SimpleASTVisitor(\n\t\t[&](ASTNode const& _node) -> bool\n\t\t{\n\t\t\t// In the AST parent location always covers the whole child location.\n\t\t\t// The parent is visited first so to get the innermost node we simply\n\t\t\t// take the last one that still contains the offset.\n\n\t\t\tif (!_node.location().containsOffset(_offsetInFile))\n\t\t\t\treturn false;\n\n\t\t\tinnermostMatch = &_node;\n\t\t\treturn true;\n\t\t},\n\t\t[](ASTNode const&) {}\n\t);\n\t_sourceUnit.accept(locator);\n\treturn innermostMatch;\n}\n\nbool isConstantVariableRecursive(VariableDeclaration const& _varDecl)\n{\n\tsolAssert(_varDecl.isConstant(), \"Constant variable expected\");\n\n\tauto visitor = [](VariableDeclaration const& _variable, util::CycleDetector<VariableDeclaration>& _cycleDetector, size_t _depth)\n\t{\n\t\tsolAssert(_depth < 256, \"Recursion depth limit reached\");\n\t\tif (!_variable.value())\n\t\t\t// This should result in an error later on.\n\t\t\treturn;\n\n\t\tif (auto referencedVarDecl = dynamic_cast<VariableDeclaration const*>(\n\t\t\tASTNode::referencedDeclaration(*_variable.value()))\n\t\t)\n\t\t\tif (referencedVarDecl->isConstant())\n\t\t\t\t_cycleDetector.run(*referencedVarDecl);\n\t};\n\n\treturn util::CycleDetector<VariableDeclaration>(visitor).run(_varDecl) != nullptr;\n}\n\nVariableDeclaration const* rootConstVariableDeclaration(VariableDeclaration const& _varDecl)\n{\n\tsolAssert(_varDecl.isConstant(), \"Constant variable expected\");\n\tsolAssert(!isConstantVariableRecursive(_varDecl), \"Recursive declaration\");\n\n\tVariableDeclaration const* rootDecl = &_varDecl;\n\tIdentifier const* identifier;\n\twhile ((identifier = dynamic_cast<Identifier const*>(rootDecl->value().get())))\n\t{\n\t\tauto referencedVarDecl = dynamic_cast<VariableDeclaration const*>(identifier->annotation().referencedDeclaration);\n\t\tif (!referencedVarDecl || !referencedVarDecl->isConstant())\n\t\t\treturn nullptr;\n\t\trootDecl = referencedVarDecl;\n\t}\n\treturn rootDecl;\n}\n\nExpression const* resolveOuterUnaryTuples(Expression const* _expr)\n{\n\twhile (auto const* tupleExpression = dynamic_cast<TupleExpression const*>(_expr))\n\t\tif (tupleExpression->components().size() == 1)\n\t\t\t_expr = tupleExpression->components().front().get();\n\t\telse\n\t\t\tbreak;\n\treturn _expr;\n}\n\nType const* type(Expression const& _expression)\n{\n\tsolAssert(!!_expression.annotation().type, \"Type requested but not present.\");\n\treturn _expression.annotation().type;\n}\n\nType const* type(VariableDeclaration const& _variable)\n{\n\tsolAssert(!!_variable.annotation().type, \"Type requested but not present.\");\n\treturn _variable.annotation().type;\n}\n\nbigint contractStorageSizeUpperBound(ContractDefinition const& _contract, VariableDeclaration::Location _location)\n{\n\tsolAssert(_location == VariableDeclaration::Location::Unspecified || _location == VariableDeclaration::Location::Transient);\n\n\tbigint size = 0;\n\tfor (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts)\n\t\tfor (VariableDeclaration const* variable: contract->stateVariables())\n\t\t\tif (\n\t\t\t\t!(variable->isConstant() || variable->immutable()) &&\n\t\t\t\tvariable->referenceLocation() == _location\n\t\t\t)\n\t\t\t\tsize += variable->annotation().type->storageSizeUpperBound();\n\n\treturn size;\n}\n\nu256 layoutBaseForInheritanceHierarchy(ContractDefinition const& _topLevelContract, DataLocation _location)\n{\n\tif (_location != DataLocation::Storage)\n\t{\n\t\tsolAssert(_location == DataLocation::Transient);\n\t\treturn 0;\n\t}\n\n\tif (auto const* storageLayoutSpecifier = _topLevelContract.storageLayoutSpecifier())\n\t\treturn *storageLayoutSpecifier->annotation().baseSlot;\n\n\treturn 0;\n}\n\nstd::optional<u256> erc7201CompileTimeValue(FunctionCall const& _erc7201Call)\n{\n\tauto const* erc7201Function = dynamic_cast<MagicVariableDeclaration const*>(ASTNode::referencedDeclaration(_erc7201Call.expression()));\n\tsolAssert(erc7201Function);\n\tsolAssert(erc7201Function->functionType(true /* internal */)->kind() == FunctionType::Kind::ERC7201);\n\n\tauto evaluatedResult = ConstantEvaluator::tryEvaluate(_erc7201Call);\n\n\tif (std::holds_alternative<std::monostate>(evaluatedResult.value))\n\t\treturn std::nullopt;\n\n\tsolAssert(std::holds_alternative<rational>(evaluatedResult.value));\n\tauto rationalValue = std::get<rational>(evaluatedResult.value);\n\tsolAssert(rationalValue.denominator() == 1);\n\tbigint baseSlot = rationalValue.numerator();\n\tsolAssert(baseSlot <= std::numeric_limits<u256>::max());\n\treturn u256(baseSlot);\n}\n}\n"
  },
  {
    "path": "libsolidity/ast/ASTUtils.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/Numeric.h>\n\nnamespace solidity::frontend\n{\n\nclass ASTNode;\nclass ContractDefinition;\nclass Declaration;\nclass Expression;\nclass FunctionCall;\nclass SourceUnit;\nclass VariableDeclaration;\n\n/// Find the topmost referenced constant variable declaration when the given variable\n/// declaration value is an identifier. Works only for constant variable declarations.\n/// Returns nullptr if an identifier in the chain is not referencing a constant variable declaration.\nVariableDeclaration const* rootConstVariableDeclaration(VariableDeclaration const& _varDecl);\n\n/// Returns true if the constant variable declaration is recursive.\nbool isConstantVariableRecursive(VariableDeclaration const& _varDecl);\n\n/// Returns the innermost AST node that covers the given location or nullptr if not found.\nASTNode const* locateInnermostASTNode(int _offsetInFile, SourceUnit const& _sourceUnit);\n\n/// @returns @a _expr itself, in case it is not a unary tuple expression. Otherwise it descends recursively\n/// into unary tuples and returns the contained expression.\nExpression const* resolveOuterUnaryTuples(Expression const* _expr);\n\n/// @returns the type of an expression and asserts that it is present.\nType const* type(Expression const& _expression);\n/// @returns the type of the given variable and throws if the type is not present\n/// (this can happen for variables with non-explicit types before their types are resolved)\nType const* type(VariableDeclaration const& _variable);\n\n/// @returns The number of slots occupied by all state variables in contract's inheritance hierarchy,\n/// located in @a _location (either storage or transient storage).\nbigint contractStorageSizeUpperBound(ContractDefinition const& _contract, VariableDeclaration::Location _location);\n\n/// @returns The base slot of the inheritance hierarchy rooted at the specified contract.\n/// The value comes from the inheritance specifier of the contract and defaults to zero.\n/// The value is zero also when the contract is an interface or a library (and cannot have storage).\n/// Assumes analysis was successful.\nu256 layoutBaseForInheritanceHierarchy(ContractDefinition const& _topLevelContract, DataLocation _location);\n\n/// @returns The storage namespace base address using the ERC-7201 formula, if it can be calculated at compile time.\n/// Assumes FunctionCall refers to erc7201 builtin.\nstd::optional<u256> erc7201CompileTimeValue(FunctionCall const& _erc7201Call);\n\n}\n"
  },
  {
    "path": "libsolidity/ast/ASTVisitor.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * AST visitor base class.\n */\n\n#pragma once\n\n#include <libsolidity/ast/AST.h>\n\n#include <functional>\n#include <string>\n#include <vector>\n#include <utility>\n\nnamespace solidity::frontend\n{\n\n/**\n * Visitor interface for the abstract syntax tree. This class is tightly bound to the\n * implementation of @ref ASTNode::accept and its overrides. After a call to\n * @ref ASTNode::accept, the function visit for the appropriate parameter is called and then\n * (if it returns true) this continues recursively for all child nodes in document order\n * (there is an exception for contracts). After all child nodes have been visited, endVisit is\n * called for the node.\n */\nclass ASTVisitor\n{\npublic:\n\tASTVisitor() = default;\n\n\tASTVisitor(ASTVisitor const&) = delete;\n\tASTVisitor(ASTVisitor&&) = delete;\n\n\tASTVisitor& operator=(ASTVisitor const&) = delete;\n\tASTVisitor& operator=(ASTVisitor&&) = delete;\n\n\tvirtual ~ASTVisitor() = default;\n\n\tvirtual bool visit(SourceUnit& _node) { return visitNode(_node); }\n\tvirtual bool visit(PragmaDirective& _node) { return visitNode(_node); }\n\tvirtual bool visit(ImportDirective& _node) { return visitNode(_node); }\n\tvirtual bool visit(ContractDefinition& _node) { return visitNode(_node); }\n\tvirtual bool visit(IdentifierPath& _node) { return visitNode(_node); }\n\tvirtual bool visit(InheritanceSpecifier& _node) { return visitNode(_node); }\n\tvirtual bool visit(UsingForDirective& _node) { return visitNode(_node); }\n\tvirtual bool visit(UserDefinedValueTypeDefinition& _node) { return visitNode(_node); }\n\tvirtual bool visit(StructDefinition& _node) { return visitNode(_node); }\n\tvirtual bool visit(EnumDefinition& _node) { return visitNode(_node); }\n\tvirtual bool visit(EnumValue& _node) { return visitNode(_node); }\n\tvirtual bool visit(ParameterList& _node) { return visitNode(_node); }\n\tvirtual bool visit(OverrideSpecifier& _node) { return visitNode(_node); }\n\tvirtual bool visit(FunctionDefinition& _node) { return visitNode(_node); }\n\tvirtual bool visit(VariableDeclaration& _node) { return visitNode(_node); }\n\tvirtual bool visit(ModifierDefinition& _node) { return visitNode(_node); }\n\tvirtual bool visit(ModifierInvocation& _node) { return visitNode(_node); }\n\tvirtual bool visit(EventDefinition& _node) { return visitNode(_node); }\n\tvirtual bool visit(ErrorDefinition& _node) { return visitNode(_node); }\n\tvirtual bool visit(ElementaryTypeName& _node) { return visitNode(_node); }\n\tvirtual bool visit(UserDefinedTypeName& _node) { return visitNode(_node); }\n\tvirtual bool visit(FunctionTypeName& _node) { return visitNode(_node); }\n\tvirtual bool visit(Mapping& _node) { return visitNode(_node); }\n\tvirtual bool visit(ArrayTypeName& _node) { return visitNode(_node); }\n\tvirtual bool visit(InlineAssembly& _node) { return visitNode(_node); }\n\tvirtual bool visit(Block& _node) { return visitNode(_node); }\n\tvirtual bool visit(PlaceholderStatement& _node) { return visitNode(_node); }\n\tvirtual bool visit(IfStatement& _node) { return visitNode(_node); }\n\tvirtual bool visit(TryCatchClause& _node) { return visitNode(_node); }\n\tvirtual bool visit(TryStatement& _node) { return visitNode(_node); }\n\tvirtual bool visit(WhileStatement& _node) { return visitNode(_node); }\n\tvirtual bool visit(ForStatement& _node) { return visitNode(_node); }\n\tvirtual bool visit(Continue& _node) { return visitNode(_node); }\n\tvirtual bool visit(Break& _node) { return visitNode(_node); }\n\tvirtual bool visit(Return& _node) { return visitNode(_node); }\n\tvirtual bool visit(Throw& _node) { return visitNode(_node); }\n\tvirtual bool visit(EmitStatement& _node) { return visitNode(_node); }\n\tvirtual bool visit(RevertStatement& _node) { return visitNode(_node); }\n\tvirtual bool visit(VariableDeclarationStatement& _node) { return visitNode(_node); }\n\tvirtual bool visit(ExpressionStatement& _node) { return visitNode(_node); }\n\tvirtual bool visit(Conditional& _node) { return visitNode(_node); }\n\tvirtual bool visit(Assignment& _node) { return visitNode(_node); }\n\tvirtual bool visit(TupleExpression& _node) { return visitNode(_node); }\n\tvirtual bool visit(UnaryOperation& _node) { return visitNode(_node); }\n\tvirtual bool visit(BinaryOperation& _node) { return visitNode(_node); }\n\tvirtual bool visit(FunctionCall& _node) { return visitNode(_node); }\n\tvirtual bool visit(FunctionCallOptions& _node) { return visitNode(_node); }\n\tvirtual bool visit(NewExpression& _node) { return visitNode(_node); }\n\tvirtual bool visit(MemberAccess& _node) { return visitNode(_node); }\n\tvirtual bool visit(IndexAccess& _node) { return visitNode(_node); }\n\tvirtual bool visit(IndexRangeAccess& _node) { return visitNode(_node); }\n\tvirtual bool visit(Identifier& _node) { return visitNode(_node); }\n\tvirtual bool visit(ElementaryTypeNameExpression& _node) { return visitNode(_node); }\n\tvirtual bool visit(Literal& _node) { return visitNode(_node); }\n\tvirtual bool visit(StructuredDocumentation& _node) { return visitNode(_node); }\n\tvirtual bool visit(StorageLayoutSpecifier& _node) { return visitNode(_node); }\n\t/// Experimental Solidity nodes\n\t/// @{\n\tvirtual bool visit(TypeClassDefinition& _node) { return visitNode(_node); }\n\tvirtual bool visit(TypeClassInstantiation& _node) { return visitNode(_node); }\n\tvirtual bool visit(TypeDefinition& _node) { return visitNode(_node); }\n\tvirtual bool visit(TypeClassName& _node) { return visitNode(_node); }\n\tvirtual bool visit(Builtin& _node) { return visitNode(_node); }\n\tvirtual bool visit(ForAllQuantifier& _node) { return visitNode(_node); }\n\t///  @}\n\n\tvirtual void endVisit(SourceUnit& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(PragmaDirective& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ImportDirective& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ContractDefinition& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(IdentifierPath& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(InheritanceSpecifier& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(UsingForDirective& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(UserDefinedValueTypeDefinition& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(StructDefinition& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(EnumDefinition& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(EnumValue& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ParameterList& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(OverrideSpecifier& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(FunctionDefinition& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(VariableDeclaration& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ModifierDefinition& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ModifierInvocation& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(EventDefinition& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ErrorDefinition& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ElementaryTypeName& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(UserDefinedTypeName& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(FunctionTypeName& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Mapping& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ArrayTypeName& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(InlineAssembly& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Block& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(PlaceholderStatement& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(IfStatement& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TryCatchClause& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TryStatement& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(WhileStatement& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ForStatement& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Continue& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Break& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Return& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Throw& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(EmitStatement& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(RevertStatement& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(VariableDeclarationStatement& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ExpressionStatement& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Conditional& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Assignment& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TupleExpression& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(UnaryOperation& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(BinaryOperation& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(FunctionCall& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(FunctionCallOptions& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(NewExpression& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(MemberAccess& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(IndexAccess& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(IndexRangeAccess& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Identifier& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ElementaryTypeNameExpression& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Literal& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(StructuredDocumentation& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(StorageLayoutSpecifier& _node) { endVisitNode(_node); }\n\t/// Experimental Solidity nodes\n\t/// @{\n\tvirtual void endVisit(TypeClassDefinition& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TypeClassInstantiation& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TypeDefinition& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TypeClassName& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Builtin& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ForAllQuantifier& _node) { endVisitNode(_node); }\n\t///  @}\n\nprotected:\n\t/// Generic function called by default for each node, to be overridden by derived classes\n\t/// if behaviour unspecific to a node type is desired.\n\tvirtual bool visitNode(ASTNode&) { return true; }\n\t/// Generic function called by default for each node, to be overridden by derived classes\n\t/// if behaviour unspecific to a node type is desired.\n\tvirtual void endVisitNode(ASTNode&) { }\n};\n\nclass ASTConstVisitor\n{\npublic:\n\tASTConstVisitor() = default;\n\n\tASTConstVisitor(ASTConstVisitor const&) = delete;\n\tASTConstVisitor(ASTConstVisitor&&) = delete;\n\n\tASTConstVisitor& operator=(ASTConstVisitor const&) = delete;\n\tASTConstVisitor& operator=(ASTConstVisitor&&) = delete;\n\n\tvirtual ~ASTConstVisitor() = default;\n\n\tvirtual bool visit(SourceUnit const& _node) { return visitNode(_node); }\n\tvirtual bool visit(PragmaDirective const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ImportDirective const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ContractDefinition const& _node) { return visitNode(_node); }\n\tvirtual bool visit(IdentifierPath const& _node) { return visitNode(_node); }\n\tvirtual bool visit(InheritanceSpecifier const& _node) { return visitNode(_node); }\n\tvirtual bool visit(StructDefinition const& _node) { return visitNode(_node); }\n\tvirtual bool visit(UsingForDirective const& _node) { return visitNode(_node); }\n\tvirtual bool visit(UserDefinedValueTypeDefinition const& _node) { return visitNode(_node); }\n\tvirtual bool visit(EnumDefinition const& _node) { return visitNode(_node); }\n\tvirtual bool visit(EnumValue const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ParameterList const& _node) { return visitNode(_node); }\n\tvirtual bool visit(OverrideSpecifier const& _node) { return visitNode(_node); }\n\tvirtual bool visit(FunctionDefinition const& _node) { return visitNode(_node); }\n\tvirtual bool visit(VariableDeclaration const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ModifierDefinition const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ModifierInvocation const& _node) { return visitNode(_node); }\n\tvirtual bool visit(EventDefinition const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ErrorDefinition const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ElementaryTypeName const& _node) { return visitNode(_node); }\n\tvirtual bool visit(UserDefinedTypeName const& _node) { return visitNode(_node); }\n\tvirtual bool visit(FunctionTypeName const& _node) { return visitNode(_node); }\n\tvirtual bool visit(Mapping const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ArrayTypeName const& _node) { return visitNode(_node); }\n\tvirtual bool visit(Block const& _node) { return visitNode(_node); }\n\tvirtual bool visit(PlaceholderStatement const& _node) { return visitNode(_node); }\n\tvirtual bool visit(IfStatement const& _node) { return visitNode(_node); }\n\tvirtual bool visit(TryCatchClause const& _node) { return visitNode(_node); }\n\tvirtual bool visit(TryStatement const& _node) { return visitNode(_node); }\n\tvirtual bool visit(WhileStatement const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ForStatement const& _node) { return visitNode(_node); }\n\tvirtual bool visit(Continue const& _node) { return visitNode(_node); }\n\tvirtual bool visit(InlineAssembly const& _node) { return visitNode(_node); }\n\tvirtual bool visit(Break const& _node) { return visitNode(_node); }\n\tvirtual bool visit(Return const& _node) { return visitNode(_node); }\n\tvirtual bool visit(Throw const& _node) { return visitNode(_node); }\n\tvirtual bool visit(EmitStatement const& _node) { return visitNode(_node); }\n\tvirtual bool visit(RevertStatement const& _node) { return visitNode(_node); }\n\tvirtual bool visit(VariableDeclarationStatement const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ExpressionStatement const& _node) { return visitNode(_node); }\n\tvirtual bool visit(Conditional const& _node) { return visitNode(_node); }\n\tvirtual bool visit(Assignment const& _node) { return visitNode(_node); }\n\tvirtual bool visit(TupleExpression const& _node) { return visitNode(_node); }\n\tvirtual bool visit(UnaryOperation const& _node) { return visitNode(_node); }\n\tvirtual bool visit(BinaryOperation const& _node) { return visitNode(_node); }\n\tvirtual bool visit(FunctionCall const& _node) { return visitNode(_node); }\n\tvirtual bool visit(FunctionCallOptions const& _node) { return visitNode(_node); }\n\tvirtual bool visit(NewExpression const& _node) { return visitNode(_node); }\n\tvirtual bool visit(MemberAccess const& _node) { return visitNode(_node); }\n\tvirtual bool visit(IndexAccess const& _node) { return visitNode(_node); }\n\tvirtual bool visit(IndexRangeAccess const& _node) { return visitNode(_node); }\n\tvirtual bool visit(Identifier const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ElementaryTypeNameExpression const& _node) { return visitNode(_node); }\n\tvirtual bool visit(Literal const& _node) { return visitNode(_node); }\n\tvirtual bool visit(StructuredDocumentation const& _node) { return visitNode(_node); }\n\tvirtual bool visit(StorageLayoutSpecifier const& _node) { return visitNode(_node); }\n\t/// Experimental Solidity nodes\n\t/// @{\n\tvirtual bool visit(TypeClassDefinition const& _node) { return visitNode(_node); }\n\tvirtual bool visit(TypeClassInstantiation const& _node) { return visitNode(_node); }\n\tvirtual bool visit(TypeDefinition const& _node) { return visitNode(_node); }\n\tvirtual bool visit(TypeClassName const& _node) { return visitNode(_node); }\n\tvirtual bool visit(Builtin const& _node) { return visitNode(_node); }\n\tvirtual bool visit(ForAllQuantifier const& _node) { return visitNode(_node); }\n\t///  @}\n\n\tvirtual void endVisit(SourceUnit const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(PragmaDirective const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ImportDirective const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ContractDefinition const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(IdentifierPath const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(InheritanceSpecifier const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(UsingForDirective const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(UserDefinedValueTypeDefinition const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(StructDefinition const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(EnumDefinition const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(EnumValue const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ParameterList const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(OverrideSpecifier const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(FunctionDefinition const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(VariableDeclaration const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ModifierDefinition const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ModifierInvocation const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(EventDefinition const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ErrorDefinition const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ElementaryTypeName const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(UserDefinedTypeName const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(FunctionTypeName const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Mapping const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ArrayTypeName const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Block const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(PlaceholderStatement const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(IfStatement const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TryCatchClause const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TryStatement const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(WhileStatement const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ForStatement const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Continue const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(InlineAssembly const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Break const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Return const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Throw const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(EmitStatement const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(RevertStatement const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(VariableDeclarationStatement const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ExpressionStatement const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Conditional const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Assignment const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TupleExpression const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(UnaryOperation const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(BinaryOperation const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(FunctionCall const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(FunctionCallOptions const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(NewExpression const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(MemberAccess const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(IndexAccess const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(IndexRangeAccess const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Identifier const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ElementaryTypeNameExpression const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Literal const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(StructuredDocumentation const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(StorageLayoutSpecifier const& _node) { endVisitNode(_node); }\n\t/// Experimental Solidity nodes\n\t/// @{\n\tvirtual void endVisit(TypeClassDefinition const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TypeClassInstantiation const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TypeDefinition const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(TypeClassName const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(Builtin const& _node) { endVisitNode(_node); }\n\tvirtual void endVisit(ForAllQuantifier const& _node) { endVisitNode(_node); }\n\t///  @}\n\nprotected:\n\t/// Generic function called by default for each node, to be overridden by derived classes\n\t/// if behaviour unspecific to a node type is desired.\n\tvirtual bool visitNode(ASTNode const&) { return true; }\n\t/// Generic function called by default for each node, to be overridden by derived classes\n\t/// if behaviour unspecific to a node type is desired.\n\tvirtual void endVisitNode(ASTNode const&) { }\n};\n\n/**\n * Utility class that accepts std::functions and calls them for visitNode and endVisitNode.\n */\nclass SimpleASTVisitor: public ASTConstVisitor\n{\npublic:\n\tSimpleASTVisitor(\n\t\tstd::function<bool(ASTNode const&)> _onVisit,\n\t\tstd::function<void(ASTNode const&)> _onEndVisit\n\t): m_onVisit(std::move(_onVisit)), m_onEndVisit(std::move(_onEndVisit)) {}\n\nprotected:\n\tbool visitNode(ASTNode const& _n) override { return m_onVisit ? m_onVisit(_n) : true; }\n\tvoid endVisitNode(ASTNode const& _n) override { m_onEndVisit(_n); }\n\nprivate:\n\tstd::function<bool(ASTNode const&)> m_onVisit;\n\tstd::function<void(ASTNode const&)> m_onEndVisit;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/ast/AST_accept.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Implementation of the accept functions of AST nodes, included by AST.cpp to not clutter that\n * file with these mechanical implementations.\n */\n\n#pragma once\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTVisitor.h>\n\nnamespace solidity::frontend\n{\n\nvoid SourceUnit::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_nodes, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid SourceUnit::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_nodes, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid PragmaDirective::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid PragmaDirective::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid ImportDirective::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tfor (SymbolAlias const& symbolAlias: symbolAliases())\n\t\t\tif (symbolAlias.symbol)\n\t\t\t\tsymbolAlias.symbol->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid ImportDirective::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tfor (SymbolAlias const& symbolAlias: symbolAliases())\n\t\t\tif (symbolAlias.symbol)\n\t\t\t\tsymbolAlias.symbol->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid StructuredDocumentation::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid StructuredDocumentation::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid ContractDefinition::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tlistAccept(m_baseContracts, _visitor);\n\t\tif (m_storageLayoutSpecifier)\n\t\t\tm_storageLayoutSpecifier->accept(_visitor);\n\t\tlistAccept(m_subNodes, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ContractDefinition::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tlistAccept(m_baseContracts, _visitor);\n\t\tif (m_storageLayoutSpecifier)\n\t\t\tm_storageLayoutSpecifier->accept(_visitor);\n\t\tlistAccept(m_subNodes, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid IdentifierPath::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid IdentifierPath::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid InheritanceSpecifier::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_baseName->accept(_visitor);\n\t\tif (m_arguments)\n\t\t\tlistAccept(*m_arguments, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid InheritanceSpecifier::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_baseName->accept(_visitor);\n\t\tif (m_arguments)\n\t\t\tlistAccept(*m_arguments, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid EnumDefinition::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_members, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid EnumDefinition::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_members, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid EnumValue::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid EnumValue::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid UserDefinedValueTypeDefinition::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_underlyingType)\n\t\t\tm_underlyingType->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid UserDefinedValueTypeDefinition::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_underlyingType)\n\t\t\tm_underlyingType->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid UsingForDirective::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tlistAccept(m_functionsOrLibrary, _visitor);\n\t\tif (m_typeName)\n\t\t\tm_typeName->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid UsingForDirective::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tlistAccept(m_functionsOrLibrary, _visitor);\n\t\tif (m_typeName)\n\t\t\tm_typeName->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid StructDefinition::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_members, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid StructDefinition::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_members, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid ParameterList::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_parameters, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid ParameterList::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_parameters, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid OverrideSpecifier::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_overrides, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid OverrideSpecifier::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_overrides, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid FunctionDefinition::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tif (m_overrides)\n\t\t\tm_overrides->accept(_visitor);\n\t\tm_parameters->accept(_visitor);\n\t\tif (m_returnParameters)\n\t\t\tm_returnParameters->accept(_visitor);\n\t\tif (m_experimentalReturnExpression)\n\t\t\tm_experimentalReturnExpression->accept(_visitor);\n\t\tlistAccept(m_functionModifiers, _visitor);\n\t\tif (m_body)\n\t\t\tm_body->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid FunctionDefinition::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tif (m_overrides)\n\t\t\tm_overrides->accept(_visitor);\n\t\tm_parameters->accept(_visitor);\n\t\tif (m_returnParameters)\n\t\t\tm_returnParameters->accept(_visitor);\n\t\tif (m_experimentalReturnExpression)\n\t\t\tm_experimentalReturnExpression->accept(_visitor);\n\t\tlistAccept(m_functionModifiers, _visitor);\n\t\tif (m_body)\n\t\t\tm_body->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid VariableDeclaration::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_typeName)\n\t\t\tm_typeName->accept(_visitor);\n\t\tif (m_typeExpression)\n\t\t\tm_typeExpression->accept(_visitor);\n\t\tif (m_overrides)\n\t\t\tm_overrides->accept(_visitor);\n\t\tif (m_value)\n\t\t\tm_value->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid VariableDeclaration::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_typeName)\n\t\t\tm_typeName->accept(_visitor);\n\t\tif (m_typeExpression)\n\t\t\tm_typeExpression->accept(_visitor);\n\t\tif (m_overrides)\n\t\t\tm_overrides->accept(_visitor);\n\t\tif (m_value)\n\t\t\tm_value->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ModifierDefinition::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tm_parameters->accept(_visitor);\n\t\tif (m_overrides)\n\t\t\tm_overrides->accept(_visitor);\n\t\tif (m_body)\n\t\t\tm_body->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ModifierDefinition::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tm_parameters->accept(_visitor);\n\t\tif (m_overrides)\n\t\t\tm_overrides->accept(_visitor);\n\t\tif (m_body)\n\t\t\tm_body->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ModifierInvocation::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_modifierName->accept(_visitor);\n\t\tif (m_arguments)\n\t\t\tlistAccept(*m_arguments, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ModifierInvocation::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_modifierName->accept(_visitor);\n\t\tif (m_arguments)\n\t\t\tlistAccept(*m_arguments, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid EventDefinition::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tm_parameters->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid EventDefinition::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tm_parameters->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ErrorDefinition::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tm_parameters->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ErrorDefinition::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tm_parameters->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ElementaryTypeName::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid ElementaryTypeName::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid UserDefinedTypeName::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tthis->pathNode().accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid UserDefinedTypeName::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tthis->pathNode().accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid FunctionTypeName::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_parameterTypes->accept(_visitor);\n\t\tm_returnTypes->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid FunctionTypeName::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_parameterTypes->accept(_visitor);\n\t\tm_returnTypes->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid Mapping::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_keyType->accept(_visitor);\n\t\tm_valueType->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid Mapping::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_keyType->accept(_visitor);\n\t\tm_valueType->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ArrayTypeName::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_baseType->accept(_visitor);\n\t\tif (m_length)\n\t\t\tm_length->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ArrayTypeName::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_baseType->accept(_visitor);\n\t\tif (m_length)\n\t\t\tm_length->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid InlineAssembly::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid InlineAssembly::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid Block::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_statements, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid Block::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tlistAccept(m_statements, _visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid PlaceholderStatement::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid PlaceholderStatement::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid IfStatement::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_condition->accept(_visitor);\n\t\tm_trueBody->accept(_visitor);\n\t\tif (m_falseBody)\n\t\t\tm_falseBody->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid IfStatement::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_condition->accept(_visitor);\n\t\tm_trueBody->accept(_visitor);\n\t\tif (m_falseBody)\n\t\t\tm_falseBody->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid TryCatchClause::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_parameters)\n\t\t\tm_parameters->accept(_visitor);\n\t\tm_block->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid TryCatchClause::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_parameters)\n\t\t\tm_parameters->accept(_visitor);\n\t\tm_block->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid TryStatement::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_externalCall->accept(_visitor);\n\t\tlistAccept(m_clauses, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid TryStatement::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_externalCall->accept(_visitor);\n\t\tlistAccept(m_clauses, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid WhileStatement::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_condition->accept(_visitor);\n\t\tm_body->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid WhileStatement::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_condition->accept(_visitor);\n\t\tm_body->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ForStatement::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_initExpression)\n\t\t\tm_initExpression->accept(_visitor);\n\t\tif (m_condExpression)\n\t\t\tm_condExpression->accept(_visitor);\n\t\tif (m_loopExpression)\n\t\t\tm_loopExpression->accept(_visitor);\n\t\tm_body->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ForStatement::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_initExpression)\n\t\t\tm_initExpression->accept(_visitor);\n\t\tif (m_condExpression)\n\t\t\tm_condExpression->accept(_visitor);\n\t\tif (m_loopExpression)\n\t\t\tm_loopExpression->accept(_visitor);\n\t\tm_body->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid Continue::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid Continue::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid Break::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid Break::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid Return::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tif (m_expression)\n\t\t\tm_expression->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid Return::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tif (m_expression)\n\t\t\tm_expression->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid Throw::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid Throw::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid RevertStatement::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tm_errorCall->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid RevertStatement::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tm_errorCall->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid EmitStatement::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tm_eventCall->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid EmitStatement::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tm_eventCall->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid ExpressionStatement::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tif (m_expression)\n\t\t\tm_expression->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid ExpressionStatement::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tif (m_expression)\n\t\t\tm_expression->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid VariableDeclarationStatement::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tfor (ASTPointer<VariableDeclaration> const& var: m_variables)\n\t\t\tif (var)\n\t\t\t\tvar->accept(_visitor);\n\t\tif (m_initialValue)\n\t\t\tm_initialValue->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid VariableDeclarationStatement::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tfor (ASTPointer<VariableDeclaration> const& var: m_variables)\n\t\t\tif (var)\n\t\t\t\tvar->accept(_visitor);\n\t\tif (m_initialValue)\n\t\t\tm_initialValue->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid Conditional::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_condition->accept(_visitor);\n\t\tm_trueExpression->accept(_visitor);\n\t\tm_falseExpression->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid Conditional::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_condition->accept(_visitor);\n\t\tm_trueExpression->accept(_visitor);\n\t\tm_falseExpression->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid Assignment::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_leftHandSide->accept(_visitor);\n\t\tm_rightHandSide->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid Assignment::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_leftHandSide->accept(_visitor);\n\t\tm_rightHandSide->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid TupleExpression::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tfor (auto const& component: m_components)\n\t\t\tif (component)\n\t\t\t\tcomponent->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid TupleExpression::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tfor (auto const& component: m_components)\n\t\t\tif (component)\n\t\t\t\tcomponent->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid UnaryOperation::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tm_subExpression->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid UnaryOperation::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tm_subExpression->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid BinaryOperation::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_left->accept(_visitor);\n\t\tm_right->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid BinaryOperation::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_left->accept(_visitor);\n\t\tm_right->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid FunctionCall::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_expression->accept(_visitor);\n\t\tlistAccept(m_arguments, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid FunctionCall::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_expression->accept(_visitor);\n\t\tlistAccept(m_arguments, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid FunctionCallOptions::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_expression->accept(_visitor);\n\t\tlistAccept(m_options, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid FunctionCallOptions::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_expression->accept(_visitor);\n\t\tlistAccept(m_options, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid NewExpression::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tm_typeName->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid NewExpression::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tm_typeName->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid MemberAccess::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tm_expression->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid MemberAccess::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tm_expression->accept(_visitor);\n\t_visitor.endVisit(*this);\n}\n\nvoid IndexAccess::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_base->accept(_visitor);\n\t\tif (m_index)\n\t\t\tm_index->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid IndexAccess::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_base->accept(_visitor);\n\t\tif (m_index)\n\t\t\tm_index->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid IndexRangeAccess::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_base->accept(_visitor);\n\t\tif (m_start)\n\t\t\tm_start->accept(_visitor);\n\t\tif (m_end)\n\t\t\tm_end->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid IndexRangeAccess::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_base->accept(_visitor);\n\t\tif (m_start)\n\t\t\tm_start->accept(_visitor);\n\t\tif (m_end)\n\t\t\tm_end->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid Identifier::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid Identifier::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid ElementaryTypeNameExpression::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid ElementaryTypeNameExpression::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid Literal::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid Literal::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\n/// Experimental Solidity nodes\n/// @{\nvoid TypeClassDefinition::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_typeVariable->accept(_visitor);\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tlistAccept(m_subNodes, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid TypeClassDefinition::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_typeVariable->accept(_visitor);\n\t\tif (m_documentation)\n\t\t\tm_documentation->accept(_visitor);\n\t\tlistAccept(m_subNodes, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid TypeClassInstantiation::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_typeConstructor->accept(_visitor);\n\t\tif (m_argumentSorts)\n\t\t\tm_argumentSorts->accept(_visitor);\n\t\tm_class->accept(_visitor);\n\t\tlistAccept(m_subNodes, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid TypeClassInstantiation::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_typeConstructor->accept(_visitor);\n\t\tif (m_argumentSorts)\n\t\t\tm_argumentSorts->accept(_visitor);\n\t\tm_class->accept(_visitor);\n\t\tlistAccept(m_subNodes, _visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid TypeDefinition::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_arguments)\n\t\t\tm_arguments->accept(_visitor);\n\t\tif (m_typeExpression)\n\t\t\tm_typeExpression->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid TypeDefinition::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (m_arguments)\n\t\t\tm_arguments->accept(_visitor);\n\t\tif (m_typeExpression)\n\t\t\tm_typeExpression->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\n\nvoid TypeClassName::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (auto* path = std::get_if<ASTPointer<IdentifierPath>>(&m_name))\n\t\t\t(*path)->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid TypeClassName::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tif (auto* path = std::get_if<ASTPointer<IdentifierPath>>(&m_name))\n\t\t\t(*path)->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid Builtin::accept(ASTVisitor& _visitor)\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid Builtin::accept(ASTConstVisitor& _visitor) const\n{\n\t_visitor.visit(*this);\n\t_visitor.endVisit(*this);\n}\n\nvoid ForAllQuantifier::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_typeVariableDeclarations->accept(_visitor);\n\t\tm_quantifiedDeclaration->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid ForAllQuantifier::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t{\n\t\tm_typeVariableDeclarations->accept(_visitor);\n\t\tm_quantifiedDeclaration->accept(_visitor);\n\t}\n\t_visitor.endVisit(*this);\n}\n\nvoid StorageLayoutSpecifier::accept(ASTVisitor& _visitor)\n{\n\tif (_visitor.visit(*this))\n\t\tm_baseSlotExpression->accept(_visitor);\n\n\t_visitor.endVisit(*this);\n}\n\nvoid StorageLayoutSpecifier::accept(ASTConstVisitor& _visitor) const\n{\n\tif (_visitor.visit(*this))\n\t\tm_baseSlotExpression->accept(_visitor);\n\n\t_visitor.endVisit(*this);\n}\n/// @}\n\n}\n"
  },
  {
    "path": "libsolidity/ast/CallGraph.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/ast/CallGraph.h>\n\nusing namespace solidity::frontend;\n\nbool CallGraph::CompareByID::operator()(Node const& _lhs, Node const& _rhs) const\n{\n\tif (_lhs.index() != _rhs.index())\n\t\treturn _lhs.index() < _rhs.index();\n\n\tif (std::holds_alternative<SpecialNode>(_lhs))\n\t\treturn std::get<SpecialNode>(_lhs) < std::get<SpecialNode>(_rhs);\n\treturn std::get<CallableDeclaration const*>(_lhs)->id() < std::get<CallableDeclaration const*>(_rhs)->id();\n}\n\nbool CallGraph::CompareByID::operator()(Node const& _lhs, int64_t _rhs) const\n{\n\tsolAssert(!std::holds_alternative<SpecialNode>(_lhs), \"\");\n\n\treturn std::get<CallableDeclaration const*>(_lhs)->id() < _rhs;\n}\n\nbool CallGraph::CompareByID::operator()(int64_t _lhs, Node const& _rhs) const\n{\n\tsolAssert(!std::holds_alternative<SpecialNode>(_rhs), \"\");\n\n\treturn _lhs < std::get<CallableDeclaration const*>(_rhs)->id();\n}\n"
  },
  {
    "path": "libsolidity/ast/CallGraph.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n/// Data structure representing a function call graph.\n\n#pragma once\n\n#include <libsolidity/ast/AST.h>\n\n#include <map>\n#include <set>\n#include <variant>\n\nnamespace solidity::frontend\n{\n\n/**\n * Function call graph for a contract at the granularity of Solidity functions and modifiers.\n * The graph can represent the situation either at contract creation or after deployment.\n * The graph does not preserve temporal relations between calls - edges coming out of the same node\n * show which calls were performed but not in what order.\n *\n * Stores also extra information about contracts that can be created and events that can be emitted\n * from any of the functions in it.\n */\nstruct CallGraph\n{\n\tenum class SpecialNode\n\t{\n\t\tInternalDispatch,\n\t\tEntry,\n\t};\n\n\tusing Node = std::variant<CallableDeclaration const*, SpecialNode>;\n\n\tstruct CompareByID\n\t{\n\t\tusing is_transparent = void;\n\t\tbool operator()(Node const& _lhs, Node const& _rhs) const;\n\t\tbool operator()(Node const& _lhs, int64_t _rhs) const;\n\t\tbool operator()(int64_t _lhs, Node const& _rhs) const;\n\t};\n\n\t/// Graph edges. Edges are directed and lead from the caller to the callee.\n\t/// The map contains a key for every possible caller, even if does not actually perform\n\t/// any calls.\n\tstd::map<Node, std::set<Node, CompareByID>, CompareByID> edges;\n\n\t/// Contracts that need to be compiled before this one can be compiled.\n\t/// The value is the ast node that created the dependency.\n\tstd::map<ContractDefinition const*, ASTNode const*, ASTCompareByID<ContractDefinition>> bytecodeDependency;\n\n\t/// Events that may get emitted by functions present in the graph.\n\tstd::set<EventDefinition const*, ASTNode::CompareByID> emittedEvents;\n\n\t/// Errors that are used by functions present in the graph.\n\tstd::set<ErrorDefinition const*, ASTNode::CompareByID> usedErrors;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/ast/ExperimentalFeatures.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * List of experimental features.\n */\n\n#pragma once\n\n#include <map>\n#include <set>\n\nnamespace solidity::frontend\n{\n\nenum class ExperimentalFeature\n{\n\tABIEncoderV2, // new ABI encoder that makes use of Yul\n\tSMTChecker,\n\tTest,\n\tTestOnlyAnalysis,\n\tSolidity\n};\n\nstatic std::set<ExperimentalFeature> const ExperimentalFeatureWithoutWarning =\n{\n\tExperimentalFeature::ABIEncoderV2,\n\tExperimentalFeature::SMTChecker,\n\tExperimentalFeature::TestOnlyAnalysis,\n};\n\nstatic std::map<std::string, ExperimentalFeature> const ExperimentalFeatureNames =\n{\n\t{ \"ABIEncoderV2\", ExperimentalFeature::ABIEncoderV2 },\n\t{ \"SMTChecker\", ExperimentalFeature::SMTChecker },\n\t{ \"__test\", ExperimentalFeature::Test },\n\t{ \"__testOnlyAnalysis\", ExperimentalFeature::TestOnlyAnalysis },\n\t{ \"solidity\", ExperimentalFeature::Solidity }\n};\n\n}\n"
  },
  {
    "path": "libsolidity/ast/TypeProvider.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <boost/algorithm/string.hpp>\n#include <boost/algorithm/string/split.hpp>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\nusing namespace solidity::util;\n\nBoolType const TypeProvider::m_boolean{};\nInaccessibleDynamicType const TypeProvider::m_inaccessibleDynamic{};\n\n/// The string and bytes unique_ptrs are initialized when they are first used because\n/// they rely on `byte` being available which we cannot guarantee in the static init context.\nstd::unique_ptr<ArrayType> TypeProvider::m_bytesStorage;\nstd::unique_ptr<ArrayType> TypeProvider::m_bytesMemory;\nstd::unique_ptr<ArrayType> TypeProvider::m_bytesCalldata;\nstd::unique_ptr<ArrayType> TypeProvider::m_stringStorage;\nstd::unique_ptr<ArrayType> TypeProvider::m_stringMemory;\n\nTupleType const TypeProvider::m_emptyTuple{};\nAddressType const TypeProvider::m_payableAddress{StateMutability::Payable};\nAddressType const TypeProvider::m_address{StateMutability::NonPayable};\n\nstd::array<std::unique_ptr<IntegerType>, 32> const TypeProvider::m_intM{{\n\t{std::make_unique<IntegerType>(8 * 1, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 2, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 3, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 4, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 5, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 6, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 7, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 8, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 9, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 10, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 11, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 12, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 13, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 14, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 15, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 16, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 17, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 18, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 19, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 20, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 21, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 22, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 23, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 24, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 25, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 26, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 27, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 28, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 29, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 30, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 31, IntegerType::Modifier::Signed)},\n\t{std::make_unique<IntegerType>(8 * 32, IntegerType::Modifier::Signed)}\n}};\n\nstd::array<std::unique_ptr<IntegerType>, 32> const TypeProvider::m_uintM{{\n\t{std::make_unique<IntegerType>(8 * 1, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 2, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 3, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 4, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 5, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 6, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 7, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 8, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 9, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 10, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 11, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 12, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 13, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 14, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 15, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 16, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 17, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 18, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 19, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 20, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 21, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 22, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 23, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 24, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 25, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 26, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 27, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 28, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 29, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 30, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 31, IntegerType::Modifier::Unsigned)},\n\t{std::make_unique<IntegerType>(8 * 32, IntegerType::Modifier::Unsigned)}\n}};\n\nstd::array<std::unique_ptr<FixedBytesType>, 32> const TypeProvider::m_bytesM{{\n\t{std::make_unique<FixedBytesType>(1)},\n\t{std::make_unique<FixedBytesType>(2)},\n\t{std::make_unique<FixedBytesType>(3)},\n\t{std::make_unique<FixedBytesType>(4)},\n\t{std::make_unique<FixedBytesType>(5)},\n\t{std::make_unique<FixedBytesType>(6)},\n\t{std::make_unique<FixedBytesType>(7)},\n\t{std::make_unique<FixedBytesType>(8)},\n\t{std::make_unique<FixedBytesType>(9)},\n\t{std::make_unique<FixedBytesType>(10)},\n\t{std::make_unique<FixedBytesType>(11)},\n\t{std::make_unique<FixedBytesType>(12)},\n\t{std::make_unique<FixedBytesType>(13)},\n\t{std::make_unique<FixedBytesType>(14)},\n\t{std::make_unique<FixedBytesType>(15)},\n\t{std::make_unique<FixedBytesType>(16)},\n\t{std::make_unique<FixedBytesType>(17)},\n\t{std::make_unique<FixedBytesType>(18)},\n\t{std::make_unique<FixedBytesType>(19)},\n\t{std::make_unique<FixedBytesType>(20)},\n\t{std::make_unique<FixedBytesType>(21)},\n\t{std::make_unique<FixedBytesType>(22)},\n\t{std::make_unique<FixedBytesType>(23)},\n\t{std::make_unique<FixedBytesType>(24)},\n\t{std::make_unique<FixedBytesType>(25)},\n\t{std::make_unique<FixedBytesType>(26)},\n\t{std::make_unique<FixedBytesType>(27)},\n\t{std::make_unique<FixedBytesType>(28)},\n\t{std::make_unique<FixedBytesType>(29)},\n\t{std::make_unique<FixedBytesType>(30)},\n\t{std::make_unique<FixedBytesType>(31)},\n\t{std::make_unique<FixedBytesType>(32)}\n}};\n\nstd::array<std::unique_ptr<MagicType>, 5> const TypeProvider::m_magics{{\n\t{std::make_unique<MagicType>(MagicType::Kind::Block)},\n\t{std::make_unique<MagicType>(MagicType::Kind::Message)},\n\t{std::make_unique<MagicType>(MagicType::Kind::Transaction)},\n\t{std::make_unique<MagicType>(MagicType::Kind::ABI)},\n\t{std::make_unique<MagicType>(MagicType::Kind::Error)}\n\t// MetaType is stored separately\n}};\n\ninline void clearCache(Type const& type)\n{\n\ttype.clearCache();\n}\n\ntemplate <typename T>\ninline void clearCache(std::unique_ptr<T> const& type)\n{\n\t// Some lazy-initialized types might not exist yet.\n\tif (type)\n\t\ttype->clearCache();\n}\n\ntemplate <typename Container>\ninline void clearCaches(Container& container)\n{\n\tfor (auto const& e: container)\n\t\tclearCache(e);\n}\n\nvoid TypeProvider::reset()\n{\n\tclearCache(m_boolean);\n\tclearCache(m_inaccessibleDynamic);\n\tclearCache(m_bytesStorage);\n\tclearCache(m_bytesMemory);\n\tclearCache(m_bytesCalldata);\n\tclearCache(m_stringStorage);\n\tclearCache(m_stringMemory);\n\tclearCache(m_emptyTuple);\n\tclearCache(m_payableAddress);\n\tclearCache(m_address);\n\tclearCaches(instance().m_intM);\n\tclearCaches(instance().m_uintM);\n\tclearCaches(instance().m_bytesM);\n\tclearCaches(instance().m_magics);\n\n\tinstance().m_generalTypes.clear();\n\tinstance().m_stringLiteralTypes.clear();\n\tinstance().m_ufixedMxN.clear();\n\tinstance().m_fixedMxN.clear();\n}\n\ntemplate <typename T, typename... Args>\ninline T const* TypeProvider::createAndGet(Args&& ... _args)\n{\n\tinstance().m_generalTypes.emplace_back(std::make_unique<T>(std::forward<Args>(_args)...));\n\treturn static_cast<T const*>(instance().m_generalTypes.back().get());\n}\n\nType const* TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken const& _type, std::optional<StateMutability> _stateMutability)\n{\n\tsolAssert(\n\t\tTokenTraits::isElementaryTypeName(_type.token()),\n\t\t\"Expected an elementary type name but got \" + _type.toString()\n\t);\n\n\tunsigned const m = _type.firstNumber();\n\tunsigned const n = _type.secondNumber();\n\n\tswitch (_type.token())\n\t{\n\tcase Token::IntM:\n\t\treturn integer(m, IntegerType::Modifier::Signed);\n\tcase Token::UIntM:\n\t\treturn integer(m, IntegerType::Modifier::Unsigned);\n\tcase Token::Byte:\n\t\treturn byte();\n\tcase Token::BytesM:\n\t\treturn fixedBytes(m);\n\tcase Token::FixedMxN:\n\t\treturn fixedPoint(m, n, FixedPointType::Modifier::Signed);\n\tcase Token::UFixedMxN:\n\t\treturn fixedPoint(m, n, FixedPointType::Modifier::Unsigned);\n\tcase Token::Int:\n\t\treturn integer(256, IntegerType::Modifier::Signed);\n\tcase Token::UInt:\n\t\treturn integer(256, IntegerType::Modifier::Unsigned);\n\tcase Token::Fixed:\n\t\treturn fixedPoint(128, 18, FixedPointType::Modifier::Signed);\n\tcase Token::UFixed:\n\t\treturn fixedPoint(128, 18, FixedPointType::Modifier::Unsigned);\n\tcase Token::Address:\n\t{\n\t\tif (_stateMutability)\n\t\t{\n\t\t\tsolAssert(*_stateMutability == StateMutability::Payable, \"\");\n\t\t\treturn payableAddress();\n\t\t}\n\t\treturn address();\n\t}\n\tcase Token::Bool:\n\t\treturn boolean();\n\tcase Token::Bytes:\n\t\treturn bytesStorage();\n\tcase Token::String:\n\t\treturn stringStorage();\n\tdefault:\n\t\tsolAssert(\n\t\t\tfalse,\n\t\t\t\"Unable to convert elementary typename \" + _type.toString() + \" to type.\"\n\t\t);\n\t}\n}\n\nType const* TypeProvider::fromElementaryTypeName(std::string const& _name)\n{\n\tstd::vector<std::string> nameParts;\n\tboost::split(nameParts, _name, boost::is_any_of(\" \"));\n\tsolAssert(nameParts.size() == 1 || nameParts.size() == 2, \"Cannot parse elementary type: \" + _name);\n\n\tToken token;\n\tunsigned short firstNum, secondNum;\n\tstd::tie(token, firstNum, secondNum) = TokenTraits::fromIdentifierOrKeyword(nameParts[0]);\n\n\tauto t = fromElementaryTypeName(ElementaryTypeNameToken(token, firstNum, secondNum));\n\tif (auto* ref = dynamic_cast<ReferenceType const*>(t))\n\t{\n\t\tDataLocation location = DataLocation::Storage;\n\t\tif (nameParts.size() == 2)\n\t\t{\n\t\t\tif (nameParts[1] == \"storage\")\n\t\t\t\tlocation = DataLocation::Storage;\n\t\t\telse if (nameParts[1] == \"calldata\")\n\t\t\t\tlocation = DataLocation::CallData;\n\t\t\telse if (nameParts[1] == \"memory\")\n\t\t\t\tlocation = DataLocation::Memory;\n\t\t\telse\n\t\t\t\tsolAssert(false, \"Unknown data location: \" + nameParts[1]);\n\t\t}\n\t\treturn withLocation(ref, location, true);\n\t}\n\telse if (t->category() == Type::Category::Address)\n\t{\n\t\tif (nameParts.size() == 2)\n\t\t{\n\t\t\tif (nameParts[1] == \"payable\")\n\t\t\t\treturn payableAddress();\n\t\t\telse\n\t\t\t\tsolAssert(false, \"Invalid state mutability for address type: \" + nameParts[1]);\n\t\t}\n\t\treturn address();\n\t}\n\telse\n\t{\n\t\tsolAssert(nameParts.size() == 1, \"Storage location suffix only allowed for reference types\");\n\t\treturn t;\n\t}\n}\n\nArrayType const* TypeProvider::bytesStorage()\n{\n\tif (!m_bytesStorage)\n\t\tm_bytesStorage = std::make_unique<ArrayType>(DataLocation::Storage, false);\n\treturn m_bytesStorage.get();\n}\n\nArrayType const* TypeProvider::bytesMemory()\n{\n\tif (!m_bytesMemory)\n\t\tm_bytesMemory = std::make_unique<ArrayType>(DataLocation::Memory, false);\n\treturn m_bytesMemory.get();\n}\n\nArrayType const* TypeProvider::bytesCalldata()\n{\n\tif (!m_bytesCalldata)\n\t\tm_bytesCalldata = std::make_unique<ArrayType>(DataLocation::CallData, false);\n\treturn m_bytesCalldata.get();\n}\n\nArrayType const* TypeProvider::stringStorage()\n{\n\tif (!m_stringStorage)\n\t\tm_stringStorage = std::make_unique<ArrayType>(DataLocation::Storage, true);\n\treturn m_stringStorage.get();\n}\n\nArrayType const* TypeProvider::stringMemory()\n{\n\tif (!m_stringMemory)\n\t\tm_stringMemory = std::make_unique<ArrayType>(DataLocation::Memory, true);\n\treturn m_stringMemory.get();\n}\n\nType const* TypeProvider::forLiteral(Literal const& _literal)\n{\n\tswitch (_literal.token())\n\t{\n\tcase Token::TrueLiteral:\n\tcase Token::FalseLiteral:\n\t\treturn boolean();\n\tcase Token::Number:\n\t\treturn rationalNumber(_literal);\n\tcase Token::StringLiteral:\n\tcase Token::UnicodeStringLiteral:\n\tcase Token::HexStringLiteral:\n\t\treturn stringLiteral(_literal.value());\n\tdefault:\n\t\treturn nullptr;\n\t}\n}\n\nRationalNumberType const* TypeProvider::rationalNumber(Literal const& _literal)\n{\n\tsolAssert(_literal.token() == Token::Number, \"\");\n\tstd::tuple<bool, rational> validLiteral = RationalNumberType::isValidLiteral(_literal);\n\tif (std::get<0>(validLiteral))\n\t{\n\t\tType const* compatibleBytesType = nullptr;\n\t\tif (_literal.isHexNumber())\n\t\t{\n\t\t\tsize_t const digitCount = _literal.valueWithoutUnderscores().length() - 2;\n\t\t\tif (digitCount % 2 == 0 && (digitCount / 2) <= 32)\n\t\t\t\tcompatibleBytesType = fixedBytes(static_cast<unsigned>(digitCount / 2));\n\t\t}\n\n\t\treturn rationalNumber(std::get<1>(validLiteral), compatibleBytesType);\n\t}\n\treturn nullptr;\n}\n\nStringLiteralType const* TypeProvider::stringLiteral(std::string const& literal)\n{\n\tauto i = instance().m_stringLiteralTypes.find(literal);\n\tif (i != instance().m_stringLiteralTypes.end())\n\t\treturn i->second.get();\n\telse\n\t\treturn instance().m_stringLiteralTypes.emplace(literal, std::make_unique<StringLiteralType>(literal)).first->second.get();\n}\n\nFixedPointType const* TypeProvider::fixedPoint(unsigned m, unsigned n, FixedPointType::Modifier _modifier)\n{\n\tauto& map = _modifier == FixedPointType::Modifier::Unsigned ? instance().m_ufixedMxN : instance().m_fixedMxN;\n\n\tauto i = map.find(std::make_pair(m, n));\n\tif (i != map.end())\n\t\treturn i->second.get();\n\n\treturn map.emplace(\n\t\tstd::make_pair(m, n),\n\t\tstd::make_unique<FixedPointType>(m, n, _modifier)\n\t).first->second.get();\n}\n\nTupleType const* TypeProvider::tuple(std::vector<Type const*> members)\n{\n\tif (members.empty())\n\t\treturn &m_emptyTuple;\n\n\treturn createAndGet<TupleType>(std::move(members));\n}\n\nReferenceType const* TypeProvider::withLocation(ReferenceType const* _type, DataLocation _location, bool _isPointer)\n{\n\tif (_type->location() == _location && _type->isPointer() == _isPointer)\n\t\treturn _type;\n\n\tinstance().m_generalTypes.emplace_back(_type->copyForLocation(_location, _isPointer));\n\treturn static_cast<ReferenceType const*>(instance().m_generalTypes.back().get());\n}\n\nFunctionType const* TypeProvider::function(FunctionDefinition const& _function, FunctionType::Kind _kind)\n{\n\treturn createAndGet<FunctionType>(_function, _kind);\n}\n\nFunctionType const* TypeProvider::function(VariableDeclaration const& _varDecl)\n{\n\treturn createAndGet<FunctionType>(_varDecl);\n}\n\nFunctionType const* TypeProvider::function(EventDefinition const& _def)\n{\n\treturn createAndGet<FunctionType>(_def);\n}\n\nFunctionType const* TypeProvider::function(ErrorDefinition const& _def)\n{\n\treturn createAndGet<FunctionType>(_def);\n}\n\nFunctionType const* TypeProvider::function(FunctionTypeName const& _typeName)\n{\n\treturn createAndGet<FunctionType>(_typeName);\n}\n\nFunctionType const* TypeProvider::function(\n\tstrings const& _parameterTypes,\n\tstrings const& _returnParameterTypes,\n\tFunctionType::Kind _kind,\n\tStateMutability _stateMutability,\n\tFunctionType::Options _options\n)\n{\n\t// Can only use this constructor for \"arbitraryParameters\".\n\tsolAssert(!_options.valueSet && !_options.gasSet && !_options.saltSet && !_options.hasBoundFirstArgument);\n\treturn createAndGet<FunctionType>(\n\t\t_parameterTypes,\n\t\t_returnParameterTypes,\n\t\t_kind,\n\t\t_stateMutability,\n\t\tstd::move(_options)\n\t);\n}\n\nFunctionType const* TypeProvider::function(\n\tTypePointers const& _parameterTypes,\n\tTypePointers const& _returnParameterTypes,\n\tstrings _parameterNames,\n\tstrings _returnParameterNames,\n\tFunctionType::Kind _kind,\n\tStateMutability _stateMutability,\n\tDeclaration const* _declaration,\n\tFunctionType::Options _options\n)\n{\n\treturn createAndGet<FunctionType>(\n\t\t_parameterTypes,\n\t\t_returnParameterTypes,\n\t\t_parameterNames,\n\t\t_returnParameterNames,\n\t\t_kind,\n\t\t_stateMutability,\n\t\t_declaration,\n\t\tstd::move(_options)\n\t);\n}\n\nRationalNumberType const* TypeProvider::rationalNumber(rational const& _value, Type const* _compatibleBytesType)\n{\n\treturn createAndGet<RationalNumberType>(_value, _compatibleBytesType);\n}\n\nArrayType const* TypeProvider::array(DataLocation _location, bool _isString)\n{\n\tif (_isString)\n\t{\n\t\tif (_location == DataLocation::Storage)\n\t\t\treturn stringStorage();\n\t\tif (_location == DataLocation::Memory)\n\t\t\treturn stringMemory();\n\t}\n\telse\n\t{\n\t\tif (_location == DataLocation::Storage)\n\t\t\treturn bytesStorage();\n\t\tif (_location == DataLocation::Memory)\n\t\t\treturn bytesMemory();\n\t}\n\treturn createAndGet<ArrayType>(_location, _isString);\n}\n\nArrayType const* TypeProvider::array(DataLocation _location, Type const* _baseType)\n{\n\treturn createAndGet<ArrayType>(_location, _baseType);\n}\n\nArrayType const* TypeProvider::array(DataLocation _location, Type const* _baseType, u256 const& _length)\n{\n\treturn createAndGet<ArrayType>(_location, _baseType, _length);\n}\n\nArraySliceType const* TypeProvider::arraySlice(ArrayType const& _arrayType)\n{\n\treturn createAndGet<ArraySliceType>(_arrayType);\n}\n\nContractType const* TypeProvider::contract(ContractDefinition const& _contractDef, bool _isSuper)\n{\n\treturn createAndGet<ContractType>(_contractDef, _isSuper);\n}\n\nEnumType const* TypeProvider::enumType(EnumDefinition const& _enumDef)\n{\n\treturn createAndGet<EnumType>(_enumDef);\n}\n\nModuleType const* TypeProvider::module(SourceUnit const& _source)\n{\n\treturn createAndGet<ModuleType>(_source);\n}\n\nTypeType const* TypeProvider::typeType(Type const* _actualType)\n{\n\treturn createAndGet<TypeType>(_actualType);\n}\n\nStructType const* TypeProvider::structType(StructDefinition const& _struct, DataLocation _location)\n{\n\treturn createAndGet<StructType>(_struct, _location);\n}\n\nModifierType const* TypeProvider::modifier(ModifierDefinition const& _def)\n{\n\treturn createAndGet<ModifierType>(_def);\n}\n\nMagicType const* TypeProvider::magic(MagicType::Kind _kind)\n{\n\tsolAssert(_kind != MagicType::Kind::MetaType, \"MetaType is handled separately\");\n\treturn m_magics.at(static_cast<size_t>(_kind)).get();\n}\n\nMagicType const* TypeProvider::meta(Type const* _type)\n{\n\tsolAssert(\n\t\t_type && (\n\t\t\t_type->category() == Type::Category::Contract ||\n\t\t\t_type->category() == Type::Category::Integer ||\n\t\t\t_type->category() == Type::Category::Enum\n\t\t),\n\t\t\"Only enum, contracts or integer types supported for now.\"\n\t);\n\treturn createAndGet<MagicType>(_type);\n}\n\nMappingType const* TypeProvider::mapping(Type const* _keyType, ASTString _keyName, Type const* _valueType, ASTString _valueName)\n{\n\treturn createAndGet<MappingType>(_keyType, _keyName, _valueType, _valueName);\n}\n\nUserDefinedValueType const* TypeProvider::userDefinedValueType(UserDefinedValueTypeDefinition const& _definition)\n{\n\treturn createAndGet<UserDefinedValueType>(_definition);\n}\n"
  },
  {
    "path": "libsolidity/ast/TypeProvider.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/Types.h>\n\n#include <array>\n#include <map>\n#include <memory>\n#include <optional>\n#include <utility>\n\nnamespace solidity::frontend\n{\n\n/**\n * API for accessing the Solidity Type System.\n *\n * This is the Solidity Compiler's type provider. Use it to request for types. The caller does\n * <b>not</b> own the types.\n *\n * It is not recommended to explicitly instantiate types unless you really know what and why\n * you are doing it.\n */\nclass TypeProvider\n{\npublic:\n\tTypeProvider() = default;\n\tTypeProvider(TypeProvider&&) = default;\n\tTypeProvider(TypeProvider const&) = delete;\n\tTypeProvider& operator=(TypeProvider&&) = default;\n\tTypeProvider& operator=(TypeProvider const&) = delete;\n\t~TypeProvider() = default;\n\n\t/// Resets state of this TypeProvider to initial state, wiping all mutable types.\n\t/// This invalidates all dangling pointers to types provided by this TypeProvider.\n\tstatic void reset();\n\n\t/// @name Factory functions\n\t/// Factory functions that convert an AST @ref TypeName to a Type.\n\tstatic Type const* fromElementaryTypeName(ElementaryTypeNameToken const& _type, std::optional<StateMutability> _stateMutability = {});\n\n\t/// Converts a given elementary type name with optional data location\n\t/// suffix \" storage\", \" calldata\" or \" memory\" to a type pointer. If suffix not given, defaults to \" storage\".\n\tstatic Type const* fromElementaryTypeName(std::string const& _name);\n\n\t/// @returns boolean type.\n\tstatic BoolType const* boolean() noexcept { return &m_boolean; }\n\n\tstatic FixedBytesType const* byte() { return fixedBytes(1); }\n\tstatic FixedBytesType const* fixedBytes(unsigned m) { return m_bytesM.at(m - 1).get(); }\n\n\tstatic ArrayType const* bytesStorage();\n\tstatic ArrayType const* bytesMemory();\n\tstatic ArrayType const* bytesCalldata();\n\tstatic ArrayType const* stringStorage();\n\tstatic ArrayType const* stringMemory();\n\n\t/// Constructor for a byte array (\"bytes\") and string.\n\tstatic ArrayType const* array(DataLocation _location, bool _isString = false);\n\n\t/// Constructor for a dynamically sized array type (\"type[]\")\n\tstatic ArrayType const* array(DataLocation _location, Type const* _baseType);\n\n\t/// Constructor for a fixed-size array type (\"type[20]\")\n\tstatic ArrayType const* array(DataLocation _location, Type const* _baseType, u256 const& _length);\n\n\tstatic ArraySliceType const* arraySlice(ArrayType const& _arrayType);\n\n\tstatic AddressType const* payableAddress() noexcept { return &m_payableAddress; }\n\tstatic AddressType const* address() noexcept { return &m_address; }\n\n\tstatic IntegerType const* integer(unsigned _bits, IntegerType::Modifier _modifier)\n\t{\n\t\tsolAssert((_bits % 8) == 0, \"\");\n\t\tif (_modifier == IntegerType::Modifier::Unsigned)\n\t\t\treturn m_uintM.at(_bits / 8 - 1).get();\n\t\telse\n\t\t\treturn m_intM.at(_bits / 8 - 1).get();\n\t}\n\tstatic IntegerType const* uint(unsigned _bits) { return integer(_bits, IntegerType::Modifier::Unsigned); }\n\n\tstatic IntegerType const* uint256() { return uint(256); }\n\tstatic IntegerType const* int256() { return integer(256, IntegerType::Modifier::Signed); }\n\n\tstatic FixedPointType const* fixedPoint(unsigned m, unsigned n, FixedPointType::Modifier _modifier);\n\n\tstatic StringLiteralType const* stringLiteral(std::string const& literal);\n\n\t/// @param members the member types the tuple type must contain. This is passed by value on purspose.\n\t/// @returns a tuple type with the given members.\n\tstatic TupleType const* tuple(std::vector<Type const*> members);\n\n\tstatic TupleType const* emptyTuple() noexcept { return &m_emptyTuple; }\n\n\tstatic ReferenceType const* withLocation(ReferenceType const* _type, DataLocation _location, bool _isPointer);\n\n\t/// @returns a copy of @a _type having the same location as this (and is not a pointer type)\n\t///          if _type is a reference type and an unmodified copy of _type otherwise.\n\t///          This function is mostly useful to modify inner types appropriately.\n\tstatic Type const* withLocationIfReference(DataLocation _location, Type const* _type, bool _isPointer = false)\n\t{\n\t\tif (auto refType = dynamic_cast<ReferenceType const*>(_type))\n\t\t\treturn withLocation(refType, _location, _isPointer);\n\n\t\treturn _type;\n\t}\n\n\tstatic bool isReferenceWithLocation(Type const* _type, DataLocation _location)\n\t{\n\t\tif (auto const* refType = dynamic_cast<ReferenceType const*>(_type))\n\t\t\tif (refType->location() == _location)\n\t\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\t/// @returns the internally-facing or externally-facing type of a function or the type of a function declaration.\n\tstatic FunctionType const* function(FunctionDefinition const& _function, FunctionType::Kind _kind = FunctionType::Kind::Declaration);\n\n\t/// @returns the accessor function type of a state variable.\n\tstatic FunctionType const* function(VariableDeclaration const& _varDecl);\n\n\t/// @returns the function type of an event.\n\tstatic FunctionType const* function(EventDefinition const& _event);\n\n\tstatic FunctionType const* function(ErrorDefinition const& _error);\n\n\t/// @returns the type of a function type name.\n\tstatic FunctionType const* function(FunctionTypeName const& _typeName);\n\n\t/// @returns the function type to be used for a plain type (not derived from a declaration).\n\tstatic FunctionType const* function(\n\t\tstrings const& _parameterTypes,\n\t\tstrings const& _returnParameterTypes,\n\t\tFunctionType::Kind _kind = FunctionType::Kind::Internal,\n\t\tStateMutability _stateMutability = StateMutability::NonPayable,\n\t\tFunctionType::Options _options = {}\n\t);\n\n\t/// @returns a highly customized FunctionType, use with care.\n\tstatic FunctionType const* function(\n\t\tTypePointers const& _parameterTypes,\n\t\tTypePointers const& _returnParameterTypes,\n\t\tstrings _parameterNames = strings{},\n\t\tstrings _returnParameterNames = strings{},\n\t\tFunctionType::Kind _kind = FunctionType::Kind::Internal,\n\t\tStateMutability _stateMutability = StateMutability::NonPayable,\n\t\tDeclaration const* _declaration = nullptr,\n\t\tFunctionType::Options _options = {}\n\t);\n\n\t/// Auto-detect the proper type for a literal. @returns an empty pointer if the literal does\n\t/// not fit any type.\n\tstatic Type const* forLiteral(Literal const& _literal);\n\tstatic RationalNumberType const* rationalNumber(Literal const& _literal);\n\n\tstatic RationalNumberType const* rationalNumber(\n\t\trational const& _value,\n\t\tType const* _compatibleBytesType = nullptr\n\t);\n\n\tstatic ContractType const* contract(ContractDefinition const& _contract, bool _isSuper = false);\n\n\tstatic InaccessibleDynamicType const* inaccessibleDynamic() noexcept { return &m_inaccessibleDynamic; }\n\n\t/// @returns the type of an enum instance for given definition, there is one distinct type per enum definition.\n\tstatic EnumType const* enumType(EnumDefinition const& _enum);\n\n\t/// @returns special type for imported modules. These mainly give access to their scope via members.\n\tstatic ModuleType const* module(SourceUnit const& _source);\n\n\tstatic TypeType const* typeType(Type const* _actualType);\n\n\tstatic StructType const* structType(StructDefinition const& _struct, DataLocation _location);\n\n\tstatic ModifierType const* modifier(ModifierDefinition const& _modifierDef);\n\n\tstatic MagicType const* magic(MagicType::Kind _kind);\n\n\tstatic MagicType const* meta(Type const* _type);\n\n\tstatic MappingType const* mapping(Type const* _keyType, ASTString _keyName, Type const* _valueType, ASTString _valueName);\n\n\tstatic UserDefinedValueType const* userDefinedValueType(UserDefinedValueTypeDefinition const& _definition);\n\nprivate:\n\t/// Global TypeProvider instance.\n\tstatic TypeProvider& instance()\n\t{\n\t\tstatic TypeProvider _provider;\n\t\treturn _provider;\n\t}\n\n\ttemplate <typename T, typename... Args>\n\tstatic inline T const* createAndGet(Args&& ... _args);\n\n\tstatic BoolType const m_boolean;\n\tstatic InaccessibleDynamicType const m_inaccessibleDynamic;\n\n\t/// These are lazy-initialized because they depend on `byte` being available.\n\tstatic std::unique_ptr<ArrayType> m_bytesStorage;\n\tstatic std::unique_ptr<ArrayType> m_bytesMemory;\n\tstatic std::unique_ptr<ArrayType> m_bytesCalldata;\n\tstatic std::unique_ptr<ArrayType> m_stringStorage;\n\tstatic std::unique_ptr<ArrayType> m_stringMemory;\n\n\tstatic TupleType const m_emptyTuple;\n\tstatic AddressType const m_payableAddress;\n\tstatic AddressType const m_address;\n\tstatic std::array<std::unique_ptr<IntegerType>, 32> const m_intM;\n\tstatic std::array<std::unique_ptr<IntegerType>, 32> const m_uintM;\n\tstatic std::array<std::unique_ptr<FixedBytesType>, 32> const m_bytesM;\n\tstatic std::array<std::unique_ptr<MagicType>, 5> const m_magics;        ///< MagicType's except MetaType\n\n\tstd::map<std::pair<unsigned, unsigned>, std::unique_ptr<FixedPointType>> m_ufixedMxN{};\n\tstd::map<std::pair<unsigned, unsigned>, std::unique_ptr<FixedPointType>> m_fixedMxN{};\n\tstd::map<std::string, std::unique_ptr<StringLiteralType>> m_stringLiteralTypes{};\n\tstd::vector<std::unique_ptr<Type>> m_generalTypes{};\n};\n\n}\n"
  },
  {
    "path": "libsolidity/ast/Types.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity data types\n */\n\n#include <libsolidity/ast/Types.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTUtils.h>\n#include <libsolidity/ast/TypeProvider.h>\n\n#include <libsolidity/analysis/ConstantEvaluator.h>\n\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/FunctionSelector.h>\n#include <libsolutil/Keccak256.h>\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/UTF8.h>\n#include <libsolutil/Visitor.h>\n\n#include <boost/algorithm/string.hpp>\n#include <boost/algorithm/string/classification.hpp>\n#include <boost/algorithm/string/join.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n#include <boost/algorithm/string/replace.hpp>\n#include <boost/algorithm/string/split.hpp>\n\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/reverse.hpp>\n#include <range/v3/view/tail.hpp>\n#include <range/v3/view/transform.hpp>\n#include <range/v3/view/filter.hpp>\n\n#include <limits>\n#include <unordered_set>\n#include <utility>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nnamespace\n{\n\n/// Checks whether _mantissa * (10 ** _expBase10) fits into 4096 bits.\nbool fitsPrecisionBase10(bigint const& _mantissa, uint32_t _expBase10)\n{\n\tdouble const log2Of10AwayFromZero = 3.3219280948873624;\n\treturn fitsPrecisionBaseX(_mantissa, log2Of10AwayFromZero, _expBase10);\n}\n\n/// Checks whether _value fits into IntegerType _type.\nBoolResult fitsIntegerType(bigint const& _value, IntegerType const& _type)\n{\n\tif (_value < 0 && !_type.isSigned())\n\t\treturn BoolResult::err(\"Cannot implicitly convert signed literal to unsigned type.\");\n\n\tif (_type.minValue() > _value || _value > _type.maxValue())\n\t\treturn BoolResult::err(\"Literal is too large to fit in \" + _type.toString(false) + \".\");\n\n\treturn true;\n}\n\n/// Checks whether _value fits into _bits bits when having 1 bit as the sign bit\n/// if _signed is true.\nbool fitsIntoBits(bigint const& _value, unsigned _bits, bool _signed)\n{\n\treturn fitsIntegerType(\n\t\t_value,\n\t\t*TypeProvider::integer(\n\t\t\t_bits,\n\t\t\t_signed ? IntegerType::Modifier::Signed : IntegerType::Modifier::Unsigned\n\t\t)\n\t);\n}\n\nutil::Result<TypePointers> transformParametersToExternal(TypePointers const& _parameters, bool _inLibrary)\n{\n\tTypePointers transformed;\n\n\tfor (auto const& type: _parameters)\n\t{\n\t\tif (!type)\n\t\t\treturn util::Result<TypePointers>::err(\"Type information not present.\");\n\t\telse if (Type const* ext = type->interfaceType(_inLibrary).get())\n\t\t\ttransformed.push_back(ext);\n\t\telse\n\t\t\treturn util::Result<TypePointers>::err(\"Parameter should have external type.\");\n\t}\n\n\treturn transformed;\n}\n\nstd::string toStringInParentheses(TypePointers const& _types, bool _withoutDataLocation)\n{\n\treturn '(' + util::joinHumanReadable(\n\t\t_types | ranges::views::transform([&](auto const* _type) { return _type->toString(_withoutDataLocation); }),\n\t\t\",\"\n\t) + ')';\n}\n\n}\n\nMemberList::Member::Member(Declaration const* _declaration, Type const* _type):\n\tMember(_declaration, _type, _declaration->name())\n{}\n\nMemberList::Member::Member(Declaration const* _declaration, Type const* _type, std::string _name):\n\tname(std::move(_name)),\n\ttype(_type),\n\tdeclaration(_declaration)\n{\n}\n\nvoid Type::clearCache() const\n{\n\tm_members.clear();\n\tm_stackItems.reset();\n\tm_stackSize.reset();\n}\n\nvoid StorageOffsets::computeOffsets(TypePointers const& _types, u256 _baseSlot)\n{\n\tbigint slotOffset = bigint(_baseSlot);\n\tunsigned byteOffset = 0;\n\tstd::map<size_t, std::pair<u256, unsigned>> offsets;\n\tfor (size_t i = 0; i < _types.size(); ++i)\n\t{\n\t\tType const* type = _types[i];\n\t\tsolAssert(type->canBeStored());\n\t\tsolAssert(type->storageBytes() <= 32);\n\t\tif (byteOffset + type->storageBytes() > 32)\n\t\t{\n\t\t\t// would overflow, go to next slot\n\t\t\t++slotOffset;\n\t\t\tbyteOffset = 0;\n\t\t}\n\t\tsolAssert(slotOffset < bigint(1) << 256, \"Object extends past the end of storage.\");\n\t\toffsets[i] = std::make_pair(u256(slotOffset), byteOffset);\n\t\tsolAssert(type->storageSize() >= 1, \"Invalid storage size.\");\n\t\tif (type->storageSize() == 1 && byteOffset + type->storageBytes() <= 32)\n\t\t\tbyteOffset += type->storageBytes();\n\t\telse\n\t\t{\n\t\t\tslotOffset += type->storageSize();\n\t\t\tbyteOffset = 0;\n\t\t}\n\t}\n\tif (byteOffset > 0)\n\t\t++slotOffset;\n\n\tsolAssert(slotOffset < bigint(1) << 256, \"Object extends past the end of storage.\");\n\tm_storageSize = u256(slotOffset - _baseSlot);\n\tswap(m_offsets, offsets);\n}\n\nstd::pair<u256, unsigned> const* StorageOffsets::offset(size_t _index) const\n{\n\tif (m_offsets.count(_index))\n\t\treturn &m_offsets.at(_index);\n\telse\n\t\treturn nullptr;\n}\n\nvoid MemberList::combine(MemberList const & _other)\n{\n\tm_memberTypes += _other.m_memberTypes;\n}\n\nstd::pair<u256, unsigned> const* MemberList::memberStorageOffset(std::string const& _name) const\n{\n\tStorageOffsets const& offsets = storageOffsets();\n\n\tfor (auto&& [index, member]: m_memberTypes | ranges::views::enumerate)\n\t\tif (member.name == _name)\n\t\t\treturn offsets.offset(index);\n\treturn nullptr;\n}\n\nu256 const& MemberList::storageSize() const\n{\n\treturn storageOffsets().storageSize();\n}\n\nStorageOffsets const& MemberList::storageOffsets() const {\n\treturn m_storageOffsets.init([&]{\n\t\tTypePointers memberTypes;\n\t\tmemberTypes.reserve(m_memberTypes.size());\n\t\tfor (auto const& member: m_memberTypes)\n\t\t\tmemberTypes.push_back(member.type);\n\n\t\tStorageOffsets storageOffsets;\n\t\tstorageOffsets.computeOffsets(memberTypes);\n\n\t\treturn storageOffsets;\n\t});\n}\n\n/// Helper functions for type identifier\nnamespace\n{\n\nstd::string parenthesizeIdentifier(std::string const& _internal)\n{\n\treturn \"(\" + _internal + \")\";\n}\n\ntemplate <class Range>\nstd::string identifierList(Range const&& _list)\n{\n\treturn parenthesizeIdentifier(boost::algorithm::join(_list, \",\"));\n}\n\nstd::string richIdentifier(Type const* _type)\n{\n\treturn _type ? _type->richIdentifier() : \"\";\n}\n\nstd::string identifierList(std::vector<Type const*> const& _list)\n{\n\treturn identifierList(_list | ranges::views::transform(richIdentifier));\n}\n\nstd::string identifierList(Type const* _type)\n{\n\treturn parenthesizeIdentifier(richIdentifier(_type));\n}\n\nstd::string identifierList(Type const* _type1, Type const* _type2)\n{\n\tTypePointers list;\n\tlist.push_back(_type1);\n\tlist.push_back(_type2);\n\treturn identifierList(list);\n}\n\nstd::string parenthesizeUserIdentifier(std::string const& _internal)\n{\n\treturn parenthesizeIdentifier(_internal);\n}\n\n}\n\nstd::string Type::escapeIdentifier(std::string const& _identifier)\n{\n\tstd::string ret = _identifier;\n\t// FIXME: should be _$$$_\n\tboost::algorithm::replace_all(ret, \"$\", \"$$$\");\n\tboost::algorithm::replace_all(ret, \",\", \"_$_\");\n\tboost::algorithm::replace_all(ret, \"(\", \"$_\");\n\tboost::algorithm::replace_all(ret, \")\", \"_$\");\n\treturn ret;\n}\n\nstd::string Type::identifier() const\n{\n\tstd::string ret = escapeIdentifier(richIdentifier());\n\tsolAssert(ret.find_first_of(\"0123456789\") != 0, \"Identifier cannot start with a number.\");\n\tsolAssert(\n\t\tret.find_first_not_of(\"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMONPQRSTUVWXYZ_$\") == std::string::npos,\n\t\t\"Identifier contains invalid characters.\"\n\t);\n\treturn ret;\n}\n\nType const* Type::commonType(Type const* _a, Type const* _b)\n{\n\tif (!_a || !_b)\n\t\treturn nullptr;\n\telse if (_a->mobileType() && _b->isImplicitlyConvertibleTo(*_a->mobileType()))\n\t\treturn _a->mobileType();\n\telse if (_b->mobileType() && _a->isImplicitlyConvertibleTo(*_b->mobileType()))\n\t\treturn _b->mobileType();\n\telse\n\t\treturn nullptr;\n}\n\nMemberList const& Type::members(ASTNode const* _currentScope) const\n{\n\tif (!m_members[_currentScope])\n\t{\n\t\tsolAssert(\n\t\t\t_currentScope == nullptr ||\n\t\t\tdynamic_cast<SourceUnit const*>(_currentScope) ||\n\t\t\tdynamic_cast<ContractDefinition const*>(_currentScope),\n\t\t\"\");\n\t\tMemberList::MemberMap members = nativeMembers(_currentScope);\n\t\tif (_currentScope)\n\t\t\tmembers += attachedFunctions(*this, *_currentScope);\n\t\tm_members[_currentScope] = std::make_unique<MemberList>(std::move(members));\n\t}\n\treturn *m_members[_currentScope];\n}\n\nType const* Type::fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool) const\n{\n\tType const* encodingType = mobileType();\n\tif (encodingType)\n\t\tencodingType = encodingType->interfaceType(_inLibraryCall);\n\tif (encodingType)\n\t\tencodingType = encodingType->encodingType();\n\t// Structs are fine in the following circumstances:\n\t// - ABIv2 or,\n\t// - storage struct for a library\n\tif (_inLibraryCall && encodingType && encodingType->dataStoredIn(DataLocation::Storage))\n\t\treturn encodingType;\n\tType const* baseType = encodingType;\n\twhile (auto const* arrayType = dynamic_cast<ArrayType const*>(baseType))\n\t{\n\t\tbaseType = arrayType->baseType();\n\n\t\tauto const* baseArrayType = dynamic_cast<ArrayType const*>(baseType);\n\t\tif (!_encoderV2 && baseArrayType && baseArrayType->isDynamicallySized())\n\t\t\treturn nullptr;\n\t}\n\tif (!_encoderV2 && dynamic_cast<StructType const*>(baseType))\n\t\treturn nullptr;\n\n\treturn encodingType;\n}\n\nnamespace\n{\n\nstd::vector<UsingForDirective const*> usingForDirectivesForType(Type const& _type, ASTNode const& _scope)\n{\n\tstd::vector<UsingForDirective const*> usingForDirectives;\n\tSourceUnit const* sourceUnit = dynamic_cast<SourceUnit const*>(&_scope);\n\tif (auto const* contract = dynamic_cast<ContractDefinition const*>(&_scope))\n\t{\n\t\tsourceUnit = &contract->sourceUnit();\n\t\tusingForDirectives += contract->usingForDirectives();\n\t}\n\telse\n\t\tsolAssert(sourceUnit, \"\");\n\tusingForDirectives += ASTNode::filteredNodes<UsingForDirective>(sourceUnit->nodes());\n\n\tif (Declaration const* typeDefinition = _type.typeDefinition())\n\t\tif (auto const* sourceUnit = dynamic_cast<SourceUnit const*>(typeDefinition->scope()))\n\t\t\tfor (auto usingFor: ASTNode::filteredNodes<UsingForDirective>(sourceUnit->nodes()))\n\t\t\t\t// We do not yet compare the type name because of normalization.\n\t\t\t\tif (usingFor->global() && usingFor->typeName())\n\t\t\t\t\tusingForDirectives.emplace_back(usingFor);\n\n\t// Normalise data location of type.\n\tDataLocation typeLocation = DataLocation::Storage;\n\tif (auto refType = dynamic_cast<ReferenceType const*>(&_type))\n\t\ttypeLocation = refType->location();\n\n\treturn usingForDirectives | ranges::views::filter([&](UsingForDirective const* _directive) -> bool {\n\t\t// Convert both types to pointers for comparison to see if the `using for` directive applies.\n\t\t// Note that at this point we don't yet know if the functions are actually usable with the type.\n\t\t// `_type` may not be convertible to the function parameter type.\n\t\treturn\n\t\t\t!_directive->typeName() ||\n\t\t\t*TypeProvider::withLocationIfReference(typeLocation, &_type, true) ==\n\t\t\t*TypeProvider::withLocationIfReference(\n\t\t\t\ttypeLocation,\n\t\t\t\t_directive->typeName()->annotation().type,\n\t\t\t\ttrue\n\t\t\t);\n\t}) | ranges::to<std::vector<UsingForDirective const*>>;\n}\n\n}\n\nstd::set<FunctionDefinition const*, ASTNode::CompareByID> Type::operatorDefinitions(\n\tToken _token,\n\tASTNode const& _scope,\n\tbool _unary\n) const\n{\n\tif (!typeDefinition())\n\t\treturn {};\n\n\tstd::set<FunctionDefinition const*, ASTNode::CompareByID> matchingDefinitions;\n\tfor (UsingForDirective const* directive: usingForDirectivesForType(*this, _scope))\n\t\tfor (auto const& [identifierPath, operator_]: directive->functionsAndOperators())\n\t\t{\n\t\t\tif (operator_ != _token)\n\t\t\t\tcontinue;\n\n\t\t\tauto const& functionDefinition = dynamic_cast<FunctionDefinition const&>(\n\t\t\t\t*identifierPath->annotation().referencedDeclaration\n\t\t\t);\n\t\t\tauto const* functionType = dynamic_cast<FunctionType const*>(\n\t\t\t\tfunctionDefinition.libraryFunction() ? functionDefinition.typeViaContractName() : functionDefinition.type()\n\t\t\t);\n\t\t\tsolAssert(functionType && !functionType->parameterTypes().empty());\n\n\t\t\tsize_t parameterCount = functionDefinition.parameterList().parameters().size();\n\t\t\tif (*this == *functionType->parameterTypes().front() && (_unary ? parameterCount == 1 : parameterCount == 2))\n\t\t\t\tmatchingDefinitions.insert(&functionDefinition);\n\t\t}\n\n\treturn matchingDefinitions;\n}\n\nMemberList::MemberMap Type::attachedFunctions(Type const& _type, ASTNode const& _scope)\n{\n\tMemberList::MemberMap members;\n\n\tstd::set<std::pair<std::string, Declaration const*>> seenFunctions;\n\tauto addFunction = [&](FunctionDefinition const& _function, std::optional<std::string> _name = {})\n\t{\n\t\tif (!_name)\n\t\t\t_name = _function.name();\n\t\tType const* functionType =\n\t\t\t_function.libraryFunction() ? _function.typeViaContractName() : _function.type();\n\t\tsolAssert(functionType, \"\");\n\t\tFunctionType const* withBoundFirstArgument =\n\t\t\tdynamic_cast<FunctionType const&>(*functionType).withBoundFirstArgument();\n\t\tsolAssert(withBoundFirstArgument, \"\");\n\n\t\tif (_type.isImplicitlyConvertibleTo(*withBoundFirstArgument->selfType()))\n\t\t\tif (seenFunctions.insert(std::make_pair(*_name, &_function)).second)\n\t\t\t\tmembers.emplace_back(&_function, withBoundFirstArgument, *_name);\n\t};\n\n\tfor (UsingForDirective const* ufd: usingForDirectivesForType(_type, _scope))\n\t\tfor (auto const& [identifierPath, operator_]: ufd->functionsAndOperators())\n\t\t{\n\t\t\tif (operator_.has_value())\n\t\t\t\t// Functions used to define operators are not automatically attached to the type.\n\t\t\t\t// I.e. `using {f, f as +} for T` allows `T x; x.f()` but `using {f as +} for T` does not.\n\t\t\t\tcontinue;\n\n\t\t\tsolAssert(identifierPath);\n\t\t\tDeclaration const* declaration = identifierPath->annotation().referencedDeclaration;\n\t\t\tsolAssert(declaration);\n\n\t\t\tif (ContractDefinition const* library = dynamic_cast<ContractDefinition const*>(declaration))\n\t\t\t{\n\t\t\t\tsolAssert(library->isLibrary());\n\t\t\t\tfor (FunctionDefinition const* function: library->definedFunctions())\n\t\t\t\t{\n\t\t\t\t\tif (!function->isOrdinary() || !function->isVisibleAsLibraryMember() || function->parameters().empty())\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\taddFunction(*function);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\taddFunction(\n\t\t\t\t\tdynamic_cast<FunctionDefinition const&>(*declaration),\n\t\t\t\t\tidentifierPath->path().back()\n\t\t\t\t);\n\t\t}\n\n\treturn members;\n}\n\nAddressType::AddressType(StateMutability _stateMutability):\n\tm_stateMutability(_stateMutability)\n{\n\tsolAssert(m_stateMutability == StateMutability::Payable || m_stateMutability == StateMutability::NonPayable, \"\");\n}\n\nstd::string AddressType::richIdentifier() const\n{\n\tif (m_stateMutability == StateMutability::Payable)\n\t\treturn \"t_address_payable\";\n\telse\n\t\treturn \"t_address\";\n}\n\nBoolResult AddressType::isImplicitlyConvertibleTo(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tAddressType const& other = dynamic_cast<AddressType const&>(_other);\n\n\treturn other.m_stateMutability <= m_stateMutability;\n}\n\nBoolResult AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif ((_convertTo.category() == category()) || isImplicitlyConvertibleTo(_convertTo))\n\t\treturn true;\n\telse if (auto const* contractType = dynamic_cast<ContractType const*>(&_convertTo))\n\t\treturn (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable();\n\telse if (m_stateMutability == StateMutability::NonPayable)\n\t{\n\t\tif (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))\n\t\t\treturn (!integerType->isSigned() && integerType->numBits() == 160);\n\t\telse if (auto fixedBytesType = dynamic_cast<FixedBytesType const*>(&_convertTo))\n\t\t\treturn (fixedBytesType->numBytes() == 20);\n\t}\n\n\treturn false;\n}\n\nstd::string AddressType::toString(bool) const\n{\n\tif (m_stateMutability == StateMutability::Payable)\n\t\treturn \"address payable\";\n\telse\n\t\treturn \"address\";\n}\n\nstd::string AddressType::canonicalName() const\n{\n\treturn \"address\";\n}\n\nu256 AddressType::literalValue(Literal const* _literal) const\n{\n\tsolAssert(_literal, \"\");\n\tsolAssert(_literal->value().substr(0, 2) == \"0x\", \"\");\n\treturn u256(_literal->valueWithoutUnderscores());\n}\n\nTypeResult AddressType::unaryOperatorResult(Token _operator) const\n{\n\treturn _operator == Token::Delete ? TypeProvider::emptyTuple() : nullptr;\n}\n\n\nTypeResult AddressType::binaryOperatorResult(Token _operator, Type const* _other) const\n{\n\tif (!TokenTraits::isCompareOp(_operator))\n\t\treturn TypeResult::err(\"Arithmetic operations on addresses are not supported. Convert to integer first before using them.\");\n\n\treturn Type::commonType(this, _other);\n}\n\nbool AddressType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tAddressType const& other = dynamic_cast<AddressType const&>(_other);\n\treturn other.m_stateMutability == m_stateMutability;\n}\n\nMemberList::MemberMap AddressType::nativeMembers(ASTNode const*) const\n{\n\tMemberList::MemberMap members = {\n\t\t{\"balance\", TypeProvider::uint256()},\n\t\t{\"code\", TypeProvider::array(DataLocation::Memory)},\n\t\t{\"codehash\",  TypeProvider::fixedBytes(32)},\n\t\t{\"call\", TypeProvider::function(strings{\"bytes memory\"}, strings{\"bool\", \"bytes memory\"}, FunctionType::Kind::BareCall, StateMutability::Payable)},\n\t\t{\"callcode\", TypeProvider::function(strings{\"bytes memory\"}, strings{\"bool\", \"bytes memory\"}, FunctionType::Kind::BareCallCode, StateMutability::Payable)},\n\t\t{\"delegatecall\", TypeProvider::function(strings{\"bytes memory\"}, strings{\"bool\", \"bytes memory\"}, FunctionType::Kind::BareDelegateCall, StateMutability::NonPayable)},\n\t\t{\"staticcall\", TypeProvider::function(strings{\"bytes memory\"}, strings{\"bool\", \"bytes memory\"}, FunctionType::Kind::BareStaticCall, StateMutability::View)}\n\t};\n\tif (m_stateMutability == StateMutability::Payable)\n\t{\n\t\tmembers.emplace_back(MemberList::Member{\"send\", TypeProvider::function(strings{\"uint\"}, strings{\"bool\"}, FunctionType::Kind::Send, StateMutability::NonPayable)});\n\t\tmembers.emplace_back(MemberList::Member{\"transfer\", TypeProvider::function(strings{\"uint\"}, strings(), FunctionType::Kind::Transfer, StateMutability::NonPayable)});\n\t}\n\treturn members;\n}\n\nnamespace\n{\n\nbool isValidShiftAndAmountType(Token _operator, Type const& _shiftAmountType)\n{\n\t// Disable >>> here.\n\tif (_operator == Token::SHR)\n\t\treturn false;\n\telse if (IntegerType const* otherInt = dynamic_cast<decltype(otherInt)>(&_shiftAmountType))\n\t\treturn !otherInt->isSigned();\n\telse if (RationalNumberType const* otherRat = dynamic_cast<decltype(otherRat)>(&_shiftAmountType))\n\t\treturn !otherRat->isFractional() && otherRat->integerType() && !otherRat->integerType()->isSigned();\n\telse\n\t\treturn false;\n}\n\n}\n\nIntegerType::IntegerType(unsigned _bits, IntegerType::Modifier _modifier):\n\tm_bits(_bits), m_modifier(_modifier)\n{\n\tsolAssert(\n\t\tm_bits > 0 && m_bits <= 256 && m_bits % 8 == 0,\n\t\t\"Invalid bit number for integer type: \" + util::toString(m_bits)\n\t);\n}\n\nstd::string IntegerType::richIdentifier() const\n{\n\treturn \"t_\" + std::string(isSigned() ? \"\" : \"u\") + \"int\" + std::to_string(numBits());\n}\n\nBoolResult IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (_convertTo.category() == category())\n\t{\n\t\tIntegerType const& convertTo = dynamic_cast<IntegerType const&>(_convertTo);\n\t\t// disallowing unsigned to signed conversion of different bits\n\t\tif (isSigned() != convertTo.isSigned())\n\t\t\treturn false;\n\t\telse if (convertTo.m_bits < m_bits)\n\t\t\treturn false;\n\t\telse\n\t\t\treturn true;\n\t}\n\telse if (_convertTo.category() == Category::FixedPoint)\n\t{\n\t\tFixedPointType const& convertTo = dynamic_cast<FixedPointType const&>(_convertTo);\n\t\treturn maxValue() <= convertTo.maxIntegerValue() && minValue() >= convertTo.minIntegerValue();\n\t}\n\telse\n\t\treturn false;\n}\n\nBoolResult IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (isImplicitlyConvertibleTo(_convertTo))\n\t\treturn true;\n\telse if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))\n\t\treturn (numBits() == integerType->numBits()) || (isSigned() == integerType->isSigned());\n\telse if (auto addressType = dynamic_cast<AddressType const*>(&_convertTo))\n\t\treturn\n\t\t\t(addressType->stateMutability() != StateMutability::Payable) &&\n\t\t\t!isSigned() &&\n\t\t\t(numBits() == 160);\n\telse if (auto fixedBytesType = dynamic_cast<FixedBytesType const*>(&_convertTo))\n\t\treturn (!isSigned() && (numBits() == fixedBytesType->numBytes() * 8));\n\telse if (dynamic_cast<EnumType const*>(&_convertTo))\n\t\treturn true;\n\telse if (auto fixedPointType = dynamic_cast<FixedPointType const*>(&_convertTo))\n\t\treturn (isSigned() == fixedPointType->isSigned()) && (numBits() == fixedPointType->numBits());\n\n\treturn false;\n}\n\nTypeResult IntegerType::unaryOperatorResult(Token _operator) const\n{\n\t// \"delete\" is ok for all integer types\n\tif (_operator == Token::Delete)\n\t\treturn TypeResult{TypeProvider::emptyTuple()};\n\t// unary negation only on signed types\n\telse if (_operator == Token::Sub)\n\t\treturn isSigned() ? TypeResult{this} : TypeResult::err(\"Unary negation is only allowed for signed integers.\");\n\telse if (_operator == Token::Inc || _operator == Token::Dec || _operator == Token::BitNot)\n\t\treturn TypeResult{this};\n\telse\n\t\treturn TypeResult::err(\"\");\n}\n\nbool IntegerType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\treturn *this == dynamic_cast<IntegerType const&>(_other);\n}\n\nbool IntegerType::operator==(IntegerType const& _other) const\n{\n\treturn _other.m_bits == m_bits && _other.m_modifier == m_modifier;\n}\n\nstd::string IntegerType::toString(bool) const\n{\n\tstd::string prefix = isSigned() ? \"int\" : \"uint\";\n\treturn prefix + util::toString(m_bits);\n}\n\nu256 IntegerType::min() const\n{\n\tif (isSigned())\n\t\treturn s2u(s256(minValue()));\n\telse\n\t\treturn u256(minValue());\n}\n\nu256 IntegerType::max() const\n{\n\tif (isSigned())\n\t\treturn s2u(s256(maxValue()));\n\telse\n\t\treturn u256(maxValue());\n}\n\nbigint IntegerType::minValue() const\n{\n\tif (isSigned())\n\t\treturn -(bigint(1) << (m_bits - 1));\n\telse\n\t\treturn bigint(0);\n}\n\nbigint IntegerType::maxValue() const\n{\n\tif (isSigned())\n\t\treturn (bigint(1) << (m_bits - 1)) - 1;\n\telse\n\t\treturn (bigint(1) << m_bits) - 1;\n}\n\nTypeResult IntegerType::binaryOperatorResult(Token _operator, Type const* _other) const\n{\n\tif (\n\t\t_other->category() != Category::RationalNumber &&\n\t\t_other->category() != Category::FixedPoint &&\n\t\t_other->category() != category()\n\t)\n\t\treturn nullptr;\n\tif (TokenTraits::isShiftOp(_operator))\n\t{\n\t\t// Shifts are not symmetric with respect to the type\n\t\tif (isValidShiftAndAmountType(_operator, *_other))\n\t\t\treturn this;\n\t\telse\n\t\t\treturn nullptr;\n\t}\n\telse if (Token::Exp == _operator)\n\t{\n\t\tif (auto otherIntType = dynamic_cast<IntegerType const*>(_other))\n\t\t{\n\t\t\tif (otherIntType->isSigned())\n\t\t\t\treturn TypeResult::err(\"Exponentiation power is not allowed to be a signed integer type.\");\n\t\t}\n\t\telse if (dynamic_cast<FixedPointType const*>(_other))\n\t\t\treturn nullptr;\n\t\telse if (auto rationalNumberType = dynamic_cast<RationalNumberType const*>(_other))\n\t\t{\n\t\t\tif (rationalNumberType->isFractional())\n\t\t\t\treturn TypeResult::err(\"Exponent is fractional.\");\n\t\t\tif (!rationalNumberType->integerType())\n\t\t\t\treturn TypeResult::err(\"Exponent too large.\");\n\t\t\tif (rationalNumberType->isNegative())\n\t\t\t\treturn TypeResult::err(\"Exponentiation power is not allowed to be a negative integer literal.\");\n\t\t}\n\t\treturn this;\n\t}\n\n\tauto commonType = Type::commonType(this, _other); //might be an integer or fixed point\n\tif (!commonType)\n\t\treturn nullptr;\n\n\t// All integer types can be compared\n\tif (TokenTraits::isCompareOp(_operator))\n\t\treturn commonType;\n\tif (TokenTraits::isBooleanOp(_operator))\n\t\treturn nullptr;\n\treturn commonType;\n}\n\nFixedPointType::FixedPointType(unsigned _totalBits, unsigned _fractionalDigits, FixedPointType::Modifier _modifier):\n\tm_totalBits(_totalBits), m_fractionalDigits(_fractionalDigits), m_modifier(_modifier)\n{\n\tsolAssert(\n\t\t8 <= m_totalBits && m_totalBits <= 256 && m_totalBits % 8 == 0 && m_fractionalDigits <= 80,\n\t\t\"Invalid bit number(s) for fixed type: \" +\n\t\tutil::toString(_totalBits) + \"x\" + util::toString(_fractionalDigits)\n\t);\n}\n\nstd::string FixedPointType::richIdentifier() const\n{\n\treturn \"t_\" + std::string(isSigned() ? \"\" : \"u\") + \"fixed\" + std::to_string(m_totalBits) + \"x\" + std::to_string(m_fractionalDigits);\n}\n\nBoolResult FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (_convertTo.category() == category())\n\t{\n\t\tFixedPointType const& convertTo = dynamic_cast<FixedPointType const&>(_convertTo);\n\t\tif (convertTo.fractionalDigits() < m_fractionalDigits)\n\t\t\treturn BoolResult::err(\"Too many fractional digits.\");\n\t\tif (convertTo.numBits() < m_totalBits)\n\t\t\treturn false;\n\t\telse\n\t\t\treturn convertTo.maxIntegerValue() >= maxIntegerValue() && convertTo.minIntegerValue() <= minIntegerValue();\n\t}\n\treturn false;\n}\n\nBoolResult FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\treturn _convertTo.category() == category() || _convertTo.category() == Category::Integer;\n}\n\nTypeResult FixedPointType::unaryOperatorResult(Token _operator) const\n{\n\tsolAssert(_operator != Token::Add);\n\n\tswitch (_operator)\n\t{\n\tcase Token::Delete:\n\t\t// \"delete\" is ok for all fixed types\n\t\treturn TypeResult{TypeProvider::emptyTuple()};\n\tcase Token::Sub:\n\tcase Token::Inc:\n\tcase Token::Dec:\n\t\t// for fixed, we allow -, ++ and --\n\t\treturn this;\n\tdefault:\n\t\treturn nullptr;\n\t}\n}\n\nbool FixedPointType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tFixedPointType const& other = dynamic_cast<FixedPointType const&>(_other);\n\treturn other.m_totalBits == m_totalBits && other.m_fractionalDigits == m_fractionalDigits && other.m_modifier == m_modifier;\n}\n\nstd::string FixedPointType::toString(bool) const\n{\n\tstd::string prefix = isSigned() ? \"fixed\" : \"ufixed\";\n\treturn prefix + util::toString(m_totalBits) + \"x\" + util::toString(m_fractionalDigits);\n}\n\nbigint FixedPointType::maxIntegerValue() const\n{\n\tbigint maxValue = (bigint(1) << (m_totalBits - (isSigned() ? 1 : 0))) - 1;\n\treturn maxValue / boost::multiprecision::pow(bigint(10), m_fractionalDigits);\n}\n\nbigint FixedPointType::minIntegerValue() const\n{\n\tif (isSigned())\n\t{\n\t\tbigint minValue = -(bigint(1) << (m_totalBits - (isSigned() ? 1 : 0)));\n\t\treturn minValue / boost::multiprecision::pow(bigint(10), m_fractionalDigits);\n\t}\n\telse\n\t\treturn bigint(0);\n}\n\nTypeResult FixedPointType::binaryOperatorResult(Token _operator, Type const* _other) const\n{\n\tauto commonType = Type::commonType(this, _other);\n\n\tif (!commonType)\n\t\treturn nullptr;\n\n\t// All fixed types can be compared\n\tif (TokenTraits::isCompareOp(_operator))\n\t\treturn commonType;\n\tif (TokenTraits::isBitOp(_operator) || TokenTraits::isBooleanOp(_operator) || _operator == Token::Exp)\n\t\treturn nullptr;\n\treturn commonType;\n}\n\nIntegerType const* FixedPointType::asIntegerType() const\n{\n\treturn TypeProvider::integer(numBits(), isSigned() ? IntegerType::Modifier::Signed : IntegerType::Modifier::Unsigned);\n}\n\nstd::tuple<bool, rational> RationalNumberType::parseRational(std::string const& _value)\n{\n\trational value;\n\ttry\n\t{\n\t\tauto radixPoint = find(_value.begin(), _value.end(), '.');\n\n\t\tif (radixPoint != _value.end())\n\t\t{\n\t\t\tif (\n\t\t\t\t!all_of(radixPoint + 1, _value.end(), util::isDigit) ||\n\t\t\t\t!all_of(_value.begin(), radixPoint, util::isDigit)\n\t\t\t)\n\t\t\t\treturn std::make_tuple(false, rational(0));\n\n\t\t\t// Only decimal notation allowed here, leading zeros would switch to octal.\n\t\t\tauto fractionalBegin = find_if_not(\n\t\t\t\tradixPoint + 1,\n\t\t\t\t_value.end(),\n\t\t\t\t[](char const& a) { return a == '0'; }\n\t\t\t);\n\n\t\t\trational numerator;\n\t\t\trational denominator(1);\n\n\t\t\tdenominator = bigint(std::string(fractionalBegin, _value.end()));\n\t\t\tdenominator /= boost::multiprecision::pow(\n\t\t\t\tbigint(10),\n\t\t\t\tstatic_cast<unsigned>(distance(radixPoint + 1, _value.end()))\n\t\t\t);\n\t\t\tnumerator = bigint(std::string(_value.begin(), radixPoint));\n\t\t\tvalue = numerator + denominator;\n\t\t}\n\t\telse\n\t\t\tvalue = bigint(_value);\n\t\treturn std::make_tuple(true, value);\n\t}\n\tcatch (...)\n\t{\n\t\treturn std::make_tuple(false, rational(0));\n\t}\n}\n\nstd::tuple<bool, rational> RationalNumberType::isValidLiteral(Literal const& _literal)\n{\n\trational value;\n\ttry\n\t{\n\t\tASTString valueString = _literal.valueWithoutUnderscores();\n\n\t\tauto expPoint = find(valueString.begin(), valueString.end(), 'e');\n\t\tif (expPoint == valueString.end())\n\t\t\texpPoint = find(valueString.begin(), valueString.end(), 'E');\n\n\t\tif (boost::starts_with(valueString, \"0x\"))\n\t\t{\n\t\t\t// process as hex\n\t\t\tvalue = bigint(valueString);\n\t\t}\n\t\telse if (expPoint != valueString.end())\n\t\t{\n\t\t\t// Parse mantissa and exponent. Checks numeric limit.\n\t\t\tstd::tuple<bool, rational> mantissa = parseRational(std::string(valueString.begin(), expPoint));\n\n\t\t\tif (!std::get<0>(mantissa))\n\t\t\t\treturn std::make_tuple(false, rational(0));\n\t\t\tvalue = std::get<1>(mantissa);\n\n\t\t\t// 0E... is always zero.\n\t\t\tif (value == 0)\n\t\t\t\treturn std::make_tuple(true, rational(0));\n\n\t\t\tbigint exp = bigint(std::string(expPoint + 1, valueString.end()));\n\n\t\t\tif (exp > std::numeric_limits<int32_t>::max() || exp < std::numeric_limits<int32_t>::min())\n\t\t\t\treturn std::make_tuple(false, rational(0));\n\n\t\t\tuint32_t expAbs = bigint(abs(exp)).convert_to<uint32_t>();\n\n\t\t\tif (exp < 0)\n\t\t\t{\n\t\t\t\tif (!fitsPrecisionBase10(abs(value.denominator()), expAbs))\n\t\t\t\t\treturn std::make_tuple(false, rational(0));\n\t\t\t\tvalue /= boost::multiprecision::pow(\n\t\t\t\t\tbigint(10),\n\t\t\t\t\texpAbs\n\t\t\t\t);\n\t\t\t}\n\t\t\telse if (exp > 0)\n\t\t\t{\n\t\t\t\tif (!fitsPrecisionBase10(abs(value.numerator()), expAbs))\n\t\t\t\t\treturn std::make_tuple(false, rational(0));\n\t\t\t\tvalue *= boost::multiprecision::pow(\n\t\t\t\t\tbigint(10),\n\t\t\t\t\texpAbs\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// parse as rational number\n\t\t\tstd::tuple<bool, rational> tmp = parseRational(valueString);\n\t\t\tif (!std::get<0>(tmp))\n\t\t\t\treturn tmp;\n\t\t\tvalue = std::get<1>(tmp);\n\t\t}\n\t}\n\tcatch (...)\n\t{\n\t\treturn std::make_tuple(false, rational(0));\n\t}\n\tswitch (_literal.subDenomination())\n\t{\n\t\tcase Literal::SubDenomination::None:\n\t\tcase Literal::SubDenomination::Wei:\n\t\tcase Literal::SubDenomination::Second:\n\t\t\tbreak;\n\t\tcase Literal::SubDenomination::Gwei:\n\t\t\tvalue *= bigint(\"1000000000\");\n\t\t\tbreak;\n\t\tcase Literal::SubDenomination::Ether:\n\t\t\tvalue *= bigint(\"1000000000000000000\");\n\t\t\tbreak;\n\t\tcase Literal::SubDenomination::Minute:\n\t\t\tvalue *= bigint(\"60\");\n\t\t\tbreak;\n\t\tcase Literal::SubDenomination::Hour:\n\t\t\tvalue *= bigint(\"3600\");\n\t\t\tbreak;\n\t\tcase Literal::SubDenomination::Day:\n\t\t\tvalue *= bigint(\"86400\");\n\t\t\tbreak;\n\t\tcase Literal::SubDenomination::Week:\n\t\t\tvalue *= bigint(\"604800\");\n\t\t\tbreak;\n\t\tcase Literal::SubDenomination::Year:\n\t\t\tvalue *= bigint(\"31536000\");\n\t\t\tbreak;\n\t}\n\n\n\treturn std::make_tuple(true, value);\n}\n\nBoolResult RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tswitch (_convertTo.category())\n\t{\n\tcase Category::Integer:\n\t{\n\t\tif (isFractional())\n\t\t\treturn false;\n\t\tIntegerType const& targetType = dynamic_cast<IntegerType const&>(_convertTo);\n\t\treturn fitsIntegerType(m_value.numerator(), targetType);\n\t}\n\tcase Category::FixedPoint:\n\t{\n\t\tFixedPointType const& targetType = dynamic_cast<FixedPointType const&>(_convertTo);\n\t\t// Store a negative number into an unsigned.\n\t\tif (isNegative() && !targetType.isSigned())\n\t\t\treturn false;\n\t\tif (!isFractional())\n\t\t\treturn (targetType.minIntegerValue() <= m_value) && (m_value <= targetType.maxIntegerValue());\n\t\trational value = m_value * pow(bigint(10), targetType.fractionalDigits());\n\t\t// Need explicit conversion since truncation will occur.\n\t\tif (value.denominator() != 1)\n\t\t\treturn false;\n\t\treturn fitsIntoBits(value.numerator(), targetType.numBits(), targetType.isSigned());\n\t}\n\tcase Category::FixedBytes:\n\t\treturn (m_value == rational(0)) || (m_compatibleBytesType && *m_compatibleBytesType == _convertTo);\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nBoolResult RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (isImplicitlyConvertibleTo(_convertTo))\n\t\treturn true;\n\n\tauto category = _convertTo.category();\n\tif (category == Category::FixedBytes)\n\t\treturn false;\n\telse if (auto addressType = dynamic_cast<AddressType const*>(&_convertTo))\n\t\treturn (m_value == 0) ||\n\t\t\t((addressType->stateMutability() != StateMutability::Payable) &&\n\t\t\t!isNegative() &&\n\t\t\t!isFractional() &&\n\t\t\tintegerType() &&\n\t\t\t(integerType()->numBits() <= 160));\n\telse if (category == Category::Integer)\n\t\treturn false;\n\telse if (auto enumType = dynamic_cast<EnumType const*>(&_convertTo))\n\t\tif (isNegative() || isFractional() || m_value >= enumType->numberOfMembers())\n\t\t\treturn false;\n\n\tType const* mobType = mobileType();\n\treturn (mobType && mobType->isExplicitlyConvertibleTo(_convertTo));\n\n}\n\nTypeResult RationalNumberType::unaryOperatorResult(Token _operator) const\n{\n\tif (std::optional<rational> value = ConstantEvaluator::evaluateUnaryOperator(_operator, m_value))\n\t\treturn TypeResult{TypeProvider::rationalNumber(*value)};\n\telse\n\t\treturn nullptr;\n}\n\nTypeResult RationalNumberType::binaryOperatorResult(Token _operator, Type const* _other) const\n{\n\tif (_other->category() == Category::Integer || _other->category() == Category::FixedPoint)\n\t{\n\t\tif (isFractional())\n\t\t\treturn TypeResult::err(\"Fractional literals not supported.\");\n\t\telse if (!integerType())\n\t\t\treturn TypeResult::err(\"Literal too large.\");\n\n\t\t// Shift and exp are not symmetric, so it does not make sense to swap\n\t\t// the types as below. As an exception, we always use uint here.\n\t\tif (TokenTraits::isShiftOp(_operator))\n\t\t{\n\t\t\tif (!isValidShiftAndAmountType(_operator, *_other))\n\t\t\t\treturn nullptr;\n\t\t\treturn isNegative() ? TypeProvider::int256() : TypeProvider::uint256();\n\t\t}\n\t\telse if (Token::Exp == _operator)\n\t\t{\n\t\t\tif (auto const* otherIntType = dynamic_cast<IntegerType const*>(_other))\n\t\t\t{\n\t\t\t\tif (otherIntType->isSigned())\n\t\t\t\t\treturn TypeResult::err(\"Exponentiation power is not allowed to be a signed integer type.\");\n\t\t\t}\n\t\t\telse if (dynamic_cast<FixedPointType const*>(_other))\n\t\t\t\treturn TypeResult::err(\"Exponent is fractional.\");\n\n\t\t\treturn isNegative() ? TypeProvider::int256() : TypeProvider::uint256();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto commonType = Type::commonType(this, _other);\n\t\t\tif (!commonType)\n\t\t\t\treturn nullptr;\n\t\t\treturn commonType->binaryOperatorResult(_operator, _other);\n\t\t}\n\t}\n\telse if (_other->category() != category())\n\t\treturn nullptr;\n\n\tRationalNumberType const& other = dynamic_cast<RationalNumberType const&>(*_other);\n\tif (TokenTraits::isCompareOp(_operator))\n\t{\n\t\t// Since we do not have a \"BoolConstantType\", we have to do the actual comparison\n\t\t// at runtime and convert to mobile typse first. Such a comparison is not a very common\n\t\t// use-case and will be optimized away.\n\t\tType const* thisMobile = mobileType();\n\t\tType const* otherMobile = other.mobileType();\n\t\tif (!thisMobile || !otherMobile)\n\t\t\treturn nullptr;\n\t\treturn thisMobile->binaryOperatorResult(_operator, otherMobile);\n\t}\n\telse if (std::optional<rational> value = ConstantEvaluator::evaluateBinaryOperator(_operator, m_value, other.m_value))\n\t{\n\t\t// verify that numerator and denominator fit into 4096 bit after every operation\n\t\tif (value->numerator() != 0 && std::max(boost::multiprecision::msb(abs(value->numerator())), boost::multiprecision::msb(abs(value->denominator()))) > 4096)\n\t\t\treturn TypeResult::err(\"Precision of rational constants is limited to 4096 bits.\");\n\n\t\treturn TypeResult{TypeProvider::rationalNumber(*value)};\n\t}\n\telse\n\t\treturn nullptr;\n}\n\nstd::string RationalNumberType::richIdentifier() const\n{\n\t// rational seemingly will put the sign always on the numerator,\n\t// but let just make it deterministic here.\n\tbigint numerator = abs(m_value.numerator());\n\tbigint denominator = abs(m_value.denominator());\n\tif (m_value < 0)\n\t\treturn \"t_rational_minus_\" + numerator.str() + \"_by_\" + denominator.str();\n\telse\n\t\treturn \"t_rational_\" + numerator.str() + \"_by_\" + denominator.str();\n}\n\nbool RationalNumberType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tRationalNumberType const& other = dynamic_cast<RationalNumberType const&>(_other);\n\treturn m_value == other.m_value;\n}\n\nstd::string RationalNumberType::bigintToReadableString(bigint const& _num)\n{\n\tstd::string str = _num.str();\n\tif (str.size() > 32)\n\t{\n\t\tsize_t omitted = str.size() - 8;\n\t\tstr = str.substr(0, 4) + \"...(\" + std::to_string(omitted) + \" digits omitted)...\" + str.substr(str.size() - 4, 4);\n\t}\n\treturn str;\n}\n\nstd::string RationalNumberType::toString(bool) const\n{\n\tif (!isFractional())\n\t\treturn \"int_const \" + bigintToReadableString(m_value.numerator());\n\n\tstd::string numerator = bigintToReadableString(m_value.numerator());\n\tstd::string denominator = bigintToReadableString(m_value.denominator());\n\treturn \"rational_const \" + numerator + \" / \" + denominator;\n}\n\nu256 RationalNumberType::literalValue(Literal const*) const\n{\n\t// We ignore the literal and hope that the type was correctly determined to represent\n\t// its value.\n\n\tu256 value;\n\tbigint shiftedValue;\n\n\tif (!isFractional())\n\t\tshiftedValue = m_value.numerator();\n\telse\n\t{\n\t\tauto fixed = fixedPointType();\n\t\tsolAssert(fixed, \"Rational number cannot be represented as fixed point type.\");\n\t\tunsigned fractionalDigits = fixed->fractionalDigits();\n\t\tshiftedValue = m_value.numerator() * boost::multiprecision::pow(bigint(10), fractionalDigits) / m_value.denominator();\n\t}\n\n\t// we ignore the literal and hope that the type was correctly determined\n\tsolAssert(shiftedValue <= u256(-1), \"Number constant too large.\");\n\tsolAssert(shiftedValue >= -(bigint(1) << 255), \"Number constant too small.\");\n\n\tif (m_value >= rational(0))\n\t\tvalue = u256(shiftedValue);\n\telse\n\t\tvalue = s2u(s256(shiftedValue));\n\treturn value;\n}\n\nType const* RationalNumberType::mobileType() const\n{\n\tif (!isFractional())\n\t\treturn integerType();\n\telse\n\t\treturn fixedPointType();\n}\n\nIntegerType const* RationalNumberType::integerType() const\n{\n\tsolAssert(!isFractional(), \"integerType() called for fractional number.\");\n\tbigint value = m_value.numerator();\n\tbool negative = (value < 0);\n\tif (negative) // convert to positive number of same bit requirements\n\t\tvalue = ((0 - value) - 1) << 1;\n\tif (value > u256(-1))\n\t\treturn nullptr;\n\telse\n\t\treturn TypeProvider::integer(\n\t\t\tstd::max(numberEncodingSize(value), 1u) * 8,\n\t\t\tnegative ? IntegerType::Modifier::Signed : IntegerType::Modifier::Unsigned\n\t\t);\n}\n\nFixedPointType const* RationalNumberType::fixedPointType() const\n{\n\tbool negative = (m_value < 0);\n\tunsigned fractionalDigits = 0;\n\trational value = abs(m_value); // We care about the sign later.\n\trational maxValue = negative ?\n\t\trational(bigint(1) << 255, 1):\n\t\trational((bigint(1) << 256) - 1, 1);\n\n\twhile (value * 10 <= maxValue && value.denominator() != 1 && fractionalDigits < 80)\n\t{\n\t\tvalue *= 10;\n\t\tfractionalDigits++;\n\t}\n\n\tif (value > maxValue)\n\t\treturn nullptr;\n\n\t// This means we round towards zero for positive and negative values.\n\tbigint v = value.numerator() / value.denominator();\n\n\tif (negative && v != 0)\n\t\t// modify value to satisfy bit requirements for negative numbers:\n\t\t// add one bit for sign and decrement because negative numbers can be larger\n\t\tv = (v - 1) << 1;\n\n\tif (v > u256(-1))\n\t\treturn nullptr;\n\n\tunsigned totalBits = std::max(numberEncodingSize(v), 1u) * 8;\n\tsolAssert(totalBits <= 256, \"\");\n\n\treturn TypeProvider::fixedPoint(\n\t\ttotalBits, fractionalDigits,\n\t\tnegative ? FixedPointType::Modifier::Signed : FixedPointType::Modifier::Unsigned\n\t);\n}\n\nStringLiteralType::StringLiteralType(Literal const& _literal):\n\tm_value(_literal.value())\n{\n}\n\nStringLiteralType::StringLiteralType(std::string _value):\n\tm_value{std::move(_value)}\n{\n}\n\nBoolResult StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (auto fixedBytes = dynamic_cast<FixedBytesType const*>(&_convertTo))\n\t{\n\t\tif (static_cast<size_t>(fixedBytes->numBytes()) < m_value.size())\n\t\t\treturn BoolResult::err(\"Literal is larger than the type.\");\n\t\treturn true;\n\t}\n\telse if (auto arrayType = dynamic_cast<ArrayType const*>(&_convertTo))\n\t{\n\t\tsize_t invalidSequence;\n\t\tif (arrayType->isString() && !util::validateUTF8(value(), invalidSequence))\n\t\t\treturn BoolResult::err(\n\t\t\t\t\"Contains invalid UTF-8 sequence at position \" +\n\t\t\t\tutil::toString(invalidSequence) +\n\t\t\t\t\".\"\n\t\t\t);\n\t\treturn\n\t\t\tarrayType->location() != DataLocation::CallData &&\n\t\t\tarrayType->isByteArrayOrString() &&\n\t\t\t!(arrayType->dataStoredIn(DataLocation::Storage) && arrayType->isPointer());\n\t}\n\telse\n\t\treturn false;\n}\n\nstd::string StringLiteralType::richIdentifier() const\n{\n\t// Since we have to return a valid identifier and the std::string itself may contain\n\t// anything, we hash it.\n\treturn \"t_stringliteral_\" + util::toHex(util::keccak256(m_value).asBytes());\n}\n\nbool StringLiteralType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\treturn m_value == dynamic_cast<StringLiteralType const&>(_other).m_value;\n}\n\nstd::string StringLiteralType::toString(bool) const\n{\n\tauto isPrintableASCII = [](std::string const& s)\n\t{\n\t\tfor (auto c: s)\n\t\t{\n\t\t\tif (static_cast<unsigned>(c) <= 0x1f || static_cast<unsigned>(c) >= 0x7f)\n\t\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t};\n\n\treturn isPrintableASCII(m_value) ?\n\t\t(\"literal_string \\\"\" + m_value + \"\\\"\") :\n\t\t(\"literal_string hex\\\"\" + util::toHex(util::asBytes(m_value)) + \"\\\"\");\n}\n\nType const* StringLiteralType::mobileType() const\n{\n\treturn TypeProvider::stringMemory();\n}\n\nFixedBytesType::FixedBytesType(unsigned _bytes): m_bytes(_bytes)\n{\n\tsolAssert(\n\t\tm_bytes > 0 && m_bytes <= 32,\n\t\t\"Invalid byte number for fixed bytes type: \" + util::toString(m_bytes)\n\t);\n}\n\nBoolResult FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (_convertTo.category() != category())\n\t\treturn false;\n\tFixedBytesType const& convertTo = dynamic_cast<FixedBytesType const&>(_convertTo);\n\treturn convertTo.m_bytes >= m_bytes;\n}\n\nBoolResult FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (_convertTo.category() == category())\n\t\treturn true;\n\telse if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))\n\t\treturn (!integerType->isSigned() && integerType->numBits() == numBytes() * 8);\n\telse if (auto addressType = dynamic_cast<AddressType const*>(&_convertTo))\n\t\treturn\n\t\t\t(addressType->stateMutability() != StateMutability::Payable) &&\n\t\t\t(numBytes() == 20);\n\telse if (auto fixedPointType = dynamic_cast<FixedPointType const*>(&_convertTo))\n\t\treturn fixedPointType->numBits() == numBytes() * 8;\n\n\treturn false;\n}\n\nTypeResult FixedBytesType::unaryOperatorResult(Token _operator) const\n{\n\t// \"delete\" and \"~\" is okay for FixedBytesType\n\tif (_operator == Token::Delete)\n\t\treturn TypeResult{TypeProvider::emptyTuple()};\n\telse if (_operator == Token::BitNot)\n\t\treturn this;\n\n\treturn nullptr;\n}\n\nTypeResult FixedBytesType::binaryOperatorResult(Token _operator, Type const* _other) const\n{\n\tif (TokenTraits::isShiftOp(_operator))\n\t{\n\t\tif (isValidShiftAndAmountType(_operator, *_other))\n\t\t\treturn this;\n\t\telse\n\t\t\treturn nullptr;\n\t}\n\n\tauto commonType = dynamic_cast<FixedBytesType const*>(Type::commonType(this, _other));\n\tif (!commonType)\n\t\treturn nullptr;\n\n\t// FixedBytes can be compared and have bitwise operators applied to them\n\tif (TokenTraits::isCompareOp(_operator) || TokenTraits::isBitOp(_operator))\n\t\treturn TypeResult(commonType);\n\n\treturn nullptr;\n}\n\nMemberList::MemberMap FixedBytesType::nativeMembers(ASTNode const*) const\n{\n\treturn MemberList::MemberMap{MemberList::Member{\"length\", TypeProvider::uint(8)}};\n}\n\nstd::string FixedBytesType::richIdentifier() const\n{\n\treturn \"t_bytes\" + std::to_string(m_bytes);\n}\n\nbool FixedBytesType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tFixedBytesType const& other = dynamic_cast<FixedBytesType const&>(_other);\n\treturn other.m_bytes == m_bytes;\n}\n\nu256 BoolType::literalValue(Literal const* _literal) const\n{\n\tsolAssert(_literal, \"\");\n\tif (_literal->token() == Token::TrueLiteral)\n\t\treturn u256(1);\n\telse if (_literal->token() == Token::FalseLiteral)\n\t\treturn u256(0);\n\telse\n\t\tsolAssert(false, \"Bool type constructed from non-boolean literal.\");\n}\n\nTypeResult BoolType::unaryOperatorResult(Token _operator) const\n{\n\tif (_operator == Token::Delete)\n\t\treturn TypeProvider::emptyTuple();\n\telse if (_operator == Token::Not)\n\t\treturn this;\n\telse\n\t\treturn nullptr;\n}\n\nTypeResult BoolType::binaryOperatorResult(Token _operator, Type const* _other) const\n{\n\tif (category() != _other->category())\n\t\treturn nullptr;\n\tif (_operator == Token::Equal || _operator == Token::NotEqual || _operator == Token::And || _operator == Token::Or)\n\t\treturn _other;\n\telse\n\t\treturn nullptr;\n}\n\nType const* ContractType::encodingType() const\n{\n\tif (isSuper())\n\t\treturn nullptr;\n\n\tif (isPayable())\n\t\treturn TypeProvider::payableAddress();\n\telse\n\t\treturn TypeProvider::address();\n}\n\nBoolResult ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (m_super)\n\t\treturn false;\n\n\tif (*this == _convertTo)\n\t\treturn true;\n\tif (_convertTo.category() == Category::Contract)\n\t{\n\t\tauto const& targetContractType = dynamic_cast<ContractType const&>(_convertTo);\n\t\tif (targetContractType.isSuper())\n\t\t\treturn false;\n\n\t\tauto const& bases = contractDefinition().annotation().linearizedBaseContracts;\n\t\treturn find(\n\t\t\tbases.begin(),\n\t\t\tbases.end(),\n\t\t\t&targetContractType.contractDefinition()\n\t\t) != bases.end();\n\t}\n\treturn false;\n}\n\nBoolResult ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (m_super)\n\t\treturn false;\n\n\tif (auto const* addressType = dynamic_cast<AddressType const*>(&_convertTo))\n\t\treturn isPayable() || (addressType->stateMutability() < StateMutability::Payable);\n\n\treturn isImplicitlyConvertibleTo(_convertTo);\n}\n\nbool ContractType::isPayable() const\n{\n\tauto receiveFunction = m_contract.receiveFunction();\n\tauto fallbackFunction = m_contract.fallbackFunction();\n\treturn receiveFunction || (fallbackFunction && fallbackFunction->isPayable());\n}\n\nTypeResult ContractType::unaryOperatorResult(Token _operator) const\n{\n\tif (isSuper())\n\t\treturn nullptr;\n\telse if (_operator == Token::Delete)\n\t\treturn TypeProvider::emptyTuple();\n\telse\n\t\treturn nullptr;\n}\n\nstd::vector<Type const*> CompositeType::fullDecomposition() const\n{\n\tstd::vector<Type const*> res = {this};\n\tstd::unordered_set<std::string> seen = {richIdentifier()};\n\tfor (size_t k = 0; k < res.size(); ++k)\n\t\tif (auto composite = dynamic_cast<CompositeType const*>(res[k]))\n\t\t\tfor (Type const* next: composite->decomposition())\n\t\t\t\tif (seen.count(next->richIdentifier()) == 0)\n\t\t\t\t{\n\t\t\t\t\tseen.insert(next->richIdentifier());\n\t\t\t\t\tres.push_back(next);\n\t\t\t\t}\n\treturn res;\n}\n\nType const* ReferenceType::withLocation(DataLocation _location, bool _isPointer) const\n{\n\treturn TypeProvider::withLocation(this, _location, _isPointer);\n}\n\nTypeResult ReferenceType::unaryOperatorResult(Token _operator) const\n{\n\tif (_operator != Token::Delete)\n\t\treturn nullptr;\n\t// delete can be used on everything except calldata references or storage pointers\n\t// (storage references are ok)\n\tswitch (location())\n\t{\n\tcase DataLocation::CallData:\n\t\treturn nullptr;\n\tcase DataLocation::Memory:\n\t\treturn TypeProvider::emptyTuple();\n\tcase DataLocation::Storage:\n\t\treturn isPointer() ? nullptr : TypeProvider::emptyTuple();\n\tcase DataLocation::Transient:\n\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t}\n\treturn nullptr;\n}\n\nbool ReferenceType::isPointer() const\n{\n\tif (m_location == DataLocation::Storage)\n\t\treturn m_isPointer;\n\telse\n\t\treturn true;\n}\n\nType const* ReferenceType::copyForLocationIfReference(Type const* _type) const\n{\n\treturn TypeProvider::withLocationIfReference(m_location, _type);\n}\n\nstd::string ReferenceType::stringForReferencePart() const\n{\n\tswitch (m_location)\n\t{\n\tcase DataLocation::Storage:\n\t\treturn std::string(\"storage \") + (isPointer() ? \"pointer\" : \"ref\");\n\tcase DataLocation::CallData:\n\t\treturn \"calldata\";\n\tcase DataLocation::Memory:\n\t\treturn \"memory\";\n\tcase DataLocation::Transient:\n\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\tbreak;\n\t}\n\tsolAssert(false, \"\");\n\treturn \"\";\n}\n\nstd::string ReferenceType::identifierLocationSuffix() const\n{\n\tstd::string id;\n\tswitch (location())\n\t{\n\tcase DataLocation::Storage:\n\t\tid += \"_storage\";\n\t\tbreak;\n\tcase DataLocation::Transient:\n\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\tbreak;\n\tcase DataLocation::Memory:\n\t\tid += \"_memory\";\n\t\tbreak;\n\tcase DataLocation::CallData:\n\t\tid += \"_calldata\";\n\t\tbreak;\n\t}\n\tif (isPointer())\n\t\tid += \"_ptr\";\n\treturn id;\n}\n\nArrayType::ArrayType(DataLocation _location, bool _isString):\n\tReferenceType(_location),\n\tm_arrayKind(_isString ? ArrayKind::String : ArrayKind::Bytes),\n\tm_baseType{TypeProvider::byte()}\n{\n}\n\nvoid ArrayType::clearCache() const\n{\n\tType::clearCache();\n\n\tm_interfaceType.reset();\n\tm_interfaceType_library.reset();\n}\n\nBoolResult ArrayType::isImplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (_convertTo.category() != category())\n\t\treturn false;\n\tauto& convertTo = dynamic_cast<ArrayType const&>(_convertTo);\n\tif (convertTo.isByteArray() != isByteArray() || convertTo.isString() != isString())\n\t\treturn false;\n\t// memory/calldata to storage can be converted, but only to a direct storage reference\n\tif (convertTo.location() == DataLocation::Storage && location() != DataLocation::Storage && convertTo.isPointer())\n\t\treturn false;\n\tif (convertTo.location() == DataLocation::CallData && location() != convertTo.location())\n\t\treturn false;\n\tif (convertTo.location() == DataLocation::Storage && !convertTo.isPointer())\n\t{\n\t\t// Less restrictive conversion, since we need to copy anyway.\n\t\tif (!baseType()->isImplicitlyConvertibleTo(*convertTo.baseType()))\n\t\t\treturn false;\n\t\tif (convertTo.isDynamicallySized())\n\t\t\treturn true;\n\t\treturn !isDynamicallySized() && convertTo.length() >= length();\n\t}\n\telse\n\t{\n\t\t// Conversion to storage pointer or to memory, we do not copy element-for-element here, so\n\t\t// require that the base type is the same, not only convertible.\n\t\t// This disallows assignment of nested dynamic arrays from storage to memory for now.\n\t\tif (\n\t\t\t*TypeProvider::withLocationIfReference(location(), baseType()) !=\n\t\t\t*TypeProvider::withLocationIfReference(location(), convertTo.baseType())\n\t\t)\n\t\t\treturn false;\n\t\tif (isDynamicallySized() != convertTo.isDynamicallySized())\n\t\t\treturn false;\n\t\t// We also require that the size is the same.\n\t\tif (!isDynamicallySized() && length() != convertTo.length())\n\t\t\treturn false;\n\t\treturn true;\n\t}\n}\n\nBoolResult ArrayType::isExplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (isImplicitlyConvertibleTo(_convertTo))\n\t\treturn true;\n\t// allow conversion bytes <-> std::string and bytes -> bytesNN\n\tif (_convertTo.category() != category())\n\t\treturn isByteArray() && _convertTo.category() == Type::Category::FixedBytes;\n\tauto& convertTo = dynamic_cast<ArrayType const&>(_convertTo);\n\tif (convertTo.location() != location())\n\t\treturn false;\n\tif (!isByteArrayOrString() || !convertTo.isByteArrayOrString())\n\t\treturn false;\n\treturn true;\n}\n\nstd::string ArrayType::richIdentifier() const\n{\n\tstd::string id;\n\tif (isString())\n\t\tid = \"t_string\";\n\telse if (isByteArrayOrString())\n\t\tid = \"t_bytes\";\n\telse\n\t{\n\t\tid = \"t_array\";\n\t\tid += identifierList(baseType());\n\t\tif (isDynamicallySized())\n\t\t\tid += \"dyn\";\n\t\telse\n\t\t\tid += length().str();\n\t}\n\tid += identifierLocationSuffix();\n\n\treturn id;\n}\n\nbool ArrayType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\treturn *this == dynamic_cast<ArrayType const&>(_other);\n}\n\nbool ArrayType::operator==(ArrayType const& _other) const\n{\n\tif (\n\t\t!equals(_other) ||\n\t\t_other.isByteArray() != isByteArray() ||\n\t\t_other.isString() != isString() ||\n\t\t_other.isDynamicallySized() != isDynamicallySized()\n\t)\n\t\treturn false;\n\tif (*_other.baseType() != *baseType())\n\t\treturn false;\n\treturn isDynamicallySized() || length() == _other.length();\n}\n\nBoolResult ArrayType::validForLocation(DataLocation _loc) const\n{\n\tif (auto arrayBaseType = dynamic_cast<ArrayType const*>(baseType()))\n\t{\n\t\tBoolResult result = arrayBaseType->validForLocation(_loc);\n\t\tif (!result)\n\t\t\treturn result;\n\t}\n\tif (isDynamicallySized())\n\t\treturn true;\n\tswitch (_loc)\n\t{\n\t\tcase DataLocation::Memory:\n\t\t{\n\t\t\tbigint size = bigint(length());\n\t\t\tauto type = m_baseType;\n\t\t\twhile (auto arrayType = dynamic_cast<ArrayType const*>(type))\n\t\t\t{\n\t\t\t\tif (arrayType->isDynamicallySized())\n\t\t\t\t\tbreak;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsize *= arrayType->length();\n\t\t\t\t\ttype = arrayType->baseType();\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (type->isDynamicallySized())\n\t\t\t\tsize *= type->memoryHeadSize();\n\t\t\telse\n\t\t\t\tsize *= type->memoryDataSize();\n\t\t\tif (size >= std::numeric_limits<unsigned>::max())\n\t\t\t\treturn BoolResult::err(\"Type too large for memory.\");\n\t\t\tbreak;\n\t\t}\n\t\tcase DataLocation::CallData:\n\t\t{\n\t\t\tif (unlimitedStaticCalldataSize(true) >= std::numeric_limits<unsigned>::max())\n\t\t\t\treturn BoolResult::err(\"Type too large for calldata.\");\n\t\t\tbreak;\n\t\t}\n\t\tcase DataLocation::Storage:\n\t\t\tif (storageSizeUpperBound() >= bigint(1) << 256)\n\t\t\t\treturn BoolResult::err(\"Type too large for storage.\");\n\t\t\tbreak;\n\t\tcase DataLocation::Transient:\n\t\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\t\tbreak;\n\t}\n\treturn true;\n}\n\nbigint ArrayType::unlimitedStaticCalldataSize(bool _padded) const\n{\n\tsolAssert(!isDynamicallySized(), \"\");\n\tbigint size = bigint(length()) * calldataStride();\n\tif (_padded)\n\t\tsize = ((size + 31) / 32) * 32;\n\treturn size;\n}\n\nunsigned ArrayType::calldataEncodedSize(bool _padded) const\n{\n\tsolAssert(!isDynamicallyEncoded(), \"\");\n\tbigint size = unlimitedStaticCalldataSize(_padded);\n\tsolAssert(size <= std::numeric_limits<unsigned>::max(), \"Array size does not fit unsigned.\");\n\treturn unsigned(size);\n}\n\nunsigned ArrayType::calldataEncodedTailSize() const\n{\n\tsolAssert(isDynamicallyEncoded(), \"\");\n\tif (isDynamicallySized())\n\t\t// We do not know the dynamic length itself, but at least the uint256 containing the\n\t\t// length must still be present.\n\t\treturn 32;\n\tbigint size = unlimitedStaticCalldataSize(false);\n\tsolAssert(size <= std::numeric_limits<unsigned>::max(), \"Array size does not fit unsigned.\");\n\treturn unsigned(size);\n}\n\nbool ArrayType::isDynamicallyEncoded() const\n{\n\treturn isDynamicallySized() || baseType()->isDynamicallyEncoded();\n}\n\nbigint ArrayType::storageSizeUpperBound() const\n{\n\tif (isDynamicallySized())\n\t\treturn 1;\n\telse\n\t\treturn length() * baseType()->storageSizeUpperBound();\n}\n\nu256 ArrayType::storageSize() const\n{\n\tif (isDynamicallySized())\n\t\treturn 1;\n\n\tbigint size;\n\tunsigned baseBytes = baseType()->storageBytes();\n\tif (baseBytes == 0)\n\t\tsize = 1;\n\telse if (baseBytes < 32)\n\t{\n\t\tunsigned itemsPerSlot = 32 / baseBytes;\n\t\tsize = (bigint(length()) + (itemsPerSlot - 1)) / itemsPerSlot;\n\t}\n\telse\n\t\tsize = bigint(length()) * baseType()->storageSize();\n\tsolAssert(size < bigint(1) << 256, \"Array too large for storage.\");\n\treturn std::max<u256>(1, u256(size));\n}\n\nstd::vector<std::tuple<std::string, Type const*>> ArrayType::makeStackItems() const\n{\n\tswitch (m_location)\n\t{\n\t\tcase DataLocation::CallData:\n\t\t\tif (isDynamicallySized())\n\t\t\t\treturn {std::make_tuple(\"offset\", TypeProvider::uint256()), std::make_tuple(\"length\", TypeProvider::uint256())};\n\t\t\telse\n\t\t\t\treturn {std::make_tuple(\"offset\", TypeProvider::uint256())};\n\t\tcase DataLocation::Memory:\n\t\t\treturn {std::make_tuple(\"mpos\", TypeProvider::uint256())};\n\t\tcase DataLocation::Storage:\n\t\t\t// byte offset inside storage value is omitted\n\t\t\treturn {std::make_tuple(\"slot\", TypeProvider::uint256())};\n\t\tcase DataLocation::Transient:\n\t\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\t\tbreak;\n\t}\n\tsolAssert(false, \"\");\n}\n\nstd::string ArrayType::toString(bool _withoutDataLocation) const\n{\n\tstd::string ret;\n\tif (isString())\n\t\tret = \"string\";\n\telse if (isByteArrayOrString())\n\t\tret = \"bytes\";\n\telse\n\t{\n\t\tret = baseType()->toString(_withoutDataLocation) + \"[\";\n\t\tif (!isDynamicallySized())\n\t\t\tret += length().str();\n\t\tret += \"]\";\n\t}\n\tif (!_withoutDataLocation)\n\t\tret += \" \" + stringForReferencePart();\n\treturn ret;\n}\n\nstd::string ArrayType::humanReadableName() const\n{\n\tstd::string ret;\n\tif (isString())\n\t\tret = \"string\";\n\telse if (isByteArrayOrString())\n\t\tret = \"bytes\";\n\telse\n\t{\n\t\tret = baseType()->toString(true) + \"[\";\n\t\tif (!isDynamicallySized())\n\t\t\tret += length().str();\n\t\tret += \"]\";\n\t}\n\tret += \" \" + stringForReferencePart();\n\treturn ret;\n}\n\nstd::string ArrayType::canonicalName() const\n{\n\tstd::string ret;\n\tif (isString())\n\t\tret = \"string\";\n\telse if (isByteArrayOrString())\n\t\tret = \"bytes\";\n\telse\n\t{\n\t\tret = baseType()->canonicalName() + \"[\";\n\t\tif (!isDynamicallySized())\n\t\t\tret += length().str();\n\t\tret += \"]\";\n\t}\n\treturn ret;\n}\n\nstd::string ArrayType::signatureInExternalFunction(bool _structsByName) const\n{\n\tif (isByteArrayOrString())\n\t\treturn canonicalName();\n\telse\n\t{\n\t\tsolAssert(baseType(), \"\");\n\t\treturn\n\t\t\tbaseType()->signatureInExternalFunction(_structsByName) +\n\t\t\t\"[\" +\n\t\t\t(isDynamicallySized() ? \"\" : length().str()) +\n\t\t\t\"]\";\n\t}\n}\n\nMemberList::MemberMap ArrayType::nativeMembers(ASTNode const*) const\n{\n\tMemberList::MemberMap members;\n\tif (!isString())\n\t{\n\t\tmembers.emplace_back(\"length\", TypeProvider::uint256());\n\t\tif (isDynamicallySized() && location() == DataLocation::Storage)\n\t\t{\n\t\t\tType const* thisAsPointer = TypeProvider::withLocation(this, location(), true);\n\t\t\tmembers.emplace_back(\"push\", TypeProvider::function(\n\t\t\t\tTypePointers{thisAsPointer},\n\t\t\t\tTypePointers{baseType()},\n\t\t\t\tstrings{std::string()},\n\t\t\t\tstrings{std::string()},\n\t\t\t\tFunctionType::Kind::ArrayPush\n\t\t\t)->withBoundFirstArgument());\n\t\t\tmembers.emplace_back(\"push\", TypeProvider::function(\n\t\t\t\tTypePointers{thisAsPointer, baseType()},\n\t\t\t\tTypePointers{},\n\t\t\t\tstrings{std::string(),std::string()},\n\t\t\t\tstrings{},\n\t\t\t\tFunctionType::Kind::ArrayPush\n\t\t\t)->withBoundFirstArgument());\n\t\t\tmembers.emplace_back(\"pop\", TypeProvider::function(\n\t\t\t\tTypePointers{thisAsPointer},\n\t\t\t\tTypePointers{},\n\t\t\t\tstrings{std::string()},\n\t\t\t\tstrings{},\n\t\t\t\tFunctionType::Kind::ArrayPop\n\t\t\t)->withBoundFirstArgument());\n\t\t}\n\t}\n\treturn members;\n}\n\nType const* ArrayType::encodingType() const\n{\n\tif (location() == DataLocation::Storage)\n\t\treturn TypeProvider::uint256();\n\telse\n\t\treturn TypeProvider::withLocation(this, DataLocation::Memory, true);\n}\n\nType const* ArrayType::decodingType() const\n{\n\tif (location() == DataLocation::Storage)\n\t\treturn TypeProvider::uint256();\n\telse\n\t\treturn this;\n}\n\nTypeResult ArrayType::interfaceType(bool _inLibrary) const\n{\n\tif (_inLibrary && m_interfaceType_library.has_value())\n\t\treturn *m_interfaceType_library;\n\n\tif (!_inLibrary && m_interfaceType.has_value())\n\t\treturn *m_interfaceType;\n\n\tTypeResult result{nullptr};\n\tTypeResult baseInterfaceType = m_baseType->interfaceType(_inLibrary);\n\n\tif (!baseInterfaceType.get())\n\t{\n\t\tsolAssert(!baseInterfaceType.message().empty(), \"Expected detailed error message!\");\n\t\tresult = baseInterfaceType;\n\t}\n\telse if (_inLibrary && location() == DataLocation::Storage)\n\t\tresult = this;\n\telse if (m_arrayKind != ArrayKind::Ordinary)\n\t\tresult = TypeProvider::withLocation(this, DataLocation::Memory, true);\n\telse if (isDynamicallySized())\n\t\tresult = TypeProvider::array(DataLocation::Memory, baseInterfaceType);\n\telse\n\t\tresult = TypeProvider::array(DataLocation::Memory, baseInterfaceType, m_length);\n\n\tif (_inLibrary)\n\t\tm_interfaceType_library = result;\n\telse\n\t\tm_interfaceType = result;\n\n\treturn result;\n}\n\nType const* ArrayType::finalBaseType(bool _breakIfDynamicArrayType) const\n{\n\tType const* finalBaseType = this;\n\n\twhile (auto arrayType = dynamic_cast<ArrayType const*>(finalBaseType))\n\t{\n\t\tif (_breakIfDynamicArrayType && arrayType->isDynamicallySized())\n\t\t\tbreak;\n\t\tfinalBaseType = arrayType->baseType();\n\t}\n\n\treturn finalBaseType;\n}\n\nu256 ArrayType::memoryDataSize() const\n{\n\tsolAssert(!isDynamicallySized(), \"\");\n\tsolAssert(m_location == DataLocation::Memory, \"\");\n\tsolAssert(!isByteArrayOrString(), \"\");\n\tbigint size = bigint(m_length) * m_baseType->memoryHeadSize();\n\tsolAssert(size <= std::numeric_limits<u256>::max(), \"Array size does not fit u256.\");\n\treturn u256(size);\n}\n\nstd::unique_ptr<ReferenceType> ArrayType::copyForLocation(DataLocation _location, bool _isPointer) const\n{\n\tauto copy = std::make_unique<ArrayType>(_location);\n\tif (_location == DataLocation::Storage)\n\t\tcopy->m_isPointer = _isPointer;\n\tcopy->m_arrayKind = m_arrayKind;\n\tcopy->m_baseType = copy->copyForLocationIfReference(m_baseType);\n\tcopy->m_hasDynamicLength = m_hasDynamicLength;\n\tcopy->m_length = m_length;\n\treturn copy;\n}\n\nBoolResult ArraySliceType::isImplicitlyConvertibleTo(Type const& _other) const\n{\n\treturn\n\t\t(*this) == _other ||\n\t\t(\n\t\t\tm_arrayType.dataStoredIn(DataLocation::CallData) &&\n\t\t\tm_arrayType.isDynamicallySized() &&\n\t\t\tm_arrayType.isImplicitlyConvertibleTo(_other)\n\t\t);\n}\n\nBoolResult ArraySliceType::isExplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\treturn\n\t\tisImplicitlyConvertibleTo(_convertTo) ||\n\t\tm_arrayType.isExplicitlyConvertibleTo(_convertTo);\n}\n\nstd::string ArraySliceType::richIdentifier() const\n{\n\treturn m_arrayType.richIdentifier() + \"_slice\";\n}\n\nbool ArraySliceType::operator==(Type const& _other) const\n{\n\tif (auto const* other = dynamic_cast<ArraySliceType const*>(&_other))\n\t\treturn m_arrayType == other->m_arrayType;\n\treturn false;\n}\n\nstd::string ArraySliceType::toString(bool _withoutDataLocation) const\n{\n\treturn m_arrayType.toString(_withoutDataLocation) + \" slice\";\n}\n\nstd::string ArraySliceType::humanReadableName() const\n{\n\treturn m_arrayType.humanReadableName() + \" slice\";\n}\n\nType const* ArraySliceType::mobileType() const\n{\n\tif (\n\t\tm_arrayType.dataStoredIn(DataLocation::CallData) &&\n\t\tm_arrayType.isDynamicallySized() &&\n\t\t!m_arrayType.baseType()->isDynamicallyEncoded()\n\t)\n\t\treturn &m_arrayType;\n\telse\n\t\treturn this;\n}\n\n\nstd::vector<std::tuple<std::string, Type const*>> ArraySliceType::makeStackItems() const\n{\n\treturn {{\"offset\", TypeProvider::uint256()}, {\"length\", TypeProvider::uint256()}};\n}\n\nstd::string ContractType::richIdentifier() const\n{\n\treturn (m_super ? \"t_super\" : \"t_contract\") + parenthesizeUserIdentifier(m_contract.name()) + std::to_string(m_contract.id());\n}\n\nbool ContractType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tContractType const& other = dynamic_cast<ContractType const&>(_other);\n\treturn other.m_contract == m_contract && other.m_super == m_super;\n}\n\nstd::string ContractType::toString(bool) const\n{\n\treturn\n\t\tstd::string(m_contract.isLibrary() ? \"library \" : \"contract \") +\n\t\tstd::string(m_super ? \"super \" : \"\") +\n\t\tm_contract.name();\n}\n\nstd::string ContractType::canonicalName() const\n{\n\treturn *m_contract.annotation().canonicalName;\n}\n\nMemberList::MemberMap ContractType::nativeMembers(ASTNode const*) const\n{\n\tMemberList::MemberMap members;\n\tsolAssert(!m_super, \"\");\n\tif (!m_contract.isLibrary())\n\t\tfor (auto const& it: m_contract.interfaceFunctions())\n\t\t\tmembers.emplace_back(\n\t\t\t\t&it.second->declaration(),\n\t\t\t\tit.second->asExternallyCallableFunction(m_contract.isLibrary())\n\t\t\t);\n\n\treturn members;\n}\n\nFunctionType const* ContractType::newExpressionType() const\n{\n\tif (!m_constructorType)\n\t\tm_constructorType = FunctionType::newExpressionType(m_contract);\n\treturn m_constructorType;\n}\n\nstd::vector<std::tuple<VariableDeclaration const*, u256, unsigned>> ContractType::linearizedStateVariables(DataLocation _location) const\n{\n\tVariableDeclaration::Location location;\n\tswitch (_location)\n\t{\n\tcase DataLocation::Storage:\n\t\tlocation = VariableDeclaration::Location::Unspecified;\n\t\tbreak;\n\tcase DataLocation::Transient:\n\t\tlocation = VariableDeclaration::Location::Transient;\n\t\tbreak;\n\tdefault:\n\t\tsolAssert(false);\n\t}\n\n\tstd::vector<VariableDeclaration const*> variables;\n\tfor (ContractDefinition const* contract: m_contract.annotation().linearizedBaseContracts | ranges::views::reverse)\n\t\tfor (VariableDeclaration const* variable: contract->stateVariables())\n\t\t\tif (!(variable->isConstant() || variable->immutable()) && variable->referenceLocation() == location)\n\t\t\t\tvariables.push_back(variable);\n\n\tTypePointers types;\n\tfor (auto variable: variables)\n\t\ttypes.push_back(variable->annotation().type);\n\tStorageOffsets offsets;\n\toffsets.computeOffsets(types, layoutBaseForInheritanceHierarchy(m_contract, _location));\n\n\tstd::vector<std::tuple<VariableDeclaration const*, u256, unsigned>> variablesAndOffsets;\n\tfor (size_t index = 0; index < variables.size(); ++index)\n\t\tif (auto const* offset = offsets.offset(index))\n\t\t\tvariablesAndOffsets.emplace_back(variables[index], offset->first, offset->second);\n\treturn variablesAndOffsets;\n}\n\nstd::vector<VariableDeclaration const*> ContractType::immutableVariables() const\n{\n\tstd::vector<VariableDeclaration const*> variables;\n\tfor (ContractDefinition const* contract: m_contract.annotation().linearizedBaseContracts | ranges::views::reverse)\n\t\tfor (VariableDeclaration const* variable: contract->stateVariables())\n\t\t\tif (variable->immutable())\n\t\t\t\tvariables.push_back(variable);\n\treturn variables;\n}\n\nstd::vector<std::tuple<std::string, Type const*>> ContractType::makeStackItems() const\n{\n\tif (m_super)\n\t\treturn {};\n\telse\n\t\treturn {std::make_tuple(\"address\", isPayable() ? TypeProvider::payableAddress() : TypeProvider::address())};\n}\n\nvoid StructType::clearCache() const\n{\n\tType::clearCache();\n\n\tm_interfaceType.reset();\n\tm_interfaceType_library.reset();\n}\n\nType const* StructType::encodingType() const\n{\n\tif (location() != DataLocation::Storage)\n\t\treturn this;\n\n\treturn TypeProvider::uint256();\n}\n\nBoolResult StructType::isImplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (_convertTo.category() != category())\n\t\treturn false;\n\tauto& convertTo = dynamic_cast<StructType const&>(_convertTo);\n\t// memory/calldata to storage can be converted, but only to a direct storage reference\n\tif (convertTo.location() == DataLocation::Storage && location() != DataLocation::Storage && convertTo.isPointer())\n\t\treturn false;\n\tif (convertTo.location() == DataLocation::CallData && location() != convertTo.location())\n\t\treturn false;\n\treturn this->m_struct == convertTo.m_struct;\n}\n\nstd::string StructType::richIdentifier() const\n{\n\treturn \"t_struct\" + parenthesizeUserIdentifier(m_struct.name()) + std::to_string(m_struct.id()) + identifierLocationSuffix();\n}\n\nbool StructType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tStructType const& other = dynamic_cast<StructType const&>(_other);\n\treturn equals(other) && other.m_struct == m_struct;\n}\n\n\nunsigned StructType::calldataEncodedSize(bool) const\n{\n\tsolAssert(!isDynamicallyEncoded(), \"\");\n\n\tunsigned size = 0;\n\tfor (auto const& member: members(nullptr))\n\t{\n\t\tsolAssert(!member.type->containsNestedMapping(), \"\");\n\t\t// Struct members are always padded.\n\t\tsize += member.type->calldataEncodedSize();\n\t}\n\treturn size;\n}\n\n\nunsigned StructType::calldataEncodedTailSize() const\n{\n\tsolAssert(isDynamicallyEncoded(), \"\");\n\n\tunsigned size = 0;\n\tfor (auto const& member: members(nullptr))\n\t{\n\t\tsolAssert(!member.type->containsNestedMapping(), \"\");\n\t\t// Struct members are always padded.\n\t\tsize += member.type->calldataHeadSize();\n\t}\n\treturn size;\n}\n\nunsigned StructType::calldataOffsetOfMember(std::string const& _member) const\n{\n\tunsigned offset = 0;\n\tfor (auto const& member: members(nullptr))\n\t{\n\t\tsolAssert(!member.type->containsNestedMapping(), \"\");\n\t\tif (member.name == _member)\n\t\t\treturn offset;\n\t\t// Struct members are always padded.\n\t\toffset += member.type->calldataHeadSize();\n\t}\n\tsolAssert(false, \"Struct member not found.\");\n}\n\nbool StructType::isDynamicallyEncoded() const\n{\n\tif (recursive())\n\t\treturn true;\n\tsolAssert(interfaceType(false).get(), \"\");\n\tfor (auto t: memoryMemberTypes())\n\t{\n\t\tsolAssert(t, \"Parameter should have external type.\");\n\t\tt = t->interfaceType(false);\n\t\tif (t->isDynamicallyEncoded())\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\nu256 StructType::memoryDataSize() const\n{\n\tu256 size;\n\tfor (auto const& t: memoryMemberTypes())\n\t\tsize += t->memoryHeadSize();\n\treturn size;\n}\n\nbigint StructType::storageSizeUpperBound() const\n{\n\tbigint size = 1;\n\tfor (auto const& member: members(nullptr))\n\t\tsize += member.type->storageSizeUpperBound();\n\treturn size;\n}\n\nu256 StructType::storageSize() const\n{\n\treturn std::max<u256>(1, members(nullptr).storageSize());\n}\n\nbool StructType::containsNestedMapping() const\n{\n\tif (!m_struct.annotation().containsNestedMapping.has_value())\n\t{\n\t\tbool hasNestedMapping = false;\n\n\t\tutil::BreadthFirstSearch<StructDefinition const*> breadthFirstSearch{{&m_struct}};\n\n\t\tbreadthFirstSearch.run(\n\t\t\t[&](StructDefinition const* _struct, auto&& _addChild)\n\t\t\t{\n\t\t\t\tfor (auto const& member: _struct->members())\n\t\t\t\t{\n\t\t\t\t\tType const* memberType = member->annotation().type;\n\t\t\t\t\tsolAssert(memberType, \"\");\n\n\t\t\t\t\tif (auto arrayType = dynamic_cast<ArrayType const*>(memberType))\n\t\t\t\t\t\tmemberType = arrayType->finalBaseType(false);\n\n\t\t\t\t\tif (dynamic_cast<MappingType const*>(memberType))\n\t\t\t\t\t{\n\t\t\t\t\t\thasNestedMapping = true;\n\t\t\t\t\t\tbreadthFirstSearch.abort();\n\t\t\t\t\t}\n\t\t\t\t\telse if (auto structType = dynamic_cast<StructType const*>(memberType))\n\t\t\t\t\t\t_addChild(&structType->structDefinition());\n\t\t\t\t}\n\n\t\t\t});\n\n\t\tm_struct.annotation().containsNestedMapping = hasNestedMapping;\n\t}\n\n\treturn m_struct.annotation().containsNestedMapping.value();\n}\n\nstd::string StructType::toString(bool _withoutDataLocation) const\n{\n\tstd::string ret = \"struct \" + *m_struct.annotation().canonicalName;\n\tif (!_withoutDataLocation)\n\t\tret += \" \" + stringForReferencePart();\n\treturn ret;\n}\n\nMemberList::MemberMap StructType::nativeMembers(ASTNode const*) const\n{\n\tMemberList::MemberMap members;\n\tfor (ASTPointer<VariableDeclaration> const& variable: m_struct.members())\n\t{\n\t\tType const* type = variable->annotation().type;\n\t\tsolAssert(type, \"\");\n\t\tsolAssert(!(location() != DataLocation::Storage && type->containsNestedMapping()), \"\");\n\t\tmembers.emplace_back(\n\t\t\tvariable.get(),\n\t\t\tcopyForLocationIfReference(type)\n\t\t);\n\t}\n\treturn members;\n}\n\nTypeResult StructType::interfaceType(bool _inLibrary) const\n{\n\tif (!_inLibrary)\n\t{\n\t\tif (!m_interfaceType.has_value())\n\t\t{\n\t\t\tif (recursive())\n\t\t\t\tm_interfaceType = TypeResult::err(\"Recursive type not allowed for public or external contract functions.\");\n\t\t\telse\n\t\t\t{\n\t\t\t\tTypeResult result{nullptr};\n\t\t\t\tfor (ASTPointer<VariableDeclaration> const& member: m_struct.members())\n\t\t\t\t{\n\t\t\t\t\tif (!member->annotation().type)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = TypeResult::err(\"Invalid type!\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tauto interfaceType = member->annotation().type->interfaceType(false);\n\t\t\t\t\tif (!interfaceType.get())\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(!interfaceType.message().empty(), \"Expected detailed error message!\");\n\t\t\t\t\t\tresult = interfaceType;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (result.message().empty())\n\t\t\t\t\tm_interfaceType = TypeProvider::withLocation(this, DataLocation::Memory, true);\n\t\t\t\telse\n\t\t\t\t\tm_interfaceType = result;\n\t\t\t}\n\t\t}\n\t\treturn *m_interfaceType;\n\t}\n\telse if (m_interfaceType_library.has_value())\n\t\treturn *m_interfaceType_library;\n\n\tTypeResult result{nullptr};\n\n\tif (recursive() && !(_inLibrary && location() == DataLocation::Storage))\n\t\treturn TypeResult::err(\n\t\t\t\"Recursive structs can only be passed as storage pointers to libraries, \"\n\t\t\t\"not as memory objects to contract functions.\"\n\t\t);\n\n\tutil::BreadthFirstSearch<StructDefinition const*> breadthFirstSearch{{&m_struct}};\n\tbreadthFirstSearch.run(\n\t\t[&](StructDefinition const* _struct, auto&& _addChild)\n\t\t{\n\t\t\t// Check that all members have interface types.\n\t\t\t// Return an error if at least one struct member does not have a type.\n\t\t\t// This might happen, for example, if the type of the member does not exist.\n\t\t\tfor (ASTPointer<VariableDeclaration> const& variable: _struct->members())\n\t\t\t{\n\t\t\t\t// If the struct member does not have a type return false.\n\t\t\t\t// A TypeError is expected in this case.\n\t\t\t\tif (!variable->annotation().type)\n\t\t\t\t{\n\t\t\t\t\tresult = TypeResult::err(\"Invalid type!\");\n\t\t\t\t\tbreadthFirstSearch.abort();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tType const* memberType = variable->annotation().type;\n\n\t\t\t\twhile (\n\t\t\t\t\tmemberType->category() == Type::Category::Array ||\n\t\t\t\t\tmemberType->category() == Type::Category::Mapping\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tif (auto arrayType = dynamic_cast<ArrayType const*>(memberType))\n\t\t\t\t\t\tmemberType = arrayType->finalBaseType(false);\n\t\t\t\t\telse if (auto mappingType = dynamic_cast<MappingType const*>(memberType))\n\t\t\t\t\t\tmemberType = mappingType->valueType();\n\t\t\t\t}\n\n\t\t\t\tif (StructType const* innerStruct = dynamic_cast<StructType const*>(memberType))\n\t\t\t\t\t_addChild(&innerStruct->structDefinition());\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tauto iType = memberType->interfaceType(_inLibrary);\n\t\t\t\t\tif (!iType.get())\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(!iType.message().empty(), \"Expected detailed error message!\");\n\t\t\t\t\t\tresult = iType;\n\t\t\t\t\t\tbreadthFirstSearch.abort();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t);\n\n\tif (!result.message().empty())\n\t\treturn result;\n\n\tif (location() == DataLocation::Storage)\n\t\tm_interfaceType_library = this;\n\telse\n\t\tm_interfaceType_library = TypeProvider::withLocation(this, DataLocation::Memory, true);\n\treturn *m_interfaceType_library;\n}\n\nDeclaration const* StructType::typeDefinition() const\n{\n\treturn &structDefinition();\n}\n\nBoolResult StructType::validForLocation(DataLocation _loc) const\n{\n\tfor (auto const& member: m_struct.members())\n\t\tif (auto referenceType = dynamic_cast<ReferenceType const*>(member->annotation().type))\n\t\t{\n\t\t\tBoolResult result = referenceType->validForLocation(_loc);\n\t\t\tif (!result)\n\t\t\t\treturn result;\n\t\t}\n\n\tif (\n\t\t_loc == DataLocation::Storage &&\n\t\tstorageSizeUpperBound() >= bigint(1) << 256\n\t)\n\t\treturn BoolResult::err(\"Type too large for storage.\");\n\n\treturn true;\n}\n\nbool StructType::recursive() const\n{\n\tsolAssert(m_struct.annotation().recursive.has_value(), \"Called StructType::recursive() before DeclarationTypeChecker.\");\n\treturn *m_struct.annotation().recursive;\n}\n\nstd::unique_ptr<ReferenceType> StructType::copyForLocation(DataLocation _location, bool _isPointer) const\n{\n\tauto copy = std::make_unique<StructType>(m_struct, _location);\n\tif (_location == DataLocation::Storage)\n\t\tcopy->m_isPointer = _isPointer;\n\treturn copy;\n}\n\nstd::string StructType::signatureInExternalFunction(bool _structsByName) const\n{\n\tif (_structsByName)\n\t\treturn canonicalName();\n\telse\n\t{\n\t\tTypePointers memberTypes = memoryMemberTypes();\n\t\tauto memberTypeStrings = memberTypes | ranges::views::transform([&](Type const* _t) -> std::string\n\t\t{\n\t\t\tsolAssert(_t, \"Parameter should have external type.\");\n\t\t\tauto t = _t->interfaceType(_structsByName);\n\t\t\tsolAssert(t.get(), \"\");\n\t\t\treturn t.get()->signatureInExternalFunction(_structsByName);\n\t\t});\n\t\treturn \"(\" + boost::algorithm::join(memberTypeStrings, \",\") + \")\";\n\t}\n}\n\nstd::string StructType::canonicalName() const\n{\n\treturn *m_struct.annotation().canonicalName;\n}\n\nFunctionTypePointer StructType::constructorType() const\n{\n\tTypePointers paramTypes;\n\tstrings paramNames;\n\tsolAssert(!containsNestedMapping(), \"\");\n\tfor (auto const& member: members(nullptr))\n\t{\n\t\tparamNames.push_back(member.name);\n\t\tparamTypes.push_back(TypeProvider::withLocationIfReference(DataLocation::Memory, member.type));\n\t}\n\treturn TypeProvider::function(\n\t\tparamTypes,\n\t\tTypePointers{TypeProvider::withLocation(this, DataLocation::Memory, false)},\n\t\tparamNames,\n\t\tstrings(1, \"\"),\n\t\tFunctionType::Kind::Internal\n\t);\n}\n\nstd::pair<u256, unsigned> const& StructType::storageOffsetsOfMember(std::string const& _name) const\n{\n\tauto const* offsets = members(nullptr).memberStorageOffset(_name);\n\tsolAssert(offsets, \"Storage offset of non-existing member requested.\");\n\treturn *offsets;\n}\n\nu256 StructType::memoryOffsetOfMember(std::string const& _name) const\n{\n\tu256 offset;\n\tfor (auto const& member: members(nullptr))\n\t\tif (member.name == _name)\n\t\t\treturn offset;\n\t\telse\n\t\t\toffset += member.type->memoryHeadSize();\n\tsolAssert(false, \"Member not found in struct.\");\n\treturn 0;\n}\n\nTypePointers StructType::memoryMemberTypes() const\n{\n\tsolAssert(!containsNestedMapping(), \"\");\n\tTypePointers types;\n\tfor (ASTPointer<VariableDeclaration> const& variable: m_struct.members())\n\t\ttypes.push_back(TypeProvider::withLocationIfReference(DataLocation::Memory, variable->annotation().type));\n\n\treturn types;\n}\n\nstd::vector<std::tuple<std::string, Type const*>> StructType::makeStackItems() const\n{\n\tswitch (m_location)\n\t{\n\t\tcase DataLocation::CallData:\n\t\t\treturn {std::make_tuple(\"offset\", TypeProvider::uint256())};\n\t\tcase DataLocation::Memory:\n\t\t\treturn {std::make_tuple(\"mpos\", TypeProvider::uint256())};\n\t\tcase DataLocation::Storage:\n\t\t\treturn {std::make_tuple(\"slot\", TypeProvider::uint256())};\n\t\tcase DataLocation::Transient:\n\t\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\t\tbreak;\n\t}\n\tsolAssert(false, \"\");\n}\n\nstd::vector<Type const*> StructType::decomposition() const\n{\n\tstd::vector<Type const*> res;\n\tfor (MemberList::Member const& member: members(nullptr))\n\t\tres.push_back(member.type);\n\treturn res;\n}\n\nType const* EnumType::encodingType() const\n{\n\tsolAssert(numberOfMembers() <= 256, \"\");\n\treturn TypeProvider::uint(8);\n}\n\nDeclaration const* EnumType::typeDefinition() const\n{\n\treturn &enumDefinition();\n}\n\nTypeResult EnumType::unaryOperatorResult(Token _operator) const\n{\n\treturn _operator == Token::Delete ? TypeProvider::emptyTuple() : nullptr;\n}\n\nstd::string EnumType::richIdentifier() const\n{\n\treturn \"t_enum\" + parenthesizeUserIdentifier(m_enum.name()) + std::to_string(m_enum.id());\n}\n\nbool EnumType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tEnumType const& other = dynamic_cast<EnumType const&>(_other);\n\treturn other.m_enum == m_enum;\n}\n\nunsigned EnumType::storageBytes() const\n{\n\tsolAssert(numberOfMembers() <= 256, \"\");\n\treturn 1;\n}\n\nstd::string EnumType::toString(bool) const\n{\n\treturn std::string(\"enum \") + *m_enum.annotation().canonicalName;\n}\n\nstd::string EnumType::canonicalName() const\n{\n\treturn *m_enum.annotation().canonicalName;\n}\n\nsize_t EnumType::numberOfMembers() const\n{\n\treturn m_enum.members().size();\n}\n\nBoolResult EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (_convertTo == *this)\n\t\treturn true;\n\telse if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))\n\t\treturn !integerType->isSigned();\n\treturn false;\n}\n\nunsigned EnumType::memberValue(ASTString const& _member) const\n{\n\tunsigned index = 0;\n\tfor (ASTPointer<EnumValue> const& decl: m_enum.members())\n\t{\n\t\tif (decl->name() == _member)\n\t\t\treturn index;\n\t\t++index;\n\t}\n\tsolAssert(false, \"Requested unknown enum value \" + _member);\n}\n\nType const& UserDefinedValueType::underlyingType() const\n{\n\tType const* type = m_definition.underlyingType()->annotation().type;\n\tsolAssert(type, \"\");\n\tsolAssert(type->category() != Category::UserDefinedValueType, \"\");\n\treturn *type;\n}\n\nDeclaration const* UserDefinedValueType::typeDefinition() const\n{\n\treturn &m_definition;\n}\n\nstd::string UserDefinedValueType::richIdentifier() const\n{\n\treturn \"t_userDefinedValueType\" + parenthesizeIdentifier(m_definition.name()) + std::to_string(m_definition.id());\n}\n\nbool UserDefinedValueType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tUserDefinedValueType const& other = dynamic_cast<UserDefinedValueType const&>(_other);\n\treturn *this == other;\n}\n\nbool UserDefinedValueType::operator==(UserDefinedValueType const& _other) const\n{\n\treturn _other.definition() == definition();\n}\n\nstd::string UserDefinedValueType::toString(bool /* _withoutDataLocation */) const\n{\n\treturn *definition().annotation().canonicalName;\n}\n\nstd::string UserDefinedValueType::canonicalName() const\n{\n\treturn *definition().annotation().canonicalName;\n}\n\nstd::vector<std::tuple<std::string, Type const*>> UserDefinedValueType::makeStackItems() const\n{\n\treturn underlyingType().stackItems();\n}\n\nBoolResult TupleType::isImplicitlyConvertibleTo(Type const& _other) const\n{\n\tif (auto tupleType = dynamic_cast<TupleType const*>(&_other))\n\t{\n\t\tTypePointers const& targets = tupleType->components();\n\t\tif (targets.empty())\n\t\t\treturn components().empty();\n\t\tif (components().size() != targets.size())\n\t\t\treturn false;\n\t\tfor (size_t i = 0; i < targets.size(); ++i)\n\t\t\tif (!components()[i] && targets[i])\n\t\t\t\treturn false;\n\t\t\telse if (components()[i] && targets[i] && !components()[i]->isImplicitlyConvertibleTo(*targets[i]))\n\t\t\t\treturn false;\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n\nstd::string TupleType::richIdentifier() const\n{\n\treturn \"t_tuple\" + identifierList(components());\n}\n\nbool TupleType::operator==(Type const& _other) const\n{\n\tif (auto tupleType = dynamic_cast<TupleType const*>(&_other))\n\t\treturn components() == tupleType->components();\n\telse\n\t\treturn false;\n}\n\nstd::string TupleType::toString(bool _withoutDataLocation) const\n{\n\tif (components().empty())\n\t\treturn \"tuple()\";\n\tstd::string str = \"tuple(\";\n\tfor (auto const& t: components())\n\t\tstr += (t ? t->toString(_withoutDataLocation) : \"\") + \",\";\n\tstr.pop_back();\n\treturn str + \")\";\n}\n\nstd::string TupleType::humanReadableName() const\n{\n\tif (components().empty())\n\t\treturn \"tuple()\";\n\tstd::string str = \"tuple(\";\n\tfor (auto const& t: components())\n\t\tstr += (t ? t->humanReadableName() : \"\") + \",\";\n\tstr.pop_back();\n\treturn str + \")\";\n}\n\nu256 TupleType::storageSize() const\n{\n\tsolAssert(false, \"Storage size of non-storable tuple type requested.\");\n}\n\nstd::vector<std::tuple<std::string, Type const*>> TupleType::makeStackItems() const\n{\n\tstd::vector<std::tuple<std::string, Type const*>> slots;\n\tunsigned i = 1;\n\tfor (auto const& t: components())\n\t{\n\t\tif (t)\n\t\t\tslots.emplace_back(\"component_\" + std::to_string(i), t);\n\t\t++i;\n\t}\n\treturn slots;\n}\n\nType const* TupleType::mobileType() const\n{\n\tTypePointers mobiles;\n\tfor (auto const& c: components())\n\t{\n\t\tif (c)\n\t\t{\n\t\t\tauto mt = c->mobileType();\n\t\t\tif (!mt)\n\t\t\t\treturn nullptr;\n\t\t\tmobiles.push_back(mt);\n\t\t}\n\t\telse\n\t\t\tmobiles.push_back(nullptr);\n\t}\n\treturn TypeProvider::tuple(std::move(mobiles));\n}\n\nFunctionType::FunctionType(FunctionDefinition const& _function, Kind _kind):\n\tm_kind(_kind),\n\tm_stateMutability(_function.stateMutability()),\n\tm_declaration(&_function)\n{\n\tsolAssert(\n\t\t_kind == Kind::Internal || _kind == Kind::External || _kind == Kind::Declaration,\n\t\t\"Only internal or external function types or function declaration types can be created from function definitions.\"\n\t);\n\tif (_kind == Kind::Internal && m_stateMutability == StateMutability::Payable)\n\t\tm_stateMutability = StateMutability::NonPayable;\n\n\tfor (ASTPointer<VariableDeclaration> const& var: _function.parameters())\n\t{\n\t\tsolAssert(var->annotation().type, \"Parameter type is not yet available in the AST.\");\n\t\tm_parameterNames.push_back(var->name());\n\t\tm_parameterTypes.push_back(var->annotation().type);\n\t}\n\tfor (ASTPointer<VariableDeclaration> const& var: _function.returnParameters())\n\t{\n\t\tsolAssert(var->annotation().type, \"Return parameter type is not yet available in the AST.\");\n\t\tm_returnParameterNames.push_back(var->name());\n\t\tm_returnParameterTypes.push_back(var->annotation().type);\n\t}\n\n\tsolAssert(\n\t\tm_parameterNames.size() == m_parameterTypes.size(),\n\t\t\"Parameter names list must match parameter types list!\"\n\t);\n\n\tsolAssert(\n\t\tm_returnParameterNames.size() == m_returnParameterTypes.size(),\n\t\t\"Return parameter names list must match return parameter types list!\"\n\t);\n}\n\nFunctionType::FunctionType(VariableDeclaration const& _varDecl):\n\tm_kind(Kind::External),\n\tm_stateMutability(StateMutability::View),\n\tm_declaration(&_varDecl)\n{\n\tauto returnType = _varDecl.annotation().type;\n\tASTString returnName;\n\n\twhile (true)\n\t{\n\t\tif (auto mappingType = dynamic_cast<MappingType const*>(returnType))\n\t\t{\n\t\t\tm_parameterTypes.push_back(mappingType->keyType());\n\t\t\tm_parameterNames.push_back(mappingType->keyName());\n\t\t\treturnType = mappingType->valueType();\n\t\t\treturnName = mappingType->valueName();\n\t\t}\n\t\telse if (auto arrayType = dynamic_cast<ArrayType const*>(returnType))\n\t\t{\n\t\t\tif (arrayType->isByteArrayOrString())\n\t\t\t\t// Return byte arrays as whole.\n\t\t\t\tbreak;\n\t\t\treturnType = arrayType->baseType();\n\t\t\tm_parameterNames.emplace_back(\"\");\n\t\t\tm_parameterTypes.push_back(TypeProvider::uint256());\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n\n\tif (auto structType = dynamic_cast<StructType const*>(returnType))\n\t{\n\t\tfor (auto const& member: structType->members(nullptr))\n\t\t{\n\t\t\tsolAssert(member.type, \"\");\n\t\t\tif (member.type->category() != Category::Mapping)\n\t\t\t{\n\t\t\t\tif (auto arrayType = dynamic_cast<ArrayType const*>(member.type))\n\t\t\t\t\tif (!arrayType->isByteArrayOrString())\n\t\t\t\t\t\tcontinue;\n\t\t\t\tm_returnParameterTypes.push_back(TypeProvider::withLocationIfReference(\n\t\t\t\t\tDataLocation::Memory,\n\t\t\t\t\tmember.type\n\t\t\t\t));\n\t\t\t\tm_returnParameterNames.push_back(member.name);\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tm_returnParameterTypes.push_back(TypeProvider::withLocationIfReference(\n\t\t\tDataLocation::Memory,\n\t\t\treturnType\n\t\t));\n\t\tm_returnParameterNames.emplace_back(returnName);\n\t}\n\n\tsolAssert(\n\t\t\tm_parameterNames.size() == m_parameterTypes.size(),\n\t\t\t\"Parameter names list must match parameter types list!\"\n\t\t\t);\n\tsolAssert(\n\t\t\tm_returnParameterNames.size() == m_returnParameterTypes.size(),\n\t\t\t\"Return parameter names list must match return parameter types list!\"\n\t\t\t);\n}\n\nFunctionType::FunctionType(EventDefinition const& _event):\n\tm_kind(Kind::Event),\n\tm_stateMutability(StateMutability::NonPayable),\n\tm_declaration(&_event)\n{\n\tfor (ASTPointer<VariableDeclaration> const& var: _event.parameters())\n\t{\n\t\tm_parameterNames.push_back(var->name());\n\t\tm_parameterTypes.push_back(var->annotation().type);\n\t}\n\n\tsolAssert(\n\t\tm_parameterNames.size() == m_parameterTypes.size(),\n\t\t\"Parameter names list must match parameter types list!\"\n\t);\n\tsolAssert(\n\t\tm_returnParameterNames.size() == 0 &&\n\t\tm_returnParameterTypes.size() == 0,\n\t\t\"\"\n\t);\n}\n\nFunctionType::FunctionType(ErrorDefinition const& _error):\n\tm_kind(Kind::Error),\n\tm_stateMutability(StateMutability::Pure),\n\tm_declaration(&_error)\n{\n\tfor (ASTPointer<VariableDeclaration> const& var: _error.parameters())\n\t{\n\t\tm_parameterNames.push_back(var->name());\n\t\tm_parameterTypes.push_back(var->annotation().type);\n\t}\n\n\tm_returnParameterNames.push_back(\"\");\n\tm_returnParameterTypes.push_back(TypeProvider::magic(MagicType::Kind::Error));\n\n\tsolAssert(\n\t\tm_parameterNames.size() == m_parameterTypes.size(),\n\t\t\"Parameter names list must match parameter types list!\"\n\t);\n\tsolAssert(\n\t\tm_returnParameterNames.size() == m_returnParameterTypes.size(),\n\t\t\"\"\n\t);\n}\n\nFunctionType::FunctionType(FunctionTypeName const& _typeName):\n\tm_parameterNames(_typeName.parameterTypes().size(), \"\"),\n\tm_returnParameterNames(_typeName.returnParameterTypes().size(), \"\"),\n\tm_kind(_typeName.visibility() == Visibility::External ? Kind::External : Kind::Internal),\n\tm_stateMutability(_typeName.stateMutability())\n{\n\tif (_typeName.isPayable())\n\t\tsolAssert(m_kind == Kind::External, \"Internal payable function type used.\");\n\tfor (auto const& t: _typeName.parameterTypes())\n\t{\n\t\tsolAssert(t->annotation().type, \"Type not set for parameter.\");\n\t\tm_parameterTypes.push_back(t->annotation().type);\n\t}\n\tfor (auto const& t: _typeName.returnParameterTypes())\n\t{\n\t\tsolAssert(t->annotation().type, \"Type not set for return parameter.\");\n\t\tm_returnParameterTypes.push_back(t->annotation().type);\n\t}\n\n\tsolAssert(\n\t\t\tm_parameterNames.size() == m_parameterTypes.size(),\n\t\t\t\"Parameter names list must match parameter types list!\"\n\t\t\t);\n\tsolAssert(\n\t\t\tm_returnParameterNames.size() == m_returnParameterTypes.size(),\n\t\t\t\"Return parameter names list must match return parameter types list!\"\n\t\t\t);\n}\n\nFunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _contract)\n{\n\tFunctionDefinition const* constructor = _contract.constructor();\n\tTypePointers parameters;\n\tstrings parameterNames;\n\tStateMutability stateMutability = StateMutability::NonPayable;\n\n\tsolAssert(!_contract.isInterface(), \"\");\n\n\tif (constructor)\n\t{\n\t\tfor (ASTPointer<VariableDeclaration> const& var: constructor->parameters())\n\t\t{\n\t\t\tparameterNames.push_back(var->name());\n\t\t\tparameters.push_back(var->annotation().type);\n\t\t}\n\t\tif (constructor->isPayable())\n\t\t\tstateMutability = StateMutability::Payable;\n\t}\n\n\treturn TypeProvider::function(\n\t\tparameters,\n\t\tTypePointers{TypeProvider::contract(_contract)},\n\t\tparameterNames,\n\t\tstrings{\"\"},\n\t\tKind::Creation,\n\t\tstateMutability\n\t);\n}\n\nstd::vector<std::string> FunctionType::parameterNames() const\n{\n\tif (!hasBoundFirstArgument())\n\t\treturn m_parameterNames;\n\treturn std::vector<std::string>(m_parameterNames.cbegin() + 1, m_parameterNames.cend());\n}\n\nTypePointers FunctionType::returnParameterTypesWithoutDynamicTypes() const\n{\n\tTypePointers returnParameterTypes = m_returnParameterTypes;\n\n\tif (\n\t\tm_kind == Kind::External ||\n\t\tm_kind == Kind::DelegateCall ||\n\t\tm_kind == Kind::BareCall ||\n\t\tm_kind == Kind::BareCallCode ||\n\t\tm_kind == Kind::BareDelegateCall ||\n\t\tm_kind == Kind::BareStaticCall\n\t)\n\t\tfor (auto& param: returnParameterTypes)\n\t\t{\n\t\t\tsolAssert(param->decodingType(), \"\");\n\t\t\tif (param->decodingType()->isDynamicallyEncoded())\n\t\t\t\tparam = TypeProvider::inaccessibleDynamic();\n\t\t}\n\n\treturn returnParameterTypes;\n}\n\nTypePointers FunctionType::parameterTypes() const\n{\n\tif (!hasBoundFirstArgument())\n\t\treturn m_parameterTypes;\n\treturn TypePointers(m_parameterTypes.cbegin() + 1, m_parameterTypes.cend());\n}\n\nTypePointers const& FunctionType::parameterTypesIncludingSelf() const\n{\n\treturn m_parameterTypes;\n}\n\nstd::string FunctionType::richIdentifier() const\n{\n\tstd::string id = \"t_function_\";\n\tswitch (m_kind)\n\t{\n\tcase Kind::Declaration: id += \"declaration\"; break;\n\tcase Kind::Internal: id += \"internal\"; break;\n\tcase Kind::External: id += \"external\"; break;\n\tcase Kind::DelegateCall: id += \"delegatecall\"; break;\n\tcase Kind::BareCall: id += \"barecall\"; break;\n\tcase Kind::BareCallCode: id += \"barecallcode\"; break;\n\tcase Kind::BareDelegateCall: id += \"baredelegatecall\"; break;\n\tcase Kind::BareStaticCall: id += \"barestaticcall\"; break;\n\tcase Kind::Creation: id += \"creation\"; break;\n\tcase Kind::Send: id += \"send\"; break;\n\tcase Kind::Transfer: id += \"transfer\"; break;\n\tcase Kind::KECCAK256: id += \"keccak256\"; break;\n\tcase Kind::Selfdestruct: id += \"selfdestruct\"; break;\n\tcase Kind::Revert: id += \"revert\"; break;\n\tcase Kind::ECRecover: id += \"ecrecover\"; break;\n\tcase Kind::SHA256: id += \"sha256\"; break;\n\tcase Kind::RIPEMD160: id += \"ripemd160\"; break;\n\tcase Kind::GasLeft: id += \"gasleft\"; break;\n\tcase Kind::Event: id += \"event\"; break;\n\tcase Kind::Error: id += \"error\"; break;\n\tcase Kind::Wrap: id += \"wrap\"; break;\n\tcase Kind::Unwrap: id += \"unwrap\"; break;\n\tcase Kind::SetGas: id += \"setgas\"; break;\n\tcase Kind::SetValue: id += \"setvalue\"; break;\n\tcase Kind::BlockHash: id += \"blockhash\"; break;\n\tcase Kind::AddMod: id += \"addmod\"; break;\n\tcase Kind::MulMod: id += \"mulmod\"; break;\n\tcase Kind::ArrayPush: id += \"arraypush\"; break;\n\tcase Kind::ArrayPop: id += \"arraypop\"; break;\n\tcase Kind::BytesConcat: id += \"bytesconcat\"; break;\n\tcase Kind::StringConcat: id += \"stringconcat\"; break;\n\tcase Kind::ObjectCreation: id += \"objectcreation\"; break;\n\tcase Kind::Assert: id += \"assert\"; break;\n\tcase Kind::Require: id += \"require\"; break;\n\tcase Kind::ABIEncode: id += \"abiencode\"; break;\n\tcase Kind::ABIEncodePacked: id += \"abiencodepacked\"; break;\n\tcase Kind::ABIEncodeWithSelector: id += \"abiencodewithselector\"; break;\n\tcase Kind::ABIEncodeCall: id += \"abiencodecall\"; break;\n\tcase Kind::ABIEncodeWithSignature: id += \"abiencodewithsignature\"; break;\n\tcase Kind::ABIDecode: id += \"abidecode\"; break;\n\tcase Kind::BlobHash: id += \"blobhash\"; break;\n\tcase Kind::MetaType: id += \"metatype\"; break;\n\tcase Kind::ERC7201: id += \"erc7201\"; break;\n\t}\n\tid += \"_\" + stateMutabilityToString(m_stateMutability);\n\tid += identifierList(m_parameterTypes) + \"returns\" + identifierList(m_returnParameterTypes);\n\tif (gasSet())\n\t\tid += \"gas\";\n\tif (valueSet())\n\t\tid += \"value\";\n\tif (saltSet())\n\t\tid += \"salt\";\n\tif (hasBoundFirstArgument())\n\t\tid += \"attached_to\" + identifierList(selfType());\n\treturn id;\n}\n\nbool FunctionType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tFunctionType const& other = dynamic_cast<FunctionType const&>(_other);\n\tif (!equalExcludingStateMutability(other))\n\t\treturn false;\n\tif (m_stateMutability != other.stateMutability())\n\t\treturn false;\n\treturn true;\n}\n\nBoolResult FunctionType::isExplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (_convertTo.category() == category())\n\t{\n\t\tauto const& convertToType = dynamic_cast<FunctionType const&>(_convertTo);\n\t\treturn (m_kind == FunctionType::Kind::Declaration) == (convertToType.kind() == FunctionType::Kind::Declaration);\n\t}\n\treturn false;\n}\n\nBoolResult FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (_convertTo.category() != category())\n\t\treturn false;\n\n\tFunctionType const& convertTo = dynamic_cast<FunctionType const&>(_convertTo);\n\n\t// These two checks are duplicated in equalExcludingStateMutability, but are added here for error reporting.\n\tif (convertTo.hasBoundFirstArgument() != hasBoundFirstArgument())\n\t\treturn BoolResult::err(\"Attached functions cannot be converted into unattached functions.\");\n\n\tif (convertTo.kind() != kind())\n\t\treturn BoolResult::err(\"Special functions cannot be converted to function types.\");\n\n\tif (\n\t\tkind() == FunctionType::Kind::Declaration &&\n\t\tm_declaration != convertTo.m_declaration\n\t)\n\t\treturn BoolResult::err(\"Function declaration types referring to different functions cannot be converted to each other.\");\n\n\tif (!equalExcludingStateMutability(convertTo))\n\t\treturn false;\n\n\t// non-payable should not be convertible to payable\n\tif (m_stateMutability != StateMutability::Payable && convertTo.stateMutability() == StateMutability::Payable)\n\t\treturn false;\n\n\t// payable should be convertible to non-payable, because you are free to pay 0 ether\n\tif (m_stateMutability == StateMutability::Payable && convertTo.stateMutability() == StateMutability::NonPayable)\n\t\treturn true;\n\n\t// e.g. pure should be convertible to view, but not the other way around.\n\tif (m_stateMutability > convertTo.stateMutability())\n\t\treturn false;\n\n\treturn true;\n}\n\nTypeResult FunctionType::unaryOperatorResult(Token _operator) const\n{\n\tif (_operator == Token::Delete)\n\t\treturn TypeResult(TypeProvider::emptyTuple());\n\treturn nullptr;\n}\n\nTypeResult FunctionType::binaryOperatorResult(Token _operator, Type const* _other) const\n{\n\tif (_other->category() != category() || !(_operator == Token::Equal || _operator == Token::NotEqual))\n\t\treturn nullptr;\n\tFunctionType const& other = dynamic_cast<FunctionType const&>(*_other);\n\tif (kind() == Kind::Internal && sizeOnStack() == 1 && other.kind() == Kind::Internal && other.sizeOnStack() == 1)\n\t\treturn commonType(this, _other);\n\telse if (\n\t\tkind() == Kind::External &&\n\t\tsizeOnStack() == 2 &&\n\t\t!hasBoundFirstArgument() &&\n\t\tother.kind() == Kind::External &&\n\t\tother.sizeOnStack() == 2 &&\n\t\t!other.hasBoundFirstArgument()\n\t)\n\t\treturn commonType(this, _other);\n\n\treturn nullptr;\n}\n\nstd::string FunctionType::canonicalName() const\n{\n\tsolAssert(m_kind == Kind::External, \"\");\n\treturn \"function\";\n}\n\nstd::string FunctionType::humanReadableName() const\n{\n\tswitch (m_kind)\n\t{\n\tcase Kind::Error:\n\t\treturn \"error \" + m_declaration->name() + toStringInParentheses(m_parameterTypes, /* _withoutDataLocation */ true);\n\tcase Kind::Event:\n\t\treturn \"event \" + m_declaration->name() + toStringInParentheses(m_parameterTypes, /* _withoutDataLocation */ true);\n\tdefault:\n\t\treturn toString(/* _withoutDataLocation */ false);\n\t}\n}\n\nstd::string FunctionType::toString(bool _withoutDataLocation) const\n{\n\tstd::string name = \"function \";\n\tif (m_kind == Kind::Declaration)\n\t{\n\t\tauto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(m_declaration);\n\t\tsolAssert(functionDefinition, \"\");\n\t\tif (auto const* contract = dynamic_cast<ContractDefinition const*>(functionDefinition->scope()))\n\t\t\tname += *contract->annotation().canonicalName + \".\";\n\t\tname += functionDefinition->name();\n\t}\n\tname += toStringInParentheses(m_parameterTypes, _withoutDataLocation);\n\tif (m_stateMutability != StateMutability::NonPayable)\n\t\tname += \" \" + stateMutabilityToString(m_stateMutability);\n\tif (m_kind == Kind::External)\n\t\tname += \" external\";\n\tif (!m_returnParameterTypes.empty())\n\t{\n\t\tname += \" returns \";\n\t\tname += toStringInParentheses(m_returnParameterTypes, _withoutDataLocation);\n\t}\n\treturn name;\n}\n\nunsigned FunctionType::calldataEncodedSize(bool _padded) const\n{\n\tunsigned size = storageBytes();\n\tif (_padded)\n\t\tsize = ((size + 31) / 32) * 32;\n\treturn size;\n}\n\nu256 FunctionType::storageSize() const\n{\n\tif (m_kind == Kind::External || m_kind == Kind::Internal)\n\t\treturn 1;\n\telse\n\t\tsolAssert(false, \"Storage size of non-storable function type requested.\");\n}\n\nbool FunctionType::leftAligned() const\n{\n\treturn m_kind == Kind::External;\n}\n\nunsigned FunctionType::storageBytes() const\n{\n\tif (m_kind == Kind::External)\n\t\treturn 20 + 4;\n\telse if (m_kind == Kind::Internal)\n\t\treturn 8; // it should really not be possible to create larger programs\n\telse\n\t\tsolAssert(false, \"Storage size of non-storable function type requested.\");\n}\n\nbool FunctionType::nameable() const\n{\n\treturn\n\t\t(m_kind == Kind::Internal || m_kind == Kind::External) &&\n\t\t!hasBoundFirstArgument() &&\n\t\t!takesArbitraryParameters() &&\n\t\t!gasSet() &&\n\t\t!valueSet() &&\n\t\t!saltSet();\n}\n\nstd::vector<std::tuple<std::string, Type const*>> FunctionType::makeStackItems() const\n{\n\tstd::vector<std::tuple<std::string, Type const*>> slots;\n\tKind kind = m_kind;\n\tif (m_kind == Kind::SetGas || m_kind == Kind::SetValue)\n\t{\n\t\tsolAssert(m_returnParameterTypes.size() == 1, \"\");\n\t\tkind = dynamic_cast<FunctionType const&>(*m_returnParameterTypes.front()).m_kind;\n\t}\n\n\tswitch (kind)\n\t{\n\tcase Kind::External:\n\tcase Kind::DelegateCall:\n\t\tslots = {\n\t\t\tstd::make_tuple(\"address\", TypeProvider::address()),\n\t\t\tstd::make_tuple(\"functionSelector\", TypeProvider::uint(32))\n\t\t};\n\t\tbreak;\n\tcase Kind::BareCall:\n\tcase Kind::BareCallCode:\n\tcase Kind::BareDelegateCall:\n\tcase Kind::BareStaticCall:\n\tcase Kind::Transfer:\n\tcase Kind::Send:\n\t\tslots = {std::make_tuple(\"address\", TypeProvider::address())};\n\t\tbreak;\n\tcase Kind::Internal:\n\t\tslots = {std::make_tuple(\"functionIdentifier\", TypeProvider::uint256())};\n\t\tbreak;\n\tcase Kind::ArrayPush:\n\tcase Kind::ArrayPop:\n\t\tsolAssert(hasBoundFirstArgument(), \"\");\n\t\tslots = {};\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tif (gasSet())\n\t\tslots.emplace_back(\"gas\", TypeProvider::uint256());\n\tif (valueSet())\n\t\tslots.emplace_back(\"value\", TypeProvider::uint256());\n\tif (saltSet())\n\t\tslots.emplace_back(\"salt\", TypeProvider::fixedBytes(32));\n\tif (hasBoundFirstArgument())\n\t\tslots.emplace_back(\"self\", m_parameterTypes.front());\n\treturn slots;\n}\n\nFunctionTypePointer FunctionType::interfaceFunctionType() const\n{\n\t// Note that m_declaration might also be a state variable!\n\tsolAssert(m_declaration, \"Declaration needed to determine interface function type.\");\n\tbool isLibraryFunction = false;\n\tif (kind() != Kind::Event && kind() != Kind::Error)\n\t\tif (auto const* contract = dynamic_cast<ContractDefinition const*>(m_declaration->scope()))\n\t\t\tisLibraryFunction = contract->isLibrary();\n\n\tutil::Result<TypePointers> paramTypes =\n\t\ttransformParametersToExternal(m_parameterTypes, isLibraryFunction);\n\n\tif (!paramTypes.message().empty())\n\t\treturn FunctionTypePointer();\n\n\tutil::Result<TypePointers> retParamTypes =\n\t\ttransformParametersToExternal(m_returnParameterTypes, isLibraryFunction);\n\n\tif (!retParamTypes.message().empty())\n\t\treturn FunctionTypePointer();\n\n\tauto variable = dynamic_cast<VariableDeclaration const*>(m_declaration);\n\tif (variable && retParamTypes.get().empty())\n\t\treturn FunctionTypePointer();\n\n\tsolAssert(!takesArbitraryParameters());\n\treturn TypeProvider::function(\n\t\tparamTypes,\n\t\tretParamTypes,\n\t\tm_parameterNames,\n\t\tm_returnParameterNames,\n\t\tm_kind,\n\t\tm_stateMutability,\n\t\tm_declaration\n\t);\n}\n\nMemberList::MemberMap FunctionType::nativeMembers(ASTNode const* _scope) const\n{\n\tswitch (m_kind)\n\t{\n\tcase Kind::Declaration:\n\t\tif (declaration().isPartOfExternalInterface())\n\t\t\treturn {{\"selector\", TypeProvider::fixedBytes(4)}};\n\t\telse\n\t\t\treturn MemberList::MemberMap();\n\tcase Kind::Internal:\n\t\tif (\n\t\t\tauto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(m_declaration);\n\t\t\tfunctionDefinition &&\n\t\t\t_scope &&\n\t\t\tfunctionDefinition->annotation().contract &&\n\t\t\t_scope != functionDefinition->annotation().contract &&\n\t\t\tfunctionDefinition->isPartOfExternalInterface()\n\t\t)\n\t\t{\n\t\t\tauto const* contractScope = dynamic_cast<ContractDefinition const*>(_scope);\n\t\t\tsolAssert(contractScope && contractScope->derivesFrom(*functionDefinition->annotation().contract), \"\");\n\t\t\treturn {{\"selector\", TypeProvider::fixedBytes(4)}};\n\t\t}\n\t\telse\n\t\t\treturn MemberList::MemberMap();\n\tcase Kind::External:\n\tcase Kind::Creation:\n\tcase Kind::BareCall:\n\tcase Kind::BareCallCode:\n\tcase Kind::BareDelegateCall:\n\tcase Kind::BareStaticCall:\n\t{\n\t\tMemberList::MemberMap members;\n\t\tif (m_kind == Kind::External)\n\t\t{\n\t\t\tmembers.emplace_back(\"selector\", TypeProvider::fixedBytes(4));\n\t\t\tmembers.emplace_back(\"address\", TypeProvider::address());\n\t\t}\n\t\tif (m_kind != Kind::BareDelegateCall)\n\t\t{\n\t\t\tif (isPayable())\n\t\t\t\tmembers.emplace_back(\n\t\t\t\t\t\"value\",\n\t\t\t\t\tTypeProvider::function(\n\t\t\t\t\t\tparseElementaryTypeVector({\"uint\"}),\n\t\t\t\t\t\tTypePointers{copyAndSetCallOptions(false, true, false)},\n\t\t\t\t\t\tstrings(1, \"\"),\n\t\t\t\t\t\tstrings(1, \"\"),\n\t\t\t\t\t\tKind::SetValue,\n\t\t\t\t\t\tStateMutability::Pure,\n\t\t\t\t\t\tnullptr,\n\t\t\t\t\t\tOptions::fromFunctionType(*this)\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t}\n\t\tif (m_kind != Kind::Creation)\n\t\t\tmembers.emplace_back(\n\t\t\t\t\"gas\",\n\t\t\t\tTypeProvider::function(\n\t\t\t\t\tparseElementaryTypeVector({\"uint\"}),\n\t\t\t\t\tTypePointers{copyAndSetCallOptions(true, false, false)},\n\t\t\t\t\tstrings(1, \"\"),\n\t\t\t\t\tstrings(1, \"\"),\n\t\t\t\t\tKind::SetGas,\n\t\t\t\t\tStateMutability::Pure,\n\t\t\t\t\tnullptr,\n\t\t\t\t\tOptions::fromFunctionType(*this)\n\t\t\t\t)\n\t\t\t);\n\t\treturn members;\n\t}\n\tcase Kind::DelegateCall:\n\t{\n\t\tif (auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(m_declaration))\n\t\t{\n\t\t\tsolAssert(functionDefinition->visibility() > Visibility::Internal, \"\");\n\t\t\tauto const* contract = dynamic_cast<ContractDefinition const*>(m_declaration->scope());\n\t\t\tsolAssert(contract, \"\");\n\t\t\tsolAssert(contract->isLibrary(), \"\");\n\t\t\treturn {{\"selector\", TypeProvider::fixedBytes(4)}};\n\t\t}\n\t\treturn {};\n\t}\n\tcase Kind::Error:\n\t\treturn {{\"selector\", TypeProvider::fixedBytes(4)}};\n\tcase Kind::Event:\n\t{\n\t\tif (!(dynamic_cast<EventDefinition const&>(declaration()).isAnonymous()))\n\t\t\treturn {{\"selector\", TypeProvider::fixedBytes(32)}};\n\t\treturn MemberList::MemberMap();\n\t}\n\tdefault:\n\t\treturn MemberList::MemberMap();\n\t}\n}\n\nType const* FunctionType::encodingType() const\n{\n\tif (gasSet() || valueSet())\n\t\treturn nullptr;\n\t// Only external functions can be encoded, internal functions cannot leave code boundaries.\n\tif (m_kind == Kind::External)\n\t\treturn this;\n\telse\n\t\treturn nullptr;\n}\n\nTypeResult FunctionType::interfaceType(bool /*_inLibrary*/) const\n{\n\tif (m_kind == Kind::External)\n\t\treturn this;\n\telse\n\t\treturn TypeResult::err(\"Internal type is not allowed for public or external functions.\");\n}\n\nType const* FunctionType::mobileType() const\n{\n\tif (valueSet() || gasSet() || saltSet() || hasBoundFirstArgument())\n\t\treturn nullptr;\n\n\t// Special function types do not get a mobile type, such that they cannot be used in complex expressions.\n\tif (m_kind != FunctionType::Kind::Internal && m_kind != FunctionType::Kind::External && m_kind != FunctionType::Kind::DelegateCall)\n\t\treturn nullptr;\n\n\t// return function without parameter names and without declaration\n\treturn TypeProvider::function(\n\t\tm_parameterTypes,\n\t\tm_returnParameterTypes,\n\t\tstrings(m_parameterTypes.size()),\n\t\tstrings(m_returnParameterNames.size()),\n\t\tm_kind,\n\t\tm_stateMutability,\n\t\tnullptr,\n\t\tOptions::fromFunctionType(*this)\n\t);\n}\n\nbool FunctionType::canTakeArguments(\n\tFuncCallArguments const& _arguments,\n\tType const* _selfType\n) const\n{\n\tsolAssert(!hasBoundFirstArgument() || _selfType, \"\");\n\tif (hasBoundFirstArgument() && !_selfType->isImplicitlyConvertibleTo(*selfType()))\n\t\treturn false;\n\tTypePointers paramTypes = parameterTypes();\n\tstd::vector<std::string> const paramNames = parameterNames();\n\n\tif (takesArbitraryParameters())\n\t\treturn true;\n\telse if (_arguments.numArguments() != paramTypes.size())\n\t\treturn false;\n\telse if (!_arguments.hasNamedArguments())\n\t\treturn equal(\n\t\t\t_arguments.types.cbegin(),\n\t\t\t_arguments.types.cend(),\n\t\t\tparamTypes.cbegin(),\n\t\t\t[](Type const* argumentType, Type const* parameterType)\n\t\t\t{\n\t\t\t\treturn argumentType->isImplicitlyConvertibleTo(*parameterType);\n\t\t\t}\n\t\t);\n\telse if (paramNames.size() != _arguments.numNames())\n\t\treturn false;\n\telse\n\t{\n\t\tsolAssert(_arguments.numArguments() == _arguments.numNames(), \"Expected equal sized type & name vectors\");\n\n\t\tsize_t matchedNames = 0;\n\n\t\tfor (size_t a = 0; a < _arguments.names.size(); a++)\n\t\t\tfor (size_t p = 0; p < paramNames.size(); p++)\n\t\t\t\tif (*_arguments.names[a] == paramNames[p])\n\t\t\t\t{\n\t\t\t\t\tmatchedNames++;\n\t\t\t\t\tif (!_arguments.types[a]->isImplicitlyConvertibleTo(*paramTypes[p]))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\tif (matchedNames == _arguments.numNames())\n\t\t\treturn true;\n\n\t\treturn false;\n\t}\n}\n\nbool FunctionType::hasEqualParameterTypes(FunctionType const& _other) const\n{\n\tif (m_parameterTypes.size() != _other.m_parameterTypes.size())\n\t\treturn false;\n\treturn equal(\n\t\tm_parameterTypes.cbegin(),\n\t\tm_parameterTypes.cend(),\n\t\t_other.m_parameterTypes.cbegin(),\n\t\t[](Type const* _a, Type const* _b) -> bool { return *_a == *_b; }\n\t);\n}\n\nbool FunctionType::hasEqualReturnTypes(FunctionType const& _other) const\n{\n\tif (m_returnParameterTypes.size() != _other.m_returnParameterTypes.size())\n\t\treturn false;\n\treturn equal(\n\t\tm_returnParameterTypes.cbegin(),\n\t\tm_returnParameterTypes.cend(),\n\t\t_other.m_returnParameterTypes.cbegin(),\n\t\t[](Type const* _a, Type const* _b) -> bool { return *_a == *_b; }\n\t);\n}\n\nbool FunctionType::equalExcludingStateMutability(FunctionType const& _other) const\n{\n\tif (m_kind != _other.m_kind)\n\t\treturn false;\n\n\tif (!hasEqualParameterTypes(_other) || !hasEqualReturnTypes(_other))\n\t\treturn false;\n\n\t//@todo this is ugly, but cannot be prevented right now\n\tif (gasSet() != _other.gasSet() || valueSet() != _other.valueSet() || saltSet() != _other.saltSet())\n\t\treturn false;\n\n\tif (hasBoundFirstArgument() != _other.hasBoundFirstArgument())\n\t\treturn false;\n\n\tsolAssert(!hasBoundFirstArgument() || *selfType() == *_other.selfType(), \"\");\n\n\treturn true;\n}\n\nbool FunctionType::isBareCall() const\n{\n\tswitch (m_kind)\n\t{\n\tcase Kind::BareCall:\n\tcase Kind::BareCallCode:\n\tcase Kind::BareDelegateCall:\n\tcase Kind::BareStaticCall:\n\tcase Kind::ECRecover:\n\tcase Kind::SHA256:\n\tcase Kind::RIPEMD160:\n\t\treturn true;\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nstd::string FunctionType::externalSignature() const\n{\n\tsolAssert(m_declaration != nullptr, \"External signature of function needs declaration\");\n\tsolAssert(!m_declaration->name().empty(), \"Fallback function has no signature.\");\n\tswitch (kind())\n\t{\n\tcase Kind::Internal:\n\tcase Kind::External:\n\tcase Kind::DelegateCall:\n\tcase Kind::Event:\n\tcase Kind::Error:\n\tcase Kind::Declaration:\n\t\tbreak;\n\tdefault:\n\t\tsolAssert(false, \"Invalid function type for requesting external signature.\");\n\t}\n\n\t// \"inLibrary\" is only relevant if this is neither an event nor an error.\n\tbool inLibrary = false;\n\tif (kind() != Kind::Event && kind() != Kind::Error)\n\t\tif (auto const* contract = dynamic_cast<ContractDefinition const*>(m_declaration->scope()))\n\t\t\tinLibrary = contract->isLibrary();\n\n\tauto extParams = transformParametersToExternal(m_parameterTypes, inLibrary);\n\n\tsolAssert(extParams.message().empty(), extParams.message());\n\n\tauto typeStrings = extParams.get() | ranges::views::transform([&](Type const* _t) -> std::string\n\t{\n\t\tstd::string typeName = _t->signatureInExternalFunction(inLibrary);\n\n\t\tif (inLibrary && _t->dataStoredIn(DataLocation::Storage))\n\t\t\ttypeName += \" storage\";\n\t\treturn typeName;\n\t});\n\treturn m_declaration->name() + \"(\" + boost::algorithm::join(typeStrings, \",\") + \")\";\n}\n\nu256 FunctionType::externalIdentifier() const\n{\n\treturn util::selectorFromSignatureU32(externalSignature());\n}\n\nstd::string FunctionType::externalIdentifierHex() const\n{\n\treturn util::selectorFromSignatureH32(externalSignature()).hex();\n}\n\nbool FunctionType::isPure() const\n{\n\t// TODO: replace this with m_stateMutability == StateMutability::Pure once\n\t//       the callgraph analyzer is in place\n\treturn\n\t\tm_kind == Kind::KECCAK256 ||\n\t\tm_kind == Kind::ECRecover ||\n\t\tm_kind == Kind::SHA256 ||\n\t\tm_kind == Kind::RIPEMD160 ||\n\t\tm_kind == Kind::AddMod ||\n\t\tm_kind == Kind::MulMod ||\n\t\tm_kind == Kind::ObjectCreation ||\n\t\tm_kind == Kind::ABIEncode ||\n\t\tm_kind == Kind::ABIEncodePacked ||\n\t\tm_kind == Kind::ABIEncodeWithSelector ||\n\t\tm_kind == Kind::ABIEncodeCall ||\n\t\tm_kind == Kind::ABIEncodeWithSignature ||\n\t\tm_kind == Kind::ABIDecode ||\n\t\tm_kind == Kind::MetaType ||\n\t\tm_kind == Kind::Wrap ||\n\t\tm_kind == Kind::Unwrap ||\n\t\tm_kind == Kind::BytesConcat ||\n\t\tm_kind == Kind::StringConcat ||\n\t\tm_kind == Kind::ERC7201;\n}\n\nTypePointers FunctionType::parseElementaryTypeVector(strings const& _types)\n{\n\tTypePointers pointers;\n\tpointers.reserve(_types.size());\n\tfor (std::string const& type: _types)\n\t\tpointers.push_back(TypeProvider::fromElementaryTypeName(type));\n\treturn pointers;\n}\n\nType const* FunctionType::copyAndSetCallOptions(bool _setGas, bool _setValue, bool _setSalt) const\n{\n\tsolAssert(m_kind != Kind::Declaration, \"\");\n\tOptions options = Options::fromFunctionType(*this);\n\tif (_setGas) options.gasSet = true;\n\tif (_setValue) options.valueSet = true;\n\tif (_setSalt) options.saltSet = true;\n\treturn TypeProvider::function(\n\t\tm_parameterTypes,\n\t\tm_returnParameterTypes,\n\t\tm_parameterNames,\n\t\tm_returnParameterNames,\n\t\tm_kind,\n\t\tm_stateMutability,\n\t\tm_declaration,\n\t\toptions\n\t);\n}\n\nFunctionTypePointer FunctionType::withBoundFirstArgument() const\n{\n\tsolAssert(!m_parameterTypes.empty(), \"\");\n\tsolAssert(!gasSet(), \"\");\n\tsolAssert(!valueSet(), \"\");\n\tsolAssert(!saltSet(), \"\");\n\tOptions options = Options::fromFunctionType(*this);\n\toptions.hasBoundFirstArgument = true;\n\treturn TypeProvider::function(\n\t\tm_parameterTypes,\n\t\tm_returnParameterTypes,\n\t\tm_parameterNames,\n\t\tm_returnParameterNames,\n\t\tm_kind,\n\t\tm_stateMutability,\n\t\tm_declaration,\n\t\toptions\n\t);\n}\n\nFunctionTypePointer FunctionType::asExternallyCallableFunction(bool _inLibrary) const\n{\n\tTypePointers parameterTypes;\n\tfor (auto const& t: m_parameterTypes)\n\t\tif (TypeProvider::isReferenceWithLocation(t, DataLocation::CallData))\n\t\t\tparameterTypes.push_back(\n\t\t\t\tTypeProvider::withLocationIfReference(DataLocation::Memory, t, true)\n\t\t\t);\n\t\telse\n\t\t\tparameterTypes.push_back(t);\n\n\tTypePointers returnParameterTypes;\n\tfor (auto const& returnParamType: m_returnParameterTypes)\n\t\tif (TypeProvider::isReferenceWithLocation(returnParamType, DataLocation::CallData))\n\t\t\treturnParameterTypes.push_back(\n\t\t\t\tTypeProvider::withLocationIfReference(DataLocation::Memory, returnParamType, true)\n\t\t\t);\n\t\telse\n\t\t\treturnParameterTypes.push_back(returnParamType);\n\n\tKind kind = m_kind;\n\tif (_inLibrary)\n\t{\n\t\tsolAssert(!!m_declaration, \"Declaration has to be available.\");\n\t\tsolAssert(m_declaration->isPublic(), \"\");\n\t\tkind = Kind::DelegateCall;\n\t}\n\n\treturn TypeProvider::function(\n\t\tparameterTypes,\n\t\treturnParameterTypes,\n\t\tm_parameterNames,\n\t\tm_returnParameterNames,\n\t\tkind,\n\t\tm_stateMutability,\n\t\tm_declaration,\n\t\tOptions::fromFunctionType(*this)\n\t);\n}\n\nType const* FunctionType::selfType() const\n{\n\tsolAssert(hasBoundFirstArgument(), \"Function is not attached to a type.\");\n\tsolAssert(m_parameterTypes.size() > 0, \"Function has no self type.\");\n\treturn m_parameterTypes.at(0);\n}\n\nASTPointer<StructuredDocumentation> FunctionType::documentation() const\n{\n\tauto function = dynamic_cast<StructurallyDocumented const*>(m_declaration);\n\tif (function)\n\t\treturn function->documentation();\n\n\treturn ASTPointer<StructuredDocumentation>();\n}\n\nbool FunctionType::padArguments() const\n{\n\t// No padding only for hash functions, low-level calls and the packed encoding function.\n\tswitch (m_kind)\n\t{\n\tcase Kind::BareCall:\n\tcase Kind::BareCallCode:\n\tcase Kind::BareDelegateCall:\n\tcase Kind::BareStaticCall:\n\tcase Kind::SHA256:\n\tcase Kind::RIPEMD160:\n\tcase Kind::KECCAK256:\n\tcase Kind::ABIEncodePacked:\n\t\treturn false;\n\tdefault:\n\t\treturn true;\n\t}\n\treturn true;\n}\n\nType const* MappingType::encodingType() const\n{\n\treturn TypeProvider::integer(256, IntegerType::Modifier::Unsigned);\n}\n\nstd::string MappingType::richIdentifier() const\n{\n\treturn \"t_mapping\" + identifierList(m_keyType, m_valueType);\n}\n\nbool MappingType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tMappingType const& other = dynamic_cast<MappingType const&>(_other);\n\treturn *other.m_keyType == *m_keyType && *other.m_valueType == *m_valueType;\n}\n\nstd::string MappingType::toString(bool _withoutDataLocation) const\n{\n\treturn \"mapping(\" + keyType()->toString(_withoutDataLocation) + \" => \" + valueType()->toString(_withoutDataLocation) + \")\";\n}\n\nstd::string MappingType::canonicalName() const\n{\n\treturn \"mapping(\" + keyType()->canonicalName() + \" => \" + valueType()->canonicalName() + \")\";\n}\n\nTypeResult MappingType::interfaceType(bool _inLibrary) const\n{\n\tsolAssert(keyType()->interfaceType(_inLibrary).get(), \"Must be an elementary type!\");\n\n\tif (_inLibrary)\n\t{\n\t\tauto iType = valueType()->interfaceType(_inLibrary);\n\n\t\tif (!iType.get())\n\t\t{\n\t\t\tsolAssert(!iType.message().empty(), \"Expected detailed error message!\");\n\t\t\treturn iType;\n\t\t}\n\t}\n\telse\n\t\treturn TypeResult::err(\n\t\t\t\"Types containing (nested) mappings can only be parameters or \"\n\t\t\t\"return variables of internal or library functions.\"\n\t\t);\n\n\treturn this;\n}\n\nstd::vector<std::tuple<std::string, Type const*>> MappingType::makeStackItems() const\n{\n\treturn {std::make_tuple(\"slot\", TypeProvider::uint256())};\n}\n\nstd::string TypeType::richIdentifier() const\n{\n\treturn \"t_type\" + identifierList(actualType());\n}\n\nbool TypeType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tTypeType const& other = dynamic_cast<TypeType const&>(_other);\n\treturn *actualType() == *other.actualType();\n}\n\nu256 TypeType::storageSize() const\n{\n\tsolAssert(false, \"Storage size of non-storable type type requested.\");\n}\n\nstd::vector<std::tuple<std::string, Type const*>> TypeType::makeStackItems() const\n{\n\tif (auto contractType = dynamic_cast<ContractType const*>(m_actualType))\n\t\tif (contractType->contractDefinition().isLibrary())\n\t\t{\n\t\t\tsolAssert(!contractType->isSuper(), \"\");\n\t\t\treturn {std::make_tuple(\"address\", TypeProvider::address())};\n\t\t}\n\n\treturn {};\n}\n\nMemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) const\n{\n\tMemberList::MemberMap members;\n\tif (m_actualType->category() == Category::Contract)\n\t{\n\t\tauto contractType = dynamic_cast<ContractType const*>(m_actualType);\n\t\tContractDefinition const& contract = contractType->contractDefinition();\n\t\tif (contractType->isSuper())\n\t\t{\n\t\t\t// add the most derived of all functions which are visible in derived contracts\n\t\t\tauto bases = contract.annotation().linearizedBaseContracts;\n\t\t\tsolAssert(bases.size() >= 1, \"linearizedBaseContracts should at least contain the most derived contract.\");\n\t\t\t// `sliced(1, ...)` ignores the most derived contract, which should not be searchable from `super`.\n\t\t\tfor (ContractDefinition const* base: bases | ranges::views::tail)\n\t\t\t\tfor (FunctionDefinition const* function: base->definedFunctions())\n\t\t\t\t{\n\t\t\t\t\tif (!function->isVisibleInDerivedContracts() || !function->isImplemented())\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tauto functionType = TypeProvider::function(*function, FunctionType::Kind::Internal);\n\t\t\t\t\tbool functionWithEqualArgumentsFound = false;\n\t\t\t\t\tfor (auto const& member: members)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (member.name != function->name())\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tauto memberType = dynamic_cast<FunctionType const*>(member.type);\n\t\t\t\t\t\tsolAssert(!!memberType, \"Override changes type.\");\n\t\t\t\t\t\tif (!memberType->hasEqualParameterTypes(*functionType))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tfunctionWithEqualArgumentsFound = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (!functionWithEqualArgumentsFound)\n\t\t\t\t\t\tmembers.emplace_back(function, functionType);\n\t\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto const* contractScope = dynamic_cast<ContractDefinition const*>(_currentScope);\n\t\t\tbool inDerivingScope = contractScope && contractScope->derivesFrom(contract);\n\n\t\t\tfor (auto const* declaration: contract.declarations())\n\t\t\t{\n\t\t\t\tif (dynamic_cast<ModifierDefinition const*>(declaration))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (declaration->name().empty())\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (!contract.isLibrary() && inDerivingScope && declaration->isVisibleInDerivedContracts())\n\t\t\t\t{\n\t\t\t\t\tif (\n\t\t\t\t\t\tauto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(declaration);\n\t\t\t\t\t\tfunctionDefinition && !functionDefinition->isImplemented()\n\t\t\t\t\t)\n\t\t\t\t\t\tmembers.emplace_back(declaration, declaration->typeViaContractName());\n\t\t\t\t\telse\n\t\t\t\t\t\tmembers.emplace_back(declaration, declaration->type());\n\t\t\t\t}\n\t\t\t\telse if (\n\t\t\t\t\t(contract.isLibrary() && declaration->isVisibleAsLibraryMember()) ||\n\t\t\t\t\tdeclaration->isVisibleViaContractTypeAccess()\n\t\t\t\t)\n\t\t\t\t\tmembers.emplace_back(declaration, declaration->typeViaContractName());\n\t\t\t}\n\t\t}\n\t}\n\telse if (m_actualType->category() == Category::Enum)\n\t{\n\t\tEnumDefinition const& enumDef = dynamic_cast<EnumType const&>(*m_actualType).enumDefinition();\n\t\tauto enumType = TypeProvider::enumType(enumDef);\n\t\tfor (ASTPointer<EnumValue> const& enumValue: enumDef.members())\n\t\t\tmembers.emplace_back(enumValue.get(), enumType);\n\t}\n\telse if (m_actualType->category() == Category::UserDefinedValueType)\n\t{\n\t\tauto& userDefined = dynamic_cast<UserDefinedValueType const&>(*m_actualType);\n\t\tmembers.emplace_back(\n\t\t\t\"wrap\",\n\t\t\tTypeProvider::function(\n\t\t\t\tTypePointers{&userDefined.underlyingType()},\n\t\t\t\tTypePointers{&userDefined},\n\t\t\t\tstrings{std::string{}},\n\t\t\t\tstrings{std::string{}},\n\t\t\t\tFunctionType::Kind::Wrap,\n\t\t\t\tStateMutability::Pure\n\t\t\t)\n\t\t);\n\t\tmembers.emplace_back(\n\t\t\t\"unwrap\",\n\t\t\tTypeProvider::function(\n\t\t\t\tTypePointers{&userDefined},\n\t\t\t\tTypePointers{&userDefined.underlyingType()},\n\t\t\t\tstrings{std::string{}},\n\t\t\t\tstrings{std::string{}},\n\t\t\t\tFunctionType::Kind::Unwrap,\n\t\t\t\tStateMutability::Pure\n\t\t\t)\n\t\t);\n\t}\n\telse if (\n\t\tauto const* arrayType = dynamic_cast<ArrayType const*>(m_actualType);\n\t\tarrayType && arrayType->isByteArrayOrString()\n\t)\n\t\tmembers.emplace_back(\"concat\", TypeProvider::function(\n\t\t\tTypePointers{},\n\t\t\tTypePointers{arrayType->isString() ? TypeProvider::stringMemory() : TypeProvider::bytesMemory()},\n\t\t\tstrings{},\n\t\t\tstrings{std::string{}},\n\t\t\tarrayType->isString() ? FunctionType::Kind::StringConcat : FunctionType::Kind::BytesConcat,\n\t\t\tStateMutability::Pure,\n\t\t\tnullptr,\n\t\t\tFunctionType::Options::withArbitraryParameters()\n\t\t));\n\treturn members;\n}\n\nBoolResult TypeType::isExplicitlyConvertibleTo(Type const& _convertTo) const\n{\n\tif (auto const* address = dynamic_cast<AddressType const*>(&_convertTo))\n\t\tif (address->stateMutability() == StateMutability::NonPayable)\n\t\t\tif (auto const* contractType = dynamic_cast<ContractType const*>(m_actualType))\n\t\t\t\treturn contractType->contractDefinition().isLibrary();\n\treturn isImplicitlyConvertibleTo(_convertTo);\n}\n\nModifierType::ModifierType(ModifierDefinition const& _modifier)\n{\n\tTypePointers params;\n\tparams.reserve(_modifier.parameters().size());\n\tfor (ASTPointer<VariableDeclaration> const& var: _modifier.parameters())\n\t\tparams.push_back(var->annotation().type);\n\tswap(params, m_parameterTypes);\n}\n\nu256 ModifierType::storageSize() const\n{\n\tsolAssert(false, \"Storage size of non-storable type type requested.\");\n}\n\nstd::string ModifierType::richIdentifier() const\n{\n\treturn \"t_modifier\" + identifierList(m_parameterTypes);\n}\n\nbool ModifierType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\treturn *this == dynamic_cast<ModifierType const&>(_other);\n}\n\nbool ModifierType::operator==(ModifierType const& _other) const\n{\n\tModifierType const& other = dynamic_cast<ModifierType const&>(_other);\n\n\tif (m_parameterTypes.size() != other.m_parameterTypes.size())\n\t\treturn false;\n\tauto typeCompare = [](Type const* _a, Type const* _b) -> bool { return *_a == *_b; };\n\n\tif (!equal(\n\t\tm_parameterTypes.cbegin(),\n\t\tm_parameterTypes.cend(),\n\t\tother.m_parameterTypes.cbegin(),\n\t\ttypeCompare\n\t))\n\t\treturn false;\n\treturn true;\n}\n\nstd::string ModifierType::toString(bool _withoutDataLocation) const\n{\n\tstd::string name = \"modifier (\";\n\tfor (auto it = m_parameterTypes.begin(); it != m_parameterTypes.end(); ++it)\n\t\tname += (*it)->toString(_withoutDataLocation) + (it + 1 == m_parameterTypes.end() ? \"\" : \",\");\n\treturn name + \")\";\n}\n\nstd::string ModuleType::richIdentifier() const\n{\n\treturn \"t_module_\" + std::to_string(m_sourceUnit.id());\n}\n\nbool ModuleType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\treturn &m_sourceUnit == &dynamic_cast<ModuleType const&>(_other).m_sourceUnit;\n}\n\nMemberList::MemberMap ModuleType::nativeMembers(ASTNode const*) const\n{\n\tMemberList::MemberMap symbols;\n\tfor (auto const& [name, declarations]: *m_sourceUnit.annotation().exportedSymbols)\n\t\tfor (Declaration const* symbol: declarations)\n\t\t\tsymbols.emplace_back(symbol, symbol->type(), name);\n\treturn symbols;\n}\n\nstd::string ModuleType::toString(bool) const\n{\n\treturn std::string(\"module \\\"\") + *m_sourceUnit.annotation().path + std::string(\"\\\"\");\n}\n\nstd::string MagicType::richIdentifier() const\n{\n\tswitch (m_kind)\n\t{\n\tcase Kind::Block:\n\t\treturn \"t_magic_block\";\n\tcase Kind::Message:\n\t\treturn \"t_magic_message\";\n\tcase Kind::Transaction:\n\t\treturn \"t_magic_transaction\";\n\tcase Kind::ABI:\n\t\treturn \"t_magic_abi\";\n\tcase Kind::MetaType:\n\t\tsolAssert(m_typeArgument, \"\");\n\t\treturn \"t_magic_meta_type_\" + m_typeArgument->richIdentifier();\n\tcase Kind::Error:\n\t\treturn \"t_error\";\n\t}\n\treturn \"\";\n}\n\nbool MagicType::operator==(Type const& _other) const\n{\n\tif (_other.category() != category())\n\t\treturn false;\n\tMagicType const& other = dynamic_cast<MagicType const&>(_other);\n\treturn other.m_kind == m_kind;\n}\n\nMemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const\n{\n\tswitch (m_kind)\n\t{\n\tcase Kind::Block:\n\t\treturn MemberList::MemberMap({\n\t\t\t{\"coinbase\", TypeProvider::payableAddress()},\n\t\t\t{\"timestamp\", TypeProvider::uint256()},\n\t\t\t{\"blockhash\", TypeProvider::function(strings{\"uint\"}, strings{\"bytes32\"}, FunctionType::Kind::BlockHash, StateMutability::View)},\n\t\t\t{\"difficulty\", TypeProvider::uint256()},\n\t\t\t{\"prevrandao\", TypeProvider::uint256()},\n\t\t\t{\"number\", TypeProvider::uint256()},\n\t\t\t{\"gaslimit\", TypeProvider::uint256()},\n\t\t\t{\"chainid\", TypeProvider::uint256()},\n\t\t\t{\"basefee\", TypeProvider::uint256()},\n\t\t\t{\"blobbasefee\", TypeProvider::uint256()}\n\t\t});\n\tcase Kind::Message:\n\t\treturn MemberList::MemberMap({\n\t\t\t{\"sender\", TypeProvider::address()},\n\t\t\t{\"gas\", TypeProvider::uint256()},\n\t\t\t{\"value\", TypeProvider::uint256()},\n\t\t\t{\"data\", TypeProvider::array(DataLocation::CallData)},\n\t\t\t{\"sig\", TypeProvider::fixedBytes(4)}\n\t\t});\n\tcase Kind::Transaction:\n\t\treturn MemberList::MemberMap({\n\t\t\t{\"origin\", TypeProvider::address()},\n\t\t\t{\"gasprice\", TypeProvider::uint256()}\n\t\t});\n\tcase Kind::ABI:\n\t\treturn MemberList::MemberMap({\n\t\t\t{\"encode\", TypeProvider::function(\n\t\t\t\tTypePointers{},\n\t\t\t\tTypePointers{TypeProvider::array(DataLocation::Memory)},\n\t\t\t\tstrings{},\n\t\t\t\tstrings{1, \"\"},\n\t\t\t\tFunctionType::Kind::ABIEncode,\n\t\t\t\tStateMutability::Pure,\n\t\t\t\tnullptr,\n\t\t\t\tFunctionType::Options::withArbitraryParameters()\n\t\t\t)},\n\t\t\t{\"encodePacked\", TypeProvider::function(\n\t\t\t\tTypePointers{},\n\t\t\t\tTypePointers{TypeProvider::array(DataLocation::Memory)},\n\t\t\t\tstrings{},\n\t\t\t\tstrings{1, \"\"},\n\t\t\t\tFunctionType::Kind::ABIEncodePacked,\n\t\t\t\tStateMutability::Pure,\n\t\t\t\tnullptr,\n\t\t\t\tFunctionType::Options::withArbitraryParameters()\n\t\t\t)},\n\t\t\t{\"encodeWithSelector\", TypeProvider::function(\n\t\t\t\tTypePointers{TypeProvider::fixedBytes(4)},\n\t\t\t\tTypePointers{TypeProvider::array(DataLocation::Memory)},\n\t\t\t\tstrings{1, \"\"},\n\t\t\t\tstrings{1, \"\"},\n\t\t\t\tFunctionType::Kind::ABIEncodeWithSelector,\n\t\t\t\tStateMutability::Pure,\n\t\t\t\tnullptr,\n\t\t\t\tFunctionType::Options::withArbitraryParameters()\n\t\t\t)},\n\t\t\t{\"encodeCall\", TypeProvider::function(\n\t\t\t\tTypePointers{},\n\t\t\t\tTypePointers{TypeProvider::array(DataLocation::Memory)},\n\t\t\t\tstrings{},\n\t\t\t\tstrings{1, \"\"},\n\t\t\t\tFunctionType::Kind::ABIEncodeCall,\n\t\t\t\tStateMutability::Pure,\n\t\t\t\tnullptr,\n\t\t\t\tFunctionType::Options::withArbitraryParameters()\n\t\t\t)},\n\t\t\t{\"encodeWithSignature\", TypeProvider::function(\n\t\t\t\tTypePointers{TypeProvider::array(DataLocation::Memory, true)},\n\t\t\t\tTypePointers{TypeProvider::array(DataLocation::Memory)},\n\t\t\t\tstrings{1, \"\"},\n\t\t\t\tstrings{1, \"\"},\n\t\t\t\tFunctionType::Kind::ABIEncodeWithSignature,\n\t\t\t\tStateMutability::Pure,\n\t\t\t\tnullptr,\n\t\t\t\tFunctionType::Options::withArbitraryParameters()\n\t\t\t)},\n\t\t\t{\"decode\", TypeProvider::function(\n\t\t\t\tTypePointers(),\n\t\t\t\tTypePointers(),\n\t\t\t\tstrings{},\n\t\t\t\tstrings{},\n\t\t\t\tFunctionType::Kind::ABIDecode,\n\t\t\t\tStateMutability::Pure,\n\t\t\t\tnullptr,\n\t\t\t\tFunctionType::Options::withArbitraryParameters()\n\t\t\t)}\n\t\t});\n\tcase Kind::Error:\n\t\treturn {};\n\tcase Kind::MetaType:\n\t{\n\t\tsolAssert(\n\t\t\tm_typeArgument && (\n\t\t\t\t\tm_typeArgument->category() == Type::Category::Contract ||\n\t\t\t\t\tm_typeArgument->category() == Type::Category::Integer ||\n\t\t\t\t\tm_typeArgument->category() == Type::Category::Enum\n\t\t\t),\n\t\t\t\"Only enums, contracts or integer types supported for now\"\n\t\t);\n\n\t\tif (m_typeArgument->category() == Type::Category::Contract)\n\t\t{\n\t\t\tContractDefinition const& contract = dynamic_cast<ContractType const&>(*m_typeArgument).contractDefinition();\n\t\t\tif (contract.canBeDeployed())\n\t\t\t\treturn MemberList::MemberMap({\n\t\t\t\t\t{\"creationCode\", TypeProvider::array(DataLocation::Memory)},\n\t\t\t\t\t{\"runtimeCode\", TypeProvider::array(DataLocation::Memory)},\n\t\t\t\t\t{\"name\", TypeProvider::stringMemory()},\n\t\t\t\t});\n\t\t\telse\n\t\t\t\treturn MemberList::MemberMap({\n\t\t\t\t\t{\"interfaceId\", TypeProvider::fixedBytes(4)},\n\t\t\t\t\t{\"name\", TypeProvider::stringMemory()},\n\t\t\t\t});\n\t\t}\n\t\telse if (m_typeArgument->category() == Type::Category::Integer)\n\t\t{\n\t\t\tIntegerType const* integerTypePointer = dynamic_cast<IntegerType const*>(m_typeArgument);\n\t\t\treturn MemberList::MemberMap({\n\t\t\t\t{\"min\", integerTypePointer},\n\t\t\t\t{\"max\", integerTypePointer},\n\t\t\t});\n\t\t}\n\t\telse if (m_typeArgument->category() == Type::Category::Enum)\n\t\t{\n\t\t\tEnumType const* enumTypePointer = dynamic_cast<EnumType const*>(m_typeArgument);\n\t\t\treturn MemberList::MemberMap({\n\t\t\t\t{\"min\", enumTypePointer},\n\t\t\t\t{\"max\", enumTypePointer},\n\t\t\t});\n\t\t}\n\t}\n\t}\n\tsolAssert(false, \"Unknown kind of magic.\");\n\treturn {};\n}\n\nstd::string MagicType::toString(bool _withoutDataLocation) const\n{\n\tswitch (m_kind)\n\t{\n\tcase Kind::Block:\n\t\treturn \"block\";\n\tcase Kind::Message:\n\t\treturn \"msg\";\n\tcase Kind::Transaction:\n\t\treturn \"tx\";\n\tcase Kind::ABI:\n\t\treturn \"abi\";\n\tcase Kind::MetaType:\n\t\tsolAssert(m_typeArgument, \"\");\n\t\treturn \"type(\" + m_typeArgument->toString(_withoutDataLocation) + \")\";\n\tcase Kind::Error:\n\t\treturn \"error\";\n\t}\n\tsolAssert(false, \"Unknown kind of magic.\");\n\treturn {};\n}\n\nType const* MagicType::typeArgument() const\n{\n\tsolAssert(m_kind == Kind::MetaType, \"\");\n\tsolAssert(m_typeArgument, \"\");\n\treturn m_typeArgument;\n}\n\nType const* InaccessibleDynamicType::decodingType() const\n{\n\treturn TypeProvider::integer(256, IntegerType::Modifier::Unsigned);\n}\n"
  },
  {
    "path": "libsolidity/ast/Types.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity data types\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTEnums.h>\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/parsing/Token.h>\n#include <liblangutil/Exceptions.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/Numeric.h>\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/LazyInit.h>\n#include <libsolutil/Result.h>\n\n#include <boost/rational.hpp>\n\n#include <map>\n#include <memory>\n#include <optional>\n#include <set>\n#include <string>\n#include <utility>\n\nnamespace solidity::frontend\n{\n\nclass TypeProvider;\nclass Type; // forward\nclass FunctionType; // forward\nusing FunctionTypePointer = FunctionType const*;\nusing TypePointers = std::vector<Type const*>;\nusing rational = boost::rational<bigint>;\nusing TypeResult = util::Result<Type const*>;\nusing BoolResult = util::Result<bool>;\n\n}\n\nnamespace solidity::frontend\n{\n\ninline rational makeRational(bigint const& _numerator, bigint const& _denominator)\n{\n\tsolAssert(_denominator != 0, \"division by zero\");\n\t// due to a bug in certain versions of boost the denominator has to be positive\n\tif (_denominator < 0)\n\t\treturn rational(-_numerator, -_denominator);\n\telse\n\t\treturn rational(_numerator, _denominator);\n}\n\nenum class DataLocation { Storage, Transient, CallData, Memory };\n\n\n/**\n * Helper class to compute storage offsets of members of structs and contracts.\n */\nclass StorageOffsets\n{\npublic:\n\t/// Resets the StorageOffsets objects and determines the position in storage for each\n\t/// of the elements of @a _types.\n\t/// Calculated positions are absolute and start at @a _baseSlot.\n\t/// Assumes that @a _types is small enough to fit in the area between @a _baseSlot and the end of storage\n\t/// (the caller is responsible for validating that).\n\tvoid computeOffsets(TypePointers const& _types, u256 _baseSlot = 0);\n\t/// @returns the offset of the given member, might be null if the member is not part of storage.\n\tstd::pair<u256, unsigned> const* offset(size_t _index) const;\n\t/// @returns the total number of slots occupied by all members.\n\tu256 const& storageSize() const { return m_storageSize; }\n\nprivate:\n\tu256 m_storageSize;\n\tstd::map<size_t, std::pair<u256, unsigned>> m_offsets;\n};\n\n/**\n * List of members of a type.\n */\nclass MemberList\n{\npublic:\n\tstruct Member\n\t{\n\t\t/// Manual constructor for members that are not taken from a declaration.\n\t\tMember(char const* _name, Type const* _type):\n\t\t\tname(_name),\n\t\t\ttype(_type),\n\t\t\tdeclaration(nullptr)\n\t\t{\n\t\t}\n\n\t\t/// Constructs a Member with the name extracted from @p _declaration's name.\n\t\tMember(Declaration const* _declaration, Type const* _type);\n\t\tMember(Declaration const* _declaration, Type const* _type, std::string _name);\n\n\t\tstd::string name;\n\t\tType const* type = nullptr;\n\t\tDeclaration const* declaration = nullptr;\n\t};\n\n\tusing MemberMap = std::vector<Member>;\n\n\texplicit MemberList(MemberMap _members): m_memberTypes(std::move(_members)) {}\n\n\tvoid combine(MemberList const& _other);\n\tType const* memberType(std::string const& _name) const\n\t{\n\t\tType const* type = nullptr;\n\t\tfor (auto const& it: m_memberTypes)\n\t\t\tif (it.name == _name)\n\t\t\t{\n\t\t\t\tsolAssert(!type, \"Requested member type by non-unique name.\");\n\t\t\t\ttype = it.type;\n\t\t\t}\n\t\treturn type;\n\t}\n\tMemberMap membersByName(std::string const& _name) const\n\t{\n\t\tMemberMap members;\n\t\tfor (auto const& it: m_memberTypes)\n\t\t\tif (it.name == _name)\n\t\t\t\tmembers.push_back(it);\n\t\treturn members;\n\t}\n\t/// @returns the offset of the given member in storage slots and bytes inside a slot or\n\t/// a nullptr if the member is not part of storage.\n\tstd::pair<u256, unsigned> const* memberStorageOffset(std::string const& _name) const;\n\t/// @returns the number of storage slots occupied by the members.\n\tu256 const& storageSize() const;\n\n\tMemberMap::const_iterator begin() const { return m_memberTypes.begin(); }\n\tMemberMap::const_iterator end() const { return m_memberTypes.end(); }\n\nprivate:\n\tStorageOffsets const& storageOffsets() const;\n\n\tMemberMap m_memberTypes;\n\tutil::LazyInit<StorageOffsets> m_storageOffsets;\n};\n\nstatic_assert(std::is_nothrow_move_constructible<MemberList>::value, \"MemberList should be noexcept move constructible\");\n\n/**\n * Abstract base class that forms the root of the type hierarchy.\n */\nclass Type\n{\npublic:\n\tType() = default;\n\tType(Type const&) = delete;\n\tType(Type&&) = delete;\n\tType& operator=(Type const&) = delete;\n\tType& operator=(Type&&) = delete;\n\tvirtual ~Type() = default;\n\n\tenum class Category\n\t{\n\t\tAddress,\n\t\tInteger,\n\t\tRationalNumber,\n\t\tStringLiteral,\n\t\tBool,\n\t\tFixedPoint,\n\t\tArray,\n\t\tArraySlice,\n\t\tFixedBytes,\n\t\tContract,\n\t\tStruct,\n\t\tFunction,\n\t\tEnum,\n\t\tUserDefinedValueType,\n\t\tTuple,\n\t\tMapping,\n\t\tTypeType,\n\t\tModifier,\n\t\tMagic,\n\t\tModule,\n\t\tInaccessibleDynamic\n\t};\n\n\t/// @returns a pointer to _a or _b if the other is implicitly convertible to it or nullptr otherwise\n\tstatic Type const* commonType(Type const* _a, Type const* _b);\n\n\tvirtual Category category() const = 0;\n\t/// @returns a valid solidity identifier such that two types should compare equal if and\n\t/// only if they have the same identifier.\n\t/// The identifier should start with \"t_\".\n\t/// Can contain characters which are invalid in identifiers.\n\tvirtual std::string richIdentifier() const = 0;\n\t/// @returns a valid solidity identifier such that two types should compare equal if and\n\t/// only if they have the same identifier.\n\t/// The identifier should start with \"t_\".\n\t/// Will not contain any character which would be invalid as an identifier.\n\tstd::string identifier() const;\n\n\t/// More complex identifier strings use \"parentheses\", where $_ is interpreted as\n\t/// \"opening parenthesis\", _$ as \"closing parenthesis\", _$_ as \"comma\" and any $ that\n\t/// appears as part of a user-supplied identifier is escaped as _$$$_.\n\t/// @returns an escaped identifier (will not contain any parenthesis or commas)\n\tstatic std::string escapeIdentifier(std::string const& _identifier);\n\n\tvirtual BoolResult isImplicitlyConvertibleTo(Type const& _other) const { return *this == _other; }\n\tvirtual BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const\n\t{\n\t\treturn isImplicitlyConvertibleTo(_convertTo);\n\t}\n\t/// @returns the resulting type of applying the given unary operator or an empty pointer if\n\t/// this is not possible.\n\t/// The default implementation does not allow any unary operator.\n\tvirtual TypeResult unaryOperatorResult(Token) const { return nullptr; }\n\t/// @returns the resulting type of applying the given binary operator or an empty pointer if\n\t/// this is not possible.\n\t/// The default implementation allows comparison operators if a common type exists\n\tvirtual TypeResult binaryOperatorResult(Token _operator, Type const* _other) const\n\t{\n\t\treturn TokenTraits::isCompareOp(_operator) ? commonType(this, _other) : nullptr;\n\t}\n\n\tvirtual bool operator==(Type const& _other) const { return category() == _other.category(); }\n\tvirtual bool operator!=(Type const& _other) const { return !this->operator ==(_other); }\n\n\t/// @returns number of bytes used by this type when encoded for CALL. Cannot be used for\n\t/// dynamically encoded types.\n\t/// Always returns a value greater than zero and throws if the type cannot be encoded in calldata\n\t/// (or is dynamically encoded).\n\t/// If @a _padded then it is assumed that each element is padded to a multiple of 32 bytes.\n\tvirtual unsigned calldataEncodedSize([[maybe_unused]] bool _padded) const { solAssert(false, \"\"); }\n\t/// Convenience version of @see calldataEncodedSize(bool)\n\tunsigned calldataEncodedSize() const { return calldataEncodedSize(true); }\n\t/// @returns the distance between two elements of this type in a calldata array, tuple or struct.\n\t/// For statically encoded types this is the same as calldataEncodedSize(true).\n\t/// For dynamically encoded types this is the distance between two tail pointers, i.e. 32.\n\t/// Always returns a value greater than zero and throws if the type cannot be encoded in calldata.\n\tunsigned calldataHeadSize() const { return isDynamicallyEncoded() ? 32 : calldataEncodedSize(true); }\n\t/// @returns the (minimal) size of the calldata tail for this type. Can only be used for\n\t/// dynamically encoded types. For dynamically-sized arrays this is 32 (the size of the length),\n\t/// for statically-sized, but dynamically encoded arrays this is 32*length(), for structs\n\t/// this is the sum of the calldataHeadSize's of its members.\n\t/// Always returns a value greater than zero and throws if the type cannot be encoded in calldata\n\t/// (or is not dynamically encoded).\n\tvirtual unsigned calldataEncodedTailSize() const { solAssert(false, \"\"); }\n\t/// @returns the size of this data type in bytes when stored in memory. For memory-reference\n\t/// types, this is the size of the memory pointer.\n\tvirtual unsigned memoryHeadSize() const { return calldataEncodedSize(); }\n\t/// @returns the size of this data type in bytes when stored in memory. For memory-reference\n\t/// types, this is the size of the actual data area, if it is statically-sized.\n\tvirtual u256 memoryDataSize() const { return calldataEncodedSize(); }\n\t/// @returns true if the type is a dynamic array\n\tvirtual bool isDynamicallySized() const { return false; }\n\t/// @returns true if the type is dynamically encoded in the ABI\n\tvirtual bool isDynamicallyEncoded() const { return false; }\n\t/// @returns the number of storage slots required to hold this value in storage.\n\t/// For dynamically \"allocated\" types, it returns the size of the statically allocated head,\n\tvirtual u256 storageSize() const { return 1; }\n\t/// @returns an upper bound on the total storage size required by this type, descending\n\t/// into structs and statically-sized arrays. This is mainly to ensure that the storage\n\t/// slot allocation algorithm does not overflow, it is not a protection against collisions.\n\tvirtual bigint storageSizeUpperBound() const { return 1; }\n\t/// Multiple small types can be packed into a single storage slot. If such a packing is possible\n\t/// this function @returns the size in bytes smaller than 32. Data is moved to the next slot if\n\t/// it does not fit.\n\t/// In order to avoid computation at runtime of whether such moving is necessary, structs and\n\t/// array data (not each element) always start a new slot.\n\tvirtual unsigned storageBytes() const { return 32; }\n\t/// Returns true if the type is a value type that is left-aligned on the stack with a size of\n\t/// storageBytes() bytes. Returns false if the type is a value type that is right-aligned on\n\t/// the stack with a size of storageBytes() bytes. Asserts if it is not a value type or the\n\t/// encoding is more complicated.\n\t/// Signed integers are not considered \"more complicated\" even though they need to be\n\t/// sign-extended.\n\tvirtual bool leftAligned() const { solAssert(false, \"Alignment property of non-value type requested.\"); }\n\t/// Returns true if the type can be stored in storage.\n\tvirtual bool canBeStored() const { return true; }\n\t/// Returns false if the type cannot live outside the storage, i.e. if it includes some mapping.\n\tvirtual bool containsNestedMapping() const\n\t{\n\t\tsolAssert(nameable(), \"Called for a non nameable type.\");\n\t\treturn false;\n\t}\n\t/// Returns true if the type can be stored as a value (as opposed to a reference) on the stack,\n\t/// i.e. it behaves differently in lvalue context and in value context.\n\tvirtual bool isValueType() const { return false; }\n\t/// @returns true if this type can be used for variables. It returns false for\n\t/// types like magic types, literals and function types with a kind that is not\n\t/// internal or external.\n\tvirtual bool nameable() const { return false; }\n\t/// @returns a list of named and typed stack items that determine the layout of this type on the stack.\n\t/// A stack item either has an empty name and type ``nullptr`` referring to a single stack slot, or\n\t/// has a non-empty name and a valid type referring to the stack layout of that type.\n\t/// The complete layout of a type on the stack can be obtained from its stack items recursively as follows:\n\t/// - Each unnamed stack item is untyped (its type is ``nullptr``) and contributes exactly one stack slot.\n\t/// - Each named stack item is typed and contributes the stack slots given by the stack items of its type.\n\tstd::vector<std::tuple<std::string, Type const*>> const& stackItems() const\n\t{\n\t\tif (!m_stackItems)\n\t\t\tm_stackItems = makeStackItems();\n\t\treturn *m_stackItems;\n\t}\n\t/// Total number of stack slots occupied by this type. This is the sum of ``sizeOnStack`` of all ``stackItems()``.\n\t// TODO: consider changing the return type to be size_t\n\tunsigned sizeOnStack() const\n\t{\n\t\tif (!m_stackSize)\n\t\t{\n\t\t\tsize_t sizeOnStack = 0;\n\t\t\tfor (auto const& slot: stackItems())\n\t\t\t\tif (std::get<1>(slot))\n\t\t\t\t\tsizeOnStack += std::get<1>(slot)->sizeOnStack();\n\t\t\t\telse\n\t\t\t\t\t++sizeOnStack;\n\t\t\tm_stackSize = sizeOnStack;\n\t\t}\n\t\treturn static_cast<unsigned>(*m_stackSize);\n\t}\n\t/// If it is possible to initialize such a value in memory by just writing zeros\n\t/// of the size memoryHeadSize().\n\tvirtual bool hasSimpleZeroValueInMemory() const { return true; }\n\t/// @returns the mobile (in contrast to static) type corresponding to the given type.\n\t/// This returns the corresponding IntegerType or FixedPointType for RationalNumberType\n\t/// and the pointer type for storage reference types.\n\t/// Might return a null pointer if there is no fitting type.\n\tvirtual Type const* mobileType() const { return this; }\n\t/// @returns true if this is a non-value type and the data of this type is stored at the\n\t/// given location.\n\tvirtual bool dataStoredIn(DataLocation) const { return false; }\n\n\t/// Returns the list of all members of this type. Default implementation: no members apart from attached functions.\n\t/// @param _currentScope scope in which the members are accessed.\n\tMemberList const& members(ASTNode const* _currentScope) const;\n\t/// Convenience method, returns the type of the given named member or an empty pointer if no such member exists.\n\tType const* memberType(std::string const& _name, ASTNode const* _currentScope = nullptr) const\n\t{\n\t\treturn members(_currentScope).memberType(_name);\n\t}\n\n\tvirtual std::string toString(bool _withoutDataLocation) const = 0;\n\tstd::string toString() const { return toString(false); }\n\t/// @returns the canonical name of this type for use in library function signatures.\n\tvirtual std::string canonicalName() const { return toString(true); }\n\tvirtual std::string humanReadableName() const { return toString(); }\n\t/// @returns the signature of this type in external functions, i.e. `uint256` for integers\n\t/// or `(uint256,bytes8)[2]` for an array of structs. If @a _structsByName,\n\t/// structs are given by canonical name like `ContractName.StructName[2]`.\n\tvirtual std::string signatureInExternalFunction(bool /*_structsByName*/) const\n\t{\n\t\treturn canonicalName();\n\t}\n\tvirtual u256 literalValue(Literal const*) const\n\t{\n\t\tsolAssert(false, \"Literal value requested for type without literals: \" + toString(false));\n\t}\n\n\t/// @returns a (simpler) type that is encoded in the same way for external function calls.\n\t/// This for example returns address for contract types.\n\t/// If there is no such type, returns an empty shared pointer.\n\tvirtual Type const* encodingType() const { return nullptr; }\n\t/// @returns the encoding type used under the given circumstances for the type of an expression\n\t/// when used for e.g. abi.encode(...) or the empty pointer if the object\n\t/// cannot be encoded.\n\t/// This is different from encodingType since it takes implicit conversions into account.\n\tType const* fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool _packed) const;\n\t/// @returns a (simpler) type that is used when decoding this type in calldata.\n\tvirtual Type const* decodingType() const { return encodingType(); }\n\t/// @returns a type that will be used outside of Solidity for e.g. function signatures.\n\t/// This for example returns address for contract types.\n\t/// If there is no such type, returns an empty shared pointer.\n\t/// @param _inLibrary if set, returns types as used in a library, e.g. struct and contract types\n\t/// are returned without modification.\n\tvirtual TypeResult interfaceType(bool /*_inLibrary*/) const { return nullptr; }\n\n\t/// @returns the declaration of a user defined type (enum, struct, user defined value type).\n\t/// Returns nullptr otherwise.\n\tvirtual Declaration const* typeDefinition() const { return nullptr; }\n\n\t/// Clears all internally cached values (if any).\n\tvirtual void clearCache() const;\n\n\t/// Scans all \"using for\" directives in the @a _scope for functions implementing\n\t/// the operator represented by @a _token. Returns the set of all definitions where the type\n\t/// of the first argument matches this type object.\n\t///\n\t/// @note: If the AST has passed analysis without errors,\n\t/// the function will find at most one definition for an operator.\n\t///\n\t/// @param _unary If true, only definitions that accept exactly one argument are included.\n\t/// Otherwise only definitions that accept exactly two arguments.\n\tstd::set<FunctionDefinition const*, ASTCompareByID<ASTNode>> operatorDefinitions(\n\t\tToken _token,\n\t\tASTNode const& _scope,\n\t\tbool _unary\n\t) const;\n\nprivate:\n\t/// @returns a member list containing all members added to this type by `using for` directives.\n\tstatic MemberList::MemberMap attachedFunctions(Type const& _type, ASTNode const& _scope);\n\nprotected:\n\t/// @returns the members native to this type depending on the given context. This function\n\t/// is used (in conjunction with attachedFunctions to fill m_members below.\n\tvirtual MemberList::MemberMap nativeMembers(ASTNode const* /*_currentScope*/) const\n\t{\n\t\treturn MemberList::MemberMap();\n\t}\n\t/// Generates the stack items to be returned by ``stackItems()``. Defaults\n\t/// to exactly one unnamed and untyped stack item referring to a single stack slot.\n\tvirtual std::vector<std::tuple<std::string, Type const*>> makeStackItems() const\n\t{\n\t\treturn {std::make_tuple(std::string(), nullptr)};\n\t}\n\n\n\t/// List of member types (parameterised by scape), will be lazy-initialized.\n\tmutable std::map<ASTNode const*, std::unique_ptr<MemberList>> m_members;\n\tmutable std::optional<std::vector<std::tuple<std::string, Type const*>>> m_stackItems;\n\tmutable std::optional<size_t> m_stackSize;\n};\n\n/**\n * Type for addresses.\n */\nclass AddressType: public Type\n{\npublic:\n\texplicit AddressType(StateMutability _stateMutability);\n\n\tCategory category() const override { return Category::Address; }\n\n\tstd::string richIdentifier() const override;\n\tBoolResult isImplicitlyConvertibleTo(Type const& _other) const override;\n\tBoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tTypeResult unaryOperatorResult(Token _operator) const override;\n\tTypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;\n\n\tbool operator==(Type const& _other) const override;\n\n\tunsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : 160 / 8; }\n\tunsigned storageBytes() const override { return 160 / 8; }\n\tbool leftAligned() const override { return false; }\n\tbool isValueType() const override { return true; }\n\tbool nameable() const override { return true; }\n\n\tMemberList::MemberMap nativeMembers(ASTNode const*) const override;\n\n\tstd::string toString(bool _withoutDataLocation) const override;\n\tstd::string canonicalName() const override;\n\n\tu256 literalValue(Literal const* _literal) const override;\n\n\tType const* encodingType() const override { return this; }\n\tTypeResult interfaceType(bool) const override { return this; }\n\n\tStateMutability stateMutability(void) const { return m_stateMutability; }\n\nprivate:\n\tStateMutability m_stateMutability;\n};\n\n/**\n * Any kind of integer type (signed, unsigned).\n */\nclass IntegerType: public Type\n{\npublic:\n\tenum class Modifier\n\t{\n\t\tUnsigned, Signed\n\t};\n\n\texplicit IntegerType(unsigned _bits, Modifier _modifier = Modifier::Unsigned);\n\n\tCategory category() const override { return Category::Integer; }\n\n\tstd::string richIdentifier() const override;\n\tBoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tBoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tTypeResult unaryOperatorResult(Token _operator) const override;\n\tTypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;\n\n\tbool operator==(IntegerType const& _other) const;\n\tbool operator==(Type const& _other) const override;\n\n\tunsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_bits / 8; }\n\tunsigned storageBytes() const override { return m_bits / 8; }\n\tbool leftAligned() const override { return false; }\n\tbool isValueType() const override { return true; }\n\tbool nameable() const override { return true; }\n\n\tstd::string toString(bool _withoutDataLocation) const override;\n\n\tType const* encodingType() const override { return this; }\n\tTypeResult interfaceType(bool) const override { return this; }\n\n\tunsigned numBits() const { return m_bits; }\n\tbool isSigned() const { return m_modifier == Modifier::Signed; }\n\n\tu256 min() const;\n\tu256 max() const;\n\n\tbigint minValue() const;\n\tbigint maxValue() const;\n\nprivate:\n\tunsigned const m_bits;\n\tModifier const m_modifier;\n};\n\n/**\n * A fixed point type number (signed, unsigned).\n */\nclass FixedPointType: public Type\n{\npublic:\n\tenum class Modifier\n\t{\n\t\tUnsigned, Signed\n\t};\n\n\texplicit FixedPointType(unsigned _totalBits, unsigned _fractionalDigits, Modifier _modifier = Modifier::Unsigned);\n\tCategory category() const override { return Category::FixedPoint; }\n\n\tstd::string richIdentifier() const override;\n\tBoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tBoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tTypeResult unaryOperatorResult(Token _operator) const override;\n\tTypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;\n\n\tbool operator==(Type const& _other) const override;\n\n\tunsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_totalBits / 8; }\n\tunsigned storageBytes() const override { return m_totalBits / 8; }\n\tbool leftAligned() const override { return false; }\n\tbool isValueType() const override { return true; }\n\tbool nameable() const override { return true; }\n\n\tstd::string toString(bool _withoutDataLocation) const override;\n\n\tType const* encodingType() const override { return this; }\n\tTypeResult interfaceType(bool) const override { return this; }\n\n\t/// Number of bits used for this type in total.\n\tunsigned numBits() const { return m_totalBits; }\n\t/// Number of decimal digits after the radix point.\n\tunsigned fractionalDigits() const { return m_fractionalDigits; }\n\tbool isSigned() const { return m_modifier == Modifier::Signed; }\n\t/// @returns the largest integer value this type con hold. Note that this is not the\n\t/// largest value in general.\n\tbigint maxIntegerValue() const;\n\t/// @returns the smallest integer value this type can hold. Note hat this is not the\n\t/// smallest value in general.\n\tbigint minIntegerValue() const;\n\n\t/// @returns the smallest integer type that can hold this type with fractional parts shifted to integers.\n\tIntegerType const* asIntegerType() const;\n\nprivate:\n\tunsigned m_totalBits;\n\tunsigned m_fractionalDigits;\n\tModifier m_modifier;\n};\n\n/**\n * Integer and fixed point constants either literals or computed.\n * Example expressions: 2, 3.14, 2+10.2, ~10.\n * There is one distinct type per value.\n */\nclass RationalNumberType: public Type\n{\npublic:\n\texplicit RationalNumberType(rational _value, Type const* _compatibleBytesType = nullptr):\n\t\tm_value(std::move(_value)), m_compatibleBytesType(_compatibleBytesType)\n\t{}\n\n\tCategory category() const override { return Category::RationalNumber; }\n\n\tBoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tBoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tTypeResult unaryOperatorResult(Token _operator) const override;\n\tTypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;\n\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\n\tbool canBeStored() const override { return false; }\n\n\tstd::string toString(bool _withoutDataLocation) const override;\n\tu256 literalValue(Literal const* _literal) const override;\n\tType const* mobileType() const override;\n\n\t/// @returns the underlying raw literal value.\n\t///\n\t/// @see literalValue(Literal const*))\n\trational const& value() const noexcept { return m_value; }\n\n\t/// @returns the smallest integer type that can hold the value or an empty pointer if not possible.\n\tIntegerType const* integerType() const;\n\t/// @returns the smallest fixed type that can hold the value or incurs the least precision loss,\n\t/// unless the value was truncated, then a suitable type will be chosen to indicate such event.\n\t/// If the integer part does not fit, returns an empty pointer.\n\tFixedPointType const* fixedPointType() const;\n\n\t/// @returns true if the value is not an integer.\n\tbool isFractional() const { return m_value.denominator() != 1; }\n\n\t/// @returns true if the value is negative.\n\tbool isNegative() const { return m_value < 0; }\n\n\t/// @returns true if the value is zero.\n\tbool isZero() const { return m_value == 0; }\n\n\t/// @returns true if the literal is a valid integer.\n\tstatic std::tuple<bool, rational> isValidLiteral(Literal const& _literal);\n\nprivate:\n\trational m_value;\n\n\t/// Bytes type to which the rational can be implicitly converted.\n\t/// Empty for all rationals that are not directly parsed from hex literals.\n\tType const* m_compatibleBytesType;\n\n\t/// @returns true if the literal is a valid rational number.\n\tstatic std::tuple<bool, rational> parseRational(std::string const& _value);\n\n\t/// @returns a truncated readable representation of the bigint keeping only\n\t/// up to 4 leading and 4 trailing digits.\n\tstatic std::string bigintToReadableString(bigint const& num);\n};\n\n/**\n * Literal string, can be converted to bytes, bytesX or string.\n */\nclass StringLiteralType: public Type\n{\npublic:\n\texplicit StringLiteralType(Literal const& _literal);\n\texplicit StringLiteralType(std::string _value);\n\n\tCategory category() const override { return Category::StringLiteral; }\n\n\tBoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tTypeResult binaryOperatorResult(Token, Type const*) const override\n\t{\n\t\treturn nullptr;\n\t}\n\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\n\tbool canBeStored() const override { return false; }\n\n\tstd::string toString(bool) const override;\n\tType const* mobileType() const override;\n\n\tstd::string const& value() const { return m_value; }\n\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override { return {}; }\nprivate:\n\tstd::string m_value;\n};\n\n/**\n * Bytes type with fixed length of up to 32 bytes.\n */\nclass FixedBytesType: public Type\n{\npublic:\n\texplicit FixedBytesType(unsigned _bytes);\n\n\tCategory category() const override { return Category::FixedBytes; }\n\n\tBoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tBoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tTypeResult unaryOperatorResult(Token _operator) const override;\n\tTypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;\n\n\tunsigned calldataEncodedSize(bool _padded) const override { return _padded && m_bytes > 0 ? 32 : m_bytes; }\n\tunsigned storageBytes() const override { return m_bytes; }\n\tbool leftAligned() const override { return true; }\n\tbool isValueType() const override { return true; }\n\tbool nameable() const override { return true; }\n\n\tstd::string toString(bool) const override { return \"bytes\" + util::toString(m_bytes); }\n\tMemberList::MemberMap nativeMembers(ASTNode const*) const override;\n\tType const* encodingType() const override { return this; }\n\tTypeResult interfaceType(bool) const override { return this; }\n\n\tunsigned numBytes() const { return m_bytes; }\n\nprivate:\n\tunsigned m_bytes;\n};\n\n/**\n * The boolean type.\n */\nclass BoolType: public Type\n{\npublic:\n\tCategory category() const override { return Category::Bool; }\n\tstd::string richIdentifier() const override { return \"t_bool\"; }\n\tTypeResult unaryOperatorResult(Token _operator) const override;\n\tTypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;\n\n\tunsigned calldataEncodedSize(bool _padded) const override{ return _padded ? 32 : 1; }\n\tunsigned storageBytes() const override { return 1; }\n\tbool leftAligned() const override { return false; }\n\tbool isValueType() const override { return true; }\n\tbool nameable() const override { return true; }\n\n\tstd::string toString(bool) const override { return \"bool\"; }\n\tu256 literalValue(Literal const* _literal) const override;\n\tType const* encodingType() const override { return this; }\n\tTypeResult interfaceType(bool) const override { return this; }\n};\n\n/**\n * Base class for types which can be thought of as several elements of other types put together.\n * For example a struct is composed of its members, an array is composed of multiple copies of its\n * base element and a mapping is composed of its value type elements (note that keys are not\n * stored anywhere).\n */\nclass CompositeType: public Type\n{\nprotected:\n\tCompositeType() = default;\n\npublic:\n\t/// @returns a list containing the type itself, elements of its decomposition,\n\t/// elements of decomposition of these elements and so on, up to non-composite types.\n\t/// Each type is included only once.\n\tstd::vector<Type const*> fullDecomposition() const;\n\nprotected:\n\t/// @returns a list of types that together make up the data part of this type.\n\t/// Contains all types that will have to be implicitly stored, whenever an object of this type is stored.\n\t/// In particular, it returns the base type for arrays and array slices, the member types for structs,\n\t/// the component types for tuples and the value type for mappings\n\t/// (note that the key type of a mapping is *not* part of the list).\n\tvirtual std::vector<Type const*> decomposition() const = 0;\n};\n\n/**\n * Base class used by types which are not value types and can be stored either in storage, memory\n * or calldata. This is currently used by arrays and structs.\n */\nclass ReferenceType: public CompositeType\n{\nprotected:\n\texplicit ReferenceType(DataLocation _location): m_location(_location) {}\n\npublic:\n\tDataLocation location() const { return m_location; }\n\n\tTypeResult unaryOperatorResult(Token _operator) const override;\n\tTypeResult binaryOperatorResult(Token, Type const*) const override\n\t{\n\t\treturn nullptr;\n\t}\n\tunsigned memoryHeadSize() const override { return 32; }\n\tu256 memoryDataSize() const override = 0;\n\n\tunsigned calldataEncodedSize(bool) const override = 0;\n\tunsigned calldataEncodedTailSize() const override = 0;\n\n\t/// @returns a copy of this type with location (recursively) changed to @a _location,\n\t/// whereas isPointer is only shallowly changed - the deep copy is always a bound reference.\n\tvirtual std::unique_ptr<ReferenceType> copyForLocation(DataLocation _location, bool _isPointer) const = 0;\n\n\tType const* mobileType() const override { return withLocation(m_location, true); }\n\tbool dataStoredIn(DataLocation _location) const override { return m_location == _location; }\n\tbool hasSimpleZeroValueInMemory() const override { return false; }\n\n\t/// Storage references can be pointers or bound references. In general, local variables are of\n\t/// pointer type, state variables are bound references. Assignments to pointers or deleting\n\t/// them will not modify storage (that will only change the pointer). Assignment from\n\t/// non-storage objects to a variable of storage pointer type is not possible.\n\t/// For anything other than storage, this always returns true because assignments\n\t/// never change the contents of the original value.\n\tbool isPointer() const;\n\n\t/// @returns true if this is valid to be stored in data location _loc\n\t/// The function mostly checks sizes. For calldata, this should only be called\n\t/// if the type has an interfaceType.\n\tvirtual BoolResult validForLocation(DataLocation _loc) const = 0;\n\n\tbool equals(ReferenceType const& _other) const\n\t{\n\t\treturn location() == _other.location() && isPointer() == _other.isPointer();\n\t}\n\n\tType const* withLocation(DataLocation _location, bool _isPointer) const;\n\nprotected:\n\tType const* copyForLocationIfReference(Type const* _type) const;\n\t/// @returns a human-readable description of the reference part of the type.\n\tstd::string stringForReferencePart() const;\n\t/// @returns the suffix computed from the reference part to be used by identifier();\n\tstd::string identifierLocationSuffix() const;\n\n\tDataLocation m_location = DataLocation::Storage;\n\tbool m_isPointer = true;\n};\n\n/**\n * The type of an array. The flavours are byte array (bytes), statically- (<type>[<length>])\n * and dynamically-sized array (<type>[]).\n * In storage, all arrays are packed tightly (as long as more than one elementary type fits in\n * one slot). Dynamically sized arrays (including byte arrays) start with their size as a uint and\n * thus start on their own slot.\n */\nclass ArrayType: public ReferenceType\n{\npublic:\n\t/// Constructor for a byte array (\"bytes\") and string.\n\texplicit ArrayType(DataLocation _location, bool _isString = false);\n\n\t/// Constructor for a dynamically sized array type (\"<type>[]\")\n\tArrayType(DataLocation _location, Type const* _baseType):\n\t\tReferenceType(_location),\n\t\tm_baseType(copyForLocationIfReference(_baseType))\n\t{\n\t}\n\n\t/// Constructor for a fixed-size array type (\"<type>[<length>]\")\n\tArrayType(DataLocation _location, Type const* _baseType, u256 _length):\n\t\tReferenceType(_location),\n\t\tm_baseType(copyForLocationIfReference(_baseType)),\n\t\tm_hasDynamicLength(false),\n\t\tm_length(std::move(_length))\n\t{}\n\n\tCategory category() const override { return Category::Array; }\n\n\tBoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tBoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tstd::string richIdentifier() const override;\n\tbool operator==(ArrayType const& _other) const;\n\tbool operator==(Type const& _other) const override;\n\tunsigned calldataEncodedSize(bool) const override;\n\tunsigned calldataEncodedTailSize() const override;\n\tbool isDynamicallySized() const override { return m_hasDynamicLength; }\n\tbool isDynamicallyEncoded() const override;\n\tbigint storageSizeUpperBound() const override;\n\tu256 storageSize() const override;\n\tbool containsNestedMapping() const override { return m_baseType->containsNestedMapping(); }\n\tbool nameable() const override { return true; }\n\n\tstd::string toString(bool _withoutDataLocation) const override;\n\tstd::string humanReadableName() const override;\n\tstd::string canonicalName() const override;\n\tstd::string signatureInExternalFunction(bool _structsByName) const override;\n\tMemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;\n\tType const* encodingType() const override;\n\tType const* decodingType() const override;\n\tTypeResult interfaceType(bool _inLibrary) const override;\n\n\tBoolResult validForLocation(DataLocation _loc) const override;\n\n\t/// @returns true if this is a byte array.\n\tbool isByteArray() const { return m_arrayKind == ArrayKind::Bytes; }\n\t/// @returns true if this is a byte array or a string\n\tbool isByteArrayOrString() const { return m_arrayKind != ArrayKind::Ordinary; }\n\t/// @returns true if this is a string\n\tbool isString() const { return m_arrayKind == ArrayKind::String; }\n\tType const* baseType() const { solAssert(!!m_baseType, \"\"); return m_baseType; }\n\tType const* finalBaseType(bool breakIfDynamicArrayType) const;\n\tu256 const& length() const { return m_length; }\n\tu256 memoryDataSize() const override;\n\n\tstd::unique_ptr<ReferenceType> copyForLocation(DataLocation _location, bool _isPointer) const override;\n\n\t/// The offset to advance in calldata to move from one array element to the next.\n\tunsigned calldataStride() const { return isByteArrayOrString() ? 1 : m_baseType->calldataHeadSize(); }\n\t/// The offset to advance in memory to move from one array element to the next.\n\tunsigned memoryStride() const { return isByteArrayOrString() ? 1 : m_baseType->memoryHeadSize(); }\n\t/// The offset to advance in storage to move from one array element to the next.\n\tunsigned storageStride() const { return isByteArrayOrString() ? 1 : m_baseType->storageBytes(); }\n\n\tvoid clearCache() const override;\n\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;\n\tstd::vector<Type const*> decomposition() const override { return {m_baseType}; }\n\nprivate:\n\tenum class ArrayKind { Ordinary, Bytes, String };\n\n\tbigint unlimitedStaticCalldataSize(bool _padded) const;\n\n\t///< Byte arrays (\"bytes\") and strings have different semantics from ordinary arrays.\n\tArrayKind m_arrayKind = ArrayKind::Ordinary;\n\tType const* m_baseType;\n\tbool m_hasDynamicLength = true;\n\tu256 m_length;\n\tmutable std::optional<TypeResult> m_interfaceType;\n\tmutable std::optional<TypeResult> m_interfaceType_library;\n};\n\nclass ArraySliceType: public ReferenceType\n{\npublic:\n\texplicit ArraySliceType(ArrayType const& _arrayType): ReferenceType(_arrayType.location()), m_arrayType(_arrayType) {}\n\tCategory category() const override { return Category::ArraySlice; }\n\n\tBoolResult isImplicitlyConvertibleTo(Type const& _other) const override;\n\tBoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tunsigned calldataEncodedSize(bool) const override { solAssert(false, \"\"); }\n\tunsigned calldataEncodedTailSize() const override { return 32; }\n\tbool isDynamicallySized() const override { return true; }\n\tbool isDynamicallyEncoded() const override { return true; }\n\tstd::string toString(bool _withoutDataLocation) const override;\n\tstd::string humanReadableName() const override;\n\tType const* mobileType() const override;\n\n\tBoolResult validForLocation(DataLocation _loc) const override { return m_arrayType.validForLocation(_loc); }\n\n\tArrayType const& arrayType() const { return m_arrayType; }\n\tu256 memoryDataSize() const override { solAssert(false, \"\"); }\n\n\tstd::unique_ptr<ReferenceType> copyForLocation(DataLocation, bool) const override { solAssert(false, \"\"); }\n\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;\n\tstd::vector<Type const*> decomposition() const override { return {m_arrayType.baseType()}; }\n\nprivate:\n\tArrayType const& m_arrayType;\n};\n\n/**\n * The type of a contract instance or library, there is one distinct type for each contract definition.\n */\nclass ContractType: public Type\n{\npublic:\n\texplicit ContractType(ContractDefinition const& _contract, bool _super = false):\n\t\tm_contract(_contract), m_super(_super) {}\n\n\tCategory category() const override { return Category::Contract; }\n\t/// Contracts can be implicitly converted only to base contracts.\n\tBoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;\n\t/// Contracts can only be explicitly converted to address types and base contracts.\n\tBoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tTypeResult unaryOperatorResult(Token _operator) const override;\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tunsigned calldataEncodedSize(bool _padded ) const override\n\t{\n\t\tsolAssert(!isSuper(), \"\");\n\t\treturn encodingType()->calldataEncodedSize(_padded);\n\t}\n\tunsigned storageBytes() const override { solAssert(!isSuper(), \"\"); return 20; }\n\tbool leftAligned() const override { solAssert(!isSuper(), \"\"); return false; }\n\tbool isValueType() const override { return !isSuper(); }\n\tbool nameable() const override { return !isSuper(); }\n\tstd::string toString(bool _withoutDataLocation) const override;\n\tstd::string canonicalName() const override;\n\n\tMemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;\n\n\tType const* encodingType() const override;\n\n\tTypeResult interfaceType(bool _inLibrary) const override\n\t{\n\t\tif (isSuper())\n\t\t\treturn nullptr;\n\t\treturn _inLibrary ? this : encodingType();\n\t}\n\n\t/// See documentation of m_super\n\tbool isSuper() const { return m_super; }\n\n\t// @returns true if and only if the contract has a receive ether function or a payable fallback function, i.e.\n\t// if it has code that will be executed on plain ether transfers\n\tbool isPayable() const;\n\n\tContractDefinition const& contractDefinition() const { return m_contract; }\n\n\t/// Returns the function type of the constructor modified to return an object of the contract's type.\n\tFunctionType const* newExpressionType() const;\n\n\t/// @returns a list of all state variables in the linearized inheritance hierarchy and\n\t/// their respective slots and offsets in storage/transient storage.\n\t/// It should only be called for the top level contract in order to get the absolute slots and\n\t/// offsets values in storage/transient storage. Otherwise, the slots of the state variables\n\t/// will be relative to the contract position in the hierarchy.\n\tstd::vector<std::tuple<VariableDeclaration const*, u256, unsigned>> linearizedStateVariables(DataLocation _location) const;\n\t/// @returns a list of all immutable variables (including inherited) of the contract.\n\tstd::vector<VariableDeclaration const*> immutableVariables() const;\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;\nprivate:\n\tContractDefinition const& m_contract;\n\t/// If true, this is a special \"super\" type of m_contract containing only members that m_contract inherited\n\tbool m_super = false;\n\t/// Type of the constructor, @see constructorType. Lazily initialized.\n\tmutable FunctionType const* m_constructorType = nullptr;\n};\n\n/**\n * The type of a struct instance, there is one distinct type per struct definition.\n */\nclass StructType: public ReferenceType\n{\npublic:\n\texplicit StructType(StructDefinition const& _struct, DataLocation _location = DataLocation::Storage):\n\t\tReferenceType(_location), m_struct(_struct) {}\n\n\tCategory category() const override { return Category::Struct; }\n\tBoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tunsigned calldataEncodedSize(bool) const override;\n\tunsigned calldataEncodedTailSize() const override;\n\tbool isDynamicallyEncoded() const override;\n\tu256 memoryDataSize() const override;\n\tbigint storageSizeUpperBound() const override;\n\tu256 storageSize() const override;\n\tbool containsNestedMapping() const override;\n\tbool nameable() const override { return true; }\n\tstd::string toString(bool _withoutDataLocation) const override;\n\n\tMemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;\n\n\tType const* encodingType() const override;\n\tTypeResult interfaceType(bool _inLibrary) const override;\n\n\tDeclaration const* typeDefinition() const override;\n\n\tBoolResult validForLocation(DataLocation _loc) const override;\n\n\tbool recursive() const;\n\n\tstd::unique_ptr<ReferenceType> copyForLocation(DataLocation _location, bool _isPointer) const override;\n\n\tstd::string canonicalName() const override;\n\tstd::string signatureInExternalFunction(bool _structsByName) const override;\n\n\t/// @returns a function that performs the type conversion between a list of struct members\n\t/// and a memory struct of this type.\n\tFunctionType const* constructorType() const;\n\n\tstd::pair<u256, unsigned> const& storageOffsetsOfMember(std::string const& _name) const;\n\tu256 memoryOffsetOfMember(std::string const& _name) const;\n\tunsigned calldataOffsetOfMember(std::string const& _name) const;\n\n\tStructDefinition const& structDefinition() const { return m_struct; }\n\n\t/// @returns the vector of types of members available in memory.\n\tTypePointers memoryMemberTypes() const;\n\n\tvoid clearCache() const override;\n\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;\n\tstd::vector<Type const*> decomposition() const override;\n\nprivate:\n\tStructDefinition const& m_struct;\n\t// Caches for interfaceType(bool)\n\tmutable std::optional<TypeResult> m_interfaceType;\n\tmutable std::optional<TypeResult> m_interfaceType_library;\n};\n\n/**\n * The type of an enum instance, there is one distinct type per enum definition.\n */\nclass EnumType: public Type\n{\npublic:\n\texplicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}\n\n\tCategory category() const override { return Category::Enum; }\n\tTypeResult unaryOperatorResult(Token _operator) const override;\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tunsigned calldataEncodedSize(bool _padded) const override\n\t{\n\t\treturn encodingType()->calldataEncodedSize(_padded);\n\t}\n\tunsigned storageBytes() const override;\n\tbool leftAligned() const override { return false; }\n\tstd::string toString(bool _withoutDataLocation) const override;\n\tstd::string canonicalName() const override;\n\tbool isValueType() const override { return true; }\n\tbool nameable() const override { return true; }\n\n\tBoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tType const* encodingType() const override;\n\tTypeResult interfaceType(bool _inLibrary) const override\n\t{\n\t\treturn _inLibrary ? this : encodingType();\n\t}\n\n\tDeclaration const* typeDefinition() const override;\n\n\tEnumDefinition const& enumDefinition() const { return m_enum; }\n\t/// @returns the value that the string has in the Enum\n\tunsigned int memberValue(ASTString const& _member) const;\n\tsize_t numberOfMembers() const;\n\tunsigned int minValue() const { return 0; }\n\tunsigned int maxValue() const\n\t{\n\t\tsolAssert(numberOfMembers() <= 256, \"\");\n\t\treturn static_cast<unsigned int>(numberOfMembers()) - 1;\n\t}\n\nprivate:\n\tEnumDefinition const& m_enum;\n};\n\n/**\n * The type of a UserDefinedValueType.\n */\nclass UserDefinedValueType: public Type\n{\npublic:\n\texplicit UserDefinedValueType(UserDefinedValueTypeDefinition const& _definition):\n\t\tm_definition(_definition)\n\t{}\n\n\tCategory category() const override { return Category::UserDefinedValueType; }\n\tType const& underlyingType() const;\n\tUserDefinedValueTypeDefinition const& definition() const { return m_definition; }\n\n\tTypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }\n\tType const* encodingType() const override { return &underlyingType(); }\n\tTypeResult interfaceType(bool /* _inLibrary */) const override {return &underlyingType(); }\n\n\tDeclaration const* typeDefinition() const override;\n\n\tstd::string richIdentifier() const override;\n\tbool operator==(UserDefinedValueType const& _other) const;\n\tbool operator==(Type const& _other) const override;\n\n\tunsigned calldataEncodedSize(bool _padded) const override { return underlyingType().calldataEncodedSize(_padded); }\n\n\tbool leftAligned() const override { return underlyingType().leftAligned(); }\n\tbool canBeStored() const override { return underlyingType().canBeStored(); }\n\tu256 storageSize() const override { return underlyingType().storageSize(); }\n\tunsigned storageBytes() const override { return underlyingType().storageBytes(); }\n\n\tbool isValueType() const override { return true; }\n\tbool nameable() const override\n\t{\n\t\tsolAssert(underlyingType().nameable(), \"\");\n\t\treturn true;\n\t}\n\n\tbool containsNestedMapping() const override\n\t{\n\t\tsolAssert(nameable(), \"Called for a non nameable type.\");\n\t\t// DeclarationTypeChecker::endVisit(VariableDeclaration const&)\n\t\t// assumes that this will never be true.\n\t\tsolAssert(!underlyingType().containsNestedMapping(), \"\");\n\t\treturn false;\n\t}\n\n\tbool hasSimpleZeroValueInMemory() const override\n\t{\n\t\tsolAssert(underlyingType().hasSimpleZeroValueInMemory(), \"\");\n\t\treturn true;\n\t}\n\n\tbool dataStoredIn(DataLocation _loc) const override\n\t{\n\t\tsolAssert(!underlyingType().dataStoredIn(_loc), \"\");\n\t\treturn false;\n\t}\n\n\tstd::string toString(bool _withoutDataLocation) const override;\n\tstd::string canonicalName() const override;\n\tstd::string signatureInExternalFunction(bool) const override { solAssert(false, \"\"); }\n\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;\n\nprivate:\n\tUserDefinedValueTypeDefinition const& m_definition;\n};\n\n/**\n * Type that can hold a finite sequence of values of different types.\n * In some cases, the components are empty pointers (when used as placeholders).\n */\nclass TupleType: public CompositeType\n{\npublic:\n\texplicit TupleType(std::vector<Type const*> _types = {}): m_components(std::move(_types)) {}\n\n\tCategory category() const override { return Category::Tuple; }\n\n\tBoolResult isImplicitlyConvertibleTo(Type const& _other) const override;\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tTypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }\n\tstd::string toString(bool _withoutDataLocation) const override;\n\tstd::string humanReadableName() const override;\n\tbool canBeStored() const override { return false; }\n\tu256 storageSize() const override;\n\tbool hasSimpleZeroValueInMemory() const override { return false; }\n\tType const* mobileType() const override;\n\n\tstd::vector<Type const*> const& components() const { return m_components; }\n\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;\n\tstd::vector<Type const*> decomposition() const override\n\t{\n\t\t// Currently calling TupleType::decomposition() is not expected, because we cannot declare a variable of a tuple type.\n\t\t// If that changes, before removing the solAssert, make sure the function does the right thing and is used properly.\n\t\t// Note that different tuple members can have different data locations, so using decomposition() to check\n\t\t// the tuple validity for a data location might require special care.\n\t\tsolUnimplemented(\"Tuple decomposition is not expected.\");\n\t\treturn m_components;\n\t}\n\nprivate:\n\tstd::vector<Type const*> const m_components;\n};\n\n/**\n * The type of a function, identified by its (return) parameter types.\n * @todo the return parameters should also have names, i.e. return parameters should be a struct\n * type.\n */\nclass FunctionType: public Type\n{\npublic:\n\t/// How this function is invoked on the EVM.\n\tenum class Kind\n\t{\n\t\tInternal, ///< stack-call using plain JUMP\n\t\tExternal, ///< external call using CALL\n\t\tDelegateCall, ///< external call using DELEGATECALL, i.e. not exchanging the storage\n\t\tBareCall, ///< CALL without function hash\n\t\tBareCallCode, ///< CALLCODE without function hash\n\t\tBareDelegateCall, ///< DELEGATECALL without function hash\n\t\tBareStaticCall, ///< STATICCALL without function hash\n\t\tCreation, ///< external call using CREATE\n\t\tSend, ///< CALL, but without data and gas\n\t\tTransfer, ///< CALL, but without data and throws on error\n\t\tKECCAK256, ///< KECCAK256\n\t\tERC7201, ///< erc7201(...)\n\t\tSelfdestruct, ///< SELFDESTRUCT\n\t\tRevert, ///< REVERT\n\t\tECRecover, ///< CALL to special contract for ecrecover\n\t\tSHA256, ///< CALL to special contract for sha256\n\t\tRIPEMD160, ///< CALL to special contract for ripemd160\n\t\tEvent, ///< syntactic sugar for LOG*\n\t\tError, ///< creating an error instance in revert or require\n\t\tWrap, ///< customType.wrap(...) for user defined value types\n\t\tUnwrap, ///< customType.unwrap(...) for user defined value types\n\t\tSetGas, ///< modify the default gas value for the function call\n\t\tSetValue, ///< modify the default value transfer for the function call\n\t\tBlockHash, ///< BLOCKHASH\n\t\tBlobHash, ///< BLOBHASH\n\t\tAddMod, ///< ADDMOD\n\t\tMulMod, ///< MULMOD\n\t\tArrayPush, ///< .push() to a dynamically sized array in storage\n\t\tArrayPop, ///< .pop() from a dynamically sized array in storage\n\t\tBytesConcat, ///< .concat() on bytes (type type)\n\t\tStringConcat, ///< .concat() on string (type type)\n\t\tObjectCreation, ///< array creation using new\n\t\tAssert, ///< assert()\n\t\tRequire, ///< require()\n\t\tABIEncode,\n\t\tABIEncodePacked,\n\t\tABIEncodeWithSelector,\n\t\tABIEncodeCall,\n\t\tABIEncodeWithSignature,\n\t\tABIDecode,\n\t\tGasLeft, ///< gasleft()\n\t\tMetaType, ///< type(...)\n\t\t/// Refers to a function declaration without calling context\n\t\t/// (i.e. when accessed directly via the name of the containing contract).\n\t\t/// Cannot be called.\n\t\tDeclaration,\n\t};\n\tstruct Options\n\t{\n\t\t/// true iff the function takes an arbitrary number of arguments of arbitrary types\n\t\tbool arbitraryParameters = false;\n\t\t/// true iff the gas value to be used is on the stack\n\t\tbool gasSet = false;\n\t\t/// true iff the value to be sent is on the stack\n\t\tbool valueSet = false;\n\t\t/// iff the salt value (for create2) to be used is on the stack\n\t\tbool saltSet = false;\n\t\t/// true iff the function is called as arg1.fun(arg2, ..., argn).\n\t\t/// This is achieved through the \"using for\" directive.\n\t\tbool hasBoundFirstArgument = false;\n\n\t\tstatic Options withArbitraryParameters()\n\t\t{\n\t\t\tOptions result;\n\t\t\tresult.arbitraryParameters = true;\n\t\t\treturn result;\n\t\t}\n\t\tstatic Options fromFunctionType(FunctionType const& _type)\n\t\t{\n\t\t\tOptions result;\n\t\t\tresult.arbitraryParameters = _type.takesArbitraryParameters();\n\t\t\tresult.gasSet = _type.gasSet();\n\t\t\tresult.valueSet = _type.valueSet();\n\t\t\tresult.saltSet = _type.saltSet();\n\t\t\tresult.hasBoundFirstArgument = _type.hasBoundFirstArgument();\n\t\t\treturn result;\n\t\t}\n\t};\n\n\n\t/// Creates the type of a function.\n\t/// @arg _kind must be Kind::Internal, Kind::External or Kind::Declaration.\n\texplicit FunctionType(FunctionDefinition const& _function, Kind _kind = Kind::Declaration);\n\t/// Creates the accessor function type of a state variable.\n\texplicit FunctionType(VariableDeclaration const& _varDecl);\n\t/// Creates the function type of an event.\n\texplicit FunctionType(EventDefinition const& _event);\n\texplicit FunctionType(ErrorDefinition const& _error);\n\t/// Creates the type of a function type name.\n\texplicit FunctionType(FunctionTypeName const& _typeName);\n\t/// Function type constructor to be used for a plain type (not derived from a declaration).\n\tFunctionType(\n\t\tstrings const& _parameterTypes,\n\t\tstrings const& _returnParameterTypes,\n\t\tKind _kind,\n\t\tStateMutability _stateMutability = StateMutability::NonPayable,\n\t\tOptions _options = Options{false, false, false, false, false}\n\t): FunctionType(\n\t\tparseElementaryTypeVector(_parameterTypes),\n\t\tparseElementaryTypeVector(_returnParameterTypes),\n\t\tstrings(_parameterTypes.size(), \"\"),\n\t\tstrings(_returnParameterTypes.size(), \"\"),\n\t\t_kind,\n\t\t_stateMutability,\n\t\tnullptr,\n\t\tstd::move(_options)\n\t)\n\t{\n\t\t// In this constructor, only the \"arbitrary Parameters\" option should be used.\n\t\tsolAssert(!hasBoundFirstArgument() && !gasSet() && !valueSet() && !saltSet());\n\t}\n\n\t/// Detailed constructor, use with care.\n\tFunctionType(\n\t\tTypePointers _parameterTypes,\n\t\tTypePointers _returnParameterTypes,\n\t\tstrings _parameterNames = strings(),\n\t\tstrings _returnParameterNames = strings(),\n\t\tKind _kind = Kind::Internal,\n\t\tStateMutability _stateMutability = StateMutability::NonPayable,\n\t\tDeclaration const* _declaration = nullptr,\n\t\tOptions _options = Options{false, false, false, false, false}\n\t):\n\t\tm_parameterTypes(std::move(_parameterTypes)),\n\t\tm_returnParameterTypes(std::move(_returnParameterTypes)),\n\t\tm_parameterNames(std::move(_parameterNames)),\n\t\tm_returnParameterNames(std::move(_returnParameterNames)),\n\t\tm_kind(_kind),\n\t\tm_stateMutability(_stateMutability),\n\t\tm_declaration(_declaration),\n\t\tm_options(std::move(_options))\n\t{\n\t\tsolAssert(\n\t\t\tm_parameterNames.size() == m_parameterTypes.size(),\n\t\t\t\"Parameter names list must match parameter types list!\"\n\t\t);\n\t\tsolAssert(\n\t\t\tm_returnParameterNames.size() == m_returnParameterTypes.size(),\n\t\t\t\"Return parameter names list must match return parameter types list!\"\n\t\t);\n\t\tsolAssert(\n\t\t\t!hasBoundFirstArgument() || !m_parameterTypes.empty(),\n\t\t\t\"Attempted construction of attached function without self type\"\n\t\t);\n\t}\n\n\tCategory category() const override { return Category::Function; }\n\n\t/// @returns the type of the \"new Contract\" function, i.e. basically the constructor.\n\tstatic FunctionTypePointer newExpressionType(ContractDefinition const& _contract);\n\n\tTypePointers parameterTypes() const;\n\tTypePointers const& parameterTypesIncludingSelf() const;\n\tstd::vector<std::string> parameterNames() const;\n\tTypePointers const& returnParameterTypes() const { return m_returnParameterTypes; }\n\t/// @returns the list of return parameter types. All dynamically-sized types (this excludes\n\t/// storage pointers) are replaced by InaccessibleDynamicType instances.\n\tTypePointers returnParameterTypesWithoutDynamicTypes() const;\n\tstd::vector<std::string> const& returnParameterNames() const { return m_returnParameterNames; }\n\t/// @returns the \"self\" parameter type for an attached function\n\tType const* selfType() const;\n\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tBoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tBoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;\n\tTypeResult unaryOperatorResult(Token _operator) const override;\n\tTypeResult binaryOperatorResult(Token, Type const*) const override;\n\tstd::string canonicalName() const override;\n\tstd::string humanReadableName() const override;\n\tstd::string toString(bool _withoutDataLocation) const override;\n\tunsigned calldataEncodedSize(bool _padded) const override;\n\tbool canBeStored() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }\n\tu256 storageSize() const override;\n\tbool leftAligned() const override;\n\tunsigned storageBytes() const override;\n\tbool isValueType() const override { return true; }\n\tbool nameable() const override;\n\tbool hasSimpleZeroValueInMemory() const override { return false; }\n\tMemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;\n\tType const* encodingType() const override;\n\tTypeResult interfaceType(bool _inLibrary) const override;\n\tType const* mobileType() const override;\n\n\t/// @returns Type const* of a new FunctionType object. All input/return parameters are an\n\t/// appropriate external types (i.e. the interfaceType()s) of input/return parameters of\n\t/// current function.\n\t/// @returns an empty shared pointer if one of the input/return parameters does not have an\n\t/// external type.\n\tFunctionTypePointer interfaceFunctionType() const;\n\n\t/// @returns true if this function can take the given arguments (possibly\n\t/// after implicit conversion).\n\t/// @param _selfType if the function is attached as a member function, this has to be supplied\n\t/// and is the type of the expression the function is called on.\n\tbool canTakeArguments(\n\t\tFuncCallArguments const& _arguments,\n\t\tType const* _selfType = nullptr\n\t) const;\n\n\t/// @returns true if the types of parameters are equal (does not check return parameter types)\n\tbool hasEqualParameterTypes(FunctionType const& _other) const;\n\t/// @returns true iff the return types are equal (does not check parameter types)\n\tbool hasEqualReturnTypes(FunctionType const& _other) const;\n\t/// @returns true iff the function type is equal to the given type, ignoring state mutability differences.\n\tbool equalExcludingStateMutability(FunctionType const& _other) const;\n\n\t/// @returns true if the ABI is NOT used for this call (only meaningful for external calls)\n\tbool isBareCall() const;\n\tKind const& kind() const { return m_kind; }\n\tStateMutability stateMutability() const { return m_stateMutability; }\n\t/// @returns the external signature of this function type given the function name\n\tstd::string externalSignature() const;\n\t/// @returns the external identifier of this function (the hash of the signature).\n\tu256 externalIdentifier() const;\n\t/// @returns the external identifier of this function (the hash of the signature) as a hex string.\n\tstd::string externalIdentifierHex() const;\n\tDeclaration const& declaration() const\n\t{\n\t\tsolAssert(m_declaration, \"Requested declaration from a FunctionType that has none\");\n\t\treturn *m_declaration;\n\t}\n\tbool hasDeclaration() const { return !!m_declaration; }\n\t/// @returns true if the result of this function only depends on its arguments,\n\t/// does not modify the state and is a compile-time constant.\n\t/// Currently, this will only return true for internal functions like keccak and ecrecover.\n\tbool isPure() const;\n\tbool isPayable() const { return m_stateMutability == StateMutability::Payable; }\n\t/// @return A shared pointer of StructuredDocumentation.\n\t/// Can contain a nullptr in which case indicates absence of documentation.\n\tASTPointer<StructuredDocumentation> documentation() const;\n\n\t/// true iff arguments are to be padded to multiples of 32 bytes for external calls\n\t/// The only functions that do not pad are hash functions, the low-level call functions\n\t/// and abi.encodePacked.\n\tbool padArguments() const;\n\tbool takesArbitraryParameters() const { return m_options.arbitraryParameters; }\n\t/// true iff the function takes a single bytes parameter and it is passed on without padding.\n\tbool takesSinglePackedBytesParameter() const\n\t{\n\t\tswitch (m_kind)\n\t\t{\n\t\tcase FunctionType::Kind::KECCAK256:\n\t\tcase FunctionType::Kind::SHA256:\n\t\tcase FunctionType::Kind::RIPEMD160:\n\t\tcase FunctionType::Kind::BareCall:\n\t\tcase FunctionType::Kind::BareCallCode:\n\t\tcase FunctionType::Kind::BareDelegateCall:\n\t\tcase FunctionType::Kind::BareStaticCall:\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tbool gasSet() const { return m_options.gasSet; }\n\tbool valueSet() const { return m_options.valueSet; }\n\tbool saltSet() const { return m_options.saltSet; }\n\tbool hasBoundFirstArgument() const { return m_options.hasBoundFirstArgument; }\n\n\t/// @returns a copy of this type, where gas or value are set manually. This will never set one\n\t/// of the parameters to false.\n\tType const* copyAndSetCallOptions(bool _setGas, bool _setValue, bool _setSalt) const;\n\n\t/// @returns a copy of this function type with the `hasBoundFirstArgument` flag set to true.\n\t/// Should only be called on library functions.\n\tFunctionTypePointer withBoundFirstArgument() const;\n\n\t/// @returns a copy of this function type where the location of reference types is changed\n\t/// from CallData to Memory. This is the type that would be used when the function is\n\t/// called externally, as opposed to the parameter types that are available inside the function body.\n\t/// Also supports variants to be used for library or attached function calls.\n\t/// @param _inLibrary if true, uses DelegateCall as location.\n\tFunctionTypePointer asExternallyCallableFunction(bool _inLibrary) const;\n\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;\nprivate:\n\tstatic TypePointers parseElementaryTypeVector(strings const& _types);\n\n\tTypePointers m_parameterTypes;\n\tTypePointers m_returnParameterTypes;\n\tstd::vector<std::string> m_parameterNames;\n\tstd::vector<std::string> m_returnParameterNames;\n\tKind const m_kind;\n\tStateMutability m_stateMutability = StateMutability::NonPayable;\n\tDeclaration const* m_declaration = nullptr;\n\tOptions const m_options;\n};\n\n/**\n * The type of a mapping, there is one distinct type per key/value type pair.\n * Mappings always occupy their own storage slot, but do not actually use it.\n */\nclass MappingType: public CompositeType\n{\npublic:\n\tMappingType(Type const* _keyType, ASTString _keyName, Type const* _valueType, ASTString _valueName):\n\t\tm_keyType(_keyType), m_keyName(_keyName), m_valueType(_valueType), m_valueName(_valueName) {}\n\n\tCategory category() const override { return Category::Mapping; }\n\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tstd::string toString(bool _withoutDataLocation) const override;\n\tstd::string canonicalName() const override;\n\tbool containsNestedMapping() const override { return true; }\n\tTypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }\n\tType const* encodingType() const override;\n\tTypeResult interfaceType(bool _inLibrary) const override;\n\tbool dataStoredIn(DataLocation _location) const override { return _location == DataLocation::Storage; }\n\t/// Cannot be stored in memory, but just in case.\n\tbool hasSimpleZeroValueInMemory() const override { solAssert(false, \"\"); }\n\tbool nameable() const override { return true; }\n\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;\n\n\tType const* keyType() const { return m_keyType; }\n\tASTString keyName() const { return m_keyName; }\n\tType const* valueType() const { return m_valueType; }\n\tASTString valueName() const { return m_valueName; }\n\nprotected:\n\tstd::vector<Type const*> decomposition() const override { return {m_valueType}; }\n\nprivate:\n\tType const* m_keyType;\n\tASTString m_keyName;\n\tType const* m_valueType;\n\tASTString m_valueName;\n};\n\n/**\n * The type of a type reference. The type of \"uint32\" when used in \"a = uint32(2)\" is an example\n * of a TypeType.\n * For super contracts or libraries, this has members directly.\n */\nclass TypeType: public Type\n{\npublic:\n\texplicit TypeType(Type const* _actualType): m_actualType(_actualType) {}\n\n\tCategory category() const override { return Category::TypeType; }\n\tType const* actualType() const { return m_actualType; }\n\n\tTypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tbool canBeStored() const override { return false; }\n\tu256 storageSize() const override;\n\tbool hasSimpleZeroValueInMemory() const override { solAssert(false, \"\"); }\n\tstd::string toString(bool _withoutDataLocation) const override { return \"type(\" + m_actualType->toString(_withoutDataLocation) + \")\"; }\n\tMemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;\n\tType const* mobileType() const override { return nullptr; }\n\n\tBoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;\nprivate:\n\tType const* m_actualType;\n};\n\n\n/**\n * The type of a function modifier. Not used for anything for now.\n */\nclass ModifierType: public Type\n{\npublic:\n\texplicit ModifierType(ModifierDefinition const& _modifier);\n\n\tCategory category() const override { return Category::Modifier; }\n\n\tTypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }\n\tbool canBeStored() const override { return false; }\n\tu256 storageSize() const override;\n\tbool hasSimpleZeroValueInMemory() const override { solAssert(false, \"\"); }\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tbool operator==(ModifierType const& _other) const;\n\tstd::string toString(bool _withoutDataLocation) const override;\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override { return {}; }\nprivate:\n\tTypePointers m_parameterTypes;\n};\n\n\n\n/**\n * Special type for imported modules. These mainly give access to their scope via members.\n */\nclass ModuleType: public Type\n{\npublic:\n\texplicit ModuleType(SourceUnit const& _source): m_sourceUnit(_source) {}\n\n\tCategory category() const override { return Category::Module; }\n\n\tTypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tbool canBeStored() const override { return false; }\n\tbool hasSimpleZeroValueInMemory() const override { solAssert(false, \"\"); }\n\tMemberList::MemberMap nativeMembers(ASTNode const*) const override;\n\n\tstd::string toString(bool _withoutDataLocation) const override;\n\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override { return {}; }\nprivate:\n\tSourceUnit const& m_sourceUnit;\n};\n\n/**\n * Special type for magic variables (block, msg, tx, type(...)), similar to a struct but without any reference.\n *\n * It is also the type shared by all instances of all custom error types.\n */\nclass MagicType: public Type\n{\npublic:\n\tenum class Kind {\n\t\tBlock, ///< \"block\"\n\t\tMessage, ///< \"msg\"\n\t\tTransaction, ///< \"tx\"\n\t\tABI, ///< \"abi\"\n\t\tError, ///< custom error instance\n\t\tMetaType ///< \"type(...)\"\n\t};\n\npublic:\n\texplicit MagicType(Kind _kind): m_kind(_kind) {}\n\texplicit MagicType(Type const* _metaTypeArg): m_kind{Kind::MetaType}, m_typeArgument{_metaTypeArg} {}\n\n\tCategory category() const override { return Category::Magic; }\n\n\tTypeResult binaryOperatorResult(Token, Type const*) const override\n\t{\n\t\treturn nullptr;\n\t}\n\n\tstd::string richIdentifier() const override;\n\tbool operator==(Type const& _other) const override;\n\tbool canBeStored() const override { return false; }\n\tbool hasSimpleZeroValueInMemory() const override { solAssert(false, \"\"); }\n\tMemberList::MemberMap nativeMembers(ASTNode const*) const override;\n\n\tstd::string toString(bool _withoutDataLocation) const override;\n\n\tKind kind() const { return m_kind; }\n\n\tType const* typeArgument() const;\n\n\tType const* mobileType() const override { return nullptr; }\n\nprotected:\n\tstd::vector<std::tuple<std::string, Type const*>> makeStackItems() const override { return {}; }\nprivate:\n\tKind m_kind;\n\t/// Contract type used for contract metadata magic.\n\tType const* m_typeArgument;\n};\n\n/**\n * Special type that is used for dynamic types in returns from external function calls\n * (The EVM currently cannot access dynamically-sized return values).\n */\nclass InaccessibleDynamicType: public Type\n{\npublic:\n\tCategory category() const override { return Category::InaccessibleDynamic; }\n\n\tstd::string richIdentifier() const override { return \"t_inaccessible\"; }\n\tBoolResult isImplicitlyConvertibleTo(Type const&) const override { return false; }\n\tBoolResult isExplicitlyConvertibleTo(Type const&) const override { return false; }\n\tTypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }\n\tunsigned calldataEncodedSize(bool) const override { return 32; }\n\tbool canBeStored() const override { return false; }\n\tbool isValueType() const override { return true; }\n\tbool hasSimpleZeroValueInMemory() const override { solAssert(false, \"\"); }\n\tstd::string toString(bool) const override { return \"inaccessible dynamic type\"; }\n\tType const* decodingType() const override;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/ast/UserDefinableOperators.h",
    "content": "#pragma once\n\n#include <liblangutil/Token.h>\n\n#include <vector>\n\nnamespace solidity::frontend\n{\n\nstd::vector<langutil::Token> const userDefinableOperators = {\n\t// Bitwise\n\tlangutil::Token::BitOr,\n\tlangutil::Token::BitAnd,\n\tlangutil::Token::BitXor,\n\tlangutil::Token::BitNot,\n\t// Arithmetic\n\tlangutil::Token::Add,\n\tlangutil::Token::Sub,\n\tlangutil::Token::Mul,\n\tlangutil::Token::Div,\n\tlangutil::Token::Mod,\n\t// Comparison\n\tlangutil::Token::Equal,\n\tlangutil::Token::NotEqual,\n\tlangutil::Token::LessThan,\n\tlangutil::Token::GreaterThan,\n\tlangutil::Token::LessThanOrEqual,\n\tlangutil::Token::GreaterThanOrEqual,\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ABIFunctions.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <chris@ethereum.org>\n * @date 2017\n * Routines that generate Yul code related to ABI encoding, decoding and type conversions.\n */\n\n#include <libsolidity/codegen/ABIFunctions.h>\n\n#include <libsolidity/codegen/CompilerUtils.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Whiskers.h>\n#include <libsolutil/StringUtils.h>\n\n#include <boost/algorithm/string/join.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::frontend;\n\nstd::string ABIFunctions::tupleEncoder(\n\tTypePointers const& _givenTypes,\n\tTypePointers _targetTypes,\n\tbool _encodeAsLibraryTypes,\n\tbool _reversed\n)\n{\n\tsolAssert(_givenTypes.size() == _targetTypes.size(), \"\");\n\tEncodingOptions options;\n\toptions.encodeAsLibraryTypes = _encodeAsLibraryTypes;\n\toptions.encodeFunctionFromStack = true;\n\toptions.padded = true;\n\toptions.dynamicInplace = false;\n\n\tfor (Type const*& t: _targetTypes)\n\t{\n\t\tsolAssert(t, \"\");\n\t\tt = t->fullEncodingType(options.encodeAsLibraryTypes, true, !options.padded);\n\t\tsolAssert(t, \"\");\n\t}\n\n\tstd::string functionName = std::string(\"abi_encode_tuple_\");\n\tfor (auto const& t: _givenTypes)\n\t\tfunctionName += t->identifier() + \"_\";\n\tfunctionName += \"_to_\";\n\tfor (auto const& t: _targetTypes)\n\t\tfunctionName += t->identifier() + \"_\";\n\tfunctionName += options.toFunctionNameSuffix();\n\tif (_reversed)\n\t\tfunctionName += \"_reversed\";\n\n\treturn createFunction(functionName, [&]() {\n\t\t// Note that the values are in reverse due to the difference in calling semantics.\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(headStart <valueParams>) -> tail {\n\t\t\t\ttail := add(headStart, <headSize>)\n\t\t\t\t<encodeElements>\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\tsize_t const headSize_ = headSize(_targetTypes);\n\t\ttempl(\"headSize\", std::to_string(headSize_));\n\t\tstd::string encodeElements;\n\t\tsize_t headPos = 0;\n\t\tsize_t stackPos = 0;\n\t\tfor (size_t i = 0; i < _givenTypes.size(); ++i)\n\t\t{\n\t\t\tsolAssert(_givenTypes[i], \"\");\n\t\t\tsolAssert(_targetTypes[i], \"\");\n\t\t\tsize_t sizeOnStack = _givenTypes[i]->sizeOnStack();\n\t\t\tbool dynamic = _targetTypes[i]->isDynamicallyEncoded();\n\t\t\tWhiskers elementTempl(\n\t\t\t\tdynamic ?\n\t\t\t\tstd::string(R\"(\n\t\t\t\t\tmstore(add(headStart, <pos>), sub(tail, headStart))\n\t\t\t\t\ttail := <abiEncode>(<values> tail)\n\t\t\t\t)\") :\n\t\t\t\tstd::string(R\"(\n\t\t\t\t\t<abiEncode>(<values> add(headStart, <pos>))\n\t\t\t\t)\")\n\t\t\t);\n\t\t\tstd::string values = suffixedVariableNameList(\"value\", stackPos, stackPos + sizeOnStack);\n\t\t\telementTempl(\"values\", values.empty() ? \"\" : values + \", \");\n\t\t\telementTempl(\"pos\", std::to_string(headPos));\n\t\t\telementTempl(\"abiEncode\", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options));\n\t\t\tencodeElements += elementTempl.render();\n\t\t\theadPos += _targetTypes[i]->calldataHeadSize();\n\t\t\tstackPos += sizeOnStack;\n\t\t}\n\t\tsolAssert(headPos == headSize_, \"\");\n\t\tstd::string valueParams =\n\t\t\t_reversed ?\n\t\t\tsuffixedVariableNameList(\"value\", stackPos, 0) :\n\t\t\tsuffixedVariableNameList(\"value\", 0, stackPos);\n\t\ttempl(\"valueParams\", valueParams.empty() ? \"\" : \", \" + valueParams);\n\t\ttempl(\"encodeElements\", encodeElements);\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string ABIFunctions::tupleEncoderPacked(\n\tTypePointers const& _givenTypes,\n\tTypePointers _targetTypes,\n\tbool _reversed\n)\n{\n\tEncodingOptions options;\n\toptions.encodeAsLibraryTypes = false;\n\toptions.encodeFunctionFromStack = true;\n\toptions.padded = false;\n\toptions.dynamicInplace = true;\n\n\tfor (Type const*& t: _targetTypes)\n\t{\n\t\tsolAssert(t, \"\");\n\t\tt = t->fullEncodingType(options.encodeAsLibraryTypes, true, !options.padded);\n\t\tsolAssert(t, \"\");\n\t}\n\n\tstd::string functionName = std::string(\"abi_encode_tuple_packed_\");\n\tfor (auto const& t: _givenTypes)\n\t\tfunctionName += t->identifier() + \"_\";\n\tfunctionName += \"_to_\";\n\tfor (auto const& t: _targetTypes)\n\t\tfunctionName += t->identifier() + \"_\";\n\tfunctionName += options.toFunctionNameSuffix();\n\tif (_reversed)\n\t\tfunctionName += \"_reversed\";\n\n\treturn createFunction(functionName, [&]() {\n\t\t// Note that the values are in reverse due to the difference in calling semantics.\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(pos <valueParams>) -> end {\n\t\t\t\t<encodeElements>\n\t\t\t\tend := pos\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\tstd::string encodeElements;\n\t\tsize_t stackPos = 0;\n\t\tfor (size_t i = 0; i < _givenTypes.size(); ++i)\n\t\t{\n\t\t\tsolAssert(_givenTypes[i], \"\");\n\t\t\tsolAssert(_targetTypes[i], \"\");\n\t\t\tsize_t sizeOnStack = _givenTypes[i]->sizeOnStack();\n\t\t\tbool dynamic = _targetTypes[i]->isDynamicallyEncoded();\n\t\t\tWhiskers elementTempl(\n\t\t\t\tdynamic ?\n\t\t\t\tstd::string(R\"(\n\t\t\t\t\tpos := <abiEncode>(<values> pos)\n\t\t\t\t)\") :\n\t\t\t\tstd::string(R\"(\n\t\t\t\t\t<abiEncode>(<values> pos)\n\t\t\t\t\tpos := add(pos, <calldataEncodedSize>)\n\t\t\t\t)\")\n\t\t\t);\n\t\t\tstd::string values = suffixedVariableNameList(\"value\", stackPos, stackPos + sizeOnStack);\n\t\t\telementTempl(\"values\", values.empty() ? \"\" : values + \", \");\n\t\t\tif (!dynamic)\n\t\t\t\telementTempl(\"calldataEncodedSize\", std::to_string(_targetTypes[i]->calldataEncodedSize(false)));\n\t\t\telementTempl(\"abiEncode\", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options));\n\t\t\tencodeElements += elementTempl.render();\n\t\t\tstackPos += sizeOnStack;\n\t\t}\n\t\tstd::string valueParams =\n\t\t\t_reversed ?\n\t\t\tsuffixedVariableNameList(\"value\", stackPos, 0) :\n\t\t\tsuffixedVariableNameList(\"value\", 0, stackPos);\n\t\ttempl(\"valueParams\", valueParams.empty() ? \"\" : \", \" + valueParams);\n\t\ttempl(\"encodeElements\", encodeElements);\n\n\t\treturn templ.render();\n\t});\n}\nstd::string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)\n{\n\tstd::string functionName = std::string(\"abi_decode_tuple_\");\n\tfor (auto const& t: _types)\n\t\tfunctionName += t->identifier();\n\tif (_fromMemory)\n\t\tfunctionName += \"_fromMemory\";\n\n\treturn createFunction(functionName, [&]() {\n\t\tTypePointers decodingTypes;\n\t\tfor (auto const& t: _types)\n\t\t\tdecodingTypes.emplace_back(t->decodingType());\n\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(headStart, dataEnd) <arrow> <valueReturnParams> {\n\t\t\t\tif slt(sub(dataEnd, headStart), <minimumSize>) { <revertString>() }\n\t\t\t\t<decodeElements>\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"revertString\", revertReasonIfDebugFunction(\"ABI decoding: tuple data too short\"));\n\t\ttempl(\"minimumSize\", std::to_string(headSize(decodingTypes)));\n\n\t\tstd::string decodeElements;\n\t\tstd::vector<std::string> valueReturnParams;\n\t\tsize_t headPos = 0;\n\t\tsize_t stackPos = 0;\n\t\tfor (size_t i = 0; i < _types.size(); ++i)\n\t\t{\n\t\t\tsolAssert(_types[i], \"\");\n\t\t\tsolAssert(decodingTypes[i], \"\");\n\t\t\tsize_t sizeOnStack = _types[i]->sizeOnStack();\n\t\t\tsolAssert(sizeOnStack == decodingTypes[i]->sizeOnStack(), \"\");\n\t\t\tsolAssert(sizeOnStack > 0, \"\");\n\t\t\tstd::vector<std::string> valueNamesLocal;\n\t\t\tfor (size_t j = 0; j < sizeOnStack; j++)\n\t\t\t{\n\t\t\t\tvalueNamesLocal.emplace_back(\"value\" + std::to_string(stackPos));\n\t\t\t\tvalueReturnParams.emplace_back(\"value\" + std::to_string(stackPos));\n\t\t\t\tstackPos++;\n\t\t\t}\n\t\t\tWhiskers elementTempl(R\"(\n\t\t\t\t{\n\t\t\t\t\t<?dynamic>\n\t\t\t\t\t\tlet offset := <load>(add(headStart, <pos>))\n\t\t\t\t\t\tif gt(offset, 0xffffffffffffffff) { <revertString>() }\n\t\t\t\t\t<!dynamic>\n\t\t\t\t\t\tlet offset := <pos>\n\t\t\t\t\t</dynamic>\n\t\t\t\t\t<values> := <abiDecode>(add(headStart, offset), dataEnd)\n\t\t\t\t}\n\t\t\t)\");\n\t\t\telementTempl(\"dynamic\", decodingTypes[i]->isDynamicallyEncoded());\n\t\t\t// TODO add test\n\t\t\telementTempl(\"revertString\", revertReasonIfDebugFunction(\"ABI decoding: invalid tuple offset\"));\n\t\t\telementTempl(\"load\", _fromMemory ? \"mload\" : \"calldataload\");\n\t\t\telementTempl(\"values\", boost::algorithm::join(valueNamesLocal, \", \"));\n\t\t\telementTempl(\"pos\", std::to_string(headPos));\n\t\t\telementTempl(\"abiDecode\", abiDecodingFunction(*_types[i], _fromMemory, true));\n\t\t\tdecodeElements += elementTempl.render();\n\t\t\theadPos += decodingTypes[i]->calldataHeadSize();\n\t\t}\n\t\ttempl(\"valueReturnParams\", boost::algorithm::join(valueReturnParams, \", \"));\n\t\ttempl(\"arrow\", valueReturnParams.empty() ? \"\" : \"->\");\n\t\ttempl(\"decodeElements\", decodeElements);\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string ABIFunctions::EncodingOptions::toFunctionNameSuffix() const\n{\n\tstd::string suffix;\n\tif (!padded)\n\t\tsuffix += \"_nonPadded\";\n\tif (dynamicInplace)\n\t\tsuffix += \"_inplace\";\n\tif (encodeFunctionFromStack)\n\t\tsuffix += \"_fromStack\";\n\tif (encodeAsLibraryTypes)\n\t\tsuffix += \"_library\";\n\treturn suffix;\n}\n\nstd::string ABIFunctions::abiEncodingFunction(\n\tType const& _from,\n\tType const& _to,\n\tEncodingOptions const& _options\n)\n{\n\tType const* toInterface = _to.fullEncodingType(_options.encodeAsLibraryTypes, true, false);\n\tsolUnimplementedAssert(toInterface, \"Encoding type \\\"\" + _to.toString() + \"\\\" not yet implemented.\");\n\tType const& to = *toInterface;\n\n\tif (_from.category() == Type::Category::StringLiteral)\n\t\treturn abiEncodingFunctionStringLiteral(_from, to, _options);\n\telse if (auto toArray = dynamic_cast<ArrayType const*>(&to))\n\t{\n\t\tArrayType const* fromArray = nullptr;\n\t\tswitch (_from.category())\n\t\t{\n\t\t\tcase Type::Category::Array:\n\t\t\t\tfromArray = dynamic_cast<ArrayType const*>(&_from);\n\t\t\t\tbreak;\n\t\t\tcase Type::Category::ArraySlice:\n\t\t\t\tfromArray = &dynamic_cast<ArraySliceType const*>(&_from)->arrayType();\n\t\t\t\tsolAssert(\n\t\t\t\t\tfromArray->dataStoredIn(DataLocation::CallData) &&\n\t\t\t\t\tfromArray->isDynamicallySized() &&\n\t\t\t\t\t!fromArray->baseType()->isDynamicallyEncoded(),\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tsolAssert(false, \"\");\n\t\t\t\tbreak;\n\t\t}\n\n\t\tswitch (fromArray->location())\n\t\t{\n\t\t\tcase DataLocation::CallData:\n\t\t\t\tif (\n\t\t\t\t\tfromArray->isByteArrayOrString() ||\n\t\t\t\t\t*fromArray->baseType() == *TypeProvider::uint256() ||\n\t\t\t\t\t*fromArray->baseType() == FixedBytesType(32)\n\t\t\t\t)\n\t\t\t\t\treturn abiEncodingFunctionCalldataArrayWithoutCleanup(*fromArray, *toArray, _options);\n\t\t\t\telse\n\t\t\t\t\treturn abiEncodingFunctionSimpleArray(*fromArray, *toArray, _options);\n\t\t\tcase DataLocation::Memory:\n\t\t\t\tif (fromArray->isByteArrayOrString())\n\t\t\t\t\treturn abiEncodingFunctionMemoryByteArray(*fromArray, *toArray, _options);\n\t\t\t\telse\n\t\t\t\t\treturn abiEncodingFunctionSimpleArray(*fromArray, *toArray, _options);\n\t\t\tcase DataLocation::Storage:\n\t\t\t\tif (fromArray->baseType()->storageBytes() <= 16)\n\t\t\t\t\treturn abiEncodingFunctionCompactStorageArray(*fromArray, *toArray, _options);\n\t\t\t\telse\n\t\t\t\t\treturn abiEncodingFunctionSimpleArray(*fromArray, *toArray, _options);\n\t\t\tdefault:\n\t\t\t\tsolAssert(false, \"\");\n\t\t}\n\t}\n\telse if (auto const* toStruct = dynamic_cast<StructType const*>(&to))\n\t{\n\t\tStructType const* fromStruct = dynamic_cast<StructType const*>(&_from);\n\t\tsolAssert(fromStruct, \"\");\n\t\treturn abiEncodingFunctionStruct(*fromStruct, *toStruct, _options);\n\t}\n\telse if (_from.category() == Type::Category::Function)\n\t\treturn abiEncodingFunctionFunctionType(\n\t\t\tdynamic_cast<FunctionType const&>(_from),\n\t\t\tto,\n\t\t\t_options\n\t\t);\n\n\tsolAssert(_from.sizeOnStack() == 1, \"\");\n\tsolAssert(to.isValueType(), \"\");\n\tsolAssert(to.calldataEncodedSize() == 32, \"\");\n\tstd::string functionName =\n\t\t\"abi_encode_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\tto.identifier() +\n\t\t_options.toFunctionNameSuffix();\n\treturn createFunction(functionName, [&]() {\n\t\tsolAssert(!to.isDynamicallyEncoded(), \"\");\n\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(value, pos) {\n\t\t\t\tmstore(pos, <cleanupConvert>)\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\n\t\tif (_from.dataStoredIn(DataLocation::Storage))\n\t\t{\n\t\t\t// special case: convert storage reference type to value type - this is only\n\t\t\t// possible for library calls where we just forward the storage reference\n\t\t\tsolAssert(_options.encodeAsLibraryTypes, \"\");\n\t\t\tsolAssert(_options.padded && !_options.dynamicInplace, \"Non-padded / inplace encoding for library call requested.\");\n\t\t\tsolAssert(to == *TypeProvider::uint256(), \"\");\n\t\t\ttempl(\"cleanupConvert\", \"value\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstd::string cleanupConvert;\n\t\t\tif (_from == to)\n\t\t\t\tcleanupConvert = m_utils.cleanupFunction(_from) + \"(value)\";\n\t\t\telse\n\t\t\t\tcleanupConvert = m_utils.conversionFunction(_from, to) + \"(value)\";\n\t\t\tif (!_options.padded)\n\t\t\t\tcleanupConvert = m_utils.leftAlignFunction(to) + \"(\" + cleanupConvert + \")\";\n\t\t\ttempl(\"cleanupConvert\", cleanupConvert);\n\t\t}\n\t\treturn templ.render();\n\t});\n}\n\nstd::string ABIFunctions::abiEncodeAndReturnUpdatedPosFunction(\n\tType const& _givenType,\n\tType const& _targetType,\n\tABIFunctions::EncodingOptions const& _options\n)\n{\n\tstd::string functionName =\n\t\t\"abi_encodeUpdatedPos_\" +\n\t\t_givenType.identifier() +\n\t\t\"_to_\" +\n\t\t_targetType.identifier() +\n\t\t_options.toFunctionNameSuffix();\n\treturn createFunction(functionName, [&]() {\n\t\tstd::string values = suffixedVariableNameList(\"value\", 0, numVariablesForType(_givenType, _options));\n\t\tstd::string encoder = abiEncodingFunction(_givenType, _targetType, _options);\n\t\tType const* targetEncoding = _targetType.fullEncodingType(_options.encodeAsLibraryTypes, true, false);\n\t\tsolAssert(targetEncoding, \"\");\n\t\tif (targetEncoding->isDynamicallyEncoded())\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(<values>, pos) -> updatedPos {\n\t\t\t\t\tupdatedPos := <encode>(<values>, pos)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"encode\", encoder)\n\t\t\t(\"values\", values)\n\t\t\t.render();\n\t\telse\n\t\t{\n\t\t\tunsigned encodedSize = targetEncoding->calldataEncodedSize(_options.padded);\n\t\t\tsolAssert(encodedSize != 0, \"Invalid encoded size.\");\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(<values>, pos) -> updatedPos {\n\t\t\t\t\t<encode>(<values>, pos)\n\t\t\t\t\tupdatedPos := add(pos, <encodedSize>)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"encode\", encoder)\n\t\t\t(\"encodedSize\", toCompactHexWithPrefix(encodedSize))\n\t\t\t(\"values\", values)\n\t\t\t.render();\n\t\t}\n\t});\n}\n\nstd::string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup(\n\tType const& _from,\n\tType const& _to,\n\tEncodingOptions const& _options\n)\n{\n\tsolAssert(_from.category() == Type::Category::Array, \"Unknown dynamic type.\");\n\tsolAssert(_to.category() == Type::Category::Array, \"Unknown dynamic type.\");\n\tauto const& fromArrayType = dynamic_cast<ArrayType const&>(_from);\n\tauto const& toArrayType = dynamic_cast<ArrayType const&>(_to);\n\n\tsolAssert(fromArrayType.location() == DataLocation::CallData, \"\");\n\tsolAssert(\n\t\tfromArrayType.isByteArrayOrString() ||\n\t\t*fromArrayType.baseType() == *TypeProvider::uint256() ||\n\t\t*fromArrayType.baseType() == FixedBytesType(32),\n\t\t\"\"\n\t);\n\tsolAssert(fromArrayType.calldataStride() == toArrayType.memoryStride(), \"\");\n\n\tsolAssert(\n\t\t*fromArrayType.copyForLocation(DataLocation::Memory, true) ==\n\t\t*toArrayType.copyForLocation(DataLocation::Memory, true),\n\t\t\"\"\n\t);\n\n\tstd::string functionName =\n\t\t\"abi_encode_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\t_to.identifier() +\n\t\t_options.toFunctionNameSuffix();\n\treturn createFunction(functionName, [&]() {\n\t\tbool bytesOrString = fromArrayType.isByteArrayOrString();\n\t\tbool needsPadding = _options.padded && bytesOrString;\n\t\tif (fromArrayType.isDynamicallySized())\n\t\t{\n\t\t\tWhiskers templ(R\"(\n\t\t\t\t// <readableTypeNameFrom> -> <readableTypeNameTo>\n\t\t\t\tfunction <functionName>(start, length, pos) -> end {\n\t\t\t\t\tpos := <storeLength>(pos, length)\n\t\t\t\t\t<scaleLengthByStride>\n\t\t\t\t\t<copyFun>(start, pos, length)\n\t\t\t\t\tend := add(pos, <lengthPadded>)\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"storeLength\", arrayStoreLengthForEncodingFunction(toArrayType, _options));\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\tif (fromArrayType.isByteArrayOrString() || fromArrayType.calldataStride() == 1)\n\t\t\t\ttempl(\"scaleLengthByStride\", \"\");\n\t\t\telse\n\t\t\t\ttempl(\"scaleLengthByStride\",\n\t\t\t\t\tWhiskers(R\"(\n\t\t\t\t\t\tif gt(length, <maxLength>) { <revertString>() }\n\t\t\t\t\t\tlength := mul(length, <stride>)\n\t\t\t\t\t)\")\n\t\t\t\t\t(\"stride\", toCompactHexWithPrefix(fromArrayType.calldataStride()))\n\t\t\t\t\t(\"maxLength\", toCompactHexWithPrefix(u256(-1) / fromArrayType.calldataStride()))\n\t\t\t\t\t(\"revertString\", revertReasonIfDebugFunction(\"ABI encoding: array data too long\"))\n\t\t\t\t\t.render()\n\t\t\t\t\t// TODO add revert test\n\t\t\t\t);\n\t\t\ttempl(\"readableTypeNameFrom\", _from.toString(true));\n\t\t\ttempl(\"readableTypeNameTo\", _to.toString(true));\n\t\t\ttempl(\"copyFun\", m_utils.copyToMemoryFunction(true, /*cleanup*/bytesOrString));\n\t\t\ttempl(\"lengthPadded\", needsPadding ? m_utils.roundUpFunction() + \"(length)\" : \"length\");\n\t\t\treturn templ.render();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(fromArrayType.calldataStride() == 32, \"\");\n\t\t\tWhiskers templ(R\"(\n\t\t\t\t// <readableTypeNameFrom> -> <readableTypeNameTo>\n\t\t\t\tfunction <functionName>(start, pos) {\n\t\t\t\t\t<copyFun>(start, pos, <byteLength>)\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\ttempl(\"readableTypeNameFrom\", _from.toString(true));\n\t\t\ttempl(\"readableTypeNameTo\", _to.toString(true));\n\t\t\ttempl(\"copyFun\", m_utils.copyToMemoryFunction(true, /*cleanup*/bytesOrString));\n\t\t\ttempl(\"byteLength\", toCompactHexWithPrefix(fromArrayType.length() * fromArrayType.calldataStride()));\n\t\t\treturn templ.render();\n\t\t}\n\t});\n}\n\nstd::string ABIFunctions::abiEncodingFunctionSimpleArray(\n\tArrayType const& _from,\n\tArrayType const& _to,\n\tEncodingOptions const& _options\n)\n{\n\tstd::string functionName =\n\t\t\"abi_encode_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\t_to.identifier() +\n\t\t_options.toFunctionNameSuffix();\n\n\tsolAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), \"\");\n\tsolAssert(_from.length() == _to.length(), \"\");\n\tsolAssert(!_from.isByteArrayOrString(), \"\");\n\tif (_from.dataStoredIn(DataLocation::Storage))\n\t\tsolAssert(_from.baseType()->storageBytes() > 16, \"\");\n\n\treturn createFunction(functionName, [&]() {\n\t\tbool dynamic = _to.isDynamicallyEncoded();\n\t\tbool dynamicBase = _to.baseType()->isDynamicallyEncoded();\n\t\tbool const usesTail = dynamicBase && !_options.dynamicInplace;\n\t\tEncodingOptions subOptions(_options);\n\t\tsubOptions.encodeFunctionFromStack = false;\n\t\tsubOptions.padded = true;\n\t\tstd::string elementValues = suffixedVariableNameList(\"elementValue\", 0, numVariablesForType(*_from.baseType(), subOptions));\n\t\tWhiskers templ(\n\t\t\tusesTail ?\n\t\t\tR\"(\n\t\t\t\t// <readableTypeNameFrom> -> <readableTypeNameTo>\n\t\t\t\tfunction <functionName>(value,<maybeLength> pos) <return> {\n\t\t\t\t\t<declareLength>\n\t\t\t\t\tpos := <storeLength>(pos, length)\n\t\t\t\t\tlet headStart := pos\n\t\t\t\t\tlet tail := add(pos, mul(length, 0x20))\n\t\t\t\t\tlet baseRef := <dataAreaFun>(value)\n\t\t\t\t\tlet srcPtr := baseRef\n\t\t\t\t\tfor { let i := 0 } lt(i, length) { i := add(i, 1) }\n\t\t\t\t\t{\n\t\t\t\t\t\tmstore(pos, sub(tail, headStart))\n\t\t\t\t\t\tlet <elementValues> := <arrayElementAccess>\n\t\t\t\t\t\ttail := <encodeToMemoryFun>(<elementValues>, tail)\n\t\t\t\t\t\tsrcPtr := <nextArrayElement>(srcPtr)\n\t\t\t\t\t\tpos := add(pos, 0x20)\n\t\t\t\t\t}\n\t\t\t\t\tpos := tail\n\t\t\t\t\t<assignEnd>\n\t\t\t\t}\n\t\t\t)\" :\n\t\t\tR\"(\n\t\t\t\t// <readableTypeNameFrom> -> <readableTypeNameTo>\n\t\t\t\tfunction <functionName>(value,<maybeLength> pos) <return> {\n\t\t\t\t\t<declareLength>\n\t\t\t\t\tpos := <storeLength>(pos, length)\n\t\t\t\t\tlet baseRef := <dataAreaFun>(value)\n\t\t\t\t\tlet srcPtr := baseRef\n\t\t\t\t\tfor { let i := 0 } lt(i, length) { i := add(i, 1) }\n\t\t\t\t\t{\n\t\t\t\t\t\tlet <elementValues> := <arrayElementAccess>\n\t\t\t\t\t\tpos := <encodeToMemoryFun>(<elementValues>, pos)\n\t\t\t\t\t\tsrcPtr := <nextArrayElement>(srcPtr)\n\t\t\t\t\t}\n\t\t\t\t\t<assignEnd>\n\t\t\t\t}\n\t\t\t)\"\n\t\t);\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"elementValues\", elementValues);\n\t\tbool lengthAsArgument = _from.dataStoredIn(DataLocation::CallData) && _from.isDynamicallySized();\n\t\tif (lengthAsArgument)\n\t\t{\n\t\t\ttempl(\"maybeLength\", \" length,\");\n\t\t\ttempl(\"declareLength\", \"\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttempl(\"maybeLength\", \"\");\n\t\t\ttempl(\"declareLength\", \"let length := \" + m_utils.arrayLengthFunction(_from) + \"(value)\");\n\t\t}\n\t\ttempl(\"readableTypeNameFrom\", _from.toString(true));\n\t\ttempl(\"readableTypeNameTo\", _to.toString(true));\n\t\ttempl(\"return\", dynamic ? \" -> end \" : \"\");\n\t\ttempl(\"assignEnd\", dynamic ? \"end := pos\" : \"\");\n\t\ttempl(\"storeLength\", arrayStoreLengthForEncodingFunction(_to, _options));\n\t\ttempl(\"dataAreaFun\", m_utils.arrayDataAreaFunction(_from));\n\n\t\ttempl(\"encodeToMemoryFun\", abiEncodeAndReturnUpdatedPosFunction(*_from.baseType(), *_to.baseType(), subOptions));\n\t\tswitch (_from.location())\n\t\t{\n\t\t\tcase DataLocation::Memory:\n\t\t\t\ttempl(\"arrayElementAccess\", \"mload(srcPtr)\");\n\t\t\t\tbreak;\n\t\t\tcase DataLocation::Storage:\n\t\t\t\tif (_from.baseType()->isValueType())\n\t\t\t\t\ttempl(\"arrayElementAccess\", m_utils.readFromStorage(*_from.baseType(), 0, false, VariableDeclaration::Location::Unspecified) + \"(srcPtr)\");\n\t\t\t\telse\n\t\t\t\t\ttempl(\"arrayElementAccess\", \"srcPtr\");\n\t\t\t\tbreak;\n\t\t\tcase DataLocation::CallData:\n\t\t\t\ttempl(\"arrayElementAccess\", calldataAccessFunction(*_from.baseType()) + \"(baseRef, srcPtr)\");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tsolAssert(false, \"\");\n\t\t}\n\t\ttempl(\"nextArrayElement\", m_utils.nextArrayElementFunction(_from));\n\t\treturn templ.render();\n\t});\n}\n\nstd::string ABIFunctions::abiEncodingFunctionMemoryByteArray(\n\tArrayType const& _from,\n\tArrayType const& _to,\n\tEncodingOptions const& _options\n)\n{\n\tstd::string functionName =\n\t\t\"abi_encode_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\t_to.identifier() +\n\t\t_options.toFunctionNameSuffix();\n\n\tsolAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), \"\");\n\tsolAssert(_from.length() == _to.length(), \"\");\n\tsolAssert(_from.dataStoredIn(DataLocation::Memory), \"\");\n\tsolAssert(_from.isByteArrayOrString(), \"\");\n\n\treturn createFunction(functionName, [&]() {\n\t\tsolAssert(_to.isByteArrayOrString(), \"\");\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(value, pos) -> end {\n\t\t\t\tlet length := <lengthFun>(value)\n\t\t\t\tpos := <storeLength>(pos, length)\n\t\t\t\t<copyFun>(add(value, 0x20), pos, length)\n\t\t\t\tend := add(pos, <lengthPadded>)\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"lengthFun\", m_utils.arrayLengthFunction(_from));\n\t\ttempl(\"storeLength\", arrayStoreLengthForEncodingFunction(_to, _options));\n\t\ttempl(\"copyFun\", m_utils.copyToMemoryFunction(false, /*cleanup*/true));\n\t\ttempl(\"lengthPadded\", _options.padded ? m_utils.roundUpFunction() + \"(length)\" : \"length\");\n\t\treturn templ.render();\n\t});\n}\n\nstd::string ABIFunctions::abiEncodingFunctionCompactStorageArray(\n\tArrayType const& _from,\n\tArrayType const& _to,\n\tEncodingOptions const& _options\n)\n{\n\tstd::string functionName =\n\t\t\"abi_encode_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\t_to.identifier() +\n\t\t_options.toFunctionNameSuffix();\n\n\tsolAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), \"\");\n\tsolAssert(_from.length() == _to.length(), \"\");\n\tsolAssert(_from.dataStoredIn(DataLocation::Storage), \"\");\n\n\treturn createFunction(functionName, [&]() {\n\t\tif (_from.isByteArrayOrString())\n\t\t{\n\t\t\tsolAssert(_to.isByteArrayOrString(), \"\");\n\t\t\tWhiskers templ(R\"(\n\t\t\t\t// <readableTypeNameFrom> -> <readableTypeNameTo>\n\t\t\t\tfunction <functionName>(value, pos) -> ret {\n\t\t\t\t\tlet slotValue := sload(value)\n\t\t\t\t\tlet length := <byteArrayLengthFunction>(slotValue)\n\t\t\t\t\tpos := <storeLength>(pos, length)\n\t\t\t\t\tswitch and(slotValue, 1)\n\t\t\t\t\tcase 0 {\n\t\t\t\t\t\t// short byte array\n\t\t\t\t\t\tmstore(pos, and(slotValue, not(0xff)))\n\t\t\t\t\t\tret := add(pos, mul(<lengthPaddedShort>, iszero(iszero(length))))\n\t\t\t\t\t}\n\t\t\t\t\tcase 1 {\n\t\t\t\t\t\t// long byte array\n\t\t\t\t\t\tlet dataPos := <arrayDataSlot>(value)\n\t\t\t\t\t\tlet i := 0\n\t\t\t\t\t\tfor { } lt(i, length) { i := add(i, 0x20) } {\n\t\t\t\t\t\t\tmstore(add(pos, i), sload(dataPos))\n\t\t\t\t\t\t\tdataPos := add(dataPos, 1)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tret := add(pos, <lengthPaddedLong>)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\ttempl(\"readableTypeNameFrom\", _from.toString(true));\n\t\t\ttempl(\"readableTypeNameTo\", _to.toString(true));\n\t\t\ttempl(\"byteArrayLengthFunction\", m_utils.extractByteArrayLengthFunction());\n\t\t\ttempl(\"storeLength\", arrayStoreLengthForEncodingFunction(_to, _options));\n\t\t\ttempl(\"lengthPaddedShort\", _options.padded ? \"0x20\" : \"length\");\n\t\t\ttempl(\"lengthPaddedLong\", _options.padded ? \"i\" : \"length\");\n\t\t\ttempl(\"arrayDataSlot\", m_utils.arrayDataAreaFunction(_from));\n\t\t\treturn templ.render();\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Multiple items per slot\n\t\t\tsolAssert(_from.baseType()->storageBytes() <= 16, \"\");\n\t\t\tsolAssert(!_from.baseType()->isDynamicallyEncoded(), \"\");\n\t\t\tsolAssert(!_to.baseType()->isDynamicallyEncoded(), \"\");\n\t\t\tsolAssert(_from.baseType()->isValueType(), \"\");\n\t\t\tbool dynamic = _to.isDynamicallyEncoded();\n\t\t\tsize_t storageBytes = _from.baseType()->storageBytes();\n\t\t\tsize_t itemsPerSlot = 32 / storageBytes;\n\t\t\tsolAssert(itemsPerSlot > 0, \"\");\n\t\t\t// The number of elements we need to handle manually after the loop.\n\t\t\tsize_t spill = static_cast<size_t>(_from.length() % itemsPerSlot);\n\t\t\tWhiskers templ(\n\t\t\t\tR\"(\n\t\t\t\t\t// <readableTypeNameFrom> -> <readableTypeNameTo>\n\t\t\t\t\tfunction <functionName>(value, pos) <return> {\n\t\t\t\t\t\tlet length := <lengthFun>(value)\n\t\t\t\t\t\tpos := <storeLength>(pos, length)\n\t\t\t\t\t\tlet originalPos := pos\n\t\t\t\t\t\tlet srcPtr := <dataArea>(value)\n\t\t\t\t\t\tlet itemCounter := 0\n\t\t\t\t\t\tif <useLoop> {\n\t\t\t\t\t\t\t// Run the loop over all full slots\n\t\t\t\t\t\t\tfor { } lt(add(itemCounter, sub(<itemsPerSlot>, 1)), length)\n\t\t\t\t\t\t\t\t\t\t{ itemCounter := add(itemCounter, <itemsPerSlot>) }\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlet data := sload(srcPtr)\n\t\t\t\t\t\t\t\t<#items>\n\t\t\t\t\t\t\t\t\t<encodeToMemoryFun>(<extractFromSlot>(data), pos)\n\t\t\t\t\t\t\t\t\tpos := add(pos, <stride>)\n\t\t\t\t\t\t\t\t</items>\n\t\t\t\t\t\t\t\tsrcPtr := add(srcPtr, 1)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Handle the last (not necessarily full) slot specially\n\t\t\t\t\t\tif <useSpill> {\n\t\t\t\t\t\t\tlet data := sload(srcPtr)\n\t\t\t\t\t\t\t<#items>\n\t\t\t\t\t\t\t\tif <inRange> {\n\t\t\t\t\t\t\t\t\t<encodeToMemoryFun>(<extractFromSlot>(data), pos)\n\t\t\t\t\t\t\t\t\tpos := add(pos, <stride>)\n\t\t\t\t\t\t\t\t\titemCounter := add(itemCounter, 1)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</items>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<assignEnd>\n\t\t\t\t\t}\n\t\t\t\t)\"\n\t\t\t);\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\ttempl(\"readableTypeNameFrom\", _from.toString(true));\n\t\t\ttempl(\"readableTypeNameTo\", _to.toString(true));\n\t\t\ttempl(\"return\", dynamic ? \" -> end \" : \"\");\n\t\t\ttempl(\"assignEnd\", dynamic ? \"end := pos\" : \"\");\n\t\t\ttempl(\"lengthFun\", m_utils.arrayLengthFunction(_from));\n\t\t\ttempl(\"storeLength\", arrayStoreLengthForEncodingFunction(_to, _options));\n\t\t\ttempl(\"dataArea\", m_utils.arrayDataAreaFunction(_from));\n\t\t\t// We skip the loop for arrays that fit a single slot.\n\t\t\tif (_from.isDynamicallySized() || _from.length() >= itemsPerSlot)\n\t\t\t\ttempl(\"useLoop\", \"1\");\n\t\t\telse\n\t\t\t\ttempl(\"useLoop\", \"0\");\n\t\t\tif (_from.isDynamicallySized() || spill != 0)\n\t\t\t\ttempl(\"useSpill\", \"1\");\n\t\t\telse\n\t\t\t\ttempl(\"useSpill\", \"0\");\n\t\t\ttempl(\"itemsPerSlot\", std::to_string(itemsPerSlot));\n\t\t\ttempl(\"stride\", toCompactHexWithPrefix(_to.calldataStride()));\n\n\t\t\tEncodingOptions subOptions(_options);\n\t\t\tsubOptions.encodeFunctionFromStack = false;\n\t\t\tsubOptions.padded = true;\n\t\t\tstd::string encodeToMemoryFun = abiEncodingFunction(\n\t\t\t\t*_from.baseType(),\n\t\t\t\t*_to.baseType(),\n\t\t\t\tsubOptions\n\t\t\t);\n\t\t\ttempl(\"encodeToMemoryFun\", encodeToMemoryFun);\n\t\t\tstd::vector<std::map<std::string, std::string>> items(itemsPerSlot);\n\t\t\tfor (size_t i = 0; i < itemsPerSlot; ++i)\n\t\t\t{\n\t\t\t\tif (_from.isDynamicallySized())\n\t\t\t\t\titems[i][\"inRange\"] = \"lt(itemCounter, length)\";\n\t\t\t\telse if (i < spill)\n\t\t\t\t\titems[i][\"inRange\"] = \"1\";\n\t\t\t\telse\n\t\t\t\t\titems[i][\"inRange\"] = \"0\";\n\t\t\t\titems[i][\"extractFromSlot\"] = m_utils.extractFromStorageValue(*_from.baseType(), i * storageBytes);\n\t\t\t}\n\t\t\ttempl(\"items\", items);\n\t\t\treturn templ.render();\n\t\t}\n\t});\n}\n\nstd::string ABIFunctions::abiEncodingFunctionStruct(\n\tStructType const& _from,\n\tStructType const& _to,\n\tEncodingOptions const& _options\n)\n{\n\tstd::string functionName =\n\t\t\"abi_encode_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\t_to.identifier() +\n\t\t_options.toFunctionNameSuffix();\n\n\tsolAssert(&_from.structDefinition() == &_to.structDefinition(), \"\");\n\n\treturn createFunction(functionName, [&]() {\n\t\tbool dynamic = _to.isDynamicallyEncoded();\n\t\tWhiskers templ(R\"(\n\t\t\t// <readableTypeNameFrom> -> <readableTypeNameTo>\n\t\t\tfunction <functionName>(value, pos) <return> {\n\t\t\t\tlet tail := add(pos, <headSize>)\n\t\t\t\t<init>\n\t\t\t\t<#members>\n\t\t\t\t{\n\t\t\t\t\t// <memberName>\n\t\t\t\t\t<preprocess>\n\t\t\t\t\tlet <memberValues> := <retrieveValue>\n\t\t\t\t\t<encode>\n\t\t\t\t}\n\t\t\t\t</members>\n\t\t\t\t<assignEnd>\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"readableTypeNameFrom\", _from.toString(true));\n\t\ttempl(\"readableTypeNameTo\", _to.toString(true));\n\t\ttempl(\"return\", dynamic ? \" -> end \" : \"\");\n\t\tif (dynamic && _options.dynamicInplace)\n\t\t\ttempl(\"assignEnd\", \"end := pos\");\n\t\telse if (dynamic && !_options.dynamicInplace)\n\t\t\ttempl(\"assignEnd\", \"end := tail\");\n\t\telse\n\t\t\ttempl(\"assignEnd\", \"\");\n\t\t// to avoid multiple loads from the same slot for subsequent members\n\t\ttempl(\"init\", _from.dataStoredIn(DataLocation::Storage) ? \"let slotValue := 0\" : \"\");\n\t\tu256 previousSlotOffset(-1);\n\t\tu256 encodingOffset = 0;\n\t\tstd::vector<std::map<std::string, std::string>> members;\n\t\tfor (auto const& member: _to.members(nullptr))\n\t\t{\n\t\t\tsolAssert(member.type, \"\");\n\t\t\tsolAssert(!member.type->containsNestedMapping(), \"\");\n\t\t\tType const* memberTypeTo = member.type->fullEncodingType(_options.encodeAsLibraryTypes, true, false);\n\t\t\tsolUnimplementedAssert(memberTypeTo, \"Encoding type \\\"\" + member.type->toString() + \"\\\" not yet implemented.\");\n\t\t\tauto memberTypeFrom = _from.memberType(member.name);\n\t\t\tsolAssert(memberTypeFrom, \"\");\n\t\t\tbool dynamicMember = memberTypeTo->isDynamicallyEncoded();\n\t\t\tif (dynamicMember)\n\t\t\t\tsolAssert(dynamic, \"\");\n\n\t\t\tmembers.emplace_back();\n\t\t\tmembers.back()[\"preprocess\"] = \"\";\n\n\t\t\tswitch (_from.location())\n\t\t\t{\n\t\t\t\tcase DataLocation::Storage:\n\t\t\t\t{\n\t\t\t\t\tsolAssert(memberTypeFrom->isValueType() == memberTypeTo->isValueType(), \"\");\n\t\t\t\t\tu256 storageSlotOffset;\n\t\t\t\t\tsize_t intraSlotOffset;\n\t\t\t\t\tstd::tie(storageSlotOffset, intraSlotOffset) = _from.storageOffsetsOfMember(member.name);\n\t\t\t\t\tif (memberTypeFrom->isValueType())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (storageSlotOffset != previousSlotOffset)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmembers.back()[\"preprocess\"] = \"slotValue := sload(add(value, \" + toCompactHexWithPrefix(storageSlotOffset) + \"))\";\n\t\t\t\t\t\t\tpreviousSlotOffset = storageSlotOffset;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmembers.back()[\"retrieveValue\"] = m_utils.extractFromStorageValue(*memberTypeFrom, intraSlotOffset) + \"(slotValue)\";\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(memberTypeFrom->dataStoredIn(DataLocation::Storage), \"\");\n\t\t\t\t\t\tsolAssert(intraSlotOffset == 0, \"\");\n\t\t\t\t\t\tmembers.back()[\"retrieveValue\"] = \"add(value, \" + toCompactHexWithPrefix(storageSlotOffset) + \")\";\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DataLocation::Memory:\n\t\t\t\t{\n\t\t\t\t\tstd::string sourceOffset = toCompactHexWithPrefix(_from.memoryOffsetOfMember(member.name));\n\t\t\t\t\tmembers.back()[\"retrieveValue\"] = \"mload(add(value, \" + sourceOffset + \"))\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DataLocation::CallData:\n\t\t\t\t{\n\t\t\t\t\tstd::string sourceOffset = toCompactHexWithPrefix(_from.calldataOffsetOfMember(member.name));\n\t\t\t\t\tmembers.back()[\"retrieveValue\"] = calldataAccessFunction(*memberTypeFrom) + \"(value, add(value, \" + sourceOffset + \"))\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tsolAssert(false, \"\");\n\t\t\t}\n\n\t\t\tEncodingOptions subOptions(_options);\n\t\t\tsubOptions.encodeFunctionFromStack = false;\n\t\t\t// Like with arrays, struct members are always padded.\n\t\t\tsubOptions.padded = true;\n\n\t\t\tstd::string memberValues = suffixedVariableNameList(\"memberValue\", 0, numVariablesForType(*memberTypeFrom, subOptions));\n\t\t\tmembers.back()[\"memberValues\"] = memberValues;\n\n\t\t\tstd::string encode;\n\t\t\tif (_options.dynamicInplace)\n\t\t\t\tencode = Whiskers{\"pos := <encode>(<memberValues>, pos)\"}\n\t\t\t\t\t(\"encode\", abiEncodeAndReturnUpdatedPosFunction(*memberTypeFrom, *memberTypeTo, subOptions))\n\t\t\t\t\t(\"memberValues\", memberValues)\n\t\t\t\t\t.render();\n\t\t\telse\n\t\t\t{\n\t\t\t\tWhiskers encodeTempl(\n\t\t\t\t\tdynamicMember ?\n\t\t\t\t\tstd::string(R\"(\n\t\t\t\t\t\tmstore(add(pos, <encodingOffset>), sub(tail, pos))\n\t\t\t\t\t\ttail := <abiEncode>(<memberValues>, tail)\n\t\t\t\t\t)\") :\n\t\t\t\t\t\"<abiEncode>(<memberValues>, add(pos, <encodingOffset>))\"\n\t\t\t\t);\n\t\t\t\tencodeTempl(\"memberValues\", memberValues);\n\t\t\t\tencodeTempl(\"encodingOffset\", toCompactHexWithPrefix(encodingOffset));\n\t\t\t\tencodingOffset += memberTypeTo->calldataHeadSize();\n\t\t\t\tencodeTempl(\"abiEncode\", abiEncodingFunction(*memberTypeFrom, *memberTypeTo, subOptions));\n\t\t\t\tencode = encodeTempl.render();\n\t\t\t}\n\t\t\tmembers.back()[\"encode\"] = encode;\n\n\t\t\tmembers.back()[\"memberName\"] = member.name;\n\t\t}\n\t\ttempl(\"members\", members);\n\t\tif (_options.dynamicInplace)\n\t\t\tsolAssert(encodingOffset == 0, \"In-place encoding should enforce zero head size.\");\n\t\ttempl(\"headSize\", toCompactHexWithPrefix(encodingOffset));\n\t\treturn templ.render();\n\t});\n}\n\nstd::string ABIFunctions::abiEncodingFunctionStringLiteral(\n\tType const& _from,\n\tType const& _to,\n\tEncodingOptions const& _options\n)\n{\n\tsolAssert(_from.category() == Type::Category::StringLiteral, \"\");\n\n\tstd::string functionName =\n\t\t\"abi_encode_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\t_to.identifier() +\n\t\t_options.toFunctionNameSuffix();\n\treturn createFunction(functionName, [&]() {\n\t\tauto const& strType = dynamic_cast<StringLiteralType const&>(_from);\n\t\tstd::string const& value = strType.value();\n\t\tsolAssert(_from.sizeOnStack() == 0, \"\");\n\n\t\tif (_to.isDynamicallySized())\n\t\t{\n\t\t\tsolAssert(_to.category() == Type::Category::Array, \"\");\n\t\t\tWhiskers templ(R\"(\n\t\t\t\tfunction <functionName>(pos) -> end {\n\t\t\t\t\tpos := <storeLength>(pos, <length>)\n\t\t\t\t\t<storeLiteralInMemory>(pos)\n\t\t\t\t\tend := add(pos, <overallSize>)\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"functionName\", functionName);\n\n\t\t\t// TODO this can make use of CODECOPY for large strings once we have that in Yul\n\t\t\ttempl(\"length\", std::to_string(value.size()));\n\t\t\ttempl(\"storeLength\", arrayStoreLengthForEncodingFunction(dynamic_cast<ArrayType const&>(_to), _options));\n\t\t\tif (_options.padded)\n\t\t\t\ttempl(\"overallSize\", std::to_string(((value.size() + 31) / 32) * 32));\n\t\t\telse\n\t\t\t\ttempl(\"overallSize\", std::to_string(value.size()));\n\t\t\ttempl(\"storeLiteralInMemory\", m_utils.storeLiteralInMemoryFunction(value));\n\t\t\treturn templ.render();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(_to.category() == Type::Category::FixedBytes, \"\");\n\t\t\tsolAssert(value.size() <= 32, \"\");\n\t\t\tWhiskers templ(R\"(\n\t\t\t\tfunction <functionName>(pos) {\n\t\t\t\t\tmstore(pos, <wordValue>)\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\ttempl(\"wordValue\", formatAsStringOrNumber(value));\n\t\t\treturn templ.render();\n\t\t}\n\t});\n}\n\nstd::string ABIFunctions::abiEncodingFunctionFunctionType(\n\tFunctionType const& _from,\n\tType const& _to,\n\tEncodingOptions const& _options\n)\n{\n\tsolAssert(\n\t\t_from.kind() == FunctionType::Kind::External &&\n\t\t_from.isImplicitlyConvertibleTo(_to) &&\n\t\t_from.sizeOnStack() == _to.sizeOnStack(),\n\t\t\"Invalid function type conversion requested\"\n\t);\n\n\tstd::string functionName =\n\t\t\"abi_encode_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\t_to.identifier() +\n\t\t_options.toFunctionNameSuffix();\n\n\tif (_options.encodeFunctionFromStack)\n\t\treturn createFunction(functionName, [&]() {\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(addr, function_id, pos) {\n\t\t\t\t\taddr, function_id := <convert>(addr, function_id)\n\t\t\t\t\tmstore(pos, <combineExtFun>(addr, function_id))\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"combineExtFun\", m_utils.combineExternalFunctionIdFunction())\n\t\t\t(\"convert\", m_utils.conversionFunction(_from, _to))\n\t\t\t.render();\n\t\t});\n\telse\n\t\treturn createFunction(functionName, [&]() {\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(addr_and_function_id, pos) {\n\t\t\t\t\tmstore(pos, <cleanExtFun>(addr_and_function_id))\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"cleanExtFun\", m_utils.cleanupFunction(_to))\n\t\t\t.render();\n\t\t});\n}\n\nstd::string ABIFunctions::abiDecodingFunction(Type const& _type, bool _fromMemory, bool _forUseOnStack)\n{\n\t// The decoding function has to perform bounds checks unless it decodes a value type.\n\t// Conversely, bounds checks have to be performed before the decoding function\n\t// of a value type is called.\n\n\tType const* decodingType = _type.decodingType();\n\tsolAssert(decodingType, \"\");\n\n\tif (auto arrayType = dynamic_cast<ArrayType const*>(decodingType))\n\t{\n\t\tif (arrayType->dataStoredIn(DataLocation::CallData))\n\t\t{\n\t\t\tsolAssert(!_fromMemory, \"\");\n\t\t\treturn abiDecodingFunctionCalldataArray(*arrayType);\n\t\t}\n\t\telse\n\t\t\treturn abiDecodingFunctionArray(*arrayType, _fromMemory);\n\t}\n\telse if (auto const* structType = dynamic_cast<StructType const*>(decodingType))\n\t{\n\t\tif (structType->dataStoredIn(DataLocation::CallData))\n\t\t{\n\t\t\tsolAssert(!_fromMemory, \"\");\n\t\t\treturn abiDecodingFunctionCalldataStruct(*structType);\n\t\t}\n\t\telse\n\t\t\treturn abiDecodingFunctionStruct(*structType, _fromMemory);\n\t}\n\telse if (auto const* functionType = dynamic_cast<FunctionType const*>(decodingType))\n\t\treturn abiDecodingFunctionFunctionType(*functionType, _fromMemory, _forUseOnStack);\n\telse\n\t\treturn abiDecodingFunctionValueType(_type, _fromMemory);\n}\n\nstd::string ABIFunctions::abiDecodingFunctionValueType(Type const& _type, bool _fromMemory)\n{\n\tType const* decodingType = _type.decodingType();\n\tsolAssert(decodingType, \"\");\n\tsolAssert(decodingType->sizeOnStack() == 1, \"\");\n\tsolAssert(decodingType->isValueType(), \"\");\n\tsolAssert(!decodingType->isDynamicallyEncoded(), \"\");\n\tsolAssert(decodingType->calldataEncodedSize() == 32, \"\");\n\n\tstd::string functionName =\n\t\t\"abi_decode_\" +\n\t\t_type.identifier() +\n\t\t(_fromMemory ? \"_fromMemory\" : \"\");\n\treturn createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(offset, end) -> value {\n\t\t\t\tvalue := <load>(offset)\n\t\t\t\t<validator>(value)\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"load\", _fromMemory ? \"mload\" : \"calldataload\");\n\t\t// Validation should use the type and not decodingType, because e.g.\n\t\t// the decoding type of an enum is a plain int.\n\t\ttempl(\"validator\", m_utils.validatorFunction(_type, true));\n\t\treturn templ.render();\n\t});\n\n}\n\nstd::string ABIFunctions::abiDecodingFunctionArray(ArrayType const& _type, bool _fromMemory)\n{\n\tsolAssert(_type.dataStoredIn(DataLocation::Memory), \"\");\n\n\tstd::string functionName =\n\t\t\"abi_decode_\" +\n\t\t_type.identifier() +\n\t\t(_fromMemory ? \"_fromMemory\" : \"\");\n\n\treturn createFunction(functionName, [&]() {\n\t\tstd::string load = _fromMemory ? \"mload\" : \"calldataload\";\n\t\tWhiskers templ(\n\t\t\tR\"(\n\t\t\t\t// <readableTypeName>\n\t\t\t\tfunction <functionName>(offset, end) -> array {\n\t\t\t\t\tif iszero(slt(add(offset, 0x1f), end)) { <revertString>() }\n\t\t\t\t\tlet length := <retrieveLength>\n\t\t\t\t\tarray := <abiDecodeAvailableLen>(<offset>, length, end)\n\t\t\t\t}\n\t\t\t)\"\n\t\t);\n\t\t// TODO add test\n\t\ttempl(\"revertString\", revertReasonIfDebugFunction(\"ABI decoding: invalid calldata array offset\"));\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"readableTypeName\", _type.toString(true));\n\t\ttempl(\"retrieveLength\", _type.isDynamicallySized() ? (load + \"(offset)\") : toCompactHexWithPrefix(_type.length()));\n\t\ttempl(\"offset\", _type.isDynamicallySized() ? \"add(offset, 0x20)\" : \"offset\");\n\t\ttempl(\"abiDecodeAvailableLen\", abiDecodingFunctionArrayAvailableLength(_type, _fromMemory));\n\t\treturn templ.render();\n\t});\n}\n\nstd::string ABIFunctions::abiDecodingFunctionArrayAvailableLength(ArrayType const& _type, bool _fromMemory)\n{\n\tsolAssert(_type.dataStoredIn(DataLocation::Memory), \"\");\n\tif (_type.isByteArrayOrString())\n\t\treturn abiDecodingFunctionByteArrayAvailableLength(_type, _fromMemory);\n\tsolAssert(_type.calldataStride() > 0, \"\");\n\n\tstd::string functionName =\n\t\t\"abi_decode_available_length_\" +\n\t\t_type.identifier() +\n\t\t(_fromMemory ? \"_fromMemory\" : \"\");\n\n\treturn createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\t// <readableTypeName>\n\t\t\tfunction <functionName>(offset, length, end) -> array {\n\t\t\t\tarray := <allocate>(<allocationSize>(length))\n\t\t\t\tlet dst := array\n\t\t\t\t<?dynamic>\n\t\t\t\t\tmstore(array, length)\n\t\t\t\t\tdst := add(array, 0x20)\n\t\t\t\t</dynamic>\n\t\t\t\tlet srcEnd := add(offset, mul(length, <stride>))\n\t\t\t\tif gt(srcEnd, end) {\n\t\t\t\t\t<revertInvalidStride>()\n\t\t\t\t}\n\t\t\t\tfor { let src := offset } lt(src, srcEnd) { src := add(src, <stride>) }\n\t\t\t\t{\n\t\t\t\t\t<?dynamicBase>\n\t\t\t\t\t\tlet innerOffset := <load>(src)\n\t\t\t\t\t\tif gt(innerOffset, 0xffffffffffffffff) { <revertStringOffset>() }\n\t\t\t\t\t\tlet elementPos := add(offset, innerOffset)\n\t\t\t\t\t<!dynamicBase>\n\t\t\t\t\t\tlet elementPos := src\n\t\t\t\t\t</dynamicBase>\n\t\t\t\t\tmstore(dst, <decodingFun>(elementPos, end))\n\t\t\t\t\tdst := add(dst, 0x20)\n\t\t\t\t}\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"readableTypeName\", _type.toString(true));\n\t\ttempl(\"allocate\", m_utils.allocationFunction());\n\t\ttempl(\"allocationSize\", m_utils.arrayAllocationSizeFunction(_type));\n\t\ttempl(\"stride\", toCompactHexWithPrefix(_type.calldataStride()));\n\t\ttempl(\"dynamic\", _type.isDynamicallySized());\n\t\ttempl(\"load\", _fromMemory ? \"mload\" : \"calldataload\");\n\t\ttempl(\"dynamicBase\", _type.baseType()->isDynamicallyEncoded());\n\t\ttempl(\n\t\t\t\"revertInvalidStride\",\n\t\t\trevertReasonIfDebugFunction(\"ABI decoding: invalid calldata array stride\")\n\t\t);\n\t\ttempl(\"revertStringOffset\", revertReasonIfDebugFunction(\"ABI decoding: invalid calldata array offset\"));\n\t\ttempl(\"decodingFun\", abiDecodingFunction(*_type.baseType(), _fromMemory, false));\n\t\treturn templ.render();\n\t});\n}\n\nstd::string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type)\n{\n\tsolAssert(_type.dataStoredIn(DataLocation::CallData), \"\");\n\tif (!_type.isDynamicallySized())\n\t\tsolAssert(_type.length() < u256(\"0xffffffffffffffff\"), \"\");\n\tsolAssert(_type.calldataStride() > 0, \"\");\n\tsolAssert(_type.calldataStride() < u256(\"0xffffffffffffffff\"), \"\");\n\n\tstd::string functionName =\n\t\t\"abi_decode_\" +\n\t\t_type.identifier();\n\treturn createFunction(functionName, [&]() {\n\t\tWhiskers w;\n\t\tif (_type.isDynamicallySized())\n\t\t{\n\t\t\tw = Whiskers(R\"(\n\t\t\t\t// <readableTypeName>\n\t\t\t\tfunction <functionName>(offset, end) -> arrayPos, length {\n\t\t\t\t\tif iszero(slt(add(offset, 0x1f), end)) { <revertStringOffset>() }\n\t\t\t\t\tlength := calldataload(offset)\n\t\t\t\t\tif gt(length, 0xffffffffffffffff) { <revertStringLength>() }\n\t\t\t\t\tarrayPos := add(offset, 0x20)\n\t\t\t\t\tif gt(add(arrayPos, mul(length, <stride>)), end) { <revertStringPos>() }\n\t\t\t\t}\n\t\t\t)\");\n\t\t\tw(\"revertStringOffset\", revertReasonIfDebugFunction(\"ABI decoding: invalid calldata array offset\"));\n\t\t\tw(\"revertStringLength\", revertReasonIfDebugFunction(\"ABI decoding: invalid calldata array length\"));\n\t\t}\n\t\telse\n\t\t{\n\t\t\tw = Whiskers(R\"(\n\t\t\t\t// <readableTypeName>\n\t\t\t\tfunction <functionName>(offset, end) -> arrayPos {\n\t\t\t\t\tarrayPos := offset\n\t\t\t\t\tif gt(add(arrayPos, mul(<length>, <stride>)), end) { <revertStringPos>() }\n\t\t\t\t}\n\t\t\t)\");\n\t\t\tw(\"length\", toCompactHexWithPrefix(_type.length()));\n\t\t}\n\t\tw(\"revertStringPos\", revertReasonIfDebugFunction(\"ABI decoding: invalid calldata array stride\"));\n\t\tw(\"functionName\", functionName);\n\t\tw(\"readableTypeName\", _type.toString(true));\n\t\tw(\"stride\", toCompactHexWithPrefix(_type.calldataStride()));\n\n\t\t// TODO add test\n\t\treturn w.render();\n\t});\n}\n\nstd::string ABIFunctions::abiDecodingFunctionByteArrayAvailableLength(ArrayType const& _type, bool _fromMemory)\n{\n\tsolAssert(_type.dataStoredIn(DataLocation::Memory), \"\");\n\tsolAssert(_type.isByteArrayOrString(), \"\");\n\n\tstd::string functionName =\n\t\t\"abi_decode_available_length_\" +\n\t\t_type.identifier() +\n\t\t(_fromMemory ? \"_fromMemory\" : \"\");\n\n\treturn createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(src, length, end) -> array {\n\t\t\t\tarray := <allocate>(<allocationSize>(length))\n\t\t\t\tmstore(array, length)\n\t\t\t\tlet dst := add(array, 0x20)\n\t\t\t\tif gt(add(src, length), end) { <revertStringLength>() }\n\t\t\t\t<copyToMemFun>(src, dst, length)\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"revertStringLength\", revertReasonIfDebugFunction(\"ABI decoding: invalid byte array length\"));\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"allocate\", m_utils.allocationFunction());\n\t\ttempl(\"allocationSize\", m_utils.arrayAllocationSizeFunction(_type));\n\t\ttempl(\"copyToMemFun\", m_utils.copyToMemoryFunction(!_fromMemory, /*cleanup*/true));\n\t\treturn templ.render();\n\t});\n}\n\nstd::string ABIFunctions::abiDecodingFunctionCalldataStruct(StructType const& _type)\n{\n\tsolAssert(_type.dataStoredIn(DataLocation::CallData), \"\");\n\tstd::string functionName =\n\t\t\"abi_decode_\" +\n\t\t_type.identifier();\n\n\treturn createFunction(functionName, [&]() {\n\t\tWhiskers w{R\"(\n\t\t\t\t// <readableTypeName>\n\t\t\t\tfunction <functionName>(offset, end) -> value {\n\t\t\t\t\tif slt(sub(end, offset), <minimumSize>) { <revertString>() }\n\t\t\t\t\tvalue := offset\n\t\t\t\t}\n\t\t)\"};\n\t\t// TODO add test\n\t\tw(\"revertString\", revertReasonIfDebugFunction(\"ABI decoding: struct calldata too short\"));\n\t\tw(\"functionName\", functionName);\n\t\tw(\"readableTypeName\", _type.toString(true));\n\t\tw(\"minimumSize\", std::to_string(_type.isDynamicallyEncoded() ? _type.calldataEncodedTailSize() : _type.calldataEncodedSize(true)));\n\t\treturn w.render();\n\t});\n}\n\nstd::string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fromMemory)\n{\n\tsolAssert(!_type.dataStoredIn(DataLocation::CallData), \"\");\n\tstd::string functionName =\n\t\t\"abi_decode_\" +\n\t\t_type.identifier() +\n\t\t(_fromMemory ? \"_fromMemory\" : \"\");\n\n\treturn createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\t// <readableTypeName>\n\t\t\tfunction <functionName>(headStart, end) -> value {\n\t\t\t\tif slt(sub(end, headStart), <minimumSize>) { <revertString>() }\n\t\t\t\tvalue := <allocate>(<memorySize>)\n\t\t\t\t<#members>\n\t\t\t\t{\n\t\t\t\t\t// <memberName>\n\t\t\t\t\t<decode>\n\t\t\t\t}\n\t\t\t\t</members>\n\t\t\t}\n\t\t)\");\n\t\t// TODO add test\n\t\ttempl(\"revertString\", revertReasonIfDebugFunction(\"ABI decoding: struct data too short\"));\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"readableTypeName\", _type.toString(true));\n\t\ttempl(\"allocate\", m_utils.allocationFunction());\n\t\tsolAssert(_type.memoryDataSize() < u256(\"0xffffffffffffffff\"), \"\");\n\t\ttempl(\"memorySize\", toCompactHexWithPrefix(_type.memoryDataSize()));\n\t\tsize_t headPos = 0;\n\t\tstd::vector<std::map<std::string, std::string>> members;\n\t\tfor (auto const& member: _type.members(nullptr))\n\t\t{\n\t\t\tsolAssert(member.type, \"\");\n\t\t\tsolAssert(!member.type->containsNestedMapping(), \"\");\n\t\t\tauto decodingType = member.type->decodingType();\n\t\t\tsolAssert(decodingType, \"\");\n\t\t\tWhiskers memberTempl(R\"(\n\t\t\t\t<?dynamic>\n\t\t\t\t\tlet offset := <load>(add(headStart, <pos>))\n\t\t\t\t\tif gt(offset, 0xffffffffffffffff) { <revertString>() }\n\t\t\t\t<!dynamic>\n\t\t\t\t\tlet offset := <pos>\n\t\t\t\t</dynamic>\n\t\t\t\tmstore(add(value, <memoryOffset>), <abiDecode>(add(headStart, offset), end))\n\t\t\t)\");\n\t\t\tmemberTempl(\"dynamic\", decodingType->isDynamicallyEncoded());\n\t\t\t// TODO add test\n\t\t\tmemberTempl(\"revertString\", revertReasonIfDebugFunction(\"ABI decoding: invalid struct offset\"));\n\t\t\tmemberTempl(\"load\", _fromMemory ? \"mload\" : \"calldataload\");\n\t\t\tmemberTempl(\"pos\", std::to_string(headPos));\n\t\t\tmemberTempl(\"memoryOffset\", toCompactHexWithPrefix(_type.memoryOffsetOfMember(member.name)));\n\t\t\tmemberTempl(\"abiDecode\", abiDecodingFunction(*member.type, _fromMemory, false));\n\n\t\t\tmembers.emplace_back();\n\t\t\tmembers.back()[\"decode\"] = memberTempl.render();\n\t\t\tmembers.back()[\"memberName\"] = member.name;\n\t\t\theadPos += decodingType->calldataHeadSize();\n\t\t}\n\t\ttempl(\"members\", members);\n\t\ttempl(\"minimumSize\", toCompactHexWithPrefix(headPos));\n\t\treturn templ.render();\n\t});\n}\n\nstd::string ABIFunctions::abiDecodingFunctionFunctionType(FunctionType const& _type, bool _fromMemory, bool _forUseOnStack)\n{\n\tsolAssert(_type.kind() == FunctionType::Kind::External, \"\");\n\n\tstd::string functionName =\n\t\t\"abi_decode_\" +\n\t\t_type.identifier() +\n\t\t(_fromMemory ? \"_fromMemory\" : \"\") +\n\t\t(_forUseOnStack ? \"_onStack\" : \"\");\n\n\treturn createFunction(functionName, [&]() {\n\t\tif (_forUseOnStack)\n\t\t{\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(offset, end) -> addr, function_selector {\n\t\t\t\t\taddr, function_selector := <splitExtFun>(<decodeFun>(offset, end))\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"decodeFun\", abiDecodingFunctionFunctionType(_type, _fromMemory, false))\n\t\t\t(\"splitExtFun\", m_utils.splitExternalFunctionIdFunction())\n\t\t\t.render();\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(offset, end) -> fun {\n\t\t\t\t\tfun := <load>(offset)\n\t\t\t\t\t<validateExtFun>(fun)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"load\", _fromMemory ? \"mload\" : \"calldataload\")\n\t\t\t(\"validateExtFun\", m_utils.validatorFunction(_type, true))\n\t\t\t.render();\n\t\t}\n\t});\n}\n\nstd::string ABIFunctions::calldataAccessFunction(Type const& _type)\n{\n\tsolAssert(_type.isValueType() || _type.dataStoredIn(DataLocation::CallData), \"\");\n\tstd::string functionName = \"calldata_access_\" + _type.identifier();\n\treturn createFunction(functionName, [&]() {\n\t\tif (_type.isDynamicallyEncoded())\n\t\t{\n\t\t\tunsigned int tailSize = _type.calldataEncodedTailSize();\n\t\t\tsolAssert(tailSize > 1, \"\");\n\t\t\tWhiskers w(R\"(\n\t\t\t\tfunction <functionName>(base_ref, ptr) -> <return> {\n\t\t\t\t\tlet rel_offset_of_tail := calldataload(ptr)\n\t\t\t\t\tif iszero(slt(rel_offset_of_tail, sub(sub(calldatasize(), base_ref), sub(<neededLength>, 1)))) { <revertStringOffset>() }\n\t\t\t\t\tvalue := add(rel_offset_of_tail, base_ref)\n\t\t\t\t\t<handleLength>\n\t\t\t\t}\n\t\t\t)\");\n\t\t\tif (_type.isDynamicallySized())\n\t\t\t{\n\t\t\t\tauto const* arrayType = dynamic_cast<ArrayType const*>(&_type);\n\t\t\t\tsolAssert(!!arrayType, \"\");\n\t\t\t\tw(\"handleLength\", Whiskers(R\"(\n\t\t\t\t\tlength := calldataload(value)\n\t\t\t\t\tvalue := add(value, 0x20)\n\t\t\t\t\tif gt(length, 0xffffffffffffffff) { <revertStringLength>() }\n\t\t\t\t\tif sgt(value, sub(calldatasize(), mul(length, <calldataStride>))) { <revertStringStride>() }\n\t\t\t\t)\")\n\t\t\t\t(\"calldataStride\", toCompactHexWithPrefix(arrayType->calldataStride()))\n\t\t\t\t// TODO add test\n\t\t\t\t(\"revertStringLength\", revertReasonIfDebugFunction(\"Invalid calldata access length\"))\n\t\t\t\t// TODO add test\n\t\t\t\t(\"revertStringStride\", revertReasonIfDebugFunction(\"Invalid calldata access stride\"))\n\t\t\t\t.render());\n\t\t\t\tw(\"return\", \"value, length\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tw(\"handleLength\", \"\");\n\t\t\t\tw(\"return\", \"value\");\n\t\t\t}\n\t\t\tw(\"neededLength\", toCompactHexWithPrefix(tailSize));\n\t\t\tw(\"functionName\", functionName);\n\t\t\tw(\"revertStringOffset\", revertReasonIfDebugFunction(\"Invalid calldata access offset\"));\n\t\t\treturn w.render();\n\t\t}\n\t\telse if (_type.isValueType())\n\t\t{\n\t\t\tstd::string decodingFunction;\n\t\t\tif (auto const* functionType = dynamic_cast<FunctionType const*>(&_type))\n\t\t\t\tdecodingFunction = abiDecodingFunctionFunctionType(*functionType, false, false);\n\t\t\telse\n\t\t\t\tdecodingFunction = abiDecodingFunctionValueType(_type, false);\n\t\t\t// Note that the second argument to the decoding function should be discarded after inlining.\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(baseRef, ptr) -> value {\n\t\t\t\t\tvalue := <decodingFunction>(ptr, add(ptr, 32))\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"decodingFunction\", decodingFunction)\n\t\t\t.render();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\t_type.category() == Type::Category::Array ||\n\t\t\t\t_type.category() == Type::Category::Struct,\n\t\t\t\t\"\"\n\t\t\t);\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(baseRef, ptr) -> value {\n\t\t\t\t\tvalue := ptr\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t.render();\n\t\t}\n\t});\n}\n\nstd::string ABIFunctions::arrayStoreLengthForEncodingFunction(ArrayType const& _type, EncodingOptions const& _options)\n{\n\tstd::string functionName = \"array_storeLengthForEncoding_\" + _type.identifier() + _options.toFunctionNameSuffix();\n\treturn createFunction(functionName, [&]() {\n\t\tif (_type.isDynamicallySized() && !_options.dynamicInplace)\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(pos, length) -> updated_pos {\n\t\t\t\t\tmstore(pos, length)\n\t\t\t\t\tupdated_pos := add(pos, 0x20)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t.render();\n\t\telse\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(pos, length) -> updated_pos {\n\t\t\t\t\tupdated_pos := pos\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t.render();\n\t});\n}\n\nstd::string ABIFunctions::createFunction(std::string const& _name, std::function<std::string ()> const& _creator)\n{\n\treturn m_functionCollector.createFunction(_name, _creator);\n}\n\nsize_t ABIFunctions::headSize(TypePointers const& _targetTypes)\n{\n\tsize_t headSize = 0;\n\tfor (auto const& t: _targetTypes)\n\t\theadSize += t->calldataHeadSize();\n\n\treturn headSize;\n}\n\nsize_t ABIFunctions::numVariablesForType(Type const& _type, EncodingOptions const& _options)\n{\n\tif (_type.category() == Type::Category::Function && !_options.encodeFunctionFromStack)\n\t\treturn 1;\n\telse\n\t\treturn _type.sizeOnStack();\n}\n\nstd::string ABIFunctions::revertReasonIfDebugFunction(std::string const& _message)\n{\n\treturn m_utils.revertReasonIfDebugFunction(_message);\n}\n"
  },
  {
    "path": "libsolidity/codegen/ABIFunctions.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <chris@ethereum.org>\n * @date 2017\n * Routines that generate Yul code related to ABI encoding, decoding and type conversions.\n */\n\n#pragma once\n\n#include <libsolidity/codegen/MultiUseYulFunctionCollector.h>\n#include <libsolidity/codegen/YulUtilFunctions.h>\n\n#include <libsolidity/interface/DebugSettings.h>\n\n#include <liblangutil/EVMVersion.h>\n\n#include <functional>\n#include <map>\n#include <vector>\n\nnamespace solidity::frontend\n{\n\nclass Type;\nclass ArrayType;\nclass StructType;\nclass FunctionType;\nusing TypePointers = std::vector<Type const*>;\n\n/**\n * Class to generate encoding and decoding functions. Also maintains a collection\n * of \"functions to be generated\" in order to avoid generating the same function\n * multiple times.\n *\n * Make sure to include the result of ``requestedFunctions()`` to a block that\n * is visible from the code that was generated here, or use named labels.\n */\nclass ABIFunctions\n{\npublic:\n\texplicit ABIFunctions(\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tRevertStrings _revertStrings,\n\t\tMultiUseYulFunctionCollector& _functionCollector\n\t):\n\t\tm_evmVersion(_evmVersion),\n\t\tm_revertStrings(_revertStrings),\n\t\tm_functionCollector(_functionCollector),\n\t\tm_utils(_evmVersion, _eofVersion, m_revertStrings, m_functionCollector)\n\t{}\n\n\t/// @returns name of an assembly function to ABI-encode values of @a _givenTypes\n\t/// into memory, converting the types to @a _targetTypes on the fly.\n\t/// Parameters are: <headStart> <value_1> ... <value_n>, i.e.\n\t/// the layout on the stack is <value_n> ... <value_1> <headStart> with\n\t/// the top of the stack on the right.\n\t/// The values represent stack slots. If a type occupies more or less than one\n\t/// stack slot, it takes exactly that number of values.\n\t/// Returns a pointer to the end of the area written in memory.\n\t/// Does not allocate memory (does not change the free memory pointer), but writes\n\t/// to memory starting at $headStart and an unrestricted amount after that.\n\t/// If @reversed is true, the order of the variables after <headStart> is reversed.\n\tstd::string tupleEncoder(\n\t\tTypePointers const& _givenTypes,\n\t\tTypePointers _targetTypes,\n\t\tbool _encodeAsLibraryTypes = false,\n\t\tbool _reversed = false\n\t);\n\n\t/// Specialization of tupleEncoder to _reversed = true\n\tstd::string tupleEncoderReversed(\n\t\tTypePointers const& _givenTypes,\n\t\tTypePointers const& _targetTypes,\n\t\tbool _encodeAsLibraryTypes = false\n\t) {\n\t\treturn tupleEncoder(_givenTypes, _targetTypes, _encodeAsLibraryTypes, true);\n\t}\n\n\t/// @returns name of an assembly function to encode values of @a _givenTypes\n\t/// with packed encoding into memory, converting the types to @a _targetTypes on the fly.\n\t/// Parameters are: <memPos> <value_1> ... <value_n>, i.e.\n\t/// the layout on the stack is <value_n> ... <value_1> <memPos> with\n\t/// the top of the stack on the right.\n\t/// The values represent stack slots. If a type occupies more or less than one\n\t/// stack slot, it takes exactly that number of values.\n\t/// Returns a pointer to the end of the area written in memory.\n\t/// Does not allocate memory (does not change the free memory pointer), but writes\n\t/// to memory starting at memPos and an unrestricted amount after that.\n\t/// If @reversed is true, the order of the variables after <headStart> is reversed.\n\tstd::string tupleEncoderPacked(\n\t\tTypePointers const& _givenTypes,\n\t\tTypePointers _targetTypes,\n\t\tbool _reversed = false\n\t);\n\n\t/// Specialization of tupleEncoderPacked to _reversed = true\n\tstd::string tupleEncoderPackedReversed(TypePointers const& _givenTypes, TypePointers const& _targetTypes)\n\t{\n\t\treturn tupleEncoderPacked(_givenTypes, _targetTypes, true);\n\t}\n\n\t/// @returns name of an assembly function to ABI-decode values of @a _types\n\t/// into memory. If @a _fromMemory is true, decodes from memory instead of\n\t/// from calldata.\n\t/// Can allocate memory.\n\t/// Inputs: <source_offset> <source_end> (layout reversed on stack)\n\t/// Outputs: <value0> <value1> ... <valuen>\n\t/// The values represent stack slots. If a type occupies more or less than one\n\t/// stack slot, it takes exactly that number of values.\n\tstd::string tupleDecoder(TypePointers const& _types, bool _fromMemory = false);\n\n\tstruct EncodingOptions\n\t{\n\t\t/// Pad/signextend value types and bytes/string to multiples of 32 bytes.\n\t\t/// If false, data is always left-aligned.\n\t\t/// Note that this is always re-set to true for the elements of arrays and structs.\n\t\tbool padded = true;\n\t\t/// Store arrays and structs in place without \"data pointer\" and do not store the length.\n\t\tbool dynamicInplace = false;\n\t\t/// Only for external function types: The value is a pair of address / function id instead\n\t\t/// of a memory pointer to the compression representation.\n\t\tbool encodeFunctionFromStack = false;\n\t\t/// Encode storage pointers as storage pointers (we are targeting a library call).\n\t\tbool encodeAsLibraryTypes = false;\n\n\t\t/// @returns a string to uniquely identify the encoding options for the encoding\n\t\t/// function name. Skips everything that has its default value.\n\t\tstd::string toFunctionNameSuffix() const;\n\t};\n\n\t/// Internal encoding function that is also used by some copying routines.\n\t/// @returns the name of the ABI encoding function with the given type\n\t/// and queues the generation of the function to the requested functions.\n\t/// @param _fromStack if false, the input value was just loaded from storage\n\t/// or memory and thus might be compacted into a single slot (depending on the type).\n\tstd::string abiEncodingFunction(\n\t\tType const& _givenType,\n\t\tType const& _targetType,\n\t\tEncodingOptions const& _options\n\t);\n\t/// Internal encoding function that is also used by some copying routines.\n\t/// @returns the name of a function that internally calls `abiEncodingFunction`\n\t/// but always returns the updated encoding position, even if the type is\n\t/// statically encoded.\n\tstd::string abiEncodeAndReturnUpdatedPosFunction(\n\t\tType const& _givenType,\n\t\tType const& _targetType,\n\t\tEncodingOptions const& _options\n\t);\n\n\t/// Decodes array in case of dynamic arrays with offset pointing to\n\t/// data and length already on stack\n\t/// signature: (dataOffset, length, dataEnd) -> decodedArray\n\tstd::string abiDecodingFunctionArrayAvailableLength(ArrayType const& _type, bool _fromMemory);\n\n\t/// Internal decoding function that is also used by some copying routines.\n\t/// @returns the name of a function that decodes structs.\n\t/// signature: (dataStart, dataEnd) -> decodedStruct\n\tstd::string abiDecodingFunctionStruct(StructType const& _type, bool _fromMemory);\n\nprivate:\n\t/// Part of @a abiEncodingFunction for array target type and given calldata array.\n\t/// Uses calldatacopy and does not perform cleanup or validation and can therefore only\n\t/// be used for byte arrays and arrays with the base type uint256 or bytes32.\n\tstd::string abiEncodingFunctionCalldataArrayWithoutCleanup(\n\t\tType const& _givenType,\n\t\tType const& _targetType,\n\t\tEncodingOptions const& _options\n\t);\n\t/// Part of @a abiEncodingFunction for array target type and given memory array or\n\t/// a given storage array with every item occupies one or multiple full slots.\n\tstd::string abiEncodingFunctionSimpleArray(\n\t\tArrayType const& _givenType,\n\t\tArrayType const& _targetType,\n\t\tEncodingOptions const& _options\n\t);\n\tstd::string abiEncodingFunctionMemoryByteArray(\n\t\tArrayType const& _givenType,\n\t\tArrayType const& _targetType,\n\t\tEncodingOptions const& _options\n\t);\n\t/// Part of @a abiEncodingFunction for array target type and given storage array\n\t/// where multiple items are packed into the same storage slot.\n\tstd::string abiEncodingFunctionCompactStorageArray(\n\t\tArrayType const& _givenType,\n\t\tArrayType const& _targetType,\n\t\tEncodingOptions const& _options\n\t);\n\n\t/// Part of @a abiEncodingFunction for struct types.\n\tstd::string abiEncodingFunctionStruct(\n\t\tStructType const& _givenType,\n\t\tStructType const& _targetType,\n\t\tEncodingOptions const& _options\n\t);\n\n\t// @returns the name of the ABI encoding function with the given type\n\t// and queues the generation of the function to the requested functions.\n\t// Case for _givenType being a string literal\n\tstd::string abiEncodingFunctionStringLiteral(\n\t\tType const& _givenType,\n\t\tType const& _targetType,\n\t\tEncodingOptions const& _options\n\t);\n\n\tstd::string abiEncodingFunctionFunctionType(\n\t\tFunctionType const& _from,\n\t\tType const& _to,\n\t\tEncodingOptions const& _options\n\t);\n\n\t/// @returns the name of the ABI decoding function for the given type\n\t/// and queues the generation of the function to the requested functions.\n\t/// The caller has to ensure that no out of bounds access (at least to the static\n\t/// part) can happen inside this function.\n\t/// @param _fromMemory if decoding from memory instead of from calldata\n\t/// @param _forUseOnStack if the decoded value is stored on stack or in memory.\n\tstd::string abiDecodingFunction(\n\t\tType const& _type,\n\t\tbool _fromMemory,\n\t\tbool _forUseOnStack\n\t);\n\n\t/// Part of @a abiDecodingFunction for value types.\n\tstd::string abiDecodingFunctionValueType(Type const& _type, bool _fromMemory);\n\t/// Part of @a abiDecodingFunction for \"regular\" array types.\n\tstd::string abiDecodingFunctionArray(ArrayType const& _type, bool _fromMemory);\n\t/// Part of @a abiDecodingFunction for calldata array types.\n\tstd::string abiDecodingFunctionCalldataArray(ArrayType const& _type);\n\t/// Part of @a abiDecodingFunctionArrayAvailableLength\n\tstd::string abiDecodingFunctionByteArrayAvailableLength(ArrayType const& _type, bool _fromMemory);\n\t/// Part of @a abiDecodingFunction for calldata struct types.\n\tstd::string abiDecodingFunctionCalldataStruct(StructType const& _type);\n\t/// Part of @a abiDecodingFunction for array types.\n\tstd::string abiDecodingFunctionFunctionType(FunctionType const& _type, bool _fromMemory, bool _forUseOnStack);\n\t/// @returns the name of a function that retrieves an element from calldata.\n\tstd::string calldataAccessFunction(Type const& _type);\n\n\t/// @returns the name of a function used during encoding that stores the length\n\t/// if the array is dynamically sized (and the options do not request in-place encoding).\n\t/// It returns the new encoding position.\n\t/// If the array is not dynamically sized (or in-place encoding was requested),\n\t/// does nothing and just returns the position again.\n\tstd::string arrayStoreLengthForEncodingFunction(ArrayType const& _type, EncodingOptions const& _options);\n\n\t/// Helper function that uses @a _creator to create a function and add it to\n\t/// @a m_requestedFunctions if it has not been created yet and returns @a _name in both\n\t/// cases.\n\tstd::string createFunction(std::string const& _name, std::function<std::string()> const& _creator);\n\n\t/// @returns the size of the static part of the encoding of the given types.\n\tstatic size_t headSize(TypePointers const& _targetTypes);\n\n\t/// @returns the number of variables needed to store a type.\n\t/// This is one for almost all types. The exception being dynamically sized calldata arrays or\n\t/// external function types (if we are encoding from stack, i.e. _options.encodeFunctionFromStack\n\t/// is true), for which it is two.\n\tstatic size_t numVariablesForType(Type const& _type, EncodingOptions const& _options);\n\n\t/// @returns the name of a function that uses @param _message for revert reason\n\t/// if m_revertStrings is debug.\n\tstd::string revertReasonIfDebugFunction(std::string const& _message = \"\");\n\n\tlangutil::EVMVersion m_evmVersion;\n\tRevertStrings const m_revertStrings;\n\tMultiUseYulFunctionCollector& m_functionCollector;\n\tYulUtilFunctions m_utils;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ArrayUtils.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Code generation utils that handle arrays.\n */\n\n#include <libsolidity/codegen/ArrayUtils.h>\n\n#include <libsolidity/ast/Types.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/codegen/CompilerContext.h>\n#include <libsolidity/codegen/CompilerUtils.h>\n#include <libsolidity/codegen/LValue.h>\n\n#include <libsolutil/FunctionSelector.h>\n#include <libsolutil/Whiskers.h>\n#include <libsolutil/StackTooDeepString.h>\n\n#include <libevmasm/Instruction.h>\n#include <liblangutil/Exceptions.h>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\n\nvoid ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType const& _sourceType) const\n{\n\t// this copies source to target and also clears target if it was larger\n\t// need to leave \"target_ref target_byte_off\" on the stack at the end\n\n\t// stack layout: source_ref [source length] target_ref (top)\n\tsolAssert(_targetType.location() == DataLocation::Storage, \"\");\n\n\t// TODO unroll loop for small sizes\n\n\tbool fromCalldata = _sourceType.location() == DataLocation::CallData;\n\tbool haveSourceLengthOnStack = fromCalldata && _sourceType.isDynamicallySized();\n\n\tfor (unsigned i = _sourceType.sizeOnStack(); i > 0; --i)\n\t\tm_context << swapInstruction(i);\n\t// stack: target_ref source_ref [source_length]\n\n\tif (_sourceType.baseType()->category() == Type::Category::Array)\n\t{\n\t\t// TODO: This limitation can now be removed since we use Yul utility functions that handle nested arrays correctly.\n\t\t// The old inline assembly implementation couldn't handle nested calldata dynamic arrays, but the Yul functions\n\t\t// support them through recursive calls. We keep this check temporarily for backward compatibility.\n\t\tauto const& sourceBaseArrayType = dynamic_cast<ArrayType const&>(*_sourceType.baseType());\n\t\tsolUnimplementedAssert(\n\t\t\t!fromCalldata ||\n\t\t\t!_sourceType.isDynamicallyEncoded() ||\n\t\t\t!sourceBaseArrayType.isDynamicallySized(),\n\t\t\t\"Copying nested calldata dynamic arrays to storage is not implemented in the old code generator.\"\n\t\t);\n\t}\n\telse\n\t{\n\t\t// TODO: This limitation can now be removed since we use Yul utility functions that handle non-value types correctly.\n\t\t// The old inline assembly implementation couldn't handle copying arrays of non-value types from memory or calldata to storage,\n\t\t// but the Yul functions support them. We keep this check temporarily for backward compatibility.\n\t\tbool fromMemoryOrCalldata = _sourceType.location() == DataLocation::Memory || _sourceType.location() == DataLocation::CallData;\n\t\tsolUnimplementedAssert(\n\t\t\t_sourceType.baseType()->isValueType() || !fromMemoryOrCalldata,\n\t\t\t\"Copying of type \" + _sourceType.toString(false) + \" to storage is not supported in legacy (only supported by the IR pipeline). \" +\n\t\t\t\"Hint: try compiling with `--via-ir` (CLI) or the equivalent `viaIR: true` (Standard JSON).\"\n\t\t);\n\t}\n\n\tif (haveSourceLengthOnStack)\n\t{\n\t\t// stack: target_ref source_ref source_length\n\t\tm_context << Instruction::SWAP1;\n\t\t// stack: target_ref source_length source_ref\n\t\tm_context << Instruction::DUP3;\n\t\t// stack: target_ref source_length source_ref target_ref\n\t}\n\telse\n\t{\n\t\t// stack: target_ref source_ref\n\t\tm_context << Instruction::DUP2;\n\t\t// stack: target_ref source_ref target_ref\n\t}\n\n\tm_context.callYulFunction(\n\t\tm_context.utilFunctions().copyArrayToStorageFunction(_sourceType, _targetType),\n\t\thaveSourceLengthOnStack ? 3 : 2,\n\t\t0\n\t);\n\t// stack: target_ref\n}\n\nvoid ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWordBoundaries) const\n{\n\tsolUnimplementedAssert(\n\t\t!_sourceType.baseType()->isDynamicallySized(),\n\t\t\"Nested dynamic arrays not implemented here.\"\n\t);\n\tCompilerUtils utils(m_context);\n\n\tif (_sourceType.location() == DataLocation::CallData)\n\t{\n\t\tif (!_sourceType.isDynamicallySized())\n\t\t\tm_context << _sourceType.length();\n\t\tif (!_sourceType.isByteArrayOrString())\n\t\t\tconvertLengthToSize(_sourceType);\n\n\t\tstd::string routine = \"calldatacopy(target, source, len)\\n\";\n\t\tif (_padToWordBoundaries)\n\t\t\troutine += R\"(\n\t\t\t\t// Set padding suffix to zero\n\t\t\t\tmstore(add(target, len), 0)\n\t\t\t\tlen := and(add(len, 0x1f), not(0x1f))\n\t\t\t)\";\n\t\troutine += \"target := add(target, len)\\n\";\n\t\tm_context.appendInlineAssembly(\"{\" + routine + \"}\", {\"target\", \"source\", \"len\"});\n\t\tm_context << Instruction::POP << Instruction::POP;\n\t}\n\telse if (_sourceType.location() == DataLocation::Memory)\n\t{\n\t\tretrieveLength(_sourceType);\n\t\t// stack: target source length\n\t\tif (!_sourceType.baseType()->isValueType())\n\t\t{\n\t\t\t// copy using a loop\n\t\t\tm_context << u256(0) << Instruction::SWAP3;\n\t\t\t// stack: counter source length target\n\t\t\tauto repeat = m_context.newTag();\n\t\t\tm_context << repeat;\n\t\t\tm_context << Instruction::DUP2 << Instruction::DUP5;\n\t\t\tm_context << Instruction::LT << Instruction::ISZERO;\n\t\t\tauto loopEnd = m_context.appendConditionalJump();\n\t\t\tm_context << Instruction::DUP3 << Instruction::DUP5;\n\t\t\taccessIndex(_sourceType, false);\n\t\t\tMemoryItem(m_context, *_sourceType.baseType(), true).retrieveValue(SourceLocation(), true);\n\t\t\tif (auto baseArray = dynamic_cast<ArrayType const*>(_sourceType.baseType()))\n\t\t\t\tcopyArrayToMemory(*baseArray, _padToWordBoundaries);\n\t\t\telse\n\t\t\t\tutils.storeInMemoryDynamic(*_sourceType.baseType());\n\t\t\tm_context << Instruction::SWAP3 << u256(1) << Instruction::ADD;\n\t\t\tm_context << Instruction::SWAP3;\n\t\t\tm_context.appendJumpTo(repeat);\n\t\t\tm_context << loopEnd;\n\t\t\tm_context << Instruction::SWAP3;\n\t\t\tutils.popStackSlots(3);\n\t\t\t// stack: updated_target_pos\n\t\t\treturn;\n\t\t}\n\n\t\t// memcpy using the built-in contract\n\t\tif (_sourceType.isDynamicallySized())\n\t\t{\n\t\t\t// change pointer to data part\n\t\t\tm_context << Instruction::SWAP1 << u256(32) << Instruction::ADD;\n\t\t\tm_context << Instruction::SWAP1;\n\t\t}\n\t\tif (!_sourceType.isByteArrayOrString())\n\t\t\tconvertLengthToSize(_sourceType);\n\t\t// stack: <target> <source> <size>\n\t\tm_context << Instruction::DUP1 << Instruction::DUP4 << Instruction::DUP4;\n\t\t// We can resort to copying full 32 bytes only if\n\t\t// - the length is known to be a multiple of 32 or\n\t\t// - we will pad to full 32 bytes later anyway.\n\t\tif (!_sourceType.isByteArrayOrString() || _padToWordBoundaries)\n\t\t\tutils.memoryCopy32();\n\t\telse\n\t\t\tutils.memoryCopy();\n\n\t\tm_context << Instruction::SWAP1 << Instruction::POP;\n\t\t// stack: <target> <size>\n\n\t\tbool paddingNeeded = _padToWordBoundaries && _sourceType.isByteArrayOrString();\n\n\t\tif (paddingNeeded)\n\t\t{\n\t\t\t// stack: <target> <size>\n\t\t\tm_context << Instruction::SWAP1 << Instruction::DUP2 << Instruction::ADD;\n\t\t\t// stack: <length> <target + size>\n\t\t\tm_context << Instruction::SWAP1 << u256(31) << Instruction::AND;\n\t\t\t// stack: <target + size> <remainder = size % 32>\n\t\t\tevmasm::AssemblyItem skip = m_context.newTag();\n\t\t\tif (_sourceType.isDynamicallySized())\n\t\t\t{\n\t\t\t\tm_context << Instruction::DUP1 << Instruction::ISZERO;\n\t\t\t\tm_context.appendConditionalJumpTo(skip);\n\t\t\t}\n\t\t\t// round off, load from there.\n\t\t\t// stack <target + size> <remainder = size % 32>\n\t\t\tm_context << Instruction::DUP1 << Instruction::DUP3;\n\t\t\tm_context << Instruction::SUB;\n\t\t\t// stack: target+size remainder <target + size - remainder>\n\t\t\tm_context << Instruction::DUP1 << Instruction::MLOAD;\n\t\t\t// Now we AND it with ~(2**(8 * (32 - remainder)) - 1)\n\t\t\tm_context << u256(1);\n\t\t\tm_context << Instruction::DUP4 << u256(32) << Instruction::SUB;\n\t\t\t// stack: ...<v> 1 <32 - remainder>\n\t\t\tm_context << u256(0x100) << Instruction::EXP << Instruction::SUB;\n\t\t\tm_context << Instruction::NOT << Instruction::AND;\n\t\t\t// stack: target+size remainder target+size-remainder <v & ...>\n\t\t\tm_context << Instruction::DUP2 << Instruction::MSTORE;\n\t\t\t// stack: target+size remainder target+size-remainder\n\t\t\tm_context << u256(32) << Instruction::ADD;\n\t\t\t// stack: target+size remainder <new_padded_end>\n\t\t\tm_context << Instruction::SWAP2 << Instruction::POP;\n\n\t\t\tif (_sourceType.isDynamicallySized())\n\t\t\t\tm_context << skip.tag();\n\t\t\t// stack <target + \"size\"> <remainder = size % 32>\n\t\t\tm_context << Instruction::POP;\n\t\t}\n\t\telse\n\t\t\t// stack: <target> <size>\n\t\t\tm_context << Instruction::ADD;\n\t}\n\telse\n\t{\n\t\tsolAssert(_sourceType.location() == DataLocation::Storage, \"\");\n\t\tunsigned storageBytes = _sourceType.baseType()->storageBytes();\n\t\tu256 storageSize = _sourceType.baseType()->storageSize();\n\t\tsolAssert(storageSize > 1 || (storageSize == 1 && storageBytes > 0), \"\");\n\n\t\tretrieveLength(_sourceType);\n\t\t// stack here: memory_offset storage_offset length\n\t\t// jump to end if length is zero\n\t\tm_context << Instruction::DUP1 << Instruction::ISZERO;\n\t\tevmasm::AssemblyItem loopEnd = m_context.appendConditionalJump();\n\t\t// Special case for tightly-stored byte arrays\n\t\tif (_sourceType.isByteArrayOrString())\n\t\t{\n\t\t\t// stack here: memory_offset storage_offset length\n\t\t\tm_context << Instruction::DUP1 << u256(31) << Instruction::LT;\n\t\t\tevmasm::AssemblyItem longByteArray = m_context.appendConditionalJump();\n\t\t\t// store the short byte array (discard lower-order byte)\n\t\t\tm_context << u256(0x100) << Instruction::DUP1;\n\t\t\tm_context << Instruction::DUP4 << Instruction::SLOAD;\n\t\t\tm_context << Instruction::DIV << Instruction::MUL;\n\t\t\tm_context << Instruction::DUP4 << Instruction::MSTORE;\n\t\t\t// stack here: memory_offset storage_offset length\n\t\t\t// add 32 or length to memory offset\n\t\t\tm_context << Instruction::SWAP2;\n\t\t\tif (_padToWordBoundaries)\n\t\t\t\tm_context << u256(32);\n\t\t\telse\n\t\t\t\tm_context << Instruction::DUP3;\n\t\t\tm_context << Instruction::ADD;\n\t\t\tm_context << Instruction::SWAP2;\n\t\t\tm_context.appendJumpTo(loopEnd);\n\t\t\tm_context << longByteArray;\n\t\t}\n\t\telse\n\t\t\t// convert length to memory size\n\t\t\tm_context << _sourceType.baseType()->memoryHeadSize() << Instruction::MUL;\n\n\t\tm_context << Instruction::DUP3 << Instruction::ADD << Instruction::SWAP2;\n\t\tif (_sourceType.isDynamicallySized())\n\t\t{\n\t\t\t// actual array data is stored at KECCAK256(storage_offset)\n\t\t\tm_context << Instruction::SWAP1;\n\t\t\tutils.computeHashStatic();\n\t\t\tm_context << Instruction::SWAP1;\n\t\t}\n\n\t\t// stack here: memory_end_offset storage_data_offset memory_offset\n\t\tbool haveByteOffset = !_sourceType.isByteArrayOrString() && storageBytes <= 16;\n\t\tif (haveByteOffset)\n\t\t\tm_context << u256(0) << Instruction::SWAP1;\n\t\t// stack here: memory_end_offset storage_data_offset [storage_byte_offset] memory_offset\n\t\tevmasm::AssemblyItem loopStart = m_context.newTag();\n\t\tm_context << loopStart;\n\t\t// load and store\n\t\tif (_sourceType.isByteArrayOrString())\n\t\t{\n\t\t\t// Packed both in storage and memory.\n\t\t\tm_context << Instruction::DUP2 << Instruction::SLOAD;\n\t\t\tm_context << Instruction::DUP2 << Instruction::MSTORE;\n\t\t\t// increment storage_data_offset by 1\n\t\t\tm_context << Instruction::SWAP1 << u256(1) << Instruction::ADD;\n\t\t\t// increment memory offset by 32\n\t\t\tm_context << Instruction::SWAP1 << u256(32) << Instruction::ADD;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// stack here: memory_end_offset storage_data_offset [storage_byte_offset] memory_offset\n\t\t\tif (haveByteOffset)\n\t\t\t\tm_context << Instruction::DUP3 << Instruction::DUP3;\n\t\t\telse\n\t\t\t\tm_context << Instruction::DUP2 << u256(0);\n\t\t\tStorageItem(m_context, *_sourceType.baseType()).retrieveValue(SourceLocation(), true);\n\t\t\tif (auto baseArray = dynamic_cast<ArrayType const*>(_sourceType.baseType()))\n\t\t\t\tcopyArrayToMemory(*baseArray, _padToWordBoundaries);\n\t\t\telse\n\t\t\t\tutils.storeInMemoryDynamic(*_sourceType.baseType());\n\t\t\t// increment storage_data_offset and byte offset\n\t\t\tif (haveByteOffset)\n\t\t\t\tincrementByteOffset(storageBytes, 2, 3);\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t\tm_context << storageSize << Instruction::ADD;\n\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t}\n\t\t}\n\t\t// check for loop condition\n\t\tm_context << Instruction::DUP1 << dupInstruction(haveByteOffset ? 5 : 4);\n\t\tm_context << Instruction::GT;\n\t\tm_context.appendConditionalJumpTo(loopStart);\n\t\t// stack here: memory_end_offset storage_data_offset [storage_byte_offset] memory_offset\n\t\tif (haveByteOffset)\n\t\t\tm_context << Instruction::SWAP1 << Instruction::POP;\n\t\tif (!_sourceType.isByteArrayOrString())\n\t\t{\n\t\t\tsolAssert(_sourceType.calldataStride() % 32 == 0, \"\");\n\t\t\tsolAssert(_sourceType.memoryStride() % 32 == 0, \"\");\n\t\t}\n\t\tif (_padToWordBoundaries && _sourceType.isByteArrayOrString())\n\t\t{\n\t\t\t// memory_end_offset - start is the actual length (we want to compute the ceil of).\n\t\t\t// memory_offset - start is its next multiple of 32, but it might be off by 32.\n\t\t\t// so we compute: memory_end_offset += (memory_offset - memory_end_offset) & 31\n\t\t\tm_context << Instruction::DUP3 << Instruction::SWAP1 << Instruction::SUB;\n\t\t\tm_context << u256(31) << Instruction::AND;\n\t\t\tm_context << Instruction::DUP3 << Instruction::ADD;\n\t\t\tm_context << Instruction::SWAP2;\n\t\t}\n\t\tm_context << loopEnd << Instruction::POP << Instruction::POP;\n\t}\n}\n\nvoid ArrayUtils::clearArray(ArrayType const& _typeIn) const\n{\n\tType const* type = &_typeIn;\n\tm_context.callLowLevelFunction(\n\t\t\"$clearArray_\" + _typeIn.identifier(),\n\t\t2,\n\t\t0,\n\t\t[type](CompilerContext& _context)\n\t\t{\n\t\t\tArrayType const& _type = dynamic_cast<ArrayType const&>(*type);\n\t\t\tunsigned stackHeightStart = _context.stackHeight();\n\t\t\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\t\t\tif (_type.baseType()->storageBytes() < 32)\n\t\t\t{\n\t\t\t\tsolAssert(_type.baseType()->isValueType(), \"Invalid storage size for non-value type.\");\n\t\t\t\tsolAssert(_type.baseType()->storageSize() <= 1, \"Invalid storage size for type.\");\n\t\t\t}\n\t\t\tif (_type.baseType()->isValueType())\n\t\t\t\tsolAssert(_type.baseType()->storageSize() <= 1, \"Invalid size for value type.\");\n\n\t\t\t_context << Instruction::POP; // remove byte offset\n\t\t\tif (_type.isDynamicallySized())\n\t\t\t\tArrayUtils(_context).clearDynamicArray(_type);\n\t\t\telse if (_type.length() == 0 || _type.baseType()->category() == Type::Category::Mapping)\n\t\t\t\t_context << Instruction::POP;\n\t\t\telse if (_type.baseType()->isValueType() && _type.storageSize() <= 5)\n\t\t\t{\n\t\t\t\t// unroll loop for small arrays @todo choose a good value\n\t\t\t\t// Note that we loop over storage slots here, not elements.\n\t\t\t\tfor (unsigned i = 1; i < _type.storageSize(); ++i)\n\t\t\t\t\t_context\n\t\t\t\t\t\t<< u256(0) << Instruction::DUP2 << Instruction::SSTORE\n\t\t\t\t\t\t<< u256(1) << Instruction::ADD;\n\t\t\t\t_context << u256(0) << Instruction::SWAP1 << Instruction::SSTORE;\n\t\t\t}\n\t\t\telse if (!_type.baseType()->isValueType() && _type.length() <= 4)\n\t\t\t{\n\t\t\t\t// unroll loop for small arrays @todo choose a good value\n\t\t\t\tsolAssert(_type.baseType()->storageBytes() >= 32, \"Invalid storage size.\");\n\t\t\t\tfor (unsigned i = 1; i < _type.length(); ++i)\n\t\t\t\t{\n\t\t\t\t\t_context << u256(0);\n\t\t\t\t\tStorageItem(_context, *_type.baseType()).setToZero(SourceLocation(), false);\n\t\t\t\t\t_context\n\t\t\t\t\t\t<< Instruction::POP\n\t\t\t\t\t\t<< u256(_type.baseType()->storageSize()) << Instruction::ADD;\n\t\t\t\t}\n\t\t\t\t_context << u256(0);\n\t\t\t\tStorageItem(_context, *_type.baseType()).setToZero(SourceLocation(), true);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t_context << _type.length();\n\t\t\t\tArrayUtils(_context).convertLengthToSize(_type);\n\t\t\t\t// stack: storage_ref slot_count\n\t\t\t\tif (_type.baseType()->storageBytes() < 32)\n\t\t\t\t\tArrayUtils(_context).clearStorageLoop(TypeProvider::uint256());\n\t\t\t\telse\n\t\t\t\t\tArrayUtils(_context).clearStorageLoop(_type.baseType());\n\t\t\t}\n\t\t\tsolAssert(_context.stackHeight() == stackHeightStart - 2, \"\");\n\t\t}\n\t);\n}\n\nvoid ArrayUtils::clearDynamicArray(ArrayType const& _type) const\n{\n\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\tsolAssert(_type.isDynamicallySized(), \"\");\n\n\t// fetch length\n\tretrieveLength(_type);\n\t// set length to zero\n\tm_context << u256(0) << Instruction::DUP3 << Instruction::SSTORE;\n\t// Special case: short byte arrays are stored togeher with their length\n\tevmasm::AssemblyItem endTag = m_context.newTag();\n\tif (_type.isByteArrayOrString())\n\t{\n\t\t// stack: ref old_length\n\t\tm_context << Instruction::DUP1 << u256(31) << Instruction::LT;\n\t\tevmasm::AssemblyItem longByteArray = m_context.appendConditionalJump();\n\t\t// Short byte array: no data slots to clear, just pop and exit\n\t\tm_context << Instruction::POP << Instruction::POP;\n\t\tm_context.appendJumpTo(endTag);\n\t\tm_context.adjustStackOffset(2); // the longByteArray path has 2 more items on stack\n\t\tm_context << longByteArray;\n\t}\n\t// stack: ref old_length\n\tconvertLengthToSize(_type);\n\t// stack: ref slot_count\n\tm_context << Instruction::SWAP1;\n\tCompilerUtils(m_context).computeHashStatic();\n\t// stack: slot_count data_pos\n\tm_context << Instruction::SWAP1;\n\t// stack: data_pos slot_count\n\tif (_type.storageStride() < 32)\n\t\tclearStorageLoop(TypeProvider::uint256());\n\telse\n\t\tclearStorageLoop(_type.baseType());\n\t// cleanup\n\tm_context << endTag;\n}\n\nvoid ArrayUtils::incrementDynamicArraySize(ArrayType const& _type) const\n{\n\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\tsolAssert(_type.isDynamicallySized(), \"\");\n\tif (!_type.isByteArrayOrString() && _type.baseType()->storageBytes() < 32)\n\t\tsolAssert(_type.baseType()->isValueType(), \"Invalid storage size for non-value type.\");\n\n\tif (_type.isByteArrayOrString())\n\t{\n\t\t// We almost always just add 2 (length of byte arrays is shifted left by one)\n\t\t// except for the case where we transition from a short byte array\n\t\t// to a long byte array, there we have to copy.\n\t\t// This happens if the length is exactly 31, which means that the\n\t\t// lowest-order byte (we actually use a mask with fewer bits) must\n\t\t// be (31*2+0) = 62\n\n\t\tm_context << Instruction::DUP1 << Instruction::SLOAD << Instruction::DUP1;\n\t\tm_context.callYulFunction(m_context.utilFunctions().extractByteArrayLengthFunction(), 1, 1);\n\t\tm_context.appendInlineAssembly(R\"({\n\t\t\t// We have to copy if length is exactly 31, because that marks\n\t\t\t// the transition between in-place and out-of-place storage.\n\t\t\tswitch length\n\t\t\tcase 31\n\t\t\t{\n\t\t\t\tmstore(0, ref)\n\t\t\t\tlet data_area := keccak256(0, 0x20)\n\t\t\t\tsstore(data_area, and(data, not(0xff)))\n\t\t\t\t// Set old length in new format (31 * 2 + 1)\n\t\t\t\tdata := 63\n\t\t\t}\n\t\t\tsstore(ref, add(data, 2))\n\t\t\t// return new length in ref\n\t\t\tref := add(length, 1)\n\t\t})\", {\"ref\", \"data\", \"length\"});\n\t\tm_context << Instruction::POP << Instruction::POP;\n\t}\n\telse\n\t\tm_context.appendInlineAssembly(R\"({\n\t\t\tlet new_length := add(sload(ref), 1)\n\t\t\tsstore(ref, new_length)\n\t\t\tref := new_length\n\t\t})\", {\"ref\"});\n}\n\nvoid ArrayUtils::popStorageArrayElement(ArrayType const& _type) const\n{\n\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\tsolAssert(_type.isDynamicallySized(), \"\");\n\tif (!_type.isByteArrayOrString() && _type.baseType()->storageBytes() < 32)\n\t\tsolAssert(_type.baseType()->isValueType(), \"Invalid storage size for non-value type.\");\n\n\tif (_type.isByteArrayOrString())\n\t{\n\t\tm_context << Instruction::DUP1 << Instruction::SLOAD << Instruction::DUP1;\n\t\tm_context.callYulFunction(m_context.utilFunctions().extractByteArrayLengthFunction(), 1, 1);\n\t\tutil::Whiskers code(R\"({\n\t\t\tif iszero(length) {\n\t\t\t\tmstore(0, <panicSelector>)\n\t\t\t\tmstore(4, <emptyArrayPop>)\n\t\t\t\trevert(0, 0x24)\n\t\t\t}\n\t\t\tswitch gt(length, 31)\n\t\t\tcase 0 {\n\t\t\t\t// short byte array\n\t\t\t\t// Zero-out the suffix including the least significant byte.\n\t\t\t\tlet mask := sub(exp(0x100, sub(33, length)), 1)\n\t\t\t\tlength := sub(length, 1)\n\t\t\t\tslot_value := or(and(not(mask), slot_value), mul(length, 2))\n\t\t\t}\n\t\t\tcase 1 {\n\t\t\t\t// long byte array\n\t\t\t\tmstore(0, ref)\n\t\t\t\tlet slot := keccak256(0, 0x20)\n\t\t\t\tswitch length\n\t\t\t\tcase 32\n\t\t\t\t{\n\t\t\t\t\tlet data := sload(slot)\n\t\t\t\t\tsstore(slot, 0)\n\t\t\t\t\tdata := and(data, not(0xff))\n\t\t\t\t\tslot_value := or(data, 62)\n\t\t\t\t}\n\t\t\t\tdefault\n\t\t\t\t{\n\t\t\t\t\tlet offset_inside_slot := and(sub(length, 1), 0x1f)\n\t\t\t\t\tslot := add(slot, div(sub(length, 1), 32))\n\t\t\t\t\tlet data := sload(slot)\n\n\t\t\t\t\t// Zero-out the suffix of the byte array by masking it.\n\t\t\t\t\t// ((1<<(8 * (32 - offset))) - 1)\n\t\t\t\t\tlet mask := sub(exp(0x100, sub(32, offset_inside_slot)), 1)\n\t\t\t\t\tdata := and(not(mask), data)\n\t\t\t\t\tsstore(slot, data)\n\n\t\t\t\t\t// Reduce the length by 1\n\t\t\t\t\tslot_value := sub(slot_value, 2)\n\t\t\t\t}\n\t\t\t}\n\t\t\tsstore(ref, slot_value)\n\t\t})\");\n\t\tcode(\"panicSelector\", util::selectorFromSignatureU256(\"Panic(uint256)\").str());\n\t\tcode(\"emptyArrayPop\", std::to_string(unsigned(util::PanicCode::EmptyArrayPop)));\n\t\tm_context.appendInlineAssembly(code.render(), {\"ref\", \"slot_value\", \"length\"});\n\t\tm_context << Instruction::POP << Instruction::POP << Instruction::POP;\n\t}\n\telse\n\t{\n\t\t// stack: ArrayReference\n\t\tretrieveLength(_type);\n\t\t// stack: ArrayReference oldLength\n\t\tm_context << Instruction::DUP1;\n\t\t// stack: ArrayReference oldLength oldLength\n\t\tm_context << Instruction::ISZERO;\n\t\tm_context.appendConditionalPanic(util::PanicCode::EmptyArrayPop);\n\n\t\t// Stack: ArrayReference oldLength\n\t\tm_context << u256(1) << Instruction::SWAP1 << Instruction::SUB;\n\t\t// Stack ArrayReference newLength\n\n\t\tif (_type.baseType()->category() != Type::Category::Mapping)\n\t\t{\n\t\t\tm_context << Instruction::DUP2 << Instruction::DUP2;\n\t\t\t// Stack ArrayReference newLength ArrayReference newLength;\n\t\t\taccessIndex(_type, false);\n\t\t\t// Stack: ArrayReference newLength storage_slot byte_offset\n\t\t\tStorageItem(m_context, *_type.baseType()).setToZero(SourceLocation(), true);\n\t\t}\n\n\t\t// Stack: ArrayReference newLength\n\t\tm_context << Instruction::SWAP1 << Instruction::SSTORE;\n\t}\n}\n\nvoid ArrayUtils::clearStorageLoop(Type const* _type) const\n{\n\tsolAssert(_type->storageBytes() >= 32, \"\");\n\tm_context.callLowLevelFunction(\n\t\t\"$clearStorageLoop_\" + _type->identifier(),\n\t\t2,\n\t\t0,\n\t\t[_type](CompilerContext& _context)\n\t\t{\n\t\t\tunsigned stackHeightStart = _context.stackHeight();\n\t\t\tif (_type->category() == Type::Category::Mapping)\n\t\t\t{\n\t\t\t\t_context << Instruction::POP << Instruction::POP;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// stack: start_pos slot_count\n\t\t\t// Initialize loop counter i = 0\n\t\t\t_context << u256(0);\n\t\t\t// stack: start_pos slot_count i\n\t\t\tevmasm::AssemblyItem loopStart = _context.appendJumpToNew();\n\t\t\t_context << loopStart;\n\t\t\t// check for loop condition: !(slot_count > i) = (i >= slot_count)\n\t\t\t_context << Instruction::DUP1 << Instruction::DUP3 << Instruction::GT << Instruction::ISZERO;\n\t\t\tevmasm::AssemblyItem zeroLoopEnd = _context.newTag();\n\t\t\t_context.appendConditionalJumpTo(zeroLoopEnd);\n\t\t\t// stack: start_pos slot_count i\n\t\t\t// compute storage position: start_pos + i\n\t\t\t_context << Instruction::DUP3 << Instruction::DUP2 << Instruction::ADD;\n\t\t\t// stack: start_pos slot_count i (start_pos+i)\n\t\t\t// delete storage slot\n\t\t\t_context << u256(0);\n\t\t\tStorageItem(_context, *_type).setToZero(SourceLocation(), /* _removeReference = */ true);\n\t\t\t// stack: start_pos slot_count i\n\t\t\t// increment counter: i += storageSize\n\t\t\t_context << _type->storageSize() << Instruction::ADD;\n\t\t\t_context.appendJumpTo(loopStart);\n\t\t\t// cleanup\n\t\t\t_context << zeroLoopEnd;\n\t\t\t// stack: start_pos slot_count i\n\t\t\t_context << Instruction::POP << Instruction::POP << Instruction::POP;\n\t\t\tsolAssert(_context.stackHeight() == stackHeightStart - 2, \"\");\n\t\t}\n\t);\n}\n\nvoid ArrayUtils::convertLengthToSize(ArrayType const& _arrayType, bool _pad) const\n{\n\tif (_arrayType.location() == DataLocation::Storage)\n\t{\n\t\tif (_arrayType.baseType()->storageSize() <= 1)\n\t\t{\n\t\t\tunsigned baseBytes = _arrayType.baseType()->storageBytes();\n\t\t\tif (baseBytes == 0)\n\t\t\t\tm_context << Instruction::POP << u256(1);\n\t\t\telse if (baseBytes <= 16)\n\t\t\t{\n\t\t\t\tunsigned itemsPerSlot = 32 / baseBytes;\n\t\t\t\tm_context\n\t\t\t\t\t<< u256(itemsPerSlot - 1) << Instruction::ADD\n\t\t\t\t\t<< u256(itemsPerSlot) << Instruction::SWAP1 << Instruction::DIV;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tm_context << _arrayType.baseType()->storageSize() << Instruction::MUL;\n\t}\n\telse\n\t{\n\t\tif (!_arrayType.isByteArrayOrString())\n\t\t{\n\t\t\tif (_arrayType.location() == DataLocation::Memory)\n\t\t\t\tm_context << _arrayType.memoryStride();\n\t\t\telse\n\t\t\t\tm_context << _arrayType.calldataStride();\n\t\t\tm_context << Instruction::MUL;\n\t\t}\n\t\telse if (_pad)\n\t\t\tm_context << u256(31) << Instruction::ADD\n\t\t\t\t<< u256(32) << Instruction::DUP1\n\t\t\t\t<< Instruction::SWAP2 << Instruction::DIV << Instruction::MUL;\n\t}\n}\n\nvoid ArrayUtils::retrieveLength(ArrayType const& _arrayType, unsigned _stackDepth) const\n{\n\tif (!_arrayType.isDynamicallySized())\n\t\tm_context << _arrayType.length();\n\telse\n\t{\n\t\tm_context << dupInstruction(1 + _stackDepth);\n\t\tswitch (_arrayType.location())\n\t\t{\n\t\tcase DataLocation::CallData:\n\t\t\t// length is stored on the stack\n\t\t\tbreak;\n\t\tcase DataLocation::Memory:\n\t\t\tm_context << Instruction::MLOAD;\n\t\t\tbreak;\n\t\tcase DataLocation::Storage:\n\t\t\tm_context << Instruction::SLOAD;\n\t\t\tif (_arrayType.isByteArrayOrString())\n\t\t\t\tm_context.callYulFunction(m_context.utilFunctions().extractByteArrayLengthFunction(), 1, 1);\n\t\t\tbreak;\n\t\tcase DataLocation::Transient:\n\t\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nvoid ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck, bool _keepReference) const\n{\n\t/// Stack: reference [length] index\n\tDataLocation location = _arrayType.location();\n\n\tif (_doBoundsCheck)\n\t{\n\t\t// retrieve length\n\t\tArrayUtils::retrieveLength(_arrayType, 1);\n\t\t// Stack: ref [length] index length\n\t\t// check out-of-bounds access\n\t\tm_context << Instruction::DUP2 << Instruction::LT << Instruction::ISZERO;\n\t\t// out-of-bounds access throws exception\n\t\tm_context.appendConditionalPanic(util::PanicCode::ArrayOutOfBounds);\n\t}\n\tif (location == DataLocation::CallData && _arrayType.isDynamicallySized())\n\t\t// remove length if present\n\t\tm_context << Instruction::SWAP1 << Instruction::POP;\n\n\t// stack: <base_ref> <index>\n\tswitch (location)\n\t{\n\tcase DataLocation::Memory:\n\t\t// stack: <base_ref> <index>\n\t\tif (!_arrayType.isByteArrayOrString())\n\t\t\tm_context << u256(_arrayType.memoryHeadSize()) << Instruction::MUL;\n\t\tif (_arrayType.isDynamicallySized())\n\t\t\tm_context << u256(32) << Instruction::ADD;\n\t\tif (_keepReference)\n\t\t\tm_context << Instruction::DUP2;\n\t\tm_context << Instruction::ADD;\n\t\tbreak;\n\tcase DataLocation::CallData:\n\t\tif (!_arrayType.isByteArrayOrString())\n\t\t{\n\t\t\tm_context << _arrayType.calldataStride();\n\t\t\tm_context << Instruction::MUL;\n\t\t}\n\t\t// stack: <base_ref> <index * size>\n\t\tif (_keepReference)\n\t\t\tm_context << Instruction::DUP2;\n\t\tm_context << Instruction::ADD;\n\t\tbreak;\n\tcase DataLocation::Storage:\n\t{\n\t\tif (_keepReference)\n\t\t\tm_context << Instruction::DUP2;\n\t\telse\n\t\t\tm_context << Instruction::SWAP1;\n\t\t// stack: [<base_ref>] <index> <base_ref>\n\n\t\tevmasm::AssemblyItem endTag = m_context.newTag();\n\t\tif (_arrayType.isByteArrayOrString())\n\t\t{\n\t\t\t// Special case of short byte arrays.\n\t\t\tm_context << Instruction::SWAP1;\n\t\t\tm_context << Instruction::DUP2 << Instruction::SLOAD;\n\t\t\tm_context << u256(1) << Instruction::AND << Instruction::ISZERO;\n\t\t\t// No action needed for short byte arrays.\n\t\t\tm_context.appendConditionalJumpTo(endTag);\n\t\t\tm_context << Instruction::SWAP1;\n\t\t}\n\t\tif (_arrayType.isDynamicallySized())\n\t\t\tCompilerUtils(m_context).computeHashStatic();\n\t\tm_context << Instruction::SWAP1;\n\t\tif (_arrayType.baseType()->storageBytes() <= 16)\n\t\t{\n\t\t\t// stack: <data_ref> <index>\n\t\t\t// goal:\n\t\t\t// <ref> <byte_number> = <base_ref + index / itemsPerSlot> <(index % itemsPerSlot) * byteSize>\n\t\t\tunsigned byteSize = _arrayType.baseType()->storageBytes();\n\t\t\tsolAssert(byteSize != 0, \"\");\n\t\t\tunsigned itemsPerSlot = 32 / byteSize;\n\t\t\tm_context << u256(itemsPerSlot) << Instruction::SWAP2;\n\t\t\t// stack: itemsPerSlot index data_ref\n\t\t\tm_context\n\t\t\t\t<< Instruction::DUP3 << Instruction::DUP3\n\t\t\t\t<< Instruction::DIV << Instruction::ADD\n\t\t\t// stack: itemsPerSlot index (data_ref + index / itemsPerSlot)\n\t\t\t\t<< Instruction::SWAP2 << Instruction::SWAP1\n\t\t\t\t<< Instruction::MOD;\n\t\t\tif (byteSize != 1)\n\t\t\t\tm_context << u256(byteSize) << Instruction::MUL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (_arrayType.baseType()->storageSize() != 1)\n\t\t\t\tm_context << _arrayType.baseType()->storageSize() << Instruction::MUL;\n\t\t\tm_context << Instruction::ADD << u256(0);\n\t\t}\n\t\tm_context << endTag;\n\t\tbreak;\n\t}\n\tcase DataLocation::Transient:\n\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\tbreak;\n\t}\n}\n\nvoid ArrayUtils::accessCallDataArrayElement(ArrayType const& _arrayType, bool _doBoundsCheck) const\n{\n\tsolAssert(_arrayType.location() == DataLocation::CallData, \"\");\n\tif (_arrayType.baseType()->isDynamicallyEncoded())\n\t{\n\t\t// stack layout: <base_ref> <length> <index>\n\t\tArrayUtils(m_context).accessIndex(_arrayType, _doBoundsCheck, true);\n\t\t// stack layout: <base_ref> <ptr_to_tail>\n\n\t\tCompilerUtils(m_context).accessCalldataTail(*_arrayType.baseType());\n\t\t// stack layout: <tail_ref> [length]\n\t}\n\telse\n\t{\n\t\tArrayUtils(m_context).accessIndex(_arrayType, _doBoundsCheck);\n\t\tif (_arrayType.baseType()->isValueType())\n\t\t{\n\t\t\tsolAssert(_arrayType.baseType()->storageBytes() <= 32, \"\");\n\t\t\tif (\n\t\t\t\t!_arrayType.isByteArrayOrString() &&\n\t\t\t\t_arrayType.baseType()->storageBytes() < 32 &&\n\t\t\t\tm_context.useABICoderV2()\n\t\t\t)\n\t\t\t{\n\t\t\t\tm_context << u256(32);\n\t\t\t\tCompilerUtils(m_context).abiDecodeV2({_arrayType.baseType()}, false);\n\t\t\t}\n\t\t\telse\n\t\t\t\tCompilerUtils(m_context).loadFromMemoryDynamic(\n\t\t\t\t\t*_arrayType.baseType(),\n\t\t\t\t\ttrue,\n\t\t\t\t\t!_arrayType.isByteArrayOrString(),\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t}\n\t\telse\n\t\t\tsolAssert(\n\t\t\t\t_arrayType.baseType()->category() == Type::Category::Struct ||\n\t\t\t\t_arrayType.baseType()->category() == Type::Category::Array,\n\t\t\t\t\"Invalid statically sized non-value base type on array access.\"\n\t\t\t);\n\t}\n}\n\nvoid ArrayUtils::incrementByteOffset(unsigned _byteSize, unsigned _byteOffsetPosition, unsigned _storageOffsetPosition) const\n{\n\tsolAssert(_byteSize < 32, \"\");\n\tsolAssert(_byteSize != 0, \"\");\n\t// We do the following, but avoiding jumps:\n\t// byteOffset += byteSize\n\t// if (byteOffset + byteSize > 32)\n\t// {\n\t//     storageOffset++;\n\t//     byteOffset = 0;\n\t// }\n\tif (_byteOffsetPosition > 1)\n\t\tm_context << swapInstruction(_byteOffsetPosition - 1);\n\tm_context << u256(_byteSize) << Instruction::ADD;\n\tif (_byteOffsetPosition > 1)\n\t\tm_context << swapInstruction(_byteOffsetPosition - 1);\n\t// compute, X := (byteOffset + byteSize - 1) / 32, should be 1 iff byteOffset + bytesize > 32\n\tm_context\n\t\t<< u256(32) << dupInstruction(1 + _byteOffsetPosition) << u256(_byteSize - 1)\n\t\t<< Instruction::ADD << Instruction::DIV;\n\t// increment storage offset if X == 1 (just add X to it)\n\t// stack: X\n\tm_context\n\t\t<< swapInstruction(_storageOffsetPosition) << dupInstruction(_storageOffsetPosition + 1)\n\t\t<< Instruction::ADD << swapInstruction(_storageOffsetPosition);\n\t// stack: X\n\t// set source_byte_offset to zero if X == 1 (using source_byte_offset *= 1 - X)\n\tm_context << u256(1) << Instruction::SUB;\n\t// stack: 1 - X\n\tif (_byteOffsetPosition == 1)\n\t\tm_context << Instruction::MUL;\n\telse\n\t\tm_context\n\t\t\t<< dupInstruction(_byteOffsetPosition + 1) << Instruction::MUL\n\t\t\t<< swapInstruction(_byteOffsetPosition) << Instruction::POP;\n}\n"
  },
  {
    "path": "libsolidity/codegen/ArrayUtils.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Code generation utils that handle arrays.\n */\n\n#pragma once\n\n#include <memory>\n\nnamespace solidity::frontend\n{\n\nclass CompilerContext;\nclass Type;\nclass ArrayType;\n\n/**\n * Class that provides code generation for handling arrays.\n */\nclass ArrayUtils\n{\npublic:\n\texplicit ArrayUtils(CompilerContext& _context): m_context(_context) {}\n\n\t/// Copies an array to an array in storage. The arrays can be of different types only if\n\t/// their storage representation is the same.\n\t/// Stack pre: source_reference [source_length] target_reference\n\t/// Stack post: target_reference\n\tvoid copyArrayToStorage(ArrayType const& _targetType, ArrayType const& _sourceType) const;\n\t/// Copies the data part of an array (which cannot be dynamically nested) from anywhere\n\t/// to a given position in memory.\n\t/// This always copies contained data as is (i.e. structs and fixed-size arrays are copied in\n\t/// place as required by the ABI encoding). Use CompilerUtils::convertType if you want real\n\t/// memory copies of nested arrays.\n\t/// Stack pre: memory_offset source_item\n\t/// Stack post: memory_offset + length(padded)\n\tvoid copyArrayToMemory(ArrayType const& _sourceType, bool _padToWordBoundaries = true) const;\n\t/// Clears the given dynamic or static array.\n\t/// Stack pre: storage_ref storage_byte_offset\n\t/// Stack post:\n\tvoid clearArray(ArrayType const& _type) const;\n\t/// Clears the length and data elements of the array referenced on the stack.\n\t/// Stack pre: reference (excludes byte offset)\n\t/// Stack post:\n\tvoid clearDynamicArray(ArrayType const& _type) const;\n\t/// Increments the size of a dynamic array by one.\n\t/// Does not touch the new data element. In case of a byte array, this might move the\n\t/// data.\n\t/// Stack pre: reference (excludes byte offset)\n\t/// Stack post: new_length\n\tvoid incrementDynamicArraySize(ArrayType const& _type) const;\n\t/// Decrements the size of a dynamic array by one if length is nonzero. Causes a Panic otherwise.\n\t/// Clears the removed data element. In case of a byte array, this might move the data.\n\t/// Stack pre: reference\n\t/// Stack post:\n\tvoid popStorageArrayElement(ArrayType const& _type) const;\n\t/// Appends a loop that clears a sequence of storage slots of the given type.\n\t/// Stack pre: start_ref slot_count\n\t/// Stack post:\n\tvoid clearStorageLoop(Type const* _type) const;\n\t/// Converts length to size (number of storage slots or calldata/memory bytes).\n\t/// if @a _pad then add padding to multiples of 32 bytes for calldata/memory.\n\t/// Stack pre: length\n\t/// Stack post: size\n\tvoid convertLengthToSize(ArrayType const& _arrayType, bool _pad = false) const;\n\t/// Retrieves the length (number of elements) of the array ref on the stack. This also\n\t/// works for statically-sized arrays.\n\t/// @param _stackDepth number of stack elements between top of stack and top (!) of reference\n\t/// Stack pre: reference (excludes byte offset for dynamic storage arrays)\n\t/// Stack post: reference length\n\tvoid retrieveLength(ArrayType const& _arrayType, unsigned _stackDepth = 0) const;\n\t/// Stores the length of an array of type @a _arrayType in storage. The length itself is stored\n\t/// on the stack at position @a _stackDepthLength and the storage reference at @a _stackDepthRef.\n\t/// If @a _arrayType is a byte array, takes tight coding into account.\n\tvoid storeLength(ArrayType const& _arrayType, unsigned _stackDepthLength = 0, unsigned _stackDepthRef = 1) const;\n\t/// Checks whether the index is out of range and returns the absolute offset of the element reference[index]\n\t/// (i.e. reference + index * size_of_base_type).\n\t/// If @a _keepReference is true, the base reference to the beginning of the array is kept on the stack.\n\t/// Stack pre: reference [length] index\n\t/// Stack post (storage): [reference] storage_slot byte_offset\n\t/// Stack post: [reference] memory/calldata_offset\n\tvoid accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck = true, bool _keepReference = false) const;\n\t/// Access calldata array's element and put it on stack.\n\t/// Stack pre: reference [length] index\n\t/// Stack post: value\n\tvoid accessCallDataArrayElement(ArrayType const& _arrayType, bool _doBoundsCheck = true) const;\n\nprivate:\n\t/// Adds the given number of bytes to a storage byte offset counter and also increments\n\t/// the storage offset if adding this number again would increase the counter over 32.\n\t/// @param byteOffsetPosition the stack offset of the storage byte offset\n\t/// @param storageOffsetPosition the stack offset of the storage slot offset\n\tvoid incrementByteOffset(unsigned _byteSize, unsigned _byteOffsetPosition, unsigned _storageOffsetPosition) const;\n\n\tCompilerContext& m_context;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/Compiler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity compiler.\n */\n\n#include <libsolidity/codegen/Compiler.h>\n\n#include <libsolidity/codegen/ContractCompiler.h>\n#include <libevmasm/Assembly.h>\n\n#include <range/v3/algorithm/none_of.hpp>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\n\nvoid Compiler::compileContract(\n\tContractDefinition const& _contract,\n\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers,\n\tbytes const& _metadata\n)\n{\n\tauto static isTransientReferenceType = [](VariableDeclaration const* _varDeclaration) {\n\t\tsolAssert(_varDeclaration && _varDeclaration->type());\n\t\treturn\n\t\t\t_varDeclaration->referenceLocation() == VariableDeclaration::Location::Transient &&\n\t\t\t!_varDeclaration->type()->isValueType();\n\t};\n\n\tsolUnimplementedAssert(\n\t\tranges::none_of(_contract.stateVariables(), isTransientReferenceType),\n\t\t\"Transient storage reference type variables are not supported.\"\n\t);\n\n\tContractCompiler runtimeCompiler(nullptr, m_runtimeContext, m_optimiserSettings);\n\truntimeCompiler.compileContract(_contract, _otherCompilers);\n\tm_runtimeContext.appendToAuxiliaryData(_metadata);\n\n\t// This might modify m_runtimeContext because it can access runtime functions at\n\t// creation time.\n\tOptimiserSettings creationSettings{m_optimiserSettings};\n\t// The creation code will be executed at most once, so we modify the optimizer\n\t// settings accordingly.\n\tcreationSettings.expectedExecutionsPerDeployment = 1;\n\tContractCompiler creationCompiler(&runtimeCompiler, m_context, creationSettings);\n\tm_runtimeSub = creationCompiler.compileConstructor(_contract, _otherCompilers);\n\n\tm_context.optimise(m_optimiserSettings);\n\n\tsolAssert(m_context.appendYulUtilityFunctionsRan(), \"appendYulUtilityFunctions() was not called.\");\n\tsolAssert(m_runtimeContext.appendYulUtilityFunctionsRan(), \"appendYulUtilityFunctions() was not called.\");\n}\n\nstd::shared_ptr<evmasm::Assembly> Compiler::runtimeAssemblyPtr() const\n{\n\tsolAssert(m_context.runtimeContext(), \"\");\n\treturn m_context.runtimeContext()->assemblyPtr();\n}\n"
  },
  {
    "path": "libsolidity/codegen/Compiler.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity AST to EVM bytecode compiler.\n */\n\n#pragma once\n\n#include <libsolidity/codegen/CompilerContext.h>\n#include <libsolidity/interface/OptimiserSettings.h>\n#include <libsolidity/interface/DebugSettings.h>\n#include <liblangutil/EVMVersion.h>\n#include <libevmasm/Assembly.h>\n#include <functional>\n#include <ostream>\n\nnamespace solidity::frontend\n{\n\nclass Compiler\n{\npublic:\n\tCompiler(\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tRevertStrings _revertStrings,\n\t\tOptimiserSettings _optimiserSettings\n\t):\n\t\tm_optimiserSettings(std::move(_optimiserSettings)),\n\t\tm_runtimeContext(_evmVersion, _eofVersion, _revertStrings),\n\t\tm_context(_evmVersion, _eofVersion, _revertStrings, &m_runtimeContext)\n\t{ }\n\n\t/// Compiles a contract.\n\t/// @arg _metadata contains the to be injected metadata CBOR\n\tvoid compileContract(\n\t\tContractDefinition const& _contract,\n\t\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers,\n\t\tbytes const& _metadata\n\t);\n\t/// @returns Entire assembly.\n\tevmasm::Assembly const& assembly() const { return m_context.assembly(); }\n\t/// @returns Runtime assembly.\n\tevmasm::Assembly const& runtimeAssembly() const { return m_context.assembly().sub(m_runtimeSub); }\n\t/// @returns Entire assembly as a shared pointer to non-const.\n\tstd::shared_ptr<evmasm::Assembly> assemblyPtr() const { return m_context.assemblyPtr(); }\n\t/// @returns Runtime assembly as a shared pointer.\n\tstd::shared_ptr<evmasm::Assembly> runtimeAssemblyPtr() const;\n\n\tstd::string generatedYulUtilityCode() const { return m_context.generatedYulUtilityCode(); }\n\tstd::string runtimeGeneratedYulUtilityCode() const { return m_runtimeContext.generatedYulUtilityCode(); }\n\nprivate:\n\tOptimiserSettings const m_optimiserSettings;\n\tCompilerContext m_runtimeContext;\n\tevmasm::SubAssemblyID m_runtimeSub{}; ///< Identifier of the runtime sub-assembly, if present.\n\tCompilerContext m_context;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/CompilerContext.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Utilities for the solidity compiler.\n */\n\n#include <libsolidity/codegen/CompilerContext.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/codegen/Compiler.h>\n#include <libsolidity/codegen/CompilerUtils.h>\n#include <libsolidity/interface/Version.h>\n\n#include <libyul/AST.h>\n#include <libyul/AsmParser.h>\n#include <libyul/AsmPrinter.h>\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/backends/evm/AsmCodeGen.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/backends/evm/EVMMetrics.h>\n#include <libyul/optimiser/Suite.h>\n#include <libyul/Object.h>\n#include <libyul/YulName.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/Whiskers.h>\n#include <libsolutil/FunctionSelector.h>\n#include <libsolutil/StackTooDeepString.h>\n\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/Scanner.h>\n#include <liblangutil/SourceReferenceFormatter.h>\n\n#include <utility>\n\n// Change to \"define\" to output all intermediate code\n#undef SOL_OUTPUT_ASM\n\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::evmasm;\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\n\nvoid CompilerContext::addStateVariable(\n\tVariableDeclaration const& _declaration,\n\tu256 const& _storageOffset,\n\tunsigned _byteOffset\n)\n{\n\tm_stateVariables[&_declaration] = std::make_pair(_storageOffset, _byteOffset);\n}\n\nvoid CompilerContext::addImmutable(VariableDeclaration const& _variable)\n{\n\tsolAssert(_variable.immutable(), \"Attempted to register a non-immutable variable as immutable.\");\n\tsolUnimplementedAssert(_variable.annotation().type->isValueType(), \"Only immutable variables of value type are supported.\");\n\tsolAssert(m_runtimeContext, \"Attempted to register an immutable variable for runtime code generation.\");\n\tm_immutableVariables[&_variable] = CompilerUtils::generalPurposeMemoryStart + *m_reservedMemory;\n\tsolAssert(_variable.annotation().type->memoryHeadSize() == 32, \"Memory writes might overlap.\");\n\t*m_reservedMemory += _variable.annotation().type->memoryHeadSize();\n}\n\nsize_t CompilerContext::immutableMemoryOffset(VariableDeclaration const& _variable) const\n{\n\tsolAssert(m_immutableVariables.count(&_variable), \"Memory offset of unknown immutable queried.\");\n\tsolAssert(m_runtimeContext, \"Attempted to fetch the memory offset of an immutable variable during runtime code generation.\");\n\treturn m_immutableVariables.at(&_variable);\n}\n\nstd::vector<std::string> CompilerContext::immutableVariableSlotNames(VariableDeclaration const& _variable)\n{\n\tstd::string baseName = std::to_string(_variable.id());\n\tsolAssert(_variable.annotation().type->sizeOnStack() > 0, \"\");\n\tif (_variable.annotation().type->sizeOnStack() == 1)\n\t\treturn {baseName};\n\tstd::vector<std::string> names;\n\tauto collectSlotNames = [&](std::string const& _baseName, Type const* type, auto const& _recurse) -> void {\n\t\tfor (auto const& [slot, type]: type->stackItems())\n\t\t\tif (type)\n\t\t\t\t_recurse(_baseName + \" \" + slot, type, _recurse);\n\t\t\telse\n\t\t\t\tnames.emplace_back(_baseName);\n\t};\n\tcollectSlotNames(baseName, _variable.annotation().type, collectSlotNames);\n\treturn names;\n}\n\nsize_t CompilerContext::reservedMemory()\n{\n\tsolAssert(m_reservedMemory.has_value(), \"Reserved memory was used before \");\n\tsize_t reservedMemory = *m_reservedMemory;\n\tm_reservedMemory = std::nullopt;\n\treturn reservedMemory;\n}\n\nvoid CompilerContext::startFunction(Declaration const& _function)\n{\n\tm_functionCompilationQueue.startFunction(_function);\n\t*this << functionEntryLabel(_function);\n}\n\nvoid CompilerContext::callLowLevelFunction(\n\tstd::string const& _name,\n\tunsigned _inArgs,\n\tunsigned _outArgs,\n\tstd::function<void(CompilerContext&)> const& _generator\n)\n{\n\tevmasm::AssemblyItem retTag = pushNewTag();\n\tCompilerUtils(*this).moveIntoStack(_inArgs);\n\n\t*this << lowLevelFunctionTag(_name, _inArgs, _outArgs, _generator);\n\n\tappendJump(evmasm::AssemblyItem::JumpType::IntoFunction);\n\tadjustStackOffset(static_cast<int>(_outArgs) - 1 - static_cast<int>(_inArgs));\n\t*this << retTag.tag();\n}\n\nvoid CompilerContext::callYulFunction(\n\tstd::string const& _name,\n\tunsigned _inArgs,\n\tunsigned _outArgs\n)\n{\n\tm_externallyUsedYulFunctions.insert(_name);\n\tauto const retTag = pushNewTag();\n\tCompilerUtils(*this).moveIntoStack(_inArgs);\n\tappendJumpTo(namedTag(_name, _inArgs, _outArgs, {}), evmasm::AssemblyItem::JumpType::IntoFunction);\n\tadjustStackOffset(static_cast<int>(_outArgs) - 1 - static_cast<int>(_inArgs));\n\t*this << retTag.tag();\n}\n\nevmasm::AssemblyItem CompilerContext::lowLevelFunctionTag(\n\tstd::string const& _name,\n\tunsigned _inArgs,\n\tunsigned _outArgs,\n\tstd::function<void(CompilerContext&)> const& _generator\n)\n{\n\tauto it = m_lowLevelFunctions.find(_name);\n\tif (it == m_lowLevelFunctions.end())\n\t{\n\t\tevmasm::AssemblyItem tag = newTag().pushTag();\n\t\tm_lowLevelFunctions.insert(make_pair(_name, tag));\n\t\tm_lowLevelFunctionGenerationQueue.push(make_tuple(_name, _inArgs, _outArgs, _generator));\n\t\treturn tag;\n\t}\n\telse\n\t\treturn it->second;\n}\n\nvoid CompilerContext::appendMissingLowLevelFunctions()\n{\n\twhile (!m_lowLevelFunctionGenerationQueue.empty())\n\t{\n\t\tstd::string name;\n\t\tunsigned inArgs;\n\t\tunsigned outArgs;\n\t\tstd::function<void(CompilerContext&)> generator;\n\t\ttie(name, inArgs, outArgs, generator) = m_lowLevelFunctionGenerationQueue.front();\n\t\tm_lowLevelFunctionGenerationQueue.pop();\n\n\t\tsetStackOffset(static_cast<int>(inArgs) + 1);\n\t\t*this << m_lowLevelFunctions.at(name).tag();\n\t\tgenerator(*this);\n\t\tCompilerUtils(*this).moveToStackTop(outArgs);\n\t\tappendJump(evmasm::AssemblyItem::JumpType::OutOfFunction);\n\t\tsolAssert(stackHeight() == outArgs, \"Invalid stack height in low-level function \" + name + \".\");\n\t}\n}\n\nvoid CompilerContext::appendYulUtilityFunctions(OptimiserSettings const& _optimiserSettings)\n{\n\tsolAssert(!m_appendYulUtilityFunctionsRan, \"requestedYulFunctions called more than once.\");\n\tm_appendYulUtilityFunctionsRan = true;\n\n\tstd::string code = m_yulFunctionCollector.requestedFunctions();\n\tif (!code.empty())\n\t{\n\t\tappendInlineAssembly(\n\t\t\tyul::reindent(\"{\\n\" + std::move(code) + \"\\n}\"),\n\t\t\t{},\n\t\t\tm_externallyUsedYulFunctions,\n\t\t\ttrue,\n\t\t\t_optimiserSettings,\n\t\t\tyulUtilityFileName()\n\t\t);\n\t\tsolAssert(!m_generatedYulUtilityCode.empty(), \"\");\n\t}\n}\n\nvoid CompilerContext::addVariable(\n\tVariableDeclaration const& _declaration,\n\tunsigned _offsetToCurrent\n)\n{\n\tsolAssert(m_asm->deposit() >= 0 && unsigned(m_asm->deposit()) >= _offsetToCurrent, \"\");\n\tunsigned sizeOnStack = _declaration.annotation().type->sizeOnStack();\n\t// Variables should not have stack size other than [1, 2],\n\t// but that might change when new types are introduced.\n\tsolAssert(sizeOnStack == 1 || sizeOnStack == 2, \"\");\n\tm_localVariables[&_declaration].push_back(unsigned(m_asm->deposit()) - _offsetToCurrent);\n}\n\nvoid CompilerContext::removeVariable(Declaration const& _declaration)\n{\n\tsolAssert(m_localVariables.count(&_declaration) && !m_localVariables[&_declaration].empty(), \"\");\n\tm_localVariables[&_declaration].pop_back();\n\tif (m_localVariables[&_declaration].empty())\n\t\tm_localVariables.erase(&_declaration);\n}\n\nvoid CompilerContext::removeVariablesAboveStackHeight(unsigned _stackHeight)\n{\n\tstd::vector<Declaration const*> toRemove;\n\tfor (auto _var: m_localVariables)\n\t{\n\t\tsolAssert(!_var.second.empty(), \"\");\n\t\tsolAssert(_var.second.back() <= stackHeight(), \"\");\n\t\tif (_var.second.back() >= _stackHeight)\n\t\t\ttoRemove.push_back(_var.first);\n\t}\n\tfor (auto _var: toRemove)\n\t\tremoveVariable(*_var);\n}\n\nunsigned CompilerContext::numberOfLocalVariables() const\n{\n\treturn static_cast<unsigned>(m_localVariables.size());\n}\n\nstd::shared_ptr<evmasm::Assembly> CompilerContext::compiledContract(ContractDefinition const& _contract) const\n{\n\tauto ret = m_otherCompilers.find(&_contract);\n\tsolAssert(ret != m_otherCompilers.end(), \"Compiled contract not found.\");\n\treturn ret->second->assemblyPtr();\n}\n\nstd::shared_ptr<evmasm::Assembly> CompilerContext::compiledContractRuntime(ContractDefinition const& _contract) const\n{\n\tauto ret = m_otherCompilers.find(&_contract);\n\tsolAssert(ret != m_otherCompilers.end(), \"Compiled contract not found.\");\n\treturn ret->second->runtimeAssemblyPtr();\n}\n\nbool CompilerContext::isLocalVariable(Declaration const* _declaration) const\n{\n\treturn !!m_localVariables.count(_declaration);\n}\n\nevmasm::AssemblyItem CompilerContext::functionEntryLabel(Declaration const& _declaration)\n{\n\treturn m_functionCompilationQueue.entryLabel(_declaration, *this);\n}\n\nevmasm::AssemblyItem CompilerContext::functionEntryLabelIfExists(Declaration const& _declaration) const\n{\n\treturn m_functionCompilationQueue.entryLabelIfExists(_declaration);\n}\n\nFunctionDefinition const& CompilerContext::superFunction(FunctionDefinition const& _function, ContractDefinition const& _base)\n{\n\tsolAssert(m_mostDerivedContract, \"No most derived contract set.\");\n\tContractDefinition const* super = _base.superContract(mostDerivedContract());\n\tsolAssert(super, \"Super contract not available.\");\n\n\tFunctionDefinition const& resolvedFunction = _function.resolveVirtual(mostDerivedContract(), super);\n\tsolAssert(resolvedFunction.isImplemented(), \"\");\n\n\treturn resolvedFunction;\n}\n\nContractDefinition const& CompilerContext::mostDerivedContract() const\n{\n\tsolAssert(m_mostDerivedContract, \"Most derived contract not set.\");\n\treturn *m_mostDerivedContract;\n}\n\nDeclaration const* CompilerContext::nextFunctionToCompile() const\n{\n\treturn m_functionCompilationQueue.nextFunctionToCompile();\n}\n\nunsigned CompilerContext::baseStackOffsetOfVariable(Declaration const& _declaration) const\n{\n\tauto res = m_localVariables.find(&_declaration);\n\tsolAssert(res != m_localVariables.end(), \"Variable not found on stack.\");\n\tsolAssert(!res->second.empty(), \"\");\n\treturn res->second.back();\n}\n\nunsigned CompilerContext::baseToCurrentStackOffset(unsigned _baseOffset) const\n{\n\treturn static_cast<unsigned>(m_asm->deposit()) - _baseOffset - 1;\n}\n\nunsigned CompilerContext::currentToBaseStackOffset(unsigned _offset) const\n{\n\treturn static_cast<unsigned>(m_asm->deposit()) - _offset - 1;\n}\n\nstd::pair<u256, unsigned> CompilerContext::storageLocationOfVariable(Declaration const& _declaration) const\n{\n\tauto it = m_stateVariables.find(&_declaration);\n\tsolAssert(it != m_stateVariables.end(), \"Variable not found in storage.\");\n\treturn it->second;\n}\n\nCompilerContext& CompilerContext::appendJump(evmasm::AssemblyItem::JumpType _jumpType)\n{\n\tevmasm::AssemblyItem item(Instruction::JUMP);\n\titem.setJumpType(_jumpType);\n\treturn *this << item;\n}\n\nCompilerContext& CompilerContext::appendPanic(util::PanicCode _code)\n{\n\tcallYulFunction(utilFunctions().panicFunction(_code), 0, 0);\n\treturn *this;\n}\n\nCompilerContext& CompilerContext::appendConditionalPanic(util::PanicCode _code)\n{\n\t*this << Instruction::ISZERO;\n\tevmasm::AssemblyItem afterTag = appendConditionalJump();\n\tappendPanic(_code);\n\t*this << afterTag;\n\treturn *this;\n}\n\nCompilerContext& CompilerContext::appendRevert(std::string const& _message)\n{\n\tappendInlineAssembly(\"{ \" + revertReasonIfDebug(_message) + \" }\");\n\treturn *this;\n}\n\nCompilerContext& CompilerContext::appendConditionalRevert(bool _forwardReturnData, std::string const& _message)\n{\n\tif (_forwardReturnData && m_evmVersion.supportsReturndata())\n\t\tappendInlineAssembly(R\"({\n\t\t\tif condition {\n\t\t\t\treturndatacopy(0, 0, returndatasize())\n\t\t\t\trevert(0, returndatasize())\n\t\t\t}\n\t\t})\", {\"condition\"});\n\telse\n\t\tappendInlineAssembly(\"{ if condition { \" + revertReasonIfDebug(_message) + \" } }\", {\"condition\"});\n\t*this << Instruction::POP;\n\treturn *this;\n}\n\nvoid CompilerContext::resetVisitedNodes(ASTNode const* _node)\n{\n\tstd::stack<ASTNode const*> newStack;\n\tnewStack.push(_node);\n\tstd::swap(m_visitedNodes, newStack);\n\tupdateSourceLocation();\n}\n\nvoid CompilerContext::appendInlineAssembly(\n\tstd::string const& _assembly,\n\tstd::vector<std::string> const& _localVariables,\n\tstd::set<std::string> const& _externallyUsedFunctions,\n\tbool _system,\n\tOptimiserSettings const& _optimiserSettings,\n\tstd::string _sourceName\n)\n{\n\tunsigned startStackHeight = stackHeight();\n\n\tstd::set<yul::YulName> externallyUsedIdentifiers;\n\tfor (auto const& fun: _externallyUsedFunctions)\n\t\texternallyUsedIdentifiers.insert(yul::YulName(fun));\n\tfor (auto const& var: _localVariables)\n\t\texternallyUsedIdentifiers.insert(yul::YulName(var));\n\n\tyul::ExternalIdentifierAccess identifierAccess;\n\tidentifierAccess.resolve = [&](\n\t\tyul::Identifier const& _identifier,\n\t\tyul::IdentifierContext,\n\t\tbool _insideFunction\n\t) -> bool\n\t{\n\t\tif (_insideFunction)\n\t\t\treturn false;\n\t\treturn util::contains(_localVariables, _identifier.name.str());\n\t};\n\tidentifierAccess.generateCode = [&](\n\t\tyul::Identifier const& _identifier,\n\t\tyul::IdentifierContext _context,\n\t\tyul::AbstractAssembly& _assembly\n\t)\n\t{\n\t\tsolAssert(_context == yul::IdentifierContext::RValue || _context == yul::IdentifierContext::LValue, \"\");\n\t\tauto it = std::find(_localVariables.begin(), _localVariables.end(), _identifier.name.str());\n\t\tsolAssert(it != _localVariables.end(), \"\");\n\t\tauto stackDepth = static_cast<size_t>(distance(it, _localVariables.end()));\n\t\tsize_t stackDiff = static_cast<size_t>(_assembly.stackHeight()) - startStackHeight + stackDepth;\n\t\tif (_context == yul::IdentifierContext::LValue)\n\t\t\tstackDiff -= 1;\n\t\tif (stackDiff < 1 || stackDiff > reachableStackDepth())\n\t\t\tBOOST_THROW_EXCEPTION(\n\t\t\t\tStackTooDeepError() <<\n\t\t\t\terrinfo_sourceLocation(nativeLocationOf(_identifier)) <<\n\t\t\t\tutil::errinfo_comment(util::stackTooDeepString)\n\t\t\t);\n\t\tif (_context == yul::IdentifierContext::RValue)\n\t\t\t_assembly.appendInstruction(dupInstruction(static_cast<unsigned>(stackDiff)));\n\t\telse\n\t\t{\n\t\t\t_assembly.appendInstruction(swapInstruction(static_cast<unsigned>(stackDiff)));\n\t\t\t_assembly.appendInstruction(Instruction::POP);\n\t\t}\n\t};\n\n\tErrorList errors;\n\tErrorReporter errorReporter(errors);\n\tlangutil::CharStream charStream(_assembly, _sourceName);\n\tyul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion, std::nullopt);\n\tstd::optional<langutil::SourceLocation> locationOverride;\n\tif (!_system)\n\t\tlocationOverride = m_asm->currentSourceLocation();\n\tstd::shared_ptr<yul::AST> parserResult =\n\t\tyul::Parser(errorReporter, dialect, std::move(locationOverride))\n\t\t.parse(charStream);\n#ifdef SOL_OUTPUT_ASM\n\tstd::cout << yul::AsmPrinter::format(*parserResult) << std::endl;\n#endif\n\n\tauto reportError = [&](std::string const& _context)\n\t{\n\t\tstd::string message =\n\t\t\t\"Error parsing/analyzing inline assembly block:\\n\" +\n\t\t\t_context + \"\\n\"\n\t\t\t\"------------------ Input: -----------------\\n\" +\n\t\t\t_assembly + \"\\n\"\n\t\t\t\"------------------ Errors: ----------------\\n\";\n\t\tfor (auto const& error: errorReporter.errors())\n\t\t\t// TODO if we have \"locationOverride\", it will be the wrong char stream,\n\t\t\t// but we do not have access to the solidity scanner.\n\t\t\tmessage += SourceReferenceFormatter::formatErrorInformation(*error, charStream);\n\t\tmessage += \"-------------------------------------------\\n\";\n\n\t\tsolAssert(false, message);\n\t};\n\n\tyul::AsmAnalysisInfo analysisInfo;\n\tbool analyzerResult = false;\n\tif (parserResult)\n\t\tanalyzerResult = yul::AsmAnalyzer(\n\t\t\tanalysisInfo,\n\t\t\terrorReporter,\n\t\t\tdialect,\n\t\t\tidentifierAccess.resolve\n\t\t).analyze(parserResult->root());\n\tif (!parserResult || errorReporter.hasErrorsWarningsOrInfos() || !analyzerResult)\n\t\treportError(\"Invalid assembly generated by code generator.\");\n\tstd::shared_ptr<yul::AST const> toBeAssembledAST = parserResult;\n\n\t// Several optimizer steps cannot handle externally supplied stack variables,\n\t// so we essentially only optimize the ABI functions.\n\tif (_optimiserSettings.runYulOptimiser && _localVariables.empty())\n\t{\n\t\tyul::Object obj;\n\t\tobj.setCode(parserResult, std::make_shared<yul::AsmAnalysisInfo>(analysisInfo));\n\n\t\tsolAssert(!dialect.providesObjectAccess());\n\t\toptimizeYul(obj, _optimiserSettings, externallyUsedIdentifiers);\n\n\t\tif (_system)\n\t\t{\n\t\t\t// Store as generated sources, but first re-parse to update the source references.\n\t\t\tsolAssert(m_generatedYulUtilityCode.empty(), \"\");\n\t\t\tm_generatedYulUtilityCode = yul::AsmPrinter::format(*obj.code());\n\t\t\tlangutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName);\n\t\t\tobj.setCode(yul::Parser(errorReporter, dialect).parse(charStream));\n\t\t\tobj.analysisInfo = std::make_shared<yul::AsmAnalysisInfo>(yul::AsmAnalyzer::analyzeStrictAssertCorrect(obj));\n\t\t}\n\n\t\tanalysisInfo = std::move(*obj.analysisInfo);\n\t\ttoBeAssembledAST = obj.code();\n\n#ifdef SOL_OUTPUT_ASM\n\t\tstd::cout << \"After optimizer:\" << std::endl;\n\t\tstd::cout << yul::AsmPrinter::format(*parserResult) << std::endl;\n#endif\n\t}\n\telse if (_system)\n\t{\n\t\t// Store as generated source.\n\t\tsolAssert(m_generatedYulUtilityCode.empty(), \"\");\n\t\tm_generatedYulUtilityCode = _assembly;\n\t}\n\n\tif (errorReporter.hasErrorsWarningsOrInfos())\n\t\treportError(\"Failed to analyze inline assembly block.\");\n\n\tsolAssert(!errorReporter.hasErrorsWarningsOrInfos(), \"Failed to analyze inline assembly block.\");\n\tyul::CodeGenerator::assemble(\n\t\ttoBeAssembledAST->root(),\n\t\tanalysisInfo,\n\t\t*m_asm,\n\t\tm_evmVersion,\n\t\tstd::nullopt,\n\t\tidentifierAccess.generateCode,\n\t\t_system,\n\t\t_optimiserSettings.optimizeStackAllocation\n\t);\n\n\t// Reset the source location to the one of the node (instead of the CODEGEN source location)\n\tupdateSourceLocation();\n}\n\n\nvoid CompilerContext::optimizeYul(yul::Object& _object, OptimiserSettings const& _optimiserSettings, std::set<yul::YulName> const& _externalIdentifiers)\n{\n\tyulAssert(_object.dialect());\n\tauto const* evmDialect = dynamic_cast<yul::EVMDialect const*>(_object.dialect());\n\tyulAssert(evmDialect);\n#ifdef SOL_OUTPUT_ASM\n\tstd::cout << yul::AsmPrinter::format(*_object.code()) << std::endl;\n#endif\n\n\tbool const isCreation = runtimeContext() != nullptr;\n\tyul::GasMeter meter(*evmDialect, isCreation, _optimiserSettings.expectedExecutionsPerDeployment);\n\tyul::OptimiserSuite::run(\n\t\t&meter,\n\t\t_object,\n\t\t_optimiserSettings.optimizeStackAllocation,\n\t\t_optimiserSettings.yulOptimiserSteps,\n\t\t_optimiserSettings.yulOptimiserCleanupSteps,\n\t\tisCreation? std::nullopt : std::make_optional(_optimiserSettings.expectedExecutionsPerDeployment),\n\t\t_externalIdentifiers\n\t);\n\n#ifdef SOL_OUTPUT_ASM\n\tstd::cout << \"After optimizer:\" << std::endl;\n\tstd::cout << yul::AsmPrinter::format(*_object.code()) << std::endl;\n#endif\n}\n\nstd::string CompilerContext::revertReasonIfDebug(std::string const& _message)\n{\n\treturn YulUtilFunctions::revertReasonIfDebugBody(\n\t\tm_revertStrings,\n\t\t\"mload(\" + std::to_string(CompilerUtils::freeMemoryPointer) + \")\",\n\t\t_message\n\t);\n}\n\nvoid CompilerContext::updateSourceLocation()\n{\n\tm_asm->setSourceLocation(m_visitedNodes.empty() ? SourceLocation() : m_visitedNodes.top()->location());\n}\n\nevmasm::AssemblyItem CompilerContext::FunctionCompilationQueue::entryLabel(\n\tDeclaration const& _declaration,\n\tCompilerContext& _context\n)\n{\n\tauto res = m_entryLabels.find(&_declaration);\n\tif (res == m_entryLabels.end())\n\t{\n\t\tsize_t params = 0;\n\t\tsize_t returns = 0;\n\t\tif (auto const* function = dynamic_cast<FunctionDefinition const*>(&_declaration))\n\t\t{\n\t\t\tFunctionType functionType(*function, FunctionType::Kind::Internal);\n\t\t\tparams = CompilerUtils::sizeOnStack(functionType.parameterTypes());\n\t\t\treturns = CompilerUtils::sizeOnStack(functionType.returnParameterTypes());\n\t\t}\n\n\t\t// some name that cannot clash with yul function names.\n\t\tstd::string labelName = \"@\" + _declaration.name() + \"_\" + std::to_string(_declaration.id());\n\t\tevmasm::AssemblyItem tag = _context.namedTag(\n\t\t\tlabelName,\n\t\t\tparams,\n\t\t\treturns,\n\t\t\t_declaration.id()\n\t\t);\n\t\tm_entryLabels.insert(std::make_pair(&_declaration, tag));\n\t\tm_functionsToCompile.push(&_declaration);\n\t\treturn tag.tag();\n\t}\n\telse\n\t\treturn res->second.tag();\n\n}\n\nevmasm::AssemblyItem CompilerContext::FunctionCompilationQueue::entryLabelIfExists(Declaration const& _declaration) const\n{\n\tauto res = m_entryLabels.find(&_declaration);\n\treturn res == m_entryLabels.end() ? evmasm::AssemblyItem(evmasm::UndefinedItem) : res->second.tag();\n}\n\nDeclaration const* CompilerContext::FunctionCompilationQueue::nextFunctionToCompile() const\n{\n\twhile (!m_functionsToCompile.empty())\n\t{\n\t\tif (m_alreadyCompiledFunctions.count(m_functionsToCompile.front()))\n\t\t\tm_functionsToCompile.pop();\n\t\telse\n\t\t\treturn m_functionsToCompile.front();\n\t}\n\treturn nullptr;\n}\n\nvoid CompilerContext::FunctionCompilationQueue::startFunction(Declaration const& _function)\n{\n\tif (!m_functionsToCompile.empty() && m_functionsToCompile.front() == &_function)\n\t\tm_functionsToCompile.pop();\n\tm_alreadyCompiledFunctions.insert(&_function);\n}\n"
  },
  {
    "path": "libsolidity/codegen/CompilerContext.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Utilities for the solidity compiler.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/Types.h>\n#include <libsolidity/codegen/ABIFunctions.h>\n\n#include <libsolidity/interface/DebugSettings.h>\n#include <libsolidity/interface/OptimiserSettings.h>\n\n#include <libevmasm/Assembly.h>\n#include <libevmasm/Instruction.h>\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/EVMVersion.h>\n#include <libsolutil/Common.h>\n#include <libsolutil/ErrorCodes.h>\n\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <functional>\n#include <ostream>\n#include <stack>\n#include <queue>\n#include <utility>\n#include <limits>\n\nnamespace solidity::frontend\n{\n\nclass Compiler;\n\n/**\n * Context to be shared by all units that compile the same contract.\n * It stores the generated bytecode and the position of identifiers in memory and on the stack.\n */\nclass CompilerContext\n{\npublic:\n\texplicit CompilerContext(\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tRevertStrings _revertStrings,\n\t\tCompilerContext* _runtimeContext = nullptr\n\t):\n\t\tm_asm(std::make_shared<evmasm::Assembly>(_evmVersion, _runtimeContext != nullptr, std::nullopt, std::string{})),\n\t\tm_evmVersion(_evmVersion),\n\t\tm_revertStrings(_revertStrings),\n\t\tm_reservedMemory{0},\n\t\tm_runtimeContext(_runtimeContext),\n\t\tm_abiFunctions(m_evmVersion, _eofVersion, m_revertStrings, m_yulFunctionCollector),\n\t\tm_yulUtilFunctions(m_evmVersion, _eofVersion, m_revertStrings, m_yulFunctionCollector)\n\t{\n\t\tif (m_runtimeContext)\n\t\t\tm_runtimeSub = evmasm::SubAssemblyID{m_asm->newSub(m_runtimeContext->m_asm).data()};\n\t}\n\n\tlangutil::EVMVersion const& evmVersion() const { return m_evmVersion; }\n\n\tvoid setUseABICoderV2(bool _value) { m_useABICoderV2 = _value; }\n\tbool useABICoderV2() const { return m_useABICoderV2; }\n\n\tvoid addStateVariable(VariableDeclaration const& _declaration, u256 const& _storageOffset, unsigned _byteOffset);\n\tvoid addImmutable(VariableDeclaration const& _declaration);\n\n\t/// @returns the reserved memory for storing the value of the immutable @a _variable during contract creation.\n\tsize_t immutableMemoryOffset(VariableDeclaration const& _variable) const;\n\t/// @returns a list of slot names referring to the stack slots of an immutable variable.\n\tstatic std::vector<std::string> immutableVariableSlotNames(VariableDeclaration const& _variable);\n\n\t/// @returns the reserved memory and resets it to mark it as used.\n\tsize_t reservedMemory();\n\n\tvoid addVariable(VariableDeclaration const& _declaration, unsigned _offsetToCurrent = 0);\n\tvoid removeVariable(Declaration const& _declaration);\n\t/// Removes all local variables currently allocated above _stackHeight.\n\tvoid removeVariablesAboveStackHeight(unsigned _stackHeight);\n\t/// Returns the number of currently allocated local variables.\n\tunsigned numberOfLocalVariables() const;\n\n\tvoid setOtherCompilers(std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers) { m_otherCompilers = _otherCompilers; }\n\tstd::shared_ptr<evmasm::Assembly> compiledContract(ContractDefinition const& _contract) const;\n\tstd::shared_ptr<evmasm::Assembly> compiledContractRuntime(ContractDefinition const& _contract) const;\n\n\tvoid setStackOffset(int _offset) { m_asm->setDeposit(_offset); }\n\tvoid adjustStackOffset(int _adjustment) { m_asm->adjustDeposit(_adjustment); }\n\tunsigned stackHeight() const { solAssert(m_asm->deposit() >= 0, \"\"); return unsigned(m_asm->deposit()); }\n\tsize_t reachableStackDepth() const { return m_evmVersion.reachableStackDepth(); }\n\n\tbool isLocalVariable(Declaration const* _declaration) const;\n\tbool isStateVariable(Declaration const* _declaration) const { return m_stateVariables.count(_declaration) != 0; }\n\n\t/// @returns the entry label of the given function and creates it if it does not exist yet.\n\tevmasm::AssemblyItem functionEntryLabel(Declaration const& _declaration);\n\t/// @returns the entry label of the given function. Might return an AssemblyItem of type\n\t/// UndefinedItem if it does not exist yet.\n\tevmasm::AssemblyItem functionEntryLabelIfExists(Declaration const& _declaration) const;\n\t/// @returns the function that overrides the given declaration from the most derived class just\n\t/// above _base in the current inheritance hierarchy.\n\tFunctionDefinition const& superFunction(FunctionDefinition const& _function, ContractDefinition const& _base);\n\t/// Sets the contract currently being compiled - the most derived one.\n\tvoid setMostDerivedContract(ContractDefinition const& _contract) { m_mostDerivedContract = &_contract; }\n\tContractDefinition const& mostDerivedContract() const;\n\n\tvoid setArithmetic(Arithmetic _value) { m_arithmetic = _value; }\n\tArithmetic arithmetic() const { return m_arithmetic; }\n\n\t/// @returns the next function in the queue of functions that are still to be compiled\n\t/// (i.e. that were referenced during compilation but where we did not yet generate code for).\n\t/// Returns nullptr if the queue is empty. Does not remove the function from the queue,\n\t/// that will only be done by startFunction below.\n\tDeclaration const* nextFunctionToCompile() const;\n\t/// Resets function specific members, inserts the function entry label and marks the function\n\t/// as \"having code\".\n\tvoid startFunction(Declaration const& _function);\n\n\t/// Appends a call to the named low-level function and inserts the generator into the\n\t/// list of low-level-functions to be generated, unless it already exists.\n\t/// Note that the generator should not assume that objects are still alive when it is called,\n\t/// unless they are guaranteed to be alive for the whole run of the compiler (AST nodes, for example).\n\tvoid callLowLevelFunction(\n\t\tstd::string const& _name,\n\t\tunsigned _inArgs,\n\t\tunsigned _outArgs,\n\t\tstd::function<void(CompilerContext&)> const& _generator\n\t);\n\n\t/// Appends a call to a yul function and registers the function as externally used.\n\tvoid callYulFunction(\n\t\tstd::string const& _name,\n\t\tunsigned _inArgs,\n\t\tunsigned _outArgs\n\t);\n\n\t/// Returns the tag of the named low-level function and inserts the generator into the\n\t/// list of low-level-functions to be generated, unless it already exists.\n\t/// Note that the generator should not assume that objects are still alive when it is called,\n\t/// unless they are guaranteed to be alive for the whole run of the compiler (AST nodes, for example).\n\tevmasm::AssemblyItem lowLevelFunctionTag(\n\t\tstd::string const& _name,\n\t\tunsigned _inArgs,\n\t\tunsigned _outArgs,\n\t\tstd::function<void(CompilerContext&)> const& _generator\n\t);\n\t/// Generates the code for missing low-level functions, i.e. calls the generators passed above.\n\tvoid appendMissingLowLevelFunctions();\n\tABIFunctions& abiFunctions() { return m_abiFunctions; }\n\tYulUtilFunctions& utilFunctions() { return m_yulUtilFunctions; }\n\n\t/// Appends concatenation of all generated Yul functions to the bytecode\n\t/// and stores the Yul source code to be returned by @a generatedYulUtilityCode.\n\t/// Should be called exactly once on each context.\n\tvoid appendYulUtilityFunctions(OptimiserSettings const& _optimiserSettings);\n\tbool appendYulUtilityFunctionsRan() const { return m_appendYulUtilityFunctionsRan; }\n\tstd::string const& generatedYulUtilityCode() const { return m_generatedYulUtilityCode; }\n\tstatic std::string yulUtilityFileName() { return \"#utility.yul\"; }\n\n\t/// Returns the distance of the given local variable from the bottom of the stack (of the current function).\n\tunsigned baseStackOffsetOfVariable(Declaration const& _declaration) const;\n\t/// If supplied by a value returned by @ref baseStackOffsetOfVariable(variable), returns\n\t/// the distance of that variable from the current top of the stack.\n\tunsigned baseToCurrentStackOffset(unsigned _baseOffset) const;\n\t/// Converts an offset relative to the current stack height to a value that can be used later\n\t/// with baseToCurrentStackOffset to point to the same stack element.\n\tunsigned currentToBaseStackOffset(unsigned _offset) const;\n\t/// @returns pair of slot and byte offset of the value inside this slot.\n\tstd::pair<u256, unsigned> storageLocationOfVariable(Declaration const& _declaration) const;\n\n\t/// Appends a JUMPI instruction to a new tag and @returns the tag\n\tevmasm::AssemblyItem appendConditionalJump() { return m_asm->appendJumpI().tag(); }\n\t/// Appends a JUMPI instruction to @a _tag\n\tCompilerContext& appendConditionalJumpTo(evmasm::AssemblyItem const& _tag) { m_asm->appendJumpI(_tag); return *this; }\n\t/// Appends a JUMP to a new tag and @returns the tag\n\tevmasm::AssemblyItem appendJumpToNew() { return m_asm->appendJump().tag(); }\n\t/// Appends a JUMP to a tag already on the stack\n\tCompilerContext& appendJump(evmasm::AssemblyItem::JumpType _jumpType = evmasm::AssemblyItem::JumpType::Ordinary);\n\t/// Appends code to revert with a Panic(uint256) error.\n\tCompilerContext& appendPanic(util::PanicCode _code);\n\t/// Appends code to revert with a Panic(uint256) error if the topmost stack element is nonzero.\n\tCompilerContext& appendConditionalPanic(util::PanicCode _code);\n\t/// Appends a REVERT(0, 0) call\n\t/// @param _message is an optional revert message used in debug mode\n\tCompilerContext& appendRevert(std::string const& _message = \"\");\n\t/// Appends a conditional REVERT-call, either forwarding the RETURNDATA or providing the\n\t/// empty string. Consumes the condition.\n\t/// If the current EVM version does not support RETURNDATA, uses REVERT but does not forward\n\t/// the data.\n\t/// @param _message is an optional revert message used in debug mode\n\tCompilerContext& appendConditionalRevert(bool _forwardReturnData = false, std::string const& _message = \"\");\n\t/// Appends a JUMP to a specific tag\n\tCompilerContext& appendJumpTo(\n\t\tevmasm::AssemblyItem const& _tag,\n\t\tevmasm::AssemblyItem::JumpType _jumpType = evmasm::AssemblyItem::JumpType::Ordinary\n\t) { *m_asm << _tag.pushTag(); return appendJump(_jumpType); }\n\t/// Appends pushing of a new tag and @returns the new tag.\n\tevmasm::AssemblyItem pushNewTag() { return m_asm->append(m_asm->newPushTag()).tag(); }\n\t/// @returns a new tag without pushing any opcodes or data\n\tevmasm::AssemblyItem newTag() { return m_asm->newTag(); }\n\t/// @returns a new tag identified by name.\n\tevmasm::AssemblyItem namedTag(std::string const& _name, size_t _params, size_t _returns, std::optional<uint64_t> _sourceID)\n\t{\n\t\treturn m_asm->namedTag(_name, _params, _returns, _sourceID);\n\t}\n\t/// Adds a subroutine to the code (in the data section) and pushes its size (via a tag)\n\t/// on the stack. @returns the pushsub assembly item.\n\tevmasm::AssemblyItem addSubroutine(evmasm::AssemblyPointer const& _assembly) { return m_asm->appendSubroutine(_assembly); }\n\t/// Pushes the size of the subroutine.\n\tvoid pushSubroutineSize(evmasm::SubAssemblyID _subRoutine) { m_asm->pushSubroutineSize(_subRoutine); }\n\t/// Pushes the offset of the subroutine.\n\tvoid pushSubroutineOffset(evmasm::SubAssemblyID _subRoutine) { m_asm->pushSubroutineOffset(_subRoutine); }\n\t/// Pushes the size of the final program\n\tvoid appendProgramSize() { m_asm->appendProgramSize(); }\n\t/// Adds data to the data section, pushes a reference to the stack\n\tevmasm::AssemblyItem appendData(bytes const& _data) { return m_asm->append(_data); }\n\t/// Appends the address (virtual, will be filled in by linker) of a library.\n\tvoid appendLibraryAddress(std::string const& _identifier) { m_asm->appendLibraryAddress(_identifier); }\n\t/// Appends an immutable variable. The value will be filled in by the constructor.\n\tvoid appendImmutable(std::string const& _identifier) { m_asm->appendImmutable(_identifier); }\n\t/// Appends an assignment to an immutable variable. Only valid in creation code.\n\tvoid appendImmutableAssignment(std::string const& _identifier) { m_asm->appendImmutableAssignment(_identifier); }\n\t/// Appends a zero-address that can be replaced by something else at deploy time (if the\n\t/// position in bytecode is known).\n\tvoid appendDeployTimeAddress() { m_asm->append(evmasm::PushDeployTimeAddress); }\n\t/// Resets the stack of visited nodes with a new stack having only @c _node\n\tvoid resetVisitedNodes(ASTNode const* _node);\n\t/// Pops the stack of visited nodes\n\tvoid popVisitedNodes() { m_visitedNodes.pop(); updateSourceLocation(); }\n\t/// Pushes an ASTNode to the stack of visited nodes\n\tvoid pushVisitedNodes(ASTNode const* _node) { m_visitedNodes.push(_node); updateSourceLocation(); }\n\n\t/// Append elements to the current instruction list and adjust @a m_stackOffset.\n\tCompilerContext& operator<<(evmasm::AssemblyItem const& _item) { m_asm->append(_item); return *this; }\n\tCompilerContext& operator<<(evmasm::Instruction _instruction) { m_asm->append(_instruction); return *this; }\n\tCompilerContext& operator<<(u256 const& _value) { m_asm->append(_value); return *this; }\n\tCompilerContext& operator<<(bytes const& _data) { m_asm->append(_data); return *this; }\n\n\t/// Appends inline assembly (strict-EVM dialect for the current version).\n\t/// @param _assembly the assembly text, should be a block.\n\t/// @param _localVariables assigns stack positions to variables with the last one being the stack top\n\t/// @param _externallyUsedFunctions a set of function names that are not to be renamed or removed.\n\t/// @param _system if true, this is a \"system-level\" assembly where all functions use named labels\n\t///                and the code is marked to be exported as \"compiler-generated assembly utility file\".\n\t/// @param _optimiserSettings settings for the Yul optimiser, which is run in this function already.\n\t/// @param _sourceName the name of the assembly file to be used for source locations\n\tvoid appendInlineAssembly(\n\t\tstd::string const& _assembly,\n\t\tstd::vector<std::string> const& _localVariables = std::vector<std::string>(),\n\t\tstd::set<std::string> const& _externallyUsedFunctions = std::set<std::string>(),\n\t\tbool _system = false,\n\t\tOptimiserSettings const& _optimiserSettings = OptimiserSettings::none(),\n\t\tstd::string _sourceName = \"--CODEGEN--\"\n\t);\n\n\t/// If m_revertStrings is debug, @returns inline assembly code that\n\t/// stores @param _message at the free memory pointer and reverts.\n\t/// Otherwise returns \"revert(0, 0)\".\n\tstd::string revertReasonIfDebug(std::string const& _message = \"\");\n\n\tvoid optimizeYul(yul::Object& _object, OptimiserSettings const& _optimiserSetting, std::set<yul::YulName> const& _externalIdentifiers = {});\n\n\t/// Appends arbitrary data to the end of the bytecode.\n\tvoid appendToAuxiliaryData(bytes const& _data) { m_asm->appendToAuxiliaryData(_data); }\n\n\t/// Run optimisation step.\n\tvoid optimise(OptimiserSettings const& _settings) { m_asm->optimise(evmasm::Assembly::OptimiserSettings::translateSettings(_settings)); }\n\n\t/// @returns the runtime context if in creation mode and runtime context is set, nullptr otherwise.\n\tCompilerContext* runtimeContext() const { return m_runtimeContext; }\n\t/// @returns the identifier of the runtime subroutine.\n\tevmasm::SubAssemblyID runtimeSub() const { return m_runtimeSub; }\n\n\t/// @returns a const reference to the underlying assembly.\n\tevmasm::Assembly const& assembly() const { return *m_asm; }\n\t/// @returns a shared pointer to the assembly.\n\t/// Should be avoided except when adding sub-assemblies.\n\tstd::shared_ptr<evmasm::Assembly> assemblyPtr() const { return m_asm; }\n\n\t/**\n\t * Helper class to pop the visited nodes stack when a scope closes\n\t */\n\tclass LocationSetter: public ScopeGuard\n\t{\n\tpublic:\n\t\tLocationSetter(CompilerContext& _compilerContext, ASTNode const& _node):\n\t\t\tScopeGuard([&]{ _compilerContext.popVisitedNodes(); }) { _compilerContext.pushVisitedNodes(&_node); }\n\t};\n\n\tvoid setModifierDepth(size_t _modifierDepth) { m_asm->m_currentModifierDepth = _modifierDepth; }\n\n\tRevertStrings revertStrings() const { return m_revertStrings; }\n\nprivate:\n\t/// Updates source location set in the assembly.\n\tvoid updateSourceLocation();\n\n\t/**\n\t * Helper class that manages function labels and ensures that referenced functions are\n\t * compiled in a specific order.\n\t */\n\tstruct FunctionCompilationQueue\n\t{\n\t\t/// @returns the entry label of the given function and creates it if it does not exist yet.\n\t\t/// @param _context compiler context used to create a new tag if needed\n\t\tevmasm::AssemblyItem entryLabel(Declaration const& _declaration, CompilerContext& _context);\n\t\t/// @returns the entry label of the given function. Might return an AssemblyItem of type\n\t\t/// UndefinedItem if it does not exist yet.\n\t\tevmasm::AssemblyItem entryLabelIfExists(Declaration const& _declaration) const;\n\n\t\t/// @returns the next function in the queue of functions that are still to be compiled\n\t\t/// (i.e. that were referenced during compilation but where we did not yet generate code for).\n\t\t/// Returns nullptr if the queue is empty. Does not remove the function from the queue,\n\t\t/// that will only be done by startFunction below.\n\t\tDeclaration const* nextFunctionToCompile() const;\n\t\t/// Informs the queue that we are about to compile the given function, i.e. removes\n\t\t/// the function from the queue of functions to compile.\n\t\tvoid startFunction(Declaration const& _function);\n\n\t\t/// Labels pointing to the entry points of functions.\n\t\tstd::map<Declaration const*, evmasm::AssemblyItem> m_entryLabels;\n\t\t/// Set of functions for which we did not yet generate code.\n\t\tstd::set<Declaration const*> m_alreadyCompiledFunctions;\n\t\t/// Queue of functions that still need to be compiled (important to be a queue to maintain\n\t\t/// determinism even in the presence of a non-deterministic allocator).\n\t\t/// Mutable because we will throw out some functions earlier than needed.\n\t\tmutable std::queue<Declaration const*> m_functionsToCompile;\n\t} m_functionCompilationQueue;\n\n\tevmasm::AssemblyPointer m_asm;\n\t/// Version of the EVM to compile against.\n\tlangutil::EVMVersion m_evmVersion;\n\tRevertStrings const m_revertStrings;\n\tbool m_useABICoderV2 = false;\n\t/// Other already compiled contracts to be used in contract creation calls.\n\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>> m_otherCompilers;\n\t/// Storage offsets of state variables\n\tstd::map<Declaration const*, std::pair<u256, unsigned>> m_stateVariables;\n\t/// Memory offsets reserved for the values of immutable variables during contract creation.\n\tstd::map<VariableDeclaration const*, size_t> m_immutableVariables;\n\t/// Total amount of reserved memory. Reserved memory is used to store immutable variables during contract creation.\n\t/// This has to be finalized before initialiseFreeMemoryPointer() is called. That function\n\t/// will reset the optional to verify that.\n\tstd::optional<size_t> m_reservedMemory = {0};\n\t/// Offsets of local variables on the stack (relative to stack base).\n\t/// This needs to be a stack because if a modifier contains a local variable and this\n\t/// modifier is applied twice, the position of the variable needs to be restored\n\t/// after the nested modifier is left.\n\tstd::map<Declaration const*, std::vector<unsigned>> m_localVariables;\n\t/// The contract currently being compiled. Virtual function lookup starts from this contract.\n\tContractDefinition const* m_mostDerivedContract = nullptr;\n\t/// Whether to use checked arithmetic.\n\tArithmetic m_arithmetic = Arithmetic::Checked;\n\t/// Stack of current visited AST nodes, used for location attachment\n\tstd::stack<ASTNode const*> m_visitedNodes;\n\t/// The runtime context if in Creation mode, this is used for generating tags that would be stored into the storage and then used at runtime.\n\tCompilerContext* m_runtimeContext;\n\t/// The index of the runtime subroutine.\n\tevmasm::SubAssemblyID m_runtimeSub{};\n\t/// An index of low-level function labels by name.\n\tstd::map<std::string, evmasm::AssemblyItem> m_lowLevelFunctions;\n\t/// Collector for yul functions.\n\tMultiUseYulFunctionCollector m_yulFunctionCollector;\n\t/// Set of externally used yul functions.\n\tstd::set<std::string> m_externallyUsedYulFunctions;\n\t/// Generated Yul code used as utility. Source references from the bytecode can point here.\n\t/// Produced from @a m_yulFunctionCollector.\n\tstd::string m_generatedYulUtilityCode;\n\t/// Container for ABI functions to be generated.\n\tABIFunctions m_abiFunctions;\n\t/// Container for Yul Util functions to be generated.\n\tYulUtilFunctions m_yulUtilFunctions;\n\t/// The queue of low-level functions to generate.\n\tstd::queue<std::tuple<std::string, unsigned, unsigned, std::function<void(CompilerContext&)>>> m_lowLevelFunctionGenerationQueue;\n\t/// Flag to check that appendYulUtilityFunctions() was called exactly once\n\tbool m_appendYulUtilityFunctionsRan = false;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/CompilerUtils.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Routines used by both the compiler and the expression compiler.\n */\n\n#include <libsolidity/codegen/CompilerUtils.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/codegen/ABIFunctions.h>\n#include <libsolidity/codegen/ArrayUtils.h>\n#include <libsolidity/codegen/LValue.h>\n#include <libsolutil/FunctionSelector.h>\n#include <libevmasm/Instruction.h>\n#include <libsolutil/Whiskers.h>\n#include <libsolutil/StackTooDeepString.h>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\n\nusing solidity::util::Whiskers;\nusing solidity::util::h256;\nusing solidity::toCompactHexWithPrefix;\n\nunsigned const CompilerUtils::dataStartOffset = 4;\nsize_t const CompilerUtils::freeMemoryPointer = 64;\nsize_t const CompilerUtils::zeroPointer = CompilerUtils::freeMemoryPointer + 32;\nsize_t const CompilerUtils::generalPurposeMemoryStart = CompilerUtils::zeroPointer + 32;\n\nstatic_assert(CompilerUtils::freeMemoryPointer >= 64, \"Free memory pointer must not overlap with scratch area.\");\nstatic_assert(CompilerUtils::zeroPointer >= CompilerUtils::freeMemoryPointer + 32, \"Zero pointer must not overlap with free memory pointer.\");\nstatic_assert(CompilerUtils::generalPurposeMemoryStart >= CompilerUtils::zeroPointer + 32, \"General purpose memory must not overlap with zero area.\");\n\nvoid CompilerUtils::initialiseFreeMemoryPointer()\n{\n\tsize_t reservedMemory = m_context.reservedMemory();\n\tsolAssert(bigint(generalPurposeMemoryStart) + bigint(reservedMemory) < bigint(1) << 63);\n\tm_context << (u256(generalPurposeMemoryStart) + reservedMemory);\n\tstoreFreeMemoryPointer();\n}\n\nvoid CompilerUtils::fetchFreeMemoryPointer()\n{\n\tm_context << u256(freeMemoryPointer) << Instruction::MLOAD;\n}\n\nvoid CompilerUtils::storeFreeMemoryPointer()\n{\n\tm_context << u256(freeMemoryPointer) << Instruction::MSTORE;\n}\n\nvoid CompilerUtils::allocateMemory()\n{\n\tfetchFreeMemoryPointer();\n\tm_context << Instruction::SWAP1 << Instruction::DUP2 << Instruction::ADD;\n\tstoreFreeMemoryPointer();\n}\n\nvoid CompilerUtils::allocateMemory(u256 const& size)\n{\n\tfetchFreeMemoryPointer();\n\tm_context << Instruction::DUP1 << size << Instruction::ADD;\n\tstoreFreeMemoryPointer();\n}\n\nvoid CompilerUtils::toSizeAfterFreeMemoryPointer()\n{\n\tfetchFreeMemoryPointer();\n\tm_context << Instruction::DUP1 << Instruction::SWAP2 << Instruction::SUB;\n\tm_context << Instruction::SWAP1;\n}\n\nvoid CompilerUtils::revertWithStringData(Type const& _argumentType)\n{\n\tsolAssert(_argumentType.isImplicitlyConvertibleTo(*TypeProvider::fromElementaryTypeName(\"string memory\")));\n\tfetchFreeMemoryPointer();\n\tm_context << util::selectorFromSignatureU256(\"Error(string)\");\n\tm_context << Instruction::DUP2 << Instruction::MSTORE;\n\tm_context << u256(4) << Instruction::ADD;\n\t// Stack: <string data> <mem pos of encoding start>\n\tabiEncode({&_argumentType}, {TypeProvider::array(DataLocation::Memory, true)});\n\ttoSizeAfterFreeMemoryPointer();\n\tm_context << Instruction::REVERT;\n}\n\nvoid CompilerUtils::revertWithError(\n\tstd::string const& _signature,\n\tstd::vector<Type const*> const& _parameterTypes,\n\tstd::vector<Type const*> const& _argumentTypes\n)\n{\n\tfetchFreeMemoryPointer();\n\tm_context << util::selectorFromSignatureU256(_signature);\n\tm_context << Instruction::DUP2 << Instruction::MSTORE;\n\tm_context << u256(4) << Instruction::ADD;\n\t// Stack: <arguments...> <mem pos of encoding start>\n\tabiEncode(_argumentTypes, _parameterTypes);\n\ttoSizeAfterFreeMemoryPointer();\n\tm_context << Instruction::REVERT;\n}\n\nvoid CompilerUtils::returnDataToArray()\n{\n\tif (m_context.evmVersion().supportsReturndata())\n\t{\n\t\tm_context << Instruction::RETURNDATASIZE;\n\t\tm_context.appendInlineAssembly(R\"({\n\t\t\tswitch v case 0 {\n\t\t\t\tv := 0x60\n\t\t\t} default {\n\t\t\t\tv := mload(0x40)\n\t\t\t\tmstore(0x40, add(v, and(add(returndatasize(), 0x3f), not(0x1f))))\n\t\t\t\tmstore(v, returndatasize())\n\t\t\t\treturndatacopy(add(v, 0x20), 0, returndatasize())\n\t\t\t}\n\t\t})\", {\"v\"});\n\t}\n\telse\n\t\tpushZeroPointer();\n}\n\nvoid CompilerUtils::accessCalldataTail(Type const& _type)\n{\n\tm_context << Instruction::SWAP1;\n\tm_context.callYulFunction(\n\t\tm_context.utilFunctions().accessCalldataTailFunction(_type),\n\t\t2,\n\t\t_type.isDynamicallySized() ? 2 : 1\n\t);\n}\n\nunsigned CompilerUtils::loadFromMemory(\n\tunsigned _offset,\n\tType const& _type,\n\tbool _fromCalldata,\n\tbool _padToWordBoundaries\n)\n{\n\tsolAssert(_type.category() != Type::Category::Array, \"Unable to statically load dynamic type.\");\n\tm_context << u256(_offset);\n\treturn loadFromMemoryHelper(_type, _fromCalldata, _padToWordBoundaries);\n}\n\nvoid CompilerUtils::loadFromMemoryDynamic(\n\tType const& _type,\n\tbool _fromCalldata,\n\tbool _padToWordBoundaries,\n\tbool _keepUpdatedMemoryOffset\n)\n{\n\tif (_keepUpdatedMemoryOffset)\n\t\tm_context << Instruction::DUP1;\n\n\tif (auto arrayType = dynamic_cast<ArrayType const*>(&_type))\n\t{\n\t\tsolAssert(!arrayType->isDynamicallySized());\n\t\tsolAssert(!_fromCalldata);\n\t\tsolAssert(_padToWordBoundaries);\n\t\tif (_keepUpdatedMemoryOffset)\n\t\t\tm_context << arrayType->memoryDataSize() << Instruction::ADD;\n\t}\n\telse\n\t{\n\t\tunsigned numBytes = loadFromMemoryHelper(_type, _fromCalldata, _padToWordBoundaries);\n\t\tif (_keepUpdatedMemoryOffset)\n\t\t{\n\t\t\t// update memory counter\n\t\t\tmoveToStackTop(_type.sizeOnStack());\n\t\t\tm_context << u256(numBytes) << Instruction::ADD;\n\t\t}\n\t}\n}\n\nvoid CompilerUtils::storeInMemory(unsigned _offset)\n{\n\tunsigned numBytes = prepareMemoryStore(*TypeProvider::uint256(), true);\n\tif (numBytes > 0)\n\t\tm_context << u256(_offset) << Instruction::MSTORE;\n}\n\nvoid CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBoundaries, bool _cleanup)\n{\n\t// process special types (Reference, StringLiteral, Function)\n\tif (auto ref = dynamic_cast<ReferenceType const*>(&_type))\n\t{\n\t\tsolUnimplementedAssert(\n\t\t\tref->location() == DataLocation::Memory,\n\t\t\t\"Only in-memory reference type can be stored.\"\n\t\t);\n\t\tstoreInMemoryDynamic(*TypeProvider::uint256(), _padToWordBoundaries, _cleanup);\n\t}\n\telse if (auto str = dynamic_cast<StringLiteralType const*>(&_type))\n\t{\n\t\tm_context << Instruction::DUP1;\n\t\tstoreStringData(bytesConstRef(str->value()));\n\t\tif (_padToWordBoundaries)\n\t\t\tm_context << u256(std::max<size_t>(32, ((str->value().size() + 31) / 32) * 32));\n\t\telse\n\t\t\tm_context << u256(str->value().size());\n\t\tm_context << Instruction::ADD;\n\t}\n\telse if (\n\t\t_type.category() == Type::Category::Function &&\n\t\tdynamic_cast<FunctionType const&>(_type).kind() == FunctionType::Kind::External\n\t)\n\t{\n\t\tcombineExternalFunctionType(true);\n\t\tm_context << Instruction::DUP2 << Instruction::MSTORE;\n\t\tm_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD;\n\t}\n\telse if (_type.isValueType())\n\t{\n\t\tunsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries, _cleanup);\n\t\tm_context << Instruction::DUP2 << Instruction::MSTORE;\n\t\tm_context << u256(numBytes) << Instruction::ADD;\n\t}\n\telse // Should never happen\n\t{\n\t\tsolAssert(\n\t\t\tfalse,\n\t\t\t\"Memory store of type \" + _type.toString(true) + \" not allowed.\"\n\t\t);\n\t}\n}\n\nvoid CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMemory)\n{\n\t/// Stack: <source_offset> <length>\n\tif (m_context.useABICoderV2())\n\t{\n\t\t// Use the new Yul-based decoding function\n\t\tauto stackHeightBefore = m_context.stackHeight();\n\t\tabiDecodeV2(_typeParameters, _fromMemory);\n\t\tsolAssert(m_context.stackHeight() - stackHeightBefore == sizeOnStack(_typeParameters) - 2);\n\t\treturn;\n\t}\n\n\t//@todo this does not yet support nested dynamic arrays\n\tsize_t encodedSize = 0;\n\tfor (auto const& t: _typeParameters)\n\t\tencodedSize += t->decodingType()->calldataHeadSize();\n\n\tWhiskers templ(R\"({\n\t\tif lt(len, <encodedSize>) { <revertString> }\n\t})\");\n\ttempl(\"encodedSize\", std::to_string(encodedSize));\n\ttempl(\"revertString\", m_context.revertReasonIfDebug(\"Calldata too short\"));\n\tm_context.appendInlineAssembly(templ.render(), {\"len\"});\n\n\tm_context << Instruction::DUP2 << Instruction::ADD;\n\tm_context << Instruction::SWAP1;\n\t/// Stack: <input_end> <source_offset>\n\n\t// Retain the offset pointer as base_offset, the point from which the data offsets are computed.\n\tm_context << Instruction::DUP1;\n\tfor (Type const* parameterType: _typeParameters)\n\t{\n\t\t// stack: v1 v2 ... v(k-1) input_end base_offset current_offset\n\t\tType const* type = parameterType->decodingType();\n\t\tsolUnimplementedAssert(type, \"No decoding type found.\");\n\t\tif (type->category() == Type::Category::Array)\n\t\t{\n\t\t\tauto const& arrayType = dynamic_cast<ArrayType const&>(*type);\n\t\t\tsolUnimplementedAssert(!arrayType.baseType()->isDynamicallyEncoded(), \"Nested arrays not yet implemented.\");\n\t\t\tif (_fromMemory)\n\t\t\t{\n\t\t\t\tsolUnimplementedAssert(\n\t\t\t\t\tarrayType.baseType()->isValueType(),\n\t\t\t\t\t\"Nested memory arrays not yet implemented here.\"\n\t\t\t\t);\n\t\t\t\t// @todo If base type is an array or struct, it is still calldata-style encoded, so\n\t\t\t\t// we would have to convert it like below.\n\t\t\t\tsolAssert(arrayType.location() == DataLocation::Memory);\n\t\t\t\tif (arrayType.isDynamicallySized())\n\t\t\t\t{\n\t\t\t\t\t// compute data pointer\n\t\t\t\t\tm_context << Instruction::DUP1 << Instruction::MLOAD;\n\t\t\t\t\t// stack: v1 v2 ... v(k-1) input_end base_offset current_offset data_offset\n\n\t\t\t\t\tfetchFreeMemoryPointer();\n\t\t\t\t\t// stack: v1 v2 ... v(k-1) input_end base_offset current_offset data_offset dstmem\n\t\t\t\t\tmoveIntoStack(4);\n\t\t\t\t\t// stack: v1 v2 ... v(k-1) dstmem input_end base_offset current_offset data_offset\n\t\t\t\t\tm_context << Instruction::DUP5;\n\t\t\t\t\t// stack: v1 v2 ... v(k-1) dstmem input_end base_offset current_offset data_offset dstmem\n\n\t\t\t\t\t// Check that the data pointer is valid and that length times\n\t\t\t\t\t// item size is still inside the range.\n\t\t\t\t\tWhiskers templ(R\"({\n\t\t\t\t\t\tif gt(ptr, 0x100000000) { <revertStringPointer> }\n\t\t\t\t\t\tptr := add(ptr, base_offset)\n\t\t\t\t\t\tlet array_data_start := add(ptr, 0x20)\n\t\t\t\t\t\tif gt(array_data_start, input_end) { <revertStringStart> }\n\t\t\t\t\t\tlet array_length := mload(ptr)\n\t\t\t\t\t\tif or(\n\t\t\t\t\t\t\tgt(array_length, 0x100000000),\n\t\t\t\t\t\t\tgt(add(array_data_start, mul(array_length, <item_size>)), input_end)\n\t\t\t\t\t\t) { <revertStringLength> }\n\t\t\t\t\t\tmstore(dst, array_length)\n\t\t\t\t\t\tdst := add(dst, 0x20)\n\t\t\t\t\t})\");\n\t\t\t\t\ttempl(\"item_size\", std::to_string(arrayType.calldataStride()));\n\t\t\t\t\t// TODO add test\n\t\t\t\t\ttempl(\"revertStringPointer\", m_context.revertReasonIfDebug(\"ABI memory decoding: invalid data pointer\"));\n\t\t\t\t\ttempl(\"revertStringStart\", m_context.revertReasonIfDebug(\"ABI memory decoding: invalid data start\"));\n\t\t\t\t\ttempl(\"revertStringLength\", m_context.revertReasonIfDebug(\"ABI memory decoding: invalid data length\"));\n\t\t\t\t\tm_context.appendInlineAssembly(templ.render(), {\"input_end\", \"base_offset\", \"offset\", \"ptr\", \"dst\"});\n\t\t\t\t\t// stack: v1 v2 ... v(k-1) dstmem input_end base_offset current_offset data_ptr dstdata\n\t\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t\t\t// stack: v1 v2 ... v(k-1) dstmem input_end base_offset current_offset dstdata data_ptr\n\t\t\t\t\tArrayUtils(m_context).copyArrayToMemory(arrayType, true);\n\t\t\t\t\t// stack: v1 v2 ... v(k-1) dstmem input_end base_offset current_offset mem_end\n\t\t\t\t\tstoreFreeMemoryPointer();\n\t\t\t\t\tm_context << u256(0x20) << Instruction::ADD;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Size has already been checked for this one.\n\t\t\t\t\tmoveIntoStack(2);\n\t\t\t\t\tm_context << Instruction::DUP3;\n\t\t\t\t\tm_context << u256(arrayType.calldataHeadSize()) << Instruction::ADD;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// first load from calldata and potentially convert to memory if arrayType is memory\n\t\t\t\tType const* calldataType = TypeProvider::withLocation(&arrayType, DataLocation::CallData, false);\n\t\t\t\tif (calldataType->isDynamicallySized())\n\t\t\t\t{\n\t\t\t\t\t// put on stack: data_pointer length\n\t\t\t\t\tloadFromMemoryDynamic(*TypeProvider::uint256(), !_fromMemory);\n\t\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t\t\t// stack: input_end base_offset next_pointer data_offset\n\t\t\t\t\tm_context.appendInlineAssembly(Whiskers(R\"({\n\t\t\t\t\t\tif gt(data_offset, 0x100000000) { <revertString> }\n\t\t\t\t\t})\")\n\t\t\t\t\t// TODO add test\n\t\t\t\t\t(\"revertString\", m_context.revertReasonIfDebug(\"ABI calldata decoding: invalid data offset\"))\n\t\t\t\t\t.render(), {\"data_offset\"});\n\t\t\t\t\tm_context << Instruction::DUP3 << Instruction::ADD;\n\t\t\t\t\t// stack: input_end base_offset next_pointer array_head_ptr\n\t\t\t\t\tm_context.appendInlineAssembly(Whiskers(R\"({\n\t\t\t\t\t\tif gt(add(array_head_ptr, 0x20), input_end) { <revertString> }\n\t\t\t\t\t})\")\n\t\t\t\t\t(\"revertString\", m_context.revertReasonIfDebug(\"ABI calldata decoding: invalid head pointer\"))\n\t\t\t\t\t.render(), {\"input_end\", \"base_offset\", \"next_ptr\", \"array_head_ptr\"});\n\n\t\t\t\t\t// retrieve length\n\t\t\t\t\tloadFromMemoryDynamic(*TypeProvider::uint256(), !_fromMemory, true);\n\t\t\t\t\t// stack: input_end base_offset next_pointer array_length data_pointer\n\t\t\t\t\tm_context << Instruction::SWAP2;\n\t\t\t\t\t// stack: input_end base_offset data_pointer array_length next_pointer\n\t\t\t\t\tm_context.appendInlineAssembly(Whiskers(R\"({\n\t\t\t\t\t\tif or(\n\t\t\t\t\t\t\tgt(array_length, 0x100000000),\n\t\t\t\t\t\t\tgt(add(data_ptr, mul(array_length, )\" + std::to_string(arrayType.calldataStride()) + R\"()), input_end)\n\t\t\t\t\t\t) { <revertString> }\n\t\t\t\t\t})\")\n\t\t\t\t\t(\"revertString\", m_context.revertReasonIfDebug(\"ABI calldata decoding: invalid data pointer\"))\n\t\t\t\t\t.render(), {\"input_end\", \"base_offset\", \"data_ptr\", \"array_length\", \"next_ptr\"});\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// size has already been checked\n\t\t\t\t\t// stack: input_end base_offset data_offset\n\t\t\t\t\tm_context << Instruction::DUP1;\n\t\t\t\t\tm_context << u256(calldataType->calldataHeadSize()) << Instruction::ADD;\n\t\t\t\t}\n\t\t\t\tif (arrayType.location() == DataLocation::Memory)\n\t\t\t\t{\n\t\t\t\t\t// stack: input_end base_offset calldata_ref [length] next_calldata\n\t\t\t\t\t// copy to memory\n\t\t\t\t\t// move calldata type up again\n\t\t\t\t\tmoveIntoStack(calldataType->sizeOnStack());\n\t\t\t\t\tconvertType(*calldataType, arrayType, false, false, true);\n\t\t\t\t\t// fetch next pointer again\n\t\t\t\t\tmoveToStackTop(arrayType.sizeOnStack());\n\t\t\t\t}\n\t\t\t\t// move input_end up\n\t\t\t\t// stack: input_end base_offset calldata_ref [length] next_calldata\n\t\t\t\tmoveToStackTop(2 + arrayType.sizeOnStack());\n\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t\t// stack: base_offset calldata_ref [length] input_end next_calldata\n\t\t\t\tmoveToStackTop(2 + arrayType.sizeOnStack());\n\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t\t// stack: calldata_ref [length] input_end base_offset next_calldata\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(!type->isDynamicallyEncoded(), \"Unknown dynamically sized type: \" + type->toString());\n\t\t\tloadFromMemoryDynamic(*type, !_fromMemory, true);\n\t\t\t// stack: v1 v2 ... v(k-1) input_end base_offset v(k) mem_offset\n\t\t\tmoveToStackTop(1, type->sizeOnStack());\n\t\t\tmoveIntoStack(3, type->sizeOnStack());\n\t\t}\n\t\t// stack: v1 v2 ... v(k-1) v(k) input_end base_offset next_offset\n\t}\n\tpopStackSlots(3);\n}\n\nvoid CompilerUtils::encodeToMemory(\n\tTypePointers const& _givenTypes,\n\tTypePointers const& _targetTypes,\n\tbool _padToWordBoundaries,\n\tbool _copyDynamicDataInPlace,\n\tbool _encodeAsLibraryTypes\n)\n{\n\t// stack: <v1> <v2> ... <vn> <mem>\n\tbool const encoderV2 = m_context.useABICoderV2();\n\tTypePointers targetTypes = _targetTypes.empty() ? _givenTypes : _targetTypes;\n\tsolAssert(targetTypes.size() == _givenTypes.size());\n\tfor (Type const*& t: targetTypes)\n\t{\n\t\tType const* tEncoding = t->fullEncodingType(_encodeAsLibraryTypes, encoderV2, !_padToWordBoundaries);\n\t\tsolUnimplementedAssert(tEncoding, \"Encoding type \\\"\" + t->toString() + \"\\\" not yet implemented.\");\n\t\tt = std::move(tEncoding);\n\t}\n\n\tif (_givenTypes.empty())\n\t\treturn;\n\tif (encoderV2)\n\t{\n\t\t// Use the new Yul-based encoding function\n\t\tsolAssert(\n\t\t\t_padToWordBoundaries != _copyDynamicDataInPlace,\n\t\t\t\"Non-padded and in-place encoding can only be combined.\"\n\t\t);\n\t\tauto stackHeightBefore = m_context.stackHeight();\n\t\tabiEncodeV2(_givenTypes, targetTypes, _encodeAsLibraryTypes, _padToWordBoundaries);\n\t\tsolAssert(stackHeightBefore - m_context.stackHeight() == sizeOnStack(_givenTypes));\n\t\treturn;\n\t}\n\n\t// Stack during operation:\n\t// <v1> <v2> ... <vn> <mem_start> <dyn_head_1> ... <dyn_head_r> <end_of_mem>\n\t// The values dyn_head_n are added during the first loop and they point to the head part\n\t// of the nth dynamic parameter, which is filled once the dynamic parts are processed.\n\n\t// store memory start pointer\n\tm_context << Instruction::DUP1;\n\n\tunsigned argSize = CompilerUtils::sizeOnStack(_givenTypes);\n\tunsigned stackPos = 0; // advances through the argument values\n\tunsigned dynPointers = 0; // number of dynamic head pointers on the stack\n\tfor (size_t i = 0; i < _givenTypes.size(); ++i)\n\t{\n\t\tType const* targetType = targetTypes[i];\n\t\tsolAssert(!!targetType, \"Externalable type expected.\");\n\t\tif (targetType->isDynamicallySized() && !_copyDynamicDataInPlace)\n\t\t{\n\t\t\t// leave end_of_mem as dyn head pointer\n\t\t\tm_context << Instruction::DUP1 << u256(32) << Instruction::ADD;\n\t\t\tdynPointers++;\n\t\t\tassertThrow(\n\t\t\t\t(argSize + dynPointers) < m_context.reachableStackDepth(),\n\t\t\t\tStackTooDeepError,\n\t\t\t\tutil::stackTooDeepString\n\t\t\t);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbool needCleanup = true;\n\t\t\tcopyToStackTop(argSize - stackPos + dynPointers + 2, _givenTypes[i]->sizeOnStack());\n\t\t\tsolAssert(!!targetType, \"Externalable type expected.\");\n\t\t\tType const* type = targetType;\n\t\t\tif (_givenTypes[i]->dataStoredIn(DataLocation::Storage) && targetType->isValueType())\n\t\t\t{\n\t\t\t\t// special case: convert storage reference type to value type - this is only\n\t\t\t\t// possible for library calls where we just forward the storage reference\n\t\t\t\tsolAssert(_encodeAsLibraryTypes);\n\t\t\t\tsolAssert(_givenTypes[i]->sizeOnStack() == 1);\n\t\t\t}\n\t\t\telse if (\n\t\t\t\t_givenTypes[i]->dataStoredIn(DataLocation::Storage) ||\n\t\t\t\t_givenTypes[i]->dataStoredIn(DataLocation::CallData) ||\n\t\t\t\t_givenTypes[i]->category() == Type::Category::StringLiteral ||\n\t\t\t\t_givenTypes[i]->category() == Type::Category::Function\n\t\t\t)\n\t\t\t\ttype = _givenTypes[i]; // delay conversion\n\t\t\telse\n\t\t\t{\n\t\t\t\tconvertType(*_givenTypes[i], *targetType, true);\n\t\t\t\tneedCleanup = false;\n\t\t\t}\n\n\t\t\tif (auto arrayType = dynamic_cast<ArrayType const*>(type))\n\t\t\t\tArrayUtils(m_context).copyArrayToMemory(*arrayType, _padToWordBoundaries);\n\t\t\telse if (auto arraySliceType = dynamic_cast<ArraySliceType const*>(type))\n\t\t\t{\n\t\t\t\tsolAssert(\n\t\t\t\t\tarraySliceType->dataStoredIn(DataLocation::CallData) &&\n\t\t\t\t\tarraySliceType->isDynamicallySized() &&\n\t\t\t\t\t!arraySliceType->arrayType().baseType()->isDynamicallyEncoded(),\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\t\t\t\tArrayUtils(m_context).copyArrayToMemory(arraySliceType->arrayType(), _padToWordBoundaries);\n\t\t\t}\n\t\t\telse\n\t\t\t\tstoreInMemoryDynamic(*type, _padToWordBoundaries, needCleanup);\n\t\t}\n\t\tstackPos += _givenTypes[i]->sizeOnStack();\n\t}\n\n\t// now copy the dynamic part\n\t// Stack: <v1> <v2> ... <vn> <mem_start> <dyn_head_1> ... <dyn_head_r> <end_of_mem>\n\tstackPos = 0;\n\tunsigned thisDynPointer = 0;\n\tfor (size_t i = 0; i < _givenTypes.size(); ++i)\n\t{\n\t\tType const* targetType = targetTypes[i];\n\t\tsolAssert(!!targetType, \"Externalable type expected.\");\n\t\tif (targetType->isDynamicallySized() && !_copyDynamicDataInPlace)\n\t\t{\n\t\t\t// copy tail pointer (=mem_end - mem_start) to memory\n\t\t\tassertThrow(\n\t\t\t\t(2 + dynPointers) <= m_context.reachableStackDepth(),\n\t\t\t\tStackTooDeepError,\n\t\t\t\tutil::stackTooDeepString\n\t\t\t);\n\t\t\tm_context << dupInstruction(2 + dynPointers) << Instruction::DUP2;\n\t\t\tm_context << Instruction::SUB;\n\t\t\tm_context << dupInstruction(2 + dynPointers - thisDynPointer);\n\t\t\tm_context << Instruction::MSTORE;\n\t\t\t// stack: ... <end_of_mem>\n\t\t\tif (_givenTypes[i]->category() == Type::Category::StringLiteral)\n\t\t\t{\n\t\t\t\tauto const& strType = dynamic_cast<StringLiteralType const&>(*_givenTypes[i]);\n\t\t\t\tauto const size = strType.value().size();\n\t\t\t\tm_context << u256(size);\n\t\t\t\tstoreInMemoryDynamic(*TypeProvider::uint256(), true);\n\t\t\t\t// stack: ... <end_of_mem'>\n\n\t\t\t\t// Do not output empty padding for zero-length strings.\n\t\t\t\t// TODO: handle this in storeInMemoryDynamic\n\t\t\t\tif (size != 0)\n\t\t\t\t\tstoreInMemoryDynamic(strType, _padToWordBoundaries);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tArrayType const* arrayType = nullptr;\n\t\t\t\tswitch (_givenTypes[i]->category())\n\t\t\t\t{\n\t\t\t\t\tcase Type::Category::Array:\n\t\t\t\t\t\tarrayType = dynamic_cast<ArrayType const*>(_givenTypes[i]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase Type::Category::ArraySlice:\n\t\t\t\t\t\tarrayType = &dynamic_cast<ArraySliceType const*>(_givenTypes[i])->arrayType();\n\t\t\t\t\t\tsolAssert(\n\t\t\t\t\t\t\tarrayType->isDynamicallySized() &&\n\t\t\t\t\t\t\tarrayType->dataStoredIn(DataLocation::CallData) &&\n\t\t\t\t\t\t\t!arrayType->baseType()->isDynamicallyEncoded(),\n\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsolAssert(false, \"Unknown dynamic type.\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t// now copy the array\n\t\t\t\tcopyToStackTop(argSize - stackPos + dynPointers + 2, arrayType->sizeOnStack());\n\t\t\t\t// stack: ... <end_of_mem> <value...>\n\t\t\t\t// copy length to memory\n\t\t\t\tm_context << dupInstruction(1 + arrayType->sizeOnStack());\n\t\t\t\tArrayUtils(m_context).retrieveLength(*arrayType, 1);\n\t\t\t\t// stack: ... <end_of_mem> <value...> <end_of_mem'> <length>\n\t\t\t\tstoreInMemoryDynamic(*TypeProvider::uint256(), true);\n\t\t\t\t// stack: ... <end_of_mem> <value...> <end_of_mem''>\n\t\t\t\t// copy the new memory pointer\n\t\t\t\tm_context << swapInstruction(arrayType->sizeOnStack() + 1) << Instruction::POP;\n\t\t\t\t// stack: ... <end_of_mem''> <value...>\n\t\t\t\t// copy data part\n\t\t\t\tArrayUtils(m_context).copyArrayToMemory(*arrayType, _padToWordBoundaries);\n\t\t\t\t// stack: ... <end_of_mem'''>\n\t\t\t}\n\n\t\t\tthisDynPointer++;\n\t\t}\n\t\tstackPos += _givenTypes[i]->sizeOnStack();\n\t}\n\n\t// remove unneeded stack elements (and retain memory pointer)\n\tm_context << swapInstruction(argSize + dynPointers + 1);\n\tpopStackSlots(argSize + dynPointers + 1);\n}\n\nvoid CompilerUtils::abiEncodeV2(\n\tTypePointers const& _givenTypes,\n\tTypePointers const& _targetTypes,\n\tbool _encodeAsLibraryTypes,\n\tbool _padToWordBoundaries\n)\n{\n\tif (!_padToWordBoundaries)\n\t\tsolAssert(!_encodeAsLibraryTypes, \"Library calls cannot be packed.\");\n\n\t// stack: <$value0> <$value1> ... <$value(n-1)> <$headStart>\n\n\tstd::string encoderName =\n\t\t_padToWordBoundaries ?\n\t\tm_context.abiFunctions().tupleEncoderReversed(_givenTypes, _targetTypes, _encodeAsLibraryTypes) :\n\t\tm_context.abiFunctions().tupleEncoderPackedReversed(_givenTypes, _targetTypes);\n\tm_context.callYulFunction(encoderName, sizeOnStack(_givenTypes) + 1, 1);\n}\n\nvoid CompilerUtils::abiDecodeV2(TypePointers const& _parameterTypes, bool _fromMemory)\n{\n\t// stack: <source_offset> <length> [stack top]\n\tm_context << Instruction::DUP2 << Instruction::ADD;\n\tm_context << Instruction::SWAP1;\n\t// stack: <end> <start>\n\tstd::string decoderName = m_context.abiFunctions().tupleDecoder(_parameterTypes, _fromMemory);\n\tm_context.callYulFunction(decoderName, 2, sizeOnStack(_parameterTypes));\n}\n\nvoid CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type)\n{\n\tif (_type.baseType()->hasSimpleZeroValueInMemory())\n\t{\n\t\tsolAssert(_type.baseType()->isValueType());\n\t\tWhiskers templ(R\"({\n\t\t\tlet size := mul(length, <element_size>)\n\t\t\t// cheap way of zero-initializing a memory range\n\t\t\tcalldatacopy(memptr, calldatasize(), size)\n\t\t\tmemptr := add(memptr, size)\n\t\t})\");\n\t\ttempl(\"element_size\", std::to_string(_type.memoryStride()));\n\t\tm_context.appendInlineAssembly(templ.render(), {\"length\", \"memptr\"});\n\t}\n\telse\n\t{\n\t\tauto repeat = m_context.newTag();\n\t\tm_context << repeat;\n\t\tpushZeroValue(*_type.baseType());\n\t\tstoreInMemoryDynamic(*_type.baseType());\n\t\tm_context << Instruction::SWAP1 << u256(1) << Instruction::SWAP1;\n\t\tm_context << Instruction::SUB << Instruction::SWAP1;\n\t\tm_context << Instruction::DUP2;\n\t\tm_context.appendConditionalJumpTo(repeat);\n\t}\n\tm_context << Instruction::SWAP1 << Instruction::POP;\n}\n\nvoid CompilerUtils::memoryCopy32()\n{\n\t// Stack here: size target source\n\n\tm_context.appendInlineAssembly(R\"(\n\t\t{\n\t\t\tfor { let i := 0 } lt(i, len) { i := add(i, 32) } {\n\t\t\t\tmstore(add(dst, i), mload(add(src, i)))\n\t\t\t}\n\t\t}\n\t)\",\n\t\t{ \"len\", \"dst\", \"src\" }\n\t);\n\tm_context << Instruction::POP << Instruction::POP << Instruction::POP;\n}\n\nvoid CompilerUtils::memoryCopy()\n{\n\t// Stack here: size target source\n\n\tm_context.appendInlineAssembly(R\"(\n\t\t{\n\t\t\t// copy 32 bytes at once\n\t\t\tfor\n\t\t\t\t{}\n\t\t\t\tiszero(lt(len, 32))\n\t\t\t\t{\n\t\t\t\t\tdst := add(dst, 32)\n\t\t\t\t\tsrc := add(src, 32)\n\t\t\t\t\tlen := sub(len, 32)\n\t\t\t\t}\n\t\t\t\t{ mstore(dst, mload(src)) }\n\n\t\t\t// copy the remainder (0 < len < 32)\n\t\t\tlet mask := sub(exp(256, sub(32, len)), 1)\n\t\t\tlet srcpart := and(mload(src), not(mask))\n\t\t\tlet dstpart := and(mload(dst), mask)\n\t\t\tmstore(dst, or(srcpart, dstpart))\n\t\t}\n\t)\",\n\t\t{ \"len\", \"dst\", \"src\" }\n\t);\n\tm_context << Instruction::POP << Instruction::POP << Instruction::POP;\n}\n\nvoid CompilerUtils::splitExternalFunctionType(bool _leftAligned)\n{\n\t// We have to split the left-aligned <address><function identifier> into two stack slots:\n\t// address (right aligned), function identifier (right aligned)\n\tif (_leftAligned)\n\t{\n\t\tm_context << Instruction::DUP1;\n\t\trightShiftNumberOnStack(64 + 32);\n\t\t// <input> <address>\n\t\tm_context << Instruction::SWAP1;\n\t\trightShiftNumberOnStack(64);\n\t}\n\telse\n\t{\n\t\tm_context << Instruction::DUP1;\n\t\trightShiftNumberOnStack(32);\n\t\tm_context << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::SWAP1;\n\t}\n\tm_context << u256(0xffffffffUL) << Instruction::AND;\n}\n\nvoid CompilerUtils::combineExternalFunctionType(bool _leftAligned)\n{\n\t// <address> <function_id>\n\tm_context << u256(0xffffffffUL) << Instruction::AND << Instruction::SWAP1;\n\tif (!_leftAligned)\n\t\tm_context << ((u256(1) << 160) - 1) << Instruction::AND;\n\tleftShiftNumberOnStack(32);\n\tm_context << Instruction::OR;\n\tif (_leftAligned)\n\t\tleftShiftNumberOnStack(64);\n}\n\nvoid CompilerUtils::pushCombinedFunctionEntryLabel(Declaration const& _function, bool _runtimeOnly)\n{\n\tm_context << m_context.functionEntryLabel(_function).pushTag();\n\t// If there is a runtime context, we have to merge both labels into the same\n\t// stack slot in case we store it in storage.\n\tif (CompilerContext* rtc = m_context.runtimeContext())\n\t{\n\t\tleftShiftNumberOnStack(32);\n\t\tif (_runtimeOnly)\n\t\t\tm_context <<\n\t\t\t\trtc->functionEntryLabel(_function).toSubAssemblyTag(m_context.runtimeSub()) <<\n\t\t\t\tInstruction::OR;\n\t}\n}\n\nvoid CompilerUtils::convertType(\n\tType const& _typeOnStack,\n\tType const& _targetType,\n\tbool _cleanupNeeded,\n\tbool _chopSignBits,\n\tbool _asPartOfArgumentDecoding\n)\n{\n\t// For a type extension, we need to remove all higher-order bits that we might have ignored in\n\t// previous operations.\n\t// @todo: store in the AST whether the operand might have \"dirty\" higher order bits\n\n\tif (_typeOnStack == _targetType && !_cleanupNeeded)\n\t\treturn;\n\tType::Category stackTypeCategory = _typeOnStack.category();\n\tType::Category targetTypeCategory = _targetType.category();\n\n\tif (stackTypeCategory == Type::Category::UserDefinedValueType)\n\t{\n\t\tsolAssert(_cleanupNeeded);\n\t\tauto& userDefined = dynamic_cast<UserDefinedValueType const&>(_typeOnStack);\n\t\tsolAssert(_typeOnStack == _targetType || _targetType == userDefined.underlyingType());\n\t\treturn convertType(\n\t\t\tuserDefined.underlyingType(),\n\t\t\t_targetType,\n\t\t\t_cleanupNeeded,\n\t\t\t_chopSignBits,\n\t\t\t_asPartOfArgumentDecoding\n\t\t);\n\t}\n\tif (targetTypeCategory == Type::Category::UserDefinedValueType)\n\t{\n\t\tsolAssert(_cleanupNeeded);\n\t\tauto& userDefined = dynamic_cast<UserDefinedValueType const&>(_targetType);\n\t\tsolAssert(_typeOnStack.isImplicitlyConvertibleTo(userDefined.underlyingType()));\n\t\treturn convertType(\n\t\t\t_typeOnStack,\n\t\t\tuserDefined.underlyingType(),\n\t\t\t_cleanupNeeded,\n\t\t\t_chopSignBits,\n\t\t\t_asPartOfArgumentDecoding\n\t\t);\n\t}\n\n\tif (auto contrType = dynamic_cast<ContractType const*>(&_typeOnStack))\n\t\tsolAssert(!contrType->isSuper(), \"Cannot convert magic variable \\\"super\\\"\");\n\n\tbool enumOverflowCheckPending = (targetTypeCategory == Type::Category::Enum || stackTypeCategory == Type::Category::Enum);\n\tbool chopSignBitsPending = _chopSignBits && targetTypeCategory == Type::Category::Integer;\n\tif (chopSignBitsPending)\n\t{\n\t\tIntegerType const& targetIntegerType = dynamic_cast<IntegerType const&>(_targetType);\n\t\tchopSignBitsPending = targetIntegerType.isSigned();\n\t}\n\n\tif (targetTypeCategory == Type::Category::FixedPoint)\n\t\tsolUnimplemented(\"Not yet implemented - FixedPointType.\");\n\n\tswitch (stackTypeCategory)\n\t{\n\tcase Type::Category::FixedBytes:\n\t{\n\t\tFixedBytesType const& typeOnStack = dynamic_cast<FixedBytesType const&>(_typeOnStack);\n\t\tif (targetTypeCategory == Type::Category::Integer)\n\t\t{\n\t\t\t// conversion from bytes to integer. no need to clean the high bit\n\t\t\t// only to shift right because of opposite alignment\n\t\t\tIntegerType const& targetIntegerType = dynamic_cast<IntegerType const&>(_targetType);\n\t\t\trightShiftNumberOnStack(256 - typeOnStack.numBytes() * 8);\n\t\t\tif (targetIntegerType.numBits() < typeOnStack.numBytes() * 8)\n\t\t\t\tconvertType(IntegerType(typeOnStack.numBytes() * 8), _targetType, _cleanupNeeded);\n\t\t}\n\t\telse if (targetTypeCategory == Type::Category::Address)\n\t\t{\n\t\t\tsolAssert(typeOnStack.numBytes() * 8 == 160);\n\t\t\trightShiftNumberOnStack(256 - 160);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// clear for conversion to longer bytes\n\t\t\tsolAssert(targetTypeCategory == Type::Category::FixedBytes, \"Invalid type conversion requested.\");\n\t\t\tFixedBytesType const& targetType = dynamic_cast<FixedBytesType const&>(_targetType);\n\t\t\tif (typeOnStack.numBytes() == 0 || targetType.numBytes() == 0)\n\t\t\t\tm_context << Instruction::POP << u256(0);\n\t\t\telse if (targetType.numBytes() > typeOnStack.numBytes() || _cleanupNeeded)\n\t\t\t{\n\t\t\t\tunsigned bytes = std::min(typeOnStack.numBytes(), targetType.numBytes());\n\t\t\t\tm_context << ((u256(1) << (256 - bytes * 8)) - 1);\n\t\t\t\tm_context << Instruction::NOT << Instruction::AND;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\tcase Type::Category::Enum:\n\t\tsolAssert(_targetType == _typeOnStack || targetTypeCategory == Type::Category::Integer);\n\t\tif (enumOverflowCheckPending)\n\t\t{\n\t\t\tEnumType const& enumType = dynamic_cast<decltype(enumType)>(_typeOnStack);\n\t\t\tsolAssert(enumType.numberOfMembers() > 0, \"empty enum should have caused a parser error.\");\n\t\t\tm_context << u256(enumType.numberOfMembers() - 1) << Instruction::DUP2 << Instruction::GT;\n\t\t\tif (_asPartOfArgumentDecoding)\n\t\t\t\tm_context.appendConditionalRevert(false, \"Enum out of range\");\n\t\t\telse\n\t\t\t\tm_context.appendConditionalPanic(util::PanicCode::EnumConversionError);\n\t\t\tenumOverflowCheckPending = false;\n\t\t}\n\t\tbreak;\n\tcase Type::Category::FixedPoint:\n\t\tsolUnimplemented(\"Not yet implemented - FixedPointType.\");\n\tcase Type::Category::Address:\n\tcase Type::Category::Integer:\n\tcase Type::Category::Contract:\n\tcase Type::Category::RationalNumber:\n\t\tif (targetTypeCategory == Type::Category::FixedBytes)\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\tstackTypeCategory == Type::Category::Address ||\n\t\t\t\tstackTypeCategory == Type::Category::Integer ||\n\t\t\t\tstackTypeCategory == Type::Category::RationalNumber,\n\t\t\t\t\"Invalid conversion to FixedBytesType requested.\"\n\t\t\t);\n\t\t\t// conversion from bytes to string. no need to clean the high bit\n\t\t\t// only to shift left because of opposite alignment\n\t\t\tFixedBytesType const& targetBytesType = dynamic_cast<FixedBytesType const&>(_targetType);\n\t\t\tif (auto typeOnStack = dynamic_cast<IntegerType const*>(&_typeOnStack))\n\t\t\t{\n\t\t\t\tif (targetBytesType.numBytes() * 8 > typeOnStack->numBits())\n\t\t\t\t\tcleanHigherOrderBits(*typeOnStack);\n\t\t\t}\n\t\t\telse if (stackTypeCategory == Type::Category::Address)\n\t\t\t\tsolAssert(targetBytesType.numBytes() * 8 == 160);\n\t\t\tleftShiftNumberOnStack(256 - targetBytesType.numBytes() * 8);\n\t\t}\n\t\telse if (targetTypeCategory == Type::Category::Enum)\n\t\t{\n\t\t\tsolAssert(stackTypeCategory != Type::Category::Address, \"Invalid conversion to EnumType requested.\");\n\t\t\tsolAssert(_typeOnStack.mobileType());\n\t\t\t// just clean\n\t\t\tconvertType(_typeOnStack, *_typeOnStack.mobileType(), true);\n\t\t\tEnumType const& enumType = dynamic_cast<decltype(enumType)>(_targetType);\n\t\t\tsolAssert(enumType.numberOfMembers() > 0, \"empty enum should have caused a parser error.\");\n\t\t\tm_context << u256(enumType.numberOfMembers() - 1) << Instruction::DUP2 << Instruction::GT;\n\t\t\tm_context.appendConditionalPanic(util::PanicCode::EnumConversionError);\n\t\t\tenumOverflowCheckPending = false;\n\t\t}\n\t\telse if (targetTypeCategory == Type::Category::FixedPoint)\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\tstackTypeCategory == Type::Category::Integer ||\n\t\t\t\tstackTypeCategory == Type::Category::RationalNumber ||\n\t\t\t\tstackTypeCategory == Type::Category::FixedPoint,\n\t\t\t\t\"Invalid conversion to FixedMxNType requested.\"\n\t\t\t);\n\t\t\t//shift all integer bits onto the left side of the fixed type\n\t\t\tFixedPointType const& targetFixedPointType = dynamic_cast<FixedPointType const&>(_targetType);\n\t\t\tif (auto typeOnStack = dynamic_cast<IntegerType const*>(&_typeOnStack))\n\t\t\t\tif (targetFixedPointType.numBits() > typeOnStack->numBits())\n\t\t\t\t\tcleanHigherOrderBits(*typeOnStack);\n\t\t\tsolUnimplemented(\"Not yet implemented - FixedPointType.\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\ttargetTypeCategory == Type::Category::Integer ||\n\t\t\t\ttargetTypeCategory == Type::Category::Contract ||\n\t\t\t\ttargetTypeCategory == Type::Category::Address,\n\t\t\t\t\"\"\n\t\t\t);\n\t\t\tIntegerType addressType(160);\n\t\t\tIntegerType const& targetType = targetTypeCategory == Type::Category::Integer\n\t\t\t\t? dynamic_cast<IntegerType const&>(_targetType) : addressType;\n\t\t\tif (stackTypeCategory == Type::Category::RationalNumber)\n\t\t\t{\n\t\t\t\tRationalNumberType const& constType = dynamic_cast<RationalNumberType const&>(_typeOnStack);\n\t\t\t\t// We know that the stack is clean, we only have to clean for a narrowing conversion\n\t\t\t\t// where cleanup is forced.\n\t\t\t\tsolUnimplementedAssert(!constType.isFractional(), \"Not yet implemented - FixedPointType.\");\n\t\t\t\tif (targetType.numBits() < constType.integerType()->numBits() && _cleanupNeeded)\n\t\t\t\t\tcleanHigherOrderBits(targetType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tIntegerType const& typeOnStack = stackTypeCategory == Type::Category::Integer\n\t\t\t\t\t? dynamic_cast<IntegerType const&>(_typeOnStack) : addressType;\n\t\t\t\t// Widening: clean up according to source type width\n\t\t\t\t// Non-widening and force: clean up according to target type bits\n\t\t\t\tif (targetType.numBits() > typeOnStack.numBits())\n\t\t\t\t\tcleanHigherOrderBits(typeOnStack);\n\t\t\t\telse if (_cleanupNeeded)\n\t\t\t\t\tcleanHigherOrderBits(targetType);\n\t\t\t\tif (chopSignBitsPending)\n\t\t\t\t{\n\t\t\t\t\tif (targetType.numBits() < 256)\n\t\t\t\t\t\tm_context\n\t\t\t\t\t\t\t<< ((u256(1) << targetType.numBits()) - 1)\n\t\t\t\t\t\t\t<< Instruction::AND;\n\t\t\t\t\tchopSignBitsPending = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase Type::Category::StringLiteral:\n\t{\n\t\tauto const& literalType = dynamic_cast<StringLiteralType const&>(_typeOnStack);\n\t\tstd::string const& value = literalType.value();\n\t\tbytesConstRef data(value);\n\t\tif (targetTypeCategory == Type::Category::FixedBytes)\n\t\t{\n\t\t\tunsigned const numBytes = dynamic_cast<FixedBytesType const&>(_targetType).numBytes();\n\t\t\tsolAssert(data.size() <= 32);\n\t\t\tm_context << (u256(h256(data, h256::AlignLeft)) & (~(u256(-1) >> (8 * numBytes))));\n\t\t}\n\t\telse if (targetTypeCategory == Type::Category::Array)\n\t\t{\n\t\t\tauto const& arrayType = dynamic_cast<ArrayType const&>(_targetType);\n\t\t\tsolAssert(arrayType.isByteArrayOrString());\n\t\t\tsize_t storageSize = 32 + ((data.size() + 31) / 32) * 32;\n\t\t\tallocateMemory(storageSize);\n\t\t\t// stack: mempos\n\t\t\tm_context << Instruction::DUP1 << u256(data.size());\n\t\t\tstoreInMemoryDynamic(*TypeProvider::uint256());\n\t\t\t// stack: mempos datapos\n\t\t\tstoreStringData(data);\n\t\t}\n\t\telse\n\t\t\tsolAssert(\n\t\t\t\tfalse,\n\t\t\t\t\"Invalid conversion from string literal to \" + _targetType.toString(false) + \" requested.\"\n\t\t\t);\n\t\tbreak;\n\t}\n\tcase Type::Category::Array:\n\t{\n\t\tauto const& typeOnStack = dynamic_cast<ArrayType const&>(_typeOnStack);\n\t\tif (_targetType.category() == Type::Category::FixedBytes)\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\ttypeOnStack.isByteArray(),\n\t\t\t\t\"Array types other than bytes not convertible to bytesNN.\"\n\t\t\t);\n\t\t\tsolAssert(typeOnStack.isDynamicallySized());\n\n\t\t\tbool fromCalldata = typeOnStack.dataStoredIn(DataLocation::CallData);\n\t\t\tsolAssert(typeOnStack.sizeOnStack() == (fromCalldata ? 2 : 1));\n\t\t\tif (fromCalldata)\n\t\t\t\tm_context << Instruction::SWAP1;\n\n\t\t\tm_context.callYulFunction(\n\t\t\t\tm_context.utilFunctions().bytesToFixedBytesConversionFunction(\n\t\t\t\t\ttypeOnStack,\n\t\t\t\t\tdynamic_cast<FixedBytesType const &>(_targetType)\n\t\t\t\t),\n\t\t\t\ttypeOnStack.sizeOnStack(),\n\t\t\t\t1\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tsolAssert(targetTypeCategory == stackTypeCategory);\n\t\tauto const& targetType = dynamic_cast<ArrayType const&>(_targetType);\n\t\tswitch (targetType.location())\n\t\t{\n\t\tcase DataLocation::Storage:\n\t\t\t// Other cases are done explicitly in LValue::storeValue, and only possible by assignment.\n\t\t\tsolAssert(\n\t\t\t\t(targetType.isPointer() || (typeOnStack.isByteArrayOrString() && targetType.isByteArrayOrString())) &&\n\t\t\t\ttypeOnStack.location() == DataLocation::Storage,\n\t\t\t\t\"Invalid conversion to storage type.\"\n\t\t\t);\n\t\t\tbreak;\n\t\tcase DataLocation::Transient:\n\t\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\t\tbreak;\n\t\tcase DataLocation::Memory:\n\t\t{\n\t\t\t// Copy the array to a free position in memory, unless it is already in memory.\n\t\t\tif (typeOnStack.location() != DataLocation::Memory)\n\t\t\t{\n\t\t\t\tif (\n\t\t\t\t\ttypeOnStack.dataStoredIn(DataLocation::CallData) &&\n\t\t\t\t\ttypeOnStack.baseType()->isDynamicallyEncoded()\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tsolAssert(m_context.useABICoderV2());\n\t\t\t\t\t// stack: offset length(optional in case of dynamically sized array)\n\t\t\t\t\tsolAssert(typeOnStack.sizeOnStack() == (typeOnStack.isDynamicallySized() ? 2 : 1));\n\t\t\t\t\tif (typeOnStack.isDynamicallySized())\n\t\t\t\t\t\tm_context << Instruction::SWAP1;\n\n\t\t\t\t\tm_context.callYulFunction(\n\t\t\t\t\t\tm_context.utilFunctions().conversionFunction(typeOnStack, targetType),\n\t\t\t\t\t\ttypeOnStack.isDynamicallySized() ? 2 : 1,\n\t\t\t\t\t\t1\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// stack: <source ref> (variably sized)\n\t\t\t\t\tunsigned stackSize = typeOnStack.sizeOnStack();\n\t\t\t\t\tArrayUtils(m_context).retrieveLength(typeOnStack);\n\n\t\t\t\t\t// allocate memory\n\t\t\t\t\t// stack: <source ref> (variably sized) <length>\n\t\t\t\t\tm_context << Instruction::DUP1;\n\t\t\t\t\tArrayUtils(m_context).convertLengthToSize(targetType, true);\n\t\t\t\t\t// stack: <source ref> (variably sized) <length> <size>\n\t\t\t\t\tif (targetType.isDynamicallySized())\n\t\t\t\t\t\tm_context << u256(0x20) << Instruction::ADD;\n\t\t\t\t\tallocateMemory();\n\t\t\t\t\t// stack: <source ref> (variably sized) <length> <mem start>\n\t\t\t\t\tm_context << Instruction::DUP1;\n\t\t\t\t\tmoveIntoStack(2 + stackSize);\n\t\t\t\t\tif (targetType.isDynamicallySized())\n\t\t\t\t\t{\n\t\t\t\t\t\tm_context << Instruction::DUP2;\n\t\t\t\t\t\tstoreInMemoryDynamic(*TypeProvider::uint256());\n\t\t\t\t\t}\n\t\t\t\t\t// stack: <mem start> <source ref> (variably sized) <length> <mem data pos>\n\t\t\t\t\tif (targetType.baseType()->isValueType())\n\t\t\t\t\t{\n\t\t\t\t\t\tcopyToStackTop(2 + stackSize, stackSize);\n\t\t\t\t\t\tArrayUtils(m_context).copyArrayToMemory(typeOnStack);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tm_context << u256(0) << Instruction::SWAP1;\n\t\t\t\t\t\t// stack: <mem start> <source ref> (variably sized) <length> <counter> <mem data pos>\n\t\t\t\t\t\tauto repeat = m_context.newTag();\n\t\t\t\t\t\tm_context << repeat;\n\t\t\t\t\t\tm_context << Instruction::DUP3 << Instruction::DUP3;\n\t\t\t\t\t\tm_context << Instruction::LT << Instruction::ISZERO;\n\t\t\t\t\t\tauto loopEnd = m_context.appendConditionalJump();\n\t\t\t\t\t\tcopyToStackTop(3 + stackSize, stackSize);\n\t\t\t\t\t\tcopyToStackTop(2 + stackSize, 1);\n\t\t\t\t\t\tArrayUtils(m_context).accessIndex(typeOnStack, false);\n\t\t\t\t\t\tif (typeOnStack.location() == DataLocation::Storage)\n\t\t\t\t\t\t\tStorageItem(m_context, *typeOnStack.baseType()).retrieveValue(SourceLocation(), true);\n\t\t\t\t\t\tconvertType(*typeOnStack.baseType(), *targetType.baseType(), _cleanupNeeded);\n\t\t\t\t\t\tstoreInMemoryDynamic(*targetType.baseType(), true);\n\t\t\t\t\t\tm_context << Instruction::SWAP1 << u256(1) << Instruction::ADD;\n\t\t\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t\t\t\tm_context.appendJumpTo(repeat);\n\t\t\t\t\t\tm_context << loopEnd;\n\t\t\t\t\t\tm_context << Instruction::POP;\n\t\t\t\t\t}\n\t\t\t\t\t// stack: <mem start> <source ref> (variably sized) <length> <mem data pos updated>\n\t\t\t\t\tpopStackSlots(2 + stackSize);\n\t\t\t\t\t// Stack: <mem start>\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DataLocation::CallData:\n\t\t\tsolAssert(\n\t\t\t\t((targetType.isByteArrayOrString() && typeOnStack.isByteArrayOrString()) || _typeOnStack == _targetType) &&\n\t\t\t\ttypeOnStack.location() == DataLocation::CallData,\n\t\t\t\t\"Invalid conversion to calldata type.\"\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\t}\n\tcase Type::Category::ArraySlice:\n\t{\n\t\tauto& typeOnStack = dynamic_cast<ArraySliceType const&>(_typeOnStack);\n\t\tif (_targetType.category() == Type::Category::FixedBytes)\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\ttypeOnStack.arrayType().isByteArray(),\n\t\t\t\t\"Array types other than bytes not convertible to bytesNN.\"\n\t\t\t);\n\t\t\tsolAssert(typeOnStack.isDynamicallySized());\n\t\t\tsolAssert(typeOnStack.dataStoredIn(DataLocation::CallData));\n\t\t\tsolAssert(typeOnStack.sizeOnStack() == 2);\n\n\t\t\tm_context << Instruction::SWAP1;\n\t\t\tm_context.callYulFunction(\n\t\t\t\tm_context.utilFunctions().bytesToFixedBytesConversionFunction(\n\t\t\t\t\ttypeOnStack.arrayType(),\n\t\t\t\t\tdynamic_cast<FixedBytesType const &>(_targetType)\n\t\t\t\t),\n\t\t\t\t2,\n\t\t\t\t1\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\n\t\tsolAssert(_targetType.category() == Type::Category::Array);\n\t\tauto const& targetArrayType = dynamic_cast<ArrayType const&>(_targetType);\n\t\tsolAssert(\n\t\t\ttypeOnStack.arrayType().isImplicitlyConvertibleTo(targetArrayType) ||\n\t\t\t(typeOnStack.arrayType().isByteArrayOrString() && targetArrayType.isByteArrayOrString())\n\t\t);\n\t\tsolAssert(\n\t\t\ttypeOnStack.arrayType().dataStoredIn(DataLocation::CallData) &&\n\t\t\ttypeOnStack.arrayType().isDynamicallySized() &&\n\t\t\t!typeOnStack.arrayType().baseType()->isDynamicallyEncoded()\n\t\t);\n\t\tif (!_targetType.dataStoredIn(DataLocation::CallData))\n\t\t\treturn convertType(typeOnStack.arrayType(), _targetType);\n\t\tbreak;\n\t}\n\tcase Type::Category::Struct:\n\t{\n\t\tsolAssert(targetTypeCategory == stackTypeCategory);\n\t\tauto& targetType = dynamic_cast<StructType const&>(_targetType);\n\t\tauto& typeOnStack = dynamic_cast<StructType const&>(_typeOnStack);\n\t\tswitch (targetType.location())\n\t\t{\n\t\tcase DataLocation::Storage:\n\t\t\t// Other cases are done explicitly in LValue::storeValue, and only possible by assignment.\n\t\t\tsolAssert(\n\t\t\t\ttargetType.isPointer() &&\n\t\t\t\ttypeOnStack.location() == DataLocation::Storage,\n\t\t\t\t\"Invalid conversion to storage type.\"\n\t\t\t);\n\t\t\tbreak;\n\t\tcase DataLocation::Transient:\n\t\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\t\tbreak;\n\t\tcase DataLocation::Memory:\n\t\t\t// Copy the array to a free position in memory, unless it is already in memory.\n\t\t\tswitch (typeOnStack.location())\n\t\t\t{\n\t\t\tcase DataLocation::Storage:\n\t\t\t{\n\t\t\t\tauto conversionImpl =\n\t\t\t\t\t[typeOnStack = &typeOnStack, targetType = &targetType](CompilerContext& _context)\n\t\t\t\t{\n\t\t\t\t\tCompilerUtils utils(_context);\n\t\t\t\t\t// stack: <source ref>\n\t\t\t\t\tutils.allocateMemory(typeOnStack->memoryDataSize());\n\t\t\t\t\t_context << Instruction::SWAP1 << Instruction::DUP2;\n\t\t\t\t\t// stack: <memory ptr> <source ref> <memory ptr>\n\t\t\t\t\tfor (auto const& member: typeOnStack->members(nullptr))\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(!member.type->containsNestedMapping());\n\t\t\t\t\t\tstd::pair<u256, unsigned> const& offsets = typeOnStack->storageOffsetsOfMember(member.name);\n\t\t\t\t\t\t_context << offsets.first << Instruction::DUP3 << Instruction::ADD;\n\t\t\t\t\t\t_context << u256(offsets.second);\n\t\t\t\t\t\tStorageItem(_context, *member.type).retrieveValue(SourceLocation(), true);\n\t\t\t\t\t\tType const* targetMemberType = targetType->memberType(member.name);\n\t\t\t\t\t\tsolAssert(!!targetMemberType, \"Member not found in target type.\");\n\t\t\t\t\t\tutils.convertType(*member.type, *targetMemberType, true);\n\t\t\t\t\t\tutils.storeInMemoryDynamic(*targetMemberType, true);\n\t\t\t\t\t}\n\t\t\t\t\t_context << Instruction::POP << Instruction::POP;\n\t\t\t\t};\n\t\t\t\tif (typeOnStack.recursive())\n\t\t\t\t\tm_context.callLowLevelFunction(\n\t\t\t\t\t\t\"$convertRecursiveArrayStorageToMemory_\" + typeOnStack.identifier() + \"_to_\" + targetType.identifier(),\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\tconversionImpl\n\t\t\t\t\t);\n\t\t\t\telse\n\t\t\t\t\tconversionImpl(m_context);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DataLocation::Transient:\n\t\t\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\t\t\tbreak;\n\t\t\tcase DataLocation::CallData:\n\t\t\t{\n\t\t\t\tif (typeOnStack.isDynamicallyEncoded())\n\t\t\t\t{\n\t\t\t\t\tsolAssert(m_context.useABICoderV2());\n\t\t\t\t\tm_context.callYulFunction(\n\t\t\t\t\t\tm_context.utilFunctions().conversionFunction(typeOnStack, targetType),\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t1\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tm_context << Instruction::DUP1;\n\t\t\t\t\tm_context << Instruction::CALLDATASIZE;\n\t\t\t\t\tm_context << Instruction::SUB;\n\t\t\t\t\tabiDecode({&targetType}, false);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DataLocation::Memory:\n\t\t\t\t// nothing to do\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase DataLocation::CallData:\n\t\t\tsolAssert(_typeOnStack == _targetType);\n\t\t\t// nothing to do\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\t}\n\tcase Type::Category::Tuple:\n\t{\n\t\tTupleType const& sourceTuple = dynamic_cast<TupleType const&>(_typeOnStack);\n\t\tTupleType const& targetTuple = dynamic_cast<TupleType const&>(_targetType);\n\t\tsolAssert(targetTuple.components().size() == sourceTuple.components().size());\n\t\tunsigned depth = sourceTuple.sizeOnStack();\n\t\tfor (size_t i = 0; i < sourceTuple.components().size(); ++i)\n\t\t{\n\t\t\tType const* sourceType = sourceTuple.components()[i];\n\t\t\tType const* targetType = targetTuple.components()[i];\n\t\t\tif (!sourceType)\n\t\t\t{\n\t\t\t\tsolAssert(!targetType);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tunsigned sourceSize = sourceType->sizeOnStack();\n\t\t\tunsigned targetSize = targetType ? targetType->sizeOnStack() : 0;\n\t\t\tif (!targetType || *sourceType != *targetType || _cleanupNeeded)\n\t\t\t{\n\t\t\t\tif (targetType)\n\t\t\t\t{\n\t\t\t\t\tif (sourceSize > 0)\n\t\t\t\t\t\tcopyToStackTop(depth, sourceSize);\n\t\t\t\t\tconvertType(*sourceType, *targetType, _cleanupNeeded);\n\t\t\t\t}\n\t\t\t\tif (sourceSize > 0 || targetSize > 0)\n\t\t\t\t{\n\t\t\t\t\t// Move it back into its place.\n\t\t\t\t\tfor (unsigned j = 0; j < std::min(sourceSize, targetSize); ++j)\n\t\t\t\t\t\tm_context <<\n\t\t\t\t\t\t\tswapInstruction(depth + targetSize - sourceSize) <<\n\t\t\t\t\t\t\tInstruction::POP;\n\t\t\t\t\t// Value shrank\n\t\t\t\t\tfor (unsigned j = targetSize; j < sourceSize; ++j)\n\t\t\t\t\t{\n\t\t\t\t\t\tmoveToStackTop(depth + targetSize - sourceSize, 1);\n\t\t\t\t\t\tm_context << Instruction::POP;\n\t\t\t\t\t}\n\t\t\t\t\t// Value grew\n\t\t\t\t\tif (targetSize > sourceSize)\n\t\t\t\t\t\tmoveIntoStack(depth - sourceSize, targetSize - sourceSize);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdepth -= sourceSize;\n\t\t}\n\t\tbreak;\n\t}\n\tcase Type::Category::Bool:\n\t\tsolAssert(_targetType == _typeOnStack, \"Invalid conversion for bool.\");\n\t\tif (_cleanupNeeded)\n\t\t\tm_context << Instruction::ISZERO << Instruction::ISZERO;\n\t\tbreak;\n\tdefault:\n\t\t// we used to allow conversions from function to address\n\t\tsolAssert(!(stackTypeCategory == Type::Category::Function && targetTypeCategory == Type::Category::Address));\n\t\tif (stackTypeCategory == Type::Category::Function && targetTypeCategory == Type::Category::Function)\n\t\t{\n\t\t\tFunctionType const& typeOnStack = dynamic_cast<FunctionType const&>(_typeOnStack);\n\t\t\tFunctionType const& targetType = dynamic_cast<FunctionType const&>(_targetType);\n\t\t\tsolAssert(\n\t\t\t\ttypeOnStack.isImplicitlyConvertibleTo(targetType) &&\n\t\t\t\ttypeOnStack.sizeOnStack() == targetType.sizeOnStack() &&\n\t\t\t\t(typeOnStack.kind() == FunctionType::Kind::Internal || typeOnStack.kind() == FunctionType::Kind::External) &&\n\t\t\t\ttypeOnStack.kind() == targetType.kind(),\n\t\t\t\t\"Invalid function type conversion requested.\"\n\t\t\t);\n\t\t}\n\t\telse\n\t\t\t// All other types should not be convertible to non-equal types.\n\t\t\tsolAssert(_typeOnStack == _targetType, \"Invalid type conversion requested.\");\n\n\t\tif (_cleanupNeeded && _targetType.canBeStored() && _targetType.storageBytes() < 32)\n\t\t\tm_context\n\t\t\t\t<< ((u256(1) << (8 * _targetType.storageBytes())) - 1)\n\t\t\t\t<< Instruction::AND;\n\t\tbreak;\n\t}\n\n\tsolAssert(!enumOverflowCheckPending, \"enum overflow checking missing.\");\n\tsolAssert(!chopSignBitsPending, \"forgot to chop the sign bits.\");\n}\n\nvoid CompilerUtils::pushZeroValue(Type const& _type)\n{\n\tif (auto const* funType = dynamic_cast<FunctionType const*>(&_type))\n\t{\n\t\tif (funType->kind() == FunctionType::Kind::Internal)\n\t\t{\n\t\t\tm_context << m_context.lowLevelFunctionTag(\"$invalidFunction\", 0, 0, [](CompilerContext& _context) {\n\t\t\t\t_context.appendPanic(util::PanicCode::InvalidInternalFunction);\n\t\t\t});\n\t\t\tif (CompilerContext* runCon = m_context.runtimeContext())\n\t\t\t{\n\t\t\t\tleftShiftNumberOnStack(32);\n\t\t\t\tm_context << runCon->lowLevelFunctionTag(\"$invalidFunction\", 0, 0, [](CompilerContext& _context) {\n\t\t\t\t\t_context.appendPanic(util::PanicCode::InvalidInternalFunction);\n\t\t\t\t}).toSubAssemblyTag(m_context.runtimeSub());\n\t\t\t\tm_context << Instruction::OR;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t}\n\tauto const* referenceType = dynamic_cast<ReferenceType const*>(&_type);\n\tif (!referenceType || referenceType->location() == DataLocation::Storage)\n\t{\n\t\tfor (size_t i = 0; i < _type.sizeOnStack(); ++i)\n\t\t\tm_context << u256(0);\n\t\treturn;\n\t}\n\tif (referenceType->location() == DataLocation::CallData)\n\t{\n\t\tsolAssert(referenceType->sizeOnStack() == 1 || referenceType->sizeOnStack() == 2);\n\t\tm_context << Instruction::CALLDATASIZE;\n\t\tif (referenceType->sizeOnStack() == 2)\n\t\t\tm_context << 0;\n\t\treturn;\n\t}\n\n\tsolAssert(referenceType->location() == DataLocation::Memory);\n\tif (auto arrayType = dynamic_cast<ArrayType const*>(&_type))\n\t\tif (arrayType->isDynamicallySized())\n\t\t{\n\t\t\t// Push a memory location that is (hopefully) always zero.\n\t\t\tpushZeroPointer();\n\t\t\treturn;\n\t\t}\n\n\tType const* type = &_type;\n\tm_context.callLowLevelFunction(\n\t\t\"$pushZeroValue_\" + referenceType->identifier(),\n\t\t0,\n\t\t1,\n\t\t[type](CompilerContext& _context) {\n\t\t\tCompilerUtils utils(_context);\n\n\t\t\tutils.allocateMemory(std::max<u256>(32u, type->memoryDataSize()));\n\t\t\t_context << Instruction::DUP1;\n\n\t\t\tif (auto structType = dynamic_cast<StructType const*>(type))\n\t\t\t\tfor (auto const& member: structType->members(nullptr))\n\t\t\t\t{\n\t\t\t\t\tutils.pushZeroValue(*member.type);\n\t\t\t\t\tutils.storeInMemoryDynamic(*member.type);\n\t\t\t\t}\n\t\t\telse if (auto arrayType = dynamic_cast<ArrayType const*>(type))\n\t\t\t{\n\t\t\t\tsolAssert(!arrayType->isDynamicallySized());\n\t\t\t\tif (arrayType->length() > 0)\n\t\t\t\t{\n\t\t\t\t\t_context << arrayType->length() << Instruction::SWAP1;\n\t\t\t\t\t// stack: items_to_do memory_pos\n\t\t\t\t\tutils.zeroInitialiseMemoryArray(*arrayType);\n\t\t\t\t\t// stack: updated_memory_pos\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tsolAssert(false, \"Requested initialisation for unknown type: \" + type->toString());\n\n\t\t\t// remove the updated memory pointer\n\t\t\t_context << Instruction::POP;\n\t\t}\n\t);\n}\n\nvoid CompilerUtils::pushZeroPointer()\n{\n\tm_context << u256(zeroPointer);\n}\n\nvoid CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable)\n{\n\tunsigned const stackPosition = m_context.baseToCurrentStackOffset(m_context.baseStackOffsetOfVariable(_variable));\n\tunsigned const size = _variable.annotation().type->sizeOnStack();\n\tsolAssert(stackPosition >= size, \"Variable size and position mismatch.\");\n\t// move variable starting from its top end in the stack\n\tif (stackPosition - size + 1 > m_context.reachableStackDepth())\n\t\tBOOST_THROW_EXCEPTION(\n\t\t\tStackTooDeepError() <<\n\t\t\terrinfo_sourceLocation(_variable.location()) <<\n\t\t\tutil::errinfo_comment(util::stackTooDeepString)\n\t\t);\n\tfor (unsigned i = 0; i < size; ++i)\n\t\tm_context << swapInstruction(stackPosition - size + 1) << Instruction::POP;\n}\n\nvoid CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)\n{\n\tassertThrow(\n\t\t_stackDepth <= m_context.reachableStackDepth(),\n\t\tStackTooDeepError,\n\t\tutil::stackTooDeepString\n\t);\n\tfor (unsigned i = 0; i < _itemSize; ++i)\n\t\tm_context << dupInstruction(_stackDepth);\n}\n\nvoid CompilerUtils::moveToStackTop(unsigned _stackDepth, unsigned _itemSize)\n{\n\tmoveIntoStack(_itemSize, _stackDepth);\n}\n\nvoid CompilerUtils::moveIntoStack(unsigned _stackDepth, unsigned _itemSize)\n{\n\tif (_stackDepth <= _itemSize)\n\t\tfor (unsigned i = 0; i < _stackDepth; ++i)\n\t\t\trotateStackDown(_stackDepth + _itemSize);\n\telse\n\t\tfor (unsigned i = 0; i < _itemSize; ++i)\n\t\t\trotateStackUp(_stackDepth + _itemSize);\n}\n\nvoid CompilerUtils::rotateStackUp(unsigned _items)\n{\n\tassertThrow(\n\t\t_items - 1 <= m_context.reachableStackDepth(),\n\t\tStackTooDeepError,\n\t\tutil::stackTooDeepString\n\t);\n\tfor (unsigned i = 1; i < _items; ++i)\n\t\tm_context << swapInstruction(_items - i);\n}\n\nvoid CompilerUtils::rotateStackDown(unsigned _items)\n{\n\tassertThrow(\n\t\t_items - 1 <= m_context.reachableStackDepth(),\n\t\tStackTooDeepError,\n\t\tutil::stackTooDeepString\n\t);\n\tfor (unsigned i = 1; i < _items; ++i)\n\t\tm_context << swapInstruction(i);\n}\n\nvoid CompilerUtils::popStackElement(Type const& _type)\n{\n\tpopStackSlots(_type.sizeOnStack());\n}\n\nvoid CompilerUtils::popStackSlots(size_t _amount)\n{\n\tfor (size_t i = 0; i < _amount; ++i)\n\t\tm_context << Instruction::POP;\n}\n\nvoid CompilerUtils::popAndJump(unsigned _toHeight, evmasm::AssemblyItem const& _jumpTo)\n{\n\tsolAssert(m_context.stackHeight() >= _toHeight);\n\tunsigned amount = m_context.stackHeight() - _toHeight;\n\tpopStackSlots(amount);\n\tm_context.appendJumpTo(_jumpTo);\n\tm_context.adjustStackOffset(static_cast<int>(amount));\n}\n\nunsigned CompilerUtils::sizeOnStack(std::vector<Type const*> const& _variableTypes)\n{\n\tunsigned size = 0;\n\tfor (Type const* type: _variableTypes)\n\t\tsize += type->sizeOnStack();\n\treturn size;\n}\n\nvoid CompilerUtils::computeHashStatic()\n{\n\tstoreInMemory(0);\n\tm_context << u256(32) << u256(0) << Instruction::KECCAK256;\n}\n\nvoid CompilerUtils::copyContractCodeToMemory(ContractDefinition const& contract, bool _creation)\n{\n\tstd::string which = _creation ? \"Creation\" : \"Runtime\";\n\tm_context.callLowLevelFunction(\n\t\t\"$copyContract\" + which + \"CodeToMemory_\" + contract.type()->identifier(),\n\t\t1,\n\t\t1,\n\t\t[&contract, _creation](CompilerContext& _context)\n\t\t{\n\t\t\t// copy the contract's code into memory\n\t\t\tstd::shared_ptr<evmasm::Assembly> assembly =\n\t\t\t\t_creation ?\n\t\t\t\t_context.compiledContract(contract) :\n\t\t\t\t_context.compiledContractRuntime(contract);\n\t\t\t// pushes size\n\t\t\tauto subroutine = _context.addSubroutine(assembly);\n\t\t\t_context << Instruction::DUP1 << subroutine;\n\t\t\t_context << Instruction::DUP4 << Instruction::CODECOPY;\n\t\t\t_context << Instruction::ADD;\n\t\t}\n\t);\n}\n\nvoid CompilerUtils::storeStringData(bytesConstRef _data)\n{\n\t//@todo provide both alternatives to the optimiser\n\t// stack: mempos\n\tif (_data.size() <= 32)\n\t{\n\t\tfor (unsigned i = 0; i < _data.size(); i += 32)\n\t\t{\n\t\t\tm_context << u256(h256(_data.cropped(i), h256::AlignLeft));\n\t\t\tstoreInMemoryDynamic(*TypeProvider::uint256());\n\t\t}\n\t\tm_context << Instruction::POP;\n\t}\n\telse\n\t{\n\t\t// stack: mempos mempos_data\n\t\tm_context.appendData(_data.toBytes());\n\t\tm_context << u256(_data.size()) << Instruction::SWAP2;\n\t\tm_context << Instruction::CODECOPY;\n\t}\n}\n\nunsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWords)\n{\n\tsolAssert(_type.isValueType());\n\tType const* type = &_type;\n\tif (auto const* userDefined = dynamic_cast<UserDefinedValueType const*>(type))\n\t\ttype = &userDefined->underlyingType();\n\n\tunsigned numBytes = type->calldataEncodedSize(_padToWords);\n\tbool isExternalFunctionType = false;\n\tif (auto const* funType = dynamic_cast<FunctionType const*>(type))\n\t\tif (funType->kind() == FunctionType::Kind::External)\n\t\t\tisExternalFunctionType = true;\n\tif (numBytes == 0)\n\t{\n\t\tm_context << Instruction::POP << u256(0);\n\t\treturn numBytes;\n\t}\n\tsolAssert(numBytes <= 32, \"Static memory load of more than 32 bytes requested.\");\n\tm_context << (_fromCalldata ? Instruction::CALLDATALOAD : Instruction::MLOAD);\n\tbool cleanupNeeded = true;\n\tif (isExternalFunctionType)\n\t\tsplitExternalFunctionType(true);\n\telse if (numBytes != 32)\n\t{\n\t\t// add leading or trailing zeros by dividing/multiplying depending on alignment\n\t\tunsigned shiftFactor = (32 - numBytes) * 8;\n\t\trightShiftNumberOnStack(shiftFactor);\n\t\tif (type->leftAligned())\n\t\t{\n\t\t\tleftShiftNumberOnStack(shiftFactor);\n\t\t\tcleanupNeeded = false;\n\t\t}\n\t\telse if (IntegerType const* intType = dynamic_cast<IntegerType const*>(type))\n\t\t\tif (!intType->isSigned())\n\t\t\t\tcleanupNeeded = false;\n\t}\n\tif (_fromCalldata)\n\t\tconvertType(_type, *type, cleanupNeeded, false, true);\n\n\treturn numBytes;\n}\n\nvoid CompilerUtils::cleanHigherOrderBits(IntegerType const& _typeOnStack)\n{\n\tif (_typeOnStack.numBits() == 256)\n\t\treturn;\n\telse if (_typeOnStack.isSigned())\n\t\tm_context << u256(_typeOnStack.numBits() / 8 - 1) << Instruction::SIGNEXTEND;\n\telse\n\t\tm_context << ((u256(1) << _typeOnStack.numBits()) - 1) << Instruction::AND;\n}\n\nvoid CompilerUtils::leftShiftNumberOnStack(unsigned _bits)\n{\n\tsolAssert(_bits < 256);\n\tif (m_context.evmVersion().hasBitwiseShifting())\n\t\tm_context << _bits << Instruction::SHL;\n\telse\n\t\tm_context << (u256(1) << _bits) << Instruction::MUL;\n}\n\nvoid CompilerUtils::rightShiftNumberOnStack(unsigned _bits)\n{\n\tsolAssert(_bits < 256);\n\t// NOTE: If we add signed right shift, SAR rounds differently than SDIV\n\tif (m_context.evmVersion().hasBitwiseShifting())\n\t\tm_context << _bits << Instruction::SHR;\n\telse\n\t\tm_context << (u256(1) << _bits) << Instruction::SWAP1 << Instruction::DIV;\n}\n\nunsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWords, bool _cleanup)\n{\n\tsolAssert(\n\t\t_type.sizeOnStack() == 1,\n\t\t\"Memory store of types with stack size != 1 not allowed (Type: \" + _type.toString(true) + \").\"\n\t);\n\n\tsolAssert(!_type.isDynamicallyEncoded());\n\n\tunsigned numBytes = _type.calldataEncodedSize(_padToWords);\n\n\tsolAssert(\n\t\tnumBytes > 0,\n\t\t\"Memory store of 0 bytes requested (Type: \" + _type.toString(true) + \").\"\n\t);\n\n\tsolAssert(\n\t\tnumBytes <= 32,\n\t\t\"Memory store of more than 32 bytes requested (Type: \" + _type.toString(true) + \").\"\n\t);\n\n\tif (_cleanup)\n\t\tconvertType(_type, _type, true);\n\n\tif (numBytes != 32 && !_type.leftAligned() && !_padToWords)\n\t\t// shift the value accordingly before storing\n\t\tleftShiftNumberOnStack((32 - numBytes) * 8);\n\n\treturn numBytes;\n}\n"
  },
  {
    "path": "libsolidity/codegen/CompilerUtils.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Routines used by both the compiler and the expression compiler.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/interface/DebugSettings.h>\n#include <libsolidity/codegen/CompilerContext.h>\n#include <libsolidity/codegen/CompilerContext.h>\n\nnamespace solidity::frontend\n{\n\nclass Type; // forward\n\nclass CompilerUtils\n{\npublic:\n\texplicit CompilerUtils(CompilerContext& _context): m_context(_context)\n\t{}\n\n\t/// Stores the initial value of the free-memory-pointer at its position;\n\tvoid initialiseFreeMemoryPointer();\n\t/// Copies the free memory pointer to the stack.\n\t/// Stack pre:\n\t/// Stack post: <mem_start>\n\tvoid fetchFreeMemoryPointer();\n\t/// Stores the free memory pointer from the stack.\n\t/// Stack pre: <mem_end>\n\t/// Stack post:\n\tvoid storeFreeMemoryPointer();\n\t/// Allocates a number of bytes in memory as given on the stack.\n\t/// Stack pre: <size>\n\t/// Stack post: <mem_start>\n\tvoid allocateMemory();\n\t/// Allocates a number of bytes in memory as given on the stack.\n\t/// Stack pre:\n\t/// Stack post: <mem_start>\n\tvoid allocateMemory(u256 const& size);\n\t/// Appends code that transforms memptr to (memptr - free_memptr) memptr\n\t/// Stack pre: <mem_end>\n\t/// Stack post: <size> <mem_start>\n\tvoid toSizeAfterFreeMemoryPointer();\n\n\t/// Appends code that performs a revert, providing the given string data.\n\t/// Will also append an error signature corresponding to Error(string).\n\t/// @param _argumentType the type of the string argument, will be converted to memory string.\n\t/// Stack pre: string data\n\t/// Stack post:\n\tvoid revertWithStringData(Type const& _argumentType);\n\n\tvoid revertWithError(\n\t\tstd::string const& _errorName,\n\t\tstd::vector<Type const*> const& _parameterTypes,\n\t\tstd::vector<Type const*> const& _argumentTypes\n\t);\n\n\t/// Allocates a new array and copies the return data to it.\n\t/// If the EVM does not support return data, creates an empty array.\n\tvoid returnDataToArray();\n\n\t/// Computes the absolute calldata offset of a tail given a base reference and the (absolute)\n\t/// offset of the tail pointer. Performs bounds checks. If @a _type is a dynamically sized array it also\n\t/// returns the array length on the stack.\n\t/// Stack pre: base_ref tail_ptr\n\t/// Stack post: tail_ref [length]\n\tvoid accessCalldataTail(Type const& _type);\n\n\t/// Loads data from memory to the stack.\n\t/// @param _offset offset in memory (or calldata)\n\t/// @param _type data type to load\n\t/// @param _fromCalldata if true, load from calldata, not from memory\n\t/// @param _padToWords if true, assume the data is padded to full words (32 bytes)\n\t/// @returns the number of bytes consumed in memory.\n\tunsigned loadFromMemory(\n\t\tunsigned _offset,\n\t\tType const& _type,\n\t\tbool _fromCalldata,\n\t\tbool _padToWords\n\t);\n\t/// Dynamic version of @see loadFromMemory, expects the memory offset on the stack.\n\t/// Stack pre: memory_offset\n\t/// Stack post: value... (memory_offset+length)\n\tvoid loadFromMemoryDynamic(\n\t\tType const& _type,\n\t\tbool _fromCalldata = false,\n\t\tbool _padToWords = true,\n\t\tbool _keepUpdatedMemoryOffset = true\n\t);\n\t/// Stores a 256 bit integer from stack in memory.\n\t/// @param _offset offset in memory\n\tvoid storeInMemory(unsigned _offset);\n\n\t/// Dynamic version of @see storeInMemory, expects the memory offset below the value on the stack\n\t/// and also updates that. For reference types, only copies the data pointer. Fails for\n\t/// non-memory-references. For string literals no value is available on the stack.\n\t/// @param _padToWords if true, adds zeros to pad to multiple of 32 bytes. Array elements\n\t///                    are always padded (except for byte arrays), regardless of this parameter.\n\t/// @param _cleanup if true, adds code to cleanup the value before storing it.\n\t/// Stack pre: memory_offset value...\n\t/// Stack post: (memory_offset+length)\n\tvoid storeInMemoryDynamic(Type const& _type, bool _padToWords = true, bool _cleanup = true);\n\n\t/// Creates code that unpacks the arguments according to their types specified by a vector of TypePointers.\n\t/// From memory if @a _fromMemory is true, otherwise from call data.\n\t/// Calls revert if the supplied size is shorter than the static data requirements\n\t/// or if dynamic data pointers reach outside of the area.\n\t/// Also has a hard cap of 0x100000000 for any given length/offset field.\n\t/// Stack pre: <source_offset> <length>\n\t/// Stack post: <value0> <value1> ... <valuen>\n\tvoid abiDecode(TypePointers const& _typeParameters, bool _fromMemory = false);\n\n\t/// Copies values (of types @a _givenTypes) given on the stack to a location in memory given\n\t/// at the stack top, encoding them according to the ABI as the given types @a _targetTypes.\n\t/// Removes the values from the stack and leaves the updated memory pointer.\n\t/// Stack pre: <v1> <v2> ... <vn> <memptr>\n\t/// Stack post: <memptr_updated>\n\t/// Does not touch the memory-free pointer.\n\t/// @param _padToWords if false, all values are concatenated without padding.\n\t/// @param _copyDynamicDataInPlace if true, dynamic types is stored (without length)\n\t/// together with fixed-length data.\n\t/// @param _encodeAsLibraryTypes if true, encodes for a library function, e.g. does not\n\t/// convert storage pointer types to memory types.\n\t/// @note the locations of target reference types are ignored, because it will always be\n\t/// memory.\n\tvoid encodeToMemory(\n\t\tTypePointers const& _givenTypes,\n\t\tTypePointers const& _targetTypes,\n\t\tbool _padToWords,\n\t\tbool _copyDynamicDataInPlace,\n\t\tbool _encodeAsLibraryTypes = false\n\t);\n\n\t/// Special case of @a encodeToMemory which assumes tight packing, e.g. no zero padding\n\t/// and dynamic data is encoded in-place.\n\t/// Stack pre: <value0> <value1> ... <valueN-1> <head_start>\n\t/// Stack post: <mem_ptr>\n\tvoid packedEncode(\n\t\tTypePointers const& _givenTypes,\n\t\tTypePointers const& _targetTypes,\n\t\tbool _encodeAsLibraryTypes = false\n\t)\n\t{\n\t\tencodeToMemory(_givenTypes, _targetTypes, false, true, _encodeAsLibraryTypes);\n\t}\n\n\t/// Special case of @a encodeToMemory which assumes that everything is padded to words\n\t/// and dynamic data is not copied in place (i.e. a proper ABI encoding).\n\t/// Stack pre: <value0> <value1> ... <valueN-1> <head_start>\n\t/// Stack post: <mem_ptr>\n\tvoid abiEncode(\n\t\tTypePointers const& _givenTypes,\n\t\tTypePointers const& _targetTypes,\n\t\tbool _encodeAsLibraryTypes = false\n\t)\n\t{\n\t\tencodeToMemory(_givenTypes, _targetTypes, true, false, _encodeAsLibraryTypes);\n\t}\n\n\t/// Special case of @a encodeToMemory which assumes that everything is padded to words\n\t/// and dynamic data is not copied in place (i.e. a proper ABI encoding).\n\t/// Uses a new, less tested encoder implementation.\n\t/// Stack pre: <value0> <value1> ... <valueN-1> <head_start>\n\t/// Stack post: <mem_ptr>\n\tvoid abiEncodeV2(\n\t\tTypePointers const& _givenTypes,\n\t\tTypePointers const& _targetTypes,\n\t\tbool _encodeAsLibraryTypes = false,\n\t\tbool _padToWordBoundaries = true\n\t);\n\n\t/// Decodes data from ABI encoding into internal encoding. If @a _fromMemory is set to true,\n\t/// the data is taken from memory instead of from calldata.\n\t/// Can allocate memory.\n\t/// Stack pre: <source_offset> <length>\n\t/// Stack post: <value0> <value1> ... <valuen>\n\tvoid abiDecodeV2(TypePointers const& _parameterTypes, bool _fromMemory = false);\n\n\t/// Zero-initialises (the data part of) an already allocated memory array.\n\t/// Length has to be nonzero!\n\t/// Stack pre: <length> <memptr>\n\t/// Stack post: <updated_memptr>\n\tvoid zeroInitialiseMemoryArray(ArrayType const& _type);\n\n\t/// Copies full 32 byte words in memory (regions cannot overlap), i.e. may copy more than length.\n\t/// Length can be zero, in this case, it copies nothing.\n\t/// Stack pre: <size> <target> <source>\n\t/// Stack post:\n\tvoid memoryCopy32();\n\t/// Copies data in memory (regions cannot overlap).\n\t/// Length can be zero, in this case, it copies nothing.\n\t/// Stack pre: <size> <target> <source>\n\t/// Stack post:\n\tvoid memoryCopy();\n\n\t/// Stores the given string in memory.\n\t/// Stack pre: mempos\n\t/// Stack post:\n\tvoid storeStringData(bytesConstRef _data);\n\n\t/// Converts the combined and left-aligned (right-aligned if @a _rightAligned is true)\n\t/// external function type <address><function identifier> into two stack slots:\n\t/// address (right aligned), function identifier (right aligned)\n\tvoid splitExternalFunctionType(bool _rightAligned);\n\t/// Performs the opposite operation of splitExternalFunctionType(_rightAligned)\n\tvoid combineExternalFunctionType(bool _rightAligned);\n\t/// Appends code that combines the construction-time (if available) and runtime function\n\t/// entry label of the given function into a single stack slot.\n\t/// Note: This might cause the compilation queue of the runtime context to be extended.\n\t/// If @a _runtimeOnly, the entry label will include the runtime assembly tag.\n\tvoid pushCombinedFunctionEntryLabel(Declaration const& _function, bool _runtimeOnly = true);\n\n\t/// Appends code for an implicit or explicit type conversion. This includes erasing higher\n\t/// order bits (@see appendHighBitCleanup) when widening integer but also copy to memory\n\t/// if a reference type is converted from calldata or storage to memory.\n\t/// If @a _cleanupNeeded, high order bits cleanup is also done if no type conversion would be\n\t/// necessary.\n\t/// If @a _chopSignBits, the function resets the signed bits out of the width of the signed integer.\n\t/// If @a _asPartOfArgumentDecoding is true, failed conversions are flagged via REVERT,\n\t/// otherwise they are flagged with INVALID.\n\tvoid convertType(\n\t\tType const& _typeOnStack,\n\t\tType const& _targetType,\n\t\tbool _cleanupNeeded = false,\n\t\tbool _chopSignBits = false,\n\t\tbool _asPartOfArgumentDecoding = false\n\t);\n\n\t/// Creates a zero-value for the given type and puts it onto the stack. This might allocate\n\t/// memory for memory references.\n\tvoid pushZeroValue(Type const& _type);\n\t/// Pushes a pointer to the stack that points to a (potentially shared) location in memory\n\t/// that always contains a zero. It is not allowed to write there.\n\tvoid pushZeroPointer();\n\n\t/// Moves the value that is at the top of the stack to a stack variable.\n\tvoid moveToStackVariable(VariableDeclaration const& _variable);\n\t/// Copies an item that occupies @a _itemSize stack slots from a stack depth of @a _stackDepth\n\t/// to the top of the stack.\n\tvoid copyToStackTop(unsigned _stackDepth, unsigned _itemSize);\n\t/// Moves an item that occupies @a _itemSize stack slots and has items occupying @a _stackDepth\n\t/// slots above it to the top of the stack.\n\tvoid moveToStackTop(unsigned _stackDepth, unsigned _itemSize = 1);\n\t/// Moves @a _itemSize elements past @a _stackDepth other stack elements\n\tvoid moveIntoStack(unsigned _stackDepth, unsigned _itemSize = 1);\n\t/// Rotates the topmost @a _items items on the stack, such that the previously topmost element\n\t/// is bottom-most.\n\tvoid rotateStackUp(unsigned _items);\n\t/// Rotates the topmost @a _items items on the stack, such that the previously bottom-most element\n\t/// is now topmost.\n\tvoid rotateStackDown(unsigned _items);\n\t/// Removes the current value from the top of the stack.\n\tvoid popStackElement(Type const& _type);\n\t/// Removes element from the top of the stack _amount times.\n\tvoid popStackSlots(size_t _amount);\n\t/// Pops slots from the stack such that its height is _toHeight.\n\t/// Adds jump to _jumpTo.\n\t/// Readjusts the stack offset to the original value.\n\tvoid popAndJump(unsigned _toHeight, evmasm::AssemblyItem const& _jumpTo);\n\n\ttemplate <class T>\n\tstatic unsigned sizeOnStack(std::vector<T> const& _variables);\n\tstatic unsigned sizeOnStack(std::vector<Type const*> const& _variableTypes);\n\n\t/// Helper function to shift top value on the stack to the left.\n\t/// Stack pre: <value> <shift_by_bits>\n\t/// Stack post: <shifted_value>\n\tvoid leftShiftNumberOnStack(unsigned _bits);\n\n\t/// Helper function to shift top value on the stack to the right.\n\t/// Stack pre: <value> <shift_by_bits>\n\t/// Stack post: <shifted_value>\n\tvoid rightShiftNumberOnStack(unsigned _bits);\n\n\t/// Appends code that computes the Keccak-256 hash of the topmost stack element of 32 byte type.\n\tvoid computeHashStatic();\n\n\t/// Appends code that copies the code of the given contract to memory.\n\t/// Stack pre: Memory position\n\t/// Stack post: Updated memory position\n\t/// @param creation if true, copies creation code, if false copies runtime code.\n\t/// @note the contract has to be compiled already, so beware of cyclic dependencies!\n\tvoid copyContractCodeToMemory(ContractDefinition const& contract, bool _creationCode);\n\n\t/// Bytes we need to the start of call data.\n\t///  - The size in bytes of the function (hash) identifier.\n\tstatic unsigned const dataStartOffset;\n\n\t/// Position of the free-memory-pointer in memory;\n\tstatic size_t const freeMemoryPointer;\n\t/// Position of the memory slot that is always zero.\n\tstatic size_t const zeroPointer;\n\t/// Starting offset for memory available to the user (aka the contract).\n\tstatic size_t const generalPurposeMemoryStart;\n\nprivate:\n\t/// Appends code that cleans higher-order bits for integer types.\n\tvoid cleanHigherOrderBits(IntegerType const& _typeOnStack);\n\n\t/// Prepares the given type for storing in memory by shifting it if necessary.\n\t/// @param _cleanup if true, also cleanup the value when preparing to store it in memory\n\tunsigned prepareMemoryStore(Type const& _type, bool _padToWords, bool _cleanup = true);\n\t/// Loads type from memory assuming memory offset is on stack top.\n\tunsigned loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWords);\n\n\tCompilerContext& m_context;\n};\n\n\ntemplate <class T>\nunsigned CompilerUtils::sizeOnStack(std::vector<T> const& _variables)\n{\n\tunsigned size = 0;\n\tfor (T const& variable: _variables)\n\t\tsize += variable->annotation().type->sizeOnStack();\n\treturn size;\n}\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ContractCompiler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity compiler.\n */\n\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTUtils.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/codegen/CompilerUtils.h>\n#include <libsolidity/codegen/ContractCompiler.h>\n#include <libsolidity/codegen/ExpressionCompiler.h>\n\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AST.h>\n#include <libyul/backends/evm/AsmCodeGen.h>\n#include <libyul/backends/evm/EVMMetrics.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/optimiser/Suite.h>\n#include <libyul/Object.h>\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/YulName.h>\n\n#include <libevmasm/Instruction.h>\n#include <libevmasm/Assembly.h>\n#include <libevmasm/GasMeter.h>\n\n#include <liblangutil/ErrorReporter.h>\n\n#include <libsolutil/Whiskers.h>\n#include <libsolutil/FunctionSelector.h>\n#include <libsolutil/StackTooDeepString.h>\n\n#include <range/v3/view/reverse.hpp>\n\n#include <algorithm>\n#include <limits>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\n\nusing solidity::util::FixedHash;\nusing solidity::util::h256;\nusing solidity::util::errinfo_comment;\n\nnamespace\n{\n\n/**\n * Simple helper class to ensure that the stack height is the same at certain places in the code.\n */\nclass StackHeightChecker\n{\npublic:\n\texplicit StackHeightChecker(CompilerContext const& _context):\n\t\tm_context(_context), stackHeight(m_context.stackHeight()) {}\n\tvoid check()\n\t{\n\t\tsolAssert(\n\t\t\tm_context.stackHeight() == stackHeight,\n\t\t\tstd::string(\"I sense a disturbance in the stack: \") + std::to_string(m_context.stackHeight()) + \" vs \" + std::to_string(stackHeight)\n\t\t);\n\t}\nprivate:\n\tCompilerContext const& m_context;\n\tunsigned stackHeight;\n};\n\n}\n\nvoid ContractCompiler::compileContract(\n\tContractDefinition const& _contract,\n\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers\n)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _contract);\n\n\tif (_contract.isLibrary())\n\t\t// Check whether this is a call (true) or a delegatecall (false).\n\t\t// This has to be the first code in the contract.\n\t\tappendDelegatecallCheck();\n\n\tinitializeContext(_contract, _otherCompilers);\n\t// This generates the dispatch function for externally visible functions\n\t// and adds the function to the compilation queue. Additionally internal functions,\n\t// which are referenced directly or indirectly will be added.\n\tappendFunctionSelector(_contract);\n}\n\nSubAssemblyID ContractCompiler::compileConstructor(\n\tContractDefinition const& _contract,\n\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers\n)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _contract);\n\tif (_contract.isLibrary())\n\t\treturn deployLibrary(_contract);\n\telse\n\t{\n\t\tinitializeContext(_contract, _otherCompilers);\n\t\treturn packIntoContractCreator(_contract);\n\t}\n}\n\nvoid ContractCompiler::initializeContext(\n\tContractDefinition const& _contract,\n\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers\n)\n{\n\tm_context.setUseABICoderV2(*_contract.sourceUnit().annotation().useABICoderV2);\n\tm_context.setOtherCompilers(_otherCompilers);\n\tm_context.setMostDerivedContract(_contract);\n\tif (m_runtimeCompiler)\n\t\tregisterImmutableVariables(_contract);\n\tCompilerUtils(m_context).initialiseFreeMemoryPointer();\n\tregisterStateVariables(_contract);\n\tm_context.resetVisitedNodes(&_contract);\n}\n\nvoid ContractCompiler::appendCallValueCheck()\n{\n\t// Throw if function is not payable but call contained ether.\n\tm_context << Instruction::CALLVALUE;\n\tm_context.appendConditionalRevert(false, \"Ether sent to non-payable function\");\n}\n\nvoid ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _contract)\n{\n\tsolAssert(!_contract.isLibrary(), \"Tried to initialize library.\");\n\tCompilerContext::LocationSetter locationSetter(m_context, _contract);\n\n\tm_baseArguments = &_contract.annotation().baseConstructorArguments;\n\n\t// Initialization of state variables in base-to-derived order.\n\tfor (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts | ranges::views::reverse)\n\t\tinitializeStateVariables(*contract);\n\n\tif (FunctionDefinition const* constructor = _contract.constructor())\n\t\tappendConstructor(*constructor);\n\telse\n\t{\n\t\t// Implicit constructors are always non-payable.\n\t\tappendCallValueCheck();\n\t\tif (auto c = _contract.nextConstructor(m_context.mostDerivedContract()))\n\t\t\tappendBaseConstructor(*c);\n\t}\n}\n\nSubAssemblyID ContractCompiler::packIntoContractCreator(ContractDefinition const& _contract)\n{\n\tsolAssert(!!m_runtimeCompiler, \"\");\n\tsolAssert(!_contract.isLibrary(), \"Tried to use contract creator or library.\");\n\n\tappendInitAndConstructorCode(_contract);\n\n\t// We jump to the deploy routine because we first have to append all missing functions,\n\t// which can cause further functions to be added to the runtime context.\n\tevmasm::AssemblyItem deployRoutine = m_context.appendJumpToNew();\n\n\t// We have to include copies of functions in the construction time and runtime context\n\t// because of absolute jumps.\n\tappendMissingFunctions();\n\tm_runtimeCompiler->appendMissingFunctions();\n\n\tCompilerContext::LocationSetter locationSetter(m_context, _contract);\n\tm_context << deployRoutine;\n\n\tsolAssert(!m_context.runtimeSub().empty(), \"Runtime sub not registered\");\n\n\tContractType contractType(_contract);\n\tauto const& immutables = contractType.immutableVariables();\n\t// Push all immutable values on the stack.\n\tfor (auto const& immutable: immutables)\n\t\tCompilerUtils(m_context).loadFromMemory(\n\t\t\tstatic_cast<unsigned>(m_context.immutableMemoryOffset(*immutable)),\n\t\t\t*immutable->annotation().type,\n\t\t\tfalse,\n\t\t\ttrue\n\t);\n\tm_context.pushSubroutineSize(m_context.runtimeSub());\n\tif (immutables.empty())\n\t\tm_context << Instruction::DUP1;\n\tm_context.pushSubroutineOffset(m_context.runtimeSub());\n\tm_context << u256(0) << Instruction::CODECOPY;\n\t// Assign immutable values from stack in reversed order.\n\tfor (auto const& immutable: immutables | ranges::views::reverse)\n\t{\n\t\tauto slotNames = m_context.immutableVariableSlotNames(*immutable);\n\t\tfor (auto&& slotName: slotNames | ranges::views::reverse)\n\t\t{\n\t\t\tm_context << u256(0);\n\t\t\tm_context.appendImmutableAssignment(slotName);\n\t\t}\n\t}\n\tif (!immutables.empty())\n\t\tm_context.pushSubroutineSize(m_context.runtimeSub());\n\tm_context << u256(0) << Instruction::RETURN;\n\n\treturn m_context.runtimeSub();\n}\n\nSubAssemblyID ContractCompiler::deployLibrary(ContractDefinition const& _contract)\n{\n\tsolAssert(!!m_runtimeCompiler, \"\");\n\tsolAssert(_contract.isLibrary(), \"Tried to deploy contract as library.\");\n\n\tappendMissingFunctions();\n\tm_runtimeCompiler->appendMissingFunctions();\n\n\tCompilerContext::LocationSetter locationSetter(m_context, _contract);\n\n\tsolAssert(!m_context.runtimeSub().empty(), \"Runtime sub not registered\");\n\tm_context.pushSubroutineSize(m_context.runtimeSub());\n\tm_context.pushSubroutineOffset(m_context.runtimeSub());\n\t// This code replaces the address added by appendDeployTimeAddress().\n\tm_context.appendInlineAssembly(\n\t\tutil::Whiskers(R\"(\n\t\t{\n\t\t\t// If code starts at 11, an mstore(0) writes to the full PUSH20 plus data\n\t\t\t// without the need for a shift.\n\t\t\tlet codepos := 11\n\t\t\tcodecopy(codepos, subOffset, subSize)\n\t\t\t// Check that the first opcode is a PUSH20\n\t\t\tif iszero(eq(0x73, byte(0, mload(codepos)))) {\n\t\t\t\tmstore(0, <panicSelector>)\n\t\t\t\tmstore(4, <panicCode>)\n\t\t\t\trevert(0, 0x24)\n\t\t\t}\n\t\t\tmstore(0, address())\n\t\t\tmstore8(codepos, 0x73)\n\t\t\treturn(codepos, subSize)\n\t\t}\n\t\t)\")\n\t\t(\"panicSelector\", util::selectorFromSignatureU256(\"Panic(uint256)\").str())\n\t\t(\"panicCode\", \"0\")\n\t\t.render(),\n\t\t{\"subSize\", \"subOffset\"}\n\t);\n\n\treturn m_context.runtimeSub();\n}\n\nvoid ContractCompiler::appendBaseConstructor(FunctionDefinition const& _constructor)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _constructor);\n\tFunctionType constructorType(_constructor);\n\tif (!constructorType.parameterTypes().empty())\n\t{\n\t\tsolAssert(m_baseArguments, \"\");\n\t\tsolAssert(m_baseArguments->count(&_constructor), \"\");\n\t\tstd::vector<ASTPointer<Expression>> const* arguments = nullptr;\n\t\tASTNode const* baseArgumentNode = m_baseArguments->at(&_constructor);\n\t\tif (auto inheritanceSpecifier = dynamic_cast<InheritanceSpecifier const*>(baseArgumentNode))\n\t\t\targuments = inheritanceSpecifier->arguments();\n\t\telse if (auto modifierInvocation = dynamic_cast<ModifierInvocation const*>(baseArgumentNode))\n\t\t\targuments = modifierInvocation->arguments();\n\t\tsolAssert(arguments, \"\");\n\t\tsolAssert(arguments->size() == constructorType.parameterTypes().size(), \"\");\n\t\tfor (unsigned i = 0; i < arguments->size(); ++i)\n\t\t\tcompileExpression(*(arguments->at(i)), constructorType.parameterTypes()[i]);\n\t}\n\t_constructor.accept(*this);\n}\n\nvoid ContractCompiler::appendConstructor(FunctionDefinition const& _constructor)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _constructor);\n\tif (!_constructor.isPayable())\n\t\tappendCallValueCheck();\n\n\t// copy constructor arguments from code to memory and then to stack, they are supplied after the actual program\n\tif (!_constructor.parameters().empty())\n\t{\n\t\tCompilerUtils(m_context).fetchFreeMemoryPointer();\n\t\t// CODESIZE returns the actual size of the code,\n\t\t// which is the size of the generated code (``programSize``)\n\t\t// plus the constructor arguments added to the transaction payload.\n\t\tm_context.appendProgramSize();\n\t\tm_context << Instruction::CODESIZE << Instruction::SUB;\n\t\t// stack: <memptr> <argument size>\n\t\tm_context << Instruction::DUP1;\n\t\tm_context.appendProgramSize();\n\t\tm_context << Instruction::DUP4 << Instruction::CODECOPY;\n\t\t// stack: <memptr> <argument size>\n\t\tm_context << Instruction::DUP2 << Instruction::DUP2 << Instruction::ADD;\n\t\t// stack: <memptr> <argument size> <mem end>\n\t\tCompilerUtils(m_context).storeFreeMemoryPointer();\n\t\t// stack: <memptr> <argument size>\n\t\tCompilerUtils(m_context).abiDecode(FunctionType(_constructor).parameterTypes(), true);\n\t}\n\t_constructor.accept(*this);\n}\n\nvoid ContractCompiler::appendDelegatecallCheck()\n{\n\t// Special constant that will be replaced by the address at deploy time.\n\t// At compilation time, this is just \"PUSH20 00...000\".\n\tm_context.appendDeployTimeAddress();\n\tm_context << Instruction::ADDRESS << Instruction::EQ;\n\t// The result on the stack is\n\t// \"We have not been called via DELEGATECALL\".\n}\n\nvoid ContractCompiler::appendInternalSelector(\n\tstd::map<FixedHash<4>, evmasm::AssemblyItem const> const& _entryPoints,\n\tstd::vector<FixedHash<4>> const& _ids,\n\tevmasm::AssemblyItem const& _notFoundTag,\n\tsize_t _runs\n)\n{\n\t// Code for selecting from n functions without split:\n\t//   n times: dup1, push4 <id_i>, eq, push2/3 <tag_i>, jumpi\n\t//   push2/3 <notfound> jump\n\t// (called SELECT[n])\n\t// Code for selecting from n functions with split:\n\t//   dup1, push4 <pivot>, gt, push2/3<tag_less>, jumpi\n\t//     SELECT[n/2]\n\t//   tag_less:\n\t//     SELECT[n/2]\n\t//\n\t// This means each split adds 16-18 bytes of additional code (note the additional jump out!)\n\t// The average execution cost if we do not split at all are:\n\t//   (3 + 3 + 3 + 3 + 10) * n/2 = 24 * n/2 = 12 * n\n\t// If we split once:\n\t//    (3 + 3 + 3 + 3 + 10) + 24 * n/4 = 24 * (n/4 + 1) = 6 * n + 24;\n\t//\n\t// We should split if\n\t//     _runs * 12 * n > _runs * (6 * n + 24) + 17 * createDataGas\n\t// <=> _runs * 6 * (n - 4) > 17 * createDataGas\n\t//\n\t// Which also means that the execution itself is not profitable\n\t// unless we have at least 5 functions.\n\n\t// Start with some comparisons to avoid overflow, then do the actual comparison.\n\tbool split = false;\n\tif (_ids.size() <= 4)\n\t\tsplit = false;\n\telse if (_runs > (17 * evmasm::GasCosts::createDataGas) / 6)\n\t\tsplit = true;\n\telse\n\t\tsplit = (_runs * 6 * (_ids.size() - 4) > 17 * evmasm::GasCosts::createDataGas);\n\n\tif (split)\n\t{\n\t\tsize_t pivotIndex = _ids.size() / 2;\n\t\tFixedHash<4> pivot{_ids.at(pivotIndex)};\n\t\tm_context << dupInstruction(1) << u256(FixedHash<4>::Arith(pivot)) << Instruction::GT;\n\t\tevmasm::AssemblyItem lessTag{m_context.appendConditionalJump()};\n\t\t// Here, we have funid >= pivot\n\t\tstd::vector<FixedHash<4>> larger{_ids.begin() + static_cast<ptrdiff_t>(pivotIndex), _ids.end()};\n\t\tappendInternalSelector(_entryPoints, larger, _notFoundTag, _runs);\n\t\tm_context << lessTag;\n\t\t// Here, we have funid < pivot\n\t\tstd::vector<FixedHash<4>> smaller{_ids.begin(), _ids.begin() + static_cast<ptrdiff_t>(pivotIndex)};\n\t\tappendInternalSelector(_entryPoints, smaller, _notFoundTag, _runs);\n\t}\n\telse\n\t{\n\t\tfor (auto const& id: _ids)\n\t\t{\n\t\t\tm_context << dupInstruction(1) << u256(FixedHash<4>::Arith(id)) << Instruction::EQ;\n\t\t\tm_context.appendConditionalJumpTo(_entryPoints.at(id));\n\t\t}\n\t\tm_context.appendJumpTo(_notFoundTag);\n\t}\n}\n\nnamespace\n{\n\n// Helper function to check if any function is payable\nbool hasPayableFunctions(ContractDefinition const& _contract)\n{\n\tif (_contract.receiveFunction())\n\t\treturn true;\n\n\tFunctionDefinition const* fallback = _contract.fallbackFunction();\n\tif (fallback && fallback->isPayable())\n\t\treturn true;\n\n\tfor (auto const& it: _contract.interfaceFunctions())\n\t\tif (it.second->isPayable())\n\t\t\treturn true;\n\n\treturn false;\n}\n\n}\n\nvoid ContractCompiler::appendFunctionSelector(ContractDefinition const& _contract)\n{\n\tstd::map<FixedHash<4>, FunctionTypePointer> interfaceFunctions = _contract.interfaceFunctions();\n\tstd::map<FixedHash<4>, evmasm::AssemblyItem const> callDataUnpackerEntryPoints;\n\n\tif (_contract.isLibrary())\n\t{\n\t\tsolAssert(m_context.stackHeight() == 1, \"CALL / DELEGATECALL flag expected.\");\n\t}\n\n\tFunctionDefinition const* fallback = _contract.fallbackFunction();\n\tsolAssert(!_contract.isLibrary() || !fallback, \"Libraries can't have fallback functions\");\n\n\tFunctionDefinition const* etherReceiver = _contract.receiveFunction();\n\tsolAssert(!_contract.isLibrary() || !etherReceiver, \"Libraries can't have ether receiver functions\");\n\n\tbool needToAddCallvalueCheck = true;\n\tif (!hasPayableFunctions(_contract) && !interfaceFunctions.empty() && !_contract.isLibrary())\n\t{\n\t\tappendCallValueCheck();\n\t\tneedToAddCallvalueCheck = false;\n\t}\n\n\tevmasm::AssemblyItem notFoundOrReceiveEther = m_context.newTag();\n\t// If there is neither a fallback nor a receive ether function, we only need one label to jump to, which\n\t// always reverts.\n\tevmasm::AssemblyItem notFound = (!fallback && !etherReceiver) ? notFoundOrReceiveEther : m_context.newTag();\n\n\t// directly jump to fallback or ether receiver if the data is too short to contain a function selector\n\t// also guards against short data\n\tm_context << u256(4) << Instruction::CALLDATASIZE << Instruction::LT;\n\tm_context.appendConditionalJumpTo(notFoundOrReceiveEther);\n\n\t// retrieve the function signature hash from the calldata\n\tif (!interfaceFunctions.empty())\n\t{\n\t\tCompilerUtils(m_context).loadFromMemory(0, IntegerType(CompilerUtils::dataStartOffset * 8), true, false);\n\n\t\t// stack now is: <can-call-non-view-functions>? <funhash>\n\t\tstd::vector<FixedHash<4>> sortedIDs;\n\t\tfor (auto const& it: interfaceFunctions)\n\t\t{\n\t\t\tcallDataUnpackerEntryPoints.emplace(it.first, m_context.newTag());\n\t\t\tsortedIDs.emplace_back(it.first);\n\t\t}\n\t\tstd::sort(sortedIDs.begin(), sortedIDs.end());\n\t\tappendInternalSelector(callDataUnpackerEntryPoints, sortedIDs, notFound, m_optimiserSettings.expectedExecutionsPerDeployment);\n\t}\n\n\tm_context << notFoundOrReceiveEther;\n\n\tif (!fallback && !etherReceiver)\n\t\tm_context.appendRevert(\"Contract does not have fallback nor receive functions\");\n\telse\n\t{\n\t\tif (etherReceiver)\n\t\t{\n\t\t\t// directly jump to fallback, if there is calldata\n\t\t\tm_context << Instruction::CALLDATASIZE;\n\t\t\tm_context.appendConditionalJumpTo(notFound);\n\n\t\t\tsolAssert(!_contract.isLibrary(), \"\");\n\t\t\tsolAssert(etherReceiver->isReceive(), \"\");\n\t\t\tsolAssert(FunctionType(*etherReceiver).parameterTypes().empty(), \"\");\n\t\t\tsolAssert(FunctionType(*etherReceiver).returnParameterTypes().empty(), \"\");\n\t\t\tetherReceiver->accept(*this);\n\t\t\tm_context << Instruction::STOP;\n\t\t}\n\n\t\tm_context << notFound;\n\t\tif (fallback)\n\t\t{\n\t\t\tsolAssert(!_contract.isLibrary(), \"\");\n\t\t\tif (!fallback->isPayable() && needToAddCallvalueCheck)\n\t\t\t\tappendCallValueCheck();\n\n\t\t\tsolAssert(fallback->isFallback(), \"\");\n\t\t\tm_context.setStackOffset(0);\n\n\t\t\tif (!FunctionType(*fallback).parameterTypes().empty())\n\t\t\t\tm_context << u256(0) << Instruction::CALLDATASIZE;\n\n\t\t\tfallback->accept(*this);\n\n\t\t\tif (FunctionType(*fallback).returnParameterTypes().empty())\n\t\t\t\tm_context << Instruction::STOP;\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_context << Instruction::DUP1 << Instruction::MLOAD << Instruction::SWAP1;\n\t\t\t\tm_context << u256(0x20) << Instruction::ADD;\n\t\t\t\tm_context << Instruction::RETURN;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tm_context.appendRevert(\"Unknown signature and no fallback defined\");\n\t}\n\n\n\tfor (auto const& it: interfaceFunctions)\n\t{\n\t\tm_context.setStackOffset(1);\n\t\tFunctionTypePointer const& functionType = it.second;\n\t\tsolAssert(functionType->hasDeclaration(), \"\");\n\t\tCompilerContext::LocationSetter locationSetter(m_context, functionType->declaration());\n\n\t\tm_context << callDataUnpackerEntryPoints.at(it.first);\n\t\tif (_contract.isLibrary() && functionType->stateMutability() > StateMutability::View)\n\t\t{\n\t\t\t// If the function is not a view function and is called without DELEGATECALL,\n\t\t\t// we revert.\n\t\t\tm_context << dupInstruction(2);\n\t\t\tm_context.appendConditionalRevert(false, \"Non-view function of library called without DELEGATECALL\");\n\t\t}\n\t\tm_context.setStackOffset(0);\n\t\t// We have to allow this for libraries, because value of the previous\n\t\t// call is still visible in the delegatecall.\n\t\tif (!functionType->isPayable() && !_contract.isLibrary() && needToAddCallvalueCheck)\n\t\t\tappendCallValueCheck();\n\n\t\t// Return tag is used to jump out of the function.\n\t\tevmasm::AssemblyItem returnTag = m_context.pushNewTag();\n\t\tif (!functionType->parameterTypes().empty())\n\t\t{\n\t\t\t// Parameter for calldataUnpacker\n\t\t\tm_context << CompilerUtils::dataStartOffset;\n\t\t\tm_context << Instruction::DUP1 << Instruction::CALLDATASIZE << Instruction::SUB;\n\t\t\tCompilerUtils(m_context).abiDecode(functionType->parameterTypes());\n\t\t}\n\t\tm_context.appendJumpTo(\n\t\t\tm_context.functionEntryLabel(functionType->declaration()),\n\t\t\tevmasm::AssemblyItem::JumpType::IntoFunction\n\t\t);\n\t\tm_context << returnTag;\n\t\t// Return tag and input parameters get consumed.\n\t\tm_context.adjustStackOffset(\n\t\t\tstatic_cast<int>(CompilerUtils::sizeOnStack(functionType->returnParameterTypes())) -\n\t\t\tstatic_cast<int>(CompilerUtils::sizeOnStack(functionType->parameterTypes())) -\n\t\t\t1\n\t\t);\n\t\t// Consumes the return parameters.\n\t\tappendReturnValuePacker(functionType->returnParameterTypes(), _contract.isLibrary());\n\t}\n}\n\nvoid ContractCompiler::appendReturnValuePacker(TypePointers const& _typeParameters, bool _isLibrary)\n{\n\tCompilerUtils utils(m_context);\n\tif (_typeParameters.empty())\n\t\tm_context << Instruction::STOP;\n\telse\n\t{\n\t\tutils.fetchFreeMemoryPointer();\n\t\t//@todo optimization: if we return a single memory array, there should be enough space before\n\t\t// its data to add the needed parts and we avoid a memory copy.\n\t\tutils.abiEncode(_typeParameters, _typeParameters, _isLibrary);\n\t\tutils.toSizeAfterFreeMemoryPointer();\n\t\tm_context << Instruction::RETURN;\n\t}\n}\n\nvoid ContractCompiler::registerStateVariables(ContractDefinition const& _contract)\n{\n\tfor (auto const location: {DataLocation::Storage, DataLocation::Transient})\n\t\tfor (auto const& var: ContractType(_contract).linearizedStateVariables(location))\n\t\t\tm_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var));\n}\n\nvoid ContractCompiler::registerImmutableVariables(ContractDefinition const& _contract)\n{\n\tsolAssert(m_runtimeCompiler, \"Attempted to register immutables for runtime code generation.\");\n\tfor (auto const& var: ContractType(_contract).immutableVariables())\n\t\tm_context.addImmutable(*var);\n}\n\nvoid ContractCompiler::initializeStateVariables(ContractDefinition const& _contract)\n{\n\tsolAssert(!_contract.isLibrary(), \"Tried to initialize state variables of library.\");\n\tfor (VariableDeclaration const* variable: _contract.stateVariables())\n\t{\n\t\tsolAssert(variable->referenceLocation() != VariableDeclaration::Location::Transient || !variable->value());\n\t\tif (variable->value() && !variable->isConstant())\n\t\t\tExpressionCompiler(m_context, m_optimiserSettings.runOrderLiterals).appendStateVariableInitialization(*variable);\n\t}\n}\n\nbool ContractCompiler::visit(VariableDeclaration const& _variableDeclaration)\n{\n\tsolAssert(_variableDeclaration.isStateVariable(), \"Compiler visit to non-state variable declaration.\");\n\tCompilerContext::LocationSetter locationSetter(m_context, _variableDeclaration);\n\n\tm_context.startFunction(_variableDeclaration);\n\tm_breakTags.clear();\n\tm_continueTags.clear();\n\n\tif (_variableDeclaration.isConstant())\n\t\tExpressionCompiler(m_context, m_optimiserSettings.runOrderLiterals)\n\t\t\t.appendConstStateVariableAccessor(_variableDeclaration);\n\telse\n\t\tExpressionCompiler(m_context, m_optimiserSettings.runOrderLiterals)\n\t\t\t.appendStateVariableAccessor(_variableDeclaration);\n\n\treturn false;\n}\n\nbool ContractCompiler::visit(FunctionDefinition const& _function)\n{\n\tsolAssert(_function.isImplemented(), \"\");\n\n\tCompilerContext::LocationSetter locationSetter(m_context, _function);\n\n\tm_context.startFunction(_function);\n\n\t// stack upon entry: [return address] [arg0] [arg1] ... [argn]\n\t// reserve additional slots: [retarg0] ... [retargm]\n\n\tunsigned parametersSize = CompilerUtils::sizeOnStack(_function.parameters());\n\tif (_function.isFallback())\n\t\tm_context.adjustStackOffset(static_cast<int>(parametersSize));\n\telse if (!_function.isConstructor())\n\t\t// adding 1 for return address.\n\t\tm_context.adjustStackOffset(static_cast<int>(parametersSize) + 1);\n\tfor (ASTPointer<VariableDeclaration> const& variable: _function.parameters())\n\t{\n\t\tm_context.addVariable(*variable, parametersSize);\n\t\tparametersSize -= variable->annotation().type->sizeOnStack();\n\t}\n\n\tfor (ASTPointer<VariableDeclaration> const& variable: _function.returnParameters())\n\t\tappendStackVariableInitialisation(*variable, /* _provideDefaultValue = */ true);\n\n\tif (_function.isConstructor())\n\t\tif (auto c = dynamic_cast<ContractDefinition const&>(*_function.scope()).nextConstructor(\n\t\t\t\tm_context.mostDerivedContract()\n\t\t))\n\t\t\tappendBaseConstructor(*c);\n\n\tsolAssert(m_returnTags.empty(), \"\");\n\tm_breakTags.clear();\n\tm_continueTags.clear();\n\tm_currentFunction = &_function;\n\tm_modifierDepth = std::numeric_limits<unsigned>::max();\n\tm_scopeStackHeight.clear();\n\tm_context.setModifierDepth(0);\n\n\tappendModifierOrFunctionCode();\n\tm_context.setModifierDepth(0);\n\tsolAssert(m_returnTags.empty(), \"\");\n\n\t// Now we need to re-shuffle the stack. For this we keep a record of the stack layout\n\t// that shows the target positions of the elements, where \"-1\" denotes that this element needs\n\t// to be removed from the stack.\n\t// Note that the fact that the return arguments are of increasing index is vital for this\n\t// algorithm to work.\n\n\tunsigned const c_argumentsSize = CompilerUtils::sizeOnStack(_function.parameters());\n\tunsigned const c_returnValuesSize = CompilerUtils::sizeOnStack(_function.returnParameters());\n\n\tstd::vector<int> stackLayout;\n\tif (!_function.isConstructor() && !_function.isFallback())\n\t\tstackLayout.push_back(static_cast<int>(c_returnValuesSize)); // target of return address\n\tstackLayout += std::vector<int>(c_argumentsSize, -1); // discard all arguments\n\tfor (size_t i = 0; i < c_returnValuesSize; ++i)\n\t\tstackLayout.push_back(static_cast<int>(i));\n\n\tif (stackLayout.size() > m_context.reachableStackDepth() + 1)\n\t\tBOOST_THROW_EXCEPTION(\n\t\t\tStackTooDeepError() <<\n\t\t\terrinfo_sourceLocation(_function.location()) <<\n\t\t\tutil::errinfo_comment(util::stackTooDeepString)\n\t\t);\n\twhile (!stackLayout.empty() && stackLayout.back() != static_cast<int>(stackLayout.size() - 1))\n\t\tif (stackLayout.back() < 0)\n\t\t{\n\t\t\tm_context << Instruction::POP;\n\t\t\tstackLayout.pop_back();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_context << swapInstruction(static_cast<unsigned>(stackLayout.size()) - static_cast<unsigned>(stackLayout.back()) - 1u);\n\t\t\tstd::swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back());\n\t\t}\n\tfor (size_t i = 0; i < stackLayout.size(); ++i)\n\t\tif (stackLayout[i] != static_cast<int>(i))\n\t\t\tsolAssert(false, \"Invalid stack layout on cleanup.\");\n\n\tfor (ASTPointer<VariableDeclaration> const& variable: _function.parameters() + _function.returnParameters())\n\t\tm_context.removeVariable(*variable);\n\n\tm_context.adjustStackOffset(-(int)c_returnValuesSize);\n\n\t/// The constructor and the fallback function doesn't to jump out.\n\tif (!_function.isConstructor())\n\t{\n\t\tsolAssert(m_context.numberOfLocalVariables() == 0, \"\");\n\t\tif (!_function.isFallback() && !_function.isReceive())\n\t\t\tm_context.appendJump(evmasm::AssemblyItem::JumpType::OutOfFunction);\n\t}\n\n\treturn false;\n}\n\nbool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)\n{\n\tunsigned startStackHeight = m_context.stackHeight();\n\tyul::ExternalIdentifierAccess::CodeGenerator identifierAccessCodeGen = [&](\n\t\tyul::Identifier const& _identifier,\n\t\tyul::IdentifierContext _context,\n\t\tyul::AbstractAssembly& _assembly\n\t)\n\t{\n\t\tsolAssert(_context == yul::IdentifierContext::RValue || _context == yul::IdentifierContext::LValue, \"\");\n\t\tauto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier);\n\t\tsolAssert(ref != _inlineAssembly.annotation().externalReferences.end(), \"\");\n\t\tDeclaration const* decl = ref->second.declaration;\n\t\tsolAssert(!!decl, \"\");\n\t\tif (_context == yul::IdentifierContext::RValue)\n\t\t{\n\t\t\tint const depositBefore = _assembly.stackHeight();\n\t\t\tsolAssert(!!decl->type(), \"Type of declaration required but not yet determined.\");\n\t\t\tif (auto variable = dynamic_cast<VariableDeclaration const*>(decl))\n\t\t\t{\n\t\t\t\tsolAssert(!variable->immutable(), \"\");\n\t\t\t\tif (variable->isConstant())\n\t\t\t\t{\n\t\t\t\t\tvariable = rootConstVariableDeclaration(*variable);\n\t\t\t\t\t// If rootConstVariableDeclaration fails and returns nullptr,\n\t\t\t\t\t// it should have failed in TypeChecker already, causing a compilation error.\n\t\t\t\t\t// In such case we should not get here.\n\t\t\t\t\tsolAssert(variable, \"\");\n\n\t\t\t\t\tu256 value;\n\t\t\t\t\tif (variable->value()->annotation().type->category() == Type::Category::RationalNumber)\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue = dynamic_cast<RationalNumberType const&>(*variable->value()->annotation().type).literalValue(nullptr);\n\t\t\t\t\t\tif (FixedBytesType const* bytesType = dynamic_cast<FixedBytesType const*>(variable->type()))\n\t\t\t\t\t\t\tvalue = value << (256 - 8 * bytesType->numBytes());\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsolAssert(variable->type()->category() == Type::Category::Integer, \"\");\n\t\t\t\t\t}\n\t\t\t\t\telse if (Literal const* literal = dynamic_cast<Literal const*>(variable->value().get()))\n\t\t\t\t\t{\n\t\t\t\t\t\tType const* type = literal->annotation().type;\n\n\t\t\t\t\t\tswitch (type->category())\n\t\t\t\t\t\t{\n\t\t\t\t\t\tcase Type::Category::Bool:\n\t\t\t\t\t\tcase Type::Category::Address:\n\t\t\t\t\t\t\t// Either both the literal and the variable are bools, or they are both addresses.\n\t\t\t\t\t\t\t// If they are both bools, comparing category is the same as comparing the types.\n\t\t\t\t\t\t\t// If they are both addresses, compare category so that payable/nonpayable is not compared.\n\t\t\t\t\t\t\tsolAssert(type->category() == variable->annotation().type->category(), \"\");\n\t\t\t\t\t\t\tvalue = type->literalValue(literal);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase Type::Category::StringLiteral:\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tStringLiteralType const& stringLiteral = dynamic_cast<StringLiteralType const&>(*type);\n\t\t\t\t\t\t\tsolAssert(variable->type()->category() == Type::Category::FixedBytes, \"\");\n\t\t\t\t\t\t\tunsigned const numBytes = dynamic_cast<FixedBytesType const&>(*variable->type()).numBytes();\n\t\t\t\t\t\t\tsolAssert(stringLiteral.value().size() <= numBytes, \"\");\n\t\t\t\t\t\t\tvalue = u256(h256(stringLiteral.value(), h256::AlignLeft));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tsolAssert(false, \"\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tsolAssert(false, \"Invalid constant in inline assembly.\");\n\t\t\t\t\tm_context << value;\n\t\t\t\t}\n\t\t\t\telse if (m_context.isStateVariable(decl))\n\t\t\t\t{\n\t\t\t\t\tauto const& location = m_context.storageLocationOfVariable(*decl);\n\t\t\t\t\tif (ref->second.suffix == \"slot\")\n\t\t\t\t\t\tm_context << location.first;\n\t\t\t\t\telse if (ref->second.suffix == \"offset\")\n\t\t\t\t\t\tm_context << u256(location.second);\n\t\t\t\t\telse\n\t\t\t\t\t\tsolAssert(false, \"\");\n\t\t\t\t}\n\t\t\t\telse if (m_context.isLocalVariable(decl))\n\t\t\t\t{\n\t\t\t\t\tunsigned stackDiff = static_cast<unsigned>(_assembly.stackHeight()) - m_context.baseStackOffsetOfVariable(*variable);\n\t\t\t\t\tif (!ref->second.suffix.empty())\n\t\t\t\t\t{\n\t\t\t\t\t\tstd::string const& suffix = ref->second.suffix;\n\t\t\t\t\t\tif (variable->type()->dataStoredIn(DataLocation::Storage))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsolAssert(suffix == \"offset\" || suffix == \"slot\", \"\");\n\t\t\t\t\t\t\tunsigned size = variable->type()->sizeOnStack();\n\t\t\t\t\t\t\tif (size == 2)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// slot plus offset\n\t\t\t\t\t\t\t\tif (suffix == \"offset\")\n\t\t\t\t\t\t\t\t\tstackDiff--;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsolAssert(size == 1, \"\");\n\t\t\t\t\t\t\t\t// only slot, offset is zero\n\t\t\t\t\t\t\t\tif (suffix == \"offset\")\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t_assembly.appendConstant(u256(0));\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (variable->type()->dataStoredIn(DataLocation::CallData))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tauto const* arrayType = dynamic_cast<ArrayType const*>(variable->type());\n\t\t\t\t\t\t\tsolAssert(\n\t\t\t\t\t\t\t\tarrayType && arrayType->isDynamicallySized() && arrayType->dataStoredIn(DataLocation::CallData),\n\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tsolAssert(suffix == \"offset\" || suffix == \"length\", \"\");\n\t\t\t\t\t\t\tsolAssert(variable->type()->sizeOnStack() == 2, \"\");\n\t\t\t\t\t\t\tif (suffix == \"length\")\n\t\t\t\t\t\t\t\tstackDiff--;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (\n\t\t\t\t\t\t\tauto const* functionType = dynamic_cast<FunctionType const*>(variable->type());\n\t\t\t\t\t\t\tfunctionType && functionType->kind() == FunctionType::Kind::External\n\t\t\t\t\t\t)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsolAssert(suffix == \"selector\" || suffix == \"address\", \"\");\n\t\t\t\t\t\t\tsolAssert(variable->type()->sizeOnStack() == 2, \"\");\n\t\t\t\t\t\t\tif (suffix == \"selector\")\n\t\t\t\t\t\t\t\tstackDiff--;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsolAssert(false, \"\");\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tsolAssert(variable->type()->sizeOnStack() == 1, \"\");\n\t\t\t\t\tif (stackDiff < 1 || stackDiff > m_context.reachableStackDepth())\n\t\t\t\t\t\tBOOST_THROW_EXCEPTION(\n\t\t\t\t\t\t\tStackTooDeepError() <<\n\t\t\t\t\t\t\terrinfo_sourceLocation(_inlineAssembly.location()) <<\n\t\t\t\t\t\t\tutil::errinfo_comment(util::stackTooDeepString)\n\t\t\t\t\t\t);\n\t\t\t\t\t_assembly.appendInstruction(dupInstruction(stackDiff));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tsolAssert(false, \"\");\n\t\t\t}\n\t\t\telse if (auto contract = dynamic_cast<ContractDefinition const*>(decl))\n\t\t\t{\n\t\t\t\tsolAssert(ref->second.suffix.empty(), \"\");\n\t\t\t\tsolAssert(contract->isLibrary(), \"\");\n\t\t\t\t_assembly.appendLinkerSymbol(contract->fullyQualifiedName());\n\t\t\t}\n\t\t\telse\n\t\t\t\tsolAssert(false, \"Invalid declaration type.\");\n\t\t\tsolAssert(_assembly.stackHeight() - depositBefore == static_cast<int>(ref->second.valueSize), \"\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// lvalue context\n\t\t\tauto variable = dynamic_cast<VariableDeclaration const*>(decl);\n\t\t\tunsigned stackDiff = static_cast<unsigned>(_assembly.stackHeight()) - m_context.baseStackOffsetOfVariable(*variable) - 1;\n\t\t\tstd::string const& suffix = ref->second.suffix;\n\t\t\tif (variable->type()->dataStoredIn(DataLocation::Storage))\n\t\t\t{\n\t\t\t\tsolAssert(\n\t\t\t\t\t!!variable && m_context.isLocalVariable(variable),\n\t\t\t\t\t\"Can only assign to stack variables in inline assembly.\"\n\t\t\t\t);\n\t\t\t\tsolAssert(variable->type()->sizeOnStack() == 1, \"\");\n\t\t\t\tsolAssert(suffix == \"slot\", \"\");\n\t\t\t}\n\t\t\telse if (variable->type()->dataStoredIn(DataLocation::CallData))\n\t\t\t{\n\t\t\t\tif (auto const* arrayType = dynamic_cast<ArrayType const*>(variable->type()))\n\t\t\t\t{\n\t\t\t\t\tif (arrayType->isDynamicallySized())\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(suffix == \"offset\" || suffix == \"length\", \"\");\n\t\t\t\t\t\tsolAssert(variable->type()->sizeOnStack() == 2, \"\");\n\t\t\t\t\t\tif (suffix == \"length\")\n\t\t\t\t\t\t\tstackDiff--;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(variable->type()->sizeOnStack() == 1, \"\");\n\t\t\t\t\t\tsolAssert(suffix.empty(), \"\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tauto const* structType = dynamic_cast<StructType const*>(variable->type());\n\t\t\t\t\tsolAssert(structType, \"\");\n\t\t\t\t\tsolAssert(variable->type()->sizeOnStack() == 1, \"\");\n\t\t\t\t\tsolAssert(suffix.empty(), \"\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (\n\t\t\t\tauto const* functionType = dynamic_cast<FunctionType const*>(variable->type());\n\t\t\t\tfunctionType && functionType->kind() == FunctionType::Kind::External\n\t\t\t)\n\t\t\t{\n\t\t\t\tsolAssert(suffix == \"selector\" || suffix == \"address\", \"\");\n\t\t\t\tsolAssert(variable->type()->sizeOnStack() == 2, \"\");\n\t\t\t\tif (suffix == \"selector\")\n\t\t\t\t\tstackDiff--;\n\t\t\t}\n\t\t\telse\n\t\t\t\tsolAssert(suffix.empty(), \"\");\n\n\t\t\tif (stackDiff > m_context.reachableStackDepth() || stackDiff < 1)\n\t\t\t\tBOOST_THROW_EXCEPTION(\n\t\t\t\t\tStackTooDeepError() <<\n\t\t\t\t\terrinfo_sourceLocation(_inlineAssembly.location()) <<\n\t\t\t\t\tutil::errinfo_comment(util::stackTooDeepString)\n\t\t\t\t);\n\t\t\t_assembly.appendInstruction(swapInstruction(stackDiff));\n\t\t\t_assembly.appendInstruction(Instruction::POP);\n\t\t}\n\t};\n\n\tyul::AST const* code = &_inlineAssembly.operations();\n\tyul::AsmAnalysisInfo* analysisInfo = _inlineAssembly.annotation().analysisInfo.get();\n\n\t// Only used in the scope below, but required to live outside to keep the\n\t// std::shared_ptr's alive\n\tyul::Object object;\n\n\t// The optimiser cannot handle external references\n\tif (\n\t\tm_optimiserSettings.runYulOptimiser &&\n\t\t_inlineAssembly.annotation().externalReferences.empty()\n\t)\n\t{\n\t\tyul::EVMDialect const* dialect = dynamic_cast<decltype(dialect)>(&_inlineAssembly.dialect());\n\t\tsolAssert(dialect, \"\");\n\n\t\t// Create a modifiable copy of the code and analysis\n\t\tobject.setCode(std::make_shared<yul::AST>(_inlineAssembly.dialect(), yul::ASTCopier().translate(code->root())));\n\t\tobject.analysisInfo = std::make_shared<yul::AsmAnalysisInfo>(yul::AsmAnalyzer::analyzeStrictAssertCorrect(object));\n\n\t\tm_context.optimizeYul(object, m_optimiserSettings);\n\n\t\tcode = object.code().get();\n\t\tanalysisInfo = object.analysisInfo.get();\n\t}\n\n\tyul::CodeGenerator::assemble(\n\t\tcode->root(),\n\t\t*analysisInfo,\n\t\t*m_context.assemblyPtr(),\n\t\tm_context.evmVersion(),\n\t\tstd::nullopt,\n\t\tidentifierAccessCodeGen,\n\t\tfalse,\n\t\tm_optimiserSettings.optimizeStackAllocation\n\t);\n\tm_context.setStackOffset(static_cast<int>(startStackHeight));\n\treturn false;\n}\n\nbool ContractCompiler::visit(TryStatement const& _tryStatement)\n{\n\tStackHeightChecker checker(m_context);\n\tCompilerContext::LocationSetter locationSetter(m_context, _tryStatement);\n\n\tcompileExpression(_tryStatement.externalCall());\n\tint const returnSize = static_cast<int>(_tryStatement.externalCall().annotation().type->sizeOnStack());\n\n\t// Stack: [ return values] <success flag>\n\tevmasm::AssemblyItem successTag = m_context.appendConditionalJump();\n\n\t// Catch case.\n\tm_context.adjustStackOffset(-returnSize);\n\n\thandleCatch(_tryStatement.clauses());\n\n\tevmasm::AssemblyItem endTag = m_context.appendJumpToNew();\n\n\tm_context << successTag;\n\tm_context.adjustStackOffset(returnSize);\n\t{\n\t\t// Success case.\n\t\t// Stack: return values\n\t\tTryCatchClause const& successClause = *_tryStatement.clauses().front();\n\t\tif (successClause.parameters())\n\t\t{\n\t\t\tstd::vector<Type const*> exprTypes{_tryStatement.externalCall().annotation().type};\n\t\t\tif (auto tupleType = dynamic_cast<TupleType const*>(exprTypes.front()))\n\t\t\t\texprTypes = tupleType->components();\n\t\t\tstd::vector<ASTPointer<VariableDeclaration>> const& params = successClause.parameters()->parameters();\n\t\t\tsolAssert(exprTypes.size() == params.size(), \"\");\n\t\t\tfor (size_t i = 0; i < exprTypes.size(); ++i)\n\t\t\t\tsolAssert(params[i] && exprTypes[i] && *params[i]->annotation().type == *exprTypes[i], \"\");\n\t\t}\n\t\telse\n\t\t\tCompilerUtils(m_context).popStackSlots(static_cast<size_t>(returnSize));\n\n\t\t_tryStatement.clauses().front()->accept(*this);\n\t}\n\n\tm_context << endTag;\n\tchecker.check();\n\treturn false;\n}\n\nvoid ContractCompiler::handleCatch(std::vector<ASTPointer<TryCatchClause>> const& _catchClauses)\n{\n\t// Stack is empty.\n\tASTPointer<TryCatchClause> error{};\n\tASTPointer<TryCatchClause> panic{};\n\tASTPointer<TryCatchClause> fallback{};\n\tfor (size_t i = 1; i < _catchClauses.size(); ++i)\n\t\tif (_catchClauses[i]->errorName() == \"Error\")\n\t\t\terror = _catchClauses[i];\n\t\telse if (_catchClauses[i]->errorName() == \"Panic\")\n\t\t\tpanic = _catchClauses[i];\n\t\telse if (_catchClauses[i]->errorName().empty())\n\t\t\tfallback = _catchClauses[i];\n\t\telse\n\t\t\tsolAssert(false, \"\");\n\n\tsolAssert(_catchClauses.size() == 1ul + (error ? 1 : 0) + (panic ? 1 : 0) + (fallback ? 1 : 0), \"\");\n\n\tevmasm::AssemblyItem endTag = m_context.newTag();\n\tevmasm::AssemblyItem fallbackTag = m_context.newTag();\n\tevmasm::AssemblyItem panicTag = m_context.newTag();\n\tif (error || panic)\n\t\t// Note that this function returns zero on failure, which is not a problem yet,\n\t\t// but will be a problem once we allow user-defined errors.\n\t\tm_context.callYulFunction(m_context.utilFunctions().returnDataSelectorFunction(), 0, 1);\n\t\t// stack: <selector>\n\tif (error)\n\t{\n\t\tsolAssert(\n\t\t\terror->parameters() &&\n\t\t\terror->parameters()->parameters().size() == 1 &&\n\t\t\terror->parameters()->parameters().front() &&\n\t\t\t*error->parameters()->parameters().front()->annotation().type == *TypeProvider::stringMemory(),\n\t\t\t\"\"\n\t\t);\n\t\tsolAssert(m_context.evmVersion().supportsReturndata(), \"\");\n\n\t\t// stack: <selector>\n\t\tm_context << Instruction::DUP1 << util::selectorFromSignatureU32(\"Error(string)\") << Instruction::EQ;\n\t\tm_context << Instruction::ISZERO;\n\t\tm_context.appendConditionalJumpTo(panicTag);\n\t\tm_context << Instruction::POP; // remove selector\n\n\t\t// Try to decode the error message.\n\t\t// If this fails, leaves 0 on the stack, otherwise the pointer to the data string.\n\t\tm_context.callYulFunction(m_context.utilFunctions().tryDecodeErrorMessageFunction(), 0, 1);\n\t\tm_context << Instruction::DUP1;\n\t\tAssemblyItem decodeSuccessTag = m_context.appendConditionalJump();\n\t\tm_context << Instruction::POP;\n\t\tm_context.appendJumpTo(fallbackTag);\n\t\tm_context.adjustStackOffset(1);\n\n\t\tm_context << decodeSuccessTag;\n\t\terror->accept(*this);\n\t\tm_context.appendJumpTo(endTag);\n\t\tm_context.adjustStackOffset(1);\n\t}\n\tm_context << panicTag;\n\tif (panic)\n\t{\n\t\tsolAssert(\n\t\t\tpanic->parameters() &&\n\t\t\tpanic->parameters()->parameters().size() == 1 &&\n\t\t\tpanic->parameters()->parameters().front() &&\n\t\t\t*panic->parameters()->parameters().front()->annotation().type == *TypeProvider::uint256(),\n\t\t\t\"\"\n\t\t);\n\t\tsolAssert(m_context.evmVersion().supportsReturndata(), \"\");\n\n\t\t// stack: <selector>\n\t\tm_context << util::selectorFromSignatureU32(\"Panic(uint256)\") << Instruction::EQ;\n\t\tm_context << Instruction::ISZERO;\n\t\tm_context.appendConditionalJumpTo(fallbackTag);\n\n\t\tm_context.callYulFunction(m_context.utilFunctions().tryDecodePanicDataFunction(), 0, 2);\n\t\tm_context << Instruction::SWAP1;\n\t\t// stack: <code> <success>\n\t\tAssemblyItem decodeSuccessTag = m_context.appendConditionalJump();\n\t\tm_context << Instruction::POP;\n\t\tm_context.appendJumpTo(fallbackTag);\n\t\tm_context.adjustStackOffset(1);\n\n\t\tm_context << decodeSuccessTag;\n\t\tpanic->accept(*this);\n\t\tm_context.appendJumpTo(endTag);\n\t\tm_context.adjustStackOffset(1);\n\t}\n\tif (error || panic)\n\t\tm_context << Instruction::POP; // selector\n\tm_context << fallbackTag;\n\tif (fallback)\n\t{\n\t\tif (fallback->parameters())\n\t\t{\n\t\t\tsolAssert(m_context.evmVersion().supportsReturndata(), \"\");\n\t\t\tsolAssert(\n\t\t\t\tfallback->parameters()->parameters().size() == 1 &&\n\t\t\t\tfallback->parameters()->parameters().front() &&\n\t\t\t\t*fallback->parameters()->parameters().front()->annotation().type == *TypeProvider::bytesMemory(),\n\t\t\t\t\"\"\n\t\t\t);\n\t\t\tCompilerUtils(m_context).returnDataToArray();\n\t\t}\n\n\t\tfallback->accept(*this);\n\t}\n\telse\n\t{\n\t\t// re-throw\n\t\tif (m_context.evmVersion().supportsReturndata())\n\t\t\tm_context.appendInlineAssembly(R\"({\n\t\t\t\treturndatacopy(0, 0, returndatasize())\n\t\t\t\trevert(0, returndatasize())\n\t\t\t})\");\n\t\telse\n\t\t\t// Since both returndata and revert are >=byzantium, this should be unreachable.\n\t\t\tsolAssert(false, \"\");\n\t}\n\tm_context << endTag;\n}\n\nbool ContractCompiler::visit(TryCatchClause const& _clause)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _clause);\n\n\tunsigned varSize = 0;\n\n\tif (_clause.parameters())\n\t\tfor (ASTPointer<VariableDeclaration> const& varDecl: _clause.parameters()->parameters() | ranges::views::reverse)\n\t\t{\n\t\t\tsolAssert(varDecl, \"\");\n\t\t\tvarSize += varDecl->annotation().type->sizeOnStack();\n\t\t\tm_context.addVariable(*varDecl, varSize);\n\t\t}\n\n\t_clause.block().accept(*this);\n\n\tm_context.removeVariablesAboveStackHeight(m_context.stackHeight() - varSize);\n\tCompilerUtils(m_context).popStackSlots(varSize);\n\n\treturn false;\n}\n\nbool ContractCompiler::visit(IfStatement const& _ifStatement)\n{\n\tStackHeightChecker checker(m_context);\n\tCompilerContext::LocationSetter locationSetter(m_context, _ifStatement);\n\tcompileExpression(_ifStatement.condition());\n\tm_context << Instruction::ISZERO;\n\tevmasm::AssemblyItem falseTag = m_context.appendConditionalJump();\n\tevmasm::AssemblyItem endTag = falseTag;\n\t_ifStatement.trueStatement().accept(*this);\n\tif (_ifStatement.falseStatement())\n\t{\n\t\tendTag = m_context.appendJumpToNew();\n\t\tm_context << falseTag;\n\t\t_ifStatement.falseStatement()->accept(*this);\n\t}\n\tm_context << endTag;\n\n\tchecker.check();\n\treturn false;\n}\n\nbool ContractCompiler::visit(WhileStatement const& _whileStatement)\n{\n\tStackHeightChecker checker(m_context);\n\tCompilerContext::LocationSetter locationSetter(m_context, _whileStatement);\n\n\tevmasm::AssemblyItem loopStart = m_context.newTag();\n\tevmasm::AssemblyItem loopEnd = m_context.newTag();\n\tm_breakTags.emplace_back(loopEnd, m_context.stackHeight());\n\n\tm_context << loopStart;\n\n\tif (_whileStatement.isDoWhile())\n\t{\n\t\tevmasm::AssemblyItem condition = m_context.newTag();\n\t\tm_continueTags.emplace_back(condition, m_context.stackHeight());\n\n\t\t_whileStatement.body().accept(*this);\n\n\t\tm_context << condition;\n\t\tcompileExpression(_whileStatement.condition());\n\t\tm_context << Instruction::ISZERO << Instruction::ISZERO;\n\t\tm_context.appendConditionalJumpTo(loopStart);\n\t}\n\telse\n\t{\n\t\tm_continueTags.emplace_back(loopStart, m_context.stackHeight());\n\t\tcompileExpression(_whileStatement.condition());\n\t\tm_context << Instruction::ISZERO;\n\t\tm_context.appendConditionalJumpTo(loopEnd);\n\n\t\t_whileStatement.body().accept(*this);\n\n\t\tm_context.appendJumpTo(loopStart);\n\t}\n\tm_context << loopEnd;\n\n\tm_continueTags.pop_back();\n\tm_breakTags.pop_back();\n\n\tchecker.check();\n\treturn false;\n}\n\nbool ContractCompiler::visit(ForStatement const& _forStatement)\n{\n\tStackHeightChecker checker(m_context);\n\tCompilerContext::LocationSetter locationSetter(m_context, _forStatement);\n\tevmasm::AssemblyItem loopStart = m_context.newTag();\n\tevmasm::AssemblyItem loopEnd = m_context.newTag();\n\tevmasm::AssemblyItem loopNext = m_context.newTag();\n\n\tstoreStackHeight(&_forStatement);\n\n\tif (_forStatement.initializationExpression())\n\t\t_forStatement.initializationExpression()->accept(*this);\n\n\tm_breakTags.emplace_back(loopEnd, m_context.stackHeight());\n\tm_continueTags.emplace_back(loopNext, m_context.stackHeight());\n\tm_context << loopStart;\n\n\t// if there is no terminating condition in for, default is to always be true\n\tif (_forStatement.condition())\n\t{\n\t\tcompileExpression(*_forStatement.condition());\n\t\tm_context << Instruction::ISZERO;\n\t\tm_context.appendConditionalJumpTo(loopEnd);\n\t}\n\n\t_forStatement.body().accept(*this);\n\n\tm_context << loopNext;\n\n\t// for's loop expression if existing\n\tif (_forStatement.loopExpression())\n\t{\n\t\tArithmetic previousArithmetic = m_context.arithmetic();\n\t\tif (\n\t\t\t*_forStatement.annotation().isSimpleCounterLoop &&\n\t\t\tm_optimiserSettings.simpleCounterForLoopUncheckedIncrement\n\t\t)\n\t\t\tm_context.setArithmetic(Arithmetic::Wrapping);\n\t\t_forStatement.loopExpression()->accept(*this);\n\t\tm_context.setArithmetic(previousArithmetic);\n\t}\n\n\tm_context.appendJumpTo(loopStart);\n\n\tm_context << loopEnd;\n\n\tm_continueTags.pop_back();\n\tm_breakTags.pop_back();\n\n\t// For the case where no break/return is executed:\n\t// loop initialization variables have to be freed\n\tpopScopedVariables(&_forStatement);\n\n\tchecker.check();\n\treturn false;\n}\n\nbool ContractCompiler::visit(Continue const& _continueStatement)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _continueStatement);\n\tsolAssert(!m_continueTags.empty(), \"\");\n\tCompilerUtils(m_context).popAndJump(m_continueTags.back().second, m_continueTags.back().first);\n\treturn false;\n}\n\nbool ContractCompiler::visit(Break const& _breakStatement)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _breakStatement);\n\tsolAssert(!m_breakTags.empty(), \"\");\n\tCompilerUtils(m_context).popAndJump(m_breakTags.back().second, m_breakTags.back().first);\n\treturn false;\n}\n\nbool ContractCompiler::visit(Return const& _return)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _return);\n\tif (Expression const* expression = _return.expression())\n\t{\n\t\tsolAssert(_return.annotation().functionReturnParameters, \"Invalid return parameters pointer.\");\n\t\tstd::vector<ASTPointer<VariableDeclaration>> const& returnParameters =\n\t\t\t_return.annotation().functionReturnParameters->parameters();\n\t\tTypePointers types;\n\t\tfor (auto const& retVariable: returnParameters)\n\t\t\ttypes.push_back(retVariable->annotation().type);\n\n\t\tType const* expectedType;\n\t\tif (expression->annotation().type->category() == Type::Category::Tuple || types.size() != 1)\n\t\t\texpectedType = TypeProvider::tuple(std::move(types));\n\t\telse\n\t\t\texpectedType = types.front();\n\t\tcompileExpression(*expression, expectedType);\n\n\t\tfor (auto const& retVariable: returnParameters | ranges::views::reverse)\n\t\t\tCompilerUtils(m_context).moveToStackVariable(*retVariable);\n\t}\n\n\tCompilerUtils(m_context).popAndJump(m_returnTags.back().second, m_returnTags.back().first);\n\treturn false;\n}\n\nbool ContractCompiler::visit(Throw const&)\n{\n\tsolAssert(false, \"Throw statement is disallowed.\");\n\treturn false;\n}\n\nbool ContractCompiler::visit(EmitStatement const& _emit)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _emit);\n\tStackHeightChecker checker(m_context);\n\tcompileExpression(_emit.eventCall());\n\tchecker.check();\n\treturn false;\n}\n\nbool ContractCompiler::visit(RevertStatement const& _revert)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _revert);\n\tStackHeightChecker checker(m_context);\n\tcompileExpression(_revert.errorCall());\n\tchecker.check();\n\treturn false;\n}\n\nbool ContractCompiler::visit(VariableDeclarationStatement const& _variableDeclarationStatement)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _variableDeclarationStatement);\n\n\t// Local variable slots are reserved when their declaration is visited,\n\t// and freed in the end of their scope.\n\tfor (auto decl: _variableDeclarationStatement.declarations())\n\t\tif (decl)\n\t\t\tappendStackVariableInitialisation(*decl, !_variableDeclarationStatement.initialValue());\n\n\tStackHeightChecker checker(m_context);\n\tif (Expression const* expression = _variableDeclarationStatement.initialValue())\n\t{\n\t\tCompilerUtils utils(m_context);\n\t\tcompileExpression(*expression);\n\t\tTypePointers valueTypes;\n\t\tif (auto tupleType = dynamic_cast<TupleType const*>(expression->annotation().type))\n\t\t\tvalueTypes = tupleType->components();\n\t\telse\n\t\t\tvalueTypes = TypePointers{expression->annotation().type};\n\t\tauto const& declarations = _variableDeclarationStatement.declarations();\n\t\tsolAssert(declarations.size() == valueTypes.size(), \"\");\n\t\tfor (size_t i = 0; i < declarations.size(); ++i)\n\t\t{\n\t\t\tsize_t j = declarations.size() - i - 1;\n\t\t\tsolAssert(!!valueTypes[j], \"\");\n\t\t\tif (VariableDeclaration const* varDecl = declarations[j].get())\n\t\t\t{\n\t\t\t\tutils.convertType(*valueTypes[j], *varDecl->annotation().type);\n\t\t\t\tutils.moveToStackVariable(*varDecl);\n\t\t\t}\n\t\t\telse\n\t\t\t\tutils.popStackElement(*valueTypes[j]);\n\t\t}\n\t}\n\tchecker.check();\n\treturn false;\n}\n\nbool ContractCompiler::visit(ExpressionStatement const& _expressionStatement)\n{\n\tStackHeightChecker checker(m_context);\n\tCompilerContext::LocationSetter locationSetter(m_context, _expressionStatement);\n\tExpression const& expression = _expressionStatement.expression();\n\tcompileExpression(expression);\n\tCompilerUtils(m_context).popStackElement(*expression.annotation().type);\n\tchecker.check();\n\treturn false;\n}\n\nbool ContractCompiler::visit(PlaceholderStatement const& _placeholderStatement)\n{\n\tStackHeightChecker checker(m_context);\n\tCompilerContext::LocationSetter locationSetter(m_context, _placeholderStatement);\n\tsolAssert(m_context.arithmetic() == Arithmetic::Checked, \"Placeholder cannot be used inside unchecked block.\");\n\tappendModifierOrFunctionCode();\n\tsolAssert(m_context.arithmetic() == Arithmetic::Checked, \"Arithmetic not reset to 'checked'.\");\n\tchecker.check();\n\treturn true;\n}\n\nbool ContractCompiler::visit(Block const& _block)\n{\n\tm_context.pushVisitedNodes(&_block);\n\tif (_block.unchecked())\n\t{\n\t\tsolAssert(m_context.arithmetic() == Arithmetic::Checked, \"\");\n\t\tm_context.setArithmetic(Arithmetic::Wrapping);\n\t}\n\tstoreStackHeight(&_block);\n\treturn true;\n}\n\nvoid ContractCompiler::endVisit(Block const& _block)\n{\n\tif (_block.unchecked())\n\t{\n\t\tsolAssert(m_context.arithmetic() == Arithmetic::Wrapping, \"\");\n\t\tm_context.setArithmetic(Arithmetic::Checked);\n\t}\n\t// Frees local variables declared in the scope of this block.\n\tpopScopedVariables(&_block);\n\tm_context.popVisitedNodes();\n}\n\nvoid ContractCompiler::appendMissingFunctions()\n{\n\twhile (Declaration const* function = m_context.nextFunctionToCompile())\n\t{\n\t\tm_context.setStackOffset(0);\n\t\tfunction->accept(*this);\n\t\tsolAssert(m_context.nextFunctionToCompile() != function, \"Compiled the wrong function?\");\n\t}\n\tm_context.appendMissingLowLevelFunctions();\n\tm_context.appendYulUtilityFunctions(m_optimiserSettings);\n}\n\nvoid ContractCompiler::appendModifierOrFunctionCode()\n{\n\tsolAssert(m_currentFunction, \"\");\n\tunsigned stackSurplus = 0;\n\tBlock const* codeBlock = nullptr;\n\tstd::vector<VariableDeclaration const*> addedVariables;\n\n\tm_modifierDepth++;\n\tm_context.setModifierDepth(m_modifierDepth);\n\n\tif (m_modifierDepth >= m_currentFunction->modifiers().size())\n\t{\n\t\tsolAssert(m_currentFunction->isImplemented(), \"\");\n\t\tcodeBlock = &m_currentFunction->body();\n\t}\n\telse\n\t{\n\t\tASTPointer<ModifierInvocation> const& modifierInvocation = m_currentFunction->modifiers()[m_modifierDepth];\n\n\t\t// constructor call should be excluded\n\t\tif (dynamic_cast<ContractDefinition const*>(modifierInvocation->name().annotation().referencedDeclaration))\n\t\t\tappendModifierOrFunctionCode();\n\t\telse\n\t\t{\n\t\t\tModifierDefinition const& referencedModifier = dynamic_cast<ModifierDefinition const&>(\n\t\t\t\t*modifierInvocation->name().annotation().referencedDeclaration\n\t\t\t);\n\t\t\tVirtualLookup lookup = *modifierInvocation->name().annotation().requiredLookup;\n\t\t\tsolAssert(lookup == VirtualLookup::Virtual || lookup == VirtualLookup::Static, \"\");\n\t\t\tModifierDefinition const& modifier =\n\t\t\t\tlookup == VirtualLookup::Virtual ?\n\t\t\t\treferencedModifier.resolveVirtual(m_context.mostDerivedContract()) :\n\t\t\t\treferencedModifier;\n\n\t\t\tCompilerContext::LocationSetter locationSetter(m_context, modifier);\n\t\t\tstd::vector<ASTPointer<Expression>> const& modifierArguments =\n\t\t\t\tmodifierInvocation->arguments() ? *modifierInvocation->arguments() : std::vector<ASTPointer<Expression>>();\n\n\t\t\tsolAssert(modifier.parameters().size() == modifierArguments.size(), \"\");\n\t\t\tfor (unsigned i = 0; i < modifier.parameters().size(); ++i)\n\t\t\t{\n\t\t\t\tm_context.addVariable(*modifier.parameters()[i]);\n\t\t\t\taddedVariables.push_back(modifier.parameters()[i].get());\n\t\t\t\tcompileExpression(\n\t\t\t\t\t*modifierArguments[i],\n\t\t\t\t\tmodifier.parameters()[i]->annotation().type\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tstackSurplus = CompilerUtils::sizeOnStack(modifier.parameters());\n\t\t\tcodeBlock = &modifier.body();\n\t\t}\n\t}\n\n\tif (codeBlock)\n\t{\n\t\tm_context.setArithmetic(Arithmetic::Checked);\n\n\t\tbool coderV2Outside = m_context.useABICoderV2();\n\t\tm_context.setUseABICoderV2(*codeBlock->sourceUnit().annotation().useABICoderV2);\n\n\t\tm_returnTags.emplace_back(m_context.newTag(), m_context.stackHeight());\n\t\tcodeBlock->accept(*this);\n\n\t\tm_context.setUseABICoderV2(coderV2Outside);\n\n\t\tsolAssert(!m_returnTags.empty(), \"\");\n\t\tm_context << m_returnTags.back().first;\n\t\tm_returnTags.pop_back();\n\n\t\tCompilerUtils(m_context).popStackSlots(stackSurplus);\n\t\tfor (auto var: addedVariables)\n\t\t\tm_context.removeVariable(*var);\n\t}\n\tm_modifierDepth--;\n\tm_context.setModifierDepth(m_modifierDepth);\n}\n\nvoid ContractCompiler::appendStackVariableInitialisation(\n\tVariableDeclaration const& _variable,\n\tbool _provideDefaultValue\n)\n{\n\tCompilerContext::LocationSetter location(m_context, _variable);\n\tm_context.addVariable(_variable);\n\tif (!_provideDefaultValue && _variable.type()->dataStoredIn(DataLocation::Memory))\n\t{\n\t\tsolAssert(_variable.type()->sizeOnStack() == 1, \"\");\n\t\tm_context << u256(0);\n\t}\n\telse\n\t\tCompilerUtils(m_context).pushZeroValue(*_variable.annotation().type);\n}\n\nvoid ContractCompiler::compileExpression(Expression const& _expression, Type const* _targetType)\n{\n\tExpressionCompiler expressionCompiler(m_context, m_optimiserSettings.runOrderLiterals);\n\texpressionCompiler.compile(_expression);\n\tif (_targetType)\n\t\tCompilerUtils(m_context).convertType(*_expression.annotation().type, *_targetType);\n}\n\nvoid ContractCompiler::popScopedVariables(ASTNode const* _node)\n{\n\tunsigned blockHeight = m_scopeStackHeight.at(m_modifierDepth).at(_node);\n\tm_context.removeVariablesAboveStackHeight(blockHeight);\n\tsolAssert(m_context.stackHeight() >= blockHeight, \"\");\n\tunsigned stackDiff = m_context.stackHeight() - blockHeight;\n\tCompilerUtils(m_context).popStackSlots(stackDiff);\n\tm_scopeStackHeight[m_modifierDepth].erase(_node);\n\tif (m_scopeStackHeight[m_modifierDepth].empty())\n\t\tm_scopeStackHeight.erase(m_modifierDepth);\n}\n\nvoid ContractCompiler::storeStackHeight(ASTNode const* _node)\n{\n\tm_scopeStackHeight[m_modifierDepth][_node] = m_context.stackHeight();\n}\n"
  },
  {
    "path": "libsolidity/codegen/ContractCompiler.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Code generator for contracts.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/codegen/CompilerContext.h>\n#include <libsolidity/interface/DebugSettings.h>\n#include <libevmasm/Assembly.h>\n#include <functional>\n#include <ostream>\n#include <map>\n\nnamespace solidity::frontend\n{\n\n/**\n * Code generator at the contract level. Can be used to generate code for exactly one contract\n * either in \"runtime mode\" or \"creation mode\".\n */\nclass ContractCompiler: private ASTConstVisitor\n{\npublic:\n\texplicit ContractCompiler(\n\t\tContractCompiler* _runtimeCompiler,\n\t\tCompilerContext& _context,\n\t\tOptimiserSettings _optimiserSettings\n\t):\n\t\tm_optimiserSettings(std::move(_optimiserSettings)),\n\t\tm_runtimeCompiler(_runtimeCompiler),\n\t\tm_context(_context)\n\t{\n\t}\n\n\tvoid compileContract(\n\t\tContractDefinition const& _contract,\n\t\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers\n\t);\n\t/// Compiles the constructor part of the contract.\n\t/// @returns the identifier of the runtime sub-assembly.\n\tevmasm::SubAssemblyID compileConstructor(\n\t\tContractDefinition const& _contract,\n\t\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers\n\t);\n\nprivate:\n\t/// Registers the non-function objects inside the contract with the context and stores the basic\n\t/// information about the contract like the AST annotations.\n\tvoid initializeContext(\n\t\tContractDefinition const& _contract,\n\t\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers\n\t);\n\t/// Adds the code that is run at creation time. Should be run after exchanging the run-time context\n\t/// with a new and initialized context. Adds the constructor code.\n\t/// @returns the identifier of the runtime sub assembly\n\tevmasm::SubAssemblyID packIntoContractCreator(ContractDefinition const& _contract);\n\t/// Appends code that deploys the given contract as a library.\n\t/// Will also add code that modifies the contract in memory by injecting the current address\n\t/// for the call protector.\n\tevmasm::SubAssemblyID deployLibrary(ContractDefinition const& _contract);\n\t/// Appends state variable initialisation and constructor code.\n\tvoid appendInitAndConstructorCode(ContractDefinition const& _contract);\n\tvoid appendBaseConstructor(FunctionDefinition const& _constructor);\n\tvoid appendConstructor(FunctionDefinition const& _constructor);\n\t/// Appends code that returns a boolean flag on the stack that tells whether\n\t/// the contract has been called via delegatecall (false) or regular call (true).\n\t/// This is done by inserting a specific push constant as the first instruction\n\t/// whose data will be modified in memory at deploy time.\n\tvoid appendDelegatecallCheck();\n\t/// Appends the function selector. Is called recursively to create a binary search tree.\n\t/// @a _runs the number of intended executions of the contract to tune the split point.\n\tvoid appendInternalSelector(\n\t\tstd::map<util::FixedHash<4>, evmasm::AssemblyItem const> const& _entryPoints,\n\t\tstd::vector<util::FixedHash<4>> const& _ids,\n\t\tevmasm::AssemblyItem const& _notFoundTag,\n\t\tsize_t _runs\n\t);\n\tvoid appendFunctionSelector(ContractDefinition const& _contract);\n\tvoid appendCallValueCheck();\n\tvoid appendReturnValuePacker(TypePointers const& _typeParameters, bool _isLibrary);\n\n\tvoid registerStateVariables(ContractDefinition const& _contract);\n\tvoid registerImmutableVariables(ContractDefinition const& _contract);\n\tvoid initializeStateVariables(ContractDefinition const& _contract);\n\n\tbool visit(VariableDeclaration const& _variableDeclaration) override;\n\tbool visit(FunctionDefinition const& _function) override;\n\tbool visit(InlineAssembly const& _inlineAssembly) override;\n\tbool visit(TryStatement const& _tryStatement) override;\n\tvoid handleCatch(std::vector<ASTPointer<TryCatchClause>> const& _catchClauses);\n\tbool visit(TryCatchClause const& _clause) override;\n\tbool visit(IfStatement const& _ifStatement) override;\n\tbool visit(WhileStatement const& _whileStatement) override;\n\tbool visit(ForStatement const& _forStatement) override;\n\tbool visit(Continue const& _continueStatement) override;\n\tbool visit(Break const& _breakStatement) override;\n\tbool visit(Return const& _return) override;\n\tbool visit(Throw const& _throw) override;\n\tbool visit(EmitStatement const& _emit) override;\n\tbool visit(RevertStatement const& _revert) override;\n\tbool visit(VariableDeclarationStatement const& _variableDeclarationStatement) override;\n\tbool visit(ExpressionStatement const& _expressionStatement) override;\n\tbool visit(PlaceholderStatement const&) override;\n\tbool visit(Block const& _block) override;\n\tvoid endVisit(Block const& _block) override;\n\n\t/// Repeatedly visits all function which are referenced but which are not compiled yet.\n\tvoid appendMissingFunctions();\n\n\t/// Appends one layer of function modifier code of the current function, or the function\n\t/// body itself if the last modifier was reached.\n\tvoid appendModifierOrFunctionCode();\n\n\t/// Creates a stack slot for the given variable and assigns a default value.\n\t/// If the default value is complex (needs memory allocation) and @a _provideDefaultValue\n\t/// is false, this might be skipped.\n\tvoid appendStackVariableInitialisation(VariableDeclaration const& _variable, bool _provideDefaultValue);\n\tvoid compileExpression(Expression const& _expression, Type const* _targetType = nullptr);\n\n\t/// Frees the variables of a certain scope (to be used when leaving).\n\tvoid popScopedVariables(ASTNode const* _node);\n\n\t/// Sets the stack height for the visited loop.\n\tvoid storeStackHeight(ASTNode const* _node);\n\n\tOptimiserSettings const m_optimiserSettings;\n\t/// Pointer to the runtime compiler in case this is a creation compiler.\n\tContractCompiler* m_runtimeCompiler = nullptr;\n\tCompilerContext& m_context;\n\n\t/// Tag to jump to for a \"break\" statement and the stack height after freeing the local loop variables.\n\tstd::vector<std::pair<evmasm::AssemblyItem, unsigned>> m_breakTags;\n\t/// Tag to jump to for a \"continue\" statement and the stack height after freeing the local loop variables.\n\tstd::vector<std::pair<evmasm::AssemblyItem, unsigned>> m_continueTags;\n\t/// Tag to jump to for a \"return\" statement and the stack height after freeing the local function or modifier variables.\n\t/// Needs to be stacked because of modifiers.\n\tstd::vector<std::pair<evmasm::AssemblyItem, unsigned>> m_returnTags;\n\tunsigned m_modifierDepth = 0;\n\tFunctionDefinition const* m_currentFunction = nullptr;\n\n\t// arguments for base constructors, filled in derived-to-base order\n\tstd::map<FunctionDefinition const*, ASTNode const*> const* m_baseArguments;\n\n\t/// Stores the variables that were declared inside a specific scope, for each modifier depth.\n\tstd::map<unsigned, std::map<ASTNode const*, unsigned>> m_scopeStackHeight;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ExpressionCompiler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity AST to EVM bytecode compiler for expressions.\n */\n\n#include <libsolidity/codegen/ExpressionCompiler.h>\n\n#include <libsolidity/codegen/ReturnInfo.h>\n#include <libsolidity/codegen/CompilerContext.h>\n#include <libsolidity/codegen/CompilerUtils.h>\n#include <libsolidity/codegen/LValue.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTUtils.h>\n#include <libsolidity/ast/TypeProvider.h>\n\n#include <libsolidity/analysis/ConstantEvaluator.h>\n\n#include <libevmasm/GasMeter.h>\n#include <libsolutil/Common.h>\n#include <libsolutil/FunctionSelector.h>\n#include <libsolutil/Keccak256.h>\n#include <libsolutil/Whiskers.h>\n#include <libsolutil/StackTooDeepString.h>\n\n#include <boost/algorithm/string/replace.hpp>\n#include <numeric>\n#include <utility>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\n\nnamespace\n{\n\nType const* closestType(Type const* _type, Type const* _targetType, bool _isShiftOp)\n{\n\tif (_isShiftOp)\n\t\treturn _type->mobileType();\n\telse if (auto const* tupleType = dynamic_cast<TupleType const*>(_type))\n\t{\n\t\tsolAssert(_targetType, \"\");\n\t\tTypePointers const& targetComponents = dynamic_cast<TupleType const&>(*_targetType).components();\n\t\tsolAssert(tupleType->components().size() == targetComponents.size(), \"\");\n\t\tTypePointers tempComponents(targetComponents.size());\n\t\tfor (size_t i = 0; i < targetComponents.size(); ++i)\n\t\t{\n\t\t\tif (tupleType->components()[i] && targetComponents[i])\n\t\t\t{\n\t\t\t\ttempComponents[i] = closestType(tupleType->components()[i], targetComponents[i], _isShiftOp);\n\t\t\t\tsolAssert(tempComponents[i], \"\");\n\t\t\t}\n\t\t}\n\t\treturn TypeProvider::tuple(std::move(tempComponents));\n\t}\n\telse\n\t\treturn _targetType->dataStoredIn(DataLocation::Storage) ? _type->mobileType() : _targetType;\n}\n\n}\n\nvoid ExpressionCompiler::compile(Expression const& _expression)\n{\n\t_expression.accept(*this);\n}\n\nvoid ExpressionCompiler::appendStateVariableInitialization(VariableDeclaration const& _varDecl)\n{\n\tif (!_varDecl.value())\n\t\treturn;\n\tType const* type = _varDecl.value()->annotation().type;\n\tsolAssert(!!type, \"Type information not available.\");\n\tCompilerContext::LocationSetter locationSetter(m_context, _varDecl);\n\t_varDecl.value()->accept(*this);\n\n\tif (_varDecl.annotation().type->dataStoredIn(DataLocation::Storage))\n\t{\n\t\t// reference type, only convert value to mobile type and do final conversion in storeValue.\n\t\tauto mt = type->mobileType();\n\t\tsolAssert(mt, \"\");\n\t\tutils().convertType(*type, *mt);\n\t\ttype = mt;\n\t}\n\telse\n\t{\n\t\tutils().convertType(*type, *_varDecl.annotation().type);\n\t\ttype = _varDecl.annotation().type;\n\t}\n\tif (_varDecl.immutable())\n\t\tImmutableItem(m_context, _varDecl).storeValue(*type, _varDecl.location(), true);\n\telse\n\t{\n\t\tsolAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient);\n\t\tStorageItem(m_context, _varDecl).storeValue(*type, _varDecl.location(), true);\n\t}\n}\n\nvoid ExpressionCompiler::appendConstStateVariableAccessor(VariableDeclaration const& _varDecl)\n{\n\tsolAssert(_varDecl.isConstant(), \"\");\n\tacceptAndConvert(*_varDecl.value(), *_varDecl.annotation().type);\n\n\t// append return\n\tm_context << dupInstruction(_varDecl.annotation().type->sizeOnStack() + 1);\n\tm_context.appendJump(evmasm::AssemblyItem::JumpType::OutOfFunction);\n}\n\nvoid ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl)\n{\n\tsolAssert(!_varDecl.isConstant(), \"\");\n\tCompilerContext::LocationSetter locationSetter(m_context, _varDecl);\n\tFunctionType accessorType(_varDecl);\n\n\tTypePointers paramTypes = accessorType.parameterTypes();\n\tif (_varDecl.immutable())\n\t\tsolAssert(paramTypes.empty(), \"\");\n\n\tm_context.adjustStackOffset(static_cast<int>(1 + CompilerUtils::sizeOnStack(paramTypes)));\n\n\tif (!_varDecl.immutable())\n\t{\n\t\t// retrieve the position of the variable\n\t\tauto const& location = m_context.storageLocationOfVariable(_varDecl);\n\t\tm_context << location.first << u256(location.second);\n\t}\n\n\tType const* returnType = _varDecl.annotation().type;\n\n\tfor (size_t i = 0; i < paramTypes.size(); ++i)\n\t{\n\t\tif (auto mappingType = dynamic_cast<MappingType const*>(returnType))\n\t\t{\n\t\t\tsolAssert(CompilerUtils::freeMemoryPointer >= 0x40, \"\");\n\t\t\tsolAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient);\n\n\t\t\t// pop offset\n\t\t\tm_context << Instruction::POP;\n\t\t\tif (paramTypes[i]->isDynamicallySized())\n\t\t\t{\n\t\t\t\tsolAssert(\n\t\t\t\t\tdynamic_cast<ArrayType const&>(*paramTypes[i]).isByteArrayOrString(),\n\t\t\t\t\t\"Expected string or byte array for mapping key type\"\n\t\t\t\t);\n\n\t\t\t\t// stack: <keys..> <slot position>\n\n\t\t\t\t// copy key[i] to top.\n\t\t\t\tutils().copyToStackTop(static_cast<unsigned>(paramTypes.size() - i + 1), 1);\n\n\t\t\t\tm_context.appendInlineAssembly(R\"({\n\t\t\t\t\tlet key_len := mload(key_ptr)\n\t\t\t\t\t// Temp. use the memory after the array data for the slot\n\t\t\t\t\t// position\n\t\t\t\t\tlet post_data_ptr := add(key_ptr, add(key_len, 0x20))\n\t\t\t\t\tlet orig_data := mload(post_data_ptr)\n\t\t\t\t\tmstore(post_data_ptr, slot_pos)\n\t\t\t\t\tlet hash := keccak256(add(key_ptr, 0x20), add(key_len, 0x20))\n\t\t\t\t\tmstore(post_data_ptr, orig_data)\n\t\t\t\t\tslot_pos := hash\n\t\t\t\t})\", {\"slot_pos\", \"key_ptr\"});\n\n\t\t\t\tm_context << Instruction::POP;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsolAssert(paramTypes[i]->isValueType(), \"Expected value type for mapping key\");\n\n\t\t\t\t// move storage offset to memory.\n\t\t\t\tutils().storeInMemory(32);\n\n\t\t\t\t// move key to memory.\n\t\t\t\tutils().copyToStackTop(static_cast<unsigned>(paramTypes.size() - i), 1);\n\t\t\t\tutils().storeInMemory(0);\n\t\t\t\tm_context << u256(64) << u256(0);\n\t\t\t\tm_context << Instruction::KECCAK256;\n\t\t\t}\n\n\t\t\t// push offset\n\t\t\tm_context << u256(0);\n\t\t\treturnType = mappingType->valueType();\n\t\t}\n\t\telse if (auto arrayType = dynamic_cast<ArrayType const*>(returnType))\n\t\t{\n\t\t\tsolAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient);\n\n\t\t\t// pop offset\n\t\t\tm_context << Instruction::POP;\n\t\t\tutils().copyToStackTop(static_cast<unsigned>(paramTypes.size() - i + 1), 1);\n\n\t\t\tArrayUtils(m_context).retrieveLength(*arrayType, 1);\n\t\t\t// Stack: ref [length] index length\n\t\t\t// check out-of-bounds access\n\t\t\tm_context << Instruction::DUP2 << Instruction::LT;\n\t\t\tauto tag = m_context.appendConditionalJump();\n\t\t\tm_context << u256(0) << Instruction::DUP1 << Instruction::REVERT;\n\t\t\tm_context << tag;\n\n\t\t\tArrayUtils(m_context).accessIndex(*arrayType, false);\n\t\t\treturnType = arrayType->baseType();\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"Index access is allowed only for \\\"mapping\\\" and \\\"array\\\" types.\");\n\t}\n\t// remove index arguments.\n\tif (paramTypes.size() == 1)\n\t\tm_context << Instruction::SWAP2 << Instruction::POP << Instruction::SWAP1;\n\telse if (paramTypes.size() >= 2)\n\t{\n\t\tm_context << swapInstruction(static_cast<unsigned>(paramTypes.size()));\n\t\tm_context << Instruction::POP;\n\t\tm_context << swapInstruction(static_cast<unsigned>(paramTypes.size()));\n\t\tutils().popStackSlots(paramTypes.size() - 1);\n\t}\n\tunsigned retSizeOnStack = 0;\n\tauto returnTypes = accessorType.returnParameterTypes();\n\tsolAssert(returnTypes.size() >= 1, \"\");\n\tif (StructType const* structType = dynamic_cast<StructType const*>(returnType))\n\t{\n\t\tsolAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient);\n\t\tsolAssert(!_varDecl.immutable(), \"\");\n\t\t// remove offset\n\t\tm_context << Instruction::POP;\n\t\tauto const& names = accessorType.returnParameterNames();\n\t\t// struct\n\t\tfor (size_t i = 0; i < names.size(); ++i)\n\t\t{\n\t\t\tif (returnTypes[i]->category() == Type::Category::Mapping)\n\t\t\t\tcontinue;\n\t\t\tif (auto arrayType = dynamic_cast<ArrayType const*>(returnTypes[i]))\n\t\t\t\tif (!arrayType->isByteArrayOrString())\n\t\t\t\t\tcontinue;\n\t\t\tstd::pair<u256, unsigned> const& offsets = structType->storageOffsetsOfMember(names[i]);\n\t\t\tm_context << Instruction::DUP1 << u256(offsets.first) << Instruction::ADD << u256(offsets.second);\n\t\t\tType const* memberType = structType->memberType(names[i]);\n\t\t\tStorageItem(m_context, *memberType).retrieveValue(SourceLocation(), true);\n\t\t\tutils().convertType(*memberType, *returnTypes[i]);\n\t\t\tutils().moveToStackTop(returnTypes[i]->sizeOnStack());\n\t\t\tretSizeOnStack += returnTypes[i]->sizeOnStack();\n\t\t}\n\t\t// remove slot\n\t\tm_context << Instruction::POP;\n\t}\n\telse\n\t{\n\t\t// simple value or array\n\t\tsolAssert(returnTypes.size() == 1, \"\");\n\t\tif (_varDecl.immutable())\n\t\t\tImmutableItem(m_context, _varDecl).retrieveValue(SourceLocation());\n\t\telse if (_varDecl.referenceLocation() == VariableDeclaration::Location::Transient)\n\t\t\tTransientStorageItem(m_context, *returnType).retrieveValue(SourceLocation(), true);\n\t\telse\n\t\t\tStorageItem(m_context, *returnType).retrieveValue(SourceLocation(), true);\n\t\tutils().convertType(*returnType, *returnTypes.front());\n\t\tretSizeOnStack = returnTypes.front()->sizeOnStack();\n\t}\n\tsolAssert(retSizeOnStack == utils().sizeOnStack(returnTypes), \"\");\n\tif (retSizeOnStack + 1 > m_context.reachableStackDepth())\n\t\tBOOST_THROW_EXCEPTION(\n\t\t\tStackTooDeepError() <<\n\t\t\terrinfo_sourceLocation(_varDecl.location()) <<\n\t\t\tutil::errinfo_comment(util::stackTooDeepString)\n\t\t);\n\tm_context << dupInstruction(retSizeOnStack + 1);\n\tm_context.appendJump(evmasm::AssemblyItem::JumpType::OutOfFunction);\n}\n\nbool ExpressionCompiler::visit(Conditional const& _condition)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _condition);\n\t_condition.condition().accept(*this);\n\tevmasm::AssemblyItem trueTag = m_context.appendConditionalJump();\n\tacceptAndConvert(_condition.falseExpression(), *_condition.annotation().type);\n\tevmasm::AssemblyItem endTag = m_context.appendJumpToNew();\n\tm_context << trueTag;\n\tint offset = static_cast<int>(_condition.annotation().type->sizeOnStack());\n\tm_context.adjustStackOffset(-offset);\n\tacceptAndConvert(_condition.trueExpression(), *_condition.annotation().type);\n\tm_context << endTag;\n\treturn false;\n}\n\nbool ExpressionCompiler::visit(Assignment const& _assignment)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _assignment);\n\tToken op = _assignment.assignmentOperator();\n\tToken binOp = op == Token::Assign ? op : TokenTraits::AssignmentToBinaryOp(op);\n\tType const& leftType = *_assignment.leftHandSide().annotation().type;\n\tif (leftType.category() == Type::Category::Tuple)\n\t{\n\t\tsolAssert(*_assignment.annotation().type == TupleType(), \"\");\n\t\tsolAssert(op == Token::Assign, \"\");\n\t}\n\telse\n\t\tsolAssert(*_assignment.annotation().type == leftType, \"\");\n\tbool cleanupNeeded = false;\n\tif (op != Token::Assign)\n\t\tcleanupNeeded = cleanupNeededForOp(leftType.category(), binOp, m_context.arithmetic());\n\t_assignment.rightHandSide().accept(*this);\n\t// Perform some conversion already. This will convert storage types to memory and literals\n\t// to their actual type, but will not convert e.g. memory to storage.\n\tType const* rightIntermediateType = closestType(\n\t\t_assignment.rightHandSide().annotation().type,\n\t\t_assignment.leftHandSide().annotation().type,\n\t\top != Token::Assign && TokenTraits::isShiftOp(binOp)\n\t);\n\n\tsolAssert(rightIntermediateType, \"\");\n\tutils().convertType(*_assignment.rightHandSide().annotation().type, *rightIntermediateType, cleanupNeeded);\n\n\t_assignment.leftHandSide().accept(*this);\n\tsolAssert(!!m_currentLValue, \"LValue not retrieved.\");\n\n\tif (op == Token::Assign)\n\t\tm_currentLValue->storeValue(*rightIntermediateType, _assignment.location());\n\telse  // compound assignment\n\t{\n\t\tsolAssert(binOp != Token::Exp, \"Compound exp is not possible.\");\n\t\tsolAssert(leftType.isValueType(), \"Compound operators only available for value types.\");\n\t\tunsigned lvalueSize = m_currentLValue->sizeOnStack();\n\t\tunsigned itemSize = _assignment.annotation().type->sizeOnStack();\n\t\tif (lvalueSize > 0)\n\t\t{\n\t\t\tutils().copyToStackTop(lvalueSize + itemSize, itemSize);\n\t\t\tutils().copyToStackTop(itemSize + lvalueSize, lvalueSize);\n\t\t\t// value lvalue_ref value lvalue_ref\n\t\t}\n\t\tm_currentLValue->retrieveValue(_assignment.location(), true);\n\t\tutils().convertType(leftType, leftType, cleanupNeeded);\n\n\t\tif (TokenTraits::isShiftOp(binOp))\n\t\t\tappendShiftOperatorCode(binOp, leftType, *rightIntermediateType);\n\t\telse\n\t\t{\n\t\t\tsolAssert(leftType == *rightIntermediateType, \"\");\n\t\t\tappendOrdinaryBinaryOperatorCode(binOp, leftType);\n\t\t}\n\t\tif (lvalueSize > 0)\n\t\t{\n\t\t\tif (itemSize + lvalueSize > m_context.reachableStackDepth())\n\t\t\t\tBOOST_THROW_EXCEPTION(\n\t\t\t\t\tStackTooDeepError() <<\n\t\t\t\t\terrinfo_sourceLocation(_assignment.location()) <<\n\t\t\t\t\tutil::errinfo_comment(util::stackTooDeepString)\n\t\t\t\t);\n\t\t\t// value [lvalue_ref] updated_value\n\t\t\tfor (unsigned i = 0; i < itemSize; ++i)\n\t\t\t\tm_context << swapInstruction(itemSize + lvalueSize) << Instruction::POP;\n\t\t}\n\t\tm_currentLValue->storeValue(*_assignment.annotation().type, _assignment.location());\n\t}\n\tm_currentLValue.reset();\n\treturn false;\n}\n\nbool ExpressionCompiler::visit(TupleExpression const& _tuple)\n{\n\tif (_tuple.isInlineArray())\n\t{\n\t\tArrayType const& arrayType = dynamic_cast<ArrayType const&>(*_tuple.annotation().type);\n\n\t\tsolAssert(!arrayType.isDynamicallySized(), \"Cannot create dynamically sized inline array.\");\n\t\tutils().allocateMemory(std::max(u256(32u), arrayType.memoryDataSize()));\n\t\tm_context << Instruction::DUP1;\n\n\t\tfor (auto const& component: _tuple.components())\n\t\t{\n\t\t\tacceptAndConvert(*component, *arrayType.baseType(), true);\n\t\t\tutils().storeInMemoryDynamic(*arrayType.baseType(), true);\n\t\t}\n\n\t\tm_context << Instruction::POP;\n\t}\n\telse\n\t{\n\t\tstd::vector<std::unique_ptr<LValue>> lvalues;\n\t\tfor (auto const& component: _tuple.components())\n\t\t\tif (component)\n\t\t\t{\n\t\t\t\tcomponent->accept(*this);\n\t\t\t\tif (_tuple.annotation().willBeWrittenTo)\n\t\t\t\t{\n\t\t\t\t\tsolAssert(!!m_currentLValue, \"\");\n\t\t\t\t\tlvalues.push_back(std::move(m_currentLValue));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (_tuple.annotation().willBeWrittenTo)\n\t\t\t\tlvalues.push_back(std::unique_ptr<LValue>());\n\t\tif (_tuple.annotation().willBeWrittenTo)\n\t\t{\n\t\t\tif (_tuple.components().size() == 1)\n\t\t\t\tm_currentLValue = std::move(lvalues[0]);\n\t\t\telse\n\t\t\t\tm_currentLValue = std::make_unique<TupleObject>(m_context, std::move(lvalues));\n\t\t}\n\t}\n\treturn false;\n}\n\nbool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _unaryOperation);\n\n\tFunctionDefinition const* function = *_unaryOperation.annotation().userDefinedFunction;\n\tif (function)\n\t{\n\t\tsolAssert(function->isFree());\n\n\t\tFunctionType const* functionType = _unaryOperation.userDefinedFunctionType();\n\t\tsolAssert(functionType);\n\t\tsolAssert(functionType->parameterTypes().size() == 1);\n\t\tsolAssert(functionType->returnParameterTypes().size() == 1);\n\t\tsolAssert(functionType->kind() == FunctionType::Kind::Internal);\n\n\t\tevmasm::AssemblyItem returnLabel = m_context.pushNewTag();\n\t\tacceptAndConvert(\n\t\t\t_unaryOperation.subExpression(),\n\t\t\t*functionType->parameterTypes()[0],\n\t\t\tfalse // _cleanupNeeded\n\t\t);\n\n\t\tm_context << m_context.functionEntryLabel(*function).pushTag();\n\t\tm_context.appendJump(evmasm::AssemblyItem::JumpType::IntoFunction);\n\t\tm_context << returnLabel;\n\n\t\tunsigned parameterSize = CompilerUtils::sizeOnStack(functionType->parameterTypes());\n\t\tunsigned returnParametersSize = CompilerUtils::sizeOnStack(functionType->returnParameterTypes());\n\n\t\t// callee adds return parameters, but removes arguments and return label\n\t\tm_context.adjustStackOffset(static_cast<int>(returnParametersSize) - static_cast<int>(parameterSize) - 1);\n\n\t\treturn false;\n\t}\n\n\tType const& type = *_unaryOperation.annotation().type;\n\tif (type.category() == Type::Category::RationalNumber)\n\t{\n\t\tm_context << type.literalValue(nullptr);\n\t\treturn false;\n\t}\n\n\t_unaryOperation.subExpression().accept(*this);\n\n\tswitch (_unaryOperation.getOperator())\n\t{\n\tcase Token::Not: // !\n\t\tm_context << Instruction::ISZERO;\n\t\tbreak;\n\tcase Token::BitNot: // ~\n\t\tm_context << Instruction::NOT;\n\t\tbreak;\n\tcase Token::Delete: // delete\n\t\tsolAssert(!!m_currentLValue, \"LValue not retrieved.\");\n\t\tm_currentLValue->setToZero(_unaryOperation.location());\n\t\tm_currentLValue.reset();\n\t\tbreak;\n\tcase Token::Inc: // ++ (pre- or postfix)\n\tcase Token::Dec: // -- (pre- or postfix)\n\t\tsolAssert(!!m_currentLValue, \"LValue not retrieved.\");\n\t\tsolUnimplementedAssert(\n\t\t\ttype.category() != Type::Category::FixedPoint,\n\t\t\t\"Not yet implemented - FixedPointType.\"\n\t\t);\n\t\tm_currentLValue->retrieveValue(_unaryOperation.location());\n\t\tif (!_unaryOperation.isPrefixOperation())\n\t\t{\n\t\t\t// store value for later\n\t\t\tsolUnimplementedAssert(type.sizeOnStack() == 1, \"Stack size != 1 not implemented.\");\n\t\t\tm_context << Instruction::DUP1;\n\t\t\tif (m_currentLValue->sizeOnStack() > 0)\n\t\t\t\tfor (unsigned i = 1 + m_currentLValue->sizeOnStack(); i > 0; --i)\n\t\t\t\t\tm_context << swapInstruction(i);\n\t\t}\n\t\tif (_unaryOperation.getOperator() == Token::Inc)\n\t\t{\n\t\t\tif (m_context.arithmetic() == Arithmetic::Checked)\n\t\t\t\tm_context.callYulFunction(m_context.utilFunctions().incrementCheckedFunction(type), 1, 1);\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_context << u256(1);\n\t\t\t\tm_context << Instruction::ADD;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (m_context.arithmetic() == Arithmetic::Checked)\n\t\t\t\tm_context.callYulFunction(m_context.utilFunctions().decrementCheckedFunction(type), 1, 1);\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_context << u256(1);\n\t\t\t\tm_context << Instruction::SWAP1 << Instruction::SUB;\n\t\t\t}\n\t\t}\n\t\t// Stack for prefix: [ref...] (*ref)+-1\n\t\t// Stack for postfix: *ref [ref...] (*ref)+-1\n\t\tfor (unsigned i = m_currentLValue->sizeOnStack(); i > 0; --i)\n\t\t\tm_context << swapInstruction(i);\n\t\tm_currentLValue->storeValue(\n\t\t\t*_unaryOperation.annotation().type, _unaryOperation.location(),\n\t\t\t!_unaryOperation.isPrefixOperation());\n\t\tm_currentLValue.reset();\n\t\tbreak;\n\tcase Token::Add: // +\n\t\t// According to SyntaxChecker...\n\t\tsolAssert(false, \"Use of unary + is disallowed.\");\n\tcase Token::Sub: // -\n\t\tsolUnimplementedAssert(\n\t\t\ttype.category() != Type::Category::FixedPoint,\n\t\t\t\"Not yet implemented - FixedPointType.\"\n\t\t);\n\t\tif (m_context.arithmetic() == Arithmetic::Checked)\n\t\t\tm_context.callYulFunction(m_context.utilFunctions().negateNumberCheckedFunction(type), 1, 1);\n\t\telse\n\t\t\tm_context << u256(0) << Instruction::SUB;\n\t\tbreak;\n\tdefault:\n\t\tsolAssert(false, \"Invalid unary operator: \" + std::string(TokenTraits::toString(_unaryOperation.getOperator())));\n\t}\n\treturn false;\n}\n\nbool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _binaryOperation);\n\tExpression const& leftExpression = _binaryOperation.leftExpression();\n\tExpression const& rightExpression = _binaryOperation.rightExpression();\n\tFunctionDefinition const* function = *_binaryOperation.annotation().userDefinedFunction;\n\tif (function)\n\t{\n\t\tsolAssert(function->isFree());\n\n\t\tFunctionType const* functionType = _binaryOperation.userDefinedFunctionType();\n\t\tsolAssert(functionType);\n\t\tsolAssert(functionType->parameterTypes().size() == 2);\n\t\tsolAssert(functionType->returnParameterTypes().size() == 1);\n\t\tsolAssert(functionType->kind() == FunctionType::Kind::Internal);\n\n\t\tevmasm::AssemblyItem returnLabel = m_context.pushNewTag();\n\t\tacceptAndConvert(\n\t\t\tleftExpression,\n\t\t\t*functionType->parameterTypes()[0],\n\t\t\tfalse // _cleanupNeeded\n\t\t);\n\t\tacceptAndConvert(\n\t\t\trightExpression,\n\t\t\t*functionType->parameterTypes()[1],\n\t\t\tfalse // _cleanupNeeded\n\t\t);\n\n\t\tm_context << m_context.functionEntryLabel(*function).pushTag();\n\t\tm_context.appendJump(evmasm::AssemblyItem::JumpType::IntoFunction);\n\t\tm_context << returnLabel;\n\n\t\tunsigned parameterSize = CompilerUtils::sizeOnStack(functionType->parameterTypes());\n\t\tunsigned returnParametersSize = CompilerUtils::sizeOnStack(functionType->returnParameterTypes());\n\n\t\t// callee adds return parameters, but removes arguments and return label\n\t\tm_context.adjustStackOffset(static_cast<int>(returnParametersSize) - static_cast<int>(parameterSize) - 1);\n\t\treturn false;\n\t}\n\n\tsolAssert(!!_binaryOperation.annotation().commonType);\n\tType const* commonType = _binaryOperation.annotation().commonType;\n\tToken const c_op = _binaryOperation.getOperator();\n\n\tif (c_op == Token::And || c_op == Token::Or) // special case: short-circuiting\n\t\tappendAndOrOperatorCode(_binaryOperation);\n\telse if (commonType->category() == Type::Category::RationalNumber)\n\t\tm_context << commonType->literalValue(nullptr);\n\telse\n\t{\n\t\tbool cleanupNeeded = cleanupNeededForOp(commonType->category(), c_op, m_context.arithmetic());\n\n\t\tType const* leftTargetType = commonType;\n\t\tType const* rightTargetType =\n\t\t\tTokenTraits::isShiftOp(c_op) || c_op == Token::Exp ?\n\t\t\trightExpression.annotation().type->mobileType() :\n\t\t\tcommonType;\n\t\tsolAssert(rightTargetType, \"\");\n\n\t\t// for commutative operators, push the literal as late as possible to allow improved optimization\n\t\tauto isLiteral = [](Expression const& _e)\n\t\t{\n\t\t\treturn dynamic_cast<Literal const*>(&_e) || _e.annotation().type->category() == Type::Category::RationalNumber;\n\t\t};\n\t\tbool swap = m_optimiseOrderLiterals && TokenTraits::isCommutativeOp(c_op) && isLiteral(rightExpression) && !isLiteral(leftExpression);\n\t\tif (swap)\n\t\t{\n\t\t\tacceptAndConvert(leftExpression, *leftTargetType, cleanupNeeded);\n\t\t\tacceptAndConvert(rightExpression, *rightTargetType, cleanupNeeded);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tacceptAndConvert(rightExpression, *rightTargetType, cleanupNeeded);\n\t\t\tacceptAndConvert(leftExpression, *leftTargetType, cleanupNeeded);\n\t\t}\n\t\tif (TokenTraits::isShiftOp(c_op))\n\t\t\t// shift only cares about the signedness of both sides\n\t\t\tappendShiftOperatorCode(c_op, *leftTargetType, *rightTargetType);\n\t\telse if (c_op == Token::Exp)\n\t\t\tappendExpOperatorCode(*leftTargetType, *rightTargetType);\n\t\telse if (TokenTraits::isCompareOp(c_op))\n\t\t\tappendCompareOperatorCode(c_op, *commonType);\n\t\telse\n\t\t\tappendOrdinaryBinaryOperatorCode(c_op, *commonType);\n\t}\n\n\t// do not visit the child nodes, we already did that explicitly\n\treturn false;\n}\n\nbool ExpressionCompiler::visit(FunctionCall const& _functionCall)\n{\n\tauto functionCallKind = *_functionCall.annotation().kind;\n\n\tCompilerContext::LocationSetter locationSetter(m_context, _functionCall);\n\tif (functionCallKind == FunctionCallKind::TypeConversion)\n\t{\n\t\tsolAssert(_functionCall.arguments().size() == 1, \"\");\n\t\tsolAssert(_functionCall.names().empty(), \"\");\n\t\tauto const& expression = *_functionCall.arguments().front();\n\t\tauto const& targetType = *_functionCall.annotation().type;\n\t\tif (auto const* typeType = dynamic_cast<TypeType const*>(expression.annotation().type))\n\t\t\tif (auto const* addressType = dynamic_cast<AddressType const*>(&targetType))\n\t\t\t{\n\t\t\t\tauto const* contractType = dynamic_cast<ContractType const*>(typeType->actualType());\n\t\t\t\tsolAssert(\n\t\t\t\t\tcontractType &&\n\t\t\t\t\tcontractType->contractDefinition().isLibrary() &&\n\t\t\t\t\taddressType->stateMutability() == StateMutability::NonPayable,\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\t\t\t\tm_context.appendLibraryAddress(contractType->contractDefinition().fullyQualifiedName());\n\t\t\t\treturn false;\n\t\t\t}\n\t\tacceptAndConvert(expression, targetType);\n\t\treturn false;\n\t}\n\n\tFunctionTypePointer functionType;\n\tif (functionCallKind == FunctionCallKind::StructConstructorCall)\n\t{\n\t\tauto const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type);\n\t\tauto const& structType = dynamic_cast<StructType const&>(*type.actualType());\n\t\tfunctionType = structType.constructorType();\n\t}\n\telse\n\t\tfunctionType = dynamic_cast<FunctionType const*>(_functionCall.expression().annotation().type);\n\n\tTypePointers parameterTypes = functionType->parameterTypes();\n\n\tstd::vector<ASTPointer<Expression const>> const& arguments = _functionCall.sortedArguments();\n\n\tif (functionCallKind == FunctionCallKind::StructConstructorCall)\n\t{\n\t\tTypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type);\n\t\tauto const& structType = dynamic_cast<StructType const&>(*type.actualType());\n\n\t\tutils().allocateMemory(std::max(u256(32u), structType.memoryDataSize()));\n\t\tm_context << Instruction::DUP1;\n\n\t\tfor (unsigned i = 0; i < arguments.size(); ++i)\n\t\t{\n\t\t\tacceptAndConvert(*arguments[i], *functionType->parameterTypes()[i]);\n\t\t\tutils().storeInMemoryDynamic(*functionType->parameterTypes()[i]);\n\t\t}\n\t\tm_context << Instruction::POP;\n\t}\n\telse\n\t{\n\t\tFunctionType const& function = *functionType;\n\t\tif (function.hasBoundFirstArgument())\n\t\t\tsolAssert(\n\t\t\t\tfunction.kind() == FunctionType::Kind::DelegateCall ||\n\t\t\t\tfunction.kind() == FunctionType::Kind::Internal ||\n\t\t\t\tfunction.kind() == FunctionType::Kind::ArrayPush ||\n\t\t\t\tfunction.kind() == FunctionType::Kind::ArrayPop,\n\t\t\t\"\");\n\t\tswitch (function.kind())\n\t\t{\n\t\tcase FunctionType::Kind::Declaration:\n\t\t\tsolAssert(false, \"Attempted to generate code for calling a function definition.\");\n\t\t\tbreak;\n\t\tcase FunctionType::Kind::Internal:\n\t\t{\n\t\t\t// Calling convention: Caller pushes return address and arguments\n\t\t\t// Callee removes them and pushes return values\n\n\t\t\tevmasm::AssemblyItem returnLabel = m_context.pushNewTag();\n\t\t\tfor (unsigned i = 0; i < arguments.size(); ++i)\n\t\t\t\tacceptAndConvert(*arguments[i], *function.parameterTypes()[i]);\n\t\t\t_functionCall.expression().accept(*this);\n\n\t\t\tunsigned parameterSize = CompilerUtils::sizeOnStack(function.parameterTypes());\n\t\t\tif (function.hasBoundFirstArgument())\n\t\t\t{\n\t\t\t\t// stack: arg2, ..., argn, label, arg1\n\t\t\t\tunsigned depth = parameterSize + 1;\n\t\t\t\tutils().moveIntoStack(depth, function.selfType()->sizeOnStack());\n\t\t\t\tparameterSize += function.selfType()->sizeOnStack();\n\t\t\t}\n\n\t\t\tif (m_context.runtimeContext())\n\t\t\t\t// We have a runtime context, so we need the creation part.\n\t\t\t\tutils().rightShiftNumberOnStack(32);\n\t\t\telse\n\t\t\t\t// Extract the runtime part.\n\t\t\t\tm_context << ((u256(1) << 32) - 1) << Instruction::AND;\n\n\t\t\tm_context.appendJump(evmasm::AssemblyItem::JumpType::IntoFunction);\n\t\t\tm_context << returnLabel;\n\n\t\t\tunsigned returnParametersSize = CompilerUtils::sizeOnStack(function.returnParameterTypes());\n\t\t\t// callee adds return parameters, but removes arguments and return label\n\t\t\tm_context.adjustStackOffset(static_cast<int>(returnParametersSize) - static_cast<int>(parameterSize) - 1);\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::BareCall:\n\t\tcase FunctionType::Kind::BareDelegateCall:\n\t\tcase FunctionType::Kind::BareStaticCall:\n\t\t\tsolAssert(!_functionCall.annotation().tryCall, \"\");\n\t\t\t[[fallthrough]];\n\t\tcase FunctionType::Kind::External:\n\t\tcase FunctionType::Kind::DelegateCall:\n\t\t\t_functionCall.expression().accept(*this);\n\t\t\tappendExternalFunctionCall(function, arguments, _functionCall.annotation().tryCall);\n\t\t\tbreak;\n\t\tcase FunctionType::Kind::BareCallCode:\n\t\t\tsolAssert(false, \"Callcode has been removed.\");\n\t\tcase FunctionType::Kind::Creation:\n\t\t{\n\t\t\t_functionCall.expression().accept(*this);\n\t\t\t// Stack: [salt], [value]\n\n\t\t\tsolAssert(!function.gasSet(), \"Gas limit set for contract creation.\");\n\t\t\tsolAssert(function.returnParameterTypes().size() == 1, \"\");\n\t\t\tTypePointers argumentTypes;\n\t\t\tfor (auto const& arg: arguments)\n\t\t\t{\n\t\t\t\targ->accept(*this);\n\t\t\t\targumentTypes.push_back(arg->annotation().type);\n\t\t\t}\n\t\t\tContractDefinition const* contract =\n\t\t\t\t&dynamic_cast<ContractType const&>(*function.returnParameterTypes().front()).contractDefinition();\n\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\tutils().copyContractCodeToMemory(*contract, true);\n\t\t\tutils().abiEncode(argumentTypes, function.parameterTypes());\n\t\t\t// now on stack: [salt], [value], memory_end_ptr\n\t\t\t// need: [salt], size, offset, value\n\n\t\t\tif (function.saltSet())\n\t\t\t{\n\t\t\t\tm_context << dupInstruction(2 + (function.valueSet() ? 1 : 0));\n\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t}\n\n\t\t\t// now: [salt], [value], [salt], memory_end_ptr\n\t\t\tutils().toSizeAfterFreeMemoryPointer();\n\n\t\t\t// now: [salt], [value], [salt], size, offset\n\t\t\tif (function.valueSet())\n\t\t\t\tm_context << dupInstruction(3 + (function.saltSet() ? 1 : 0));\n\t\t\telse\n\t\t\t\tm_context << u256(0);\n\n\t\t\t// now: [salt], [value], [salt], size, offset, value\n\t\t\tif (function.saltSet())\n\t\t\t\tm_context << Instruction::CREATE2;\n\t\t\telse\n\t\t\t\tm_context << Instruction::CREATE;\n\n\t\t\t// now: [salt], [value], address\n\n\t\t\tif (function.valueSet())\n\t\t\t\tm_context << swapInstruction(1) << Instruction::POP;\n\t\t\tif (function.saltSet())\n\t\t\t\tm_context << swapInstruction(1) << Instruction::POP;\n\n\t\t\t// Check if zero (reverted)\n\t\t\tm_context << Instruction::DUP1 << Instruction::ISZERO;\n\t\t\tif (_functionCall.annotation().tryCall)\n\t\t\t{\n\t\t\t\t// If this is a try call, return \"<address> 1\" in the success case and\n\t\t\t\t// \"0\" in the error case.\n\t\t\t\tAssemblyItem errorCase = m_context.appendConditionalJump();\n\t\t\t\tm_context << u256(1);\n\t\t\t\tm_context << errorCase;\n\t\t\t}\n\t\t\telse\n\t\t\t\tm_context.appendConditionalRevert(true);\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::SetGas:\n\t\t{\n\t\t\t// stack layout: contract_address function_id [gas] [value]\n\t\t\t_functionCall.expression().accept(*this);\n\n\t\t\tacceptAndConvert(*arguments.front(), *TypeProvider::uint256(), true);\n\t\t\t// Note that function is not the original function, but the \".gas\" function.\n\t\t\t// Its values of gasSet and valueSet is equal to the original function's though.\n\t\t\tunsigned stackDepth = (function.gasSet() ? 1u : 0u) + (function.valueSet() ? 1u : 0u);\n\t\t\tif (stackDepth > 0)\n\t\t\t\tm_context << swapInstruction(stackDepth);\n\t\t\tif (function.gasSet())\n\t\t\t\tm_context << Instruction::POP;\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::SetValue:\n\t\t\t// stack layout: contract_address function_id [gas] [value]\n\t\t\t_functionCall.expression().accept(*this);\n\t\t\t// Note that function is not the original function, but the \".value\" function.\n\t\t\t// Its values of gasSet and valueSet is equal to the original function's though.\n\t\t\tif (function.valueSet())\n\t\t\t\tm_context << Instruction::POP;\n\t\t\targuments.front()->accept(*this);\n\t\t\tbreak;\n\t\tcase FunctionType::Kind::Send:\n\t\tcase FunctionType::Kind::Transfer:\n\t\t{\n\t\t\t_functionCall.expression().accept(*this);\n\t\t\t// Provide the gas stipend manually at first because we may send zero ether.\n\t\t\t// Will be zeroed if we send more than zero ether.\n\t\t\tm_context << u256(evmasm::GasCosts::callStipend);\n\t\t\tacceptAndConvert(*arguments.front(), *function.parameterTypes().front(), true);\n\t\t\t// gas <- gas * !value\n\t\t\tm_context << Instruction::SWAP1 << Instruction::DUP2;\n\t\t\tm_context << Instruction::ISZERO << Instruction::MUL << Instruction::SWAP1;\n\t\t\tFunctionType::Options callOptions;\n\t\t\tcallOptions.valueSet = true;\n\t\t\tcallOptions.gasSet = true;\n\t\t\tappendExternalFunctionCall(\n\t\t\t\tFunctionType(\n\t\t\t\t\tTypePointers{},\n\t\t\t\t\tTypePointers{},\n\t\t\t\t\tstrings(),\n\t\t\t\t\tstrings(),\n\t\t\t\t\tFunctionType::Kind::BareCall,\n\t\t\t\t\tStateMutability::NonPayable,\n\t\t\t\t\tnullptr,\n\t\t\t\t\tcallOptions\n\t\t\t\t),\n\t\t\t\t{},\n\t\t\t\tfalse\n\t\t\t);\n\t\t\tif (function.kind() == FunctionType::Kind::Transfer)\n\t\t\t{\n\t\t\t\t// Check if zero (out of stack or not enough balance).\n\t\t\t\tm_context << Instruction::ISZERO;\n\t\t\t\t// Revert message bubbles up.\n\t\t\t\tm_context.appendConditionalRevert(true);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::Selfdestruct:\n\t\t\tacceptAndConvert(*arguments.front(), *function.parameterTypes().front(), true);\n\t\t\tm_context << Instruction::SELFDESTRUCT;\n\t\t\tbreak;\n\t\tcase FunctionType::Kind::Revert:\n\t\t{\n\t\t\tif (arguments.empty())\n\t\t\t\tm_context.appendRevert();\n\t\t\telse\n\t\t\t{\n\t\t\t\t// function-sel(Error(string)) + encoding\n\t\t\t\tsolAssert(arguments.size() == 1, \"\");\n\t\t\t\tsolAssert(function.parameterTypes().size() == 1, \"\");\n\t\t\t\tif (m_context.revertStrings() == RevertStrings::Strip)\n\t\t\t\t{\n\t\t\t\t\tif (!*arguments.front()->annotation().isPure)\n\t\t\t\t\t{\n\t\t\t\t\t\targuments.front()->accept(*this);\n\t\t\t\t\t\tutils().popStackElement(*arguments.front()->annotation().type);\n\t\t\t\t\t}\n\t\t\t\t\tm_context.appendRevert();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\targuments.front()->accept(*this);\n\t\t\t\t\tutils().revertWithStringData(*arguments.front()->annotation().type);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::KECCAK256:\n\t\t{\n\t\t\tsolAssert(arguments.size() == 1, \"\");\n\t\t\tsolAssert(!function.padArguments(), \"\");\n\t\t\tType const* argType = arguments.front()->annotation().type;\n\t\t\tsolAssert(argType, \"\");\n\t\t\targuments.front()->accept(*this);\n\t\t\tif (auto const* stringLiteral = dynamic_cast<StringLiteralType const*>(argType))\n\t\t\t\t// Optimization: Compute keccak256 on string literals at compile-time.\n\t\t\t\tm_context << u256(keccak256(stringLiteral->value()));\n\t\t\telse if (*argType == *TypeProvider::bytesMemory() || *argType == *TypeProvider::stringMemory())\n\t\t\t{\n\t\t\t\t// Optimization: If type is bytes or string, then do not encode,\n\t\t\t\t// but directly compute keccak256 on memory.\n\t\t\t\tArrayUtils(m_context).retrieveLength(*TypeProvider::bytesMemory());\n\t\t\t\tm_context << Instruction::SWAP1 << u256(0x20) << Instruction::ADD;\n\t\t\t\tm_context << Instruction::KECCAK256;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\t\tutils().packedEncode({argType}, TypePointers());\n\t\t\t\tutils().toSizeAfterFreeMemoryPointer();\n\t\t\t\tm_context << Instruction::KECCAK256;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::ERC7201:\n\t\t{\n\t\t\tsolAssert(arguments.size() == 1);\n\t\t\tType const* argType = arguments.front()->annotation().type;\n\t\t\tsolAssert(argType);\n\t\t\targuments.front()->accept(*this);\n\t\t\tif (dynamic_cast<StringLiteralType const*>(argType))\n\t\t\t{\n\t\t\t\tstd::optional<u256> slot = erc7201CompileTimeValue(_functionCall);\n\t\t\t\tsolAssert(slot.has_value());\n\t\t\t\tm_context << *slot;\n\t\t\t}\n\t\t\t// `bytes memory` does not conform to ERC7201 spec, so analysis rejects it.\n\t\t\t// Internally string and bytes have the same representation though, so generating code for it is still possible.\n\t\t\telse if (*argType == *TypeProvider::stringMemory() || *argType == *TypeProvider::bytesMemory())\n\t\t\t{\n\t\t\t\t// stack layout: string_mem\n\t\t\t\tArrayUtils(m_context).retrieveLength(*TypeProvider::bytesMemory());\n\t\t\t\t// stack layout: string_mem length\n\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t\t// stack layout: length string_mem\n\t\t\t\t// adjust to start of string data, first slot is size\n\t\t\t\tm_context << u256(32) << Instruction::ADD;\n\t\t\t\t// stack layout: length string_data_ptr\n\t\t\t\tm_context.callYulFunction(m_context.utilFunctions().erc7201(), 2, 1);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsolAssert(!argType->dataStoredIn(DataLocation::Memory));\n\t\t\t\tsolAssert(argType->isImplicitlyConvertibleTo(*TypeProvider::stringMemory()));\n\n\t\t\t\t// stack layout: string_ref\n\t\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\t\t// stack layout: string_ref mem_start_ptr\n\t\t\t\tutils().packedEncode({argType}, TypePointers());\n\t\t\t\t// stack layout: mem_end_ptr\n\t\t\t\tutils().toSizeAfterFreeMemoryPointer();\n\t\t\t\t// stack layout: length mem_ptr_start\n\n\t\t\t\tm_context.callYulFunction(m_context.utilFunctions().erc7201(), 2, 1);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::Event:\n\t\t{\n\t\t\t_functionCall.expression().accept(*this);\n\t\t\tauto const& event = dynamic_cast<EventDefinition const&>(function.declaration());\n\t\t\tunsigned numIndexed = 0;\n\t\t\tTypePointers paramTypes = function.parameterTypes();\n\t\t\t// All indexed arguments go to the stack\n\t\t\tfor (size_t arg = arguments.size(); arg > 0; --arg)\n\t\t\t\tif (event.parameters()[arg - 1]->isIndexed())\n\t\t\t\t{\n\t\t\t\t\t++numIndexed;\n\t\t\t\t\targuments[arg - 1]->accept(*this);\n\t\t\t\t\tif (auto const& referenceType = dynamic_cast<ReferenceType const*>(paramTypes[arg - 1]))\n\t\t\t\t\t{\n\t\t\t\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\t\t\t\tutils().packedEncode(\n\t\t\t\t\t\t\t{arguments[arg - 1]->annotation().type},\n\t\t\t\t\t\t\t{referenceType}\n\t\t\t\t\t\t);\n\t\t\t\t\t\tutils().toSizeAfterFreeMemoryPointer();\n\t\t\t\t\t\tm_context << Instruction::KECCAK256;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(paramTypes[arg - 1]->isValueType(), \"\");\n\t\t\t\t\t\tif (auto functionType = dynamic_cast<FunctionType const*>(paramTypes[arg - 1]))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tauto argumentType =\n\t\t\t\t\t\t\t\tdynamic_cast<FunctionType const*>(arguments[arg-1]->annotation().type);\n\t\t\t\t\t\t\tsolAssert(\n\t\t\t\t\t\t\t\targumentType &&\n\t\t\t\t\t\t\t\tfunctionType->kind() == FunctionType::Kind::External &&\n\t\t\t\t\t\t\t\targumentType->kind() == FunctionType::Kind::External &&\n\t\t\t\t\t\t\t\t!argumentType->hasBoundFirstArgument(),\n\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tutils().combineExternalFunctionType(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tutils().convertType(\n\t\t\t\t\t\t\t\t*arguments[arg - 1]->annotation().type,\n\t\t\t\t\t\t\t\t*paramTypes[arg - 1],\n\t\t\t\t\t\t\t\ttrue\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tif (!event.isAnonymous())\n\t\t\t{\n\t\t\t\tm_context << u256(h256::Arith(keccak256(function.externalSignature())));\n\t\t\t\t++numIndexed;\n\t\t\t}\n\t\t\tsolAssert(numIndexed <= 4, \"Too many indexed arguments.\");\n\t\t\t// Copy all non-indexed arguments to memory (data)\n\t\t\t// Memory position is only a hack and should be removed once we have free memory pointer.\n\t\t\tTypePointers nonIndexedArgTypes;\n\t\t\tTypePointers nonIndexedParamTypes;\n\t\t\tfor (unsigned arg = 0; arg < arguments.size(); ++arg)\n\t\t\t\tif (!event.parameters()[arg]->isIndexed())\n\t\t\t\t{\n\t\t\t\t\targuments[arg]->accept(*this);\n\t\t\t\t\tnonIndexedArgTypes.push_back(arguments[arg]->annotation().type);\n\t\t\t\t\tnonIndexedParamTypes.push_back(paramTypes[arg]);\n\t\t\t\t}\n\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\tutils().abiEncode(nonIndexedArgTypes, nonIndexedParamTypes);\n\t\t\t// need: topic1 ... topicn memsize memstart\n\t\t\tutils().toSizeAfterFreeMemoryPointer();\n\t\t\tm_context << logInstruction(numIndexed);\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::Error:\n\t\t{\n\t\t\t// This case is part of the ``revert <error>`` path of the codegen.\n\t\t\t// For ``require(bool, <error>)`` refer to the ``Kind::Require`` case.\n\t\t\t_functionCall.expression().accept(*this);\n\t\t\tstd::vector<Type const*> argumentTypes;\n\t\t\tfor (ASTPointer<Expression const> const& arg: _functionCall.sortedArguments())\n\t\t\t{\n\t\t\t\targ->accept(*this);\n\t\t\t\targumentTypes.push_back(arg->annotation().type);\n\t\t\t}\n\t\t\tsolAssert(dynamic_cast<ErrorDefinition const*>(&function.declaration()), \"\");\n\t\t\tutils().revertWithError(\n\t\t\t\tfunction.externalSignature(),\n\t\t\t\tfunction.parameterTypes(),\n\t\t\t\targumentTypes\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::Wrap:\n\t\tcase FunctionType::Kind::Unwrap:\n\t\t{\n\t\t\tsolAssert(arguments.size() == 1, \"\");\n\t\t\tType const* argumentType = arguments.at(0)->annotation().type;\n\t\t\tType const* functionCallType = _functionCall.annotation().type;\n\t\t\tsolAssert(argumentType, \"\");\n\t\t\tsolAssert(functionCallType, \"\");\n\t\t\tFunctionType::Kind kind = functionType->kind();\n\t\t\tif (kind == FunctionType::Kind::Wrap)\n\t\t\t{\n\t\t\t\tsolAssert(\n\t\t\t\t\targumentType->isImplicitlyConvertibleTo(\n\t\t\t\t\t\tdynamic_cast<UserDefinedValueType const&>(*functionCallType).underlyingType()\n\t\t\t\t\t),\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\t\t\t\tsolAssert(argumentType->isImplicitlyConvertibleTo(*function.parameterTypes()[0]), \"\");\n\t\t\t}\n\t\t\telse\n\t\t\t\tsolAssert(\n\t\t\t\t\tdynamic_cast<UserDefinedValueType const&>(*argumentType) ==\n\t\t\t\t\tdynamic_cast<UserDefinedValueType const&>(*function.parameterTypes()[0]),\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\tacceptAndConvert(*arguments[0], *function.parameterTypes()[0]);\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::BlockHash:\n\t\tcase FunctionType::Kind::BlobHash:\n\t\t{\n\t\t\tacceptAndConvert(*arguments[0], *function.parameterTypes()[0], true);\n\t\t\tif (function.kind() == FunctionType::Kind::BlockHash)\n\t\t\t\tm_context << Instruction::BLOCKHASH;\n\t\t\telse\n\t\t\t\tm_context << Instruction::BLOBHASH;\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::AddMod:\n\t\tcase FunctionType::Kind::MulMod:\n\t\t{\n\t\t\tacceptAndConvert(*arguments[2], *TypeProvider::uint256());\n\t\t\tm_context << Instruction::DUP1 << Instruction::ISZERO;\n\t\t\tm_context.appendConditionalPanic(util::PanicCode::DivisionByZero);\n\t\t\tfor (unsigned i = 1; i < 3; i ++)\n\t\t\t\tacceptAndConvert(*arguments[2 - i], *TypeProvider::uint256());\n\t\t\tif (function.kind() == FunctionType::Kind::AddMod)\n\t\t\t\tm_context << Instruction::ADDMOD;\n\t\t\telse\n\t\t\t\tm_context << Instruction::MULMOD;\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::ECRecover:\n\t\tcase FunctionType::Kind::SHA256:\n\t\tcase FunctionType::Kind::RIPEMD160:\n\t\t{\n\t\t\t_functionCall.expression().accept(*this);\n\t\t\tstatic std::map<FunctionType::Kind, u256> const contractAddresses{\n\t\t\t\t{FunctionType::Kind::ECRecover, 1},\n\t\t\t\t{FunctionType::Kind::SHA256, 2},\n\t\t\t\t{FunctionType::Kind::RIPEMD160, 3}\n\t\t\t};\n\t\t\tm_context << contractAddresses.at(function.kind());\n\t\t\tfor (unsigned i = function.sizeOnStack(); i > 0; --i)\n\t\t\t\tm_context << swapInstruction(i);\n\t\t\tsolAssert(!_functionCall.annotation().tryCall, \"\");\n\t\t\tappendExternalFunctionCall(function, arguments, false);\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::ArrayPush:\n\t\t{\n\t\t\tsolAssert(function.hasBoundFirstArgument(), \"\");\n\t\t\t_functionCall.expression().accept(*this);\n\n\t\t\tif (function.parameterTypes().size() == 0)\n\t\t\t{\n\t\t\t\tauto paramType = function.returnParameterTypes().at(0);\n\t\t\t\tsolAssert(paramType, \"\");\n\n\t\t\t\tArrayType const* arrayType = dynamic_cast<ArrayType const*>(function.selfType());\n\t\t\t\tsolAssert(arrayType, \"\");\n\n\t\t\t\t// stack: ArrayReference\n\t\t\t\tm_context << u256(1) << Instruction::DUP2;\n\t\t\t\tArrayUtils(m_context).incrementDynamicArraySize(*arrayType);\n\t\t\t\t// stack: ArrayReference 1 newLength\n\t\t\t\tm_context << Instruction::SUB;\n\t\t\t\t// stack: ArrayReference (newLength-1)\n\t\t\t\tArrayUtils(m_context).accessIndex(*arrayType, false);\n\n\t\t\t\tif (arrayType->isByteArrayOrString())\n\t\t\t\t\tsetLValue<StorageByteArrayElement>(_functionCall);\n\t\t\t\telse\n\t\t\t\t\tsetLValueToStorageItem(_functionCall);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsolAssert(function.parameterTypes().size() == 1, \"\");\n\t\t\t\tsolAssert(!!function.parameterTypes()[0], \"\");\n\t\t\t\tType const* paramType = function.parameterTypes()[0];\n\t\t\t\tArrayType const* arrayType = dynamic_cast<ArrayType const*>(function.selfType());\n\t\t\t\tsolAssert(arrayType, \"\");\n\n\t\t\t\t// stack: ArrayReference\n\t\t\t\targuments[0]->accept(*this);\n\t\t\t\tType const* argType = arguments[0]->annotation().type;\n\t\t\t\t// stack: ArrayReference argValue\n\t\t\t\tutils().moveToStackTop(argType->sizeOnStack(), 1);\n\t\t\t\t// stack: argValue ArrayReference\n\t\t\t\tm_context << Instruction::DUP1;\n\t\t\t\tArrayUtils(m_context).incrementDynamicArraySize(*arrayType);\n\t\t\t\t// stack: argValue ArrayReference newLength\n\t\t\t\tm_context << u256(1) << Instruction::SWAP1 << Instruction::SUB;\n\t\t\t\t// stack: argValue ArrayReference (newLength-1)\n\t\t\t\tArrayUtils(m_context).accessIndex(*arrayType, false);\n\t\t\t\t// stack: argValue storageSlot slotOffset\n\t\t\t\tutils().moveToStackTop(2, argType->sizeOnStack());\n\t\t\t\t// stack: storageSlot slotOffset argValue\n\t\t\t\tType const* type =\n\t\t\t\t\tarrayType->baseType()->dataStoredIn(DataLocation::Storage) ?\n\t\t\t\t\targuments[0]->annotation().type->mobileType() :\n\t\t\t\t\tarrayType->baseType();\n\t\t\t\tsolAssert(type, \"\");\n\t\t\t\tutils().convertType(*argType, *type);\n\t\t\t\tutils().moveToStackTop(1 + type->sizeOnStack());\n\t\t\t\tutils().moveToStackTop(1 + type->sizeOnStack());\n\t\t\t\t// stack: argValue storageSlot slotOffset\n\t\t\t\tif (!arrayType->isByteArrayOrString())\n\t\t\t\t\tStorageItem(m_context, *paramType).storeValue(*type, _functionCall.location(), true);\n\t\t\t\telse\n\t\t\t\t\tStorageByteArrayElement(m_context).storeValue(*type, _functionCall.location(), true);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::ArrayPop:\n\t\t{\n\t\t\t_functionCall.expression().accept(*this);\n\t\t\tsolAssert(function.hasBoundFirstArgument(), \"\");\n\t\t\tsolAssert(function.parameterTypes().empty(), \"\");\n\t\t\tArrayType const* arrayType = dynamic_cast<ArrayType const*>(function.selfType());\n\t\t\tsolAssert(arrayType && arrayType->dataStoredIn(DataLocation::Storage), \"\");\n\t\t\tArrayUtils(m_context).popStorageArrayElement(*arrayType);\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::StringConcat:\n\t\tcase FunctionType::Kind::BytesConcat:\n\t\t{\n\t\t\t_functionCall.expression().accept(*this);\n\t\t\tstd::vector<Type const*> argumentTypes;\n\t\t\tstd::vector<Type const*> targetTypes;\n\t\t\tfor (auto const& argument: arguments)\n\t\t\t{\n\t\t\t\targument->accept(*this);\n\t\t\t\tsolAssert(argument->annotation().type, \"\");\n\t\t\t\targumentTypes.emplace_back(argument->annotation().type);\n\t\t\t\tif (argument->annotation().type->category() == Type::Category::FixedBytes)\n\t\t\t\t\ttargetTypes.emplace_back(argument->annotation().type);\n\t\t\t\telse if (\n\t\t\t\t\tauto const* literalType = dynamic_cast<StringLiteralType const*>(argument->annotation().type);\n\t\t\t\t\tliteralType && !literalType->value().empty() && literalType->value().size() <= 32\n\t\t\t\t)\n\t\t\t\t\ttargetTypes.emplace_back(TypeProvider::fixedBytes(static_cast<unsigned>(literalType->value().size())));\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsolAssert(!dynamic_cast<RationalNumberType const*>(argument->annotation().type), \"\");\n\t\t\t\t\tif (function.kind() == FunctionType::Kind::StringConcat)\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(argument->annotation().type->isImplicitlyConvertibleTo(*TypeProvider::stringMemory()), \"\");\n\t\t\t\t\t\ttargetTypes.emplace_back(TypeProvider::stringMemory());\n\t\t\t\t\t}\n\t\t\t\t\telse if (function.kind() == FunctionType::Kind::BytesConcat)\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(argument->annotation().type->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()), \"\");\n\t\t\t\t\t\ttargetTypes.emplace_back(TypeProvider::bytesMemory());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\t// stack: <arg1> <arg2> ... <argn> <free mem>\n\t\t\tm_context << u256(32) << Instruction::ADD;\n\t\t\tutils().packedEncode(argumentTypes, targetTypes);\n\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\tm_context.appendInlineAssembly(R\"({\n\t\t\t\tmstore(mem_ptr, sub(sub(mem_end, mem_ptr), 0x20))\n\t\t\t})\", {\"mem_end\", \"mem_ptr\"});\n\t\t\tm_context << Instruction::SWAP1;\n\t\t\tutils().storeFreeMemoryPointer();\n\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::ObjectCreation:\n\t\t{\n\t\t\tArrayType const& arrayType = dynamic_cast<ArrayType const&>(*_functionCall.annotation().type);\n\t\t\t_functionCall.expression().accept(*this);\n\t\t\tsolAssert(arguments.size() == 1, \"\");\n\n\t\t\t// Fetch requested length.\n\t\t\tacceptAndConvert(*arguments[0], *TypeProvider::uint256());\n\n\t\t\t// Make sure we can allocate memory without overflow\n\t\t\tm_context << u256(0xffffffffffffffff);\n\t\t\tm_context << Instruction::DUP2;\n\t\t\tm_context << Instruction::GT;\n\t\t\tm_context.appendConditionalPanic(PanicCode::ResourceError);\n\n\t\t\t// Stack: requested_length\n\t\t\tutils().fetchFreeMemoryPointer();\n\n\t\t\t// Stack: requested_length memptr\n\t\t\tm_context << Instruction::SWAP1;\n\t\t\t// Stack: memptr requested_length\n\t\t\t// store length\n\t\t\tm_context << Instruction::DUP1 << Instruction::DUP3 << Instruction::MSTORE;\n\t\t\t// Stack: memptr requested_length\n\t\t\t// update free memory pointer\n\t\t\tm_context << Instruction::DUP1;\n\t\t\t// Stack: memptr requested_length requested_length\n\t\t\tif (arrayType.isByteArrayOrString())\n\t\t\t\t// Round up to multiple of 32\n\t\t\t\tm_context << u256(31) << Instruction::ADD << u256(31) << Instruction::NOT << Instruction::AND;\n\t\t\telse\n\t\t\t\tm_context << arrayType.baseType()->memoryHeadSize() << Instruction::MUL;\n\t\t\t// stacK: memptr requested_length data_size\n\t\t\tm_context << u256(32) << Instruction::ADD;\n\t\t\tm_context << Instruction::DUP3 << Instruction::ADD;\n\t\t\tutils().storeFreeMemoryPointer();\n\t\t\t// Stack: memptr requested_length\n\n\t\t\t// Check if length is zero\n\t\t\tm_context << Instruction::DUP1 << Instruction::ISZERO;\n\t\t\tauto skipInit = m_context.appendConditionalJump();\n\t\t\t// Always initialize because the free memory pointer might point at\n\t\t\t// a dirty memory area.\n\t\t\tm_context << Instruction::DUP2 << u256(32) << Instruction::ADD;\n\t\t\tutils().zeroInitialiseMemoryArray(arrayType);\n\t\t\tm_context << skipInit;\n\t\t\tm_context << Instruction::POP;\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::Assert:\n\t\tcase FunctionType::Kind::Require:\n\t\t{\n\t\t\tacceptAndConvert(*arguments.front(), *function.parameterTypes().front(), false);\n\t\t\t// stack: <condition>\n\t\t\tbool haveReasonString = arguments.size() > 1 && m_context.revertStrings() != RevertStrings::Strip;\n\t\t\tif (arguments.size() > 1)\n\t\t\t{\n\t\t\t\t// Users probably expect the second argument to be evaluated\n\t\t\t\t// even if the condition is false, as would be the case for an actual\n\t\t\t\t// function call.\n\t\t\t\tsolAssert(arguments.size() == 2, \"\");\n\t\t\t\tsolAssert(function.kind() == FunctionType::Kind::Require, \"\");\n\t\t\t\tauto const* magicType = dynamic_cast<MagicType const*>(arguments[1]->annotation().type);\n\t\t\t\tif (magicType && magicType->kind() == MagicType::Kind::Error)\n\t\t\t\t{\n\t\t\t\t\t// Make sure that error constructor arguments are evaluated regardless of the require condition\n\t\t\t\t\tauto const& errorConstructorCall = dynamic_cast<FunctionCall const&>(*arguments[1]);\n\t\t\t\t\terrorConstructorCall.expression().accept(*this);\n\t\t\t\t\tstd::vector<Type const*> errorConstructorArgumentTypes{};\n\t\t\t\t\tfor (ASTPointer<Expression const> const& errorConstructorArgument: errorConstructorCall.sortedArguments())\n\t\t\t\t\t{\n\t\t\t\t\t\terrorConstructorArgument->accept(*this);\n\t\t\t\t\t\terrorConstructorArgumentTypes.push_back(errorConstructorArgument->annotation().type);\n\t\t\t\t\t}\n\t\t\t\t\tunsigned const sizeOfConditionArgument = arguments.at(0)->annotation().type->sizeOnStack();\n\t\t\t\t\tunsigned const sizeOfErrorArguments = CompilerUtils::sizeOnStack(errorConstructorArgumentTypes);\n\t\t\t\t\t// stack: <condition> <arg0> <arg1> ... <argN>\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\t// Move condition to the top of the stack\n\t\t\t\t\t\tutils().moveToStackTop(sizeOfErrorArguments, sizeOfConditionArgument);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (StackTooDeepError const& _exception)\n\t\t\t\t\t{\n\t\t\t\t\t\t_exception << errinfo_sourceLocation(errorConstructorCall.location());\n\t\t\t\t\t\tthrow _exception;\n\t\t\t\t\t}\n\t\t\t\t\t// stack: <arg0> <arg1> ... <argN> <condition>\n\t\t\t\t\tm_context << Instruction::ISZERO << Instruction::ISZERO;\n\t\t\t\t\tAssemblyItem successBranchTag = m_context.appendConditionalJump();\n\n\t\t\t\t\tauto const* errorDefinition = dynamic_cast<ErrorDefinition const*>(ASTNode::referencedDeclaration(errorConstructorCall.expression()));\n\t\t\t\t\tsolAssert(errorDefinition && errorDefinition->functionType(true));\n\t\t\t\t\tutils().revertWithError(\n\t\t\t\t\t\terrorDefinition->functionType(true)->externalSignature(),\n\t\t\t\t\t\terrorDefinition->functionType(true)->parameterTypes(),\n\t\t\t\t\t\terrorConstructorArgumentTypes\n\t\t\t\t\t);\n\t\t\t\t\t// Here, the argument is consumed, but in the other branch, it is still there.\n\t\t\t\t\tm_context.adjustStackOffset(static_cast<int>(sizeOfErrorArguments));\n\t\t\t\t\tm_context << successBranchTag;\n\t\t\t\t\t// In case of the success branch i.e. require(true, ...), pop error constructor arguments\n\t\t\t\t\tutils().popStackSlots(sizeOfErrorArguments);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (m_context.revertStrings() == RevertStrings::Strip)\n\t\t\t\t{\n\t\t\t\t\tif (!*arguments.at(1)->annotation().isPure)\n\t\t\t\t\t{\n\t\t\t\t\t\targuments.at(1)->accept(*this);\n\t\t\t\t\t\tutils().popStackElement(*arguments.at(1)->annotation().type);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\targuments.at(1)->accept(*this);\n\t\t\t\t\tutils().moveIntoStack(1, arguments.at(1)->annotation().type->sizeOnStack());\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Stack: <error string (unconverted)> <condition>\n\t\t\t// jump if condition was met\n\t\t\tm_context << Instruction::ISZERO << Instruction::ISZERO;\n\t\t\tauto success = m_context.appendConditionalJump();\n\t\t\tif (function.kind() == FunctionType::Kind::Assert)\n\t\t\t\t// condition was not met, flag an error\n\t\t\t\tm_context.appendPanic(util::PanicCode::Assert);\n\t\t\telse if (haveReasonString)\n\t\t\t{\n\t\t\t\tutils().revertWithStringData(*arguments.at(1)->annotation().type);\n\t\t\t\t// Here, the argument is consumed, but in the other branch, it is still there.\n\t\t\t\tm_context.adjustStackOffset(static_cast<int>(arguments.at(1)->annotation().type->sizeOnStack()));\n\t\t\t}\n\t\t\telse\n\t\t\t\tm_context.appendRevert();\n\t\t\t// the success branch\n\t\t\tm_context << success;\n\t\t\tif (haveReasonString)\n\t\t\t\tutils().popStackElement(*arguments.at(1)->annotation().type);\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::ABIEncode:\n\t\tcase FunctionType::Kind::ABIEncodePacked:\n\t\tcase FunctionType::Kind::ABIEncodeWithSelector:\n\t\tcase FunctionType::Kind::ABIEncodeCall:\n\t\tcase FunctionType::Kind::ABIEncodeWithSignature:\n\t\t{\n\t\t\tbool const isPacked = function.kind() == FunctionType::Kind::ABIEncodePacked;\n\t\t\tbool const hasSelectorOrSignature =\n\t\t\t\tfunction.kind() == FunctionType::Kind::ABIEncodeWithSelector ||\n\t\t\t\tfunction.kind() == FunctionType::Kind::ABIEncodeCall ||\n\t\t\t\tfunction.kind() == FunctionType::Kind::ABIEncodeWithSignature;\n\n\t\t\tTypePointers argumentTypes;\n\t\t\tTypePointers targetTypes;\n\n\t\t\tASTNode::listAccept(arguments, *this);\n\n\t\t\tif (function.kind() == FunctionType::Kind::ABIEncodeCall)\n\t\t\t{\n\t\t\t\tsolAssert(arguments.size() == 2);\n\n\t\t\t\t// Account for tuples with one component which become that component\n\t\t\t\tif (auto const tupleType = dynamic_cast<TupleType const*>(arguments[1]->annotation().type))\n\t\t\t\t\targumentTypes = tupleType->components();\n\t\t\t\telse\n\t\t\t\t\targumentTypes.emplace_back(arguments[1]->annotation().type);\n\n\t\t\t\tauto functionPtr = dynamic_cast<FunctionTypePointer>(arguments[0]->annotation().type);\n\t\t\t\tsolAssert(functionPtr);\n\t\t\t\tfunctionPtr = functionPtr->asExternallyCallableFunction(false);\n\t\t\t\tsolAssert(functionPtr);\n\t\t\t\ttargetTypes = functionPtr->parameterTypes();\n\t\t\t}\n\t\t\telse\n\t\t\t\tfor (unsigned i = 0; i < arguments.size(); ++i)\n\t\t\t\t{\n\t\t\t\t\t// Do not keep the selector as part of the ABI encoded args\n\t\t\t\t\tif (!hasSelectorOrSignature || i > 0)\n\t\t\t\t\t\targumentTypes.push_back(arguments[i]->annotation().type);\n\t\t\t\t}\n\n\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\t// stack now: [<selector/functionPointer/signature>] <arg1> .. <argN> <free_mem>\n\n\t\t\t// adjust by 32(+4) bytes to accommodate the length(+selector)\n\t\t\tm_context << u256(32 + (hasSelectorOrSignature ? 4 : 0)) << Instruction::ADD;\n\t\t\t// stack now: [<selector/functionPointer/signature>] <arg1> .. <argN> <data_encoding_area_start>\n\n\t\t\tif (isPacked)\n\t\t\t{\n\t\t\t\tsolAssert(!function.padArguments(), \"\");\n\t\t\t\tutils().packedEncode(argumentTypes, targetTypes);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsolAssert(function.padArguments(), \"\");\n\t\t\t\tutils().abiEncode(argumentTypes, targetTypes);\n\t\t\t}\n\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\t// stack: [<selector/functionPointer/signature>] <data_encoding_area_end> <bytes_memory_ptr>\n\n\t\t\t// size is end minus start minus length slot\n\t\t\tm_context.appendInlineAssembly(R\"({\n\t\t\t\tmstore(mem_ptr, sub(sub(mem_end, mem_ptr), 0x20))\n\t\t\t})\", {\"mem_end\", \"mem_ptr\"});\n\t\t\tm_context << Instruction::SWAP1;\n\t\t\tutils().storeFreeMemoryPointer();\n\t\t\t// stack: [<selector/functionPointer/signature>] <memory ptr>\n\n\t\t\tif (hasSelectorOrSignature)\n\t\t\t{\n\t\t\t\t// stack: <selector/functionPointer/signature> <memory pointer>\n\t\t\t\tsolAssert(arguments.size() >= 1, \"\");\n\t\t\t\tType const* selectorType = arguments[0]->annotation().type;\n\t\t\t\tutils().moveIntoStack(selectorType->sizeOnStack());\n\t\t\t\tType const* dataOnStack = selectorType;\n\n\t\t\t\t// stack: <memory pointer> <selector/functionPointer/signature>\n\t\t\t\tif (function.kind() == FunctionType::Kind::ABIEncodeWithSignature)\n\t\t\t\t{\n\t\t\t\t\t// hash the signature\n\t\t\t\t\tif (auto const* stringType = dynamic_cast<StringLiteralType const*>(selectorType))\n\t\t\t\t\t{\n\t\t\t\t\t\tm_context << util::selectorFromSignatureU256(stringType->value());\n\t\t\t\t\t\tdataOnStack = TypeProvider::fixedBytes(4);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\t\t\t\t// stack: <memory pointer> <signature> <free mem ptr>\n\t\t\t\t\t\tutils().packedEncode(TypePointers{selectorType}, TypePointers());\n\t\t\t\t\t\tutils().toSizeAfterFreeMemoryPointer();\n\t\t\t\t\t\tm_context << Instruction::KECCAK256;\n\t\t\t\t\t\t// stack: <memory pointer> <hash>\n\n\t\t\t\t\t\tdataOnStack = TypeProvider::fixedBytes(32);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (function.kind() == FunctionType::Kind::ABIEncodeCall)\n\t\t\t\t{\n\t\t\t\t\tauto const& funType = dynamic_cast<FunctionType const&>(*selectorType);\n\t\t\t\t\tif (funType.kind() == FunctionType::Kind::Declaration)\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(funType.hasDeclaration());\n\t\t\t\t\t\tsolAssert(selectorType->sizeOnStack() == 0);\n\t\t\t\t\t\tm_context << funType.externalIdentifier();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(selectorType->sizeOnStack() == 2);\n\t\t\t\t\t\t// stack: <memory pointer> <functionPointer>\n\t\t\t\t\t\t// Extract selector from the stack\n\t\t\t\t\t\tm_context << Instruction::SWAP1 << Instruction::POP;\n\t\t\t\t\t}\n\t\t\t\t\t// Conversion will be done below\n\t\t\t\t\tdataOnStack = TypeProvider::uint(32);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tsolAssert(function.kind() == FunctionType::Kind::ABIEncodeWithSelector, \"\");\n\n\t\t\t\tutils().convertType(*dataOnStack, FixedBytesType(4), true);\n\n\t\t\t\t// stack: <memory pointer> <selector>\n\n\t\t\t\t// load current memory, mask and combine the selector\n\t\t\t\tstd::string mask = formatNumber((u256(-1) >> 32));\n\t\t\t\tm_context.appendInlineAssembly(R\"({\n\t\t\t\t\tlet data_start := add(mem_ptr, 0x20)\n\t\t\t\t\tlet data := mload(data_start)\n\t\t\t\t\tlet mask := )\" + mask + R\"(\n\t\t\t\t\tmstore(data_start, or(and(data, mask), selector))\n\t\t\t\t})\", {\"mem_ptr\", \"selector\"});\n\t\t\t\tm_context << Instruction::POP;\n\t\t\t}\n\n\t\t\t// stack now: <memory pointer>\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::ABIDecode:\n\t\t{\n\t\t\targuments.front()->accept(*this);\n\t\t\tType const* firstArgType = arguments.front()->annotation().type;\n\t\t\tTypePointers targetTypes;\n\t\t\tif (TupleType const* targetTupleType = dynamic_cast<TupleType const*>(_functionCall.annotation().type))\n\t\t\t\ttargetTypes = targetTupleType->components();\n\t\t\telse\n\t\t\t\ttargetTypes = TypePointers{_functionCall.annotation().type};\n\t\t\tif (\n\t\t\t\tauto referenceType = dynamic_cast<ReferenceType const*>(firstArgType);\n\t\t\t\treferenceType && referenceType->dataStoredIn(DataLocation::CallData)\n\t\t\t)\n\t\t\t{\n\t\t\t\tsolAssert(referenceType->isImplicitlyConvertibleTo(*TypeProvider::bytesCalldata()), \"\");\n\t\t\t\tutils().convertType(*referenceType, *TypeProvider::bytesCalldata());\n\t\t\t\tutils().abiDecode(targetTypes, false);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tutils().convertType(*firstArgType, *TypeProvider::bytesMemory());\n\t\t\t\tm_context << Instruction::DUP1 << u256(32) << Instruction::ADD;\n\t\t\t\tm_context << Instruction::SWAP1 << Instruction::MLOAD;\n\t\t\t\t// stack now: <mem_pos> <length>\n\n\t\t\t\tutils().abiDecode(targetTypes, true);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase FunctionType::Kind::GasLeft:\n\t\t\tm_context << Instruction::GAS;\n\t\t\tbreak;\n\t\tcase FunctionType::Kind::MetaType:\n\t\t\t// No code to generate.\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn false;\n}\n\nbool ExpressionCompiler::visit(FunctionCallOptions const& _functionCallOptions)\n{\n\t_functionCallOptions.expression().accept(*this);\n\n\t// Desired Stack: [salt], [gas], [value]\n\tenum Option { Salt, Gas, Value };\n\n\tstd::vector<Option> presentOptions;\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(\n\t\t*_functionCallOptions.expression().annotation().type\n\t);\n\tif (funType.saltSet()) presentOptions.emplace_back(Salt);\n\tif (funType.gasSet()) presentOptions.emplace_back(Gas);\n\tif (funType.valueSet()) presentOptions.emplace_back(Value);\n\n\tfor (size_t i = 0; i < _functionCallOptions.options().size(); ++i)\n\t{\n\t\tstd::string const& name = *_functionCallOptions.names()[i];\n\t\tType const* requiredType = TypeProvider::uint256();\n\t\tOption newOption;\n\t\tif (name == \"salt\")\n\t\t{\n\t\t\tnewOption = Salt;\n\t\t\trequiredType = TypeProvider::fixedBytes(32);\n\t\t}\n\t\telse if (name == \"gas\")\n\t\t\tnewOption = Gas;\n\t\telse if (name == \"value\")\n\t\t\tnewOption = Value;\n\t\telse\n\t\t\tsolAssert(false, \"Unexpected option name!\");\n\t\tacceptAndConvert(*_functionCallOptions.options()[i], *requiredType);\n\n\t\tsolAssert(!util::contains(presentOptions, newOption), \"\");\n\t\tptrdiff_t insertPos = presentOptions.end() - lower_bound(presentOptions.begin(), presentOptions.end(), newOption);\n\n\t\tutils().moveIntoStack(static_cast<unsigned>(insertPos), 1);\n\t\tpresentOptions.insert(presentOptions.end() - insertPos, newOption);\n\t}\n\n\treturn false;\n}\n\nbool ExpressionCompiler::visit(NewExpression const&)\n{\n\t// code is created for the function call (CREATION) only\n\treturn false;\n}\n\nbool ExpressionCompiler::visit(MemberAccess const& _memberAccess)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _memberAccess);\n\t// Check whether the member is an attached function.\n\tASTString const& member = _memberAccess.memberName();\n\tif (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type))\n\t\tif (funType->hasBoundFirstArgument())\n\t\t{\n\t\t\tacceptAndConvert(_memberAccess.expression(), *funType->selfType(), true);\n\t\t\tif (funType->kind() == FunctionType::Kind::Internal)\n\t\t\t{\n\t\t\t\tFunctionDefinition const& funDef = dynamic_cast<decltype(funDef)>(funType->declaration());\n\t\t\t\tsolAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Static, \"\");\n\t\t\t\tutils().pushCombinedFunctionEntryLabel(\n\t\t\t\t\tfunDef,\n\t\t\t\t\t// If we call directly, do not include the second label.\n\t\t\t\t\t!_memberAccess.annotation().calledDirectly\n\t\t\t\t);\n\t\t\t\tutils().moveIntoStack(funType->selfType()->sizeOnStack(), 1);\n\t\t\t}\n\t\t\telse if (\n\t\t\t\tfunType->kind() == FunctionType::Kind::ArrayPop ||\n\t\t\t\tfunType->kind() == FunctionType::Kind::ArrayPush\n\t\t\t)\n\t\t\t{\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsolAssert(funType->kind() == FunctionType::Kind::DelegateCall, \"\");\n\t\t\t\tauto contract = dynamic_cast<ContractDefinition const*>(funType->declaration().scope());\n\t\t\t\tsolAssert(contract && contract->isLibrary(), \"\");\n\t\t\t\tm_context.appendLibraryAddress(contract->fullyQualifiedName());\n\t\t\t\tm_context << funType->externalIdentifier();\n\t\t\t\tutils().moveIntoStack(funType->selfType()->sizeOnStack(), 2);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t// Special processing for TypeType because we do not want to visit the library itself\n\t// for internal functions, or enum/struct definitions.\n\tif (TypeType const* type = dynamic_cast<TypeType const*>(_memberAccess.expression().annotation().type))\n\t{\n\t\tif (auto contractType = dynamic_cast<ContractType const*>(type->actualType()))\n\t\t{\n\t\t\tsolAssert(_memberAccess.annotation().type, \"_memberAccess has no type\");\n\t\t\tif (contractType->isSuper())\n\t\t\t{\n\t\t\t\t_memberAccess.expression().accept(*this);\n\t\t\t\tsolAssert(_memberAccess.annotation().referencedDeclaration, \"Referenced declaration not resolved.\");\n\t\t\t\tsolAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Super, \"\");\n\t\t\t\tutils().pushCombinedFunctionEntryLabel(\n\t\t\t\t\tm_context.superFunction(\n\t\t\t\t\t\tdynamic_cast<FunctionDefinition const&>(*_memberAccess.annotation().referencedDeclaration),\n\t\t\t\t\t\tcontractType->contractDefinition()\n\t\t\t\t\t),\n\t\t\t\t\t// If we call directly, do not include the second label.\n\t\t\t\t\t!_memberAccess.annotation().calledDirectly\n\t\t\t\t);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (auto variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t\t\t\tappendVariable(*variable, static_cast<Expression const&>(_memberAccess));\n\t\t\t\telse if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type))\n\t\t\t\t{\n\t\t\t\t\tswitch (funType->kind())\n\t\t\t\t\t{\n\t\t\t\t\tcase FunctionType::Kind::Declaration:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase FunctionType::Kind::Internal:\n\t\t\t\t\t\t// We do not visit the expression here on purpose, because in the case of an\n\t\t\t\t\t\t// internal library function call, this would push the library address forcing\n\t\t\t\t\t\t// us to link against it although we actually do not need it.\n\t\t\t\t\t\tif (auto const* function = dynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsolAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Static, \"\");\n\t\t\t\t\t\t\tutils().pushCombinedFunctionEntryLabel(\n\t\t\t\t\t\t\t\t*function,\n\t\t\t\t\t\t\t\t// If we call directly, do not include the second label.\n\t\t\t\t\t\t\t\t!_memberAccess.annotation().calledDirectly\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsolAssert(false, \"Function not found in member access\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase FunctionType::Kind::Event:\n\t\t\t\t\t\tif (!dynamic_cast<EventDefinition const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t\t\t\t\t\tsolAssert(false, \"event not found\");\n\t\t\t\t\t\t// no-op, because the parent node will do the job\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase FunctionType::Kind::Error:\n\t\t\t\t\t\tif (!dynamic_cast<ErrorDefinition const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t\t\t\t\t\tsolAssert(false, \"error not found\");\n\t\t\t\t\t\t// no-op, because the parent node will do the job\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase FunctionType::Kind::DelegateCall:\n\t\t\t\t\t\t_memberAccess.expression().accept(*this);\n\t\t\t\t\t\tm_context << funType->externalIdentifier();\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase FunctionType::Kind::External:\n\t\t\t\t\tcase FunctionType::Kind::Creation:\n\t\t\t\t\tcase FunctionType::Kind::Send:\n\t\t\t\t\tcase FunctionType::Kind::BareCall:\n\t\t\t\t\tcase FunctionType::Kind::BareCallCode:\n\t\t\t\t\tcase FunctionType::Kind::BareDelegateCall:\n\t\t\t\t\tcase FunctionType::Kind::BareStaticCall:\n\t\t\t\t\tcase FunctionType::Kind::Transfer:\n\t\t\t\t\tcase FunctionType::Kind::ECRecover:\n\t\t\t\t\tcase FunctionType::Kind::SHA256:\n\t\t\t\t\tcase FunctionType::Kind::RIPEMD160:\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsolAssert(false, \"unsupported member function\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (dynamic_cast<TypeType const*>(_memberAccess.annotation().type))\n\t\t\t\t{\n\t\t\t\t\t// no-op\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\t_memberAccess.expression().accept(*this);\n\t\t\t}\n\t\t}\n\t\telse if (auto enumType = dynamic_cast<EnumType const*>(type->actualType()))\n\t\t{\n\t\t\t_memberAccess.expression().accept(*this);\n\t\t\tm_context << enumType->memberValue(_memberAccess.memberName());\n\t\t}\n\t\telse\n\t\t\t_memberAccess.expression().accept(*this);\n\t\treturn false;\n\t}\n\t// Another special case for `this.f.selector` and for ``C.f.selector`` which do not need the address.\n\t// There are other uses of `.selector` which do need the address, but we want these\n\t// specific uses to be pure expressions.\n\tif (\n\t\tauto const* functionType = dynamic_cast<FunctionType const*>(_memberAccess.expression().annotation().type);\n\t\tfunctionType && member == \"selector\"\n\t)\n\t{\n\t\tif (functionType->hasDeclaration())\n\t\t{\n\t\t\t// Still visit the expression in case it has side effects.\n\t\t\t_memberAccess.expression().accept(*this);\n\t\t\tutils().popStackElement(*functionType);\n\n\t\t\tif (functionType->kind() == FunctionType::Kind::Event)\n\t\t\t\tm_context << u256(h256::Arith(util::keccak256(functionType->externalSignature())));\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_context << functionType->externalIdentifier();\n\t\t\t\t/// need to store it as bytes4\n\t\t\t\tutils().leftShiftNumberOnStack(224);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\telse if (auto const* expr = dynamic_cast<MemberAccess const*>(&_memberAccess.expression()))\n\t\t\tif (auto const* exprInt = dynamic_cast<Identifier const*>(&expr->expression()))\n\t\t\t\tif (exprInt->name() == \"this\")\n\t\t\t\t\tif (Declaration const* declaration = expr->annotation().referencedDeclaration)\n\t\t\t\t\t{\n\t\t\t\t\t\tu256 identifier;\n\t\t\t\t\t\tif (auto const* variable = dynamic_cast<VariableDeclaration const*>(declaration))\n\t\t\t\t\t\t\tidentifier = FunctionType(*variable).externalIdentifier();\n\t\t\t\t\t\telse if (auto const* function = dynamic_cast<FunctionDefinition const*>(declaration))\n\t\t\t\t\t\t\tidentifier = FunctionType(*function).externalIdentifier();\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsolAssert(false, \"Contract member is neither variable nor function.\");\n\t\t\t\t\t\tm_context << identifier;\n\t\t\t\t\t\t/// need to store it as bytes4\n\t\t\t\t\t\tutils().leftShiftNumberOnStack(224);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t}\n\t// Another special case for `address(this).balance`. Post-Istanbul, we can use the selfbalance\n\t// opcode.\n\tif (\n\t\tm_context.evmVersion().hasSelfBalance() &&\n\t\tmember == \"balance\" &&\n\t\t_memberAccess.expression().annotation().type->category() == Type::Category::Address\n\t)\n\t\tif (FunctionCall const* funCall = dynamic_cast<FunctionCall const*>(&_memberAccess.expression()))\n\t\t\tif (auto const* addr = dynamic_cast<ElementaryTypeNameExpression const*>(&funCall->expression()))\n\t\t\t\tif (\n\t\t\t\t\taddr->type().typeName().token() == Token::Address &&\n\t\t\t\t\tfunCall->arguments().size() == 1\n\t\t\t\t)\n\t\t\t\t\tif (auto arg = dynamic_cast<Identifier const*>( funCall->arguments().front().get()))\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\targ->name() == \"this\" &&\n\t\t\t\t\t\t\tdynamic_cast<MagicVariableDeclaration const*>(arg->annotation().referencedDeclaration)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tm_context << Instruction::SELFBALANCE;\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t// Another special case for `address.code.length`, which should simply call extcodesize\n\tif (\n\t\tauto innerExpression = dynamic_cast<MemberAccess const*>(&_memberAccess.expression());\n\t\tmember == \"length\" &&\n\t\tinnerExpression &&\n\t\tinnerExpression->memberName() == \"code\" &&\n\t\tinnerExpression->expression().annotation().type->category() == Type::Category::Address\n\t)\n\t{\n\t\tsolAssert(innerExpression->annotation().type->category() == Type::Category::Array, \"\");\n\n\t\tinnerExpression->expression().accept(*this);\n\n\t\tutils().convertType(\n\t\t\t*innerExpression->expression().annotation().type,\n\t\t\t*TypeProvider::address(),\n\t\t\ttrue\n\t\t);\n\t\tm_context << Instruction::EXTCODESIZE;\n\n\t\treturn false;\n\t}\n\n\t_memberAccess.expression().accept(*this);\n\tswitch (_memberAccess.expression().annotation().type->category())\n\t{\n\tcase Type::Category::Contract:\n\t{\n\t\tContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);\n\t\t// ordinary contract type\n\t\tif (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)\n\t\t{\n\t\t\tu256 identifier;\n\t\t\tif (auto const* variable = dynamic_cast<VariableDeclaration const*>(declaration))\n\t\t\t\tidentifier = FunctionType(*variable).externalIdentifier();\n\t\t\telse if (auto const* function = dynamic_cast<FunctionDefinition const*>(declaration))\n\t\t\t\tidentifier = FunctionType(*function).externalIdentifier();\n\t\t\telse\n\t\t\t\tsolAssert(false, \"Contract member is neither variable nor function.\");\n\t\t\tutils().convertType(type, type.isPayable() ? *TypeProvider::payableAddress() : *TypeProvider::address(), true);\n\t\t\tm_context << identifier;\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"Invalid member access in contract\");\n\t\tbreak;\n\t}\n\tcase Type::Category::Integer:\n\t{\n\t\tsolAssert(false, \"Invalid member access to integer\");\n\t\tbreak;\n\t}\n\tcase Type::Category::Address:\n\t{\n\t\tif (member == \"balance\")\n\t\t{\n\t\t\tutils().convertType(\n\t\t\t\t*_memberAccess.expression().annotation().type,\n\t\t\t\t*TypeProvider::address(),\n\t\t\t\ttrue\n\t\t\t);\n\t\t\tm_context << Instruction::BALANCE;\n\t\t}\n\t\telse if (member == \"code\")\n\t\t{\n\t\t\t// Stack: <address>\n\t\t\tutils().convertType(\n\t\t\t\t*_memberAccess.expression().annotation().type,\n\t\t\t\t*TypeProvider::address(),\n\t\t\t\ttrue\n\t\t\t);\n\n\t\t\tm_context << Instruction::DUP1 << Instruction::EXTCODESIZE;\n\t\t\t// Stack post: <address> <size>\n\n\t\t\tm_context << Instruction::DUP1;\n\t\t\t// Account for the size field of `bytes memory`\n\t\t\tm_context << u256(32) << Instruction::ADD;\n\t\t\tutils().allocateMemory();\n\t\t\t// Stack post: <address> <size> <mem_offset>\n\n\t\t\t// Store size at mem_offset\n\t\t\tm_context << Instruction::DUP2 << Instruction::DUP2 << Instruction::MSTORE;\n\n\t\t\tm_context << u256(0) << Instruction::SWAP1 << Instruction::DUP1;\n\t\t\t// Stack post: <address> <size> 0 <mem_offset> <mem_offset>\n\n\t\t\tm_context << u256(32) << Instruction::ADD << Instruction::SWAP1;\n\t\t\t// Stack post: <address> <size> 0 <mem_offset_adjusted> <mem_offset>\n\n\t\t\tm_context << Instruction::SWAP4;\n\t\t\t// Stack post: <mem_offset> <size> 0 <mem_offset_adjusted> <address>\n\n\t\t\tm_context << Instruction::EXTCODECOPY;\n\t\t\t// Stack post: <mem_offset>\n\t\t}\n\t\telse if (member == \"codehash\")\n\t\t{\n\t\t\tutils().convertType(\n\t\t\t\t*_memberAccess.expression().annotation().type,\n\t\t\t\t*TypeProvider::address(),\n\t\t\t\ttrue\n\t\t\t);\n\t\t\tm_context << Instruction::EXTCODEHASH;\n\t\t}\n\t\telse if ((std::set<std::string>{\"send\", \"transfer\"}).count(member))\n\t\t{\n\t\t\tsolAssert(dynamic_cast<AddressType const&>(*_memberAccess.expression().annotation().type).stateMutability() == StateMutability::Payable, \"\");\n\t\t\tutils().convertType(\n\t\t\t\t*_memberAccess.expression().annotation().type,\n\t\t\t\tAddressType(StateMutability::Payable),\n\t\t\t\ttrue\n\t\t\t);\n\t\t}\n\t\telse if ((std::set<std::string>{\"call\", \"callcode\", \"delegatecall\", \"staticcall\"}).count(member))\n\t\t\tutils().convertType(\n\t\t\t\t*_memberAccess.expression().annotation().type,\n\t\t\t\t*TypeProvider::address(),\n\t\t\t\ttrue\n\t\t\t);\n\t\telse\n\t\t\tsolAssert(false, \"Invalid member access to address\");\n\t\tbreak;\n\t}\n\tcase Type::Category::Function:\n\t\tif (member == \"selector\")\n\t\t{\n\t\t\tauto const& functionType = dynamic_cast<FunctionType const&>(*_memberAccess.expression().annotation().type);\n\t\t\t// all events should have already been caught by this stage\n\t\t\tsolAssert(!(functionType.kind() == FunctionType::Kind::Event));\n\n\t\t\tif (functionType.kind() == FunctionType::Kind::External)\n\t\t\t\tCompilerUtils(m_context).popStackSlots(functionType.sizeOnStack() - 2);\n\t\t\tm_context << Instruction::SWAP1 << Instruction::POP;\n\n\t\t\t/// need to store it as bytes4\n\t\t\tutils().leftShiftNumberOnStack(224);\n\t\t}\n\t\telse if (member == \"address\")\n\t\t{\n\t\t\tauto const& functionType = dynamic_cast<FunctionType const&>(*_memberAccess.expression().annotation().type);\n\t\t\tsolAssert(functionType.kind() == FunctionType::Kind::External, \"\");\n\t\t\tCompilerUtils(m_context).popStackSlots(functionType.sizeOnStack() - 1);\n\t\t}\n\t\telse\n\t\t\tsolAssert(\n\t\t\t\t!!_memberAccess.expression().annotation().type->memberType(member),\n\t\t\t\t\"Invalid member access to function.\"\n\t\t\t);\n\t\tbreak;\n\tcase Type::Category::Magic:\n\t\t// we can ignore the kind of magic and only look at the name of the member\n\t\tif (member == \"coinbase\")\n\t\t\tm_context << Instruction::COINBASE;\n\t\telse if (member == \"timestamp\")\n\t\t\tm_context << Instruction::TIMESTAMP;\n\t\telse if (member == \"difficulty\" || member == \"prevrandao\")\n\t\t\tm_context << Instruction::PREVRANDAO;\n\t\telse if (member == \"number\")\n\t\t\tm_context << Instruction::NUMBER;\n\t\telse if (member == \"gaslimit\")\n\t\t\tm_context << Instruction::GASLIMIT;\n\t\telse if (member == \"sender\")\n\t\t\tm_context << Instruction::CALLER;\n\t\telse if (member == \"value\")\n\t\t\tm_context << Instruction::CALLVALUE;\n\t\telse if (member == \"origin\")\n\t\t\tm_context << Instruction::ORIGIN;\n\t\telse if (member == \"gasprice\")\n\t\t\tm_context << Instruction::GASPRICE;\n\t\telse if (member == \"chainid\")\n\t\t\tm_context << Instruction::CHAINID;\n\t\telse if (member == \"basefee\")\n\t\t\tm_context << Instruction::BASEFEE;\n\t\telse if (member == \"blobbasefee\")\n\t\t\tm_context << Instruction::BLOBBASEFEE;\n\t\telse if (member == \"data\")\n\t\t\tm_context << u256(0) << Instruction::CALLDATASIZE;\n\t\telse if (member == \"sig\")\n\t\t\tm_context << u256(0) << Instruction::CALLDATALOAD\n\t\t\t\t<< (u256(0xffffffff) << (256 - 32)) << Instruction::AND;\n\t\telse if (member == \"gas\")\n\t\t\tsolAssert(false, \"Gas has been removed.\");\n\t\telse if (member == \"blockhash\")\n\t\t\tsolAssert(false, \"Blockhash has been removed.\");\n\t\telse if (member == \"creationCode\" || member == \"runtimeCode\")\n\t\t{\n\t\t\tType const* arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();\n\t\t\tauto const& contractType = dynamic_cast<ContractType const&>(*arg);\n\t\t\tsolAssert(!contractType.isSuper(), \"\");\n\t\t\tContractDefinition const& contract = contractType.contractDefinition();\n\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\tm_context << Instruction::DUP1 << u256(32) << Instruction::ADD;\n\t\t\tutils().copyContractCodeToMemory(contract, member == \"creationCode\");\n\t\t\t// Stack: start end\n\t\t\tm_context.appendInlineAssembly(\n\t\t\t\tWhiskers(R\"({\n\t\t\t\t\tmstore(start, sub(end, add(start, 0x20)))\n\t\t\t\t\tmstore(<free>, and(add(end, 31), not(31)))\n\t\t\t\t})\")(\"free\", std::to_string(CompilerUtils::freeMemoryPointer)).render(),\n\t\t\t\t{\"start\", \"end\"}\n\t\t\t);\n\t\t\tm_context << Instruction::POP;\n\t\t}\n\t\telse if (member == \"name\")\n\t\t{\n\t\t\tType const* arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();\n\t\t\tauto const& contractType = dynamic_cast<ContractType const&>(*arg);\n\t\t\tContractDefinition const& contract = contractType.isSuper() ?\n\t\t\t\t*contractType.contractDefinition().superContract(m_context.mostDerivedContract()) :\n\t\t\t\tdynamic_cast<ContractType const&>(*arg).contractDefinition();\n\t\t\tutils().allocateMemory(((contract.name().length() + 31) / 32) * 32 + 32);\n\t\t\t// store string length\n\t\t\tm_context << u256(contract.name().length()) << Instruction::DUP2 << Instruction::MSTORE;\n\t\t\t// adjust pointer\n\t\t\tm_context << Instruction::DUP1 << u256(32) << Instruction::ADD;\n\t\t\tutils().storeStringData(contract.name());\n\t\t}\n\t\telse if (member == \"interfaceId\")\n\t\t{\n\t\t\tType const* arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();\n\t\t\tContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();\n\t\t\tm_context << (u256{contract.interfaceId()} << (256 - 32));\n\t\t}\n\t\telse if (member == \"min\" || member == \"max\")\n\t\t{\n\t\t\tMagicType const* arg = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type);\n\t\t\tif (IntegerType const* integerType = dynamic_cast<IntegerType const*>(arg->typeArgument()))\n\t\t\t\tm_context << (member == \"min\" ? integerType->min() : integerType->max());\n\t\t\telse if (EnumType const* enumType = dynamic_cast<EnumType const*>(arg->typeArgument()))\n\t\t\t\tm_context << (member == \"min\" ? enumType->minValue() : enumType->maxValue());\n\t\t\telse\n\t\t\t\tsolAssert(false, \"min/max not available for the given type.\");\n\n\t\t}\n\t\telse if ((std::set<std::string>{\"encode\", \"encodePacked\", \"encodeWithSelector\", \"encodeWithSignature\", \"decode\"}).count(member))\n\t\t{\n\t\t\t// no-op\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"Unknown magic member.\");\n\t\tbreak;\n\tcase Type::Category::Struct:\n\t{\n\t\tStructType const& type = dynamic_cast<StructType const&>(*_memberAccess.expression().annotation().type);\n\t\tType const* memberType = _memberAccess.annotation().type;\n\t\tswitch (type.location())\n\t\t{\n\t\tcase DataLocation::Storage:\n\t\t{\n\t\t\tstd::pair<u256, unsigned> const& offsets = type.storageOffsetsOfMember(member);\n\t\t\tm_context << offsets.first << Instruction::ADD << u256(offsets.second);\n\t\t\tsetLValueToStorageItem(_memberAccess);\n\t\t\tbreak;\n\t\t}\n\t\tcase DataLocation::Memory:\n\t\t{\n\t\t\tm_context << type.memoryOffsetOfMember(member) << Instruction::ADD;\n\t\t\tsetLValue<MemoryItem>(_memberAccess, *memberType);\n\t\t\tbreak;\n\t\t}\n\t\tcase DataLocation::CallData:\n\t\t{\n\t\t\tif (_memberAccess.annotation().type->isDynamicallyEncoded())\n\t\t\t{\n\t\t\t\tm_context << Instruction::DUP1;\n\t\t\t\tm_context << type.calldataOffsetOfMember(member) << Instruction::ADD;\n\t\t\t\tCompilerUtils(m_context).accessCalldataTail(*memberType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_context << type.calldataOffsetOfMember(member) << Instruction::ADD;\n\t\t\t\t// For non-value types the calldata offset is returned directly.\n\t\t\t\tif (memberType->isValueType())\n\t\t\t\t{\n\t\t\t\t\tsolAssert(memberType->calldataEncodedSize() > 0, \"\");\n\t\t\t\t\tsolAssert(memberType->storageBytes() <= 32, \"\");\n\t\t\t\t\tif (memberType->storageBytes() < 32 && m_context.useABICoderV2())\n\t\t\t\t\t{\n\t\t\t\t\t\tm_context << u256(32);\n\t\t\t\t\t\tCompilerUtils(m_context).abiDecodeV2({memberType}, false);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tCompilerUtils(m_context).loadFromMemoryDynamic(*memberType, true, true, false);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tsolAssert(\n\t\t\t\t\t\tmemberType->category() == Type::Category::Array ||\n\t\t\t\t\t\tmemberType->category() == Type::Category::Struct,\n\t\t\t\t\t\t\"\"\n\t\t\t\t\t);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tsolAssert(false, \"Illegal data location for struct.\");\n\t\t}\n\t\tbreak;\n\t}\n\tcase Type::Category::Enum:\n\t{\n\t\tEnumType const& type = dynamic_cast<EnumType const&>(*_memberAccess.expression().annotation().type);\n\t\tm_context << type.memberValue(_memberAccess.memberName());\n\t\tbreak;\n\t}\n\tcase Type::Category::Array:\n\t{\n\t\tauto const& type = dynamic_cast<ArrayType const&>(*_memberAccess.expression().annotation().type);\n\t\tif (member == \"length\")\n\t\t{\n\t\t\tif (!type.isDynamicallySized())\n\t\t\t{\n\t\t\t\tutils().popStackElement(type);\n\t\t\t\tm_context << type.length();\n\t\t\t}\n\t\t\telse\n\t\t\t\tswitch (type.location())\n\t\t\t\t{\n\t\t\t\tcase DataLocation::CallData:\n\t\t\t\t\tm_context << Instruction::SWAP1 << Instruction::POP;\n\t\t\t\t\tbreak;\n\t\t\t\tcase DataLocation::Storage:\n\t\t\t\t\tArrayUtils(m_context).retrieveLength(type);\n\t\t\t\t\tm_context << Instruction::SWAP1 << Instruction::POP;\n\t\t\t\t\tbreak;\n\t\t\t\tcase DataLocation::Transient:\n\t\t\t\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase DataLocation::Memory:\n\t\t\t\t\tm_context << Instruction::MLOAD;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t}\n\t\telse if (member == \"push\" || member == \"pop\")\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\ttype.isDynamicallySized() &&\n\t\t\t\ttype.location() == DataLocation::Storage &&\n\t\t\t\ttype.category() == Type::Category::Array,\n\t\t\t\t\"Tried to use .\" + member + \"() on a non-dynamically sized array\"\n\t\t\t);\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"Illegal array member.\");\n\t\tbreak;\n\t}\n\tcase Type::Category::FixedBytes:\n\t{\n\t\tauto const& type = dynamic_cast<FixedBytesType const&>(*_memberAccess.expression().annotation().type);\n\t\tutils().popStackElement(type);\n\t\tif (member == \"length\")\n\t\t\tm_context << u256(type.numBytes());\n\t\telse\n\t\t\tsolAssert(false, \"Illegal fixed bytes member.\");\n\t\tbreak;\n\t}\n\tcase Type::Category::Module:\n\t{\n\t\tType::Category category = _memberAccess.annotation().type->category();\n\t\tsolAssert(\n\t\t\tdynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration) ||\n\t\t\tdynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration) ||\n\t\t\tdynamic_cast<ErrorDefinition const*>(_memberAccess.annotation().referencedDeclaration) ||\n\t\t\tdynamic_cast<EventDefinition const*>(_memberAccess.annotation().referencedDeclaration) ||\n\t\t\tcategory == Type::Category::TypeType ||\n\t\t\tcategory == Type::Category::Module,\n\t\t\t\"\"\n\t\t);\n\t\tif (auto variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t{\n\t\t\tsolAssert(variable->isConstant(), \"\");\n\t\t\tappendVariable(*variable, static_cast<Expression const&>(_memberAccess));\n\t\t}\n\t\telse if (auto const* function = dynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t{\n\t\t\tauto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type);\n\t\t\tsolAssert(function && function->isFree(), \"\");\n\t\t\tsolAssert(funType->kind() == FunctionType::Kind::Internal, \"\");\n\t\t\tsolAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Static, \"\");\n\t\t\tutils().pushCombinedFunctionEntryLabel(\n\t\t\t\t*function,\n\t\t\t\t// If we call directly, do not include the second label.\n\t\t\t\t!_memberAccess.annotation().calledDirectly\n\t\t\t);\n\t\t}\n\t\telse if (auto const* contract = dynamic_cast<ContractDefinition const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t{\n\t\t\tif (contract->isLibrary())\n\t\t\t\tm_context.appendLibraryAddress(contract->fullyQualifiedName());\n\t\t}\n\t\tbreak;\n\t}\n\tdefault:\n\t\tsolAssert(false, \"Member access to unknown type.\");\n\t}\n\treturn false;\n}\n\nbool ExpressionCompiler::visit(IndexAccess const& _indexAccess)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _indexAccess);\n\t_indexAccess.baseExpression().accept(*this);\n\n\tType const& baseType = *_indexAccess.baseExpression().annotation().type;\n\n\tswitch (baseType.category())\n\t{\n\t\tcase Type::Category::Mapping:\n\t\t{\n\t\t\t// stack: storage_base_ref\n\t\t\tType const* keyType = dynamic_cast<MappingType const&>(baseType).keyType();\n\t\t\tsolAssert(_indexAccess.indexExpression(), \"Index expression expected.\");\n\t\t\tif (keyType->isDynamicallySized())\n\t\t\t{\n\t\t\t\t_indexAccess.indexExpression()->accept(*this);\n\t\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\t\t// stack: base index mem\n\t\t\t\t// note: the following operations must not allocate memory!\n\t\t\t\tutils().packedEncode(\n\t\t\t\t\tTypePointers{_indexAccess.indexExpression()->annotation().type},\n\t\t\t\t\tTypePointers{keyType}\n\t\t\t\t);\n\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t\tutils().storeInMemoryDynamic(*TypeProvider::uint256());\n\t\t\t\tutils().toSizeAfterFreeMemoryPointer();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_context << u256(0); // memory position\n\t\t\t\tappendExpressionCopyToMemory(*keyType, *_indexAccess.indexExpression());\n\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t\tsolAssert(CompilerUtils::freeMemoryPointer >= 0x40, \"\");\n\t\t\t\tutils().storeInMemoryDynamic(*TypeProvider::uint256());\n\t\t\t\tm_context << u256(0);\n\t\t\t}\n\t\t\tm_context << Instruction::KECCAK256;\n\t\t\tm_context << u256(0);\n\t\t\tsetLValueToStorageItem(_indexAccess);\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::ArraySlice:\n\t\t{\n\t\t\tauto const& arrayType = dynamic_cast<ArraySliceType const&>(baseType).arrayType();\n\t\t\tsolAssert(\n\t\t\t\tarrayType.location() == DataLocation::CallData &&\n\t\t\t\tarrayType.isDynamicallySized() &&\n\t\t\t\t!arrayType.baseType()->isDynamicallyEncoded(),\n\t\t\t\t\"\"\n\t\t\t);\n\t\t\tsolAssert(_indexAccess.indexExpression(), \"Index expression expected.\");\n\n\t\t\tacceptAndConvert(*_indexAccess.indexExpression(), *TypeProvider::uint256(), true);\n\t\t\tArrayUtils(m_context).accessCallDataArrayElement(arrayType);\n\t\t\tbreak;\n\n\t\t}\n\t\tcase Type::Category::Array:\n\t\t{\n\t\t\tArrayType const& arrayType = dynamic_cast<ArrayType const&>(baseType);\n\t\t\tsolAssert(_indexAccess.indexExpression(), \"Index expression expected.\");\n\n\t\t\tacceptAndConvert(*_indexAccess.indexExpression(), *TypeProvider::uint256(), true);\n\t\t\t// stack layout: <base_ref> [<length>] <index>\n\t\t\tswitch (arrayType.location())\n\t\t\t{\n\t\t\t\tcase DataLocation::Storage:\n\t\t\t\t\tArrayUtils(m_context).accessIndex(arrayType);\n\t\t\t\t\tif (arrayType.isByteArrayOrString())\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(!arrayType.isString(), \"Index access to string is not allowed.\");\n\t\t\t\t\t\tsetLValue<StorageByteArrayElement>(_indexAccess);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tsetLValueToStorageItem(_indexAccess);\n\t\t\t\t\tbreak;\n\t\t\t\tcase DataLocation::Transient:\n\t\t\t\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase DataLocation::Memory:\n\t\t\t\t\tArrayUtils(m_context).accessIndex(arrayType);\n\t\t\t\t\tsetLValue<MemoryItem>(_indexAccess, *_indexAccess.annotation().type, !arrayType.isByteArrayOrString());\n\t\t\t\t\tbreak;\n\t\t\t\tcase DataLocation::CallData:\n\t\t\t\t\tArrayUtils(m_context).accessCallDataArrayElement(arrayType);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::FixedBytes:\n\t\t{\n\t\t\tFixedBytesType const& fixedBytesType = dynamic_cast<FixedBytesType const&>(baseType);\n\t\t\tsolAssert(_indexAccess.indexExpression(), \"Index expression expected.\");\n\n\t\t\tacceptAndConvert(*_indexAccess.indexExpression(), *TypeProvider::uint256(), true);\n\t\t\t// stack layout: <value> <index>\n\t\t\t// check out-of-bounds access\n\t\t\tm_context << u256(fixedBytesType.numBytes());\n\t\t\tm_context << Instruction::DUP2 << Instruction::LT << Instruction::ISZERO;\n\t\t\t// out-of-bounds access throws exception\n\t\t\tm_context.appendConditionalPanic(util::PanicCode::ArrayOutOfBounds);\n\n\t\t\tm_context << Instruction::BYTE;\n\t\t\tutils().leftShiftNumberOnStack(256 - 8);\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::TypeType:\n\t\t{\n\t\t\tsolAssert(baseType.sizeOnStack() == 0, \"\");\n\t\t\tsolAssert(_indexAccess.annotation().type->sizeOnStack() == 0, \"\");\n\t\t\t// no-op - this seems to be a lone array type (`structType[];`)\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tsolAssert(false, \"Index access only allowed for mappings or arrays.\");\n\t\t\tbreak;\n\t}\n\n\treturn false;\n}\n\nbool ExpressionCompiler::visit(IndexRangeAccess const& _indexAccess)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _indexAccess);\n\t_indexAccess.baseExpression().accept(*this);\n\t// stack: offset length\n\n\tType const& baseType = *_indexAccess.baseExpression().annotation().type;\n\n\tArrayType const* arrayType = dynamic_cast<ArrayType const*>(&baseType);\n\tif (!arrayType)\n\t\tif (ArraySliceType const* sliceType = dynamic_cast<ArraySliceType const*>(&baseType))\n\t\t\tarrayType = &sliceType->arrayType();\n\n\tsolAssert(arrayType, \"\");\n\tsolUnimplementedAssert(\n\t\tarrayType->location() == DataLocation::CallData &&\n\t\tarrayType->isDynamicallySized() &&\n\t\t!arrayType->baseType()->isDynamicallyEncoded()\n\t);\n\n\tif (_indexAccess.startExpression())\n\t\tacceptAndConvert(*_indexAccess.startExpression(), *TypeProvider::uint256());\n\telse\n\t\tm_context << u256(0);\n\t// stack: offset length sliceStart\n\n\tm_context << Instruction::SWAP1;\n\t// stack: offset sliceStart length\n\n\tif (_indexAccess.endExpression())\n\t\tacceptAndConvert(*_indexAccess.endExpression(), *TypeProvider::uint256());\n\telse\n\t\tm_context << Instruction::DUP1;\n\t// stack: offset sliceStart length sliceEnd\n\n\tm_context << Instruction::SWAP3;\n\t// stack: sliceEnd sliceStart length offset\n\n\tm_context.callYulFunction(m_context.utilFunctions().calldataArrayIndexRangeAccess(*arrayType), 4, 2);\n\n\treturn false;\n}\n\nvoid ExpressionCompiler::endVisit(Identifier const& _identifier)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _identifier);\n\tDeclaration const* declaration = _identifier.annotation().referencedDeclaration;\n\tif (MagicVariableDeclaration const* magicVar = dynamic_cast<MagicVariableDeclaration const*>(declaration))\n\t{\n\t\tswitch (magicVar->type()->category())\n\t\t{\n\t\tcase Type::Category::Contract:\n\t\t\tif (dynamic_cast<ContractType const*>(magicVar->type()))\n\t\t\t{\n\t\t\t\tsolAssert(_identifier.name() == \"this\", \"\");\n\t\t\t\tm_context << Instruction::ADDRESS;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\telse if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))\n\t{\n\t\tsolAssert(*_identifier.annotation().requiredLookup == VirtualLookup::Virtual, \"\");\n\t\tutils().pushCombinedFunctionEntryLabel(\n\t\t\tfunctionDef->resolveVirtual(m_context.mostDerivedContract()),\n\t\t\t// If we call directly, do not include the second (potential runtime) label.\n\t\t\t// Including the label might lead to the runtime code being included in the creation\n\t\t\t// code even though it is never executed.\n\t\t\t!_identifier.annotation().calledDirectly\n\t\t);\n\t}\n\telse if (auto variable = dynamic_cast<VariableDeclaration const*>(declaration))\n\t\tappendVariable(*variable, static_cast<Expression const&>(_identifier));\n\telse if (auto contract = dynamic_cast<ContractDefinition const*>(declaration))\n\t{\n\t\tif (contract->isLibrary())\n\t\t\tm_context.appendLibraryAddress(contract->fullyQualifiedName());\n\t}\n\telse if (dynamic_cast<EventDefinition const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse if (dynamic_cast<ErrorDefinition const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse if (dynamic_cast<EnumDefinition const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse if (dynamic_cast<UserDefinedValueTypeDefinition const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse if (dynamic_cast<StructDefinition const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse if (dynamic_cast<ImportDirective const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse\n\t{\n\t\tsolAssert(false, \"Identifier type not expected in expression context.\");\n\t}\n}\n\nvoid ExpressionCompiler::endVisit(Literal const& _literal)\n{\n\tCompilerContext::LocationSetter locationSetter(m_context, _literal);\n\tType const* type = _literal.annotation().type;\n\n\tswitch (type->category())\n\t{\n\tcase Type::Category::RationalNumber:\n\tcase Type::Category::Bool:\n\tcase Type::Category::Address:\n\t\tm_context << type->literalValue(&_literal);\n\t\tbreak;\n\tcase Type::Category::StringLiteral:\n\t\tbreak; // will be done during conversion\n\tdefault:\n\t\tsolUnimplemented(\"Only integer, boolean and string literals implemented for now.\");\n\t}\n}\n\nvoid ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation const& _binaryOperation)\n{\n\tToken const c_op = _binaryOperation.getOperator();\n\tsolAssert(c_op == Token::Or || c_op == Token::And, \"\");\n\n\t_binaryOperation.leftExpression().accept(*this);\n\tm_context << Instruction::DUP1;\n\tif (c_op == Token::And)\n\t\tm_context << Instruction::ISZERO;\n\tevmasm::AssemblyItem endLabel = m_context.appendConditionalJump();\n\tm_context << Instruction::POP;\n\t_binaryOperation.rightExpression().accept(*this);\n\tm_context << endLabel;\n}\n\nvoid ExpressionCompiler::appendCompareOperatorCode(Token _operator, Type const& _type)\n{\n\tif (_operator == Token::Equal || _operator == Token::NotEqual)\n\t{\n\t\tFunctionType const* functionType = dynamic_cast<decltype(functionType)>(&_type);\n\t\tif (functionType && functionType->kind() == FunctionType::Kind::External)\n\t\t{\n\t\t\tsolUnimplementedAssert(functionType->sizeOnStack() == 2, \"\");\n\t\t\tm_context << Instruction::SWAP3;\n\n\t\t\tm_context << ((u256(1) << 160) - 1) << Instruction::AND;\n\t\t\tm_context << Instruction::SWAP1;\n\t\t\tm_context << ((u256(1) << 160) - 1) << Instruction::AND;\n\t\t\tm_context << Instruction::EQ;\n\t\t\tm_context << Instruction::SWAP2;\n\t\t\tm_context << ((u256(1) << 32) - 1) << Instruction::AND;\n\t\t\tm_context << Instruction::SWAP1;\n\t\t\tm_context << ((u256(1) << 32) - 1) << Instruction::AND;\n\t\t\tm_context << Instruction::EQ;\n\t\t\tm_context << Instruction::AND;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(_type.sizeOnStack() == 1, \"Comparison of multi-slot types.\");\n\t\t\tif (functionType && functionType->kind() == FunctionType::Kind::Internal)\n\t\t\t{\n\t\t\t\t// We have to remove the upper bits (construction time value) because they might\n\t\t\t\t// be \"unknown\" in one of the operands and not in the other.\n\t\t\t\tm_context << ((u256(1) << 32) - 1) << Instruction::AND;\n\t\t\t\tm_context << Instruction::SWAP1;\n\t\t\t\tm_context << ((u256(1) << 32) - 1) << Instruction::AND;\n\t\t\t}\n\t\t\tm_context << Instruction::EQ;\n\t\t}\n\t\tif (_operator == Token::NotEqual)\n\t\t\tm_context << Instruction::ISZERO;\n\t}\n\telse\n\t{\n\t\tsolAssert(_type.sizeOnStack() == 1, \"Comparison of multi-slot types.\");\n\t\tbool isSigned = false;\n\t\tif (auto type = dynamic_cast<IntegerType const*>(&_type))\n\t\t\tisSigned = type->isSigned();\n\n\t\tswitch (_operator)\n\t\t{\n\t\tcase Token::GreaterThanOrEqual:\n\t\t\tm_context <<\n\t\t\t\t(isSigned ? Instruction::SLT : Instruction::LT) <<\n\t\t\t\tInstruction::ISZERO;\n\t\t\tbreak;\n\t\tcase Token::LessThanOrEqual:\n\t\t\tm_context <<\n\t\t\t\t(isSigned ? Instruction::SGT : Instruction::GT) <<\n\t\t\t\tInstruction::ISZERO;\n\t\t\tbreak;\n\t\tcase Token::GreaterThan:\n\t\t\tm_context << (isSigned ? Instruction::SGT : Instruction::GT);\n\t\t\tbreak;\n\t\tcase Token::LessThan:\n\t\t\tm_context << (isSigned ? Instruction::SLT : Instruction::LT);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tsolAssert(false, \"Unknown comparison operator.\");\n\t\t}\n\t}\n}\n\nvoid ExpressionCompiler::appendOrdinaryBinaryOperatorCode(Token _operator, Type const& _type)\n{\n\tif (TokenTraits::isArithmeticOp(_operator))\n\t\tappendArithmeticOperatorCode(_operator, _type);\n\telse if (TokenTraits::isBitOp(_operator))\n\t\tappendBitOperatorCode(_operator);\n\telse\n\t\tsolAssert(false, \"Unknown binary operator.\");\n}\n\nvoid ExpressionCompiler::appendArithmeticOperatorCode(Token _operator, Type const& _type)\n{\n\tif (_type.category() == Type::Category::FixedPoint)\n\t\tsolUnimplemented(\"Not yet implemented - FixedPointType.\");\n\n\tIntegerType const& type = dynamic_cast<IntegerType const&>(_type);\n\tif (m_context.arithmetic() == Arithmetic::Checked)\n\t{\n\t\tstd::string functionName;\n\t\tswitch (_operator)\n\t\t{\n\t\tcase Token::Add:\n\t\t\tfunctionName = m_context.utilFunctions().overflowCheckedIntAddFunction(type);\n\t\t\tbreak;\n\t\tcase Token::Sub:\n\t\t\tfunctionName = m_context.utilFunctions().overflowCheckedIntSubFunction(type);\n\t\t\tbreak;\n\t\tcase Token::Mul:\n\t\t\tfunctionName = m_context.utilFunctions().overflowCheckedIntMulFunction(type);\n\t\t\tbreak;\n\t\tcase Token::Div:\n\t\t\tfunctionName = m_context.utilFunctions().overflowCheckedIntDivFunction(type);\n\t\t\tbreak;\n\t\tcase Token::Mod:\n\t\t\tfunctionName = m_context.utilFunctions().intModFunction(type);\n\t\t\tbreak;\n\t\tcase Token::Exp:\n\t\t\t// EXP is handled in a different function.\n\t\tdefault:\n\t\t\tsolAssert(false, \"Unknown arithmetic operator.\");\n\t\t}\n\t\t// TODO Maybe we want to force-inline this?\n\t\tm_context.callYulFunction(functionName, 2, 1);\n\t}\n\telse\n\t{\n\t\tbool const c_isSigned = type.isSigned();\n\n\t\tswitch (_operator)\n\t\t{\n\t\tcase Token::Add:\n\t\t\tm_context << Instruction::ADD;\n\t\t\tbreak;\n\t\tcase Token::Sub:\n\t\t\tm_context << Instruction::SUB;\n\t\t\tbreak;\n\t\tcase Token::Mul:\n\t\t\tm_context << Instruction::MUL;\n\t\t\tbreak;\n\t\tcase Token::Div:\n\t\tcase Token::Mod:\n\t\t{\n\t\t\t// Test for division by zero\n\t\t\tm_context << Instruction::DUP2 << Instruction::ISZERO;\n\t\t\tm_context.appendConditionalPanic(util::PanicCode::DivisionByZero);\n\n\t\t\tif (_operator == Token::Div)\n\t\t\t\tm_context << (c_isSigned ? Instruction::SDIV : Instruction::DIV);\n\t\t\telse\n\t\t\t\tm_context << (c_isSigned ? Instruction::SMOD : Instruction::MOD);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tsolAssert(false, \"Unknown arithmetic operator.\");\n\t\t}\n\t}\n}\n\nvoid ExpressionCompiler::appendBitOperatorCode(Token _operator)\n{\n\tswitch (_operator)\n\t{\n\tcase Token::BitOr:\n\t\tm_context << Instruction::OR;\n\t\tbreak;\n\tcase Token::BitAnd:\n\t\tm_context << Instruction::AND;\n\t\tbreak;\n\tcase Token::BitXor:\n\t\tm_context << Instruction::XOR;\n\t\tbreak;\n\tdefault:\n\t\tsolAssert(false, \"Unknown bit operator.\");\n\t}\n}\n\nvoid ExpressionCompiler::appendShiftOperatorCode(Token _operator, Type const& _valueType, Type const& _shiftAmountType)\n{\n\t// stack: shift_amount value_to_shift\n\n\tbool c_valueSigned = false;\n\tif (auto valueType = dynamic_cast<IntegerType const*>(&_valueType))\n\t\tc_valueSigned = valueType->isSigned();\n\telse\n\t\tsolAssert(dynamic_cast<FixedBytesType const*>(&_valueType), \"Only integer and fixed bytes type supported for shifts.\");\n\n\t// The amount can be a RationalNumberType too.\n\tif (auto amountType = dynamic_cast<RationalNumberType const*>(&_shiftAmountType))\n\t{\n\t\t// This should be handled by the type checker.\n\t\tsolAssert(amountType->integerType(), \"\");\n\t\tsolAssert(!amountType->integerType()->isSigned(), \"\");\n\t}\n\telse if (auto amountType = dynamic_cast<IntegerType const*>(&_shiftAmountType))\n\t\tsolAssert(!amountType->isSigned(), \"\");\n\telse\n\t\tsolAssert(false, \"Invalid shift amount type.\");\n\n\tm_context << Instruction::SWAP1;\n\t// stack: value_to_shift shift_amount\n\n\tswitch (_operator)\n\t{\n\tcase Token::SHL:\n\t\tif (m_context.evmVersion().hasBitwiseShifting())\n\t\t\tm_context << Instruction::SHL;\n\t\telse\n\t\t\tm_context << u256(2) << Instruction::EXP << Instruction::MUL;\n\t\tbreak;\n\tcase Token::SAR:\n\t\tif (m_context.evmVersion().hasBitwiseShifting())\n\t\t\tm_context << (c_valueSigned ? Instruction::SAR : Instruction::SHR);\n\t\telse\n\t\t{\n\t\t\tif (c_valueSigned)\n\t\t\t\t// In the following assembly snippet, xor_mask will be zero, if value_to_shift is positive.\n\t\t\t\t// Therefore xor'ing with xor_mask is the identity and the computation reduces to\n\t\t\t\t// div(value_to_shift, exp(2, shift_amount)), which is correct, since for positive values\n\t\t\t\t// arithmetic right shift is dividing by a power of two (which, as a bitwise operation, results\n\t\t\t\t// in discarding bits on the right and filling with zeros from the left).\n\t\t\t\t// For negative values arithmetic right shift, viewed as a bitwise operation, discards bits to the\n\t\t\t\t// right and fills in ones from the left. This is achieved as follows:\n\t\t\t\t// If value_to_shift is negative, then xor_mask will have all bits set, so xor'ing with xor_mask\n\t\t\t\t// will flip all bits. First all bits in value_to_shift are flipped. As for the positive case,\n\t\t\t\t// dividing by a power of two using integer arithmetic results in discarding bits to the right\n\t\t\t\t// and filling with zeros from the left. Flipping all bits in the result again, turns all zeros\n\t\t\t\t// on the left to ones and restores the non-discarded, shifted bits to their original value (they\n\t\t\t\t// have now been flipped twice). In summary we now have discarded bits to the right and filled with\n\t\t\t\t// ones from the left, i.e. we have performed an arithmetic right shift.\n\t\t\t\tm_context.appendInlineAssembly(R\"({\n\t\t\t\t\tlet xor_mask := sub(0, slt(value_to_shift, 0))\n\t\t\t\t\tvalue_to_shift := xor(div(xor(value_to_shift, xor_mask), exp(2, shift_amount)), xor_mask)\n\t\t\t\t})\", {\"value_to_shift\", \"shift_amount\"});\n\t\t\telse\n\t\t\t\tm_context.appendInlineAssembly(R\"({\n\t\t\t\t\tvalue_to_shift := div(value_to_shift, exp(2, shift_amount))\n\t\t\t\t})\", {\"value_to_shift\", \"shift_amount\"});\n\t\t\tm_context << Instruction::POP;\n\n\t\t}\n\t\tbreak;\n\tcase Token::SHR:\n\tdefault:\n\t\tsolAssert(false, \"Unknown shift operator.\");\n\t}\n}\n\nvoid ExpressionCompiler::appendExpOperatorCode(Type const& _valueType, Type const& _exponentType)\n{\n\tsolAssert(_valueType.category() == Type::Category::Integer, \"\");\n\tsolAssert(!dynamic_cast<IntegerType const&>(_exponentType).isSigned(), \"\");\n\n\n\tif (m_context.arithmetic() == Arithmetic::Checked)\n\t\tm_context.callYulFunction(m_context.utilFunctions().overflowCheckedIntExpFunction(\n\t\t\tdynamic_cast<IntegerType const&>(_valueType),\n\t\t\tdynamic_cast<IntegerType const&>(_exponentType)\n\t\t), 2, 1);\n\telse\n\t\tm_context << Instruction::EXP;\n}\n\nvoid ExpressionCompiler::appendExternalFunctionCall(\n\tFunctionType const& _functionType,\n\tstd::vector<ASTPointer<Expression const>> const& _arguments,\n\tbool _tryCall\n)\n{\n\tsolAssert(\n\t\t_functionType.takesArbitraryParameters() ||\n\t\t_arguments.size() == _functionType.parameterTypes().size(), \"\"\n\t);\n\n\t// Assumed stack content here:\n\t// <stack top>\n\t// value [if _functionType.valueSet()]\n\t// gas [if _functionType.gasSet()]\n\t// self object [if bound - moved to top right away]\n\t// function identifier [unless bare]\n\t// contract address\n\n\tunsigned selfSize = _functionType.hasBoundFirstArgument() ? _functionType.selfType()->sizeOnStack() : 0;\n\tunsigned gasValueSize = (_functionType.gasSet() ? 1u : 0u) + (_functionType.valueSet() ? 1u : 0u);\n\tunsigned contractStackPos = m_context.currentToBaseStackOffset(1 + gasValueSize + selfSize + (_functionType.isBareCall() ? 0 : 1));\n\tunsigned gasStackPos = m_context.currentToBaseStackOffset(gasValueSize);\n\tunsigned valueStackPos = m_context.currentToBaseStackOffset(1);\n\n\t// move self object to top\n\tif (_functionType.hasBoundFirstArgument())\n\t\tutils().moveToStackTop(gasValueSize, _functionType.selfType()->sizeOnStack());\n\n\tauto funKind = _functionType.kind();\n\n\tsolAssert(funKind != FunctionType::Kind::BareStaticCall || m_context.evmVersion().hasStaticCall(), \"\");\n\n\tsolAssert(funKind != FunctionType::Kind::BareCallCode, \"Callcode has been removed.\");\n\n\tbool returnSuccessConditionAndReturndata = funKind == FunctionType::Kind::BareCall || funKind == FunctionType::Kind::BareDelegateCall || funKind == FunctionType::Kind::BareStaticCall;\n\tbool isDelegateCall = funKind == FunctionType::Kind::BareDelegateCall || funKind == FunctionType::Kind::DelegateCall;\n\tbool useStaticCall = funKind == FunctionType::Kind::BareStaticCall || (_functionType.stateMutability() <= StateMutability::View && m_context.evmVersion().hasStaticCall());\n\n\tif (_tryCall)\n\t{\n\t\tsolAssert(!returnSuccessConditionAndReturndata, \"\");\n\t\tsolAssert(!_functionType.isBareCall(), \"\");\n\t}\n\n\tReturnInfo const returnInfo{m_context.evmVersion(), _functionType};\n\tbool const haveReturndatacopy = m_context.evmVersion().supportsReturndata();\n\tunsigned const retSize = returnInfo.estimatedReturnSize;\n\tbool const dynamicReturnSize = returnInfo.dynamicReturnSize;\n\tTypePointers const& returnTypes = returnInfo.returnTypes;\n\n\t// Evaluate arguments.\n\tTypePointers argumentTypes;\n\tTypePointers parameterTypes = _functionType.parameterTypes();\n\tif (_functionType.hasBoundFirstArgument())\n\t{\n\t\targumentTypes.push_back(_functionType.selfType());\n\t\tparameterTypes.insert(parameterTypes.begin(), _functionType.selfType());\n\t}\n\tfor (size_t i = 0; i < _arguments.size(); ++i)\n\t{\n\t\t_arguments[i]->accept(*this);\n\t\targumentTypes.push_back(_arguments[i]->annotation().type);\n\t}\n\n\tif (funKind == FunctionType::Kind::ECRecover)\n\t{\n\t\t// Clears 32 bytes of currently free memory and advances free memory pointer.\n\t\t// Output area will be \"start of input area\" - 32.\n\t\t// The reason is that a failing ECRecover cannot be detected, it will just return\n\t\t// zero bytes (which we cannot detect).\n\t\tsolAssert(0 < retSize && retSize <= 32, \"\");\n\t\tutils().fetchFreeMemoryPointer();\n\t\tm_context << u256(0) << Instruction::DUP2 << Instruction::MSTORE;\n\t\tm_context << u256(32) << Instruction::ADD;\n\t\tutils().storeFreeMemoryPointer();\n\t}\n\n\tif (!m_context.evmVersion().canOverchargeGasForCall())\n\t{\n\t\t// Touch the end of the output area so that we do not pay for memory resize during the call\n\t\t// (which we would have to subtract from the gas left)\n\t\t// We could also just use MLOAD; POP right before the gas calculation, but the optimizer\n\t\t// would remove that, so we use MSTORE here.\n\t\tif (!_functionType.gasSet() && retSize > 0)\n\t\t{\n\t\t\tm_context << u256(0);\n\t\t\tutils().fetchFreeMemoryPointer();\n\t\t\t// This touches too much, but that way we save some rounding arithmetic\n\t\t\tm_context << u256(retSize) << Instruction::ADD << Instruction::MSTORE;\n\t\t}\n\t}\n\n\t// Copy function identifier to memory.\n\tutils().fetchFreeMemoryPointer();\n\tif (!_functionType.isBareCall())\n\t{\n\t\tm_context << dupInstruction(2 + gasValueSize + CompilerUtils::sizeOnStack(argumentTypes));\n\t\tutils().storeInMemoryDynamic(IntegerType(8 * CompilerUtils::dataStartOffset), false);\n\t}\n\n\t// If the function takes arbitrary parameters or is a bare call, copy dynamic length data in place.\n\t// Move arguments to memory, will not update the free memory pointer (but will update the memory\n\t// pointer on the stack).\n\tbool encodeInPlace = _functionType.takesArbitraryParameters() || _functionType.isBareCall();\n\tif (_functionType.kind() == FunctionType::Kind::ECRecover)\n\t\t// This would be the only combination of padding and in-place encoding,\n\t\t// but all parameters of ecrecover are value types anyway.\n\t\tencodeInPlace = false;\n\tbool encodeForLibraryCall = funKind == FunctionType::Kind::DelegateCall;\n\tutils().encodeToMemory(\n\t\targumentTypes,\n\t\tparameterTypes,\n\t\t_functionType.padArguments(),\n\t\tencodeInPlace,\n\t\tencodeForLibraryCall\n\t);\n\n\t// Stack now:\n\t// <stack top>\n\t// input_memory_end\n\t// value [if _functionType.valueSet()]\n\t// gas [if _functionType.gasSet()]\n\t// function identifier [unless bare]\n\t// contract address\n\n\t// Output data will replace input data, unless we have ECRecover (then, output\n\t// area will be 32 bytes just before input area).\n\t// put on stack: <size of output> <memory pos of output> <size of input> <memory pos of input>\n\tm_context << u256(retSize);\n\tutils().fetchFreeMemoryPointer(); // This is the start of input\n\tif (funKind == FunctionType::Kind::ECRecover)\n\t{\n\t\t// In this case, output is 32 bytes before input and has already been cleared.\n\t\tm_context << u256(32) << Instruction::DUP2 << Instruction::SUB << Instruction::SWAP1;\n\t\t// Here: <input end> <output size> <outpos> <input pos>\n\t\tm_context << Instruction::DUP1 << Instruction::DUP5 << Instruction::SUB;\n\t\tm_context << Instruction::SWAP1;\n\t}\n\telse\n\t{\n\t\tm_context << Instruction::DUP1 << Instruction::DUP4 << Instruction::SUB;\n\t\tm_context << Instruction::DUP2;\n\t}\n\n\t// CALL arguments: outSize, outOff, inSize, inOff (already present up to here)\n\t// [value,] addr, gas (stack top)\n\tif (isDelegateCall)\n\t\tsolAssert(!_functionType.valueSet(), \"Value set for delegatecall\");\n\telse if (useStaticCall)\n\t\tsolAssert(!_functionType.valueSet(), \"Value set for staticcall\");\n\telse if (_functionType.valueSet())\n\t\tm_context << dupInstruction(m_context.baseToCurrentStackOffset(valueStackPos));\n\telse\n\t\tm_context << u256(0);\n\tm_context << dupInstruction(m_context.baseToCurrentStackOffset(contractStackPos));\n\n\tbool existenceChecked = false;\n\t// Check the target contract exists (has code) for non-low-level calls.\n\tif (funKind == FunctionType::Kind::External || funKind == FunctionType::Kind::DelegateCall)\n\t{\n\t\tsize_t encodedHeadSize = 0;\n\t\tfor (auto const& t: returnTypes)\n\t\t\tencodedHeadSize += t->decodingType()->calldataHeadSize();\n\t\t// We do not need to check extcodesize if we expect return data, since if there is no\n\t\t// code, the call will return empty data and the ABI decoder will revert.\n\t\tif (\n\t\t\tencodedHeadSize == 0 ||\n\t\t\t!haveReturndatacopy ||\n\t\t\tm_context.revertStrings() >= RevertStrings::Debug\n\t\t)\n\t\t{\n\t\t\tm_context << Instruction::DUP1 << Instruction::EXTCODESIZE << Instruction::ISZERO;\n\t\t\tm_context.appendConditionalRevert(false, \"Target contract does not contain code\");\n\t\t\texistenceChecked = true;\n\t\t}\n\t}\n\n\tif (_functionType.gasSet())\n\t\tm_context << dupInstruction(m_context.baseToCurrentStackOffset(gasStackPos));\n\telse if (m_context.evmVersion().canOverchargeGasForCall())\n\t\t// Send all gas (requires tangerine whistle EVM)\n\t\tm_context << Instruction::GAS;\n\telse\n\t{\n\t\t// send all gas except the amount needed to execute \"SUB\" and \"CALL\"\n\t\t// @todo this retains too much gas for now, needs to be fine-tuned.\n\t\tu256 gasNeededByCaller = evmasm::GasCosts::callGas(m_context.evmVersion()) + 10;\n\t\tif (_functionType.valueSet())\n\t\t\tgasNeededByCaller += evmasm::GasCosts::callValueTransferGas;\n\t\tif (!existenceChecked)\n\t\t\tgasNeededByCaller += evmasm::GasCosts::callNewAccountGas; // we never know\n\t\tm_context << gasNeededByCaller << Instruction::GAS << Instruction::SUB;\n\t}\n\t// Order is important here, STATICCALL might overlap with DELEGATECALL.\n\tif (isDelegateCall)\n\t\tm_context << Instruction::DELEGATECALL;\n\telse if (useStaticCall)\n\t\tm_context << Instruction::STATICCALL;\n\telse\n\t\tm_context << Instruction::CALL;\n\n\tunsigned remainsSize =\n\t\t2u + // contract address, input_memory_end\n\t\t(_functionType.valueSet() ? 1 : 0) +\n\t\t(_functionType.gasSet() ? 1 : 0) +\n\t\t(!_functionType.isBareCall() ? 1 : 0);\n\n\tevmasm::AssemblyItem endTag = m_context.newTag();\n\n\tif (!returnSuccessConditionAndReturndata && !_tryCall)\n\t{\n\t\t// Propagate error condition (if CALL pushes 0 on stack).\n\t\tm_context << Instruction::ISZERO;\n\t\tm_context.appendConditionalRevert(true);\n\t}\n\telse\n\t\tm_context << swapInstruction(remainsSize);\n\tutils().popStackSlots(remainsSize);\n\n\t// Only success flag is remaining on stack.\n\n\tif (_tryCall)\n\t{\n\t\tm_context << Instruction::DUP1 << Instruction::ISZERO;\n\t\tm_context.appendConditionalJumpTo(endTag);\n\t\tm_context << Instruction::POP;\n\t}\n\n\tif (returnSuccessConditionAndReturndata)\n\t{\n\t\t// success condition is already there\n\t\t// The return parameter types can be empty, when this function is used as\n\t\t// an internal helper function e.g. for ``send`` and ``transfer``. In that\n\t\t// case we're only interested in the success condition, not the return data.\n\t\tif (!_functionType.returnParameterTypes().empty())\n\t\t\tutils().returnDataToArray();\n\t}\n\telse if (funKind == FunctionType::Kind::RIPEMD160)\n\t{\n\t\t// fix: built-in contract returns right-aligned data\n\t\tutils().fetchFreeMemoryPointer();\n\t\tutils().loadFromMemoryDynamic(IntegerType(160), false, true, false);\n\t\tutils().convertType(IntegerType(160), FixedBytesType(20));\n\t}\n\telse if (funKind == FunctionType::Kind::ECRecover)\n\t{\n\t\t// Output is 32 bytes before input / free mem pointer.\n\t\t// Failing ecrecover cannot be detected, so we clear output before the call.\n\t\tm_context << u256(32);\n\t\tutils().fetchFreeMemoryPointer();\n\t\tm_context << Instruction::SUB << Instruction::MLOAD;\n\t}\n\telse if (!returnTypes.empty())\n\t{\n\t\tutils().fetchFreeMemoryPointer();\n\t\t// Stack: return_data_start\n\n\t\t// The old decoder did not allocate any memory (i.e. did not touch the free\n\t\t// memory pointer), but kept references to the return data for\n\t\t// (statically-sized) arrays\n\t\tbool needToUpdateFreeMemoryPtr = false;\n\t\tif (dynamicReturnSize || m_context.useABICoderV2())\n\t\t\tneedToUpdateFreeMemoryPtr = true;\n\t\telse\n\t\t\tfor (auto const& retType: returnTypes)\n\t\t\t\tif (dynamic_cast<ReferenceType const*>(retType))\n\t\t\t\t\tneedToUpdateFreeMemoryPtr = true;\n\n\t\t// Stack: return_data_start\n\t\tif (dynamicReturnSize)\n\t\t{\n\t\t\tsolAssert(haveReturndatacopy, \"\");\n\t\t\tm_context.appendInlineAssembly(\"{ returndatacopy(return_data_start, 0, returndatasize()) }\", {\"return_data_start\"});\n\t\t}\n\t\telse\n\t\t\tsolAssert(retSize > 0, \"\");\n\t\t// Always use the actual return length, and not our calculated expected length, if returndatacopy is supported.\n\t\t// This ensures it can catch badly formatted input from external calls.\n\t\tm_context << (haveReturndatacopy ? evmasm::AssemblyItem(Instruction::RETURNDATASIZE) : u256(retSize));\n\t\t// Stack: return_data_start return_data_size\n\t\tif (needToUpdateFreeMemoryPtr)\n\t\t\tm_context.appendInlineAssembly(R\"({\n\t\t\t\t// round size to the next multiple of 32\n\t\t\t\tlet newMem := add(start, and(add(size, 0x1f), not(0x1f)))\n\t\t\t\tmstore(0x40, newMem)\n\t\t\t})\", {\"start\", \"size\"});\n\n\t\tutils().abiDecode(returnTypes, true);\n\t}\n\n\tif (_tryCall)\n\t{\n\t\t// Success branch will reach this, failure branch will directly jump to endTag.\n\t\tm_context << u256(1);\n\t\tm_context << endTag;\n\t}\n}\n\nvoid ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression)\n{\n\tsolUnimplementedAssert(_expectedType.isValueType(), \"Not implemented for non-value types.\");\n\tacceptAndConvert(_expression, _expectedType, true);\n\tutils().storeInMemoryDynamic(_expectedType);\n}\n\nvoid ExpressionCompiler::appendVariable(VariableDeclaration const& _variable, Expression const& _expression)\n{\n\tif (_variable.isConstant())\n\t\tacceptAndConvert(*_variable.value(), *_variable.annotation().type);\n\telse if (_variable.immutable())\n\t\tsetLValue<ImmutableItem>(_expression, _variable);\n\telse\n\t\tsetLValueFromDeclaration(_variable, _expression);\n}\n\nvoid ExpressionCompiler::setLValueFromDeclaration(Declaration const& _declaration, Expression const& _expression)\n{\n\tif (m_context.isLocalVariable(&_declaration))\n\t\tsetLValue<StackVariable>(_expression, dynamic_cast<VariableDeclaration const&>(_declaration));\n\telse if (m_context.isStateVariable(&_declaration))\n\t{\n\t\tif (dynamic_cast<VariableDeclaration const&>(_declaration).referenceLocation() == VariableDeclaration::Location::Transient)\n\t\t\tsetLValue<TransientStorageItem>(_expression, dynamic_cast<VariableDeclaration const&>(_declaration));\n\t\telse\n\t\t\tsetLValue<StorageItem>(_expression, dynamic_cast<VariableDeclaration const&>(_declaration));\n\t}\n\telse\n\t\tsolAssert(false, \"Identifier type not supported or identifier not found.\");\n}\n\nvoid ExpressionCompiler::setLValueToStorageItem(Expression const& _expression)\n{\n\tsetLValue<StorageItem>(_expression, *_expression.annotation().type);\n}\n\nbool ExpressionCompiler::cleanupNeededForOp(Type::Category _type, Token _op, Arithmetic _arithmetic)\n{\n\tif (TokenTraits::isCompareOp(_op) || TokenTraits::isShiftOp(_op))\n\t\treturn true;\n\telse if (\n\t\t_arithmetic == Arithmetic::Wrapping &&\n\t\t_type == Type::Category::Integer &&\n\t\t(_op == Token::Div || _op == Token::Mod || _op == Token::Exp)\n\t)\n\t\t// We need cleanup for EXP because 0**0 == 1, but 0**0x100 == 0\n\t\t// It would suffice to clean the exponent, though.\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nvoid ExpressionCompiler::acceptAndConvert(Expression const& _expression, Type const& _type, bool _cleanupNeeded)\n{\n\t_expression.accept(*this);\n\tutils().convertType(*_expression.annotation().type, _type, _cleanupNeeded);\n}\n\nCompilerUtils ExpressionCompiler::utils()\n{\n\treturn CompilerUtils(m_context);\n}\n"
  },
  {
    "path": "libsolidity/codegen/ExpressionCompiler.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @author Gav Wood <g@ethdev.com>\n * @date 2014\n * Solidity AST to EVM bytecode compiler for expressions.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/codegen/LValue.h>\n#include <libsolidity/interface/DebugSettings.h>\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/SourceLocation.h>\n#include <libsolutil/Common.h>\n\n#include <functional>\n#include <memory>\n\nnamespace solidity::evmasm\n{\nclass AssemblyItem; // forward\n}\n\nnamespace solidity::frontend\n{\n\n// forward declarations\nclass CompilerContext;\nclass CompilerUtils;\nclass Type;\nclass IntegerType;\nclass ArrayType;\n\n/**\n * Compiler for expressions, i.e. converts an AST tree whose root is an Expression into a stream\n * of EVM instructions. It needs a compiler context that is the same for the whole compilation\n * unit.\n */\nclass ExpressionCompiler: private ASTConstVisitor\n{\npublic:\n\tExpressionCompiler(\n\t\tCompilerContext& _compilerContext,\n\t\tbool _optimiseOrderLiterals\n\t):\n\t\tm_optimiseOrderLiterals(_optimiseOrderLiterals),\n\t\tm_context(_compilerContext)\n\t{}\n\n\t/// Compile the given @a _expression and leave its value on the stack.\n\tvoid compile(Expression const& _expression);\n\n\t/// Appends code to set a state variable to its initial value/expression.\n\tvoid appendStateVariableInitialization(VariableDeclaration const& _varDecl);\n\n\t/// Appends code for a State Variable accessor function\n\tvoid appendStateVariableAccessor(VariableDeclaration const& _varDecl);\n\n\t/// Appends code for a Constant State Variable accessor function\n\tvoid appendConstStateVariableAccessor(VariableDeclaration const& _varDecl);\n\nprivate:\n\tbool visit(Conditional const& _condition) override;\n\tbool visit(Assignment const& _assignment) override;\n\tbool visit(TupleExpression const& _tuple) override;\n\tbool visit(UnaryOperation const& _unaryOperation) override;\n\tbool visit(BinaryOperation const& _binaryOperation) override;\n\tbool visit(FunctionCall const& _functionCall) override;\n\tbool visit(FunctionCallOptions const& _functionCallOptions) override;\n\tbool visit(NewExpression const& _newExpression) override;\n\tbool visit(MemberAccess const& _memberAccess) override;\n\tbool visit(IndexAccess const& _indexAccess) override;\n\tbool visit(IndexRangeAccess const& _indexAccess) override;\n\tvoid endVisit(Identifier const& _identifier) override;\n\tvoid endVisit(Literal const& _literal) override;\n\n\t///@{\n\t///@name Append code for various operator types\n\tvoid appendAndOrOperatorCode(BinaryOperation const& _binaryOperation);\n\tvoid appendCompareOperatorCode(Token _operator, Type const& _type);\n\tvoid appendOrdinaryBinaryOperatorCode(Token _operator, Type const& _type);\n\n\tvoid appendArithmeticOperatorCode(Token _operator, Type const& _type);\n\tvoid appendBitOperatorCode(Token _operator);\n\tvoid appendShiftOperatorCode(Token _operator, Type const& _valueType, Type const& _shiftAmountType);\n\tvoid appendExpOperatorCode(Type const& _valueType, Type const& _exponentType);\n\t/// @}\n\n\t/// Appends code to call a function of the given type with the given arguments.\n\t/// @param _tryCall if true, this is the external call of a try statement. In that case,\n\t///                 returns success flag on top of stack and does not revert on failure.\n\tvoid appendExternalFunctionCall(\n\t\tFunctionType const& _functionType,\n\t\tstd::vector<ASTPointer<Expression const>> const& _arguments,\n\t\tbool _tryCall\n\t);\n\t/// Appends code that evaluates a single expression and moves the result to memory. The memory offset is\n\t/// expected to be on the stack and is updated by this call.\n\tvoid appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression);\n\n\t/// Appends code for a variable that might be a constant or not\n\tvoid appendVariable(VariableDeclaration const& _variable, Expression const& _expression);\n\t/// Sets the current LValue to a new one (of the appropriate type) from the given declaration.\n\t/// Also retrieves the value if it was not requested by @a _expression.\n\tvoid setLValueFromDeclaration(Declaration const& _declaration, Expression const& _expression);\n\t/// Sets the current LValue to a StorageItem holding the type of @a _expression. The reference is assumed\n\t/// to be on the stack.\n\t/// Also retrieves the value if it was not requested by @a _expression.\n\tvoid setLValueToStorageItem(Expression const& _expression);\n\t/// Sets the current LValue to a new LValue constructed from the arguments.\n\t/// Also retrieves the value if it was not requested by @a _expression.\n\ttemplate <class LValueType, class... Arguments>\n\tvoid setLValue(Expression const& _expression, Arguments const&... _arguments);\n\n\t/// @returns true if the operator applied to the given type requires a cleanup prior to the\n\t/// operation.\n\tstatic bool cleanupNeededForOp(Type::Category _type, Token _op, Arithmetic _arithmetic);\n\n\tvoid acceptAndConvert(Expression const& _expression, Type const& _type, bool _cleanupNeeded = false);\n\n\t/// @returns the CompilerUtils object containing the current context.\n\tCompilerUtils utils();\n\n\tbool m_optimiseOrderLiterals;\n\tCompilerContext& m_context;\n\tstd::unique_ptr<LValue> m_currentLValue;\n\n};\n\ntemplate <class LValueType, class... Arguments>\nvoid ExpressionCompiler::setLValue(Expression const& _expression, Arguments const&... _arguments)\n{\n\tsolAssert(!m_currentLValue, \"Current LValue not reset before trying to set new one.\");\n\tstd::unique_ptr<LValueType> lvalue = std::make_unique<LValueType>(m_context, _arguments...);\n\tif (_expression.annotation().willBeWrittenTo)\n\t\tm_currentLValue = std::move(lvalue);\n\telse\n\t\tlvalue->retrieveValue(_expression.location(), true);\n}\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/LValue.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * LValues for use in the expression compiler.\n */\n\n#include <libsolidity/codegen/LValue.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/Types.h>\n#include <libsolidity/codegen/CompilerUtils.h>\n#include <libevmasm/Instruction.h>\n\n#include <libsolutil/StackTooDeepString.h>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\n\nStackVariable::StackVariable(CompilerContext& _compilerContext, VariableDeclaration const& _declaration):\n\tLValue(_compilerContext, _declaration.annotation().type),\n\tm_baseStackOffset(m_context.baseStackOffsetOfVariable(_declaration)),\n\tm_size(m_dataType->sizeOnStack())\n{\n}\n\nvoid StackVariable::retrieveValue(SourceLocation const& _location, bool) const\n{\n\tunsigned stackPos = m_context.baseToCurrentStackOffset(m_baseStackOffset);\n\tif (stackPos + 1 > m_context.reachableStackDepth()) //@todo correct this by fetching earlier or moving to memory\n\t\tBOOST_THROW_EXCEPTION(\n\t\t\tStackTooDeepError() <<\n\t\t\terrinfo_sourceLocation(_location) <<\n\t\t\tutil::errinfo_comment(util::stackTooDeepString)\n\t\t);\n\tsolAssert(stackPos + 1 >= m_size, \"Size and stack pos mismatch.\");\n\tfor (unsigned i = 0; i < m_size; ++i)\n\t\tm_context << dupInstruction(stackPos + 1);\n}\n\nvoid StackVariable::storeValue(Type const&, SourceLocation const& _location, bool _move) const\n{\n\tunsigned stackDiff = m_context.baseToCurrentStackOffset(m_baseStackOffset) - m_size + 1;\n\tif (stackDiff > m_context.reachableStackDepth())\n\t\tBOOST_THROW_EXCEPTION(\n\t\t\tStackTooDeepError() <<\n\t\t\terrinfo_sourceLocation(_location) <<\n\t\t\tutil::errinfo_comment(util::stackTooDeepString)\n\t\t);\n\telse if (stackDiff > 0)\n\t\tfor (unsigned i = 0; i < m_size; ++i)\n\t\t\tm_context << swapInstruction(stackDiff) << Instruction::POP;\n\tif (!_move)\n\t\tretrieveValue(_location);\n}\n\nvoid StackVariable::setToZero(SourceLocation const& _location, bool) const\n{\n\tCompilerUtils(m_context).pushZeroValue(*m_dataType);\n\tstoreValue(*m_dataType, _location, true);\n}\n\nMemoryItem::MemoryItem(CompilerContext& _compilerContext, Type const& _type, bool _padded):\n\tLValue(_compilerContext, &_type),\n\tm_padded(_padded)\n{\n}\n\nvoid MemoryItem::retrieveValue(SourceLocation const&, bool _remove) const\n{\n\tif (m_dataType->isValueType())\n\t{\n\t\tif (!_remove)\n\t\t\tm_context << Instruction::DUP1;\n\t\tCompilerUtils(m_context).loadFromMemoryDynamic(*m_dataType, false, m_padded, false);\n\t}\n\telse\n\t\tm_context << Instruction::MLOAD;\n}\n\nvoid MemoryItem::storeValue(Type const& _sourceType, SourceLocation const&, bool _move) const\n{\n\tCompilerUtils utils(m_context);\n\tif (m_dataType->isValueType())\n\t{\n\t\tsolAssert(_sourceType.isValueType(), \"\");\n\t\tutils.moveIntoStack(_sourceType.sizeOnStack());\n\t\tutils.convertType(_sourceType, *m_dataType, true);\n\t\tif (!_move)\n\t\t{\n\t\t\tutils.moveToStackTop(m_dataType->sizeOnStack());\n\t\t\tutils.copyToStackTop(1 + m_dataType->sizeOnStack(), m_dataType->sizeOnStack());\n\t\t}\n\t\tif (!m_padded)\n\t\t{\n\t\t\tsolAssert(m_dataType->calldataEncodedSize(false) == 1, \"Invalid non-padded type.\");\n\t\t\tsolAssert(m_dataType->category() != Type::Category::UserDefinedValueType, \"\");\n\t\t\tif (m_dataType->category() == Type::Category::FixedBytes)\n\t\t\t\tm_context << u256(0) << Instruction::BYTE;\n\t\t\tm_context << Instruction::SWAP1 << Instruction::MSTORE8;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tutils.storeInMemoryDynamic(*m_dataType, m_padded);\n\t\t\tm_context << Instruction::POP;\n\t\t}\n\t}\n\telse\n\t{\n\t\tsolUnimplementedAssert(_sourceType == *m_dataType, \"Conversion not implemented for assignment to memory.\");\n\n\t\tsolAssert(m_dataType->sizeOnStack() == 1, \"\");\n\t\tif (!_move)\n\t\t\tm_context << Instruction::DUP2 << Instruction::SWAP1;\n\t\t// stack: [value] value lvalue\n\t\t// only store the reference\n\t\tm_context << Instruction::MSTORE;\n\t}\n}\n\nvoid MemoryItem::setToZero(SourceLocation const&, bool _removeReference) const\n{\n\tCompilerUtils utils(m_context);\n\tsolAssert(_removeReference, \"\");\n\tutils.pushZeroValue(*m_dataType);\n\tutils.storeInMemoryDynamic(*m_dataType, m_padded);\n\tm_context << Instruction::POP;\n}\n\n\nImmutableItem::ImmutableItem(CompilerContext& _compilerContext, VariableDeclaration const& _variable):\n\tLValue(_compilerContext, _variable.annotation().type), m_variable(_variable)\n{\n\tsolAssert(_variable.immutable(), \"\");\n}\n\nvoid ImmutableItem::retrieveValue(SourceLocation const&, bool) const\n{\n\tsolUnimplementedAssert(m_dataType->isValueType());\n\n\tif (m_context.runtimeContext())\n\t\tCompilerUtils(m_context).loadFromMemory(\n\t\t\tstatic_cast<unsigned>(m_context.immutableMemoryOffset(m_variable)),\n\t\t\t*m_dataType,\n\t\t\tfalse,\n\t\t\ttrue\n\t\t);\n\telse\n\t\tfor (auto&& slotName: m_context.immutableVariableSlotNames(m_variable))\n\t\t\tm_context.appendImmutable(slotName);\n}\n\nvoid ImmutableItem::storeValue(Type const& _sourceType, SourceLocation const&, bool _move) const\n{\n\tCompilerUtils utils(m_context);\n\tsolUnimplementedAssert(m_dataType->isValueType());\n\tsolAssert(_sourceType.isValueType(), \"\");\n\n\tutils.convertType(_sourceType, *m_dataType, true);\n\tm_context << m_context.immutableMemoryOffset(m_variable);\n\tif (_move)\n\t\tutils.moveIntoStack(m_dataType->sizeOnStack());\n\telse\n\t\tutils.copyToStackTop(m_dataType->sizeOnStack() + 1, m_dataType->sizeOnStack());\n\tutils.storeInMemoryDynamic(*m_dataType);\n\tm_context << Instruction::POP;\n}\n\nvoid ImmutableItem::setToZero(SourceLocation const&, bool _removeReference) const\n{\n\tCompilerUtils utils(m_context);\n\tsolUnimplementedAssert(m_dataType->isValueType());\n\tsolAssert(_removeReference);\n\n\tm_context << m_context.immutableMemoryOffset(m_variable);\n\tutils.pushZeroValue(*m_dataType);\n\tutils.storeInMemoryDynamic(*m_dataType);\n\tm_context << Instruction::POP;\n}\n\ntemplate<bool IsTransient>\nGenericStorageItem<IsTransient>::GenericStorageItem(CompilerContext& _compilerContext, VariableDeclaration const& _declaration):\n\tGenericStorageItem<IsTransient>(_compilerContext, *_declaration.annotation().type)\n{\n\tsolAssert(!_declaration.immutable(), \"\");\n\tauto const& location = m_context.storageLocationOfVariable(_declaration);\n\tm_context << location.first << u256(location.second);\n}\n\ntemplate<bool IsTransient>\nGenericStorageItem<IsTransient>::GenericStorageItem(CompilerContext& _compilerContext, Type const& _type):\n\tLValue(_compilerContext, &_type)\n{\n\tif (m_dataType->isValueType())\n\t{\n\t\tif (m_dataType->category() != Type::Category::Function)\n\t\t\tsolAssert(m_dataType->storageSize() == m_dataType->sizeOnStack(), \"\");\n\t\tsolAssert(m_dataType->storageSize() == 1, \"Invalid storage size.\");\n\t}\n}\n\ntemplate<bool IsTransient>\nvoid GenericStorageItem<IsTransient>::retrieveValue(langutil::SourceLocation const&, bool _remove) const\n{\n\t// stack: storage_key storage_offset\n\tif (!m_dataType->isValueType())\n\t{\n\t\tsolUnimplementedAssert(!IsTransient, \"Transient storage reference types are not supported yet.\");\n\t\tsolAssert(m_dataType->sizeOnStack() == 1, \"Invalid storage ref size.\");\n\t\tif (_remove)\n\t\t\tm_context << Instruction::POP; // remove byte offset\n\t\telse\n\t\t\tm_context << Instruction::DUP2;\n\t\treturn;\n\t}\n\tif (!_remove)\n\t\tCompilerUtils(m_context).copyToStackTop(sizeOnStack(), sizeOnStack());\n\tif (m_dataType->storageBytes() == 32)\n\t\tm_context << Instruction::POP << s_loadInstruction;\n\telse\n\t{\n\t\tType const* type = m_dataType;\n\t\tif (type->category() == Type::Category::UserDefinedValueType)\n\t\t\ttype = type->encodingType();\n\t\tbool cleaned = false;\n\t\tm_context\n\t\t\t<< Instruction::SWAP1 << s_loadInstruction << Instruction::SWAP1\n\t\t\t<< u256(0x100) << Instruction::EXP << Instruction::SWAP1 << Instruction::DIV;\n\t\tif (type->category() == Type::Category::FixedPoint)\n\t\t\t// implementation should be very similar to the integer case.\n\t\t\tsolUnimplemented(\"Not yet implemented - FixedPointType.\");\n\t\telse if (auto const* fun = dynamic_cast<FunctionType const*>(type))\n\t\t{\n\t\t\tif (fun->kind() == FunctionType::Kind::External)\n\t\t\t{\n\t\t\t\tCompilerUtils(m_context).splitExternalFunctionType(false);\n\t\t\t\tcleaned = true;\n\t\t\t}\n\t\t\telse if (fun->kind() == FunctionType::Kind::Internal)\n\t\t\t{\n\t\t\t\tm_context << Instruction::DUP1 << Instruction::ISZERO;\n\t\t\t\tCompilerUtils(m_context).pushZeroValue(*fun);\n\t\t\t\tm_context << Instruction::MUL << Instruction::OR;\n\t\t\t}\n\t\t}\n\t\telse if (type->leftAligned())\n\t\t{\n\t\t\tCompilerUtils(m_context).leftShiftNumberOnStack(256 - 8 * type->storageBytes());\n\t\t\tcleaned = true;\n\t\t}\n\t\telse if (\n\t\t\ttype->category() == Type::Category::Integer &&\n\t\t\tdynamic_cast<IntegerType const&>(*type).isSigned()\n\t\t)\n\t\t{\n\t\t\tm_context << u256(type->storageBytes() - 1) << Instruction::SIGNEXTEND;\n\t\t\tcleaned = true;\n\t\t}\n\n\t\tif (!cleaned)\n\t\t{\n\t\t\tsolAssert(type->sizeOnStack() == 1, \"\");\n\t\t\tm_context << ((u256(0x1) << (8 * type->storageBytes())) - 1) << Instruction::AND;\n\t\t}\n\t}\n}\n\ntemplate<bool IsTransient>\nvoid GenericStorageItem<IsTransient>::storeValue(Type const& _sourceType, langutil::SourceLocation const& _location, bool _move) const\n{\n\tCompilerUtils utils(m_context);\n\tsolAssert(m_dataType, \"\");\n\n\t// stack: value storage_key storage_offset\n\tif (m_dataType->isValueType())\n\t{\n\t\tsolAssert(m_dataType->storageBytes() <= 32, \"Invalid storage bytes size.\");\n\t\tsolAssert(m_dataType->storageBytes() > 0, \"Invalid storage bytes size.\");\n\t\tif (m_dataType->storageBytes() == 32)\n\t\t{\n\t\t\tsolAssert(m_dataType->sizeOnStack() == 1, \"Invalid stack size.\");\n\t\t\t// offset should be zero\n\t\t\tm_context << Instruction::POP;\n\t\t\tif (!_move)\n\t\t\t\tm_context << Instruction::DUP2 << Instruction::SWAP1;\n\n\t\t\tm_context << Instruction::SWAP1;\n\t\t\tutils.convertType(_sourceType, *m_dataType, true);\n\t\t\tm_context << Instruction::SWAP1;\n\n\t\t\tm_context << s_storeInstruction;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// OR the value into the other values in the storage slot\n\t\t\tm_context << u256(0x100) << Instruction::EXP;\n\t\t\t// stack: value storage_ref multiplier\n\t\t\t// fetch old value\n\t\t\tm_context << Instruction::DUP2 << s_loadInstruction;\n\t\t\t// stack: value storage_ref multiplier old_full_value\n\t\t\t// clear bytes in old value\n\t\t\tm_context\n\t\t\t\t<< Instruction::DUP2 << ((u256(1) << (8 * m_dataType->storageBytes())) - 1)\n\t\t\t\t<< Instruction::MUL;\n\t\t\tm_context << Instruction::NOT << Instruction::AND << Instruction::SWAP1;\n\t\t\t// stack: value storage_ref cleared_value multiplier\n\t\t\tutils.copyToStackTop(3 + m_dataType->sizeOnStack(), m_dataType->sizeOnStack());\n\t\t\t// stack: value storage_ref cleared_value multiplier value\n\t\t\tif (auto const* fun = dynamic_cast<FunctionType const*>(m_dataType))\n\t\t\t{\n\t\t\t\tsolAssert(\n\t\t\t\t\t_sourceType.isImplicitlyConvertibleTo(*m_dataType),\n\t\t\t\t\t\"function item stored but target is not implicitly convertible to source\"\n\t\t\t\t);\n\t\t\t\tsolAssert(!fun->hasBoundFirstArgument(), \"\");\n\t\t\t\tif (fun->kind() == FunctionType::Kind::External)\n\t\t\t\t{\n\t\t\t\t\tsolAssert(fun->sizeOnStack() == 2, \"\");\n\t\t\t\t\t// Combine the two-item function type into a single stack slot.\n\t\t\t\t\tutils.combineExternalFunctionType(false);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsolAssert(fun->sizeOnStack() == 1, \"\");\n\t\t\t\t\tm_context <<\n\t\t\t\t\t\t((u256(1) << (8 * m_dataType->storageBytes())) - 1) <<\n\t\t\t\t\t\tInstruction::AND;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (m_dataType->leftAligned())\n\t\t\t{\n\t\t\t\tsolAssert(_sourceType.category() == Type::Category::FixedBytes || (\n\t\t\t\t\t_sourceType.encodingType() &&\n\t\t\t\t\t_sourceType.encodingType()->category() == Type::Category::FixedBytes\n\t\t\t\t), \"source not fixed bytes\");\n\t\t\t\tCompilerUtils(m_context).rightShiftNumberOnStack(256 - 8 * m_dataType->storageBytes());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsolAssert(m_dataType->sizeOnStack() == 1, \"Invalid stack size for opaque type.\");\n\t\t\t\t// remove the higher order bits\n\t\t\t\tutils.convertType(_sourceType, *m_dataType, true, true);\n\t\t\t}\n\t\t\tm_context  << Instruction::MUL << Instruction::OR;\n\t\t\t// stack: value storage_ref updated_value\n\t\t\tm_context << Instruction::SWAP1 << s_storeInstruction;\n\t\t\tif (_move)\n\t\t\t\tutils.popStackElement(*m_dataType);\n\t\t}\n\t}\n\telse\n\t{\n\t\tsolUnimplementedAssert(!IsTransient, \"Transient storage reference types are not supported yet.\");\n\t\tsolAssert(\n\t\t\t_sourceType.category() == m_dataType->category(),\n\t\t\t\"Wrong type conversation for assignment.\"\n\t\t);\n\t\tif (m_dataType->category() == Type::Category::Array)\n\t\t{\n\t\t\tm_context << Instruction::POP; // remove byte offset\n\t\t\tArrayUtils(m_context).copyArrayToStorage(\n\t\t\t\tdynamic_cast<ArrayType const&>(*m_dataType),\n\t\t\t\tdynamic_cast<ArrayType const&>(_sourceType)\n\t\t\t);\n\t\t\tif (_move)\n\t\t\t\tm_context << Instruction::POP;\n\t\t}\n\t\telse if (m_dataType->category() == Type::Category::Struct)\n\t\t{\n\t\t\t// stack layout: source_ref target_ref target_offset\n\t\t\t// note that we have structs, so offset should be zero and are ignored\n\t\t\tm_context << Instruction::POP;\n\t\t\tauto const& structType = dynamic_cast<StructType const&>(*m_dataType);\n\t\t\tauto const& sourceType = dynamic_cast<StructType const&>(_sourceType);\n\t\t\tsolAssert(\n\t\t\t\tstructType.structDefinition() == sourceType.structDefinition(),\n\t\t\t\t\"Struct assignment with conversion.\"\n\t\t\t);\n\t\t\tsolAssert(!structType.containsNestedMapping(), \"\");\n\t\t\tif (sourceType.location() == DataLocation::CallData)\n\t\t\t{\n\t\t\t\tsolAssert(sourceType.sizeOnStack() == 1, \"\");\n\t\t\t\tsolAssert(structType.sizeOnStack() == 1, \"\");\n\t\t\t\tm_context << Instruction::DUP2 << Instruction::DUP2;\n\t\t\t\tm_context.callYulFunction(m_context.utilFunctions().updateStorageValueFunction(sourceType, structType, VariableDeclaration::Location::Unspecified, 0), 2, 0);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfor (auto const& member: structType.members(nullptr))\n\t\t\t\t{\n\t\t\t\t\t// assign each member that can live outside of storage\n\t\t\t\t\tType const* memberType = member.type;\n\t\t\t\t\tsolAssert(memberType->nameable(), \"\");\n\t\t\t\t\tType const* sourceMemberType = sourceType.memberType(member.name);\n\t\t\t\t\tif (sourceType.location() == DataLocation::Storage)\n\t\t\t\t\t{\n\t\t\t\t\t\t// stack layout: source_ref target_ref\n\t\t\t\t\t\tstd::pair<u256, unsigned> const& offsets = sourceType.storageOffsetsOfMember(member.name);\n\t\t\t\t\t\tm_context << offsets.first << Instruction::DUP3 << Instruction::ADD;\n\t\t\t\t\t\tm_context << u256(offsets.second);\n\t\t\t\t\t\t// stack: source_ref target_ref source_member_ref source_member_off\n\t\t\t\t\t\tStorageItem(m_context, *sourceMemberType).retrieveValue(_location, true);\n\t\t\t\t\t\t// stack: source_ref target_ref source_value...\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(sourceType.location() == DataLocation::Memory, \"\");\n\t\t\t\t\t\t// stack layout: source_ref target_ref\n\t\t\t\t\t\tm_context << sourceType.memoryOffsetOfMember(member.name);\n\t\t\t\t\t\tm_context << Instruction::DUP3 << Instruction::ADD;\n\t\t\t\t\t\tMemoryItem(m_context, *sourceMemberType).retrieveValue(_location, true);\n\t\t\t\t\t\t// stack layout: source_ref target_ref source_value...\n\t\t\t\t\t}\n\t\t\t\t\tunsigned stackSize = sourceMemberType->sizeOnStack();\n\t\t\t\t\tstd::pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member.name);\n\t\t\t\t\tm_context << dupInstruction(1 + stackSize) << offsets.first << Instruction::ADD;\n\t\t\t\t\tm_context << u256(offsets.second);\n\t\t\t\t\t// stack: source_ref target_ref target_off source_value... target_member_ref target_member_byte_off\n\t\t\t\t\tStorageItem(m_context, *memberType).storeValue(*sourceMemberType, _location, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// stack layout: source_ref target_ref\n\t\t\tsolAssert(sourceType.sizeOnStack() == 1, \"Unexpected source size.\");\n\t\t\tif (_move)\n\t\t\t\tutils.popStackSlots(2);\n\t\t\telse\n\t\t\t\tm_context << Instruction::SWAP1 << Instruction::POP;\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"Invalid non-value type for assignment.\");\n\t}\n}\n\ntemplate<bool IsTransient>\nvoid GenericStorageItem<IsTransient>::setToZero(langutil::SourceLocation const&, bool _removeReference) const\n{\n\tif (m_dataType->category() == Type::Category::Array)\n\t{\n\t\tsolUnimplementedAssert(!IsTransient, \"Transient storage reference types are not supported yet.\");\n\t\tif (!_removeReference)\n\t\t\tCompilerUtils(m_context).copyToStackTop(sizeOnStack(), sizeOnStack());\n\t\tArrayUtils(m_context).clearArray(dynamic_cast<ArrayType const&>(*m_dataType));\n\t}\n\telse if (m_dataType->category() == Type::Category::Struct)\n\t{\n\t\tsolUnimplementedAssert(!IsTransient, \"Transient storage reference types are not supported yet.\");\n\t\t// stack layout: storage_key storage_offset\n\t\t// @todo this can be improved: use StorageItem for non-value types, and just store 0 in\n\t\t// all slots that contain value types later.\n\t\tauto const& structType = dynamic_cast<StructType const&>(*m_dataType);\n\t\tfor (auto const& member: structType.members(nullptr))\n\t\t{\n\t\t\t// zero each member that is not a mapping\n\t\t\tType const* memberType = member.type;\n\t\t\tif (memberType->category() == Type::Category::Mapping)\n\t\t\t\tcontinue;\n\t\t\tstd::pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member.name);\n\t\t\tm_context\n\t\t\t\t<< offsets.first << Instruction::DUP3 << Instruction::ADD\n\t\t\t\t<< u256(offsets.second);\n\t\t\tStorageItem(m_context, *memberType).setToZero();\n\t\t}\n\t\tif (_removeReference)\n\t\t\tm_context << Instruction::POP << Instruction::POP;\n\t}\n\telse\n\t{\n\t\tsolAssert(m_dataType->isValueType(), \"Clearing of unsupported type requested: \" + m_dataType->toString());\n\t\tif (!_removeReference)\n\t\t\tCompilerUtils(m_context).copyToStackTop(sizeOnStack(), sizeOnStack());\n\t\tif (m_dataType->storageBytes() == 32)\n\t\t{\n\t\t\t// offset should be zero\n\t\t\tm_context\n\t\t\t\t<< Instruction::POP << u256(0)\n\t\t\t\t<< Instruction::SWAP1 << s_storeInstruction;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_context << u256(0x100) << Instruction::EXP;\n\t\t\t// stack: storage_ref multiplier\n\t\t\t// fetch old value\n\t\t\tm_context << Instruction::DUP2 << s_loadInstruction;\n\t\t\t// stack: storage_ref multiplier old_full_value\n\t\t\t// clear bytes in old value\n\t\t\tm_context\n\t\t\t\t<< Instruction::SWAP1 << ((u256(1) << (8 * m_dataType->storageBytes())) - 1)\n\t\t\t\t<< Instruction::MUL;\n\t\t\tm_context << Instruction::NOT << Instruction::AND;\n\t\t\t// stack: storage_ref cleared_value\n\t\t\tm_context << Instruction::SWAP1 << s_storeInstruction;\n\t\t}\n\t}\n}\n\nStorageByteArrayElement::StorageByteArrayElement(CompilerContext& _compilerContext):\n\tLValue(_compilerContext, TypeProvider::byte())\n{\n}\n\nvoid StorageByteArrayElement::retrieveValue(SourceLocation const&, bool _remove) const\n{\n\t// stack: ref byte_number\n\tif (_remove)\n\t\tm_context << Instruction::SWAP1 << Instruction::SLOAD\n\t\t\t<< Instruction::SWAP1 << Instruction::BYTE;\n\telse\n\t\tm_context << Instruction::DUP2 << Instruction::SLOAD\n\t\t\t<< Instruction::DUP2 << Instruction::BYTE;\n\tm_context << (u256(1) << (256 - 8)) << Instruction::MUL;\n}\n\nvoid StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, bool _move) const\n{\n\t// stack: value ref byte_number\n\tm_context << u256(31) << Instruction::SUB << u256(0x100) << Instruction::EXP;\n\t// stack: value ref (1<<(8*(31-byte_number)))\n\tm_context << Instruction::DUP2 << Instruction::SLOAD;\n\t// stack: value ref (1<<(8*(31-byte_number))) old_full_value\n\t// clear byte in old value\n\tm_context << Instruction::DUP2 << u256(0xff) << Instruction::MUL\n\t\t<< Instruction::NOT << Instruction::AND;\n\t// stack: value ref (1<<(32-byte_number)) old_full_value_with_cleared_byte\n\tm_context << Instruction::SWAP1;\n\tm_context << (u256(1) << (256 - 8)) << Instruction::DUP5 << Instruction::DIV\n\t\t<< Instruction::MUL << Instruction::OR;\n\t// stack: value ref new_full_value\n\tm_context << Instruction::SWAP1 << Instruction::SSTORE;\n\tif (_move)\n\t\tm_context << Instruction::POP;\n}\n\nvoid StorageByteArrayElement::setToZero(SourceLocation const&, bool _removeReference) const\n{\n\t// stack: ref byte_number\n\tsolAssert(_removeReference, \"\");\n\tm_context << u256(31) << Instruction::SUB << u256(0x100) << Instruction::EXP;\n\t// stack: ref (1<<(8*(31-byte_number)))\n\tm_context << Instruction::DUP2 << Instruction::SLOAD;\n\t// stack: ref (1<<(8*(31-byte_number))) old_full_value\n\t// clear byte in old value\n\tm_context << Instruction::SWAP1 << u256(0xff) << Instruction::MUL;\n\tm_context << Instruction::NOT << Instruction::AND;\n\t// stack: ref old_full_value_with_cleared_byte\n\tm_context << Instruction::SWAP1 << Instruction::SSTORE;\n}\n\nTupleObject::TupleObject(\n\tCompilerContext& _compilerContext,\n\tstd::vector<std::unique_ptr<LValue>>&& _lvalues\n):\n\tLValue(_compilerContext), m_lvalues(std::move(_lvalues))\n{\n}\n\nunsigned TupleObject::sizeOnStack() const\n{\n\tunsigned size = 0;\n\tfor (auto const& lv: m_lvalues)\n\t\tif (lv)\n\t\t\tsize += lv->sizeOnStack();\n\treturn size;\n}\n\nvoid TupleObject::retrieveValue(SourceLocation const&, bool) const\n{\n\tsolAssert(false, \"Tried to retrieve value of tuple.\");\n}\n\nvoid TupleObject::storeValue(Type const& _sourceType, SourceLocation const& _location, bool) const\n{\n\t// values are below the lvalue references\n\tunsigned valuePos = sizeOnStack();\n\tTypePointers const& valueTypes = dynamic_cast<TupleType const&>(_sourceType).components();\n\tsolAssert(valueTypes.size() == m_lvalues.size(), \"\");\n\t// valuePos .... refPos ...\n\t// We will assign from right to left to optimize stack layout.\n\tfor (size_t i = 0; i < m_lvalues.size(); ++i)\n\t{\n\t\tstd::unique_ptr<LValue> const& lvalue = m_lvalues[m_lvalues.size() - i - 1];\n\t\tType const* valType = valueTypes[valueTypes.size() - i - 1];\n\t\tunsigned stackHeight = m_context.stackHeight();\n\t\tsolAssert(!valType == !lvalue, \"\");\n\t\tif (!lvalue)\n\t\t\tcontinue;\n\t\tvaluePos += valType->sizeOnStack();\n\t\t// copy value to top\n\t\tCompilerUtils(m_context).copyToStackTop(valuePos, valType->sizeOnStack());\n\t\t// move lvalue ref above value\n\t\tCompilerUtils(m_context).moveToStackTop(valType->sizeOnStack(), lvalue->sizeOnStack());\n\t\tlvalue->storeValue(*valType, _location, true);\n\t\tvaluePos += m_context.stackHeight() - stackHeight;\n\t}\n\t// As the type of an assignment to a tuple type is the empty tuple, we always move.\n\tCompilerUtils(m_context).popStackElement(_sourceType);\n}\n\nvoid TupleObject::setToZero(SourceLocation const&, bool) const\n{\n\tsolAssert(false, \"Tried to delete tuple.\");\n}\n\ntemplate class solidity::frontend::GenericStorageItem<false>;\ntemplate class solidity::frontend::GenericStorageItem<true>;\n"
  },
  {
    "path": "libsolidity/codegen/LValue.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * LValues for use in the expression compiler.\n */\n\n#pragma once\n\n#include <libsolidity/codegen/ArrayUtils.h>\n#include <libsolutil/Common.h>\n#include <liblangutil/SourceLocation.h>\n#include <libevmasm/Instruction.h>\n#include <memory>\n#include <vector>\n\nnamespace solidity::frontend\n{\n\nclass Declaration;\nclass Type;\nclass TupleType;\nclass ArrayType;\nclass CompilerContext;\nclass VariableDeclaration;\n\n/**\n * Abstract class used to retrieve, delete and store data in lvalues/variables.\n */\nclass LValue\n{\nprotected:\n\texplicit LValue(CompilerContext& _compilerContext, Type const* _dataType = nullptr):\n\t\tm_context(_compilerContext), m_dataType(_dataType) {}\n\npublic:\n\tvirtual ~LValue() = default;\n\t/// @returns the number of stack slots occupied by the lvalue reference\n\tvirtual unsigned sizeOnStack() const { return 1; }\n\t/// Copies the value of the current lvalue to the top of the stack and, if @a _remove is true,\n\t/// also removes the reference from the stack.\n\t/// @a _location source location of the current expression, used for error reporting.\n\tvirtual void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const = 0;\n\t/// Moves a value from the stack to the lvalue. Removes the value if @a _move is true.\n\t/// @a _location is the source location of the expression that caused this operation.\n\t/// Stack pre: value [lvalue_ref]\n\t/// Stack post: if !_move: value_of(lvalue_ref)\n\tvirtual void storeValue(Type const& _sourceType,\n\t\tlangutil::SourceLocation const& _location = {}, bool _move = false) const = 0;\n\t/// Stores zero in the lvalue. Removes the reference from the stack if @a _removeReference is true.\n\t/// @a _location is the source location of the requested operation\n\tvirtual void setToZero(\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _removeReference = true\n\t) const = 0;\n\nprotected:\n\tCompilerContext& m_context;\n\tType const* m_dataType;\n};\n\n/**\n * Local variable that is completely stored on the stack.\n */\nclass StackVariable: public LValue\n{\npublic:\n\tStackVariable(CompilerContext& _compilerContext, VariableDeclaration const& _declaration);\n\n\tunsigned sizeOnStack() const override { return 0; }\n\tvoid retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;\n\tvoid storeValue(\n\t\tType const& _sourceType,\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _move = false\n\t) const override;\n\tvoid setToZero(\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _removeReference = true\n\t) const override;\n\nprivate:\n\t/// Base stack offset (@see CompilerContext::baseStackOffsetOfVariable) of the local variable.\n\tunsigned m_baseStackOffset;\n\t/// Number of stack elements occupied by the value (not the reference).\n\tunsigned m_size;\n};\n\n/**\n * Reference to some item in memory.\n */\nclass MemoryItem: public LValue\n{\npublic:\n\tMemoryItem(CompilerContext& _compilerContext, Type const& _type, bool _padded = true);\n\tunsigned sizeOnStack() const override { return 1; }\n\tvoid retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;\n\tvoid storeValue(\n\t\tType const& _sourceType,\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _move = false\n\t) const override;\n\tvoid setToZero(\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _removeReference = true\n\t) const override;\nprivate:\n\t/// Special flag to deal with byte array elements.\n\tbool m_padded = false;\n};\n\n/**\n * Reference to an immutable variable. During contract creation this refers to a location in memory. At the\n * end of contract creation the values from these memory locations are copied into all occurrences of the immutable\n * variable in the runtime code.\n */\nclass ImmutableItem: public LValue\n{\npublic:\n\tImmutableItem(CompilerContext& _compilerContext, VariableDeclaration const& _variable);\n\tunsigned sizeOnStack() const override { return 0; }\n\tvoid retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;\n\tvoid storeValue(\n\t\tType const& _sourceType,\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _move = false\n\t) const override;\n\tvoid setToZero(\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _removeReference = true\n\t) const override;\nprivate:\n\tVariableDeclaration const& m_variable;\n};\n\n/**\n * Reference to some item in storage/transient storage. On the stack this is <storage key> <offset_inside_value>,\n * where 0 <= offset_inside_value < 32 and an offset of i means that the value is multiplied\n * by 2**i before storing it.\n */\ntemplate<bool IsTransient>\nclass GenericStorageItem : public LValue\n{\npublic:\n\t/// Constructs the LValue and pushes the location of @a _declaration onto the stack.\n\tGenericStorageItem(CompilerContext& _compilerContext, VariableDeclaration const& _declaration);\n\t/// Constructs the LValue and assumes that the storage reference is already on the stack.\n\tGenericStorageItem(CompilerContext& _compilerContext, Type const& _type);\n\tunsigned sizeOnStack() const override { return 2; }\n\tvoid retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;\n\tvoid storeValue(\n\t\tType const& _sourceType,\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _move = false\n\t) const override;\n\tvoid setToZero(\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _removeReference = true\n\t) const override;\nprivate:\n\tstatic constexpr evmasm::Instruction s_storeInstruction = IsTransient ? evmasm::Instruction::TSTORE : evmasm::Instruction::SSTORE;\n\tstatic constexpr evmasm::Instruction s_loadInstruction = IsTransient ? evmasm::Instruction::TLOAD : evmasm::Instruction::SLOAD;\n};\nextern template class GenericStorageItem<false>;\nextern template class GenericStorageItem<true>;\nusing StorageItem = GenericStorageItem<false>;\nusing TransientStorageItem = GenericStorageItem<true>;\n\n/**\n * Reference to a single byte inside a storage byte array.\n * Stack: <storage_ref> <byte_number>\n */\nclass StorageByteArrayElement: public LValue\n{\npublic:\n\t/// Constructs the LValue and assumes that the storage reference is already on the stack.\n\tStorageByteArrayElement(CompilerContext& _compilerContext);\n\tunsigned sizeOnStack() const override { return 2; }\n\tvoid retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;\n\tvoid storeValue(\n\t\tType const& _sourceType,\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _move = false\n\t) const override;\n\tvoid setToZero(\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _removeReference = true\n\t) const override;\n};\n\n/**\n * Tuple object that can itself hold several LValues.\n */\nclass TupleObject: public LValue\n{\npublic:\n\t/// Constructs the LValue assuming that the other LValues are present on the stack.\n\t/// Empty unique_ptrs are possible if e.g. some values should be ignored during assignment.\n\tTupleObject(CompilerContext& _compilerContext, std::vector<std::unique_ptr<LValue>>&& _lvalues);\n\tunsigned sizeOnStack() const override;\n\tvoid retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;\n\tvoid storeValue(\n\t\tType const& _sourceType,\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _move = false\n\t) const override;\n\tvoid setToZero(\n\t\tlangutil::SourceLocation const& _location = {},\n\t\tbool _removeReference = true\n\t) const override;\n\nprivate:\n\tstd::vector<std::unique_ptr<LValue>> m_lvalues;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/MultiUseYulFunctionCollector.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Container of (unparsed) Yul functions identified by name which are meant to be generated\n * only once.\n */\n\n#include <libsolidity/codegen/MultiUseYulFunctionCollector.h>\n\n#include <liblangutil/Exceptions.h>\n#include <libsolutil/Whiskers.h>\n#include <libsolutil/StringUtils.h>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\nusing namespace solidity::util;\n\nstd::string MultiUseYulFunctionCollector::requestedFunctions()\n{\n\tstd::string result = std::move(m_code);\n\tm_code.clear();\n\tm_requestedFunctions.clear();\n\treturn result;\n}\n\nstd::string MultiUseYulFunctionCollector::createFunction(std::string const& _name, std::function<std::string()> const& _creator)\n{\n\tif (!m_requestedFunctions.count(_name))\n\t{\n\t\tm_requestedFunctions.insert(_name);\n\t\tstd::string fun = _creator();\n\t\tsolAssert(!fun.empty(), \"\");\n\t\tsolAssert(fun.find(\"function \" + _name + \"(\") != std::string::npos, \"Function not properly named.\");\n\t\tm_code += std::move(fun);\n\t}\n\treturn _name;\n}\n\nstd::string MultiUseYulFunctionCollector::createFunction(\n\tstd::string const& _name,\n\tstd::function<std::string(std::vector<std::string>&, std::vector<std::string>&)> const& _creator\n)\n{\n\tsolAssert(!_name.empty(), \"\");\n\tif (!m_requestedFunctions.count(_name))\n\t{\n\t\tm_requestedFunctions.insert(_name);\n\t\tstd::vector<std::string> arguments;\n\t\tstd::vector<std::string> returnParameters;\n\t\tstd::string body = _creator(arguments, returnParameters);\n\t\tsolAssert(!body.empty(), \"\");\n\n\t\tm_code += Whiskers(R\"(\n\t\t\tfunction <functionName>(<args>)<?+retParams> -> <retParams></+retParams> {\n\t\t\t\t<body>\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", _name)\n\t\t(\"args\", joinHumanReadable(arguments))\n\t\t(\"retParams\", joinHumanReadable(returnParameters))\n\t\t(\"body\", body)\n\t\t.render();\n\t}\n\treturn _name;\n}\n"
  },
  {
    "path": "libsolidity/codegen/MultiUseYulFunctionCollector.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Container of (unparsed) Yul functions identified by name which are meant to be generated\n * only once.\n */\n\n#pragma once\n\n#include <functional>\n#include <map>\n#include <string>\n#include <set>\n\nnamespace solidity::frontend\n{\n\n/**\n * Container of (unparsed) Yul functions identified by name which are meant to be generated\n * only once.\n */\nclass MultiUseYulFunctionCollector\n{\npublic:\n\t/// Helper function that uses @a _creator to create a function and add it to\n\t/// @a m_requestedFunctions if it has not been created yet and returns @a _name in both\n\t/// cases.\n\tstd::string createFunction(std::string const& _name, std::function<std::string()> const& _creator);\n\n\tstd::string createFunction(\n\t\tstd::string const& _name,\n\t\tstd::function<std::string(std::vector<std::string>&, std::vector<std::string>&)> const& _creator\n\t);\n\n\t/// @returns concatenation of all generated functions in the order in which they were\n\t/// generated.\n\t/// Clears the internal list, i.e. calling it again will result in an\n\t/// empty return value.\n\tstd::string requestedFunctions();\n\n\t/// @returns true IFF a function with the specified name has already been collected.\n\tbool contains(std::string const& _name) const { return m_requestedFunctions.count(_name) > 0; }\n\nprivate:\n\tstd::set<std::string> m_requestedFunctions;\n\tstd::string m_code;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ReturnInfo.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/codegen/ReturnInfo.h>\n\n#include <libsolidity/ast/Types.h>\n#include <libsolidity/ast/AST.h>\n\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\n\nReturnInfo::ReturnInfo(EVMVersion const& _evmVersion, FunctionType const& _functionType)\n{\n\tFunctionType::Kind const funKind = _functionType.kind();\n\tbool const haveReturndatacopy = _evmVersion.supportsReturndata();\n\tbool const returnSuccessConditionAndReturndata =\n\t\tfunKind == FunctionType::Kind::BareCall ||\n\t\tfunKind == FunctionType::Kind::BareDelegateCall ||\n\t\tfunKind == FunctionType::Kind::BareStaticCall;\n\n\tif (!returnSuccessConditionAndReturndata)\n\t{\n\t\tif (haveReturndatacopy)\n\t\t\treturnTypes = _functionType.returnParameterTypes();\n\t\telse\n\t\t\treturnTypes = _functionType.returnParameterTypesWithoutDynamicTypes();\n\n\t\tfor (auto const& retType: returnTypes)\n\t\t{\n\t\t\tsolAssert(retType->decodingType(), \"\");\n\t\t\tif (retType->decodingType()->isDynamicallyEncoded())\n\t\t\t{\n\t\t\t\tsolAssert(haveReturndatacopy, \"\");\n\t\t\t\tdynamicReturnSize = true;\n\t\t\t\testimatedReturnSize = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t\testimatedReturnSize += retType->decodingType()->calldataEncodedSize();\n\t\t}\n\t}\n\tif (dynamicReturnSize)\n\t\tsolAssert(estimatedReturnSize == 0);\n}\n"
  },
  {
    "path": "libsolidity/codegen/ReturnInfo.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that computes information relevant during decoding an external function\n * call's return values.\n */\n#pragma once\n\n#include <liblangutil/EVMVersion.h>\n#include <libsolidity/ast/Types.h>\n\nnamespace solidity::frontend\n{\n\n/**\n * Computes and holds information relevant during decoding an external function\n * call's return values.\n */\nstruct ReturnInfo\n{\n\tReturnInfo(langutil::EVMVersion const& _evmVersion, FunctionType const& _functionType);\n\n\t/// Vector of Type const*, for each return variable. Dynamic types are already replaced if required.\n\tTypePointers returnTypes = {};\n\n\t/// Boolean, indicating whether or not return size is only known at runtime.\n\tbool dynamicReturnSize = false;\n\n\t/// Contains the at compile time estimated return size.\n\tunsigned estimatedReturnSize = 0;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/YulUtilFunctions.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that can generate various useful Yul functions.\n */\n\n#include <libsolidity/codegen/YulUtilFunctions.h>\n\n#include <libsolidity/codegen/MultiUseYulFunctionCollector.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/codegen/CompilerUtils.h>\n#include <libsolidity/codegen/ir/IRVariable.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/FunctionSelector.h>\n#include <libsolutil/Whiskers.h>\n#include <libsolutil/StringUtils.h>\n#include <libsolidity/ast/TypeProvider.h>\n\n#include <range/v3/algorithm/all_of.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::frontend;\nusing namespace std::string_literals;\n\nnamespace\n{\n\nstd::optional<size_t> staticEncodingSize(std::vector<Type const*> const& _parameterTypes)\n{\n\tsize_t encodedSize = 0;\n\tfor (auto* type: _parameterTypes)\n\t{\n\t\tif (type->isDynamicallyEncoded())\n\t\t\treturn std::nullopt;\n\t\tencodedSize += type->calldataHeadSize();\n\t}\n\treturn encodedSize;\n}\n\n}\n\nstd::string YulUtilFunctions::identityFunction()\n{\n\tstd::string functionName = \"identity\";\n\treturn m_functionCollector.createFunction(\"identity\", [&](std::vector<std::string>& _args, std::vector<std::string>& _rets) {\n\t\t_args.push_back(\"value\");\n\t\t_rets.push_back(\"ret\");\n\t\treturn \"ret := value\";\n\t});\n}\n\nstd::string YulUtilFunctions::combineExternalFunctionIdFunction()\n{\n\tstd::string functionName = \"combine_external_function_id\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(addr, selector) -> combined {\n\t\t\t\tcombined := <shl64>(or(<shl32>(addr), and(selector, 0xffffffff)))\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"shl32\", shiftLeftFunction(32))\n\t\t(\"shl64\", shiftLeftFunction(64))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::splitExternalFunctionIdFunction()\n{\n\tstd::string functionName = \"split_external_function_id\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(combined) -> addr, selector {\n\t\t\t\tcombined := <shr64>(combined)\n\t\t\t\tselector := and(combined, 0xffffffff)\n\t\t\t\taddr := <shr32>(combined)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"shr32\", shiftRightFunction(32))\n\t\t(\"shr64\", shiftRightFunction(64))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::copyToMemoryFunction(bool _fromCalldata, bool _cleanup)\n{\n\tstd::string functionName =\n\t\t\"copy_\"s +\n\t\t(_fromCalldata ? \"calldata\"s : \"memory\"s) +\n\t\t\"_to_memory\"s +\n\t\t(_cleanup ? \"_with_cleanup\"s : \"\"s);\n\n\treturn m_functionCollector.createFunction(functionName, [&](std::vector<std::string>& _args, std::vector<std::string>&) {\n\t\t_args = {\"src\", \"dst\", \"length\"};\n\n\t\tif (_fromCalldata)\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tcalldatacopy(dst, src, length)\n\t\t\t\t<?cleanup>mstore(add(dst, length), 0)</cleanup>\n\t\t\t)\")\n\t\t\t(\"cleanup\", _cleanup)\n\t\t\t.render();\n\t\telse\n\t\t{\n\t\t\tif (m_evmVersion.hasMcopy())\n\t\t\t\treturn Whiskers(R\"(\n\t\t\t\t\tmcopy(dst, src, length)\n\t\t\t\t\t<?cleanup>mstore(add(dst, length), 0)</cleanup>\n\t\t\t\t)\")\n\t\t\t\t(\"cleanup\", _cleanup)\n\t\t\t\t.render();\n\t\t\telse\n\t\t\t\treturn Whiskers(R\"(\n\t\t\t\t\tlet i := 0\n\t\t\t\t\tfor { } lt(i, length) { i := add(i, 32) }\n\t\t\t\t\t{\n\t\t\t\t\t\tmstore(add(dst, i), mload(add(src, i)))\n\t\t\t\t\t}\n\t\t\t\t\t<?cleanup>mstore(add(dst, length), 0)</cleanup>\n\t\t\t\t)\")\n\t\t\t\t(\"cleanup\", _cleanup)\n\t\t\t\t.render();\n\t\t}\n\t});\n}\n\nstd::string YulUtilFunctions::copyLiteralToMemoryFunction(std::string const& _literal)\n{\n\tstd::string functionName = \"copy_literal_to_memory_\" + util::toHex(util::keccak256(_literal).asBytes());\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>() -> memPtr {\n\t\t\t\tmemPtr := <arrayAllocationFunction>(<size>)\n\t\t\t\t<storeLiteralInMem>(add(memPtr, 32))\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"arrayAllocationFunction\", allocateMemoryArrayFunction(*TypeProvider::array(DataLocation::Memory, true)))\n\t\t\t(\"size\", std::to_string(_literal.size()))\n\t\t\t(\"storeLiteralInMem\", storeLiteralInMemoryFunction(_literal))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::storeLiteralInMemoryFunction(std::string const& _literal)\n{\n\tstd::string functionName = \"store_literal_in_memory_\" + util::toHex(util::keccak256(_literal).asBytes());\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tsize_t words = (_literal.length() + 31) / 32;\n\t\tstd::vector<std::map<std::string, std::string>> wordParams(words);\n\t\tfor (size_t i = 0; i < words; ++i)\n\t\t{\n\t\t\twordParams[i][\"offset\"] = std::to_string(i * 32);\n\t\t\twordParams[i][\"wordValue\"] = formatAsStringOrNumber(_literal.substr(32 * i, 32));\n\t\t}\n\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(memPtr) {\n\t\t\t\t<#word>\n\t\t\t\t\tmstore(add(memPtr, <offset>), <wordValue>)\n\t\t\t\t</word>\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"word\", wordParams)\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::copyLiteralToStorageFunction(std::string const& _literal)\n{\n\tstd::string functionName = \"copy_literal_to_storage_\" + util::toHex(util::keccak256(_literal).asBytes());\n\n\treturn m_functionCollector.createFunction(functionName, [&](std::vector<std::string>& _args, std::vector<std::string>&) {\n\t\t_args = {\"slot\"};\n\n\t\tif (_literal.size() >= 32)\n\t\t{\n\t\t\tsize_t words = (_literal.length() + 31) / 32;\n\t\t\tstd::vector<std::map<std::string, std::string>> wordParams(words);\n\t\t\tfor (size_t i = 0; i < words; ++i)\n\t\t\t{\n\t\t\t\twordParams[i][\"offset\"] = std::to_string(i);\n\t\t\t\twordParams[i][\"wordValue\"] = formatAsStringOrNumber(_literal.substr(32 * i, 32));\n\t\t\t}\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tlet oldLen := <byteArrayLength>(sload(slot))\n\t\t\t\t<cleanUpArrayEnd>(slot, oldLen, <length>)\n\t\t\t\tsstore(slot, <encodedLen>)\n\t\t\t\tlet dstPtr := <dataArea>(slot)\n\t\t\t\t<#word>\n\t\t\t\t\tsstore(add(dstPtr, <offset>), <wordValue>)\n\t\t\t\t</word>\n\t\t\t)\")\n\t\t\t(\"byteArrayLength\", extractByteArrayLengthFunction())\n\t\t\t(\"cleanUpArrayEnd\", cleanUpDynamicByteArrayEndSlotsFunction(*TypeProvider::bytesStorage()))\n\t\t\t(\"dataArea\", arrayDataAreaFunction(*TypeProvider::bytesStorage()))\n\t\t\t(\"word\", wordParams)\n\t\t\t(\"length\", std::to_string(_literal.size()))\n\t\t\t(\"encodedLen\", std::to_string(2 * _literal.size() + 1))\n\t\t\t.render();\n\t\t}\n\t\telse\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tlet oldLen := <byteArrayLength>(sload(slot))\n\t\t\t\t<cleanUpArrayEnd>(slot, oldLen, <length>)\n\t\t\t\tsstore(slot, add(<wordValue>, <encodedLen>))\n\t\t\t)\")\n\t\t\t(\"byteArrayLength\", extractByteArrayLengthFunction())\n\t\t\t(\"cleanUpArrayEnd\", cleanUpDynamicByteArrayEndSlotsFunction(*TypeProvider::bytesStorage()))\n\t\t\t(\"wordValue\", formatAsStringOrNumber(_literal))\n\t\t\t(\"length\", std::to_string(_literal.size()))\n\t\t\t(\"encodedLen\", std::to_string(2 * _literal.size()))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::revertWithError(\n\tstd::string const& _signature,\n\tstd::vector<Type const*> const& _parameterTypes,\n\tstd::vector<ASTPointer<Expression const>> const& _errorArguments,\n\tstd::string const& _posVar,\n\tstd::string const& _endVar\n)\n{\n\tsolAssert((!_posVar.empty() && !_endVar.empty()) || (_posVar.empty() && _endVar.empty()));\n\tbool const needsNewVariable = !_posVar.empty() && !_endVar.empty();\n\tbool needsAllocation = true;\n\n\tif (std::optional<size_t> size = staticEncodingSize(_parameterTypes))\n\t\tif (\n\t\t\tranges::all_of(_parameterTypes, [](auto const* type) {\n\t\t\t\tsolAssert(!dynamic_cast<InaccessibleDynamicType const*>(type));\n\t\t\t\treturn type && type->isValueType();\n\t\t\t})\n\t\t)\n\t\t{\n\t\t\tconstexpr size_t errorSelectorSize = 4;\n\t\t\tneedsAllocation = *size + errorSelectorSize > CompilerUtils::generalPurposeMemoryStart;\n\t\t}\n\n\tWhiskers templ(R\"({\n\t\t<?needsAllocation>\n\t\tlet <pos> := <allocateUnbounded>()\n\t\t<!needsAllocation>\n\t\tlet <pos> := 0\n\t\t</needsAllocation>\n\t\tmstore(<pos>, <hash>)\n\t\tlet <end> := <encode>(add(<pos>, 4) <argumentVars>)\n\t\trevert(<pos>, sub(<end>, <pos>))\n\t})\");\n\ttempl(\"pos\", needsNewVariable ? _posVar : \"memPtr\");\n\ttempl(\"end\", needsNewVariable ? _endVar : \"end\");\n\ttempl(\"hash\", formatNumber(util::selectorFromSignatureU256(_signature)));\n\ttempl(\"needsAllocation\", needsAllocation);\n\tif (needsAllocation)\n\t\ttempl(\"allocateUnbounded\", allocateUnboundedFunction());\n\n\tstd::vector<std::string> errorArgumentVars;\n\tstd::vector<Type const*> errorArgumentTypes;\n\tfor (ASTPointer<Expression const> const& arg: _errorArguments)\n\t{\n\t\terrorArgumentVars += IRVariable(*arg).stackSlots();\n\t\tsolAssert(arg->annotation().type);\n\t\terrorArgumentTypes.push_back(arg->annotation().type);\n\t}\n\ttempl(\"argumentVars\", joinHumanReadablePrefixed(errorArgumentVars));\n\ttempl(\"encode\", ABIFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector).tupleEncoder(errorArgumentTypes, _parameterTypes));\n\n\treturn templ.render();\n}\n\nstd::string YulUtilFunctions::requireOrAssertFunction(bool _assert, Type const* _messageType, ASTPointer<Expression const> _stringArgumentExpression)\n{\n\tstd::string functionName =\n\t\tstd::string(_assert ? \"assert_helper\" : \"require_helper\") +\n\t\t(_messageType ? (\"_\" + _messageType->identifier()) : \"\");\n\n\tsolAssert(!_assert || !_messageType, \"Asserts can't have messages!\");\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tif (!_messageType)\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(condition) {\n\t\t\t\t\tif iszero(condition) { <error> }\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"error\", _assert ? panicFunction(PanicCode::Assert) + \"()\" : \"revert(0, 0)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t.render();\n\n\t\tsolAssert(_stringArgumentExpression, \"Require with string must have a string argument\");\n\t\tsolAssert(_stringArgumentExpression->annotation().type);\n\t\tstd::vector<std::string> functionParameterNames = IRVariable(*_stringArgumentExpression).stackSlots();\n\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(condition <functionParameterNames>) {\n\t\t\t\tif iszero(condition)\n\t\t\t\t\t<revertWithError>\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"revertWithError\", revertWithError(\"Error(string)\", {TypeProvider::stringMemory()}, {_stringArgumentExpression}))\n\t\t(\"functionParameterNames\", joinHumanReadablePrefixed(functionParameterNames))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::requireWithErrorFunction(FunctionCall const& errorConstructorCall)\n{\n\tErrorDefinition const* errorDefinition = dynamic_cast<ErrorDefinition const*>(ASTNode::referencedDeclaration(errorConstructorCall.expression()));\n\tsolAssert(errorDefinition);\n\n\tstd::string const errorSignature = errorDefinition->functionType(true)->externalSignature();\n\t// Note that in most cases we'll always generate one function per error definition,\n\t// because types in the constructor call will match the ones in the definition. The only\n\t// exception are calls with types, where each instance has its own type (e.g. literals).\n\tstd::string functionName = \"require_helper_t_error_\" + std::to_string(errorDefinition->id()) + \"_\" + errorDefinition->name();\n\tfor (ASTPointer<Expression const> const& argument: errorConstructorCall.sortedArguments())\n\t{\n\t\tsolAssert(argument->annotation().type);\n\t\tfunctionName += (\"_\" + argument->annotation().type->identifier());\n\t}\n\n\tstd::vector<std::string> functionParameterNames;\n\tfor (ASTPointer<Expression const> const& arg: errorConstructorCall.sortedArguments())\n\t{\n\t\tsolAssert(arg->annotation().type);\n\t\tif (arg->annotation().type->sizeOnStack() > 0)\n\t\t\tfunctionParameterNames += IRVariable(*arg).stackSlots();\n\t}\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(condition <functionParameterNames>) {\n\t\t\t\tif iszero(condition)\n\t\t\t\t\t<revertWithError>\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"functionParameterNames\", joinHumanReadablePrefixed(functionParameterNames))\n\t\t// We're creating parameter names from the expressions passed into the constructor call,\n\t\t// which will result in odd names like `expr_29` that would normally be used for locals.\n\t\t// Note that this is the naming expected by `revertWithError()`.\n\t\t(\"revertWithError\", revertWithError(errorSignature, errorDefinition->functionType(true)->parameterTypes(), errorConstructorCall.sortedArguments()))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::leftAlignFunction(Type const& _type)\n{\n\tstd::string functionName = std::string(\"leftAlign_\") + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(value) -> aligned {\n\t\t\t\t<body>\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\tswitch (_type.category())\n\t\t{\n\t\tcase Type::Category::Address:\n\t\t\ttempl(\"body\", \"aligned := \" + leftAlignFunction(IntegerType(160)) + \"(value)\");\n\t\t\tbreak;\n\t\tcase Type::Category::Integer:\n\t\t{\n\t\t\tIntegerType const& type = dynamic_cast<IntegerType const&>(_type);\n\t\t\tif (type.numBits() == 256)\n\t\t\t\ttempl(\"body\", \"aligned := value\");\n\t\t\telse\n\t\t\t\ttempl(\"body\", \"aligned := \" + shiftLeftFunction(256 - type.numBits()) + \"(value)\");\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::RationalNumber:\n\t\t\tsolAssert(false, \"Left align requested for rational number.\");\n\t\t\tbreak;\n\t\tcase Type::Category::Bool:\n\t\t\ttempl(\"body\", \"aligned := \" + leftAlignFunction(IntegerType(8)) + \"(value)\");\n\t\t\tbreak;\n\t\tcase Type::Category::FixedPoint:\n\t\t\tsolUnimplemented(\"Fixed point types not implemented.\");\n\t\t\tbreak;\n\t\tcase Type::Category::Array:\n\t\tcase Type::Category::Struct:\n\t\t\tsolAssert(false, \"Left align requested for non-value type.\");\n\t\t\tbreak;\n\t\tcase Type::Category::FixedBytes:\n\t\t\ttempl(\"body\", \"aligned := value\");\n\t\t\tbreak;\n\t\tcase Type::Category::Contract:\n\t\t\ttempl(\"body\", \"aligned := \" + leftAlignFunction(*TypeProvider::address()) + \"(value)\");\n\t\t\tbreak;\n\t\tcase Type::Category::Enum:\n\t\t{\n\t\t\tsolAssert(dynamic_cast<EnumType const&>(_type).storageBytes() == 1, \"\");\n\t\t\ttempl(\"body\", \"aligned := \" + leftAlignFunction(IntegerType(8)) + \"(value)\");\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::InaccessibleDynamic:\n\t\t\tsolAssert(false, \"Left align requested for inaccessible dynamic type.\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tsolAssert(false, \"Left align of type \" + _type.identifier() + \" requested.\");\n\t\t}\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::shiftLeftFunction(size_t _numBits)\n{\n\tsolAssert(_numBits < 256, \"\");\n\n\tstd::string functionName = \"shift_left_\" + std::to_string(_numBits);\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(value) -> newValue {\n\t\t\t\tnewValue :=\n\t\t\t\t<?hasShifts>\n\t\t\t\t\tshl(<numBits>, value)\n\t\t\t\t<!hasShifts>\n\t\t\t\t\tmul(value, <multiplier>)\n\t\t\t\t</hasShifts>\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"numBits\", std::to_string(_numBits))\n\t\t\t(\"hasShifts\", m_evmVersion.hasBitwiseShifting())\n\t\t\t(\"multiplier\", toCompactHexWithPrefix(u256(1) << _numBits))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::shiftLeftFunctionDynamic()\n{\n\tstd::string functionName = \"shift_left_dynamic\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(bits, value) -> newValue {\n\t\t\t\tnewValue :=\n\t\t\t\t<?hasShifts>\n\t\t\t\t\tshl(bits, value)\n\t\t\t\t<!hasShifts>\n\t\t\t\t\tmul(value, exp(2, bits))\n\t\t\t\t</hasShifts>\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"hasShifts\", m_evmVersion.hasBitwiseShifting())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::shiftRightFunction(size_t _numBits)\n{\n\tsolAssert(_numBits < 256, \"\");\n\n\t// Note that if this is extended with signed shifts,\n\t// the opcodes SAR and SDIV behave differently with regards to rounding!\n\n\tstd::string functionName = \"shift_right_\" + std::to_string(_numBits) + \"_unsigned\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(value) -> newValue {\n\t\t\t\tnewValue :=\n\t\t\t\t<?hasShifts>\n\t\t\t\t\tshr(<numBits>, value)\n\t\t\t\t<!hasShifts>\n\t\t\t\t\tdiv(value, <multiplier>)\n\t\t\t\t</hasShifts>\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"hasShifts\", m_evmVersion.hasBitwiseShifting())\n\t\t\t(\"numBits\", std::to_string(_numBits))\n\t\t\t(\"multiplier\", toCompactHexWithPrefix(u256(1) << _numBits))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::shiftRightFunctionDynamic()\n{\n\tstd::string const functionName = \"shift_right_unsigned_dynamic\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(bits, value) -> newValue {\n\t\t\t\tnewValue :=\n\t\t\t\t<?hasShifts>\n\t\t\t\t\tshr(bits, value)\n\t\t\t\t<!hasShifts>\n\t\t\t\t\tdiv(value, exp(2, bits))\n\t\t\t\t</hasShifts>\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"hasShifts\", m_evmVersion.hasBitwiseShifting())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::shiftRightSignedFunctionDynamic()\n{\n\tstd::string const functionName = \"shift_right_signed_dynamic\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(bits, value) -> result {\n\t\t\t\t<?hasShifts>\n\t\t\t\t\tresult := sar(bits, value)\n\t\t\t\t<!hasShifts>\n\t\t\t\t\tlet divisor := exp(2, bits)\n\t\t\t\t\tlet xor_mask := sub(0, slt(value, 0))\n\t\t\t\t\tresult := xor(div(xor(value, xor_mask), divisor), xor_mask)\n\t\t\t\t\t// combined version of\n\t\t\t\t\t//   switch slt(value, 0)\n\t\t\t\t\t//   case 0 { result := div(value, divisor) }\n\t\t\t\t\t//   default { result := not(div(not(value), divisor)) }\n\t\t\t\t</hasShifts>\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"hasShifts\", m_evmVersion.hasBitwiseShifting())\n\t\t\t.render();\n\t});\n}\n\n\nstd::string YulUtilFunctions::typedShiftLeftFunction(Type const& _type, Type const& _amountType)\n{\n\tsolUnimplementedAssert(_type.category() != Type::Category::FixedPoint, \"Not yet implemented - FixedPointType.\");\n\tsolAssert(_type.category() == Type::Category::FixedBytes || _type.category() == Type::Category::Integer, \"\");\n\tsolAssert(_amountType.category() == Type::Category::Integer, \"\");\n\tsolAssert(!dynamic_cast<IntegerType const&>(_amountType).isSigned(), \"\");\n\tstd::string const functionName = \"shift_left_\" + _type.identifier() + \"_\" + _amountType.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(value, bits) -> result {\n\t\t\t\tbits := <cleanAmount>(bits)\n\t\t\t\tresult := <cleanup>(<shift>(bits, <cleanup>(value)))\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"cleanAmount\", cleanupFunction(_amountType))\n\t\t\t(\"shift\", shiftLeftFunctionDynamic())\n\t\t\t(\"cleanup\", cleanupFunction(_type))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::typedShiftRightFunction(Type const& _type, Type const& _amountType)\n{\n\tsolUnimplementedAssert(_type.category() != Type::Category::FixedPoint, \"Not yet implemented - FixedPointType.\");\n\tsolAssert(_type.category() == Type::Category::FixedBytes || _type.category() == Type::Category::Integer, \"\");\n\tsolAssert(_amountType.category() == Type::Category::Integer, \"\");\n\tsolAssert(!dynamic_cast<IntegerType const&>(_amountType).isSigned(), \"\");\n\tIntegerType const* integerType = dynamic_cast<IntegerType const*>(&_type);\n\tbool valueSigned = integerType && integerType->isSigned();\n\n\tstd::string const functionName = \"shift_right_\" + _type.identifier() + \"_\" + _amountType.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(value, bits) -> result {\n\t\t\t\tbits := <cleanAmount>(bits)\n\t\t\t\tresult := <cleanup>(<shift>(bits, <cleanup>(value)))\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"cleanAmount\", cleanupFunction(_amountType))\n\t\t\t(\"shift\", valueSigned ? shiftRightSignedFunctionDynamic() : shiftRightFunctionDynamic())\n\t\t\t(\"cleanup\", cleanupFunction(_type))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::updateByteSliceFunction(size_t _numBytes, size_t _shiftBytes)\n{\n\tsolAssert(_numBytes <= 32, \"\");\n\tsolAssert(_shiftBytes <= 32, \"\");\n\tsize_t numBits = _numBytes * 8;\n\tsize_t shiftBits = _shiftBytes * 8;\n\tstd::string functionName = \"update_byte_slice_\" + std::to_string(_numBytes) + \"_shift_\" + std::to_string(_shiftBytes);\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(value, toInsert) -> result {\n\t\t\t\tlet mask := <mask>\n\t\t\t\ttoInsert := <shl>(toInsert)\n\t\t\t\tvalue := and(value, not(mask))\n\t\t\t\tresult := or(value, and(toInsert, mask))\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"mask\", formatNumber(((bigint(1) << numBits) - 1) << shiftBits))\n\t\t\t(\"shl\", shiftLeftFunction(shiftBits))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::updateByteSliceFunctionDynamic(size_t _numBytes)\n{\n\tsolAssert(_numBytes <= 32, \"\");\n\tsize_t numBits = _numBytes * 8;\n\tstd::string functionName = \"update_byte_slice_dynamic\" + std::to_string(_numBytes);\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(value, shiftBytes, toInsert) -> result {\n\t\t\t\tlet shiftBits := mul(shiftBytes, 8)\n\t\t\t\tlet mask := <shl>(shiftBits, <mask>)\n\t\t\t\ttoInsert := <shl>(shiftBits, toInsert)\n\t\t\t\tvalue := and(value, not(mask))\n\t\t\t\tresult := or(value, and(toInsert, mask))\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"mask\", formatNumber((bigint(1) << numBits) - 1))\n\t\t\t(\"shl\", shiftLeftFunctionDynamic())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::maskBytesFunctionDynamic()\n{\n\tstd::string functionName = \"mask_bytes_dynamic\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(data, bytes) -> result {\n\t\t\t\tlet mask := not(<shr>(mul(8, bytes), not(0)))\n\t\t\t\tresult := and(data, mask)\n\t\t\t})\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"shr\", shiftRightFunctionDynamic())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::maskLowerOrderBytesFunction(size_t _bytes)\n{\n\tstd::string functionName = \"mask_lower_order_bytes_\" + std::to_string(_bytes);\n\tsolAssert(_bytes <= 32, \"\");\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(data) -> result {\n\t\t\t\tresult := and(data, <mask>)\n\t\t\t})\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"mask\", formatNumber((~u256(0)) >> (256 - 8 * _bytes)))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::maskLowerOrderBytesFunctionDynamic()\n{\n\tstd::string functionName = \"mask_lower_order_bytes_dynamic\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(data, bytes) -> result {\n\t\t\t\tlet mask := not(<shl>(mul(8, bytes), not(0)))\n\t\t\t\tresult := and(data, mask)\n\t\t\t})\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"shl\", shiftLeftFunctionDynamic())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::roundUpFunction()\n{\n\tstd::string functionName = \"round_up_to_mul_of_32\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(value) -> result {\n\t\t\t\tresult := and(add(value, 31), not(31))\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::divide32CeilFunction()\n{\n\treturn m_functionCollector.createFunction(\n\t\t\"divide_by_32_ceil\",\n\t\t[&](std::vector<std::string>& _args, std::vector<std::string>& _ret) {\n\t\t\t_args = {\"value\"};\n\t\t\t_ret = {\"result\"};\n\t\t\treturn \"result := div(add(value, 31), 32)\";\n\t\t}\n\t);\n}\n\nstd::string YulUtilFunctions::overflowCheckedIntAddFunction(IntegerType const& _type)\n{\n\tstd::string functionName = \"checked_add_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(x, y) -> sum {\n\t\t\t\tx := <cleanupFunction>(x)\n\t\t\t\ty := <cleanupFunction>(y)\n\t\t\t\tsum := add(x, y)\n\t\t\t\t<?signed>\n\t\t\t\t\t<?256bit>\n\t\t\t\t\t\t// overflow, if x >= 0 and sum < y\n\t\t\t\t\t\t// underflow, if x < 0 and sum >= y\n\t\t\t\t\t\tif or(\n\t\t\t\t\t\t\tand(iszero(slt(x, 0)), slt(sum, y)),\n\t\t\t\t\t\t\tand(slt(x, 0), iszero(slt(sum, y)))\n\t\t\t\t\t\t) { <panic>() }\n\t\t\t\t\t<!256bit>\n\t\t\t\t\t\tif or(\n\t\t\t\t\t\t\tsgt(sum, <maxValue>),\n\t\t\t\t\t\t\tslt(sum, <minValue>)\n\t\t\t\t\t\t) { <panic>() }\n\t\t\t\t\t</256bit>\n\t\t\t\t<!signed>\n\t\t\t\t\t<?256bit>\n\t\t\t\t\t\tif gt(x, sum) { <panic>() }\n\t\t\t\t\t<!256bit>\n\t\t\t\t\t\tif gt(sum, <maxValue>) { <panic>() }\n\t\t\t\t\t</256bit>\n\t\t\t\t</signed>\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"signed\", _type.isSigned())\n\t\t\t(\"maxValue\", toCompactHexWithPrefix(u256(_type.maxValue())))\n\t\t\t(\"minValue\", toCompactHexWithPrefix(u256(_type.minValue())))\n\t\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t\t(\"panic\", panicFunction(PanicCode::UnderOverflow))\n\t\t\t(\"256bit\", _type.numBits() == 256)\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::wrappingIntAddFunction(IntegerType const& _type)\n{\n\tstd::string functionName = \"wrapping_add_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(x, y) -> sum {\n\t\t\t\tsum := <cleanupFunction>(add(x, y))\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::overflowCheckedIntMulFunction(IntegerType const& _type)\n{\n\tstd::string functionName = \"checked_mul_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\t// Multiplication by zero could be treated separately and directly return zero.\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(x, y) -> product {\n\t\t\t\tx := <cleanupFunction>(x)\n\t\t\t\ty := <cleanupFunction>(y)\n\t\t\t\tlet product_raw := mul(x, y)\n\t\t\t\tproduct := <cleanupFunction>(product_raw)\n\t\t\t\t<?signed>\n\t\t\t\t\t<?gt128bit>\n\t\t\t\t\t\t<?256bit>\n\t\t\t\t\t\t\t// special case\n\t\t\t\t\t\t\tif and(slt(x, 0), eq(y, <minValue>)) { <panic>() }\n\t\t\t\t\t\t</256bit>\n\t\t\t\t\t\t// overflow, if x != 0 and y != product/x\n\t\t\t\t\t\tif iszero(\n\t\t\t\t\t\t\tor(\n\t\t\t\t\t\t\t\tiszero(x),\n\t\t\t\t\t\t\t\teq(y, sdiv(product, x))\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) { <panic>() }\n\t\t\t\t\t<!gt128bit>\n\t\t\t\t\t\tif iszero(eq(product, product_raw)) { <panic>() }\n\t\t\t\t\t</gt128bit>\n\t\t\t\t<!signed>\n\t\t\t\t\t<?gt128bit>\n\t\t\t\t\t\t// overflow, if x != 0 and y != product/x\n\t\t\t\t\t\tif iszero(\n\t\t\t\t\t\t\tor(\n\t\t\t\t\t\t\t\tiszero(x),\n\t\t\t\t\t\t\t\teq(y, div(product, x))\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) { <panic>() }\n\t\t\t\t\t<!gt128bit>\n\t\t\t\t\t\tif iszero(eq(product, product_raw)) { <panic>() }\n\t\t\t\t\t</gt128bit>\n\t\t\t\t</signed>\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"signed\", _type.isSigned())\n\t\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t\t(\"panic\", panicFunction(PanicCode::UnderOverflow))\n\t\t\t(\"minValue\", toCompactHexWithPrefix(u256(_type.minValue())))\n\t\t\t(\"256bit\", _type.numBits() == 256)\n\t\t\t(\"gt128bit\", _type.numBits() > 128)\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::wrappingIntMulFunction(IntegerType const& _type)\n{\n\tstd::string functionName = \"wrapping_mul_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(x, y) -> product {\n\t\t\t\tproduct := <cleanupFunction>(mul(x, y))\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::overflowCheckedIntDivFunction(IntegerType const& _type)\n{\n\tstd::string functionName = \"checked_div_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(x, y) -> r {\n\t\t\t\tx := <cleanupFunction>(x)\n\t\t\t\ty := <cleanupFunction>(y)\n\t\t\t\tif iszero(y) { <panicDivZero>() }\n\t\t\t\t<?signed>\n\t\t\t\t// overflow for minVal / -1\n\t\t\t\tif and(\n\t\t\t\t\teq(x, <minVal>),\n\t\t\t\t\teq(y, sub(0, 1))\n\t\t\t\t) { <panicOverflow>() }\n\t\t\t\t</signed>\n\t\t\t\tr := <?signed>s</signed>div(x, y)\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"signed\", _type.isSigned())\n\t\t\t(\"minVal\", toCompactHexWithPrefix(u256(_type.minValue())))\n\t\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t\t(\"panicDivZero\", panicFunction(PanicCode::DivisionByZero))\n\t\t\t(\"panicOverflow\", panicFunction(PanicCode::UnderOverflow))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::wrappingIntDivFunction(IntegerType const& _type)\n{\n\tstd::string functionName = \"wrapping_div_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(x, y) -> r {\n\t\t\t\tx := <cleanupFunction>(x)\n\t\t\t\ty := <cleanupFunction>(y)\n\t\t\t\tif iszero(y) { <error>() }\n\t\t\t\tr := <?signed>s</signed>div(x, y)\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t\t(\"signed\", _type.isSigned())\n\t\t\t(\"error\", panicFunction(PanicCode::DivisionByZero))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::intModFunction(IntegerType const& _type)\n{\n\tstd::string functionName = \"mod_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(x, y) -> r {\n\t\t\t\tx := <cleanupFunction>(x)\n\t\t\t\ty := <cleanupFunction>(y)\n\t\t\t\tif iszero(y) { <panic>() }\n\t\t\t\tr := <?signed>s</signed>mod(x, y)\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"signed\", _type.isSigned())\n\t\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t\t(\"panic\", panicFunction(PanicCode::DivisionByZero))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::overflowCheckedIntSubFunction(IntegerType const& _type)\n{\n\tstd::string functionName = \"checked_sub_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(x, y) -> diff {\n\t\t\t\tx := <cleanupFunction>(x)\n\t\t\t\ty := <cleanupFunction>(y)\n\t\t\t\tdiff := sub(x, y)\n\t\t\t\t<?signed>\n\t\t\t\t\t<?256bit>\n\t\t\t\t\t\t// underflow, if y >= 0 and diff > x\n\t\t\t\t\t\t// overflow, if y < 0 and diff < x\n\t\t\t\t\t\tif or(\n\t\t\t\t\t\t\tand(iszero(slt(y, 0)), sgt(diff, x)),\n\t\t\t\t\t\t\tand(slt(y, 0), slt(diff, x))\n\t\t\t\t\t\t) { <panic>() }\n\t\t\t\t\t<!256bit>\n\t\t\t\t\t\tif or(\n\t\t\t\t\t\t\tslt(diff, <minValue>),\n\t\t\t\t\t\t\tsgt(diff, <maxValue>)\n\t\t\t\t\t\t) { <panic>() }\n\t\t\t\t\t</256bit>\n\t\t\t\t<!signed>\n\t\t\t\t\t<?256bit>\n\t\t\t\t\t\tif gt(diff, x) { <panic>() }\n\t\t\t\t\t<!256bit>\n\t\t\t\t\t\tif gt(diff, <maxValue>) { <panic>() }\n\t\t\t\t\t</256bit>\n\t\t\t\t</signed>\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"signed\", _type.isSigned())\n\t\t\t(\"maxValue\", toCompactHexWithPrefix(u256(_type.maxValue())))\n\t\t\t(\"minValue\", toCompactHexWithPrefix(u256(_type.minValue())))\n\t\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t\t(\"panic\", panicFunction(PanicCode::UnderOverflow))\n\t\t\t(\"256bit\", _type.numBits() == 256)\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::wrappingIntSubFunction(IntegerType const& _type)\n{\n\tstd::string functionName = \"wrapping_sub_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(x, y) -> diff {\n\t\t\t\tdiff := <cleanupFunction>(sub(x, y))\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::overflowCheckedIntExpFunction(\n\tIntegerType const& _type,\n\tIntegerType const& _exponentType\n)\n{\n\tsolAssert(!_exponentType.isSigned(), \"\");\n\n\tstd::string functionName = \"checked_exp_\" + _type.identifier() + \"_\" + _exponentType.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(base, exponent) -> power {\n\t\t\t\tbase := <baseCleanupFunction>(base)\n\t\t\t\texponent := <exponentCleanupFunction>(exponent)\n\t\t\t\t<?signed>\n\t\t\t\t\tpower := <exp>(base, exponent, <minValue>, <maxValue>)\n\t\t\t\t<!signed>\n\t\t\t\t\tpower := <exp>(base, exponent, <maxValue>)\n\t\t\t\t</signed>\n\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"signed\", _type.isSigned())\n\t\t\t(\"exp\", _type.isSigned() ? overflowCheckedSignedExpFunction() : overflowCheckedUnsignedExpFunction())\n\t\t\t(\"maxValue\", toCompactHexWithPrefix(_type.max()))\n\t\t\t(\"minValue\", toCompactHexWithPrefix(_type.min()))\n\t\t\t(\"baseCleanupFunction\", cleanupFunction(_type))\n\t\t\t(\"exponentCleanupFunction\", cleanupFunction(_exponentType))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::overflowCheckedIntLiteralExpFunction(\n\tRationalNumberType const& _baseType,\n\tIntegerType const& _exponentType,\n\tIntegerType const& _commonType\n)\n{\n\tsolAssert(!_exponentType.isSigned(), \"\");\n\tsolAssert(_baseType.isNegative() == _commonType.isSigned(), \"\");\n\tsolAssert(_commonType.numBits() == 256, \"\");\n\n\tstd::string functionName = \"checked_exp_\" + _baseType.richIdentifier() + \"_\" + _exponentType.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&]()\n\t{\n\t\t// Converts a bigint number into u256 (negative numbers represented in two's complement form.)\n\t\t// We assume that `_v` fits in 256 bits.\n\t\tauto bigint2u = [&](bigint const& _v) -> u256\n\t\t{\n\t\t\tif (_v < 0)\n\t\t\t\treturn s2u(s256(_v));\n\t\t\treturn u256(_v);\n\t\t};\n\n\t\t// Calculates the upperbound for exponentiation, that is, calculate `b`, such that\n\t\t// _base**b <= _maxValue and _base**(b + 1) > _maxValue\n\t\tauto findExponentUpperbound = [](bigint const _base, bigint const _maxValue) -> unsigned\n\t\t{\n\t\t\t// There is no overflow for these cases\n\t\t\tif (_base == 0 || _base == -1 || _base == 1)\n\t\t\t\treturn 0;\n\n\t\t\tunsigned first = 0;\n\t\t\tunsigned last = 255;\n\t\t\tunsigned middle;\n\n\t\t\twhile (first < last)\n\t\t\t{\n\t\t\t\tmiddle = (first + last) / 2;\n\n\t\t\t\tif (\n\t\t\t\t\t// The condition on msb is a shortcut that avoids computing large powers in\n\t\t\t\t\t// arbitrary precision.\n\t\t\t\t\tboost::multiprecision::msb(_base) * middle <= boost::multiprecision::msb(_maxValue) &&\n\t\t\t\t\tboost::multiprecision::pow(_base, middle) <= _maxValue\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tif (boost::multiprecision::pow(_base, middle + 1) > _maxValue)\n\t\t\t\t\t\treturn middle;\n\t\t\t\t\telse\n\t\t\t\t\t\tfirst = middle + 1;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tlast = middle;\n\t\t\t}\n\n\t\t\treturn last;\n\t\t};\n\n\t\tbigint baseValue = _baseType.isNegative() ?\n\t\t\tu2s(_baseType.literalValue(nullptr)) :\n\t\t\t_baseType.literalValue(nullptr);\n\t\tbool needsOverflowCheck = !((baseValue == 0) || (baseValue == -1) || (baseValue == 1));\n\t\tunsigned exponentUpperbound;\n\n\t\tif (_baseType.isNegative())\n\t\t{\n\t\t\t// Only checks for underflow. The only case where this can be a problem is when, for a\n\t\t\t// negative base, say `b`, and an even exponent, say `e`, `b**e = 2**255` (which is an\n\t\t\t// overflow.) But this never happens because, `255 = 3*5*17`, and therefore there is no even\n\t\t\t// number `e` such that `b**e = 2**255`.\n\t\t\texponentUpperbound = findExponentUpperbound(abs(baseValue), abs(_commonType.minValue()));\n\n\t\t\tbigint power = boost::multiprecision::pow(baseValue, exponentUpperbound);\n\t\t\tbigint overflowedPower = boost::multiprecision::pow(baseValue, exponentUpperbound + 1);\n\n\t\t\tif (needsOverflowCheck)\n\t\t\t\tsolAssert(\n\t\t\t\t\t(power <= _commonType.maxValue()) && (power >= _commonType.minValue()) &&\n\t\t\t\t\t!((overflowedPower <= _commonType.maxValue()) && (overflowedPower >= _commonType.minValue())),\n\t\t\t\t\t\"Incorrect exponent upper bound calculated.\"\n\t\t\t\t);\n\t\t}\n\t\telse\n\t\t{\n\t\t\texponentUpperbound = findExponentUpperbound(baseValue, _commonType.maxValue());\n\n\t\t\tif (needsOverflowCheck)\n\t\t\t\tsolAssert(\n\t\t\t\t\tboost::multiprecision::pow(baseValue, exponentUpperbound) <= _commonType.maxValue() &&\n\t\t\t\t\tboost::multiprecision::pow(baseValue, exponentUpperbound + 1) > _commonType.maxValue(),\n\t\t\t\t\t\"Incorrect exponent upper bound calculated.\"\n\t\t\t\t);\n\t\t}\n\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(exponent) -> power {\n\t\t\t\texponent := <exponentCleanupFunction>(exponent)\n\t\t\t\t<?needsOverflowCheck>\n\t\t\t\tif gt(exponent, <exponentUpperbound>) { <panic>() }\n\t\t\t\t</needsOverflowCheck>\n\t\t\t\tpower := exp(<base>, exponent)\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"exponentCleanupFunction\", cleanupFunction(_exponentType))\n\t\t\t(\"needsOverflowCheck\", needsOverflowCheck)\n\t\t\t(\"exponentUpperbound\", std::to_string(exponentUpperbound))\n\t\t\t(\"panic\", panicFunction(PanicCode::UnderOverflow))\n\t\t\t(\"base\", bigint2u(baseValue).str())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::overflowCheckedUnsignedExpFunction()\n{\n\t// Checks for the \"small number specialization\" below.\n\tusing namespace boost::multiprecision;\n\tsolAssert(pow(bigint(10), 77) < pow(bigint(2), 256), \"\");\n\tsolAssert(pow(bigint(11), 77) >= pow(bigint(2), 256), \"\");\n\tsolAssert(pow(bigint(10), 78) >= pow(bigint(2), 256), \"\");\n\n\tsolAssert(pow(bigint(306), 31) < pow(bigint(2), 256), \"\");\n\tsolAssert(pow(bigint(307), 31) >= pow(bigint(2), 256), \"\");\n\tsolAssert(pow(bigint(306), 32) >= pow(bigint(2), 256), \"\");\n\n\tstd::string functionName = \"checked_exp_unsigned\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(base, exponent, max) -> power {\n\t\t\t\t// This function currently cannot be inlined because of the\n\t\t\t\t// \"leave\" statements. We have to improve the optimizer.\n\n\t\t\t\t// Note that 0**0 == 1\n\t\t\t\tif iszero(exponent) { power := 1 leave }\n\t\t\t\tif iszero(base) { power := 0 leave }\n\n\t\t\t\t// Specializations for small bases\n\t\t\t\tswitch base\n\t\t\t\t// 0 is handled above\n\t\t\t\tcase 1 { power := 1 leave }\n\t\t\t\tcase 2\n\t\t\t\t{\n\t\t\t\t\tif gt(exponent, 255) { <panic>() }\n\t\t\t\t\tpower := exp(2, exponent)\n\t\t\t\t\tif gt(power, max) { <panic>() }\n\t\t\t\t\tleave\n\t\t\t\t}\n\t\t\t\tif or(\n\t\t\t\t\tand(lt(base, 11), lt(exponent, 78)),\n\t\t\t\t\tand(lt(base, 307), lt(exponent, 32))\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tpower := exp(base, exponent)\n\t\t\t\t\tif gt(power, max) { <panic>() }\n\t\t\t\t\tleave\n\t\t\t\t}\n\n\t\t\t\tpower, base := <expLoop>(1, base, exponent, max)\n\n\t\t\t\tif gt(power, div(max, base)) { <panic>() }\n\t\t\t\tpower := mul(power, base)\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"panic\", panicFunction(PanicCode::UnderOverflow))\n\t\t\t(\"expLoop\", overflowCheckedExpLoopFunction())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::overflowCheckedSignedExpFunction()\n{\n\tstd::string functionName = \"checked_exp_signed\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(base, exponent, min, max) -> power {\n\t\t\t\t// Currently, `leave` avoids this function being inlined.\n\t\t\t\t// We have to improve the optimizer.\n\n\t\t\t\t// Note that 0**0 == 1\n\t\t\t\tswitch exponent\n\t\t\t\tcase 0 { power := 1 leave }\n\t\t\t\tcase 1 { power := base leave }\n\t\t\t\tif iszero(base) { power := 0 leave }\n\n\t\t\t\tpower := 1\n\n\t\t\t\t// We pull out the first iteration because it is the only one in which\n\t\t\t\t// base can be negative.\n\t\t\t\t// Exponent is at least 2 here.\n\n\t\t\t\t// overflow check for base * base\n\t\t\t\tswitch sgt(base, 0)\n\t\t\t\tcase 1 { if gt(base, div(max, base)) { <panic>() } }\n\t\t\t\tcase 0 { if slt(base, sdiv(max, base)) { <panic>() } }\n\t\t\t\tif and(exponent, 1)\n\t\t\t\t{\n\t\t\t\t\tpower := base\n\t\t\t\t}\n\t\t\t\tbase := mul(base, base)\n\t\t\t\texponent := <shr_1>(exponent)\n\n\t\t\t\t// Below this point, base is always positive.\n\n\t\t\t\tpower, base := <expLoop>(power, base, exponent, max)\n\n\t\t\t\tif and(sgt(power, 0), gt(power, div(max, base))) { <panic>() }\n\t\t\t\tif and(slt(power, 0), slt(power, sdiv(min, base))) { <panic>() }\n\t\t\t\tpower := mul(power, base)\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"panic\", panicFunction(PanicCode::UnderOverflow))\n\t\t\t(\"expLoop\", overflowCheckedExpLoopFunction())\n\t\t\t(\"shr_1\", shiftRightFunction(1))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::overflowCheckedExpLoopFunction()\n{\n\t// We use this loop for both signed and unsigned exponentiation\n\t// because we pull out the first iteration in the signed case which\n\t// results in the base always being positive.\n\n\t// This function does not include the final multiplication.\n\n\tstd::string functionName = \"checked_exp_helper\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(_power, _base, exponent, max) -> power, base {\n\t\t\t\tpower := _power\n\t\t\t\tbase  := _base\n\t\t\t\tfor { } gt(exponent, 1) {}\n\t\t\t\t{\n\t\t\t\t\t// overflow check for base * base\n\t\t\t\t\tif gt(base, div(max, base)) { <panic>() }\n\t\t\t\t\tif and(exponent, 1)\n\t\t\t\t\t{\n\t\t\t\t\t\t// No checks for power := mul(power, base) needed, because the check\n\t\t\t\t\t\t// for base * base above is sufficient, since:\n\t\t\t\t\t\t// |power| <= base (proof by induction) and thus:\n\t\t\t\t\t\t// |power * base| <= base * base <= max <= |min| (for signed)\n\t\t\t\t\t\t// (this is equally true for signed and unsigned exp)\n\t\t\t\t\t\tpower := mul(power, base)\n\t\t\t\t\t}\n\t\t\t\t\tbase := mul(base, base)\n\t\t\t\t\texponent := <shr_1>(exponent)\n\t\t\t\t}\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"panic\", panicFunction(PanicCode::UnderOverflow))\n\t\t\t(\"shr_1\", shiftRightFunction(1))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::wrappingIntExpFunction(\n\tIntegerType const& _type,\n\tIntegerType const& _exponentType\n)\n{\n\tsolAssert(!_exponentType.isSigned(), \"\");\n\n\tstd::string functionName = \"wrapping_exp_\" + _type.identifier() + \"_\" + _exponentType.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn\n\t\t\tWhiskers(R\"(\n\t\t\tfunction <functionName>(base, exponent) -> power {\n\t\t\t\tbase := <baseCleanupFunction>(base)\n\t\t\t\texponent := <exponentCleanupFunction>(exponent)\n\t\t\t\tpower := <baseCleanupFunction>(exp(base, exponent))\n\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"baseCleanupFunction\", cleanupFunction(_type))\n\t\t\t(\"exponentCleanupFunction\", cleanupFunction(_exponentType))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::erc7201()\n{\n\tstd::string functionName = \"erc7201\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction erc7201(namespaceIDDataPtr, namespaceIDLength) -> slot {\n\t\t\t\tlet innerKeccak := keccak256(namespaceIDDataPtr, namespaceIDLength)\n\t\t\t\tmstore(0, sub(innerKeccak, 1))\n\t\t\t\t// slot = keccak256(keccak256(id) - 1) & ~0xff\n\t\t\t\tslot := and(keccak256(0, 32), not(0xff))\n\t\t\t}\n\t\t)\");\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::arrayLengthFunction(ArrayType const& _type)\n{\n\tstd::string functionName = \"array_length_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers w(R\"(\n\t\t\tfunction <functionName>(value<?dynamic><?calldata>, len</calldata></dynamic>) -> length {\n\t\t\t\t<?dynamic>\n\t\t\t\t\t<?memory>\n\t\t\t\t\t\tlength := mload(value)\n\t\t\t\t\t</memory>\n\t\t\t\t\t<?storage>\n\t\t\t\t\t\tlength := sload(value)\n\t\t\t\t\t\t<?byteArray>\n\t\t\t\t\t\t\tlength := <extractByteArrayLength>(length)\n\t\t\t\t\t\t</byteArray>\n\t\t\t\t\t</storage>\n\t\t\t\t\t<?calldata>\n\t\t\t\t\t\tlength := len\n\t\t\t\t\t</calldata>\n\t\t\t\t<!dynamic>\n\t\t\t\t\tlength := <length>\n\t\t\t\t</dynamic>\n\t\t\t}\n\t\t)\");\n\t\tw(\"functionName\", functionName);\n\t\tw(\"dynamic\", _type.isDynamicallySized());\n\t\tif (!_type.isDynamicallySized())\n\t\t\tw(\"length\", toCompactHexWithPrefix(_type.length()));\n\t\tw(\"memory\", _type.location() == DataLocation::Memory);\n\t\tw(\"storage\", _type.location() == DataLocation::Storage);\n\t\tw(\"calldata\", _type.location() == DataLocation::CallData);\n\t\tif (_type.location() == DataLocation::Storage)\n\t\t{\n\t\t\tw(\"byteArray\", _type.isByteArrayOrString());\n\t\t\tif (_type.isByteArrayOrString())\n\t\t\t\tw(\"extractByteArrayLength\", extractByteArrayLengthFunction());\n\t\t}\n\n\t\treturn w.render();\n\t});\n}\n\nstd::string YulUtilFunctions::extractByteArrayLengthFunction()\n{\n\tstd::string functionName = \"extract_byte_array_length\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers w(R\"(\n\t\t\tfunction <functionName>(data) -> length {\n\t\t\t\tlength := div(data, 2)\n\t\t\t\tlet outOfPlaceEncoding := and(data, 1)\n\t\t\t\tif iszero(outOfPlaceEncoding) {\n\t\t\t\t\tlength := and(length, 0x7f)\n\t\t\t\t}\n\n\t\t\t\tif eq(outOfPlaceEncoding, lt(length, 32)) {\n\t\t\t\t\t<panic>()\n\t\t\t\t}\n\t\t\t}\n\t\t)\");\n\t\tw(\"functionName\", functionName);\n\t\tw(\"panic\", panicFunction(PanicCode::StorageEncodingError));\n\t\treturn w.render();\n\t});\n}\n\nstd::string YulUtilFunctions::resizeArrayFunction(ArrayType const& _type)\n{\n\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\tsolUnimplementedAssert(_type.baseType()->storageBytes() <= 32);\n\n\tif (_type.isByteArrayOrString())\n\t\treturn resizeDynamicByteArrayFunction(_type);\n\n\tstd::string functionName = \"resize_array_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(array, newLen) {\n\t\t\t\tif gt(newLen, <maxArrayLength>) {\n\t\t\t\t\t<panic>()\n\t\t\t\t}\n\n\t\t\t\tlet oldLen := <fetchLength>(array)\n\n\t\t\t\t<?isDynamic>\n\t\t\t\t\t// Store new length\n\t\t\t\t\tsstore(array, newLen)\n\t\t\t\t</isDynamic>\n\n\t\t\t\t<?needsClearing>\n\t\t\t\t\t<cleanUpArrayEnd>(array, oldLen, newLen)\n\t\t\t\t</needsClearing>\n\t\t\t})\");\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\ttempl(\"maxArrayLength\", (u256(1) << 64).str());\n\t\t\ttempl(\"panic\", panicFunction(util::PanicCode::ResourceError));\n\t\t\ttempl(\"fetchLength\", arrayLengthFunction(_type));\n\t\t\ttempl(\"isDynamic\", _type.isDynamicallySized());\n\t\t\tbool isMappingBase = _type.baseType()->category() == Type::Category::Mapping;\n\t\t\ttempl(\"needsClearing\", !isMappingBase);\n\t\t\tif (!isMappingBase)\n\t\t\t\ttempl(\"cleanUpArrayEnd\", cleanUpStorageArrayEndFunction(_type));\n\t\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::cleanUpStorageArrayEndFunction(ArrayType const& _type)\n{\n\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\tsolAssert(_type.baseType()->category() != Type::Category::Mapping, \"\");\n\tsolAssert(!_type.isByteArrayOrString(), \"\");\n\tsolUnimplementedAssert(_type.baseType()->storageBytes() <= 32);\n\n\tstd::string functionName = \"cleanup_storage_array_end_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&](std::vector<std::string>& _args, std::vector<std::string>&) {\n\t\t_args = {\"array\", \"len\", \"startIndex\"};\n\t\treturn Whiskers(R\"(\n\t\t\tif lt(startIndex, len) {\n\t\t\t\t// Size was reduced, clear end of array\n\t\t\t\tlet oldSlotCount := <convertToSize>(len)\n\t\t\t\tlet newSlotCount := <convertToSize>(startIndex)\n\t\t\t\tlet arrayDataStart := <dataPosition>(array)\n\t\t\t\tlet deleteStart := add(arrayDataStart, newSlotCount)\n\t\t\t\t<?packed>\n\t\t\t\t\t// if we are dealing with packed array and offset is greater than zero\n\t\t\t\t\t// we have  to partially clear last slot that is still used, so decreasing start by one\n\t\t\t\t\tlet offset := mul(mod(startIndex, <itemsPerSlot>), <storageBytes>)\n\t\t\t\t\tif gt(offset, 0) { <partialClearStorageSlot>(sub(deleteStart, 1), offset) }\n\t\t\t\t</packed>\n\t\t\t\t<clearStorageRange>(deleteStart, sub(oldSlotCount, newSlotCount))\n\t\t\t}\n\t\t)\")\n\t\t(\"convertToSize\", arrayConvertLengthToSize(_type))\n\t\t(\"dataPosition\", arrayDataAreaFunction(_type))\n\t\t(\"clearStorageRange\", clearStorageRangeFunction(*_type.baseType()))\n\t\t(\"packed\", _type.baseType()->storageBytes() <= 16)\n\t\t(\"itemsPerSlot\", std::to_string(32 / _type.baseType()->storageBytes()))\n\t\t(\"storageBytes\", std::to_string(_type.baseType()->storageBytes()))\n\t\t(\"partialClearStorageSlot\", partialClearStorageSlotFunction())\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::resizeDynamicByteArrayFunction(ArrayType const& _type)\n{\n\tstd::string functionName = \"resize_array_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&](std::vector<std::string>& _args, std::vector<std::string>&) {\n\t\t_args = {\"array\", \"newLen\"};\n\t\treturn Whiskers(R\"(\n\t\t\tlet data := sload(array)\n\t\t\tlet oldLen := <extractLength>(data)\n\n\t\t\tif gt(newLen, oldLen) {\n\t\t\t\t<increaseSize>(array, data, oldLen, newLen)\n\t\t\t}\n\n\t\t\tif lt(newLen, oldLen) {\n\t\t\t\t<decreaseSize>(array, data, oldLen, newLen)\n\t\t\t}\n\t\t)\")\n\t\t(\"extractLength\", extractByteArrayLengthFunction())\n\t\t(\"decreaseSize\", decreaseByteArraySizeFunction(_type))\n\t\t(\"increaseSize\", increaseByteArraySizeFunction(_type))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::cleanUpDynamicByteArrayEndSlotsFunction(ArrayType const& _type)\n{\n\tsolAssert(_type.isByteArrayOrString(), \"\");\n\tsolAssert(_type.isDynamicallySized(), \"\");\n\n\tstd::string functionName = \"clean_up_bytearray_end_slots_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&](std::vector<std::string>& _args, std::vector<std::string>&) {\n\t\t_args = {\"array\", \"len\", \"startIndex\"};\n\t\treturn Whiskers(R\"(\n\t\t\tif gt(len, 31) {\n\t\t\t\tif gt(len, startIndex) {\n\t\t\t\t\tlet dataArea := <dataLocation>(array)\n\t\t\t\t\tlet oldSlotCount := <div32Ceil>(len)\n\t\t\t\t\tlet newSlotCount := <div32Ceil>(startIndex)\n\t\t\t\t\t// If we are clearing array to be short byte array, we want to clear only data starting from array data area.\n\t\t\t\t\tif lt(startIndex, 32) {\n\t\t\t\t\t\tnewSlotCount := 0\n\t\t\t\t\t}\n\t\t\t\t\tlet deleteStart := add(dataArea, newSlotCount)\n\t\t\t\t\t<clearStorageRange>(deleteStart, sub(oldSlotCount, newSlotCount))\n\t\t\t\t}\n\t\t\t}\n\t\t)\")\n\t\t(\"dataLocation\", arrayDataAreaFunction(_type))\n\t\t(\"div32Ceil\", divide32CeilFunction())\n\t\t(\"clearStorageRange\", clearStorageRangeFunction(*_type.baseType()))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::decreaseByteArraySizeFunction(ArrayType const& _type)\n{\n\tstd::string functionName = \"byte_array_decrease_size_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(array, data, oldLen, newLen) {\n\t\t\t\tswitch lt(newLen, 32)\n\t\t\t\tcase  0 {\n\t\t\t\t\t// NOTE: This branch (newLen >= 32) is currently unreachable from Solidity code.\n\t\t\t\t\t// All delete operations use newLen=0, and assignment uses copyByteArrayToStorageFunction.\n\t\t\t\t\t// However, we maintain correct logic here for future-proofing and consistency.\n\t\t\t\t\tlet newSlots := <div32Ceil>(newLen)\n\t\t\t\t\tlet oldSlots := <div32Ceil>(oldLen)\n\t\t\t\t\tlet arrayDataStart := <dataPosition>(array)\n\t\t\t\t\tlet deleteStart := add(arrayDataStart, newSlots)\n\n\t\t\t\t\t// we have to partially clear last slot that is still used\n\t\t\t\t\tlet offset := and(newLen, 0x1f)\n\t\t\t\t\tif offset { <partialClearStorageSlot>(sub(deleteStart, 1), offset) }\n\n\t\t\t\t\tif gt(oldSlots, newSlots) {\n\t\t\t\t\t\t<clearStorageRange>(deleteStart, sub(oldSlots, newSlots))\n\t\t\t\t\t}\n\n\t\t\t\t\tsstore(array, or(mul(2, newLen), 1))\n\t\t\t\t}\n\t\t\t\tdefault {\n\t\t\t\t\tswitch gt(oldLen, 31)\n\t\t\t\t\tcase 1 {\n\t\t\t\t\t\tlet arrayDataStart := <dataPosition>(array)\n\t\t\t\t\t\t// Clear whole old array, as we are transforming to short bytes array.\n\t\t\t\t\t\t// <transitLongToShort>() will clear the first slot after copying its content.\n\t\t\t\t\t\t<clearStorageRange>(add(arrayDataStart, 1), sub(<div32Ceil>(oldLen), 1))\n\t\t\t\t\t\t<transitLongToShort>(array, newLen)\n\t\t\t\t\t}\n\t\t\t\t\tdefault {\n\t\t\t\t\t\tsstore(array, <encodeUsedSetLen>(data, newLen))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"dataPosition\", arrayDataAreaFunction(_type))\n\t\t\t(\"partialClearStorageSlot\", partialClearStorageSlotFunction())\n\t\t\t(\"clearStorageRange\", clearStorageRangeFunction(*_type.baseType()))\n\t\t\t(\"transitLongToShort\", byteArrayTransitLongToShortFunction(_type))\n\t\t\t(\"div32Ceil\", divide32CeilFunction())\n\t\t\t(\"encodeUsedSetLen\", shortByteArrayEncodeUsedAreaSetLengthFunction())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::increaseByteArraySizeFunction(ArrayType const& _type)\n{\n\tstd::string functionName = \"byte_array_increase_size_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&](std::vector<std::string>& _args, std::vector<std::string>&) {\n\t\t_args = {\"array\", \"data\", \"oldLen\", \"newLen\"};\n\t\treturn Whiskers(R\"(\n\t\t\tif gt(newLen, <maxArrayLength>) { <panic>() }\n\n\t\t\tswitch lt(oldLen, 32)\n\t\t\tcase 0 {\n\t\t\t\t// in this case array stays unpacked, so we just set new length\n\t\t\t\tsstore(array, add(mul(2, newLen), 1))\n\t\t\t}\n\t\t\tdefault {\n\t\t\t\tswitch lt(newLen, 32)\n\t\t\t\tcase 0 {\n\t\t\t\t\t// we need to copy elements to data area as we changed array from packed to unpacked\n\t\t\t\t\tdata := and(not(0xff), data)\n\t\t\t\t\tsstore(<dataPosition>(array), data)\n\t\t\t\t\tsstore(array, add(mul(2, newLen), 1))\n\t\t\t\t}\n\t\t\t\tdefault {\n\t\t\t\t\t// here array stays packed, we just need to increase length\n\t\t\t\t\tsstore(array, <encodeUsedSetLen>(data, newLen))\n\t\t\t\t}\n\t\t\t}\n\t\t)\")\n\t\t(\"panic\", panicFunction(PanicCode::ResourceError))\n\t\t(\"maxArrayLength\", (u256(1) << 64).str())\n\t\t(\"dataPosition\", arrayDataAreaFunction(_type))\n\t\t(\"encodeUsedSetLen\", shortByteArrayEncodeUsedAreaSetLengthFunction())\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::byteArrayTransitLongToShortFunction(ArrayType const& _type)\n{\n\tstd::string functionName = \"transit_byte_array_long_to_short_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(array, len) {\n\t\t\t\t// we need to copy elements from old array to new\n\t\t\t\t// we want to copy only elements that are part of the array after resizing\n\t\t\t\tlet dataPos := <dataPosition>(array)\n\t\t\t\tlet data := <extractUsedApplyLen>(sload(dataPos), len)\n\t\t\t\tsstore(array, data)\n\t\t\t\tsstore(dataPos, 0)\n\t\t\t})\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"dataPosition\", arrayDataAreaFunction(_type))\n\t\t\t(\"extractUsedApplyLen\", shortByteArrayEncodeUsedAreaSetLengthFunction())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::shortByteArrayEncodeUsedAreaSetLengthFunction()\n{\n\tstd::string functionName = \"extract_used_part_and_set_length_of_short_byte_array\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(data, len) -> used {\n\t\t\t\t// we want to save only elements that are part of the array after resizing\n\t\t\t\t// others should be set to zero\n\t\t\t\tdata := <maskBytes>(data, len)\n\t\t\t\tused := or(data, mul(2, len))\n\t\t\t})\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"maskBytes\", maskBytesFunctionDynamic())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::longByteArrayStorageIndexAccessNoCheckFunction()\n{\n\treturn m_functionCollector.createFunction(\n\t\t\"long_byte_array_index_access_no_checks\",\n\t\t[&](std::vector<std::string>& _args, std::vector<std::string>& _returnParams) {\n\t\t\t_args = {\"array\", \"index\"};\n\t\t\t_returnParams = {\"slot\", \"offset\"};\n\t\t\treturn Whiskers(R\"(\n\t\t\t\toffset := sub(31, mod(index, 0x20))\n\t\t\t\tlet dataArea := <dataAreaFunc>(array)\n\t\t\t\tslot := add(dataArea, div(index, 0x20))\n\t\t\t)\")\n\t\t\t(\"dataAreaFunc\", arrayDataAreaFunction(*TypeProvider::bytesStorage()))\n\t\t\t.render();\n\t\t}\n\t);\n}\n\nstd::string YulUtilFunctions::storageArrayPopFunction(ArrayType const& _type)\n{\n\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\tsolAssert(_type.isDynamicallySized(), \"\");\n\tsolUnimplementedAssert(_type.baseType()->storageBytes() <= 32, \"Base type is not yet implemented.\");\n\tif (_type.isByteArrayOrString())\n\t\treturn storageByteArrayPopFunction(_type);\n\n\tstd::string functionName = \"array_pop_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(array) {\n\t\t\t\tlet oldLen := <fetchLength>(array)\n\t\t\t\tif iszero(oldLen) { <panic>() }\n\t\t\t\tlet newLen := sub(oldLen, 1)\n\t\t\t\tlet slot, offset := <indexAccess>(array, newLen)\n\t\t\t\t<?+setToZero><setToZero>(slot, offset)</+setToZero>\n\t\t\t\tsstore(array, newLen)\n\t\t\t})\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"panic\", panicFunction(PanicCode::EmptyArrayPop))\n\t\t\t(\"fetchLength\", arrayLengthFunction(_type))\n\t\t\t(\"indexAccess\", storageArrayIndexAccessFunction(_type))\n\t\t\t(\n\t\t\t\t\"setToZero\",\n\t\t\t\t_type.baseType()->category() != Type::Category::Mapping ? storageSetToZeroFunction(*_type.baseType(), VariableDeclaration::Location::Unspecified) : \"\"\n\t\t\t)\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::storageByteArrayPopFunction(ArrayType const& _type)\n{\n\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\tsolAssert(_type.isDynamicallySized(), \"\");\n\tsolAssert(_type.isByteArrayOrString(), \"\");\n\n\tstd::string functionName = \"byte_array_pop_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(array) {\n\t\t\t\tlet data := sload(array)\n\t\t\t\tlet oldLen := <extractByteArrayLength>(data)\n\t\t\t\tif iszero(oldLen) { <panic>() }\n\n\t\t\t\tswitch oldLen\n\t\t\t\tcase 32 {\n\t\t\t\t\t// Here we have a special case where array transitions to shorter than 32\n\t\t\t\t\t// So we need to copy data\n\t\t\t\t\t<transitLongToShort>(array, 31)\n\t\t\t\t}\n\t\t\t\tdefault {\n\t\t\t\t\tlet newLen := sub(oldLen, 1)\n\t\t\t\t\tswitch lt(oldLen, 32)\n\t\t\t\t\tcase 1 {\n\t\t\t\t\t\tsstore(array, <encodeUsedSetLen>(data, newLen))\n\t\t\t\t\t}\n\t\t\t\t\tdefault {\n\t\t\t\t\t\tlet slot, offset := <indexAccessNoChecks>(array, newLen)\n\t\t\t\t\t\t<setToZero>(slot, offset)\n\t\t\t\t\t\tsstore(array, sub(data, 2))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"panic\", panicFunction(PanicCode::EmptyArrayPop))\n\t\t\t(\"extractByteArrayLength\", extractByteArrayLengthFunction())\n\t\t\t(\"transitLongToShort\", byteArrayTransitLongToShortFunction(_type))\n\t\t\t(\"encodeUsedSetLen\", shortByteArrayEncodeUsedAreaSetLengthFunction())\n\t\t\t(\"indexAccessNoChecks\", longByteArrayStorageIndexAccessNoCheckFunction())\n\t\t\t(\"setToZero\", storageSetToZeroFunction(*_type.baseType(), VariableDeclaration::Location::Unspecified))\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::storageArrayPushFunction(ArrayType const& _type, Type const* _fromType)\n{\n\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\tsolAssert(_type.isDynamicallySized(), \"\");\n\tif (!_fromType)\n\t\t_fromType = _type.baseType();\n\telse if (_fromType->isValueType())\n\t\tsolUnimplementedAssert(*_fromType == *_type.baseType());\n\n\tstd::string functionName =\n\t\tstd::string{\"array_push_from_\"} +\n\t\t_fromType->identifier() +\n\t\t\"_to_\" +\n\t\t_type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(array <values>) {\n\t\t\t\t<?isByteArrayOrString>\n\t\t\t\t\tlet data := sload(array)\n\t\t\t\t\tlet oldLen := <extractByteArrayLength>(data)\n\t\t\t\t\tif iszero(lt(oldLen, <maxArrayLength>)) { <panic>() }\n\n\t\t\t\t\tswitch gt(oldLen, 31)\n\t\t\t\t\tcase 0 {\n\t\t\t\t\t\tlet value := byte(0 <values>)\n\t\t\t\t\t\tswitch oldLen\n\t\t\t\t\t\tcase 31 {\n\t\t\t\t\t\t\t// Here we have special case when array switches from short array to long array\n\t\t\t\t\t\t\t// We need to copy data\n\t\t\t\t\t\t\tlet dataArea := <dataAreaFunction>(array)\n\t\t\t\t\t\t\tdata := and(data, not(0xff))\n\t\t\t\t\t\t\tsstore(dataArea, or(and(0xff, value), data))\n\t\t\t\t\t\t\t// New length is 32, encoded as (32 * 2 + 1)\n\t\t\t\t\t\t\tsstore(array, 65)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault {\n\t\t\t\t\t\t\tdata := add(data, 2)\n\t\t\t\t\t\t\tlet shiftBits := mul(8, sub(31, oldLen))\n\t\t\t\t\t\t\tlet valueShifted := <shl>(shiftBits, and(0xff, value))\n\t\t\t\t\t\t\tlet mask := <shl>(shiftBits, 0xff)\n\t\t\t\t\t\t\tdata := or(and(data, not(mask)), valueShifted)\n\t\t\t\t\t\t\tsstore(array, data)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdefault {\n\t\t\t\t\t\tsstore(array, add(data, 2))\n\t\t\t\t\t\tlet slot, offset := <indexAccess>(array, oldLen)\n\t\t\t\t\t\t<storeValue>(slot, offset <values>)\n\t\t\t\t\t}\n\t\t\t\t<!isByteArrayOrString>\n\t\t\t\t\tlet oldLen := sload(array)\n\t\t\t\t\tif iszero(lt(oldLen, <maxArrayLength>)) { <panic>() }\n\t\t\t\t\tsstore(array, add(oldLen, 1))\n\t\t\t\t\tlet slot, offset := <indexAccess>(array, oldLen)\n\t\t\t\t\t<storeValue>(slot, offset <values>)\n\t\t\t\t</isByteArrayOrString>\n\t\t\t})\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"values\", _fromType->sizeOnStack() == 0 ? \"\" : \", \" + suffixedVariableNameList(\"value\", 0, _fromType->sizeOnStack()))\n\t\t\t(\"panic\", panicFunction(PanicCode::ResourceError))\n\t\t\t(\"extractByteArrayLength\", _type.isByteArrayOrString() ? extractByteArrayLengthFunction() : \"\")\n\t\t\t(\"dataAreaFunction\", arrayDataAreaFunction(_type))\n\t\t\t(\"isByteArrayOrString\", _type.isByteArrayOrString())\n\t\t\t(\"indexAccess\", storageArrayIndexAccessFunction(_type))\n\t\t\t(\"storeValue\", updateStorageValueFunction(*_fromType, *_type.baseType(), VariableDeclaration::Location::Unspecified))\n\t\t\t(\"maxArrayLength\", (u256(1) << 64).str())\n\t\t\t(\"shl\", shiftLeftFunctionDynamic())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::storageArrayPushZeroFunction(ArrayType const& _type)\n{\n\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\tsolAssert(_type.isDynamicallySized(), \"\");\n\tsolUnimplementedAssert(_type.baseType()->storageBytes() <= 32, \"Base type is not yet implemented.\");\n\n\tstd::string functionName = \"array_push_zero_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(array) -> slot, offset {\n\t\t\t\t<?isBytes>\n\t\t\t\t\tlet data := sload(array)\n\t\t\t\t\tlet oldLen := <extractLength>(data)\n\t\t\t\t\t<increaseBytesSize>(array, data, oldLen, add(oldLen, 1))\n\t\t\t\t<!isBytes>\n\t\t\t\t\tlet oldLen := <fetchLength>(array)\n\t\t\t\t\tif iszero(lt(oldLen, <maxArrayLength>)) { <panic>() }\n\t\t\t\t\tsstore(array, add(oldLen, 1))\n\t\t\t\t</isBytes>\n\t\t\t\tslot, offset := <indexAccess>(array, oldLen)\n\t\t\t})\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"isBytes\", _type.isByteArrayOrString())\n\t\t\t(\"increaseBytesSize\", _type.isByteArrayOrString() ? increaseByteArraySizeFunction(_type) : \"\")\n\t\t\t(\"extractLength\", _type.isByteArrayOrString() ? extractByteArrayLengthFunction() : \"\")\n\t\t\t(\"panic\", panicFunction(PanicCode::ResourceError))\n\t\t\t(\"fetchLength\", arrayLengthFunction(_type))\n\t\t\t(\"indexAccess\", storageArrayIndexAccessFunction(_type))\n\t\t\t(\"maxArrayLength\", (u256(1) << 64).str())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::partialClearStorageSlotFunction()\n{\n\tstd::string functionName = \"partial_clear_storage_slot\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\tfunction <functionName>(slot, offset) {\n\t\t\tlet mask := <shr>(mul(8, sub(32, offset)), <ones>)\n\t\t\tsstore(slot, and(mask, sload(slot)))\n\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"ones\", formatNumber((bigint(1) << 256) - 1))\n\t\t(\"shr\", shiftRightFunctionDynamic())\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::clearStorageRangeFunction(Type const& _type)\n{\n\tif (_type.storageBytes() < 32)\n\t\tsolAssert(_type.isValueType(), \"\");\n\n\tstd::string functionName = \"clear_storage_range_\" + _type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(startSlot, slotCount) {\n\t\t\t\tfor { let i := 0 } lt(i, slotCount) { i := add(i, <increment>) }\n\t\t\t\t{\n\t\t\t\t\t<setToZero>(add(startSlot, i), 0)\n\t\t\t\t}\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"setToZero\", storageSetToZeroFunction(_type.storageBytes() < 32 ? *TypeProvider::uint256() : _type, VariableDeclaration::Location::Unspecified))\n\t\t(\"increment\", _type.storageSize().str())\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::clearStorageArrayFunction(ArrayType const& _type)\n{\n\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\n\tif (_type.baseType()->storageBytes() < 32)\n\t{\n\t\tsolAssert(_type.baseType()->isValueType(), \"Invalid storage size for non-value type.\");\n\t\tsolAssert(_type.baseType()->storageSize() <= 1, \"Invalid storage size for type.\");\n\t}\n\n\tif (_type.baseType()->isValueType())\n\t\tsolAssert(_type.baseType()->storageSize() <= 1, \"Invalid size for value type.\");\n\n\tstd::string functionName = \"clear_storage_array_\" + _type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(slot) {\n\t\t\t\t<?dynamic>\n\t\t\t\t\t<resizeArray>(slot, 0)\n\t\t\t\t<!dynamic>\n\t\t\t\t\t<?+clearRange><clearRange>(slot, <lenToSize>(<len>))</+clearRange>\n\t\t\t\t</dynamic>\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"dynamic\", _type.isDynamicallySized())\n\t\t(\"resizeArray\", _type.isDynamicallySized() ? resizeArrayFunction(_type) : \"\")\n\t\t(\n\t\t\t\"clearRange\",\n\t\t\t_type.baseType()->category() != Type::Category::Mapping ?\n\t\t\tclearStorageRangeFunction((_type.baseType()->storageBytes() < 32) ? *TypeProvider::uint256() : *_type.baseType()) :\n\t\t\t\"\"\n\t\t)\n\t\t(\"lenToSize\", arrayConvertLengthToSize(_type))\n\t\t(\"len\", _type.length().str())\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::clearStorageStructFunction(StructType const& _type)\n{\n\tsolAssert(_type.location() == DataLocation::Storage, \"\");\n\n\tstd::string functionName = \"clear_struct_storage_\" + _type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\tMemberList::MemberMap structMembers = _type.nativeMembers(nullptr);\n\t\tstd::vector<std::map<std::string, std::string>> memberSetValues;\n\n\t\tstd::set<u256> slotsCleared;\n\t\tfor (auto const& member: structMembers)\n\t\t{\n\t\t\tif (member.type->category() == Type::Category::Mapping)\n\t\t\t\tcontinue;\n\t\t\tif (member.type->storageBytes() < 32)\n\t\t\t{\n\t\t\t\tauto const& slotDiff = _type.storageOffsetsOfMember(member.name).first;\n\t\t\t\tif (!slotsCleared.count(slotDiff))\n\t\t\t\t{\n\t\t\t\t\tmemberSetValues.emplace_back().emplace(\"clearMember\", \"sstore(add(slot, \" + slotDiff.str() + \"), 0)\");\n\t\t\t\t\tslotsCleared.emplace(slotDiff);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto const& [memberSlotDiff, memberStorageOffset] = _type.storageOffsetsOfMember(member.name);\n\t\t\t\tsolAssert(memberStorageOffset == 0, \"\");\n\n\t\t\t\tmemberSetValues.emplace_back().emplace(\"clearMember\", Whiskers(R\"(\n\t\t\t\t\t\t<setZero>(add(slot, <memberSlotDiff>), <memberStorageOffset>)\n\t\t\t\t\t)\")\n\t\t\t\t\t(\"setZero\", storageSetToZeroFunction(*member.type, VariableDeclaration::Location::Unspecified))\n\t\t\t\t\t(\"memberSlotDiff\",  memberSlotDiff.str())\n\t\t\t\t\t(\"memberStorageOffset\", std::to_string(memberStorageOffset))\n\t\t\t\t\t.render()\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(slot) {\n\t\t\t\t<#member>\n\t\t\t\t\t<clearMember>\n\t\t\t\t</member>\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"member\", memberSetValues)\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::copyArrayToStorageFunction(ArrayType const& _fromType, ArrayType const& _toType)\n{\n\tsolAssert(\n\t\t(*_fromType.copyForLocation(_toType.location(), _toType.isPointer())).equals(dynamic_cast<ReferenceType const&>(_toType)),\n\t\t\"\"\n\t);\n\tif (!_toType.isDynamicallySized())\n\t\tsolAssert(!_fromType.isDynamicallySized() && _fromType.length() <= _toType.length(), \"\");\n\n\tif (_fromType.isByteArrayOrString())\n\t\treturn copyByteArrayToStorageFunction(_fromType, _toType);\n\tif (_toType.baseType()->isValueType())\n\t\treturn copyValueArrayToStorageFunction(_fromType, _toType);\n\n\tsolAssert(_toType.storageStride() == 32);\n\tsolAssert(!_fromType.baseType()->isValueType());\n\n\tstd::string functionName = \"copy_array_to_storage_from_\" + _fromType.identifier() + \"_to_\" + _toType.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&](){\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(slot, value<?isFromDynamicCalldata>, len</isFromDynamicCalldata>) {\n\t\t\t\t<?fromStorage> if eq(slot, value) { leave } </fromStorage>\n\t\t\t\tlet length := <arrayLength>(value<?isFromDynamicCalldata>, len</isFromDynamicCalldata>)\n\n\t\t\t\t<resizeArray>(slot, length)\n\n\t\t\t\tlet srcPtr := <srcDataLocation>(value)\n\n\t\t\t\tlet elementSlot := <dstDataLocation>(slot)\n\n\t\t\t\tfor { let i := 0 } lt(i, length) {i := add(i, 1)} {\n\t\t\t\t\t<?fromCalldata>\n\t\t\t\t\t\tlet <stackItems> :=\n\t\t\t\t\t\t<?dynamicallyEncodedBase>\n\t\t\t\t\t\t\t<accessCalldataTail>(value, srcPtr)\n\t\t\t\t\t\t<!dynamicallyEncodedBase>\n\t\t\t\t\t\t\tsrcPtr\n\t\t\t\t\t\t</dynamicallyEncodedBase>\n\t\t\t\t\t</fromCalldata>\n\n\t\t\t\t\t<?fromMemory>\n\t\t\t\t\t\tlet <stackItems> := <readFromMemoryOrCalldata>(srcPtr)\n\t\t\t\t\t</fromMemory>\n\n\t\t\t\t\t<?fromStorage>\n\t\t\t\t\t\tlet <stackItems> := srcPtr\n\t\t\t\t\t</fromStorage>\n\n\t\t\t\t\t<updateStorageValue>(elementSlot, <stackItems>)\n\n\t\t\t\t\tsrcPtr := add(srcPtr, <srcStride>)\n\n\t\t\t\t\telementSlot := add(elementSlot, <storageSize>)\n\t\t\t\t}\n\t\t\t}\n\t\t)\");\n\t\tif (_fromType.dataStoredIn(DataLocation::Storage))\n\t\t\tsolAssert(!_fromType.isValueType(), \"\");\n\t\ttempl(\"functionName\", functionName);\n\t\tbool fromCalldata = _fromType.dataStoredIn(DataLocation::CallData);\n\t\ttempl(\"isFromDynamicCalldata\", _fromType.isDynamicallySized() && fromCalldata);\n\t\ttempl(\"fromStorage\", _fromType.dataStoredIn(DataLocation::Storage));\n\t\tbool fromMemory = _fromType.dataStoredIn(DataLocation::Memory);\n\t\ttempl(\"fromMemory\", fromMemory);\n\t\ttempl(\"fromCalldata\", fromCalldata);\n\t\ttempl(\"srcDataLocation\", arrayDataAreaFunction(_fromType));\n\t\tif (fromCalldata)\n\t\t{\n\t\t\ttempl(\"dynamicallyEncodedBase\", _fromType.baseType()->isDynamicallyEncoded());\n\t\t\tif (_fromType.baseType()->isDynamicallyEncoded())\n\t\t\t\ttempl(\"accessCalldataTail\", accessCalldataTailFunction(*_fromType.baseType()));\n\t\t}\n\t\ttempl(\"resizeArray\", resizeArrayFunction(_toType));\n\t\ttempl(\"arrayLength\",arrayLengthFunction(_fromType));\n\t\ttempl(\"dstDataLocation\", arrayDataAreaFunction(_toType));\n\t\tif (fromMemory || (fromCalldata && _fromType.baseType()->isValueType()))\n\t\t\ttempl(\"readFromMemoryOrCalldata\", readFromMemoryOrCalldata(*_fromType.baseType(), fromCalldata));\n\t\ttempl(\"stackItems\", suffixedVariableNameList(\n\t\t\t\"stackItem_\",\n\t\t\t0,\n\t\t\t_fromType.baseType()->stackItems().size()\n\t\t));\n\t\ttempl(\"updateStorageValue\", updateStorageValueFunction(*_fromType.baseType(), *_toType.baseType(), VariableDeclaration::Location::Unspecified, 0));\n\t\ttempl(\"srcStride\",\n\t\t\tfromCalldata ?\n\t\t\tstd::to_string(_fromType.calldataStride()) :\n\t\t\t\tfromMemory ?\n\t\t\t\tstd::to_string(_fromType.memoryStride()) :\n\t\t\t\tformatNumber(_fromType.baseType()->storageSize())\n\t\t);\n\t\ttempl(\"storageSize\", _toType.baseType()->storageSize().str());\n\n\t\treturn templ.render();\n\t});\n}\n\n\nstd::string YulUtilFunctions::copyByteArrayToStorageFunction(ArrayType const& _fromType, ArrayType const& _toType)\n{\n\tsolAssert(\n\t\t(*_fromType.copyForLocation(_toType.location(), _toType.isPointer())).equals(dynamic_cast<ReferenceType const&>(_toType)),\n\t\t\"\"\n\t);\n\tsolAssert(_fromType.isByteArrayOrString(), \"\");\n\tsolAssert(_toType.isByteArrayOrString(), \"\");\n\n\tstd::string functionName = \"copy_byte_array_to_storage_from_\" + _fromType.identifier() + \"_to_\" + _toType.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&](){\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(slot, src<?fromCalldata>, len</fromCalldata>) {\n\t\t\t\t<?fromStorage> if eq(slot, src) { leave } </fromStorage>\n\n\t\t\t\tlet newLen := <arrayLength>(src<?fromCalldata>, len</fromCalldata>)\n\t\t\t\t// Make sure array length is sane\n\t\t\t\tif gt(newLen, 0xffffffffffffffff) { <panic>() }\n\n\t\t\t\tlet oldLen := <byteArrayLength>(sload(slot))\n\n\t\t\t\t// potentially truncate data\n\t\t\t\t<cleanUpEndArray>(slot, oldLen, newLen)\n\n\t\t\t\tlet srcOffset := 0\n\t\t\t\t<?fromMemory>\n\t\t\t\t\tsrcOffset := 0x20\n\t\t\t\t</fromMemory>\n\n\t\t\t\tswitch gt(newLen, 31)\n\t\t\t\tcase 1 {\n\t\t\t\t\tlet loopEnd := and(newLen, not(0x1f))\n\t\t\t\t\t<?fromStorage> src := <srcDataLocation>(src) </fromStorage>\n\t\t\t\t\tlet dstPtr := <dstDataLocation>(slot)\n\t\t\t\t\tlet i := 0\n\t\t\t\t\tfor { } lt(i, loopEnd) { i := add(i, 0x20) } {\n\t\t\t\t\t\tsstore(dstPtr, <read>(add(src, srcOffset)))\n\t\t\t\t\t\tdstPtr := add(dstPtr, 1)\n\t\t\t\t\t\tsrcOffset := add(srcOffset, <srcIncrement>)\n\t\t\t\t\t}\n\t\t\t\t\tif lt(loopEnd, newLen) {\n\t\t\t\t\t\tlet lastValue := <read>(add(src, srcOffset))\n\t\t\t\t\t\tsstore(dstPtr, <maskBytes>(lastValue, and(newLen, 0x1f)))\n\t\t\t\t\t}\n\t\t\t\t\tsstore(slot, add(mul(newLen, 2), 1))\n\t\t\t\t}\n\t\t\t\tdefault {\n\t\t\t\t\tlet value := 0\n\t\t\t\t\tif newLen {\n\t\t\t\t\t\tvalue := <read>(add(src, srcOffset))\n\t\t\t\t\t}\n\t\t\t\t\tsstore(slot, <byteArrayCombineShort>(value, newLen))\n\t\t\t\t}\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\tbool fromStorage = _fromType.dataStoredIn(DataLocation::Storage);\n\t\ttempl(\"fromStorage\", fromStorage);\n\t\tbool fromCalldata = _fromType.dataStoredIn(DataLocation::CallData);\n\t\ttempl(\"fromMemory\", _fromType.dataStoredIn(DataLocation::Memory));\n\t\ttempl(\"fromCalldata\", fromCalldata);\n\t\ttempl(\"arrayLength\", arrayLengthFunction(_fromType));\n\t\ttempl(\"panic\", panicFunction(PanicCode::ResourceError));\n\t\ttempl(\"byteArrayLength\", extractByteArrayLengthFunction());\n\t\ttempl(\"dstDataLocation\", arrayDataAreaFunction(_toType));\n\t\tif (fromStorage)\n\t\t\ttempl(\"srcDataLocation\", arrayDataAreaFunction(_fromType));\n\t\ttempl(\"cleanUpEndArray\", cleanUpDynamicByteArrayEndSlotsFunction(_toType));\n\t\ttempl(\"srcIncrement\", std::to_string(fromStorage ? 1 : 0x20));\n\t\ttempl(\"read\", fromStorage ? \"sload\" : fromCalldata ? \"calldataload\" : \"mload\");\n\t\ttempl(\"maskBytes\", maskBytesFunctionDynamic());\n\t\ttempl(\"byteArrayCombineShort\", shortByteArrayEncodeUsedAreaSetLengthFunction());\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::copyValueArrayToStorageFunction(ArrayType const& _fromType, ArrayType const& _toType)\n{\n\tsolAssert(_fromType.baseType()->isValueType(), \"\");\n\tsolAssert(_toType.baseType()->isValueType(), \"\");\n\tsolAssert(_fromType.baseType()->isImplicitlyConvertibleTo(*_toType.baseType()), \"\");\n\n\tsolAssert(!_fromType.isByteArrayOrString(), \"\");\n\tsolAssert(!_toType.isByteArrayOrString(), \"\");\n\tsolAssert(_toType.dataStoredIn(DataLocation::Storage), \"\");\n\n\tsolAssert(_fromType.storageStride() <= _toType.storageStride(), \"\");\n\tsolAssert(_toType.storageStride() <= 32, \"\");\n\n\tstd::string functionName = \"copy_array_to_storage_from_\" + _fromType.identifier() + \"_to_\" + _toType.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&](){\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(dst, src<?isFromDynamicCalldata>, len</isFromDynamicCalldata>) {\n\t\t\t\t<?isFromStorage>\n\t\t\t\tif eq(dst, src) { leave }\n\t\t\t\t</isFromStorage>\n\t\t\t\tlet length := <arrayLength>(src<?isFromDynamicCalldata>, len</isFromDynamicCalldata>)\n\t\t\t\t// Make sure array length is sane\n\t\t\t\tif gt(length, 0xffffffffffffffff) { <panic>() }\n\t\t\t\t<resizeArray>(dst, length)\n\n\t\t\t\tlet srcPtr := <srcDataLocation>(src)\n\t\t\t\tlet dstSlot := <dstDataLocation>(dst)\n\n\t\t\t\tlet fullSlots := div(length, <itemsPerSlot>)\n\n\t\t\t\t<?isFromStorage>\n\t\t\t\tlet srcSlotValue := sload(srcPtr)\n\t\t\t\tlet srcItemIndexInSlot := 0\n\t\t\t\t</isFromStorage>\n\n\t\t\t\tfor { let i := 0 } lt(i, fullSlots) { i := add(i, 1) } {\n\t\t\t\t\tlet dstSlotValue := 0\n\t\t\t\t\t<?sameTypeFromStorage>\n\t\t\t\t\t\tdstSlotValue := <maskFull>(srcSlotValue)\n\t\t\t\t\t\t<updateSrcPtr>\n\t\t\t\t\t<!sameTypeFromStorage>\n\t\t\t\t\t\t<?multipleItemsPerSlotDst>for { let j := 0 } lt(j, <itemsPerSlot>) { j := add(j, 1) } </multipleItemsPerSlotDst>\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t<?isFromStorage>\n\t\t\t\t\t\t\tlet <stackItems> := <convert>(\n\t\t\t\t\t\t\t\t<extractFromSlot>(srcSlotValue, mul(<srcStride>, srcItemIndexInSlot))\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t<!isFromStorage>\n\t\t\t\t\t\t\tlet <stackItems> := <readFromMemoryOrCalldata>(srcPtr)\n\t\t\t\t\t\t\t</isFromStorage>\n\t\t\t\t\t\t\tlet itemValue := <prepareStore>(<stackItems>)\n\t\t\t\t\t\t\tdstSlotValue :=\n\t\t\t\t\t\t\t<?multipleItemsPerSlotDst>\n\t\t\t\t\t\t\t\t<updateByteSlice>(dstSlotValue, mul(<dstStride>, j), itemValue)\n\t\t\t\t\t\t\t<!multipleItemsPerSlotDst>\n\t\t\t\t\t\t\t\titemValue\n\t\t\t\t\t\t\t</multipleItemsPerSlotDst>\n\n\t\t\t\t\t\t\t<updateSrcPtr>\n\t\t\t\t\t\t}\n\t\t\t\t\t</sameTypeFromStorage>\n\n\t\t\t\t\tsstore(add(dstSlot, i), dstSlotValue)\n\t\t\t\t}\n\n\t\t\t\t<?multipleItemsPerSlotDst>\n\t\t\t\t\tlet spill := sub(length, mul(fullSlots, <itemsPerSlot>))\n\t\t\t\t\tif gt(spill, 0) {\n\t\t\t\t\t\tlet dstSlotValue := 0\n\t\t\t\t\t\t<?sameTypeFromStorage>\n\t\t\t\t\t\t\tdstSlotValue := <maskBytes>(srcSlotValue, mul(spill, <srcStride>))\n\t\t\t\t\t\t\t<updateSrcPtr>\n\t\t\t\t\t\t<!sameTypeFromStorage>\n\t\t\t\t\t\t\tfor { let j := 0 } lt(j, spill) { j := add(j, 1) } {\n\t\t\t\t\t\t\t\t<?isFromStorage>\n\t\t\t\t\t\t\t\tlet <stackItems> := <convert>(\n\t\t\t\t\t\t\t\t\t<extractFromSlot>(srcSlotValue, mul(<srcStride>, srcItemIndexInSlot))\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t<!isFromStorage>\n\t\t\t\t\t\t\t\tlet <stackItems> := <readFromMemoryOrCalldata>(srcPtr)\n\t\t\t\t\t\t\t\t</isFromStorage>\n\t\t\t\t\t\t\t\tlet itemValue := <prepareStore>(<stackItems>)\n\t\t\t\t\t\t\t\tdstSlotValue := <updateByteSlice>(dstSlotValue, mul(<dstStride>, j), itemValue)\n\n\t\t\t\t\t\t\t\t<updateSrcPtr>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</sameTypeFromStorage>\n\t\t\t\t\t\tsstore(add(dstSlot, fullSlots), dstSlotValue)\n\t\t\t\t\t}\n\t\t\t\t</multipleItemsPerSlotDst>\n\t\t\t}\n\t\t)\");\n\t\tif (_fromType.dataStoredIn(DataLocation::Storage))\n\t\t\tsolAssert(!_fromType.isValueType(), \"\");\n\n\t\tbool fromCalldata = _fromType.dataStoredIn(DataLocation::CallData);\n\t\tbool fromStorage = _fromType.dataStoredIn(DataLocation::Storage);\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"resizeArray\", resizeArrayFunction(_toType));\n\t\ttempl(\"arrayLength\", arrayLengthFunction(_fromType));\n\t\ttempl(\"panic\", panicFunction(PanicCode::ResourceError));\n\t\ttempl(\"isFromDynamicCalldata\", _fromType.isDynamicallySized() && fromCalldata);\n\t\ttempl(\"isFromStorage\", fromStorage);\n\t\ttempl(\"readFromMemoryOrCalldata\", readFromMemoryOrCalldata(*_fromType.baseType(), fromCalldata));\n\t\ttempl(\"srcDataLocation\", arrayDataAreaFunction(_fromType));\n\t\ttempl(\"dstDataLocation\", arrayDataAreaFunction(_toType));\n\t\ttempl(\"srcStride\", std::to_string(_fromType.storageStride()));\n\t\ttempl(\"stackItems\", suffixedVariableNameList(\n\t\t\t\"stackItem_\",\n\t\t\t0,\n\t\t\t_fromType.baseType()->stackItems().size()\n\t\t));\n\t\tunsigned itemsPerSlot = 32 / _toType.storageStride();\n\t\ttempl(\"itemsPerSlot\", std::to_string(itemsPerSlot));\n\t\ttempl(\"multipleItemsPerSlotDst\", itemsPerSlot > 1);\n\t\tbool sameTypeFromStorage = fromStorage && (*_fromType.baseType() == *_toType.baseType());\n\t\tif (auto functionType = dynamic_cast<FunctionType const*>(_fromType.baseType()))\n\t\t{\n\t\t\tsolAssert(functionType->equalExcludingStateMutability(\n\t\t\t\tdynamic_cast<FunctionType const&>(*_toType.baseType())\n\t\t\t));\n\t\t\tsameTypeFromStorage = fromStorage;\n\t\t}\n\t\ttempl(\"sameTypeFromStorage\", sameTypeFromStorage);\n\t\tif (sameTypeFromStorage)\n\t\t{\n\t\t\ttempl(\"maskFull\", maskLowerOrderBytesFunction(itemsPerSlot * _toType.storageStride()));\n\t\t\ttempl(\"maskBytes\", maskLowerOrderBytesFunctionDynamic());\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttempl(\"dstStride\", std::to_string(_toType.storageStride()));\n\t\t\ttempl(\"extractFromSlot\", extractFromStorageValueDynamic(*_fromType.baseType()));\n\t\t\ttempl(\"updateByteSlice\", updateByteSliceFunctionDynamic(_toType.storageStride()));\n\t\t\ttempl(\"convert\", conversionFunction(*_fromType.baseType(), *_toType.baseType()));\n\t\t\ttempl(\"prepareStore\", prepareStoreFunction(*_toType.baseType()));\n\t\t}\n\t\tif (fromStorage)\n\t\t\ttempl(\"updateSrcPtr\", Whiskers(R\"(\n\t\t\t\t<?srcReadMultiPerSlot>\n\t\t\t\t\tsrcItemIndexInSlot := add(srcItemIndexInSlot, 1)\n\t\t\t\t\tif eq(srcItemIndexInSlot, <srcItemsPerSlot>) {\n\t\t\t\t\t\t// here we are done with this slot, we need to read next one\n\t\t\t\t\t\tsrcPtr := add(srcPtr, 1)\n\t\t\t\t\t\tsrcSlotValue := sload(srcPtr)\n\t\t\t\t\t\tsrcItemIndexInSlot := 0\n\t\t\t\t\t}\n\t\t\t\t<!srcReadMultiPerSlot>\n\t\t\t\t\tsrcPtr := add(srcPtr, 1)\n\t\t\t\t\tsrcSlotValue := sload(srcPtr)\n\t\t\t\t</srcReadMultiPerSlot>\n\t\t\t\t)\")\n\t\t\t\t(\"srcReadMultiPerSlot\", !sameTypeFromStorage && _fromType.storageStride() <= 16)\n\t\t\t\t(\"srcItemsPerSlot\", std::to_string(32 / _fromType.storageStride()))\n\t\t\t\t.render()\n\t\t\t);\n\t\telse\n\t\t\ttempl(\"updateSrcPtr\", Whiskers(R\"(\n\t\t\t\t\tsrcPtr := add(srcPtr, <srcStride>)\n\t\t\t\t)\")\n\t\t\t\t(\"srcStride\", fromCalldata ? std::to_string(_fromType.calldataStride()) : std::to_string(_fromType.memoryStride()))\n\t\t\t\t.render()\n\t\t\t);\n\n\t\treturn templ.render();\n\t});\n}\n\n\nstd::string YulUtilFunctions::arrayConvertLengthToSize(ArrayType const& _type)\n{\n\tstd::string functionName = \"array_convert_length_to_size_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tType const& baseType = *_type.baseType();\n\n\t\tswitch (_type.location())\n\t\t{\n\t\t\tcase DataLocation::Storage:\n\t\t\t{\n\t\t\t\tunsigned const baseStorageBytes = baseType.storageBytes();\n\t\t\t\tsolAssert(baseStorageBytes > 0, \"\");\n\t\t\t\tsolAssert(32 / baseStorageBytes > 0, \"\");\n\n\t\t\t\treturn Whiskers(R\"(\n\t\t\t\t\tfunction <functionName>(length) -> size {\n\t\t\t\t\t\tsize := length\n\t\t\t\t\t\t<?multiSlot>\n\t\t\t\t\t\t\tsize := <mul>(<storageSize>, length)\n\t\t\t\t\t\t<!multiSlot>\n\t\t\t\t\t\t\t// Number of slots rounded up\n\t\t\t\t\t\t\tsize := div(add(length, sub(<itemsPerSlot>, 1)), <itemsPerSlot>)\n\t\t\t\t\t\t</multiSlot>\n\t\t\t\t\t})\")\n\t\t\t\t\t(\"functionName\", functionName)\n\t\t\t\t\t(\"multiSlot\", baseType.storageSize() > 1)\n\t\t\t\t\t(\"itemsPerSlot\", std::to_string(32 / baseStorageBytes))\n\t\t\t\t\t(\"storageSize\", baseType.storageSize().str())\n\t\t\t\t\t(\"mul\", overflowCheckedIntMulFunction(*TypeProvider::uint256()))\n\t\t\t\t\t.render();\n\t\t\t}\n\t\t\tcase DataLocation::CallData: // fallthrough\n\t\t\tcase DataLocation::Memory:\n\t\t\t\treturn Whiskers(R\"(\n\t\t\t\t\tfunction <functionName>(length) -> size {\n\t\t\t\t\t\t<?byteArray>\n\t\t\t\t\t\t\tsize := length\n\t\t\t\t\t\t<!byteArray>\n\t\t\t\t\t\t\tsize := <mul>(length, <stride>)\n\t\t\t\t\t\t</byteArray>\n\t\t\t\t\t})\")\n\t\t\t\t\t(\"functionName\", functionName)\n\t\t\t\t\t(\"stride\", std::to_string(_type.location() == DataLocation::Memory ? _type.memoryStride() : _type.calldataStride()))\n\t\t\t\t\t(\"byteArray\", _type.isByteArrayOrString())\n\t\t\t\t\t(\"mul\", overflowCheckedIntMulFunction(*TypeProvider::uint256()))\n\t\t\t\t\t.render();\n\t\t\tdefault:\n\t\t\t\tsolAssert(false, \"\");\n\t\t}\n\n\t});\n}\n\nstd::string YulUtilFunctions::arrayAllocationSizeFunction(ArrayType const& _type)\n{\n\tsolAssert(_type.dataStoredIn(DataLocation::Memory), \"\");\n\tstd::string functionName = \"array_allocation_size_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers w(R\"(\n\t\t\tfunction <functionName>(length) -> size {\n\t\t\t\t// Make sure we can allocate memory without overflow\n\t\t\t\tif gt(length, 0xffffffffffffffff) { <panic>() }\n\t\t\t\t<?byteArray>\n\t\t\t\t\tsize := <roundUp>(length)\n\t\t\t\t<!byteArray>\n\t\t\t\t\tsize := mul(length, 0x20)\n\t\t\t\t</byteArray>\n\t\t\t\t<?dynamic>\n\t\t\t\t\t// add length slot\n\t\t\t\t\tsize := add(size, 0x20)\n\t\t\t\t</dynamic>\n\t\t\t}\n\t\t)\");\n\t\tw(\"functionName\", functionName);\n\t\tw(\"panic\", panicFunction(PanicCode::ResourceError));\n\t\tw(\"byteArray\", _type.isByteArrayOrString());\n\t\tw(\"roundUp\", roundUpFunction());\n\t\tw(\"dynamic\", _type.isDynamicallySized());\n\t\treturn w.render();\n\t});\n}\n\nstd::string YulUtilFunctions::arrayDataAreaFunction(ArrayType const& _type)\n{\n\tstd::string functionName = \"array_dataslot_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\t// No special processing for calldata arrays, because they are stored as\n\t\t// offset of the data area and length on the stack, so the offset already\n\t\t// points to the data area.\n\t\t// This might change, if calldata arrays are stored in a single\n\t\t// stack slot at some point.\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(ptr) -> data {\n\t\t\t\tdata := ptr\n\t\t\t\t<?dynamic>\n\t\t\t\t\t<?memory>\n\t\t\t\t\t\tdata := add(ptr, 0x20)\n\t\t\t\t\t</memory>\n\t\t\t\t\t<?storage>\n\t\t\t\t\t\tmstore(0, ptr)\n\t\t\t\t\t\tdata := keccak256(0, 0x20)\n\t\t\t\t\t</storage>\n\t\t\t\t</dynamic>\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"dynamic\", _type.isDynamicallySized())\n\t\t(\"memory\", _type.location() == DataLocation::Memory)\n\t\t(\"storage\", _type.location() == DataLocation::Storage)\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::storageArrayIndexAccessFunction(ArrayType const& _type)\n{\n\tstd::string functionName = \"storage_array_index_access_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(array, index) -> slot, offset {\n\t\t\t\tlet arrayLength := <arrayLen>(array)\n\t\t\t\tif iszero(lt(index, arrayLength)) { <panic>() }\n\n\t\t\t\t<?multipleItemsPerSlot>\n\t\t\t\t\t<?isBytesArray>\n\t\t\t\t\t\tswitch lt(arrayLength, 0x20)\n\t\t\t\t\t\tcase 0 {\n\t\t\t\t\t\t\tslot, offset := <indexAccessNoChecks>(array, index)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault {\n\t\t\t\t\t\t\toffset := sub(31, mod(index, 0x20))\n\t\t\t\t\t\t\tslot := array\n\t\t\t\t\t\t}\n\t\t\t\t\t<!isBytesArray>\n\t\t\t\t\t\tlet dataArea := <dataAreaFunc>(array)\n\t\t\t\t\t\tslot := add(dataArea, div(index, <itemsPerSlot>))\n\t\t\t\t\t\toffset := mul(mod(index, <itemsPerSlot>), <storageBytes>)\n\t\t\t\t\t</isBytesArray>\n\t\t\t\t<!multipleItemsPerSlot>\n\t\t\t\t\tlet dataArea := <dataAreaFunc>(array)\n\t\t\t\t\tslot := add(dataArea, mul(index, <storageSize>))\n\t\t\t\t\toffset := 0\n\t\t\t\t</multipleItemsPerSlot>\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"panic\", panicFunction(PanicCode::ArrayOutOfBounds))\n\t\t(\"arrayLen\", arrayLengthFunction(_type))\n\t\t(\"dataAreaFunc\", arrayDataAreaFunction(_type))\n\t\t(\"indexAccessNoChecks\", longByteArrayStorageIndexAccessNoCheckFunction())\n\t\t(\"multipleItemsPerSlot\", _type.baseType()->storageBytes() <= 16)\n\t\t(\"isBytesArray\", _type.isByteArrayOrString())\n\t\t(\"storageSize\", _type.baseType()->storageSize().str())\n\t\t(\"storageBytes\", toString(_type.baseType()->storageBytes()))\n\t\t(\"itemsPerSlot\", std::to_string(32 / _type.baseType()->storageBytes()))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::memoryArrayIndexAccessFunction(ArrayType const& _type)\n{\n\tstd::string functionName = \"memory_array_index_access_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(baseRef, index) -> addr {\n\t\t\t\tif iszero(lt(index, <arrayLen>(baseRef))) {\n\t\t\t\t\t<panic>()\n\t\t\t\t}\n\n\t\t\t\tlet offset := mul(index, <stride>)\n\t\t\t\t<?dynamicallySized>\n\t\t\t\t\toffset := add(offset, 32)\n\t\t\t\t</dynamicallySized>\n\t\t\t\taddr := add(baseRef, offset)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"panic\", panicFunction(PanicCode::ArrayOutOfBounds))\n\t\t(\"arrayLen\", arrayLengthFunction(_type))\n\t\t(\"stride\", std::to_string(_type.memoryStride()))\n\t\t(\"dynamicallySized\", _type.isDynamicallySized())\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::calldataArrayIndexAccessFunction(ArrayType const& _type)\n{\n\tsolAssert(_type.dataStoredIn(DataLocation::CallData), \"\");\n\tstd::string functionName = \"calldata_array_index_access_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(base_ref<?dynamicallySized>, length</dynamicallySized>, index) -> addr<?dynamicallySizedBase>, len</dynamicallySizedBase> {\n\t\t\t\tif iszero(lt(index, <?dynamicallySized>length<!dynamicallySized><arrayLen></dynamicallySized>)) { <panic>() }\n\t\t\t\taddr := add(base_ref, mul(index, <stride>))\n\t\t\t\t<?dynamicallyEncodedBase>\n\t\t\t\t\taddr<?dynamicallySizedBase>, len</dynamicallySizedBase> := <accessCalldataTail>(base_ref, addr)\n\t\t\t\t</dynamicallyEncodedBase>\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"panic\", panicFunction(PanicCode::ArrayOutOfBounds))\n\t\t(\"stride\", std::to_string(_type.calldataStride()))\n\t\t(\"dynamicallySized\", _type.isDynamicallySized())\n\t\t(\"dynamicallyEncodedBase\", _type.baseType()->isDynamicallyEncoded())\n\t\t(\"dynamicallySizedBase\", _type.baseType()->isDynamicallySized())\n\t\t(\"arrayLen\",  toCompactHexWithPrefix(_type.length()))\n\t\t(\"accessCalldataTail\", _type.baseType()->isDynamicallyEncoded() ? accessCalldataTailFunction(*_type.baseType()): \"\")\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::calldataArrayIndexRangeAccess(ArrayType const& _type)\n{\n\tsolAssert(_type.dataStoredIn(DataLocation::CallData), \"\");\n\tsolAssert(_type.isDynamicallySized(), \"\");\n\tstd::string functionName = \"calldata_array_index_range_access_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(offset, length, startIndex, endIndex) -> offsetOut, lengthOut {\n\t\t\t\tif gt(startIndex, endIndex) { <revertSliceStartAfterEnd>() }\n\t\t\t\tif gt(endIndex, length) { <revertSliceGreaterThanLength>() }\n\t\t\t\toffsetOut := add(offset, mul(startIndex, <stride>))\n\t\t\t\tlengthOut := sub(endIndex, startIndex)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"stride\", std::to_string(_type.calldataStride()))\n\t\t(\"revertSliceStartAfterEnd\", revertReasonIfDebugFunction(\"Slice starts after end\"))\n\t\t(\"revertSliceGreaterThanLength\", revertReasonIfDebugFunction(\"Slice is greater than length\"))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::accessCalldataTailFunction(Type const& _type)\n{\n\tsolAssert(_type.isDynamicallyEncoded(), \"\");\n\tsolAssert(_type.dataStoredIn(DataLocation::CallData), \"\");\n\tstd::string functionName = \"access_calldata_tail_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(base_ref, ptr_to_tail) -> addr<?dynamicallySized>, length</dynamicallySized> {\n\t\t\t\tlet rel_offset_of_tail := calldataload(ptr_to_tail)\n\t\t\t\tif iszero(slt(rel_offset_of_tail, sub(sub(calldatasize(), base_ref), sub(<neededLength>, 1)))) { <invalidCalldataTailOffset>() }\n\t\t\t\taddr := add(base_ref, rel_offset_of_tail)\n\t\t\t\t<?dynamicallySized>\n\t\t\t\t\tlength := calldataload(addr)\n\t\t\t\t\tif gt(length, 0xffffffffffffffff) { <invalidCalldataTailLength>() }\n\t\t\t\t\taddr := add(addr, 32)\n\t\t\t\t\tif sgt(addr, sub(calldatasize(), mul(length, <calldataStride>))) { <shortCalldataTail>() }\n\t\t\t\t</dynamicallySized>\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"dynamicallySized\", _type.isDynamicallySized())\n\t\t(\"neededLength\", toCompactHexWithPrefix(_type.calldataEncodedTailSize()))\n\t\t(\"calldataStride\", toCompactHexWithPrefix(_type.isDynamicallySized() ? dynamic_cast<ArrayType const&>(_type).calldataStride() : 0))\n\t\t(\"invalidCalldataTailOffset\", revertReasonIfDebugFunction(\"Invalid calldata tail offset\"))\n\t\t(\"invalidCalldataTailLength\", revertReasonIfDebugFunction(\"Invalid calldata tail length\"))\n\t\t(\"shortCalldataTail\", revertReasonIfDebugFunction(\"Calldata tail too short\"))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::nextArrayElementFunction(ArrayType const& _type)\n{\n\tsolAssert(!_type.isByteArrayOrString(), \"\");\n\tif (_type.dataStoredIn(DataLocation::Storage))\n\t\tsolAssert(_type.baseType()->storageBytes() > 16, \"\");\n\tstd::string functionName = \"array_nextElement_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(ptr) -> next {\n\t\t\t\tnext := add(ptr, <advance>)\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\tswitch (_type.location())\n\t\t{\n\t\tcase DataLocation::Memory:\n\t\t\ttempl(\"advance\", \"0x20\");\n\t\t\tbreak;\n\t\tcase DataLocation::Storage:\n\t\t{\n\t\t\tu256 size = _type.baseType()->storageSize();\n\t\t\tsolAssert(size >= 1, \"\");\n\t\t\ttempl(\"advance\", toCompactHexWithPrefix(size));\n\t\t\tbreak;\n\t\t}\n\t\tcase DataLocation::Transient:\n\t\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\t\tbreak;\n\t\tcase DataLocation::CallData:\n\t\t{\n\t\t\tu256 size = _type.calldataStride();\n\t\t\tsolAssert(size >= 32 && size % 32 == 0, \"\");\n\t\t\ttempl(\"advance\", toCompactHexWithPrefix(size));\n\t\t\tbreak;\n\t\t}\n\t\t}\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::copyArrayFromStorageToMemoryFunction(ArrayType const& _from, ArrayType const& _to)\n{\n\tsolAssert(_from.dataStoredIn(DataLocation::Storage), \"\");\n\tsolAssert(_to.dataStoredIn(DataLocation::Memory), \"\");\n\tsolAssert(_from.isDynamicallySized() == _to.isDynamicallySized(), \"\");\n\tif (!_from.isDynamicallySized())\n\t\tsolAssert(_from.length() == _to.length(), \"\");\n\n\tstd::string functionName = \"copy_array_from_storage_to_memory_\" + _from.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tif (_from.baseType()->isValueType())\n\t\t{\n\t\t\tsolAssert(*_from.baseType() == *_to.baseType(), \"\");\n\t\t\tABIFunctions abi(m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector);\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(slot) -> memPtr {\n\t\t\t\t\tmemPtr := <allocateUnbounded>()\n\t\t\t\t\tlet end := <encode>(slot, memPtr)\n\t\t\t\t\t<finalizeAllocation>(memPtr, sub(end, memPtr))\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"allocateUnbounded\", allocateUnboundedFunction())\n\t\t\t(\n\t\t\t\t\"encode\",\n\t\t\t\tabi.abiEncodeAndReturnUpdatedPosFunction(_from, _to, ABIFunctions::EncodingOptions{})\n\t\t\t)\n\t\t\t(\"finalizeAllocation\", finalizeAllocationFunction())\n\t\t\t.render();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(_to.memoryStride() == 32, \"\");\n\t\t\tsolAssert(_to.baseType()->dataStoredIn(DataLocation::Memory), \"\");\n\t\t\tsolAssert(_from.baseType()->dataStoredIn(DataLocation::Storage), \"\");\n\t\t\tsolAssert(!_from.isByteArrayOrString(), \"\");\n\t\t\tsolAssert(*_to.withLocation(DataLocation::Storage, _from.isPointer()) == _from, \"\");\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(slot) -> memPtr {\n\t\t\t\t\tlet length := <lengthFunction>(slot)\n\t\t\t\t\tmemPtr := <allocateArray>(length)\n\t\t\t\t\tlet mpos := memPtr\n\t\t\t\t\t<?dynamic>mpos := add(mpos, 0x20)</dynamic>\n\t\t\t\t\tlet spos := <arrayDataArea>(slot)\n\t\t\t\t\tfor { let i := 0 } lt(i, length) { i := add(i, 1) } {\n\t\t\t\t\t\tmstore(mpos, <convert>(spos))\n\t\t\t\t\t\tmpos := add(mpos, 0x20)\n\t\t\t\t\t\tspos := add(spos, <baseStorageSize>)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"lengthFunction\", arrayLengthFunction(_from))\n\t\t\t(\"allocateArray\", allocateMemoryArrayFunction(_to))\n\t\t\t(\"arrayDataArea\", arrayDataAreaFunction(_from))\n\t\t\t(\"dynamic\", _to.isDynamicallySized())\n\t\t\t(\"convert\", conversionFunction(*_from.baseType(), *_to.baseType()))\n\t\t\t(\"baseStorageSize\", _from.baseType()->storageSize().str())\n\t\t\t.render();\n\t\t}\n\t});\n}\n\nstd::string YulUtilFunctions::bytesOrStringConcatFunction(\n\tstd::vector<Type const*> const& _argumentTypes,\n\tFunctionType::Kind _functionTypeKind\n)\n{\n\tsolAssert(_functionTypeKind == FunctionType::Kind::BytesConcat || _functionTypeKind == FunctionType::Kind::StringConcat);\n\tstd::string functionName = (_functionTypeKind == FunctionType::Kind::StringConcat) ? \"string_concat\" : \"bytes_concat\";\n\tsize_t totalParams = 0;\n\tstd::vector<Type const*> targetTypes;\n\n\tfor (Type const* argumentType: _argumentTypes)\n\t{\n\t\tif (_functionTypeKind == FunctionType::Kind::StringConcat)\n\t\t\tsolAssert(argumentType->isImplicitlyConvertibleTo(*TypeProvider::stringMemory()));\n\t\telse if (_functionTypeKind == FunctionType::Kind::BytesConcat)\n\t\t\tsolAssert(\n\t\t\t\targumentType->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()) ||\n\t\t\t\targumentType->isImplicitlyConvertibleTo(*TypeProvider::fixedBytes(32))\n\t\t\t);\n\n\t\tif (argumentType->category() == Type::Category::FixedBytes)\n\t\t\ttargetTypes.emplace_back(argumentType);\n\t\telse if (\n\t\t\tauto const* literalType = dynamic_cast<StringLiteralType const*>(argumentType);\n\t\t\tliteralType && !literalType->value().empty() && literalType->value().size() <= 32\n\t\t)\n\t\t\ttargetTypes.emplace_back(TypeProvider::fixedBytes(static_cast<unsigned>(literalType->value().size())));\n\t\telse\n\t\t{\n\t\t\tsolAssert(!dynamic_cast<RationalNumberType const*>(argumentType));\n\t\t\ttargetTypes.emplace_back(\n\t\t\t\t_functionTypeKind == FunctionType::Kind::StringConcat ?\n\t\t\t\tTypeProvider::stringMemory() :\n\t\t\t\tTypeProvider::bytesMemory()\n\t\t\t);\n\t\t}\n\t\ttotalParams += argumentType->sizeOnStack();\n\t\tfunctionName += \"_\" + argumentType->identifier();\n\t}\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(<parameters>) -> outPtr {\n\t\t\t\toutPtr := <allocateUnbounded>()\n\t\t\t\tlet dataStart := add(outPtr, 0x20)\n\t\t\t\tlet dataEnd := <encodePacked>(dataStart<?+parameters>, <parameters></+parameters>)\n\t\t\t\tmstore(outPtr, sub(dataEnd, dataStart))\n\t\t\t\t<finalizeAllocation>(outPtr, sub(dataEnd, outPtr))\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"parameters\", suffixedVariableNameList(\"param_\", 0, totalParams));\n\t\ttempl(\"allocateUnbounded\", allocateUnboundedFunction());\n\t\ttempl(\"finalizeAllocation\", finalizeAllocationFunction());\n\t\ttempl(\n\t\t\t\"encodePacked\",\n\t\t\tABIFunctions{m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector}.tupleEncoderPacked(\n\t\t\t\t_argumentTypes,\n\t\t\t\ttargetTypes\n\t\t\t)\n\t\t);\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::mappingIndexAccessFunction(MappingType const& _mappingType, Type const& _keyType)\n{\n\tstd::string functionName = \"mapping_index_access_\" + _mappingType.identifier() + \"_of_\" + _keyType.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tif (_mappingType.keyType()->isDynamicallySized())\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(slot <?+key>,</+key> <key>) -> dataSlot {\n\t\t\t\t\tdataSlot := <hash>(<key> <?+key>,</+key> slot)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"key\", suffixedVariableNameList(\"key_\", 0, _keyType.sizeOnStack()))\n\t\t\t(\"hash\", packedHashFunction(\n\t\t\t\t{&_keyType, TypeProvider::uint256()},\n\t\t\t\t{_mappingType.keyType(), TypeProvider::uint256()}\n\t\t\t))\n\t\t\t.render();\n\t\telse\n\t\t{\n\t\t\tsolAssert(CompilerUtils::freeMemoryPointer >= 0x40, \"\");\n\t\t\tsolAssert(!_mappingType.keyType()->isDynamicallyEncoded(), \"\");\n\t\t\tsolAssert(_mappingType.keyType()->calldataEncodedSize(false) <= 0x20, \"\");\n\t\t\tWhiskers templ(R\"(\n\t\t\t\tfunction <functionName>(slot <key>) -> dataSlot {\n\t\t\t\t\tmstore(0, <convertedKey>)\n\t\t\t\t\tmstore(0x20, slot)\n\t\t\t\t\tdataSlot := keccak256(0, 0x40)\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\ttempl(\"key\", _keyType.sizeOnStack() == 1 ? \", key\" : \"\");\n\t\t\tif (_keyType.sizeOnStack() == 0)\n\t\t\t\ttempl(\"convertedKey\", conversionFunction(_keyType, *_mappingType.keyType()) + \"()\");\n\t\t\telse\n\t\t\t\ttempl(\"convertedKey\", conversionFunction(_keyType, *_mappingType.keyType()) + \"(key)\");\n\t\t\treturn templ.render();\n\t\t}\n\t});\n}\n\nstd::string YulUtilFunctions::readFromStorage(\n\tType const& _type,\n\tsize_t _offset,\n\tbool _splitFunctionTypes,\n\tVariableDeclaration::Location _location\n)\n{\n\tif (_type.isValueType())\n\t\treturn readFromStorageValueType(_type, _offset, _splitFunctionTypes, _location);\n\telse\n\t{\n\t\tsolAssert(_location != VariableDeclaration::Location::Transient);\n\t\tsolAssert(_offset == 0, \"\");\n\t\treturn readFromStorageReferenceType(_type);\n\t}\n}\n\nstd::string YulUtilFunctions::readFromStorageDynamic(\n\tType const& _type,\n\tbool _splitFunctionTypes,\n\tVariableDeclaration::Location _location\n)\n{\n\tif (_type.isValueType())\n\t\treturn readFromStorageValueType(_type, {}, _splitFunctionTypes, _location);\n\n\tsolAssert(_location != VariableDeclaration::Location::Transient);\n\tstd::string functionName =\n\t\t\"read_from_storage__dynamic_\" +\n\t\tstd::string(_splitFunctionTypes ? \"split_\" : \"\") +\n\t\t_type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(slot, offset) -> value {\n\t\t\t\tif gt(offset, 0) { <panic>() }\n\t\t\t\tvalue := <readFromStorage>(slot)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"panic\", panicFunction(util::PanicCode::Generic))\n\t\t(\"readFromStorage\", readFromStorageReferenceType(_type))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::readFromStorageValueType(\n\tType const& _type,\n\tstd::optional<size_t> _offset,\n\tbool _splitFunctionTypes,\n\tVariableDeclaration::Location _location\n)\n{\n\tsolAssert(_type.isValueType(), \"\");\n\tsolAssert(\n\t\t_location == VariableDeclaration::Location::Transient ||\n\t\t_location == VariableDeclaration::Location::Unspecified,\n\t\t\"Variable location can only be transient or plain storage\"\n\t);\n\n\tstd::string functionName =\n\t\t\"read_from_\" +\n\t\t(_location == VariableDeclaration::Location::Transient ? \"transient_\"s : \"\") +\n\t\t\"storage_\" +\n\t\tstd::string(_splitFunctionTypes ? \"split_\" : \"\") + (\n\t\t\t_offset.has_value() ?\n\t\t\t\"offset_\" + std::to_string(*_offset) :\n\t\t\t\"dynamic\"\n\t\t) +\n\t\t\"_\" +\n\t\t_type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(slot<?dynamic>, offset</dynamic>) -> <?split>addr, selector<!split>value</split> {\n\t\t\t\t<?split>let</split> value := <extract>(<loadOpcode>(slot)<?dynamic>, offset</dynamic>)\n\t\t\t\t<?split>\n\t\t\t\t\taddr, selector := <splitFunction>(value)\n\t\t\t\t</split>\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"dynamic\", !_offset.has_value());\n\t\ttempl(\"loadOpcode\", _location == VariableDeclaration::Location::Transient ? \"tload\" : \"sload\");\n\t\tif (_offset.has_value())\n\t\t\ttempl(\"extract\", extractFromStorageValue(_type, *_offset));\n\t\telse\n\t\t\ttempl(\"extract\", extractFromStorageValueDynamic(_type));\n\t\tauto const* funType = dynamic_cast<FunctionType const*>(&_type);\n\t\tbool split = _splitFunctionTypes && funType && funType->kind() == FunctionType::Kind::External;\n\t\ttempl(\"split\", split);\n\t\tif (split)\n\t\t\ttempl(\"splitFunction\", splitExternalFunctionIdFunction());\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::readFromStorageReferenceType(Type const& _type)\n{\n\tif (auto const* arrayType = dynamic_cast<ArrayType const*>(&_type))\n\t{\n\t\tsolAssert(arrayType->dataStoredIn(DataLocation::Memory), \"\");\n\t\treturn copyArrayFromStorageToMemoryFunction(\n\t\t\tdynamic_cast<ArrayType const&>(*arrayType->copyForLocation(DataLocation::Storage, false)),\n\t\t\t*arrayType\n\t\t);\n\t}\n\tsolAssert(_type.category() == Type::Category::Struct, \"\");\n\n\tstd::string functionName = \"read_from_storage_reference_type_\" + _type.identifier();\n\n\tauto const& structType = dynamic_cast<StructType const&>(_type);\n\tsolAssert(structType.location() == DataLocation::Memory, \"\");\n\tMemberList::MemberMap structMembers = structType.nativeMembers(nullptr);\n\tstd::vector<std::map<std::string, std::string>> memberSetValues(structMembers.size());\n\tfor (size_t i = 0; i < structMembers.size(); ++i)\n\t{\n\t\tauto const& [memberSlotDiff, memberStorageOffset] = structType.storageOffsetsOfMember(structMembers[i].name);\n\t\tsolAssert(structMembers[i].type->isValueType() || memberStorageOffset == 0, \"\");\n\n\t\tmemberSetValues[i][\"setMember\"] = Whiskers(R\"(\n\t\t\t{\n\t\t\t\tlet <memberValues> := <readFromStorage>(add(slot, <memberSlotDiff>))\n\t\t\t\t<writeToMemory>(add(value, <memberMemoryOffset>), <memberValues>)\n\t\t\t}\n\t\t)\")\n\t\t(\"memberValues\", suffixedVariableNameList(\"memberValue_\", 0, structMembers[i].type->stackItems().size()))\n\t\t(\"memberMemoryOffset\", structType.memoryOffsetOfMember(structMembers[i].name).str())\n\t\t(\"memberSlotDiff\",  memberSlotDiff.str())\n\t\t(\"readFromStorage\", readFromStorage(*structMembers[i].type, memberStorageOffset, true, VariableDeclaration::Location::Unspecified))\n\t\t(\"writeToMemory\", writeToMemoryFunction(*structMembers[i].type))\n\t\t.render();\n\t}\n\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(slot) -> value {\n\t\t\t\tvalue := <allocStruct>()\n\t\t\t\t<#member>\n\t\t\t\t\t<setMember>\n\t\t\t\t</member>\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"allocStruct\", allocateMemoryStructFunction(structType))\n\t\t(\"member\", memberSetValues)\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::readFromMemory(Type const& _type)\n{\n\treturn readFromMemoryOrCalldata(_type, false);\n}\n\nstd::string YulUtilFunctions::readFromCalldata(Type const& _type)\n{\n\treturn readFromMemoryOrCalldata(_type, true);\n}\n\nstd::string YulUtilFunctions::updateStorageValueFunction(\n\tType const& _fromType,\n\tType const& _toType,\n\tVariableDeclaration::Location _location,\n\tstd::optional<unsigned> const& _offset\n)\n{\n\tsolAssert(\n\t\t_location == VariableDeclaration::Location::Transient ||\n\t\t_location == VariableDeclaration::Location::Unspecified,\n\t\t\"Variable location can only be transient or plain storage\"\n\t);\n\n\tstd::string const functionName =\n\t\t\"update_\" +\n\t\t(_location == VariableDeclaration::Location::Transient ? \"transient_\"s : \"\") +\n\t\t\"storage_value_\" +\n\t\t(_offset.has_value() ? (\"offset_\" + std::to_string(*_offset)) + \"_\" : \"\") +\n\t\t_fromType.identifier() +\n\t\t\"_to_\" +\n\t\t_toType.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\tif (_toType.isValueType())\n\t\t{\n\t\t\tsolAssert(_fromType.isImplicitlyConvertibleTo(_toType), \"\");\n\t\t\tsolAssert(_toType.storageBytes() <= 32, \"Invalid storage bytes size.\");\n\t\t\tsolAssert(_toType.storageBytes() > 0, \"Invalid storage bytes size.\");\n\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(slot, <offset><fromValues>) {\n\t\t\t\t\tlet <toValues> := <convert>(<fromValues>)\n\t\t\t\t\t<storeOpcode>(slot, <update>(<loadOpcode>(slot), <offset><prepare>(<toValues>)))\n\t\t\t\t}\n\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"update\",\n\t\t\t\t_offset.has_value() ?\n\t\t\t\t\tupdateByteSliceFunction(_toType.storageBytes(), *_offset) :\n\t\t\t\t\tupdateByteSliceFunctionDynamic(_toType.storageBytes())\n\t\t\t)\n\t\t\t(\"offset\", _offset.has_value() ? \"\" : \"offset, \")\n\t\t\t(\"convert\", conversionFunction(_fromType, _toType))\n\t\t\t(\"fromValues\", suffixedVariableNameList(\"value_\", 0, _fromType.sizeOnStack()))\n\t\t\t(\"toValues\", suffixedVariableNameList(\"convertedValue_\", 0, _toType.sizeOnStack()))\n\t\t\t(\"storeOpcode\", _location == VariableDeclaration::Location::Transient ? \"tstore\" : \"sstore\")\n\t\t\t(\"loadOpcode\", _location == VariableDeclaration::Location::Transient ? \"tload\" : \"sload\")\n\t\t\t(\"prepare\", prepareStoreFunction(_toType))\n\t\t\t.render();\n\t\t}\n\n\t\tsolAssert(_location != VariableDeclaration::Location::Transient);\n\t\tauto const* toReferenceType = dynamic_cast<ReferenceType const*>(&_toType);\n\t\tauto const* fromReferenceType = dynamic_cast<ReferenceType const*>(&_fromType);\n\t\tsolAssert(toReferenceType, \"\");\n\n\t\tif (!fromReferenceType)\n\t\t{\n\t\t\tsolAssert(_fromType.category() == Type::Category::StringLiteral, \"\");\n\t\t\tsolAssert(toReferenceType->category() == Type::Category::Array, \"\");\n\t\t\tauto const& toArrayType = dynamic_cast<ArrayType const&>(*toReferenceType);\n\t\t\tsolAssert(toArrayType.isByteArrayOrString(), \"\");\n\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(slot<?dynamicOffset>, offset</dynamicOffset>) {\n\t\t\t\t\t<?dynamicOffset>if offset { <panic>() }</dynamicOffset>\n\t\t\t\t\t<copyToStorage>(slot)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"dynamicOffset\", !_offset.has_value())\n\t\t\t(\"panic\", panicFunction(PanicCode::Generic))\n\t\t\t(\"copyToStorage\", copyLiteralToStorageFunction(dynamic_cast<StringLiteralType const&>(_fromType).value()))\n\t\t\t.render();\n\t\t}\n\n\t\tsolAssert((*toReferenceType->copyForLocation(\n\t\t\tfromReferenceType->location(),\n\t\t\tfromReferenceType->isPointer()\n\t\t).get()).equals(*fromReferenceType), \"\");\n\n\t\tif (fromReferenceType->category() == Type::Category::ArraySlice)\n\t\t\tsolAssert(toReferenceType->category() == Type::Category::Array, \"\");\n\t\telse\n\t\t\tsolAssert(toReferenceType->category() == fromReferenceType->category(), \"\");\n\t\tsolAssert(_offset.value_or(0) == 0, \"\");\n\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(slot, <?dynamicOffset>offset, </dynamicOffset><value>) {\n\t\t\t\t<?dynamicOffset>if offset { <panic>() }</dynamicOffset>\n\t\t\t\t<copyToStorage>(slot, <value>)\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"dynamicOffset\", !_offset.has_value());\n\t\ttempl(\"panic\", panicFunction(PanicCode::Generic));\n\t\ttempl(\"value\", suffixedVariableNameList(\"value_\", 0, _fromType.sizeOnStack()));\n\t\tif (_fromType.category() == Type::Category::Array)\n\t\t\ttempl(\"copyToStorage\", copyArrayToStorageFunction(\n\t\t\t\tdynamic_cast<ArrayType const&>(_fromType),\n\t\t\t\tdynamic_cast<ArrayType const&>(_toType)\n\t\t\t));\n\t\telse if (_fromType.category() == Type::Category::ArraySlice)\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\t_fromType.dataStoredIn(DataLocation::CallData),\n\t\t\t\t\"Currently only calldata array slices are supported!\"\n\t\t\t);\n\t\t\ttempl(\"copyToStorage\", copyArrayToStorageFunction(\n\t\t\t\tdynamic_cast<ArraySliceType const&>(_fromType).arrayType(),\n\t\t\t\tdynamic_cast<ArrayType const&>(_toType)\n\t\t\t));\n\t\t}\n\t\telse\n\t\t\ttempl(\"copyToStorage\", copyStructToStorageFunction(\n\t\t\t\tdynamic_cast<StructType const&>(_fromType),\n\t\t\t\tdynamic_cast<StructType const&>(_toType)\n\t\t\t));\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::writeToMemoryFunction(Type const& _type)\n{\n\tstd::string const functionName = \"write_to_memory_\" + _type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\tsolAssert(!dynamic_cast<StringLiteralType const*>(&_type), \"\");\n\t\tif (auto ref = dynamic_cast<ReferenceType const*>(&_type))\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\tref->location() == DataLocation::Memory,\n\t\t\t\t\"Can only update types with location memory.\"\n\t\t\t);\n\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(memPtr, value) {\n\t\t\t\t\tmstore(memPtr, value)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t.render();\n\t\t}\n\t\telse if (\n\t\t\t_type.category() == Type::Category::Function &&\n\t\t\tdynamic_cast<FunctionType const&>(_type).kind() == FunctionType::Kind::External\n\t\t)\n\t\t{\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(memPtr, addr, selector) {\n\t\t\t\t\tmstore(memPtr, <combine>(addr, selector))\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"combine\", combineExternalFunctionIdFunction())\n\t\t\t.render();\n\t\t}\n\t\telse if (_type.isValueType())\n\t\t{\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(memPtr, value) {\n\t\t\t\t\tmstore(memPtr, <cleanup>(value))\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"cleanup\", cleanupFunction(_type))\n\t\t\t.render();\n\t\t}\n\t\telse // Should never happen\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\tfalse,\n\t\t\t\t\"Memory store of type \" + _type.toString(true) + \" not allowed.\"\n\t\t\t);\n\t\t}\n\t});\n}\n\nstd::string YulUtilFunctions::extractFromStorageValueDynamic(Type const& _type)\n{\n\tstd::string functionName =\n\t\t\"extract_from_storage_value_dynamic\" +\n\t\t_type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(slot_value, offset) -> value {\n\t\t\t\tvalue := <cleanupStorage>(<shr>(mul(offset, 8), slot_value))\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"shr\", shiftRightFunctionDynamic())\n\t\t(\"cleanupStorage\", cleanupFromStorageFunction(_type))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::extractFromStorageValue(Type const& _type, size_t _offset)\n{\n\tstd::string functionName = \"extract_from_storage_value_offset_\" + std::to_string(_offset) + \"_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(slot_value) -> value {\n\t\t\t\tvalue := <cleanupStorage>(<shr>(slot_value))\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"shr\", shiftRightFunction(_offset * 8))\n\t\t(\"cleanupStorage\", cleanupFromStorageFunction(_type))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::cleanupFromStorageFunction(Type const& _type)\n{\n\tsolAssert(_type.isValueType(), \"\");\n\n\tstd::string functionName = std::string(\"cleanup_from_storage_\") + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(value) -> cleaned {\n\t\t\t\tcleaned := <cleaned>\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\n\t\tType const* encodingType = &_type;\n\t\tif (_type.category() == Type::Category::UserDefinedValueType)\n\t\t\tencodingType = _type.encodingType();\n\t\tunsigned storageBytes = encodingType->storageBytes();\n\t\tif (IntegerType const* intType = dynamic_cast<IntegerType const*>(encodingType))\n\t\t\tif (intType->isSigned() && storageBytes != 32)\n\t\t\t{\n\t\t\t\ttempl(\"cleaned\", \"signextend(\" + std::to_string(storageBytes - 1) + \", value)\");\n\t\t\t\treturn templ.render();\n\t\t\t}\n\n\t\tif (storageBytes == 32)\n\t\t\ttempl(\"cleaned\", \"value\");\n\t\telse if (encodingType->leftAligned())\n\t\t\ttempl(\"cleaned\", shiftLeftFunction(256 - 8 * storageBytes) + \"(value)\");\n\t\telse\n\t\t\ttempl(\"cleaned\", \"and(value, \" + toCompactHexWithPrefix((u256(1) << (8 * storageBytes)) - 1) + \")\");\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::prepareStoreFunction(Type const& _type)\n{\n\tstd::string functionName = \"prepare_store_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tsolAssert(_type.isValueType(), \"\");\n\t\tauto const* funType = dynamic_cast<FunctionType const*>(&_type);\n\t\tif (funType && funType->kind() == FunctionType::Kind::External)\n\t\t{\n\t\t\tWhiskers templ(R\"(\n\t\t\t\tfunction <functionName>(addr, selector) -> ret {\n\t\t\t\t\tret := <prepareBytes>(<combine>(addr, selector))\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\ttempl(\"prepareBytes\", prepareStoreFunction(*TypeProvider::fixedBytes(24)));\n\t\t\ttempl(\"combine\", combineExternalFunctionIdFunction());\n\t\t\treturn templ.render();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(_type.sizeOnStack() == 1, \"\");\n\t\t\tWhiskers templ(R\"(\n\t\t\t\tfunction <functionName>(value) -> ret {\n\t\t\t\t\tret := <actualPrepare>\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\tif (_type.leftAligned())\n\t\t\t\ttempl(\"actualPrepare\", shiftRightFunction(256 - 8 * _type.storageBytes()) + \"(value)\");\n\t\t\telse\n\t\t\t\ttempl(\"actualPrepare\", \"value\");\n\t\t\treturn templ.render();\n\t\t}\n\t});\n}\n\nstd::string YulUtilFunctions::allocationFunction()\n{\n\tstd::string functionName = \"allocate_memory\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(size) -> memPtr {\n\t\t\t\tmemPtr := <allocateUnbounded>()\n\t\t\t\t<finalizeAllocation>(memPtr, size)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"allocateUnbounded\", allocateUnboundedFunction())\n\t\t(\"finalizeAllocation\", finalizeAllocationFunction())\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::allocateUnboundedFunction()\n{\n\tstd::string functionName = \"allocate_unbounded\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>() -> memPtr {\n\t\t\t\tmemPtr := mload(<freeMemoryPointer>)\n\t\t\t}\n\t\t)\")\n\t\t(\"freeMemoryPointer\", std::to_string(CompilerUtils::freeMemoryPointer))\n\t\t(\"functionName\", functionName)\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::finalizeAllocationFunction()\n{\n\tstd::string functionName = \"finalize_allocation\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(memPtr, size) {\n\t\t\t\tlet newFreePtr := add(memPtr, <roundUp>(size))\n\t\t\t\t// protect against overflow\n\t\t\t\tif or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { <panic>() }\n\t\t\t\tmstore(<freeMemoryPointer>, newFreePtr)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"freeMemoryPointer\", std::to_string(CompilerUtils::freeMemoryPointer))\n\t\t(\"roundUp\", roundUpFunction())\n\t\t(\"panic\", panicFunction(PanicCode::ResourceError))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::zeroMemoryArrayFunction(ArrayType const& _type)\n{\n\tif (_type.baseType()->hasSimpleZeroValueInMemory())\n\t\treturn zeroMemoryFunction(*_type.baseType());\n\treturn zeroComplexMemoryArrayFunction(_type);\n}\n\nstd::string YulUtilFunctions::zeroMemoryFunction(Type const& _type)\n{\n\tsolAssert(_type.hasSimpleZeroValueInMemory(), \"\");\n\n\tstd::string functionName = \"zero_memory_chunk_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(dataStart, dataSizeInBytes) {\n\t\t\t\tcalldatacopy(dataStart, calldatasize(), dataSizeInBytes)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::zeroComplexMemoryArrayFunction(ArrayType const& _type)\n{\n\tsolAssert(!_type.baseType()->hasSimpleZeroValueInMemory(), \"\");\n\n\tstd::string functionName = \"zero_complex_memory_array_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tsolAssert(_type.memoryStride() == 32, \"\");\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(dataStart, dataSizeInBytes) {\n\t\t\t\tfor {let i := 0} lt(i, dataSizeInBytes) { i := add(i, <stride>) } {\n\t\t\t\t\tmstore(add(dataStart, i), <zeroValue>())\n\t\t\t\t}\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"stride\", std::to_string(_type.memoryStride()))\n\t\t(\"zeroValue\", zeroValueFunction(*_type.baseType(), false))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::allocateMemoryArrayFunction(ArrayType const& _type)\n{\n\tstd::string functionName = \"allocate_memory_array_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(length) -> memPtr {\n\t\t\t\t\tlet allocSize := <allocSize>(length)\n\t\t\t\t\tmemPtr := <alloc>(allocSize)\n\t\t\t\t\t<?dynamic>\n\t\t\t\t\tmstore(memPtr, length)\n\t\t\t\t\t</dynamic>\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"alloc\", allocationFunction())\n\t\t\t(\"allocSize\", arrayAllocationSizeFunction(_type))\n\t\t\t(\"dynamic\", _type.isDynamicallySized())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::allocateAndInitializeMemoryArrayFunction(ArrayType const& _type)\n{\n\tstd::string functionName = \"allocate_and_zero_memory_array_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(length) -> memPtr {\n\t\t\t\t\tmemPtr := <allocArray>(length)\n\t\t\t\t\tlet dataStart := memPtr\n\t\t\t\t\tlet dataSize := <allocSize>(length)\n\t\t\t\t\t<?dynamic>\n\t\t\t\t\tdataStart := add(dataStart, 32)\n\t\t\t\t\tdataSize := sub(dataSize, 32)\n\t\t\t\t\t</dynamic>\n\t\t\t\t\t<zeroArrayFunction>(dataStart, dataSize)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"allocArray\", allocateMemoryArrayFunction(_type))\n\t\t\t(\"allocSize\", arrayAllocationSizeFunction(_type))\n\t\t\t(\"zeroArrayFunction\", zeroMemoryArrayFunction(_type))\n\t\t\t(\"dynamic\", _type.isDynamicallySized())\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::allocateMemoryStructFunction(StructType const& _type)\n{\n\tstd::string functionName = \"allocate_memory_struct_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\tfunction <functionName>() -> memPtr {\n\t\t\tmemPtr := <alloc>(<allocSize>)\n\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"alloc\", allocationFunction());\n\t\ttempl(\"allocSize\", _type.memoryDataSize().str());\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::allocateAndInitializeMemoryStructFunction(StructType const& _type)\n{\n\tstd::string functionName = \"allocate_and_zero_memory_struct_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\tfunction <functionName>() -> memPtr {\n\t\t\tmemPtr := <allocStruct>()\n\t\t\tlet offset := memPtr\n\t\t\t<#member>\n\t\t\t\tmstore(offset, <zeroValue>())\n\t\t\t\toffset := add(offset, 32)\n\t\t\t</member>\n\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"allocStruct\", allocateMemoryStructFunction(_type));\n\n\t\tTypePointers const& members = _type.memoryMemberTypes();\n\n\t\tstd::vector<std::map<std::string, std::string>> memberParams(members.size());\n\t\tfor (size_t i = 0; i < members.size(); ++i)\n\t\t{\n\t\t\tsolAssert(members[i]->memoryHeadSize() == 32, \"\");\n\t\t\tmemberParams[i][\"zeroValue\"] = zeroValueFunction(\n\t\t\t\t*TypeProvider::withLocationIfReference(DataLocation::Memory, members[i]),\n\t\t\t\tfalse\n\t\t\t);\n\t\t}\n\t\ttempl(\"member\", memberParams);\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)\n{\n\tif (_from.category() == Type::Category::UserDefinedValueType)\n\t{\n\t\tsolAssert(_from == _to || _to == dynamic_cast<UserDefinedValueType const&>(_from).underlyingType(), \"\");\n\t\treturn conversionFunction(dynamic_cast<UserDefinedValueType const&>(_from).underlyingType(), _to);\n\t}\n\tif (_to.category() == Type::Category::UserDefinedValueType)\n\t{\n\t\tsolAssert(_from == _to || _from.isImplicitlyConvertibleTo(dynamic_cast<UserDefinedValueType const&>(_to).underlyingType()), \"\");\n\t\treturn conversionFunction(_from, dynamic_cast<UserDefinedValueType const&>(_to).underlyingType());\n\t}\n\tif (_from.category() == Type::Category::Function)\n\t{\n\t\tsolAssert(_to.category() == Type::Category::Function, \"\");\n\t\tFunctionType const& fromType = dynamic_cast<FunctionType const&>(_from);\n\t\tFunctionType const& targetType = dynamic_cast<FunctionType const&>(_to);\n\t\tsolAssert(\n\t\t\tfromType.isImplicitlyConvertibleTo(targetType) &&\n\t\t\tfromType.sizeOnStack() == targetType.sizeOnStack() &&\n\t\t\t(fromType.kind() == FunctionType::Kind::Internal || fromType.kind() == FunctionType::Kind::External) &&\n\t\t\tfromType.kind() == targetType.kind(),\n\t\t\t\"Invalid function type conversion requested.\"\n\t\t);\n\t\tstd::string const functionName =\n\t\t\t\"convert_\" +\n\t\t\t_from.identifier() +\n\t\t\t\"_to_\" +\n\t\t\t_to.identifier();\n\t\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(<?external>addr, </external>functionId) -> <?external>outAddr, </external>outFunctionId {\n\t\t\t\t\t<?external>outAddr := addr</external>\n\t\t\t\t\toutFunctionId := functionId\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"external\", fromType.kind() == FunctionType::Kind::External)\n\t\t\t.render();\n\t\t});\n\t}\n\telse if (_from.category() == Type::Category::ArraySlice)\n\t{\n\t\tauto const& fromType = dynamic_cast<ArraySliceType const&>(_from);\n\t\tif (_to.category() == Type::Category::FixedBytes)\n\t\t{\n\t\t\tsolAssert(fromType.arrayType().isByteArray(), \"Array types other than bytes not convertible to bytesNN.\");\n\t\t\treturn bytesToFixedBytesConversionFunction(fromType.arrayType(), dynamic_cast<FixedBytesType const &>(_to));\n\t\t}\n\t\tsolAssert(_to.category() == Type::Category::Array);\n\t\tauto const& targetType = dynamic_cast<ArrayType const&>(_to);\n\n\t\tsolAssert(\n\t\t\tfromType.arrayType().isImplicitlyConvertibleTo(targetType) ||\n\t\t\t(fromType.arrayType().isByteArrayOrString() && targetType.isByteArrayOrString())\n\t\t);\n\t\tsolAssert(\n\t\t\tfromType.arrayType().dataStoredIn(DataLocation::CallData) &&\n\t\t\tfromType.arrayType().isDynamicallySized() &&\n\t\t\t!fromType.arrayType().baseType()->isDynamicallyEncoded()\n\t\t);\n\n\t\tif (!targetType.dataStoredIn(DataLocation::CallData))\n\t\t\treturn arrayConversionFunction(fromType.arrayType(), targetType);\n\n\t\tstd::string const functionName =\n\t\t\t\"convert_\" +\n\t\t\t_from.identifier() +\n\t\t\t\"_to_\" +\n\t\t\t_to.identifier();\n\t\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(offset, length) -> outOffset, outLength {\n\t\t\t\t\toutOffset := offset\n\t\t\t\t\toutLength := length\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t.render();\n\t\t});\n\t}\n\telse if (_from.category() == Type::Category::Array)\n\t{\n\t\tauto const& fromArrayType =  dynamic_cast<ArrayType const&>(_from);\n\t\tif (_to.category() == Type::Category::FixedBytes)\n\t\t{\n\t\t\tsolAssert(fromArrayType.isByteArray(), \"Array types other than bytes not convertible to bytesNN.\");\n\t\t\treturn bytesToFixedBytesConversionFunction(fromArrayType, dynamic_cast<FixedBytesType const &>(_to));\n\t\t}\n\t\tsolAssert(_to.category() == Type::Category::Array, \"\");\n\t\treturn arrayConversionFunction(fromArrayType, dynamic_cast<ArrayType const&>(_to));\n\t}\n\n\tif (_from.sizeOnStack() != 1 || _to.sizeOnStack() != 1)\n\t\treturn conversionFunctionSpecial(_from, _to);\n\n\tstd::string functionName =\n\t\t\"convert_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\t_to.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(value) -> converted {\n\t\t\t\t<body>\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\tstd::string body;\n\t\tauto toCategory = _to.category();\n\t\tauto fromCategory = _from.category();\n\t\tswitch (fromCategory)\n\t\t{\n\t\tcase Type::Category::Address:\n\t\tcase Type::Category::Contract:\n\t\t\tbody =\n\t\t\t\tWhiskers(\"converted := <convert>(value)\")\n\t\t\t\t\t(\"convert\", conversionFunction(IntegerType(160), _to))\n\t\t\t\t\t.render();\n\t\t\tbreak;\n\t\tcase Type::Category::Integer:\n\t\tcase Type::Category::RationalNumber:\n\t\t{\n\t\t\tsolAssert(_from.mobileType(), \"\");\n\t\t\tif (RationalNumberType const* rational = dynamic_cast<RationalNumberType const*>(&_from))\n\t\t\t\tif (rational->isFractional())\n\t\t\t\t\tsolAssert(toCategory == Type::Category::FixedPoint, \"\");\n\n\t\t\tif (toCategory == Type::Category::Address || toCategory == Type::Category::Contract)\n\t\t\t\tbody =\n\t\t\t\t\tWhiskers(\"converted := <convert>(value)\")\n\t\t\t\t\t(\"convert\", conversionFunction(_from, IntegerType(160)))\n\t\t\t\t\t.render();\n\t\t\telse\n\t\t\t{\n\t\t\t\tWhiskers bodyTemplate(\"converted := <cleanOutput>(<convert>(<cleanInput>(value)))\");\n\t\t\t\tbodyTemplate(\"cleanInput\", cleanupFunction(_from));\n\t\t\t\tbodyTemplate(\"cleanOutput\", cleanupFunction(_to));\n\t\t\t\tstd::string convert;\n\n\t\t\t\tsolAssert(_to.category() != Type::Category::UserDefinedValueType, \"\");\n\t\t\t\tif (auto const* toFixedBytes = dynamic_cast<FixedBytesType const*>(&_to))\n\t\t\t\t\tconvert = shiftLeftFunction(256 - toFixedBytes->numBytes() * 8);\n\t\t\t\telse if (dynamic_cast<FixedPointType const*>(&_to))\n\t\t\t\t\tsolUnimplemented(\"\");\n\t\t\t\telse if (dynamic_cast<IntegerType const*>(&_to))\n\t\t\t\t{\n\t\t\t\t\tsolUnimplementedAssert(fromCategory != Type::Category::FixedPoint);\n\t\t\t\t\tconvert = identityFunction();\n\t\t\t\t}\n\t\t\t\telse if (toCategory == Type::Category::Enum)\n\t\t\t\t{\n\t\t\t\t\tsolAssert(fromCategory != Type::Category::FixedPoint, \"\");\n\t\t\t\t\tconvert = identityFunction();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tsolAssert(false, \"\");\n\t\t\t\tsolAssert(!convert.empty(), \"\");\n\t\t\t\tbodyTemplate(\"convert\", convert);\n\t\t\t\tbody = bodyTemplate.render();\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::Bool:\n\t\t{\n\t\t\tsolAssert(_from == _to, \"Invalid conversion for bool.\");\n\t\t\tbody =\n\t\t\t\tWhiskers(\"converted := <clean>(value)\")\n\t\t\t\t(\"clean\", cleanupFunction(_from))\n\t\t\t\t.render();\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::FixedPoint:\n\t\t\tsolUnimplemented(\"Fixed point types not implemented.\");\n\t\t\tbreak;\n\t\tcase Type::Category::Struct:\n\t\t{\n\t\t\tsolAssert(toCategory == Type::Category::Struct, \"\");\n\t\t\tauto const& fromStructType = dynamic_cast<StructType const &>(_from);\n\t\t\tauto const& toStructType = dynamic_cast<StructType const &>(_to);\n\t\t\tsolAssert(fromStructType.structDefinition() == toStructType.structDefinition(), \"\");\n\n\t\t\tif (fromStructType.location() == toStructType.location() && toStructType.isPointer())\n\t\t\t\tbody = \"converted := value\";\n\t\t\telse\n\t\t\t{\n\t\t\t\tsolUnimplementedAssert(toStructType.location() == DataLocation::Memory);\n\t\t\t\tsolUnimplementedAssert(fromStructType.location() != DataLocation::Memory);\n\n\t\t\t\tif (fromStructType.location() == DataLocation::CallData)\n\t\t\t\t\tbody = Whiskers(R\"(\n\t\t\t\t\t\tconverted := <abiDecode>(value, calldatasize())\n\t\t\t\t\t)\")\n\t\t\t\t\t(\n\t\t\t\t\t\t\"abiDecode\",\n\t\t\t\t\t\tABIFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector).abiDecodingFunctionStruct(\n\t\t\t\t\t\t\ttoStructType,\n\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t)\n\t\t\t\t\t).render();\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsolAssert(fromStructType.location() == DataLocation::Storage, \"\");\n\n\t\t\t\t\tbody = Whiskers(R\"(\n\t\t\t\t\t\tconverted := <readFromStorage>(value)\n\t\t\t\t\t)\")\n\t\t\t\t\t(\"readFromStorage\", readFromStorage(toStructType, 0, true, VariableDeclaration::Location::Unspecified))\n\t\t\t\t\t.render();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::FixedBytes:\n\t\t{\n\t\t\tFixedBytesType const& from = dynamic_cast<FixedBytesType const&>(_from);\n\t\t\tif (toCategory == Type::Category::Integer)\n\t\t\t\tbody =\n\t\t\t\t\tWhiskers(\"converted := <convert>(<shift>(value))\")\n\t\t\t\t\t(\"shift\", shiftRightFunction(256 - from.numBytes() * 8))\n\t\t\t\t\t(\"convert\", conversionFunction(IntegerType(from.numBytes() * 8), _to))\n\t\t\t\t\t.render();\n\t\t\telse if (toCategory == Type::Category::Address)\n\t\t\t\tbody =\n\t\t\t\t\tWhiskers(\"converted := <convert>(value)\")\n\t\t\t\t\t\t(\"convert\", conversionFunction(_from, IntegerType(160)))\n\t\t\t\t\t\t.render();\n\t\t\telse\n\t\t\t{\n\t\t\t\tsolAssert(toCategory == Type::Category::FixedBytes, \"Invalid type conversion requested.\");\n\t\t\t\tFixedBytesType const& to = dynamic_cast<FixedBytesType const&>(_to);\n\t\t\t\tbody =\n\t\t\t\t\tWhiskers(\"converted := <clean>(value)\")\n\t\t\t\t\t(\"clean\", cleanupFunction((to.numBytes() <= from.numBytes()) ? to : from))\n\t\t\t\t\t.render();\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::Function:\n\t\t{\n\t\t\tsolAssert(false, \"Conversion should not be called for function types.\");\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::Enum:\n\t\t{\n\t\t\tsolAssert(toCategory == Type::Category::Integer || _from == _to, \"\");\n\t\t\tEnumType const& enumType = dynamic_cast<decltype(enumType)>(_from);\n\t\t\tbody =\n\t\t\t\tWhiskers(\"converted := <clean>(value)\")\n\t\t\t\t(\"clean\", cleanupFunction(enumType))\n\t\t\t\t.render();\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::Tuple:\n\t\t{\n\t\t\tsolUnimplemented(\"Tuple conversion not implemented.\");\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::TypeType:\n\t\t{\n\t\t\tTypeType const& typeType = dynamic_cast<decltype(typeType)>(_from);\n\t\t\tif (\n\t\t\t\tauto const* contractType = dynamic_cast<ContractType const*>(typeType.actualType());\n\t\t\t\tcontractType->contractDefinition().isLibrary() &&\n\t\t\t\t_to == *TypeProvider::address()\n\t\t\t)\n\t\t\t\tbody = \"converted := value\";\n\t\t\telse\n\t\t\t\tsolAssert(false, \"Invalid conversion from \" + _from.canonicalName() + \" to \" + _to.canonicalName());\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::Mapping:\n\t\t{\n\t\t\tsolAssert(_from == _to, \"\");\n\t\t\tbody = \"converted := value\";\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tsolAssert(false, \"Invalid conversion from \" + _from.canonicalName() + \" to \" + _to.canonicalName());\n\t\t}\n\n\t\tsolAssert(!body.empty(), _from.canonicalName() + \" to \" + _to.canonicalName());\n\t\ttempl(\"body\", body);\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::bytesToFixedBytesConversionFunction(ArrayType const& _from, FixedBytesType const& _to)\n{\n\tsolAssert(_from.isByteArray(), \"\");\n\tsolAssert(_from.isDynamicallySized(), \"\");\n\tstd::string functionName = \"convert_bytes_to_fixedbytes_from_\" + _from.identifier() + \"_to_\" + _to.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&](auto& _args, auto& _returnParams) {\n\t\t_args = { \"array\" };\n\t\tbool fromCalldata = _from.dataStoredIn(DataLocation::CallData);\n\t\tif (fromCalldata)\n\t\t\t_args.emplace_back(\"len\");\n\t\t_returnParams = {\"value\"};\n\t\tWhiskers templ(R\"(\n\t\t\tlet length := <arrayLen>(array<?fromCalldata>, len</fromCalldata>)\n\t\t\tlet dataArea := array\n\t\t\t<?fromMemory>\n\t\t\t\tdataArea := <dataArea>(array)\n\t\t\t</fromMemory>\n\t\t\t<?fromStorage>\n\t\t\t\tif gt(length, 31) { dataArea := <dataArea>(array) }\n\t\t\t</fromStorage>\n\n\t\t\t<?fromCalldata>\n\t\t\t\tvalue := <cleanup>(calldataload(dataArea))\n\t\t\t<!fromCalldata>\n\t\t\t\tvalue := <extractValue>(dataArea)\n\t\t\t</fromCalldata>\n\n\t\t\tif lt(length, <fixedBytesLen>) {\n\t\t\t\tvalue := and(\n\t\t\t\t\tvalue,\n\t\t\t\t\t<shl>(\n\t\t\t\t\t\tmul(8, sub(<fixedBytesLen>, length)),\n\t\t\t\t\t\t<mask>\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"fromCalldata\", fromCalldata);\n\t\ttempl(\"arrayLen\", arrayLengthFunction(_from));\n\t\ttempl(\"fixedBytesLen\", std::to_string(_to.numBytes()));\n\t\ttempl(\"fromMemory\", _from.dataStoredIn(DataLocation::Memory));\n\t\ttempl(\"fromStorage\", _from.dataStoredIn(DataLocation::Storage));\n\t\ttempl(\"dataArea\", arrayDataAreaFunction(_from));\n\t\tif (fromCalldata)\n\t\t\ttempl(\"cleanup\", cleanupFunction(_to));\n\t\telse\n\t\t\ttempl(\n\t\t\t\t\"extractValue\",\n\t\t\t\t_from.dataStoredIn(DataLocation::Storage) ?\n\t\t\t\treadFromStorage(_to, 32 - _to.numBytes(), false, VariableDeclaration::Location::Unspecified) :\n\t\t\t\treadFromMemory(_to)\n\t\t\t);\n\t\ttempl(\"shl\", shiftLeftFunctionDynamic());\n\t\ttempl(\"mask\", formatNumber(~((u256(1) << (256 - _to.numBytes() * 8)) - 1)));\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::copyStructToStorageFunction(StructType const& _from, StructType const& _to)\n{\n\tsolAssert(_to.dataStoredIn(DataLocation::Storage), \"\");\n\tsolAssert(_from.structDefinition() == _to.structDefinition(), \"\");\n\n\tstd::string functionName =\n\t\t\"copy_struct_to_storage_from_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\t_to.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&](auto& _arguments, auto&) {\n\t\t_arguments = {\"slot\", \"value\"};\n\t\tWhiskers templ(R\"(\n\t\t\t<?fromStorage> if iszero(eq(slot, value)) { </fromStorage>\n\t\t\t<#member>\n\t\t\t{\n\t\t\t\t<updateMemberCall>\n\t\t\t}\n\t\t\t</member>\n\t\t\t<?fromStorage> } </fromStorage>\n\t\t)\");\n\t\ttempl(\"fromStorage\", _from.dataStoredIn(DataLocation::Storage));\n\n\t\tMemberList::MemberMap structMembers = _from.nativeMembers(nullptr);\n\t\tMemberList::MemberMap toStructMembers = _to.nativeMembers(nullptr);\n\n\t\tstd::vector<std::map<std::string, std::string>> memberParams(structMembers.size());\n\t\tfor (size_t i = 0; i < structMembers.size(); ++i)\n\t\t{\n\t\t\tType const& memberType = *structMembers[i].type;\n\t\t\tsolAssert(memberType.memoryHeadSize() == 32, \"\");\n\t\t\tauto const&[slotDiff, offset] = _to.storageOffsetsOfMember(structMembers[i].name);\n\n\t\t\tWhiskers t(R\"(\n\t\t\t\tlet memberSlot := add(slot, <memberStorageSlotDiff>)\n\t\t\t\tlet memberSrcPtr := add(value, <memberOffset>)\n\n\t\t\t\t<?fromCalldata>\n\t\t\t\t\tlet <memberValues> :=\n\t\t\t\t\t\t<?dynamicallyEncodedMember>\n\t\t\t\t\t\t\t<accessCalldataTail>(value, memberSrcPtr)\n\t\t\t\t\t\t<!dynamicallyEncodedMember>\n\t\t\t\t\t\t\tmemberSrcPtr\n\t\t\t\t\t\t</dynamicallyEncodedMember>\n\n\t\t\t\t\t<?isValueType>\n\t\t\t\t\t\t<memberValues> := <read>(<memberValues>)\n\t\t\t\t\t</isValueType>\n\t\t\t\t</fromCalldata>\n\n\t\t\t\t<?fromMemory>\n\t\t\t\t\tlet <memberValues> := <read>(memberSrcPtr)\n\t\t\t\t</fromMemory>\n\n\t\t\t\t<?fromStorage>\n\t\t\t\t\tlet <memberValues> :=\n\t\t\t\t\t\t<?isValueType>\n\t\t\t\t\t\t\t<read>(memberSrcPtr)\n\t\t\t\t\t\t<!isValueType>\n\t\t\t\t\t\t\tmemberSrcPtr\n\t\t\t\t\t\t</isValueType>\n\t\t\t\t</fromStorage>\n\n\t\t\t\t<updateStorageValue>(memberSlot, <memberValues>)\n\t\t\t)\");\n\t\t\tbool fromCalldata = _from.location() == DataLocation::CallData;\n\t\t\tt(\"fromCalldata\", fromCalldata);\n\t\t\tbool fromMemory = _from.location() == DataLocation::Memory;\n\t\t\tt(\"fromMemory\", fromMemory);\n\t\t\tbool fromStorage = _from.location() == DataLocation::Storage;\n\t\t\tt(\"fromStorage\", fromStorage);\n\t\t\tt(\"isValueType\", memberType.isValueType());\n\t\t\tt(\"memberValues\", suffixedVariableNameList(\"memberValue_\", 0, memberType.stackItems().size()));\n\n\t\t\tt(\"memberStorageSlotDiff\", slotDiff.str());\n\t\t\tif (fromCalldata)\n\t\t\t{\n\t\t\t\tt(\"memberOffset\", std::to_string(_from.calldataOffsetOfMember(structMembers[i].name)));\n\t\t\t\tt(\"dynamicallyEncodedMember\", memberType.isDynamicallyEncoded());\n\t\t\t\tif (memberType.isDynamicallyEncoded())\n\t\t\t\t\tt(\"accessCalldataTail\", accessCalldataTailFunction(memberType));\n\t\t\t\tif (memberType.isValueType())\n\t\t\t\t\tt(\"read\", readFromCalldata(memberType));\n\t\t\t}\n\t\t\telse if (fromMemory)\n\t\t\t{\n\t\t\t\tt(\"memberOffset\", _from.memoryOffsetOfMember(structMembers[i].name).str());\n\t\t\t\tt(\"read\", readFromMemory(memberType));\n\t\t\t}\n\t\t\telse if (fromStorage)\n\t\t\t{\n\t\t\t\tauto const& [srcSlotOffset, srcOffset] = _from.storageOffsetsOfMember(structMembers[i].name);\n\t\t\t\tt(\"memberOffset\", formatNumber(srcSlotOffset));\n\t\t\t\tif (memberType.isValueType())\n\t\t\t\t\tt(\"read\", readFromStorageValueType(memberType, srcOffset, true, VariableDeclaration::Location::Unspecified));\n\t\t\t\telse\n\t\t\t\t\tsolAssert(srcOffset == 0, \"\");\n\n\t\t\t}\n\t\t\tt(\"updateStorageValue\", updateStorageValueFunction(\n\t\t\t\tmemberType,\n\t\t\t\t*toStructMembers[i].type,\n\t\t\t\tVariableDeclaration::Location::Unspecified,\n\t\t\t\tstd::optional<unsigned>{offset}\n\t\t\t));\n\t\t\tmemberParams[i][\"updateMemberCall\"] = t.render();\n\t\t}\n\t\ttempl(\"member\", memberParams);\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::arrayConversionFunction(ArrayType const& _from, ArrayType const& _to)\n{\n\tif (_to.dataStoredIn(DataLocation::CallData))\n\t\tsolAssert(\n\t\t\t_from.dataStoredIn(DataLocation::CallData) && _from.isByteArrayOrString() && _to.isByteArrayOrString(),\n\t\t\t\"\"\n\t\t);\n\n\t// Other cases are done explicitly in LValue::storeValue, and only possible by assignment.\n\tif (_to.location() == DataLocation::Storage)\n\t\tsolAssert(\n\t\t\t(_to.isPointer() || (_from.isByteArrayOrString() && _to.isByteArrayOrString())) &&\n\t\t\t_from.location() == DataLocation::Storage,\n\t\t\t\"Invalid conversion to storage type.\"\n\t\t);\n\n\tstd::string functionName =\n\t\t\"convert_array_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\t_to.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(value<?fromCalldataDynamic>, length</fromCalldataDynamic>) -> converted <?toCalldataDynamic>, outLength</toCalldataDynamic> {\n\t\t\t\t<body>\n\t\t\t\t<?toCalldataDynamic>\n\t\t\t\t\toutLength := <length>\n\t\t\t\t</toCalldataDynamic>\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"fromCalldataDynamic\", _from.dataStoredIn(DataLocation::CallData) && _from.isDynamicallySized());\n\t\ttempl(\"toCalldataDynamic\", _to.dataStoredIn(DataLocation::CallData) && _to.isDynamicallySized());\n\t\ttempl(\"length\", _from.isDynamicallySized() ? \"length\" : _from.length().str());\n\n\t\tif (\n\t\t\t_from == _to ||\n\t\t\t(_from.dataStoredIn(DataLocation::Memory) && _to.dataStoredIn(DataLocation::Memory)) ||\n\t\t\t(_from.dataStoredIn(DataLocation::CallData) && _to.dataStoredIn(DataLocation::CallData)) ||\n\t\t\t_to.dataStoredIn(DataLocation::Storage)\n\t\t)\n\t\t\ttempl(\"body\", \"converted := value\");\n\t\telse if (_to.dataStoredIn(DataLocation::Memory))\n\t\t\ttempl(\n\t\t\t\t\"body\",\n\t\t\t\tWhiskers(R\"(\n\t\t\t\t\t// Copy the array to a free position in memory\n\t\t\t\t\tconverted :=\n\t\t\t\t\t<?fromStorage>\n\t\t\t\t\t\t<arrayStorageToMem>(value)\n\t\t\t\t\t</fromStorage>\n\t\t\t\t\t<?fromCalldata>\n\t\t\t\t\t\t<abiDecode>(value, <length>, calldatasize())\n\t\t\t\t\t</fromCalldata>\n\t\t\t\t)\")\n\t\t\t\t(\"fromStorage\", _from.dataStoredIn(DataLocation::Storage))\n\t\t\t\t(\"fromCalldata\", _from.dataStoredIn(DataLocation::CallData))\n\t\t\t\t(\"length\", _from.isDynamicallySized() ? \"length\" : _from.length().str())\n\t\t\t\t(\n\t\t\t\t\t\"abiDecode\",\n\t\t\t\t\t_from.dataStoredIn(DataLocation::CallData) ?\n\t\t\t\t\tABIFunctions(\n\t\t\t\t\t\tm_evmVersion,\n\t\t\t\t\t\tm_eofVersion,\n\t\t\t\t\t\tm_revertStrings,\n\t\t\t\t\t\tm_functionCollector\n\t\t\t\t\t).abiDecodingFunctionArrayAvailableLength(_to, false) :\n\t\t\t\t\t\"\"\n\t\t\t\t)\n\t\t\t\t(\n\t\t\t\t\t\"arrayStorageToMem\",\n\t\t\t\t\t_from.dataStoredIn(DataLocation::Storage) ? copyArrayFromStorageToMemoryFunction(_from, _to) : \"\"\n\t\t\t\t)\n\t\t\t\t.render()\n\t\t\t);\n\t\telse\n\t\t\tsolAssert(false, \"\");\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::cleanupFunction(Type const& _type)\n{\n\tif (auto userDefinedValueType = dynamic_cast<UserDefinedValueType const*>(&_type))\n\t\treturn cleanupFunction(userDefinedValueType->underlyingType());\n\n\tstd::string functionName = std::string(\"cleanup_\") + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(value) -> cleaned {\n\t\t\t\t<body>\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\tswitch (_type.category())\n\t\t{\n\t\tcase Type::Category::Address:\n\t\t\ttempl(\"body\", \"cleaned := \" + cleanupFunction(IntegerType(160)) + \"(value)\");\n\t\t\tbreak;\n\t\tcase Type::Category::Integer:\n\t\t{\n\t\t\tIntegerType const& type = dynamic_cast<IntegerType const&>(_type);\n\t\t\tif (type.numBits() == 256)\n\t\t\t\ttempl(\"body\", \"cleaned := value\");\n\t\t\telse if (type.isSigned())\n\t\t\t\ttempl(\"body\", \"cleaned := signextend(\" + std::to_string(type.numBits() / 8 - 1) + \", value)\");\n\t\t\telse\n\t\t\t\ttempl(\"body\", \"cleaned := and(value, \" + toCompactHexWithPrefix((u256(1) << type.numBits()) - 1) + \")\");\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::RationalNumber:\n\t\t\ttempl(\"body\", \"cleaned := value\");\n\t\t\tbreak;\n\t\tcase Type::Category::Bool:\n\t\t\ttempl(\"body\", \"cleaned := iszero(iszero(value))\");\n\t\t\tbreak;\n\t\tcase Type::Category::FixedPoint:\n\t\t\tsolUnimplemented(\"Fixed point types not implemented.\");\n\t\t\tbreak;\n\t\tcase Type::Category::Function:\n\t\t\tswitch (dynamic_cast<FunctionType const&>(_type).kind())\n\t\t\t{\n\t\t\t\tcase FunctionType::Kind::External:\n\t\t\t\t\ttempl(\"body\", \"cleaned := \" + cleanupFunction(FixedBytesType(24)) + \"(value)\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase FunctionType::Kind::Internal:\n\t\t\t\t\ttempl(\"body\", \"cleaned := value\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tsolAssert(false, \"\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase Type::Category::Array:\n\t\tcase Type::Category::Struct:\n\t\tcase Type::Category::Mapping:\n\t\t\tsolAssert(_type.dataStoredIn(DataLocation::Storage), \"Cleanup requested for non-storage reference type.\");\n\t\t\ttempl(\"body\", \"cleaned := value\");\n\t\t\tbreak;\n\t\tcase Type::Category::FixedBytes:\n\t\t{\n\t\t\tFixedBytesType const& type = dynamic_cast<FixedBytesType const&>(_type);\n\t\t\tif (type.numBytes() == 32)\n\t\t\t\ttempl(\"body\", \"cleaned := value\");\n\t\t\telse if (type.numBytes() == 0)\n\t\t\t\t// This is disallowed in the type system.\n\t\t\t\tsolAssert(false, \"\");\n\t\t\telse\n\t\t\t{\n\t\t\t\tsize_t numBits = type.numBytes() * 8;\n\t\t\t\tu256 mask = ((u256(1) << numBits) - 1) << (256 - numBits);\n\t\t\t\ttempl(\"body\", \"cleaned := and(value, \" + toCompactHexWithPrefix(mask) + \")\");\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::Contract:\n\t\t{\n\t\t\tAddressType addressType(dynamic_cast<ContractType const&>(_type).isPayable() ?\n\t\t\t\tStateMutability::Payable :\n\t\t\t\tStateMutability::NonPayable\n\t\t\t);\n\t\t\ttempl(\"body\", \"cleaned := \" + cleanupFunction(addressType) + \"(value)\");\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::Enum:\n\t\t{\n\t\t\t// Out of range enums cannot be truncated unambiguously and therefore it should be an error.\n\t\t\ttempl(\"body\", \"cleaned := value \" + validatorFunction(_type, false) + \"(value)\");\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::InaccessibleDynamic:\n\t\t\ttempl(\"body\", \"cleaned := 0\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tsolAssert(false, \"Cleanup of type \" + _type.identifier() + \" requested.\");\n\t\t}\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::validatorFunction(Type const& _type, bool _revertOnFailure)\n{\n\tstd::string functionName = std::string(\"validator_\") + (_revertOnFailure ? \"revert_\" : \"assert_\") + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(value) {\n\t\t\t\tif iszero(<condition>) { <failure> }\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\tPanicCode panicCode = PanicCode::Generic;\n\n\t\tswitch (_type.category())\n\t\t{\n\t\tcase Type::Category::Address:\n\t\tcase Type::Category::Integer:\n\t\tcase Type::Category::RationalNumber:\n\t\tcase Type::Category::Bool:\n\t\tcase Type::Category::FixedPoint:\n\t\tcase Type::Category::Function:\n\t\tcase Type::Category::Array:\n\t\tcase Type::Category::Struct:\n\t\tcase Type::Category::Mapping:\n\t\tcase Type::Category::FixedBytes:\n\t\tcase Type::Category::Contract:\n\t\tcase Type::Category::UserDefinedValueType:\n\t\t{\n\t\t\ttempl(\"condition\", \"eq(value, \" + cleanupFunction(_type) + \"(value))\");\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::Enum:\n\t\t{\n\t\t\tsize_t members = dynamic_cast<EnumType const&>(_type).numberOfMembers();\n\t\t\tsolAssert(members > 0, \"empty enum should have caused a parser error.\");\n\t\t\tpanicCode = PanicCode::EnumConversionError;\n\t\t\ttempl(\"condition\", \"lt(value, \" + std::to_string(members) + \")\");\n\t\t\tbreak;\n\t\t}\n\t\tcase Type::Category::InaccessibleDynamic:\n\t\t\ttempl(\"condition\", \"1\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tsolAssert(false, \"Validation of type \" + _type.identifier() + \" requested.\");\n\t\t}\n\n\t\tif (_revertOnFailure)\n\t\t\ttempl(\"failure\", \"revert(0, 0)\");\n\t\telse\n\t\t\ttempl(\"failure\", panicFunction(panicCode) + \"()\");\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::packedHashFunction(\n\tstd::vector<Type const*> const& _givenTypes,\n\tstd::vector<Type const*> const& _targetTypes\n)\n{\n\tstd::string functionName = std::string(\"packed_hashed_\");\n\tfor (auto const& t: _givenTypes)\n\t\tfunctionName += t->identifier() + \"_\";\n\tfunctionName += \"_to_\";\n\tfor (auto const& t: _targetTypes)\n\t\tfunctionName += t->identifier() + \"_\";\n\tsize_t sizeOnStack = 0;\n\tfor (Type const* t: _givenTypes)\n\t\tsizeOnStack += t->sizeOnStack();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(<variables>) -> hash {\n\t\t\t\tlet pos := <allocateUnbounded>()\n\t\t\t\tlet end := <packedEncode>(pos <comma> <variables>)\n\t\t\t\thash := keccak256(pos, sub(end, pos))\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"variables\", suffixedVariableNameList(\"var_\", 1, 1 + sizeOnStack));\n\t\ttempl(\"comma\", sizeOnStack > 0 ? \",\" : \"\");\n\t\ttempl(\"allocateUnbounded\", allocateUnboundedFunction());\n\t\ttempl(\n\t\t\t\"packedEncode\",\n\t\t\tABIFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector).tupleEncoderPacked(_givenTypes, _targetTypes)\n\t\t);\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::forwardingRevertFunction()\n{\n\tbool forward = m_evmVersion.supportsReturndata();\n\tstd::string functionName = \"revert_forward_\" + std::to_string(forward);\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tif (forward)\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>() {\n\t\t\t\t\tlet pos := <allocateUnbounded>()\n\t\t\t\t\treturndatacopy(pos, 0, returndatasize())\n\t\t\t\t\trevert(pos, returndatasize())\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"allocateUnbounded\", allocateUnboundedFunction())\n\t\t\t.render();\n\t\telse\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>() {\n\t\t\t\t\trevert(0, 0)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::decrementCheckedFunction(Type const& _type)\n{\n\tsolAssert(_type.category() == Type::Category::Integer, \"\");\n\tIntegerType const& type = dynamic_cast<IntegerType const&>(_type);\n\n\tstd::string const functionName = \"decrement_\" + _type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(value) -> ret {\n\t\t\t\tvalue := <cleanupFunction>(value)\n\t\t\t\tif eq(value, <minval>) { <panic>() }\n\t\t\t\tret := sub(value, 1)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"panic\", panicFunction(PanicCode::UnderOverflow))\n\t\t(\"minval\", toCompactHexWithPrefix(type.min()))\n\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::decrementWrappingFunction(Type const& _type)\n{\n\tsolAssert(_type.category() == Type::Category::Integer, \"\");\n\tIntegerType const& type = dynamic_cast<IntegerType const&>(_type);\n\n\tstd::string const functionName = \"decrement_wrapping_\" + _type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(value) -> ret {\n\t\t\t\tret := <cleanupFunction>(sub(value, 1))\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"cleanupFunction\", cleanupFunction(type))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::incrementCheckedFunction(Type const& _type)\n{\n\tsolAssert(_type.category() == Type::Category::Integer, \"\");\n\tIntegerType const& type = dynamic_cast<IntegerType const&>(_type);\n\n\tstd::string const functionName = \"increment_\" + _type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(value) -> ret {\n\t\t\t\tvalue := <cleanupFunction>(value)\n\t\t\t\tif eq(value, <maxval>) { <panic>() }\n\t\t\t\tret := add(value, 1)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"maxval\", toCompactHexWithPrefix(type.max()))\n\t\t(\"panic\", panicFunction(PanicCode::UnderOverflow))\n\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::incrementWrappingFunction(Type const& _type)\n{\n\tsolAssert(_type.category() == Type::Category::Integer, \"\");\n\tIntegerType const& type = dynamic_cast<IntegerType const&>(_type);\n\n\tstd::string const functionName = \"increment_wrapping_\" + _type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(value) -> ret {\n\t\t\t\tret := <cleanupFunction>(add(value, 1))\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"cleanupFunction\", cleanupFunction(type))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::negateNumberCheckedFunction(Type const& _type)\n{\n\tsolAssert(_type.category() == Type::Category::Integer, \"\");\n\tIntegerType const& type = dynamic_cast<IntegerType const&>(_type);\n\tsolAssert(type.isSigned(), \"Expected signed type!\");\n\n\tstd::string const functionName = \"negate_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(value) -> ret {\n\t\t\t\tvalue := <cleanupFunction>(value)\n\t\t\t\tif eq(value, <minval>) { <panic>() }\n\t\t\t\tret := sub(0, value)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"minval\", toCompactHexWithPrefix(type.min()))\n\t\t(\"cleanupFunction\", cleanupFunction(_type))\n\t\t(\"panic\", panicFunction(PanicCode::UnderOverflow))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::negateNumberWrappingFunction(Type const& _type)\n{\n\tsolAssert(_type.category() == Type::Category::Integer, \"\");\n\tIntegerType const& type = dynamic_cast<IntegerType const&>(_type);\n\tsolAssert(type.isSigned(), \"Expected signed type!\");\n\n\tstd::string const functionName = \"negate_wrapping_\" + _type.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>(value) -> ret {\n\t\t\t\tret := <cleanupFunction>(sub(0, value))\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"cleanupFunction\", cleanupFunction(type))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::zeroValueFunction(Type const& _type, bool _splitFunctionTypes)\n{\n\tsolAssert(_type.category() != Type::Category::Mapping, \"\");\n\n\tstd::string const functionName = \"zero_value_for_\" + std::string(_splitFunctionTypes ? \"split_\" : \"\") + _type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tFunctionType const* fType = dynamic_cast<FunctionType const*>(&_type);\n\t\tif (fType && fType->kind() == FunctionType::Kind::External && _splitFunctionTypes)\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>() -> retAddress, retFunction {\n\t\t\t\t\tretAddress := 0\n\t\t\t\t\tretFunction := 0\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t.render();\n\n\t\tif (_type.dataStoredIn(DataLocation::CallData))\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\t_type.category() == Type::Category::Struct ||\n\t\t\t\t_type.category() == Type::Category::Array,\n\t\t\t\"\");\n\t\t\tWhiskers templ(R\"(\n\t\t\t\tfunction <functionName>() -> offset<?hasLength>, length</hasLength> {\n\t\t\t\t\toffset := calldatasize()\n\t\t\t\t\t<?hasLength> length := 0 </hasLength>\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\ttempl(\"hasLength\",\n\t\t\t\t_type.category() == Type::Category::Array &&\n\t\t\t\tdynamic_cast<ArrayType const&>(_type).isDynamicallySized()\n\t\t\t);\n\n\t\t\treturn templ.render();\n\t\t}\n\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>() -> ret {\n\t\t\t\tret := <zeroValue>\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\n\t\tif (_type.isValueType())\n\t\t{\n\t\t\tsolAssert((\n\t\t\t\t_type.hasSimpleZeroValueInMemory() ||\n\t\t\t\t(fType && (fType->kind() == FunctionType::Kind::Internal || fType->kind() == FunctionType::Kind::External))\n\t\t\t), \"\");\n\t\t\ttempl(\"zeroValue\", \"0\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(_type.dataStoredIn(DataLocation::Memory), \"\");\n\t\t\tif (auto const* arrayType = dynamic_cast<ArrayType const*>(&_type))\n\t\t\t{\n\t\t\t\tif (_type.isDynamicallySized())\n\t\t\t\t\ttempl(\"zeroValue\", std::to_string(CompilerUtils::zeroPointer));\n\t\t\t\telse\n\t\t\t\t\ttempl(\"zeroValue\", allocateAndInitializeMemoryArrayFunction(*arrayType) + \"(\" + std::to_string(unsigned(arrayType->length())) + \")\");\n\n\t\t\t}\n\t\t\telse if (auto const* structType = dynamic_cast<StructType const*>(&_type))\n\t\t\t\ttempl(\"zeroValue\", allocateAndInitializeMemoryStructFunction(*structType) + \"()\");\n\t\t\telse\n\t\t\t\tsolUnimplemented(\"\");\n\t\t}\n\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::storageSetToZeroFunction(Type const& _type, VariableDeclaration::Location _location)\n{\n\tsolAssert(\n\t\t_location == VariableDeclaration::Location::Transient ||\n\t\t_location == VariableDeclaration::Location::Unspecified,\n\t\t\"Invalid location for the storage_set_to_zero function\"\n\t);\n\n\tif (dynamic_cast<ReferenceType const*>(&_type))\n\t\tsolAssert(\n\t\t\t_location == VariableDeclaration::Location::Unspecified &&\n\t\t\t_type.dataStoredIn(DataLocation::Storage)\n\t\t);\n\n\tstd::string const functionName =\n\t\t(_location == VariableDeclaration::Location::Transient ? \"transient_\"s : \"\") +\n\t\t\"storage_set_to_zero_\" +\n\t\t_type.identifier();\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tif (_type.isValueType())\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(slot, offset) {\n\t\t\t\t\tlet <values> := <zeroValue>()\n\t\t\t\t\t<store>(slot, offset, <values>)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"store\", updateStorageValueFunction(_type, _type, _location))\n\t\t\t(\"values\", suffixedVariableNameList(\"zero_\", 0, _type.sizeOnStack()))\n\t\t\t(\"zeroValue\", zeroValueFunction(_type))\n\t\t\t.render();\n\t\telse if (_type.category() == Type::Category::Array)\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(slot, offset) {\n\t\t\t\t\tif iszero(eq(offset, 0)) { <panic>() }\n\t\t\t\t\t<clearArray>(slot)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"clearArray\", clearStorageArrayFunction(dynamic_cast<ArrayType const&>(_type)))\n\t\t\t(\"panic\", panicFunction(PanicCode::Generic))\n\t\t\t.render();\n\t\telse if (_type.category() == Type::Category::Struct)\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(slot, offset) {\n\t\t\t\t\tif iszero(eq(offset, 0)) { <panic>() }\n\t\t\t\t\t<clearStruct>(slot)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"clearStruct\", clearStorageStructFunction(dynamic_cast<StructType const&>(_type)))\n\t\t\t(\"panic\", panicFunction(PanicCode::Generic))\n\t\t\t.render();\n\t\telse\n\t\t\tsolUnimplemented(\"setToZero for type \" + _type.identifier() + \" not yet implemented!\");\n\t});\n}\n\nstd::string YulUtilFunctions::conversionFunctionSpecial(Type const& _from, Type const& _to)\n{\n\tstd::string functionName =\n\t\t\"convert_\" +\n\t\t_from.identifier() +\n\t\t\"_to_\" +\n\t\t_to.identifier();\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tif (\n\t\t\tauto fromTuple = dynamic_cast<TupleType const*>(&_from), toTuple = dynamic_cast<TupleType const*>(&_to);\n\t\t\tfromTuple && toTuple && fromTuple->components().size() == toTuple->components().size()\n\t\t)\n\t\t{\n\t\t\tsize_t sourceStackSize = 0;\n\t\t\tsize_t destStackSize = 0;\n\t\t\tstd::string conversions;\n\t\t\tfor (size_t i = 0; i < fromTuple->components().size(); ++i)\n\t\t\t{\n\t\t\t\tauto fromComponent = fromTuple->components()[i];\n\t\t\t\tauto toComponent = toTuple->components()[i];\n\t\t\t\tsolAssert(fromComponent, \"\");\n\t\t\t\tif (toComponent)\n\t\t\t\t{\n\t\t\t\t\tconversions +=\n\t\t\t\t\t\tsuffixedVariableNameList(\"converted\", destStackSize, destStackSize + toComponent->sizeOnStack()) +\n\t\t\t\t\t\t(toComponent->sizeOnStack() > 0 ? \" := \" : \"\") +\n\t\t\t\t\t\tconversionFunction(*fromComponent, *toComponent) +\n\t\t\t\t\t\t\"(\" +\n\t\t\t\t\t\tsuffixedVariableNameList(\"value\", sourceStackSize, sourceStackSize + fromComponent->sizeOnStack()) +\n\t\t\t\t\t\t\")\\n\";\n\t\t\t\t\tdestStackSize += toComponent->sizeOnStack();\n\t\t\t\t}\n\t\t\t\tsourceStackSize += fromComponent->sizeOnStack();\n\t\t\t}\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(<values>) <arrow> <converted> {\n\t\t\t\t\t<conversions>\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"values\", suffixedVariableNameList(\"value\", 0, sourceStackSize))\n\t\t\t(\"arrow\", destStackSize > 0 ? \"->\" : \"\")\n\t\t\t(\"converted\", suffixedVariableNameList(\"converted\", 0, destStackSize))\n\t\t\t(\"conversions\", conversions)\n\t\t\t.render();\n\t\t}\n\n\t\tsolUnimplementedAssert(\n\t\t\t_from.category() == Type::Category::StringLiteral,\n\t\t\t\"Type conversion \" + _from.toString() + \" -> \" + _to.toString() + \" not yet implemented.\"\n\t\t);\n\t\tstd::string const& data = dynamic_cast<StringLiteralType const&>(_from).value();\n\t\tif (_to.category() == Type::Category::FixedBytes)\n\t\t{\n\t\t\tunsigned const numBytes = dynamic_cast<FixedBytesType const&>(_to).numBytes();\n\t\t\tsolAssert(data.size() <= 32, \"\");\n\t\t\tWhiskers templ(R\"(\n\t\t\t\tfunction <functionName>() -> converted {\n\t\t\t\t\tconverted := <data>\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\ttempl(\"data\", formatNumber(\n\t\t\t\th256::Arith(h256(data, h256::AlignLeft)) &\n\t\t\t\t(~(u256(-1) >> (8 * numBytes)))\n\t\t\t));\n\t\t\treturn templ.render();\n\t\t}\n\t\telse if (_to.category() == Type::Category::Array)\n\t\t{\n\t\t\tsolAssert(dynamic_cast<ArrayType const&>(_to).isByteArrayOrString(), \"\");\n\t\t\tWhiskers templ(R\"(\n\t\t\t\tfunction <functionName>() -> converted {\n\t\t\t\t\tconverted := <copyLiteralToMemory>()\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\ttempl(\"copyLiteralToMemory\", copyLiteralToMemoryFunction(data));\n\t\t\treturn templ.render();\n\t\t}\n\t\telse\n\t\t\tsolAssert(\n\t\t\t\tfalse,\n\t\t\t\t\"Invalid conversion from std::string literal to \" + _to.toString() + \" requested.\"\n\t\t\t);\n\t});\n}\n\nstd::string YulUtilFunctions::readFromMemoryOrCalldata(Type const& _type, bool _fromCalldata)\n{\n\tstd::string functionName =\n\t\tstd::string(\"read_from_\") +\n\t\t(_fromCalldata ? \"calldata\" : \"memory\") +\n\t\t_type.identifier();\n\n\t// TODO use ABI functions for handling calldata\n\tif (_fromCalldata)\n\t\tsolAssert(!_type.isDynamicallyEncoded(), \"\");\n\n\treturn m_functionCollector.createFunction(functionName, [&] {\n\t\tif (auto refType = dynamic_cast<ReferenceType const*>(&_type))\n\t\t{\n\t\t\tsolAssert(refType->sizeOnStack() == 1, \"\");\n\t\t\tsolAssert(!_fromCalldata, \"\");\n\n\t\t\treturn Whiskers(R\"(\n\t\t\t\tfunction <functionName>(memPtr) -> value {\n\t\t\t\t\tvalue := mload(memPtr)\n\t\t\t\t}\n\t\t\t)\")\n\t\t\t(\"functionName\", functionName)\n\t\t\t.render();\n\t\t}\n\n\t\tsolAssert(_type.isValueType(), \"\");\n\t\tWhiskers templ(R\"(\n\t\t\tfunction <functionName>(ptr) -> <returnVariables> {\n\t\t\t\t<?fromCalldata>\n\t\t\t\t\tlet value := calldataload(ptr)\n\t\t\t\t\t<validate>(value)\n\t\t\t\t<!fromCalldata>\n\t\t\t\t\tlet value := <cleanup>(mload(ptr))\n\t\t\t\t</fromCalldata>\n\n\t\t\t\t<returnVariables> :=\n\t\t\t\t<?externalFunction>\n\t\t\t\t\t<splitFunction>(value)\n\t\t\t\t<!externalFunction>\n\t\t\t\t\tvalue\n\t\t\t\t</externalFunction>\n\t\t\t}\n\t\t)\");\n\t\ttempl(\"functionName\", functionName);\n\t\ttempl(\"fromCalldata\", _fromCalldata);\n\t\tif (_fromCalldata)\n\t\t\ttempl(\"validate\", validatorFunction(_type, true));\n\t\tauto const* funType = dynamic_cast<FunctionType const*>(&_type);\n\t\tif (funType && funType->kind() == FunctionType::Kind::External)\n\t\t{\n\t\t\ttempl(\"externalFunction\", true);\n\t\t\ttempl(\"splitFunction\", splitExternalFunctionIdFunction());\n\t\t\ttempl(\"returnVariables\", \"addr, selector\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttempl(\"externalFunction\", false);\n\t\t\ttempl(\"returnVariables\", \"returnValue\");\n\t\t}\n\n\t\t// Byte array elements generally need cleanup.\n\t\t// Other types are cleaned as well to account for dirty memory e.g. due to inline assembly.\n\t\ttempl(\"cleanup\", cleanupFunction(_type));\n\t\treturn templ.render();\n\t});\n}\n\nstd::string YulUtilFunctions::revertReasonIfDebugFunction(std::string const& _message)\n{\n\tstd::string functionName = \"revert_error_\" + util::toHex(util::keccak256(_message).asBytes());\n\treturn m_functionCollector.createFunction(functionName, [&](auto&, auto&) -> std::string {\n\t\treturn revertReasonIfDebugBody(m_revertStrings, allocateUnboundedFunction() + \"()\", _message);\n\t});\n}\n\nstd::string YulUtilFunctions::revertReasonIfDebugBody(\n\tRevertStrings _revertStrings,\n\tstd::string const& _allocation,\n\tstd::string const& _message\n)\n{\n\tif (_revertStrings < RevertStrings::Debug || _message.empty())\n\t\treturn \"revert(0, 0)\";\n\n\tWhiskers templ(R\"(\n\t\tlet start := <allocate>\n\t\tlet pos := start\n\t\tmstore(pos, <sig>)\n\t\tpos := add(pos, 4)\n\t\tmstore(pos, 0x20)\n\t\tpos := add(pos, 0x20)\n\t\tmstore(pos, <length>)\n\t\tpos := add(pos, 0x20)\n\t\t<#word>\n\t\t\tmstore(add(pos, <offset>), <wordValue>)\n\t\t</word>\n\t\trevert(start, <overallLength>)\n\t)\");\n\ttempl(\"allocate\", _allocation);\n\ttempl(\"sig\", util::selectorFromSignatureU256(\"Error(string)\").str());\n\ttempl(\"length\", std::to_string(_message.length()));\n\n\tsize_t words = (_message.length() + 31) / 32;\n\tstd::vector<std::map<std::string, std::string>> wordParams(words);\n\tfor (size_t i = 0; i < words; ++i)\n\t{\n\t\twordParams[i][\"offset\"] = std::to_string(i * 32);\n\t\twordParams[i][\"wordValue\"] = formatAsStringOrNumber(_message.substr(32 * i, 32));\n\t}\n\ttempl(\"word\", wordParams);\n\ttempl(\"overallLength\", std::to_string(4 + 0x20 + 0x20 + words * 32));\n\n\treturn templ.render();\n}\n\nstd::string YulUtilFunctions::panicFunction(util::PanicCode _code)\n{\n\tstd::string functionName = \"panic_error_\" + toCompactHexWithPrefix(uint64_t(_code));\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn Whiskers(R\"(\n\t\t\tfunction <functionName>() {\n\t\t\t\tmstore(0, <selector>)\n\t\t\t\tmstore(4, <code>)\n\t\t\t\trevert(0, 0x24)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"selector\", util::selectorFromSignatureU256(\"Panic(uint256)\").str())\n\t\t(\"code\", toCompactHexWithPrefix(static_cast<unsigned>(_code)))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::returnDataSelectorFunction()\n{\n\tstd::string const functionName = \"return_data_selector\";\n\tsolAssert(m_evmVersion.supportsReturndata(), \"\");\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn util::Whiskers(R\"(\n\t\t\tfunction <functionName>() -> sig {\n\t\t\t\tif gt(returndatasize(), 3) {\n\t\t\t\t\treturndatacopy(0, 0, 4)\n\t\t\t\t\tsig := <shr224>(mload(0))\n\t\t\t\t}\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"shr224\", shiftRightFunction(224))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::tryDecodeErrorMessageFunction()\n{\n\tstd::string const functionName = \"try_decode_error_message\";\n\tsolAssert(m_evmVersion.supportsReturndata(), \"\");\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn util::Whiskers(R\"(\n\t\t\tfunction <functionName>() -> ret {\n\t\t\t\tif lt(returndatasize(), 0x44) { leave }\n\n\t\t\t\tlet data := <allocateUnbounded>()\n\t\t\t\treturndatacopy(data, 4, sub(returndatasize(), 4))\n\n\t\t\t\tlet offset := mload(data)\n\t\t\t\tif or(\n\t\t\t\t\tgt(offset, 0xffffffffffffffff),\n\t\t\t\t\tgt(add(offset, 0x24), returndatasize())\n\t\t\t\t) {\n\t\t\t\t\tleave\n\t\t\t\t}\n\n\t\t\t\tlet msg := add(data, offset)\n\t\t\t\tlet length := mload(msg)\n\t\t\t\tif gt(length, 0xffffffffffffffff) { leave }\n\n\t\t\t\tlet end := add(add(msg, 0x20), length)\n\t\t\t\tif gt(end, add(data, sub(returndatasize(), 4))) { leave }\n\n\t\t\t\t<finalizeAllocation>(data, add(offset, add(0x20, length)))\n\t\t\t\tret := msg\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"allocateUnbounded\", allocateUnboundedFunction())\n\t\t(\"finalizeAllocation\", finalizeAllocationFunction())\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::tryDecodePanicDataFunction()\n{\n\tstd::string const functionName = \"try_decode_panic_data\";\n\tsolAssert(m_evmVersion.supportsReturndata(), \"\");\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn util::Whiskers(R\"(\n\t\t\tfunction <functionName>() -> success, data {\n\t\t\t\tif gt(returndatasize(), 0x23) {\n\t\t\t\t\treturndatacopy(0, 4, 0x20)\n\t\t\t\t\tsuccess := 1\n\t\t\t\t\tdata := mload(0)\n\t\t\t\t}\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::extractReturndataFunction()\n{\n\tstd::string const functionName = \"extract_returndata\";\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn util::Whiskers(R\"(\n\t\t\tfunction <functionName>() -> data {\n\t\t\t\t<?supportsReturndata>\n\t\t\t\t\tswitch returndatasize()\n\t\t\t\t\tcase 0 {\n\t\t\t\t\t\tdata := <emptyArray>()\n\t\t\t\t\t}\n\t\t\t\t\tdefault {\n\t\t\t\t\t\tdata := <allocateArray>(returndatasize())\n\t\t\t\t\t\treturndatacopy(add(data, 0x20), 0, returndatasize())\n\t\t\t\t\t}\n\t\t\t\t<!supportsReturndata>\n\t\t\t\t\tdata := <emptyArray>()\n\t\t\t\t</supportsReturndata>\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"supportsReturndata\", m_evmVersion.supportsReturndata())\n\t\t(\"allocateArray\", allocateMemoryArrayFunction(*TypeProvider::bytesMemory()))\n\t\t(\"emptyArray\", zeroValueFunction(*TypeProvider::bytesMemory()))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::copyConstructorArgumentsToMemoryFunction(\n\tContractDefinition const& _contract,\n\tstd::string const& _creationObjectName\n)\n{\n\tstd::string functionName = \"copy_arguments_for_constructor_\" +\n\t\ttoString(_contract.constructor()->id()) +\n\t\t\"_object_\" +\n\t\t_contract.name() +\n\t\t\"_\" +\n\t\ttoString(_contract.id());\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\tstd::string returnParams = suffixedVariableNameList(\"ret_param_\",0, CompilerUtils::sizeOnStack(_contract.constructor()->parameters()));\n\t\tABIFunctions abiFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functionCollector);\n\n\t\treturn util::Whiskers(R\"(\n\t\t\tfunction <functionName>() -> <retParams> {\n\t\t\t\t<?eof>\n\t\t\t\t\tlet argSize := calldatasize()\n\t\t\t\t\tlet memoryDataOffset := <allocate>(argSize)\n\t\t\t\t\tcalldatacopy(memoryDataOffset, 0, argSize)\n\t\t\t\t<!eof>\n\t\t\t\t\tlet programSize := datasize(\"<object>\")\n\t\t\t\t\tlet argSize := sub(codesize(), programSize)\n\n\t\t\t\t\tlet memoryDataOffset := <allocate>(argSize)\n\t\t\t\t\tcodecopy(memoryDataOffset, programSize, argSize)\n\t\t\t\t</eof>\n\n\t\t\t\t<retParams> := <abiDecode>(memoryDataOffset, add(memoryDataOffset, argSize))\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"retParams\", returnParams)\n\t\t(\"object\", _creationObjectName)\n\t\t(\"allocate\", allocationFunction())\n\t\t(\"abiDecode\", abiFunctions.tupleDecoder(FunctionType(*_contract.constructor()).parameterTypes(), true))\n\t\t(\"eof\", m_eofVersion.has_value())\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::externalCodeFunction()\n{\n\tstd::string functionName = \"external_code_at\";\n\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn util::Whiskers(R\"(\n\t\t\tfunction <functionName>(addr) -> mpos {\n\t\t\t\tlet length := extcodesize(addr)\n\t\t\t\tmpos := <allocateArray>(length)\n\t\t\t\textcodecopy(addr, add(mpos, 0x20), 0, length)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"allocateArray\", allocateMemoryArrayFunction(*TypeProvider::bytesMemory()))\n\t\t.render();\n\t});\n}\n\nstd::string YulUtilFunctions::externalFunctionPointersEqualFunction()\n{\n\tstd::string const functionName = \"externalFunctionPointersEqualFunction\";\n\treturn m_functionCollector.createFunction(functionName, [&]() {\n\t\treturn util::Whiskers(R\"(\n\t\t\tfunction <functionName>(\n\t\t\t\tleftAddress,\n\t\t\t\tleftSelector,\n\t\t\t\trightAddress,\n\t\t\t\trightSelector\n\t\t\t) -> result {\n\t\t\t\tresult := and(\n\t\t\t\t\teq(\n\t\t\t\t\t\t<addressCleanUpFunction>(leftAddress), <addressCleanUpFunction>(rightAddress)\n\t\t\t\t\t),\n\t\t\t\t\teq(\n\t\t\t\t\t\t<selectorCleanUpFunction>(leftSelector), <selectorCleanUpFunction>(rightSelector)\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t}\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"addressCleanUpFunction\", cleanupFunction(*TypeProvider::address()))\n\t\t(\"selectorCleanUpFunction\", cleanupFunction(*TypeProvider::uint(32)))\n\t\t.render();\n\t});\n}\n"
  },
  {
    "path": "libsolidity/codegen/YulUtilFunctions.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that can generate various useful Yul functions.\n */\n\n#pragma once\n\n#include <liblangutil/EVMVersion.h>\n\n#include <libsolidity/ast/Types.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/codegen/MultiUseYulFunctionCollector.h>\n\n#include <libsolidity/interface/DebugSettings.h>\n\n#include <libsolutil/ErrorCodes.h>\n\n#include <memory>\n#include <string>\n#include <vector>\n\nnamespace solidity::frontend\n{\n\nclass Type;\nclass ArrayType;\nclass MappingType;\nclass IntegerType;\nclass StructType;\n\n/**\n * Component that can generate various useful Yul functions.\n */\nclass YulUtilFunctions\n{\npublic:\n\texplicit YulUtilFunctions(\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tRevertStrings _revertStrings,\n\t\tMultiUseYulFunctionCollector& _functionCollector\n\t):\n\t\tm_evmVersion(_evmVersion),\n\t\tm_eofVersion(_eofVersion),\n\t\tm_revertStrings(_revertStrings),\n\t\tm_functionCollector(_functionCollector)\n\t{}\n\n\t/// @returns the name of a function that returns its argument.\n\t/// Sometimes needed to satisfy templates.\n\tstd::string identityFunction();\n\n\t/// @returns a function that combines the address and selector to a single value\n\t/// for use in the ABI.\n\tstd::string combineExternalFunctionIdFunction();\n\n\t/// @returns a function that splits the address and selector from a single value\n\t/// for use in the ABI.\n\tstd::string splitExternalFunctionIdFunction();\n\n\t/// @returns a function that copies raw bytes of dynamic length from calldata\n\t/// or memory to memory.\n\t/// @params _cleanup If true, pads with zeros up to the 32 byte boundary after the specified length\n\t/// signature: (src, dst, length) ->\n\tstd::string copyToMemoryFunction(bool _fromCalldata, bool _cleanup);\n\n\t/// @returns the name of a function that copies a string literal to memory\n\t/// and returns a pointer to the memory area containing the string literal.\n\t/// signature: () -> memPtr\n\tstd::string copyLiteralToMemoryFunction(std::string const& _literal);\n\n\t/// @returns the name of a function that stores a string literal at a specific location in memory\n\t/// signature: (memPtr) ->\n\tstd::string storeLiteralInMemoryFunction(std::string const& _literal);\n\n\t/// @returns the name of a function that stores a string literal at a specific location in storage\n\t/// signature: (slot) ->\n\tstd::string copyLiteralToStorageFunction(std::string const& _literal);\n\n\t/// @returns statements to revert with an error.\n\t/// Generates code to revert with an error. The error arguments are assumed to\n\t/// be already evaluated and available in local IRVariables, but not yet\n\t/// converted.\n\tstd::string revertWithError(\n\t\tstd::string const& _signature,\n\t\tstd::vector<Type const*> const& _parameterTypes,\n\t\tstd::vector<ASTPointer<Expression const>> const& _errorArguments,\n\t\tstd::string const& _posVar = {},\n\t\tstd::string const& _endVar = {}\n\t);\n\n\t// @returns the name of a function that has the equivalent logic of an\n\t// `assert` or `require` call.\n\tstd::string requireOrAssertFunction(\n\t\tbool _assert,\n\t\tType const* _messageType = nullptr,\n\t\tASTPointer<Expression const> _stringArgumentExpression = nullptr\n\t);\n\n\t// @returns function that has equivalent logic of a require function, but with a custom\n\t// error constructor parameter.\n\tstd::string requireWithErrorFunction(FunctionCall const& errorConstructorCall);\n\n\t/// @returns the name of a function that takes a (cleaned) value of the given value type and\n\t/// left-aligns it, usually for use in non-padded encoding.\n\tstd::string leftAlignFunction(Type const& _type);\n\n\tstd::string shiftLeftFunction(size_t _numBits);\n\tstd::string shiftLeftFunctionDynamic();\n\tstd::string shiftRightFunction(size_t _numBits);\n\tstd::string shiftRightFunctionDynamic();\n\tstd::string shiftRightSignedFunctionDynamic();\n\n\t/// @returns the name of a function that performs a left shift and subsequent cleanup\n\t/// and, if needed, prior cleanup.\n\t/// signature: (value, amountToShift) -> result\n\tstd::string typedShiftLeftFunction(Type const& _type, Type const& _amountType);\n\tstd::string typedShiftRightFunction(Type const& _type, Type const& _amountType);\n\n\t/// @returns the name of a function which replaces the\n\t/// _numBytes bytes starting at byte position _shiftBytes (counted from the least significant\n\t/// byte) by the _numBytes least significant bytes of `toInsert`.\n\t/// signature: (value, toInsert) -> result\n\tstd::string updateByteSliceFunction(size_t _numBytes, size_t _shiftBytes);\n\n\t/// signature: (value, shiftBytes, toInsert) -> result\n\tstd::string updateByteSliceFunctionDynamic(size_t _numBytes);\n\n\t/// Function that sets all but the first ``bytes`` bytes of ``value`` to zero.\n\t/// @note ``bytes`` has to be small enough not to overflow ``8 * bytes``.\n\t/// signature: (value, bytes) -> result\n\tstd::string maskBytesFunctionDynamic();\n\n\t/// Zeroes out all bytes above the first ``_bytes`` lower order bytes.\n\t/// signature: (value) -> result\n\tstd::string maskLowerOrderBytesFunction(size_t _bytes);\n\n\t/// Zeroes out all bytes above the first ``bytes`` lower order bytes.\n\t/// @note ``bytes`` has to be small enough not to overflow ``8 * bytes``.\n\t/// signature: (value, bytes) -> result\n\tstd::string maskLowerOrderBytesFunctionDynamic();\n\n\t/// @returns the name of a function that rounds its input to the next multiple\n\t/// of 32 or the input if it is a multiple of 32.\n\t/// Ignores overflow.\n\t/// signature: (value) -> result\n\tstd::string roundUpFunction();\n\n\t/// @returns the name of a function that divides by 32 and rounds up during the division.\n\t/// In other words, on input x it returns the smallest y such that y * 32 >= x.\n\t/// Ignores overflow.\n\t/// signature: (x) -> y\n\tstd::string divide32CeilFunction();\n\n\t/// signature: (x, y) -> sum\n\tstd::string overflowCheckedIntAddFunction(IntegerType const& _type);\n\t/// signature: (x, y) -> sum\n\tstd::string wrappingIntAddFunction(IntegerType const& _type);\n\n\t/// signature: (x, y) -> product\n\tstd::string overflowCheckedIntMulFunction(IntegerType const& _type);\n\t/// signature: (x, y) -> product\n\tstd::string wrappingIntMulFunction(IntegerType const& _type);\n\n\t/// @returns name of function to perform division on integers.\n\t/// Checks for division by zero and the special case of\n\t/// signed division of the smallest number by -1.\n\tstd::string overflowCheckedIntDivFunction(IntegerType const& _type);\n\t/// @returns name of function to perform division on integers.\n\t/// Checks for division by zero.\n\tstd::string wrappingIntDivFunction(IntegerType const& _type);\n\n\t/// @returns name of function to perform modulo on integers.\n\t/// Reverts for modulo by zero.\n\tstd::string intModFunction(IntegerType const& _type);\n\n\t/// @returns computes the difference between two values.\n\t/// Assumes the input to be in range for the type.\n\t/// signature: (x, y) -> diff\n\tstd::string overflowCheckedIntSubFunction(IntegerType const& _type);\n\n\t/// @returns computes the difference between two values.\n\t/// signature: (x, y) -> diff\n\tstd::string wrappingIntSubFunction(IntegerType const& _type);\n\n\t/// @returns the name of the exponentiation function.\n\t/// signature: (base, exponent) -> power\n\tstd::string overflowCheckedIntExpFunction(IntegerType const& _type, IntegerType const& _exponentType);\n\n\t/// @returns the name of the exponentiation function, specialized for literal base.\n\t/// signature: exponent -> power\n\tstd::string overflowCheckedIntLiteralExpFunction(\n\t\tRationalNumberType const& _baseType,\n\t\tIntegerType const& _exponentType,\n\t\tIntegerType const& _commonType\n\t);\n\n\t/// Generic unsigned checked exponentiation function.\n\t/// Reverts if the result is larger than max.\n\t/// signature: (base, exponent, max) -> power\n\tstd::string overflowCheckedUnsignedExpFunction();\n\n\t/// Generic signed checked exponentiation function.\n\t/// Reverts if the result is smaller than min or larger than max.\n\t/// The code relies on max <= |min| and min < 0.\n\t/// signature: (base, exponent, min, max) -> power\n\tstd::string overflowCheckedSignedExpFunction();\n\n\t/// Helper function for the two checked exponentiation functions.\n\t/// signature: (power, base, exponent, max) -> power\n\tstd::string overflowCheckedExpLoopFunction();\n\n\t/// @returns the name of the exponentiation function.\n\t/// signature: (base, exponent) -> power\n\tstd::string wrappingIntExpFunction(IntegerType const& _type, IntegerType const& _exponentType);\n\n\t/// @returns the name of a function that fetches the length of the given\n\t/// array\n\t/// signature: (array) -> length\n\tstd::string arrayLengthFunction(ArrayType const& _type);\n\n\t/// @returns function name that extracts and returns byte array length from the value\n\t/// stored at the slot.\n\t/// Causes a Panic if the length encoding is wrong.\n\t/// signature: (data) -> length\n\tstd::string extractByteArrayLengthFunction();\n\n\t/// @returns the name of a function that resizes a storage array\n\t/// for statically sized arrays, it will just clean-up elements of array starting from newLen until the end\n\t/// signature: (array, newLen)\n\tstd::string resizeArrayFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that zeroes all storage array elements from `startIndex` to `len` (excluding).\n\t/// Assumes that `len` is the array length. Does nothing if `startIndex >= len`. Does not modify the stored length.\n\t/// signature: (array, len, startIndex)\n\tstd::string cleanUpStorageArrayEndFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that reduces the size of a storage array by one element\n\t/// signature: (array)\n\tstd::string storageArrayPopFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that pushes an element to a storage array\n\t/// @param _fromType represents the type of the element being pushed.\n\t/// If _fromType is ReferenceType the function will perform deep copy.\n\t/// signature: (array, value)\n\tstd::string storageArrayPushFunction(ArrayType const& _type, Type const* _fromType = nullptr);\n\n\t/// @returns the name of a function that pushes the base type's zero element to a storage array and returns storage slot and offset of the added element.\n\t/// signature: (array) -> slot, offset\n\tstd::string storageArrayPushZeroFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that will clear the storage area given\n\t/// by the start position and number of slots to clear. The start position is in terms of storage slots and we\n\t/// assume that the beginning of the clear range starts at the beginning of the start slot.\n\t/// `slot_count` is assumed to be a multiple of `_type.storageSize()`. The function clears storage in increments\n\t/// of `_type.storageSize()` and does not perform any runtime checks.\n\t/// signature: (start_slot, slot_count)\n\tstd::string clearStorageRangeFunction(Type const& _type);\n\n\t/// @returns the name of a function that will clear the given storage array\n\t/// signature: (slot) ->\n\tstd::string clearStorageArrayFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that will copy an array to storage\n\t/// signature (to_slot, from_ptr) ->\n\tstd::string copyArrayToStorageFunction(ArrayType const& _fromType, ArrayType const& _toType);\n\n\t/// @returns the name of a function that will copy a byte array to storage\n\t/// signature (to_slot, from_ptr) ->\n\tstd::string copyByteArrayToStorageFunction(ArrayType const& _fromType, ArrayType const& _toType);\n\n\t/// @returns the name of a function that will copy an array of value types to storage.\n\t/// signature (to_slot, from_ptr[, from_length]) ->\n\tstd::string copyValueArrayToStorageFunction(ArrayType const& _fromType, ArrayType const& _toType);\n\n\t/// Returns the name of a function that will convert a given length to the\n\t/// size in memory (number of storage slots or calldata/memory bytes) it\n\t/// will require.\n\t/// signature: (length) -> size\n\tstd::string arrayConvertLengthToSize(ArrayType const& _type);\n\n\t/// @returns the name of a function that computes the number of bytes required\n\t/// to store an array in memory given its length (internally encoded, not ABI encoded).\n\t/// The function reverts for too large lengths.\n\tstd::string arrayAllocationSizeFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that converts a storage slot number,\n\t/// a memory pointer or a calldata pointer to the slot number / memory pointer / calldata pointer\n\t/// for the data position of an array which is stored in that slot / memory area / calldata area.\n\tstd::string arrayDataAreaFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that returns the slot and offset for the\n\t/// given array and index\n\t/// signature: (array, index) -> slot, offset\n\tstd::string storageArrayIndexAccessFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that returns the memory address for the\n\t/// given array base ref and index.\n\t/// Causes invalid opcode on out of range access.\n\t/// signature: (baseRef, index) -> address\n\tstd::string memoryArrayIndexAccessFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that returns the calldata address for the\n\t/// given array base ref and index.\n\t/// signature: (baseRef, index) -> offset[, length]\n\tstd::string calldataArrayIndexAccessFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that returns offset and length for array slice\n\t/// for the given array offset, length and start and end indices for slice\n\t/// signature: (arrayOffset, arrayLength, sliceStart, sliceEnd) -> offset, length\n\tstd::string calldataArrayIndexRangeAccess(ArrayType const& _type);\n\n\t/// @returns the name of a function that follows a calldata tail while performing\n\t/// bounds checks.\n\t/// signature: (baseRef, tailPointer) -> offset[, length]\n\tstd::string accessCalldataTailFunction(Type const& _type);\n\n\t/// @returns the name of a function that advances an array data pointer to the next element.\n\t/// Only works for memory arrays, calldata arrays and storage arrays that every item occupies one or multiple full slots.\n\tstd::string nextArrayElementFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that allocates a memory array and copies the contents\n\t/// of the storage array into it.\n\tstd::string copyArrayFromStorageToMemoryFunction(ArrayType const& _from, ArrayType const& _to);\n\n\t/// @returns the name of a function that does concatenation of variadic number of\n\t/// bytes if @a functionTypeKind is FunctionType::Kind::BytesConcat,\n\t/// or of strings, if @a functionTypeKind is FunctionType::Kind::StringConcat.\n\tstd::string bytesOrStringConcatFunction(\n\t\tstd::vector<Type const*> const& _argumentTypes,\n\t\tFunctionType::Kind _functionTypeKind\n\t);\n\n\t/// @returns the name of a function that performs index access for mappings.\n\t/// @param _mappingType the type of the mapping\n\t/// @param _keyType the type of the value provided\n\tstd::string mappingIndexAccessFunction(MappingType const& _mappingType, Type const& _keyType);\n\n\t/// @returns a function that reads a type from storage.\n\t/// @param _splitFunctionTypes if false, returns the address and function signature in a\n\t/// single variable.\n\tstd::string readFromStorage(\n\t\tType const& _type,\n\t\tsize_t _offset,\n\t\tbool _splitFunctionTypes,\n\t\tVariableDeclaration::Location _location\n\t);\n\tstd::string readFromStorageDynamic(\n\t\tType const& _type,\n\t\tbool _splitFunctionTypes,\n\t\tVariableDeclaration::Location _location\n\t);\n\n\t/// @returns a function that reads a value type from memory. Performs cleanup.\n\t/// signature: (addr) -> value\n\tstd::string readFromMemory(Type const& _type);\n\t/// @returns a function that reads a value type from calldata.\n\t/// Reverts on invalid input.\n\t/// signature: (addr) -> value\n\tstd::string readFromCalldata(Type const& _type);\n\n\t/// @returns a function that extracts a value type from storage slot that has been\n\t/// retrieved already.\n\t/// Performs bit mask/sign extend cleanup and appropriate left / right shift, but not validation.\n\t///\n\t/// For external function types, input and output is in \"compressed\"/\"unsplit\" form.\n\tstd::string extractFromStorageValue(Type const& _type, size_t _offset);\n\tstd::string extractFromStorageValueDynamic(Type const& _type);\n\n\t/// Returns the name of a function will write the given value to\n\t/// the specified slot and offset. If offset is not given, it is expected as\n\t/// runtime parameter.\n\t/// For reference types, offset is checked to be zero at runtime.\n\t/// signature: (slot, [offset,] value)\n\tstd::string updateStorageValueFunction(\n\t\tType const& _fromType,\n\t\tType const& _toType,\n\t\tVariableDeclaration::Location _location,\n\t\tstd::optional<unsigned> const& _offset = std::optional<unsigned>()\n\t);\n\n\t/// Returns the name of a function that will write the given value to\n\t/// the specified address.\n\t/// Performs a cleanup before writing for value types.\n\t/// signature: (memPtr, value) ->\n\tstd::string writeToMemoryFunction(Type const& _type);\n\n\t/// Performs cleanup after reading from a potentially compressed storage slot.\n\t/// The function does not perform any validation, it just masks or sign-extends\n\t/// higher order bytes or left-aligns (in case of bytesNN).\n\t/// The storage cleanup expects the value to be right-aligned with potentially\n\t/// dirty higher order bytes.\n\t/// For external functions, input and output is in \"compressed\"/\"unsplit\" form.\n\tstd::string cleanupFromStorageFunction(Type const& _type);\n\n\t/// @returns the name of a function that prepares a value of the given type\n\t/// for being stored in storage. This usually includes cleanup and right-alignment\n\t/// to fit the number of bytes in storage.\n\t/// The resulting value might still have dirty higher order bits.\n\tstd::string prepareStoreFunction(Type const& _type);\n\n\t/// @returns the name of a function that allocates memory.\n\t/// Modifies the \"free memory pointer\"\n\t/// signature: (size) -> memPtr\n\tstd::string allocationFunction();\n\n\t/// @returns the name of the function that allocates memory whose size might be defined later.\n\t/// The allocation can be finalized using finalizeAllocationFunction.\n\t/// Any other allocation will invalidate the memory pointer unless finalizeAllocationFunction\n\t/// is called.\n\t/// signature: () -> memPtr\n\tstd::string allocateUnboundedFunction();\n\n\t/// @returns the name of the function that finalizes an unbounded memory allocation,\n\t/// i.e. sets its size and makes the allocation permanent.\n\t/// signature: (memPtr, size) ->\n\tstd::string finalizeAllocationFunction();\n\n\t/// @returns the name of a function that zeroes an array.\n\t/// signature: (dataStart, dataSizeInBytes) ->\n\tstd::string zeroMemoryArrayFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that zeroes a chunk of memory.\n\t/// signature: (dataStart, dataSizeInBytes) ->\n\tstd::string zeroMemoryFunction(Type const& _type);\n\n\t/// @returns the name of a function that zeroes an array\n\t/// where the base does not have simple zero value in memory.\n\t/// signature: (dataStart, dataSizeInBytes) ->\n\tstd::string zeroComplexMemoryArrayFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that allocates a memory array.\n\t/// For dynamic arrays it adds space for length and stores it.\n\t/// The contents of the data area are unspecified.\n\t/// signature: (length) -> memPtr\n\tstd::string allocateMemoryArrayFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that allocates and zeroes a memory array.\n\t/// For dynamic arrays it adds space for length and stores it.\n\t/// signature: (length) -> memPtr\n\tstd::string allocateAndInitializeMemoryArrayFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that allocates a memory struct (no\n\t/// initialization takes place).\n\t/// signature: () -> memPtr\n\tstd::string allocateMemoryStructFunction(StructType const& _type);\n\n\t/// @returns the name of a function that allocates and zeroes a memory struct.\n\t/// signature: () -> memPtr\n\tstd::string allocateAndInitializeMemoryStructFunction(StructType const& _type);\n\n\t/// @returns the name of the function that converts a value of type @a _from\n\t/// to a value of type @a _to. The resulting vale is guaranteed to be in range\n\t/// (i.e. \"clean\"). Asserts on failure.\n\t///\n\t/// This is used for data being encoded or general type conversions in the code.\n\tstd::string conversionFunction(Type const& _from, Type const& _to);\n\n\t/// @returns the name of a function that converts bytes array to fixed bytes type\n\t/// signature: (array) -> value\n\tstd::string bytesToFixedBytesConversionFunction(ArrayType const& _from, FixedBytesType const& _to);\n\n\t/// @returns the name of the cleanup function for the given type and\n\t/// adds its implementation to the requested functions.\n\t/// The cleanup function defers to the validator function with \"assert\"\n\t/// if there is no reasonable way to clean a value.\n\tstd::string cleanupFunction(Type const& _type);\n\n\t/// @returns the name of the validator function for the given type and\n\t/// adds its implementation to the requested functions.\n\t/// @param _revertOnFailure if true, causes revert on invalid data,\n\t/// otherwise an assertion failure.\n\t///\n\t/// This is used for data decoded from external sources.\n\tstd::string validatorFunction(Type const& _type, bool _revertOnFailure);\n\n\tstd::string packedHashFunction(std::vector<Type const*> const& _givenTypes, std::vector<Type const*> const& _targetTypes);\n\n\t/// @returns the name of a function that reverts and uses returndata (if available)\n\t/// as reason string.\n\tstd::string forwardingRevertFunction();\n\n\tstd::string incrementCheckedFunction(Type const& _type);\n\tstd::string incrementWrappingFunction(Type const& _type);\n\tstd::string decrementCheckedFunction(Type const& _type);\n\tstd::string decrementWrappingFunction(Type const& _type);\n\n\tstd::string negateNumberCheckedFunction(Type const& _type);\n\tstd::string negateNumberWrappingFunction(Type const& _type);\n\n\t/// @returns the name of a function that returns the zero value for the\n\t/// provided type.\n\t/// @param _splitFunctionTypes if false, returns two zeroes\n\tstd::string zeroValueFunction(Type const& _type, bool _splitFunctionTypes = true);\n\n\t/// @returns the name of a function that will set the given storage item to\n\t/// zero\n\t/// signature: (slot, offset) ->\n\tstd::string storageSetToZeroFunction(Type const& _type, VariableDeclaration::Location _location);\n\n\t/// If revertStrings is debug, @returns the name of a function that\n\t/// stores @param _message in memory position 0 and reverts.\n\t/// Otherwise returns the name of a function that uses \"revert(0, 0)\".\n\tstd::string revertReasonIfDebugFunction(std::string const& _message = \"\");\n\n\t/// @returns the function body of ``revertReasonIfDebug``.\n\t/// Should only be used internally and by the old code generator.\n\tstatic std::string revertReasonIfDebugBody(\n\t\tRevertStrings _revertStrings,\n\t\tstd::string const& _allocation,\n\t\tstd::string const& _message\n\t);\n\n\t/// Reverts with ``Panic(uint256)`` and the given code.\n\tstd::string panicFunction(util::PanicCode _code);\n\n\t/// @returns the name of a function that returns the return data selector.\n\t/// Returns zero if return data is too short.\n\tstd::string returnDataSelectorFunction();\n\n\t/// @returns the name of a function that tries to abi-decode a string from offset 4 in the\n\t/// return data. On failure, returns 0, otherwise a pointer to the newly allocated string.\n\t/// Does not check the return data signature.\n\t/// signature: () -> ptr\n\tstd::string tryDecodeErrorMessageFunction();\n\n\t/// @returns the name of a function that tries to abi-decode a uint256 value from offset 4 in the\n\t/// return data.\n\t/// Does not check the return data signature.\n\t/// signature: () -> success, value\n\tstd::string tryDecodePanicDataFunction();\n\n\t/// Returns a function name that returns a newly allocated `bytes` array that contains the return data.\n\t///\n\t/// If returndatacopy() is not supported by the underlying target, a empty array will be returned instead.\n\tstd::string extractReturndataFunction();\n\n\t/// @returns function name that returns constructor arguments copied to memory\n\t/// signature: () -> arguments\n\tstd::string copyConstructorArgumentsToMemoryFunction(\n\t\tContractDefinition const& _contract,\n\t\tstd::string const& _creationObjectName\n\t);\n\n\t/// @returns the name of a function that copies code from a given address to a newly\n\t/// allocated byte array in memory.\n\t/// Signature: (address) -> mpos\n\tstd::string externalCodeFunction();\n\n\t/// @return the name of a function that checks if two external functions pointers are equal or not\n\tstd::string externalFunctionPointersEqualFunction();\n\n\t/// Generates a function that calculates storage namespace base address using the ERC-7201 formula.\n\t/// The function expects an address pointing to the data of a byte array stored in memory\n\t/// and the size of the data as its arguments.\n\t/// The function uses scratch space.\n\t/// @return The name of the function.\n\t/// Signature: (namespaceIDDataPtr, namespaceIDLength) -> slot\n\tstd::string erc7201();\n\nprivate:\n\t/// @returns the name of a function that copies a struct from calldata or memory to storage\n\t/// signature: (slot, value) ->\n\tstd::string copyStructToStorageFunction(StructType const& _from, StructType const& _to);\n\n\t/// Special case of conversion functions - handles all array conversions.\n\tstd::string arrayConversionFunction(ArrayType const& _from, ArrayType const& _to);\n\n\t/// Special case of conversionFunction - handles everything that does not\n\t/// use exactly one variable to hold the value.\n\tstd::string conversionFunctionSpecial(Type const& _from, Type const& _to);\n\n\t/// @returns the name of a function that reduces the size of a storage byte array by one element\n\t/// signature: (byteArray)\n\tstd::string storageByteArrayPopFunction(ArrayType const& _type);\n\n\tstd::string readFromMemoryOrCalldata(Type const& _type, bool _fromCalldata);\n\n\t/// @returns a function that reads a value type from storage.\n\t/// Performs bit mask/sign extend cleanup and appropriate left / right shift, but not validation.\n\t/// @param _splitFunctionTypes if false, returns the address and function signature in a\n\t/// single variable.\n\t/// @param _offset if provided, read from static offset, otherwise offset is a parameter of the Yul function.\n\t/// @param _location if provided, indicates whether we're reading from storage our transient storage.\n\tstd::string readFromStorageValueType(\n\t\tType const& _type,\n\t\tstd::optional<size_t> _offset,\n\t\tbool _splitFunctionTypes,\n\t\tVariableDeclaration::Location _location\n\t);\n\t/// @returns a function that reads a reference type from storage to memory (performing a deep copy).\n\tstd::string readFromStorageReferenceType(Type const& _type);\n\n\t/// @returns the name of a function that will clear given storage slot\n\t/// starting with given offset until the end of the slot\n\t/// signature: (slot, offset)\n\tstd::string partialClearStorageSlotFunction();\n\n\t/// @returns the name of a function that will clear the given storage struct\n\t/// signature: (slot) ->\n\tstd::string clearStorageStructFunction(StructType const& _type);\n\n\t/// @returns the name of a function that resizes a storage byte array\n\t/// signature: (array, newLen)\n\tstd::string resizeDynamicByteArrayFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that cleans up elements of a storage byte array starting from startIndex.\n\t/// It will not copy elements in case of transformation to short byte array, and will not change array length.\n\t/// In case of startIndex is greater than len, doesn't do anything.\n\t/// In case of short byte array (< 32 bytes) doesn't do anything.\n\t/// If the first slot to be cleaned up is partially occupied, does not touch it. Cleans up only completely unused slots.\n\t/// signature: (array, len, startIndex)\n\tstd::string cleanUpDynamicByteArrayEndSlotsFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that increases size of byte array\n\t/// 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\n\t/// signature: (array, data, oldLen, newLen)\n\tstd::string increaseByteArraySizeFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that decreases size of byte array\n\t/// when we resize byte array from >= 32 elements to < 32 elements or we pop from byte array of size 32 copying of data will  occur\n\t/// signature: (array, data, oldLen, newLen)\n\tstd::string decreaseByteArraySizeFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that sets size of short byte array while copying data\n\t/// should be called when we resize from long byte array (more than 32 elements) to short byte array\n\t/// signature: (array, data, len)\n\tstd::string byteArrayTransitLongToShortFunction(ArrayType const& _type);\n\n\t/// @returns the name of a function that extracts only used part of slot that represents short byte array\n\t/// signature: (data, len) -> data\n\tstd::string shortByteArrayEncodeUsedAreaSetLengthFunction();\n\n\t/// @returns the name of a function that calculates slot and offset for index\n\t/// Doesn't perform length checks, assumes that index is in bounds\n\t/// signature: (array, index)\n\tstd::string longByteArrayStorageIndexAccessNoCheckFunction();\n\n\tlangutil::EVMVersion m_evmVersion;\n\tstd::optional<uint8_t> m_eofVersion;\n\tRevertStrings m_revertStrings;\n\tMultiUseYulFunctionCollector& m_functionCollector;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ir/Common.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/codegen/ir/Common.h>\n#include <libsolidity/codegen/ir/IRGenerationContext.h>\n\n#include <libsolutil/CommonIO.h>\n\n#include <libyul/AsmPrinter.h>\n\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::util;\nusing namespace solidity::yul;\n\nnamespace solidity::frontend\n{\n\nYulArity YulArity::fromType(FunctionType const& _functionType)\n{\n\treturn YulArity{\n\t\tTupleType(_functionType.parameterTypesIncludingSelf()).sizeOnStack(),\n\t\tTupleType(_functionType.returnParameterTypes()).sizeOnStack()\n\t};\n}\n\nstd::string IRNames::externalFunctionABIWrapper(Declaration const& _functionOrVarDecl)\n{\n\tif (auto const* function = dynamic_cast<FunctionDefinition const*>(&_functionOrVarDecl))\n\t\tsolAssert(!function->isConstructor());\n\n\treturn \"external_fun_\" + _functionOrVarDecl.name() + \"_\" + std::to_string(_functionOrVarDecl.id());\n}\n\nstd::string IRNames::function(FunctionDefinition const& _function)\n{\n\tif (_function.isConstructor())\n\t\treturn constructor(*_function.annotation().contract);\n\n\treturn \"fun_\" + _function.name() + \"_\" + std::to_string(_function.id());\n}\n\nstd::string IRNames::function(VariableDeclaration const& _varDecl)\n{\n\treturn \"getter_fun_\" + _varDecl.name() + \"_\" + std::to_string(_varDecl.id());\n}\n\nstd::string IRNames::modifierInvocation(ModifierInvocation const& _modifierInvocation)\n{\n\t// This uses the ID of the modifier invocation because it has to be unique\n\t// for each invocation.\n\tsolAssert(!_modifierInvocation.name().path().empty(), \"\");\n\tstd::string const& modifierName = _modifierInvocation.name().path().back();\n\tsolAssert(!modifierName.empty(), \"\");\n\treturn \"modifier_\" + modifierName + \"_\" + std::to_string(_modifierInvocation.id());\n}\n\nstd::string IRNames::functionWithModifierInner(FunctionDefinition const& _function)\n{\n\treturn \"fun_\" + _function.name() + \"_\" + std::to_string(_function.id()) + \"_inner\";\n}\n\nstd::string IRNames::creationObject(ContractDefinition const& _contract)\n{\n\treturn _contract.name() + \"_\" + toString(_contract.id());\n}\n\nstd::string IRNames::deployedObject(ContractDefinition const& _contract)\n{\n\treturn _contract.name() + \"_\" + toString(_contract.id()) + \"_deployed\";\n}\n\nstd::string IRNames::internalDispatch(YulArity const& _arity)\n{\n\treturn \"dispatch_internal\"\n\t\t\"_in_\" + std::to_string(_arity.in) +\n\t\t\"_out_\" + std::to_string(_arity.out);\n}\n\nstd::string IRNames::constructor(ContractDefinition const& _contract)\n{\n\treturn \"constructor_\" + _contract.name() + \"_\" + std::to_string(_contract.id());\n}\n\nstd::string IRNames::libraryAddressImmutable()\n{\n\treturn \"library_deploy_address\";\n}\n\nstd::string IRNames::constantValueFunction(VariableDeclaration const& _constant)\n{\n\tsolAssert(_constant.isConstant(), \"\");\n\treturn \"constant_\" + _constant.name() + \"_\" + std::to_string(_constant.id());\n}\n\nstd::string IRNames::localVariable(VariableDeclaration const& _declaration)\n{\n\treturn \"var_\" + _declaration.name() + '_' + std::to_string(_declaration.id());\n}\n\nstd::string IRNames::localVariable(Expression const& _expression)\n{\n\treturn \"expr_\" + std::to_string(_expression.id());\n}\n\nstd::string IRNames::trySuccessConditionVariable(Expression const& _expression)\n{\n\tauto annotation = dynamic_cast<FunctionCallAnnotation const*>(&_expression.annotation());\n\tsolAssert(annotation, \"\");\n\tsolAssert(annotation->tryCall, \"Parameter must be a FunctionCall with tryCall-annotation set.\");\n\n\treturn \"trySuccessCondition_\" + std::to_string(_expression.id());\n}\n\nstd::string IRNames::tupleComponent(size_t _i)\n{\n\treturn \"component_\" + std::to_string(_i + 1);\n}\n\nstd::string IRNames::zeroValue(Type const& _type, std::string const& _variableName)\n{\n\treturn \"zero_\" + _type.identifier() + _variableName;\n}\n\nstd::string dispenseLocationComment(langutil::SourceLocation const& _location, IRGenerationContext& _context)\n{\n\tsolAssert(_location.sourceName, \"\");\n\t_context.markSourceUsed(*_location.sourceName);\n\n\tstd::string debugInfo = AsmPrinter::formatSourceLocation(\n\t\t_location,\n\t\t_context.sourceIndices(),\n\t\t_context.debugInfoSelection(),\n\t\t_context.soliditySourceProvider()\n\t);\n\n\treturn debugInfo.empty() ? \"\" : \"/// \" + debugInfo;\n}\n\nstd::string dispenseLocationComment(ASTNode const& _node, IRGenerationContext& _context)\n{\n\treturn dispenseLocationComment(_node.location(), _context);\n}\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ir/Common.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Miscellaneous utilities for use in IR generator.\n */\n\n#pragma once\n\n#include <libsolidity/ast/AST.h>\n\n#include <algorithm>\n#include <string>\n\nnamespace solidity::frontend\n{\n\nclass IRGenerationContext;\n\n/**\n * Structure that describes arity and co-arity of a Yul function, i.e. the number of its inputs and outputs.\n */\nstruct YulArity\n{\n\texplicit YulArity(size_t _in, size_t _out): in(_in), out(_out) {}\n\n\tstatic YulArity fromType(FunctionType const& _functionType);\n\n\tbool operator==(YulArity const& _other) const { return in == _other.in && out == _other.out; }\n\tbool operator!=(YulArity const& _other) const { return !(*this == _other); }\n\n\tsize_t in;  /// Number of input parameters\n\tsize_t out; /// Number of output parameters\n};\n\nstruct IRNames\n{\n\tstatic std::string externalFunctionABIWrapper(Declaration const& _functionOrVardecl);\n\tstatic std::string function(FunctionDefinition const& _function);\n\tstatic std::string function(VariableDeclaration const& _varDecl);\n\tstatic std::string modifierInvocation(ModifierInvocation const& _modifierInvocation);\n\tstatic std::string functionWithModifierInner(FunctionDefinition const& _function);\n\tstatic std::string creationObject(ContractDefinition const& _contract);\n\tstatic std::string deployedObject(ContractDefinition const& _contract);\n\tstatic std::string internalDispatch(YulArity const& _arity);\n\tstatic std::string constructor(ContractDefinition const& _contract);\n\tstatic std::string libraryAddressImmutable();\n\tstatic std::string constantValueFunction(VariableDeclaration const& _constant);\n\tstatic std::string localVariable(VariableDeclaration const& _declaration);\n\tstatic std::string localVariable(Expression const& _expression);\n\t/// @returns the variable name that can be used to inspect the success or failure of an external\n\t/// function call that was invoked as part of the try statement.\n\tstatic std::string trySuccessConditionVariable(Expression const& _expression);\n\tstatic std::string tupleComponent(size_t _i);\n\tstatic std::string zeroValue(Type const& _type, std::string const& _variableName);\n};\n\n\n/**\n * @returns a source location comment in the form of\n * `/// @src <sourceIndex>:<locationStart>:<locationEnd>`\n * and marks the source index as used.\n */\nstd::string dispenseLocationComment(langutil::SourceLocation const& _location, IRGenerationContext& _context);\nstd::string dispenseLocationComment(ASTNode const& _node, IRGenerationContext& _context);\n\n}\n\n// Overloading std::less() makes it possible to use YulArity as a map key. We could define operator<\n// instead but such an operator would be a bit ambiguous (e.g. YulArity{2, 2} would be greater than\n// YulArity{1, 10} in lexicographical order but the latter has greater total number of inputs and outputs).\ntemplate<>\nstruct std::less<solidity::frontend::YulArity>\n{\n\tbool operator() (solidity::frontend::YulArity const& _lhs, solidity::frontend::YulArity const& _rhs) const\n\t{\n\t\treturn _lhs.in < _rhs.in || (_lhs.in == _rhs.in && _lhs.out < _rhs.out);\n\t}\n};\n"
  },
  {
    "path": "libsolidity/codegen/ir/IRGenerationContext.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Class that contains contextual information during IR generation.\n */\n\n#include <libsolidity/codegen/ir/IRGenerationContext.h>\n\n#include <libsolidity/codegen/YulUtilFunctions.h>\n#include <libsolidity/codegen/ABIFunctions.h>\n#include <libsolidity/codegen/CompilerUtils.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n\n#include <libsolutil/Whiskers.h>\n#include <libsolutil/StringUtils.h>\n\n#include <range/v3/view/map.hpp>\n#include <range/v3/algorithm/find.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::frontend;\n\nstd::string IRGenerationContext::enqueueFunctionForCodeGeneration(FunctionDefinition const& _function)\n{\n\tstd::string name = IRNames::function(_function);\n\n\tif (!m_functions.contains(name))\n\t\tm_functionGenerationQueue.push_back(&_function);\n\n\treturn name;\n}\n\nFunctionDefinition const* IRGenerationContext::dequeueFunctionForCodeGeneration()\n{\n\tsolAssert(!m_functionGenerationQueue.empty(), \"\");\n\n\tFunctionDefinition const* result = m_functionGenerationQueue.front();\n\tm_functionGenerationQueue.pop_front();\n\treturn result;\n}\n\nContractDefinition const& IRGenerationContext::mostDerivedContract() const\n{\n\tsolAssert(m_mostDerivedContract, \"Most derived contract requested but not set.\");\n\treturn *m_mostDerivedContract;\n}\n\nIRVariable const& IRGenerationContext::addLocalVariable(VariableDeclaration const& _varDecl)\n{\n\tauto const& [it, didInsert] = m_localVariables.emplace(\n\t\tstd::make_pair(&_varDecl, IRVariable{_varDecl})\n\t);\n\tsolAssert(didInsert, \"Local variable added multiple times.\");\n\treturn it->second;\n}\n\nIRVariable const& IRGenerationContext::localVariable(VariableDeclaration const& _varDecl)\n{\n\tsolAssert(\n\t\tm_localVariables.count(&_varDecl),\n\t\t\"Unknown variable: \" + _varDecl.name()\n\t);\n\treturn m_localVariables.at(&_varDecl);\n}\n\nvoid IRGenerationContext::resetLocalVariables()\n{\n\tm_localVariables.clear();\n}\n\nvoid IRGenerationContext::registerImmutableVariable(VariableDeclaration const& _variable)\n{\n\tsolAssert(m_executionContext != ExecutionContext::Deployed);\n\tsolAssert(_variable.immutable(), \"Attempted to register a non-immutable variable as immutable.\");\n\tsolUnimplementedAssert(\n\t\t_variable.annotation().type->isValueType(),\n\t\t\"Only immutable variables of value type are supported.\"\n\t);\n\tsolAssert(m_reservedMemory.has_value(), \"Reserved memory has already been reset.\");\n\tm_immutableVariables[&_variable] = CompilerUtils::generalPurposeMemoryStart + *m_reservedMemory;\n\tsolAssert(_variable.annotation().type->memoryHeadSize() == 32, \"Memory writes might overlap.\");\n\t*m_reservedMemory += _variable.annotation().type->memoryHeadSize();\n}\n\nsize_t IRGenerationContext::immutableMemoryOffset(VariableDeclaration const& _variable) const\n{\n\tsolAssert(\n\t\tm_immutableVariables.count(&_variable),\n\t\t\"Unknown immutable variable: \" + _variable.name()\n\t);\n\treturn m_immutableVariables.at(&_variable);\n}\n\nsize_t IRGenerationContext::immutableMemoryOffsetRelative(VariableDeclaration const& _variable) const\n{\n\tauto const absoluteOffset = immutableMemoryOffset(_variable);\n\tsolAssert(absoluteOffset >= CompilerUtils::generalPurposeMemoryStart);\n\treturn absoluteOffset - CompilerUtils::generalPurposeMemoryStart;\n}\n\nsize_t IRGenerationContext::reservedMemorySize() const\n{\n\tsolAssert(m_reservedMemory.has_value());\n\treturn *m_reservedMemory;\n}\n\nvoid IRGenerationContext::registerLibraryAddressImmutable()\n{\n\tsolAssert(m_executionContext != ExecutionContext::Deployed);\n\tsolAssert(m_reservedMemory.has_value(), \"Reserved memory has already been reset.\");\n\tsolAssert(!m_libraryAddressImmutableOffset.has_value());\n\tm_libraryAddressImmutableOffset = CompilerUtils::generalPurposeMemoryStart + *m_reservedMemory;\n\t*m_reservedMemory += 32;\n}\n\nsize_t IRGenerationContext::libraryAddressImmutableOffset() const\n{\n\tsolAssert(m_libraryAddressImmutableOffset.has_value());\n\treturn *m_libraryAddressImmutableOffset;\n}\n\nsize_t IRGenerationContext::libraryAddressImmutableOffsetRelative() const\n{\n\tsolAssert(m_libraryAddressImmutableOffset.has_value());\n\tsolAssert(m_libraryAddressImmutableOffset >= CompilerUtils::generalPurposeMemoryStart);\n\treturn *m_libraryAddressImmutableOffset - CompilerUtils::generalPurposeMemoryStart;\n}\n\nsize_t IRGenerationContext::reservedMemory()\n{\n\tsolAssert(m_reservedMemory.has_value(), \"Reserved memory was used before.\");\n\tsize_t reservedMemory = *m_reservedMemory;\n\n\t// We assume reserved memory contains only immutable variables.\n\t// This memory is used i.e. by RETURNCONTRACT to create new EOF container with aux data.\n\tsize_t immutableVariablesSize = 0;\n\tfor (auto const* var: keys(m_immutableVariables))\n\t{\n\t\tsolUnimplementedAssert(var->type()->isValueType());\n\t\tsolUnimplementedAssert(var->type()->sizeOnStack() == 1);\n\t\timmutableVariablesSize += var->type()->sizeOnStack() * 32;\n\t}\n\n\t// In Creation context check that only immutable variables or library address are stored in the reserved memory.\n\t// In Deployed context (for EOF) m_immutableVariables contains offsets in EOF data section.\n\tsolAssert(\n\t\t(m_executionContext == ExecutionContext::Creation &&\n\t\t\treservedMemory == immutableVariablesSize + (m_libraryAddressImmutableOffset.has_value() ? 32 : 0)) ||\n\t\t(m_executionContext == ExecutionContext::Deployed && reservedMemory == 0)\n\t);\n\n\tm_reservedMemory = std::nullopt;\n\treturn reservedMemory;\n}\n\nvoid IRGenerationContext::addStateVariable(\n\tVariableDeclaration const& _declaration,\n\tu256 _storageOffset,\n\tunsigned _byteOffset\n)\n{\n\tm_stateVariables[&_declaration] = std::make_pair(std::move(_storageOffset), _byteOffset);\n}\n\nstd::string IRGenerationContext::newYulVariable()\n{\n\treturn \"_\" + std::to_string(++m_varCounter);\n}\n\nvoid IRGenerationContext::initializeInternalDispatch(InternalDispatchMap _internalDispatch)\n{\n\tsolAssert(internalDispatchClean(), \"\");\n\n\tfor (DispatchQueue const& functions: _internalDispatch | ranges::views::values)\n\t\tfor (auto function: functions)\n\t\t\tenqueueFunctionForCodeGeneration(*function);\n\n\tm_internalDispatchMap = std::move(_internalDispatch);\n}\n\nInternalDispatchMap IRGenerationContext::consumeInternalDispatchMap()\n{\n\tInternalDispatchMap internalDispatch = std::move(m_internalDispatchMap);\n\tm_internalDispatchMap.clear();\n\treturn internalDispatch;\n}\n\nvoid IRGenerationContext::addToInternalDispatch(FunctionDefinition const& _function)\n{\n\tFunctionType const* functionType = TypeProvider::function(_function, FunctionType::Kind::Internal);\n\tsolAssert(functionType);\n\n\tYulArity arity = YulArity::fromType(*functionType);\n\tDispatchQueue& dispatchQueue = m_internalDispatchMap[arity];\n\tif (ranges::find(dispatchQueue, &_function) == ranges::end(dispatchQueue))\n\t{\n\t\tdispatchQueue.push_back(&_function);\n\t\tenqueueFunctionForCodeGeneration(_function);\n\t}\n}\n\n\nvoid IRGenerationContext::internalFunctionCalledThroughDispatch(YulArity const& _arity)\n{\n\tm_internalDispatchMap.try_emplace(_arity);\n}\n\nYulUtilFunctions IRGenerationContext::utils()\n{\n\treturn YulUtilFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functions);\n}\n\nABIFunctions IRGenerationContext::abiFunctions()\n{\n\treturn ABIFunctions(m_evmVersion, m_eofVersion, m_revertStrings, m_functions);\n}\n"
  },
  {
    "path": "libsolidity/codegen/ir/IRGenerationContext.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Class that contains contextual information during IR generation.\n */\n\n#pragma once\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/codegen/ir/IRVariable.h>\n#include <libsolidity/interface/DebugSettings.h>\n\n#include <libsolidity/codegen/MultiUseYulFunctionCollector.h>\n#include <libsolidity/codegen/ir/Common.h>\n\n#include <liblangutil/CharStreamProvider.h>\n#include <liblangutil/DebugInfoSelection.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <libsolutil/Common.h>\n\n#include <set>\n#include <string>\n#include <memory>\n#include <deque>\n\nnamespace solidity::frontend\n{\n\nclass YulUtilFunctions;\nclass ABIFunctions;\n\nusing DispatchQueue = std::deque<FunctionDefinition const*>;\nusing InternalDispatchMap = std::map<YulArity, DispatchQueue>;\n\n/**\n * Class that contains contextual information during IR generation.\n */\nclass IRGenerationContext\n{\npublic:\n\tenum class ExecutionContext { Creation, Deployed };\n\n\tIRGenerationContext(\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tExecutionContext _executionContext,\n\t\tRevertStrings _revertStrings,\n\t\tstd::map<std::string, unsigned> _sourceIndices,\n\t\tlangutil::DebugInfoSelection const& _debugInfoSelection,\n\t\tlangutil::CharStreamProvider const* _soliditySourceProvider\n\t):\n\t\tm_evmVersion(_evmVersion),\n\t\tm_eofVersion(_eofVersion),\n\t\tm_executionContext(_executionContext),\n\t\tm_revertStrings(_revertStrings),\n\t\tm_sourceIndices(std::move(_sourceIndices)),\n\t\tm_debugInfoSelection(_debugInfoSelection),\n\t\tm_soliditySourceProvider(_soliditySourceProvider)\n\t{}\n\n\tMultiUseYulFunctionCollector& functionCollector() { return m_functions; }\n\n\t/// Adds a Solidity function to the function generation queue and returns the name of the\n\t/// corresponding Yul function.\n\tstd::string enqueueFunctionForCodeGeneration(FunctionDefinition const& _function);\n\n\t/// Pops one item from the function generation queue. Must not be called if the queue is empty.\n\tFunctionDefinition const* dequeueFunctionForCodeGeneration();\n\n\tbool functionGenerationQueueEmpty() { return m_functionGenerationQueue.empty(); }\n\n\t/// Sets the most derived contract (the one currently being compiled)>\n\tvoid setMostDerivedContract(ContractDefinition const& _mostDerivedContract)\n\t{\n\t\tm_mostDerivedContract = &_mostDerivedContract;\n\t}\n\tContractDefinition const& mostDerivedContract() const;\n\n\n\tIRVariable const& addLocalVariable(VariableDeclaration const& _varDecl);\n\tbool isLocalVariable(VariableDeclaration const& _varDecl) const { return m_localVariables.count(&_varDecl); }\n\tIRVariable const& localVariable(VariableDeclaration const& _varDecl);\n\tvoid resetLocalVariables();\n\n\t/// Registers an immutable variable of the contract.\n\t/// Should only be called at construction time.\n\tvoid registerImmutableVariable(VariableDeclaration const& _varDecl);\n\tvoid registerLibraryAddressImmutable();\n\tsize_t libraryAddressImmutableOffset() const;\n\tsize_t libraryAddressImmutableOffsetRelative() const;\n\t/// @returns the reserved memory for storing the value of the\n\t/// immutable @a _variable during contract creation.\n\tsize_t immutableMemoryOffset(VariableDeclaration const& _variable) const;\n\tsize_t immutableMemoryOffsetRelative(VariableDeclaration const& _variable) const;\n\t/// @returns the reserved memory and resets it to mark it as used.\n\t/// Intended to be used only once for initializing the free memory pointer\n\t/// to after the area used for immutables.\n\tsize_t reservedMemory();\n\tsize_t reservedMemorySize() const;\n\n\tvoid addStateVariable(VariableDeclaration const& _varDecl, u256 _storageOffset, unsigned _byteOffset);\n\tbool isStateVariable(VariableDeclaration const& _varDecl) const { return m_stateVariables.count(&_varDecl); }\n\tstd::pair<u256, unsigned> storageLocationOfStateVariable(VariableDeclaration const& _varDecl) const\n\t{\n\t\tsolAssert(isStateVariable(_varDecl), \"\");\n\t\treturn m_stateVariables.at(&_varDecl);\n\t}\n\n\tstd::string newYulVariable();\n\n\tvoid initializeInternalDispatch(InternalDispatchMap _internalDispatchMap);\n\tInternalDispatchMap consumeInternalDispatchMap();\n\tbool internalDispatchClean() const { return m_internalDispatchMap.empty(); }\n\n\t/// Notifies the context that a function call that needs to go through internal dispatch was\n\t/// encountered while visiting the AST. This ensures that the corresponding dispatch function\n\t/// gets added to the dispatch map even if there are no entries in it (which may happen if\n\t/// the code contains a call to an uninitialized function variable).\n\tvoid internalFunctionCalledThroughDispatch(YulArity const& _arity);\n\n\t/// Adds a function to the internal dispatch.\n\tvoid addToInternalDispatch(FunctionDefinition const& _function);\n\n\t/// @returns a new copy of the utility function generator (but using the same function set).\n\tYulUtilFunctions utils();\n\n\tlangutil::EVMVersion evmVersion() const { return m_evmVersion; }\n\tstd::optional<uint8_t> eofVersion() const { return m_eofVersion; }\n\tExecutionContext executionContext() const { return m_executionContext; }\n\n\tvoid setArithmetic(Arithmetic _value) { m_arithmetic = _value; }\n\tArithmetic arithmetic() const { return m_arithmetic; }\n\n\tABIFunctions abiFunctions();\n\n\tRevertStrings revertStrings() const { return m_revertStrings; }\n\n\tutil::UniqueVector<ContractDefinition const*> const& subObjectsCreated() const { return m_subObjects; }\n\tvoid addSubObject(ContractDefinition const* _contractDefinition) { m_subObjects.pushBack(_contractDefinition); }\n\n\tbool memoryUnsafeInlineAssemblySeen() const { return m_memoryUnsafeInlineAssemblySeen; }\n\tvoid setMemoryUnsafeInlineAssemblySeen() { m_memoryUnsafeInlineAssemblySeen = true; }\n\n\tstd::map<std::string, unsigned> const& sourceIndices() const { return m_sourceIndices; }\n\tvoid markSourceUsed(std::string const& _name) { m_usedSourceNames.insert(_name); }\n\tstd::set<std::string> const& usedSourceNames() const { return m_usedSourceNames; }\n\n\tbool immutableRegistered(VariableDeclaration const& _varDecl) const { return m_immutableVariables.count(&_varDecl); }\n\n\tlangutil::DebugInfoSelection debugInfoSelection() const { return m_debugInfoSelection; }\n\tlangutil::CharStreamProvider const* soliditySourceProvider() const { return m_soliditySourceProvider; }\n\tstd::map<VariableDeclaration const*, size_t> const& immutableVariables() const { return m_immutableVariables; }\n\tvoid setImmutableVariables(std::map<VariableDeclaration const*, size_t> _immutableVariables)\n\t{\n\t\tsolAssert(m_eofVersion.has_value());\n\t\tsolAssert(m_executionContext == ExecutionContext::Deployed);\n\t\tm_immutableVariables = std::move(_immutableVariables);\n\t}\n\tvoid setLibraryAddressImmutableOffset(size_t _libraryAddressImmutableOffset)\n\t{\n\t\tsolAssert(m_eofVersion.has_value());\n\t\tsolAssert(m_executionContext == ExecutionContext::Deployed);\n\t\tm_libraryAddressImmutableOffset = _libraryAddressImmutableOffset;\n\t}\n\nprivate:\n\tlangutil::EVMVersion m_evmVersion;\n\tstd::optional<uint8_t> m_eofVersion;\n\tExecutionContext m_executionContext;\n\tRevertStrings m_revertStrings;\n\tstd::map<std::string, unsigned> m_sourceIndices;\n\tstd::set<std::string> m_usedSourceNames;\n\tContractDefinition const* m_mostDerivedContract = nullptr;\n\tstd::map<VariableDeclaration const*, IRVariable> m_localVariables;\n\t/// Memory offsets reserved for the values of immutable variables during contract creation.\n\t/// This map is empty in the legacy runtime context and may be not empty in EOF runtime context.\n\tstd::map<VariableDeclaration const*, size_t> m_immutableVariables;\n\tstd::optional<size_t> m_libraryAddressImmutableOffset;\n\t/// Total amount of reserved memory. Reserved memory is used to store\n\t/// immutable variables during contract creation.\n\tstd::optional<size_t> m_reservedMemory = {0};\n\t/// Storage offsets of state variables\n\tstd::map<VariableDeclaration const*, std::pair<u256, unsigned>> m_stateVariables;\n\tMultiUseYulFunctionCollector m_functions;\n\tsize_t m_varCounter = 0;\n\t/// Whether to use checked or wrapping arithmetic.\n\tArithmetic m_arithmetic = Arithmetic::Checked;\n\n\t/// Flag indicating whether any memory-unsafe inline assembly block was seen.\n\tbool m_memoryUnsafeInlineAssemblySeen = false;\n\n\t/// Function definitions queued for code generation. They're the Solidity functions whose calls\n\t/// were discovered by the IR generator during AST traversal.\n\t/// Note that the queue gets filled in a lazy way - new definitions can be added while the\n\t/// collected ones get removed and traversed.\n\t/// The order and duplicates are relevant here\n\t/// (see: IRGenerationContext::[enqueue|dequeue]FunctionForCodeGeneration)\n\tDispatchQueue m_functionGenerationQueue;\n\n\t/// Collection of functions that need to be callable via internal dispatch.\n\t/// Note that having a key with an empty set of functions is a valid situation. It means that\n\t/// the code contains a call via a pointer even though a specific function is never assigned to it.\n\t/// It will fail at runtime but the code must still compile.\n\tInternalDispatchMap m_internalDispatchMap;\n\n\tutil::UniqueVector<ContractDefinition const*> m_subObjects;\n\n\tlangutil::DebugInfoSelection m_debugInfoSelection = {};\n\tlangutil::CharStreamProvider const* m_soliditySourceProvider = nullptr;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ir/IRGenerator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Alex Beregszaszi\n * @date 2017\n * Component that translates Solidity code into Yul.\n */\n\n#include <libsolidity/codegen/ir/Common.h>\n#include <libsolidity/codegen/ir/IRGenerator.h>\n#include <libsolidity/codegen/ir/IRGeneratorForStatements.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/codegen/ABIFunctions.h>\n#include <libsolidity/codegen/CompilerUtils.h>\n\n#include <libyul/Object.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/Whiskers.h>\n#include <libsolutil/JSON.h>\n\n#include <range/v3/algorithm/all_of.hpp>\n\n#include <sstream>\n#include <variant>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\nusing namespace std::string_literals;\n\nnamespace\n{\n\nvoid verifyCallGraph(\n\tstd::set<CallableDeclaration const*, ASTNode::CompareByID> const& _expectedCallables,\n\tstd::set<FunctionDefinition const*> _generatedFunctions\n)\n{\n\tfor (auto const& expectedCallable: _expectedCallables)\n\t\tif (auto const* expectedFunction = dynamic_cast<FunctionDefinition const*>(expectedCallable))\n\t\t{\n\t\t\tsolAssert(\n\t\t\t\t_generatedFunctions.count(expectedFunction) == 1 || expectedFunction->isConstructor(),\n\t\t\t\t\"No code generated for function \" + expectedFunction->name() + \" even though it is not a constructor.\"\n\t\t\t);\n\t\t\t_generatedFunctions.erase(expectedFunction);\n\t\t}\n\n\tsolAssert(\n\t\t_generatedFunctions.size() == 0,\n\t\t\"Of the generated functions \" + toString(_generatedFunctions.size()) + \" are not in the call graph.\"\n\t);\n}\n\nstd::set<CallableDeclaration const*, ASTNode::CompareByID> collectReachableCallables(\n\tCallGraph const& _graph\n)\n{\n\tstd::set<CallableDeclaration const*, ASTNode::CompareByID> reachableCallables;\n\tfor (CallGraph::Node const& reachableNode: _graph.edges | ranges::views::keys)\n\t\tif (std::holds_alternative<CallableDeclaration const*>(reachableNode))\n\t\t\treachableCallables.emplace(std::get<CallableDeclaration const*>(reachableNode));\n\n\treturn reachableCallables;\n}\n\n}\n\nstd::string IRGenerator::run(\n\tContractDefinition const& _contract,\n\tbytes const& _cborMetadata,\n\tstd::map<ContractDefinition const*, std::string_view const> const& _otherYulSources\n)\n{\n\treturn yul::reindent(generate(_contract, _cborMetadata, _otherYulSources));\n}\n\nstd::string IRGenerator::generate(\n\tContractDefinition const& _contract,\n\tbytes const& _cborMetadata,\n\tstd::map<ContractDefinition const*, std::string_view const> const& _otherYulSources\n)\n{\n\tauto subObjectSources = [&_otherYulSources](UniqueVector<ContractDefinition const*> const& _subObjects) -> std::string\n\t{\n\t\tstd::string subObjectsSources;\n\t\tfor (ContractDefinition const* subObject: _subObjects)\n\t\t\tsubObjectsSources += _otherYulSources.at(subObject);\n\t\treturn subObjectsSources;\n\t};\n\tauto formatUseSrcMap = [](IRGenerationContext const& _context) -> std::string\n\t{\n\t\treturn joinHumanReadable(\n\t\t\tranges::views::transform(_context.usedSourceNames(), [_context](std::string const& _sourceName) {\n\t\t\t\treturn std::to_string(_context.sourceIndices().at(_sourceName)) + \":\" + escapeAndQuoteString(_sourceName);\n\t\t\t}),\n\t\t\t\", \"\n\t\t);\n\t};\n\n\tWhiskers t(R\"(<?isEthdebugEnabled>/// ethdebug: enabled</isEthdebugEnabled>\n\t\t/// @use-src <useSrcMapCreation>\n\t\tobject \"<CreationObject>\" {\n\t\t\tcode {\n\t\t\t\t<sourceLocationCommentCreation>\n\t\t\t\t<memoryInitCreation>\n\t\t\t\t<callValueCheck>\n\t\t\t\t<?library>\n\t\t\t\t<!library>\n\t\t\t\t<?constructorHasParams> let <constructorParams> := <copyConstructorArguments>() </constructorHasParams>\n\t\t\t\t<constructor>(<constructorParams>)\n\t\t\t\t</library>\n\t\t\t\t<deploy>\n\t\t\t\t<functions>\n\t\t\t}\n\t\t\t/// @use-src <useSrcMapDeployed>\n\t\t\tobject \"<DeployedObject>\" {\n\t\t\t\tcode {\n\t\t\t\t\t<sourceLocationCommentDeployed>\n\t\t\t\t\t<memoryInitDeployed>\n\t\t\t\t\t<?library>\n\t\t\t\t\t\t<?eof>\n\t\t\t\t\t\t\tlet called_via_delegatecall := iszero(eq(auxdataloadn(<library_address_immutable_offset>), address()))\n\t\t\t\t\t\t<!eof>\n\t\t\t\t\t\t\tlet called_via_delegatecall := iszero(eq(loadimmutable(\"<library_address>\"), address()))\n\t\t\t\t\t\t</eof>\n\t\t\t\t\t</library>\n\t\t\t\t\t<dispatch>\n\t\t\t\t\t<deployedFunctions>\n\t\t\t\t}\n\t\t\t\t<deployedSubObjects>\n\t\t\t\tdata \"<metadataName>\" hex\"<cborMetadata>\"\n\t\t\t}\n\t\t\t<subObjects>\n\t\t}\n\t)\");\n\n\tresetContext(_contract, ExecutionContext::Creation);\n\tauto const eof = m_context.eofVersion().has_value();\n\tif (eof && _contract.isLibrary())\n\t\tm_context.registerLibraryAddressImmutable();\n\tfor (VariableDeclaration const* var: ContractType(_contract).immutableVariables())\n\t\tm_context.registerImmutableVariable(*var);\n\n\tt(\"isEthdebugEnabled\", m_context.debugInfoSelection().ethdebug);\n\tt(\"CreationObject\", IRNames::creationObject(_contract));\n\tt(\"sourceLocationCommentCreation\", dispenseLocationComment(_contract));\n\tt(\"library\", _contract.isLibrary());\n\n\tFunctionDefinition const* constructor = _contract.constructor();\n\tt(\"callValueCheck\", !constructor || !constructor->isPayable() ? callValueCheck() : \"\");\n\tstd::vector<std::string> constructorParams;\n\tif (constructor && !constructor->parameters().empty())\n\t{\n\t\tfor (size_t i = 0; i < CompilerUtils::sizeOnStack(constructor->parameters()); ++i)\n\t\t\tconstructorParams.emplace_back(m_context.newYulVariable());\n\t\tt(\n\t\t\t\"copyConstructorArguments\",\n\t\t\tm_utils.copyConstructorArgumentsToMemoryFunction(\n\t\t\t\t_contract,\n\t\t\t\tIRNames::creationObject(_contract)\n\t\t\t)\n\t\t);\n\t}\n\tt(\"constructorParams\", joinHumanReadable(constructorParams));\n\tt(\"constructorHasParams\", !constructorParams.empty());\n\tt(\"constructor\", IRNames::constructor(_contract));\n\n\tt(\"deploy\", deployCode(_contract));\n\tgenerateConstructors(_contract);\n\tstd::set<FunctionDefinition const*> creationFunctionList = generateQueuedFunctions();\n\tInternalDispatchMap internalDispatchMap = generateInternalDispatchFunctions(_contract);\n\n\tt(\"functions\", m_context.functionCollector().requestedFunctions());\n\tt(\"subObjects\", subObjectSources(m_context.subObjectsCreated()));\n\n\t// This has to be called only after all other code generation for the creation object is complete.\n\tbool creationInvolvesMemoryUnsafeAssembly = m_context.memoryUnsafeInlineAssemblySeen();\n\tt(\"memoryInitCreation\", memoryInit(!creationInvolvesMemoryUnsafeAssembly));\n\tt(\"useSrcMapCreation\", formatUseSrcMap(m_context));\n\n\tauto const immutableVariables = m_context.immutableVariables();\n\tauto const libraryAddressImmutableOffset = (_contract.isLibrary() && eof) ?\n\t\tm_context.libraryAddressImmutableOffset() : 0;\n\n\tresetContext(_contract, ExecutionContext::Deployed);\n\n\t// When generating to EOF we have to initialize these two members, because they store offsets in EOF data section\n\t// which is used during deployed container generation\n\tif (m_eofVersion.has_value())\n\t{\n\t\tm_context.setImmutableVariables(std::move(immutableVariables));\n\t\tif (_contract.isLibrary())\n\t\t\tm_context.setLibraryAddressImmutableOffset(libraryAddressImmutableOffset);\n\t}\n\n\t// NOTE: Function pointers can be passed from creation code via storage variables. We need to\n\t// get all the functions they could point to into the dispatch functions even if they're never\n\t// referenced by name in the deployed code.\n\tm_context.initializeInternalDispatch(std::move(internalDispatchMap));\n\n\t// Do not register immutables to avoid assignment.\n\tt(\"DeployedObject\", IRNames::deployedObject(_contract));\n\tt(\"sourceLocationCommentDeployed\", dispenseLocationComment(_contract));\n\tt(\"eof\", eof);\n\tif (_contract.isLibrary())\n\t{\n\t\tif (!eof)\n\t\t\tt(\"library_address\", IRNames::libraryAddressImmutable());\n\t\telse\n\t\t\tt(\"library_address_immutable_offset\", std::to_string(m_context.libraryAddressImmutableOffsetRelative()));\n\t}\n\n\tt(\"dispatch\", dispatchRoutine(_contract));\n\tstd::set<FunctionDefinition const*> deployedFunctionList = generateQueuedFunctions();\n\tgenerateInternalDispatchFunctions(_contract);\n\tt(\"deployedFunctions\", m_context.functionCollector().requestedFunctions());\n\tt(\"deployedSubObjects\", subObjectSources(m_context.subObjectsCreated()));\n\tt(\"metadataName\", yul::Object::metadataName());\n\tt(\"cborMetadata\", util::toHex(_cborMetadata));\n\n\tt(\"useSrcMapDeployed\", formatUseSrcMap(m_context));\n\n\t// This has to be called only after all other code generation for the deployed object is complete.\n\tbool deployedInvolvesMemoryUnsafeAssembly = m_context.memoryUnsafeInlineAssemblySeen();\n\tt(\"memoryInitDeployed\", memoryInit(!deployedInvolvesMemoryUnsafeAssembly));\n\n\tsolAssert(_contract.annotation().creationCallGraph->get() != nullptr, \"\");\n\tsolAssert(_contract.annotation().deployedCallGraph->get() != nullptr, \"\");\n\tverifyCallGraph(collectReachableCallables(**_contract.annotation().creationCallGraph), std::move(creationFunctionList));\n\tverifyCallGraph(collectReachableCallables(**_contract.annotation().deployedCallGraph), std::move(deployedFunctionList));\n\n\treturn t.render();\n}\n\nstd::string IRGenerator::generate(Block const& _block)\n{\n\tIRGeneratorForStatements generator(m_context, m_utils, m_optimiserSettings);\n\tgenerator.generate(_block);\n\treturn generator.code();\n}\n\nstd::set<FunctionDefinition const*> IRGenerator::generateQueuedFunctions()\n{\n\tstd::set<FunctionDefinition const*> functions;\n\n\twhile (!m_context.functionGenerationQueueEmpty())\n\t{\n\t\tFunctionDefinition const& functionDefinition = *m_context.dequeueFunctionForCodeGeneration();\n\n\t\tfunctions.emplace(&functionDefinition);\n\t\t// NOTE: generateFunction() may modify function generation queue\n\t\tgenerateFunction(functionDefinition);\n\t}\n\n\treturn functions;\n}\n\nInternalDispatchMap IRGenerator::generateInternalDispatchFunctions(ContractDefinition const& _contract)\n{\n\tsolAssert(\n\t\tm_context.functionGenerationQueueEmpty(),\n\t\t\"At this point all the enqueued functions should have been generated. \"\n\t\t\"Otherwise the dispatch may be incomplete.\"\n\t);\n\n\tInternalDispatchMap internalDispatchMap = m_context.consumeInternalDispatchMap();\n\tfor (YulArity const& arity: internalDispatchMap | ranges::views::keys)\n\t{\n\t\tstd::string funName = IRNames::internalDispatch(arity);\n\t\tm_context.functionCollector().createFunction(funName, [&]() {\n\t\t\tWhiskers templ(R\"(\n\t\t\t\t<sourceLocationComment>\n\t\t\t\tfunction <functionName>(fun<?+in>, <in></+in>) <?+out>-> <out></+out> {\n\t\t\t\t\tswitch fun\n\t\t\t\t\t<#cases>\n\t\t\t\t\tcase <funID>\n\t\t\t\t\t{\n\t\t\t\t\t\t<?+out> <out> :=</+out> <name>(<in>)\n\t\t\t\t\t}\n\t\t\t\t\t</cases>\n\t\t\t\t\tdefault { <panic>() }\n\t\t\t\t}\n\t\t\t\t<sourceLocationComment>\n\t\t\t)\");\n\t\t\ttempl(\"sourceLocationComment\", dispenseLocationComment(_contract));\n\t\t\ttempl(\"functionName\", funName);\n\t\t\ttempl(\"panic\", m_utils.panicFunction(PanicCode::InvalidInternalFunction));\n\t\t\ttempl(\"in\", suffixedVariableNameList(\"in_\", 0, arity.in));\n\t\t\ttempl(\"out\", suffixedVariableNameList(\"out_\", 0, arity.out));\n\n\t\t\tstd::vector<std::map<std::string, std::string>> cases;\n\t\t\tstd::set<int64_t> caseValues;\n\t\t\tfor (FunctionDefinition const* function: internalDispatchMap.at(arity))\n\t\t\t{\n\t\t\t\tsolAssert(function, \"\");\n\t\t\t\tsolAssert(\n\t\t\t\t\tYulArity::fromType(*TypeProvider::function(*function, FunctionType::Kind::Internal)) == arity,\n\t\t\t\t\t\"A single dispatch function can only handle functions of one arity\"\n\t\t\t\t);\n\t\t\t\tsolAssert(!function->isConstructor(), \"\");\n\t\t\t\t// 0 is reserved for uninitialized function pointers\n\t\t\t\tsolAssert(function->id() != 0, \"Unexpected function ID: 0\");\n\t\t\t\tsolAssert(caseValues.count(function->id()) == 0, \"Duplicate function ID\");\n\t\t\t\tsolAssert(m_context.functionCollector().contains(IRNames::function(*function)), \"\");\n\n\t\t\t\tcases.emplace_back(std::map<std::string, std::string>{\n\t\t\t\t\t{\"funID\", std::to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(function))},\n\t\t\t\t\t{\"name\", IRNames::function(*function)}\n\t\t\t\t});\n\t\t\t\tcaseValues.insert(function->id());\n\t\t\t}\n\n\t\t\ttempl(\"cases\", std::move(cases));\n\t\t\treturn templ.render();\n\t\t});\n\t}\n\n\tsolAssert(m_context.internalDispatchClean(), \"\");\n\tsolAssert(\n\t\tm_context.functionGenerationQueueEmpty(),\n\t\t\"Internal dispatch generation must not add new functions to generation queue because they won't be proeessed.\"\n\t);\n\n\treturn internalDispatchMap;\n}\n\nstd::string IRGenerator::generateFunction(FunctionDefinition const& _function)\n{\n\tstd::string functionName = IRNames::function(_function);\n\treturn m_context.functionCollector().createFunction(functionName, [&]() {\n\t\tm_context.resetLocalVariables();\n\t\tWhiskers t(R\"(\n\t\t\t<astIDComment><sourceLocationComment>\n\t\t\tfunction <functionName>(<params>)<?+retParams> -> <retParams></+retParams> {\n\t\t\t\t<retInit>\n\t\t\t\t<body>\n\t\t\t}\n\t\t\t<contractSourceLocationComment>\n\t\t)\");\n\n\t\tif (m_context.debugInfoSelection().astID)\n\t\t\tt(\"astIDComment\", \"/// @ast-id \" + std::to_string(_function.id()) + \"\\n\");\n\t\telse\n\t\t\tt(\"astIDComment\", \"\");\n\t\tt(\"sourceLocationComment\", dispenseLocationComment(_function));\n\t\tt(\n\t\t\t\"contractSourceLocationComment\",\n\t\t\tdispenseLocationComment(m_context.mostDerivedContract())\n\t\t);\n\n\t\tt(\"functionName\", functionName);\n\t\tstd::vector<std::string> params;\n\t\tfor (auto const& varDecl: _function.parameters())\n\t\t\tparams += m_context.addLocalVariable(*varDecl).stackSlots();\n\t\tt(\"params\", joinHumanReadable(params));\n\t\tstd::vector<std::string> retParams;\n\t\tstd::string retInit;\n\t\tfor (auto const& varDecl: _function.returnParameters())\n\t\t{\n\t\t\tretParams += m_context.addLocalVariable(*varDecl).stackSlots();\n\t\t\tretInit += generateInitialAssignment(*varDecl);\n\t\t}\n\n\t\tt(\"retParams\", joinHumanReadable(retParams));\n\t\tt(\"retInit\", retInit);\n\n\t\tif (_function.modifiers().empty())\n\t\t\tt(\"body\", generate(_function.body()));\n\t\telse\n\t\t{\n\t\t\tfor (size_t i = 0; i < _function.modifiers().size(); ++i)\n\t\t\t{\n\t\t\t\tModifierInvocation const& modifier = *_function.modifiers().at(i);\n\t\t\t\tstd::string next =\n\t\t\t\t\ti + 1 < _function.modifiers().size() ?\n\t\t\t\t\tIRNames::modifierInvocation(*_function.modifiers().at(i + 1)) :\n\t\t\t\t\tIRNames::functionWithModifierInner(_function);\n\t\t\t\tgenerateModifier(modifier, _function, next);\n\t\t\t}\n\t\t\tt(\"body\",\n\t\t\t\t(retParams.empty() ? std::string{} : joinHumanReadable(retParams) + \" := \") +\n\t\t\t\tIRNames::modifierInvocation(*_function.modifiers().at(0)) +\n\t\t\t\t\"(\" +\n\t\t\t\tjoinHumanReadable(retParams + params) +\n\t\t\t\t\")\"\n\t\t\t);\n\t\t\t// Now generate the actual inner function.\n\t\t\tgenerateFunctionWithModifierInner(_function);\n\t\t}\n\t\treturn t.render();\n\t});\n}\n\nstd::string IRGenerator::generateModifier(\n\tModifierInvocation const& _modifierInvocation,\n\tFunctionDefinition const& _function,\n\tstd::string const& _nextFunction\n)\n{\n\tstd::string functionName = IRNames::modifierInvocation(_modifierInvocation);\n\treturn m_context.functionCollector().createFunction(functionName, [&]() {\n\t\tm_context.resetLocalVariables();\n\t\tWhiskers t(R\"(\n\t\t\t<astIDComment><sourceLocationComment>\n\t\t\tfunction <functionName>(<params>)<?+retParams> -> <retParams></+retParams> {\n\t\t\t\t<assignRetParams>\n\t\t\t\t<evalArgs>\n\t\t\t\t<body>\n\t\t\t}\n\t\t\t<contractSourceLocationComment>\n\t\t)\");\n\n\t\tt(\"functionName\", functionName);\n\t\tstd::vector<std::string> retParamsIn;\n\t\tfor (auto const& varDecl: _function.returnParameters())\n\t\t\tretParamsIn += m_context.addLocalVariable(*varDecl).stackSlots();\n\t\tstd::vector<std::string> params = retParamsIn;\n\t\tfor (auto const& varDecl: _function.parameters())\n\t\t\tparams += m_context.addLocalVariable(*varDecl).stackSlots();\n\t\tt(\"params\", joinHumanReadable(params));\n\t\tstd::vector<std::string> retParams;\n\t\tstd::string assignRetParams;\n\t\tfor (size_t i = 0; i < retParamsIn.size(); ++i)\n\t\t{\n\t\t\tretParams.emplace_back(m_context.newYulVariable());\n\t\t\tassignRetParams += retParams.at(i) + \" := \" + retParamsIn.at(i) + \"\\n\";\n\t\t}\n\t\tt(\"retParams\", joinHumanReadable(retParams));\n\t\tt(\"assignRetParams\", assignRetParams);\n\n\t\tModifierDefinition const* modifier = dynamic_cast<ModifierDefinition const*>(\n\t\t\t_modifierInvocation.name().annotation().referencedDeclaration\n\t\t);\n\t\tsolAssert(modifier, \"\");\n\n\t\tif (m_context.debugInfoSelection().astID)\n\t\t\tt(\"astIDComment\", \"/// @ast-id \" + std::to_string(modifier->id()) + \"\\n\");\n\t\telse\n\t\t\tt(\"astIDComment\", \"\");\n\t\tt(\"sourceLocationComment\", dispenseLocationComment(*modifier));\n\t\tt(\n\t\t\t\"contractSourceLocationComment\",\n\t\t\tdispenseLocationComment(m_context.mostDerivedContract())\n\t\t);\n\n\t\tswitch (*_modifierInvocation.name().annotation().requiredLookup)\n\t\t{\n\t\tcase VirtualLookup::Virtual:\n\t\t\tmodifier = &modifier->resolveVirtual(m_context.mostDerivedContract());\n\t\t\tsolAssert(modifier, \"\");\n\t\t\tbreak;\n\t\tcase VirtualLookup::Static:\n\t\t\tbreak;\n\t\tcase VirtualLookup::Super:\n\t\t\tsolAssert(false, \"\");\n\t\t}\n\n\t\tsolAssert(\n\t\t\tmodifier->parameters().empty() ==\n\t\t\t(!_modifierInvocation.arguments() || _modifierInvocation.arguments()->empty()),\n\t\t\t\"\"\n\t\t);\n\t\tIRGeneratorForStatements expressionEvaluator(m_context, m_utils, m_optimiserSettings);\n\t\tif (_modifierInvocation.arguments())\n\t\t\tfor (size_t i = 0; i < _modifierInvocation.arguments()->size(); i++)\n\t\t\t{\n\t\t\t\tIRVariable argument = expressionEvaluator.evaluateExpression(\n\t\t\t\t\t*_modifierInvocation.arguments()->at(i),\n\t\t\t\t\t*modifier->parameters()[i]->annotation().type\n\t\t\t\t);\n\t\t\t\texpressionEvaluator.define(\n\t\t\t\t\tm_context.addLocalVariable(*modifier->parameters()[i]),\n\t\t\t\t\targument\n\t\t\t\t);\n\t\t\t}\n\n\t\tt(\"evalArgs\", expressionEvaluator.code());\n\t\tIRGeneratorForStatements generator(m_context, m_utils, m_optimiserSettings, [&]() {\n\t\t\tstd::string ret = joinHumanReadable(retParams);\n\t\t\treturn\n\t\t\t\t(ret.empty() ? \"\" : ret + \" := \") +\n\t\t\t\t_nextFunction + \"(\" + joinHumanReadable(params) + \")\\n\";\n\t\t});\n\t\tgenerator.generate(modifier->body());\n\t\tt(\"body\", generator.code());\n\t\treturn t.render();\n\t});\n}\n\nstd::string IRGenerator::generateFunctionWithModifierInner(FunctionDefinition const& _function)\n{\n\tstd::string functionName = IRNames::functionWithModifierInner(_function);\n\treturn m_context.functionCollector().createFunction(functionName, [&]() {\n\t\tm_context.resetLocalVariables();\n\t\tWhiskers t(R\"(\n\t\t\t<sourceLocationComment>\n\t\t\tfunction <functionName>(<params>)<?+retParams> -> <retParams></+retParams> {\n\t\t\t\t<assignRetParams>\n\t\t\t\t<body>\n\t\t\t}\n\t\t\t<contractSourceLocationComment>\n\t\t)\");\n\t\tt(\"sourceLocationComment\", dispenseLocationComment(_function));\n\t\tt(\n\t\t\t\"contractSourceLocationComment\",\n\t\t\tdispenseLocationComment(m_context.mostDerivedContract())\n\t\t);\n\t\tt(\"functionName\", functionName);\n\t\tstd::vector<std::string> retParams;\n\t\tstd::vector<std::string> retParamsIn;\n\t\tfor (auto const& varDecl: _function.returnParameters())\n\t\t\tretParams += m_context.addLocalVariable(*varDecl).stackSlots();\n\t\tstd::string assignRetParams;\n\t\tfor (size_t i = 0; i < retParams.size(); ++i)\n\t\t{\n\t\t\tretParamsIn.emplace_back(m_context.newYulVariable());\n\t\t\tassignRetParams += retParams.at(i) + \" := \" + retParamsIn.at(i) + \"\\n\";\n\t\t}\n\t\tstd::vector<std::string> params = retParamsIn;\n\t\tfor (auto const& varDecl: _function.parameters())\n\t\t\tparams += m_context.addLocalVariable(*varDecl).stackSlots();\n\t\tt(\"params\", joinHumanReadable(params));\n\t\tt(\"retParams\", joinHumanReadable(retParams));\n\t\tt(\"assignRetParams\", assignRetParams);\n\t\tt(\"body\", generate(_function.body()));\n\t\treturn t.render();\n\t});\n}\n\nstd::string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)\n{\n\tstd::string functionName = IRNames::function(_varDecl);\n\treturn m_context.functionCollector().createFunction(functionName, [&]() {\n\t\tType const* type = _varDecl.annotation().type;\n\n\t\tsolAssert(_varDecl.isStateVariable(), \"\");\n\n\t\tFunctionType accessorType(_varDecl);\n\t\tTypePointers paramTypes = accessorType.parameterTypes();\n\t\tif (_varDecl.immutable())\n\t\t{\n\t\t\tsolAssert(paramTypes.empty(), \"\");\n\t\t\tsolUnimplementedAssert(type->sizeOnStack() == 1);\n\n\t\t\tauto t = Whiskers(R\"(\n\t\t\t\t<astIDComment><sourceLocationComment>\n\t\t\t\tfunction <functionName>() -> rval {\n\t\t\t\t\t<?eof>\n\t\t\t\t\t\trval := auxdataloadn(<immutableOffset>)\n\t\t\t\t\t<!eof>\n\t\t\t\t\t\trval := loadimmutable(\"<id>\")\n\t\t\t\t\t</eof>\n\t\t\t\t}\n\t\t\t\t<contractSourceLocationComment>\n\t\t\t\t)\");\n\t\t\tt(\n\t\t\t\t\"astIDComment\",\n\t\t\t\tm_context.debugInfoSelection().astID ?\n\t\t\t\t\t\"/// @ast-id \" + std::to_string(_varDecl.id()) + \"\\n\" :\n\t\t\t\t\t\"\"\n\t\t\t);\n\t\t\tt(\"sourceLocationComment\", dispenseLocationComment(_varDecl));\n\t\t\tt(\n\t\t\t\t\"contractSourceLocationComment\",\n\t\t\t\tdispenseLocationComment(m_context.mostDerivedContract())\n\t\t\t);\n\t\t\tt(\"functionName\", functionName);\n\n\t\t\tauto const eof = m_context.eofVersion().has_value();\n\t\t\tt(\"eof\", eof);\n\t\t\tif (!eof)\n\t\t\t\tt(\"id\", std::to_string(_varDecl.id()));\n\t\t\telse\n\t\t\t\tt(\"immutableOffset\", std::to_string(m_context.immutableMemoryOffsetRelative(_varDecl)));\n\n\t\t\treturn t.render();\n\t\t}\n\t\telse if (_varDecl.isConstant())\n\t\t{\n\t\t\tsolAssert(paramTypes.empty(), \"\");\n\t\t\treturn Whiskers(R\"(\n\t\t\t\t<astIDComment><sourceLocationComment>\n\t\t\t\tfunction <functionName>() -> <ret> {\n\t\t\t\t\t<ret> := <constantValueFunction>()\n\t\t\t\t}\n\t\t\t\t<contractSourceLocationComment>\n\t\t\t)\")\n\t\t\t(\n\t\t\t\t\"astIDComment\",\n\t\t\t\tm_context.debugInfoSelection().astID ?\n\t\t\t\t\t\"/// @ast-id \" + std::to_string(_varDecl.id()) + \"\\n\" :\n\t\t\t\t\t\"\"\n\t\t\t)\n\t\t\t(\"sourceLocationComment\", dispenseLocationComment(_varDecl))\n\t\t\t(\n\t\t\t\t\"contractSourceLocationComment\",\n\t\t\t\tdispenseLocationComment(m_context.mostDerivedContract())\n\t\t\t)\n\t\t\t(\"functionName\", functionName)\n\t\t\t(\"constantValueFunction\", IRGeneratorForStatements(m_context, m_utils, m_optimiserSettings).constantValueFunction(_varDecl))\n\t\t\t(\"ret\", suffixedVariableNameList(\"ret_\", 0, _varDecl.type()->sizeOnStack()))\n\t\t\t.render();\n\t\t}\n\n\t\tstd::string code;\n\n\t\tauto const& location = m_context.storageLocationOfStateVariable(_varDecl);\n\t\tcode += Whiskers(R\"(\n\t\t\tlet slot := <slot>\n\t\t\tlet offset := <offset>\n\t\t)\")\n\t\t(\"slot\", location.first.str())\n\t\t(\"offset\", std::to_string(location.second))\n\t\t.render();\n\n\t\tif (!paramTypes.empty())\n\t\t\tsolAssert(\n\t\t\t\tlocation.second == 0,\n\t\t\t\t\"If there are parameters, we are dealing with structs or mappings and thus should have offset zero.\"\n\t\t\t);\n\n\t\t// The code of an accessor is of the form `x[a][b][c]` (it is slightly more complicated\n\t\t// if the final type is a struct).\n\t\t// In each iteration of the loop below, we consume one parameter, perform an\n\t\t// index access, reassign the yul variable `slot` and move @a currentType further \"down\".\n\t\t// The initial value of @a currentType is only used if we skip the loop completely.\n\t\tType const* currentType = _varDecl.annotation().type;\n\n\t\tstd::vector<std::string> parameters;\n\t\tstd::vector<std::string> returnVariables;\n\n\t\tfor (size_t i = 0; i < paramTypes.size(); ++i)\n\t\t{\n\t\t\tMappingType const* mappingType = dynamic_cast<MappingType const*>(currentType);\n\t\t\tArrayType const* arrayType = dynamic_cast<ArrayType const*>(currentType);\n\t\t\tsolAssert(mappingType || arrayType, \"\");\n\n\t\t\tstd::vector<std::string> keys = IRVariable(\"key_\" + std::to_string(i),\n\t\t\t\tmappingType ? *mappingType->keyType() : *TypeProvider::uint256()\n\t\t\t).stackSlots();\n\t\t\tparameters += keys;\n\n\t\t\tWhiskers templ(R\"(\n\t\t\t\t<?array>\n\t\t\t\t\tif iszero(lt(<keys>, <length>(slot))) { revert(0, 0) }\n\t\t\t\t</array>\n\t\t\t\tslot<?array>, offset</array> := <indexAccess>(slot<?+keys>, <keys></+keys>)\n\t\t\t)\");\n\t\t\ttempl(\n\t\t\t\t\"indexAccess\",\n\t\t\t\tmappingType ?\n\t\t\t\tm_utils.mappingIndexAccessFunction(*mappingType, *mappingType->keyType()) :\n\t\t\t\tm_utils.storageArrayIndexAccessFunction(*arrayType)\n\t\t\t)\n\t\t\t(\"array\", arrayType != nullptr)\n\t\t\t(\"keys\", joinHumanReadable(keys));\n\t\t\tif (arrayType)\n\t\t\t\ttempl(\"length\", m_utils.arrayLengthFunction(*arrayType));\n\n\t\t\tcode += templ.render();\n\n\t\t\tcurrentType = mappingType ? mappingType->valueType() : arrayType->baseType();\n\t\t}\n\n\t\tauto returnTypes = accessorType.returnParameterTypes();\n\t\tsolAssert(returnTypes.size() >= 1, \"\");\n\t\tif (StructType const* structType = dynamic_cast<StructType const*>(currentType))\n\t\t{\n\t\t\tsolAssert(location.second == 0, \"\");\n\t\t\tauto const& names = accessorType.returnParameterNames();\n\t\t\tfor (size_t i = 0; i < names.size(); ++i)\n\t\t\t{\n\t\t\t\tif (returnTypes[i]->category() == Type::Category::Mapping)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (\n\t\t\t\t\tauto const* arrayType = dynamic_cast<ArrayType const*>(returnTypes[i]);\n\t\t\t\t\tarrayType && !arrayType->isByteArrayOrString()\n\t\t\t\t)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tstd::pair<u256, unsigned> const& offsets = structType->storageOffsetsOfMember(names[i]);\n\t\t\t\tstd::vector<std::string> retVars = IRVariable(\"ret_\" + std::to_string(returnVariables.size()), *returnTypes[i]).stackSlots();\n\t\t\t\treturnVariables += retVars;\n\t\t\t\tcode += Whiskers(R\"(\n\t\t\t\t\t<ret> := <readStorage>(add(slot, <slotOffset>))\n\t\t\t\t)\")\n\t\t\t\t(\"ret\", joinHumanReadable(retVars))\n\t\t\t\t(\"readStorage\", m_utils.readFromStorage(*returnTypes[i], offsets.second, true, _varDecl.referenceLocation()))\n\t\t\t\t(\"slotOffset\", offsets.first.str())\n\t\t\t\t.render();\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(returnTypes.size() == 1, \"\");\n\t\t\tauto const* arrayType = dynamic_cast<ArrayType const*>(returnTypes.front());\n\t\t\tif (arrayType)\n\t\t\t\tsolAssert(arrayType->isByteArrayOrString(), \"\");\n\t\t\tstd::vector<std::string> retVars = IRVariable(\"ret\", *returnTypes.front()).stackSlots();\n\t\t\treturnVariables += retVars;\n\t\t\tcode += Whiskers(R\"(\n\t\t\t\t<ret> := <readStorage>(slot, offset)\n\t\t\t)\")\n\t\t\t(\"ret\", joinHumanReadable(retVars))\n\t\t\t(\"readStorage\", m_utils.readFromStorageDynamic(*returnTypes.front(), true, _varDecl.referenceLocation()))\n\t\t\t.render();\n\t\t}\n\n\t\treturn Whiskers(R\"(\n\t\t\t<astIDComment><sourceLocationComment>\n\t\t\tfunction <functionName>(<params>) -> <retVariables> {\n\t\t\t\t<code>\n\t\t\t}\n\t\t\t<contractSourceLocationComment>\n\t\t)\")\n\t\t(\"functionName\", functionName)\n\t\t(\"params\", joinHumanReadable(parameters))\n\t\t(\"retVariables\", joinHumanReadable(returnVariables))\n\t\t(\"code\", std::move(code))\n\t\t(\n\t\t\t\"astIDComment\",\n\t\t\tm_context.debugInfoSelection().astID ?\n\t\t\t\t\"/// @ast-id \" + std::to_string(_varDecl.id()) + \"\\n\" :\n\t\t\t\t\"\"\n\t\t)\n\t\t(\"sourceLocationComment\", dispenseLocationComment(_varDecl))\n\t\t(\n\t\t\t\"contractSourceLocationComment\",\n\t\t\tdispenseLocationComment(m_context.mostDerivedContract())\n\t\t)\n\t\t.render();\n\t});\n}\n\nstd::string IRGenerator::generateExternalFunction(ContractDefinition const& _contract, FunctionType const& _functionType)\n{\n\tstd::string functionName = IRNames::externalFunctionABIWrapper(_functionType.declaration());\n\treturn m_context.functionCollector().createFunction(functionName, [&](std::vector<std::string>&, std::vector<std::string>&) -> std::string {\n\t\tWhiskers t(R\"X(\n\t\t\t<callValueCheck>\n\t\t\t<?+params>let <params> := </+params> <abiDecode>(4, calldatasize())\n\t\t\t<?+retParams>let <retParams> := </+retParams> <function>(<params>)\n\t\t\tlet memPos := <allocateUnbounded>()\n\t\t\tlet memEnd := <abiEncode>(memPos <?+retParams>,</+retParams> <retParams>)\n\t\t\treturn(memPos, sub(memEnd, memPos))\n\t\t)X\");\n\t\tt(\"callValueCheck\", (_functionType.isPayable() || _contract.isLibrary()) ? \"\" : callValueCheck());\n\n\t\tunsigned paramVars = std::make_shared<TupleType>(_functionType.parameterTypes())->sizeOnStack();\n\t\tunsigned retVars = std::make_shared<TupleType>(_functionType.returnParameterTypes())->sizeOnStack();\n\n\t\tABIFunctions abiFunctions(m_evmVersion, m_eofVersion, m_context.revertStrings(), m_context.functionCollector());\n\t\tt(\"abiDecode\", abiFunctions.tupleDecoder(_functionType.parameterTypes()));\n\t\tt(\"params\",  suffixedVariableNameList(\"param_\", 0, paramVars));\n\t\tt(\"retParams\",  suffixedVariableNameList(\"ret_\", 0, retVars));\n\n\t\tif (FunctionDefinition const* funDef = dynamic_cast<FunctionDefinition const*>(&_functionType.declaration()))\n\t\t{\n\t\t\tsolAssert(!funDef->isConstructor());\n\t\t\tt(\"function\", m_context.enqueueFunctionForCodeGeneration(*funDef));\n\t\t}\n\t\telse if (VariableDeclaration const* varDecl = dynamic_cast<VariableDeclaration const*>(&_functionType.declaration()))\n\t\t\tt(\"function\", generateGetter(*varDecl));\n\t\telse\n\t\t\tsolAssert(false, \"Unexpected declaration for function!\");\n\n\t\tt(\"allocateUnbounded\", m_utils.allocateUnboundedFunction());\n\t\tt(\"abiEncode\", abiFunctions.tupleEncoder(_functionType.returnParameterTypes(), _functionType.returnParameterTypes(), _contract.isLibrary()));\n\t\treturn t.render();\n\t});\n}\n\nstd::string IRGenerator::generateInitialAssignment(VariableDeclaration const& _varDecl)\n{\n\tIRGeneratorForStatements generator(m_context, m_utils, m_optimiserSettings);\n\tgenerator.initializeLocalVar(_varDecl);\n\treturn generator.code();\n}\n\nstd::pair<std::string, std::map<ContractDefinition const*, std::vector<std::string>>> IRGenerator::evaluateConstructorArguments(\n\tContractDefinition const& _contract\n)\n{\n\tstruct InheritanceOrder\n\t{\n\t\tbool operator()(ContractDefinition const* _c1, ContractDefinition const* _c2) const\n\t\t{\n\t\t\tsolAssert(util::contains(linearizedBaseContracts, _c1) && util::contains(linearizedBaseContracts, _c2), \"\");\n\t\t\tauto it1 = find(linearizedBaseContracts.begin(), linearizedBaseContracts.end(), _c1);\n\t\t\tauto it2 = find(linearizedBaseContracts.begin(), linearizedBaseContracts.end(), _c2);\n\t\t\treturn it1 < it2;\n\t\t}\n\t\tstd::vector<ContractDefinition const*> const& linearizedBaseContracts;\n\t} inheritanceOrder{_contract.annotation().linearizedBaseContracts};\n\n\tstd::map<ContractDefinition const*, std::vector<std::string>> constructorParams;\n\n\tstd::map<ContractDefinition const*, std::vector<ASTPointer<Expression>>const *, InheritanceOrder>\n\t\tbaseConstructorArguments(inheritanceOrder);\n\n\tfor (ASTPointer<InheritanceSpecifier> const& base: _contract.baseContracts())\n\t\tif (FunctionDefinition const* baseConstructor = dynamic_cast<ContractDefinition const*>(\n\t\t\t\tbase->name().annotation().referencedDeclaration\n\t\t)->constructor(); baseConstructor && base->arguments())\n\t\t\tsolAssert(baseConstructorArguments.emplace(\n\t\t\t\tdynamic_cast<ContractDefinition const*>(baseConstructor->scope()),\n\t\t\t\tbase->arguments()\n\t\t\t).second, \"\");\n\n\tif (FunctionDefinition const* constructor = _contract.constructor())\n\t\tfor (ASTPointer<ModifierInvocation> const& modifier: constructor->modifiers())\n\t\t\tif (auto const* baseContract = dynamic_cast<ContractDefinition const*>(\n\t\t\t\tmodifier->name().annotation().referencedDeclaration\n\t\t\t))\n\t\t\t\tif (\n\t\t\t\t\tFunctionDefinition const* baseConstructor = baseContract->constructor();\n\t\t\t\t\tbaseConstructor && modifier->arguments()\n\t\t\t\t)\n\t\t\t\t\tsolAssert(baseConstructorArguments.emplace(\n\t\t\t\t\t\tdynamic_cast<ContractDefinition const*>(baseConstructor->scope()),\n\t\t\t\t\t\tmodifier->arguments()\n\t\t\t\t\t).second, \"\");\n\n\tIRGeneratorForStatements generator{m_context, m_utils, m_optimiserSettings};\n\tfor (auto&& [baseContract, arguments]: baseConstructorArguments)\n\t{\n\t\tsolAssert(baseContract && arguments, \"\");\n\t\tif (baseContract->constructor() && !arguments->empty())\n\t\t{\n\t\t\tstd::vector<std::string> params;\n\t\t\tfor (size_t i = 0; i < arguments->size(); ++i)\n\t\t\t\tparams += generator.evaluateExpression(\n\t\t\t\t\t*(arguments->at(i)),\n\t\t\t\t\t*(baseContract->constructor()->parameters()[i]->type())\n\t\t\t\t).stackSlots();\n\t\t\tconstructorParams[baseContract] = std::move(params);\n\t\t}\n\t}\n\n\treturn {generator.code(), constructorParams};\n}\n\nstd::string IRGenerator::initStateVariables(ContractDefinition const& _contract)\n{\n\tIRGeneratorForStatements generator{m_context, m_utils, m_optimiserSettings};\n\tfor (VariableDeclaration const* variable: _contract.stateVariables())\n\t{\n\t\tif (!variable->isConstant())\n\t\t\tgenerator.initializeStateVar(*variable);\n\t}\n\n\treturn generator.code();\n}\n\n\nvoid IRGenerator::generateConstructors(ContractDefinition const& _contract)\n{\n\tauto listAllParams =\n\t\t[&](std::map<ContractDefinition const*, std::vector<std::string>> const& baseParams) -> std::vector<std::string>\n\t\t{\n\t\t\tstd::vector<std::string> params;\n\t\t\tfor (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts)\n\t\t\t\tif (baseParams.count(contract))\n\t\t\t\t\tparams += baseParams.at(contract);\n\t\t\treturn params;\n\t\t};\n\n\tstd::map<ContractDefinition const*, std::vector<std::string>> baseConstructorParams;\n\tfor (size_t i = 0; i < _contract.annotation().linearizedBaseContracts.size(); ++i)\n\t{\n\t\tContractDefinition const* contract = _contract.annotation().linearizedBaseContracts[i];\n\t\tbaseConstructorParams.erase(contract);\n\n\t\tm_context.resetLocalVariables();\n\t\tm_context.functionCollector().createFunction(IRNames::constructor(*contract), [&]() {\n\t\t\tWhiskers t(R\"(\n\t\t\t\t<astIDComment><sourceLocationComment>\n\t\t\t\tfunction <functionName>(<params><comma><baseParams>) {\n\t\t\t\t\t<evalBaseArguments>\n\t\t\t\t\t<sourceLocationComment>\n\t\t\t\t\t<?hasNextConstructor> <nextConstructor>(<nextParams>) </hasNextConstructor>\n\t\t\t\t\t<initStateVariables>\n\t\t\t\t\t<userDefinedConstructorBody>\n\t\t\t\t}\n\t\t\t\t<contractSourceLocationComment>\n\t\t\t)\");\n\t\t\tstd::vector<std::string> params;\n\t\t\tif (contract->constructor())\n\t\t\t\tfor (ASTPointer<VariableDeclaration> const& varDecl: contract->constructor()->parameters())\n\t\t\t\t\tparams += m_context.addLocalVariable(*varDecl).stackSlots();\n\n\t\t\tif (m_context.debugInfoSelection().astID && contract->constructor())\n\t\t\t\tt(\"astIDComment\", \"/// @ast-id \" + std::to_string(contract->constructor()->id()) + \"\\n\");\n\t\t\telse\n\t\t\t\tt(\"astIDComment\", \"\");\n\t\t\tt(\"sourceLocationComment\", dispenseLocationComment(\n\t\t\t\tcontract->constructor() ?\n\t\t\t\tdynamic_cast<ASTNode const&>(*contract->constructor()) :\n\t\t\t\tdynamic_cast<ASTNode const&>(*contract)\n\t\t\t));\n\t\t\tt(\n\t\t\t\t\"contractSourceLocationComment\",\n\t\t\t\tdispenseLocationComment(m_context.mostDerivedContract())\n\t\t\t);\n\n\t\t\tt(\"params\", joinHumanReadable(params));\n\t\t\tstd::vector<std::string> baseParams = listAllParams(baseConstructorParams);\n\t\t\tt(\"baseParams\", joinHumanReadable(baseParams));\n\t\t\tt(\"comma\", !params.empty() && !baseParams.empty() ? \", \" : \"\");\n\t\t\tt(\"functionName\", IRNames::constructor(*contract));\n\t\t\tstd::pair<std::string, std::map<ContractDefinition const*, std::vector<std::string>>> evaluatedArgs = evaluateConstructorArguments(*contract);\n\t\t\tbaseConstructorParams.insert(evaluatedArgs.second.begin(), evaluatedArgs.second.end());\n\t\t\tt(\"evalBaseArguments\", evaluatedArgs.first);\n\t\t\tif (i < _contract.annotation().linearizedBaseContracts.size() - 1)\n\t\t\t{\n\t\t\t\tt(\"hasNextConstructor\", true);\n\t\t\t\tContractDefinition const* nextContract = _contract.annotation().linearizedBaseContracts[i + 1];\n\t\t\t\tt(\"nextConstructor\", IRNames::constructor(*nextContract));\n\t\t\t\tt(\"nextParams\", joinHumanReadable(listAllParams(baseConstructorParams)));\n\t\t\t}\n\t\t\telse\n\t\t\t\tt(\"hasNextConstructor\", false);\n\t\t\tt(\"initStateVariables\", initStateVariables(*contract));\n\t\t\tstd::string body;\n\t\t\tif (FunctionDefinition const* constructor = contract->constructor())\n\t\t\t{\n\t\t\t\tstd::vector<ModifierInvocation*> realModifiers;\n\t\t\t\tfor (auto const& modifierInvocation: constructor->modifiers())\n\t\t\t\t\t// Filter out the base constructor calls\n\t\t\t\t\tif (dynamic_cast<ModifierDefinition const*>(modifierInvocation->name().annotation().referencedDeclaration))\n\t\t\t\t\t\trealModifiers.emplace_back(modifierInvocation.get());\n\t\t\t\tif (realModifiers.empty())\n\t\t\t\t\tbody = generate(constructor->body());\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfor (size_t i = 0; i < realModifiers.size(); ++i)\n\t\t\t\t\t{\n\t\t\t\t\t\tModifierInvocation const& modifier = *realModifiers.at(i);\n\t\t\t\t\t\tstd::string next =\n\t\t\t\t\t\t\ti + 1 < realModifiers.size() ?\n\t\t\t\t\t\t\tIRNames::modifierInvocation(*realModifiers.at(i + 1)) :\n\t\t\t\t\t\t\tIRNames::functionWithModifierInner(*constructor);\n\t\t\t\t\t\tgenerateModifier(modifier, *constructor, next);\n\t\t\t\t\t}\n\t\t\t\t\tbody =\n\t\t\t\t\t\tIRNames::modifierInvocation(*realModifiers.at(0)) +\n\t\t\t\t\t\t\"(\" +\n\t\t\t\t\t\tjoinHumanReadable(params) +\n\t\t\t\t\t\t\")\";\n\t\t\t\t\t// Now generate the actual inner function.\n\t\t\t\t\tgenerateFunctionWithModifierInner(*constructor);\n\t\t\t\t}\n\t\t\t}\n\t\t\tt(\"userDefinedConstructorBody\", std::move(body));\n\n\t\t\treturn t.render();\n\t\t});\n\t}\n}\n\nstd::string IRGenerator::deployCode(ContractDefinition const& _contract)\n{\n\tWhiskers t(R\"X(\n\t\t<?eof>\n\t\t\t<?library>\n\t\t\t\tmstore(<libraryAddressImmutableOffset>, address())\n\t\t\t</library>\n\t\t\treturncontract(\"<object>\", <auxDataStart>, <auxDataSize>)\n\t\t<!eof>\n\t\t\tlet <codeOffset> := <allocateUnbounded>()\n\t\t\tcodecopy(<codeOffset>, dataoffset(\"<object>\"), datasize(\"<object>\"))\n\t\t\t<#immutables>\n\t\t\t\tsetimmutable(<codeOffset>, \"<immutableName>\", <value>)\n\t\t\t</immutables>\n\t\t\treturn(<codeOffset>, datasize(\"<object>\"))\n\t\t</eof>\n\t)X\");\n\tauto const eof = m_context.eofVersion().has_value();\n\tt(\"eof\", eof);\n\tt(\"allocateUnbounded\", m_utils.allocateUnboundedFunction());\n\tt(\"codeOffset\", m_context.newYulVariable());\n\tt(\"object\", IRNames::deployedObject(_contract));\n\n\tstd::vector<std::map<std::string, std::string>> immutables;\n\tif (_contract.isLibrary())\n\t{\n\t\tsolAssert(ContractType(_contract).immutableVariables().empty(), \"\");\n\t\tif (!eof)\n\t\t\timmutables.emplace_back(std::map<std::string, std::string>{\n\t\t\t\t{\"immutableName\"s, IRNames::libraryAddressImmutable()},\n\t\t\t\t{\"value\"s, \"address()\"}\n\t\t\t});\n\t\telse\n\t\t\tt(\"libraryAddressImmutableOffset\", std::to_string(m_context.libraryAddressImmutableOffset()));\n\t}\n\telse\n\t{\n\t\tfor (VariableDeclaration const* immutable: ContractType(_contract).immutableVariables())\n\t\t{\n\t\t\tsolUnimplementedAssert(immutable->type()->isValueType());\n\t\t\tsolUnimplementedAssert(immutable->type()->sizeOnStack() == 1);\n\t\t\tif (!eof)\n\t\t\t\timmutables.emplace_back(std::map<std::string, std::string>{\n\t\t\t\t\t{\"immutableName\"s, std::to_string(immutable->id())},\n\t\t\t\t\t{\"value\"s, \"mload(\" + std::to_string(m_context.immutableMemoryOffset(*immutable)) + \")\"}\n\t\t\t\t});\n\t\t}\n\t}\n\n\tif (eof)\n\t{\n\t\tt(\"library\", _contract.isLibrary());\n\t\tt(\"auxDataStart\", std::to_string(CompilerUtils::generalPurposeMemoryStart));\n\t\tsolAssert(m_context.reservedMemorySize() <= 0xFFFF, \"Reserved memory size exceeded maximum allowed EOF data section size.\");\n\t\tt(\"auxDataSize\", std::to_string(m_context.reservedMemorySize()));\n\t}\n\telse\n\t\tt(\"immutables\", std::move(immutables));\n\n\treturn t.render();\n}\n\nstd::string IRGenerator::callValueCheck()\n{\n\treturn \"if callvalue() { \" + m_utils.revertReasonIfDebugFunction(\"Ether sent to non-payable function\") + \"() }\";\n}\n\nstd::string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)\n{\n\tWhiskers t(R\"X(\n\t\t<?+cases>if iszero(lt(calldatasize(), 4))\n\t\t{\n\t\t\tlet selector := <shr224>(calldataload(0))\n\t\t\tswitch selector\n\t\t\t<#cases>\n\t\t\tcase <functionSelector>\n\t\t\t{\n\t\t\t\t// <functionName>\n\t\t\t\t<delegatecallCheck>\n\t\t\t\t<externalFunction>()\n\t\t\t}\n\t\t\t</cases>\n\t\t\tdefault {}\n\t\t}</+cases>\n\t\t<?+receiveEther>if iszero(calldatasize()) { <receiveEther> }</+receiveEther>\n\t\t<fallback>\n\t)X\");\n\tt(\"shr224\", m_utils.shiftRightFunction(224));\n\tstd::vector<std::map<std::string, std::string>> functions;\n\tfor (auto const& function: _contract.interfaceFunctions())\n\t{\n\t\tfunctions.emplace_back();\n\t\tstd::map<std::string, std::string>& templ = functions.back();\n\t\ttempl[\"functionSelector\"] = \"0x\" + function.first.hex();\n\t\tFunctionTypePointer const& type = function.second;\n\t\ttempl[\"functionName\"] = type->externalSignature();\n\t\tstd::string delegatecallCheck;\n\t\tif (_contract.isLibrary())\n\t\t{\n\t\t\tsolAssert(!type->isPayable(), \"\");\n\t\t\tif (type->stateMutability() > StateMutability::View)\n\t\t\t\t// If the function is not a view function and is called without DELEGATECALL,\n\t\t\t\t// we revert.\n\t\t\t\tdelegatecallCheck =\n\t\t\t\t\t\"if iszero(called_via_delegatecall) { \" +\n\t\t\t\t\tm_utils.revertReasonIfDebugFunction(\"Non-view function of library called without DELEGATECALL\") +\n\t\t\t\t\t\"() }\";\n\t\t}\n\t\ttempl[\"delegatecallCheck\"] = delegatecallCheck;\n\n\t\ttempl[\"externalFunction\"] = generateExternalFunction(_contract, *type);\n\t}\n\tt(\"cases\", functions);\n\tFunctionDefinition const* etherReceiver = _contract.receiveFunction();\n\tif (etherReceiver)\n\t{\n\t\tsolAssert(!_contract.isLibrary(), \"\");\n\t\tt(\"receiveEther\", m_context.enqueueFunctionForCodeGeneration(*etherReceiver) + \"() stop()\");\n\t}\n\telse\n\t\tt(\"receiveEther\", \"\");\n\tif (FunctionDefinition const* fallback = _contract.fallbackFunction())\n\t{\n\t\tsolAssert(!_contract.isLibrary(), \"\");\n\t\tstd::string fallbackCode;\n\t\tif (!fallback->isPayable())\n\t\t\tfallbackCode += callValueCheck() + \"\\n\";\n\t\tif (fallback->parameters().empty())\n\t\t\tfallbackCode += m_context.enqueueFunctionForCodeGeneration(*fallback) + \"() stop()\";\n\t\telse\n\t\t{\n\t\t\tsolAssert(fallback->parameters().size() == 1 && fallback->returnParameters().size() == 1, \"\");\n\t\t\tfallbackCode += \"let retval := \" + m_context.enqueueFunctionForCodeGeneration(*fallback) + \"(0, calldatasize())\\n\";\n\t\t\tfallbackCode += \"return(add(retval, 0x20), mload(retval))\\n\";\n\n\t\t}\n\n\t\tt(\"fallback\", fallbackCode);\n\t}\n\telse\n\t\tt(\"fallback\", (\n\t\t\tetherReceiver ?\n\t\t\tm_utils.revertReasonIfDebugFunction(\"Unknown signature and no fallback defined\") :\n\t\t\tm_utils.revertReasonIfDebugFunction(\"Contract does not have fallback nor receive functions\")\n\t\t) + \"()\");\n\treturn t.render();\n}\n\nstd::string IRGenerator::memoryInit(bool _useMemoryGuard)\n{\n\t// This function should be called at the beginning of the EVM call frame\n\t// and thus can assume all memory to be zero, including the contents of\n\t// the \"zero memory area\" (the position CompilerUtils::zeroPointer points to).\n\treturn\n\t\tWhiskers{\n\t\t\t_useMemoryGuard ?\n\t\t\t\"mstore(<memPtr>, memoryguard(<freeMemoryStart>))\" :\n\t\t\t\"mstore(<memPtr>, <freeMemoryStart>)\"\n\t\t}\n\t\t(\"memPtr\", std::to_string(CompilerUtils::freeMemoryPointer))\n\t\t(\n\t\t\t\"freeMemoryStart\",\n\t\t\tstd::to_string(CompilerUtils::generalPurposeMemoryStart + m_context.reservedMemory())\n\t\t).render();\n}\n\nvoid IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionContext _context)\n{\n\tsolAssert(\n\t\tm_context.functionGenerationQueueEmpty(),\n\t\t\"Reset function generation queue while it still had functions.\"\n\t);\n\tsolAssert(\n\t\tm_context.functionCollector().requestedFunctions().empty(),\n\t\t\"Reset context while it still had functions.\"\n\t);\n\tsolAssert(\n\t\tm_context.internalDispatchClean(),\n\t\t\"Reset internal dispatch map without consuming it.\"\n\t);\n\tIRGenerationContext newContext(\n\t\tm_evmVersion,\n\t\tm_eofVersion,\n\t\t_context,\n\t\tm_context.revertStrings(),\n\t\tm_context.sourceIndices(),\n\t\tm_context.debugInfoSelection(),\n\t\tm_context.soliditySourceProvider()\n\t);\n\n\tm_context = std::move(newContext);\n\n\tm_context.setMostDerivedContract(_contract);\n\tfor (auto const location: {DataLocation::Storage, DataLocation::Transient})\n\t\tfor (auto const& var: ContractType(_contract).linearizedStateVariables(location))\n\t\t\tm_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var));\n}\n\nstd::string IRGenerator::dispenseLocationComment(ASTNode const& _node)\n{\n\treturn ::dispenseLocationComment(_node, m_context);\n}\n"
  },
  {
    "path": "libsolidity/codegen/ir/IRGenerator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Alex Beregszaszi\n * @date 2017\n * Component that translates Solidity code into Yul.\n */\n\n#pragma once\n\n#include <libsolutil/JSON.h>\n\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/CallGraph.h>\n#include <libsolidity/codegen/ir/IRGenerationContext.h>\n#include <libsolidity/codegen/YulUtilFunctions.h>\n#include <libsolidity/interface/OptimiserSettings.h>\n\n#include <liblangutil/CharStreamProvider.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <string>\n\nnamespace solidity::frontend\n{\n\nclass SourceUnit;\n\nclass IRGenerator\n{\npublic:\n\tusing ExecutionContext = IRGenerationContext::ExecutionContext;\n\n\tIRGenerator(\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tRevertStrings _revertStrings,\n\t\tstd::map<std::string, unsigned> _sourceIndices,\n\t\tlangutil::DebugInfoSelection const& _debugInfoSelection,\n\t\tlangutil::CharStreamProvider const* _soliditySourceProvider,\n\t\tOptimiserSettings& _optimiserSettings\n\t):\n\t\tm_evmVersion(_evmVersion),\n\t\tm_eofVersion(_eofVersion),\n\t\tm_context(\n\t\t\t_evmVersion,\n\t\t\t_eofVersion,\n\t\t\tExecutionContext::Creation,\n\t\t\t_revertStrings,\n\t\t\tstd::move(_sourceIndices),\n\t\t\t_debugInfoSelection,\n\t\t\t_soliditySourceProvider\n\t\t),\n\t\tm_utils(_evmVersion, _eofVersion, m_context.revertStrings(), m_context.functionCollector()),\n\t\tm_optimiserSettings(_optimiserSettings)\n\t{}\n\n\t/// Generates and returns (unoptimized) IR code.\n\tstd::string run(\n\t\tContractDefinition const& _contract,\n\t\tbytes const& _cborMetadata,\n\t\tstd::map<ContractDefinition const*, std::string_view const> const& _otherYulSources\n\t);\n\nprivate:\n\tstd::string generate(\n\t\tContractDefinition const& _contract,\n\t\tbytes const& _cborMetadata,\n\t\tstd::map<ContractDefinition const*, std::string_view const> const& _otherYulSources\n\t);\n\tstd::string generate(Block const& _block);\n\n\t/// Generates code for all the functions from the function generation queue.\n\t/// The resulting code is stored in the function collector in IRGenerationContext.\n\t/// @returns A set of ast nodes of the generated functions.\n\tstd::set<FunctionDefinition const*> generateQueuedFunctions();\n\t/// Generates  all the internal dispatch functions necessary to handle any function that could\n\t/// possibly be called via a pointer.\n\t/// @return The content of the dispatch for reuse in runtime code. Reuse is necessary because\n\t/// pointers to functions can be passed from the creation code in storage variables.\n\tInternalDispatchMap generateInternalDispatchFunctions(ContractDefinition const& _contract);\n\t/// Generates code for and returns the name of the function.\n\tstd::string generateFunction(FunctionDefinition const& _function);\n\tstd::string generateModifier(\n\t\tModifierInvocation const& _modifierInvocation,\n\t\tFunctionDefinition const& _function,\n\t\tstd::string const& _nextFunction\n\t);\n\tstd::string generateFunctionWithModifierInner(FunctionDefinition const& _function);\n\t/// Generates a getter for the given declaration and returns its name\n\tstd::string generateGetter(VariableDeclaration const& _varDecl);\n\n\t/// Generates the external part (ABI decoding and encoding) of a function or getter.\n\tstd::string generateExternalFunction(ContractDefinition const& _contract, FunctionType const& _functionType);\n\n\t/// Generates code that assigns the initial value of the respective type.\n\tstd::string generateInitialAssignment(VariableDeclaration const& _varDecl);\n\n\t/// Generates constructors for all contracts in the inheritance hierarchy of\n\t/// @a _contract\n\t/// If there are user defined constructors, their body will be included in the implicit constructor's body.\n\tvoid generateConstructors(ContractDefinition const& _contract);\n\n\t/// Evaluates constructor's arguments for all base contracts (listed in inheritance specifiers) of\n\t/// @a _contract\n\t/// @returns Pair of expressions needed to evaluate params and list of parameters in a map contract -> params\n\tstd::pair<std::string, std::map<ContractDefinition const*, std::vector<std::string>>>\n\tevaluateConstructorArguments(ContractDefinition const& _contract);\n\n\t/// Initializes state variables of\n\t/// @a _contract\n\t/// @returns Source code to initialize state variables\n\tstd::string initStateVariables(ContractDefinition const& _contract);\n\n\tstd::string deployCode(ContractDefinition const& _contract);\n\tstd::string callValueCheck();\n\n\tstd::string dispatchRoutine(ContractDefinition const& _contract);\n\n\t/// @a _useMemoryGuard If true, use a memory guard, allowing the optimiser\n\t/// to perform memory optimizations.\n\tstd::string memoryInit(bool _useMemoryGuard);\n\n\tvoid resetContext(ContractDefinition const& _contract, ExecutionContext _context);\n\n\tstd::string dispenseLocationComment(ASTNode const& _node);\n\n\tlangutil::EVMVersion const m_evmVersion;\n\tstd::optional<uint8_t> const m_eofVersion;\n\n\tIRGenerationContext m_context;\n\tYulUtilFunctions m_utils;\n\tOptimiserSettings m_optimiserSettings;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ir/IRGeneratorForStatements.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that translates Solidity code into Yul at statement level and below.\n */\n\n#include <libsolidity/codegen/ir/IRGeneratorForStatements.h>\n\n#include <libsolidity/codegen/ABIFunctions.h>\n#include <libsolidity/codegen/ir/IRGenerationContext.h>\n#include <libsolidity/codegen/ir/IRLValue.h>\n#include <libsolidity/codegen/ir/IRVariable.h>\n#include <libsolidity/codegen/YulUtilFunctions.h>\n#include <libsolidity/codegen/ABIFunctions.h>\n#include <libsolidity/codegen/CompilerUtils.h>\n#include <libsolidity/codegen/ReturnInfo.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/ast/ASTUtils.h>\n#include <libsolidity/analysis/ConstantEvaluator.h>\n\n#include <libevmasm/GasMeter.h>\n\n#include <libyul/AsmPrinter.h>\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/Utilities.h>\n#include <libyul/optimiser/ASTCopier.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <libsolutil/Whiskers.h>\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/Keccak256.h>\n#include <libsolutil/FunctionSelector.h>\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/algorithm/all_of.hpp>\n#include <range/v3/view/transform.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::frontend;\nusing namespace std::string_literals;\n\nnamespace\n{\n\nstruct CopyTranslate: public yul::ASTCopier\n{\n\tusing ExternalRefsMap = std::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo>;\n\n\tCopyTranslate(IRGenerationContext& _context, ExternalRefsMap const& _references):\n\t\tm_context(_context), m_references(_references) {}\n\n\tusing ASTCopier::operator();\n\n\tyul::Expression operator()(yul::Identifier const& _identifier) override\n\t{\n\t\t// The operator() function is only called in lvalue context. In rvalue context,\n\t\t// only translate(yul::Identifier) is called.\n\t\tif (m_references.count(&_identifier))\n\t\t\treturn translateReference(_identifier);\n\t\telse\n\t\t\treturn ASTCopier::operator()(_identifier);\n\t}\n\n\tyul::YulName translateIdentifier(yul::YulName _name) override\n\t{\n\t\t// Strictly, the dialect used by inline assembly could be different\n\t\t// from the Yul dialect we are compiling to. By only translating `YulName`s which correspond to Identifiers,\n\t\t// we are implicitly excluding builtins together with the assumption, that numerical builtin handles\n\t\t// stay identical. Special care has to be taken, that these numerical handles stay consistent.\n\t\treturn yul::YulName{\"usr$\" + _name.str()};\n\t}\n\n\tyul::Identifier translate(yul::Identifier const& _identifier) override\n\t{\n\t\tif (!m_references.count(&_identifier))\n\t\t\treturn ASTCopier::translate(_identifier);\n\n\t\tyul::Expression translated = translateReference(_identifier);\n\t\tsolAssert(std::holds_alternative<yul::Identifier>(translated));\n\t\treturn std::get<yul::Identifier>(std::move(translated));\n\t}\n\nprivate:\n\n\t/// Translates a reference to a local variable, potentially including\n\t/// a suffix. Might return a literal, which causes this to be invalid in\n\t/// lvalue-context.\n\tyul::Expression translateReference(yul::Identifier const& _identifier)\n\t{\n\t\tauto const& reference = m_references.at(&_identifier);\n\t\tauto const varDecl = dynamic_cast<VariableDeclaration const*>(reference.declaration);\n\t\tsolUnimplementedAssert(varDecl);\n\t\tstd::string const& suffix = reference.suffix;\n\n\t\tstd::string value;\n\t\tif (suffix.empty() && varDecl->isLocalVariable())\n\t\t{\n\t\t\tauto const& var = m_context.localVariable(*varDecl);\n\t\t\tsolAssert(var.type().sizeOnStack() == 1);\n\n\t\t\tvalue = var.commaSeparatedList();\n\t\t}\n\t\telse if (varDecl->isConstant())\n\t\t{\n\t\t\tVariableDeclaration const* variable = rootConstVariableDeclaration(*varDecl);\n\t\t\tsolAssert(variable);\n\n\t\t\tif (variable->value()->annotation().type->category() == Type::Category::RationalNumber)\n\t\t\t{\n\t\t\t\tu256 intValue = dynamic_cast<RationalNumberType const&>(*variable->value()->annotation().type).literalValue(nullptr);\n\t\t\t\tif (auto const* bytesType = dynamic_cast<FixedBytesType const*>(variable->type()))\n\t\t\t\t\tintValue <<= 256 - 8 * bytesType->numBytes();\n\t\t\t\telse\n\t\t\t\t\tsolAssert(variable->type()->category() == Type::Category::Integer);\n\t\t\t\tvalue = intValue.str();\n\t\t\t}\n\t\t\telse if (auto const* literal = dynamic_cast<Literal const*>(variable->value().get()))\n\t\t\t{\n\t\t\t\tType const* type = literal->annotation().type;\n\n\t\t\t\tswitch (type->category())\n\t\t\t\t{\n\t\t\t\tcase Type::Category::Bool:\n\t\t\t\tcase Type::Category::Address:\n\t\t\t\t\tsolAssert(type->category() == variable->annotation().type->category());\n\t\t\t\t\tvalue = toCompactHexWithPrefix(type->literalValue(literal));\n\t\t\t\t\tbreak;\n\t\t\t\tcase Type::Category::StringLiteral:\n\t\t\t\t{\n\t\t\t\t\tauto const& stringLiteral = dynamic_cast<StringLiteralType const&>(*type);\n\t\t\t\t\tsolAssert(variable->type()->category() == Type::Category::FixedBytes);\n\t\t\t\t\tunsigned const numBytes = dynamic_cast<FixedBytesType const&>(*variable->type()).numBytes();\n\t\t\t\t\tsolAssert(stringLiteral.value().size() <= numBytes);\n\t\t\t\t\tvalue = formatNumber(u256(h256(stringLiteral.value(), h256::AlignLeft)));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tsolAssert(false);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tsolAssert(false, \"Invalid constant in inline assembly.\");\n\t\t}\n\t\telse if (varDecl->isStateVariable())\n\t\t{\n\t\t\tif (suffix == \"slot\")\n\t\t\t\tvalue = m_context.storageLocationOfStateVariable(*varDecl).first.str();\n\t\t\telse if (suffix == \"offset\")\n\t\t\t\tvalue = std::to_string(m_context.storageLocationOfStateVariable(*varDecl).second);\n\t\t\telse\n\t\t\t\tsolAssert(false);\n\t\t}\n\t\telse if (varDecl->type()->dataStoredIn(DataLocation::Storage))\n\t\t{\n\t\t\tsolAssert(suffix == \"slot\" || suffix == \"offset\");\n\t\t\tsolAssert(varDecl->isLocalVariable());\n\t\t\tsolAssert(!varDecl->type()->isValueType());\n\t\t\tif (suffix == \"slot\")\n\t\t\t\tvalue = IRVariable{*varDecl}.part(\"slot\").name();\n\t\t\telse\n\t\t\t{\n\t\t\t\tsolAssert(!IRVariable{*varDecl}.hasPart(\"offset\"));\n\t\t\t\tvalue = \"0\"s;\n\t\t\t}\n\t\t}\n\t\telse if (varDecl->type()->dataStoredIn(DataLocation::CallData))\n\t\t{\n\t\t\tsolAssert(suffix == \"offset\" || suffix == \"length\");\n\t\t\tvalue = IRVariable{*varDecl}.part(suffix).name();\n\t\t}\n\t\telse if (\n\t\t\tauto const* functionType = dynamic_cast<FunctionType const*>(varDecl->type());\n\t\t\tfunctionType && functionType->kind() == FunctionType::Kind::External\n\t\t)\n\t\t{\n\t\t\tsolAssert(suffix == \"selector\" || suffix == \"address\");\n\t\t\tsolAssert(varDecl->type()->sizeOnStack() == 2);\n\t\t\tif (suffix == \"selector\")\n\t\t\t\tvalue = IRVariable{*varDecl}.part(\"functionSelector\").name();\n\t\t\telse\n\t\t\t\tvalue = IRVariable{*varDecl}.part(\"address\").name();\n\t\t}\n\t\telse\n\t\t\tsolAssert(false);\n\n\t\tif (isDigit(value.front()))\n\t\t\treturn yul::Literal{_identifier.debugData, yul::LiteralKind::Number, yul::valueOfNumberLiteral(value)};\n\t\telse\n\t\t\treturn yul::Identifier{_identifier.debugData, yul::YulName{value}};\n\t}\n\n\tIRGenerationContext& m_context;\n\tExternalRefsMap const& m_references;\n};\n\n}\n\nstd::string IRGeneratorForStatementsBase::code() const\n{\n\treturn m_code.str();\n}\n\nstd::ostringstream& IRGeneratorForStatementsBase::appendCode(bool _addLocationComment)\n{\n\tif (\n\t\t_addLocationComment &&\n\t\tm_currentLocation.isValid() &&\n\t\tm_lastLocation != m_currentLocation\n\t)\n\t\tm_code << dispenseLocationComment(m_currentLocation, m_context) << \"\\n\";\n\n\tm_lastLocation = m_currentLocation;\n\n\treturn m_code;\n}\n\nvoid IRGeneratorForStatementsBase::setLocation(ASTNode const& _node)\n{\n\tm_currentLocation = _node.location();\n}\n\nstd::string IRGeneratorForStatements::code() const\n{\n\tsolAssert(!m_currentLValue, \"LValue not reset!\");\n\treturn IRGeneratorForStatementsBase::code();\n}\n\nvoid IRGeneratorForStatements::generate(Block const& _block)\n{\n\ttry\n\t{\n\t\t_block.accept(*this);\n\t}\n\tcatch (langutil::UnimplementedFeatureError const& _error)\n\t{\n\t\tif (!boost::get_error_info<langutil::errinfo_sourceLocation>(_error))\n\t\t\t_error << langutil::errinfo_sourceLocation(m_currentLocation);\n\t\tBOOST_THROW_EXCEPTION(_error);\n\t}\n}\n\nvoid IRGeneratorForStatements::initializeStateVar(VariableDeclaration const& _varDecl)\n{\n\ttry\n\t{\n\t\tsetLocation(_varDecl);\n\n\t\tsolAssert(_varDecl.immutable() || m_context.isStateVariable(_varDecl), \"Must be immutable or a state variable.\");\n\t\tsolAssert(!_varDecl.isConstant());\n\t\tif (!_varDecl.value())\n\t\t\treturn;\n\t\tsolAssert(_varDecl.referenceLocation() != VariableDeclaration::Location::Transient, \"Transient storage state variables cannot be initialized in place.\");\n\n\t\t_varDecl.value()->accept(*this);\n\n\t\twriteToLValue(\n\t\t\t_varDecl.immutable() ?\n\t\t\tIRLValue{*_varDecl.annotation().type, IRLValue::Immutable{&_varDecl}} :\n\t\t\tIRLValue{*_varDecl.annotation().type, IRLValue::Storage{\n\t\t\t\ttoCompactHexWithPrefix(m_context.storageLocationOfStateVariable(_varDecl).first),\n\t\t\t\tm_context.storageLocationOfStateVariable(_varDecl).second\n\t\t\t}},\n\t\t\t*_varDecl.value()\n\t\t);\n\t}\n\tcatch (langutil::UnimplementedFeatureError const& _error)\n\t{\n\t\tif (!boost::get_error_info<langutil::errinfo_sourceLocation>(_error))\n\t\t\t_error << langutil::errinfo_sourceLocation(m_currentLocation);\n\t\tBOOST_THROW_EXCEPTION(_error);\n\t}\n}\n\nvoid IRGeneratorForStatements::initializeLocalVar(VariableDeclaration const& _varDecl)\n{\n\ttry\n\t{\n\t\tsetLocation(_varDecl);\n\n\t\tsolAssert(m_context.isLocalVariable(_varDecl), \"Must be a local variable.\");\n\n\t\tauto const* type = _varDecl.type();\n\t\tif (dynamic_cast<MappingType const*>(type))\n\t\t\treturn;\n\t\telse if (auto const* refType = dynamic_cast<ReferenceType const*>(type))\n\t\t\tif (refType->dataStoredIn(DataLocation::Storage) && refType->isPointer())\n\t\t\t\treturn;\n\n\t\tIRVariable zero = zeroValue(*type);\n\t\tassign(m_context.localVariable(_varDecl), zero);\n\t}\n\tcatch (langutil::UnimplementedFeatureError const& _error)\n\t{\n\t\tif (!boost::get_error_info<langutil::errinfo_sourceLocation>(_error))\n\t\t\t_error << langutil::errinfo_sourceLocation(m_currentLocation);\n\t\tBOOST_THROW_EXCEPTION(_error);\n\t}\n}\n\nIRVariable IRGeneratorForStatements::evaluateExpression(Expression const& _expression, Type const& _targetType)\n{\n\ttry\n\t{\n\t\tsetLocation(_expression);\n\n\t\t_expression.accept(*this);\n\n\t\tsetLocation(_expression);\n\t\tIRVariable variable{m_context.newYulVariable(), _targetType};\n\t\tdefine(variable, _expression);\n\t\treturn variable;\n\t}\n\tcatch (langutil::UnimplementedFeatureError const& _error)\n\t{\n\t\tif (!boost::get_error_info<langutil::errinfo_sourceLocation>(_error))\n\t\t\t_error << langutil::errinfo_sourceLocation(m_currentLocation);\n\t\tBOOST_THROW_EXCEPTION(_error);\n\t}\n}\n\nstd::string IRGeneratorForStatements::constantValueFunction(VariableDeclaration const& _constant)\n{\n\ttry\n\t{\n\t\tstd::string functionName = IRNames::constantValueFunction(_constant);\n\t\treturn m_context.functionCollector().createFunction(functionName, [&] {\n\t\t\tWhiskers templ(R\"(\n\t\t\t\t<sourceLocationComment>\n\t\t\t\tfunction <functionName>() -> <ret> {\n\t\t\t\t\t<code>\n\t\t\t\t\t<ret> := <value>\n\t\t\t\t}\n\t\t\t)\");\n\t\t\ttempl(\"sourceLocationComment\", dispenseLocationComment(_constant, m_context));\n\t\t\ttempl(\"functionName\", functionName);\n\t\t\tIRGeneratorForStatements generator(m_context, m_utils, m_optimiserSettings);\n\t\t\tsolAssert(_constant.value());\n\t\t\tType const& constantType = *_constant.type();\n\t\t\ttempl(\"value\", generator.evaluateExpression(*_constant.value(), constantType).commaSeparatedList());\n\t\t\ttempl(\"code\", generator.code());\n\t\t\ttempl(\"ret\", IRVariable(\"ret\", constantType).commaSeparatedList());\n\n\t\t\treturn templ.render();\n\t\t});\n\t}\n\tcatch (langutil::UnimplementedFeatureError const& _error)\n\t{\n\t\tif (!boost::get_error_info<langutil::errinfo_sourceLocation>(_error))\n\t\t\t_error << langutil::errinfo_sourceLocation(m_currentLocation);\n\t\tBOOST_THROW_EXCEPTION(_error);\n\t}\n}\n\nvoid IRGeneratorForStatements::endVisit(VariableDeclarationStatement const& _varDeclStatement)\n{\n\tsetLocation(_varDeclStatement);\n\n\tif (Expression const* expression = _varDeclStatement.initialValue())\n\t{\n\t\tif (_varDeclStatement.declarations().size() > 1)\n\t\t{\n\t\t\tauto const* tupleType = dynamic_cast<TupleType const*>(expression->annotation().type);\n\t\t\tsolAssert(tupleType, \"Expected expression of tuple type.\");\n\t\t\tsolAssert(_varDeclStatement.declarations().size() == tupleType->components().size(), \"Invalid number of tuple components.\");\n\t\t\tfor (size_t i = 0; i < _varDeclStatement.declarations().size(); ++i)\n\t\t\t\tif (auto const& decl = _varDeclStatement.declarations()[i])\n\t\t\t\t{\n\t\t\t\t\tsolAssert(tupleType->components()[i]);\n\t\t\t\t\tdefine(m_context.addLocalVariable(*decl), IRVariable(*expression).tupleComponent(i));\n\t\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tVariableDeclaration const& varDecl = *_varDeclStatement.declarations().front();\n\t\t\tdefine(m_context.addLocalVariable(varDecl), *expression);\n\t\t}\n\t}\n\telse\n\t\tfor (auto const& decl: _varDeclStatement.declarations())\n\t\t\tif (decl)\n\t\t\t{\n\t\t\t\tdeclare(m_context.addLocalVariable(*decl));\n\t\t\t\tinitializeLocalVar(*decl);\n\t\t\t}\n}\n\nbool IRGeneratorForStatements::visit(Conditional const& _conditional)\n{\n\t_conditional.condition().accept(*this);\n\n\tsetLocation(_conditional);\n\n\tstd::string condition = expressionAsType(_conditional.condition(), *TypeProvider::boolean());\n\tdeclare(_conditional);\n\n\tappendCode() << \"switch \" << condition << \"\\n\" \"case 0 {\\n\";\n\n\t_conditional.falseExpression().accept(*this);\n\tsetLocation(_conditional);\n\n\tassign(_conditional, _conditional.falseExpression());\n\tappendCode() << \"}\\n\" \"default {\\n\";\n\n\t_conditional.trueExpression().accept(*this);\n\tsetLocation(_conditional);\n\n\tassign(_conditional, _conditional.trueExpression());\n\tappendCode() << \"}\\n\";\n\n\treturn false;\n}\n\nbool IRGeneratorForStatements::visit(Assignment const& _assignment)\n{\n\t_assignment.rightHandSide().accept(*this);\n\tsetLocation(_assignment);\n\n\tToken assignmentOperator = _assignment.assignmentOperator();\n\tToken binaryOperator =\n\t\tassignmentOperator == Token::Assign ?\n\t\tassignmentOperator :\n\t\tTokenTraits::AssignmentToBinaryOp(assignmentOperator);\n\n\tif (TokenTraits::isShiftOp(binaryOperator))\n\t\tsolAssert(type(_assignment.rightHandSide()).mobileType());\n\tIRVariable value =\n\t\ttype(_assignment.leftHandSide()).isValueType() ?\n\t\tconvert(\n\t\t\t_assignment.rightHandSide(),\n\t\t\tTokenTraits::isShiftOp(binaryOperator) ? *type(_assignment.rightHandSide()).mobileType() : type(_assignment)\n\t\t) :\n\t\t_assignment.rightHandSide();\n\n\t_assignment.leftHandSide().accept(*this);\n\n\tsolAssert(!!m_currentLValue, \"LValue not retrieved.\");\n\tsetLocation(_assignment);\n\n\tif (assignmentOperator != Token::Assign)\n\t{\n\t\tsolAssert(type(_assignment.leftHandSide()).isValueType(), \"Compound operators only available for value types.\");\n\t\tsolAssert(binaryOperator != Token::Exp);\n\t\tsolAssert(type(_assignment) == type(_assignment.leftHandSide()));\n\n\t\tIRVariable leftIntermediate = readFromLValue(*m_currentLValue);\n\t\tsolAssert(type(_assignment) == leftIntermediate.type());\n\n\t\tdefine(_assignment) << (\n\t\t\tTokenTraits::isShiftOp(binaryOperator) ?\n\t\t\tshiftOperation(binaryOperator, leftIntermediate, value) :\n\t\t\tbinaryOperation(binaryOperator, type(_assignment), leftIntermediate.name(), value.name())\n\t\t) << \"\\n\";\n\n\t\twriteToLValue(*m_currentLValue, IRVariable(_assignment));\n\t}\n\telse\n\t{\n\t\twriteToLValue(*m_currentLValue, value);\n\n\t\tif (dynamic_cast<ReferenceType const*>(&m_currentLValue->type))\n\t\t\tdefine(_assignment, readFromLValue(*m_currentLValue));\n\t\telse if (*_assignment.annotation().type != *TypeProvider::emptyTuple())\n\t\t\tdefine(_assignment, value);\n\t}\n\n\tm_currentLValue.reset();\n\treturn false;\n}\n\nbool IRGeneratorForStatements::visit(TupleExpression const& _tuple)\n{\n\tsetLocation(_tuple);\n\n\tif (_tuple.isInlineArray())\n\t{\n\t\tauto const& arrayType = dynamic_cast<ArrayType const&>(*_tuple.annotation().type);\n\t\tsolAssert(!arrayType.isDynamicallySized(), \"Cannot create dynamically sized inline array.\");\n\t\tdefine(_tuple) <<\n\t\t\tm_utils.allocateMemoryArrayFunction(arrayType) <<\n\t\t\t\"(\" <<\n\t\t\t_tuple.components().size() <<\n\t\t\t\")\\n\";\n\n\t\tstd::string mpos = IRVariable(_tuple).part(\"mpos\").name();\n\t\tType const& baseType = *arrayType.baseType();\n\t\tfor (size_t i = 0; i < _tuple.components().size(); i++)\n\t\t{\n\t\t\tExpression const& component = *_tuple.components()[i];\n\t\t\tcomponent.accept(*this);\n\t\t\tsetLocation(_tuple);\n\t\t\tIRVariable converted = convert(component, baseType);\n\t\t\tappendCode() <<\n\t\t\t\tm_utils.writeToMemoryFunction(baseType) <<\n\t\t\t\t\"(\" <<\n\t\t\t\t(\"add(\" + mpos + \", \" + std::to_string(i * arrayType.memoryStride()) + \")\") <<\n\t\t\t\t\", \" <<\n\t\t\t\tconverted.commaSeparatedList() <<\n\t\t\t\t\")\\n\";\n\t\t}\n\t}\n\telse\n\t{\n\t\tbool willBeWrittenTo = _tuple.annotation().willBeWrittenTo;\n\t\tif (willBeWrittenTo)\n\t\t\tsolAssert(!m_currentLValue);\n\t\tif (_tuple.components().size() == 1)\n\t\t{\n\t\t\tsolAssert(_tuple.components().front());\n\t\t\t_tuple.components().front()->accept(*this);\n\t\t\tsetLocation(_tuple);\n\t\t\tif (willBeWrittenTo)\n\t\t\t\tsolAssert(!!m_currentLValue);\n\t\t\telse\n\t\t\t\tdefine(_tuple, *_tuple.components().front());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstd::vector<std::optional<IRLValue>> lvalues;\n\t\t\tfor (size_t i = 0; i < _tuple.components().size(); ++i)\n\t\t\t\tif (auto const& component = _tuple.components()[i])\n\t\t\t\t{\n\t\t\t\t\tcomponent->accept(*this);\n\t\t\t\t\tsetLocation(_tuple);\n\t\t\t\t\tif (willBeWrittenTo)\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(!!m_currentLValue);\n\t\t\t\t\t\tlvalues.emplace_back(std::move(m_currentLValue));\n\t\t\t\t\t\tm_currentLValue.reset();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tdefine(IRVariable(_tuple).tupleComponent(i), *component);\n\t\t\t\t}\n\t\t\t\telse if (willBeWrittenTo)\n\t\t\t\t\tlvalues.emplace_back();\n\n\t\t\tif (_tuple.annotation().willBeWrittenTo)\n\t\t\t\tm_currentLValue.emplace(IRLValue{\n\t\t\t\t\t*_tuple.annotation().type,\n\t\t\t\t\tIRLValue::Tuple{std::move(lvalues)}\n\t\t\t\t});\n\t\t}\n\t}\n\treturn false;\n}\n\nbool IRGeneratorForStatements::visit(Block const& _block)\n{\n\tif (_block.unchecked())\n\t{\n\t\tsolAssert(m_context.arithmetic() == Arithmetic::Checked);\n\t\tm_context.setArithmetic(Arithmetic::Wrapping);\n\t}\n\treturn true;\n}\n\nvoid IRGeneratorForStatements::endVisit(Block const& _block)\n{\n\tif (_block.unchecked())\n\t{\n\t\tsolAssert(m_context.arithmetic() == Arithmetic::Wrapping);\n\t\tm_context.setArithmetic(Arithmetic::Checked);\n\t}\n}\n\nbool IRGeneratorForStatements::visit(IfStatement const& _ifStatement)\n{\n\t_ifStatement.condition().accept(*this);\n\tsetLocation(_ifStatement);\n\tstd::string condition = expressionAsType(_ifStatement.condition(), *TypeProvider::boolean());\n\n\tif (_ifStatement.falseStatement())\n\t{\n\t\tappendCode() << \"switch \" << condition << \"\\n\" \"case 0 {\\n\";\n\t\t_ifStatement.falseStatement()->accept(*this);\n\t\tsetLocation(_ifStatement);\n\t\tappendCode() << \"}\\n\" \"default {\\n\";\n\t}\n\telse\n\t\tappendCode() << \"if \" << condition << \" {\\n\";\n\t_ifStatement.trueStatement().accept(*this);\n\tsetLocation(_ifStatement);\n\tappendCode() << \"}\\n\";\n\n\treturn false;\n}\n\nvoid IRGeneratorForStatements::endVisit(PlaceholderStatement const& _placeholder)\n{\n\tsolAssert(m_placeholderCallback);\n\tsetLocation(_placeholder);\n\tappendCode() << m_placeholderCallback();\n}\n\nbool IRGeneratorForStatements::visit(ForStatement const& _forStatement)\n{\n\tsetLocation(_forStatement);\n\tgenerateLoop(\n\t\t_forStatement.body(),\n\t\t_forStatement.condition(),\n\t\t_forStatement.initializationExpression(),\n\t\t_forStatement.loopExpression(),\n\t\tfalse, // _isDoWhile\n\t\t*_forStatement.annotation().isSimpleCounterLoop\n\t);\n\n\treturn false;\n}\n\nbool IRGeneratorForStatements::visit(WhileStatement const& _whileStatement)\n{\n\tsetLocation(_whileStatement);\n\tgenerateLoop(\n\t\t_whileStatement.body(),\n\t\t&_whileStatement.condition(),\n\t\tnullptr,\n\t\tnullptr,\n\t\t_whileStatement.isDoWhile()\n\t);\n\n\treturn false;\n}\n\nbool IRGeneratorForStatements::visit(Continue const& _continue)\n{\n\tsetLocation(_continue);\n\tappendCode() << \"continue\\n\";\n\treturn false;\n}\n\nbool IRGeneratorForStatements::visit(Break const& _break)\n{\n\tsetLocation(_break);\n\tappendCode() << \"break\\n\";\n\treturn false;\n}\n\nvoid IRGeneratorForStatements::endVisit(Return const& _return)\n{\n\tsetLocation(_return);\n\tif (Expression const* value = _return.expression())\n\t{\n\t\tsolAssert(_return.annotation().functionReturnParameters, \"Invalid return parameters pointer.\");\n\t\tstd::vector<ASTPointer<VariableDeclaration>> const& returnParameters =\n\t\t\t_return.annotation().functionReturnParameters->parameters();\n\t\tif (returnParameters.size() > 1)\n\t\t\tfor (size_t i = 0; i < returnParameters.size(); ++i)\n\t\t\t\tassign(m_context.localVariable(*returnParameters[i]), IRVariable(*value).tupleComponent(i));\n\t\telse if (returnParameters.size() == 1)\n\t\t\tassign(m_context.localVariable(*returnParameters.front()), *value);\n\t}\n\tappendCode() << \"leave\\n\";\n}\n\nbool IRGeneratorForStatements::visit(UnaryOperation const& _unaryOperation)\n{\n\tsetLocation(_unaryOperation);\n\n\tFunctionDefinition const* function = *_unaryOperation.annotation().userDefinedFunction;\n\tif (function)\n\t{\n\t\t_unaryOperation.subExpression().accept(*this);\n\t\tsetLocation(_unaryOperation);\n\n\t\tsolAssert(function->isImplemented());\n\t\tsolAssert(function->isFree());\n\t\tsolAssert(function->parameters().size() == 1);\n\t\tsolAssert(function->returnParameters().size() == 1);\n\t\tsolAssert(*function->returnParameters()[0]->type() == *_unaryOperation.annotation().type);\n\n\t\tstd::string argument = expressionAsType(_unaryOperation.subExpression(), *function->parameters()[0]->type());\n\t\tsolAssert(!argument.empty());\n\n\t\tsolAssert(_unaryOperation.userDefinedFunctionType()->kind() == FunctionType::Kind::Internal);\n\t\tdefine(_unaryOperation) <<\n\t\t\tm_context.enqueueFunctionForCodeGeneration(*function) <<\n\t\t\t(\"(\" + argument + \")\\n\");\n\n\t\treturn false;\n\t}\n\n\tType const& resultType = type(_unaryOperation);\n\tToken const op = _unaryOperation.getOperator();\n\n\tif (resultType.category() == Type::Category::RationalNumber)\n\t{\n\t\tdefine(_unaryOperation) << formatNumber(resultType.literalValue(nullptr)) << \"\\n\";\n\t\treturn false;\n\t}\n\n\t_unaryOperation.subExpression().accept(*this);\n\tsetLocation(_unaryOperation);\n\n\tif (op == Token::Delete)\n\t{\n\t\tsolAssert(!!m_currentLValue, \"LValue not retrieved.\");\n\t\tstd::visit(\n\t\t\tutil::GenericVisitor{\n\t\t\t\t[&](IRLValue::Storage const& _storage) {\n\t\t\t\t\tappendCode() <<\n\t\t\t\t\t\tm_utils.storageSetToZeroFunction(m_currentLValue->type, VariableDeclaration::Location::Unspecified) <<\n\t\t\t\t\t\t\"(\" <<\n\t\t\t\t\t\t_storage.slot <<\n\t\t\t\t\t\t\", \" <<\n\t\t\t\t\t\t_storage.offsetString() <<\n\t\t\t\t\t\t\")\\n\";\n\t\t\t\t\tm_currentLValue.reset();\n\t\t\t\t},\n\t\t\t\t[&](IRLValue::TransientStorage const& _transientStorage) {\n\t\t\t\t\tappendCode() <<\n\t\t\t\t\t\tm_utils.storageSetToZeroFunction(m_currentLValue->type, VariableDeclaration::Location::Transient) <<\n\t\t\t\t\t\t\"(\" <<\n\t\t\t\t\t\t_transientStorage.slot <<\n\t\t\t\t\t\t\", \" <<\n\t\t\t\t\t\t_transientStorage.offsetString() <<\n\t\t\t\t\t\t\")\\n\";\n\t\t\t\t\tm_currentLValue.reset();\n\t\t\t\t},\n\t\t\t\t[&](auto const&) {\n\t\t\t\t\tIRVariable zeroValue(m_context.newYulVariable(), m_currentLValue->type);\n\t\t\t\t\tdefine(zeroValue) << m_utils.zeroValueFunction(m_currentLValue->type) << \"()\\n\";\n\t\t\t\t\twriteToLValue(*m_currentLValue, zeroValue);\n\t\t\t\t\tm_currentLValue.reset();\n\t\t\t\t}\n\t\t\t},\n\t\t\tm_currentLValue->kind\n\t\t);\n\t}\n\telse if (resultType.category() == Type::Category::Integer)\n\t{\n\t\tsolAssert(resultType == type(_unaryOperation.subExpression()), \"Result type doesn't match!\");\n\n\t\tif (op == Token::Inc || op == Token::Dec)\n\t\t{\n\t\t\tsolAssert(!!m_currentLValue, \"LValue not retrieved.\");\n\t\t\tIRVariable modifiedValue(m_context.newYulVariable(), resultType);\n\t\t\tIRVariable originalValue = readFromLValue(*m_currentLValue);\n\n\t\t\tbool checked = m_context.arithmetic() == Arithmetic::Checked;\n\t\t\tdefine(modifiedValue) <<\n\t\t\t\t(op == Token::Inc ?\n\t\t\t\t\t(checked ? m_utils.incrementCheckedFunction(resultType) : m_utils.incrementWrappingFunction(resultType)) :\n\t\t\t\t\t(checked ? m_utils.decrementCheckedFunction(resultType) : m_utils.decrementWrappingFunction(resultType))\n\t\t\t\t) <<\n\t\t\t\t\"(\" <<\n\t\t\t\toriginalValue.name() <<\n\t\t\t\t\")\\n\";\n\t\t\twriteToLValue(*m_currentLValue, modifiedValue);\n\t\t\tm_currentLValue.reset();\n\n\t\t\tdefine(_unaryOperation, _unaryOperation.isPrefixOperation() ? modifiedValue : originalValue);\n\t\t}\n\t\telse if (op == Token::BitNot)\n\t\t\tappendSimpleUnaryOperation(_unaryOperation, _unaryOperation.subExpression());\n\t\telse if (op == Token::Add)\n\t\t\t// According to SyntaxChecker...\n\t\t\tsolAssert(false, \"Use of unary + is disallowed.\");\n\t\telse if (op == Token::Sub)\n\t\t{\n\t\t\tIntegerType const& intType = *dynamic_cast<IntegerType const*>(&resultType);\n\t\t\tdefine(_unaryOperation) << (\n\t\t\t\tm_context.arithmetic() == Arithmetic::Checked ?\n\t\t\t\tm_utils.negateNumberCheckedFunction(intType) :\n\t\t\t\tm_utils.negateNumberWrappingFunction(intType)\n\t\t\t) << \"(\" << IRVariable(_unaryOperation.subExpression()).name() << \")\\n\";\n\t\t}\n\t\telse\n\t\t\tsolUnimplemented(\"Unary operator not yet implemented\");\n\t}\n\telse if (resultType.category() == Type::Category::FixedBytes)\n\t{\n\t\tsolAssert(op == Token::BitNot, \"Only bitwise negation is allowed for FixedBytes\");\n\t\tsolAssert(resultType == type(_unaryOperation.subExpression()), \"Result type doesn't match!\");\n\t\tappendSimpleUnaryOperation(_unaryOperation, _unaryOperation.subExpression());\n\t}\n\telse if (resultType.category() == Type::Category::Bool)\n\t{\n\t\tsolAssert(\n\t\t\top != Token::BitNot,\n\t\t\t\"Bitwise Negation can't be done on bool!\"\n\t\t);\n\n\t\tappendSimpleUnaryOperation(_unaryOperation, _unaryOperation.subExpression());\n\t}\n\telse\n\t\tsolUnimplemented(\"Unary operator not yet implemented\");\n\n\treturn false;\n}\n\nvoid IRGeneratorForStatements::endVisit(RevertStatement const& _revertStatement)\n{\n\tErrorDefinition const* error = dynamic_cast<ErrorDefinition const*>(ASTNode::referencedDeclaration(_revertStatement.errorCall().expression()));\n\tsolAssert(error);\n\trevertWithError(\n\t\terror->functionType(true)->externalSignature(),\n\t\terror->functionType(true)->parameterTypes(),\n\t\t_revertStatement.errorCall().sortedArguments()\n\t);\n}\n\nbool IRGeneratorForStatements::visit(BinaryOperation const& _binOp)\n{\n\tsetLocation(_binOp);\n\n\tFunctionDefinition const* function = *_binOp.annotation().userDefinedFunction;\n\tif (function)\n\t{\n\t\t_binOp.leftExpression().accept(*this);\n\t\t_binOp.rightExpression().accept(*this);\n\t\tsetLocation(_binOp);\n\n\t\tsolAssert(function->isImplemented());\n\t\tsolAssert(function->isFree());\n\t\tsolAssert(function->parameters().size() == 2);\n\t\tsolAssert(function->returnParameters().size() == 1);\n\t\tsolAssert(*function->returnParameters()[0]->type() == *_binOp.annotation().type);\n\n\t\tstd::string left = expressionAsType(_binOp.leftExpression(), *function->parameters()[0]->type());\n\t\tstd::string right = expressionAsType(_binOp.rightExpression(), *function->parameters()[1]->type());\n\t\tsolAssert(!left.empty() && !right.empty());\n\n\t\tsolAssert(_binOp.userDefinedFunctionType()->kind() == FunctionType::Kind::Internal);\n\t\tdefine(_binOp) <<\n\t\t\tm_context.enqueueFunctionForCodeGeneration(*function) <<\n\t\t\t(\"(\" + left + \", \" + right + \")\\n\");\n\n\t\treturn false;\n\t}\n\n\tsolAssert(!!_binOp.annotation().commonType);\n\tType const* commonType = _binOp.annotation().commonType;\n\tlangutil::Token op = _binOp.getOperator();\n\n\tif (op == Token::And || op == Token::Or)\n\t{\n\t\t// This can short-circuit!\n\t\tappendAndOrOperatorCode(_binOp);\n\t\treturn false;\n\t}\n\n\tif (commonType->category() == Type::Category::RationalNumber)\n\t{\n\t\tdefine(_binOp) << toCompactHexWithPrefix(commonType->literalValue(nullptr)) << \"\\n\";\n\t\treturn false; // skip sub-expressions\n\t}\n\n\t_binOp.leftExpression().accept(*this);\n\t_binOp.rightExpression().accept(*this);\n\tsetLocation(_binOp);\n\n\tif (TokenTraits::isCompareOp(op))\n\t{\n\t\tsolAssert(commonType->isValueType());\n\n\t\tbool isSigned = false;\n\t\tif (auto type = dynamic_cast<IntegerType const*>(commonType))\n\t\t\tisSigned = type->isSigned();\n\n\t\tstd::string args = expressionAsCleanedType(_binOp.leftExpression(), *commonType);\n\t\targs += \", \" + expressionAsCleanedType(_binOp.rightExpression(), *commonType);\n\n\t\tauto functionType = dynamic_cast<FunctionType const*>(commonType);\n\t\tsolAssert(functionType ? (op == Token::Equal || op == Token::NotEqual) : true, \"Invalid function pointer comparison!\");\n\n\t\tstd::string expr;\n\n\t\tif (functionType && functionType->kind() ==  FunctionType::Kind::External)\n\t\t{\n\t\t\tsolUnimplementedAssert(functionType->sizeOnStack() == 2, \"\");\n\t\t\texpr = m_utils.externalFunctionPointersEqualFunction() +\n\t\t\t\t\"(\" +\n\t\t\t\tIRVariable{_binOp.leftExpression()}.part(\"address\").name() + \",\" +\n\t\t\t\tIRVariable{_binOp.leftExpression()}.part(\"functionSelector\").name() + \",\" +\n\t\t\t\tIRVariable{_binOp.rightExpression()}.part(\"address\").name() + \",\" +\n\t\t\t\tIRVariable{_binOp.rightExpression()}.part(\"functionSelector\").name() +\n\t\t\t\t\")\";\n\t\t\tif (op == Token::NotEqual)\n\t\t\t\texpr = \"iszero(\" + expr + \")\";\n\t\t}\n\t\telse if (op == Token::Equal)\n\t\t\texpr = \"eq(\" + std::move(args) + \")\";\n\t\telse if (op == Token::NotEqual)\n\t\t\texpr = \"iszero(eq(\" + std::move(args) + \"))\";\n\t\telse if (op == Token::GreaterThanOrEqual)\n\t\t\texpr = \"iszero(\" + std::string(isSigned ? \"slt(\" : \"lt(\") + std::move(args) + \"))\";\n\t\telse if (op == Token::LessThanOrEqual)\n\t\t\texpr = \"iszero(\" + std::string(isSigned ? \"sgt(\" : \"gt(\") + std::move(args) + \"))\";\n\t\telse if (op == Token::GreaterThan)\n\t\t\texpr = (isSigned ? \"sgt(\" : \"gt(\") + std::move(args) + \")\";\n\t\telse if (op == Token::LessThan)\n\t\t\texpr = (isSigned ? \"slt(\" : \"lt(\") + std::move(args) + \")\";\n\t\telse\n\t\t\tsolAssert(false, \"Unknown comparison operator.\");\n\t\tdefine(_binOp) << expr << \"\\n\";\n\t}\n\telse if (op == Token::Exp)\n\t{\n\t\tIRVariable left = convert(_binOp.leftExpression(), *commonType);\n\t\tIRVariable right = convert(_binOp.rightExpression(), *type(_binOp.rightExpression()).mobileType());\n\n\t\tif (m_context.arithmetic() == Arithmetic::Wrapping)\n\t\t\tdefine(_binOp) << m_utils.wrappingIntExpFunction(\n\t\t\t\tdynamic_cast<IntegerType const&>(left.type()),\n\t\t\t\tdynamic_cast<IntegerType const&>(right.type())\n\t\t\t) << \"(\" << left.name() << \", \" << right.name() << \")\\n\";\n\t\telse if (auto rationalNumberType = dynamic_cast<RationalNumberType const*>(_binOp.leftExpression().annotation().type))\n\t\t{\n\t\t\tsolAssert(rationalNumberType->integerType(), \"Invalid literal as the base for exponentiation.\");\n\t\t\tsolAssert(dynamic_cast<IntegerType const*>(commonType));\n\n\t\t\tdefine(_binOp) << m_utils.overflowCheckedIntLiteralExpFunction(\n\t\t\t\t*rationalNumberType,\n\t\t\t\tdynamic_cast<IntegerType const&>(right.type()),\n\t\t\t\tdynamic_cast<IntegerType const&>(*commonType)\n\t\t\t) << \"(\" << right.name() << \")\\n\";\n\t\t}\n\t\telse\n\t\t\tdefine(_binOp) << m_utils.overflowCheckedIntExpFunction(\n\t\t\t\tdynamic_cast<IntegerType const&>(left.type()),\n\t\t\t\tdynamic_cast<IntegerType const&>(right.type())\n\t\t\t) << \"(\" << left.name() << \", \" << right.name() << \")\\n\";\n\t}\n\telse if (TokenTraits::isShiftOp(op))\n\t{\n\t\tIRVariable left = convert(_binOp.leftExpression(), *commonType);\n\t\tIRVariable right = convert(_binOp.rightExpression(), *type(_binOp.rightExpression()).mobileType());\n\t\tdefine(_binOp) << shiftOperation(_binOp.getOperator(), left, right) << \"\\n\";\n\t}\n\telse\n\t{\n\t\tstd::string left = expressionAsType(_binOp.leftExpression(), *commonType);\n\t\tstd::string right = expressionAsType(_binOp.rightExpression(), *commonType);\n\t\tdefine(_binOp) << binaryOperation(_binOp.getOperator(), *commonType, left, right) << \"\\n\";\n\t}\n\treturn false;\n}\n\nvoid IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)\n{\n\tsetLocation(_functionCall);\n\tauto functionCallKind = *_functionCall.annotation().kind;\n\n\tif (functionCallKind == FunctionCallKind::TypeConversion)\n\t{\n\t\tsolAssert(\n\t\t\t_functionCall.expression().annotation().type->category() == Type::Category::TypeType,\n\t\t\t\"Expected category to be TypeType\"\n\t\t);\n\t\tsolAssert(_functionCall.arguments().size() == 1, \"Expected one argument for type conversion\");\n\t\tdefine(_functionCall, *_functionCall.arguments().front());\n\t\treturn;\n\t}\n\n\tFunctionTypePointer functionType = nullptr;\n\tif (functionCallKind == FunctionCallKind::StructConstructorCall)\n\t{\n\t\tauto const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type);\n\t\tauto const& structType = dynamic_cast<StructType const&>(*type.actualType());\n\t\tfunctionType = structType.constructorType();\n\t}\n\telse\n\t\tfunctionType = dynamic_cast<FunctionType const*>(_functionCall.expression().annotation().type);\n\n\tTypePointers parameterTypes = functionType->parameterTypes();\n\n\tstd::vector<ASTPointer<Expression const>> const& arguments = _functionCall.sortedArguments();\n\n\tif (functionCallKind == FunctionCallKind::StructConstructorCall)\n\t{\n\t\tTypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type);\n\t\tauto const& structType = dynamic_cast<StructType const&>(*type.actualType());\n\n\t\tdefine(_functionCall) << m_utils.allocateMemoryStructFunction(structType) << \"()\\n\";\n\n\t\tMemberList::MemberMap members = structType.nativeMembers(nullptr);\n\n\t\tsolAssert(members.size() == arguments.size(), \"Struct parameter mismatch.\");\n\n\t\tfor (size_t i = 0; i < arguments.size(); i++)\n\t\t{\n\t\t\tIRVariable converted = convert(*arguments[i], *parameterTypes[i]);\n\t\t\tappendCode() <<\n\t\t\t\tm_utils.writeToMemoryFunction(*functionType->parameterTypes()[i]) <<\n\t\t\t\t\"(add(\" <<\n\t\t\t\tIRVariable(_functionCall).part(\"mpos\").name() <<\n\t\t\t\t\", \" <<\n\t\t\t\tstructType.memoryOffsetOfMember(members[i].name) <<\n\t\t\t\t\"), \" <<\n\t\t\t\tconverted.commaSeparatedList() <<\n\t\t\t\t\")\\n\";\n\t\t}\n\n\t\treturn;\n\t}\n\n\tswitch (functionType->kind())\n\t{\n\tcase FunctionType::Kind::Declaration:\n\t\tsolAssert(false, \"Attempted to generate code for calling a function definition.\");\n\t\tbreak;\n\tcase FunctionType::Kind::Internal:\n\t{\n\t\tFunctionDefinition const* functionDef = ASTNode::resolveFunctionCall(_functionCall, &m_context.mostDerivedContract());\n\n\t\tsolAssert(!functionType->takesArbitraryParameters());\n\n\t\tstd::vector<std::string> args;\n\t\tif (functionType->hasBoundFirstArgument())\n\t\t\targs += IRVariable(_functionCall.expression()).part(\"self\").stackSlots();\n\n\t\tfor (size_t i = 0; i < arguments.size(); ++i)\n\t\t\targs += convert(*arguments[i], *parameterTypes[i]).stackSlots();\n\n\t\tif (functionDef)\n\t\t{\n\t\t\tsolAssert(functionDef->isImplemented());\n\n\t\t\tdefine(_functionCall) <<\n\t\t\t\tm_context.enqueueFunctionForCodeGeneration(*functionDef) <<\n\t\t\t\t\"(\" <<\n\t\t\t\tjoinHumanReadable(args) <<\n\t\t\t\t\")\\n\";\n\t\t}\n\t\telse\n\t\t{\n\t\t\tYulArity arity = YulArity::fromType(*functionType);\n\t\t\tm_context.internalFunctionCalledThroughDispatch(arity);\n\n\t\t\tdefine(_functionCall) <<\n\t\t\t\tIRNames::internalDispatch(arity) <<\n\t\t\t\t\"(\" <<\n\t\t\t\tIRVariable(_functionCall.expression()).part(\"functionIdentifier\").name() <<\n\t\t\t\tjoinHumanReadablePrefixed(args) <<\n\t\t\t\t\")\\n\";\n\t\t}\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::External:\n\tcase FunctionType::Kind::DelegateCall:\n\t\tappendExternalFunctionCall(_functionCall, arguments);\n\t\tbreak;\n\tcase FunctionType::Kind::BareCall:\n\tcase FunctionType::Kind::BareDelegateCall:\n\tcase FunctionType::Kind::BareStaticCall:\n\t\tappendBareCall(_functionCall, arguments);\n\t\tbreak;\n\tcase FunctionType::Kind::BareCallCode:\n\t\tsolAssert(false, \"Callcode has been removed.\");\n\tcase FunctionType::Kind::Event:\n\t{\n\t\tauto const& event = dynamic_cast<EventDefinition const&>(functionType->declaration());\n\t\tTypePointers paramTypes = functionType->parameterTypes();\n\t\tABIFunctions abi(m_context.evmVersion(), m_context.eofVersion(), m_context.revertStrings(), m_context.functionCollector());\n\n\t\tstd::vector<IRVariable> indexedArgs;\n\t\tstd::vector<std::string> nonIndexedArgs;\n\t\tTypePointers nonIndexedArgTypes;\n\t\tTypePointers nonIndexedParamTypes;\n\t\tif (!event.isAnonymous())\n\t\t\tdefine(indexedArgs.emplace_back(m_context.newYulVariable(), *TypeProvider::uint256())) <<\n\t\t\t\tformatNumber(u256(h256::Arith(keccak256(functionType->externalSignature())))) << \"\\n\";\n\t\tfor (size_t i = 0; i < event.parameters().size(); ++i)\n\t\t{\n\t\t\tExpression const& arg = *arguments[i];\n\t\t\tif (event.parameters()[i]->isIndexed())\n\t\t\t{\n\t\t\t\tstd::string value;\n\t\t\t\tif (auto const& referenceType = dynamic_cast<ReferenceType const*>(paramTypes[i]))\n\t\t\t\t\tdefine(indexedArgs.emplace_back(m_context.newYulVariable(), *TypeProvider::uint256())) <<\n\t\t\t\t\t\tm_utils.packedHashFunction({arg.annotation().type}, {referenceType}) <<\n\t\t\t\t\t\t\"(\" <<\n\t\t\t\t\t\tIRVariable(arg).commaSeparatedList() <<\n\t\t\t\t\t\t\")\\n\";\n\t\t\t\telse if (auto functionType = dynamic_cast<FunctionType const*>(paramTypes[i]))\n\t\t\t\t{\n\t\t\t\t\tsolAssert(\n\t\t\t\t\t\tIRVariable(arg).type() == *functionType &&\n\t\t\t\t\t\tfunctionType->kind() == FunctionType::Kind::External &&\n\t\t\t\t\t\t!functionType->hasBoundFirstArgument(),\n\t\t\t\t\t\t\"\"\n\t\t\t\t\t);\n\t\t\t\t\tdefine(indexedArgs.emplace_back(m_context.newYulVariable(), *TypeProvider::fixedBytes(32))) <<\n\t\t\t\t\t\tm_utils.combineExternalFunctionIdFunction() <<\n\t\t\t\t\t\t\"(\" <<\n\t\t\t\t\t\tIRVariable(arg).commaSeparatedList() <<\n\t\t\t\t\t\t\")\\n\";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsolAssert(parameterTypes[i]->sizeOnStack() == 1, \"\");\n\t\t\t\t\tindexedArgs.emplace_back(convertAndCleanup(arg, *parameterTypes[i]));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnonIndexedArgs += IRVariable(arg).stackSlots();\n\t\t\t\tnonIndexedArgTypes.push_back(arg.annotation().type);\n\t\t\t\tnonIndexedParamTypes.push_back(paramTypes[i]);\n\t\t\t}\n\t\t}\n\t\tsolAssert(indexedArgs.size() <= 4, \"Too many indexed arguments.\");\n\t\tWhiskers templ(R\"({\n\t\t\tlet <pos> := <allocateUnbounded>()\n\t\t\tlet <end> := <encode>(<pos> <nonIndexedArgs>)\n\t\t\t<log>(<pos>, sub(<end>, <pos>) <indexedArgs>)\n\t\t})\");\n\t\ttempl(\"pos\", m_context.newYulVariable());\n\t\ttempl(\"end\", m_context.newYulVariable());\n\t\ttempl(\"allocateUnbounded\", m_utils.allocateUnboundedFunction());\n\t\ttempl(\"encode\", abi.tupleEncoder(nonIndexedArgTypes, nonIndexedParamTypes));\n\t\ttempl(\"nonIndexedArgs\", joinHumanReadablePrefixed(nonIndexedArgs));\n\t\ttempl(\"log\", \"log\" + std::to_string(indexedArgs.size()));\n\t\ttempl(\"indexedArgs\", joinHumanReadablePrefixed(indexedArgs | ranges::views::transform([&](auto const& _arg) {\n\t\t\treturn _arg.commaSeparatedList();\n\t\t})));\n\t\tappendCode() << templ.render();\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::Wrap:\n\tcase FunctionType::Kind::Unwrap:\n\t{\n\t\tsolAssert(arguments.size() == 1);\n\t\tFunctionType::Kind kind = functionType->kind();\n\t\tif (kind == FunctionType::Kind::Wrap)\n\t\t\tsolAssert(\n\t\t\t\ttype(*arguments.at(0)).isImplicitlyConvertibleTo(\n\t\t\t\t\tdynamic_cast<UserDefinedValueType const&>(type(_functionCall)).underlyingType()\n\t\t\t\t),\n\t\t\t\t\"\"\n\t\t\t);\n\t\telse\n\t\t\tsolAssert(type(*arguments.at(0)).category() == Type::Category::UserDefinedValueType);\n\n\t\tdefine(_functionCall, *arguments.at(0));\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::Assert:\n\tcase FunctionType::Kind::Require:\n\t{\n\t\tsolAssert(arguments.size() > 0, \"Expected at least one parameter for require/assert\");\n\t\tsolAssert(arguments.size() <= 2, \"Expected no more than two parameters for require/assert\");\n\n\t\tType const* messageArgumentType =\n\t\t\targuments.size() > 1 && m_context.revertStrings() != RevertStrings::Strip ?\n\t\t\targuments[1]->annotation().type :\n\t\t\tnullptr;\n\n\t\tauto const* magicType = dynamic_cast<MagicType const*>(messageArgumentType);\n\t\tif (magicType && magicType->kind() == MagicType::Kind::Error)\n\t\t{\n\t\t\tauto const& errorConstructorCall = dynamic_cast<FunctionCall const&>(*arguments[1]);\n\t\t\tappendCode() << m_utils.requireWithErrorFunction(errorConstructorCall) << \"(\" <<IRVariable(*arguments[0]).name();\n\t\t\tfor (auto argument: errorConstructorCall.arguments())\n\t\t\t\tif (argument->annotation().type->sizeOnStack() > 0)\n\t\t\t\t\tappendCode() << \", \" << IRVariable(*argument).commaSeparatedList();\n\t\t\tappendCode() << \")\\n\";\n\t\t}\n\t\telse\n\t\t{\n\t\t\tASTPointer<Expression const> stringArgumentExpression = messageArgumentType ? arguments[1] : nullptr;\n\t\t\tstd::string requireOrAssertFunction = m_utils.requireOrAssertFunction(\n\t\t\t\tfunctionType->kind() == FunctionType::Kind::Assert,\n\t\t\t\tmessageArgumentType,\n\t\t\t\tstringArgumentExpression\n\t\t\t);\n\t\t\tappendCode() << std::move(requireOrAssertFunction) << \"(\" << IRVariable(*arguments[0]).name();\n\t\t\tif (messageArgumentType && messageArgumentType->sizeOnStack() > 0)\n\t\t\t\tappendCode() << \", \" << IRVariable(*arguments[1]).commaSeparatedList();\n\t\t\tappendCode() << \")\\n\";\n\t\t}\n\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::ABIEncode:\n\tcase FunctionType::Kind::ABIEncodePacked:\n\tcase FunctionType::Kind::ABIEncodeWithSelector:\n\tcase FunctionType::Kind::ABIEncodeCall:\n\tcase FunctionType::Kind::ABIEncodeWithSignature:\n\t{\n\t\tbool const isPacked = functionType->kind() == FunctionType::Kind::ABIEncodePacked;\n\t\tsolAssert(functionType->padArguments() != isPacked);\n\t\tbool const hasSelectorOrSignature =\n\t\t\tfunctionType->kind() == FunctionType::Kind::ABIEncodeWithSelector ||\n\t\t\tfunctionType->kind() == FunctionType::Kind::ABIEncodeCall ||\n\t\t\tfunctionType->kind() == FunctionType::Kind::ABIEncodeWithSignature;\n\n\t\tTypePointers argumentTypes;\n\t\tTypePointers targetTypes;\n\t\tstd::vector<std::string> argumentVars;\n\t\tstd::string selector;\n\t\tstd::vector<ASTPointer<Expression const>> argumentsOfEncodeFunction;\n\n\t\tif (functionType->kind() == FunctionType::Kind::ABIEncodeCall)\n\t\t{\n\t\t\tsolAssert(arguments.size() == 2);\n\t\t\t// Account for tuples with one component which become that component\n\t\t\tif (type(*arguments[1]).category() == Type::Category::Tuple)\n\t\t\t{\n\t\t\t\tauto const& tupleExpression = dynamic_cast<TupleExpression const&>(*arguments[1]);\n\t\t\t\tfor (auto component: tupleExpression.components())\n\t\t\t\t\targumentsOfEncodeFunction.push_back(component);\n\t\t\t}\n\t\t\telse\n\t\t\t\targumentsOfEncodeFunction.push_back(arguments[1]);\n\t\t}\n\t\telse\n\t\t\tfor (size_t i = 0; i < arguments.size(); ++i)\n\t\t\t{\n\t\t\t\t// ignore selector\n\t\t\t\tif (hasSelectorOrSignature && i == 0)\n\t\t\t\t\tcontinue;\n\t\t\t\targumentsOfEncodeFunction.push_back(arguments[i]);\n\t\t\t}\n\n\t\tfor (auto const& argument: argumentsOfEncodeFunction)\n\t\t{\n\t\t\targumentTypes.emplace_back(&type(*argument));\n\t\t\targumentVars += IRVariable(*argument).stackSlots();\n\t\t}\n\n\t\tif (functionType->kind() == FunctionType::Kind::ABIEncodeCall)\n\t\t{\n\t\t\tauto encodedFunctionType = dynamic_cast<FunctionType const*>(arguments.front()->annotation().type);\n\t\t\tsolAssert(encodedFunctionType);\n\t\t\tencodedFunctionType = encodedFunctionType->asExternallyCallableFunction(false);\n\t\t\tsolAssert(encodedFunctionType);\n\t\t\ttargetTypes = encodedFunctionType->parameterTypes();\n\t\t}\n\t\telse\n\t\t\tfor (auto const& argument: argumentsOfEncodeFunction)\n\t\t\t\ttargetTypes.emplace_back(type(*argument).fullEncodingType(false, true, isPacked));\n\n\n\t\tif (functionType->kind() == FunctionType::Kind::ABIEncodeCall)\n\t\t{\n\t\t\tauto const& selectorType = dynamic_cast<FunctionType const&>(type(*arguments.front()));\n\t\t\tif (selectorType.kind() == FunctionType::Kind::Declaration)\n\t\t\t{\n\t\t\t\tsolAssert(selectorType.hasDeclaration());\n\t\t\t\tselector = formatNumber(selectorType.externalIdentifier() << (256 - 32));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tselector = convert(\n\t\t\t\t\tIRVariable(*arguments[0]).part(\"functionSelector\"),\n\t\t\t\t\t*TypeProvider::fixedBytes(4)\n\t\t\t\t).name();\n\t\t\t}\n\t\t}\n\t\telse if (functionType->kind() == FunctionType::Kind::ABIEncodeWithSignature)\n\t\t{\n\t\t\t// hash the signature\n\t\t\tType const& selectorType = type(*arguments.front());\n\t\t\tif (auto const* stringType = dynamic_cast<StringLiteralType const*>(&selectorType))\n\t\t\t\tselector = formatNumber(util::selectorFromSignatureU256(stringType->value()));\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Used to reset the free memory pointer later.\n\t\t\t\t// TODO This is an abuse of the `allocateUnbounded` function.\n\t\t\t\t// We might want to introduce a new set of memory handling functions here\n\t\t\t\t// a la \"setMemoryCheckPoint\" and \"freeUntilCheckPoint\".\n\t\t\t\tstd::string freeMemoryPre = m_context.newYulVariable();\n\t\t\t\tappendCode() << \"let \" << freeMemoryPre << \" := \" << m_utils.allocateUnboundedFunction() << \"()\\n\";\n\t\t\t\tIRVariable array = convert(*arguments[0], *TypeProvider::bytesMemory());\n\t\t\t\tIRVariable hashVariable(m_context.newYulVariable(), *TypeProvider::fixedBytes(32));\n\n\t\t\t\tstd::string dataAreaFunction = m_utils.arrayDataAreaFunction(*TypeProvider::bytesMemory());\n\t\t\t\tstd::string arrayLengthFunction = m_utils.arrayLengthFunction(*TypeProvider::bytesMemory());\n\t\t\t\tdefine(hashVariable) <<\n\t\t\t\t\t\"keccak256(\" <<\n\t\t\t\t\t(dataAreaFunction + \"(\" + array.commaSeparatedList() + \")\") <<\n\t\t\t\t\t\", \" <<\n\t\t\t\t\t(arrayLengthFunction + \"(\" + array.commaSeparatedList() +\")\") <<\n\t\t\t\t\t\")\\n\";\n\t\t\t\tIRVariable selectorVariable(m_context.newYulVariable(), *TypeProvider::fixedBytes(4));\n\t\t\t\tdefine(selectorVariable, hashVariable);\n\t\t\t\tselector = selectorVariable.name();\n\t\t\t\tappendCode() << m_utils.finalizeAllocationFunction() << \"(\" << freeMemoryPre << \", 0)\\n\";\n\t\t\t}\n\t\t}\n\t\telse if (functionType->kind() == FunctionType::Kind::ABIEncodeWithSelector)\n\t\t\tselector = convert(*arguments.front(), *TypeProvider::fixedBytes(4)).name();\n\n\t\tWhiskers templ(R\"(\n\t\t\tlet <data> := <allocateUnbounded>()\n\t\t\tlet <memPtr> := add(<data>, 0x20)\n\t\t\t<?+selector>\n\t\t\t\tmstore(<memPtr>, <selector>)\n\t\t\t\t<memPtr> := add(<memPtr>, 4)\n\t\t\t</+selector>\n\t\t\tlet <mend> := <encode>(<memPtr><arguments>)\n\t\t\tmstore(<data>, sub(<mend>, add(<data>, 0x20)))\n\t\t\t<finalizeAllocation>(<data>, sub(<mend>, <data>))\n\t\t)\");\n\t\ttempl(\"data\", IRVariable(_functionCall).part(\"mpos\").name());\n\t\ttempl(\"allocateUnbounded\", m_utils.allocateUnboundedFunction());\n\t\ttempl(\"memPtr\", m_context.newYulVariable());\n\t\ttempl(\"mend\", m_context.newYulVariable());\n\t\ttempl(\"selector\", selector);\n\t\ttempl(\"encode\",\n\t\t\tisPacked ?\n\t\t\tm_context.abiFunctions().tupleEncoderPacked(argumentTypes, targetTypes) :\n\t\t\tm_context.abiFunctions().tupleEncoder(argumentTypes, targetTypes, false)\n\t\t);\n\t\ttempl(\"arguments\", joinHumanReadablePrefixed(argumentVars));\n\t\ttempl(\"finalizeAllocation\", m_utils.finalizeAllocationFunction());\n\n\t\tappendCode() << templ.render();\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::ABIDecode:\n\t{\n\t\tWhiskers templ(R\"(\n\t\t\t<?+retVars>let <retVars> := </+retVars> <abiDecode>(<offset>, add(<offset>, <length>))\n\t\t)\");\n\n\t\tType const* firstArgType = arguments.front()->annotation().type;\n\t\tTypePointers targetTypes;\n\n\t\tif (TupleType const* targetTupleType = dynamic_cast<TupleType const*>(_functionCall.annotation().type))\n\t\t\ttargetTypes = targetTupleType->components();\n\t\telse\n\t\t\ttargetTypes = TypePointers{_functionCall.annotation().type};\n\n\t\tif (\n\t\t\tauto referenceType = dynamic_cast<ReferenceType const*>(firstArgType);\n\t\t\treferenceType && referenceType->dataStoredIn(DataLocation::CallData)\n\t\t\t)\n\t\t{\n\t\t\tsolAssert(referenceType->isImplicitlyConvertibleTo(*TypeProvider::bytesCalldata()));\n\t\t\tIRVariable var = convert(*arguments[0], *TypeProvider::bytesCalldata());\n\t\t\ttempl(\"abiDecode\", m_context.abiFunctions().tupleDecoder(targetTypes, false));\n\t\t\ttempl(\"offset\", var.part(\"offset\").name());\n\t\t\ttempl(\"length\", var.part(\"length\").name());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tIRVariable var = convert(*arguments[0], *TypeProvider::bytesMemory());\n\t\t\ttempl(\"abiDecode\", m_context.abiFunctions().tupleDecoder(targetTypes, true));\n\t\t\ttempl(\"offset\", \"add(\" + var.part(\"mpos\").name() + \", 32)\");\n\t\t\ttempl(\"length\",\n\t\t\t\tm_utils.arrayLengthFunction(*TypeProvider::bytesMemory()) + \"(\" + var.part(\"mpos\").name() + \")\"\n\t\t\t);\n\t\t}\n\t\ttempl(\"retVars\", IRVariable(_functionCall).commaSeparatedList());\n\n\t\tappendCode() << templ.render();\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::Revert:\n\t{\n\t\tsolAssert(arguments.size() == parameterTypes.size());\n\t\tsolAssert(arguments.size() <= 1);\n\t\tsolAssert(\n\t\t\targuments.empty() ||\n\t\t\targuments.front()->annotation().type->isImplicitlyConvertibleTo(*TypeProvider::stringMemory()),\n\t\t\"\");\n\t\tif (m_context.revertStrings() == RevertStrings::Strip || arguments.empty())\n\t\t\tappendCode() << \"revert(0, 0)\\n\";\n\t\telse\n\t\t\trevertWithError(\n\t\t\t\t\"Error(string)\",\n\t\t\t\t{TypeProvider::stringMemory()},\n\t\t\t\t{arguments.front()}\n\t\t\t);\n\t\tbreak;\n\t}\n\t// Array creation using new\n\tcase FunctionType::Kind::ObjectCreation:\n\t{\n\t\tArrayType const& arrayType = dynamic_cast<ArrayType const&>(*_functionCall.annotation().type);\n\t\tsolAssert(arguments.size() == 1);\n\n\t\tIRVariable value = convert(*arguments[0], *TypeProvider::uint256());\n\t\tdefine(_functionCall) <<\n\t\t\tm_utils.allocateAndInitializeMemoryArrayFunction(arrayType) <<\n\t\t\t\"(\" <<\n\t\t\tvalue.commaSeparatedList() <<\n\t\t\t\")\\n\";\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::KECCAK256:\n\t{\n\t\tsolAssert(arguments.size() == 1);\n\n\t\tArrayType const* arrayType = TypeProvider::bytesMemory();\n\n\t\tif (auto const* stringLiteral = dynamic_cast<StringLiteralType const*>(arguments.front()->annotation().type))\n\t\t{\n\t\t\t// Optimization: Compute keccak256 on string literals at compile-time.\n\t\t\tdefine(_functionCall) <<\n\t\t\t\t(\"0x\" + keccak256(stringLiteral->value()).hex()) <<\n\t\t\t\t\"\\n\";\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto array = convert(*arguments[0], *arrayType);\n\n\t\t\tstd::string dataAreaFunction = m_utils.arrayDataAreaFunction(*arrayType);\n\t\t\tstd::string arrayLengthFunction = m_utils.arrayLengthFunction(*arrayType);\n\t\t\tdefine(_functionCall) <<\n\t\t\t\t\"keccak256(\" <<\n\t\t\t\t(dataAreaFunction + \"(\" + array.commaSeparatedList() + \")\") <<\n\t\t\t\t\", \" <<\n\t\t\t\t(arrayLengthFunction + \"(\" + array.commaSeparatedList() +\")\") <<\n\t\t\t\t\")\\n\";\n\t\t}\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::ERC7201:\n\t{\n\t\tsolAssert(arguments.size() == 1);\n\t\tType const* argType = arguments.front()->annotation().type;\n\t\tsolAssert(argType);\n\t\tif (dynamic_cast<StringLiteralType const*>(argType))\n\t\t{\n\t\t\tstd::optional<u256> slot = erc7201CompileTimeValue(_functionCall);\n\t\t\tsolAssert(slot.has_value());\n\t\t\tdefine(_functionCall) << formatNumber(*slot) << \"\\n\";\n\t\t}\n\t\telse\n\t\t{\n\t\t\tWhiskers templ(R\"(\n\t\t\t\t<erc7201Builtin>(<arrayDataArea>(<namespaceID>), <arrayLength>(<namespaceID>))\n\t\t\t)\");\n\n\t\t\tIRVariable stringArg = convert(*arguments[0], *TypeProvider::stringMemory());\n\t\t\tsolAssert(stringArg.stackSlots().size() == 1);\n\t\t\tstd::string namespaceID = stringArg.stackSlots().front();\n\n\t\t\ttempl(\"arrayDataArea\", m_utils.arrayDataAreaFunction(*TypeProvider::stringMemory()));\n\t\t\ttempl(\"arrayLength\", m_utils.arrayLengthFunction(*TypeProvider::stringMemory()));\n\t\t\ttempl(\"namespaceID\", namespaceID);\n\t\t\ttempl(\"erc7201Builtin\", m_utils.erc7201());\n\n\t\t\tdefine(_functionCall) << templ.render();\n\t\t}\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::ArrayPop:\n\t{\n\t\tsolAssert(functionType->hasBoundFirstArgument());\n\t\tsolAssert(functionType->parameterTypes().empty());\n\t\tArrayType const* arrayType = dynamic_cast<ArrayType const*>(functionType->selfType());\n\t\tsolAssert(arrayType);\n\t\tdefine(_functionCall) <<\n\t\t\tm_utils.storageArrayPopFunction(*arrayType) <<\n\t\t\t\"(\" <<\n\t\t\tIRVariable(_functionCall.expression()).commaSeparatedList() <<\n\t\t\t\")\\n\";\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::ArrayPush:\n\t{\n\t\tArrayType const* arrayType = dynamic_cast<ArrayType const*>(functionType->selfType());\n\t\tsolAssert(arrayType);\n\n\t\tif (arguments.empty())\n\t\t{\n\t\t\tauto slotName = m_context.newYulVariable();\n\t\t\tauto offsetName = m_context.newYulVariable();\n\t\t\tappendCode() << \"let \" << slotName << \", \" << offsetName << \" := \" <<\n\t\t\t\tm_utils.storageArrayPushZeroFunction(*arrayType) <<\n\t\t\t\t\"(\" << IRVariable(_functionCall.expression()).commaSeparatedList() << \")\\n\";\n\t\t\tsetLValue(_functionCall, IRLValue{\n\t\t\t\t*arrayType->baseType(),\n\t\t\t\tIRLValue::Storage{\n\t\t\t\t\tslotName,\n\t\t\t\t\toffsetName,\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\telse\n\t\t{\n\t\t\tIRVariable argument =\n\t\t\t\tarrayType->baseType()->isValueType() ?\n\t\t\t\tconvert(*arguments.front(), *arrayType->baseType()) :\n\t\t\t\t*arguments.front();\n\n\t\t\tappendCode() <<\n\t\t\t\tm_utils.storageArrayPushFunction(*arrayType, &argument.type()) <<\n\t\t\t\t\"(\" <<\n\t\t\t\tIRVariable(_functionCall.expression()).commaSeparatedList() <<\n\t\t\t\t(argument.stackSlots().empty() ? \"\" : (\", \" + argument.commaSeparatedList()))  <<\n\t\t\t\t\")\\n\";\n\t\t}\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::StringConcat:\n\tcase FunctionType::Kind::BytesConcat:\n\t{\n\t\tTypePointers argumentTypes;\n\t\tstd::vector<std::string> argumentVars;\n\t\tfor (ASTPointer<Expression const> const& argument: arguments)\n\t\t{\n\t\t\targumentTypes.emplace_back(&type(*argument));\n\t\t\targumentVars += IRVariable(*argument).stackSlots();\n\t\t}\n\t\tdefine(IRVariable(_functionCall)) <<\n\t\t\tm_utils.bytesOrStringConcatFunction(argumentTypes, functionType->kind()) <<\n\t\t\t\"(\" <<\n\t\t\tjoinHumanReadable(argumentVars) <<\n\t\t\t\")\\n\";\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::Error:\n\tcase FunctionType::Kind::MetaType:\n\t{\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::AddMod:\n\tcase FunctionType::Kind::MulMod:\n\t{\n\t\tstatic std::map<FunctionType::Kind, std::string> functions = {\n\t\t\t{FunctionType::Kind::AddMod, \"addmod\"},\n\t\t\t{FunctionType::Kind::MulMod, \"mulmod\"},\n\t\t};\n\t\tsolAssert(functions.find(functionType->kind()) != functions.end());\n\t\tsolAssert(arguments.size() == 3 && parameterTypes.size() == 3);\n\n\t\tIRVariable modulus(m_context.newYulVariable(), *(parameterTypes[2]));\n\t\tdefine(modulus, *arguments[2]);\n\t\tWhiskers templ(\"if iszero(<modulus>) { <panic>() }\\n\");\n\t\ttempl(\"modulus\", modulus.name());\n\t\ttempl(\"panic\", m_utils.panicFunction(PanicCode::DivisionByZero));\n\t\tappendCode() << templ.render();\n\n\t\tstd::string args;\n\t\tfor (size_t i = 0; i < 2; ++i)\n\t\t\targs += expressionAsType(*arguments[i], *(parameterTypes[i])) + \", \";\n\t\targs += modulus.name();\n\t\tdefine(_functionCall) << functions[functionType->kind()] << \"(\" << args << \")\\n\";\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::GasLeft:\n\tcase FunctionType::Kind::Selfdestruct:\n\tcase FunctionType::Kind::BlockHash:\n\tcase FunctionType::Kind::BlobHash:\n\t{\n\t\tsolAssert(\n\t\t\t!m_context.eofVersion().has_value() || functionType->kind() != FunctionType::Kind::GasLeft,\n\t\t\t\"EOF does not support gasleft.\"\n\t\t);\n\t\tsolAssert(\n\t\t\t!m_context.eofVersion().has_value() || functionType->kind() != FunctionType::Kind::Selfdestruct,\n\t\t\t\"EOF does not support selfdestruct.\"\n\t\t);\n\n\t\tstatic std::map<FunctionType::Kind, std::string> functions = {\n\t\t\t{FunctionType::Kind::GasLeft, \"gas\"},\n\t\t\t{FunctionType::Kind::Selfdestruct, \"selfdestruct\"},\n\t\t\t{FunctionType::Kind::BlockHash, \"blockhash\"},\n\t\t\t{FunctionType::Kind::BlobHash, \"blobhash\"},\n\t\t};\n\t\tsolAssert(functions.find(functionType->kind()) != functions.end());\n\n\t\tstd::string args;\n\t\tfor (size_t i = 0; i < arguments.size(); ++i)\n\t\t\targs += (args.empty() ? \"\" : \", \") + expressionAsType(*arguments[i], *(parameterTypes[i]));\n\t\tdefine(_functionCall) << functions[functionType->kind()] << \"(\" << args << \")\\n\";\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::Creation:\n\t{\n\t\tsolAssert(!functionType->gasSet(), \"Gas limit set for contract creation.\");\n\t\tsolAssert(\n\t\t\tfunctionType->returnParameterTypes().size() == 1,\n\t\t\t\"Constructor should return only one type\"\n\t\t);\n\n\t\tTypePointers argumentTypes;\n\t\tstd::vector<std::string> constructorParams;\n\t\tfor (ASTPointer<Expression const> const& arg: arguments)\n\t\t{\n\t\t\targumentTypes.push_back(arg->annotation().type);\n\t\t\tconstructorParams += IRVariable{*arg}.stackSlots();\n\t\t}\n\n\t\tContractDefinition const* contract =\n\t\t\t&dynamic_cast<ContractType const&>(*functionType->returnParameterTypes().front()).contractDefinition();\n\t\tm_context.addSubObject(contract);\n\n\t\tWhiskers t(R\"(\n\t\t\t<?eof>\n\t\t\t\tlet <memPos> := <allocateUnbounded>()\n\t\t\t\tlet <memEnd> := <abiEncode>(<memPos><constructorParams>)\n\t\t\t\tlet <address> := eofcreate(\"<object>\", <value>, <salt>, <memPos>, sub(<memEnd>, <memPos>))\n\t\t\t<!eof>\n\t\t\t\tlet <memPos> := <allocateUnbounded>()\n\t\t\t\tlet <memEnd> := add(<memPos>, datasize(\"<object>\"))\n\t\t\t\tif or(gt(<memEnd>, 0xffffffffffffffff), lt(<memEnd>, <memPos>)) { <panic>() }\n\t\t\t\tdatacopy(<memPos>, dataoffset(\"<object>\"), datasize(\"<object>\"))\n\t\t\t\t<memEnd> := <abiEncode>(<memEnd><constructorParams>)\n\t\t\t\t<?saltSet>\n\t\t\t\t\tlet <address> := create2(<value>, <memPos>, sub(<memEnd>, <memPos>), <salt>)\n\t\t\t\t<!saltSet>\n\t\t\t\t\tlet <address> := create(<value>, <memPos>, sub(<memEnd>, <memPos>))\n\t\t\t\t</saltSet>\n\t\t\t</eof>\n\t\t\t<?isTryCall>\n\t\t\t\tlet <success> := iszero(iszero(<address>))\n\t\t\t<!isTryCall>\n\t\t\t\tif iszero(<address>) { <forwardingRevert>() }\n\t\t\t</isTryCall>\n\t\t)\");\n\t\tt(\"eof\", m_context.eofVersion().has_value());\n\t\tt(\"memPos\", m_context.newYulVariable());\n\t\tt(\"memEnd\", m_context.newYulVariable());\n\t\tt(\"allocateUnbounded\", m_utils.allocateUnboundedFunction());\n\t\tt(\"object\", IRNames::creationObject(*contract));\n\t\tt(\"panic\", m_utils.panicFunction(PanicCode::ResourceError));\n\t\tt(\"abiEncode\",\n\t\t\tm_context.abiFunctions().tupleEncoder(argumentTypes, functionType->parameterTypes(), false)\n\t\t);\n\t\tt(\"constructorParams\", joinHumanReadablePrefixed(constructorParams));\n\t\tt(\"value\", functionType->valueSet() ? IRVariable(_functionCall.expression()).part(\"value\").name() : \"0\");\n\t\tt(\"saltSet\", functionType->saltSet());\n\t\tif (functionType->saltSet())\n\t\t\tt(\"salt\", IRVariable(_functionCall.expression()).part(\"salt\").name());\n\t\telse if (m_context.eofVersion().has_value()) // Set salt to 0 if not defined.\n\t\t\tt(\"salt\", \"0\"); // TODO: We should reject non-salted creation during analysis and not set here\n\t\tsolAssert(IRVariable(_functionCall).stackSlots().size() == 1);\n\t\tt(\"address\", IRVariable(_functionCall).commaSeparatedList());\n\t\tt(\"isTryCall\", _functionCall.annotation().tryCall);\n\t\tif (_functionCall.annotation().tryCall)\n\t\t\tt(\"success\", IRNames::trySuccessConditionVariable(_functionCall));\n\t\telse\n\t\t\tt(\"forwardingRevert\", m_utils.forwardingRevertFunction());\n\t\tappendCode() << t.render();\n\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::Send:\n\tcase FunctionType::Kind::Transfer:\n\t{\n\t\tsolAssert(arguments.size() == 1 && parameterTypes.size() == 1);\n\t\tstd::string address{IRVariable(_functionCall.expression()).part(\"address\").name()};\n\t\tstd::string value{expressionAsType(*arguments[0], *(parameterTypes[0]))};\n\t\tWhiskers templ(R\"(\n\t\t\tlet <gas> := 0\n\t\t\tif iszero(<value>) { <gas> := <callStipend> }\n\t\t\t<?eof>\n\t\t\t\tlet <success> := iszero(extcall(<address>, 0, 0, <value>))\n\t\t\t<!eof>\n\t\t\t\tlet <success> := call(<gas>, <address>, <value>, 0, 0, 0, 0)\n\t\t\t</eof>\n\t\t\t<?isTransfer>\n\t\t\t\tif iszero(<success>) { <forwardingRevert>() }\n\t\t\t</isTransfer>\n\t\t)\");\n\t\ttempl(\"eof\", m_context.eofVersion().has_value());\n\t\ttempl(\"gas\", m_context.newYulVariable());\n\t\ttempl(\"callStipend\", toString(evmasm::GasCosts::callStipend));\n\t\ttempl(\"address\", address);\n\t\ttempl(\"value\", value);\n\t\tif (functionType->kind() == FunctionType::Kind::Transfer)\n\t\t\ttempl(\"success\", m_context.newYulVariable());\n\t\telse\n\t\t\ttempl(\"success\", IRVariable(_functionCall).commaSeparatedList());\n\t\ttempl(\"isTransfer\", functionType->kind() == FunctionType::Kind::Transfer);\n\t\ttempl(\"forwardingRevert\", m_utils.forwardingRevertFunction());\n\t\tappendCode() << templ.render();\n\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::ECRecover:\n\tcase FunctionType::Kind::RIPEMD160:\n\tcase FunctionType::Kind::SHA256:\n\t{\n\t\tsolAssert(!_functionCall.annotation().tryCall);\n\t\tsolAssert(!functionType->valueSet());\n\t\tsolAssert(!functionType->gasSet());\n\t\tsolAssert(!functionType->hasBoundFirstArgument());\n\n\t\tstatic std::map<FunctionType::Kind, std::tuple<unsigned, size_t>> precompiles = {\n\t\t\t{FunctionType::Kind::ECRecover, std::make_tuple(1, 0)},\n\t\t\t{FunctionType::Kind::SHA256, std::make_tuple(2, 0)},\n\t\t\t{FunctionType::Kind::RIPEMD160, std::make_tuple(3, 12)},\n\t\t};\n\t\tauto [ address, offset ] = precompiles[functionType->kind()];\n\t\tTypePointers argumentTypes;\n\t\tstd::vector<std::string> argumentStrings;\n\t\tfor (auto const& arg: arguments)\n\t\t{\n\t\t\targumentTypes.emplace_back(&type(*arg));\n\t\t\targumentStrings += IRVariable(*arg).stackSlots();\n\t\t}\n\t\tWhiskers templ(R\"(\n\t\t\tlet <pos> := <allocateUnbounded>()\n\t\t\tlet <end> := <encodeArgs>(<pos> <argumentString>)\n\t\t\t<?isECRecover>\n\t\t\t\tmstore(0, 0)\n\t\t\t</isECRecover>\n\t\t\t<?eof>\n\t\t\t\t// EOF always uses extstaticcall\n\t\t\t\tlet <success> := iszero(extstaticcall(<address>, <pos>, sub(<end>, <pos>)))\n\t\t\t<!eof>\n\t\t\t\tlet <success> := <call>(<gas>, <address> <?isCall>, 0</isCall>, <pos>, sub(<end>, <pos>), 0, 32)\n\t\t\t</eof>\n\t\t\tif iszero(<success>) { <forwardingRevert>() }\n\t\t\t<?eof>\n\t\t\t\tif eq(returndatasize(), 32) { returndatacopy(0, 0, 32) }\n\t\t\t</eof>\n\t\t\tlet <retVars> := <shl>(mload(0))\n\t\t)\");\n\t\tauto const eof = m_context.eofVersion().has_value();\n\t\tif (!eof)\n\t\t{\n\t\t\ttempl(\"call\", m_context.evmVersion().hasStaticCall() ? \"staticcall\" : \"call\");\n\t\t\ttempl(\"isCall\", !m_context.evmVersion().hasStaticCall());\n\t\t}\n\t\ttempl(\"shl\", m_utils.shiftLeftFunction(offset * 8));\n\t\ttempl(\"allocateUnbounded\", m_utils.allocateUnboundedFunction());\n\t\ttempl(\"pos\", m_context.newYulVariable());\n\t\ttempl(\"end\", m_context.newYulVariable());\n\t\ttempl(\"isECRecover\", FunctionType::Kind::ECRecover == functionType->kind());\n\t\ttempl(\"eof\", eof);\n\t\tif (FunctionType::Kind::ECRecover == functionType->kind())\n\t\t\ttempl(\"encodeArgs\", m_context.abiFunctions().tupleEncoder(argumentTypes, parameterTypes));\n\t\telse\n\t\t\ttempl(\"encodeArgs\", m_context.abiFunctions().tupleEncoderPacked(argumentTypes, parameterTypes));\n\t\ttempl(\"argumentString\", joinHumanReadablePrefixed(argumentStrings));\n\t\ttempl(\"address\", toString(address));\n\t\ttempl(\"success\", m_context.newYulVariable());\n\t\ttempl(\"retVars\", IRVariable(_functionCall).commaSeparatedList());\n\t\ttempl(\"forwardingRevert\", m_utils.forwardingRevertFunction());\n\t\tif (m_context.evmVersion().canOverchargeGasForCall())\n\t\t\t// Send all gas (requires tangerine whistle EVM)\n\t\t\ttempl(\"gas\", \"gas()\");\n\t\telse\n\t\t{\n\t\t\t// @todo The value 10 is not exact and this could be fine-tuned,\n\t\t\t// but this has worked for years in the old code generator.\n\t\t\tu256 gasNeededByCaller = evmasm::GasCosts::callGas(m_context.evmVersion()) + 10 + evmasm::GasCosts::callNewAccountGas;\n\t\t\ttempl(\"gas\", \"sub(gas(), \" + formatNumber(gasNeededByCaller) + \")\");\n\t\t}\n\n\t\tappendCode() << templ.render();\n\n\t\tbreak;\n\t}\n\tdefault:\n\t\tsolUnimplemented(\"FunctionKind \" + toString(static_cast<int>(functionType->kind())) + \" not yet implemented\");\n\t}\n}\n\nvoid IRGeneratorForStatements::endVisit(FunctionCallOptions const& _options)\n{\n\tsetLocation(_options);\n\tFunctionType const& previousType = dynamic_cast<FunctionType const&>(*_options.expression().annotation().type);\n\n\tsolUnimplementedAssert(!previousType.hasBoundFirstArgument());\n\n\t// Copy over existing values.\n\tfor (auto const& item: previousType.stackItems())\n\t\tdefine(IRVariable(_options).part(std::get<0>(item)), IRVariable(_options.expression()).part(std::get<0>(item)));\n\n\tfor (size_t i = 0; i < _options.names().size(); ++i)\n\t{\n\t\tstd::string const& name = *_options.names()[i];\n\t\tsolAssert(name == \"salt\" || name == \"gas\" || name == \"value\");\n\n\t\tdefine(IRVariable(_options).part(name), *_options.options()[i]);\n\t}\n}\n\nbool IRGeneratorForStatements::visit(MemberAccess const& _memberAccess)\n{\n\t// A shortcut for <address>.code.length. We skip visiting <address>.code and directly visit\n\t// <address>. The actual code is generated in endVisit.\n\tif (\n\t\tauto innerExpression = dynamic_cast<MemberAccess const*>(&_memberAccess.expression());\n\t\t_memberAccess.memberName() == \"length\" &&\n\t\tinnerExpression &&\n\t\tinnerExpression->memberName() == \"code\" &&\n\t\tinnerExpression->expression().annotation().type->category() == Type::Category::Address\n\t)\n\t{\n\t\tsolAssert(innerExpression->annotation().type->category() == Type::Category::Array);\n\t\t// Skip visiting <address>.code\n\t\tinnerExpression->expression().accept(*this);\n\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nvoid IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)\n{\n\tsetLocation(_memberAccess);\n\n\tASTString const& member = _memberAccess.memberName();\n\tauto memberFunctionType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type);\n\tType::Category objectCategory = _memberAccess.expression().annotation().type->category();\n\n\tif (memberFunctionType && memberFunctionType->hasBoundFirstArgument())\n\t{\n\t\tdefine(IRVariable(_memberAccess).part(\"self\"), _memberAccess.expression());\n\t\tsolAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Static);\n\t\tif (memberFunctionType->kind() == FunctionType::Kind::Internal)\n\t\t\tassignInternalFunctionIDIfNotCalledDirectly(\n\t\t\t\t_memberAccess,\n\t\t\t\tdynamic_cast<FunctionDefinition const&>(memberFunctionType->declaration())\n\t\t\t);\n\t\telse if (\n\t\t\tmemberFunctionType->kind() == FunctionType::Kind::ArrayPush ||\n\t\t\tmemberFunctionType->kind() == FunctionType::Kind::ArrayPop\n\t\t)\n\t\t{\n\t\t\t// Nothing to do.\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto const& functionDefinition = dynamic_cast<FunctionDefinition const&>(memberFunctionType->declaration());\n\t\t\tsolAssert(memberFunctionType->kind() == FunctionType::Kind::DelegateCall);\n\t\t\tauto contract = dynamic_cast<ContractDefinition const*>(functionDefinition.scope());\n\t\t\tsolAssert(contract && contract->isLibrary());\n\t\t\tdefine(IRVariable(_memberAccess).part(\"address\")) << linkerSymbol(*contract) << \"\\n\";\n\t\t\tdefine(IRVariable(_memberAccess).part(\"functionSelector\")) << memberFunctionType->externalIdentifier() << \"\\n\";\n\t\t}\n\t\treturn;\n\t}\n\n\tswitch (objectCategory)\n\t{\n\tcase Type::Category::Contract:\n\t{\n\t\tContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);\n\t\tif (type.isSuper())\n\t\t\tsolAssert(false);\n\n\t\t// ordinary contract type\n\t\telse if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)\n\t\t{\n\t\t\tu256 identifier;\n\t\t\tif (auto const* variable = dynamic_cast<VariableDeclaration const*>(declaration))\n\t\t\t\tidentifier = FunctionType(*variable).externalIdentifier();\n\t\t\telse if (auto const* function = dynamic_cast<FunctionDefinition const*>(declaration))\n\t\t\t\tidentifier = FunctionType(*function).externalIdentifier();\n\t\t\telse\n\t\t\t\tsolAssert(false, \"Contract member is neither variable nor function.\");\n\n\t\t\tdefine(IRVariable(_memberAccess).part(\"address\"), _memberAccess.expression());\n\t\t\tdefine(IRVariable(_memberAccess).part(\"functionSelector\")) << formatNumber(identifier) << \"\\n\";\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"Invalid member access in contract\");\n\t\tbreak;\n\t}\n\tcase Type::Category::Integer:\n\t{\n\t\tsolAssert(false, \"Invalid member access to integer\");\n\t\tbreak;\n\t}\n\tcase Type::Category::Address:\n\t{\n\t\tif (member == \"balance\")\n\t\t\tdefine(_memberAccess) <<\n\t\t\t\t\"balance(\" <<\n\t\t\t\texpressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<\n\t\t\t\t\")\\n\";\n\t\telse if (member == \"code\")\n\t\t{\n\t\t\tsolAssert(!m_context.eofVersion().has_value(), \"EOF does not support address.code.\");\n\t\t\tstd::string externalCodeFunction = m_utils.externalCodeFunction();\n\t\t\tdefine(_memberAccess) <<\n\t\t\t\texternalCodeFunction <<\n\t\t\t\t\"(\" <<\n\t\t\t\texpressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<\n\t\t\t\t\")\\n\";\n\t\t}\n\t\telse if (member == \"codehash\")\n\t\t{\n\t\t\tsolAssert(!m_context.eofVersion().has_value(), \"EOF does not support address.codehash.\");\n\t\t\tdefine(_memberAccess) <<\n\t\t\t\t\"extcodehash(\" <<\n\t\t\t\texpressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<\n\t\t\t\t\")\\n\";\n\t\t}\n\t\telse if (std::set<std::string>{\"send\", \"transfer\"}.count(member))\n\t\t{\n\t\t\tsolAssert(dynamic_cast<AddressType const&>(*_memberAccess.expression().annotation().type).stateMutability() == StateMutability::Payable);\n\t\t\tdefine(IRVariable{_memberAccess}.part(\"address\"), _memberAccess.expression());\n\t\t}\n\t\telse if (std::set<std::string>{\"call\", \"callcode\", \"delegatecall\", \"staticcall\"}.count(member))\n\t\t\tdefine(IRVariable{_memberAccess}.part(\"address\"), _memberAccess.expression());\n\t\telse\n\t\t\tsolAssert(false, \"Invalid member access to address\");\n\t\tbreak;\n\t}\n\tcase Type::Category::Function:\n\t\tif (member == \"selector\")\n\t\t{\n\t\t\tFunctionType const& functionType = dynamic_cast<FunctionType const&>(\n\t\t\t\t*_memberAccess.expression().annotation().type\n\t\t\t);\n\t\t\tif (\n\t\t\t\tfunctionType.kind() == FunctionType::Kind::External ||\n\t\t\t\tfunctionType.kind() == FunctionType::Kind::DelegateCall\n\t\t\t)\n\t\t\t\tdefine(IRVariable{_memberAccess}, IRVariable(_memberAccess.expression()).part(\"functionSelector\"));\n\t\t\telse if (\n\t\t\t\tfunctionType.kind() == FunctionType::Kind::Declaration ||\n\t\t\t\tfunctionType.kind() == FunctionType::Kind::Error ||\n\t\t\t\t// In some situations, internal function types also provide the \"selector\" member.\n\t\t\t\t// See Types.cpp for details.\n\t\t\t\tfunctionType.kind() == FunctionType::Kind::Internal\n\t\t\t)\n\t\t\t{\n\t\t\t\tsolAssert(functionType.hasDeclaration());\n\t\t\t\tsolAssert(\n\t\t\t\t\tfunctionType.kind() == FunctionType::Kind::Error ||\n\t\t\t\t\tfunctionType.declaration().isPartOfExternalInterface(),\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\t\t\t\tdefine(IRVariable{_memberAccess}) << formatNumber(\n\t\t\t\t\tutil::selectorFromSignatureU256(functionType.externalSignature())\n\t\t\t\t) << \"\\n\";\n\t\t\t}\n\t\t\telse if (functionType.kind() == FunctionType::Kind::Event)\n\t\t\t{\n\t\t\t\tsolAssert(functionType.hasDeclaration());\n\t\t\t\tsolAssert(functionType.kind() == FunctionType::Kind::Event);\n\t\t\t\tsolAssert(\n\t\t\t\t\t!(dynamic_cast<EventDefinition const&>(functionType.declaration()).isAnonymous())\n\t\t\t\t);\n\t\t\t\tdefine(IRVariable{_memberAccess}) << formatNumber(\n\t\t\t\t\tu256(h256::Arith(util::keccak256(functionType.externalSignature())))\n\t\t\t\t) << \"\\n\";\n\t\t\t}\n\t\t\telse\n\t\t\t\tsolAssert(false, \"Invalid use of .selector: \" + functionType.toString(false));\n\t\t}\n\t\telse if (member == \"address\")\n\t\t{\n\t\t\tsolUnimplementedAssert(\n\t\t\t\tdynamic_cast<FunctionType const&>(*_memberAccess.expression().annotation().type).kind() ==\n\t\t\t\tFunctionType::Kind::External\n\t\t\t);\n\t\t\tdefine(IRVariable{_memberAccess}, IRVariable(_memberAccess.expression()).part(\"address\"));\n\t\t}\n\t\telse\n\t\t\tsolAssert(\n\t\t\t\t!!_memberAccess.expression().annotation().type->memberType(member),\n\t\t\t\t\"Invalid member access to function.\"\n\t\t\t);\n\t\tbreak;\n\tcase Type::Category::Magic:\n\t\t// we can ignore the kind of magic and only look at the name of the member\n\t\tif (member == \"coinbase\")\n\t\t\tdefine(_memberAccess) << \"coinbase()\\n\";\n\t\telse if (member == \"timestamp\")\n\t\t\tdefine(_memberAccess) << \"timestamp()\\n\";\n\t\telse if (member == \"difficulty\" || member == \"prevrandao\")\n\t\t{\n\t\t\tif (m_context.evmVersion().hasPrevRandao())\n\t\t\t\tdefine(_memberAccess) << \"prevrandao()\\n\";\n\t\t\telse\n\t\t\t\tdefine(_memberAccess) << \"difficulty()\\n\";\n\t\t}\n\t\telse if (member == \"number\")\n\t\t\tdefine(_memberAccess) << \"number()\\n\";\n\t\telse if (member == \"gaslimit\")\n\t\t\tdefine(_memberAccess) << \"gaslimit()\\n\";\n\t\telse if (member == \"sender\")\n\t\t\tdefine(_memberAccess) << \"caller()\\n\";\n\t\telse if (member == \"value\")\n\t\t\tdefine(_memberAccess) << \"callvalue()\\n\";\n\t\telse if (member == \"origin\")\n\t\t\tdefine(_memberAccess) << \"origin()\\n\";\n\t\telse if (member == \"gasprice\")\n\t\t\tdefine(_memberAccess) << \"gasprice()\\n\";\n\t\telse if (member == \"chainid\")\n\t\t\tdefine(_memberAccess) << \"chainid()\\n\";\n\t\telse if (member == \"basefee\")\n\t\t\tdefine(_memberAccess) << \"basefee()\\n\";\n\t\telse if (member == \"blobbasefee\")\n\t\t\tdefine(_memberAccess) << \"blobbasefee()\\n\";\n\t\telse if (member == \"data\")\n\t\t{\n\t\t\tIRVariable var(_memberAccess);\n\t\t\tdefine(var.part(\"offset\")) << \"0\\n\";\n\t\t\tdefine(var.part(\"length\")) << \"calldatasize()\\n\";\n\t\t}\n\t\telse if (member == \"sig\")\n\t\t\tdefine(_memberAccess) <<\n\t\t\t\t\"and(calldataload(0), \" <<\n\t\t\t\tformatNumber(u256(0xffffffff) << (256 - 32)) <<\n\t\t\t\t\")\\n\";\n\t\telse if (member == \"gas\")\n\t\t\tsolAssert(false, \"Gas has been removed.\");\n\t\telse if (member == \"blockhash\")\n\t\t\tsolAssert(false, \"Blockhash has been removed.\");\n\t\telse if (member == \"creationCode\" || member == \"runtimeCode\")\n\t\t{\n\t\t\tsolAssert(!m_context.eofVersion().has_value(), \"EOF does not support \\\"\" + member + \"\\\".\");\n\t\t\tType const* arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();\n\t\t\tauto const& contractType = dynamic_cast<ContractType const&>(*arg);\n\t\t\tsolAssert(!contractType.isSuper());\n\t\t\tContractDefinition const& contract = contractType.contractDefinition();\n\t\t\tm_context.addSubObject(&contract);\n\t\t\tappendCode() << Whiskers(R\"(\n\t\t\t\tlet <size> := datasize(\"<objectName>\")\n\t\t\t\tlet <result> := <allocationFunction>(add(<size>, 32))\n\t\t\t\tmstore(<result>, <size>)\n\t\t\t\tdatacopy(add(<result>, 32), dataoffset(\"<objectName>\"), <size>)\n\t\t\t)\")\n\t\t\t(\"allocationFunction\", m_utils.allocationFunction())\n\t\t\t(\"size\", m_context.newYulVariable())\n\t\t\t(\"objectName\", IRNames::creationObject(contract) + (member == \"runtimeCode\" ? \".\" + IRNames::deployedObject(contract) : \"\"))\n\t\t\t(\"result\", IRVariable(_memberAccess).commaSeparatedList()).render();\n\t\t}\n\t\telse if (member == \"name\")\n\t\t{\n\t\t\tType const* arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();\n\t\t\tContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();\n\t\t\tdefine(IRVariable(_memberAccess)) << m_utils.copyLiteralToMemoryFunction(contract.name()) << \"()\\n\";\n\t\t}\n\t\telse if (member == \"interfaceId\")\n\t\t{\n\t\t\tType const* arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();\n\t\t\tauto const& contractType = dynamic_cast<ContractType const&>(*arg);\n\t\t\tsolAssert(!contractType.isSuper());\n\t\t\tContractDefinition const& contract = contractType.contractDefinition();\n\t\t\tdefine(_memberAccess) << formatNumber(u256{contract.interfaceId()} << (256 - 32)) << \"\\n\";\n\t\t}\n\t\telse if (member == \"min\" || member == \"max\")\n\t\t{\n\t\t\tMagicType const* arg = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type);\n\n\t\t\tstd::string requestedValue;\n\t\t\tif (IntegerType const* integerType = dynamic_cast<IntegerType const*>(arg->typeArgument()))\n\t\t\t{\n\t\t\t\tif (member == \"min\")\n\t\t\t\t\trequestedValue = formatNumber(integerType->min());\n\t\t\t\telse\n\t\t\t\t\trequestedValue = formatNumber(integerType->max());\n\t\t\t}\n\t\t\telse if (EnumType const* enumType = dynamic_cast<EnumType const*>(arg->typeArgument()))\n\t\t\t{\n\t\t\t\tif (member == \"min\")\n\t\t\t\t\trequestedValue = std::to_string(enumType->minValue());\n\t\t\t\telse\n\t\t\t\t\trequestedValue = std::to_string(enumType->maxValue());\n\t\t\t}\n\t\t\telse\n\t\t\t\tsolAssert(false, \"min/max requested on unexpected type.\");\n\n\t\t\tdefine(_memberAccess) << requestedValue << \"\\n\";\n\t\t}\n\t\telse if (std::set<std::string>{\"encode\", \"encodePacked\", \"encodeWithSelector\", \"encodeCall\", \"encodeWithSignature\", \"decode\"}.count(member))\n\t\t{\n\t\t\t// no-op\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"Unknown magic member.\");\n\t\tbreak;\n\tcase Type::Category::Struct:\n\t{\n\t\tauto const& structType = dynamic_cast<StructType const&>(*_memberAccess.expression().annotation().type);\n\n\t\tIRVariable expression(_memberAccess.expression());\n\t\tswitch (structType.location())\n\t\t{\n\t\tcase DataLocation::Storage:\n\t\t{\n\t\t\tstd::pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member);\n\t\t\tstd::string slot = m_context.newYulVariable();\n\t\t\tappendCode() << \"let \" << slot << \" := \" <<\n\t\t\t\t(\"add(\" + expression.part(\"slot\").name() + \", \" + offsets.first.str() + \")\\n\");\n\t\t\tsetLValue(_memberAccess, IRLValue{\n\t\t\t\ttype(_memberAccess),\n\t\t\t\tIRLValue::Storage{slot, offsets.second}\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\t\tcase DataLocation::Memory:\n\t\t{\n\t\t\tstd::string pos = m_context.newYulVariable();\n\t\t\tappendCode() << \"let \" << pos << \" := \" <<\n\t\t\t\t(\"add(\" + expression.part(\"mpos\").name() + \", \" + structType.memoryOffsetOfMember(member).str() + \")\\n\");\n\t\t\tsetLValue(_memberAccess, IRLValue{\n\t\t\t\ttype(_memberAccess),\n\t\t\t\tIRLValue::Memory{pos}\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\t\tcase DataLocation::CallData:\n\t\t{\n\t\t\tstd::string baseRef = expression.part(\"offset\").name();\n\t\t\tstd::string offset = m_context.newYulVariable();\n\t\t\tappendCode() << \"let \" << offset << \" := \" << \"add(\" << baseRef << \", \" << std::to_string(structType.calldataOffsetOfMember(member)) << \")\\n\";\n\t\t\tif (_memberAccess.annotation().type->isDynamicallyEncoded())\n\t\t\t\tdefine(_memberAccess) <<\n\t\t\t\t\tm_utils.accessCalldataTailFunction(*_memberAccess.annotation().type) <<\n\t\t\t\t\t\"(\" <<\n\t\t\t\t\tbaseRef <<\n\t\t\t\t\t\", \" <<\n\t\t\t\t\toffset <<\n\t\t\t\t\t\")\\n\";\n\t\t\telse if (\n\t\t\t\tdynamic_cast<ArrayType const*>(_memberAccess.annotation().type) ||\n\t\t\t\tdynamic_cast<StructType const*>(_memberAccess.annotation().type)\n\t\t\t)\n\t\t\t\tdefine(_memberAccess) << offset << \"\\n\";\n\t\t\telse\n\t\t\t\tdefine(_memberAccess) <<\n\t\t\t\t\tm_utils.readFromCalldata(*_memberAccess.annotation().type) <<\n\t\t\t\t\t\"(\" <<\n\t\t\t\t\toffset <<\n\t\t\t\t\t\")\\n\";\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tsolAssert(false, \"Illegal data location for struct.\");\n\t\t}\n\t\tbreak;\n\t}\n\tcase Type::Category::Enum:\n\t{\n\t\tEnumType const& type = dynamic_cast<EnumType const&>(*_memberAccess.expression().annotation().type);\n\t\tdefine(_memberAccess) << std::to_string(type.memberValue(_memberAccess.memberName())) << \"\\n\";\n\t\tbreak;\n\t}\n\tcase Type::Category::Array:\n\t{\n\t\tauto const& type = dynamic_cast<ArrayType const&>(*_memberAccess.expression().annotation().type);\n\t\tif (member == \"length\")\n\t\t{\n\t\t\t// shortcut for <address>.code.length\n\t\t\tif (\n\t\t\t\tauto innerExpression = dynamic_cast<MemberAccess const*>(&_memberAccess.expression());\n\t\t\t\tinnerExpression &&\n\t\t\t\tinnerExpression->memberName() == \"code\" &&\n\t\t\t\tinnerExpression->expression().annotation().type->category() == Type::Category::Address\n\t\t\t)\n\t\t\t\tdefine(_memberAccess) <<\n\t\t\t\t\t\"extcodesize(\" <<\n\t\t\t\t\texpressionAsType(innerExpression->expression(), *TypeProvider::address()) <<\n\t\t\t\t\t\")\\n\";\n\t\t\telse\n\t\t\t\tdefine(_memberAccess) <<\n\t\t\t\t\tm_utils.arrayLengthFunction(type) <<\n\t\t\t\t\t\"(\" <<\n\t\t\t\t\tIRVariable(_memberAccess.expression()).commaSeparatedList() <<\n\t\t\t\t\t\")\\n\";\n\t\t}\n\t\telse if (member == \"pop\" || member == \"push\")\n\t\t{\n\t\t\tsolAssert(type.location() == DataLocation::Storage);\n\t\t\tdefine(IRVariable{_memberAccess}.part(\"slot\"), IRVariable{_memberAccess.expression()}.part(\"slot\"));\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"Invalid array member access.\");\n\n\t\tbreak;\n\t}\n\tcase Type::Category::FixedBytes:\n\t{\n\t\tauto const& type = dynamic_cast<FixedBytesType const&>(*_memberAccess.expression().annotation().type);\n\t\tif (member == \"length\")\n\t\t\tdefine(_memberAccess) << std::to_string(type.numBytes()) << \"\\n\";\n\t\telse\n\t\t\tsolAssert(false, \"Illegal fixed bytes member.\");\n\t\tbreak;\n\t}\n\tcase Type::Category::TypeType:\n\t{\n\t\tType const& actualType = *dynamic_cast<TypeType const&>(\n\t\t\t*_memberAccess.expression().annotation().type\n\t\t).actualType();\n\n\t\tif (actualType.category() == Type::Category::Contract)\n\t\t{\n\t\t\tContractType const& contractType = dynamic_cast<ContractType const&>(actualType);\n\t\t\tif (contractType.isSuper())\n\t\t\t{\n\t\t\t\tsolAssert(!!_memberAccess.annotation().referencedDeclaration, \"Referenced declaration not resolved.\");\n\t\t\t\tContractDefinition const* super = contractType.contractDefinition().superContract(m_context.mostDerivedContract());\n\t\t\t\tsolAssert(super, \"Super contract not available.\");\n\t\t\t\tFunctionDefinition const& resolvedFunctionDef =\n\t\t\t\t\tdynamic_cast<FunctionDefinition const&>(\n\t\t\t\t\t\t*_memberAccess.annotation().referencedDeclaration\n\t\t\t\t\t).resolveVirtual(m_context.mostDerivedContract(), super);\n\n\t\t\t\tsolAssert(resolvedFunctionDef.functionType(true));\n\t\t\t\tsolAssert(resolvedFunctionDef.functionType(true)->kind() == FunctionType::Kind::Internal);\n\t\t\t\tassignInternalFunctionIDIfNotCalledDirectly(_memberAccess, resolvedFunctionDef);\n\t\t\t}\n\t\t\telse if (auto const* variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t\t\thandleVariableReference(*variable, _memberAccess);\n\t\t\telse if (memberFunctionType)\n\t\t\t{\n\t\t\t\tswitch (memberFunctionType->kind())\n\t\t\t\t{\n\t\t\t\tcase FunctionType::Kind::Declaration:\n\t\t\t\t\tbreak;\n\t\t\t\tcase FunctionType::Kind::Internal:\n\t\t\t\t\tif (auto const* function = dynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t\t\t\t\tassignInternalFunctionIDIfNotCalledDirectly(_memberAccess, *function);\n\t\t\t\t\telse\n\t\t\t\t\t\tsolAssert(false, \"Function not found in member access\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase FunctionType::Kind::Event:\n\t\t\t\t\tsolAssert(\n\t\t\t\t\t\tdynamic_cast<EventDefinition const*>(_memberAccess.annotation().referencedDeclaration),\n\t\t\t\t\t\t\"Event not found\"\n\t\t\t\t\t);\n\t\t\t\t\t\t// the call will do the resolving\n\t\t\t\t\tbreak;\n\t\t\t\tcase FunctionType::Kind::Error:\n\t\t\t\t\tsolAssert(\n\t\t\t\t\t\tdynamic_cast<ErrorDefinition const*>(_memberAccess.annotation().referencedDeclaration),\n\t\t\t\t\t\t\"Error not found\"\n\t\t\t\t\t);\n\t\t\t\t\t// The function call will resolve the selector.\n\t\t\t\t\tbreak;\n\t\t\t\tcase FunctionType::Kind::DelegateCall:\n\t\t\t\t\tdefine(IRVariable(_memberAccess).part(\"address\"), _memberAccess.expression());\n\t\t\t\t\tdefine(IRVariable(_memberAccess).part(\"functionSelector\")) << formatNumber(memberFunctionType->externalIdentifier()) << \"\\n\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase FunctionType::Kind::External:\n\t\t\t\tcase FunctionType::Kind::Creation:\n\t\t\t\tcase FunctionType::Kind::Send:\n\t\t\t\tcase FunctionType::Kind::BareCall:\n\t\t\t\tcase FunctionType::Kind::BareCallCode:\n\t\t\t\tcase FunctionType::Kind::BareDelegateCall:\n\t\t\t\tcase FunctionType::Kind::BareStaticCall:\n\t\t\t\tcase FunctionType::Kind::Transfer:\n\t\t\t\tcase FunctionType::Kind::ECRecover:\n\t\t\t\tcase FunctionType::Kind::SHA256:\n\t\t\t\tcase FunctionType::Kind::RIPEMD160:\n\t\t\t\tdefault:\n\t\t\t\t\tsolAssert(false, \"unsupported member function\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (dynamic_cast<TypeType const*>(_memberAccess.annotation().type))\n\t\t\t{\n\t\t\t// no-op\n\t\t\t}\n\t\t\telse\n\t\t\t\t// The old code generator had a generic \"else\" case here\n\t\t\t\t// without any specific code being generated,\n\t\t\t\t// but it would still be better to have an exhaustive list.\n\t\t\t\tsolAssert(false);\n\t\t}\n\t\telse if (EnumType const* enumType = dynamic_cast<EnumType const*>(&actualType))\n\t\t\tdefine(_memberAccess) << std::to_string(enumType->memberValue(_memberAccess.memberName())) << \"\\n\";\n\t\telse if (dynamic_cast<UserDefinedValueType const*>(&actualType))\n\t\t\tsolAssert(member == \"wrap\" || member == \"unwrap\");\n\t\telse if (auto const* arrayType = dynamic_cast<ArrayType const*>(&actualType))\n\t\t\tsolAssert(arrayType->isByteArrayOrString() && member == \"concat\");\n\t\telse\n\t\t\t// The old code generator had a generic \"else\" case here\n\t\t\t// without any specific code being generated,\n\t\t\t// but it would still be better to have an exhaustive list.\n\t\t\tsolAssert(false);\n\t\tbreak;\n\t}\n\tcase Type::Category::Module:\n\t{\n\t\tType::Category category = _memberAccess.annotation().type->category();\n\t\tsolAssert(\n\t\t\tdynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration) ||\n\t\t\tdynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration) ||\n\t\t\tdynamic_cast<ErrorDefinition const*>(_memberAccess.annotation().referencedDeclaration) ||\n\t\t\tdynamic_cast<EventDefinition const*>(_memberAccess.annotation().referencedDeclaration) ||\n\t\t\tcategory == Type::Category::TypeType ||\n\t\t\tcategory == Type::Category::Module,\n\t\t\t\"\"\n\t\t);\n\t\tif (auto variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t{\n\t\t\tsolAssert(variable->isConstant());\n\t\t\thandleVariableReference(*variable, static_cast<Expression const&>(_memberAccess));\n\t\t}\n\t\telse if (auto const* function = dynamic_cast<FunctionDefinition const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t{\n\t\t\tauto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type);\n\t\t\tsolAssert(function && function->isFree());\n\t\t\tsolAssert(function->functionType(true));\n\t\t\tsolAssert(function->functionType(true)->kind() == FunctionType::Kind::Internal);\n\t\t\tsolAssert(funType->kind() == FunctionType::Kind::Internal);\n\t\t\tsolAssert(*_memberAccess.annotation().requiredLookup == VirtualLookup::Static);\n\n\t\t\tassignInternalFunctionIDIfNotCalledDirectly(_memberAccess, *function);\n\t\t}\n\t\telse if (auto const* contract = dynamic_cast<ContractDefinition const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t{\n\t\t\tif (contract->isLibrary())\n\t\t\t\tdefine(IRVariable(_memberAccess).part(\"address\")) << linkerSymbol(*contract) << \"\\n\";\n\t\t}\n\t\tbreak;\n\t}\n\tdefault:\n\t\tsolAssert(false, \"Member access to unknown type.\");\n\t}\n}\n\nbool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)\n{\n\tsetLocation(_inlineAsm);\n\tif (*_inlineAsm.annotation().hasMemoryEffects && !_inlineAsm.annotation().markedMemorySafe)\n\t\tm_context.setMemoryUnsafeInlineAssemblySeen();\n\tCopyTranslate bodyCopier{m_context, _inlineAsm.annotation().externalReferences};\n\n\tyul::Statement modified = bodyCopier(_inlineAsm.operations().root());\n\n\tsolAssert(std::holds_alternative<yul::Block>(modified));\n\n\tappendCode() << yul::AsmPrinter(_inlineAsm.dialect())(std::get<yul::Block>(modified)) << \"\\n\";\n\treturn false;\n}\n\n\nvoid IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)\n{\n\tsetLocation(_indexAccess);\n\tType const& baseType = *_indexAccess.baseExpression().annotation().type;\n\n\tif (baseType.category() == Type::Category::Mapping)\n\t{\n\t\tsolAssert(_indexAccess.indexExpression(), \"Index expression expected.\");\n\n\t\tMappingType const& mappingType = dynamic_cast<MappingType const&>(baseType);\n\t\tType const& keyType = *_indexAccess.indexExpression()->annotation().type;\n\n\t\tstd::string slot = m_context.newYulVariable();\n\t\tWhiskers templ(\"let <slot> := <indexAccess>(<base><?+key>,<key></+key>)\\n\");\n\t\ttempl(\"slot\", slot);\n\t\ttempl(\"indexAccess\", m_utils.mappingIndexAccessFunction(mappingType, keyType));\n\t\ttempl(\"base\", IRVariable(_indexAccess.baseExpression()).commaSeparatedList());\n\t\ttempl(\"key\", IRVariable(*_indexAccess.indexExpression()).commaSeparatedList());\n\t\tappendCode() << templ.render();\n\t\tsetLValue(_indexAccess, IRLValue{\n\t\t\t*_indexAccess.annotation().type,\n\t\t\tIRLValue::Storage{\n\t\t\t\tslot,\n\t\t\t\t0u\n\t\t\t}\n\t\t});\n\t}\n\telse if (baseType.category() == Type::Category::Array || baseType.category() == Type::Category::ArraySlice)\n\t{\n\t\tArrayType const& arrayType =\n\t\t\tbaseType.category() == Type::Category::Array ?\n\t\t\tdynamic_cast<ArrayType const&>(baseType) :\n\t\t\tdynamic_cast<ArraySliceType const&>(baseType).arrayType();\n\n\t\tif (baseType.category() == Type::Category::ArraySlice)\n\t\t\tsolAssert(arrayType.dataStoredIn(DataLocation::CallData) && arrayType.isDynamicallySized());\n\n\t\tsolAssert(_indexAccess.indexExpression(), \"Index expression expected.\");\n\n\t\tswitch (arrayType.location())\n\t\t{\n\t\t\tcase DataLocation::Storage:\n\t\t\t{\n\t\t\t\tstd::string slot = m_context.newYulVariable();\n\t\t\t\tstd::string offset = m_context.newYulVariable();\n\n\t\t\t\tappendCode() << Whiskers(R\"(\n\t\t\t\t\tlet <slot>, <offset> := <indexFunc>(<array>, <index>)\n\t\t\t\t)\")\n\t\t\t\t(\"slot\", slot)\n\t\t\t\t(\"offset\", offset)\n\t\t\t\t(\"indexFunc\", m_utils.storageArrayIndexAccessFunction(arrayType))\n\t\t\t\t(\"array\", IRVariable(_indexAccess.baseExpression()).part(\"slot\").name())\n\t\t\t\t(\"index\", IRVariable(*_indexAccess.indexExpression()).name())\n\t\t\t\t.render();\n\n\t\t\t\tsetLValue(_indexAccess, IRLValue{\n\t\t\t\t\t*_indexAccess.annotation().type,\n\t\t\t\t\tIRLValue::Storage{slot, offset}\n\t\t\t\t});\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DataLocation::Transient:\n\t\t\t\tsolUnimplemented(\"Transient data location is only supported for value types.\");\n\t\t\t\tbreak;\n\t\t\tcase DataLocation::Memory:\n\t\t\t{\n\t\t\t\tstd::string const indexAccessFunction = m_utils.memoryArrayIndexAccessFunction(arrayType);\n\t\t\t\tstd::string const baseRef = IRVariable(_indexAccess.baseExpression()).part(\"mpos\").name();\n\t\t\t\tstd::string const indexExpression = expressionAsType(\n\t\t\t\t\t*_indexAccess.indexExpression(),\n\t\t\t\t\t*TypeProvider::uint256()\n\t\t\t\t);\n\t\t\t\tstd::string const memAddress = indexAccessFunction + \"(\" + baseRef + \", \" + indexExpression + \")\";\n\n\t\t\t\tsetLValue(_indexAccess, IRLValue{\n\t\t\t\t\t*arrayType.baseType(),\n\t\t\t\t\tIRLValue::Memory{memAddress, arrayType.isByteArrayOrString()}\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DataLocation::CallData:\n\t\t\t{\n\t\t\t\tstd::string const indexAccessFunction = m_utils.calldataArrayIndexAccessFunction(arrayType);\n\t\t\t\tstd::string const baseRef = IRVariable(_indexAccess.baseExpression()).commaSeparatedList();\n\t\t\t\tstd::string const indexExpression = expressionAsType(\n\t\t\t\t\t*_indexAccess.indexExpression(),\n\t\t\t\t\t*TypeProvider::uint256()\n\t\t\t\t);\n\t\t\t\tstd::string const calldataAddress = indexAccessFunction + \"(\" + baseRef + \", \" + indexExpression + \")\";\n\n\t\t\t\tif (arrayType.isByteArrayOrString())\n\t\t\t\t\tdefine(_indexAccess) <<\n\t\t\t\t\t\tm_utils.cleanupFunction(*arrayType.baseType()) <<\n\t\t\t\t\t\t\"(calldataload(\" <<\n\t\t\t\t\t\tcalldataAddress <<\n\t\t\t\t\t\t\"))\\n\";\n\t\t\t\telse if (arrayType.baseType()->isValueType())\n\t\t\t\t\tdefine(_indexAccess) <<\n\t\t\t\t\t\tm_utils.readFromCalldata(*arrayType.baseType()) <<\n\t\t\t\t\t\t\"(\" <<\n\t\t\t\t\t\tcalldataAddress <<\n\t\t\t\t\t\t\")\\n\";\n\t\t\t\telse\n\t\t\t\t\tdefine(_indexAccess) << calldataAddress << \"\\n\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\telse if (baseType.category() == Type::Category::FixedBytes)\n\t{\n\t\tauto const& fixedBytesType = dynamic_cast<FixedBytesType const&>(baseType);\n\t\tsolAssert(_indexAccess.indexExpression(), \"Index expression expected.\");\n\n\t\tIRVariable index{m_context.newYulVariable(), *TypeProvider::uint256()};\n\t\tdefine(index, *_indexAccess.indexExpression());\n\t\tappendCode() << Whiskers(R\"(\n\t\t\tif iszero(lt(<index>, <length>)) { <panic>() }\n\t\t\tlet <result> := <shl248>(byte(<index>, <array>))\n\t\t)\")\n\t\t(\"index\", index.name())\n\t\t(\"length\", std::to_string(fixedBytesType.numBytes()))\n\t\t(\"panic\", m_utils.panicFunction(PanicCode::ArrayOutOfBounds))\n\t\t(\"array\", IRVariable(_indexAccess.baseExpression()).name())\n\t\t(\"shl248\", m_utils.shiftLeftFunction(256 - 8))\n\t\t(\"result\", IRVariable(_indexAccess).name())\n\t\t.render();\n\t}\n\telse if (baseType.category() == Type::Category::TypeType)\n\t{\n\t\tsolAssert(baseType.sizeOnStack() == 0);\n\t\tsolAssert(_indexAccess.annotation().type->sizeOnStack() == 0);\n\t\t// no-op - this seems to be a lone array type (`structType[];`)\n\t}\n\telse\n\t\tsolAssert(false, \"Index access only allowed for mappings or arrays.\");\n}\n\nvoid IRGeneratorForStatements::endVisit(IndexRangeAccess const& _indexRangeAccess)\n{\n\tsetLocation(_indexRangeAccess);\n\tType const& baseType = *_indexRangeAccess.baseExpression().annotation().type;\n\tsolAssert(\n\t\tbaseType.category() == Type::Category::Array || baseType.category() == Type::Category::ArraySlice,\n\t\t\"Index range accesses is available only on arrays and array slices.\"\n\t);\n\n\tArrayType const& arrayType =\n\t\tbaseType.category() == Type::Category::Array ?\n\t\tdynamic_cast<ArrayType const &>(baseType) :\n\t\tdynamic_cast<ArraySliceType const &>(baseType).arrayType();\n\n\tswitch (arrayType.location())\n\t{\n\t\tcase DataLocation::CallData:\n\t\t{\n\t\t\tsolAssert(baseType.isDynamicallySized());\n\t\t\tIRVariable sliceStart{m_context.newYulVariable(), *TypeProvider::uint256()};\n\t\t\tif (_indexRangeAccess.startExpression())\n\t\t\t\tdefine(sliceStart, IRVariable{*_indexRangeAccess.startExpression()});\n\t\t\telse\n\t\t\t\tdefine(sliceStart) << u256(0) << \"\\n\";\n\n\t\t\tIRVariable sliceEnd{\n\t\t\t\tm_context.newYulVariable(),\n\t\t\t\t*TypeProvider::uint256()\n\t\t\t};\n\t\t\tif (_indexRangeAccess.endExpression())\n\t\t\t\tdefine(sliceEnd, IRVariable{*_indexRangeAccess.endExpression()});\n\t\t\telse\n\t\t\t\tdefine(sliceEnd, IRVariable{_indexRangeAccess.baseExpression()}.part(\"length\"));\n\n\t\t\tIRVariable range{_indexRangeAccess};\n\t\t\tdefine(range) <<\n\t\t\t\tm_utils.calldataArrayIndexRangeAccess(arrayType) << \"(\" <<\n\t\t\t\tIRVariable{_indexRangeAccess.baseExpression()}.commaSeparatedList() << \", \" <<\n\t\t\t\tsliceStart.name() << \", \" <<\n\t\t\t\tsliceEnd.name() << \")\\n\";\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tsolUnimplemented(\"Index range accesses is implemented only on calldata arrays.\");\n\t}\n}\n\nvoid IRGeneratorForStatements::endVisit(Identifier const& _identifier)\n{\n\tsetLocation(_identifier);\n\tDeclaration const* declaration = _identifier.annotation().referencedDeclaration;\n\tif (MagicVariableDeclaration const* magicVar = dynamic_cast<MagicVariableDeclaration const*>(declaration))\n\t{\n\t\tswitch (magicVar->type()->category())\n\t\t{\n\t\tcase Type::Category::Contract:\n\t\t\tsolAssert(_identifier.name() == \"this\");\n\t\t\tdefine(_identifier) << \"address()\\n\";\n\t\t\tbreak;\n\t\tcase Type::Category::Integer:\n\t\t\tsolAssert(_identifier.name() == \"now\");\n\t\t\tdefine(_identifier) << \"timestamp()\\n\";\n\t\t\tbreak;\n\t\tcase Type::Category::TypeType:\n\t\t{\n\t\t\tauto typeType = dynamic_cast<TypeType const*>(magicVar->type());\n\t\t\tif (auto contractType = dynamic_cast<ContractType const*>(typeType->actualType()))\n\t\t\t\tsolAssert(!contractType->isSuper() || _identifier.name() == \"super\");\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t\treturn;\n\t}\n\telse if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))\n\t{\n\t\tsolAssert(*_identifier.annotation().requiredLookup == VirtualLookup::Virtual);\n\t\tFunctionDefinition const& resolvedFunctionDef = functionDef->resolveVirtual(m_context.mostDerivedContract());\n\n\t\tsolAssert(resolvedFunctionDef.functionType(true));\n\t\tsolAssert(resolvedFunctionDef.functionType(true)->kind() == FunctionType::Kind::Internal);\n\t\tassignInternalFunctionIDIfNotCalledDirectly(_identifier, resolvedFunctionDef);\n\t}\n\telse if (VariableDeclaration const* varDecl = dynamic_cast<VariableDeclaration const*>(declaration))\n\t\thandleVariableReference(*varDecl, _identifier);\n\telse if (auto const* contract = dynamic_cast<ContractDefinition const*>(declaration))\n\t{\n\t\tif (contract->isLibrary())\n\t\t\tdefine(IRVariable(_identifier).part(\"address\")) << linkerSymbol(*contract) << \"\\n\";\n\t}\n\telse if (dynamic_cast<EventDefinition const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse if (dynamic_cast<ErrorDefinition const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse if (dynamic_cast<EnumDefinition const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse if (dynamic_cast<StructDefinition const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse if (dynamic_cast<ImportDirective const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse if (dynamic_cast<UserDefinedValueTypeDefinition const*>(declaration))\n\t{\n\t\t// no-op\n\t}\n\telse\n\t{\n\t\tsolAssert(false, \"Identifier type not expected in expression context.\");\n\t}\n}\n\nbool IRGeneratorForStatements::visit(Literal const& _literal)\n{\n\tsetLocation(_literal);\n\tType const& literalType = type(_literal);\n\n\tswitch (literalType.category())\n\t{\n\tcase Type::Category::RationalNumber:\n\tcase Type::Category::Bool:\n\tcase Type::Category::Address:\n\t\tdefine(_literal) << toCompactHexWithPrefix(literalType.literalValue(&_literal)) << \"\\n\";\n\t\tbreak;\n\tcase Type::Category::StringLiteral:\n\t\tbreak; // will be done during conversion\n\tdefault:\n\t\tsolUnimplemented(\"Only integer, boolean and string literals implemented for now.\");\n\t}\n\treturn false;\n}\n\nvoid IRGeneratorForStatements::handleVariableReference(\n\tVariableDeclaration const& _variable,\n\tExpression const& _referencingExpression\n)\n{\n\tif ((_variable.isStateVariable() || _variable.isFileLevelVariable()) && _variable.isConstant())\n\t\tdefine(_referencingExpression) << constantValueFunction(_variable) << \"()\\n\";\n\telse if (_variable.isStateVariable() && _variable.immutable())\n\t\tsetLValue(_referencingExpression, IRLValue{\n\t\t\t*_variable.annotation().type,\n\t\t\tIRLValue::Immutable{&_variable}\n\t\t});\n\telse if (m_context.isLocalVariable(_variable))\n\t\tsetLValue(_referencingExpression, IRLValue{\n\t\t\t*_variable.annotation().type,\n\t\t\tIRLValue::Stack{m_context.localVariable(_variable)}\n\t\t});\n\telse if (m_context.isStateVariable(_variable) && _variable.referenceLocation() == VariableDeclaration::Location::Transient)\n\t\tsetLValue(_referencingExpression, IRLValue{\n\t\t\t*_variable.annotation().type,\n\t\t\tIRLValue::TransientStorage{\n\t\t\t\ttoCompactHexWithPrefix(m_context.storageLocationOfStateVariable(_variable).first),\n\t\t\t\tm_context.storageLocationOfStateVariable(_variable).second\n\t\t\t}\n\t\t});\n\telse if (m_context.isStateVariable(_variable))\n\t{\n\t\tsolAssert(_variable.referenceLocation() == VariableDeclaration::Location::Unspecified, \"Must have storage location.\");\n\t\tsetLValue(_referencingExpression, IRLValue{\n\t\t\t*_variable.annotation().type,\n\t\t\tIRLValue::Storage{\n\t\t\t\ttoCompactHexWithPrefix(m_context.storageLocationOfStateVariable(_variable).first),\n\t\t\t\tm_context.storageLocationOfStateVariable(_variable).second\n\t\t\t}\n\t\t});\n\t}\n\telse\n\t\tsolAssert(false, \"Invalid variable kind.\");\n}\n\nvoid IRGeneratorForStatements::appendExternalFunctionCall(\n\tFunctionCall const& _functionCall,\n\tstd::vector<ASTPointer<Expression const>> const& _arguments\n)\n{\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(type(_functionCall.expression()));\n\tsolAssert(!funType.takesArbitraryParameters());\n\tsolAssert(_arguments.size() == funType.parameterTypes().size());\n\tsolAssert(!funType.isBareCall());\n\tFunctionType::Kind const funKind = funType.kind();\n\n\tsolAssert(\n\t\tfunKind == FunctionType::Kind::External || funKind == FunctionType::Kind::DelegateCall,\n\t\t\"Can only be used for regular external calls.\"\n\t);\n\n\tbool const isDelegateCall = funKind == FunctionType::Kind::DelegateCall;\n\tbool const useStaticCall = funType.stateMutability() <= StateMutability::View && m_context.evmVersion().hasStaticCall();\n\n\tReturnInfo const returnInfo{m_context.evmVersion(), funType};\n\n\tTypePointers parameterTypes = funType.parameterTypes();\n\tTypePointers argumentTypes;\n\tstd::vector<std::string> argumentStrings;\n\tif (funType.hasBoundFirstArgument())\n\t{\n\t\tparameterTypes.insert(parameterTypes.begin(), funType.selfType());\n\t\targumentTypes.emplace_back(funType.selfType());\n\t\targumentStrings += IRVariable(_functionCall.expression()).part(\"self\").stackSlots();\n\t}\n\n\tfor (auto const& arg: _arguments)\n\t{\n\t\targumentTypes.emplace_back(&type(*arg));\n\t\targumentStrings += IRVariable(*arg).stackSlots();\n\t}\n\n\tif (!m_context.evmVersion().canOverchargeGasForCall())\n\t{\n\t\t// Touch the end of the output area so that we do not pay for memory resize during the call\n\t\t// (which we would have to subtract from the gas left)\n\t\t// We could also just use MLOAD; POP right before the gas calculation, but the optimizer\n\t\t// would remove that, so we use MSTORE here.\n\t\tif (!funType.gasSet() && returnInfo.estimatedReturnSize > 0)\n\t\t\tappendCode() << \"mstore(add(\" << m_utils.allocateUnboundedFunction() << \"() , \" << std::to_string(returnInfo.estimatedReturnSize) << \"), 0)\\n\";\n\t}\n\n\t// NOTE: When the expected size of returndata is static, we pass that in to the call opcode and it gets copied automatically.\n\t// When it's dynamic, we get zero from estimatedReturnSize() instead and then we need an explicit returndatacopy().\n\tWhiskers templ(R\"(\n\t\t<?checkExtcodesize>\n\t\t\tif iszero(extcodesize(<address>)) { <revertNoCode>() }\n\t\t</checkExtcodesize>\n\t\t// storage for arguments and returned data\n\t\tlet <pos> := <allocateUnbounded>()\n\t\tmstore(<pos>, <shl28>(<funSel>))\n\t\tlet <end> := <encodeArgs>(add(<pos>, 4) <argumentString>)\n\n\t\t<?eof>\n\t\t\tlet <success> := iszero(<call>(<address>, <pos>, sub(<end>, <pos>) <?hasValue>, <value></hasValue>))\n\t\t<!eof>\n\t\t\tlet <success> := <call>(<gas>, <address>, <?hasValue> <value>, </hasValue> <pos>, sub(<end>, <pos>), <pos>, <staticReturndataSize>)\n\t\t</eof>\n\t\t<?noTryCall>\n\t\t\tif iszero(<success>) { <forwardingRevert>() }\n\t\t</noTryCall>\n\t\t<?+retVars> let <retVars> </+retVars>\n\t\tif <success> {\n\t\t\t<?isReturndataSizeDynamic>\n\t\t\t\tlet <returnDataSizeVar> := returndatasize()\n\t\t\t\treturndatacopy(<pos>, 0, <returnDataSizeVar>)\n\t\t\t<!isReturndataSizeDynamic>\n\t\t\t\tlet <returnDataSizeVar> := <staticReturndataSize>\n\t\t\t\t<?supportsReturnData>\n\t\t\t\t\tif gt(<returnDataSizeVar>, returndatasize()) {\n\t\t\t\t\t\t<returnDataSizeVar> := returndatasize()\n\t\t\t\t\t}\n\t\t\t\t\t<?eof>\n\t\t\t\t\t\treturndatacopy(<pos>, 0, <returnDataSizeVar>)\n\t\t\t\t\t</eof>\n\t\t\t\t</supportsReturnData>\n\t\t\t</isReturndataSizeDynamic>\n\n\t\t\t// update freeMemoryPointer according to dynamic return size\n\t\t\t<finalizeAllocation>(<pos>, <returnDataSizeVar>)\n\n\t\t\t// decode return parameters from external try-call into retVars\n\t\t\t<?+retVars> <retVars> := </+retVars> <abiDecode>(<pos>, add(<pos>, <returnDataSizeVar>))\n\t\t}\n\t)\");\n\ttempl(\"revertNoCode\", m_utils.revertReasonIfDebugFunction(\"Target contract does not contain code\"));\n\tauto const eof = m_context.eofVersion().has_value();\n\tsolAssert(!eof || !funType.gasSet());\n\ttempl(\"eof\", eof);\n\n\t// We do not need to check extcodesize if we expect return data: If there is no\n\t// code, the call will return empty data and the ABI decoder will revert.\n\tsize_t encodedHeadSize = 0;\n\tfor (auto const& t: returnInfo.returnTypes)\n\t\tencodedHeadSize += t->decodingType()->calldataHeadSize();\n\tbool const checkExtcodesize =\n\t\t!eof &&\n\t\t(\n\t\t\tencodedHeadSize == 0 ||\n\t\t\t!m_context.evmVersion().supportsReturndata() ||\n\t\t\tm_context.revertStrings() >= RevertStrings::Debug\n\t\t);\n\ttempl(\"checkExtcodesize\", checkExtcodesize);\n\n\ttempl(\"pos\", m_context.newYulVariable());\n\ttempl(\"end\", m_context.newYulVariable());\n\tif (_functionCall.annotation().tryCall)\n\t\ttempl(\"success\", IRNames::trySuccessConditionVariable(_functionCall));\n\telse\n\t\ttempl(\"success\", m_context.newYulVariable());\n\ttempl(\"allocateUnbounded\", m_utils.allocateUnboundedFunction());\n\ttempl(\"finalizeAllocation\", m_utils.finalizeAllocationFunction());\n\ttempl(\"shl28\", m_utils.shiftLeftFunction(8 * (32 - 4)));\n\n\ttempl(\"funSel\", IRVariable(_functionCall.expression()).part(\"functionSelector\").name());\n\ttempl(\"address\", IRVariable(_functionCall.expression()).part(\"address\").name());\n\n\tif (returnInfo.dynamicReturnSize)\n\t\tsolAssert(m_context.evmVersion().supportsReturndata());\n\ttempl(\"returnDataSizeVar\", m_context.newYulVariable());\n\ttempl(\"staticReturndataSize\", std::to_string(returnInfo.estimatedReturnSize));\n\ttempl(\"supportsReturnData\", m_context.evmVersion().supportsReturndata());\n\n\tstd::string const retVars = IRVariable(_functionCall).commaSeparatedList();\n\ttempl(\"retVars\", retVars);\n\tsolAssert(retVars.empty() == returnInfo.returnTypes.empty());\n\n\ttempl(\"abiDecode\", m_context.abiFunctions().tupleDecoder(returnInfo.returnTypes, true));\n\ttempl(\"isReturndataSizeDynamic\", returnInfo.dynamicReturnSize);\n\n\ttempl(\"noTryCall\", !_functionCall.annotation().tryCall);\n\n\tbool encodeForLibraryCall = funKind == FunctionType::Kind::DelegateCall;\n\n\tsolAssert(funType.padArguments());\n\ttempl(\"encodeArgs\", m_context.abiFunctions().tupleEncoder(argumentTypes, parameterTypes, encodeForLibraryCall));\n\ttempl(\"argumentString\", joinHumanReadablePrefixed(argumentStrings));\n\n\tsolAssert(!isDelegateCall || !funType.valueSet(), \"Value set for delegatecall\");\n\tsolAssert(!useStaticCall || !funType.valueSet(), \"Value set for staticcall\");\n\n\ttempl(\"hasValue\", !isDelegateCall && !useStaticCall);\n\ttempl(\"value\", funType.valueSet() ? IRVariable(_functionCall.expression()).part(\"value\").name() : \"0\");\n\n\tif (funType.gasSet())\n\t\ttempl(\"gas\", IRVariable(_functionCall.expression()).part(\"gas\").name());\n\telse if (m_context.evmVersion().canOverchargeGasForCall())\n\t\t// Send all gas (requires tangerine whistle EVM)\n\t\ttempl(\"gas\", \"gas()\");\n\telse\n\t{\n\t\t// send all gas except the amount needed to execute \"SUB\" and \"CALL\"\n\t\t// @todo this retains too much gas for now, needs to be fine-tuned.\n\t\tu256 gasNeededByCaller = evmasm::GasCosts::callGas(m_context.evmVersion()) + 10;\n\t\tif (funType.valueSet())\n\t\t\tgasNeededByCaller += evmasm::GasCosts::callValueTransferGas;\n\t\tif (!checkExtcodesize)\n\t\t\tgasNeededByCaller += evmasm::GasCosts::callNewAccountGas; // we never know\n\t\ttempl(\"gas\", \"sub(gas(), \" + formatNumber(gasNeededByCaller) + \")\");\n\t}\n\t// Order is important here, STATICCALL might overlap with DELEGATECALL.\n\tif (isDelegateCall)\n\t\ttempl(\"call\", eof ? \"extdelegatecall\" : \"delegatecall\");\n\telse if (useStaticCall)\n\t\ttempl(\"call\", eof ? \"extstaticcall\" : \"staticcall\");\n\telse\n\t\ttempl(\"call\", eof ? \"extcall\" : \"call\");\n\n\ttempl(\"forwardingRevert\", m_utils.forwardingRevertFunction());\n\n\tappendCode() << templ.render();\n}\n\nvoid IRGeneratorForStatements::appendBareCall(\n\tFunctionCall const& _functionCall,\n\tstd::vector<ASTPointer<Expression const>> const& _arguments\n)\n{\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(type(_functionCall.expression()));\n\tsolAssert(\n\t\t!funType.hasBoundFirstArgument() &&\n\t\t!funType.takesArbitraryParameters() &&\n\t\t_arguments.size() == 1 &&\n\t\tfunType.parameterTypes().size() == 1, \"\"\n\t);\n\tFunctionType::Kind const funKind = funType.kind();\n\n\tsolAssert(funKind != FunctionType::Kind::BareStaticCall || m_context.evmVersion().hasStaticCall());\n\tsolAssert(funKind != FunctionType::Kind::BareCallCode, \"Callcode has been removed.\");\n\tsolAssert(\n\t\tfunKind == FunctionType::Kind::BareCall ||\n\t\tfunKind == FunctionType::Kind::BareDelegateCall ||\n\t\tfunKind == FunctionType::Kind::BareStaticCall, \"\"\n\t);\n\n\tsolAssert(!_functionCall.annotation().tryCall);\n\tWhiskers templ(R\"(\n\t\t<?needsEncoding>\n\t\t\tlet <pos> := <allocateUnbounded>()\n\t\t\tlet <length> := sub(<encode>(<pos> <?+arg>,</+arg> <arg>), <pos>)\n\t\t<!needsEncoding>\n\t\t\tlet <pos> := add(<arg>, 0x20)\n\t\t\tlet <length> := mload(<arg>)\n\t\t</needsEncoding>\n\n\t\t<?eof>\n\t\t\tlet <success> := iszero(<call>(<address>, <pos>, <length> <?+value>, <value></+value>))\n\t\t<!eof>\n\t\t\tlet <success> := <call>(<gas>, <address>, <?+value> <value>, </+value> <pos>, <length>, 0, 0)\n\t\t</eof>\n\n\t\tlet <returndataVar> := <extractReturndataFunction>()\n\t)\");\n\n\ttempl(\"allocateUnbounded\", m_utils.allocateUnboundedFunction());\n\ttempl(\"pos\", m_context.newYulVariable());\n\ttempl(\"length\", m_context.newYulVariable());\n\tauto const eof = m_context.eofVersion().has_value();\n\ttempl(\"eof\", eof);\n\n\ttempl(\"arg\", IRVariable(*_arguments.front()).commaSeparatedList());\n\tType const& argType = type(*_arguments.front());\n\tif (argType == *TypeProvider::bytesMemory() || argType == *TypeProvider::stringMemory())\n\t\ttempl(\"needsEncoding\", false);\n\telse\n\t{\n\t\ttempl(\"needsEncoding\", true);\n\t\tABIFunctions abi(m_context.evmVersion(), m_context.eofVersion(), m_context.revertStrings(), m_context.functionCollector());\n\t\ttempl(\"encode\", abi.tupleEncoderPacked({&argType}, {TypeProvider::bytesMemory()}));\n\t}\n\n\ttempl(\"success\", IRVariable(_functionCall).tupleComponent(0).name());\n\ttempl(\"returndataVar\", IRVariable(_functionCall).tupleComponent(1).commaSeparatedList());\n\ttempl(\"extractReturndataFunction\", m_utils.extractReturndataFunction());\n\n\ttempl(\"address\", IRVariable(_functionCall.expression()).part(\"address\").name());\n\n\tif (funKind == FunctionType::Kind::BareCall)\n\t{\n\t\ttempl(\"value\", funType.valueSet() ? IRVariable(_functionCall.expression()).part(\"value\").name() : \"0\");\n\t\ttempl(\"call\", eof ? \"extcall\" : \"call\");\n\t}\n\telse\n\t{\n\t\tsolAssert(!funType.valueSet(), \"Value set for delegatecall or staticcall.\");\n\t\ttempl(\"value\", \"\");\n\t\tif (funKind == FunctionType::Kind::BareStaticCall)\n\t\t\ttempl(\"call\", eof ? \"extstaticcall\" : \"staticcall\");\n\t\telse\n\t\t\ttempl(\"call\", eof ? \"extdelegatecall\" : \"delegatecall\");\n\t}\n\n\tsolAssert(!eof || !funType.gasSet());\n\tif (funType.gasSet())\n\t\ttempl(\"gas\", IRVariable(_functionCall.expression()).part(\"gas\").name());\n\telse if (m_context.evmVersion().canOverchargeGasForCall())\n\t\t// Send all gas (requires tangerine whistle EVM)\n\t\ttempl(\"gas\", \"gas()\");\n\telse\n\t{\n\t\t// send all gas except the amount needed to execute \"SUB\" and \"CALL\"\n\t\t// @todo this retains too much gas for now, needs to be fine-tuned.\n\t\tu256 gasNeededByCaller = evmasm::GasCosts::callGas(m_context.evmVersion()) + 10;\n\t\tif (funType.valueSet())\n\t\t\tgasNeededByCaller += evmasm::GasCosts::callValueTransferGas;\n\t\tgasNeededByCaller += evmasm::GasCosts::callNewAccountGas; // we never know\n\t\ttempl(\"gas\", \"sub(gas(), \" + formatNumber(gasNeededByCaller) + \")\");\n\t}\n\n\tappendCode() << templ.render();\n}\n\nvoid IRGeneratorForStatements::assignInternalFunctionIDIfNotCalledDirectly(\n\tExpression const& _expression,\n\tFunctionDefinition const& _referencedFunction\n)\n{\n\tsolAssert(\n\t\tdynamic_cast<MemberAccess const*>(&_expression) ||\n\t\tdynamic_cast<Identifier const*>(&_expression),\n\t\t\"\"\n\t);\n\tif (_expression.annotation().calledDirectly)\n\t\treturn;\n\n\tdefine(IRVariable(_expression).part(\"functionIdentifier\")) <<\n\t\tstd::to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(&_referencedFunction)) <<\n\t\t\"\\n\";\n\tm_context.addToInternalDispatch(_referencedFunction);\n}\n\nIRVariable IRGeneratorForStatements::convert(IRVariable const& _from, Type const& _to)\n{\n\tif (_from.type() == _to)\n\t\treturn _from;\n\telse\n\t{\n\t\tIRVariable converted(m_context.newYulVariable(), _to);\n\t\tdefine(converted, _from);\n\t\treturn converted;\n\t}\n}\n\nIRVariable IRGeneratorForStatements::convertAndCleanup(IRVariable const& _from, Type const& _to)\n{\n\tIRVariable converted(m_context.newYulVariable(), _to);\n\tdefineAndCleanup(converted, _from);\n\treturn converted;\n}\n\nstd::string IRGeneratorForStatements::expressionAsType(Expression const& _expression, Type const& _to)\n{\n\tIRVariable from(_expression);\n\tif (from.type() == _to)\n\t\treturn from.commaSeparatedList();\n\telse\n\t\treturn m_utils.conversionFunction(from.type(), _to) + \"(\" + from.commaSeparatedList() + \")\";\n}\n\nstd::string IRGeneratorForStatements::expressionAsCleanedType(Expression const& _expression, Type const& _to)\n{\n\tIRVariable from(_expression);\n\tif (from.type() == _to)\n\t\treturn m_utils.cleanupFunction(_to) + \"(\" + expressionAsType(_expression, _to) + \")\";\n\telse\n\t\treturn expressionAsType(_expression, _to) ;\n}\n\nstd::ostream& IRGeneratorForStatements::define(IRVariable const& _var)\n{\n\tif (_var.type().sizeOnStack() > 0)\n\t\tappendCode() << \"let \" << _var.commaSeparatedList() << \" := \";\n\treturn appendCode(false);\n}\n\nvoid IRGeneratorForStatements::declare(IRVariable const& _var)\n{\n\tif (_var.type().sizeOnStack() > 0)\n\t\tappendCode() << \"let \" << _var.commaSeparatedList() << \"\\n\";\n}\n\nvoid IRGeneratorForStatements::declareAssign(IRVariable const& _lhs, IRVariable const& _rhs, bool _declare, bool _forceCleanup)\n{\n\tstd::string output;\n\tif (_lhs.type() == _rhs.type() && !_forceCleanup)\n\t\tfor (auto const& [stackItemName, stackItemType]: _lhs.type().stackItems())\n\t\t\tif (stackItemType)\n\t\t\t\tdeclareAssign(_lhs.part(stackItemName), _rhs.part(stackItemName), _declare);\n\t\t\telse\n\t\t\t\tappendCode() << (_declare ? \"let \": \"\") << _lhs.part(stackItemName).name() << \" := \" << _rhs.part(stackItemName).name() << \"\\n\";\n\telse\n\t{\n\t\tif (_lhs.type().sizeOnStack() > 0)\n\t\t\tappendCode() <<\n\t\t\t\t(_declare ? \"let \": \"\") <<\n\t\t\t\t_lhs.commaSeparatedList() <<\n\t\t\t\t\" := \";\n\t\tappendCode() << m_context.utils().conversionFunction(_rhs.type(), _lhs.type()) <<\n\t\t\t\"(\" <<\n\t\t\t_rhs.commaSeparatedList() <<\n\t\t\t\")\\n\";\n\t}\n}\n\nIRVariable IRGeneratorForStatements::zeroValue(Type const& _type, bool _splitFunctionTypes)\n{\n\tIRVariable irVar{IRNames::zeroValue(_type, m_context.newYulVariable()), _type};\n\tdefine(irVar) << m_utils.zeroValueFunction(_type, _splitFunctionTypes) << \"()\\n\";\n\treturn irVar;\n}\n\nvoid IRGeneratorForStatements::appendSimpleUnaryOperation(UnaryOperation const& _operation, Expression const& _expr)\n{\n\tstd::string func;\n\n\tif (_operation.getOperator() == Token::Not)\n\t\tfunc = \"iszero\";\n\telse if (_operation.getOperator() == Token::BitNot)\n\t\tfunc = \"not\";\n\telse\n\t\tsolAssert(false, \"Invalid Token!\");\n\n\tdefine(_operation) <<\n\t\tm_utils.cleanupFunction(type(_expr)) <<\n\t\t\"(\" <<\n\t\t\tfunc <<\n\t\t\t\"(\" <<\n\t\t\tIRVariable(_expr).commaSeparatedList() <<\n\t\t\t\")\" <<\n\t\t\")\\n\";\n}\n\nstd::string IRGeneratorForStatements::binaryOperation(\n\tlangutil::Token _operator,\n\tType const& _type,\n\tstd::string const& _left,\n\tstd::string const& _right\n)\n{\n\tsolAssert(\n\t\t!TokenTraits::isShiftOp(_operator),\n\t\t\"Have to use specific shift operation function for shifts.\"\n\t);\n\tstd::string fun;\n\tif (TokenTraits::isBitOp(_operator))\n\t{\n\t\tsolAssert(\n\t\t\t_type.category() == Type::Category::Integer ||\n\t\t\t_type.category() == Type::Category::FixedBytes,\n\t\t\t\"\"\n\t\t);\n\t\tswitch (_operator)\n\t\t{\n\t\tcase Token::BitOr: fun = \"or\"; break;\n\t\tcase Token::BitXor: fun = \"xor\"; break;\n\t\tcase Token::BitAnd: fun = \"and\"; break;\n\t\tdefault: break;\n\t\t}\n\t}\n\telse if (TokenTraits::isArithmeticOp(_operator))\n\t{\n\t\tsolUnimplementedAssert(\n\t\t\t_type.category() != Type::Category::FixedPoint,\n\t\t\t\"Not yet implemented - FixedPointType.\"\n\t\t);\n\t\tIntegerType const* type = dynamic_cast<IntegerType const*>(&_type);\n\t\tsolAssert(type);\n\t\tbool checked = m_context.arithmetic() == Arithmetic::Checked;\n\t\tswitch (_operator)\n\t\t{\n\t\tcase Token::Add:\n\t\t\tfun = checked ? m_utils.overflowCheckedIntAddFunction(*type) : m_utils.wrappingIntAddFunction(*type);\n\t\t\tbreak;\n\t\tcase Token::Sub:\n\t\t\tfun = checked ? m_utils.overflowCheckedIntSubFunction(*type) : m_utils.wrappingIntSubFunction(*type);\n\t\t\tbreak;\n\t\tcase Token::Mul:\n\t\t\tfun = checked ? m_utils.overflowCheckedIntMulFunction(*type) : m_utils.wrappingIntMulFunction(*type);\n\t\t\tbreak;\n\t\tcase Token::Div:\n\t\t\tfun = checked ? m_utils.overflowCheckedIntDivFunction(*type) : m_utils.wrappingIntDivFunction(*type);\n\t\t\tbreak;\n\t\tcase Token::Mod:\n\t\t\tfun = m_utils.intModFunction(*type);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tsolUnimplementedAssert(!fun.empty(), \"Type: \" + _type.toString());\n\treturn fun + \"(\" + _left + \", \" + _right + \")\\n\";\n}\n\nstd::string IRGeneratorForStatements::shiftOperation(\n\tlangutil::Token _operator,\n\tIRVariable const& _value,\n\tIRVariable const& _amountToShift\n)\n{\n\tsolUnimplementedAssert(\n\t\t_amountToShift.type().category() != Type::Category::FixedPoint &&\n\t\t_value.type().category() != Type::Category::FixedPoint,\n\t\t\"Not yet implemented - FixedPointType.\"\n\t);\n\tIntegerType const* amountType = dynamic_cast<IntegerType const*>(&_amountToShift.type());\n\tsolAssert(amountType);\n\n\tsolAssert(_operator == Token::SHL || _operator == Token::SAR);\n\n\treturn\n\t\tWhiskers(R\"(\n\t\t\t<shift>(<value>, <amount>)\n\t\t)\")\n\t\t(\"shift\",\n\t\t\t_operator == Token::SHL ?\n\t\t\tm_utils.typedShiftLeftFunction(_value.type(), *amountType) :\n\t\t\tm_utils.typedShiftRightFunction(_value.type(), *amountType)\n\t\t)\n\t\t(\"value\", _value.name())\n\t\t(\"amount\", _amountToShift.name())\n\t\t.render();\n}\n\nvoid IRGeneratorForStatements::appendAndOrOperatorCode(BinaryOperation const& _binOp)\n{\n\tlangutil::Token const op = _binOp.getOperator();\n\tsolAssert(op == Token::Or || op == Token::And);\n\n\t_binOp.leftExpression().accept(*this);\n\tsetLocation(_binOp);\n\n\tIRVariable value(_binOp);\n\tdefine(value, _binOp.leftExpression());\n\tif (op == Token::Or)\n\t\tappendCode() << \"if iszero(\" << value.name() << \") {\\n\";\n\telse\n\t\tappendCode() << \"if \" << value.name() << \" {\\n\";\n\t_binOp.rightExpression().accept(*this);\n\tsetLocation(_binOp);\n\tassign(value, _binOp.rightExpression());\n\tappendCode() << \"}\\n\";\n}\n\nvoid IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable const& _value)\n{\n\tstd::visit(\n\t\tutil::GenericVisitor{\n\t\t\t[&](IRLValue::Storage const& _storage) {\n\t\t\t\tstd::string offsetArgument;\n\t\t\t\tstd::optional<unsigned> offsetStatic;\n\n\t\t\t\tstd::visit(GenericVisitor{\n\t\t\t\t\t[&](unsigned _offset) { offsetStatic = _offset; },\n\t\t\t\t\t[&](std::string const& _offset) { offsetArgument = \", \" + _offset; }\n\t\t\t\t}, _storage.offset);\n\n\t\t\t\tappendCode() <<\n\t\t\t\t\tm_utils.updateStorageValueFunction(_value.type(), _lvalue.type, VariableDeclaration::Location::Unspecified, offsetStatic) <<\n\t\t\t\t\t\"(\" <<\n\t\t\t\t\t_storage.slot <<\n\t\t\t\t\toffsetArgument <<\n\t\t\t\t\t_value.commaSeparatedListPrefixed() <<\n\t\t\t\t\t\")\\n\";\n\t\t\t},\n\t\t\t[&](IRLValue::TransientStorage const& _transientStorage) {\n\t\t\t\tstd::string offsetArgument;\n\t\t\t\tstd::optional<unsigned> offsetStatic;\n\n\t\t\t\tstd::visit(GenericVisitor{\n\t\t\t\t\t[&](unsigned _offset) { offsetStatic = _offset; },\n\t\t\t\t\t[&](std::string const& _offset) { offsetArgument = \", \" + _offset; }\n\t\t\t\t}, _transientStorage.offset);\n\n\t\t\t\tappendCode() <<\n\t\t\t\t\tm_utils.updateStorageValueFunction(_value.type(), _lvalue.type, VariableDeclaration::Location::Transient, offsetStatic) <<\n\t\t\t\t\t\"(\" <<\n\t\t\t\t\t_transientStorage.slot <<\n\t\t\t\t\toffsetArgument <<\n\t\t\t\t\t_value.commaSeparatedListPrefixed() <<\n\t\t\t\t\t\")\\n\";\n\t\t\t},\n\t\t\t[&](IRLValue::Memory const& _memory) {\n\t\t\t\tif (_lvalue.type.isValueType())\n\t\t\t\t{\n\t\t\t\t\tIRVariable prepared(m_context.newYulVariable(), _lvalue.type);\n\t\t\t\t\tdefine(prepared, _value);\n\n\t\t\t\t\tif (_memory.byteArrayElement)\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(_lvalue.type == *TypeProvider::byte());\n\t\t\t\t\t\tappendCode() << \"mstore8(\" + _memory.address + \", byte(0, \" + prepared.commaSeparatedList() + \"))\\n\";\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tappendCode() << m_utils.writeToMemoryFunction(_lvalue.type) <<\n\t\t\t\t\t\t\t\"(\" <<\n\t\t\t\t\t\t\t_memory.address <<\n\t\t\t\t\t\t\t\", \" <<\n\t\t\t\t\t\t\tprepared.commaSeparatedList() <<\n\t\t\t\t\t\t\t\")\\n\";\n\t\t\t\t}\n\t\t\t\telse if (auto const* literalType = dynamic_cast<StringLiteralType const*>(&_value.type()))\n\t\t\t\t{\n\t\t\t\t\tstd::string writeUInt = m_utils.writeToMemoryFunction(*TypeProvider::uint256());\n\t\t\t\t\tappendCode() <<\n\t\t\t\t\t\twriteUInt <<\n\t\t\t\t\t\t\"(\" <<\n\t\t\t\t\t\t_memory.address <<\n\t\t\t\t\t\t\", \" <<\n\t\t\t\t\t\tm_utils.copyLiteralToMemoryFunction(literalType->value()) + \"()\" <<\n\t\t\t\t\t\t\")\\n\";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsolAssert(_lvalue.type.sizeOnStack() == 1);\n\t\t\t\t\tauto const* valueReferenceType = dynamic_cast<ReferenceType const*>(&_value.type());\n\t\t\t\t\tsolAssert(valueReferenceType);\n\t\t\t\t\tif (valueReferenceType->dataStoredIn(DataLocation::Memory))\n\t\t\t\t\t\tappendCode() << \"mstore(\" + _memory.address + \", \" + _value.part(\"mpos\").name() + \")\\n\";\n\t\t\t\t\telse\n\t\t\t\t\t\tappendCode() << \"mstore(\" + _memory.address + \", \" + m_utils.conversionFunction(_value.type(), _lvalue.type) + \"(\" + _value.commaSeparatedList() + \"))\\n\";\n\t\t\t\t}\n\t\t\t},\n\t\t\t[&](IRLValue::Stack const& _stack) { assign(_stack.variable, _value); },\n\t\t\t[&](IRLValue::Immutable const& _immutable)\n\t\t\t{\n\t\t\t\tsolUnimplementedAssert(_lvalue.type.isValueType());\n\t\t\t\tsolUnimplementedAssert(_lvalue.type.sizeOnStack() == 1);\n\t\t\t\tsolAssert(_lvalue.type == *_immutable.variable->type());\n\t\t\t\tsize_t memOffset = m_context.immutableMemoryOffset(*_immutable.variable);\n\n\t\t\t\tIRVariable prepared(m_context.newYulVariable(), _lvalue.type);\n\t\t\t\tdefine(prepared, _value);\n\n\t\t\t\tappendCode() << \"mstore(\" << std::to_string(memOffset) << \", \" << prepared.commaSeparatedList() << \")\\n\";\n\t\t\t},\n\t\t\t[&](IRLValue::Tuple const& _tuple) {\n\t\t\t\tauto components = std::move(_tuple.components);\n\t\t\t\tfor (size_t i = 0; i < components.size(); i++)\n\t\t\t\t{\n\t\t\t\t\tsize_t idx = components.size() - i - 1;\n\t\t\t\t\tif (components[idx])\n\t\t\t\t\t\twriteToLValue(*components[idx], _value.tupleComponent(idx));\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t_lvalue.kind\n\t);\n}\n\nIRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue)\n{\n\tIRVariable result{m_context.newYulVariable(), _lvalue.type};\n\tstd::visit(GenericVisitor{\n\t\t[&](IRLValue::Storage const& _storage) {\n\t\t\tif (!_lvalue.type.isValueType())\n\t\t\t\tdefine(result) << _storage.slot << \"\\n\";\n\t\t\telse if (std::holds_alternative<std::string>(_storage.offset))\n\t\t\t\tdefine(result) <<\n\t\t\t\t\tm_utils.readFromStorageDynamic(_lvalue.type, true, VariableDeclaration::Location::Unspecified) <<\n\t\t\t\t\t\"(\" <<\n\t\t\t\t\t_storage.slot <<\n\t\t\t\t\t\", \" <<\n\t\t\t\t\tstd::get<std::string>(_storage.offset) <<\n\t\t\t\t\t\")\\n\";\n\t\t\telse\n\t\t\t\tdefine(result) <<\n\t\t\t\t\tm_utils.readFromStorage(_lvalue.type, std::get<unsigned>(_storage.offset), true, VariableDeclaration::Location::Unspecified) <<\n\t\t\t\t\t\"(\" <<\n\t\t\t\t\t_storage.slot <<\n\t\t\t\t\t\")\\n\";\n\t\t},\n\t\t[&](IRLValue::TransientStorage const& _transientStorage) {\n\t\t\tif (!_lvalue.type.isValueType())\n\t\t\t\tdefine(result) << _transientStorage.slot << \"\\n\";\n\t\t\telse if (std::holds_alternative<std::string>(_transientStorage.offset))\n\t\t\t\tdefine(result) <<\n\t\t\t\t\tm_utils.readFromStorageDynamic(_lvalue.type, true, VariableDeclaration::Location::Transient) <<\n\t\t\t\t\t\"(\" <<\n\t\t\t\t\t_transientStorage.slot <<\n\t\t\t\t\t\", \" <<\n\t\t\t\t\tstd::get<std::string>(_transientStorage.offset) <<\n\t\t\t\t\t\")\\n\";\n\t\t\telse\n\t\t\t\tdefine(result) <<\n\t\t\t\t\tm_utils.readFromStorage(_lvalue.type, std::get<unsigned>(_transientStorage.offset), true, VariableDeclaration::Location::Transient) <<\n\t\t\t\t\t\"(\" <<\n\t\t\t\t\t_transientStorage.slot <<\n\t\t\t\t\t\")\\n\";\n\t\t},\n\t\t[&](IRLValue::Memory const& _memory) {\n\t\t\tif (_lvalue.type.isValueType())\n\t\t\t\tdefine(result) <<\n\t\t\t\t\tm_utils.readFromMemory(_lvalue.type) <<\n\t\t\t\t\t\"(\" <<\n\t\t\t\t\t_memory.address <<\n\t\t\t\t\t\")\\n\";\n\t\t\telse\n\t\t\t\tdefine(result) << \"mload(\" << _memory.address << \")\\n\";\n\t\t},\n\t\t[&](IRLValue::Stack const& _stack) {\n\t\t\tdefine(result, _stack.variable);\n\t\t},\n\t\t[&](IRLValue::Immutable const& _immutable) {\n\t\t\tsolUnimplementedAssert(_lvalue.type.isValueType());\n\t\t\tsolUnimplementedAssert(_lvalue.type.sizeOnStack() == 1);\n\t\t\tsolAssert(_lvalue.type == *_immutable.variable->type());\n\t\t\tif (m_context.executionContext() == IRGenerationContext::ExecutionContext::Creation)\n\t\t\t{\n\t\t\t\tstd::string readFunction = m_utils.readFromMemory(*_immutable.variable->type());\n\t\t\t\tdefine(result) <<\n\t\t\t\t\treadFunction <<\n\t\t\t\t\t\"(\" <<\n\t\t\t\t\tstd::to_string(m_context.immutableMemoryOffset(*_immutable.variable)) <<\n\t\t\t\t\t\")\\n\";\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!m_context.eofVersion().has_value())\n\t\t\t\t\tdefine(result) << \"loadimmutable(\\\"\" << std::to_string(_immutable.variable->id()) << \"\\\")\\n\";\n\t\t\t\telse\n\t\t\t\t\tdefine(result) << \"auxdataloadn(\" << std::to_string(m_context.immutableMemoryOffsetRelative(*_immutable.variable)) << \")\\n\";\n\t\t\t}\n\t\t},\n\t\t[&](IRLValue::Tuple const&) {\n\t\t\tsolAssert(false, \"Attempted to read from tuple lvalue.\");\n\t\t}\n\t}, _lvalue.kind);\n\treturn result;\n}\n\nvoid IRGeneratorForStatements::setLValue(Expression const& _expression, IRLValue _lvalue)\n{\n\tsolAssert(!m_currentLValue);\n\n\tif (_expression.annotation().willBeWrittenTo)\n\t{\n\t\tm_currentLValue.emplace(std::move(_lvalue));\n\t\tif (_lvalue.type.dataStoredIn(DataLocation::CallData))\n\t\t\tsolAssert(std::holds_alternative<IRLValue::Stack>(_lvalue.kind));\n\t}\n\telse\n\t\t// Only define the expression, if it will not be written to.\n\t\tdefine(_expression, readFromLValue(_lvalue));\n}\n\nvoid IRGeneratorForStatements::generateLoop(\n\tStatement const& _body,\n\tExpression const* _conditionExpression,\n\tStatement const*  _initExpression,\n\tExpressionStatement const* _loopExpression,\n\tbool _isDoWhile,\n\tbool _isSimpleCounterLoop\n)\n{\n\tstd::string firstRun;\n\n\tif (_isDoWhile)\n\t{\n\t\tsolAssert(_conditionExpression, \"Expected condition for doWhile\");\n\t\tfirstRun = m_context.newYulVariable();\n\t\tappendCode() << \"let \" << firstRun << \" := 1\\n\";\n\t}\n\n\tappendCode() << \"for {\\n\";\n\tif (_initExpression)\n\t\t_initExpression->accept(*this);\n\tappendCode() << \"} 1 {\\n\";\n\tif (_loopExpression)\n\t{\n\t\tArithmetic previousArithmetic = m_context.arithmetic();\n\t\tif (m_optimiserSettings.simpleCounterForLoopUncheckedIncrement && _isSimpleCounterLoop)\n\t\t\tm_context.setArithmetic(Arithmetic::Wrapping);\n\t\t_loopExpression->accept(*this);\n\t\tm_context.setArithmetic(previousArithmetic);\n\t}\n\tappendCode() << \"}\\n\";\n\tappendCode() << \"{\\n\";\n\n\tif (_conditionExpression)\n\t{\n\t\tif (_isDoWhile)\n\t\t\tappendCode() << \"if iszero(\" << firstRun << \") {\\n\";\n\n\t\t_conditionExpression->accept(*this);\n\t\tappendCode() <<\n\t\t\t\"if iszero(\" <<\n\t\t\texpressionAsType(*_conditionExpression, *TypeProvider::boolean()) <<\n\t\t\t\") { break }\\n\";\n\n\t\tif (_isDoWhile)\n\t\t\tappendCode() << \"}\\n\" << firstRun << \" := 0\\n\";\n\t}\n\n\t_body.accept(*this);\n\n\tappendCode() << \"}\\n\";\n}\n\nType const& IRGeneratorForStatements::type(Expression const& _expression)\n{\n\tsolAssert(_expression.annotation().type, \"Type of expression not set.\");\n\treturn *_expression.annotation().type;\n}\n\nbool IRGeneratorForStatements::visit(TryStatement const& _tryStatement)\n{\n\tExpression const& externalCall = _tryStatement.externalCall();\n\texternalCall.accept(*this);\n\tsetLocation(_tryStatement);\n\n\tappendCode() << \"switch iszero(\" << IRNames::trySuccessConditionVariable(externalCall) << \")\\n\";\n\n\tappendCode() << \"case 0 { // success case\\n\";\n\tTryCatchClause const& successClause = *_tryStatement.clauses().front();\n\tif (successClause.parameters())\n\t{\n\t\tsize_t i = 0;\n\t\tfor (ASTPointer<VariableDeclaration> const& varDecl: successClause.parameters()->parameters())\n\t\t{\n\t\t\tsolAssert(varDecl);\n\t\t\tdefine(m_context.addLocalVariable(*varDecl),\n\t\t\t\tsuccessClause.parameters()->parameters().size() == 1 ?\n\t\t\t\tIRVariable(externalCall) :\n\t\t\t\tIRVariable(externalCall).tupleComponent(i++)\n\t\t\t);\n\t\t}\n\t}\n\n\tsuccessClause.block().accept(*this);\n\tsetLocation(_tryStatement);\n\tappendCode() << \"}\\n\";\n\n\tappendCode() << \"default { // failure case\\n\";\n\thandleCatch(_tryStatement);\n\tappendCode() << \"}\\n\";\n\n\treturn false;\n}\n\nvoid IRGeneratorForStatements::handleCatch(TryStatement const& _tryStatement)\n{\n\tsetLocation(_tryStatement);\n\tstd::string const runFallback = m_context.newYulVariable();\n\tappendCode() << \"let \" << runFallback << \" := 1\\n\";\n\n\t// This function returns zero on \"short returndata\". We have to add a success flag\n\t// once we implement custom error codes.\n\tif (_tryStatement.errorClause() || _tryStatement.panicClause())\n\t\tappendCode() << \"switch \" << m_utils.returnDataSelectorFunction() << \"()\\n\";\n\n\tif (TryCatchClause const* errorClause = _tryStatement.errorClause())\n\t{\n\t\tappendCode() << \"case \" << selectorFromSignatureU32(\"Error(string)\") << \" {\\n\";\n\t\tsetLocation(*errorClause);\n\t\tstd::string const dataVariable = m_context.newYulVariable();\n\t\tappendCode() << \"let \" << dataVariable << \" := \" << m_utils.tryDecodeErrorMessageFunction() << \"()\\n\";\n\t\tappendCode() << \"if \" << dataVariable << \" {\\n\";\n\t\tappendCode() << runFallback << \" := 0\\n\";\n\t\tif (errorClause->parameters())\n\t\t{\n\t\t\tsolAssert(errorClause->parameters()->parameters().size() == 1);\n\t\t\tIRVariable const& var = m_context.addLocalVariable(*errorClause->parameters()->parameters().front());\n\t\t\tdefine(var) << dataVariable << \"\\n\";\n\t\t}\n\t\terrorClause->accept(*this);\n\t\tsetLocation(*errorClause);\n\t\tappendCode() << \"}\\n\";\n\t\tsetLocation(_tryStatement);\n\t\tappendCode() << \"}\\n\";\n\t}\n\tif (TryCatchClause const* panicClause = _tryStatement.panicClause())\n\t{\n\t\tappendCode() << \"case \" << selectorFromSignatureU32(\"Panic(uint256)\") << \" {\\n\";\n\t\tsetLocation(*panicClause);\n\t\tstd::string const success = m_context.newYulVariable();\n\t\tstd::string const code = m_context.newYulVariable();\n\t\tappendCode() << \"let \" << success << \", \" << code << \" := \" << m_utils.tryDecodePanicDataFunction() << \"()\\n\";\n\t\tappendCode() << \"if \" << success << \" {\\n\";\n\t\tappendCode() << runFallback << \" := 0\\n\";\n\t\tif (panicClause->parameters())\n\t\t{\n\t\t\tsolAssert(panicClause->parameters()->parameters().size() == 1);\n\t\t\tIRVariable const& var = m_context.addLocalVariable(*panicClause->parameters()->parameters().front());\n\t\t\tdefine(var) << code << \"\\n\";\n\t\t}\n\t\tpanicClause->accept(*this);\n\t\tsetLocation(*panicClause);\n\t\tappendCode() << \"}\\n\";\n\t\tsetLocation(_tryStatement);\n\t\tappendCode() << \"}\\n\";\n\t}\n\n\tsetLocation(_tryStatement);\n\tappendCode() << \"if \" << runFallback << \" {\\n\";\n\tif (_tryStatement.fallbackClause())\n\t\thandleCatchFallback(*_tryStatement.fallbackClause());\n\telse\n\t\tappendCode() << m_utils.forwardingRevertFunction() << \"()\\n\";\n\tsetLocation(_tryStatement);\n\tappendCode() << \"}\\n\";\n}\n\nvoid IRGeneratorForStatements::handleCatchFallback(TryCatchClause const& _fallback)\n{\n\tsetLocation(_fallback);\n\tif (_fallback.parameters())\n\t{\n\t\tsolAssert(m_context.evmVersion().supportsReturndata());\n\t\tsolAssert(\n\t\t\t_fallback.parameters()->parameters().size() == 1 &&\n\t\t\t_fallback.parameters()->parameters().front() &&\n\t\t\t*_fallback.parameters()->parameters().front()->annotation().type == *TypeProvider::bytesMemory(),\n\t\t\t\"\"\n\t\t);\n\n\t\tVariableDeclaration const& paramDecl = *_fallback.parameters()->parameters().front();\n\t\tdefine(m_context.addLocalVariable(paramDecl)) << m_utils.extractReturndataFunction() << \"()\\n\";\n\t}\n\t_fallback.accept(*this);\n}\n\nvoid IRGeneratorForStatements::revertWithError(\n\tstd::string const& _signature,\n\tstd::vector<Type const*> const& _parameterTypes,\n\tstd::vector<ASTPointer<Expression const>> const& _errorArguments\n)\n{\n\tappendCode() << m_utils.revertWithError(\n\t\t_signature,\n\t\t_parameterTypes,\n\t\t_errorArguments,\n\t\tm_context.newYulVariable(),\n\t\tm_context.newYulVariable()\n\t);\n}\n\nbool IRGeneratorForStatements::visit(TryCatchClause const& _clause)\n{\n\t_clause.block().accept(*this);\n\treturn false;\n}\n\nstd::string IRGeneratorForStatements::linkerSymbol(ContractDefinition const& _library) const\n{\n\tsolAssert(_library.isLibrary());\n\treturn \"linkersymbol(\" + util::escapeAndQuoteString(_library.fullyQualifiedName()) + \")\";\n}\n"
  },
  {
    "path": "libsolidity/codegen/ir/IRGeneratorForStatements.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that translates Solidity code into Yul at statement level and below.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/codegen/ir/IRLValue.h>\n#include <libsolidity/codegen/ir/IRVariable.h>\n#include <libsolidity/interface/OptimiserSettings.h>\n\n#include <functional>\n\nnamespace solidity::frontend\n{\n\nclass IRGenerationContext;\nclass YulUtilFunctions;\n\n/**\n * Base class for the statement generator.\n * Encapsulates access to the yul code stream and handles source code locations.\n */\nclass IRGeneratorForStatementsBase: public ASTConstVisitor\n{\npublic:\n\tIRGeneratorForStatementsBase(IRGenerationContext& _context):\n\t\tm_context(_context)\n\t{}\n\n\tvirtual std::string code() const;\n\tstd::ostringstream& appendCode(bool _addLocationComment = true);\nprotected:\n\tvoid setLocation(ASTNode const& _node);\n\tlangutil::SourceLocation m_currentLocation = {};\n\tlangutil::SourceLocation m_lastLocation = {};\n\tIRGenerationContext& m_context;\nprivate:\n\tstd::ostringstream m_code;\n};\n\n/**\n * Component that translates Solidity's AST into Yul at statement level and below.\n * It is an AST visitor that appends to an internal string buffer.\n */\nclass IRGeneratorForStatements: public IRGeneratorForStatementsBase\n{\npublic:\n\tIRGeneratorForStatements(\n\t\tIRGenerationContext& _context,\n\t\tYulUtilFunctions& _utils,\n\t\tOptimiserSettings& _optimiserSettings,\n\t\tstd::function<std::string()> _placeholderCallback = {}\n\t):\n\t\tIRGeneratorForStatementsBase(_context),\n\t\tm_placeholderCallback(std::move(_placeholderCallback)),\n\t\tm_utils(_utils),\n\t\tm_optimiserSettings(_optimiserSettings)\n\t{}\n\n\tstd::string code() const override;\n\n\t/// Generate the code for the statements in the block;\n\tvoid generate(Block const& _block);\n\n\t/// Generates code to initialize the given state variable.\n\tvoid initializeStateVar(VariableDeclaration const& _varDecl);\n\t/// Generates code to initialize the given local variable.\n\tvoid initializeLocalVar(VariableDeclaration const& _varDecl);\n\n\t/// Calculates expression's value and returns variable where it was stored\n\tIRVariable evaluateExpression(Expression const& _expression, Type const& _to);\n\n\t/// Defines @a _var using the value of @a _value while performing type conversions, if required.\n\tvoid define(IRVariable const& _var, IRVariable const& _value)\n\t{\n\t\tbool _declare = true;\n\t\tdeclareAssign(_var, _value, _declare);\n\t}\n\n\t/// Defines @a _var using the value of @a _value while performing type conversions, if required.\n\t/// It also cleans the value of the variable.\n\tvoid defineAndCleanup(IRVariable const& _var, IRVariable const& _value)\n\t{\n\t\tbool _forceCleanup = true;\n\t\tbool _declare = true;\n\t\tdeclareAssign(_var, _value, _declare, _forceCleanup);\n\t}\n\n\t/// @returns the name of a function that computes the value of the given constant\n\t/// and also generates the function.\n\tstd::string constantValueFunction(VariableDeclaration const& _constant);\n\n\tvoid endVisit(VariableDeclarationStatement const& _variableDeclaration) override;\n\tbool visit(Conditional const& _conditional) override;\n\tbool visit(Assignment const& _assignment) override;\n\tbool visit(TupleExpression const& _tuple) override;\n\tvoid endVisit(PlaceholderStatement const& _placeholder) override;\n\tbool visit(Block const& _block) override;\n\tvoid endVisit(Block const& _block) override;\n\tbool visit(IfStatement const& _ifStatement) override;\n\tbool visit(ForStatement const& _forStatement) override;\n\tbool visit(WhileStatement const& _whileStatement) override;\n\tbool visit(Continue const& _continueStatement) override;\n\tbool visit(Break const& _breakStatement) override;\n\tvoid endVisit(Return const& _return) override;\n\tbool visit(UnaryOperation const& _unaryOperation) override;\n\tbool visit(BinaryOperation const& _binOp) override;\n\tvoid endVisit(FunctionCall const& _funCall) override;\n\tvoid endVisit(FunctionCallOptions const& _funCallOptions) override;\n\tbool visit(MemberAccess const& _memberAccess) override;\n\tvoid endVisit(MemberAccess const& _memberAccess) override;\n\tbool visit(InlineAssembly const& _inlineAsm) override;\n\tvoid endVisit(IndexAccess const& _indexAccess) override;\n\tvoid endVisit(IndexRangeAccess const& _indexRangeAccess) override;\n\tvoid endVisit(Identifier const& _identifier) override;\n\tbool visit(Literal const& _literal) override;\n\tvoid endVisit(RevertStatement const& _revertStatement) override;\n\n\tbool visit(TryStatement const& _tryStatement) override;\n\tbool visit(TryCatchClause const& _tryCatchClause) override;\n\nprivate:\n\t/// Handles all catch cases of a try statement, except the success-case.\n\tvoid handleCatch(TryStatement const& _tryStatement);\n\tvoid handleCatchFallback(TryCatchClause const& _fallback);\n\n\t/// Generates code to revert with an error. The error arguments are assumed to\n\t/// be already evaluated and available in local IRVariables, but not yet\n\t/// converted.\n\tvoid revertWithError(\n\t\tstd::string const& _signature,\n\t\tstd::vector<Type const*> const& _parameterTypes,\n\t\tstd::vector<ASTPointer<Expression const>> const& _errorArguments\n\t);\n\n\tvoid handleVariableReference(\n\t\tVariableDeclaration const& _variable,\n\t\tExpression const& _referencingExpression\n\t);\n\n\t/// Appends code to call an external function with the given arguments.\n\t/// All involved expressions have already been visited.\n\tvoid appendExternalFunctionCall(\n\t\tFunctionCall const& _functionCall,\n\t\tstd::vector<ASTPointer<Expression const>> const& _arguments\n\t);\n\n\t/// Appends code for .call / .delegatecall / .staticcall.\n\t/// All involved expressions have already been visited.\n\tvoid appendBareCall(\n\t\tFunctionCall const& _functionCall,\n\t\tstd::vector<ASTPointer<Expression const>> const& _arguments\n\t);\n\n\t/// Requests and assigns the internal ID of the referenced function to the referencing\n\t/// expression and adds the function to the internal dispatch.\n\t/// If the function is called right away, it does nothing.\n\tvoid assignInternalFunctionIDIfNotCalledDirectly(\n\t\tExpression const& _expression,\n\t\tFunctionDefinition const& _referencedFunction\n\t);\n\n\t/// Generates the required conversion code and @returns an IRVariable referring to the value of @a _variable\n\tIRVariable convert(IRVariable const& _variable, Type const& _to);\n\n\t/// Generates the required conversion code and @returns an IRVariable referring to the value of @a _variable\n\t/// It also cleans the value of the variable.\n\tIRVariable convertAndCleanup(IRVariable const& _from, Type const& _to);\n\n\t/// @returns a Yul expression representing the current value of @a _expression,\n\t/// converted to type @a _to if it does not yet have that type.\n\tstd::string expressionAsType(Expression const& _expression, Type const& _to);\n\n\t/// @returns a Yul expression representing the current value of @a _expression,\n\t/// converted to type @a _to if it does not yet have that type.\n\t/// It also cleans the value, in case it already has type @a _to.\n\tstd::string expressionAsCleanedType(Expression const& _expression, Type const& _to);\n\n\t/// @returns an output stream that can be used to define @a _var using a function call or\n\t/// single stack slot expression.\n\tstd::ostream& define(IRVariable const& _var);\n\n\t/// Assigns @a _var to the value of @a _value while performing type conversions, if required.\n\tvoid assign(IRVariable const& _var, IRVariable const& _value) { declareAssign(_var, _value, false); }\n\t/// Declares variable @a _var.\n\tvoid declare(IRVariable const& _var);\n\n\tvoid declareAssign(IRVariable const& _var, IRVariable const& _value, bool _define, bool _forceCleanup = false);\n\n\t/// @returns an IRVariable with the zero\n\t/// value of @a _type.\n\t/// @param _splitFunctionTypes if false, returns two zeroes\n\tIRVariable zeroValue(Type const& _type, bool _splitFunctionTypes = true);\n\n\tvoid appendAndOrOperatorCode(BinaryOperation const& _binOp);\n\tvoid appendSimpleUnaryOperation(UnaryOperation const& _operation, Expression const& _expr);\n\n\t/// @returns code to perform the given binary operation in the given type on the two values.\n\tstd::string binaryOperation(\n\t\tlangutil::Token _op,\n\t\tType const& _type,\n\t\tstd::string const& _left,\n\t\tstd::string const& _right\n\t);\n\n\t/// @returns code to perform the given shift operation.\n\t/// The operation itself will be performed in the type of the value,\n\t/// while the amount to shift can have its own type.\n\tstd::string shiftOperation(langutil::Token _op, IRVariable const& _value, IRVariable const& _shiftAmount);\n\n\t/// Assigns the value of @a _value to the lvalue @a _lvalue.\n\tvoid writeToLValue(IRLValue const& _lvalue, IRVariable const& _value);\n\n\t/// @returns a fresh IR variable containing the value of the lvalue @a _lvalue.\n\tIRVariable readFromLValue(IRLValue const& _lvalue);\n\n\t/// Stores the given @a _lvalue in m_currentLValue, if it will be written to (willBeWrittenTo). Otherwise\n\t/// defines the expression @a _expression by reading the value from @a _lvalue.\n\tvoid setLValue(Expression const& _expression, IRLValue _lvalue);\n\tvoid generateLoop(\n\t\tStatement const& _body,\n\t\tExpression const* _conditionExpression,\n\t\tStatement const*  _initExpression = nullptr,\n\t\tExpressionStatement const* _loopExpression = nullptr,\n\t\tbool _isDoWhile = false,\n\t\tbool _isSimpleCounterLoop = false\n\t);\n\n\tstatic Type const& type(Expression const& _expression);\n\n\tstd::string linkerSymbol(ContractDefinition const& _library) const;\n\n\tstd::function<std::string()> m_placeholderCallback;\n\tYulUtilFunctions& m_utils;\n\tstd::optional<IRLValue> m_currentLValue;\n\tOptimiserSettings m_optimiserSettings;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ir/IRLValue.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Classes that store locations of lvalues.\n */\n\n#pragma once\n\n#include <libsolidity/codegen/ir/IRVariable.h>\n#include <variant>\n\nnamespace solidity::frontend\n{\n\nclass Type;\n\nstruct IRLValue\n{\n\tType const& type;\n\tstruct Stack\n\t{\n\t\tIRVariable variable;\n\t};\n\tstruct Immutable\n\t{\n\t\tVariableDeclaration const* variable = nullptr;\n\t};\n\tstruct GenericStorage\n\t{\n\t\tstd::string const slot;\n\t\t/// unsigned: Used when the offset is known at compile time, uses optimized\n\t\t///           functions\n\t\t/// string: Used when the offset is determined at run time\n\t\tstd::variant<std::string, unsigned> const offset;\n\t\tstd::string offsetString() const\n\t\t{\n\t\t\tif (std::holds_alternative<unsigned>(offset))\n\t\t\t\treturn std::to_string(std::get<unsigned>(offset));\n\t\t\telse\n\t\t\t\treturn std::get<std::string>(offset);\n\t\t}\n\t};\n\tstruct Storage : public GenericStorage {};\n\tstruct TransientStorage : public GenericStorage {};\n\tstruct Memory\n\t{\n\t\tstd::string const address;\n\t\tbool byteArrayElement = false;\n\t};\n\tstruct Tuple\n\t{\n\t\tstd::vector<std::optional<IRLValue>> components;\n\t};\n\tstd::variant<Stack, Immutable, Storage, TransientStorage, Memory, Tuple> kind;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ir/IRVariable.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/codegen/ir/Common.h>\n#include <libsolidity/codegen/ir/IRVariable.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolutil/StringUtils.h>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\nusing namespace solidity::util;\n\nIRVariable::IRVariable(std::string _baseName, Type const& _type):\n\tm_baseName(std::move(_baseName)), m_type(_type)\n{\n}\n\nIRVariable::IRVariable(VariableDeclaration const& _declaration):\n\tIRVariable(IRNames::localVariable(_declaration), *_declaration.annotation().type)\n{\n\tsolAssert(!_declaration.isStateVariable(), \"\");\n}\n\nIRVariable::IRVariable(Expression const& _expression):\n\tIRVariable(IRNames::localVariable(_expression), *_expression.annotation().type)\n{\n}\n\nIRVariable IRVariable::part(std::string const& _name) const\n{\n\tfor (auto const& [itemName, itemType]: m_type.stackItems())\n\t\tif (itemName == _name)\n\t\t{\n\t\t\tsolAssert(itemName.empty() || itemType, \"\");\n\t\t\treturn IRVariable{suffixedName(itemName), itemType ? *itemType : m_type};\n\t\t}\n\tsolAssert(false, \"Invalid stack item name: \" + _name);\n}\n\nbool IRVariable::hasPart(std::string const& _name) const\n{\n\tfor (auto const& [itemName, itemType]: m_type.stackItems())\n\t\tif (itemName == _name)\n\t\t{\n\t\t\tsolAssert(itemName.empty() || itemType, \"\");\n\t\t\treturn true;\n\t\t}\n\treturn false;\n}\n\nstd::vector<std::string> IRVariable::stackSlots() const\n{\n\tstd::vector<std::string> result;\n\tfor (auto const& [itemName, itemType]: m_type.stackItems())\n\t\tif (itemType)\n\t\t{\n\t\t\tsolAssert(!itemName.empty(), \"\");\n\t\t\tsolAssert(m_type != *itemType, \"\");\n\t\t\tresult += IRVariable{suffixedName(itemName), *itemType}.stackSlots();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(itemName.empty(), \"\");\n\t\t\tresult.emplace_back(m_baseName);\n\t\t}\n\treturn result;\n}\n\nstd::string IRVariable::commaSeparatedList() const\n{\n\treturn joinHumanReadable(stackSlots());\n}\n\nstd::string IRVariable::commaSeparatedListPrefixed() const\n{\n\treturn joinHumanReadablePrefixed(stackSlots());\n}\n\nstd::string IRVariable::name() const\n{\n\tsolAssert(m_type.sizeOnStack() == 1, \"\");\n\tauto const& [itemName, type] = m_type.stackItems().front();\n\tsolAssert(!type, \"Expected null type for name \" + itemName);\n\treturn suffixedName(itemName);\n}\n\nIRVariable IRVariable::tupleComponent(size_t _i) const\n{\n\tsolAssert(\n\t\tm_type.category() == Type::Category::Tuple,\n\t\t\"Requested tuple component of non-tuple IR variable.\"\n\t);\n\treturn part(IRNames::tupleComponent(_i));\n}\n\nstd::string IRVariable::suffixedName(std::string const& _suffix) const\n{\n\tif (_suffix.empty())\n\t\treturn m_baseName;\n\telse\n\t\treturn m_baseName + '_' + _suffix;\n}\n"
  },
  {
    "path": "libsolidity/codegen/ir/IRVariable.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <optional>\n#include <string>\n#include <vector>\n\nnamespace solidity::frontend\n{\n\nclass VariableDeclaration;\nclass Type;\nclass Expression;\n\n/**\n * An IRVariable refers to a set of yul variables that correspond to the stack layout of a Solidity variable or expression\n * of a specific Solidity type. If the Solidity type occupies a single stack slot, the IRVariable refers to a single yul variable.\n * Otherwise the set of yul variables it refers to is (recursively) determined by  @see ``Type::stackItems()``.\n * For example, an IRVariable referring to a dynamically sized calldata array will consist of two parts named\n * ``offset`` and ``length``, whereas an IRVariable referring to a statically sized calldata type, a storage reference\n * type or a memory reference type will contain a single unnamed part containing an offset. An IRVariable referring to\n * a value type will contain a single unnamed part containing the value, an IRVariable referring to a tuple will\n * have the typed tuple components as parts.\n */\nclass IRVariable\n{\npublic:\n\t/// IR variable with explicit base name @a _baseName and type @a _type.\n\tIRVariable(std::string _baseName, Type const& _type);\n\t/// IR variable referring to the declaration @a _decl.\n\texplicit IRVariable(VariableDeclaration const& _decl);\n\t/// IR variable referring to the expression @a _expr.\n\t/// Intentionally not defined as explicit to allow defining IRVariables for expressions directly via implicit conversions.\n\tIRVariable(Expression const& _expression);\n\n\t/// @returns the name of the variable, if it occupies a single stack slot (otherwise throws).\n\tstd::string name() const;\n\n\t/// @returns a comma-separated list of the stack slots of the variable.\n\tstd::string commaSeparatedList() const;\n\n\t/// @returns a comma-separated list of the stack slots of the variable that is\n\t/// prefixed with a comma, unless it is empty.\n\tstd::string commaSeparatedListPrefixed() const;\n\n\t/// @returns an IRVariable referring to the tuple component @a _i of a tuple variable.\n\tIRVariable tupleComponent(std::size_t _i) const;\n\n\t/// @returns the type of the variable.\n\tType const& type() const { return m_type; }\n\n\t/// @returns an IRVariable referring to the stack component @a _slot of the variable.\n\t/// @a _slot must be among the stack slots in ``m_type.stackItems()``.\n\t/// The returned IRVariable is itself typed with the type of the stack slot as defined\n\t/// in ``m_type.stackItems()`` and may again occupy multiple stack slots.\n\tIRVariable part(std::string const& _slot) const;\n\n\t/// @returns true if variable contains @a _name component\n\t/// @a _name name of the component that is being checked\n\tbool hasPart(std::string const& _name) const;\n\n\t/// @returns a vector containing the names of the stack slots of the variable.\n\tstd::vector<std::string> stackSlots() const;\n\nprivate:\n\t/// @returns a name consisting of the base name appended with an underscore and @æ _suffix,\n\t/// unless @a _suffix is empty, in which case the base name itself is returned.\n\tstd::string suffixedName(std::string const& _suffix) const;\n\tstd::string m_baseName;\n\tType const& m_type;\n};\n\n\n}\n"
  },
  {
    "path": "libsolidity/codegen/ir/README.md",
    "content": "# The Solidity to Yul Code Generator\n\nThis directory contains the new experimental code generator that\ncompiles Solidity to an intermediate representation in Yul\nwith EVM dialect.\n\nThe main semantic differences to the legacy code generator are the following:\n\n- Arithmetic operations cause a failing assertion if the result is not in range.\n- Resizing a storage array to a length larger than 2**64 causes a failing assertion.\n"
  },
  {
    "path": "libsolidity/experimental/analysis/Analysis.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/experimental/analysis/Analysis.h>\n#include <libsolidity/experimental/analysis/DebugWarner.h>\n#include <libsolidity/experimental/analysis/FunctionDependencyAnalysis.h>\n#include <libsolidity/experimental/analysis/SyntaxRestrictor.h>\n#include <libsolidity/experimental/analysis/TypeClassRegistration.h>\n#include <libsolidity/experimental/analysis/TypeInference.h>\n#include <libsolidity/experimental/analysis/TypeRegistration.h>\n\nusing namespace solidity::langutil;\nusing namespace solidity::frontend::experimental;\n\n// TODO: creating all of them for all nodes up front may be wasteful, we should improve the mechanism.\nstruct Analysis::AnnotationContainer\n{\n\tTypeClassRegistration::Annotation typeClassRegistrationAnnotation;\n\tTypeRegistration::Annotation typeRegistrationAnnotation;\n\tTypeInference::Annotation typeInferenceAnnotation;\n};\n\nstruct Analysis::GlobalAnnotationContainer\n{\n\tFunctionDependencyAnalysis::GlobalAnnotation functionDependencyGraphAnnotation;\n\tTypeClassRegistration::GlobalAnnotation typeClassRegistrationAnnotation;\n\tTypeRegistration::GlobalAnnotation typeRegistrationAnnotation;\n\tTypeInference::GlobalAnnotation typeInferenceAnnotation;\n};\n\ntemplate<>\nTypeClassRegistration::Annotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeClassRegistration>::get(ASTNode const& _node)\n{\n\treturn analysis.annotationContainer(_node).typeClassRegistrationAnnotation;\n}\n\ntemplate<>\nTypeClassRegistration::GlobalAnnotation const& solidity::frontend::experimental::detail::ConstAnnotationFetcher<TypeClassRegistration>::get() const\n{\n\treturn analysis.annotationContainer().typeClassRegistrationAnnotation;\n}\n\ntemplate<>\nTypeClassRegistration::GlobalAnnotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeClassRegistration>::get()\n{\n\treturn analysis.annotationContainer().typeClassRegistrationAnnotation;\n}\n\ntemplate<>\nTypeClassRegistration::Annotation const& solidity::frontend::experimental::detail::ConstAnnotationFetcher<TypeClassRegistration>::get(ASTNode const& _node) const\n{\n\treturn analysis.annotationContainer(_node).typeClassRegistrationAnnotation;\n}\n\ntemplate<>\nFunctionDependencyAnalysis::GlobalAnnotation const& solidity::frontend::experimental::detail::ConstAnnotationFetcher<FunctionDependencyAnalysis>::get() const\n{\n\treturn analysis.annotationContainer().functionDependencyGraphAnnotation;\n}\n\ntemplate<>\nFunctionDependencyAnalysis::GlobalAnnotation& solidity::frontend::experimental::detail::AnnotationFetcher<FunctionDependencyAnalysis>::get()\n{\n\treturn analysis.annotationContainer().functionDependencyGraphAnnotation;\n}\n\ntemplate<>\nTypeRegistration::Annotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeRegistration>::get(ASTNode const& _node)\n{\n\treturn analysis.annotationContainer(_node).typeRegistrationAnnotation;\n}\n\ntemplate<>\nTypeRegistration::GlobalAnnotation const& solidity::frontend::experimental::detail::ConstAnnotationFetcher<TypeRegistration>::get() const\n{\n\treturn analysis.annotationContainer().typeRegistrationAnnotation;\n}\n\ntemplate<>\nTypeRegistration::GlobalAnnotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeRegistration>::get()\n{\n\treturn analysis.annotationContainer().typeRegistrationAnnotation;\n}\n\ntemplate<>\nTypeRegistration::Annotation const& solidity::frontend::experimental::detail::ConstAnnotationFetcher<TypeRegistration>::get(ASTNode const& _node) const\n{\n\treturn analysis.annotationContainer(_node).typeRegistrationAnnotation;\n}\n\ntemplate<>\nTypeInference::Annotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeInference>::get(ASTNode const& _node)\n{\n\treturn analysis.annotationContainer(_node).typeInferenceAnnotation;\n}\n\ntemplate<>\nTypeInference::Annotation const& solidity::frontend::experimental::detail::ConstAnnotationFetcher<TypeInference>::get(ASTNode const& _node) const\n{\n\treturn analysis.annotationContainer(_node).typeInferenceAnnotation;\n}\n\ntemplate<>\nTypeInference::GlobalAnnotation const& solidity::frontend::experimental::detail::ConstAnnotationFetcher<TypeInference>::get() const\n{\n\treturn analysis.annotationContainer().typeInferenceAnnotation;\n}\n\ntemplate<>\nTypeInference::GlobalAnnotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeInference>::get()\n{\n\treturn analysis.annotationContainer().typeInferenceAnnotation;\n}\n\nAnalysis::AnnotationContainer& Analysis::annotationContainer(ASTNode const& _node)\n{\n\tsolAssert(_node.id() > 0);\n\tsize_t id = static_cast<size_t>(_node.id());\n\tsolAssert(id <= m_maxAstId);\n\treturn m_annotations[id];\n}\n\nAnalysis::AnnotationContainer const& Analysis::annotationContainer(ASTNode const& _node) const\n{\n\tsolAssert(_node.id() > 0);\n\tsize_t id = static_cast<size_t>(_node.id());\n\tsolAssert(id <= m_maxAstId);\n\treturn m_annotations[id];\n}\n\nAnalysis::Analysis(langutil::ErrorReporter& _errorReporter, uint64_t _maxAstId):\n\tm_errorReporter(_errorReporter),\n\tm_maxAstId(_maxAstId),\n\tm_annotations(std::make_unique<AnnotationContainer[]>(static_cast<size_t>(_maxAstId + 1))),\n\tm_globalAnnotation(std::make_unique<GlobalAnnotationContainer>())\n{\n}\n\nAnalysis::~Analysis()\n{}\n\ntemplate<size_t... Is>\nstd::tuple<std::integral_constant<size_t, Is>...> makeIndexTuple(std::index_sequence<Is...>) {\n\treturn std::make_tuple( std::integral_constant<size_t, Is>{}...);\n}\n\nbool Analysis::check(std::vector<std::shared_ptr<SourceUnit const>> const& _sourceUnits)\n{\n\tusing AnalysisSteps = std::tuple<\n\t\tSyntaxRestrictor,\n\t\tTypeClassRegistration,\n\t\tTypeRegistration,\n\t\t// TODO move after step introduced in https://github.com/argotorg/solidity/pull/14578, but before TypeInference\n\t\tFunctionDependencyAnalysis,\n\t\tTypeInference,\n\t\tDebugWarner\n\t>;\n\n\treturn std::apply([&](auto... _indexTuple) {\n\t\treturn ([&](auto&& _step) {\n\t\t\tfor (auto source: _sourceUnits)\n\t\t\t\tif (!_step.analyze(*source))\n\t\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}(std::tuple_element_t<decltype(_indexTuple)::value, AnalysisSteps>{*this}) && ...);\n\t}, makeIndexTuple(std::make_index_sequence<std::tuple_size_v<AnalysisSteps>>{}));\n\n/*\n\t{\n\t\tSyntaxRestrictor syntaxRestrictor{*this};\n\t\tfor (auto source: _sourceUnits)\n\t\t\tif (!syntaxRestrictor.analyze(*source))\n\t\t\t\treturn false;\n\t}\n\n\t{\n\t\tTypeRegistration typeRegistration{*this};\n\t\tfor (auto source: _sourceUnits)\n\t\t\tif (!typeRegistration.analyze(*source))\n\t\t\t\treturn false;\n\t}\n\t{\n\t\tTypeInference typeInference{*this};\n\t\tfor (auto source: _sourceUnits)\n\t\t\tif (!typeInference.analyze(*source))\n\t\t\t\treturn false;\n\t}\n\treturn true;\n */\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/Analysis.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/experimental/ast/TypeSystem.h>\n\n#include <cstdint>\n#include <memory>\n#include <vector>\n\nnamespace solidity::frontend\n{\nclass SourceUnit;\nclass ASTNode;\n}\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend::experimental\n{\n\nclass TypeSystem;\n\nclass Analysis;\n\nnamespace detail\n{\ntemplate<typename Step>\nstruct AnnotationFetcher\n{\n\tAnalysis& analysis;\n\ttypename Step::Annotation& get(ASTNode const& _node);\n\ttypename Step::GlobalAnnotation& get();\n};\ntemplate<typename Step>\nstruct ConstAnnotationFetcher\n{\n\tAnalysis const& analysis;\n\ttypename Step::Annotation const& get(ASTNode const& _node) const;\n\ttypename Step::GlobalAnnotation const& get() const;\n};\n}\n\nclass Analysis\n{\n\tstruct AnnotationContainer;\n\tstruct GlobalAnnotationContainer;\n\npublic:\n\tAnalysis(langutil::ErrorReporter& _errorReporter, uint64_t _maxAstId);\n\tAnalysis(Analysis const&) = delete;\n\t~Analysis();\n\tAnalysis const& operator=(Analysis const&) = delete;\n\tbool check(std::vector<std::shared_ptr<SourceUnit const>> const& _sourceUnits);\n\tlangutil::ErrorReporter& errorReporter() { return m_errorReporter; }\n\tuint64_t maxAstId() const { return m_maxAstId; }\n\tTypeSystem& typeSystem() { return m_typeSystem; }\n\tTypeSystem const& typeSystem() const { return m_typeSystem; }\n\n\ttemplate<typename Step>\n\ttypename Step::Annotation& annotation(ASTNode const& _node)\n\t{\n\t\treturn detail::AnnotationFetcher<Step>{*this}.get(_node);\n\t}\n\n\ttemplate<typename Step>\n\ttypename Step::Annotation const& annotation(ASTNode const& _node) const\n\t{\n\t\treturn detail::ConstAnnotationFetcher<Step>{*this}.get(_node);\n\t}\n\n\ttemplate<typename Step>\n\ttypename Step::GlobalAnnotation& annotation()\n\t{\n\t\treturn detail::AnnotationFetcher<Step>{*this}.get();\n\t}\n\n\ttemplate<typename Step>\n\ttypename Step::GlobalAnnotation const& annotation() const\n\t{\n\t\treturn detail::ConstAnnotationFetcher<Step>{*this}.get();\n\t}\n\n\tAnnotationContainer& annotationContainer(ASTNode const& _node);\n\tAnnotationContainer const& annotationContainer(ASTNode const& _node) const;\n\tGlobalAnnotationContainer& annotationContainer() { return *m_globalAnnotation; }\n\tGlobalAnnotationContainer const& annotationContainer() const { return *m_globalAnnotation; }\n\nprivate:\n\tlangutil::ErrorReporter& m_errorReporter;\n\tTypeSystem m_typeSystem;\n\tuint64_t m_maxAstId = 0;\n\tstd::unique_ptr<AnnotationContainer[]> m_annotations;\n\tstd::unique_ptr<GlobalAnnotationContainer> m_globalAnnotation;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/DebugWarner.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/experimental/analysis/DebugWarner.h>\n\n#include <libsolidity/experimental/analysis/Analysis.h>\n#include <libsolidity/experimental/analysis/TypeInference.h>\n#include <libsolidity/experimental/ast/TypeSystemHelper.h>\n\n#include <liblangutil/Exceptions.h>\n\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::experimental;\nusing namespace solidity::langutil;\n\nDebugWarner::DebugWarner(Analysis& _analysis): m_analysis(_analysis), m_errorReporter(_analysis.errorReporter())\n{}\n\nbool DebugWarner::analyze(ASTNode const& _astRoot)\n{\n\t_astRoot.accept(*this);\n\treturn !Error::containsErrors(m_errorReporter.errors());\n}\n\nbool DebugWarner::visitNode(ASTNode const& _node)\n{\n\tstd::optional<Type> const& inferredType = m_analysis.annotation<TypeInference>(_node).type;\n\tif (inferredType.has_value())\n\t\tm_errorReporter.info(\n\t\t\t4164_error,\n\t\t\t_node.location(),\n\t\t\t\"Inferred type: \" + TypeEnvironmentHelpers{m_analysis.typeSystem().env()}.typeToString(*inferredType)\n\t\t);\n\treturn true;\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/DebugWarner.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n\n#include <liblangutil/ErrorReporter.h>\n\nnamespace solidity::frontend::experimental\n{\nclass Analysis;\n\nclass DebugWarner: public ASTConstVisitor\n{\npublic:\n\tDebugWarner(Analysis& _analysis);\n\n\tbool analyze(ASTNode const& _astRoot);\n\nprivate:\n\tbool visitNode(ASTNode const& _node) override;\n\n\tAnalysis& m_analysis;\n\tlangutil::ErrorReporter& m_errorReporter;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/FunctionDependencyAnalysis.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/experimental/analysis/Analysis.h>\n#include <libsolidity/experimental/analysis/FunctionDependencyAnalysis.h>\n\nusing namespace solidity::frontend::experimental;\nusing namespace solidity::util;\n\nFunctionDependencyAnalysis::FunctionDependencyAnalysis(Analysis& _analysis):\n\tm_analysis(_analysis),\n\tm_errorReporter(_analysis.errorReporter())\n{\n}\n\nbool FunctionDependencyAnalysis::analyze(SourceUnit const& _sourceUnit)\n{\n\t_sourceUnit.accept(*this);\n\treturn !m_errorReporter.hasErrors();\n}\n\nbool FunctionDependencyAnalysis::visit(FunctionDefinition const& _functionDefinition)\n{\n\tsolAssert(!m_currentFunction);\n\tm_currentFunction = &_functionDefinition;\n\t// Insert a function definition pointer that maps to an empty set; the pointed to set will later be\n\t// populated in ``endVisit(Identifier const& _identifier)`` if ``m_currentFunction`` references another.\n\tauto [_, inserted] = annotation().functionCallGraph.edges.try_emplace(\n\t\tm_currentFunction, std::set<FunctionDefinition const*, ASTCompareByID<FunctionDefinition>>{}\n\t);\n\tsolAssert(inserted);\n\treturn true;\n}\n\nvoid FunctionDependencyAnalysis::endVisit(FunctionDefinition const&)\n{\n\tm_currentFunction = nullptr;\n}\n\nvoid FunctionDependencyAnalysis::endVisit(Identifier const& _identifier)\n{\n\tauto const* callee = dynamic_cast<FunctionDefinition const*>(_identifier.annotation().referencedDeclaration);\n\t// Check that the identifier is within a function body and is a function, and add it to the graph\n\t// as an ``m_currentFunction`` -> ``callee`` edge.\n\tif (m_currentFunction && callee)\n\t\taddEdge(m_currentFunction, callee);\n}\n\nvoid FunctionDependencyAnalysis::addEdge(FunctionDefinition const* _caller, FunctionDefinition const* _callee)\n{\n\tannotation().functionCallGraph.edges[_caller].insert(_callee);\n}\n\nFunctionDependencyAnalysis::GlobalAnnotation& FunctionDependencyAnalysis::annotation()\n{\n\treturn m_analysis.annotation<FunctionDependencyAnalysis>();\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/FunctionDependencyAnalysis.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <liblangutil/ErrorReporter.h>\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/experimental/ast/FunctionCallGraph.h>\n\n#include <memory>\n\nnamespace solidity::frontend::experimental\n{\n\nclass Analysis;\n\nclass FunctionDependencyAnalysis: private ASTConstVisitor\n{\npublic:\n\tFunctionDependencyAnalysis(Analysis& _analysis);\n\tbool analyze(SourceUnit const& _sourceUnit);\n\n\tstruct Annotation {};\n\tstruct GlobalAnnotation\n\t{\n\t\tFunctionDependencyGraph functionCallGraph;\n\t};\n\nprivate:\n\tbool visit(FunctionDefinition const& _functionDefinition) override;\n\tvoid endVisit(FunctionDefinition const&) override;\n\tvoid endVisit(Identifier const& _identifier) override;\n\tvoid addEdge(FunctionDefinition const* _caller, FunctionDefinition const* _callee);\n\tGlobalAnnotation& annotation();\n\n\tAnalysis& m_analysis;\n\tlangutil::ErrorReporter& m_errorReporter;\n\tFunctionDefinition const* m_currentFunction = nullptr;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/SyntaxRestrictor.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/experimental/analysis/SyntaxRestrictor.h>\n\n#include <libsolidity/experimental/analysis/Analysis.h>\n\n#include <liblangutil/Exceptions.h>\n\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::experimental;\nusing namespace solidity::langutil;\n\nSyntaxRestrictor::SyntaxRestrictor(Analysis& _analysis): m_errorReporter(_analysis.errorReporter())\n{}\n\nbool SyntaxRestrictor::analyze(ASTNode const& _astRoot)\n{\n\t_astRoot.accept(*this);\n\treturn !Error::containsErrors(m_errorReporter.errors());\n}\n\nbool SyntaxRestrictor::visitNode(ASTNode const& _node)\n{\n\tif (!_node.experimentalSolidityOnly())\n\t\tm_errorReporter.syntaxError(9282_error, _node.location(), \"Unsupported AST node.\");\n\treturn false;\n}\n\nbool SyntaxRestrictor::visit(ContractDefinition const& _contractDefinition)\n{\n\tif (_contractDefinition.contractKind() != ContractKind::Contract)\n\t\tm_errorReporter.syntaxError(9159_error, _contractDefinition.location(), \"Only contracts are supported.\");\n\tif (!_contractDefinition.baseContracts().empty())\n\t\tm_errorReporter.syntaxError(5731_error, _contractDefinition.location(), \"Inheritance unsupported.\");\n\treturn true;\n}\n\nbool SyntaxRestrictor::visit(FunctionDefinition const& _functionDefinition)\n{\n\tif (!_functionDefinition.isImplemented())\n\t\tm_errorReporter.syntaxError(1741_error, _functionDefinition.location(), \"Functions must be implemented.\");\n\tif (!_functionDefinition.modifiers().empty())\n\t\tm_errorReporter.syntaxError(9988_error, _functionDefinition.location(), \"Function may not have modifiers.\");\n\tif (_functionDefinition.overrides())\n\t\tm_errorReporter.syntaxError(5044_error, _functionDefinition.location(), \"Function may not have override specifiers.\");\n\tsolAssert(!_functionDefinition.returnParameterList());\n\tif (_functionDefinition.isFree())\n\t{\n\t\tif (_functionDefinition.stateMutability() != StateMutability::NonPayable)\n\t\t\tm_errorReporter.syntaxError(5714_error, _functionDefinition.location(), \"Free functions may not have a mutability.\");\n\t}\n\telse\n\t{\n\t\tif (_functionDefinition.isFallback())\n\t\t{\n\t\t\tif (_functionDefinition.visibility() != Visibility::External)\n\t\t\t\tm_errorReporter.syntaxError(7341_error, _functionDefinition.location(), \"Fallback function must be external.\");\n\t\t}\n\t\telse\n\t\t\tm_errorReporter.syntaxError(4496_error, _functionDefinition.location(), \"Only fallback functions are supported in contracts.\");\n\t}\n\n\treturn true;\n}\n\nbool SyntaxRestrictor::visit(VariableDeclarationStatement const& _variableDeclarationStatement)\n{\n\tif (_variableDeclarationStatement.declarations().size() == 1)\n\t{\n\t\tif (!_variableDeclarationStatement.declarations().front())\n\t\t\tm_errorReporter.syntaxError(9658_error, _variableDeclarationStatement.initialValue()->location(), \"Variable declaration has to declare a single variable.\");\n\t}\n\telse\n\t\tm_errorReporter.syntaxError(3520_error, _variableDeclarationStatement.initialValue()->location(), \"Variable declarations can only declare a single variable.\");\n\treturn true;\n}\n\nbool SyntaxRestrictor::visit(VariableDeclaration const& _variableDeclaration)\n{\n\tif (_variableDeclaration.value())\n\t\tm_errorReporter.syntaxError(1801_error, _variableDeclaration.value()->location(), \"Variable declarations with initial value not supported.\");\n\tif (_variableDeclaration.isStateVariable())\n\t\tm_errorReporter.syntaxError(6388_error, _variableDeclaration.location(), \"State variables are not supported.\");\n\tif (!_variableDeclaration.isLocalVariable())\n\t\tm_errorReporter.syntaxError(8953_error, _variableDeclaration.location(), \"Only local variables are supported.\");\n\tif (_variableDeclaration.mutability() != VariableDeclaration::Mutability::Mutable)\n\t\tm_errorReporter.syntaxError(2934_error, _variableDeclaration.location(), \"Only mutable variables are supported.\");\n\tif (_variableDeclaration.isIndexed())\n\t\tm_errorReporter.syntaxError(9603_error, _variableDeclaration.location(), \"Indexed variables are not supported.\");\n\tif (!_variableDeclaration.noVisibilitySpecified())\n\t\tm_errorReporter.syntaxError(8809_error, _variableDeclaration.location(), \"Variables with visibility not supported.\");\n\tif (_variableDeclaration.overrides())\n\t\tm_errorReporter.syntaxError(6175_error, _variableDeclaration.location(), \"Variables with override specifier not supported.\");\n\tif (_variableDeclaration.referenceLocation() != VariableDeclaration::Location::Unspecified)\n\t\tm_errorReporter.syntaxError(5360_error, _variableDeclaration.location(), \"Variables with reference location not supported.\");\n\treturn true;\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/SyntaxRestrictor.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/Exceptions.h>\n\nnamespace solidity::frontend::experimental\n{\nclass Analysis;\n\nclass SyntaxRestrictor: public ASTConstVisitor\n{\npublic:\n\tSyntaxRestrictor(Analysis& _analysis);\n\n\tbool analyze(ASTNode const& _astRoot);\n\nprivate:\n\t/// Default visit will reject all AST nodes that are not explicitly allowed.\n\tbool visitNode(ASTNode const& _node) override;\n\n\tbool visit(SourceUnit const&) override { return true; }\n\tbool visit(PragmaDirective const&) override { return true; }\n\tbool visit(ImportDirective const&) override { return true; }\n\tbool visit(ContractDefinition const& _contractDefinition) override;\n\tbool visit(FunctionDefinition const& _functionDefinition) override;\n\tbool visit(ExpressionStatement const&) override { return true; }\n\tbool visit(FunctionCall const&) override { return true; }\n\tbool visit(Assignment const&) override { return true; }\n\tbool visit(Block const&) override { return true; }\n\tbool visit(InlineAssembly const&) override { return true; }\n\tbool visit(Identifier const&) override { return true; }\n\tbool visit(IdentifierPath const&) override { return true; }\n\tbool visit(IfStatement const&) override { return true; }\n\tbool visit(VariableDeclarationStatement const&) override;\n\tbool visit(VariableDeclaration const&) override;\n\tbool visit(ElementaryTypeName const&) override { return true; }\n\tbool visit(ParameterList const&) override { return true; }\n\tbool visit(Return const&) override { return true; }\n\tbool visit(MemberAccess const&) override { return true; }\n\tbool visit(BinaryOperation const&) override { return true; }\n\tbool visit(ElementaryTypeNameExpression const&) override { return true; }\n\tbool visit(TupleExpression const&) override { return true; }\n\tbool visit(Literal const&) override { return true; }\n\n\tlangutil::ErrorReporter& m_errorReporter;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/TypeClassRegistration.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n\n#include <libsolidity/experimental/analysis/TypeClassRegistration.h>\n\n#include <libsolidity/experimental/analysis/Analysis.h>\n\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/Exceptions.h>\n\nusing namespace solidity::frontend::experimental;\nusing namespace solidity::langutil;\n\nTypeClassRegistration::TypeClassRegistration(Analysis& _analysis):\n\tm_analysis(_analysis),\n\tm_errorReporter(_analysis.errorReporter()),\n\tm_typeSystem(_analysis.typeSystem())\n{\n}\n\nbool TypeClassRegistration::analyze(SourceUnit const& _sourceUnit)\n{\n\t_sourceUnit.accept(*this);\n\treturn !m_errorReporter.hasErrors();\n}\n\nbool TypeClassRegistration::visit(TypeClassDefinition const& _typeClassDefinition)\n{\n\tstd::variant<TypeClass, std::string> typeClassOrError = m_typeSystem.declareTypeClass(\n\t\t_typeClassDefinition.name(),\n\t\t&_typeClassDefinition\n\t);\n\n\tm_analysis.annotation<TypeClassRegistration>(_typeClassDefinition).typeClass = std::visit(\n\t\tutil::GenericVisitor{\n\t\t\t[](TypeClass _class) -> TypeClass { return _class; },\n\t\t\t[&](std::string _error) -> TypeClass {\n\t\t\t\tm_errorReporter.fatalTypeError(4767_error, _typeClassDefinition.location(), _error);\n\t\t\t\tutil::unreachable();\n\t\t\t}\n\t\t},\n\t\ttypeClassOrError\n\t);\n\n\treturn true;\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/TypeClassRegistration.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/experimental/ast/TypeSystem.h>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend::experimental\n{\n\nclass Analysis;\nclass TypeSystem;\n\nclass TypeClassRegistration: public ASTConstVisitor\n{\npublic:\n\tstruct Annotation\n\t{\n\t\t// Type classes.\n\t\tstd::optional<TypeClass> typeClass;\n\t};\n\tstruct GlobalAnnotation\n\t{\n\t};\n\n\tTypeClassRegistration(Analysis& _analysis);\n\n\tbool analyze(SourceUnit const& _sourceUnit);\n\nprivate:\n\tbool visit(TypeClassDefinition const& _typeClassDefinition) override;\n\n\tAnalysis& m_analysis;\n\tlangutil::ErrorReporter& m_errorReporter;\n\tTypeSystem& m_typeSystem;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/TypeInference.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n\n#include <libsolidity/experimental/analysis/TypeInference.h>\n\n#include <libsolidity/experimental/analysis/TypeClassRegistration.h>\n#include <libsolidity/experimental/analysis/TypeRegistration.h>\n#include <libsolidity/experimental/analysis/Analysis.h>\n#include <libsolidity/experimental/ast/TypeSystemHelper.h>\n\n#include <libsolutil/Numeric.h>\n#include <libsolutil/StringUtils.h>\n#include <liblangutil/Exceptions.h>\n\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/AST.h>\n\n#include <boost/algorithm/string.hpp>\n\n#include <range/v3/view/transform.hpp>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::experimental;\nusing namespace solidity::langutil;\n\nTypeInference::TypeInference(Analysis& _analysis):\n\tm_analysis(_analysis),\n\tm_errorReporter(_analysis.errorReporter()),\n\tm_typeSystem(_analysis.typeSystem()),\n\tm_env(&m_typeSystem.env()),\n\tm_voidType(m_typeSystem.type(PrimitiveType::Void, {})),\n\tm_wordType(m_typeSystem.type(PrimitiveType::Word, {})),\n\tm_integerType(m_typeSystem.type(PrimitiveType::Integer, {})),\n\tm_unitType(m_typeSystem.type(PrimitiveType::Unit, {})),\n\tm_boolType(m_typeSystem.type(PrimitiveType::Bool, {}))\n{\n\tTypeSystemHelpers helper{m_typeSystem};\n\n\tauto declareBuiltinClass = [&](std::string _name, BuiltinClass _class) -> TypeClass {\n\t\tauto result = m_typeSystem.declareTypeClass(_name, nullptr);\n\t\tif (auto error = std::get_if<std::string>(&result))\n\t\t\tsolAssert(!error, *error);\n\t\tTypeClass declaredClass = std::get<TypeClass>(result);\n\t\t// TODO: validation?\n\t\tsolAssert(annotation().builtinClassesByName.emplace(_name, _class).second);\n\t\treturn annotation().builtinClasses.emplace(_class, declaredClass).first->second;\n\t};\n\n\tauto registeredTypeClass = [&](BuiltinClass _builtinClass) -> TypeClass {\n\t\treturn annotation().builtinClasses.at(_builtinClass);\n\t};\n\n\tauto defineConversion = [&](BuiltinClass _builtinClass, PrimitiveType _fromType, std::string _functionName) {\n\t\tannotation().typeClassFunctions[registeredTypeClass(_builtinClass)] = {{\n\t\t\tstd::move(_functionName),\n\t\t\thelper.functionType(\n\t\t\t\tm_typeSystem.type(_fromType, {}),\n\t\t\t\tm_typeSystem.typeClassInfo(registeredTypeClass(_builtinClass)).typeVariable\n\t\t\t),\n\t\t}};\n\t};\n\n\tauto defineBinaryMonoidalOperator = [&](BuiltinClass _builtinClass, Token _token, std::string _functionName) {\n\t\tType typeVar = m_typeSystem.typeClassInfo(registeredTypeClass(_builtinClass)).typeVariable;\n\t\tannotation().operators.emplace(_token, std::make_tuple(registeredTypeClass(_builtinClass), _functionName));\n\t\tannotation().typeClassFunctions[registeredTypeClass(_builtinClass)] = {{\n\t\t\tstd::move(_functionName),\n\t\t\thelper.functionType(\n\t\t\t\thelper.tupleType({typeVar, typeVar}),\n\t\t\t\ttypeVar\n\t\t\t)\n\t\t}};\n\t};\n\n\tauto defineBinaryCompareOperator = [&](BuiltinClass _builtinClass, Token _token, std::string _functionName) {\n\t\tType typeVar = m_typeSystem.typeClassInfo(registeredTypeClass(_builtinClass)).typeVariable;\n\t\tannotation().operators.emplace(_token, std::make_tuple(registeredTypeClass(_builtinClass), _functionName));\n\t\tannotation().typeClassFunctions[registeredTypeClass(_builtinClass)] = {{\n\t\t\tstd::move(_functionName),\n\t\t\thelper.functionType(\n\t\t\t\thelper.tupleType({typeVar, typeVar}),\n\t\t\t\tm_typeSystem.type(PrimitiveType::Bool, {})\n\t\t\t)\n\t\t}};\n\t};\n\n\tdeclareBuiltinClass(\"integer\", BuiltinClass::Integer);\n\tdeclareBuiltinClass(\"*\", BuiltinClass::Mul);\n\tdeclareBuiltinClass(\"+\", BuiltinClass::Add);\n\tdeclareBuiltinClass(\"==\", BuiltinClass::Equal);\n\tdeclareBuiltinClass(\"<\", BuiltinClass::Less);\n\tdeclareBuiltinClass(\"<=\", BuiltinClass::LessOrEqual);\n\tdeclareBuiltinClass(\">\", BuiltinClass::Greater);\n\tdeclareBuiltinClass(\">=\", BuiltinClass::GreaterOrEqual);\n\n\tdefineConversion(BuiltinClass::Integer, PrimitiveType::Integer, \"fromInteger\");\n\n\tdefineBinaryMonoidalOperator(BuiltinClass::Mul, Token::Mul, \"mul\");\n\tdefineBinaryMonoidalOperator(BuiltinClass::Add, Token::Add, \"add\");\n\n\tdefineBinaryCompareOperator(BuiltinClass::Equal, Token::Equal, \"eq\");\n\tdefineBinaryCompareOperator(BuiltinClass::Less, Token::LessThan, \"lt\");\n\tdefineBinaryCompareOperator(BuiltinClass::LessOrEqual, Token::LessThanOrEqual, \"leq\");\n\tdefineBinaryCompareOperator(BuiltinClass::Greater, Token::GreaterThan, \"gt\");\n\tdefineBinaryCompareOperator(BuiltinClass::GreaterOrEqual, Token::GreaterThanOrEqual, \"geq\");\n}\n\nbool TypeInference::analyze(SourceUnit const& _sourceUnit)\n{\n\t_sourceUnit.accept(*this);\n\treturn !m_errorReporter.hasErrors();\n}\n\nbool TypeInference::visit(ForAllQuantifier const& _quantifier)\n{\n\tsolAssert(m_expressionContext == ExpressionContext::Term);\n\n\t{\n\t\tScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Type};\n\t\t_quantifier.typeVariableDeclarations().accept(*this);\n\t}\n\n\t_quantifier.quantifiedDeclaration().accept(*this);\n\treturn false;\n}\n\nbool TypeInference::visit(FunctionDefinition const& _functionDefinition)\n{\n\tsolAssert(m_expressionContext == ExpressionContext::Term);\n\tauto& functionAnnotation = annotation(_functionDefinition);\n\tif (functionAnnotation.type)\n\t\treturn false;\n\n\tScopedSaveAndRestore signatureRestore(m_currentFunctionType, std::nullopt);\n\n\tType argumentsType = m_typeSystem.freshTypeVariable({});\n\tType returnType = m_typeSystem.freshTypeVariable({});\n\tType functionType = TypeSystemHelpers{m_typeSystem}.functionType(argumentsType, returnType);\n\n\tm_currentFunctionType = functionType;\n\tfunctionAnnotation.type = functionType;\n\n\n\t_functionDefinition.parameterList().accept(*this);\n\tunify(argumentsType, type(_functionDefinition.parameterList()), _functionDefinition.parameterList().location());\n\tif (_functionDefinition.experimentalReturnExpression())\n\t{\n\t\tScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Type};\n\t\t_functionDefinition.experimentalReturnExpression()->accept(*this);\n\t\tunify(\n\t\t\treturnType,\n\t\t\ttype(*_functionDefinition.experimentalReturnExpression()),\n\t\t\t_functionDefinition.experimentalReturnExpression()->location()\n\t\t);\n\t}\n\telse\n\t\tunify(returnType, m_unitType, _functionDefinition.location());\n\n\tif (_functionDefinition.isImplemented())\n\t\t_functionDefinition.body().accept(*this);\n\n\treturn false;\n}\n\nvoid TypeInference::endVisit(FunctionDefinition const& _functionDefinition)\n{\n\tsolAssert(m_expressionContext == ExpressionContext::Term);\n\n\tm_env->fixTypeVars(TypeEnvironmentHelpers{*m_env}.typeVars(type(_functionDefinition)));\n}\n\nvoid TypeInference::endVisit(Return const& _return)\n{\n\tsolAssert(m_currentFunctionType);\n\tType functionReturnType = std::get<1>(TypeSystemHelpers{m_typeSystem}.destFunctionType(*m_currentFunctionType));\n\tif (_return.expression())\n\t\tunify(functionReturnType, type(*_return.expression()), _return.location());\n\telse\n\t\tunify(functionReturnType, m_unitType, _return.location());\n}\n\nvoid TypeInference::endVisit(ParameterList const& _parameterList)\n{\n\tauto& listAnnotation = annotation(_parameterList);\n\tsolAssert(!listAnnotation.type);\n\tlistAnnotation.type = TypeSystemHelpers{m_typeSystem}.tupleType(\n\t\t_parameterList.parameters() | ranges::views::transform([&](auto _arg) { return type(*_arg); }) | ranges::to<std::vector<Type>>\n\t);\n}\n\nbool TypeInference::visit(TypeClassDefinition const& _typeClassDefinition)\n{\n\tsolAssert(m_expressionContext == ExpressionContext::Term);\n\tauto& typeClassDefinitionAnnotation = annotation(_typeClassDefinition);\n\tif (typeClassDefinitionAnnotation.type)\n\t\treturn false;\n\n\ttypeClassDefinitionAnnotation.type = type(&_typeClassDefinition, {});\n\n\t{\n\t\tScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Type};\n\t\t_typeClassDefinition.typeVariable().accept(*this);\n\t}\n\n\tstd::map<std::string, Type> functionTypes;\n\n\tsolAssert(m_analysis.annotation<TypeClassRegistration>(_typeClassDefinition).typeClass.has_value());\n\tTypeClass typeClass = m_analysis.annotation<TypeClassRegistration>(_typeClassDefinition).typeClass.value();\n\tType typeVar = m_typeSystem.typeClassVariable(typeClass);\n\tunify(type(_typeClassDefinition.typeVariable()), typeVar, _typeClassDefinition.location());\n\n\tauto& typeMembersAnnotation = annotation().members[typeConstructor(&_typeClassDefinition)];\n\n\tfor (auto subNode: _typeClassDefinition.subNodes())\n\t{\n\t\tsubNode->accept(*this);\n\t\tauto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(subNode.get());\n\t\tsolAssert(functionDefinition);\n\t\tauto functionType = type(*functionDefinition);\n\t\tif (!functionTypes.emplace(functionDefinition->name(), functionType).second)\n\t\t\tm_errorReporter.fatalTypeError(3195_error, functionDefinition->location(), \"Function in type class declared multiple times.\");\n\t\tauto typeVars = TypeEnvironmentHelpers{*m_env}.typeVars(functionType);\n\t\tif (typeVars.size() != 1)\n\t\t\tm_errorReporter.fatalTypeError(8379_error, functionDefinition->location(), \"Function in type class may only depend on the type class variable.\");\n\t\tunify(typeVars.front(), typeVar, functionDefinition->location());\n\t\ttypeMembersAnnotation[functionDefinition->name()] = TypeMember{functionType};\n\t}\n\n\tannotation().typeClassFunctions[typeClass] = std::move(functionTypes);\n\n\tfor (auto [functionName, functionType]: functionTypes)\n\t{\n\t\tTypeEnvironmentHelpers helper{*m_env};\n\t\tauto typeVars = helper.typeVars(functionType);\n\t\tif (typeVars.empty())\n\t\t\tm_errorReporter.typeError(1723_error, _typeClassDefinition.location(), \"Function \" + functionName + \" does not depend on class variable.\");\n\t\tif (typeVars.size() > 2)\n\t\t\tm_errorReporter.typeError(6387_error, _typeClassDefinition.location(), \"Function \" + functionName + \" depends on multiple type variables.\");\n\t\tif (!m_env->typeEquals(typeVars.front(), typeVar))\n\t\t\tm_errorReporter.typeError(1807_error, _typeClassDefinition.location(), \"Function \" + functionName + \" depends on invalid type variable.\");\n\t}\n\n\tfor (auto instantiation: m_analysis.annotation<TypeRegistration>(_typeClassDefinition).instantiations | ranges::views::values)\n\t\t// TODO: recursion-safety? Order of instantiation?\n\t\tinstantiation->accept(*this);\n\n\treturn false;\n}\n\nbool TypeInference::visit(InlineAssembly const& _inlineAssembly)\n{\n\t// External references have already been resolved in a prior stage and stored in the annotation.\n\t// We run the resolve step again regardless.\n\tyul::ExternalIdentifierAccess::Resolver identifierAccess = [&](\n\t\tyul::Identifier const& _identifier,\n\t\tyul::IdentifierContext _context,\n\t\tbool\n\t) -> bool\n\t{\n\t\tif (_context == yul::IdentifierContext::NonExternal)\n\t\t{\n\t\t\t// TODO: do we need this?\n\t\t\t// Hack until we can disallow any shadowing: If we found an internal reference,\n\t\t\t// clear the external references, so that codegen does not use it.\n\t\t\t_inlineAssembly.annotation().externalReferences.erase(& _identifier);\n\t\t\treturn false;\n\t\t}\n\t\tInlineAssemblyAnnotation::ExternalIdentifierInfo* identifierInfo = util::valueOrNullptr(_inlineAssembly.annotation().externalReferences, &_identifier);\n\t\tif (!identifierInfo)\n\t\t\treturn false;\n\t\tDeclaration const* declaration = identifierInfo->declaration;\n\t\tsolAssert(!!declaration, \"\");\n\t\tsolAssert(identifierInfo->suffix == \"\", \"\");\n\n\t\tunify(type(*declaration), m_wordType, originLocationOf(_identifier));\n\t\tidentifierInfo->valueSize = 1;\n\t\treturn true;\n\t};\n\tsolAssert(!_inlineAssembly.annotation().analysisInfo, \"\");\n\t_inlineAssembly.annotation().analysisInfo = std::make_shared<yul::AsmAnalysisInfo>();\n\tyul::AsmAnalyzer analyzer(\n\t\t*_inlineAssembly.annotation().analysisInfo,\n\t\tm_errorReporter,\n\t\t_inlineAssembly.dialect(),\n\t\tidentifierAccess\n\t);\n\tif (!analyzer.analyze(_inlineAssembly.operations().root()))\n\t\tsolAssert(m_errorReporter.hasErrors());\n\treturn false;\n}\n\nbool TypeInference::visit(BinaryOperation const& _binaryOperation)\n{\n\tauto& operationAnnotation = annotation(_binaryOperation);\n\tsolAssert(!operationAnnotation.type);\n\tTypeSystemHelpers helper{m_typeSystem};\n\tswitch (m_expressionContext)\n\t{\n\tcase ExpressionContext::Term:\n\t\tif (auto* operatorInfo = util::valueOrNullptr(annotation().operators, _binaryOperation.getOperator()))\n\t\t{\n\t\t\tauto [typeClass, functionName] = *operatorInfo;\n\t\t\t// TODO: error robustness?\n\t\t\tType functionType = m_env->fresh(annotation().typeClassFunctions.at(typeClass).at(functionName));\n\n\t\t\t_binaryOperation.leftExpression().accept(*this);\n\t\t\t_binaryOperation.rightExpression().accept(*this);\n\n\t\t\tType argTuple = helper.tupleType({type(_binaryOperation.leftExpression()), type(_binaryOperation.rightExpression())});\n\t\t\tType resultType = m_typeSystem.freshTypeVariable({});\n\t\t\tType genericFunctionType = helper.functionType(argTuple, resultType);\n\t\t\tunify(functionType, genericFunctionType, _binaryOperation.location());\n\n\t\t\toperationAnnotation.type = resultType;\n\t\t}\n\t\telse if (_binaryOperation.getOperator() == Token::Colon)\n\t\t{\n\t\t\t_binaryOperation.leftExpression().accept(*this);\n\t\t\t{\n\t\t\t\tScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Type};\n\t\t\t\t_binaryOperation.rightExpression().accept(*this);\n\t\t\t}\n\t\t\tType leftType = type(_binaryOperation.leftExpression());\n\t\t\tunify(leftType, type(_binaryOperation.rightExpression()), _binaryOperation.location());\n\t\t\toperationAnnotation.type = leftType;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_errorReporter.typeError(4504_error, _binaryOperation.location(), \"Binary operation in term context not yet supported.\");\n\t\t\toperationAnnotation.type = m_typeSystem.freshTypeVariable({});\n\t\t}\n\t\treturn false;\n\tcase ExpressionContext::Type:\n\t\tif (_binaryOperation.getOperator() == Token::Colon)\n\t\t{\n\t\t\t_binaryOperation.leftExpression().accept(*this);\n\t\t\t{\n\t\t\t\tScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Sort};\n\t\t\t\t_binaryOperation.rightExpression().accept(*this);\n\t\t\t}\n\t\t\tType leftType = type(_binaryOperation.leftExpression());\n\t\t\tunify(leftType, type(_binaryOperation.rightExpression()), _binaryOperation.location());\n\t\t\toperationAnnotation.type = leftType;\n\t\t}\n\t\telse if (_binaryOperation.getOperator() == Token::RightArrow)\n\t\t{\n\t\t\t_binaryOperation.leftExpression().accept(*this);\n\t\t\t_binaryOperation.rightExpression().accept(*this);\n\t\t\toperationAnnotation.type = helper.functionType(type(_binaryOperation.leftExpression()), type(_binaryOperation.rightExpression()));\n\t\t}\n\t\telse if (_binaryOperation.getOperator() == Token::BitOr)\n\t\t{\n\t\t\t_binaryOperation.leftExpression().accept(*this);\n\t\t\t_binaryOperation.rightExpression().accept(*this);\n\t\t\toperationAnnotation.type = helper.sumType({type(_binaryOperation.leftExpression()), type(_binaryOperation.rightExpression())});\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_errorReporter.typeError(1439_error, _binaryOperation.location(), \"Invalid binary operations in type context.\");\n\t\t\toperationAnnotation.type = m_typeSystem.freshTypeVariable({});\n\t\t}\n\t\treturn false;\n\tcase ExpressionContext::Sort:\n\t\tm_errorReporter.typeError(1017_error, _binaryOperation.location(), \"Invalid binary operation in sort context.\");\n\t\toperationAnnotation.type = m_typeSystem.freshTypeVariable({});\n\t\treturn false;\n\t}\n\treturn false;\n}\n\nvoid TypeInference::endVisit(VariableDeclarationStatement const& _variableDeclarationStatement)\n{\n\tsolAssert(m_expressionContext == ExpressionContext::Term);\n\tif (_variableDeclarationStatement.declarations().size () != 1)\n\t{\n\t\tm_errorReporter.typeError(2655_error, _variableDeclarationStatement.location(), \"Multi variable declaration not supported.\");\n\t\treturn;\n\t}\n\tType variableType = type(*_variableDeclarationStatement.declarations().front());\n\tif (_variableDeclarationStatement.initialValue())\n\t\tunify(variableType, type(*_variableDeclarationStatement.initialValue()), _variableDeclarationStatement.location());\n}\n\nbool TypeInference::visit(VariableDeclaration const& _variableDeclaration)\n{\n\tsolAssert(!_variableDeclaration.value());\n\tauto& variableAnnotation = annotation(_variableDeclaration);\n\tsolAssert(!variableAnnotation.type);\n\n\tswitch (m_expressionContext)\n\t{\n\tcase ExpressionContext::Term:\n\t\tif (_variableDeclaration.typeExpression())\n\t\t{\n\t\t\tScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Type};\n\t\t\t_variableDeclaration.typeExpression()->accept(*this);\n\t\t\tvariableAnnotation.type = type(*_variableDeclaration.typeExpression());\n\t\t\treturn false;\n\t\t}\n\t\tvariableAnnotation.type = m_typeSystem.freshTypeVariable({});\n\t\treturn false;\n\tcase ExpressionContext::Type:\n\t\tvariableAnnotation.type = m_typeSystem.freshTypeVariable({});\n\t\tif (_variableDeclaration.typeExpression())\n\t\t{\n\t\t\tScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Sort};\n\t\t\t_variableDeclaration.typeExpression()->accept(*this);\n\t\t\tunify(*variableAnnotation.type, type(*_variableDeclaration.typeExpression()), _variableDeclaration.typeExpression()->location());\n\t\t}\n\t\treturn false;\n\tcase ExpressionContext::Sort:\n\t\tm_errorReporter.typeError(2399_error, _variableDeclaration.location(), \"Variable declaration in sort context.\");\n\t\tvariableAnnotation.type = m_typeSystem.freshTypeVariable({});\n\t\treturn false;\n\t}\n\tutil::unreachable();\n}\n\nvoid TypeInference::endVisit(IfStatement const& _ifStatement)\n{\n\tauto& ifAnnotation = annotation(_ifStatement);\n\tsolAssert(!ifAnnotation.type);\n\n\tif (m_expressionContext != ExpressionContext::Term)\n\t{\n\t\tm_errorReporter.typeError(2015_error, _ifStatement.location(), \"If statement outside term context.\");\n\t\tifAnnotation.type = m_typeSystem.freshTypeVariable({});\n\t\treturn;\n\t}\n\n\tunify(type(_ifStatement.condition()), m_boolType, _ifStatement.condition().location());\n\n\tifAnnotation.type = m_unitType;\n}\n\nvoid TypeInference::endVisit(Assignment const& _assignment)\n{\n\tauto& assignmentAnnotation = annotation(_assignment);\n\tsolAssert(!assignmentAnnotation.type);\n\n\tif (m_expressionContext != ExpressionContext::Term)\n\t{\n\t\tm_errorReporter.typeError(4337_error, _assignment.location(), \"Assignment outside term context.\");\n\t\tassignmentAnnotation.type = m_typeSystem.freshTypeVariable({});\n\t\treturn;\n\t}\n\n\tType leftType = type(_assignment.leftHandSide());\n\tunify(leftType, type(_assignment.rightHandSide()), _assignment.location());\n\tassignmentAnnotation.type = leftType;\n}\n\nexperimental::Type TypeInference::handleIdentifierByReferencedDeclaration(langutil::SourceLocation _location, Declaration const& _declaration)\n{\n\tswitch (m_expressionContext)\n\t{\n\tcase ExpressionContext::Term:\n\t{\n\t\tif (\n\t\t\t!dynamic_cast<FunctionDefinition const*>(&_declaration) &&\n\t\t\t!dynamic_cast<VariableDeclaration const*>(&_declaration) &&\n\t\t\t!dynamic_cast<TypeClassDefinition const*>(&_declaration) &&\n\t\t\t!dynamic_cast<TypeDefinition const*>(&_declaration)\n\t\t)\n\t\t{\n\t\t\tSecondarySourceLocation ssl;\n\t\t\tssl.append(\"Referenced node.\", _declaration.location());\n\t\t\tm_errorReporter.fatalTypeError(3101_error, _location, ssl, \"Attempt to type identifier referring to unexpected node.\");\n\t\t}\n\n\t\tauto& declarationAnnotation = annotation(_declaration);\n\t\tif (!declarationAnnotation.type)\n\t\t\t_declaration.accept(*this);\n\n\t\tsolAssert(declarationAnnotation.type);\n\n\t\tif (dynamic_cast<VariableDeclaration const*>(&_declaration))\n\t\t\treturn *declarationAnnotation.type;\n\t\telse if (dynamic_cast<FunctionDefinition const*>(&_declaration))\n\t\t\treturn polymorphicInstance(*declarationAnnotation.type);\n\t\telse if (dynamic_cast<TypeClassDefinition const*>(&_declaration))\n\t\t{\n\t\t\tsolAssert(TypeEnvironmentHelpers{*m_env}.typeVars(*declarationAnnotation.type).empty());\n\t\t\treturn *declarationAnnotation.type;\n\t\t}\n\t\telse if (dynamic_cast<TypeDefinition const*>(&_declaration))\n\t\t{\n\t\t\t// TODO: can we avoid this?\n\t\t\tType type = *declarationAnnotation.type;\n\t\t\tif (TypeSystemHelpers{m_typeSystem}.isTypeFunctionType(type))\n\t\t\t\ttype = std::get<1>(TypeSystemHelpers{m_typeSystem}.destTypeFunctionType(type));\n\t\t\treturn polymorphicInstance(type);\n\t\t}\n\t\telse\n\t\t\tsolAssert(false);\n\t\tbreak;\n\t}\n\tcase ExpressionContext::Type:\n\t{\n\t\tif (\n\t\t\t!dynamic_cast<VariableDeclaration const*>(&_declaration) &&\n\t\t\t!dynamic_cast<TypeDefinition const*>(&_declaration)\n\t\t)\n\t\t{\n\t\t\tSecondarySourceLocation ssl;\n\t\t\tssl.append(\"Referenced node.\", _declaration.location());\n\t\t\tm_errorReporter.fatalTypeError(2217_error, _location, ssl, \"Attempt to type identifier referring to unexpected node.\");\n\t\t}\n\n\t\t// TODO: Assert that this is a type class variable declaration?\n\t\tauto& declarationAnnotation = annotation(_declaration);\n\t\tif (!declarationAnnotation.type)\n\t\t\t_declaration.accept(*this);\n\n\t\tsolAssert(declarationAnnotation.type);\n\n\t\tif (dynamic_cast<VariableDeclaration const*>(&_declaration))\n\t\t\treturn *declarationAnnotation.type;\n\t\telse if (dynamic_cast<TypeDefinition const*>(&_declaration))\n\t\t\treturn polymorphicInstance(*declarationAnnotation.type);\n\t\telse\n\t\t\tsolAssert(false);\n\t\tbreak;\n\t}\n\tcase ExpressionContext::Sort:\n\t{\n\t\tif (auto const* typeClassDefinition = dynamic_cast<TypeClassDefinition const*>(&_declaration))\n\t\t{\n\t\t\tScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Term};\n\t\t\ttypeClassDefinition->accept(*this);\n\n\t\t\tsolAssert(m_analysis.annotation<TypeClassRegistration>(*typeClassDefinition).typeClass.has_value());\n\t\t\tTypeClass typeClass = m_analysis.annotation<TypeClassRegistration>(*typeClassDefinition).typeClass.value();\n\t\t\treturn m_typeSystem.freshTypeVariable(Sort{{typeClass}});\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_errorReporter.typeError(2599_error, _location, \"Expected type class.\");\n\t\t\treturn m_typeSystem.freshTypeVariable({});\n\t\t}\n\t\tbreak;\n\t}\n\t}\n\tutil::unreachable();\n}\n\nbool TypeInference::visit(Identifier const& _identifier)\n{\n\tauto& identifierAnnotation = annotation(_identifier);\n\tsolAssert(!identifierAnnotation.type);\n\n\tif (auto const* referencedDeclaration = _identifier.annotation().referencedDeclaration)\n\t{\n\t\tidentifierAnnotation.type = handleIdentifierByReferencedDeclaration(_identifier.location(), *referencedDeclaration);\n\t\treturn false;\n\t}\n\n\tswitch (m_expressionContext)\n\t{\n\tcase ExpressionContext::Term:\n\t\t// TODO: error handling\n\t\tsolAssert(false);\n\t\tbreak;\n\tcase ExpressionContext::Type:\n\t\tm_errorReporter.typeError(5934_error, _identifier.location(), \"Undeclared type variable.\");\n\n\t\t// Assign it a fresh variable anyway just so that we can continue analysis.\n\t\tidentifierAnnotation.type = m_typeSystem.freshTypeVariable({});\n\t\tbreak;\n\tcase ExpressionContext::Sort:\n\t\t// TODO: error handling\n\t\tsolAssert(false);\n\t\tbreak;\n\t}\n\n\treturn false;\n}\n\nvoid TypeInference::endVisit(TupleExpression const& _tupleExpression)\n{\n\tauto& expressionAnnotation = annotation(_tupleExpression);\n\tsolAssert(!expressionAnnotation.type);\n\n\tTypeSystemHelpers helper{m_typeSystem};\n\tauto componentTypes = _tupleExpression.components() | ranges::views::transform([&](auto _expr) -> Type {\n\t\tauto& componentAnnotation = annotation(*_expr);\n\t\tsolAssert(componentAnnotation.type);\n\t\treturn *componentAnnotation.type;\n\t}) | ranges::to<std::vector<Type>>;\n\tswitch (m_expressionContext)\n\t{\n\tcase ExpressionContext::Term:\n\tcase ExpressionContext::Type:\n\t\texpressionAnnotation.type = helper.tupleType(componentTypes);\n\t\tbreak;\n\tcase ExpressionContext::Sort:\n\t{\n\t\tType type = m_typeSystem.freshTypeVariable({});\n\t\tfor (auto componentType: componentTypes)\n\t\t\tunify(type, componentType, _tupleExpression.location());\n\t\texpressionAnnotation.type = type;\n\t\tbreak;\n\t}\n\t}\n}\n\nbool TypeInference::visit(IdentifierPath const& _identifierPath)\n{\n\tauto& identifierAnnotation = annotation(_identifierPath);\n\tsolAssert(!identifierAnnotation.type);\n\n\tif (auto const* referencedDeclaration = _identifierPath.annotation().referencedDeclaration)\n\t{\n\t\tidentifierAnnotation.type = handleIdentifierByReferencedDeclaration(_identifierPath.location(), *referencedDeclaration);\n\t\treturn false;\n\t}\n\n\t// TODO: error handling\n\tsolAssert(false);\n}\n\nbool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation)\n{\n\tScopedSaveAndRestore activeInstantiations{m_activeInstantiations, m_activeInstantiations + std::set<TypeClassInstantiation const*>{&_typeClassInstantiation}};\n\t// Note: recursion is resolved due to special handling during unification.\n\tauto& instantiationAnnotation = annotation(_typeClassInstantiation);\n\tif (instantiationAnnotation.type)\n\t\treturn false;\n\tinstantiationAnnotation.type = m_voidType;\n\tTypeClass typeClass = std::visit(util::GenericVisitor{\n\t\t[&](ASTPointer<IdentifierPath> _typeClassName) -> TypeClass {\n\t\t\tauto const* typeClassDefinition = dynamic_cast<TypeClassDefinition const*>(_typeClassName->annotation().referencedDeclaration);\n\t\t\tsolAssert(typeClassDefinition);\n\n\t\t\t// visiting the type class will re-visit this instantiation\n\t\t\ttypeClassDefinition->accept(*this);\n\t\t\t// TODO: more error handling? Should be covered by the visit above.\n\t\t\tsolAssert(m_analysis.annotation<TypeClassRegistration>(*typeClassDefinition).typeClass.has_value());\n\t\t\treturn m_analysis.annotation<TypeClassRegistration>(*typeClassDefinition).typeClass.value();\n\t\t},\n\t\t[&](Token _token) -> TypeClass {\n\t\t\tstd::optional<BuiltinClass> builtinClass = builtinClassFromToken(_token);\n\t\t\tsolAssert(builtinClass.has_value());\n\t\t\tsolAssert(annotation().builtinClasses.count(*builtinClass) != 0);\n\t\t\treturn annotation().builtinClasses.at(*builtinClass);\n\t\t}\n\t}, _typeClassInstantiation.typeClass().name());\n\n\t// TODO: _typeClassInstantiation.typeConstructor().accept(*this); ?\n\tauto typeConstructor = m_analysis.annotation<TypeRegistration>(_typeClassInstantiation.typeConstructor()).typeConstructor;\n\tsolAssert(typeConstructor);\n\n\tstd::vector<Type> arguments;\n\tArity arity{\n\t\t{},\n\t\ttypeClass\n\t};\n\n\t{\n\t\tScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Type};\n\t\tif (_typeClassInstantiation.argumentSorts())\n\t\t{\n\t\t\t_typeClassInstantiation.argumentSorts()->accept(*this);\n\t\t\tauto& argumentSortAnnotation = annotation(*_typeClassInstantiation.argumentSorts());\n\t\t\tsolAssert(argumentSortAnnotation.type);\n\t\t\targuments = TypeSystemHelpers{m_typeSystem}.destTupleType(*argumentSortAnnotation.type);\n\t\t\tarity.argumentSorts = arguments | ranges::views::transform([&](Type _type) {\n\t\t\t\treturn m_env->sort(_type);\n\t\t\t}) | ranges::to<std::vector<Sort>>;\n\t\t}\n\t}\n\tm_env->fixTypeVars(arguments);\n\n\tType instanceType{TypeConstant{*typeConstructor, arguments}};\n\n\tstd::map<std::string, Type> functionTypes;\n\n\tfor (auto subNode: _typeClassInstantiation.subNodes())\n\t{\n\t\tauto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(subNode.get());\n\t\tsolAssert(functionDefinition);\n\t\tsubNode->accept(*this);\n\t\tif (!functionTypes.emplace(functionDefinition->name(), type(*functionDefinition)).second)\n\t\t\tm_errorReporter.typeError(3654_error, subNode->location(), \"Duplicate definition of function \" + functionDefinition->name() + \" during type class instantiation.\");\n\t}\n\n\tif (auto error = m_typeSystem.instantiateClass(instanceType, arity))\n\t\tm_errorReporter.typeError(5094_error, _typeClassInstantiation.location(), *error);\n\n\tauto const& classFunctions = annotation().typeClassFunctions.at(typeClass);\n\n\tsolAssert(std::holds_alternative<TypeVariable>(m_typeSystem.typeClassVariable(typeClass)));\n\tTypeVariable classVar = std::get<TypeVariable>(m_typeSystem.typeClassVariable(typeClass));\n\n\tfor (auto [name, classFunctionType]: classFunctions)\n\t{\n\t\tif (!functionTypes.count(name))\n\t\t{\n\t\t\tm_errorReporter.typeError(6948_error, _typeClassInstantiation.location(), \"Missing function: \" + name);\n\t\t\tcontinue;\n\t\t}\n\t\tType instantiatedClassFunctionType = TypeEnvironmentHelpers{*m_env}.substitute(classFunctionType, classVar, instanceType);\n\n\t\tType instanceFunctionType = functionTypes.at(name);\n\t\tfunctionTypes.erase(name);\n\n\t\tif (!m_env->typeEquals(instanceFunctionType, instantiatedClassFunctionType))\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t7428_error,\n\t\t\t\t_typeClassInstantiation.location(),\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"Instantiation function '{}' does not match the declaration in the type class ({} != {}).\",\n\t\t\t\t\tname,\n\t\t\t\t\tTypeEnvironmentHelpers{*m_env}.typeToString(instanceFunctionType),\n\t\t\t\t\tTypeEnvironmentHelpers{*m_env}.typeToString(instantiatedClassFunctionType)\n\t\t\t\t)\n\t\t\t);\n\t}\n\n\tif (!functionTypes.empty())\n\t\tm_errorReporter.typeError(4873_error, _typeClassInstantiation.location(), \"Additional functions in class instantiation.\");\n\n\treturn false;\n}\n\nbool TypeInference::visit(MemberAccess const& _memberAccess)\n{\n\tif (m_expressionContext != ExpressionContext::Term)\n\t{\n\t\tm_errorReporter.typeError(5195_error, _memberAccess.location(), \"Member access outside term context.\");\n\t\tannotation(_memberAccess).type = m_typeSystem.freshTypeVariable({});\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nexperimental::Type TypeInference::memberType(Type _type, std::string _memberName, langutil::SourceLocation _location)\n{\n\tType resolvedType = m_env->resolve(_type);\n\tTypeSystemHelpers helper{m_typeSystem};\n\tif (helper.isTypeConstant(resolvedType))\n\t{\n\t\tauto constructor = std::get<0>(helper.destTypeConstant(resolvedType));\n\t\tif (auto* typeMember = util::valueOrNullptr(annotation().members.at(constructor), _memberName))\n\t\t\treturn polymorphicInstance(typeMember->type);\n\t\telse\n\t\t{\n\t\t\tm_errorReporter.typeError(5755_error, _location, fmt::format(\"Member {} not found in type {}.\", _memberName, TypeEnvironmentHelpers{*m_env}.typeToString(_type)));\n\t\t\treturn m_typeSystem.freshTypeVariable({});\n\t\t}\n\t}\n\telse\n\t{\n\t\tm_errorReporter.typeError(5104_error, _location, \"Unsupported member access expression.\");\n\t\treturn m_typeSystem.freshTypeVariable({});\n\t}\n}\n\nvoid TypeInference::endVisit(MemberAccess const& _memberAccess)\n{\n\tauto& memberAccessAnnotation = annotation(_memberAccess);\n\tsolAssert(!memberAccessAnnotation.type);\n\tType expressionType = type(_memberAccess.expression());\n\tmemberAccessAnnotation.type = memberType(expressionType, _memberAccess.memberName(), _memberAccess.location());\n}\n\nbool TypeInference::visit(TypeDefinition const& _typeDefinition)\n{\n\tbool isBuiltIn = dynamic_cast<Builtin const*>(_typeDefinition.typeExpression());\n\n\tTypeSystemHelpers helper{m_typeSystem};\n\tauto& typeDefinitionAnnotation = annotation(_typeDefinition);\n\tif (typeDefinitionAnnotation.type)\n\t\treturn false;\n\n\tif (_typeDefinition.arguments())\n\t{\n\t\tScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Type};\n\t\t_typeDefinition.arguments()->accept(*this);\n\t}\n\n\tstd::vector<Type> arguments;\n\tif (_typeDefinition.arguments())\n\t\tfor (ASTPointer<VariableDeclaration> argumentDeclaration: _typeDefinition.arguments()->parameters())\n\t\t{\n\t\t\tsolAssert(argumentDeclaration);\n\t\t\tType typeVar = type(*argumentDeclaration);\n\t\t\tsolAssert(std::holds_alternative<TypeVariable>(typeVar));\n\t\t\targuments.emplace_back(typeVar);\n\t\t}\n\tm_env->fixTypeVars(arguments);\n\n\tType definedType = type(&_typeDefinition, arguments);\n\tif (arguments.empty())\n\t\ttypeDefinitionAnnotation.type = definedType;\n\telse\n\t\ttypeDefinitionAnnotation.type = helper.typeFunctionType(helper.tupleType(arguments), definedType);\n\n\tstd::optional<Type> underlyingType;\n\n\tif (isBuiltIn)\n\t\t// TODO: This special case should eventually become user-definable.\n\t\tunderlyingType = m_wordType;\n\telse if (_typeDefinition.typeExpression())\n\t{\n\t\tScopedSaveAndRestore expressionContext{m_expressionContext, ExpressionContext::Type};\n\t\t_typeDefinition.typeExpression()->accept(*this);\n\n\t\tunderlyingType = annotation(*_typeDefinition.typeExpression()).type;\n\t}\n\n\tTypeConstructor constructor = typeConstructor(&_typeDefinition);\n\tauto [members, newlyInserted] = annotation().members.emplace(constructor, std::map<std::string, TypeMember>{});\n\tsolAssert(newlyInserted, fmt::format(\"Members of type '{}' are already defined.\", m_typeSystem.constructorInfo(constructor).name));\n\tif (underlyingType)\n\t{\n\t\t// Undeclared type variables are not allowed in type definitions and we fixed all the declared ones.\n\t\tsolAssert(!TypeEnvironmentHelpers{*m_env}.hasGenericTypeVars(*underlyingType));\n\n\t\tmembers->second.emplace(\"abs\", TypeMember{helper.functionType(*underlyingType, definedType)});\n\t\tmembers->second.emplace(\"rep\", TypeMember{helper.functionType(definedType, *underlyingType)});\n\t}\n\n\tif (helper.isPrimitiveType(definedType, PrimitiveType::Pair))\n\t{\n\t\tsolAssert(isBuiltIn);\n\t\tsolAssert(arguments.size() == 2);\n\t\tmembers->second.emplace(\"first\", TypeMember{helper.functionType(definedType, arguments[0])});\n\t\tmembers->second.emplace(\"second\", TypeMember{helper.functionType(definedType, arguments[1])});\n\t}\n\n\treturn false;\n}\n\nbool TypeInference::visit(FunctionCall const&) { return true; }\nvoid TypeInference::endVisit(FunctionCall const& _functionCall)\n{\n\tauto& functionCallAnnotation = annotation(_functionCall);\n\tsolAssert(!functionCallAnnotation.type);\n\n\tType functionType = type(_functionCall.expression());\n\n\tTypeSystemHelpers helper{m_typeSystem};\n\tstd::vector<Type> argTypes;\n\tfor (auto arg: _functionCall.arguments())\n\t{\n\t\tswitch (m_expressionContext)\n\t\t{\n\t\tcase ExpressionContext::Term:\n\t\tcase ExpressionContext::Type:\n\t\t\targTypes.emplace_back(type(*arg));\n\t\t\tbreak;\n\t\tcase ExpressionContext::Sort:\n\t\t\tm_errorReporter.typeError(9173_error, _functionCall.location(), \"Function call in sort context.\");\n\t\t\tfunctionCallAnnotation.type = m_typeSystem.freshTypeVariable({});\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tswitch (m_expressionContext)\n\t{\n\tcase ExpressionContext::Term:\n\t{\n\t\tType argTuple = helper.tupleType(argTypes);\n\t\tType resultType = m_typeSystem.freshTypeVariable({});\n\t\tType genericFunctionType = helper.functionType(argTuple, resultType);\n\t\tunify(functionType, genericFunctionType, _functionCall.location());\n\t\tfunctionCallAnnotation.type = resultType;\n\t\tbreak;\n\t}\n\tcase ExpressionContext::Type:\n\t{\n\t\tType argTuple = helper.tupleType(argTypes);\n\t\tType resultType = m_typeSystem.freshTypeVariable({});\n\t\tType genericFunctionType = helper.typeFunctionType(argTuple, resultType);\n\t\tunify(functionType, genericFunctionType, _functionCall.location());\n\t\tfunctionCallAnnotation.type = resultType;\n\t\tbreak;\n\t}\n\tcase ExpressionContext::Sort:\n\t\tsolAssert(false);\n\t}\n}\n\n// TODO: clean up rational parsing\nnamespace\n{\n\nstd::optional<rational> parseRational(std::string const& _value)\n{\n\trational value;\n\ttry\n\t{\n\t\tauto radixPoint = find(_value.begin(), _value.end(), '.');\n\n\t\tif (radixPoint != _value.end())\n\t\t{\n\t\t\tif (\n\t\t\t\t!all_of(radixPoint + 1, _value.end(), util::isDigit) ||\n\t\t\t\t!all_of(_value.begin(), radixPoint, util::isDigit)\n\t\t\t)\n\t\t\t\treturn std::nullopt;\n\n\t\t\t// Only decimal notation allowed here, leading zeros would switch to octal.\n\t\t\tauto fractionalBegin = find_if_not(\n\t\t\t\tradixPoint + 1,\n\t\t\t\t_value.end(),\n\t\t\t\t[](char const& a) { return a == '0'; }\n\t\t\t);\n\n\t\t\trational numerator;\n\t\t\trational denominator(1);\n\n\t\t\tdenominator = bigint(std::string(fractionalBegin, _value.end()));\n\t\t\tdenominator /= boost::multiprecision::pow(\n\t\t\t\tbigint(10),\n\t\t\t\tstatic_cast<unsigned>(distance(radixPoint + 1, _value.end()))\n\t\t\t);\n\t\t\tnumerator = bigint(std::string(_value.begin(), radixPoint));\n\t\t\tvalue = numerator + denominator;\n\t\t}\n\t\telse\n\t\t\tvalue = bigint(_value);\n\t\treturn value;\n\t}\n\tcatch (...)\n\t{\n\t\treturn std::nullopt;\n\t}\n}\n\n/// Checks whether _mantissa * (10 ** _expBase10) fits into 4096 bits.\nbool fitsPrecisionBase10(bigint const& _mantissa, uint32_t _expBase10)\n{\n\tdouble const log2Of10AwayFromZero = 3.3219280948873624;\n\treturn fitsPrecisionBaseX(_mantissa, log2Of10AwayFromZero, _expBase10);\n}\n\nstd::optional<rational> rationalValue(Literal const& _literal)\n{\n\trational value;\n\ttry\n\t{\n\t\tASTString valueString = _literal.valueWithoutUnderscores();\n\n\t\tauto expPoint = find(valueString.begin(), valueString.end(), 'e');\n\t\tif (expPoint == valueString.end())\n\t\t\texpPoint = find(valueString.begin(), valueString.end(), 'E');\n\n\t\tif (boost::starts_with(valueString, \"0x\"))\n\t\t{\n\t\t\t// process as hex\n\t\t\tvalue = bigint(valueString);\n\t\t}\n\t\telse if (expPoint != valueString.end())\n\t\t{\n\t\t\t// Parse mantissa and exponent. Checks numeric limit.\n\t\t\tstd::optional<rational> mantissa = parseRational(std::string(valueString.begin(), expPoint));\n\n\t\t\tif (!mantissa)\n\t\t\t\treturn std::nullopt;\n\t\t\tvalue = *mantissa;\n\n\t\t\t// 0E... is always zero.\n\t\t\tif (value == 0)\n\t\t\t\treturn std::nullopt;\n\n\t\t\tbigint exp = bigint(std::string(expPoint + 1, valueString.end()));\n\n\t\t\tif (exp > std::numeric_limits<int32_t>::max() || exp < std::numeric_limits<int32_t>::min())\n\t\t\t\treturn std::nullopt;\n\n\t\t\tuint32_t expAbs = bigint(abs(exp)).convert_to<uint32_t>();\n\n\t\t\tif (exp < 0)\n\t\t\t{\n\t\t\t\tif (!fitsPrecisionBase10(abs(value.denominator()), expAbs))\n\t\t\t\t\treturn std::nullopt;\n\t\t\t\tvalue /= boost::multiprecision::pow(\n\t\t\t\t\tbigint(10),\n\t\t\t\t\texpAbs\n\t\t\t\t);\n\t\t\t}\n\t\t\telse if (exp > 0)\n\t\t\t{\n\t\t\t\tif (!fitsPrecisionBase10(abs(value.numerator()), expAbs))\n\t\t\t\t\treturn std::nullopt;\n\t\t\t\tvalue *= boost::multiprecision::pow(\n\t\t\t\t\tbigint(10),\n\t\t\t\t\texpAbs\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// parse as rational number\n\t\t\tstd::optional<rational> tmp = parseRational(valueString);\n\t\t\tif (!tmp)\n\t\t\t\treturn std::nullopt;\n\t\t\tvalue = *tmp;\n\t\t}\n\t}\n\tcatch (...)\n\t{\n\t\treturn std::nullopt;\n\t}\n\tswitch (_literal.subDenomination())\n\t{\n\tcase Literal::SubDenomination::None:\n\tcase Literal::SubDenomination::Wei:\n\tcase Literal::SubDenomination::Second:\n\t\tbreak;\n\tcase Literal::SubDenomination::Gwei:\n\t\tvalue *= bigint(\"1000000000\");\n\t\tbreak;\n\tcase Literal::SubDenomination::Ether:\n\t\tvalue *= bigint(\"1000000000000000000\");\n\t\tbreak;\n\tcase Literal::SubDenomination::Minute:\n\t\tvalue *= bigint(\"60\");\n\t\tbreak;\n\tcase Literal::SubDenomination::Hour:\n\t\tvalue *= bigint(\"3600\");\n\t\tbreak;\n\tcase Literal::SubDenomination::Day:\n\t\tvalue *= bigint(\"86400\");\n\t\tbreak;\n\tcase Literal::SubDenomination::Week:\n\t\tvalue *= bigint(\"604800\");\n\t\tbreak;\n\tcase Literal::SubDenomination::Year:\n\t\tvalue *= bigint(\"31536000\");\n\t\tbreak;\n\t}\n\n\treturn value;\n}\n}\n\nbool TypeInference::visit(Literal const& _literal)\n{\n\tauto& literalAnnotation = annotation(_literal);\n\tif (_literal.token() != Token::Number)\n\t{\n\t\tm_errorReporter.typeError(4316_error, _literal.location(), \"Only number literals are supported.\");\n\t\treturn false;\n\t}\n\tstd::optional<rational> value = rationalValue(_literal);\n\tif (!value)\n\t{\n\t\tm_errorReporter.typeError(6739_error, _literal.location(), \"Invalid number literals.\");\n\t\treturn false;\n\t}\n\tif (value->denominator() != 1)\n\t{\n\t\tm_errorReporter.typeError(2345_error, _literal.location(), \"Only integers are supported.\");\n\t\treturn false;\n\t}\n\tliteralAnnotation.type = m_typeSystem.freshTypeVariable(Sort{{annotation().builtinClasses.at(BuiltinClass::Integer)}});\n\treturn false;\n}\n\n\nnamespace\n{\n// TODO: put at a nice place to deduplicate.\nTypeRegistration::TypeClassInstantiations const& typeClassInstantiations(Analysis const& _analysis, TypeClass _class)\n{\n\tauto const* typeClassDeclaration = _analysis.typeSystem().typeClassDeclaration(_class);\n\tif (typeClassDeclaration)\n\t\treturn _analysis.annotation<TypeRegistration>(*typeClassDeclaration).instantiations;\n\t// TODO: better mechanism than fetching by name.\n\tauto const& annotation = _analysis.annotation<TypeRegistration>();\n\tauto const& inferenceAnnotation = _analysis.annotation<TypeInference>();\n\treturn annotation.builtinClassInstantiations.at(\n\t\tinferenceAnnotation.builtinClassesByName.at(\n\t\t\t_analysis.typeSystem().typeClassName(_class)\n\t\t)\n\t);\n}\n}\n\nexperimental::Type TypeInference::polymorphicInstance(Type const& _scheme)\n{\n\treturn m_env->fresh(_scheme);\n}\n\nvoid TypeInference::unify(Type _a, Type _b, langutil::SourceLocation _location)\n{\n\tTypeSystemHelpers helper{m_typeSystem};\n\tauto unificationFailures = m_env->unify(_a, _b);\n\n\tif (!m_activeInstantiations.empty())\n\t{\n\t\t// TODO: This entire logic is superfluous - I thought mutually recursive dependencies between\n\t\t// class instantiations are a problem, but in fact they're not, they just resolve to mutually recursive\n\t\t// functions that are fine. So instead, all instantiations can be registered with the type system directly\n\t\t// when visiting the type class (assuming that they all work out) - and then all instantiations can be checked\n\t\t// individually, which should still catch all actual issues (while allowing recursions).\n\t\t// Original comment: Attempt to resolve interdependencies between type class instantiations.\n\t\tstd::vector<TypeClassInstantiation const*> missingInstantiations;\n\t\tbool recursion = false;\n\t\tbool onlyMissingInstantiations = [&]() {\n\t\t\tfor (auto failure: unificationFailures)\n\t\t\t{\n\t\t\t\tif (auto* sortMismatch = std::get_if<TypeEnvironment::SortMismatch>(&failure))\n\t\t\t\t\tif (helper.isTypeConstant(sortMismatch->type))\n\t\t\t\t\t{\n\t\t\t\t\t\tTypeConstructor constructor = std::get<0>(helper.destTypeConstant(sortMismatch->type));\n\t\t\t\t\t\tfor (auto typeClass: sortMismatch->sort.classes)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (auto const* instantiation = util::valueOrDefault(typeClassInstantiations(m_analysis, typeClass), constructor, nullptr))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (m_activeInstantiations.count(instantiation))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlangutil::SecondarySourceLocation ssl;\n\t\t\t\t\t\t\t\t\tfor (auto activeInstantiation: m_activeInstantiations)\n\t\t\t\t\t\t\t\t\t\tssl.append(\"Involved instantiation\", activeInstantiation->location());\n\t\t\t\t\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t\t\t\t\t3573_error,\n\t\t\t\t\t\t\t\t\t\t_location,\n\t\t\t\t\t\t\t\t\t\tssl,\n\t\t\t\t\t\t\t\t\t\t\"Recursion during type class instantiation.\"\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\trecursion = true;\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tmissingInstantiations.emplace_back(instantiation);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}();\n\n\t\tif (recursion)\n\t\t\treturn;\n\n\t\tif (onlyMissingInstantiations)\n\t\t{\n\t\t\tfor (auto instantiation: missingInstantiations)\n\t\t\t\tinstantiation->accept(*this);\n\t\t\tunificationFailures = m_env->unify(_a, _b);\n\t\t}\n\t}\n\n\tfor (auto failure: unificationFailures)\n\t{\n\t\tTypeEnvironmentHelpers envHelper{*m_env};\n\t\tstd::visit(util::GenericVisitor{\n\t\t\t[&](TypeEnvironment::TypeMismatch _typeMismatch) {\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t8456_error,\n\t\t\t\t\t_location,\n\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\"Cannot unify {} and {}.\",\n\t\t\t\t\t\tenvHelper.typeToString(_typeMismatch.a),\n\t\t\t\t\t\tenvHelper.typeToString(_typeMismatch.b)\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t},\n\t\t\t[&](TypeEnvironment::SortMismatch _sortMismatch) {\n\t\t\t\tm_errorReporter.typeError(3111_error, _location, fmt::format(\n\t\t\t\t\t\"{} does not have sort {}\",\n\t\t\t\t\tenvHelper.typeToString(_sortMismatch.type),\n\t\t\t\t\tTypeSystemHelpers{m_typeSystem}.sortToString(_sortMismatch.sort)\n\t\t\t\t));\n\t\t\t},\n\t\t\t[&](TypeEnvironment::RecursiveUnification _recursiveUnification) {\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t6460_error,\n\t\t\t\t\t_location,\n\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\"Recursive unification: {} occurs in {}.\",\n\t\t\t\t\t\tenvHelper.typeToString(_recursiveUnification.var),\n\t\t\t\t\t\tenvHelper.typeToString(_recursiveUnification.type)\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}, failure);\n\t}\n}\n\nexperimental::Type TypeInference::type(ASTNode const& _node) const\n{\n\tauto result = annotation(_node).type;\n\tsolAssert(result);\n\treturn *result;\n}\nTypeConstructor TypeInference::typeConstructor(Declaration const* _type) const\n{\n\tif (auto const& constructor = m_analysis.annotation<TypeRegistration>(*_type).typeConstructor)\n\t\treturn *constructor;\n\tm_errorReporter.fatalTypeError(5904_error, _type->location(), \"Unregistered type.\");\n\tutil::unreachable();\n}\nexperimental::Type TypeInference::type(Declaration const* _type, std::vector<Type> _arguments) const\n{\n\treturn m_typeSystem.type(typeConstructor(_type), std::move(_arguments));\n}\n\nbool TypeInference::visitNode(ASTNode const& _node)\n{\n\tm_errorReporter.fatalTypeError(5348_error, _node.location(), \"Unsupported AST node during type inference.\");\n\treturn false;\n}\n\nTypeInference::Annotation& TypeInference::annotation(ASTNode const& _node)\n{\n\treturn m_analysis.annotation<TypeInference>(_node);\n}\n\nTypeInference::Annotation const& TypeInference::annotation(ASTNode const& _node) const\n{\n\treturn m_analysis.annotation<TypeInference>(_node);\n}\n\nTypeInference::GlobalAnnotation& TypeInference::annotation()\n{\n\treturn m_analysis.annotation<TypeInference>();\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/TypeInference.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/experimental/ast/TypeSystem.h>\n\n#include <liblangutil/ErrorReporter.h>\n\nnamespace solidity::frontend::experimental\n{\n\nclass Analysis;\n\nclass TypeInference: public ASTConstVisitor\n{\npublic:\n\tTypeInference(Analysis& _analysis);\n\n\tbool analyze(SourceUnit const& _sourceUnit);\n\n\tstruct Annotation\n\t{\n\t\t/// Expressions, variable declarations, function declarations.\n\t\tstd::optional<Type> type;\n\t};\n\tstruct TypeMember\n\t{\n\t\tType type;\n\t};\n\tstruct GlobalAnnotation\n\t{\n\t\tstd::map<BuiltinClass, TypeClass> builtinClasses;\n\t\tstd::map<std::string, BuiltinClass> builtinClassesByName;\n\t\tstd::map<TypeClass, std::map<std::string, Type>> typeClassFunctions;\n\t\tstd::map<Token, std::tuple<TypeClass, std::string>> operators;\n\t\tstd::map<TypeConstructor, std::map<std::string, TypeMember>> members;\n\t};\n\tbool visit(Block const&) override { return true; }\n\tbool visit(VariableDeclarationStatement const&) override { return true; }\n\tvoid endVisit(VariableDeclarationStatement const& _variableDeclarationStatement) override;\n\tbool visit(VariableDeclaration const& _variableDeclaration) override;\n\n\tbool visit(ForAllQuantifier const& _forAllQuantifier) override;\n\tbool visit(FunctionDefinition const& _functionDefinition) override;\n\tvoid endVisit(FunctionDefinition const& _functionDefinition) override;\n\tbool visit(ParameterList const&) override { return true; }\n\tvoid endVisit(ParameterList const& _parameterList) override;\n\tbool visit(SourceUnit const&) override { return true; }\n\tbool visit(ContractDefinition const&) override { return true; }\n\tbool visit(InlineAssembly const& _inlineAssembly) override;\n\tbool visit(ImportDirective const&) override { return true; }\n\tbool visit(PragmaDirective const&) override { return false; }\n\n\tbool visit(IfStatement const&) override { return true; }\n\tvoid endVisit(IfStatement const& _ifStatement) override;\n\tbool visit(ExpressionStatement const&) override { return true; }\n\tbool visit(Assignment const&) override { return true; }\n\tvoid endVisit(Assignment const& _assignment) override;\n\tbool visit(Identifier const&) override;\n\tbool visit(IdentifierPath const&) override;\n\tbool visit(FunctionCall const& _functionCall) override;\n\tvoid endVisit(FunctionCall const& _functionCall) override;\n\tbool visit(Return const&) override { return true; }\n\tvoid endVisit(Return const& _return) override;\n\n\tbool visit(MemberAccess const& _memberAccess) override;\n\tvoid endVisit(MemberAccess const& _memberAccess) override;\n\n\tbool visit(TypeClassDefinition const& _typeClassDefinition) override;\n\tbool visit(TypeClassInstantiation const& _typeClassInstantiation) override;\n\tbool visit(TupleExpression const&) override { return true; }\n\tvoid endVisit(TupleExpression const& _tupleExpression) override;\n\tbool visit(TypeDefinition const& _typeDefinition) override;\n\n\tbool visitNode(ASTNode const& _node) override;\n\n\tbool visit(BinaryOperation const& _operation) override;\n\n\tbool visit(Literal const& _literal) override;\nprivate:\n\tAnalysis& m_analysis;\n\tlangutil::ErrorReporter& m_errorReporter;\n\tTypeSystem& m_typeSystem;\n\tTypeEnvironment* m_env = nullptr;\n\tType m_voidType;\n\tType m_wordType;\n\tType m_integerType;\n\tType m_unitType;\n\tType m_boolType;\n\tstd::optional<Type> m_currentFunctionType;\n\n\tType type(ASTNode const& _node) const;\n\n\tAnnotation& annotation(ASTNode const& _node);\n\tAnnotation const& annotation(ASTNode const& _node) const;\n\tGlobalAnnotation& annotation();\n\n\tvoid unify(Type _a, Type _b, langutil::SourceLocation _location = {});\n\t/// Creates a polymorphic instance of a global type scheme\n\tType polymorphicInstance(Type const& _scheme);\n\tType memberType(Type _type, std::string _memberName, langutil::SourceLocation _location = {});\n\tenum class ExpressionContext { Term, Type, Sort };\n\tType handleIdentifierByReferencedDeclaration(langutil::SourceLocation _location, Declaration const& _declaration);\n\tTypeConstructor typeConstructor(Declaration const* _type) const;\n\tType type(Declaration const* _type, std::vector<Type> _arguments) const;\n\tExpressionContext m_expressionContext = ExpressionContext::Term;\n\tstd::set<TypeClassInstantiation const*, ASTCompareByID<TypeClassInstantiation>> m_activeInstantiations;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/TypeRegistration.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n\n#include <libsolidity/experimental/analysis/TypeRegistration.h>\n#include <libsolidity/experimental/analysis/Analysis.h>\n#include <libsolidity/experimental/ast/TypeSystemHelper.h>\n#include <liblangutil/Exceptions.h>\n\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/AST.h>\n\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::experimental;\nusing namespace solidity::langutil;\n\nTypeRegistration::TypeRegistration(Analysis& _analysis):\n\tm_analysis(_analysis),\n\tm_errorReporter(_analysis.errorReporter()),\n\tm_typeSystem(_analysis.typeSystem())\n{\n}\n\nbool TypeRegistration::analyze(SourceUnit const& _sourceUnit)\n{\n\t_sourceUnit.accept(*this);\n\treturn !m_errorReporter.hasErrors();\n}\n\nbool TypeRegistration::visit(TypeClassDefinition const& _typeClassDefinition)\n{\n\tif (annotation(_typeClassDefinition).typeConstructor)\n\t\treturn false;\n\tannotation(_typeClassDefinition).typeConstructor = m_typeSystem.declareTypeConstructor(\n\t\t_typeClassDefinition.name(),\n\t\t\"t_\" + *_typeClassDefinition.annotation().canonicalName + \"_\" + util::toString(_typeClassDefinition.id()),\n\t\t0,\n\t\t&_typeClassDefinition\n\t);\n\treturn true;\n}\n\nbool TypeRegistration::visit(Builtin const& _builtin)\n{\n\tif (annotation(_builtin).typeConstructor)\n\t\treturn false;\n\n\tauto primitiveType = [&](std::string _name) -> std::optional<PrimitiveType> {\n\t\tif (_name == \"void\") return PrimitiveType::Void;\n\t\tif (_name == \"fun\") return PrimitiveType::Function;\n\t\tif (_name == \"unit\") return PrimitiveType::Unit;\n\t\tif (_name == \"pair\") return PrimitiveType::Pair;\n\t\tif (_name == \"word\") return PrimitiveType::Word;\n\t\tif (_name == \"integer\") return PrimitiveType::Integer;\n\t\tif (_name == \"bool\") return PrimitiveType::Bool;\n\t\treturn std::nullopt;\n\t}(_builtin.nameParameter());\n\n\tif (!primitiveType.has_value())\n\t\tm_errorReporter.fatalTypeError(\n\t\t\t7758_error,\n\t\t\t_builtin.location(),\n\t\t\t\"Expected the name of a built-in primitive type.\"\n\t\t);\n\n\tannotation(_builtin).typeConstructor = m_typeSystem.constructor(primitiveType.value());\n\treturn true;\n}\n\nvoid TypeRegistration::endVisit(ElementaryTypeNameExpression const & _typeNameExpression)\n{\n\tif (annotation(_typeNameExpression).typeConstructor)\n\t\treturn;\n\n\t// TODO: this is not visited in the ElementaryTypeNameExpression visit - is that intentional?\n\t_typeNameExpression.type().accept(*this);\n\tif (auto constructor = annotation(_typeNameExpression.type()).typeConstructor)\n\t\tannotation(_typeNameExpression).typeConstructor = constructor;\n\telse\n\t\tsolAssert(m_errorReporter.hasErrors());\n}\n\nbool TypeRegistration::visit(UserDefinedTypeName const& _userDefinedTypeName)\n{\n\tif (annotation(_userDefinedTypeName).typeConstructor)\n\t\treturn false;\n\tauto const* declaration = _userDefinedTypeName.pathNode().annotation().referencedDeclaration;\n\tif (!declaration)\n\t{\n\t\t// TODO: fatal/non-fatal\n\t\tm_errorReporter.fatalTypeError(5096_error, _userDefinedTypeName.pathNode().location(), \"Expected declaration.\");\n\t\treturn false;\n\t}\n\tdeclaration->accept(*this);\n\tif (!(annotation(_userDefinedTypeName).typeConstructor = annotation(*declaration).typeConstructor))\n\t{\n\t\t// TODO: fatal/non-fatal\n\t\tm_errorReporter.fatalTypeError(9831_error, _userDefinedTypeName.pathNode().location(), \"Expected type declaration.\");\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nbool TypeRegistration::visit(TypeClassInstantiation const& _typeClassInstantiation)\n{\n\tif (annotation(_typeClassInstantiation).typeConstructor)\n\t\treturn false;\n\t_typeClassInstantiation.typeConstructor().accept(*this);\n\tauto typeConstructor = annotation(_typeClassInstantiation.typeConstructor()).typeConstructor;\n\tif (!typeConstructor)\n\t{\n\t\tm_errorReporter.typeError(5577_error, _typeClassInstantiation.typeConstructor().location(), \"Invalid type name.\");\n\t\treturn false;\n\t}\n\tauto* instantiations = std::visit(util::GenericVisitor{\n\t\t[&](ASTPointer<IdentifierPath> _path) -> TypeClassInstantiations*\n\t\t{\n\t\t\tif (TypeClassDefinition const* classDefinition = dynamic_cast<TypeClassDefinition const*>(_path->annotation().referencedDeclaration))\n\t\t\t\treturn &annotation(*classDefinition).instantiations;\n\t\t\tm_errorReporter.typeError(3570_error, _typeClassInstantiation.typeClass().location(), \"Expected a type class.\");\n\t\t\treturn nullptr;\n\t\t},\n\t\t[&](Token _token) -> TypeClassInstantiations*\n\t\t{\n\t\t\tif (auto typeClass = builtinClassFromToken(_token))\n\t\t\t\treturn &annotation().builtinClassInstantiations[*typeClass];\n\t\t\tm_errorReporter.typeError(5262_error, _typeClassInstantiation.typeClass().location(), \"Expected a type class.\");\n\t\t\treturn nullptr;\n\t\t}\n\t}, _typeClassInstantiation.typeClass().name());\n\n\tif (!instantiations)\n\t\treturn false;\n\n\tif (\n\t\tauto [instantiation, newlyInserted] = instantiations->emplace(*typeConstructor, &_typeClassInstantiation);\n\t\t!newlyInserted\n\t)\n\t{\n\t\tSecondarySourceLocation ssl;\n\t\tssl.append(\"Previous instantiation.\", instantiation->second->location());\n\t\tm_errorReporter.typeError(6620_error, _typeClassInstantiation.location(), ssl, \"Duplicate type class instantiation.\");\n\t}\n\n\treturn true;\n}\n\nbool TypeRegistration::visit(TypeDefinition const& _typeDefinition)\n{\n\treturn !annotation(_typeDefinition).typeConstructor.has_value();\n}\n\nvoid TypeRegistration::endVisit(TypeDefinition const& _typeDefinition)\n{\n\tif (annotation(_typeDefinition).typeConstructor.has_value())\n\t\treturn;\n\n\tif (auto const* builtin = dynamic_cast<Builtin const*>(_typeDefinition.typeExpression()))\n\t{\n\t\tauto [previousDefinitionIt, inserted] = annotation().builtinTypeDefinitions.try_emplace(\n\t\t\tbuiltin->nameParameter(),\n\t\t\t&_typeDefinition\n\t\t);\n\n\t\tif (inserted)\n\t\t\tannotation(_typeDefinition).typeConstructor = annotation(*builtin).typeConstructor;\n\t\telse\n\t\t{\n\t\t\tauto const& [builtinName, previousDefinition] = *previousDefinitionIt;\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t9609_error,\n\t\t\t\t_typeDefinition.location(),\n\t\t\t\tSecondarySourceLocation{}.append(\"Previous definition:\", previousDefinition->location()),\n\t\t\t\t\"Duplicate builtin type definition.\"\n\t\t\t);\n\t\t}\n\t}\n\telse\n\t\tannotation(_typeDefinition).typeConstructor = m_typeSystem.declareTypeConstructor(\n\t\t\t_typeDefinition.name(),\n\t\t\t\"t_\" + *_typeDefinition.annotation().canonicalName + \"_\" + util::toString(_typeDefinition.id()),\n\t\t\t_typeDefinition.arguments() ? _typeDefinition.arguments()->parameters().size() : 0,\n\t\t\t&_typeDefinition\n\t\t);\n}\n\nTypeRegistration::Annotation& TypeRegistration::annotation(ASTNode const& _node)\n{\n\treturn m_analysis.annotation<TypeRegistration>(_node);\n}\n\nTypeRegistration::GlobalAnnotation& TypeRegistration::annotation()\n{\n\treturn m_analysis.annotation<TypeRegistration>();\n}\n"
  },
  {
    "path": "libsolidity/experimental/analysis/TypeRegistration.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/experimental/ast/TypeSystem.h>\n\n#include <liblangutil/ErrorReporter.h>\n\nnamespace solidity::frontend::experimental\n{\n\nclass Analysis;\n\nclass TypeRegistration: public ASTConstVisitor\n{\npublic:\n\tusing TypeClassInstantiations = std::map<TypeConstructor, TypeClassInstantiation const*>;\n\tstruct Annotation\n\t{\n\t\t// For type class definitions.\n\t\tTypeClassInstantiations instantiations;\n\t\t// For builtins, type definitions, type class definitions, type names and type name expressions.\n\t\tstd::optional<TypeConstructor> typeConstructor;\n\t};\n\tstruct GlobalAnnotation\n\t{\n\t\tstd::map<PrimitiveClass, TypeClassInstantiations> primitiveClassInstantiations;\n\t\tstd::map<BuiltinClass, TypeClassInstantiations> builtinClassInstantiations;\n\t\tstd::map<std::string, TypeDefinition const*> builtinTypeDefinitions;\n\t};\n\tTypeRegistration(Analysis& _analysis);\n\n\tbool analyze(SourceUnit const& _sourceUnit);\nprivate:\n\tbool visit(TypeClassDefinition const& _typeClassDefinition) override;\n\tbool visit(TypeClassInstantiation const& _typeClassInstantiation) override;\n\tbool visit(TypeDefinition const& _typeDefinition) override;\n\tvoid endVisit(TypeDefinition const& _typeDefinition) override;\n\tbool visit(UserDefinedTypeName const& _typeName) override;\n\tvoid endVisit(ElementaryTypeNameExpression const& _typeName) override;\n\tbool visit(Builtin const& _builtin) override;\n\tAnnotation& annotation(ASTNode const& _node);\n\tGlobalAnnotation& annotation();\n\n\tAnalysis& m_analysis;\n\tlangutil::ErrorReporter& m_errorReporter;\n\tTypeSystem& m_typeSystem;\n\tstd::set<int64_t> m_visitedClasses;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/ast/FunctionCallGraph.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n/// Data structure representing a function dependency graph.\n\n#pragma once\n\n#include <libsolidity/ast/AST.h>\n\n#include <map>\n#include <set>\n#include <ostream>\n\nnamespace solidity::frontend::experimental\n{\n\nstruct FunctionDependencyGraph\n{\n\t/// Graph edges. Edges are directed and lead from the caller to the callee.\n\t/// The map contains a key for every function, even if does not actually perform\n\t/// any calls.\n\tstd::map<FunctionDefinition const*, std::set<FunctionDefinition const*, ASTCompareByID<FunctionDefinition>>, ASTCompareByID<FunctionDefinition>> edges;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/ast/Type.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/experimental/ast/Type.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/view/drop_last.hpp>\n#include <range/v3/view/zip.hpp>\n\n#include <sstream>\n\nusing namespace solidity;\nusing namespace solidity::frontend::experimental;\n\nbool Sort::operator==(Sort const& _rhs) const\n{\n\tif (classes.size() != _rhs.classes.size())\n\t\treturn false;\n\tfor (auto [lhs, rhs]: ranges::zip_view(classes, _rhs.classes))\n\t\tif (lhs != rhs)\n\t\t\treturn false;\n\treturn true;\n}\n\nbool Sort::operator<=(Sort const& _rhs) const\n{\n\tfor (auto c: classes)\n\t\tif (!_rhs.classes.count(c))\n\t\t\treturn false;\n\treturn true;\n}\n\nSort Sort::operator+(Sort const& _rhs) const\n{\n\tSort result { classes };\n\tresult.classes += _rhs.classes;\n\treturn result;\n}\n\n\nSort Sort::operator-(Sort const& _rhs) const\n{\n\tSort result { classes };\n\tresult.classes -= _rhs.classes;\n\treturn result;\n}\n"
  },
  {
    "path": "libsolidity/experimental/ast/Type.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <cstddef>\n#include <set>\n#include <variant>\n#include <vector>\n\nnamespace solidity::frontend::experimental\n{\n\nclass TypeSystem;\n\nstruct TypeConstant;\nstruct TypeVariable;\n\nusing Type = std::variant<std::monostate, TypeConstant, TypeVariable>;\n\nenum class PrimitiveType\n{\n\tVoid,\n\tFunction,\n\tTypeFunction,\n\tItself,\n\tUnit,\n\tPair,\n\tSum,\n\tWord,\n\tBool,\n\tInteger\n};\n\nenum class PrimitiveClass\n{\n\tType\n};\n\n// TODO: move elsewhere?\nenum class BuiltinClass\n{\n\tInteger,\n\tMul,\n\tAdd,\n\tEqual,\n\tLess,\n\tLessOrEqual,\n\tGreater,\n\tGreaterOrEqual\n};\n\nstruct TypeConstructor\n{\npublic:\n\tTypeConstructor(TypeConstructor const& _typeConstructor): m_index(_typeConstructor.m_index) {}\n\tTypeConstructor& operator=(TypeConstructor const& _typeConstructor)\n\t{\n\t\tm_index = _typeConstructor.m_index;\n\t\treturn *this;\n\t}\n\tbool operator<(TypeConstructor const& _rhs) const\n\t{\n\t\treturn m_index < _rhs.m_index;\n\t}\n\tbool operator==(TypeConstructor const& _rhs) const\n\t{\n\t\treturn m_index == _rhs.m_index;\n\t}\n\tbool operator!=(TypeConstructor const& _rhs) const\n\t{\n\t\treturn m_index != _rhs.m_index;\n\t}\nprivate:\n\tfriend class TypeSystem;\n\tTypeConstructor(std::size_t _index): m_index(_index) {}\n\tstd::size_t m_index = 0;\n};\n\nstruct TypeConstant\n{\n\tTypeConstructor constructor;\n\tstd::vector<Type> arguments;\n};\n\nstruct TypeClass\n{\npublic:\n\tTypeClass(TypeClass const& _typeClass): m_index(_typeClass.m_index) {}\n\tTypeClass& operator=(TypeClass const& _typeConstructor)\n\t{\n\t\tm_index = _typeConstructor.m_index;\n\t\treturn *this;\n\t}\n\tbool operator<(TypeClass const& _rhs) const\n\t{\n\t\treturn m_index < _rhs.m_index;\n\t}\n\tbool operator==(TypeClass const& _rhs) const\n\t{\n\t\treturn m_index == _rhs.m_index;\n\t}\n\tbool operator!=(TypeClass const& _rhs) const\n\t{\n\t\treturn m_index != _rhs.m_index;\n\t}\nprivate:\n\tfriend class TypeSystem;\n\tTypeClass(std::size_t _index): m_index(_index) {}\n\tstd::size_t m_index = 0;\n};\n\nstruct Sort\n{\n\tstd::set<TypeClass> classes;\n\tbool operator==(Sort const& _rhs) const;\n\tbool operator!=(Sort const& _rhs) const { return !operator==(_rhs); }\n\tbool operator<=(Sort const& _rhs) const;\n\tSort operator+(Sort const& _rhs) const;\n\tSort operator-(Sort const& _rhs) const;\n};\n\nstruct Arity\n{\n\tstd::vector<Sort> argumentSorts;\n\tTypeClass typeClass;\n};\n\nstruct TypeVariable\n{\n\tstd::size_t index() const { return m_index; }\n\tSort const& sort() const { return m_sort; }\nprivate:\n\tfriend class TypeSystem;\n\tstd::size_t m_index = 0;\n\tSort m_sort;\n\tTypeVariable(std::size_t _index, Sort _sort): m_index(_index), m_sort(std::move(_sort)) {}\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/ast/TypeSystem.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n\n#include <libsolidity/experimental/ast/TypeSystem.h>\n#include <libsolidity/experimental/ast/TypeSystemHelper.h>\n#include <libsolidity/ast/AST.h>\n#include <liblangutil/Exceptions.h>\n\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/range/conversion.hpp>\n\n#include <range/v3/view/drop_exactly.hpp>\n#include <range/v3/view/drop_last.hpp>\n#include <range/v3/view/reverse.hpp>\n#include <range/v3/view/zip.hpp>\n\n#include <fmt/format.h>\n\n#include <unordered_map>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::experimental;\n\nstd::vector<TypeEnvironment::UnificationFailure> TypeEnvironment::unify(Type _a, Type _b)\n{\n\tstd::vector<UnificationFailure> failures;\n\tauto unificationFailure = [&]() {\n\t\tfailures.emplace_back(UnificationFailure{TypeMismatch{_a, _b}});\n\t};\n\t_a = resolve(_a);\n\t_b = resolve(_b);\n\tstd::visit(util::GenericVisitor{\n\t\t[&](TypeVariable _left, TypeVariable _right) {\n\t\t\tif (_left.index() == _right.index())\n\t\t\t\tsolAssert(_left.sort() == _right.sort());\n\t\t\telse if (isFixedTypeVar(_left) && isFixedTypeVar(_right))\n\t\t\t\tunificationFailure();\n\t\t\telse if (isFixedTypeVar(_left))\n\t\t\t\tfailures += instantiate(_right, _left);\n\t\t\telse if (isFixedTypeVar(_right))\n\t\t\t\tfailures += instantiate(_left, _right);\n\t\t\telse if (_left.sort() <= _right.sort())\n\t\t\t\tfailures += instantiate(_left, _right);\n\t\t\telse if (_right.sort() <= _left.sort())\n\t\t\t\tfailures += instantiate(_right, _left);\n\t\t\telse\n\t\t\t{\n\t\t\t\tType newVar = m_typeSystem.freshVariable(_left.sort() + _right.sort());\n\t\t\t\tfailures += instantiate(_left, newVar);\n\t\t\t\tfailures += instantiate(_right, newVar);\n\t\t\t}\n\t\t},\n\t\t[&](TypeVariable _var, auto) {\n\t\t\tfailures += instantiate(_var, _b);\n\t\t},\n\t\t[&](auto, TypeVariable _var) {\n\t\t\tfailures += instantiate(_var, _a);\n\t\t},\n\t\t[&](TypeConstant _left, TypeConstant _right) {\n\t\t\tif (_left.constructor != _right.constructor)\n\t\t\t\treturn unificationFailure();\n\t\t\tif (_left.arguments.size() != _right.arguments.size())\n\t\t\t\treturn unificationFailure();\n\t\t\tfor (auto&& [left, right]: ranges::zip_view(_left.arguments, _right.arguments))\n\t\t\t\tfailures += unify(left, right);\n\t\t},\n\t\t[&](auto, auto) {\n\t\t\tunificationFailure();\n\t\t}\n\t}, _a, _b);\n\treturn failures;\n}\n\nbool TypeEnvironment::typeEquals(Type _lhs, Type _rhs) const\n{\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](TypeVariable _left, TypeVariable _right) {\n\t\t\tif (_left.index() == _right.index())\n\t\t\t{\n\t\t\t\tsolAssert(_left.sort() == _right.sort());\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\t[&](TypeConstant _left, TypeConstant _right) {\n\t\t\tif (_left.constructor != _right.constructor)\n\t\t\t\treturn false;\n\t\t\tif (_left.arguments.size() != _right.arguments.size())\n\t\t\t\treturn false;\n\t\t\tfor (auto&& [left, right]: ranges::zip_view(_left.arguments, _right.arguments))\n\t\t\t\tif (!typeEquals(left, right))\n\t\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t},\n\t\t[&](auto, auto) {\n\t\t\treturn false;\n\t\t}\n\t}, resolve(_lhs), resolve(_rhs));\n}\n\n\nbool TypeEnvironment::isFixedTypeVar(Type const& _typeVar) const\n{\n\treturn\n\t\tstd::holds_alternative<TypeVariable>(_typeVar) &&\n\t\tm_fixedTypeVariables.count(std::get<TypeVariable>(_typeVar).index()) != 0;\n}\n\nvoid TypeEnvironment::fixTypeVars(std::vector<Type> const& _typeVars)\n{\n\tfor (Type const& typeVar: _typeVars)\n\t{\n\t\tsolAssert(std::holds_alternative<TypeVariable>(typeVar));\n\t\tm_fixedTypeVariables.insert(std::get<TypeVariable>(typeVar).index());\n\t}\n}\n\nTypeEnvironment TypeEnvironment::clone() const\n{\n\tTypeEnvironment result{m_typeSystem};\n\tresult.m_typeVariables = m_typeVariables;\n\treturn result;\n}\n\nTypeSystem::TypeSystem()\n{\n\tauto declarePrimitiveClass = [&](std::string _name) {\n\t\treturn std::visit(util::GenericVisitor{\n\t\t\t[](std::string _error) -> TypeClass {\n\t\t\t\tsolAssert(false, _error);\n\t\t\t},\n\t\t\t[](TypeClass _class) -> TypeClass { return _class; }\n\t\t}, declareTypeClass(_name, nullptr, true /* _primitive */));\n\t};\n\n\tm_primitiveTypeClasses.emplace(PrimitiveClass::Type, declarePrimitiveClass(\"type\"));\n\n\tfor (auto [type, name, arity]: std::initializer_list<std::tuple<PrimitiveType, char const*, size_t>>{\n\t\t{PrimitiveType::TypeFunction, \"tfun\", 2},\n\t\t{PrimitiveType::Function, \"fun\", 2},\n\t\t{PrimitiveType::Itself, \"itself\", 1},\n\t\t{PrimitiveType::Void, \"void\", 0},\n\t\t{PrimitiveType::Unit, \"unit\", 0},\n\t\t{PrimitiveType::Pair, \"pair\", 2},\n\t\t{PrimitiveType::Sum, \"sum\", 2},\n\t\t{PrimitiveType::Word, \"word\", 0},\n\t\t{PrimitiveType::Integer, \"integer\", 0},\n\t\t{PrimitiveType::Bool, \"bool\", 0},\n\t})\n\t\tm_primitiveTypeConstructors.emplace(type, declareTypeConstructor(name, name, arity, nullptr));\n\n\tTypeClass classType = primitiveClass(PrimitiveClass::Type);\n\t//TypeClass classKind = primitiveClass(PrimitiveClass::Kind);\n\tSort typeSort{{classType}};\n\tm_typeConstructors.at(m_primitiveTypeConstructors.at(PrimitiveType::TypeFunction).m_index).arities = {Arity{std::vector<Sort>{{typeSort},{typeSort}}, classType}};\n\tm_typeConstructors.at(m_primitiveTypeConstructors.at(PrimitiveType::Function).m_index).arities = {Arity{std::vector<Sort>{{typeSort, typeSort}}, classType}};\n\tm_typeConstructors.at(m_primitiveTypeConstructors.at(PrimitiveType::Itself).m_index).arities = {Arity{std::vector<Sort>{{typeSort, typeSort}}, classType}};\n}\n\nexperimental::Type TypeSystem::freshVariable(Sort _sort)\n{\n\tsize_t index = m_numTypeVariables++;\n\treturn TypeVariable(index, std::move(_sort));\n}\n\nexperimental::Type TypeSystem::freshTypeVariable(Sort _sort)\n{\n\t_sort.classes.emplace(primitiveClass(PrimitiveClass::Type));\n\treturn freshVariable(_sort);\n}\n\nstd::vector<TypeEnvironment::UnificationFailure> TypeEnvironment::instantiate(TypeVariable _variable, Type _type)\n{\n\tfor (auto const& maybeTypeVar: TypeEnvironmentHelpers{*this}.typeVars(_type))\n\t\tif (auto const* typeVar = std::get_if<TypeVariable>(&maybeTypeVar))\n\t\t\tif (typeVar->index() == _variable.index())\n\t\t\t\treturn {UnificationFailure{RecursiveUnification{_variable, _type}}};\n\tSort typeSort = sort(_type);\n\tif (!(_variable.sort() <= typeSort))\n\t{\n\t\treturn {UnificationFailure{SortMismatch{_type, _variable.sort() - typeSort}}};\n\t}\n\tsolAssert(m_typeVariables.emplace(_variable.index(), _type).second);\n\treturn {};\n}\n\nexperimental::Type TypeEnvironment::resolve(Type _type) const\n{\n\tType result = _type;\n\twhile (auto const* var = std::get_if<TypeVariable>(&result))\n\t\tif (Type const* resolvedType = util::valueOrNullptr(m_typeVariables, var->index()))\n\t\t\tresult = *resolvedType;\n\t\telse\n\t\t\tbreak;\n\treturn result;\n}\n\nexperimental::Type TypeEnvironment::resolveRecursive(Type _type) const\n{\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](TypeConstant const& _typeConstant) -> Type {\n\t\t\treturn TypeConstant{\n\t\t\t\t_typeConstant.constructor,\n\t\t\t\t_typeConstant.arguments | ranges::views::transform([&](Type const& _argType) {\n\t\t\t\t\treturn resolveRecursive(_argType);\n\t\t\t\t}) | ranges::to<std::vector<Type>>\n\t\t\t};\n\t\t},\n\t\t[](TypeVariable const& _typeVar) -> Type {\n\t\t\treturn _typeVar;\n\t\t},\n\t\t[](std::monostate _nothing) -> Type {\n\t\t\treturn _nothing;\n\t\t}\n\t}, resolve(_type));\n}\n\nSort TypeEnvironment::sort(Type _type) const\n{\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](TypeConstant const& _expression) -> Sort\n\t\t{\n\t\t\tauto const& constructorInfo = m_typeSystem.constructorInfo(_expression.constructor);\n\t\t\tauto argumentSorts = _expression.arguments | ranges::views::transform([&](Type _argumentType) {\n\t\t\t\treturn sort(resolve(_argumentType));\n\t\t\t}) | ranges::to<std::vector<Sort>>;\n\t\t\tSort sort;\n\t\t\tfor (auto const& arity: constructorInfo.arities)\n\t\t\t{\n\t\t\t\tsolAssert(arity.argumentSorts.size() == argumentSorts.size());\n\t\t\t\tbool hasArity = true;\n\t\t\t\tfor (auto&& [argumentSort, arityArgumentSort]: ranges::zip_view(argumentSorts, arity.argumentSorts))\n\t\t\t\t{\n\t\t\t\t\tif (!(arityArgumentSort <= argumentSort))\n\t\t\t\t\t{\n\t\t\t\t\t\thasArity = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (hasArity)\n\t\t\t\t\tsort.classes.insert(arity.typeClass);\n\t\t\t}\n\t\t\treturn sort;\n\t\t},\n\t\t[](TypeVariable const& _variable) -> Sort { return _variable.sort(); },\n\t\t[](std::monostate) -> Sort { solAssert(false); }\n\t}, _type);\n}\n\nTypeConstructor TypeSystem::declareTypeConstructor(std::string _name, std::string _canonicalName, size_t _arguments, Declaration const* _declaration)\n{\n\tsolAssert(m_canonicalTypeNames.insert(_canonicalName).second, \"Duplicate canonical type name.\");\n\tSort baseSort{{primitiveClass(PrimitiveClass::Type)}};\n\tsize_t index = m_typeConstructors.size();\n\tm_typeConstructors.emplace_back(TypeConstructorInfo{\n\t\t_name,\n\t\t_canonicalName,\n\t\t{Arity{std::vector<Sort>{_arguments, baseSort}, primitiveClass(PrimitiveClass::Type)}},\n\t\t_declaration\n\t});\n\tTypeConstructor constructor{index};\n\tif (_arguments)\n\t{\n\t\tstd::vector<Sort> argumentSorts;\n\t\tstd::generate_n(std::back_inserter(argumentSorts), _arguments, [&](){ return Sort{{primitiveClass(PrimitiveClass::Type)}}; });\n\t\tstd::vector<Type> argumentTypes;\n\t\tstd::generate_n(std::back_inserter(argumentTypes), _arguments, [&](){ return freshVariable({}); });\n\t\tm_globalTypeEnvironment.fixTypeVars(argumentTypes);\n\t\tauto error = instantiateClass(type(constructor, argumentTypes), Arity{argumentSorts, primitiveClass(PrimitiveClass::Type)});\n\t\tsolAssert(!error, *error);\n\t}\n\telse\n\t{\n\t\tauto error = instantiateClass(type(constructor, {}), Arity{{}, primitiveClass(PrimitiveClass::Type)});\n\t\tsolAssert(!error, *error);\n\t}\n\treturn constructor;\n}\n\nstd::variant<TypeClass, std::string> TypeSystem::declareTypeClass(std::string _name, Declaration const* _declaration, bool _primitive)\n{\n\tTypeClass typeClass{m_typeClasses.size()};\n\n\tType typeVariable = (_primitive ? freshVariable({{typeClass}}) : freshTypeVariable({{typeClass}}));\n\tsolAssert(std::holds_alternative<TypeVariable>(typeVariable));\n\n\tm_globalTypeEnvironment.fixTypeVars({typeVariable});\n\n\tm_typeClasses.emplace_back(TypeClassInfo{\n\t\ttypeVariable,\n\t\t_name,\n\t\t_declaration\n\t});\n\treturn typeClass;\n}\n\nexperimental::Type TypeSystem::type(TypeConstructor _constructor, std::vector<Type> _arguments) const\n{\n\t// TODO: proper error handling\n\tauto const& info = m_typeConstructors.at(_constructor.m_index);\n\tsolAssert(\n\t\tinfo.arguments() == _arguments.size(),\n\t\tfmt::format(\"Type constructor '{}' accepts {} type arguments (got {}).\", constructorInfo(_constructor).name, info.arguments(), _arguments.size())\n\t);\n\treturn TypeConstant{_constructor, _arguments};\n}\n\nexperimental::Type TypeEnvironment::fresh(Type _type)\n{\n\tstd::unordered_map<size_t, Type> mapping;\n\tauto freshImpl = [&](Type _type, auto _recurse) -> Type {\n\t\treturn std::visit(util::GenericVisitor{\n\t\t\t[&](TypeConstant const& _type) -> Type {\n\t\t\t\treturn TypeConstant{\n\t\t\t\t\t_type.constructor,\n\t\t\t\t\t_type.arguments | ranges::views::transform([&](Type _argType) {\n\t\t\t\t\t\treturn _recurse(_argType, _recurse);\n\t\t\t\t\t}) | ranges::to<std::vector<Type>>\n\t\t\t\t};\n\t\t\t},\n\t\t\t[&](TypeVariable const& _var) -> Type {\n\t\t\t\tif (auto* mapped = util::valueOrNullptr(mapping, _var.index()))\n\t\t\t\t{\n\t\t\t\t\tauto* typeVariable = std::get_if<TypeVariable>(mapped);\n\t\t\t\t\tsolAssert(typeVariable);\n\t\t\t\t\t// TODO: can there be a mismatch?\n\t\t\t\t\tsolAssert(typeVariable->sort() == _var.sort());\n\t\t\t\t\treturn *mapped;\n\t\t\t\t}\n\t\t\t\treturn mapping[_var.index()] = m_typeSystem.freshTypeVariable(_var.sort());\n\t\t\t},\n\t\t\t[](std::monostate) -> Type { solAssert(false); }\n\t\t}, resolve(_type));\n\t};\n\treturn freshImpl(_type, freshImpl);\n}\n\nstd::optional<std::string> TypeSystem::instantiateClass(Type _instanceVariable, Arity _arity)\n{\n\tif (!TypeSystemHelpers{*this}.isTypeConstant(_instanceVariable))\n\t\treturn \"Invalid instance variable.\";\n\tauto [typeConstructor, typeArguments] = TypeSystemHelpers{*this}.destTypeConstant(_instanceVariable);\n\tauto& typeConstructorInfo = m_typeConstructors.at(typeConstructor.m_index);\n\tif (_arity.argumentSorts.size() != typeConstructorInfo.arguments())\n\t\treturn \"Invalid arity.\";\n\tif (typeArguments.size() != typeConstructorInfo.arguments())\n\t\treturn \"Invalid arity.\";\n\n\ttypeConstructorInfo.arities.emplace_back(_arity);\n\n\treturn std::nullopt;\n}\n"
  },
  {
    "path": "libsolidity/experimental/ast/TypeSystem.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/experimental/ast/Type.h>\n#include <liblangutil/Exceptions.h>\n\n#include <optional>\n#include <string>\n#include <variant>\n#include <vector>\n\nnamespace solidity::frontend\n{\nclass Declaration;\n}\n\nnamespace solidity::frontend::experimental\n{\n\nclass TypeEnvironment\n{\npublic:\n\tstruct TypeMismatch\n\t{\n\t\tType a;\n\t\tType b;\n\t};\n\n\tstruct SortMismatch {\n\t\tType type;\n\t\tSort sort;\n\t};\n\n\tstruct RecursiveUnification\n\t{\n\t\tType var;\n\t\tType type;\n\t};\n\n\tusing UnificationFailure = std::variant<\n\t\tTypeMismatch,\n\t\tSortMismatch,\n\t\tRecursiveUnification\n\t>;\n\n\tTypeEnvironment(TypeSystem& _typeSystem): m_typeSystem(_typeSystem) {}\n\tTypeEnvironment(TypeEnvironment const&) = delete;\n\tTypeEnvironment& operator=(TypeEnvironment const&) = delete;\n\tTypeEnvironment clone() const;\n\n\tType resolve(Type _type) const;\n\tType resolveRecursive(Type _type) const;\n\tType fresh(Type _type);\n\t[[nodiscard]] std::vector<UnificationFailure> unify(Type _a, Type _b);\n\tSort sort(Type _type) const;\n\tbool typeEquals(Type _lhs, Type _rhs) const;\n\n\tTypeSystem& typeSystem() { return m_typeSystem; }\n\tTypeSystem const& typeSystem() const { return m_typeSystem; }\n\n\tbool isFixedTypeVar(Type const& _typeVar) const;\n\tvoid fixTypeVars(std::vector<Type> const& _typeVars);\n\nprivate:\n\tTypeEnvironment(TypeEnvironment&& _env):\n\t\tm_typeSystem(_env.m_typeSystem),\n\t\tm_typeVariables(std::move(_env.m_typeVariables))\n\t{}\n\n\t[[nodiscard]] std::vector<TypeEnvironment::UnificationFailure> instantiate(TypeVariable _variable, Type _type);\n\n\tTypeSystem& m_typeSystem;\n\n\t/// For each @a TypeVariable (identified by its index) stores the type is has been successfully\n\t/// unified with. Used for type resolution. Note that @a Type may itself be a type variable\n\t/// or may contain type variables so resolution must be recursive.\n\tstd::map<size_t, Type> m_typeVariables;\n\n\t/// Type variables marked as fixed free type variables (as opposed to generic type variables).\n\t/// Identified by their indices.\n\tstd::set<size_t> m_fixedTypeVariables;\n};\n\nclass TypeSystem\n{\npublic:\n\tstruct TypeConstructorInfo\n\t{\n\t\tstd::string name;\n\t\tstd::string canonicalName;\n\t\tstd::vector<Arity> arities;\n\t\tDeclaration const* typeDeclaration = nullptr;\n\t\tsize_t arguments() const\n\t\t{\n\t\t\tsolAssert(!arities.empty());\n\t\t\treturn arities.front().argumentSorts.size();\n\t\t}\n\t};\n\tstruct TypeClassInfo\n\t{\n\t\tType typeVariable;\n\t\tstd::string name;\n\t\tDeclaration const* classDeclaration = nullptr;\n\t};\n\tTypeSystem();\n\tTypeSystem(TypeSystem const&) = delete;\n\tTypeSystem const& operator=(TypeSystem const&) = delete;\n\tType type(PrimitiveType _typeConstructor, std::vector<Type> _arguments) const\n\t{\n\t\treturn type(m_primitiveTypeConstructors.at(_typeConstructor), std::move(_arguments));\n\t}\n\tType type(TypeConstructor _typeConstructor, std::vector<Type> _arguments) const;\n\tstd::string typeName(TypeConstructor _typeConstructor) const\n\t{\n\t\t// TODO: proper error handling\n\t\treturn m_typeConstructors.at(_typeConstructor.m_index).name;\n\t}\n\tstd::string canonicalName(TypeConstructor _typeConstructor) const\n\t{\n\t\t// TODO: proper error handling\n\t\treturn m_typeConstructors.at(_typeConstructor.m_index).canonicalName;\n\t}\n\tTypeConstructor declareTypeConstructor(std::string _name, std::string _canonicalName, size_t _arguments, Declaration const* _declaration);\n\tTypeConstructor constructor(PrimitiveType _type) const\n\t{\n\t\treturn m_primitiveTypeConstructors.at(_type);\n\t}\n\tTypeClass primitiveClass(PrimitiveClass _class) const\n\t{\n\t\treturn m_primitiveTypeClasses.at(_class);\n\t}\n\tsize_t constructorArguments(TypeConstructor _typeConstructor) const\n\t{\n\t\t// TODO: error handling\n\t\treturn m_typeConstructors.at(_typeConstructor.m_index).arguments();\n\t}\n\tTypeConstructorInfo const& constructorInfo(TypeConstructor _typeConstructor) const\n\t{\n\t\t// TODO: error handling\n\t\treturn m_typeConstructors.at(_typeConstructor.m_index);\n\t}\n\tTypeConstructorInfo const& constructorInfo(PrimitiveType _typeConstructor) const\n\t{\n\t\treturn constructorInfo(constructor(_typeConstructor));\n\t}\n\n\tstd::variant<TypeClass, std::string> declareTypeClass(std::string _name, Declaration const* _declaration, bool _primitive = false);\n\t[[nodiscard]] std::optional<std::string> instantiateClass(Type _instanceVariable, Arity _arity);\n\n\tType freshTypeVariable(Sort _sort);\n\n\tTypeEnvironment const& env() const { return m_globalTypeEnvironment; }\n\tTypeEnvironment& env() { return m_globalTypeEnvironment; }\n\n\tType freshVariable(Sort _sort);\n\tstd::string typeClassName(TypeClass _class) const { return m_typeClasses.at(_class.m_index).name; }\n\tDeclaration const* typeClassDeclaration(TypeClass _class) const { return m_typeClasses.at(_class.m_index).classDeclaration; }\n\tType typeClassVariable(TypeClass _class) const\n\t{\n\t\treturn m_typeClasses.at(_class.m_index).typeVariable;\n\t}\n\n\tTypeClassInfo const& typeClassInfo(TypeClass _class) const\n\t{\n\t\treturn m_typeClasses.at(_class.m_index);\n\t}\n\nprivate:\n\tfriend class TypeEnvironment;\n\tsize_t m_numTypeVariables = 0;\n\tstd::map<PrimitiveType, TypeConstructor> m_primitiveTypeConstructors;\n\tstd::map<PrimitiveClass, TypeClass> m_primitiveTypeClasses;\n\tstd::set<std::string> m_canonicalTypeNames;\n\tstd::vector<TypeConstructorInfo> m_typeConstructors;\n\tstd::vector<TypeClassInfo> m_typeClasses;\n\tTypeEnvironment m_globalTypeEnvironment{*this};\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/ast/TypeSystemHelper.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n\n#include <libsolidity/experimental/ast/TypeSystemHelper.h>\n#include <libsolidity/ast/AST.h>\n\n#include <libsolidity/experimental/analysis/Analysis.h>\n#include <libsolidity/experimental/analysis/TypeRegistration.h>\n\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/algorithm/any_of.hpp>\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/drop_exactly.hpp>\n#include <range/v3/view/drop_last.hpp>\n#include <range/v3/view/reverse.hpp>\n\n#include <fmt/format.h>\n\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::experimental;\n\n/*std::optional<TypeConstructor> experimental::typeConstructorFromTypeName(Analysis const& _analysis, TypeName const& _typeName)\n{\n\tif (auto const* elementaryTypeName = dynamic_cast<ElementaryTypeName const*>(&_typeName))\n\t{\n\t\tif (auto constructor = typeConstructorFromToken(_analysis, elementaryTypeName->typeName().token()))\n\t\t\treturn *constructor;\n\t}\n\telse if (auto const* userDefinedType = dynamic_cast<UserDefinedTypeName const*>(&_typeName))\n\t{\n\t\tif (auto const* referencedDeclaration = userDefinedType->pathNode().annotation().referencedDeclaration)\n\t\t\treturn _analysis.annotation<TypeRegistration>(*referencedDeclaration).typeConstructor;\n\t}\n\treturn nullopt;\n}*/\n/*\nstd::optional<TypeConstructor> experimental::typeConstructorFromToken(Analysis const& _analysis, langutil::Token _token)\n{\n\tTypeSystem const& typeSystem = _analysis.typeSystem();\n\tswitch (_token)\n\t{\n\tcase Token::Void:\n\t\treturn typeSystem.builtinConstructor(BuiltinType::Void);\n\tcase Token::Fun:\n\t\treturn typeSystem.builtinConstructor(BuiltinType::Function);\n\tcase Token::Unit:\n\t\treturn typeSystem.builtinConstructor(BuiltinType::Unit);\n\tcase Token::Pair:\n\t\treturn typeSystem.builtinConstructor(BuiltinType::Pair);\n\tcase Token::Word:\n\t\treturn typeSystem.builtinConstructor(BuiltinType::Word);\n\tcase Token::IntegerType:\n\t\treturn typeSystem.builtinConstructor(BuiltinType::Integer);\n\tcase Token::Bool:\n\t\treturn typeSystem.builtinConstructor(BuiltinType::Bool);\n\tdefault:\n\t\treturn nullopt;\n\t}\n}*/\n\nstd::optional<BuiltinClass> experimental::builtinClassFromToken(langutil::Token _token)\n{\n\tswitch (_token)\n\t{\n\tcase Token::Integer:\n\t\treturn BuiltinClass::Integer;\n\tcase Token::Mul:\n\t\treturn BuiltinClass::Mul;\n\tcase Token::Add:\n\t\treturn BuiltinClass::Add;\n\tcase Token::Equal:\n\t\treturn BuiltinClass::Equal;\n\tcase Token::LessThan:\n\t\treturn BuiltinClass::Less;\n\tcase Token::LessThanOrEqual:\n\t\treturn BuiltinClass::LessOrEqual;\n\tcase Token::GreaterThan:\n\t\treturn BuiltinClass::Greater;\n\tcase Token::GreaterThanOrEqual:\n\t\treturn BuiltinClass::GreaterOrEqual;\n\tdefault:\n\t\treturn std::nullopt;\n\t}\n}\n/*\nstd::optional<TypeClass> experimental::typeClassFromTypeClassName(TypeClassName const& _typeClass)\n{\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](ASTPointer<IdentifierPath> _path) -> optional<TypeClass> {\n\t\t\tauto classDefinition = dynamic_cast<TypeClassDefinition const*>(_path->annotation().referencedDeclaration);\n\t\t\tif (!classDefinition)\n\t\t\t\treturn nullopt;\n\t\t\treturn TypeClass{classDefinition};\n\t\t},\n\t\t[&](Token _token) -> optional<TypeClass> {\n\t\t\treturn typeClassFromToken(_token);\n\t\t}\n\t}, _typeClass.name());\n}\n*/\nexperimental::Type TypeSystemHelpers::tupleType(std::vector<Type> _elements) const\n{\n\tif (_elements.empty())\n\t\treturn typeSystem.type(PrimitiveType::Unit, {});\n\tif (_elements.size() == 1)\n\t\treturn _elements.front();\n\tType result = _elements.back();\n\tfor (Type type: _elements | ranges::views::reverse | ranges::views::drop_exactly(1))\n\t\tresult = typeSystem.type(PrimitiveType::Pair, {type, result});\n\treturn result;\n}\n\nstd::vector<experimental::Type> TypeSystemHelpers::destTupleType(Type _tupleType) const\n{\n\tif (!isTypeConstant(_tupleType))\n\t\treturn {_tupleType};\n\tTypeConstructor pairConstructor = typeSystem.constructor(PrimitiveType::Pair);\n\tauto [constructor, arguments] = destTypeConstant(_tupleType);\n\tif (constructor == typeSystem.constructor(PrimitiveType::Unit))\n\t\treturn {};\n\tif (constructor != pairConstructor)\n\t\treturn {_tupleType};\n\tsolAssert(arguments.size() == 2);\n\n\tstd::vector<Type> result;\n\tresult.emplace_back(arguments.front());\n\tType tail = arguments.back();\n\twhile (true)\n\t{\n\t\tif (!isTypeConstant(tail))\n\t\t\tbreak;\n\t\tauto [tailConstructor, tailArguments] = destTypeConstant(tail);\n\t\tif (tailConstructor != pairConstructor)\n\t\t\tbreak;\n\t\tsolAssert(tailArguments.size() == 2);\n\t\tresult.emplace_back(tailArguments.front());\n\t\ttail = tailArguments.back();\n\t}\n\tresult.emplace_back(tail);\n\treturn result;\n}\n\nexperimental::Type TypeSystemHelpers::sumType(std::vector<Type> _elements) const\n{\n\tif (_elements.empty())\n\t\treturn typeSystem.type(PrimitiveType::Void, {});\n\tif (_elements.size() == 1)\n\t\treturn _elements.front();\n\tType result = _elements.back();\n\tfor (Type type: _elements | ranges::views::reverse | ranges::views::drop_exactly(1))\n\t\tresult = typeSystem.type(PrimitiveType::Sum, {type, result});\n\treturn result;\n}\n\nstd::vector<experimental::Type> TypeSystemHelpers::destSumType(Type _tupleType) const\n{\n\tif (!isTypeConstant(_tupleType))\n\t\treturn {_tupleType};\n\tTypeConstructor sumConstructor = typeSystem.constructor(PrimitiveType::Sum);\n\tauto [constructor, arguments] = destTypeConstant(_tupleType);\n\tif (constructor == typeSystem.constructor(PrimitiveType::Void))\n\t\treturn {};\n\tif (constructor != sumConstructor)\n\t\treturn {_tupleType};\n\tsolAssert(arguments.size() == 2);\n\n\tstd::vector<Type> result;\n\tresult.emplace_back(arguments.front());\n\tType tail = arguments.back();\n\twhile (true)\n\t{\n\t\tif (!isTypeConstant(tail))\n\t\t\tbreak;\n\t\tauto [tailConstructor, tailArguments] = destTypeConstant(tail);\n\t\tif (tailConstructor != sumConstructor)\n\t\t\tbreak;\n\t\tsolAssert(tailArguments.size() == 2);\n\t\tresult.emplace_back(tailArguments.front());\n\t\ttail = tailArguments.back();\n\t}\n\tresult.emplace_back(tail);\n\treturn result;\n}\n\nstd::tuple<TypeConstructor, std::vector<experimental::Type>> TypeSystemHelpers::destTypeConstant(Type _type) const\n{\n\tusing ResultType = std::tuple<TypeConstructor, std::vector<Type>>;\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](TypeConstant const& _type) -> ResultType {\n\t\t\treturn std::make_tuple(_type.constructor, _type.arguments);\n\t\t},\n\t\t[](auto const&) -> ResultType {\n\t\t\tsolAssert(false);\n\t\t}\n\t}, _type);\n}\n\nbool TypeSystemHelpers::isTypeConstant(Type _type) const\n{\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](TypeConstant const&) -> bool {\n\t\t\treturn true;\n\t\t},\n\t\t[](auto const&) -> bool {\n\t\t\treturn false;\n\t\t}\n\t}, _type);\n}\n\nbool TypeSystemHelpers::isPrimitiveType(Type _type, PrimitiveType _primitiveType) const\n{\n\tif (!isTypeConstant(_type))\n\t\treturn false;\n\tauto constructor = std::get<0>(destTypeConstant(_type));\n\treturn constructor == typeSystem.constructor(_primitiveType);\n}\n\nexperimental::Type TypeSystemHelpers::functionType(experimental::Type _argType, experimental::Type _resultType) const\n{\n\treturn typeSystem.type(PrimitiveType::Function, {_argType, _resultType});\n}\n\nstd::tuple<experimental::Type, experimental::Type> TypeSystemHelpers::destFunctionType(Type _functionType) const\n{\n\tauto [constructor, arguments] = destTypeConstant(_functionType);\n\tsolAssert(constructor == typeSystem.constructor(PrimitiveType::Function));\n\tsolAssert(arguments.size() == 2);\n\treturn std::make_tuple(arguments.front(), arguments.back());\n}\n\nbool TypeSystemHelpers::isFunctionType(Type _type) const\n{\n\treturn isPrimitiveType(_type, PrimitiveType::Function);\n}\n\nexperimental::Type TypeSystemHelpers::typeFunctionType(experimental::Type _argType, experimental::Type _resultType) const\n{\n\treturn typeSystem.type(PrimitiveType::TypeFunction, {_argType, _resultType});\n}\n\nstd::tuple<experimental::Type, experimental::Type> TypeSystemHelpers::destTypeFunctionType(Type _functionType) const\n{\n\tauto [constructor, arguments] = destTypeConstant(_functionType);\n\tsolAssert(constructor == typeSystem.constructor(PrimitiveType::TypeFunction));\n\tsolAssert(arguments.size() == 2);\n\treturn std::make_tuple(arguments.front(), arguments.back());\n}\n\nbool TypeSystemHelpers::isTypeFunctionType(Type _type) const\n{\n\treturn isPrimitiveType(_type, PrimitiveType::TypeFunction);\n}\n\nstd::vector<experimental::Type> TypeEnvironmentHelpers::typeVars(Type _type) const\n{\n\tstd::set<size_t> indices;\n\tstd::vector<Type> typeVars;\n\tauto typeVarsImpl = [&](Type _type, auto _recurse) -> void {\n\t\tstd::visit(util::GenericVisitor{\n\t\t\t[&](TypeConstant const& _type) {\n\t\t\t\tfor (auto arg: _type.arguments)\n\t\t\t\t\t_recurse(arg, _recurse);\n\t\t\t},\n\t\t\t[&](TypeVariable const& _var) {\n\t\t\t\tif (indices.emplace(_var.index()).second)\n\t\t\t\t\ttypeVars.emplace_back(_var);\n\t\t\t},\n\t\t\t[](std::monostate) { solAssert(false); }\n\t\t}, env.resolve(_type));\n\t};\n\ttypeVarsImpl(_type, typeVarsImpl);\n\treturn typeVars;\n}\n\n\nbool TypeEnvironmentHelpers::hasGenericTypeVars(Type const& _type) const\n{\n\treturn ranges::any_of(\n\t\tTypeEnvironmentHelpers{*this}.typeVars(_type),\n\t\t[&](Type const& _maybeTypeVar) {\n\t\t\tsolAssert(std::holds_alternative<TypeVariable>(_maybeTypeVar));\n\t\t\treturn !env.isFixedTypeVar(_maybeTypeVar);\n\t\t}\n\t);\n}\n\nexperimental::Type TypeEnvironmentHelpers::substitute(\n\tType const& _type,\n\tType const& _partToReplace,\n\tType const& _replacement\n) const\n{\n\tusing ranges::views::transform;\n\tusing ranges::to;\n\n\tif (env.typeEquals(_type, _partToReplace))\n\t\treturn _replacement;\n\n\tauto recurse = [&](Type const& _t) { return substitute(_t, _partToReplace, _replacement); };\n\n\treturn visit(util::GenericVisitor{\n\t\t[&](TypeConstant const& _typeConstant) -> Type {\n\t\t\treturn TypeConstant{\n\t\t\t\t_typeConstant.constructor,\n\t\t\t\t_typeConstant.arguments | transform(recurse) | to<std::vector<Type>>,\n\t\t\t};\n\t\t},\n\t\t[&](auto const& _type) -> Type {\n\t\t\treturn _type;\n\t\t},\n\t}, env.resolve(_type));\n}\n\nstd::string TypeSystemHelpers::sortToString(Sort _sort) const\n{\n\tswitch (_sort.classes.size())\n\t{\n\tcase 0:\n\t\treturn \"()\";\n\tcase 1:\n\t\treturn typeSystem.typeClassName(*_sort.classes.begin());\n\tdefault:\n\t{\n\t\tstd::stringstream stream;\n\t\tstream << \"(\";\n\t\tfor (auto typeClass: _sort.classes | ranges::views::drop_last(1))\n\t\t\tstream << typeSystem.typeClassName(typeClass) << \", \";\n\t\tstream << typeSystem.typeClassName(*_sort.classes.rbegin()) << \")\";\n\t\treturn stream.str();\n\t}\n\t}\n}\n\nstd::string TypeEnvironmentHelpers::canonicalTypeName(Type _type) const\n{\n\treturn visit(util::GenericVisitor{\n\t\t[&](TypeConstant _type) -> std::string {\n\t\t\tstd::stringstream stream;\n\t\t\tstream << env.typeSystem().constructorInfo(_type.constructor).canonicalName;\n\t\t\tif (!_type.arguments.empty())\n\t\t\t{\n\t\t\t\tstream << \"$\";\n\t\t\t\tfor (auto type: _type.arguments | ranges::views::drop_last(1))\n\t\t\t\t\tstream << canonicalTypeName(type) << \"$\";\n\t\t\t\tstream << canonicalTypeName(_type.arguments.back());\n\t\t\t\tstream << \"$\";\n\t\t\t}\n\t\t\treturn stream.str();\n\t\t},\n\t\t[](TypeVariable) -> std::string {\n\t\t\tsolAssert(false);\n\t\t},\n\t\t[](std::monostate) -> std::string {\n\t\t\tsolAssert(false);\n\t\t},\n\t}, env.resolve(_type));\n}\n\nstd::string TypeEnvironmentHelpers::typeToString(Type const& _type) const\n{\n\tstd::map<TypeConstructor, std::function<std::string(std::vector<Type>)>> formatters{\n\t\t{env.typeSystem().constructor(PrimitiveType::Function), [&](auto const& _args) {\n\t\t\tsolAssert(_args.size() == 2);\n\t\t\treturn fmt::format(\"{} -> {}\", typeToString(_args.front()), typeToString(_args.back()));\n\t\t}},\n\t\t{env.typeSystem().constructor(PrimitiveType::Unit), [&](auto const& _args) {\n\t\t\tsolAssert(_args.size() == 0);\n\t\t\treturn \"()\";\n\t\t}},\n\t\t{env.typeSystem().constructor(PrimitiveType::Pair), [&](auto const& _arguments) {\n\t\t\tauto tupleTypes = TypeSystemHelpers{env.typeSystem()}.destTupleType(_arguments.back());\n\t\t\tstd::string result = \"(\";\n\t\t\tresult += typeToString(_arguments.front());\n\t\t\tfor (auto type: tupleTypes)\n\t\t\t\tresult += \", \" + typeToString(type);\n\t\t\tresult += \")\";\n\t\t\treturn result;\n\t\t}},\n\t};\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](TypeConstant const& _type) {\n\t\t\tif (auto* formatter = util::valueOrNullptr(formatters, _type.constructor))\n\t\t\t\treturn (*formatter)(_type.arguments);\n\t\t\tstd::stringstream stream;\n\t\t\tstream << env.typeSystem().constructorInfo(_type.constructor).name;\n\t\t\tif (!_type.arguments.empty())\n\t\t\t{\n\t\t\t\tstream << \"(\";\n\t\t\t\tfor (auto type: _type.arguments | ranges::views::drop_last(1))\n\t\t\t\t\tstream << typeToString(type) << \", \";\n\t\t\t\tstream << typeToString(_type.arguments.back());\n\t\t\t\tstream << \")\";\n\t\t\t}\n\t\t\treturn stream.str();\n\t\t},\n\t\t[&](TypeVariable const& _type) {\n\t\t\tstd::stringstream stream;\n\t\t\tstd::string varName;\n\t\t\tsize_t index = _type.index();\n\t\t\tvarName += static_cast<char>('a' + (index%26));\n\t\t\twhile (index /= 26)\n\t\t\t\tvarName += static_cast<char>('a' + (index%26));\n\t\t\treverse(varName.begin(), varName.end());\n\t\t\tstream << (env.isFixedTypeVar(_type) ? \"'\" : \"?\") << varName;\n\t\t\tswitch (_type.sort().classes.size())\n\t\t\t{\n\t\t\tcase 0:\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tstream << \":\" << env.typeSystem().typeClassName(*_type.sort().classes.begin());\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tstream << \":(\";\n\t\t\t\tfor (auto typeClass: _type.sort().classes | ranges::views::drop_last(1))\n\t\t\t\t\tstream << env.typeSystem().typeClassName(typeClass) << \", \";\n\t\t\t\tstream << env.typeSystem().typeClassName(*_type.sort().classes.rbegin());\n\t\t\t\tstream << \")\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn stream.str();\n\t\t},\n\t\t[](std::monostate) -> std::string { solAssert(false); }\n\t}, env.resolve(_type));\n}\n"
  },
  {
    "path": "libsolidity/experimental/ast/TypeSystemHelper.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/experimental/ast/TypeSystem.h>\n#include <libsolidity/ast/ASTForward.h>\n#include <liblangutil/Token.h>\n\nnamespace solidity::frontend::experimental\n{\nclass Analysis;\nenum class BuiltinClass;\n//std::optional<TypeConstructor> typeConstructorFromTypeName(Analysis const& _analysis, TypeName const& _typeName);\n//std::optional<TypeConstructor> typeConstructorFromToken(Analysis const& _analysis, langutil::Token _token);\n//std::optional<TypeClass> typeClassFromTypeClassName(TypeClassName const& _typeClass);\nstd::optional<BuiltinClass> builtinClassFromToken(langutil::Token _token);\n\nstruct TypeSystemHelpers\n{\n\tTypeSystem const& typeSystem;\n\tstd::tuple<TypeConstructor, std::vector<Type>> destTypeConstant(Type _type) const;\n\tbool isTypeConstant(Type _type) const;\n\tbool isPrimitiveType(Type _type, PrimitiveType _primitiveType) const;\n\tType tupleType(std::vector<Type> _elements) const;\n\tstd::vector<Type> destTupleType(Type _tupleType) const;\n\tType sumType(std::vector<Type> _elements) const;\n\tstd::vector<Type> destSumType(Type _tupleType) const;\n\tType functionType(Type _argType, Type _resultType) const;\n\tstd::tuple<Type, Type> destFunctionType(Type _functionType) const;\n\tbool isFunctionType(Type _type) const;\n\tType typeFunctionType(Type _argType, Type _resultType) const;\n\tstd::tuple<Type, Type> destTypeFunctionType(Type _functionType) const;\n\tbool isTypeFunctionType(Type _type) const;\n\tstd::string sortToString(Sort _sort) const;\n};\n\nstruct TypeEnvironmentHelpers\n{\n\tTypeEnvironment const& env;\n\tstd::string typeToString(Type const& _type) const;\n\tstd::string canonicalTypeName(Type _type) const;\n\tstd::vector<Type> typeVars(Type _type) const;\n\n\tbool hasGenericTypeVars(Type const& _type) const;\n\n\tType substitute(Type const& _type, Type const& _partToReplace, Type const& _replacement) const;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/codegen/Common.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/experimental/codegen/Common.h>\n#include <libsolidity/experimental/ast/TypeSystem.h>\n#include <libsolidity/experimental/ast/TypeSystemHelper.h>\n\n#include <libsolutil/CommonIO.h>\n\n#include <libyul/AsmPrinter.h>\n\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::util;\nusing namespace solidity::yul;\n\nnamespace solidity::frontend::experimental\n{\n\nstd::string IRNames::function(TypeEnvironment const& _env, FunctionDefinition const& _function, Type _type)\n{\n\tif (_function.isConstructor())\n\t\treturn constructor(*_function.annotation().contract);\n\n\treturn \"fun_\" + _function.name() + \"_\" + std::to_string(_function.id()) + \"$\" + TypeEnvironmentHelpers{_env}.canonicalTypeName(_type) + \"$\";\n}\n\nstd::string IRNames::function(VariableDeclaration const& _varDecl)\n{\n\treturn \"getter_fun_\" + _varDecl.name() + \"_\" + std::to_string(_varDecl.id());\n}\n\nstd::string IRNames::creationObject(ContractDefinition const& _contract)\n{\n\treturn _contract.name() + \"_\" + toString(_contract.id());\n}\n\nstd::string IRNames::deployedObject(ContractDefinition const& _contract)\n{\n\treturn _contract.name() + \"_\" + toString(_contract.id()) + \"_deployed\";\n}\n\nstd::string IRNames::constructor(ContractDefinition const& _contract)\n{\n\treturn \"constructor_\" + _contract.name() + \"_\" + std::to_string(_contract.id());\n}\n\nstd::string IRNames::localVariable(VariableDeclaration const& _declaration)\n{\n\treturn \"var_\" + _declaration.name() + '_' + std::to_string(_declaration.id());\n}\n\nstd::string IRNames::localVariable(Expression const& _expression)\n{\n\treturn \"expr_\" + std::to_string(_expression.id());\n}\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/codegen/Common.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/experimental/ast/TypeSystem.h>\n\n#include <algorithm>\n#include <string>\n\nnamespace solidity::frontend::experimental\n{\n\nstruct IRNames\n{\n\tstatic std::string function(TypeEnvironment const& _env, FunctionDefinition const& _function, Type _type);\n\tstatic std::string function(VariableDeclaration const& _varDecl);\n\tstatic std::string creationObject(ContractDefinition const& _contract);\n\tstatic std::string deployedObject(ContractDefinition const& _contract);\n\tstatic std::string constructor(ContractDefinition const& _contract);\n\tstatic std::string localVariable(VariableDeclaration const& _declaration);\n\tstatic std::string localVariable(Expression const& _expression);\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/codegen/IRGenerationContext.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/ast/ASTForward.h>\n\n#include <libsolidity/experimental/analysis/Analysis.h>\n#include <libsolidity/experimental/ast/TypeSystem.h>\n\n#include <list>\n#include <set>\n\nnamespace solidity::frontend::experimental\n{\n\nclass Analysis;\n\nstruct IRGenerationContext\n{\n\tAnalysis const& analysis;\n\tTypeEnvironment const* env = nullptr;\n\tvoid enqueueFunctionDefinition(FunctionDefinition const* _functionDefinition, Type _type)\n\t{\n\t\tQueuedFunction queue{_functionDefinition, env->resolve(_type)};\n\t\tfor (auto type: generatedFunctions[_functionDefinition])\n\t\t\tif (env->typeEquals(type, _type))\n\t\t\t\treturn;\n\t\tfunctionQueue.emplace_back(queue);\n\t}\n\tstruct QueuedFunction\n\t{\n\t\tFunctionDefinition const* function = nullptr;\n\t\tType type = std::monostate{};\n\t};\n\tstd::list<QueuedFunction> functionQueue;\n\tstd::map<FunctionDefinition const*, std::vector<Type>> generatedFunctions;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/codegen/IRGenerator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/experimental/codegen/IRGenerator.h>\n#include <libsolidity/experimental/codegen/IRGenerationContext.h>\n#include <libsolidity/experimental/codegen/IRGeneratorForStatements.h>\n\n#include <libsolidity/experimental/codegen/Common.h>\n\n#include <libsolidity/experimental/analysis/Analysis.h>\n#include <libsolidity/experimental/analysis/TypeInference.h>\n\n#include <libsolidity/experimental/ast/TypeSystemHelper.h>\n\n#include <libyul/AsmPrinter.h>\n#include <libyul/AST.h>\n#include <libyul/optimiser/ASTCopier.h>\n\n#include <liblangutil/SourceReferenceFormatter.h>\n\n#include <libsolutil/Whiskers.h>\n\n#include <range/v3/view/drop_last.hpp>\n\n#include <variant>\n\nusing namespace solidity;\nusing namespace solidity::frontend::experimental;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\n\nIRGenerator::IRGenerator(\n\tEVMVersion _evmVersion,\n\tstd::optional<uint8_t> _eofVersion,\n\tfrontend::RevertStrings, std::map<std::string, unsigned int>,\n\tDebugInfoSelection const&,\n\tCharStreamProvider const*,\n\tAnalysis const& _analysis\n):\n\tm_evmVersion(_evmVersion),\n\tm_eofVersion(_eofVersion),\n\t//m_debugInfoSelection(_debugInfoSelection),\n\t//m_soliditySourceProvider(_soliditySourceProvider),\n\tm_env(_analysis.typeSystem().env().clone()),\n\tm_context{_analysis, &m_env, {}, {}}\n{\n}\n\nstd::string IRGenerator::run(\n\tContractDefinition const& _contract,\n\tbytes const& /*_cborMetadata*/,\n\tstd::map<ContractDefinition const*, std::string_view const> const& /*_otherYulSources*/\n)\n{\n\tsolUnimplementedAssert(!m_eofVersion.has_value(), \"Experimental IRGenerator not implemented for EOF\");\n\n\tWhiskers t(R\"(\n\t\tobject \"<CreationObject>\" {\n\t\t\tcode {\n\t\t\t\tcodecopy(0, dataoffset(\"<DeployedObject>\"), datasize(\"<DeployedObject>\"))\n\t\t\t\treturn(0, datasize(\"<DeployedObject>\"))\n\t\t\t}\n\t\t\tobject \"<DeployedObject>\" {\n\t\t\t\tcode {\n\t\t\t\t\t<code>\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t)\");\n\tt(\"CreationObject\", IRNames::creationObject(_contract));\n\tt(\"DeployedObject\", IRNames::deployedObject(_contract));\n\tt(\"code\", generate(_contract));\n\n\treturn t.render();\n}\n\nstd::string IRGenerator::generate(ContractDefinition const& _contract)\n{\n\tstd::stringstream code;\n\tcode << \"{\\n\";\n\tif (_contract.fallbackFunction())\n\t{\n\t\tauto type = m_context.analysis.annotation<TypeInference>(*_contract.fallbackFunction()).type;\n\t\tsolAssert(type);\n\t\ttype = m_context.env->resolve(*type);\n\t\tcode << IRNames::function(*m_context.env, *_contract.fallbackFunction(), *type) << \"()\\n\";\n\t\tm_context.enqueueFunctionDefinition(_contract.fallbackFunction(), *type);\n\t}\n\tcode << \"revert(0,0)\\n\";\n\tcode << \"}\\n\";\n\n\twhile (!m_context.functionQueue.empty())\n\t{\n\t\tauto queueEntry = m_context.functionQueue.front();\n\t\tm_context.functionQueue.pop_front();\n\t\tauto& generatedTypes = m_context.generatedFunctions.insert(std::make_pair(queueEntry.function, std::vector<Type>{})).first->second;\n\t\tif (!util::contains_if(generatedTypes, [&](auto const& _generatedType) { return m_context.env->typeEquals(_generatedType, queueEntry.type); }))\n\t\t{\n\t\t\tgeneratedTypes.emplace_back(queueEntry.type);\n\t\t\tcode << generate(*queueEntry.function, queueEntry.type);\n\t\t}\n\t}\n\n\treturn code.str();\n}\n\nstd::string IRGenerator::generate(FunctionDefinition const& _function, Type _type)\n{\n\tTypeEnvironment newEnv = m_context.env->clone();\n\tScopedSaveAndRestore envRestore{m_context.env, &newEnv};\n\tauto type = m_context.analysis.annotation<TypeInference>(_function).type;\n\tsolAssert(type);\n\tfor (auto err: newEnv.unify(*type, _type))\n\t{\n\t\tTypeEnvironmentHelpers helper{newEnv};\n\t\tsolAssert(false, helper.typeToString(*type) + \" <-> \" + helper.typeToString(_type));\n\t}\n\tstd::stringstream code;\n\tcode << \"function \" << IRNames::function(newEnv, _function, _type) << \"(\";\n\tif (_function.parameters().size() > 1)\n\t\tfor (auto const& arg: _function.parameters() | ranges::views::drop_last(1))\n\t\t\tcode << IRNames::localVariable(*arg) << \", \";\n\tif (!_function.parameters().empty())\n\t\tcode << IRNames::localVariable(*_function.parameters().back());\n\tcode << \")\";\n\tif (_function.experimentalReturnExpression())\n\t{\n\t\tauto returnType = m_context.analysis.annotation<TypeInference>(*_function.experimentalReturnExpression()).type;\n\t\tsolAssert(returnType);\n\t\tif (!m_env.typeEquals(*returnType, m_context.analysis.typeSystem().type(PrimitiveType::Unit, {})))\n\t\t{\n\t\t\t// TODO: destructure tuples.\n\t\t\tcode << \" -> \" << IRNames::localVariable(*_function.experimentalReturnExpression()) << \" \";\n\t\t}\n\t}\n\tcode << \"{\\n\";\n\tfor (auto _statement: _function.body().statements())\n\t{\n\t\tIRGeneratorForStatements statementGenerator{m_context};\n\t\tcode << statementGenerator.generate(*_statement);\n\t}\n\tcode << \"}\\n\";\n\treturn code.str();\n}\n"
  },
  {
    "path": "libsolidity/experimental/codegen/IRGenerator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/experimental/codegen/IRGenerationContext.h>\n#include <libsolidity/interface/DebugSettings.h>\n#include <libsolidity/interface/OptimiserSettings.h>\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/CallGraph.h>\n#include <libsolidity/experimental/ast/TypeSystem.h>\n\n#include <liblangutil/CharStreamProvider.h>\n#include <liblangutil/DebugInfoSelection.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <libsolutil/JSON.h>\n\n#include <string>\n\nnamespace solidity::frontend::experimental\n{\n\nclass Analysis;\n\nclass IRGenerator\n{\npublic:\n\tIRGenerator(\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tRevertStrings /*_revertStrings*/,\n\t\tstd::map<std::string, unsigned> /*_sourceIndices*/,\n\t\tlangutil::DebugInfoSelection const& /*_debugInfoSelection*/,\n\t\tlangutil::CharStreamProvider const* /*_soliditySourceProvider*/,\n\t\tAnalysis const& _analysis\n\t);\n\n\tstd::string run(\n\t\tContractDefinition const& _contract,\n\t\tbytes const& _cborMetadata,\n\t\tstd::map<ContractDefinition const*, std::string_view const> const& _otherYulSources\n\t);\n\n\tstd::string generate(ContractDefinition const& _contract);\n\tstd::string generate(FunctionDefinition const& _function, Type _type);\nprivate:\n\tlangutil::EVMVersion const m_evmVersion;\n\tstd::optional<uint8_t> const m_eofVersion;\n\tOptimiserSettings const m_optimiserSettings;\n\t//langutil::DebugInfoSelection m_debugInfoSelection = {};\n\t//langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr;\n\tTypeEnvironment m_env;\n\tIRGenerationContext m_context;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/experimental/codegen/IRGeneratorForStatements.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/experimental/codegen/IRGeneratorForStatements.h>\n\n#include <libsolidity/experimental/analysis/Analysis.h>\n#include <libsolidity/experimental/analysis/TypeClassRegistration.h>\n#include <libsolidity/experimental/analysis/TypeInference.h>\n#include <libsolidity/experimental/analysis/TypeRegistration.h>\n\n#include <libsolidity/experimental/ast/TypeSystemHelper.h>\n\n#include <libyul/AsmPrinter.h>\n#include <libyul/AST.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/optimiser/ASTCopier.h>\n\n#include <libsolidity/experimental/codegen/Common.h>\n\n#include <range/v3/view/drop_last.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::experimental;\nusing namespace std::string_literals;\n\nstd::string IRGeneratorForStatements::generate(ASTNode const& _node)\n{\n\t_node.accept(*this);\n\treturn m_code.str();\n}\n\n\nnamespace\n{\n\nstruct CopyTranslate: public yul::ASTCopier\n{\n\tCopyTranslate(\n\t\tIRGenerationContext const& _context,\n\t\tstd::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> _references\n\t): m_context(_context), m_references(std::move(_references)) {}\n\n\tusing ASTCopier::operator();\n\n\tyul::Expression operator()(yul::Identifier const& _identifier) override\n\t{\n\t\t// The operator() function is only called in lvalue context. In rvalue context,\n\t\t// only translate(yul::Identifier) is called.\n\t\tif (m_references.count(&_identifier))\n\t\t\treturn translateReference(_identifier);\n\t\telse\n\t\t\treturn ASTCopier::operator()(_identifier);\n\t}\n\n\tyul::YulName translateIdentifier(yul::YulName _name) override\n\t{\n\t\treturn yul::YulName{\"usr$\" + _name.str()};\n\t}\n\n\tyul::Identifier translate(yul::Identifier const& _identifier) override\n\t{\n\t\tif (!m_references.count(&_identifier))\n\t\t\treturn ASTCopier::translate(_identifier);\n\n\t\tyul::Expression translated = translateReference(_identifier);\n\t\tsolAssert(std::holds_alternative<yul::Identifier>(translated));\n\t\treturn std::get<yul::Identifier>(std::move(translated));\n\t}\n\nprivate:\n\n\t/// Translates a reference to a local variable, potentially including\n\t/// a suffix. Might return a literal, which causes this to be invalid in\n\t/// lvalue-context.\n\tyul::Expression translateReference(yul::Identifier const& _identifier)\n\t{\n\t\tauto const& reference = m_references.at(&_identifier);\n\t\tauto const varDecl = dynamic_cast<VariableDeclaration const*>(reference.declaration);\n\t\tsolAssert(varDecl, \"External reference in inline assembly to something that is not a variable declaration.\");\n\t\tauto type = m_context.analysis.annotation<TypeInference>(*varDecl).type;\n\t\tsolAssert(type);\n\t\tsolAssert(m_context.env->typeEquals(*type, m_context.analysis.typeSystem().type(PrimitiveType::Word, {})));\n\t\tstd::string value = IRNames::localVariable(*varDecl);\n\t\treturn yul::Identifier{_identifier.debugData, yul::YulName{value}};\n\t}\n\n\tIRGenerationContext const& m_context;\n\tstd::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> m_references;\n};\n\n}\n\nbool IRGeneratorForStatements::visit(TupleExpression const& _tupleExpression)\n{\n\tstd::vector<std::string> components;\n\tfor (auto const& component: _tupleExpression.components())\n\t{\n\t\tsolUnimplementedAssert(component);\n\t\tcomponent->accept(*this);\n\t\tcomponents.emplace_back(IRNames::localVariable(*component));\n\t}\n\n\tsolUnimplementedAssert(false, \"No support for tuples.\");\n\n\treturn false;\n}\n\nbool IRGeneratorForStatements::visit(InlineAssembly const& _assembly)\n{\n\tCopyTranslate bodyCopier{m_context, _assembly.annotation().externalReferences};\n\tyul::Statement modified = bodyCopier(_assembly.operations().root());\n\tsolAssert(std::holds_alternative<yul::Block>(modified));\n\tm_code << yul::AsmPrinter(_assembly.dialect())(std::get<yul::Block>(modified)) << \"\\n\";\n\treturn false;\n}\n\nbool IRGeneratorForStatements::visit(VariableDeclarationStatement const& _variableDeclarationStatement)\n{\n\tif (_variableDeclarationStatement.initialValue())\n\t\t_variableDeclarationStatement.initialValue()->accept(*this);\n\tsolAssert(_variableDeclarationStatement.declarations().size() == 1, \"multi variable declarations not supported\");\n\tVariableDeclaration const* variableDeclaration = _variableDeclarationStatement.declarations().front().get();\n\tsolAssert(variableDeclaration);\n\t// TODO: check the type of the variable; register local variable; initialize\n\tm_code << \"let \" << IRNames::localVariable(*variableDeclaration);\n\tif (_variableDeclarationStatement.initialValue())\n\t\tm_code << \" := \" << IRNames::localVariable(*_variableDeclarationStatement.initialValue());\n\tm_code << \"\\n\";\n\treturn false;\n}\n\nbool IRGeneratorForStatements::visit(ExpressionStatement const&)\n{\n\treturn true;\n}\n\nbool IRGeneratorForStatements::visit(Identifier const& _identifier)\n{\n\tif (auto const* var = dynamic_cast<VariableDeclaration const*>(_identifier.annotation().referencedDeclaration))\n\t{\n\t\tm_code << \"let \" << IRNames::localVariable(_identifier) << \" := \" << IRNames::localVariable(*var) << \"\\n\";\n\t}\n\telse if (auto const* function = dynamic_cast<FunctionDefinition const*>(_identifier.annotation().referencedDeclaration))\n\t\tsolAssert(m_expressionDeclaration.emplace(&_identifier, function).second);\n\telse if (auto const* typeClass = dynamic_cast<TypeClassDefinition const*>(_identifier.annotation().referencedDeclaration))\n\t\tsolAssert(m_expressionDeclaration.emplace(&_identifier, typeClass).second);\n\telse if (auto const* typeDefinition = dynamic_cast<TypeDefinition const*>(_identifier.annotation().referencedDeclaration))\n\t\tsolAssert(m_expressionDeclaration.emplace(&_identifier, typeDefinition).second);\n\telse\n\t\tsolAssert(false, \"Unsupported Identifier\");\n\treturn false;\n}\n\nvoid IRGeneratorForStatements::endVisit(Return const& _return)\n{\n\tif (Expression const* value = _return.expression())\n\t{\n\t\tsolAssert(_return.annotation().function, \"Invalid return.\");\n\t\tsolAssert(_return.annotation().function->experimentalReturnExpression(), \"Invalid return.\");\n\t\tm_code << IRNames::localVariable(*_return.annotation().function->experimentalReturnExpression()) << \" := \" << IRNames::localVariable(*value) << \"\\n\";\n\t}\n\n\tm_code << \"leave\\n\";\n}\n\nexperimental::Type IRGeneratorForStatements::type(ASTNode const& _node) const\n{\n\tauto type = m_context.analysis.annotation<TypeInference>(_node).type;\n\tsolAssert(type);\n\treturn *type;\n}\n\nvoid IRGeneratorForStatements::endVisit(BinaryOperation const& _binaryOperation)\n{\n\tTypeSystemHelpers helper{m_context.analysis.typeSystem()};\n\tType leftType = type(_binaryOperation.leftExpression());\n\tType rightType = type(_binaryOperation.rightExpression());\n\tType resultType = type(_binaryOperation);\n\tType functionType = helper.functionType(helper.tupleType({leftType, rightType}), resultType);\n\tauto [typeClass, memberName] = m_context.analysis.annotation<TypeInference>().operators.at(_binaryOperation.getOperator());\n\tauto const& functionDefinition = resolveTypeClassFunction(typeClass, memberName, functionType);\n\t// TODO: deduplicate with FunctionCall\n\t// TODO: get around resolveRecursive by passing the environment further down?\n\tfunctionType = m_context.env->resolveRecursive(functionType);\n\tm_context.enqueueFunctionDefinition(&functionDefinition, functionType);\n\t// TODO: account for return stack size\n\tm_code << \"let \" << IRNames::localVariable(_binaryOperation) << \" := \" << IRNames::function(*m_context.env, functionDefinition, functionType) << \"(\"\n\t\t<< IRNames::localVariable(_binaryOperation.leftExpression()) << \", \" << IRNames::localVariable(_binaryOperation.rightExpression()) << \")\\n\";\n}\n\nnamespace\n{\nTypeRegistration::TypeClassInstantiations const& typeClassInstantiations(IRGenerationContext const& _context, TypeClass _class)\n{\n\tauto const* typeClassDeclaration = _context.analysis.typeSystem().typeClassDeclaration(_class);\n\tif (typeClassDeclaration)\n\t\treturn _context.analysis.annotation<TypeRegistration>(*typeClassDeclaration).instantiations;\n\t// TODO: better mechanism than fetching by name.\n\tauto& instantiations = _context.analysis.annotation<TypeRegistration>().builtinClassInstantiations;\n\tauto& builtinClassesByName = _context.analysis.annotation<TypeInference>().builtinClassesByName;\n\treturn instantiations.at(builtinClassesByName.at(_context.analysis.typeSystem().typeClassName(_class)));\n}\n}\n\nFunctionDefinition const& IRGeneratorForStatements::resolveTypeClassFunction(TypeClass _class, std::string _name, Type _type)\n{\n\tTypeSystemHelpers helper{m_context.analysis.typeSystem()};\n\n\tTypeEnvironment env = m_context.env->clone();\n\tType genericFunctionType = env.fresh(m_context.analysis.annotation<TypeInference>().typeClassFunctions.at(_class).at(_name));\n\tauto typeVars = TypeEnvironmentHelpers{env}.typeVars(genericFunctionType);\n\tsolAssert(typeVars.size() == 1);\n\tsolAssert(env.unify(genericFunctionType, _type).empty());\n\tauto typeClassInstantiation = std::get<0>(helper.destTypeConstant(env.resolve(typeVars.front())));\n\n\tauto const& instantiations = typeClassInstantiations(m_context, _class);\n\tTypeClassInstantiation const* instantiation = instantiations.at(typeClassInstantiation);\n\tFunctionDefinition const* functionDefinition = nullptr;\n\tfor (auto const& node: instantiation->subNodes())\n\t{\n\t\tauto const* def = dynamic_cast<FunctionDefinition const*>(node.get());\n\t\tsolAssert(def);\n\t\tif (def->name() == _name)\n\t\t{\n\t\t\tfunctionDefinition = def;\n\t\t\tbreak;\n\t\t}\n\t}\n\tsolAssert(functionDefinition);\n\treturn *functionDefinition;\n}\n\nvoid IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)\n{\n\tTypeSystemHelpers helper{m_context.analysis.typeSystem()};\n\t// TODO: avoid resolve?\n\tauto expressionType = m_context.env->resolve(type(_memberAccess.expression()));\n\tauto constructor = std::get<0>(helper.destTypeConstant(expressionType));\n\tauto memberAccessType = type(_memberAccess);\n\t// TODO: better mechanism\n\tif (constructor == m_context.analysis.typeSystem().constructor(PrimitiveType::Bool))\n\t{\n\t\tif (_memberAccess.memberName() == \"abs\")\n\t\t\tsolAssert(m_expressionDeclaration.emplace(&_memberAccess, Builtins::ToBool).second);\n\t\telse if (_memberAccess.memberName() == \"rep\")\n\t\t\tsolAssert(m_expressionDeclaration.emplace(&_memberAccess, Builtins::FromBool).second);\n\t\treturn;\n\t}\n\tauto const* declaration = m_context.analysis.typeSystem().constructorInfo(constructor).typeDeclaration;\n\tsolAssert(declaration);\n\tif (auto const* typeClassDefinition = dynamic_cast<TypeClassDefinition const*>(declaration))\n\t{\n\t\tsolAssert(m_context.analysis.annotation<TypeClassRegistration>(*typeClassDefinition).typeClass.has_value());\n\t\tTypeClass typeClass = m_context.analysis.annotation<TypeClassRegistration>(*typeClassDefinition).typeClass.value();\n\t\tsolAssert(m_expressionDeclaration.emplace(\n\t\t\t&_memberAccess,\n\t\t\t&resolveTypeClassFunction(typeClass, _memberAccess.memberName(), memberAccessType)\n\t\t).second);\n\t}\n\telse if (dynamic_cast<TypeDefinition const*>(declaration))\n\t{\n\t\tif (_memberAccess.memberName() == \"abs\" || _memberAccess.memberName() == \"rep\")\n\t\t\tsolAssert(m_expressionDeclaration.emplace(&_memberAccess, Builtins::Identity).second);\n\t\telse\n\t\t\tsolAssert(false);\n\t}\n\telse\n\t\tsolAssert(false);\n}\n\nbool IRGeneratorForStatements::visit(ElementaryTypeNameExpression const&)\n{\n\t// TODO: is this always a no-op?\n\treturn false;\n}\n\nvoid IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)\n{\n\tType functionType = type(_functionCall.expression());\n\tsolUnimplementedAssert(m_expressionDeclaration.count(&_functionCall.expression()) != 0, \"No support for calling functions pointers yet.\");\n\tauto declaration = m_expressionDeclaration.at(&_functionCall.expression());\n\tif (auto builtin = std::get_if<Builtins>(&declaration))\n\t{\n\t\tswitch (*builtin)\n\t\t{\n\t\tcase Builtins::FromBool:\n\t\tcase Builtins::Identity:\n\t\t\tsolAssert(_functionCall.arguments().size() == 1);\n\t\t\tm_code << \"let \" << IRNames::localVariable(_functionCall) << \" := \" << IRNames::localVariable(*_functionCall.arguments().front()) << \"\\n\";\n\t\t\treturn;\n\t\tcase Builtins::ToBool:\n\t\t\tsolAssert(_functionCall.arguments().size() == 1);\n\t\t\tm_code << \"let \" << IRNames::localVariable(_functionCall) << \" := iszero(iszero(\" << IRNames::localVariable(*_functionCall.arguments().front()) << \"))\\n\";\n\t\t\treturn;\n\t\t}\n\t\tsolAssert(false);\n\t}\n\tFunctionDefinition const* functionDefinition = dynamic_cast<FunctionDefinition const*>(std::get<Declaration const*>(declaration));\n\tsolAssert(functionDefinition);\n\t// TODO: get around resolveRecursive by passing the environment further down?\n\tfunctionType = m_context.env->resolveRecursive(functionType);\n\tm_context.enqueueFunctionDefinition(functionDefinition, functionType);\n\t// TODO: account for return stack size\n\tsolAssert(!functionDefinition->returnParameterList());\n\tif (functionDefinition->experimentalReturnExpression())\n\t\tm_code << \"let \" << IRNames::localVariable(_functionCall) << \" := \";\n\tm_code << IRNames::function(*m_context.env, *functionDefinition, functionType) << \"(\";\n\tauto const& arguments = _functionCall.arguments();\n\tif (arguments.size() > 1)\n\t\tfor (auto arg: arguments | ranges::views::drop_last(1))\n\t\t\tm_code << IRNames::localVariable(*arg) << \", \";\n\tif (!arguments.empty())\n\t\tm_code << IRNames::localVariable(*arguments.back());\n\tm_code << \")\\n\";\n}\n\nbool IRGeneratorForStatements::visit(FunctionCall const&)\n{\n\treturn true;\n}\n\nbool IRGeneratorForStatements::visit(Block const& _block)\n{\n\tm_code << \"{\\n\";\n\tsolAssert(!_block.unchecked());\n\tfor (auto const& statement: _block.statements())\n\t\tstatement->accept(*this);\n\tm_code << \"}\\n\";\n\treturn false;\n}\n\nbool IRGeneratorForStatements::visit(IfStatement const& _ifStatement)\n{\n\t_ifStatement.condition().accept(*this);\n\tif (_ifStatement.falseStatement())\n\t{\n\t\tm_code << \"switch \" << IRNames::localVariable(_ifStatement.condition()) << \" {\\n\";\n\t\tm_code << \"case 0 {\\n\";\n\t\t_ifStatement.falseStatement()->accept(*this);\n\t\tm_code << \"}\\n\";\n\t\tm_code << \"default {\\n\";\n\t\t_ifStatement.trueStatement().accept(*this);\n\t\tm_code << \"}\\n\";\n\t}\n\telse\n\t{\n\t\tm_code << \"if \" << IRNames::localVariable(_ifStatement.condition()) << \" {\\n\";\n\t\t_ifStatement.trueStatement().accept(*this);\n\t\tm_code << \"}\\n\";\n\t}\n\treturn false;\n}\n\nbool IRGeneratorForStatements::visit(Assignment const& _assignment)\n{\n\t_assignment.rightHandSide().accept(*this);\n\tauto const* lhs = dynamic_cast<Identifier const*>(&_assignment.leftHandSide());\n\tsolAssert(lhs, \"Can only assign to identifiers.\");\n\tauto const* lhsVar = dynamic_cast<VariableDeclaration const*>(lhs->annotation().referencedDeclaration);\n\tsolAssert(lhsVar, \"Can only assign to identifiers referring to variables.\");\n\tm_code << IRNames::localVariable(*lhsVar) << \" := \" << IRNames::localVariable(_assignment.rightHandSide()) << \"\\n\";\n\n\tm_code << \"let \" << IRNames::localVariable(_assignment) << \" := \" << IRNames::localVariable(*lhsVar) << \"\\n\";\n\treturn false;\n}\n\n\nbool IRGeneratorForStatements::visitNode(ASTNode const&)\n{\n\tsolAssert(false, \"Unsupported AST node during statement code generation.\");\n}\n"
  },
  {
    "path": "libsolidity/experimental/codegen/IRGeneratorForStatements.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/experimental/codegen/IRGenerationContext.h>\n#include <libsolidity/ast/ASTVisitor.h>\n\n#include <functional>\n#include <sstream>\n\nnamespace solidity::frontend::experimental\n{\nclass Analysis;\n\nclass IRGeneratorForStatements: public ASTConstVisitor\n{\npublic:\n\tIRGeneratorForStatements(IRGenerationContext& _context): m_context(_context) {}\n\n\tstd::string generate(ASTNode const& _node);\nprivate:\n\tbool visit(ExpressionStatement const& _expressionStatement) override;\n\tbool visit(Block const& _block) override;\n\tbool visit(IfStatement const& _ifStatement) override;\n\tbool visit(Assignment const& _assignment) override;\n\tbool visit(Identifier const& _identifier) override;\n\tbool visit(FunctionCall const& _functionCall) override;\n\tvoid endVisit(FunctionCall const& _functionCall) override;\n\tbool visit(ElementaryTypeNameExpression const& _elementaryTypeNameExpression) override;\n\tbool visit(MemberAccess const&) override { return true; }\n\tbool visit(TupleExpression const&) override;\n\tvoid endVisit(MemberAccess const& _memberAccess) override;\n\tbool visit(InlineAssembly const& _inlineAssembly) override;\n\tbool visit(BinaryOperation const&) override { return true; }\n\tvoid endVisit(BinaryOperation const& _binaryOperation) override;\n\tbool visit(VariableDeclarationStatement const& _variableDeclarationStatement) override;\n\tbool visit(Return const&) override { return true; }\n\tvoid endVisit(Return const& _return) override;\n\t/// Default visit will reject all AST nodes that are not explicitly supported.\n\tbool visitNode(ASTNode const& _node) override;\n\tIRGenerationContext& m_context;\n\tstd::stringstream m_code;\n\tenum class Builtins\n\t{\n\t\tIdentity,\n\t\tFromBool,\n\t\tToBool\n\t};\n\tstd::map<Expression const*, std::variant<Declaration const*, Builtins>> m_expressionDeclaration;\n\tType type(ASTNode const& _node) const;\n\n\tFunctionDefinition const& resolveTypeClassFunction(TypeClass _class, std::string _name, Type _type);\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/ArraySlicePredicate.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/ArraySlicePredicate.h>\n\n#include <libsolidity/formal/SymbolicVariables.h>\n\n#include <liblangutil/Exceptions.h>\n\nusing namespace solidity;\nusing namespace solidity::smtutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::smt;\n\nstd::map<std::string, ArraySlicePredicate::SliceData> ArraySlicePredicate::m_slicePredicates;\n\nstd::pair<bool, ArraySlicePredicate::SliceData const&> ArraySlicePredicate::create(SortPointer _sort, EncodingContext& _context)\n{\n\tsolAssert(_sort->kind == Kind::Tuple, \"\");\n\tauto tupleSort = std::dynamic_pointer_cast<TupleSort>(_sort);\n\tsolAssert(tupleSort, \"\");\n\n\tauto tupleName = tupleSort->name;\n\tif (m_slicePredicates.count(tupleName))\n\t\treturn {true, m_slicePredicates.at(tupleName)};\n\n\tauto sort = tupleSort->components.at(0);\n\tsolAssert(sort->kind == Kind::Array, \"\");\n\n\tsmt::SymbolicArrayVariable aVar{sort, \"a_\" + tupleName, _context };\n\tsmt::SymbolicArrayVariable bVar{sort, \"b_\" + tupleName, _context};\n\tsmt::SymbolicIntVariable startVar{TypeProvider::uint256(), TypeProvider::uint256(), \"start_\" + tupleName, _context};\n\tsmt::SymbolicIntVariable endVar{TypeProvider::uint256(), TypeProvider::uint256(), \"end_\" + tupleName, _context };\n\tsmt::SymbolicIntVariable iVar{TypeProvider::uint256(), TypeProvider::uint256(), \"i_\" + tupleName, _context};\n\n\tstd::vector<SortPointer> domain{sort, sort, startVar.sort(), endVar.sort()};\n\tauto sliceSort = std::make_shared<FunctionSort>(domain, SortProvider::boolSort);\n\tPredicate const& slice = *Predicate::create(sliceSort, \"array_slice_\" + tupleName, PredicateType::Custom, _context);\n\n\tdomain.emplace_back(iVar.sort());\n\tauto predSort = std::make_shared<FunctionSort>(domain, SortProvider::boolSort);\n\tPredicate const& header = *Predicate::create(predSort, \"array_slice_header_\" + tupleName, PredicateType::Custom, _context);\n\tPredicate const& loop = *Predicate::create(predSort, \"array_slice_loop_\" + tupleName, PredicateType::Custom, _context);\n\n\tauto a = aVar.elements();\n\tauto b = bVar.elements();\n\tauto start = startVar.currentValue();\n\tauto end = endVar.currentValue();\n\tauto i = iVar.currentValue();\n\n\tauto rule1 = smtutil::Expression::implies(\n\t\tend > start,\n\t\theader({a, b, start, end, 0})\n\t);\n\n\tauto rule2 = smtutil::Expression::implies(\n\t\theader({a, b, start, end, i}) && i >= (end - start),\n\t\tslice({a, b, start, end})\n\t);\n\n\tauto rule3 = smtutil::Expression::implies(\n\t\theader({a, b, start, end, i}) && i >= 0 && i < (end - start),\n\t\tloop({a, b, start, end, i})\n\t);\n\n\tauto b_i = smtutil::Expression::select(b, i);\n\tauto a_start_i = smtutil::Expression::select(a, start + i);\n\tauto rule4 = smtutil::Expression::implies(\n\t\tloop({a, b, start, end, i}) && b_i == a_start_i,\n\t\theader({a, b, start, end, i + 1})\n\t);\n\n\treturn {false, m_slicePredicates[tupleName] = {\n\t\t{&slice, &header, &loop},\n\t\t{std::move(rule1), std::move(rule2), std::move(rule3), std::move(rule4)}\n\t}};\n}\n"
  },
  {
    "path": "libsolidity/formal/ArraySlicePredicate.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/formal/Predicate.h>\n\n#include <libsmtutil/Sorts.h>\n\n#include <vector>\n\nnamespace solidity::frontend\n{\n\n/**\n * Contains the set of rules to compute an array slice.\n * Rules:\n * 1. end > start => ArraySliceHeader(a, b, start, end, 0)\n * 2. ArraySliceHeader(a, b, start, end, i) && i >= (end - start) => ArraySlice(a, b, start, end)\n * 3. ArraySliceHeader(a, b, start, end, i) && i >= 0 && i < (end - start) => ArraySliceLoop(a, b, start, end, i)\n * 4. ArraySliceLoop(a, b, start, end, i) && b[i] = a[start + i] => ArraySliceHeader(a, b, start, end, i + 1)\n *\n * The rule to be used by CHC is ArraySlice(a, b, start, end).\n */\n\nstruct ArraySlicePredicate\n{\n\t/// Contains the predicates and rules created to compute\n\t/// array slices for a given sort.\n\tstruct SliceData\n\t{\n\t\tstd::vector<Predicate const*> predicates;\n\t\tstd::vector<smtutil::Expression> rules;\n\t};\n\n\t/// @returns a flag representing whether the array slice predicates had already been created before for this sort,\n\t/// and the corresponding slice data.\n\tstatic std::pair<bool, SliceData const&> create(smtutil::SortPointer _sort, smt::EncodingContext& _context);\n\n\tstatic void reset() { m_slicePredicates.clear(); }\n\nprivate:\n\t/// Maps a unique sort name to its slice data.\n\tstatic std::map<std::string, SliceData> m_slicePredicates;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/BMC.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/BMC.h>\n\n#include <libsolidity/formal/Cvc5SMTLib2Interface.h>\n#include <libsolidity/formal/SymbolicTypes.h>\n#include <libsolidity/formal/Z3SMTLib2Interface.h>\n\n#include <libsmtutil/SMTLib2Interface.h>\n#include <libsmtutil/SMTPortfolio.h>\n\n#include <liblangutil/CharStream.h>\n#include <liblangutil/CharStreamProvider.h>\n\n#include <utility>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::smt;\nusing namespace solidity::smtutil;\n\nBMC::BMC(\n\tsmt::EncodingContext& _context,\n\tUniqueErrorReporter& _errorReporter,\n\tUniqueErrorReporter& _unsupportedErrorReporter,\n\tErrorReporter& _provedSafeReporter,\n\tstd::map<h256, std::string> const& _smtlib2Responses,\n\tReadCallback::Callback const& _smtCallback,\n\tModelCheckerSettings _settings,\n\tCharStreamProvider const& _charStreamProvider\n):\n\tSMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _provedSafeReporter, _charStreamProvider)\n{\n\tstd::vector<std::unique_ptr<BMCSolverInterface>> solvers;\n\tif (_settings.solvers.smtlib2)\n\t\tsolvers.emplace_back(std::make_unique<SMTLib2Interface>(_smtlib2Responses, _smtCallback, _settings.timeout));\n\tif (_settings.solvers.cvc5)\n\t\tsolvers.emplace_back(std::make_unique<Cvc5SMTLib2Interface>(_smtCallback, _settings.timeout));\n\tif (_settings.solvers.z3 )\n\t\tsolvers.emplace_back(std::make_unique<Z3SMTLib2Interface>(_smtCallback, _settings.timeout));\n\tm_interface = std::make_unique<SMTPortfolio>(std::move(solvers), _settings.timeout);\n}\n\nvoid BMC::analyze(SourceUnit const& _source, std::map<ASTNode const*, std::set<VerificationTargetType>, smt::EncodingContext::IdCompare> _solvedTargets)\n{\n\t// At this point every enabled solver is available.\n\tif (!m_settings.solvers.cvc5 && !m_settings.solvers.smtlib2 && !m_settings.solvers.z3)\n\t{\n\t\tm_errorReporter.warning(\n\t\t\t7710_error,\n\t\t\tSourceLocation(),\n\t\t\t\"BMC analysis was not possible since no SMT solver was found and enabled.\"\n\t\t\t\" The accepted solvers for BMC are cvc5 and z3.\"\n\t\t);\n\t\treturn;\n\t}\n\n\tSMTEncoder::resetSourceAnalysis();\n\n\tstate().prepareForSourceUnit(_source, false);\n\tm_solvedTargets = std::move(_solvedTargets);\n\tm_context.setSolver(m_interface.get());\n\tm_context.reset();\n\tm_context.setAssertionAccumulation(true);\n\tauto const& sources = sourceDependencies(_source);\n\tcreateFreeConstants(sources);\n\tcreateStateVariables(sources);\n\tm_unprovedAmt = 0;\n\n\t_source.accept(*this);\n\n\tif (m_unprovedAmt > 0 && !m_settings.showUnproved)\n\t\tm_errorReporter.warning(\n\t\t\t2788_error,\n\t\t\t{},\n\t\t\t\"BMC: \" +\n\t\t\tstd::to_string(m_unprovedAmt) +\n\t\t\t\" verification condition(s) could not be proved.\" +\n\t\t\t\" Enable the model checker option \\\"show unproved\\\" to see all of them.\" +\n\t\t\t\" Consider choosing a specific contract to be verified in order to reduce the solving problems.\" +\n\t\t\t\" Consider increasing the timeout per query.\"\n\t\t);\n\n\tif (!m_settings.showProvedSafe && !m_safeTargets.empty())\n\t{\n\t\tstd::size_t provedSafeNum = 0;\n\t\tfor (auto&& [_, targets]: m_safeTargets)\n\t\t\tprovedSafeNum += targets.size();\n\t\tm_errorReporter.info(\n\t\t\t6002_error,\n\t\t\t\"BMC: \" +\n\t\t\tstd::to_string(provedSafeNum) +\n\t\t\t\" verification condition(s) proved safe!\" +\n\t\t\t\" Enable the model checker option \\\"show proved safe\\\" to see all of them.\"\n\t\t);\n\t}\n\telse if (m_settings.showProvedSafe)\n\t\tfor (auto const& [node, targets]: m_safeTargets)\n\t\t\tfor (auto const& target: targets)\n\t\t\t\tm_provedSafeReporter.info(\n\t\t\t\t\t2961_error,\n\t\t\t\t\tnode->location(),\n\t\t\t\t\t\"BMC: \" +\n\t\t\t\t\ttargetDescription(target) +\n\t\t\t\t\t\" check is safe!\"\n\t\t\t\t);\n\n\t// If this check is true, Z3 and cvc5 are not available\n\t// and the query answers were not provided, since SMTPortfolio\n\t// guarantees that SmtLib2Interface is the first solver, if enabled.\n\tif (\n\t\t!m_interface->unhandledQueries().empty() &&\n\t\tm_interface->solvers() == 1 &&\n\t\tm_settings.solvers.smtlib2\n\t)\n\t\tm_errorReporter.warning(\n\t\t\t8084_error,\n\t\t\tSourceLocation(),\n\t\t\t\"BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available.\"\n\t\t\t\" None of the installed solvers was enabled.\"\n\t\t);\n}\n\nbool BMC::shouldInlineFunctionCall(\n\tFunctionCall const& _funCall,\n\tContractDefinition const* _scopeContract,\n\tContractDefinition const* _contextContract\n)\n{\n\tauto funDef = functionCallToDefinition(_funCall, _scopeContract, _contextContract);\n\tif (!funDef || !funDef->isImplemented())\n\t\treturn false;\n\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);\n\tif (funType.kind() == FunctionType::Kind::External)\n\t\treturn isExternalCallToThis(&_funCall.expression());\n\telse if (funType.kind() != FunctionType::Kind::Internal)\n\t\treturn false;\n\n\treturn true;\n}\n\n/// AST visitors.\n\nbool BMC::visit(ContractDefinition const& _contract)\n{\n\t// Raises UnimplementedFeatureError in the presence of transient storage variables\n\tTransientDataLocationChecker checker(_contract);\n\n\tinitContract(_contract);\n\n\tSMTEncoder::visit(_contract);\n\n\treturn false;\n}\n\nvoid BMC::endVisit(ContractDefinition const& _contract)\n{\n\tif (auto constructor = _contract.constructor())\n\t\tconstructor->accept(*this);\n\telse\n\t{\n\t\t/// Visiting implicit constructor - we need a dummy callstack frame\n\t\tpushCallStack({nullptr, nullptr});\n\t\tinlineConstructorHierarchy(_contract);\n\t\tpopCallStack();\n\t\t/// Check targets created by state variable initialization.\n\t\tcheckVerificationTargets();\n\t\tm_verificationTargets.clear();\n\t}\n\n\tSMTEncoder::endVisit(_contract);\n}\n\nbool BMC::visit(FunctionDefinition const& _function)\n{\n\t// Free functions need to be visited in the context of a contract.\n\tif (!m_currentContract)\n\t\treturn false;\n\n\tauto contract = dynamic_cast<ContractDefinition const*>(_function.scope());\n\tauto const& hierarchy = m_currentContract->annotation().linearizedBaseContracts;\n\tif (contract && find(hierarchy.begin(), hierarchy.end(), contract) == hierarchy.end())\n\t\tcreateStateVariables(*contract);\n\n\tif (m_callStack.empty())\n\t{\n\t\treset();\n\t\tinitFunction(_function);\n\t\tif (_function.isConstructor() || _function.isPublic())\n\t\t\tm_context.addAssertion(state().txTypeConstraints() && state().txFunctionConstraints(_function));\n\t\tresetStateVariables();\n\t}\n\n\tif (_function.isConstructor())\n\t{\n\t\tsolAssert(contract, \"\");\n\t\tinlineConstructorHierarchy(*contract);\n\t}\n\n\t/// Already visits the children.\n\tSMTEncoder::visit(_function);\n\n\treturn false;\n}\n\nvoid BMC::endVisit(FunctionDefinition const& _function)\n{\n\t// Free functions need to be visited in the context of a contract.\n\tif (!m_currentContract)\n\t\treturn;\n\n\tif (isRootFunction())\n\t{\n\t\tcheckVerificationTargets();\n\t\tm_verificationTargets.clear();\n\t\tm_pathConditions.clear();\n\t}\n\n\tSMTEncoder::endVisit(_function);\n}\n\nbool BMC::visit(IfStatement const& _node)\n{\n\tauto indicesBeforePush = copyVariableIndices();\n\t// This check needs to be done in its own context otherwise\n\t// constraints from the If body might influence it.\n\tm_context.pushSolver();\n\t_node.condition().accept(*this);\n\n\tcheckIfConditionIsConstant(_node.condition());\n\n\tm_context.popSolver();\n\tresetVariableIndices(std::move(indicesBeforePush));\n\n\t_node.condition().accept(*this);\n\tauto conditionExpr = expr(_node.condition());\n\t// visit true branch\n\tauto [indicesEndTrue, trueEndPathCondition] = visitBranch(&_node.trueStatement(), conditionExpr);\n\n\t// visit false branch\n\tdecltype(indicesEndTrue) indicesEndFalse;\n\tauto falseEndPathCondition = currentPathConditions() && !conditionExpr;\n\tif (_node.falseStatement())\n\t\tstd::tie(indicesEndFalse, falseEndPathCondition) = visitBranch(_node.falseStatement(), !conditionExpr);\n\telse\n\t\tindicesEndFalse = copyVariableIndices();\n\n\t// merge the information from branches\n\tsetPathCondition(trueEndPathCondition || falseEndPathCondition);\n\tmergeVariables(expr(_node.condition()), indicesEndTrue, indicesEndFalse);\n\n\treturn false;\n}\n\nbool BMC::visit(Conditional const& _op)\n{\n\tauto indicesBeforePush = copyVariableIndices();\n\tm_context.pushSolver();\n\t_op.condition().accept(*this);\n\tcheckIfConditionIsConstant(_op.condition());\n\tm_context.popSolver();\n\tresetVariableIndices(std::move(indicesBeforePush));\n\n\tSMTEncoder::visit(_op);\n\n\treturn false;\n}\n\n// Unrolls while or do-while loop\nbool BMC::visit(WhileStatement const& _node)\n{\n\tunsigned int bmcLoopIterations = m_settings.bmcLoopIterations.value_or(1);\n\tsmtutil::Expression broke(false);\n\tsmtutil::Expression loopCondition(true);\n\tif (_node.isDoWhile())\n\t{\n\t\tfor (unsigned int i = 0; i < bmcLoopIterations; ++i)\n\t\t{\n\t\t\tm_loopCheckpoints.emplace();\n\n\t\t\tauto indicesBefore = copyVariableIndices();\n\t\t\t_node.body().accept(*this);\n\n\t\t\tauto brokeInCurrentIteration = mergeVariablesFromLoopCheckpoints();\n\n\t\t\tauto indicesBreak = copyVariableIndices();\n\t\t\t_node.condition().accept(*this);\n\t\t\tmergeVariables(\n\t\t\t\t!brokeInCurrentIteration,\n\t\t\t\tcopyVariableIndices(),\n\t\t\t\tindicesBreak\n\t\t\t);\n\n\t\t\tmergeVariables(\n\t\t\t\tbroke || !loopCondition,\n\t\t\t\tindicesBefore,\n\t\t\t\tcopyVariableIndices()\n\t\t\t);\n\t\t\tloopCondition = loopCondition && expr(_node.condition());\n\t\t\tbroke = broke || brokeInCurrentIteration;\n\t\t\tm_loopCheckpoints.pop();\n\t\t}\n\t\tif (bmcLoopIterations > 0)\n\t\t\tm_context.addAssertion(!loopCondition || broke);\n\t}\n\telse {\n\t\tsmtutil::Expression loopConditionOnPreviousIterations(true);\n\t\tfor (unsigned int i = 0; i < bmcLoopIterations; ++i)\n\t\t{\n\t\t\tm_loopCheckpoints.emplace();\n\t\t\tauto indicesBefore = copyVariableIndices();\n\t\t\t_node.condition().accept(*this);\n\t\t\tloopCondition = expr(_node.condition());\n\n\t\t\tauto indicesAfterCondition = copyVariableIndices();\n\n\t\t\tpushPathCondition(loopCondition);\n\t\t\t_node.body().accept(*this);\n\t\t\tpopPathCondition();\n\n\t\t\tauto brokeInCurrentIteration = mergeVariablesFromLoopCheckpoints();\n\n\t\t\t// merges indices modified when accepting loop condition that no longer holds\n\t\t\tmergeVariables(\n\t\t\t\t!loopCondition,\n\t\t\t\tindicesAfterCondition,\n\t\t\t\tcopyVariableIndices()\n\t\t\t);\n\n\t\t\t// handles breaks in previous iterations\n\t\t\t// breaks in current iterations are handled when traversing loop checkpoints\n\t\t\t// handles case when the loop condition no longer holds but bmc loop iterations still unrolls the loop\n\t\t\tmergeVariables(\n\t\t\t\tbroke || !loopConditionOnPreviousIterations,\n\t\t\t\tindicesBefore,\n\t\t\t\tcopyVariableIndices()\n\t\t\t);\n\t\t\tm_loopCheckpoints.pop();\n\t\t\tbroke = broke || brokeInCurrentIteration;\n\t\t\tloopConditionOnPreviousIterations = loopConditionOnPreviousIterations && loopCondition;\n\t\t}\n\t\tif (bmcLoopIterations > 0)\n\t\t{\n\t\t\t//after loop iterations are done, we check the loop condition last final time\n\t\t\tauto indices = copyVariableIndices();\n\t\t\tm_loopCheckpoints.emplace();\n\t\t\t_node.condition().accept(*this);\n\t\t\tm_loopCheckpoints.pop();\n\t\t\tloopCondition = expr(_node.condition());\n\t\t\t// assert that the loop is complete\n\t\t\tm_context.addAssertion(!loopCondition || broke || !loopConditionOnPreviousIterations);\n\t\t\tmergeVariables(\n\t\t\t\tbroke || !loopConditionOnPreviousIterations,\n\t\t\t\tindices,\n\t\t\t\tcopyVariableIndices()\n\t\t\t);\n\t\t}\n\t}\n\tm_loopExecutionHappened = true;\n\treturn false;\n}\n\n// Unrolls for loop\nbool BMC::visit(ForStatement const& _node)\n{\n\tif (_node.initializationExpression())\n\t\t_node.initializationExpression()->accept(*this);\n\n\tsmtutil::Expression broke(false);\n\tsmtutil::Expression forCondition(true);\n\tsmtutil::Expression forConditionOnPreviousIterations(true);\n\tunsigned int bmcLoopIterations = m_settings.bmcLoopIterations.value_or(1);\n\tfor (unsigned int i = 0; i < bmcLoopIterations; ++i)\n\t{\n\t\tauto indicesBefore = copyVariableIndices();\n\t\tm_loopCheckpoints.emplace();\n\t\tif (_node.condition())\n\t\t{\n\t\t\t_node.condition()->accept(*this);\n\t\t\t// values in loop condition might change during loop iteration\n\t\t\tforCondition = expr(*_node.condition());\n\t\t}\n\t\tauto indicesAfterCondition = copyVariableIndices();\n\n\t\tpushPathCondition(forCondition);\n\t\t_node.body().accept(*this);\n\n\t\tauto brokeInCurrentIteration = mergeVariablesFromLoopCheckpoints();\n\n\t\t// accept loop expression if there was no break\n\t\tif (_node.loopExpression())\n\t\t{\n\t\t\tauto indicesBreak = copyVariableIndices();\n\t\t\t_node.loopExpression()->accept(*this);\n\t\t\tmergeVariables(\n\t\t\t\t!brokeInCurrentIteration,\n\t\t\t\tcopyVariableIndices(),\n\t\t\t\tindicesBreak\n\t\t\t);\n\t\t}\n\t\tpopPathCondition();\n\n\t\t// merges indices modified when accepting loop condition that does no longer hold\n\t\tmergeVariables(\n\t\t\t!forCondition,\n\t\t\tindicesAfterCondition,\n\t\t\tcopyVariableIndices()\n\t\t);\n\n\t\t// handles breaks in previous iterations\n\t\t// breaks in current iterations are handled when traversing loop checkpoints\n\t\t// handles case when the loop condition no longer holds but bmc loop iterations still unrolls the loop\n\t\tmergeVariables(\n\t\t\tbroke || !forConditionOnPreviousIterations,\n\t\t\tindicesBefore,\n\t\t\tcopyVariableIndices()\n\t\t);\n\t\tm_loopCheckpoints.pop();\n\t\tbroke = broke || brokeInCurrentIteration;\n\t\tforConditionOnPreviousIterations = forConditionOnPreviousIterations && forCondition;\n\t}\n\tif (bmcLoopIterations > 0)\n\t{\n\t\t//after loop iterations are done, we check the loop condition last final time\n\t\tauto indices = copyVariableIndices();\n\t\tif (_node.condition())\n\t\t{\n\t\t\tm_loopCheckpoints.emplace();\n\t\t\t_node.condition()->accept(*this);\n\t\t\tforCondition = expr(*_node.condition());\n\t\t\tm_loopCheckpoints.pop();\n\t\t}\n\t\t// assert that the loop is complete\n\t\tm_context.addAssertion(!forCondition || broke || !forConditionOnPreviousIterations);\n\t\tmergeVariables(\n\t\t\tbroke || !forConditionOnPreviousIterations,\n\t\t\tindices,\n\t\t\tcopyVariableIndices()\n\t\t);\n\t}\n\tm_loopExecutionHappened = true;\n\treturn false;\n}\n\n// merges variables based on loop control statements\n// returns expression indicating whether there was a break in current loop unroll iteration\nsmtutil::Expression BMC::mergeVariablesFromLoopCheckpoints()\n{\n\tsmtutil::Expression continues(false);\n\tsmtutil::Expression brokeInCurrentIteration(false);\n\tfor (auto const& loopControl: m_loopCheckpoints.top())\n\t{\n\t\t// use SSAs associated with this break statement only if\n\t\t// loop didn't break or continue earlier in the iteration\n\t\t// loop condition is included in break path conditions\n\t\tmergeVariables(\n\t\t\t!brokeInCurrentIteration && !continues && loopControl.pathConditions,\n\t\t\tloopControl.variableIndices,\n\t\t\tcopyVariableIndices()\n\t\t);\n\t\tif (loopControl.kind == LoopControlKind::Break)\n\t\t\tbrokeInCurrentIteration =\n\t\t\t\tbrokeInCurrentIteration || loopControl.pathConditions;\n\t\telse if (loopControl.kind == LoopControlKind::Continue)\n\t\t\tcontinues = continues || loopControl.pathConditions;\n\t}\n\treturn brokeInCurrentIteration;\n}\n\nbool BMC::visit(TryStatement const& _tryStatement)\n{\n\tFunctionCall const* externalCall = dynamic_cast<FunctionCall const*>(&_tryStatement.externalCall());\n\tsolAssert(externalCall && externalCall->annotation().tryCall, \"\");\n\n\texternalCall->accept(*this);\n\tif (_tryStatement.successClause()->parameters())\n\t\texpressionToTupleAssignment(_tryStatement.successClause()->parameters()->parameters(), *externalCall);\n\n\tsmtutil::Expression clauseId = m_context.newVariable(\"clause_choice_\" + std::to_string(m_context.newUniqueId()), smtutil::SortProvider::uintSort);\n\tauto const& clauses = _tryStatement.clauses();\n\tm_context.addAssertion(clauseId >= 0 && clauseId < clauses.size());\n\tsolAssert(clauses[0].get() == _tryStatement.successClause(), \"First clause of TryStatement should be the success clause\");\n\tstd::vector<std::pair<VariableIndices, smtutil::Expression>> clausesVisitResults;\n\tfor (size_t i = 0; i < clauses.size(); ++i)\n\t\tclausesVisitResults.push_back(visitBranch(clauses[i].get()));\n\n\t// merge the information from all clauses\n\tsmtutil::Expression pathCondition = clausesVisitResults.front().second;\n\tauto currentIndices = clausesVisitResults[0].first;\n\tfor (size_t i = 1; i < clauses.size(); ++i)\n\t{\n\t\tmergeVariables(clauseId == i, clausesVisitResults[i].first, currentIndices);\n\t\tcurrentIndices = copyVariableIndices();\n\t\tpathCondition = pathCondition || clausesVisitResults[i].second;\n\t}\n\tsetPathCondition(pathCondition);\n\n\treturn false;\n}\n\nbool BMC::visit(Break const&)\n{\n\tLoopControl control = {\n\t\tLoopControlKind::Break,\n\t\tcurrentPathConditions(),\n\t\tcopyVariableIndices()\n\t};\n\tm_loopCheckpoints.top().emplace_back(control);\n\treturn false;\n}\n\nbool BMC::visit(Continue const&)\n{\n\tLoopControl control = {\n\t\tLoopControlKind::Continue,\n\t\tcurrentPathConditions(),\n\t\tcopyVariableIndices()\n\t};\n\tm_loopCheckpoints.top().emplace_back(control);\n\treturn false;\n}\n\nvoid BMC::endVisit(UnaryOperation const& _op)\n{\n\tSMTEncoder::endVisit(_op);\n\n\t// User-defined operators are essentially function calls.\n\tif (auto funDef = *_op.annotation().userDefinedFunction)\n\t{\n\t\tstd::vector<Expression const*> arguments;\n\t\targuments.push_back(&_op.subExpression());\n\t\t// pushCallStack and defineExpr inside createReturnedExpression should be called on the expression\n\t\t// in case of a user-defined operator call\n\t\tinlineFunctionCall(funDef, _op, std::nullopt, arguments);\n\t\treturn;\n\t}\n\n\tif (\n\t\t_op.annotation().type->category() == Type::Category::RationalNumber ||\n\t\t_op.annotation().type->category() == Type::Category::FixedPoint\n\t)\n\t\treturn;\n\n\tif (_op.getOperator() == Token::Sub && smt::isInteger(*_op.annotation().type))\n\t{\n\t\taddVerificationTarget(\n\t\t\tVerificationTargetType::Underflow,\n\t\t\texpr(_op),\n\t\t\t&_op\n\t\t);\n\t\taddVerificationTarget(\n\t\t\tVerificationTargetType::Overflow,\n\t\t\texpr(_op),\n\t\t\t&_op\n\t\t);\n\t}\n}\n\nvoid BMC::endVisit(BinaryOperation const& _op)\n{\n\tSMTEncoder::endVisit(_op);\n\n\tif (auto funDef = *_op.annotation().userDefinedFunction)\n\t{\n\t\tstd::vector<Expression const*> arguments;\n\t\targuments.push_back(&_op.leftExpression());\n\t\targuments.push_back(&_op.rightExpression());\n\n\t\t// pushCallStack and defineExpr inside createReturnedExpression should be called on the expression\n\t\t// in case of a user-defined operator call\n\t\tinlineFunctionCall(funDef, _op, std::nullopt, arguments);\n\t}\n}\n\nvoid BMC::endVisit(FunctionCall const& _funCall)\n{\n\tauto functionCallKind = *_funCall.annotation().kind;\n\n\tif (functionCallKind != FunctionCallKind::FunctionCall)\n\t{\n\t\tSMTEncoder::endVisit(_funCall);\n\t\treturn;\n\t}\n\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);\n\tswitch (funType.kind())\n\t{\n\tcase FunctionType::Kind::Assert:\n\t\tvisitAssert(_funCall);\n\t\tSMTEncoder::endVisit(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Require:\n\t\tvisitRequire(_funCall);\n\t\tSMTEncoder::endVisit(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Internal:\n\tcase FunctionType::Kind::External:\n\tcase FunctionType::Kind::DelegateCall:\n\tcase FunctionType::Kind::BareCall:\n\tcase FunctionType::Kind::BareCallCode:\n\tcase FunctionType::Kind::BareDelegateCall:\n\tcase FunctionType::Kind::BareStaticCall:\n\tcase FunctionType::Kind::Creation:\n\t\tSMTEncoder::endVisit(_funCall);\n\t\tinternalOrExternalFunctionCall(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Send:\n\tcase FunctionType::Kind::Transfer:\n\t{\n\t\tauto value = _funCall.arguments().front();\n\t\tsolAssert(value, \"\");\n\t\tsmtutil::Expression thisBalance = state().balance();\n\n\t\taddVerificationTarget(\n\t\t\tVerificationTargetType::Balance,\n\t\t\tthisBalance < expr(*value),\n\t\t\t&_funCall\n\t\t);\n\n\t\tSMTEncoder::endVisit(_funCall);\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::KECCAK256:\n\tcase FunctionType::Kind::ECRecover:\n\tcase FunctionType::Kind::SHA256:\n\tcase FunctionType::Kind::RIPEMD160:\n\tcase FunctionType::Kind::BlobHash:\n\tcase FunctionType::Kind::BlockHash:\n\tcase FunctionType::Kind::AddMod:\n\tcase FunctionType::Kind::MulMod:\n\tcase FunctionType::Kind::Unwrap:\n\tcase FunctionType::Kind::Wrap:\n\t\t[[fallthrough]];\n\tdefault:\n\t\tSMTEncoder::endVisit(_funCall);\n\t\tbreak;\n\t}\n}\n\nvoid BMC::endVisit(Return const& _return)\n{\n\tSMTEncoder::endVisit(_return);\n\tsetPathCondition(smtutil::Expression(false));\n}\n\n/// Visitor helpers.\n\nvoid BMC::visitAssert(FunctionCall const& _funCall)\n{\n\tauto const& args = _funCall.arguments();\n\tsolAssert(args.size() == 1, \"\");\n\tsolAssert(args.front()->annotation().type->category() == Type::Category::Bool, \"\");\n\taddVerificationTarget(\n\t\tVerificationTargetType::Assert,\n\t\texpr(*args.front()),\n\t\t&_funCall\n\t);\n}\n\nvoid BMC::visitRequire(FunctionCall const& _funCall)\n{\n\tauto const& args = _funCall.arguments();\n\tsolAssert(args.size() >= 1, \"\");\n\tsolAssert(args.front()->annotation().type->category() == Type::Category::Bool, \"\");\n\tcheckIfConditionIsConstant(*args.front());\n}\n\nvoid BMC::visitAddMulMod(FunctionCall const& _funCall)\n{\n\tsolAssert(_funCall.arguments().at(2), \"\");\n\taddVerificationTarget(\n\t\tVerificationTargetType::DivByZero,\n\t\texpr(*_funCall.arguments().at(2)),\n\t\t&_funCall\n\t);\n\n\tSMTEncoder::visitAddMulMod(_funCall);\n}\n\nvoid BMC::inlineFunctionCall(\n\tFunctionDefinition const* _funDef,\n\tExpression const& _callStackExpr,\n\tstd::optional<Expression const*> _boundArgumentCall,\n\tstd::vector<Expression const*> const& _arguments\n)\n{\n\tsolAssert(_funDef, \"\");\n\n\tif (visitedFunction(_funDef))\n\t{\n\t\tauto const& returnParams = _funDef->returnParameters();\n\t\tfor (auto param: returnParams)\n\t\t{\n\t\t\tm_context.newValue(*param);\n\t\t\tm_context.setUnknownValue(*param);\n\t\t}\n\t}\n\telse\n\t{\n\t\tinitializeFunctionCallParameters(*_funDef, symbolicArguments(_funDef->parameters(), _arguments, _boundArgumentCall));\n\n\t\t// The reason why we need to pushCallStack here instead of visit(FunctionDefinition)\n\t\t// is that there we don't have `_callStackExpr`.\n\t\tpushCallStack({_funDef, &_callStackExpr});\n\t\tpushPathCondition(currentPathConditions());\n\t\tauto oldChecked = std::exchange(m_checked, true);\n\t\t_funDef->accept(*this);\n\t\tm_checked = oldChecked;\n\t\tpopPathCondition();\n\t}\n\n\tcreateReturnedExpressions(_funDef, _callStackExpr);\n}\n\nvoid BMC::inlineFunctionCall(FunctionCall const& _funCall)\n{\n\tsolAssert(shouldInlineFunctionCall(_funCall, currentScopeContract(), m_currentContract), \"\");\n\n\tauto funDef = functionCallToDefinition(_funCall, currentScopeContract(), m_currentContract);\n\tExpression const* expr = &_funCall.expression();\n\tauto funType = dynamic_cast<FunctionType const*>(expr->annotation().type);\n\tstd::optional<Expression const*> boundArgumentCall =\n\t\tfunType->hasBoundFirstArgument() ? std::make_optional(expr) : std::nullopt;\n\n\tstd::vector<Expression const*> arguments;\n\tfor (auto& arg: _funCall.sortedArguments())\n\t\targuments.push_back(&(*arg));\n\n\t// pushCallStack and defineExpr inside createReturnedExpression should be called\n\t// on the FunctionCall object for the normal function call case\n\tinlineFunctionCall(funDef, _funCall, boundArgumentCall, arguments);\n}\n\nvoid BMC::internalOrExternalFunctionCall(FunctionCall const& _funCall)\n{\n\tauto const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);\n\tif (shouldInlineFunctionCall(_funCall, currentScopeContract(), m_currentContract))\n\t\tinlineFunctionCall(_funCall);\n\telse if (publicGetter(_funCall.expression()))\n\t{\n\t\t// Do nothing here.\n\t\t// The processing happens in SMT Encoder, but we need to prevent the resetting of the state variables.\n\t}\n\telse if (funType.kind() == FunctionType::Kind::Internal)\n\t\tm_unsupportedErrors.warning(\n\t\t\t5729_error,\n\t\t\t_funCall.location(),\n\t\t\t\"BMC does not yet implement this type of function call.\"\n\t\t);\n\telse if (funType.kind() == FunctionType::Kind::BareStaticCall)\n\t{\n\t\t// Do nothing here.\n\t\t// Neither storage nor balances should be modified.\n\t}\n\telse\n\t{\n\t\tm_externalFunctionCallHappened = true;\n\t\tresetStorageVariables();\n\t\tresetBalances();\n\t}\n}\n\nstd::pair<smtutil::Expression, smtutil::Expression> BMC::arithmeticOperation(\n\tToken _op,\n\tsmtutil::Expression const& _left,\n\tsmtutil::Expression const& _right,\n\tType const* _commonType,\n\tExpression const& _expression\n)\n{\n\t// Unchecked does not disable div by 0 checks.\n\tif (_op == Token::Div || _op == Token::Mod)\n\t\taddVerificationTarget(\n\t\t\tVerificationTargetType::DivByZero,\n\t\t\t_right,\n\t\t\t&_expression\n\t\t);\n\n\tauto values = SMTEncoder::arithmeticOperation(_op, _left, _right, _commonType, _expression);\n\n\tif (!m_checked)\n\t\treturn values;\n\n\tauto const* intType = dynamic_cast<IntegerType const*>(_commonType);\n\tif (!intType)\n\t\tintType = TypeProvider::uint256();\n\n\t// Mod does not need underflow/overflow checks.\n\tif (_op == Token::Mod)\n\t\treturn values;\n\n\t// The order matters here:\n\t// If _op is Div and intType is signed, we only care about overflow.\n\tif (_op == Token::Div)\n\t{\n\t\tif (intType->isSigned())\n\t\t\t// Signed division can only overflow.\n\t\t\taddVerificationTarget(VerificationTargetType::Overflow, values.second, &_expression);\n\t\telse\n\t\t\t// Unsigned division cannot underflow/overflow.\n\t\t\treturn values;\n\t}\n\telse if (intType->isSigned())\n\t{\n\t\taddVerificationTarget(VerificationTargetType::Overflow, values.second, &_expression);\n\t\taddVerificationTarget(VerificationTargetType::Underflow, values.second, &_expression);\n\t}\n\telse if (_op == Token::Sub)\n\t\taddVerificationTarget(VerificationTargetType::Underflow, values.second, &_expression);\n\telse if (_op == Token::Add || _op == Token::Mul)\n\t\taddVerificationTarget(VerificationTargetType::Overflow, values.second, &_expression);\n\telse\n\t\tsolAssert(false, \"\");\n\n\treturn values;\n}\n\nvoid BMC::reset()\n{\n\tm_externalFunctionCallHappened = false;\n\tm_loopExecutionHappened = false;\n}\n\nstd::pair<std::vector<smtutil::Expression>, std::vector<std::string>> BMC::modelExpressions()\n{\n\tstd::vector<smtutil::Expression> expressionsToEvaluate;\n\tstd::vector<std::string> expressionNames;\n\tfor (auto const& var: m_context.variables())\n\t\tif (var.first->type()->isValueType())\n\t\t{\n\t\t\texpressionsToEvaluate.emplace_back(currentValue(*var.first));\n\t\t\texpressionNames.push_back(var.first->name());\n\t\t}\n\tfor (auto const& var: m_context.globalSymbols())\n\t{\n\t\tauto const& type = var.second->type();\n\t\tif (\n\t\t\ttype->isValueType() &&\n\t\t\tsmt::smtKind(*type) != smtutil::Kind::Function\n\t\t)\n\t\t{\n\t\t\texpressionsToEvaluate.emplace_back(var.second->currentValue());\n\t\t\texpressionNames.push_back(var.first);\n\t\t}\n\t}\n\tfor (auto const& uf: m_uninterpretedTerms)\n\t\tif (uf->annotation().type->isValueType())\n\t\t{\n\t\t\texpressionsToEvaluate.emplace_back(expr(*uf));\n\t\t\tstd::string expressionName;\n\t\t\tif (uf->location().hasText())\n\t\t\t\texpressionName = m_charStreamProvider.charStream(*uf->location().sourceName).text(\n\t\t\t\t\tuf->location()\n\t\t\t\t);\n\t\t\texpressionNames.push_back(std::move(expressionName));\n\t\t}\n\n\treturn {expressionsToEvaluate, expressionNames};\n}\n\n/// Verification targets.\n\nstd::string BMC::targetDescription(BMCVerificationTarget const& _target)\n{\n\tif (\n\t\t_target.type == VerificationTargetType::Underflow ||\n\t\t_target.type == VerificationTargetType::Overflow\n\t)\n\t{\n\t\tauto const* intType = dynamic_cast<IntegerType const*>(_target.expression->annotation().type);\n\t\tif (!intType)\n\t\t\tintType = TypeProvider::uint256();\n\n\t\tif (_target.type == VerificationTargetType::Underflow)\n\t\t\treturn \"Underflow (resulting value less than \" + formatNumberReadable(intType->minValue()) + \")\";\n\t\treturn \"Overflow (resulting value larger than \" + formatNumberReadable(intType->maxValue()) + \")\";\n\t}\n\telse if (_target.type == VerificationTargetType::DivByZero)\n\t\treturn \"Division by zero\";\n\telse if (_target.type == VerificationTargetType::Assert)\n\t\treturn \"Assertion violation\";\n\telse if (_target.type == VerificationTargetType::Balance)\n\t\treturn \"Insufficient funds\";\n\tsolAssert(false);\n}\n\nvoid BMC::checkVerificationTargets()\n{\n\tfor (auto& target: m_verificationTargets)\n\t\tcheckVerificationTarget(target);\n}\n\nvoid BMC::checkVerificationTarget(BMCVerificationTarget& _target)\n{\n\tif (\n\t\tm_solvedTargets.count(_target.expression) &&\n\t\tm_solvedTargets.at(_target.expression).count(_target.type)\n\t)\n\t\treturn;\n\n\tswitch (_target.type)\n\t{\n\t\tcase VerificationTargetType::Underflow:\n\t\t\tcheckUnderflow(_target);\n\t\t\tbreak;\n\t\tcase VerificationTargetType::Overflow:\n\t\t\tcheckOverflow(_target);\n\t\t\tbreak;\n\t\tcase VerificationTargetType::DivByZero:\n\t\t\tcheckDivByZero(_target);\n\t\t\tbreak;\n\t\tcase VerificationTargetType::Balance:\n\t\t\tcheckBalance(_target);\n\t\t\tbreak;\n\t\tcase VerificationTargetType::Assert:\n\t\t\tcheckAssert(_target);\n\t\t\tbreak;\n\t\tcase VerificationTargetType::ConstantCondition:\n\t\t\tsmtAssert(false, \"Checks for constant condition are handled separately\");\n\t\tdefault:\n\t\t\tsmtAssert(false);\n\t}\n}\n\nvoid BMC::checkIfConditionIsConstant(Expression const& _condition)\n{\n\tif (\n\t\t!m_settings.targets.has(VerificationTargetType::ConstantCondition) ||\n\t\t(m_currentContract && !shouldEncode(*m_currentContract))\n\t)\n\t\treturn;\n\n\t// We ignore called functions here because they have specific input values.\n\t// Also, expressions inside loop can have different values in different iterations.\n\tif (!isRootFunction() || isInsideLoop())\n\t\treturn;\n\n\t// Do not check for const-ness if this is a literal.\n\tif (dynamic_cast<Literal const*>(&_condition))\n\t\treturn;\n\n\tauto [canBeTrue, canBeFalse] = checkBooleanNotConstant(currentPathConditions() && m_context.assertions(), expr(_condition));\n\n\t// Report based on the result of the checks\n\tif (canBeTrue == CheckResult::ERROR || canBeFalse == CheckResult::ERROR)\n\t\tm_errorReporter.warning(8592_error, _condition.location(), \"BMC: Error trying to invoke SMT solver.\");\n\telse if (canBeTrue == CheckResult::CONFLICTING || canBeFalse == CheckResult::CONFLICTING)\n\t\tm_errorReporter.warning(3356_error, _condition.location(), \"BMC: At least two SMT solvers provided conflicting answers. Results might not be sound.\");\n\telse if (canBeTrue == CheckResult::UNKNOWN || canBeFalse == CheckResult::UNKNOWN)\n\t{\n\t\t// Not enough information to make definite claims.\n\t}\n\telse if (canBeTrue == CheckResult::SATISFIABLE && canBeFalse == CheckResult::SATISFIABLE)\n\t{\n\t\t// Condition can be both true and false for some program runs.\n\t}\n\n\telse if (canBeTrue == CheckResult::UNSATISFIABLE && canBeFalse == CheckResult::UNSATISFIABLE)\n\t\tm_errorReporter.warning(2512_error, _condition.location(), \"BMC: Condition unreachable.\", SMTEncoder::callStackMessage(m_callStack));\n\telse\n\t{\n\t\tstd::string description;\n\t\tif (canBeFalse == smtutil::CheckResult::UNSATISFIABLE)\n\t\t{\n\t\t\tsmtAssert(canBeTrue == smtutil::CheckResult::SATISFIABLE);\n\t\t\tdescription = \"BMC: Condition is always true.\";\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsmtAssert(canBeTrue == smtutil::CheckResult::UNSATISFIABLE);\n\t\t\tsmtAssert(canBeFalse == smtutil::CheckResult::SATISFIABLE);\n\t\t\tdescription = \"BMC: Condition is always false.\";\n\t\t}\n\t\tm_errorReporter.warning(\n\t\t\t6838_error,\n\t\t\t_condition.location(),\n\t\t\tdescription,\n\t\t\tSMTEncoder::callStackMessage(m_callStack)\n\t\t);\n\t}\n\n}\n\nvoid BMC::checkUnderflow(BMCVerificationTarget& _target)\n{\n\tsolAssert(\n\t\t_target.type == VerificationTargetType::Underflow,\n\t\t\"\"\n\t);\n\n\tauto const* intType = dynamic_cast<IntegerType const*>(_target.expression->annotation().type);\n\tif (!intType)\n\t\tintType = TypeProvider::uint256();\n\n\tcheckCondition(\n\t\t_target,\n\t\t_target.constraints && _target.value < smt::minValue(*intType),\n\t\t_target.callStack,\n\t\t_target.modelExpressions,\n\t\t_target.expression->location(),\n\t\t4144_error,\n\t\t8312_error,\n\t\t\"<result>\",\n\t\t&_target.value\n\t);\n}\n\nvoid BMC::checkOverflow(BMCVerificationTarget& _target)\n{\n\tsolAssert(\n\t\t_target.type == VerificationTargetType::Overflow,\n\t\t\"\"\n\t);\n\n\tauto const* intType = dynamic_cast<IntegerType const*>(_target.expression->annotation().type);\n\tif (!intType)\n\t\tintType = TypeProvider::uint256();\n\n\tcheckCondition(\n\t\t_target,\n\t\t_target.constraints && _target.value > smt::maxValue(*intType),\n\t\t_target.callStack,\n\t\t_target.modelExpressions,\n\t\t_target.expression->location(),\n\t\t2661_error,\n\t\t8065_error,\n\t\t\"<result>\",\n\t\t&_target.value\n\t);\n}\n\nvoid BMC::checkDivByZero(BMCVerificationTarget& _target)\n{\n\tsolAssert(_target.type == VerificationTargetType::DivByZero, \"\");\n\n\tcheckCondition(\n\t\t_target,\n\t\t_target.constraints && (_target.value == 0),\n\t\t_target.callStack,\n\t\t_target.modelExpressions,\n\t\t_target.expression->location(),\n\t\t3046_error,\n\t\t5272_error,\n\t\t\"<result>\",\n\t\t&_target.value\n\t);\n}\n\nvoid BMC::checkBalance(BMCVerificationTarget& _target)\n{\n\tsolAssert(_target.type == VerificationTargetType::Balance, \"\");\n\n\tcheckCondition(\n\t\t_target,\n\t\t_target.constraints && _target.value,\n\t\t_target.callStack,\n\t\t_target.modelExpressions,\n\t\t_target.expression->location(),\n\t\t1236_error,\n\t\t4010_error,\n\t\t\"address(this).balance\"\n\t);\n}\n\nvoid BMC::checkAssert(BMCVerificationTarget& _target)\n{\n\tsolAssert(_target.type == VerificationTargetType::Assert, \"\");\n\n\tcheckCondition(\n\t\t_target,\n\t\t_target.constraints && !_target.value,\n\t\t_target.callStack,\n\t\t_target.modelExpressions,\n\t\t_target.expression->location(),\n\t\t4661_error,\n\t\t7812_error\n\t);\n}\n\nvoid BMC::addVerificationTarget(\n\tVerificationTargetType _type,\n\tsmtutil::Expression const& _value,\n\tExpression const* _expression\n)\n{\n\tsmtAssert(_type != VerificationTargetType::ConstantCondition, \"Checks for constant condition are handled separately\");\n\tif (!m_settings.targets.has(_type) || (m_currentContract && !shouldAnalyzeVerificationTargetsFor(*m_currentContract)))\n\t\treturn;\n\n\tBMCVerificationTarget target{\n\t\t{\n\t\t\t_type,\n\t\t\t_value,\n\t\t\tcurrentPathConditions() && m_context.assertions()\n\t\t},\n\t\t_expression,\n\t\tm_callStack,\n\t\tmodelExpressions()\n\t};\n\tm_verificationTargets.emplace_back(std::move(target));\n}\n\n/// Solving.\n\nvoid BMC::checkCondition(\n\tBMCVerificationTarget const& _target,\n\tsmtutil::Expression _condition,\n\tstd::vector<SMTEncoder::CallStackEntry> const& _callStack,\n\tstd::pair<std::vector<smtutil::Expression>, std::vector<std::string>> const& _modelExpressions,\n\tSourceLocation const& _location,\n\tErrorId _errorHappens,\n\tErrorId _errorMightHappen,\n\tstd::string const& _additionalValueName,\n\tsmtutil::Expression const* _additionalValue\n)\n{\n\tm_interface->push();\n\tm_interface->addAssertion(_condition);\n\n\tstd::vector<smtutil::Expression> expressionsToEvaluate;\n\tstd::vector<std::string> expressionNames;\n\ttie(expressionsToEvaluate, expressionNames) = _modelExpressions;\n\tif (!_callStack.empty())\n\t\tif (_additionalValue)\n\t\t{\n\t\t\texpressionsToEvaluate.emplace_back(*_additionalValue);\n\t\t\texpressionNames.push_back(_additionalValueName);\n\t\t}\n\tsmtutil::CheckResult result;\n\tstd::vector<std::string> values;\n\ttie(result, values) = checkSatisfiableAndGenerateModel(expressionsToEvaluate);\n\n\tstd::string extraComment = SMTEncoder::extraComment();\n\tif (m_loopExecutionHappened)\n\t\textraComment +=\n\t\t\t\"False negatives are possible when unrolling loops.\\n\"\n\t\t\t\"This is due to the possibility that the BMC loop iteration setting is\"\n\t\t\t\" smaller than the actual number of iterations needed to complete a loop.\";\n\tif (m_externalFunctionCallHappened)\n\t\textraComment +=\n\t\t\t\"\\nNote that external function calls are not inlined,\"\n\t\t\t\" even if the source code of the function is available.\"\n\t\t\t\" This is due to the possibility that the actual called contract\"\n\t\t\t\" has the same ABI but implements the function differently.\";\n\n\tSecondarySourceLocation secondaryLocation{};\n\tsecondaryLocation.append(extraComment, SourceLocation{});\n\n\tswitch (result)\n\t{\n\tcase smtutil::CheckResult::SATISFIABLE:\n\t{\n\t\tsolAssert(!_callStack.empty(), \"\");\n\t\tstd::ostringstream message;\n\t\tmessage << \"BMC: \" << targetDescription(_target) << \" happens here.\";\n\n\t\tstd::ostringstream modelMessage;\n\t\t// Sometimes models have complex smtlib2 expressions that SMTLib2Interface fails to parse.\n\t\tif (values.size() == expressionNames.size())\n\t\t{\n\t\t\tmodelMessage << \"Counterexample:\\n\";\n\t\t\tstd::map<std::string, std::string> sortedModel;\n\t\t\tfor (size_t i = 0; i < values.size(); ++i)\n\t\t\t\tif (expressionsToEvaluate.at(i).name != values.at(i))\n\t\t\t\t\tsortedModel[expressionNames.at(i)] = values.at(i);\n\n\t\t\tfor (auto const& eval: sortedModel)\n\t\t\t\tmodelMessage << \"  \" << eval.first << \" = \" << eval.second << \"\\n\";\n\t\t}\n\n\t\tm_errorReporter.warning(\n\t\t\t_errorHappens,\n\t\t\t_location,\n\t\t\tmessage.str(),\n\t\t\tSecondarySourceLocation().append(modelMessage.str(), SourceLocation{})\n\t\t\t.append(SMTEncoder::callStackMessage(_callStack))\n\t\t\t.append(std::move(secondaryLocation))\n\t\t);\n\t\tbreak;\n\t}\n\tcase smtutil::CheckResult::UNSATISFIABLE:\n\t{\n\t\tm_safeTargets[_target.expression].insert(_target);\n\t\tbreak;\n\t}\n\tcase smtutil::CheckResult::UNKNOWN:\n\t{\n\t\t++m_unprovedAmt;\n\t\tif (m_settings.showUnproved)\n\t\t\tm_errorReporter.warning(_errorMightHappen, _location, \"BMC: \" + targetDescription(_target) + \" might happen here.\", secondaryLocation);\n\t\tbreak;\n\t}\n\tcase smtutil::CheckResult::CONFLICTING:\n\t\tm_errorReporter.warning(1584_error, _location, \"BMC: At least two SMT solvers provided conflicting answers. Results might not be sound.\");\n\t\tbreak;\n\tcase smtutil::CheckResult::ERROR:\n\t\tm_errorReporter.warning(1823_error, _location, \"BMC: Error during interaction with the SMT solver.\");\n\t\tbreak;\n\t}\n\n\tm_interface->pop();\n}\n\nBMC::ConstantExpressionCheckResult BMC::checkBooleanNotConstant(\n\tsmtutil::Expression const& _constraints,\n\tsmtutil::Expression const& _condition\n)\n{\n\tm_interface->push();\n\tm_interface->addAssertion(_constraints && _condition);\n\tauto positiveResult = checkSatisfiable();\n\tm_interface->pop();\n\n\tm_interface->push();\n\tm_interface->addAssertion(_constraints && !_condition);\n\tauto negatedResult = checkSatisfiable();\n\tm_interface->pop();\n\n\treturn {.canBeTrue = positiveResult, .canBeFalse = negatedResult};\n}\n\nstd::pair<smtutil::CheckResult, std::vector<std::string>>\nBMC::checkSatisfiableAndGenerateModel(std::vector<smtutil::Expression> const& _expressionsToEvaluate)\n{\n\tsmtutil::CheckResult result;\n\tstd::vector<std::string> values;\n\ttry\n\t{\n\t\tif (m_settings.printQuery)\n\t\t{\n\t\t\tauto portfolio = dynamic_cast<smtutil::SMTPortfolio*>(m_interface.get());\n\t\t\tstd::string smtlibCode = portfolio->dumpQuery(_expressionsToEvaluate);\n\t\t\tm_errorReporter.info(\n\t\t\t\t6240_error,\n\t\t\t\t\"BMC: Requested query:\\n\" + smtlibCode\n\t\t\t);\n\t\t\tresult = CheckResult::UNKNOWN;\n\t\t}\n\t\telse\n\t\t\ttie(result, values) = m_interface->check(_expressionsToEvaluate);\n\t}\n\tcatch (smtutil::SolverError const& _e)\n\t{\n\t\tstd::string description(\"BMC: Error querying SMT solver\");\n\t\tif (_e.comment())\n\t\t\tdescription += \": \" + *_e.comment();\n\t\tm_errorReporter.warning(8140_error, description);\n\t\tresult = smtutil::CheckResult::ERROR;\n\t}\n\n\tfor (std::string& value: values)\n\t{\n\t\ttry\n\t\t{\n\t\t\t// Parse and re-format nicely\n\t\t\tvalue = formatNumberReadable(bigint(value));\n\t\t}\n\t\tcatch (...) { }\n\t}\n\n\treturn make_pair(result, values);\n}\n\nsmtutil::CheckResult BMC::checkSatisfiable()\n{\n\treturn checkSatisfiableAndGenerateModel({}).first;\n}\n\nvoid BMC::assignment(smt::SymbolicVariable& _symVar, smtutil::Expression const& _value)\n{\n\tauto oldVar = _symVar.currentValue();\n\tauto newVar = _symVar.increaseIndex();\n\tm_context.addAssertion(smtutil::Expression::ite(\n\t\tcurrentPathConditions(),\n\t\tnewVar == _value,\n\t\tnewVar == oldVar\n\t));\n}\n\nbool BMC::isInsideLoop() const\n{\n\treturn !m_loopCheckpoints.empty();\n}\n"
  },
  {
    "path": "libsolidity/formal/BMC.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Class that implements an SMT-based Bounded Model Checker (BMC).\n * Traverses the AST such that:\n * - Loops are unrolled\n * - Internal function calls are inlined\n * Creates verification targets for:\n * - Underflow/Overflow\n * - Constant conditions\n * - Assertions\n */\n\n#pragma once\n\n\n#include <libsolidity/formal/EncodingContext.h>\n#include <libsolidity/formal/ModelCheckerSettings.h>\n#include <libsolidity/formal/SMTEncoder.h>\n\n#include <libsolidity/interface/ReadFile.h>\n\n#include <libsmtutil/BMCSolverInterface.h>\n#include <liblangutil/UniqueErrorReporter.h>\n\n#include <set>\n#include <string>\n#include <vector>\n#include <stack>\n\nusing solidity::util::h256;\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\nstruct ErrorId;\nstruct SourceLocation;\n}\n\nnamespace solidity::frontend\n{\n\nclass BMC: public SMTEncoder\n{\npublic:\n\tBMC(\n\t\tsmt::EncodingContext& _context,\n\t\tlangutil::UniqueErrorReporter& _errorReporter,\n\t\tlangutil::UniqueErrorReporter& _unsupportedErrorReporter,\n\t\tlangutil::ErrorReporter& _provedSafeReporter,\n\t\tstd::map<h256, std::string> const& _smtlib2Responses,\n\t\tReadCallback::Callback const& _smtCallback,\n\t\tModelCheckerSettings _settings,\n\t\tlangutil::CharStreamProvider const& _charStreamProvider\n\t);\n\n\tvoid analyze(SourceUnit const& _sources, std::map<ASTNode const*, std::set<VerificationTargetType>, smt::EncodingContext::IdCompare> _solvedTargets);\n\n\t/// This is used if the SMT solver is not directly linked into this binary.\n\t/// @returns a list of inputs to the SMT solver that were not part of the argument to\n\t/// the constructor.\n\tstd::vector<std::string> unhandledQueries() { return m_interface->unhandledQueries(); }\n\n\t/// @returns true if _funCall should be inlined, otherwise false.\n\t/// @param _scopeContract The contract that contains the current function being analyzed.\n\t/// @param _contextContract The most derived contract, currently being analyzed.\n\tstatic bool shouldInlineFunctionCall(\n\t\tFunctionCall const& _funCall,\n\t\tContractDefinition const* _scopeContract,\n\t\tContractDefinition const* _contextContract\n\t);\n\nprivate:\n\t/// AST visitors.\n\t/// Only nodes that lead to verification targets being built\n\t/// or checked are visited.\n\t//@{\n\tbool visit(ContractDefinition const& _node) override;\n\tvoid endVisit(ContractDefinition const& _node) override;\n\tbool visit(FunctionDefinition const& _node) override;\n\tvoid endVisit(FunctionDefinition const& _node) override;\n\tbool visit(IfStatement const& _node) override;\n\tbool visit(Conditional const& _node) override;\n\tbool visit(WhileStatement const& _node) override;\n\tbool visit(ForStatement const& _node) override;\n\tvoid endVisit(UnaryOperation const& _node) override;\n\tvoid endVisit(BinaryOperation const& _node) override;\n\tvoid endVisit(FunctionCall const& _node) override;\n\tvoid endVisit(Return const& _node) override;\n\tbool visit(TryStatement const& _node) override;\n\tbool visit(Break const& _node) override;\n\tbool visit(Continue const& _node) override;\n\t//@}\n\n\t/// Visitor helpers.\n\t//@{\n\tvoid visitAssert(FunctionCall const& _funCall);\n\tvoid visitRequire(FunctionCall const& _funCall);\n\tvoid visitAddMulMod(FunctionCall const& _funCall) override;\n\tvoid assignment(smt::SymbolicVariable& _symVar, smtutil::Expression const& _value) override;\n\t/// Visits the FunctionDefinition of the called function\n\t/// if available and inlines the return value.\n\tvoid inlineFunctionCall(FunctionCall const& _funCall);\n\tvoid inlineFunctionCall(\n\t\tFunctionDefinition const* _funDef,\n\t\tExpression const& _callStackExpr,\n\t\tstd::optional<Expression const*> _calledExpr,\n\t\tstd::vector<Expression const*> const& _arguments\n\t);\n\t/// Inlines if the function call is internal or external to `this`.\n\t/// Erases knowledge about state variables if external.\n\tvoid internalOrExternalFunctionCall(FunctionCall const& _funCall);\n\n\t/// Creates underflow/overflow verification targets.\n\tstd::pair<smtutil::Expression, smtutil::Expression> arithmeticOperation(\n\t\tToken _op,\n\t\tsmtutil::Expression const& _left,\n\t\tsmtutil::Expression const& _right,\n\t\tType const* _commonType,\n\t\tExpression const& _expression\n\t) override;\n\n\tvoid reset();\n\n\tstd::pair<std::vector<smtutil::Expression>, std::vector<std::string>> modelExpressions();\n\t//@}\n\n\t/// Verification targets.\n\t//@{\n\tstruct BMCVerificationTarget: VerificationTarget\n\t{\n\t\tExpression const* expression;\n\t\tstd::vector<CallStackEntry> callStack;\n\t\tstd::pair<std::vector<smtutil::Expression>, std::vector<std::string>> modelExpressions;\n\n\t\tfriend bool operator<(BMCVerificationTarget const& _a, BMCVerificationTarget const& _b)\n\t\t{\n\t\t\tif (_a.expression->id() == _b.expression->id())\n\t\t\t\treturn _a.type < _b.type;\n\t\t\telse\n\t\t\t\treturn _a.expression->id() < _b.expression->id();\n\t\t}\n\t};\n\n\tstd::string targetDescription(BMCVerificationTarget const& _target);\n\n\tvoid checkVerificationTargets();\n\tvoid checkVerificationTarget(BMCVerificationTarget& _target);\n\tvoid checkUnderflow(BMCVerificationTarget& _target);\n\tvoid checkOverflow(BMCVerificationTarget& _target);\n\tvoid checkDivByZero(BMCVerificationTarget& _target);\n\tvoid checkBalance(BMCVerificationTarget& _target);\n\tvoid checkAssert(BMCVerificationTarget& _target);\n\tvoid addVerificationTarget(\n\t\tVerificationTargetType _type,\n\t\tsmtutil::Expression const& _value,\n\t\tExpression const* _expression\n\t);\n\t/// Special handling of ConstantCondition verification target.\n\t/// The target is checked immediately, unlike the other targets that are queued for checking at the end of analysis.\n\tvoid checkIfConditionIsConstant(Expression const& _condition);\n\t//@}\n\n\n\n\t/// Solver related.\n\t//@{\n\t/// Check that a condition can be satisfied.\n\tvoid checkCondition(\n\t\tBMCVerificationTarget const& _target,\n\t\tsmtutil::Expression _condition,\n\t\tstd::vector<CallStackEntry> const& _callStack,\n\t\tstd::pair<std::vector<smtutil::Expression>, std::vector<std::string>> const& _modelExpressions,\n\t\tlangutil::SourceLocation const& _location,\n\t\tlangutil::ErrorId _errorHappens,\n\t\tlangutil::ErrorId _errorMightHappen,\n\t\tstd::string const& _additionalValueName = \"\",\n\t\tsmtutil::Expression const* _additionalValue = nullptr\n\t);\n\n\tstruct ConstantExpressionCheckResult\n\t{\n\t\tsmtutil::CheckResult canBeTrue;\n\t\tsmtutil::CheckResult canBeFalse;\n\t};\n\n\t/// Checks whether the given boolean condition is either true or always false under given constraints.\n\t/// Returns the results from the solver for these two checks.\n\tConstantExpressionCheckResult checkBooleanNotConstant(\n\t\tsmtutil::Expression const& _constraints,\n\t\tsmtutil::Expression const& _condition\n\t);\n\tstd::pair<smtutil::CheckResult, std::vector<std::string>>\n\tcheckSatisfiableAndGenerateModel(std::vector<smtutil::Expression> const& _expressionsToEvaluate);\n\n\tsmtutil::CheckResult checkSatisfiable();\n\t//@}\n\n\tsmtutil::Expression mergeVariablesFromLoopCheckpoints();\n\tbool isInsideLoop() const;\n\n\tstd::unique_ptr<smtutil::BMCSolverInterface> m_interface;\n\n\t/// Flags used for better warning messages.\n\tbool m_loopExecutionHappened = false;\n\tbool m_externalFunctionCallHappened = false;\n\n\tstd::vector<BMCVerificationTarget> m_verificationTargets;\n\n\t/// Targets proved safe by this engine.\n\tstd::map<ASTNode const*, std::set<BMCVerificationTarget>, smt::EncodingContext::IdCompare> m_safeTargets;\n\n\t/// Targets that were already proven before this engine started.\n\tstd::map<ASTNode const*, std::set<VerificationTargetType>, smt::EncodingContext::IdCompare> m_solvedTargets;\n\n\t/// Number of verification conditions that could not be proved.\n\tsize_t m_unprovedAmt = 0;\n\n\t/// Loop analysis\n\t//@{\n\tenum class LoopControlKind\n\t{\n\t\tContinue,\n\t\tBreak\n\t};\n\n\t/// Current path conditions and SSA indices for break or continue statement\n\tstruct LoopControl {\n\t\tLoopControlKind kind;\n\t\tsmtutil::Expression pathConditions;\n\t\tVariableIndices variableIndices;\n\t};\n\n\t/// Loop control statements for every loop\n\tstd::stack<std::vector<LoopControl>> m_loopCheckpoints;\n\t//@}\n};\n}\n"
  },
  {
    "path": "libsolidity/formal/CHC.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/CHC.h>\n\n#include <libsolidity/formal/ArraySlicePredicate.h>\n#include <libsolidity/formal/ExpressionFormatter.h>\n#include <libsolidity/formal/EldaricaCHCSmtLib2Interface.h>\n#include <libsolidity/formal/ModelChecker.h>\n#include <libsolidity/formal/PredicateInstance.h>\n#include <libsolidity/formal/PredicateSort.h>\n#include <libsolidity/formal/SymbolicTypes.h>\n#include <libsolidity/formal/Z3CHCSmtLib2Interface.h>\n\n#include <libsolidity/ast/TypeProvider.h>\n\n#include <libsmtutil/CHCSmtLib2Interface.h>\n#include <liblangutil/CharStreamProvider.h>\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/StringUtils.h>\n\n#include <range/v3/algorithm/for_each.hpp>\n#include <range/v3/algorithm/none_of.hpp>\n#include <range/v3/view.hpp>\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/reverse.hpp>\n\n#include <charconv>\n#include <queue>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\nusing namespace solidity::smtutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::smt;\n\nCHC::CHC(\n\tEncodingContext& _context,\n\tUniqueErrorReporter& _errorReporter,\n\tUniqueErrorReporter& _unsupportedErrorReporter,\n\tErrorReporter& _provedSafeReporter,\n\tstd::map<util::h256, std::string> const& _smtlib2Responses,\n\tReadCallback::Callback const& _smtCallback,\n\tModelCheckerSettings _settings,\n\tCharStreamProvider const& _charStreamProvider\n):\n\tSMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _provedSafeReporter, _charStreamProvider),\n\tm_smtlib2Responses(_smtlib2Responses),\n\tm_smtCallback(_smtCallback)\n{}\n\nvoid CHC::analyze(SourceUnit const& _source)\n{\n\t// At this point every enabled solver is available.\n\tif (!m_settings.solvers.eld && !m_settings.solvers.smtlib2 && !m_settings.solvers.z3)\n\t{\n\t\tm_errorReporter.warning(\n\t\t\t7649_error,\n\t\t\tSourceLocation(),\n\t\t\t\"CHC analysis was not possible since no Horn solver was found and enabled.\"\n\t\t\t\" The accepted solvers for CHC are Eldarica and z3.\"\n\t\t);\n\t\treturn;\n\t}\n\n\tif (m_settings.solvers.eld && m_settings.solvers.z3)\n\t\tm_errorReporter.warning(\n\t\t\t5798_error,\n\t\t\tSourceLocation(),\n\t\t\t\"Multiple Horn solvers were selected for CHC.\"\n\t\t\t\" CHC only supports one solver at a time, therefore only z3 will be used.\"\n\t\t\t\" If you wish to use Eldarica, please enable Eldarica only.\"\n\t\t);\n\n\tif (!shouldAnalyzeVerificationTargetsFor(_source))\n\t\treturn;\n\n\tresetSourceAnalysis();\n\n\tauto sources = sourceDependencies(_source);\n\tcollectFreeFunctions(sources);\n\tcreateFreeConstants(sources);\n\tstate().prepareForSourceUnit(_source, encodeExternalCallsAsTrusted());\n\n\tfor (auto const* source: sources)\n\t\tdefineInterfacesAndSummaries(*source);\n\tfor (auto const* source: sources)\n\t\tsource->accept(*this);\n\n\tcheckVerificationTargets();\n\n\tbool ranSolver = true;\n\t// If ranSolver is true here it's because an SMT solver callback was\n\t// actually given and the queries were solved,\n\t// or Eldarica was chosen and was present in the system.\n\tif (auto const* smtLibInterface = dynamic_cast<CHCSmtLib2Interface const*>(m_interface.get()))\n\t\tranSolver = smtLibInterface->unhandledQueries().empty();\n\tif (!ranSolver)\n\t\tm_errorReporter.warning(\n\t\t\t3996_error,\n\t\t\tSourceLocation(),\n\t\t\t\"CHC analysis was not possible. No Horn solver was available.\"\n\t\t\t\" None of the installed solvers was enabled.\"\n\t\t);\n}\n\nstd::vector<std::string> CHC::unhandledQueries() const\n{\n\tif (auto smtlib2 = dynamic_cast<CHCSmtLib2Interface const*>(m_interface.get()))\n\t\treturn smtlib2->unhandledQueries();\n\n\treturn {};\n}\n\nbool CHC::visit(ContractDefinition const& _contract)\n{\n\tif (!shouldEncode(_contract))\n\t\treturn false;\n\n\t// Raises UnimplementedFeatureError in the presence of transient storage variables\n\tTransientDataLocationChecker checker(_contract);\n\n\tresetContractAnalysis();\n\tinitContract(_contract);\n\tclearIndices(&_contract);\n\n\tm_scopes.push_back(&_contract);\n\n\tm_stateVariables = SMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract);\n\tsolAssert(m_currentContract, \"\");\n\n\tSMTEncoder::visit(_contract);\n\treturn false;\n}\n\nvoid CHC::endVisit(ContractDefinition const& _contract)\n{\n\tif (!shouldEncode(_contract))\n\t\treturn;\n\n\tfor (auto base: _contract.annotation().linearizedBaseContracts)\n\t{\n\t\tif (auto constructor = base->constructor())\n\t\t\tconstructor->accept(*this);\n\t\tdefineContractInitializer(*base, _contract);\n\t}\n\n\tauto const& entry = *createConstructorBlock(_contract, \"implicit_constructor_entry\");\n\n\t// In case constructors use uninitialized state variables,\n\t// they need to be zeroed.\n\t// This is not part of `initialConstraints` because it's only true here,\n\t// at the beginning of the deployment routine.\n\tsmtutil::Expression zeroes(true);\n\tfor (auto var: stateVariablesIncludingInheritedAndPrivate(_contract))\n\t\tzeroes = zeroes && currentValue(*var) == smt::zeroValue(var->type());\n\n\tsmtutil::Expression newAddress = encodeExternalCallsAsTrusted() ?\n\t\t!state().addressActive(state().thisAddress()) :\n\t\tsmtutil::Expression(true);\n\n\t// The contract's address might already have funds before deployment,\n\t// so the balance must be at least `msg.value`, but not equals.\n\tauto initialBalanceConstraint = state().balance(state().thisAddress()) >= state().txMember(\"msg.value\");\n\taddRule(smtutil::Expression::implies(\n\t\tinitialConstraints(_contract) && zeroes && newAddress && initialBalanceConstraint,\n\t\tpredicate(entry)\n\t), entry.functor().name);\n\n\tsetCurrentBlock(entry);\n\n\tif (encodeExternalCallsAsTrusted())\n\t{\n\t\tauto const& entryAfterAddress = *createConstructorBlock(_contract, \"implicit_constructor_entry_after_address\");\n\t\tstate().setAddressActive(state().thisAddress(), true);\n\n\t\tconnectBlocks(m_currentBlock, predicate(entryAfterAddress));\n\t\tsetCurrentBlock(entryAfterAddress);\n\t}\n\n\tsolAssert(!m_errorDest, \"\");\n\tm_errorDest = m_constructorSummaries.at(&_contract);\n\t// We need to evaluate the base constructor calls (arguments) from derived -> base\n\tauto baseArgs = baseArguments(_contract);\n\tfor (auto base: _contract.annotation().linearizedBaseContracts)\n\t\tif (base != &_contract)\n\t\t{\n\t\t\tm_callGraph[&_contract].insert(base);\n\n\t\t\tauto baseConstructor = base->constructor();\n\t\t\tif (baseConstructor && baseArgs.count(base))\n\t\t\t{\n\t\t\t\tstd::vector<ASTPointer<Expression>> const& args = baseArgs.at(base);\n\t\t\t\tauto const& params = baseConstructor->parameters();\n\t\t\t\tsolAssert(params.size() == args.size(), \"\");\n\t\t\t\tfor (unsigned i = 0; i < params.size(); ++i)\n\t\t\t\t{\n\t\t\t\t\targs.at(i)->accept(*this);\n\t\t\t\t\tif (params.at(i))\n\t\t\t\t\t{\n\t\t\t\t\t\tsolAssert(m_context.knownVariable(*params.at(i)), \"\");\n\t\t\t\t\t\tm_context.addAssertion(currentValue(*params.at(i)) == expr(*args.at(i), params.at(i)->type()));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\tm_errorDest = nullptr;\n\t// Then call initializer_Base from base -> derived\n\tfor (auto base: _contract.annotation().linearizedBaseContracts | ranges::views::reverse)\n\t{\n\t\terrorFlag().increaseIndex();\n\t\tm_context.addAssertion(smt::constructorCall(*m_contractInitializers.at(&_contract).at(base), m_context));\n\t\tconnectBlocks(m_currentBlock, summary(_contract), errorFlag().currentValue() > 0);\n\t\tm_context.addAssertion(errorFlag().currentValue() == 0);\n\t}\n\n\tif (encodeExternalCallsAsTrusted())\n\t\tstate().writeStateVars(_contract, state().thisAddress());\n\n\tconnectBlocks(m_currentBlock, summary(_contract));\n\n\tsetCurrentBlock(*m_constructorSummaries.at(&_contract));\n\n\tsolAssert(&_contract == m_currentContract, \"\");\n\tsmtAssert(shouldEncode(_contract));\n\tauto constructor = _contract.constructor();\n\tauto txConstraints = state().txTypeConstraints();\n\tif (!constructor || !constructor->isPayable())\n\t\ttxConstraints = txConstraints && state().txNonPayableConstraint();\n\tconnectBlocks(m_currentBlock, interface(), txConstraints && errorFlag().currentValue() == 0);\n\tif (shouldAnalyzeVerificationTargetsFor(_contract))\n\t\tm_queryPlaceholders[&_contract].push_back({txConstraints, errorFlag().currentValue(), m_currentBlock});\n\n\tsolAssert(m_scopes.back() == &_contract, \"\");\n\tm_scopes.pop_back();\n\n\tSMTEncoder::endVisit(_contract);\n}\n\nbool CHC::visit(FunctionDefinition const& _function)\n{\n\t// Free functions need to be visited in the context of a contract.\n\tif (!m_currentContract)\n\t\treturn false;\n\n\tif (\n\t\t!_function.isImplemented() ||\n\t\tabstractAsNondet(_function)\n\t)\n\t{\n\t\tsmtutil::Expression conj(true);\n\t\tif (\n\t\t\t_function.stateMutability() == StateMutability::Pure ||\n\t\t\t_function.stateMutability() == StateMutability::View\n\t\t)\n\t\t\tconj = conj && currentEqualInitialVarsConstraints(stateVariablesIncludingInheritedAndPrivate(_function));\n\n\t\tconj = conj && errorFlag().currentValue() == 0;\n\t\taddRule(smtutil::Expression::implies(conj, summary(_function)), \"summary_function_\" + std::to_string(_function.id()));\n\t\treturn false;\n\t}\n\n\t// No inlining.\n\tsolAssert(!m_currentFunction, \"Function inlining should not happen in CHC.\");\n\tm_currentFunction = &_function;\n\n\tm_scopes.push_back(&_function);\n\n\tinitFunction(_function);\n\n\tauto functionEntryBlock = createBlock(m_currentFunction, PredicateType::FunctionBlock);\n\tauto bodyBlock = createBlock(&m_currentFunction->body(), PredicateType::FunctionBlock);\n\n\tauto functionPred = predicate(*functionEntryBlock);\n\tauto bodyPred = predicate(*bodyBlock);\n\n\taddRule(functionPred, functionPred.name);\n\n\tsolAssert(m_currentContract, \"\");\n\tm_context.addAssertion(initialConstraints(*m_currentContract, &_function));\n\n\tconnectBlocks(functionPred, bodyPred);\n\n\tsetCurrentBlock(*bodyBlock);\n\n\tsolAssert(!m_errorDest, \"\");\n\tm_errorDest = m_summaries.at(m_currentContract).at(&_function);\n\tSMTEncoder::visit(*m_currentFunction);\n\tm_errorDest = nullptr;\n\n\treturn false;\n}\n\nvoid CHC::endVisit(FunctionDefinition const& _function)\n{\n\t// Free functions need to be visited in the context of a contract.\n\tif (!m_currentContract)\n\t\treturn;\n\n\tif (\n\t\t!_function.isImplemented() ||\n\t\tabstractAsNondet(_function)\n\t)\n\t\treturn;\n\n\tsolAssert(m_currentFunction && m_currentContract, \"\");\n\t// No inlining.\n\tsolAssert(m_currentFunction == &_function, \"\");\n\n\tsolAssert(m_scopes.back() == &_function, \"\");\n\tm_scopes.pop_back();\n\n\tconnectBlocks(m_currentBlock, summary(_function));\n\tsetCurrentBlock(*m_summaries.at(m_currentContract).at(&_function));\n\n\t// Query placeholders for constructors are not created here because\n\t// of contracts without constructors.\n\t// Instead, those are created in endVisit(ContractDefinition).\n\tif (\n\t\t!_function.isConstructor() &&\n\t\t_function.isPublic() &&\n\t\tcontractFunctions(*m_currentContract).count(&_function) &&\n\t\tshouldEncode(*m_currentContract)\n\t)\n\t{\n\t\tdefineExternalFunctionInterface(_function, *m_currentContract);\n\t\tsetCurrentBlock(*m_interfaces.at(m_currentContract));\n\n\t\t// Create the rule\n\t\t// interface \\land externalFunctionEntry => interface'\n\t\tauto ifacePre = smt::interfacePre(*m_interfaces.at(m_currentContract), *m_currentContract, m_context);\n\t\tauto sum = externalSummary(_function);\n\n\t\tconnectBlocks(ifacePre, interface(), sum && errorFlag().currentValue() == 0);\n\t\tif (shouldAnalyzeVerificationTargetsFor(*m_currentContract))\n\t\t\tm_queryPlaceholders[&_function].push_back({sum, errorFlag().currentValue(), ifacePre});\n\t}\n\n\tm_currentFunction = nullptr;\n\n\tSMTEncoder::endVisit(_function);\n}\n\nbool CHC::visit(Block const& _block)\n{\n\tm_scopes.push_back(&_block);\n\treturn SMTEncoder::visit(_block);\n}\n\nvoid CHC::endVisit(Block const& _block)\n{\n\tsolAssert(m_scopes.back() == &_block, \"\");\n\tm_scopes.pop_back();\n\tSMTEncoder::endVisit(_block);\n}\n\nbool CHC::visit(IfStatement const& _if)\n{\n\tsolAssert(m_currentFunction, \"\");\n\n\tbool unknownFunctionCallWasSeen = m_unknownFunctionCallSeen;\n\tm_unknownFunctionCallSeen = false;\n\n\tsolAssert(m_currentFunction, \"\");\n\tauto const& functionBody = m_currentFunction->body();\n\n\tauto ifHeaderBlock = createBlock(&_if, PredicateType::FunctionBlock, \"if_header_\");\n\tauto trueBlock = createBlock(&_if.trueStatement(), PredicateType::FunctionBlock, \"if_true_\");\n\tauto falseBlock = _if.falseStatement() ? createBlock(_if.falseStatement(), PredicateType::FunctionBlock, \"if_false_\") : nullptr;\n\tauto afterIfBlock = createBlock(&functionBody, PredicateType::FunctionBlock);\n\n\tconnectBlocks(m_currentBlock, predicate(*ifHeaderBlock));\n\n\tsetCurrentBlock(*ifHeaderBlock);\n\t_if.condition().accept(*this);\n\tauto condition = expr(_if.condition());\n\n\tconnectBlocks(m_currentBlock, predicate(*trueBlock), condition);\n\tif (_if.falseStatement())\n\t\tconnectBlocks(m_currentBlock, predicate(*falseBlock), !condition);\n\telse\n\t\tconnectBlocks(m_currentBlock, predicate(*afterIfBlock), !condition);\n\n\tsetCurrentBlock(*trueBlock);\n\t_if.trueStatement().accept(*this);\n\tconnectBlocks(m_currentBlock, predicate(*afterIfBlock));\n\n\tif (_if.falseStatement())\n\t{\n\t\tsetCurrentBlock(*falseBlock);\n\t\t_if.falseStatement()->accept(*this);\n\t\tconnectBlocks(m_currentBlock, predicate(*afterIfBlock));\n\t}\n\n\tsetCurrentBlock(*afterIfBlock);\n\n\tif (m_unknownFunctionCallSeen)\n\t\teraseKnowledge();\n\n\tm_unknownFunctionCallSeen = unknownFunctionCallWasSeen;\n\n\treturn false;\n}\n\nbool CHC::visit(WhileStatement const& _while)\n{\n\tbool unknownFunctionCallWasSeen = m_unknownFunctionCallSeen;\n\tm_unknownFunctionCallSeen = false;\n\n\tsolAssert(m_currentFunction, \"\");\n\tauto const& functionBody = m_currentFunction->body();\n\n\tauto namePrefix = std::string(_while.isDoWhile() ? \"do_\" : \"\") + \"while\";\n\tauto loopHeaderBlock = createBlock(&_while, PredicateType::FunctionBlock, namePrefix + \"_header_\");\n\tauto loopBodyBlock = createBlock(&_while.body(), PredicateType::FunctionBlock, namePrefix + \"_body_\");\n\tauto afterLoopBlock = createBlock(&functionBody, PredicateType::FunctionBlock);\n\n\tauto outerBreakDest = m_breakDest;\n\tauto outerContinueDest = m_continueDest;\n\tm_breakDest = afterLoopBlock;\n\tm_continueDest = loopHeaderBlock;\n\n\tif (_while.isDoWhile())\n\t\t_while.body().accept(*this);\n\n\tconnectBlocks(m_currentBlock, predicate(*loopHeaderBlock));\n\n\tsetCurrentBlock(*loopHeaderBlock);\n\n\t_while.condition().accept(*this);\n\tauto condition = expr(_while.condition());\n\n\tconnectBlocks(m_currentBlock, predicate(*loopBodyBlock), condition);\n\tconnectBlocks(m_currentBlock, predicate(*afterLoopBlock), !condition);\n\n\t// Loop body visit.\n\tsetCurrentBlock(*loopBodyBlock);\n\t_while.body().accept(*this);\n\n\tm_breakDest = outerBreakDest;\n\tm_continueDest = outerContinueDest;\n\n\t// Back edge.\n\tconnectBlocks(m_currentBlock, predicate(*loopHeaderBlock));\n\tsetCurrentBlock(*afterLoopBlock);\n\n\tif (m_unknownFunctionCallSeen)\n\t\teraseKnowledge();\n\n\tm_unknownFunctionCallSeen = unknownFunctionCallWasSeen;\n\n\treturn false;\n}\n\nbool CHC::visit(ForStatement const& _for)\n{\n\tm_scopes.push_back(&_for);\n\n\tbool unknownFunctionCallWasSeen = m_unknownFunctionCallSeen;\n\tm_unknownFunctionCallSeen = false;\n\n\tsolAssert(m_currentFunction, \"\");\n\tauto const& functionBody = m_currentFunction->body();\n\n\tauto loopHeaderBlock = createBlock(&_for, PredicateType::FunctionBlock, \"for_header_\");\n\tauto loopBodyBlock = createBlock(&_for.body(), PredicateType::FunctionBlock, \"for_body_\");\n\tauto afterLoopBlock = createBlock(&functionBody, PredicateType::FunctionBlock);\n\tauto postLoop = _for.loopExpression();\n\tauto postLoopBlock = postLoop ? createBlock(postLoop, PredicateType::FunctionBlock, \"for_post_\") : nullptr;\n\n\tauto outerBreakDest = m_breakDest;\n\tauto outerContinueDest = m_continueDest;\n\tm_breakDest = afterLoopBlock;\n\tm_continueDest = postLoop ? postLoopBlock : loopHeaderBlock;\n\n\tif (auto init = _for.initializationExpression())\n\t\tinit->accept(*this);\n\n\tconnectBlocks(m_currentBlock, predicate(*loopHeaderBlock));\n\tsetCurrentBlock(*loopHeaderBlock);\n\n\tauto condition = smtutil::Expression(true);\n\tif (auto forCondition = _for.condition())\n\t{\n\t\tforCondition->accept(*this);\n\t\tcondition = expr(*forCondition);\n\t}\n\n\tconnectBlocks(m_currentBlock, predicate(*loopBodyBlock), condition);\n\tconnectBlocks(m_currentBlock, predicate(*afterLoopBlock), !condition);\n\n\t// Loop body visit.\n\tsetCurrentBlock(*loopBodyBlock);\n\t_for.body().accept(*this);\n\n\tif (postLoop)\n\t{\n\t\tconnectBlocks(m_currentBlock, predicate(*postLoopBlock));\n\t\tsetCurrentBlock(*postLoopBlock);\n\t\tpostLoop->accept(*this);\n\t}\n\n\tm_breakDest = outerBreakDest;\n\tm_continueDest = outerContinueDest;\n\n\t// Back edge.\n\tconnectBlocks(m_currentBlock, predicate(*loopHeaderBlock));\n\tsetCurrentBlock(*afterLoopBlock);\n\n\tif (m_unknownFunctionCallSeen)\n\t\teraseKnowledge();\n\n\tm_unknownFunctionCallSeen = unknownFunctionCallWasSeen;\n\n\treturn false;\n}\n\nvoid CHC::endVisit(ForStatement const& _for)\n{\n\tsolAssert(m_scopes.back() == &_for, \"\");\n\tm_scopes.pop_back();\n}\n\nvoid CHC::endVisit(UnaryOperation const& _op)\n{\n\tSMTEncoder::endVisit(_op);\n\n\tif (auto funDef = *_op.annotation().userDefinedFunction)\n\t{\n\t\tstd::vector<Expression const*> arguments;\n\t\targuments.push_back(&_op.subExpression());\n\t\tinternalFunctionCall(funDef, std::nullopt, _op.userDefinedFunctionType(), arguments, state().thisAddress());\n\n\t\tcreateReturnedExpressions(funDef, _op);\n\t\treturn;\n\t}\n\n\tif (\n\t\t_op.annotation().type->category() == Type::Category::RationalNumber ||\n\t\t_op.annotation().type->category() == Type::Category::FixedPoint\n\t)\n\t\treturn;\n\n\tif (_op.getOperator() == Token::Sub && smt::isInteger(*_op.annotation().type))\n\t{\n\t\tauto const* intType = dynamic_cast<IntegerType const*>(_op.annotation().type);\n\t\tif (!intType)\n\t\t\tintType = TypeProvider::uint256();\n\n\t\tverificationTargetEncountered(&_op, VerificationTargetType::Underflow, expr(_op) < intType->minValue());\n\t\tverificationTargetEncountered(&_op, VerificationTargetType::Overflow, expr(_op) > intType->maxValue());\n\t}\n}\n\nvoid CHC::endVisit(BinaryOperation const& _op)\n{\n\tSMTEncoder::endVisit(_op);\n\n\tif (auto funDef = *_op.annotation().userDefinedFunction)\n\t{\n\t\tstd::vector<Expression const*> arguments;\n\t\targuments.push_back(&_op.leftExpression());\n\t\targuments.push_back(&_op.rightExpression());\n\t\tinternalFunctionCall(funDef, std::nullopt, _op.userDefinedFunctionType(), arguments, state().thisAddress());\n\n\t\tcreateReturnedExpressions(funDef, _op);\n\t}\n}\n\nvoid CHC::endVisit(FunctionCall const& _funCall)\n{\n\tauto functionCallKind = *_funCall.annotation().kind;\n\n\tif (functionCallKind != FunctionCallKind::FunctionCall)\n\t{\n\t\tSMTEncoder::endVisit(_funCall);\n\t\treturn;\n\t}\n\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);\n\tswitch (funType.kind())\n\t{\n\tcase FunctionType::Kind::Assert:\n\t\tvisitAssert(_funCall);\n\t\tSMTEncoder::endVisit(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Internal:\n\t\tinternalFunctionCall(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::External:\n\tcase FunctionType::Kind::BareStaticCall:\n\tcase FunctionType::Kind::BareCall:\n\t\texternalFunctionCall(_funCall);\n\t\tSMTEncoder::endVisit(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Creation:\n\t\tvisitDeployment(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::DelegateCall:\n\tcase FunctionType::Kind::BareCallCode:\n\tcase FunctionType::Kind::BareDelegateCall:\n\t\tSMTEncoder::endVisit(_funCall);\n\t\tunknownFunctionCall(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Send:\n\tcase FunctionType::Kind::Transfer:\n\t{\n\t\tauto value = _funCall.arguments().front();\n\t\tsolAssert(value, \"\");\n\t\tsmtutil::Expression thisBalance = state().balance();\n\n\t\tverificationTargetEncountered(\n\t\t\t&_funCall,\n\t\t\tVerificationTargetType::Balance,\n\t\t\tthisBalance < expr(*value)\n\t\t);\n\n\t\tSMTEncoder::endVisit(_funCall);\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::KECCAK256:\n\tcase FunctionType::Kind::ECRecover:\n\tcase FunctionType::Kind::SHA256:\n\tcase FunctionType::Kind::RIPEMD160:\n\tcase FunctionType::Kind::BlobHash:\n\tcase FunctionType::Kind::BlockHash:\n\tcase FunctionType::Kind::AddMod:\n\tcase FunctionType::Kind::MulMod:\n\tcase FunctionType::Kind::Unwrap:\n\tcase FunctionType::Kind::Wrap:\n\t\t[[fallthrough]];\n\tdefault:\n\t\tSMTEncoder::endVisit(_funCall);\n\t\tbreak;\n\t}\n\n\tauto funDef = functionCallToDefinition(_funCall, currentScopeContract(), m_currentContract);\n\tcreateReturnedExpressions(funDef, _funCall);\n}\n\nvoid CHC::endVisit(Break const& _break)\n{\n\tsolAssert(m_breakDest, \"\");\n\tconnectBlocks(m_currentBlock, predicate(*m_breakDest));\n\n\t// Add an unreachable ghost node to collect unreachable statements after a break.\n\tauto breakGhost = createBlock(&_break, PredicateType::FunctionBlock, \"break_ghost_\");\n\tm_currentBlock = predicate(*breakGhost);\n}\n\nvoid CHC::endVisit(Continue const& _continue)\n{\n\tsolAssert(m_continueDest, \"\");\n\tconnectBlocks(m_currentBlock, predicate(*m_continueDest));\n\n\t// Add an unreachable ghost node to collect unreachable statements after a continue.\n\tauto continueGhost = createBlock(&_continue, PredicateType::FunctionBlock, \"continue_ghost_\");\n\tm_currentBlock = predicate(*continueGhost);\n}\n\nvoid CHC::endVisit(IndexRangeAccess const& _range)\n{\n\tcreateExpr(_range);\n\n\tauto baseArray = std::dynamic_pointer_cast<SymbolicArrayVariable>(m_context.expression(_range.baseExpression()));\n\tauto sliceArray = std::dynamic_pointer_cast<SymbolicArrayVariable>(m_context.expression(_range));\n\tsolAssert(baseArray && sliceArray, \"\");\n\n\tauto const& sliceData = ArraySlicePredicate::create(sliceArray->sort(), m_context);\n\tif (!sliceData.first)\n\t{\n\t\tfor (auto pred: sliceData.second.predicates)\n\t\t\tm_interface->registerRelation(pred->functor());\n\t\tfor (auto const& rule: sliceData.second.rules)\n\t\t\taddRule(rule, \"\");\n\t}\n\n\tauto start = _range.startExpression() ? expr(*_range.startExpression()) : 0;\n\tauto end = _range.endExpression() ? expr(*_range.endExpression()) : baseArray->length();\n\tauto slicePred = (*sliceData.second.predicates.at(0))({\n\t\tbaseArray->elements(),\n\t\tsliceArray->elements(),\n\t\tstart,\n\t\tend\n\t});\n\n\tm_context.addAssertion(slicePred);\n\tm_context.addAssertion(sliceArray->length() == end - start);\n}\n\nvoid CHC::endVisit(Return const& _return)\n{\n\tSMTEncoder::endVisit(_return);\n\n\tconnectBlocks(m_currentBlock, predicate(*m_returnDests.back()));\n\n\t// Add an unreachable ghost node to collect unreachable statements after a return.\n\tauto returnGhost = createBlock(&_return, PredicateType::FunctionBlock, \"return_ghost_\");\n\tm_currentBlock = predicate(*returnGhost);\n}\n\nbool CHC::visit(TryCatchClause const& _tryStatement)\n{\n\tm_scopes.push_back(&_tryStatement);\n\treturn SMTEncoder::visit(_tryStatement);\n}\n\nvoid CHC::endVisit(TryCatchClause const& _tryStatement)\n{\n\tsolAssert(m_scopes.back() == &_tryStatement, \"\");\n\tm_scopes.pop_back();\n}\n\nbool CHC::visit(TryStatement const& _tryStatement)\n{\n\tFunctionCall const* externalCall = dynamic_cast<FunctionCall const*>(&_tryStatement.externalCall());\n\tsolAssert(externalCall && externalCall->annotation().tryCall, \"\");\n\tsolAssert(m_currentFunction, \"\");\n\n\tauto tryHeaderBlock = createBlock(&_tryStatement, PredicateType::FunctionBlock, \"try_header_\");\n\tauto afterTryBlock = createBlock(&m_currentFunction->body(), PredicateType::FunctionBlock);\n\n\tauto const& clauses = _tryStatement.clauses();\n\tsolAssert(clauses[0].get() == _tryStatement.successClause(), \"First clause of TryStatement should be the success clause\");\n\tauto clauseBlocks = applyMap(clauses, [this](ASTPointer<TryCatchClause> clause) {\n\t\treturn createBlock(clause.get(), PredicateType::FunctionBlock, \"try_clause_\" + std::to_string(clause->id()));\n\t});\n\n\tconnectBlocks(m_currentBlock, predicate(*tryHeaderBlock));\n\tsetCurrentBlock(*tryHeaderBlock);\n\t// Visit everything, except the actual external call.\n\texternalCall->expression().accept(*this);\n\tASTNode::listAccept(externalCall->arguments(), *this);\n\t// Branch directly to all catch clauses, since in these cases, any effects of the external call are reverted.\n\tfor (size_t i = 1; i < clauseBlocks.size(); ++i)\n\t\tconnectBlocks(m_currentBlock, predicate(*clauseBlocks[i]));\n\t// Only now visit the actual call to record its effects and connect to the success clause.\n\tendVisit(*externalCall);\n\tif (_tryStatement.successClause()->parameters())\n\t\texpressionToTupleAssignment(_tryStatement.successClause()->parameters()->parameters(), *externalCall);\n\n\tconnectBlocks(m_currentBlock, predicate(*clauseBlocks[0]));\n\n\tfor (size_t i = 0; i < clauses.size(); ++i)\n\t{\n\t\tsetCurrentBlock(*clauseBlocks[i]);\n\t\tclauses[i]->accept(*this);\n\t\tconnectBlocks(m_currentBlock, predicate(*afterTryBlock));\n\t}\n\tsetCurrentBlock(*afterTryBlock);\n\n\treturn false;\n}\n\nvoid CHC::pushInlineFrame(CallableDeclaration const& _callable)\n{\n\tm_returnDests.push_back(createBlock(&_callable, PredicateType::FunctionBlock, \"return_\"));\n}\n\nvoid CHC::popInlineFrame(CallableDeclaration const& _callable)\n{\n\tsolAssert(!m_returnDests.empty(), \"\");\n\tauto const& ret = *m_returnDests.back();\n\tsolAssert(ret.programNode() == &_callable, \"\");\n\tconnectBlocks(m_currentBlock, predicate(ret));\n\tsetCurrentBlock(ret);\n\tm_returnDests.pop_back();\n}\n\nvoid CHC::visitAssert(FunctionCall const& _funCall)\n{\n\tauto const& args = _funCall.arguments();\n\tsolAssert(args.size() == 1, \"\");\n\tsolAssert(args.front()->annotation().type->category() == Type::Category::Bool, \"\");\n\n\tsolAssert(m_currentContract, \"\");\n\tsolAssert(m_currentFunction, \"\");\n\tauto errorCondition = !m_context.expression(*args.front())->currentValue();\n\tverificationTargetEncountered(&_funCall, VerificationTargetType::Assert, errorCondition);\n}\n\nvoid CHC::visitPublicGetter(FunctionCall const& _funCall)\n{\n\tcreateExpr(_funCall);\n\tif (encodeExternalCallsAsTrusted())\n\t{\n\t\tauto const& access = dynamic_cast<MemberAccess const&>(_funCall.expression());\n\t\tauto const& contractType = dynamic_cast<ContractType const&>(*access.expression().annotation().type);\n\t\tstate().writeStateVars(*m_currentContract, state().thisAddress());\n\t\tstate().readStateVars(contractType.contractDefinition(), expr(access.expression()));\n\t}\n\tSMTEncoder::visitPublicGetter(_funCall);\n}\n\nvoid CHC::visitAddMulMod(FunctionCall const& _funCall)\n{\n\tsolAssert(_funCall.arguments().at(2), \"\");\n\n\tverificationTargetEncountered(&_funCall, VerificationTargetType::DivByZero, expr(*_funCall.arguments().at(2)) == 0);\n\n\tSMTEncoder::visitAddMulMod(_funCall);\n}\n\nvoid CHC::visitDeployment(FunctionCall const& _funCall)\n{\n\tif (!encodeExternalCallsAsTrusted())\n\t{\n\t\tSMTEncoder::endVisit(_funCall);\n\t\tunknownFunctionCall(_funCall);\n\t\treturn;\n\t}\n\n\tauto [callExpr, callOptions] = functionCallExpression(_funCall);\n\tauto funType = dynamic_cast<FunctionType const*>(callExpr->annotation().type);\n\tContractDefinition const* contract =\n\t\t&dynamic_cast<ContractType const&>(*funType->returnParameterTypes().front()).contractDefinition();\n\n\t// copy state variables from m_currentContract to state.storage.\n\tstate().writeStateVars(*m_currentContract, state().thisAddress());\n\terrorFlag().increaseIndex();\n\n\tExpression const* value = valueOption(callOptions);\n\tif (value)\n\t\tdecreaseBalanceFromOptionsValue(*value);\n\n\tauto originalTx = state().tx();\n\tnewTxConstraints(value);\n\n\tauto prevThisAddr = state().thisAddress();\n\tauto newAddr = state().newThisAddress();\n\n\tif (auto constructor = contract->constructor())\n\t{\n\t\tauto const& args = _funCall.sortedArguments();\n\t\tauto const& params = constructor->parameters();\n\t\tsolAssert(args.size() == params.size(), \"\");\n\t\tfor (auto [arg, param]: ranges::zip_view(args, params))\n\t\t\tm_context.addAssertion(expr(*arg, param->type()) == m_context.variable(*param)->currentValue());\n\t}\n\tfor (auto var: stateVariablesIncludingInheritedAndPrivate(*contract))\n\t\tm_context.variable(*var)->increaseIndex();\n\tPredicate const& constructorSummary = *m_constructorSummaries.at(contract);\n\tm_context.addAssertion(smt::constructorCall(constructorSummary, m_context, false));\n\n\tsolAssert(m_errorDest, \"\");\n\tconnectBlocks(\n\t\tm_currentBlock,\n\t\tpredicate(*m_errorDest),\n\t\terrorFlag().currentValue() > 0\n\t);\n\tm_context.addAssertion(errorFlag().currentValue() == 0);\n\n\tm_context.addAssertion(state().newThisAddress() == prevThisAddr);\n\n\t// copy state variables from state.storage to m_currentContract.\n\tstate().readStateVars(*m_currentContract, state().thisAddress());\n\n\tstate().newTx();\n\tm_context.addAssertion(originalTx == state().tx());\n\n\tdefineExpr(_funCall, newAddr);\n}\n\nvoid CHC::internalFunctionCall(\n\tFunctionDefinition const* _funDef,\n\tstd::optional<Expression const*> _boundArgumentCall,\n\tFunctionType const* _funType,\n\tstd::vector<Expression const*> const& _arguments,\n\tsmtutil::Expression _contractAddressValue\n)\n{\n\tsolAssert(m_currentContract, \"\");\n\tsolAssert(_funType, \"\");\n\n\tif (_funDef)\n\t{\n\t\tif (m_currentFunction && !m_currentFunction->isConstructor())\n\t\t\tm_callGraph[m_currentFunction].insert(_funDef);\n\t\telse\n\t\t\tm_callGraph[m_currentContract].insert(_funDef);\n\t}\n\n\tm_context.addAssertion(predicate(_funDef, _boundArgumentCall, _funType, _arguments, _contractAddressValue));\n\n\tsolAssert(m_errorDest, \"\");\n\tconnectBlocks(\n\t\tm_currentBlock,\n\t\tpredicate(*m_errorDest),\n\t\terrorFlag().currentValue() > 0 && currentPathConditions()\n\t);\n\tm_context.addAssertion(smtutil::Expression::implies(currentPathConditions(), errorFlag().currentValue() == 0));\n\tm_context.addAssertion(errorFlag().increaseIndex() == 0);\n}\n\nvoid CHC::internalFunctionCall(FunctionCall const& _funCall)\n{\n\tsolAssert(m_currentContract, \"\");\n\n\tauto funDef = functionCallToDefinition(_funCall, currentScopeContract(), m_currentContract);\n\tif (funDef)\n\t{\n\t\tif (m_currentFunction && !m_currentFunction->isConstructor())\n\t\t\tm_callGraph[m_currentFunction].insert(funDef);\n\t\telse\n\t\t\tm_callGraph[m_currentContract].insert(funDef);\n\t}\n\n\tExpression const* calledExpr = &_funCall.expression();\n\tauto funType = dynamic_cast<FunctionType const*>(calledExpr->annotation().type);\n\n\tstd::vector<Expression const*> arguments;\n\tfor (auto& arg: _funCall.sortedArguments())\n\t\targuments.push_back(&(*arg));\n\n\tstd::optional<Expression const*> boundArgumentCall =\n\t\tfunType->hasBoundFirstArgument() ? std::make_optional(calledExpr) : std::nullopt;\n\tinternalFunctionCall(funDef, boundArgumentCall, funType, arguments, contractAddressValue(_funCall));\n}\n\nvoid CHC::addNondetCalls(ContractDefinition const& _contract)\n{\n\tfor (auto var: _contract.stateVariables())\n\t\tif (auto contractType = dynamic_cast<ContractType const*>(var->type()))\n\t\t{\n\t\t\tauto const& symbVar = m_context.variable(*var);\n\t\t\tm_context.addAssertion(symbVar->currentValue() == symbVar->valueAtIndex(0));\n\t\t\tnondetCall(contractType->contractDefinition(), *var);\n\t\t}\n}\n\nvoid CHC::nondetCall(ContractDefinition const& _contract, VariableDeclaration const& _var)\n{\n\tauto address = m_context.variable(_var)->currentValue();\n\t// Load the called contract's state variables from the global state.\n\tstate().readStateVars(_contract, address);\n\n\tm_context.addAssertion(state().state() == state().state(0));\n\tauto preCallState = std::vector<smtutil::Expression>{state().state()} + currentStateVariables(_contract);\n\n\tstate().newState();\n\tfor (auto const* var: _contract.stateVariables())\n\t\tm_context.variable(*var)->increaseIndex();\n\n\tPredicate const& callPredicate = *createSymbolicBlock(\n\t\tnondetInterfaceSort(_contract, state()),\n\t\t\"nondet_call_\" + uniquePrefix(),\n\t\tPredicateType::FunctionSummary,\n\t\t&_var,\n\t\tm_currentContract\n\t);\n\tauto postCallState = std::vector<smtutil::Expression>{state().state()} + currentStateVariables(_contract);\n\tstd::vector<smtutil::Expression> stateExprs = commonStateExpressions(errorFlag().increaseIndex(), address);\n\n\tauto nondet = (*m_nondetInterfaces.at(&_contract))(stateExprs + preCallState + postCallState);\n\tauto nondetCall = callPredicate(stateExprs + preCallState + postCallState);\n\n\taddRule(smtutil::Expression::implies(nondet, nondetCall), nondetCall.name);\n\n\tm_context.addAssertion(nondetCall);\n\n\t// Load the called contract's state variables into the global state.\n\tstate().writeStateVars(_contract, address);\n}\n\nvoid CHC::externalFunctionCall(FunctionCall const& _funCall)\n{\n\t/// In external function calls we do not add a \"predicate call\"\n\t/// because we do not trust their function body anyway,\n\t/// so we just add the nondet_interface predicate.\n\n\tsolAssert(m_currentContract, \"\");\n\n\tauto [callExpr, callOptions] = functionCallExpression(_funCall);\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(*callExpr->annotation().type);\n\n\tauto kind = funType.kind();\n\tsolAssert(\n\t\tkind == FunctionType::Kind::External ||\n\t\tkind == FunctionType::Kind::BareCall ||\n\t\tkind == FunctionType::Kind::BareStaticCall,\n\t\t\"\"\n\t);\n\n\n\t// Only consider high level external calls in trusted mode.\n\tif (\n\t\tkind == FunctionType::Kind::External &&\n\t\t(encodeExternalCallsAsTrusted() || isExternalCallToThis(callExpr))\n\t)\n\t{\n\t\texternalFunctionCallToTrustedCode(_funCall);\n\t\treturn;\n\t}\n\n\t// Low level calls are still encoded nondeterministically.\n\n\tauto function = functionCallToDefinition(_funCall, currentScopeContract(), m_currentContract);\n\tif (function)\n\t\tfor (auto var: function->returnParameters())\n\t\t\tm_context.variable(*var)->increaseIndex();\n\n\t// If we see a low level call in trusted mode,\n\t// we need to havoc the global state.\n\tif (\n\t\tkind == FunctionType::Kind::BareCall &&\n\t\tencodeExternalCallsAsTrusted()\n\t)\n\t\tstate().newStorage();\n\n\t// No reentrancy from constructor calls.\n\tif (!m_currentFunction || m_currentFunction->isConstructor())\n\t\treturn;\n\n\tif (Expression const* value = valueOption(callOptions))\n\t\tdecreaseBalanceFromOptionsValue(*value);\n\n\tauto preCallState = std::vector<smtutil::Expression>{state().state()} + currentStateVariables();\n\n\tif (!usesStaticCall(_funCall))\n\t{\n\t\tstate().newState();\n\t\tfor (auto const* var: m_stateVariables)\n\t\t\tm_context.variable(*var)->increaseIndex();\n\t}\n\n\tPredicate const& callPredicate = *createSymbolicBlock(\n\t\tnondetInterfaceSort(*m_currentContract, state()),\n\t\t\"nondet_call_\" + uniquePrefix(),\n\t\tPredicateType::ExternalCallUntrusted,\n\t\t&_funCall\n\t);\n\tauto postCallState = std::vector<smtutil::Expression>{state().state()} + currentStateVariables();\n\tstd::vector<smtutil::Expression> stateExprs = commonStateExpressions(errorFlag().increaseIndex(), state().thisAddress());\n\n\tauto nondet = (*m_nondetInterfaces.at(m_currentContract))(stateExprs + preCallState + postCallState);\n\tauto nondetCall = callPredicate(stateExprs + preCallState + postCallState);\n\n\taddRule(smtutil::Expression::implies(nondet, nondetCall), nondetCall.name);\n\n\tm_context.addAssertion(nondetCall);\n\tsolAssert(m_errorDest, \"\");\n\tconnectBlocks(m_currentBlock, predicate(*m_errorDest), errorFlag().currentValue() > 0 && currentPathConditions());\n\n\t// To capture the possibility of a reentrant call, we record in the call graph that the  current function\n\t// can call any of the external methods of the current contract.\n\tif (m_currentFunction)\n\t\tfor (auto const* definedFunction: contractFunctions(*m_currentContract))\n\t\t\tif (!definedFunction->isConstructor() && definedFunction->isPublic())\n\t\t\t\tm_callGraph[m_currentFunction].insert(definedFunction);\n\n\tm_context.addAssertion(errorFlag().currentValue() == 0);\n}\n\nvoid CHC::externalFunctionCallToTrustedCode(FunctionCall const& _funCall)\n{\n\tif (publicGetter(_funCall.expression()))\n\t\tvisitPublicGetter(_funCall);\n\n\tsolAssert(m_currentContract, \"\");\n\n\tauto [callExpr, callOptions] = functionCallExpression(_funCall);\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(*callExpr->annotation().type);\n\n\tauto kind = funType.kind();\n\tsolAssert(kind == FunctionType::Kind::External || kind == FunctionType::Kind::BareStaticCall, \"\");\n\n\tauto function = functionCallToDefinition(_funCall, currentScopeContract(), m_currentContract);\n\tif (!function)\n\t\treturn;\n\n\t// Remember the external call in the call graph to properly detect verification targets for the current function\n\tif (m_currentFunction && !m_currentFunction->isConstructor())\n\t\tm_callGraph[m_currentFunction].insert(function);\n\telse\n\t\tm_callGraph[m_currentContract].insert(function);\n\n\t// External call creates a new transaction.\n\tauto originalTx = state().tx();\n\tExpression const* value = valueOption(callOptions);\n\tnewTxConstraints(value);\n\n\tauto calledAddress = contractAddressValue(_funCall);\n\tif (value)\n\t{\n\t\tdecreaseBalanceFromOptionsValue(*value);\n\t\tstate().addBalance(calledAddress, expr(*value));\n\t}\n\n\tif (encodeExternalCallsAsTrusted())\n\t{\n\t\t// The order here is important!! Write should go first.\n\n\t\t// Load the caller contract's state variables into the global state.\n\t\tstate().writeStateVars(*m_currentContract, state().thisAddress());\n\t\t// Load the called contract's state variables from the global state.\n\t\tstate().readStateVars(*function->annotation().contract, contractAddressValue(_funCall));\n\t}\n\n\tstd::vector<Expression const*> arguments;\n\tfor (auto& arg: _funCall.sortedArguments())\n\t\targuments.push_back(&(*arg));\n\tsmtutil::Expression pred = predicate(function, std::nullopt, &funType, arguments, calledAddress);\n\n\tauto txConstraints = state().txTypeConstraints() && state().txFunctionConstraints(*function);\n\tm_context.addAssertion(pred && txConstraints);\n\t// restore the original transaction data\n\tstate().newTx();\n\tm_context.addAssertion(originalTx == state().tx());\n\n\tsolAssert(m_errorDest, \"\");\n\tconnectBlocks(\n\t\tm_currentBlock,\n\t\tpredicate(*m_errorDest),\n\t\t(errorFlag().currentValue() > 0)\n\t);\n\tm_context.addAssertion(errorFlag().currentValue() == 0);\n\n\tif (!usesStaticCall(_funCall))\n\t\tif (encodeExternalCallsAsTrusted())\n\t\t{\n\t\t\t// The order here is important!! Write should go first.\n\n\t\t\t// Load the called contract's state variables into the global state.\n\t\t\tstate().writeStateVars(*function->annotation().contract, contractAddressValue(_funCall));\n\t\t\t// Load the caller contract's state variables from the global state.\n\t\t\tstate().readStateVars(*m_currentContract, state().thisAddress());\n\t\t}\n}\n\nvoid CHC::unknownFunctionCall(FunctionCall const&)\n{\n\t/// Function calls are not handled at the moment,\n\t/// so always erase knowledge.\n\t/// TODO remove when function calls get predicates/blocks.\n\teraseKnowledge();\n\n\t/// Used to erase outer scope knowledge in loops and ifs.\n\t/// TODO remove when function calls get predicates/blocks.\n\tm_unknownFunctionCallSeen = true;\n}\n\nvoid CHC::makeArrayPopVerificationTarget(FunctionCall const& _arrayPop)\n{\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(*_arrayPop.expression().annotation().type);\n\tsolAssert(funType.kind() == FunctionType::Kind::ArrayPop, \"\");\n\n\tauto memberAccess = dynamic_cast<MemberAccess const*>(cleanExpression(_arrayPop.expression()));\n\tsolAssert(memberAccess, \"\");\n\tauto symbArray = std::dynamic_pointer_cast<SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));\n\tsolAssert(symbArray, \"\");\n\n\tverificationTargetEncountered(&_arrayPop, VerificationTargetType::PopEmptyArray, symbArray->length() <= 0);\n}\n\nvoid CHC::makeOutOfBoundsVerificationTarget(IndexAccess const& _indexAccess)\n{\n\tif (_indexAccess.annotation().type->category() == Type::Category::TypeType)\n\t\treturn;\n\n\tauto baseType = _indexAccess.baseExpression().annotation().type;\n\n\tstd::optional<smtutil::Expression> length;\n\tif (smt::isArray(*baseType))\n\t\tlength = dynamic_cast<smt::SymbolicArrayVariable const&>(\n\t\t\t*m_context.expression(_indexAccess.baseExpression())\n\t\t).length();\n\telse if (auto const* type = dynamic_cast<FixedBytesType const*>(baseType))\n\t\tlength = smtutil::Expression(static_cast<size_t>(type->numBytes()));\n\n\tstd::optional<smtutil::Expression> target;\n\tif (\n\t\tauto index = _indexAccess.indexExpression();\n\t\tindex && length\n\t)\n\t\ttarget = expr(*index) < 0 || expr(*index) >= *length;\n\n\tif (target)\n\t\tverificationTargetEncountered(&_indexAccess, VerificationTargetType::OutOfBounds, *target);\n}\n\nstd::pair<smtutil::Expression, smtutil::Expression> CHC::arithmeticOperation(\n\tToken _op,\n\tsmtutil::Expression const& _left,\n\tsmtutil::Expression const& _right,\n\tType const* _commonType,\n\tfrontend::Expression const& _expression\n)\n{\n\t// Unchecked does not disable div by 0 checks.\n\tif (_op == Token::Mod || _op == Token::Div)\n\t\tverificationTargetEncountered(&_expression, VerificationTargetType::DivByZero, _right == 0);\n\n\tauto values = SMTEncoder::arithmeticOperation(_op, _left, _right, _commonType, _expression);\n\n\tif (!m_checked)\n\t\treturn values;\n\n\tIntegerType const* intType = nullptr;\n\tif (auto const* type = dynamic_cast<IntegerType const*>(_commonType))\n\t\tintType = type;\n\telse\n\t\tintType = TypeProvider::uint256();\n\n\t// Mod does not need underflow/overflow checks.\n\t// Div only needs overflow check for signed types.\n\tif (_op == Token::Mod || (_op == Token::Div && !intType->isSigned()))\n\t\treturn values;\n\n\tif (_op == Token::Div)\n\t\tverificationTargetEncountered(&_expression, VerificationTargetType::Overflow, values.second > intType->maxValue());\n\telse if (intType->isSigned())\n\t{\n\t\tverificationTargetEncountered(&_expression, VerificationTargetType::Underflow, values.second < intType->minValue());\n\t\tverificationTargetEncountered(&_expression, VerificationTargetType::Overflow, values.second > intType->maxValue());\n\t}\n\telse if (_op == Token::Sub)\n\t\tverificationTargetEncountered(&_expression, VerificationTargetType::Underflow, values.second < intType->minValue());\n\telse if (_op == Token::Add || _op == Token::Mul)\n\t\tverificationTargetEncountered(&_expression, VerificationTargetType::Overflow, values.second > intType->maxValue());\n\telse\n\t\tsolAssert(false, \"\");\n\treturn values;\n}\n\nvoid CHC::resetSourceAnalysis()\n{\n\tSMTEncoder::resetSourceAnalysis();\n\n\tm_unprovedTargets.clear();\n\tm_invariants.clear();\n\tm_functionTargetIds.clear();\n\tm_verificationTargets.clear();\n\tm_queryPlaceholders.clear();\n\tm_callGraph.clear();\n\tm_summaries.clear();\n\tm_externalSummaries.clear();\n\tm_interfaces.clear();\n\tm_nondetInterfaces.clear();\n\tm_constructorSummaries.clear();\n\tm_contractInitializers.clear();\n\tPredicate::reset();\n\tArraySlicePredicate::reset();\n\tm_blockCounter = 0;\n\n\tsolAssert(m_settings.solvers.smtlib2 || m_settings.solvers.eld || m_settings.solvers.z3);\n\tif (!m_interface)\n\t{\n\t\tif (m_settings.solvers.z3)\n\t\t\tm_interface = std::make_unique<Z3CHCSmtLib2Interface>(\n\t\t\t\tm_smtCallback,\n\t\t\t\tm_settings.timeout,\n\t\t\t\tm_settings.invariants != ModelCheckerInvariants::None()\n\t\t\t);\n\t\telse if (m_settings.solvers.eld)\n\t\t\tm_interface = std::make_unique<EldaricaCHCSmtLib2Interface>(\n\t\t\t\tm_smtCallback,\n\t\t\t\tm_settings.timeout,\n\t\t\t\tm_settings.invariants != ModelCheckerInvariants::None()\n\t\t\t);\n\t\telse\n\t\t\tm_interface = std::make_unique<CHCSmtLib2Interface>(m_smtlib2Responses, m_smtCallback, m_settings.timeout);\n\t}\n\n\tauto smtlib2Interface = dynamic_cast<CHCSmtLib2Interface*>(m_interface.get());\n\tsolAssert(smtlib2Interface);\n\tsmtlib2Interface->reset();\n\tm_context.setSolver(smtlib2Interface);\n\n\tm_context.reset();\n\tm_context.resetUniqueId();\n\tm_context.setAssertionAccumulation(false);\n}\n\nvoid CHC::resetContractAnalysis()\n{\n\tm_stateVariables.clear();\n\tm_unknownFunctionCallSeen = false;\n\tm_breakDest = nullptr;\n\tm_continueDest = nullptr;\n\tm_returnDests.clear();\n\terrorFlag().resetIndex();\n}\n\nvoid CHC::eraseKnowledge()\n{\n\tresetStorageVariables();\n\tresetBalances();\n}\n\nvoid CHC::clearIndices(ContractDefinition const* _contract, FunctionDefinition const* _function)\n{\n\tSMTEncoder::clearIndices(_contract, _function);\n\tfor (auto const* var: m_stateVariables)\n\t\t/// SSA index 0 is reserved for state variables at the beginning\n\t\t/// of the current transaction.\n\t\tm_context.variable(*var)->increaseIndex();\n\tif (_function)\n\t{\n\t\tfor (auto const& var: _function->parameters() + _function->returnParameters())\n\t\t\tm_context.variable(*var)->increaseIndex();\n\t\tfor (auto const& var: localVariablesIncludingModifiers(*_function, _contract))\n\t\t\tm_context.variable(*var)->increaseIndex();\n\t}\n\n\tstate().newState();\n}\n\nvoid CHC::setCurrentBlock(Predicate const& _block)\n{\n\tif (m_context.solverStackHeight() > 0)\n\t\tm_context.popSolver();\n\tsolAssert(m_currentContract, \"\");\n\tclearIndices(m_currentContract, m_currentFunction);\n\tm_context.pushSolver();\n\tm_currentBlock = predicate(_block);\n}\n\nstd::set<unsigned> CHC::transactionVerificationTargetsIds(ASTNode const* _txRoot)\n{\n\tstd::set<unsigned> verificationTargetsIds;\n\tstruct ASTNodeCompare: EncodingContext::IdCompare\n\t{\n\t\tbool operator<(ASTNodeCompare _other) const { return operator()(node, _other.node); }\n\t\tASTNode const* node;\n\t};\n\tsolidity::util::BreadthFirstSearch<ASTNodeCompare>{{{{}, _txRoot}}}.run([&](auto _node, auto&& _addChild) {\n\t\tverificationTargetsIds.insert(m_functionTargetIds[_node.node].begin(), m_functionTargetIds[_node.node].end());\n\t\tfor (ASTNode const* called: m_callGraph[_node.node])\n\t\t\t_addChild({{}, called});\n\t});\n\treturn verificationTargetsIds;\n}\n\nbool CHC::usesStaticCall(FunctionDefinition const* _funDef, FunctionType const* _funType)\n{\n\tauto kind = _funType->kind();\n\treturn (_funDef && (_funDef->stateMutability() == StateMutability::Pure || _funDef->stateMutability() == StateMutability::View)) || kind == FunctionType::Kind::BareStaticCall;\n}\n\nbool CHC::usesStaticCall(FunctionCall const& _funCall)\n{\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);\n\tauto kind = funType.kind();\n\tauto function = functionCallToDefinition(_funCall, currentScopeContract(), m_currentContract);\n\treturn (function && (function->stateMutability() == StateMutability::Pure || function->stateMutability() == StateMutability::View)) || kind == FunctionType::Kind::BareStaticCall;\n}\n\nstd::optional<CHC::CHCNatspecOption> CHC::natspecOptionFromString(std::string const& _option)\n{\n\tstatic std::map<std::string, CHCNatspecOption> options{\n\t\t{\"abstract-function-nondet\", CHCNatspecOption::AbstractFunctionNondet}\n\t};\n\tif (options.count(_option))\n\t\treturn options.at(_option);\n\treturn {};\n}\n\nstd::set<CHC::CHCNatspecOption> CHC::smtNatspecTags(FunctionDefinition const& _function)\n{\n\tstd::set<CHC::CHCNatspecOption> options;\n\tstd::string smtStr = \"custom:smtchecker\";\n\tbool errorSeen = false;\n\tfor (auto const& [tag, value]: _function.annotation().docTags)\n\t\tif (tag == smtStr)\n\t\t{\n\t\t\tstd::string const& content = value.content;\n\t\t\tif (auto option = natspecOptionFromString(content))\n\t\t\t\toptions.insert(*option);\n\t\t\telse if (!errorSeen)\n\t\t\t{\n\t\t\t\terrorSeen = true;\n\t\t\t\tm_errorReporter.warning(3130_error, _function.location(), \"Unknown option for \\\"\" + smtStr + \"\\\": \\\"\" + content + \"\\\"\");\n\t\t\t}\n\t\t}\n\treturn options;\n}\n\nbool CHC::abstractAsNondet(FunctionDefinition const& _function)\n{\n\treturn smtNatspecTags(_function).count(CHCNatspecOption::AbstractFunctionNondet);\n}\n\nSortPointer CHC::sort(FunctionDefinition const& _function)\n{\n\treturn functionBodySort(_function, m_currentContract, state());\n}\n\nbool CHC::encodeExternalCallsAsTrusted()\n{\n\treturn m_settings.externalCalls.isTrusted();\n}\n\nSortPointer CHC::sort(ASTNode const* _node)\n{\n\tif (auto funDef = dynamic_cast<FunctionDefinition const*>(_node))\n\t\treturn sort(*funDef);\n\n\tsolAssert(m_currentFunction, \"\");\n\treturn functionBodySort(*m_currentFunction, m_currentContract, state());\n}\n\nPredicate const* CHC::createSymbolicBlock(SortPointer _sort, std::string const& _name, PredicateType _predType, ASTNode const* _node, ContractDefinition const* _contractContext)\n{\n\tauto const* block = Predicate::create(_sort, _name, _predType, m_context, _node, _contractContext, m_scopes);\n\tm_interface->registerRelation(block->functor());\n\treturn block;\n}\n\nvoid CHC::defineInterfacesAndSummaries(SourceUnit const& _source)\n{\n\tfor (auto const& node: _source.nodes())\n\t\tif (auto const* contract = dynamic_cast<ContractDefinition const*>(node.get()))\n\t\t{\n\t\t\tstd::string suffix = contract->name() + \"_\" + std::to_string(contract->id());\n\t\t\tm_interfaces[contract] = createSymbolicBlock(interfaceSort(*contract, state()), \"interface_\" + uniquePrefix() + \"_\" + suffix, PredicateType::Interface, contract, contract);\n\t\t\tm_nondetInterfaces[contract] = createSymbolicBlock(nondetInterfaceSort(*contract, state()), \"nondet_interface_\" + uniquePrefix() + \"_\" + suffix, PredicateType::NondetInterface, contract, contract);\n\t\t\tm_constructorSummaries[contract] = createConstructorBlock(*contract, \"summary_constructor\");\n\n\t\t\tfor (auto const* var: stateVariablesIncludingInheritedAndPrivate(*contract))\n\t\t\t\tif (!m_context.knownVariable(*var))\n\t\t\t\t\tcreateVariable(*var);\n\n\t\t\t/// Base nondeterministic interface that allows\n\t\t\t/// 0 steps to be taken, used as base for the inductive\n\t\t\t/// rule for each function.\n\t\t\tauto const& iface = *m_nondetInterfaces.at(contract);\n\t\t\taddRule(smtutil::Expression::implies(errorFlag().currentValue() == 0, smt::nondetInterface(iface, *contract, m_context, 0, 0)), \"base_nondet\");\n\n\t\t\tauto const& resolved = contractFunctions(*contract);\n\t\t\tfor (auto const* function: contractFunctionsWithoutVirtual(*contract) + allFreeFunctions())\n\t\t\t{\n\t\t\t\tfor (auto var: function->parameters())\n\t\t\t\t\tcreateVariable(*var);\n\t\t\t\tfor (auto var: function->returnParameters())\n\t\t\t\t\tcreateVariable(*var);\n\t\t\t\tfor (auto const* var: localVariablesIncludingModifiers(*function, contract))\n\t\t\t\t\tcreateVariable(*var);\n\n\t\t\t\tm_summaries[contract].emplace(function, createSummaryBlock(*function, *contract));\n\n\t\t\t\tif (\n\t\t\t\t\t!function->isConstructor() &&\n\t\t\t\t\tfunction->isPublic() &&\n\t\t\t\t\t// Public library functions should have interfaces only for the libraries\n\t\t\t\t\t// they're declared in.\n\t\t\t\t\t(!function->libraryFunction() || (function->scope() == contract)) &&\n\t\t\t\t\tresolved.count(function)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tm_externalSummaries[contract].emplace(function, createSummaryBlock(*function, *contract));\n\n\t\t\t\t\tauto state1 = stateVariablesAtIndex(1, *contract);\n\t\t\t\t\tauto state2 = stateVariablesAtIndex(2, *contract);\n\n\t\t\t\t\tauto errorPre = errorFlag().currentValue();\n\t\t\t\t\tauto nondetPre = smt::nondetInterface(iface, *contract, m_context, 0, 1);\n\t\t\t\t\tauto errorPost = errorFlag().increaseIndex();\n\t\t\t\t\tauto nondetPost = smt::nondetInterface(iface, *contract, m_context, 0, 2);\n\n\t\t\t\t\tstd::vector<smtutil::Expression> args =\n\t\t\t\t\t\tcommonStateExpressions(errorPost, state().thisAddress()) +\n\t\t\t\t\t\tstd::vector<smtutil::Expression>{state().tx(), state().state(1)};\n\t\t\t\t\targs += state1 +\n\t\t\t\t\t\tapplyMap(function->parameters(), [this](auto _var) { return valueAtIndex(*_var, 0); }) +\n\t\t\t\t\t\tstd::vector<smtutil::Expression>{state().state(2)} +\n\t\t\t\t\t\tstate2 +\n\t\t\t\t\t\tapplyMap(function->parameters(), [this](auto _var) { return valueAtIndex(*_var, 1); }) +\n\t\t\t\t\t\tapplyMap(function->returnParameters(), [this](auto _var) { return valueAtIndex(*_var, 1); });\n\n\t\t\t\t\tconnectBlocks(nondetPre, nondetPost, errorPre == 0 && (*m_externalSummaries.at(contract).at(function))(args));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n}\n\nvoid CHC::defineExternalFunctionInterface(FunctionDefinition const& _function, ContractDefinition const& _contract)\n{\n\t// Create a rule that represents an external call to this function.\n\t// This contains more things than the function body itself,\n\t// such as balance updates because of ``msg.value``.\n\tauto functionEntryBlock = createBlock(&_function, PredicateType::FunctionBlock);\n\tauto functionPred = predicate(*functionEntryBlock);\n\taddRule(functionPred, functionPred.name);\n\tsetCurrentBlock(*functionEntryBlock);\n\n\tm_context.addAssertion(initialConstraints(_contract, &_function));\n\tm_context.addAssertion(state().txTypeConstraints() && state().txFunctionConstraints(_function));\n\n\t// The contract may have received funds through a selfdestruct or\n\t// block.coinbase, which do not trigger calls into the contract.\n\t// So the only constraint we can add here is that the balance of\n\t// the contract grows by at least `msg.value`.\n\tSymbolicIntVariable k{TypeProvider::uint256(), TypeProvider::uint256(), \"funds_\" + std::to_string(m_context.newUniqueId()), m_context};\n\tm_context.addAssertion(k.currentValue() >= state().txMember(\"msg.value\"));\n\t// Assume that address(this).balance cannot overflow.\n\tm_context.addAssertion(smt::symbolicUnknownConstraints(state().balance(state().thisAddress()) + k.currentValue(), TypeProvider::uint256()));\n\tstate().addBalance(state().thisAddress(), k.currentValue());\n\n\tif (encodeExternalCallsAsTrusted())\n\t{\n\t\t// If the contract has state variables that are addresses to other contracts,\n\t\t// we need to encode the fact that those contracts may have been called in between\n\t\t// transactions to _contract.\n\t\t//\n\t\t// We do that by adding nondet_interface constraints for those contracts,\n\t\t// in the last line of this if block.\n\t\t//\n\t\t// If there are state variables of container types like structs or arrays\n\t\t// that indirectly contain contract types, we havoc the state for simplicity,\n\t\t// in the first part of this block.\n\t\t// TODO: This could actually be supported.\n\t\t// For structs: simply collect the SMT expressions of all the indirect contract type members.\n\t\t// For arrays: more involved, needs to traverse the array symbolically and do the same for each contract.\n\t\t// For mappings: way more complicated if the element type is a contract.\n\t\tauto hasContractOrAddressSubType = [&](VariableDeclaration const* _var) -> bool {\n\t\t\tbool foundContract = false;\n\t\t\tsolidity::util::BreadthFirstSearch<Type const*> bfs{{_var->type()}};\n\t\t\tbfs.run([&](auto _type, auto&& _addChild) {\n\t\t\t\tif (\n\t\t\t\t\t_type->category() == Type::Category::Address ||\n\t\t\t\t\t_type->category() == Type::Category::Contract\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tfoundContract = true;\n\t\t\t\t\tbfs.abort();\n\t\t\t\t}\n\t\t\t\tif (auto const* mapType = dynamic_cast<MappingType const*>(_type))\n\t\t\t\t\t_addChild(mapType->valueType());\n\t\t\t\telse if (auto const* arrayType = dynamic_cast<ArrayType const*>(_type))\n\t\t\t\t\t_addChild(arrayType->baseType());\n\t\t\t\telse if (auto const* structType = dynamic_cast<StructType const*>(_type))\n\t\t\t\t\tfor (auto const& member: structType->nativeMembers(nullptr))\n\t\t\t\t\t\t_addChild(member.type);\n\t\t\t});\n\t\t\treturn foundContract;\n\t\t};\n\t\tbool found = false;\n\t\tfor (auto var: m_currentContract->stateVariables())\n\t\t\tif (\n\t\t\t\tvar->type()->category() != Type::Category::Address &&\n\t\t\t\tvar->type()->category() != Type::Category::Contract &&\n\t\t\t\thasContractOrAddressSubType(var)\n\t\t\t)\n\t\t\t{\n\t\t\t\tfound = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\tif (found)\n\t\t\tstate().newStorage();\n\t\telse\n\t\t\taddNondetCalls(*m_currentContract);\n\t}\n\n\terrorFlag().increaseIndex();\n\tm_context.addAssertion(summaryCall(_function));\n\n\tconnectBlocks(functionPred, externalSummary(_function));\n}\n\nvoid CHC::defineContractInitializer(ContractDefinition const& _contract, ContractDefinition const& _contextContract)\n{\n\tm_contractInitializers[&_contextContract][&_contract] = createConstructorBlock(_contract, \"contract_initializer\");\n\tauto const& implicitConstructorPredicate = *createConstructorBlock(_contract, \"contract_initializer_entry\");\n\n\tauto implicitFact = smt::constructor(implicitConstructorPredicate, m_context);\n\taddRule(smtutil::Expression::implies(initialConstraints(_contract), implicitFact), implicitFact.name);\n\tsetCurrentBlock(implicitConstructorPredicate);\n\n\tauto prevErrorDest = m_errorDest;\n\tm_errorDest = m_contractInitializers.at(&_contextContract).at(&_contract);\n\tfor (auto var: _contract.stateVariables())\n\t\tif (var->value())\n\t\t{\n\t\t\tvar->value()->accept(*this);\n\t\t\tassignment(*var, *var->value());\n\t\t}\n\tm_errorDest = prevErrorDest;\n\n\tauto const& afterInit = *createConstructorBlock(_contract, \"contract_initializer_after_init\");\n\tconnectBlocks(m_currentBlock, predicate(afterInit));\n\tsetCurrentBlock(afterInit);\n\n\tif (auto constructor = _contract.constructor())\n\t{\n\t\terrorFlag().increaseIndex();\n\t\tm_context.addAssertion(smt::functionCall(*m_summaries.at(&_contextContract).at(constructor), &_contextContract, m_context));\n\t\tconnectBlocks(m_currentBlock, initializer(_contract, _contextContract), errorFlag().currentValue() > 0);\n\t\tm_context.addAssertion(errorFlag().currentValue() == 0);\n\t}\n\n\tconnectBlocks(m_currentBlock, initializer(_contract, _contextContract));\n}\n\nsmtutil::Expression CHC::interface()\n{\n\tsolAssert(m_currentContract, \"\");\n\treturn interface(*m_currentContract);\n}\n\nsmtutil::Expression CHC::interface(ContractDefinition const& _contract)\n{\n\treturn ::interface(*m_interfaces.at(&_contract), _contract, m_context);\n}\n\nsmtutil::Expression CHC::error()\n{\n\treturn (*m_errorPredicate)({});\n}\n\nsmtutil::Expression CHC::initializer(ContractDefinition const& _contract, ContractDefinition const& _contractContext)\n{\n\treturn predicate(*m_contractInitializers.at(&_contractContext).at(&_contract));\n}\n\nsmtutil::Expression CHC::summary(ContractDefinition const& _contract)\n{\n\treturn predicate(*m_constructorSummaries.at(&_contract));\n}\n\nsmtutil::Expression CHC::summary(FunctionDefinition const& _function, ContractDefinition const& _contract)\n{\n\treturn smt::function(*m_summaries.at(&_contract).at(&_function), &_contract, m_context);\n}\n\nsmtutil::Expression CHC::summary(FunctionDefinition const& _function)\n{\n\tsolAssert(m_currentContract, \"\");\n\treturn summary(_function, *m_currentContract);\n}\n\nsmtutil::Expression CHC::summaryCall(FunctionDefinition const& _function, ContractDefinition const& _contract)\n{\n\treturn smt::functionCall(*m_summaries.at(&_contract).at(&_function), &_contract, m_context);\n}\n\nsmtutil::Expression CHC::summaryCall(FunctionDefinition const& _function)\n{\n\tsolAssert(m_currentContract, \"\");\n\treturn summaryCall(_function, *m_currentContract);\n}\n\nsmtutil::Expression CHC::externalSummary(FunctionDefinition const& _function, ContractDefinition const& _contract)\n{\n\treturn smt::function(*m_externalSummaries.at(&_contract).at(&_function), &_contract, m_context);\n}\n\nsmtutil::Expression CHC::externalSummary(FunctionDefinition const& _function)\n{\n\tsolAssert(m_currentContract, \"\");\n\treturn externalSummary(_function, *m_currentContract);\n}\n\nPredicate const* CHC::createBlock(ASTNode const* _node, PredicateType _predType, std::string const& _prefix)\n{\n\tauto block = createSymbolicBlock(\n\t\tsort(_node),\n\t\t\"block_\" + uniquePrefix() + \"_\" + _prefix + predicateName(_node),\n\t\t_predType,\n\t\t_node,\n\t\tm_currentContract\n\t);\n\n\tsolAssert(m_currentFunction, \"\");\n\treturn block;\n}\n\nPredicate const* CHC::createSummaryBlock(FunctionDefinition const& _function, ContractDefinition const& _contract, PredicateType _type)\n{\n\treturn createSymbolicBlock(\n\t\tfunctionSort(_function, &_contract, state()),\n\t\t\"summary_\" + uniquePrefix() + \"_\" + predicateName(&_function, &_contract),\n\t\t_type,\n\t\t&_function,\n\t\t&_contract\n\t);\n}\n\nPredicate const* CHC::createConstructorBlock(ContractDefinition const& _contract, std::string const& _prefix)\n{\n\treturn createSymbolicBlock(\n\t\tconstructorSort(_contract, state()),\n\t\t_prefix + \"_\" + uniquePrefix() + \"_\" + contractSuffix(_contract),\n\t\tPredicateType::ConstructorSummary,\n\t\t&_contract,\n\t\t&_contract\n\t);\n}\n\nvoid CHC::createErrorBlock()\n{\n\tm_errorPredicate = createSymbolicBlock(\n\t\tarity0FunctionSort(),\n\t\t\"error_target_\" + std::to_string(m_context.newUniqueId()),\n\t\tPredicateType::Error\n\t);\n}\n\nvoid CHC::connectBlocks(smtutil::Expression const& _from, smtutil::Expression const& _to, smtutil::Expression const& _constraints)\n{\n\tsmtutil::Expression edge = smtutil::Expression::implies(\n\t\t_from && m_context.assertions() && _constraints,\n\t\t_to\n\t);\n\taddRule(edge, _from.name + \"_to_\" + _to.name);\n}\n\nsmtutil::Expression CHC::initialConstraints(ContractDefinition const& _contract, FunctionDefinition const* _function)\n{\n\tsmtutil::Expression conj = state().state() == state().state(0);\n\tconj = conj && errorFlag().currentValue() == 0;\n\tconj = conj && currentEqualInitialVarsConstraints(stateVariablesIncludingInheritedAndPrivate(_contract));\n\n\tFunctionDefinition const* function = _function ? _function : _contract.constructor();\n\tif (function)\n\t\tconj = conj && currentEqualInitialVarsConstraints(applyMap(function->parameters(), [](auto&& _var) -> VariableDeclaration const* { return _var.get(); }));\n\n\treturn conj;\n}\n\nstd::vector<smtutil::Expression> CHC::initialStateVariables()\n{\n\treturn stateVariablesAtIndex(0);\n}\n\nstd::vector<smtutil::Expression> CHC::stateVariablesAtIndex(unsigned _index)\n{\n\tsolAssert(m_currentContract, \"\");\n\treturn stateVariablesAtIndex(_index, *m_currentContract);\n}\n\nstd::vector<smtutil::Expression> CHC::stateVariablesAtIndex(unsigned _index, ContractDefinition const& _contract)\n{\n\treturn applyMap(\n\t\tSMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract),\n\t\t[&](auto _var) { return valueAtIndex(*_var, _index); }\n\t);\n}\n\nstd::vector<smtutil::Expression> CHC::currentStateVariables()\n{\n\tsolAssert(m_currentContract, \"\");\n\treturn currentStateVariables(*m_currentContract);\n}\n\nstd::vector<smtutil::Expression> CHC::currentStateVariables(ContractDefinition const& _contract)\n{\n\treturn applyMap(SMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract), [this](auto _var) { return currentValue(*_var); });\n}\n\nsmtutil::Expression CHC::currentEqualInitialVarsConstraints(std::vector<VariableDeclaration const*> const& _vars) const\n{\n\treturn fold(_vars, smtutil::Expression(true), [this](auto&& _conj, auto _var) {\n\t\treturn std::move(_conj) && currentValue(*_var) == m_context.variable(*_var)->valueAtIndex(0);\n\t});\n}\n\nstd::string CHC::predicateName(ASTNode const* _node, ContractDefinition const* _contract)\n{\n\tstd::string prefix;\n\tif (auto funDef = dynamic_cast<FunctionDefinition const*>(_node))\n\t{\n\t\tprefix += TokenTraits::toString(funDef->kind());\n\t\tif (!funDef->name().empty())\n\t\t\tprefix += \"_\" + funDef->name() + \"_\";\n\t}\n\telse if (m_currentFunction && !m_currentFunction->name().empty())\n\t\tprefix += m_currentFunction->name();\n\n\tauto contract = _contract ? _contract : m_currentContract;\n\tsolAssert(contract, \"\");\n\treturn prefix + \"_\" + std::to_string(_node->id()) + \"_\" + std::to_string(contract->id());\n}\n\nsmtutil::Expression CHC::predicate(Predicate const& _block)\n{\n\tswitch (_block.type())\n\t{\n\tcase PredicateType::Interface:\n\t\tsolAssert(m_currentContract, \"\");\n\t\treturn ::interface(_block, *m_currentContract, m_context);\n\tcase PredicateType::ConstructorSummary:\n\t\treturn constructor(_block, m_context);\n\tcase PredicateType::FunctionSummary:\n\tcase PredicateType::InternalCall:\n\tcase PredicateType::ExternalCallTrusted:\n\tcase PredicateType::ExternalCallUntrusted:\n\t\treturn smt::function(_block, m_currentContract, m_context);\n\tcase PredicateType::FunctionBlock:\n\tcase PredicateType::FunctionErrorBlock:\n\t\tsolAssert(m_currentFunction, \"\");\n\t\treturn functionBlock(_block, *m_currentFunction, m_currentContract, m_context);\n\tcase PredicateType::Error:\n\t\treturn _block({});\n\tcase PredicateType::NondetInterface:\n\t\t// Nondeterministic interface predicates are handled differently.\n\t\tsolAssert(false, \"\");\n\tcase PredicateType::Custom:\n\t\t// Custom rules are handled separately.\n\t\tsolAssert(false, \"\");\n\t}\n\tsolAssert(false, \"\");\n}\n\nsmtutil::Expression CHC::predicate(\n\tFunctionDefinition const* _funDef,\n\tstd::optional<Expression const*> _boundArgumentCall,\n\tFunctionType const* _funType,\n\tstd::vector<Expression const*> _arguments,\n\tsmtutil::Expression _contractAddressValue\n)\n{\n\tsolAssert(_funType, \"\");\n\tauto kind = _funType->kind();\n\tsolAssert(kind == FunctionType::Kind::Internal || kind == FunctionType::Kind::External || kind == FunctionType::Kind::BareStaticCall, \"\");\n\tif (!_funDef)\n\t\treturn smtutil::Expression(true);\n\n\terrorFlag().increaseIndex();\n\n\tstd::vector<smtutil::Expression> args =\n\t\tcommonStateExpressions(errorFlag().currentValue(), _contractAddressValue) +\n\t\tstd::vector<smtutil::Expression>{state().tx(), state().state()};\n\n\tauto const* contract = _funDef->annotation().contract;\n\tauto const& hierarchy = m_currentContract->annotation().linearizedBaseContracts;\n\tsolAssert(kind != FunctionType::Kind::Internal || _funDef->isFree() || (contract && contract->isLibrary()) || util::contains(hierarchy, contract), \"\");\n\n\tif (kind == FunctionType::Kind::Internal)\n\t\tcontract = m_currentContract;\n\n\targs += currentStateVariables(*contract);\n\targs += symbolicArguments(_funDef->parameters(), _arguments, _boundArgumentCall);\n\tif (!usesStaticCall(_funDef, _funType))\n\t{\n\t\tstate().newState();\n\t\tfor (auto const& var: stateVariablesIncludingInheritedAndPrivate(*contract))\n\t\t\tm_context.variable(*var)->increaseIndex();\n\t}\n\targs += std::vector<smtutil::Expression>{state().state()};\n\targs += currentStateVariables(*contract);\n\n\tfor (auto var: _funDef->parameters() + _funDef->returnParameters())\n\t{\n\t\tif (m_context.knownVariable(*var))\n\t\t\tm_context.variable(*var)->increaseIndex();\n\t\telse\n\t\t\tcreateVariable(*var);\n\t\targs.push_back(currentValue(*var));\n\t}\n\n\tPredicate const& summary = *m_summaries.at(contract).at(_funDef);\n\tauto from = smt::function(summary, contract, m_context);\n\tPredicate const& callPredicate = *createSummaryBlock(\n\t\t*_funDef,\n\t\t*contract,\n\t\tkind == FunctionType::Kind::Internal ? PredicateType::InternalCall : PredicateType::ExternalCallTrusted\n\t);\n\tauto to = smt::function(callPredicate, contract, m_context);\n\taddRule(smtutil::Expression::implies(from, to), to.name);\n\n\treturn callPredicate(args);\n}\n\nvoid CHC::addRule(smtutil::Expression const& _rule, std::string const& _ruleName)\n{\n\tm_interface->addRule(_rule, _ruleName);\n}\n\nCHCSolverInterface::QueryResult CHC::query(smtutil::Expression const& _query, langutil::SourceLocation const& _location)\n{\n\tif (m_settings.printQuery)\n\t{\n\t\tauto smtLibInterface = dynamic_cast<CHCSmtLib2Interface*>(m_interface.get());\n\t\tsolAssert(smtLibInterface, \"Requested to print queries but CHCSmtLib2Interface not available\");\n\t\tstd::string smtLibCode = smtLibInterface->dumpQuery(_query);\n\t\tm_errorReporter.info(\n\t\t\t2339_error,\n\t\t\t\"CHC: Requested query:\\n\" + smtLibCode\n\t\t);\n\t\treturn {.answer = CheckResult::UNKNOWN, .invariants = {}, .cex = {}};\n\t}\n\tauto result = m_interface->query(_query);\n\tswitch (result.answer)\n\t{\n\tcase CheckResult::SATISFIABLE:\n\tcase CheckResult::UNSATISFIABLE:\n\tcase CheckResult::UNKNOWN:\n\t\tbreak;\n\tcase CheckResult::CONFLICTING:\n\t\tm_errorReporter.warning(1988_error, _location, \"CHC: At least two SMT solvers provided conflicting answers. Results might not be sound.\");\n\t\tbreak;\n\tcase CheckResult::ERROR:\n\t\tm_errorReporter.warning(1218_error, _location, \"CHC: Error during interaction with the solver.\");\n\t\tbreak;\n\t}\n\treturn result;\n}\n\nvoid CHC::verificationTargetEncountered(\n\tASTNode const* const _errorNode,\n\tVerificationTargetType _type,\n\tsmtutil::Expression const& _errorCondition\n)\n{\n\tif (!m_settings.targets.has(_type))\n\t\treturn;\n\n\tif (!(m_currentContract || m_currentFunction))\n\t\treturn;\n\n\tbool scopeIsFunction = m_currentFunction && !m_currentFunction->isConstructor();\n\tauto errorId = newErrorId();\n\tsolAssert(m_verificationTargets.count(errorId) == 0, \"Error ID is not unique!\");\n\tm_verificationTargets.emplace(errorId, CHCVerificationTarget{{_type, _errorCondition, smtutil::Expression(true)}, errorId, _errorNode});\n\tif (scopeIsFunction)\n\t\tm_functionTargetIds[m_currentFunction].push_back(errorId);\n\telse\n\t\tm_functionTargetIds[m_currentContract].push_back(errorId);\n\tauto previousError = errorFlag().currentValue();\n\terrorFlag().increaseIndex();\n\tauto extendedErrorCondition = currentPathConditions() && _errorCondition;\n\n\tPredicate const* localBlock = m_currentFunction ?\n\t\tcreateBlock(m_currentFunction, PredicateType::FunctionErrorBlock) :\n\t\tcreateConstructorBlock(*m_currentContract, \"local_error\");\n\n\tauto pred = predicate(*localBlock);\n\tconnectBlocks(\n\t\tm_currentBlock,\n\t\tpred,\n\t\textendedErrorCondition && errorFlag().currentValue() == errorId\n\t);\n\tsolAssert(m_errorDest, \"\");\n\taddRule(smtutil::Expression::implies(pred, predicate(*m_errorDest)), pred.name);\n\n\tm_context.addAssertion(errorFlag().currentValue() == previousError);\n}\n\nstd::pair<std::string, ErrorId> CHC::targetDescription(CHCVerificationTarget const& _target)\n{\n\tif (_target.type == VerificationTargetType::PopEmptyArray)\n\t{\n\t\tsolAssert(dynamic_cast<FunctionCall const*>(_target.errorNode), \"\");\n\t\treturn {\"Empty array \\\"pop\\\"\", 2529_error};\n\t}\n\telse if (_target.type == VerificationTargetType::OutOfBounds)\n\t{\n\t\tsolAssert(dynamic_cast<IndexAccess const*>(_target.errorNode), \"\");\n\t\treturn {\"Out of bounds access\", 6368_error};\n\t}\n\telse if (\n\t\t_target.type == VerificationTargetType::Underflow ||\n\t\t_target.type == VerificationTargetType::Overflow\n\t)\n\t{\n\t\tauto const* expr = dynamic_cast<Expression const*>(_target.errorNode);\n\t\tsolAssert(expr, \"\");\n\t\tauto const* intType = dynamic_cast<IntegerType const*>(expr->annotation().type);\n\t\tif (!intType)\n\t\t\tintType = TypeProvider::uint256();\n\n\t\tif (_target.type == VerificationTargetType::Underflow)\n\t\t\treturn {\n\t\t\t\t\"Underflow (resulting value less than \" + formatNumberReadable(intType->minValue()) + \")\",\n\t\t\t\t3944_error\n\t\t\t};\n\n\t\treturn {\n\t\t\t\"Overflow (resulting value larger than \" + formatNumberReadable(intType->maxValue()) + \")\",\n\t\t\t4984_error\n\t\t};\n\t}\n\telse if (_target.type == VerificationTargetType::DivByZero)\n\t\treturn {\"Division by zero\", 4281_error};\n\telse if (_target.type == VerificationTargetType::Assert)\n\t\treturn {\"Assertion violation\", 6328_error};\n\telse if (_target.type == VerificationTargetType::Balance)\n\t\treturn {\"Insufficient funds\", 8656_error};\n\telse\n\t\tsolAssert(false);\n}\n\nvoid CHC::checkVerificationTargets()\n{\n\t// The verification conditions have been collected per function where they have been encountered (m_verificationTargets).\n\t// Also, all possible contexts in which an external function can be called has been recorded (m_queryPlaceholders).\n\t// Here we combine every context in which an external function can be called with all possible verification conditions\n\t// in its call graph. Each such combination forms a unique verification target.\n\tstd::map<unsigned, std::vector<CHCQueryPlaceholder>> targetEntryPoints;\n\tfor (auto const& [function, placeholders]: m_queryPlaceholders)\n\t{\n\t\tauto functionTargets = transactionVerificationTargetsIds(function);\n\t\tfor (auto const& placeholder: placeholders)\n\t\t\tfor (unsigned id: functionTargets)\n\t\t\t\ttargetEntryPoints[id].push_back(placeholder);\n\t}\n\n\tstd::set<unsigned> checkedErrorIds;\n\tfor (auto const& [targetId, placeholders]: targetEntryPoints)\n\t{\n\t\tauto const& target = m_verificationTargets.at(targetId);\n\t\tauto [errorType, errorReporterId] = targetDescription(target);\n\n\t\tcheckAndReportTarget(target, placeholders, errorReporterId, errorType + \" happens here.\", errorType + \" might happen here.\");\n\t\tcheckedErrorIds.insert(target.errorId);\n\t}\n\n\tauto toReport = m_unsafeTargets;\n\tif (m_settings.showUnproved)\n\t\tfor (auto const& [node, targets]: m_unprovedTargets)\n\t\t\tfor (auto const& [target, info]: targets)\n\t\t\t\ttoReport[node].emplace(target, info);\n\n\tfor (auto const& [node, targets]: toReport)\n\t\tfor (auto const& [target, info]: targets)\n\t\t\tm_errorReporter.warning(\n\t\t\t\tinfo.error,\n\t\t\t\tinfo.location,\n\t\t\t\tinfo.message\n\t\t\t);\n\n\tif (!m_settings.showUnproved && !m_unprovedTargets.empty())\n\t\tm_errorReporter.warning(\n\t\t\t5840_error,\n\t\t\t{},\n\t\t\t\"CHC: \" +\n\t\t\tstd::to_string(m_unprovedTargets.size()) +\n\t\t\t\" verification condition(s) could not be proved.\" +\n\t\t\t\" Enable the model checker option \\\"show unproved\\\" to see all of them.\" +\n\t\t\t\" Consider choosing a specific contract to be verified in order to reduce the solving problems.\" +\n\t\t\t\" Consider increasing the timeout per query.\"\n\t\t);\n\n\tif (!m_settings.showProvedSafe && !m_safeTargets.empty())\n\t{\n\t\tstd::size_t provedSafeNum = 0;\n\t\tfor (auto&& [_, targets]: m_safeTargets)\n\t\t\tprovedSafeNum += targets.size();\n\t\tm_errorReporter.info(\n\t\t\t1391_error,\n\t\t\t\"CHC: \" +\n\t\t\tstd::to_string(provedSafeNum) +\n\t\t\t\" verification condition(s) proved safe!\" +\n\t\t\t\" Enable the model checker option \\\"show proved safe\\\" to see all of them.\"\n\t\t);\n\t}\n\telse if (m_settings.showProvedSafe)\n\t\tfor (auto const& [node, targets]: m_safeTargets)\n\t\t\tfor (auto const& target: targets)\n\t\t\t\tm_provedSafeReporter.info(\n\t\t\t\t\t9576_error,\n\t\t\t\t\tnode->location(),\n\t\t\t\t\t\"CHC: \" +\n\t\t\t\t\ttargetDescription(target).first +\n\t\t\t\t\t\" check is safe!\"\n\t\t\t\t);\n\n\tif (!m_settings.invariants.invariants.empty())\n\t{\n\t\tstd::string msg;\n\t\tfor (auto pred: m_invariants | ranges::views::keys)\n\t\t{\n\t\t\tASTNode const* node = pred->programNode();\n\t\t\tstd::string what;\n\t\t\tif (auto contract = dynamic_cast<ContractDefinition const*>(node))\n\t\t\t\twhat = contract->fullyQualifiedName();\n\t\t\telse\n\t\t\t\tsolAssert(false, \"\");\n\n\t\t\tstd::string invType;\n\t\t\tif (pred->type() == PredicateType::Interface)\n\t\t\t\tinvType = \"Contract invariant(s)\";\n\t\t\telse if (pred->type() == PredicateType::NondetInterface)\n\t\t\t\tinvType = \"Reentrancy property(ies)\";\n\t\t\telse\n\t\t\t\tsolAssert(false, \"\");\n\n\t\t\tmsg += invType + \" for \" + what + \":\\n\";\n\t\t\tfor (auto const& inv: m_invariants.at(pred))\n\t\t\t\tmsg += inv + \"\\n\";\n\t\t}\n\t\tif (msg.find(\"<errorCode>\") != std::string::npos)\n\t\t{\n\t\t\tstd::set<unsigned> seenErrors;\n\t\t\tmsg += \"<errorCode> = 0 -> no errors\\n\";\n\t\t\tfor (auto const& [id, target]: m_verificationTargets)\n\t\t\t\tif (!seenErrors.count(target.errorId))\n\t\t\t\t{\n\t\t\t\t\tseenErrors.insert(target.errorId);\n\t\t\t\t\tstd::string loc = std::string(m_charStreamProvider.charStream(*target.errorNode->location().sourceName).text(target.errorNode->location()));\n\t\t\t\t\tmsg += \"<errorCode> = \" + std::to_string(target.errorId) + \" -> \" + ModelCheckerTargets::targetTypeToString.at(target.type) + \" at \" + loc + \"\\n\";\n\n\t\t\t\t}\n\t\t}\n\t\tif (!msg.empty())\n\t\t\tm_errorReporter.info(1180_error, msg);\n\t}\n\n\t// There can be targets in internal functions that are not reachable from the external interface.\n\t// These are safe by definition and are not even checked by the CHC engine, but this information\n\t// must still be reported safe by the BMC engine.\n\tstd::set<unsigned> allErrorIds;\n\tfor (auto const& entry: m_functionTargetIds)\n\t\tfor (unsigned id: entry.second)\n\t\t\tallErrorIds.insert(id);\n\n\tstd::set<unsigned> unreachableErrorIds;\n\tset_difference(\n\t\tallErrorIds.begin(),\n\t\tallErrorIds.end(),\n\t\tcheckedErrorIds.begin(),\n\t\tcheckedErrorIds.end(),\n\t\tinserter(unreachableErrorIds, unreachableErrorIds.begin())\n\t);\n\tfor (auto id: unreachableErrorIds)\n\t\tm_safeTargets[m_verificationTargets.at(id).errorNode].insert(m_verificationTargets.at(id));\n}\n\nnamespace\n{\nstd::map<Predicate const*, std::set<std::string>> collectInvariants(\n\tCHCSmtLib2Interface::Invariants const& _invariants,\n\tstd::set<Predicate const*> const& _predicates,\n\tModelCheckerInvariants const& _invariantsSetting\n)\n{\n\tstd::set<std::string> targets;\n\tif (_invariantsSetting.has(InvariantType::Contract))\n\t\ttargets.insert(\"interface_\");\n\tif (_invariantsSetting.has(InvariantType::Reentrancy))\n\t\ttargets.insert(\"nondet_interface_\");\n\n\tstd::map<Predicate const*, std::set<std::string>> invariants;\n\tfor (auto const* pred: _predicates)\n\t{\n\t\tsmtAssert(pred);\n\t\tauto const& predName = pred->functor().name;\n\t\tif (!_invariants.contains(predName))\n\t\t\tcontinue;\n\t\tif (ranges::none_of(targets, [&](auto const& _target) { return predName.starts_with(_target); }))\n\t\t\tcontinue;\n\n\t\tsmtAssert(pred->contextContract());\n\n\t\tauto const& [definition, formalArguments] = _invariants.at(predName);\n\n\t\tauto r = substitute(definition, pred->expressionSubstitution(formalArguments));\n\t\t// No point in reporting true/false as invariants.\n\t\tif (r.name != \"true\" && r.name != \"false\")\n\t\t\tinvariants[pred].insert(toSolidityStr(r));\n\t}\n\treturn invariants;\n}\n} // namespace\n\nvoid CHC::checkAndReportTarget(\n\tCHCVerificationTarget const& _target,\n\tstd::vector<CHCQueryPlaceholder> const& _placeholders,\n\tErrorId _errorReporterId,\n\tstd::string _satMsg,\n\tstd::string _unknownMsg\n)\n{\n\tif (m_unsafeTargets.count(_target.errorNode) && m_unsafeTargets.at(_target.errorNode).count(_target.type))\n\t\treturn;\n\n\tcreateErrorBlock();\n\tfor (auto const& placeholder: _placeholders)\n\t\tconnectBlocks(\n\t\t\tplaceholder.fromPredicate,\n\t\t\terror(),\n\t\t\tplaceholder.constraints && placeholder.errorExpression == _target.errorId\n\t\t);\n\tauto const& location = _target.errorNode->location();\n\tauto [result, invariants, model] = query(error(), location);\n\tif (result == CheckResult::UNSATISFIABLE)\n\t{\n\t\tm_safeTargets[_target.errorNode].insert(_target);\n\t\tstd::set<Predicate const*> predicates;\n\t\tfor (auto const* pred: m_interfaces | ranges::views::values)\n\t\t\tpredicates.insert(pred);\n\t\tfor (auto const* pred: m_nondetInterfaces | ranges::views::values)\n\t\t\tpredicates.insert(pred);\n\t\tstd::map<Predicate const*, std::set<std::string>> invariantStrings = collectInvariants(invariants, predicates, m_settings.invariants);\n\t\tfor (auto pred: invariantStrings | ranges::views::keys)\n\t\t\tm_invariants[pred] += std::move(invariantStrings.at(pred));\n\t}\n\telse if (result == CheckResult::SATISFIABLE)\n\t{\n\t\tsolAssert(!_satMsg.empty());\n\t\tif (auto it = m_safeTargets.find(_target.errorNode); it != m_safeTargets.end())\n\t\t{\n\t\t\tstd::erase_if(it->second, [&](auto const& target) { return target.type == _target.type; });\n\t\t\tif (it->second.empty())\n\t\t\t\tm_safeTargets.erase(it);\n\t\t}\n\t\tauto cex = generateCounterexample(model, error().name);\n\t\tif (cex)\n\t\t\tm_unsafeTargets[_target.errorNode][_target.type] = {\n\t\t\t\t_errorReporterId,\n\t\t\t\tlocation,\n\t\t\t\t\"CHC: \" + _satMsg + \"\\nCounterexample:\\n\" + *cex\n\t\t\t};\n\t\telse\n\t\t\tm_unsafeTargets[_target.errorNode][_target.type] = {\n\t\t\t\t_errorReporterId,\n\t\t\t\tlocation,\n\t\t\t\t\"CHC: \" + _satMsg\n\t\t\t};\n\t}\n\telse if (!_unknownMsg.empty())\n\t\tm_unprovedTargets[_target.errorNode][_target.type] = {\n\t\t\t_errorReporterId,\n\t\t\tlocation,\n\t\t\t\"CHC: \" + _unknownMsg\n\t\t};\n}\n\n/**\nThe counterexample DAG has the following properties:\n1) The root node represents the reachable error predicate.\n2) The root node has 1 or 2 children:\n\t- One of them is the summary of the function that was called and led to that node.\n\tIf this is the only child, this function must be the constructor.\n\t- If it has 2 children, the function is not the constructor and the other child is the interface node,\n\tthat is, it represents the state of the contract before the function described above was called.\n3) Interface nodes also have property 2.\n\nWe run a BFS on the DAG from the root node collecting the reachable function summaries from the given node.\nWhen a function summary is seen, the search continues with that summary as the new root for its subgraph.\nThe result of the search is a callgraph containing:\n- Functions calls needed to reach the root node, that is, transaction entry points.\n- Functions called by other functions (internal calls or external calls/internal transactions).\nThe BFS visit order and the shape of the DAG described in the previous paragraph guarantee that the order of\nthe function summaries in the callgraph of the error node is the reverse transaction trace.\n\nThe first function summary seen contains the values for the state, input and output variables at the\nerror point.\n*/\nstd::optional<std::string> CHC::generateCounterexample(CHCSolverInterface::CexGraph const& _graph, std::string const& _root)\n{\n\tstd::optional<unsigned> rootId;\n\tfor (auto const& [id, node]: _graph.nodes)\n\t\tif (node.name == _root)\n\t\t{\n\t\t\trootId = id;\n\t\t\tbreak;\n\t\t}\n\tif (!rootId)\n\t\treturn {};\n\n\tstd::vector<std::string> path;\n\tstd::string localState;\n\n\tauto callGraph = summaryCalls(_graph, *rootId);\n\n\tauto nodePred = [&](auto _node) { return Predicate::predicate(_graph.nodes.at(_node).name); };\n\tauto nodeArgs = [&](auto _node) { return _graph.nodes.at(_node).arguments; };\n\n\tbool first = true;\n\tfor (auto summaryId: callGraph.at(*rootId))\n\t{\n\t\tCHCSolverInterface::CexNode const& summaryNode = _graph.nodes.at(summaryId);\n\t\tPredicate const* summaryPredicate = Predicate::predicate(summaryNode.name);\n\t\tauto const& summaryArgs = summaryNode.arguments;\n\n\t\tif (!summaryPredicate->programVariable())\n\t\t{\n\t\t\tauto stateVars = summaryPredicate->stateVariables();\n\t\t\tsolAssert(stateVars.has_value(), \"\");\n\t\t\tauto stateValues = summaryPredicate->summaryStateValues(summaryArgs);\n\t\t\tsolAssert(stateValues.size() == stateVars->size(), \"\");\n\n\t\t\tif (first)\n\t\t\t{\n\t\t\t\tfirst = false;\n\t\t\t\t/// Generate counterexample message local to the failed target.\n\t\t\t\tlocalState = formatVariableModel(*stateVars, stateValues, \", \") + \"\\n\";\n\n\t\t\t\tif (auto calledFun = summaryPredicate->programFunction())\n\t\t\t\t{\n\t\t\t\t\tauto inValues = summaryPredicate->summaryPostInputValues(summaryArgs);\n\t\t\t\t\tauto const& inParams = calledFun->parameters();\n\t\t\t\t\tif (auto inStr = formatVariableModel(inParams, inValues, \"\\n\"); !inStr.empty())\n\t\t\t\t\t\tlocalState += inStr + \"\\n\";\n\t\t\t\t\tauto outValues = summaryPredicate->summaryPostOutputValues(summaryArgs);\n\t\t\t\t\tauto const& outParams = calledFun->returnParameters();\n\t\t\t\t\tif (auto outStr = formatVariableModel(outParams, outValues, \"\\n\"); !outStr.empty())\n\t\t\t\t\t\tlocalState += outStr + \"\\n\";\n\n\t\t\t\t\tstd::optional<unsigned> localErrorId;\n\t\t\t\t\tsolidity::util::BreadthFirstSearch<unsigned> bfs{{summaryId}};\n\t\t\t\t\tbfs.run([&](auto _nodeId, auto&& _addChild) {\n\t\t\t\t\t\tauto const& children = _graph.edges.at(_nodeId);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tchildren.size() == 1 &&\n\t\t\t\t\t\t\tnodePred(children.front())->isFunctionErrorBlock()\n\t\t\t\t\t\t)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlocalErrorId = children.front();\n\t\t\t\t\t\t\tbfs.abort();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tranges::for_each(children, _addChild);\n\t\t\t\t\t});\n\n\t\t\t\t\tif (localErrorId.has_value())\n\t\t\t\t\t{\n\t\t\t\t\t\tauto const* localError = nodePred(*localErrorId);\n\t\t\t\t\t\tsolAssert(localError && localError->isFunctionErrorBlock(), \"\");\n\t\t\t\t\t\tauto const [localValues, localVars] = localError->localVariableValues(nodeArgs(*localErrorId));\n\t\t\t\t\t\tif (auto localStr = formatVariableModel(localVars, localValues, \"\\n\"); !localStr.empty())\n\t\t\t\t\t\t\tlocalState += localStr + \"\\n\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto modelMsg = formatVariableModel(*stateVars, stateValues, \", \");\n\t\t\t\t/// We report the state after every tx in the trace except for the last, which is reported\n\t\t\t\t/// first in the code above.\n\t\t\t\tif (!modelMsg.empty())\n\t\t\t\t\tpath.emplace_back(\"State: \" + modelMsg);\n\t\t\t}\n\t\t}\n\t\tstd::string txCex = summaryPredicate->formatSummaryCall(summaryArgs, m_charStreamProvider);\n\n\t\tstd::list<std::string> calls;\n\t\tauto dfs = [&](unsigned parent, unsigned node, unsigned depth, auto&& _dfs) -> void {\n\t\t\tauto pred = nodePred(node);\n\t\t\tauto parentPred = nodePred(parent);\n\t\t\tsolAssert(pred && pred->isSummary(), \"\");\n\t\t\tsolAssert(parentPred && parentPred->isSummary(), \"\");\n\t\t\tauto callTraceSize = calls.size();\n\t\t\tif (!pred->isConstructorSummary())\n\t\t\t\tfor (unsigned v: callGraph[node])\n\t\t\t\t\t_dfs(node, v, depth + 1, _dfs);\n\n\t\t\tbool appendTxVars = pred->isConstructorSummary() || pred->isFunctionSummary() || pred->isExternalCallUntrusted();\n\n\t\t\tcalls.push_front(std::string(depth * 4, ' ') + pred->formatSummaryCall(nodeArgs(node), m_charStreamProvider, appendTxVars));\n\t\t\tif (pred->isInternalCall())\n\t\t\t\tcalls.front() += \" -- internal call\";\n\t\t\telse if (pred->isExternalCallTrusted())\n\t\t\t\tcalls.front() += \" -- trusted external call\";\n\t\t\telse if (pred->isExternalCallUntrusted())\n\t\t\t{\n\t\t\t\tcalls.front() += \" -- untrusted external call\";\n\t\t\t\tif (calls.size() > callTraceSize + 1)\n\t\t\t\t\tcalls.front() += \", synthesized as:\";\n\t\t\t}\n\t\t\telse if (pred->programVariable())\n\t\t\t{\n\t\t\t\tcalls.front() += \"-- action on external contract in state variable \\\"\" + pred->programVariable()->name() + \"\\\"\";\n\t\t\t\tif (calls.size() > callTraceSize + 1)\n\t\t\t\t\tcalls.front() += \", synthesized as:\";\n\t\t\t}\n\t\t\telse if (pred->isFunctionSummary() && parentPred->isExternalCallUntrusted())\n\t\t\t\tcalls.front() += \" -- reentrant call\";\n\t\t};\n\t\tdfs(summaryId, summaryId, 0, dfs);\n\t\tpath.emplace_back(boost::algorithm::join(calls, \"\\n\"));\n\t}\n\n\treturn localState + \"\\nTransaction trace:\\n\" + boost::algorithm::join(path | ranges::views::reverse, \"\\n\");\n}\n\nstd::map<unsigned, std::vector<unsigned>> CHC::summaryCalls(CHCSolverInterface::CexGraph const& _graph, unsigned _root)\n{\n\tstd::map<unsigned, std::vector<unsigned>> calls;\n\n\tauto compare = [&](unsigned _a, unsigned _b) {\n\t\tauto extract = [&](std::string const& _s) {\n\t\t\t// We want to sort sibling predicates in the counterexample graph by their unique predicate id.\n\t\t\t// For most predicates, this actually doesn't matter.\n\t\t\t// The cases where this matters are internal and external function calls which have the form:\n\t\t\t// summary_<CALLID>_<suffix>\n\t\t\t// nondet_call_<CALLID>_<suffix>\n\t\t\t// Those have the extra unique <CALLID> numbers based on the traversal order, and are necessary\n\t\t\t// to infer the call order so that's shown property in the counterexample trace.\n\t\t\t// For other predicates, we do not care.\n\t\t\tauto beg = _s.data();\n\t\t\twhile (beg != _s.data() + _s.size() && !isDigit(*beg)) ++beg;\n\t\t\tint result = -1;\n\t\t\tstatic_cast<void>(std::from_chars(beg, _s.data() + _s.size(), result));\n\t\t\treturn result;\n\t\t};\n\t\tauto anum = extract(_graph.nodes.at(_a).name);\n\t\tauto bnum = extract(_graph.nodes.at(_b).name);\n\t\t// The second part of the condition is needed to ensure that two different predicates are not considered equal\n\t\treturn (anum > bnum) || (anum == bnum && _graph.nodes.at(_a).name > _graph.nodes.at(_b).name);\n\t};\n\n\tstd::queue<std::pair<unsigned, unsigned>> q;\n\tq.push({_root, _root});\n\twhile (!q.empty())\n\t{\n\t\tauto [node, root] = q.front();\n\t\tq.pop();\n\n\t\tPredicate const* nodePred = Predicate::predicate(_graph.nodes.at(node).name);\n\t\tPredicate const* rootPred = Predicate::predicate(_graph.nodes.at(root).name);\n\t\tif (nodePred->isSummary() && (\n\t\t\t_root == root ||\n\t\t\tnodePred->isInternalCall() ||\n\t\t\tnodePred->isExternalCallTrusted() ||\n\t\t\tnodePred->isExternalCallUntrusted() ||\n\t\t\trootPred->isExternalCallUntrusted() ||\n\t\t\trootPred->programVariable()\n\t\t))\n\t\t{\n\t\t\tcalls[root].push_back(node);\n\t\t\troot = node;\n\t\t}\n\t\tauto const& edges = _graph.edges.at(node);\n\t\tfor (unsigned v: std::set<unsigned, decltype(compare)>(begin(edges), end(edges), compare))\n\t\t\tq.push({v, root});\n\t}\n\n\treturn calls;\n}\n\nstd::string CHC::cex2dot(CHCSolverInterface::CexGraph const& _cex)\n{\n\tstd::string dot = \"digraph {\\n\";\n\n\tauto pred = [&](CHCSolverInterface::CexNode const& _node) {\n\t\tstd::vector<std::string> args = applyMap(\n\t\t\t_node.arguments,\n\t\t\t[&](auto const& arg) { return arg.name; }\n\t\t);\n\t\treturn \"\\\"\" + _node.name + \"(\" + boost::algorithm::join(args, \", \") + \")\\\"\";\n\t};\n\n\tfor (auto const& [u, vs]: _cex.edges)\n\t\tfor (auto v: vs)\n\t\t\tdot += pred(_cex.nodes.at(v)) + \" -> \" + pred(_cex.nodes.at(u)) + \"\\n\";\n\n\tdot += \"}\";\n\treturn dot;\n}\n\nstd::string CHC::uniquePrefix()\n{\n\treturn std::to_string(m_blockCounter++);\n}\n\nstd::string CHC::contractSuffix(ContractDefinition const& _contract)\n{\n\treturn _contract.name() + \"_\" + std::to_string(_contract.id());\n}\n\nunsigned CHC::newErrorId()\n{\n\tunsigned errorId = m_context.newUniqueId();\n\t// We need to make sure the error id is not zero,\n\t// because error id zero actually means no error in the CHC encoding.\n\tif (errorId == 0)\n\t\terrorId = m_context.newUniqueId();\n\treturn errorId;\n}\n\nSymbolicIntVariable& CHC::errorFlag()\n{\n\treturn state().errorFlag();\n}\n\nvoid CHC::newTxConstraints(Expression const* _value)\n{\n\tauto txOrigin = state().txMember(\"tx.origin\");\n\tstate().newTx();\n\t// set the transaction sender as this contract\n\tm_context.addAssertion(state().txMember(\"msg.sender\") == state().thisAddress());\n\t// set the origin to be the current transaction origin\n\tm_context.addAssertion(state().txMember(\"tx.origin\") == txOrigin);\n\n\tif (_value)\n\t\t// set the msg value\n\t\tm_context.addAssertion(state().txMember(\"msg.value\") == expr(*_value));\n}\n\nfrontend::Expression const* CHC::valueOption(FunctionCallOptions const* _options)\n{\n\tif (_options)\n\t\tfor (auto&& [i, name]: _options->names() | ranges::views::enumerate)\n\t\t\tif (name && *name == \"value\")\n\t\t\t\treturn _options->options().at(i).get();\n\treturn nullptr;\n}\n\nvoid CHC::decreaseBalanceFromOptionsValue(Expression const& _value)\n{\n\tstate().addBalance(state().thisAddress(), 0 - expr(_value));\n}\n\nstd::vector<smtutil::Expression> CHC::commonStateExpressions(smtutil::Expression const& error, smtutil::Expression const& address)\n{\n\tif (state().hasBytesConcatFunction())\n\t\treturn {error, address, state().abi(), state().bytesConcat(), state().crypto()};\n\treturn {error, address, state().abi(), state().crypto()};\n}\n"
  },
  {
    "path": "libsolidity/formal/CHC.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n/**\n * Model checker based on Constrained Horn Clauses.\n *\n * A Solidity contract's CFG is encoded into a system of Horn clauses where\n * each block has a predicate and edges are rules.\n *\n * The entry block is the constructor which has no in-edges.\n * The constructor has one out-edge to an artificial block named _Interface_\n * which has in/out-edges from/to all public functions.\n *\n * Loop invariants for Interface -> Interface' are state invariants.\n */\n\n#pragma once\n\n#include <libsolidity/formal/ModelCheckerSettings.h>\n#include <libsolidity/formal/Predicate.h>\n#include <libsolidity/formal/SMTEncoder.h>\n\n#include <libsolidity/interface/ReadFile.h>\n\n#include <libsmtutil/CHCSolverInterface.h>\n\n#include <liblangutil/SourceLocation.h>\n#include <liblangutil/UniqueErrorReporter.h>\n\n#include <boost/algorithm/string/join.hpp>\n\n#include <map>\n#include <optional>\n#include <set>\n\nnamespace solidity::frontend\n{\n\nclass CHC: public SMTEncoder\n{\npublic:\n\tCHC(\n\t\tsmt::EncodingContext& _context,\n\t\tlangutil::UniqueErrorReporter& _errorReporter,\n\t\tlangutil::UniqueErrorReporter& _unsupportedErrorReporter,\n\t\tlangutil::ErrorReporter& _provedSafeReporter,\n\t\tstd::map<util::h256, std::string> const& _smtlib2Responses,\n\t\tReadCallback::Callback const& _smtCallback,\n\t\tModelCheckerSettings _settings,\n\t\tlangutil::CharStreamProvider const& _charStreamProvider\n\t);\n\n\tvoid analyze(SourceUnit const& _sources);\n\n\tstruct CHCVerificationTarget: VerificationTarget\n\t{\n\t\tunsigned const errorId;\n\t\tASTNode const* const errorNode;\n\n\t\tfriend bool operator<(CHCVerificationTarget const& _a, CHCVerificationTarget const& _b)\n\t\t{\n\t\t\tif (_a.errorNode->id() == _b.errorNode->id())\n\t\t\t\treturn _a.type < _b.type;\n\t\t\telse\n\t\t\t\treturn _a.errorNode->id() < _b.errorNode->id();\n\t\t}\n\t};\n\n\tstruct ReportTargetInfo\n\t{\n\t\tlangutil::ErrorId error;\n\t\tlangutil::SourceLocation location;\n\t\tstd::string message;\n\t};\n\n\tstd::map<ASTNode const*, std::set<CHCVerificationTarget>, smt::EncodingContext::IdCompare> const& safeTargets() const { return m_safeTargets; }\n\tstd::map<ASTNode const*, std::map<VerificationTargetType, ReportTargetInfo>, smt::EncodingContext::IdCompare> const& unsafeTargets() const { return m_unsafeTargets; }\n\n\t/// This is used if the Horn solver is not directly linked into this binary.\n\t/// @returns a list of inputs to the Horn solver that were not part of the argument to\n\t/// the constructor.\n\tstd::vector<std::string> unhandledQueries() const;\n\n\tenum class CHCNatspecOption\n\t{\n\t\tAbstractFunctionNondet\n\t};\n\nprivate:\n\t/// Visitor functions.\n\t//@{\n\tbool visit(ContractDefinition const& _node) override;\n\tvoid endVisit(ContractDefinition const& _node) override;\n\tbool visit(FunctionDefinition const& _node) override;\n\tvoid endVisit(FunctionDefinition const& _node) override;\n\tbool visit(Block const& _block) override;\n\tvoid endVisit(Block const& _block) override;\n\tbool visit(IfStatement const& _node) override;\n\tbool visit(WhileStatement const&) override;\n\tbool visit(ForStatement const&) override;\n\tvoid endVisit(ForStatement const&) override;\n\tvoid endVisit(FunctionCall const& _node) override;\n\tvoid endVisit(BinaryOperation const& _op) override;\n\tvoid endVisit(UnaryOperation const& _op) override;\n\tvoid endVisit(Break const& _node) override;\n\tvoid endVisit(Continue const& _node) override;\n\tvoid endVisit(IndexRangeAccess const& _node) override;\n\tvoid endVisit(Return const& _node) override;\n\tbool visit(TryCatchClause const&) override;\n\tvoid endVisit(TryCatchClause const&) override;\n\tbool visit(TryStatement const& _node) override;\n\n\tvoid pushInlineFrame(CallableDeclaration const& _callable) override;\n\tvoid popInlineFrame(CallableDeclaration const& _callable) override;\n\n\tvoid visitAssert(FunctionCall const& _funCall);\n\tvoid visitPublicGetter(FunctionCall const& _funCall) override;\n\tvoid visitAddMulMod(FunctionCall const& _funCall) override;\n\tvoid visitDeployment(FunctionCall const& _funCall);\n\tvoid internalFunctionCall(FunctionCall const& _funCall);\n\tvoid internalFunctionCall(\n\t\tFunctionDefinition const* _funDef,\n\t\tstd::optional<Expression const*> _boundArgumentCall,\n\t\tFunctionType const* _funType,\n\t\tstd::vector<Expression const*> const& _arguments,\n\t\tsmtutil::Expression _contractAddressValue\n\t);\n\tvoid externalFunctionCall(FunctionCall const& _funCall);\n\tvoid externalFunctionCallToTrustedCode(FunctionCall const& _funCall);\n\tvoid addNondetCalls(ContractDefinition const& _contract);\n\tvoid nondetCall(ContractDefinition const& _contract, VariableDeclaration const& _var);\n\tvoid unknownFunctionCall(FunctionCall const& _funCall);\n\tvoid makeArrayPopVerificationTarget(FunctionCall const& _arrayPop) override;\n\tvoid makeOutOfBoundsVerificationTarget(IndexAccess const& _access) override;\n\t/// Creates underflow/overflow verification targets.\n\tstd::pair<smtutil::Expression, smtutil::Expression> arithmeticOperation(\n\t\tToken _op,\n\t\tsmtutil::Expression const& _left,\n\t\tsmtutil::Expression const& _right,\n\t\tType const* _commonType,\n\t\tExpression const& _expression\n\t) override;\n\t//@}\n\n\t/// Helpers.\n\t//@{\n\tvoid resetSourceAnalysis();\n\tvoid resetContractAnalysis();\n\tvoid eraseKnowledge();\n\tvoid clearIndices(ContractDefinition const* _contract, FunctionDefinition const* _function = nullptr) override;\n\tvoid setCurrentBlock(Predicate const& _block);\n\tstd::set<unsigned> transactionVerificationTargetsIds(ASTNode const* _txRoot);\n\tbool usesStaticCall(FunctionDefinition const* _funDef, FunctionType const* _funType);\n\tbool usesStaticCall(FunctionCall const& _funCall);\n\t//@}\n\n\t/// SMT Natspec and abstraction helpers.\n\t//@{\n\t/// @returns a CHCNatspecOption enum if _option is a valid SMTChecker Natspec value\n\t/// or nullopt otherwise.\n\tstatic std::optional<CHCNatspecOption> natspecOptionFromString(std::string const& _option);\n\t/// @returns which SMTChecker options are enabled by @a _function's Natspec via\n\t/// `@custom:smtchecker <option>` or nullopt if none is used.\n\tstd::set<CHCNatspecOption> smtNatspecTags(FunctionDefinition const& _function);\n\t/// @returns true if _function is Natspec annotated to be abstracted by\n\t/// nondeterministic values.\n\tbool abstractAsNondet(FunctionDefinition const& _function);\n\n\t/// @returns true if external calls should be considered trusted.\n\t/// If that's the case, their code is used if available at compile time.\n\tbool encodeExternalCallsAsTrusted();\n\t//@}\n\n\t/// Sort helpers.\n\t//@{\n\tsmtutil::SortPointer sort(FunctionDefinition const& _function);\n\tsmtutil::SortPointer sort(ASTNode const* _block);\n\t//@}\n\n\t/// Predicate helpers.\n\t//@{\n\t/// @returns a new block of given _sort and _name.\n\tPredicate const* createSymbolicBlock(smtutil::SortPointer _sort, std::string const& _name, PredicateType _predType, ASTNode const* _node = nullptr, ContractDefinition const* _contractContext = nullptr);\n\n\t/// Creates summary predicates for all functions of all contracts\n\t/// in a given _source.\n\tvoid defineInterfacesAndSummaries(SourceUnit const& _source);\n\n\t/// Creates the rule\n\t/// summary_function \\land transaction_entry_constraints => external_summary_function\n\t/// This is needed to add these transaction entry constraints which include\n\t/// potential balance increase by external means, for example.\n\tvoid defineExternalFunctionInterface(FunctionDefinition const& _function, ContractDefinition const& _contract);\n\n\t/// Creates a CHC system that, for a given contract,\n\t/// - initializes its state variables (as 0 or given value, if any).\n\t/// - \"calls\" the explicit constructor function of the contract, if any.\n\tvoid defineContractInitializer(ContractDefinition const& _contract, ContractDefinition const& _contractContext);\n\n\t/// Interface predicate over current variables.\n\tsmtutil::Expression interface();\n\tsmtutil::Expression interface(ContractDefinition const& _contract);\n\t/// Error predicate over current variables.\n\tsmtutil::Expression error();\n\n\t/// Creates a block for the given _node.\n\tPredicate const* createBlock(ASTNode const* _node, PredicateType _predType, std::string const& _prefix = \"\");\n\t/// Creates a call block for the given function _function from contract _contract.\n\t/// The contract is needed here because of inheritance.\n\t/// There are different types of summaries, where the most common is FunctionSummary,\n\t/// but other summaries are also used for internal and external function calls.\n\tPredicate const* createSummaryBlock(\n\t\tFunctionDefinition const& _function,\n\t\tContractDefinition const& _contract,\n\t\tPredicateType _type = PredicateType::FunctionSummary\n\t);\n\n\t/// @returns a block related to @a _contract's constructor.\n\tPredicate const* createConstructorBlock(ContractDefinition const& _contract, std::string const& _prefix);\n\n\t/// Creates a new error block to be used by an assertion.\n\t/// Also registers the predicate.\n\tvoid createErrorBlock();\n\n\tvoid connectBlocks(smtutil::Expression const& _from, smtutil::Expression const& _to, smtutil::Expression const& _constraints = smtutil::Expression(true));\n\n\t/// @returns The initial constraints that set up the beginning of a function.\n\tsmtutil::Expression initialConstraints(ContractDefinition const& _contract, FunctionDefinition const* _function = nullptr);\n\n\t/// @returns the symbolic values of the state variables at the beginning\n\t/// of the current transaction.\n\tstd::vector<smtutil::Expression> initialStateVariables();\n\tstd::vector<smtutil::Expression> stateVariablesAtIndex(unsigned _index);\n\tstd::vector<smtutil::Expression> stateVariablesAtIndex(unsigned _index, ContractDefinition const& _contract);\n\t/// @returns the current symbolic values of the current state variables.\n\tstd::vector<smtutil::Expression> currentStateVariables();\n\tstd::vector<smtutil::Expression> currentStateVariables(ContractDefinition const& _contract);\n\n\t/// @returns \\bigwedge currentValue(_vars[i]) == initialState(_var[i])\n\tsmtutil::Expression currentEqualInitialVarsConstraints(std::vector<VariableDeclaration const*> const& _vars) const;\n\n\t/// @returns the predicate name for a given node.\n\tstd::string predicateName(ASTNode const* _node, ContractDefinition const* _contract = nullptr);\n\t/// @returns a predicate application after checking the predicate's type.\n\tsmtutil::Expression predicate(Predicate const& _block);\n\t/// @returns the summary predicate for the called function.\n\tsmtutil::Expression predicate(\n\t\tFunctionDefinition const* _funDef,\n\t\tstd::optional<Expression const*> _boundArgumentCall,\n\t\tFunctionType const* _funType,\n\t\tstd::vector<Expression const*> _arguments,\n\t\tsmtutil::Expression _contractAddressValue\n\t);\n\t/// @returns a predicate that defines a contract initializer for _contract in the context of _contractContext.\n\tsmtutil::Expression initializer(ContractDefinition const& _contract, ContractDefinition const& _contractContext);\n\t/// @returns a predicate that defines a constructor summary.\n\tsmtutil::Expression summary(ContractDefinition const& _contract);\n\t/// @returns a predicate that defines a function summary.\n\tsmtutil::Expression summary(FunctionDefinition const& _function);\n\tsmtutil::Expression summary(FunctionDefinition const& _function, ContractDefinition const& _contract);\n\t/// @returns a predicate that applies a function summary\n\t/// over the constrained variables.\n\tsmtutil::Expression summaryCall(FunctionDefinition const& _function);\n\tsmtutil::Expression summaryCall(FunctionDefinition const& _function, ContractDefinition const& _contract);\n\t/// @returns a predicate that defines an external function summary.\n\tsmtutil::Expression externalSummary(FunctionDefinition const& _function);\n\tsmtutil::Expression externalSummary(FunctionDefinition const& _function, ContractDefinition const& _contract);\n\t//@}\n\n\t/// Solver related.\n\t//@{\n\t/// Adds Horn rule to the solver.\n\tvoid addRule(smtutil::Expression const& _rule, std::string const& _ruleName);\n\t/// @returns <true, invariant, empty> if query is unsatisfiable (safe).\n\t/// @returns <false, Expression(true), model> otherwise.\n\tsmtutil::CHCSolverInterface::QueryResult query(smtutil::Expression const& _query, langutil::SourceLocation const& _location);\n\n\tvoid verificationTargetEncountered(ASTNode const* const _errorNode, VerificationTargetType _type, smtutil::Expression const& _errorCondition);\n\n\tvoid checkVerificationTargets();\n\tstruct CHCQueryPlaceholder;\n\tvoid checkAssertTarget(ASTNode const* _scope, CHCVerificationTarget const& _target);\n\tvoid checkAndReportTarget(\n\t\tCHCVerificationTarget const& _target,\n\t\tstd::vector<CHCQueryPlaceholder> const& _placeholders,\n\t\tlangutil::ErrorId _errorReporterId,\n\t\tstd::string _satMsg,\n\t\tstd::string _unknownMsg = \"\"\n\t);\n\n\tstd::pair<std::string, langutil::ErrorId> targetDescription(CHCVerificationTarget const& _target);\n\n\tstd::optional<std::string> generateCounterexample(smtutil::CHCSolverInterface::CexGraph const& _graph, std::string const& _root);\n\n\t/// @returns a call graph for function summaries in the counterexample graph.\n\t/// The returned map also contains a key _root, whose value are the\n\t/// summaries called by _root.\n\tstd::map<unsigned, std::vector<unsigned>> summaryCalls(\n\t\tsmtutil::CHCSolverInterface::CexGraph const& _graph,\n\t\tunsigned _root\n\t);\n\n\t/// @returns a set of pairs _var = _value separated by _separator.\n\ttemplate <typename T>\n\tstd::string formatVariableModel(std::vector<T> const& _variables, std::vector<std::optional<std::string>> const& _values, std::string const& _separator) const\n\t{\n\t\tsolAssert(_variables.size() == _values.size(), \"\");\n\n\t\tstd::vector<std::string> assignments;\n\t\tfor (unsigned i = 0; i < _values.size(); ++i)\n\t\t{\n\t\t\tauto var = _variables.at(i);\n\t\t\tif (var && _values.at(i))\n\t\t\t\tassignments.emplace_back(var->name() + \" = \" + *_values.at(i));\n\t\t}\n\n\t\treturn boost::algorithm::join(assignments, _separator);\n\t}\n\n\t/// @returns a DAG in the dot format.\n\t/// Used for debugging purposes.\n\tstd::string cex2dot(smtutil::CHCSolverInterface::CexGraph const& _graph);\n\t//@}\n\n\t/// Misc.\n\t//@{\n\t/// @returns a prefix to be used in a new unique block name\n\t/// and increases the block counter.\n\tstd::string uniquePrefix();\n\n\t/// @returns a suffix to be used by contract related predicates.\n\tstd::string contractSuffix(ContractDefinition const& _contract);\n\n\t/// @returns a new unique error id associated with _expr and stores\n\t/// it into m_errorIds.\n\tunsigned newErrorId();\n\n\tsmt::SymbolicIntVariable& errorFlag();\n\n\t/// Adds to the solver constraints that\n\t/// - propagate tx.origin\n\t/// - set the current contract as msg.sender\n\t/// - set the msg.value as _value, if not nullptr\n\tvoid newTxConstraints(Expression const* _value);\n\n\t/// @returns the expression representing the value sent in\n\t/// an external call if present,\n\t/// and nullptr otherwise.\n\tfrontend::Expression const* valueOption(FunctionCallOptions const* _options);\n\n\t/// Adds constraints that decrease the balance of the caller by _value.\n\tvoid decreaseBalanceFromOptionsValue(Expression const& _value);\n\n\tstd::vector<smtutil::Expression> commonStateExpressions(smtutil::Expression const& error, smtutil::Expression const& address);\n\t//@}\n\n\t/// Predicates.\n\t//@{\n\t/// Artificial Interface predicate.\n\t/// Single entry block for all functions.\n\tstd::map<ContractDefinition const*, Predicate const*> m_interfaces;\n\n\t/// Nondeterministic interfaces.\n\t/// These are used when the analyzed contract makes external calls to unknown code,\n\t/// which means that the analyzed contract can potentially be called\n\t/// nondeterministically.\n\tstd::map<ContractDefinition const*, Predicate const*> m_nondetInterfaces;\n\n\tstd::map<ContractDefinition const*, Predicate const*> m_constructorSummaries;\n\tstd::map<ContractDefinition const*, std::map<ContractDefinition const*, Predicate const*>> m_contractInitializers;\n\n\t/// Artificial Error predicate.\n\t/// Single error block for all assertions.\n\tPredicate const* m_errorPredicate = nullptr;\n\n\t/// Function predicates.\n\tstd::map<ContractDefinition const*, std::map<FunctionDefinition const*, Predicate const*>> m_summaries;\n\n\t/// External function predicates.\n\tstd::map<ContractDefinition const*, std::map<FunctionDefinition const*, Predicate const*>> m_externalSummaries;\n\t//@}\n\n\t/// Variables.\n\t//@{\n\t/// State variables.\n\t/// Used to create all predicates.\n\tstd::vector<VariableDeclaration const*> m_stateVariables;\n\t//@}\n\n\t/// Verification targets.\n\t//@{\n\t/// Query placeholder stores information necessary to create the final query edge in the CHC system.\n\t/// It is combined with the unique error id (and error type) to create a complete Verification Target.\n\tstruct CHCQueryPlaceholder\n\t{\n\t\tsmtutil::Expression const constraints;\n\t\tsmtutil::Expression const errorExpression;\n\t\tsmtutil::Expression const fromPredicate;\n\t};\n\n\t/// Query placeholders for constructors, if the key has type ContractDefinition*,\n\t/// or external functions, if the key has type FunctionDefinition*.\n\t/// A placeholder is created for each possible context of a function (e.g. multiple contracts in contract inheritance hierarchy).\n\tstd::map<ASTNode const*, std::vector<CHCQueryPlaceholder>, smt::EncodingContext::IdCompare> m_queryPlaceholders;\n\n\t/// Records verification conditions IDs per function encountered during an analysis of that function.\n\t/// The key is the ASTNode of the function where the verification condition has been encountered,\n\t/// or the ASTNode of the contract if the verification condition happens inside an implicit constructor.\n\tstd::map<ASTNode const*, std::vector<unsigned>, smt::EncodingContext::IdCompare> m_functionTargetIds;\n\t/// Helper mapping unique IDs to actual verification targets.\n\tstd::map<unsigned, CHCVerificationTarget> m_verificationTargets;\n\n\t/// Targets proved safe.\n\tstd::map<ASTNode const*, std::set<CHCVerificationTarget>, smt::EncodingContext::IdCompare> m_safeTargets;\n\t/// Targets proved unsafe.\n\tstd::map<ASTNode const*, std::map<VerificationTargetType, ReportTargetInfo>, smt::EncodingContext::IdCompare> m_unsafeTargets;\n\t/// Targets not proved.\n\tstd::map<ASTNode const*, std::map<VerificationTargetType, ReportTargetInfo>, smt::EncodingContext::IdCompare> m_unprovedTargets;\n\n\t/// Inferred invariants.\n\tstd::map<Predicate const*, std::set<std::string>, PredicateCompare> m_invariants;\n\t//@}\n\n\t/// Control-flow.\n\t//@{\n\tFunctionDefinition const* m_currentFunction = nullptr;\n\n\tstd::map<ASTNode const*, std::set<ASTNode const*, smt::EncodingContext::IdCompare>, smt::EncodingContext::IdCompare> m_callGraph;\n\n\t/// The current block.\n\tsmtutil::Expression m_currentBlock = smtutil::Expression(true);\n\n\t/// Counter to generate unique block names.\n\tunsigned m_blockCounter = 0;\n\n\t/// Whether a function call was seen in the current scope.\n\tbool m_unknownFunctionCallSeen = false;\n\n\t/// Block where a loop break should go to.\n\tPredicate const* m_breakDest = nullptr;\n\t/// Block where a loop continue should go to.\n\tPredicate const* m_continueDest = nullptr;\n\n\t/// Block where an error condition should go to.\n\t/// This can be:\n\t/// 1) Constructor initializer summary, if error happens while evaluating initial values of state variables.\n\t/// 2) Constructor summary, if error happens while evaluating base constructor arguments.\n\t/// 3) Function summary, if error happens inside a function.\n\tPredicate const* m_errorDest = nullptr;\n\n\t/// Represents the stack of destinations where a `return` should go.\n\t/// This is different from `m_errorDest` above:\n\t/// - Constructor initializers and constructor summaries will never be `return` targets because they are artificial.\n\t/// - Modifiers also have their own `return` target blocks, whereas they do not have their own error destination.\n\tstd::vector<Predicate const*> m_returnDests;\n\t//@}\n\n\t/// CHC solver.\n\tstd::unique_ptr<smtutil::CHCSolverInterface> m_interface;\n\n\tstd::map<util::h256, std::string> const& m_smtlib2Responses;\n\tReadCallback::Callback const& m_smtCallback;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/Cvc5SMTLib2Interface.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/Cvc5SMTLib2Interface.h>\n\n#include <libsolidity/interface/UniversalCallback.h>\n\nusing namespace solidity::frontend::smt;\n\nCvc5SMTLib2Interface::Cvc5SMTLib2Interface(\n\tfrontend::ReadCallback::Callback _smtCallback,\n\tstd::optional<unsigned int> _queryTimeout\n): SMTLib2Interface({}, std::move(_smtCallback), _queryTimeout)\n{\n}\n\nvoid Cvc5SMTLib2Interface::setupSmtCallback() {\n\tif (auto* universalCallback = m_smtCallback.target<frontend::UniversalCallback>())\n\t\tuniversalCallback->smtCommand().setCvc5(m_queryTimeout);\n}\n"
  },
  {
    "path": "libsolidity/formal/Cvc5SMTLib2Interface.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/SMTLib2Interface.h>\n\nnamespace solidity::frontend::smt\n{\n\nclass Cvc5SMTLib2Interface: public smtutil::SMTLib2Interface\n{\npublic:\n\texplicit Cvc5SMTLib2Interface(\n\t\tfrontend::ReadCallback::Callback _smtCallback = {},\n\t\tstd::optional<unsigned> _queryTimeout = {}\n\t);\nprivate:\n\tvoid setupSmtCallback() override;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/EldaricaCHCSmtLib2Interface.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/EldaricaCHCSmtLib2Interface.h>\n\n#include <libsolidity/interface/UniversalCallback.h>\n\nusing namespace solidity::frontend::smt;\n\nEldaricaCHCSmtLib2Interface::EldaricaCHCSmtLib2Interface(\n\tfrontend::ReadCallback::Callback _smtCallback,\n\tstd::optional<unsigned int> _queryTimeout,\n\tbool computeInvariants\n): CHCSmtLib2Interface({}, std::move(_smtCallback), _queryTimeout), m_computeInvariants(computeInvariants)\n{\n}\n\nstd::string EldaricaCHCSmtLib2Interface::querySolver(std::string const& _input)\n{\n\tif (auto* universalCallback = m_smtCallback.target<frontend::UniversalCallback>())\n\t\tuniversalCallback->smtCommand().setEldarica(m_queryTimeout, m_computeInvariants);\n\n\treturn CHCSmtLib2Interface::querySolver(_input);\n}\n"
  },
  {
    "path": "libsolidity/formal/EldaricaCHCSmtLib2Interface.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/CHCSmtLib2Interface.h>\n\nnamespace solidity::frontend::smt\n{\n\nclass EldaricaCHCSmtLib2Interface: public smtutil::CHCSmtLib2Interface\n{\npublic:\n\tEldaricaCHCSmtLib2Interface(\n\t\tfrontend::ReadCallback::Callback _smtCallback,\n\t\tstd::optional<unsigned int> _queryTimeout,\n\t\tbool computeInvariants\n\t);\n\nprivate:\n\tstd::string querySolver(std::string const& _input) override;\n\n\tbool m_computeInvariants;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/EncodingContext.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/EncodingContext.h>\n\n#include <libsolidity/ast/AST.h>\n\n#include <libsolidity/formal/SymbolicTypes.h>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::frontend::smt;\n\nbool EncodingContext::IdCompare::operator()(ASTNode const* lhs, ASTNode const* rhs) const\n{\n\treturn lhs->id() < rhs->id();\n}\n\nEncodingContext::EncodingContext():\n\tm_state(*this)\n{\n}\n\nvoid EncodingContext::reset()\n{\n\tresetAllVariables();\n\tm_expressions.clear();\n\tm_globalContext.clear();\n\tm_state.reset();\n\tm_assertions.clear();\n}\n\nvoid EncodingContext::resetUniqueId()\n{\n\tm_nextUniqueId = 0;\n}\n\nunsigned EncodingContext::newUniqueId()\n{\n\treturn m_nextUniqueId++;\n}\n\n/// Variables.\n\nstd::shared_ptr<SymbolicVariable> EncodingContext::variable(frontend::VariableDeclaration const& _varDecl)\n{\n\tsolAssert(knownVariable(_varDecl), \"\");\n\treturn m_variables[&_varDecl];\n}\n\nbool EncodingContext::createVariable(frontend::VariableDeclaration const& _varDecl)\n{\n\tsolAssert(!knownVariable(_varDecl), \"\");\n\tauto const& type = _varDecl.type();\n\tauto result = newSymbolicVariable(*type, _varDecl.name() + \"_\" + std::to_string(_varDecl.id()), *this);\n\tm_variables.emplace(&_varDecl, result.second);\n\treturn result.first;\n}\n\nbool EncodingContext::knownVariable(frontend::VariableDeclaration const& _varDecl)\n{\n\treturn m_variables.count(&_varDecl);\n}\n\nvoid EncodingContext::resetVariable(frontend::VariableDeclaration const& _variable)\n{\n\tnewValue(_variable);\n\tsetUnknownValue(_variable);\n}\n\nvoid EncodingContext::resetVariables(std::set<frontend::VariableDeclaration const*> const& _variables)\n{\n\tfor (auto const* decl: _variables)\n\t\tresetVariable(*decl);\n}\n\nvoid EncodingContext::resetVariables(std::function<bool(frontend::VariableDeclaration const&)> const& _filter)\n{\n\tfor_each(begin(m_variables), end(m_variables), [&](auto _variable)\n\t{\n\t\tif (_filter(*_variable.first))\n\t\t\tthis->resetVariable(*_variable.first);\n\t});\n}\n\nvoid EncodingContext::resetAllVariables()\n{\n\tresetVariables([&](frontend::VariableDeclaration const&) { return true; });\n}\n\nsmtutil::Expression EncodingContext::newValue(frontend::VariableDeclaration const& _decl)\n{\n\tsolAssert(knownVariable(_decl), \"\");\n\treturn m_variables.at(&_decl)->increaseIndex();\n}\n\nvoid EncodingContext::setZeroValue(frontend::VariableDeclaration const& _decl)\n{\n\tsolAssert(knownVariable(_decl), \"\");\n\tsetZeroValue(*m_variables.at(&_decl));\n}\n\nvoid EncodingContext::setZeroValue(SymbolicVariable& _variable)\n{\n\tsetSymbolicZeroValue(_variable, *this);\n}\n\nvoid EncodingContext::setUnknownValue(frontend::VariableDeclaration const& _decl)\n{\n\tsolAssert(knownVariable(_decl), \"\");\n\tsetUnknownValue(*m_variables.at(&_decl));\n}\n\nvoid EncodingContext::setUnknownValue(SymbolicVariable& _variable)\n{\n\tsetSymbolicUnknownValue(_variable, *this);\n}\n\n/// Expressions\n\nstd::shared_ptr<SymbolicVariable> EncodingContext::expression(frontend::Expression const& _e)\n{\n\tif (!knownExpression(_e))\n\t\tcreateExpression(_e);\n\treturn m_expressions.at(&_e);\n}\n\nbool EncodingContext::createExpression(frontend::Expression const& _e, std::shared_ptr<SymbolicVariable> _symbVar)\n{\n\tsolAssert(_e.annotation().type, \"\");\n\tif (knownExpression(_e))\n\t{\n\t\texpression(_e)->increaseIndex();\n\t\treturn false;\n\t}\n\telse if (_symbVar)\n\t{\n\t\tm_expressions.emplace(&_e, _symbVar);\n\t\treturn false;\n\t}\n\telse\n\t{\n\t\tauto result = newSymbolicVariable(*_e.annotation().type, \"expr_\" + std::to_string(_e.id()), *this);\n\t\tm_expressions.emplace(&_e, result.second);\n\t\treturn result.first;\n\t}\n}\n\nbool EncodingContext::knownExpression(frontend::Expression const& _e) const\n{\n\treturn m_expressions.count(&_e);\n}\n\n/// Global variables and functions.\n\nstd::shared_ptr<SymbolicVariable> EncodingContext::globalSymbol(std::string const& _name)\n{\n\tsolAssert(knownGlobalSymbol(_name), \"\");\n\treturn m_globalContext.at(_name);\n}\n\nbool EncodingContext::createGlobalSymbol(std::string const& _name, frontend::Expression const& _expr)\n{\n\tsolAssert(!knownGlobalSymbol(_name), \"\");\n\tauto result = newSymbolicVariable(*_expr.annotation().type, _name, *this);\n\tm_globalContext.emplace(_name, result.second);\n\tsetUnknownValue(*result.second);\n\treturn result.first;\n}\n\nbool EncodingContext::knownGlobalSymbol(std::string const& _var) const\n{\n\treturn m_globalContext.count(_var);\n}\n\n/// Solver.\n\nsmtutil::Expression EncodingContext::assertions()\n{\n\tif (m_assertions.empty())\n\t\treturn smtutil::Expression(true);\n\n\treturn m_assertions.back();\n}\n\nvoid EncodingContext::pushSolver()\n{\n\tif (m_accumulateAssertions)\n\t\tm_assertions.push_back(assertions());\n\telse\n\t\tm_assertions.emplace_back(true);\n}\n\nvoid EncodingContext::popSolver()\n{\n\tsolAssert(!m_assertions.empty(), \"\");\n\tm_assertions.pop_back();\n}\n\nvoid EncodingContext::addAssertion(smtutil::Expression const& _expr)\n{\n\tif (m_assertions.empty())\n\t\tm_assertions.push_back(_expr);\n\telse\n\t\tm_assertions.back() = _expr && std::move(m_assertions.back());\n}\n"
  },
  {
    "path": "libsolidity/formal/EncodingContext.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/formal/SymbolicState.h>\n#include <libsolidity/formal/SymbolicVariables.h>\n\n#include <libsmtutil/SolverInterface.h>\n\n#include <map>\n\nnamespace solidity::frontend::smt\n{\n\n/**\n * Stores the context of the SMT encoding.\n */\nclass EncodingContext\n{\npublic:\n\tEncodingContext();\n\n\t/// Resets the entire context except for symbolic variables which stay\n\t/// alive because of state variables and inlined function calls.\n\t/// To be used in the beginning of a root function visit.\n\tvoid reset();\n\t/// Resets the fresh id for slack variables.\n\tvoid resetUniqueId();\n\t/// Returns the current fresh slack id and increments it.\n\tunsigned newUniqueId();\n\n\t/// Sets the current solver used by the current engine for\n\t/// SMT variable declaration.\n\tvoid setSolver(smtutil::SolverInterface* _solver)\n\t{\n\t\tsolAssert(_solver, \"\");\n\t\tm_solver = _solver;\n\t}\n\n\t/// Sets whether the context should conjoin assertions in the assertion stack.\n\tvoid setAssertionAccumulation(bool _acc) { m_accumulateAssertions = _acc; }\n\n\t/// Forwards variable creation to the solver.\n\tsmtutil::Expression newVariable(std::string _name, smtutil::SortPointer _sort)\n\t{\n\t\tsolAssert(m_solver, \"\");\n\t\treturn m_solver->newVariable(std::move(_name), std::move(_sort));\n\t}\n\n\tstruct IdCompare\n\t{\n\t\tbool operator()(ASTNode const* lhs, ASTNode const* rhs) const;\n\t};\n\n\t/// Variables.\n\t//@{\n\t/// @returns the symbolic representation of a program variable.\n\tstd::shared_ptr<SymbolicVariable> variable(frontend::VariableDeclaration const& _varDecl);\n\t/// @returns all symbolic variables.\n\tstd::map<frontend::VariableDeclaration const*, std::shared_ptr<SymbolicVariable>, IdCompare> const& variables() const { return m_variables; }\n\n\t/// Creates a symbolic variable and\n\t/// @returns true if a variable's type is not supported and is therefore abstract.\n\tbool createVariable(frontend::VariableDeclaration const& _varDecl);\n\t/// @returns true if variable was created.\n\tbool knownVariable(frontend::VariableDeclaration const& _varDecl);\n\n\t/// Resets a specific variable.\n\tvoid resetVariable(frontend::VariableDeclaration const& _variable);\n\t/// Resets a set of variables.\n\tvoid resetVariables(std::set<frontend::VariableDeclaration const*> const& _variables);\n\t/// Resets variables according to a predicate.\n\tvoid resetVariables(std::function<bool(frontend::VariableDeclaration const&)> const& _filter);\n\t///Resets all variables.\n\tvoid resetAllVariables();\n\n\t/// Allocates a new index for the declaration, updates the current\n\t/// index to this value and returns the expression.\n\tsmtutil::Expression newValue(frontend::VariableDeclaration const& _decl);\n\t/// Sets the value of the declaration to zero.\n\tvoid setZeroValue(frontend::VariableDeclaration const& _decl);\n\tvoid setZeroValue(SymbolicVariable& _variable);\n\t/// Resets the variable to an unknown value (in its range).\n\tvoid setUnknownValue(frontend::VariableDeclaration const& decl);\n\tvoid setUnknownValue(SymbolicVariable& _variable);\n\t//@}\n\n\t/// Expressions.\n\t////@{\n\t/// @returns the symbolic representation of an AST node expression.\n\tstd::shared_ptr<SymbolicVariable> expression(frontend::Expression const& _e);\n\t/// @returns all symbolic expressions.\n\tstd::map<frontend::Expression const*, std::shared_ptr<SymbolicVariable>, IdCompare> const& expressions() const { return m_expressions; }\n\n\t/// Creates the expression (value can be arbitrary).\n\t/// @returns true if type is not supported.\n\tbool createExpression(frontend::Expression const& _e, std::shared_ptr<SymbolicVariable> _symbExpr = nullptr);\n\t/// Checks if expression was created.\n\tbool knownExpression(frontend::Expression const& _e) const;\n\t//@}\n\n\t/// Global variables and functions.\n\t//@{\n\t/// Global variables and functions.\n\tstd::shared_ptr<SymbolicVariable> globalSymbol(std::string const& _name);\n\t/// @returns all symbolic globals.\n\tstd::map<std::string, std::shared_ptr<SymbolicVariable>> const& globalSymbols() const { return m_globalContext; }\n\n\t/// Defines a new global variable or function\n\t/// and @returns true if type was abstracted.\n\tbool createGlobalSymbol(std::string const& _name, frontend::Expression const& _expr);\n\t/// Checks if special variable or function was seen.\n\tbool knownGlobalSymbol(std::string const& _var) const;\n\t//@}\n\n\t/// Solver.\n\t//@{\n\t/// @returns conjunction of all added assertions.\n\tsmtutil::Expression assertions();\n\tvoid pushSolver();\n\tvoid popSolver();\n\tvoid addAssertion(smtutil::Expression const& _e);\n\tsize_t solverStackHeight() const { return m_assertions.size(); }\n\t//@}\n\n\tSymbolicState& state() { return m_state; }\n\nprivate:\n\t/// Symbolic expressions.\n\t//{@\n\t/// Symbolic variables.\n\tstd::map<frontend::VariableDeclaration const*, std::shared_ptr<SymbolicVariable>, IdCompare> m_variables;\n\n\t/// Symbolic expressions.\n\tstd::map<frontend::Expression const*, std::shared_ptr<SymbolicVariable>, IdCompare> m_expressions;\n\n\t/// Symbolic representation of global symbols including\n\t/// variables and functions.\n\tstd::map<std::string, std::shared_ptr<smt::SymbolicVariable>> m_globalContext;\n\n\t/// Symbolic representation of the blockchain state.\n\tSymbolicState m_state;\n\t//@}\n\n\t/// Solver related.\n\t//@{\n\t/// Solver can be SMT solver or Horn solver in the future.\n\tsmtutil::SolverInterface* m_solver = nullptr;\n\n\t/// Assertion stack.\n\tstd::vector<smtutil::Expression> m_assertions;\n\n\t/// Whether to conjoin assertions in the assertion stack.\n\tbool m_accumulateAssertions = true;\n\t//@}\n\n\t/// Central source of unique ids.\n\tunsigned m_nextUniqueId = 0;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/ExpressionFormatter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/ExpressionFormatter.h>\n\n#include <libsolidity/formal/SymbolicTypes.h>\n\n#include <libsolidity/ast/AST.h>\n\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/CommonData.h>\n\n#include <boost/algorithm/string.hpp>\n\n#include <map>\n#include <vector>\n#include <string>\n\nusing boost::algorithm::starts_with;\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::smtutil;\nusing namespace solidity::frontend::smt;\n\nnamespace solidity::frontend::smt\n{\n\nnamespace\n{\n\nstd::string formatDatatypeAccessor(smtutil::Expression const& _expr, std::vector<std::string> const& _args)\n{\n\tauto const& op = _expr.name;\n\n\t// This is the most complicated part of the translation.\n\t// Datatype accessor means access to a field of a datatype.\n\t// In our encoding, datatypes are used to encode:\n\t// - arrays/mappings as the tuple (array, length)\n\t// - structs as the tuple (<member1>, ..., <memberK>)\n\t// - hash and signature functions as the tuple (keccak256, sha256, ripemd160, ecrecover),\n\t//   where each element is an array emulating an UF\n\t// - abi.* functions as the tuple (<abiCall1>, ..., <abiCallK>).\n\tif (op == \"dt_accessor_keccak256\")\n\t\treturn \"keccak256\";\n\tif (op == \"dt_accessor_sha256\")\n\t\treturn \"sha256\";\n\tif (op == \"dt_accessor_ripemd160\")\n\t\treturn \"ripemd160\";\n\tif (op == \"dt_accessor_ecrecover\")\n\t\treturn \"ecrecover\";\n\n\tstd::string accessorStr = \"accessor_\";\n\t// Struct members have suffix \"accessor_<memberName>\".\n\tstd::string type = op.substr(op.rfind(accessorStr) + accessorStr.size());\n\tsolAssert(_expr.arguments.size() == 1, \"\");\n\n\tif (type == \"length\")\n\t\treturn _args.at(0) + \".length\";\n\tif (type == \"array\")\n\t\treturn _args.at(0);\n\n\tif (\n\t\tstarts_with(type, \"block\") ||\n\t\tstarts_with(type, \"msg\") ||\n\t\tstarts_with(type, \"tx\") ||\n\t\tstarts_with(type, \"abi\")\n\t)\n\t\treturn type;\n\n\tif (starts_with(type, \"t_function_abi\"))\n\t\treturn type;\n\n\treturn _args.at(0) + \".\" + type;\n}\n\nstd::string formatGenericOp(smtutil::Expression const& _expr, std::vector<std::string> const& _args)\n{\n\treturn _expr.name + \"(\" + boost::algorithm::join(_args, \", \") + \")\";\n}\n\nstd::string formatInfixOp(std::string const& _op, std::vector<std::string> const& _args)\n{\n\treturn \"(\" + boost::algorithm::join(_args, \" \" + _op + \" \") + \")\";\n}\n\nstd::string formatArrayOp(smtutil::Expression const& _expr, std::vector<std::string> const& _args)\n{\n\tif (_expr.name == \"select\")\n\t{\n\t\tauto const& a0 = _args.at(0);\n\t\tstatic std::set<std::string> const ufs{\"keccak256\", \"sha256\", \"ripemd160\", \"ecrecover\"};\n\t\tif (ufs.count(a0) || starts_with(a0, \"t_function_abi\"))\n\t\t\treturn _args.at(0) + \"(\" + _args.at(1) + \")\";\n\t\treturn _args.at(0) + \"[\" + _args.at(1) + \"]\";\n\t}\n\tif (_expr.name == \"store\")\n\t\treturn \"(\" + _args.at(0) + \"[\" + _args.at(1) + \"] := \" + _args.at(2) + \")\";\n\treturn formatGenericOp(_expr, _args);\n}\n\nstd::string formatUnaryOp(smtutil::Expression const& _expr, std::vector<std::string> const& _args)\n{\n\tif (_expr.name == \"not\")\n\t\treturn \"!\" + _args.at(0);\n\tif (_expr.name == \"-\")\n\t\treturn \"-\" + _args.at(0);\n\t// Other operators such as exists may end up here.\n\treturn formatGenericOp(_expr, _args);\n}\n\n}\n\nsmtutil::Expression substitute(smtutil::Expression _from, std::map<std::string, std::string> const& _subst)\n{\n\t// TODO For now we ignore nested quantifier expressions,\n\t// but we should support them in the future.\n\tif (_from.name == \"forall\" || _from.name == \"exists\")\n\t\treturn smtutil::Expression(true);\n\tif (_subst.count(_from.name))\n\t\t_from.name = _subst.at(_from.name);\n\tfor (auto& arg: _from.arguments)\n\t\targ = substitute(arg, _subst);\n\treturn _from;\n}\n\nstd::string toSolidityStr(smtutil::Expression const& _expr)\n{\n\tauto const& op = _expr.name;\n\n\tauto const& args = _expr.arguments;\n\tauto strArgs = util::applyMap(args, [](auto const& _arg) { return toSolidityStr(_arg); });\n\n\t// Constant or variable.\n\tif (args.empty())\n\t\treturn op;\n\n\tif (starts_with(op, \"dt_accessor\"))\n\t\treturn formatDatatypeAccessor(_expr, strArgs);\n\n\t// Infix operators with format replacements.\n\tstatic std::map<std::string, std::string> const infixOps{\n\t\t{\"and\", \"&&\"},\n\t\t{\"or\", \"||\"},\n\t\t{\"implies\", \"=>\"},\n\t\t{\"=\", \"=\"},\n\t\t{\">\", \">\"},\n\t\t{\">=\", \">=\"},\n\t\t{\"<\", \"<\"},\n\t\t{\"<=\", \"<=\"},\n\t\t{\"+\", \"+\"},\n\t\t{\"-\", \"-\"},\n\t\t{\"*\", \"*\"},\n\t\t{\"/\", \"/\"},\n\t\t{\"div\", \"/\"},\n\t\t{\"mod\", \"%\"}\n\t};\n\t// Some of these (and, or, +, *) may have >= 2 arguments from z3.\n\tif (infixOps.count(op) && args.size() >= 2)\n\t\treturn formatInfixOp(infixOps.at(op), strArgs);\n\n\tstatic std::set<std::string> const arrayOps{\"select\", \"store\", \"const_array\"};\n\tif (arrayOps.count(op))\n\t\treturn formatArrayOp(_expr, strArgs);\n\n\tif (args.size() == 1)\n\t\treturn formatUnaryOp(_expr, strArgs);\n\n\t// Other operators such as bv2int, int2bv may end up here.\n\treturn op + \"(\" + boost::algorithm::join(strArgs, \", \") + \")\";\n}\n\nnamespace\n{\nbool fillArray(smtutil::Expression const& _expr, std::vector<std::string>& _array, ArrayType const& _type)\n{\n\t// Base case\n\tif (_expr.name == \"const_array\")\n\t{\n\t\tauto length = _array.size();\n\t\tstd::optional<std::string> elemStr = expressionToString(_expr.arguments.at(1), _type.baseType());\n\t\tif (!elemStr)\n\t\t\treturn false;\n\t\t_array.clear();\n\t\t_array.resize(length, *elemStr);\n\t\treturn true;\n\t}\n\n\t// Recursive case.\n\tif (_expr.name == \"store\")\n\t{\n\t\tif (!fillArray(_expr.arguments.at(0), _array, _type))\n\t\t\treturn false;\n\t\tstd::optional<std::string> indexStr = expressionToString(_expr.arguments.at(1), TypeProvider::uint256());\n\t\tif (!indexStr)\n\t\t\treturn false;\n\t\t// Sometimes the solver assigns huge lengths that are not related,\n\t\t// we should catch and ignore those.\n\t\tunsigned long index;\n\t\ttry\n\t\t{\n\t\t\tindex = stoul(*indexStr);\n\t\t}\n\t\tcatch (std::out_of_range const&)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tcatch (std::invalid_argument const&)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tstd::optional<std::string> elemStr = expressionToString(_expr.arguments.at(2), _type.baseType());\n\t\tif (!elemStr)\n\t\t\treturn false;\n\t\tif (index < _array.size())\n\t\t\t_array.at(index) = *elemStr;\n\t\treturn true;\n\t}\n\n\t// Special base case, not supported yet.\n\tif (_expr.name.rfind(\"(_ as-array\") == 0)\n\t{\n\t\t// Z3 expression representing reinterpretation of a different term as an array\n\t\treturn false;\n\t}\n\n\tsolAssert(false);\n}\n}\n\nstd::optional<std::string> expressionToString(smtutil::Expression const& _expr, frontend::Type const* _type)\n{\n\tif (smt::isNumber(*_type))\n\t{\n\t\tsolAssert(_expr.sort->kind == Kind::Int);\n\t\tsolAssert(_expr.arguments.empty() || _expr.name == \"-\");\n\t\tif (_expr.name == \"-\")\n\t\t{\n\t\t\tsolAssert(_expr.arguments.size() == 1);\n\t\t\tsmtutil::Expression const& val = _expr.arguments[0];\n\t\t\tsolAssert(val.sort->kind == Kind::Int && val.arguments.empty());\n\t\t\treturn \"(- \" + val.name + \")\";\n\t\t}\n\n\t\tif (\n\t\t\t_type->category() == frontend::Type::Category::Address ||\n\t\t\t_type->category() == frontend::Type::Category::FixedBytes\n\t\t)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (_expr.name == \"0\")\n\t\t\t\t\treturn \"0x0\";\n\t\t\t\t// For some reason the code below returns \"0x\" for \"0\".\n\t\t\t\treturn util::toHex(toCompactBigEndian(bigint(_expr.name)), util::HexPrefix::Add, util::HexCase::Lower);\n\t\t\t}\n\t\t\tcatch (std::out_of_range const&)\n\t\t\t{\n\t\t\t}\n\t\t\tcatch (std::invalid_argument const&)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\treturn _expr.name;\n\t}\n\tif (smt::isBool(*_type))\n\t{\n\t\tsolAssert(_expr.sort->kind == Kind::Bool);\n\t\tsolAssert(_expr.arguments.empty());\n\t\tsolAssert(_expr.name == \"true\" || _expr.name == \"false\");\n\t\treturn _expr.name;\n\t}\n\tif (smt::isFunction(*_type))\n\t{\n\t\tsolAssert(_expr.arguments.empty());\n\t\treturn _expr.name;\n\t}\n\tif (smt::isArray(*_type))\n\t{\n\t\tauto const& arrayType = dynamic_cast<ArrayType const&>(*_type);\n\t\tif (_expr.name != \"tuple_constructor\")\n\t\t\treturn {};\n\n\t\tauto const& tupleSort = dynamic_cast<TupleSort const&>(*_expr.sort);\n\t\tsolAssert(tupleSort.components.size() == 2);\n\n\t\tunsigned long length;\n\t\ttry\n\t\t{\n\t\t\tlength = stoul(_expr.arguments.at(1).name);\n\t\t}\n\t\tcatch(std::out_of_range const&)\n\t\t{\n\t\t\treturn {};\n\t\t}\n\t\tcatch(std::invalid_argument const&)\n\t\t{\n\t\t\treturn {};\n\t\t}\n\n\t\t// Limit this counterexample size to 1k.\n\t\t// Some OSs give you \"unlimited\" memory through swap and other virtual memory,\n\t\t// so purely relying on bad_alloc being thrown is not a good idea.\n\t\t// In that case, the array allocation might cause OOM and the program is killed.\n\t\tif (length >= 1024)\n\t\t\treturn {};\n\t\ttry\n\t\t{\n\t\t\tstd::vector<std::string> array(length);\n\t\t\tif (!fillArray(_expr.arguments.at(0), array, arrayType))\n\t\t\t\treturn {};\n\t\t\treturn \"[\" + boost::algorithm::join(array, \", \") + \"]\";\n\t\t}\n\t\tcatch (std::bad_alloc const&)\n\t\t{\n\t\t\t// Solver gave a concrete array but length is too large.\n\t\t}\n\t}\n\tif (smt::isNonRecursiveStruct(*_type))\n\t{\n\t\tauto const& structType = dynamic_cast<StructType const&>(*_type);\n\t\tsolAssert(_expr.name == \"tuple_constructor\");\n\t\tauto const& tupleSort = dynamic_cast<TupleSort const&>(*_expr.sort);\n\t\tauto members = structType.structDefinition().members();\n\t\tsolAssert(tupleSort.components.size() == members.size());\n\t\tsolAssert(_expr.arguments.size() == members.size());\n\t\tstd::vector<std::string> elements;\n\t\tfor (unsigned i = 0; i < members.size(); ++i)\n\t\t{\n\t\t\tstd::optional<std::string> elementStr = expressionToString(_expr.arguments.at(i), members[i]->type());\n\t\t\telements.push_back(members[i]->name() + (elementStr.has_value() ?  \": \" + elementStr.value() : \"\"));\n\t\t}\n\t\treturn \"{\" + boost::algorithm::join(elements, \", \") + \"}\";\n\t}\n\n\treturn {};\n}\n\nstd::vector<std::optional<std::string>> formatExpressions(\n\tstd::vector<smtutil::Expression> const& _exprs,\n\tstd::vector<frontend::Type const*> const& _types\n)\n{\n\tsolAssert(_exprs.size() == _types.size());\n\tstd::vector<std::optional<std::string>> strExprs;\n\tfor (unsigned i = 0; i < _exprs.size(); ++i)\n\t\tstrExprs.push_back(expressionToString(_exprs.at(i), _types.at(i)));\n\treturn strExprs;\n}\n\n}\n"
  },
  {
    "path": "libsolidity/formal/ExpressionFormatter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n/**\n * Helper methods for formatting SMT expressions\n */\n\n#include <libsmtutil/SolverInterface.h>\n\n#include <libsolidity/ast/Types.h>\n\n#include <map>\n#include <string>\n\nnamespace solidity::frontend::smt\n{\n\n/// @returns another smtutil::Expressions where every term in _from\n/// may be replaced if it is in the substitution map _subst.\nsmtutil::Expression substitute(smtutil::Expression _from, std::map<std::string, std::string> const& _subst);\n\n/// @returns a Solidity-like expression string built from _expr.\n/// This is done at best-effort and is not guaranteed to always create a perfect Solidity expression string.\nstd::string toSolidityStr(smtutil::Expression const& _expr);\n\n/// @returns a string representation of the SMT expression based on a Solidity type.\nstd::optional<std::string> expressionToString(smtutil::Expression const& _expr, Type const* _type);\n\n/// @returns the formatted version of the given SMT expressions. Those expressions must be SMT constants.\nstd::vector<std::optional<std::string>> formatExpressions(std::vector<smtutil::Expression> const& _exprs, std::vector<Type const*> const& _types);\n}\n"
  },
  {
    "path": "libsolidity/formal/ModelChecker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/ModelChecker.h>\n\n#include <boost/version.hpp>\n#if (BOOST_VERSION < 108800)\n#include <boost/process.hpp>\n#else\n#define BOOST_PROCESS_VERSION 1\n#include <boost/process/v1/search_path.hpp>\n#endif\n\n#include <range/v3/algorithm/any_of.hpp>\n#include <range/v3/view.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::smtutil;\n\nModelChecker::ModelChecker(\n\tErrorReporter& _errorReporter,\n\tlangutil::CharStreamProvider const& _charStreamProvider,\n\tstd::map<h256, std::string> const& _smtlib2Responses,\n\tModelCheckerSettings _settings,\n\tReadCallback::Callback const& _smtCallback\n):\n\tm_errorReporter(_errorReporter),\n\tm_provedSafeReporter(m_provedSafeLogs),\n\tm_settings(std::move(_settings)),\n\tm_context(),\n\tm_bmc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, m_provedSafeReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider),\n\tm_chc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, m_provedSafeReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider)\n{\n}\n\n// TODO This should be removed for 0.9.0.\nbool ModelChecker::isPragmaPresent(std::vector<std::shared_ptr<SourceUnit>> const& _sources)\n{\n\treturn ranges::any_of(_sources, [](auto _source) {\n\t\treturn _source && _source->annotation().experimentalFeatures.count(ExperimentalFeature::SMTChecker);\n\t});\n}\n\nvoid ModelChecker::checkRequestedSourcesAndContracts(std::vector<std::shared_ptr<SourceUnit>> const& _sources)\n{\n\tstd::map<std::string, std::set<std::string>> exist;\n\tfor (auto const& source: _sources)\n\t\tfor (auto node: source->nodes())\n\t\t\tif (auto contract = std::dynamic_pointer_cast<ContractDefinition>(node))\n\t\t\t\texist[contract->sourceUnitName()].insert(contract->name());\n\n\t// Requested sources\n\tfor (auto const& sourceName: m_settings.contracts.contracts | ranges::views::keys)\n\t{\n\t\tif (!exist.count(sourceName))\n\t\t{\n\t\t\tm_uniqueErrorReporter.warning(\n\t\t\t\t9134_error,\n\t\t\t\tSourceLocation(),\n\t\t\t\t\"Requested source \\\"\" + sourceName + \"\\\" does not exist.\"\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tauto const& source = exist.at(sourceName);\n\t\t// Requested contracts in source `s`.\n\t\tfor (auto const& contract: m_settings.contracts.contracts.at(sourceName))\n\t\t\tif (!source.count(contract))\n\t\t\t\tm_uniqueErrorReporter.warning(\n\t\t\t\t\t7400_error,\n\t\t\t\t\tSourceLocation(),\n\t\t\t\t\t\"Requested contract \\\"\" + contract + \"\\\" does not exist in source \\\"\" + sourceName + \"\\\".\"\n\t\t\t\t);\n\t}\n}\n\nvoid ModelChecker::analyze(SourceUnit const& _source)\n{\n\t// TODO This should be removed for 0.9.0.\n\tif (_source.annotation().experimentalFeatures.count(ExperimentalFeature::SMTChecker))\n\t{\n\t\tPragmaDirective const* smtPragma = nullptr;\n\t\tfor (auto node: _source.nodes())\n\t\t\tif (auto pragma = std::dynamic_pointer_cast<PragmaDirective>(node))\n\t\t\t\tif (\n\t\t\t\t\tpragma->literals().size() >= 2 &&\n\t\t\t\t\tpragma->literals().at(1) == \"SMTChecker\"\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tsmtPragma = pragma.get();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\tsolAssert(smtPragma, \"\");\n\t\tm_uniqueErrorReporter.warning(\n\t\t\t5523_error,\n\t\t\tsmtPragma->location(),\n\t\t\t\"The SMTChecker pragma has been deprecated and will be removed in the future. \"\n\t\t\t\"Please use the \\\"model checker engine\\\" compiler setting to activate the SMTChecker instead. \"\n\t\t\t\"If the pragma is enabled, all engines will be used.\"\n\t\t);\n\t}\n\n\tif (m_settings.engine.none())\n\t\treturn;\n\n\tif (m_settings.engine.chc)\n\t\tm_chc.analyze(_source);\n\n\tstd::map<ASTNode const*, std::set<VerificationTargetType>, smt::EncodingContext::IdCompare> solvedTargets;\n\n\tfor (auto const& [node, targets]: m_chc.safeTargets())\n\t\tfor (auto const& target: targets)\n\t\t\tsolvedTargets[node].insert(target.type);\n\n\tfor (auto const& [node, targets]: m_chc.unsafeTargets())\n\t\tsolvedTargets[node] += targets | ranges::views::keys;\n\n\tif (m_settings.engine.bmc)\n\t\tm_bmc.analyze(_source, solvedTargets);\n\n\tif (m_settings.showUnsupported)\n\t{\n\t\tm_errorReporter.append(m_unsupportedErrorReporter.errors());\n\t\tm_unsupportedErrorReporter.clear();\n\t}\n\telse if (!m_unsupportedErrorReporter.errors().empty())\n\t\tm_errorReporter.warning(\n\t\t\t5724_error,\n\t\t\t{},\n\t\t\t\"SMTChecker: \" +\n\t\t\tstd::to_string(m_unsupportedErrorReporter.errors().size()) +\n\t\t\t\" unsupported language feature(s).\"\n\t\t\t\" Enable the model checker option \\\"show unsupported\\\" to see all of them.\"\n\t\t);\n\n\tm_errorReporter.append(m_uniqueErrorReporter.errors());\n\tm_uniqueErrorReporter.clear();\n\n\tif (m_settings.showProvedSafe)\n\t{\n\t\tm_errorReporter.append(m_provedSafeReporter.errors());\n\t\tm_provedSafeReporter.clear();\n\t}\n}\n\nstd::vector<std::string> ModelChecker::unhandledQueries()\n{\n\treturn m_bmc.unhandledQueries() + m_chc.unhandledQueries();\n}\n\nSMTSolverChoice ModelChecker::availableSolvers()\n{\n\tsmtutil::SMTSolverChoice available = smtutil::SMTSolverChoice::SMTLIB2();\n\tavailable.eld = !boost::process::search_path(\"eld\").empty();\n\tavailable.cvc5 = !boost::process::search_path(\"cvc5\").empty();\n#ifdef EMSCRIPTEN_BUILD\n\tavailable.z3 = true;\n#else\n\tavailable.z3 = !boost::process::search_path(\"z3\").empty();\n#endif\n\treturn available;\n}\n\nSMTSolverChoice ModelChecker::checkRequestedSolvers(SMTSolverChoice _enabled, ErrorReporter& _errorReporter)\n{\n\tSMTSolverChoice availableSolvers{ModelChecker::availableSolvers()};\n\n\tif (_enabled.cvc5 && !availableSolvers.cvc5)\n\t{\n\t\t_enabled.cvc5 = false;\n\t\t_errorReporter.warning(\n\t\t\t4902_error,\n\t\t\tSourceLocation(),\n\t\t\t\"Solver cvc5 was selected for SMTChecker but it is not available.\"\n\t\t);\n\t}\n\n\tif (_enabled.eld && !availableSolvers.eld)\n\t{\n\t\t_enabled.eld = false;\n\t\t_errorReporter.warning(\n\t\t\t4458_error,\n\t\t\tSourceLocation(),\n#if defined(__linux) || defined(__APPLE__)\n\t\t\t\"Solver Eldarica was selected for SMTChecker but it was not found in the system.\"\n#else\n\t\t\t\"Solver Eldarica was selected for SMTChecker but it is only supported on Linux and MacOS.\"\n#endif\n\t\t);\n\t}\n\n\tif (_enabled.z3 && !availableSolvers.z3)\n\t{\n\t\t_enabled.z3 = false;\n\t\t_errorReporter.warning(\n\t\t\t8158_error,\n\t\t\tSourceLocation(),\n\t\t\t\"Solver z3 was selected for SMTChecker but it is not available.\"\n\t\t);\n\t}\n\n\treturn _enabled;\n}\n"
  },
  {
    "path": "libsolidity/formal/ModelChecker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Entry point to the model checking engines.\n * The goal of this class is to make different\n * engines share knowledge to boost their proving power.\n */\n\n#pragma once\n\n#include <libsolidity/formal/BMC.h>\n#include <libsolidity/formal/CHC.h>\n#include <libsolidity/formal/EncodingContext.h>\n#include <libsolidity/formal/ModelCheckerSettings.h>\n\n#include <libsolidity/interface/ReadFile.h>\n\n#include <libsmtutil/SolverInterface.h>\n\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/UniqueErrorReporter.h>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\nstruct SourceLocation;\n}\n\nnamespace solidity::frontend\n{\n\nclass ModelChecker\n{\npublic:\n\t/// @param _enabledSolvers represents a runtime choice of which SMT solvers\n\t/// should be used, even if all are available. The default choice is to use all.\n\tModelChecker(\n\t\tlangutil::ErrorReporter& _errorReporter,\n\t\tlangutil::CharStreamProvider const& _charStreamProvider,\n\t\tstd::map<solidity::util::h256, std::string> const& _smtlib2Responses,\n\t\tModelCheckerSettings _settings = ModelCheckerSettings{},\n\t\tReadCallback::Callback const& _smtCallback = ReadCallback::Callback()\n\t);\n\n\t// TODO This should be removed for 0.9.0.\n\tstatic bool isPragmaPresent(std::vector<std::shared_ptr<SourceUnit>> const& _sources);\n\n\t/// Generates error messages if the requested sources and contracts\n\t/// do not exist.\n\tvoid checkRequestedSourcesAndContracts(std::vector<std::shared_ptr<SourceUnit>> const& _sources);\n\n\tvoid analyze(SourceUnit const& _sources);\n\n\t/// This is used if the SMT solver is not directly linked into this binary.\n\t/// @returns a list of inputs to the SMT solver that were not part of the argument to\n\t/// the constructor.\n\tstd::vector<std::string> unhandledQueries();\n\n\t/// @returns SMT solvers that are available via the C++ API.\n\tstatic smtutil::SMTSolverChoice availableSolvers();\n\n\t/// @returns the intersection of the enabled and available solvers,\n\t/// reporting warnings when a solver is enabled but not available.\n\tstatic smtutil::SMTSolverChoice checkRequestedSolvers(smtutil::SMTSolverChoice _enabled, langutil::ErrorReporter& _errorReporter);\n\nprivate:\n\t/// Error reporter from CompilerStack.\n\t/// We need to append m_uniqueErrorReporter\n\t/// to this one when the analysis is done.\n\tlangutil::ErrorReporter& m_errorReporter;\n\n\t/// Used by ModelChecker, SMTEncoder, BMC and CHC to avoid duplicates.\n\t/// This is local to ModelChecker, so needs to be appended\n\t/// to m_errorReporter at the end of the analysis.\n\tlangutil::UniqueErrorReporter m_uniqueErrorReporter;\n\n\t/// Used by SMTEncoder, BMC and CHC to accumulate unsupported\n\t/// warnings and avoid duplicates.\n\t/// This is local to ModelChecker, so needs to be appended\n\t/// to m_errorReporter at the end of the analysis.\n\tlangutil::UniqueErrorReporter m_unsupportedErrorReporter;\n\n\tlangutil::ErrorList m_provedSafeLogs;\n\t/// Used by SMTEncoder, BMC and CHC to accumulate info about proved targets.\n\t/// This is local to ModelChecker, so needs to be appended\n\t/// to m_errorReporter at the end of the analysis.\n\tlangutil::ErrorReporter m_provedSafeReporter;\n\n\tModelCheckerSettings m_settings;\n\n\t/// Stores the context of the encoding.\n\tsmt::EncodingContext m_context;\n\n\t/// Bounded Model Checker engine.\n\tBMC m_bmc;\n\n\t/// Constrained Horn Clauses engine.\n\tCHC m_chc;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/ModelCheckerSettings.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/ModelCheckerSettings.h>\n\n#include <optional>\n#include <range/v3/view.hpp>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\n\nstd::map<std::string, InvariantType> const ModelCheckerInvariants::validInvariants{\n\t{\"contract\", InvariantType::Contract},\n\t{\"reentrancy\", InvariantType::Reentrancy}\n};\n\nstd::optional<ModelCheckerInvariants> ModelCheckerInvariants::fromString(std::string const& _invs)\n{\n\tstd::set<InvariantType> chosenInvs;\n\tif (_invs == \"default\")\n\t{\n\t\t// The default is that no invariants are reported.\n\t}\n\telse if (_invs == \"all\")\n\t\tfor (auto&& v: validInvariants | ranges::views::values)\n\t\t\tchosenInvs.insert(v);\n\telse\n\t\tfor (auto&& t: _invs | ranges::views::split(',') | ranges::to<std::vector<std::string>>())\n\t\t{\n\t\t\tif (!validInvariants.count(t))\n\t\t\t\treturn {};\n\t\t\tchosenInvs.insert(validInvariants.at(t));\n\t\t}\n\n\treturn ModelCheckerInvariants{chosenInvs};\n}\n\nbool ModelCheckerInvariants::setFromString(std::string const& _inv)\n{\n\tif (!validInvariants.count(_inv))\n\t\treturn false;\n\tinvariants.insert(validInvariants.at(_inv));\n\treturn true;\n}\n\nusing TargetType = VerificationTargetType;\nstd::map<std::string, TargetType> const ModelCheckerTargets::targetStrings{\n\t{\"constantCondition\", TargetType::ConstantCondition},\n\t{\"underflow\", TargetType::Underflow},\n\t{\"overflow\", TargetType::Overflow},\n\t{\"divByZero\", TargetType::DivByZero},\n\t{\"balance\", TargetType::Balance},\n\t{\"assert\", TargetType::Assert},\n\t{\"popEmptyArray\", TargetType::PopEmptyArray},\n\t{\"outOfBounds\", TargetType::OutOfBounds}\n};\n\nstd::map<TargetType, std::string> const ModelCheckerTargets::targetTypeToString{\n\t{TargetType::ConstantCondition, \"Constant condition\"},\n\t{TargetType::Underflow, \"Underflow\"},\n\t{TargetType::Overflow, \"Overflow\"},\n\t{TargetType::DivByZero, \"Division by zero\"},\n\t{TargetType::Balance, \"Insufficient balance\"},\n\t{TargetType::Assert, \"Assertion failed\"},\n\t{TargetType::PopEmptyArray, \"Empty array pop\"},\n\t{TargetType::OutOfBounds, \"Out of bounds access\"}\n};\n\nstd::optional<ModelCheckerTargets> ModelCheckerTargets::fromString(std::string const& _targets)\n{\n\tstd::set<TargetType> chosenTargets;\n\tif (_targets == \"default\" || _targets == \"all\")\n\t{\n\t\tbool all = _targets == \"all\";\n\t\tfor (auto&& v: targetStrings | ranges::views::values)\n\t\t{\n\t\t\tif (!all && (v == TargetType::Underflow || v == TargetType::Overflow))\n\t\t\t\tcontinue;\n\t\t\tchosenTargets.insert(v);\n\t\t}\n\t}\n\telse\n\t\tfor (auto&& t: _targets | ranges::views::split(',') | ranges::to<std::vector<std::string>>())\n\t\t{\n\t\t\tif (!targetStrings.count(t))\n\t\t\t\treturn {};\n\t\t\tchosenTargets.insert(targetStrings.at(t));\n\t\t}\n\n\treturn ModelCheckerTargets{chosenTargets};\n}\n\nbool ModelCheckerTargets::setFromString(std::string const& _target)\n{\n\tif (!targetStrings.count(_target))\n\t\treturn false;\n\ttargets.insert(targetStrings.at(_target));\n\treturn true;\n}\n\nstd::optional<ModelCheckerContracts> ModelCheckerContracts::fromString(std::string const& _contracts)\n{\n\tstd::map<std::string, std::set<std::string>> chosen;\n\tif (_contracts == \"default\")\n\t\treturn ModelCheckerContracts::Default();\n\n\tfor (auto&& sourceContract: _contracts | ranges::views::split(',') | ranges::to<std::vector<std::string>>())\n\t{\n\t\tauto&& names = sourceContract | ranges::views::split(':') | ranges::to<std::vector<std::string>>();\n\t\tif (names.size() != 2 || names.at(0).empty() || names.at(1).empty())\n\t\t\treturn std::nullopt;\n\t\tchosen[names.at(0)].insert(names.at(1));\n\t}\n\n\treturn ModelCheckerContracts{chosen};\n}\n\nstd::optional<ModelCheckerExtCalls> ModelCheckerExtCalls::fromString(std::string const& _mode)\n{\n\tif (_mode == \"untrusted\")\n\t\treturn ModelCheckerExtCalls{Mode::UNTRUSTED};\n\tif (_mode == \"trusted\")\n\t\treturn ModelCheckerExtCalls{Mode::TRUSTED};\n\treturn {};\n}\n"
  },
  {
    "path": "libsolidity/formal/ModelCheckerSettings.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/SolverInterface.h>\n\n#include <optional>\n#include <set>\n\nnamespace solidity::frontend\n{\n\nstruct ModelCheckerContracts\n{\n\t/// By default all contracts are analyzed.\n\tstatic ModelCheckerContracts Default() { return {}; }\n\n\t/// Parses a string of the form <path>:<contract>,<path>:contract,...\n\t/// and returns nullopt if a path or contract name is empty.\n\tstatic std::optional<ModelCheckerContracts> fromString(std::string const& _contracts);\n\n\t/// @returns true if all contracts should be analyzed.\n\tbool isDefault() const { return contracts.empty(); }\n\n\tbool has(std::string const& _source) const { return contracts.count(_source); }\n\tbool has(std::string const& _source, std::string const& _contract) const\n\t{\n\t\treturn has(_source) && contracts.at(_source).count(_contract);\n\t}\n\n\tbool operator!=(ModelCheckerContracts const& _other) const noexcept { return !(*this == _other); }\n\tbool operator==(ModelCheckerContracts const& _other) const noexcept { return contracts == _other.contracts; }\n\n\t/// Represents which contracts should be analyzed by the SMTChecker\n\t/// as the most derived.\n\t/// The key is the source file. If the map is empty, all sources must be analyzed.\n\t/// For each source, contracts[source] represents the contracts in that source\n\t/// that should be analyzed.\n\t/// If the set of contracts is empty, all contracts in that source should be analyzed.\n\tstd::map<std::string, std::set<std::string>> contracts;\n};\n\nstruct ModelCheckerEngine\n{\n\tbool bmc = false;\n\tbool chc = false;\n\n\tstatic constexpr ModelCheckerEngine All() { return {true, true}; }\n\tstatic constexpr ModelCheckerEngine BMC() { return {true, false}; }\n\tstatic constexpr ModelCheckerEngine CHC() { return {false, true}; }\n\tstatic constexpr ModelCheckerEngine None() { return {false, false}; }\n\n\tbool none() const { return !any(); }\n\tbool any() const { return bmc || chc; }\n\tbool all() const { return bmc && chc; }\n\n\tstatic std::optional<ModelCheckerEngine> fromString(std::string const& _engine)\n\t{\n\t\tstatic std::map<std::string, ModelCheckerEngine> engineMap{\n\t\t\t{\"all\", All()},\n\t\t\t{\"bmc\", BMC()},\n\t\t\t{\"chc\", CHC()},\n\t\t\t{\"none\", None()}\n\t\t};\n\t\tif (engineMap.count(_engine))\n\t\t\treturn engineMap.at(_engine);\n\t\treturn {};\n\t}\n\n\tbool operator!=(ModelCheckerEngine const& _other) const noexcept { return !(*this == _other); }\n\tbool operator==(ModelCheckerEngine const& _other) const noexcept { return bmc == _other.bmc && chc == _other.chc; }\n};\n\nenum class InvariantType { Contract, Reentrancy };\n\nstruct ModelCheckerInvariants\n{\n\t/// Adds the default targets, that is, all except underflow and overflow.\n\tstatic ModelCheckerInvariants Default() { return *fromString(\"default\"); }\n\t/// Adds all targets, including underflow and overflow.\n\tstatic ModelCheckerInvariants All() { return *fromString(\"all\"); }\n\tstatic ModelCheckerInvariants None() { return {{}}; }\n\n\tstatic std::optional<ModelCheckerInvariants> fromString(std::string const& _invs);\n\n\tbool has(InvariantType _inv) const { return invariants.count(_inv); }\n\n\t/// @returns true if the @p _target is valid,\n\t/// and false otherwise.\n\tbool setFromString(std::string const& _target);\n\n\tstatic std::map<std::string, InvariantType> const validInvariants;\n\n\tbool operator!=(ModelCheckerInvariants const& _other) const noexcept { return !(*this == _other); }\n\tbool operator==(ModelCheckerInvariants const& _other) const noexcept { return invariants == _other.invariants; }\n\n\tstd::set<InvariantType> invariants;\n};\n\nenum class VerificationTargetType { ConstantCondition, Underflow, Overflow, DivByZero, Balance, Assert, PopEmptyArray, OutOfBounds };\n\nstruct ModelCheckerTargets\n{\n\t/// Adds the default targets, that is, all except underflow and overflow.\n\tstatic ModelCheckerTargets Default() { return *fromString(\"default\"); }\n\t/// Adds all targets, including underflow and overflow.\n\tstatic ModelCheckerTargets All() { return *fromString(\"all\"); }\n\n\tstatic std::optional<ModelCheckerTargets> fromString(std::string const& _targets);\n\n\tbool has(VerificationTargetType _type) const { return targets.count(_type); }\n\n\t/// @returns true if the @p _target is valid,\n\t/// and false otherwise.\n\tbool setFromString(std::string const& _target);\n\n\tstatic std::map<std::string, VerificationTargetType> const targetStrings;\n\n\tstatic std::map<VerificationTargetType, std::string> const targetTypeToString;\n\n\tbool operator!=(ModelCheckerTargets const& _other) const noexcept { return !(*this == _other); }\n\tbool operator==(ModelCheckerTargets const& _other) const noexcept { return targets == _other.targets; }\n\n\tstd::set<VerificationTargetType> targets;\n};\n\nstruct ModelCheckerExtCalls\n{\n\tenum class Mode\n\t{\n\t\tUNTRUSTED,\n\t\tTRUSTED\n\t};\n\n\tMode mode = Mode::UNTRUSTED;\n\n\tstatic std::optional<ModelCheckerExtCalls> fromString(std::string const& _mode);\n\n\tbool isTrusted() const { return mode == Mode::TRUSTED; }\n};\n\nstruct ModelCheckerSettings\n{\n\tstd::optional<unsigned> bmcLoopIterations;\n\tModelCheckerContracts contracts = ModelCheckerContracts::Default();\n\t/// Currently division and modulo are replaced by multiplication with slack vars, such that\n\t/// a / b <=> a = b * k + m\n\t/// where k and m are slack variables.\n\t/// This is the default because Spacer prefers that over precise / and mod.\n\t/// This option allows disabling this mechanism since other solvers\n\t/// might prefer the precise encoding.\n\tbool divModNoSlacks = false;\n\tModelCheckerEngine engine = ModelCheckerEngine::None();\n\tModelCheckerExtCalls externalCalls = {};\n\tModelCheckerInvariants invariants = ModelCheckerInvariants::Default();\n\tbool printQuery = false;\n\tbool showProvedSafe = false;\n\tbool showUnproved = false;\n\tbool showUnsupported = false;\n\tsmtutil::SMTSolverChoice solvers = smtutil::SMTSolverChoice::Z3();\n\tModelCheckerTargets targets = ModelCheckerTargets::Default();\n\tstd::optional<unsigned> timeout; // in milliseconds\n\n\tbool operator!=(ModelCheckerSettings const& _other) const noexcept { return !(*this == _other); }\n\tbool operator==(ModelCheckerSettings const& _other) const noexcept\n\t{\n\t\treturn\n\t\t\tbmcLoopIterations == _other.bmcLoopIterations &&\n\t\t\tcontracts == _other.contracts &&\n\t\t\tdivModNoSlacks == _other.divModNoSlacks &&\n\t\t\tengine == _other.engine &&\n\t\t\texternalCalls.mode == _other.externalCalls.mode &&\n\t\t\tinvariants == _other.invariants &&\n\t\t\tprintQuery == _other.printQuery &&\n\t\t\tshowProvedSafe == _other.showProvedSafe &&\n\t\t\tshowUnproved == _other.showUnproved &&\n\t\t\tshowUnsupported == _other.showUnsupported &&\n\t\t\tsolvers == _other.solvers &&\n\t\t\ttargets == _other.targets &&\n\t\t\ttimeout == _other.timeout;\n\t}\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/Predicate.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/Predicate.h>\n\n#include <libsolidity/formal/ExpressionFormatter.h>\n#include <libsolidity/formal/SMTEncoder.h>\n\n#include <liblangutil/CharStreamProvider.h>\n#include <liblangutil/CharStream.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n\n#include <boost/algorithm/string/join.hpp>\n\n#include <range/v3/view/enumerate.hpp>\n#include <utility>\n\nusing namespace solidity;\nusing namespace solidity::smtutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::smt;\n\nstd::map<std::string, Predicate> Predicate::m_predicates;\n\nPredicate const* Predicate::create(\n\tSortPointer _sort,\n\tstd::string _name,\n\tPredicateType _type,\n\tEncodingContext& _context,\n\tASTNode const* _node,\n\tContractDefinition const* _contractContext,\n\tstd::vector<ScopeOpener const*> _scopeStack\n)\n{\n\tsolAssert(!m_predicates.count(_name), \"\");\n\treturn &m_predicates.emplace(\n\t\tstd::piecewise_construct,\n\t\tstd::forward_as_tuple(_name),\n\t\tstd::forward_as_tuple(_name, std::move(_sort), _type, _context.state().hasBytesConcatFunction(),\n\t\t\t_node, _contractContext, std::move(_scopeStack))\n\t).first->second;\n}\n\nPredicate::Predicate(\n\tstd::string _name,\n\tSortPointer _sort,\n\tPredicateType _type,\n\tbool _bytesConcatFunctionInContext,\n\tASTNode const* _node,\n\tContractDefinition const* _contractContext,\n\tstd::vector<ScopeOpener const*> _scopeStack\n):\n\tm_functor(std::move(_name), {}, std::move(_sort)),\n\tm_type(_type),\n\tm_node(_node),\n\tm_contractContext(_contractContext),\n\tm_scopeStack(_scopeStack),\n\tm_bytesConcatFunctionInContext(_bytesConcatFunctionInContext)\n{\n}\n\nPredicate const* Predicate::predicate(std::string const& _name)\n{\n\treturn &m_predicates.at(_name);\n}\n\nvoid Predicate::reset()\n{\n\tm_predicates.clear();\n}\n\nsmtutil::Expression Predicate::operator()(std::vector<smtutil::Expression> const& _args) const\n{\n\treturn smtutil::Expression(m_functor.name, _args, SortProvider::boolSort);\n}\n\nsmtutil::Expression const& Predicate::functor() const\n{\n\treturn m_functor;\n}\n\nASTNode const* Predicate::programNode() const\n{\n\treturn m_node;\n}\n\nContractDefinition const* Predicate::contextContract() const\n{\n\treturn m_contractContext;\n}\n\nContractDefinition const* Predicate::programContract() const\n{\n\tif (auto const* contract = dynamic_cast<ContractDefinition const*>(m_node))\n\t\tif (!contract->constructor())\n\t\t\treturn contract;\n\n\treturn nullptr;\n}\n\nFunctionDefinition const* Predicate::programFunction() const\n{\n\tif (auto const* contract = dynamic_cast<ContractDefinition const*>(m_node))\n\t{\n\t\tif (contract->constructor())\n\t\t\treturn contract->constructor();\n\t\treturn nullptr;\n\t}\n\n\tif (auto const* fun = dynamic_cast<FunctionDefinition const*>(m_node))\n\t\treturn fun;\n\n\treturn nullptr;\n}\n\nFunctionCall const* Predicate::programFunctionCall() const\n{\n\treturn dynamic_cast<FunctionCall const*>(m_node);\n}\n\nVariableDeclaration  const* Predicate::programVariable() const\n{\n\treturn dynamic_cast<VariableDeclaration const*>(m_node);\n}\n\nstd::optional<std::vector<VariableDeclaration const*>> Predicate::stateVariables() const\n{\n\tif (m_contractContext)\n\t\treturn SMTEncoder::stateVariablesIncludingInheritedAndPrivate(*m_contractContext);\n\n\treturn std::nullopt;\n}\n\nbool Predicate::isSummary() const\n{\n\treturn isFunctionSummary() ||\n\t\tisInternalCall() ||\n\t\tisExternalCallTrusted() ||\n\t\tisExternalCallUntrusted() ||\n\t\tisConstructorSummary();\n}\n\nbool Predicate::isFunctionSummary() const\n{\n\treturn m_type == PredicateType::FunctionSummary;\n}\n\nbool Predicate::isFunctionBlock() const\n{\n\treturn m_type == PredicateType::FunctionBlock;\n}\n\nbool Predicate::isFunctionErrorBlock() const\n{\n\treturn m_type == PredicateType::FunctionErrorBlock;\n}\n\nbool Predicate::isInternalCall() const\n{\n\treturn m_type == PredicateType::InternalCall;\n}\n\nbool Predicate::isExternalCallTrusted() const\n{\n\treturn m_type == PredicateType::ExternalCallTrusted;\n}\n\nbool Predicate::isExternalCallUntrusted() const\n{\n\treturn m_type == PredicateType::ExternalCallUntrusted;\n}\n\nbool Predicate::isConstructorSummary() const\n{\n\treturn m_type == PredicateType::ConstructorSummary;\n}\n\nbool Predicate::isInterface() const\n{\n\treturn m_type == PredicateType::Interface;\n}\n\nbool Predicate::isNondetInterface() const\n{\n\treturn m_type == PredicateType::NondetInterface;\n}\n\nstd::string Predicate::formatSummaryCall(\n\tstd::vector<smtutil::Expression> const& _args,\n\tlangutil::CharStreamProvider const& _charStreamProvider,\n\tbool _appendTxVars\n) const\n{\n\tsolAssert(isSummary(), \"\");\n\n\tif (programVariable())\n\t\treturn {};\n\n\tif (auto funCall = programFunctionCall())\n\t{\n\t\tif (funCall->location().hasText())\n\t\t\treturn std::string(_charStreamProvider.charStream(*funCall->location().sourceName).text(funCall->location()));\n\t\telse\n\t\t\treturn {};\n\t}\n\n\t/// The signature of a function summary predicate is: summary(error, this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, txData, preBlockChainState, preStateVars, preInputVars, postBlockchainState, postStateVars, postInputVars, outputVars).\n\t/// Here we are interested in preInputVars to format the function call.\n\n\tstd::string txModel;\n\n\tif (_appendTxVars)\n\t{\n\t\tstd::set<std::string> txVars;\n\t\tif (isFunctionSummary())\n\t\t{\n\t\t\tsolAssert(programFunction(), \"\");\n\t\t\tif (programFunction()->isPayable())\n\t\t\t\ttxVars.insert(\"msg.value\");\n\t\t}\n\t\telse if (isConstructorSummary())\n\t\t{\n\t\t\tFunctionDefinition const* fun = programFunction();\n\t\t\tif (fun && fun->isPayable())\n\t\t\t\ttxVars.insert(\"msg.value\");\n\t\t}\n\n\t\tstruct TxVarsVisitor: public ASTConstVisitor\n\t\t{\n\t\t\tbool visit(MemberAccess const& _memberAccess)\n\t\t\t{\n\t\t\t\tif (auto magicType = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type))\n\t\t\t\t{\n\t\t\t\t\tauto memberName = _memberAccess.memberName();\n\t\t\t\t\tauto magicKind = magicType->kind();\n\t\t\t\t\t// TODO remove this for 0.9.0\n\t\t\t\t\tif (magicKind == MagicType::Kind::Block && memberName == \"difficulty\")\n\t\t\t\t\t\tmemberName = \"prevrandao\";\n\n\t\t\t\t\tif (magicKind == MagicType::Kind::Block || magicKind == MagicType::Kind::Message || magicKind == MagicType::Kind::Transaction)\n\t\t\t\t\t\ttxVars.insert(magicType->toString(true) + \".\" + memberName);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tstd::set<std::string> txVars;\n\t\t} txVarsVisitor;\n\n\t\tif (auto fun = programFunction())\n\t\t{\n\t\t\tfun->accept(txVarsVisitor);\n\t\t\ttxVars += txVarsVisitor.txVars;\n\t\t}\n\n\t\t// Here we are interested in txData from the summary predicate.\n\t\tauto txValues = readTxVars(_args.at(txValuesIndex()));\n\t\tstd::vector<std::string> values;\n\t\tfor (auto const& _var: txVars)\n\t\t\tif (auto v = txValues.at(_var))\n\t\t\t\tvalues.push_back(_var + \": \" + *v);\n\n\t\tif (!values.empty())\n\t\t\ttxModel = \"{ \" + boost::algorithm::join(values, \", \") + \" }\";\n\t}\n\n\tif (auto contract = programContract())\n\t\treturn contract->name() + \".constructor()\" + txModel;\n\n\tauto stateVars = stateVariables();\n\tsolAssert(stateVars.has_value(), \"\");\n\tauto const* fun = programFunction();\n\tsolAssert(fun, \"\");\n\n\tauto first = _args.begin() + static_cast<int>(firstArgIndex()) + static_cast<int>(stateVars->size());\n\tauto last = first + static_cast<int>(fun->parameters().size());\n\tsolAssert(first >= _args.begin() && first <= _args.end(), \"\");\n\tsolAssert(last >= _args.begin() && last <= _args.end(), \"\");\n\tauto inTypes = SMTEncoder::replaceUserTypes(FunctionType(*fun).parameterTypes());\n\tstd::vector<std::optional<std::string>> functionArgsCex = formatExpressions(std::vector<smtutil::Expression>(first, last), inTypes);\n\tstd::vector<std::string> functionArgs;\n\n\tauto const& params = fun->parameters();\n\tsolAssert(params.size() == functionArgsCex.size(), \"\");\n\tbool paramNameInsteadOfValue = false;\n\tfor (unsigned i = 0; i < params.size(); ++i)\n\t\tif (params.at(i) && functionArgsCex.at(i))\n\t\t\tfunctionArgs.emplace_back(*functionArgsCex.at(i));\n\t\telse {\n\t\t\tparamNameInsteadOfValue = true;\n\t\t\tfunctionArgs.emplace_back(params[i]->name());\n\t\t}\n\n\tstd::string fName = fun->isConstructor() ? \"constructor\" :\n\t\tfun->isFallback() ? \"fallback\" :\n\t\tfun->isReceive() ? \"receive\" :\n\t\tfun->name();\n\n\tstd::string prefix;\n\tif (fun->isFree())\n\t\tprefix = !fun->sourceUnitName().empty() ? (fun->sourceUnitName() + \":\") : \"\";\n\telse\n\t{\n\t\tsolAssert(fun->annotation().contract, \"\");\n\t\tprefix = fun->annotation().contract->name() + \".\";\n\t}\n\n\tstd::string summary = prefix + fName + \"(\" + boost::algorithm::join(functionArgs, \", \") + \")\" + txModel;\n\tif (paramNameInsteadOfValue)\n\t\tsummary += \" -- counterexample incomplete; parameter name used instead of value\";\n\treturn summary;\n}\n\nstd::vector<std::optional<std::string>> Predicate::summaryStateValues(std::vector<smtutil::Expression> const& _args) const\n{\n\t/// The signature of a function summary predicate is: summary(error, this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, txData, preBlockchainState, preStateVars, preInputVars, postBlockchainState, postStateVars, postInputVars, outputVars).\n\t/// The signature of the summary predicate of a contract without constructor is: summary(error, this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, txData, preBlockchainState, postBlockchainState, preStateVars, postStateVars).\n\t/// Here we are interested in postStateVars.\n\tauto stateVars = stateVariables();\n\tsolAssert(stateVars.has_value(), \"\");\n\n\tstd::vector<smtutil::Expression>::const_iterator stateFirst;\n\tstd::vector<smtutil::Expression>::const_iterator stateLast;\n\tif (auto const* function = programFunction())\n\t{\n\t\tstateFirst = _args.begin() + static_cast<int>(firstArgIndex()) + static_cast<int>(stateVars->size()) + static_cast<int>(function->parameters().size()) + 1;\n\t\tstateLast = stateFirst + static_cast<int>(stateVars->size());\n\t}\n\telse if (programContract())\n\t{\n\t\tstateFirst = _args.begin() + static_cast<int>(firstStateVarIndex()) + static_cast<int>(stateVars->size());\n\t\tstateLast = stateFirst + static_cast<int>(stateVars->size());\n\t}\n\telse if (programVariable())\n\t\treturn {};\n\telse\n\t\tsolAssert(false, \"\");\n\n\tsolAssert(stateFirst >= _args.begin() && stateFirst <= _args.end(), \"\");\n\tsolAssert(stateLast >= _args.begin() && stateLast <= _args.end(), \"\");\n\n\tstd::vector<smtutil::Expression> stateArgs(stateFirst, stateLast);\n\tsolAssert(stateArgs.size() == stateVars->size(), \"\");\n\tauto stateTypes = util::applyMap(*stateVars, [&](auto const& _var) { return _var->type(); });\n\treturn formatExpressions(stateArgs, stateTypes);\n}\n\nstd::vector<std::optional<std::string>> Predicate::summaryPostInputValues(std::vector<smtutil::Expression> const& _args) const\n{\n\t/// The signature of a function summary predicate is: summary(error, this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, txData, preBlockchainState, preStateVars, preInputVars, postBlockchainState, postStateVars, postInputVars, outputVars).\n\t/// Here we are interested in postInputVars.\n\tauto const* function = programFunction();\n\tsolAssert(function, \"\");\n\n\tauto stateVars = stateVariables();\n\tsolAssert(stateVars.has_value(), \"\");\n\n\tauto const& inParams = function->parameters();\n\n\tauto first = _args.begin() + static_cast<int>(firstArgIndex()) + static_cast<int>(stateVars->size()) * 2 + static_cast<int>(inParams.size()) + 1;\n\tauto last = first + static_cast<int>(inParams.size());\n\n\tsolAssert(first >= _args.begin() && first <= _args.end(), \"\");\n\tsolAssert(last >= _args.begin() && last <= _args.end(), \"\");\n\n\tstd::vector<smtutil::Expression> inValues(first, last);\n\tsolAssert(inValues.size() == inParams.size(), \"\");\n\tauto inTypes = SMTEncoder::replaceUserTypes(FunctionType(*function).parameterTypes());\n\treturn formatExpressions(inValues, inTypes);\n}\n\nstd::vector<std::optional<std::string>> Predicate::summaryPostOutputValues(std::vector<smtutil::Expression> const& _args) const\n{\n\t/// The signature of a function summary predicate is: summary(error, this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, txData, preBlockchainState, preStateVars, preInputVars, postBlockchainState, postStateVars, postInputVars, outputVars).\n\t/// Here we are interested in outputVars.\n\tauto const* function = programFunction();\n\tsolAssert(function, \"\");\n\n\tauto stateVars = stateVariables();\n\tsolAssert(stateVars.has_value(), \"\");\n\n\tauto const& inParams = function->parameters();\n\n\tauto first = _args.begin() + static_cast<int>(firstArgIndex()) + static_cast<int>(stateVars->size()) * 2 + static_cast<int>(inParams.size()) * 2 + 1;\n\n\tsolAssert(first >= _args.begin() && first <= _args.end(), \"\");\n\n\tstd::vector<smtutil::Expression> outValues(first, _args.end());\n\tsolAssert(outValues.size() == function->returnParameters().size(), \"\");\n\tauto outTypes = SMTEncoder::replaceUserTypes(FunctionType(*function).returnParameterTypes());\n\treturn formatExpressions(outValues, outTypes);\n}\n\nstd::pair<std::vector<std::optional<std::string>>, std::vector<VariableDeclaration const*>> Predicate::localVariableValues(std::vector<smtutil::Expression> const& _args) const\n{\n\t/// The signature of a local block predicate is:\n\t/// block(error, this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, txData, preBlockchainState, preStateVars, preInputVars, postBlockchainState, postStateVars, postInputVars, outputVars, localVars).\n\t/// Here we are interested in localVars.\n\tauto const* function = programFunction();\n\tsolAssert(function, \"\");\n\n\tauto const& localVars = SMTEncoder::localVariablesIncludingModifiers(*function, m_contractContext);\n\tauto first = _args.end() - static_cast<int>(localVars.size());\n\tstd::vector<smtutil::Expression> outValues(first, _args.end());\n\n\tauto mask = util::applyMap(\n\t\tlocalVars,\n\t\t[this](auto _var) {\n\t\t\tauto varScope = dynamic_cast<ScopeOpener const*>(_var->scope());\n\t\t\treturn find(begin(m_scopeStack), end(m_scopeStack), varScope) != end(m_scopeStack);\n\t\t}\n\t);\n\tauto localVarsInScope = util::filter(localVars, mask);\n\tauto outValuesInScope = util::filter(outValues, mask);\n\n\tauto outTypes = util::applyMap(localVarsInScope, [](auto _var) { return _var->type(); });\n\treturn {formatExpressions(outValuesInScope, outTypes), localVarsInScope};\n}\n\nstd::map<std::string, std::string> Predicate::expressionSubstitution(std::vector<std::string> const& _predArgs) const\n{\n\tstd::map<std::string, std::string> subst;\n\tstd::string predName = functor().name;\n\n\tsmtAssert(contextContract());\n\tauto const& stateVars = SMTEncoder::stateVariablesIncludingInheritedAndPrivate(*contextContract());\n\n\tauto const nArgs = _predArgs.size();\n\n\t// The signature of an interface predicate is\n\t// interface(this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, blockchainState, stateVariables).\n\t// An invariant for an interface predicate is a contract\n\t// invariant over its state, for example `x <= 0`.\n\tif (isInterface())\n\t{\n\t\tsmtAssert(nArgs > 0);\n\t\tsize_t shift = txValuesIndex();\n\t\tsmtAssert(predName.starts_with(\"interface\"));\n\t\tsubst[_predArgs.at(0)] = \"address(this)\";\n\t\tsmtAssert(nArgs == stateVars.size() + shift);\n\t\tfor (size_t i = nArgs - stateVars.size(); i < nArgs; ++i)\n\t\t\tsubst[_predArgs.at(i)] = stateVars.at(i - shift)->name();\n\t}\n\t// The signature of a nondet interface predicate is\n\t// nondet_interface(error, this, abiFunctions, (optionally) bytesConcatFunctions, cryptoFunctions, blockchainState, stateVariables, blockchainState', stateVariables').\n\t// An invariant for a nondet interface predicate is a reentrancy property\n\t// over the pre and post state variables of a contract, where pre state vars\n\t// are represented by the variable's name and post state vars are represented\n\t// by the primed variable's name, for example\n\t// `(x <= 0) => (x' <= 100)`.\n\telse if (isNondetInterface())\n\t{\n\t\tsmtAssert(nArgs > 1);\n\t\tsmtAssert(predName.starts_with(\"nondet_interface\"));\n\t\tsubst[_predArgs.at(0)] = \"<errorCode>\";\n\t\tsubst[_predArgs.at(1)] = \"address(this)\";\n\t\tsmtAssert(nArgs == stateVars.size() * 2 + firstArgIndex());\n\t\tfor (size_t i = nArgs - stateVars.size(), s = 0; i < nArgs; ++i, ++s)\n\t\t\tsubst[_predArgs.at(i)] = stateVars.at(s)->name() + \"'\";\n\t\tfor (size_t i = nArgs - (stateVars.size() * 2 + 1), s = 0; i < nArgs - (stateVars.size() + 1); ++i, ++s)\n\t\t\tsubst[_predArgs.at(i)] = stateVars.at(s)->name();\n\t}\n\n\treturn subst;\n}\n\n\nstd::map<std::string, std::optional<std::string>> Predicate::readTxVars(smtutil::Expression const& _tx) const\n{\n\tstd::map<std::string, Type const*> const txVars = transactionMemberTypes();\n\tstd::map<std::string, std::optional<std::string>> vars;\n\tfor (auto&& [i, v]: txVars | ranges::views::enumerate)\n\t\tvars.emplace(v.first, expressionToString(_tx.arguments.at(i), v.second));\n\treturn vars;\n}\n"
  },
  {
    "path": "libsolidity/formal/Predicate.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n\n#include <libsolidity/ast/ASTForward.h>\n#include <libsolidity/ast/Types.h>\n\n#include <libsmtutil/SolverInterface.h>\n#include <libsmtutil/Sorts.h>\n\n#include <map>\n#include <optional>\n#include <vector>\n\nnamespace solidity::langutil\n{\nclass CharStreamProvider;\n}\n\nnamespace solidity::frontend\n{\n\nnamespace smt\n{\nclass EncodingContext;\n}\n\nenum class PredicateType\n{\n\tInterface,\n\tNondetInterface,\n\tConstructorSummary,\n\tFunctionSummary,\n\tFunctionBlock,\n\tFunctionErrorBlock,\n\tInternalCall,\n\tExternalCallTrusted,\n\tExternalCallUntrusted,\n\tError,\n\tCustom\n};\n\n/**\n * Represents a predicate used by the CHC engine.\n */\nclass Predicate\n{\npublic:\n\tstatic Predicate const* create(\n\t\tsmtutil::SortPointer _sort,\n\t\tstd::string _name,\n\t\tPredicateType _type,\n\t\tsmt::EncodingContext& _context,\n\t\tASTNode const* _node = nullptr,\n\t\tContractDefinition const* _contractContext = nullptr,\n\t\tstd::vector<ScopeOpener const*> _scopeStack = {}\n\t);\n\n\tPredicate(\n\t\tstd::string _name,\n\t\tsmtutil::SortPointer _sort,\n\t\tPredicateType _type,\n\t\tbool _bytesConcatFunctionInContext,\n\t\tASTNode const* _node = nullptr,\n\t\tContractDefinition const* _contractContext = nullptr,\n\t\tstd::vector<ScopeOpener const*> _scopeStack = {}\n\t);\n\n\t/// Predicate should not be copiable.\n\tPredicate(Predicate const&) = delete;\n\tPredicate& operator=(Predicate const&) = delete;\n\n\t/// @returns the Predicate associated with _name.\n\tstatic Predicate const* predicate(std::string const& _name);\n\n\t/// Resets all the allocated predicates.\n\tstatic void reset();\n\n\t/// @returns a function application of the predicate over _args.\n\tsmtutil::Expression operator()(std::vector<smtutil::Expression> const& _args) const;\n\n\t/// @returns the function declaration of the predicate.\n\tsmtutil::Expression const& functor() const;\n\n\t/// @returns the program node this predicate represents.\n\tASTNode const* programNode() const;\n\n\t/// @returns the ContractDefinition of the most derived contract\n\t/// being analyzed.\n\tContractDefinition const* contextContract() const;\n\n\t/// @returns the ContractDefinition that this predicate represents\n\t/// or nullptr otherwise.\n\tContractDefinition const* programContract() const;\n\n\t/// @returns the FunctionDefinition that this predicate represents\n\t/// or nullptr otherwise.\n\tFunctionDefinition const* programFunction() const;\n\n\t/// @returns the FunctionCall that this predicate represents\n\t/// or nullptr otherwise.\n\tFunctionCall const* programFunctionCall() const;\n\n\t/// @returns the VariableDeclaration that this predicate represents\n\t/// or nullptr otherwise.\n\tVariableDeclaration const* programVariable() const;\n\n\t/// @returns the program state variables in the scope of this predicate.\n\tstd::optional<std::vector<VariableDeclaration const*>> stateVariables() const;\n\n\t/// @returns true if this predicate represents a summary.\n\tbool isSummary() const;\n\n\t/// @returns true if this predicate represents a function summary.\n\tbool isFunctionSummary() const;\n\n\t/// @returns true if this predicate represents a function block.\n\tbool isFunctionBlock() const;\n\n\t/// @returns true if this predicate represents a function error block.\n\tbool isFunctionErrorBlock() const;\n\n\t/// @returns true if this predicate represents an internal function call.\n\tbool isInternalCall() const;\n\n\t/// @returns true if this predicate represents a trusted external function call.\n\tbool isExternalCallTrusted() const;\n\n\t/// @returns true if this predicate represents an untrusted external function call.\n\tbool isExternalCallUntrusted() const;\n\n\t/// @returns true if this predicate represents a constructor summary.\n\tbool isConstructorSummary() const;\n\n\t/// @returns true if this predicate represents an interface.\n\tbool isInterface() const;\n\n\t/// @returns true if this predicate represents a nondeterministic interface.\n\tbool isNondetInterface() const;\n\n\tPredicateType type() const { return m_type; }\n\n\t/// @returns a formatted string representing a call to this predicate\n\t/// with _args.\n\tstd::string formatSummaryCall(\n\t\tstd::vector<smtutil::Expression> const& _args,\n\t\tlangutil::CharStreamProvider const& _charStreamProvider,\n\t\tbool _appendTxVars = false\n\t) const;\n\n\t/// @returns the values of the state variables from _args at the point\n\t/// where this summary was reached.\n\tstd::vector<std::optional<std::string>> summaryStateValues(std::vector<smtutil::Expression> const& _args) const;\n\n\t/// @returns the values of the function input variables from _args at the point\n\t/// where this summary was reached.\n\tstd::vector<std::optional<std::string>> summaryPostInputValues(std::vector<smtutil::Expression> const& _args) const;\n\n\t/// @returns the values of the function output variables from _args at the point\n\t/// where this summary was reached.\n\tstd::vector<std::optional<std::string>> summaryPostOutputValues(std::vector<smtutil::Expression> const& _args) const;\n\n\t/// @returns the values of the local variables used by this predicate.\n\tstd::pair<std::vector<std::optional<std::string>>, std::vector<VariableDeclaration const*>> localVariableValues(std::vector<smtutil::Expression> const& _args) const;\n\n\t/// @returns a substitution map from the predicate arguments @p _predArgs\n\t/// to a Solidity-like expression.\n\tstd::map<std::string, std::string> expressionSubstitution(std::vector<std::string> const& _predArgs) const;\n\nprivate:\n\t/// Recursively fills _array from _expr.\n\t/// _expr should have the form `store(store(...(const_array(x_0), i_0, e_0), i_m, e_m), i_k, e_k)`.\n\t/// @returns true if the construction worked,\n\t/// and false if at least one element could not be built.\n\tbool fillArray(smtutil::Expression const& _expr, std::vector<std::string>& _array, ArrayType const& _type) const;\n\n\tstd::map<std::string, std::optional<std::string>> readTxVars(smtutil::Expression const& _tx) const;\n\n\t/// @returns index at which transaction values start in args list\n\tsize_t txValuesIndex() const { return m_bytesConcatFunctionInContext ? 5 : 4; }\n\t/// @returns index at which function arguments start in args list\n\tsize_t firstArgIndex() const { return m_bytesConcatFunctionInContext ? 7 : 6; }\n\t/// @returns index at which state variables values start in args list\n\tsize_t firstStateVarIndex() const { return m_bytesConcatFunctionInContext ? 8 : 7; }\n\n\tsmtutil::Expression m_functor;\n\n\t/// The type of this predicate.\n\tPredicateType m_type;\n\n\t/// The ASTNode that this predicate represents.\n\t/// nullptr if this predicate is not associated with a specific program AST node.\n\tASTNode const* m_node = nullptr;\n\n\t/// The ContractDefinition that contains this predicate.\n\t/// nullptr if this predicate is not associated with a specific contract.\n\t/// This is unfortunately necessary because of virtual resolution for\n\t/// function nodes.\n\tContractDefinition const* m_contractContext = nullptr;\n\n\t/// Maps the name of the predicate to the actual Predicate.\n\t/// Used in counterexample generation.\n\tstatic std::map<std::string, Predicate> m_predicates;\n\n\t/// The scope stack when the predicate was created.\n\t/// Used to identify the subset of variables in scope.\n\tstd::vector<ScopeOpener const*> const m_scopeStack;\n\n\t/// True iff there is a bytes concat function in contract scope\n\tbool m_bytesConcatFunctionInContext;\n};\n\nstruct PredicateCompare\n{\n\tbool operator()(Predicate const* lhs, Predicate const* rhs) const\n\t{\n\t\t// We cannot use m_node->id() because different predicates may\n\t\t// represent the same program node.\n\t\t// We use the symbolic name since it is unique per predicate and\n\t\t// the order does not really matter.\n\t\treturn lhs->functor().name < rhs->functor().name;\n\t}\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/PredicateInstance.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/PredicateInstance.h>\n\n#include <libsolidity/formal/EncodingContext.h>\n#include <libsolidity/formal/SMTEncoder.h>\n\nusing namespace solidity::util;\nusing namespace solidity::smtutil;\n\nnamespace solidity::frontend::smt\n{\nsmtutil::Expression interfacePre(Predicate const& _pred, ContractDefinition const& _contract, EncodingContext& _context)\n{\n\tauto& state = _context.state();\n\tstd::vector<smtutil::Expression> stateExprs = getStateExpressionsForInterfacePre(state);\n\treturn _pred(stateExprs + initialStateVariables(_contract, _context));\n}\n\nsmtutil::Expression interface(Predicate const& _pred, ContractDefinition const& _contract, EncodingContext& _context)\n{\n\tauto const& state = _context.state();\n\tstd::vector<smtutil::Expression> stateExprs = getStateExpressionsForInterface(state);\n\treturn _pred(stateExprs + currentStateVariables(_contract, _context));\n}\n\nsmtutil::Expression nondetInterface(\n\tPredicate const& _pred,\n\tContractDefinition const& _contract,\n\tEncodingContext& _context,\n\tunsigned _preIdx,\n\tunsigned _postIdx)\n{\n\tauto const& state = _context.state();\n\tstd::vector<smtutil::Expression> stateExprs = getStateExpressionsForNondetInterface(state);\n\treturn _pred(\n\t\tstateExprs +\n\t\tstd::vector<smtutil::Expression>{_context.state().state(_preIdx)} +\n\t\tstateVariablesAtIndex(_preIdx, _contract, _context) +\n\t\tstd::vector<smtutil::Expression>{_context.state().state(_postIdx)} +\n\t\tstateVariablesAtIndex(_postIdx, _contract, _context)\n\t);\n}\n\nsmtutil::Expression constructor(Predicate const& _pred, EncodingContext& _context)\n{\n\tauto const& contract = dynamic_cast<ContractDefinition const&>(*_pred.programNode());\n\tif (auto const* constructor = contract.constructor())\n\t\treturn _pred(currentFunctionVariablesForDefinition(*constructor, &contract, _context));\n\n\tauto& state = _context.state();\n\tstd::vector<smtutil::Expression> stateExprs = getStateExpressionsForConstructor(state);\n\treturn _pred(stateExprs + initialStateVariables(contract, _context) + currentStateVariables(contract, _context));\n}\n\nsmtutil::Expression constructorCall(Predicate const& _pred, EncodingContext& _context, bool _internal)\n{\n\tauto const& contract = dynamic_cast<ContractDefinition const&>(*_pred.programNode());\n\tif (auto const* constructor = contract.constructor())\n\t\treturn _pred(currentFunctionVariablesForCall(*constructor, &contract, _context, _internal));\n\n\tauto& state = _context.state();\n\tstd::vector<smtutil::Expression> stateExprs = getStateExpressionsForCall(state, _internal);\n\tstate.newState();\n\tstateExprs += std::vector<smtutil::Expression>{state.state()};\n\tstateExprs += currentStateVariables(contract, _context);\n\tstateExprs += newStateVariables(contract, _context);\n\treturn _pred(stateExprs);\n}\n\nsmtutil::Expression function(\n\tPredicate const& _pred,\n\tContractDefinition const* _contract,\n\tEncodingContext& _context\n)\n{\n\tauto const& function = dynamic_cast<FunctionDefinition const&>(*_pred.programNode());\n\treturn _pred(currentFunctionVariablesForDefinition(function, _contract, _context));\n}\n\nsmtutil::Expression functionCall(\n\tPredicate const& _pred,\n\tContractDefinition const* _contract,\n\tEncodingContext& _context\n)\n{\n\tauto const& function = dynamic_cast<FunctionDefinition const&>(*_pred.programNode());\n\treturn _pred(currentFunctionVariablesForCall(function, _contract, _context));\n}\n\nsmtutil::Expression functionBlock(\n\tPredicate const& _pred,\n\tFunctionDefinition const& _function,\n\tContractDefinition const* _contract,\n\tEncodingContext& _context\n)\n{\n\treturn _pred(currentBlockVariables(_function, _contract, _context));\n}\n\n/// Helpers\n\nstd::vector<smtutil::Expression> initialStateVariables(ContractDefinition const& _contract, EncodingContext& _context)\n{\n\treturn stateVariablesAtIndex(0, _contract, _context);\n}\n\nstd::vector<smtutil::Expression> stateVariablesAtIndex(unsigned _index, ContractDefinition const& _contract, EncodingContext& _context)\n{\n\treturn applyMap(\n\t\tSMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract),\n\t\t[&](auto _var) { return _context.variable(*_var)->valueAtIndex(_index); }\n\t);\n}\n\nstd::vector<smtutil::Expression> currentStateVariables(ContractDefinition const& _contract, EncodingContext& _context)\n{\n\treturn applyMap(\n\t\tSMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract),\n\t\t[&](auto _var) { return _context.variable(*_var)->currentValue(); }\n\t);\n}\n\nstd::vector<smtutil::Expression> newStateVariables(ContractDefinition const& _contract, EncodingContext& _context)\n{\n\treturn applyMap(\n\t\tSMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract),\n\t\t[&](auto _var) { return _context.variable(*_var)->increaseIndex(); }\n\t);\n}\n\nstd::vector<smtutil::Expression> currentFunctionVariablesForDefinition(\n\tFunctionDefinition const& _function,\n\tContractDefinition const* _contract,\n\tEncodingContext& _context\n)\n{\n\tauto& state = _context.state();\n\tstd::vector<smtutil::Expression> exprs = getStateExpressionsForDefinition(state);\n\texprs += _contract ? initialStateVariables(*_contract, _context) : std::vector<smtutil::Expression>{};\n\texprs += applyMap(_function.parameters(), [&](auto _var) { return _context.variable(*_var)->valueAtIndex(0); });\n\texprs += std::vector<smtutil::Expression>{state.state()};\n\texprs += _contract ? currentStateVariables(*_contract, _context) : std::vector<smtutil::Expression>{};\n\texprs += applyMap(_function.parameters(), [&](auto _var) { return _context.variable(*_var)->currentValue(); });\n\texprs += applyMap(_function.returnParameters(), [&](auto _var) { return _context.variable(*_var)->currentValue(); });\n\treturn exprs;\n}\n\nstd::vector<smtutil::Expression> currentFunctionVariablesForCall(\n\tFunctionDefinition const& _function,\n\tContractDefinition const* _contract,\n\tEncodingContext& _context,\n\tbool _internal\n)\n{\n\tauto& state = _context.state();\n\tstd::vector<smtutil::Expression> exprs = getStateExpressionsForCall(state, _internal);\n\texprs += _contract ? currentStateVariables(*_contract, _context) : std::vector<smtutil::Expression>{};\n\texprs += applyMap(_function.parameters(), [&](auto _var) { return _context.variable(*_var)->currentValue(); });\n\n\tstate.newState();\n\n\texprs += std::vector<smtutil::Expression>{state.state()};\n\texprs += _contract ? newStateVariables(*_contract, _context) : std::vector<smtutil::Expression>{};\n\texprs += applyMap(_function.parameters(), [&](auto _var) { return _context.variable(*_var)->increaseIndex(); });\n\texprs += applyMap(_function.returnParameters(), [&](auto _var) { return _context.variable(*_var)->currentValue(); });\n\treturn exprs;\n}\n\nstd::vector<smtutil::Expression> currentBlockVariables(FunctionDefinition const& _function, ContractDefinition const* _contract, EncodingContext& _context)\n{\n\treturn currentFunctionVariablesForDefinition(_function, _contract, _context) +\n\t\tapplyMap(\n\t\t\tSMTEncoder::localVariablesIncludingModifiers(_function, _contract),\n\t\t\t[&](auto _var) { return _context.variable(*_var)->currentValue(); }\n\t\t);\n}\n\nstd::vector<smtutil::Expression> getStateExpressionsForInterfacePre(SymbolicState const& _state)\n{\n\tif (_state.hasBytesConcatFunction())\n\t\treturn {_state.thisAddress(0),\n\t\t\t_state.abi(0), _state.bytesConcat(0), _state.crypto(0), _state.state(0)};\nreturn {_state.thisAddress(0), _state.abi(0),  _state.crypto(0), _state.state(0)};\n}\n\nstd::vector<smtutil::Expression> getStateExpressionsForInterface(SymbolicState const& _state)\n{\n\tif (_state.hasBytesConcatFunction())\n\t\treturn {_state.thisAddress(0), _state.abi(0), _state.bytesConcat(0), _state.crypto(0), _state.state()};\n\treturn {_state.thisAddress(0), _state.abi(0), _state.crypto(0), _state.state()};\n}\n\nstd::vector<smtutil::Expression> getStateExpressionsForNondetInterface(SymbolicState const& _state)\n{\n\tif (_state.hasBytesConcatFunction())\n\t\treturn {_state.errorFlag().currentValue(), _state.thisAddress(), _state.abi(), _state.bytesConcat(), _state.crypto()};\n\treturn {_state.errorFlag().currentValue(), _state.thisAddress(), _state.abi(), _state.crypto()};\n}\n\nstd::vector<smtutil::Expression> getStateExpressionsForConstructor(SymbolicState const& _state)\n{\n\tif (_state.hasBytesConcatFunction())\n\t\treturn {_state.errorFlag().currentValue(), _state.thisAddress(0), _state.abi(0),\n\t\t\t_state.bytesConcat(0), _state.crypto(0), _state.tx(0), _state.state(0), _state.state()};\n\treturn {_state.errorFlag().currentValue(), _state.thisAddress(0), _state.abi(0),\n\t\t_state.crypto(0), _state.tx(0), _state.state(0), _state.state()};\n}\n\nstd::vector<smtutil::Expression> getStateExpressionsForCall(SymbolicState const& _state, bool _internal)\n{\n\tif (_state.hasBytesConcatFunction())\n\t\treturn {_state.errorFlag().currentValue(), _internal ? _state.thisAddress(0) : _state.thisAddress(),\n\t\t\t_state.abi(0), _state.bytesConcat(0), _state.crypto(0), _internal ? _state.tx(0) : _state.tx(), _state.state()};\n\treturn {_state.errorFlag().currentValue(), _internal ? _state.thisAddress(0) : _state.thisAddress(),\n\t\t\t_state.abi(0), _state.crypto(0), _internal ? _state.tx(0) : _state.tx(), _state.state()};\n}\n\nstd::vector<smtutil::Expression> getStateExpressionsForDefinition(SymbolicState const& _state)\n{\n\tif (_state.hasBytesConcatFunction())\n\t\treturn {_state.errorFlag().currentValue(), _state.thisAddress(0), _state.abi(0),\n\t\t\t_state.bytesConcat(0), _state.crypto(0), _state.tx(0), _state.state(0)};\n\treturn {_state.errorFlag().currentValue(), _state.thisAddress(0), _state.abi(0),\n\t\t_state.crypto(0), _state.tx(0), _state.state(0)};\n}\n}\n"
  },
  {
    "path": "libsolidity/formal/PredicateInstance.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/formal/Predicate.h>\n#include <libsolidity/formal/SymbolicState.h>\n\nnamespace solidity::frontend::smt\n{\n\nclass EncodingContext;\n\n/**\n * This file represents the specification for building CHC predicate instances.\n * The predicates follow the specification in PredicateSort.h.\n * */\n\nsmtutil::Expression interfacePre(Predicate const& _pred, ContractDefinition const& _contract, EncodingContext& _context);\n\nsmtutil::Expression interface(Predicate const& _pred, ContractDefinition const& _contract, EncodingContext& _context);\n\nsmtutil::Expression nondetInterface(Predicate const& _pred, ContractDefinition const& _contract, EncodingContext& _context, unsigned _preIdx, unsigned _postIdx);\n\nsmtutil::Expression constructor(Predicate const& _pred, EncodingContext& _context);\n/// The encoding of the deployment procedure includes adding constraints\n/// for base constructors if inheritance is used.\n/// From the predicate point of view this is not different,\n/// but some of the arguments are different.\n/// @param _internal = true means that this constructor call is used in the\n/// deployment procedure, whereas false means it is used in the deployment\n/// of a contract.\nsmtutil::Expression constructorCall(Predicate const& _pred, EncodingContext& _context, bool _internal = true);\n\nsmtutil::Expression function(\n\tPredicate const& _pred,\n\tContractDefinition const* _contract,\n\tEncodingContext& _context\n);\n\nsmtutil::Expression functionCall(\n\tPredicate const& _pred,\n\tContractDefinition const* _contract,\n\tEncodingContext& _context\n);\n\nsmtutil::Expression functionBlock(\n\tPredicate const& _pred,\n\tFunctionDefinition const& _function,\n\tContractDefinition const* _contract,\n\tEncodingContext& _context\n);\n\n/// Helpers\n\nstd::vector<smtutil::Expression> initialStateVariables(ContractDefinition const& _contract, EncodingContext& _context);\n\nstd::vector<smtutil::Expression> stateVariablesAtIndex(unsigned _index, ContractDefinition const& _contract, EncodingContext& _context);\n\nstd::vector<smtutil::Expression> currentStateVariables(ContractDefinition const& _contract, EncodingContext& _context);\n\nstd::vector<smtutil::Expression> newStateVariables(ContractDefinition const& _contract, EncodingContext& _context);\n\nstd::vector<smtutil::Expression> currentFunctionVariablesForDefinition(\n\tFunctionDefinition const& _function,\n\tContractDefinition const* _contract,\n\tEncodingContext& _context\n);\n\nstd::vector<smtutil::Expression> currentFunctionVariablesForCall(\n\tFunctionDefinition const& _function,\n\tContractDefinition const* _contract,\n\tEncodingContext& _context,\n\tbool _internal = true\n);\n\nstd::vector<smtutil::Expression> currentBlockVariables(\n\tFunctionDefinition const& _function,\n\tContractDefinition const* _contract,\n\tEncodingContext& _context\n);\n\nstd::vector<smtutil::Expression> getStateExpressionsForInterfacePre(SymbolicState const& _state);\nstd::vector<smtutil::Expression> getStateExpressionsForInterface(SymbolicState  const& _state);\nstd::vector<smtutil::Expression> getStateExpressionsForNondetInterface(SymbolicState  const& _state);\nstd::vector<smtutil::Expression> getStateExpressionsForConstructor(SymbolicState  const& _state);\nstd::vector<smtutil::Expression> getStateExpressionsForCall(SymbolicState  const& _state, bool _internal);\nstd::vector<smtutil::Expression> getStateExpressionsForDefinition(SymbolicState  const& _state);\n}\n"
  },
  {
    "path": "libsolidity/formal/PredicateSort.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/PredicateSort.h>\n\n#include <libsolidity/formal/SMTEncoder.h>\n#include <libsolidity/formal/SymbolicTypes.h>\n\nusing namespace solidity::util;\nusing namespace solidity::smtutil;\n\nnamespace solidity::frontend::smt\n{\n\nSortPointer interfaceSort(ContractDefinition const& _contract, SymbolicState& _state)\n{\n\treturn std::make_shared<FunctionSort>(\n\t\tstd::vector<SortPointer>{_state.thisAddressSort()} +\n\t\t\tgetBuiltInFunctionsSorts(_state) +\n\t\t\tstd::vector<SortPointer>{_state.stateSort()} +\n\t\t\tstateSorts(_contract),\n\t\tSortProvider::boolSort\n\t);\n}\n\nSortPointer nondetInterfaceSort(ContractDefinition const& _contract, SymbolicState& _state)\n{\n\tauto varSorts = stateSorts(_contract);\n\tstd::vector<SortPointer> stateSort{_state.stateSort()};\n\treturn std::make_shared<FunctionSort>(\n\t\tstd::vector<SortPointer>{_state.errorFlagSort(), _state.thisAddressSort()} +\n\t\t\tgetBuiltInFunctionsSorts(_state) +\n\t\t\tstateSort +\n\t\t\tvarSorts +\n\t\t\tstateSort +\n\t\t\tvarSorts,\n\t\tSortProvider::boolSort\n\t);\n}\n\nSortPointer constructorSort(ContractDefinition const& _contract, SymbolicState& _state)\n{\n\tif (auto const* constructor = _contract.constructor())\n\t\treturn functionSort(*constructor, &_contract, _state);\n\n\tauto varSorts = stateSorts(_contract);\n\tstd::vector<SortPointer> stateSort{_state.stateSort()};\n\treturn std::make_shared<FunctionSort>(\n\t\tstd::vector<SortPointer>{_state.errorFlagSort(), _state.thisAddressSort()} +\n\t\t\tgetBuiltInFunctionsSorts(_state) +\n\t\t\tstd::vector<SortPointer>{_state.txSort(), _state.stateSort(), _state.stateSort()} +\n\t\t\tvarSorts + varSorts,\n\t\tSortProvider::boolSort\n\t);\n}\n\nSortPointer functionSort(FunctionDefinition const& _function, ContractDefinition const* _contract, SymbolicState& _state)\n{\n\tauto smtSort = [](auto _var) { return smt::smtSortAbstractFunction(*_var->type()); };\n\tauto varSorts = _contract ? stateSorts(*_contract) : std::vector<SortPointer>{};\n\tauto inputSorts = applyMap(_function.parameters(), smtSort);\n\tauto outputSorts = applyMap(_function.returnParameters(), smtSort);\n\treturn std::make_shared<FunctionSort>(\n\t\tstd::vector<SortPointer>{_state.errorFlagSort(), _state.thisAddressSort()} +\n\t\t\tgetBuiltInFunctionsSorts(_state) +\n\t\t\tstd::vector<SortPointer>{_state.txSort(), _state.stateSort()} +\n\t\t\tvarSorts +\n\t\t\tinputSorts +\n\t\t\tstd::vector<SortPointer>{_state.stateSort()} +\n\t\t\tvarSorts +\n\t\t\tinputSorts +\n\t\t\toutputSorts,\n\t\tSortProvider::boolSort\n\t);\n}\n\nSortPointer functionBodySort(FunctionDefinition const& _function, ContractDefinition const* _contract, SymbolicState& _state)\n{\n\tauto fSort = std::dynamic_pointer_cast<FunctionSort>(functionSort(_function, _contract, _state));\n\tsolAssert(fSort, \"\");\n\n\tauto smtSort = [](auto _var) { return smt::smtSortAbstractFunction(*_var->type()); };\n\treturn std::make_shared<FunctionSort>(\n\t\tfSort->domain + applyMap(SMTEncoder::localVariablesIncludingModifiers(_function, _contract), smtSort),\n\t\tSortProvider::boolSort\n\t);\n}\n\nSortPointer arity0FunctionSort()\n{\n\treturn std::make_shared<FunctionSort>(\n\t\tstd::vector<SortPointer>(),\n\t\tSortProvider::boolSort\n\t);\n}\n\n/// Helpers\n\nstd::vector<SortPointer> stateSorts(ContractDefinition const& _contract)\n{\n\treturn applyMap(\n\t\tSMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract),\n\t\t[](auto _var) { return smt::smtSortAbstractFunction(*_var->type()); }\n\t);\n}\n\nstd::vector<SortPointer> getBuiltInFunctionsSorts(SymbolicState& _state)\n{\n\tif (_state.hasBytesConcatFunction())\n\t\treturn {_state.abiSort(), _state.bytesConcatSort(), _state.cryptoSort()};\n\treturn {_state.abiSort(), _state.cryptoSort()};\n}\n}\n"
  },
  {
    "path": "libsolidity/formal/PredicateSort.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/formal/Predicate.h>\n\n#include <libsolidity/formal/SymbolicState.h>\n\n#include <libsmtutil/Sorts.h>\n\nnamespace solidity::frontend::smt\n{\n\n/**\n * This file represents the specification for CHC predicate sorts.\n * Types of predicates:\n *\n * 1. Interface\n * The idle state of a contract. Signature:\n * interface(this, abiFunctions, cryptoFunctions, blockchainState, stateVariables).\n *\n * 2. Nondet interface\n * The nondeterminism behavior of a contract. Signature:\n * nondet_interface(error, this, abiFunctions, cryptoFunctions, blockchainState, stateVariables, blockchainState', stateVariables').\n *\n * 3. Constructor entry/summary\n * The summary of a contract's deployment procedure.\n * Signature:\n * If the contract has a constructor function, this is the same as the summary of that function. Otherwise:\n * constructor_summary(error, this, abiFunctions, cryptoFunctions, txData, blockchainState, blockchainState', stateVariables, stateVariables').\n *\n * 4. Function entry/summary\n * The entry point of a function definition. Signature:\n * function_entry(error, this, abiFunctions, cryptoFunctions, txData, blockchainState, stateVariables, inputVariables, blockchainState', stateVariables', inputVariables', outputVariables').\n *\n * 5. Function body\n * Use for any predicate within a function. Signature:\n * function_body(error, this, abiFunctions, cryptoFunctions, txData, blockchainState, stateVariables, inputVariables, blockchainState', stateVariables', inputVariables', outputVariables', localVariables).\n */\n\n/// @returns the interface predicate sort for _contract.\nsmtutil::SortPointer interfaceSort(ContractDefinition const& _contract, SymbolicState& _state);\n\n/// @returns the nondeterminisc interface predicate sort for _contract.\nsmtutil::SortPointer nondetInterfaceSort(ContractDefinition const& _contract, SymbolicState& _state);\n\n/// @returns the constructor entry/summary predicate sort for _contract.\nsmtutil::SortPointer constructorSort(ContractDefinition const& _contract, SymbolicState& _state);\n\n/// @returns the function entry/summary predicate sort for _function contained in _contract.\nsmtutil::SortPointer functionSort(FunctionDefinition const& _function, ContractDefinition const* _contract, SymbolicState& _state);\n\n/// @returns the function body predicate sort for _function contained in _contract.\nsmtutil::SortPointer functionBodySort(FunctionDefinition const& _function, ContractDefinition const* _contract, SymbolicState& _state);\n\n/// @returns the sort of a predicate without parameters.\nsmtutil::SortPointer arity0FunctionSort();\n\n/// Helpers\n\nstd::vector<smtutil::SortPointer> stateSorts(ContractDefinition const& _contract);\n\nstd::vector<smtutil::SortPointer> getBuiltInFunctionsSorts(SymbolicState& _state);\n\n}\n"
  },
  {
    "path": "libsolidity/formal/SMTEncoder.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/SMTEncoder.h>\n\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/formal/SymbolicState.h>\n#include <libsolidity/formal/SymbolicTypes.h>\n\n#include <libsolidity/analysis/ConstantEvaluator.h>\n\n#include <libyul/AST.h>\n#include <libyul/optimiser/Semantics.h>\n\n#include <libsmtutil/SMTPortfolio.h>\n#include <libsmtutil/Helpers.h>\n\n#include <liblangutil/CharStreamProvider.h>\n\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/FunctionSelector.h>\n\n#include <range/v3/view.hpp>\n\n#include <limits>\n#include <deque>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace std::string_literals;\n\nSMTEncoder::SMTEncoder(\n\tsmt::EncodingContext& _context,\n\tModelCheckerSettings _settings,\n\tUniqueErrorReporter& _errorReporter,\n\tUniqueErrorReporter& _unsupportedErrorReporter,\n\tErrorReporter& _provedSafeReporter,\n\tlangutil::CharStreamProvider const& _charStreamProvider\n):\n\tm_errorReporter(_errorReporter),\n\tm_unsupportedErrors(_unsupportedErrorReporter),\n\tm_provedSafeReporter(_provedSafeReporter),\n\tm_context(_context),\n\tm_settings(std::move(_settings)),\n\tm_charStreamProvider(_charStreamProvider)\n{\n}\n\nvoid SMTEncoder::resetSourceAnalysis()\n{\n\tm_freeFunctions.clear();\n}\n\nbool SMTEncoder::visit(ContractDefinition const& _contract)\n{\n\tsolAssert(m_currentContract, \"\");\n\n\tfor (auto const& node: _contract.subNodes())\n\t\tif (\n\t\t\t!std::dynamic_pointer_cast<FunctionDefinition>(node) &&\n\t\t\t!std::dynamic_pointer_cast<VariableDeclaration>(node)\n\t\t)\n\t\t\tnode->accept(*this);\n\n\tfor (auto const& base: _contract.annotation().linearizedBaseContracts)\n\t{\n\t\t// Look for all the constructor invocations bottom up.\n\t\tif (auto const& constructor =  base->constructor())\n\t\t\tfor (auto const& invocation: constructor->modifiers())\n\t\t\t{\n\t\t\t\tauto refDecl = invocation->name().annotation().referencedDeclaration;\n\t\t\t\tif (auto const& baseContract = dynamic_cast<ContractDefinition const*>(refDecl))\n\t\t\t\t{\n\t\t\t\t\tsolAssert(!m_baseConstructorCalls.count(baseContract), \"\");\n\t\t\t\t\tm_baseConstructorCalls[baseContract] = invocation.get();\n\t\t\t\t}\n\t\t\t}\n\t}\n\t// Functions are visited first since they might be used\n\t// for state variable initialization which is part of\n\t// the constructor.\n\t// Constructors are visited as part of the constructor\n\t// hierarchy inlining.\n\tfor (auto const* function: contractFunctionsWithoutVirtual(_contract) + allFreeFunctions())\n\t\tif (!function->isConstructor())\n\t\t\tfunction->accept(*this);\n\n\t// Constructors need to be handled by the engines separately.\n\n\treturn false;\n}\n\nvoid SMTEncoder::endVisit(ContractDefinition const& _contract)\n{\n\tm_context.resetAllVariables();\n\n\tm_baseConstructorCalls.clear();\n\n\tsolAssert(m_currentContract == &_contract, \"\");\n\tm_currentContract = nullptr;\n\n\tif (m_callStack.empty())\n\t\tm_context.popSolver();\n}\n\nbool SMTEncoder::visit(ImportDirective const&)\n{\n\t// do not visit because the identifier therein will confuse us.\n\treturn false;\n}\n\nvoid SMTEncoder::endVisit(VariableDeclaration const& _varDecl)\n{\n\t// State variables are handled by the constructor.\n\tif (_varDecl.isLocalVariable() &&_varDecl.value())\n\t\tassignment(_varDecl, *_varDecl.value());\n}\n\nbool SMTEncoder::visit(ModifierDefinition const&)\n{\n\treturn false;\n}\n\nbool SMTEncoder::visit(FunctionDefinition const& _function)\n{\n\tsolAssert(m_currentContract, \"\");\n\n\tm_modifierDepthStack.push_back(-1);\n\n\tinitializeLocalVariables(_function);\n\n\t_function.parameterList().accept(*this);\n\tif (_function.returnParameterList())\n\t\t_function.returnParameterList()->accept(*this);\n\n\tvisitFunctionOrModifier();\n\n\treturn false;\n}\n\nvoid SMTEncoder::visitFunctionOrModifier()\n{\n\tsolAssert(!m_callStack.empty(), \"\");\n\tsolAssert(!m_modifierDepthStack.empty(), \"\");\n\n\t++m_modifierDepthStack.back();\n\tFunctionDefinition const& function = dynamic_cast<FunctionDefinition const&>(*m_callStack.back().first);\n\n\tif (m_modifierDepthStack.back() == static_cast<int>(function.modifiers().size()))\n\t{\n\t\tif (function.isImplemented())\n\t\t{\n\t\t\tpushInlineFrame(function);\n\t\t\tfunction.body().accept(*this);\n\t\t\tpopInlineFrame(function);\n\t\t}\n\t}\n\telse\n\t{\n\t\tsolAssert(m_modifierDepthStack.back() < static_cast<int>(function.modifiers().size()), \"\");\n\t\tASTPointer<ModifierInvocation> const& modifierInvocation =\n\t\t\tfunction.modifiers()[static_cast<size_t>(m_modifierDepthStack.back())];\n\t\tsolAssert(modifierInvocation, \"\");\n\t\tauto refDecl = modifierInvocation->name().annotation().referencedDeclaration;\n\t\tif (dynamic_cast<ContractDefinition const*>(refDecl))\n\t\t\tvisitFunctionOrModifier();\n\t\telse if (auto modifier = resolveModifierInvocation(*modifierInvocation, m_currentContract))\n\t\t{\n\t\t\tm_scopes.push_back(modifier);\n\t\t\tinlineModifierInvocation(modifierInvocation.get(), modifier);\n\t\t\tsolAssert(m_scopes.back() == modifier, \"\");\n\t\t\tm_scopes.pop_back();\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"\");\n\t}\n\n\t--m_modifierDepthStack.back();\n}\n\nvoid SMTEncoder::inlineModifierInvocation(ModifierInvocation const* _invocation, CallableDeclaration const* _definition)\n{\n\tsolAssert(_invocation, \"\");\n\t_invocation->accept(*this);\n\n\tstd::vector<smtutil::Expression> args;\n\tif (auto const* arguments = _invocation->arguments())\n\t{\n\t\tauto const& modifierParams = _definition->parameters();\n\t\tsolAssert(modifierParams.size() == arguments->size(), \"\");\n\t\tfor (unsigned i = 0; i < arguments->size(); ++i)\n\t\t\targs.push_back(expr(*arguments->at(i), modifierParams.at(i)->type()));\n\t}\n\n\tinitializeFunctionCallParameters(*_definition, args);\n\n\tpushCallStack({_definition, _invocation});\n\tpushInlineFrame(*_definition);\n\tif (auto modifier = dynamic_cast<ModifierDefinition const*>(_definition))\n\t{\n\t\tif (modifier->isImplemented())\n\t\t\tmodifier->body().accept(*this);\n\t\tpopCallStack();\n\t}\n\telse if (auto function = dynamic_cast<FunctionDefinition const*>(_definition))\n\t{\n\t\tif (function->isImplemented())\n\t\t\tfunction->accept(*this);\n\t\t// Functions are popped from the callstack in endVisit(FunctionDefinition)\n\t}\n\tpopInlineFrame(*_definition);\n}\n\nvoid SMTEncoder::inlineConstructorHierarchy(ContractDefinition const& _contract)\n{\n\tauto const& hierarchy = m_currentContract->annotation().linearizedBaseContracts;\n\tauto it = find(begin(hierarchy), end(hierarchy), &_contract);\n\tsolAssert(it != end(hierarchy), \"\");\n\n\tauto nextBase = it + 1;\n\t// Initialize the base contracts here as long as their constructors are implicit,\n\t// stop when the first explicit constructor is found.\n\twhile (nextBase != end(hierarchy))\n\t{\n\t\tif (auto baseConstructor = (*nextBase)->constructor())\n\t\t{\n\t\t\tcreateLocalVariables(*baseConstructor);\n\t\t\t// If any subcontract explicitly called baseConstructor, use those arguments.\n\t\t\tif (m_baseConstructorCalls.count(*nextBase))\n\t\t\t\tinlineModifierInvocation(m_baseConstructorCalls.at(*nextBase), baseConstructor);\n\t\t\telse if (baseConstructor->isImplemented())\n\t\t\t{\n\t\t\t\t// The first constructor found is handled like a function\n\t\t\t\t// and its pushed into the callstack there.\n\t\t\t\t// This if avoids duplication in the callstack.\n\t\t\t\tif (!m_callStack.empty())\n\t\t\t\t\tpushCallStack({baseConstructor, nullptr});\n\t\t\t\tbaseConstructor->accept(*this);\n\t\t\t\t// popped by endVisit(FunctionDefinition)\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tinitializeStateVariables(**nextBase);\n\t\t\t++nextBase;\n\t\t}\n\t}\n\n\tinitializeStateVariables(_contract);\n}\n\nbool SMTEncoder::visit(PlaceholderStatement const&)\n{\n\tsolAssert(!m_callStack.empty(), \"\");\n\tauto lastCall = popCallStack();\n\tvisitFunctionOrModifier();\n\tpushCallStack(lastCall);\n\treturn true;\n}\n\nvoid SMTEncoder::endVisit(FunctionDefinition const&)\n{\n\tsolAssert(m_currentContract, \"\");\n\n\tpopCallStack();\n\tsolAssert(m_modifierDepthStack.back() == -1, \"\");\n\tm_modifierDepthStack.pop_back();\n\tif (m_callStack.empty())\n\t\tm_context.popSolver();\n}\n\nbool SMTEncoder::visit(Block const& _block)\n{\n\tif (_block.unchecked())\n\t{\n\t\tsolAssert(m_checked, \"\");\n\t\tm_checked = false;\n\t}\n\treturn true;\n}\n\nvoid SMTEncoder::endVisit(Block const& _block)\n{\n\tif (_block.unchecked())\n\t{\n\t\tsolAssert(!m_checked, \"\");\n\t\tm_checked = true;\n\t}\n}\n\nbool SMTEncoder::visit(InlineAssembly const& _inlineAsm)\n{\n\t/// This is very similar to `yul::Assignments`, except I need to collect `Identifier`s and not just names as `YulString`s.\n\tstruct AssignedExternalsCollector: public yul::ASTWalker\n\t{\n\t\tAssignedExternalsCollector(InlineAssembly const& _inlineAsm): externalReferences(_inlineAsm.annotation().externalReferences)\n\t\t{\n\t\t\tthis->operator()(_inlineAsm.operations().root());\n\t\t}\n\n\t\tstd::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> const& externalReferences;\n\t\tstd::set<VariableDeclaration const*> assignedVars;\n\n\t\tusing yul::ASTWalker::operator();\n\t\tvoid operator()(yul::Assignment const& _assignment)\n\t\t{\n\t\t\tauto const& vars = _assignment.variableNames;\n\t\t\tfor (auto const& identifier: vars)\n\t\t\t\tif (auto externalInfo = util::valueOrNullptr(externalReferences, &identifier))\n\t\t\t\t\tif (auto varDecl = dynamic_cast<VariableDeclaration const*>(externalInfo->declaration))\n\t\t\t\t\t\tassignedVars.insert(varDecl);\n\t\t}\n\t};\n\n\tyul::SideEffectsCollector sideEffectsCollector(_inlineAsm.dialect(), _inlineAsm.operations().root());\n\tif (sideEffectsCollector.invalidatesMemory())\n\t\tresetMemoryVariables();\n\tif (sideEffectsCollector.invalidatesStorage())\n\t\tresetStorageVariables();\n\n\tauto assignedVars = AssignedExternalsCollector(_inlineAsm).assignedVars;\n\tfor (auto const* var: assignedVars)\n\t{\n\t\tsolAssert(var, \"\");\n\t\tsolAssert(var->isLocalVariable(), \"Non-local variable assigned in inlined assembly\");\n\t\tm_context.resetVariable(*var);\n\t}\n\n\tm_unsupportedErrors.warning(\n\t\t7737_error,\n\t\t_inlineAsm.location(),\n\t\t\"Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\"\n\t);\n\treturn false;\n}\n\nvoid SMTEncoder::pushInlineFrame(CallableDeclaration const&)\n{\n\tpushPathCondition(currentPathConditions());\n}\n\nvoid SMTEncoder::popInlineFrame(CallableDeclaration const&)\n{\n\tpopPathCondition();\n}\n\nvoid SMTEncoder::endVisit(VariableDeclarationStatement const& _varDecl)\n{\n\tif (auto init = _varDecl.initialValue())\n\t\texpressionToTupleAssignment(_varDecl.declarations(), *init);\n}\n\nbool SMTEncoder::visit(Assignment const& _assignment)\n{\n\t// RHS must be visited before LHS; as opposed to what Assignment::accept does\n\t_assignment.rightHandSide().accept(*this);\n\t_assignment.leftHandSide().accept(*this);\n\treturn false;\n}\n\nvoid SMTEncoder::endVisit(Assignment const& _assignment)\n{\n\tcreateExpr(_assignment);\n\n\tToken op = _assignment.assignmentOperator();\n\tsolAssert(TokenTraits::isAssignmentOp(op), \"\");\n\n\tif (!isSupportedType(*_assignment.annotation().type))\n\t{\n\t\t// Give it a new index anyway to keep the SSA scheme sound.\n\n\t\tExpression const* base = &_assignment.leftHandSide();\n\t\tif (auto const* indexAccess = dynamic_cast<IndexAccess const*>(base))\n\t\t\tbase = leftmostBase(*indexAccess);\n\n\t\tif (auto varDecl = identifierToVariable(*base))\n\t\t\tm_context.newValue(*varDecl);\n\t}\n\telse\n\t{\n\t\tif (dynamic_cast<TupleType const*>(_assignment.rightHandSide().annotation().type))\n\t\t\ttupleAssignment(_assignment.leftHandSide(), _assignment.rightHandSide());\n\t\telse\n\t\t{\n\t\t\tauto const& type = _assignment.annotation().type;\n\t\t\tauto rightHandSide = op == Token::Assign ?\n\t\t\t\texpr(_assignment.rightHandSide(), type) :\n\t\t\t\tcompoundAssignment(_assignment);\n\t\t\tdefineExpr(_assignment, rightHandSide);\n\t\t\tassignment(\n\t\t\t\t_assignment.leftHandSide(),\n\t\t\t\texpr(_assignment, type),\n\t\t\t\ttype\n\t\t\t);\n\t\t}\n\t}\n}\n\nvoid SMTEncoder::endVisit(TupleExpression const& _tuple)\n{\n\tif (_tuple.annotation().type->category() == Type::Category::Function)\n\t\treturn;\n\n\tif (_tuple.annotation().type->category() == Type::Category::TypeType)\n\t\treturn;\n\n\tcreateExpr(_tuple);\n\n\tif (_tuple.isInlineArray())\n\t{\n\t\t// Add constraints for the length and values as it is known.\n\t\tauto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(_tuple));\n\t\tsmtAssert(symbArray, \"Inline array must be represented with SymbolicArrayVariable\");\n\t\tauto originalType = symbArray->originalType();\n\t\tauto arrayType = dynamic_cast<ArrayType const*>(originalType);\n\t\tsmtAssert(arrayType, \"Type of inline array must be ArrayType\");\n\t\taddArrayLiteralAssertions(*symbArray, applyMap(_tuple.components(), [&](auto const& c) { return expr(*c, arrayType->baseType()); }));\n\t}\n\telse\n\t{\n\t\tauto values = applyMap(_tuple.components(), [this](auto const& component) -> std::optional<smtutil::Expression> {\n\t\t\tif (component)\n\t\t\t{\n\t\t\t\tif (!m_context.knownExpression(*component))\n\t\t\t\t\t\tcreateExpr(*component);\n\t\t\t\treturn expr(*component);\n\t\t\t}\n\t\t\treturn {};\n\t\t});\n\t\tdefineExpr(_tuple, values);\n\t}\n}\n\nvoid SMTEncoder::endVisit(UnaryOperation const& _op)\n{\n\t/// We need to shortcut here due to potentially unknown\n\t/// rational number sizes.\n\tif (_op.annotation().type->category() == Type::Category::RationalNumber)\n\t\treturn;\n\n\tif (TokenTraits::isBitOp(_op.getOperator()) && !*_op.annotation().userDefinedFunction)\n\t\treturn bitwiseNotOperation(_op);\n\n\tcreateExpr(_op);\n\n\t// User-defined operators are essentially function calls.\n\tif (*_op.annotation().userDefinedFunction)\n\t\treturn;\n\n\tauto const& subExpr = innermostTuple(_op.subExpression());\n\tauto type = _op.annotation().type;\n\tswitch (_op.getOperator())\n\t{\n\tcase Token::Not: // !\n\t{\n\t\tsolAssert(smt::isBool(*type), \"\");\n\t\tdefineExpr(_op, !expr(subExpr));\n\t\tbreak;\n\t}\n\tcase Token::Inc: // ++ (pre- or postfix)\n\tcase Token::Dec: // -- (pre- or postfix)\n\t{\n\t\tsolAssert(smt::isInteger(*type) || smt::isFixedPoint(*type), \"\");\n\t\tsolAssert(subExpr.annotation().willBeWrittenTo, \"\");\n\t\tauto innerValue = expr(subExpr);\n\t\tauto newValue = arithmeticOperation(\n\t\t\t_op.getOperator() == Token::Inc ? Token::Add : Token::Sub,\n\t\t\tinnerValue,\n\t\t\tsmtutil::Expression(size_t(1)),\n\t\t\t_op.annotation().type,\n\t\t\t_op\n\t\t).first;\n\t\tdefineExpr(_op, _op.isPrefixOperation() ? newValue : innerValue);\n\t\tassignment(subExpr, newValue);\n\t\tbreak;\n\t}\n\tcase Token::Sub: // -\n\t{\n\t\tdefineExpr(_op, 0 - expr(subExpr));\n\t\tbreak;\n\t}\n\tcase Token::Delete:\n\t{\n\t\tif (auto decl = identifierToVariable(subExpr))\n\t\t{\n\t\t\tm_context.newValue(*decl);\n\t\t\tm_context.setZeroValue(*decl);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(m_context.knownExpression(subExpr), \"\");\n\t\t\tauto const& symbVar = m_context.expression(subExpr);\n\t\t\tsymbVar->increaseIndex();\n\t\t\tm_context.setZeroValue(*symbVar);\n\t\t\tif (\n\t\t\t\tdynamic_cast<IndexAccess const*>(&subExpr) ||\n\t\t\t\tdynamic_cast<MemberAccess const*>(&subExpr)\n\t\t\t)\n\t\t\t\tindexOrMemberAssignment(subExpr, symbVar->currentValue());\n\t\t\t// Empty push added a zero value anyway, so no need to delete extra.\n\t\t\telse if (!isEmptyPush(subExpr))\n\t\t\t\tsolAssert(false, \"\");\n\t\t}\n\t\tbreak;\n\t}\n\tdefault:\n\t\tsolAssert(false, \"\");\n\t}\n}\n\nbool SMTEncoder::visit(UnaryOperation const& _op)\n{\n\treturn !shortcutRationalNumber(_op);\n}\n\nbool SMTEncoder::visit(BinaryOperation const& _op)\n{\n\tif (shortcutRationalNumber(_op))\n\t\treturn false;\n\tif (TokenTraits::isBooleanOp(_op.getOperator()) && !*_op.annotation().userDefinedFunction)\n\t{\n\t\tbooleanOperation(_op);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nvoid SMTEncoder::endVisit(BinaryOperation const& _op)\n{\n\t/// If _op is const evaluated the RationalNumber shortcut was taken.\n\tif (isConstant(_op))\n\t\treturn;\n\tif (TokenTraits::isBooleanOp(_op.getOperator()) && !*_op.annotation().userDefinedFunction)\n\t\treturn;\n\n\tcreateExpr(_op);\n\n\t// User-defined operators are essentially function calls.\n\tif (*_op.annotation().userDefinedFunction)\n\t\treturn;\n\n\tif (TokenTraits::isArithmeticOp(_op.getOperator()))\n\t\tarithmeticOperation(_op);\n\telse if (TokenTraits::isCompareOp(_op.getOperator()))\n\t\tcompareOperation(_op);\n\telse if (TokenTraits::isBitOp(_op.getOperator()) || TokenTraits::isShiftOp(_op.getOperator()))\n\t\tbitwiseOperation(_op);\n\telse\n\t\tsolAssert(false, \"\");\n}\n\nbool SMTEncoder::visit(Conditional const& _op)\n{\n\t_op.condition().accept(*this);\n\n\tauto indicesEndTrue = visitBranch(&_op.trueExpression(), expr(_op.condition())).first;\n\n\tauto indicesEndFalse = visitBranch(&_op.falseExpression(), !expr(_op.condition())).first;\n\n\tmergeVariables(expr(_op.condition()), indicesEndTrue, indicesEndFalse);\n\n\tdefineExpr(_op, smtutil::Expression::ite(\n\t\texpr(_op.condition()),\n\t\texpr(_op.trueExpression(), _op.annotation().type),\n\t\texpr(_op.falseExpression(), _op.annotation().type)\n\t));\n\n\treturn false;\n}\n\nbool SMTEncoder::visit(FunctionCall const& _funCall)\n{\n\tauto functionCallKind = *_funCall.annotation().kind;\n\tif (functionCallKind != FunctionCallKind::FunctionCall)\n\t\treturn true;\n\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);\n\t// We do not want to visit the TypeTypes in the second argument of `abi.decode`.\n\t// Those types are checked/used in SymbolicState::buildABIFunctions.\n\tif (funType.kind() == FunctionType::Kind::ABIDecode)\n\t{\n\t\tif (auto arg = _funCall.arguments().front())\n\t\t\targ->accept(*this);\n\t\treturn false;\n\t}\n\n\t// We do not really need to visit the expression in a wrap/unwrap no-op call,\n\t// so we just ignore the function call expression to avoid \"unsupported\" warnings.\n\telse if (\n\t\tfunType.kind() == FunctionType::Kind::Wrap ||\n\t\tfunType.kind() == FunctionType::Kind::Unwrap\n\t)\n\t{\n\t\tif (auto arg = _funCall.arguments().front())\n\t\t\targ->accept(*this);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nvoid SMTEncoder::endVisit(FunctionCall const& _funCall)\n{\n\tauto functionCallKind = *_funCall.annotation().kind;\n\n\tcreateExpr(_funCall);\n\tif (functionCallKind == FunctionCallKind::StructConstructorCall)\n\t{\n\t\tvisitStructConstructorCall(_funCall);\n\t\treturn;\n\t}\n\n\tif (functionCallKind == FunctionCallKind::TypeConversion)\n\t{\n\t\tvisitTypeConversion(_funCall);\n\t\treturn;\n\t}\n\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);\n\n\tstd::vector<ASTPointer<Expression const>> const args = _funCall.arguments();\n\tswitch (funType.kind())\n\t{\n\tcase FunctionType::Kind::Assert:\n\t\tvisitAssert(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Require:\n\t\tvisitRequire(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Revert:\n\t\t// Revert is a special case of require and equals to `require(false)`\n\t\taddPathImpliedExpression(smtutil::Expression(false));\n\t\tbreak;\n\tcase FunctionType::Kind::GasLeft:\n\t\tvisitGasLeft(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::External:\n\t\tif (publicGetter(_funCall.expression()))\n\t\t\tvisitPublicGetter(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::BytesConcat:\n\t\tvisitBytesConcat(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::ABIDecode:\n\tcase FunctionType::Kind::ABIEncode:\n\tcase FunctionType::Kind::ABIEncodePacked:\n\tcase FunctionType::Kind::ABIEncodeWithSelector:\n\tcase FunctionType::Kind::ABIEncodeCall:\n\tcase FunctionType::Kind::ABIEncodeWithSignature:\n\t\tvisitABIFunction(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Internal:\n\tcase FunctionType::Kind::BareStaticCall:\n\tcase FunctionType::Kind::BareCall:\n\t\tbreak;\n\tcase FunctionType::Kind::KECCAK256:\n\tcase FunctionType::Kind::ECRecover:\n\tcase FunctionType::Kind::SHA256:\n\tcase FunctionType::Kind::RIPEMD160:\n\t\tvisitCryptoFunction(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::BlockHash:\n\t\tdefineExpr(_funCall, state().blockhash(expr(*_funCall.arguments().at(0))));\n\t\tbreak;\n\tcase FunctionType::Kind::BlobHash:\n\t\tvisitBlobHash(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::AddMod:\n\tcase FunctionType::Kind::MulMod:\n\t\tvisitAddMulMod(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Unwrap:\n\tcase FunctionType::Kind::Wrap:\n\t\tvisitWrapUnwrap(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Send:\n\tcase FunctionType::Kind::Transfer:\n\t{\n\t\tauto const& memberAccess = dynamic_cast<MemberAccess const&>(_funCall.expression());\n\t\tauto const& address = memberAccess.expression();\n\t\tauto const& value = args.front();\n\t\tsolAssert(value, \"\");\n\n\t\tsmtutil::Expression thisBalance = state().balance();\n\t\tsetSymbolicUnknownValue(thisBalance, TypeProvider::uint256(), m_context);\n\n\t\tstate().transfer(state().thisAddress(), expr(address), expr(*value));\n\t\tbreak;\n\t}\n\tcase FunctionType::Kind::ArrayPush:\n\t\tarrayPush(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::ArrayPop:\n\t\tarrayPop(_funCall);\n\t\tbreak;\n\tcase FunctionType::Kind::Event:\n\tcase FunctionType::Kind::Error:\n\t\t// This can be safely ignored.\n\t\tbreak;\n\tcase FunctionType::Kind::ObjectCreation:\n\t\tvisitObjectCreation(_funCall);\n\t\treturn;\n\tcase FunctionType::Kind::Creation:\n\t\tif (!m_settings.engine.chc || !m_settings.externalCalls.isTrusted())\n\t\t\tm_unsupportedErrors.warning(\n\t\t\t\t8729_error,\n\t\t\t\t_funCall.location(),\n\t\t\t\t\"Contract deployment is only supported in the trusted mode for external calls\"\n\t\t\t\t\" with the CHC engine.\"\n\t\t\t);\n\t\tbreak;\n\tcase FunctionType::Kind::DelegateCall:\n\tcase FunctionType::Kind::BareCallCode:\n\tcase FunctionType::Kind::BareDelegateCall:\n\tdefault:\n\t\tm_unsupportedErrors.warning(\n\t\t\t4588_error,\n\t\t\t_funCall.location(),\n\t\t\t\"Assertion checker does not yet implement this type of function call.\"\n\t\t);\n\t}\n}\n\nbool SMTEncoder::visit(ModifierInvocation const& _node)\n{\n\tif (auto const* args = _node.arguments())\n\t\tfor (auto const& arg: *args)\n\t\t\tif (arg)\n\t\t\t\targ->accept(*this);\n\treturn false;\n}\n\nvoid SMTEncoder::initContract(ContractDefinition const& _contract)\n{\n\tsolAssert(m_currentContract == nullptr, \"\");\n\tm_currentContract = &_contract;\n\n\tm_context.reset();\n\tm_context.pushSolver();\n\tcreateStateVariables(_contract);\n\tclearIndices(m_currentContract, nullptr);\n\tm_checked = true;\n}\n\nvoid SMTEncoder::initFunction(FunctionDefinition const& _function)\n{\n\tsolAssert(m_callStack.empty(), \"\");\n\tsolAssert(m_currentContract, \"\");\n\tm_context.pushSolver();\n\tm_pathConditions.clear();\n\tpushCallStack({&_function, nullptr});\n\tm_uninterpretedTerms.clear();\n\tcreateStateVariables(*m_currentContract);\n\tcreateLocalVariables(_function);\n\tm_arrayAssignmentHappened = false;\n\tclearIndices(m_currentContract, &_function);\n\tm_checked = true;\n}\n\nvoid SMTEncoder::visitAssert(FunctionCall const& _funCall)\n{\n\tauto const& args = _funCall.arguments();\n\tsolAssert(args.size() == 1, \"\");\n\tsolAssert(args.front()->annotation().type->category() == Type::Category::Bool, \"\");\n}\n\nvoid SMTEncoder::visitRequire(FunctionCall const& _funCall)\n{\n\tauto const& args = _funCall.arguments();\n\tsolAssert(args.size() >= 1, \"\");\n\tsolAssert(args.front()->annotation().type->category() == Type::Category::Bool, \"\");\n\taddPathImpliedExpression(expr(*args.front()));\n}\n\nvoid SMTEncoder::visitBytesConcat(FunctionCall const& _funCall)\n{\n\tauto const& args = _funCall.sortedArguments();\n\n\t// bytes.concat call with no arguments returns an empty array\n\tif (args.size() == 0)\n\t{\n\t\tdefineExpr(_funCall, smt::zeroValue(TypeProvider::bytesMemory()));\n\t\treturn;\n\t}\n\n\t// bytes.concat with single argument of type bytes memory\n\tif (args.size() == 1 && args.front()->annotation().type->category() == frontend::Type::Category::Array)\n\t{\n\t\tdefineExpr(_funCall, expr(*args.front(), TypeProvider::bytesMemory()));\n\t\treturn;\n\t}\n\n\tauto const& [name, inTypes, outType] = state().bytesConcatFunctionTypes(&_funCall);\n\tsolAssert(inTypes.size() == args.size(), \"\");\n\n\tauto symbFunction = state().bytesConcatFunction(&_funCall);\n\tauto out = createSelectExpressionForFunction(symbFunction, args, inTypes, args.size());\n\n\tdefineExpr(_funCall, out);\n}\n\nvoid SMTEncoder::visitABIFunction(FunctionCall const& _funCall)\n{\n\tauto symbFunction = state().abiFunction(&_funCall);\n\tauto const& [name, inTypes, outTypes] = state().abiFunctionTypes(&_funCall);\n\n\tauto const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);\n\tauto kind = funType.kind();\n\tauto const& args = _funCall.sortedArguments();\n\tauto argsActualLength = kind == FunctionType::Kind::ABIDecode ? 1 : args.size();\n\n\tsolAssert(inTypes.size() == argsActualLength, \"\");\n\tif (argsActualLength == 0)\n\t{\n\t\tdefineExpr(_funCall, smt::zeroValue(TypeProvider::bytesMemory()));\n\t\treturn;\n\t}\n\n\tauto out = createSelectExpressionForFunction(symbFunction, args, inTypes, argsActualLength);\n\tif (outTypes.size() == 1)\n\t\tdefineExpr(_funCall, out);\n\telse\n\t{\n\t\tauto symbTuple = std::dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(_funCall));\n\t\tsolAssert(symbTuple, \"\");\n\t\tsolAssert(symbTuple->components().size() == outTypes.size(), \"\");\n\t\tsolAssert(out.sort->kind == smtutil::Kind::Tuple, \"\");\n\n\t\tsymbTuple->increaseIndex();\n\t\tfor (unsigned i = 0; i < symbTuple->components().size(); ++i)\n\t\t\tm_context.addAssertion(symbTuple->component(i) == smtutil::Expression::tuple_get(out, i));\n\t}\n}\n\nvoid SMTEncoder::visitCryptoFunction(FunctionCall const& _funCall)\n{\n\tauto const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);\n\tauto kind = funType.kind();\n\tauto arg0 = expr(*_funCall.arguments().at(0), TypeProvider::bytesStorage());\n\tstd::optional<smtutil::Expression> result;\n\tif (kind == FunctionType::Kind::KECCAK256)\n\t\tresult = smtutil::Expression::select(state().cryptoFunction(\"keccak256\"), arg0);\n\telse if (kind == FunctionType::Kind::SHA256)\n\t\tresult = smtutil::Expression::select(state().cryptoFunction(\"sha256\"), arg0);\n\telse if (kind == FunctionType::Kind::RIPEMD160)\n\t\tresult = smtutil::Expression::select(state().cryptoFunction(\"ripemd160\"), arg0);\n\telse if (kind == FunctionType::Kind::ECRecover)\n\t{\n\t\tauto e = state().cryptoFunction(\"ecrecover\");\n\t\tauto arg0 = expr(*_funCall.arguments().at(0), TypeProvider::fixedBytes(32));\n\t\tauto arg1 = expr(*_funCall.arguments().at(1), TypeProvider::uint(8));\n\t\tauto arg2 = expr(*_funCall.arguments().at(2), TypeProvider::fixedBytes(32));\n\t\tauto arg3 = expr(*_funCall.arguments().at(3), TypeProvider::fixedBytes(32));\n\t\tauto inputSort = dynamic_cast<smtutil::ArraySort&>(*e.sort).domain;\n\t\tauto ecrecoverInput = smtutil::Expression::tuple_constructor(\n\t\t\tsmtutil::Expression(std::make_shared<smtutil::SortSort>(inputSort), \"\"),\n\t\t\t{arg0, arg1, arg2, arg3}\n\t\t);\n\t\tresult = smtutil::Expression::select(e, ecrecoverInput);\n\t}\n\telse\n\t\tsolAssert(false, \"\");\n\n\tdefineExpr(_funCall, *result);\n}\n\nvoid SMTEncoder::visitGasLeft(FunctionCall const& _funCall)\n{\n\tstd::string gasLeft = \"gasleft\";\n\t// We increase the variable index since gasleft changes\n\t// inside a tx.\n\tdefineGlobalVariable(gasLeft, _funCall, true);\n\tauto const& symbolicVar = m_context.globalSymbol(gasLeft);\n\tunsigned index = symbolicVar->index();\n\t// We set the current value to unknown anyway to add type constraints.\n\tm_context.setUnknownValue(*symbolicVar);\n\tif (index > 0)\n\t\tm_context.addAssertion(symbolicVar->currentValue() <= symbolicVar->valueAtIndex(index - 1));\n}\n\nvoid SMTEncoder::visitBlobHash(FunctionCall const& _funCall)\n{\n\tconstexpr unsigned BLOB_TRANSACTION_LIMIT = 9; // Since pectra\n\tauto indexExpr = expr(*_funCall.arguments().at(0));\n\tauto valueExpr = smtutil::Expression::ite(\n\t\tindexExpr >= BLOB_TRANSACTION_LIMIT,\n\t\tsmtutil::Expression(u256(0)),\n\t\tstate().blobhash(indexExpr)\n\t);\n\tdefineExpr(_funCall, std::move(valueExpr));\n}\n\nvoid SMTEncoder::visitAddMulMod(FunctionCall const& _funCall)\n{\n\tauto const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);\n\tauto kind = funType.kind();\n\tsolAssert(kind == FunctionType::Kind::AddMod || kind == FunctionType::Kind::MulMod, \"\");\n\tauto const& args = _funCall.arguments();\n\tsolAssert(args.at(0) && args.at(1) && args.at(2), \"\");\n\tauto x = expr(*args.at(0));\n\tauto y = expr(*args.at(1));\n\tauto k = expr(*args.at(2));\n\tauto const& intType = dynamic_cast<IntegerType const&>(*_funCall.annotation().type);\n\n\tif (kind == FunctionType::Kind::AddMod)\n\t\tdefineExpr(_funCall, divModWithSlacks(x + y, k, intType).second);\n\telse\n\t\tdefineExpr(_funCall, divModWithSlacks(x * y, k, intType).second);\n}\n\nvoid SMTEncoder::visitWrapUnwrap(FunctionCall const& _funCall)\n{\n\tauto const& args = _funCall.arguments();\n\tsmtAssert(args.size() == 1, \"Expected exactly one argument to wrap/unwrap\");\n\tauto const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);\n\tauto const* argType = funType.parameterTypes().front();\n\tdefineExpr(_funCall, expr(*args.front(), argType));\n}\n\nvoid SMTEncoder::visitObjectCreation(FunctionCall const& _funCall)\n{\n\tauto const& args = _funCall.arguments();\n\tsolAssert(args.size() >= 1, \"\");\n\tauto argType = args.front()->annotation().type->category();\n\tsolAssert(argType == Type::Category::Integer || argType == Type::Category::RationalNumber, \"\");\n\n\tsmtutil::Expression arraySize = expr(*args.front());\n\tsetSymbolicUnknownValue(arraySize, TypeProvider::uint256(), m_context);\n\tauto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(_funCall));\n\tsolAssert(symbArray, \"\");\n\tsmt::setSymbolicZeroValue(*symbArray, m_context);\n\tauto zeroElements = symbArray->elements();\n\tsymbArray->increaseIndex();\n\tm_context.addAssertion(symbArray->length() == arraySize);\n\tm_context.addAssertion(symbArray->elements() == zeroElements);\n}\n\nvoid SMTEncoder::endVisit(Identifier const& _identifier)\n{\n\tif (auto decl = identifierToVariable(_identifier))\n\t{\n\t\tif (decl->isConstant())\n\t\t\tdefineExpr(_identifier, constantExpr(_identifier, *decl));\n\t\telse\n\t\t\tdefineExpr(_identifier, currentValue(*decl));\n\t}\n\telse if (_identifier.annotation().type->category() == Type::Category::Function)\n\t\tvisitFunctionIdentifier(_identifier);\n\telse if (_identifier.name() == \"now\")\n\t\tdefineGlobalVariable(_identifier.name(), _identifier);\n\telse if (_identifier.name() == \"this\")\n\t{\n\t\tdefineExpr(_identifier, state().thisAddress());\n\t\tm_uninterpretedTerms.insert(&_identifier);\n\t}\n\t// Ignore type identifiers\n\telse if (dynamic_cast<TypeType const*>(_identifier.annotation().type))\n\t\treturn;\n\t// Ignore module identifiers\n\telse if (dynamic_cast<ModuleType const*>(_identifier.annotation().type))\n\t\treturn;\n\t// Ignore user defined value type identifiers\n\telse if (dynamic_cast<UserDefinedValueType const*>(_identifier.annotation().type))\n\t\treturn;\n\t// Ignore the builtin abi, it is handled in FunctionCall.\n\t// TODO: ignore MagicType in general (abi, block, msg, tx, type)\n\telse if (auto magicType = dynamic_cast<MagicType const*>(_identifier.annotation().type); magicType && magicType->kind() == MagicType::Kind::ABI)\n\t{\n\t\tsolAssert(_identifier.name() == \"abi\", \"\");\n\t\treturn;\n\t}\n\telse\n\t\tcreateExpr(_identifier);\n}\n\nvoid SMTEncoder::endVisit(ElementaryTypeNameExpression const& _typeName)\n{\n\tauto const& typeType = dynamic_cast<TypeType const&>(*_typeName.annotation().type);\n\tauto result = smt::newSymbolicVariable(\n\t\t*TypeProvider::uint256(),\n\t\ttypeType.actualType()->toString(false),\n\t\tm_context\n\t);\n\tsolAssert(!result.first && result.second, \"\");\n\tm_context.createExpression(_typeName, result.second);\n}\n\nnamespace // helpers for SMTEncoder::visitPublicGetter\n{\n\nbool isReturnedFromStructGetter(Type const* _type)\n{\n\t// So far it seems that only Mappings and ordinary Arrays are not returned.\n\tauto category = _type->category();\n\tif (category == Type::Category::Mapping)\n\t\treturn false;\n\tif (category == Type::Category::Array)\n\t\treturn dynamic_cast<ArrayType const&>(*_type).isByteArrayOrString();\n\t// default\n\treturn true;\n}\n\nstd::vector<std::string> structGetterReturnedMembers(StructType const& _structType)\n{\n\tstd::vector<std::string> returnedMembers;\n\tfor (auto const& member: _structType.nativeMembers(nullptr))\n\t\tif (isReturnedFromStructGetter(member.type))\n\t\t\treturnedMembers.push_back(member.name);\n\treturn returnedMembers;\n}\n\n}\n\nvoid SMTEncoder::visitPublicGetter(FunctionCall const& _funCall)\n{\n\tauto var = publicGetter(_funCall.expression());\n\tsolAssert(var && var->isStateVariable(), \"\");\n\tsolAssert(m_context.knownExpression(_funCall), \"\");\n\tauto paramExpectedTypes = replaceUserTypes(FunctionType(*var).parameterTypes());\n\tauto actualArguments = _funCall.arguments();\n\tsolAssert(actualArguments.size() == paramExpectedTypes.size(), \"\");\n\tstd::deque<smtutil::Expression> symbArguments;\n\tfor (unsigned i = 0; i < paramExpectedTypes.size(); ++i)\n\t\tsymbArguments.push_back(expr(*actualArguments[i], paramExpectedTypes[i]));\n\n\t// See FunctionType::FunctionType(VariableDeclaration const& _varDecl)\n\t// to understand the return types of public getters.\n\tType const* type = var->type();\n\tsmtutil::Expression currentExpr = currentValue(*var);\n\twhile (true)\n\t{\n\t\tif (\n\t\t\ttype->isValueType() ||\n\t\t\t(type->category() == Type::Category::Array && dynamic_cast<ArrayType const&>(*type).isByteArrayOrString())\n\t\t)\n\t\t{\n\t\t\tsolAssert(symbArguments.empty(), \"\");\n\t\t\tdefineExpr(_funCall, currentExpr);\n\t\t\treturn;\n\t\t}\n\t\tswitch (type->category())\n\t\t{\n\t\t\tcase Type::Category::Array:\n\t\t\tcase Type::Category::Mapping:\n\t\t\t{\n\t\t\t\tsolAssert(!symbArguments.empty(), \"\");\n\t\t\t\t// For nested arrays/mappings, each argument in the call is an index to the next layer.\n\t\t\t\t// We mirror this with `select` after unpacking the SMT-LIB array expression.\n\t\t\t\tcurrentExpr = smtutil::Expression::select(smtutil::Expression::tuple_get(currentExpr, 0), symbArguments.front());\n\t\t\t\tsymbArguments.pop_front();\n\t\t\t\tif (auto arrayType = dynamic_cast<ArrayType const*>(type))\n\t\t\t\t\ttype = arrayType->baseType();\n\t\t\t\telse if (auto mappingType = dynamic_cast<MappingType const*>(type))\n\t\t\t\t\ttype = mappingType->valueType();\n\t\t\t\telse\n\t\t\t\t\tsolAssert(false, \"\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase Type::Category::Struct:\n\t\t\t{\n\t\t\t\tsolAssert(symbArguments.empty(), \"\");\n\t\t\t\tsmt::SymbolicStructVariable structVar(dynamic_cast<StructType const*>(type), \"struct_temp_\" + std::to_string(_funCall.id()), m_context);\n\t\t\t\tm_context.addAssertion(structVar.currentValue() == currentExpr);\n\t\t\t\tauto returnedMembers = structGetterReturnedMembers(dynamic_cast<StructType const&>(*structVar.type()));\n\t\t\t\tsolAssert(!returnedMembers.empty(), \"\");\n\t\t\t\tauto returnedValues = applyMap(returnedMembers, [&](std::string const& memberName) -> std::optional<smtutil::Expression> { return structVar.member(memberName); });\n\t\t\t\tdefineExpr(_funCall, returnedValues);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t{\n\t\t\t\t// Unsupported cases, do nothing and the getter will be abstracted.\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n}\n\nbool SMTEncoder::shouldEncode(ContractDefinition const& _contract) const\n{\n\treturn _contract.canBeDeployed();\n}\n\nbool SMTEncoder::shouldAnalyzeVerificationTargetsFor(SourceUnit const& _source) const\n{\n\treturn m_settings.contracts.isDefault() ||\n\t\tm_settings.contracts.has(*_source.annotation().path);\n}\n\nbool SMTEncoder::shouldAnalyzeVerificationTargetsFor(ContractDefinition const& _contract) const\n{\n\tif (!shouldEncode(_contract))\n\t\treturn false;\n\n\treturn m_settings.contracts.isDefault() ||\n\t\tm_settings.contracts.has(_contract.sourceUnitName(), _contract.name());\n}\n\nvoid SMTEncoder::visitTypeConversion(FunctionCall const& _funCall)\n{\n\tsolAssert(*_funCall.annotation().kind == FunctionCallKind::TypeConversion, \"\");\n\tsolAssert(_funCall.arguments().size() == 1, \"\");\n\n\tauto argument = _funCall.arguments().front();\n\tauto const argType = argument->annotation().type;\n\tauto const funCallType = _funCall.annotation().type;\n\n\tauto symbArg = expr(*argument, funCallType);\n\n\tif (smt::isStringLiteral(*argType) && smt::isFixedBytes(*funCallType))\n\t{\n\t\tdefineExpr(_funCall, symbArg);\n\t\treturn;\n\t}\n\n\tArrayType const* arrayType = dynamic_cast<ArrayType const*>(argType);\n\tif (auto sliceType = dynamic_cast<ArraySliceType const*>(argType))\n\t\tarrayType = &sliceType->arrayType();\n\n\tif (arrayType && arrayType->isByteArrayOrString() && smt::isFixedBytes(*funCallType))\n\t{\n\t\tauto array = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(*argument));\n\t\tbytesToFixedBytesAssertions(*array, _funCall);\n\t\treturn;\n\t}\n\n\t// TODO Simplify this whole thing for 0.8.0 where weird casts are disallowed.\n\n\tunsigned argSize = argType->storageBytes();\n\tunsigned castSize = funCallType->storageBytes();\n\tbool castIsSigned = smt::isNumber(*funCallType) && smt::isSigned(funCallType);\n\tbool argIsSigned = smt::isNumber(*argType) && smt::isSigned(argType);\n\tstd::optional<smtutil::Expression> symbMin;\n\tstd::optional<smtutil::Expression> symbMax;\n\tif (smt::isNumber(*funCallType))\n\t{\n\t\tsymbMin = smt::minValue(funCallType);\n\t\tsymbMax = smt::maxValue(funCallType);\n\t}\n\tif (argSize == castSize)\n\t{\n\t\t// If sizes are the same, it's possible that the signs are different.\n\t\tif (smt::isNumber(*funCallType) && smt::isNumber(*argType))\n\t\t{\n\t\t\t// castIsSigned && !argIsSigned => might overflow if arg > castType.max\n\t\t\t// !castIsSigned && argIsSigned => might underflow if arg < castType.min\n\t\t\t// !castIsSigned && !argIsSigned => ok\n\t\t\t// castIsSigned && argIsSigned => ok\n\n\t\t\tif (castIsSigned && !argIsSigned)\n\t\t\t{\n\t\t\t\tauto wrap = smtutil::Expression::ite(\n\t\t\t\t\tsymbArg > *symbMax,\n\t\t\t\t\tsymbArg - (*symbMax - *symbMin + 1),\n\t\t\t\t\tsymbArg\n\t\t\t\t);\n\t\t\t\tdefineExpr(_funCall, wrap);\n\t\t\t}\n\t\t\telse if (!castIsSigned && argIsSigned)\n\t\t\t{\n\t\t\t\tauto wrap = smtutil::Expression::ite(\n\t\t\t\t\tsymbArg < *symbMin,\n\t\t\t\t\tsymbArg + (*symbMax + 1),\n\t\t\t\t\tsymbArg\n\t\t\t\t);\n\t\t\t\tdefineExpr(_funCall, wrap);\n\t\t\t}\n\t\t\telse\n\t\t\t\tdefineExpr(_funCall, symbArg);\n\t\t}\n\t\telse\n\t\t\tdefineExpr(_funCall, symbArg);\n\t}\n\telse if (castSize > argSize)\n\t{\n\t\tsolAssert(smt::isNumber(*funCallType), \"\");\n\t\t// RationalNumbers have size 32.\n\t\tsolAssert(argType->category() != Type::Category::RationalNumber, \"\");\n\n\t\t// castIsSigned && !argIsSigned => ok\n\t\t// castIsSigned && argIsSigned => ok\n\t\t// !castIsSigned && !argIsSigned => ok except for FixedBytesType, need to adjust padding\n\t\t// !castIsSigned && argIsSigned => might underflow if arg < castType.min\n\n\t\tif (!castIsSigned && argIsSigned)\n\t\t{\n\t\t\tauto wrap = smtutil::Expression::ite(\n\t\t\t\tsymbArg < *symbMin,\n\t\t\t\tsymbArg + (*symbMax + 1),\n\t\t\t\tsymbArg\n\t\t\t);\n\t\t\tdefineExpr(_funCall, wrap);\n\t\t}\n\t\telse if (!castIsSigned && !argIsSigned)\n\t\t{\n\t\t\tif (auto const* fixedCast = dynamic_cast<FixedBytesType const*>(funCallType))\n\t\t\t{\n\t\t\t\tauto const* fixedArg = dynamic_cast<FixedBytesType const*>(argType);\n\t\t\t\tsolAssert(fixedArg, \"\");\n\t\t\t\tauto diff = fixedCast->numBytes() - fixedArg->numBytes();\n\t\t\t\tsolAssert(diff > 0, \"\");\n\t\t\t\tauto bvSize = fixedCast->numBytes() * 8;\n\t\t\t\tdefineExpr(\n\t\t\t\t\t_funCall,\n\t\t\t\t\tsmtutil::Expression::bv2int(smtutil::Expression::int2bv(symbArg, bvSize) << smtutil::Expression::int2bv(diff * 8, bvSize))\n\t\t\t\t);\n\t\t\t}\n\t\t\telse\n\t\t\t\tdefineExpr(_funCall, symbArg);\n\t\t}\n\t\telse\n\t\t\tdefineExpr(_funCall, symbArg);\n\t}\n\telse // castSize < argSize\n\t{\n\t\tsolAssert(smt::isNumber(*funCallType), \"\");\n\n\t\tRationalNumberType const* rationalType = isConstant(*argument);\n\t\tif (rationalType)\n\t\t{\n\t\t\t// The TypeChecker guarantees that a constant fits in the cast size.\n\t\t\tdefineExpr(_funCall, symbArg);\n\t\t\treturn;\n\t\t}\n\n\t\tauto const* fixedCast = dynamic_cast<FixedBytesType const*>(funCallType);\n\t\tauto const* fixedArg = dynamic_cast<FixedBytesType const*>(argType);\n\t\tif (fixedCast && fixedArg)\n\t\t{\n\t\t\tcreateExpr(_funCall);\n\t\t\tauto diff = argSize - castSize;\n\t\t\tsolAssert(fixedArg->numBytes() - fixedCast->numBytes() == diff, \"\");\n\n\t\t\tauto argValueBV = smtutil::Expression::int2bv(symbArg, argSize * 8);\n\t\t\tauto shr = smtutil::Expression::int2bv(diff * 8, argSize * 8);\n\t\t\tsolAssert(!castIsSigned, \"\");\n\t\t\tdefineExpr(_funCall, smtutil::Expression::bv2int(argValueBV >> shr));\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto argValueBV = smtutil::Expression::int2bv(symbArg, castSize * 8);\n\t\t\tdefineExpr(_funCall, smtutil::Expression::bv2int(argValueBV, castIsSigned));\n\t\t}\n\t}\n}\n\nvoid SMTEncoder::visitFunctionIdentifier(Identifier const& _identifier)\n{\n\tauto const& fType = dynamic_cast<FunctionType const&>(*_identifier.annotation().type);\n\tif (replaceUserTypes(fType.returnParameterTypes()).size() == 1)\n\t{\n\t\tdefineGlobalVariable(fType.identifier(), _identifier);\n\t\tm_context.createExpression(_identifier, m_context.globalSymbol(fType.identifier()));\n\t}\n}\n\nvoid SMTEncoder::visitStructConstructorCall(FunctionCall const& _funCall)\n{\n\tsolAssert(*_funCall.annotation().kind == FunctionCallKind::StructConstructorCall, \"\");\n\tif (smt::isNonRecursiveStruct(*_funCall.annotation().type))\n\t{\n\t\tauto& structSymbolicVar = dynamic_cast<smt::SymbolicStructVariable&>(*m_context.expression(_funCall));\n\t\tauto structType = dynamic_cast<StructType const*>(structSymbolicVar.type());\n\t\tsolAssert(structType, \"\");\n\t\tauto const& structMembers = structType->structDefinition().members();\n\t\tsolAssert(structMembers.size() == _funCall.sortedArguments().size(), \"\");\n\t\tauto args = _funCall.sortedArguments();\n\t\tstructSymbolicVar.assignAllMembers(applyMap(\n\t\t\tranges::views::zip(args, structMembers),\n\t\t\t[this] (auto const& argMemberPair) { return expr(*argMemberPair.first, argMemberPair.second->type()); }\n\t\t));\n\t}\n\n}\n\nvoid SMTEncoder::endVisit(Literal const& _literal)\n{\n\tsolAssert(_literal.annotation().type, \"Expected type for AST node\");\n\tType const& type = *_literal.annotation().type;\n\tif (smt::isNumber(type))\n\t\tdefineExpr(_literal, smtutil::Expression(type.literalValue(&_literal)));\n\telse if (smt::isBool(type))\n\t\tdefineExpr(_literal, smtutil::Expression(_literal.token() == Token::TrueLiteral ? true : false));\n\telse if (smt::isStringLiteral(type))\n\t{\n\t\tcreateExpr(_literal);\n\n\t\t// Add constraints for the length and values as it is known.\n\t\tauto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(_literal));\n\t\tsolAssert(symbArray, \"\");\n\n\t\taddArrayLiteralAssertions(\n\t\t\t*symbArray,\n\t\t\tapplyMap(_literal.value(), [](unsigned char c) { return smtutil::Expression{size_t(c)}; })\n\t\t);\n\t}\n\telse\n\t\tsolAssert(false, \"\");\n}\n\nvoid SMTEncoder::addArrayLiteralAssertions(\n\tsmt::SymbolicArrayVariable& _symArray,\n\tstd::vector<smtutil::Expression> const& _elementValues\n)\n{\n\tm_context.addAssertion(_symArray.length() == _elementValues.size());\n\n\t// Assert to the solver that _elementValues are exactly the elements at the beginning of the array.\n\t// Since we create new symbolic representation for every array literal in the source file, we want to ensure that\n\t// representations of two equal literals are also equal. For this reason we always start from constant-zero array.\n\t// This ensures SMT-LIB arrays (which are infinite) are also equal beyond the length of the Solidity array literal.\n\tauto type = _symArray.type();\n\tsmtAssert(type);\n\tauto valueType = [&]() {\n\t\tif (auto const* arrayType = dynamic_cast<ArrayType const*>(type))\n\t\t\treturn arrayType->baseType();\n\t\tif (smt::isStringLiteral(*type))\n\t\t\treturn TypeProvider::stringMemory()->baseType();\n\t\tsmtAssert(false);\n\t}();\n\tauto tupleSort = std::dynamic_pointer_cast<smtutil::TupleSort>(smt::smtSort(*type));\n\tauto sortSort = std::make_shared<smtutil::SortSort>(tupleSort->components.front());\n\tsmtutil::Expression arrayExpr = smtutil::Expression::const_array(smtutil::Expression(sortSort), smt::zeroValue(valueType));\n\tsmtAssert(arrayExpr.sort->kind == smtutil::Kind::Array);\n\tfor (size_t i = 0; i < _elementValues.size(); i++)\n\t\tarrayExpr = smtutil::Expression::store(arrayExpr, smtutil::Expression(i), _elementValues[i]);\n\tm_context.addAssertion(_symArray.elements() == arrayExpr);\n}\n\nvoid SMTEncoder::bytesToFixedBytesAssertions(\n\tsmt::SymbolicArrayVariable& _symArray,\n\tExpression const& _fixedBytes\n)\n{\n\tauto const& fixed = dynamic_cast<FixedBytesType const&>(*_fixedBytes.annotation().type);\n\tauto intType = TypeProvider::uint256();\n\tstd::string suffix = std::to_string(_fixedBytes.id()) + \"_\" + std::to_string(m_context.newUniqueId());\n\tsmt::SymbolicIntVariable k(intType, intType, \"k_\" + suffix, m_context);\n\tm_context.addAssertion(k.currentValue() == 0);\n\tsize_t n = fixed.numBytes();\n\tfor (size_t i = 0; i < n; i++)\n\t{\n\t\tauto kPrev = k.currentValue();\n\t\tm_context.addAssertion((smtutil::Expression::select(_symArray.elements(), i) * (u256(1) << ((n - i - 1) * 8))) + kPrev == k.increaseIndex());\n\t}\n\tm_context.addAssertion(expr(_fixedBytes) == k.currentValue());\n}\n\nvoid SMTEncoder::endVisit(Return const& _return)\n{\n\tif (_return.expression() && m_context.knownExpression(*_return.expression()))\n\t{\n\t\tauto returnParams = m_callStack.back().first->returnParameters();\n\t\tif (returnParams.size() > 1)\n\t\t{\n\t\t\tauto const& symbTuple = std::dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(*_return.expression()));\n\t\t\tsolAssert(symbTuple, \"\");\n\t\t\tsolAssert(symbTuple->components().size() == returnParams.size(), \"\");\n\n\t\t\tauto const* tupleType = dynamic_cast<TupleType const*>(_return.expression()->annotation().type);\n\t\t\tsolAssert(tupleType, \"\");\n\t\t\tauto const& types = tupleType->components();\n\t\t\tsolAssert(types.size() == returnParams.size(), \"\");\n\n\t\t\tfor (unsigned i = 0; i < returnParams.size(); ++i)\n\t\t\t\tassignment(*returnParams.at(i), symbTuple->component(i, types.at(i), returnParams.at(i)->type()));\n\t\t}\n\t\telse if (returnParams.size() == 1)\n\t\t\tassignment(*returnParams.front(), expr(*_return.expression(), returnParams.front()->type()));\n\t}\n}\n\nbool SMTEncoder::visit(MemberAccess const& _memberAccess)\n{\n\tcreateExpr(_memberAccess);\n\n\tauto const& accessType = _memberAccess.annotation().type;\n\tif (accessType->category() == Type::Category::Function)\n\t{\n\t\tauto const* functionType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type);\n\t\tif (functionType && functionType->hasDeclaration())\n\t\t\tdefineExpr(\n\t\t\t\t_memberAccess,\n\t\t\t\tutil::selectorFromSignatureU32(functionType->richIdentifier())\n\t\t\t);\n\n\t\treturn true;\n\t}\n\n\tExpression const& memberExpr = innermostTuple(_memberAccess.expression());\n\n\tauto const& exprType = memberExpr.annotation().type;\n\tsolAssert(exprType, \"\");\n\n\tif (exprType->category() == Type::Category::Magic)\n\t{\n\t\tif (auto const* identifier = dynamic_cast<Identifier const*>(&memberExpr))\n\t\t{\n\t\t\tauto const& name = identifier->name();\n\t\t\tsolAssert(name == \"block\" || name == \"msg\" || name == \"tx\", \"\");\n\t\t\tauto memberName = _memberAccess.memberName();\n\n\t\t\t// TODO remove this for 0.9.0\n\t\t\tif (name == \"block\" && memberName == \"difficulty\")\n\t\t\t\tmemberName = \"prevrandao\";\n\n\t\t\tdefineExpr(_memberAccess, state().txMember(name + \".\" + memberName));\n\t\t}\n\t\telse if (auto magicType = dynamic_cast<MagicType const*>(exprType))\n\t\t{\n\t\t\tif (magicType->kind() == MagicType::Kind::Block)\n\t\t\t\tdefineExpr(_memberAccess, state().txMember(\"block.\" + _memberAccess.memberName()));\n\t\t\telse if (magicType->kind() == MagicType::Kind::Message)\n\t\t\t\tdefineExpr(_memberAccess, state().txMember(\"msg.\" + _memberAccess.memberName()));\n\t\t\telse if (magicType->kind() == MagicType::Kind::Transaction)\n\t\t\t\tdefineExpr(_memberAccess, state().txMember(\"tx.\" + _memberAccess.memberName()));\n\t\t\telse if (magicType->kind() == MagicType::Kind::MetaType)\n\t\t\t{\n\t\t\t\tauto const& memberName = _memberAccess.memberName();\n\t\t\t\tif (memberName == \"min\" || memberName == \"max\")\n\t\t\t\t{\n\t\t\t\t\tif (IntegerType const* integerType = dynamic_cast<IntegerType const*>(magicType->typeArgument()))\n\t\t\t\t\t\tdefineExpr(_memberAccess, memberName == \"min\" ? integerType->minValue() : integerType->maxValue());\n\t\t\t\t\telse if (EnumType const* enumType = dynamic_cast<EnumType const*>(magicType->typeArgument()))\n\t\t\t\t\t\tdefineExpr(_memberAccess, memberName == \"min\" ? enumType->minValue() : enumType->maxValue());\n\t\t\t\t}\n\t\t\t\telse if (memberName == \"interfaceId\")\n\t\t\t\t{\n\t\t\t\t\tContractDefinition const& contract = dynamic_cast<ContractType const&>(*magicType->typeArgument()).contractDefinition();\n\t\t\t\t\tdefineExpr(_memberAccess, contract.interfaceId());\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\t// NOTE: supporting name, creationCode, runtimeCode would be easy enough, but the bytes/string they return are not\n\t\t\t\t\t//       at all usable in the SMT checker currently\n\t\t\t\t\tm_unsupportedErrors.warning(\n\t\t\t\t\t\t7507_error,\n\t\t\t\t\t\t_memberAccess.location(),\n\t\t\t\t\t\t\"Assertion checker does not yet support this expression.\"\n\t\t\t\t\t);\n\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"\");\n\n\t\treturn false;\n\t}\n\telse if (smt::isNonRecursiveStruct(*exprType))\n\t{\n\t\tmemberExpr.accept(*this);\n\t\tauto const& symbStruct = std::dynamic_pointer_cast<smt::SymbolicStructVariable>(m_context.expression(memberExpr));\n\t\tdefineExpr(_memberAccess, symbStruct->member(_memberAccess.memberName()));\n\t\treturn false;\n\t}\n\telse if (exprType->category() == Type::Category::TypeType)\n\t{\n\t\tauto const* decl = expressionToDeclaration(memberExpr);\n\t\tif (dynamic_cast<EnumDefinition const*>(decl))\n\t\t{\n\t\t\tauto enumType = dynamic_cast<EnumType const*>(accessType);\n\t\t\tsolAssert(enumType, \"\");\n\t\t\tdefineExpr(_memberAccess, enumType->memberValue(_memberAccess.memberName()));\n\n\t\t\treturn false;\n\t\t}\n\t\telse if (dynamic_cast<ContractDefinition const*>(decl))\n\t\t{\n\t\t\tif (auto const* var = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t\t{\n\t\t\t\tif (var->isConstant())\n\t\t\t\t\tdefineExpr(_memberAccess, constantExpr(_memberAccess, *var));\n\t\t\t\telse\n\t\t\t\t\tdefineExpr(_memberAccess, currentValue(*var));\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\telse if (exprType->category() == Type::Category::Address)\n\t{\n\t\tmemberExpr.accept(*this);\n\t\tif (_memberAccess.memberName() == \"balance\")\n\t\t{\n\t\t\tdefineExpr(_memberAccess, state().balance(expr(memberExpr)));\n\t\t\tsetSymbolicUnknownValue(*m_context.expression(_memberAccess), m_context);\n\t\t\tm_uninterpretedTerms.insert(&_memberAccess);\n\t\t\treturn false;\n\t\t}\n\t}\n\telse if (exprType->category() == Type::Category::Array)\n\t{\n\t\tmemberExpr.accept(*this);\n\t\tif (_memberAccess.memberName() == \"length\")\n\t\t{\n\t\t\tauto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(memberExpr));\n\t\t\tsolAssert(symbArray, \"\");\n\t\t\tdefineExpr(_memberAccess, symbArray->length());\n\t\t\tm_uninterpretedTerms.insert(&_memberAccess);\n\t\t\tsetSymbolicUnknownValue(\n\t\t\t\texpr(_memberAccess),\n\t\t\t\t_memberAccess.annotation().type,\n\t\t\t\tm_context\n\t\t\t);\n\t\t}\n\t\treturn false;\n\t}\n\telse if (\n\t\tauto const* functionType = dynamic_cast<FunctionType const*>(exprType);\n\t\tfunctionType &&\n\t\t_memberAccess.memberName() == \"selector\" &&\n\t\tfunctionType->hasDeclaration()\n\t)\n\t{\n\t\tdefineExpr(_memberAccess, functionType->externalIdentifier());\n\t\treturn false;\n\t}\n\telse if (exprType->category() == Type::Category::Module)\n\t{\n\t\tif (auto const* var = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))\n\t\t{\n\t\t\tsolAssert(var->isConstant(), \"\");\n\t\t\tdefineExpr(_memberAccess, constantExpr(_memberAccess, *var));\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tm_unsupportedErrors.warning(\n\t\t7650_error,\n\t\t_memberAccess.location(),\n\t\t\"Assertion checker does not yet support this expression.\"\n\t);\n\n\treturn true;\n}\n\nvoid SMTEncoder::endVisit(IndexAccess const& _indexAccess)\n{\n\tcreateExpr(_indexAccess);\n\n\tif (_indexAccess.annotation().type->category() == Type::Category::TypeType)\n\t\treturn;\n\n\tmakeOutOfBoundsVerificationTarget(_indexAccess);\n\n\tif (auto const* type = dynamic_cast<FixedBytesType const*>(_indexAccess.baseExpression().annotation().type))\n\t{\n\t\tsmtutil::Expression base = expr(_indexAccess.baseExpression());\n\n\t\tif (type->numBytes() == 1)\n\t\t\tdefineExpr(_indexAccess, base);\n\t\telse\n\t\t{\n\t\t\tauto [bvSize, isSigned] = smt::typeBvSizeAndSignedness(_indexAccess.baseExpression().annotation().type);\n\t\t\tsolAssert(!isSigned, \"\");\n\t\t\tsolAssert(bvSize >= 16, \"\");\n\t\t\tsolAssert(bvSize % 8 == 0, \"\");\n\n\t\t\tsmtutil::Expression idx = expr(*_indexAccess.indexExpression());\n\n\t\t\tauto bvBase = smtutil::Expression::int2bv(base, bvSize);\n\t\t\tauto bvShl = smtutil::Expression::int2bv(idx * 8, bvSize);\n\t\t\tauto bvShr = smtutil::Expression::int2bv(bvSize - 8, bvSize);\n\t\t\tauto result = (bvBase << bvShl) >> bvShr;\n\n\t\t\tauto anyValue = expr(_indexAccess);\n\t\t\tm_context.expression(_indexAccess)->increaseIndex();\n\t\t\tunsigned numBytes = bvSize / 8;\n\t\t\tauto withBound = smtutil::Expression::ite(\n\t\t\t\tidx < numBytes,\n\t\t\t\tsmtutil::Expression::bv2int(result, false),\n\t\t\t\tanyValue\n\t\t\t);\n\t\t\tdefineExpr(_indexAccess, withBound);\n\t\t}\n\t\treturn;\n\t}\n\n\tstd::shared_ptr<smt::SymbolicVariable> array;\n\tif (auto const* id = dynamic_cast<Identifier const*>(&_indexAccess.baseExpression()))\n\t{\n\t\tauto varDecl = identifierToVariable(*id);\n\t\tsolAssert(varDecl, \"\");\n\t\tarray = m_context.variable(*varDecl);\n\n\t\tif (varDecl && varDecl->isConstant())\n\t\t\tm_context.addAssertion(currentValue(*varDecl) == expr(*id));\n\t}\n\telse\n\t{\n\t\tsolAssert(m_context.knownExpression(_indexAccess.baseExpression()), \"\");\n\t\tarray = m_context.expression(_indexAccess.baseExpression());\n\t}\n\n\tauto arrayVar = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(array);\n\tsolAssert(arrayVar, \"\");\n\n\tType const* baseType = _indexAccess.baseExpression().annotation().type;\n\tdefineExpr(_indexAccess, smtutil::Expression::select(\n\t\tarrayVar->elements(),\n\t\texpr(*_indexAccess.indexExpression(), keyType(baseType))\n\t));\n\tsetSymbolicUnknownValue(\n\t\texpr(_indexAccess),\n\t\t_indexAccess.annotation().type,\n\t\tm_context\n\t);\n\tm_uninterpretedTerms.insert(&_indexAccess);\n}\n\nvoid SMTEncoder::endVisit(IndexRangeAccess const& _indexRangeAccess)\n{\n\tcreateExpr(_indexRangeAccess);\n\t/// The actual slice is created by CHC which also assigns the length.\n}\n\nvoid SMTEncoder::arrayAssignment()\n{\n\tm_arrayAssignmentHappened = true;\n}\n\nvoid SMTEncoder::indexOrMemberAssignment(Expression const& _expr, smtutil::Expression const& _rightHandSide)\n{\n\tauto toStore = _rightHandSide;\n\tauto const* lastExpr = &_expr;\n\twhile (true)\n\t{\n\t\tif (auto const* indexAccess = dynamic_cast<IndexAccess const*>(lastExpr))\n\t\t{\n\t\t\tauto const& base = indexAccess->baseExpression();\n\t\t\tif (dynamic_cast<Identifier const*>(&base))\n\t\t\t\tbase.accept(*this);\n\n\t\t\tType const* baseType = base.annotation().type;\n\t\t\tauto indexExpr = expr(*indexAccess->indexExpression(), keyType(baseType));\n\t\t\tauto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(base));\n\t\t\tsolAssert(symbArray, \"\");\n\t\t\ttoStore = smtutil::Expression::tuple_constructor(\n\t\t\t\tsmtutil::Expression(std::make_shared<smtutil::SortSort>(smt::smtSort(*baseType)), baseType->toString(true)),\n\t\t\t\t{smtutil::Expression::store(symbArray->elements(), indexExpr, toStore), symbArray->length()}\n\t\t\t);\n\t\t\tdefineExpr(*indexAccess, smtutil::Expression::select(\n\t\t\t\tsymbArray->elements(),\n\t\t\t\tindexExpr\n\t\t\t));\n\t\t\tlastExpr = &indexAccess->baseExpression();\n\t\t}\n\t\telse if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(lastExpr))\n\t\t{\n\t\t\tauto const& base = memberAccess->expression();\n\t\t\tif (dynamic_cast<Identifier const*>(&base))\n\t\t\t\tbase.accept(*this);\n\n\t\t\tif (\n\t\t\t\tauto const* structType = dynamic_cast<StructType const*>(base.annotation().type);\n\t\t\t\tstructType && structType->recursive()\n\t\t\t)\n\t\t\t{\n\t\t\t\tm_unsupportedErrors.warning(\n\t\t\t\t\t4375_error,\n\t\t\t\t\tmemberAccess->location(),\n\t\t\t\t\t\"Assertion checker does not support recursive structs.\"\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (auto varDecl = identifierToVariable(*memberAccess))\n\t\t\t{\n\t\t\t\tif (varDecl->hasReferenceOrMappingType())\n\t\t\t\t\tresetReferences(*varDecl);\n\n\t\t\t\tassignment(*varDecl, toStore);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tauto symbStruct = std::dynamic_pointer_cast<smt::SymbolicStructVariable>(m_context.expression(base));\n\t\t\tsolAssert(symbStruct, \"\");\n\t\t\tsymbStruct->assignMember(memberAccess->memberName(), toStore);\n\t\t\ttoStore = symbStruct->currentValue();\n\t\t\tdefineExpr(*memberAccess, symbStruct->member(memberAccess->memberName()));\n\t\t\tlastExpr = &memberAccess->expression();\n\t\t}\n\t\telse if (auto const& id = dynamic_cast<Identifier const*>(lastExpr))\n\t\t{\n\t\t\tauto varDecl = identifierToVariable(*id);\n\t\t\tsolAssert(varDecl, \"\");\n\n\t\t\tif (varDecl->hasReferenceOrMappingType())\n\t\t\t\tresetReferences(*varDecl);\n\n\t\t\tassignment(*varDecl, toStore);\n\t\t\tdefineExpr(*id, currentValue(*varDecl));\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto type = lastExpr->annotation().type;\n\t\t\tif (\n\t\t\t\tdynamic_cast<ReferenceType const*>(type) ||\n\t\t\t\tdynamic_cast<MappingType const*>(type)\n\t\t\t)\n\t\t\t\tresetReferences(type);\n\n\t\t\tassignment(*m_context.expression(*lastExpr), toStore);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nvoid SMTEncoder::arrayPush(FunctionCall const& _funCall)\n{\n\tauto memberAccess = dynamic_cast<MemberAccess const*>(&_funCall.expression());\n\tsolAssert(memberAccess, \"\");\n\tauto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));\n\tsolAssert(symbArray, \"\");\n\tauto oldLength = symbArray->length();\n\tm_context.addAssertion(oldLength >= 0);\n\t// Real world assumption: the array length is assumed to not overflow.\n\t// This assertion guarantees that both the current and updated lengths have the above property.\n\tm_context.addAssertion(oldLength + 1 < (smt::maxValue(*TypeProvider::uint256()) - 1));\n\n\tauto const& arguments = _funCall.arguments();\n\tauto arrayType = dynamic_cast<ArrayType const*>(symbArray->type());\n\tsolAssert(arrayType, \"\");\n\tauto elementType = arrayType->baseType();\n\tsmtutil::Expression element = arguments.empty() ?\n\t\tsmt::zeroValue(elementType) :\n\t\texpr(*arguments.front(), elementType);\n\tsmtutil::Expression store = smtutil::Expression::store(\n\t\tsymbArray->elements(),\n\t\toldLength,\n\t\telement\n\t);\n\tsymbArray->increaseIndex();\n\tm_context.addAssertion(symbArray->elements() == store);\n\tm_context.addAssertion(symbArray->length() == oldLength + 1);\n\n\tif (arguments.empty())\n\t\tdefineExpr(_funCall, element);\n\n\tassignment(memberAccess->expression(), symbArray->currentValue());\n}\n\nvoid SMTEncoder::arrayPop(FunctionCall const& _funCall)\n{\n\tauto memberAccess = dynamic_cast<MemberAccess const*>(cleanExpression(_funCall.expression()));\n\tsolAssert(memberAccess, \"\");\n\tauto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));\n\tsolAssert(symbArray, \"\");\n\n\tmakeArrayPopVerificationTarget(_funCall);\n\n\tauto oldElements = symbArray->elements();\n\tauto oldLength = symbArray->length();\n\n\tsymbArray->increaseIndex();\n\tm_context.addAssertion(symbArray->elements() == oldElements);\n\tauto newLength = smtutil::Expression::ite(\n\t\toldLength > 0,\n\t\toldLength - 1,\n\t\t0\n\t);\n\tm_context.addAssertion(symbArray->length() == newLength);\n\n\tassignment(memberAccess->expression(), symbArray->currentValue());\n}\n\nvoid SMTEncoder::defineGlobalVariable(std::string const& _name, Expression const& _expr, bool _increaseIndex)\n{\n\tif (!m_context.knownGlobalSymbol(_name))\n\t{\n\t\tbool abstract = m_context.createGlobalSymbol(_name, _expr);\n\t\tif (abstract)\n\t\t\tm_unsupportedErrors.warning(\n\t\t\t\t1695_error,\n\t\t\t\t_expr.location(),\n\t\t\t\t\"Assertion checker does not yet support this global variable.\"\n\t\t\t);\n\t}\n\telse if (_increaseIndex)\n\t\tm_context.globalSymbol(_name)->increaseIndex();\n\t// The default behavior is not to increase the index since\n\t// most of the global values stay the same throughout a tx.\n\tif (isSupportedType(*_expr.annotation().type))\n\t\tdefineExpr(_expr, m_context.globalSymbol(_name)->currentValue());\n}\n\nbool SMTEncoder::shortcutRationalNumber(Expression const& _expr)\n{\n\tRationalNumberType const* rationalType = isConstant(_expr);\n\tif (!rationalType)\n\t\treturn false;\n\n\tif (rationalType->isNegative())\n\t\tdefineExpr(_expr, smtutil::Expression(u2s(rationalType->literalValue(nullptr))));\n\telse\n\t\tdefineExpr(_expr, smtutil::Expression(rationalType->literalValue(nullptr)));\n\treturn true;\n}\n\nvoid SMTEncoder::arithmeticOperation(BinaryOperation const& _op)\n{\n\tauto type = _op.annotation().commonType;\n\tsolAssert(type, \"\");\n\tsolAssert(type->category() == Type::Category::Integer || type->category() == Type::Category::FixedPoint, \"\");\n\tswitch (_op.getOperator())\n\t{\n\tcase Token::Add:\n\tcase Token::Sub:\n\tcase Token::Mul:\n\tcase Token::Div:\n\tcase Token::Mod:\n\t{\n\t\tauto values = arithmeticOperation(\n\t\t\t_op.getOperator(),\n\t\t\texpr(_op.leftExpression()),\n\t\t\texpr(_op.rightExpression()),\n\t\t\t_op.annotation().commonType,\n\t\t\t_op\n\t\t);\n\t\tdefineExpr(_op, values.first);\n\t\tbreak;\n\t}\n\tdefault:\n\t\tm_unsupportedErrors.warning(\n\t\t\t5188_error,\n\t\t\t_op.location(),\n\t\t\t\"Assertion checker does not yet implement this operator.\"\n\t\t);\n\t}\n}\n\nstd::pair<smtutil::Expression, smtutil::Expression> SMTEncoder::arithmeticOperation(\n\tToken _op,\n\tsmtutil::Expression const& _left,\n\tsmtutil::Expression const& _right,\n\tType const* _commonType,\n\tExpression const& _operation\n)\n{\n\tstatic std::set<Token> validOperators{\n\t\tToken::Add,\n\t\tToken::Sub,\n\t\tToken::Mul,\n\t\tToken::Div,\n\t\tToken::Mod\n\t};\n\tsolAssert(validOperators.count(_op), \"\");\n\tsolAssert(_commonType, \"\");\n\tsolAssert(\n\t\t_commonType->category() == Type::Category::Integer || _commonType->category() == Type::Category::FixedPoint,\n\t\t\"\"\n\t);\n\n\tIntegerType const* intType = nullptr;\n\tif (auto type = dynamic_cast<IntegerType const*>(_commonType))\n\t\tintType = type;\n\telse\n\t\tintType = TypeProvider::uint256();\n\n\tauto valueUnbounded = [&]() -> smtutil::Expression {\n\t\tswitch (_op)\n\t\t{\n\t\tcase Token::Add: return _left + _right;\n\t\tcase Token::Sub: return _left - _right;\n\t\tcase Token::Mul: return _left * _right;\n\t\tcase Token::Div: return divModWithSlacks(_left, _right, *intType).first;\n\t\tcase Token::Mod: return divModWithSlacks(_left, _right, *intType).second;\n\t\tdefault: solAssert(false, \"\");\n\t\t}\n\t}();\n\n\tif (m_checked)\n\t\treturn {valueUnbounded, valueUnbounded};\n\n\tif (_op == Token::Div || _op == Token::Mod)\n\t{\n\t\t// mod and unsigned division never underflow/overflow\n\t\tif (_op == Token::Mod || !intType->isSigned())\n\t\t\treturn {valueUnbounded, valueUnbounded};\n\n\t\t// The only case where division overflows is\n\t\t// - type is signed\n\t\t// - LHS is type.min\n\t\t// - RHS is -1\n\t\t// the result is then -(type.min), which wraps back to type.min\n\t\tsmtutil::Expression maxLeft = _left == smt::minValue(*intType);\n\t\tsmtutil::Expression minusOneRight = _right == std::numeric_limits<size_t >::max();\n\t\tsmtutil::Expression wrap = smtutil::Expression::ite(maxLeft && minusOneRight, smt::minValue(*intType), valueUnbounded);\n\t\treturn {wrap, valueUnbounded};\n\t}\n\n\tauto symbMin = smt::minValue(*intType);\n\tauto symbMax = smt::maxValue(*intType);\n\n\tsmtutil::Expression intValueRange = (0 - symbMin) + symbMax + 1;\n\tstd::string suffix = std::to_string(_operation.id()) + \"_\" + std::to_string(m_context.newUniqueId());\n\tsmt::SymbolicIntVariable k(intType, intType, \"k_\" + suffix, m_context);\n\tsmt::SymbolicIntVariable m(intType, intType, \"m_\" + suffix, m_context);\n\n\t// To wrap around valueUnbounded in case of overflow or underflow, we replace it with a k, given:\n\t// 1. k + m * intValueRange = valueUnbounded\n\t// 2. k is in range of the desired integer type\n\tauto wrap = k.currentValue();\n\tm_context.addAssertion(valueUnbounded == (k.currentValue() + intValueRange * m.currentValue()));\n\tm_context.addAssertion(k.currentValue() >= symbMin);\n\tm_context.addAssertion(k.currentValue() <= symbMax);\n\n\t// TODO this could be refined:\n\t// for unsigned types it's enough to check only the upper bound.\n\tauto value = smtutil::Expression::ite(\n\t\tvalueUnbounded > symbMax,\n\t\twrap,\n\t\tsmtutil::Expression::ite(\n\t\t\tvalueUnbounded < symbMin,\n\t\t\twrap,\n\t\t\tvalueUnbounded\n\t\t)\n\t);\n\n\treturn {value, valueUnbounded};\n}\n\nsmtutil::Expression SMTEncoder::bitwiseOperation(\n\tToken _op,\n\tsmtutil::Expression const& _left,\n\tsmtutil::Expression const& _right,\n\tType const* _commonType\n)\n{\n\tstatic std::set<Token> validOperators{\n\t\tToken::BitAnd,\n\t\tToken::BitOr,\n\t\tToken::BitXor,\n\t\tToken::SHL,\n\t\tToken::SHR,\n\t\tToken::SAR\n\t};\n\tsolAssert(validOperators.count(_op), \"\");\n\tsolAssert(_commonType, \"\");\n\n\tauto [bvSize, isSigned] = smt::typeBvSizeAndSignedness(_commonType);\n\n\tauto bvLeft = smtutil::Expression::int2bv(_left, bvSize);\n\tauto bvRight = smtutil::Expression::int2bv(_right, bvSize);\n\n\tstd::optional<smtutil::Expression> result;\n\tswitch (_op)\n\t{\n\t\tcase Token::BitAnd:\n\t\t\tresult = bvLeft & bvRight;\n\t\t\tbreak;\n\t\tcase Token::BitOr:\n\t\t\tresult = bvLeft | bvRight;\n\t\t\tbreak;\n\t\tcase Token::BitXor:\n\t\t\tresult = bvLeft ^ bvRight;\n\t\t\tbreak;\n\t\tcase Token::SHL:\n\t\t\tresult = bvLeft << bvRight;\n\t\t\tbreak;\n\t\tcase Token::SHR:\n\t\t\tresult = bvLeft >> bvRight;\n\t\t\tbreak;\n\t\tcase Token::SAR:\n\t\t\tresult = isSigned ?\n\t\t\t\tsmtutil::Expression::ashr(bvLeft, bvRight) :\n\t\t\t\tbvLeft >> bvRight;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tsolAssert(false, \"\");\n\t}\n\n\tsolAssert(result.has_value(), \"\");\n\treturn smtutil::Expression::bv2int(*result, isSigned);\n}\n\nvoid SMTEncoder::compareOperation(BinaryOperation const& _op)\n{\n\tauto commonType = _op.annotation().commonType;\n\tsolAssert(commonType, \"\");\n\n\tif (isSupportedType(*commonType))\n\t{\n\t\tsmtutil::Expression left(expr(_op.leftExpression(), commonType));\n\t\tsmtutil::Expression right(expr(_op.rightExpression(), commonType));\n\t\tToken op = _op.getOperator();\n\t\tstd::shared_ptr<smtutil::Expression> value;\n\t\tif (smt::isNumber(*commonType))\n\t\t{\n\t\t\tvalue = std::make_shared<smtutil::Expression>(\n\t\t\t\top == Token::Equal ? (left == right) :\n\t\t\t\top == Token::NotEqual ? (left != right) :\n\t\t\t\top == Token::LessThan ? (left < right) :\n\t\t\t\top == Token::LessThanOrEqual ? (left <= right) :\n\t\t\t\top == Token::GreaterThan ? (left > right) :\n\t\t\t\t/*op == Token::GreaterThanOrEqual*/ (left >= right)\n\t\t\t);\n\t\t}\n\t\telse // Bool\n\t\t{\n\t\t\tsolUnimplementedAssert(smt::isBool(*commonType), \"Operation not yet supported\");\n\t\t\tvalue = std::make_shared<smtutil::Expression>(\n\t\t\t\top == Token::Equal ? (left == right) :\n\t\t\t\t/*op == Token::NotEqual*/ (left != right)\n\t\t\t);\n\t\t}\n\t\t// TODO: check that other values for op are not possible.\n\t\tdefineExpr(_op, *value);\n\t}\n\telse\n\t\tm_unsupportedErrors.warning(\n\t\t\t7229_error,\n\t\t\t_op.location(),\n\t\t\t\"Assertion checker does not yet implement the type \" + _op.annotation().commonType->toString() + \" for comparisons\"\n\t\t);\n}\n\nvoid SMTEncoder::booleanOperation(BinaryOperation const& _op)\n{\n\tsolAssert(_op.getOperator() == Token::And || _op.getOperator() == Token::Or, \"\");\n\tsolAssert(_op.annotation().commonType, \"\");\n\tsolAssert(_op.annotation().commonType->category() == Type::Category::Bool, \"\");\n\t// @TODO check that both of them are not constant\n\t_op.leftExpression().accept(*this);\n\tif (_op.getOperator() == Token::And)\n\t{\n\t\tauto indicesAfterSecond = visitBranch(&_op.rightExpression(), expr(_op.leftExpression())).first;\n\t\tmergeVariables(!expr(_op.leftExpression()), copyVariableIndices(), indicesAfterSecond);\n\t\tdefineExpr(_op, expr(_op.leftExpression()) && expr(_op.rightExpression()));\n\t}\n\telse\n\t{\n\t\tauto indicesAfterSecond = visitBranch(&_op.rightExpression(), !expr(_op.leftExpression())).first;\n\t\tmergeVariables(expr(_op.leftExpression()), copyVariableIndices(), indicesAfterSecond);\n\t\tdefineExpr(_op, expr(_op.leftExpression()) || expr(_op.rightExpression()));\n\t}\n}\n\nvoid SMTEncoder::bitwiseOperation(BinaryOperation const& _op)\n{\n\tauto op = _op.getOperator();\n\tsolAssert(TokenTraits::isBitOp(op) || TokenTraits::isShiftOp(op), \"\");\n\tauto commonType = _op.annotation().commonType;\n\tsolAssert(commonType, \"\");\n\n\tdefineExpr(_op, bitwiseOperation(\n\t\t_op.getOperator(),\n\t\texpr(_op.leftExpression(), commonType),\n\t\texpr(_op.rightExpression(), commonType),\n\t\tcommonType\n\t));\n}\n\nvoid SMTEncoder::bitwiseNotOperation(UnaryOperation const& _op)\n{\n\tsolAssert(_op.getOperator() == Token::BitNot, \"\");\n\n\tauto [bvSize, isSigned] = smt::typeBvSizeAndSignedness(_op.annotation().type);\n\n\tauto bvOperand = smtutil::Expression::int2bv(expr(_op.subExpression(), _op.annotation().type), bvSize);\n\tdefineExpr(_op, smtutil::Expression::bv2int(~bvOperand, isSigned));\n}\n\nstd::pair<smtutil::Expression, smtutil::Expression> SMTEncoder::divModWithSlacks(\n\tsmtutil::Expression _left,\n\tsmtutil::Expression _right,\n\tIntegerType const& _type\n)\n{\n\tif (m_settings.divModNoSlacks)\n\t\treturn {_left / _right, _left % _right};\n\n\tIntegerType const* intType = &_type;\n\tstd::string suffix = \"div_mod_\" + std::to_string(m_context.newUniqueId());\n\tsmt::SymbolicIntVariable dSymb(intType, intType, \"d_\" + suffix, m_context);\n\tsmt::SymbolicIntVariable rSymb(intType, intType, \"r_\" + suffix, m_context);\n\tauto d = dSymb.currentValue();\n\tauto r = rSymb.currentValue();\n\n\t// x / y = d and x % y = r iff d * y + r = x and\n\t// either x >= 0 and 0 <= r < abs(y) (or just 0 <= r < y for unsigned)\n\t// or     x < 0 and -abs(y) < r <= 0\n\tm_context.addAssertion(((d * _right) + r) == _left);\n\tif (_type.isSigned())\n\t\tm_context.addAssertion(\n\t\t\t(_left >= 0 && 0 <= r && (_right == 0 || r < smtutil::abs(_right))) ||\n\t\t\t(_left < 0 && ((_right == 0 || 0 - smtutil::abs(_right) < r) && r <= 0))\n\t\t);\n\telse // unsigned version\n\t\tm_context.addAssertion(0 <= r && (_right == 0 || r < _right));\n\n\tauto divResult = smtutil::Expression::ite(_right == 0, 0, d);\n\tauto modResult = smtutil::Expression::ite(_right == 0, 0, r);\n\treturn {divResult, modResult};\n}\n\nvoid SMTEncoder::assignment(Expression const& _left, smtutil::Expression const& _right)\n{\n\tassignment(_left, _right, _left.annotation().type);\n}\n\nvoid SMTEncoder::assignment(\n\tExpression const& _left,\n\tsmtutil::Expression const& _right,\n\tType const* _type\n)\n{\n\tsolAssert(\n\t\t_left.annotation().type->category() != Type::Category::Tuple,\n\t\t\"Tuple assignments should be handled by tupleAssignment.\"\n\t);\n\n\tExpression const* left = cleanExpression(_left);\n\n\tif (!isSupportedType(*_type))\n\t{\n\t\t// Give it a new index anyway to keep the SSA scheme sound.\n\t\tif (auto varDecl = identifierToVariable(*left))\n\t\t\tm_context.newValue(*varDecl);\n\t}\n\telse if (auto varDecl = identifierToVariable(*left))\n\t{\n\t\tif (varDecl->hasReferenceOrMappingType())\n\t\t\tresetReferences(*varDecl);\n\t\tassignment(*varDecl, _right);\n\t}\n\telse if (\n\t\tdynamic_cast<IndexAccess const*>(left) ||\n\t\tdynamic_cast<MemberAccess const*>(left)\n\t)\n\t\tindexOrMemberAssignment(*left, _right);\n\telse if (auto const* funCall = dynamic_cast<FunctionCall const*>(left))\n\t{\n\t\tif (auto funType = dynamic_cast<FunctionType const*>(funCall->expression().annotation().type))\n\t\t{\n\t\t\tif (funType->kind() == FunctionType::Kind::ArrayPush)\n\t\t\t{\n\t\t\t\tauto memberAccess = dynamic_cast<MemberAccess const*>(&funCall->expression());\n\t\t\t\tsolAssert(memberAccess, \"\");\n\t\t\t\tauto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));\n\t\t\t\tsolAssert(symbArray, \"\");\n\n\t\t\t\tauto oldLength = symbArray->length();\n\t\t\t\tauto store = smtutil::Expression::store(\n\t\t\t\t\tsymbArray->elements(),\n\t\t\t\t\tsymbArray->length() - 1,\n\t\t\t\t\t_right\n\t\t\t\t);\n\t\t\t\tsymbArray->increaseIndex();\n\t\t\t\tm_context.addAssertion(symbArray->elements() == store);\n\t\t\t\tm_context.addAssertion(symbArray->length() == oldLength);\n\t\t\t\tassignment(memberAccess->expression(), symbArray->currentValue());\n\t\t\t}\n\t\t\telse if (funType->kind() == FunctionType::Kind::Internal)\n\t\t\t{\n\t\t\t\tfor (auto type: replaceUserTypes(funType->returnParameterTypes()))\n\t\t\t\t\tif (type->category() == Type::Category::Mapping || dynamic_cast<ReferenceType const*>(type))\n\t\t\t\t\t\tresetReferences(type);\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t\tsolAssert(false, \"\");\n}\n\nvoid SMTEncoder::tupleAssignment(Expression const& _left, Expression const& _right)\n{\n\tauto lTuple = dynamic_cast<TupleExpression const*>(&innermostTuple(_left));\n\tsolAssert(lTuple, \"\");\n\tExpression const& right = innermostTuple(_right);\n\n\tauto const& lComponents = lTuple->components();\n\n\t// If both sides are tuple expressions, we individually and potentially\n\t// recursively assign each pair of components.\n\t// This is because of potential type conversion.\n\tif (auto rTuple = dynamic_cast<TupleExpression const*>(&right))\n\t{\n\t\tauto const& rComponents = rTuple->components();\n\t\tsolAssert(lComponents.size() == rComponents.size(), \"\");\n\t\tfor (unsigned i = 0; i < lComponents.size(); ++i)\n\t\t{\n\t\t\tif (!lComponents.at(i) || !rComponents.at(i))\n\t\t\t\tcontinue;\n\t\t\tauto const& lExpr = *lComponents.at(i);\n\t\t\tauto const& rExpr = *rComponents.at(i);\n\t\t\tif (lExpr.annotation().type->category() == Type::Category::Tuple)\n\t\t\t\ttupleAssignment(lExpr, rExpr);\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto type = lExpr.annotation().type;\n\t\t\t\tassignment(lExpr, expr(rExpr, type), type);\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tauto rType = dynamic_cast<TupleType const*>(right.annotation().type);\n\t\tsolAssert(rType, \"\");\n\n\t\tauto const& rComponents = rType->components();\n\t\tsolAssert(lComponents.size() == rComponents.size(), \"\");\n\n\t\tauto symbRight = expr(right);\n\t\tsolAssert(symbRight.sort->kind == smtutil::Kind::Tuple, \"\");\n\n\t\tfor (unsigned i = 0; i < lComponents.size(); ++i)\n\t\t\tif (auto component = lComponents.at(i); component && rComponents.at(i))\n\t\t\t\tassignment(*component, smtutil::Expression::tuple_get(symbRight, i), component->annotation().type);\n\t}\n}\n\nsmtutil::Expression SMTEncoder::compoundAssignment(Assignment const& _assignment)\n{\n\tstatic std::map<Token, Token> const compoundToArithmetic{\n\t\t{Token::AssignAdd, Token::Add},\n\t\t{Token::AssignSub, Token::Sub},\n\t\t{Token::AssignMul, Token::Mul},\n\t\t{Token::AssignDiv, Token::Div},\n\t\t{Token::AssignMod, Token::Mod}\n\t};\n\tstatic std::map<Token, Token> const compoundToBitwise{\n\t\t{Token::AssignBitAnd, Token::BitAnd},\n\t\t{Token::AssignBitOr, Token::BitOr},\n\t\t{Token::AssignBitXor, Token::BitXor},\n\t\t{Token::AssignShl, Token::SHL},\n\t\t{Token::AssignShr, Token::SHR},\n\t\t{Token::AssignSar, Token::SAR}\n\t};\n\tToken op = _assignment.assignmentOperator();\n\tsolAssert(compoundToArithmetic.count(op) || compoundToBitwise.count(op), \"\");\n\n\tauto decl = identifierToVariable(_assignment.leftHandSide());\n\n\tif (compoundToBitwise.count(op))\n\t\treturn bitwiseOperation(\n\t\t\tcompoundToBitwise.at(op),\n\t\t\tdecl ? currentValue(*decl) : expr(_assignment.leftHandSide(), _assignment.annotation().type),\n\t\t\texpr(_assignment.rightHandSide(), _assignment.annotation().type),\n\t\t\t_assignment.annotation().type\n\t\t);\n\n\tauto values = arithmeticOperation(\n\t\tcompoundToArithmetic.at(op),\n\t\tdecl ? currentValue(*decl) : expr(_assignment.leftHandSide(), _assignment.annotation().type),\n\t\texpr(_assignment.rightHandSide(), _assignment.annotation().type),\n\t\t_assignment.annotation().type,\n\t\t_assignment\n\t);\n\treturn values.first;\n}\n\nvoid SMTEncoder::expressionToTupleAssignment(std::vector<std::shared_ptr<VariableDeclaration>> const& _variables, Expression const& _rhs)\n{\n\tauto symbolicVar = m_context.expression(_rhs);\n\tif (_variables.size() > 1)\n\t{\n\t\tauto symbTuple = std::dynamic_pointer_cast<smt::SymbolicTupleVariable>(symbolicVar);\n\t\tsolAssert(symbTuple, \"\");\n\t\tauto const& symbComponents = symbTuple->components();\n\t\tsolAssert(symbComponents.size() == _variables.size(), \"\");\n\t\tauto tupleType = dynamic_cast<TupleType const*>(_rhs.annotation().type);\n\t\tsolAssert(tupleType, \"\");\n\t\tauto const& typeComponents = tupleType->components();\n\t\tsolAssert(typeComponents.size() == symbComponents.size(), \"\");\n\t\tfor (unsigned i = 0; i < symbComponents.size(); ++i)\n\t\t{\n\t\t\tauto param = _variables.at(i);\n\t\t\tif (param)\n\t\t\t{\n\t\t\t\tsolAssert(m_context.knownVariable(*param), \"\");\n\t\t\t\tassignment(*param, symbTuple->component(i, typeComponents[i], param->type()));\n\t\t\t}\n\t\t}\n\t}\n\telse if (_variables.size() == 1)\n\t{\n\t\tauto const& var = *_variables.front();\n\t\tsolAssert(m_context.knownVariable(var), \"\");\n\t\tassignment(var, _rhs);\n\t}\n}\n\nvoid SMTEncoder::assignment(VariableDeclaration const& _variable, Expression const& _value)\n{\n\t// In general, at this point, the SMT sorts of _variable and _value are the same,\n\t// even if there is implicit conversion.\n\t// This is a special case where the SMT sorts are different.\n\t// For now we are unaware of other cases where this happens, but if they do appear\n\t// we should extract this into an `implicitConversion` function.\n\tassignment(_variable, expr(_value, _variable.type()));\n}\n\nvoid SMTEncoder::assignment(VariableDeclaration const& _variable, smtutil::Expression const& _value)\n{\n\tType const* type = _variable.type();\n\tif (type->category() == Type::Category::Mapping)\n\t\tarrayAssignment();\n\tassignment(*m_context.variable(_variable), _value);\n}\n\nvoid SMTEncoder::assignment(smt::SymbolicVariable& _symVar, smtutil::Expression const& _value)\n{\n\tm_context.addAssertion(_symVar.increaseIndex() == _value);\n}\n\nstd::pair<SMTEncoder::VariableIndices, smtutil::Expression> SMTEncoder::visitBranch(\n\tASTNode const* _statement,\n\tsmtutil::Expression _condition\n)\n{\n\treturn visitBranch(_statement, &_condition);\n}\n\nstd::pair<SMTEncoder::VariableIndices, smtutil::Expression> SMTEncoder::visitBranch(\n\tASTNode const* _statement,\n\tsmtutil::Expression const* _condition\n)\n{\n\tauto indicesBeforeBranch = copyVariableIndices();\n\tif (_condition)\n\t\tpushPathCondition(*_condition);\n\t_statement->accept(*this);\n\tauto pathConditionOnExit = currentPathConditions();\n\tif (_condition)\n\t\tpopPathCondition();\n\tauto indicesAfterBranch = copyVariableIndices();\n\tresetVariableIndices(indicesBeforeBranch);\n\treturn {indicesAfterBranch, pathConditionOnExit};\n}\n\nvoid SMTEncoder::initializeFunctionCallParameters(CallableDeclaration const& _function, std::vector<smtutil::Expression> const& _callArgs)\n{\n\tauto const& funParams = _function.parameters();\n\tsolAssert(funParams.size() == _callArgs.size(), \"\");\n\tfor (unsigned i = 0; i < funParams.size(); ++i)\n\t\tif (createVariable(*funParams[i]))\n\t\t{\n\t\t\tm_context.addAssertion(_callArgs[i] == m_context.newValue(*funParams[i]));\n\t\t\tif (funParams[i]->annotation().type->category() == Type::Category::Mapping)\n\t\t\t\tm_arrayAssignmentHappened = true;\n\t\t}\n\n\tstd::vector<VariableDeclaration const*> localVars;\n\tif (auto const* fun = dynamic_cast<FunctionDefinition const*>(&_function))\n\t\tlocalVars = localVariablesIncludingModifiers(*fun, m_currentContract);\n\telse\n\t\tlocalVars = _function.localVariables();\n\tfor (auto const& variable: localVars)\n\t\tif (createVariable(*variable))\n\t\t{\n\t\t\tm_context.newValue(*variable);\n\t\t\tm_context.setZeroValue(*variable);\n\t\t}\n\n\tif (_function.returnParameterList())\n\t\tfor (auto const& retParam: _function.returnParameters())\n\t\t\tif (createVariable(*retParam))\n\t\t\t{\n\t\t\t\tm_context.newValue(*retParam);\n\t\t\t\tm_context.setZeroValue(*retParam);\n\t\t\t}\n}\n\nvoid SMTEncoder::createStateVariables(ContractDefinition const& _contract)\n{\n\tfor (auto var: stateVariablesIncludingInheritedAndPrivate(_contract))\n\t\tcreateVariable(*var);\n}\n\nvoid SMTEncoder::initializeStateVariables(ContractDefinition const& _contract)\n{\n\tfor (auto var: _contract.stateVariables())\n\t{\n\t\tsolAssert(m_context.knownVariable(*var), \"\");\n\t\tm_context.setZeroValue(*var);\n\t}\n\n\tfor (auto var: _contract.stateVariables())\n\t\tif (var->value())\n\t\t{\n\t\t\tvar->value()->accept(*this);\n\t\t\tassignment(*var, *var->value());\n\t\t}\n}\n\nvoid SMTEncoder::createLocalVariables(FunctionDefinition const& _function)\n{\n\tfor (auto const& variable: localVariablesIncludingModifiers(_function, m_currentContract))\n\t\tcreateVariable(*variable);\n\n\tfor (auto const& param: _function.parameters())\n\t\tcreateVariable(*param);\n\n\tif (_function.returnParameterList())\n\t\tfor (auto const& retParam: _function.returnParameters())\n\t\t\tcreateVariable(*retParam);\n}\n\nvoid SMTEncoder::initializeLocalVariables(FunctionDefinition const& _function)\n{\n\tfor (auto const& variable: localVariablesIncludingModifiers(_function, m_currentContract))\n\t{\n\t\tsolAssert(m_context.knownVariable(*variable), \"\");\n\t\tm_context.setZeroValue(*variable);\n\t}\n\n\tfor (auto const& param: _function.parameters())\n\t{\n\t\tsolAssert(m_context.knownVariable(*param), \"\");\n\t\tm_context.setUnknownValue(*param);\n\t}\n\n\tif (_function.returnParameterList())\n\t\tfor (auto const& retParam: _function.returnParameters())\n\t\t{\n\t\t\tsolAssert(m_context.knownVariable(*retParam), \"\");\n\t\t\tm_context.setZeroValue(*retParam);\n\t\t}\n}\n\nvoid SMTEncoder::resetStateVariables()\n{\n\tm_context.resetVariables([&](VariableDeclaration const& _variable) { return _variable.isStateVariable(); });\n}\n\nvoid SMTEncoder::resetMemoryVariables()\n{\n\tm_context.resetVariables([&](VariableDeclaration const& _variable) {\n\t\treturn _variable.referenceLocation() == VariableDeclaration::Location::Memory;\n\t});\n}\n\nvoid SMTEncoder::resetStorageVariables()\n{\n\tm_context.resetVariables([&](VariableDeclaration const& _variable) {\n\t\treturn _variable.referenceLocation() == VariableDeclaration::Location::Storage || _variable.isStateVariable();\n\t});\n}\n\nvoid SMTEncoder::resetBalances()\n{\n\tstate().newBalances();\n}\n\nvoid SMTEncoder::resetReferences(VariableDeclaration const& _varDecl)\n{\n\tm_context.resetVariables([&](VariableDeclaration const& _var) {\n\t\tif (_var == _varDecl)\n\t\t\treturn false;\n\n\t\t// If both are state variables no need to clear knowledge.\n\t\tif (_var.isStateVariable() && _varDecl.isStateVariable())\n\t\t\treturn false;\n\n\t\treturn sameTypeOrSubtype(_var.type(), _varDecl.type());\n\t});\n}\n\nvoid SMTEncoder::resetReferences(Type const* _type)\n{\n\tm_context.resetVariables([&](VariableDeclaration const& _var) {\n\t\treturn sameTypeOrSubtype(_var.type(), _type);\n\t});\n}\n\nbool SMTEncoder::sameTypeOrSubtype(Type const* _a, Type const* _b)\n{\n\tbool foundSame = false;\n\n\tsolidity::util::BreadthFirstSearch<Type const*> bfs{{_a}};\n\tbfs.run([&](auto _type, auto&& _addChild) {\n\t\tif (*typeWithoutPointer(_b) == *typeWithoutPointer(_type))\n\t\t{\n\t\t\tfoundSame = true;\n\t\t\tbfs.abort();\n\t\t}\n\t\tif (auto const* mapType = dynamic_cast<MappingType const*>(_type))\n\t\t\t_addChild(mapType->valueType());\n\t\telse if (auto const* arrayType = dynamic_cast<ArrayType const*>(_type))\n\t\t\t_addChild(arrayType->baseType());\n\t\telse if (auto const* structType = dynamic_cast<StructType const*>(_type))\n\t\t\tfor (auto const& member: structType->nativeMembers(nullptr))\n\t\t\t\t_addChild(member.type);\n\t});\n\n\treturn foundSame;\n}\n\nbool SMTEncoder::isSupportedType(Type const& _type) const\n{\n\treturn smt::isSupportedType(*underlyingType(&_type));\n}\n\nType const* SMTEncoder::typeWithoutPointer(Type const* _type)\n{\n\tif (auto refType = dynamic_cast<ReferenceType const*>(_type))\n\t\treturn TypeProvider::withLocationIfReference(refType->location(), _type);\n\treturn _type;\n}\n\nvoid SMTEncoder::mergeVariables(smtutil::Expression const& _condition, VariableIndices const& _indicesEndTrue, VariableIndices const& _indicesEndFalse)\n{\n\tfor (auto const& entry: _indicesEndTrue)\n\t{\n\t\tVariableDeclaration const* var = entry.first;\n\t\tauto trueIndex = entry.second;\n\t\tif (_indicesEndFalse.count(var) && _indicesEndFalse.at(var) != trueIndex)\n\t\t{\n\t\t\tm_context.addAssertion(m_context.newValue(*var) == smtutil::Expression::ite(\n\t\t\t\t_condition,\n\t\t\t\tvalueAtIndex(*var, trueIndex),\n\t\t\t\tvalueAtIndex(*var, _indicesEndFalse.at(var)))\n\t\t\t);\n\t\t}\n\t}\n}\n\nsmtutil::Expression SMTEncoder::currentValue(VariableDeclaration const& _decl) const\n{\n\tsolAssert(m_context.knownVariable(_decl), \"\");\n\treturn m_context.variable(_decl)->currentValue();\n}\n\nsmtutil::Expression SMTEncoder::valueAtIndex(VariableDeclaration const& _decl, unsigned _index) const\n{\n\tsolAssert(m_context.knownVariable(_decl), \"\");\n\treturn m_context.variable(_decl)->valueAtIndex(_index);\n}\n\nbool SMTEncoder::createVariable(VariableDeclaration const& _varDecl)\n{\n\tif (m_context.knownVariable(_varDecl))\n\t\treturn true;\n\tbool abstract = m_context.createVariable(_varDecl);\n\tif (abstract)\n\t{\n\t\tm_unsupportedErrors.warning(\n\t\t\t8115_error,\n\t\t\t_varDecl.location(),\n\t\t\t\"Assertion checker does not yet support the type of this variable.\"\n\t\t);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nsmtutil::Expression SMTEncoder::expr(Expression const& _e, Type const* _targetType)\n{\n\tif (!m_context.knownExpression(_e))\n\t{\n\t\tm_unsupportedErrors.warning(6031_error, _e.location(), \"Internal error: Expression undefined for SMT solver.\" );\n\t\tcreateExpr(_e);\n\t}\n\n\treturn m_context.expression(_e)->currentValue(underlyingType(_targetType));\n}\n\nvoid SMTEncoder::createExpr(Expression const& _e)\n{\n\tbool abstract = m_context.createExpression(_e);\n\tif (abstract)\n\t\tm_unsupportedErrors.warning(\n\t\t\t8364_error,\n\t\t\t_e.location(),\n\t\t\t\"Assertion checker does not yet implement type \" + _e.annotation().type->toString()\n\t\t);\n}\n\nvoid SMTEncoder::defineExpr(Expression const& _e, smtutil::Expression _value)\n{\n\tauto type = _e.annotation().type;\n\tcreateExpr(_e);\n\tsolAssert(_value.sort->kind != smtutil::Kind::Function, \"Equality operator applied to type that is not fully supported\");\n\tif (!smt::isInaccessibleDynamic(*type))\n\t\tm_context.addAssertion(expr(_e) == _value);\n\n\tif (m_checked && smt::isNumber(*type))\n\t\tm_context.addAssertion(smtutil::Expression::implies(\n\t\t\tcurrentPathConditions(),\n\t\t\tsmt::symbolicUnknownConstraints(expr(_e), type)\n\t\t));\n}\n\nvoid SMTEncoder::defineExpr(Expression const& _e, std::vector<std::optional<smtutil::Expression>> const& _values)\n{\n\tif (_values.size() == 1 && _values.front())\n\t{\n\t\tdefineExpr(_e, *_values.front());\n\t\treturn;\n\t}\n\tauto const& symbTuple = std::dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(_e));\n\tsolAssert(symbTuple, \"\");\n\tsymbTuple->increaseIndex();\n\tauto const& symbComponents = symbTuple->components();\n\tsolAssert(symbComponents.size() == _values.size(), \"\");\n\tauto tupleType = dynamic_cast<TupleType const*>(_e.annotation().type);\n\tsolAssert(tupleType, \"\");\n\tsolAssert(tupleType->components().size() == symbComponents.size(), \"\");\n\tfor (unsigned i = 0; i < symbComponents.size(); ++i)\n\t\tif (_values[i] && !smt::isInaccessibleDynamic(*tupleType->components()[i]))\n\t\t\tm_context.addAssertion(symbTuple->component(i) == *_values[i]);\n}\n\nvoid SMTEncoder::popPathCondition()\n{\n\tsolAssert(m_pathConditions.size() > 0, \"Cannot pop path condition, empty.\");\n\tm_pathConditions.pop_back();\n}\n\nvoid SMTEncoder::pushPathCondition(smtutil::Expression const& _e)\n{\n\tm_pathConditions.push_back(currentPathConditions() && _e);\n}\n\nvoid SMTEncoder::setPathCondition(smtutil::Expression const& _e)\n{\n\tif (m_pathConditions.empty())\n\t\tm_pathConditions.push_back(_e);\n\telse\n\t\tm_pathConditions.back() = _e;\n}\n\nsmtutil::Expression SMTEncoder::currentPathConditions()\n{\n\tif (m_pathConditions.empty())\n\t\treturn smtutil::Expression(true);\n\treturn m_pathConditions.back();\n}\n\nSecondarySourceLocation SMTEncoder::callStackMessage(std::vector<CallStackEntry> const& _callStack)\n{\n\tSecondarySourceLocation callStackLocation;\n\tsolAssert(!_callStack.empty(), \"\");\n\tcallStackLocation.append(\"Callstack:\", SourceLocation());\n\tfor (auto const& call: _callStack | ranges::views::reverse)\n\t\tif (call.second)\n\t\t\tcallStackLocation.append(\"\", call.second->location());\n\treturn callStackLocation;\n}\n\nstd::pair<CallableDeclaration const*, ASTNode const*> SMTEncoder::popCallStack()\n{\n\tsolAssert(!m_callStack.empty(), \"\");\n\tauto lastCalled = m_callStack.back();\n\tm_callStack.pop_back();\n\treturn lastCalled;\n}\n\nvoid SMTEncoder::pushCallStack(CallStackEntry _entry)\n{\n\tm_callStack.push_back(_entry);\n}\n\nvoid SMTEncoder::addPathImpliedExpression(smtutil::Expression const& _e)\n{\n\tm_context.addAssertion(smtutil::Expression::implies(currentPathConditions(), _e));\n}\n\nbool SMTEncoder::isRootFunction()\n{\n\treturn m_callStack.size() == 1;\n}\n\nbool SMTEncoder::visitedFunction(FunctionDefinition const* _funDef)\n{\n\tfor (auto const& call: m_callStack)\n\t\tif (call.first == _funDef)\n\t\t\treturn true;\n\treturn false;\n}\n\nContractDefinition const* SMTEncoder::currentScopeContract()\n{\n\tfor (auto&& f: m_callStack | ranges::views::reverse | ranges::views::keys)\n\t\tif (auto fun = dynamic_cast<FunctionDefinition const*>(f))\n\t\t\treturn fun->annotation().contract;\n\treturn nullptr;\n}\n\nSMTEncoder::VariableIndices SMTEncoder::copyVariableIndices()\n{\n\tVariableIndices indices;\n\tfor (auto const& var: m_context.variables())\n\t\tindices.emplace(var.first, var.second->index());\n\treturn indices;\n}\n\nvoid SMTEncoder::resetVariableIndices(VariableIndices const& _indices)\n{\n\tfor (auto const& var: _indices)\n\t\tm_context.variable(*var.first)->setIndex(var.second);\n}\n\nvoid SMTEncoder::clearIndices(ContractDefinition const* _contract, FunctionDefinition const* _function)\n{\n\tsolAssert(_contract, \"\");\n\tfor (auto var: stateVariablesIncludingInheritedAndPrivate(*_contract))\n\t\tm_context.variable(*var)->resetIndex();\n\tif (_function)\n\t{\n\t\tfor (auto const& var: _function->parameters() + _function->returnParameters())\n\t\t\tm_context.variable(*var)->resetIndex();\n\t\tfor (auto const& var: localVariablesIncludingModifiers(*_function, _contract))\n\t\t\tm_context.variable(*var)->resetIndex();\n\t}\n\tstate().reset();\n}\n\nExpression const* SMTEncoder::leftmostBase(IndexAccess const& _indexAccess)\n{\n\tExpression const* base = &_indexAccess.baseExpression();\n\twhile (auto access = dynamic_cast<IndexAccess const*>(base))\n\t\tbase = &access->baseExpression();\n\treturn base;\n}\n\nType const* SMTEncoder::keyType(Type const* _type)\n{\n\tif (auto const* mappingType = dynamic_cast<MappingType const*>(_type))\n\t\treturn mappingType->keyType();\n\tif (\n\t\tdynamic_cast<ArrayType const*>(_type) ||\n\t\tdynamic_cast<ArraySliceType const*>(_type)\n\t)\n\t\treturn TypeProvider::uint256();\n\telse\n\t\tsolAssert(false, \"\");\n}\n\nExpression const& SMTEncoder::innermostTuple(Expression const& _expr)\n{\n\tauto const* tuple = dynamic_cast<TupleExpression const*>(&_expr);\n\tif (!tuple || tuple->isInlineArray())\n\t\treturn _expr;\n\n\tExpression const* expr = tuple;\n\twhile (tuple && !tuple->isInlineArray() && tuple->components().size() == 1)\n\t{\n\t\texpr = tuple->components().front().get();\n\t\ttuple = dynamic_cast<TupleExpression const*>(expr);\n\t}\n\tsolAssert(expr, \"\");\n\treturn *expr;\n}\n\nType const* SMTEncoder::underlyingType(Type const* _type)\n{\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(_type))\n\t\t_type = &userType->underlyingType();\n\treturn _type;\n}\n\nTypePointers SMTEncoder::replaceUserTypes(TypePointers const& _types)\n{\n\treturn applyMap(_types, [](auto _type) {\n\t\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(_type))\n\t\t\treturn &userType->underlyingType();\n\t\treturn _type;\n\t});\n}\n\nstd::pair<Expression const*, FunctionCallOptions const*> SMTEncoder::functionCallExpression(FunctionCall const& _funCall)\n{\n\tExpression const* callExpr = &innermostTuple(_funCall.expression());\n\tauto const* callOptions = dynamic_cast<FunctionCallOptions const*>(callExpr);\n\tif (callOptions)\n\t\tcallExpr = &callOptions->expression();\n\n\treturn {callExpr, callOptions};\n}\n\nExpression const* SMTEncoder::cleanExpression(Expression const& _expr)\n{\n\tauto const* expr = &_expr;\n\tif (auto const* tuple = dynamic_cast<TupleExpression const*>(expr))\n\t\treturn cleanExpression(innermostTuple(*tuple));\n\tif (auto const* functionCall = dynamic_cast<FunctionCall const*>(expr))\n\t\tif (*functionCall->annotation().kind == FunctionCallKind::TypeConversion)\n\t\t{\n\t\t\tauto typeType = dynamic_cast<TypeType const*>(functionCall->expression().annotation().type);\n\t\t\tsolAssert(typeType, \"\");\n\t\t\tif (auto const* arrayType = dynamic_cast<ArrayType const*>(typeType->actualType()))\n\t\t\t\tif (arrayType->isByteArrayOrString())\n\t\t\t\t{\n\t\t\t\t\t// this is a cast to `bytes`\n\t\t\t\t\tsolAssert(functionCall->arguments().size() == 1, \"\");\n\t\t\t\t\tExpression const& arg = *functionCall->arguments()[0];\n\t\t\t\t\tif (\n\t\t\t\t\t\tauto const* argArrayType = dynamic_cast<ArrayType const*>(arg.annotation().type);\n\t\t\t\t\t\targArrayType && argArrayType->isByteArrayOrString()\n\t\t\t\t\t)\n\t\t\t\t\t\treturn cleanExpression(arg);\n\t\t\t\t}\n\t\t}\n\tsolAssert(expr, \"\");\n\treturn expr;\n}\n\nDeclaration const* SMTEncoder::expressionToDeclaration(Expression const& _expr) const\n{\n\tif (auto const* identifier = dynamic_cast<Identifier const*>(&_expr))\n\t\treturn identifier->annotation().referencedDeclaration;\n\tif (auto const* outerMemberAccess = dynamic_cast<MemberAccess const*>(&_expr))\n\t\treturn outerMemberAccess->annotation().referencedDeclaration;\n\treturn nullptr;\n}\n\nVariableDeclaration const* SMTEncoder::identifierToVariable(Expression const& _expr) const\n{\n\t// We do not use `expressionToDeclaration` here because we are not interested in\n\t// struct.field, for example.\n\tif (auto const* identifier = dynamic_cast<Identifier const*>(&_expr))\n\t\tif (auto const* varDecl = dynamic_cast<VariableDeclaration const*>(identifier->annotation().referencedDeclaration))\n\t\t{\n\t\t\tsolAssert(m_context.knownVariable(*varDecl), \"\");\n\t\t\treturn varDecl;\n\t\t}\n\t// But we are interested in \"contract.var\", because that is the same as just \"var\".\n\tif (auto const* memberAccess = dynamic_cast<MemberAccess const*>(&_expr))\n\t\tif (dynamic_cast<ContractDefinition const*>(expressionToDeclaration(\n\t\t\t*cleanExpression(memberAccess->expression())\n\t\t)))\n\t\t\tif (auto const* varDecl = dynamic_cast<VariableDeclaration const*>(memberAccess->annotation().referencedDeclaration))\n\t\t\t{\n\t\t\t\tsolAssert(m_context.knownVariable(*varDecl), \"\");\n\t\t\t\treturn varDecl;\n\t\t\t}\n\n\treturn nullptr;\n}\n\nMemberAccess const* SMTEncoder::isEmptyPush(Expression const& _expr) const\n{\n\tif (\n\t\tauto const* funCall = dynamic_cast<FunctionCall const*>(&_expr);\n\t\tfunCall && funCall->arguments().empty()\n\t)\n\t{\n\t\tauto const& funType = dynamic_cast<FunctionType const&>(*funCall->expression().annotation().type);\n\t\tif (funType.kind() == FunctionType::Kind::ArrayPush)\n\t\t\treturn &dynamic_cast<MemberAccess const&>(funCall->expression());\n\t}\n\treturn nullptr;\n}\n\nsmtutil::Expression SMTEncoder::contractAddressValue(FunctionCall const& _f)\n{\n\tFunctionType const& funType = dynamic_cast<FunctionType const&>(*_f.expression().annotation().type);\n\tif (funType.kind() == FunctionType::Kind::Internal)\n\t\treturn state().thisAddress();\n\tauto [funExpr, funOptions] = functionCallExpression(_f);\n\tif (MemberAccess const* callBase = dynamic_cast<MemberAccess const*>(funExpr))\n\t\treturn expr(callBase->expression());\n\tsmtAssert(false, \"Unexpected function call type encountered while getting contract address!\");\n}\n\nVariableDeclaration const* SMTEncoder::publicGetter(Expression const& _expr) const {\n\tif (auto memberAccess = dynamic_cast<MemberAccess const*>(&_expr))\n\t\tif (auto variableDeclaration = dynamic_cast<VariableDeclaration const*>(memberAccess->annotation().referencedDeclaration))\n\t\t\treturn variableDeclaration->isStateVariable() ? variableDeclaration : nullptr;\n\treturn nullptr;\n}\n\nbool SMTEncoder::isExternalCallToThis(Expression const* _expr) {\n\tauto memberAccess = dynamic_cast<MemberAccess const*>(_expr);\n\tif (!memberAccess)\n\t\treturn false;\n\n\tauto identifier = dynamic_cast<Identifier const*>(&memberAccess->expression());\n\treturn identifier &&\n\t\tidentifier->name() == \"this\" &&\n\t\tidentifier->annotation().referencedDeclaration &&\n\t\tdynamic_cast<MagicVariableDeclaration const*>(identifier->annotation().referencedDeclaration)\n\t;\n}\n\nstd::string SMTEncoder::extraComment()\n{\n\tstd::string extra;\n\tif (m_arrayAssignmentHappened)\n\t\textra +=\n\t\t\t\"\\nNote that array aliasing is not supported,\"\n\t\t\t\" therefore all mapping information is erased after\"\n\t\t\t\" a mapping local variable/parameter is assigned.\\n\"\n\t\t\t\"You can re-introduce information using require().\";\n\treturn extra;\n}\n\nFunctionDefinition const* SMTEncoder::functionCallToDefinition(\n\tFunctionCall const& _funCall,\n\tContractDefinition const* _scopeContract,\n\tContractDefinition const* _contextContract\n)\n{\n\tif (*_funCall.annotation().kind != FunctionCallKind::FunctionCall)\n\t\treturn {};\n\n\tauto [calledExpr, callOptions] = functionCallExpression(_funCall);\n\n\tif (TupleExpression const* fun = dynamic_cast<TupleExpression const*>(calledExpr))\n\t{\n\t\tsolAssert(fun->components().size() == 1, \"\");\n\t\tcalledExpr = &innermostTuple(*calledExpr);\n\t}\n\n\tauto resolveVirtual = [&](auto const* _ref) -> FunctionDefinition const* {\n\t\tVirtualLookup lookup = *_ref->annotation().requiredLookup;\n\t\tsolAssert(_contextContract || lookup == VirtualLookup::Static, \"No contract context provided for function lookup resolution!\");\n\t\tauto funDef = dynamic_cast<FunctionDefinition const*>(_ref->annotation().referencedDeclaration);\n\t\tif (!funDef)\n\t\t\treturn funDef;\n\t\tswitch (lookup)\n\t\t{\n\t\tcase VirtualLookup::Virtual:\n\t\t\treturn &(funDef->resolveVirtual(*_contextContract));\n\t\tcase VirtualLookup::Super:\n\t\t{\n\t\t\tsolAssert(_scopeContract, \"\");\n\t\t\tauto super = _scopeContract->superContract(*_contextContract);\n\t\t\tsolAssert(super, \"Super contract not available.\");\n\t\t\treturn &funDef->resolveVirtual(*_contextContract, super);\n\t\t}\n\t\tcase VirtualLookup::Static:\n\t\t\treturn funDef;\n\t\t}\n\t\tsolAssert(false, \"\");\n\t};\n\n\tif (Identifier const* fun = dynamic_cast<Identifier const*>(calledExpr))\n\t\treturn resolveVirtual(fun);\n\telse if (MemberAccess const* fun = dynamic_cast<MemberAccess const*>(calledExpr))\n\t\treturn resolveVirtual(fun);\n\n\treturn {};\n}\n\nstd::vector<VariableDeclaration const*> SMTEncoder::stateVariablesIncludingInheritedAndPrivate(ContractDefinition const& _contract)\n{\n\treturn fold(\n\t\t_contract.annotation().linearizedBaseContracts,\n\t\tstd::vector<VariableDeclaration const*>{},\n\t\t[](auto&& _acc, auto _contract) { return _acc + _contract->stateVariables(); }\n\t);\n}\n\nstd::vector<VariableDeclaration const*> SMTEncoder::stateVariablesIncludingInheritedAndPrivate(FunctionDefinition const& _function)\n{\n\tif (auto contract = dynamic_cast<ContractDefinition const*>(_function.scope()))\n\t\treturn stateVariablesIncludingInheritedAndPrivate(*contract);\n\treturn {};\n}\n\nstd::vector<VariableDeclaration const*> SMTEncoder::localVariablesIncludingModifiers(FunctionDefinition const& _function, ContractDefinition const* _contract)\n{\n\treturn _function.localVariables() + tryCatchVariables(_function) + modifiersVariables(_function, _contract);\n}\n\nstd::vector<VariableDeclaration const*> SMTEncoder::tryCatchVariables(FunctionDefinition const& _function)\n{\n\tstruct TryCatchVarsVisitor : public ASTConstVisitor\n\t{\n\t\tbool visit(TryCatchClause const& _catchClause) override\n\t\t{\n\t\t\tif (_catchClause.parameters())\n\t\t\t{\n\t\t\t\tauto const& params = _catchClause.parameters()->parameters();\n\t\t\t\tfor (auto param: params)\n\t\t\t\t\tvars.push_back(param.get());\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tstd::vector<VariableDeclaration const*> vars;\n\t} tryCatchVarsVisitor;\n\t_function.accept(tryCatchVarsVisitor);\n\treturn tryCatchVarsVisitor.vars;\n}\n\nstd::vector<VariableDeclaration const*> SMTEncoder::modifiersVariables(FunctionDefinition const& _function, ContractDefinition const* _contract)\n{\n\tstruct BlockVars: ASTConstVisitor\n\t{\n\t\tBlockVars(Block const& _block) { _block.accept(*this); }\n\t\tvoid endVisit(VariableDeclaration const& _var) { vars.push_back(&_var); }\n\t\tstd::vector<VariableDeclaration const*> vars;\n\t};\n\n\tstd::vector<VariableDeclaration const*> vars;\n\tstd::set<ModifierDefinition const*> visited;\n\tfor (auto invok: _function.modifiers())\n\t{\n\t\tif (!invok)\n\t\t\tcontinue;\n\t\tauto const* modifier = resolveModifierInvocation(*invok, _contract);\n\t\tif (!modifier || visited.count(modifier))\n\t\t\tcontinue;\n\n\t\tvisited.insert(modifier);\n\t\tif (modifier->isImplemented())\n\t\t{\n\t\t\tvars += applyMap(modifier->parameters(), [](auto _var) { return _var.get(); });\n\t\t\tvars += BlockVars(modifier->body()).vars;\n\t\t}\n\t}\n\treturn vars;\n}\n\nModifierDefinition const* SMTEncoder::resolveModifierInvocation(ModifierInvocation const& _invocation, ContractDefinition const* _contract)\n{\n\tauto const* modifier = dynamic_cast<ModifierDefinition const*>(_invocation.name().annotation().referencedDeclaration);\n\tif (modifier)\n\t{\n\t\tVirtualLookup lookup = *_invocation.name().annotation().requiredLookup;\n\t\tsolAssert(lookup == VirtualLookup::Virtual || lookup == VirtualLookup::Static, \"\");\n\t\tsolAssert(_contract || lookup == VirtualLookup::Static, \"No contract context provided for modifier lookup resolution!\");\n\t\tif (lookup == VirtualLookup::Virtual)\n\t\t\tmodifier = &modifier->resolveVirtual(*_contract);\n\t}\n\treturn modifier;\n}\n\nstd::set<FunctionDefinition const*, ASTNode::CompareByID> const& SMTEncoder::contractFunctions(ContractDefinition const& _contract)\n{\n\tif (!m_contractFunctions.count(&_contract))\n\t{\n\t\tauto const& functions = _contract.definedFunctions();\n\t\tstd::set<FunctionDefinition const*, ASTNode::CompareByID> resolvedFunctions(begin(functions), end(functions));\n\t\tfor (auto const* base: _contract.annotation().linearizedBaseContracts)\n\t\t{\n\t\t\tif (base == &_contract)\n\t\t\t\tcontinue;\n\t\t\tfor (auto const* baseFunction: base->definedFunctions())\n\t\t\t{\n\t\t\t\tif (baseFunction->isConstructor()) // We don't want to include constructors of parent contracts\n\t\t\t\t\tcontinue;\n\t\t\t\tbool overridden = false;\n\t\t\t\tfor (auto const* function: resolvedFunctions)\n\t\t\t\t\tif (\n\t\t\t\t\t\tfunction->name() == baseFunction->name() &&\n\t\t\t\t\t\tfunction->kind() == baseFunction->kind() &&\n\t\t\t\t\t\tFunctionType(*function).asExternallyCallableFunction(false)->\n\t\t\t\t\t\t\thasEqualParameterTypes(*FunctionType(*baseFunction).asExternallyCallableFunction(false))\n\t\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\toverridden = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\tif (!overridden)\n\t\t\t\t\tresolvedFunctions.insert(baseFunction);\n\t\t\t}\n\t\t}\n\t\tm_contractFunctions.emplace(&_contract, std::move(resolvedFunctions));\n\t}\n\treturn m_contractFunctions.at(&_contract);\n}\n\nstd::set<FunctionDefinition const*, ASTNode::CompareByID> const& SMTEncoder::contractFunctionsWithoutVirtual(ContractDefinition const& _contract)\n{\n\tif (!m_contractFunctionsWithoutVirtual.count(&_contract))\n\t{\n\t\tauto allFunctions = contractFunctions(_contract);\n\t\tfor (auto const* base: _contract.annotation().linearizedBaseContracts)\n\t\t\tfor (auto const* baseFun: base->definedFunctions())\n\t\t\t\tallFunctions.insert(baseFun);\n\n\t\tm_contractFunctionsWithoutVirtual.emplace(&_contract, std::move(allFunctions));\n\n\t}\n\treturn m_contractFunctionsWithoutVirtual.at(&_contract);\n}\n\nstd::map<ContractDefinition const*, std::vector<ASTPointer<frontend::Expression>>> SMTEncoder::baseArguments(ContractDefinition const& _contract)\n{\n\tstd::map<ContractDefinition const*, std::vector<ASTPointer<Expression>>> baseArgs;\n\n\tfor (auto contract: _contract.annotation().linearizedBaseContracts)\n\t{\n\t\t/// Collect base contracts and potential constructor arguments.\n\t\tfor (auto specifier: contract->baseContracts())\n\t\t{\n\t\t\tsolAssert(specifier, \"\");\n\t\t\tauto const& base = dynamic_cast<ContractDefinition const&>(*specifier->name().annotation().referencedDeclaration);\n\t\t\tif (auto args = specifier->arguments())\n\t\t\t\tbaseArgs[&base] = *args;\n\t\t}\n\t\t/// Collect base constructor arguments given as constructor modifiers.\n\t\tif (auto constructor = contract->constructor())\n\t\t\tfor (auto mod: constructor->modifiers())\n\t\t\t{\n\t\t\t\tauto decl = mod->name().annotation().referencedDeclaration;\n\t\t\t\tif (auto base = dynamic_cast<ContractDefinition const*>(decl))\n\t\t\t\t{\n\t\t\t\t\tsolAssert(!baseArgs.count(base), \"\");\n\t\t\t\t\tif (auto args = mod->arguments())\n\t\t\t\t\t\tbaseArgs[base] = *args;\n\t\t\t\t}\n\t\t\t}\n\t}\n\n\treturn baseArgs;\n}\n\nRationalNumberType const* SMTEncoder::isConstant(Expression const& _expr)\n{\n\tif (auto type = dynamic_cast<RationalNumberType const*>(_expr.annotation().type))\n\t\treturn type;\n\n\tif (\n\t\tauto typedValue = ConstantEvaluator::tryEvaluate(_expr);\n\t\tstd::holds_alternative<rational>(typedValue.value)\n\t)\n\t\treturn TypeProvider::rationalNumber(std::get<rational>(typedValue.value));\n\n\treturn nullptr;\n}\n\nstd::set<FunctionCall const*, ASTCompareByID<FunctionCall>> SMTEncoder::collectABICalls(ASTNode const* _node)\n{\n\tstruct ABIFunctions: public ASTConstVisitor\n\t{\n\t\tABIFunctions(ASTNode const* _node) { _node->accept(*this); }\n\t\tvoid endVisit(FunctionCall const& _funCall)\n\t\t{\n\t\t\tif (*_funCall.annotation().kind == FunctionCallKind::FunctionCall)\n\t\t\t\tswitch (dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type).kind())\n\t\t\t\t{\n\t\t\t\tcase FunctionType::Kind::ABIEncode:\n\t\t\t\tcase FunctionType::Kind::ABIEncodePacked:\n\t\t\t\tcase FunctionType::Kind::ABIEncodeWithSelector:\n\t\t\t\tcase FunctionType::Kind::ABIEncodeCall:\n\t\t\t\tcase FunctionType::Kind::ABIEncodeWithSignature:\n\t\t\t\tcase FunctionType::Kind::ABIDecode:\n\t\t\t\t\tabiCalls.insert(&_funCall);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: {}\n\t\t\t\t}\n\t\t}\n\n\t\tstd::set<FunctionCall const*, ASTCompareByID<FunctionCall>> abiCalls;\n\t};\n\n\treturn ABIFunctions(_node).abiCalls;\n}\n\nstd::set<FunctionCall const*, ASTCompareByID<FunctionCall>> SMTEncoder::collectBytesConcatCalls(ASTNode const* _node)\n{\n\tstruct BytesConcatFunctions: public ASTConstVisitor\n\t{\n\t\tBytesConcatFunctions(ASTNode const* _node) { _node->accept(*this); }\n\t\tvoid endVisit(FunctionCall const& _funCall)\n\t\t{\n\t\t\tif (*_funCall.annotation().kind == FunctionCallKind::FunctionCall)\n\t\t\t\tswitch (dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type).kind())\n\t\t\t\t{\n\t\t\t\tcase FunctionType::Kind::BytesConcat:\n\t\t\t\t\tbytesConcatCalls.insert(&_funCall);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: {}\n\t\t\t\t}\n\t\t}\n\n\t\tstd::set<FunctionCall const*, ASTCompareByID<FunctionCall>> bytesConcatCalls;\n\t};\n\n\treturn BytesConcatFunctions(_node).bytesConcatCalls;\n}\n\nstd::set<SourceUnit const*, ASTNode::CompareByID> SMTEncoder::sourceDependencies(SourceUnit const& _source)\n{\n\tstd::set<SourceUnit const*, ASTNode::CompareByID> sources;\n\tsources.insert(&_source);\n\tfor (auto const& source: _source.referencedSourceUnits(true))\n\t\tsources.insert(source);\n\treturn sources;\n}\n\nvoid SMTEncoder::createReturnedExpressions(FunctionDefinition const* _funDef, Expression const& _callStackExpr)\n{\n\tif (!_funDef)\n\t\treturn;\n\n\tauto const& returnParams = _funDef->returnParameters();\n\tfor (auto param: returnParams)\n\t\tcreateVariable(*param);\n\tauto returnValues = applyMap(returnParams, [this](auto const& param) -> std::optional<smtutil::Expression> {\n\t\tsolAssert(param && m_context.knownVariable(*param), \"\");\n\t\treturn currentValue(*param);\n\t});\n\tdefineExpr(_callStackExpr, returnValues);\n}\n\nstd::vector<smtutil::Expression> SMTEncoder::symbolicArguments(\n\tstd::vector<ASTPointer<VariableDeclaration>> const& _funParameters,\n\tstd::vector<Expression const*> const& _arguments,\n\tstd::optional<Expression const*> _boundArgumentCall\n)\n{\n\tstd::vector<smtutil::Expression> args;\n\tunsigned firstParam = 0;\n\tif (_boundArgumentCall)\n\t{\n\t\tExpression const& calledExpr = innermostTuple(*_boundArgumentCall.value());\n\t\tauto const& attachedFunction = dynamic_cast<MemberAccess const*>(&calledExpr);\n\t\tsolAssert(attachedFunction, \"\");\n\t\targs.push_back(expr(attachedFunction->expression(), _funParameters.front()->type()));\n\t\tfirstParam = 1;\n\t}\n\n\tsolAssert((_arguments.size() + firstParam) == _funParameters.size(), \"\");\n\n\tfor (unsigned i = 0; i < _arguments.size(); ++i)\n\t\targs.push_back(expr(*_arguments.at(i), _funParameters.at(i + firstParam)->type()));\n\n\treturn args;\n}\n\nsmtutil::Expression SMTEncoder::constantExpr(Expression const& _expr, VariableDeclaration const& _var)\n{\n\tif (RationalNumberType const* rationalType = isConstant(_expr))\n\t{\n\t\tif (rationalType->isNegative())\n\t\t\treturn smtutil::Expression(u2s(rationalType->literalValue(nullptr)));\n\t\telse\n\t\t\treturn smtutil::Expression(rationalType->literalValue(nullptr));\n\t}\n\telse\n\t{\n\t\tsolAssert(_var.value(), \"\");\n\t\t_var.value()->accept(*this);\n\t\treturn expr(*_var.value(), _expr.annotation().type);\n\t}\n\tsolAssert(false, \"\");\n}\n\nvoid SMTEncoder::collectFreeFunctions(std::set<SourceUnit const*, ASTNode::CompareByID> const& _sources)\n{\n\tfor (auto source: _sources)\n\t\tfor (auto node: source->nodes())\n\t\t\tif (auto function = dynamic_cast<FunctionDefinition const*>(node.get()))\n\t\t\t\tm_freeFunctions.insert(function);\n\t\t\telse if (\n\t\t\t\tauto contract = dynamic_cast<ContractDefinition const*>(node.get());\n\t\t\t\tcontract && contract->isLibrary()\n\t\t\t)\n\t\t\t\tfor (auto function: contract->definedFunctions())\n\t\t\t\t\t// We need to add public library functions too because they can be called\n\t\t\t\t\t// internally by internal library functions that are considered free functions.\n\t\t\t\t\tm_freeFunctions.insert(function);\n}\n\nvoid SMTEncoder::createFreeConstants(std::set<SourceUnit const*, ASTNode::CompareByID> const& _sources)\n{\n\tfor (auto source: _sources)\n\t\tfor (auto node: source->nodes())\n\t\t\tif (auto var = dynamic_cast<VariableDeclaration const*>(node.get()))\n\t\t\t\tcreateVariable(*var);\n\t\t\telse if (\n\t\t\t\tauto contract = dynamic_cast<ContractDefinition const*>(node.get());\n\t\t\t\tcontract && contract->isLibrary()\n\t\t\t)\n\t\t\t\tfor (auto var: contract->stateVariables())\n\t\t\t\t{\n\t\t\t\t\tsolAssert(var->isConstant(), \"\");\n\t\t\t\t\tcreateVariable(*var);\n\t\t\t\t}\n}\n\nvoid SMTEncoder::createStateVariables(std::set<SourceUnit const*, ASTNode::CompareByID> const& _sources)\n{\n\tfor (auto const& source: _sources)\n\t\tfor (auto const& node: source->nodes())\n\t\t\tif (auto contract = dynamic_cast<ContractDefinition const*>(node.get()))\n\t\t\t\tcreateStateVariables(*contract);\n}\n\nsmt::SymbolicState& SMTEncoder::state()\n{\n\treturn m_context.state();\n}\n\nsmtutil::Expression SMTEncoder::createSelectExpressionForFunction(\n\tsmtutil::Expression symbFunction,\n\tstd::vector<frontend::ASTPointer<frontend::Expression const>> const& args,\n\tfrontend::TypePointers const& inTypes,\n\tunsigned long argsActualLength\n)\n{\n\tsolAssert(argsActualLength <= args.size() && inTypes.size() == argsActualLength);\n\tif (inTypes.size() == 1)\n\t{\n\t\tsmtutil::Expression arg = expr(*args.at(0), inTypes.at(0));\n\t\treturn smtutil::Expression::select(symbFunction, arg);\n\t}\n\n\tstd::vector<smtutil::Expression> symbArgs;\n\tfor (unsigned i = 0; i < argsActualLength; ++i)\n\t\tif (args.at(i))\n\t\t\tsymbArgs.emplace_back(expr(*args.at(i), inTypes.at(i)));\n\n\tauto inputSort = dynamic_cast<smtutil::ArraySort&>(*symbFunction.sort).domain;\n\tsmtutil::Expression arg = smtutil::Expression::tuple_constructor(\n\t\tsmtutil::Expression(std::make_shared<smtutil::SortSort>(inputSort), \"\"),\n\t\tsymbArgs\n\t);\n\treturn smtutil::Expression::select(symbFunction, arg);\n}\n"
  },
  {
    "path": "libsolidity/formal/SMTEncoder.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Encodes Solidity into SMT expressions without creating\n * any verification targets.\n * Also implements the SSA scheme for branches.\n */\n\n#pragma once\n\n\n#include <libsolidity/formal/EncodingContext.h>\n#include <libsolidity/formal/ModelCheckerSettings.h>\n#include <libsolidity/formal/SymbolicVariables.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/interface/ReadFile.h>\n#include <liblangutil/UniqueErrorReporter.h>\n\n#include <string>\n#include <unordered_map>\n#include <vector>\n#include <utility>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\nstruct SourceLocation;\nclass CharStreamProvider;\n}\n\nnamespace solidity::frontend\n{\n\nclass SMTEncoder: public ASTConstVisitor\n{\npublic:\n\tSMTEncoder(\n\t\tsmt::EncodingContext& _context,\n\t\tModelCheckerSettings _settings,\n\t\tlangutil::UniqueErrorReporter& _errorReporter,\n\t\tlangutil::UniqueErrorReporter& _unsupportedErrorReporter,\n\t\tlangutil::ErrorReporter& _provedSafeReporter,\n\t\tlangutil::CharStreamProvider const& _charStreamProvider\n\t);\n\n\t/// @returns the leftmost identifier in a multi-d IndexAccess.\n\tstatic Expression const* leftmostBase(IndexAccess const& _indexAccess);\n\n\t/// @returns the key type in _type.\n\t/// _type must allow IndexAccess, that is,\n\t/// it must be either ArrayType or MappingType\n\tstatic Type const* keyType(Type const* _type);\n\n\t/// @returns the innermost element in a chain of 1-tuples if applicable,\n\t/// otherwise _expr.\n\tstatic Expression const& innermostTuple(Expression const& _expr);\n\n\t/// @returns the underlying type if _type is UserDefinedValueType,\n\t/// and _type otherwise.\n\tstatic Type const* underlyingType(Type const* _type);\n\n\tstatic TypePointers replaceUserTypes(TypePointers const& _types);\n\n\t/// @returns {_funCall.expression(), nullptr} if function call option values are not given, and\n\t/// {_funCall.expression().expression(), _funCall.expression()} if they are.\n\tstatic std::pair<Expression const*, FunctionCallOptions const*> functionCallExpression(FunctionCall const& _funCall);\n\n\t/// @returns the expression after stripping redundant syntactic sugar.\n\t/// Currently supports stripping:\n\t/// 1. 1-tuple; i.e. ((x)) -> x\n\t/// 2. Explicit cast from string to bytes; i.e. bytes(s) -> s; for s of type string\n\tstatic Expression const* cleanExpression(Expression const& _expr);\n\n\t/// @returns the FunctionDefinition of a FunctionCall\n\t/// if possible or nullptr.\n\t/// @param _scopeContract is the contract that contains the function currently being\n\t///        analyzed, if applicable.\n\t/// @param _contextContract is the most derived contract currently being analyzed.\n\t/// The difference between the two parameters appears in the case of inheritance.\n\t/// Let A and B be two contracts so that B derives from A, and A defines a function `f`\n\t/// that `B` does not override. Function `f` is visited twice:\n\t/// - Once when A is the most derived contract, where both _scopeContract and _contextContract are A.\n\t/// - Once when B is the most derived contract, where _scopeContract is A and _contextContract is B.\n\tstatic FunctionDefinition const* functionCallToDefinition(\n\t\tFunctionCall const& _funCall,\n\t\tContractDefinition const* _scopeContract,\n\t\tContractDefinition const* _contextContract\n\t);\n\n\tstatic std::vector<VariableDeclaration const*> stateVariablesIncludingInheritedAndPrivate(ContractDefinition const& _contract);\n\tstatic std::vector<VariableDeclaration const*> stateVariablesIncludingInheritedAndPrivate(FunctionDefinition const& _function);\n\n\tstatic std::vector<VariableDeclaration const*> localVariablesIncludingModifiers(FunctionDefinition const& _function, ContractDefinition const* _contract);\n\tstatic std::vector<VariableDeclaration const*> modifiersVariables(FunctionDefinition const& _function, ContractDefinition const* _contract);\n\tstatic std::vector<VariableDeclaration const*> tryCatchVariables(FunctionDefinition const& _function);\n\n\t/// @returns the ModifierDefinition of a ModifierInvocation if possible, or nullptr.\n\tstatic ModifierDefinition const* resolveModifierInvocation(ModifierInvocation const& _invocation, ContractDefinition const* _contract);\n\n\t/// @returns the arguments for each base constructor call in the hierarchy of @a _contract.\n\tstd::map<ContractDefinition const*, std::vector<ASTPointer<frontend::Expression>>> baseArguments(ContractDefinition const& _contract);\n\n\t/// @returns a valid RationalNumberType pointer if _expr has type\n\t/// RationalNumberType or can be const evaluated, and nullptr otherwise.\n\tstatic RationalNumberType const* isConstant(Expression const& _expr);\n\n\tstatic std::set<FunctionCall const*, ASTCompareByID<FunctionCall>> collectABICalls(ASTNode const* _node);\n\tstatic std::set<FunctionCall const*, ASTCompareByID<FunctionCall>> collectBytesConcatCalls(ASTNode const* _node);\n\n\t/// @returns all the sources that @param _source depends on,\n\t/// including itself.\n\tstatic std::set<SourceUnit const*, ASTNode::CompareByID> sourceDependencies(SourceUnit const& _source);\n\nprotected:\n\tstruct TransientDataLocationChecker: ASTConstVisitor\n\t{\n\t\tTransientDataLocationChecker(ContractDefinition const& _contract) { _contract.accept(*this); }\n\n\t\tvoid endVisit(VariableDeclaration const& _var)\n\t\t{\n\t\t\tsolUnimplementedAssert(\n\t\t\t\t_var.referenceLocation() != VariableDeclaration::Location::Transient,\n\t\t\t\t\"Transient storage variables are not supported.\"\n\t\t\t);\n\t\t}\n\t};\n\n\tvoid resetSourceAnalysis();\n\n\t// TODO: Check that we do not have concurrent reads and writes to a variable,\n\t// because the order of expression evaluation is undefined\n\t// TODO: or just force a certain order, but people might have a different idea about that.\n\n\tbool visit(ImportDirective const& _node) override;\n\tbool visit(ContractDefinition const& _node) override;\n\tvoid endVisit(ContractDefinition const& _node) override;\n\tvoid endVisit(VariableDeclaration const& _node) override;\n\tbool visit(ModifierDefinition const& _node) override;\n\tbool visit(FunctionDefinition const& _node) override;\n\tvoid endVisit(FunctionDefinition const& _node) override;\n\tbool visit(Block const& _node) override;\n\tvoid endVisit(Block const& _node) override;\n\tbool visit(PlaceholderStatement const& _node) override;\n\tbool visit(IfStatement const&) override { return false; }\n\tbool visit(WhileStatement const&) override { return false; }\n\tbool visit(ForStatement const&) override { return false; }\n\tvoid endVisit(ForStatement const&) override {}\n\tvoid endVisit(VariableDeclarationStatement const& _node) override;\n\tbool visit(Assignment const& _node) override;\n\tvoid endVisit(Assignment const& _node) override;\n\tvoid endVisit(TupleExpression const& _node) override;\n\tbool visit(UnaryOperation const& _node) override;\n\tvoid endVisit(UnaryOperation const& _node) override;\n\tbool visit(BinaryOperation const& _node) override;\n\tvoid endVisit(BinaryOperation const& _node) override;\n\tbool visit(Conditional const& _node) override;\n\tbool visit(FunctionCall const& _node) override;\n\tvoid endVisit(FunctionCall const& _node) override;\n\tbool visit(ModifierInvocation const& _node) override;\n\tvoid endVisit(Identifier const& _node) override;\n\tvoid endVisit(ElementaryTypeNameExpression const& _node) override;\n\tvoid endVisit(Literal const& _node) override;\n\tvoid endVisit(Return const& _node) override;\n\tbool visit(MemberAccess const& _node) override;\n\tvoid endVisit(IndexAccess const& _node) override;\n\tvoid endVisit(IndexRangeAccess const& _node) override;\n\tbool visit(InlineAssembly const& _node) override;\n\tbool visit(Break const&) override { return false; }\n\tvoid endVisit(Break const&) override {}\n\tbool visit(Continue const&) override { return false; }\n\tvoid endVisit(Continue const&) override {}\n\tbool visit(TryCatchClause const&) override { return true; }\n\tvoid endVisit(TryCatchClause const&) override {}\n\tbool visit(TryStatement const&) override { return false; }\n\n\tvirtual void pushInlineFrame(CallableDeclaration const&);\n\tvirtual void popInlineFrame(CallableDeclaration const&);\n\n\t/// Do not visit subtree if node is a RationalNumber.\n\t/// Symbolic _expr is the rational literal.\n\tbool shortcutRationalNumber(Expression const& _expr);\n\tvoid arithmeticOperation(BinaryOperation const& _op);\n\t/// @returns _op(_left, _right) with and without modular arithmetic.\n\t/// Used by the function above, compound assignments and\n\t/// unary increment/decrement.\n\tvirtual std::pair<smtutil::Expression, smtutil::Expression> arithmeticOperation(\n\t\tToken _op,\n\t\tsmtutil::Expression const& _left,\n\t\tsmtutil::Expression const& _right,\n\t\tType const* _commonType,\n\t\tExpression const& _expression\n\t);\n\n\tsmtutil::Expression bitwiseOperation(\n\t\tToken _op,\n\t\tsmtutil::Expression const& _left,\n\t\tsmtutil::Expression const& _right,\n\t\tType const* _commonType\n\t);\n\n\tvoid compareOperation(BinaryOperation const& _op);\n\tvoid booleanOperation(BinaryOperation const& _op);\n\tvoid bitwiseOperation(BinaryOperation const& _op);\n\tvoid bitwiseNotOperation(UnaryOperation const& _op);\n\n\tvoid initContract(ContractDefinition const& _contract);\n\tvoid initFunction(FunctionDefinition const& _function);\n\tvoid visitAssert(FunctionCall const& _funCall);\n\tvoid visitRequire(FunctionCall const& _funCall);\n\tvoid visitABIFunction(FunctionCall const& _funCall);\n\tvoid visitBytesConcat(FunctionCall const& _funCall);\n\tvoid visitCryptoFunction(FunctionCall const& _funCall);\n\tvoid visitGasLeft(FunctionCall const& _funCall);\n\tvoid visitBlobHash(FunctionCall const& _funCall);\n\tvirtual void visitAddMulMod(FunctionCall const& _funCall);\n\tvoid visitWrapUnwrap(FunctionCall const& _funCall);\n\tvoid visitObjectCreation(FunctionCall const& _funCall);\n\tvoid visitTypeConversion(FunctionCall const& _funCall);\n\tvoid visitStructConstructorCall(FunctionCall const& _funCall);\n\tvoid visitFunctionIdentifier(Identifier const& _identifier);\n\tvirtual void visitPublicGetter(FunctionCall const& _funCall);\n\n\t/// @returns true if symbolic representation of @param _contract is required for verification\n\tbool shouldEncode(ContractDefinition const& _contract) const;\n\t/// @returns true if the verification targets of @param _contract are actually selected for verification\n\tbool shouldAnalyzeVerificationTargetsFor(ContractDefinition const& _contract) const;\n\t/// @returns true if we should descend into @param _source to look for contracts that should be verified\n\tbool shouldAnalyzeVerificationTargetsFor(SourceUnit const& _source) const;\n\n\t/// @returns the state variable returned by a public getter if\n\t/// @a _expr is a call to a public getter,\n\t/// otherwise nullptr.\n\tVariableDeclaration const* publicGetter(Expression const& _expr) const;\n\n\tsmtutil::Expression contractAddressValue(FunctionCall const& _f);\n\n\t/// Encodes a modifier or function body according to the modifier\n\t/// visit depth.\n\tvoid visitFunctionOrModifier();\n\n\t/// Inlines a modifier or base constructor call.\n\tvoid inlineModifierInvocation(ModifierInvocation const* _invocation, CallableDeclaration const* _definition);\n\n\t/// Inlines the constructor hierarchy into a single constructor.\n\tvoid inlineConstructorHierarchy(ContractDefinition const& _contract);\n\n\t/// Defines a new global variable or function.\n\tvoid defineGlobalVariable(std::string const& _name, Expression const& _expr, bool _increaseIndex = false);\n\n\t/// Handles the side effects of assignment\n\t/// to variable of some SMT array type\n\t/// while aliasing is not supported.\n\tvoid arrayAssignment();\n\t/// Handles assignments to index or member access.\n\tvoid indexOrMemberAssignment(Expression const& _expr, smtutil::Expression const& _rightHandSide);\n\n\tvoid arrayPush(FunctionCall const& _funCall);\n\tvoid arrayPop(FunctionCall const& _funCall);\n\t/// Allows BMC and CHC to create verification targets for popping\n\t/// an empty array.\n\tvirtual void makeArrayPopVerificationTarget(FunctionCall const&) {}\n\t/// Allows BMC and CHC to create verification targets for out of bounds access.\n\tvirtual void makeOutOfBoundsVerificationTarget(IndexAccess const&) {}\n\n\tvoid addArrayLiteralAssertions(\n\t\tsmt::SymbolicArrayVariable& _symArray,\n\t\tstd::vector<smtutil::Expression> const& _elementValues\n\t);\n\n\tvoid bytesToFixedBytesAssertions(\n\t\tsmt::SymbolicArrayVariable& _symArray,\n\t\tExpression const& _fixedBytes\n\t);\n\n\t/// @returns a pair of expressions representing _left / _right and _left mod _right, respectively.\n\t/// Uses slack variables and additional constraints to express the results using only operations\n\t/// more friendly to the SMT solver (multiplication, addition, subtraction and comparison).\n\tstd::pair<smtutil::Expression, smtutil::Expression> divModWithSlacks(\n\t\tsmtutil::Expression _left,\n\t\tsmtutil::Expression _right,\n\t\tIntegerType const& _type\n\t);\n\n\t/// Handles the actual assertion of the new value to the encoding context.\n\t/// Other assignment methods should use this one in the end.\n\tvirtual void assignment(smt::SymbolicVariable& _symVar, smtutil::Expression const& _value);\n\n\tvoid assignment(VariableDeclaration const& _variable, Expression const& _value);\n\t/// Handles assignments to variables of different types.\n\tvoid assignment(VariableDeclaration const& _variable, smtutil::Expression const& _value);\n\t/// Handles assignments between generic expressions.\n\t/// Will also be used for assignments of tuple components.\n\tvoid assignment(Expression const& _left, smtutil::Expression const& _right);\n\tvoid assignment(\n\t\tExpression const& _left,\n\t\tsmtutil::Expression const& _right,\n\t\tType const* _type\n\t);\n\t/// Handle assignments between tuples.\n\tvoid tupleAssignment(Expression const& _left, Expression const& _right);\n\t/// Computes the right hand side of a compound assignment.\n\tsmtutil::Expression compoundAssignment(Assignment const& _assignment);\n\t/// Handles assignment of an expression to a tuple of variables.\n\tvoid expressionToTupleAssignment(std::vector<std::shared_ptr<VariableDeclaration>> const& _variables, Expression const& _rhs);\n\n\t/// Maps a variable to an SSA index.\n\tusing VariableIndices = std::unordered_map<VariableDeclaration const*, unsigned>;\n\n\t/// Visits the branch given by the statement, pushes and pops the current path conditions.\n\t/// @param _condition if present, asserts that this condition is true within the branch.\n\t/// @returns the variable indices after visiting the branch and the expression representing\n\t/// the path condition at the end of the branch.\n\tstd::pair<VariableIndices, smtutil::Expression> visitBranch(ASTNode const* _statement, smtutil::Expression const* _condition = nullptr);\n\tstd::pair<VariableIndices, smtutil::Expression> visitBranch(ASTNode const* _statement, smtutil::Expression _condition);\n\n\tusing CallStackEntry = std::pair<CallableDeclaration const*, ASTNode const*>;\n\n\tvoid createStateVariables(ContractDefinition const& _contract);\n\tvoid initializeStateVariables(ContractDefinition const& _contract);\n\tvoid createLocalVariables(FunctionDefinition const& _function);\n\tvoid initializeLocalVariables(FunctionDefinition const& _function);\n\tvoid initializeFunctionCallParameters(CallableDeclaration const& _function, std::vector<smtutil::Expression> const& _callArgs);\n\tvoid resetStateVariables();\n\tvoid resetStorageVariables();\n\tvoid resetMemoryVariables();\n\tvoid resetBalances();\n\t/// Resets all references/pointers that have the same type or have\n\t/// a subexpression of the same type as _varDecl.\n\tvoid resetReferences(VariableDeclaration const& _varDecl);\n\t/// Resets all references/pointers that have type _type.\n\tvoid resetReferences(Type const* _type);\n\t/// @returns the type without storage pointer information if it has it.\n\tType const* typeWithoutPointer(Type const* _type);\n\t/// @returns whether _a or a subtype of _a is the same as _b.\n\tbool sameTypeOrSubtype(Type const* _a, Type const* _b);\n\n\tbool isSupportedType(Type const& _type) const;\n\n\t/// Given the state of the symbolic variables at the end of two different branches,\n\t/// create a merged state using the given branch condition.\n\tvoid mergeVariables(smtutil::Expression const& _condition, VariableIndices const& _indicesEndTrue, VariableIndices const& _indicesEndFalse);\n\t/// Tries to create an uninitialized variable and returns true on success.\n\tbool createVariable(VariableDeclaration const& _varDecl);\n\n\t/// @returns an expression denoting the value of the variable declared in @a _decl\n\t/// at the current point.\n\tsmtutil::Expression currentValue(VariableDeclaration const& _decl) const;\n\t/// @returns an expression denoting the value of the variable declared in @a _decl\n\t/// at the given index. Does not ensure that this index exists.\n\tsmtutil::Expression valueAtIndex(VariableDeclaration const& _decl, unsigned _index) const;\n\t/// Returns the expression corresponding to the AST node.\n\t/// If _targetType is not null apply conversion.\n\t/// Throws if the expression does not exist.\n\tsmtutil::Expression expr(Expression const& _e, Type const* _targetType = nullptr);\n\t/// Creates the expression (value can be arbitrary)\n\tvoid createExpr(Expression const& _e);\n\t/// Creates the expression and sets its value.\n\tvoid defineExpr(Expression const& _e, smtutil::Expression _value);\n\t/// Creates the tuple expression and sets its value.\n\tvoid defineExpr(Expression const& _e, std::vector<std::optional<smtutil::Expression>> const& _values);\n\t/// Overwrites the current path condition\n\tvoid setPathCondition(smtutil::Expression const& _e);\n\t/// Adds a new path condition\n\tvoid pushPathCondition(smtutil::Expression const& _e);\n\t/// Remove the last path condition\n\tvoid popPathCondition();\n\t/// Returns the conjunction of all path conditions or True if empty\n\tsmtutil::Expression currentPathConditions();\n\t/// @returns a human-readable call stack. Used for models.\n\tlangutil::SecondarySourceLocation callStackMessage(std::vector<CallStackEntry> const& _callStack);\n\t/// Copies and pops the last called node.\n\tCallStackEntry popCallStack();\n\t/// Adds (_definition, _node) to the callstack.\n\tvoid pushCallStack(CallStackEntry _entry);\n\t/// Add to the solver: the given expression implied by the current path conditions\n\tvoid addPathImpliedExpression(smtutil::Expression const& _e);\n\n\t/// Copy the SSA indices of m_variables.\n\tVariableIndices copyVariableIndices();\n\t/// Resets the variable indices.\n\tvoid resetVariableIndices(VariableIndices const& _indices);\n\t/// Used when starting a new block.\n\tvirtual void clearIndices(ContractDefinition const* _contract, FunctionDefinition const* _function = nullptr);\n\n\n\t/// @returns variables that are touched in _node's subtree.\n\tstd::set<VariableDeclaration const*> touchedVariables(ASTNode const& _node);\n\n\t/// @returns the declaration referenced by _expr, if any,\n\t/// and nullptr otherwise.\n\tDeclaration const* expressionToDeclaration(Expression const& _expr) const;\n\n\t/// @returns the VariableDeclaration referenced by an Expression or nullptr.\n\tVariableDeclaration const* identifierToVariable(Expression const& _expr) const;\n\n\t/// @returns the MemberAccess <expression>.push if _expr is an empty array push call,\n\t/// otherwise nullptr.\n\tMemberAccess const* isEmptyPush(Expression const& _expr) const;\n\n\t/// @returns true if the given expression is `this`.\n\t/// This means we don't have to abstract away effects of external function calls to this contract.\n\tstatic bool isExternalCallToThis(Expression const* _expr);\n\n\t/// Creates symbolic expressions for the returned values\n\t/// and set them as the components of the symbolic tuple.\n\tvoid createReturnedExpressions(FunctionDefinition const* _funDef, Expression const& _calledExpr);\n\n\t/// @returns the symbolic arguments for a function call,\n\t/// taking into account attached functions and\n\t/// type conversion.\n\tstd::vector<smtutil::Expression> symbolicArguments(\n\t\tstd::vector<ASTPointer<VariableDeclaration>> const& _funParameters,\n\t\tstd::vector<Expression const*> const& _arguments,\n\t\tstd::optional<Expression const*> _calledExpr\n\t);\n\n\tsmtutil::Expression constantExpr(Expression const& _expr, VariableDeclaration const& _var);\n\n\t/// Traverses all source units available collecting free functions\n\t/// and internal library functions in m_freeFunctions.\n\tvoid collectFreeFunctions(std::set<SourceUnit const*, ASTNode::CompareByID> const& _sources);\n\tstd::set<FunctionDefinition const*, ASTNode::CompareByID> const& allFreeFunctions() const { return m_freeFunctions; }\n\t/// Create symbolic variables for the free constants in all @param _sources.\n\tvoid createFreeConstants(std::set<SourceUnit const*, ASTNode::CompareByID> const& _sources);\n\n\t/// Create symbolic variables for all state variables for all contracts in all @param _sources.\n\tvoid createStateVariables(std::set<SourceUnit const*, ASTNode::CompareByID> const& _sources);\n\n\t/// @returns a note to be added to warnings.\n\tstd::string extraComment();\n\n\tstruct VerificationTarget\n\t{\n\t\tVerificationTargetType type;\n\t\tsmtutil::Expression value;\n\t\tsmtutil::Expression constraints;\n\t};\n\n\tbool m_arrayAssignmentHappened = false;\n\n\t/// Stores the instances of an Uninterpreted Function applied to arguments.\n\t/// These may be direct application of UFs or Array index access.\n\t/// Used to retrieve models.\n\tstd::set<Expression const*> m_uninterpretedTerms;\n\tstd::vector<smtutil::Expression> m_pathConditions;\n\n\t/// Whether the currently visited block uses checked\n\t/// or unchecked arithmetic.\n\tbool m_checked = true;\n\n\tlangutil::UniqueErrorReporter& m_errorReporter;\n\tlangutil::UniqueErrorReporter& m_unsupportedErrors;\n\tlangutil::ErrorReporter& m_provedSafeReporter;\n\n\t/// Stores the current function/modifier call/invocation path.\n\tstd::vector<CallStackEntry> m_callStack;\n\n\t/// Stack of scopes.\n\tstd::vector<ScopeOpener const*> m_scopes;\n\n\t/// Returns true if the current function was not visited by\n\t/// a function call.\n\tbool isRootFunction();\n\t/// Returns true if _funDef was already visited.\n\tbool visitedFunction(FunctionDefinition const* _funDef);\n\t/// @returns the contract that contains the current FunctionDefinition that is being visited,\n\t/// or nullptr if the analysis is not inside a FunctionDefinition.\n\tContractDefinition const* currentScopeContract();\n\n\t/// @returns FunctionDefinitions of the given contract (including its constructor and inherited methods),\n\t/// taking into account overriding of the virtual functions.\n\tstd::set<FunctionDefinition const*, ASTNode::CompareByID> const& contractFunctions(ContractDefinition const& _contract);\n\t/// Cache for the method contractFunctions.\n\tstd::map<ContractDefinition const*, std::set<FunctionDefinition const*, ASTNode::CompareByID>> m_contractFunctions;\n\n\t/// @returns FunctionDefinitions of the given contract (including its constructor and methods of bases),\n\t/// without taking into account overriding of the virtual functions.\n\tstd::set<FunctionDefinition const*, ASTNode::CompareByID> const& contractFunctionsWithoutVirtual(ContractDefinition const& _contract);\n\t/// Cache for the method contractFunctionsWithoutVirtual.\n\tstd::map<ContractDefinition const*, std::set<FunctionDefinition const*, ASTNode::CompareByID>> m_contractFunctionsWithoutVirtual;\n\n\t/// Depth of visit to modifiers.\n\t/// When m_modifierDepth == #modifiers the function can be visited\n\t/// when placeholder is visited.\n\t/// Needs to be a stack because of function calls.\n\tstd::vector<int> m_modifierDepthStack;\n\n\tstd::map<ContractDefinition const*, ModifierInvocation const*> m_baseConstructorCalls;\n\n\tContractDefinition const* m_currentContract = nullptr;\n\n\t/// Stores the free functions and internal library functions.\n\t/// Those need to be encoded repeatedly for every analyzed contract.\n\tstd::set<FunctionDefinition const*, ASTNode::CompareByID> m_freeFunctions;\n\n\t/// Stores the context of the encoding.\n\tsmt::EncodingContext& m_context;\n\n\tModelCheckerSettings m_settings;\n\n\t/// Character stream for each source,\n\t/// used for retrieving source text of expressions for e.g. counter-examples.\n\tlangutil::CharStreamProvider const& m_charStreamProvider;\n\n\tsmt::SymbolicState& state();\n\nprivate:\n\tsmtutil::Expression createSelectExpressionForFunction(\n\t\tsmtutil::Expression symbFunction,\n\t\tstd::vector<frontend::ASTPointer<frontend::Expression const>> const& args,\n\t\tfrontend::TypePointers const& inTypes,\n\t\tunsigned long argsActualLength\n\t);\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/SSAVariable.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/SSAVariable.h>\n\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::smt;\n\nSSAVariable::SSAVariable()\n{\n\tresetIndex();\n}\n\nvoid SSAVariable::resetIndex()\n{\n\tm_currentIndex = 0;\n\tm_nextFreeIndex = 1;\n}\n\nvoid SSAVariable::setIndex(unsigned _index)\n{\n\tm_currentIndex = _index;\n\tif (m_nextFreeIndex <= _index)\n\t\tm_nextFreeIndex = _index + 1;\n}\n"
  },
  {
    "path": "libsolidity/formal/SSAVariable.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <memory>\n\nnamespace solidity::frontend::smt\n{\n\n/**\n * This class represents the SSA representation of a program variable.\n */\nclass SSAVariable\n{\npublic:\n\tSSAVariable();\n\t/// Resets index to 0 and next index to 1.\n\tvoid resetIndex();\n\t/// Sets index to _index and only adjusts next if next <= _index.\n\tvoid setIndex(unsigned _index);\n\n\t/// This function returns the current index of this SSA variable.\n\tunsigned index() const { return m_currentIndex; }\n\tunsigned& index() { return m_currentIndex; }\n\n\tunsigned operator++()\n\t{\n\t\treturn m_currentIndex = m_nextFreeIndex++;\n\t}\n\nprivate:\n\tunsigned m_currentIndex;\n\tunsigned m_nextFreeIndex;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/SymbolicState.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/SymbolicState.h>\n\n#include <libsolidity/formal/SymbolicTypes.h>\n#include <libsolidity/formal/EncodingContext.h>\n#include <libsolidity/formal/SMTEncoder.h>\n\n#include <libsmtutil/Sorts.h>\n\n#include <range/v3/view.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::smtutil;\nusing namespace solidity::frontend::smt;\n\nBlockchainVariable::BlockchainVariable(\n\tstd::string _name,\n\tstd::map<std::string, smtutil::SortPointer> _members,\n\tEncodingContext& _context\n):\n\tm_name(std::move(_name)),\n\tm_members(std::move(_members)),\n\tm_context(_context)\n{\n\tstd::vector<std::string> members;\n\tstd::vector<SortPointer> sorts;\n\tfor (auto const& [component, sort]: m_members)\n\t{\n\t\tmembers.emplace_back(component);\n\t\tsorts.emplace_back(sort);\n\t\tm_componentIndices[component] = static_cast<unsigned>(members.size() - 1);\n\t}\n\tm_tuple = std::make_unique<SymbolicTupleVariable>(\n\t\tstd::make_shared<smtutil::TupleSort>(m_name + \"_type\", members, sorts),\n\t\tm_name,\n\t\tm_context\n\t);\n}\n\nsmtutil::Expression BlockchainVariable::member(std::string const& _member) const\n{\n\treturn m_tuple->component(m_componentIndices.at(_member));\n}\n\nsmtutil::Expression BlockchainVariable::assignMember(std::string const& _member, smtutil::Expression const& _value)\n{\n\tsmtutil::Expression newTuple = smt::assignMember(m_tuple->currentValue(), {{_member, _value}});\n\tm_context.addAssertion(m_tuple->increaseIndex() == newTuple);\n\treturn m_tuple->currentValue();\n}\n\nvoid SymbolicState::reset()\n{\n\tm_error.resetIndex();\n\tm_thisAddress.resetIndex();\n\tm_tx.reset();\n\tm_crypto.reset();\n\tif (m_abi)\n\t\tm_abi->reset();\n\t/// We don't reset nor clear these pointers on purpose,\n\t/// since it only helps to keep the already generated types.\n\tif (m_state)\n\t\tm_state->reset();\n}\n\nsmtutil::Expression SymbolicState::balances() const\n{\n\treturn m_state->member(\"balances\");\n}\n\nsmtutil::Expression SymbolicState::balance() const\n{\n\treturn balance(thisAddress());\n}\n\nsmtutil::Expression SymbolicState::balance(smtutil::Expression _address) const\n{\n\treturn smtutil::Expression::select(balances(), std::move(_address));\n}\n\nsmtutil::Expression SymbolicState::blobhash(smtutil::Expression _blobIndex) const\n{\n\treturn smtutil::Expression::select(m_tx.member(\"blobhash\"), std::move(_blobIndex));\n}\n\nsmtutil::Expression SymbolicState::blockhash(smtutil::Expression _blockNumber) const\n{\n\treturn smtutil::Expression::select(m_tx.member(\"blockhash\"), std::move(_blockNumber));\n}\n\nvoid SymbolicState::newBalances()\n{\n\tauto tupleSort = std::dynamic_pointer_cast<TupleSort>(stateSort());\n\tauto balanceSort = tupleSort->components.at(tupleSort->memberToIndex.at(\"balances\"));\n\tSymbolicVariable newBalances(balanceSort, \"fresh_balances_\" + std::to_string(m_context.newUniqueId()), m_context);\n\tm_state->assignMember(\"balances\", newBalances.currentValue());\n}\n\nvoid SymbolicState::transfer(smtutil::Expression _from, smtutil::Expression _to, smtutil::Expression _value)\n{\n\tunsigned indexBefore = m_state->index();\n\taddBalance(_from, 0 - _value);\n\taddBalance(_to, std::move(_value));\n\tunsigned indexAfter = m_state->index();\n\tsolAssert(indexAfter > indexBefore, \"\");\n\tm_state->newVar();\n\t/// Do not apply the transfer operation if _from == _to.\n\tauto newState = smtutil::Expression::ite(\n\t\tstd::move(_from) == std::move(_to),\n\t\tm_state->value(indexBefore),\n\t\tm_state->value(indexAfter)\n\t);\n\tm_context.addAssertion(m_state->value() == newState);\n}\n\nsmtutil::Expression SymbolicState::storage(ContractDefinition const& _contract) const\n{\n\treturn smt::member(m_state->member(\"storage\"), contractStorageKey(_contract));\n}\n\nsmtutil::Expression SymbolicState::storage(ContractDefinition const& _contract, smtutil::Expression _address) const\n{\n\treturn smtutil::Expression::select(storage(_contract), std::move(_address));\n}\n\nsmtutil::Expression SymbolicState::addressActive(smtutil::Expression _address) const\n{\n\treturn smtutil::Expression::select(m_state->member(\"isActive\"), std::move(_address));\n}\n\nvoid SymbolicState::setAddressActive(\n\tsmtutil::Expression _address,\n\tbool _active\n)\n{\n\tm_state->assignMember(\"isActive\", smtutil::Expression::store(\n\t\tm_state->member(\"isActive\"),\n\t\tstd::move(_address),\n\t\tsmtutil::Expression(_active))\n\t);\n}\n\nvoid SymbolicState::newStorage()\n{\n\tauto newStorageVar = SymbolicTupleVariable(\n\t\tm_state->member(\"storage\").sort,\n\t\t\"havoc_storage_\" + std::to_string(m_context.newUniqueId()),\n\t\tm_context\n\t);\n\tm_state->assignMember(\"storage\", newStorageVar.currentValue());\n}\n\nvoid SymbolicState::writeStateVars(ContractDefinition const& _contract, smtutil::Expression _address)\n{\n\tauto stateVars = SMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract);\n\tif (stateVars.empty())\n\t\treturn;\n\n\tstd::map<std::string, smtutil::Expression> values;\n\tfor (auto var: stateVars)\n\t\tvalues.emplace(stateVarStorageKey(*var, _contract), m_context.variable(*var)->currentValue());\n\n\tsmtutil::Expression thisStorage = storage(_contract, _address);\n\tsmtutil::Expression newStorage = smt::assignMember(thisStorage, values);\n\tauto newContractStorage = smtutil::Expression::store(\n\t\tstorage(_contract), std::move(_address), newStorage\n\t);\n\tsmtutil::Expression newAllStorage = smt::assignMember(m_state->member(\"storage\"), {{contractStorageKey(_contract), newContractStorage}});\n\tm_state->assignMember(\"storage\", newAllStorage);\n}\n\nvoid SymbolicState::readStateVars(ContractDefinition const& _contract, smtutil::Expression _address)\n{\n\tauto stateVars = SMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract);\n\tif (stateVars.empty())\n\t\treturn;\n\n\tauto contractStorage = storage(_contract, std::move(_address));\n\tfor (auto var: stateVars)\n\t\tm_context.addAssertion(\n\t\t\tm_context.variable(*var)->increaseIndex() ==\n\t\t\tsmt::member(contractStorage, stateVarStorageKey(*var, _contract))\n\t\t);\n}\n\nvoid SymbolicState::addBalance(smtutil::Expression _address, smtutil::Expression _value)\n{\n\tauto newBalances = smtutil::Expression::store(\n\t\tbalances(),\n\t\t_address,\n\t\tbalance(_address) + std::move(_value)\n\t);\n\tm_state->assignMember(\"balances\", newBalances);\n}\n\nsmtutil::Expression SymbolicState::txMember(std::string const& _member) const\n{\n\treturn m_tx.member(_member);\n}\n\nsmtutil::Expression SymbolicState::evmParisConstraints() const\n{\n\t// Ensure prevrandao range as defined by EIP-4399.\n\treturn txMember(\"block.prevrandao\") > (u256(1) << 64);\n}\n\nsmtutil::Expression SymbolicState::txTypeConstraints() const\n{\n\treturn\n\t\tevmParisConstraints() &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"block.basefee\"), TypeProvider::uint256()) &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"block.blobbasefee\"), TypeProvider::uint256()) &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"block.chainid\"), TypeProvider::uint256()) &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"block.coinbase\"), TypeProvider::address()) &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"block.prevrandao\"), TypeProvider::uint256()) &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"block.gaslimit\"), TypeProvider::uint256()) &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"block.number\"), TypeProvider::uint256()) &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"block.timestamp\"), TypeProvider::uint256()) &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"msg.sender\"), TypeProvider::address()) &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"msg.value\"), TypeProvider::uint256()) &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"tx.origin\"), TypeProvider::address()) &&\n\t\tsmt::symbolicUnknownConstraints(m_tx.member(\"tx.gasprice\"), TypeProvider::uint256());\n}\n\nsmtutil::Expression SymbolicState::txNonPayableConstraint() const\n{\n\treturn m_tx.member(\"msg.value\") == 0;\n}\n\nsmtutil::Expression SymbolicState::txFunctionConstraints(FunctionDefinition const& _function) const\n{\n\tsmtutil::Expression conj = _function.isPayable() ? smtutil::Expression(true) : txNonPayableConstraint();\n\tif (_function.isPartOfExternalInterface())\n\t{\n\t\tauto sig = TypeProvider::function(_function)->externalIdentifier();\n\t\tconj = conj && m_tx.member(\"msg.sig\") == sig;\n\t\tauto b0 = sig >> (3 * 8);\n\t\tauto b1 = (sig & 0x00ff0000) >> (2 * 8);\n\t\tauto b2 = (sig & 0x0000ff00) >> (1 * 8);\n\t\tauto b3 = (sig & 0x000000ff);\n\t\tauto data = smtutil::Expression::tuple_get(m_tx.member(\"msg.data\"), 0);\n\t\tconj = conj && smtutil::Expression::select(data, 0) == b0;\n\t\tconj = conj && smtutil::Expression::select(data, 1) == b1;\n\t\tconj = conj && smtutil::Expression::select(data, 2) == b2;\n\t\tconj = conj && smtutil::Expression::select(data, 3) == b3;\n\t\tauto length = smtutil::Expression::tuple_get(m_tx.member(\"msg.data\"), 1);\n\t\t// TODO add ABI size of function input parameters here \\/\n\t\tconj = conj && length >= 4;\n\t}\n\n\treturn conj;\n}\n\nvoid SymbolicState::prepareForSourceUnit(SourceUnit const& _source, bool _storage)\n{\n\tauto allSources = _source.referencedSourceUnits(true);\n\tallSources.insert(&_source);\n\tstd::set<FunctionCall const*, ASTCompareByID<FunctionCall>> abiCalls;\n\tstd::set<FunctionCall const*, ASTCompareByID<FunctionCall>> bytesConcatCalls;\n\tstd::set<ContractDefinition const*, ASTCompareByID<ContractDefinition>> contracts;\n\tfor (auto const& source: allSources)\n\t{\n\t\tabiCalls += SMTEncoder::collectABICalls(source);\n\t\tbytesConcatCalls += SMTEncoder::collectBytesConcatCalls(source);\n\t\tfor (auto node: source->nodes())\n\t\t\tif (auto contract = dynamic_cast<ContractDefinition const*>(node.get()))\n\t\t\t\tcontracts.insert(contract);\n\t}\n\tbuildState(contracts, _storage);\n\tbuildABIFunctions(abiCalls);\n\tbuildBytesConcatFunctions(bytesConcatCalls);\n}\n\n/// Private helpers.\n\nstd::string SymbolicState::contractSuffix(ContractDefinition const& _contract) const\n{\n\treturn \"_\" + _contract.name() + \"_\" + std::to_string(_contract.id());\n}\n\nstd::string SymbolicState::contractStorageKey(ContractDefinition const& _contract) const\n{\n\treturn \"storage\" + contractSuffix(_contract);\n}\n\nstd::string SymbolicState::stateVarStorageKey(VariableDeclaration const& _var, ContractDefinition const& _contract) const\n{\n\treturn _var.name() + \"_\" + std::to_string(_var.id()) + contractSuffix(_contract);\n}\n\nvoid SymbolicState::buildState(std::set<ContractDefinition const*, ASTCompareByID<ContractDefinition>> const& _contracts, bool _allStorages)\n{\n\tstd::map<std::string, SortPointer> stateMembers{\n\t\t{\"balances\", std::make_shared<smtutil::ArraySort>(smtutil::SortProvider::uintSort, smtutil::SortProvider::uintSort)}\n\t};\n\n\tif (_allStorages)\n\t{\n\t\tstd::vector<std::string> memberNames;\n\t\tstd::vector<SortPointer> memberSorts;\n\t\tfor (auto contract: _contracts)\n\t\t{\n\t\t\tstd::string suffix = contractSuffix(*contract);\n\n\t\t\t// z3 doesn't like empty tuples, so if the contract has 0\n\t\t\t// state vars we can't put it there.\n\t\t\tauto stateVars = SMTEncoder::stateVariablesIncludingInheritedAndPrivate(*contract);\n\t\t\tif (stateVars.empty())\n\t\t\t\tcontinue;\n\n\t\t\tauto names = applyMap(stateVars, [&](auto var) {\n\t\t\t\treturn var->name() + \"_\" + std::to_string(var->id()) + suffix;\n\t\t\t});\n\t\t\tauto sorts = applyMap(stateVars, [](auto var) { return smtSortAbstractFunction(*var->type()); });\n\n\t\t\tstd::string name = \"storage\" + suffix;\n\t\t\tauto storageTuple = std::make_shared<smtutil::TupleSort>(\n\t\t\t\tname + \"_type\", names, sorts\n\t\t\t);\n\n\t\t\tauto storageSort = std::make_shared<smtutil::ArraySort>(\n\t\t\t\tsmtSort(*TypeProvider::address()),\n\t\t\t\tstorageTuple\n\t\t\t);\n\n\t\t\tmemberNames.emplace_back(name);\n\t\t\tmemberSorts.emplace_back(storageSort);\n\t\t}\n\n\t\tstateMembers.emplace(\n\t\t\t\"isActive\",\n\t\t\tstd::make_shared<smtutil::ArraySort>(smtSort(*TypeProvider::address()), smtutil::SortProvider::boolSort)\n\t\t);\n\t\tstateMembers.emplace(\n\t\t\t\"storage\",\n\t\t\tstd::make_shared<smtutil::TupleSort>(\n\t\t\t\t\"storage_type\", memberNames, memberSorts\n\t\t\t)\n\t\t);\n\t}\n\n\tm_state = std::make_unique<BlockchainVariable>(\n\t\t\"state\",\n\t\tstd::move(stateMembers),\n\t\tm_context\n\t);\n}\n\nvoid SymbolicState::buildBytesConcatFunctions(std::set<FunctionCall const*, ASTCompareByID<FunctionCall>> const& _bytesConcatCalls)\n{\n\tstd::map<std::string, SortPointer> functions;\n\n\tfor (auto const* funCall: _bytesConcatCalls)\n\t{\n\t\tauto t = dynamic_cast<FunctionType const*>(funCall->expression().annotation().type);\n\t\tsolAssert(t->kind() == FunctionType::Kind::BytesConcat, \"Expected bytes.concat function\");\n\n\t\tauto const& args = funCall->sortedArguments();\n\n\t\tauto argTypes = [](auto const& _args) {\n\t\t\treturn util::applyMap(_args, [](auto arg) { return arg->annotation().type; });\n\t\t};\n\n\t\t// bytes.concat : (bytes/literal/fixed bytes, ... ) -> bytes\n\t\tstd::vector<frontend::Type const*> inTypes = argTypes(args);\n\n\t\tauto replaceUserDefinedValueTypes = [](auto& _types) {\n\t\t\tfor (auto& t: _types)\n\t\t\t\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(t))\n\t\t\t\t\tt = &userType->underlyingType();\n\t\t};\n\t\tauto replaceStringLiteralTypes = [](auto& _types) {\n\t\t\tfor (auto& t: _types)\n\t\t\t\tif (t->category() == frontend::Type::Category::StringLiteral)\n\t\t\t\t\tt = TypeProvider::bytesMemory();\n\t\t};\n\t\treplaceUserDefinedValueTypes(inTypes);\n\t\treplaceStringLiteralTypes(inTypes);\n\n\t\tauto name = t->richIdentifier();\n\t\tfor (auto paramType: inTypes)\n\t\t\tname += \"_\" + paramType->richIdentifier();\n\n\t\tfrontend::Type const* outType = TypeProvider::bytesMemory();\n\t\tname += \"_\" + outType->richIdentifier();\n\n\t\tm_bytesConcatMembers[funCall] = {name, inTypes, outType};\n\n\t\tif (functions.count(name))\n\t\t\tcontinue;\n\n\t\t/// If there is only one parameter, we use that type directly.\n\t\t/// Otherwise we create a tuple wrapping the necessary types.\n\t\tauto typesToSort = [](auto const& _types, std::string const& _name) -> std::shared_ptr<Sort> {\n\t\t\tif (_types.size() == 1)\n\t\t\t\treturn smtSortAbstractFunction(*_types.front());\n\n\t\t\tstd::vector<std::string> inNames;\n\t\t\tstd::vector<SortPointer> sorts;\n\t\t\tfor (unsigned i = 0; i < _types.size(); ++i)\n\t\t\t{\n\t\t\t\tinNames.emplace_back(_name + \"_input_\" + std::to_string(i));\n\t\t\t\tsorts.emplace_back(smtSortAbstractFunction(*_types.at(i)));\n\t\t\t}\n\t\t\treturn std::make_shared<smtutil::TupleSort>(\n\t\t\t\t_name + \"_input\",\n\t\t\t\tinNames,\n\t\t\t\tsorts\n\t\t\t);\n\t\t};\n\n\t\tauto functionSort = std::make_shared<smtutil::ArraySort>(\n\t\t\ttypesToSort(inTypes, name),\n\t\t\tsmtSortAbstractFunction(*outType)\n\t\t);\n\n\t\tfunctions[name] = functionSort;\n\t}\n\n\tm_bytesConcat = std::make_unique<BlockchainVariable>(\"bytesConcat\", std::move(functions), m_context);\n}\n\nvoid SymbolicState::buildABIFunctions(std::set<FunctionCall const*, ASTCompareByID<FunctionCall>> const& _abiFunctions)\n{\n\tstd::map<std::string, SortPointer> functions;\n\n\tfor (auto const* funCall: _abiFunctions)\n\t{\n\t\tauto t = dynamic_cast<FunctionType const*>(funCall->expression().annotation().type);\n\n\t\tauto const& args = funCall->sortedArguments();\n\t\tauto const& paramTypes = t->parameterTypes();\n\t\tauto const& returnTypes = t->returnParameterTypes();\n\n\t\tauto argTypes = [](auto const& _args) {\n\t\t\treturn util::applyMap(_args, [](auto arg) { return arg->annotation().type; });\n\t\t};\n\n\t\t/// Since each abi.* function may have a different number of input/output parameters,\n\t\t/// we generically compute those types.\n\t\tstd::vector<frontend::Type const*> inTypes;\n\t\tstd::vector<frontend::Type const*> outTypes;\n\t\tif (t->kind() == FunctionType::Kind::ABIDecode)\n\t\t{\n\t\t\t/// abi.decode : (bytes, tuple_of_types(return_types)) -> (return_types)\n\t\t\tsolAssert(args.size() == 2, \"Unexpected number of arguments for abi.decode\");\n\t\t\tinTypes.emplace_back(TypeProvider::bytesMemory());\n\t\t\tauto argType = args.at(1)->annotation().type;\n\t\t\tif (auto const* tupleType = dynamic_cast<TupleType const*>(argType))\n\t\t\t\tfor (auto componentType: tupleType->components())\n\t\t\t\t{\n\t\t\t\t\tauto typeType = dynamic_cast<TypeType const*>(componentType);\n\t\t\t\t\tsolAssert(typeType, \"\");\n\t\t\t\t\toutTypes.emplace_back(typeType->actualType());\n\t\t\t\t}\n\t\t\telse if (auto const* typeType = dynamic_cast<TypeType const*>(argType))\n\t\t\t\toutTypes.emplace_back(typeType->actualType());\n\t\t\telse\n\t\t\t\tsolAssert(false, \"Unexpected argument of abi.decode\");\n\t\t}\n\t\telse if (t->kind() == FunctionType::Kind::ABIEncodeCall)\n\t\t{\n\t\t\t// abi.encodeCall : (functionPointer, tuple_of_args_or_one_non_tuple_arg(arguments)) -> bytes\n\t\t\tsolAssert(args.size() == 2, \"Unexpected number of arguments for abi.encodeCall\");\n\n\t\t\toutTypes.emplace_back(TypeProvider::bytesMemory());\n\t\t\tinTypes.emplace_back(args.at(0)->annotation().type);\n\t\t\tinTypes.emplace_back(args.at(1)->annotation().type);\n\t\t}\n\t\telse\n\t\t{\n\t\t\toutTypes = returnTypes;\n\t\t\tif (\n\t\t\t\tt->kind() == FunctionType::Kind::ABIEncodeWithSelector ||\n\t\t\t\tt->kind() == FunctionType::Kind::ABIEncodeWithSignature\n\t\t\t)\n\t\t\t{\n\t\t\t\t/// abi.encodeWithSelector : (bytes4, one_or_more_types) -> bytes\n\t\t\t\t/// abi.encodeWithSignature : (string, one_or_more_types) -> bytes\n\t\t\t\tinTypes.emplace_back(paramTypes.front());\n\t\t\t\tinTypes += argTypes(std::vector<ASTPointer<Expression const>>(args.begin() + 1, args.end()));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/// abi.encode/abi.encodePacked : one_or_more_types -> bytes\n\t\t\t\tsolAssert(\n\t\t\t\t\tt->kind() == FunctionType::Kind::ABIEncode ||\n\t\t\t\t\tt->kind() == FunctionType::Kind::ABIEncodePacked,\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\t\t\t\tinTypes = argTypes(args);\n\t\t\t}\n\t\t}\n\n\t\t/// Rational numbers and string literals add the concrete values to the type name,\n\t\t/// so we replace them by uint256 and bytes since those are the same as their SMT types.\n\t\t/// TODO we could also replace all types by their ABI type.\n\t\tauto replaceTypes = [](auto& _types) {\n\t\t\tfor (auto& t: _types)\n\t\t\t\tif (t->category() == frontend::Type::Category::RationalNumber)\n\t\t\t\t\tt = TypeProvider::uint256();\n\t\t\t\telse if (t->category() == frontend::Type::Category::StringLiteral)\n\t\t\t\t\tt = TypeProvider::bytesMemory();\n\t\t\t\telse if (auto userType = dynamic_cast<UserDefinedValueType const*>(t))\n\t\t\t\t\tt = &userType->underlyingType();\n\t\t};\n\t\treplaceTypes(inTypes);\n\t\treplaceTypes(outTypes);\n\n\t\tauto name = t->richIdentifier();\n\t\tfor (auto paramType: inTypes + outTypes)\n\t\t\tname += \"_\" + paramType->richIdentifier();\n\n\t\tm_abiMembers[funCall] = {name, inTypes, outTypes};\n\n\t\tif (functions.count(name))\n\t\t\tcontinue;\n\n\t\t/// If there is only one input or output parameter, we use that type directly.\n\t\t/// Otherwise we create a tuple wrapping the necessary input or output types.\n\t\tauto typesToSort = [](auto const& _types, std::string const& _name) -> std::shared_ptr<Sort> {\n\t\t\tif (_types.size() == 1)\n\t\t\t\treturn smtSortAbstractFunction(*_types.front());\n\n\t\t\tstd::vector<std::string> inNames;\n\t\t\tstd::vector<SortPointer> sorts;\n\t\t\tfor (unsigned i = 0; i < _types.size(); ++i)\n\t\t\t{\n\t\t\t\tinNames.emplace_back(_name + \"_input_\" + std::to_string(i));\n\t\t\t\tsorts.emplace_back(smtSortAbstractFunction(*_types.at(i)));\n\t\t\t}\n\t\t\treturn std::make_shared<smtutil::TupleSort>(\n\t\t\t\t_name + \"_input\",\n\t\t\t\tinNames,\n\t\t\t\tsorts\n\t\t\t);\n\t\t};\n\n\t\tauto functionSort = std::make_shared<smtutil::ArraySort>(\n\t\t\ttypesToSort(inTypes, name),\n\t\t\ttypesToSort(outTypes, name)\n\t\t);\n\n\t\tfunctions[name] = functionSort;\n\t}\n\n\tm_abi = std::make_unique<BlockchainVariable>(\"abi\", std::move(functions), m_context);\n}\n\nsmtutil::Expression SymbolicState::abiFunction(frontend::FunctionCall const* _funCall)\n{\n\tsolAssert(m_abi, \"\");\n\treturn m_abi->member(std::get<0>(m_abiMembers.at(_funCall)));\n}\n\nSymbolicState::SymbolicABIFunction const& SymbolicState::abiFunctionTypes(FunctionCall const* _funCall) const\n{\n\treturn m_abiMembers.at(_funCall);\n}\n\nsmtutil::Expression SymbolicState::bytesConcatFunction(frontend::FunctionCall const* _funCall)\n{\n\tsolAssert(m_bytesConcat, \"\");\n\treturn m_bytesConcat->member(std::get<0>(m_bytesConcatMembers.at(_funCall)));\n}\n\nSymbolicState::SymbolicBytesConcatFunction const& SymbolicState::bytesConcatFunctionTypes(FunctionCall const* _funCall) const\n{\n\treturn m_bytesConcatMembers.at(_funCall);\n}\n"
  },
  {
    "path": "libsolidity/formal/SymbolicState.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/formal/SymbolicTypes.h>\n#include <libsolidity/formal/SymbolicVariables.h>\n\n#include <libsmtutil/Sorts.h>\n#include <libsmtutil/SolverInterface.h>\n\nnamespace solidity::frontend::smt\n{\n\nclass EncodingContext;\nclass SymbolicAddressVariable;\nclass SymbolicArrayVariable;\n\nclass BlockchainVariable\n{\npublic:\n\tBlockchainVariable(std::string _name, std::map<std::string, smtutil::SortPointer> _members, EncodingContext& _context);\n\t/// @returns the variable data as a tuple.\n\tsmtutil::Expression value() const { return m_tuple->currentValue(); }\n\tsmtutil::Expression value(unsigned _idx) const { return m_tuple->valueAtIndex(_idx); }\n\tsmtutil::SortPointer const& sort() const { return m_tuple->sort(); }\n\tunsigned index() const { return m_tuple->index(); }\n\tvoid newVar() { m_tuple->increaseIndex(); }\n\tvoid reset() { m_tuple->resetIndex(); }\n\n\t/// @returns the symbolic _member.\n\tsmtutil::Expression member(std::string const& _member) const;\n\t/// Generates a new tuple where _member is assigned _value.\n\tsmtutil::Expression assignMember(std::string const& _member, smtutil::Expression const& _value);\n\nprivate:\n\tstd::string const m_name;\n\tstd::map<std::string, smtutil::SortPointer> const m_members;\n\tEncodingContext& m_context;\n\tstd::map<std::string, unsigned> m_componentIndices;\n\tstd::unique_ptr<SymbolicTupleVariable> m_tuple;\n};\n\n/**\n * Symbolic representation of the blockchain context:\n * - error flag\n * - this (the address of the currently executing contract)\n * - state, represented as a tuple of:\n *   - balances\n *   - array of address => bool representing whether an address is used by a contract\n *   - storage of contracts\n * - block and transaction properties, represented as a tuple of:\n *   - blobhash\n *   - blockhash\n *   - block basefee\n *   - block blobbasefee\n *   - block chainid\n *   - block coinbase\n *   - block gaslimit\n *   - block number\n *   - block prevrandao\n *   - block timestamp\n *   - TODO gasleft\n *   - msg data\n *   - msg sender\n *   - msg sig\n *   - msg value\n *   - tx gasprice\n *   - tx origin\n */\nclass SymbolicState\n{\npublic:\n\tSymbolicState(EncodingContext& _context): m_context(_context) {}\n\n\tvoid reset();\n\n\t/// Error flag.\n\t//@{\n\tSymbolicIntVariable& errorFlag() { return m_error; }\n\tSymbolicIntVariable const& errorFlag() const { return m_error; }\n\tsmtutil::SortPointer const& errorFlagSort() const { return m_error.sort(); }\n\t//@}\n\n\t/// This.\n\t//@{\n\t/// @returns the symbolic value of the currently executing contract's address.\n\tsmtutil::Expression thisAddress() const { return m_thisAddress.currentValue(); }\n\tsmtutil::Expression thisAddress(unsigned _idx) const { return m_thisAddress.valueAtIndex(_idx); }\n\tsmtutil::Expression newThisAddress() { return m_thisAddress.increaseIndex(); }\n\tsmtutil::SortPointer const& thisAddressSort() const { return m_thisAddress.sort(); }\n\t//@}\n\n\t/// Blockchain state.\n\t//@{\n\tsmtutil::Expression state() const { solAssert(m_state, \"\"); return m_state->value(); }\n\tsmtutil::Expression state(unsigned _idx) const { solAssert(m_state, \"\"); return m_state->value(_idx); }\n\tsmtutil::SortPointer const& stateSort() const { solAssert(m_state, \"\"); return m_state->sort(); }\n\tvoid newState() { solAssert(m_state, \"\"); m_state->newVar(); }\n\n\tvoid newBalances();\n\n\t/// Balance.\n\t/// @returns the symbolic balances.\n\tsmtutil::Expression balances() const;\n\t/// @returns the symbolic balance of address `this`.\n\tsmtutil::Expression balance() const;\n\t/// @returns the symbolic balance of an address.\n\tsmtutil::Expression balance(smtutil::Expression _address) const;\n\t/// Transfer _value from _from to _to.\n\tvoid transfer(smtutil::Expression _from, smtutil::Expression _to, smtutil::Expression _value);\n\n\t/// Adds _value to _account's balance.\n\tvoid addBalance(smtutil::Expression _account, smtutil::Expression _value);\n\n\t/// Storage.\n\tsmtutil::Expression storage(ContractDefinition const& _contract) const;\n\tsmtutil::Expression storage(ContractDefinition const& _contract, smtutil::Expression _address) const;\n\tsmtutil::Expression addressActive(smtutil::Expression _address) const;\n\tvoid setAddressActive(smtutil::Expression _address, bool _active);\n\n\tvoid newStorage();\n\tvoid writeStateVars(ContractDefinition const& _contract, smtutil::Expression _address);\n\tvoid readStateVars(ContractDefinition const& _contract, smtutil::Expression _address);\n\t//@}\n\n\t/// Transaction data.\n\t//@{\n\t/// @returns the tx data as a tuple.\n\tsmtutil::Expression tx() const { return m_tx.value(); }\n\tsmtutil::Expression tx(unsigned _idx) const { return m_tx.value(_idx); }\n\tsmtutil::SortPointer const& txSort() const { return m_tx.sort(); }\n\tvoid newTx() { m_tx.newVar(); }\n\tsmtutil::Expression txMember(std::string const& _member) const;\n\tsmtutil::Expression txFunctionConstraints(FunctionDefinition const& _function) const;\n\tsmtutil::Expression txTypeConstraints() const;\n\tsmtutil::Expression txNonPayableConstraint() const;\n\tsmtutil::Expression blobhash(smtutil::Expression _blobIndex) const;\n\tsmtutil::Expression blockhash(smtutil::Expression _blockNumber) const;\n\tsmtutil::Expression evmParisConstraints() const;\n\t//@}\n\n\t/// Crypto functions.\n\t//@{\n\t/// @returns the crypto functions represented as a tuple of arrays.\n\tsmtutil::Expression crypto() const { return m_crypto.value(); }\n\tsmtutil::Expression crypto(unsigned _idx) const { return m_crypto.value(_idx); }\n\tsmtutil::SortPointer const& cryptoSort() const { return m_crypto.sort(); }\n\tvoid newCrypto() { m_crypto.newVar(); }\n\tsmtutil::Expression cryptoFunction(std::string const& _member) const { return m_crypto.member(_member); }\n\t//@}\n\n\t/// Calls the internal methods that build\n\t/// - the symbolic ABI functions based on the abi.* calls\n\t///   in _source and referenced sources.\n\t/// - the symbolic storages for all contracts in _source and\n\t///   referenced sources.\n\tvoid prepareForSourceUnit(SourceUnit const& _source, bool _storage);\n\n\t/// ABI functions.\n\t//@{\n\tsmtutil::Expression abiFunction(FunctionCall const* _funCall);\n\tusing SymbolicABIFunction = std::tuple<\n\t\tstd::string,\n\t\tstd::vector<frontend::Type const*>,\n\t\tstd::vector<frontend::Type const*>\n\t>;\n\tSymbolicABIFunction const& abiFunctionTypes(FunctionCall const* _funCall) const;\n\n\tsmtutil::Expression abi() const { solAssert(m_abi, \"\"); return m_abi->value(); }\n\tsmtutil::Expression abi(unsigned _idx) const { solAssert(m_abi, \"\"); return m_abi->value(_idx); }\n\tsmtutil::SortPointer const& abiSort() const { solAssert(m_abi, \"\"); return m_abi->sort(); }\n\t//@}\n\n\t/// bytes.concat functions.\n\t//@{\n\tsmtutil::Expression bytesConcatFunction(FunctionCall const* _funCall);\n\tusing SymbolicBytesConcatFunction = std::tuple<\n\t\tstd::string,\n\t\tstd::vector<frontend::Type const*>,\n\t\tfrontend::Type const*\n\t>;\n\tSymbolicBytesConcatFunction const& bytesConcatFunctionTypes(FunctionCall const* _funCall) const;\n\tsmtutil::Expression bytesConcat() const { solAssert(m_bytesConcat, \"\"); return m_bytesConcat->value(); }\n\tsmtutil::Expression bytesConcat(unsigned _idx) const { solAssert(m_bytesConcat, \"\"); return m_bytesConcat->value(_idx); }\n\tsmtutil::SortPointer const& bytesConcatSort() const { solAssert(m_bytesConcat, \"\"); return m_bytesConcat->sort(); }\n\tbool hasBytesConcatFunction() const {solAssert(m_bytesConcat, \"\"); return !m_bytesConcatMembers.empty(); }\n\t//@}\n\nprivate:\n\tstd::string contractSuffix(ContractDefinition const& _contract) const;\n\tstd::string contractStorageKey(ContractDefinition const& _contract) const;\n\tstd::string stateVarStorageKey(VariableDeclaration const& _var, ContractDefinition const& _contract) const;\n\n\t/// Builds state.storage based on _contracts.\n\tvoid buildState(std::set<ContractDefinition const*, ASTCompareByID<ContractDefinition>> const& _contracts, bool _allStorages);\n\n\t/// Builds m_abi based on the abi.* calls _abiFunctions.\n\tvoid buildABIFunctions(std::set<FunctionCall const*, ASTCompareByID<FunctionCall>> const& _abiFunctions);\n\n\t/// Builds m_bytesConcat based on the bytes.concat calls\n\tvoid buildBytesConcatFunctions(std::set<FunctionCall const*, ASTCompareByID<FunctionCall>> const& _bytesConcatCalls);\n\n\tEncodingContext& m_context;\n\n\tSymbolicIntVariable m_error{\n\t\tTypeProvider::uint256(),\n\t\tTypeProvider::uint256(),\n\t\t\"error\",\n\t\tm_context\n\t};\n\n\tSymbolicAddressVariable m_thisAddress{\n\t\t\"this\",\n\t\tm_context\n\t};\n\n\t/// m_state is a tuple of\n\t/// - balances: array of address to balance of address.\n\t/// - isActive: array of address to Boolean, where element is true iff address is used.\n\t/// - storage: tuple containing the storage of every contract, where\n\t/// each element of the tuple represents a contract,\n\t/// and is defined by an array where the index is the contract's address\n\t/// and the element is a tuple containing the state variables of that contract.\n\tstd::unique_ptr<BlockchainVariable> m_state;\n\n\tBlockchainVariable m_tx{\"tx\", transactionMemberSorts(), m_context};\n\n\tBlockchainVariable m_crypto{\n\t\t\"crypto\",\n\t\t{\n\t\t\t{\"keccak256\", std::make_shared<smtutil::ArraySort>(\n\t\t\t\tsmt::smtSort(*TypeProvider::bytesStorage()),\n\t\t\t\tsmtSort(*TypeProvider::fixedBytes(32))\n\t\t\t)},\n\t\t\t{\"sha256\", std::make_shared<smtutil::ArraySort>(\n\t\t\t\tsmt::smtSort(*TypeProvider::bytesStorage()),\n\t\t\t\tsmtSort(*TypeProvider::fixedBytes(32))\n\t\t\t)},\n\t\t\t{\"ripemd160\", std::make_shared<smtutil::ArraySort>(\n\t\t\t\tsmt::smtSort(*TypeProvider::bytesStorage()),\n\t\t\t\tsmtSort(*TypeProvider::fixedBytes(20))\n\t\t\t)},\n\t\t\t{\"ecrecover\", std::make_shared<smtutil::ArraySort>(\n\t\t\t\tstd::make_shared<smtutil::TupleSort>(\n\t\t\t\t\t\"ecrecover_input_type\",\n\t\t\t\t\tstd::vector<std::string>{\"hash\", \"v\", \"r\", \"s\"},\n\t\t\t\t\tstd::vector<smtutil::SortPointer>{\n\t\t\t\t\t\tsmt::smtSort(*TypeProvider::fixedBytes(32)),\n\t\t\t\t\t\tsmt::smtSort(*TypeProvider::uint(8)),\n\t\t\t\t\t\tsmt::smtSort(*TypeProvider::fixedBytes(32)),\n\t\t\t\t\t\tsmt::smtSort(*TypeProvider::fixedBytes(32))\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t\tsmtSort(*TypeProvider::address())\n\t\t\t)}\n\t\t},\n\t\tm_context\n\t};\n\n\t/// Tuple containing all used ABI functions.\n\tstd::unique_ptr<BlockchainVariable> m_abi;\n\t/// Maps ABI functions calls to their tuple names generated by\n\t/// `buildABIFunctions`.\n\tstd::map<FunctionCall const*, SymbolicABIFunction> m_abiMembers;\n\n\t/// Tuple containing all used bytes.concat functions.\n\tstd::unique_ptr<BlockchainVariable> m_bytesConcat;\n\t/// Maps bytes.concat functions calls to their tuple names generated by\n\t/// `buildBytesConcatFunctions`.\n\tstd::map<FunctionCall const*, SymbolicBytesConcatFunction> m_bytesConcatMembers;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/SymbolicTypes.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/SymbolicTypes.h>\n\n#include <libsolidity/formal/EncodingContext.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/ast/Types.h>\n#include <libsolutil/CommonData.h>\n#include <memory>\n#include <vector>\n\nusing namespace solidity::util;\nusing namespace solidity::smtutil;\n\n\nnamespace\n{\n\t// HACK to get around Z3 bug in printing type names with spaces (https://github.com/Z3Prover/z3/issues/6850)\n\t// Should be fixed in Z3 4.13.0\n\t// TODO: Remove this afterwards\n\tvoid sanitizeTypeName(std::string& name)\n\t{\n\t\tstd::replace(name.begin(), name.end(), ' ', '_');\n\t\tstd::replace(name.begin(), name.end(), '(', '[');\n\t\tstd::replace(name.begin(), name.end(), ')', ']');\n\t}\n}\n\nnamespace solidity::frontend::smt\n{\n\nSortPointer smtSort(frontend::Type const& _type)\n{\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(&_type))\n\t\treturn smtSort(userType->underlyingType());\n\n\tswitch (smtKind(_type))\n\t{\n\tcase Kind::Int:\n\t\tif (auto const* intType = dynamic_cast<IntegerType const*>(&_type))\n\t\t\treturn SortProvider::intSort(intType->isSigned());\n\t\tif (auto const* fixedType = dynamic_cast<FixedPointType const*>(&_type))\n\t\t\treturn SortProvider::intSort(fixedType->isSigned());\n\t\treturn SortProvider::uintSort;\n\tcase Kind::Bool:\n\t\treturn SortProvider::boolSort;\n\tcase Kind::Function:\n\t{\n\t\tauto fType = dynamic_cast<frontend::FunctionType const*>(&_type);\n\t\tsolAssert(fType, \"\");\n\t\tstd::vector<SortPointer> parameterSorts = smtSort(fType->parameterTypes());\n\t\tauto returnTypes = fType->returnParameterTypes();\n\t\tSortPointer returnSort;\n\t\t// TODO change this when we support tuples.\n\t\tif (returnTypes.size() == 0)\n\t\t\t// We cannot declare functions without a return sort, so we use the smallest.\n\t\t\treturnSort = SortProvider::boolSort;\n\t\telse if (returnTypes.size() > 1)\n\t\t\t// Abstract sort.\n\t\t\treturnSort = SortProvider::uintSort;\n\t\telse\n\t\t\treturnSort = smtSort(*returnTypes.front());\n\t\treturn std::make_shared<FunctionSort>(parameterSorts, returnSort);\n\t}\n\tcase Kind::Array:\n\t{\n\t\tstd::shared_ptr<ArraySort> array;\n\t\tif (isMapping(_type))\n\t\t{\n\t\t\tauto mapType = dynamic_cast<frontend::MappingType const*>(&_type);\n\t\t\tsolAssert(mapType, \"\");\n\t\t\tarray = std::make_shared<ArraySort>(smtSortAbstractFunction(*mapType->keyType()), smtSortAbstractFunction(*mapType->valueType()));\n\t\t}\n\t\telse if (isStringLiteral(_type))\n\t\t{\n\t\t\tauto stringLitType = dynamic_cast<frontend::StringLiteralType const*>(&_type);\n\t\t\tsolAssert(stringLitType, \"\");\n\t\t\tarray = std::make_shared<ArraySort>(SortProvider::uintSort, SortProvider::uintSort);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfrontend::ArrayType const* arrayType = nullptr;\n\t\t\tif (auto const* arr = dynamic_cast<frontend::ArrayType const*>(&_type))\n\t\t\t\tarrayType = arr;\n\t\t\telse if (auto const* slice = dynamic_cast<frontend::ArraySliceType const*>(&_type))\n\t\t\t\tarrayType = &slice->arrayType();\n\t\t\telse\n\t\t\t\tsolAssert(false, \"\");\n\n\t\t\tsolAssert(arrayType, \"\");\n\t\t\tarray = std::make_shared<ArraySort>(SortProvider::uintSort, smtSortAbstractFunction(*arrayType->baseType()));\n\t\t}\n\n\t\tstd::string tupleName;\n\t\tauto sliceArrayType = dynamic_cast<ArraySliceType const*>(&_type);\n\t\tArrayType const* arrayType = sliceArrayType ? &sliceArrayType->arrayType() : dynamic_cast<ArrayType const*>(&_type);\n\t\tif (\n\t\t\t(arrayType && arrayType->isByteArrayOrString()) ||\n\t\t\t_type.category() == frontend::Type::Category::StringLiteral\n\t\t)\n\t\t\ttupleName = \"bytes\";\n\t\telse if (arrayType)\n\t\t{\n\t\t\tauto baseType = arrayType->baseType();\n\t\t\t// Solidity allows implicit conversion also when assigning arrays.\n\t\t\t// So if the base type potentially has a size, that size cannot go\n\t\t\t// in the tuple's name.\n\t\t\tif (auto tupleSort = std::dynamic_pointer_cast<TupleSort>(array->range))\n\t\t\t\ttupleName = tupleSort->name;\n\t\t\telse if (isContract(*baseType))\n\t\t\t\t// use a common sort for contracts so inheriting contracts do not cause conflicting SMT types\n\t\t\t\t// solc handles types mismatch\n\t\t\t\ttupleName = \"contract\";\n\t\t\telse if (isFunction(*baseType))\n\t\t\t\t// use a common sort for functions so pure and view modifier do not cause conflicting SMT types\n\t\t\t\t// solc handles types mismatch\n\t\t\t\ttupleName = \"function\";\n\t\t\telse if (isAddress(*baseType))\n\t\t\t\t// use a common sort for address and address payable so it does not cause conflicting SMT types\n\t\t\t\t// solc handles types mismatch\n\t\t\t\ttupleName = \"address\";\n\t\t\telse if (\n\t\t\t\tbaseType->category() == frontend::Type::Category::Integer ||\n\t\t\t\tbaseType->category() == frontend::Type::Category::FixedPoint\n\t\t\t)\n\t\t\t\ttupleName = \"uint\";\n\t\t\telse if (baseType->category() == frontend::Type::Category::FixedBytes)\n\t\t\t\ttupleName = \"fixedbytes\";\n\t\t\telse\n\t\t\t\ttupleName = arrayType->baseType()->toString(true);\n\n\t\t\ttupleName += \"_array\";\n\t\t}\n\t\telse\n\t\t\ttupleName = _type.toString(true);\n\n\t\tsanitizeTypeName(tupleName);\n\t\ttupleName += \"_tuple\";\n\n\t\treturn std::make_shared<TupleSort>(\n\t\t\ttupleName,\n\t\t\tstd::vector<std::string>{tupleName + \"_accessor_array\", tupleName + \"_accessor_length\"},\n\t\t\tstd::vector<SortPointer>{array, SortProvider::uintSort}\n\t\t);\n\t}\n\tcase Kind::Tuple:\n\t{\n\t\tstd::vector<std::string> members;\n\t\tauto tupleName = _type.toString(true);\n\t\tsanitizeTypeName(tupleName);\n\t\tstd::vector<SortPointer> sorts;\n\n\t\tif (auto const* tupleType = dynamic_cast<frontend::TupleType const*>(&_type))\n\t\t{\n\t\t\tauto const& components = tupleType->components();\n\t\t\tfor (unsigned i = 0; i < components.size(); ++i)\n\t\t\t\tmembers.emplace_back(tupleName + \"_accessor_\" + std::to_string(i));\n\t\t\tsorts = smtSortAbstractFunction(tupleType->components());\n\t\t}\n\t\telse if (auto const* structType = dynamic_cast<frontend::StructType const*>(&_type))\n\t\t{\n\t\t\tsolAssert(!structType->recursive(), \"\");\n\t\t\tauto const& structMembers = structType->structDefinition().members();\n\t\t\tfor (auto member: structMembers)\n\t\t\t\tmembers.emplace_back(tupleName + \"_accessor_\" + member->name());\n\t\t\tsorts = smtSortAbstractFunction(applyMap(\n\t\t\t\tstructMembers,\n\t\t\t\t[](auto var) { return var->type(); }\n\t\t\t));\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"\");\n\n\t\treturn std::make_shared<TupleSort>(tupleName, members, sorts);\n\t}\n\tdefault:\n\t\t// Abstract case.\n\t\treturn SortProvider::uintSort;\n\t}\n}\n\nstd::vector<SortPointer> smtSort(std::vector<frontend::Type const*> const& _types)\n{\n\tstd::vector<SortPointer> sorts;\n\tfor (auto const& type: _types)\n\t\tsorts.push_back(smtSort(*type));\n\treturn sorts;\n}\n\nSortPointer smtSortAbstractFunction(frontend::Type const& _type)\n{\n\tif (isFunction(_type))\n\t\treturn SortProvider::uintSort;\n\treturn smtSort(_type);\n}\n\nstd::vector<SortPointer> smtSortAbstractFunction(std::vector<frontend::Type const*> const& _types)\n{\n\tstd::vector<SortPointer> sorts;\n\tfor (auto const& type: _types)\n\t\tif (type)\n\t\t\tsorts.push_back(smtSortAbstractFunction(*type));\n\t\telse\n\t\t\tsorts.push_back(SortProvider::uintSort);\n\treturn sorts;\n}\n\nKind smtKind(frontend::Type const& _type)\n{\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(&_type))\n\t\treturn smtKind(userType->underlyingType());\n\n\tif (isNumber(_type))\n\t\treturn Kind::Int;\n\telse if (isBool(_type))\n\t\treturn Kind::Bool;\n\telse if (isFunction(_type))\n\t\treturn Kind::Function;\n\telse if (isMapping(_type) || isArray(_type))\n\t\treturn Kind::Array;\n\telse if (isTuple(_type) || isNonRecursiveStruct(_type))\n\t\treturn Kind::Tuple;\n\t// Abstract case.\n\treturn Kind::Int;\n}\n\nbool isSupportedType(frontend::Type const& _type)\n{\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(&_type))\n\t\treturn isSupportedType(userType->underlyingType());\n\n\treturn isNumber(_type) ||\n\t\tisBool(_type) ||\n\t\tisMapping(_type) ||\n\t\tisArray(_type) ||\n\t\tisTuple(_type) ||\n\t\tisNonRecursiveStruct(_type);\n}\n\nbool isSupportedTypeDeclaration(frontend::Type const& _type)\n{\n\treturn isSupportedType(_type) ||\n\t\tisFunction(_type);\n}\n\nstd::pair<bool, std::shared_ptr<SymbolicVariable>> newSymbolicVariable(\n\tfrontend::Type const& _type,\n\tstd::string const& _uniqueName,\n\tEncodingContext& _context\n)\n{\n\tbool abstract = false;\n\tstd::shared_ptr<SymbolicVariable> var;\n\tfrontend::Type const* type = &_type;\n\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(type))\n\t\treturn newSymbolicVariable(userType->underlyingType(), _uniqueName, _context);\n\n\tif (!isSupportedTypeDeclaration(_type))\n\t{\n\t\tabstract = true;\n\t\tvar = std::make_shared<SymbolicIntVariable>(frontend::TypeProvider::uint256(), type, _uniqueName, _context);\n\t}\n\telse if (isBool(_type))\n\t\tvar = std::make_shared<SymbolicBoolVariable>(type, _uniqueName, _context);\n\telse if (isFunction(_type))\n\t{\n\t\tauto const& fType = dynamic_cast<FunctionType const*>(type);\n\t\tauto const& paramsIn = fType->parameterTypes();\n\t\tauto const& paramsOut = fType->returnParameterTypes();\n\t\tauto findFunctionParam = [&](auto&& params) {\n\t\t\treturn find_if(\n\t\t\t\tbegin(params),\n\t\t\t\tend(params),\n\t\t\t\t[&](frontend::Type const* _paramType) { return _paramType->category() == frontend::Type::Category::Function; }\n\t\t\t);\n\t\t};\n\t\tif (\n\t\t\tfindFunctionParam(paramsIn) != end(paramsIn) ||\n\t\t\tfindFunctionParam(paramsOut) != end(paramsOut)\n\t\t)\n\t\t{\n\t\t\tabstract = true;\n\t\t\tvar = std::make_shared<SymbolicIntVariable>(TypeProvider::uint256(), type, _uniqueName, _context);\n\t\t}\n\t\telse\n\t\t\tvar = std::make_shared<SymbolicFunctionVariable>(type, _uniqueName, _context);\n\t}\n\telse if (isInteger(_type))\n\t\tvar = std::make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);\n\telse if (isFixedPoint(_type))\n\t\tvar = std::make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);\n\telse if (isFixedBytes(_type))\n\t{\n\t\tauto fixedBytesType = dynamic_cast<frontend::FixedBytesType const*>(type);\n\t\tsolAssert(fixedBytesType, \"\");\n\t\tvar = std::make_shared<SymbolicFixedBytesVariable>(type, fixedBytesType->numBytes(), _uniqueName, _context);\n\t}\n\telse if (isAddress(_type) || isContract(_type))\n\t\tvar = std::make_shared<SymbolicAddressVariable>(_uniqueName, _context);\n\telse if (isEnum(_type))\n\t\tvar = std::make_shared<SymbolicEnumVariable>(type, _uniqueName, _context);\n\telse if (isRational(_type))\n\t{\n\t\tauto rational = dynamic_cast<frontend::RationalNumberType const*>(&_type);\n\t\tsolAssert(rational, \"\");\n\t\tif (rational->isFractional())\n\t\t\tvar = std::make_shared<SymbolicIntVariable>(frontend::TypeProvider::uint256(), type, _uniqueName, _context);\n\t\telse\n\t\t\tvar = std::make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);\n\t}\n\telse if (isMapping(_type) || isArray(_type))\n\t\tvar = std::make_shared<SymbolicArrayVariable>(type, type, _uniqueName, _context);\n\telse if (isTuple(_type))\n\t\tvar = std::make_shared<SymbolicTupleVariable>(type, _uniqueName, _context);\n\telse if (isStringLiteral(_type))\n\t{\n\t\tauto stringType = TypeProvider::stringMemory();\n\t\tvar = std::make_shared<SymbolicArrayVariable>(stringType, type, _uniqueName, _context);\n\t}\n\telse if (isNonRecursiveStruct(_type))\n\t\tvar = std::make_shared<SymbolicStructVariable>(type, _uniqueName, _context);\n\telse\n\t\tsolAssert(false, \"\");\n\treturn make_pair(abstract, var);\n}\n\nbool isInteger(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::Integer;\n}\n\nbool isFixedPoint(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::FixedPoint;\n}\n\nbool isRational(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::RationalNumber;\n}\n\nbool isFixedBytes(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::FixedBytes;\n}\n\nbool isAddress(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::Address;\n}\n\nbool isContract(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::Contract;\n}\n\nbool isEnum(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::Enum;\n}\n\nbool isNumber(frontend::Type const& _type)\n{\n\treturn isInteger(_type) ||\n\t\tisFixedPoint(_type) ||\n\t\tisRational(_type) ||\n\t\tisFixedBytes(_type) ||\n\t\tisAddress(_type) ||\n\t\tisContract(_type) ||\n\t\tisEnum(_type);\n}\n\nbool isBool(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::Bool;\n}\n\nbool isFunction(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::Function;\n}\n\nbool isMapping(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::Mapping;\n}\n\nbool isArray(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::Array ||\n\t\t_type.category() == frontend::Type::Category::StringLiteral ||\n\t\t_type.category() == frontend::Type::Category::ArraySlice;\n}\n\nbool isTuple(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::Tuple;\n}\n\nbool isStringLiteral(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::StringLiteral;\n}\n\nbool isNonRecursiveStruct(frontend::Type const& _type)\n{\n\tauto structType = dynamic_cast<StructType const*>(&_type);\n\treturn structType && !structType->recursive();\n}\n\nbool isInaccessibleDynamic(frontend::Type const& _type)\n{\n\treturn _type.category() == frontend::Type::Category::InaccessibleDynamic;\n}\n\nsmtutil::Expression minValue(frontend::IntegerType const& _type)\n{\n\treturn smtutil::Expression(_type.minValue());\n}\n\nsmtutil::Expression minValue(frontend::Type const* _type)\n{\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(_type))\n\t\treturn minValue(&userType->underlyingType());\n\n\tsolAssert(isNumber(*_type), \"\");\n\tif (auto const* intType = dynamic_cast<IntegerType const*>(_type))\n\t\treturn intType->minValue();\n\tif (auto const* fixedType = dynamic_cast<FixedPointType const*>(_type))\n\t\treturn fixedType->minIntegerValue();\n\tif (\n\t\tdynamic_cast<AddressType const*>(_type) ||\n\t\tdynamic_cast<ContractType const*>(_type) ||\n\t\tdynamic_cast<EnumType const*>(_type) ||\n\t\tdynamic_cast<FixedBytesType const*>(_type)\n\t)\n\t\treturn 0;\n\tsolAssert(false, \"\");\n}\n\nsmtutil::Expression maxValue(frontend::IntegerType const& _type)\n{\n\treturn smtutil::Expression(_type.maxValue());\n}\n\nsmtutil::Expression maxValue(frontend::Type const* _type)\n{\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(_type))\n\t\treturn maxValue(&userType->underlyingType());\n\n\tsolAssert(isNumber(*_type), \"\");\n\tif (auto const* intType = dynamic_cast<IntegerType const*>(_type))\n\t\treturn intType->maxValue();\n\tif (auto const* fixedType = dynamic_cast<FixedPointType const*>(_type))\n\t\treturn fixedType->maxIntegerValue();\n\tif (\n\t\tdynamic_cast<AddressType const*>(_type) ||\n\t\tdynamic_cast<ContractType const*>(_type)\n\t)\n\t\treturn TypeProvider::uint(160)->maxValue();\n\tif (auto const* enumType = dynamic_cast<EnumType const*>(_type))\n\t\treturn enumType->numberOfMembers() - 1;\n\tif (auto const* bytesType = dynamic_cast<FixedBytesType const*>(_type))\n\t\treturn TypeProvider::uint(bytesType->numBytes() * 8)->maxValue();\n\tsolAssert(false, \"\");\n}\n\nvoid setSymbolicZeroValue(SymbolicVariable const& _variable, EncodingContext& _context)\n{\n\tsetSymbolicZeroValue(_variable.currentValue(), _variable.type(), _context);\n}\n\nvoid setSymbolicZeroValue(smtutil::Expression _expr, frontend::Type const* _type, EncodingContext& _context)\n{\n\tsolAssert(_type, \"\");\n\t_context.addAssertion(_expr == zeroValue(_type));\n}\n\nsmtutil::Expression zeroValue(frontend::Type const* _type)\n{\n\tsolAssert(_type, \"\");\n\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(_type))\n\t\treturn zeroValue(&userType->underlyingType());\n\n\tif (isSupportedType(*_type))\n\t{\n\t\tif (isNumber(*_type))\n\t\t\treturn isSigned(_type) ? smtutil::Expression(s256(0)) : smtutil::Expression(static_cast<size_t>(0));\n\t\tif (isBool(*_type))\n\t\t\treturn smtutil::Expression(false);\n\t\tif (isArray(*_type) || isMapping(*_type))\n\t\t{\n\t\t\tauto tupleSort = std::dynamic_pointer_cast<TupleSort>(smtSort(*_type));\n\t\t\tsolAssert(tupleSort, \"\");\n\t\t\tauto sortSort = std::make_shared<SortSort>(tupleSort->components.front());\n\n\t\t\tstd::optional<smtutil::Expression> zeroArray;\n\t\t\tauto length = bigint(0);\n\t\t\tif (auto arrayType = dynamic_cast<ArrayType const*>(_type))\n\t\t\t{\n\t\t\t\tzeroArray = smtutil::Expression::const_array(smtutil::Expression(sortSort), zeroValue(arrayType->baseType()));\n\t\t\t\tif (!arrayType->isDynamicallySized())\n\t\t\t\t\tlength = bigint(arrayType->length());\n\t\t\t}\n\t\t\telse if (auto mappingType = dynamic_cast<MappingType const*>(_type))\n\t\t\t\tzeroArray = smtutil::Expression::const_array(smtutil::Expression(sortSort), zeroValue(mappingType->valueType()));\n\t\t\telse\n\t\t\t\tsolAssert(false, \"\");\n\n\t\t\tsolAssert(zeroArray, \"\");\n\t\t\treturn smtutil::Expression::tuple_constructor(\n\t\t\t\tsmtutil::Expression(std::make_shared<SortSort>(tupleSort), tupleSort->name),\n\t\t\t\tstd::vector<smtutil::Expression>{*zeroArray, length}\n\t\t\t);\n\n\t\t}\n\t\tif (isNonRecursiveStruct(*_type))\n\t\t{\n\t\t\tauto const* structType = dynamic_cast<StructType const*>(_type);\n\t\t\tauto structSort = std::dynamic_pointer_cast<TupleSort>(smtSort(*_type));\n\t\t\treturn smtutil::Expression::tuple_constructor(\n\t\t\t\tsmtutil::Expression(std::make_shared<SortSort>(structSort), structSort->name),\n\t\t\t\tapplyMap(\n\t\t\t\t\tstructType->structDefinition().members(),\n\t\t\t\t\t[](auto var) { return zeroValue(var->type()); }\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\t\tsolAssert(false, \"\");\n\t}\n\t// Unsupported types are abstracted as Int.\n\treturn 0;\n}\n\nbool isSigned(frontend::Type const* _type)\n{\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(_type))\n\t\treturn isSigned(&userType->underlyingType());\n\n\tsolAssert(smt::isNumber(*_type), \"\");\n\tbool isSigned = false;\n\tif (auto const* numberType = dynamic_cast<RationalNumberType const*>(_type))\n\t\tisSigned |= numberType->isNegative();\n\telse if (auto const* intType = dynamic_cast<IntegerType const*>(_type))\n\t\tisSigned |= intType->isSigned();\n\telse if (auto const* fixedType = dynamic_cast<FixedPointType const*>(_type))\n\t\tisSigned |= fixedType->isSigned();\n\telse if (\n\t\tdynamic_cast<AddressType const*>(_type) ||\n\t\tdynamic_cast<ContractType const*>(_type) ||\n\t\tdynamic_cast<EnumType const*>(_type) ||\n\t\tdynamic_cast<FixedBytesType const*>(_type)\n\t)\n\t\treturn false;\n\telse\n\t\tsolAssert(false, \"\");\n\n\treturn isSigned;\n}\n\nstd::pair<unsigned, bool> typeBvSizeAndSignedness(frontend::Type const* _type)\n{\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(_type))\n\t\treturn typeBvSizeAndSignedness(&userType->underlyingType());\n\n\tif (auto const* intType = dynamic_cast<IntegerType const*>(_type))\n\t\treturn {intType->numBits(), intType->isSigned()};\n\telse if (auto const* fixedType = dynamic_cast<FixedPointType const*>(_type))\n\t\treturn {fixedType->numBits(), fixedType->isSigned()};\n\telse if (auto const* fixedBytesType = dynamic_cast<FixedBytesType const*>(_type))\n\t\treturn {fixedBytesType->numBytes() * 8, false};\n\telse\n\t\tsolAssert(false, \"\");\n}\n\nvoid setSymbolicUnknownValue(SymbolicVariable const& _variable, EncodingContext& _context)\n{\n\tsetSymbolicUnknownValue(_variable.currentValue(), _variable.type(), _context);\n}\n\nvoid setSymbolicUnknownValue(smtutil::Expression _expr, frontend::Type const* _type, EncodingContext& _context)\n{\n\t_context.addAssertion(symbolicUnknownConstraints(_expr, _type));\n}\n\nsmtutil::Expression symbolicUnknownConstraints(smtutil::Expression _expr, frontend::Type const* _type)\n{\n\tsolAssert(_type, \"\");\n\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(_type))\n\t\treturn symbolicUnknownConstraints(std::move(_expr), &userType->underlyingType());\n\n\tif (isEnum(*_type) || isInteger(*_type) || isAddress(*_type) || isFixedBytes(*_type))\n\t\treturn _expr >= minValue(_type) && _expr <= maxValue(_type);\n\telse if (\n\t\tauto arrayType = dynamic_cast<ArrayType const*>(_type);\n\t\tarrayType && !arrayType->isDynamicallySized()\n\t)\n\t\treturn smtutil::Expression::tuple_get(_expr, 1) == arrayType->length();\n\telse if (isArray(*_type) || isMapping(*_type))\n\t\t/// Length cannot be negative.\n\t\treturn smtutil::Expression::tuple_get(_expr, 1) >= 0;\n\n\treturn smtutil::Expression(true);\n}\n\nstd::optional<smtutil::Expression> symbolicTypeConversion(frontend::Type const* _from, frontend::Type const* _to)\n{\n\tif (auto userType = dynamic_cast<UserDefinedValueType const*>(_to))\n\t\treturn symbolicTypeConversion(_from, &userType->underlyingType());\n\n\tif (_to && _from)\n\t\t// StringLiterals are encoded as SMT arrays in the generic case,\n\t\t// but they can also be compared/assigned to fixed bytes, in which\n\t\t// case they'd need to be encoded as numbers.\n\t\tif (auto strType = dynamic_cast<StringLiteralType const*>(_from))\n\t\t\tif (auto fixedBytesType = dynamic_cast<FixedBytesType const*>(_to))\n\t\t\t{\n\t\t\t\tif (strType->value().empty())\n\t\t\t\t\treturn smtutil::Expression(size_t(0));\n\t\t\t\tauto bytesVec = util::asBytes(strType->value());\n\t\t\t\tbytesVec.resize(fixedBytesType->numBytes(), 0);\n\t\t\t\treturn smtutil::Expression(u256(util::toHex(bytesVec, util::HexPrefix::Add)));\n\t\t\t}\n\n\treturn std::nullopt;\n}\n\nsmtutil::Expression member(smtutil::Expression const& _tuple, std::string const& _member)\n{\n\tTupleSort const& _sort = dynamic_cast<TupleSort const&>(*_tuple.sort);\n\treturn smtutil::Expression::tuple_get(\n\t\t_tuple,\n\t\t_sort.memberToIndex.at(_member)\n\t);\n}\n\nsmtutil::Expression assignMember(smtutil::Expression const _tuple, std::map<std::string, smtutil::Expression> const& _values)\n{\n\tTupleSort const& _sort = dynamic_cast<TupleSort const&>(*_tuple.sort);\n\tstd::vector<smtutil::Expression> args;\n\tfor (auto const& m: _sort.members)\n\t\tif (auto* value = util::valueOrNullptr(_values, m))\n\t\t\targs.emplace_back(*value);\n\t\telse\n\t\t\targs.emplace_back(member(_tuple, m));\n\tauto sortExpr = smtutil::Expression(std::make_shared<smtutil::SortSort>(_tuple.sort), _tuple.name);\n\treturn smtutil::Expression::tuple_constructor(sortExpr, args);\n}\n\nstd::map<std::string, frontend::Type const*> transactionMemberTypes()\n{\n\t// TODO: gasleft\n\treturn {\n\t\t{\"block.basefee\", TypeProvider::uint256()},\n\t\t{\"block.blobbasefee\", TypeProvider::uint256()},\n\t\t{\"block.chainid\", TypeProvider::uint256()},\n\t\t{\"block.coinbase\", TypeProvider::address()},\n\t\t{\"block.prevrandao\", TypeProvider::uint256()},\n\t\t{\"block.gaslimit\", TypeProvider::uint256()},\n\t\t{\"block.number\", TypeProvider::uint256()},\n\t\t{\"block.timestamp\", TypeProvider::uint256()},\n\t\t{\"blobhash\", TypeProvider::array(DataLocation::Memory, TypeProvider::uint256())},\n\t\t{\"blockhash\", TypeProvider::array(DataLocation::Memory, TypeProvider::uint256())},\n\t\t{\"msg.data\", TypeProvider::bytesCalldata()},\n\t\t{\"msg.sender\", TypeProvider::address()},\n\t\t{\"msg.sig\", TypeProvider::fixedBytes(4)},\n\t\t{\"msg.value\", TypeProvider::uint256()},\n\t\t{\"tx.gasprice\", TypeProvider::uint256()},\n\t\t{\"tx.origin\", TypeProvider::address()}\n\t};\n}\n\nstd::map<std::string, SortPointer> transactionMemberSorts()\n{\n\t// NOTE: `blockhash` and `blobhash` need proper `ArraySort`, `smtSort()` wraps array types into array+length pair\n\tauto toSort = [&](auto const& entry) -> SortPointer\n\t{\n\t\tif (entry.first == \"blockhash\" || entry.first == \"blobhash\")\n\t\t\treturn std::make_shared<ArraySort>(SortProvider::uintSort, SortProvider::uintSort);\n\t\treturn smtSort(*entry.second);\n\t};\n\tauto types = transactionMemberTypes();\n\treturn types\n\t| ranges::views::transform([&](auto const& entry) { return std::make_pair(entry.first, toSort(entry)); })\n\t| ranges::to<std::map<std::string, SortPointer>>();\n}\n}\n"
  },
  {
    "path": "libsolidity/formal/SymbolicTypes.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/formal/SymbolicVariables.h>\n#include <libsolidity/ast/Types.h>\n\nnamespace solidity::frontend::smt\n{\n\nclass EncodingContext;\n\n/// Returns the SMT sort that models the Solidity type _type.\nsmtutil::SortPointer smtSort(frontend::Type const& _type);\nstd::vector<smtutil::SortPointer> smtSort(std::vector<frontend::Type const*> const& _types);\n/// If _type has type Function, abstract it to Integer.\n/// Otherwise return smtSort(_type).\nsmtutil::SortPointer smtSortAbstractFunction(frontend::Type const& _type);\nstd::vector<smtutil::SortPointer> smtSortAbstractFunction(std::vector<frontend::Type const*> const& _types);\n/// Returns the SMT kind that models the Solidity type type category _category.\nsmtutil::Kind smtKind(frontend::Type const& _type);\n\n/// Returns true if type is fully supported (declaration and operations).\nbool isSupportedType(frontend::Type const& _type);\nbool isSupportedType(frontend::Type const& _type);\n/// Returns true if type is partially supported (declaration).\nbool isSupportedTypeDeclaration(frontend::Type const& _type);\nbool isSupportedTypeDeclaration(frontend::Type const& _type);\n\nbool isInteger(frontend::Type const& _type);\nbool isFixedPoint(frontend::Type const& _type);\nbool isRational(frontend::Type const& _type);\nbool isFixedBytes(frontend::Type const& _type);\nbool isAddress(frontend::Type const& _type);\nbool isContract(frontend::Type const& _type);\nbool isEnum(frontend::Type const& _type);\nbool isNumber(frontend::Type const& _type);\nbool isBool(frontend::Type const& _type);\nbool isFunction(frontend::Type const& _type);\nbool isMapping(frontend::Type const& _type);\nbool isArray(frontend::Type const& _type);\nbool isTuple(frontend::Type const& _type);\nbool isStringLiteral(frontend::Type const& _type);\nbool isNonRecursiveStruct(frontend::Type const& _type);\nbool isInaccessibleDynamic(frontend::Type const& _type);\n\n/// Returns a new symbolic variable, according to _type.\n/// Also returns whether the type is abstract or not,\n/// which is true for unsupported types.\nstd::pair<bool, std::shared_ptr<SymbolicVariable>> newSymbolicVariable(frontend::Type const& _type, std::string const& _uniqueName, EncodingContext& _context);\n\nsmtutil::Expression minValue(frontend::IntegerType const& _type);\nsmtutil::Expression minValue(frontend::Type const* _type);\nsmtutil::Expression maxValue(frontend::IntegerType const& _type);\nsmtutil::Expression maxValue(frontend::Type const* _type);\nsmtutil::Expression zeroValue(frontend::Type const* _type);\nbool isSigned(frontend::Type const* _type);\n\nstd::pair<unsigned, bool> typeBvSizeAndSignedness(frontend::Type const* type);\n\nvoid setSymbolicZeroValue(SymbolicVariable const& _variable, EncodingContext& _context);\nvoid setSymbolicZeroValue(smtutil::Expression _expr, frontend::Type const* _type, EncodingContext& _context);\nvoid setSymbolicUnknownValue(SymbolicVariable const& _variable, EncodingContext& _context);\nvoid setSymbolicUnknownValue(smtutil::Expression _expr, frontend::Type const* _type, EncodingContext& _context);\nsmtutil::Expression symbolicUnknownConstraints(smtutil::Expression _expr, frontend::Type const* _type);\n\nstd::optional<smtutil::Expression> symbolicTypeConversion(frontend::Type const* _from, frontend::Type const* _to);\n\nsmtutil::Expression member(smtutil::Expression const& _tuple, std::string const& _member);\nsmtutil::Expression assignMember(smtutil::Expression const _tuple, std::map<std::string, smtutil::Expression> const& _values);\n\nstd::map<std::string, frontend::Type const*> transactionMemberTypes();\nstd::map<std::string, smtutil::SortPointer> transactionMemberSorts();\n}\n"
  },
  {
    "path": "libsolidity/formal/SymbolicVariables.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/SymbolicVariables.h>\n\n#include <libsolidity/ast/AST.h>\n\n#include <libsolidity/formal/EncodingContext.h>\n#include <libsolidity/formal/SymbolicTypes.h>\n\n#include <libsolutil/Algorithms.h>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::smtutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::smt;\n\nSymbolicVariable::SymbolicVariable(\n\tfrontend::Type const* _type,\n\tfrontend::Type const* _originalType,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tm_type(_type),\n\tm_originalType(_originalType),\n\tm_uniqueName(std::move(_uniqueName)),\n\tm_context(_context),\n\tm_ssa(std::make_unique<SSAVariable>())\n{\n\tsolAssert(m_type, \"\");\n\tm_sort = smtSort(*m_type);\n\tsolAssert(m_sort, \"\");\n}\n\nSymbolicVariable::SymbolicVariable(\n\tSortPointer _sort,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tm_sort(std::move(_sort)),\n\tm_uniqueName(std::move(_uniqueName)),\n\tm_context(_context),\n\tm_ssa(std::make_unique<SSAVariable>())\n{\n\tsolAssert(m_sort, \"\");\n}\n\nsmtutil::Expression SymbolicVariable::currentValue(frontend::Type const*) const\n{\n\treturn valueAtIndex(m_ssa->index());\n}\n\nstd::string SymbolicVariable::currentName() const\n{\n\treturn uniqueSymbol(m_ssa->index());\n}\n\nsmtutil::Expression SymbolicVariable::valueAtIndex(unsigned _index) const\n{\n\treturn m_context.newVariable(uniqueSymbol(_index), m_sort);\n}\n\nstd::string SymbolicVariable::nameAtIndex(unsigned _index) const\n{\n\treturn uniqueSymbol(_index);\n}\n\nstd::string SymbolicVariable::uniqueSymbol(unsigned _index) const\n{\n\treturn m_uniqueName + \"_\" + std::to_string(_index);\n}\n\nsmtutil::Expression SymbolicVariable::resetIndex()\n{\n\tm_ssa->resetIndex();\n\treturn currentValue();\n}\n\nsmtutil::Expression SymbolicVariable::setIndex(unsigned _index)\n{\n\tm_ssa->setIndex(_index);\n\treturn currentValue();\n}\n\nsmtutil::Expression SymbolicVariable::increaseIndex()\n{\n\t++(*m_ssa);\n\treturn currentValue();\n}\n\nSymbolicBoolVariable::SymbolicBoolVariable(\n\tfrontend::Type const* _type,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicVariable(_type, _type, std::move(_uniqueName), _context)\n{\n\tsolAssert(m_type->category() == frontend::Type::Category::Bool, \"\");\n}\n\nSymbolicIntVariable::SymbolicIntVariable(\n\tfrontend::Type const* _type,\n\tfrontend::Type const* _originalType,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicVariable(_type, _originalType, std::move(_uniqueName), _context)\n{\n\tsolAssert(isNumber(*m_type), \"\");\n}\n\nSymbolicAddressVariable::SymbolicAddressVariable(\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicIntVariable(TypeProvider::uint(160), TypeProvider::uint(160), std::move(_uniqueName), _context)\n{\n}\n\nSymbolicFixedBytesVariable::SymbolicFixedBytesVariable(\n\tfrontend::Type const* _originalType,\n\tunsigned _numBytes,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicIntVariable(TypeProvider::uint(_numBytes * 8), _originalType, std::move(_uniqueName), _context)\n{\n}\n\nSymbolicFunctionVariable::SymbolicFunctionVariable(\n\tfrontend::Type const* _type,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicVariable(_type, _type, std::move(_uniqueName), _context),\n\tm_declaration(m_context.newVariable(currentName(), m_sort))\n{\n\tsolAssert(m_type->category() == frontend::Type::Category::Function, \"\");\n}\n\nSymbolicFunctionVariable::SymbolicFunctionVariable(\n\tSortPointer _sort,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicVariable(std::move(_sort), std::move(_uniqueName), _context),\n\tm_declaration(m_context.newVariable(currentName(), m_sort))\n{\n\tsolAssert(m_sort->kind == Kind::Function, \"\");\n}\n\nsmtutil::Expression SymbolicFunctionVariable::currentValue(frontend::Type const* _targetType) const\n{\n\treturn m_abstract.currentValue(_targetType);\n}\n\nsmtutil::Expression SymbolicFunctionVariable::currentFunctionValue() const\n{\n\treturn m_declaration;\n}\n\nsmtutil::Expression SymbolicFunctionVariable::valueAtIndex(unsigned _index) const\n{\n\treturn m_abstract.valueAtIndex(_index);\n}\n\nsmtutil::Expression SymbolicFunctionVariable::functionValueAtIndex(unsigned _index) const\n{\n\treturn SymbolicVariable::valueAtIndex(_index);\n}\n\nsmtutil::Expression SymbolicFunctionVariable::resetIndex()\n{\n\tSymbolicVariable::resetIndex();\n\treturn m_abstract.resetIndex();\n}\n\nsmtutil::Expression SymbolicFunctionVariable::setIndex(unsigned _index)\n{\n\tSymbolicVariable::setIndex(_index);\n\treturn m_abstract.setIndex(_index);\n}\n\nsmtutil::Expression SymbolicFunctionVariable::increaseIndex()\n{\n\t++(*m_ssa);\n\tresetDeclaration();\n\tm_abstract.increaseIndex();\n\treturn m_abstract.currentValue();\n}\n\nsmtutil::Expression SymbolicFunctionVariable::operator()(std::vector<smtutil::Expression> const& _arguments) const\n{\n\treturn m_declaration(_arguments);\n}\n\nvoid SymbolicFunctionVariable::resetDeclaration()\n{\n\tm_declaration = m_context.newVariable(currentName(), m_sort);\n}\n\nSymbolicEnumVariable::SymbolicEnumVariable(\n\tfrontend::Type const* _type,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicVariable(_type, _type, std::move(_uniqueName), _context)\n{\n\tsolAssert(isEnum(*m_type), \"\");\n}\n\nSymbolicTupleVariable::SymbolicTupleVariable(\n\tfrontend::Type const* _type,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicVariable(_type, _type, std::move(_uniqueName), _context)\n{\n\tsolAssert(isTuple(*m_type), \"\");\n}\n\nSymbolicTupleVariable::SymbolicTupleVariable(\n\tSortPointer _sort,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicVariable(std::move(_sort), std::move(_uniqueName), _context)\n{\n\tsolAssert(m_sort->kind == Kind::Tuple, \"\");\n}\n\nsmtutil::Expression SymbolicTupleVariable::currentValue(frontend::Type const* _targetType) const\n{\n\tif (!_targetType || sort() == smtSort(*_targetType))\n\t\treturn SymbolicVariable::currentValue();\n\n\tauto thisTuple = std::dynamic_pointer_cast<TupleSort>(sort());\n\tauto otherTuple = std::dynamic_pointer_cast<TupleSort>(smtSort(*_targetType));\n\tsolAssert(thisTuple && otherTuple, \"\");\n\tsolAssert(thisTuple->components.size() == otherTuple->components.size(), \"\");\n\tstd::vector<smtutil::Expression> args;\n\tfor (size_t i = 0; i < thisTuple->components.size(); ++i)\n\t\targs.emplace_back(component(i, type(), _targetType));\n\treturn smtutil::Expression::tuple_constructor(\n\t\tsmtutil::Expression(std::make_shared<smtutil::SortSort>(smtSort(*_targetType)), \"\"),\n\t\targs\n\t);\n}\n\nstd::vector<SortPointer> const& SymbolicTupleVariable::components() const\n{\n\tauto tupleSort = std::dynamic_pointer_cast<TupleSort>(m_sort);\n\tsolAssert(tupleSort, \"\");\n\treturn tupleSort->components;\n}\n\nsmtutil::Expression SymbolicTupleVariable::component(\n\tsize_t _index,\n\tfrontend::Type const* _fromType,\n\tfrontend::Type const* _toType\n) const\n{\n\tstd::optional<smtutil::Expression> conversion = symbolicTypeConversion(_fromType, _toType);\n\tif (conversion)\n\t\treturn *conversion;\n\n\treturn smtutil::Expression::tuple_get(currentValue(), _index);\n}\n\nSymbolicArrayVariable::SymbolicArrayVariable(\n\tfrontend::Type const* _type,\n\tfrontend::Type const* _originalType,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicVariable(_type, _originalType, std::move(_uniqueName), _context),\n\tm_pair(\n\t\tsmtSort(*_type),\n\t\tm_uniqueName + \"_length_pair\",\n\t\tm_context\n\t)\n{\n\tsolAssert(isArray(*m_type) || isMapping(*m_type), \"\");\n}\n\nSymbolicArrayVariable::SymbolicArrayVariable(\n\tSortPointer _sort,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicVariable(std::move(_sort), std::move(_uniqueName), _context),\n\tm_pair(\n\t\tstd::make_shared<TupleSort>(\n\t\t\t\"array_length_pair\",\n\t\t\tstd::vector<std::string>{\"array\", \"length\"},\n\t\t\tstd::vector<SortPointer>{m_sort, SortProvider::uintSort}\n\t\t),\n\t\tm_uniqueName + \"_array_length_pair\",\n\t\tm_context\n\t)\n{\n\tsolAssert(m_sort->kind == Kind::Array, \"\");\n}\n\nsmtutil::Expression SymbolicArrayVariable::currentValue(frontend::Type const* _targetType) const\n{\n\tstd::optional<smtutil::Expression> conversion = symbolicTypeConversion(m_originalType, _targetType);\n\tif (conversion)\n\t\treturn *conversion;\n\n\treturn m_pair.currentValue();\n}\n\nsmtutil::Expression SymbolicArrayVariable::valueAtIndex(unsigned _index) const\n{\n\treturn m_pair.valueAtIndex(_index);\n}\n\nsmtutil::Expression SymbolicArrayVariable::elements() const\n{\n\treturn m_pair.component(0);\n}\n\nsmtutil::Expression SymbolicArrayVariable::length() const\n{\n\treturn m_pair.component(1);\n}\n\nSymbolicStructVariable::SymbolicStructVariable(\n\tfrontend::Type const* _type,\n\tstd::string _uniqueName,\n\tEncodingContext& _context\n):\n\tSymbolicVariable(_type, _type, std::move(_uniqueName), _context)\n{\n\tsolAssert(isNonRecursiveStruct(*m_type), \"\");\n\tauto const* structType = dynamic_cast<StructType const*>(_type);\n\tsolAssert(structType, \"\");\n\tauto const& members = structType->structDefinition().members();\n\tfor (unsigned i = 0; i < members.size(); ++i)\n\t{\n\t\tsolAssert(members.at(i), \"\");\n\t\tm_memberIndices.emplace(members.at(i)->name(), i);\n\t}\n}\n\nsmtutil::Expression SymbolicStructVariable::member(std::string const& _member) const\n{\n\treturn smtutil::Expression::tuple_get(currentValue(), m_memberIndices.at(_member));\n}\n\nsmtutil::Expression SymbolicStructVariable::assignMember(std::string const& _member, smtutil::Expression const& _memberValue)\n{\n\tauto const* structType = dynamic_cast<StructType const*>(m_type);\n\tsolAssert(structType, \"\");\n\tauto const& structDef = structType->structDefinition();\n\tauto const& structMembers = structDef.members();\n\tauto oldMembers = applyMap(\n\t\tstructMembers,\n\t\t[&](auto _member) { return member(_member->name()); }\n\t);\n\tincreaseIndex();\n\tfor (unsigned i = 0; i < structMembers.size(); ++i)\n\t{\n\t\tauto const& memberName = structMembers.at(i)->name();\n\t\tauto newMember = memberName == _member ? _memberValue : oldMembers.at(i);\n\t\tm_context.addAssertion(member(memberName) == newMember);\n\t}\n\n\treturn currentValue();\n}\n\nsmtutil::Expression SymbolicStructVariable::assignAllMembers(std::vector<smtutil::Expression> const& _memberValues)\n{\n\tauto structType = dynamic_cast<StructType const*>(m_type);\n\tsolAssert(structType, \"\");\n\n\tauto const& structDef = structType->structDefinition();\n\tauto const& structMembers = structDef.members();\n\tsolAssert(_memberValues.size() == structMembers.size(), \"\");\n\tincreaseIndex();\n\tfor (unsigned i = 0; i < _memberValues.size(); ++i)\n\t\tm_context.addAssertion(_memberValues[i] == member(structMembers[i]->name()));\n\n\treturn currentValue();\n}\n"
  },
  {
    "path": "libsolidity/formal/SymbolicVariables.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolidity/formal/SSAVariable.h>\n#include <libsolidity/ast/Types.h>\n#include <libsolidity/ast/TypeProvider.h>\n\n#include <libsmtutil/SolverInterface.h>\n\n#include <map>\n#include <memory>\n\nnamespace solidity::frontend::smt\n{\n\nclass EncodingContext;\nclass Type;\n\n/**\n * This abstract class represents the symbolic version of a program variable.\n */\nclass SymbolicVariable\n{\npublic:\n\tSymbolicVariable(\n\t\tfrontend::Type const* _type,\n\t\tfrontend::Type const* _originalType,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n\tSymbolicVariable(\n\t\tsmtutil::SortPointer _sort,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n\n\tSymbolicVariable(SymbolicVariable&&) = default;\n\n\tvirtual ~SymbolicVariable() = default;\n\n\tvirtual smtutil::Expression currentValue(frontend::Type const* _targetType = nullptr) const;\n\tstd::string currentName() const;\n\tvirtual smtutil::Expression valueAtIndex(unsigned _index) const;\n\tvirtual std::string nameAtIndex(unsigned _index) const;\n\tvirtual smtutil::Expression resetIndex();\n\tvirtual smtutil::Expression setIndex(unsigned _index);\n\tvirtual smtutil::Expression increaseIndex();\n\tvirtual smtutil::Expression operator()(std::vector<smtutil::Expression> const& /*_arguments*/) const\n\t{\n\t\tsolAssert(false, \"Function application to non-function.\");\n\t}\n\n\tunsigned index() const { return m_ssa->index(); }\n\tunsigned& index() { return m_ssa->index(); }\n\n\tsmtutil::SortPointer const& sort() const { return m_sort; }\n\tfrontend::Type const* type() const { return m_type; }\n\tfrontend::Type const* originalType() const { return m_originalType; }\n\nprotected:\n\tstd::string uniqueSymbol(unsigned _index) const;\n\n\t/// SMT sort.\n\tsmtutil::SortPointer m_sort;\n\t/// Solidity type, used for size and range in number types.\n\tfrontend::Type const* m_type;\n\t/// Solidity original type, used for type conversion if necessary.\n\tfrontend::Type const* m_originalType;\n\tstd::string m_uniqueName;\n\tEncodingContext& m_context;\n\tstd::unique_ptr<SSAVariable> m_ssa;\n};\n\n/**\n * Specialization of SymbolicVariable for Bool\n */\nclass SymbolicBoolVariable: public SymbolicVariable\n{\npublic:\n\tSymbolicBoolVariable(\n\t\tfrontend::Type const* _type,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n};\n\n/**\n * Specialization of SymbolicVariable for Integers\n */\nclass SymbolicIntVariable: public SymbolicVariable\n{\npublic:\n\tSymbolicIntVariable(\n\t\tfrontend::Type const* _type,\n\t\tfrontend::Type const* _originalType,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n};\n\n/**\n * Specialization of SymbolicVariable for Address\n */\nclass SymbolicAddressVariable: public SymbolicIntVariable\n{\npublic:\n\tSymbolicAddressVariable(\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n};\n\n/**\n * Specialization of SymbolicVariable for FixedBytes\n */\nclass SymbolicFixedBytesVariable: public SymbolicIntVariable\n{\npublic:\n\tSymbolicFixedBytesVariable(\n\t\tfrontend::Type const* _originalType,\n\t\tunsigned _numBytes,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n};\n\n/**\n * Specialization of SymbolicVariable for FunctionType.\n * Besides containing a symbolic function declaration,\n * it also has an integer used as abstraction.\n * By default, the abstract representation is used when\n * values are requested, and the function declaration is\n * used when operator() is applied over arguments.\n */\nclass SymbolicFunctionVariable: public SymbolicVariable\n{\npublic:\n\tSymbolicFunctionVariable(\n\t\tfrontend::Type const* _type,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n\tSymbolicFunctionVariable(\n\t\tsmtutil::SortPointer _sort,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n\n\tsmtutil::Expression currentValue(frontend::Type const* _targetType = nullptr) const override;\n\n\t// Explicit request the function declaration.\n\tsmtutil::Expression currentFunctionValue() const;\n\n\tsmtutil::Expression valueAtIndex(unsigned _index) const override;\n\n\t// Explicit request the function declaration.\n\tsmtutil::Expression functionValueAtIndex(unsigned _index) const;\n\n\tsmtutil::Expression resetIndex() override;\n\tsmtutil::Expression setIndex(unsigned _index) override;\n\tsmtutil::Expression increaseIndex() override;\n\n\tsmtutil::Expression operator()(std::vector<smtutil::Expression> const& _arguments) const override;\n\nprivate:\n\t/// Creates a new function declaration.\n\tvoid resetDeclaration();\n\n\t/// Stores the current function declaration.\n\tsmtutil::Expression m_declaration;\n\n\t/// Abstract representation.\n\tSymbolicIntVariable m_abstract{\n\t\tTypeProvider::uint256(),\n\t\tTypeProvider::uint256(),\n\t\tm_uniqueName + \"_abstract\",\n\t\tm_context\n\t};\n};\n\n/**\n * Specialization of SymbolicVariable for Enum\n */\nclass SymbolicEnumVariable: public SymbolicVariable\n{\npublic:\n\tSymbolicEnumVariable(\n\t\tfrontend::Type const* _type,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n};\n\n/**\n * Specialization of SymbolicVariable for Tuple\n */\nclass SymbolicTupleVariable: public SymbolicVariable\n{\npublic:\n\tSymbolicTupleVariable(\n\t\tfrontend::Type const* _type,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n\tSymbolicTupleVariable(\n\t\tsmtutil::SortPointer _sort,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n\n\tsmtutil::Expression currentValue(frontend::Type const* _targetType = nullptr) const override;\n\n\tstd::vector<smtutil::SortPointer> const& components() const;\n\tsmtutil::Expression component(\n\t\tsize_t _index,\n\t\tfrontend::Type const* _fromType = nullptr,\n\t\tfrontend::Type const* _toType = nullptr\n\t) const;\n};\n\n/**\n * Specialization of SymbolicVariable for Array\n */\nclass SymbolicArrayVariable: public SymbolicVariable\n{\npublic:\n\tSymbolicArrayVariable(\n\t\tfrontend::Type const* _type,\n\t\tfrontend::Type const* _originalTtype,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n\tSymbolicArrayVariable(\n\t\tsmtutil::SortPointer _sort,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n\n\tSymbolicArrayVariable(SymbolicArrayVariable&&) = default;\n\n\tsmtutil::Expression currentValue(frontend::Type const* _targetType = nullptr) const override;\n\tsmtutil::Expression valueAtIndex(unsigned _index) const override;\n\tsmtutil::Expression resetIndex() override { SymbolicVariable::resetIndex(); return m_pair.resetIndex(); }\n\tsmtutil::Expression setIndex(unsigned _index) override { SymbolicVariable::setIndex(_index); return m_pair.setIndex(_index); }\n\tsmtutil::Expression increaseIndex() override { SymbolicVariable::increaseIndex(); return m_pair.increaseIndex(); }\n\tsmtutil::Expression elements() const;\n\tsmtutil::Expression length() const;\n\n\tsmtutil::SortPointer tupleSort() { return m_pair.sort(); }\n\nprivate:\n\tSymbolicTupleVariable m_pair;\n};\n\n/**\n * Specialization of SymbolicVariable for Struct.\n */\nclass SymbolicStructVariable: public SymbolicVariable\n{\npublic:\n\tSymbolicStructVariable(\n\t\tfrontend::Type const* _type,\n\t\tstd::string _uniqueName,\n\t\tEncodingContext& _context\n\t);\n\n\t/// @returns the symbolic expression representing _member.\n\tsmtutil::Expression member(std::string const& _member) const;\n\n\t/// @returns the symbolic expression representing this struct\n\t/// with field _member updated.\n\tsmtutil::Expression assignMember(std::string const& _member, smtutil::Expression const& _memberValue);\n\n\t/// @returns the symbolic expression representing this struct\n\t/// with all fields updated with the given values.\n\tsmtutil::Expression assignAllMembers(std::vector<smtutil::Expression> const& _memberValues);\n\nprivate:\n\tstd::map<std::string, unsigned> m_memberIndices;\n};\n\n\n\n}\n"
  },
  {
    "path": "libsolidity/formal/Z3CHCSmtLib2Interface.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/Z3CHCSmtLib2Interface.h>\n\n#include <libsolidity/interface/UniversalCallback.h>\n\n#include <libsmtutil/SMTLib2Parser.h>\n\n#include <boost/algorithm/string/predicate.hpp>\n\n#include <stack>\n\n#ifdef EMSCRIPTEN_BUILD\n#include <z3++.h>\n#endif\n\nusing namespace solidity::frontend::smt;\nusing namespace solidity::smtutil;\n\nZ3CHCSmtLib2Interface::Z3CHCSmtLib2Interface(\n\tfrontend::ReadCallback::Callback _smtCallback,\n\tstd::optional<unsigned int> _queryTimeout,\n\tbool _computeInvariants\n): CHCSmtLib2Interface({}, std::move(_smtCallback), _queryTimeout), m_computeInvariants(_computeInvariants)\n{\n#ifdef EMSCRIPTEN_BUILD\n\tconstexpr int resourceLimit = 2000000;\n\tif (m_queryTimeout)\n\t\tz3::set_param(\"timeout\", int(*m_queryTimeout));\n\telse\n\t\tz3::set_param(\"rlimit\", resourceLimit);\n\tz3::set_param(\"rewriter.pull_cheap_ite\", true);\n\tz3::set_param(\"fp.spacer.q3.use_qgen\", true);\n\tz3::set_param(\"fp.spacer.mbqi\", false);\n\tz3::set_param(\"fp.spacer.ground_pobs\", false);\n#endif\n}\n\nvoid Z3CHCSmtLib2Interface::setupSmtCallback(bool _enablePreprocessing)\n{\n\tif (auto* universalCallback = m_smtCallback.target<frontend::UniversalCallback>())\n\t\tuniversalCallback->smtCommand().setZ3(m_queryTimeout, _enablePreprocessing, m_computeInvariants);\n}\n\nCHCSolverInterface::QueryResult Z3CHCSmtLib2Interface::query(smtutil::Expression const& _block)\n{\n\tsetupSmtCallback(true);\n\tstd::string query = dumpQuery(_block);\n\ttry\n\t{\n#ifdef EMSCRIPTEN_BUILD\n\t\tz3::set_param(\"fp.xform.slice\", true);\n\t\tz3::set_param(\"fp.xform.inline_linear\", true);\n\t\tz3::set_param(\"fp.xform.inline_eager\", true);\n\t\tstd::string response = Z3_eval_smtlib2_string(z3::context{}, query.c_str());\n#else\n\t\tstd::string response = querySolver(query);\n#endif\n\t\t// NOTE: Our internal semantics is UNSAT -> SAFE and SAT -> UNSAFE, which corresponds to usual SMT-based model checking\n\t\t// However, with CHC solvers, the meaning is flipped, UNSAT -> UNSAFE and SAT -> SAFE.\n\t\t// So we have to flip the answer.\n\t\tif (boost::starts_with(response, \"unsat\"))\n\t\t{\n\t\t\t// Repeat the query with preprocessing disabled, to get the full proof\n\t\t\tsetupSmtCallback(false);\n\t\t\tquery = \"(set-option :produce-proofs true)\" + query + \"\\n(get-proof)\";\n#ifdef EMSCRIPTEN_BUILD\n\t\t\tz3::set_param(\"fp.xform.slice\", false);\n\t\t\tz3::set_param(\"fp.xform.inline_linear\", false);\n\t\t\tz3::set_param(\"fp.xform.inline_eager\", false);\n\t\t\tresponse = Z3_eval_smtlib2_string(z3::context{}, query.c_str());\n#else\n\t\t\tresponse = querySolver(query);\n#endif\n\t\t\tsetupSmtCallback(true);\n\t\t\tif (!boost::starts_with(response, \"unsat\"))\n\t\t\t\treturn {CheckResult::SATISFIABLE, {}, {}};\n\t\t\treturn {CheckResult::SATISFIABLE, {}, graphFromZ3Answer(response)};\n\t\t}\n\n\t\tCheckResult result;\n\t\tif (boost::starts_with(response, \"sat\"))\n\t\t\treturn {CheckResult::UNSATISFIABLE, invariantsFromSolverResponse(response), {}};\n\t\tif (boost::starts_with(response, \"unknown\"))\n\t\t\tresult = CheckResult::UNKNOWN;\n\t\telse\n\t\t\tresult = CheckResult::ERROR;\n\n\t\treturn {result, {}, {}};\n\t}\n\tcatch(smtutil::SMTSolverInteractionError const&)\n\t{\n\t\treturn {CheckResult::ERROR, {}, {}};\n\t}\n}\n\n\nCHCSolverInterface::CexGraph Z3CHCSmtLib2Interface::graphFromZ3Answer(std::string const& _proof) const\n{\n\tstd::stringstream ss(_proof);\n\tstd::string answer;\n\tss >> answer;\n\tsmtSolverInteractionRequire(answer == \"unsat\", \"Proof must follow an unsat answer\");\n\n\tSMTLib2Parser parser(ss);\n\tif (parser.isEOF()) // No proof from Z3\n\t\treturn {};\n\t// For some reason Z3 outputs everything as a single s-expression\n\tSMTLib2Expression parsedOutput;\n\ttry\n\t{\n\t\tparsedOutput = parser.parseExpression();\n\t}\n\tcatch (SMTLib2Parser::ParsingException&)\n\t{\n\t\tsmtSolverInteractionRequire(false, \"Error during parsing Z3's proof\");\n\t}\n\tsmtSolverInteractionRequire(parser.isEOF(), \"Error during parsing Z3's proof\");\n\tsmtSolverInteractionRequire(!isAtom(parsedOutput), \"Encountered unexpected format of Z3's proof\");\n\tauto& commands = asSubExpressions(parsedOutput);\n\tScopedParser expressionParser(m_context);\n\tfor (auto& command: commands)\n\t{\n\t\tif (isAtom(command))\n\t\t\tcontinue;\n\n\t\tauto const& args = asSubExpressions(command);\n\t\tsmtSolverInteractionRequire(args.size() > 0, \"Encountered unexpected format of Z3's proof\");\n\t\tauto const& head = args[0];\n\t\tif (!isAtom(head))\n\t\t\tcontinue;\n\n\t\t// Z3 can introduce new helper predicates to be used in the proof\n\t\t// e.g., \"(declare-fun query!0 (Bool Bool Bool Int Int Bool Bool Bool Bool Bool Bool Bool Int) Bool)\"\n\t\tif (asAtom(head) == \"declare-fun\")\n\t\t{\n\t\t\tsmtSolverInteractionRequire(args.size() == 4, \"Encountered unexpected format of Z3's proof\");\n\t\t\tauto const& name = args[1];\n\t\t\tauto const& domainSorts = args[2];\n\t\t\tauto const& codomainSort = args[3];\n\t\t\tsmtSolverInteractionRequire(isAtom(name), \"Encountered unexpected format of Z3's proof\");\n\t\t\tsmtSolverInteractionRequire(!isAtom(domainSorts), \"Encountered unexpected format of Z3's proof\");\n\t\t\texpressionParser.addVariableDeclaration(asAtom(name), expressionParser.toSort(codomainSort));\n\t\t}\n\t\t// The subexpression starting with \"proof\" contains the whole proof, which we need to transform to our internal\n\t\t// representation\n\t\telse if (asAtom(head) == \"proof\")\n\t\t{\n\t\t\tinlineLetExpressions(command);\n\t\t\treturn graphFromSMTLib2Expression(command, expressionParser);\n\t\t}\n\t}\n\treturn {};\n}\n\nCHCSolverInterface::CexGraph Z3CHCSmtLib2Interface::graphFromSMTLib2Expression(\n\tSMTLib2Expression const& _proof,\n\tScopedParser& _context\n)\n{\n\tauto fact = [](SMTLib2Expression const& _node) -> SMTLib2Expression const& {\n\t\tif (isAtom(_node))\n\t\t\treturn _node;\n\t\tsmtSolverInteractionRequire(!asSubExpressions(_node).empty(), \"Encountered unexpected format of Z3's proof\");\n\t\treturn asSubExpressions(_node).back();\n\t};\n\tsmtSolverInteractionRequire(!isAtom(_proof), \"Encountered unexpected format of Z3's proof\");\n\tauto const& proofArgs = asSubExpressions(_proof);\n\tsmtSolverInteractionRequire(proofArgs.size() == 2, \"Encountered unexpected format of Z3's proof\");\n\tsmtSolverInteractionRequire(isAtom(proofArgs.at(0)) && asAtom(proofArgs.at(0)) == \"proof\", \"Encountered unexpected format of Z3's proof\");\n\tauto const& proofNode = proofArgs.at(1);\n\tauto const& derivedFact = fact(proofNode);\n\tif (isAtom(proofNode) || !isAtom(derivedFact) || asAtom(derivedFact) != \"false\")\n\t\treturn {};\n\n\tCHCSolverInterface::CexGraph graph;\n\n\tstd::stack<SMTLib2Expression const*> proofStack;\n\tproofStack.push(&asSubExpressions(proofNode).at(1));\n\n\tstd::map<SMTLib2Expression const*, unsigned> visitedIds;\n\tunsigned nextId = 0;\n\n\tauto const* root = proofStack.top();\n\tauto const& derivedRootFact = fact(*root);\n\tvisitedIds.emplace(root, nextId++);\n\tgraph.nodes.emplace(visitedIds.at(root), _context.toSMTUtilExpression(derivedRootFact));\n\n\tauto isHyperRes = [](SMTLib2Expression const& expr) {\n\t\tif (isAtom(expr)) return false;\n\t\tauto const& subExprs = asSubExpressions(expr);\n\t\tsmtSolverInteractionRequire(!subExprs.empty(), \"Encountered unexpected format of Z3's proof\");\n\t\tauto const& op = subExprs.at(0);\n\t\tif (isAtom(op)) return false;\n\t\tauto const& opExprs = asSubExpressions(op);\n\t\tif (opExprs.size() < 2) return false;\n\t\tauto const& ruleName = opExprs.at(1);\n\t\treturn isAtom(ruleName) && asAtom(ruleName) == \"hyper-res\";\n\t};\n\n\twhile (!proofStack.empty())\n\t{\n\t\tauto const* currentNode = proofStack.top();\n\t\tsmtSolverInteractionRequire(visitedIds.find(currentNode) != visitedIds.end(), \"Error in processing Z3's proof\");\n\t\tauto id = visitedIds.at(currentNode);\n\t\tsmtSolverInteractionRequire(graph.nodes.count(id), \"Error in processing Z3's proof\");\n\t\tproofStack.pop();\n\n\t\tif (isHyperRes(*currentNode))\n\t\t{\n\t\t\tauto const& args = asSubExpressions(*currentNode);\n\t\t\tsmtSolverInteractionRequire(args.size() > 1, \"Unexpected format of hyper-resolution rule in Z3's proof\");\n\t\t\t// args[0] is the name of the rule\n\t\t\t// args[1] is the clause used\n\t\t\t// last argument is the derived fact\n\t\t\t// the arguments in the middle are the facts where we need to recurse\n\t\t\tfor (unsigned i = 2; i < args.size() - 1; ++i)\n\t\t\t{\n\t\t\t\tauto const* child = &args[i];\n\t\t\t\tif (!visitedIds.count(child))\n\t\t\t\t{\n\t\t\t\t\tvisitedIds.emplace(child, nextId++);\n\t\t\t\t\tproofStack.push(child);\n\t\t\t\t}\n\n\t\t\t\tauto childId = visitedIds.at(child);\n\t\t\t\tif (!graph.nodes.count(childId))\n\t\t\t\t{\n\t\t\t\t\tgraph.nodes.emplace(childId, _context.toSMTUtilExpression(fact(*child)));\n\t\t\t\t\tgraph.edges[childId] = {};\n\t\t\t\t}\n\n\t\t\t\tgraph.edges[id].push_back(childId);\n\t\t\t}\n\t\t}\n\t}\n\treturn graph;\n}\n\n"
  },
  {
    "path": "libsolidity/formal/Z3CHCSmtLib2Interface.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/CHCSmtLib2Interface.h>\n\nnamespace solidity::frontend::smt\n{\n\nclass Z3CHCSmtLib2Interface: public smtutil::CHCSmtLib2Interface\n{\npublic:\n\tZ3CHCSmtLib2Interface(\n\t\tfrontend::ReadCallback::Callback _smtCallback,\n\t\tstd::optional<unsigned int> _queryTimeout,\n\t\tbool _computeInvariants\n\t);\n\nprivate:\n\tvoid setupSmtCallback(bool _disablePreprocessing);\n\n\tCHCSolverInterface::QueryResult query(smtutil::Expression const& _expr) override;\n\n\tCHCSolverInterface::CexGraph graphFromZ3Answer(std::string const& _proof) const;\n\n\tstatic CHCSolverInterface::CexGraph graphFromSMTLib2Expression(\n\t\tsmtutil::SMTLib2Expression const& _proof,\n\t\tScopedParser& _context\n\t);\n\n\tbool m_computeInvariants;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/formal/Z3SMTLib2Interface.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/formal/Z3SMTLib2Interface.h>\n\n#include <libsolidity/interface/UniversalCallback.h>\n\n#ifdef EMSCRIPTEN_BUILD\n#include <z3++.h>\n#endif\n\nusing namespace solidity::frontend::smt;\n\nZ3SMTLib2Interface::Z3SMTLib2Interface(\n\tfrontend::ReadCallback::Callback _smtCallback,\n\tstd::optional<unsigned int> _queryTimeout\n): SMTLib2Interface({}, std::move(_smtCallback), _queryTimeout)\n{\n#ifdef EMSCRIPTEN_BUILD\n\tconstexpr int resourceLimit = 2000000;\n\tif (m_queryTimeout)\n\t\tz3::set_param(\"timeout\", int(*m_queryTimeout));\n\telse\n\t\tz3::set_param(\"rlimit\", resourceLimit);\n\tz3::set_param(\"rewriter.pull_cheap_ite\", true);\n\tz3::set_param(\"fp.spacer.q3.use_qgen\", true);\n\tz3::set_param(\"fp.spacer.mbqi\", false);\n\tz3::set_param(\"fp.spacer.ground_pobs\", false);\n#endif\n}\n\nvoid Z3SMTLib2Interface::setupSmtCallback() {\n\tif (auto* universalCallback = m_smtCallback.target<frontend::UniversalCallback>())\n\t\tuniversalCallback->smtCommand().setZ3(m_queryTimeout, true, false);\n}\n\nstd::string Z3SMTLib2Interface::querySolver(std::string const& _query)\n{\n#ifdef EMSCRIPTEN_BUILD\n\tz3::context context;\n\treturn Z3_eval_smtlib2_string(context, _query.c_str());\n#else\n\treturn SMTLib2Interface::querySolver(_query);\n#endif\n}\n"
  },
  {
    "path": "libsolidity/formal/Z3SMTLib2Interface.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsmtutil/SMTLib2Interface.h>\n\nnamespace solidity::frontend::smt\n{\n\nclass Z3SMTLib2Interface: public smtutil::SMTLib2Interface\n{\npublic:\n\texplicit Z3SMTLib2Interface(\n\t\tfrontend::ReadCallback::Callback _smtCallback = {},\n\t\tstd::optional<unsigned> _queryTimeout = {}\n\t);\nprivate:\n\tvoid setupSmtCallback() override;\n\tstd::string querySolver(std::string const& _query) override;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/ABI.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Utilities to handle the Contract ABI (https://docs.soliditylang.org/en/develop/abi-spec.html)\n */\n\n#include <libsolidity/interface/ABI.h>\n\n#include <libsolidity/ast/AST.h>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\n\nnamespace\n{\nbool anyDataStoredInStorage(TypePointers const& _pointers)\n{\n\tfor (Type const* pointer: _pointers)\n\t\tif (pointer->dataStoredIn(DataLocation::Storage))\n\t\t\treturn true;\n\n\treturn false;\n}\n}\n\nJson ABI::generate(ContractDefinition const& _contractDef)\n{\n\tauto compare = [](Json const& _a, Json const& _b) -> bool\n\t{\n\t\treturn std::make_tuple(_a.value(\"type\", Json()), _a.value(\"name\", Json())) <\n\t\t\t\t\tstd::make_tuple(_b.value(\"type\", Json()), _b.value(\"name\", Json()));\n\t};\n\tstd::multiset<Json, decltype(compare)> abi(compare);\n\n\tfor (auto it: _contractDef.interfaceFunctions())\n\t{\n\t\tif (_contractDef.isLibrary() && (\n\t\t\tit.second->stateMutability() > StateMutability::View ||\n\t\t\tanyDataStoredInStorage(it.second->parameterTypes() + it.second->returnParameterTypes())\n\t\t))\n\t\t\tcontinue;\n\n\t\tFunctionType const* externalFunctionType = it.second->interfaceFunctionType();\n\t\tsolAssert(!!externalFunctionType, \"\");\n\t\tJson method;\n\t\tmethod[\"type\"] = \"function\";\n\t\tmethod[\"name\"] = it.second->declaration().name();\n\t\tmethod[\"stateMutability\"] = stateMutabilityToString(externalFunctionType->stateMutability());\n\t\tmethod[\"inputs\"] = formatTypeList(\n\t\t\texternalFunctionType->parameterNames(),\n\t\t\texternalFunctionType->parameterTypes(),\n\t\t\tit.second->parameterTypes(),\n\t\t\t_contractDef.isLibrary()\n\t\t);\n\t\tmethod[\"outputs\"] = formatTypeList(\n\t\t\texternalFunctionType->returnParameterNames(),\n\t\t\texternalFunctionType->returnParameterTypes(),\n\t\t\tit.second->returnParameterTypes(),\n\t\t\t_contractDef.isLibrary()\n\t\t);\n\t\tabi.emplace(std::move(method));\n\t}\n\tFunctionDefinition const* constructor = _contractDef.constructor();\n\tif (constructor && !_contractDef.abstract())\n\t{\n\t\tFunctionType constrType(*constructor);\n\t\tFunctionType const* externalFunctionType = constrType.interfaceFunctionType();\n\t\tsolAssert(!!externalFunctionType, \"\");\n\t\tJson method;\n\t\tmethod[\"type\"] = \"constructor\";\n\t\tmethod[\"stateMutability\"] = stateMutabilityToString(externalFunctionType->stateMutability());\n\t\tmethod[\"inputs\"] = formatTypeList(\n\t\t\texternalFunctionType->parameterNames(),\n\t\t\texternalFunctionType->parameterTypes(),\n\t\t\tconstrType.parameterTypes(),\n\t\t\t_contractDef.isLibrary()\n\t\t);\n\t\tabi.emplace(std::move(method));\n\t}\n\tfor (auto const* fallbackOrReceive: {_contractDef.fallbackFunction(), _contractDef.receiveFunction()})\n\t\tif (fallbackOrReceive)\n\t\t{\n\t\t\tauto const* externalFunctionType = FunctionType(*fallbackOrReceive).interfaceFunctionType();\n\t\t\tsolAssert(!!externalFunctionType, \"\");\n\t\t\tJson method;\n\t\t\tmethod[\"type\"] = TokenTraits::toString(fallbackOrReceive->kind());\n\t\t\tmethod[\"stateMutability\"] = stateMutabilityToString(externalFunctionType->stateMutability());\n\t\t\tabi.emplace(std::move(method));\n\t\t}\n\tfor (auto const& it: _contractDef.interfaceEvents())\n\t{\n\t\tJson event;\n\t\tevent[\"type\"] = \"event\";\n\t\tevent[\"name\"] = it->name();\n\t\tevent[\"anonymous\"] = it->isAnonymous();\n\t\tJson params = Json::array();\n\t\tfor (auto const& p: it->parameters())\n\t\t{\n\t\t\tType const* type = p->annotation().type->interfaceType(false);\n\t\t\tsolAssert(type, \"\");\n\t\t\tauto param = formatType(p->name(), *type, *p->annotation().type, false);\n\t\t\tparam[\"indexed\"] = p->isIndexed();\n\t\t\tparams.emplace_back(param);\n\t\t}\n\t\tevent[\"inputs\"] = std::move(params);\n\t\tabi.emplace(std::move(event));\n\t}\n\n\tfor (ErrorDefinition const* error: _contractDef.interfaceErrors())\n\t{\n\t\tJson errorJson;\n\t\terrorJson[\"type\"] = \"error\";\n\t\terrorJson[\"name\"] = error->name();\n\t\terrorJson[\"inputs\"] = Json::array();\n\t\tfor (auto const& p: error->parameters())\n\t\t{\n\t\t\tType const* type = p->annotation().type->interfaceType(false);\n\t\t\tsolAssert(type, \"\");\n\t\t\terrorJson[\"inputs\"].emplace_back(\n\t\t\t\tformatType(p->name(), *type, *p->annotation().type, false)\n\t\t\t);\n\t\t}\n\t\tabi.emplace(std::move(errorJson));\n\t}\n\n\tJson abiJson = Json::array();\n\tfor (auto& f: abi)\n\t\tabiJson.emplace_back(std::move(f));\n\treturn abiJson;\n}\n\nJson ABI::formatTypeList(\n\tstd::vector<std::string> const& _names,\n\tstd::vector<Type const*> const& _encodingTypes,\n\tstd::vector<Type const*> const& _solidityTypes,\n\tbool _forLibrary\n)\n{\n\tJson params = Json::array();\n\tsolAssert(_names.size() == _encodingTypes.size(), \"Names and types vector size does not match\");\n\tsolAssert(_names.size() == _solidityTypes.size(), \"\");\n\tfor (unsigned i = 0; i < _names.size(); ++i)\n\t{\n\t\tsolAssert(_encodingTypes[i], \"\");\n\t\tparams.emplace_back(formatType(_names[i], *_encodingTypes[i], *_solidityTypes[i], _forLibrary));\n\t}\n\treturn params;\n}\n\nJson ABI::formatType(\n\tstd::string const& _name,\n\tType const& _encodingType,\n\tType const& _solidityType,\n\tbool _forLibrary\n)\n{\n\tJson ret;\n\tret[\"name\"] = _name;\n\tret[\"internalType\"] = _solidityType.toString(true);\n\tstd::string suffix = (_forLibrary && _encodingType.dataStoredIn(DataLocation::Storage)) ? \" storage\" : \"\";\n\tif (_encodingType.isValueType() || (_forLibrary && _encodingType.dataStoredIn(DataLocation::Storage)))\n\t\tret[\"type\"] = _encodingType.canonicalName() + suffix;\n\telse if (ArrayType const* arrayType = dynamic_cast<ArrayType const*>(&_encodingType))\n\t{\n\t\tif (arrayType->isByteArrayOrString())\n\t\t\tret[\"type\"] = _encodingType.canonicalName() + suffix;\n\t\telse\n\t\t{\n\t\t\tstd::string suffix;\n\t\t\tif (arrayType->isDynamicallySized())\n\t\t\t\tsuffix = \"[]\";\n\t\t\telse\n\t\t\t\tsuffix = std::string(\"[\") + arrayType->length().str() + \"]\";\n\t\t\tsolAssert(arrayType->baseType(), \"\");\n\t\t\tJson subtype = formatType(\n\t\t\t\t\"\",\n\t\t\t\t*arrayType->baseType(),\n\t\t\t\t*dynamic_cast<ArrayType const&>(_solidityType).baseType(),\n\t\t\t\t_forLibrary\n\t\t\t);\n\t\t\tif (subtype.contains(\"components\"))\n\t\t\t{\n\t\t\t\tret[\"type\"] = subtype[\"type\"].get<std::string>() + suffix;\n\t\t\t\tret[\"components\"] = subtype[\"components\"];\n\t\t\t}\n\t\t\telse\n\t\t\t\tret[\"type\"] = subtype[\"type\"].get<std::string>() + suffix;\n\t\t}\n\t}\n\telse if (StructType const* structType = dynamic_cast<StructType const*>(&_encodingType))\n\t{\n\t\tret[\"type\"] = \"tuple\";\n\t\tret[\"components\"] = Json::array();\n\t\tfor (auto const& member: structType->members(nullptr))\n\t\t{\n\t\t\tsolAssert(member.type, \"\");\n\t\t\tType const* t = member.type->interfaceType(_forLibrary);\n\t\t\tsolAssert(t, \"\");\n\t\t\tret[\"components\"].emplace_back(formatType(member.name, *t, *member.type, _forLibrary));\n\t\t}\n\t}\n\telse\n\t\tsolAssert(false, \"Invalid type.\");\n\treturn ret;\n}\n"
  },
  {
    "path": "libsolidity/interface/ABI.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Utilities to handle the Contract ABI (https://docs.soliditylang.org/en/develop/abi-spec.html)\n */\n\n#pragma once\n\n#include <libsolutil/JSON.h>\n#include <memory>\n#include <string>\n\nnamespace solidity::frontend\n{\n\n// Forward declarations\nclass ContractDefinition;\nclass Type;\n\nclass ABI\n{\npublic:\n\t/// Get the ABI Interface of the contract\n\t/// @param _contractDef The contract definition\n\t/// @return             A JSON representation of the contract's ABI Interface\n\tstatic Json generate(ContractDefinition const& _contractDef);\nprivate:\n\t/// @returns a json value suitable for a list of types in function input or output\n\t/// parameters or other places. If @a _forLibrary is true, complex types are referenced\n\t/// by name, otherwise they are anonymously expanded.\n\t/// @a _solidityTypes is the list of original Solidity types where @a _encodingTypes is the list of\n\t/// ABI types used for the actual encoding.\n\tstatic Json formatTypeList(\n\t\tstd::vector<std::string> const& _names,\n\t\tstd::vector<Type const*> const& _encodingTypes,\n\t\tstd::vector<Type const*> const& _solidityTypes,\n\t\tbool _forLibrary\n\t);\n\t/// @returns a Json object with \"name\", \"type\", \"internalType\" and potentially\n\t/// \"components\" keys, according to the ABI specification.\n\t/// If it is possible to express the type as a single string, it is allowed to return a single string.\n\t/// @a _solidityType is the original Solidity type and @a _encodingTypes is the\n\t/// ABI type used for the actual encoding.\n\tstatic Json formatType(\n\t\tstd::string const& _name,\n\t\tType const& _encodingType,\n\t\tType const& _solidityType,\n\t\tbool _forLibrary\n\t);\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/CompilerStack.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @author Gav Wood <g@ethdev.com>\n * @date 2014\n * Full-stack compiler that converts a source code string to bytecode.\n */\n\n\n#include <libsolidity/interface/CompilerStack.h>\n#include <libsolidity/interface/ImportRemapper.h>\n\n#include <libsolidity/analysis/ControlFlowAnalyzer.h>\n#include <libsolidity/analysis/ControlFlowGraph.h>\n#include <libsolidity/analysis/ControlFlowRevertPruner.h>\n#include <libsolidity/analysis/ContractLevelChecker.h>\n#include <libsolidity/analysis/DeclarationTypeChecker.h>\n#include <libsolidity/analysis/DocStringAnalyser.h>\n#include <libsolidity/analysis/DocStringTagParser.h>\n#include <libsolidity/analysis/GlobalContext.h>\n#include <libsolidity/analysis/NameAndTypeResolver.h>\n#include <libsolidity/analysis/PostTypeChecker.h>\n#include <libsolidity/analysis/PostTypeContractLevelChecker.h>\n#include <libsolidity/analysis/StaticAnalyzer.h>\n#include <libsolidity/analysis/SyntaxChecker.h>\n#include <libsolidity/analysis/Scoper.h>\n#include <libsolidity/analysis/TypeChecker.h>\n#include <libsolidity/analysis/ViewPureChecker.h>\n#include <libsolidity/analysis/ImmutableValidator.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/ast/ASTJsonImporter.h>\n#include <libsolidity/codegen/Compiler.h>\n#include <libsolidity/formal/ModelChecker.h>\n#include <libsolidity/interface/ABI.h>\n#include <libsolidity/interface/Natspec.h>\n#include <libsolidity/interface/GasEstimator.h>\n#include <libsolidity/interface/StorageLayout.h>\n#include <libsolidity/interface/UniversalCallback.h>\n#include <libsolidity/interface/Version.h>\n#include <libsolidity/parsing/Parser.h>\n\n#include <libsolidity/experimental/analysis/Analysis.h>\n#include <libsolidity/experimental/analysis/FunctionDependencyAnalysis.h>\n#include <libsolidity/experimental/codegen/IRGenerator.h>\n\n#include <libsolidity/codegen/ir/Common.h>\n#include <libsolidity/codegen/ir/IRGenerator.h>\n\n#include <libstdlib/stdlib.h>\n\n#include <libyul/YulName.h>\n#include <libyul/AsmPrinter.h>\n#include <libyul/AsmJsonConverter.h>\n#include <libyul/YulStack.h>\n#include <libyul/AST.h>\n#include <libyul/AsmParser.h>\n#include <libyul/optimiser/Suite.h>\n\n#include <liblangutil/Scanner.h>\n#include <liblangutil/SemVerHandler.h>\n#include <liblangutil/SourceReferenceFormatter.h>\n\n#include <libsolutil/SwarmHash.h>\n#include <libsolutil/IpfsHash.h>\n#include <libsolutil/JSON.h>\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/FunctionSelector.h>\n\n#include <libevmasm/Ethdebug.h>\n\n#include <boost/algorithm/string/replace.hpp>\n\n#include <range/v3/algorithm/all_of.hpp>\n#include <range/v3/view/concat.hpp>\n#include <range/v3/view/map.hpp>\n\n#include <fmt/format.h>\n\n#include <utility>\n#include <map>\n#include <limits>\n#include <string>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::stdlib;\nusing namespace solidity::yul;\nusing namespace std::string_literals;\n\nusing solidity::util::errinfo_comment;\n\nstatic int g_compilerStackCounts = 0;\n\nCompilerStack::CompilerStack(ReadCallback::Callback _readFile):\n\tm_readFile{std::move(_readFile)},\n\tm_objectOptimizer(std::make_shared<yul::ObjectOptimizer>()),\n\tm_errorReporter{m_errorList}\n{\n\t// Because TypeProvider is currently a singleton API, we must ensure that\n\t// no more than one entity is actually using it at a time.\n\tsolAssert(g_compilerStackCounts == 0, \"You shall not have another CompilerStack aside me.\");\n\t++g_compilerStackCounts;\n}\n\nCompilerStack::~CompilerStack()\n{\n\t--g_compilerStackCounts;\n\tTypeProvider::reset();\n}\n\nvoid CompilerStack::createAndAssignCallGraphs()\n{\n\tfor (Source const* source: m_sourceOrder)\n\t{\n\t\tif (!source->ast)\n\t\t\tcontinue;\n\n\t\tfor (ContractDefinition const* contract: ASTNode::filteredNodes<ContractDefinition>(source->ast->nodes()))\n\t\t{\n\t\t\tContractDefinitionAnnotation& annotation =\n\t\t\t\tm_contracts.at(contract->fullyQualifiedName()).contract->annotation();\n\n\t\t\tannotation.creationCallGraph = std::make_unique<CallGraph>(\n\t\t\t\tFunctionCallGraphBuilder::buildCreationGraph(*contract)\n\t\t\t);\n\t\t\tannotation.deployedCallGraph = std::make_unique<CallGraph>(\n\t\t\t\tFunctionCallGraphBuilder::buildDeployedGraph(\n\t\t\t\t\t*contract,\n\t\t\t\t\t**annotation.creationCallGraph\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tsolAssert(annotation.contractDependencies.empty(), \"contractDependencies expected to be empty?!\");\n\n\t\t\tannotation.contractDependencies = annotation.creationCallGraph->get()->bytecodeDependency;\n\n\t\t\tfor (auto const& [dependencyContract, referencee]: annotation.deployedCallGraph->get()->bytecodeDependency)\n\t\t\t\tannotation.contractDependencies.emplace(dependencyContract, referencee);\n\t\t}\n\t}\n}\n\nvoid CompilerStack::findAndReportCyclicContractDependencies()\n{\n\t// Cycles we found, used to avoid duplicate reports for the same reference\n\tstd::set<ASTNode const*, ASTNode::CompareByID> foundCycles;\n\n\tfor (Source const* source: m_sourceOrder)\n\t{\n\t\tif (!source->ast)\n\t\t\tcontinue;\n\n\t\tfor (ContractDefinition const* contractDefinition: ASTNode::filteredNodes<ContractDefinition>(source->ast->nodes()))\n\t\t{\n\t\t\tutil::CycleDetector<ContractDefinition> cycleDetector{[&](\n\t\t\t\tContractDefinition const& _contract,\n\t\t\t\tutil::CycleDetector<ContractDefinition>& _cycleDetector,\n\t\t\t\tsize_t _depth\n\t\t\t)\n\t\t\t{\n\t\t\t\t// No specific reason for exactly that number, just a limit we're unlikely to hit.\n\t\t\t\tif (_depth >= 256)\n\t\t\t\t\tm_errorReporter.fatalTypeError(\n\t\t\t\t\t\t7864_error,\n\t\t\t\t\t\t_contract.location(),\n\t\t\t\t\t\t\"Contract dependencies exhausting cyclic dependency validator\"\n\t\t\t\t\t);\n\n\t\t\t\tfor (auto& [dependencyContract, referencee]: _contract.annotation().contractDependencies)\n\t\t\t\t\tif (_cycleDetector.run(*dependencyContract))\n\t\t\t\t\t\treturn;\n\t\t\t}};\n\n\t\t\tContractDefinition const* cycle = cycleDetector.run(*contractDefinition);\n\n\t\t\tif (!cycle)\n\t\t\t\tcontinue;\n\n\t\t\tASTNode const* referencee = contractDefinition->annotation().contractDependencies.at(cycle);\n\n\t\t\tif (foundCycles.find(referencee) != foundCycles.end())\n\t\t\t\tcontinue;\n\n\t\t\tSecondarySourceLocation secondaryLocation{};\n\t\t\tsecondaryLocation.append(\"Referenced contract is here:\"s, cycle->location());\n\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t7813_error,\n\t\t\t\treferencee->location(),\n\t\t\t\tsecondaryLocation,\n\t\t\t\t\"Circular reference to contract bytecode either via \\\"new\\\" or \\\"type(...).creationCode\\\" / \\\"type(...).runtimeCode\\\".\"\n\t\t\t);\n\n\t\t\tfoundCycles.emplace(referencee);\n\t\t}\n\t}\n}\n\nvoid CompilerStack::setRemappings(std::vector<ImportRemapper::Remapping> _remappings)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must set remappings before parsing.\");\n\tfor (auto const& remapping: _remappings)\n\t\tsolAssert(!remapping.prefix.empty(), \"\");\n\tm_importRemapper.setRemappings(std::move(_remappings));\n}\n\nvoid CompilerStack::setViaIR(bool _viaIR)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must set viaIR before parsing.\");\n\tm_viaIR = _viaIR;\n}\n\nvoid CompilerStack::setExperimental(bool _experimental)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must set experimental before parsing.\");\n\tm_experimental = _experimental;\n}\n\nvoid CompilerStack::setViaSSACFG(bool _viaSSACFG)\n{\n\tsolAssert(m_stackState < CompilationSuccessful, \"Must set SSA CFG codegen before compilation.\");\n\tm_viaSSACFG = _viaSSACFG;\n}\n\nvoid CompilerStack::setEVMVersion(langutil::EVMVersion _version)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must set EVM version before parsing.\");\n\tm_evmVersion = _version;\n\t// GlobalContext depends on evmVersion since the Cancun hardfork.\n\t// Therefore, we reset it whenever we set a new EVM version, ensuring that the context is never reused with a mismatched version.\n\tm_globalContext.reset();\n}\n\nvoid CompilerStack::setEOFVersion(std::optional<uint8_t> _version)\n{\n\tsolAssert(m_stackState < CompilationSuccessful, \"Must set EOF version before compiling.\");\n\tsolAssert(!_version || _version == 1, \"Invalid EOF version.\");\n\tm_eofVersion = _version;\n}\n\nvoid CompilerStack::setModelCheckerSettings(ModelCheckerSettings _settings)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must set model checking settings before parsing.\");\n\tm_modelCheckerSettings = _settings;\n}\n\nvoid CompilerStack::selectContracts(ContractSelection const& _selectedContracts)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must request outputs before parsing.\");\n\tm_selectedContracts = _selectedContracts;\n}\n\nvoid CompilerStack::setLibraries(std::map<std::string, util::h160> const& _libraries)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must set libraries before parsing.\");\n\tm_libraries = _libraries;\n}\n\nvoid CompilerStack::setOptimiserSettings(bool _optimize, size_t _runs)\n{\n\tOptimiserSettings settings = _optimize ? OptimiserSettings::standard() : OptimiserSettings::minimal();\n\tsettings.expectedExecutionsPerDeployment = _runs;\n\tsetOptimiserSettings(std::move(settings));\n}\n\nvoid CompilerStack::setOptimiserSettings(OptimiserSettings _settings)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must set optimiser settings before parsing.\");\n\tm_optimiserSettings = std::move(_settings);\n}\n\nvoid CompilerStack::setRevertStringBehaviour(RevertStrings _revertStrings)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must set revert string settings before parsing.\");\n\tsolUnimplementedAssert(_revertStrings != RevertStrings::VerboseDebug);\n\tm_revertStrings = _revertStrings;\n}\n\nvoid CompilerStack::useMetadataLiteralSources(bool _metadataLiteralSources)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must set use literal sources before parsing.\");\n\tm_metadataLiteralSources = _metadataLiteralSources;\n}\n\nvoid CompilerStack::setMetadataHash(MetadataHash _metadataHash)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must set metadata hash before parsing.\");\n\tm_metadataHash = _metadataHash;\n}\n\nvoid CompilerStack::selectDebugInfo(DebugInfoSelection _debugInfoSelection)\n{\n\tsolAssert(m_stackState < CompilationSuccessful, \"Must select debug info components before compilation.\");\n\tm_debugInfoSelection = _debugInfoSelection;\n}\n\nvoid CompilerStack::addSMTLib2Response(h256 const& _hash, std::string const& _response)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"Must add SMTLib2 responses before parsing.\");\n\tm_smtlib2Responses[_hash] = _response;\n}\n\nvoid CompilerStack::reset(bool _keepSettings)\n{\n\tm_stackState = Empty;\n\tm_sources.clear();\n\tm_maxAstId.reset();\n\tm_smtlib2Responses.clear();\n\tm_unhandledSMTLib2Queries.clear();\n\tif (!_keepSettings)\n\t{\n\t\tm_importRemapper.clear();\n\t\tm_libraries.clear();\n\t\tm_viaIR = false;\n\t\tm_viaSSACFG = false;\n\t\tm_evmVersion = langutil::EVMVersion();\n\t\tm_eofVersion.reset();\n\t\tm_modelCheckerSettings = ModelCheckerSettings{};\n\t\tm_selectedContracts.clear();\n\t\tm_revertStrings = RevertStrings::Default;\n\t\tm_optimiserSettings = OptimiserSettings::minimal();\n\t\tm_metadataLiteralSources = false;\n\t\tm_metadataFormat = defaultMetadataFormat();\n\t\tm_metadataHash = MetadataHash::IPFS;\n\t\tm_stopAfter = State::CompilationSuccessful;\n\t\tm_compilationSourceType = CompilationSourceType::Solidity;\n\t}\n\tm_experimentalAnalysis.reset();\n\tm_globalContext.reset();\n\tm_sourceOrder.clear();\n\tm_contracts.clear();\n\tm_errorReporter.clear();\n\tTypeProvider::reset();\n}\n\nvoid CompilerStack::setSources(StringMap _sources)\n{\n\tsolAssert(m_stackState != SourcesSet, \"Cannot change sources once set.\");\n\tsolAssert(m_stackState == Empty, \"Must set sources before parsing.\");\n\tfor (auto source: _sources)\n\t\tm_sources[source.first].charStream = std::make_unique<CharStream>(/*content*/std::move(source.second), /*name*/source.first);\n\tm_stackState = SourcesSet;\n}\n\nbool CompilerStack::parse()\n{\n\tsolAssert(m_stackState == SourcesSet, \"Must call parse only after the SourcesSet state.\");\n\tm_errorReporter.clear();\n\n\tif (SemVerVersion{std::string(VersionString)}.isPrerelease())\n\t\tm_errorReporter.warning(3805_error, \"This is a pre-release compiler version, please do not use it in production.\");\n\n\ttry\n\t{\n\t\tParser parser{m_errorReporter, m_evmVersion, m_eofVersion};\n\n\t\tstd::vector<std::string> sourcesToParse;\n\t\tfor (auto const& s: m_sources)\n\t\t\tsourcesToParse.push_back(s.first);\n\n\t\tfor (size_t i = 0; i < sourcesToParse.size(); ++i)\n\t\t{\n\t\t\tstd::string const path = sourcesToParse[i];\n\t\t\tSource& source = m_sources[path];\n\t\t\tsource.ast = parser.parse(*source.charStream);\n\t\t\tif (!source.ast)\n\t\t\t\tsolAssert(Error::containsErrors(m_errorReporter.errors()), \"Parser returned null but did not report error.\");\n\t\t\telse\n\t\t\t{\n\t\t\t\tsource.ast->annotation().path = path;\n\n\t\t\t\tfor (auto const& import: ASTNode::filteredNodes<ImportDirective>(source.ast->nodes()))\n\t\t\t\t{\n\t\t\t\t\tsolAssert(!import->path().empty(), \"Import path cannot be empty.\");\n\t\t\t\t\t// Check whether the import directive is for the standard library,\n\t\t\t\t\t// and if yes, add specified file to source units to be parsed.\n\t\t\t\t\tauto it = stdlib::sources.find(import->path());\n\t\t\t\t\tif (it != stdlib::sources.end())\n\t\t\t\t\t{\n\t\t\t\t\t\tauto [name, content] = *it;\n\t\t\t\t\t\tm_sources[name].charStream = std::make_unique<CharStream>(content, name);\n\t\t\t\t\t\tsourcesToParse.push_back(name);\n\t\t\t\t\t}\n\n\t\t\t\t\t// The current value of `path` is the absolute path as seen from this source file.\n\t\t\t\t\t// We first have to apply remappings before we can store the actual absolute path\n\t\t\t\t\t// as seen globally.\n\t\t\t\t\timport->annotation().absolutePath = applyRemapping(util::absolutePath(\n\t\t\t\t\t\timport->path(),\n\t\t\t\t\t\tpath\n\t\t\t\t\t), path);\n\t\t\t\t}\n\n\t\t\t\tif (m_stopAfter >= ParsedAndImported)\n\t\t\t\t\tfor (auto const& newSource: loadMissingSources(*source.ast))\n\t\t\t\t\t{\n\t\t\t\t\t\tstd::string const& newPath = newSource.first;\n\t\t\t\t\t\tstd::string const& newContents = newSource.second;\n\t\t\t\t\t\tm_sources[newPath].charStream = std::make_shared<CharStream>(newContents, newPath);\n\t\t\t\t\t\tsourcesToParse.push_back(newPath);\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (Error::containsErrors(m_errorReporter.errors()))\n\t\t\treturn false;\n\n\t\tm_stackState = (m_stopAfter <= Parsed ? Parsed : ParsedAndImported);\n\t\tstoreContractDefinitions();\n\n\t\tsolAssert(!m_maxAstId.has_value());\n\t\tm_maxAstId = parser.maxID();\n\t}\n\tcatch (UnimplementedFeatureError const& _error)\n\t{\n\t\treportUnimplementedFeatureError(_error);\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nvoid CompilerStack::importASTs(std::map<std::string, Json> const& _sources)\n{\n\tsolAssert(m_stackState == Empty, \"Must call importASTs only before the SourcesSet state.\");\n\tstd::map<std::string, ASTPointer<SourceUnit>> reconstructedSources =\n\t\tASTJsonImporter(m_evmVersion, m_eofVersion).jsonToSourceUnit(_sources);\n\tfor (auto& src: reconstructedSources)\n\t{\n\t\tsolUnimplementedAssert(!src.second->experimentalSolidity());\n\t\tstd::string const& path = src.first;\n\t\tSource source;\n\t\tsource.ast = src.second;\n\t\tsource.charStream = std::make_shared<CharStream>(\n\t\t\tutil::jsonCompactPrint(_sources.at(src.first)),\n\t\t\tsrc.first,\n\t\t\ttrue // imported from AST\n\t\t);\n\t\tm_sources[path] = std::move(source);\n\t}\n\tm_stackState = ParsedAndImported;\n\tm_compilationSourceType = CompilationSourceType::SolidityAST;\n\n\tstoreContractDefinitions();\n}\n\nnamespace\n{\n\nbool onlySafeExperimentalFeaturesActivated(std::set<ExperimentalFeature> const& _features)\n{\n\tfor (auto const feature: _features)\n\t\tif (!ExperimentalFeatureWithoutWarning.contains(feature))\n\t\t\treturn false;\n\treturn true;\n}\n\n}\n\nbool CompilerStack::analyze()\n{\n\tsolAssert(m_stackState == ParsedAndImported, \"Must call analyze only after parsing was successful.\");\n\n\tif (!resolveImports())\n\t\treturn false;\n\n\tfor (Source const* source: m_sourceOrder)\n\t\tif (source->ast)\n\t\t\tScoper::assignScopes(*source->ast);\n\n\tbool noErrors = true;\n\n\ttry\n\t{\n\t\tbool experimentalSolidity = isExperimentalSolidity();\n\n\t\tSyntaxChecker syntaxChecker(m_errorReporter, m_optimiserSettings.runYulOptimiser, m_experimental);\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast && !syntaxChecker.checkSyntax(*source->ast))\n\t\t\t\tnoErrors = false;\n\n\t\tm_globalContext = std::make_shared<GlobalContext>(m_evmVersion);\n\t\t// We need to keep the same resolver during the whole process.\n\t\tNameAndTypeResolver resolver(*m_globalContext, m_evmVersion, m_errorReporter, experimentalSolidity);\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast && !resolver.registerDeclarations(*source->ast))\n\t\t\t\treturn false;\n\n\t\tstd::map<std::string, SourceUnit const*> sourceUnitsByName;\n\t\tfor (auto& source: m_sources)\n\t\t\tsourceUnitsByName[source.first] = source.second.ast.get();\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast && !resolver.performImports(*source->ast, sourceUnitsByName))\n\t\t\t\treturn false;\n\n\t\tresolver.warnHomonymDeclarations();\n\n\t\t{\n\t\t\tDocStringTagParser docStringTagParser(m_errorReporter);\n\t\t\tfor (Source const* source: m_sourceOrder)\n\t\t\t\tif (source->ast && !docStringTagParser.parseDocStrings(*source->ast))\n\t\t\t\t\tnoErrors = false;\n\t\t}\n\n\t\t// Requires DocStringTagParser\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast && !resolver.resolveNamesAndTypes(*source->ast))\n\t\t\t\treturn false;\n\n\t\tif (experimentalSolidity)\n\t\t{\n\t\t\tif (!analyzeExperimental())\n\t\t\t\tnoErrors = false;\n\t\t}\n\t\telse if (!analyzeLegacy(noErrors))\n\t\t\tnoErrors = false;\n\t}\n\tcatch (FatalError const&)\n\t{\n\t\tif (!m_errorReporter.hasErrors())\n\t\t{\n\t\t\tstd::cerr << \"Unreported fatal error:\" << std::endl;\n\t\t\tstd::cerr << boost::current_exception_diagnostic_information() << std::endl;\n\t\t\tsolAssert(false, \"Unreported fatal error.\");\n\t\t}\n\t\tnoErrors = false;\n\t}\n\tcatch (UnimplementedFeatureError const& _error)\n\t{\n\t\treportUnimplementedFeatureError(_error);\n\t\tnoErrors = false;\n\t}\n\n\tif (!noErrors)\n\t\treturn false;\n\n\tfor (Source const* source: m_sourceOrder)\n\t\tif (source->ast && !m_experimental)\n\t\t\tsolAssert(onlySafeExperimentalFeaturesActivated(source->ast->annotation().experimentalFeatures));\n\n\tm_stackState = AnalysisSuccessful;\n\treturn true;\n}\n\n\nbool CompilerStack::analyzeLegacy(bool _noErrorsSoFar)\n{\n\tbool noErrors = _noErrorsSoFar;\n\n\tDeclarationTypeChecker declarationTypeChecker(m_errorReporter, m_evmVersion);\n\tfor (Source const* source: m_sourceOrder)\n\t\tif (source->ast && !declarationTypeChecker.check(*source->ast))\n\t\t\treturn false;\n\n\t// Requires DeclarationTypeChecker to have run\n\tDocStringTagParser docStringTagParser(m_errorReporter);\n\tfor (Source const* source: m_sourceOrder)\n\t\tif (source->ast && !docStringTagParser.validateDocStringsUsingTypes(*source->ast))\n\t\t\tnoErrors = false;\n\n\t// Next, we check inheritance, overrides, function collisions and other things at\n\t// contract or function level.\n\t// This also calculates whether a contract is abstract, which is needed by the\n\t// type checker.\n\tContractLevelChecker contractLevelChecker(m_errorReporter);\n\n\tfor (Source const* source: m_sourceOrder)\n\t\tif (auto sourceAst = source->ast)\n\t\t\tnoErrors = contractLevelChecker.check(*sourceAst);\n\n\t// Now we run full type checks that go down to the expression level. This\n\t// cannot be done earlier, because we need cross-contract types and information\n\t// about whether a contract is abstract for the `new` expression.\n\t// This populates the `type` annotation for all expressions.\n\t//\n\t// Note: this does not resolve overloaded functions. In order to do that, types of arguments are needed,\n\t// which is only done one step later.\n\tTypeChecker typeChecker(m_evmVersion, m_eofVersion, m_errorReporter);\n\tfor (Source const* source: m_sourceOrder)\n\t\tif (source->ast && !typeChecker.checkTypeRequirements(*source->ast))\n\t\t\tnoErrors = false;\n\n\tif (noErrors)\n\t{\n\t\t// Requires ContractLevelChecker and TypeChecker\n\t\tDocStringAnalyser docStringAnalyser(m_errorReporter);\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast && !docStringAnalyser.analyseDocStrings(*source->ast))\n\t\t\t\tnoErrors = false;\n\t}\n\n\tif (noErrors)\n\t{\n\t\t// Checks that can only be done when all types of all AST nodes are known.\n\t\tPostTypeChecker postTypeChecker(m_errorReporter);\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast && !postTypeChecker.check(*source->ast))\n\t\t\t\tnoErrors = false;\n\t\tif (!postTypeChecker.finalize())\n\t\t\tnoErrors = false;\n\t}\n\n\t// Create & assign callgraphs and check for contract dependency cycles\n\tif (noErrors)\n\t{\n\t\tcreateAndAssignCallGraphs();\n\t\tannotateInternalFunctionIDs();\n\t\tfindAndReportCyclicContractDependencies();\n\t}\n\n\tif (noErrors)\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast && !PostTypeContractLevelChecker{m_errorReporter}.check(*source->ast))\n\t\t\t\tnoErrors = false;\n\n\t// Check that immutable variables are never read in c'tors and assigned\n\t// exactly once\n\tif (noErrors)\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast)\n\t\t\t\tfor (ASTPointer<ASTNode> const& node: source->ast->nodes())\n\t\t\t\t\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))\n\t\t\t\t\t\tImmutableValidator(m_errorReporter, *contract).analyze();\n\n\tif (noErrors)\n\t{\n\t\t// Control flow graph generator and analyzer. It can check for issues such as\n\t\t// variable is used before it is assigned to.\n\t\tCFG cfg(m_errorReporter);\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast && !cfg.constructFlow(*source->ast))\n\t\t\t\tnoErrors = false;\n\n\t\tif (noErrors)\n\t\t{\n\t\t\tControlFlowRevertPruner pruner(cfg);\n\t\t\tpruner.run();\n\n\t\t\tControlFlowAnalyzer controlFlowAnalyzer(cfg, m_errorReporter);\n\t\t\tif (!controlFlowAnalyzer.run())\n\t\t\t\tnoErrors = false;\n\t\t}\n\t}\n\n\tif (noErrors)\n\t{\n\t\t// Checks for common mistakes. Only generates warnings.\n\t\tStaticAnalyzer staticAnalyzer(m_errorReporter);\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast && !staticAnalyzer.analyze(*source->ast))\n\t\t\t\tnoErrors = false;\n\t}\n\n\tif (noErrors)\n\t{\n\t\t// Check for state mutability in every function.\n\t\tstd::vector<ASTPointer<ASTNode>> ast;\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast)\n\t\t\t\tast.push_back(source->ast);\n\n\t\tif (!ViewPureChecker(ast, m_errorReporter).check())\n\t\t\tnoErrors = false;\n\t}\n\n\tif (noErrors)\n\t{\n\t\t// Run SMTChecker\n\n\t\tauto allSources = util::applyMap(m_sourceOrder, [](Source const* _source) { return _source->ast; });\n\t\tif (ModelChecker::isPragmaPresent(allSources))\n\t\t\tm_modelCheckerSettings.engine = ModelCheckerEngine::All();\n\n\t\t// m_modelCheckerSettings is spread to engines and solver interfaces,\n\t\t// so we need to check whether the enabled ones are available before building the classes.\n\t\tif (m_modelCheckerSettings.engine.any())\n\t\t\tm_modelCheckerSettings.solvers = ModelChecker::checkRequestedSolvers(m_modelCheckerSettings.solvers, m_errorReporter);\n\n\t\tModelChecker modelChecker(m_errorReporter, *this, m_smtlib2Responses, m_modelCheckerSettings, m_readFile);\n\t\tmodelChecker.checkRequestedSourcesAndContracts(allSources);\n\t\tfor (Source const* source: m_sourceOrder)\n\t\t\tif (source->ast)\n\t\t\t\tmodelChecker.analyze(*source->ast);\n\t\tm_unhandledSMTLib2Queries += modelChecker.unhandledQueries();\n\t}\n\n\treturn noErrors;\n}\n\nbool CompilerStack::analyzeExperimental()\n{\n\tsolAssert(!m_experimentalAnalysis);\n\tsolAssert(m_maxAstId && *m_maxAstId >= 0);\n\tm_experimentalAnalysis = std::make_unique<experimental::Analysis>(m_errorReporter, static_cast<std::uint64_t>(*m_maxAstId));\n\tstd::vector<std::shared_ptr<SourceUnit const>> sourceAsts;\n\tfor (Source const* source: m_sourceOrder)\n\t\tif (source->ast)\n\t\t\tsourceAsts.emplace_back(source->ast);\n\treturn m_experimentalAnalysis->check(sourceAsts);\n}\n\nbool CompilerStack::parseAndAnalyze(State _stopAfter)\n{\n\tm_stopAfter = _stopAfter;\n\n\tbool success = parse();\n\tif (m_stackState >= m_stopAfter)\n\t\treturn success;\n\tif (success)\n\t\tsuccess = analyze();\n\treturn success;\n}\n\nbool CompilerStack::isRequestedSource(std::string const& _sourceName) const\n{\n\treturn\n\t\tm_selectedContracts.empty() ||\n\t\tm_selectedContracts.count(\"\") ||\n\t\tm_selectedContracts.count(_sourceName);\n}\n\nbool CompilerStack::isRequestedContract(ContractDefinition const& _contract) const\n{\n\t/// In case nothing was specified in selectedContracts.\n\tif (m_selectedContracts.empty())\n\t\treturn true;\n\n\tfor (auto const& key: std::vector<std::string>{\"\", _contract.sourceUnitName()})\n\t{\n\t\tauto const& it = m_selectedContracts.find(key);\n\t\tif (it != m_selectedContracts.end())\n\t\t\tif (it->second.count(_contract.name()) || it->second.count(\"\"))\n\t\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nCompilerStack::PipelineConfig CompilerStack::requestedPipelineConfig(ContractDefinition const& _contract) const\n{\n\tstatic PipelineConfig constexpr defaultPipelineConfig = PipelineConfig{\n\t\tfalse, // irCodegen\n\t\tfalse, // irOptimization\n\t\ttrue,  // bytecode\n\t};\n\n\t// If nothing was explicitly selected, all contracts are selected by default.\n\tif (m_selectedContracts.empty())\n\t\treturn defaultPipelineConfig;\n\n\tPipelineConfig combinedConfig;\n\tfor (std::string const& sourceUnitName: {\"\"s, _contract.sourceUnitName()})\n\t\tif (m_selectedContracts.count(sourceUnitName) != 0)\n\t\t\tfor (std::string const& contractName: {\"\"s, _contract.name()})\n\t\t\t\tif (m_selectedContracts.at(sourceUnitName).count(contractName) != 0)\n\t\t\t\t\tcombinedConfig = combinedConfig | m_selectedContracts.at(sourceUnitName).at(contractName);\n\n\treturn combinedConfig;\n}\n\nbool CompilerStack::compile(State _stopAfter)\n{\n\tm_stopAfter = _stopAfter;\n\n\tsolAssert(!m_viaSSACFG || m_experimental, \"SSA CFG code generation is an experimental feature. It requires experimental mode to be enabled.\");\n\n\tif (m_stackState < AnalysisSuccessful)\n\t\tif (!parseAndAnalyze(_stopAfter))\n\t\t\treturn false;\n\n\tif (m_stackState >= m_stopAfter)\n\t\treturn true;\n\n\t// Only compile contracts individually which have been requested.\n\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>> otherCompilers;\n\n\tfor (Source const* source: m_sourceOrder)\n\t\tfor (ASTPointer<ASTNode> const& node: source->ast->nodes())\n\t\t\tif (auto contract = dynamic_cast<ContractDefinition const*>(node.get()))\n\t\t\t\tif (isRequestedContract(*contract))\n\t\t\t\t{\n\t\t\t\t\tPipelineConfig pipelineConfig = requestedPipelineConfig(*contract);\n\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tif (pipelineConfig.needIR(m_viaIR))\n\t\t\t\t\t\t\tgenerateIR(*contract, pipelineConfig.needIRCodegenOnly(m_viaIR));\n\t\t\t\t\t\tif (pipelineConfig.needBytecode())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (m_viaIR)\n\t\t\t\t\t\t\t\tgenerateEVMFromIR(*contract);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (m_experimentalAnalysis)\n\t\t\t\t\t\t\t\t\tsolThrow(CompilerError, \"Legacy codegen after experimental analysis is unsupported.\");\n\t\t\t\t\t\t\t\tcompileContract(*contract, otherCompilers);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Error const& _error)\n\t\t\t\t\t{\n\t\t\t\t\t\treportCodeGenerationError(_error, contract);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (UnimplementedFeatureError const& _error)\n\t\t\t\t\t{\n\t\t\t\t\t\treportUnimplementedFeatureError(_error, contract);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (m_errorReporter.hasErrors())\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\tsolAssert(!m_errorReporter.hasErrors());\n\tm_stackState = CompilationSuccessful;\n\tthis->link();\n\treturn true;\n}\n\nvoid CompilerStack::link()\n{\n\tsolAssert(m_stackState >= CompilationSuccessful, \"\");\n\tfor (auto& contract: m_contracts)\n\t{\n\t\tcontract.second.object.link(m_libraries);\n\t\tcontract.second.runtimeObject.link(m_libraries);\n\t}\n}\n\nYulStack CompilerStack::loadGeneratedIR(std::string const& _ir) const\n{\n\tYulStack stack(\n\t\tm_evmVersion,\n\t\tm_eofVersion,\n\t\tm_optimiserSettings,\n\t\tm_debugInfoSelection,\n\t\tthis, // _soliditySourceProvider\n\t\tm_objectOptimizer\n\t);\n\tbool yulAnalysisSuccessful = stack.parseAndAnalyze(\"\", _ir);\n\tsolAssert(\n\t\tyulAnalysisSuccessful,\n\t\t_ir + \"\\n\\n\"\n\t\t\"Invalid IR generated:\\n\" +\n\t\tSourceReferenceFormatter::formatErrorInformation(\n\t\t\tstack.errors(),\n\t\t\tstack, // _charStreamProvider\n\t\t\tfalse, // _colored\n\t\t\ttrue   // _withErrorIds\n\t\t) + \"\\n\"\n\t);\n\n\treturn stack;\n}\n\nstd::vector<std::string> CompilerStack::contractNames() const\n{\n\tsolAssert(m_stackState >= Parsed, \"Parsing was not successful.\");\n\tstd::vector<std::string> contractNames;\n\tfor (auto const& contract: m_contracts)\n\t\tcontractNames.push_back(contract.first);\n\treturn contractNames;\n}\n\nstd::string const CompilerStack::lastContractName(std::optional<std::string> const& _sourceName) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Parsing was not successful.\");\n\t// try to find some user-supplied contract\n\tstd::string contractName;\n\tfor (auto const& it: m_sources)\n\t\tif (_sourceName.value_or(it.first) == it.first)\n\t\t\tfor (auto const* contract: ASTNode::filteredNodes<ContractDefinition>(it.second.ast->nodes()))\n\t\t\t\tcontractName = contract->fullyQualifiedName();\n\treturn contractName;\n}\n\nevmasm::AssemblyItems const* CompilerStack::assemblyItems(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\n\tContract const& currentContract = contract(_contractName);\n\tif (!currentContract.evmAssembly)\n\t\treturn nullptr;\n\tsolUnimplementedAssert(!m_eofVersion.has_value(), \"EVM assembly output not implemented for EOF yet.\");\n\tsolAssert(currentContract.evmAssembly->codeSections().size() == 1, \"Expected a single code section in legacy codegen.\");\n\treturn &currentContract.evmAssembly->codeSections().front().items;\n}\n\nevmasm::AssemblyItems const* CompilerStack::runtimeAssemblyItems(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\n\tContract const& currentContract = contract(_contractName);\n\n\tif (!currentContract.evmRuntimeAssembly)\n\t\treturn nullptr;\n\tsolUnimplementedAssert(!m_eofVersion.has_value(), \"EVM assembly output not implemented for EOF yet.\");\n\tsolAssert(currentContract.evmRuntimeAssembly->codeSections().size() == 1, \"Expected a single code section in legacy codegen.\");\n\treturn &currentContract.evmRuntimeAssembly->codeSections().front().items;\n}\n\nJson CompilerStack::generatedSources(std::string const& _contractName, bool _runtime) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\n\tContract const& c = contract(_contractName);\n\tJson sources = Json::array();\n\t// If there is no compiler, then no bytecode was generated and thus no\n\t// sources were generated (or we compiled \"via IR\").\n\tif (c.runtimeGeneratedYulUtilityCode.has_value())\n\t{\n\t\tsolAssert(c.generatedYulUtilityCode.has_value() == c.runtimeGeneratedYulUtilityCode.has_value());\n\t\tsolAssert(!m_viaIR);\n\t\tstd::string source =\n\t\t\t_runtime ?\n\t\t\t*c.runtimeGeneratedYulUtilityCode :\n\t\t\t*c.generatedYulUtilityCode;\n\t\tif (!source.empty())\n\t\t{\n\t\t\tstd::string sourceName = CompilerContext::yulUtilityFileName();\n\t\t\tunsigned sourceIndex = sourceIndices()[sourceName];\n\t\t\tErrorList errors;\n\t\t\tErrorReporter errorReporter(errors);\n\t\t\tCharStream charStream(source, sourceName);\n\t\t\tyul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion, m_eofVersion);\n\t\t\tstd::shared_ptr<yul::AST> parserResult = yul::Parser{errorReporter, dialect}.parse(charStream);\n\t\t\tsolAssert(parserResult);\n\t\t\tsources[0][\"ast\"] = yul::AsmJsonConverter{dialect, sourceIndex}(parserResult->root());\n\t\t\tsources[0][\"name\"] = sourceName;\n\t\t\tsources[0][\"id\"] = sourceIndex;\n\t\t\tsources[0][\"language\"] = \"Yul\";\n\t\t\tsources[0][\"contents\"] = std::move(source);\n\t\t}\n\t}\n\treturn sources;\n}\n\nstd::string const* CompilerStack::sourceMapping(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\n\t// TODO\n\tif (m_eofVersion.has_value())\n\t\treturn nullptr;\n\n\tContract const& c = contract(_contractName);\n\tif (!c.sourceMapping)\n\t{\n\t\tif (auto items = assemblyItems(_contractName))\n\t\t\tc.sourceMapping.emplace(evmasm::AssemblyItem::computeSourceMapping(*items, sourceIndices()));\n\t}\n\treturn c.sourceMapping ? &*c.sourceMapping : nullptr;\n}\n\nstd::string const* CompilerStack::runtimeSourceMapping(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\n\t// TODO\n\tif (m_eofVersion.has_value())\n\t\treturn nullptr;\n\n\tContract const& c = contract(_contractName);\n\tif (!c.runtimeSourceMapping)\n\t{\n\t\tif (auto items = runtimeAssemblyItems(_contractName))\n\t\t\tc.runtimeSourceMapping.emplace(\n\t\t\t\tevmasm::AssemblyItem::computeSourceMapping(*items, sourceIndices())\n\t\t\t);\n\t}\n\treturn c.runtimeSourceMapping ? &*c.runtimeSourceMapping : nullptr;\n}\n\nstd::string const CompilerStack::filesystemFriendlyName(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"No compiled contracts found.\");\n\n\t// Look up the contract (by its fully-qualified name)\n\tContract const& matchContract = m_contracts.at(_contractName);\n\t// Check to see if it could collide on name\n\tfor (auto const& contract: m_contracts)\n\t{\n\t\tif (contract.second.contract->name() == matchContract.contract->name() &&\n\t\t\t\tcontract.second.contract != matchContract.contract)\n\t\t{\n\t\t\t// If it does, then return its fully-qualified name, made fs-friendly\n\t\t\tstd::string friendlyName = boost::algorithm::replace_all_copy(_contractName, \"/\", \"_\");\n\t\t\tboost::algorithm::replace_all(friendlyName, \":\", \"_\");\n\t\t\tboost::algorithm::replace_all(friendlyName, \".\", \"_\");\n\t\t\treturn friendlyName;\n\t\t}\n\t}\n\t// If no collision, return the contract's name\n\treturn matchContract.contract->name();\n}\n\nstd::optional<std::string> const& CompilerStack::yulIR(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\treturn contract(_contractName).yulIR;\n}\n\nstd::optional<Json> CompilerStack::yulIRAst(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\n\t// NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to\n\t// keep it around when compiling a large project containing many contracts.\n\tContract const& currentContract = contract(_contractName);\n\tyulAssert(currentContract.contract);\n\tyulAssert(currentContract.yulIR.has_value() == currentContract.contract->canBeDeployed());\n\tif (!currentContract.yulIR)\n\t\treturn std::nullopt;\n\treturn loadGeneratedIR(*currentContract.yulIR).astJson();\n}\n\nstd::optional<Json> CompilerStack::yulCFGJson(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\n\t// NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to\n\t// keep it around when compiling a large project containing many contracts.\n\tContract const& currentContract = contract(_contractName);\n\tyulAssert(currentContract.contract);\n\tyulAssert(currentContract.yulIROptimized.has_value() == currentContract.contract->canBeDeployed());\n\tif (!currentContract.yulIROptimized)\n\t\treturn std::nullopt;\n\treturn loadGeneratedIR(*currentContract.yulIROptimized).cfgJson();\n}\n\nstd::optional<std::string> const& CompilerStack::yulIROptimized(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\treturn contract(_contractName).yulIROptimized;\n}\n\nstd::optional<Json> CompilerStack::yulIROptimizedAst(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\n\t// NOTE: Intentionally not using LazyInit. The artifact can get very large and we don't want to\n\t// keep it around when compiling a large project containing many contracts.\n\tContract const& currentContract = contract(_contractName);\n\tyulAssert(currentContract.contract);\n\tyulAssert(currentContract.yulIROptimized.has_value() == currentContract.contract->canBeDeployed());\n\tif (!currentContract.yulIROptimized)\n\t\treturn std::nullopt;\n\treturn loadGeneratedIR(*currentContract.yulIROptimized).astJson();\n}\n\nevmasm::LinkerObject const& CompilerStack::object(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\treturn contract(_contractName).object;\n}\n\nevmasm::LinkerObject const& CompilerStack::runtimeObject(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\treturn contract(_contractName).runtimeObject;\n}\n\n/// TODO: cache this string\nstd::string CompilerStack::assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\n\tContract const& currentContract = contract(_contractName);\n\tif (currentContract.evmAssembly)\n\t\treturn currentContract.evmAssembly->assemblyString(m_debugInfoSelection, _sourceCodes);\n\telse\n\t\treturn std::string();\n}\n\n/// TODO: cache the JSON\nJson CompilerStack::assemblyJSON(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\n\tContract const& currentContract = contract(_contractName);\n\tif (currentContract.evmAssembly)\n\t\treturn currentContract.evmAssembly->assemblyJSON(sourceIndices());\n\telse\n\t\treturn Json();\n}\n\nstd::vector<std::string> CompilerStack::sourceNames() const\n{\n\treturn ranges::to<std::vector>(m_sources | ranges::views::keys);\n}\n\nstd::map<std::string, unsigned> CompilerStack::sourceIndices() const\n{\n\tstd::map<std::string, unsigned> indices;\n\tunsigned index = 0;\n\tfor (auto const& s: m_sources)\n\t\tindices[s.first] = index++;\n\tsolAssert(!indices.count(CompilerContext::yulUtilityFileName()), \"\");\n\tindices[CompilerContext::yulUtilityFileName()] = index++;\n\treturn indices;\n}\n\nJson const& CompilerStack::contractABI(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\treturn contractABI(contract(_contractName));\n}\n\nJson const& CompilerStack::contractABI(Contract const& _contract) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\tsolAssert(_contract.contract);\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\treturn _contract.abi.init([&]{ return ABI::generate(*_contract.contract); });\n}\n\nJson const& CompilerStack::storageLayout(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\treturn storageLayout(contract(_contractName));\n}\n\nJson const& CompilerStack::storageLayout(Contract const& _contract) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\tsolAssert(_contract.contract);\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\n\treturn _contract.storageLayout.init([&]{ return StorageLayout().generate(*_contract.contract, DataLocation::Storage); });\n}\n\nJson const& CompilerStack::transientStorageLayout(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\treturn transientStorageLayout(contract(_contractName));\n}\n\nJson const& CompilerStack::transientStorageLayout(Contract const& _contract) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\tsolAssert(_contract.contract);\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\n\treturn _contract.transientStorageLayout.init([&]{ return StorageLayout().generate(*_contract.contract, DataLocation::Transient); });\n}\n\nJson const& CompilerStack::natspecUser(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\treturn natspecUser(contract(_contractName));\n}\n\nJson const& CompilerStack::natspecUser(Contract const& _contract) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\tsolAssert(_contract.contract);\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\treturn _contract.userDocumentation.init([&]{ return Natspec::userDocumentation(*_contract.contract); });\n}\n\nJson const& CompilerStack::natspecDev(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\treturn natspecDev(contract(_contractName));\n}\n\nJson const& CompilerStack::natspecDev(Contract const& _contract) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\tsolAssert(_contract.contract);\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\treturn _contract.devDocumentation.init([&]{ return Natspec::devDocumentation(*_contract.contract); });\n}\n\nJson CompilerStack::interfaceSymbols(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\n\tJson interfaceSymbols;\n\t// Always have a methods object\n\tinterfaceSymbols[\"methods\"] = Json::object();\n\n\tfor (auto const& it: contractDefinition(_contractName).interfaceFunctions())\n\t\tinterfaceSymbols[\"methods\"][it.second->externalSignature()] = it.first.hex();\n\tfor (ErrorDefinition const* error: contractDefinition(_contractName).interfaceErrors())\n\t{\n\t\tstd::string signature = error->functionType(true)->externalSignature();\n\t\tinterfaceSymbols[\"errors\"][signature] = util::toHex(toCompactBigEndian(util::selectorFromSignatureU32(signature), 4));\n\t}\n\n\tfor (EventDefinition const* event: ranges::concat_view(\n\t\tcontractDefinition(_contractName).definedInterfaceEvents(),\n\t\tcontractDefinition(_contractName).usedInterfaceEvents()\n\t))\n\t\tif (!event->isAnonymous())\n\t\t{\n\t\t\tstd::string signature = event->functionType(true)->externalSignature();\n\t\t\tinterfaceSymbols[\"events\"][signature] = toHex(u256(h256::Arith(util::keccak256(signature))));\n\t\t}\n\n\treturn interfaceSymbols;\n}\n\nJson CompilerStack::ethdebug() const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\tsolAssert(!m_contracts.empty());\n\treturn evmasm::ethdebug::resources(sourceNames(), VersionString);\n}\n\nJson CompilerStack::ethdebug(std::string const& _contractName) const\n{\n\treturn ethdebug(contract(_contractName), /* runtime */ false);\n}\n\nJson CompilerStack::ethdebugRuntime(std::string const& _contractName) const\n{\n\treturn ethdebug(contract(_contractName), /* runtime */ true);\n}\n\nJson CompilerStack::ethdebug(Contract const& _contract, bool _runtime) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\tsolAssert(_contract.contract);\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\tevmasm::LinkerObject const& object = _runtime ? _contract.runtimeObject : _contract.object;\n\tstd::shared_ptr<evmasm::Assembly> const& assembly = _runtime ? _contract.evmRuntimeAssembly : _contract.evmAssembly;\n\tif (!assembly)\n\t\treturn {};\n\n\tsolAssert(sourceIndices().contains(_contract.contract->sourceUnitName()));\n\treturn evmasm::ethdebug::program(_contract.contract->name(), sourceIndices()[_contract.contract->sourceUnitName()], *assembly, object);\n}\n\nbytes CompilerStack::cborMetadata(std::string const& _contractName, bool _forIR) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\treturn createCBORMetadata(contract(_contractName), _forIR);\n}\n\nstd::string const& CompilerStack::metadata(Contract const& _contract) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\tsolAssert(_contract.contract);\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\treturn _contract.metadata.init([&]{ return createMetadata(_contract, m_viaIR); });\n}\n\nCharStream const& CompilerStack::charStream(std::string const& _sourceName) const\n{\n\tsolAssert(m_stackState >= SourcesSet, \"No sources set.\");\n\tsolAssert(source(_sourceName).charStream);\n\treturn *source(_sourceName).charStream;\n}\n\nSourceUnit const& CompilerStack::ast(std::string const& _sourceName) const\n{\n\tsolAssert(m_stackState >= Parsed, \"Parsing not yet performed.\");\n\tsolAssert(source(_sourceName).ast, \"Parsing was not successful.\");\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\treturn *source(_sourceName).ast;\n}\n\nContractDefinition const& CompilerStack::contractDefinition(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\n\treturn *contract(_contractName).contract;\n}\n\nsize_t CompilerStack::functionEntryPoint(\n\tstd::string const& _contractName,\n\tFunctionDefinition const& _function\n) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\n\tfor (auto&& [name, data]: contract(_contractName).runtimeObject.functionDebugData)\n\t\tif (data.sourceID == _function.id())\n\t\t\tif (data.instructionIndex)\n\t\t\t\treturn *data.instructionIndex;\n\treturn 0;\n}\n\nh256 const& CompilerStack::Source::keccak256() const\n{\n\tif (keccak256HashCached == h256{})\n\t\tkeccak256HashCached = util::keccak256(charStream->source());\n\treturn keccak256HashCached;\n}\n\nh256 const& CompilerStack::Source::swarmHash() const\n{\n\tif (swarmHashCached == h256{})\n\t\tswarmHashCached = util::bzzr1Hash(charStream->source());\n\treturn swarmHashCached;\n}\n\nstd::string const& CompilerStack::Source::ipfsUrl() const\n{\n\tif (ipfsUrlCached.empty())\n\t\tipfsUrlCached = \"dweb:/ipfs/\" + util::ipfsHashBase58(charStream->source());\n\treturn ipfsUrlCached;\n}\n\nStringMap CompilerStack::loadMissingSources(SourceUnit const& _ast)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"\");\n\tStringMap newSources;\n\ttry\n\t{\n\t\tfor (auto const& node: _ast.nodes())\n\t\t\tif (ImportDirective const* import = dynamic_cast<ImportDirective*>(node.get()))\n\t\t\t{\n\t\t\t\tstd::string const& importPath = *import->annotation().absolutePath;\n\n\t\t\t\tif (m_sources.count(importPath) || newSources.count(importPath))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tReadCallback::Result result{false, std::string(\"File not supplied initially.\")};\n\t\t\t\tif (m_readFile)\n\t\t\t\t\tresult = m_readFile(ReadCallback::kindString(ReadCallback::Kind::ReadFile), importPath);\n\n\t\t\t\tif (result.success)\n\t\t\t\t\tnewSources[importPath] = result.responseOrErrorMessage;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tm_errorReporter.parserError(\n\t\t\t\t\t\t6275_error,\n\t\t\t\t\t\timport->location(),\n\t\t\t\t\t\tstd::string(\"Source \\\"\" + importPath + \"\\\" not found: \" + result.responseOrErrorMessage)\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t}\n\tcatch (FatalError const&)\n\t{\n\t\tif (!m_errorReporter.hasErrors())\n\t\t{\n\t\t\tstd::cerr << \"Unreported fatal error:\" << std::endl;\n\t\t\tstd::cerr << boost::current_exception_diagnostic_information() << std::endl;\n\t\t\tsolAssert(false, \"Unreported fatal error.\");\n\t\t}\n\t}\n\treturn newSources;\n}\n\nstd::string CompilerStack::applyRemapping(std::string const& _path, std::string const& _context)\n{\n\tsolAssert(m_stackState < ParsedAndImported, \"\");\n\treturn m_importRemapper.apply(_path, _context);\n}\n\nbool CompilerStack::resolveImports()\n{\n\tsolAssert(m_stackState == ParsedAndImported, \"\");\n\n\t// topological sorting (depth first search) of the import graph, cutting potential cycles\n\tstd::vector<Source const*> sourceOrder;\n\tstd::set<Source const*> sourcesSeen;\n\n\tstd::function<void(Source const*)> toposort = [&](Source const* _source)\n\t{\n\t\tif (sourcesSeen.count(_source))\n\t\t\treturn;\n\t\tsourcesSeen.insert(_source);\n\t\tsolAssert(_source->ast);\n\t\tfor (ASTPointer<ASTNode> const& node: _source->ast->nodes())\n\t\t\tif (ImportDirective const* import = dynamic_cast<ImportDirective*>(node.get()))\n\t\t\t{\n\t\t\t\tstd::string const& path = *import->annotation().absolutePath;\n\t\t\t\tsolAssert(m_sources.count(path), \"\");\n\t\t\t\timport->annotation().sourceUnit = m_sources[path].ast.get();\n\t\t\t\ttoposort(&m_sources[path]);\n\t\t\t}\n\t\tsourceOrder.push_back(_source);\n\t};\n\n\tstd::vector<PragmaDirective const*> experimentalPragmaDirectives;\n\tfor (auto const& sourcePair: m_sources)\n\t{\n\t\tif (isRequestedSource(sourcePair.first))\n\t\t\ttoposort(&sourcePair.second);\n\t\tif (sourcePair.second.ast && sourcePair.second.ast->experimentalSolidity())\n\t\t\tfor (ASTPointer<ASTNode> const& node: sourcePair.second.ast->nodes())\n\t\t\t\tif (PragmaDirective const* pragma = dynamic_cast<PragmaDirective*>(node.get()))\n\t\t\t\t\tif (pragma->literals().size() >=2 && pragma->literals()[0] == \"experimental\" && pragma->literals()[1] == \"solidity\")\n\t\t\t\t\t{\n\t\t\t\t\t\texperimentalPragmaDirectives.push_back(pragma);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t}\n\n\tif (!experimentalPragmaDirectives.empty() && experimentalPragmaDirectives.size() != m_sources.size())\n\t{\n\t\tfor (auto &&pragma: experimentalPragmaDirectives)\n\t\t\tm_errorReporter.parserError(\n\t\t\t\t\t2141_error,\n\t\t\t\t\tpragma->location(),\n\t\t\t\t\t\"File declares \\\"pragma experimental solidity\\\". If you want to enable the experimental mode, all source units must include the pragma.\"\n\t\t\t);\n\t\treturn false;\n\t}\n\n\tswap(m_sourceOrder, sourceOrder);\n\treturn true;\n}\n\nvoid CompilerStack::storeContractDefinitions()\n{\n\tfor (auto const& pair: m_sources)\n\t\tif (pair.second.ast)\n\t\t\tfor (\n\t\t\t\tContractDefinition const* contract:\n\t\t\t\tASTNode::filteredNodes<ContractDefinition>(pair.second.ast->nodes())\n\t\t\t)\n\t\t\t{\n\t\t\t\tstd::string fullyQualifiedName = *pair.second.ast->annotation().path + \":\" + contract->name();\n\t\t\t\t// Note that we now reference contracts by their fully qualified names, and\n\t\t\t\t// thus contracts can only conflict if declared in the same source file. This\n\t\t\t\t// should already cause a double-declaration error elsewhere.\n\t\t\t\tif (!m_contracts.count(fullyQualifiedName))\n\t\t\t\t\tm_contracts[fullyQualifiedName].contract = contract;\n\t\t\t}\n}\n\nvoid CompilerStack::annotateInternalFunctionIDs()\n{\n\tfor (Source const* source: m_sourceOrder)\n\t{\n\t\tif (!source->ast)\n\t\t\tcontinue;\n\n\t\tfor (ContractDefinition const* contract: ASTNode::filteredNodes<ContractDefinition>(source->ast->nodes()))\n\t\t{\n\t\t\tuint64_t internalFunctionID = 1;\n\t\t\tContractDefinitionAnnotation& annotation = contract->annotation();\n\n\t\t\tif (auto const* deployTimeInternalDispatch = util::valueOrNullptr((*annotation.deployedCallGraph)->edges, CallGraph::SpecialNode::InternalDispatch))\n\t\t\t\tfor (auto const& node: *deployTimeInternalDispatch)\n\t\t\t\t\tif (auto const* callable = std::get_if<CallableDeclaration const*>(&node))\n\t\t\t\t\t\tif (auto const* function = dynamic_cast<FunctionDefinition const*>(*callable))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsolAssert(contract->annotation().internalFunctionIDs.count(function) == 0);\n\t\t\t\t\t\t\tcontract->annotation().internalFunctionIDs[function] = internalFunctionID++;\n\t\t\t\t\t\t}\n\t\t\tif (auto const* creationTimeInternalDispatch = util::valueOrNullptr((*annotation.creationCallGraph)->edges, CallGraph::SpecialNode::InternalDispatch))\n\t\t\t\tfor (auto const& node: *creationTimeInternalDispatch)\n\t\t\t\t\tif (auto const* callable = std::get_if<CallableDeclaration const*>(&node))\n\t\t\t\t\t\tif (auto const* function = dynamic_cast<FunctionDefinition const*>(*callable))\n\t\t\t\t\t\t\t// Make sure the function already got an ID since it also occurs in the deploy-time internal dispatch.\n\t\t\t\t\t\t\tsolAssert(contract->annotation().internalFunctionIDs.count(function) != 0);\n\t\t}\n\t}\n}\n\nvoid CompilerStack::assembleYul(\n\tContractDefinition const& _contract,\n\tstd::shared_ptr<evmasm::Assembly> _assembly,\n\tstd::shared_ptr<evmasm::Assembly> _runtimeAssembly\n)\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"\");\n\n\tContract& compiledContract = m_contracts.at(_contract.fullyQualifiedName());\n\n\tcompiledContract.evmAssembly = _assembly;\n\tsolAssert(compiledContract.evmAssembly, \"\");\n\ttry\n\t{\n\t\t// Assemble deployment (incl. runtime)  object.\n\t\tcompiledContract.object = compiledContract.evmAssembly->assemble();\n\t}\n\tcatch (evmasm::AssemblyException const& error)\n\t{\n\t\tsolAssert(false, \"Assembly exception for bytecode: \"s + error.what());\n\t}\n\tsolAssert(compiledContract.object.immutableReferences.empty(), \"Leftover immutables.\");\n\n\tcompiledContract.evmRuntimeAssembly = _runtimeAssembly;\n\tsolAssert(compiledContract.evmRuntimeAssembly, \"\");\n\ttry\n\t{\n\t\t// Assemble runtime object.\n\t\tcompiledContract.runtimeObject = compiledContract.evmRuntimeAssembly->assemble();\n\t}\n\tcatch (evmasm::AssemblyException const& error)\n\t{\n\t\tsolAssert(false, \"Assembly exception for deployed bytecode\"s + error.what());\n\t}\n\n\t// Throw a warning if EIP-170 limits are exceeded:\n\t//   If contract creation returns data with length greater than 0x6000 (2^14 + 2^13) bytes,\n\t//   contract creation fails with an out of gas error.\n\tif (\n\t\tm_evmVersion >= langutil::EVMVersion::spuriousDragon() &&\n\t\tcompiledContract.runtimeObject.bytecode.size() > 0x6000\n\t)\n\t\tm_errorReporter.warning(\n\t\t\t5574_error,\n\t\t\t_contract.location(),\n\t\t\t\"Contract code size is \"s +\n\t\t\tstd::to_string(compiledContract.runtimeObject.bytecode.size()) +\n\t\t\t\" bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). \"\n\t\t\t\"This contract may not be deployable on Mainnet. \"\n\t\t\t\"Consider enabling the optimizer (with a low \\\"runs\\\" value!), \"\n\t\t\t\"turning off revert strings, or using libraries.\"\n\t\t);\n\n\t// Throw a warning if EIP-3860 limits are exceeded:\n\t//   If initcode is larger than 0xC000 bytes (twice the runtime code limit),\n\t//   then contract creation fails with an out of gas error.\n\tif (\n\t\tm_evmVersion >= langutil::EVMVersion::shanghai() &&\n\t\tcompiledContract.object.bytecode.size() > 0xC000\n\t)\n\t\tm_errorReporter.warning(\n\t\t\t3860_error,\n\t\t\t_contract.location(),\n\t\t\t\"Contract initcode size is \"s +\n\t\t\tstd::to_string(compiledContract.object.bytecode.size()) +\n\t\t\t\" bytes and exceeds 49152 bytes (a limit introduced in Shanghai). \"\n\t\t\t\"This contract may not be deployable on Mainnet. \"\n\t\t\t\"Consider enabling the optimizer (with a low \\\"runs\\\" value!), \"\n\t\t\t\"turning off revert strings, or using libraries.\"\n\t\t);\n}\n\nvoid CompilerStack::compileContract(\n\tContractDefinition const& _contract,\n\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>>& _otherCompilers\n)\n{\n\tsolAssert(!m_viaIR, \"\");\n\tsolUnimplementedAssert(!m_eofVersion.has_value(), \"Experimental EOF support is only available for via-IR compilation.\");\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"\");\n\n\tif (_otherCompilers.count(&_contract))\n\t\treturn;\n\n\tfor (auto const& [dependency, referencee]: _contract.annotation().contractDependencies)\n\t\tcompileContract(*dependency, _otherCompilers);\n\n\tif (!_contract.canBeDeployed())\n\t\treturn;\n\n\tContract& compiledContract = m_contracts.at(_contract.fullyQualifiedName());\n\n\tstd::shared_ptr<Compiler> compiler = std::make_shared<Compiler>(\n\t\tm_evmVersion,\n\t\tm_eofVersion,\n\t\tm_revertStrings,\n\t\tm_optimiserSettings\n\t);\n\n\tsolAssert(!m_viaIR, \"\");\n\tbytes cborEncodedMetadata = createCBORMetadata(compiledContract, /* _forIR */ false);\n\n\t// Run optimiser and compile the contract.\n\tcompiler->compileContract(_contract, _otherCompilers, cborEncodedMetadata);\n\tcompiledContract.generatedYulUtilityCode = compiler->generatedYulUtilityCode();\n\tcompiledContract.runtimeGeneratedYulUtilityCode = compiler->runtimeGeneratedYulUtilityCode();\n\n\t_otherCompilers[compiledContract.contract] = compiler;\n\n\tassembleYul(_contract, compiler->assemblyPtr(), compiler->runtimeAssemblyPtr());\n}\n\nvoid CompilerStack::generateIR(ContractDefinition const& _contract, bool _unoptimizedOnly)\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"\");\n\tContract& compiledContract = m_contracts.at(_contract.fullyQualifiedName());\n\tif (compiledContract.yulIR)\n\t{\n\t\tsolAssert(!compiledContract.yulIR->empty());\n\t\treturn;\n\t}\n\n\tif (!*_contract.sourceUnit().annotation().useABICoderV2)\n\t\tm_errorReporter.warning(\n\t\t\t2066_error,\n\t\t\t_contract.location(),\n\t\t\t\"Contract requests the ABI coder v1, which is incompatible with the IR. \"\n\t\t\t\"Using ABI coder v2 instead.\"\n\t\t);\n\n\tstd::string dependenciesSource;\n\tfor (auto const& [dependency, referencee]: _contract.annotation().contractDependencies)\n\t\tgenerateIR(*dependency, _unoptimizedOnly);\n\n\tif (!_contract.canBeDeployed())\n\t\treturn;\n\n\tstd::map<ContractDefinition const*, std::string_view const> otherYulSources;\n\tfor (auto const& pair: m_contracts)\n\t\totherYulSources.emplace(pair.second.contract, pair.second.yulIR ? *pair.second.yulIR : std::string_view{});\n\n\tif (m_experimentalAnalysis)\n\t{\n\t\texperimental::IRGenerator generator(\n\t\t\tm_evmVersion,\n\t\t\tm_eofVersion,\n\t\t\tm_revertStrings,\n\t\t\tsourceIndices(),\n\t\t\tm_debugInfoSelection,\n\t\t\tthis,\n\t\t\t*m_experimentalAnalysis\n\t\t);\n\t\tcompiledContract.yulIR = generator.run(\n\t\t\t_contract,\n\t\t\t{}, // TODO: createCBORMetadata(compiledContract, /* _forIR */ true),\n\t\t\totherYulSources\n\t\t);\n\t}\n\telse\n\t{\n\t\tIRGenerator generator(\n\t\t\tm_evmVersion,\n\t\t\tm_eofVersion,\n\t\t\tm_revertStrings,\n\t\t\tsourceIndices(),\n\t\t\tm_debugInfoSelection,\n\t\t\tthis,\n\t\t\tm_optimiserSettings\n\t\t);\n\t\tcompiledContract.yulIR = generator.run(\n\t\t\t_contract,\n\t\t\tcreateCBORMetadata(compiledContract, /* _forIR */ true),\n\t\t\totherYulSources\n\t\t);\n\t}\n\n\tyulAssert(compiledContract.yulIR);\n\tYulStack stack = loadGeneratedIR(*compiledContract.yulIR);\n\tif (!_unoptimizedOnly)\n\t{\n\t\tstack.optimize();\n\t\tcompiledContract.yulIROptimized = stack.print();\n\t}\n}\n\nvoid CompilerStack::generateEVMFromIR(ContractDefinition const& _contract)\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"\");\n\n\tif (!_contract.canBeDeployed())\n\t\treturn;\n\n\tContract& compiledContract = m_contracts.at(_contract.fullyQualifiedName());\n\tsolAssert(compiledContract.yulIROptimized);\n\tsolAssert(!compiledContract.yulIROptimized->empty());\n\tif (!compiledContract.object.bytecode.empty())\n\t\treturn;\n\n\t// Re-parse the Yul IR in EVM dialect\n\tYulStack stack = loadGeneratedIR(*compiledContract.yulIROptimized);\n\n\tstd::string deployedName = IRNames::deployedObject(_contract);\n\tsolAssert(!deployedName.empty(), \"\");\n\ttie(compiledContract.evmAssembly, compiledContract.evmRuntimeAssembly) = stack.assembleEVMWithDeployed(deployedName, m_viaSSACFG);\n\n\tif (stack.hasErrors())\n\t{\n\t\tfor (std::shared_ptr<Error const> const& error: stack.errors())\n\t\t\treportIRPostAnalysisError(error.get(), compiledContract.contract);\n\t\treturn;\n\t}\n\n\tassembleYul(_contract, compiledContract.evmAssembly, compiledContract.evmRuntimeAssembly);\n}\n\nCompilerStack::Contract const& CompilerStack::contract(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState >= AnalysisSuccessful, \"\");\n\n\tauto it = m_contracts.find(_contractName);\n\tif (it != m_contracts.end())\n\t\treturn it->second;\n\n\t// To provide a measure of backward-compatibility, if a contract is not located by its\n\t// fully-qualified name, a lookup will be attempted purely on the contract's name to see\n\t// if anything will satisfy.\n\tif (_contractName.find(':') == std::string::npos)\n\t{\n\t\tfor (auto const& contractEntry: m_contracts)\n\t\t{\n\t\t\tstd::stringstream ss;\n\t\t\tss.str(contractEntry.first);\n\t\t\t// All entries are <source>:<contract>\n\t\t\tstd::string source;\n\t\t\tstd::string foundName;\n\t\t\tgetline(ss, source, ':');\n\t\t\tgetline(ss, foundName, ':');\n\t\t\tif (foundName == _contractName)\n\t\t\t\treturn contractEntry.second;\n\t\t}\n\t}\n\n\t// If we get here, both lookup methods failed.\n\tsolAssert(false, \"Contract \\\"\" + _contractName + \"\\\" not found.\");\n}\n\nCompilerStack::Source const& CompilerStack::source(std::string const& _sourceName) const\n{\n\tauto it = m_sources.find(_sourceName);\n\tsolAssert(it != m_sources.end(), \"Given source file not found: \" + _sourceName);\n\n\treturn it->second;\n}\n\nstd::string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) const\n{\n\tJson meta;\n\tmeta[\"version\"] = 1;\n\tstd::string sourceType;\n\tswitch (m_compilationSourceType)\n\t{\n\tcase CompilationSourceType::Solidity:\n\t\tsourceType = \"Solidity\";\n\t\tbreak;\n\tcase CompilationSourceType::SolidityAST:\n\t\tsourceType = \"SolidityAST\";\n\t\tbreak;\n\t}\n\tmeta[\"language\"] = sourceType;\n\tmeta[\"compiler\"][\"version\"] = VersionStringStrict;\n\n\t/// All the source files (including self), which should be included in the metadata.\n\tstd::set<std::string> referencedSources;\n\treferencedSources.insert(*_contract.contract->sourceUnit().annotation().path);\n\tfor (auto const sourceUnit: _contract.contract->sourceUnit().referencedSourceUnits(true))\n\t\treferencedSources.insert(*sourceUnit->annotation().path);\n\n\tmeta[\"sources\"] = Json::object();\n\tfor (auto const& s: m_sources)\n\t{\n\t\tif (!referencedSources.count(s.first))\n\t\t\tcontinue;\n\n\t\tsolAssert(s.second.charStream, \"Character stream not available\");\n\t\tmeta[\"sources\"][s.first][\"keccak256\"] = \"0x\" + util::toHex(s.second.keccak256().asBytes());\n\t\tif (std::optional<std::string> licenseString = s.second.ast->licenseString())\n\t\t\tmeta[\"sources\"][s.first][\"license\"] = *licenseString;\n\t\tif (m_metadataLiteralSources)\n\t\t\tmeta[\"sources\"][s.first][\"content\"] = s.second.charStream->source();\n\t\telse\n\t\t{\n\t\t\tmeta[\"sources\"][s.first][\"urls\"] = Json::array();\n\t\t\tmeta[\"sources\"][s.first][\"urls\"].emplace_back(\"bzz-raw://\" + util::toHex(s.second.swarmHash().asBytes()));\n\t\t\tmeta[\"sources\"][s.first][\"urls\"].emplace_back(s.second.ipfsUrl());\n\t\t}\n\t}\n\n\tstatic_assert(sizeof(m_optimiserSettings.expectedExecutionsPerDeployment) <= sizeof(Json::number_integer_t), \"Invalid word size.\");\n\tsolAssert(static_cast<Json::number_integer_t>(m_optimiserSettings.expectedExecutionsPerDeployment) < std::numeric_limits<Json::number_integer_t>::max(), \"\");\n\tmeta[\"settings\"][\"optimizer\"][\"runs\"] = Json::number_integer_t(m_optimiserSettings.expectedExecutionsPerDeployment);\n\n\t/// Backwards compatibility: If set to one of the default settings, do not provide details.\n\tOptimiserSettings settingsWithoutRuns = m_optimiserSettings;\n\t// reset to default\n\tsettingsWithoutRuns.expectedExecutionsPerDeployment = OptimiserSettings::minimal().expectedExecutionsPerDeployment;\n\tif (settingsWithoutRuns == OptimiserSettings::minimal())\n\t\tmeta[\"settings\"][\"optimizer\"][\"enabled\"] = false;\n\telse if (settingsWithoutRuns == OptimiserSettings::standard())\n\t\tmeta[\"settings\"][\"optimizer\"][\"enabled\"] = true;\n\telse\n\t{\n\t\tJson details = Json::object();\n\n\t\tdetails[\"orderLiterals\"] = m_optimiserSettings.runOrderLiterals;\n\t\tdetails[\"inliner\"] = m_optimiserSettings.runInliner;\n\t\tdetails[\"jumpdestRemover\"] = m_optimiserSettings.runJumpdestRemover;\n\t\tdetails[\"peephole\"] = m_optimiserSettings.runPeephole;\n\t\tdetails[\"deduplicate\"] = m_optimiserSettings.runDeduplicate;\n\t\tdetails[\"cse\"] = m_optimiserSettings.runCSE;\n\t\tdetails[\"constantOptimizer\"] = m_optimiserSettings.runConstantOptimiser;\n\t\tdetails[\"simpleCounterForLoopUncheckedIncrement\"] = m_optimiserSettings.simpleCounterForLoopUncheckedIncrement;\n\t\tdetails[\"yul\"] = m_optimiserSettings.runYulOptimiser;\n\t\tif (m_optimiserSettings.runYulOptimiser)\n\t\t{\n\t\t\tdetails[\"yulDetails\"] = Json::object();\n\t\t\tdetails[\"yulDetails\"][\"stackAllocation\"] = m_optimiserSettings.optimizeStackAllocation;\n\t\t\tdetails[\"yulDetails\"][\"optimizerSteps\"] = m_optimiserSettings.yulOptimiserSteps + \":\" + m_optimiserSettings.yulOptimiserCleanupSteps;\n\t\t}\n\t\telse if (OptimiserSuite::isEmptyOptimizerSequence(m_optimiserSettings.yulOptimiserSteps + \":\" + m_optimiserSettings.yulOptimiserCleanupSteps))\n\t\t{\n\t\t\tsolAssert(m_optimiserSettings.optimizeStackAllocation == false);\n\t\t\tdetails[\"yulDetails\"] = Json::object();\n\t\t\tdetails[\"yulDetails\"][\"optimizerSteps\"] = \":\";\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsolAssert(m_optimiserSettings.optimizeStackAllocation == false);\n\t\t\tsolAssert(m_optimiserSettings.yulOptimiserSteps == OptimiserSettings::DefaultYulOptimiserSteps);\n\t\t\tsolAssert(m_optimiserSettings.yulOptimiserCleanupSteps == OptimiserSettings::DefaultYulOptimiserCleanupSteps);\n\t\t}\n\n\t\tmeta[\"settings\"][\"optimizer\"][\"details\"] = std::move(details);\n\t}\n\n\tif (m_revertStrings != RevertStrings::Default)\n\t\tmeta[\"settings\"][\"debug\"][\"revertStrings\"] = revertStringsToString(m_revertStrings);\n\n\tif (m_metadataFormat == MetadataFormat::NoMetadata)\n\t\tmeta[\"settings\"][\"metadata\"][\"appendCBOR\"] = false;\n\n\tif (m_metadataLiteralSources)\n\t\tmeta[\"settings\"][\"metadata\"][\"useLiteralContent\"] = true;\n\n\tstatic std::vector<std::string> hashes{\"ipfs\", \"bzzr1\", \"none\"};\n\tmeta[\"settings\"][\"metadata\"][\"bytecodeHash\"] = hashes.at(unsigned(m_metadataHash));\n\n\tif (_forIR)\n\t\tmeta[\"settings\"][\"viaIR\"] = _forIR;\n\tmeta[\"settings\"][\"evmVersion\"] = m_evmVersion.name();\n\tif (m_experimental)\n\t\tmeta[\"settings\"][\"experimental\"] = m_experimental;\n\tif (m_eofVersion.has_value())\n\t\tmeta[\"settings\"][\"eofVersion\"] = *m_eofVersion;\n\tif (m_viaSSACFG)\n\t\tmeta[\"settings\"][\"viaSSACFG\"] = m_viaSSACFG;\n\tmeta[\"settings\"][\"compilationTarget\"][_contract.contract->sourceUnitName()] =\n\t\t*_contract.contract->annotation().canonicalName;\n\n\tmeta[\"settings\"][\"remappings\"] = Json::array();\n\tstd::set<std::string> remappings;\n\tfor (auto const& r: m_importRemapper.remappings())\n\t\tremappings.insert(r.context + \":\" + r.prefix + \"=\" + r.target);\n\tfor (auto const& r: remappings)\n\t\tmeta[\"settings\"][\"remappings\"].emplace_back(r);\n\n\tmeta[\"settings\"][\"libraries\"] = Json::object();\n\tfor (auto const& library: m_libraries)\n\t\tmeta[\"settings\"][\"libraries\"][library.first] = \"0x\" + util::toHex(library.second.asBytes());\n\n\tmeta[\"output\"][\"abi\"] = contractABI(_contract);\n\tmeta[\"output\"][\"userdoc\"] = natspecUser(_contract);\n\tmeta[\"output\"][\"devdoc\"] = natspecDev(_contract);\n\n\treturn util::jsonCompactPrint(meta);\n}\n\nclass MetadataCBOREncoder\n{\npublic:\n\tvoid pushBytes(std::string const& key, bytes const& value)\n\t{\n\t\tm_entryCount++;\n\t\tpushTextString(key);\n\t\tpushByteString(value);\n\t}\n\n\tvoid pushString(std::string const& key, std::string const& value)\n\t{\n\t\tm_entryCount++;\n\t\tpushTextString(key);\n\t\tpushTextString(value);\n\t}\n\n\tvoid pushBool(std::string const& key, bool value)\n\t{\n\t\tm_entryCount++;\n\t\tpushTextString(key);\n\t\tpushBool(value);\n\t}\n\n\tbytes serialise() const\n\t{\n\t\tsize_t size = m_data.size() + 1;\n\t\tsolAssert(size <= 0xffff, \"Metadata too large.\");\n\t\tsolAssert(m_entryCount <= 0x1f, \"Too many map entries.\");\n\n\t\t// CBOR fixed-length map\n\t\tbytes ret{static_cast<unsigned char>(0xa0 + m_entryCount)};\n\t\t// The already encoded key-value pairs\n\t\tret += m_data;\n\t\t// 16-bit big endian length\n\t\tret += toCompactBigEndian(size, 2);\n\t\treturn ret;\n\t}\n\nprivate:\n\tvoid pushTextString(std::string const& key)\n\t{\n\t\tsize_t length = key.size();\n\t\tif (length < 24)\n\t\t{\n\t\t\tm_data += bytes{static_cast<unsigned char>(0x60 + length)};\n\t\t\tm_data += key;\n\t\t}\n\t\telse if (length <= 256)\n\t\t{\n\t\t\tm_data += bytes{0x78, static_cast<unsigned char>(length)};\n\t\t\tm_data += key;\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"Text std::string too large.\");\n\t}\n\tvoid pushByteString(bytes const& key)\n\t{\n\t\tsize_t length = key.size();\n\t\tif (length < 24)\n\t\t{\n\t\t\tm_data += bytes{static_cast<unsigned char>(0x40 + length)};\n\t\t\tm_data += key;\n\t\t}\n\t\telse if (length <= 256)\n\t\t{\n\t\t\tm_data += bytes{0x58, static_cast<unsigned char>(length)};\n\t\t\tm_data += key;\n\t\t}\n\t\telse\n\t\t\tsolAssert(false, \"Byte std::string too large.\");\n\t}\n\tvoid pushBool(bool value)\n\t{\n\t\tif (value)\n\t\t\tm_data += bytes{0xf5};\n\t\telse\n\t\t\tm_data += bytes{0xf4};\n\t}\n\tunsigned m_entryCount = 0;\n\tbytes m_data;\n};\n\nbytes CompilerStack::createCBORMetadata(Contract const& _contract, bool _forIR) const\n{\n\tif (m_metadataFormat == MetadataFormat::NoMetadata)\n\t\treturn bytes{};\n\n\tbool const usesExperimentalSyntax = !_contract.contract->sourceUnit().annotation().experimentalFeatures.empty();\n\tbool const onlySafeExperimentalFeatures = onlySafeExperimentalFeaturesActivated(\n\t\t_contract.contract->sourceUnit().annotation().experimentalFeatures\n\t);\n\n\tif (m_eofVersion.has_value() || (usesExperimentalSyntax && !onlySafeExperimentalFeatures))\n\t\tsolAssert(m_experimental, \"Experimental mode not enabled\");\n\n\tstd::string meta = (_forIR == m_viaIR ? metadata(_contract) : createMetadata(_contract, _forIR));\n\n\tMetadataCBOREncoder encoder;\n\n\tif (m_metadataHash == MetadataHash::IPFS)\n\t\tencoder.pushBytes(\"ipfs\", util::ipfsHash(meta));\n\telse if (m_metadataHash == MetadataHash::Bzzr1)\n\t\tencoder.pushBytes(\"bzzr1\", util::bzzr1Hash(meta).asBytes());\n\telse\n\t\tsolAssert(m_metadataHash == MetadataHash::None, \"Invalid metadata hash\");\n\n\tif (m_experimental)\n\t\tencoder.pushBool(\"experimental\", true);\n\tif (m_metadataFormat == MetadataFormat::WithReleaseVersionTag)\n\t\tencoder.pushBytes(\"solc\", VersionCompactBytes);\n\telse\n\t{\n\t\tsolAssert(\n\t\t\tm_metadataFormat == MetadataFormat::WithPrereleaseVersionTag,\n\t\t\t\"Invalid metadata format.\"\n\t\t);\n\t\tencoder.pushString(\"solc\", VersionStringStrict);\n\t}\n\treturn encoder.serialise();\n}\n\nnamespace\n{\n\nJson gasToJson(GasEstimator::GasConsumption const& _gas)\n{\n\tif (_gas.isInfinite)\n\t\treturn Json(\"infinite\");\n\telse\n\t\treturn Json(util::toString(_gas.value));\n}\n\n}\n\nJson CompilerStack::gasEstimates(std::string const& _contractName) const\n{\n\tsolAssert(m_stackState == CompilationSuccessful, \"Compilation was not successful.\");\n\tsolUnimplementedAssert(!isExperimentalSolidity());\n\n\tif (!assemblyItems(_contractName) && !runtimeAssemblyItems(_contractName))\n\t\treturn Json();\n\n\tusing Gas = GasEstimator::GasConsumption;\n\tGasEstimator gasEstimator(m_evmVersion);\n\tJson output = Json::object();\n\n\tif (evmasm::AssemblyItems const* items = assemblyItems(_contractName))\n\t{\n\t\tGas executionGas = gasEstimator.functionalEstimation(*items);\n\t\tGas codeDepositGas{evmasm::GasMeter::dataGas(runtimeObject(_contractName).bytecode, false, m_evmVersion)};\n\n\t\tJson creation = Json::object();\n\t\tcreation[\"codeDepositCost\"] = gasToJson(codeDepositGas);\n\t\tcreation[\"executionCost\"] = gasToJson(executionGas);\n\t\t/// TODO: implement + overload to avoid the need of +=\n\t\texecutionGas += codeDepositGas;\n\t\tcreation[\"totalCost\"] = gasToJson(executionGas);\n\t\toutput[\"creation\"] = creation;\n\t}\n\n\tif (evmasm::AssemblyItems const* items = runtimeAssemblyItems(_contractName))\n\t{\n\t\t/// External functions\n\t\tContractDefinition const& contract = contractDefinition(_contractName);\n\t\tJson externalFunctions = Json::object();\n\t\tfor (auto it: contract.interfaceFunctions())\n\t\t{\n\t\t\tstd::string sig = it.second->externalSignature();\n\t\t\texternalFunctions[sig] = gasToJson(gasEstimator.functionalEstimation(*items, sig));\n\t\t}\n\n\t\tif (contract.fallbackFunction())\n\t\t\t/// This needs to be set to an invalid signature in order to trigger the fallback,\n\t\t\t/// without the shortcut (of CALLDATSIZE == 0), and therefore to receive the upper bound.\n\t\t\t/// An empty string (\"\") would work to trigger the shortcut only.\n\t\t\texternalFunctions[\"\"] = gasToJson(gasEstimator.functionalEstimation(*items, \"INVALID\"));\n\n\t\tif (!externalFunctions.empty())\n\t\t\toutput[\"external\"] = externalFunctions;\n\n\t\t/// Internal functions\n\t\tJson internalFunctions = Json::object();\n\t\tfor (auto const& it: contract.definedFunctions())\n\t\t{\n\t\t\t/// Exclude externally visible functions, constructor, fallback and receive ether function\n\t\t\tif (it->isPartOfExternalInterface() || !it->isOrdinary())\n\t\t\t\tcontinue;\n\n\t\t\tsize_t entry = functionEntryPoint(_contractName, *it);\n\t\t\tGasEstimator::GasConsumption gas = GasEstimator::GasConsumption::infinite();\n\t\t\tif (entry > 0)\n\t\t\t\tgas = gasEstimator.functionalEstimation(*items, entry, *it);\n\n\t\t\t/// TODO: This could move into a method shared with externalSignature()\n\t\t\tFunctionType type(*it);\n\t\t\tstd::string sig = it->name() + \"(\";\n\t\t\tauto paramTypes = type.parameterTypes();\n\t\t\tfor (auto it = paramTypes.begin(); it != paramTypes.end(); ++it)\n\t\t\t\tsig += (*it)->toString() + (it + 1 == paramTypes.end() ? \"\" : \",\");\n\t\t\tsig += \")\";\n\n\t\t\tinternalFunctions[sig] = gasToJson(gas);\n\t\t}\n\n\t\tif (!internalFunctions.empty())\n\t\t\toutput[\"internal\"] = internalFunctions;\n\t}\n\n\treturn output;\n}\n\nbool CompilerStack::isExperimentalSolidity() const\n{\n\treturn\n\t\t!m_sourceOrder.empty() &&\n\t\tranges::all_of(m_sourceOrder, [](auto const* _source) { return _source->ast->experimentalSolidity(); } )\n\t;\n}\n\nexperimental::Analysis const& CompilerStack::experimentalAnalysis() const\n{\n\tsolAssert(!!m_experimentalAnalysis);\n\treturn *m_experimentalAnalysis;\n}\n\nvoid CompilerStack::reportUnimplementedFeatureError(\n\tUnimplementedFeatureError const& _error,\n\tContractDefinition const* _contractDefinition\n)\n{\n\tsolAssert(_error.comment(), \"Errors must include a message for the user.\");\n\tif (_error.sourceLocation().sourceName)\n\t\tsolAssert(m_sources.count(*_error.sourceLocation().sourceName) != 0);\n\n\tm_errorReporter.unimplementedFeatureError(\n\t\t1834_error,\n\t\t(_error.sourceLocation().sourceName || !_contractDefinition) ?\n\t\t\t_error.sourceLocation() :\n\t\t\t_contractDefinition->location(),\n\t\t*_error.comment()\n\t);\n}\n\nvoid CompilerStack::reportCodeGenerationError(Error const& _error, ContractDefinition const* _contractDefinition)\n{\n\tsolAssert(_error.type() == Error::Type::CodeGenerationError);\n\tsolAssert(_error.comment(), \"Errors must include a message for the user.\");\n\tif (_error.sourceLocation() && _error.sourceLocation()->sourceName)\n\t\tsolAssert(m_sources.count(*_error.sourceLocation()->sourceName) != 0);\n\tsolAssert(_contractDefinition);\n\n\tm_errorReporter.codeGenerationError(\n\t\t_error.errorId(),\n\t\t(_error.sourceLocation() && _error.sourceLocation()->sourceName) ?\n\t\t\t*_error.sourceLocation() :\n\t\t\t_contractDefinition->location(),\n\t\t*_error.comment()\n\t);\n}\n\nvoid CompilerStack::reportIRPostAnalysisError(Error const* _error, ContractDefinition const* _contractDefinition)\n{\n\tsolAssert(_error);\n\tsolAssert(_error->comment(), \"Errors must include a message for the user.\");\n\tsolAssert(!_error->secondarySourceLocation());\n\tsolAssert(_contractDefinition);\n\n\t// Do not report Yul warnings and infos. These are only reported in pure Yul compilation.\n\tif (!Error::isError(_error->severity()))\n\t\treturn;\n\n\tm_errorReporter.error(\n\t\t_error->errorId(),\n\t\t_error->type(),\n\t\t// Ignore the original location. It's likely missing, but even if not, it points at Yul source.\n\t\t// CompilerStack can only point at locations in Solidity sources.\n\t\t_contractDefinition->location(),\n\t\t*_error->comment()\n\t);\n}\n"
  },
  {
    "path": "libsolidity/interface/CompilerStack.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @author Gav Wood <g@ethdev.com>\n * @date 2014\n * Full-stack compiler that converts a source code string to bytecode.\n */\n\n#pragma once\n\n#include <libsolidity/analysis/FunctionCallGraph.h>\n#include <libsolidity/interface/ReadFile.h>\n#include <libsolidity/interface/ImportRemapper.h>\n#include <libsolidity/interface/OptimiserSettings.h>\n#include <libsolidity/interface/Version.h>\n#include <libsolidity/interface/DebugSettings.h>\n\n#include <libsolidity/formal/ModelCheckerSettings.h>\n\n#include <libsmtutil/SolverInterface.h>\n\n#include <liblangutil/CharStreamProvider.h>\n#include <liblangutil/DebugInfoSelection.h>\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/EVMVersion.h>\n#include <liblangutil/SourceLocation.h>\n\n#include <libevmasm/AbstractAssemblyStack.h>\n#include <libevmasm/LinkerObject.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/FixedHash.h>\n#include <libsolutil/LazyInit.h>\n#include <libsolutil/JSON.h>\n\n#include <libyul/ObjectOptimizer.h>\n\n#include <functional>\n#include <memory>\n#include <ostream>\n#include <set>\n#include <string>\n#include <vector>\n\nnamespace solidity::langutil\n{\nclass CharStream;\n}\n\n\nnamespace solidity::evmasm\n{\nclass Assembly;\nclass AssemblyItem;\nusing AssemblyItems = std::vector<AssemblyItem>;\n}\n\nnamespace solidity::yul\n{\nclass YulStack;\n}\n\nnamespace solidity::frontend\n{\n\n// forward declarations\nclass ASTNode;\nclass ContractDefinition;\nclass FunctionDefinition;\nclass SourceUnit;\nclass Compiler;\nclass GlobalContext;\nclass Natspec;\nclass DeclarationContainer;\nnamespace experimental\n{\nclass Analysis;\n}\n\n/**\n * Easy to use and self-contained Solidity compiler with as few header dependencies as possible.\n * It holds state and can be used to either step through the compilation stages (and abort e.g.\n * before compilation to bytecode) or run the whole compilation in one call.\n */\nclass CompilerStack: public langutil::CharStreamProvider, public evmasm::AbstractAssemblyStack\n{\npublic:\n\t/// Noncopyable.\n\tCompilerStack(CompilerStack const&) = delete;\n\tCompilerStack& operator=(CompilerStack const&) = delete;\n\n\tenum State {\n\t\tEmpty,\n\t\tSourcesSet,\n\t\tParsed,\n\t\tParsedAndImported,\n\t\tAnalysisSuccessful,\n\t\tCompilationSuccessful\n\t};\n\n\tenum class MetadataFormat {\n\t\tWithReleaseVersionTag,\n\t\tWithPrereleaseVersionTag,\n\t\tNoMetadata\n\t};\n\n\tenum class MetadataHash {\n\t\tIPFS,\n\t\tBzzr1,\n\t\tNone\n\t};\n\n\tenum class CompilationSourceType {\n\t\t/// Regular compilation from Solidity source files.\n\t\tSolidity,\n\t\t/// Compilation from an imported Solidity AST.\n\t\tSolidityAST,\n\t};\n\n\t/// Indicates which stages of the compilation pipeline were explicitly requested and provides\n\t/// logic to determine which ones are effectively needed to accomplish that.\n\t/// Note that parsing and analysis are not selectable, since they cannot be skipped.\n\tstruct PipelineConfig\n\t{\n\t\tbool irCodegen = false;      ///< Want IR output straight from code generator.\n\t\tbool irOptimization = false; ///< Want reparsed IR that went through YulStack. May be optimized or not, depending on settings.\n\t\tbool bytecode = false;       ///< Want EVM-level outputs, especially EVM assembly and bytecode. May be optimized or not, depending on settings.\n\n\t\tbool needIR(bool _viaIR) const\n\t\t{\n\t\t\treturn\n\t\t\t\tirCodegen ||\n\t\t\t\tirOptimization ||\n\t\t\t\t(bytecode && _viaIR);\n\t\t}\n\n\t\tbool needIRCodegenOnly(bool _viaIR) const\n\t\t{\n\t\t\treturn !(bytecode && _viaIR) && !irOptimization;\n\t\t}\n\n\t\tbool needBytecode() const\n\t\t{\n\t\t\treturn bytecode;\n\t\t}\n\n\t\tPipelineConfig operator|(PipelineConfig const& _other) const\n\t\t{\n\t\t\treturn {\n\t\t\t\tirCodegen || _other.irCodegen,\n\t\t\t\tirOptimization || _other.irOptimization,\n\t\t\t\tbytecode || _other.bytecode,\n\t\t\t};\n\t\t}\n\n\t\tbool operator!=(PipelineConfig const& _other) const { return !(*this == _other); }\n\t\tbool operator==(PipelineConfig const& _other) const\n\t\t{\n\t\t\treturn\n\t\t\t\tirCodegen == _other.irCodegen &&\n\t\t\t\tirOptimization == _other.irOptimization &&\n\t\t\t\tbytecode == _other.bytecode;\n\t\t}\n\t};\n\n\tusing ContractSelection = std::map<std::string, std::map<std::string, CompilerStack::PipelineConfig>>;\n\n\t/// Creates a new compiler stack.\n\t/// @param _readFile callback used to read files for import statements. Must return\n\t/// and must not emit exceptions.\n\texplicit CompilerStack(ReadCallback::Callback _readFile = ReadCallback::Callback());\n\n\t~CompilerStack() override;\n\n\t/// @returns the list of errors that occurred during parsing and type checking.\n\tlangutil::ErrorList const& errors() const { return m_errorReporter.errors(); }\n\n\t/// @returns the current state.\n\tState state() const { return m_stackState; }\n\n\tvirtual bool compilationSuccessful() const override { return m_stackState >= CompilationSuccessful; }\n\n\t/// Resets the compiler to an empty state. Unless @a _keepSettings is set to true,\n\t/// all settings are reset as well.\n\tvoid reset(bool _keepSettings = false);\n\n\t/// Sets path remappings.\n\t/// Must be set before parsing.\n\tvoid setRemappings(std::vector<ImportRemapper::Remapping> _remappings);\n\n\t/// Sets library addresses. Addresses are cleared iff @a _libraries is missing.\n\t/// Must be set before parsing.\n\tvoid setLibraries(std::map<std::string, util::h160> const& _libraries = {});\n\n\t/// Changes the optimiser settings.\n\t/// Must be set before parsing.\n\tvoid setOptimiserSettings(bool _optimize, size_t _runs = OptimiserSettings{}.expectedExecutionsPerDeployment);\n\n\t/// Changes the optimiser settings.\n\t/// Must be set before parsing.\n\tvoid setOptimiserSettings(OptimiserSettings _settings);\n\n\t/// Sets whether to strip revert strings, add additional strings or do nothing at all.\n\tvoid setRevertStringBehaviour(RevertStrings _revertStrings);\n\n\t/// Sets the pipeline to go through the Yul IR or not.\n\t/// Must be set before parsing.\n\tvoid setViaIR(bool _viaIR);\n\n\t/// Sets the pipeline to use the SSA CFG code generator instead of OptimizedEVMCodeTransform.\n\t/// Must be set before compilation.\n\tvoid setViaSSACFG(bool _viaSSACFG);\n\n\t/// Sets the experimental toggle to allow usage of experimental features.\n\tvoid setExperimental(bool _experimental);\n\n\t/// Set the EVM version used before running compile.\n\t/// When called without an argument it will revert to the default version.\n\t/// Must be set before parsing.\n\tvoid setEVMVersion(langutil::EVMVersion _version = langutil::EVMVersion{});\n\n\t/// Set the EOF version used before running compile.\n\t/// If set to std::nullopt (the default), legacy non-EOF bytecode is generated.\n\tvoid setEOFVersion(std::optional<uint8_t> version);\n\n\t/// Set model checker settings.\n\tvoid setModelCheckerSettings(ModelCheckerSettings _settings);\n\n\t/// Sets names of the contracts from each source that should be compiled.\n\t/// If empty, no filtering is performed and every contract found in the supplied sources goes\n\t/// through the default pipeline stages (bytecode-only, no IR).\n\t/// Source/contract names are not validated - ones that do not exist are ignored.\n\t/// The empty source/contract name can be used as a wildcard that matches all sources/contracts.\n\t/// If a contract matches more than one entry, the pipeline selection from all matches is combined.\n\tvoid selectContracts(ContractSelection const& _selectedContracts);\n\n\t/// @arg _metadataLiteralSources When true, store sources as literals in the contract metadata.\n\t/// Must be set before parsing.\n\tvoid useMetadataLiteralSources(bool _metadataLiteralSources);\n\n\t/// Sets whether and which hash should be used\n\t/// to store the metadata in the bytecode.\n\t/// @param _metadataHash can be IPFS, Bzzr1, None\n\tvoid setMetadataHash(MetadataHash _metadataHash);\n\n\t/// Select components of debug info that should be included in comments in generated assembly.\n\tvoid selectDebugInfo(langutil::DebugInfoSelection _debugInfoSelection);\n\n\t/// Sets the sources. Must be set before parsing.\n\tvoid setSources(StringMap _sources);\n\n\t/// Adds a response to an SMTLib2 query (identified by the hash of the query input).\n\t/// Must be set before parsing.\n\tvoid addSMTLib2Response(util::h256 const& _hash, std::string const& _response);\n\n\t/// Parses all source units that were added\n\t/// @returns false on error.\n\tbool parse();\n\n\t/// Imports given SourceUnits so they can be analyzed. Leads to the same internal state as parse().\n\t/// Will throw errors if the import fails\n\tvoid importASTs(std::map<std::string, Json> const& _sources);\n\n\t/// Performs the analysis steps (imports, scopesetting, syntaxCheck, referenceResolving,\n\t///  typechecking, staticAnalysis) on previously parsed sources.\n\t/// @returns false on error.\n\tbool analyze();\n\n\t/// Parses and analyzes all source units that were added\n\t/// @returns false on error.\n\tbool parseAndAnalyze(State _stopAfter = State::CompilationSuccessful);\n\n\t/// Compiles the source units that were previously added and parsed.\n\t/// @returns false on error.\n\tbool compile(State _stopAfter = State::CompilationSuccessful);\n\n\t/// Checks whether experimental analysis is on; used in SyntaxTests to skip compilation in case it's ``true``.\n\t/// @returns true if experimental analysis is set\n\tbool isExperimentalAnalysis() const\n\t{\n\t\treturn !!m_experimentalAnalysis;\n\t}\n\n\t/// @returns the list of sources (paths) used\n\tvirtual std::vector<std::string> sourceNames() const override;\n\n\t/// @returns a mapping assigning each source name its index inside the vector returned\n\t/// by sourceNames().\n\tstd::map<std::string, unsigned> sourceIndices() const;\n\n\t/// @returns the previously used character stream, useful for counting lines during error reporting.\n\tlangutil::CharStream const& charStream(std::string const& _sourceName) const override;\n\n\t/// @returns the parsed source unit with the supplied name.\n\tSourceUnit const& ast(std::string const& _sourceName) const;\n\n\t/// @returns the parsed contract with the supplied name. Throws an exception if the contract\n\t/// does not exist.\n\tContractDefinition const& contractDefinition(std::string const& _contractName) const;\n\n\t/// @returns a list of unhandled queries to the SMT solver (has to be supplied in a second run\n\t/// by calling @a addSMTLib2Response).\n\tstd::vector<std::string> const& unhandledSMTLib2Queries() const { return m_unhandledSMTLib2Queries; }\n\n\t/// @returns a list of the contract names in the sources.\n\tvirtual std::vector<std::string> contractNames() const override;\n\n\t/// @returns the name of the last contract. If _sourceName is defined the last contract of that source will be returned.\n\tstd::string const lastContractName(std::optional<std::string> const& _sourceName = std::nullopt) const;\n\n\t/// @returns either the contract's name or a mixture of its name and source file, sanitized for filesystem use\n\tvirtual std::string const filesystemFriendlyName(std::string const& _contractName) const override;\n\n\t/// @returns the IR representation of a contract.\n\tstd::optional<std::string> const& yulIR(std::string const& _contractName) const;\n\n\t/// @returns the IR representation of a contract AST in format.\n\tstd::optional<Json> yulIRAst(std::string const& _contractName) const;\n\n\t/// @returns the optimized IR representation of a contract.\n\tstd::optional<std::string> const& yulIROptimized(std::string const& _contractName) const;\n\n\t/// @returns the optimized IR representation of a contract AST in JSON format.\n\tstd::optional<Json> yulIROptimizedAst(std::string const& _contractName) const;\n\n\tstd::optional<Json> yulCFGJson(std::string const& _contractName) const;\n\n\t/// @returns the assembled object for a contract.\n\tvirtual evmasm::LinkerObject const& object(std::string const& _contractName) const override;\n\n\t/// @returns the runtime object for the contract.\n\tvirtual evmasm::LinkerObject const& runtimeObject(std::string const& _contractName) const override;\n\n\t/// @returns normal contract assembly items\n\tevmasm::AssemblyItems const* assemblyItems(std::string const& _contractName) const;\n\n\t/// @returns runtime contract assembly items\n\tevmasm::AssemblyItems const* runtimeAssemblyItems(std::string const& _contractName) const;\n\n\t/// @returns an array containing all utility sources generated during compilation.\n\t/// Format: [ { name: string, id: number, language: \"Yul\", contents: string }, ... ]\n\tJson generatedSources(std::string const& _contractName, bool _runtime = false) const;\n\n\t/// @returns the string that provides a mapping between bytecode and sourcecode or a nullptr\n\t/// if the contract does not (yet) have bytecode.\n\tvirtual std::string const* sourceMapping(std::string const& _contractName) const override;\n\n\t/// @returns the string that provides a mapping between runtime bytecode and sourcecode.\n\t/// if the contract does not (yet) have bytecode.\n\tvirtual std::string const* runtimeSourceMapping(std::string const& _contractName) const override;\n\n\t/// @return a verbose text representation of the assembly.\n\t/// @arg _sourceCodes is the map of input files to source code strings\n\t/// Prerequisite: Successful compilation.\n\tvirtual std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes = StringMap()) const override;\n\n\t/// @returns a JSON representation of the assembly.\n\t/// @arg _sourceCodes is the map of input files to source code strings\n\t/// Prerequisite: Successful compilation.\n\tvirtual Json assemblyJSON(std::string const& _contractName) const override;\n\n\t/// @returns a JSON representing the contract ABI.\n\t/// Prerequisite: Successful call to parse or compile.\n\tJson const& contractABI(std::string const& _contractName) const;\n\n\t/// @returns a JSON representing the storage layout of the contract.\n\t/// Prerequisite: Successful call to parse or compile.\n\tJson const& storageLayout(std::string const& _contractName) const;\n\n\t/// @returns a JSON representing the transient storage layout of the contract.\n\t/// Prerequisite: Successful call to parse or compile.\n\tJson const& transientStorageLayout(std::string const& _contractName) const;\n\n\t/// @returns a JSON representing the contract's user documentation.\n\t/// Prerequisite: Successful call to parse or compile.\n\tJson const& natspecUser(std::string const& _contractName) const;\n\n\t/// @returns a JSON representing the contract's developer documentation.\n\t/// Prerequisite: Successful call to parse or compile.\n\tJson const& natspecDev(std::string const& _contractName) const;\n\n\t/// @returns a JSON object with the three members ``methods``, ``events``, ``errors``. Each is a map, mapping identifiers (hashes) to function names.\n\tJson interfaceSymbols(std::string const& _contractName) const;\n\n\t/// @returns a JSON representing the ethdebug data of the specified contract.\n\t/// Prerequisite: Successful call to parse or compile.\n\tJson ethdebug(std::string const& _contractName) const override;\n\n\t/// @returns a JSON representing the ethdebug data of the specified contract.\n\t/// Prerequisite: Successful call to parse or compile.\n\tJson ethdebugRuntime(std::string const& _contractName) const override;\n\n\t/// @returns a JSON representing the top-level ethdebug data (types, etc.).\n\t/// Prerequisite: Successful call to parse or compile.\n\tJson ethdebug() const override;\n\n\t/// @returns the Contract Metadata matching the pipeline selected using the viaIR setting.\n\tstd::string const& metadata(std::string const& _contractName) const { return metadata(contract(_contractName)); }\n\n\t/// @returns the CBOR-encoded metadata matching the pipeline selected using the viaIR setting.\n\tbytes cborMetadata(std::string const& _contractName) const { return cborMetadata(_contractName, m_viaIR); }\n\n\t/// @returns the CBOR-encoded metadata.\n\t/// @param _forIR If true, the metadata for the IR codegen is used. Otherwise it's the metadata\n\t///               for the EVM codegen\n\tbytes cborMetadata(std::string const& _contractName, bool _forIR) const;\n\n\t/// @returns a JSON representing the estimated gas usage for contract creation, internal and external functions\n\tJson gasEstimates(std::string const& _contractName) const;\n\n\t/// Changes the format of the metadata appended at the end of the bytecode.\n\tvoid setMetadataFormat(MetadataFormat _metadataFormat) { m_metadataFormat = _metadataFormat; }\n\n\tbool isExperimentalSolidity() const;\n\n\texperimental::Analysis const& experimentalAnalysis() const;\n\n\tstatic MetadataFormat defaultMetadataFormat()\n\t{\n\t\treturn VersionIsRelease ? MetadataFormat::WithReleaseVersionTag : MetadataFormat::WithPrereleaseVersionTag;\n\t}\n\n\tyul::ObjectOptimizer const& objectOptimizer() const { return *m_objectOptimizer; }\n\nprivate:\n\t/// The state per source unit. Filled gradually during parsing.\n\tstruct Source\n\t{\n\t\tstd::shared_ptr<langutil::CharStream> charStream;\n\t\tstd::shared_ptr<SourceUnit> ast;\n\t\tutil::h256 mutable keccak256HashCached;\n\t\tutil::h256 mutable swarmHashCached;\n\t\tstd::string mutable ipfsUrlCached;\n\t\tvoid reset() { *this = Source(); }\n\t\tutil::h256 const& keccak256() const;\n\t\tutil::h256 const& swarmHash() const;\n\t\tstd::string const& ipfsUrl() const;\n\t};\n\n\t/// The state per contract. Filled gradually during compilation.\n\tstruct Contract\n\t{\n\t\tContractDefinition const* contract = nullptr;\n\n\t\tstd::shared_ptr<evmasm::Assembly> evmAssembly;\n\t\tstd::shared_ptr<evmasm::Assembly> evmRuntimeAssembly;\n\t\tstd::optional<std::string> generatedYulUtilityCode; ///< Extra Yul utility code that was used when compiling the creation assembly\n\t\tstd::optional<std::string> runtimeGeneratedYulUtilityCode; ///< Extra Yul utility code that was used when compiling the deployed assembly\n\t\tevmasm::LinkerObject object; ///< Deployment object (includes the runtime sub-object).\n\t\tevmasm::LinkerObject runtimeObject; ///< Runtime object.\n\t\tstd::optional<std::string> yulIR; ///< Yul IR code straight from the code generator.\n\t\tstd::optional<std::string> yulIROptimized; ///< Reparsed and possibly optimized Yul IR code.\n\t\tutil::LazyInit<std::string const> metadata; ///< The metadata json that will be hashed into the chain.\n\t\tutil::LazyInit<Json const> abi;\n\t\tutil::LazyInit<Json const> storageLayout;\n\t\tutil::LazyInit<Json const> transientStorageLayout;\n\t\tutil::LazyInit<Json const> userDocumentation;\n\t\tutil::LazyInit<Json const> devDocumentation;\n\t\tmutable std::optional<std::string const> sourceMapping;\n\t\tmutable std::optional<std::string const> runtimeSourceMapping;\n\t};\n\n\tvoid createAndAssignCallGraphs();\n\tvoid findAndReportCyclicContractDependencies();\n\n\t/// Loads the missing sources from @a _ast (named @a _path) using the callback\n\t/// @a m_readFile\n\t/// @returns the newly loaded sources.\n\tStringMap loadMissingSources(SourceUnit const& _ast);\n\tstd::string applyRemapping(std::string const& _path, std::string const& _context);\n\tbool resolveImports();\n\n\t/// Store the contract definitions in m_contracts.\n\tvoid storeContractDefinitions();\n\n\t/// Annotate internal dispatch function Ids\n\tvoid annotateInternalFunctionIDs();\n\n\t/// @returns true if the source is requested to be compiled.\n\tbool isRequestedSource(std::string const& _sourceName) const;\n\n\t/// @returns true if the contract is requested to be compiled.\n\tbool isRequestedContract(ContractDefinition const& _contract) const;\n\n\t/// @returns The effective pipeline configuration for a given contract.\n\t///     Applies defaults for contracts that were not explicitly selected and combines\n\t///     multiple entries if the contact is matched by wildcards.\n\tPipelineConfig requestedPipelineConfig(ContractDefinition const& _contract) const;\n\n\t/// Perform the analysis steps of legacy language mode.\n\t/// @returns false on error.\n\tbool analyzeLegacy(bool _noErrorsSoFar);\n\n\t/// Perform the analysis steps of experimental language mode.\n\t/// @returns false on error.\n\tbool analyzeExperimental();\n\n\t/// Assembles the contract.\n\t/// This function should only be internally called by compileContract and generateEVMFromIR.\n\tvoid assembleYul(\n\t\tContractDefinition const& _contract,\n\t\tstd::shared_ptr<evmasm::Assembly> _assembly,\n\t\tstd::shared_ptr<evmasm::Assembly> _runtimeAssembly\n\t);\n\n\t/// Compile a single contract.\n\t/// @param _otherCompilers provides access to compilers of other contracts, to get\n\t///                        their bytecode if needed. Only filled after they have been compiled.\n\tvoid compileContract(\n\t\tContractDefinition const& _contract,\n\t\tstd::map<ContractDefinition const*, std::shared_ptr<Compiler const>>& _otherCompilers\n\t);\n\n\t/// Generate Yul IR for a single contract.\n\t/// Unoptimized IR is stored but otherwise unused, while optimized IR may be used for code\n\t/// generation if compilation via IR is enabled. Note that whether \"optimized IR\" is actually\n\t/// optimized depends on the optimizer settings.\n\t/// @param _contract Contract to generate IR for.\n\t/// @param _unoptimizedOnly If true, only the IR coming directly from the codegen is stored.\n\t///     Optimizer is not invoked and optimized IR output is not available, which means that\n\t///     optimized IR, its AST or compilation via IR must not be requested.\n\tvoid generateIR(ContractDefinition const& _contract, bool _unoptimizedOnly);\n\n\t/// Generate EVM representation for a single contract.\n\t/// Depends on output generated by generateIR.\n\tvoid generateEVMFromIR(ContractDefinition const& _contract);\n\n\t/// Links all the known library addresses in the available objects. Any unknown\n\t/// library will still be kept as an unlinked placeholder in the objects.\n\tvoid link();\n\n\t/// Parses and analyzes specified Yul source and returns the YulStack that can be used to manipulate it.\n\t/// Assumes that the IR was generated from sources loaded currently into CompilerStack, which\n\t/// means that it is error-free and uses the same settings.\n\tyul::YulStack loadGeneratedIR(std::string const& _ir) const;\n\n\t/// @returns the contract object for the given @a _contractName.\n\t/// Can only be called after state is CompilationSuccessful.\n\tContract const& contract(std::string const& _contractName) const;\n\n\t/// @returns the source object for the given @a _sourceName.\n\t/// Can only be called after state is SourcesSet.\n\tSource const& source(std::string const& _sourceName) const;\n\n\t/// @param _forIR If true, include a flag that indicates that the bytecode comes from IR codegen.\n\t/// @returns the metadata JSON as a compact string for the given contract.\n\tstd::string createMetadata(Contract const& _contract, bool _forIR) const;\n\n\t/// @returns the metadata CBOR for the given serialised metadata JSON.\n\t/// @param _forIR If true, use the metadata for the IR codegen. Otherwise the one for EVM codegen.\n\tbytes createCBORMetadata(Contract const& _contract, bool _forIR) const;\n\n\t/// @returns the contract ABI as a JSON object.\n\t/// This will generate the JSON object and store it in the Contract object if it is not present yet.\n\tJson const& contractABI(Contract const&) const;\n\n\t/// @returns the storage layout of the contract as a JSON object.\n\t/// This will generate the JSON object and store it in the Contract object if it is not present yet.\n\tJson const& storageLayout(Contract const&) const;\n\n\t/// @returns the transient storage layout of the contract as a JSON object.\n\t/// This will generate the JSON object and store it in the Contract object if it is not present yet.\n\tJson const& transientStorageLayout(Contract const&) const;\n\n\t/// @returns the Natspec User documentation as a JSON object.\n\t/// This will generate the JSON object and store it in the Contract object if it is not present yet.\n\tJson const& natspecUser(Contract const&) const;\n\n\t/// @returns the Natspec Developer documentation as a JSON object.\n\t/// This will generate the JSON object and store it in the Contract object if it is not present yet.\n\tJson const& natspecDev(Contract const&) const;\n\n\t/// @returns the Contract Metadata matching the pipeline selected using the viaIR setting.\n\t/// This will generate the metadata and store it in the Contract object if it is not present yet.\n\tstd::string const& metadata(Contract const& _contract) const;\n\n\t/// @returns the Contract ethdebug data.\n\t/// This will generate the JSON object and store it in the Contract object if it is not present yet.\n\t/// Prerequisite: Successful call to parse or compile.\n\tJson ethdebug(Contract const& _contract, bool _runtime) const;\n\n\t/// @returns the offset of the entry point of the given function into the list of assembly items\n\t/// or zero if it is not found or does not exist.\n\tsize_t functionEntryPoint(\n\t\tstd::string const& _contractName,\n\t\tFunctionDefinition const& _function\n\t) const;\n\n\tvoid reportUnimplementedFeatureError(\n\t\tlangutil::UnimplementedFeatureError const& _error,\n\t\tContractDefinition const* _contractDefinition = nullptr\n\t);\n\tvoid reportCodeGenerationError(langutil::Error const& _error, ContractDefinition const* _contractDefinition);\n\tvoid reportIRPostAnalysisError(langutil::Error const* _error, ContractDefinition const* _contractDefinition);\n\n\tReadCallback::Callback m_readFile;\n\tOptimiserSettings m_optimiserSettings;\n\tRevertStrings m_revertStrings = RevertStrings::Default;\n\tState m_stopAfter = State::CompilationSuccessful;\n\tbool m_viaIR = false;\n\tbool m_viaSSACFG = false;\n\tbool m_experimental = false;\n\tlangutil::EVMVersion m_evmVersion;\n\tstd::optional<uint8_t> m_eofVersion;\n\tModelCheckerSettings m_modelCheckerSettings;\n\tContractSelection m_selectedContracts;\n\tstd::map<std::string, util::h160> m_libraries;\n\tImportRemapper m_importRemapper;\n\tstd::map<std::string const, Source> m_sources;\n\tstd::optional<int64_t> m_maxAstId;\n\tstd::vector<std::string> m_unhandledSMTLib2Queries;\n\tstd::map<util::h256, std::string> m_smtlib2Responses;\n\tstd::shared_ptr<GlobalContext> m_globalContext;\n\tstd::vector<Source const*> m_sourceOrder;\n\tstd::map<std::string const, Contract> m_contracts;\n\tstd::shared_ptr<yul::ObjectOptimizer> m_objectOptimizer;\n\n\tlangutil::ErrorList m_errorList;\n\tlangutil::ErrorReporter m_errorReporter;\n\tstd::unique_ptr<experimental::Analysis> m_experimentalAnalysis;\n\tbool m_metadataLiteralSources = false;\n\tMetadataHash m_metadataHash = MetadataHash::IPFS;\n\tlangutil::DebugInfoSelection m_debugInfoSelection = langutil::DebugInfoSelection::Default();\n\tState m_stackState = Empty;\n\tCompilationSourceType m_compilationSourceType = CompilationSourceType::Solidity;\n\tMetadataFormat m_metadataFormat = defaultMetadataFormat();\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/DebugSettings.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Settings to aid debugging.\n */\n\n#pragma once\n\n#include <cstddef>\n#include <string>\n#include <optional>\n\nnamespace solidity::frontend\n{\n\nenum class RevertStrings\n{\n\n\tDefault, // no compiler-generated strings, keep user-supplied strings\n\tStrip, // no compiler-generated strings, remove user-supplied strings (if possible)\n\tDebug, // add strings for internal reverts, keep user-supplied strings\n\tVerboseDebug // add strings for internal reverts, add user-supplied strings if not provided\n};\n\ninline std::string revertStringsToString(RevertStrings _str)\n{\n\tswitch (_str)\n\t{\n\tcase RevertStrings::Default: return \"default\";\n\tcase RevertStrings::Strip: return \"strip\";\n\tcase RevertStrings::Debug: return \"debug\";\n\tcase RevertStrings::VerboseDebug: return \"verboseDebug\";\n\t}\n\t// Cannot reach this.\n\treturn \"INVALID\";\n}\n\ninline std::optional<RevertStrings> revertStringsFromString(std::string const& _str)\n{\n\tfor (auto i: {RevertStrings::Default, RevertStrings::Strip, RevertStrings::Debug, RevertStrings::VerboseDebug})\n\t\tif (revertStringsToString(i) == _str)\n\t\t\treturn i;\n\treturn std::nullopt;\n}\n\n}\n"
  },
  {
    "path": "libsolidity/interface/FileReader.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/interface/FileReader.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/Exceptions.h>\n#include <libsolutil/StringUtils.h>\n\n#include <boost/algorithm/string/predicate.hpp>\n#include <range/v3/view/transform.hpp>\n\n#include <range/v3/range/conversion.hpp>\n\n#include <functional>\n\nusing solidity::frontend::ReadCallback;\nusing solidity::util::errinfo_comment;\nusing solidity::util::readFileAsString;\nusing solidity::util::joinHumanReadable;\n\nnamespace solidity::frontend\n{\n\nFileReader::FileReader(\n\tboost::filesystem::path _basePath,\n\tstd::vector<boost::filesystem::path> const& _includePaths,\n\tFileSystemPathSet _allowedDirectories\n):\n\tm_allowedDirectories(std::move(_allowedDirectories)),\n\tm_sourceCodes()\n{\n\tsetBasePath(_basePath);\n\tfor (boost::filesystem::path const& includePath: _includePaths)\n\t\taddIncludePath(includePath);\n\n\tfor (boost::filesystem::path const& allowedDir: m_allowedDirectories)\n\t\tsolAssert(!allowedDir.empty(), \"\");\n}\n\nvoid FileReader::setBasePath(boost::filesystem::path const& _path)\n{\n\tif (_path.empty())\n\t{\n\t\t// Empty base path is a special case that does not make sense when include paths are used.\n\t\tsolAssert(m_includePaths.empty(), \"\");\n\t\tm_basePath = \"\";\n\t}\n\telse\n\t\tm_basePath = normalizeCLIPathForVFS(_path);\n}\n\nvoid FileReader::addIncludePath(boost::filesystem::path const& _path)\n{\n\tsolAssert(!m_basePath.empty(), \"\");\n\tsolAssert(!_path.empty(), \"\");\n\tm_includePaths.push_back(normalizeCLIPathForVFS(_path));\n}\n\nvoid FileReader::allowDirectory(boost::filesystem::path _path)\n{\n\tsolAssert(!_path.empty(), \"\");\n\tm_allowedDirectories.insert(std::move(_path));\n}\n\nvoid FileReader::addOrUpdateFile(boost::filesystem::path const& _path, SourceCode _source)\n{\n\tm_sourceCodes[cliPathToSourceUnitName(_path)] = std::move(_source);\n}\n\nvoid FileReader::setStdin(SourceCode _source)\n{\n\tm_sourceCodes[\"<stdin>\"] = std::move(_source);\n}\n\nvoid FileReader::setSourceUnits(StringMap _sources)\n{\n\tm_sourceCodes = std::move(_sources);\n}\n\nReadCallback::Result FileReader::readFile(std::string const& _kind, std::string const& _sourceUnitName)\n{\n\ttry\n\t{\n\t\tif (_kind != ReadCallback::kindString(ReadCallback::Kind::ReadFile))\n\t\t\tsolAssert(false, \"ReadFile callback used as callback kind \" + _kind);\n\t\tstd::string strippedSourceUnitName = _sourceUnitName;\n\t\tif (strippedSourceUnitName.find(\"file://\") == 0)\n\t\t\tstrippedSourceUnitName.erase(0, 7);\n\n\t\tstd::vector<boost::filesystem::path> candidates;\n\t\tstd::vector<std::reference_wrapper<boost::filesystem::path>> prefixes = {m_basePath};\n\t\tprefixes += (m_includePaths | ranges::to<std::vector<std::reference_wrapper<boost::filesystem::path>>>);\n\n\t\tfor (auto const& prefix: prefixes)\n\t\t{\n\t\t\tboost::filesystem::path canonicalPath = normalizeCLIPathForVFS(prefix / strippedSourceUnitName, SymlinkResolution::Enabled);\n\t\t\tif (boost::filesystem::exists(canonicalPath))\n\t\t\t\tcandidates.push_back(std::move(canonicalPath));\n\t\t}\n\n\t\tauto pathToQuotedString = [](boost::filesystem::path const& _path){ return \"\\\"\" + _path.string() + \"\\\"\"; };\n\n\t\tif (candidates.empty())\n\t\t\treturn ReadCallback::Result{\n\t\t\t\tfalse,\n\t\t\t\t\"File not found. Searched the following locations: \" +\n\t\t\t\tjoinHumanReadable(prefixes | ranges::views::transform(pathToQuotedString), \", \") +\n\t\t\t\t\".\"\n\t\t\t};\n\n\t\tif (candidates.size() >= 2)\n\t\t\treturn ReadCallback::Result{\n\t\t\t\tfalse,\n\t\t\t\t\"Ambiguous import. \"\n\t\t\t\t\"Multiple matching files found inside base path and/or include paths: \" +\n\t\t\t\tjoinHumanReadable(candidates | ranges::views::transform(pathToQuotedString), \", \") +\n\t\t\t\t\".\"\n\t\t\t};\n\n\t\tFileSystemPathSet allowedPaths =\n\t\t\tm_allowedDirectories +\n\t\t\tdecltype(allowedPaths){m_basePath.empty() ? \".\" : m_basePath} +\n\t\t\tm_includePaths;\n\n\t\tbool isAllowed = false;\n\t\tfor (boost::filesystem::path const& allowedDir: allowedPaths)\n\t\t\tif (isPathPrefix(normalizeCLIPathForVFS(allowedDir, SymlinkResolution::Enabled), candidates[0]))\n\t\t\t{\n\t\t\t\tisAllowed = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\tif (!isAllowed)\n\t\t\treturn ReadCallback::Result{\n\t\t\t\tfalse,\n\t\t\t\t\"File outside of allowed directories. The following are allowed: \" +\n\t\t\t\tjoinHumanReadable(allowedPaths | ranges::views::transform(pathToQuotedString), \", \") +\n\t\t\t\t\".\"\n\t\t\t};\n\n\t\tif (!boost::filesystem::is_regular_file(candidates[0]))\n\t\t\treturn ReadCallback::Result{false, \"Not a valid file.\"};\n\n\t\t// NOTE: we ignore the FileNotFound exception as we manually check above\n\t\tauto contents = readFileAsString(candidates[0]);\n\t\tsolAssert(m_sourceCodes.count(_sourceUnitName) == 0, \"\");\n\t\tm_sourceCodes[_sourceUnitName] = contents;\n\t\treturn ReadCallback::Result{true, contents};\n\t}\n\tcatch (...)\n\t{\n\t\treturn ReadCallback::Result{false, \"Exception in read callback: \" + boost::current_exception_diagnostic_information()};\n\t}\n}\n\nstd::string FileReader::cliPathToSourceUnitName(boost::filesystem::path const& _cliPath) const\n{\n\tstd::vector<boost::filesystem::path> prefixes = {m_basePath.empty() ? normalizeCLIPathForVFS(\".\") : m_basePath};\n\tprefixes += m_includePaths;\n\n\tboost::filesystem::path normalizedPath = normalizeCLIPathForVFS(_cliPath);\n\tfor (boost::filesystem::path const& prefix: prefixes)\n\t\tif (isPathPrefix(prefix, normalizedPath))\n\t\t{\n\t\t\t// Multiple prefixes can potentially match the path. We take the first one.\n\t\t\tnormalizedPath = stripPrefixIfPresent(prefix, normalizedPath);\n\t\t\tbreak;\n\t\t}\n\n\treturn normalizedPath.generic_string();\n}\n\nstd::map<std::string, FileReader::FileSystemPathSet> FileReader::detectSourceUnitNameCollisions(FileSystemPathSet const& _cliPaths) const\n{\n\tstd::map<std::string, FileReader::FileSystemPathSet> nameToPaths;\n\tfor (boost::filesystem::path const& cliPath: _cliPaths)\n\t{\n\t\tstd::string sourceUnitName = cliPathToSourceUnitName(cliPath);\n\t\tboost::filesystem::path normalizedPath = normalizeCLIPathForVFS(cliPath);\n\t\tnameToPaths[sourceUnitName].insert(normalizedPath);\n\t}\n\n\tstd::map<std::string, FileReader::FileSystemPathSet> collisions;\n\tfor (auto&& [sourceUnitName, cliPaths]: nameToPaths)\n\t\tif (cliPaths.size() >= 2)\n\t\t\tcollisions[sourceUnitName] = std::move(cliPaths);\n\n\treturn collisions;\n}\n\nboost::filesystem::path FileReader::normalizeCLIPathForVFS(\n\tboost::filesystem::path const& _path,\n\tSymlinkResolution _symlinkResolution\n)\n{\n\t// Detailed normalization rules:\n\t// - Makes the path either be absolute or have slash as root (note that on Windows paths with\n\t//   slash as root are not considered absolute by Boost). If it is empty, it becomes\n\t//   the current working directory.\n\t// - Collapses redundant . and .. segments.\n\t// - Removes leading .. segments from an absolute path (i.e. /../../ becomes just /).\n\t// - Squashes sequences of multiple path separators into one.\n\t// - Ensures that forward slashes are used as path separators on all platforms.\n\t// - Removes the root name (e.g. drive letter on Windows) when it matches the root name in the\n\t//   path to the current working directory.\n\t//\n\t// Also note that this function:\n\t// - Does NOT resolve symlinks (except for symlinks in the path to the current working directory)\n\t//   unless explicitly requested.\n\t// - Does NOT check if the path refers to a file or a directory. If the path ends with a slash,\n\t//   the slash is preserved even if it's a file.\n\t//   - The only exception are paths where the file name is a dot (e.g. '.' or 'a/b/.'). These\n\t//     always have a trailing slash after normalization.\n\t// - Preserves case. Even if the filesystem is case-insensitive but case-preserving and the\n\t//   case differs, the actual case from disk is NOT detected.\n\n\tboost::filesystem::path canonicalWorkDir = boost::filesystem::weakly_canonical(boost::filesystem::current_path());\n\n\t// NOTE: On UNIX systems the path returned from current_path() has symlinks resolved while on\n\t// Windows it does not. To get consistent results we resolve them on all platforms.\n\tboost::filesystem::path absolutePath = boost::filesystem::absolute(_path, canonicalWorkDir);\n\n\tboost::filesystem::path normalizedPath;\n\tif (_symlinkResolution == SymlinkResolution::Enabled)\n\t{\n\t\t// NOTE: weakly_canonical() will not convert a relative path into an absolute one if no\n\t\t// directory included in the path actually exists.\n\t\tnormalizedPath = boost::filesystem::weakly_canonical(absolutePath);\n\n\t\t// The three corner cases in which lexically_normal() includes a trailing slash in the\n\t\t// normalized path but weakly_canonical() does not. Note that the trailing slash is not\n\t\t// ignored when comparing paths with ==.\n\t\tif ((_path == \".\" || _path == \"./\" || _path == \"../\") && !boost::ends_with(normalizedPath.generic_string(), \"/\"))\n\t\t\tnormalizedPath = normalizedPath.parent_path() / (normalizedPath.filename().string() + \"/\");\n\t}\n\telse\n\t{\n\t\tsolAssert(_symlinkResolution == SymlinkResolution::Disabled, \"\");\n\n\t\t// NOTE: boost path preserves certain differences that are ignored by its operator ==.\n\t\t// E.g. \"a//b\" vs \"a/b\" or \"a/b/\" vs \"a/b/.\". lexically_normal() does remove these differences.\n\t\tnormalizedPath = absolutePath.lexically_normal();\n\t}\n\tsolAssert(normalizedPath.is_absolute() || normalizedPath.root_path() == \"/\", \"\");\n\n\t// If the path is on the same drive as the working dir, for portability we prefer not to\n\t// include the root name. Do this only for non-UNC paths - my experiments show that on Windows\n\t// when the working dir is an UNC path, / does not actually refer to the root of the UNC path.\n\n\tboost::filesystem::path normalizedRootPath = normalizeCLIRootPathForVFS(normalizedPath, canonicalWorkDir);\n\n\t// lexically_normal() will not squash paths like \"/../../\" into \"/\". We have to do it manually.\n\tboost::filesystem::path dotDotPrefix = absoluteDotDotPrefix(normalizedPath);\n\n\tboost::filesystem::path normalizedPathNoDotDot = normalizedPath;\n\tif (dotDotPrefix.empty())\n\t\tnormalizedPathNoDotDot = normalizedRootPath / normalizedPath.relative_path();\n\telse\n\t\tnormalizedPathNoDotDot = normalizedRootPath / normalizedPath.lexically_relative(normalizedPath.root_path() / dotDotPrefix);\n\tsolAssert(!hasDotDotSegments(normalizedPathNoDotDot), \"\");\n\n\t// NOTE: On Windows lexically_normal() converts all separators to forward slashes. Convert them back.\n\t// Separators do not affect path comparison but remain in internal representation returned by native().\n\t// This will also normalize the root name to start with // in UNC paths.\n\tnormalizedPathNoDotDot = normalizedPathNoDotDot.generic_string();\n\n\t// For some reason boost considers \"/.\" different than \"/\" even though for other directories\n\t// the trailing dot is ignored.\n\tif (normalizedPathNoDotDot == \"/.\")\n\t\treturn \"/\";\n\n\treturn normalizedPathNoDotDot;\n}\n\nboost::filesystem::path FileReader::normalizeCLIRootPathForVFS(\n\tboost::filesystem::path const& _path,\n\tboost::filesystem::path const& _workDir\n)\n{\n\tsolAssert(_workDir.is_absolute(), \"\");\n\n\tboost::filesystem::path absolutePath = boost::filesystem::absolute(_path, _workDir);\n\tboost::filesystem::path rootPath = absolutePath.root_path();\n\tboost::filesystem::path baseRootPath = _workDir.root_path();\n\n\tif (isUNCPath(absolutePath))\n\t\treturn rootPath;\n\n\t// Ignore drive letter case on Windows (C:\\ <=> c:\\).\n\tif (boost::filesystem::equivalent(rootPath, baseRootPath))\n\t\treturn \"/\";\n\n\treturn rootPath;\n}\n\nbool FileReader::isPathPrefix(boost::filesystem::path const& _prefix, boost::filesystem::path const& _path)\n{\n\tsolAssert(!_prefix.empty() && !_path.empty(), \"\");\n\t// NOTE: On Windows paths starting with a slash (rather than a drive letter) are considered relative by boost.\n\tsolAssert(_prefix.is_absolute() || isUNCPath(_prefix) || _prefix.root_path() == \"/\", \"\");\n\tsolAssert(_path.is_absolute() || isUNCPath(_path) || _path.root_path() == \"/\", \"\");\n\t// NOTE: On Windows before Boost 1.78 lexically_normal() would not replace the `//` UNC prefix with `\\\\\\\\`.\n\t// Later versions do. Use generic_path() to normalize all slashes to `/` and ignore that difference.\n\t// This does not make the assert weaker because == ignores slash type anyway.\n\tsolAssert(_prefix == _prefix.lexically_normal().generic_string() && _path == _path.lexically_normal().generic_string(), \"\");\n\tsolAssert(!hasDotDotSegments(_prefix) && !hasDotDotSegments(_path), \"\");\n\n\tboost::filesystem::path strippedPath = _path.lexically_relative(\n\t\t// Before 1.72.0 lexically_relative() was not handling paths with empty, dot and dot dot segments\n\t\t// correctly (see https://github.com/boostorg/filesystem/issues/76). The only case where this\n\t\t// is possible after our normalization is a directory name ending in a slash (filename is a dot).\n\t\t_prefix.filename_is_dot() ? _prefix.parent_path() : _prefix\n\t);\n\treturn !strippedPath.empty() && *strippedPath.begin() != \"..\";\n}\n\nboost::filesystem::path FileReader::stripPrefixIfPresent(boost::filesystem::path const& _prefix, boost::filesystem::path const& _path)\n{\n\tif (!isPathPrefix(_prefix, _path))\n\t\treturn _path;\n\n\tboost::filesystem::path strippedPath = _path.lexically_relative(\n\t\t_prefix.filename_is_dot() ? _prefix.parent_path() : _prefix\n\t);\n\tsolAssert(strippedPath.empty() || *strippedPath.begin() != \"..\", \"\");\n\treturn strippedPath;\n}\n\nboost::filesystem::path FileReader::absoluteDotDotPrefix(boost::filesystem::path const& _path)\n{\n\tsolAssert(_path.is_absolute() || _path.root_path() == \"/\", \"\");\n\n\tboost::filesystem::path _pathWithoutRoot = _path.relative_path();\n\tboost::filesystem::path prefix;\n\tfor (boost::filesystem::path const& segment: _pathWithoutRoot)\n\t\tif (segment.filename_is_dot_dot())\n\t\t\tprefix /= segment;\n\n\treturn prefix;\n}\n\nbool FileReader::hasDotDotSegments(boost::filesystem::path const& _path)\n{\n\tfor (boost::filesystem::path const& segment: _path)\n\t\tif (segment.filename_is_dot_dot())\n\t\t\treturn true;\n\n\treturn false;\n}\n\nbool FileReader::isUNCPath(boost::filesystem::path const& _path)\n{\n\tstd::string rootName = _path.root_name().string();\n\n\treturn (\n\t\trootName.size() == 2 ||\n\t\t(rootName.size() > 2 && rootName[2] != rootName[1])\n\t) && (\n\t\t(rootName[0] == '/' && rootName[1] == '/')\n#if defined(_WIN32)\n\t\t|| (rootName[0] == '\\\\' && rootName[1] == '\\\\')\n#endif\n\t);\n}\n\n}\n"
  },
  {
    "path": "libsolidity/interface/FileReader.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/interface/ImportRemapper.h>\n#include <libsolidity/interface/ReadFile.h>\n\n#include <boost/filesystem.hpp>\n\n#include <map>\n#include <set>\n\nnamespace solidity::frontend\n{\n\n/// FileReader - used for progressively loading source code.\n///\n/// It is used in solc to load files from CLI parameters, stdin, or from JSON and\n/// also used in the solc language server where solc is a long running process.\nclass FileReader\n{\npublic:\n\tusing StringMap = std::map<SourceUnitName, SourceCode>;\n\tusing PathMap = std::map<SourceUnitName, boost::filesystem::path>;\n\tusing FileSystemPathSet = std::set<boost::filesystem::path>;\n\n\tenum SymlinkResolution {\n\t\tDisabled, ///< Do not resolve symbolic links in the path.\n\t\tEnabled,  ///< Follow symbolic links. The path should contain no symlinks.\n\t};\n\n\t/// Constructs a FileReader with a base path and sets of include paths and allowed directories\n\t/// that will be used when requesting files from this file reader instance.\n\texplicit FileReader(\n\t\tboost::filesystem::path _basePath = {},\n\t\tstd::vector<boost::filesystem::path> const& _includePaths = {},\n\t\tFileSystemPathSet _allowedDirectories = {}\n\t);\n\n\tvoid setBasePath(boost::filesystem::path const& _path);\n\tboost::filesystem::path const& basePath() const noexcept { return m_basePath; }\n\n\tvoid addIncludePath(boost::filesystem::path const& _path);\n\tstd::vector<boost::filesystem::path> const& includePaths() const noexcept { return m_includePaths; }\n\n\tvoid allowDirectory(boost::filesystem::path _path);\n\tFileSystemPathSet const& allowedDirectories() const noexcept { return m_allowedDirectories; }\n\n\t/// @returns all sources by their internal source unit names.\n\tStringMap const& sourceUnits() const noexcept { return m_sourceCodes; }\n\n\t/// Resets all sources to the given map of source unit name to source codes.\n\t/// Does not enforce @a allowedDirectories().\n\tvoid setSourceUnits(StringMap _sources);\n\n\t/// Adds the source code under a source unit name created by normalizing the file path\n\t/// or changes an existing source.\n\t/// Does not enforce @a allowedDirectories().\n\tvoid addOrUpdateFile(boost::filesystem::path const& _path, SourceCode _source);\n\n\t/// Adds the source code under the source unit name of @a <stdin>.\n\t/// Does not enforce @a allowedDirectories().\n\tvoid setStdin(SourceCode _source);\n\n\t/// Receives a @p _sourceUnitName that refers to a source unit in compiler's virtual filesystem\n\t/// and attempts to interpret it as a path and read the corresponding file from disk.\n\t/// The read will only succeed if the canonical path of the file is within one of the @a allowedDirectories().\n\t/// @param _kind must be equal to \"source\". Other values are not supported.\n\t/// @return Content of the loaded file or an error message. If the operation succeeds, a copy of\n\t/// the content is retained in @a sourceUnits() under the key of @a _sourceUnitName. If the key\n\t/// already exists, previous content is discarded.\n\tfrontend::ReadCallback::Result readFile(std::string const& _kind, std::string const& _sourceUnitName);\n\n\tfrontend::ReadCallback::Callback reader()\n\t{\n\t\treturn [this](std::string const& _kind, std::string const& _path) { return readFile(_kind, _path); };\n\t}\n\n\t/// Creates a source unit name by normalizing a path given on the command line and, if possible,\n\t/// making it relative to base path or one of the include directories.\n\tstd::string cliPathToSourceUnitName(boost::filesystem::path const& _cliPath) const;\n\n\t/// Checks if a set contains any paths that lead to different files but would receive identical\n\t/// source unit names. Files are considered the same if their paths are exactly the same after\n\t/// normalization (without following symlinks).\n\t/// @returns a map containing all the conflicting source unit names and the paths that would\n\t/// receive them. The returned paths are normalized.\n\tstd::map<std::string, FileSystemPathSet> detectSourceUnitNameCollisions(FileSystemPathSet const& _cliPaths) const;\n\n\t/// Normalizes a filesystem path to make it include all components up to the filesystem root,\n\t/// remove small, inconsequential differences that do not affect the meaning and make it look\n\t/// the same on all platforms (if possible).\n\t/// The resulting path uses forward slashes as path separators, has no redundant separators,\n\t/// has no redundant . or .. segments and has no root name if removing it does not change the meaning.\n\t/// The path does not have to actually exist.\n\t/// @param _path Path to normalize.\n\t/// @param _symlinkResolution If @a Disabled, any symlinks present in @a _path are preserved.\n\tstatic boost::filesystem::path normalizeCLIPathForVFS(\n\t\tboost::filesystem::path const& _path,\n\t\tSymlinkResolution _symlinkResolution = SymlinkResolution::Disabled\n\t);\n\n\t/// Normalizes a root path by excluding, in some cases, its root name.\n\t/// The function is used for better portability, and intended to omit root name\n\t/// if the path can be used without it.\n\t/// @param _path Path to normalize the root path.\n\t/// @param _workDir Current working directory path, must be absolute.\n\t/// @returns a normalized root path.\n\tstatic boost::filesystem::path normalizeCLIRootPathForVFS(\n\t\tboost::filesystem::path const& _path,\n\t\tboost::filesystem::path const& _workDir = boost::filesystem::current_path()\n\t);\n\n\t/// @returns true if all the path components of @a _prefix are present at the beginning of @a _path.\n\t/// Both paths must be absolute (or have slash as root) and normalized (no . or .. segments, no\n\t/// multiple consecutive slashes).\n\t/// Paths are treated as case-sensitive. Does not require the path to actually exist in the\n\t/// filesystem and does not follow symlinks. Only considers whole segments, e.g. /abc/d is not\n\t/// considered a prefix of /abc/def. Both paths must be non-empty.\n\t/// Ignores the trailing slash, i.e. /a/b/c.sol/ is treated as a valid prefix of /a/b/c.sol.\n\tstatic bool isPathPrefix(boost::filesystem::path const& _prefix, boost::filesystem::path const& _path);\n\n\t/// If @a _prefix is actually a prefix of @p _path, removes it from @a _path to make it relative.\n\t/// @returns The path without the prefix or unchanged path if there is not prefix.\n\t/// If @a _path and @_prefix are identical, the result is '.'.\n\tstatic boost::filesystem::path stripPrefixIfPresent(boost::filesystem::path const& _prefix, boost::filesystem::path const& _path);\n\n\t/// @returns true if the specified path is an UNC path.\n\t/// UNC paths start with // followed by a name (on Windows they can also start with \\\\).\n\t/// They are used for network shares on Windows. On UNIX systems they do not have the same\n\t/// functionality but usually they are still recognized and treated in a special way.\n\tstatic bool isUNCPath(boost::filesystem::path const& _path);\n\nprivate:\n\t/// If @a _path starts with a number of .. segments, returns a path consisting only of those\n\t/// segments (root name is not included). Otherwise returns an empty path. @a _path must be\n\t/// absolute (or have slash as root).\n\tstatic boost::filesystem::path absoluteDotDotPrefix(boost::filesystem::path const& _path);\n\n\t/// @returns true if the path contains any .. segments.\n\tstatic bool hasDotDotSegments(boost::filesystem::path const& _path);\n\n\t/// Base path, used for resolving relative paths in imports.\n\tboost::filesystem::path m_basePath;\n\n\t/// Additional directories used for resolving relative paths in imports.\n\tstd::vector<boost::filesystem::path> m_includePaths;\n\n\t/// list of allowed directories to read files from\n\tFileSystemPathSet m_allowedDirectories;\n\n\t/// map of input files to source code strings\n\tStringMap m_sourceCodes;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/GasEstimator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Gas consumption estimator working alongside the AST.\n */\n\n#include <libsolidity/interface/GasEstimator.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/codegen/CompilerUtils.h>\n\n#include <libevmasm/ControlFlowGraph.h>\n#include <libevmasm/KnownState.h>\n#include <libevmasm/PathGasMeter.h>\n#include <libsolutil/FunctionSelector.h>\n#include <libsolutil/Keccak256.h>\n\n#include <functional>\n#include <map>\n#include <memory>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\n\nGasEstimator::GasConsumption GasEstimator::functionalEstimation(\n\tAssemblyItems const& _items,\n\tstd::string const& _signature\n) const\n{\n\tauto state = std::make_shared<KnownState>();\n\n\tif (!_signature.empty())\n\t{\n\t\tExpressionClasses& classes = state->expressionClasses();\n\t\tusing Id = ExpressionClasses::Id;\n\t\tusing Ids = std::vector<Id>;\n\t\tId hashValue = classes.find(u256(util::selectorFromSignatureU32(_signature)));\n\t\tId calldata = classes.find(Instruction::CALLDATALOAD, Ids{classes.find(u256(0))});\n\t\tif (!m_evmVersion.hasBitwiseShifting())\n\t\t\t// div(calldataload(0), 1 << 224) equals to hashValue\n\t\t\tclasses.forceEqual(\n\t\t\t\thashValue,\n\t\t\t\tInstruction::DIV,\n\t\t\t\tIds{calldata, classes.find(u256(1) << 224)}\n\t\t\t);\n\t\telse\n\t\t\t// shr(0xe0, calldataload(0)) equals to hashValue\n\t\t\tclasses.forceEqual(\n\t\t\t\thashValue,\n\t\t\t\tInstruction::SHR,\n\t\t\t\tIds{classes.find(u256(0xe0)), calldata}\n\t\t\t);\n\t\t// lt(calldatasize(), 4) equals to 0 (ignore the shortcut for fallback functions)\n\t\tclasses.forceEqual(\n\t\t\tclasses.find(u256(0)),\n\t\t\tInstruction::LT,\n\t\t\tIds{classes.find(Instruction::CALLDATASIZE), classes.find(u256(4))}\n\t\t);\n\t}\n\n\treturn PathGasMeter::estimateMax(_items, m_evmVersion, 0, state);\n}\n\nGasEstimator::GasConsumption GasEstimator::functionalEstimation(\n\tAssemblyItems const& _items,\n\tsize_t const& _offset,\n\tFunctionDefinition const& _function\n) const\n{\n\tauto state = std::make_shared<KnownState>();\n\n\tunsigned parametersSize = CompilerUtils::sizeOnStack(_function.parameters());\n\tif (parametersSize > m_evmVersion.reachableStackDepth())\n\t\treturn GasConsumption::infinite();\n\n\t// Store an invalid return value on the stack, so that the path estimator breaks upon reaching\n\t// the return jump.\n\tAssemblyItem invalidTag(PushTag, u256(-0x10));\n\tstate->feedItem(invalidTag, true);\n\tif (parametersSize > 0)\n\t\tstate->feedItem(swapInstruction(parametersSize));\n\n\treturn PathGasMeter::estimateMax(_items, m_evmVersion, _offset, state);\n}\n\nstd::set<ASTNode const*> GasEstimator::finestNodesAtLocation(\n\tstd::vector<ASTNode const*> const& _roots\n)\n{\n\tstd::map<SourceLocation, ASTNode const*> locations;\n\tstd::set<ASTNode const*> nodes;\n\tSimpleASTVisitor visitor([](ASTNode const&) { return false; }, [&](ASTNode const& _n)\n\t{\n\t\tif (!locations.count(_n.location()))\n\t\t{\n\t\t\tlocations[_n.location()] = &_n;\n\t\t\tnodes.insert(&_n);\n\t\t}\n\t});\n\n\tfor (ASTNode const* root: _roots)\n\t\troot->accept(visitor);\n\treturn nodes;\n}\n"
  },
  {
    "path": "libsolidity/interface/GasEstimator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Gas consumption estimator working alongside the AST.\n */\n\n#pragma once\n\n#include <liblangutil/EVMVersion.h>\n\n#include <libevmasm/Assembly.h>\n#include <libevmasm/GasMeter.h>\n\n#include <array>\n#include <map>\n#include <vector>\n\nnamespace solidity::frontend\n{\n\nclass ASTNode;\nclass FunctionDefinition;\n\nstruct GasEstimator\n{\npublic:\n\tusing GasConsumption = evmasm::GasMeter::GasConsumption;\n\tusing ASTGasConsumption = std::map<ASTNode const*, GasConsumption>;\n\tusing ASTGasConsumptionSelfAccumulated =\n\t\tstd::map<ASTNode const*, std::array<GasConsumption, 2>>;\n\n\texplicit GasEstimator(langutil::EVMVersion _evmVersion): m_evmVersion(_evmVersion) {}\n\n\t/// @returns the estimated gas consumption by the (public or external) function with the\n\t/// given signature. If no signature is given, estimates the maximum gas usage.\n\tGasConsumption functionalEstimation(\n\t\tevmasm::AssemblyItems const& _items,\n\t\tstd::string const& _signature = \"\"\n\t) const;\n\n\t/// @returns the estimated gas consumption by the given function which starts at the given\n\t/// offset into the list of assembly items.\n\t/// @note this does not work correctly for recursive functions.\n\tGasConsumption functionalEstimation(\n\t\tevmasm::AssemblyItems const& _items,\n\t\tsize_t const& _offset,\n\t\tFunctionDefinition const& _function\n\t) const;\n\nprivate:\n\t/// @returns the set of AST nodes which are the finest nodes at their location.\n\tstatic std::set<ASTNode const*> finestNodesAtLocation(std::vector<ASTNode const*> const& _roots);\n\tlangutil::EVMVersion m_evmVersion;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/ImportRemapper.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/interface/ImportRemapper.h>\n#include <libsolutil/CommonIO.h>\n#include <liblangutil/Exceptions.h>\n\nnamespace solidity::frontend\n{\n\nvoid ImportRemapper::setRemappings(std::vector<Remapping> _remappings)\n{\n\tfor (auto const& remapping: _remappings)\n\t\tsolAssert(!remapping.prefix.empty(), \"\");\n\tm_remappings = std::move(_remappings);\n}\n\nSourceUnitName ImportRemapper::apply(ImportPath const& _path, std::string const& _context) const\n{\n\t// Try to find the longest prefix match in all remappings that are active in the current context.\n\tauto isPrefixOf = [](std::string const& _a, std::string const& _b)\n\t{\n\t\tif (_a.length() > _b.length())\n\t\t\treturn false;\n\t\treturn equal(_a.begin(), _a.end(), _b.begin());\n\t};\n\n\tsize_t longestPrefix = 0;\n\tsize_t longestContext = 0;\n\tstd::string bestMatchTarget;\n\n\tfor (auto const& redir: m_remappings)\n\t{\n\t\tstd::string context = util::sanitizePath(redir.context);\n\t\tstd::string prefix = util::sanitizePath(redir.prefix);\n\n\t\t// Skip if current context is closer\n\t\tif (context.length() < longestContext)\n\t\t\tcontinue;\n\t\t// Skip if redir.context is not a prefix of _context\n\t\tif (!isPrefixOf(context, _context))\n\t\t\tcontinue;\n\t\t// Skip if we already have a closer prefix match.\n\t\tif (prefix.length() < longestPrefix && context.length() == longestContext)\n\t\t\tcontinue;\n\t\t// Skip if the prefix does not match.\n\t\tif (!isPrefixOf(prefix, _path))\n\t\t\tcontinue;\n\n\t\tlongestContext = context.length();\n\t\tlongestPrefix = prefix.length();\n\t\tbestMatchTarget = util::sanitizePath(redir.target);\n\t}\n\tstd::string path = bestMatchTarget;\n\tpath.append(_path.begin() + static_cast<std::string::difference_type>(longestPrefix), _path.end());\n\treturn path;\n}\n\nbool ImportRemapper::isRemapping(std::string_view _input)\n{\n\treturn _input.find(\"=\") != std::string::npos;\n}\n\n\tstd::optional<ImportRemapper::Remapping> ImportRemapper::parseRemapping(std::string_view _input)\n{\n\tauto equals = std::find(_input.cbegin(), _input.cend(), '=');\n\tif (equals == _input.end())\n\t\treturn std::nullopt;\n\n\tauto const colon = std::find(_input.cbegin(), equals, ':');\n\n\tRemapping remapping{\n\t\t(colon == equals ? \"\" : std::string(_input.cbegin(), colon)),\n\t\t(colon == equals ? std::string(_input.cbegin(), equals) : std::string(colon + 1, equals)),\n\t\tstd::string(equals + 1, _input.cend()),\n\t};\n\n\tif (remapping.prefix.empty())\n\t\treturn std::nullopt;\n\n\treturn remapping;\n}\n\n}\n"
  },
  {
    "path": "libsolidity/interface/ImportRemapper.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <optional>\n#include <string>\n#include <vector>\n\nnamespace solidity::frontend\n{\n\n// Some helper typedefs to make reading the signatures more self explaining.\nusing SourceUnitName = std::string;\nusing SourceCode = std::string;\nusing ImportPath = std::string;\n\n/// The ImportRemapper is being used on imported file paths for being remapped to source unit IDs before being loaded.\nclass ImportRemapper\n{\npublic:\n\tstruct Remapping\n\t{\n\t\tbool operator!=(Remapping const& _other) const noexcept { return !(*this == _other); }\n\t\tbool operator==(Remapping const& _other) const noexcept\n\t\t{\n\t\t\treturn\n\t\t\t\tcontext == _other.context &&\n\t\t\t\tprefix == _other.prefix &&\n\t\t\t\ttarget == _other.target;\n\t\t}\n\n\t\tstd::string context;\n\t\tstd::string prefix;\n\t\tstd::string target;\n\t};\n\n\tvoid clear() { m_remappings.clear(); }\n\n\tvoid setRemappings(std::vector<Remapping> _remappings);\n\tstd::vector<Remapping> const& remappings() const noexcept { return m_remappings; }\n\n\tSourceUnitName apply(ImportPath const& _path, std::string const& _context) const;\n\n\t/// @returns true if the string can be parsed as a remapping\n\tstatic bool isRemapping(std::string_view _input);\n\n\t/// Parses a remapping of the format \"context:prefix=target\".\n\tstatic std::optional<Remapping> parseRemapping(std::string_view _input);\n\nprivate:\n\t/// list of path prefix remappings, e.g. mylibrary: github.com/argotorg = /usr/local/argotorg\n\t/// \"context:prefix=target\"\n\tstd::vector<Remapping> m_remappings = {};\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/Natspec.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Lefteris <lefteris@ethdev.com>\n * @date 2014\n * Takes the parsed AST and produces the Natspec documentation:\n * https://docs.soliditylang.org/en/latest/natspec-format.html\n *\n * Can generally deal with JSON files\n */\n\n#include <libsolidity/interface/Natspec.h>\n\n#include <libsolidity/ast/AST.h>\n\n#include <boost/algorithm/string.hpp>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\n\nJson Natspec::userDocumentation(ContractDefinition const& _contractDef)\n{\n\tJson doc;\n\n\tdoc[\"version\"] = Json(c_natspecVersion);\n\tdoc[\"kind\"]    = Json(\"user\");\n\tdoc[\"methods\"] = Json::object();\n\n\tauto constructorDefinition(_contractDef.constructor());\n\tif (constructorDefinition)\n\t{\n\t\tstd::string const value = extractDoc(constructorDefinition->annotation().docTags, \"notice\");\n\t\tif (!value.empty())\n\t\t{\n\t\t\t// add the constructor, only if we have any documentation to add\n\t\t\tJson user;\n\t\t\tuser[\"notice\"] = Json(value);\n\t\t\tdoc[\"methods\"][\"constructor\"] = user;\n\t\t}\n\t}\n\n\tstd::string notice = extractDoc(_contractDef.annotation().docTags, \"notice\");\n\tif (!notice.empty())\n\t\tdoc[\"notice\"] = Json(notice);\n\n\tfor (auto const& it: _contractDef.interfaceFunctions())\n\t\tif (it.second->hasDeclaration())\n\t\t{\n\t\t\tstd::string value;\n\n\t\t\tif (auto const* f = dynamic_cast<FunctionDefinition const*>(&it.second->declaration()))\n\t\t\t\tvalue = extractDoc(f->annotation().docTags, \"notice\");\n\t\t\telse if (auto var = dynamic_cast<VariableDeclaration const*>(&it.second->declaration()))\n\t\t\t{\n\t\t\t\tsolAssert(var->isStateVariable() && var->isPublic(), \"\");\n\t\t\t\tvalue = extractDoc(var->annotation().docTags, \"notice\");\n\t\t\t}\n\n\t\t\tif (!value.empty())\n\t\t\t\t// since @notice is the only user tag if missing function should not appear\n\t\t\t\tdoc[\"methods\"][it.second->externalSignature()][\"notice\"] = value;\n\t\t}\n\n\tfor (auto const& event: uniqueInterfaceEvents(_contractDef))\n\t{\n\t\tstd::string value = extractDoc(event->annotation().docTags, \"notice\");\n\t\tif (!value.empty())\n\t\t\tdoc[\"events\"][event->functionType(true)->externalSignature()][\"notice\"] = value;\n\t}\n\n\tfor (auto const& error: _contractDef.interfaceErrors())\n\t{\n\t\tstd::string value = extractDoc(error->annotation().docTags, \"notice\");\n\t\tif (!value.empty())\n\t\t{\n\t\t\tJson errorDoc;\n\t\t\terrorDoc[\"notice\"] = value;\n\t\t\tdoc[\"errors\"][error->functionType(true)->externalSignature()].emplace_back(std::move(errorDoc));\n\t\t}\n\t}\n\n\treturn doc;\n}\n\nJson Natspec::devDocumentation(ContractDefinition const& _contractDef)\n{\n\tJson doc = extractCustomDoc(_contractDef.annotation().docTags);\n\n\tdoc[\"version\"] = Json(c_natspecVersion);\n\tdoc[\"kind\"] = Json(\"dev\");\n\n\tauto author = extractDoc(_contractDef.annotation().docTags, \"author\");\n\tif (!author.empty())\n\t\tdoc[\"author\"] = author;\n\tauto title = extractDoc(_contractDef.annotation().docTags, \"title\");\n\tif (!title.empty())\n\t\tdoc[\"title\"] = title;\n\tauto dev = extractDoc(_contractDef.annotation().docTags, \"dev\");\n\tif (!dev.empty())\n\t\tdoc[\"details\"] = Json(dev);\n\n\tdoc[\"methods\"] = Json::object();\n\tauto constructorDefinition(_contractDef.constructor());\n\tif (constructorDefinition)\n\t{\n\t\tJson constructor(devDocumentation(constructorDefinition->annotation().docTags));\n\t\tif (!constructor.empty())\n\t\t\t// add the constructor, only if we have any documentation to add\n\t\t\tdoc[\"methods\"][\"constructor\"] = constructor;\n\t}\n\n\tfor (auto const& it: _contractDef.interfaceFunctions())\n\t{\n\t\tif (!it.second->hasDeclaration())\n\t\t\tcontinue;\n\t\tif (auto fun = dynamic_cast<FunctionDefinition const*>(&it.second->declaration()))\n\t\t{\n\t\t\tJson method(devDocumentation(fun->annotation().docTags));\n\t\t\t// add the function, only if we have any documentation to add\n\t\t\tJson jsonReturn = extractReturnParameterDocs(\n\t\t\t\tfun->annotation().docTags,\n\t\t\t\tfun->functionType(false)->returnParameterNames()\n\t\t\t);\n\n\t\t\tif (!jsonReturn.empty())\n\t\t\t\tmethod[\"returns\"] = std::move(jsonReturn);\n\n\t\t\tif (!method.empty())\n\t\t\t\tdoc[\"methods\"][it.second->externalSignature()] = std::move(method);\n\t\t}\n\t}\n\n\tfor (VariableDeclaration const* varDecl: _contractDef.stateVariables())\n\t{\n\t\tif (auto devDoc = devDocumentation(varDecl->annotation().docTags); !devDoc.empty())\n\t\t\tdoc[\"stateVariables\"][varDecl->name()] = devDoc;\n\n\t\tauto const assignIfNotEmpty = [&](std::string const& _name, Json const& _content)\n\t\t{\n\t\t\tif (!_content.empty())\n\t\t\t\tdoc[\"stateVariables\"][varDecl->name()][_name] = _content;\n\t\t};\n\n\t\tif (varDecl->annotation().docTags.count(\"return\") == 1)\n\t\t\tassignIfNotEmpty(\"return\", extractDoc(varDecl->annotation().docTags, \"return\"));\n\n\t\tif (FunctionTypePointer functionType = varDecl->functionType(false))\n\t\t\tassignIfNotEmpty(\"returns\", extractReturnParameterDocs(\n\t\t\t\tvarDecl->annotation().docTags,\n\t\t\t\tfunctionType->returnParameterNames()\n\t\t\t));\n\t}\n\n\tfor (auto const& event: uniqueInterfaceEvents(_contractDef))\n\t\tif (auto devDoc = devDocumentation(event->annotation().docTags); !devDoc.empty())\n\t\t\tdoc[\"events\"][event->functionType(true)->externalSignature()] = devDoc;\n\tfor (auto const& error: _contractDef.interfaceErrors())\n\t\tif (auto devDoc = devDocumentation(error->annotation().docTags); !devDoc.empty())\n\t\t\tdoc[\"errors\"][error->functionType(true)->externalSignature()].emplace_back(devDoc);\n\n\treturn doc;\n}\n\nJson Natspec::extractReturnParameterDocs(std::multimap<std::string, DocTag> const& _tags, std::vector<std::string> const& _returnParameterNames)\n{\n\tJson jsonReturn;\n\tauto returnDocs = _tags.equal_range(\"return\");\n\n\tif (!_returnParameterNames.empty())\n\t{\n\t\tsize_t n = 0;\n\t\tfor (auto i = returnDocs.first; i != returnDocs.second; i++)\n\t\t{\n\t\t\tstd::string paramName = _returnParameterNames.at(n);\n\t\t\tstd::string content = i->second.content;\n\n\t\t\tif (paramName.empty())\n\t\t\t\tparamName = \"_\" + std::to_string(n);\n\t\t\telse\n\t\t\t{\n\t\t\t\t//check to make sure the first word of the doc str is the same as the return name\n\t\t\t\tauto nameEndPos = content.find_first_of(\" \\t\");\n\t\t\t\tsolAssert(content.substr(0, nameEndPos) == paramName, \"No return param name given: \" + paramName);\n\t\t\t\tcontent = content.substr(nameEndPos+1);\n\t\t\t}\n\n\t\t\tjsonReturn[paramName] = Json(content);\n\t\t\tn++;\n\t\t}\n\t}\n\n\treturn jsonReturn;\n}\n\nstd::string Natspec::extractDoc(std::multimap<std::string, DocTag> const& _tags, std::string const& _name)\n{\n\tstd::string value;\n\tauto range = _tags.equal_range(_name);\n\tfor (auto i = range.first; i != range.second; i++)\n\t\tvalue += i->second.content;\n\treturn value;\n}\n\nJson Natspec::extractCustomDoc(std::multimap<std::string, DocTag> const& _tags)\n{\n\tstd::map<std::string, std::string> concatenated;\n\tfor (auto const& [tag, value]: _tags)\n\t\tif (boost::starts_with(tag, \"custom\"))\n\t\t\tconcatenated[tag] += value.content;\n\t// We do not want to create an object if there are no custom tags found.\n\tif (concatenated.empty())\n\t\treturn Json();\n\tJson result;\n\tfor (auto& [tag, value]: concatenated)\n\t\tresult[tag] = std::move(value);\n\treturn result;\n}\n\nJson Natspec::devDocumentation(std::multimap<std::string, DocTag> const& _tags)\n{\n\tJson json = extractCustomDoc(_tags);\n\tauto dev = extractDoc(_tags, \"dev\");\n\tif (!dev.empty())\n\t\tjson[\"details\"] = Json(dev);\n\n\tauto author = extractDoc(_tags, \"author\");\n\tif (!author.empty())\n\t\tjson[\"author\"] = author;\n\n\tJson params;\n\tauto paramRange = _tags.equal_range(\"param\");\n\tfor (auto i = paramRange.first; i != paramRange.second; ++i)\n\t\tparams[i->second.paramName] = Json(i->second.content);\n\n\tif (!params.empty())\n\t\tjson[\"params\"] = params;\n\n\treturn json;\n}\n\nstd::vector<EventDefinition const*>  Natspec::uniqueInterfaceEvents(ContractDefinition const& _contract)\n{\n\tauto eventSignature = [](EventDefinition const* _event) -> std::string {\n\t\tFunctionType const* functionType = _event->functionType(true);\n\t\tsolAssert(functionType, \"\");\n\t\treturn functionType->externalSignature();\n\t};\n\tauto compareBySignature =\n\t\t[&](EventDefinition const* _lhs, EventDefinition const* _rhs) -> bool {\n\t\t\treturn eventSignature(_lhs) < eventSignature(_rhs);\n\t\t};\n\n\tstd::set<EventDefinition const*, decltype(compareBySignature)> uniqueEvents{compareBySignature};\n\t// Insert events defined in the contract first so that in case of a conflict\n\t// they're the ones that get selected.\n\tuniqueEvents += _contract.definedInterfaceEvents();\n\n\tstd::set<EventDefinition const*, decltype(compareBySignature)> filteredUsedEvents{compareBySignature};\n\tstd::set<std::string> usedSignatures;\n\tfor (EventDefinition const* event: _contract.usedInterfaceEvents())\n\t{\n\t\tauto&& [eventIt, eventInserted] = filteredUsedEvents.insert(event);\n\t\tauto&& [signatureIt, signatureInserted] = usedSignatures.insert(eventSignature(event));\n\t\tif (!signatureInserted)\n\t\t\tfilteredUsedEvents.erase(eventIt);\n\t}\n\n\tuniqueEvents += filteredUsedEvents;\n\treturn util::convertContainer<std::vector<EventDefinition const*>>(std::move(uniqueEvents));\n}\n"
  },
  {
    "path": "libsolidity/interface/Natspec.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Lefteris <lefteris@ethdev.com>\n * @date 2014\n * Takes the parsed AST and produces the Natspec documentation:\n * https://docs.soliditylang.org/en/develop/natspec-format.html\n *\n * Can generally deal with JSON files\n */\n\n#pragma once\n\n#include <libsolutil/JSON.h>\n#include <libsolidity/ast/AST.h>\n#include <memory>\n#include <string>\n\nnamespace solidity::frontend\n{\n\n// Forward declarations\nclass ContractDefinition;\nstruct DocTag;\n\nclass Natspec\n{\npublic:\n\tstatic unsigned int constexpr c_natspecVersion = 1;\n\n\t/// Get the User documentation of the contract\n\t/// @param _contractDef The contract definition\n\t/// @return             A JSON representation of the contract's user documentation\n\tstatic Json userDocumentation(ContractDefinition const& _contractDef);\n\t/// Generates the Developer's documentation of the contract\n\t/// @param _contractDef The contract definition\n\t/// @return             A JSON representation\n\t///                     of the contract's developer documentation\n\tstatic Json devDocumentation(ContractDefinition const& _contractDef);\n\nprivate:\n\t/// @returns concatenation of all content under the given tag name.\n\tstatic std::string extractDoc(std::multimap<std::string, DocTag> const& _tags, std::string const& _name);\n\n\t/// Extract all custom tags from @a _tags.\n\tstatic Json extractCustomDoc(std::multimap<std::string, DocTag> const& _tags);\n\n\t/// Helper-function that will create a json object with dev specific annotations, if present.\n\t/// @param _tags docTags that are used.\n\t/// @return      A JSON representation\n\t///              of the contract's developer documentation\n\tstatic Json devDocumentation(std::multimap<std::string, DocTag> const& _tags);\n\n\t/// Helper-function that will create a json object for the \"returns\" field for a given function definition.\n\t/// @param _tags docTags that are used.\n\t/// @param _returnParameterNames names of the return parameters\n\t/// @return      A JSON representation\n\t///              of a method's return notice documentation\n\tstatic Json extractReturnParameterDocs(std::multimap<std::string, DocTag> const& _tags, std::vector<std::string> const& _returnParameterNames);\n\n\t/// Temporary function until https://github.com/argotorg/solidity/issues/11114 is implemented.\n\t/// @return all events defined in the contract and its base contracts and all events\n\t/// that are emitted during the execution of the contract, but allowing only unique signatures.\n\t/// In case of conflict between a library event and a contract one, selects the latter\n\t/// In case of conflict between two library events, none is selected\n\tstatic std::vector<EventDefinition const*> uniqueInterfaceEvents(ContractDefinition const& _contract);\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/OptimiserSettings.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Alex Beregszaszi\n * @date 2017\n * Helper class for optimiser settings.\n */\n\n#pragma once\n\n#include <liblangutil/Exceptions.h>\n\n#include <cstddef>\n#include <string>\n\nnamespace solidity::frontend\n{\n\nenum class OptimisationPreset\n{\n\tNone,\n\tMinimal,\n\tStandard,\n\tFull,\n};\n\nstruct OptimiserSettings\n{\n\tstatic char constexpr DefaultYulOptimiserSteps[] =\n\t\t\"dfDvulfnTUtnIf\"               // None of these can make stack problems worse\n\n\t\t\"xa[r]EscLM\"                   // Turn into SSA and simplify\n\t\t\"Vcul [j]\"                     // Reverse SSA\n\n\t\t// should have good \"compilability\" property here.\n\n\t\t\"Trpeul\"                       // Run functional expression inliner\n\t\t\"xa[r]cL\"                      // Turn into SSA again and simplify\n\t\t\"vifM\"                         // Run full inliner\n\t\t\"CTUca[r]LSsTFOtfDnca[r]Iulc\"  // SSA plus simplify\n\n\t\t\"scCTUt\"\n\t\t\"vifM\"                         // Run full inliner\n\t\t\"x[scCTUt] TOntnfDIul\"         // Perform structural simplification\n\t\t\"vifM\"                         // Run full inliner\n\n\t\t\"jmul[jul] VcTOcul jmul\";      // Make source short and pretty\n\n\tstatic char constexpr DefaultYulOptimiserCleanupSteps[] = \"fDnTOcmuO\";\n\n\t/// No optimisations at all - not recommended.\n\tstatic OptimiserSettings none()\n\t{\n\t\treturn {};\n\t}\n\t/// Minimal optimisations: Peephole and jumpdest remover\n\tstatic OptimiserSettings minimal()\n\t{\n\t\tOptimiserSettings s = none();\n\t\ts.runJumpdestRemover = true;\n\t\ts.runPeephole = true;\n\t\ts.simpleCounterForLoopUncheckedIncrement = true;\n\t\treturn s;\n\t}\n\t/// Standard optimisations.\n\tstatic OptimiserSettings standard()\n\t{\n\t\tOptimiserSettings s;\n\t\ts.runOrderLiterals = true;\n\t\ts.runInliner = true;\n\t\ts.runJumpdestRemover = true;\n\t\ts.runPeephole = true;\n\t\ts.runDeduplicate = true;\n\t\ts.runCSE = true;\n\t\ts.runConstantOptimiser = true;\n\t\ts.simpleCounterForLoopUncheckedIncrement = true;\n\t\ts.runYulOptimiser = true;\n\t\ts.optimizeStackAllocation = true;\n\t\treturn s;\n\t}\n\t/// Full optimisations. Currently an alias for standard optimisations.\n\tstatic OptimiserSettings full()\n\t{\n\t\treturn standard();\n\t}\n\n\tstatic OptimiserSettings preset(OptimisationPreset _preset)\n\t{\n\t\tswitch (_preset)\n\t\t{\n\t\t\tcase OptimisationPreset::None: return none();\n\t\t\tcase OptimisationPreset::Minimal: return minimal();\n\t\t\tcase OptimisationPreset::Standard: return standard();\n\t\t\tcase OptimisationPreset::Full: return full();\n\t\t}\n\t\tutil::unreachable();\n\t}\n\n\tbool operator==(OptimiserSettings const& _other) const = default;\n\tbool operator!=(OptimiserSettings const& _other) const = default;\n\n\t/// Move literals to the right of commutative binary operators during code generation.\n\t/// This helps exploiting associativity.\n\tbool runOrderLiterals = false;\n\t/// Inliner\n\tbool runInliner = false;\n\t/// Non-referenced jump destination remover.\n\tbool runJumpdestRemover = false;\n\t/// Peephole optimizer\n\tbool runPeephole = false;\n\t/// Assembly block deduplicator\n\tbool runDeduplicate = false;\n\t/// Common subexpression eliminator based on assembly items.\n\tbool runCSE = false;\n\t/// Constant optimizer, which tries to find better representations that satisfy the given\n\t/// size/cost-trade-off.\n\tbool runConstantOptimiser = false;\n\t/// Allow unchecked arithmetic when incrementing the counter of certain kinds of 'for' loop\n\tbool simpleCounterForLoopUncheckedIncrement = false;\n\t/// Perform more efficient stack allocation for variables during code generation from Yul to bytecode.\n\tbool optimizeStackAllocation = false;\n\t/// Yul optimiser with default settings. Will only run on certain parts of the code for now.\n\tbool runYulOptimiser = false;\n\t/// Sequence of optimisation steps to be performed by Yul optimiser.\n\t/// Note that there are some hard-coded steps in the optimiser and you cannot disable\n\t/// them just by setting this to an empty string. Set @a runYulOptimiser to false if you want\n\t/// no optimisations.\n\tstd::string yulOptimiserSteps = DefaultYulOptimiserSteps;\n\t/// Sequence of clean-up optimisation steps after yulOptimiserSteps is run. Note that if the string\n\t/// is left empty, there will still be hard-coded optimisation steps that will run regardless.\n\t/// Set @a runYulOptimiser to false if you want no optimisations.\n\tstd::string yulOptimiserCleanupSteps = DefaultYulOptimiserCleanupSteps;\n\t/// This specifies an estimate on how often each opcode in this assembly will be executed,\n\t/// i.e. use a small value to optimise for size and a large value to optimise for runtime gas usage.\n\tsize_t expectedExecutionsPerDeployment = 200;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/ReadFile.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <liblangutil/Exceptions.h>\n\n#include <functional>\n#include <string>\n\nnamespace solidity::frontend\n{\n\nclass ReadCallback\n{\npublic:\n\t/// Noncopyable.\n\tReadCallback(ReadCallback const&) = delete;\n\tReadCallback& operator=(ReadCallback const&) = delete;\n\n\t/// File reading or generic query result.\n\tstruct Result\n\t{\n\t\tbool success;\n\t\tstd::string responseOrErrorMessage;\n\t};\n\n\tenum class Kind\n\t{\n\t\tReadFile,\n\t\tSMTQuery\n\t};\n\n\tstatic std::string kindString(Kind _kind)\n\t{\n\t\tswitch (_kind)\n\t\t{\n\t\tcase Kind::ReadFile:\n\t\t\treturn \"source\";\n\t\tcase Kind::SMTQuery:\n\t\t\treturn \"smt-query\";\n\t\tdefault:\n\t\t\tsolAssert(false, \"\");\n\t\t}\n\t}\n\n\t/// File reading or generic query callback.\n\tusing Callback = std::function<Result(std::string const&, std::string const&)>;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/SMTSolverCommand.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/interface/SMTSolverCommand.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <boost/algorithm/string/join.hpp>\n#include <boost/version.hpp>\n#if (BOOST_VERSION < 108800)\n#include <boost/process.hpp>\n#else\n#define BOOST_PROCESS_VERSION 1\n#include <boost/process/v1/child.hpp>\n#include <boost/process/v1/io.hpp>\n#include <boost/process/v1/pipe.hpp>\n#include <boost/process/v1/search_path.hpp>\n#endif\n\nnamespace solidity::frontend\n{\n\nvoid SMTSolverCommand::setEldarica(std::optional<unsigned int> timeoutInMilliseconds, bool computeInvariants)\n{\n\tm_arguments.clear();\n\tm_solverCmd = \"eld\";\n\tm_arguments.emplace_back(\"-hsmt\"); // Tell Eldarica to expect input in SMT2 format\n\tm_arguments.emplace_back(\"-in\"); // Tell Eldarica to read from standard input\n\tif (timeoutInMilliseconds)\n\t{\n\t\tunsigned int timeoutInSeconds = timeoutInMilliseconds.value() / 1000u;\n\t\ttimeoutInSeconds = timeoutInSeconds == 0 ? 1 : timeoutInSeconds;\n\t\tm_arguments.push_back(\"-t:\" + std::to_string(timeoutInSeconds));\n\t}\n\tif (computeInvariants)\n\t\tm_arguments.emplace_back(\"-ssol\"); // Tell Eldarica to produce model (invariant)\n}\n\nvoid SMTSolverCommand::setCvc5(std::optional<unsigned int> timeoutInMilliseconds)\n{\n\tm_arguments.clear();\n\tm_solverCmd = \"cvc5\";\n\tif (timeoutInMilliseconds)\n\t{\n\t\tm_arguments.emplace_back(\"--tlimit-per\");\n\t\tm_arguments.push_back(std::to_string(timeoutInMilliseconds.value()));\n\t}\n\telse\n\t{\n\t\tm_arguments.emplace_back(\"--rlimit\"); // Set resource limit cvc5 can spend on a query\n\t\tm_arguments.push_back(std::to_string(12000));\n\t}\n}\n\nvoid SMTSolverCommand::setZ3(std::optional<unsigned int> timeoutInMilliseconds, bool _preprocessing, bool _computeInvariants)\n{\n\tconstexpr int Z3ResourceLimit = 2000000;\n\tm_arguments.clear();\n\tm_solverCmd = \"z3\";\n\tm_arguments.emplace_back(\"-in\"); // Read from standard input\n\tm_arguments.emplace_back(\"-smt2\"); // Expect input in SMT-LIB2 format\n\tif (_computeInvariants)\n\t\tm_arguments.emplace_back(\"-model\"); // Output model automatically after check-sat\n\tif (timeoutInMilliseconds)\n\t\tm_arguments.emplace_back(\"-t:\" + std::to_string(timeoutInMilliseconds.value()));\n\telse\n\t\tm_arguments.emplace_back(\"rlimit=\" + std::to_string(Z3ResourceLimit));\n\n\t// These options have been empirically established to be helpful\n\tm_arguments.emplace_back(\"rewriter.pull_cheap_ite=true\");\n\tm_arguments.emplace_back(\"fp.spacer.q3.use_qgen=true\");\n\tm_arguments.emplace_back(\"fp.spacer.mbqi=false\");\n\tm_arguments.emplace_back(\"fp.spacer.ground_pobs=false\");\n\n\t// Spacer optimization should be\n\t// - enabled for better solving (default)\n\t// - disable for counterexample generation\n\tstd::string preprocessingArg = _preprocessing ? \"true\" : \"false\";\n\tm_arguments.emplace_back(\"fp.xform.slice=\" + preprocessingArg);\n\tm_arguments.emplace_back(\"fp.xform.inline_linear=\" + preprocessingArg);\n\tm_arguments.emplace_back(\"fp.xform.inline_eager=\" + preprocessingArg);\n}\n\nReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::string const& _query) const\n{\n\ttry\n\t{\n\t\tif (_kind != ReadCallback::kindString(ReadCallback::Kind::SMTQuery))\n\t\t\tsolAssert(false, \"SMTQuery callback used as callback kind \" + _kind);\n\n\t\tif (m_solverCmd.empty())\n\t\t\treturn ReadCallback::Result{false, \"No solver set.\"};\n\n\t\tauto solverBin = boost::process::search_path(m_solverCmd);\n\n\t\tif (solverBin.empty())\n\t\t\treturn ReadCallback::Result{false, m_solverCmd + \" binary not found.\"};\n\n\t\tauto args = m_arguments;\n\n\t\tboost::process::opstream in;  // input to subprocess written to by the main process\n\t\tboost::process::ipstream out; // output from subprocess read by the main process\n\t\tboost::process::child solverProcess(\n\t\t\tsolverBin,\n\t\t\targs,\n\t\t\tboost::process::std_out > out,\n\t\t\tboost::process::std_in < in,\n\t\t\tboost::process::std_err > boost::process::null\n\t\t);\n\n\t\tin << _query << std::flush;\n\t\tin.pipe().close();\n\t\tin.close();\n\n\t\tstd::vector<std::string> data;\n\t\tstd::string line;\n\t\twhile (!(out.fail() || out.eof()) && std::getline(out, line))\n\t\t\tif (!line.empty())\n\t\t\t\tdata.push_back(line);\n\n\t\tsolverProcess.wait();\n\n\t\treturn ReadCallback::Result{true, boost::join(data, \"\\n\")};\n\t}\n\tcatch (...)\n\t{\n\t\treturn ReadCallback::Result{false, \"Exception in SMTQuery callback: \" + boost::current_exception_diagnostic_information()};\n\t}\n}\n\n}\n"
  },
  {
    "path": "libsolidity/interface/SMTSolverCommand.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/interface/ReadFile.h>\n\n#include <boost/filesystem.hpp>\n\nnamespace solidity::frontend\n{\n\n/// SMTSolverCommand wraps an SMT solver called via its binary in the OS.\nclass SMTSolverCommand\n{\npublic:\n\t/// Calls an SMT solver with the given query.\n\tfrontend::ReadCallback::Result solve(std::string const& _kind, std::string const& _query) const;\n\n\tfrontend::ReadCallback::Callback solver() const\n\t{\n\t\treturn [this](std::string const& _kind, std::string const& _query) { return solve(_kind, _query); };\n\t}\n\n\tvoid setEldarica(std::optional<unsigned int> timeoutInMilliseconds, bool computeInvariants);\n\tvoid setCvc5(std::optional<unsigned int> timeoutInMilliseconds);\n\tvoid setZ3(std::optional<unsigned int> timeoutInMilliseconds, bool _preprocessing, bool _computeInvariants);\n\nprivate:\n\t/// The name of the solver's binary.\n\tstd::string m_solverCmd;\n\tstd::vector<std::string> m_arguments;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/StandardCompiler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Alex Beregszaszi\n * @date 2016\n * Standard JSON compiler interface.\n */\n\n#include <libsolidity/interface/StandardCompiler.h>\n#include <libsolidity/interface/ImportRemapper.h>\n\n#include <libsolidity/ast/ASTJsonExporter.h>\n#include <libyul/YulStack.h>\n#include <libyul/Exceptions.h>\n#include <libyul/optimiser/Suite.h>\n\n#include <libevmasm/Disassemble.h>\n#include <libevmasm/Ethdebug.h>\n#include <libevmasm/EVMAssemblyStack.h>\n\n#include <libsmtutil/Exceptions.h>\n\n#include <liblangutil/SourceReferenceFormatter.h>\n\n#include <libsolutil/JSON.h>\n#include <libsolutil/Keccak256.h>\n#include <libsolutil/CommonData.h>\n\n#include <boost/algorithm/string/predicate.hpp>\n\n#include <algorithm>\n#include <optional>\n\n#include <range/v3/algorithm/contains.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\nusing namespace std::string_literals;\n\nnamespace\n{\n\nJson formatError(\n\tError::Type _type,\n\tstd::string const& _component,\n\tstd::string const& _message,\n\tstd::string const& _formattedMessage = \"\",\n\tJson const& _sourceLocation = Json(),\n\tJson const& _secondarySourceLocation = Json()\n)\n{\n\tJson error;\n\terror[\"type\"] = Error::formatErrorType(_type);\n\terror[\"component\"] = _component;\n\terror[\"severity\"] = Error::formatErrorSeverityLowercase(Error::errorSeverity(_type));\n\terror[\"message\"] = _message;\n\terror[\"formattedMessage\"] = (_formattedMessage.length() > 0) ? _formattedMessage : _message;\n\tif (_sourceLocation.is_object())\n\t\terror[\"sourceLocation\"] = _sourceLocation;\n\tif (_secondarySourceLocation.is_array())\n\t\terror[\"secondarySourceLocations\"] = _secondarySourceLocation;\n\treturn error;\n}\n\nJson formatFatalError(Error::Type _type, std::string const& _message)\n{\n\tJson output;\n\toutput[\"errors\"] = Json::array();\n\toutput[\"errors\"].emplace_back(formatError(_type, \"general\", _message));\n\treturn output;\n}\n\nJson formatSourceLocation(SourceLocation const* location)\n{\n\tif (!location || !location->sourceName)\n\t\treturn Json();\n\n\tJson sourceLocation;\n\tsourceLocation[\"file\"] = *location->sourceName;\n\tsourceLocation[\"start\"] = location->start;\n\tsourceLocation[\"end\"] = location->end;\n\treturn sourceLocation;\n}\n\nJson formatSecondarySourceLocation(SecondarySourceLocation const* _secondaryLocation)\n{\n\tif (!_secondaryLocation)\n\t\treturn Json();\n\n\tJson secondarySourceLocation = Json::array();\n\tfor (auto const& location: _secondaryLocation->infos)\n\t{\n\t\tJson msg = formatSourceLocation(&location.second);\n\t\tmsg[\"message\"] = location.first;\n\t\tsecondarySourceLocation.emplace_back(msg);\n\t}\n\treturn secondarySourceLocation;\n}\n\nJson formatErrorWithException(\n\tCharStreamProvider const& _charStreamProvider,\n\tutil::Exception const& _exception,\n\tError::Type _type,\n\tstd::string const& _component,\n\tstd::string const& _message,\n\tstd::optional<ErrorId> _errorId = std::nullopt\n)\n{\n\tstd::string message;\n\t// TODO: consider enabling color\n\tstd::string formattedMessage = SourceReferenceFormatter::formatExceptionInformation(\n\t\t_exception,\n\t\t_type,\n\t\t_charStreamProvider,\n\t\tfalse // colored\n\t);\n\n\tif (std::string const* description = _exception.comment())\n\t\tmessage = ((_message.length() > 0) ? (_message + \": \") : \"\") + *description;\n\telse\n\t\tmessage = _message;\n\n\tJson error = formatError(\n\t\t_type,\n\t\t_component,\n\t\tmessage,\n\t\tformattedMessage,\n\t\tformatSourceLocation(boost::get_error_info<errinfo_sourceLocation>(_exception)),\n\t\tformatSecondarySourceLocation(boost::get_error_info<errinfo_secondarySourceLocation>(_exception))\n\t);\n\n\tif (_errorId)\n\t\terror[\"errorCode\"] = std::to_string(_errorId.value().error);\n\n\treturn error;\n}\n\n/// Returns true iff @a _hash (hex with 0x prefix) is the Keccak256 hash of the binary data in @a _content.\nbool hashMatchesContent(std::string const& _hash, std::string const& _content)\n{\n\ttry\n\t{\n\t\treturn util::h256(_hash) == util::keccak256(_content);\n\t}\n\tcatch (util::BadHexCharacter const&)\n\t{\n\t\treturn false;\n\t}\n}\n\nbool isArtifactRequested(Json const& _outputSelection, std::string const& _artifact, bool _wildcardMatchesExperimental)\n{\n\tstatic std::set<std::string> experimental{\"ir\", \"irAst\", \"irOptimized\", \"irOptimizedAst\", \"yulCFGJson\", \"ethdebug\"};\n\tfor (auto const& selectedArtifactJson: _outputSelection)\n\t{\n\t\tstd::string const& selectedArtifact = selectedArtifactJson.get<std::string>();\n\t\tif (\n\t\t\t_artifact == selectedArtifact ||\n\t\t\tboost::algorithm::starts_with(_artifact, selectedArtifact + \".\")\n\t\t)\n\t\t{\n\t\t\tif (_artifact.find(\"ethdebug\") != std::string::npos)\n\t\t\t\t// only accept exact matches for ethdebug, e.g. evm.bytecode.ethdebug\n\t\t\t\treturn selectedArtifact == _artifact;\n\t\t\treturn true;\n\t\t}\n\t\telse if (selectedArtifact == \"*\")\n\t\t{\n\t\t\t// TODO: yulCFGJson is only experimental now, so it should not be matched by \"*\".\n\t\t\tif (_artifact == \"yulCFGJson\")\n\t\t\t\treturn false;\n\t\t\t// TODO: everything ethdebug related is only experimental for now, so it should not be matched by \"*\".\n\t\t\tif (_artifact.find(\"ethdebug\") != std::string::npos)\n\t\t\t\treturn false;\n\t\t\t// \"ir\", \"irOptimized\" can only be matched by \"*\" if activated.\n\t\t\tif (experimental.count(_artifact) == 0 || _wildcardMatchesExperimental)\n\t\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n///\n/// @a _outputSelection is a JSON object containing a two-level hashmap, where the first level is the filename,\n/// the second level is the contract name and the value is an array of artifact names to be requested for that contract.\n/// @a _file is the current file\n/// @a _contract is the current contract\n/// @a _artifact is the current artifact name\n///\n/// @returns true if the @a _outputSelection has a match for the requested target in the specific file / contract.\n///\n/// In @a _outputSelection the use of '*' as a wildcard is permitted.\n///\n/// @TODO optimise this. Perhaps flatten the structure upfront.\n///\nbool isArtifactRequested(Json const& _outputSelection, std::string const& _file, std::string const& _contract, std::string const& _artifact, bool _wildcardMatchesExperimental)\n{\n\tif (!_outputSelection.is_object())\n\t\treturn false;\n\n\tfor (auto const& file: { _file, std::string(\"*\") })\n\t\tif (_outputSelection.contains(file) && _outputSelection[file].is_object())\n\t\t{\n\t\t\t/// For SourceUnit-level targets (such as AST) only allow empty name, otherwise\n\t\t\t/// for Contract-level targets try both contract name and wildcard\n\t\t\tstd::vector<std::string> contracts{ _contract };\n\t\t\tif (!_contract.empty())\n\t\t\t\tcontracts.emplace_back(\"*\");\n\t\t\tfor (auto const& contract: contracts)\n\t\t\t\tif (\n\t\t\t\t\t_outputSelection[file].contains(contract) &&\n\t\t\t\t\t_outputSelection[file][contract].is_array() &&\n\t\t\t\t\tisArtifactRequested(_outputSelection[file][contract], _artifact, _wildcardMatchesExperimental)\n\t\t\t\t)\n\t\t\t\t\treturn true;\n\t\t}\n\n\treturn false;\n}\n\nbool isArtifactRequested(Json const& _outputSelection, std::string const& _file, std::string const& _contract, std::vector<std::string> const& _artifacts, bool _wildcardMatchesExperimental)\n{\n\tfor (auto const& artifact: _artifacts)\n\t\tif (isArtifactRequested(_outputSelection, _file, _contract, artifact, _wildcardMatchesExperimental))\n\t\t\treturn true;\n\treturn false;\n}\n\n/// @returns all artifact names of the EVM object, either for creation or deploy time.\nstd::vector<std::string> evmObjectComponents(std::string const& _objectKind)\n{\n\tsolAssert(_objectKind == \"bytecode\" || _objectKind == \"deployedBytecode\", \"\");\n\tstd::vector<std::string> components{\"\", \".object\", \".opcodes\", \".sourceMap\", \".functionDebugData\", \".generatedSources\", \".linkReferences\", \".ethdebug\"};\n\tif (_objectKind == \"deployedBytecode\")\n\t\tcomponents.push_back(\".immutableReferences\");\n\treturn util::applyMap(components, [&](auto const& _s) { return \"evm.\" + _objectKind + _s; });\n}\n\n/// @returns true if any binary was requested, i.e. we actually have to perform compilation.\nbool isBinaryRequested(Json const& _outputSelection)\n{\n\tif (!_outputSelection.is_object())\n\t\treturn false;\n\n\t// This does not include \"evm.methodIdentifiers\" on purpose!\n\tstatic std::vector<std::string> const outputsThatRequireBinaries = std::vector<std::string>{\n\t\t\"*\",\n\t\t\"ir\", \"irAst\", \"irOptimized\", \"irOptimizedAst\", \"yulCFGJson\",\n\t\t\"evm.gasEstimates\", \"evm.legacyAssembly\", \"evm.assembly\", \"ethdebug\"\n\t} + evmObjectComponents(\"bytecode\") + evmObjectComponents(\"deployedBytecode\");\n\n\tfor (auto const& fileRequests: _outputSelection)\n\t\tfor (auto const& requests: fileRequests)\n\t\t\tfor (auto const& output: outputsThatRequireBinaries)\n\t\t\t\tif (isArtifactRequested(requests, output, false))\n\t\t\t\t\treturn true;\n\treturn false;\n}\n\n/// @returns true if EVM bytecode was requested, i.e. we have to run the old code generator.\nbool isEvmBytecodeRequested(Json const& _outputSelection)\n{\n\tif (!_outputSelection.is_object())\n\t\treturn false;\n\n\tstatic std::vector<std::string> const outputsThatRequireEvmBinaries = std::vector<std::string>{\n\t\t\"*\",\n\t\t\"evm.gasEstimates\", \"evm.legacyAssembly\", \"evm.assembly\"\n\t} + evmObjectComponents(\"bytecode\") + evmObjectComponents(\"deployedBytecode\");\n\n\tfor (auto const& fileRequests: _outputSelection)\n\t\tfor (auto const& requests: fileRequests)\n\t\t\tfor (auto const& output: outputsThatRequireEvmBinaries)\n\t\t\t\tif (isArtifactRequested(requests, output, false))\n\t\t\t\t\treturn true;\n\treturn false;\n}\n\n/// @returns true if ethdebug was requested.\nbool isEthdebugRequested(Json const& _outputSelection)\n{\n\tif (!_outputSelection.is_object())\n\t\treturn false;\n\n\tstatic std::array<std::string, 2> const ethdebugArtifacts{\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"};\n\n\tfor (auto const& fileRequests: _outputSelection)\n\t\tfor (auto const& requests: fileRequests)\n\t\t\tfor (auto const& request: requests)\n\t\t\t\tif (ranges::contains(ethdebugArtifacts, request.get<std::string>()))\n\t\t\t\t\treturn true;\n\n\treturn false;\n}\n\nbool isExperimentalArtifactRequested(Json const& _outputSelection)\n{\n\tstatic std::array<std::string, 3> const experimentalArtifacts{\"irAst\", \"irOptimizedAst\", \"yulCFGJson\"};\n\n\tif (isEthdebugRequested(_outputSelection))\n\t\treturn true;\n\n\tfor (auto const& fileRequests: _outputSelection)\n\t\tfor (auto const& requests: fileRequests)\n\t\t\tfor (auto const& request: requests)\n\t\t\t\tif (ranges::contains(experimentalArtifacts, request.get<std::string>()))\n\t\t\t\t\treturn true;\n\n\treturn false;\n}\n\n/// @returns The set of selected contracts, along with their compiler pipeline configuration, based\n/// on outputs requested in the JSON. Translates wildcards to the ones understood by CompilerStack.\n/// Note that as an exception, '*' does not yet match \"ir\", \"irAst\", \"irOptimized\" or \"irOptimizedAst\".\nCompilerStack::ContractSelection pipelineConfig(\n\tJson const& _jsonOutputSelection\n)\n{\n\tif (!_jsonOutputSelection.is_object())\n\t\treturn {};\n\n\tCompilerStack::ContractSelection contractSelection;\n\tfor (auto const& [sourceUnitName, jsonOutputSelectionForSource]: _jsonOutputSelection.items())\n\t{\n\t\tsolAssert(jsonOutputSelectionForSource.is_object());\n\t\tfor (auto const& [contractName, jsonOutputSelectionForContract]: jsonOutputSelectionForSource.items())\n\t\t{\n\t\t\tsolAssert(jsonOutputSelectionForContract.is_array());\n\t\t\tCompilerStack::PipelineConfig pipelineForContract;\n\t\t\tfor (Json const& request: jsonOutputSelectionForContract)\n\t\t\t{\n\t\t\t\tsolAssert(request.is_string());\n\t\t\t\tpipelineForContract.irOptimization =\n\t\t\t\t\tpipelineForContract.irOptimization ||\n\t\t\t\t\trequest == \"irOptimized\" ||\n\t\t\t\t\trequest == \"irOptimizedAst\" ||\n\t\t\t\t\trequest == \"yulCFGJson\";\n\t\t\t\tpipelineForContract.irCodegen =\n\t\t\t\t\tpipelineForContract.irCodegen ||\n\t\t\t\t\tpipelineForContract.irOptimization ||\n\t\t\t\t\trequest == \"ir\" ||\n\t\t\t\t\trequest == \"irAst\";\n\t\t\t\tpipelineForContract.bytecode = isEvmBytecodeRequested(_jsonOutputSelection);\n\t\t\t}\n\t\t\tstd::string key = (sourceUnitName == \"*\") ? \"\" : sourceUnitName;\n\t\t\tstd::string value = (contractName == \"*\") ? \"\" : contractName;\n\t\t\tcontractSelection[key][value] = pipelineForContract;\n\t\t}\n\t}\n\treturn contractSelection;\n}\n\nJson formatLinkReferences(std::map<size_t, std::string> const& linkReferences)\n{\n\tJson ret = Json::object();\n\n\tfor (auto const& ref: linkReferences)\n\t{\n\t\tstd::string const& fullname = ref.second;\n\n\t\t// If the link reference does not contain a colon, assume that the file name is missing and\n\t\t// the whole string represents the library name.\n\t\tsize_t colon = fullname.rfind(':');\n\t\tstd::string file = (colon != std::string::npos ? fullname.substr(0, colon) : \"\");\n\t\tstd::string name = (colon != std::string::npos ? fullname.substr(colon + 1) : fullname);\n\n\t\tJson fileObject = ret.value(file, Json::object());\n\t\tJson libraryArray = fileObject.value(name, Json::array());\n\n\t\tJson entry;\n\t\tentry[\"start\"] = Json(ref.first);\n\t\tentry[\"length\"] = 20;\n\n\t\tlibraryArray.emplace_back(entry);\n\t\tfileObject[name] = libraryArray;\n\t\tret[file] = fileObject;\n\t}\n\n\treturn ret;\n}\n\nJson formatImmutableReferences(std::map<u256, evmasm::LinkerObject::ImmutableRefs> const& _immutableReferences)\n{\n\tJson ret = Json::object();\n\n\tfor (auto const& immutableReference: _immutableReferences)\n\t{\n\t\tauto const& [identifier, byteOffsets] = immutableReference.second;\n\t\tJson array = Json::array();\n\t\tfor (size_t byteOffset: byteOffsets)\n\t\t{\n\t\t\tJson byteRange;\n\t\t\tbyteRange[\"start\"] = Json::number_unsigned_t(byteOffset);\n\t\t\tbyteRange[\"length\"] = Json::number_unsigned_t(32); // immutable references are currently always 32 bytes wide\n\t\t\tarray.emplace_back(byteRange);\n\t\t}\n\t\tret[identifier] = array;\n\t}\n\n\treturn ret;\n}\n\nstd::optional<Json> checkKeys(Json const& _input, std::set<std::string> const& _keys, std::string const& _name)\n{\n\tif (!_input.empty() && !_input.is_object())\n\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"\" + _name + \"\\\" must be an object\");\n\n\tfor (auto const& [member, _]: _input.items())\n\t\tif (!_keys.count(member))\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"Unknown key \\\"\" + member + \"\\\"\");\n\n\treturn std::nullopt;\n}\n\nstd::optional<Json> checkRootKeys(Json const& _input)\n{\n\tstatic std::set<std::string> keys{\"auxiliaryInput\", \"language\", \"settings\", \"sources\"};\n\treturn checkKeys(_input, keys, \"root\");\n}\n\nstd::optional<Json> checkSourceKeys(Json const& _input, std::string const& _name)\n{\n\tstatic std::set<std::string> keys{\"content\", \"keccak256\", \"urls\"};\n\treturn checkKeys(_input, keys, \"sources.\" + _name);\n}\n\nstd::optional<Json> checkAuxiliaryInputKeys(Json const& _input)\n{\n\tstatic std::set<std::string> keys{\"smtlib2responses\"};\n\treturn checkKeys(_input, keys, \"auxiliaryInput\");\n}\n\nstd::optional<Json> checkSettingsKeys(Json const& _input)\n{\n\tstatic std::set<std::string> keys{\"debug\", \"evmVersion\", \"experimental\", \"eofVersion\", \"libraries\", \"metadata\", \"modelChecker\", \"optimizer\", \"outputSelection\", \"remappings\", \"stopAfter\", \"viaIR\", \"viaSSACFG\"};\n\treturn checkKeys(_input, keys, \"settings\");\n}\n\nstd::optional<Json> checkModelCheckerSettingsKeys(Json const& _input)\n{\n\tstatic std::set<std::string> keys{\"bmcLoopIterations\", \"contracts\", \"divModNoSlacks\", \"engine\", \"extCalls\", \"invariants\", \"printQuery\", \"showProvedSafe\", \"showUnproved\", \"showUnsupported\", \"solvers\", \"targets\", \"timeout\"};\n\treturn checkKeys(_input, keys, \"modelChecker\");\n}\n\nstd::optional<Json> checkOptimizerKeys(Json const& _input)\n{\n\tstatic std::set<std::string> keys{\"details\", \"enabled\", \"runs\"};\n\treturn checkKeys(_input, keys, \"settings.optimizer\");\n}\n\nstd::optional<Json> checkOptimizerDetailsKeys(Json const& _input)\n{\n\tstatic std::set<std::string> keys{\"peephole\", \"inliner\", \"jumpdestRemover\", \"orderLiterals\", \"deduplicate\", \"cse\", \"constantOptimizer\", \"yul\", \"yulDetails\", \"simpleCounterForLoopUncheckedIncrement\"};\n\treturn checkKeys(_input, keys, \"settings.optimizer.details\");\n}\n\nstd::optional<Json> checkOptimizerDetail(Json const& _details, std::string const& _name, bool& _setting)\n{\n\tif (_details.contains(_name))\n\t{\n\t\tif (!_details[_name].is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"settings.optimizer.details.\" + _name + \"\\\" must be Boolean\");\n\t\t_setting = _details[_name].get<bool>();\n\t}\n\treturn {};\n}\n\nstd::optional<Json> checkOptimizerDetailSteps(Json const& _details, std::string const& _name, std::string& _optimiserSetting, std::string& _cleanupSetting, bool _runYulOptimizer)\n{\n\tif (_details.contains(_name))\n\t{\n\t\tif (_details[_name].is_string())\n\t\t{\n\t\t\tstd::string const fullSequence = _details[_name].get<std::string>();\n\t\t\tif (!_runYulOptimizer && !OptimiserSuite::isEmptyOptimizerSequence(fullSequence))\n\t\t\t{\n\t\t\t\tstd::string errorMessage =\n\t\t\t\t\t\"If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted.\"\n\t\t\t\t\t\" Note that the empty optimizer sequence is properly denoted by \\\":\\\".\";\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, errorMessage);\n\t\t\t}\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyul::OptimiserSuite::validateSequence(_details[_name].get<std::string>());\n\t\t\t}\n\t\t\tcatch (yul::OptimizerException const& _exception)\n\t\t\t{\n\t\t\t\treturn formatFatalError(\n\t\t\t\t\tError::Type::JSONError,\n\t\t\t\t\t\"Invalid optimizer step sequence in \\\"settings.optimizer.details.\" + _name + \"\\\": \" + _exception.what()\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tauto const delimiterPos = fullSequence.find(\":\");\n\t\t\t_optimiserSetting = fullSequence.substr(0, delimiterPos);\n\n\t\t\tif (delimiterPos != std::string::npos)\n\t\t\t\t_cleanupSetting = fullSequence.substr(delimiterPos + 1);\n\t\t\telse\n\t\t\t\tsolAssert(_cleanupSetting == OptimiserSettings::DefaultYulOptimiserCleanupSteps);\n\t\t}\n\t\telse\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"settings.optimizer.details.\" + _name + \"\\\" must be a string\");\n\n\t}\n\treturn {};\n}\n\nstd::optional<Json> checkMetadataKeys(Json const& _input)\n{\n\tif (_input.is_object())\n\t{\n\t\tif (_input.contains(\"appendCBOR\") && !_input[\"appendCBOR\"].is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"settings.metadata.appendCBOR\\\" must be Boolean\");\n\t\tif (_input.contains(\"useLiteralContent\") && !_input[\"useLiteralContent\"].is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"settings.metadata.useLiteralContent\\\" must be Boolean\");\n\n\t\tstatic std::set<std::string> hashes{\"ipfs\", \"bzzr1\", \"none\"};\n\t\tif (_input.contains(\"bytecodeHash\") && !hashes.count(_input[\"bytecodeHash\"].get<std::string>()))\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"settings.metadata.bytecodeHash\\\" must be \\\"ipfs\\\", \\\"bzzr1\\\" or \\\"none\\\"\");\n\t}\n\tstatic std::set<std::string> keys{\"appendCBOR\", \"useLiteralContent\", \"bytecodeHash\"};\n\treturn checkKeys(_input, keys, \"settings.metadata\");\n}\n\nstd::optional<Json> checkOutputSelection(Json const& _outputSelection)\n{\n\tif (!_outputSelection.empty() && !_outputSelection.is_object())\n\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"settings.outputSelection\\\" must be an object\");\n\n\tfor (auto const& [sourceName, sourceVal]: _outputSelection.items())\n\t{\n\t\tif (!sourceVal.is_object())\n\t\t\treturn formatFatalError(\n\t\t\t\tError::Type::JSONError,\n\t\t\t\t\"\\\"settings.outputSelection.\" + sourceName + \"\\\" must be an object\"\n\t\t\t);\n\n\t\tfor (auto const& [contractName, contractVal]: sourceVal.items())\n\t\t{\n\t\t\tif (!contractVal.is_array())\n\t\t\t\treturn formatFatalError(\n\t\t\t\t\tError::Type::JSONError,\n\t\t\t\t\t\"\\\"settings.outputSelection.\" +\n\t\t\t\t\tsourceName +\n\t\t\t\t\t\".\" +\n\t\t\t\t\tcontractName +\n\t\t\t\t\t\"\\\" must be a string array\"\n\t\t\t\t);\n\n\t\t\tfor (auto const& output: contractVal)\n\t\t\t\tif (!output.is_string())\n\t\t\t\t\treturn formatFatalError(\n\t\t\t\t\t\tError::Type::JSONError,\n\t\t\t\t\t\t\"\\\"settings.outputSelection.\" +\n\t\t\t\t\t\tsourceName +\n\t\t\t\t\t\t\".\" +\n\t\t\t\t\t\tcontractName +\n\t\t\t\t\t\t\"\\\" must be a string array\"\n\t\t\t\t\t);\n\t\t}\n\t}\n\n\treturn std::nullopt;\n}\n\n/// Validates the optimizer settings and returns them in a parsed object.\n/// On error returns the json-formatted error message.\nstd::variant<OptimiserSettings, Json> parseOptimizerSettings(std::string_view const _language, Json const& _jsonInput)\n{\n\tif (auto result = checkOptimizerKeys(_jsonInput))\n\t\treturn *result;\n\n\tOptimiserSettings settings = _language == \"EVMAssembly\" ? OptimiserSettings::none() : OptimiserSettings::minimal();\n\n\tif (_jsonInput.contains(\"enabled\"))\n\t{\n\t\tif (!_jsonInput[\"enabled\"].is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"The \\\"enabled\\\" setting must be a Boolean.\");\n\n\t\tif (_jsonInput[\"enabled\"].get<bool>())\n\t\t\tsettings = OptimiserSettings::standard();\n\t}\n\n\tif (_jsonInput.contains(\"runs\"))\n\t{\n\t\tif (!_jsonInput[\"runs\"].is_number_unsigned())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"The \\\"runs\\\" setting must be an unsigned number.\");\n\t\tsettings.expectedExecutionsPerDeployment = _jsonInput[\"runs\"].get<size_t>();\n\t}\n\n\tif (_jsonInput.contains(\"details\"))\n\t{\n\t\tJson const& details = _jsonInput[\"details\"];\n\t\tif (auto result = checkOptimizerDetailsKeys(details))\n\t\t\treturn *result;\n\n\t\tif (auto error = checkOptimizerDetail(details, \"peephole\", settings.runPeephole))\n\t\t\treturn *error;\n\t\tif (auto error = checkOptimizerDetail(details, \"inliner\", settings.runInliner))\n\t\t\treturn *error;\n\t\tif (auto error = checkOptimizerDetail(details, \"jumpdestRemover\", settings.runJumpdestRemover))\n\t\t\treturn *error;\n\t\tif (auto error = checkOptimizerDetail(details, \"orderLiterals\", settings.runOrderLiterals))\n\t\t\treturn *error;\n\t\tif (auto error = checkOptimizerDetail(details, \"deduplicate\", settings.runDeduplicate))\n\t\t\treturn *error;\n\t\tif (auto error = checkOptimizerDetail(details, \"cse\", settings.runCSE))\n\t\t\treturn *error;\n\t\tif (auto error = checkOptimizerDetail(details, \"constantOptimizer\", settings.runConstantOptimiser))\n\t\t\treturn *error;\n\t\tif (auto error = checkOptimizerDetail(details, \"yul\", settings.runYulOptimiser))\n\t\t\treturn *error;\n\t\tif (auto error = checkOptimizerDetail(details, \"simpleCounterForLoopUncheckedIncrement\", settings.simpleCounterForLoopUncheckedIncrement))\n\t\t\treturn *error;\n\t\tsettings.optimizeStackAllocation = settings.runYulOptimiser;\n\t\tif (details.contains(\"yulDetails\"))\n\t\t{\n\t\t\tif (!settings.runYulOptimiser)\n\t\t\t{\n\t\t\t\tif (checkKeys(details[\"yulDetails\"], {\"optimizerSteps\"}, \"settings.optimizer.details.yulDetails\"))\n\t\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Only optimizerSteps can be set in yulDetails when Yul optimizer is disabled.\");\n\t\t\t\tif (auto error = checkOptimizerDetailSteps(details[\"yulDetails\"], \"optimizerSteps\", settings.yulOptimiserSteps, settings.yulOptimiserCleanupSteps, settings.runYulOptimiser))\n\t\t\t\t\treturn *error;\n\t\t\t\treturn {std::move(settings)};\n\t\t\t}\n\n\t\t\tif (auto result = checkKeys(details[\"yulDetails\"], {\"stackAllocation\", \"optimizerSteps\"}, \"settings.optimizer.details.yulDetails\"))\n\t\t\t\treturn *result;\n\t\t\tif (auto error = checkOptimizerDetail(details[\"yulDetails\"], \"stackAllocation\", settings.optimizeStackAllocation))\n\t\t\t\treturn *error;\n\t\t\tif (auto error = checkOptimizerDetailSteps(details[\"yulDetails\"], \"optimizerSteps\", settings.yulOptimiserSteps, settings.yulOptimiserCleanupSteps, settings.runYulOptimiser))\n\t\t\t\treturn *error;\n\t\t}\n\t}\n\treturn {std::move(settings)};\n}\n\n}\n\nstd::variant<StandardCompiler::InputsAndSettings, Json> StandardCompiler::parseInput(Json const& _input)\n{\n\tInputsAndSettings ret;\n\n\tif (!_input.is_object())\n\t\treturn formatFatalError(Error::Type::JSONError, \"Input is not a JSON object.\");\n\n\tif (auto result = checkRootKeys(_input))\n\t\treturn *result;\n\n\tret.language = _input.value<std::string>(\"language\", \"\");\n\n\tJson const& sources = _input.value<Json>(\"sources\", Json());\n\n\tif (!sources.is_object() && !sources.is_null())\n\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"sources\\\" is not a JSON object.\");\n\n\tif (sources.empty())\n\t\treturn formatFatalError(Error::Type::JSONError, \"No input sources specified.\");\n\n\tret.errors = Json::array();\n\tret.sources = Json::object();\n\n\tif (ret.language == \"Solidity\" || ret.language == \"Yul\")\n\t{\n\t\tfor (auto const& [sourceName, sourceValue]: sources.items())\n\t\t{\n\t\t\tstd::string hash;\n\n\t\t\tif (auto result = checkSourceKeys(sourceValue, sourceName))\n\t\t\t\treturn *result;\n\n\t\t\tif (sourceValue.contains(\"keccak256\") && sourceValue[\"keccak256\"].is_string())\n\t\t\t\thash = sourceValue[\"keccak256\"].get<std::string>();\n\n\t\t\tif (sourceValue.contains(\"content\") && sourceValue[\"content\"].is_string())\n\t\t\t{\n\t\t\t\tstd::string content = sourceValue[\"content\"].get<std::string>();\n\t\t\t\tif (!hash.empty() && !hashMatchesContent(hash, content))\n\t\t\t\t\tret.errors.emplace_back(formatError(\n\t\t\t\t\t\tError::Type::IOError,\n\t\t\t\t\t\t\"general\",\n\t\t\t\t\t\t\"Mismatch between content and supplied hash for \\\"\" + sourceName + \"\\\"\"\n\t\t\t\t\t));\n\t\t\t\telse\n\t\t\t\t\tret.sources[sourceName] = content;\n\t\t\t}\n\t\t\telse if (sourceValue[\"urls\"].is_array())\n\t\t\t{\n\t\t\t\tif (!m_readFile)\n\t\t\t\t\treturn formatFatalError(\n\t\t\t\t\t\tError::Type::JSONError, \"No import callback supplied, but URL is requested.\"\n\t\t\t\t\t);\n\n\t\t\t\tstd::vector<std::string> failures;\n\t\t\t\tbool found = false;\n\n\t\t\t\tfor (auto const& url: sourceValue[\"urls\"])\n\t\t\t\t{\n\t\t\t\t\tif (!url.is_string())\n\t\t\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"URL must be a string.\");\n\t\t\t\t\tReadCallback::Result result = m_readFile(ReadCallback::kindString(ReadCallback::Kind::ReadFile), url.get<std::string>());\n\t\t\t\t\tif (result.success)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!hash.empty() && !hashMatchesContent(hash, result.responseOrErrorMessage))\n\t\t\t\t\t\t\tret.errors.emplace_back(formatError(\n\t\t\t\t\t\t\t\tError::Type::IOError,\n\t\t\t\t\t\t\t\t\"general\",\n\t\t\t\t\t\t\t\t\"Mismatch between content and supplied hash for \\\"\" + sourceName + \"\\\" at \\\"\" + url.get<std::string>() + \"\\\"\"\n\t\t\t\t\t\t\t));\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tret.sources[sourceName] = result.responseOrErrorMessage;\n\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tfailures.push_back(\n\t\t\t\t\t\t\t\"Cannot import url (\\\"\" + url.get<std::string>() + \"\\\"): \" + result.responseOrErrorMessage\n\t\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tfor (auto const& failure: failures)\n\t\t\t\t{\n\t\t\t\t\t/// If the import succeeded, let mark all the others as warnings, otherwise all of them are errors.\n\t\t\t\t\tret.errors.emplace_back(formatError(\n\t\t\t\t\t\tfound ? Error::Type::Warning : Error::Type::IOError,\n\t\t\t\t\t\t\"general\",\n\t\t\t\t\t\tfailure\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid input source specified.\");\n\t\t}\n\t}\n\telse if (ret.language == \"SolidityAST\")\n\t{\n\t\tfor (auto const& [sourceName, sourceValue]: sources.items())\n\t\t\tret.sources[sourceName] = util::jsonCompactPrint(sourceValue);\n\t}\n\telse if (ret.language == \"EVMAssembly\")\n\t{\n\t\tfor (auto const& [sourceName, sourceValue]: sources.items())\n\t\t{\n\t\t\tsolAssert(sources.contains(sourceName));\n\t\t\tif (\n\t\t\t\t!sourceValue.contains(\"assemblyJson\") ||\n\t\t\t\t!sourceValue[\"assemblyJson\"].is_object() ||\n\t\t\t\tsourceValue.size() != 1\n\t\t\t)\n\t\t\t\treturn formatFatalError(\n\t\t\t\t\tError::Type::JSONError,\n\t\t\t\t\t\"Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.\" + sourceName\n\t\t\t\t);\n\n\t\t\tret.jsonSources[sourceName] = sourceValue[\"assemblyJson\"];\n\t\t}\n\t\tif (ret.jsonSources.size() != 1)\n\t\t\treturn formatFatalError(\n\t\t\t\tError::Type::JSONError,\n\t\t\t\t\"EVMAssembly import only supports exactly one input file.\"\n\t\t\t);\n\t}\n\tJson const& auxInputs = _input.value(\"auxiliaryInput\", Json::object());\n\n\tif (auto result = checkAuxiliaryInputKeys(auxInputs))\n\t\treturn *result;\n\n\tif (!auxInputs.empty())\n\t{\n\t\tJson const& smtlib2Responses = auxInputs.value(\"smtlib2responses\", Json::object());\n\t\tif (!smtlib2Responses.empty())\n\t\t{\n\t\t\tif (!smtlib2Responses.is_object())\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"auxiliaryInput.smtlib2responses\\\" must be an object.\");\n\n\t\t\tfor (auto const& [hashString, response]: smtlib2Responses.items())\n\t\t\t{\n\t\t\t\tutil::h256 hash;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\thash = util::h256(hashString);\n\t\t\t\t}\n\t\t\t\tcatch (util::BadHexCharacter const&)\n\t\t\t\t{\n\t\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid hex encoding of SMTLib2 auxiliary input.\");\n\t\t\t\t}\n\n\t\t\t\tif (!response.is_string())\n\t\t\t\t\treturn formatFatalError(\n\t\t\t\t\t\tError::Type::JSONError,\n\t\t\t\t\t\t\"\\\"smtlib2Responses.\" + hashString + \"\\\" must be a string.\"\n\t\t\t\t\t);\n\n\t\t\t\tret.smtLib2Responses[hash] = response.get<std::string>();\n\t\t\t}\n\t\t}\n\t}\n\n\tJson const& settings = _input.value(\"settings\", Json::object());\n\n\tif (auto result = checkSettingsKeys(settings))\n\t\treturn *result;\n\n\tif (settings.contains(\"experimental\"))\n\t{\n\t\tif (!settings[\"experimental\"].is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"'settings.experimental' must be a Boolean.\");\n\t\tret.experimental = settings[\"experimental\"].get<bool>();\n\t}\n\n\tif (settings.contains(\"stopAfter\"))\n\t{\n\t\tif (!settings[\"stopAfter\"].is_string())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"settings.stopAfter\\\" must be a string.\");\n\n\t\tif (settings[\"stopAfter\"].get<std::string>() != \"parsing\")\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid value for \\\"settings.stopAfter\\\". Only valid value is \\\"parsing\\\".\");\n\n\t\tret.stopAfter = CompilerStack::State::Parsed;\n\t}\n\n\tif (settings.contains(\"viaIR\"))\n\t{\n\t\tif (!settings[\"viaIR\"].is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"settings.viaIR\\\" must be a Boolean.\");\n\t\tret.viaIR = settings[\"viaIR\"].get<bool>();\n\t}\n\n\tif (settings.contains(\"viaSSACFG\"))\n\t{\n\t\tif (!settings[\"viaSSACFG\"].is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"settings.viaSSACFG\\\" must be a Boolean.\");\n\t\tret.viaSSACFG = settings[\"viaSSACFG\"].get<bool>();\n\t\tif (ret.viaSSACFG)\n\t\t{\n\t\t\tif (settings.contains(\"viaIR\") && !ret.viaIR)\n\t\t\t\treturn formatFatalError(\n\t\t\t\t\tError::Type::JSONError,\n\t\t\t\t\t\"\\\"settings.viaSSACFG\\\" requires compilation via IR.\"\n\t\t\t\t);\n\t\t\tret.viaIR = true;\n\t\t}\n\t}\n\n\tif (settings.contains(\"evmVersion\"))\n\t{\n\t\tif (!settings[\"evmVersion\"].is_string())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"evmVersion must be a string.\");\n\t\tstd::optional<langutil::EVMVersion> version = langutil::EVMVersion::fromString(settings[\"evmVersion\"].get<std::string>());\n\t\tif (!version)\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid EVM version requested.\");\n\t\tif (version < EVMVersion::constantinople())\n\t\t\tret.errors.emplace_back(formatError(\n\t\t\t\tError::Type::Warning,\n\t\t\t\t\"general\",\n\t\t\t\t\"Support for EVM versions older than constantinople is deprecated and will be removed in the future.\"\n\t\t\t));\n\t\tret.evmVersion = *version;\n\t}\n\n\tif (settings.contains(\"eofVersion\"))\n\t{\n\t\tif (!settings[\"eofVersion\"].is_number_unsigned())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"eofVersion must be an unsigned integer.\");\n\t\tauto eofVersion = settings[\"eofVersion\"].get<uint8_t>();\n\t\tif (eofVersion != 1)\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid EOF version requested.\");\n\t\tret.eofVersion = 1;\n\t}\n\n\tif (ret.eofVersion.has_value() && !ret.evmVersion.supportsEOF())\n\t\treturn formatFatalError(Error::Type::JSONError, \"EOF is not supported by EVM versions earlier than \" + EVMVersion::firstWithEOF().name() + \".\");\n\n\tif (settings.contains(\"debug\"))\n\t{\n\t\tif (auto result = checkKeys(settings[\"debug\"], {\"revertStrings\", \"debugInfo\"}, \"settings.debug\"))\n\t\t\treturn *result;\n\n\t\tif (settings[\"debug\"].contains(\"revertStrings\"))\n\t\t{\n\t\t\tif (!settings[\"debug\"][\"revertStrings\"].is_string())\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.debug.revertStrings must be a string.\");\n\t\t\tstd::optional<RevertStrings> revertStrings = revertStringsFromString(settings[\"debug\"][\"revertStrings\"].get<std::string>());\n\t\t\tif (!revertStrings)\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid value for settings.debug.revertStrings.\");\n\t\t\tif (*revertStrings == RevertStrings::VerboseDebug)\n\t\t\t\treturn formatFatalError(\n\t\t\t\t\tError::Type::UnimplementedFeatureError,\n\t\t\t\t\t\"Only \\\"default\\\", \\\"strip\\\" and \\\"debug\\\" are implemented for settings.debug.revertStrings for now.\"\n\t\t\t\t);\n\t\t\tret.revertStrings = *revertStrings;\n\t\t}\n\n\t\tif (settings[\"debug\"].contains(\"debugInfo\"))\n\t\t{\n\t\t\tif (!settings[\"debug\"][\"debugInfo\"].is_array())\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.debug.debugInfo must be an array.\");\n\n\t\t\tstd::vector<std::string> components;\n\t\t\tfor (Json const& arrayValue: settings[\"debug\"][\"debugInfo\"])\n\t\t\t\tcomponents.push_back(arrayValue.get<std::string>());\n\n\t\t\tstd::optional<DebugInfoSelection> debugInfoSelection = DebugInfoSelection::fromComponents(\n\t\t\t\tcomponents,\n\t\t\t\ttrue /* _acceptWildcards */\n\t\t\t);\n\t\t\tif (!debugInfoSelection.has_value())\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid value in settings.debug.debugInfo.\");\n\n\t\t\tif (debugInfoSelection->snippet && !debugInfoSelection->location)\n\t\t\t\treturn formatFatalError(\n\t\t\t\t\tError::Type::JSONError,\n\t\t\t\t\t\"To use 'snippet' with settings.debug.debugInfo you must select also 'location'.\"\n\t\t\t\t);\n\n\t\t\tret.debugInfoSelection = debugInfoSelection.value();\n\t\t}\n\t}\n\n\tif (settings.contains(\"remappings\") && !settings[\"remappings\"].is_array())\n\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"settings.remappings\\\" must be an array of strings.\");\n\n\tfor (auto const& remapping: settings.value(\"remappings\", Json::object()))\n\t{\n\t\tif (!remapping.is_string())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"settings.remappings\\\" must be an array of strings\");\n\t\tif (auto r = ImportRemapper::parseRemapping(remapping.get<std::string>()))\n\t\t\tret.remappings.emplace_back(std::move(*r));\n\t\telse\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid remapping: \\\"\" + remapping.get<std::string>() + \"\\\"\");\n\t}\n\n\tif (settings.contains(\"optimizer\"))\n\t{\n\t\tauto optimiserSettings = parseOptimizerSettings(ret.language, settings[\"optimizer\"]);\n\t\tif (std::holds_alternative<Json>(optimiserSettings))\n\t\t\treturn std::get<Json>(std::move(optimiserSettings)); // was an error\n\t\telse\n\t\t\tret.optimiserSettings = std::get<OptimiserSettings>(std::move(optimiserSettings));\n\t}\n\telse if (ret.language == \"EVMAssembly\")\n\t\tret.optimiserSettings = OptimiserSettings::none();\n\telse\n\t\tret.optimiserSettings = OptimiserSettings::minimal();\n\n\tJson const& jsonLibraries = settings.value(\"libraries\", Json::object());\n\tif (!jsonLibraries.is_object())\n\t\treturn formatFatalError(Error::Type::JSONError, \"\\\"libraries\\\" is not a JSON object.\");\n\tfor (auto const& [sourceName, jsonSourceName]: jsonLibraries.items())\n\t{\n\t\tif (!jsonSourceName.is_object())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"Library entry is not a JSON object.\");\n\t\tfor (auto const& [library, libraryValue]: jsonSourceName.items())\n\t\t{\n\t\t\tif (!libraryValue.is_string())\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Library address must be a string.\");\n\t\t\tstd::string address = libraryValue.get<std::string>();\n\n\t\t\tif (!boost::starts_with(address, \"0x\"))\n\t\t\t\treturn formatFatalError(\n\t\t\t\t\tError::Type::JSONError,\n\t\t\t\t\t\"Library address is not prefixed with \\\"0x\\\".\"\n\t\t\t\t);\n\n\t\t\tif (address.length() != 42)\n\t\t\t\treturn formatFatalError(\n\t\t\t\t\tError::Type::JSONError,\n\t\t\t\t\t\"Library address is of invalid length.\"\n\t\t\t\t);\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tret.libraries[sourceName + \":\" + library] = util::h160(address);\n\t\t\t}\n\t\t\tcatch (util::BadHexCharacter const&)\n\t\t\t{\n\t\t\t\treturn formatFatalError(\n\t\t\t\t\tError::Type::JSONError,\n\t\t\t\t\t\"Invalid library address (\\\"\" + address + \"\\\") supplied.\"\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tJson const& metadataSettings = settings.value(\"metadata\", Json::object());\n\n\tif (auto result = checkMetadataKeys(metadataSettings))\n\t\treturn *result;\n\n\tsolAssert(CompilerStack::defaultMetadataFormat() != CompilerStack::MetadataFormat::NoMetadata, \"\");\n\tret.metadataFormat =\n\t\tmetadataSettings.value(\"appendCBOR\", Json(true)) ?\n\t\tCompilerStack::defaultMetadataFormat() :\n\t\tCompilerStack::MetadataFormat::NoMetadata;\n\n\tret.metadataLiteralSources =\n\t\tmetadataSettings.contains(\"useLiteralContent\") &&\n\t\tmetadataSettings[\"useLiteralContent\"].is_boolean() &&\n\t\tmetadataSettings[\"useLiteralContent\"].get<bool>();\n\tif (metadataSettings.contains(\"bytecodeHash\"))\n\t{\n\t\tauto metadataHash = metadataSettings[\"bytecodeHash\"].get<std::string>();\n\t\tret.metadataHash =\n\t\t\tmetadataHash == \"ipfs\" ?\n\t\t\tCompilerStack::MetadataHash::IPFS :\n\t\t\t\tmetadataHash == \"bzzr1\" ?\n\t\t\t\tCompilerStack::MetadataHash::Bzzr1 :\n\t\t\t\tCompilerStack::MetadataHash::None;\n\t\tif (ret.metadataFormat == CompilerStack::MetadataFormat::NoMetadata && ret.metadataHash != CompilerStack::MetadataHash::None)\n\t\t\treturn formatFatalError(\n\t\t\t\tError::Type::JSONError,\n\t\t\t\t\"When the parameter \\\"appendCBOR\\\" is set to false, the parameter \\\"bytecodeHash\\\" cannot be set to \\\"\" +\n\t\t\t\tmetadataHash +\n\t\t\t\t\"\\\". The parameter \\\"bytecodeHash\\\" should either be skipped, or set to \\\"none\\\".\"\n\t\t\t);\n\t}\n\n\tJson const& outputSelection = settings.value(\"outputSelection\", Json::object());\n\n\tif (auto jsonError = checkOutputSelection(outputSelection))\n\t\treturn *jsonError;\n\n\tret.outputSelection = outputSelection;\n\n\tif (ret.stopAfter != CompilerStack::State::CompilationSuccessful && isBinaryRequested(ret.outputSelection))\n\t\treturn formatFatalError(\n\t\t\tError::Type::JSONError,\n\t\t\t\"Requested output selection conflicts with \\\"settings.stopAfter\\\".\"\n\t\t);\n\n\tJson const& modelCheckerSettings = settings.value(\"modelChecker\", Json::object());\n\n\tif (auto result = checkModelCheckerSettingsKeys(modelCheckerSettings))\n\t\treturn *result;\n\n\tif (modelCheckerSettings.contains(\"contracts\"))\n\t{\n\t\tauto const& sources = modelCheckerSettings[\"contracts\"];\n\t\tif (!sources.is_object() && !sources.is_null())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.contracts is not a JSON object.\");\n\n\t\tstd::map<std::string, std::set<std::string>> sourceContracts;\n\t\tfor (auto const& [source, contracts]: sources.items())\n\t\t{\n\t\t\tif (source.empty())\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Source name cannot be empty.\");\n\n\t\t\tif (!contracts.is_array())\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Source contracts must be an array.\");\n\n\t\t\tfor (auto const& contract: contracts)\n\t\t\t{\n\t\t\t\tif (!contract.is_string())\n\t\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Every contract in settings.modelChecker.contracts must be a string.\");\n\t\t\t\tif (contract.get<std::string>().empty())\n\t\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Contract name cannot be empty.\");\n\t\t\t\tsourceContracts[source].insert(contract.get<std::string>());\n\t\t\t}\n\n\t\t\tif (sourceContracts[source].empty())\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Source contracts must be a non-empty array.\");\n\t\t}\n\t\tret.modelCheckerSettings.contracts = {std::move(sourceContracts)};\n\t}\n\n\tif (modelCheckerSettings.contains(\"divModNoSlacks\"))\n\t{\n\t\tauto const& divModNoSlacks = modelCheckerSettings[\"divModNoSlacks\"];\n\t\tif (!divModNoSlacks.is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.divModNoSlacks must be a Boolean.\");\n\t\tret.modelCheckerSettings.divModNoSlacks = divModNoSlacks.get<bool>();\n\t}\n\n\tif (modelCheckerSettings.contains(\"engine\"))\n\t{\n\t\tif (!modelCheckerSettings[\"engine\"].is_string())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.engine must be a string.\");\n\t\tstd::optional<ModelCheckerEngine> engine = ModelCheckerEngine::fromString(modelCheckerSettings[\"engine\"].get<std::string>());\n\t\tif (!engine)\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid model checker engine requested.\");\n\t\tret.modelCheckerSettings.engine = *engine;\n\t}\n\n\tif (modelCheckerSettings.contains(\"bmcLoopIterations\"))\n\t{\n\t\tif (!ret.modelCheckerSettings.engine.bmc)\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.bmcLoopIterations requires the BMC engine to be enabled.\");\n\t\tif (modelCheckerSettings[\"bmcLoopIterations\"].is_number_unsigned())\n\t\t\tret.modelCheckerSettings.bmcLoopIterations = modelCheckerSettings[\"bmcLoopIterations\"].get<unsigned>();\n\t\telse\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.bmcLoopIterations must be an unsigned integer.\");\n\t}\n\n\tif (modelCheckerSettings.contains(\"extCalls\"))\n\t{\n\t\tif (!modelCheckerSettings[\"extCalls\"].is_string())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.extCalls must be a string.\");\n\t\tstd::optional<ModelCheckerExtCalls> extCalls = ModelCheckerExtCalls::fromString(modelCheckerSettings[\"extCalls\"].get<std::string>());\n\t\tif (!extCalls)\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid model checker extCalls requested.\");\n\t\tret.modelCheckerSettings.externalCalls = *extCalls;\n\t}\n\n\tif (modelCheckerSettings.contains(\"invariants\"))\n\t{\n\t\tauto const& invariantsArray = modelCheckerSettings[\"invariants\"];\n\t\tif (!invariantsArray.is_array())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.invariants must be an array.\");\n\n\t\tModelCheckerInvariants invariants;\n\t\tfor (auto const& i: invariantsArray)\n\t\t{\n\t\t\tif (!i.is_string())\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Every invariant type in settings.modelChecker.invariants must be a string.\");\n\t\t\tif (!invariants.setFromString(i.get<std::string>()))\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid model checker invariants requested.\");\n\t\t}\n\n\t\tif (invariants.invariants.empty())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.invariants must be a non-empty array.\");\n\n\t\tret.modelCheckerSettings.invariants = invariants;\n\t}\n\n\tif (modelCheckerSettings.contains(\"showProvedSafe\"))\n\t{\n\t\tauto const& showProvedSafe = modelCheckerSettings[\"showProvedSafe\"];\n\t\tif (!showProvedSafe.is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.showProvedSafe must be a Boolean value.\");\n\t\tret.modelCheckerSettings.showProvedSafe = showProvedSafe.get<bool>();\n\t}\n\n\tif (modelCheckerSettings.contains(\"showUnproved\"))\n\t{\n\t\tauto const& showUnproved = modelCheckerSettings[\"showUnproved\"];\n\t\tif (!showUnproved.is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.showUnproved must be a Boolean value.\");\n\t\tret.modelCheckerSettings.showUnproved = showUnproved.get<bool>();\n\t}\n\n\tif (modelCheckerSettings.contains(\"showUnsupported\"))\n\t{\n\t\tauto const& showUnsupported = modelCheckerSettings[\"showUnsupported\"];\n\t\tif (!showUnsupported.is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.showUnsupported must be a Boolean value.\");\n\t\tret.modelCheckerSettings.showUnsupported = showUnsupported.get<bool>();\n\t}\n\n\tif (modelCheckerSettings.contains(\"solvers\"))\n\t{\n\t\tauto const& solversArray = modelCheckerSettings[\"solvers\"];\n\t\tif (!solversArray.is_array())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.solvers must be an array.\");\n\n\t\tsmtutil::SMTSolverChoice solvers;\n\t\tfor (auto const& s: solversArray)\n\t\t{\n\t\t\tif (!s.is_string())\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Every target in settings.modelChecker.solvers must be a string.\");\n\t\t\tif (!solvers.setSolver(s.get<std::string>()))\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid model checker solvers requested.\");\n\t\t}\n\n\t\tret.modelCheckerSettings.solvers = solvers;\n\t}\n\n\tif (modelCheckerSettings.contains(\"printQuery\"))\n\t{\n\t\tauto const& printQuery = modelCheckerSettings[\"printQuery\"];\n\t\tif (!printQuery.is_boolean())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.printQuery must be a Boolean value.\");\n\n\t\tret.modelCheckerSettings.printQuery = printQuery.get<bool>();\n\t}\n\n\tif (modelCheckerSettings.contains(\"targets\"))\n\t{\n\t\tauto const& targetsArray = modelCheckerSettings[\"targets\"];\n\t\tif (!targetsArray.is_array())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.targets must be an array.\");\n\n\t\tModelCheckerTargets targets;\n\t\tfor (auto const& t: targetsArray)\n\t\t{\n\t\t\tif (!t.is_string())\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Every target in settings.modelChecker.targets must be a string.\");\n\t\t\tif (!targets.setFromString(t.get<std::string>()))\n\t\t\t\treturn formatFatalError(Error::Type::JSONError, \"Invalid model checker targets requested.\");\n\t\t}\n\n\t\tif (targets.targets.empty())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.targets must be a non-empty array.\");\n\n\t\tret.modelCheckerSettings.targets = targets;\n\t}\n\n\tif (modelCheckerSettings.contains(\"timeout\"))\n\t{\n\t\tif (!modelCheckerSettings[\"timeout\"].is_number_unsigned())\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"settings.modelChecker.timeout must be an unsigned integer.\");\n\t\tret.modelCheckerSettings.timeout = modelCheckerSettings[\"timeout\"].get<Json::number_unsigned_t>();\n\t}\n\n\tif ((ret.debugInfoSelection.has_value() && ret.debugInfoSelection->ethdebug) || isEthdebugRequested(ret.outputSelection))\n\t{\n\t\tif (ret.language != \"Solidity\" && ret.language != \"Yul\")\n\t\t\treturn formatFatalError(Error::Type::FatalError, \"'settings.debug.debugInfo' 'ethdebug' is only supported for languages 'Solidity' and 'Yul'.\");\n\t}\n\n\tif (isEthdebugRequested(ret.outputSelection))\n\t{\n\t\tif (ret.language == \"Solidity\" && !ret.viaIR)\n\t\t\treturn formatFatalError(Error::Type::FatalError, \"'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.\");\n\n\t\tif (!ret.debugInfoSelection.has_value())\n\t\t{\n\t\t\tret.debugInfoSelection = DebugInfoSelection::Default();\n\t\t\tret.debugInfoSelection->enable(\"ethdebug\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (!ret.debugInfoSelection->ethdebug && ret.language == \"Solidity\")\n\t\t\t\treturn formatFatalError(Error::Type::FatalError, \"'ethdebug' needs to be enabled in 'settings.debug.debugInfo', if 'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' was selected as output.\");\n\t\t}\n\t}\n\n\tif (ret.debugInfoSelection.has_value() && ret.debugInfoSelection->ethdebug)\n\t{\n\t\tif (!ret.experimental)\n\t\t\treturn formatFatalError(Error::Type::FatalError, \"Ethdebug annotations are experimental and can only be included in 'settings.debug.debugInfo' by enabling the 'settings.experimental' option.\");\n\t\tif (!pipelineConfig(ret.outputSelection)[\"\"][\"\"].irCodegen && !isEthdebugRequested(ret.outputSelection))\n\t\t\treturn formatFatalError(Error::Type::FatalError, \"'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.\");\n\t}\n\n\tif (isEthdebugRequested(ret.outputSelection))\n\t{\n\t\tif (ret.optimiserSettings.runYulOptimiser)\n\t\t\tsolUnimplemented(\"Optimization is not yet supported with ethdebug.\");\n\t\tif (ret.viaSSACFG)\n\t\t\tsolUnimplemented(\"SSA CFG codegen does not yet support ethdebug.\");\n\t}\n\n\tif (!ret.experimental)\n\t{\n\t\tif (ret.language == \"SolidityAST\" || ret.language == \"EVMAssembly\")\n\t\t\treturn formatFatalError(Error::Type::FatalError, \"'SolidityAST' and 'EVMAssembly' inputs are experimental and can only be used with the 'settings.experimental' option enabled.\");\n\n\t\tif (ret.evmVersion.isExperimental())\n\t\t\t// TODO: Cover with test when the Amsterdam version is introduced\n\t\t\treturn formatFatalError(Error::Type::FatalError, fmt::format(\"EVM version '{}' is experimental and can only be used with the 'settings.experimental' option enabled.\", ret.evmVersion.name()));\n\n\t\tif (isExperimentalArtifactRequested(ret.outputSelection))\n\t\t\treturn formatFatalError(Error::Type::FatalError, \"'irAst', 'irOptimizedAst', 'yulCFGJson', and 'ethdebug' outputs are experimental and can only be used with the 'settings.experimental' option enabled.\");\n\n\t\tif (ret.eofVersion.has_value())\n\t\t\treturn formatFatalError(Error::Type::FatalError, \"'eofVersion' setting is experimental and can only be used with the 'settings.experimental' option enabled.\");\n\n\t\tif (ret.viaSSACFG)\n\t\t\treturn formatFatalError(Error::Type::FatalError, \"'viaSSACFG' setting is experimental and can only be used with the 'settings.experimental' option enabled.\");\n\t}\n\n\treturn {std::move(ret)};\n}\n\nstd::map<std::string, Json> StandardCompiler::parseAstFromInput(StringMap const& _sources)\n{\n\tstd::map<std::string, Json> sourceJsons;\n\tfor (auto const& [sourceName, sourceCode]: _sources)\n\t{\n\t\tJson ast;\n\t\tastAssert(util::jsonParseStrict(sourceCode, ast), \"Input file could not be parsed to JSON\");\n\t\tstd::string astKey = ast.contains(\"ast\") ? \"ast\" : \"AST\";\n\n\t\tastAssert(ast.contains(astKey), \"astkey is not member\");\n\t\tastAssert(ast[astKey][\"nodeType\"].get<std::string>() == \"SourceUnit\", \"Top-level node should be a 'SourceUnit'\");\n\t\tastAssert(sourceJsons.count(sourceName) == 0, \"All sources must have unique names\");\n\t\tsourceJsons.emplace(sourceName, std::move(ast[astKey]));\n\t}\n\treturn sourceJsons;\n}\n\nJson StandardCompiler::importEVMAssembly(StandardCompiler::InputsAndSettings _inputsAndSettings)\n{\n\tsolAssert(_inputsAndSettings.language == \"EVMAssembly\");\n\tsolAssert(_inputsAndSettings.sources.empty());\n\tsolAssert(_inputsAndSettings.jsonSources.size() == 1);\n\tsolAssert(_inputsAndSettings.experimental);\n\n\tif (!isBinaryRequested(_inputsAndSettings.outputSelection))\n\t\treturn Json::object();\n\n\tevmasm::EVMAssemblyStack stack(\n\t\t_inputsAndSettings.evmVersion,\n\t\t_inputsAndSettings.eofVersion,\n\t\tevmasm::Assembly::OptimiserSettings::translateSettings(\n\t\t\t_inputsAndSettings.optimiserSettings\n\t\t)\n\t);\n\tstd::string const& sourceName = _inputsAndSettings.jsonSources.begin()->first; // result of structured binding can only be used within lambda from C++20 on.\n\tJson const& sourceJson = _inputsAndSettings.jsonSources.begin()->second;\n\ttry\n\t{\n\t\tstack.analyze(sourceName, sourceJson);\n\t\tstack.assemble();\n\t}\n\tcatch (evmasm::AssemblyImportException const& e)\n\t{\n\t\treturn formatFatalError(Error::Type::Exception, \"Assembly import error: \" + std::string(e.what()));\n\t}\n\tcatch (...)\n\t{\n\t\treturn formatError(\n\t\t\tError::Type::Exception,\n\t\t\t\"general\",\n\t\t\t\"Unknown exception during assembly import: \" + boost::current_exception_diagnostic_information()\n\t\t);\n\t}\n\tif (!stack.compilationSuccessful())\n\t\treturn Json::object();\n\n\t// EVM\n\tbool const wildcardMatchesExperimental = false;\n\tJson evmData;\n\tif (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, \"\", \"evm.assembly\", wildcardMatchesExperimental))\n\t\tevmData[\"assembly\"] = stack.assemblyString(sourceName, {});\n\tif (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, \"\", \"evm.legacyAssembly\", wildcardMatchesExperimental))\n\t\tevmData[\"legacyAssembly\"] = stack.assemblyJSON(sourceName);\n\n\tif (isArtifactRequested(\n\t\t_inputsAndSettings.outputSelection,\n\t\tsourceName,\n\t\t\"\",\n\t\tevmObjectComponents(\"bytecode\"),\n\t\twildcardMatchesExperimental\n\t))\n\t{\n\t\tauto const evmCreationArtifactRequested = [&](std::string const& _element) {\n\t\t\treturn isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, \"\", \"evm.bytecode.\" + _element, wildcardMatchesExperimental);\n\t\t};\n\n\t\tJson creationJSON;\n\t\tif (evmCreationArtifactRequested(\"object\"))\n\t\t\tcreationJSON[\"object\"] = stack.object(sourceName).toHex();\n\t\tif (evmCreationArtifactRequested(\"opcodes\"))\n\t\t\tcreationJSON[\"opcodes\"] = evmasm::disassemble(stack.object(sourceName).bytecode, _inputsAndSettings.evmVersion);\n\t\tif (evmCreationArtifactRequested(\"sourceMap\"))\n\t\t\tcreationJSON[\"sourceMap\"] = stack.sourceMapping(sourceName) ? *stack.sourceMapping(sourceName) : \"\";\n\t\tif (evmCreationArtifactRequested(\"functionDebugData\"))\n\t\t\tcreationJSON[\"functionDebugData\"] = formatFunctionDebugData(stack.object(sourceName).functionDebugData);\n\t\tif (evmCreationArtifactRequested(\"linkReferences\"))\n\t\t\tcreationJSON[\"linkReferences\"] = formatLinkReferences(stack.object(sourceName).linkReferences);\n\t\tif (evmCreationArtifactRequested(\"ethdebug\"))\n\t\t\tcreationJSON[\"ethdebug\"] = stack.ethdebug(sourceName);\n\t\tevmData[\"bytecode\"] = creationJSON;\n\t}\n\n\tif (isArtifactRequested(\n\t\t_inputsAndSettings.outputSelection,\n\t\tsourceName,\n\t\t\"\",\n\t\tevmObjectComponents(\"deployedBytecode\"),\n\t\twildcardMatchesExperimental\n\t))\n\t{\n\t\tauto const evmDeployedArtifactRequested = [&](std::string const& _element) {\n\t\t\treturn isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, \"\", \"evm.deployedBytecode.\" + _element, wildcardMatchesExperimental);\n\t\t};\n\n\t\tJson deployedJSON;\n\t\tif (evmDeployedArtifactRequested(\"object\"))\n\t\t\tdeployedJSON[\"object\"] = stack.runtimeObject(sourceName).toHex();\n\t\tif (evmDeployedArtifactRequested(\"opcodes\"))\n\t\t\tdeployedJSON[\"opcodes\"] = evmasm::disassemble(stack.runtimeObject(sourceName).bytecode, _inputsAndSettings.evmVersion);\n\t\tif (evmDeployedArtifactRequested(\"sourceMap\"))\n\t\t\tdeployedJSON[\"sourceMap\"] = stack.runtimeSourceMapping(sourceName) ? *stack.runtimeSourceMapping(sourceName) : \"\";\n\t\tif (evmDeployedArtifactRequested(\"functionDebugData\"))\n\t\t\tdeployedJSON[\"functionDebugData\"] = formatFunctionDebugData(stack.runtimeObject(sourceName).functionDebugData);\n\t\tif (evmDeployedArtifactRequested(\"linkReferences\"))\n\t\t\tdeployedJSON[\"linkReferences\"] = formatLinkReferences(stack.runtimeObject(sourceName).linkReferences);\n\t\tif (evmDeployedArtifactRequested(\"immutableReferences\"))\n\t\t\tdeployedJSON[\"immutableReferences\"] = formatImmutableReferences(stack.runtimeObject(sourceName).immutableReferences);\n\t\tif (evmDeployedArtifactRequested(\"ethdebug\"))\n\t\t\tdeployedJSON[\"ethdebug\"] = stack.ethdebugRuntime(sourceName);\n\t\tevmData[\"deployedBytecode\"] = deployedJSON;\n\t}\n\n\tJson contractData;\n\tif (!evmData.empty())\n\t\tcontractData[\"evm\"] = evmData;\n\n\tJson contractsOutput;\n\tcontractsOutput[sourceName][\"\"] = contractData;\n\tJson output;\n\toutput[\"contracts\"] = contractsOutput;\n\treturn util::removeNullMembers(output);\n}\n\nJson StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inputsAndSettings)\n{\n\tsolAssert(_inputsAndSettings.jsonSources.empty());\n\n\tCompilerStack compilerStack(m_readFile);\n\n\tStringMap sourceList = std::move(_inputsAndSettings.sources);\n\tif (_inputsAndSettings.language == \"Solidity\")\n\t\tcompilerStack.setSources(sourceList);\n\tfor (auto const& smtLib2Response: _inputsAndSettings.smtLib2Responses)\n\t\tcompilerStack.addSMTLib2Response(smtLib2Response.first, smtLib2Response.second);\n\tcompilerStack.setViaIR(_inputsAndSettings.viaIR);\n\tcompilerStack.setViaSSACFG(_inputsAndSettings.viaSSACFG);\n\tcompilerStack.setEVMVersion(_inputsAndSettings.evmVersion);\n\tcompilerStack.setEOFVersion(_inputsAndSettings.eofVersion);\n\tcompilerStack.setRemappings(std::move(_inputsAndSettings.remappings));\n\tcompilerStack.setOptimiserSettings(std::move(_inputsAndSettings.optimiserSettings));\n\tcompilerStack.setRevertStringBehaviour(_inputsAndSettings.revertStrings);\n\tif (_inputsAndSettings.debugInfoSelection.has_value())\n\t\tcompilerStack.selectDebugInfo(_inputsAndSettings.debugInfoSelection.value());\n\tcompilerStack.setLibraries(_inputsAndSettings.libraries);\n\tcompilerStack.useMetadataLiteralSources(_inputsAndSettings.metadataLiteralSources);\n\tcompilerStack.setMetadataFormat(_inputsAndSettings.metadataFormat);\n\tcompilerStack.setMetadataHash(_inputsAndSettings.metadataHash);\n\tcompilerStack.selectContracts(pipelineConfig(_inputsAndSettings.outputSelection));\n\tcompilerStack.setModelCheckerSettings(_inputsAndSettings.modelCheckerSettings);\n\tcompilerStack.setExperimental(_inputsAndSettings.experimental);\n\n\tJson errors = std::move(_inputsAndSettings.errors);\n\n\tbool const binariesRequested = isBinaryRequested(_inputsAndSettings.outputSelection);\n\n\ttry\n\t{\n\t\tif (_inputsAndSettings.language == \"SolidityAST\")\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tcompilerStack.importASTs(parseAstFromInput(sourceList));\n\t\t\t\tif (!compilerStack.analyze())\n\t\t\t\t\terrors.emplace_back(formatError(Error::Type::FatalError, \"general\", \"Analysis of the AST failed.\"));\n\t\t\t\tif (binariesRequested)\n\t\t\t\t\tcompilerStack.compile();\n\t\t\t}\n\t\t\tcatch (util::Exception const& _exc)\n\t\t\t{\n\t\t\t\tsolThrow(util::Exception, \"Failed to import AST: \"s + _exc.what());\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (binariesRequested)\n\t\t\t\tcompilerStack.compile();\n\t\t\telse\n\t\t\t\tcompilerStack.parseAndAnalyze(_inputsAndSettings.stopAfter);\n\n\t\t\tfor (auto const& error: compilerStack.errors())\n\t\t\t\terrors.emplace_back(formatErrorWithException(\n\t\t\t\t\tcompilerStack,\n\t\t\t\t\t*error,\n\t\t\t\t\terror->type(),\n\t\t\t\t\t\"general\",\n\t\t\t\t\t\"\",\n\t\t\t\t\terror->errorId()\n\t\t\t\t));\n\t\t}\n\t}\n\t// NOTE: This includes langutil::StackTooDeepError.\n\tcatch (CompilerError const& _exception)\n\t{\n\t\terrors.emplace_back(formatErrorWithException(\n\t\t\tcompilerStack,\n\t\t\t_exception,\n\t\t\tError::Type::CompilerError,\n\t\t\t\"general\",\n\t\t\t\"Compiler error (\" + _exception.lineInfo() + \")\"\n\t\t));\n\t}\n\tcatch (yul::StackTooDeepError const& _exception)\n\t{\n\t\terrors.emplace_back(formatErrorWithException(\n\t\t\tcompilerStack,\n\t\t\t_exception,\n\t\t\tError::Type::YulException,\n\t\t\t\"general\",\n\t\t\t\"\" // No prefix needed. These messages already say it's a \"stack too deep\" error.\n\t\t));\n\t}\n\tcatch (InternalCompilerError const&)\n\t{\n\t\terrors.emplace_back(formatError(\n\t\t\tError::Type::InternalCompilerError,\n\t\t\t\"general\",\n\t\t\t\"Internal compiler error:\\n\" + boost::current_exception_diagnostic_information()\n\t\t));\n\t}\n\tcatch (UnimplementedFeatureError const& _exception)\n\t{\n\t\t// let StandardCompiler::compile handle this\n\t\tthrow _exception;\n\t}\n\tcatch (YulAssertion const&)\n\t{\n\t\terrors.emplace_back(formatError(\n\t\t\tError::Type::YulException,\n\t\t\t\"general\",\n\t\t\t\"Yul assertion failed:\\n\" + boost::current_exception_diagnostic_information()\n\t\t));\n\t}\n\tcatch (smtutil::SMTLogicError const&)\n\t{\n\t\terrors.emplace_back(formatError(\n\t\t\tError::Type::SMTLogicException,\n\t\t\t\"general\",\n\t\t\t\"SMT logic error:\\n\" + boost::current_exception_diagnostic_information()\n\t\t));\n\t}\n\tcatch (...)\n\t{\n\t\terrors.emplace_back(formatError(\n\t\t\tError::Type::Exception,\n\t\t\t\"general\",\n\t\t\t\"Unknown exception during compilation: \" + boost::current_exception_diagnostic_information()\n\t\t));\n\t}\n\n\tbool parsingSuccess = compilerStack.state() >= CompilerStack::State::Parsed;\n\tbool analysisSuccess = compilerStack.state() >= CompilerStack::State::AnalysisSuccessful;\n\tbool compilationSuccess = compilerStack.state() == CompilerStack::State::CompilationSuccessful;\n\n\t// If analysis fails, the artifacts inside CompilerStack are potentially incomplete and must not be returned.\n\t// Note that not completing analysis due to stopAfter does not count as a failure. It's neither failure nor success.\n\tbool analysisFailed = !analysisSuccess && _inputsAndSettings.stopAfter >= CompilerStack::State::AnalysisSuccessful;\n\tbool compilationFailed = !compilationSuccess && binariesRequested;\n\tif (compilationFailed || analysisFailed || !parsingSuccess)\n\t\tsolAssert(!errors.empty(), \"No error reported, but compilation failed.\");\n\n\tJson output;\n\n\tif (errors.size() > 0)\n\t\toutput[\"errors\"] = std::move(errors);\n\n\tif (!compilerStack.unhandledSMTLib2Queries().empty())\n\t\tfor (std::string const& query: compilerStack.unhandledSMTLib2Queries())\n\t\t\toutput[\"auxiliaryInputRequested\"][\"smtlib2queries\"][\"0x\" + util::keccak256(query).hex()] = query;\n\n\tbool const wildcardMatchesExperimental = false;\n\n\toutput[\"sources\"] = Json::object();\n\tunsigned sourceIndex = 0;\n\t// NOTE: A case that will pass `parsingSuccess && !analysisFailed` but not `analysisSuccess` is\n\t// stopAfter: parsing with no parsing errors.\n\tif (parsingSuccess && !analysisFailed)\n\t\tfor (std::string const& sourceName: compilerStack.sourceNames())\n\t\t{\n\t\t\tJson sourceResult;\n\t\t\tsourceResult[\"id\"] = sourceIndex++;\n\t\t\tif (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, \"\", \"ast\", wildcardMatchesExperimental))\n\t\t\t\tsourceResult[\"ast\"] = ASTJsonExporter(compilerStack.state(), compilerStack.sourceIndices()).toJson(compilerStack.ast(sourceName));\n\t\t\toutput[\"sources\"][sourceName] = sourceResult;\n\t\t}\n\n\tJson contractsOutput;\n\tfor (std::string const& contractName: analysisSuccess ? compilerStack.contractNames() : std::vector<std::string>())\n\t{\n\t\tsize_t colon = contractName.rfind(':');\n\t\tsolAssert(colon != std::string::npos, \"\");\n\t\tstd::string file = contractName.substr(0, colon);\n\t\tstd::string name = contractName.substr(colon + 1);\n\n\t\t// ABI, storage layout, documentation and metadata\n\t\tJson contractData;\n\t\tif (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"abi\", wildcardMatchesExperimental))\n\t\t\tcontractData[\"abi\"] = compilerStack.contractABI(contractName);\n\t\tif (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"storageLayout\", false))\n\t\t\tcontractData[\"storageLayout\"] = compilerStack.storageLayout(contractName);\n\t\tif (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"transientStorageLayout\", false))\n\t\t\tcontractData[\"transientStorageLayout\"] = compilerStack.transientStorageLayout(contractName);\n\t\tif (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"metadata\", wildcardMatchesExperimental))\n\t\t\tcontractData[\"metadata\"] = compilerStack.metadata(contractName);\n\t\tif (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"userdoc\", wildcardMatchesExperimental))\n\t\t\tcontractData[\"userdoc\"] = compilerStack.natspecUser(contractName);\n\t\tif (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"devdoc\", wildcardMatchesExperimental))\n\t\t\tcontractData[\"devdoc\"] = compilerStack.natspecDev(contractName);\n\n\t\t// IR\n\t\tif (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"ir\", wildcardMatchesExperimental))\n\t\t\tcontractData[\"ir\"] = compilerStack.yulIR(contractName).value_or(\"\");\n\t\tif (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"irAst\", wildcardMatchesExperimental))\n\t\t\tcontractData[\"irAst\"] = compilerStack.yulIRAst(contractName).value_or(Json{});\n\t\tif (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"irOptimized\", wildcardMatchesExperimental))\n\t\t\tcontractData[\"irOptimized\"] = compilerStack.yulIROptimized(contractName).value_or(\"\");\n\t\tif (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"irOptimizedAst\", wildcardMatchesExperimental))\n\t\t\tcontractData[\"irOptimizedAst\"] = compilerStack.yulIROptimizedAst(contractName).value_or(Json{});\n\t\tif (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"yulCFGJson\", wildcardMatchesExperimental))\n\t\t\tcontractData[\"yulCFGJson\"] = compilerStack.yulCFGJson(contractName).value_or(Json{});\n\n\t\t// EVM\n\t\tJson evmData;\n\t\tif (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"evm.assembly\", wildcardMatchesExperimental))\n\t\t\tevmData[\"assembly\"] = compilerStack.assemblyString(contractName, sourceList);\n\t\tif (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"evm.legacyAssembly\", wildcardMatchesExperimental))\n\t\t\tevmData[\"legacyAssembly\"] = compilerStack.assemblyJSON(contractName);\n\t\tif (isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"evm.methodIdentifiers\", wildcardMatchesExperimental))\n\t\t\tevmData[\"methodIdentifiers\"] = compilerStack.interfaceSymbols(contractName)[\"methods\"];\n\t\tif (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"evm.gasEstimates\", wildcardMatchesExperimental))\n\t\t\tevmData[\"gasEstimates\"] = compilerStack.gasEstimates(contractName);\n\n\t\tif (compilationSuccess && isArtifactRequested(\n\t\t\t_inputsAndSettings.outputSelection,\n\t\t\tfile,\n\t\t\tname,\n\t\t\tevmObjectComponents(\"bytecode\"),\n\t\t\twildcardMatchesExperimental\n\t\t))\n\t\t{\n\t\t\tauto const evmCreationArtifactRequested = [&](std::string const& _element) {\n\t\t\t\treturn isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"evm.bytecode.\" + _element, wildcardMatchesExperimental);\n\t\t\t};\n\n\t\t\tJson creationJSON;\n\t\t\tif (evmCreationArtifactRequested(\"object\"))\n\t\t\t\tcreationJSON[\"object\"] = compilerStack.object(contractName).toHex();\n\t\t\tif (evmCreationArtifactRequested(\"opcodes\"))\n\t\t\t\tcreationJSON[\"opcodes\"] = evmasm::disassemble(compilerStack.object(contractName).bytecode, _inputsAndSettings.evmVersion);\n\t\t\tif (evmCreationArtifactRequested(\"sourceMap\"))\n\t\t\t\tcreationJSON[\"sourceMap\"] = compilerStack.sourceMapping(contractName) ? *compilerStack.sourceMapping(contractName) : \"\";\n\t\t\tif (evmCreationArtifactRequested(\"functionDebugData\"))\n\t\t\t\tcreationJSON[\"functionDebugData\"] = formatFunctionDebugData(compilerStack.object(contractName).functionDebugData);\n\t\t\tif (evmCreationArtifactRequested(\"linkReferences\"))\n\t\t\t\tcreationJSON[\"linkReferences\"] = formatLinkReferences(compilerStack.object(contractName).linkReferences);\n\t\t\tif (evmCreationArtifactRequested(\"generatedSources\"))\n\t\t\t\tcreationJSON[\"generatedSources\"] = compilerStack.generatedSources(contractName, /* _runtime */ false);\n\t\t\tif (evmCreationArtifactRequested(\"ethdebug\"))\n\t\t\t\tcreationJSON[\"ethdebug\"] = compilerStack.ethdebug(contractName);\n\t\t\tevmData[\"bytecode\"] = creationJSON;\n\t\t}\n\n\t\tif (compilationSuccess && isArtifactRequested(\n\t\t\t_inputsAndSettings.outputSelection,\n\t\t\tfile,\n\t\t\tname,\n\t\t\tevmObjectComponents(\"deployedBytecode\"),\n\t\t\twildcardMatchesExperimental\n\t\t))\n\t\t{\n\t\t\tauto const evmDeployedArtifactRequested = [&](std::string const& _element) {\n\t\t\t\treturn isArtifactRequested(_inputsAndSettings.outputSelection, file, name, \"evm.deployedBytecode.\" + _element, wildcardMatchesExperimental);\n\t\t\t};\n\n\t\t\tJson deployedJSON;\n\t\t\tif (evmDeployedArtifactRequested(\"object\"))\n\t\t\t\tdeployedJSON[\"object\"] = compilerStack.runtimeObject(contractName).toHex();\n\t\t\tif (evmDeployedArtifactRequested(\"opcodes\"))\n\t\t\t\tdeployedJSON[\"opcodes\"] = evmasm::disassemble(compilerStack.runtimeObject(contractName).bytecode, _inputsAndSettings.evmVersion);\n\t\t\tif (evmDeployedArtifactRequested(\"sourceMap\"))\n\t\t\t\tdeployedJSON[\"sourceMap\"] = compilerStack.runtimeSourceMapping(contractName) ? *compilerStack.runtimeSourceMapping(contractName) : \"\";\n\t\t\tif (evmDeployedArtifactRequested(\"functionDebugData\"))\n\t\t\t\tdeployedJSON[\"functionDebugData\"] = formatFunctionDebugData(compilerStack.runtimeObject(contractName).functionDebugData);\n\t\t\tif (evmDeployedArtifactRequested(\"linkReferences\"))\n\t\t\t\tdeployedJSON[\"linkReferences\"] = formatLinkReferences(compilerStack.runtimeObject(contractName).linkReferences);\n\t\t\tif (evmDeployedArtifactRequested(\"immutableReferences\"))\n\t\t\t\tdeployedJSON[\"immutableReferences\"] = formatImmutableReferences(compilerStack.runtimeObject(contractName).immutableReferences);\n\t\t\tif (evmDeployedArtifactRequested(\"generatedSources\"))\n\t\t\t\tdeployedJSON[\"generatedSources\"] = compilerStack.generatedSources(contractName, /* _runtime */ true);\n\t\t\tif (evmDeployedArtifactRequested(\"ethdebug\"))\n\t\t\t\tdeployedJSON[\"ethdebug\"] = compilerStack.ethdebugRuntime(contractName);\n\t\t\tevmData[\"deployedBytecode\"] = deployedJSON;\n\t\t}\n\n\t\tif (!evmData.empty())\n\t\t\tcontractData[\"evm\"] = evmData;\n\n\t\tif (!contractData.empty())\n\t\t{\n\t\t\tif (!contractsOutput.contains(file))\n\t\t\t\tcontractsOutput[file] = Json::object();\n\t\t\tcontractsOutput[file][name] = contractData;\n\t\t}\n\t}\n\n\tif (isEthdebugRequested(_inputsAndSettings.outputSelection))\n\t\toutput[\"ethdebug\"] = compilerStack.ethdebug();\n\n\tif (!contractsOutput.empty())\n\t\toutput[\"contracts\"] = contractsOutput;\n\n\treturn output;\n}\n\n\nJson StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)\n{\n\tsolAssert(_inputsAndSettings.jsonSources.empty());\n\n\tJson output;\n\toutput[\"errors\"] = std::move(_inputsAndSettings.errors);\n\n\tif (_inputsAndSettings.sources.size() != 1)\n\t{\n\t\toutput[\"errors\"].emplace_back(formatError(\n\t\t\tError::Type::JSONError,\n\t\t\t\"general\",\n\t\t\t\"Yul mode only supports exactly one input file.\"\n\t\t));\n\t\treturn output;\n\t}\n\tif (!_inputsAndSettings.smtLib2Responses.empty())\n\t{\n\t\toutput[\"errors\"].emplace_back(formatError(\n\t\t\tError::Type::JSONError,\n\t\t\t\"general\",\n\t\t\t\"Yul mode does not support smtlib2responses.\"\n\t\t));\n\t\treturn output;\n\t}\n\tif (!_inputsAndSettings.remappings.empty())\n\t{\n\t\toutput[\"errors\"].emplace_back(formatError(\n\t\t\tError::Type::JSONError,\n\t\t\t\"general\",\n\t\t\t\"Field \\\"settings.remappings\\\" cannot be used for Yul.\"\n\t\t));\n\t\treturn output;\n\t}\n\tif (_inputsAndSettings.revertStrings != RevertStrings::Default)\n\t{\n\t\toutput[\"errors\"].emplace_back(formatError(\n\t\t\tError::Type::JSONError,\n\t\t\t\"general\",\n\t\t\t\"Field \\\"settings.debug.revertStrings\\\" cannot be used for Yul.\"\n\t\t));\n\t\treturn output;\n\t}\n\n\tYulStack stack(\n\t\t_inputsAndSettings.evmVersion,\n\t\t_inputsAndSettings.eofVersion,\n\t\t_inputsAndSettings.optimiserSettings,\n\t\t_inputsAndSettings.debugInfoSelection.has_value() ?\n\t\t\t_inputsAndSettings.debugInfoSelection.value() :\n\t\t\tDebugInfoSelection::Default()\n\t);\n\tstd::string const& sourceName = _inputsAndSettings.sources.begin()->first;\n\tstd::string const& sourceContents = _inputsAndSettings.sources.begin()->second;\n\n\tstd::string contractName;\n\tbool const wildcardMatchesExperimental = true;\n\tMachineAssemblyObject object;\n\tMachineAssemblyObject deployedObject;\n\n\tbool successful = stack.parseAndAnalyze(sourceName, sourceContents);\n\tif (!successful)\n\t\t// Inconsistent state - stop here to receive error reports from users\n\t\tsolAssert(stack.hasErrors(), \"No error reported, but parsing/analysis failed.\");\n\telse\n\t{\n\t\tcontractName = stack.parserResult()->name;\n\t\tif (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, \"ir\", wildcardMatchesExperimental))\n\t\t\toutput[\"contracts\"][sourceName][contractName][\"ir\"] = stack.print();\n\n\t\tif (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, \"ast\", wildcardMatchesExperimental))\n\t\t{\n\t\t\tJson sourceResult;\n\t\t\tsourceResult[\"id\"] = 0;\n\t\t\tsourceResult[\"ast\"] = stack.astJson();\n\t\t\toutput[\"sources\"][sourceName] = sourceResult;\n\t\t}\n\t\tstack.optimize();\n\t\tstd::tie(object, deployedObject) = stack.assembleWithDeployed({}, _inputsAndSettings.viaSSACFG);\n\t\tif (object.bytecode)\n\t\t\tobject.bytecode->link(_inputsAndSettings.libraries);\n\t\tif (deployedObject.bytecode)\n\t\t\tdeployedObject.bytecode->link(_inputsAndSettings.libraries);\n\t}\n\n\tfor (auto const& error: stack.errors())\n\t{\n\t\tauto err = std::dynamic_pointer_cast<Error const>(error);\n\n\t\toutput[\"errors\"].emplace_back(formatErrorWithException(\n\t\t\tstack,\n\t\t\t*error,\n\t\t\terr->type(),\n\t\t\t\"general\",\n\t\t\t\"\"\n\t\t));\n\t}\n\tif (stack.hasErrors())\n\t\treturn output;\n\n\tfor (auto&& [kind, isDeployed]: {make_pair(\"bytecode\"s, false), make_pair(\"deployedBytecode\"s, true)})\n\t\tif (isArtifactRequested(\n\t\t\t_inputsAndSettings.outputSelection,\n\t\t\tsourceName,\n\t\t\tcontractName,\n\t\t\tevmObjectComponents(kind),\n\t\t\twildcardMatchesExperimental\n\t\t))\n\t\t{\n\t\t\tauto const evmArtifactRequested = [&](std::string const& _kind, std::string const& _element) {\n\t\t\t\treturn isArtifactRequested(\n\t\t\t\t\t_inputsAndSettings.outputSelection,\n\t\t\t\t\tsourceName,\n\t\t\t\t\tcontractName,\n\t\t\t\t\t\"evm.\" + _kind + \".\" + _element,\n\t\t\t\t\twildcardMatchesExperimental\n\t\t\t\t);\n\t\t\t};\n\n\t\t\tMachineAssemblyObject const& selectedObject = isDeployed ? deployedObject : object;\n\t\t\tif (selectedObject.bytecode)\n\t\t\t{\n\t\t\t\tJson bytecodeJSON;\n\t\t\t\tif (evmArtifactRequested(kind, \"object\"))\n\t\t\t\t\tbytecodeJSON[\"object\"] = selectedObject.bytecode->toHex();\n\t\t\t\tif (evmArtifactRequested(kind, \"opcodes\"))\n\t\t\t\t\tbytecodeJSON[\"opcodes\"] = evmasm::disassemble(selectedObject.bytecode->bytecode, _inputsAndSettings.evmVersion);\n\t\t\t\tif (evmArtifactRequested(kind, \"sourceMap\"))\n\t\t\t\t\tbytecodeJSON[\"sourceMap\"] = selectedObject.sourceMappings ? *selectedObject.sourceMappings : \"\";\n\t\t\t\tif (evmArtifactRequested(kind, \"functionDebugData\"))\n\t\t\t\t\tbytecodeJSON[\"functionDebugData\"] = formatFunctionDebugData(selectedObject.bytecode->functionDebugData);\n\t\t\t\tif (evmArtifactRequested(kind, \"linkReferences\"))\n\t\t\t\t\tbytecodeJSON[\"linkReferences\"] = formatLinkReferences(selectedObject.bytecode->linkReferences);\n\t\t\t\tif (evmArtifactRequested(kind, \"ethdebug\"))\n\t\t\t\t{\n\t\t\t\t\tsolAssert(_inputsAndSettings.experimental);\n\t\t\t\t\tbytecodeJSON[\"ethdebug\"] = selectedObject.ethdebug;\n\t\t\t\t}\n\t\t\t\tif (isDeployed && evmArtifactRequested(kind, \"immutableReferences\"))\n\t\t\t\t\tbytecodeJSON[\"immutableReferences\"] = formatImmutableReferences(selectedObject.bytecode->immutableReferences);\n\t\t\t\toutput[\"contracts\"][sourceName][contractName][\"evm\"][kind] = bytecodeJSON;\n\t\t\t}\n\t\t}\n\n\tif (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, \"irOptimized\", wildcardMatchesExperimental))\n\t\toutput[\"contracts\"][sourceName][contractName][\"irOptimized\"] = stack.print();\n\tif (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, \"evm.assembly\", wildcardMatchesExperimental))\n\t\toutput[\"contracts\"][sourceName][contractName][\"evm\"][\"assembly\"] = object.assembly->assemblyString(stack.debugInfoSelection());\n\tif (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, \"yulCFGJson\", wildcardMatchesExperimental))\n\t{\n\t\tsolAssert(_inputsAndSettings.experimental, \"\");\n\t\toutput[\"contracts\"][sourceName][contractName][\"yulCFGJson\"] = stack.cfgJson();\n\t}\n\n\tif (isEthdebugRequested(_inputsAndSettings.outputSelection))\n\t{\n\t\tsolAssert(_inputsAndSettings.experimental, \"\");\n\t\toutput[\"ethdebug\"] = evmasm::ethdebug::resources({sourceName}, VersionString);\n\t}\n\treturn output;\n}\n\nJson StandardCompiler::compile(Json const& _input) noexcept\n{\n\tYulStringRepository::reset();\n\n\ttry\n\t{\n\t\tauto parsed = parseInput(_input);\n\t\tif (std::holds_alternative<Json>(parsed))\n\t\t\treturn std::get<Json>(std::move(parsed));\n\t\tInputsAndSettings settings = std::get<InputsAndSettings>(std::move(parsed));\n\t\tif (settings.language == \"Solidity\")\n\t\t\treturn compileSolidity(std::move(settings));\n\t\telse if (settings.language == \"Yul\")\n\t\t\treturn compileYul(std::move(settings));\n\t\telse if (settings.language == \"SolidityAST\")\n\t\t\treturn compileSolidity(std::move(settings));\n\t\telse if (settings.language == \"EVMAssembly\")\n\t\t\treturn importEVMAssembly(std::move(settings));\n\t\telse\n\t\t\treturn formatFatalError(Error::Type::JSONError, \"Only \\\"Solidity\\\", \\\"Yul\\\", \\\"SolidityAST\\\" or \\\"EVMAssembly\\\" is supported as a language.\");\n\t}\n\tcatch (UnimplementedFeatureError const& _exception)\n\t{\n\t\tsolAssert(_exception.comment(), \"Unimplemented feature errors must include a message for the user\");\n\t\treturn formatFatalError(Error::Type::UnimplementedFeatureError, stringOrDefault(_exception.comment()));\n\t}\n\tcatch (...)\n\t{\n\t\treturn formatFatalError(\n\t\t\tError::Type::InternalCompilerError,\n\t\t\t\"Uncaught exception:\\n\" + boost::current_exception_diagnostic_information()\n\t\t);\n\t}\n}\n\nstd::string StandardCompiler::compile(std::string const& _input) noexcept\n{\n\tJson input;\n\tstd::string errors;\n\ttry\n\t{\n\t\tif (!util::jsonParseStrict(_input, input, &errors))\n\t\t\treturn util::jsonPrint(formatFatalError(Error::Type::JSONError, errors), m_jsonPrintingFormat);\n\t}\n\tcatch (...)\n\t{\n\t\tif (errors.empty())\n\t\t\treturn \"{\\\"errors\\\":[{\\\"type\\\":\\\"JSONError\\\",\\\"component\\\":\\\"general\\\",\\\"severity\\\":\\\"error\\\",\\\"message\\\":\\\"Error parsing input JSON.\\\"}]}\";\n\t\telse\n\t\t\treturn \"{\\\"errors\\\":[{\\\"type\\\":\\\"JSONError\\\",\\\"component\\\":\\\"general\\\",\\\"severity\\\":\\\"error\\\",\\\"message\\\":\\\"Error parsing input JSON: \" + errors + \"\\\"}]}\";\n\t}\n\n//\tstd::cout << \"Input: \" << solidity::util::jsonPrettyPrint(input) << std::endl;\n\tJson output = compile(input);\n//\tstd::cout << \"Output: \" << solidity::util::jsonPrettyPrint(output) << std::endl;\n\n\ttry\n\t{\n\t\treturn util::jsonPrint(output, m_jsonPrintingFormat);\n\t}\n\tcatch (...)\n\t{\n\t\treturn \"{\\\"errors\\\":[{\\\"type\\\":\\\"JSONError\\\",\\\"component\\\":\\\"general\\\",\\\"severity\\\":\\\"error\\\",\\\"message\\\":\\\"Error writing output JSON.\\\"}]}\";\n\t}\n}\n\nJson StandardCompiler::formatFunctionDebugData(\n\tstd::map<std::string, evmasm::LinkerObject::FunctionDebugData> const& _debugInfo\n)\n{\n\tstatic_assert(std::is_same_v<Json::number_unsigned_t, uint64_t>);\n\tJson ret = Json::object();\n\tfor (auto const& [name, info]: _debugInfo)\n\t{\n\t\tJson fun = Json::object();\n\t\tif (info.sourceID)\n\t\t\tfun[\"id\"] = Json::number_unsigned_t(*info.sourceID);\n\t\telse\n\t\t\tfun[\"id\"] = Json();\n\t\tif (info.bytecodeOffset)\n\t\t\tfun[\"entryPoint\"] = Json::number_unsigned_t(*info.bytecodeOffset);\n\t\telse\n\t\t\tfun[\"entryPoint\"] = Json();\n\t\tfun[\"parameterSlots\"] = Json::number_unsigned_t(info.params);\n\t\tfun[\"returnSlots\"] = Json::number_unsigned_t(info.returns);\n\t\tret[name] = std::move(fun);\n\t}\n\n\treturn ret;\n}\n"
  },
  {
    "path": "libsolidity/interface/StandardCompiler.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Alex Beregszaszi\n * @date 2016\n * Standard JSON compiler interface.\n */\n\n#pragma once\n\n#include <libsolidity/interface/CompilerStack.h>\n#include <libsolutil/JSON.h>\n\n#include <liblangutil/DebugInfoSelection.h>\n\n#include <optional>\n#include <utility>\n#include <variant>\n\nnamespace solidity::frontend\n{\n\n/**\n * Standard JSON compiler interface, which expects a JSON input and returns a JSON output.\n * See docs/using-the-compiler#compiler-input-and-output-json-description.\n */\nclass StandardCompiler\n{\npublic:\n\t/// Noncopyable.\n\tStandardCompiler(StandardCompiler const&) = delete;\n\tStandardCompiler& operator=(StandardCompiler const&) = delete;\n\n\t/// Creates a new StandardCompiler.\n\t/// @param _readFile callback used to read files for import statements. Must return\n\t/// and must not emit exceptions.\n\texplicit StandardCompiler(ReadCallback::Callback _readFile = ReadCallback::Callback(),\n\t\tutil::JsonFormat const& _format = {}):\n\t\tm_readFile(std::move(_readFile)),\n\t\tm_jsonPrintingFormat(std::move(_format))\n\t{\n\t}\n\n\t/// Sets all input parameters according to @a _input which conforms to the standardized input\n\t/// format, performs compilation and returns a standardized output.\n\tJson compile(Json const& _input) noexcept;\n\t/// Parses input as JSON and performs the above processing steps, returning a serialized JSON\n\t/// output. Parsing errors are returned as regular errors.\n\tstd::string compile(std::string const& _input) noexcept;\n\n\tstatic Json formatFunctionDebugData(\n\t\tstd::map<std::string, evmasm::LinkerObject::FunctionDebugData> const& _debugInfo\n\t);\n\nprivate:\n\tstruct InputsAndSettings\n\t{\n\t\tstd::string language;\n\t\tJson errors;\n\t\tCompilerStack::State stopAfter = CompilerStack::State::CompilationSuccessful;\n\t\tstd::map<std::string, std::string> sources;\n\t\tstd::map<std::string, Json> jsonSources;\n\t\tstd::map<util::h256, std::string> smtLib2Responses;\n\t\tlangutil::EVMVersion evmVersion;\n\t\tstd::optional<uint8_t> eofVersion;\n\t\tstd::vector<ImportRemapper::Remapping> remappings;\n\t\tRevertStrings revertStrings = RevertStrings::Default;\n\t\tOptimiserSettings optimiserSettings;\n\t\tstd::optional<langutil::DebugInfoSelection> debugInfoSelection;\n\t\tstd::map<std::string, util::h160> libraries;\n\t\tbool metadataLiteralSources = false;\n\t\tCompilerStack::MetadataFormat metadataFormat = CompilerStack::defaultMetadataFormat();\n\t\tCompilerStack::MetadataHash metadataHash = CompilerStack::MetadataHash::IPFS;\n\t\tJson outputSelection;\n\t\tModelCheckerSettings modelCheckerSettings = ModelCheckerSettings{};\n\t\tbool viaIR = false;\n\t\tbool viaSSACFG = false;\n\t\tbool experimental = false;\n\t};\n\n\t/// Parses the input json (and potentially invokes the read callback) and either returns\n\t/// it in condensed form or an error as a json object.\n\tstd::variant<InputsAndSettings, Json> parseInput(Json const& _input);\n\n\tstd::map<std::string, Json> parseAstFromInput(StringMap const& _sources);\n\tJson importEVMAssembly(InputsAndSettings _inputsAndSettings);\n\tJson compileSolidity(InputsAndSettings _inputsAndSettings);\n\tJson compileYul(InputsAndSettings _inputsAndSettings);\n\n\tReadCallback::Callback m_readFile;\n\n\tutil::JsonFormat m_jsonPrintingFormat;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/StorageLayout.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/interface/StorageLayout.h>\n\n#include <libsolidity/ast/TypeProvider.h>\n\nusing namespace std::literals;\nusing namespace solidity;\nusing namespace solidity::frontend;\n\nJson StorageLayout::generate(ContractDefinition const& _contractDef, DataLocation const _location)\n{\n\tsolAssert(!m_contract, \"\");\n\tm_contract = &_contractDef;\n\tm_types.clear();\n\n\tauto typeType = dynamic_cast<TypeType const*>(_contractDef.type());\n\tsolAssert(typeType, \"\");\n\tauto contractType = dynamic_cast<ContractType const*>(typeType->actualType());\n\tsolAssert(contractType, \"\");\n\n\tJson variables = Json::array();\n\tfor (auto [var, slot, offset]: contractType->linearizedStateVariables(_location))\n\t\tvariables.emplace_back(generate(*var, slot, offset));\n\n\tJson layout;\n\tlayout[\"storage\"] = std::move(variables);\n\tlayout[\"types\"] = std::move(m_types);\n\n\treturn layout;\n}\n\nJson StorageLayout::generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset)\n{\n\tJson varEntry;\n\tType const* varType = _var.type();\n\n\tvarEntry[\"label\"] = _var.name();\n\tvarEntry[\"astId\"] = static_cast<int>(_var.id());\n\tvarEntry[\"contract\"] = m_contract->fullyQualifiedName();\n\tvarEntry[\"slot\"] = _slot.str();\n\tvarEntry[\"offset\"] = _offset;\n\tvarEntry[\"type\"] = typeKeyName(varType);\n\n\tgenerate(varType);\n\n\treturn varEntry;\n}\n\nvoid StorageLayout::generate(Type const* _type)\n{\n\tif (m_types.contains(typeKeyName(_type)))\n\t\treturn;\n\n\t// Register it now to cut recursive visits.\n\tJson& typeInfo = m_types[typeKeyName(_type)];\n\ttypeInfo[\"label\"] = _type->toString(true);\n\ttypeInfo[\"numberOfBytes\"] = u256(_type->storageBytes() * _type->storageSize()).str();\n\n\tif (auto structType = dynamic_cast<StructType const*>(_type))\n\t{\n\t\tJson members = Json::array();\n\t\tauto const& structDef = structType->structDefinition();\n\t\tfor (auto const& member: structDef.members())\n\t\t{\n\t\t\tauto const& offsets = structType->storageOffsetsOfMember(member->name());\n\t\t\tmembers.emplace_back(generate(*member, offsets.first, offsets.second));\n\t\t}\n\t\ttypeInfo[\"members\"] = std::move(members);\n\t\ttypeInfo[\"encoding\"] = \"inplace\";\n\t}\n\telse if (auto mappingType = dynamic_cast<MappingType const*>(_type))\n\t{\n\t\ttypeInfo[\"key\"] = typeKeyName(mappingType->keyType());\n\t\ttypeInfo[\"value\"] = typeKeyName(mappingType->valueType());\n\t\tgenerate(mappingType->keyType());\n\t\tgenerate(mappingType->valueType());\n\t\ttypeInfo[\"encoding\"] = \"mapping\";\n\t}\n\telse if (auto arrayType = dynamic_cast<ArrayType const*>(_type))\n\t{\n\t\tif (arrayType->isByteArrayOrString())\n\t\t\ttypeInfo[\"encoding\"] = \"bytes\";\n\t\telse\n\t\t{\n\t\t\ttypeInfo[\"base\"] = typeKeyName(arrayType->baseType());\n\t\t\tgenerate(arrayType->baseType());\n\t\t\ttypeInfo[\"encoding\"] = arrayType->isDynamicallySized() ? \"dynamic_array\" : \"inplace\";\n\t\t}\n\t}\n\telse\n\t{\n\t\tsolAssert(_type->isValueType(), \"\");\n\t\ttypeInfo[\"encoding\"] = \"inplace\";\n\t}\n\n\tsolAssert(typeInfo.contains(\"encoding\"), \"\");\n}\n\nstd::string StorageLayout::typeKeyName(Type const* _type)\n{\n\tif (auto refType = dynamic_cast<ReferenceType const*>(_type))\n\t\treturn TypeProvider::withLocationIfReference(refType->location(), _type)->richIdentifier();\n\treturn _type->richIdentifier();\n}\n"
  },
  {
    "path": "libsolidity/interface/StorageLayout.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Generates the storage/transient storage layout of a contract.\n */\n\n#pragma once\n\n#include <libsolutil/JSON.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/Types.h>\n\nnamespace solidity::frontend\n{\n\nclass StorageLayout\n{\npublic:\n\t/// Generates the storage layout of the contract\n\t/// @param _contractDef The contract definition\n\t/// @param _location The location (storage or transient storage) for which to generate the layout\n\t/// @return A JSON representation of the contract's storage layout.\n\tJson generate(ContractDefinition const& _contractDef, DataLocation const _location);\n\nprivate:\n\t/// Generates the JSON information for a variable and its storage location.\n\tJson generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset);\n\n\t/// Generates the JSON information for @param _type\n\tvoid generate(Type const* _type);\n\n\t/// The key for the JSON object describing a type.\n\tstd::string typeKeyName(Type const* _type);\n\n\tJson m_types;\n\n\t/// Current analyzed contract\n\tContractDefinition const* m_contract = nullptr;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/UniversalCallback.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/interface/FileReader.h>\n#include <libsolidity/interface/SMTSolverCommand.h>\n\nnamespace solidity::frontend\n{\n\n/// UniversalCallback is used to wrap both FileReader and SMTSolverCommand\n/// callbacks in a single callback.  It uses the Kind of the callback to\n/// determine which to call internally.\nclass UniversalCallback\n{\npublic:\n\tUniversalCallback(FileReader* _fileReader, SMTSolverCommand& _solver) :\n\t\tm_fileReader{_fileReader},\n\t\tm_solver{_solver}\n\t{}\n\n\tReadCallback::Result operator()(std::string const& _kind, std::string const& _data)\n\t{\n\t\tif (_kind == ReadCallback::kindString(ReadCallback::Kind::ReadFile))\n\t\t\tif (!m_fileReader)\n\t\t\t\treturn ReadCallback::Result{false, \"No import callback.\"};\n\t\t\telse\n\t\t\t\treturn m_fileReader->readFile(_kind, _data);\n\t\telse if (_kind == ReadCallback::kindString(ReadCallback::Kind::SMTQuery))\n\t\t\treturn m_solver.solve(_kind, _data);\n\t\tsolAssert(false, \"Unknown callback kind.\");\n\t}\n\n\tfrontend::ReadCallback::Callback callback() const\n\t{\n\t\treturn *this;\n\t}\n\n\tvoid resetImportCallback() { m_fileReader = nullptr; }\n\n\tSMTSolverCommand& smtCommand() { return m_solver; }\n\nprivate:\n\tFileReader* m_fileReader;\n\tSMTSolverCommand& m_solver;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/interface/Version.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Versioning.\n */\n\n#include <libsolidity/interface/Version.h>\n\n#include <solidity/BuildInfo.h>\n\nchar const* solidity::frontend::VersionNumber = ETH_PROJECT_VERSION;\n\nstd::string const solidity::frontend::VersionString =\n\tstd::string(solidity::frontend::VersionNumber) +\n\t(std::string(SOL_VERSION_PRERELEASE).empty() ? \"\" : \"-\" + std::string(SOL_VERSION_PRERELEASE)) +\n\t(std::string(SOL_VERSION_BUILDINFO).empty() ? \"\" : \"+\" + std::string(SOL_VERSION_BUILDINFO));\n\nstd::string const solidity::frontend::VersionStringStrict =\n\tstd::string(solidity::frontend::VersionNumber) +\n\t(std::string(SOL_VERSION_PRERELEASE).empty() ? \"\" : \"-\" + std::string(SOL_VERSION_PRERELEASE)) +\n\t(std::string(SOL_VERSION_COMMIT).empty() ? \"\" : \"+\" + std::string(SOL_VERSION_COMMIT));\n\nsolidity::bytes const solidity::frontend::VersionCompactBytes = {\n\tETH_PROJECT_VERSION_MAJOR,\n\tETH_PROJECT_VERSION_MINOR,\n\tETH_PROJECT_VERSION_PATCH\n};\n\nbool const solidity::frontend::VersionIsRelease = std::string(SOL_VERSION_PRERELEASE).empty();\n"
  },
  {
    "path": "libsolidity/interface/Version.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Versioning.\n */\n\n#pragma once\n\n#include <cstdint>\n#include <vector>\n#include <string>\n\nnamespace solidity\n{\nusing bytes = std::vector<uint8_t>;\n\nnamespace frontend\n{\n\nextern char const* VersionNumber;\nextern std::string const VersionString;\nextern std::string const VersionStringStrict;\nextern bytes const VersionCompactBytes;\nextern bool const VersionIsRelease;\n\n}\n}\n"
  },
  {
    "path": "libsolidity/lsp/DocumentHoverHandler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/lsp/DocumentHoverHandler.h>\n#include <libsolidity/lsp/Utils.h>\n\n#include <fmt/format.h>\n\nnamespace solidity::lsp\n{\nusing namespace solidity::lsp;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nnamespace\n{\n\nstruct MarkdownBuilder\n{\n\tstd::stringstream result;\n\n\tMarkdownBuilder& solidityCode(std::string const& _code)\n\t{\n\t\tauto constexpr SolidityLanguageId = \"solidity\";\n\t\tresult << \"```\" << SolidityLanguageId << '\\n' << _code << \"\\n```\\n\\n\";\n\t\treturn *this;\n\t}\n\n\tMarkdownBuilder& paragraph(std::string const& _text)\n\t{\n\t\tif (!_text.empty())\n\t\t{\n\t\t\tresult << _text << '\\n';\n\t\t\tif (_text.back() != '\\n') // We want double-LF to ensure constructing a paragraph.\n\t\t\t\tresult << '\\n';\n\t\t}\n\t\treturn *this;\n\t}\n};\n\n}\n\nvoid DocumentHoverHandler::operator()(MessageID _id, Json const& _args)\n{\n\tauto const [sourceUnitName, lineColumn] = HandlerBase(*this).extractSourceUnitNameAndLineColumn(_args);\n\tauto const [sourceNode, sourceOffset] = m_server.astNodeAndOffsetAtSourceLocation(sourceUnitName, lineColumn);\n\tif (!sourceNode)\n\t{\n\t\tclient().reply(_id, Json());\n\t\treturn;\n\t}\n\n\tMarkdownBuilder markdown;\n\tauto rangeToHighlight = toRange(sourceNode->location());\n\n\t// Try getting the type definition of the underlying AST node, if available.\n\tif (auto const* expression = dynamic_cast<Expression const*>(sourceNode))\n\t{\n\t\tif (auto const* declaration = ASTNode::referencedDeclaration(*expression))\n\t\t\tif (declaration->type())\n\t\t\t\tmarkdown.solidityCode(declaration->type()->toString(false));\n\t}\n\telse if (auto const* declaration = dynamic_cast<Declaration const*>(sourceNode))\n\t{\n\t\tif (declaration->type())\n\t\t\tmarkdown.solidityCode(declaration->type()->toString(false));\n\t}\n\telse if (auto const* identifierPath = dynamic_cast<IdentifierPath const*>(sourceNode))\n\t{\n\t\tfor (size_t i = 0; i < identifierPath->path().size(); ++i)\n\t\t{\n\t\t\tif (identifierPath->pathLocations()[i].containsOffset(sourceOffset))\n\t\t\t{\n\t\t\t\trangeToHighlight = toRange(identifierPath->pathLocations()[i]);\n\n\t\t\t\tif (i < identifierPath->annotation().pathDeclarations.size())\n\t\t\t\t{\n\t\t\t\t\tDeclaration const* declaration = identifierPath->annotation().pathDeclarations[i];\n\t\t\t\t\tif (declaration && declaration->type())\n\t\t\t\t\t\tmarkdown.solidityCode(declaration->type()->toString(false));\n\t\t\t\t\tif (auto const* structurallyDocumented = dynamic_cast<StructurallyDocumented const*>(declaration))\n\t\t\t\t\t\tif (structurallyDocumented->documentation()->text())\n\t\t\t\t\t\t\tmarkdown.paragraph(*structurallyDocumented->documentation()->text());\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// If this AST node contains documentation itself, append it.\n\tif (auto const* documented = dynamic_cast<StructurallyDocumented const*>(sourceNode))\n\t{\n\t\tif (documented->documentation())\n\t\t\tmarkdown.paragraph(*documented->documentation()->text());\n\t}\n\n\tauto tooltipText = markdown.result.str();\n\n\tif (tooltipText.empty())\n\t{\n\t\tclient().reply(_id, Json());\n\t\treturn;\n\t}\n\n\tJson reply;\n\treply[\"range\"] = rangeToHighlight;\n\treply[\"contents\"][\"kind\"] = \"markdown\";\n\treply[\"contents\"][\"value\"] = std::move(tooltipText);\n\n\tclient().reply(_id, reply);\n}\n\n}\n"
  },
  {
    "path": "libsolidity/lsp/DocumentHoverHandler.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n#include <libsolidity/lsp/HandlerBase.h>\n\nnamespace solidity::lsp\n{\n\nclass DocumentHoverHandler: public HandlerBase\n{\npublic:\n\tusing HandlerBase::HandlerBase;\n\n\tvoid operator()(MessageID, Json const&);\n};\n\n}\n"
  },
  {
    "path": "libsolidity/lsp/FileRepository.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/lsp/FileRepository.h>\n#include <libsolidity/lsp/Transport.h>\n#include <libsolidity/lsp/Utils.h>\n\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/CommonIO.h>\n\n#include <range/v3/algorithm/none_of.hpp>\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/transform.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n\n#include <regex>\n\n#include <boost/algorithm/string/predicate.hpp>\n\n#include <fmt/format.h>\n\nusing namespace solidity;\nusing namespace solidity::lsp;\nusing namespace solidity::frontend;\n\nusing solidity::util::readFileAsString;\nusing solidity::util::joinHumanReadable;\nusing solidity::util::Result;\n\nFileRepository::FileRepository(boost::filesystem::path _basePath, std::vector<boost::filesystem::path> _includePaths):\n\tm_basePath(std::move(_basePath)),\n\tm_includePaths(std::move(_includePaths))\n{\n}\n\nvoid FileRepository::setIncludePaths(std::vector<boost::filesystem::path> _paths)\n{\n\tm_includePaths = std::move(_paths);\n}\n\nstd::string FileRepository::sourceUnitNameToUri(std::string const& _sourceUnitName) const\n{\n\tstd::regex const windowsDriveLetterPath(\"^[a-zA-Z]:/\");\n\n\tauto const ensurePathIsUnixLike = [&](std::string inputPath) -> std::string {\n\t\tif (!regex_search(inputPath, windowsDriveLetterPath))\n\t\t\treturn inputPath;\n\t\telse\n\t\t\treturn \"/\" + std::move(inputPath);\n\t};\n\n\tif (m_sourceUnitNamesToUri.count(_sourceUnitName))\n\t{\n\t\tsolAssert(boost::starts_with(m_sourceUnitNamesToUri.at(_sourceUnitName), \"file://\"), \"\");\n\t\treturn m_sourceUnitNamesToUri.at(_sourceUnitName);\n\t}\n\telse if (_sourceUnitName.find(\"file://\") == 0)\n\t\treturn _sourceUnitName;\n\telse if (regex_search(_sourceUnitName, windowsDriveLetterPath))\n\t\treturn \"file:///\" + _sourceUnitName;\n\telse if (\n\t\tauto const resolvedPath = tryResolvePath(_sourceUnitName);\n\t\tresolvedPath.message().empty()\n\t)\n\t\treturn \"file://\" + ensurePathIsUnixLike(resolvedPath.get().generic_string());\n\telse if (m_basePath.generic_string() != \"/\")\n\t\treturn \"file://\" + m_basePath.generic_string() + \"/\" + _sourceUnitName;\n\telse\n\t\t// Avoid double-/ in case base-path itself is simply a UNIX root filesystem root.\n\t\treturn \"file:///\" + _sourceUnitName;\n}\n\nstd::string FileRepository::uriToSourceUnitName(std::string const& _path) const\n{\n\tlspRequire(boost::algorithm::starts_with(_path, \"file://\"), ErrorCode::InternalError, \"URI must start with file://\");\n\treturn stripFileUriSchemePrefix(_path);\n}\n\nvoid FileRepository::setSourceByUri(std::string const& _uri, std::string _source)\n{\n\t// This is needed for uris outside the base path. It can lead to collisions,\n\t// but we need to mostly rewrite this in a future version anyway.\n\tauto sourceUnitName = uriToSourceUnitName(_uri);\n\tlspDebug(fmt::format(\"FileRepository.setSourceByUri({}): {}\", _uri, _source));\n\tm_sourceUnitNamesToUri.emplace(sourceUnitName, _uri);\n\tm_sourceCodes[sourceUnitName] = std::move(_source);\n}\n\nResult<boost::filesystem::path> FileRepository::tryResolvePath(std::string const& _strippedSourceUnitName) const\n{\n\tif (\n\t\tboost::filesystem::path(_strippedSourceUnitName).has_root_path() &&\n\t\tboost::filesystem::exists(_strippedSourceUnitName)\n\t)\n\t\treturn boost::filesystem::path(_strippedSourceUnitName);\n\n\tstd::vector<boost::filesystem::path> candidates;\n\tstd::vector<std::reference_wrapper<boost::filesystem::path const>> prefixes = {m_basePath};\n\tprefixes += (m_includePaths | ranges::to<std::vector<std::reference_wrapper<boost::filesystem::path const>>>);\n\tauto const defaultInclude = m_basePath / \"node_modules\";\n\tif (m_includePaths.empty())\n\t\tprefixes.emplace_back(defaultInclude);\n\n\tauto const pathToQuotedString = [](boost::filesystem::path const& _path) { return \"\\\"\" + _path.string() + \"\\\"\"; };\n\n\tfor (auto const& prefix: prefixes)\n\t{\n\t\tboost::filesystem::path canonicalPath = boost::filesystem::path(prefix) / boost::filesystem::path(_strippedSourceUnitName);\n\n\t\tif (boost::filesystem::exists(canonicalPath))\n\t\t\tcandidates.push_back(std::move(canonicalPath));\n\t}\n\n\tif (candidates.empty())\n\t\treturn Result<boost::filesystem::path>::err(\n\t\t\t\"File not found. Searched the following locations: \" +\n\t\t\tjoinHumanReadable(prefixes | ranges::views::transform(pathToQuotedString), \", \") +\n\t\t\t\".\"\n\t\t);\n\n\tif (candidates.size() >= 2)\n\t\treturn Result<boost::filesystem::path>::err(\n\t\t\t\"Ambiguous import. \"\n\t\t\t\"Multiple matching files found inside base path and/or include paths: \" +\n\t\t\tjoinHumanReadable(candidates | ranges::views::transform(pathToQuotedString), \", \") +\n\t\t\t\".\"\n\t\t);\n\n\tif (!boost::filesystem::is_regular_file(candidates[0]))\n\t\treturn Result<boost::filesystem::path>::err(\"Not a valid file.\");\n\n\treturn candidates[0];\n}\n\nfrontend::ReadCallback::Result FileRepository::readFile(std::string const& _kind, std::string const& _sourceUnitName)\n{\n\tsolAssert(\n\t\t_kind == ReadCallback::kindString(ReadCallback::Kind::ReadFile),\n\t\t\"ReadFile callback used as callback kind \" + _kind\n\t);\n\n\ttry\n\t{\n\t\t// File was read already. Use local store.\n\t\tif (m_sourceCodes.count(_sourceUnitName))\n\t\t\treturn ReadCallback::Result{true, m_sourceCodes.at(_sourceUnitName)};\n\n\t\tstd::string const strippedSourceUnitName = stripFileUriSchemePrefix(_sourceUnitName);\n\t\tResult<boost::filesystem::path> const resolvedPath = tryResolvePath(strippedSourceUnitName);\n\t\tif (!resolvedPath.message().empty())\n\t\t\treturn ReadCallback::Result{false, resolvedPath.message()};\n\n\t\tauto contents = readFileAsString(resolvedPath.get());\n\t\tsolAssert(m_sourceCodes.count(_sourceUnitName) == 0, \"\");\n\t\tm_sourceCodes[_sourceUnitName] = contents;\n\t\treturn ReadCallback::Result{true, std::move(contents)};\n\t}\n\tcatch (...)\n\t{\n\t\treturn ReadCallback::Result{false, \"Exception in read callback: \" + boost::current_exception_diagnostic_information()};\n\t}\n}\n\n"
  },
  {
    "path": "libsolidity/lsp/FileRepository.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/interface/FileReader.h>\n#include <libsolutil/Result.h>\n\n#include <string>\n#include <map>\n\nnamespace solidity::lsp\n{\n\nclass FileRepository\n{\npublic:\n\tFileRepository(boost::filesystem::path _basePath, std::vector<boost::filesystem::path> _includePaths);\n\n\tstd::vector<boost::filesystem::path> const& includePaths() const noexcept { return m_includePaths; }\n\tvoid setIncludePaths(std::vector<boost::filesystem::path> _paths);\n\n\tboost::filesystem::path const& basePath() const { return m_basePath; }\n\n\t/// Translates a compiler-internal source unit name to an LSP client path.\n\tstd::string sourceUnitNameToUri(std::string const& _sourceUnitName) const;\n\n\t/// Translates an LSP file URI into a compiler-internal source unit name.\n\tstd::string uriToSourceUnitName(std::string const& _uri) const;\n\n\t/// @returns all sources by their compiler-internal source unit name.\n\tStringMap const& sourceUnits() const noexcept { return m_sourceCodes; }\n\n\t/// Changes the source identified by the LSP client path _uri to _text.\n\tvoid setSourceByUri(std::string const& _uri, std::string _text);\n\n\tvoid setSourceUnits(StringMap _sources);\n\tfrontend::ReadCallback::Result readFile(std::string const& _kind, std::string const& _sourceUnitName);\n\tfrontend::ReadCallback::Callback reader()\n\t{\n\t\treturn [this](std::string const& _kind, std::string const& _path) { return readFile(_kind, _path); };\n\t}\n\n\tutil::Result<boost::filesystem::path> tryResolvePath(std::string const& _sourceUnitName) const;\n\nprivate:\n\t/// Base path without URI scheme.\n\tboost::filesystem::path m_basePath;\n\n\t/// Additional directories used for resolving relative paths in imports.\n\tstd::vector<boost::filesystem::path> m_includePaths;\n\n\t/// Mapping of source unit names to their URIs as understood by the client.\n\tStringMap m_sourceUnitNamesToUri;\n\n\t/// Mapping of source unit names to their file content.\n\tStringMap m_sourceCodes;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/lsp/GotoDefinition.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/lsp/GotoDefinition.h>\n#include <libsolidity/lsp/Transport.h> // for RequestError\n#include <libsolidity/lsp/Utils.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTUtils.h>\n\n#include <fmt/format.h>\n\n#include <memory>\n#include <string>\n#include <vector>\n\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\nusing namespace solidity::lsp;\n\nvoid GotoDefinition::operator()(MessageID _id, Json const& _args)\n{\n\tauto const [sourceUnitName, lineColumn] = extractSourceUnitNameAndLineColumn(_args);\n\n\tASTNode const* sourceNode = m_server.astNodeAtSourceLocation(sourceUnitName, lineColumn);\n\n\tstd::vector<SourceLocation> locations;\n\tif (auto const* expression = dynamic_cast<Expression const*>(sourceNode))\n\t{\n\t\t// Handles all expressions that can have one or more declaration annotation.\n\t\tif (auto const* declaration = referencedDeclaration(expression))\n\t\t\tif (auto location = declarationLocation(declaration))\n\t\t\t\tlocations.emplace_back(std::move(location.value()));\n\t}\n\telse if (auto const* identifierPath = dynamic_cast<IdentifierPath const*>(sourceNode))\n\t{\n\t\tif (auto const* declaration = identifierPath->annotation().referencedDeclaration)\n\t\t\tif (auto location = declarationLocation(declaration))\n\t\t\t\tlocations.emplace_back(std::move(location.value()));\n\t}\n\telse if (auto const* importDirective = dynamic_cast<ImportDirective const*>(sourceNode))\n\t{\n\t\tauto const& path = *importDirective->annotation().absolutePath;\n\t\tif (fileRepository().sourceUnits().count(path))\n\t\t\tlocations.emplace_back(SourceLocation{0, 0, std::make_shared<std::string const>(path)});\n\t}\n\n\tJson reply = Json::array();\n\tfor (SourceLocation const& location: locations)\n\t\treply.emplace_back(toJson(location));\n\tclient().reply(_id, reply);\n}\n"
  },
  {
    "path": "libsolidity/lsp/GotoDefinition.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/lsp/HandlerBase.h>\n\nnamespace solidity::lsp\n{\n\nclass GotoDefinition: public HandlerBase\n{\npublic:\n\texplicit GotoDefinition(LanguageServer& _server): HandlerBase(_server) {}\n\n\tvoid operator()(MessageID, Json const&);\n};\n\n}\n"
  },
  {
    "path": "libsolidity/lsp/HandlerBase.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolutil/Exceptions.h>\n\n#include <libsolidity/lsp/HandlerBase.h>\n#include <libsolidity/lsp/LanguageServer.h>\n#include <libsolidity/lsp/Utils.h>\n#include <libsolidity/ast/AST.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <fmt/format.h>\n\nusing namespace solidity::langutil;\nusing namespace solidity::lsp;\nusing namespace solidity::util;\nusing namespace solidity;\n\nJson HandlerBase::toRange(SourceLocation const& _location) const\n{\n\tif (!_location.hasText())\n\t\treturn toJsonRange({}, {});\n\n\tsolAssert(_location.sourceName, \"\");\n\tlangutil::CharStream const& stream = charStreamProvider().charStream(*_location.sourceName);\n\tLineColumn start = stream.translatePositionToLineColumn(_location.start);\n\tLineColumn end = stream.translatePositionToLineColumn(_location.end);\n\treturn toJsonRange(start, end);\n}\n\nJson HandlerBase::toJson(SourceLocation const& _location) const\n{\n\tsolAssert(_location.sourceName);\n\tJson item;\n\titem[\"uri\"] = fileRepository().sourceUnitNameToUri(*_location.sourceName);\n\titem[\"range\"] = toRange(_location);\n\treturn item;\n}\n\nstd::pair<std::string, LineColumn> HandlerBase::extractSourceUnitNameAndLineColumn(Json const& _args) const\n{\n\tstd::string const uri = _args[\"textDocument\"][\"uri\"].get<std::string>();\n\tstd::string const sourceUnitName = fileRepository().uriToSourceUnitName(uri);\n\tif (!fileRepository().sourceUnits().count(sourceUnitName))\n\t\tBOOST_THROW_EXCEPTION(\n\t\t\tRequestError(ErrorCode::RequestFailed) <<\n\t\t\terrinfo_comment(\"Unknown file: \" + uri)\n\t\t);\n\n\tauto const lineColumn = parseLineColumn(_args[\"position\"]);\n\tif (!lineColumn)\n\t\tBOOST_THROW_EXCEPTION(\n\t\t\tRequestError(ErrorCode::RequestFailed) <<\n\t\t\terrinfo_comment(fmt::format(\n\t\t\t\t\"Unknown position {line}:{column} in file: {file}\",\n\t\t\t\tfmt::arg(\"line\", lineColumn.value().line),\n\t\t\t\tfmt::arg(\"column\", lineColumn.value().column),\n\t\t\t\tfmt::arg(\"file\", sourceUnitName)\n\t\t\t))\n\t\t);\n\n\treturn {sourceUnitName, *lineColumn};\n}\n"
  },
  {
    "path": "libsolidity/lsp/HandlerBase.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/lsp/FileRepository.h>\n#include <libsolidity/lsp/LanguageServer.h>\n\n#include <liblangutil/SourceLocation.h>\n#include <liblangutil/CharStreamProvider.h>\n\n#include <optional>\n\nnamespace solidity::lsp\n{\n\nclass Transport;\n\n/**\n * Helper base class for implementing handlers.\n */\nclass HandlerBase\n{\npublic:\n\texplicit HandlerBase(LanguageServer& _server): m_server{_server} {}\n\n\tJson toRange(langutil::SourceLocation const& _location) const;\n\tJson toJson(langutil::SourceLocation const& _location) const;\n\n\t/// @returns source unit name and the line column position as extracted\n\t/// from the JSON-RPC parameters.\n\tstd::pair<std::string, langutil::LineColumn> extractSourceUnitNameAndLineColumn(Json const& _params) const;\n\n\tlangutil::CharStreamProvider const& charStreamProvider() const noexcept { return m_server.compilerStack(); }\n\tFileRepository& fileRepository() const noexcept { return m_server.fileRepository(); }\n\tTransport& client() const noexcept { return m_server.client(); }\n\nprotected:\n\tLanguageServer& m_server;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/lsp/LanguageServer.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTUtils.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolidity/interface/ReadFile.h>\n#include <libsolidity/interface/StandardCompiler.h>\n#include <libsolidity/lsp/LanguageServer.h>\n#include <libsolidity/lsp/HandlerBase.h>\n#include <libsolidity/lsp/Utils.h>\n\n// LSP feature implementations\n#include <libsolidity/lsp/DocumentHoverHandler.h>\n#include <libsolidity/lsp/GotoDefinition.h>\n#include <libsolidity/lsp/RenameSymbol.h>\n#include <libsolidity/lsp/SemanticTokensBuilder.h>\n\n#include <liblangutil/SourceReferenceExtractor.h>\n#include <liblangutil/CharStream.h>\n\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/Visitor.h>\n#include <libsolutil/JSON.h>\n\n#include <boost/exception/diagnostic_information.hpp>\n#include <boost/filesystem.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n\n#include <ostream>\n#include <string>\n\n#include <fmt/format.h>\n\nusing namespace std::string_literals;\nusing namespace std::placeholders;\n\nusing namespace solidity::lsp;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity;\n\nnamespace fs = boost::filesystem;\n\nnamespace\n{\n\nbool resolvesToRegularFile(boost::filesystem::path _path, int maxRecursionDepth = 10)\n{\n\tfs::file_status fileStatus = fs::status(_path);\n\n\twhile (fileStatus.type() == fs::file_type::symlink_file && maxRecursionDepth > 0)\n\t{\n\t\t_path = boost::filesystem::read_symlink(_path);\n\t\tfileStatus = fs::status(_path);\n\t\tmaxRecursionDepth--;\n\t}\n\n\treturn fileStatus.type() == fs::file_type::regular_file;\n}\n\nint toDiagnosticSeverity(Error::Type _errorType)\n{\n\t// 1=Error, 2=Warning, 3=Info, 4=Hint\n\tswitch (Error::errorSeverity(_errorType))\n\t{\n\tcase Error::Severity::Error: return 1;\n\tcase Error::Severity::Warning: return 2;\n\tcase Error::Severity::Info: return 3;\n\t}\n\tsolAssert(false);\n\treturn -1;\n}\n\nJson semanticTokensLegend()\n{\n\tJson legend;\n\n\t// NOTE! The (alphabetical) order and items must match exactly the items of\n\t//       their respective enum class members.\n\n\tJson tokenTypes = Json::array();\n\ttokenTypes.emplace_back(\"class\");\n\ttokenTypes.emplace_back(\"comment\");\n\ttokenTypes.emplace_back(\"enum\");\n\ttokenTypes.emplace_back(\"enumMember\");\n\ttokenTypes.emplace_back(\"event\");\n\ttokenTypes.emplace_back(\"function\");\n\ttokenTypes.emplace_back(\"interface\");\n\ttokenTypes.emplace_back(\"keyword\");\n\ttokenTypes.emplace_back(\"macro\");\n\ttokenTypes.emplace_back(\"method\");\n\ttokenTypes.emplace_back(\"modifier\");\n\ttokenTypes.emplace_back(\"number\");\n\ttokenTypes.emplace_back(\"operator\");\n\ttokenTypes.emplace_back(\"parameter\");\n\ttokenTypes.emplace_back(\"property\");\n\ttokenTypes.emplace_back(\"std::string\");\n\ttokenTypes.emplace_back(\"struct\");\n\ttokenTypes.emplace_back(\"type\");\n\ttokenTypes.emplace_back(\"typeParameter\");\n\ttokenTypes.emplace_back(\"variable\");\n\tlegend[\"tokenTypes\"] = tokenTypes;\n\n\tJson tokenModifiers = Json::array();\n\ttokenModifiers.emplace_back(\"abstract\");\n\ttokenModifiers.emplace_back(\"declaration\");\n\ttokenModifiers.emplace_back(\"definition\");\n\ttokenModifiers.emplace_back(\"deprecated\");\n\ttokenModifiers.emplace_back(\"documentation\");\n\ttokenModifiers.emplace_back(\"modification\");\n\ttokenModifiers.emplace_back(\"readonly\");\n\tlegend[\"tokenModifiers\"] = tokenModifiers;\n\n\treturn legend;\n}\n\n}\n\nLanguageServer::LanguageServer(Transport& _transport):\n\tm_client{_transport},\n\tm_handlers{\n\t\t{\"$/cancelRequest\", [](auto, auto) {/*nothing for now as we are synchronous */}},\n\t\t{\"cancelRequest\", [](auto, auto) {/*nothing for now as we are synchronous */}},\n\t\t{\"exit\", [this](auto, auto) { m_state = (m_state == State::ShutdownRequested ? State::ExitRequested : State::ExitWithoutShutdown); }},\n\t\t{\"initialize\", std::bind(&LanguageServer::handleInitialize, this, _1, _2)},\n\t\t{\"initialized\", std::bind(&LanguageServer::handleInitialized, this, _1, _2)},\n\t\t{\"$/setTrace\", [this](auto, Json const& args) { setTrace(args[\"value\"]); }},\n\t\t{\"shutdown\", [this](auto, auto) { m_state = State::ShutdownRequested; }},\n\t\t{\"textDocument/definition\", GotoDefinition(*this) },\n\t\t{\"textDocument/didOpen\", std::bind(&LanguageServer::handleTextDocumentDidOpen, this, _2)},\n\t\t{\"textDocument/didChange\", std::bind(&LanguageServer::handleTextDocumentDidChange, this, _2)},\n\t\t{\"textDocument/didClose\", std::bind(&LanguageServer::handleTextDocumentDidClose, this, _2)},\n\t\t{\"textDocument/hover\", DocumentHoverHandler(*this) },\n\t\t{\"textDocument/rename\", RenameSymbol(*this) },\n\t\t{\"textDocument/implementation\", GotoDefinition(*this) },\n\t\t{\"textDocument/semanticTokens/full\", std::bind(&LanguageServer::semanticTokensFull, this, _1, _2)},\n\t\t{\"workspace/didChangeConfiguration\", std::bind(&LanguageServer::handleWorkspaceDidChangeConfiguration, this, _2)},\n\t},\n\tm_fileRepository(\"/\" /* basePath */, {} /* no search paths */),\n\tm_compilerStack{m_fileRepository.reader()}\n{\n}\n\nJson LanguageServer::toRange(SourceLocation const& _location)\n{\n\treturn HandlerBase(*this).toRange(_location);\n}\n\nJson LanguageServer::toJson(SourceLocation const& _location)\n{\n\treturn HandlerBase(*this).toJson(_location);\n}\n\nvoid LanguageServer::changeConfiguration(Json const& _settings)\n{\n\t// The settings item: \"file-load-strategy\" (enum) defaults to \"project-directory\" if not (or not correctly) set.\n\t// It can be overridden during client's handshake or at runtime, as usual.\n\t//\n\t// If this value is set to \"project-directory\" (default), all .sol files located inside the project directory or reachable through symbolic links will be subject to operations.\n\t//\n\t// Operations include compiler analysis, but also finding all symbolic references or symbolic renaming.\n\t//\n\t// If this value is set to \"directly-opened-and-on-import\", then only currently directly opened files and\n\t// those files being imported directly or indirectly will be included in operations.\n\tif (_settings.contains(\"file-load-strategy\"))\n\t{\n\t\tauto const text = _settings[\"file-load-strategy\"].get<std::string>();\n\t\tif (text == \"project-directory\")\n\t\t\tm_fileLoadStrategy = FileLoadStrategy::ProjectDirectory;\n\t\telse if (text == \"directly-opened-and-on-import\")\n\t\t\tm_fileLoadStrategy = FileLoadStrategy::DirectlyOpenedAndOnImported;\n\t\telse\n\t\t\tlspRequire(false, ErrorCode::InvalidParams, \"Invalid file load strategy: \" + text);\n\t}\n\n\tm_settingsObject = _settings;\n\tJson jsonIncludePaths = _settings.contains(\"include-paths\") ? _settings[\"include-paths\"] : Json::object();\n\n\tif (!jsonIncludePaths.empty())\n\t{\n\t\tint typeFailureCount = 0;\n\t\tif (jsonIncludePaths.is_array())\n\t\t{\n\t\t\tstd::vector<boost::filesystem::path> includePaths;\n\t\t\tfor (Json const& jsonPath: jsonIncludePaths)\n\t\t\t{\n\t\t\t\tif (jsonPath.is_string())\n\t\t\t\t\tincludePaths.emplace_back(jsonPath.get<std::string>());\n\t\t\t\telse\n\t\t\t\t\ttypeFailureCount++;\n\t\t\t}\n\t\t\tm_fileRepository.setIncludePaths(std::move(includePaths));\n\t\t}\n\t\telse\n\t\t\t++typeFailureCount;\n\n\t\tif (typeFailureCount)\n\t\t\tm_client.trace(\"Invalid JSON configuration passed. \\\"include-paths\\\" must be an array of strings.\");\n\t}\n}\n\nstd::vector<boost::filesystem::path> LanguageServer::allSolidityFilesFromProject() const\n{\n\tstd::vector<fs::path> collectedPaths{};\n\n\t// We explicitly decided against including all files from include paths but leave the possibility\n\t// open for a future PR to enable such a feature to be optionally enabled (default disabled).\n\t// Note: Newer versions of boost have deprecated symlink_option::recurse\n#if (BOOST_VERSION < 107200)\n\tauto directoryIterator = fs::recursive_directory_iterator(m_fileRepository.basePath(), fs::symlink_option::recurse);\n#else\n\tauto directoryIterator = fs::recursive_directory_iterator(m_fileRepository.basePath(), fs::directory_options::follow_directory_symlink);\n#endif\n\tfor (fs::directory_entry const& dirEntry: directoryIterator)\n\t\tif (\n\t\t\tdirEntry.path().extension() == \".sol\" &&\n\t\t\t(dirEntry.status().type() == fs::file_type::regular_file || resolvesToRegularFile(dirEntry.path()))\n\t\t)\n\t\t\tcollectedPaths.push_back(dirEntry.path());\n\n\treturn collectedPaths;\n}\n\nvoid LanguageServer::compile()\n{\n\t// For files that are not open, we have to take changes on disk into account,\n\t// so we just remove all non-open files.\n\n\tFileRepository oldRepository(m_fileRepository.basePath(), m_fileRepository.includePaths());\n\tstd::swap(oldRepository, m_fileRepository);\n\n\t// Load all solidity files from project.\n\tif (m_fileLoadStrategy == FileLoadStrategy::ProjectDirectory)\n\t\tfor (auto const& projectFile: allSolidityFilesFromProject())\n\t\t{\n\t\t\tlspDebug(fmt::format(\"adding project file: {}\", projectFile.generic_string()));\n\t\t\tm_fileRepository.setSourceByUri(\n\t\t\t\tm_fileRepository.sourceUnitNameToUri(projectFile.generic_string()),\n\t\t\t\tutil::readFileAsString(projectFile)\n\t\t\t);\n\t\t}\n\n\t// Overwrite all files as opened by the client, including the ones which might potentially have changes.\n\tfor (std::string const& fileName: m_openFiles)\n\t\tm_fileRepository.setSourceByUri(\n\t\t\tfileName,\n\t\t\toldRepository.sourceUnits().at(oldRepository.uriToSourceUnitName(fileName))\n\t\t);\n\n\t// TODO: optimize! do not recompile if nothing has changed (file(s) not flagged dirty).\n\n\tm_compilerStack.reset(false);\n\tm_compilerStack.setSources(m_fileRepository.sourceUnits());\n\tm_compilerStack.compile(CompilerStack::State::AnalysisSuccessful);\n}\n\nvoid LanguageServer::compileAndUpdateDiagnostics()\n{\n\tcompile();\n\n\t// These are the source units we will sent diagnostics to the client for sure,\n\t// even if it is just to clear previous diagnostics.\n\tstd::map<std::string, Json> diagnosticsBySourceUnit;\n\tfor (std::string const& sourceUnitName: m_fileRepository.sourceUnits() | ranges::views::keys)\n\t\tdiagnosticsBySourceUnit[sourceUnitName] = Json::array();\n\tfor (std::string const& sourceUnitName: m_nonemptyDiagnostics)\n\t\tdiagnosticsBySourceUnit[sourceUnitName] = Json::array();\n\n\tfor (std::shared_ptr<Error const> const& error: m_compilerStack.errors())\n\t{\n\t\tSourceLocation const* location = error->sourceLocation();\n\t\tif (!location || !location->sourceName)\n\t\t\t// LSP only has diagnostics applied to individual files.\n\t\t\tcontinue;\n\n\t\tJson jsonDiag;\n\t\tjsonDiag[\"source\"] = \"solc\";\n\t\tjsonDiag[\"severity\"] = toDiagnosticSeverity(error->type());\n\t\tjsonDiag[\"code\"] = Json(error->errorId().error);\n\t\tstd::string message = Error::formatErrorType(error->type()) + \":\";\n\t\tif (std::string const* comment = error->comment())\n\t\t\tmessage += \" \" + *comment;\n\t\tjsonDiag[\"message\"] = std::move(message);\n\t\tjsonDiag[\"range\"] = toRange(*location);\n\n\t\tif (auto const* secondary = error->secondarySourceLocation())\n\t\t\tfor (auto&& [secondaryMessage, secondaryLocation]: secondary->infos)\n\t\t\t{\n\t\t\t\tJson jsonRelated;\n\t\t\t\tjsonRelated[\"message\"] = secondaryMessage;\n\t\t\t\tjsonRelated[\"location\"] = toJson(secondaryLocation);\n\t\t\t\tjsonDiag[\"relatedInformation\"].emplace_back(jsonRelated);\n\t\t\t}\n\n\t\tdiagnosticsBySourceUnit[*location->sourceName].emplace_back(jsonDiag);\n\t}\n\n\tif (m_client.traceValue() != TraceValue::Off)\n\t{\n\t\tJson extra;\n\t\textra[\"openFileCount\"] = Json(diagnosticsBySourceUnit.size());\n\t\tm_client.trace(\"Number of currently open files: \" + std::to_string(diagnosticsBySourceUnit.size()), extra);\n\t}\n\n\tm_nonemptyDiagnostics.clear();\n\tfor (auto&& [sourceUnitName, diagnostics]: diagnosticsBySourceUnit)\n\t{\n\t\tJson params;\n\t\tparams[\"uri\"] = m_fileRepository.sourceUnitNameToUri(sourceUnitName);\n\t\tif (!diagnostics.empty())\n\t\t\tm_nonemptyDiagnostics.insert(sourceUnitName);\n\t\tparams[\"diagnostics\"] = std::move(diagnostics);\n\t\tm_client.notify(\"textDocument/publishDiagnostics\", std::move(params));\n\t}\n}\n\nbool LanguageServer::run()\n{\n\twhile (m_state != State::ExitRequested && m_state != State::ExitWithoutShutdown && !m_client.closed())\n\t{\n\t\tMessageID id;\n\t\ttry\n\t\t{\n\t\t\tstd::optional<Json> const jsonMessage = m_client.receive();\n\t\t\tif (!jsonMessage)\n\t\t\t\tcontinue;\n\n\t\t\tif ((*jsonMessage).contains(\"method\") && (*jsonMessage)[\"method\"].is_string())\n\t\t\t{\n\t\t\t\tstd::string const methodName = (*jsonMessage)[\"method\"].get<std::string>();\n\t\t\t\tif ((*jsonMessage).contains(\"id\"))\n\t\t\t\t\tid = (*jsonMessage)[\"id\"];\n\t\t\t\tlspDebug(fmt::format(\"received method call: {}\", methodName));\n\n\t\t\t\tif (auto handler = util::valueOrDefault(m_handlers, methodName))\n\t\t\t\t\thandler(id, (*jsonMessage)[\"params\"]);\n\t\t\t\telse\n\t\t\t\t\tm_client.error(id, ErrorCode::MethodNotFound, \"Unknown method \" + methodName);\n\t\t\t}\n\t\t\telse\n\t\t\t\tm_client.error({}, ErrorCode::ParseError, \"\\\"method\\\" has to be a string.\");\n\t\t}\n\t\tcatch (Json::exception const&)\n\t\t{\n\t\t\tm_client.error(id, ErrorCode::InvalidParams, \"JSON object access error. Most likely due to a badly formatted JSON request message.\"s);\n\t\t}\n\t\tcatch (RequestError const& error)\n\t\t{\n\t\t\tm_client.error(id, error.code(), error.comment() ? *error.comment() : \"\"s);\n\t\t}\n\t\tcatch (...)\n\t\t{\n\t\t\tm_client.error(id, ErrorCode::InternalError, \"Unhandled exception: \"s + boost::current_exception_diagnostic_information());\n\t\t}\n\t}\n\treturn m_state == State::ExitRequested;\n}\n\nvoid LanguageServer::requireServerInitialized()\n{\n\tlspRequire(\n\t\tm_state == State::Initialized,\n\t\tErrorCode::ServerNotInitialized,\n\t\t\"Server is not properly initialized.\"\n\t);\n}\n\nvoid LanguageServer::handleInitialize(MessageID _id, Json const& _args)\n{\n\tlspRequire(\n\t\tm_state == State::Started,\n\t\tErrorCode::RequestFailed,\n\t\t\"Initialize called at the wrong time.\"\n\t);\n\n\tm_state = State::Initialized;\n\n\t// The default of FileReader is to use `.`, but the path from where the LSP was started\n\t// should not matter.\n\tstd::string rootPath(\"/\");\n\tif (_args.contains(\"rootUri\") && _args[\"rootUri\"].is_string())\n\t{\n\t\trootPath = _args[\"rootUri\"].get<std::string>();\n\t\tlspRequire(\n\t\t\tboost::starts_with(rootPath, \"file://\"),\n\t\t\tErrorCode::InvalidParams,\n\t\t\t\"rootUri only supports file URI scheme.\"\n\t\t);\n\t\trootPath = stripFileUriSchemePrefix(rootPath);\n\t}\n\telse if (_args.contains(\"rootPath\"))\n\t\trootPath = _args[\"rootPath\"].get<std::string>();\n\n\tif (_args.contains(\"trace\"))\n\t\tsetTrace(_args[\"trace\"]);\n\n\tm_fileRepository = FileRepository(rootPath, {});\n\tif (_args.contains(\"initializationOptions\") && _args[\"initializationOptions\"].is_object())\n\t\tchangeConfiguration(_args[\"initializationOptions\"]);\n\n\tJson replyArgs;\n\treplyArgs[\"serverInfo\"][\"name\"] = \"solc\";\n\treplyArgs[\"serverInfo\"][\"version\"] = std::string(VersionNumber);\n\treplyArgs[\"capabilities\"][\"definitionProvider\"] = true;\n\treplyArgs[\"capabilities\"][\"implementationProvider\"] = true;\n\treplyArgs[\"capabilities\"][\"textDocumentSync\"][\"change\"] = 2; // 0=none, 1=full, 2=incremental\n\treplyArgs[\"capabilities\"][\"textDocumentSync\"][\"openClose\"] = true;\n\treplyArgs[\"capabilities\"][\"semanticTokensProvider\"][\"legend\"] = semanticTokensLegend();\n\treplyArgs[\"capabilities\"][\"semanticTokensProvider\"][\"range\"] = false;\n\treplyArgs[\"capabilities\"][\"semanticTokensProvider\"][\"full\"] = true; // XOR requests.full.delta = true\n\treplyArgs[\"capabilities\"][\"renameProvider\"] = true;\n\treplyArgs[\"capabilities\"][\"hoverProvider\"] = true;\n\n\tm_client.reply(_id, std::move(replyArgs));\n}\n\nvoid LanguageServer::handleInitialized(MessageID, Json const&)\n{\n\tif (m_fileLoadStrategy == FileLoadStrategy::ProjectDirectory)\n\t\tcompileAndUpdateDiagnostics();\n}\n\nvoid LanguageServer::semanticTokensFull(MessageID _id, Json const& _args)\n{\n\tif (_args.contains(\"textDocument\") && _args[\"textDocument\"].contains(\"uri\"))\n\t{\n\t\tauto uri = _args[\"textDocument\"][\"uri\"];\n\n\t\tcompile();\n\n\t\tauto const sourceName = m_fileRepository.uriToSourceUnitName(uri.get<std::string>());\n\t\tSourceUnit const& ast = m_compilerStack.ast(sourceName);\n\t\tm_compilerStack.charStream(sourceName);\n\t\tJson data = SemanticTokensBuilder().build(ast, m_compilerStack.charStream(sourceName));\n\n\t\tJson reply;\n\t\treply[\"data\"] = data;\n\n\t\tm_client.reply(_id, std::move(reply));\n\t}\n\telse\n\t\tm_client.error(_id, ErrorCode::InvalidParams, \"Invalid parameter: textDocument.uri expected.\");\n}\n\nvoid LanguageServer::handleWorkspaceDidChangeConfiguration(Json const& _args)\n{\n\trequireServerInitialized();\n\n\tif (_args.contains(\"settings\") && _args[\"settings\"].is_object())\n\t\tchangeConfiguration(_args[\"settings\"]);\n}\n\nvoid LanguageServer::setTrace(Json const& _args)\n{\n\tif (!_args.is_string())\n\t\t// Simply ignore invalid parameter.\n\t\treturn;\n\n\tstd::string const stringValue = _args.get<std::string>();\n\tif (stringValue == \"off\")\n\t\tm_client.setTrace(TraceValue::Off);\n\telse if (stringValue == \"messages\")\n\t\tm_client.setTrace(TraceValue::Messages);\n\telse if (stringValue == \"verbose\")\n\t\tm_client.setTrace(TraceValue::Verbose);\n}\n\nvoid LanguageServer::handleTextDocumentDidOpen(Json const& _args)\n{\n\trequireServerInitialized();\n\n\tlspRequire(\n\t\t_args.contains(\"textDocument\"),\n\t\tErrorCode::RequestFailed,\n\t\t\"Text document parameter missing.\"\n\t);\n\n\tif (_args[\"textDocument\"].contains(\"text\") && _args[\"textDocument\"].contains(\"uri\"))\n\t{\n\t\tstd::string text = _args[\"textDocument\"][\"text\"].get<std::string>();\n\t\tstd::string uri = _args[\"textDocument\"][\"uri\"].get<std::string>();\n\t\tm_openFiles.insert(uri);\n\t\tm_fileRepository.setSourceByUri(uri, std::move(text));\n\t\tcompileAndUpdateDiagnostics();\n\t}\n}\n\nvoid LanguageServer::handleTextDocumentDidChange(Json const& _args)\n{\n\trequireServerInitialized();\n\n\tif (_args.contains(\"textDocument\") && _args[\"textDocument\"].contains(\"uri\"))\n\t{\n\t\tstd::string const uri = _args[\"textDocument\"][\"uri\"].get<std::string>();\n\n\t\tif (_args.contains(\"contentChanges\"))\n\t\t\tfor (auto const& [_, jsonContentChange]: _args[\"contentChanges\"].items())\n\t\t\t{\n\t\t\t\tlspRequire(jsonContentChange.is_object(), ErrorCode::RequestFailed, \"Invalid content reference.\");\n\n\t\t\t\tstd::string const sourceUnitName = m_fileRepository.uriToSourceUnitName(uri);\n\t\t\t\tlspRequire(\n\t\t\t\t\tm_fileRepository.sourceUnits().count(sourceUnitName),\n\t\t\t\t\tErrorCode::RequestFailed,\n\t\t\t\t\t\"Unknown file: \" + uri);\n\n\t\t\t\tif (jsonContentChange.contains(\"text\"))\n\t\t\t\t{\n\t\t\t\t\tstd::string text = jsonContentChange[\"text\"].get<std::string>();\n\t\t\t\t\tif (jsonContentChange.contains(\"range\")\n\t\t\t\t\t\t&& jsonContentChange[\"range\"].is_object()) // otherwise full content update\n\t\t\t\t\t{\n\t\t\t\t\t\tstd::optional<SourceLocation> change\n\t\t\t\t\t\t\t= parseRange(m_fileRepository, sourceUnitName, jsonContentChange[\"range\"]);\n\t\t\t\t\t\tlspRequire(\n\t\t\t\t\t\t\tchange && change->hasText(),\n\t\t\t\t\t\t\tErrorCode::RequestFailed,\n\t\t\t\t\t\t\t\"Invalid source range: \" + util::jsonCompactPrint(jsonContentChange[\"range\"]));\n\n\t\t\t\t\t\tstd::string buffer = m_fileRepository.sourceUnits().at(sourceUnitName);\n\t\t\t\t\t\tbuffer.replace(\n\t\t\t\t\t\t\tstatic_cast<size_t>(change->start),\n\t\t\t\t\t\t\tstatic_cast<size_t>(change->end - change->start),\n\t\t\t\t\t\t\tstd::move(text));\n\t\t\t\t\t\ttext = std::move(buffer);\n\t\t\t\t\t}\n\t\t\t\t\tm_fileRepository.setSourceByUri(uri, std::move(text));\n\t\t\t\t}\n\t\t\t}\n\n\t\tcompileAndUpdateDiagnostics();\n\t}\n}\n\nvoid LanguageServer::handleTextDocumentDidClose(Json const& _args)\n{\n\trequireServerInitialized();\n\n\tlspRequire(\n\t\t_args.contains(\"textDocument\"),\n\t\tErrorCode::RequestFailed,\n\t\t\"Text document parameter missing.\"\n\t);\n\n\tif (_args[\"textDocument\"].contains(\"uri\"))\n\t{\n\t\tstd::string uri = _args[\"textDocument\"][\"uri\"].get<std::string>();\n\t\tm_openFiles.erase(uri);\n\n\t\tcompileAndUpdateDiagnostics();\n\t}\n}\n\nASTNode const* LanguageServer::astNodeAtSourceLocation(std::string const& _sourceUnitName, LineColumn const& _filePos)\n{\n\treturn std::get<ASTNode const*>(astNodeAndOffsetAtSourceLocation(_sourceUnitName, _filePos));\n}\n\nstd::tuple<ASTNode const*, int> LanguageServer::astNodeAndOffsetAtSourceLocation(std::string const& _sourceUnitName, LineColumn const& _filePos)\n{\n\tif (m_compilerStack.state() < CompilerStack::AnalysisSuccessful)\n\t\treturn {nullptr, -1};\n\tif (!m_fileRepository.sourceUnits().count(_sourceUnitName))\n\t\treturn {nullptr, -1};\n\n\tstd::optional<int> sourcePos = m_compilerStack.charStream(_sourceUnitName).translateLineColumnToPosition(_filePos);\n\tif (!sourcePos)\n\t\treturn {nullptr, -1};\n\n\treturn {locateInnermostASTNode(*sourcePos, m_compilerStack.ast(_sourceUnitName)), *sourcePos};\n}\n"
  },
  {
    "path": "libsolidity/lsp/LanguageServer.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolidity/lsp/Transport.h>\n#include <libsolidity/lsp/FileRepository.h>\n#include <libsolidity/interface/CompilerStack.h>\n#include <libsolidity/interface/FileReader.h>\n\n#include <libsolutil/JSON.h>\n\n#include <functional>\n#include <map>\n#include <optional>\n#include <string>\n#include <vector>\n\nnamespace solidity::lsp\n{\n\nclass RenameSymbol;\nenum class ErrorCode;\n\n/**\n * Enum to mandate what files to take into consideration for source code analysis.\n */\nenum class FileLoadStrategy\n{\n\t/// Takes only those files into consideration that are explicitly opened and those\n\t/// that have been directly or indirectly imported.\n\tDirectlyOpenedAndOnImported = 0,\n\n\t/// Takes all Solidity (.sol) files within the project root into account.\n\t/// Symbolic links will be followed, even if they lead outside of the project directory\n\t/// (`--allowed-paths` is currently ignored by the LSP).\n\t///\n\t/// This resembles the closest what other LSPs should be doing already.\n\tProjectDirectory = 1,\n};\n\n/**\n * Solidity Language Server, managing one LSP client.\n * This implements a subset of LSP version 3.16 that can be found at:\n * https://microsoft.github.io/language-server-protocol/specifications/specification-3-16/\n */\nclass LanguageServer\n{\npublic:\n\t/// @param _transport Customizable transport layer.\n\texplicit LanguageServer(Transport& _transport);\n\n\t/// Re-compiles the project and updates the diagnostics pushed to the client.\n\tvoid compileAndUpdateDiagnostics();\n\n\t/// Loops over incoming messages via the transport layer until shutdown condition is met.\n\t///\n\t/// The standard shutdown condition is when the maximum number of consecutive failures\n\t/// has been exceeded.\n\t///\n\t/// @return boolean indicating normal or abnormal termination.\n\tbool run();\n\n\tFileRepository& fileRepository() noexcept { return m_fileRepository; }\n\tTransport& client() noexcept { return m_client; }\n\tstd::tuple<frontend::ASTNode const*, int> astNodeAndOffsetAtSourceLocation(std::string const& _sourceUnitName, langutil::LineColumn const& _filePos);\n\tfrontend::ASTNode const* astNodeAtSourceLocation(std::string const& _sourceUnitName, langutil::LineColumn const& _filePos);\n\tfrontend::CompilerStack const& compilerStack() const noexcept { return m_compilerStack; }\n\nprivate:\n\t/// Checks if the server is initialized (to be used by messages that need it to be initialized).\n\t/// Reports an error and returns false if not.\n\tvoid requireServerInitialized();\n\tvoid handleInitialize(MessageID _id, Json const& _args);\n\tvoid handleInitialized(MessageID _id, Json const& _args);\n\tvoid handleWorkspaceDidChangeConfiguration(Json const& _args);\n\tvoid setTrace(Json const& _args);\n\tvoid handleTextDocumentDidOpen(Json const& _args);\n\tvoid handleTextDocumentDidChange(Json const& _args);\n\tvoid handleTextDocumentDidClose(Json const& _args);\n\tvoid handleRename(Json const& _args);\n\tvoid handleGotoDefinition(MessageID _id, Json const& _args);\n\tvoid semanticTokensFull(MessageID _id, Json const& _args);\n\n\t/// Invoked when the server user-supplied configuration changes (initiated by the client).\n\tvoid changeConfiguration(Json const&);\n\n\t/// Compile everything until after analysis phase.\n\tvoid compile();\n\n\tstd::vector<boost::filesystem::path> allSolidityFilesFromProject() const;\n\n\tusing MessageHandler = std::function<void(MessageID, Json const&)>;\n\n\tJson toRange(langutil::SourceLocation const& _location);\n\tJson toJson(langutil::SourceLocation const& _location);\n\n\t// LSP related member fields\n\n\tenum class State { Started, Initialized, ShutdownRequested, ExitRequested, ExitWithoutShutdown };\n\tState m_state = State::Started;\n\n\tTransport& m_client;\n\tstd::map<std::string, MessageHandler> m_handlers;\n\n\t/// Set of files (names in URI form) known to be open by the client.\n\tstd::set<std::string> m_openFiles;\n\t/// Set of source unit names for which we sent diagnostics to the client in the last iteration.\n\tstd::set<std::string> m_nonemptyDiagnostics;\n\tFileRepository m_fileRepository;\n\tFileLoadStrategy m_fileLoadStrategy = FileLoadStrategy::ProjectDirectory;\n\n\tfrontend::CompilerStack m_compilerStack;\n\n\t/// User-supplied custom configuration settings (such as EVM version).\n\tJson m_settingsObject;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/lsp/RenameSymbol.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/lsp/RenameSymbol.h>\n#include <libsolidity/lsp/Utils.h>\n\n#include <libyul/AST.h>\n\n#include <fmt/format.h>\n\n#include <memory>\n#include <string>\n#include <vector>\n\nusing namespace solidity::frontend;\nusing namespace solidity::langutil;\nusing namespace solidity::lsp;\n\nnamespace\n{\n\nCallableDeclaration const* extractCallableDeclaration(FunctionCall const& _functionCall)\n{\n\tif (\n\t\tauto const* functionType = dynamic_cast<FunctionType const*>(_functionCall.expression().annotation().type);\n\t\tfunctionType && functionType->hasDeclaration()\n\t)\n\t\tif (auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(&functionType->declaration()))\n\t\t\treturn functionDefinition;\n\n\treturn nullptr;\n}\n\n}\n\nvoid RenameSymbol::operator()(MessageID _id, Json const& _args)\n{\n\tauto const&& [sourceUnitName, lineColumn] = extractSourceUnitNameAndLineColumn(_args);\n\tstd::string const newName = _args[\"newName\"].get<std::string>();\n\tstd::string const uri = _args[\"textDocument\"][\"uri\"].get<std::string>();\n\n\tASTNode const* sourceNode = m_server.astNodeAtSourceLocation(sourceUnitName, lineColumn);\n\n\tm_symbolName = {};\n\tm_declarationToRename = nullptr;\n\tm_sourceUnits = { &m_server.compilerStack().ast(sourceUnitName) };\n\tm_locations.clear();\n\n\tstd::optional<int> cursorBytePosition = charStreamProvider()\n\t\t.charStream(sourceUnitName)\n\t\t.translateLineColumnToPosition(lineColumn);\n\tsolAssert(cursorBytePosition.has_value(), \"Expected source pos\");\n\n\tif (sourceNode != nullptr)\n\t\textractNameAndDeclaration(*sourceNode, *cursorBytePosition);\n\n\t// Find all source units using this symbol\n\tfor (auto const& [name, content]: fileRepository().sourceUnits())\n\t{\n\t\tauto const& sourceUnit = m_server.compilerStack().ast(name);\n\t\tfor (auto const* referencedSourceUnit: sourceUnit.referencedSourceUnits(true, util::convertContainer<std::set<SourceUnit const*>>(m_sourceUnits)))\n\t\t\tif (*referencedSourceUnit->location().sourceName == sourceUnitName)\n\t\t\t{\n\t\t\t\tm_sourceUnits.insert(&sourceUnit);\n\t\t\t\tbreak;\n\t\t\t}\n\t}\n\n\t// Origin source unit should always be checked\n\tm_sourceUnits.insert(&m_declarationToRename->sourceUnit());\n\n\tVisitor visitor(*this);\n\n\tfor (auto const* sourceUnit: m_sourceUnits)\n\t\tsourceUnit->accept(visitor);\n\n\t// Apply changes in reverse order (will iterate in reverse)\n\tsort(m_locations.begin(), m_locations.end());\n\n\tJson reply;\n\treply[\"changes\"] = Json::object();\n\n\tJson edits = Json::array();\n\n\tfor (auto i = m_locations.rbegin(); i != m_locations.rend(); i++)\n\t{\n\t\tsolAssert(i->isValid());\n\n\t\t// Replace in our file repository\n\t\tstd::string const uri = fileRepository().sourceUnitNameToUri(*i->sourceName);\n\t\tstd::string buffer = fileRepository().sourceUnits().at(*i->sourceName);\n\t\tbuffer.replace((size_t)i->start, (size_t)(i->end - i->start), newName);\n\t\tfileRepository().setSourceByUri(uri, std::move(buffer));\n\n\t\tJson edit;\n\t\tedit[\"range\"] = toRange(*i);\n\t\tedit[\"newText\"] = newName;\n\n\t\t// Record changes for the client\n\t\tedits.emplace_back(edit);\n\t\tif (i + 1 == m_locations.rend() || (i + 1)->sourceName != i->sourceName)\n\t\t{\n\t\t\treply[\"changes\"][uri] = edits;\n\t\t\tedits = Json::array(); // Reset.\n\t\t}\n\t}\n\n\tclient().reply(_id, reply);\n}\n\nvoid RenameSymbol::extractNameAndDeclaration(ASTNode const& _node, int _cursorBytePosition)\n{\n\t// Identify symbol name and node\n\tif (auto const* declaration = dynamic_cast<Declaration const*>(&_node))\n\t{\n\t\tif (declaration->nameLocation().containsOffset(_cursorBytePosition))\n\t\t{\n\t\t\tm_symbolName = declaration->name();\n\t\t\tm_declarationToRename = declaration;\n\t\t}\n\t\telse if (auto const* importDirective = dynamic_cast<ImportDirective const*>(declaration))\n\t\t\textractNameAndDeclaration(*importDirective, _cursorBytePosition);\n\t}\n\telse if (auto const* identifier = dynamic_cast<Identifier const*>(&_node))\n\t{\n\t\tif (auto const* declReference = dynamic_cast<Declaration const*>(identifier->annotation().referencedDeclaration))\n\t\t{\n\t\t\tm_symbolName = identifier->name();\n\t\t\tm_declarationToRename = declReference;\n\t\t}\n\t}\n\telse if (auto const* identifierPath = dynamic_cast<IdentifierPath const*>(&_node))\n\t\textractNameAndDeclaration(*identifierPath, _cursorBytePosition);\n\telse if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(&_node))\n\t{\n\t\tm_symbolName = memberAccess->memberName();\n\t\tm_declarationToRename = memberAccess->annotation().referencedDeclaration;\n\t}\n\telse if (auto const* functionCall = dynamic_cast<FunctionCall const*>(&_node))\n\t\textractNameAndDeclaration(*functionCall, _cursorBytePosition);\n\telse if (auto const* inlineAssembly = dynamic_cast<InlineAssembly const*>(&_node))\n\t\textractNameAndDeclaration(*inlineAssembly, _cursorBytePosition);\n\telse\n\t\tsolAssert(false, \"Unexpected ASTNODE id: \" + std::to_string(_node.id()));\n\n\tif (m_declarationToRename != nullptr)\n\t\tlspDebug(fmt::format(\"Goal: rename '{}', loc: {}-{}\", m_symbolName, m_declarationToRename->nameLocation().start, m_declarationToRename->nameLocation().end));\n}\n\nvoid RenameSymbol::extractNameAndDeclaration(ImportDirective const& _importDirective, int _cursorBytePosition)\n{\n\tfor (ImportDirective::SymbolAlias const& symbolAlias: _importDirective.symbolAliases())\n\t\tif (symbolAlias.location.containsOffset(_cursorBytePosition))\n\t\t{\n\t\t\tsolAssert(symbolAlias.alias);\n\t\t\tm_symbolName = *symbolAlias.alias;\n\t\t\tm_declarationToRename = symbolAlias.symbol->annotation().referencedDeclaration;\n\t\t\tbreak;\n\t\t}\n}\n\nvoid RenameSymbol::Visitor::endVisit(ImportDirective const& _node)\n{\n\t// Handles SourceUnit aliases\n\tif (handleGenericDeclaration(_node))\n\t\treturn;\n\n\tfor (ImportDirective::SymbolAlias const& symbolAlias: _node.symbolAliases())\n\t\tif (\n\t\t\tsymbolAlias.alias != nullptr &&\n\t\t\t*symbolAlias.alias == m_outer.m_symbolName &&\n\t\t\tsymbolAlias.symbol->annotation().referencedDeclaration == m_outer.m_declarationToRename\n\t\t)\n\t\t\tm_outer.m_locations.emplace_back(symbolAlias.location);\n}\n\nvoid RenameSymbol::extractNameAndDeclaration(FunctionCall const& _functionCall, int _cursorBytePosition)\n{\n\tif (auto const* functionDefinition = extractCallableDeclaration(_functionCall))\n\t\tfor (size_t i = 0; i < _functionCall.names().size(); i++)\n\t\t\tif (_functionCall.nameLocations()[i].containsOffset(_cursorBytePosition))\n\t\t\t{\n\t\t\t\tm_symbolName = *_functionCall.names()[i];\n\t\t\t\tfor (size_t j = 0; j < functionDefinition->parameters().size(); j++)\n\t\t\t\t\tif (\n\t\t\t\t\t\tfunctionDefinition->parameters()[j] &&\n\t\t\t\t\t\tfunctionDefinition->parameters()[j]->name() == m_symbolName\n\t\t\t\t\t)\n\t\t\t\t\t\tm_declarationToRename =  functionDefinition->parameters()[j].get();\n\t\t\t\treturn;\n\t\t\t}\n}\n\nvoid RenameSymbol::Visitor::endVisit(FunctionCall const& _node)\n{\n\tSourceLocation nameLocationInFunctionCall;\n\n\tfor (size_t i = 0; i < _node.names().size(); i++)\n\t\tif (_node.names()[i] && *_node.names()[i] == m_outer.m_symbolName)\n\t\t\tnameLocationInFunctionCall = _node.nameLocations()[i];\n\n\tif (!nameLocationInFunctionCall.isValid())\n\t\treturn;\n\n\tif (auto const* functionDefinition = extractCallableDeclaration(_node))\n\t\tfor (size_t j = 0; j < functionDefinition->parameters().size(); j++)\n\t\t\tif (\n\t\t\t\tfunctionDefinition->parameters()[j] &&\n\t\t\t\t*functionDefinition->parameters()[j] == *m_outer.m_declarationToRename\n\t\t\t)\n\t\t\t\tm_outer.m_locations.emplace_back(nameLocationInFunctionCall);\n}\n\nvoid RenameSymbol::Visitor::endVisit(MemberAccess const& _node)\n{\n\tif (\n\t\tm_outer.m_symbolName == _node.memberName() &&\n\t\t*m_outer.m_declarationToRename == *_node.annotation().referencedDeclaration\n\t)\n\t\tm_outer.m_locations.emplace_back(_node.memberLocation());\n}\n\nvoid RenameSymbol::Visitor::endVisit(Identifier const& _node)\n{\n\tif (\n\t\tm_outer.m_symbolName == _node.name() &&\n\t\t*m_outer.m_declarationToRename == *_node.annotation().referencedDeclaration\n\t)\n\t\tm_outer.m_locations.emplace_back(_node.location());\n}\n\nvoid RenameSymbol::extractNameAndDeclaration(IdentifierPath const& _identifierPath, int _cursorBytePosition)\n{\n\t// iterate through the elements of the path to find the one the cursor is on\n\tsize_t numIdentifiers = _identifierPath.pathLocations().size();\n\tfor (size_t i = 0; i < numIdentifiers; i++)\n\t{\n\t\tauto& location = _identifierPath.pathLocations()[i];\n\n\t\tif (location.containsOffset(_cursorBytePosition))\n\t\t{\n\t\t\tsolAssert(_identifierPath.annotation().pathDeclarations.size() == numIdentifiers);\n\t\t\tsolAssert(_identifierPath.path().size() == numIdentifiers);\n\n\t\t\tm_declarationToRename = _identifierPath.annotation().pathDeclarations[i];\n\t\t\tm_symbolName = _identifierPath.path()[i];\n\t\t}\n\t}\n}\n\nvoid RenameSymbol::Visitor::endVisit(IdentifierPath const& _node)\n{\n\tstd::vector<Declaration const*>& declarations = _node.annotation().pathDeclarations;\n\tsolAssert(declarations.size() == _node.path().size());\n\n\tfor (size_t i = 0; i < _node.path().size(); i++)\n\t\tif (\n\t\t\t_node.path()[i] == m_outer.m_symbolName &&\n\t\t\tdeclarations[i] == m_outer.m_declarationToRename\n\t\t)\n\t\t\tm_outer.m_locations.emplace_back(_node.pathLocations()[i]);\n}\n\nvoid RenameSymbol::extractNameAndDeclaration(InlineAssembly const& _inlineAssembly, int _cursorBytePosition)\n{\n\tfor (auto&& [identifier, externalReference]: _inlineAssembly.annotation().externalReferences)\n\t{\n\t\tSourceLocation location = yul::nativeLocationOf(*identifier);\n\t\tlocation.end -= static_cast<int>(externalReference.suffix.size() + 1);\n\n\t\tif (location.containsOffset(_cursorBytePosition))\n\t\t{\n\t\t\tm_declarationToRename = externalReference.declaration;\n\t\t\tm_symbolName = identifier->name.str();\n\n\t\t\tif (!externalReference.suffix.empty())\n\t\t\t\tm_symbolName = m_symbolName.substr(0, m_symbolName.length() - externalReference.suffix.size() - 1);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nvoid RenameSymbol::Visitor::endVisit(InlineAssembly const& _node)\n{\n\tfor (auto&& [identifier, externalReference]: _node.annotation().externalReferences)\n\t{\n\t\tstd::string identifierName = identifier->name.str();\n\t\tif (!externalReference.suffix.empty())\n\t\t\tidentifierName = identifierName.substr(0, identifierName.length() - externalReference.suffix.size() - 1);\n\n\t\tif (\n\t\t\texternalReference.declaration == m_outer.m_declarationToRename &&\n\t\t\tidentifierName == m_outer.m_symbolName\n\t\t)\n\t\t{\n\t\t\tSourceLocation location = yul::nativeLocationOf(*identifier);\n\t\t\tlocation.end -= static_cast<int>(externalReference.suffix.size() + 1);\n\n\t\t\tm_outer.m_locations.emplace_back(location);\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "libsolidity/lsp/RenameSymbol.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/lsp/HandlerBase.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTVisitor.h>\n\nnamespace solidity::lsp\n{\n\nclass RenameSymbol: public HandlerBase\n{\npublic:\n\texplicit RenameSymbol(LanguageServer& _server): HandlerBase(_server) {}\n\n\tvoid operator()(MessageID, Json const&);\nprotected:\n\t// Nested class because otherwise `RenameSymbol` couldn't be easily used\n\t// with LanguageServer::m_handlers as `ASTConstVisitor` deletes required\n\t// c'tors\n\tstruct Visitor: public frontend::ASTConstVisitor\n\t{\n\t\texplicit Visitor(RenameSymbol& _outer): m_outer(_outer) {}\n\t\tvoid endVisit(frontend::ImportDirective const& _node) override;\n\t\tvoid endVisit(frontend::MemberAccess const& _node) override;\n\t\tvoid endVisit(frontend::Identifier const& _node) override;\n\t\tvoid endVisit(frontend::IdentifierPath const& _node) override;\n\t\tvoid endVisit(frontend::FunctionCall const& _node) override;\n\t\tvoid endVisit(frontend::InlineAssembly const& _node) override;\n\n\t\tvoid endVisit(frontend::ContractDefinition const& _node) override\n\t\t{\n\t\t\thandleGenericDeclaration(_node);\n\t\t}\n\t\tvoid endVisit(frontend::StructDefinition const& _node) override\n\t\t{\n\t\t\thandleGenericDeclaration(_node);\n\t\t}\n\t\tvoid endVisit(frontend::EnumDefinition const& _node) override\n\t\t{\n\t\t\thandleGenericDeclaration(_node);\n\t\t}\n\t\tvoid endVisit(frontend::EnumValue const& _node) override\n\t\t{\n\t\t\thandleGenericDeclaration(_node);\n\t\t}\n\t\tvoid endVisit(frontend::UserDefinedValueTypeDefinition const& _node) override\n\t\t{\n\t\t\thandleGenericDeclaration(_node);\n\t\t}\n\t\tvoid endVisit(frontend::VariableDeclaration const& _node) override\n\t\t{\n\t\t\thandleGenericDeclaration(_node);\n\t\t}\n\t\tvoid endVisit(frontend::FunctionDefinition const& _node) override\n\t\t{\n\t\t\thandleGenericDeclaration(_node);\n\t\t}\n\t\tvoid endVisit(frontend::ModifierDefinition const& _node) override\n\t\t{\n\t\t\thandleGenericDeclaration(_node);\n\t\t}\n\t\tvoid endVisit(frontend::EventDefinition const& _node) override\n\t\t{\n\t\t\thandleGenericDeclaration(_node);\n\t\t}\n\t\tvoid endVisit(frontend::ErrorDefinition const& _node) override\n\t\t{\n\t\t\thandleGenericDeclaration(_node);\n\t\t}\n\n\t\tbool handleGenericDeclaration(frontend::Declaration const& _declaration)\n\t\t{\n\t\t\tif (\n\t\t\t\tm_outer.m_symbolName == _declaration.name() &&\n\t\t\t\t*m_outer.m_declarationToRename == _declaration\n\t\t\t)\n\t\t\t{\n\t\t\t\tm_outer.m_locations.emplace_back(_declaration.nameLocation());\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tprivate:\n\t\t\tRenameSymbol& m_outer;\n\t};\n\n\tvoid extractNameAndDeclaration(frontend::ASTNode const& _node, int _cursorBytePosition);\n\tvoid extractNameAndDeclaration(frontend::IdentifierPath const& _identifierPath, int _cursorBytePosition);\n\tvoid extractNameAndDeclaration(frontend::ImportDirective const& _importDirective, int _cursorBytePosition);\n\tvoid extractNameAndDeclaration(frontend::FunctionCall const& _functionCall, int _cursorBytePosition);\n\tvoid extractNameAndDeclaration(frontend::InlineAssembly const& _inlineAssembly, int _cursorBytePosition);\n\n\t// Node to rename\n\tfrontend::Declaration const* m_declarationToRename = nullptr;\n\t// Original name\n\tfrontend::ASTString m_symbolName = {};\n\t// SourceUnits to search & replace symbol in\n\tstd::set<frontend::SourceUnit const*, frontend::ASTNode::CompareByID> m_sourceUnits = {};\n\t// Source locations that need to be replaced\n\tstd::vector<langutil::SourceLocation> m_locations = {};\n};\n\n}\n"
  },
  {
    "path": "libsolidity/lsp/SemanticTokensBuilder.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/lsp/SemanticTokensBuilder.h>\n#include <libsolidity/lsp/Utils.h>\n\n#include <liblangutil/CharStream.h>\n#include <liblangutil/SourceLocation.h>\n\n#include <fmt/format.h>\n\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nnamespace solidity::lsp\n{\n\nnamespace\n{\n\nstd::optional<SemanticTokenType> semanticTokenTypeForType(frontend::Type const* _type)\n{\n\tif (!_type)\n\t\treturn std::nullopt;\n\n\tswitch (_type->category())\n\t{\n\tcase frontend::Type::Category::Address: return SemanticTokenType::Class;\n\tcase frontend::Type::Category::Bool: return SemanticTokenType::Number;\n\tcase frontend::Type::Category::Enum: return SemanticTokenType::Enum;\n\tcase frontend::Type::Category::Function: return SemanticTokenType::Function;\n\tcase frontend::Type::Category::Integer: return SemanticTokenType::Number;\n\tcase frontend::Type::Category::RationalNumber: return SemanticTokenType::Number;\n\tcase frontend::Type::Category::StringLiteral: return SemanticTokenType::String;\n\tcase frontend::Type::Category::Struct: return SemanticTokenType::Struct;\n\tcase frontend::Type::Category::Contract: return SemanticTokenType::Class;\n\tdefault:\n\t\tlspDebug(fmt::format(\"semanticTokenTypeForType: unknown category: {}\", static_cast<unsigned>(_type->category())));\n\t\treturn SemanticTokenType::Type;\n\t}\n}\n\nSemanticTokenType semanticTokenTypeForExpression(frontend::Type const* _type)\n{\n\tif (!_type)\n\t\treturn SemanticTokenType::Variable;\n\n\tswitch (_type->category())\n\t{\n\tcase frontend::Type::Category::Enum:\n\t\treturn SemanticTokenType::Enum;\n\tdefault:\n\t\treturn SemanticTokenType::Variable;\n\t}\n}\n\n} // end namespace\n\nJson SemanticTokensBuilder::build(SourceUnit const& _sourceUnit, CharStream const& _charStream)\n{\n\treset(&_charStream);\n\t_sourceUnit.accept(*this);\n\treturn m_encodedTokens;\n}\n\nvoid SemanticTokensBuilder::reset(CharStream const* _charStream)\n{\n\tm_encodedTokens = Json::array();\n\tm_charStream = _charStream;\n\tm_lastLine = 0;\n\tm_lastStartChar = 0;\n}\n\nvoid SemanticTokensBuilder::encode(\n\tSourceLocation const& _sourceLocation,\n\tSemanticTokenType _tokenType,\n\tSemanticTokenModifiers _modifiers\n)\n{\n\t/*\n\t\thttps://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#textDocument_semanticTokens\n\n\t\t// Step-1: Absolute positions\n\t\t{ line: 2, startChar:  5, length: 3, tokenType: 0, tokenModifiers: 3 },\n\t\t{ line: 2, startChar: 10, length: 4, tokenType: 1, tokenModifiers: 0 },\n\t\t{ line: 5, startChar:  2, length: 7, tokenType: 2, tokenModifiers: 0 }\n\n\t\t// Step-2: Relative positions as intermediate step\n\t\t{ deltaLine: 2, deltaStartChar: 5, length: 3, tokenType: 0, tokenModifiers: 3 },\n\t\t{ deltaLine: 0, deltaStartChar: 5, length: 4, tokenType: 1, tokenModifiers: 0 },\n\t\t{ deltaLine: 3, deltaStartChar: 2, length: 7, tokenType: 2, tokenModifiers: 0 }\n\n\t\t// Step-3: final array result\n\t\t// 1st token,  2nd token,  3rd token\n\t\t[  2,5,3,0,3,  0,5,4,1,0,  3,2,7,2,0 ]\n\n\t\tSo traverse through the AST and assign each leaf a token 5-tuple.\n\t*/\n\n\t// solAssert(_sourceLocation.isValid());\n\tif (!_sourceLocation.isValid())\n\t\treturn;\n\n\tauto const [line, startChar] = m_charStream->translatePositionToLineColumn(_sourceLocation.start);\n\tauto const length = _sourceLocation.end - _sourceLocation.start;\n\n\tlspDebug(fmt::format(\"encode [{}:{}..{}] {}\", line, startChar, length, static_cast<int>(_tokenType)));\n\n\tm_encodedTokens.emplace_back(line - m_lastLine);\n\tif (line == m_lastLine)\n\t\tm_encodedTokens.emplace_back(startChar - m_lastStartChar);\n\telse\n\t\tm_encodedTokens.emplace_back(startChar);\n\tm_encodedTokens.emplace_back(length);\n\tm_encodedTokens.emplace_back(static_cast<int>(_tokenType));\n\tm_encodedTokens.emplace_back(static_cast<int>(_modifiers));\n\n\tm_lastLine = line;\n\tm_lastStartChar = startChar;\n}\n\nbool SemanticTokensBuilder::visit(frontend::ContractDefinition const& _node)\n{\n\tencode(_node.nameLocation(), SemanticTokenType::Class);\n\treturn true;\n}\n\nbool SemanticTokensBuilder::visit(frontend::ElementaryTypeName const& _node)\n{\n\tencode(_node.location(), SemanticTokenType::Type);\n\treturn true;\n}\n\nbool SemanticTokensBuilder::visit(frontend::ElementaryTypeNameExpression const& _node)\n{\n\tif (auto const tokenType = semanticTokenTypeForType(_node.annotation().type); tokenType.has_value())\n\t\tencode(_node.location(), tokenType.value());\n\treturn true;\n}\n\nbool SemanticTokensBuilder::visit(frontend::EnumDefinition const& _node)\n{\n\tencode(_node.nameLocation(), SemanticTokenType::Enum);\n\treturn true;\n}\n\nbool SemanticTokensBuilder::visit(frontend::EnumValue const& _node)\n{\n\tencode(_node.nameLocation(), SemanticTokenType::EnumMember);\n\treturn true;\n}\n\nbool SemanticTokensBuilder::visit(frontend::ErrorDefinition const& _node)\n{\n\tencode(_node.nameLocation(), SemanticTokenType::Event);\n\treturn true;\n}\n\nbool SemanticTokensBuilder::visit(frontend::FunctionDefinition const& _node)\n{\n\tencode(_node.nameLocation(), SemanticTokenType::Function);\n\treturn true;\n}\n\nbool SemanticTokensBuilder::visit(frontend::ModifierDefinition const& _node)\n{\n\tencode(_node.nameLocation(), SemanticTokenType::Modifier);\n\treturn true;\n}\n\nvoid SemanticTokensBuilder::endVisit(frontend::Literal const& _literal)\n{\n\tencode(_literal.location(), SemanticTokenType::Number);\n}\n\nvoid SemanticTokensBuilder::endVisit(frontend::StructuredDocumentation const& _documentation)\n{\n\tencode(_documentation.location(), SemanticTokenType::Comment);\n}\n\nvoid SemanticTokensBuilder::endVisit(frontend::Identifier const& _identifier)\n{\n\t//lspDebug(fmt::format(\"Identifier: {}, {}..{} cat={}\", _identifier.name(), _identifier.location().start, _identifier.location().end, _identifier.annotation().type->category()));\n\n\tSemanticTokenModifiers modifiers = SemanticTokenModifiers::None;\n\tif (_identifier.annotation().isConstant.set() && *_identifier.annotation().isConstant)\n\t{\n\t\tlspDebug(\"OMG We've found a const!\");\n\t\tmodifiers = modifiers | SemanticTokenModifiers::Readonly;\n\t}\n\n\tencode(_identifier.location(), semanticTokenTypeForExpression(_identifier.annotation().type), modifiers);\n}\n\nvoid SemanticTokensBuilder::endVisit(frontend::IdentifierPath const& _node)\n{\n\tlspDebug(fmt::format(\"IdentifierPath: identifier path [{}..{}]\", _node.location().start, _node.location().end));\n\tfor (size_t i = 0; i < _node.path().size(); ++i)\n\t\tlspDebug(fmt::format(\"  [{}]: {}\", i, _node.path().at(i)));\n\tif (dynamic_cast<EnumDefinition const*>(_node.annotation().referencedDeclaration))\n\t\tencode(_node.location(), SemanticTokenType::EnumMember);\n\telse\n\t\tencode(_node.location(), SemanticTokenType::Variable);\n}\n\nbool SemanticTokensBuilder::visit(frontend::MemberAccess const& _node)\n{\n\tlspDebug(fmt::format(\"[{}..{}] MemberAccess({}): {}\", _node.location().start, _node.location().end, _node.annotation().referencedDeclaration ?  _node.annotation().referencedDeclaration->name() : \"?\", _node.memberName()));\n\n\tauto const memberNameLength = static_cast<int>(_node.memberName().size());\n\tauto const memberTokenType = semanticTokenTypeForExpression(_node.annotation().type);\n\n\tauto lhsLocation = _node.location();\n\tlhsLocation.end -= (memberNameLength + 1 /*exclude the dot*/);\n\n\tauto rhsLocation = _node.location();\n\trhsLocation.start = rhsLocation.end - static_cast<int>(memberNameLength);\n\n\tif (memberTokenType == SemanticTokenType::Enum)\n\t{\n\t\t// Special handling for enumeration symbols.\n\t\tencode(lhsLocation, SemanticTokenType::Enum);\n\t\tencode(rhsLocation, SemanticTokenType::EnumMember);\n\t}\n\telse if (memberTokenType == SemanticTokenType::Function)\n\t{\n\t\t// Special handling for function symbols.\n\t\tencode(lhsLocation, SemanticTokenType::Variable);\n\t\tencode(rhsLocation, memberTokenType);\n\t}\n\telse\n\t{\n\t\tencode(rhsLocation, memberTokenType);\n\t}\n\n\treturn false; // we handle LHS and RHS explicitly above.\n}\n\nvoid SemanticTokensBuilder::endVisit(PragmaDirective const& _pragma)\n{\n\tencode(_pragma.location(), SemanticTokenType::Macro);\n\t// NOTE: It would be nice if we could highlight based on the symbols,\n\t//       such as (version) numerics be different than identifiers.\n}\n\nbool SemanticTokensBuilder::visit(frontend::UserDefinedTypeName const& _node)\n{\n\tif (auto const token = semanticTokenTypeForType(_node.annotation().type); token.has_value())\n\t\tencode(_node.location(), *token);\n\treturn false;\n}\n\nbool SemanticTokensBuilder::visit(frontend::VariableDeclaration const& _node)\n{\n\tlspDebug(fmt::format(\"VariableDeclaration: {}\", _node.name()));\n\n\tif (auto const token = semanticTokenTypeForType(_node.typeName().annotation().type); token.has_value())\n\t\tencode(_node.typeName().location(), *token);\n\n\tencode(_node.nameLocation(), SemanticTokenType::Variable);\n\tif (_node.overrides())\n\t\t_node.overrides()->accept(*this);\n\tif (_node.value())\n\t\t_node.value()->accept(*this);\n\treturn false;\n}\n\n} // end namespace\n"
  },
  {
    "path": "libsolidity/lsp/SemanticTokensBuilder.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/ASTVisitor.h>\n#include <libsolutil/JSON.h>\n\n#include <fmt/format.h>\n\nnamespace solidity::langutil\n{\nclass CharStream;\nstruct SourceLocation;\n}\n\nnamespace solidity::lsp\n{\n\n// See: https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#semanticTokenTypes\nenum class SemanticTokenType\n{\n\tClass,\n\tComment,\n\tEnum,\n\tEnumMember,\n\tEvent,\n\tFunction,\n\tInterface,\n\tKeyword,\n\tMacro,\n\tMethod,\n\tModifier,\n\tNumber,\n\tOperator,\n\tParameter,\n\tProperty,\n\tString,\n\tStruct,\n\tType,\n\tTypeParameter,\n\tVariable,\n\n\t// Unused below:\n\t// Namespace,\n\t// Regexp,\n};\n\nenum class SemanticTokenModifiers\n{\n\tNone            = 0,\n\n\t// Member integer values must be bit-values as\n\t// they can be OR'd together.\n\tAbstract        = 0x0001,\n\tDeclaration     = 0x0002,\n\tDefinition      = 0x0004,\n\tDeprecated      = 0x0008,\n\tDocumentation   = 0x0010,\n\tModification    = 0x0020,\n\tReadonly        = 0x0040,\n\n\t// Unused below:\n\t// Static,\n\t// Async,\n\t// DefaultLibrary,\n};\n\nconstexpr SemanticTokenModifiers operator|(SemanticTokenModifiers a, SemanticTokenModifiers b) noexcept\n{\n\treturn static_cast<SemanticTokenModifiers>(static_cast<int>(a) | static_cast<int>(b));\n}\n\nclass SemanticTokensBuilder: public frontend::ASTConstVisitor\n{\npublic:\n\tJson build(frontend::SourceUnit const& _sourceUnit, langutil::CharStream const& _charStream);\n\n\tvoid reset(langutil::CharStream const* _charStream);\n\tvoid encode(\n\t\tlangutil::SourceLocation const& _sourceLocation,\n\t\tSemanticTokenType _tokenType,\n\t\tSemanticTokenModifiers _modifiers = SemanticTokenModifiers::None\n\t);\n\n\tbool visit(frontend::ContractDefinition const&) override;\n\tbool visit(frontend::ElementaryTypeName const&) override;\n\tbool visit(frontend::ElementaryTypeNameExpression const&) override;\n\tbool visit(frontend::EnumDefinition const&) override;\n\tbool visit(frontend::EnumValue const&) override;\n\tbool visit(frontend::ErrorDefinition const&) override;\n\tbool visit(frontend::FunctionDefinition const&) override;\n\tbool visit(frontend::ModifierDefinition const&) override;\n\tvoid endVisit(frontend::Literal const&) override;\n\tvoid endVisit(frontend::StructuredDocumentation const&) override;\n\tvoid endVisit(frontend::Identifier const&) override;\n\tvoid endVisit(frontend::IdentifierPath const&) override;\n\tbool visit(frontend::MemberAccess const&) override;\n\tvoid endVisit(frontend::PragmaDirective const&) override;\n\tbool visit(frontend::UserDefinedTypeName const&) override;\n\tbool visit(frontend::VariableDeclaration const&) override;\n\nprivate:\n\tJson m_encodedTokens;\n\tlangutil::CharStream const* m_charStream;\n\tint m_lastLine;\n\tint m_lastStartChar;\n};\n\n} // end namespace\n"
  },
  {
    "path": "libsolidity/lsp/Transport.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libsolidity/lsp/Transport.h>\n#include <libsolidity/lsp/Utils.h>\n\n#include <libsolutil/JSON.h>\n#include <libsolutil/Visitor.h>\n#include <libsolutil/CommonIO.h>\n#include <liblangutil/Exceptions.h>\n\n#include <fmt/format.h>\n\n#include <boost/algorithm/string.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n\n\n#if defined(_WIN32)\n#include <io.h>\n#include <fcntl.h>\n#endif\n\nusing namespace solidity::lsp;\nusing namespace solidity;\n\n// {{{ Transport\nstd::optional<Json> Transport::receive()\n{\n\tauto const headers = parseHeaders();\n\tif (!headers)\n\t{\n\t\terror({}, ErrorCode::ParseError, \"Could not parse RPC headers.\");\n\t\treturn std::nullopt;\n\t}\n\n\tif (!headers->count(\"content-length\"))\n\t{\n\t\terror({}, ErrorCode::ParseError, \"No content-length header found.\");\n\t\treturn std::nullopt;\n\t}\n\n\tstd::string const data = readBytes(stoul(headers->at(\"content-length\")));\n\n\tJson jsonMessage;\n\tstd::string jsonParsingErrors;\n\tsolidity::util::jsonParseStrict(data, jsonMessage, &jsonParsingErrors);\n\tif (!jsonParsingErrors.empty() || jsonMessage.empty() || !jsonMessage.is_object())\n\t{\n\t\terror({}, ErrorCode::ParseError, \"Could not parse RPC JSON payload. \" + jsonParsingErrors);\n\t\treturn std::nullopt;\n\t}\n\n\treturn {std::move(jsonMessage)};\n}\n\nvoid Transport::trace(std::string _message, Json _extra)\n{\n\tif (m_logTrace != TraceValue::Off)\n\t{\n\t\tJson params;\n\t\tif (_extra.is_object())\n\t\t\tparams = std::move(_extra);\n\t\tparams[\"message\"] = std::move(_message);\n\t\tnotify(\"$/logTrace\", std::move(params));\n\t}\n}\n\nstd::optional<std::map<std::string, std::string>> Transport::parseHeaders()\n{\n\tstd::map<std::string, std::string> headers;\n\n\twhile (true)\n\t{\n\t\tauto line = getline();\n\t\tif (boost::trim_copy(line).empty())\n\t\t\tbreak;\n\n\t\tauto const delimiterPos = line.find(':');\n\t\tif (delimiterPos == std::string::npos)\n\t\t\treturn std::nullopt;\n\n\t\tauto const name = boost::to_lower_copy(line.substr(0, delimiterPos));\n\t\tauto const value = line.substr(delimiterPos + 1);\n\t\tif (!headers.emplace(boost::trim_copy(name), boost::trim_copy(value)).second)\n\t\t\treturn std::nullopt;\n\t}\n\treturn {std::move(headers)};\n}\n\nvoid Transport::notify(std::string _method, Json _message)\n{\n\tJson json;\n\tjson[\"method\"] = std::move(_method);\n\tjson[\"params\"] = std::move(_message);\n\tsend(std::move(json));\n}\n\nvoid Transport::reply(MessageID _id, Json _message)\n{\n\tJson json;\n\tjson[\"result\"] = std::move(_message);\n\tsend(std::move(json), _id);\n}\n\nvoid Transport::error(MessageID _id, ErrorCode _code, std::string _message)\n{\n\tJson json;\n\tjson[\"error\"][\"code\"] = static_cast<int>(_code);\n\tjson[\"error\"][\"message\"] = std::move(_message);\n\tsend(std::move(json), _id);\n}\n\nvoid Transport::send(Json _json, MessageID _id)\n{\n\tsolAssert(_json.is_object());\n\t_json[\"jsonrpc\"] = \"2.0\";\n\tif (_id != Json())\n\t\t_json[\"id\"] = _id;\n\n\t// Trailing CRLF only for easier readability.\n\tstd::string const jsonString = solidity::util::jsonCompactPrint(_json);\n\n\twriteBytes(fmt::format(\"Content-Length: {}\\r\\n\\r\\n\", jsonString.size()));\n\twriteBytes(jsonString);\n\tflushOutput();\n}\n// }}}\n\n// {{{ IOStreamTransport\nIOStreamTransport::IOStreamTransport(std::istream& _in, std::ostream& _out):\n\tm_input{_in},\n\tm_output{_out}\n{\n}\n\nbool IOStreamTransport::closed() const noexcept\n{\n\treturn m_input.eof();\n}\n\nstd::string IOStreamTransport::readBytes(size_t _length)\n{\n\treturn util::readBytes(m_input, _length);\n}\n\nstd::string IOStreamTransport::getline()\n{\n\tstd::string line;\n\tstd::getline(m_input, line);\n\treturn line;\n}\n\nvoid IOStreamTransport::writeBytes(std::string_view _data)\n{\n\tm_output.write(_data.data(), static_cast<std::streamsize>(_data.size()));\n}\n\nvoid IOStreamTransport::flushOutput()\n{\n\tm_output.flush();\n}\n// }}}\n\n// {{{ StdioTransport\nStdioTransport::StdioTransport()\n{\n\t#if defined(_WIN32)\n\t// Attempt to change the modes of stdout from text to binary.\n\tsetmode(fileno(stdout), O_BINARY);\n\t#endif\n}\n\nbool StdioTransport::closed() const noexcept\n{\n\treturn feof(stdin);\n}\n\nstd::string StdioTransport::readBytes(size_t _byteCount)\n{\n\tstd::string buffer;\n\tbuffer.resize(_byteCount);\n\tauto const n = fread(buffer.data(), 1, _byteCount, stdin);\n\tif (n < _byteCount)\n\t\tbuffer.resize(n);\n\treturn buffer;\n}\n\nstd::string StdioTransport::getline()\n{\n\tstd::string line;\n\tstd::getline(std::cin, line);\n\tlspDebug(fmt::format(\"Received: {}\", line));\n\treturn line;\n}\n\nvoid StdioTransport::writeBytes(std::string_view _data)\n{\n\tlspDebug(fmt::format(\"Sending: {}\", _data));\n\tauto const bytesWritten = fwrite(_data.data(), 1, _data.size(), stdout);\n\tsolAssert(bytesWritten == _data.size());\n}\n\nvoid StdioTransport::flushOutput()\n{\n\tfflush(stdout);\n}\n// }}}\n"
  },
  {
    "path": "libsolidity/lsp/Transport.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libsolutil/Exceptions.h>\n#include <libsolutil/JSON.h>\n\n#include <functional>\n#include <iosfwd>\n#include <map>\n#include <optional>\n#include <string>\n#include <string_view>\n#include <variant>\n\nnamespace solidity::lsp\n{\n\nusing MessageID = Json;\n\nenum class TraceValue\n{\n\tOff,\n\tMessages,\n\tVerbose\n};\n\nenum class ErrorCode\n{\n\t// Defined by JSON RPC\n\tParseError = -32700,\n\tMethodNotFound = -32601,\n\tInvalidParams = -32602,\n\tInternalError = -32603,\n\n\t// Defined by the protocol.\n\tServerNotInitialized = -32002,\n\tRequestFailed = -32803\n};\n\n/**\n * Error exception used to bail out on errors in the LSP function-call handlers.\n */\nclass RequestError: public util::Exception\n{\npublic:\n\texplicit RequestError(ErrorCode _code):\n\t\tm_code{_code}\n\t{\n\t}\n\n\tErrorCode code() const noexcept { return m_code; }\n\nprivate:\n\tErrorCode m_code;\n};\n\n/**\n * Ensures precondition check is valid.\n * This is supposed to be a recoverable error, that means, if the condition fails to be valid,\n * an exception is being raised to be thrown out of the current request handlers\n * of the current LSP's client RPC call and this will cause the current request to fail\n * with the given error code - but subsequent calls shall be able to continue.\n */\n#define lspRequire(condition, errorCode, errorMessage) \\\n\tif (!(condition)) \\\n\t{ \\\n\t\tBOOST_THROW_EXCEPTION( \\\n\t\t\tRequestError(errorCode) << \\\n\t\t\tutil::errinfo_comment(errorMessage) \\\n\t\t); \\\n\t}\n\n/**\n * Transport layer API\n *\n * The transport layer API is abstracted to make LSP more testable as well as\n * this way it could be possible to support other transports (HTTP for example) easily.\n */\nclass Transport\n{\npublic:\n\tvirtual ~Transport() = default;\n\n\tstd::optional<Json> receive();\n\tvoid notify(std::string _method, Json _params);\n\tvoid reply(MessageID _id, Json _result);\n\tvoid error(MessageID _id, ErrorCode _code, std::string _message);\n\n\tvirtual bool closed() const noexcept = 0;\n\n\tvoid trace(std::string _message, Json _extra = Json{});\n\n\tTraceValue traceValue() const noexcept { return m_logTrace; }\n\tvoid setTrace(TraceValue _value) noexcept { m_logTrace = _value; }\n\nprivate:\n\tTraceValue m_logTrace = TraceValue::Off;\n\nprotected:\n\t/// Reads from the transport and parses the headers until the beginning\n\t/// of the contents.\n\tstd::optional<std::map<std::string, std::string>> parseHeaders();\n\n\t/// Consumes exactly @p _byteCount bytes, as needed for consuming\n\t/// the message body from the transport line.\n\tvirtual std::string readBytes(size_t _byteCount) = 0;\n\n\t// Mimics std::getline() on this Transport API.\n\tvirtual std::string getline() = 0;\n\n\t/// Writes the given payload @p _data to transport.\n\t/// This call may or may not buffer.\n\tvirtual void writeBytes(std::string_view _data) = 0;\n\n\t/// Ensures transport output is flushed.\n\tvirtual void flushOutput() = 0;\n\n\t/// Sends an arbitrary raw message to the client.\n\t///\n\t/// Used by the notify/reply/error function family.\n\tvirtual void send(Json _message, MessageID _id = Json{});\n};\n\n/**\n * LSP Transport using JSON-RPC over iostreams.\n */\nclass IOStreamTransport: public Transport\n{\npublic:\n\t/// Constructs a standard stream transport layer.\n\t///\n\t/// @param _in for example std::cin (stdin)\n\t/// @param _out for example std::cout (stdout)\n\tIOStreamTransport(std::istream& _in, std::ostream& _out);\n\n\tbool closed() const noexcept override;\n\nprotected:\n\tstd::string readBytes(size_t _byteCount) override;\n\tstd::string getline() override;\n\tvoid writeBytes(std::string_view _data) override;\n\tvoid flushOutput() override;\n\nprivate:\n\tstd::istream& m_input;\n\tstd::ostream& m_output;\n};\n\n/**\n * Standard I/O transport Layer utilizing stdin/stdout for communication.\n */\nclass StdioTransport: public Transport\n{\npublic:\n\tStdioTransport();\n\n\tbool closed() const noexcept override;\n\nprotected:\n\tstd::string readBytes(size_t _byteCount) override;\n\tstd::string getline() override;\n\tvoid writeBytes(std::string_view _data) override;\n\tvoid flushOutput() override;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/lsp/Utils.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <liblangutil/CharStreamProvider.h>\n#include <liblangutil/Exceptions.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/lsp/FileRepository.h>\n#include <libsolidity/lsp/Utils.h>\n\n#include <regex>\n#include <fstream>\n\nnamespace solidity::lsp\n{\n\nusing namespace frontend;\nusing namespace langutil;\n\nstd::optional<LineColumn> parseLineColumn(Json const& _lineColumn)\n{\n\tif (_lineColumn.is_object() && _lineColumn[\"line\"].is_number_integer() && _lineColumn[\"character\"].is_number_integer())\n\t\treturn LineColumn{_lineColumn[\"line\"].get<int>(), _lineColumn[\"character\"].get<int>()};\n\telse\n\t\treturn std::nullopt;\n}\n\nJson toJson(LineColumn const& _pos)\n{\n\tJson json;\n\tjson[\"line\"] = std::max(_pos.line, 0);\n\tjson[\"character\"] = std::max(_pos.column, 0);\n\n\treturn json;\n}\n\nJson toJsonRange(LineColumn const& _start, LineColumn const& _end)\n{\n\tJson json;\n\tjson[\"start\"] = toJson(_start);\n\tjson[\"end\"] = toJson(_end);\n\treturn json;\n}\n\nDeclaration const* referencedDeclaration(Expression const* _expression)\n{\n\tif (auto const* identifier = dynamic_cast<Identifier const*>(_expression))\n\t\tif (Declaration const* referencedDeclaration = identifier->annotation().referencedDeclaration)\n\t\t\treturn referencedDeclaration;\n\n\tif (auto const* memberAccess = dynamic_cast<MemberAccess const*>(_expression))\n\t\tif (memberAccess->annotation().referencedDeclaration)\n\t\t\treturn memberAccess->annotation().referencedDeclaration;\n\n\treturn nullptr;\n}\n\nstd::optional<SourceLocation> declarationLocation(Declaration const* _declaration)\n{\n\tif (!_declaration)\n\t\treturn std::nullopt;\n\n\tif (_declaration->nameLocation().isValid())\n\t\treturn _declaration->nameLocation();\n\n\tif (_declaration->location().isValid())\n\t\treturn _declaration->location();\n\n\treturn std::nullopt;\n}\n\nstd::optional<SourceLocation> parsePosition(\n\tFileRepository const& _fileRepository,\n\tstd::string const& _sourceUnitName,\n\tJson const& _position\n)\n{\n\tif (!_fileRepository.sourceUnits().count(_sourceUnitName))\n\t\treturn std::nullopt;\n\n\tif (std::optional<LineColumn> lineColumn = parseLineColumn(_position))\n\t\tif (std::optional<int> const offset = CharStream::translateLineColumnToPosition(\n\t\t\t_fileRepository.sourceUnits().at(_sourceUnitName),\n\t\t\t*lineColumn\n\t\t))\n\t\t\treturn SourceLocation{*offset, *offset, std::make_shared<std::string>(_sourceUnitName)};\n\treturn std::nullopt;\n}\n\nstd::optional<SourceLocation> parseRange(FileRepository const& _fileRepository, std::string const& _sourceUnitName, Json const& _range)\n{\n\tif (!_range.is_object())\n\t\treturn std::nullopt;\n\tstd::optional<SourceLocation> start = parsePosition(_fileRepository, _sourceUnitName, _range[\"start\"]);\n\tstd::optional<SourceLocation> end = parsePosition(_fileRepository, _sourceUnitName, _range[\"end\"]);\n\tif (!start || !end)\n\t\treturn std::nullopt;\n\tsolAssert(*start->sourceName == *end->sourceName);\n\tstart->end = end->end;\n\treturn start;\n}\n\nstd::string stripFileUriSchemePrefix(std::string const& _path)\n{\n\tstd::regex const windowsDriveLetterPath(\"^file:///[a-zA-Z]:/\");\n\tif (regex_search(_path, windowsDriveLetterPath))\n\t\treturn _path.substr(8);\n\tif (_path.find(\"file://\") == 0)\n\t\treturn _path.substr(7);\n\telse\n\t\treturn _path;\n}\n\n}\n"
  },
  {
    "path": "libsolidity/lsp/Utils.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <liblangutil/SourceLocation.h>\n\n#include <libsolidity/ast/ASTForward.h>\n\n#include <libsolutil/JSON.h>\n\n#include <optional>\n#include <vector>\n\n#if !defined(NDEBUG)\n#include <fstream>\n#define lspDebug(message) (std::ofstream(\"/tmp/solc.log\", std::ios::app) << (message) << std::endl)\n#else\n#define lspDebug(message) do {} while (0)\n#endif\n\nnamespace solidity::langutil\n{\nclass CharStreamProvider;\n}\n\nnamespace solidity::lsp\n{\n\nclass FileRepository;\n\nstd::optional<langutil::LineColumn> parseLineColumn(Json const& _lineColumn);\nJson toJson(langutil::LineColumn const& _pos);\nJson toJsonRange(langutil::LineColumn const& _start, langutil::LineColumn const& _end);\n\n/// @returns the source location given a source unit name and an LSP Range object,\n/// or nullopt on failure.\nstd::optional<langutil::SourceLocation> parsePosition(\n\tFileRepository const& _fileRepository,\n\tstd::string const& _sourceUnitName,\n\tJson const& _position\n);\n\n/// @returns the source location given a source unit name and an LSP Range object,\n/// or nullopt on failure.\nstd::optional<langutil::SourceLocation> parseRange(\n\tFileRepository const& _fileRepository,\n\tstd::string const& _sourceUnitName,\n\tJson const& _range\n);\n\n/// Strips the file:// URI prefix off the given path, if present,\n/// also taking special care of Windows-drive-letter paths.\n///\n/// So file:///path/to/some/file.txt returns /path/to/some/file.txt, as well as,\n/// file:///C:/file.txt will return C:/file.txt (forward-slash is okay on Windows).\nstd::string stripFileUriSchemePrefix(std::string const& _path);\n\n/// Extracts the resolved declaration of the given expression AST node.\n///\n/// This may for example be the type declaration of an identifier,\n/// or the type declaration of a structured member identifier.\n///\n/// @returns the resolved type declaration if found, or nullptr otherwise.\nfrontend::Declaration const* referencedDeclaration(frontend::Expression const* _expression);\n\n/// @returns the location of the declaration's name, if present, or the location of the complete\n/// declaration otherwise. If the input declaration is nullptr, std::nullopt is returned instead.\nstd::optional<langutil::SourceLocation> declarationLocation(frontend::Declaration const* _declaration);\n\n}\n"
  },
  {
    "path": "libsolidity/parsing/DocStringParser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolidity/parsing/DocStringParser.h>\n\n#include <libsolidity/ast/AST.h>\n\n#include <liblangutil/Common.h>\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/Exceptions.h>\n\n#include <range/v3/algorithm/find_first_of.hpp>\n#include <range/v3/algorithm/find_if_not.hpp>\n#include <range/v3/view/subrange.hpp>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nnamespace\n{\n\nstd::string::const_iterator skipLineOrEOS(\n\tstd::string::const_iterator _nlPos,\n\tstd::string::const_iterator _end\n)\n{\n\treturn (_nlPos == _end) ? _end : ++_nlPos;\n}\n\nstd::string::const_iterator firstNonIdentifier(\n\tstd::string::const_iterator _pos,\n\tstd::string::const_iterator _end\n)\n{\n\tauto currPos = _pos;\n\tif (currPos == _pos && isIdentifierStart(*currPos))\n\t{\n\t\tcurrPos++;\n\t\tcurrPos = ranges::find_if_not(ranges::make_subrange(currPos, _end), isIdentifierPart);\n\t}\n\treturn currPos;\n}\n\nstd::string::const_iterator firstWhitespaceOrNewline(\n\tstd::string::const_iterator _pos,\n\tstd::string::const_iterator _end\n)\n{\n\treturn ranges::find_first_of(ranges::make_subrange(_pos, _end), \" \\t\\n\");\n}\n\n\nstd::string::const_iterator skipWhitespace(\n\tstd::string::const_iterator _pos,\n\tstd::string::const_iterator _end\n)\n{\n\tauto isWhitespace = [](char const& c) { return (c == ' ' || c == '\\t'); };\n\treturn ranges::find_if_not(ranges::make_subrange(_pos, _end), isWhitespace);\n}\n\n}\n\nstd::multimap<std::string, DocTag> DocStringParser::parse()\n{\n\tm_lastTag = nullptr;\n\tm_docTags = {};\n\n\tsolAssert(m_node.text(), \"\");\n\titer currPos = m_node.text()->begin();\n\titer end = m_node.text()->end();\n\n\twhile (currPos != end)\n\t{\n\t\titer tagPos = find(currPos, end, '@');\n\t\titer nlPos = find(currPos, end, '\\n');\n\n\t\tif (tagPos != end && tagPos < nlPos)\n\t\t{\n\t\t\t// we found a tag\n\t\t\titer tagNameEndPos = firstWhitespaceOrNewline(tagPos, end);\n\t\t\tstd::string tagName{tagPos + 1, tagNameEndPos};\n\t\t\titer tagDataPos = (tagNameEndPos != end) ? tagNameEndPos + 1 : tagNameEndPos;\n\t\t\tcurrPos = parseDocTag(tagDataPos, end, tagName);\n\t\t}\n\t\telse if (!!m_lastTag) // continuation of the previous tag\n\t\t\tcurrPos = parseDocTagLine(currPos, end, true);\n\t\telse if (currPos != end)\n\t\t{\n\t\t\t// if it begins without a tag then consider it as @notice\n\t\t\tif (currPos == m_node.text()->begin())\n\t\t\t{\n\t\t\t\tcurrPos = parseDocTag(currPos, end, \"notice\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if (nlPos == end) //end of text\n\t\t\t\tbreak;\n\t\t\t// else skip the line if a newline was found and we get here\n\t\t\tcurrPos = nlPos + 1;\n\t\t}\n\t}\n\treturn std::move(m_docTags);\n}\n\nDocStringParser::iter DocStringParser::parseDocTagLine(iter _pos, iter _end, bool _appending)\n{\n\tsolAssert(!!m_lastTag, \"\");\n\tauto nlPos = find(_pos, _end, '\\n');\n\tif (_appending && _pos != _end && *_pos != ' ' && *_pos != '\\t')\n\t\tm_lastTag->content += \" \";\n\telse if (!_appending)\n\t\t_pos = skipWhitespace(_pos, _end);\n\tcopy(_pos, nlPos, back_inserter(m_lastTag->content));\n\treturn skipLineOrEOS(nlPos, _end);\n}\n\nDocStringParser::iter DocStringParser::parseDocTagParam(iter _pos, iter _end)\n{\n\t// find param name start\n\tauto nameStartPos = skipWhitespace(_pos, _end);\n\tif (nameStartPos == _end)\n\t{\n\t\tm_errorReporter.docstringParsingError(3335_error, m_node.location(), \"No param name given\");\n\t\treturn _end;\n\t}\n\tauto nameEndPos = firstNonIdentifier(nameStartPos, _end);\n\tauto paramName = std::string(nameStartPos, nameEndPos);\n\n\tauto descStartPos = skipWhitespace(nameEndPos, _end);\n\tauto nlPos = find(descStartPos, _end, '\\n');\n\n\tif (descStartPos == nlPos)\n\t{\n\t\tm_errorReporter.docstringParsingError(9942_error, m_node.location(), \"No description given for param \" + paramName);\n\t\treturn _end;\n\t}\n\n\tauto paramDesc = std::string(descStartPos, nlPos);\n\tnewTag(\"param\");\n\tm_lastTag->paramName = paramName;\n\tm_lastTag->content = paramDesc;\n\n\treturn skipLineOrEOS(nlPos, _end);\n}\n\nDocStringParser::iter DocStringParser::parseDocTag(iter _pos, iter _end, std::string const& _tag)\n{\n\t// TODO: need to check for @(start of a tag) between here and the end of line\n\t// for all cases.\n\tif (!m_lastTag || !_tag.empty())\n\t{\n\t\tif (_tag == \"param\")\n\t\t\treturn parseDocTagParam(_pos, _end);\n\t\telse\n\t\t{\n\t\t\tnewTag(_tag);\n\t\t\treturn parseDocTagLine(_pos, _end, false);\n\t\t}\n\t}\n\telse\n\t\treturn parseDocTagLine(_pos, _end, true);\n}\n\nvoid DocStringParser::newTag(std::string const& _tagName)\n{\n\tm_lastTag = &m_docTags.insert(make_pair(_tagName, DocTag()))->second;\n}\n"
  },
  {
    "path": "libsolidity/parsing/DocStringParser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Lefteris <lefteris@ethdev.com>\n * @date 2014, 2015\n * Parses a given docstring into pieces introduced by tags.\n */\n\n#pragma once\n\n#include <libsolidity/ast/ASTAnnotations.h>\n#include <liblangutil/SourceLocation.h>\n#include <string>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::frontend\n{\n\nclass StructuredDocumentation;\n\nclass DocStringParser\n{\npublic:\n\t/// @param _documentedNode the node whose documentation is parsed.\n\tDocStringParser(StructuredDocumentation const& _documentedNode, langutil::ErrorReporter& _errorReporter):\n\t\tm_node(_documentedNode),\n\t\tm_errorReporter(_errorReporter)\n\t{}\n\tstd::multimap<std::string, DocTag> parse();\n\nprivate:\n\tusing iter = std::string::const_iterator;\n\n\titer parseDocTagLine(iter _pos, iter _end, bool _appending);\n\titer parseDocTagParam(iter _pos, iter _end);\n\n\t/// Parses the doc tag named @a _tag, adds it to m_docTags and returns the position\n\t/// after the tag.\n\titer parseDocTag(iter _pos, iter _end, std::string const& _tag);\n\n\t/// Creates and inserts a new tag and adjusts m_lastTag.\n\tvoid newTag(std::string const& _tagName);\n\n\tStructuredDocumentation const& m_node;\n\tlangutil::ErrorReporter& m_errorReporter;\n\t/// Mapping tag name -> content.\n\tstd::multimap<std::string, DocTag> m_docTags;\n\tDocTag* m_lastTag = nullptr;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/parsing/Parser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity parser.\n */\n\n#include <libsolidity/parsing/Parser.h>\n\n#include <libsolidity/ast/UserDefinableOperators.h>\n#include <libsolidity/interface/Version.h>\n#include <libyul/AST.h>\n#include <libyul/AsmParser.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/Scanner.h>\n#include <liblangutil/SemVerHandler.h>\n#include <liblangutil/SourceLocation.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <boost/algorithm/string/trim.hpp>\n#include <boost/algorithm/string/replace.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n\n#include <cctype>\n#include <memory>\n#include <regex>\n#include <tuple>\n#include <vector>\n\nusing namespace solidity::langutil;\nusing namespace std::string_literals;\n\nnamespace solidity::frontend\n{\n\n/// AST node factory that also tracks the begin and end position of an AST node\n/// while it is being parsed\nclass Parser::ASTNodeFactory\n{\npublic:\n\texplicit ASTNodeFactory(Parser& _parser):\n\t\tm_parser(_parser), m_location{\n\t\t\t_parser.currentLocation().start,\n\t\t\t-1,\n\t\t\t_parser.currentLocation().sourceName\n\t\t}\n\t{}\n\tASTNodeFactory(Parser& _parser, ASTPointer<ASTNode> const& _childNode):\n\t\tm_parser(_parser), m_location{_childNode->location()} {}\n\n\tvoid markEndPosition() { m_location.end = m_parser.currentLocation().end; }\n\tvoid setLocation(SourceLocation const& _location) { m_location = _location; }\n\tvoid setLocationEmpty() { m_location.end = m_location.start; }\n\t/// Set the end position to the one of the given node.\n\tvoid setEndPositionFromNode(ASTPointer<ASTNode> const& _node) { m_location.end = _node->location().end; }\n\n\ttemplate <class NodeType, typename... Args>\n\tASTPointer<NodeType> createNode(Args&& ... _args)\n\t{\n\t\tsolAssert(m_location.sourceName, \"\");\n\t\tif (m_location.end < 0)\n\t\t\tmarkEndPosition();\n\t\treturn std::make_shared<NodeType>(m_parser.nextID(), m_location, std::forward<Args>(_args)...);\n\t}\n\n\tSourceLocation const& location() const noexcept { return m_location; }\n\nprivate:\n\tParser& m_parser;\n\tSourceLocation m_location;\n};\n\nASTPointer<SourceUnit> Parser::parse(CharStream& _charStream)\n{\n\tsolAssert(!m_insideModifier, \"\");\n\ttry\n\t{\n\t\tm_recursionDepth = 0;\n\t\tm_scanner = std::make_shared<Scanner>(_charStream);\n\t\tASTNodeFactory nodeFactory(*this);\n\t\tm_experimentalSolidityEnabledInCurrentSourceUnit = false;\n\n\t\tstd::vector<ASTPointer<ASTNode>> nodes;\n\t\twhile (m_scanner->currentToken() == Token::Pragma)\n\t\t\tnodes.push_back(parsePragmaDirective(false));\n\n\t\tif (m_experimentalSolidityEnabledInCurrentSourceUnit)\n\t\t\tm_scanner->setScannerMode(ScannerKind::ExperimentalSolidity);\n\n\t\twhile (m_scanner->currentToken() != Token::EOS)\n\t\t{\n\t\t\tswitch (m_scanner->currentToken())\n\t\t\t{\n\t\t\tcase Token::Pragma:\n\t\t\t\tnodes.push_back(parsePragmaDirective(true));\n\t\t\t\tbreak;\n\t\t\tcase Token::Import:\n\t\t\t\tnodes.push_back(parseImportDirective());\n\t\t\t\tbreak;\n\t\t\tcase Token::Abstract:\n\t\t\tcase Token::Interface:\n\t\t\tcase Token::Contract:\n\t\t\tcase Token::Library:\n\t\t\t\tnodes.push_back(parseContractDefinition());\n\t\t\t\tbreak;\n\t\t\tcase Token::Struct:\n\t\t\t\tnodes.push_back(parseStructDefinition());\n\t\t\t\tbreak;\n\t\t\tcase Token::Enum:\n\t\t\t\tnodes.push_back(parseEnumDefinition());\n\t\t\t\tbreak;\n\t\t\tcase Token::Type:\n\t\t\t\tif (m_experimentalSolidityEnabledInCurrentSourceUnit)\n\t\t\t\t\tnodes.push_back(parseTypeDefinition());\n\t\t\t\telse\n\t\t\t\t\tnodes.push_back(parseUserDefinedValueTypeDefinition());\n\t\t\t\tbreak;\n\t\t\tcase Token::Using:\n\t\t\t\tnodes.push_back(parseUsingDirective());\n\t\t\t\tbreak;\n\t\t\tcase Token::Function:\n\t\t\t\tnodes.push_back(parseFunctionDefinition(true));\n\t\t\t\tbreak;\n\t\t\tcase Token::ForAll:\n\t\t\t\tnodes.push_back(parseQuantifiedFunctionDefinition());\n\t\t\t\tbreak;\n\t\t\tcase Token::Event:\n\t\t\t\tnodes.push_back(parseEventDefinition());\n\t\t\t\tbreak;\n\t\t\tcase Token::Class:\n\t\t\t\tsolAssert(m_experimentalSolidityEnabledInCurrentSourceUnit);\n\t\t\t\tnodes.push_back(parseTypeClassDefinition());\n\t\t\t\tbreak;\n\t\t\tcase Token::Instantiation:\n\t\t\t\tsolAssert(m_experimentalSolidityEnabledInCurrentSourceUnit);\n\t\t\t\tnodes.push_back(parseTypeClassInstantiation());\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (\n\t\t\t\t\t// Workaround because `error` is not a keyword.\n\t\t\t\t\tm_scanner->currentToken() == Token::Identifier &&\n\t\t\t\t\tcurrentLiteral() == \"error\" &&\n\t\t\t\t\tm_scanner->peekNextToken() == Token::Identifier &&\n\t\t\t\t\tm_scanner->peekNextNextToken() == Token::LParen\n\t\t\t\t)\n\t\t\t\t\tnodes.push_back(parseErrorDefinition());\n\t\t\t\t// Constant variable.\n\t\t\t\telse if (variableDeclarationStart() && m_scanner->peekNextToken() != Token::EOS)\n\t\t\t\t{\n\t\t\t\t\tVarDeclParserOptions options;\n\t\t\t\t\toptions.kind = VarDeclKind::FileLevel;\n\t\t\t\t\toptions.allowInitialValue = true;\n\t\t\t\t\tnodes.push_back(parseVariableDeclaration(options));\n\t\t\t\t\texpectToken(Token::Semicolon);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tfatalParserError(7858_error, \"Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition.\");\n\t\t\t}\n\t\t}\n\t\tsolAssert(m_recursionDepth == 0, \"\");\n\t\treturn nodeFactory.createNode<SourceUnit>(findLicenseString(nodes), nodes, m_experimentalSolidityEnabledInCurrentSourceUnit);\n\t}\n\tcatch (FatalError const&)\n\t{\n\t\tif (!m_errorReporter.hasErrors())\n\t\t{\n\t\t\tstd::cerr << \"Unreported fatal error:\" << std::endl;\n\t\t\tstd::cerr << boost::current_exception_diagnostic_information() << std::endl;\n\t\t\tsolAssert(false, \"Unreported fatal error.\");\n\t\t}\n\t\treturn nullptr;\n\t}\n}\n\nvoid Parser::parsePragmaVersion(SourceLocation const& _location, std::vector<Token> const& _tokens, std::vector<std::string> const& _literals)\n{\n\tSemVerMatchExpressionParser parser(_tokens, _literals);\n\ttry\n\t{\n\t\tSemVerMatchExpression matchExpression = parser.parse();\n\t\tstatic SemVerVersion const currentVersion{std::string(VersionString)};\n\t\t// FIXME: only match for major version incompatibility\n\t\tif (!matchExpression.matches(currentVersion))\n\t\t\tm_errorReporter.fatalParserError(\n\t\t\t\t5333_error,\n\t\t\t\t_location,\n\t\t\t\t\"Source file requires different compiler version (current compiler is \" +\n\t\t\t\tstd::string(VersionString) + \") - note that nightly builds are considered to be \"\n\t\t\t\t\"strictly less than the released version\"\n\t\t\t);\n\t}\n\tcatch (SemVerError const& matchError)\n\t{\n\t\tm_errorReporter.fatalParserError(\n\t\t\t1684_error,\n\t\t\t_location,\n\t\t\t\"Invalid version pragma. \"s + matchError.what()\n\t\t);\n\t}\n}\n\nASTPointer<StructuredDocumentation> Parser::parseStructuredDocumentation()\n{\n\tif (!m_scanner->currentCommentLiteral().empty())\n\t{\n\t\tASTNodeFactory nodeFactory{*this};\n\t\tnodeFactory.setLocation(m_scanner->currentCommentLocation());\n\t\treturn nodeFactory.createNode<StructuredDocumentation>(\n\t\t\tstd::make_shared<ASTString>(m_scanner->currentCommentLiteral())\n\t\t);\n\t}\n\treturn nullptr;\n}\n\nASTPointer<PragmaDirective> Parser::parsePragmaDirective(bool const _finishedParsingTopLevelPragmas)\n{\n\tRecursionGuard recursionGuard(*this);\n\t// pragma anything* ;\n\t// Currently supported:\n\t// pragma solidity ^0.4.0 || ^0.3.0;\n\tASTNodeFactory nodeFactory(*this);\n\texpectToken(Token::Pragma);\n\tstd::vector<std::string> literals;\n\tstd::vector<Token> tokens;\n\n\tdo\n\t{\n\t\tToken token = m_scanner->currentToken();\n\t\tif (token == Token::Illegal)\n\t\t\tparserError(6281_error, \"Token incompatible with Solidity parser as part of pragma directive.\");\n\t\telse\n\t\t{\n\t\t\tstd::string literal = m_scanner->currentLiteral();\n\t\t\tif (literal.empty() && TokenTraits::toString(token))\n\t\t\t\tliteral = TokenTraits::toString(token);\n\t\t\tliterals.push_back(literal);\n\t\t\ttokens.push_back(token);\n\t\t}\n\t\tadvance();\n\t}\n\twhile (m_scanner->currentToken() != Token::Semicolon && m_scanner->currentToken() != Token::EOS);\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::Semicolon);\n\n\tif (literals.size() >= 1 && literals[0] == \"solidity\")\n\t{\n\t\tparsePragmaVersion(\n\t\t\tnodeFactory.location(),\n\t\t\tstd::vector<Token>(tokens.begin() + 1, tokens.end()),\n\t\t\tstd::vector<std::string>(literals.begin() + 1, literals.end())\n\t\t);\n\t}\n\n\tif (literals.size() >= 2 && literals[0] == \"experimental\" && literals[1] == \"solidity\")\n\t{\n\t\tif (m_evmVersion < EVMVersion::constantinople())\n\t\t\tfatalParserError(7637_error, \"Experimental solidity requires Constantinople EVM version at the minimum.\");\n\t\tif (_finishedParsingTopLevelPragmas)\n\t\t\tfatalParserError(8185_error, \"Experimental pragma \\\"solidity\\\" can only be set at the beginning of the source unit.\");\n\t\tm_experimentalSolidityEnabledInCurrentSourceUnit = true;\n\t}\n\n\treturn nodeFactory.createNode<PragmaDirective>(tokens, literals);\n}\n\nASTPointer<ImportDirective> Parser::parseImportDirective()\n{\n\tRecursionGuard recursionGuard(*this);\n\t// import \"abc\" [as x];\n\t// import * as x from \"abc\";\n\t// import {a as b, c} from \"abc\";\n\tASTNodeFactory nodeFactory(*this);\n\texpectToken(Token::Import);\n\tASTPointer<ASTString> path;\n\tASTPointer<ASTString> unitAlias = std::make_shared<std::string>();\n\tSourceLocation unitAliasLocation{};\n\tImportDirective::SymbolAliasList symbolAliases;\n\n\tif (isQuotedPath() || isStdlibPath())\n\t{\n\t\tpath = isQuotedPath() ? getLiteralAndAdvance() : getStdlibImportPathAndAdvance();\n\t\tif (m_scanner->currentToken() == Token::As)\n\t\t{\n\t\t\tadvance();\n\t\t\ttie(unitAlias, unitAliasLocation) = expectIdentifierWithLocation();\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (m_scanner->currentToken() == Token::LBrace)\n\t\t{\n\t\t\tadvance();\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tASTPointer<ASTString> alias;\n\t\t\t\tSourceLocation aliasLocation = currentLocation();\n\t\t\t\tASTPointer<Identifier> id = parseIdentifier();\n\t\t\t\tif (m_scanner->currentToken() == Token::As)\n\t\t\t\t{\n\t\t\t\t\texpectToken(Token::As);\n\t\t\t\t\ttie(alias, aliasLocation) = expectIdentifierWithLocation();\n\t\t\t\t}\n\t\t\t\tsymbolAliases.emplace_back(ImportDirective::SymbolAlias{std::move(id), std::move(alias), aliasLocation});\n\t\t\t\tif (m_scanner->currentToken() != Token::Comma)\n\t\t\t\t\tbreak;\n\t\t\t\tadvance();\n\t\t\t}\n\t\t\texpectToken(Token::RBrace);\n\t\t}\n\t\telse if (m_scanner->currentToken() == Token::Mul)\n\t\t{\n\t\t\tadvance();\n\t\t\texpectToken(Token::As);\n\t\t\ttie(unitAlias, unitAliasLocation) = expectIdentifierWithLocation();\n\t\t}\n\t\telse\n\t\t\tfatalParserError(9478_error, \"Expected string literal (path), \\\"*\\\" or alias list.\");\n\t\t// \"from\" is not a keyword but parsed as an identifier because of backwards\n\t\t// compatibility and because it is a really common word.\n\t\tif (m_scanner->currentToken() != Token::Identifier || m_scanner->currentLiteral() != \"from\")\n\t\t\tfatalParserError(8208_error, \"Expected \\\"from\\\".\");\n\t\tadvance();\n\t\tif (!isQuotedPath() && !isStdlibPath())\n\t\t\tfatalParserError(6845_error, \"Expected import path.\");\n\t\tpath = isQuotedPath() ? getLiteralAndAdvance() : getStdlibImportPathAndAdvance();\n\t}\n\tif (path->empty())\n\t\tfatalParserError(6326_error, \"Import path cannot be empty.\");\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::Semicolon);\n\treturn nodeFactory.createNode<ImportDirective>(path, unitAlias, unitAliasLocation, std::move(symbolAliases));\n}\n\nstd::pair<ContractKind, bool> Parser::parseContractKind()\n{\n\tContractKind kind;\n\tbool abstract = false;\n\tif (m_scanner->currentToken() == Token::Abstract)\n\t{\n\t\tabstract = true;\n\t\tadvance();\n\t}\n\tswitch (m_scanner->currentToken())\n\t{\n\tcase Token::Interface:\n\t\tkind = ContractKind::Interface;\n\t\tbreak;\n\tcase Token::Contract:\n\t\tkind = ContractKind::Contract;\n\t\tbreak;\n\tcase Token::Library:\n\t\tkind = ContractKind::Library;\n\t\tbreak;\n\tdefault:\n\t\tparserError(3515_error, \"Expected keyword \\\"contract\\\", \\\"interface\\\" or \\\"library\\\".\");\n\t\treturn std::make_pair(ContractKind::Contract, abstract);\n\t}\n\tadvance();\n\treturn std::make_pair(kind, abstract);\n}\n\nASTPointer<StorageLayoutSpecifier> Parser::parseStorageLayoutSpecifier()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<ASTString> layoutIdentifier = expectIdentifierToken();\n\tsolAssert(layoutIdentifier && *layoutIdentifier == \"layout\");\n\tif (\n\t\tm_scanner->currentToken() != Token::Identifier ||\n\t\tm_scanner->currentLiteral() != \"at\"\n\t)\n\t\tm_errorReporter.parserError(\n\t\t\t1994_error,\n\t\t\tm_scanner->currentLocation(),\n\t\t\t\"Expected \\'at\\' but got \" + tokenName(m_scanner->currentToken())\n\t\t);\n\n\tadvance();\n\tASTPointer<Expression> baseSlotExpression = parseExpression();\n\tsolAssert(baseSlotExpression);\n\tnodeFactory.setEndPositionFromNode(baseSlotExpression);\n\treturn nodeFactory.createNode<StorageLayoutSpecifier>(\n\t\tbaseSlotExpression\n\t);\n}\n\nASTPointer<ContractDefinition> Parser::parseContractDefinition()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<ASTString> name =  nullptr;\n\tSourceLocation nameLocation{};\n\tASTPointer<StructuredDocumentation> documentation;\n\tstd::vector<ASTPointer<InheritanceSpecifier>> baseContracts;\n\tstd::vector<ASTPointer<ASTNode>> subNodes;\n\tstd::pair<ContractKind, bool> contractKind{};\n\tASTPointer<StorageLayoutSpecifier> storageLayoutSpecifier;\n\tdocumentation = parseStructuredDocumentation();\n\tcontractKind = parseContractKind();\n\tstd::tie(name, nameLocation) = expectIdentifierWithLocation();\n\twhile (true)\n\t{\n\t\tif (m_scanner->currentToken() == Token::Is)\n\t\t{\n\t\t\tif (baseContracts.size() != 0)\n\t\t\t\tm_errorReporter.parserError(\n\t\t\t\t\t6668_error,\n\t\t\t\t\tm_scanner->currentLocation(),\n\t\t\t\t\tSecondarySourceLocation().append(\"Previous list:\", baseContracts[0]->location()),\n\t\t\t\t\t\"More than one inheritance list.\"\n\t\t\t\t);\n\t\t\tdo\n\t\t\t{\n\t\t\t\tadvance();\n\t\t\t\tbaseContracts.push_back(parseInheritanceSpecifier());\n\t\t\t}\n\t\t\twhile (m_scanner->currentToken() == Token::Comma);\n\t\t}\n\t\telse if (\n\t\t\tm_scanner->currentToken() == Token::Identifier &&\n\t\t\tm_scanner->currentLiteral() == \"layout\" &&\n\t\t\tcontractKind.first == ContractKind::Contract\n\t\t)\n\t\t{\n\t\t\tif (storageLayoutSpecifier)\n\t\t\t\tm_errorReporter.parserError(\n\t\t\t\t\t8714_error,\n\t\t\t\t\tm_scanner->currentLocation(),\n\t\t\t\t\tSecondarySourceLocation().append(\"Previous definition:\", storageLayoutSpecifier->location()),\n\t\t\t\t\t\"More than one storage layout definition.\"\n\t\t\t\t);\n\n\t\t\tstorageLayoutSpecifier = parseStorageLayoutSpecifier();\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n\n\tif (storageLayoutSpecifier && baseContracts.size() > 0)\n\t{\n\t\tsolAssert(!storageLayoutSpecifier->location().intersects(baseContracts[0]->location()));\n\t\tsolAssert(!baseContracts[0]->location().intersects(storageLayoutSpecifier->location()));\n\t}\n\n\texpectToken(Token::LBrace);\n\twhile (true)\n\t{\n\t\tToken currentTokenValue = m_scanner->currentToken();\n\t\tif (currentTokenValue == Token::RBrace)\n\t\t\tbreak;\n\t\telse if (\n\t\t\t(currentTokenValue == Token::Function && m_scanner->peekNextToken() != Token::LParen) ||\n\t\t\tcurrentTokenValue == Token::Constructor ||\n\t\t\tcurrentTokenValue == Token::Receive ||\n\t\t\tcurrentTokenValue == Token::Fallback\n\t\t)\n\t\t\tsubNodes.push_back(parseFunctionDefinition());\n\t\telse if (currentTokenValue == Token::Struct)\n\t\t\tsubNodes.push_back(parseStructDefinition());\n\t\telse if (currentTokenValue == Token::Enum)\n\t\t\tsubNodes.push_back(parseEnumDefinition());\n\t\telse if (currentTokenValue == Token::Type)\n\t\t\tsubNodes.push_back(parseUserDefinedValueTypeDefinition());\n\t\telse if (\n\t\t\t// Workaround because `error` is not a keyword.\n\t\t\tcurrentTokenValue == Token::Identifier &&\n\t\t\tcurrentLiteral() == \"error\" &&\n\t\t\tm_scanner->peekNextToken() == Token::Identifier &&\n\t\t\tm_scanner->peekNextNextToken() == Token::LParen\n\t\t)\n\t\t\tsubNodes.push_back(parseErrorDefinition());\n\t\telse if (variableDeclarationStart())\n\t\t{\n\t\t\tVarDeclParserOptions options;\n\t\t\toptions.kind = VarDeclKind::State;\n\t\t\toptions.allowInitialValue = true;\n\t\t\tsubNodes.push_back(parseVariableDeclaration(options));\n\t\t\texpectToken(Token::Semicolon);\n\t\t}\n\t\telse if (currentTokenValue == Token::Modifier)\n\t\t\tsubNodes.push_back(parseModifierDefinition());\n\t\telse if (currentTokenValue == Token::Event)\n\t\t\tsubNodes.push_back(parseEventDefinition());\n\t\telse if (currentTokenValue == Token::Using)\n\t\t\tsubNodes.push_back(parseUsingDirective());\n\t\telse\n\t\t\tfatalParserError(9182_error, \"Function, variable, struct or modifier declaration expected.\");\n\t}\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::RBrace);\n\treturn nodeFactory.createNode<ContractDefinition>(\n\t\tname,\n\t\tnameLocation,\n\t\tdocumentation,\n\t\tbaseContracts,\n\t\tsubNodes,\n\t\tcontractKind.first,\n\t\tcontractKind.second,\n\t\tstorageLayoutSpecifier\n\t);\n}\n\nASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<IdentifierPath> name(parseIdentifierPath());\n\tstd::unique_ptr<std::vector<ASTPointer<Expression>>> arguments;\n\tif (m_scanner->currentToken() == Token::LParen)\n\t{\n\t\tadvance();\n\t\targuments = std::make_unique<std::vector<ASTPointer<Expression>>>(parseFunctionCallListArguments());\n\t\tnodeFactory.markEndPosition();\n\t\texpectToken(Token::RParen);\n\t}\n\telse\n\t\tnodeFactory.setEndPositionFromNode(name);\n\treturn nodeFactory.createNode<InheritanceSpecifier>(name, std::move(arguments));\n}\n\nVisibility Parser::parseVisibilitySpecifier()\n{\n\tVisibility visibility(Visibility::Default);\n\tToken token = m_scanner->currentToken();\n\tswitch (token)\n\t{\n\t\tcase Token::Public:\n\t\t\tvisibility = Visibility::Public;\n\t\t\tbreak;\n\t\tcase Token::Internal:\n\t\t\tvisibility = Visibility::Internal;\n\t\t\tbreak;\n\t\tcase Token::Private:\n\t\t\tvisibility = Visibility::Private;\n\t\t\tbreak;\n\t\tcase Token::External:\n\t\t\tvisibility = Visibility::External;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tsolAssert(false, \"Invalid visibility specifier.\");\n\t}\n\tadvance();\n\treturn visibility;\n}\n\nASTPointer<OverrideSpecifier> Parser::parseOverrideSpecifier()\n{\n\tsolAssert(m_scanner->currentToken() == Token::Override, \"\");\n\n\tASTNodeFactory nodeFactory(*this);\n\tstd::vector<ASTPointer<IdentifierPath>> overrides;\n\n\tnodeFactory.markEndPosition();\n\tadvance();\n\n\tif (m_scanner->currentToken() == Token::LParen)\n\t{\n\t\tadvance();\n\t\twhile (true)\n\t\t{\n\t\t\toverrides.push_back(parseIdentifierPath());\n\n\t\t\tif (m_scanner->currentToken() == Token::RParen)\n\t\t\t\tbreak;\n\n\t\t\texpectToken(Token::Comma);\n\t\t}\n\n\t\tnodeFactory.markEndPosition();\n\t\texpectToken(Token::RParen);\n\t}\n\n\treturn nodeFactory.createNode<OverrideSpecifier>(std::move(overrides));\n}\n\nStateMutability Parser::parseStateMutability()\n{\n\tStateMutability stateMutability(StateMutability::NonPayable);\n\tToken token = m_scanner->currentToken();\n\tswitch (token)\n\t{\n\t\tcase Token::Payable:\n\t\t\tstateMutability = StateMutability::Payable;\n\t\t\tbreak;\n\t\tcase Token::View:\n\t\t\tstateMutability = StateMutability::View;\n\t\t\tbreak;\n\t\tcase Token::Pure:\n\t\t\tstateMutability = StateMutability::Pure;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tsolAssert(false, \"Invalid state mutability specifier.\");\n\t}\n\tadvance();\n\treturn stateMutability;\n}\n\nParser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _isStateVariable)\n{\n\tRecursionGuard recursionGuard(*this);\n\tFunctionHeaderParserResult result;\n\n\tVarDeclParserOptions options;\n\toptions.allowLocationSpecifier = true;\n\tresult.parameters = parseParameterList(options);\n\twhile (true)\n\t{\n\t\tToken token = m_scanner->currentToken();\n\t\tif (!_isStateVariable && token == Token::Identifier)\n\t\t\tresult.modifiers.push_back(parseModifierInvocation());\n\t\telse if (TokenTraits::isVisibilitySpecifier(token))\n\t\t{\n\t\t\tif (result.visibility != Visibility::Default)\n\t\t\t{\n\t\t\t\t// There is the special case of a public state variable of function type.\n\t\t\t\t// Detect this and return early.\n\t\t\t\tif (_isStateVariable && (result.visibility == Visibility::External || result.visibility == Visibility::Internal))\n\t\t\t\t\tbreak;\n\t\t\t\tparserError(\n\t\t\t\t\t9439_error,\n\t\t\t\t\t\"Visibility already specified as \\\"\" +\n\t\t\t\t\tDeclaration::visibilityToString(result.visibility) +\n\t\t\t\t\t\"\\\".\"\n\t\t\t\t);\n\t\t\t\tadvance();\n\t\t\t}\n\t\t\telse\n\t\t\t\tresult.visibility = parseVisibilitySpecifier();\n\t\t}\n\t\telse if (TokenTraits::isStateMutabilitySpecifier(token))\n\t\t{\n\t\t\tif (result.stateMutability != StateMutability::NonPayable)\n\t\t\t{\n\t\t\t\tparserError(\n\t\t\t\t\t9680_error,\n\t\t\t\t\t\"State mutability already specified as \\\"\" +\n\t\t\t\t\tstateMutabilityToString(result.stateMutability) +\n\t\t\t\t\t\"\\\".\"\n\t\t\t\t);\n\t\t\t\tadvance();\n\t\t\t}\n\t\t\telse\n\t\t\t\tresult.stateMutability = parseStateMutability();\n\t\t}\n\t\telse if (!_isStateVariable && token == Token::Override)\n\t\t{\n\t\t\tif (result.overrides)\n\t\t\t\tparserError(1827_error, \"Override already specified.\");\n\n\t\t\tresult.overrides = parseOverrideSpecifier();\n\t\t}\n\t\telse if (!_isStateVariable && token == Token::Virtual)\n\t\t{\n\t\t\tif (result.isVirtual)\n\t\t\t\tparserError(6879_error, \"Virtual already specified.\");\n\n\t\t\tresult.isVirtual = true;\n\t\t\tadvance();\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n\tif (m_experimentalSolidityEnabledInCurrentSourceUnit)\n\t{\n\t\tif (m_scanner->currentToken() == Token::RightArrow)\n\t\t{\n\t\t\tadvance();\n\t\t\tresult.experimentalReturnExpression = parseBinaryExpression();\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (m_scanner->currentToken() == Token::Returns)\n\t\t{\n\t\t\tbool const permitEmptyParameterList = m_experimentalSolidityEnabledInCurrentSourceUnit;\n\t\t\tadvance();\n\t\t\tresult.returnParameters = parseParameterList(options, permitEmptyParameterList);\n\t\t}\n\t\telse\n\t\t\tresult.returnParameters = createEmptyParameterList();\n\t}\n\treturn result;\n}\n\nASTPointer<ForAllQuantifier> Parser::parseQuantifiedFunctionDefinition()\n{\n\tsolAssert(m_experimentalSolidityEnabledInCurrentSourceUnit);\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\n\texpectToken(Token::ForAll);\n\tASTPointer<ParameterList> typeVariableDeclarations = parseParameterList();\n\tnodeFactory.markEndPosition();\n\n\tif (m_scanner->currentToken() != Token::Function)\n\t\tfatalParserError(5709_error, \"Expected a function definition.\");\n\n\tASTPointer<FunctionDefinition> quantifiedFunction = parseFunctionDefinition(true /* _freeFunction */, true /* _allowBody */);\n\n\treturn nodeFactory.createNode<ForAllQuantifier>(\n\t\tstd::move(typeVariableDeclarations),\n\t\tstd::move(quantifiedFunction)\n\t);\n}\n\nASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _freeFunction, bool _allowBody)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();\n\n\tToken kind = m_scanner->currentToken();\n\tASTPointer<ASTString> name;\n\tSourceLocation nameLocation;\n\tif (kind == Token::Function)\n\t{\n\t\tadvance();\n\t\tif (\n\t\t\tm_scanner->currentToken() == Token::Constructor ||\n\t\t\tm_scanner->currentToken() == Token::Fallback ||\n\t\t\tm_scanner->currentToken() == Token::Receive\n\t\t)\n\t\t{\n\t\t\tstd::string expected = std::map<Token, std::string>{\n\t\t\t\t{Token::Constructor, \"constructor\"},\n\t\t\t\t{Token::Fallback, \"fallback function\"},\n\t\t\t\t{Token::Receive, \"receive function\"},\n\t\t\t}.at(m_scanner->currentToken());\n\t\t\tnameLocation = currentLocation();\n\t\t\tname = std::make_shared<ASTString>(TokenTraits::toString(m_scanner->currentToken()));\n\t\t\tstd::string message{\n\t\t\t\t\"This function is named \\\"\" + *name + \"\\\" but is not the \" + expected + \" of the contract. \"\n\t\t\t\t\"If you intend this to be a \" + expected + \", use \\\"\" + *name + \"(...) { ... }\\\" without \"\n\t\t\t\t\"the \\\"function\\\" keyword to define it.\"\n\t\t\t};\n\t\t\tif (m_scanner->currentToken() == Token::Constructor)\n\t\t\t\tparserError(3323_error, message);\n\t\t\telse\n\t\t\t\tparserWarning(3445_error, message);\n\t\t\tadvance();\n\t\t}\n\t\telse\n\t\t\ttie(name, nameLocation) = expectIdentifierWithLocation();\n\t}\n\telse\n\t{\n\t\tsolAssert(kind == Token::Constructor || kind == Token::Fallback || kind == Token::Receive, \"\");\n\t\tadvance();\n\t\tname = std::make_shared<ASTString>();\n\t}\n\n\tFunctionHeaderParserResult header = parseFunctionHeader(false);\n\n\tif (m_experimentalSolidityEnabledInCurrentSourceUnit)\n\t\tsolAssert(!header.returnParameters);\n\telse\n\t\tsolAssert(!header.experimentalReturnExpression);\n\n\tASTPointer<Block> block;\n\tnodeFactory.markEndPosition();\n\tif (!_allowBody)\n\t\texpectToken(Token::Semicolon);\n\telse if (m_scanner->currentToken() == Token::Semicolon)\n\t\tadvance();\n\telse\n\t{\n\t\tblock = parseBlock();\n\t\tnodeFactory.setEndPositionFromNode(block);\n\t}\n\treturn nodeFactory.createNode<FunctionDefinition>(\n\t\tname,\n\t\tnameLocation,\n\t\theader.visibility,\n\t\theader.stateMutability,\n\t\t_freeFunction,\n\t\tkind,\n\t\theader.isVirtual,\n\t\theader.overrides,\n\t\tdocumentation,\n\t\theader.parameters,\n\t\theader.modifiers,\n\t\theader.returnParameters,\n\t\tblock,\n\t\theader.experimentalReturnExpression\n\t);\n}\n\nASTPointer<StructDefinition> Parser::parseStructDefinition()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();\n\texpectToken(Token::Struct);\n\tauto [name, nameLocation] = expectIdentifierWithLocation();\n\tstd::vector<ASTPointer<VariableDeclaration>> members;\n\texpectToken(Token::LBrace);\n\twhile (m_scanner->currentToken() != Token::RBrace)\n\t{\n\t\tmembers.push_back(parseVariableDeclaration());\n\t\texpectToken(Token::Semicolon);\n\t}\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::RBrace);\n\treturn nodeFactory.createNode<StructDefinition>(std::move(name), std::move(nameLocation), std::move(members), std::move(documentation));\n}\n\nASTPointer<EnumValue> Parser::parseEnumValue()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();\n\tnodeFactory.markEndPosition();\n\treturn nodeFactory.createNode<EnumValue>(expectIdentifierToken(), documentation);\n}\n\nASTPointer<EnumDefinition> Parser::parseEnumDefinition()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();\n\texpectToken(Token::Enum);\n\tauto [name, nameLocation] = expectIdentifierWithLocation();\n\tstd::vector<ASTPointer<EnumValue>> members;\n\texpectToken(Token::LBrace);\n\n\twhile (m_scanner->currentToken() != Token::RBrace)\n\t{\n\t\tmembers.push_back(parseEnumValue());\n\t\tif (m_scanner->currentToken() == Token::RBrace)\n\t\t\tbreak;\n\t\texpectToken(Token::Comma);\n\t\tif (m_scanner->currentToken() != Token::Identifier)\n\t\t\tfatalParserError(1612_error, \"Expected identifier after ','\");\n\t}\n\tif (members.empty())\n\t\tparserError(3147_error, \"Enum with no members is not allowed.\");\n\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::RBrace);\n\treturn nodeFactory.createNode<EnumDefinition>(name, nameLocation, members, documentation);\n}\n\nASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(\n\tVarDeclParserOptions const& _options,\n\tASTPointer<TypeName> const& _lookAheadArrayType\n)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory = _lookAheadArrayType ?\n\t\tASTNodeFactory(*this, _lookAheadArrayType) : ASTNodeFactory(*this);\n\n\tASTPointer<StructuredDocumentation> const documentation = parseStructuredDocumentation();\n\tASTPointer<TypeName> type = _lookAheadArrayType ? _lookAheadArrayType : parseTypeName();\n\tnodeFactory.setEndPositionFromNode(type);\n\n\tif (dynamic_cast<FunctionTypeName*>(type.get()) && _options.kind == VarDeclKind::State && m_scanner->currentToken() == Token::LBrace)\n\t\tfatalParserError(\n\t\t\t2915_error,\n\t\t\t\"Expected a state variable declaration. If you intended this as a fallback function \"\n\t\t\t\"or a function to handle plain ether transactions, use the \\\"fallback\\\" keyword \"\n\t\t\t\"or the \\\"receive\\\" keyword instead.\"\n\t\t);\n\n\tbool isIndexed = false;\n\tVariableDeclaration::Mutability mutability = VariableDeclaration::Mutability::Mutable;\n\tASTPointer<OverrideSpecifier> overrides = nullptr;\n\tVisibility visibility(Visibility::Default);\n\tVariableDeclaration::Location location = VariableDeclaration::Location::Unspecified;\n\tASTPointer<ASTString> identifier;\n\tSourceLocation nameLocation{};\n\n\twhile (true)\n\t{\n\t\tToken token = m_scanner->currentToken();\n\t\tif (_options.kind == VarDeclKind::State && TokenTraits::isVariableVisibilitySpecifier(token))\n\t\t{\n\t\t\tnodeFactory.markEndPosition();\n\t\t\tif (visibility != Visibility::Default)\n\t\t\t{\n\t\t\t\tparserError(\n\t\t\t\t\t4110_error,\n\t\t\t\t\t\"Visibility already specified as \\\"\" +\n\t\t\t\t\tDeclaration::visibilityToString(visibility) +\n\t\t\t\t\t\"\\\".\"\n\t\t\t\t);\n\t\t\t\tadvance();\n\t\t\t}\n\t\t\telse\n\t\t\t\tvisibility = parseVisibilitySpecifier();\n\t\t}\n\t\telse if (_options.kind == VarDeclKind::State && token == Token::Override)\n\t\t{\n\t\t\tif (overrides)\n\t\t\t\tparserError(9125_error, \"Override already specified.\");\n\n\t\t\toverrides = parseOverrideSpecifier();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (_options.allowIndexed && token == Token::Indexed)\n\t\t\t{\n\t\t\t\tif (isIndexed)\n\t\t\t\t\tparserError(5399_error, \"Indexed already specified.\");\n\n\t\t\t\tisIndexed = true;\n\t\t\t}\n\t\t\telse if (token == Token::Constant || token == Token::Immutable)\n\t\t\t{\n\t\t\t\tif (mutability != VariableDeclaration::Mutability::Mutable)\n\t\t\t\t\tparserError(\n\t\t\t\t\t\t3109_error,\n\t\t\t\t\t\tstd::string(\"Mutability already set to \") +\n\t\t\t\t\t\t(mutability == VariableDeclaration::Mutability::Constant ? \"\\\"constant\\\"\" : \"\\\"immutable\\\"\")\n\t\t\t\t\t);\n\t\t\t\telse if (token == Token::Constant)\n\t\t\t\t\tmutability = VariableDeclaration::Mutability::Constant;\n\t\t\t\telse if (token == Token::Immutable)\n\t\t\t\t\tmutability = VariableDeclaration::Mutability::Immutable;\n\t\t\t}\n\t\t\telse if (_options.allowLocationSpecifier && TokenTraits::isLocationSpecifier(token))\n\t\t\t{\n\t\t\t\tif (location != VariableDeclaration::Location::Unspecified)\n\t\t\t\t\tparserError(3548_error, \"Location already specified.\");\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tswitch (token)\n\t\t\t\t\t{\n\t\t\t\t\tcase Token::Storage:\n\t\t\t\t\t\tlocation = VariableDeclaration::Location::Storage;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase Token::Memory:\n\t\t\t\t\t\tlocation = VariableDeclaration::Location::Memory;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase Token::CallData:\n\t\t\t\t\t\tlocation = VariableDeclaration::Location::CallData;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsolAssert(false, \"Unknown data location.\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (\n\t\t\t\t_options.kind == VarDeclKind::State &&\n\t\t\t\ttoken == Token::Identifier &&\n\t\t\t\tm_scanner->currentLiteral() == \"transient\" &&\n\t\t\t\tm_scanner->peekNextToken() != Token::Assign &&\n\t\t\t\tm_scanner->peekNextToken() != Token::Semicolon\n\t\t\t)\n\t\t\t{\n\t\t\t\tif (location != VariableDeclaration::Location::Unspecified)\n\t\t\t\t\tparserError(ErrorId{3548}, \"Location already specified.\");\n\t\t\t\telse\n\t\t\t\t\tlocation = VariableDeclaration::Location::Transient;\n\t\t\t}\n\t\t\telse\n\t\t\t\tbreak;\n\t\t\tnodeFactory.markEndPosition();\n\t\t\tadvance();\n\t\t}\n\t}\n\n\tif (_options.allowEmptyName && m_scanner->currentToken() != Token::Identifier)\n\t\tidentifier = std::make_shared<ASTString>(\"\");\n\telse\n\t{\n\t\tnodeFactory.markEndPosition();\n\t\ttie(identifier, nameLocation) = expectIdentifierWithLocation();\n\t}\n\tASTPointer<Expression> value;\n\tif (_options.allowInitialValue)\n\t{\n\t\tif (m_scanner->currentToken() == Token::Assign)\n\t\t{\n\t\t\tadvance();\n\t\t\tvalue = parseExpression();\n\t\t\tnodeFactory.setEndPositionFromNode(value);\n\t\t}\n\t}\n\treturn nodeFactory.createNode<VariableDeclaration>(\n\t\ttype,\n\t\tidentifier,\n\t\tnameLocation,\n\t\tvalue,\n\t\tvisibility,\n\t\tdocumentation,\n\t\tisIndexed,\n\t\tmutability,\n\t\toverrides,\n\t\tlocation\n\t);\n}\n\nASTPointer<ModifierDefinition> Parser::parseModifierDefinition()\n{\n\tRecursionGuard recursionGuard(*this);\n\tScopeGuard resetModifierFlag([this]() { m_insideModifier = false; });\n\tm_insideModifier = true;\n\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();\n\n\texpectToken(Token::Modifier);\n\tauto [name, nameLocation] = expectIdentifierWithLocation();\n\tASTPointer<ParameterList> parameters;\n\tif (m_scanner->currentToken() == Token::LParen)\n\t{\n\t\tVarDeclParserOptions options;\n\t\toptions.allowLocationSpecifier = true;\n\t\tparameters = parseParameterList(options);\n\t}\n\telse\n\t\tparameters = createEmptyParameterList();\n\n\tASTPointer<OverrideSpecifier> overrides;\n\tbool isVirtual = false;\n\n\twhile (true)\n\t{\n\t\tif (m_scanner->currentToken() == Token::Override)\n\t\t{\n\t\t\tif (overrides)\n\t\t\t\tparserError(9102_error, \"Override already specified.\");\n\t\t\toverrides = parseOverrideSpecifier();\n\t\t}\n\t\telse if (m_scanner->currentToken() == Token::Virtual)\n\t\t{\n\t\t\tif (isVirtual)\n\t\t\t\tparserError(2662_error, \"Virtual already specified.\");\n\n\t\t\tisVirtual = true;\n\t\t\tadvance();\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n\n\tASTPointer<Block> block;\n\tnodeFactory.markEndPosition();\n\tif (m_scanner->currentToken() != Token::Semicolon)\n\t{\n\t\tblock = parseBlock();\n\t\tnodeFactory.setEndPositionFromNode(block);\n\t}\n\telse\n\t\tadvance(); // just consume the ';'\n\n\treturn nodeFactory.createNode<ModifierDefinition>(name, nameLocation, documentation, parameters, isVirtual, overrides, block);\n}\n\nstd::pair<ASTPointer<ASTString>, SourceLocation> Parser::expectIdentifierWithLocation()\n{\n\tSourceLocation nameLocation = currentLocation();\n\tASTPointer<ASTString> name = expectIdentifierToken();\n\n\treturn {std::move(name), std::move(nameLocation)};\n}\n\nASTPointer<EventDefinition> Parser::parseEventDefinition()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();\n\n\texpectToken(Token::Event);\n\tauto [name, nameLocation] = expectIdentifierWithLocation();\n\n\tVarDeclParserOptions options;\n\toptions.allowIndexed = true;\n\tASTPointer<ParameterList> parameters = parseParameterList(options);\n\n\tbool anonymous = false;\n\tif (m_scanner->currentToken() == Token::Anonymous)\n\t{\n\t\tanonymous = true;\n\t\tadvance();\n\t}\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::Semicolon);\n\treturn nodeFactory.createNode<EventDefinition>(name, nameLocation, documentation, parameters, anonymous);\n}\n\nASTPointer<ErrorDefinition> Parser::parseErrorDefinition()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();\n\n\tsolAssert(*expectIdentifierToken() == \"error\", \"\");\n\tauto&& [name, nameLocation] = expectIdentifierWithLocation();\n\n\tASTPointer<ParameterList> parameters = parseParameterList({});\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::Semicolon);\n\treturn nodeFactory.createNode<ErrorDefinition>(name, std::move(nameLocation), documentation, parameters);\n}\n\nASTPointer<UsingForDirective> Parser::parseUsingDirective()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\n\texpectToken(Token::Using);\n\n\tstd::vector<ASTPointer<IdentifierPath>> functions;\n\tstd::vector<std::optional<Token>> operators;\n\tbool const usesBraces = m_scanner->currentToken() == Token::LBrace;\n\tif (usesBraces)\n\t{\n\t\tdo\n\t\t{\n\t\t\tadvance();\n\t\t\tfunctions.emplace_back(parseIdentifierPath());\n\t\t\tif (m_scanner->currentToken() == Token::As)\n\t\t\t{\n\t\t\t\tadvance();\n\t\t\t\tToken operator_ = m_scanner->currentToken();\n\t\t\t\tif (!util::contains(userDefinableOperators, operator_))\n\t\t\t\t{\n\t\t\t\t\tstd::string operatorName;\n\t\t\t\t\tif (!m_scanner->currentLiteral().empty())\n\t\t\t\t\t\toperatorName = m_scanner->currentLiteral();\n\t\t\t\t\telse if (char const* tokenString = TokenTraits::toString(operator_))\n\t\t\t\t\t\toperatorName = std::string(tokenString);\n\n\t\t\t\t\tparserError(\n\t\t\t\t\t\t4403_error,\n\t\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\t\"Not a user-definable operator: {}. Only the following operators can be user-defined: {}\",\n\t\t\t\t\t\t\toperatorName,\n\t\t\t\t\t\t\tutil::joinHumanReadable(userDefinableOperators | ranges::views::transform([](Token _t) { return std::string{TokenTraits::toString(_t)}; }))\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\toperators.emplace_back(operator_);\n\t\t\t\tadvance();\n\t\t\t}\n\t\t\telse\n\t\t\t\toperators.emplace_back(std::nullopt);\n\t\t}\n\t\twhile (m_scanner->currentToken() == Token::Comma);\n\t\texpectToken(Token::RBrace);\n\t}\n\telse\n\t{\n\t\tfunctions.emplace_back(parseIdentifierPath());\n\t\toperators.emplace_back(std::nullopt);\n\t}\n\n\tASTPointer<TypeName> typeName;\n\texpectToken(Token::For);\n\tif (m_scanner->currentToken() == Token::Mul)\n\t\tadvance();\n\telse\n\t\ttypeName = parseTypeName();\n\tbool global = false;\n\tif (m_scanner->currentToken() == Token::Identifier && currentLiteral() == \"global\")\n\t{\n\t\tglobal = true;\n\t\tadvance();\n\t}\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::Semicolon);\n\treturn nodeFactory.createNode<UsingForDirective>(std::move(functions), std::move(operators), usesBraces, typeName, global);\n}\n\nASTPointer<ModifierInvocation> Parser::parseModifierInvocation()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<IdentifierPath> name(parseIdentifierPath());\n\tstd::unique_ptr<std::vector<ASTPointer<Expression>>> arguments;\n\tif (m_scanner->currentToken() == Token::LParen)\n\t{\n\t\tadvance();\n\t\targuments = std::make_unique<std::vector<ASTPointer<Expression>>>(parseFunctionCallListArguments());\n\t\tnodeFactory.markEndPosition();\n\t\texpectToken(Token::RParen);\n\t}\n\telse\n\t\tnodeFactory.setEndPositionFromNode(name);\n\treturn nodeFactory.createNode<ModifierInvocation>(name, std::move(arguments));\n}\n\nASTPointer<Identifier> Parser::parseIdentifier()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tnodeFactory.markEndPosition();\n\treturn nodeFactory.createNode<Identifier>(expectIdentifierToken());\n}\n\nASTPointer<Identifier> Parser::parseIdentifierOrAddress()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tnodeFactory.markEndPosition();\n\treturn nodeFactory.createNode<Identifier>(expectIdentifierTokenOrAddress());\n}\n\nASTPointer<UserDefinedTypeName> Parser::parseUserDefinedTypeName()\n{\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<IdentifierPath> identifierPath = parseIdentifierPath();\n\tnodeFactory.setEndPositionFromNode(identifierPath);\n\treturn nodeFactory.createNode<UserDefinedTypeName>(identifierPath);\n}\n\nASTPointer<UserDefinedValueTypeDefinition> Parser::parseUserDefinedValueTypeDefinition()\n{\n\tASTNodeFactory nodeFactory(*this);\n\texpectToken(Token::Type);\n\tauto&& [name, nameLocation] = expectIdentifierWithLocation();\n\texpectToken(Token::Is);\n\tASTPointer<TypeName> typeName = parseTypeName();\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::Semicolon);\n\treturn nodeFactory.createNode<UserDefinedValueTypeDefinition>(\n\t\tname,\n\t\tstd::move(nameLocation),\n\t\ttypeName\n\t);\n}\n\nASTPointer<IdentifierPath> Parser::parseIdentifierPath()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tnodeFactory.markEndPosition();\n\n\tauto [name, nameLocation] = expectIdentifierWithLocation();\n\n\tstd::vector<ASTString> identifierPath{*name};\n\tstd::vector<SourceLocation> identifierPathLocations{nameLocation};\n\n\twhile (m_scanner->currentToken() == Token::Period)\n\t{\n\t\tadvance();\n\n\t\tnodeFactory.markEndPosition();\n\n\t\ttie(name, nameLocation) = expectIdentifierWithLocation();\n\n\t\tidentifierPath.push_back(*name);\n\t\tidentifierPathLocations.push_back(nameLocation);\n\t}\n\treturn nodeFactory.createNode<IdentifierPath>(identifierPath, identifierPathLocations);\n}\n\nASTPointer<TypeName> Parser::parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory)\n{\n\tRecursionGuard recursionGuard(*this);\n\twhile (m_scanner->currentToken() == Token::LBrack)\n\t{\n\t\tadvance();\n\t\tASTPointer<Expression> length;\n\t\tif (m_scanner->currentToken() != Token::RBrack)\n\t\t\tlength = parseExpression();\n\t\tnodeFactory.markEndPosition();\n\t\texpectToken(Token::RBrack);\n\t\ttype = nodeFactory.createNode<ArrayTypeName>(type, length);\n\t}\n\treturn type;\n}\n\nASTPointer<TypeName> Parser::parseTypeName()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<TypeName> type;\n\tToken token = m_scanner->currentToken();\n\tif (TokenTraits::isElementaryTypeName(token))\n\t{\n\t\tunsigned firstSize;\n\t\tunsigned secondSize;\n\t\tstd::tie(firstSize, secondSize) = m_scanner->currentTokenInfo();\n\t\tElementaryTypeNameToken elemTypeName(token, firstSize, secondSize);\n\t\tASTNodeFactory nodeFactory(*this);\n\t\tnodeFactory.markEndPosition();\n\t\tadvance();\n\t\tauto stateMutability = elemTypeName.token() == Token::Address\n\t\t\t? std::optional<StateMutability>{StateMutability::NonPayable}\n\t\t\t: std::nullopt;\n\t\tif (TokenTraits::isStateMutabilitySpecifier(m_scanner->currentToken()))\n\t\t{\n\t\t\tif (elemTypeName.token() == Token::Address)\n\t\t\t{\n\t\t\t\tnodeFactory.markEndPosition();\n\t\t\t\tstateMutability = parseStateMutability();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tparserError(9106_error, \"State mutability can only be specified for address types.\");\n\t\t\t\tadvance();\n\t\t\t}\n\t\t}\n\t\ttype = nodeFactory.createNode<ElementaryTypeName>(elemTypeName, stateMutability);\n\t}\n\telse if (token == Token::Function)\n\t\ttype = parseFunctionType();\n\telse if (token == Token::Mapping)\n\t\ttype = parseMapping();\n\telse if (token == Token::Identifier)\n\t\ttype = parseUserDefinedTypeName();\n\telse\n\t\tfatalParserError(3546_error, \"Expected type name\");\n\n\tsolAssert(type, \"\");\n\t// Parse \"[...]\" postfixes for arrays.\n\ttype = parseTypeNameSuffix(type, nodeFactory);\n\n\treturn type;\n}\n\nASTPointer<FunctionTypeName> Parser::parseFunctionType()\n{\n\tsolAssert(!m_experimentalSolidityEnabledInCurrentSourceUnit);\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\texpectToken(Token::Function);\n\tFunctionHeaderParserResult header = parseFunctionHeader(true);\n\tsolAssert(!header.experimentalReturnExpression);\n\treturn nodeFactory.createNode<FunctionTypeName>(\n\t\theader.parameters,\n\t\theader.returnParameters,\n\t\theader.visibility,\n\t\theader.stateMutability\n\t);\n}\n\nASTPointer<Mapping> Parser::parseMapping()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\texpectToken(Token::Mapping);\n\texpectToken(Token::LParen);\n\tASTPointer<TypeName> keyType;\n\tToken token = m_scanner->currentToken();\n\tunsigned firstSize;\n\tunsigned secondSize;\n\tstd::tie(firstSize, secondSize) = m_scanner->currentTokenInfo();\n\tif (token == Token::Identifier)\n\t\tkeyType = parseUserDefinedTypeName();\n\telse if (TokenTraits::isElementaryTypeName(token))\n\t{\n\t\tkeyType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(\n\t\t\tElementaryTypeNameToken{token, firstSize, secondSize}\n\t\t);\n\t\tadvance();\n\t}\n\telse\n\t\tfatalParserError(1005_error, \"Expected elementary type name or identifier for mapping key type\");\n\tASTPointer<ASTString> keyName = std::make_shared<ASTString>(\"\");\n\tSourceLocation keyNameLocation{};\n\tif (m_scanner->currentToken() == Token::Identifier)\n\t\ttie(keyName, keyNameLocation) = expectIdentifierWithLocation();\n\texpectToken(Token::DoubleArrow);\n\tASTPointer<TypeName> valueType = parseTypeName();\n\tASTPointer<ASTString> valueName = std::make_shared<ASTString>(\"\");\n\tSourceLocation valueNameLocation{};\n\tif (m_scanner->currentToken() == Token::Identifier)\n\t\ttie(valueName, valueNameLocation) = expectIdentifierWithLocation();\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::RParen);\n\treturn nodeFactory.createNode<Mapping>(keyType, keyName, keyNameLocation, valueType, valueName, valueNameLocation);\n}\n\nASTPointer<ParameterList> Parser::parseParameterList(\n\tVarDeclParserOptions const& _options,\n\tbool _allowEmpty\n)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tstd::vector<ASTPointer<VariableDeclaration>> parameters;\n\tVarDeclParserOptions options(_options);\n\toptions.allowEmptyName = true;\n\tif (m_experimentalSolidityEnabledInCurrentSourceUnit && m_scanner->currentToken() == Token::Identifier)\n\t{\n\t\t// Parses unary parameter lists without parentheses. TODO: is this a good idea in all cases? Including arguments?\n\t\tparameters = {parsePostfixVariableDeclaration()};\n\t\tnodeFactory.setEndPositionFromNode(parameters.front());\n\t\treturn nodeFactory.createNode<ParameterList>(parameters);\n\t}\n\texpectToken(Token::LParen);\n\tauto parseSingleVariableDeclaration = [&]() {\n\t\tif (m_experimentalSolidityEnabledInCurrentSourceUnit)\n\t\t\treturn parsePostfixVariableDeclaration();\n\t\telse\n\t\t\treturn parseVariableDeclaration(options);\n\t};\n\tif (!_allowEmpty || m_scanner->currentToken() != Token::RParen)\n\t{\n\t\tparameters.push_back(parseSingleVariableDeclaration());\n\t\twhile (m_scanner->currentToken() != Token::RParen)\n\t\t{\n\t\t\tif (m_scanner->currentToken() == Token::Comma && m_scanner->peekNextToken() == Token::RParen)\n\t\t\t\tfatalParserError(7591_error, \"Unexpected trailing comma in parameter list.\");\n\t\t\texpectToken(Token::Comma);\n\t\t\tparameters.push_back(parseSingleVariableDeclaration());\n\t\t}\n\t}\n\tnodeFactory.markEndPosition();\n\tadvance();\n\treturn nodeFactory.createNode<ParameterList>(parameters);\n}\n\nASTPointer<Block> Parser::parseBlock(bool _allowUnchecked, ASTPointer<ASTString> const& _docString)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tbool const unchecked = m_scanner->currentToken() == Token::Unchecked;\n\tif (unchecked)\n\t{\n\t\tif (!_allowUnchecked)\n\t\t\tparserError(5296_error, \"\\\"unchecked\\\" blocks can only be used inside regular blocks.\");\n\t\tadvance();\n\t}\n\texpectToken(Token::LBrace);\n\tstd::vector<ASTPointer<Statement>> statements;\n\twhile (m_scanner->currentToken() != Token::RBrace)\n\t\tstatements.push_back(parseStatement(true));\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::RBrace);\n\treturn nodeFactory.createNode<Block>(_docString, unchecked, statements);\n}\n\nASTPointer<Statement> Parser::parseStatement(bool _allowUnchecked)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTPointer<ASTString> docString;\n\tASTPointer<Statement> statement;\n\tif (!m_scanner->currentCommentLiteral().empty())\n\t\tdocString = std::make_shared<ASTString>(m_scanner->currentCommentLiteral());\n\tswitch (m_scanner->currentToken())\n\t{\n\tcase Token::If:\n\t\treturn parseIfStatement(docString);\n\tcase Token::While:\n\t\treturn parseWhileStatement(docString);\n\tcase Token::Do:\n\t\treturn parseDoWhileStatement(docString);\n\tcase Token::For:\n\t\treturn parseForStatement(docString);\n\tcase Token::Unchecked:\n\tcase Token::LBrace:\n\t\treturn parseBlock(_allowUnchecked, docString);\n\tcase Token::Continue:\n\t\tstatement = ASTNodeFactory(*this).createNode<Continue>(docString);\n\t\tadvance();\n\t\tbreak;\n\tcase Token::Break:\n\t\tstatement = ASTNodeFactory(*this).createNode<Break>(docString);\n\t\tadvance();\n\t\tbreak;\n\tcase Token::Return:\n\t{\n\t\tASTNodeFactory nodeFactory(*this);\n\t\tASTPointer<Expression> expression;\n\t\tif (advance() != Token::Semicolon)\n\t\t\t{\n\t\t\t\texpression = parseExpression();\n\t\t\t\tnodeFactory.setEndPositionFromNode(expression);\n\t\t\t}\n\t\tstatement = nodeFactory.createNode<Return>(docString, expression);\n\t\t\tbreak;\n\t}\n\tcase Token::Throw:\n\t{\n\t\tstatement = ASTNodeFactory(*this).createNode<Throw>(docString);\n\t\tadvance();\n\t\tbreak;\n\t}\n\tcase Token::Try:\n\t\treturn parseTryStatement(docString);\n\tcase Token::Assembly:\n\t\treturn parseInlineAssembly(docString);\n\tcase Token::Emit:\n\t\tstatement = parseEmitStatement(docString);\n\t\tbreak;\n\tcase Token::Identifier:\n\t\tif (m_scanner->currentLiteral() == \"revert\" && m_scanner->peekNextToken() == Token::Identifier)\n\t\t\tstatement = parseRevertStatement(docString);\n\t\telse if (m_insideModifier && m_scanner->currentLiteral() == \"_\")\n\t\t{\n\t\t\tstatement = ASTNodeFactory(*this).createNode<PlaceholderStatement>(docString);\n\t\t\tadvance();\n\t\t}\n\t\telse\n\t\t\tstatement = parseSimpleStatement(docString);\n\t\tbreak;\n\tdefault:\n\t\tstatement = parseSimpleStatement(docString);\n\t\tbreak;\n\t}\n\texpectToken(Token::Semicolon);\n\treturn statement;\n}\n\nASTPointer<InlineAssembly> Parser::parseInlineAssembly(ASTPointer<ASTString> const& _docString)\n{\n\tRecursionGuard recursionGuard(*this);\n\tSourceLocation location = currentLocation();\n\n\texpectToken(Token::Assembly);\n\tyul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion, m_eofVersion);\n\tif (m_scanner->currentToken() == Token::StringLiteral)\n\t{\n\t\tif (m_scanner->currentLiteral() != \"evmasm\")\n\t\t\tfatalParserError(4531_error, \"Only \\\"evmasm\\\" supported.\");\n\t\t// This can be used in the future to set the dialect.\n\t\tadvance();\n\t}\n\n\tASTPointer<std::vector<ASTPointer<ASTString>>> flags;\n\tif (m_scanner->currentToken() == Token::LParen)\n\t{\n\t\tflags = std::make_shared<std::vector<ASTPointer<ASTString>>>();\n\t\tdo\n\t\t{\n\t\t\tadvance();\n\t\t\texpectToken(Token::StringLiteral, false);\n\t\t\tflags->emplace_back(std::make_shared<ASTString>(m_scanner->currentLiteral()));\n\t\t\tadvance();\n\t\t}\n\t\twhile (m_scanner->currentToken() == Token::Comma);\n\t\texpectToken(Token::RParen);\n\t}\n\n\tyul::Parser asmParser(m_errorReporter, dialect);\n\tstd::shared_ptr<yul::AST> ast = asmParser.parseInline(m_scanner);\n\tif (ast == nullptr)\n\t\tsolThrow(FatalError, \"Failed to parse inline assembly.\");\n\n\tlocation.end = nativeLocationOf(ast->root()).end;\n\treturn std::make_shared<InlineAssembly>(nextID(), location, _docString, dialect, std::move(flags), ast);\n}\n\nASTPointer<IfStatement> Parser::parseIfStatement(ASTPointer<ASTString> const& _docString)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\texpectToken(Token::If);\n\texpectToken(Token::LParen);\n\tASTPointer<Expression> condition = parseExpression();\n\texpectToken(Token::RParen);\n\tASTPointer<Statement> trueBody = parseStatement();\n\tASTPointer<Statement> falseBody;\n\tif (m_scanner->currentToken() == Token::Else)\n\t{\n\t\tadvance();\n\t\tfalseBody = parseStatement();\n\t\tnodeFactory.setEndPositionFromNode(falseBody);\n\t}\n\telse\n\t\tnodeFactory.setEndPositionFromNode(trueBody);\n\treturn nodeFactory.createNode<IfStatement>(_docString, condition, trueBody, falseBody);\n}\n\nASTPointer<TryStatement> Parser::parseTryStatement(ASTPointer<ASTString> const& _docString)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\texpectToken(Token::Try);\n\tASTPointer<Expression> externalCall = parseExpression();\n\tstd::vector<ASTPointer<TryCatchClause>> clauses;\n\n\tASTNodeFactory successClauseFactory(*this);\n\tASTPointer<ParameterList> returnsParameters;\n\tif (m_scanner->currentToken() == Token::Returns)\n\t{\n\t\tadvance();\n\t\tVarDeclParserOptions options;\n\t\toptions.allowEmptyName = true;\n\t\toptions.allowLocationSpecifier = true;\n\t\treturnsParameters = parseParameterList(options, false);\n\t}\n\tASTPointer<Block> successBlock = parseBlock();\n\tsuccessClauseFactory.setEndPositionFromNode(successBlock);\n\tclauses.emplace_back(successClauseFactory.createNode<TryCatchClause>(\n\t\tstd::make_shared<ASTString>(), returnsParameters, successBlock\n\t));\n\n\tdo\n\t{\n\t\tclauses.emplace_back(parseCatchClause());\n\t}\n\twhile (m_scanner->currentToken() == Token::Catch);\n\tnodeFactory.setEndPositionFromNode(clauses.back());\n\treturn nodeFactory.createNode<TryStatement>(\n\t\t_docString, externalCall, clauses\n\t);\n}\n\nASTPointer<TryCatchClause> Parser::parseCatchClause()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\texpectToken(Token::Catch);\n\tASTPointer<ASTString> errorName = std::make_shared<std::string>();\n\tASTPointer<ParameterList> errorParameters;\n\tif (m_scanner->currentToken() != Token::LBrace)\n\t{\n\t\tif (m_scanner->currentToken() == Token::Identifier)\n\t\t\terrorName = expectIdentifierToken();\n\t\tVarDeclParserOptions options;\n\t\toptions.allowEmptyName = true;\n\t\toptions.allowLocationSpecifier = true;\n\t\terrorParameters = parseParameterList(options, !errorName->empty());\n\t}\n\tASTPointer<Block> block = parseBlock();\n\tnodeFactory.setEndPositionFromNode(block);\n\treturn nodeFactory.createNode<TryCatchClause>(errorName, errorParameters, block);\n}\n\nASTPointer<WhileStatement> Parser::parseWhileStatement(ASTPointer<ASTString> const& _docString)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\texpectToken(Token::While);\n\texpectToken(Token::LParen);\n\tASTPointer<Expression> condition = parseExpression();\n\texpectToken(Token::RParen);\n\tASTPointer<Statement> body = parseStatement();\n\tnodeFactory.setEndPositionFromNode(body);\n\treturn nodeFactory.createNode<WhileStatement>(_docString, condition, body, false);\n}\n\nASTPointer<WhileStatement> Parser::parseDoWhileStatement(ASTPointer<ASTString> const& _docString)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\texpectToken(Token::Do);\n\tASTPointer<Statement> body = parseStatement();\n\texpectToken(Token::While);\n\texpectToken(Token::LParen);\n\tASTPointer<Expression> condition = parseExpression();\n\texpectToken(Token::RParen);\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::Semicolon);\n\treturn nodeFactory.createNode<WhileStatement>(_docString, condition, body, true);\n}\n\n\nASTPointer<ForStatement> Parser::parseForStatement(ASTPointer<ASTString> const& _docString)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tASTPointer<Statement> initExpression;\n\tASTPointer<Expression> conditionExpression;\n\tASTPointer<ExpressionStatement> loopExpression;\n\texpectToken(Token::For);\n\texpectToken(Token::LParen);\n\n\t// TODO: Maybe here have some predicate like peekExpression() instead of checking for semicolon and RParen?\n\tif (m_scanner->currentToken() != Token::Semicolon)\n\t\tinitExpression = parseSimpleStatement(ASTPointer<ASTString>());\n\texpectToken(Token::Semicolon);\n\n\tif (m_scanner->currentToken() != Token::Semicolon)\n\t\tconditionExpression = parseExpression();\n\texpectToken(Token::Semicolon);\n\n\tif (m_scanner->currentToken() != Token::RParen)\n\t\tloopExpression = parseExpressionStatement(ASTPointer<ASTString>());\n\texpectToken(Token::RParen);\n\n\tASTPointer<Statement> body = parseStatement();\n\tnodeFactory.setEndPositionFromNode(body);\n\treturn nodeFactory.createNode<ForStatement>(\n\t\t_docString,\n\t\tinitExpression,\n\t\tconditionExpression,\n\t\tloopExpression,\n\t\tbody\n\t);\n}\n\nASTPointer<EmitStatement> Parser::parseEmitStatement(ASTPointer<ASTString> const& _docString)\n{\n\texpectToken(Token::Emit, false);\n\n\tASTNodeFactory nodeFactory(*this);\n\tadvance();\n\tASTNodeFactory eventCallNodeFactory(*this);\n\n\tif (m_scanner->currentToken() != Token::Identifier)\n\t\tfatalParserError(5620_error, \"Expected event name or path.\");\n\n\tIndexAccessedPath iap;\n\twhile (true)\n\t{\n\t\tiap.path.push_back(parseIdentifier());\n\t\tif (m_scanner->currentToken() != Token::Period)\n\t\t\tbreak;\n\t\tadvance();\n\t}\n\n\tauto eventName = expressionFromIndexAccessStructure(iap);\n\texpectToken(Token::LParen);\n\n\tauto functionCallArguments = parseFunctionCallArguments();\n\teventCallNodeFactory.markEndPosition();\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::RParen);\n\tauto eventCall = eventCallNodeFactory.createNode<FunctionCall>(\n\t\teventName,\n\t\tfunctionCallArguments.arguments,\n\t\tfunctionCallArguments.parameterNames,\n\t\tfunctionCallArguments.parameterNameLocations\n\t);\n\treturn nodeFactory.createNode<EmitStatement>(_docString, eventCall);\n}\n\nASTPointer<RevertStatement> Parser::parseRevertStatement(ASTPointer<ASTString> const& _docString)\n{\n\tASTNodeFactory nodeFactory(*this);\n\tsolAssert(*expectIdentifierToken() == \"revert\", \"\");\n\n\tASTNodeFactory errorCallNodeFactory(*this);\n\n\tsolAssert(m_scanner->currentToken() == Token::Identifier, \"\");\n\n\tIndexAccessedPath iap;\n\twhile (true)\n\t{\n\t\tiap.path.push_back(parseIdentifier());\n\t\tif (m_scanner->currentToken() != Token::Period)\n\t\t\tbreak;\n\t\tadvance();\n\t}\n\n\tauto errorName = expressionFromIndexAccessStructure(iap);\n\texpectToken(Token::LParen);\n\n\tauto functionCallArguments = parseFunctionCallArguments();\n\terrorCallNodeFactory.markEndPosition();\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::RParen);\n\tauto errorCall = errorCallNodeFactory.createNode<FunctionCall>(\n\t\terrorName,\n\t\tfunctionCallArguments.arguments,\n\t\tfunctionCallArguments.parameterNames,\n\t\tfunctionCallArguments.parameterNameLocations\n\t);\n\treturn nodeFactory.createNode<RevertStatement>(_docString, errorCall);\n}\n\nASTPointer<VariableDeclarationStatement> Parser::parsePostfixVariableDeclarationStatement(\n\tASTPointer<ASTString> const& _docString\n)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\n\texpectToken(Token::Let);\n\n\tstd::vector<ASTPointer<VariableDeclaration>> variables;\n\tvariables.emplace_back(parsePostfixVariableDeclaration());\n\tnodeFactory.setEndPositionFromNode(variables.back());\n\n\tASTPointer<Expression> value;\n\tif (m_scanner->currentToken() == Token::Assign)\n\t{\n\t\tadvance();\n\t\tvalue = parseExpression();\n\t\tnodeFactory.setEndPositionFromNode(value);\n\t}\n\treturn nodeFactory.createNode<VariableDeclarationStatement>(_docString, variables, value);\n}\n\nASTPointer<VariableDeclaration> Parser::parsePostfixVariableDeclaration()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\n\tASTPointer<StructuredDocumentation> const documentation = parseStructuredDocumentation();\n\n\tnodeFactory.markEndPosition();\n\tauto [identifier, nameLocation] = expectIdentifierWithLocation();\n\n\tASTPointer<Expression> type;\n\tif (m_scanner->currentToken() == Token::Colon)\n\t{\n\t\tadvance();\n\t\ttype = parseBinaryExpression();\n\t\tnodeFactory.setEndPositionFromNode(type);\n\t}\n\n\treturn nodeFactory.createNode<VariableDeclaration>(\n\t\tnullptr,\n\t\tidentifier,\n\t\tnameLocation,\n\t\tnullptr,\n\t\tVisibility::Default,\n\t\tdocumentation,\n\t\tfalse,\n\t\tVariableDeclaration::Mutability::Mutable,\n\t\tnullptr,\n\t\tVariableDeclaration::Location::Unspecified,\n\t\ttype\n\t);\n}\n\nASTPointer<TypeClassDefinition> Parser::parseTypeClassDefinition()\n{\n\tsolAssert(m_experimentalSolidityEnabledInCurrentSourceUnit);\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\n\tstd::vector<ASTPointer<ASTNode>> subNodes;\n\n\tASTPointer<StructuredDocumentation> const documentation = parseStructuredDocumentation();\n\n\texpectToken(Token::Class);\n\t// TODO: parseTypeVariable()? parseTypeVariableDeclaration()?\n\tASTPointer<VariableDeclaration> typeVariable;\n\t{\n\t\tASTNodeFactory nodeFactory(*this);\n\t\tnodeFactory.markEndPosition();\n\t\tauto [identifier, nameLocation] = expectIdentifierWithLocation();\n\t\ttypeVariable = nodeFactory.createNode<VariableDeclaration>(\n\t\t\tnullptr,\n\t\t\tidentifier,\n\t\t\tnameLocation,\n\t\t\tnullptr,\n\t\t\tVisibility::Default,\n\t\t\tnullptr\n\t\t);\n\t}\n\texpectToken(Token::Colon);\n\tauto [name, nameLocation] = expectIdentifierWithLocation();\n\texpectToken(Token::LBrace);\n\twhile (true)\n\t{\n\t\tToken currentTokenValue = m_scanner->currentToken();\n\t\tif (currentTokenValue == Token::RBrace)\n\t\t\tbreak;\n\t\texpectToken(Token::Function, false);\n\t\tsubNodes.push_back(parseFunctionDefinition(false, false));\n\t}\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::RBrace);\n\n\treturn nodeFactory.createNode<TypeClassDefinition>(\n\t\ttypeVariable,\n\t\tname,\n\t\tnameLocation,\n\t\tdocumentation,\n\t\tsubNodes\n\t);\n}\n\nASTPointer<TypeClassName> Parser::parseTypeClassName()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tstd::variant<Token, ASTPointer<IdentifierPath>> name;\n\tif (TokenTraits::isBuiltinTypeClassName(m_scanner->currentToken()))\n\t{\n\t\tnodeFactory.markEndPosition();\n\t\tname = m_scanner->currentToken();\n\t\tadvance();\n\t}\n\telse\n\t{\n\t\tauto identifierPath = parseIdentifierPath();\n\t\tname = identifierPath;\n\t\tnodeFactory.setEndPositionFromNode(identifierPath);\n\t}\n\treturn nodeFactory.createNode<TypeClassName>(name);\n}\n\nASTPointer<TypeClassInstantiation> Parser::parseTypeClassInstantiation()\n{\n\tsolAssert(m_experimentalSolidityEnabledInCurrentSourceUnit);\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\n\tstd::vector<ASTPointer<ASTNode>> subNodes;\n\n\texpectToken(Token::Instantiation);\n\t// TODO: parseTypeConstructor()\n\tASTPointer<TypeName> typeConstructor = parseTypeName();\n\tASTPointer<ParameterList> argumentSorts;\n\tif (m_scanner->currentToken() == Token::LParen)\n\t{\n\t\targumentSorts = parseParameterList();\n\t}\n\texpectToken(Token::Colon);\n\tASTPointer<TypeClassName> typeClassName = parseTypeClassName();\n\texpectToken(Token::LBrace);\n\twhile (true)\n\t{\n\t\tToken currentTokenValue = m_scanner->currentToken();\n\t\tif (currentTokenValue == Token::RBrace)\n\t\t\tbreak;\n\t\texpectToken(Token::Function, false);\n\t\t// TODO: require body already during parsing?\n\t\tsubNodes.push_back(parseFunctionDefinition(false, true));\n\t}\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::RBrace);\n\n\treturn nodeFactory.createNode<TypeClassInstantiation>(\n\t\ttypeConstructor,\n\t\targumentSorts,\n\t\ttypeClassName,\n\t\tsubNodes\n\t);\n}\n\nASTPointer<TypeDefinition> Parser::parseTypeDefinition()\n{\n\tsolAssert(m_experimentalSolidityEnabledInCurrentSourceUnit);\n\tASTNodeFactory nodeFactory(*this);\n\texpectToken(Token::Type);\n\tauto&& [name, nameLocation] = expectIdentifierWithLocation();\n\n\tASTPointer<ParameterList> arguments;\n\tif (m_scanner->currentToken() == Token::LParen)\n\t\targuments = parseParameterList();\n\n\tASTPointer<Expression> expression;\n\tif (m_scanner->currentToken() == Token::Assign)\n\t{\n\t\texpectToken(Token::Assign);\n\n\t\tif (m_scanner->currentToken() != Token::Builtin)\n\t\t\texpression = parseExpression();\n\t\telse\n\t\t{\n\t\t\texpectToken(Token::Builtin);\n\t\t\texpectToken(Token::LParen);\n\n\t\t\texpression = nodeFactory.createNode<Builtin>(\n\t\t\t\tstd::make_shared<std::string>(m_scanner->currentLiteral()),\n\t\t\t\tm_scanner->currentLocation()\n\t\t\t);\n\n\t\t\texpectToken(Token::StringLiteral);\n\t\t\texpectToken(Token::RParen);\n\t\t}\n\t}\n\tnodeFactory.markEndPosition();\n\texpectToken(Token::Semicolon);\n\treturn nodeFactory.createNode<TypeDefinition>(\n\t\tstd::move(name),\n\t\tstd::move(nameLocation),\n\t\tstd::move(arguments),\n\t\tstd::move(expression)\n\t);\n}\n\nASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& _docString)\n{\n\tRecursionGuard recursionGuard(*this);\n\tLookAheadInfo statementType;\n\tIndexAccessedPath iap;\n\n\tif (m_experimentalSolidityEnabledInCurrentSourceUnit && m_scanner->currentToken() == Token::Let)\n\t\treturn parsePostfixVariableDeclarationStatement(_docString);\n\n\tif (m_scanner->currentToken() == Token::LParen)\n\t{\n\t\tASTNodeFactory nodeFactory(*this);\n\t\tsize_t emptyComponents = 0;\n\t\t// First consume all empty components.\n\t\texpectToken(Token::LParen);\n\t\twhile (m_scanner->currentToken() == Token::Comma)\n\t\t{\n\t\t\tadvance();\n\t\t\temptyComponents++;\n\t\t}\n\n\t\t// Now see whether we have a variable declaration or an expression.\n\t\tstd::tie(statementType, iap) = tryParseIndexAccessedPath();\n\t\tswitch (statementType)\n\t\t{\n\t\tcase LookAheadInfo::VariableDeclaration:\n\t\t{\n\t\t\tstd::vector<ASTPointer<VariableDeclaration>> variables;\n\t\t\tASTPointer<Expression> value;\n\t\t\t// We have already parsed something like `(,,,,a.b.c[2][3]`\n\t\t\tVarDeclParserOptions options;\n\t\t\toptions.allowLocationSpecifier = true;\n\t\t\tvariables = std::vector<ASTPointer<VariableDeclaration>>(emptyComponents, nullptr);\n\t\t\tvariables.push_back(parseVariableDeclaration(options, typeNameFromIndexAccessStructure(iap)));\n\n\t\t\twhile (m_scanner->currentToken() != Token::RParen)\n\t\t\t{\n\t\t\t\texpectToken(Token::Comma);\n\t\t\t\tif (m_scanner->currentToken() == Token::Comma || m_scanner->currentToken() == Token::RParen)\n\t\t\t\t\tvariables.push_back(nullptr);\n\t\t\t\telse\n\t\t\t\t\tvariables.push_back(parseVariableDeclaration(options));\n\t\t\t}\n\t\t\texpectToken(Token::RParen);\n\t\t\texpectToken(Token::Assign);\n\t\t\tvalue = parseExpression();\n\t\t\tnodeFactory.setEndPositionFromNode(value);\n\t\t\treturn nodeFactory.createNode<VariableDeclarationStatement>(_docString, variables, value);\n\t\t}\n\t\tcase LookAheadInfo::Expression:\n\t\t{\n\t\t\t// Complete parsing the expression in the current component.\n\t\t\tstd::vector<ASTPointer<Expression>> components(emptyComponents, nullptr);\n\t\t\tcomponents.push_back(parseExpression(expressionFromIndexAccessStructure(iap)));\n\t\t\twhile (m_scanner->currentToken() != Token::RParen)\n\t\t\t{\n\t\t\t\texpectToken(Token::Comma);\n\t\t\t\tif (m_scanner->currentToken() == Token::Comma || m_scanner->currentToken() == Token::RParen)\n\t\t\t\t\tcomponents.push_back(ASTPointer<Expression>());\n\t\t\t\telse\n\t\t\t\t\tcomponents.push_back(parseExpression());\n\t\t\t}\n\t\t\tnodeFactory.markEndPosition();\n\t\t\texpectToken(Token::RParen);\n\t\t\treturn parseExpressionStatement(_docString, nodeFactory.createNode<TupleExpression>(components, false));\n\t\t}\n\t\tdefault:\n\t\t\tsolAssert(false);\n\t\t}\n\t}\n\telse\n\t{\n\t\tstd::tie(statementType, iap) = tryParseIndexAccessedPath();\n\t\tswitch (statementType)\n\t\t{\n\t\tcase LookAheadInfo::VariableDeclaration:\n\t\t\treturn parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap));\n\t\tcase LookAheadInfo::Expression:\n\t\t\treturn parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap));\n\t\tdefault:\n\t\t\tsolAssert(false);\n\t\t}\n\t}\n\n\t// FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794)\n\tutil::unreachable();\n}\n\nbool Parser::IndexAccessedPath::empty() const\n{\n\tif (!indices.empty())\n\t\tsolAssert(!path.empty());\n\n\treturn path.empty() && indices.empty();\n}\n\n\nstd::pair<Parser::LookAheadInfo, Parser::IndexAccessedPath> Parser::tryParseIndexAccessedPath()\n{\n\t// These two cases are very hard to distinguish:\n\t// x[7 * 20 + 3] a;     and     x[7 * 20 + 3] = 9;\n\t// In the first case, x is a type name, in the second it is the name of a variable.\n\t// As an extension, we can even have:\n\t// `x.y.z[1][2] a;` and `x.y.z[1][2] = 10;`\n\t// Where in the first, x.y.z leads to a type name where in the second, it accesses structs.\n\n\tauto statementType = peekStatementType();\n\tswitch (statementType)\n\t{\n\tcase LookAheadInfo::VariableDeclaration:\n\tcase LookAheadInfo::Expression:\n\t\treturn std::make_pair(\n\t\t\tm_experimentalSolidityEnabledInCurrentSourceUnit ? LookAheadInfo::Expression : statementType,\n\t\t\tIndexAccessedPath()\n\t\t);\n\tdefault:\n\t\tbreak;\n\t}\n\n\t// At this point, we have 'Identifier \"[\"' or 'Identifier \".\" Identifier' or 'ElementoryTypeName \"[\"'.\n\t// We parse '(Identifier (\".\" Identifier)* |ElementaryTypeName) ( \"[\" Expression \"]\" )*'\n\t// until we can decide whether to hand this over to ExpressionStatement or create a\n\t// VariableDeclarationStatement out of it.\n\tIndexAccessedPath iap = parseIndexAccessedPath();\n\n\tif (m_experimentalSolidityEnabledInCurrentSourceUnit)\n\t\treturn std::make_pair(LookAheadInfo::Expression, std::move(iap));\n\n\tif (m_scanner->currentToken() == Token::Identifier || TokenTraits::isLocationSpecifier(m_scanner->currentToken()))\n\t\treturn std::make_pair(LookAheadInfo::VariableDeclaration, std::move(iap));\n\telse\n\t\treturn std::make_pair(LookAheadInfo::Expression, std::move(iap));\n}\n\nASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement(\n\tASTPointer<ASTString> const& _docString,\n\tASTPointer<TypeName> const& _lookAheadArrayType\n)\n{\n\t// This does not parse multi variable declaration statements starting directly with\n\t// `(`, they are parsed in parseSimpleStatement, because they are hard to distinguish\n\t// from tuple expressions.\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tif (_lookAheadArrayType)\n\t\tnodeFactory.setLocation(_lookAheadArrayType->location());\n\n\tVarDeclParserOptions options;\n\toptions.allowLocationSpecifier = true;\n\tstd::vector<ASTPointer<VariableDeclaration>> variables;\n\tvariables.emplace_back(parseVariableDeclaration(options, _lookAheadArrayType));\n\tnodeFactory.setEndPositionFromNode(variables.back());\n\n\tASTPointer<Expression> value;\n\tif (m_scanner->currentToken() == Token::Assign)\n\t{\n\t\tadvance();\n\t\tvalue = parseExpression();\n\t\tnodeFactory.setEndPositionFromNode(value);\n\t}\n\treturn nodeFactory.createNode<VariableDeclarationStatement>(_docString, variables, value);\n}\n\nASTPointer<ExpressionStatement> Parser::parseExpressionStatement(\n\tASTPointer<ASTString> const& _docString,\n\tASTPointer<Expression> const& _partialParserResult\n)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTPointer<Expression> expression = parseExpression(_partialParserResult);\n\treturn ASTNodeFactory(*this, expression).createNode<ExpressionStatement>(_docString, expression);\n}\n\nASTPointer<Expression> Parser::parseExpression(\n\tASTPointer<Expression> const& _partiallyParsedExpression\n)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTPointer<Expression> expression = parseBinaryExpression(4, _partiallyParsedExpression);\n\tif (TokenTraits::isAssignmentOp(m_scanner->currentToken()))\n\t{\n\t\tToken assignmentOperator = m_scanner->currentToken();\n\t\tadvance();\n\t\tASTPointer<Expression> rightHandSide = parseExpression();\n\t\tASTNodeFactory nodeFactory(*this, expression);\n\t\tnodeFactory.setEndPositionFromNode(rightHandSide);\n\t\treturn nodeFactory.createNode<Assignment>(expression, assignmentOperator, rightHandSide);\n\t}\n\telse if (m_scanner->currentToken() == Token::Conditional)\n\t{\n\t\tadvance();\n\t\tASTPointer<Expression> trueExpression = parseExpression();\n\t\texpectToken(Token::Colon);\n\t\tASTPointer<Expression> falseExpression = parseExpression();\n\t\tASTNodeFactory nodeFactory(*this, expression);\n\t\tnodeFactory.setEndPositionFromNode(falseExpression);\n\t\treturn nodeFactory.createNode<Conditional>(expression, trueExpression, falseExpression);\n\t}\n\telse\n\t\treturn expression;\n}\n\nASTPointer<Expression> Parser::parseBinaryExpression(\n\tint _minPrecedence,\n\tASTPointer<Expression> const& _partiallyParsedExpression\n)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTPointer<Expression> expression = parseUnaryExpression(_partiallyParsedExpression);\n\tASTNodeFactory nodeFactory(*this, expression);\n\tint precedence = tokenPrecedence(m_scanner->currentToken());\n\tfor (; precedence >= _minPrecedence; --precedence)\n\t\twhile (tokenPrecedence(m_scanner->currentToken()) == precedence)\n\t\t{\n\t\t\tToken op = m_scanner->currentToken();\n\t\t\tadvance();\n\n\t\t\tstatic_assert(TokenTraits::hasExpHighestPrecedence(), \"Exp does not have the highest precedence\");\n\n\t\t\t// Parse a**b**c as a**(b**c)\n\t\t\tASTPointer<Expression> right = (op == Token::Exp) ?\n\t\t\t\tparseBinaryExpression(precedence) :\n\t\t\t\tparseBinaryExpression(precedence + 1);\n\t\t\tnodeFactory.setEndPositionFromNode(right);\n\t\t\texpression = nodeFactory.createNode<BinaryOperation>(expression, op, right);\n\t\t}\n\treturn expression;\n}\n\nint Parser::tokenPrecedence(Token _token) const\n{\n\tif (m_experimentalSolidityEnabledInCurrentSourceUnit)\n\t{\n\t\tswitch (_token)\n\t\t{\n\t\tcase Token::Colon:\n\t\t\treturn 1000;\n\t\tcase Token::RightArrow:\n\t\t\treturn 999;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn TokenTraits::precedence(m_scanner->currentToken());\n}\n\nASTPointer<Expression> Parser::parseUnaryExpression(\n\tASTPointer<Expression> const& _partiallyParsedExpression\n)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory = _partiallyParsedExpression ?\n\t\tASTNodeFactory(*this, _partiallyParsedExpression) : ASTNodeFactory(*this);\n\tToken token = m_scanner->currentToken();\n\n\tif (!_partiallyParsedExpression && token == Token::Add)\n\t\tfatalParserError(9636_error, \"Use of unary + is disallowed.\");\n\n\tif (!_partiallyParsedExpression && (TokenTraits::isUnaryOp(token) || TokenTraits::isCountOp(token)))\n\t{\n\t\t// prefix expression\n\t\tadvance();\n\t\tASTPointer<Expression> subExpression = parseUnaryExpression();\n\t\tnodeFactory.setEndPositionFromNode(subExpression);\n\t\treturn nodeFactory.createNode<UnaryOperation>(token, subExpression, true);\n\t}\n\telse\n\t{\n\t\t// potential postfix expression\n\t\tASTPointer<Expression> subExpression = parseLeftHandSideExpression(_partiallyParsedExpression);\n\t\ttoken = m_scanner->currentToken();\n\n\t\tif (!TokenTraits::isCountOp(token))\n\t\t\treturn subExpression;\n\t\tnodeFactory.markEndPosition();\n\t\tadvance();\n\t\treturn nodeFactory.createNode<UnaryOperation>(token, subExpression, false);\n\t}\n}\n\nASTPointer<Expression> Parser::parseLeftHandSideExpression(\n\tASTPointer<Expression> const& _partiallyParsedExpression\n)\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory = _partiallyParsedExpression ?\n\t\tASTNodeFactory(*this, _partiallyParsedExpression) : ASTNodeFactory(*this);\n\n\tASTPointer<Expression> expression;\n\tif (_partiallyParsedExpression)\n\t\texpression = _partiallyParsedExpression;\n\telse if (m_scanner->currentToken() == Token::New)\n\t{\n\t\texpectToken(Token::New);\n\t\tASTPointer<TypeName> typeName(parseTypeName());\n\t\tnodeFactory.setEndPositionFromNode(typeName);\n\t\texpression = nodeFactory.createNode<NewExpression>(typeName);\n\t}\n\telse if (m_scanner->currentToken() == Token::Payable)\n\t{\n\t\texpectToken(Token::Payable);\n\t\tnodeFactory.markEndPosition();\n\t\tauto expressionType = nodeFactory.createNode<ElementaryTypeName>(\n\t\t\tElementaryTypeNameToken(Token::Address, 0, 0),\n\t\t\tstd::make_optional(StateMutability::Payable)\n\t\t);\n\t\texpression = nodeFactory.createNode<ElementaryTypeNameExpression>(expressionType);\n\t\texpectToken(Token::LParen, false);\n\t}\n\telse\n\t\texpression = parsePrimaryExpression();\n\n\twhile (true)\n\t{\n\t\tswitch (m_scanner->currentToken())\n\t\t{\n\t\tcase Token::LBrack:\n\t\t{\n\t\t\tadvance();\n\t\t\tASTPointer<Expression> index;\n\t\t\tASTPointer<Expression> endIndex;\n\t\t\tif (m_scanner->currentToken() != Token::RBrack && m_scanner->currentToken() != Token::Colon)\n\t\t\t\tindex = parseExpression();\n\t\t\tif (m_scanner->currentToken() == Token::Colon)\n\t\t\t{\n\t\t\t\texpectToken(Token::Colon);\n\t\t\t\tif (m_scanner->currentToken() != Token::RBrack)\n\t\t\t\t\tendIndex = parseExpression();\n\t\t\t\tnodeFactory.markEndPosition();\n\t\t\t\texpectToken(Token::RBrack);\n\t\t\t\texpression = nodeFactory.createNode<IndexRangeAccess>(expression, index, endIndex);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnodeFactory.markEndPosition();\n\t\t\t\texpectToken(Token::RBrack);\n\t\t\t\texpression = nodeFactory.createNode<IndexAccess>(expression, index);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase Token::Period:\n\t\t{\n\t\t\tadvance();\n\t\t\tnodeFactory.markEndPosition();\n\t\t\tSourceLocation memberLocation = currentLocation();\n\t\t\tASTPointer<ASTString> memberName = expectIdentifierTokenOrAddress();\n\t\t\texpression = nodeFactory.createNode<MemberAccess>(expression, std::move(memberName), std::move(memberLocation));\n\t\t\tbreak;\n\t\t}\n\t\tcase Token::LParen:\n\t\t{\n\t\t\tadvance();\n\t\t\tauto functionCallArguments = parseFunctionCallArguments();\n\t\t\tnodeFactory.markEndPosition();\n\t\t\texpectToken(Token::RParen);\n\t\t\texpression = nodeFactory.createNode<FunctionCall>(\n\t\t\t\texpression,\n\t\t\t\tfunctionCallArguments.arguments,\n\t\t\t\tfunctionCallArguments.parameterNames,\n\t\t\t\tfunctionCallArguments.parameterNameLocations);\n\t\t\tbreak;\n\t\t}\n\t\tcase Token::LBrace:\n\t\t{\n\t\t\t// See if this is followed by <identifier>, followed by \":\". If not, it is not\n\t\t\t// a function call options but a Block (from a try statement).\n\t\t\tif (\n\t\t\t\tm_scanner->peekNextToken() != Token::Identifier ||\n\t\t\t\tm_scanner->peekNextNextToken() != Token::Colon\n\t\t\t)\n\t\t\t\treturn expression;\n\n\t\t\texpectToken(Token::LBrace);\n\t\t\tauto optionList = parseNamedArguments();\n\n\t\t\tnodeFactory.markEndPosition();\n\t\t\texpectToken(Token::RBrace);\n\n\t\t\texpression = nodeFactory.createNode<FunctionCallOptions>(expression, optionList.arguments, optionList.parameterNames);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\treturn expression;\n\t\t}\n\t}\n}\n\nASTPointer<Expression> Parser::parseLiteral()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tToken initialToken = m_scanner->currentToken();\n\tASTPointer<ASTString> value = std::make_shared<std::string>(m_scanner->currentLiteral());\n\n\tswitch (initialToken)\n\t{\n\tcase Token::TrueLiteral:\n\tcase Token::FalseLiteral:\n\tcase Token::Number:\n\t{\n\t\tnodeFactory.markEndPosition();\n\t\tadvance();\n\t\tbreak;\n\t}\n\tcase Token::StringLiteral:\n\tcase Token::UnicodeStringLiteral:\n\tcase Token::HexStringLiteral:\n\t{\n\t\twhile (m_scanner->peekNextToken() == initialToken)\n\t\t{\n\t\t\tadvance();\n\t\t\t*value += m_scanner->currentLiteral();\n\t\t}\n\t\tnodeFactory.markEndPosition();\n\t\tadvance();\n\t\tif (m_scanner->currentToken() == Token::Illegal)\n\t\t\tfatalParserError(5428_error, to_string(m_scanner->currentError()));\n\t\tbreak;\n\t}\n\tdefault:\n\t\tsolAssert(false);\n\t}\n\n\tif (initialToken == Token::Number && (\n\t\tTokenTraits::isEtherSubdenomination(m_scanner->currentToken()) ||\n\t\tTokenTraits::isTimeSubdenomination(m_scanner->currentToken())\n\t))\n\t{\n\t\tnodeFactory.markEndPosition();\n\t\tLiteral::SubDenomination subDenomination = static_cast<Literal::SubDenomination>(m_scanner->currentToken());\n\t\tadvance();\n\t\treturn nodeFactory.createNode<Literal>(initialToken, std::move(value), subDenomination);\n\t}\n\n\treturn nodeFactory.createNode<Literal>(initialToken, std::move(value), Literal::SubDenomination::None);\n}\n\nASTPointer<Expression> Parser::parsePrimaryExpression()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tToken token = m_scanner->currentToken();\n\tASTPointer<Expression> expression;\n\n\tswitch (token)\n\t{\n\tcase Token::TrueLiteral:\n\tcase Token::FalseLiteral:\n\tcase Token::Number:\n\tcase Token::StringLiteral:\n\tcase Token::UnicodeStringLiteral:\n\tcase Token::HexStringLiteral:\n\t\texpression = parseLiteral();\n\t\tbreak;\n\tcase Token::Identifier:\n\t\tnodeFactory.markEndPosition();\n\t\texpression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance());\n\t\tbreak;\n\tcase Token::Type:\n\t\t// Inside expressions \"type\" is the name of a special, globally-available function.\n\t\tnodeFactory.markEndPosition();\n\t\tadvance();\n\t\texpression = nodeFactory.createNode<Identifier>(std::make_shared<ASTString>(\"type\"));\n\t\tbreak;\n\tcase Token::LParen:\n\tcase Token::LBrack:\n\t{\n\t\t// Tuple/parenthesized expression or inline array/bracketed expression.\n\t\t// Special cases: ()/[] is empty tuple/array type, (x) is not a real tuple,\n\t\t// (x,) is one-dimensional tuple, elements in arrays cannot be left out, only in tuples.\n\t\tadvance();\n\t\tstd::vector<ASTPointer<Expression>> components;\n\t\tToken oppositeToken = (token == Token::LParen ? Token::RParen : Token::RBrack);\n\t\tbool isArray = (token == Token::LBrack);\n\n\t\tif (m_scanner->currentToken() != oppositeToken)\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tif (m_scanner->currentToken() != Token::Comma && m_scanner->currentToken() != oppositeToken)\n\t\t\t\t\tcomponents.push_back(parseExpression());\n\t\t\t\telse if (isArray)\n\t\t\t\t\tparserError(4799_error, \"Expected expression (inline array elements cannot be omitted).\");\n\t\t\t\telse\n\t\t\t\t\tcomponents.push_back(ASTPointer<Expression>());\n\n\t\t\t\tif (m_scanner->currentToken() == oppositeToken)\n\t\t\t\t\tbreak;\n\n\t\t\t\texpectToken(Token::Comma);\n\t\t\t}\n\t\tnodeFactory.markEndPosition();\n\t\texpectToken(oppositeToken);\n\t\texpression = nodeFactory.createNode<TupleExpression>(components, isArray);\n\t\tbreak;\n\t}\n\tcase Token::Illegal:\n\t\tfatalParserError(8936_error, to_string(m_scanner->currentError()));\n\t\tbreak;\n\tdefault:\n\t\tif (TokenTraits::isElementaryTypeName(token))\n\t\t{\n\t\t\t//used for casts\n\t\t\tunsigned firstSize;\n\t\t\tunsigned secondSize;\n\t\t\tstd::tie(firstSize, secondSize) = m_scanner->currentTokenInfo();\n\t\t\tauto expressionType = nodeFactory.createNode<ElementaryTypeName>(\n\t\t\t\tElementaryTypeNameToken(m_scanner->currentToken(), firstSize, secondSize)\n\t\t\t);\n\t\t\texpression = nodeFactory.createNode<ElementaryTypeNameExpression>(expressionType);\n\t\t\tadvance();\n\t\t}\n\t\telse\n\t\t\tfatalParserError(6933_error, \"Expected primary expression.\");\n\t\tbreak;\n\t}\n\treturn expression;\n}\n\nstd::vector<ASTPointer<Expression>> Parser::parseFunctionCallListArguments()\n{\n\tRecursionGuard recursionGuard(*this);\n\tstd::vector<ASTPointer<Expression>> arguments;\n\tif (m_scanner->currentToken() != Token::RParen)\n\t{\n\t\targuments.push_back(parseExpression());\n\t\twhile (m_scanner->currentToken() != Token::RParen)\n\t\t{\n\t\t\texpectToken(Token::Comma);\n\t\t\targuments.push_back(parseExpression());\n\t\t}\n\t}\n\treturn arguments;\n}\n\nParser::FunctionCallArguments Parser::parseFunctionCallArguments()\n{\n\tRecursionGuard recursionGuard(*this);\n\tFunctionCallArguments ret;\n\n\tToken token = m_scanner->currentToken();\n\tif (token == Token::LBrace)\n\t{\n\t\t// call({arg1 : 1, arg2 : 2 })\n\t\texpectToken(Token::LBrace);\n\t\tret = parseNamedArguments();\n\t\texpectToken(Token::RBrace);\n\t}\n\telse\n\t\tret.arguments = parseFunctionCallListArguments();\n\treturn ret;\n}\n\nParser::FunctionCallArguments Parser::parseNamedArguments()\n{\n\tFunctionCallArguments ret;\n\n\tbool first = true;\n\twhile (m_scanner->currentToken() != Token::RBrace)\n\t{\n\t\tif (!first)\n\t\t\texpectToken(Token::Comma);\n\n\t\tauto identifierWithLocation = expectIdentifierWithLocation();\n\n\t\t// Add name\n\t\tret.parameterNames.emplace_back(std::move(identifierWithLocation.first));\n\t\t// Add location\n\t\tret.parameterNameLocations.emplace_back(std::move(identifierWithLocation.second));\n\n\t\texpectToken(Token::Colon);\n\t\tret.arguments.emplace_back(parseExpression());\n\n\t\tif (\n\t\t\tm_scanner->currentToken() == Token::Comma &&\n\t\t\tm_scanner->peekNextToken() == Token::RBrace\n\t\t)\n\t\t{\n\t\t\tparserError(2074_error, \"Unexpected trailing comma.\");\n\t\t\tadvance();\n\t\t}\n\n\t\tfirst = false;\n\t}\n\n\treturn ret;\n}\n\nbool Parser::variableDeclarationStart()\n{\n\tToken currentToken = m_scanner->currentToken();\n\treturn\n\t\tcurrentToken == Token::Identifier ||\n\t\tcurrentToken == Token::Mapping ||\n\t\tTokenTraits::isElementaryTypeName(currentToken) ||\n\t\t(currentToken == Token::Function && m_scanner->peekNextToken() == Token::LParen);\n}\n\nstd::optional<std::string> Parser::findLicenseString(std::vector<ASTPointer<ASTNode>> const& _nodes)\n{\n\t// We circumvent the scanner here, because it skips non-docstring comments.\n\tstatic std::regex const licenseNameRegex(\"([a-zA-Z0-9 ()+.-]+)\");\n\tstatic std::regex const licenseDeclarationRegex(\"SPDX-License-Identifier:\\\\s*(.+?)([\\n\\r]|(\\\\*/))\");\n\n\t// Search inside all parts of the source not covered by parsed nodes.\n\t// This will leave e.g. \"global comments\".\n\tusing iter = std::string::const_iterator;\n\tstd::vector<std::pair<iter, iter>> sequencesToSearch;\n\tstd::string const& source = m_scanner->charStream().source();\n\tsequencesToSearch.emplace_back(source.begin(), source.end());\n\tfor (ASTPointer<ASTNode> const& node: _nodes)\n\t\tif (node->location().hasText())\n\t\t{\n\t\t\tsequencesToSearch.back().second = source.begin() + node->location().start;\n\t\t\tsequencesToSearch.emplace_back(source.begin() + node->location().end, source.end());\n\t\t}\n\n\tstd::vector<std::string> licenseNames;\n\tfor (auto const& [start, end]: sequencesToSearch)\n\t{\n\t\tauto declarationsBegin = std::sregex_iterator(start, end, licenseDeclarationRegex);\n\t\tauto declarationsEnd = std::sregex_iterator();\n\n\t\tfor (std::sregex_iterator declIt = declarationsBegin; declIt != declarationsEnd; ++declIt)\n\t\t\tif (!declIt->empty())\n\t\t\t{\n\t\t\t\tstd::string license = boost::trim_copy(std::string((*declIt)[1]));\n\t\t\t\tlicenseNames.emplace_back(std::move(license));\n\t\t\t}\n\t}\n\n\tif (licenseNames.size() == 1)\n\t{\nstd::string const& license = licenseNames.front();\n\t\tif (regex_match(license, licenseNameRegex))\n\t\t\treturn license;\n\t\telse\n\t\t\tparserError(\n\t\t\t\t1114_error,\n\t\t\t\t{-1, -1, m_scanner->currentLocation().sourceName},\n\t\t\t\t\"Invalid SPDX license identifier.\"\n\t\t\t);\n\t}\n\telse if (licenseNames.empty())\n\t\tparserWarning(\n\t\t\t1878_error,\n\t\t\t{-1, -1, m_scanner->currentLocation().sourceName},\n\t\t\t\"SPDX license identifier not provided in source file. \"\n\t\t\t\"Before publishing, consider adding a comment containing \"\n\t\t\t\"\\\"SPDX-License-Identifier: <SPDX-License>\\\" to each source file. \"\n\t\t\t\"Use \\\"SPDX-License-Identifier: UNLICENSED\\\" for non-open-source code. \"\n\t\t\t\"Please see https://spdx.org for more information.\"\n\t\t);\n\telse\n\t\tparserError(\n\t\t\t3716_error,\n\t\t\t{-1, -1, m_scanner->currentLocation().sourceName},\n\t\t\t\"Multiple SPDX license identifiers found in source file. \"\n\t\t\t\"Use \\\"AND\\\" or \\\"OR\\\" to combine multiple licenses. \"\n\t\t\t\"Please see https://spdx.org for more information.\"\n\t\t);\n\n\treturn {};\n}\n\nParser::LookAheadInfo Parser::peekStatementType() const\n{\n\t// Distinguish between variable declaration (and potentially assignment) and expression statement\n\t// (which include assignments to other expressions and pre-declared variables).\n\t// We have a variable declaration if we get a keyword that specifies a type name.\n\t// If it is an identifier or an elementary type name followed by an identifier\n\t// or a mutability specifier, we also have a variable declaration.\n\t// If we get an identifier followed by a \"[\" or \".\", it can be both (\"lib.type[9] a;\" or \"variable.el[9] = 7;\").\n\t// In all other cases, we have an expression statement.\n\tToken token(m_scanner->currentToken());\n\tbool mightBeTypeName = (TokenTraits::isElementaryTypeName(token) || token == Token::Identifier);\n\n\tif (token == Token::Mapping || token == Token::Function)\n\t\treturn LookAheadInfo::VariableDeclaration;\n\tif (mightBeTypeName)\n\t{\n\t\tToken next = m_scanner->peekNextToken();\n\t\t// So far we only allow ``address payable`` in variable declaration statements and in no other\n\t\t// kind of statement. This means, for example, that we do not allow type expressions of the form\n\t\t// ``address payable;``.\n\t\t// If we want to change this in the future, we need to consider another scanner token here.\n\t\tif (TokenTraits::isElementaryTypeName(token) && TokenTraits::isStateMutabilitySpecifier(next))\n\t\t\treturn LookAheadInfo::VariableDeclaration;\n\t\tif (next == Token::Identifier || TokenTraits::isLocationSpecifier(next))\n\t\t\treturn LookAheadInfo::VariableDeclaration;\n\t\tif (next == Token::LBrack || next == Token::Period)\n\t\t\treturn LookAheadInfo::IndexAccessStructure;\n\t}\n\treturn LookAheadInfo::Expression;\n}\n\nParser::IndexAccessedPath Parser::parseIndexAccessedPath()\n{\n\tIndexAccessedPath iap;\n\tif (m_scanner->currentToken() == Token::Identifier)\n\t{\n\t\tiap.path.push_back(parseIdentifier());\n\t\twhile (m_scanner->currentToken() == Token::Period)\n\t\t{\n\t\t\tadvance();\n\t\t\tif (m_experimentalSolidityEnabledInCurrentSourceUnit && m_scanner->currentToken() == Token::Number)\n\t\t\t{\n\t\t\t\tASTNodeFactory nodeFactory(*this);\n\t\t\t\tnodeFactory.markEndPosition();\n\t\t\t\tiap.path.push_back(nodeFactory.createNode<Identifier>(getLiteralAndAdvance()));\n\t\t\t}\n\t\t\telse\n\t\t\t\tiap.path.push_back(parseIdentifierOrAddress());\n\t\t}\n\t}\n\telse\n\t{\n\t\tunsigned firstNum;\n\t\tunsigned secondNum;\n\t\tstd::tie(firstNum, secondNum) = m_scanner->currentTokenInfo();\n\t\tauto expressionType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(\n\t\t\tElementaryTypeNameToken(m_scanner->currentToken(), firstNum, secondNum)\n\t\t);\n\t\tiap.path.push_back(ASTNodeFactory(*this).createNode<ElementaryTypeNameExpression>(expressionType));\n\t\tadvance();\n\t}\n\twhile (m_scanner->currentToken() == Token::LBrack)\n\t{\n\t\texpectToken(Token::LBrack);\n\t\tASTPointer<Expression> index;\n\t\tif (m_scanner->currentToken() != Token::RBrack && m_scanner->currentToken() != Token::Colon)\n\t\t\tindex = parseExpression();\n\t\tSourceLocation indexLocation = iap.path.front()->location();\n\t\tif (m_scanner->currentToken() == Token::Colon)\n\t\t{\n\t\t\texpectToken(Token::Colon);\n\t\t\tASTPointer<Expression> endIndex;\n\t\t\tif (m_scanner->currentToken() != Token::RBrack)\n\t\t\t\tendIndex = parseExpression();\n\t\t\tindexLocation.end = currentLocation().end;\n\t\t\tiap.indices.emplace_back(IndexAccessedPath::Index{index, {endIndex}, indexLocation});\n\t\t\texpectToken(Token::RBrack);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tindexLocation.end = currentLocation().end;\n\t\t\tiap.indices.emplace_back(IndexAccessedPath::Index{index, {}, indexLocation});\n\t\t\texpectToken(Token::RBrack);\n\t\t}\n\t}\n\n\treturn iap;\n}\n\nASTPointer<TypeName> Parser::typeNameFromIndexAccessStructure(Parser::IndexAccessedPath const& _iap)\n{\n\tif (_iap.empty())\n\t\treturn {};\n\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tSourceLocation location = _iap.path.front()->location();\n\tlocation.end = _iap.path.back()->location().end;\n\tnodeFactory.setLocation(location);\n\n\tASTPointer<TypeName> type;\n\tif (auto typeName = dynamic_cast<ElementaryTypeNameExpression const*>(_iap.path.front().get()))\n\t{\n\t\tsolAssert(_iap.path.size() == 1, \"\");\n\t\ttype = nodeFactory.createNode<ElementaryTypeName>(typeName->type().typeName());\n\t}\n\telse\n\t{\n\t\tstd::vector<ASTString> path;\n\t\tstd::vector<SourceLocation> pathLocations;\n\n\t\tfor (auto const& el: _iap.path)\n\t\t{\n\t\t\tauto& identifier = dynamic_cast<Identifier const&>(*el);\n\t\t\tpath.push_back(identifier.name());\n\t\t\tpathLocations.push_back(identifier.location());\n\t\t}\n\n\t\ttype = nodeFactory.createNode<UserDefinedTypeName>(nodeFactory.createNode<IdentifierPath>(path, pathLocations));\n\t}\n\tfor (auto const& lengthExpression: _iap.indices)\n\t{\n\t\tif (lengthExpression.end)\n\t\t\tparserError(5464_error, lengthExpression.location, \"Expected array length expression.\");\n\t\tnodeFactory.setLocation(lengthExpression.location);\n\t\ttype = nodeFactory.createNode<ArrayTypeName>(type, lengthExpression.start);\n\t}\n\treturn type;\n}\n\nASTPointer<Expression> Parser::expressionFromIndexAccessStructure(\n\tParser::IndexAccessedPath const& _iap\n)\n{\n\tif (_iap.empty())\n\t\treturn {};\n\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this, _iap.path.front());\n\tASTPointer<Expression> expression(_iap.path.front());\n\tfor (size_t i = 1; i < _iap.path.size(); ++i)\n\t{\n\t\tSourceLocation location(_iap.path.front()->location());\n\t\tlocation.end = _iap.path[i]->location().end;\n\t\tnodeFactory.setLocation(location);\n\t\tIdentifier const& identifier = dynamic_cast<Identifier const&>(*_iap.path[i]);\n\t\texpression = nodeFactory.createNode<MemberAccess>(\n\t\t\texpression,\n\t\t\tstd::make_shared<ASTString>(identifier.name()),\n\t\t\tidentifier.location()\n\t\t);\n\t}\n\tfor (auto const& index: _iap.indices)\n\t{\n\t\tnodeFactory.setLocation(index.location);\n\t\tif (index.end)\n\t\t\texpression = nodeFactory.createNode<IndexRangeAccess>(expression, index.start, *index.end);\n\t\telse\n\t\t\texpression = nodeFactory.createNode<IndexAccess>(expression, index.start);\n\t}\n\treturn expression;\n}\n\nASTPointer<ParameterList> Parser::createEmptyParameterList()\n{\n\tRecursionGuard recursionGuard(*this);\n\tASTNodeFactory nodeFactory(*this);\n\tnodeFactory.setLocationEmpty();\n\treturn nodeFactory.createNode<ParameterList>(std::vector<ASTPointer<VariableDeclaration>>());\n}\n\nASTPointer<ASTString> Parser::expectIdentifierToken()\n{\n\texpectToken(Token::Identifier, false /* do not advance */);\n\treturn getLiteralAndAdvance();\n}\n\nASTPointer<ASTString> Parser::expectIdentifierTokenOrAddress()\n{\n\tASTPointer<ASTString> result;\n\tif (m_scanner->currentToken() == Token::Address)\n\t{\n\t\tresult = std::make_shared<ASTString>(\"address\");\n\t\tadvance();\n\t}\n\telse\n\t{\n\t\texpectToken(Token::Identifier, false /* do not advance */);\n\t\tresult = getLiteralAndAdvance();\n\t}\n\treturn result;\n}\n\nASTPointer<ASTString> Parser::getLiteralAndAdvance()\n{\n\tASTPointer<ASTString> identifier = std::make_shared<ASTString>(m_scanner->currentLiteral());\n\tadvance();\n\treturn identifier;\n}\n\nbool Parser::isQuotedPath() const\n{\n\treturn m_scanner->currentToken() == Token::StringLiteral;\n}\n\nbool Parser::isStdlibPath() const\n{\n\treturn m_experimentalSolidityEnabledInCurrentSourceUnit\n\t\t&& m_scanner->currentToken() == Token::Identifier\n\t\t&& m_scanner->currentLiteral() == \"std\";\n}\n\nASTPointer<ASTString> Parser::getStdlibImportPathAndAdvance()\n{\n\tASTPointer<ASTString> std = expectIdentifierToken();\n\tif (m_scanner->currentToken() == Token::Period)\n\t\tadvance();\n\tASTPointer<ASTString> library = expectIdentifierToken();\n\treturn std::make_shared<ASTString>(*std + \".\" + *library);\n}\n\n}\n"
  },
  {
    "path": "libsolidity/parsing/Parser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity parser.\n */\n\n#pragma once\n\n#include <libsolidity/ast/AST.h>\n#include <liblangutil/ParserBase.h>\n#include <liblangutil/EVMVersion.h>\n\nnamespace solidity::langutil\n{\nclass CharStream;\n}\n\nnamespace solidity::frontend\n{\n\nclass Parser: public langutil::ParserBase\n{\npublic:\n\texplicit Parser(\n\t\tlangutil::ErrorReporter& _errorReporter,\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion\n\t):\n\t\tParserBase(_errorReporter),\n\t\tm_evmVersion(_evmVersion),\n\t\tm_eofVersion(_eofVersion)\n\t{}\n\n\tASTPointer<SourceUnit> parse(langutil::CharStream& _charStream);\n\n\t/// Returns the maximal AST node ID assigned so far\n\tint64_t maxID() const { return m_currentNodeID; }\nprivate:\n\tclass ASTNodeFactory;\n\n\tenum class VarDeclKind { FileLevel, State, Other };\n\tstruct VarDeclParserOptions\n\t{\n\t\t// This is actually not needed, but due to a defect in the C++ standard, we have to.\n\t\t// https://stackoverflow.com/questions/17430377\n\t\tVarDeclParserOptions() {}\n\t\tVarDeclKind kind = VarDeclKind::Other;\n\t\tbool allowIndexed = false;\n\t\tbool allowEmptyName = false;\n\t\tbool allowInitialValue = false;\n\t\tbool allowLocationSpecifier = false;\n\t};\n\n\t/// This struct is shared for parsing a function header and a function type.\n\tstruct FunctionHeaderParserResult\n\t{\n\t\tbool isVirtual = false;\n\t\tASTPointer<OverrideSpecifier> overrides;\n\t\tASTPointer<ParameterList> parameters;\n\t\tASTPointer<ParameterList> returnParameters;\n\t\tVisibility visibility = Visibility::Default;\n\t\tStateMutability stateMutability = StateMutability::NonPayable;\n\t\tstd::vector<ASTPointer<ModifierInvocation>> modifiers;\n\t\tASTPointer<Expression> experimentalReturnExpression;\n\t};\n\n\t/// Struct to share parsed function call arguments.\n\tstruct FunctionCallArguments\n\t{\n\t\tstd::vector<ASTPointer<Expression>> arguments;\n\t\tstd::vector<ASTPointer<ASTString>> parameterNames;\n\t\tstd::vector<langutil::SourceLocation> parameterNameLocations;\n\t};\n\n\t///@{\n\t///@name Parsing functions for the AST nodes\n\tvoid parsePragmaVersion(langutil::SourceLocation const& _location, std::vector<Token> const& _tokens, std::vector<std::string> const& _literals);\n\tASTPointer<StructuredDocumentation> parseStructuredDocumentation();\n\tASTPointer<PragmaDirective> parsePragmaDirective(bool _finishedParsingTopLevelPragmas);\n\tASTPointer<ImportDirective> parseImportDirective();\n\t/// @returns an std::pair<ContractKind, bool>, where\n\t/// result.second is set to true, if an abstract contract was parsed, false otherwise.\n\tstd::pair<ContractKind, bool> parseContractKind();\n\tASTPointer<ContractDefinition> parseContractDefinition();\n\tASTPointer<InheritanceSpecifier> parseInheritanceSpecifier();\n\tVisibility parseVisibilitySpecifier();\n\tASTPointer<OverrideSpecifier> parseOverrideSpecifier();\n\tStateMutability parseStateMutability();\n\tFunctionHeaderParserResult parseFunctionHeader(bool _isStateVariable);\n\tASTPointer<ForAllQuantifier> parseQuantifiedFunctionDefinition();\n\tASTPointer<FunctionDefinition> parseFunctionDefinition(bool _freeFunction = false, bool _allowBody = true);\n\tASTPointer<StructDefinition> parseStructDefinition();\n\tASTPointer<EnumDefinition> parseEnumDefinition();\n\tASTPointer<UserDefinedValueTypeDefinition> parseUserDefinedValueTypeDefinition();\n\tASTPointer<EnumValue> parseEnumValue();\n\tASTPointer<VariableDeclaration> parseVariableDeclaration(\n\t\tVarDeclParserOptions const& _options = {},\n\t\tASTPointer<TypeName> const& _lookAheadArrayType = ASTPointer<TypeName>()\n\t);\n\tASTPointer<ModifierDefinition> parseModifierDefinition();\n\tASTPointer<EventDefinition> parseEventDefinition();\n\tASTPointer<ErrorDefinition> parseErrorDefinition();\n\tASTPointer<UsingForDirective> parseUsingDirective();\n\tASTPointer<ModifierInvocation> parseModifierInvocation();\n\tASTPointer<Identifier> parseIdentifier();\n\tASTPointer<Identifier> parseIdentifierOrAddress();\n\tASTPointer<UserDefinedTypeName> parseUserDefinedTypeName();\n\tASTPointer<IdentifierPath> parseIdentifierPath();\n\tASTPointer<TypeName> parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory);\n\tASTPointer<TypeName> parseTypeName();\n\tASTPointer<FunctionTypeName> parseFunctionType();\n\tASTPointer<Mapping> parseMapping();\n\tASTPointer<ParameterList> parseParameterList(\n\t\tVarDeclParserOptions const& _options = {},\n\t\tbool _allowEmpty = true\n\t);\n\tASTPointer<Block> parseBlock(bool _allowUncheckedBlock = false, ASTPointer<ASTString> const& _docString = {});\n\tASTPointer<Statement> parseStatement(bool _allowUncheckedBlock = false);\n\tASTPointer<InlineAssembly> parseInlineAssembly(ASTPointer<ASTString> const& _docString = {});\n\tASTPointer<IfStatement> parseIfStatement(ASTPointer<ASTString> const& _docString);\n\tASTPointer<TryStatement> parseTryStatement(ASTPointer<ASTString> const& _docString);\n\tASTPointer<TryCatchClause> parseCatchClause();\n\tASTPointer<WhileStatement> parseWhileStatement(ASTPointer<ASTString> const& _docString);\n\tASTPointer<WhileStatement> parseDoWhileStatement(ASTPointer<ASTString> const& _docString);\n\tASTPointer<ForStatement> parseForStatement(ASTPointer<ASTString> const& _docString);\n\tASTPointer<EmitStatement> parseEmitStatement(ASTPointer<ASTString> const& docString);\n\tASTPointer<RevertStatement> parseRevertStatement(ASTPointer<ASTString> const& docString);\n\t/// A \"simple statement\" can be a variable declaration statement or an expression statement.\n\tASTPointer<Statement> parseSimpleStatement(ASTPointer<ASTString> const& _docString);\n\tASTPointer<VariableDeclarationStatement> parseVariableDeclarationStatement(\n\t\tASTPointer<ASTString> const& _docString,\n\t\tASTPointer<TypeName> const& _lookAheadArrayType = ASTPointer<TypeName>()\n\t);\n\tASTPointer<ExpressionStatement> parseExpressionStatement(\n\t\tASTPointer<ASTString> const& _docString,\n\t\tASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()\n\t);\n\tASTPointer<Expression> parseExpression(\n\t\tASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()\n\t);\n\tASTPointer<Expression> parseBinaryExpression(int _minPrecedence = 4,\n\t\tASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()\n\t);\n\tASTPointer<Expression> parseUnaryExpression(\n\t\tASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()\n\t);\n\tASTPointer<Expression> parseLeftHandSideExpression(\n\t\tASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>()\n\t);\n\tASTPointer<Expression> parseLiteral();\n\tASTPointer<Expression> parsePrimaryExpression();\n\tstd::vector<ASTPointer<Expression>> parseFunctionCallListArguments();\n\n\tFunctionCallArguments parseFunctionCallArguments();\n\tFunctionCallArguments parseNamedArguments();\n\tstd::pair<ASTPointer<ASTString>, langutil::SourceLocation> expectIdentifierWithLocation();\n\n\tASTPointer<StorageLayoutSpecifier> parseStorageLayoutSpecifier();\n\t///@}\n\n\t///@{\n\t///@name Specialized parsing functions for the AST nodes of experimental solidity.\n\tASTPointer<VariableDeclarationStatement> parsePostfixVariableDeclarationStatement(\n\t\tASTPointer<ASTString> const& _docString\n\t);\n\tASTPointer<VariableDeclaration> parsePostfixVariableDeclaration();\n\tASTPointer<TypeClassDefinition> parseTypeClassDefinition();\n\tASTPointer<TypeClassInstantiation> parseTypeClassInstantiation();\n\tASTPointer<TypeDefinition> parseTypeDefinition();\n\tASTPointer<TypeClassName> parseTypeClassName();\n\t///@}\n\n\t///@{\n\t///@name Helper functions\n\n\t/// @return true if we are at the start of a variable declaration.\n\tbool variableDeclarationStart();\n\n\t/// Used as return value of @see peekStatementType.\n\tenum class LookAheadInfo\n\t{\n\t\tIndexAccessStructure, VariableDeclaration, Expression\n\t};\n\t/// Structure that represents a.b.c[x][y][z]. Can be converted either to an expression\n\t/// or to a type name. For this to be valid, path cannot be empty, but indices can be empty.\n\tstruct IndexAccessedPath\n\t{\n\t\tstruct Index\n\t\t{\n\t\t\tASTPointer<Expression> start;\n\t\t\tstd::optional<ASTPointer<Expression>> end;\n\t\t\tlangutil::SourceLocation location;\n\t\t};\n\t\tstd::vector<ASTPointer<PrimaryExpression>> path;\n\t\tstd::vector<Index> indices;\n\t\tbool empty() const;\n\t};\n\n\tstd::optional<std::string> findLicenseString(std::vector<ASTPointer<ASTNode>> const& _nodes);\n\n\t/// Returns the next AST node ID\n\tint64_t nextID() { return ++m_currentNodeID; }\n\n\tstd::pair<LookAheadInfo, IndexAccessedPath> tryParseIndexAccessedPath();\n\t/// Performs limited look-ahead to distinguish between variable declaration and expression statement.\n\t/// For source code of the form \"a[][8]\" (\"IndexAccessStructure\"), this is not possible to\n\t/// decide with constant look-ahead.\n\tLookAheadInfo peekStatementType() const;\n\t/// @returns an IndexAccessedPath as a prestage to parsing a variable declaration (type name)\n\t/// or an expression;\n\tIndexAccessedPath parseIndexAccessedPath();\n\t/// @returns a typename parsed in look-ahead fashion from something like \"a.b[8][2**70]\",\n\t/// or an empty pointer if an empty @a _pathAndIndices has been supplied.\n\tASTPointer<TypeName> typeNameFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);\n\t/// @returns an expression parsed in look-ahead fashion from something like \"a.b[8][2**70]\",\n\t/// or an empty pointer if an empty @a _pathAndIndices has been supplied.\n\tASTPointer<Expression> expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);\n\n\tASTPointer<ASTString> expectIdentifierToken();\n\tASTPointer<ASTString> expectIdentifierTokenOrAddress();\n\tASTPointer<ASTString> getLiteralAndAdvance();\n\t///@}\n\n\tbool isQuotedPath() const;\n\tbool isStdlibPath() const;\n\n\tint tokenPrecedence(Token _token) const;\n\n\tASTPointer<ASTString> getStdlibImportPathAndAdvance();\n\n\t/// Creates an empty ParameterList at the current location (used if parameters can be omitted).\n\tASTPointer<ParameterList> createEmptyParameterList();\n\n\t/// Flag that signifies whether '_' is parsed as a PlaceholderStatement or a regular identifier.\n\tbool m_insideModifier = false;\n\tlangutil::EVMVersion m_evmVersion;\n\tstd::optional<uint8_t> m_eofVersion;\n\t/// Counter for the next AST node ID\n\tint64_t m_currentNodeID = 0;\n\t/// Flag that indicates whether experimental mode is enabled in the current source unit\n\tbool m_experimentalSolidityEnabledInCurrentSourceUnit = false;\n};\n\n}\n"
  },
  {
    "path": "libsolidity/parsing/Token.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Solidity and Yul both share the same Token (and Scanner) API.\n *\n * This may (or may not) change in the future. But for the time being, we've put both\n * at a shared place, and *just* import them.\n*/\n#pragma once\n\n#include <liblangutil/Token.h>\n\nnamespace solidity::frontend\n{\nnamespace TokenTraits = langutil::TokenTraits;\n\nusing langutil::Token;\nusing langutil::ElementaryTypeNameToken;\n}\n"
  },
  {
    "path": "libsolutil/Algorithms.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n\n#include <functional>\n#include <list>\n#include <set>\n\nnamespace solidity::util\n{\n\n/**\n * Detector for cycles in directed graphs. It returns the first\n * vertex on the path towards a cycle or a nullptr if there is\n * no reachable cycle starting from a given vertex.\n */\ntemplate <typename V>\nclass CycleDetector\n{\npublic:\n\tusing Visitor = std::function<void(V const&, CycleDetector&, size_t)>;\n\n\t/// Initializes the cycle detector\n\t/// @param _visit function that is given the current vertex\n\t///               and is supposed to call @a run on all\n\t///               adjacent vertices.\n\texplicit CycleDetector(Visitor _visit):\n\t\tm_visit(std::move(_visit))\n\t{  }\n\n\t/// Recursively perform cycle detection starting\n\t/// (or continuing) with @param _vertex\n\t/// @returns the first vertex on the path towards a cycle from @a _vertex\n\t/// or nullptr if no cycle is reachable from @a _vertex.\n\tV const* run(V const& _vertex)\n\t{\n\t\tif (m_firstCycleVertex)\n\t\t\treturn m_firstCycleVertex;\n\t\tif (m_processed.count(&_vertex))\n\t\t\treturn nullptr;\n\t\telse if (m_processing.count(&_vertex))\n\t\t\treturn m_firstCycleVertex = &_vertex;\n\t\tm_processing.insert(&_vertex);\n\n\t\tm_depth++;\n\t\tm_visit(_vertex, *this, m_depth);\n\t\tm_depth--;\n\t\tif (m_firstCycleVertex && m_depth == 1)\n\t\t\tm_firstCycleVertex = &_vertex;\n\n\t\tm_processing.erase(&_vertex);\n\t\tm_processed.insert(&_vertex);\n\t\treturn m_firstCycleVertex;\n\t}\n\nprivate:\n\tVisitor m_visit;\n\tstd::set<V const*> m_processing;\n\tstd::set<V const*> m_processed;\n\tsize_t m_depth = 0;\n\tV const* m_firstCycleVertex = nullptr;\n};\n\n/**\n * Generic breadth first search.\n *\n * Note that V needs to be a comparable value type or a pointer.\n *\n * Example: Gather all (recursive) children in a graph starting at (and including) ``root``:\n *\n * Node const* root = ...;\n * std::set<Node const*> allNodes = BreadthFirstSearch<Node const*>{{root}}.run([](Node const* _node, auto&& _addChild) {\n *   // Potentially process ``_node``.\n *   for (Node const& _child: _node->children())\n *     // Potentially filter the children to be visited.\n *     _addChild(&_child);\n * }).visited;\n */\ntemplate<typename V>\nstruct BreadthFirstSearch\n{\n\t/// Runs the breadth first search. The verticesToTraverse member of the struct needs to be initialized.\n\t/// @param _forEachChild is a callable of the form [...](V const& _node, auto&& _addChild) { ... }\n\t/// that is called for each visited node and is supposed to call _addChild(childNode) for every child\n\t/// node of _node.\n\ttemplate<typename ForEachChild>\n\tBreadthFirstSearch& run(ForEachChild&& _forEachChild)\n\t{\n\t\twhile (!verticesToTraverse.empty())\n\t\t{\n\t\t\tV v = std::move(verticesToTraverse.front());\n\t\t\tverticesToTraverse.pop_front();\n\n\t\t\tif (!visited.insert(v).second)\n\t\t\t\tcontinue;\n\n\t\t\t_forEachChild(v, [this](V _vertex) {\n\t\t\t\tverticesToTraverse.emplace_back(std::move(_vertex));\n\t\t\t});\n\t\t}\n\t\treturn *this;\n\t}\n\tvoid abort()\n\t{\n\t\tverticesToTraverse.clear();\n\t}\n\n\tstd::list<V> verticesToTraverse;\n\tstd::set<V> visited{};\n};\n\n}\n"
  },
  {
    "path": "libsolutil/AnsiColorized.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <ostream>\n#include <vector>\n\nnamespace solidity::util\n{\n\nnamespace formatting\n{\n\n// control codes\nstatic constexpr char const* RESET = \"\\033[0m\";\nstatic constexpr char const* INVERSE = \"\\033[7m\";\nstatic constexpr char const* BOLD = \"\\033[1m\";\nstatic constexpr char const* BRIGHT = BOLD;\n\n// standard foreground colors\nstatic constexpr char const* BLACK = \"\\033[30m\";\nstatic constexpr char const* RED = \"\\033[31m\";\nstatic constexpr char const* GREEN = \"\\033[32m\";\nstatic constexpr char const* YELLOW = \"\\033[33m\";\nstatic constexpr char const* BLUE = \"\\033[34m\";\nstatic constexpr char const* MAGENTA = \"\\033[35m\";\nstatic constexpr char const* CYAN = \"\\033[36m\";\nstatic constexpr char const* WHITE = \"\\033[37m\";\n\n// standard background colors\nstatic constexpr char const* BLACK_BACKGROUND = \"\\033[40m\";\nstatic constexpr char const* RED_BACKGROUND = \"\\033[41m\";\nstatic constexpr char const* GREEN_BACKGROUND = \"\\033[42m\";\nstatic constexpr char const* YELLOW_BACKGROUND = \"\\033[43m\";\nstatic constexpr char const* BLUE_BACKGROUND = \"\\033[44m\";\nstatic constexpr char const* MAGENTA_BACKGROUND = \"\\033[45m\";\nstatic constexpr char const* CYAN_BACKGROUND = \"\\033[46m\";\nstatic constexpr char const* WHITE_BACKGROUND = \"\\033[47m\";\nstatic constexpr char const* GRAY_BACKGROUND = \"\\033[100m\";\n\n// 256-bit-colors (incomplete set)\nstatic constexpr char const* RED_BACKGROUND_256 = \"\\033[48;5;160m\";\nstatic constexpr char const* ORANGE_BACKGROUND_256 = \"\\033[48;5;166m\";\n\n}\n\n/// AnsiColorized provides a convenience helper to colorize ostream with formatting-reset assured.\nclass AnsiColorized\n{\npublic:\n\tAnsiColorized(std::ostream& _os, bool const _enabled, std::vector<char const*>&& _formatting):\n\t\tm_stream{_os}, m_enabled{_enabled}, m_codes{std::move(_formatting)}\n\t{\n\t\tif (m_enabled)\n\t\t\tfor (auto const& code: m_codes)\n\t\t\t\tm_stream << code;\n\t}\n\n\t~AnsiColorized()\n\t{\n\t\tif (m_enabled)\n\t\t\tm_stream << formatting::RESET;\n\t}\n\n\ttemplate <typename T>\n\tstd::ostream& operator<<(T&& _t)\n\t{\n\t\treturn m_stream << std::forward<T>(_t);\n\t}\n\nprivate:\n\tstd::ostream& m_stream;\n\tbool m_enabled;\n\tstd::vector<char const*> m_codes;\n};\n\n}\n"
  },
  {
    "path": "libsolutil/Assertions.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @file Assertions.h\n * @author Christian <c@ethdev.com>\n * @date 2015\n *\n * Assertion handling.\n */\n\n#pragma once\n\n#include <libsolutil/Exceptions.h>\n#include <libsolutil/CommonData.h>\n\n#include <string>\n#include <utility>\n\nnamespace solidity::util\n{\n\n#if defined(_MSC_VER)\n#define ETH_FUNC __FUNCSIG__\n#elif defined(__GNUC__)\n#define ETH_FUNC __PRETTY_FUNCTION__\n#else\n#define ETH_FUNC __func__\n#endif\n\n#if defined(__GNUC__)\n// GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above)\n[[noreturn]] inline __attribute__((always_inline)) void unreachable()\n{\n\t__builtin_unreachable();\n}\n\n#elif defined(_MSC_VER) // MSVC\n\n[[noreturn]] __forceinline void unreachable()\n{\n\t__assume(false);\n}\n\n#else\n\n[[noreturn]] inline void unreachable()\n{\n\tsolThrow(Exception, \"Unreachable\");\n}\n#endif\n\n/// Base macro that can be used to implement assertion macros.\n/// Throws an exception containing the given description if the condition is not met.\n/// Allows you to provide the default description for the case where the user of your macro does\n/// not provide any.\n/// The second parameter must be an exception class (rather than an instance).\n#define assertThrowWithDefaultDescription(_condition, _exceptionType, _description, _defaultDescription) \\\n\tdo \\\n\t{ \\\n\t\tif (!(_condition)) \\\n\t\t\tsolThrow( \\\n\t\t\t\t_exceptionType, \\\n\t\t\t\t::solidity::util::stringOrDefault((_description), (_defaultDescription)) \\\n\t\t\t); \\\n\t} \\\n\twhile (false)\n\n/// Assertion that throws an exception containing the given description if it is not met.\n/// Use it as assertThrow(1 == 1, ExceptionType, \"Mathematics is wrong.\");\n/// The second parameter must be an exception class (rather than an instance).\n#define assertThrow(_condition, _exceptionType, _description) \\\n\tassertThrowWithDefaultDescription((_condition), _exceptionType, (_description), \"Assertion failed\")\n\n}\n"
  },
  {
    "path": "libsolutil/CMakeLists.txt",
    "content": "set(sources\n\tAlgorithms.h\n\tAnsiColorized.h\n\tAssertions.h\n\tCommon.h\n\tCommonData.cpp\n\tCommonData.h\n\tCommonIO.cpp\n\tCommonIO.h\n\tDisjointSet.cpp\n\tDisjointSet.h\n\tDominatorFinder.h\n\tExceptions.cpp\n\tExceptions.h\n\tErrorCodes.h\n\tFixedHash.h\n\tFunctionSelector.h\n\tIpfsHash.cpp\n\tIpfsHash.h\n\tJSON.cpp\n\tJSON.h\n\tKeccak256.cpp\n\tKeccak256.h\n\tLazyInit.h\n\tLEB128.h\n\tNumeric.cpp\n\tNumeric.h\n\tpicosha2.h\n\tProfiler.cpp\n\tProfiler.h\n\tResult.h\n\tSetOnce.h\n\tStackTooDeepString.h\n\tStringUtils.cpp\n\tStringUtils.h\n\tSwarmHash.cpp\n\tSwarmHash.h\n\tTemporaryDirectory.cpp\n\tTemporaryDirectory.h\n\tUTF8.cpp\n\tUTF8.h\n\tvector_ref.h\n\tViews.h\n\tVisitor.h\n\tWhiskers.cpp\n\tWhiskers.h\n)\n\nadd_library(solutil ${sources})\ntarget_link_libraries(solutil PUBLIC Boost::boost Boost::filesystem ${Boost_SYSTEM_LIBRARY} range-v3 fmt::fmt-header-only nlohmann_json::nlohmann_json)\ntarget_include_directories(solutil PUBLIC \"${PROJECT_SOURCE_DIR}\")\nadd_dependencies(solutil solidity_BuildInfo.h)\n\nif(SOLC_LINK_STATIC)\n\ttarget_link_libraries(solutil PUBLIC Threads::Threads)\nendif()\n"
  },
  {
    "path": "libsolutil/Common.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file Common.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * Very common stuff (i.e. that every other header needs except vector_ref.h).\n */\n\n#pragma once\n\n// way too many unsigned to size_t warnings in 32 bit build\n#ifdef _M_IX86\n#pragma warning(disable:4244)\n#endif\n\n#if _MSC_VER && _MSC_VER < 1900\n#define _ALLOW_KEYWORD_MACROS\n#define noexcept throw()\n#endif\n\n#ifdef __INTEL_COMPILER\n#pragma warning(disable:3682) //call through incomplete class\n#endif\n\n#include <libsolutil/vector_ref.h>\n\n#include <boost/version.hpp>\n\n#include <cstdint>\n#include <concepts>\n#include <functional>\n#include <map>\n#include <string>\n#include <utility>\n#include <vector>\n\nnamespace solidity\n{\n\nnamespace concepts\n{\n/// Concept denoting some arithmetic type.\ntemplate <typename T>\nconcept arithmetic = std::integral<T> || std::floating_point<T>;\n}\n\n// Binary data types.\nusing bytes = std::vector<uint8_t>;\nusing bytesRef = util::vector_ref<uint8_t>;\nusing bytesConstRef = util::vector_ref<uint8_t const>;\n\n// Map types.\nusing StringMap = std::map<std::string, std::string>;\n\n// String types.\nusing strings = std::vector<std::string>;\n\n/// RAII utility class whose destructor calls a given function.\nclass ScopeGuard\n{\npublic:\n\texplicit ScopeGuard(std::function<void(void)> _f): m_f(std::move(_f)) {}\n\t~ScopeGuard() { m_f(); }\n\nprivate:\n\tstd::function<void(void)> m_f;\n};\n\n/// RAII utility class that sets the value of a variable for the current scope and restores it to its old value\n/// during its destructor.\ntemplate<typename V>\nclass ScopedSaveAndRestore\n{\npublic:\n\texplicit ScopedSaveAndRestore(V& _variable, V&& _value): m_variable(_variable), m_oldValue(std::move(_value))\n\t{\n\t\tstd::swap(m_variable, m_oldValue);\n\t}\n\tScopedSaveAndRestore(ScopedSaveAndRestore const&) = delete;\n\t~ScopedSaveAndRestore() { std::swap(m_variable, m_oldValue); }\n\tScopedSaveAndRestore& operator=(ScopedSaveAndRestore const&) = delete;\n\nprivate:\n\tV& m_variable;\n\tV m_oldValue;\n};\n\ntemplate<typename V, typename... Args>\nScopedSaveAndRestore(V, Args...) -> ScopedSaveAndRestore<V>;\n\n}\n"
  },
  {
    "path": "libsolutil/CommonData.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file CommonData.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <libsolutil/Assertions.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Exceptions.h>\n#include <libsolutil/FixedHash.h>\n#include <libsolutil/Keccak256.h>\n#include <libsolutil/StringUtils.h>\n\n#include <boost/algorithm/string.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\n\nnamespace\n{\n\nstatic char const* upperHexChars = \"0123456789ABCDEF\";\nstatic char const* lowerHexChars = \"0123456789abcdef\";\n\n}\n\nstd::string solidity::util::toHex(uint8_t _data, HexCase _case)\n{\n\tassertThrow(_case != HexCase::Mixed, BadHexCase, \"Mixed case can only be used for byte arrays.\");\n\n\tchar const* chars = _case == HexCase::Upper ? upperHexChars : lowerHexChars;\n\n\treturn std::string{\n\t\tchars[(unsigned(_data) / 16) & 0xf],\n\t\tchars[unsigned(_data) & 0xf]\n\t};\n}\n\nstd::string solidity::util::toHex(bytes const& _data, HexPrefix _prefix, HexCase _case)\n{\n\tstd::string ret(_data.size() * 2 + (_prefix == HexPrefix::Add ? 2 : 0), 0);\n\n\tsize_t i = 0;\n\tif (_prefix == HexPrefix::Add)\n\t{\n\t\tret[i++] = '0';\n\t\tret[i++] = 'x';\n\t}\n\n\t// Mixed case will be handled inside the loop.\n\tchar const* chars = _case == HexCase::Upper ? upperHexChars : lowerHexChars;\n\tsize_t rix = _data.size() - 1;\n\tfor (uint8_t c: _data)\n\t{\n\t\t// switch hex case every four hexchars\n\t\tif (_case == HexCase::Mixed)\n\t\t\tchars = (rix-- & 2) == 0 ? lowerHexChars : upperHexChars;\n\n\t\tret[i++] = chars[(static_cast<size_t>(c) >> 4ul) & 0xfu];\n\t\tret[i++] = chars[c & 0xfu];\n\t}\n\tassertThrow(i == ret.size(), Exception, \"\");\n\n\treturn ret;\n}\n\nint solidity::util::fromHex(char _i, WhenError _throw)\n{\n\tif (_i >= '0' && _i <= '9')\n\t\treturn _i - '0';\n\tif (_i >= 'a' && _i <= 'f')\n\t\treturn _i - 'a' + 10;\n\tif (_i >= 'A' && _i <= 'F')\n\t\treturn _i - 'A' + 10;\n\tif (_throw == WhenError::Throw)\n\t\tassertThrow(false, BadHexCharacter, std::to_string(_i));\n\telse\n\t\treturn -1;\n}\n\nbytes solidity::util::fromHex(std::string const& _s, WhenError _throw)\n{\n\tif (_s.empty())\n\t\treturn {};\n\n\tunsigned s = (_s.size() >= 2 && _s[0] == '0' && _s[1] == 'x') ? 2 : 0;\n\tstd::vector<uint8_t> ret;\n\tret.reserve((_s.size() - s + 1) / 2);\n\n\tif (_s.size() % 2)\n\t{\n\t\tint h = fromHex(_s[s++], _throw);\n\t\tif (h != -1)\n\t\t\tret.push_back(static_cast<uint8_t>(h));\n\t\telse\n\t\t\treturn bytes();\n\t}\n\tfor (unsigned i = s; i < _s.size(); i += 2)\n\t{\n\t\tint h = fromHex(_s[i], _throw);\n\t\tint l = fromHex(_s[i + 1], _throw);\n\t\tif (h != -1 && l != -1)\n\t\t\tret.push_back(static_cast<uint8_t>(h * 16 + l));\n\t\telse\n\t\t\treturn bytes();\n\t}\n\treturn ret;\n}\n\n\nbool solidity::util::passesAddressChecksum(std::string const& _str, bool _strict)\n{\n\tstd::string s = _str.substr(0, 2) == \"0x\" ? _str : \"0x\" + _str;\n\n\tif (s.length() != 42)\n\t\treturn false;\n\n\tif (!_strict && (\n\t\ts.find_first_of(\"abcdef\") == std::string::npos ||\n\t\ts.find_first_of(\"ABCDEF\") == std::string::npos\n\t))\n\t\treturn true;\n\n\treturn s == solidity::util::getChecksummedAddress(s);\n}\n\nstd::string solidity::util::getChecksummedAddress(std::string const& _addr)\n{\n\tstd::string s = _addr.substr(0, 2) == \"0x\" ? _addr.substr(2) : _addr;\n\tassertThrow(s.length() == 40, InvalidAddress, \"\");\n\tassertThrow(s.find_first_not_of(\"0123456789abcdefABCDEF\") == std::string::npos, InvalidAddress, \"\");\n\n\th256 hash = keccak256(boost::algorithm::to_lower_copy(s, std::locale::classic()));\n\n\tstd::string ret = \"0x\";\n\tfor (unsigned i = 0; i < 40; ++i)\n\t{\n\t\tchar addressCharacter = s[i];\n\t\tuint8_t nibble = hash[i / 2u] >> (4u * (1u - (i % 2u))) & 0xf;\n\t\tif (nibble >= 8)\n\t\t\tret += toUpper(addressCharacter);\n\t\telse\n\t\t\tret += toLower(addressCharacter);\n\t}\n\treturn ret;\n}\n\nbool solidity::util::isValidHex(std::string_view const _string)\n{\n\tif (_string.substr(0, 2) != \"0x\")\n\t\treturn false;\n\tif (_string.find_first_not_of(\"0123456789abcdefABCDEF\", 2) != std::string::npos)\n\t\treturn false;\n\treturn true;\n}\n\nbool solidity::util::isValidDecimal(std::string_view const _string)\n{\n\tif (_string.empty())\n\t\treturn false;\n\tif (_string == \"0\")\n\t\treturn true;\n\t// No leading zeros\n\tif (_string.front() == '0')\n\t\treturn false;\n\tif (_string.find_first_not_of(\"0123456789\") != std::string::npos)\n\t\treturn false;\n\treturn true;\n}\n\nstd::string solidity::util::formatAsStringOrNumber(std::string const& _value)\n{\n\tassertThrow(_value.length() <= 32, StringTooLong, \"String to be formatted longer than 32 bytes.\");\n\n\tfor (auto const& c: _value)\n\t\tif (c <= 0x1f || c >= 0x7f || c == '\"')\n\t\t\treturn \"0x\" + h256(_value, h256::AlignLeft).hex();\n\n\treturn escapeAndQuoteString(_value);\n}\n\n\nstd::string solidity::util::escapeAndQuoteString(std::string const& _input)\n{\n\tstd::string out;\n\n\tfor (char c: _input)\n\t\tif (c == '\\\\')\n\t\t\tout += \"\\\\\\\\\";\n\t\telse if (c == '\"')\n\t\t\tout += \"\\\\\\\"\";\n\t\telse if (c == '\\n')\n\t\t\tout += \"\\\\n\";\n\t\telse if (c == '\\r')\n\t\t\tout += \"\\\\r\";\n\t\telse if (c == '\\t')\n\t\t\tout += \"\\\\t\";\n\t\telse if (!isPrint(c))\n\t\t{\n\t\t\tstd::ostringstream o;\n\t\t\to << \"\\\\x\" << std::hex << std::setfill('0') << std::setw(2) << (unsigned)(unsigned char)(c);\n\t\t\tout += o.str();\n\t\t}\n\t\telse\n\t\t\tout += c;\n\n\treturn \"\\\"\" + std::move(out) + \"\\\"\";\n}\n"
  },
  {
    "path": "libsolutil/CommonData.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file CommonData.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * Shared algorithms and data types.\n */\n\n#pragma once\n\n#include <iterator>\n#include <libsolutil/Common.h>\n\n#include <vector>\n#include <type_traits>\n#include <cstring>\n#include <optional>\n#include <string>\n#include <set>\n#include <functional>\n#include <utility>\n#include <type_traits>\n#include <list>\n#include <algorithm>\n\n/// Operators need to stay in the global namespace.\n\n/// Concatenate the contents of a container onto a vector\ntemplate <class T, class U> std::vector<T>& operator+=(std::vector<T>& _a, U& _b)\n{\n\tfor (auto const& i: _b)\n\t\t_a.push_back(T(i));\n\treturn _a;\n}\n/// Concatenate the contents of a container onto a vector, move variant.\ntemplate <class T, class U> std::vector<T>& operator+=(std::vector<T>& _a, U&& _b)\n{\n\tstd::move(_b.begin(), _b.end(), std::back_inserter(_a));\n\treturn _a;\n}\n\n/// Concatenate the contents of a container onto a list\ntemplate <class T, class U> std::list<T>& operator+=(std::list<T>& _a, U& _b)\n{\n\tfor (auto const& i: _b)\n\t\t_a.push_back(T(i));\n\treturn _a;\n}\n/// Concatenate the contents of a container onto a list, move variant.\ntemplate <class T, class U> std::list<T>& operator+=(std::list<T>& _a, U&& _b)\n{\n\tstd::move(_b.begin(), _b.end(), std::back_inserter(_a));\n\treturn _a;\n}\n\n/// Concatenate the contents of a container onto a multiset\ntemplate <class U, class... T> std::multiset<T...>& operator+=(std::multiset<T...>& _a, U& _b)\n{\n\t_a.insert(_b.begin(), _b.end());\n\treturn _a;\n}\n/// Concatenate the contents of a container onto a multiset, move variant.\ntemplate <class U, class... T> std::multiset<T...>& operator+=(std::multiset<T...>& _a, U&& _b)\n{\n\tfor (auto&& x: _b)\n\t\t_a.insert(std::move(x));\n\treturn _a;\n}\n/// Concatenate the contents of a container onto a set\ntemplate <class U, class... T> std::set<T...>& operator+=(std::set<T...>& _a, U& _b)\n{\n\t_a.insert(_b.begin(), _b.end());\n\treturn _a;\n}\n/// Concatenate the contents of a container onto a set, move variant.\ntemplate <class U, class... T> std::set<T...>& operator+=(std::set<T...>& _a, U&& _b)\n{\n\tfor (auto&& x: _b)\n\t\t_a.insert(std::move(x));\n\treturn _a;\n}\n\n/// Concatenate two vectors of elements.\ntemplate <class T>\ninline std::vector<T> operator+(std::vector<T> const& _a, std::vector<T> const& _b)\n{\n\tstd::vector<T> ret(_a);\n\tret += _b;\n\treturn ret;\n}\n\n/// Concatenate two vectors of elements, moving them.\ntemplate <class T>\ninline std::vector<T> operator+(std::vector<T>&& _a, std::vector<T>&& _b)\n{\n\tstd::vector<T> ret(std::move(_a));\n\tassert(&_a != &_b);\n\tret += std::move(_b);\n\treturn ret;\n}\n\n/// Concatenate something to a sets of elements.\ntemplate <class U, class... T>\ninline std::set<T...> operator+(std::set<T...> const& _a, U&& _b)\n{\n\tstd::set<T...> ret(_a);\n\tret += std::forward<U>(_b);\n\treturn ret;\n}\n\n/// Concatenate something to a sets of elements, move variant.\ntemplate <class U, class... T>\ninline std::set<T...> operator+(std::set<T...>&& _a, U&& _b)\n{\n\tstd::set<T...> ret(std::move(_a));\n\tret += std::forward<U>(_b);\n\treturn ret;\n}\n\n/// Remove the elements of a container from a set.\ntemplate <class C, class... T>\ninline std::set<T...>& operator-=(std::set<T...>& _a, C const& _b)\n{\n\tfor (auto const& x: _b)\n\t\t_a.erase(x);\n\treturn _a;\n}\n\ntemplate <class C, class... T>\ninline std::set<T...> operator-(std::set<T...> const& _a, C const& _b)\n{\n\tauto result = _a;\n\tresult -= _b;\n\treturn result;\n}\n\n/// Remove the elements of a container from a multiset.\ntemplate <class C, class... T>\ninline std::multiset<T...>& operator-=(std::multiset<T...>& _a, C const& _b)\n{\n\tfor (auto const& x: _b)\n\t\t_a.erase(x);\n\treturn _a;\n}\n\nnamespace solidity::util\n{\n\n/// Functional map.\n/// Returns a container _oc applying @param _op to each element in @param _c.\n/// By default _oc is a vector.\n/// If another return type is desired, an empty contained of that type\n/// is given as @param _oc.\ntemplate<class Container, class Callable, class OutputContainer =\n\tstd::vector<std::invoke_result_t<\n\t\tCallable,\n\t\tdecltype(*std::begin(std::declval<Container>()))\n>>>\nauto applyMap(Container const& _c, Callable&& _op, OutputContainer _oc = OutputContainer{})\n{\n\tstd::transform(std::begin(_c), std::end(_c), std::inserter(_oc, std::end(_oc)), _op);\n\treturn _oc;\n}\n\n/// Filter a vector.\n/// Returns a copy of the vector after only taking indices `i` such that `_mask[i]` is true.\ntemplate<typename T>\nstd::vector<T> filter(std::vector<T> const& _vec, std::vector<bool> const& _mask)\n{\n\tassert(_vec.size() == _mask.size());\n\n\tstd::vector<T> ret;\n\n\tfor (size_t i = 0; i < _mask.size(); ++i)\n\t\tif (_mask[i])\n\t\t\tret.push_back(_vec[i]);\n\n\treturn ret;\n}\n\n/// Functional fold.\n/// Given a container @param _c, an initial value @param _acc,\n/// and a binary operator @param _binaryOp(T, U), accumulate\n/// the elements of _c over _acc.\n/// Note that <numeric> has a similar function `accumulate` which\n/// until C++20 does *not* std::move the partial accumulated.\ntemplate<class C, class T, class Callable>\nauto fold(C const& _c, T _acc, Callable&& _binaryOp)\n{\n\tfor (auto const& e: _c)\n\t\t_acc = _binaryOp(std::move(_acc), e);\n\treturn _acc;\n}\n\ntemplate <class T, class U>\nT convertContainer(U const& _from)\n{\n\treturn T{_from.cbegin(), _from.cend()};\n}\n\ntemplate <class T, class U>\nT convertContainer(U&& _from)\n{\n\treturn T{\n\t\tstd::make_move_iterator(_from.begin()),\n\t\tstd::make_move_iterator(_from.end())\n\t};\n}\n\n/// Gets a @a K -> @a V map and returns a map where values from the original map are keys and keys\n/// from the original map are values.\n///\n/// @pre @a originalMap must have unique values.\ntemplate <typename K, typename V>\nstd::map<V, K> invertMap(std::map<K, V> const& originalMap)\n{\n\tstd::map<V, K> inverseMap;\n\tfor (auto const& originalPair: originalMap)\n\t{\n\t\tassert(inverseMap.count(originalPair.second) == 0);\n\t\tinverseMap.insert({originalPair.second, originalPair.first});\n\t}\n\n\treturn inverseMap;\n}\n\n/// Returns a set of keys of a map.\ntemplate <typename K, typename V>\nstd::set<K> keys(std::map<K, V> const& _map)\n{\n\treturn applyMap(_map, [](auto const& _elem) { return _elem.first; }, std::set<K>{});\n}\n\n/// @returns a pointer to the entry of @a _map at @a _key, if there is one, and nullptr otherwise.\ntemplate<typename MapType, typename KeyType>\ndecltype(auto) valueOrNullptr(MapType&& _map, KeyType const& _key)\n{\n\tauto it = _map.find(_key);\n\treturn (it == _map.end()) ? nullptr : &it->second;\n}\n\nnamespace detail\n{\nstruct allow_copy {};\n}\nstatic constexpr auto allow_copy = detail::allow_copy{};\n\n/// @returns a reference to the entry of @a _map at @a _key, if there is one, and @a _defaultValue otherwise.\n/// Makes sure no copy is involved, unless allow_copy is passed as fourth argument.\ntemplate<\n\ttypename MapType,\n\ttypename KeyType,\n\ttypename ValueType = std::decay_t<decltype(std::declval<MapType>().find(std::declval<KeyType>())->second)> const&,\n\ttypename AllowCopyType = std::conditional_t<(std::is_trivial_v<ValueType> && std::is_standard_layout_v<ValueType>) || std::is_pointer_v<ValueType>, detail::allow_copy, void*>\n>\ndecltype(auto) valueOrDefault(\n\tMapType&& _map,\n\tKeyType const& _key,\n\tValueType&& _defaultValue = {},\n\tAllowCopyType = {}\n)\n{\n\tauto it = _map.find(_key);\n\tstatic_assert(\n\t\tstd::is_same_v<AllowCopyType, detail::allow_copy> ||\n\t\tstd::is_reference_v<decltype((it == _map.end()) ? std::forward<ValueType>(_defaultValue) : it->second)>,\n\t\t\"valueOrDefault does not allow copies by default. Pass allow_copy as additional argument, if you want to allow copies.\"\n\t);\n\treturn (it == _map.end()) ? std::forward<ValueType>(_defaultValue) : it->second;\n}\n\nnamespace detail\n{\ntemplate<typename Callable>\nstruct MapTuple\n{\n\tCallable callable;\n\ttemplate<typename TupleType>\n\tdecltype(auto) operator()(TupleType&& _tuple) {\n\t\tusing PlainTupleType = std::remove_cv_t<std::remove_reference_t<TupleType>>;\n\t\treturn operator()(\n\t\t\tstd::forward<TupleType>(_tuple),\n\t\t\tstd::make_index_sequence<std::tuple_size_v<PlainTupleType>>{}\n\t\t);\n\t}\nprivate:\n\ttemplate<typename TupleType, size_t... I>\n\tdecltype(auto) operator()(TupleType&& _tuple, std::index_sequence<I...>)\n\t{\n\t\treturn callable(std::get<I>(std::forward<TupleType>(_tuple))...);\n\t}\n};\n}\n\n/// Wraps @a _callable, which takes multiple arguments, into a callable that takes a single tuple of arguments.\n/// Since structured binding in lambdas is not allowed, i.e. [](auto&& [key, value]) { ... } is invalid, this allows\n/// to instead use mapTuple([](auto&& key, auto&& value) { ... }).\ntemplate<typename Callable>\ndecltype(auto) mapTuple(Callable&& _callable)\n{\n\treturn detail::MapTuple<Callable>{std::forward<Callable>(_callable)};\n}\n\n/// Merges map @a _b into map @a _a. If the same key exists in both maps,\n/// calls @a _conflictSolver to combine the two values.\ntemplate <class K, class V, class F>\nvoid joinMap(std::map<K, V>& _a, std::map<K, V>&& _b, F _conflictSolver)\n{\n\tauto ita = _a.begin();\n\tauto aend = _a.end();\n\tauto itb = _b.begin();\n\tauto bend = _b.end();\n\n\tfor (; itb != bend; ++ita)\n\t{\n\t\tif (ita == aend)\n\t\t\tita = _a.insert(ita, std::move(*itb++));\n\t\telse if (ita->first < itb->first)\n\t\t\tcontinue;\n\t\telse if (itb->first < ita->first)\n\t\t\tita = _a.insert(ita, std::move(*itb++));\n\t\telse\n\t\t{\n\t\t\t_conflictSolver(ita->second, std::move(itb->second));\n\t\t\t++itb;\n\t\t}\n\t}\n}\n\ntemplate<typename T>\nclass UniqueVector\n{\npublic:\n\tstd::vector<T> const& contents() const { return m_contents; }\n\tsize_t size() const { return m_contents.size(); }\n\tbool empty() const { return m_contents.empty(); }\n\tauto begin() const { return m_contents.begin(); }\n\tauto end() const { return m_contents.end(); }\n\tvoid clear() { m_contents.clear(); }\n\tbool contains(T const& _value) const\n\t{\n\t\treturn std::find(m_contents.begin(), m_contents.end(), _value) != m_contents.end();\n\t}\n\n\tvoid pushBack(T _value)\n\t{\n\t\tif (!contains(_value))\n\t\t\tm_contents.emplace_back(std::move(_value));\n\t}\n\n\tvoid pushBack(UniqueVector<T> const& _values)\n\t{\n\t\tfor (auto&& value: _values)\n\t\t\tpushBack(value);\n\t}\n\n\tvoid removeAll(std::vector<T> const& _values)\n\t{\n\t\tfor (auto const& value: _values)\n\t\t\tm_contents.erase(std::find(m_contents.begin(), m_contents.end(), value));\n\t}\n\nprivate:\n\tstd::vector<T> m_contents;\n};\n\nnamespace detail\n{\n\ntemplate<typename Container, typename Value>\nauto findOffset(Container&& _container, Value&& _value, int)\n-> decltype(_container.find(_value) == _container.end(), std::distance(_container.begin(), _container.find(_value)), std::optional<size_t>())\n{\n\tauto it = _container.find(std::forward<Value>(_value));\n\tauto end = _container.end();\n\tif (it == end)\n\t\treturn std::nullopt;\n\treturn std::distance(_container.begin(), it);\n}\ntemplate<typename Range, typename Value>\nauto findOffset(Range&& _range, Value&& _value, void*)\n-> decltype(std::find(std::begin(_range), std::end(_range), std::forward<Value>(_value)) == std::end(_range), std::optional<size_t>())\n{\n\tauto begin = std::begin(_range);\n\tauto end = std::end(_range);\n\tauto it = std::find(begin, end, std::forward<Value>(_value));\n\tif (it == end)\n\t\treturn std::nullopt;\n\treturn std::distance(begin, it);\n}\n\n}\n\n/// @returns an std::optional<size_t> containing the offset of the first element in @a _range that is equal to @a _value,\n/// if any, or std::nullopt otherwise.\n/// Uses a linear search (``std::find``) unless @a _range is a container and provides a\n/// suitable ``.find`` function (e.g. it will use the logarithmic ``.find`` function in ``std::set`` instead).\ntemplate<typename Range>\nauto findOffset(Range&& _range, std::remove_reference_t<decltype(*std::cbegin(_range))> const& _value)\n-> decltype(detail::findOffset(std::forward<Range>(_range), _value, 0))\n{\n\treturn detail::findOffset(std::forward<Range>(_range), _value, 0);\n}\n\n// String conversion functions, mainly to/from hex/nibble/byte representations.\n\nenum class WhenError\n{\n\tDontThrow = 0,\n\tThrow = 1,\n};\n\nenum class HexPrefix\n{\n\tDontAdd = 0,\n\tAdd = 1,\n};\n\nenum class HexCase\n{\n\tLower = 0,\n\tUpper = 1,\n\tMixed = 2,\n};\n\n/// Convert a single byte to a string of hex characters (of length two),\n/// optionally with uppercase hex letters.\nstd::string toHex(uint8_t _data, HexCase _case = HexCase::Lower);\n\n/// Convert a series of bytes to the corresponding string of hex duplets,\n/// optionally with \"0x\" prefix and with uppercase hex letters.\nstd::string toHex(bytes const& _data, HexPrefix _prefix = HexPrefix::DontAdd, HexCase _case = HexCase::Lower);\n\n/// Converts a (printable) ASCII hex character into the corresponding integer value.\n/// @example fromHex('A') == 10 && fromHex('f') == 15 && fromHex('5') == 5\nint fromHex(char _i, WhenError _throw);\n\n/// Converts a (printable) ASCII hex string into the corresponding byte stream.\n/// @example fromHex(\"41626261\") == asBytes(\"Abba\")\n/// If _throw = WhenError::DontThrow, it returns an empty bytes array on any validation error, otherwise it will throw an exception.\nbytes fromHex(std::string const& _s, WhenError _throw = WhenError::DontThrow);\n/// Converts byte array to a string containing the same (binary) data. Unless\n/// the byte array happens to contain ASCII data, this won't be printable.\ninline std::string asString(bytes const& _b)\n{\n\treturn std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size()));\n}\n\n/// Converts byte array ref to a string containing the same (binary) data. Unless\n/// the byte array happens to contain ASCII data, this won't be printable.\ninline std::string asString(bytesConstRef _b)\n{\n\treturn std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size()));\n}\n\n/// Converts a string to a byte array containing the string's (byte) data.\ninline bytes asBytes(std::string_view const _b)\n{\n\treturn bytes((uint8_t const*)_b.data(), (uint8_t const*)(_b.data() + _b.size()));\n}\n\ntemplate <class T, class V>\nbool contains(T const& _t, V const& _v)\n{\n\treturn std::end(_t) != std::find(std::begin(_t), std::end(_t), _v);\n}\n\ntemplate <class T, class Predicate>\nbool contains_if(T const& _t, Predicate const& _p)\n{\n\treturn std::end(_t) != std::find_if(std::begin(_t), std::end(_t), _p);\n}\n\n/// Function that iterates over a vector, calling a function on each of its\n/// elements. If that function returns a vector, the element is replaced by\n/// the returned vector. During the iteration, the original vector is only valid\n/// on the current element and after that. The actual replacement takes\n/// place at the end, but already visited elements might be invalidated.\n/// If nothing is replaced, no copy is performed.\ntemplate <typename T, typename F>\nvoid iterateReplacing(std::vector<T>& _vector, F const& _f)\n{\n\t// Concept: _f must be Callable, must accept param T&, must return optional<vector<T>>\n\tbool useModified = false;\n\tstd::vector<T> modifiedVector;\n\tfor (size_t i = 0; i < _vector.size(); ++i)\n\t{\n\t\tif (std::optional<std::vector<T>> r = _f(_vector[i]))\n\t\t{\n\t\t\tif (!useModified)\n\t\t\t{\n\t\t\t\tstd::move(_vector.begin(), _vector.begin() + ptrdiff_t(i), back_inserter(modifiedVector));\n\t\t\t\tuseModified = true;\n\t\t\t}\n\t\t\tmodifiedVector += std::move(*r);\n\t\t}\n\t\telse if (useModified)\n\t\t\tmodifiedVector.emplace_back(std::move(_vector[i]));\n\t}\n\tif (useModified)\n\t\t_vector = std::move(modifiedVector);\n}\n\nnamespace detail\n{\ntemplate <typename T, typename F, std::size_t... I>\nvoid iterateReplacingWindow(std::vector<T>& _vector, F const& _f, std::index_sequence<I...>)\n{\n\t// Concept: _f must be Callable, must accept sizeof...(I) parameters of type T&, must return optional<vector<T>>\n\tbool useModified = false;\n\tstd::vector<T> modifiedVector;\n\tsize_t i = 0;\n\tfor (; i + sizeof...(I) <= _vector.size(); ++i)\n\t{\n\t\tif (std::optional<std::vector<T>> r = _f(_vector[i + I]...))\n\t\t{\n\t\t\tif (!useModified)\n\t\t\t{\n\t\t\t\tstd::move(_vector.begin(), _vector.begin() + ptrdiff_t(i), back_inserter(modifiedVector));\n\t\t\t\tuseModified = true;\n\t\t\t}\n\t\t\tmodifiedVector += std::move(*r);\n\t\t\ti += sizeof...(I) - 1;\n\t\t}\n\t\telse if (useModified)\n\t\t\tmodifiedVector.emplace_back(std::move(_vector[i]));\n\t}\n\tif (useModified)\n\t{\n\t\tfor (; i < _vector.size(); ++i)\n\t\t\tmodifiedVector.emplace_back(std::move(_vector[i]));\n\t\t_vector = std::move(modifiedVector);\n\t}\n}\n\n}\n\n/// Checks if two collections possess a non-empty intersection.\n/// Assumes that both inputs are sorted in ascending order.\ntemplate<typename Collection1, typename Collection2>\nrequires (\n\tstd::forward_iterator<std::ranges::iterator_t<Collection1>> &&\n\tstd::forward_iterator<std::ranges::iterator_t<Collection2>>\n)\nbool hasNonemptyIntersectionSorted(Collection1 const& _collection1, Collection2 const& _collection2)\n{\n\tauto it1 = std::ranges::begin(_collection1);\n\tauto it2 = std::ranges::begin(_collection2);\n\twhile (it1 != std::ranges::end(_collection1) && it2 != std::ranges::end(_collection2))\n\t{\n\t\tif (*it1 == *it2)\n\t\t\treturn true;\n\t\tif (*it1 < *it2)\n\t\t\t++it1;\n\t\telse\n\t\t\t++it2;\n\t}\n\treturn false;\n}\n\n/// Function that iterates over the vector @param _vector,\n/// calling the function @param _f on sequences of @tparam N of its\n/// elements. If @param _f returns a vector, these elements are replaced by\n/// the returned vector and the iteration continues with the next @tparam N elements.\n/// If the function does not return a vector, the iteration continues with an overlapping\n/// sequence of @tparam N elements that starts with the second element of the previous\n/// iteration.\n/// During the iteration, the original vector is only valid\n/// on the current element and after that. The actual replacement takes\n/// place at the end, but already visited elements might be invalidated.\n/// If nothing is replaced, no copy is performed.\ntemplate <std::size_t N, typename T, typename F>\nvoid iterateReplacingWindow(std::vector<T>& _vector, F const& _f)\n{\n\t// Concept: _f must be Callable, must accept N parameters of type T&, must return optional<vector<T>>\n\tdetail::iterateReplacingWindow(_vector, _f, std::make_index_sequence<N>{});\n}\n\n/// @returns true iff @a _str passes the hex address checksum test.\n/// @param _strict if false, hex strings with only uppercase or only lowercase letters\n/// are considered valid.\nbool passesAddressChecksum(std::string const& _str, bool _strict);\n\n/// @returns the checksummed version of an address\n/// @param hex strings that look like an address\nstd::string getChecksummedAddress(std::string const& _addr);\n\nbool isValidHex(std::string_view _string);\nbool isValidDecimal(std::string_view _string);\n\n/// @returns a quoted string if all characters are printable ASCII chars,\n/// or its hex representation otherwise.\n/// _value cannot be longer than 32 bytes.\nstd::string formatAsStringOrNumber(std::string const& _value);\n\n/// @returns a string with the usual backslash-escapes for non-printable and non-ASCII\n/// characters and surrounded by '\"'-characters.\nstd::string escapeAndQuoteString(std::string const& _input);\n\ntemplate<typename Container, typename Compare>\nbool containerEqual(Container const& _lhs, Container const& _rhs, Compare&& _compare)\n{\n\treturn std::equal(std::begin(_lhs), std::end(_lhs), std::begin(_rhs), std::end(_rhs), std::forward<Compare>(_compare));\n}\n\ninline std::string findAnyOf(std::string const& _haystack, std::vector<std::string> const& _needles)\n{\n\tfor (std::string const& needle: _needles)\n\t\tif (_haystack.find(needle) != std::string::npos)\n\t\t\treturn needle;\n\treturn \"\";\n}\n\n\nnamespace detail\n{\ntemplate<typename T>\nvoid variadicEmplaceBack(std::vector<T>&) {}\ntemplate<typename T, typename A, typename... Args>\nvoid variadicEmplaceBack(std::vector<T>& _vector, A&& _a, Args&&... _args)\n{\n\t_vector.emplace_back(std::forward<A>(_a));\n\tvariadicEmplaceBack(_vector, std::forward<Args>(_args)...);\n}\n}\n\ntemplate<typename T, typename... Args>\nstd::vector<T> make_vector(Args&&... _args)\n{\n\tstd::vector<T> result;\n\tresult.reserve(sizeof...(_args));\n\tdetail::variadicEmplaceBack(result, std::forward<Args>(_args)...);\n\treturn result;\n}\n\ninline std::string stringOrDefault(std::string _string, std::string _defaultString = \"\")\n{\n\treturn (!_string.empty() ? std::move(_string) : std::move(_defaultString));\n}\n\ninline std::string stringOrDefault(std::string const* _string, std::string const& _defaultString = \"\")\n{\n\treturn (_string ? stringOrDefault(*_string, _defaultString) : _defaultString);\n}\n\n}\n"
  },
  {
    "path": "libsolutil/CommonIO.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file CommonIO.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/Assertions.h>\n\n#include <fstream>\n#if defined(_WIN32)\n#include <windows.h>\n#else\n#include <unistd.h>\n#include <termios.h>\n#endif\n\nusing namespace solidity::util;\n\nnamespace\n{\n\ntemplate <typename T>\ninline T readFile(boost::filesystem::path const& _file)\n{\n\tassertThrow(boost::filesystem::exists(_file), FileNotFound, _file.string());\n\n\t// ifstream does not always fail when the path leads to a directory. Instead it might succeed\n\t// with tellg() returning a nonsensical value so that std::length_error gets raised in resize().\n\tassertThrow(boost::filesystem::is_regular_file(_file), NotAFile, _file.string());\n\n\tT ret;\n\tsize_t const c_elementSize = sizeof(typename T::value_type);\n\tstd::ifstream is(_file.string(), std::ifstream::binary);\n\n\t// Technically, this can still fail even though we checked above because FS content can change at any time.\n\tassertThrow(is, FileNotFound, _file.string());\n\n\t// get length of file:\n\tis.seekg(0, is.end);\n\tstd::streamoff length = is.tellg();\n\tif (length == 0)\n\t\treturn ret; // do not read empty file (MSVC does not like it)\n\tis.seekg(0, is.beg);\n\n\tret.resize((static_cast<size_t>(length) + c_elementSize - 1) / c_elementSize);\n\tis.read(const_cast<char*>(reinterpret_cast<char const*>(ret.data())), static_cast<std::streamsize>(length));\n\treturn ret;\n}\n\n}\n\nstd::string solidity::util::readFileAsString(boost::filesystem::path const& _file)\n{\n\treturn readFile<std::string>(_file);\n}\n\nstd::string solidity::util::readUntilEnd(std::istream& _stdin)\n{\n\tstd::ostringstream ss;\n\tss << _stdin.rdbuf();\n\treturn ss.str();\n}\n\nstd::string solidity::util::readBytes(std::istream& _input, size_t _length)\n{\n\tstd::string output;\n\toutput.resize(_length);\n\t_input.read(output.data(), static_cast<std::streamsize>(_length));\n\t// If read() reads fewer bytes it sets failbit in addition to eofbit.\n\tif (_input.fail())\n\t\toutput.resize(static_cast<size_t>(_input.gcount()));\n\treturn output;\n}\n\n#if defined(_WIN32)\nclass DisableConsoleBuffering\n{\npublic:\n\tDisableConsoleBuffering()\n\t{\n\t\tm_stdin = GetStdHandle(STD_INPUT_HANDLE);\n\t\tGetConsoleMode(m_stdin, &m_oldMode);\n\t\tSetConsoleMode(m_stdin, m_oldMode & (~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT)));\n\t}\n\t~DisableConsoleBuffering()\n\t{\n\t\tSetConsoleMode(m_stdin, m_oldMode);\n\t}\nprivate:\n\tHANDLE m_stdin;\n\tDWORD m_oldMode;\n};\n#else\nclass DisableConsoleBuffering\n{\npublic:\n\tDisableConsoleBuffering()\n\t{\n\t\ttcgetattr(0, &m_termios);\n\t\tm_termios.c_lflag &= ~tcflag_t(ICANON);\n\t\tm_termios.c_lflag &= ~tcflag_t(ECHO);\n\t\tm_termios.c_cc[VMIN] = 1;\n\t\tm_termios.c_cc[VTIME] = 0;\n\t\ttcsetattr(0, TCSANOW, &m_termios);\n\t}\n\t~DisableConsoleBuffering()\n\t{\n\t\tm_termios.c_lflag |= ICANON;\n\t\tm_termios.c_lflag |= ECHO;\n\t\ttcsetattr(0, TCSADRAIN, &m_termios);\n\t}\nprivate:\n\tstruct termios m_termios;\n};\n#endif\n\nint solidity::util::readStandardInputChar()\n{\n\tDisableConsoleBuffering disableConsoleBuffering;\n\treturn std::cin.get();\n}\n\nstd::string solidity::util::absolutePath(std::string const& _path, std::string const& _reference)\n{\n\tboost::filesystem::path p(_path);\n\t// Anything that does not start with `.` is an absolute path.\n\tif (p.begin() == p.end() || (*p.begin() != \".\" && *p.begin() != \"..\"))\n\t\treturn _path;\n\tboost::filesystem::path result(_reference);\n\n\t// If filename is \"/\", then remove_filename() throws.\n\t// See: https://github.com/boostorg/filesystem/issues/176\n\tif (result.filename() != boost::filesystem::path(\"/\"))\n\t\tresult.remove_filename();\n\tfor (boost::filesystem::path::iterator it = p.begin(); it != p.end(); ++it)\n\t\tif (*it == \"..\")\n\t\t\tresult = result.parent_path();\n\t\telse if (*it != \".\")\n\t\t\tresult /= *it;\n\treturn result.generic_string();\n}\n\nstd::string solidity::util::sanitizePath(std::string const& _path) {\n\treturn boost::filesystem::path(_path).generic_string();\n}\n"
  },
  {
    "path": "libsolutil/CommonIO.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file CommonIO.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * File & stream I/O routines.\n */\n\n#pragma once\n\n#include <boost/filesystem.hpp>\n\n#include <libsolutil/Common.h>\n#include <iostream>\n#include <sstream>\n#include <string>\n\nnamespace solidity\n{\n\ninline std::ostream& operator<<(std::ostream& os, bytes const& _bytes)\n{\n\tstd::ostringstream ss;\n\tss << std::hex;\n\tstd::copy(_bytes.begin(), _bytes.end(), std::ostream_iterator<int>(ss, \",\"));\n\tstd::string result = ss.str();\n\tresult.pop_back();\n\tos << \"[\" + result + \"]\";\n\treturn os;\n}\n\nnamespace util\n{\n\n/// Retrieves and returns the contents of the given file as a std::string.\n/// If the file doesn't exist, it will throw a FileNotFound exception.\n/// If the file exists but is not a regular file, it will throw NotAFile exception.\n/// If the file is empty, returns an empty string.\nstd::string readFileAsString(boost::filesystem::path const& _file);\n\n/// Retrieves and returns the whole content of the specified input stream (until EOF).\nstd::string readUntilEnd(std::istream& _stdin);\n\n/// Tries to read exactly @a _length bytes from @a _input.\n/// Returns a string containing as much data as has been read.\nstd::string readBytes(std::istream& _input, size_t _length);\n\n/// Retrieves and returns a character from standard input (without waiting for EOL).\nint readStandardInputChar();\n\n/// Converts arbitrary value to string representation using std::stringstream.\ntemplate <class T>\nstd::string toString(T const& _t)\n{\n\tstd::ostringstream o;\n\to << _t;\n\treturn o.str();\n}\n\n/// @returns the absolute path corresponding to @a _path relative to @a _reference.\nstd::string absolutePath(std::string const& _path, std::string const& _reference);\n\n/// Helper function to return path converted strings.\nstd::string sanitizePath(std::string const& _path);\n\n}\n}\n"
  },
  {
    "path": "libsolutil/DisjointSet.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolutil/DisjointSet.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <numeric>\n\nusing namespace solidity::util;\n\ntemplate<typename ValueType>\nContiguousDisjointSet<ValueType>::ContiguousDisjointSet(size_t const _numNodes):\n\tm_parents(_numNodes),\n\tm_neighbors(_numNodes),\n\tm_sizes(_numNodes, static_cast<value_type>(1)),\n\tm_numSets(_numNodes)\n{\n\t// each is their own neighbor and parent\n\tstd::iota(m_parents.begin(), m_parents.end(), 0);\n\tstd::iota(m_neighbors.begin(), m_neighbors.end(), 0);\n}\n\ntemplate<typename ValueType>\nsize_t ContiguousDisjointSet<ValueType>::numSets() const { return m_numSets; }\n\ntemplate<typename ValueType>\ntypename ContiguousDisjointSet<ValueType>::value_type ContiguousDisjointSet<ValueType>::find(value_type const _element) const\n{\n\tsolAssert(_element < m_parents.size());\n\t// path halving\n\tvalue_type rootElement = _element;\n\twhile (rootElement != m_parents[rootElement])\n\t{\n\t\tm_parents[rootElement] = m_parents[m_parents[rootElement]];\n\t\trootElement = m_parents[rootElement];\n\t}\n\treturn rootElement;\n}\n\ntemplate<typename ValueType>\nvoid ContiguousDisjointSet<ValueType>::merge(value_type const _x, value_type const _y, bool const _mergeBySize)\n{\n\tauto xRoot = find(_x);\n\tauto yRoot = find(_y);\n\n\tif (xRoot == yRoot)\n\t\treturn;  // we're done, nothing to merge here\n\n\t// if merge by size: merge smaller (yRoot) into larger (xRoot) subset;\n\t// otherwise if _x is the representative of subset(_x), it will stay representative\n\tif (_mergeBySize && m_sizes[xRoot] < m_sizes[yRoot])\n\t\tstd::swap(xRoot, yRoot);\n\n\tm_parents[yRoot] = xRoot;\n\tm_sizes[xRoot] += m_sizes[yRoot];\n\tstd::swap(m_neighbors[xRoot], m_neighbors[yRoot]);\n\t--m_numSets;\n}\n\ntemplate<typename ValueType>\nbool ContiguousDisjointSet<ValueType>::sameSubset(value_type const _x, value_type const _y) const\n{\n\treturn find(_x) == find(_y);\n}\n\ntemplate<typename ValueType>\ntypename  ContiguousDisjointSet<ValueType>::size_type ContiguousDisjointSet<ValueType>::sizeOfSubset(value_type const _x) const\n{\n\treturn m_sizes[find(_x)];\n}\n\ntemplate<typename ValueType>\nstd::set<typename ContiguousDisjointSet<ValueType>::value_type> ContiguousDisjointSet<ValueType>::subset(value_type const _x) const\n{\n\tsolAssert(_x < m_parents.size());\n\tstd::set<value_type> result{_x};\n\tvalue_type neighbor = m_neighbors[_x];\n\twhile (neighbor != _x)\n\t{\n\t\tresult.insert(neighbor);\n\t\tneighbor = m_neighbors[neighbor];\n\t}\n\treturn result;\n}\n\ntemplate<typename ValueType>\nstd::vector<std::set<typename ContiguousDisjointSet<ValueType>::value_type>> ContiguousDisjointSet<ValueType>::subsets() const\n{\n\tstd::vector<std::set<value_type>> result;\n\tstd::vector<std::uint8_t> visited(m_parents.size(), false);\n\tfor (value_type x = 0; x < m_parents.size(); ++x)\n\t{\n\t\tauto xRoot = find(x);\n\t\tif (!visited[xRoot])\n\t\t{\n\t\t\tresult.push_back(subset(xRoot));\n\t\t\tvisited[xRoot] = true;\n\t\t}\n\t}\n\treturn result;\n}\n\ntemplate class solidity::util::ContiguousDisjointSet<std::uint32_t>;\n"
  },
  {
    "path": "libsolutil/DisjointSet.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <cstddef>\n#include <set>\n#include <vector>\n\nnamespace solidity::util\n{\n\n/// Implementation of the Disjoint set data structure [1], also called union-set, with path-halving [2].\n/// This implementation assumes that each set element is identified with an element in a iota range (hence contiguous).\n///\n/// [1] https://en.wikipedia.org/wiki/Disjoint-set_data_structure\n/// [2] Tarjan, Robert E., and Jan Van Leeuwen. \"Worst-case analysis of set union algorithms.\"\n///     Journal of the ACM (JACM) 31.2 (1984): 245-281.\ntemplate<typename ValueType>\nclass ContiguousDisjointSet\n{\npublic:\n\tusing size_type = size_t;\n\tusing value_type = ValueType;\n\n\t/// Constructs a new disjoint set datastructure with `_numNodes` elements and each element in its own individual set\n\texplicit ContiguousDisjointSet(size_t _numNodes);\n\n\tsize_type numSets() const;\n\n\t/// finds one representative for a set that contains `_element`\n\tvalue_type find(value_type _element) const;\n\n\t/// joins the two sets containing `_x` and `_y`, returns true if the sets were disjoint, otherwise false\n\tvoid merge(value_type _x, value_type _y, bool _mergeBySize=true);\n\n\tbool sameSubset(value_type _x, value_type _y) const;\n\n\tsize_type sizeOfSubset(value_type _x) const;\n\n\tstd::set<value_type> subset(value_type _x) const;\n\n\tstd::vector<std::set<value_type>> subsets() const;\n\nprivate:\n\tstd::vector<value_type> mutable m_parents;  // mutable for path compression, doesn't change semantic state\n\tstd::vector<value_type> m_neighbors;\n\tstd::vector<value_type> m_sizes;\n\tsize_type m_numSets;\n};\n\n}\n"
  },
  {
    "path": "libsolutil/DominatorFinder.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Dominator analysis of a control flow graph.\n * The implementation is based on the following paper:\n * https://www.cs.princeton.edu/courses/archive/spr03/cs423/download/dominators.pdf\n * See appendix B pg. 139.\n */\n#pragma once\n\n#include <liblangutil/Exceptions.h>\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/drop.hpp>\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/reverse.hpp>\n#include <range/v3/view/transform.hpp>\n\n#include <deque>\n#include <vector>\n#include <set>\n\nnamespace\n{\n\ttemplate <typename, typename = void>\n\tstruct has_id : std::false_type {};\n\n\ttemplate <typename T>\n\tstruct has_id<T, std::void_t<decltype(std::declval<T>().id)>> : std::true_type {};\n}\n\nnamespace solidity::util\n{\n\n/// DominatorFinder computes the dominator tree of a directed graph.\n/// V is the type of the vertex and it is assumed to have a unique identifier.\n/// ForEachSuccessor is a visitor that visits the successors of a vertex.\n///\n/// The graph must contain at least one vertex (the entry point) and is assumed to not be disconnected.\n/// Only vertices reachable from the entry vertex are visited.\ntemplate<typename V, typename ForEachSuccessor>\nclass DominatorFinder\n{\npublic:\n\tstatic_assert(has_id<V>::value, \"vertex must define id member\");\n\tusing VId = typename V::Id;\n\tusing DfsIndex = size_t;\n\n\tDominatorFinder(V const& _entry):\n\t\tm_immediateDominators(findDominators(_entry))\n\t{\n\t\tbuildDominatorTree();\n\t}\n\n\tstd::vector<VId> const& verticesIdsInDFSOrder() const\n\t{\n\t\treturn m_verticesInDFSOrder;\n\t}\n\n\tstd::map<VId, DfsIndex> const& dfsIndexById() const\n\t{\n\t\treturn m_dfsIndexByVertexId;\n\t}\n\n\tstd::map<VId, std::optional<VId>> const immediateDominators() const\n\t{\n\t\treturn m_immediateDominators\n\t\t\t| ranges::views::enumerate\n\t\t\t| ranges::views::transform([&](auto const& _v) {\n\t\t\t\tstd::optional<VId> idomId = (_v.second.has_value()) ? std::optional<VId>(m_verticesInDFSOrder[_v.second.value()]) : std::nullopt;\n\t\t\t\treturn std::make_pair(m_verticesInDFSOrder[_v.first], idomId);\n\t\t\t})\n\t\t\t| ranges::to<std::map<VId, std::optional<VId>>>;\n\t}\n\n\tstd::vector<std::optional<DfsIndex>> const& immediateDominatorsByDfsIndex() const\n\t{\n\t\treturn m_immediateDominators;\n\t}\n\n\tstd::map<VId, std::vector<VId>> const& dominatorTree() const\n\t{\n\t\treturn m_dominatorTree;\n\t}\n\n\tbool dominates(VId const& _dominatorId, VId const& _dominatedId) const\n\t{\n\t\tsolAssert(!m_dfsIndexByVertexId.empty());\n\t\tsolAssert(!m_immediateDominators.empty());\n\n\t\tsolAssert(m_dfsIndexByVertexId.count(_dominatorId) && m_dfsIndexByVertexId.count(_dominatedId));\n\t\tDfsIndex dominatorIdx = m_dfsIndexByVertexId.at(_dominatorId);\n\t\tDfsIndex dominatedIdx = m_dfsIndexByVertexId.at(_dominatedId);\n\n\t\tif (dominatorIdx == dominatedIdx)\n\t\t\treturn true;\n\n\t\tDfsIndex idomIdx = m_immediateDominators.at(dominatedIdx).value_or(0);\n\t\twhile (idomIdx != 0)\n\t\t{\n\t\t\tsolAssert(idomIdx < m_immediateDominators.size());\n\t\t\tif (idomIdx == dominatorIdx)\n\t\t\t\treturn true;\n\t\t\t// The index of the immediate dominator of a vertex is always less than the index of the vertex itself.\n\t\t\tsolAssert(m_immediateDominators.at(idomIdx).has_value() && m_immediateDominators.at(idomIdx).value() < idomIdx);\n\t\t\tidomIdx = m_immediateDominators[idomIdx].value();\n\t\t}\n\t\t// Now that we reached the entry node (i.e. idomIdx = 0),\n\t\t// either ``dominatorIdx == 0`` or it does not dominate the other node.\n\t\tsolAssert(idomIdx == 0);\n\t\treturn dominatorIdx == 0;\n\t}\n\n\t/// Checks whether vertex ``_dominator`` dominates ``_dominated`` by going\n\t/// through the path from ``_dominated`` to the entry node.\n\t/// If ``_dominator`` is found, then it dominates ``_dominated``\n\t/// otherwise it doesn't.\n\tbool dominates(V const& _dominator, V const& _dominated) const\n\t{\n\t\treturn dominates(_dominator.id, _dominated.id);\n\t}\n\n\tstd::vector<VId> dominatorsOf(VId const& _vId) const\n\t{\n\t\tsolAssert(!m_verticesInDFSOrder.empty());\n\t\tsolAssert(!m_dfsIndexByVertexId.empty());\n\t\tsolAssert(!m_immediateDominators.empty());\n\n\t\tsolAssert(m_dfsIndexByVertexId.count(_vId));\n\n\t\t// No one dominates the entry vertex and we consider self-dominance implicit\n\t\t// i.e. every node already dominates itself.\n\t\tif (m_dfsIndexByVertexId.at(_vId) == 0)\n\t\t\treturn {};\n\n\t\tsolAssert(m_dfsIndexByVertexId.at(_vId) < m_immediateDominators.size());\n\t\tDfsIndex idomIdx = m_immediateDominators.at(m_dfsIndexByVertexId.at(_vId)).value_or(0);\n\t\tsolAssert(idomIdx < m_immediateDominators.size());\n\n\t\tstd::vector<VId> dominators;\n\t\twhile (idomIdx != 0)\n\t\t{\n\t\t\tsolAssert(m_immediateDominators.at(idomIdx).has_value() && m_immediateDominators.at(idomIdx).value() < idomIdx);\n\t\t\tdominators.emplace_back(m_verticesInDFSOrder.at(idomIdx));\n\t\t\tidomIdx = m_immediateDominators[idomIdx].value();\n\t\t}\n\n\t\t// The loop above discovers the dominators in the reverse order\n\t\t// i.e. from the given vertex upwards to the entry node (the root of the dominator tree).\n\t\t// And the entry vertex always dominates all other vertices.\n\t\tdominators.emplace_back(m_verticesInDFSOrder[0]);\n\n\t\treturn dominators;\n\t}\n\n\t/// Find all dominators of a node _v\n\t/// @note for a vertex ``_v``, the _v’s inclusion in the set of dominators of ``_v`` is implicit.\n\tstd::vector<VId> dominatorsOf(V const& _v) const\n\t{\n\t\treturn dominatorsOf(_v.id);\n\t}\n\nprivate:\n\tstd::vector<std::optional<DfsIndex>> findDominators(V const& _entry)\n\t{\n\t\tsolAssert(m_verticesInDFSOrder.empty());\n\t\tsolAssert(m_dfsIndexByVertexId.empty());\n\n\t\t// parent(w): The index of the vertex which is the parent of ``w`` in the spanning\n\t\t// tree generated by the DFS.\n\t\tstd::vector<DfsIndex> parent;\n\n\t\t// step 1\n\t\t// The vertices are assigned indices in DFS order.\n\t\tstd::set<VId> visited;\n\t\tDfsIndex nextUnusedDFSIndex = 0;\n\n\t\tauto dfs = [&](V const& _v, auto _dfs) -> void {\n\t\t\tauto [_, inserted] = visited.insert(_v.id);\n\t\t\tif (!inserted)\n\t\t\t\treturn;\n\n\t\t\tm_verticesInDFSOrder.emplace_back(_v.id);\n\t\t\tm_dfsIndexByVertexId[_v.id] = nextUnusedDFSIndex;\n\t\t\tnextUnusedDFSIndex++;\n\n\t\t\tForEachSuccessor{}(_v, [&](V const& _successor) {\n\t\t\t\tif (visited.count(_successor.id) == 0)\n\t\t\t\t{\n\t\t\t\t\tparent.push_back(m_dfsIndexByVertexId[_v.id]);\n\t\t\t\t\tm_predecessors.push_back({m_dfsIndexByVertexId[_v.id]});\n\t\t\t\t\t_dfs(_successor, _dfs);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsolAssert(m_dfsIndexByVertexId[_successor.id] < m_predecessors.size());\n\t\t\t\t\tm_predecessors[m_dfsIndexByVertexId[_successor.id]].insert(m_dfsIndexByVertexId[_v.id]);\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\tparent.emplace_back(std::numeric_limits<DfsIndex>::max());\n\t\tm_predecessors.emplace_back();\n\t\tdfs(_entry, dfs);\n\n\t\tsize_t numVertices = visited.size();\n\t\tsolAssert(nextUnusedDFSIndex == numVertices);\n\t\tsolAssert(m_verticesInDFSOrder.size() == numVertices);\n\t\tsolAssert(visited.size() == numVertices);\n\t\tsolAssert(m_predecessors.size() == numVertices);\n\t\tsolAssert(parent.size() == numVertices);\n\n\t\t// ancestor(w): Parent of vertex ``w`` in the virtual forest traversed by eval().\n\t\t// The forest consists of disjoint subtrees of the spanning tree and the parent of ``w`` is\n\t\t// always one of its ancestors in that spanning tree.\n\t\t// Initially each subtree consists of a single vertex. As the algorithm iterates over the\n\t\t// graph, each processed vertex gets connected to its parent from the spanning tree using\n\t\t// link(). Later on, the path compression performed by eval() may move it up in the subtree.\n\t\tstd::vector<DfsIndex> ancestor(numVertices, std::numeric_limits<DfsIndex>::max());\n\t\t// label(w): The index of a vertex with the smallest semidominator, on the path between ``w``\n\t\t// and the root of its subtree. The value is not updated immediately by link(), but\n\t\t// only during path compression performed by eval().\n\t\tstd::vector<DfsIndex> label;\n\t\t// bucket(w): The set of all vertices having ``w`` as their semidominator.\n\t\t// The index of the array represents the vertex' DFS index.\n\t\tstd::vector<std::deque<DfsIndex>> bucket(numVertices);\n\n\t\t// semi(w): The DFS index of the semidominator of ``w``.\n\t\tstd::vector<DfsIndex> semi;\n\t\t// idom(w): The DFS index of the immediate dominator of ``w``.\n\t\tstd::vector<std::optional<DfsIndex>> idom(numVertices, std::nullopt);\n\n\t\t// ``link(v, w)`` adds an edge from ``w`` to ``v`` in the virtual forest.\n\t\t// It is meant to initially attach vertex ``w`` to its parent from the spanning tree,\n\t\t// but path compression can later limit the search path upwards.\n\t\t// TODO: implement sophisticated link-eval algorithm as shown in pg 132\n\t\t// See: https://www.cs.princeton.edu/courses/archive/spr03/cs423/download/dominators.pdf\n\t\tauto link = [&](DfsIndex _parentIdx, DfsIndex _wIdx)\n\t\t{\n\t\t\tsolAssert(ancestor[_wIdx] == std::numeric_limits<DfsIndex>::max());\n\t\t\tancestor[_wIdx] = _parentIdx;\n\t\t};\n\n\t\t// ``eval(v)`` returns a vertex with the smallest semidominator index on the path between\n\t\t// vertex ``v`` and the root of its subtree in the virtual forest, i.e. the label of ``v``.\n\t\t// Performs path compression in the process, updating labels and ancestors on the path to\n\t\t// the subtree root.\n\t\tauto eval = [&](DfsIndex _vIdx) -> DfsIndex\n\t\t{\n\t\t\tif (ancestor[_vIdx] == std::numeric_limits<DfsIndex>::max())\n\t\t\t\treturn _vIdx;\n\n\t\t\tcompressPath(ancestor, label, semi, _vIdx);\n\t\t\treturn label[_vIdx];\n\t\t};\n\n\t\tauto toDfsIndex = [&](VId const& _vId) { return m_dfsIndexByVertexId[_vId]; };\n\n\t\tfor (DfsIndex wIdx = 0; wIdx < m_verticesInDFSOrder.size(); ++wIdx)\n\t\t{\n\t\t\tsemi.push_back(wIdx);\n\t\t\tlabel.push_back(wIdx);\n\t\t}\n\n\t\t// Process the vertices in decreasing order of the DFS number\n\t\tfor (DfsIndex wIdx: m_verticesInDFSOrder | ranges::views::reverse | ranges::views::transform(toDfsIndex))\n\t\t{\n\t\t\t// step 3\n\t\t\t// NOTE: this is an optimization, i.e. performing the step 3 before step 2.\n\t\t\t// The goal is to process the bucket at the beginning of the loop for the vertex ``w``\n\t\t\t// instead of ``parent[w]`` at the end of the loop as described in the original paper.\n\t\t\t// Inverting those steps ensures that a bucket is only processed once and\n\t\t\t// it does not need to be erased.\n\t\t\t// The optimization proposal is available here: https://jgaa.info/index.php/jgaa/article/view/paper119/2847 pg.77\n\t\t\tfor (DfsIndex vIdx: bucket[wIdx])\n\t\t\t{\n\t\t\t\tDfsIndex uIdx = eval(vIdx);\n\t\t\t\tsolAssert(uIdx <= vIdx);\n\t\t\t\tidom[vIdx] = (semi[uIdx] < semi[vIdx]) ? uIdx : wIdx;\n\t\t\t}\n\n\t\t\t// step 2\n\t\t\tfor (DfsIndex vIdx: m_predecessors[wIdx])\n\t\t\t{\n\t\t\t\tDfsIndex uIdx = eval(vIdx);\n\t\t\t\tsolAssert(uIdx <= vIdx);\n\t\t\t\tif (semi[uIdx] < semi[wIdx])\n\t\t\t\t\tsemi[wIdx] = semi[uIdx];\n\t\t\t}\n\t\t\tsolAssert(semi[wIdx] < wIdx || wIdx == 0);\n\t\t\tbucket[semi[wIdx]].emplace_back(wIdx);\n\t\t\tlink(parent[wIdx], wIdx);\n\t\t\tsolAssert(ancestor[wIdx] == parent[wIdx]);\n\t\t}\n\n\t\t// step 4\n\t\t// Compute idom in DFS order\n\t\t// The entry vertex does not have an immediate dominator.\n\t\tsolAssert(idom[0] == std::nullopt);\n\t\tfor (DfsIndex wIdx: m_verticesInDFSOrder | ranges::views::drop(1) | ranges::views::transform(toDfsIndex))\n\t\t{\n\t\t\t// All the other vertices must have an immediate dominator.\n\t\t\tsolAssert(idom[wIdx].has_value());\n\t\t\tif (idom[wIdx].value() != semi[wIdx])\n\t\t\t\tidom[wIdx] = idom[idom[wIdx].value()];\n\t\t}\n\n\t\treturn idom;\n\t}\n\n\t/// Path compression updates the ancestors of vertices along\n\t/// the path to the ancestor with the minimum label value.\n\tstatic void compressPath(\n\t\tstd::vector<DfsIndex>& _ancestor,\n\t\tstd::vector<DfsIndex>& _label,\n\t\tstd::vector<DfsIndex> const& _semi,\n\t\tDfsIndex _vIdx\n\t)\n\t{\n\t\tsolAssert(_vIdx < _ancestor.size() && _vIdx < _semi.size() && _vIdx < _label.size());\n\t\tsolAssert(_ancestor[_vIdx] != std::numeric_limits<size_t>::max());\n\t\tsolAssert(_ancestor[_vIdx] < _vIdx);\n\t\tif (_ancestor[_ancestor[_vIdx]] != std::numeric_limits<DfsIndex>::max())\n\t\t{\n\t\t\tsolAssert(_ancestor[_ancestor[_vIdx]] < _ancestor[_vIdx]);\n\t\t\tcompressPath(_ancestor, _label, _semi, _ancestor[_vIdx]);\n\t\t\tif (_semi[_label[_ancestor[_vIdx]]] < _semi[_label[_vIdx]])\n\t\t\t\t_label[_vIdx] = _label[_ancestor[_vIdx]];\n\t\t\t_ancestor[_vIdx] = _ancestor[_ancestor[_vIdx]];\n\t\t}\n\t\tsolAssert(_label[_ancestor[_vIdx]] <= _label[_vIdx]);\n\t}\n\n\t/// Build dominator tree from the immediate dominators set.\n\t/// The function groups all the vertex IDs that are immediately dominated by a vertex.\n\tvoid buildDominatorTree()\n\t{\n\t\t// m_immediateDominators is guaranteed to have at least one element after findingDominators() is executed.\n\t\tsolAssert(m_immediateDominators.size() > 0);\n\t\tsolAssert(m_immediateDominators.size() == m_verticesInDFSOrder.size());\n\t\tsolAssert(m_immediateDominators[0] == std::nullopt);\n\n\t\t// Ignoring the entry node since no one dominates it.\n\t\tfor (DfsIndex dominatedIdx = 1; dominatedIdx < m_verticesInDFSOrder.size(); ++dominatedIdx)\n\t\t{\n\t\t\tVId dominatedId = m_verticesInDFSOrder[dominatedIdx];\n\t\t\tsolAssert(m_dfsIndexByVertexId.count(dominatedId));\n\t\t\tsolAssert(dominatedIdx == m_dfsIndexByVertexId.at(dominatedId));\n\n\t\t\t// If the vertex does not have an immediate dominator, it is the entry vertex (i.e. index 0).\n\t\t\t// NOTE: `dominatedIdx` will never be 0 since the loop starts from 1.\n\t\t\tsolAssert(m_immediateDominators[dominatedIdx].has_value());\n\t\t\tDfsIndex dominatorIdx = m_immediateDominators[dominatedIdx].value();\n\n\t\t\tsolAssert(dominatorIdx < dominatedIdx);\n\t\t\tVId dominatorId = m_verticesInDFSOrder[dominatorIdx];\n\t\t\tm_dominatorTree[dominatorId].emplace_back(dominatedId);\n\t\t}\n\t}\n\n\t// predecessors(w): The set of vertices ``v`` such that (``v``, ``w``) is an edge of the graph.\n\tstd::vector<std::set<DfsIndex>> m_predecessors;\n\n\t/// Keeps the list of vertex IDs in the DFS order.\n\t/// The entry vertex is the first element of the vector.\n\t/// The indices of the other vertices are assigned in the order they are visited during the DFS.\n\t/// I.e. m_verticesInDFSOrder[i] is the ID of the vertex whose DFS index is i.\n\t///\n\t/// DFS index -> vertex ID\n\tstd::vector<VId> m_verticesInDFSOrder;\n\n\t/// Maps a vertex ID to its DFS order index.\n\t///\n\t/// Vertex ID -> DFS index\n\tstd::map<VId, DfsIndex> m_dfsIndexByVertexId;\n\n\t/// Maps a vertex to all vertices that it dominates.\n\t/// If the vertex does not dominate any other vertex it has no entry in the map.\n\t/// The value is a set of IDs of vertices dominated by the vertex whose ID is the map key.\n\t///\n\t/// Vertex id -> dominates set {vertex ID}\n\tstd::map<VId, std::vector<VId>> m_dominatorTree;\n\n\t/// Immediate dominators by DFS index.\n\t/// Maps a vertex' DFS index (i.e. array index) to its immediate dominator DFS index.\n\t/// As the entry vertex does not have immediate dominator, its idom is always set to `std::nullopt`.\n\t/// However note that the DFS index of the entry vertex is 0, since it is the first element of the vector.\n\t///\n\t/// E.g. to get the immediate dominator of a Vertex w:\n\t/// idomIdx = m_immediateDominators[m_dfsIndexByVertexId[w.id]]\n\t/// idomVertexId = m_verticesInDFSOrder[domIdx]\n\t///\n\t/// DFS index -> dominates DFS index\n\tstd::vector<std::optional<DfsIndex>> m_immediateDominators;\n};\n}\n"
  },
  {
    "path": "libsolutil/ErrorCodes.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <string>\n\nnamespace solidity::util\n{\n\nenum class PanicCode\n{\n\tGeneric = 0x00, // generic / unspecified error\n\tAssert = 0x01, // used by the assert() builtin\n\tUnderOverflow = 0x11, // arithmetic underflow or overflow\n\tDivisionByZero = 0x12, // division or modulo by zero\n\tEnumConversionError = 0x21, // enum conversion error\n\tStorageEncodingError = 0x22, // invalid encoding in storage\n\tEmptyArrayPop = 0x31, // empty array pop\n\tArrayOutOfBounds = 0x32, // array out of bounds access\n\tResourceError = 0x41, // resource error (too large allocation or too large array)\n\tInvalidInternalFunction = 0x51, // calling invalid internal function\n};\n\n}\n"
  },
  {
    "path": "libsolutil/Exceptions.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolutil/Exceptions.h>\n#include <liblangutil/Exceptions.h>\n\nusing namespace solidity::util;\nusing namespace solidity::langutil;\n\nchar const* Exception::what() const noexcept\n{\n\t// Return the comment if available.\n\tif (std::string const* cmt = comment())\n\t\treturn cmt->data();\n\n\t// Fallback to base what().\n\t// Boost accepts nullptr, but the C++ standard doesn't\n\t// and crashes on some platforms.\n\treturn std::exception::what();\n}\n\nstd::string Exception::lineInfo() const\n{\n\tchar const* const* file = boost::get_error_info<boost::throw_file>(*this);\n\tint const* line = boost::get_error_info<boost::throw_line>(*this);\n\tstd::string ret;\n\tif (file)\n\t\tret += *file;\n\tret += ':';\n\tif (line)\n\t\tret += std::to_string(*line);\n\treturn ret;\n}\n\nstd::string const* Exception::comment() const noexcept\n{\n\treturn boost::get_error_info<errinfo_comment>(*this);\n}\n\nSourceLocation Exception::sourceLocation() const noexcept\n{\n\tif (SourceLocation const* sourceLocation = boost::get_error_info<errinfo_sourceLocation>(*this))\n\t\treturn *sourceLocation;\n\n\treturn SourceLocation{};\n}\n"
  },
  {
    "path": "libsolutil/Exceptions.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <liblangutil/SourceLocation.h>\n\n#include <boost/exception/exception.hpp>\n#include <boost/exception/info.hpp>\n#include <boost/exception/info_tuple.hpp>\n#include <boost/exception/diagnostic_information.hpp>\n\n#include <exception>\n#include <string>\n\nnamespace solidity::util\n{\n\n/// Base class for all exceptions.\nstruct Exception: virtual std::exception, virtual boost::exception\n{\n\tchar const* what() const noexcept override;\n\n\t/// @returns \"FileName:LineNumber\" referring to the point where the exception was thrown.\n\tstd::string lineInfo() const;\n\n\t/// @returns the errinfo_comment of this exception.\n\tstd::string const* comment() const noexcept;\n\n\t/// @returns the errinfo_sourceLocation of this exception\n\tlangutil::SourceLocation sourceLocation() const noexcept;\n};\n\n/// Throws an exception with a given description and extra information about the location the\n/// exception was thrown from.\n/// @param _exceptionType The type of the exception to throw (not an instance).\n/// @param _description The message that describes the error.\n#define solThrow(_exceptionType, _description) \\\n\t::boost::throw_exception( \\\n\t\t_exceptionType() << \\\n\t\t::solidity::util::errinfo_comment((_description)) << \\\n\t\t::boost::throw_function(ETH_FUNC) << \\\n\t\t::boost::throw_file(__FILE__) << \\\n\t\t::boost::throw_line(__LINE__) \\\n\t)\n\n/// Throws an exception if condition is not met with a given description and extra information about the location the\n/// exception was thrown from.\n/// @param _condition if condition is not met, specified exception will be thrown.\n/// @param _exceptionType The type of the exception to throw (not an instance).\n/// @param _description The message that describes the error.\n#define solRequire(_condition, _exceptionType, _description) \\\n\tif (!(_condition)) \\\n\t\tsolThrow(_exceptionType, (_description))\n\n/// Defines an exception type that's meant to signal a specific condition and be caught rather than\n/// unwind the stack all the way to the top-level exception handler and interrupt the program.\n/// As such it does not carry a message - the code catching it is expected to handle it without\n/// letting it escape.\n#define DEV_SIMPLE_EXCEPTION(X) struct X: virtual ::solidity::util::Exception { const char* what() const noexcept override { return #X; } }\n\nDEV_SIMPLE_EXCEPTION(InvalidAddress);\nDEV_SIMPLE_EXCEPTION(BadHexCharacter);\nDEV_SIMPLE_EXCEPTION(BadHexCase);\nDEV_SIMPLE_EXCEPTION(FileNotFound);\nDEV_SIMPLE_EXCEPTION(NotAFile);\nDEV_SIMPLE_EXCEPTION(DataTooLong);\nDEV_SIMPLE_EXCEPTION(StringTooLong);\nDEV_SIMPLE_EXCEPTION(InvalidType);\n\n// error information to be added to exceptions\nusing errinfo_comment = boost::error_info<struct tag_comment, std::string>;\n\n}\n"
  },
  {
    "path": "libsolutil/FixedHash.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file FixedHash.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * The FixedHash fixed-size \"hash\" container type.\n */\n\n#pragma once\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Numeric.h>\n\n#include <boost/functional/hash.hpp>\n#include <boost/io/ios_state.hpp>\n\n#include <array>\n#include <cstdint>\n#include <algorithm>\n\nnamespace solidity::util\n{\n\n/// Fixed-size raw-byte array container type, with an API optimised for storing hashes.\n/// Transparently converts to/from the corresponding arithmetic type; this will\n/// assume the data contained in the hash is big-endian.\ntemplate <unsigned N>\nclass FixedHash\n{\npublic:\n\t/// The corresponding arithmetic type.\n\tusing Arith = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N * 8, N * 8, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;\n\n\t/// The size of the container.\n\tenum { size = N };\n\tstatic_assert(N != 0);\n\n\t/// Method to convert from a string.\n\tenum ConstructFromStringType { FromHex, FromBinary };\n\n\t/// Method to convert from a string.\n\tenum ConstructFromHashType { AlignLeft, AlignRight, FailIfDifferent };\n\n\t/// Construct an empty hash.\n\texplicit FixedHash() { m_data.fill(0); }\n\n\t/// Construct from another hash, filling with zeroes or cropping as necessary.\n\ttemplate <unsigned M> explicit FixedHash(FixedHash<M> const& _h, ConstructFromHashType _t)\n\t{\n\t\tm_data.fill(0);\n\t\tunsigned c = std::min(M, N);\n\t\tfor (unsigned i = 0; i < c; ++i)\n\t\t\tm_data[_t == AlignRight ? N - 1 - i : i] = _h[_t == AlignRight ? M - 1 - i : i];\n\t}\n\n\t/// Convert from the corresponding arithmetic type.\n\tFixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); }\n\n\t/// Explicitly construct, copying from a byte array.\n\texplicit FixedHash(bytes const& _array, ConstructFromHashType _sizeMismatchBehavior = FailIfDifferent)\n\t{\n\t\tif (_array.size() == N)\n\t\t\tmemcpy(m_data.data(), _array.data(), _array.size());\n\t\telse\n\t\t{\n\t\t\tm_data.fill(0);\n\t\t\tif (_sizeMismatchBehavior != FailIfDifferent)\n\t\t\t{\n\t\t\t\tauto bytesToCopy = std::min<size_t>(_array.size(), N);\n\t\t\t\tfor (size_t i = 0; i < bytesToCopy; ++i)\n\t\t\t\t\tif (_sizeMismatchBehavior == AlignRight)\n\t\t\t\t\t\tm_data[N - 1 - i] = _array[_array.size() - 1 - i];\n\t\t\t\t\telse\n\t\t\t\t\t\tm_data[i] = _array[i];\n\t\t\t}\n\t\t}\n\t}\n\n\t/// Explicitly construct, copying from a byte array.\n\texplicit FixedHash(bytesConstRef _b, ConstructFromHashType _t = FailIfDifferent)\n\t{\n\t\tif (_b.size() == N)\n\t\t\tmemcpy(m_data.data(), _b.data(), std::min<size_t>(_b.size(), N));\n\t\telse\n\t\t{\n\t\t\tm_data.fill(0);\n\t\t\tif (_t != FailIfDifferent)\n\t\t\t{\n\t\t\t\tauto c = std::min<size_t>(_b.size(), N);\n\t\t\t\tfor (size_t i = 0; i < c; ++i)\n\t\t\t\t\tif (_t == AlignRight)\n\t\t\t\t\t\tm_data[N - 1 - i] = _b[_b.size() - 1 - i];\n\t\t\t\t\telse\n\t\t\t\t\t\tm_data[i] = _b[i];\n\t\t\t}\n\t\t}\n\t}\n\n\t/// Explicitly construct, copying from a string.\n\texplicit FixedHash(std::string const& _s, ConstructFromStringType _t = FromHex, ConstructFromHashType _ht = FailIfDifferent):\n\t\tFixedHash(_t == FromHex ? fromHex(_s, WhenError::Throw) : solidity::util::asBytes(_s), _ht)\n\t{}\n\n\t/// Convert to arithmetic type.\n\toperator Arith() const { return fromBigEndian<Arith>(m_data); }\n\n\t// The obvious comparison operators.\n\tbool operator==(FixedHash const& _c) const { return m_data == _c.m_data; }\n\tbool operator!=(FixedHash const& _c) const { return m_data != _c.m_data; }\n\t/// Required to sort objects of this type or use them as map keys.\n\tbool operator<(FixedHash const& _c) const {\n\t\tfor (unsigned i = 0; i < N; ++i)\n\t\t{\n\t\t\tif (m_data[i] < _c.m_data[i])\n\t\t\t\treturn true;\n\t\t\telse if (m_data[i] > _c.m_data[i])\n\t\t\t\treturn false;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/// @returns a particular byte from the hash.\n\tuint8_t& operator[](unsigned _i) { return m_data[_i]; }\n\t/// @returns a particular byte from the hash.\n\tuint8_t operator[](unsigned _i) const { return m_data[_i]; }\n\n\t/// @returns the hash as a user-readable hex string.\n\tstd::string hex() const { return toHex(asBytes()); }\n\n\t/// @returns a mutable byte vector_ref to the object's data.\n\tbytesRef ref() { return bytesRef(m_data.data(), N); }\n\n\t/// @returns a constant byte vector_ref to the object's data.\n\tbytesConstRef ref() const { return bytesConstRef(m_data.data(), N); }\n\n\t/// @returns a mutable byte pointer to the object's data.\n\tuint8_t* data() { return m_data.data(); }\n\n\t/// @returns a constant byte pointer to the object's data.\n\tuint8_t const* data() const { return m_data.data(); }\n\n\t/// @returns a copy of the object's data as a byte vector.\n\tbytes asBytes() const { return bytes(data(), data() + N); }\n\nprivate:\n\tstd::array<uint8_t, N> m_data; ///< The binary data.\n};\n\n/// Stream I/O for the FixedHash class.\ntemplate <unsigned N>\ninline std::ostream& operator<<(std::ostream& _out, FixedHash<N> const& _h)\n{\n\tboost::io::ios_all_saver guard(_out);\n\t_out << std::noshowbase << std::hex << std::setfill('0');\n\tfor (unsigned i = 0; i < N; ++i)\n\t\t_out << std::setw(2) << (int)_h[i];\n\t_out << std::dec;\n\treturn _out;\n}\n\n// Common types of FixedHash.\nusing h256 = FixedHash<32>;\nusing h160 = FixedHash<20>;\n\n}\n"
  },
  {
    "path": "libsolutil/FunctionSelector.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/Keccak256.h>\n#include <libsolutil/FixedHash.h>\n\n#include <string>\n\nnamespace solidity::util\n{\n\n/// @returns the ABI selector for a given function signature, as a FixedHash h32.\ninline FixedHash<4> selectorFromSignatureH32(std::string const& _signature)\n{\n\treturn FixedHash<4>(util::keccak256(_signature), FixedHash<4>::AlignLeft);\n}\n\n/// @returns the ABI selector for a given function signature, as a 32 bit number.\ninline uint32_t selectorFromSignatureU32(std::string const& _signature)\n{\n\treturn uint32_t(FixedHash<4>::Arith(selectorFromSignatureH32(_signature)));\n}\n\n/// @returns the ABI selector for a given function signature, as a u256 (left aligned) number.\ninline u256 selectorFromSignatureU256(std::string const& _signature)\n{\n\treturn u256(selectorFromSignatureU32(_signature)) << (256 - 32);\n}\n\n}\n"
  },
  {
    "path": "libsolutil/IpfsHash.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolutil/IpfsHash.h>\n\n#include <libsolutil/Exceptions.h>\n#include <libsolutil/picosha2.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Numeric.h>\n\nusing namespace solidity;\nusing namespace solidity::util;\n\nnamespace\n{\nbytes varintEncoding(size_t _n)\n{\n\tbytes encoded;\n\twhile (_n > 0x7f)\n\t{\n\t\tencoded.emplace_back(uint8_t(0x80 | (_n & 0x7f)));\n\t\t_n >>= 7;\n\t}\n\tencoded.emplace_back(_n);\n\treturn encoded;\n}\n\nbytes encodeByteArray(bytes const& _data)\n{\n\treturn bytes{0x0a} + varintEncoding(_data.size()) + _data;\n}\n\nbytes encodeHash(bytes const& _data)\n{\n\treturn bytes{0x12, 0x20} + picosha2::hash256(_data);\n}\n\nbytes encodeLinkData(bytes const& _data)\n{\n\treturn bytes{0x12} + varintEncoding(_data.size()) + _data;\n}\n\nstd::string base58Encode(bytes const& _data)\n{\n\tstatic std::string const alphabet{\"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\"};\n\tbigint data(util::toHex(_data, HexPrefix::Add));\n\tstd::string output;\n\twhile (data)\n\t{\n\t\toutput += alphabet[static_cast<size_t>(data % alphabet.size())];\n\t\tdata /= alphabet.size();\n\t}\n\treverse(output.begin(), output.end());\n\treturn output;\n}\n\nstruct Chunk\n{\n\tChunk() = default;\n\tChunk(bytes _hash, size_t _size, size_t _blockSize):\n\t\thash(std::move(_hash)),\n\t\tsize(_size),\n\t\tblockSize(_blockSize)\n\t{}\n\n\tbytes hash = {};\n\tsize_t size = 0;\n\tsize_t blockSize = 0;\n};\n\nusing Chunks = std::vector<Chunk>;\n\nChunk combineLinks(Chunks& _links)\n{\n\tbytes data = {};\n\tbytes lengths = {};\n\tChunk chunk = {};\n\tfor (Chunk& link: _links)\n\t{\n\t\tchunk.size += link.size;\n\t\tchunk.blockSize += link.blockSize;\n\n\t\tdata += encodeLinkData(\n\t\t\tbytes {0x0a} +\n\t\t\tvarintEncoding(link.hash.size()) +\n\t\t\tstd::move(link.hash) +\n\t\t\tbytes{0x12, 0x00, 0x18} +\n\t\t\tvarintEncoding(link.blockSize)\n\t\t);\n\n\t\tlengths += bytes{0x20} + varintEncoding(link.size);\n\t}\n\n\tbytes blockData = data + encodeByteArray(bytes{0x08, 0x02, 0x18} + varintEncoding(chunk.size) + lengths);\n\n\tchunk.blockSize += blockData.size();\n\tchunk.hash = encodeHash(blockData);\n\n\treturn chunk;\n}\n\nChunks buildNextLevel(Chunks& _currentLevel)\n{\n\tsize_t const maxChildNum = 174;\n\n\tChunks nextLevel;\n\tChunks links;\n\n\tfor (Chunk& chunk: _currentLevel)\n\t{\n\t\tlinks.emplace_back(std::move(chunk.hash), chunk.size, chunk.blockSize);\n\t\tif (links.size() == maxChildNum)\n\t\t{\n\t\t\tnextLevel.emplace_back(combineLinks(links));\n\t\t\tlinks = {};\n\t\t}\n\t}\n\tif (!links.empty())\n\t\tnextLevel.emplace_back(combineLinks(links));\n\n\treturn nextLevel;\n}\n\n/// Builds a tree starting from the bottom level where nodes are data nodes.\n/// Data nodes should be calculated and passed as the only level in chunk levels\n/// Each next level is calculated as following:\n///   - Pick up to maxChildNum (174) nodes until a whole level is added, group them and pass to the node in the next level\n///   - Do this until the current level has only one node, return the hash in that node\nbytes groupChunksBottomUp(Chunks _currentLevel)\n{\n\t// when we reach root it will be the only node in that level\n\twhile (_currentLevel.size() != 1)\n\t\t_currentLevel = buildNextLevel(_currentLevel);\n\n\t// top level's only node stores the hash for file\n\treturn _currentLevel.front().hash;\n}\n}\n\nbytes solidity::util::ipfsHash(std::string _data)\n{\n\tsize_t const maxChunkSize = 1024 * 256;\n\tsize_t chunkCount = _data.length() / maxChunkSize + (_data.length() % maxChunkSize > 0 ? 1 : 0);\n\tchunkCount = chunkCount == 0 ? 1 : chunkCount;\n\n\tChunks allChunks;\n\n\tfor (size_t chunkIndex = 0; chunkIndex < chunkCount; chunkIndex++)\n\t{\n\t\tbytes chunkBytes = asBytes(\n\t\t\t_data.substr(chunkIndex * maxChunkSize, std::min(maxChunkSize, _data.length() - chunkIndex * maxChunkSize))\n\t\t);\n\n\t\tbytes lengthAsVarint = varintEncoding(chunkBytes.size());\n\n\t\tbytes protobufEncodedData;\n\t\t// Type: File\n\t\tprotobufEncodedData += bytes{0x08, 0x02};\n\t\tif (!chunkBytes.empty())\n\t\t{\n\t\t\t// Data (length delimited bytes)\n\t\t\tprotobufEncodedData += bytes{0x12};\n\t\t\tprotobufEncodedData += lengthAsVarint;\n\t\t\tprotobufEncodedData += chunkBytes;\n\t\t}\n\t\t// filesize: length as varint\n\t\tprotobufEncodedData += bytes{0x18} + lengthAsVarint;\n\n\t\t// PBDag:\n\t\t// Data: (length delimited bytes)\n\t\tbytes blockData = encodeByteArray(protobufEncodedData);\n\n\t\t// Multihash: sha2-256, 256 bits\n\t\tallChunks.emplace_back(\n\t\t\tencodeHash(blockData),\n\t\t\tchunkBytes.size(),\n\t\t\tblockData.size()\n\t\t);\n\t}\n\n\treturn groupChunksBottomUp(std::move(allChunks));\n}\n\nstd::string solidity::util::ipfsHashBase58(std::string _data)\n{\n\treturn base58Encode(ipfsHash(std::move(_data)));\n}\n"
  },
  {
    "path": "libsolutil/IpfsHash.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/Common.h>\n\n#include <string>\n\nnamespace solidity::util\n{\n\n/// Compute the \"ipfs hash\" of a file with the content @a _data.\n/// The output will be the multihash of the UnixFS protobuf encoded data.\n/// As hash function it will use sha2-256.\n/// The effect is that the hash should be identical to the one produced by\n/// the command `ipfs add <filename>`.\nbytes ipfsHash(std::string _data);\n\n/// Compute the \"ipfs hash\" as above, but encoded in base58 as used by ipfs / bitcoin.\nstd::string ipfsHashBase58(std::string _data);\n\n}\n"
  },
  {
    "path": "libsolutil/JSON.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file JSON.cpp\n * @author Alexander Arlt <alexander.arlt@arlt-labs.com>\n * @date 2018\n */\n\n#include <libsolutil/JSON.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <boost/algorithm/string.hpp>\n\n#include <sstream>\n\nnamespace solidity::util\n{\n\nnamespace\n{\n\n/// Takes a JSON value (@ _json) and removes all its members with value 'null' recursively.\nvoid removeNullMembersHelper(Json& _json)\n{\n\tif (_json.is_array())\n\t{\n\t\tfor (auto& child: _json)\n\t\t\tremoveNullMembersHelper(child);\n\t}\n\telse if (_json.is_object())\n\t{\n\t\tfor (auto it = _json.begin(); it != _json.end();)\n\t\t{\n\t\t\tif (it->is_null())\n\t\t\t\tit = _json.erase(it);\n\t\t\telse\n\t\t\t{\n\t\t\t\tremoveNullMembersHelper(*it);\n\t\t\t\t++it;\n\t\t\t}\n\t\t}\n\t}\n}\n\nstd::string escapeNewlinesAndTabsWithinStringLiterals(std::string const& _json)\n{\n\tstd::stringstream fixed;\n\tbool inQuotes = false;\n\tfor (size_t i = 0; i < _json.size(); ++i)\n\t{\n\t\tchar c = _json[i];\n\n\t\t// Originally we had just this here:\n\t\t// if (c == '\"' && (i == 0 || _json[i - 1] != '\\\\'))\n\t\t//    inQuotes = !inQuotes;\n\t\t// However, this is not working if the escape character itself was escaped. e.g. \"\\n\\r'\\\"\\\\\".\n\n\t\tif (c == '\"')\n\t\t{\n\t\t\tsize_t backslashCount = 0;\n\t\t\tsize_t j = i;\n\t\t\twhile (j > 0 && _json[j - 1] == '\\\\')\n\t\t\t{\n\t\t\t\tbackslashCount++;\n\t\t\t\tj--;\n\t\t\t}\n\t\t\tif (backslashCount % 2 == 0)\n\t\t\t{\n\t\t\t\tinQuotes = !inQuotes;\n\t\t\t\tfixed << c;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (inQuotes)\n\t\t{\n\t\t\tif (c == '\\n')\n\t\t\t\tfixed << \"\\\\n\";\n\t\t\telse if (c == '\\t')\n\t\t\t\tfixed << \"\\\\t\";\n\t\t\telse\n\t\t\t\tfixed << c;\n\t\t}\n\t\telse\n\t\t\tfixed << c;\n\t}\n\treturn fixed.str();\n}\n\n} // end anonymous namespace\n\nJson removeNullMembers(Json _json)\n{\n\tremoveNullMembersHelper(_json);\n\treturn _json;\n}\n\nstd::string removeNlohmannInternalErrorIdentifier(std::string const& _input)\n{\n\tstd::string result = _input;\n\tstd::size_t startPos = result.find('[');\n\tstd::size_t endPos = result.find(']', startPos);\n\n\tif (startPos != std::string::npos && endPos != std::string::npos)\n\t\tresult.erase(startPos, endPos - startPos + 1);\n\n\treturn boost::trim_copy(result);\n}\n\nstd::string jsonPrettyPrint(Json const& _input) { return jsonPrint(_input, JsonFormat{JsonFormat::Pretty}); }\n\nstd::string jsonCompactPrint(Json const& _input) { return jsonPrint(_input, JsonFormat{JsonFormat::Compact}); }\n\nstd::string jsonPrint(Json const& _input, JsonFormat const& _format)\n{\n\t// NOTE: -1 here means no new lines (it is also the default setting)\n\tstd::string dumped = _input.dump(\n\t\t/* indent */ (_format.format == JsonFormat::Pretty) ? static_cast<int>(_format.indent) : -1,\n\t\t/* indent_char */ ' ',\n\t\t/* ensure_ascii */ true\n\t);\n\n\treturn dumped;\n}\n\nbool jsonParseStrict(std::string const& _input, Json& _json, std::string* _errs /* = nullptr */)\n{\n\ttry\n\t{\n\t\t_json = Json::parse(\n\t\t\t// TODO: remove this in the next breaking release?\n\t\t\tescapeNewlinesAndTabsWithinStringLiterals(_input),\n\t\t\t/* callback */ nullptr,\n\t\t\t/* allow exceptions */ true,\n\t\t\t/* ignore_comments */true\n\t\t);\n\t\treturn true;\n\t}\n\tcatch (Json::parse_error const& e)\n\t{\n\t\tif (_errs)\n\t\t{\n\t\t\tstd::stringstream escaped;\n\t\t\tfor (char c: removeNlohmannInternalErrorIdentifier(e.what()))\n\t\t\t\tif (std::isprint(c))\n\t\t\t\t\tescaped << c;\n\t\t\t\telse\n\t\t\t\t\tescaped << \"\\\\x\" + toHex(static_cast<uint8_t>(c));\n\t\t\t*_errs = escaped.str();\n\t\t}\n\t\treturn false;\n\t}\n}\n\nstd::optional<Json> jsonValueByPath(Json const& _node, std::string_view _jsonPath)\n{\n\tif (!_node.is_object() || _jsonPath.empty())\n\t\treturn {};\n\n\tstd::string memberName = std::string(_jsonPath.substr(0, _jsonPath.find_first_of('.')));\n\tif (!_node.contains(memberName))\n\t\treturn {};\n\n\tif (memberName == _jsonPath)\n\t\treturn _node[memberName];\n\n\treturn jsonValueByPath(_node[memberName], _jsonPath.substr(memberName.size() + 1));\n}\n\n} // namespace solidity::util\n"
  },
  {
    "path": "libsolutil/JSON.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file JSON.h\n * @date 2016\n *\n * JSON related helpers\n */\n\n#pragma once\n\n#include <libsolutil/Assertions.h>\n#include <nlohmann/json.hpp>\n\n#include <string>\n#include <string_view>\n#include <optional>\n#include <limits>\n\nnamespace solidity\n{\n\nusing Json = nlohmann::json;\n\n} // namespace solidity\n\nnamespace solidity::util\n{\n\n/// Removes members with null value recursively from (@a _json).\nJson removeNullMembers(Json _json);\n\n/// JSON printing format.\nstruct JsonFormat\n{\n\tenum Format\n\t{\n\t\tCompact, // No unnecessary whitespace (including new lines and indentation)\n\t\tPretty,  // Nicely indented, with new lines\n\t};\n\n\tstatic constexpr uint32_t defaultIndent = 2;\n\n\tbool operator==(JsonFormat const& _other) const noexcept { return (format == _other.format) && (indent == _other.indent); }\n\tbool operator!=(JsonFormat const& _other) const noexcept { return !(*this == _other); }\n\n\tFormat format = Compact;\n\tuint32_t indent = defaultIndent;\n};\n\n/// Serialise the JSON object (@a _input) with indentation\nstd::string jsonPrettyPrint(Json const& _input);\n\n/// Serialise the JSON object (@a _input) without indentation\nstd::string jsonCompactPrint(Json const& _input);\n\n/// Serialise the JSON object (@a _input) using specified format (@a _format)\nstd::string jsonPrint(Json const& _input, JsonFormat const& _format);\n\n/// Parse a JSON string (@a _input) with enabled strict-mode and writes resulting JSON object to (@a _json)\n/// \\param _input JSON input string\n/// \\param _json [out] resulting JSON object\n/// \\param _errs [out] Formatted error messages\n/// \\return \\c true if the document was successfully parsed, \\c false if an error occurred.\nbool jsonParseStrict(std::string const& _input, Json& _json, std::string* _errs = nullptr);\n\n/// Retrieves the value specified by @p _jsonPath by from a series of nested JSON dictionaries.\n/// @param _jsonPath A dot-separated series of dictionary keys.\n/// @param _node The node representing the start of the path.\n/// @returns The value of the last key on the path. @a nullptr if any node on the path descends\n/// into something that is not a dictionary or the key is not present.\nstd::optional<Json> jsonValueByPath(Json const& _node, std::string_view _jsonPath);\n\nstd::string removeNlohmannInternalErrorIdentifier(std::string const& _input);\n\nnamespace detail\n{\n\ntemplate<typename T>\nstruct helper;\n\ntemplate<typename T, bool(Json::*checkMember)() const, T(Json::*convertMember)() const>\nstruct helper_impl\n{\n\tstatic bool isOfType(Json const& _input)\n\t{\n\t\treturn (_input.*checkMember)();\n\t}\n\tstatic T get(Json const& _input)\n\t{\n\t\tassertThrow(isOfType(_input), InvalidType,  \"\");\n\t\treturn (_input.*convertMember)();\n\t}\n\tstatic T getOrDefault(Json const& _input, std::string const& _name, T _default = {})\n\t{\n\t\tT result = _default;\n\t\tif (_input.contains(_name) && isOfType(_input[_name]))\n\t\t\tresult = (_input[_name].*convertMember)();\n\t\treturn result;\n\t}\n};\n\ntemplate<typename T, typename RT, bool(Json::*checkMember)() const, T(Json::*convertMember)() const>\nstruct helper_impl_with_range_check\n{\n\tstatic bool isOfType(Json const& _input)\n\t{\n\t\tif ( (_input.*checkMember)())\n\t\t{\n\t\t\tT value = (_input.*convertMember)();\n\t\t\treturn (value >= std::numeric_limits<RT>::min() && value <= std::numeric_limits<RT>::max());\n\t\t}\n\t\treturn false;\n\t}\n\n\tstatic RT get(Json const& _input)\n\t{\n\t\tassertThrow(isOfType(_input), InvalidType,  \"\");\n\t\treturn static_cast<RT>((_input.*convertMember)());\n\t}\n\n\tstatic RT getOrDefault(Json const& _input, std::string const& _name, RT _default = {})\n\t{\n\t\tRT value = _default;\n\t\tif (_input.contains(_name) && isOfType(_input[_name]))\n\t\t\tvalue = static_cast<RT>((_input[_name].*convertMember)());\n\t\treturn value;\n\t}\n};\n\ntemplate<> struct helper<Json::string_t>: helper_impl<Json::string_t, &Json::is_string, &Json::get<Json::string_t>> {};\ntemplate<> struct helper<Json::number_integer_t>: helper_impl<Json::number_integer_t, &Json::is_number_integer, &Json::get<Json::number_integer_t>> {};\ntemplate<> struct helper<Json::number_unsigned_t>: helper_impl<Json::number_unsigned_t, &Json::is_number_integer, &Json::get<Json::number_unsigned_t>> {};\ntemplate<> struct helper<Json::number_float_t>: helper_impl<Json::number_float_t, &Json::is_number, &Json::get<Json::number_float_t>> {};\ntemplate<> struct helper<Json::boolean_t>: helper_impl<Json::boolean_t, &Json::is_boolean, &Json::get<Json::boolean_t>> {};\n\ntemplate<> struct helper<int32_t>: helper_impl_with_range_check<Json::number_integer_t, int32_t, &Json::is_number_integer, &Json::get<Json::number_integer_t>> {};\ntemplate<> struct helper<int16_t>: helper_impl_with_range_check<Json::number_integer_t, int16_t, &Json::is_number_integer, &Json::get<Json::number_integer_t>> {};\ntemplate<> struct helper<int8_t>: helper_impl_with_range_check<Json::number_integer_t, int8_t, &Json::is_number_integer, &Json::get<Json::number_integer_t>> {};\ntemplate<> struct helper<uint32_t>: helper_impl_with_range_check<Json::number_unsigned_t, uint32_t, &Json::is_number_integer, &Json::get<Json::number_unsigned_t>> {};\ntemplate<> struct helper<uint16_t>: helper_impl_with_range_check<Json::number_unsigned_t, uint16_t, &Json::is_number_integer, &Json::get<Json::number_unsigned_t>> {};\ntemplate<> struct helper<uint8_t>: helper_impl_with_range_check<Json::number_integer_t, uint8_t, &Json::is_number_integer, &Json::get<Json::number_integer_t>> {};\ntemplate<> struct helper<float>: helper_impl_with_range_check<Json::number_float_t, float, &Json::is_number, &Json::get<Json::number_float_t>> {};\n\n} // namespace detail\n\ntemplate<typename T>\nbool isOfType(Json const& _input)\n{\n\treturn detail::helper<T>::isOfType(_input);\n}\n\ntemplate<typename T>\nbool isOfTypeIfExists(Json const& _input, std::string const& _name)\n{\n\tif (_input.contains(_name))\n\t\treturn isOfType<T>(_input[_name]);\n\treturn true;\n}\n\ntemplate<typename T>\nT get(Json const& _input)\n{\n\treturn detail::helper<T>::get(_input);\n}\n\ntemplate<typename T>\nT getOrDefault(Json const& _input, std::string const& _name, T _default = {})\n{\n\treturn detail::helper<T>::getOrDefault(_input, _name, _default);\n}\n\n} // namespace solidity::util\n"
  },
  {
    "path": "libsolutil/Keccak256.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file SHA3.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <libsolutil/Keccak256.h>\n\n#include <cstdint>\n#include <cstring>\n\nnamespace solidity::util\n{\n\nnamespace\n{\n\n/** libkeccak-tiny\n *\n * A single-file implementation of SHA-3 and SHAKE.\n *\n * implementer: David Leon Gil\n * License: CC0, attribution kindly requested. Blame taken too,\n * but not liability.\n */\n\n/******** The Keccak-f[1600] permutation ********/\n\n/*** Constants. ***/\nstatic uint8_t const rho[24] = \\\n\t{ 1,  3,   6, 10, 15, 21,\n\t28, 36, 45, 55,  2, 14,\n\t27, 41, 56,  8, 25, 43,\n\t62, 18, 39, 61, 20, 44};\nstatic uint8_t const pi[24] = \\\n\t{10,  7, 11, 17, 18, 3,\n\t5, 16,  8, 21, 24, 4,\n\t15, 23, 19, 13, 12, 2,\n\t20, 14, 22,  9, 6,  1};\nstatic uint64_t const RC[24] = \\\n\t{1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,\n\t0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,\n\t0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,\n\t0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,\n\t0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,\n\t0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};\n\n/*** Helper macros to unroll the permutation. ***/\n#define rol(x, s) (((x) << s) | ((x) >> (64 - s)))\n#define REPEAT6(e) e e e e e e\n#define REPEAT24(e) REPEAT6(e e e e)\n#define REPEAT5(e) e e e e e\n#define FOR5(type, v, s, e) \\\n\tv = 0;            \\\n\tREPEAT5(e; v = static_cast<type>(v + s);)\n\n/*** Keccak-f[1600] ***/\nstatic inline void keccakf(void* state) {\n\tauto* a = static_cast<uint64_t*>(state);\n\tuint64_t b[5] = {0};\n\n\tfor (int i = 0; i < 24; i++)\n\t{\n\t\tuint8_t x, y;\n\t\t// Theta\n\t\tFOR5(uint8_t, x, 1,\n\t\t\tb[x] = 0;\n\t\t\tFOR5(uint8_t, y, 5,\n\t\t\t\tb[x] ^= a[x + y]; ))\n\t\tFOR5(uint8_t, x, 1,\n\t\t\tFOR5(uint8_t, y, 5,\n\t\t\t\ta[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); ))\n\t\t// Rho and pi\n\t\tuint64_t t = a[1];\n\t\tx = 0;\n\t\tREPEAT24(b[0] = a[pi[x]];\n\t\t\t\ta[pi[x]] = rol(t, rho[x]);\n\t\t\t\tt = b[0];\n\t\t\t\tx++; )\n\t\t// Chi\n\t\tFOR5(uint8_t,\n\t\t\ty,\n\t\t\t5,\n\t\t\tFOR5(uint8_t, x, 1,\n\t\t\t\tb[x] = a[y + x];)\n\t\t\tFOR5(uint8_t, x, 1,\n\t\t\t\ta[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); ))\n\t\t// Iota\n\t\ta[0] ^= RC[i];\n\t}\n}\n\n/******** The FIPS202-defined functions. ********/\n\n/*** Some helper macros. ***/\n\n#define _(S) do { S } while (0)\n#define FOR(i, ST, L, S) \\\n\t_(for (size_t i = 0; i < L; i += ST) { S; })\n#define mkapply_ds(NAME, S)                                          \\\n\tstatic inline void NAME(uint8_t* dst,                              \\\n\t\t\t\t\t\t\tuint8_t const* src,                        \\\n\t\t\t\t\t\t\tsize_t len) {                              \\\n\t\tFOR(i, 1, len, S);                                               \\\n\t}\n#define mkapply_sd(NAME, S)                                          \\\n\tstatic inline void NAME(uint8_t const* src,                        \\\n\t\t\t\t\t\t\tuint8_t* dst,                              \\\n\t\t\t\t\t\t\tsize_t len) {                              \\\n\t\tFOR(i, 1, len, S);                                               \\\n\t}\n\nmkapply_ds(xorin, dst[i] ^= src[i])  // xorin\nmkapply_sd(setout, dst[i] = src[i])  // setout\n\n#define P keccakf\n#define Plen 200\n\n// Fold P*F over the full blocks of an input.\n#define foldP(I, L, F) \\\n\twhile (L >= rate) {  \\\n\t\tF(a, I, rate);     \\\n\t\tP(a);              \\\n\t\tI += rate;         \\\n\t\tL -= rate;         \\\n\t}\n\n/** The sponge-based hash construction. **/\ninline void hash(\n\tuint8_t* out,\n\tsize_t outlen,\n\tuint8_t const* in,\n\tsize_t inlen,\n\tsize_t rate,\n\tuint8_t delim\n)\n{\n\tuint8_t a[Plen] = {0};\n\t// Absorb input.\n\tfoldP(in, inlen, xorin);\n\t// Xor in the DS and pad frame.\n\ta[inlen] ^= delim;\n\ta[rate - 1] ^= 0x80;\n\t// Xor in the last block.\n\txorin(a, in, inlen);\n\t// Apply P\n\tP(a);\n\t// Squeeze output.\n\tfoldP(out, outlen, setout);\n\tsetout(a, out, outlen);\n\tmemset(a, 0, 200);\n}\n\n}\n\nh256 keccak256(bytesConstRef _input)\n{\n\th256 output;\n\t// Parameters used:\n\t// The 0x01 is the specific padding for keccak (sha3 uses 0x06) and\n\t// the way the round size (or window or whatever it was) is calculated.\n\t// 200 - (256 / 4) is the \"rate\"\n\thash(output.data(), output.size, _input.data(), _input.size(), 200 - (256 / 4), 0x01);\n\treturn output;\n}\n\n}\n"
  },
  {
    "path": "libsolutil/Keccak256.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file SHA3.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * The FixedHash fixed-size \"hash\" container type.\n */\n\n#pragma once\n\n#include <libsolutil/FixedHash.h>\n\n#include <string>\n\nnamespace solidity::util\n{\n\n/// Calculate Keccak-256 hash of the given input, returning as a 256-bit hash.\nh256 keccak256(bytesConstRef _input);\n\n/// Calculate Keccak-256 hash of the given input, returning as a 256-bit hash.\ninline h256 keccak256(bytes const& _input) { return keccak256(bytesConstRef(&_input)); }\n\n/// Calculate Keccak-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash.\ninline h256 keccak256(std::string const& _input) { return keccak256(bytesConstRef(_input)); }\n\n/// Calculate Keccak-256 hash of the given input (presented as a FixedHash), returns a 256-bit hash.\ntemplate<unsigned N> inline h256 keccak256(FixedHash<N> const& _input) { return keccak256(_input.ref()); }\n\n}\n"
  },
  {
    "path": "libsolutil/LEB128.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n\n#include <libsolutil/Common.h>\n\nnamespace solidity::util\n{\n\ninline bytes lebEncode(uint64_t _n)\n{\n\tbytes encoded;\n\twhile (_n > 0x7f)\n\t{\n\t\tencoded.emplace_back(uint8_t(0x80 | (_n & 0x7f)));\n\t\t_n >>= 7;\n\t}\n\tencoded.emplace_back(_n);\n\treturn encoded;\n}\n\n// signed right shift is an arithmetic right shift\nstatic_assert((-1 >> 1) == -1, \"Arithmetic shift not supported.\");\n\ninline bytes lebEncodeSigned(int64_t _n)\n{\n\t// Based on https://github.com/llvm/llvm-project/blob/master/llvm/include/llvm/Support/LEB128.h\n\tbytes result;\n\tbool more;\n\tdo\n\t{\n\t\tuint8_t v = _n & 0x7f;\n\t\t_n >>= 7;\n\t\tmore = !((((_n == 0) && ((v & 0x40) == 0)) || ((_n == -1) && ((v & 0x40) != 0))));\n\t\tif (more)\n\t\t\tv |= 0x80; // Mark this byte to show that more bytes will follow.\n\t\tresult.emplace_back(v);\n\t}\n\twhile (more);\n\treturn result;\n}\n\n}\n"
  },
  {
    "path": "libsolutil/LazyInit.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/Assertions.h>\n#include <libsolutil/Exceptions.h>\n\n#include <memory>\n#include <optional>\n#include <type_traits>\n#include <utility>\n\nnamespace solidity::util\n{\n\nDEV_SIMPLE_EXCEPTION(BadLazyInitAccess);\n\n/**\n * A value that is initialized at some point after construction of the LazyInit. The stored value can only be accessed\n * while calling \"init\", which initializes the stored value (if it has not already been initialized).\n *\n * @tparam T the type of the stored value; may not be a function, reference, array, or void type; may be const-qualified.\n */\ntemplate<typename T>\nclass LazyInit\n{\npublic:\n\tusing value_type = T;\n\n\tstatic_assert(std::is_object_v<value_type>, \"Function, reference, and void types are not supported\");\n\tstatic_assert(!std::is_array_v<value_type>, \"Array types are not supported.\");\n\tstatic_assert(!std::is_volatile_v<value_type>, \"Volatile-qualified types are not supported.\");\n\n\tLazyInit() = default;\n\n\tLazyInit(LazyInit const&) = delete;\n\tLazyInit& operator=(LazyInit const&) = delete;\n\n\t// Move constructor must be overridden to ensure that moved-from object is left empty.\n\tconstexpr LazyInit(LazyInit&& _other) noexcept:\n\t\tm_value(std::move(_other.m_value))\n\t{\n\t\t_other.m_value.reset();\n\t}\n\n\tLazyInit& operator=(LazyInit&& _other) noexcept\n\t{\n\t\tthis->m_value.swap(_other.m_value);\n\t\t_other.m_value.reset();\n\t}\n\n\ttemplate<typename F>\n\tvalue_type& init(F&& _fun)\n\t{\n\t\tdoInit(std::forward<F>(_fun));\n\t\treturn m_value.value();\n\t}\n\n\ttemplate<typename F>\n\tvalue_type const& init(F&& _fun) const\n\t{\n\t\tdoInit(std::forward<F>(_fun));\n\t\treturn m_value.value();\n\t}\n\nprivate:\n\t/// Although not quite logically const, this is marked const for pragmatic reasons. It doesn't change the platonic\n\t/// value of the object (which is something that is initialized to some computed value on first use).\n\ttemplate<typename F>\n\tvoid doInit(F&& _fun) const\n\t{\n\t\tif (!m_value.has_value())\n\t\t\tm_value.emplace(std::forward<F>(_fun)());\n\t}\n\n\tmutable std::optional<value_type> m_value;\n};\n\n}\n"
  },
  {
    "path": "libsolutil/Numeric.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolutil/Numeric.h>\n\n#include <liblangutil/Exceptions.h>\n\nusing namespace solidity;\n\nbool solidity::fitsPrecisionBaseX(bigint const& _mantissa, double _log2OfBase, uint32_t _exp)\n{\n\tif (_mantissa == 0)\n\t\treturn true;\n\n\tsolAssert(_mantissa > 0, \"\");\n\n\tsize_t const bitsMax = 4096;\n\n\tsize_t mostSignificantMantissaBit = static_cast<size_t>(boost::multiprecision::msb(_mantissa));\n\tif (mostSignificantMantissaBit > bitsMax) // _mantissa >= 2 ^ 4096\n\t\treturn false;\n\n\tbigint bitsNeeded = mostSignificantMantissaBit + bigint(floor(double(_exp) * _log2OfBase)) + 1;\n\treturn bitsNeeded <= bitsMax;\n}\n"
  },
  {
    "path": "libsolutil/Numeric.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Definition of u256 and similar types and helper functions.\n */\n\n#pragma once\n\n#include <libsolutil/Common.h>\n#include <libsolutil/CommonData.h>\n\n#include <boost/version.hpp>\n\n// TODO: do this only conditionally as soon as a boost version with gcc 12 support is released.\n#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wmaybe-uninitialized\"\n#pragma GCC diagnostic ignored \"-Warray-bounds\"\n#pragma GCC diagnostic ignored \"-Wstringop-overread\"\n#pragma GCC diagnostic ignored \"-Waggressive-loop-optimizations\"\n#endif\n#include <boost/multiprecision/cpp_int.hpp>\n#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)\n#pragma GCC diagnostic pop\n#endif\n\n#include <limits>\n\nnamespace solidity\n{\n\n// Numeric types.\nusing bigint = boost::multiprecision::cpp_int;\nusing u256 = boost::multiprecision::uint256_t;\nusing s256 = boost::multiprecision::int256_t;\nusing u512 = boost::multiprecision::uint512_t;\n\n\n/// Interprets @a _u as a two's complement signed number and returns the resulting s256.\ninline s256 u2s(u256 _u)\n{\n\tstatic bigint const c_end = bigint(1) << 256;\n\tif (boost::multiprecision::bit_test(_u, 255))\n\t\treturn s256(-(c_end - _u));\n\telse\n\t\treturn s256(_u);\n}\n\n/// @returns the two's complement signed representation of the signed number _u.\ninline u256 s2u(s256 _u)\n{\n\tstatic bigint const c_end = bigint(1) << 256;\n\tif (_u >= 0)\n\t\treturn u256(_u);\n\telse\n\t\treturn u256(c_end + _u);\n}\n\ninline u256 exp256(u256 _base, u256 _exponent)\n{\n\tusing boost::multiprecision::limb_type;\n\tu256 result = 1;\n\twhile (_exponent)\n\t{\n\t\tif (boost::multiprecision::bit_test(_exponent, 0))\n\t\t\tresult *= _base;\n\t\t_base *= _base;\n\t\t_exponent >>= 1;\n\t}\n\treturn result;\n}\n\n/// Checks whether _mantissa * (X ** _exp) fits into 4096 bits,\n/// where X is given indirectly via _log2OfBase = log2(X).\nbool fitsPrecisionBaseX(bigint const& _mantissa, double _log2OfBase, uint32_t _exp);\n\n\n// Big-endian to/from host endian conversion functions.\n\n/// Converts a templated integer value to the big-endian byte-stream represented on a templated collection.\n/// The size of the collection object will be unchanged. If it is too small, it will not represent the\n/// value properly, if too big then the additional elements will be zeroed out.\n/// @a Out will typically be either std::string or bytes.\n/// @a T will typically by unsigned, u160, u256 or bigint.\ntemplate <class T, class Out>\ninline void toBigEndian(T _val, Out&& o_out)\n{\n\tstatic_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, \"only unsigned types or bigint supported\"); //bigint does not carry sign bit on shift\n\tfor (auto i = o_out.size(); i != 0u; _val >>= 8u, i--)\n\t{\n\t\tT v = _val & (T)0xffu;\n\t\to_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v;\n\t}\n}\n\n/// Converts a big-endian byte-stream represented on a templated collection to a templated integer value.\n/// @a In will typically be either std::string or bytes.\n/// @a T will typically by unsigned, u256 or bigint.\ntemplate <class T, class In>\ninline T fromBigEndian(In const& _bytes)\n{\n\tT ret = (T)0;\n\tfor (auto i: _bytes)\n\t\tret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i);\n\treturn ret;\n}\ninline bytes toBigEndian(u256 _val) { bytes ret(32); toBigEndian(_val, ret); return ret; }\n\n/// Convenience function for toBigEndian.\n/// @returns a byte array just big enough to represent @a _val.\ntemplate <class T>\ninline bytes toCompactBigEndian(T _val, unsigned _min = 0)\n{\n\tstatic_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, \"only unsigned types or bigint supported\"); //bigint does not carry sign bit on shift\n\tunsigned i = 0;\n\tfor (T v = _val; v; ++i, v >>= 8) {}\n\tbytes ret(std::max<unsigned>(_min, i), 0);\n\ttoBigEndian(_val, ret);\n\treturn ret;\n}\n\n/// Convenience function for conversion of a u256 to hex\ninline std::string toHex(u256 val)\n{\n\treturn util::toHex(toBigEndian(val));\n}\n\ntemplate <class T>\ninline std::string toCompactHexWithPrefix(T _value)\n{\n\treturn \"0x\" + util::toHex(toCompactBigEndian(_value, 1));\n}\n\n/// Returns decimal representation for small numbers and hex for large numbers.\ninline std::string formatNumber(bigint const& _value)\n{\n\tif (_value < 0)\n\t\treturn \"-\" + formatNumber(-_value);\n\tif (_value > 0x1000000)\n\t\treturn \"0x\" + util::toHex(toCompactBigEndian(_value, 1));\n\telse\n\t\treturn _value.str();\n}\n\ninline std::string formatNumber(u256 const& _value)\n{\n\tif (_value > 0x1000000)\n\t\treturn toCompactHexWithPrefix(_value);\n\telse\n\t\treturn _value.str();\n}\n\n\n// Algorithms for string and string-like collections.\n\n/// Determine bytes required to encode the given integer value. @returns 0 if @a _i is zero.\ntemplate <class T>\ninline unsigned numberEncodingSize(T _i)\n{\n\tstatic_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, \"only unsigned types or bigint supported\"); //bigint does not carry sign bit on shift\n\tunsigned i = 0;\n\tfor (; _i != 0; ++i, _i >>= 8) {}\n\treturn i;\n}\n\n}\n"
  },
  {
    "path": "libsolutil/Profiler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolutil/Profiler.h>\n\n#include <fmt/format.h>\n\n#include <algorithm>\n#include <iostream>\n#include <vector>\n\nusing namespace std::chrono;\nusing namespace solidity;\n\n#ifdef PROFILE_OPTIMIZER_STEPS\n\nutil::Profiler::Probe::Probe(std::string _scopeName):\n\tm_scopeName(std::move(_scopeName)),\n\tm_startTime(steady_clock::now())\n{\n}\n\nutil::Profiler::Probe::~Probe()\n{\n\tsteady_clock::time_point endTime = steady_clock::now();\n\n\tauto [metricsIt, inserted] = Profiler::singleton().m_metrics.try_emplace(m_scopeName, Metrics{0us, 0});\n\tmetricsIt->second.durationInMicroseconds += duration_cast<microseconds>(endTime - m_startTime);\n\t++metricsIt->second.callCount;\n}\n\nutil::Profiler::~Profiler()\n{\n\toutputPerformanceMetrics();\n}\n\nutil::Profiler& util::Profiler::singleton()\n{\n\tstatic Profiler profiler;\n\treturn profiler;\n}\n\nvoid util::Profiler::outputPerformanceMetrics()\n{\n\tstd::vector<std::pair<std::string, Metrics>> sortedMetrics(m_metrics.begin(), m_metrics.end());\n\tstd::sort(\n\t\tsortedMetrics.begin(),\n\t\tsortedMetrics.end(),\n\t\t[](std::pair<std::string, Metrics> const& _lhs, std::pair<std::string, Metrics> const& _rhs) -> bool\n\t\t{\n\t\t\treturn _lhs.second.durationInMicroseconds < _rhs.second.durationInMicroseconds;\n\t\t}\n\t);\n\n\tstd::chrono::microseconds totalDurationInMicroseconds = 0us;\n\tsize_t totalCallCount = 0;\n\tfor (auto&& [scopeName, scopeMetrics]: sortedMetrics)\n\t{\n\t\ttotalDurationInMicroseconds += scopeMetrics.durationInMicroseconds;\n\t\ttotalCallCount += scopeMetrics.callCount;\n\t}\n\n\tstd::cerr << \"PERFORMANCE METRICS FOR PROFILED SCOPES\\n\\n\";\n\tstd::cerr << \"| Time % | Time       | Calls   | Scope                          |\\n\";\n\tstd::cerr << \"|-------:|-----------:|--------:|--------------------------------|\\n\";\n\n\tdouble totalDurationInSeconds = duration_cast<duration<double>>(totalDurationInMicroseconds).count();\n\tfor (auto&& [scopeName, scopeMetrics]: sortedMetrics)\n\t{\n\t\tdouble durationInSeconds = duration_cast<duration<double>>(scopeMetrics.durationInMicroseconds).count();\n\t\tdouble percentage = 100.0 * durationInSeconds / totalDurationInSeconds;\n\t\tstd::cerr << fmt::format(\n\t\t\t\"| {:5.1f}% | {:8.3f} s | {:7} | {:30} |\\n\",\n\t\t\tpercentage,\n\t\t\tdurationInSeconds,\n\t\t\tscopeMetrics.callCount,\n\t\t\tscopeName\n\t\t);\n\t}\n\tstd::cerr << fmt::format(\"| {:5.1f}% | {:8.3f} s | {:7} | {:30} |\\n\", 100.0, totalDurationInSeconds, totalCallCount, \"**TOTAL**\");\n}\n\n#endif\n"
  },
  {
    "path": "libsolutil/Profiler.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <chrono>\n#include <map>\n#include <optional>\n#include <string>\n\n#ifdef PROFILE_OPTIMIZER_STEPS\n#define PROFILER_PROBE(_scopeName, _variable) solidity::util::Profiler::Probe _variable(_scopeName);\n#else\n#define PROFILER_PROBE(_scopeName, _variable) void(0);\n#endif\n\nnamespace solidity::util\n{\n\n#ifdef PROFILE_OPTIMIZER_STEPS\n\n/// Simpler profiler class that gathers metrics during program execution and prints them out on exit.\n///\n/// To gather metrics, create a Probe instance and let it live until the end of the scope.\n/// The probe will register its creation and destruction time and store the results in the profiler\n/// singleton.\n///\n/// Use the PROFILER_PROBE macro to create probes conditionally, in a way that will not affect performance\n/// unless profiling is enabled at compilation time via PROFILE_OPTIMIZER_STEPS CMake option.\n///\n/// Scopes are identified by the name supplied to the probe. Using the same name multiple times\n/// will result in metrics for those scopes being aggregated together as if they were the same scope.\nclass Profiler\n{\npublic:\n\tclass Probe\n\t{\n\tpublic:\n\t\tProbe(std::string _scopeName);\n\t\t~Probe();\n\n\tprivate:\n\t\tstd::string m_scopeName;\n\t\tstd::chrono::steady_clock::time_point m_startTime;\n\t};\n\n\tstatic Profiler& singleton();\n\nprivate:\n\t~Profiler();\n\n\tstruct Metrics\n\t{\n\t\tstd::chrono::microseconds durationInMicroseconds;\n\t\tsize_t callCount;\n\t};\n\n\t/// Summarizes gathered metric and prints a report to standard error output.\n\tvoid outputPerformanceMetrics();\n\n\tstd::map<std::string, Metrics> m_metrics;\n};\n\n#endif\n\n}\n"
  },
  {
    "path": "libsolutil/Result.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <string>\n\nnamespace solidity::util\n{\n\n/// Simple generic result that holds a value and an optional error message.\n/// Results can be implicitly converted to and created from the type of\n/// the value they hold. The class is mainly designed for a result type of\n/// bool or pointer type. The idea is that the default constructed value of\n/// the result type is interpreted as an error value.\n///\n/// Result<bool> check()\n/// {\n///     if (false)\n///         return Result<bool>::err(\"Error message.\")\n///     return true;\n/// }\n///\n\ntemplate <class ResultType>\nclass [[nodiscard]] Result\n{\npublic:\n\t/// Constructs a result with _value and an empty message.\n\t/// This is meant to be called with valid results. Please use\n\t/// the static err() member function to signal an error.\n\tResult(ResultType _value): Result(_value, std::string{}) {}\n\n\t/// Constructs a result with a default-constructed value and an\n\t/// error message.\n\tstatic Result<ResultType> err(std::string _message)\n\t{\n\t\treturn Result{ResultType{}, std::move(_message)};\n\t}\n\n\t/// @{\n\t/// @name Wrapper functions\n\t/// Wrapper functions that provide implicit conversions to and explicit retrieval of\n\t/// the value this result holds.\n\toperator ResultType const&() const { return m_value; }\n\tResultType const& get() const { return m_value; }\n\t/// @}\n\n\t/// @returns the error message (can be empty).\n\tstd::string const& message() const { return m_message; }\n\n\t/// Merges _other into this using the _merger\n\t/// and appends the error messages. Meant to be called\n\t/// with logical operators like logical_and, etc.\n\ttemplate<typename F>\n\tvoid merge(Result<ResultType> const& _other, F _merger)\n\t{\n\t\tm_value = _merger(m_value, _other.get());\n\t\tm_message += _other.message();\n\t}\n\nprivate:\n\texplicit Result(ResultType _value, std::string _message):\n\t\tm_value(std::move(_value)),\n\t\tm_message(std::move(_message))\n\t{}\n\n\tResultType m_value;\n\tstd::string m_message;\n};\n\n}\n"
  },
  {
    "path": "libsolutil/SetOnce.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#pragma once\n\n#include <libsolutil/Assertions.h>\n#include <libsolutil/Exceptions.h>\n\n#include <memory>\n#include <optional>\n#include <utility>\n\nnamespace solidity::util\n{\n\nDEV_SIMPLE_EXCEPTION(BadSetOnceReassignment);\nDEV_SIMPLE_EXCEPTION(BadSetOnceAccess);\n\n/// A class that stores a value that can only be set once\n/// \\tparam T the type of the stored value\ntemplate<typename T>\nclass SetOnce\n{\npublic:\n\t/// Initializes the class to have no stored value.\n\tSetOnce() = default;\n\n\t// Not copiable\n\tSetOnce(SetOnce const&) = delete;\n\tSetOnce(SetOnce&&) = delete;\n\n\t// Not movable\n\tSetOnce& operator=(SetOnce const&) = delete;\n\tSetOnce& operator=(SetOnce&&) = delete;\n\n\t/// @brief Sets the stored value to \\p _newValue\n\t/// @throws BadSetOnceReassignment when the stored value has already been set\n\t/// @return `*this`\n\tconstexpr SetOnce& operator=(T _newValue) &\n\t{\n\t\tassertThrow(\n\t\t\t!m_value.has_value(),\n\t\t\tBadSetOnceReassignment,\n\t\t\t\"Attempt to reassign to a SetOnce that already has a value.\"\n\t\t);\n\n\t\tm_value.emplace(std::move(_newValue));\n\t\treturn *this;\n\t}\n\n\t/// @return A reference to the stored value. The returned reference has the same lifetime as `*this`.\n\t/// @throws BadSetOnceAccess when the stored value has not yet been set\n\tT const& operator*() const\n\t{\n\t\tassertThrow(\n\t\t\tm_value.has_value(),\n\t\t\tBadSetOnceAccess,\n\t\t\t\"Attempt to access the value of a SetOnce that does not have a value.\"\n\t\t);\n\n\t\treturn m_value.value();\n\t}\n\n\t/// @return A reference to the stored value. The referent of the returned pointer has the same lifetime as `*this`.\n\t/// @throws BadSetOnceAccess when the stored value has not yet been set\n\tT const* operator->() const { return std::addressof(**this); }\n\n\t/// @return true if a value was assigned\n\tbool set() const { return m_value.has_value(); }\nprivate:\n\tstd::optional<T> m_value = std::nullopt;\n};\n\n}\n"
  },
  {
    "path": "libsolutil/StackTooDeepString.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <string>\n\nnamespace solidity::util\n{\n\tstatic std::string stackTooDeepString =\n\t\t\"Stack too deep. \"\n\t\t\"Try compiling with `--via-ir` (cli) or the equivalent `viaIR: true` (standard JSON) \"\n\t\t\"while enabling the optimizer. Otherwise, try removing local variables.\";\n}\n"
  },
  {
    "path": "libsolutil/StringUtils.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file StringUtils.h\n * @author Balajiganapathi S <balajiganapathi.s@gmail.com>\n * @date 2017\n *\n * String routines\n */\n\n#include <libsolutil/StringUtils.h>\n\n#include <boost/algorithm/string/trim.hpp>\n\n#include <fmt/format.h>\n\n#include <sstream>\n#include <string>\n#include <vector>\n\nusing namespace solidity;\nusing namespace solidity::util;\n\nbool solidity::util::stringWithinDistance(std::string const& _str1, std::string const& _str2, size_t _maxDistance, size_t _lenThreshold)\n{\n\tif (_str1 == _str2)\n\t\treturn true;\n\n\tsize_t n1 = _str1.size();\n\tsize_t n2 = _str2.size();\n\tif (_lenThreshold > 0 && n1 * n2 > _lenThreshold)\n\t\treturn false;\n\n\tsize_t distance = stringDistance(_str1, _str2);\n\n\t// if distance is not greater than _maxDistance, and distance is strictly less than length of both names, they can be considered similar\n\t// this is to avoid irrelevant suggestions\n\treturn distance <= _maxDistance && distance < n1 && distance < n2;\n}\n\nsize_t solidity::util::stringDistance(std::string const& _str1, std::string const& _str2)\n{\n\tsize_t n1 = _str1.size();\n\tsize_t n2 = _str2.size();\n\t// Optimize by storing only last 2 rows and current row. So first index is considered modulo 3\n\t// This is a two-dimensional array of size 3 x (n2 + 1).\n\tstd::vector<size_t> dp(3 * (n2 + 1));\n\n\t// In this dp formulation of Damerau–Levenshtein distance we are assuming that the strings are 1-based to make base case storage easier.\n\t// So index accesser to _name1 and _name2 have to be adjusted accordingly\n\tfor (size_t i1 = 0; i1 <= n1; ++i1)\n\t\tfor (size_t i2 = 0; i2 <= n2; ++i2)\n\t\t{\n\t\t\tsize_t x = 0;\n\t\t\tif (std::min(i1, i2) == 0) // base case\n\t\t\t\tx = std::max(i1, i2);\n\t\t\telse\n\t\t\t{\n\t\t\t\tsize_t left = dp[(i1 - 1) % 3 + i2 * 3];\n\t\t\t\tsize_t up = dp[(i1 % 3) + (i2 - 1) * 3];\n\t\t\t\tsize_t upleft = dp[((i1 - 1) % 3) + (i2 - 1) * 3];\n\t\t\t\t// deletion and insertion\n\t\t\t\tx = std::min(left + 1, up + 1);\n\t\t\t\tif (_str1[i1-1] == _str2[i2-1])\n\t\t\t\t\t// same chars, can skip\n\t\t\t\t\tx = std::min(x, upleft);\n\t\t\t\telse\n\t\t\t\t\t// different chars so try substitution\n\t\t\t\t\tx = std::min(x, upleft + 1);\n\n\t\t\t\t// transposing\n\t\t\t\tif (i1 > 1 && i2 > 1 && _str1[i1 - 1] == _str2[i2 - 2] && _str1[i1 - 2] == _str2[i2 - 1])\n\t\t\t\t\tx = std::min(x, dp[((i1 - 2) % 3) + (i2 - 2) * 3] + 1);\n\t\t\t}\n\t\t\tdp[(i1 % 3) + i2 * 3] = x;\n\t\t}\n\n\treturn dp[(n1 % 3) + n2 * 3];\n}\n\nstd::string solidity::util::quotedAlternativesList(std::vector<std::string> const& suggestions)\n{\n\tstd::vector<std::string> quotedSuggestions;\n\n\tfor (auto& suggestion: suggestions)\n\t\tquotedSuggestions.emplace_back(\"\\\"\" + suggestion + \"\\\"\");\n\n\treturn joinHumanReadable(quotedSuggestions, \", \", \" or \");\n}\n\nstd::string solidity::util::suffixedVariableNameList(std::string const& _baseName, size_t _startSuffix, size_t _endSuffix)\n{\n\tstd::string result;\n\tif (_startSuffix < _endSuffix)\n\t{\n\t\tresult = _baseName + std::to_string(_startSuffix++);\n\t\twhile (_startSuffix < _endSuffix)\n\t\t\tresult += \", \" + _baseName + std::to_string(_startSuffix++);\n\t}\n\telse if (_endSuffix < _startSuffix)\n\t{\n\t\tresult = _baseName + std::to_string(_endSuffix++);\n\t\twhile (_endSuffix < _startSuffix)\n\t\t\tresult = _baseName + std::to_string(_endSuffix++) + \", \" + result;\n\t}\n\treturn result;\n}\n\nnamespace\n{\n\n/// Try to format as N * 2**x\nstd::optional<std::string> tryFormatPowerOfTwo(bigint const& _value)\n{\n\tbigint prefix = _value;\n\n\t// when multiple trailing zero bytes, format as N * 2**x\n\tint i = 0;\n\tfor (; (prefix & 0xff) == 0; prefix >>= 8)\n\t\t++i;\n\tif (i <= 2)\n\t\treturn std::nullopt;\n\n\t// 0x100 yields 2**8 (N is 1 and redundant)\n\tif (prefix == 1)\n\t\treturn {fmt::format(\"2**{}\", i * 8)};\n\telse if ((prefix & (prefix - 1)) == 0)\n\t{\n\t\tint j = 0;\n\t\tfor (; (prefix & 0x1) == 0; prefix >>= 1)\n\t\t\tj++;\n\t\treturn {fmt::format(\"2**{}\", i * 8 + j)};\n\t}\n\telse\n\t\treturn {fmt::format(\n\t\t\t\"{} * 2**{}\",\n\t\t\ttoHex(toCompactBigEndian(prefix), HexPrefix::Add, HexCase::Mixed),\n\t\t\ti * 8\n\t\t)};\n}\n\n}\n\nstd::string solidity::util::formatNumberReadable(bigint const& _value, bool _useTruncation)\n{\n\tbool const isNegative = _value < 0;\n\tbigint const absValue = isNegative ? (bigint(-1) * _value) : bigint(_value);\n\tstd::string const sign = isNegative ? \"-\" : \"\";\n\n\t// smaller numbers return as decimal\n\tif (absValue <= 0x1000000)\n\t\treturn sign + absValue.str();\n\n\tif (auto result = tryFormatPowerOfTwo(absValue))\n\t\treturn {sign + *result};\n\telse if (auto result = tryFormatPowerOfTwo(absValue + 1))\n\t\treturn {sign + *result + (isNegative ? \" + 1\" : \" - 1\")};\n\n\tstd::string str = toHex(toCompactBigEndian(absValue), HexPrefix::Add, HexCase::Mixed);\n\n\tif (_useTruncation)\n\t{\n\t\t// return as interior-truncated hex.\n\t\tsize_t len = str.size();\n\n\t\tif (len < 24)\n\t\t\treturn sign + str;\n\n\t\tsize_t const initialChars = 6;\n\t\tsize_t const finalChars = 4;\n\t\tsize_t numSkipped = len - initialChars - finalChars;\n\n\t\treturn fmt::format(\n\t\t\t\"{}{}...{{+{} more}}...{}\",\n\t\t\tsign,\n\t\t\tstr.substr(0, initialChars),\n\t\t\tnumSkipped,\n\t\t\tstr.substr(len-finalChars, len)\n\t\t);\n\t}\n\n\treturn sign + str;\n}\n\nstd::string solidity::util::prefixLines(\n\tstd::string const& _input,\n\tstd::string const& _prefix,\n\tbool _trimPrefix\n)\n{\n\tstd::ostringstream output;\n\tprintPrefixed(output, _input, _prefix, _trimPrefix, false /* _ensureFinalNewline */);\n\treturn output.str();\n}\n\nvoid solidity::util::printPrefixed(\n\tstd::ostream& _output,\n\tstd::string const& _input,\n\tstd::string const& _prefix,\n\tbool _trimPrefix,\n\tbool _ensureFinalNewline\n)\n{\n\tstd::istringstream input(_input);\n\tstd::string line;\n\twhile (std::getline(input, line))\n\t{\n\t\tif (line.empty() && _trimPrefix)\n\t\t\t_output << boost::trim_right_copy(_prefix);\n\t\telse\n\t\t\t_output << _prefix << line;\n\t\tif (!input.eof() || _ensureFinalNewline)\n\t\t\t_output << '\\n';\n\t}\n}\n"
  },
  {
    "path": "libsolutil/StringUtils.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file StringUtils.h\n * @author Balajiganapathi S <balajiganapathi.s@gmail.com>\n * @date 2017\n *\n * String routines\n */\n\n#pragma once\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Numeric.h>\n\n#include <algorithm>\n#include <charconv>\n#include <limits>\n#include <locale>\n#include <optional>\n#include <string>\n#include <vector>\n\nnamespace solidity::util\n{\n\n// Calculates the Damerau–Levenshtein distance between _str1 and _str2 and returns true if that distance is not greater than _maxDistance\n// if _lenThreshold > 0 and the product of the strings length is greater than _lenThreshold, the function will return false\nbool stringWithinDistance(std::string const& _str1, std::string const& _str2, size_t _maxDistance, size_t _lenThreshold = 0);\n// Calculates the Damerau–Levenshtein distance between _str1 and _str2\nsize_t stringDistance(std::string const& _str1, std::string const& _str2);\n// Return a string having elements of suggestions as quoted, alternative suggestions. e.g. \"a\", \"b\" or \"c\"\nstd::string quotedAlternativesList(std::vector<std::string> const& suggestions);\n\n/// @returns a string containing a comma-separated list of variable names consisting of @a _baseName suffixed\n/// with increasing integers in the range [@a _startSuffix, @a _endSuffix), if @a _startSuffix < @a _endSuffix,\n/// and with decreasing integers in the range [@a _endSuffix, @a _startSuffix), if @a _endSuffix < @a _startSuffix.\n/// If @a _startSuffix == @a _endSuffix, the empty string is returned.\nstd::string suffixedVariableNameList(std::string const& _baseName, size_t _startSuffix, size_t _endSuffix);\n\n/// Joins collection of strings into one string with separators between, last separator can be different.\n/// @param _list collection of strings to join\n/// @param _separator defaults to \", \"\n/// @param _lastSeparator (optional) will be used to separate last two strings instead of _separator\n/// @example join(vector<string>{\"a\", \"b\", \"c\"}, \"; \", \" or \") == \"a; b or c\"\ntemplate<class T>\nstd::string joinHumanReadable\n(\n\tT const& _list,\n\tstd::string const& _separator = \", \",\n\tstd::string const& _lastSeparator = \"\"\n)\n{\n\tauto const itEnd = end(_list);\n\n\tstd::stringstream result;\n\n\tfor (auto it = begin(_list); it != itEnd; )\n\t{\n\t\tauto const& element = *it;\n\t\tbool first = (it == begin(_list));\n\t\t++it;\n\t\tif (!first)\n\t\t{\n\t\t\tif (it == itEnd && !_lastSeparator.empty())\n\t\t\t\tresult << _lastSeparator; // last iteration\n\t\t\telse\n\t\t\t\tresult << _separator;\n\t\t}\n\t\tresult << element;\n\t}\n\n\treturn result.str();\n}\n\n/// Joins collection of strings just like joinHumanReadable, but prepends the separator\n/// unless the collection is empty.\ntemplate<class T>\nstd::string joinHumanReadablePrefixed\n(\n\tT const& _list,\n\tstd::string const& _separator = \", \",\n\tstd::string const& _lastSeparator = \"\"\n)\n{\n\tif (begin(_list) == end(_list))\n\t\treturn {};\n\telse\n\t\treturn _separator + joinHumanReadable(_list, _separator, _lastSeparator);\n}\n\n/// Formats large numbers to be easily readable by humans.\n/// Returns decimal representation for smaller numbers; hex for large numbers.\n/// \"Special\" numbers, powers-of-two and powers-of-two minus 1, are returned in\n/// formulaic form like 0x01 * 2**24 - 1.\n/// @a T can be any integer type, will typically be u160, u256 or bigint.\n/// @param _value to be formatted\n/// @param _useTruncation if true, internal truncation is also applied,\n/// like  0x5555...{+56 more}...5555\n/// @example formatNumberReadable((u256)0x7ffffff) = \"2**27 - 1\"\n/// @example formatNumberReadable(-57896044618658097711785492504343953926634992332820282019728792003956564819968) = -2**255\nstd::string formatNumberReadable(bigint const& _value, bool _useTruncation = false);\n\n/// Safely converts an unsigned integer as string into an unsigned int type.\n///\n/// @return the converted number or nullopt in case of an failure (including if it would not fit).\ninline std::optional<unsigned> toUnsignedInt(std::string const& _value)\n{\n\ttry\n\t{\n\t\tauto const ulong = stoul(_value);\n\t\tif (ulong > std::numeric_limits<unsigned>::max())\n\t\t\treturn std::nullopt;\n\t\treturn static_cast<unsigned>(ulong);\n\t}\n\tcatch (...)\n\t{\n\t\treturn std::nullopt;\n\t}\n}\n\n/// Converts parameter _c to its lowercase equivalent if c is an uppercase letter and has a lowercase equivalent. It uses the classic \"C\" locale semantics.\n/// @param _c value to be converted\n/// @return the converted value\ninline char toLower(char _c)\n{\n\treturn tolower(_c, std::locale::classic());\n}\n\n/// Converts parameter _c to its uppercase equivalent if c is an lowercase letter and has a uppercase equivalent. It uses the classic \"C\" locale semantics.\n/// @param _c value to be converted\n/// @return the converted value\ninline char toUpper(char _c)\n{\n\treturn toupper(_c, std::locale::classic());\n}\n\n/// Converts parameter _s to its lowercase equivalent. It uses the classic \"C\" locale semantics.\n/// @param _s value to be converted\n/// @return the converted value\ninline std::string toLower(std::string _s)\n{\n\tstd::transform(_s.begin(), _s.end(), _s.begin(), [](char _c) {\n\t\treturn toLower(_c);\n\t});\n\treturn _s;\n}\n\n/// Checks whether _c is a decimal digit character. It uses the classic \"C\" locale semantics.\n/// @param _c character to be checked\n/// @return true if _c is a decimal digit character, false otherwise\ninline bool isDigit(char _c)\n{\n\treturn isdigit(_c, std::locale::classic());\n}\n\n/// Checks if character is printable using classic \"C\" locale\n/// @param _c character to be checked\n/// @return true if _c is a printable character, false otherwise.\ninline bool isPrint(char _c)\n{\n\treturn isprint(_c, std::locale::classic());\n}\n\n/// Adds a prefix to every line in the input.\n/// @see printPrefixed()\nstd::string prefixLines(\n\tstd::string const& _input,\n\tstd::string const& _prefix,\n\tbool _trimPrefix = true\n);\n\n/// Prints to a stream, adding a prefix to every line in the input.\n/// Assumes \\n as the line separator.\n/// @param _trimPrefix If true, the function avoids introducing trailing whitespace on empty lines.\n///     This is achieved by removing trailing spaces from the prefix on such lines.\n///     Note that tabs and newlines are not removed, only spaces are.\n/// @param _finalNewline If true, an extra \\n will be printed at the end of @a _input if it does\n///     not already end with one.\nvoid printPrefixed(\n\tstd::ostream& _output,\n\tstd::string const& _input,\n\tstd::string const& _prefix,\n\tbool _trimPrefix = true,\n\tbool _ensureFinalNewline = true\n);\n\n/// Adds a standard indent of 4 spaces to every line in the input.\n/// Assumes \\n as the line separator.\n/// @param _indentEmptyLines If true, the indent will be applied to empty lines as well, resulting\n///     such lines containing trailing whitespace.\ninline std::string indent(std::string const& _input, bool _indentEmptyLines = false)\n{\n\treturn prefixLines(_input, \"    \", !_indentEmptyLines);\n}\n\n/// Parses an arithmetic value from a `string_view` without allocating and/or throwing. Returns `nullopt` on error.\ntemplate<concepts::arithmetic T>\nstd::optional<T> parseArithmetic(std::string_view const sv)\n{\n\tT result;\n\tauto const errorCondition = std::from_chars(sv.data(), sv.data() + sv.size(), result).ec;\n\tif (errorCondition == std::errc())\n\t\treturn result;\n\treturn std::nullopt;\n}\n\n}\n"
  },
  {
    "path": "libsolutil/SwarmHash.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file SwarmHash.cpp\n */\n\n#include <libsolutil/SwarmHash.h>\n\n#include <libsolutil/Keccak256.h>\n\nusing namespace solidity;\nusing namespace solidity::util;\n\nnamespace\n{\n\nbytes toLittleEndian(uint64_t _size)\n{\n\tbytes encoded(8);\n\tfor (size_t i = 0; i < 8; ++i)\n\t\tencoded[i] = (_size >> (8 * i)) & 0xff;\n\treturn encoded;\n}\n\nh256 swarmHashSimple(bytesConstRef _data, size_t _size)\n{\n\treturn keccak256(toLittleEndian(_size) + _data.toBytes());\n}\n\nh256 swarmHashIntermediate(std::string const& _input, size_t _offset, size_t _length)\n{\n\tbytesConstRef ref;\n\tbytes innerNodes;\n\tif (_length <= 0x1000)\n\t\tref = bytesConstRef(_input).cropped(_offset, _length);\n\telse\n\t{\n\t\tsize_t maxRepresentedSize = 0x1000;\n\t\twhile (maxRepresentedSize * (0x1000 / 32) < _length)\n\t\t\tmaxRepresentedSize *= (0x1000 / 32);\n\t\tfor (size_t i = 0; i < _length; i += maxRepresentedSize)\n\t\t{\n\t\t\tsize_t size = std::min(maxRepresentedSize, _length - i);\n\t\t\tinnerNodes += swarmHashIntermediate(_input, _offset + i, size).asBytes();\n\t\t}\n\t\tref = bytesConstRef(&innerNodes);\n\t}\n\treturn swarmHashSimple(ref, _length);\n}\n\nh256 bmtHash(bytesConstRef _data)\n{\n\tif (_data.size() <= 64)\n\t\treturn keccak256(_data);\n\n\tsize_t midPoint = _data.size() / 2;\n\treturn keccak256(\n\t\tbmtHash(_data.cropped(0, midPoint)).asBytes() +\n\t\tbmtHash(_data.cropped(midPoint)).asBytes()\n\t);\n}\n\nh256 chunkHash(bytesConstRef const _data, bool _forceHigherLevel = false)\n{\n\tbytes dataToHash;\n\tif (_data.size() < 0x1000)\n\t\tdataToHash = _data.toBytes();\n\telse if (_data.size() == 0x1000 && !_forceHigherLevel)\n\t\tdataToHash = _data.toBytes();\n\telse\n\t{\n\t\tsize_t maxRepresentedSize = 0x1000;\n\t\twhile (maxRepresentedSize * (0x1000 / 32) < _data.size())\n\t\t\tmaxRepresentedSize *= (0x1000 / 32);\n\t\t// If remaining size is 0x1000, but maxRepresentedSize is not,\n\t\t// we have to still do one level of the chunk hashes.\n\t\tbool forceHigher = maxRepresentedSize > 0x1000;\n\t\tfor (size_t i = 0; i < _data.size(); i += maxRepresentedSize)\n\t\t{\n\t\t\tsize_t size = std::min(maxRepresentedSize, _data.size() - i);\n\t\t\tdataToHash += chunkHash(_data.cropped(i, size), forceHigher).asBytes();\n\t\t}\n\t}\n\n\tdataToHash.resize(0x1000, 0);\n\treturn keccak256(toLittleEndian(_data.size()) + bmtHash(&dataToHash).asBytes());\n}\n\n\n}\n\nh256 solidity::util::bzzr0Hash(std::string const& _input)\n{\n\treturn swarmHashIntermediate(_input, 0, _input.size());\n}\n\n\nh256 solidity::util::bzzr1Hash(bytes const& _input)\n{\n\tif (_input.empty())\n\t\treturn h256{};\n\treturn chunkHash(&_input);\n}\n"
  },
  {
    "path": "libsolutil/SwarmHash.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file SwarmHash.h\n */\n\n#pragma once\n\n#include <libsolutil/FixedHash.h>\n\n#include <string>\n\nnamespace solidity::util\n{\n\n/// Compute the \"swarm hash\" of @a _input (OLD 0x1000-section version)\nh256 bzzr0Hash(std::string const& _input);\n\n/// Compute the \"bzz hash\" of @a _input (the NEW binary / BMT version)\nh256 bzzr1Hash(bytes const& _input);\n\ninline h256 bzzr1Hash(std::string const& _input)\n{\n\treturn bzzr1Hash(asBytes(_input));\n}\n\n}\n"
  },
  {
    "path": "libsolutil/TemporaryDirectory.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libsolutil/TemporaryDirectory.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <boost/algorithm/string/predicate.hpp>\n#include <boost/filesystem.hpp>\n\n#include <regex>\n#include <iostream>\n\nusing namespace solidity;\nusing namespace solidity::util;\n\nnamespace fs = boost::filesystem;\n\nTemporaryDirectory::TemporaryDirectory(std::string const& _prefix):\n\tm_path(fs::temp_directory_path() / fs::unique_path(_prefix + \"-%%%%-%%%%-%%%%-%%%%\"))\n{\n\t// Prefix should just be a file name and not contain anything that would make us step out of /tmp.\n\tsolAssert(fs::path(_prefix) == fs::path(_prefix).stem(), \"\");\n\n\tfs::create_directory(m_path);\n}\n\nTemporaryDirectory::TemporaryDirectory(\n\tstd::vector<boost::filesystem::path> const& _subdirectories,\n\tstd::string const& _prefix\n):\n\tTemporaryDirectory(_prefix)\n{\n\tfor (boost::filesystem::path const& subdirectory: _subdirectories)\n\t{\n\t\tsolAssert(!subdirectory.is_absolute() && subdirectory.root_path() != \"/\", \"\");\n\t\tsolAssert(\n\t\t\tm_path.lexically_relative(subdirectory).empty() ||\n\t\t\t*m_path.lexically_relative(subdirectory).begin() != \"..\",\n\t\t\t\"\"\n\t\t);\n\t\tboost::filesystem::create_directories(m_path / subdirectory);\n\t}\n}\n\nTemporaryDirectory::~TemporaryDirectory()\n{\n\t// A few paranoid sanity checks just to be extra sure we're not deleting someone's homework.\n\tsolAssert(m_path.string().find(fs::temp_directory_path().string()) == 0, \"\");\n\tsolAssert(!fs::equivalent(m_path, fs::temp_directory_path()), \"\");\n\tsolAssert(!fs::equivalent(m_path, m_path.root_path()), \"\");\n\tsolAssert(!m_path.empty(), \"\");\n\n\tboost::system::error_code errorCode;\n\tuintmax_t numRemoved = fs::remove_all(m_path, errorCode);\n\tif (errorCode.value() != boost::system::errc::success)\n\t{\n\t\tstd::cerr << \"Failed to completely remove temporary directory '\" << m_path << \"'. \";\n\t\tstd::cerr << \"Only \" << numRemoved << \" files were actually removed.\" << std::endl;\n\t\tstd::cerr << \"Reason: \" << errorCode.message() << std::endl;\n\t}\n}\n\nTemporaryWorkingDirectory::TemporaryWorkingDirectory(fs::path const& _newDirectory):\n\tm_originalWorkingDirectory(fs::current_path())\n{\n\tfs::current_path(_newDirectory);\n}\n\nTemporaryWorkingDirectory::~TemporaryWorkingDirectory()\n{\n\tfs::current_path(m_originalWorkingDirectory);\n}\n"
  },
  {
    "path": "libsolutil/TemporaryDirectory.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Utilities for creating temporary directories and temporarily changing the working directory\n * for use in tests.\n */\n\n#pragma once\n\n#include <boost/filesystem.hpp>\n\n#include <string>\n#include <vector>\n\nnamespace solidity::util\n{\n\n/**\n * An object that creates a unique temporary directory and automatically deletes it and its\n * content upon being destroyed.\n *\n * The directory is guaranteed to be newly created and empty. Directory names are generated\n * randomly. If a directory with the same name already exists (very unlikely but possible) the\n * object won't reuse it and will fail with an exception instead.\n */\nclass TemporaryDirectory\n{\npublic:\n\tTemporaryDirectory(std::string const& _prefix = \"solidity\");\n\tTemporaryDirectory(\n\t\tstd::vector<boost::filesystem::path> const& _subdirectories,\n\t\tstd::string const& _prefix = \"solidity\"\n\t);\n\t~TemporaryDirectory();\n\n\tboost::filesystem::path const& path() const { return m_path; }\n\toperator boost::filesystem::path() const { return m_path; }\n\nprivate:\n\tboost::filesystem::path m_path;\n};\n\n/**\n * An object that changes current working directory and restores it upon destruction.\n */\nclass TemporaryWorkingDirectory\n{\npublic:\n\tTemporaryWorkingDirectory(boost::filesystem::path const& _newDirectory);\n\t~TemporaryWorkingDirectory();\n\n\tboost::filesystem::path const& originalWorkingDirectory() const { return m_originalWorkingDirectory; }\n\toperator boost::filesystem::path() const { return boost::filesystem::current_path(); }\n\nprivate:\n\tboost::filesystem::path m_originalWorkingDirectory;\n};\n\n}\n"
  },
  {
    "path": "libsolutil/UTF8.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file UTF8.cpp\n * @author Alex Beregszaszi\n * @date 2016\n *\n * UTF-8 related helpers\n */\n\n#include <libsolutil/UTF8.h>\n\nnamespace solidity::util\n{\nnamespace\n{\n\n/// Validate byte sequence against Unicode chapter 3 Table 3-7.\nbool isWellFormed(unsigned char byte1, unsigned char byte2)\n{\n\tif (byte1 == 0xc0 || byte1 == 0xc1)\n\t\treturn false;\n\telse if (byte1 >= 0xc2 && byte1 <= 0xdf)\n\t\treturn true;\n\telse if (byte1 == 0xe0)\n\t{\n\t\tif (byte2 < 0xa0)\n\t\t\treturn false;\n\t\telse\n\t\t\treturn true;\n\t}\n\telse if (byte1 >= 0xe1 && byte1 <= 0xec)\n\t\treturn true;\n\telse if (byte1 == 0xed)\n\t{\n\t\tif (byte2 > 0x9f)\n\t\t\treturn false;\n\t\telse\n\t\t\treturn true;\n\t}\n\telse if (byte1 == 0xee || byte1 == 0xef)\n\t\treturn true;\n\telse if (byte1 == 0xf0)\n\t{\n\t\tif (byte2 < 0x90)\n\t\t\treturn false;\n\t\telse\n\t\t\treturn true;\n\t}\n\telse if (byte1 >= 0xf1 && byte1 <= 0xf3)\n\t\treturn true;\n\telse if (byte1 == 0xf4)\n\t{\n\t\tif (byte2 > 0x8f)\n\t\t\treturn false;\n\t\telse\n\t\t\treturn true;\n\t}\n\t/// 0xf5 .. 0xf7 is disallowed\n\t/// Technically anything below 0xc0 or above 0xf7 is\n\t/// not possible to encode using Table 3-6 anyway.\n\treturn false;\n}\n\nbool validateUTF8(unsigned char const* _input, size_t _length, size_t& _invalidPosition)\n{\n\tbool valid = true;\n\tsize_t i = 0;\n\n\tfor (; i < _length; i++)\n\t{\n\t\t// Check for Unicode Chapter 3 Table 3-6 conformity.\n\t\tif (_input[i] < 0x80)\n\t\t\tcontinue;\n\n\t\tsize_t count = 0;\n\t\tif (_input[i] >= 0xc0 && _input[i] <= 0xdf)\n\t\t\tcount = 1;\n\t\telse if (_input[i] >= 0xe0 && _input[i] <= 0xef)\n\t\t\tcount = 2;\n\t\telse if (_input[i] >= 0xf0 && _input[i] <= 0xf7)\n\t\t\tcount = 3;\n\n\t\tif (count == 0)\n\t\t{\n\t\t\tvalid = false;\n\t\t\tbreak;\n\t\t}\n\n\t\tif ((i + count) >= _length)\n\t\t{\n\t\t\tvalid = false;\n\t\t\tbreak;\n\t\t}\n\n\t\tfor (size_t j = 0; j < count; j++)\n\t\t{\n\t\t\ti++;\n\t\t\tif ((_input[i] & 0xc0) != 0x80)\n\t\t\t{\n\t\t\t\tvalid = false;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Check for Unicode Chapter 3 Table 3-7 conformity.\n\t\t\tif ((j == 0) && !isWellFormed(_input[i - 1], _input[i]))\n\t\t\t{\n\t\t\t\tvalid = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (valid)\n\t\treturn true;\n\n\t_invalidPosition = i;\n\treturn false;\n}\n\n}\n\nbool validateUTF8(std::string const& _input, size_t& _invalidPosition)\n{\n\treturn validateUTF8(reinterpret_cast<unsigned char const*>(_input.c_str()), _input.length(), _invalidPosition);\n}\n\n}\n"
  },
  {
    "path": "libsolutil/UTF8.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file UTF8.h\n * @author Alex Beregszaszi\n * @date 2016\n *\n * UTF-8 related helpers\n */\n\n#pragma once\n\n#include <string>\n\nnamespace solidity::util\n{\n\n/// Validate an input for UTF8 encoding\n/// @returns false if it is invalid and the first invalid position in invalidPosition\nbool validateUTF8(std::string const& _input, size_t& _invalidPosition);\n\ninline bool validateUTF8(std::string const& _input)\n{\n\tsize_t invalidPos;\n\treturn validateUTF8(_input, invalidPos);\n}\n\n}\n"
  },
  {
    "path": "libsolutil/Views.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <range/v3/view/transform.hpp>\n\n#include <liblangutil/Exceptions.h>\n\n\nnamespace solidity::util::views\n{\n\nstatic constexpr auto dereference = ranges::views::transform([](auto&& x) -> decltype(auto) { return *x; });\n\nstatic constexpr auto dereferenceChecked = ranges::views::transform(\n\t[](auto&& x) -> decltype(auto)\n\t{\n\t\tsolAssert(x, \"\");\n\t\treturn *x;\n\t}\n);\n\n}\n"
  },
  {
    "path": "libsolutil/Visitor.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Visitor templates.\n */\n\n#pragma once\n\nnamespace solidity::util\n{\n\n/**\n * Generic visitor used as follows:\n * std::visit(GenericVisitor{\n *     [](Class1& _c) { _c.f(); },\n *     [](Class2& _c) { _c.g(); }\n * }, variant);\n * This one does not have a fallback and will fail at\n * compile-time if you do not specify all variants.\n *\n * Fallback with no return (it will not fail if you do not specify all variants):\n * std::visit(GenericVisitor{\n *     VisitorFallback<>{},\n *     [](Class1& _c) { _c.f(); },\n *     [](Class2& _c) { _c.g(); }\n * }, variant);\n *\n * Fallback with return type R (the fallback returns `R{}`:\n * std::visit(GenericVisitor{\n *     VisitorFallback<R>{},\n *     [](Class1& _c) { _c.f(); },\n *     [](Class2& _c) { _c.g(); }\n * }, variant);\n */\n\ntemplate <typename...> struct VisitorFallback;\n\ntemplate <typename R>\nstruct VisitorFallback<R> { template<typename T> R operator()(T&&) const { return {}; } };\n\ntemplate<>\nstruct VisitorFallback<> { template<typename T> void operator()(T&&) const {} };\n\n// MSVC. Empty base class optimization does not happen in some scenarios.\n// Enforcing it with __declspec(empty_bases) avoids MSVC Debug test crash\n// (Run-Time Check Failure #2 - Stack around the variable '....' was corrupted).\n// See https://docs.microsoft.com/en-us/cpp/cpp/empty-bases,\n//     https://developercommunity.visualstudio.com/t/10005513.\n#if defined(_MSC_VER)\n#define SOLC_EMPTY_BASES __declspec(empty_bases)\n#else\n#define SOLC_EMPTY_BASES\n#endif\n\ntemplate <typename... Visitors> struct SOLC_EMPTY_BASES GenericVisitor: Visitors... { using Visitors::operator()...; };\ntemplate <typename... Visitors> GenericVisitor(Visitors...) -> GenericVisitor<Visitors...>;\n}\n"
  },
  {
    "path": "libsolutil/Whiskers.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file Whiskers.cpp\n * @author Chris <chis@ethereum.org>\n * @date 2017\n *\n * Moustache-like templates.\n */\n\n#include <libsolutil/Whiskers.h>\n\n#include <libsolutil/Assertions.h>\n\n#include <regex>\n\nusing namespace solidity::util;\n\nWhiskers::Whiskers(std::string _template):\n\tm_template(std::move(_template))\n{\n\tcheckTemplateValid();\n}\n\nWhiskers& Whiskers::operator()(std::string _parameter, std::string _value)\n{\n\tcheckParameterValid(_parameter);\n\tcheckParameterUnknown(_parameter);\n\tcheckTemplateContainsTags(_parameter, {\"\"});\n\tm_parameters[std::move(_parameter)] = std::move(_value);\n\treturn *this;\n}\n\nWhiskers& Whiskers::operator()(std::string _parameter, bool _value)\n{\n\tcheckParameterValid(_parameter);\n\tcheckParameterUnknown(_parameter);\n\tcheckTemplateContainsTags(_parameter, {\"?\", \"/\"});\n\tm_conditions[std::move(_parameter)] = _value;\n\treturn *this;\n}\n\nWhiskers& Whiskers::operator()(\n\tstd::string _listParameter,\n\tstd::vector<std::map<std::string, std::string>> _values\n)\n{\n\tcheckParameterValid(_listParameter);\n\tcheckParameterUnknown(_listParameter);\n\tcheckTemplateContainsTags(_listParameter, {\"#\", \"/\"});\n\tfor (auto const& element: _values)\n\t\tfor (auto const& val: element)\n\t\t\tcheckParameterValid(val.first);\n\tm_listParameters[std::move(_listParameter)] = std::move(_values);\n\treturn *this;\n}\n\nstd::string Whiskers::render() const\n{\n\treturn replace(m_template, m_parameters, m_conditions, m_listParameters);\n}\n\nvoid Whiskers::checkTemplateValid() const\n{\n\tstd::regex validTemplate(\"<[#?!\\\\/]\\\\+{0,1}[a-zA-Z0-9_$-]+(?:[^a-zA-Z0-9_$>-]|$)\");\n\tstd::smatch match;\n\tassertThrow(\n\t\t!regex_search(m_template, match, validTemplate),\n\t\tWhiskersError,\n\t\t\"Template contains an invalid/unclosed tag \" + match.str()\n\t);\n}\n\nvoid Whiskers::checkParameterValid(std::string const& _parameter) const\n{\n\tstatic std::regex validParam(\"^\" + paramRegex() + \"$\");\n\tassertThrow(\n\t\tregex_match(_parameter, validParam),\n\t\tWhiskersError,\n\t\t\"Parameter\" + _parameter + \" contains invalid characters.\"\n\t);\n}\n\nvoid Whiskers::checkParameterUnknown(std::string const& _parameter) const\n{\n\tassertThrow(\n\t\t!m_parameters.count(_parameter),\n\t\tWhiskersError,\n\t\t_parameter + \" already set as value parameter.\"\n\t);\n\tassertThrow(\n\t\t!m_conditions.count(_parameter),\n\t\tWhiskersError,\n\t\t_parameter + \" already set as condition parameter.\"\n\t);\n\tassertThrow(\n\t\t!m_listParameters.count(_parameter),\n\t\tWhiskersError,\n\t\t_parameter + \" already set as list parameter.\"\n\t);\n}\n\nvoid Whiskers::checkTemplateContainsTags(std::string const& _parameter, std::vector<std::string> const& _prefixes) const\n{\n\tfor (auto const& prefix: _prefixes)\n\t{\n\t\tstd::string tag{\"<\" + prefix + _parameter + \">\"};\n\t\tassertThrow(\n\t\t\tm_template.find(tag) != std::string::npos,\n\t\t\tWhiskersError,\n\t\t\t\"Tag '\" + tag + \"' not found in template:\\n\" + m_template\n\t\t);\n\t}\n}\n\nnamespace\n{\ntemplate<class ReplaceCallback>\nstd::string regex_replace(\n\tstd::string const& _source,\n\tstd::regex const& _pattern,\n\tReplaceCallback _replace,\n\tstd::regex_constants::match_flag_type _flags = std::regex_constants::match_default\n)\n{\n\tstd::sregex_iterator curMatch(_source.begin(), _source.end(), _pattern, _flags);\n\tstd::sregex_iterator matchEnd;\n\tstd::string::const_iterator lastMatchedPos(_source.cbegin());\n\tstd::string result;\n\twhile (curMatch != matchEnd)\n\t{\n\t\tresult.append(curMatch->prefix().first, curMatch->prefix().second);\n\t\tresult.append(_replace(*curMatch));\n\t\tlastMatchedPos = (*curMatch)[0].second;\n\t\t++curMatch;\n\t}\n\tresult.append(lastMatchedPos, _source.cend());\n\treturn result;\n}\n}\n\nstd::string Whiskers::replace(\n\tstd::string const& _template,\n\tStringMap const& _parameters,\n\tstd::map<std::string, bool> const& _conditions,\n\tstd::map<std::string, std::vector<StringMap>> const& _listParameters\n)\n{\n\tstatic std::regex listOrTag(\n\t\t\"<(\" + paramRegex() + \")>|\"\n\t\t\"<#(\" + paramRegex() + \")>((?:.|\\\\r|\\\\n)*?)</\\\\2>|\"\n\t\t\"<\\\\?(\\\\+?\" + paramRegex() + \")>((?:.|\\\\r|\\\\n)*?)(<!\\\\4>((?:.|\\\\r|\\\\n)*?))?</\\\\4>\"\n\t);\n\treturn regex_replace(_template, listOrTag, [&](std::match_results<std::string::const_iterator> _match) -> std::string\n\t{\n\t\tstd::string tagName(_match[1]);\n\t\tstd::string listName(_match[2]);\n\t\tstd::string conditionName(_match[4]);\n\t\tif (!tagName.empty())\n\t\t{\n\t\t\tassertThrow(\n\t\t\t\t_parameters.count(tagName),\n\t\t\t\tWhiskersError,\n\t\t\t\t\"Value for tag \" + tagName + \" not provided.\\n\" +\n\t\t\t\t\"Template:\\n\" +\n\t\t\t\t_template\n\t\t\t);\n\t\t\treturn _parameters.at(tagName);\n\t\t}\n\t\telse if (!listName.empty())\n\t\t{\n\t\t\tstd::string templ(_match[3]);\n\t\t\tassertThrow(\n\t\t\t\t_listParameters.count(listName),\n\t\t\t\tWhiskersError, \"List parameter \" + listName + \" not set.\"\n\t\t\t);\n\t\t\tstd::string replacement;\n\t\t\tfor (auto const& parameters: _listParameters.at(listName))\n\t\t\t\treplacement += replace(templ, joinMaps(_parameters, parameters), _conditions);\n\t\t\treturn replacement;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tassertThrow(!conditionName.empty(), WhiskersError, \"\");\n\t\t\tbool conditionValue = false;\n\t\t\tif (conditionName[0] == '+')\n\t\t\t{\n\t\t\t\tstd::string tag = conditionName.substr(1);\n\n\t\t\t\tif (_parameters.count(tag))\n\t\t\t\t\tconditionValue = !_parameters.at(tag).empty();\n\t\t\t\telse if (_listParameters.count(tag))\n\t\t\t\t\tconditionValue = !_listParameters.at(tag).empty();\n\t\t\t\telse\n\t\t\t\t\tassertThrow(false, WhiskersError, \"Tag \" + tag + \" used as condition but was not set.\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tassertThrow(\n\t\t\t\t\t_conditions.count(conditionName),\n\t\t\t\t\tWhiskersError, \"Condition parameter \" + conditionName + \" not set.\"\n\t\t\t\t);\n\t\t\t\tconditionValue = _conditions.at(conditionName);\n\t\t\t}\n\t\t\treturn replace(\n\t\t\t\tconditionValue ? _match[5] : _match[7],\n\t\t\t\t_parameters,\n\t\t\t\t_conditions,\n\t\t\t\t_listParameters\n\t\t\t);\n\t\t}\n\t});\n}\n\nWhiskers::StringMap Whiskers::joinMaps(\n\tWhiskers::StringMap const& _a,\n\tWhiskers::StringMap const& _b\n)\n{\n\tWhiskers::StringMap ret = _a;\n\tfor (auto const& x: _b)\n\t\tassertThrow(\n\t\t\tret.insert(x).second,\n\t\t\tWhiskersError,\n\t\t\t\"Parameter collision\"\n\t\t);\n\treturn ret;\n}\n\n"
  },
  {
    "path": "libsolutil/Whiskers.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file Whiskers.h\n * @author Chris <chis@ethereum.org>\n * @date 2017\n *\n * Moustache-like templates.\n */\n\n#pragma once\n\n#include <libsolutil/Exceptions.h>\n\n#include <string>\n#include <map>\n#include <vector>\n\nnamespace solidity::util\n{\n\nDEV_SIMPLE_EXCEPTION(WhiskersError);\n\n/**\n * Moustache-like templates.\n *\n * Usage:\n *     std::vector<std::map<std::string, std::string>> listValues(2);\n *     listValues[0][\"k\"] = \"key1\";\n *     listValues[0][\"v\"] = \"value1\";\n *     listValues[1][\"k\"] = \"key2\";\n *     listValues[1][\"v\"] = \"value2\";\n *     auto s = Whiskers(\"<?c><p1><!c>y</c>\\n<#list><k> -> <v>\\n</list>\")\n *         (\"p1\", \"HEAD\")\n *         (\"c\", true)\n *         (\"list\", listValues)\n *         .render();\n *\n * results in s == \"HEAD\\nkey1 -> value1\\nkey2 -> value2\\n\"\n *\n * Note that lists cannot themselves contain lists - this would be a future feature.\n *\n * The elements are:\n *  - Regular parameter: <name>\n *    just replaced\n *  - Condition parameter: <?name>...<!name>...</name>, where \"<!name>\" is optional\n *    replaced (and recursively expanded) by the first part if the condition is true\n *    and by the second (or empty string if missing) if the condition is false\n *  - List parameter: <#list>...</list>\n *    The part between the tags is repeated as often as values are provided\n *    in the mapping. Each list element can have its own parameter -> value mapping.\n *  - Conditional value parameter: <?+name>...<!+name>...</+name>\n *    Works similar to a conditional parameter where the checked condition is\n *    that the string or list parameter called \"name\" is non-empty or contains\n *    no elements respectively.\n */\nclass Whiskers\n{\npublic:\n\tusing StringMap = std::map<std::string, std::string>;\n\tusing StringListMap = std::map<std::string, std::vector<StringMap>>;\n\n\texplicit Whiskers(std::string _template = \"\");\n\n\t/// Sets a single regular parameter, <paramName>.\n\tWhiskers& operator()(std::string _parameter, std::string _value);\n\tWhiskers& operator()(std::string _parameter, char const* _value) { return (*this)(_parameter, std::string{_value}); }\n\t/// Sets a condition parameter, <?paramName>...<!paramName>...</paramName>\n\tWhiskers& operator()(std::string _parameter, bool _value);\n\t/// Sets a list parameter, <#listName> </listName>.\n\tWhiskers& operator()(\n\t\tstd::string _listParameter,\n\t\tstd::vector<StringMap> _values\n\t);\n\n\tstd::string render() const;\n\nprivate:\n\t// Prevent implicit cast to bool\n\tWhiskers& operator()(std::string _parameter, long long);\n\tvoid checkTemplateValid() const;\n\tvoid checkParameterValid(std::string const& _parameter) const;\n\tvoid checkParameterUnknown(std::string const& _parameter) const;\n\n\t/// Checks whether the string stored in `m_template` contains all the tags specified.\n\t/// @param _parameter name of the parameter. This name is used to construct the tag(s).\n\t/// @param _prefixes a vector of strings, where each element is used to compose the tag\n\t///        like `\"<\" + element + _parameter + \">\"`. Each element of _prefixes is used as a prefix of the tag name.\n\tvoid checkTemplateContainsTags(std::string const& _parameter, std::vector<std::string> const& _prefixes) const;\n\n\tstatic std::string replace(\n\t\tstd::string const& _template,\n\t\tStringMap const& _parameters,\n\t\tstd::map<std::string, bool> const& _conditions,\n\t\tStringListMap const& _listParameters = StringListMap()\n\t);\n\n\tstatic std::string paramRegex() { return \"[a-zA-Z0-9_$-]+\"; }\n\n\t/// Joins the two maps throwing an exception if two keys are equal.\n\tstatic StringMap joinMaps(StringMap const& _a, StringMap const& _b);\n\n\tstd::string m_template;\n\tStringMap m_parameters;\n\tstd::map<std::string, bool> m_conditions;\n\tStringListMap m_listParameters;\n};\n\n}\n"
  },
  {
    "path": "libsolutil/picosha2.h",
    "content": "/*\nThe MIT License (MIT)\n\nCopyright (C) 2017 okdshin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n*/\n#ifndef PICOSHA2_H\n#define PICOSHA2_H\n// picosha2:20140213\n\n#ifndef PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR\n#define PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR \\\n    1048576  //=1024*1024: default is 1MB memory\n#endif\n\n#include <algorithm>\n#include <cassert>\n#include <iterator>\n#include <sstream>\n#include <vector>\n#include <fstream>\nnamespace picosha2 {\ntypedef unsigned long word_t;\ntypedef unsigned char byte_t;\n\nstatic const size_t k_digest_size = 32;\n\nnamespace detail {\ninline byte_t mask_8bit(byte_t x) { return x & 0xff; }\n\ninline word_t mask_32bit(word_t x) { return x & 0xffffffff; }\n\nconst word_t add_constant[64] = {\n    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,\n    0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,\n    0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,\n    0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,\n    0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,\n    0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};\n\nconst word_t initial_message_digest[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372,\n                                          0xa54ff53a, 0x510e527f, 0x9b05688c,\n                                          0x1f83d9ab, 0x5be0cd19};\n\ninline word_t ch(word_t x, word_t y, word_t z) { return (x & y) ^ ((~x) & z); }\n\ninline word_t maj(word_t x, word_t y, word_t z) {\n    return (x & y) ^ (x & z) ^ (y & z);\n}\n\ninline word_t rotr(word_t x, std::size_t n) {\n    assert(n < 32);\n    return mask_32bit((x >> n) | (x << (32 - n)));\n}\n\ninline word_t bsig0(word_t x) { return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22); }\n\ninline word_t bsig1(word_t x) { return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25); }\n\ninline word_t shr(word_t x, std::size_t n) {\n    assert(n < 32);\n    return x >> n;\n}\n\ninline word_t ssig0(word_t x) { return rotr(x, 7) ^ rotr(x, 18) ^ shr(x, 3); }\n\ninline word_t ssig1(word_t x) { return rotr(x, 17) ^ rotr(x, 19) ^ shr(x, 10); }\n\ntemplate <typename RaIter1, typename RaIter2>\nvoid hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last) {\n    assert(first + 64 == last);\n    static_cast<void>(last);  // for avoiding unused-variable warning\n    word_t w[64];\n    std::fill(w, w + 64, 0);\n    for (std::size_t i = 0; i < 16; ++i) {\n        w[i] = (static_cast<word_t>(mask_8bit(*(first + long(i) * 4))) << 24) |\n               (static_cast<word_t>(mask_8bit(*(first + long(i) * 4 + 1))) << 16) |\n               (static_cast<word_t>(mask_8bit(*(first + long(i) * 4 + 2))) << 8) |\n               (static_cast<word_t>(mask_8bit(*(first + long(i) * 4 + 3))));\n    }\n    for (std::size_t i = 16; i < 64; ++i) {\n        w[i] = mask_32bit(ssig1(w[i - 2]) + w[i - 7] + ssig0(w[i - 15]) +\n                          w[i - 16]);\n    }\n\n    word_t a = *message_digest;\n    word_t b = *(message_digest + 1);\n    word_t c = *(message_digest + 2);\n    word_t d = *(message_digest + 3);\n    word_t e = *(message_digest + 4);\n    word_t f = *(message_digest + 5);\n    word_t g = *(message_digest + 6);\n    word_t h = *(message_digest + 7);\n\n    for (std::size_t i = 0; i < 64; ++i) {\n        word_t temp1 = h + bsig1(e) + ch(e, f, g) + add_constant[i] + w[i];\n        word_t temp2 = bsig0(a) + maj(a, b, c);\n        h = g;\n        g = f;\n        f = e;\n        e = mask_32bit(d + temp1);\n        d = c;\n        c = b;\n        b = a;\n        a = mask_32bit(temp1 + temp2);\n    }\n    *message_digest += a;\n    *(message_digest + 1) += b;\n    *(message_digest + 2) += c;\n    *(message_digest + 3) += d;\n    *(message_digest + 4) += e;\n    *(message_digest + 5) += f;\n    *(message_digest + 6) += g;\n    *(message_digest + 7) += h;\n    for (std::size_t i = 0; i < 8; ++i) {\n        *(message_digest + i) = mask_32bit(*(message_digest + i));\n    }\n}\n\n}  // namespace detail\n\ntemplate <typename InIter>\nvoid output_hex(InIter first, InIter last, std::ostream& os) {\n    os.setf(std::ios::hex, std::ios::basefield);\n    while (first != last) {\n        os.width(2);\n        os.fill('0');\n        os << static_cast<unsigned int>(*first);\n        ++first;\n    }\n    os.setf(std::ios::dec, std::ios::basefield);\n}\n\ntemplate <typename InIter>\nvoid bytes_to_hex_string(InIter first, InIter last, std::string& hex_str) {\n    std::ostringstream oss;\n    output_hex(first, last, oss);\n    hex_str.assign(oss.str());\n}\n\ntemplate <typename InContainer>\nvoid bytes_to_hex_string(const InContainer& bytes, std::string& hex_str) {\n    bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str);\n}\n\ntemplate <typename InIter>\nstd::string bytes_to_hex_string(InIter first, InIter last) {\n    std::string hex_str;\n    bytes_to_hex_string(first, last, hex_str);\n    return hex_str;\n}\n\ntemplate <typename InContainer>\nstd::string bytes_to_hex_string(const InContainer& bytes) {\n    std::string hex_str;\n    bytes_to_hex_string(bytes, hex_str);\n    return hex_str;\n}\n\nclass hash256_one_by_one {\n   public:\n    hash256_one_by_one() { init(); }\n\n    void init() {\n        buffer_.clear();\n        std::fill(data_length_digits_, data_length_digits_ + 4, 0);\n        std::copy(detail::initial_message_digest,\n                  detail::initial_message_digest + 8, h_);\n    }\n\n    template <typename RaIter>\n    void process(RaIter first, RaIter last) {\n        add_to_data_length(static_cast<word_t>(std::distance(first, last)));\n        std::copy(first, last, std::back_inserter(buffer_));\n        std::size_t i = 0;\n        for (; i + 64 <= buffer_.size(); i += 64) {\n            detail::hash256_block(h_, buffer_.begin() + long(i),\n                                  buffer_.begin() + long(i) + 64);\n        }\n        buffer_.erase(buffer_.begin(), buffer_.begin() + long(i));\n    }\n\n    void finish() {\n        byte_t temp[64];\n        std::fill(temp, temp + 64, 0);\n        std::size_t remains = buffer_.size();\n        std::copy(buffer_.begin(), buffer_.end(), temp);\n        temp[remains] = 0x80;\n\n        if (remains > 55) {\n            std::fill(temp + remains + 1, temp + 64, 0);\n            detail::hash256_block(h_, temp, temp + 64);\n            std::fill(temp, temp + 64 - 4, 0);\n        } else {\n            std::fill(temp + remains + 1, temp + 64 - 4, 0);\n        }\n\n        write_data_bit_length(&(temp[56]));\n        detail::hash256_block(h_, temp, temp + 64);\n    }\n\n    template <typename OutIter>\n    void get_hash_bytes(OutIter first, OutIter last) const {\n        for (const word_t* iter = h_; iter != h_ + 8; ++iter) {\n            for (std::size_t i = 0; i < 4 && first != last; ++i) {\n                *(first++) = detail::mask_8bit(\n                    static_cast<byte_t>((*iter >> (24 - 8 * i))));\n            }\n        }\n    }\n\n   private:\n    void add_to_data_length(word_t n) {\n        word_t carry = 0;\n        data_length_digits_[0] += n;\n        for (std::size_t i = 0; i < 4; ++i) {\n            data_length_digits_[i] += carry;\n            if (data_length_digits_[i] >= 65536u) {\n                carry = data_length_digits_[i] >> 16;\n                data_length_digits_[i] &= 65535u;\n            } else {\n                break;\n            }\n        }\n    }\n    void write_data_bit_length(byte_t* begin) {\n        word_t data_bit_length_digits[4];\n        std::copy(data_length_digits_, data_length_digits_ + 4,\n                  data_bit_length_digits);\n\n        // convert byte length to bit length (multiply 8 or shift 3 times left)\n        word_t carry = 0;\n        for (std::size_t i = 0; i < 4; ++i) {\n            word_t before_val = data_bit_length_digits[i];\n            data_bit_length_digits[i] <<= 3;\n            data_bit_length_digits[i] |= carry;\n            data_bit_length_digits[i] &= 65535u;\n            carry = (before_val >> (16 - 3)) & 65535u;\n        }\n\n        // write data_bit_length\n        for (int i = 3; i >= 0; --i) {\n            (*begin++) = static_cast<byte_t>(data_bit_length_digits[i] >> 8);\n            (*begin++) = static_cast<byte_t>(data_bit_length_digits[i]);\n        }\n    }\n    std::vector<byte_t> buffer_;\n    word_t data_length_digits_[4];  // as 64bit integer (16bit x 4 integer)\n    word_t h_[8];\n};\n\ninline void get_hash_hex_string(const hash256_one_by_one& hasher,\n                                std::string& hex_str) {\n    byte_t hash[k_digest_size];\n    hasher.get_hash_bytes(hash, hash + k_digest_size);\n    return bytes_to_hex_string(hash, hash + k_digest_size, hex_str);\n}\n\ninline std::string get_hash_hex_string(const hash256_one_by_one& hasher) {\n    std::string hex_str;\n    get_hash_hex_string(hasher, hex_str);\n    return hex_str;\n}\n\nnamespace impl {\ntemplate <typename RaIter, typename OutIter>\nvoid hash256_impl(RaIter first, RaIter last, OutIter first2, OutIter last2, int,\n                  std::random_access_iterator_tag) {\n    hash256_one_by_one hasher;\n    // hasher.init();\n    hasher.process(first, last);\n    hasher.finish();\n    hasher.get_hash_bytes(first2, last2);\n}\n\ntemplate <typename InputIter, typename OutIter>\nvoid hash256_impl(InputIter first, InputIter last, OutIter first2,\n                  OutIter last2, size_t buffer_size, std::input_iterator_tag) {\n    std::vector<byte_t> buffer(buffer_size);\n    hash256_one_by_one hasher;\n    // hasher.init();\n    while (first != last) {\n        size_t size = buffer_size;\n        for (size_t i = 0; i != buffer_size; ++i, ++first) {\n            if (first == last) {\n                size = i;\n                break;\n            }\n            buffer[i] = *first;\n        }\n        hasher.process(buffer.begin(), buffer.begin() + ptrdiff_t(size));\n    }\n    hasher.finish();\n    hasher.get_hash_bytes(first2, last2);\n}\n}\n\ntemplate <typename InIter, typename OutIter>\nvoid hash256(InIter first, InIter last, OutIter first2, OutIter last2,\n             int buffer_size = PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR) {\n    picosha2::impl::hash256_impl(\n        first, last, first2, last2, buffer_size,\n        typename std::iterator_traits<InIter>::iterator_category());\n}\n\ntemplate <typename InIter, typename OutContainer>\nvoid hash256(InIter first, InIter last, OutContainer& dst) {\n    hash256(first, last, dst.begin(), dst.end());\n}\n\ntemplate <typename InContainer, typename OutIter>\nvoid hash256(const InContainer& src, OutIter first, OutIter last) {\n    hash256(src.begin(), src.end(), first, last);\n}\n\ntemplate <typename InContainer, typename OutContainer>\nvoid hash256(const InContainer& src, OutContainer& dst) {\n    hash256(src.begin(), src.end(), dst.begin(), dst.end());\n}\n\ntemplate <typename InIter>\nvoid hash256_hex_string(InIter first, InIter last, std::string& hex_str) {\n    byte_t hashed[k_digest_size];\n    hash256(first, last, hashed, hashed + k_digest_size);\n    std::ostringstream oss;\n    output_hex(hashed, hashed + k_digest_size, oss);\n    hex_str.assign(oss.str());\n}\n\ntemplate <typename RaContainer>\nstd::vector<uint8_t> hash256(RaContainer const& _src)\n{\n       std::vector<uint8_t> ret(32);\n       hash256(_src.begin(), _src.end(), ret.begin(), ret.end());\n       return ret;\n}\n\ntemplate <typename InIter>\nstd::string hash256_hex_string(InIter first, InIter last) {\n    std::string hex_str;\n    hash256_hex_string(first, last, hex_str);\n    return hex_str;\n}\n\ninline void hash256_hex_string(const std::string& src, std::string& hex_str) {\n    hash256_hex_string(src.begin(), src.end(), hex_str);\n}\n\ntemplate <typename InContainer>\nvoid hash256_hex_string(const InContainer& src, std::string& hex_str) {\n    hash256_hex_string(src.begin(), src.end(), hex_str);\n}\n\ntemplate <typename InContainer>\nstd::string hash256_hex_string(const InContainer& src) {\n    return hash256_hex_string(src.begin(), src.end());\n}\ntemplate<typename OutIter>void hash256(std::ifstream& f, OutIter first, OutIter last){\n    hash256(std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>(), first,last);\n\n}\n}// namespace picosha2\n#endif  // PICOSHA2_H\n"
  },
  {
    "path": "libsolutil/vector_ref.h",
    "content": "#pragma once\n\n#include <cstring>\n#include <cassert>\n#include <type_traits>\n#include <vector>\n#include <string>\n\n#ifdef __INTEL_COMPILER\n#pragma warning(disable:597) // will not be called for implicit or explicit conversions\n#endif\n\nnamespace solidity::util\n{\n\n/**\n * A modifiable reference to an existing object or vector in memory.\n */\ntemplate <class T>\nclass vector_ref\n{\npublic:\n\tusing value_type = T;\n\tusing element_type = T;\n\tusing mutable_value_type = typename std::conditional<std::is_const<T>::value, typename std::remove_const<T>::type, T>::type;\n\tusing string_type = typename std::conditional<std::is_const<T>::value, std::string const, std::string>::type;\n\tusing vector_type = typename std::conditional<std::is_const<T>::value, std::vector<typename std::remove_const<T>::type> const, std::vector<T>>::type;\n\tusing iterator = T*;\n\tusing const_iterator = T const*;\n\n\tstatic_assert(std::is_standard_layout_v<value_type> && std::is_trivial_v<value_type>, \"vector_ref can only be used with PODs due to its low-level treatment of data.\");\n\n\tvector_ref(): m_data(nullptr), m_count(0) {}\n\t/// Creates a new vector_ref to point to @a _count elements starting at @a _data.\n\tvector_ref(T* _data, size_t _count): m_data(_data), m_count(_count) {}\n\t/// Creates a new vector_ref pointing to the data part of a string (given as pointer).\n\tvector_ref(string_type* _data): m_data(reinterpret_cast<T*>(_data->data())), m_count(_data->size() / sizeof(T)) {}\n\t/// Creates a new vector_ref pointing to the data part of a string (given as reference).\n\tvector_ref(string_type& _data): vector_ref(&_data) {}\n\t/// Creates a new vector_ref pointing to the data part of a vector (given as pointer).\n\tvector_ref(vector_type* _data): m_data(_data->data()), m_count(_data->size()) {}\n\texplicit operator bool() const { return m_data && m_count; }\n\n\tstd::vector<unsigned char> toBytes() const { return std::vector<unsigned char>(reinterpret_cast<unsigned char const*>(m_data), reinterpret_cast<unsigned char const*>(m_data) + m_count * sizeof(T)); }\n\tstd::string toString() const { return std::string((char const*)m_data, ((char const*)m_data) + m_count * sizeof(T)); }\n\n\toperator vector_ref<T const>() const { return vector_ref<T const>(m_data, m_count); }\n\n\tT* data() const { return m_data; }\n\t/// @returns the number of elements referenced (not necessarily number of bytes).\n\tsize_t size() const { return m_count; }\n\tbool empty() const { return !m_count; }\n\t/// @returns a new vector_ref which is a shifted and shortened view of the original data.\n\t/// If this goes out of bounds in any way, returns an empty vector_ref.\n\t/// If @a _count is ~size_t(0), extends the view to the end of the data.\n\tvector_ref<T> cropped(size_t _begin, size_t _count) const { if (m_data && _begin <= m_count && _count <= m_count && _begin + _count <= m_count) return vector_ref<T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<T>(); }\n\t/// @returns a new vector_ref which is a shifted view of the original data (not going beyond it).\n\tvector_ref<T> cropped(size_t _begin) const { if (m_data && _begin <= m_count) return vector_ref<T>(m_data + _begin, m_count - _begin); else return vector_ref<T>(); }\n\n\tT* begin() { return m_data; }\n\tT* end() { return m_data + m_count; }\n\tT const* begin() const { return m_data; }\n\tT const* end() const { return m_data + m_count; }\n\n\tT& operator[](size_t _i) { assert(m_data); assert(_i < m_count); return m_data[_i]; }\n\tT const& operator[](size_t _i) const { assert(m_data); assert(_i < m_count); return m_data[_i]; }\n\n\tbool operator==(vector_ref<T> const& _cmp) const { return m_data == _cmp.m_data && m_count == _cmp.m_count; }\n\tbool operator!=(vector_ref<T> const& _cmp) const { return !operator==(_cmp); }\n\n\tvoid reset() { m_data = nullptr; m_count = 0; }\n\nprivate:\n\tT* m_data = nullptr;\n\tsize_t m_count = 0;\n};\n\n}\n"
  },
  {
    "path": "libstdlib/CMakeLists.txt",
    "content": "# This will re-generate the headers if any file within src was modified.\nset_directory_properties(PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/)\n\nset(STDLIB stub)\nset(GENERATED_STDLIB_HEADERS)\nforeach(src IN LISTS STDLIB)\n    set(STDLIB_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/${src}.sol)\n    file(READ ${STDLIB_FILE} STDLIB_FILE_CONTENT HEX)\n    string(REGEX MATCHALL \"..\" STDLIB_FILE_CONTENT \"${STDLIB_FILE_CONTENT}\")\n    list(REMOVE_ITEM STDLIB_FILE_CONTENT \"0d\")\n    string(REGEX REPLACE \";\" \",\\n\\t0x\" STDLIB_FILE_CONTENT \"${STDLIB_FILE_CONTENT}\")\n    set(STDLIB_FILE_CONTENT \"0x${STDLIB_FILE_CONTENT}\")\n    set(STDLIB_FILE_NAME ${src})\n    configure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/stdlib.src.h.in\" ${PROJECT_BINARY_DIR}/include/libstdlib/${src}.h NEWLINE_STYLE LF @ONLY)\n    list(APPEND GENERATED_STDLIB_HEADERS ${PROJECT_BINARY_DIR}/include/libstdlib/${src}.h)\nendforeach()\n\nconfigure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/stdlib.h.in\" ${PROJECT_BINARY_DIR}/include/libstdlib/stdlib.h NEWLINE_STYLE LF @ONLY)\n"
  },
  {
    "path": "libstdlib/src/stub.sol",
    "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.0;\n\npragma experimental solidity;\n\nfunction identity()\n{\n}\n"
  },
  {
    "path": "libstdlib/stdlib.h.in",
    "content": "#pragma once\n\n#include <map>\n#include <string>\n\n#include \"libstdlib/stub.h\"\n\nnamespace solidity::stdlib\n{\n\nstatic std::map<std::string, std::string> sources = {\n\t{ \"std.stub\", stub }\n};\n\n} // namespace solidity::stdlib\n"
  },
  {
    "path": "libstdlib/stdlib.src.h.in",
    "content": "// The generation of this file is defined in stdlib/CMakeLists.txt.\n// This file was generated by using the content of stdlib/src/@STDLIB_FILE_NAME@.sol.\n\n#pragma once\n\nnamespace solidity::stdlib\n{\n\nstatic char const @STDLIB_FILE_NAME@[] = {\n\t@STDLIB_FILE_CONTENT@, 0\n};\n\n} // namespace solidity::stdlib\n"
  },
  {
    "path": "libyul/AST.cpp",
    "content": "/*\nThis file is part of solidity.\n\nsolidity is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nsolidity is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/AST.h>\n#include <libyul/Exceptions.h>\n\nnamespace solidity::yul\n{\n\nLiteralValue::LiteralValue(std::string _builtinStringLiteralValue):\n\tm_numericValue(std::nullopt),\n\tm_stringValue(std::make_shared<std::string>(std::move(_builtinStringLiteralValue)))\n{ }\n\nLiteralValue::LiteralValue(solidity::yul::LiteralValue::Data const& _data, std::optional<std::string> const& _hint):\n\tm_numericValue(_data),\n\tm_stringValue(_hint ? std::make_shared<std::string>(*_hint) : nullptr)\n{ }\n\nLiteralValue::Data const& LiteralValue::value() const\n{\n\tyulAssert(!unlimited());\n\treturn *m_numericValue;\n}\n\nLiteralValue::BuiltinStringLiteralData const& LiteralValue::builtinStringLiteralValue() const\n{\n\tyulAssert(unlimited());\n\treturn *m_stringValue;\n}\n\nbool LiteralValue::unlimited() const\n{\n\treturn !m_numericValue.has_value();\n}\n\nLiteralValue::RepresentationHint const& LiteralValue::hint() const\n{\n\tyulAssert(!unlimited());\n\treturn m_stringValue;\n}\n\nbool LiteralValue::operator==(LiteralValue const& _rhs) const\n{\n\tif (unlimited() != _rhs.unlimited())\n\t\treturn false;\n\n\tif (unlimited())\n\t\treturn builtinStringLiteralValue() == _rhs.builtinStringLiteralValue();\n\n\treturn value() == _rhs.value();\n}\n\nbool LiteralValue::operator<(solidity::yul::LiteralValue const& _rhs) const\n{\n\tif (unlimited() != _rhs.unlimited())\n\t\treturn unlimited() < _rhs.unlimited();\n\n\tif (unlimited())\n\t\treturn builtinStringLiteralValue() < _rhs.builtinStringLiteralValue();\n\n\treturn value() < _rhs.value();\n}\n\n}\n"
  },
  {
    "path": "libyul/AST.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2016\n * Parsed inline assembly to be used by the AST\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/Builtins.h>\n#include <libyul/YulName.h>\n\n#include <liblangutil/DebugData.h>\n\n#include <libsolutil/Numeric.h>\n\n#include <memory>\n#include <optional>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\n\nstruct NameWithDebugData { langutil::DebugData::ConstPtr debugData; YulName name; };\nusing NameWithDebugDataList = std::vector<NameWithDebugData>;\n\n/// Literal number or string (up to 32 bytes)\nenum class LiteralKind { Number, Boolean, String };\n/// Literal value that holds a u256 word of data, can be of LiteralKind type and - in case of arguments to\n/// builtins - exceed the u256 word (32 bytes), in which case the value is stored as string. The former is constructed\n/// via u256 word and optional hint and leads to unlimited == false, the latter is\n/// constructed via the string constructor and leads to unlimited == true.\nclass LiteralValue {\npublic:\n\tusing Data = u256;\n\tusing BuiltinStringLiteralData = std::string;\n\tusing RepresentationHint = std::shared_ptr<std::string>;\n\n\tLiteralValue() = default;\n\texplicit LiteralValue(std::string _builtinStringLiteralValue);\n\texplicit LiteralValue(Data const& _data, std::optional<std::string> const& _hint = std::nullopt);\n\n\tbool operator==(LiteralValue const& _rhs) const;\n\tbool operator<(LiteralValue const& _rhs) const;\n\tData const& value() const;\n\tBuiltinStringLiteralData const& builtinStringLiteralValue() const;\n\tbool unlimited() const;\n\tRepresentationHint const& hint() const;\n\nprivate:\n\tstd::optional<Data> m_numericValue;\n\tstd::shared_ptr<std::string> m_stringValue;\n};\nstruct Literal { langutil::DebugData::ConstPtr debugData; LiteralKind kind; LiteralValue value; };\n/// External / internal identifier or label reference\nstruct Identifier { langutil::DebugData::ConstPtr debugData; YulName name; };\n/// AST Node representing a reference to one of the built-in functions (as defined by the dialect).\n/// In the source it's an actual name, while in the AST we only store a handle that can be used to find the function in the Dialect\nstruct BuiltinName { langutil::DebugData::ConstPtr debugData; BuiltinHandle handle; };\n/// Assignment (\"x := mload(20:u256)\", expects push-1-expression on the right hand\n/// side and requires x to occupy exactly one stack slot.\n///\n/// Multiple assignment (\"x, y := f()\"), where the left hand side variables each occupy\n/// a single stack slot and expects a single expression on the right hand returning\n/// the same amount of items as the number of variables.\nstruct Assignment { langutil::DebugData::ConstPtr debugData; std::vector<Identifier> variableNames; std::unique_ptr<Expression> value; };\nstruct FunctionCall { langutil::DebugData::ConstPtr debugData; FunctionName functionName; std::vector<Expression> arguments; };\n/// Statement that contains only a single expression\nstruct ExpressionStatement { langutil::DebugData::ConstPtr debugData; Expression expression; };\n/// Block-scope variable declaration (\"let x:u256 := mload(20:u256)\"), non-hoisted\nstruct VariableDeclaration { langutil::DebugData::ConstPtr debugData; NameWithDebugDataList variables; std::unique_ptr<Expression> value; };\n/// Block that creates a scope (frees declared stack variables)\nstruct Block { langutil::DebugData::ConstPtr debugData; std::vector<Statement> statements; };\n/// Function definition (\"function f(a, b) -> (d, e) { ... }\")\nstruct FunctionDefinition { langutil::DebugData::ConstPtr debugData; YulName name; NameWithDebugDataList parameters; NameWithDebugDataList returnVariables; Block body; };\n/// Conditional execution without \"else\" part.\nstruct If { langutil::DebugData::ConstPtr debugData; std::unique_ptr<Expression> condition; Block body; };\n/// Switch case or default case\nstruct Case { langutil::DebugData::ConstPtr debugData; std::unique_ptr<Literal> value; Block body; };\n/// Switch statement\nstruct Switch { langutil::DebugData::ConstPtr debugData; std::unique_ptr<Expression> expression; std::vector<Case> cases; };\nstruct ForLoop { langutil::DebugData::ConstPtr debugData; Block pre; std::unique_ptr<Expression> condition; Block post; Block body; };\n/// Break statement (valid within for loop)\nstruct Break { langutil::DebugData::ConstPtr debugData; };\n/// Continue statement (valid within for loop)\nstruct Continue { langutil::DebugData::ConstPtr debugData; };\n/// Leave statement (valid within function)\nstruct Leave { langutil::DebugData::ConstPtr debugData; };\n\n/// Immutable AST comprised of its top-level block\nclass AST\n{\npublic:\n\tAST(Dialect const& _dialect, Block _root): m_dialect(_dialect), m_root(std::move(_root)) {}\n\n\tDialect const& dialect() const { return m_dialect; }\n\tBlock const& root() const { return m_root; }\nprivate:\n\tDialect const& m_dialect;\n\tBlock m_root;\n};\n\nbool constexpr isBuiltinFunctionCall(FunctionCall const& _functionCall) noexcept\n{\n\treturn std::holds_alternative<BuiltinName>(_functionCall.functionName);\n}\n\n\n/// Extracts the IR source location from a Yul node.\ntemplate <class T> inline langutil::SourceLocation nativeLocationOf(T const& _node)\n{\n\treturn _node.debugData ? _node.debugData->nativeLocation : langutil::SourceLocation{};\n}\n\n/// Extracts the IR source location from a Yul node.\ntemplate <class... Args> inline langutil::SourceLocation nativeLocationOf(std::variant<Args...> const& _node)\n{\n\treturn std::visit([](auto const& _arg) { return nativeLocationOf(_arg); }, _node);\n}\n\n/// Extracts the original source location from a Yul node.\ntemplate <class T> inline langutil::SourceLocation originLocationOf(T const& _node)\n{\n\treturn _node.debugData ? _node.debugData->originLocation : langutil::SourceLocation{};\n}\n\n/// Extracts the original source location from a Yul node.\ntemplate <class... Args> inline langutil::SourceLocation originLocationOf(std::variant<Args...> const& _node)\n{\n\treturn std::visit([](auto const& _arg) { return originLocationOf(_arg); }, _node);\n}\n\n/// Extracts the debug data from a Yul node.\ntemplate <class T> inline langutil::DebugData::ConstPtr debugDataOf(T const& _node)\n{\n\treturn _node.debugData;\n}\n\n/// Extracts the debug data from a Yul node.\ntemplate <class... Args> inline langutil::DebugData::ConstPtr debugDataOf(std::variant<Args...> const& _node)\n{\n\treturn std::visit([](auto const& _arg) { return debugDataOf(_arg); }, _node);\n}\n\ninline bool hasDefaultCase(Switch const& _switch)\n{\n\treturn std::any_of(\n\t\t_switch.cases.begin(),\n\t\t_switch.cases.end(),\n\t\t[](Case const& _case) { return !_case.value; }\n\t);\n}\n\n}\n"
  },
  {
    "path": "libyul/ASTForward.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2016\n * Forward declaration of classes for inline assembly / Yul AST\n */\n\n#pragma once\n\n#include <variant>\n\nnamespace solidity::yul\n{\n\nclass YulString;\nusing YulName = YulString;\n\nenum class LiteralKind;\nclass LiteralValue;\nstruct Literal;\nstruct Label;\nstruct Identifier;\nstruct Assignment;\nstruct VariableDeclaration;\nstruct FunctionDefinition;\nstruct FunctionCall;\nstruct If;\nstruct Switch;\nstruct Case;\nstruct ForLoop;\nstruct Break;\nstruct Continue;\nstruct Leave;\nstruct ExpressionStatement;\nstruct Block;\nstruct BuiltinName;\nstruct BuiltinHandle;\nclass AST;\n\nstruct NameWithDebugData;\n\nusing Expression = std::variant<FunctionCall, Identifier, Literal>;\nusing FunctionName = std::variant<Identifier, BuiltinName>;\n/// Type that can refer to both user-defined functions and built-ins.\n/// Technically the AST allows these names to overlap, but this is not possible to represent in the source.\nusing FunctionHandle = std::variant<YulName, BuiltinHandle>;\nusing Statement = std::variant<ExpressionStatement, Assignment, VariableDeclaration, FunctionDefinition, If, Switch, ForLoop, Break, Continue, Leave, Block>;\n\n}\n"
  },
  {
    "path": "libyul/ASTLabelRegistry.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/ASTLabelRegistry.h>\n\n#include <libyul/Exceptions.h>\n\n#include <fmt/format.h>\n\nusing namespace solidity::yul;\n\nASTLabelRegistry::ASTLabelRegistry(): m_labels{\"\"}, m_idToLabelMapping{0} {}\n\nASTLabelRegistry::ASTLabelRegistry(std::vector<std::string> _labels, std::vector<size_t> _idToLabelMapping):\n\tm_labels(std::move(_labels)),\n\tm_idToLabelMapping(std::move(_idToLabelMapping))\n{\n\tyulAssert(!m_labels.empty());\n\tyulAssert(m_labels[0].empty());\n\tyulAssert(!m_idToLabelMapping.empty());\n\tyulAssert(m_idToLabelMapping[0] == 0);\n\t// using vector<uint8_t> over vector<bool>, as the latter is optimized for space-efficiency\n\tstd::vector<uint8_t> labelVisited (m_labels.size(), false);\n\tsize_t numLabels = 0;\n\tfor (auto const& labelIndex: m_idToLabelMapping)\n\t{\n\t\tif (labelIndex == ghostLabelIndex())\n\t\t\tcontinue;\n\t\tyulAssert(labelIndex < m_labels.size());\n\t\t// it is possible to have multiple references to the empty label index\n\t\t// only the id == 0 refers to an actually empty label, otherwise the LabelID is unused\n\t\tyulAssert(\n\t\t\tlabelIndex == 0 || !labelVisited[labelIndex],\n\t\t\tfmt::format(\"LabelID {} (label \\\"{}\\\") is not unique.\", labelIndex, m_labels[labelIndex])\n\t\t);\n\t\tlabelVisited[labelIndex] = true;\n\t\tif (labelIndex >= 1)\n\t\t\t++numLabels;\n\t}\n\tyulAssert(numLabels + 1 == m_labels.size(), \"Unreferenced labels present.\");\n}\n\nASTLabelRegistry::LabelID ASTLabelRegistry::maxID() const\n{\n\tyulAssert(!m_idToLabelMapping.empty());\n\treturn m_idToLabelMapping.size() - 1;\n}\n\nsize_t ASTLabelRegistry::idToLabelIndex(LabelID const _id) const\n{\n\tyulAssert(_id < m_idToLabelMapping.size());\n\treturn m_idToLabelMapping[_id];\n}\n\nstd::string_view ASTLabelRegistry::operator[](LabelID const _id) const\n{\n\tauto const labelIndex = idToLabelIndex(_id);\n\tyulAssert(labelIndex != ghostLabelIndex(), \"Ghost ids are not explicitly labelled in the registry.\");\n\t// not using `unused` here, as we already have evaluated the label index\n\t// an id is unused if it is not id == 0 (empty label) but points at label index 0\n\tyulAssert(empty(_id) || labelIndex != 0, \"Can only query ids that are not unused\");\n\treturn m_labels[labelIndex];\n}\n\nbool ASTLabelRegistry::ghost(LabelID const _id) const\n{\n\treturn idToLabelIndex(_id) == ghostLabelIndex();\n}\n\nbool ASTLabelRegistry::unused(LabelID const _id) const\n{\n\treturn !empty(_id) && idToLabelIndex(_id) == 0;\n}\n\nstd::optional<ASTLabelRegistry::LabelID> ASTLabelRegistry::findIDForLabel(std::string_view const _label) const\n{\n\tfor (LabelID id = 0; id <= maxID(); ++id)\n\t\tif ((*this)[id] == _label)\n\t\t\treturn id;\n\treturn std::nullopt;\n}\n\nstd::tuple<ASTLabelRegistry::LabelID, bool> ASTLabelRegistryBuilder::DefinedLabels::tryInsert(\n\tstd::string_view const _label,\n\tASTLabelRegistry::LabelID const _id\n)\n{\n\tauto const [it, emplaced] = m_labelToIDMapping.try_emplace(std::string{_label}, _id);\n\treturn std::make_tuple(it->second, emplaced);\n}\n\nASTLabelRegistryBuilder::ASTLabelRegistryBuilder():\n\tm_nextID(1)\n{}\n\nASTLabelRegistryBuilder::ASTLabelRegistryBuilder(ASTLabelRegistry const& _existingRegistry)\n{\n\tyulAssert(!_existingRegistry.labels().empty() && _existingRegistry[0].empty());\n\tfor (size_t id = 1; id <= _existingRegistry.maxID(); ++id)\n\t{\n\t\tif (!ASTLabelRegistry::empty(id) && !_existingRegistry.unused(id))\n\t\t{\n\t\t\t// ghost ids are not added to the map as they are not explicitly labeled\n\t\t\tif (_existingRegistry.ghost(id))\n\t\t\t\tm_ghosts.push_back(id);\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto const [_, inserted] = m_definedLabels.tryInsert(_existingRegistry[id], id);\n\t\t\t\tyulAssert(inserted, \"Existing registry cannot contain duplicate labels.\");\n\t\t\t}\n\t\t}\n\t}\n\tm_nextID = _existingRegistry.maxID() + 1;\n}\n\nASTLabelRegistry::LabelID ASTLabelRegistryBuilder::define(std::string_view const _label)\n{\n\tauto const [id, inserted] = m_definedLabels.tryInsert(_label, m_nextID);\n\tif (inserted)\n\t\tm_nextID++;\n\treturn id;\n}\n\nASTLabelRegistry::LabelID ASTLabelRegistryBuilder::addGhost()\n{\n\tm_ghosts.push_back(m_nextID);\n\treturn m_nextID++;\n}\n\nASTLabelRegistry ASTLabelRegistryBuilder::build() const\n{\n\tauto const& labelToIDMapping = m_definedLabels.labelToIDMapping();\n\tyulAssert(labelToIDMapping.contains(\"\"));\n\tyulAssert(labelToIDMapping.at(\"\") == 0);\n\n\tstd::vector<std::string> labels{\"\"};\n\tlabels.reserve(labelToIDMapping.size());\n\tstd::vector<size_t> idToLabelMapping( m_nextID + 1, 0);\n\tyulAssert(!idToLabelMapping.empty(), \"Mapping must at least contain empty label\");\n\tfor (auto const& [label, id]: labelToIDMapping)\n\t{\n\t\tif (ASTLabelRegistry::empty(id))\n\t\t\tcontinue;\n\n\t\tlabels.emplace_back(label);\n\t\tidToLabelMapping[id] = labels.size() - 1;\n\t}\n\tfor (auto const ghostId: m_ghosts)\n\t\tidToLabelMapping[ghostId] = ASTLabelRegistry::ghostLabelIndex();\n\treturn ASTLabelRegistry{std::move(labels), std::move(idToLabelMapping)};\n}\n"
  },
  {
    "path": "libyul/ASTLabelRegistry.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <limits>\n#include <map>\n#include <optional>\n#include <string>\n#include <string_view>\n#include <vector>\n\nnamespace solidity::yul\n{\n\n/// Instances of the `ASTLabelRegistry` are immutable containers describing a labelling of nodes inside the AST.\n/// Each element of the AST that possesses a label has a `ASTLabelRegistry::LabelID`, with which the label can\n/// be queried in O(1).\n/// Preferred way of creating instances is via `ASTLabelRegistryBuilder` when parsing/importing and\n/// via `LabelIDDispenser` during/after optimization.\n/// Note: The id == 0 always corresponds to the empty label. Other ids can point at the label index 0, which means that\n/// they are unused. To check, whether an id is unused, the `unused` function can be used.\n/// Note: There is a special case of ghost ids, which are added during CFG construction.\n/// They do not directly correspond to elements of an AST but live inside the CFG. They are assigned the\n/// special `std::numeric_limits<LabelID>::max` label index. The labels themselves are - if required - generated from\n/// the CFG.\nclass ASTLabelRegistry\n{\npublic:\n\t/// unsafe to use from a different registry instance, it is up to the user to safeguard against this\n\tusing LabelID = size_t;\n\n\tASTLabelRegistry();\n\tASTLabelRegistry(std::vector<std::string> _labels, std::vector<size_t> _idToLabelMapping);\n\n\tstd::string_view operator[](LabelID _id) const;\n\n\tstatic bool constexpr empty(LabelID const _id) { return _id == emptyID(); }\n\tstatic LabelID constexpr emptyID() { return 0; }\n\tstatic size_t constexpr ghostLabelIndex() { return std::numeric_limits<size_t>::max(); }\n\n\tbool unused(LabelID _id) const;\n\tbool ghost(LabelID _id) const;\n\tstd::vector<std::string> const& labels() const { return m_labels; }\n\tLabelID maxID() const;\n\n\tsize_t idToLabelIndex(LabelID _id) const;\n\t/// this is a potentially expensive operation\n\tstd::optional<LabelID> findIDForLabel(std::string_view _label) const;\n\nprivate:\n\t/// All Yul AST labels present in the registry.\n\t/// Always contains at least an empty label which also serves as a null-state for non-contiguous ID ranges.\n\t/// All items must be unique.\n\tstd::vector<std::string> const m_labels;\n\n\t/// Assignment of labels to `LabelID`s. Indices are `LabelID`s and values are indices into `m_labels`.\n\t/// Every label except empty always has exactly one `LabelID` pointing at it.\n\t/// The empty label has one canonical ID, but unused IDs point to it as well.\n\tstd::vector<size_t> const m_idToLabelMapping;\n};\n\n/// Produces instances of `ASTLabelRegistry`. Preferably used during parsing/importing.\nclass ASTLabelRegistryBuilder\n{\npublic:\n\tASTLabelRegistryBuilder();\n\t/// Creates a new builder taking an already existing label registry into account.\n\t/// Unused IDs are skipped, ghost IDs are recorded and inserted back into the newly built registry.\n\texplicit ASTLabelRegistryBuilder(ASTLabelRegistry const& _existingRegistry);\n\n\tASTLabelRegistry::LabelID define(std::string_view _label);\n\tASTLabelRegistry::LabelID addGhost();\n\n\t/// Creates a new label registry based on what was defined and potentially an existing registry. If such registry\n\t/// was provided, all labels (including unused and ghost label IDs) carry over.\n\tASTLabelRegistry build() const;\n\nprivate:\n\tclass DefinedLabels\n\t{\n\tpublic:\n\t\tstd::tuple<ASTLabelRegistry::LabelID, bool> tryInsert(std::string_view _label, ASTLabelRegistry::LabelID _id);\n\t\tauto const& labelToIDMapping() const { return m_labelToIDMapping; }\n\n\tprivate:\n\t\tstd::map<std::string, size_t, std::less<>> m_labelToIDMapping = {{\"\", 0}};\n\t};\n\n\tDefinedLabels m_definedLabels;\n\tstd::vector<ASTLabelRegistry::LabelID> m_ghosts;\n\tsize_t m_nextID{};\n};\n\n}\n"
  },
  {
    "path": "libyul/AsmAnalysis.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Analyzer part of inline assembly.\n */\n\n#include <libyul/AsmAnalysis.h>\n\n#include <libyul/AST.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/Utilities.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Object.h>\n#include <libyul/Scope.h>\n#include <libyul/ScopeFiller.h>\n\n#include <liblangutil/ErrorReporter.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/Visitor.h>\n\n#include <libevmasm/Instruction.h>\n\n#include <boost/algorithm/string.hpp>\n\n#include <fmt/format.h>\n\n#include <functional>\n\nusing namespace std::string_literals;\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\n\nnamespace\n{\ninline std::string to_string(LiteralKind _kind)\n{\n\tswitch (_kind)\n\t{\n\tcase LiteralKind::Number: return \"number\";\n\tcase LiteralKind::Boolean: return \"boolean\";\n\tcase LiteralKind::String: return \"string\";\n\tdefault: yulAssert(false, \"\");\n\t}\n}\n}\n\nbool AsmAnalyzer::analyze(Block const& _block)\n{\n\tauto watcher = m_errorReporter.errorWatcher();\n\ttry\n\t{\n\t\t// FIXME: Pass location of the object name. Now it's a location of first code section in yul\n\t\tvalidateObjectStructure(nativeLocationOf(_block));\n\t\tif (!(ScopeFiller(m_info, m_errorReporter))(_block))\n\t\t\treturn false;\n\n\t\t(*this)(_block);\n\t}\n\tcatch (FatalError const&)\n\t{\n\t\t// NOTE: There's a cap on the number of reported errors, but watcher.ok() will work fine even if\n\t\t// we exceed it because the reporter keeps counting (it just stops adding errors to the list).\n\t\t// Note also that fact of exceeding the cap triggers a FatalError so one can get thrown even\n\t\t// if we don't make any of our errors fatal.\n\t\tif (watcher.ok())\n\t\t{\n\t\t\tstd::cerr << \"Unreported fatal error:\" << std::endl;\n\t\t\tstd::cerr << boost::current_exception_diagnostic_information() << std::endl;\n\t\t\tyulAssert(false, \"Unreported fatal error.\");\n\t\t}\n\t}\n\treturn watcher.ok();\n}\n\nAsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Object const& _object)\n{\n\tyulAssert(_object.dialect());\n\treturn analyzeStrictAssertCorrect(*_object.dialect(), *_object.code(), _object.summarizeStructure());\n}\n\nAsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(\n\tDialect const& _dialect,\n\tAST const& _ast,\n\tObject::Structure _objectStructure\n)\n{\n\treturn analyzeStrictAssertCorrect(_dialect, _ast.root(), std::move(_objectStructure));\n}\n\nAsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(\n\tDialect const& _dialect,\n\tBlock const& _astRoot,\n\tObject::Structure _objectStructure\n)\n{\n\tErrorList errorList;\n\tlangutil::ErrorReporter errors(errorList);\n\tAsmAnalysisInfo analysisInfo;\n\tbool success = AsmAnalyzer(\n\t\tanalysisInfo,\n\t\terrors,\n\t\t_dialect,\n\t\t{},\n\t\tstd::move(_objectStructure)\n\t).analyze(_astRoot);\n\n\tif (!success)\n\t{\n\t\tauto formatErrors = [](ErrorList const& _errorList) {\n\t\t\tstd::vector<std::string> formattedErrors;\n\t\t\tfor (std::shared_ptr<Error const> const& error: _errorList)\n\t\t\t{\n\t\t\t\tyulAssert(error->comment());\n\t\t\t\tformattedErrors.push_back(fmt::format(\n\t\t\t\t\t// Intentionally not showing source locations because we don't have the original\n\t\t\t\t\t// source here and it's unlikely they match the pretty-printed version.\n\t\t\t\t\t// They may not even match the original source if the AST was modified by the optimizer.\n\t\t\t\t\t\"- {} {}: {}\",\n\t\t\t\t\tError::formatErrorType(error->type()),\n\t\t\t\t\terror->errorId().error,\n\t\t\t\t\t*error->comment()\n\t\t\t\t));\n\t\t\t}\n\t\t\treturn joinHumanReadable(formattedErrors, \"\\n\");\n\t\t};\n\n\t\tyulAssert(errors.hasErrors(), \"Yul analysis failed but did not report any errors.\");\n\t\tyulAssert(false, fmt::format(\n\t\t\t\"{}\\n\\nExpected valid Yul, but errors were reported during analysis:\\n{}\",\n\t\t\tAsmPrinter{_dialect}(_astRoot),\n\t\t\tformatErrors(errorList)\n\t\t));\n\t}\n\n\tyulAssert(!errors.hasErrors());\n\treturn analysisInfo;\n}\n\nsize_t AsmAnalyzer::operator()(Literal const& _literal)\n{\n\tbool erroneousLiteralValue = false;\n\tif (_literal.kind == LiteralKind::String && !_literal.value.unlimited() && _literal.value.hint() && _literal.value.hint()->size() > 32)\n\t{\n\t\terroneousLiteralValue = true;\n\t\tm_errorReporter.typeError(\n\t\t\t3069_error,\n\t\t\tnativeLocationOf(_literal),\n\t\t\tfmt::format(\"String literal too long ({} > 32)\", formatLiteral(_literal, false /* _validated */ ).size())\n\t\t);\n\t}\n\telse if (_literal.kind == LiteralKind::Number && _literal.value.hint() && bigint(*_literal.value.hint()) > u256(-1))\n\t{\n\t\terroneousLiteralValue = true;\n\t\tm_errorReporter.typeError(6708_error, nativeLocationOf(_literal), \"Number literal too large (> 256 bits)\");\n\t}\n\n\tyulAssert(erroneousLiteralValue ^ validLiteral(_literal), \"Invalid literal after validating it through AsmAnalyzer.\");\n\treturn 1;\n}\n\nsize_t AsmAnalyzer::operator()(Identifier const& _identifier)\n{\n\tyulAssert(!_identifier.name.empty());\n\tauto watcher = m_errorReporter.errorWatcher();\n\n\tif (m_currentScope->lookup(_identifier.name, GenericVisitor{\n\t\t[&](Scope::Variable const& _var)\n\t\t{\n\t\t\tif (!m_activeVariables.count(&_var))\n\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t4990_error,\n\t\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\t\tfmt::format(\"Variable {} used before it was declared.\", _identifier.name.str())\n\t\t\t\t);\n\t\t},\n\t\t[&](Scope::Function const&)\n\t\t{\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t6041_error,\n\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\tfmt::format(\"Function {} used without being called.\", _identifier.name.str())\n\t\t\t);\n\t\t}\n\t}))\n\t{\n\t\tif (m_resolver)\n\t\t\t// We found a local reference, make sure there is no external reference.\n\t\t\t// Used for side effects, e.g., error reporting in TypeChecker, hence ignoring return value\n\t\t\tstd::ignore = m_resolver(\n\t\t\t\t_identifier,\n\t\t\t\tyul::IdentifierContext::NonExternal,\n\t\t\t\tm_currentScope->insideFunction()\n\t\t\t);\n\t}\n\telse\n\t{\n\t\tbool found = m_resolver && m_resolver(\n\t\t\t_identifier,\n\t\t\tyul::IdentifierContext::RValue,\n\t\t\tm_currentScope->insideFunction()\n\t\t);\n\t\tif (!found && watcher.ok())\n\t\t\t// Only add an error message if the callback did not do it.\n\t\t\tm_errorReporter.declarationError(\n\t\t\t\t8198_error,\n\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\tfmt::format(\"Identifier \\\"{}\\\" not found.\", _identifier.name.str())\n\t\t\t);\n\n\t}\n\n\treturn 1;\n}\n\nvoid AsmAnalyzer::operator()(ExpressionStatement const& _statement)\n{\n\tauto watcher = m_errorReporter.errorWatcher();\n\tsize_t numReturns = std::visit(*this, _statement.expression);\n\tif (watcher.ok() && numReturns > 0)\n\t\tm_errorReporter.typeError(\n\t\t\t3083_error,\n\t\t\tnativeLocationOf(_statement),\n\t\t\tfmt::format(\n\t\t\t\t\"Top-level expressions are not supposed to return values (this expression returns {} value{}). \"\n\t\t\t\t\"Use ``pop()`` or assign them.\",\n\t\t\t\tnumReturns,\n\t\t\t\tnumReturns == 1 ? \"\" : \"s\"\n\t\t\t)\n\t\t);\n}\n\nvoid AsmAnalyzer::operator()(Assignment const& _assignment)\n{\n\tyulAssert(_assignment.value, \"\");\n\tsize_t const numVariables = _assignment.variableNames.size();\n\tyulAssert(numVariables >= 1, \"\");\n\n\tstd::set<YulName> variables;\n\tfor (auto const& _variableName: _assignment.variableNames)\n\t\tif (!variables.insert(_variableName.name).second)\n\t\t\tm_errorReporter.declarationError(\n\t\t\t\t9005_error,\n\t\t\t\tnativeLocationOf(_assignment),\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"Variable {} occurs multiple times on the left-hand side of the assignment.\",\n\t\t\t\t\t_variableName.name.str()\n\t\t\t\t)\n\t\t\t);\n\n\tsize_t numRhsValues = std::visit(*this, *_assignment.value);\n\n\tif (numRhsValues != numVariables)\n\t\tm_errorReporter.declarationError(\n\t\t\t8678_error,\n\t\t\tnativeLocationOf(_assignment),\n\t\t\tfmt::format(\n\t\t\t\t\"Variable count for assignment to \\\"{}\\\" does not match number of values ({} vs. {})\",\n\t\t\t\tjoinHumanReadable(applyMap(_assignment.variableNames, [](auto const& _identifier){ return _identifier.name.str(); })),\n\t\t\t\tnumVariables,\n\t\t\t\tnumRhsValues\n\t\t\t)\n\t\t);\n\n\tfor (size_t i = 0; i < numVariables; ++i)\n\t\tcheckAssignment(_assignment.variableNames[i]);\n}\n\nvoid AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)\n{\n\tsize_t const numVariables = _varDecl.variables.size();\n\tif (m_resolver)\n\t\tfor (auto const& variable: _varDecl.variables)\n\t\t\t// Call the resolver for variable declarations to allow it to raise errors on shadowing.\n\t\t\tm_resolver(\n\t\t\t\tyul::Identifier{variable.debugData, variable.name},\n\t\t\t\tyul::IdentifierContext::VariableDeclaration,\n\t\t\t\tm_currentScope->insideFunction()\n\t\t\t);\n\tfor (auto const& variable: _varDecl.variables)\n\t{\n\t\texpectValidIdentifier(variable.name, nativeLocationOf(variable));\n\t}\n\n\tif (_varDecl.value)\n\t{\n\t\tsize_t numValues = std::visit(*this, *_varDecl.value);\n\t\tif (numValues != numVariables)\n\t\t\tm_errorReporter.declarationError(\n\t\t\t\t3812_error,\n\t\t\t\tnativeLocationOf(_varDecl),\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"Variable count mismatch for declaration of \\\"{}\\\": {} variables and {} values.\",\n\t\t\t\t\tjoinHumanReadable(applyMap(_varDecl.variables, [](auto const& _identifier){ return _identifier.name.str(); })),\n\t\t\t\t\tnumVariables,\n\t\t\t\t\tnumValues\n\t\t\t\t)\n\t\t\t);\n\t}\n\n\tfor (NameWithDebugData const& variable: _varDecl.variables)\n\t\tm_activeVariables.insert(&std::get<Scope::Variable>(\n\t\t\tm_currentScope->identifiers.at(variable.name))\n\t\t);\n}\n\nvoid AsmAnalyzer::operator()(FunctionDefinition const& _funDef)\n{\n\tyulAssert(!_funDef.name.empty());\n\texpectValidIdentifier(_funDef.name, nativeLocationOf(_funDef));\n\tBlock const* virtualBlock = m_info.virtualBlocks.at(&_funDef).get();\n\tyulAssert(virtualBlock, \"\");\n\tScope& varScope = scope(virtualBlock);\n\tfor (auto const& var: _funDef.parameters + _funDef.returnVariables)\n\t{\n\t\texpectValidIdentifier(var.name, nativeLocationOf(var));\n\t\tm_activeVariables.insert(&std::get<Scope::Variable>(varScope.identifiers.at(var.name)));\n\t}\n\n\tif (m_eofVersion.has_value())\n\t{\n\t\tif (_funDef.parameters.size() >= 0x80)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t8534_error,\n\t\t\t\tnativeLocationOf(_funDef),\n\t\t\t\t\"Too many function parameters. At most 127 parameters allowed for EOF\"\n\t\t\t);\n\n\t\tif (_funDef.returnVariables.size() >= 0x80)\n\t\t\tm_errorReporter.typeError(\n\t\t\t\t2101_error,\n\t\t\t\tnativeLocationOf(_funDef),\n\t\t\t\t\"Too many function return variables. At most 127 return variables allowed for EOF\"\n\t\t\t);\n\t}\n\n\t(*this)(_funDef.body);\n}\n\nsize_t AsmAnalyzer::operator()(FunctionCall const& _funCall)\n{\n\tauto watcher = m_errorReporter.errorWatcher();\n\tstd::optional<size_t> numParameters;\n\tstd::optional<size_t> numReturns;\n\tstd::vector<std::optional<LiteralKind>> const* literalArguments = nullptr;\n\n\tstd::visit(\n\t\tGenericVisitor {\n\t\t\t[&](BuiltinName const& _builtinName)\n\t\t\t{\n\t\t\t\tBuiltinFunction const& builtin = m_dialect.builtin(_builtinName.handle);\n\t\t\t\tif (builtin.name == \"selfdestruct\")\n\t\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t\t1699_error,\n\t\t\t\t\t\tnativeLocationOf(_builtinName),\n\t\t\t\t\t\t\"\\\"selfdestruct\\\" has been deprecated. \"\n\t\t\t\t\t\t\"Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and \"\n\t\t\t\t\t\t\"data associated with an account and only transfers its Ether to the beneficiary, \"\n\t\t\t\t\t\t\"unless executed in the same transaction in which the contract was created (see EIP-6780). \"\n\t\t\t\t\t\t\"Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. \"\n\t\t\t\t\t\t\"Future changes to the EVM might further reduce the functionality of the opcode.\"\n\t\t\t\t\t);\n\t\t\t\telse if (\n\t\t\t\t\tbuiltin.name == \"tstore\" &&\n\t\t\t\t\t!m_errorReporter.hasError({2394})\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tyulAssert(m_evmVersion.supportsTransientStorage(), \"tstore is only a builtin on EVMs that support transient storage\");\n\t\t\t\t\tm_errorReporter.warning(\n\t\t\t\t\t\t2394_error,\n\t\t\t\t\t\tnativeLocationOf(_builtinName),\n\t\t\t\t\t\t\"Transient storage as defined by EIP-1153 can break the composability of smart contracts: \"\n\t\t\t\t\t\t\"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, \"\n\t\t\t\t\t\t\"your contract may unintentionally misbehave when invoked multiple times in a complex transaction. \"\n\t\t\t\t\t\t\"To avoid this, be sure to clear all transient storage at the end of any call to your contract. \"\n\t\t\t\t\t\t\"The use of transient storage for reentrancy guards that are cleared at the end of the call is safe.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tnumParameters = builtin.numParameters;\n\t\t\t\tnumReturns = builtin.numReturns;\n\t\t\t\tif (!builtin.literalArguments.empty())\n\t\t\t\t\tliteralArguments = &builtin.literalArguments;\n\n\t\t\t\tvalidateInstructions(_funCall);\n\t\t\t\tm_sideEffects += builtin.sideEffects;\n\t\t\t},\n\t\t\t[&](Identifier const& _identifier)\n\t\t\t{\n\t\t\t\tbool const identifierInCurrentScope = m_currentScope->lookup(_identifier.name, GenericVisitor{\n\t\t\t\t\t[&](Scope::Variable const&)\n\t\t\t\t\t{\n\t\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t\t4202_error,\n\t\t\t\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\t\t\t\t\"Attempt to call variable instead of function.\"\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\t[&](Scope::Function const& _fun)\n\t\t\t\t\t{\n\t\t\t\t\t\tnumParameters = _fun.numArguments;\n\t\t\t\t\t\tnumReturns = _fun.numReturns;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (identifierInCurrentScope)\n\t\t\t\t{\n\t\t\t\t\tif (m_resolver)\n\t\t\t\t\t\t// We found a local reference, make sure there is no external reference.\n\t\t\t\t\t\t// Used for side effects, e.g., error reporting in TypeChecker, hence ignoring return value\n\t\t\t\t\t\tstd::ignore = m_resolver(\n\t\t\t\t\t\t\t_identifier,\n\t\t\t\t\t\t\tyul::IdentifierContext::NonExternal,\n\t\t\t\t\t\t\tm_currentScope->insideFunction()\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!validateInstructions(_funCall))\n\t\t\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t\t\t4619_error,\n\t\t\t\t\t\t\tnativeLocationOf(_identifier),\n\t\t\t\t\t\t\tfmt::format(\"Function \\\"{}\\\" not found.\", _identifier.name.str())\n\t\t\t\t\t\t);\n\t\t\t\t\tyulAssert(!watcher.ok(), \"Expected a reported error.\");\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t_funCall.functionName\n\t);\n\n\tif (numParameters && _funCall.arguments.size() != *numParameters)\n\t\tm_errorReporter.typeError(\n\t\t\t7000_error,\n\t\t\tnativeLocationOf(_funCall.functionName),\n\t\t\tfmt::format(\n\t\t\t\t\"Function \\\"{}\\\" expects {} arguments but got {}.\",\n\t\t\t\tresolveFunctionName(_funCall.functionName, m_dialect),\n\t\t\t\t*numParameters,\n\t\t\t\t_funCall.arguments.size()\n\t\t\t)\n\t\t);\n\n\tfor (size_t i = _funCall.arguments.size(); i > 0; i--)\n\t{\n\t\tExpression const& arg = _funCall.arguments[i - 1];\n\t\tif (\n\t\t\tauto literalArgumentKind = (literalArguments && i <= literalArguments->size()) ?\n\t\t\t\tliteralArguments->at(i - 1) :\n\t\t\t\tstd::nullopt\n\t\t)\n\t\t{\n\t\t\tif (!std::holds_alternative<Literal>(arg))\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t9114_error,\n\t\t\t\t\tnativeLocationOf(_funCall.functionName),\n\t\t\t\t\t\"Function expects direct literals as arguments.\"\n\t\t\t\t);\n\t\t\telse if (*literalArgumentKind != std::get<Literal>(arg).kind)\n\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t5859_error,\n\t\t\t\t\tnativeLocationOf(arg),\n\t\t\t\t\tfmt::format(\"Function expects {} literal.\", to_string(*literalArgumentKind))\n\t\t\t\t);\n\t\t\telse if (*literalArgumentKind == LiteralKind::String)\n\t\t\t{\n\t\t\t\tstd::string_view functionName = resolveFunctionName(_funCall.functionName, m_dialect);\n\t\t\t\tif (functionName == \"datasize\" || functionName == \"dataoffset\")\n\t\t\t\t{\n\t\t\t\t\tauto const& argumentAsLiteral = std::get<Literal>(arg);\n\t\t\t\t\tif (!m_objectStructure.contains(formatLiteral(argumentAsLiteral)))\n\t\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t\t3517_error,\n\t\t\t\t\t\t\tnativeLocationOf(arg),\n\t\t\t\t\t\t\tfmt::format(\"Unknown data object \\\"{}\\\".\", formatLiteral(argumentAsLiteral))\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse if (functionName.substr(0, \"verbatim_\"s.size()) == \"verbatim_\")\n\t\t\t\t{\n\t\t\t\t\tauto const& literalValue = std::get<Literal>(arg).value;\n\t\t\t\t\tyulAssert(literalValue.unlimited());  // verbatim literals are always unlimited\n\t\t\t\t\tif (literalValue.builtinStringLiteralValue().empty())\n\t\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t\t1844_error,\n\t\t\t\t\t\t\tnativeLocationOf(arg),\n\t\t\t\t\t\t\t\"The \\\"verbatim_*\\\" builtins cannot be used with empty bytecode.\"\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse if (functionName == \"eofcreate\" || functionName == \"returncontract\")\n\t\t\t\t{\n\t\t\t\t\tauto const& argumentAsLiteral = std::get<Literal>(arg);\n\t\t\t\t\tauto const formattedLiteral = formatLiteral(argumentAsLiteral);\n\n\t\t\t\t\tif (util::contains(formattedLiteral, '.'))\n\t\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t\t2186_error,\n\t\t\t\t\t\t\tnativeLocationOf(arg),\n\t\t\t\t\t\t\tfmt::format(\"Name required but path given as \\\"{}\\\" argument.\", functionName)\n\t\t\t\t\t\t);\n\n\t\t\t\t\tif (!m_objectStructure.topLevelSubObjectNames().count(formattedLiteral))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (m_objectStructure.containsData(formattedLiteral))\n\t\t\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t\t\t7575_error,\n\t\t\t\t\t\t\t\tnativeLocationOf(arg),\n\t\t\t\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\t\t\t\"Data name \\\"{}\\\" cannot be used as an argument of eofcreate/returncontract. \"\n\t\t\t\t\t\t\t\t\t\"Only an object name is acceptable.\",\n\t\t\t\t\t\t\t\t\tformattedLiteral\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t\t\t8970_error,\n\t\t\t\t\t\t\t\tnativeLocationOf(arg),\n\t\t\t\t\t\t\t\tfmt::format(\"Unknown object \\\"{}\\\".\", formattedLiteral)\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\texpectUnlimitedStringLiteral(std::get<Literal>(arg));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if (*literalArgumentKind == LiteralKind::Number)\n\t\t\t{\n\t\t\t\tstd::string_view functionName = resolveFunctionName(_funCall.functionName, m_dialect);\n\t\t\t\tif (functionName == \"auxdataloadn\")\n\t\t\t\t{\n\t\t\t\t\tauto const& argumentAsLiteral = std::get<Literal>(arg);\n\t\t\t\t\tif (argumentAsLiteral.value.value() > std::numeric_limits<uint16_t>::max())\n\t\t\t\t\t\tm_errorReporter.typeError(\n\t\t\t\t\t\t\t5202_error,\n\t\t\t\t\t\t\tnativeLocationOf(arg),\n\t\t\t\t\t\t\t\"Invalid auxdataloadn argument value. Offset must be in range 0...0xFFFF\"\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\texpectExpression(arg);\n\t}\n\n\tif (watcher.ok())\n\t{\n\t\tyulAssert(numParameters && numParameters == _funCall.arguments.size());\n\t\tyulAssert(numReturns);\n\t\treturn *numReturns;\n\t}\n\telse if (numReturns)\n\t\treturn *numReturns;\n\telse\n\t\treturn {};\n}\n\nvoid AsmAnalyzer::operator()(If const& _if)\n{\n\texpectExpression(*_if.condition);\n\n\t(*this)(_if.body);\n}\n\nvoid AsmAnalyzer::operator()(Switch const& _switch)\n{\n\tyulAssert(_switch.expression, \"\");\n\n\tif (_switch.cases.size() == 1 && !_switch.cases[0].value)\n\t\tm_errorReporter.warning(\n\t\t\t9592_error,\n\t\t\tnativeLocationOf(_switch),\n\t\t\t\"\\\"switch\\\" statement with only a default case.\"\n\t\t);\n\n\texpectExpression(*_switch.expression);\n\n\tstd::set<u256> cases;\n\tfor (auto const& _case: _switch.cases)\n\t{\n\t\tif (_case.value)\n\t\t{\n\t\t\tauto watcher = m_errorReporter.errorWatcher();\n\n\t\t\t// We cannot use \"expectExpression\" here because *_case.value is not an\n\t\t\t// Expression and would be converted to an Expression otherwise.\n\t\t\t(*this)(*_case.value);\n\n\t\t\t/// Note: the parser ensures there is only one default case\n\t\t\tif (watcher.ok() && !cases.insert(_case.value->value.value()).second)\n\t\t\t\tm_errorReporter.declarationError(\n\t\t\t\t\t6792_error,\n\t\t\t\t\tnativeLocationOf(_case),\n\t\t\t\t\tfmt::format(\"Duplicate case \\\"{}\\\" defined.\", formatLiteral(*_case.value))\n\t\t\t\t);\n\t\t}\n\n\t\t(*this)(_case.body);\n\t}\n}\n\nvoid AsmAnalyzer::operator()(ForLoop const& _for)\n{\n\tyulAssert(_for.condition, \"\");\n\n\tScope* outerScope = m_currentScope;\n\n\t(*this)(_for.pre);\n\n\t// The block was closed already, but we re-open it again and stuff the\n\t// condition, the body and the post part inside.\n\tm_currentScope = &scope(&_for.pre);\n\n\texpectExpression(*_for.condition);\n\t// backup outer for-loop & create new state\n\tauto outerForLoop = m_currentForLoop;\n\tm_currentForLoop = &_for;\n\n\t(*this)(_for.body);\n\t(*this)(_for.post);\n\n\tm_currentScope = outerScope;\n\tm_currentForLoop = outerForLoop;\n}\n\nvoid AsmAnalyzer::operator()(Block const& _block)\n{\n\tauto previousScope = m_currentScope;\n\tm_currentScope = &scope(&_block);\n\n\tfor (auto const& s: _block.statements)\n\t\tstd::visit(*this, s);\n\n\tm_currentScope = previousScope;\n}\n\nvoid AsmAnalyzer::expectExpression(Expression const& _expr)\n{\n\tsize_t numValues = std::visit(*this, _expr);\n\tif (numValues != 1)\n\t\tm_errorReporter.typeError(\n\t\t\t3950_error,\n\t\t\tnativeLocationOf(_expr),\n\t\t\tfmt::format(\n\t\t\t\t\"Expected expression to evaluate to one value, but got {} values instead.\",\n\t\t\t\tnumValues\n\t\t\t)\n\t\t);\n}\n\nvoid AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal)\n{\n\tyulAssert(_literal.kind == LiteralKind::String);\n\tyulAssert(_literal.value.unlimited());\n}\n\nvoid AsmAnalyzer::checkAssignment(Identifier const& _variable)\n{\n\tyulAssert(!_variable.name.empty());\n\tauto watcher = m_errorReporter.errorWatcher();\n\tbool hasVariable = false;\n\tbool found = false;\n\tif (Scope::Identifier const* var = m_currentScope->lookup(_variable.name))\n\t{\n\t\tif (m_resolver)\n\t\t\t// We found a local reference, make sure there is no external reference.\n\t\t\t// Used for side effects, e.g., error reporting in TypeChecker, hence ignoring return value\n\t\t\tstd::ignore = m_resolver(\n\t\t\t\t_variable,\n\t\t\t\tyul::IdentifierContext::NonExternal,\n\t\t\t\tm_currentScope->insideFunction()\n\t\t\t);\n\n\t\tif (!std::holds_alternative<Scope::Variable>(*var))\n\t\t\tm_errorReporter.typeError(2657_error, nativeLocationOf(_variable), \"Assignment requires variable.\");\n\t\telse if (!m_activeVariables.count(&std::get<Scope::Variable>(*var)))\n\t\t\tm_errorReporter.declarationError(\n\t\t\t\t1133_error,\n\t\t\t\tnativeLocationOf(_variable),\n\t\t\t\tfmt::format(\"Variable {} used before it was declared.\", _variable.name.str())\n\t\t\t);\n\t\telse\n\t\t\thasVariable = true;\n\t\tfound = true;\n\t}\n\telse if (m_resolver)\n\t{\n\t\tbool insideFunction = m_currentScope->insideFunction();\n\t\tif (m_resolver(_variable, yul::IdentifierContext::LValue, insideFunction))\n\t\t{\n\t\t\tfound = true;\n\t\t\thasVariable = true;\n\t\t}\n\t}\n\n\tif (!found && watcher.ok())\n\t\t// Only add message if the callback did not.\n\t\tm_errorReporter.declarationError(4634_error, nativeLocationOf(_variable), \"Variable not found or variable not lvalue.\");\n\n\tyulAssert(!watcher.ok() || hasVariable, \"\");\n}\n\nScope& AsmAnalyzer::scope(Block const* _block)\n{\n\tyulAssert(m_info.scopes.count(_block) == 1, \"Scope requested but not present.\");\n\tauto scopePtr = m_info.scopes.at(_block);\n\tyulAssert(scopePtr, \"Scope requested but not present.\");\n\treturn *scopePtr;\n}\n\nvoid AsmAnalyzer::expectValidIdentifier(YulName _identifier, SourceLocation const& _location)\n{\n\tstd::string_view const label = _identifier.str();\n\t// NOTE: the leading dot case is handled by the parser not allowing it.\n\tif (label.ends_with('.'))\n\t\tm_errorReporter.syntaxError(\n\t\t\t3384_error,\n\t\t\t_location,\n\t\t\tfmt::format(\"\\\"{}\\\" is not a valid identifier (ends with a dot).\", label)\n\t\t);\n\n\tif (label.find(\"..\") != std::string::npos)\n\t\tm_errorReporter.syntaxError(\n\t\t\t7771_error,\n\t\t\t_location,\n\t\t\tfmt::format(\"\\\"{}\\\" is not a valid identifier (contains consecutive dots).\", label)\n\t\t);\n\n\tif (m_dialect.reservedIdentifier(label))\n\t\tm_errorReporter.declarationError(\n\t\t\t5017_error,\n\t\t\t_location,\n\t\t\tfmt::format(\"The identifier \\\"{}\\\" is reserved and can not be used.\", label)\n\t\t);\n}\n\nbool AsmAnalyzer::validateInstructions(std::string_view _instructionIdentifier, langutil::SourceLocation const& _location)\n{\n\t// NOTE: This function uses the default EVM version instead of the currently selected one.\n\tauto const& defaultEVMDialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion{}, std::nullopt);\n\tauto const builtinHandle = defaultEVMDialect.findBuiltin(_instructionIdentifier);\n\tif (builtinHandle && defaultEVMDialect.builtin(*builtinHandle).instruction.has_value())\n\t\treturn validateInstructions(*defaultEVMDialect.builtin(*builtinHandle).instruction, _location);\n\n\tsolAssert(!m_eofVersion.has_value() || *m_eofVersion == 1);\n\tauto const& eofDialect = EVMDialect::strictAssemblyForEVMObjects(EVMVersion::firstWithEOF(), 1);\n\tauto const eofBuiltinHandle = eofDialect.findBuiltin(_instructionIdentifier);\n\tif (eofBuiltinHandle)\n\t{\n\t\tauto const builtin = eofDialect.builtin(*eofBuiltinHandle);\n\t\tif (builtin.instruction.has_value())\n\t\t\treturn validateInstructions(*builtin.instruction, _location);\n\t\t// If builtin is available in EOF but not available in legacy (and we build to legacy) generate custom error.\n\t\telse if (!m_eofVersion.has_value() && !builtinHandle)\n\t\t{\n\t\t\tm_errorReporter.declarationError(\n\t\t\t\t7223_error,\n\t\t\t\t_location,\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"Builtin function \\\"{function}\\\" is only available in EOF.\",\n\t\t\t\t\tfmt::arg(\"function\", _instructionIdentifier)\n\t\t\t\t)\n\t\t\t);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nbool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocation const& _location)\n{\n\t// We assume that returndatacopy, returndatasize and staticcall are either all available\n\t// or all not available.\n\tyulAssert(m_evmVersion.supportsReturndata() == m_evmVersion.hasStaticCall(), \"\");\n\t// Similarly we assume bitwise shifting and create2 go together.\n\tyulAssert(m_evmVersion.hasBitwiseShifting() == m_evmVersion.hasCreate2(), \"\");\n\n\t// These instructions are disabled in the dialect.\n\tyulAssert(\n\t\t_instr != evmasm::Instruction::JUMP &&\n\t\t_instr != evmasm::Instruction::JUMPI &&\n\t\t_instr != evmasm::Instruction::JUMPDEST &&\n\t\t_instr != evmasm::Instruction::DATALOADN &&\n\t\t_instr != evmasm::Instruction::EOFCREATE &&\n\t\t_instr != evmasm::Instruction::RETURNCONTRACT &&\n\t\t_instr != evmasm::Instruction::RJUMP &&\n\t\t_instr != evmasm::Instruction::RJUMPI &&\n\t\t_instr != evmasm::Instruction::CALLF &&\n\t\t_instr != evmasm::Instruction::JUMPF &&\n\t\t_instr != evmasm::Instruction::RETF &&\n\t\t_instr != evmasm::Instruction::DUPN &&\n\t\t_instr != evmasm::Instruction::SWAPN\n\t);\n\n\tauto errorForVM = [&](ErrorId _errorId, std::string const& vmKindMessage) {\n\t\tm_errorReporter.typeError(\n\t\t\t_errorId,\n\t\t\t_location,\n\t\t\tfmt::format(\n\t\t\t\t\"The \\\"{instruction}\\\" instruction is {kind} VMs (you are currently compiling for \\\"{version}\\\").\",\n\t\t\t\tfmt::arg(\"instruction\", boost::to_lower_copy(instructionInfo(_instr, m_evmVersion).name)),\n\t\t\t\tfmt::arg(\"kind\", vmKindMessage),\n\t\t\t\tfmt::arg(\"version\", m_evmVersion.name())\n\t\t\t)\n\t\t);\n\t};\n\n\t// The errors below are meant to be issued when processing an undeclared identifier matching a builtin name\n\t// present on the default EVM version but not on the currently selected one,\n\t// since the other `validateInstructions()` overload uses the default EVM version.\n\tif (_instr == evmasm::Instruction::RETURNDATACOPY && !m_evmVersion.supportsReturndata())\n\t\terrorForVM(7756_error, \"only available for Byzantium-compatible\");\n\telse if (_instr == evmasm::Instruction::RETURNDATASIZE && !m_evmVersion.supportsReturndata())\n\t\terrorForVM(4778_error, \"only available for Byzantium-compatible\");\n\telse if (_instr == evmasm::Instruction::STATICCALL && !m_evmVersion.hasStaticCall())\n\t\terrorForVM(1503_error, \"only available for Byzantium-compatible\");\n\telse if (_instr == evmasm::Instruction::SHL && !m_evmVersion.hasBitwiseShifting())\n\t\terrorForVM(6612_error, \"only available for Constantinople-compatible\");\n\telse if (_instr == evmasm::Instruction::SHR && !m_evmVersion.hasBitwiseShifting())\n\t\terrorForVM(7458_error, \"only available for Constantinople-compatible\");\n\telse if (_instr == evmasm::Instruction::SAR && !m_evmVersion.hasBitwiseShifting())\n\t\terrorForVM(2054_error, \"only available for Constantinople-compatible\");\n\telse if (_instr == evmasm::Instruction::CLZ && !m_evmVersion.hasCLZ())\n\t\terrorForVM(4948_error, \"only available for Osaka-compatible\");\n\telse if (_instr == evmasm::Instruction::CREATE2 && !m_evmVersion.hasCreate2())\n\t\terrorForVM(6166_error, \"only available for Constantinople-compatible\");\n\telse if (_instr == evmasm::Instruction::EXTCODEHASH && !m_evmVersion.hasExtCodeHash())\n\t\terrorForVM(7110_error, \"only available for Constantinople-compatible\");\n\telse if (_instr == evmasm::Instruction::CHAINID && !m_evmVersion.hasChainID())\n\t\terrorForVM(1561_error, \"only available for Istanbul-compatible\");\n\telse if (_instr == evmasm::Instruction::SELFBALANCE && !m_evmVersion.hasSelfBalance())\n\t\terrorForVM(7721_error, \"only available for Istanbul-compatible\");\n\telse if (_instr == evmasm::Instruction::BASEFEE && !m_evmVersion.hasBaseFee())\n\t\terrorForVM(5430_error, \"only available for London-compatible\");\n\telse if (_instr == evmasm::Instruction::BLOBBASEFEE && !m_evmVersion.hasBlobBaseFee())\n\t\terrorForVM(6679_error, \"only available for Cancun-compatible\");\n\telse if (_instr == evmasm::Instruction::BLOBHASH && !m_evmVersion.hasBlobHash())\n\t\terrorForVM(8314_error, \"only available for Cancun-compatible\");\n\telse if (_instr == evmasm::Instruction::MCOPY && !m_evmVersion.hasMcopy())\n\t\terrorForVM(7755_error, \"only available for Cancun-compatible\");\n\telse if ((_instr == evmasm::Instruction::TSTORE || _instr == evmasm::Instruction::TLOAD) && !m_evmVersion.supportsTransientStorage())\n\t\terrorForVM(6243_error, \"only available for Cancun-compatible\");\n\telse if (_instr == evmasm::Instruction::PC)\n\t\tm_errorReporter.error(\n\t\t\t2450_error,\n\t\t\tError::Type::SyntaxError,\n\t\t\t_location,\n\t\t\t\"PC instruction is a low-level EVM feature. \"\n\t\t\t\"Because of that PC is disallowed in strict assembly.\"\n\t\t);\n\telse if (!m_eofVersion.has_value() && (\n\t\t_instr == evmasm::Instruction::EXTCALL ||\n\t\t_instr == evmasm::Instruction::EXTDELEGATECALL ||\n\t\t_instr == evmasm::Instruction::EXTSTATICCALL\n\t))\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t4328_error,\n\t\t\t_location,\n\t\t\tfmt::format(\n\t\t\t\t\"The \\\"{instruction}\\\" instruction is only available in EOF.\",\n\t\t\t\tfmt::arg(\"instruction\", boost::to_lower_copy(instructionInfo(_instr, m_evmVersion).name))\n\t\t\t)\n\t\t);\n\t}\n\telse if (m_eofVersion.has_value() && (\n\t\t_instr == evmasm::Instruction::CALL ||\n\t\t_instr == evmasm::Instruction::CALLCODE ||\n\t\t_instr == evmasm::Instruction::DELEGATECALL ||\n\t\t_instr == evmasm::Instruction::STATICCALL ||\n\t\t_instr == evmasm::Instruction::SELFDESTRUCT ||\n\t\t_instr == evmasm::Instruction::JUMP ||\n\t\t_instr == evmasm::Instruction::JUMPI ||\n\t\t_instr == evmasm::Instruction::PC ||\n\t\t_instr == evmasm::Instruction::CREATE ||\n\t\t_instr == evmasm::Instruction::CREATE2 ||\n\t\t_instr == evmasm::Instruction::CODESIZE ||\n\t\t_instr == evmasm::Instruction::CODECOPY ||\n\t\t_instr == evmasm::Instruction::EXTCODESIZE ||\n\t\t_instr == evmasm::Instruction::EXTCODECOPY ||\n\t\t_instr == evmasm::Instruction::EXTCODEHASH ||\n\t\t_instr == evmasm::Instruction::GAS\n\t))\n\t{\n\t\tm_errorReporter.typeError(\n\t\t\t9132_error,\n\t\t\t_location,\n\t\t\tfmt::format(\n\t\t\t\t\"The \\\"{instruction}\\\" instruction is {kind} VMs (you are currently compiling to EOF).\",\n\t\t\t\tfmt::arg(\"instruction\", boost::to_lower_copy(instructionInfo(_instr, m_evmVersion).name)),\n\t\t\t\tfmt::arg(\"kind\", \"only available in legacy bytecode\")\n\t\t\t)\n\t\t);\n\t}\n\telse\n\t{\n\t\t// Sanity check\n\t\tsolAssert(m_evmVersion.hasOpcode(_instr, m_eofVersion));\n\t\treturn false;\n\t}\n\n\t// Sanity check\n\t// PC is not available in strict assembly but it is always valid opcode in legacy evm.\n\tsolAssert(_instr == evmasm::Instruction::PC || !m_evmVersion.hasOpcode(_instr, m_eofVersion));\n\treturn true;\n}\n\nbool AsmAnalyzer::validateInstructions(FunctionCall const& _functionCall)\n{\n\treturn validateInstructions(\n\t\tresolveFunctionName(_functionCall.functionName, m_dialect),\n\t\tnativeLocationOf(_functionCall.functionName)\n\t);\n}\n\nvoid AsmAnalyzer::validateObjectStructure(langutil::SourceLocation const& _astRootLocation)\n{\n\tif (m_eofVersion.has_value())\n\t{\n\t\tif (util::contains(m_objectStructure.objectName, '.')) // No dots in object name for EOF\n\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t9822_error,\n\t\t\t\t_astRootLocation,\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"The object name \\\"{objectName}\\\" is invalid in EOF context. Object names must not contain 'dot' character.\",\n\t\t\t\t\tfmt::arg(\"objectName\", m_objectStructure.objectName)\n\t\t\t\t)\n\t\t\t);\n\t\telse if (m_objectStructure.topLevelSubObjectNames().size() > 256)\n\t\t{\n\t\t\tm_errorReporter.syntaxError(\n\t\t\t\t1305_error,\n\t\t\t\t_astRootLocation,\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"Too many subobjects in \\\"{objectName}\\\". At most 256 subobjects allowed when compiling to EOF\",\n\t\t\t\t\tfmt::arg(\"objectName\", m_objectStructure.objectName)\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "libyul/AsmAnalysis.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Analysis part of inline assembly.\n */\n\n#pragma once\n\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <libyul/ASTForward.h>\n#include <libyul/Dialect.h>\n#include <libyul/Scope.h>\n\n#include <libyul/backends/evm/AbstractAssembly.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/Object.h>\n\n#include <functional>\n#include <list>\n#include <memory>\n#include <optional>\n#include <utility>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\nstruct SourceLocation;\n}\n\nnamespace solidity::yul\n{\n\nstruct AsmAnalysisInfo;\n\n/**\n * Performs the full analysis stage, calls the ScopeFiller internally, then resolves\n * references and performs other checks.\n * If all these checks pass, code generation should not throw errors.\n */\nclass AsmAnalyzer\n{\npublic:\n\texplicit AsmAnalyzer(\n\t\tAsmAnalysisInfo& _analysisInfo,\n\t\tlangutil::ErrorReporter& _errorReporter,\n\t\tDialect const& _dialect,\n\t\tExternalIdentifierAccess::Resolver _resolver = ExternalIdentifierAccess::Resolver(),\n\t\tObject::Structure _objectStructure = {}\n\t):\n\t\tm_resolver(std::move(_resolver)),\n\t\tm_info(_analysisInfo),\n\t\tm_errorReporter(_errorReporter),\n\t\tm_dialect(_dialect),\n\t\tm_objectStructure(std::move(_objectStructure))\n\t{\n\t\tif (EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&m_dialect))\n\t\t{\n\t\t\tm_evmVersion = evmDialect->evmVersion();\n\t\t\tm_eofVersion = evmDialect->eofVersion();\n\t\t}\n\t}\n\n\tbool analyze(Block const& _block);\n\n\t/// Performs analysis on the outermost code of the given object and returns the analysis info.\n\t/// Asserts on failure.\n\tstatic AsmAnalysisInfo analyzeStrictAssertCorrect(Object const& _object);\n\tstatic AsmAnalysisInfo analyzeStrictAssertCorrect(\n\t\tDialect const& _dialect,\n\t\tBlock const& _astRoot,\n\t\tObject::Structure _objectStructure\n\t);\n\tstatic AsmAnalysisInfo analyzeStrictAssertCorrect(\n\t\tDialect const& _dialect,\n\t\tAST const& _ast,\n\t\tObject::Structure _objectStructure\n\t);\n\n\tsize_t operator()(Literal const& _literal);\n\tsize_t operator()(Identifier const&);\n\tvoid operator()(ExpressionStatement const&);\n\tvoid operator()(Assignment const& _assignment);\n\tvoid operator()(VariableDeclaration const& _variableDeclaration);\n\tvoid operator()(FunctionDefinition const& _functionDefinition);\n\tsize_t operator()(FunctionCall const& _functionCall);\n\tvoid operator()(If const& _if);\n\tvoid operator()(Switch const& _switch);\n\tvoid operator()(ForLoop const& _forLoop);\n\tvoid operator()(Break const&) const { }\n\tvoid operator()(Continue const&) const { }\n\tvoid operator()(Leave const&) const { }\n\tvoid operator()(Block const& _block);\n\n\t/// @returns the worst side effects encountered during analysis (including within defined functions).\n\tSideEffects const& sideEffects() const { return m_sideEffects; }\nprivate:\n\t/// Visits the expression, expects that it evaluates to exactly one value.\n\t/// Reports errors otherwise.\n\tvoid expectExpression(Expression const& _expr);\n\tstatic void expectUnlimitedStringLiteral(Literal const& _literal);\n\n\t/// Verifies that a variable to be assigned to exists and can be assigned to.\n\tvoid checkAssignment(Identifier const& _variable);\n\n\tScope& scope(Block const* _block);\n\tvoid expectValidIdentifier(YulName _identifier, langutil::SourceLocation const& _location);\n\n\tbool validateInstructions(evmasm::Instruction _instr, langutil::SourceLocation const& _location);\n\tbool validateInstructions(std::string_view _instrIdentifier, langutil::SourceLocation const& _location);\n\tbool validateInstructions(FunctionCall const& _functionCall);\n\n\tvoid validateObjectStructure(langutil::SourceLocation const& _astRootLocation);\n\n\tyul::ExternalIdentifierAccess::Resolver m_resolver;\n\tScope* m_currentScope = nullptr;\n\t/// Variables that are active at the current point in assembly (as opposed to\n\t/// \"part of the scope but not yet declared\")\n\tstd::set<Scope::Variable const*> m_activeVariables;\n\tAsmAnalysisInfo& m_info;\n\tlangutil::ErrorReporter& m_errorReporter;\n\tlangutil::EVMVersion m_evmVersion;\n\tstd::optional<uint8_t> m_eofVersion;\n\tDialect const& m_dialect;\n\t/// Names of data objects to be referenced by builtin functions with literal arguments.\n\tObject::Structure m_objectStructure;\n\tForLoop const* m_currentForLoop = nullptr;\n\t/// Worst side effects encountered during analysis (including within defined functions).\n\tSideEffects m_sideEffects;\n};\n\n}\n"
  },
  {
    "path": "libyul/AsmAnalysisInfo.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Information generated during analyzer part of inline assembly.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n\n#include <map>\n#include <memory>\n#include <vector>\n\nnamespace solidity::yul\n{\n\nstruct Scope;\n\nstruct AsmAnalysisInfo\n{\n\tusing StackHeightInfo = std::map<void const*, int>;\n\tusing Scopes = std::map<Block const*, std::shared_ptr<Scope>>;\n\tScopes scopes;\n\t/// Virtual blocks which will be used for scopes for function arguments and return values.\n\tstd::map<FunctionDefinition const*, std::shared_ptr<Block const>> virtualBlocks;\n};\n\n}\n"
  },
  {
    "path": "libyul/AsmJsonConverter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @date 2019\n * Converts inline assembly AST to JSON format\n */\n\n#include <libyul/AsmJsonConverter.h>\n\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Utilities.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/UTF8.h>\n\nnamespace solidity::yul\n{\n\nJson AsmJsonConverter::operator()(Block const& _node) const\n{\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulBlock\");\n\tret[\"statements\"] = vectorOfVariantsToJson(_node.statements);\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(NameWithDebugData const& _node) const\n{\n\tyulAssert(!_node.name.empty(), \"Invalid variable name.\");\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulTypedName\");\n\tret[\"name\"] = _node.name.str();\n\t// even though types are removed from Yul, we keep this field in the Json interface to not introduce\n\t// a breaking change\n\t// can be removed with the next breaking version\n\tret[\"type\"] = \"\";\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(Literal const& _node) const\n{\n\tyulAssert(validLiteral(_node));\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulLiteral\");\n\tswitch (_node.kind)\n\t{\n\tcase LiteralKind::Number:\n\t\tret[\"kind\"] = \"number\";\n\t\tbreak;\n\tcase LiteralKind::Boolean:\n\t\tret[\"kind\"] = \"bool\";\n\t\tbreak;\n\tcase LiteralKind::String:\n\t\tret[\"kind\"] = \"string\";\n\t\tret[\"hexValue\"] = util::toHex(util::asBytes(formatLiteral(_node)));\n\t\tbreak;\n\t}\n\tret[\"type\"] = \"\";\n\t{\n\t\tauto const formattedLiteral = formatLiteral(_node);\n\t\tif (util::validateUTF8(formattedLiteral))\n\t\t\tret[\"value\"] = formattedLiteral;\n\t}\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(Identifier const& _node) const\n{\n\tyulAssert(!_node.name.empty(), \"Invalid identifier\");\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulIdentifier\");\n\tret[\"name\"] = _node.name.str();\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(BuiltinName const& _node) const\n{\n\t// represents BuiltinName also with YulIdentifier node type to avoid a breaking change in the JSON interface\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulIdentifier\");\n\tret[\"name\"] = m_dialect.builtin(_node.handle).name;\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(Assignment const& _node) const\n{\n\tyulAssert(_node.variableNames.size() >= 1, \"Invalid assignment syntax\");\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulAssignment\");\n\tfor (auto const& var: _node.variableNames)\n\t\tret[\"variableNames\"].emplace_back((*this)(var));\n\tret[\"value\"] = _node.value ? std::visit(*this, *_node.value) : Json();\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(FunctionCall const& _node) const\n{\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulFunctionCall\");\n\tret[\"functionName\"] = std::visit(*this, _node.functionName);\n\tret[\"arguments\"] = vectorOfVariantsToJson(_node.arguments);\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(ExpressionStatement const& _node) const\n{\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulExpressionStatement\");\n\tret[\"expression\"] = std::visit(*this, _node.expression);\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(VariableDeclaration const& _node) const\n{\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulVariableDeclaration\");\n\tfor (auto const& var: _node.variables)\n\t\tret[\"variables\"].emplace_back((*this)(var));\n\tret[\"value\"] = _node.value ? std::visit(*this, *_node.value) : Json();\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(FunctionDefinition const& _node) const\n{\n\tyulAssert(!_node.name.empty(), \"Invalid function name.\");\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulFunctionDefinition\");\n\tret[\"name\"] = _node.name.str();\n\tfor (auto const& var: _node.parameters)\n\t\tret[\"parameters\"].emplace_back((*this)(var));\n\tfor (auto const& var: _node.returnVariables)\n\t\tret[\"returnVariables\"].emplace_back((*this)(var));\n\tret[\"body\"] = (*this)(_node.body);\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(If const& _node) const\n{\n\tyulAssert(_node.condition, \"Invalid if condition.\");\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulIf\");\n\tret[\"condition\"] = std::visit(*this, *_node.condition);\n\tret[\"body\"] = (*this)(_node.body);\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(Switch const& _node) const\n{\n\tyulAssert(_node.expression, \"Invalid expression pointer.\");\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulSwitch\");\n\tret[\"expression\"] = std::visit(*this, *_node.expression);\n\tfor (auto const& var: _node.cases)\n\t\tret[\"cases\"].emplace_back((*this)(var));\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(Case const& _node) const\n{\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulCase\");\n\tret[\"value\"] = _node.value ? (*this)(*_node.value) : \"default\";\n\tret[\"body\"] = (*this)(_node.body);\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(ForLoop const& _node) const\n{\n\tyulAssert(_node.condition, \"Invalid for loop condition.\");\n\tJson ret = createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulForLoop\");\n\tret[\"pre\"] = (*this)(_node.pre);\n\tret[\"condition\"] = std::visit(*this, *_node.condition);\n\tret[\"post\"] = (*this)(_node.post);\n\tret[\"body\"] = (*this)(_node.body);\n\treturn ret;\n}\n\nJson AsmJsonConverter::operator()(Break const& _node) const\n{\n\treturn createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulBreak\");\n}\n\nJson AsmJsonConverter::operator()(Continue const& _node) const\n{\n\treturn createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulContinue\");\n}\n\nJson AsmJsonConverter::operator()(Leave const& _node) const\n{\n\treturn createAstNode(originLocationOf(_node), nativeLocationOf(_node), \"YulLeave\");\n}\n\nJson AsmJsonConverter::createAstNode(langutil::SourceLocation const& _originLocation, langutil::SourceLocation const& _nativeLocation, std::string _nodeType) const\n{\n\tJson ret;\n\tret[\"nodeType\"] = std::move(_nodeType);\n\tauto srcLocation = [&](int start, int end) -> std::string\n\t{\n\t\tint length = (start >= 0 && end >= 0 && end >= start) ? end - start : -1;\n\t\treturn std::to_string(start) + \":\" + std::to_string(length) + \":\" + (m_sourceIndex.has_value() ? std::to_string(m_sourceIndex.value()) : \"-1\");\n\t};\n\tret[\"src\"] = srcLocation(_originLocation.start, _originLocation.end);\n\tret[\"nativeSrc\"] = srcLocation(_nativeLocation.start, _nativeLocation.end);\n\treturn ret;\n}\n\ntemplate <class T>\nJson AsmJsonConverter::vectorOfVariantsToJson(std::vector<T> const& _vec) const\n{\n\tJson ret = Json::array();\n\tfor (auto const& var: _vec)\n\t\tret.emplace_back(std::visit(*this, var));\n\treturn ret;\n}\n\n}\n"
  },
  {
    "path": "libyul/AsmJsonConverter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @date 2019\n * @author julius <djudju@protonmail.com>\n * Converts inline assembly AST to JSON format\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <liblangutil/SourceLocation.h>\n#include <libsolutil/JSON.h>\n#include <boost/variant/static_visitor.hpp>\n#include <optional>\n#include <vector>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\n\n/**\n * Converter of the yul AST into JSON format\n */\nclass AsmJsonConverter: public boost::static_visitor<Json>\n{\npublic:\n\t/// Create a converter to JSON for any block of inline assembly\n\t/// @a _sourceIndex to be used to abbreviate source name in the source locations\n\tAsmJsonConverter(Dialect const& _dialect, std::optional<size_t> _sourceIndex):\n\t\tm_dialect(_dialect), m_sourceIndex(_sourceIndex) {}\n\n\tJson operator()(Block const& _node) const;\n\tJson operator()(NameWithDebugData const& _node) const;\n\tJson operator()(Literal const& _node) const;\n\tJson operator()(Identifier const& _node) const;\n\tJson operator()(BuiltinName const& _node) const;\n\tJson operator()(Assignment const& _node) const;\n\tJson operator()(VariableDeclaration const& _node) const;\n\tJson operator()(FunctionDefinition const& _node) const;\n\tJson operator()(FunctionCall const& _node) const;\n\tJson operator()(If const& _node) const;\n\tJson operator()(Switch const& _node) const;\n\tJson operator()(Case const& _node) const;\n\tJson operator()(ForLoop const& _node) const;\n\tJson operator()(Break const& _node) const;\n\tJson operator()(Continue const& _node) const;\n\tJson operator()(Leave const& _node) const;\n\tJson operator()(ExpressionStatement const& _node) const;\n\tJson operator()(Label const& _node) const;\n\nprivate:\n\tJson createAstNode(langutil::SourceLocation const& _originLocation, langutil::SourceLocation const& _nativeLocation, std::string _nodeType) const;\n\ttemplate <class T>\n\tJson vectorOfVariantsToJson(std::vector<T> const& vec) const;\n\n\tDialect const& m_dialect;\n\tstd::optional<size_t> const m_sourceIndex;\n};\n\n}\n"
  },
  {
    "path": "libyul/AsmJsonImporter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author julius <djudju@protonmail.com>\n * @date 2019\n * Converts an inlineAssembly AST from JSON format to AsmData\n\n */\n\n#include <libyul/AsmJsonImporter.h>\n\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Utilities.h>\n\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/Scanner.h>\n\n#include <boost/algorithm/string/split.hpp>\n#include <boost/algorithm/string.hpp>\n\n#include <vector>\n\nusing namespace solidity::langutil;\n\nnamespace solidity::yul\n{\n\nusing SourceLocation = langutil::SourceLocation;\n\nSourceLocation const AsmJsonImporter::createSourceLocation(Json const& _node)\n{\n\tyulAssert(member(_node, \"src\").is_string(), \"'src' must be a string\");\n\n\treturn solidity::langutil::parseSourceLocation(_node[\"src\"].get<std::string>(), m_sourceNames);\n}\n\nAST AsmJsonImporter::createAST(solidity::Json const& _node)\n{\n\treturn {m_dialect, createBlock(_node)};\n}\n\ntemplate <class T>\nT AsmJsonImporter::createAsmNode(Json const& _node)\n{\n\tT r;\n\tSourceLocation nativeLocation = createSourceLocation(_node);\n\tyulAssert(nativeLocation.hasText(), \"Invalid source location in Asm AST\");\n\t// TODO: We should add originLocation to the AST.\n\t// While it's not included, we'll use nativeLocation for it because we only support importing\n\t// inline assembly as a part of a Solidity AST and there these locations are always the same.\n\tr.debugData = DebugData::create(nativeLocation, nativeLocation);\n\treturn r;\n}\n\nJson AsmJsonImporter::member(Json const& _node, std::string const& _name)\n{\n\tif (!_node.contains(_name))\n\t\treturn Json();\n\treturn _node[_name];\n}\n\nNameWithDebugData AsmJsonImporter::createNameWithDebugData(Json const& _node)\n{\n\tauto nameWithDebugData = createAsmNode<NameWithDebugData>(_node);\n\tnameWithDebugData.name = YulName{member(_node, \"name\").get<std::string>()};\n\treturn nameWithDebugData;\n}\n\nStatement AsmJsonImporter::createStatement(Json const& _node)\n{\n\tJson jsonNodeType = member(_node, \"nodeType\");\n\tyulAssert(jsonNodeType.is_string(), \"Expected \\\"nodeType\\\" to be of type string!\");\n\tstd::string nodeType = jsonNodeType.get<std::string>();\n\n\tyulAssert(nodeType.substr(0, 3) == \"Yul\", \"Invalid nodeType prefix\");\n\tnodeType = nodeType.substr(3);\n\n\tif (nodeType == \"ExpressionStatement\")\n\t\treturn createExpressionStatement(_node);\n\telse if (nodeType == \"Assignment\")\n\t\treturn createAssignment(_node);\n\telse if (nodeType == \"VariableDeclaration\")\n\t\treturn createVariableDeclaration(_node);\n\telse if (nodeType == \"FunctionDefinition\")\n\t\treturn createFunctionDefinition(_node);\n\telse if (nodeType == \"If\")\n\t\treturn createIf(_node);\n\telse if (nodeType == \"Switch\")\n\t\treturn createSwitch(_node);\n\telse if (nodeType == \"ForLoop\")\n\t\treturn createForLoop(_node);\n\telse if (nodeType == \"Break\")\n\t\treturn createBreak(_node);\n\telse if (nodeType == \"Continue\")\n\t\treturn createContinue(_node);\n\telse if (nodeType == \"Leave\")\n\t\treturn createLeave(_node);\n\telse if (nodeType == \"Block\")\n\t\treturn createBlock(_node);\n\telse\n\t\tyulAssert(false, \"Invalid nodeType as statement\");\n\n\t// FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794)\n\tutil::unreachable();\n}\n\nExpression AsmJsonImporter::createExpression(Json const& _node)\n{\n\tJson jsonNodeType = member(_node, \"nodeType\");\n\tyulAssert(jsonNodeType.is_string(), \"Expected \\\"nodeType\\\" to be of type string!\");\n\tstd::string nodeType = jsonNodeType.get<std::string>();\n\n\tyulAssert(nodeType.substr(0, 3) == \"Yul\", \"Invalid nodeType prefix\");\n\tnodeType = nodeType.substr(3);\n\n\tif (nodeType == \"FunctionCall\")\n\t\treturn createFunctionCall(_node);\n\telse if (nodeType == \"Identifier\")\n\t\treturn createIdentifier(_node);\n\telse if (nodeType == \"Literal\")\n\t\treturn createLiteral(_node);\n\telse\n\t\tyulAssert(false, \"Invalid nodeType as expression\");\n\n\t// FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794)\n\tutil::unreachable();\n}\n\nstd::vector<Expression> AsmJsonImporter::createExpressionVector(Json const& _array)\n{\n\tstd::vector<Expression> ret;\n\tfor (auto& var: _array)\n\t\tret.emplace_back(createExpression(var));\n\treturn ret;\n}\n\nstd::vector<Statement> AsmJsonImporter::createStatementVector(Json const& _array)\n{\n\tstd::vector<Statement> ret;\n\tfor (auto& var: _array)\n\t\tret.emplace_back(createStatement(var));\n\treturn ret;\n}\n\nBlock AsmJsonImporter::createBlock(Json const& _node)\n{\n\tauto block = createAsmNode<Block>(_node);\n\tblock.statements = createStatementVector(_node[\"statements\"]);\n\treturn block;\n}\n\nLiteral AsmJsonImporter::createLiteral(Json const& _node)\n{\n\tauto lit = createAsmNode<Literal>(_node);\n\tstd::string kind = member(_node, \"kind\").get<std::string>();\n\n\tsolAssert(member(_node, \"hexValue\").is_string() || member(_node, \"value\").is_string(), \"\");\n\tstd::string value;\n\tif (_node.contains(\"hexValue\"))\n\t\tvalue = util::asString(util::fromHex(member(_node, \"hexValue\").get<std::string>()));\n\telse\n\t\tvalue = member(_node, \"value\").get<std::string>();\n\t{\n\t\tauto const typeNode = member(_node, \"type\");\n\t\tyulAssert(\n\t\t\ttypeNode.empty() || typeNode.get<std::string>().empty(),\n\t\t\tfmt::format(\n\t\t\t\t\"Expected literal types to be either empty or absent in the JSON. Got \\\"{}\\\".\",\n\t\t\t\ttypeNode.get<std::string>()\n\t\t\t)\n\t\t);\n\t}\n\tif (kind == \"number\")\n\t{\n\t\tlangutil::CharStream charStream(value, \"\");\n\t\tlangutil::Scanner scanner{charStream};\n\t\tlit.kind = LiteralKind::Number;\n\t\tyulAssert(\n\t\t\tscanner.currentToken() == Token::Number,\n\t\t\t\"Expected number but got \" + langutil::TokenTraits::friendlyName(scanner.currentToken()) + std::string(\" while scanning \") + value\n\t\t);\n\t}\n\telse if (kind == \"bool\")\n\t{\n\t\tlangutil::CharStream charStream(value, \"\");\n\t\tlangutil::Scanner scanner{charStream};\n\t\tlit.kind = LiteralKind::Boolean;\n\t\tyulAssert(\n\t\t\tscanner.currentToken() == Token::TrueLiteral ||\n\t\t\tscanner.currentToken() == Token::FalseLiteral,\n\t\t\t\"Expected true/false literal!\"\n\t\t);\n\t}\n\telse if (kind == \"string\")\n\t{\n\t\tlit.kind = LiteralKind::String;\n\t\tyulAssert(\n\t\t\tvalue.size() <= 32,\n\t\t\t\"String literal too long (\" + std::to_string(value.size()) + \" > 32)\"\n\t\t);\n\t}\n\telse\n\t\tyulAssert(false, \"unknown type of literal\");\n\n\t// import only for inline assembly, no unlimited string literals there\n\tlit.value = valueOfLiteral(value, lit.kind, false /* _unlimitedLiteralArgument */);\n\n\tyulAssert(validLiteral(lit));\n\treturn lit;\n}\n\nLeave AsmJsonImporter::createLeave(Json const& _node)\n{\n\treturn createAsmNode<Leave>(_node);\n}\n\nIdentifier AsmJsonImporter::createIdentifier(Json const& _node)\n{\n\tauto identifier = createAsmNode<Identifier>(_node);\n\tidentifier.name = YulName(member(_node, \"name\").get<std::string>());\n\treturn identifier;\n}\n\nAssignment AsmJsonImporter::createAssignment(Json const& _node)\n{\n\tauto assignment = createAsmNode<Assignment>(_node);\n\n\tif (_node.contains(\"variableNames\"))\n\t\tfor (auto const& var: member(_node, \"variableNames\"))\n\t\t\tassignment.variableNames.emplace_back(createIdentifier(var));\n\n\tassignment.value = std::make_unique<Expression>(createExpression(member(_node, \"value\")));\n\treturn assignment;\n}\n\nFunctionCall AsmJsonImporter::createFunctionCall(Json const& _node)\n{\n\tauto functionCall = createAsmNode<FunctionCall>(_node);\n\n\tfor (auto const& var: member(_node, \"arguments\"))\n\t\tfunctionCall.arguments.emplace_back(createExpression(var));\n\n\tauto const functionNameNode = member(_node, \"functionName\");\n\tauto const name = member(functionNameNode, \"name\").get<std::string>();\n\tif (std::optional<BuiltinHandle> builtinHandle = m_dialect.findBuiltin(name))\n\t{\n\t\tauto builtin = createAsmNode<BuiltinName>(functionNameNode);\n\t\tbuiltin.handle = *builtinHandle;\n\t\tfunctionCall.functionName = builtin;\n\t}\n\telse\n\t\tfunctionCall.functionName = createIdentifier(functionNameNode);\n\n\treturn functionCall;\n}\n\nExpressionStatement AsmJsonImporter::createExpressionStatement(Json const& _node)\n{\n\tauto statement = createAsmNode<ExpressionStatement>(_node);\n\tstatement.expression = createExpression(member(_node, \"expression\"));\n\treturn statement;\n}\n\nVariableDeclaration AsmJsonImporter::createVariableDeclaration(Json const& _node)\n{\n\tauto varDec = createAsmNode<VariableDeclaration>(_node);\n\tfor (auto const& var: member(_node, \"variables\"))\n\t\tvarDec.variables.emplace_back(createNameWithDebugData(var));\n\n\tif (_node.contains(\"value\"))\n\t\tvarDec.value = std::make_unique<Expression>(createExpression(member(_node, \"value\")));\n\n\treturn varDec;\n}\n\nFunctionDefinition AsmJsonImporter::createFunctionDefinition(Json const& _node)\n{\n\tauto funcDef = createAsmNode<FunctionDefinition>(_node);\n\tfuncDef.name = YulName{member(_node, \"name\").get<std::string>()};\n\n\tif (_node.contains(\"parameters\"))\n\t\tfor (auto const& var: member(_node, \"parameters\"))\n\t\t\tfuncDef.parameters.emplace_back(createNameWithDebugData(var));\n\n\tif (_node.contains(\"returnVariables\"))\n\t\tfor (auto const& var: member(_node, \"returnVariables\"))\n\t\t\tfuncDef.returnVariables.emplace_back(createNameWithDebugData(var));\n\n\tfuncDef.body = createBlock(member(_node, \"body\"));\n\treturn funcDef;\n}\n\nIf AsmJsonImporter::createIf(Json const& _node)\n{\n\tauto ifStatement = createAsmNode<If>(_node);\n\tifStatement.condition = std::make_unique<Expression>(createExpression(member(_node, \"condition\")));\n\tifStatement.body = createBlock(member(_node, \"body\"));\n\treturn ifStatement;\n}\n\nCase AsmJsonImporter::createCase(Json const& _node)\n{\n\tauto caseStatement = createAsmNode<Case>(_node);\n\tauto const& value = member(_node, \"value\");\n\tif (value.is_string())\n\t\tyulAssert(value.get<std::string>() == \"default\", \"Expected default case\");\n\telse\n\t\tcaseStatement.value = std::make_unique<Literal>(createLiteral(value));\n\tcaseStatement.body = createBlock(member(_node, \"body\"));\n\treturn caseStatement;\n}\n\nSwitch AsmJsonImporter::createSwitch(Json const& _node)\n{\n\tauto switchStatement = createAsmNode<Switch>(_node);\n\tswitchStatement.expression = std::make_unique<Expression>(createExpression(member(_node, \"expression\")));\n\tfor (auto const& var: member(_node, \"cases\"))\n\t\tswitchStatement.cases.emplace_back(createCase(var));\n\treturn switchStatement;\n}\n\nForLoop AsmJsonImporter::createForLoop(Json const& _node)\n{\n\tauto forLoop = createAsmNode<ForLoop>(_node);\n\tforLoop.pre = createBlock(member(_node, \"pre\"));\n\tforLoop.condition = std::make_unique<Expression>(createExpression(member(_node, \"condition\")));\n\tforLoop.post = createBlock(member(_node, \"post\"));\n\tforLoop.body = createBlock(member(_node, \"body\"));\n\treturn forLoop;\n}\n\nBreak AsmJsonImporter::createBreak(Json const& _node)\n{\n\treturn createAsmNode<Break>(_node);\n}\n\nContinue AsmJsonImporter::createContinue(Json const& _node)\n{\n\treturn createAsmNode<Continue>(_node);\n}\n\n}\n"
  },
  {
    "path": "libyul/AsmJsonImporter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author julius <djudju@protonmail.com>\n * @date 2019\n * Converts an inlineAssembly AST from JSON format to AsmData\n */\n\n#pragma once\n\n#include <libsolutil/JSON.h>\n#include <liblangutil/SourceLocation.h>\n#include <libyul/ASTForward.h>\n\n#include <utility>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\n\n/**\n * Component that imports an AST from json format to the internal format\n */\nclass AsmJsonImporter\n{\npublic:\n\texplicit AsmJsonImporter(Dialect const& _dialect, std::vector<std::shared_ptr<std::string const>> const& _sourceNames):\n\t\tm_dialect(_dialect),\n\t\tm_sourceNames(_sourceNames)\n\t{}\n\n\tyul::AST createAST(Json const& node);\nprivate:\n\tlangutil::SourceLocation const createSourceLocation(Json const& _node);\n\ttemplate <class T>\n\tT createAsmNode(Json const& _node);\n\t/// helper function to access member functions of the JSON\n\t/// and throw an error if it does not exist\n\tJson member(Json const& _node, std::string const& _name);\n\n\tyul::Block createBlock(Json const& _node);\n\tyul::Statement createStatement(Json const& _node);\n\tyul::Expression createExpression(Json const& _node);\n\tstd::vector<yul::Statement> createStatementVector(Json const& _array);\n\tstd::vector<yul::Expression> createExpressionVector(Json const& _array);\n\n\tyul::NameWithDebugData createNameWithDebugData(Json const& _node);\n\tyul::Literal createLiteral(Json const& _node);\n\tyul::Leave createLeave(Json const& _node);\n\tyul::Identifier createIdentifier(Json const& _node);\n\tyul::Assignment createAssignment(Json const& _node);\n\tyul::FunctionCall createFunctionCall(Json const& _node);\n\tyul::ExpressionStatement createExpressionStatement(Json const& _node);\n\tyul::VariableDeclaration createVariableDeclaration(Json const& _node);\n\tyul::FunctionDefinition createFunctionDefinition(Json const& _node);\n\tyul::If createIf(Json const& _node);\n\tyul::Case createCase(Json const& _node);\n\tyul::Switch createSwitch(Json const& _node);\n\tyul::ForLoop createForLoop(Json const& _node);\n\tyul::Break createBreak(Json const& _node);\n\tyul::Continue createContinue(Json const& _node);\n\n\tDialect const& m_dialect;\n\tstd::vector<std::shared_ptr<std::string const>> const& m_sourceNames;\n};\n\n}\n"
  },
  {
    "path": "libyul/AsmParser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2016\n * Solidity inline assembly parser.\n */\n\n#include <libyul/AST.h>\n#include <libyul/AsmParser.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Utilities.h>\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/Scanner.h>\n#include <liblangutil/Common.h>\n#include <libsolutil/Common.h>\n#include <libsolutil/Visitor.h>\n\n#include <boost/algorithm/string.hpp>\n\n#include <algorithm>\n#include <regex>\n\nusing namespace std::string_literals;\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\nusing namespace solidity::yul;\n\nnamespace\n{\n\nstd::optional<int> toInt(std::string const& _value)\n{\n\ttry\n\t{\n\t\treturn stoi(_value);\n\t}\n\tcatch (std::out_of_range const&)\n\t{\n\t\treturn std::nullopt;\n\t}\n}\n\n}\n\nlangutil::DebugData::ConstPtr Parser::createDebugData() const\n{\n\tswitch (m_useSourceLocationFrom)\n\t{\n\t\tcase UseSourceLocationFrom::Scanner:\n\t\t\treturn DebugData::create(ParserBase::currentLocation(), ParserBase::currentLocation());\n\t\tcase UseSourceLocationFrom::LocationOverride:\n\t\t\treturn DebugData::create(m_locationOverride, m_locationOverride);\n\t\tcase UseSourceLocationFrom::Comments:\n\t\t\treturn DebugData::create(ParserBase::currentLocation(), m_locationFromComment, m_astIDFromComment);\n\t}\n\tsolAssert(false, \"\");\n}\n\nvoid Parser::updateLocationEndFrom(\n\tlangutil::DebugData::ConstPtr& _debugData,\n\tSourceLocation const& _location\n) const\n{\n\tsolAssert(_debugData, \"\");\n\n\tswitch (m_useSourceLocationFrom)\n\t{\n\t\tcase UseSourceLocationFrom::Scanner:\n\t\t{\n\t\t\tDebugData updatedDebugData = *_debugData;\n\t\t\tupdatedDebugData.nativeLocation.end = _location.end;\n\t\t\tupdatedDebugData.originLocation.end = _location.end;\n\t\t\t_debugData = std::make_shared<DebugData const>(std::move(updatedDebugData));\n\t\t\tbreak;\n\t\t}\n\t\tcase UseSourceLocationFrom::LocationOverride:\n\t\t\t// Ignore the update. The location we're overriding with is not supposed to change\n\t\t\tbreak;\n\t\tcase UseSourceLocationFrom::Comments:\n\t\t{\n\t\t\tDebugData updatedDebugData = *_debugData;\n\t\t\tupdatedDebugData.nativeLocation.end = _location.end;\n\t\t\t_debugData = std::make_shared<DebugData const>(std::move(updatedDebugData));\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstd::unique_ptr<AST> Parser::parse(CharStream& _charStream)\n{\n\tm_scanner = std::make_shared<Scanner>(_charStream);\n\tstd::unique_ptr<AST> ast = parseInline(m_scanner);\n\texpectToken(Token::EOS);\n\treturn ast;\n}\n\nstd::unique_ptr<AST> Parser::parseInline(std::shared_ptr<Scanner> const& _scanner)\n{\n\tm_recursionDepth = 0;\n\n\tauto previousScannerKind = _scanner->scannerKind();\n\t_scanner->setScannerMode(ScannerKind::Yul);\n\tScopeGuard resetScanner([&]{ _scanner->setScannerMode(previousScannerKind); });\n\n\ttry\n\t{\n\t\tm_scanner = _scanner;\n\t\tif (m_useSourceLocationFrom == UseSourceLocationFrom::Comments)\n\t\t\tfetchDebugDataFromComment();\n\t\treturn std::make_unique<AST>(m_dialect, parseBlock());\n\t}\n\tcatch (FatalError const&)\n\t{\n\t\tif (!m_errorReporter.hasErrors())\n\t\t{\n\t\t\tstd::cerr << \"Unreported fatal error:\" << std::endl;\n\t\t\tstd::cerr << boost::current_exception_diagnostic_information() << std::endl;\n\t\t\tyulAssert(false, \"Unreported fatal error.\");\n\t\t}\n\t}\n\n\treturn nullptr;\n}\n\nlangutil::Token Parser::advance()\n{\n\tauto const token = ParserBase::advance();\n\tif (m_useSourceLocationFrom == UseSourceLocationFrom::Comments)\n\t\tfetchDebugDataFromComment();\n\treturn token;\n}\n\nvoid Parser::fetchDebugDataFromComment()\n{\n\tsolAssert(m_sourceNames.has_value(), \"\");\n\n\tstd::string_view commentLiteral = m_scanner->currentCommentLiteral();\n\tif (commentLiteral.empty())\n\t{\n\t\tm_astIDFromComment = std::nullopt;\n\t\treturn;\n\t}\n\tstatic std::regex const tagRegex = std::regex(\n\t\tR\"~~((?:^|\\s+)(@[a-zA-Z0-9\\-_]+)(?:\\s+|$))~~\", // tag, e.g: @src\n\t\tstd::regex_constants::ECMAScript | std::regex_constants::optimize\n\t);\n\n\tstd::match_results<std::string_view::const_iterator> match;\n\n\tlangutil::SourceLocation originLocation = m_locationFromComment;\n\t// Empty for each new node.\n\tstd::optional<int> astID;\n\n\twhile (regex_search(commentLiteral.cbegin(), commentLiteral.cend(), match, tagRegex))\n\t{\n\t\tsolAssert(match.size() == 2, \"\");\n\t\tcommentLiteral = commentLiteral.substr(static_cast<size_t>(match.position() + match.length()));\n\n\t\tif (match[1] == \"@src\")\n\t\t{\n\t\t\tif (auto parseResult = parseSrcComment(commentLiteral, m_scanner->currentCommentLocation()))\n\t\t\t\ttie(commentLiteral, originLocation) = *parseResult;\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t\telse if (match[1] == \"@ast-id\")\n\t\t{\n\t\t\tif (auto parseResult = parseASTIDComment(commentLiteral, m_scanner->currentCommentLocation()))\n\t\t\t\ttie(commentLiteral, astID) = *parseResult;\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\t// Ignore unrecognized tags.\n\t\t\tcontinue;\n\t}\n\n\tm_locationFromComment = originLocation;\n\tm_astIDFromComment = astID;\n}\n\nstd::optional<std::pair<std::string_view, SourceLocation>> Parser::parseSrcComment(\n\tstd::string_view const _arguments,\n\tlangutil::SourceLocation const& _commentLocation\n)\n{\n\tCharStream argumentStream(std::string(_arguments), \"\");\n\tScanner scanner(argumentStream, ScannerKind::SpecialComment);\n\n\tstd::string_view tail{_arguments.substr(_arguments.size())};\n\tauto const parseLocationComponent = [](Scanner& _scanner, bool expectTrailingColon) -> std::optional<std::string>\n\t{\n\t\tbool negative = false;\n\t\tif (_scanner.currentToken() == Token::Sub)\n\t\t{\n\t\t\tnegative = true;\n\t\t\t_scanner.next();\n\t\t}\n\t\tif (_scanner.currentToken() != Token::Number)\n\t\t\treturn std::nullopt;\n\t\tif (expectTrailingColon && _scanner.peekNextToken() != Token::Colon)\n\t\t\treturn std::nullopt;\n\t\tif (!isValidDecimal(_scanner.currentLiteral()))\n\t\t\treturn std::nullopt;\n\t\tstd::string decimal = (negative ? \"-\" : \"\") + _scanner.currentLiteral();\n\t\t_scanner.next();\n\t\tif (expectTrailingColon)\n\t\t\t_scanner.next();\n\t\treturn decimal;\n\t};\n\tstd::optional<std::string> rawSourceIndex = parseLocationComponent(scanner, true);\n\tstd::optional<std::string> rawStart = parseLocationComponent(scanner, true);\n\tstd::optional<std::string> rawEnd = parseLocationComponent(scanner, false);\n\n\tsize_t const snippetStart = static_cast<size_t>(scanner.currentLocation().start);\n\tbool const locationScannedSuccessfully = rawSourceIndex && rawStart && rawEnd;\n\tbool const locationIsWhitespaceSeparated =\n\t\tscanner.peekNextToken() == Token::EOS ||\n\t\t(snippetStart > 0 && langutil::isWhiteSpace(_arguments[snippetStart - 1]));\n\n\tif (!locationScannedSuccessfully || !locationIsWhitespaceSeparated)\n\t{\n\t\tm_errorReporter.syntaxError(\n\t\t\t8387_error,\n\t\t\t_commentLocation,\n\t\t\t\"Invalid values in source location mapping. Could not parse location specification.\"\n\t\t);\n\t\treturn std::nullopt;\n\t}\n\n\t// captures error cases `\"test` (illegal end quote) and `\"test\\` (illegal escape sequence / dangling backslash)\n\tbool const illegalLiteral = scanner.currentToken() == Token::Illegal && (scanner.currentError() == ScannerError::IllegalStringEndQuote || scanner.currentError() == ScannerError::IllegalEscapeSequence);\n\tif (scanner.currentToken() == Token::StringLiteral || illegalLiteral)\n\t\ttail = _arguments.substr(static_cast<size_t>(scanner.currentLocation().end));\n\telse\n\t\ttail = _arguments.substr(static_cast<size_t>(scanner.currentLocation().start));\n\n\t// Other scanner errors may occur if there is no string literal which follows\n\t// (f.ex. IllegalHexDigit, IllegalCommentTerminator), but these are ignored\n\tif (illegalLiteral)\n\t{\n\t\tm_errorReporter.syntaxError(\n\t\t\t1544_error,\n\t\t\t_commentLocation,\n\t\t\t\"Invalid code snippet in source location mapping. Quote is not terminated.\"\n\t\t);\n\t\treturn {{tail, SourceLocation{}}};\n\t}\n\n\tstd::optional<int> const sourceIndex = toInt(*rawSourceIndex);\n\tstd::optional<int> const start = toInt(*rawStart);\n\tstd::optional<int> const end = toInt(*rawEnd);\n\n\tif (\n\t\t!sourceIndex.has_value() || *sourceIndex < -1 ||\n\t\t!start.has_value() || *start < -1 ||\n\t\t!end.has_value() || *end < -1\n\t)\n\t\tm_errorReporter.syntaxError(\n\t\t\t6367_error,\n\t\t\t_commentLocation,\n\t\t\t\"Invalid value in source location mapping. \"\n\t\t\t\"Expected non-negative integer values or -1 for source index and location.\"\n\t\t);\n\telse if (sourceIndex == -1)\n\t\treturn {{tail, SourceLocation{*start, *end, nullptr}}};\n\telse if (!(sourceIndex >= 0 && m_sourceNames->count(static_cast<unsigned>(*sourceIndex))))\n\t\tm_errorReporter.syntaxError(\n\t\t\t2674_error,\n\t\t\t_commentLocation,\n\t\t\t\"Invalid source mapping. Source index not defined via @use-src.\"\n\t\t);\n\telse\n\t{\n\t\tstd::shared_ptr<std::string const> sourceName = m_sourceNames->at(static_cast<unsigned>(*sourceIndex));\n\t\tsolAssert(sourceName, \"\");\n\t\treturn {{tail, SourceLocation{*start, *end, std::move(sourceName)}}};\n\t}\n\treturn {{tail, SourceLocation{}}};\n}\n\nstd::optional<std::pair<std::string_view, std::optional<int>>> Parser::parseASTIDComment(\n\tstd::string_view _arguments,\n\tlangutil::SourceLocation const& _commentLocation\n)\n{\n\tstatic std::regex const argRegex = std::regex(\n\t\tR\"~~(^(\\d+)(?:\\s|$))~~\",\n\t\tstd::regex_constants::ECMAScript | std::regex_constants::optimize\n\t);\n\tstd::match_results<std::string_view::const_iterator> match;\n\tstd::optional<int> astID;\n\tbool matched = regex_search(_arguments.cbegin(), _arguments.cend(), match, argRegex);\n\tstd::string_view tail = _arguments;\n\tif (matched)\n\t{\n\t\tsolAssert(match.size() == 2, \"\");\n\t\ttail = _arguments.substr(static_cast<size_t>(match.position() + match.length()));\n\n\t\tastID = toInt(match[1].str());\n\t}\n\n\tif (!matched || !astID || *astID < 0 || static_cast<int64_t>(*astID) != *astID)\n\t{\n\t\tm_errorReporter.syntaxError(1749_error, _commentLocation, \"Invalid argument for @ast-id.\");\n\t\tastID = std::nullopt;\n\t}\n\tif (matched)\n\t\treturn {{_arguments, astID}};\n\telse\n\t\treturn std::nullopt;\n}\n\nBlock Parser::parseBlock()\n{\n\tRecursionGuard recursionGuard(*this);\n\tBlock block = createWithDebugData<Block>();\n\texpectToken(Token::LBrace);\n\twhile (currentToken() != Token::RBrace)\n\t\tblock.statements.emplace_back(parseStatement());\n\tupdateLocationEndFrom(block.debugData, currentLocation());\n\tadvance();\n\treturn block;\n}\n\nStatement Parser::parseStatement()\n{\n\tRecursionGuard recursionGuard(*this);\n\tswitch (currentToken())\n\t{\n\tcase Token::Let:\n\t\treturn parseVariableDeclaration();\n\tcase Token::Function:\n\t\treturn parseFunctionDefinition();\n\tcase Token::LBrace:\n\t\treturn parseBlock();\n\tcase Token::If:\n\t{\n\t\tIf _if = createWithDebugData<If>();\n\t\tadvance();\n\t\t_if.condition = std::make_unique<Expression>(parseExpression());\n\t\t_if.body = parseBlock();\n\t\tupdateLocationEndFrom(_if.debugData, nativeLocationOf(_if.body));\n\t\treturn Statement{std::move(_if)};\n\t}\n\tcase Token::Switch:\n\t{\n\t\tSwitch _switch = createWithDebugData<Switch>();\n\t\tadvance();\n\t\t_switch.expression = std::make_unique<Expression>(parseExpression());\n\t\twhile (currentToken() == Token::Case)\n\t\t\t_switch.cases.emplace_back(parseCase());\n\t\tif (currentToken() == Token::Default)\n\t\t\t_switch.cases.emplace_back(parseCase());\n\t\tif (currentToken() == Token::Default)\n\t\t\tfatalParserError(6931_error, \"Only one default case allowed.\");\n\t\telse if (currentToken() == Token::Case)\n\t\t\tfatalParserError(4904_error, \"Case not allowed after default case.\");\n\t\tif (_switch.cases.empty())\n\t\t\tfatalParserError(2418_error, \"Switch statement without any cases.\");\n\t\tupdateLocationEndFrom(_switch.debugData, nativeLocationOf(_switch.cases.back().body));\n\t\treturn Statement{std::move(_switch)};\n\t}\n\tcase Token::For:\n\t\treturn parseForLoop();\n\tcase Token::Break:\n\t{\n\t\tStatement stmt{createWithDebugData<Break>()};\n\t\tcheckBreakContinuePosition(\"break\");\n\t\tadvance();\n\t\treturn stmt;\n\t}\n\tcase Token::Continue:\n\t{\n\t\tStatement stmt{createWithDebugData<Continue>()};\n\t\tcheckBreakContinuePosition(\"continue\");\n\t\tadvance();\n\t\treturn stmt;\n\t}\n\tcase Token::Leave:\n\t{\n\t\tStatement stmt{createWithDebugData<Leave>()};\n\t\tif (!m_insideFunction)\n\t\t\tm_errorReporter.syntaxError(8149_error, currentLocation(), \"Keyword \\\"leave\\\" can only be used inside a function.\");\n\t\tadvance();\n\t\treturn stmt;\n\t}\n\tdefault:\n\t\tbreak;\n\t}\n\n\t// Options left:\n\t// Expression/FunctionCall\n\t// Assignment\n\tstd::variant<Literal, Identifier, BuiltinName> elementary(parseLiteralOrIdentifier());\n\n\tswitch (currentToken())\n\t{\n\tcase Token::LParen:\n\t{\n\t\tExpression expr = parseCall(std::move(elementary));\n\t\treturn ExpressionStatement{debugDataOf(expr), std::move(expr)};\n\t}\n\tcase Token::Comma:\n\tcase Token::AssemblyAssign:\n\t{\n\t\tAssignment assignment;\n\t\tassignment.debugData = debugDataOf(elementary);\n\n\t\tbool foundListEnd = false;\n\t\tdo\n\t\t{\n\t\t\tstd::visit(GenericVisitor{\n\t\t\t\t[&](Literal const&)\n\t\t\t\t{\n\t\t\t\t\tauto const token = currentToken() == Token::Comma ? \",\" : \":=\";\n\n\t\t\t\t\tfatalParserError(\n\t\t\t\t\t\t2856_error,\n\t\t\t\t\t\tstd::string(\"Variable name must precede \\\"\") +\n\t\t\t\t\t\ttoken +\n\t\t\t\t\t\t\"\\\"\" +\n\t\t\t\t\t\t(currentToken() == Token::Comma ? \" in multiple assignment.\" : \" in assignment.\")\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t[&](BuiltinName const& _builtin)\n\t\t\t\t{\n\t\t\t\t\tfatalParserError(\n\t\t\t\t\t\t6272_error,\n\t\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\t\"Cannot assign to builtin function \\\"{}\\\".\",\n\t\t\t\t\t\t\tm_dialect.builtin(_builtin.handle).name\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t[&](Identifier const& _identifier)\n\t\t\t\t{\n\t\t\t\t\tassignment.variableNames.emplace_back(_identifier);\n\n\t\t\t\t\tif (currentToken() != Token::Comma)\n\t\t\t\t\t\tfoundListEnd = true;\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\texpectToken(Token::Comma);\n\t\t\t\t\t\telementary = parseLiteralOrIdentifier();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, elementary);\n\n\t\t} while (!foundListEnd);\n\n\t\texpectToken(Token::AssemblyAssign);\n\n\t\tassignment.value = std::make_unique<Expression>(parseExpression());\n\t\tupdateLocationEndFrom(assignment.debugData, nativeLocationOf(*assignment.value));\n\n\t\treturn Statement{std::move(assignment)};\n\t}\n\tdefault:\n\t\tfatalParserError(6913_error, \"Call or assignment expected.\");\n\t\tbreak;\n\t}\n\n\tyulAssert(false, \"\");\n\treturn {};\n}\n\nCase Parser::parseCase()\n{\n\tRecursionGuard recursionGuard(*this);\n\tCase _case = createWithDebugData<Case>();\n\tif (currentToken() == Token::Default)\n\t\tadvance();\n\telse if (currentToken() == Token::Case)\n\t{\n\t\tadvance();\n\t\tstd::variant<Literal, Identifier, BuiltinName> literal = parseLiteralOrIdentifier();\n\t\tif (!std::holds_alternative<Literal>(literal))\n\t\t\tfatalParserError(4805_error, \"Literal expected.\");\n\t\t_case.value = std::make_unique<Literal>(std::get<Literal>(std::move(literal)));\n\t}\n\telse\n\t\tyulAssert(false, \"Case or default case expected.\");\n\t_case.body = parseBlock();\n\tupdateLocationEndFrom(_case.debugData, nativeLocationOf(_case.body));\n\treturn _case;\n}\n\nForLoop Parser::parseForLoop()\n{\n\tRecursionGuard recursionGuard(*this);\n\n\tForLoopComponent outerForLoopComponent = m_currentForLoopComponent;\n\n\tForLoop forLoop = createWithDebugData<ForLoop>();\n\texpectToken(Token::For);\n\tm_currentForLoopComponent = ForLoopComponent::ForLoopPre;\n\tforLoop.pre = parseBlock();\n\tm_currentForLoopComponent = ForLoopComponent::None;\n\tforLoop.condition = std::make_unique<Expression>(parseExpression());\n\tm_currentForLoopComponent = ForLoopComponent::ForLoopPost;\n\tforLoop.post = parseBlock();\n\tm_currentForLoopComponent = ForLoopComponent::ForLoopBody;\n\tforLoop.body = parseBlock();\n\tupdateLocationEndFrom(forLoop.debugData, nativeLocationOf(forLoop.body));\n\n\tm_currentForLoopComponent = outerForLoopComponent;\n\n\treturn forLoop;\n}\n\nExpression Parser::parseExpression(bool _unlimitedLiteralArgument)\n{\n\tRecursionGuard recursionGuard(*this);\n\n\tstd::variant<Literal, Identifier, BuiltinName> operation = parseLiteralOrIdentifier(_unlimitedLiteralArgument);\n\treturn visit(GenericVisitor{\n\t\t[&](Identifier& _identifier) -> Expression\n\t\t{\n\t\t\tif (currentToken() == Token::LParen)\n\t\t\t\treturn parseCall(std::move(operation));\n\t\t\treturn std::move(_identifier);\n\t\t},\n\t\t[&](BuiltinName& _builtin) -> Expression\n\t\t{\n\t\t\tif (currentToken() == Token::LParen)\n\t\t\t\treturn parseCall(std::move(operation));\n\t\t\tfatalParserError(\n\t\t\t\t7104_error,\n\t\t\t\tnativeLocationOf(_builtin),\n\t\t\t\t\"Builtin function \\\"\" + m_dialect.builtin(_builtin.handle).name + \"\\\" must be called.\"\n\t\t\t);\n\t\t\tunreachable();\n\t\t},\n\t\t[&](Literal& _literal) -> Expression\n\t\t{\n\t\t\treturn std::move(_literal);\n\t\t}\n\t}, operation);\n}\n\nstd::variant<Literal, Identifier, BuiltinName> Parser::parseLiteralOrIdentifier(bool _unlimitedLiteralArgument)\n{\n\tRecursionGuard recursionGuard(*this);\n\tswitch (currentToken())\n\t{\n\tcase Token::Identifier:\n\t{\n\t\tstd::variant<Literal, Identifier, BuiltinName> literalOrIdentifier;\n\t\tif (std::optional<BuiltinHandle> const builtinHandle = m_dialect.findBuiltin(currentLiteral()))\n\t\t\tliteralOrIdentifier = BuiltinName{createDebugData(), *builtinHandle};\n\t\telse\n\t\t\tliteralOrIdentifier = Identifier{createDebugData(), YulName{currentLiteral()}};\n\t\tadvance();\n\t\treturn literalOrIdentifier;\n\t}\n\tcase Token::StringLiteral:\n\tcase Token::HexStringLiteral:\n\tcase Token::Number:\n\tcase Token::TrueLiteral:\n\tcase Token::FalseLiteral:\n\t{\n\t\tLiteralKind kind = LiteralKind::Number;\n\t\tswitch (currentToken())\n\t\t{\n\t\tcase Token::StringLiteral:\n\t\tcase Token::HexStringLiteral:\n\t\t\tkind = LiteralKind::String;\n\t\t\tbreak;\n\t\tcase Token::Number:\n\t\t\tif (!isValidNumberLiteral(currentLiteral()))\n\t\t\t\tfatalParserError(4828_error, \"Invalid number literal.\");\n\t\t\tkind = LiteralKind::Number;\n\t\t\tbreak;\n\t\tcase Token::TrueLiteral:\n\t\tcase Token::FalseLiteral:\n\t\t\tkind = LiteralKind::Boolean;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tauto const literalLocation = currentLocation();\n\t\tLiteral literal{\n\t\t\tcreateDebugData(),\n\t\t\tkind,\n\t\t\tvalueOfLiteral(currentLiteral(), kind, _unlimitedLiteralArgument && kind == LiteralKind::String)\n\t\t};\n\t\tadvance();\n\t\tif (currentToken() == Token::Colon)\n\t\t{\n\t\t\texpectToken(Token::Colon);\n\t\t\tupdateLocationEndFrom(literal.debugData, currentLocation());\n\t\t\tauto const typedLiteralLocation = SourceLocation::smallestCovering(literalLocation, currentLocation());\n\t\t\tstd::ignore = expectAsmIdentifier();\n\t\t\traiseUnsupportedTypesError(typedLiteralLocation);\n\t\t}\n\n\t\treturn literal;\n\t}\n\tcase Token::Illegal:\n\t\tfatalParserError(1465_error, \"Illegal token: \" + to_string(m_scanner->currentError()));\n\t\tbreak;\n\tdefault:\n\t\tfatalParserError(1856_error, \"Literal or identifier expected.\");\n\t}\n\treturn {};\n}\n\nVariableDeclaration Parser::parseVariableDeclaration()\n{\n\tRecursionGuard recursionGuard(*this);\n\tVariableDeclaration varDecl = createWithDebugData<VariableDeclaration>();\n\texpectToken(Token::Let);\n\twhile (true)\n\t{\n\t\tvarDecl.variables.emplace_back(parseNameWithDebugData());\n\t\tif (currentToken() == Token::Comma)\n\t\t\texpectToken(Token::Comma);\n\t\telse\n\t\t\tbreak;\n\t}\n\tif (currentToken() == Token::AssemblyAssign)\n\t{\n\t\texpectToken(Token::AssemblyAssign);\n\t\tvarDecl.value = std::make_unique<Expression>(parseExpression());\n\t\tupdateLocationEndFrom(varDecl.debugData, nativeLocationOf(*varDecl.value));\n\t}\n\telse\n\t\tupdateLocationEndFrom(varDecl.debugData, nativeLocationOf(varDecl.variables.back()));\n\n\treturn varDecl;\n}\n\nFunctionDefinition Parser::parseFunctionDefinition()\n{\n\tRecursionGuard recursionGuard(*this);\n\n\tif (m_currentForLoopComponent == ForLoopComponent::ForLoopPre)\n\t\tm_errorReporter.syntaxError(\n\t\t\t3441_error,\n\t\t\tcurrentLocation(),\n\t\t\t\"Functions cannot be defined inside a for-loop init block.\"\n\t\t);\n\n\tForLoopComponent outerForLoopComponent = m_currentForLoopComponent;\n\tm_currentForLoopComponent = ForLoopComponent::None;\n\n\tFunctionDefinition funDef = createWithDebugData<FunctionDefinition>();\n\texpectToken(Token::Function);\n\tfunDef.name = expectAsmIdentifier();\n\texpectToken(Token::LParen);\n\twhile (currentToken() != Token::RParen)\n\t{\n\t\tfunDef.parameters.emplace_back(parseNameWithDebugData());\n\t\tif (currentToken() == Token::RParen)\n\t\t\tbreak;\n\t\texpectToken(Token::Comma);\n\t}\n\texpectToken(Token::RParen);\n\tif (currentToken() == Token::RightArrow)\n\t{\n\t\texpectToken(Token::RightArrow);\n\t\twhile (true)\n\t\t{\n\t\t\tfunDef.returnVariables.emplace_back(parseNameWithDebugData());\n\t\t\tif (currentToken() == Token::LBrace)\n\t\t\t\tbreak;\n\t\t\texpectToken(Token::Comma);\n\t\t}\n\t}\n\tbool preInsideFunction = m_insideFunction;\n\tm_insideFunction = true;\n\tfunDef.body = parseBlock();\n\tm_insideFunction = preInsideFunction;\n\tupdateLocationEndFrom(funDef.debugData, nativeLocationOf(funDef.body));\n\n\tm_currentForLoopComponent = outerForLoopComponent;\n\treturn funDef;\n}\n\nFunctionCall Parser::parseCall(std::variant<Literal, Identifier, BuiltinName>&& _initialOp)\n{\n\tRecursionGuard recursionGuard(*this);\n\n\tstd::function isUnlimitedLiteralArgument = [](size_t) -> bool { return false; };\n\tFunctionCall functionCall;\n\tstd::visit(GenericVisitor{\n\t\t[&](Literal const&) { fatalParserError(9980_error, \"Function name expected.\"); },\n\t\t[&](Identifier const& _identifier)\n\t\t{\n\t\t\tfunctionCall.debugData = _identifier.debugData;\n\t\t\tfunctionCall.functionName = _identifier;\n\t\t},\n\t\t[&](BuiltinName const& _builtin)\n\t\t{\n\t\t\tisUnlimitedLiteralArgument = [builtinFunction=m_dialect.builtin(_builtin.handle)](size_t _index) {\n\t\t\t\tif (_index < builtinFunction.literalArguments.size())\n\t\t\t\t\treturn builtinFunction.literalArgument(_index).has_value();\n\t\t\t\treturn false;\n\t\t\t};\n\t\t\tfunctionCall.debugData = _builtin.debugData;\n\t\t\tfunctionCall.functionName = _builtin;\n\t\t}\n\t}, _initialOp);\n\n\tsize_t argumentIndex {0};\n\texpectToken(Token::LParen);\n\tif (currentToken() != Token::RParen)\n\t{\n\t\tfunctionCall.arguments.emplace_back(parseExpression(isUnlimitedLiteralArgument(argumentIndex++)));\n\t\twhile (currentToken() != Token::RParen)\n\t\t{\n\t\t\texpectToken(Token::Comma);\n\t\t\tfunctionCall.arguments.emplace_back(parseExpression(isUnlimitedLiteralArgument(argumentIndex++)));\n\t\t}\n\t}\n\tupdateLocationEndFrom(functionCall.debugData, currentLocation());\n\texpectToken(Token::RParen);\n\treturn functionCall;\n}\n\nNameWithDebugData Parser::parseNameWithDebugData()\n{\n\tRecursionGuard recursionGuard(*this);\n\tNameWithDebugData typedName = createWithDebugData<NameWithDebugData>();\n\tauto const nameLocation = currentLocation();\n\ttypedName.name = expectAsmIdentifier();\n\tif (currentToken() == Token::Colon)\n\t{\n\t\texpectToken(Token::Colon);\n\t\tupdateLocationEndFrom(typedName.debugData, currentLocation());\n\t\tauto const typedNameLocation = SourceLocation::smallestCovering(nameLocation, currentLocation());\n\t\tstd::ignore = expectAsmIdentifier();\n\t\traiseUnsupportedTypesError(typedNameLocation);\n\t}\n\n\treturn typedName;\n}\n\nYulName Parser::expectAsmIdentifier()\n{\n\tYulName name{currentLiteral()};\n\tif (currentToken() == Token::Identifier && m_dialect.findBuiltin(name.str()))\n\t\t// Non-fatal. We'll continue and wrongly parse it as an identifier. May lead to some spurious\n\t\t// errors after this point, but likely also much more useful ones.\n\t\tm_errorReporter.parserError(\n\t\t\t5568_error,\n\t\t\tcurrentLocation(),\n\t\t\t\"Cannot use builtin function name \\\"\" + name.str() + \"\\\" as identifier name.\"\n\t\t);\n\t// NOTE: We keep the expectation here to ensure the correct source location for the error above.\n\texpectToken(Token::Identifier);\n\treturn name;\n}\n\nvoid Parser::checkBreakContinuePosition(std::string const& _which)\n{\n\tswitch (m_currentForLoopComponent)\n\t{\n\tcase ForLoopComponent::None:\n\t\tm_errorReporter.syntaxError(2592_error, currentLocation(), \"Keyword \\\"\" + _which + \"\\\" needs to be inside a for-loop body.\");\n\t\tbreak;\n\tcase ForLoopComponent::ForLoopPre:\n\t\tm_errorReporter.syntaxError(9615_error, currentLocation(), \"Keyword \\\"\" + _which + \"\\\" in for-loop init block is not allowed.\");\n\t\tbreak;\n\tcase ForLoopComponent::ForLoopPost:\n\t\tm_errorReporter.syntaxError(2461_error, currentLocation(), \"Keyword \\\"\" + _which + \"\\\" in for-loop post block is not allowed.\");\n\t\tbreak;\n\tcase ForLoopComponent::ForLoopBody:\n\t\tbreak;\n\t}\n}\n\nbool Parser::isValidNumberLiteral(std::string_view const _literal)\n{\n\ttry\n\t{\n\t\t// Try to convert _literal to u256.\n\t\t[[maybe_unused]] auto tmp = u256(_literal);\n\t}\n\tcatch (...)\n\t{\n\t\treturn false;\n\t}\n\tif (boost::starts_with(_literal, \"0x\"))\n\t\treturn true;\n\telse\n\t\treturn _literal.find_first_not_of(\"0123456789\") == std::string_view::npos;\n}\n\nvoid Parser::raiseUnsupportedTypesError(SourceLocation const& _location) const\n{\n\tm_errorReporter.parserError(5473_error, _location, \"Types are not supported in untyped Yul.\");\n}\n"
  },
  {
    "path": "libyul/AsmParser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2016\n * Solidity inline assembly parser.\n */\n\n#pragma once\n\n#include <libyul/AST.h>\n#include <libyul/ASTForward.h>\n#include <libyul/Dialect.h>\n\n#include <liblangutil/SourceLocation.h>\n#include <liblangutil/Scanner.h>\n#include <liblangutil/ParserBase.h>\n\n#include <map>\n#include <memory>\n#include <variant>\n#include <vector>\n#include <string_view>\n\nnamespace solidity::yul\n{\n\nclass Parser: public langutil::ParserBase\n{\npublic:\n\tenum class ForLoopComponent\n\t{\n\t\tNone, ForLoopPre, ForLoopPost, ForLoopBody\n\t};\n\n\tenum class UseSourceLocationFrom\n\t{\n\t\tScanner, LocationOverride, Comments,\n\t};\n\n\texplicit Parser(\n\t\tlangutil::ErrorReporter& _errorReporter,\n\t\tDialect const& _dialect,\n\t\tstd::optional<langutil::SourceLocation> _locationOverride = {}\n\t):\n\t\tParserBase(_errorReporter),\n\t\tm_dialect(_dialect),\n\t\tm_locationOverride{_locationOverride ? *_locationOverride : langutil::SourceLocation{}},\n\t\tm_useSourceLocationFrom{\n\t\t\t_locationOverride ?\n\t\t\tUseSourceLocationFrom::LocationOverride :\n\t\t\tUseSourceLocationFrom::Scanner\n\t\t}\n\t{}\n\n\t/// Constructs a Yul parser that is using the debug data\n\t/// from the comments (via @src and other tags).\n\texplicit Parser(\n\t\tlangutil::ErrorReporter& _errorReporter,\n\t\tDialect const& _dialect,\n\t\tstd::optional<std::map<unsigned, std::shared_ptr<std::string const>>> _sourceNames\n\t):\n\t\tParserBase(_errorReporter),\n\t\tm_dialect(_dialect),\n\t\tm_sourceNames{std::move(_sourceNames)},\n\t\tm_useSourceLocationFrom{\n\t\t\tm_sourceNames.has_value() ?\n\t\t\tUseSourceLocationFrom::Comments :\n\t\t\tUseSourceLocationFrom::Scanner\n\t\t}\n\t{}\n\n\t/// Parses an inline assembly block starting with `{` and ending with `}`.\n\t/// @returns an empty shared pointer on error.\n\tstd::unique_ptr<AST> parseInline(std::shared_ptr<langutil::Scanner> const& _scanner);\n\n\t/// Parses an assembly block starting with `{` and ending with `}`\n\t/// and expects end of input after the '}'.\n\t/// @returns an empty shared pointer on error.\n\tstd::unique_ptr<AST> parse(langutil::CharStream& _charStream);\n\nprotected:\n\tlangutil::SourceLocation currentLocation() const override\n\t{\n\t\tif (m_useSourceLocationFrom == UseSourceLocationFrom::LocationOverride)\n\t\t\treturn m_locationOverride;\n\n\t\treturn ParserBase::currentLocation();\n\t}\n\n\tlangutil::Token advance() override;\n\n\tvoid fetchDebugDataFromComment();\n\n\tstd::optional<std::pair<std::string_view, langutil::SourceLocation>> parseSrcComment(\n\t\tstd::string_view _arguments,\n\t\tlangutil::SourceLocation const& _commentLocation\n\t);\n\n\tstd::optional<std::pair<std::string_view, std::optional<int>>> parseASTIDComment(\n\t\tstd::string_view _arguments,\n\t\tlangutil::SourceLocation const& _commentLocation\n\t);\n\n\t/// Creates a DebugData object with the correct source location set.\n\tlangutil::DebugData::ConstPtr createDebugData() const;\n\n\tvoid updateLocationEndFrom(\n\t\tlangutil::DebugData::ConstPtr& _debugData,\n\t\tlangutil::SourceLocation const& _location\n\t) const;\n\n\t/// Creates an inline assembly node with the current debug data.\n\ttemplate <class T> T createWithDebugData() const\n\t{\n\t\tT r;\n\t\tr.debugData = createDebugData();\n\t\treturn r;\n\t}\n\n\tBlock parseBlock();\n\tStatement parseStatement();\n\tCase parseCase();\n\tForLoop parseForLoop();\n\t/// Parses a functional expression that has to push exactly one stack element\n\tExpression parseExpression(bool _unlimitedLiteralArgument = false);\n\t/// Parses an elementary operation, i.e. a literal, identifier, instruction or\n\t/// builtin function call (only the name).\n\tstd::variant<Literal, Identifier, BuiltinName> parseLiteralOrIdentifier(bool _unlimitedLiteralArgument = false);\n\tVariableDeclaration parseVariableDeclaration();\n\tFunctionDefinition parseFunctionDefinition();\n\tFunctionCall parseCall(std::variant<Literal, Identifier, BuiltinName>&& _index);\n\tNameWithDebugData parseNameWithDebugData();\n\tYulName expectAsmIdentifier();\n\tvoid raiseUnsupportedTypesError(langutil::SourceLocation const& _location) const;\n\n\t/// Reports an error if we are currently not inside the body part of a for loop.\n\tvoid checkBreakContinuePosition(std::string const& _which);\n\n\tstatic bool isValidNumberLiteral(std::string_view _literal);\n\nprivate:\n\tDialect const& m_dialect;\n\n\tstd::optional<std::map<unsigned, std::shared_ptr<std::string const>>> m_sourceNames;\n\tlangutil::SourceLocation m_locationOverride;\n\tlangutil::SourceLocation m_locationFromComment;\n\tstd::optional<int64_t> m_astIDFromComment;\n\tUseSourceLocationFrom m_useSourceLocationFrom = UseSourceLocationFrom::Scanner;\n\tForLoopComponent m_currentForLoopComponent = ForLoopComponent::None;\n\tbool m_insideFunction = false;\n};\n\n}\n"
  },
  {
    "path": "libyul/AsmPrinter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2017\n * Converts a parsed assembly into its textual form.\n */\n\n#include <libyul/AsmPrinter.h>\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/StringUtils.h>\n\n#include <boost/algorithm/string.hpp>\n#include <boost/algorithm/string/replace.hpp>\n\n#include <range/v3/view/transform.hpp>\n\n#include <functional>\n#include <memory>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\nusing namespace solidity::yul;\n\nstd::string AsmPrinter::format(\n\tAST const& _ast,\n\tstd::optional<std::map<unsigned, std::shared_ptr<std::string const>>> const& _sourceIndexToName,\n\tDebugInfoSelection const& _debugInfoSelection,\n\tCharStreamProvider const* _soliditySourceProvider)\n{\n\treturn AsmPrinter{_ast.dialect(), _sourceIndexToName, _debugInfoSelection, _soliditySourceProvider}(_ast.root());\n}\n\n\nstd::string AsmPrinter::operator()(Literal const& _literal)\n{\n\tyulAssert(validLiteral(_literal));\n\n\tstd::string const locationComment = formatDebugData(_literal);\n\tstd::string const formattedValue = formatLiteral(_literal);\n\n\tswitch (_literal.kind)\n\t{\n\tcase LiteralKind::Number:\n\tcase LiteralKind::Boolean:\n\t\treturn locationComment + formattedValue;\n\tcase LiteralKind::String:\n\t\tbreak;\n\t}\n\n\treturn locationComment + escapeAndQuoteString(formattedValue);\n}\n\nstd::string AsmPrinter::operator()(Identifier const& _identifier)\n{\n\tyulAssert(!_identifier.name.empty(), \"Invalid identifier.\");\n\treturn formatDebugData(_identifier) + _identifier.name.str();\n}\n\nstd::string AsmPrinter::operator()(BuiltinName const& _builtin)\n{\n\treturn formatDebugData(_builtin) + m_dialect.builtin(_builtin.handle).name;\n}\n\nstd::string AsmPrinter::operator()(ExpressionStatement const& _statement)\n{\n\tstd::string const locationComment = formatDebugData(_statement);\n\n\treturn locationComment + std::visit(*this, _statement.expression);\n}\n\nstd::string AsmPrinter::operator()(Assignment const& _assignment)\n{\n\tstd::string const locationComment = formatDebugData(_assignment);\n\n\tyulAssert(_assignment.variableNames.size() >= 1, \"\");\n\tstd::string variables = (*this)(_assignment.variableNames.front());\n\tfor (size_t i = 1; i < _assignment.variableNames.size(); ++i)\n\t\tvariables += \", \" + (*this)(_assignment.variableNames[i]);\n\n\treturn locationComment + variables + \" := \" + std::visit(*this, *_assignment.value);\n}\n\nstd::string AsmPrinter::operator()(VariableDeclaration const& _variableDeclaration)\n{\n\tstd::string out = formatDebugData(_variableDeclaration);\n\n\tout += \"let \";\n\tout += boost::algorithm::join(\n\t\t_variableDeclaration.variables | ranges::views::transform(\n\t\t\t[this](NameWithDebugData argument) { return formatNameWithDebugData(argument); }\n\t\t),\n\t\t\", \"\n\t);\n\tif (_variableDeclaration.value)\n\t{\n\t\tout += \" := \";\n\t\tout += std::visit(*this, *_variableDeclaration.value);\n\t}\n\treturn out;\n}\n\nstd::string AsmPrinter::operator()(FunctionDefinition const& _functionDefinition)\n{\n\tyulAssert(!_functionDefinition.name.empty(), \"Invalid function name.\");\n\n\tstd::string out = formatDebugData(_functionDefinition);\n\tout += \"function \" + _functionDefinition.name.str() + \"(\";\n\tout += boost::algorithm::join(\n\t\t_functionDefinition.parameters | ranges::views::transform(\n\t\t\t[this](NameWithDebugData argument) { return formatNameWithDebugData(argument); }\n\t\t),\n\t\t\", \"\n\t);\n\tout += \")\";\n\tif (!_functionDefinition.returnVariables.empty())\n\t{\n\t\tout += \" -> \";\n\t\tout += boost::algorithm::join(\n\t\t\t_functionDefinition.returnVariables | ranges::views::transform(\n\t\t\t\t[this](NameWithDebugData argument) { return formatNameWithDebugData(argument); }\n\t\t\t),\n\t\t\t\", \"\n\t\t);\n\t}\n\n\treturn out + \"\\n\" + (*this)(_functionDefinition.body);\n}\n\nstd::string AsmPrinter::operator()(FunctionCall const& _functionCall)\n{\n\tstd::string const locationComment = formatDebugData(_functionCall);\n\tstd::string const functionName = std::visit(*this, _functionCall.functionName);\n\treturn\n\t\tlocationComment +\n\t\tfunctionName + \"(\" +\n\t\tboost::algorithm::join(\n\t\t\t_functionCall.arguments | ranges::views::transform([&](auto&& _node) { return std::visit(*this, _node); }),\n\t\t\t\", \" ) +\n\t\t\")\";\n}\n\nstd::string AsmPrinter::operator()(If const& _if)\n{\n\tyulAssert(_if.condition, \"Invalid if condition.\");\n\n\tstd::string out = formatDebugData(_if);\n\tout += \"if \" + std::visit(*this, *_if.condition);\n\n\tstd::string body = (*this)(_if.body);\n\tchar delim = '\\n';\n\tif (body.find('\\n') == std::string::npos)\n\t\tdelim = ' ';\n\n\treturn out + delim + body;\n}\n\nstd::string AsmPrinter::operator()(Switch const& _switch)\n{\n\tyulAssert(_switch.expression, \"Invalid expression pointer.\");\n\n\tstd::string out = formatDebugData(_switch);\n\tout += \"switch \" + std::visit(*this, *_switch.expression);\n\n\tfor (auto const& _case: _switch.cases)\n\t{\n\t\tif (!_case.value)\n\t\t\tout += \"\\ndefault \";\n\t\telse\n\t\t\tout += \"\\ncase \" + (*this)(*_case.value) + \" \";\n\t\tout += (*this)(_case.body);\n\t}\n\treturn out;\n}\n\nstd::string AsmPrinter::operator()(ForLoop const& _forLoop)\n{\n\tyulAssert(_forLoop.condition, \"Invalid for loop condition.\");\n\tstd::string const locationComment = formatDebugData(_forLoop);\n\n\tstd::string pre = (*this)(_forLoop.pre);\n\tstd::string condition = std::visit(*this, *_forLoop.condition);\n\tstd::string post = (*this)(_forLoop.post);\n\n\tchar delim = '\\n';\n\tif (\n\t\tpre.size() + condition.size() + post.size() < 60 &&\n\t\tpre.find('\\n') == std::string::npos &&\n\t\tpost.find('\\n') == std::string::npos\n\t)\n\t\tdelim = ' ';\n\treturn\n\t\tlocationComment +\n\t\t(\"for \" + std::move(pre) + delim + std::move(condition) + delim + std::move(post) + \"\\n\") +\n\t\t(*this)(_forLoop.body);\n}\n\nstd::string AsmPrinter::operator()(Break const& _break)\n{\n\treturn formatDebugData(_break) + \"break\";\n}\n\nstd::string AsmPrinter::operator()(Continue const& _continue)\n{\n\treturn formatDebugData(_continue) + \"continue\";\n}\n\n// '_leave' and '__leave' is reserved in VisualStudio\nstd::string AsmPrinter::operator()(Leave const& leave_)\n{\n\treturn formatDebugData(leave_) + \"leave\";\n}\n\nstd::string AsmPrinter::operator()(Block const& _block)\n{\n\tstd::string const locationComment = formatDebugData(_block);\n\n\tif (_block.statements.empty())\n\t\treturn locationComment + \"{ }\";\n\tstd::string body = boost::algorithm::join(\n\t\t_block.statements | ranges::views::transform([&](auto&& _node) { return std::visit(*this, _node); }),\n\t\t\"\\n\"\n\t);\n\tif (body.size() < 30 && body.find('\\n') == std::string::npos)\n\t\treturn locationComment + \"{ \" + body + \" }\";\n\telse\n\t{\n\t\tboost::replace_all(body, \"\\n\", \"\\n    \");\n\t\treturn locationComment + \"{\\n    \" + body + \"\\n}\";\n\t}\n}\n\nstd::string AsmPrinter::formatNameWithDebugData(NameWithDebugData _variable)\n{\n\tyulAssert(!_variable.name.empty(), \"Invalid variable name.\");\n\treturn formatDebugData(_variable) + _variable.name.str();\n}\n\nstd::string AsmPrinter::formatSourceLocation(\n\tSourceLocation const& _location,\n\tstd::map<std::string, unsigned> const& _nameToSourceIndex,\n\tDebugInfoSelection const& _debugInfoSelection,\n\tCharStreamProvider const* _soliditySourceProvider\n)\n{\n\tyulAssert(!_nameToSourceIndex.empty(), \"\");\n\tif (_debugInfoSelection.snippet)\n\t\tyulAssert(_debugInfoSelection.location, \"@src tag must always contain the source location\");\n\n\tif (_debugInfoSelection.none())\n\t\treturn \"\";\n\n\tstd::string sourceIndex = \"-1\";\n\tstd::string solidityCodeSnippet = \"\";\n\tif (_location.sourceName)\n\t{\n\t\tsourceIndex = std::to_string(_nameToSourceIndex.at(*_location.sourceName));\n\n\t\tif (\n\t\t\t_debugInfoSelection.snippet &&\n\t\t\t_soliditySourceProvider &&\n\t\t\t!_soliditySourceProvider->charStream(*_location.sourceName).isImportedFromAST()\n\t\t)\n\t\t{\n\t\t\tsolidityCodeSnippet = escapeAndQuoteString(\n\t\t\t\t_soliditySourceProvider->charStream(*_location.sourceName).singleLineSnippet(_location)\n\t\t\t);\n\n\t\t\t// On top of escaping quotes we also escape the slash inside any `*/` to guard against\n\t\t\t// it prematurely terminating multi-line comment blocks. We do not escape all slashes\n\t\t\t// because the ones without `*` are not dangerous and ignoring them reduces visual noise.\n\t\t\tboost::replace_all(solidityCodeSnippet, \"*/\", \"*\\\\/\");\n\t\t}\n\t}\n\n\tstd::string sourceLocation =\n\t\t\"@src \" +\n\t\tsourceIndex +\n\t\t\":\" +\n\t\tstd::to_string(_location.start) +\n\t\t\":\" +\n\t\tstd::to_string(_location.end);\n\n\treturn sourceLocation + (solidityCodeSnippet.empty() ? \"\" : \"  \") + solidityCodeSnippet;\n}\n\nstd::string AsmPrinter::formatDebugData(langutil::DebugData::ConstPtr const& _debugData, bool _statement)\n{\n\tif (!_debugData || m_debugInfoSelection.none())\n\t\treturn \"\";\n\n\tstd::vector<std::string> items;\n\tif (auto id = _debugData->astID)\n\t\tif (m_debugInfoSelection.astID)\n\t\t\titems.emplace_back(\"@ast-id \" + std::to_string(*id));\n\n\tif (\n\t\tm_lastLocation != _debugData->originLocation &&\n\t\t!m_nameToSourceIndex.empty()\n\t)\n\t{\n\t\tm_lastLocation = _debugData->originLocation;\n\n\t\titems.emplace_back(formatSourceLocation(\n\t\t\t_debugData->originLocation,\n\t\t\tm_nameToSourceIndex,\n\t\t\tm_debugInfoSelection,\n\t\t\tm_soliditySourceProvider\n\t\t));\n\t}\n\n\tstd::string commentBody = joinHumanReadable(items, \" \");\n\tif (commentBody.empty())\n\t\treturn \"\";\n\telse\n\t\treturn\n\t\t\t_statement ?\n\t\t\t\"/// \" + commentBody + \"\\n\" :\n\t\t\t\"/** \" + commentBody + \" */ \";\n}\n"
  },
  {
    "path": "libyul/AsmPrinter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2017\n * Converts a parsed assembly into its textual form.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/YulName.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <liblangutil/CharStreamProvider.h>\n#include <liblangutil/DebugInfoSelection.h>\n#include <liblangutil/DebugData.h>\n\n#include <map>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\n\n/**\n * Converts a parsed Yul AST into readable string representation.\n * Ignores source locations.\n */\nclass AsmPrinter\n{\npublic:\n\tstatic std::string format(\n\t\tAST const& _ast,\n\t\tstd::optional<std::map<unsigned, std::shared_ptr<std::string const>>> const& _sourceIndexToName = {},\n\t\tlangutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),\n\t\tlangutil::CharStreamProvider const* _soliditySourceProvider = nullptr\n\t);\n\n\texplicit AsmPrinter(\n\t\tDialect const& _dialect,\n\t\tstd::optional<std::map<unsigned, std::shared_ptr<std::string const>>> const& _sourceIndexToName = {},\n\t\tlangutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),\n\t\tlangutil::CharStreamProvider const* _soliditySourceProvider = nullptr\n\t):\n\t\tm_dialect(_dialect),\n\t\tm_debugInfoSelection(_debugInfoSelection),\n\t\tm_soliditySourceProvider(_soliditySourceProvider)\n\t{\n\t\tif (_sourceIndexToName)\n\t\t\tfor (auto&& [index, name]: *_sourceIndexToName)\n\t\t\t\tm_nameToSourceIndex[*name] = index;\n\t}\n\n\tstd::string operator()(Literal const& _literal);\n\tstd::string operator()(Identifier const& _identifier);\n\tstd::string operator()(BuiltinName const& _builtin);\n\tstd::string operator()(ExpressionStatement const& _expr);\n\tstd::string operator()(Assignment const& _assignment);\n\tstd::string operator()(VariableDeclaration const& _variableDeclaration);\n\tstd::string operator()(FunctionDefinition const& _functionDefinition);\n\tstd::string operator()(FunctionCall const& _functionCall);\n\tstd::string operator()(If const& _if);\n\tstd::string operator()(Switch const& _switch);\n\tstd::string operator()(ForLoop const& _forLoop);\n\tstd::string operator()(Break const& _break);\n\tstd::string operator()(Continue const& _continue);\n\tstd::string operator()(Leave const& _continue);\n\tstd::string operator()(Block const& _block);\n\n\tstatic std::string formatSourceLocation(\n\t\tlangutil::SourceLocation const& _location,\n\t\tstd::map<std::string, unsigned> const& _nameToSourceIndex,\n\t\tlangutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),\n\t\tlangutil::CharStreamProvider const* m_soliditySourceProvider = nullptr\n\t);\n\nprivate:\n\tstd::string formatNameWithDebugData(NameWithDebugData _variable);\n\tstd::string formatDebugData(langutil::DebugData::ConstPtr const& _debugData, bool _statement);\n\ttemplate <class T>\n\tstd::string formatDebugData(T const& _node)\n\t{\n\t\tbool isExpression = std::is_constructible<Expression, T>::value;\n\t\treturn formatDebugData(_node.debugData, !isExpression);\n\t}\n\n\tDialect const& m_dialect;\n\tstd::map<std::string, unsigned> m_nameToSourceIndex;\n\tlangutil::SourceLocation m_lastLocation = {};\n\tlangutil::DebugInfoSelection m_debugInfoSelection = {};\n\tlangutil::CharStreamProvider const* m_soliditySourceProvider = nullptr;\n};\n\n}\n"
  },
  {
    "path": "libyul/Builtins.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <cstddef>\n\nnamespace solidity::yul\n{\n\n/// Handle to reference a builtin function in the AST\nstruct BuiltinHandle\n{\n\tsize_t id;\n\n\tbool operator==(BuiltinHandle const& _other) const { return id == _other.id; }\n\tbool operator<(BuiltinHandle const& _other) const { return id < _other.id; }\n};\n\n}\n"
  },
  {
    "path": "libyul/CMakeLists.txt",
    "content": "add_library(yul\n\t${GENERATED_POLYFILL_HEADERS}\n\n\tAsmAnalysis.cpp\n\tAsmAnalysis.h\n\tAsmAnalysisInfo.h\n\tAST.h\n\tAST.cpp\n\tASTForward.h\n\tASTLabelRegistry.cpp\n\tASTLabelRegistry.h\n\tAsmJsonConverter.h\n\tAsmJsonConverter.cpp\n\tAsmJsonImporter.h\n\tAsmJsonImporter.cpp\n\tAsmParser.cpp\n\tAsmParser.h\n\tAsmPrinter.cpp\n\tAsmPrinter.h\n\tBuiltins.h\n\tYulStack.h\n\tYulStack.cpp\n\tCompilabilityChecker.cpp\n\tCompilabilityChecker.h\n\tControlFlowSideEffects.h\n\tControlFlowSideEffectsCollector.cpp\n\tControlFlowSideEffectsCollector.h\n\tDialect.cpp\n\tDialect.h\n\tExceptions.h\n\tFunctionReferenceResolver.cpp\n\tFunctionReferenceResolver.h\n\tObject.cpp\n\tObject.h\n\tObjectOptimizer.cpp\n\tObjectOptimizer.h\n\tObjectParser.cpp\n\tObjectParser.h\n\tScope.cpp\n\tScope.h\n\tScopeFiller.cpp\n\tScopeFiller.h\n\tUtilities.cpp\n\tUtilities.h\n\tYulName.h\n\tYulString.h\n\tbackends/evm/AbstractAssembly.h\n\tbackends/evm/AsmCodeGen.cpp\n\tbackends/evm/AsmCodeGen.h\n\tbackends/evm/ConstantOptimiser.cpp\n\tbackends/evm/ConstantOptimiser.h\n\tbackends/evm/ControlFlowGraph.h\n\tbackends/evm/ControlFlowGraphBuilder.cpp\n\tbackends/evm/ControlFlowGraphBuilder.h\n\tbackends/evm/EthAssemblyAdapter.cpp\n\tbackends/evm/EthAssemblyAdapter.h\n\tbackends/evm/EVMBuiltins.cpp\n\tbackends/evm/EVMBuiltins.h\n\tbackends/evm/EVMCodeTransform.cpp\n\tbackends/evm/EVMCodeTransform.h\n\tbackends/evm/EVMDialect.cpp\n\tbackends/evm/EVMDialect.h\n\tbackends/evm/EVMObjectCompiler.cpp\n\tbackends/evm/EVMObjectCompiler.h\n\tbackends/evm/EVMMetrics.cpp\n\tbackends/evm/EVMMetrics.h\n\tbackends/evm/NoOutputAssembly.h\n\tbackends/evm/NoOutputAssembly.cpp\n\tbackends/evm/OptimizedEVMCodeTransform.cpp\n\tbackends/evm/OptimizedEVMCodeTransform.h\n\tbackends/evm/StackHelpers.h\n\tbackends/evm/StackLayoutGenerator.cpp\n\tbackends/evm/StackLayoutGenerator.h\n\tbackends/evm/VariableReferenceCounter.h\n\tbackends/evm/VariableReferenceCounter.cpp\n\tbackends/evm/ssa/BridgeFinder.h\n\tbackends/evm/ssa/CodeTransform.cpp\n\tbackends/evm/ssa/CodeTransform.h\n\tbackends/evm/ssa/ControlFlow.cpp\n\tbackends/evm/ssa/ControlFlow.h\n\tbackends/evm/ssa/JunkAdmittingBlocksFinder.cpp\n\tbackends/evm/ssa/JunkAdmittingBlocksFinder.h\n\tbackends/evm/ssa/LivenessAnalysis.cpp\n\tbackends/evm/ssa/LivenessAnalysis.h\n\tbackends/evm/ssa/PhiInverse.cpp\n\tbackends/evm/ssa/PhiInverse.h\n\tbackends/evm/ssa/SSACFGLoopNestingForest.cpp\n\tbackends/evm/ssa/SSACFGLoopNestingForest.h\n\tbackends/evm/ssa/SSACFG.cpp\n\tbackends/evm/ssa/SSACFG.h\n\tbackends/evm/ssa/SSACFGBuilder.cpp\n\tbackends/evm/ssa/SSACFGBuilder.h\n\tbackends/evm/ssa/Stack.cpp\n\tbackends/evm/ssa/Stack.h\n\tbackends/evm/ssa/StackLayout.h\n\tbackends/evm/ssa/StackLayoutGenerator.cpp\n\tbackends/evm/ssa/StackLayoutGenerator.h\n\tbackends/evm/ssa/StackShuffler.cpp\n\tbackends/evm/ssa/StackShuffler.h\n\tbackends/evm/ssa/StackUtils.cpp\n\tbackends/evm/ssa/StackUtils.h\n\tbackends/evm/ssa/io/DotExporterBase.cpp\n\tbackends/evm/ssa/io/DotExporterBase.h\n\tbackends/evm/ssa/io/JSONExporter.cpp\n\tbackends/evm/ssa/io/JSONExporter.h\n\tbackends/evm/ssa/traversal/ForwardTopologicalSort.cpp\n\tbackends/evm/ssa/traversal/ForwardTopologicalSort.h\n\toptimiser/ASTCopier.cpp\n\toptimiser/ASTCopier.h\n\toptimiser/ASTWalker.cpp\n\toptimiser/ASTWalker.h\n\toptimiser/BlockFlattener.cpp\n\toptimiser/BlockFlattener.h\n\toptimiser/BlockHasher.cpp\n\toptimiser/BlockHasher.h\n\toptimiser/CallGraphGenerator.cpp\n\toptimiser/CallGraphGenerator.h\n\toptimiser/CircularReferencesPruner.cpp\n\toptimiser/CircularReferencesPruner.h\n\toptimiser/CommonSubexpressionEliminator.cpp\n\toptimiser/CommonSubexpressionEliminator.h\n\toptimiser/ConditionalSimplifier.cpp\n\toptimiser/ConditionalSimplifier.h\n\toptimiser/ConditionalUnsimplifier.cpp\n\toptimiser/ConditionalUnsimplifier.h\n\toptimiser/ControlFlowSimplifier.cpp\n\toptimiser/ControlFlowSimplifier.h\n\toptimiser/DataFlowAnalyzer.cpp\n\toptimiser/DataFlowAnalyzer.h\n\toptimiser/DeadCodeEliminator.cpp\n\toptimiser/DeadCodeEliminator.h\n\toptimiser/Disambiguator.cpp\n\toptimiser/Disambiguator.h\n\toptimiser/EqualStoreEliminator.cpp\n\toptimiser/EqualStoreEliminator.h\n\toptimiser/EquivalentFunctionDetector.cpp\n\toptimiser/EquivalentFunctionDetector.h\n\toptimiser/EquivalentFunctionCombiner.cpp\n\toptimiser/EquivalentFunctionCombiner.h\n\toptimiser/ExpressionInliner.cpp\n\toptimiser/ExpressionInliner.h\n\toptimiser/ExpressionJoiner.cpp\n\toptimiser/ExpressionJoiner.h\n\toptimiser/ExpressionSimplifier.cpp\n\toptimiser/ExpressionSimplifier.h\n\toptimiser/ExpressionSplitter.cpp\n\toptimiser/ExpressionSplitter.h\n\toptimiser/ForLoopConditionIntoBody.cpp\n\toptimiser/ForLoopConditionIntoBody.h\n\toptimiser/ForLoopConditionOutOfBody.cpp\n\toptimiser/ForLoopConditionOutOfBody.h\n\toptimiser/ForLoopInitRewriter.cpp\n\toptimiser/ForLoopInitRewriter.h\n\toptimiser/FullInliner.cpp\n\toptimiser/FullInliner.h\n\toptimiser/FunctionCallFinder.cpp\n\toptimiser/FunctionCallFinder.h\n\toptimiser/FunctionGrouper.cpp\n\toptimiser/FunctionGrouper.h\n\toptimiser/FunctionHoister.cpp\n\toptimiser/FunctionHoister.h\n\toptimiser/FunctionSpecializer.cpp\n\toptimiser/FunctionSpecializer.h\n\toptimiser/InlinableExpressionFunctionFinder.cpp\n\toptimiser/InlinableExpressionFunctionFinder.h\n\toptimiser/KnowledgeBase.cpp\n\toptimiser/KnowledgeBase.h\n\toptimiser/LabelIDDispenser.cpp\n\toptimiser/LabelIDDispenser.h\n\toptimiser/LoadResolver.cpp\n\toptimiser/LoadResolver.h\n\toptimiser/LoopInvariantCodeMotion.cpp\n\toptimiser/LoopInvariantCodeMotion.h\n\toptimiser/Metrics.cpp\n\toptimiser/Metrics.h\n\toptimiser/NameCollector.cpp\n\toptimiser/NameCollector.h\n\toptimiser/NameDispenser.cpp\n\toptimiser/NameDispenser.h\n\toptimiser/NameDisplacer.cpp\n\toptimiser/NameDisplacer.h\n\toptimiser/NameSimplifier.cpp\n\toptimiser/NameSimplifier.h\n\toptimiser/OptimiserStep.h\n\toptimiser/OptimizerUtilities.cpp\n\toptimiser/OptimizerUtilities.h\n\toptimiser/UnusedAssignEliminator.cpp\n\toptimiser/UnusedAssignEliminator.h\n\toptimiser/UnusedStoreBase.cpp\n\toptimiser/UnusedStoreBase.h\n\toptimiser/UnusedStoreEliminator.cpp\n\toptimiser/UnusedStoreEliminator.h\n\toptimiser/Rematerialiser.cpp\n\toptimiser/Rematerialiser.h\n\toptimiser/SSAReverser.cpp\n\toptimiser/SSAReverser.h\n\toptimiser/SSATransform.cpp\n\toptimiser/SSATransform.h\n\toptimiser/SSAValueTracker.cpp\n\toptimiser/SSAValueTracker.h\n\toptimiser/Semantics.cpp\n\toptimiser/Semantics.h\n\toptimiser/SimplificationRules.cpp\n\toptimiser/SimplificationRules.h\n\toptimiser/StackCompressor.cpp\n\toptimiser/StackCompressor.h\n\toptimiser/StackLimitEvader.cpp\n\toptimiser/StackLimitEvader.h\n\toptimiser/StackToMemoryMover.cpp\n\toptimiser/StackToMemoryMover.h\n\toptimiser/StructuralSimplifier.cpp\n\toptimiser/StructuralSimplifier.h\n\toptimiser/Substitution.cpp\n\toptimiser/Substitution.h\n\toptimiser/Suite.cpp\n\toptimiser/Suite.h\n\toptimiser/SyntacticalEquality.cpp\n\toptimiser/SyntacticalEquality.h\n\toptimiser/UnusedFunctionParameterPruner.cpp\n\toptimiser/UnusedFunctionParameterPruner.h\n\toptimiser/UnusedFunctionsCommon.h\n\toptimiser/UnusedFunctionsCommon.cpp\n\toptimiser/UnusedPruner.cpp\n\toptimiser/UnusedPruner.h\n\toptimiser/VarDeclInitializer.cpp\n\toptimiser/VarDeclInitializer.h\n\toptimiser/VarNameCleaner.cpp\n\toptimiser/VarNameCleaner.h\n)\n\ntarget_link_libraries(yul PUBLIC evmasm solutil langutil smtutil fmt::fmt-header-only)\n"
  },
  {
    "path": "libyul/CompilabilityChecker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * Component that checks whether all variables are reachable on the stack.\n */\n\n#include <libyul/CompilabilityChecker.h>\n\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AsmAnalysisInfo.h>\n\n#include <libyul/backends/evm/EVMCodeTransform.h>\n#include <libyul/backends/evm/NoOutputAssembly.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nCompilabilityChecker::CompilabilityChecker(\n\tObject const& _object,\n\tbool _optimizeStackAllocation\n)\n{\n\tyulAssert(_object.hasCode());\n\tif (auto const* evmDialect = dynamic_cast<EVMDialect const*>(_object.dialect()))\n\t{\n\t\tNoOutputEVMDialect noOutputDialect(*evmDialect);\n\n\t\tyul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(\n\t\t\tnoOutputDialect,\n\t\t\t_object.code()->root(),\n\t\t\t_object.summarizeStructure()\n\t\t);\n\n\t\tBuiltinContext builtinContext;\n\t\tbuiltinContext.currentObject = &_object;\n\t\tif (!_object.name.empty())\n\t\t\tbuiltinContext.subIDs[_object.name] = {1};\n\t\tfor (auto const& subNode: _object.subObjects)\n\t\t\tbuiltinContext.subIDs[subNode->name] = {1};\n\t\tNoOutputAssembly assembly{evmDialect->evmVersion()};\n\t\tCodeTransform transform(\n\t\t\tassembly,\n\t\t\tanalysisInfo,\n\t\t\t_object.code()->root(),\n\t\t\tnoOutputDialect,\n\t\t\tbuiltinContext,\n\t\t\t_optimizeStackAllocation\n\t\t);\n\t\ttransform(_object.code()->root());\n\n\t\tfor (StackTooDeepError const& error: transform.stackErrors())\n\t\t{\n\t\t\tauto& unreachables = unreachableVariables[error.functionName];\n\t\t\tif (!util::contains(unreachables, error.variable))\n\t\t\t\tunreachables.emplace_back(error.variable);\n\t\t\tint& deficit = stackDeficit[error.functionName];\n\t\t\tdeficit = std::max(error.depth, deficit);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "libyul/CompilabilityChecker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that checks whether all variables are reachable on the stack.\n */\n\n#pragma once\n\n#include <libyul/Dialect.h>\n#include <libyul/ASTForward.h>\n#include <libyul/Object.h>\n\n#include <map>\n#include <memory>\n\nnamespace solidity::yul\n{\n\n/**\n * Component that checks whether all variables are reachable on the stack and\n * provides a mapping from function name to the largest stack difference found\n * in that function (no entry present if that function is compilable), as well\n * as the set of unreachable variables for each function.\n *\n * This only works properly if the outermost block is compilable and\n * functions are not nested. Otherwise, it might miss reporting some functions.\n *\n * Only checks the code of the object itself, does not descend into sub-objects.\n */\nstruct CompilabilityChecker\n{\n\tCompilabilityChecker(\n\t\tObject const& _object,\n\t\tbool _optimizeStackAllocation\n\t);\n\tstd::map<YulName, std::vector<YulName>> unreachableVariables;\n\tstd::map<YulName, int> stackDeficit;\n};\n\n}\n"
  },
  {
    "path": "libyul/ControlFlowSideEffects.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libevmasm/Instruction.h>\n#include <libevmasm/SemanticInformation.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Side effects of a user-defined or builtin function.\n *\n * Each of the three booleans represents a reachability condition. There is an implied\n * fourth alternative, which is going out of gas while executing the function. Since\n * this can always happen and depends on the supply of gas, it is not considered.\n *\n * If all three booleans are false, it means that the function always leads to infinite\n * recursion.\n */\nstruct ControlFlowSideEffects\n{\n\t/// If true, the function contains at least one reachable branch that terminates successfully.\n\tbool canTerminate = false;\n\t/// If true, the function contains at least one reachable branch that reverts.\n\tbool canRevert = false;\n\t/// If true, the function has a regular outgoing control-flow.\n\tbool canContinue = true;\n\n\tbool terminatesOrReverts() const\n\t{\n\t\treturn (canTerminate || canRevert) && !canContinue;\n\t}\n\n\tstatic ControlFlowSideEffects fromInstruction(evmasm::Instruction _instruction)\n\t{\n\t\tControlFlowSideEffects controlFlowSideEffects;\n\t\tif (evmasm::SemanticInformation::terminatesControlFlow(_instruction))\n\t\t{\n\t\t\tcontrolFlowSideEffects.canContinue = false;\n\t\t\tif (evmasm::SemanticInformation::reverts(_instruction))\n\t\t\t{\n\t\t\t\tcontrolFlowSideEffects.canTerminate = false;\n\t\t\t\tcontrolFlowSideEffects.canRevert = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcontrolFlowSideEffects.canTerminate = true;\n\t\t\t\tcontrolFlowSideEffects.canRevert = false;\n\t\t\t}\n\t\t}\n\n\t\treturn controlFlowSideEffects;\n\t}\n\n\t/// @returns the worst-case control flow side effects.\n\tstatic ControlFlowSideEffects worst()\n\t{\n\t\treturn ControlFlowSideEffects{true, true, true};\n\t}\n};\n\n}\n"
  },
  {
    "path": "libyul/ControlFlowSideEffectsCollector.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/ControlFlowSideEffectsCollector.h>\n\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/FunctionReferenceResolver.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Algorithms.h>\n\n#include <range/v3/view/map.hpp>\n#include <range/v3/view/reverse.hpp>\n#include <range/v3/algorithm/find_if.hpp>\n\nusing namespace solidity::yul;\n\n\nControlFlowBuilder::ControlFlowBuilder(Block const& _ast)\n{\n\tm_currentNode = newNode();\n\t(*this)(_ast);\n}\n\nvoid ControlFlowBuilder::operator()(FunctionCall const& _functionCall)\n{\n\twalkVector(_functionCall.arguments | ranges::views::reverse);\n\tnewConnectedNode();\n\tm_currentNode->functionCall = &_functionCall;\n}\n\nvoid ControlFlowBuilder::operator()(If const& _if)\n{\n\tvisit(*_if.condition);\n\tControlFlowNode* node = m_currentNode;\n\n\tControlFlowNode* ifEnd = newNode();\n\tnode->successors.emplace_back(ifEnd);\n\n\tnewConnectedNode();\n\t(*this)(_if.body);\n\n\tm_currentNode->successors.emplace_back(ifEnd);\n\tm_currentNode = ifEnd;\n}\n\nvoid ControlFlowBuilder::operator()(Switch const& _switch)\n{\n\tvisit(*_switch.expression);\n\tControlFlowNode* initialNode = m_currentNode;\n\tControlFlowNode* finalNode = newNode();\n\n\tif (_switch.cases.back().value)\n\t\tinitialNode->successors.emplace_back(finalNode);\n\n\tfor (Case const& case_: _switch.cases)\n\t{\n\t\tm_currentNode = initialNode;\n\t\tnewConnectedNode();\n\t\t(*this)(case_.body);\n\t\tm_currentNode->successors.emplace_back(finalNode);\n\t}\n\tm_currentNode = finalNode;\n}\n\nvoid ControlFlowBuilder::operator()(FunctionDefinition const& _function)\n{\n\tScopedSaveAndRestore currentNode(m_currentNode, nullptr);\n\tScopedSaveAndRestore leave(m_leave, nullptr);\n\tScopedSaveAndRestore _break(m_break, nullptr);\n\tScopedSaveAndRestore _continue(m_continue, nullptr);\n\n\tFunctionFlow flow;\n\tflow.exit = newNode();\n\tm_currentNode = newNode();\n\tflow.entry = m_currentNode;\n\tm_leave = flow.exit;\n\n\t(*this)(_function.body);\n\n\tm_currentNode->successors.emplace_back(flow.exit);\n\n\tm_functionFlows[&_function] = std::move(flow);\n\n\tm_leave = nullptr;\n}\n\nvoid ControlFlowBuilder::operator()(ForLoop const& _for)\n{\n\tScopedSaveAndRestore scopedBreakNode(m_break, nullptr);\n\tScopedSaveAndRestore scopedContinueNode(m_continue, nullptr);\n\n\t(*this)(_for.pre);\n\n\tControlFlowNode* breakNode = newNode();\n\tm_break = breakNode;\n\tControlFlowNode* continueNode = newNode();\n\tm_continue = continueNode;\n\n\tnewConnectedNode();\n\tControlFlowNode* loopNode = m_currentNode;\n\tvisit(*_for.condition);\n\tm_currentNode->successors.emplace_back(m_break);\n\tnewConnectedNode();\n\n\t(*this)(_for.body);\n\n\tm_currentNode->successors.emplace_back(m_continue);\n\tm_currentNode = continueNode;\n\n\t(*this)(_for.post);\n\tm_currentNode->successors.emplace_back(loopNode);\n\n\tm_currentNode = breakNode;\n}\n\nvoid ControlFlowBuilder::operator()(Break const&)\n{\n\tyulAssert(m_break);\n\tm_currentNode->successors.emplace_back(m_break);\n\tm_currentNode = newNode();\n}\n\nvoid ControlFlowBuilder::operator()(Continue const&)\n{\n\tyulAssert(m_continue);\n\tm_currentNode->successors.emplace_back(m_continue);\n\tm_currentNode = newNode();\n}\n\nvoid ControlFlowBuilder::operator()(Leave const&)\n{\n\tyulAssert(m_leave);\n\tm_currentNode->successors.emplace_back(m_leave);\n\tm_currentNode = newNode();\n}\n\nvoid ControlFlowBuilder::newConnectedNode()\n{\n\tControlFlowNode* node = newNode();\n\tm_currentNode->successors.emplace_back(node);\n\tm_currentNode = node;\n}\n\nControlFlowNode* ControlFlowBuilder::newNode()\n{\n\tm_nodes.emplace_back();\n\treturn &m_nodes.back();\n}\n\n\nControlFlowSideEffectsCollector::ControlFlowSideEffectsCollector(\n\tDialect const& _dialect,\n\tBlock const& _ast\n):\n\tm_dialect(_dialect),\n\tm_cfgBuilder(_ast),\n\tm_functionReferences(FunctionReferenceResolver{_ast}.references())\n{\n\tfor (auto&& [function, flow]: m_cfgBuilder.functionFlows())\n\t{\n\t\tyulAssert(!flow.entry->functionCall);\n\t\tyulAssert(function);\n\t\tm_processedNodes[function] = {};\n\t\tm_pendingNodes[function].push_front(flow.entry);\n\t\tm_functionSideEffects[function] = {false, false, false};\n\t\tm_functionCalls[function] = {};\n\t}\n\n\t// Process functions while we have progress. For now, we are only interested\n\t// in `canContinue`.\n\tbool progress = true;\n\twhile (progress)\n\t{\n\t\tprogress = false;\n\t\tfor (FunctionDefinition const* function: m_pendingNodes | ranges::views::keys)\n\t\t\tif (processFunction(*function))\n\t\t\t\tprogress = true;\n\t}\n\n\t// No progress anymore: All remaining nodes are calls\n\t// to functions that always recurse.\n\t// If we have not set `canContinue` by now, the function's exit\n\t// is not reachable.\n\n\t// Now it is sufficient to handle the reachable function calls (`m_functionCalls`),\n\t// we do not have to consider the control-flow graph anymore.\n\tfor (auto&& [function, calls]: m_functionCalls)\n\t{\n\t\tyulAssert(function);\n\t\tControlFlowSideEffects& functionSideEffects = m_functionSideEffects[function];\n\t\tauto _visit = [&, visited = std::set<FunctionDefinition const*>{}](FunctionDefinition const& _function, auto&& _recurse) mutable {\n\t\t\t// Worst side-effects already, stop searching.\n\t\t\tif (functionSideEffects.canTerminate && functionSideEffects.canRevert)\n\t\t\t\treturn;\n\t\t\tif (!visited.insert(&_function).second)\n\t\t\t\treturn;\n\n\t\t\tfor (FunctionCall const* call: m_functionCalls.at(&_function))\n\t\t\t{\n\t\t\t\tControlFlowSideEffects const& calledSideEffects = sideEffects(*call);\n\t\t\t\tif (calledSideEffects.canTerminate)\n\t\t\t\t\tfunctionSideEffects.canTerminate = true;\n\t\t\t\tif (calledSideEffects.canRevert)\n\t\t\t\t\tfunctionSideEffects.canRevert = true;\n\n\t\t\t\tif (m_functionReferences.count(call))\n\t\t\t\t\t_recurse(*m_functionReferences.at(call), _recurse);\n\t\t\t}\n\t\t};\n\t\t_visit(*function, _visit);\n\t}\n}\n\nstd::map<YulName, ControlFlowSideEffects> ControlFlowSideEffectsCollector::functionSideEffectsNamed() const\n{\n\tstd::map<YulName, ControlFlowSideEffects> result;\n\tfor (auto&& [function, sideEffects]: m_functionSideEffects)\n\t\tyulAssert(result.insert({function->name, sideEffects}).second);\n\treturn result;\n}\n\nbool ControlFlowSideEffectsCollector::processFunction(FunctionDefinition const& _function)\n{\n\tbool progress = false;\n\twhile (ControlFlowNode const* node = nextProcessableNode(_function))\n\t{\n\t\tif (node == m_cfgBuilder.functionFlows().at(&_function).exit)\n\t\t{\n\t\t\tm_functionSideEffects[&_function].canContinue = true;\n\t\t\treturn true;\n\t\t}\n\t\tfor (ControlFlowNode const* s: node->successors)\n\t\t\trecordReachabilityAndQueue(_function, s);\n\n\t\tprogress = true;\n\t}\n\treturn progress;\n}\n\nControlFlowNode const* ControlFlowSideEffectsCollector::nextProcessableNode(FunctionDefinition const& _function)\n{\n\tstd::list<ControlFlowNode const*>& nodes = m_pendingNodes[&_function];\n\tauto it = ranges::find_if(nodes, [this](ControlFlowNode const* _node) {\n\t\treturn !_node->functionCall || sideEffects(*_node->functionCall).canContinue;\n\t});\n\tif (it == nodes.end())\n\t\treturn nullptr;\n\n\tControlFlowNode const* node = *it;\n\tnodes.erase(it);\n\treturn node;\n}\n\nControlFlowSideEffects const& ControlFlowSideEffectsCollector::sideEffects(FunctionCall const& _call) const\n{\n\tif (BuiltinFunction const* builtin = resolveBuiltinFunction(_call.functionName, m_dialect))\n\t\treturn builtin->controlFlowSideEffects;\n\telse\n\t\treturn m_functionSideEffects.at(m_functionReferences.at(&_call));\n}\n\nvoid ControlFlowSideEffectsCollector::recordReachabilityAndQueue(\n\tFunctionDefinition const& _function,\n\tControlFlowNode const* _node\n)\n{\n\tif (_node->functionCall)\n\t\tm_functionCalls[&_function].insert(_node->functionCall);\n\tif (m_processedNodes[&_function].insert(_node).second)\n\t\tm_pendingNodes.at(&_function).push_front(_node);\n}\n"
  },
  {
    "path": "libyul/ControlFlowSideEffectsCollector.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/ControlFlowSideEffects.h>\n\n#include <deque>\n#include <list>\n#include <unordered_map>\n#include <unordered_set>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\n\nstruct ControlFlowNode\n{\n\tstd::vector<ControlFlowNode const*> successors;\n\t/// Function call AST node, if present.\n\tFunctionCall const* functionCall = nullptr;\n};\n\n/**\n * The control flow of a function with entry and exit nodes.\n */\nstruct FunctionFlow\n{\n\tControlFlowNode const* entry;\n\tControlFlowNode const* exit;\n};\n\n/**\n * Requires: Disambiguator, Function Hoister.\n */\nclass ControlFlowBuilder: private ASTWalker\n{\npublic:\n\t/// Computes the control-flows of all function defined in the block.\n\t/// Assumes the functions are hoisted to the topmost block.\n\texplicit ControlFlowBuilder(Block const& _ast);\n\tstd::unordered_map<FunctionDefinition const*, FunctionFlow> const& functionFlows() const { return m_functionFlows; }\n\nprivate:\n\tusing ASTWalker::operator();\n\tvoid operator()(FunctionCall const& _functionCall) override;\n\tvoid operator()(If const& _if) override;\n\tvoid operator()(Switch const& _switch) override;\n\tvoid operator()(FunctionDefinition const& _functionDefinition) override;\n\tvoid operator()(ForLoop const& _forLoop) override;\n\tvoid operator()(Break const& _break) override;\n\tvoid operator()(Continue const& _continue) override;\n\tvoid operator()(Leave const& _leaveStatement) override;\n\n\tvoid newConnectedNode();\n\tControlFlowNode* newNode();\n\n\tstd::deque<ControlFlowNode> m_nodes;\n\n\tControlFlowNode* m_currentNode = nullptr;\n\tControlFlowNode const* m_leave = nullptr;\n\tControlFlowNode const* m_break = nullptr;\n\tControlFlowNode const* m_continue = nullptr;\n\n\tstd::unordered_map<FunctionDefinition const*, FunctionFlow> m_functionFlows;\n};\n\n\n/**\n * Computes control-flow side-effects for user-defined functions.\n * Source does not have to be disambiguated, unless you want the side-effects\n * based on function names.\n */\nclass ControlFlowSideEffectsCollector\n{\npublic:\n\texplicit ControlFlowSideEffectsCollector(\n\t\tDialect const& _dialect,\n\t\tBlock const& _ast\n\t);\n\n\tstd::unordered_map<FunctionDefinition const*, ControlFlowSideEffects> const& functionSideEffects() const\n\t{\n\t\treturn m_functionSideEffects;\n\t}\n\t/// Returns the side effects by function name, requires unique function names.\n\tstd::map<YulName, ControlFlowSideEffects> functionSideEffectsNamed() const;\nprivate:\n\n\t/// @returns false if nothing could be processed.\n\tbool processFunction(FunctionDefinition const& _function);\n\n\t/// @returns the next pending node of the function that is not\n\t/// a function call to a function that might not continue.\n\t/// De-queues the node or returns nullptr if no such node is found.\n\tControlFlowNode const* nextProcessableNode(FunctionDefinition const& _function);\n\n\t/// @returns the side-effects of either a builtin call or a user defined function\n\t/// call (as far as already computed).\n\tControlFlowSideEffects const& sideEffects(FunctionCall const& _call) const;\n\n\t/// Queues the given node to be processed (if not already visited)\n\t/// and if it is a function call, records that `_functionName` calls\n\t/// `*_node->functionCall`.\n\tvoid recordReachabilityAndQueue(FunctionDefinition const& _function, ControlFlowNode const* _node);\n\n\tDialect const& m_dialect;\n\tControlFlowBuilder m_cfgBuilder;\n\t/// Function references, but only for calls to user-defined functions.\n\tstd::unordered_map<FunctionCall const*, FunctionDefinition const*> m_functionReferences;\n\t/// Side effects of user-defined functions, is being constructod.\n\tstd::unordered_map<FunctionDefinition const*, ControlFlowSideEffects> m_functionSideEffects;\n\t/// Control flow nodes still to process, per function.\n\tstd::unordered_map<FunctionDefinition const*, std::list<ControlFlowNode const*>> m_pendingNodes;\n\t/// Control flow nodes already processed, per function.\n\tstd::unordered_map<FunctionDefinition const*, std::unordered_set<ControlFlowNode const*>> m_processedNodes;\n\t/// Set of reachable function calls nodes in each function (including calls to builtins).\n\tstd::unordered_map<FunctionDefinition const*, std::unordered_set<FunctionCall const*>> m_functionCalls;\n};\n\n\n}\n"
  },
  {
    "path": "libyul/Dialect.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Yul dialect.\n */\n\n#include <libyul/Dialect.h>\n#include <libyul/AST.h>\n\nusing namespace solidity::yul;\nusing namespace solidity::langutil;\n\nLiteral Dialect::zeroLiteral() const\n{\n\treturn {DebugData::create(), LiteralKind::Number, LiteralValue(0, std::nullopt)};\n}\n"
  },
  {
    "path": "libyul/Dialect.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Yul dialect.\n */\n\n#pragma once\n\n#include <libyul/Builtins.h>\n#include <libyul/ControlFlowSideEffects.h>\n#include <libyul/Exceptions.h>\n#include <libyul/SideEffects.h>\n#include <libyul/YulString.h>\n\n#include <optional>\n#include <string>\n#include <string_view>\n#include <vector>\n\nnamespace solidity::yul\n{\n\nenum class LiteralKind;\nclass LiteralValue;\nstruct Literal;\n\nstruct BuiltinFunction\n{\n\tstd::string name;\n\tsize_t numParameters;\n\tsize_t numReturns;\n\tSideEffects sideEffects;\n\tControlFlowSideEffects controlFlowSideEffects;\n\t/// If true, this is the msize instruction or might contain it.\n\tbool isMSize = false;\n\t/// Must be empty or the same length as the arguments.\n\t/// If set at index i, the i'th argument has to be a literal which means it can't be moved to variables.\n\tstd::vector<std::optional<LiteralKind>> literalArguments{};\n\tstd::optional<LiteralKind> literalArgument(size_t i) const\n\t{\n\t\treturn literalArguments.empty() ? std::nullopt : literalArguments.at(i);\n\t}\n};\n\nclass Dialect\n{\npublic:\n\t/// Noncopiable.\n\tDialect(Dialect const&) = delete;\n\tDialect& operator=(Dialect const&) = delete;\n\n    /// Finds a builtin by name and returns the corresponding handle.\n\t/// @returns Builtin handle or null if the name does not match any builtin in the dialect.\n\tvirtual std::optional<BuiltinHandle> findBuiltin(std::string_view /*_name*/) const { return std::nullopt; }\n\n    /// Retrieves the description of a builtin function by its handle.\n    /// Note that handles are dialect-specific and can be used only with a dialect that created them.\n\tvirtual BuiltinFunction const& builtin(BuiltinHandle const&) const { yulAssert(false); }\n\n\t/// @returns true if the identifier is reserved. This includes the builtins too.\n\tvirtual bool reservedIdentifier(std::string_view _name) const { return findBuiltin(_name).has_value(); }\n\n\tvirtual std::optional<BuiltinHandle> discardFunctionHandle() const { return std::nullopt; }\n\tvirtual std::optional<BuiltinHandle> equalityFunctionHandle() const { return std::nullopt; }\n\tvirtual std::optional<BuiltinHandle> booleanNegationFunctionHandle() const { return std::nullopt; }\n\n\tvirtual std::optional<BuiltinHandle> memoryStoreFunctionHandle() const { return std::nullopt; }\n\tvirtual std::optional<BuiltinHandle> memoryLoadFunctionHandle() const { return std::nullopt; }\n\tvirtual std::optional<BuiltinHandle> storageStoreFunctionHandle() const { return std::nullopt; }\n\tvirtual std::optional<BuiltinHandle> storageLoadFunctionHandle() const { return std::nullopt; }\n\tvirtual std::optional<BuiltinHandle> hashFunctionHandle() const { return std::nullopt; }\n\n\tLiteral zeroLiteral() const;\n\n\tDialect() = default;\n\tvirtual ~Dialect() = default;\n};\n\n}\n"
  },
  {
    "path": "libyul/Exceptions.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Exceptions in Yul.\n */\n\n#pragma once\n\n#include <libsolutil/Exceptions.h>\n#include <libsolutil/Assertions.h>\n\n#include <libyul/YulName.h>\n\n#include <boost/preprocessor/cat.hpp>\n#include <boost/preprocessor/facilities/empty.hpp>\n#include <boost/preprocessor/facilities/overload.hpp>\n\nnamespace solidity::yul\n{\n\nstruct YulException: virtual util::Exception {};\nstruct OptimizerException: virtual YulException {};\nstruct CodegenException: virtual YulException {};\nstruct YulAssertion: virtual util::Exception {};\n\nstruct StackTooDeepError: virtual YulException\n{\n\tStackTooDeepError(YulName _variable, int _depth, std::string const& _message):\n\t\tvariable(_variable), depth(_depth)\n\t{\n\t\t*this << util::errinfo_comment(_message);\n\t}\n\tStackTooDeepError(YulName _functionName, YulName _variable, int _depth, std::string const& _message):\n\t\tfunctionName(_functionName), variable(_variable), depth(_depth)\n\t{\n\t\t*this << util::errinfo_comment(_message);\n\t}\n\tYulName functionName;\n\tYulName variable;\n\tint depth;\n};\n\n/// Assertion that throws an YulAssertion containing the given description if it is not met.\n#if !BOOST_PP_VARIADICS_MSVC\n#define yulAssert(...) BOOST_PP_OVERLOAD(yulAssert_,__VA_ARGS__)(__VA_ARGS__)\n#else\n#define yulAssert(...) BOOST_PP_CAT(BOOST_PP_OVERLOAD(yulAssert_,__VA_ARGS__)(__VA_ARGS__),BOOST_PP_EMPTY())\n#endif\n\n#define yulAssert_1(CONDITION) \\\n\tyulAssert_2((CONDITION), \"\")\n\n#define yulAssert_2(CONDITION, DESCRIPTION) \\\n\tassertThrowWithDefaultDescription( \\\n\t\t(CONDITION), \\\n\t\t::solidity::yul::YulAssertion, \\\n\t\t(DESCRIPTION), \\\n\t\t\"Yul assertion failed\" \\\n\t)\n\n}\n"
  },
  {
    "path": "libyul/FunctionReferenceResolver.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/FunctionReferenceResolver.h>\n\n#include <libyul/AST.h>\n#include <libsolutil/CommonData.h>\n\n#include <range/v3/view/reverse.hpp>\n\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nFunctionReferenceResolver::FunctionReferenceResolver(Block const& _ast)\n{\n\t(*this)(_ast);\n\tyulAssert(m_scopes.empty());\n}\n\nvoid FunctionReferenceResolver::operator()(FunctionCall const& _functionCall)\n{\n\tif (!isBuiltinFunctionCall(_functionCall))\n\t\tfor (auto&& scope: m_scopes | ranges::views::reverse)\n\t\t{\n\t\t\tyulAssert(std::holds_alternative<Identifier>(_functionCall.functionName));\n\t\t\tif (FunctionDefinition const** function = util::valueOrNullptr(scope, std::get<Identifier>(_functionCall.functionName).name))\n\t\t\t{\n\t\t\t\tm_functionReferences[&_functionCall] = *function;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\tASTWalker::operator()(_functionCall);\n}\n\nvoid FunctionReferenceResolver::operator()(Block const& _block)\n{\n\tm_scopes.emplace_back();\n\tfor (auto const& statement: _block.statements)\n\t\tif (auto const* function = std::get_if<FunctionDefinition>(&statement))\n\t\t\tm_scopes.back()[function->name] = function;\n\n\tASTWalker::operator()(_block);\n\n\tm_scopes.pop_back();\n}\n"
  },
  {
    "path": "libyul/FunctionReferenceResolver.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n\n#include <unordered_map>\n\nnamespace solidity::yul\n{\n\n/**\n * Resolves references to user-defined functions in function calls.\n * Assumes the code is correct, i.e. does not check for references to be valid or unique.\n *\n * Be careful not to iterate over the result - it is not deterministic.\n */\nclass FunctionReferenceResolver: private ASTWalker\n{\npublic:\n\texplicit FunctionReferenceResolver(Block const& _ast);\n\tstd::unordered_map<FunctionCall const*, FunctionDefinition const*> const& references() const { return m_functionReferences; }\n\nprivate:\n\tusing ASTWalker::operator();\n\tvoid operator()(FunctionCall const& _functionCall) override;\n\tvoid operator()(Block const& _block) override;\n\n\tstd::unordered_map<FunctionCall const*, FunctionDefinition const*> m_functionReferences;\n\tstd::vector<std::unordered_map<YulName, FunctionDefinition const*>> m_scopes;\n};\n\n\n}\n"
  },
  {
    "path": "libyul/Object.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Yul code and data object container.\n */\n\n#include <libyul/Object.h>\n\n#include <libyul/AsmPrinter.h>\n#include <libyul/AsmJsonConverter.h>\n#include <libyul/AST.h>\n#include <libyul/Exceptions.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/StringUtils.h>\n\n#include <boost/algorithm/string.hpp>\n\n#include <range/v3/view/transform.hpp>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\nusing namespace solidity::yul;\n\nstd::string Data::toString(DebugInfoSelection const&, CharStreamProvider const*) const\n{\n\treturn \"data \" + util::escapeAndQuoteString(name) + \" hex\\\"\" + util::toHex(data) + \"\\\"\";\n}\n\nstd::string Object::toString(\n\tDebugInfoSelection const& _debugInfoSelection,\n\tCharStreamProvider const* _soliditySourceProvider\n) const\n{\n\tyulAssert(hasCode(), \"No code\");\n\tyulAssert(dialect(), \"No dialect\");\n\tyulAssert(debugData, \"No debug data\");\n\n\tstd::string inner = \"code \" + AsmPrinter::format(\n\t\t*code(),\n\t\tdebugData->sourceNames,\n\t\t_debugInfoSelection,\n\t\t_soliditySourceProvider\n\t);\n\n\tfor (auto const& obj: subObjects)\n\t\tinner += \"\\n\" + obj->toString(_debugInfoSelection, _soliditySourceProvider);\n\n\treturn\n\t\tdebugData->formatUseSrcComment() +\n\t\t\"object \" + util::escapeAndQuoteString(name) + \" {\\n\" +\n\t\tindent(inner) + \"\\n\" +\n\t\t\"}\";\n}\n\nJson Data::toJson() const\n{\n\tJson ret;\n\tret[\"nodeType\"] = \"YulData\";\n\tret[\"value\"] = util::toHex(data);\n\treturn ret;\n}\n\nstd::string ObjectDebugData::formatUseSrcComment() const\n{\n\tif (!sourceNames)\n\t\treturn \"\";\n\n\tauto formatIdNamePair = [](auto&& _pair) {\n\t\treturn std::to_string(_pair.first) + \":\" + util::escapeAndQuoteString(*_pair.second);\n\t};\n\n\tstd::string serializedSourceNames = joinHumanReadable(\n\t\tranges::views::transform(*sourceNames, formatIdNamePair)\n\t);\n\treturn \"/// @use-src \" + serializedSourceNames + \"\\n\";\n}\n\nJson Object::toJson() const\n{\n\tyulAssert(hasCode(), \"No code\");\n\tyulAssert(dialect(), \"No dialect\");\n\n\tJson codeJson;\n\tcodeJson[\"nodeType\"] = \"YulCode\";\n\tcodeJson[\"block\"] = AsmJsonConverter(*dialect(), 0 /* sourceIndex */)(code()->root());\n\n\tJson subObjectsJson = Json::array();\n\tfor (std::shared_ptr<ObjectNode> const& subObject: subObjects)\n\t\tsubObjectsJson.emplace_back(subObject->toJson());\n\n\tJson ret;\n\tret[\"nodeType\"] = \"YulObject\";\n\tret[\"name\"] = name;\n\tret[\"code\"] = codeJson;\n\tret[\"subObjects\"] = subObjectsJson;\n\treturn ret;\n}\n\n\nstd::set<std::string> Object::Structure::topLevelSubObjectNames() const\n{\n\tstd::set<std::string> topLevelObjectNames;\n\n\tfor (auto const& path: objectPaths)\n\t\tif (!util::contains(path, '.') && path != objectName)\n\t\t\ttopLevelObjectNames.insert(path);\n\n\treturn topLevelObjectNames;\n}\n\nObject::Structure Object::summarizeStructure() const\n{\n\tStructure structure;\n\n\tstructure.objectPaths =\n\t\tname.empty() || util::contains(name, '.') ?\n\t\tstd::set<std::string>{} :\n\t\tstd::set<std::string>{name};\n\n\tstructure.objectName = name;\n\n\tfor (std::shared_ptr<ObjectNode> const& subObjectNode: subObjects)\n\t{\n\t\tyulAssert(!structure.contains(subObjectNode->name));\n\t\tif (util::contains(subObjectNode->name, '.'))\n\t\t\tcontinue;\n\n\t\tif (auto const* subObject = dynamic_cast<Object const*>(subObjectNode.get()))\n\t\t{\n\t\t\tstructure.objectPaths.insert(subObjectNode->name);\n\n\t\t\tauto const subObjectStructure = subObject->summarizeStructure();\n\n\t\t\tfor (auto const& subSubObj: subObjectStructure.objectPaths)\n\t\t\t\tif (subObject->name != subSubObj)\n\t\t\t\t{\n\t\t\t\t\tyulAssert(!structure.contains(subObject->name + \".\" + subSubObj));\n\t\t\t\t\tstructure.objectPaths.insert(subObject->name + \".\" + subSubObj);\n\t\t\t\t}\n\t\t\tfor (auto const& subSubObjData: subObjectStructure.dataPaths)\n\t\t\t\tif (subObject->name != subSubObjData)\n\t\t\t\t{\n\t\t\t\t\tyulAssert(!structure.contains(subObject->name + \".\" + subSubObjData));\n\t\t\t\t\tstructure.dataPaths.insert(subObject->name + \".\" + subSubObjData);\n\t\t\t\t}\n\t\t}\n\t\telse\n\t\t\tstructure.dataPaths.insert(subObjectNode->name);\n\t}\n\n\tyulAssert(!structure.contains(\"\"));\n\treturn structure;\n}\n\nstd::vector<evmasm::SubAssemblyID> Object::pathToSubObject(std::string_view _qualifiedName) const\n{\n\tyulAssert(_qualifiedName != name, \"\");\n\tyulAssert(subIndexByName.count(name) == 0, \"\");\n\n\tif (boost::algorithm::starts_with(_qualifiedName, name + \".\"))\n\t\t_qualifiedName = _qualifiedName.substr(name.length() + 1);\n\tyulAssert(!_qualifiedName.empty(), \"\");\n\n\tstd::vector<std::string> subObjectPathComponents;\n\tboost::algorithm::split(subObjectPathComponents, _qualifiedName, boost::is_any_of(\".\"));\n\n\tstd::vector<evmasm::SubAssemblyID> path;\n\tObject const* object = this;\n\tfor (std::string const& currentSubObjectName: subObjectPathComponents)\n\t{\n\t\tyulAssert(!currentSubObjectName.empty(), \"\");\n\t\tauto subIndexIt = object->subIndexByName.find(currentSubObjectName);\n\t\tyulAssert(\n\t\t\tsubIndexIt != object->subIndexByName.end(),\n\t\t\t\"Assembly object <\" + std::string(_qualifiedName) + \"> not found or does not contain code.\"\n\t\t);\n\t\tobject = dynamic_cast<Object const*>(object->subObjects[subIndexIt->second].get());\n\t\tyulAssert(object, \"Assembly object <\" + std::string(_qualifiedName) + \"> not found or does not contain code.\");\n\t\tyulAssert(!object->subId.empty());\n\t\tpath.emplace_back(object->subId);\n\t}\n\n\treturn path;\n}\n\nstd::shared_ptr<AST const> Object::code() const\n{\n\treturn m_code;\n}\n\nbool Object::hasCode() const { return code() != nullptr; }\n\nvoid Object::setCode(std::shared_ptr<AST const> const& _ast, std::shared_ptr<yul::AsmAnalysisInfo> _analysisInfo)\n{\n\tm_code = _ast;\n\tanalysisInfo = std::move(_analysisInfo);\n}\n\nvoid Object::collectSourceIndices(std::map<std::string, unsigned>& _indices) const\n{\n\tif (debugData && debugData->sourceNames.has_value())\n\t\tfor (auto const& [sourceIndex, sourceName]: debugData->sourceNames.value())\n\t\t{\n\t\t\tsolAssert(_indices.count(*sourceName) == 0 || _indices[*sourceName] == sourceIndex);\n\t\t\t_indices[*sourceName] = sourceIndex;\n\t\t}\n\tfor (std::shared_ptr<ObjectNode> const& subNode: subObjects)\n\t\tif (auto subObject = dynamic_cast<Object*>(subNode.get()))\n\t\t\tsubObject->collectSourceIndices(_indices);\n}\n\nbool Object::hasContiguousSourceIndices() const\n{\n\tstd::map<std::string, unsigned> sourceIndices;\n\tcollectSourceIndices(sourceIndices);\n\n\tunsigned maxSourceIndex = 0;\n\tstd::set<unsigned> indices;\n\tfor (auto const& [sources, sourceIndex]: sourceIndices)\n\t{\n\t\tmaxSourceIndex = std::max(sourceIndex, maxSourceIndex);\n\t\tindices.insert(sourceIndex);\n\t}\n\n\tsolAssert(maxSourceIndex + 1 >= indices.size());\n\treturn indices.size() == 0 || indices.size() == maxSourceIndex + 1;\n}\n\nDialect const* Object::dialect() const\n{\n\tif (!m_code)\n\t\treturn nullptr;\n\treturn &m_code->dialect();\n}\n"
  },
  {
    "path": "libyul/Object.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Yul code and data object container.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/AsmPrinter.h>\n\n#include <libevmasm/SubAssemblyID.h>\n\n#include <liblangutil/CharStreamProvider.h>\n#include <liblangutil/DebugInfoSelection.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/JSON.h>\n\n#include <memory>\n#include <set>\n#include <limits>\n\nnamespace solidity::yul\n{\nclass Dialect;\nstruct AsmAnalysisInfo;\n\nusing SourceNameMap = std::map<unsigned, std::shared_ptr<std::string const>>;\n\nclass Object;\n\n/**\n * Generic base class for both Yul objects and Yul data.\n */\nstruct ObjectNode\n{\n\tvirtual ~ObjectNode() = default;\n\n\t/// Name of the object.\n\t/// Can be empty since .yul files can also just contain code, without explicitly placing it in an object.\n\tstd::string name;\n\tvirtual std::string toString(\n\t\tlangutil::DebugInfoSelection const& _debugInfoSelection,\n\t\tlangutil::CharStreamProvider const* _soliditySourceProvider\n\t) const = 0;\n\tvirtual Json toJson() const = 0;\n};\n\n/**\n * Named data in Yul objects.\n */\nstruct Data: public ObjectNode\n{\n\tData(std::string _name, bytes _data): data(std::move(_data)) { name = _name; }\n\n\tbytes data;\n\n\tstd::string toString(\n\t\tlangutil::DebugInfoSelection const& _debugInfoSelection,\n\t\tlangutil::CharStreamProvider const* _soliditySourceProvider\n\t) const override;\n\tJson toJson() const override;\n};\n\n\nstruct ObjectDebugData\n{\n\tstd::optional<SourceNameMap> sourceNames = {};\n\n\tstd::string formatUseSrcComment() const;\n};\n\n\n/**\n * Yul code and data object container.\n */\nclass Object: public ObjectNode\n{\npublic:\n\t/// @returns a (parseable) string representation.\n\tstd::string toString(\n\t\tlangutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),\n\t\tlangutil::CharStreamProvider const* _soliditySourceProvider = nullptr\n\t) const override;\n\t/// @returns a compact JSON representation of the AST.\n\tJson toJson() const override;\n\n\t/// Summarizes the structure of the subtree rooted at a given object,\n\t/// in particular the paths that can be used from within to refer to nested nodes (objects and data).\n\tstruct Structure\n\t{\n\t\t/// The name of the object\n\t\tstd::string objectName;\n\t\t/// Available dot-separated paths to nested objects (relative to current object).\n\t\tstd::set<std::string> objectPaths;\n\t\t/// Available dot-separated paths to nested data entries (relative to current object).\n\t\tstd::set<std::string> dataPaths;\n\n\t\t/// Checks if a path is available.\n\t\tbool contains(std::string const& _path) const { return containsObject(_path) || containsData(_path); }\n\t\t/// Checks if a path is available and leads to an object.\n\t\tbool containsObject(std::string const& _path) const { return objectPaths.count(_path) > 0; }\n\t\t/// Checks if a path is available and leads to a data entry.\n\t\tbool containsData(std::string const& _path) const { return dataPaths.count(_path) > 0; }\n\n\t\tstd::set<std::string> topLevelSubObjectNames() const;\n\t};\n\n\t/// @returns the set of names of data objects accessible from within the code of\n\t/// this object, including the name of object itself\n\t/// Handles all names containing dots as reserved identifiers, not accessible as data.\n\tStructure summarizeStructure() const;\n\n\t/// @returns vector of subIDs if possible to reach subobject with @a _qualifiedName, throws otherwise\n\t/// For \"B.C\" should return vector of two values if success (subId of B and subId of C in B).\n\t/// In object \"A\" if called for \"A.B\" will return only one value (subId for B)\n\t/// will return empty vector for @a _qualifiedName that equals to object name.\n\t/// Example:\n\t/// A1{ B2{ C3, D3 }, E2{ F3{ G4, K4, H4{ I5 } } } }\n\t/// pathToSubObject(\"A1.E2.F3.H4\") == {1, 0, 2}\n\t/// pathToSubObject(\"E2.F3.H4\") == {1, 0, 2}\n\t/// pathToSubObject(\"A1.E2\") == {1}\n\t/// The path must not lead to a @a Data object (will throw in that case).\n\tstd::vector<evmasm::SubAssemblyID> pathToSubObject(std::string_view _qualifiedName) const;\n\n\tstd::shared_ptr<AST const> code() const;\n\tvoid setCode(std::shared_ptr<AST const> const& _ast, std::shared_ptr<yul::AsmAnalysisInfo> = nullptr);\n\tbool hasCode() const;\n\n\t/// sub id for object if it is subobject of another object, max value / empty if it is not subobject\n\tevmasm::SubAssemblyID subId{};\n\n\tstd::vector<std::shared_ptr<ObjectNode>> subObjects;\n\tstd::map<std::string, size_t, std::less<>> subIndexByName;\n\tstd::shared_ptr<yul::AsmAnalysisInfo> analysisInfo;\n\n\tstd::shared_ptr<ObjectDebugData const> debugData;\n\n\t/// Collects names of all Solidity source units present in the debug data\n\t/// of the Yul object (including sub-objects) and their assigned indices.\n\t/// @param _indices map that will be filled with source indices of the current Yul object & its sub-objects.\n\tvoid collectSourceIndices(std::map<std::string, unsigned>& _indices) const;\n\n\t/// @returns true, if the range of source indices starts at zero and is contiguous, false otherwise.\n\tbool hasContiguousSourceIndices() const;\n\n\t/// @returns the name of the special metadata data object.\n\tstatic std::string metadataName() { return \".metadata\"; }\n\n\tDialect const* dialect() const;\n\nprivate:\n\tstd::shared_ptr<AST const> m_code;\n};\n\n}\n"
  },
  {
    "path": "libyul/ObjectOptimizer.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/ObjectOptimizer.h>\n\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AsmPrinter.h>\n#include <libyul/AST.h>\n#include <libyul/Exceptions.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/backends/evm/EVMMetrics.h>\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/optimiser/Suite.h>\n\n#include <liblangutil/DebugInfoSelection.h>\n\n#include <libsolutil/Keccak256.h>\n\n#include <boost/algorithm/string.hpp>\n\n#include <limits>\n#include <numeric>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\nusing namespace solidity::yul;\n\n\nvoid ObjectOptimizer::optimize(Object& _object, Settings const& _settings)\n{\n\tyulAssert(_object.subId.empty(), \"Not a top-level object.\");\n\n\toptimize(_object, _settings, true /* _isCreation */);\n}\n\nvoid ObjectOptimizer::optimize(Object& _object, Settings const& _settings, bool _isCreation)\n{\n\tyulAssert(_object.code());\n\tyulAssert(_object.debugData);\n\n\tfor (auto& subNode: _object.subObjects)\n\t\tif (auto subObject = dynamic_cast<Object*>(subNode.get()))\n\t\t{\n\t\t\tbool isCreation = !boost::ends_with(subObject->name, \"_deployed\");\n\t\t\toptimize(\n\t\t\t\t*subObject,\n\t\t\t\t_settings,\n\t\t\t\tisCreation\n\t\t\t);\n\t\t}\n\n\tEVMDialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(_settings.evmVersion, _settings.eofVersion);\n\tGasMeter const meter(dialect, _isCreation, _settings.expectedExecutionsPerDeployment);\n\n\tstd::optional<h256> cacheKey = calculateCacheKey(_object.code()->root(), *_object.debugData, _settings, _isCreation);\n\tif (cacheKey.has_value() && m_cachedObjects.count(*cacheKey) != 0)\n\t{\n\t\toverwriteWithOptimizedObject(*cacheKey, _object);\n\t\treturn;\n\t}\n\n\tOptimiserSuite::run(\n\t\t&meter,\n\t\t_object,\n\t\t_settings.optimizeStackAllocation,\n\t\t_settings.yulOptimiserSteps,\n\t\t_settings.yulOptimiserCleanupSteps,\n\t\t_isCreation ? std::nullopt : std::make_optional(_settings.expectedExecutionsPerDeployment),\n\t\t{}\n\t);\n\n\tif (cacheKey.has_value())\n\t\tstoreOptimizedObject(*cacheKey, _object, dialect);\n}\n\nvoid ObjectOptimizer::storeOptimizedObject(util::h256 _cacheKey, Object const& _optimizedObject, Dialect const& _dialect)\n{\n\tm_cachedObjects[_cacheKey] = CachedObject{\n\t\tstd::make_shared<Block>(ASTCopier{}.translate(_optimizedObject.code()->root())),\n\t\t&_dialect,\n\t};\n}\n\nvoid ObjectOptimizer::overwriteWithOptimizedObject(util::h256 _cacheKey, Object& _object) const\n{\n\tyulAssert(m_cachedObjects.count(_cacheKey) != 0);\n\tCachedObject const& cachedObject = m_cachedObjects.at(_cacheKey);\n\n\tyulAssert(cachedObject.optimizedAST);\n\tyulAssert(cachedObject.dialect);\n\t_object.setCode(std::make_shared<AST>(*cachedObject.dialect, ASTCopier{}.translate(*cachedObject.optimizedAST)));\n\tyulAssert(_object.code());\n\tyulAssert(_object.dialect());\n\n\t// There's no point in caching AnalysisInfo because it references AST nodes. It can't be shared\n\t// by multiple ASTs and it's easier to recalculate it than properly clone it.\n\t_object.analysisInfo = std::make_shared<AsmAnalysisInfo>(\n\t\tAsmAnalyzer::analyzeStrictAssertCorrect(\n\t\t\t_object\n\t\t)\n\t);\n\n\t// NOTE: Source name index is included in the key so it must be identical. No need to store and restore it.\n}\n\nstd::optional<h256> ObjectOptimizer::calculateCacheKey(\n\tBlock const& _ast,\n\tObjectDebugData const& _debugData,\n\tSettings const& _settings,\n\tbool _isCreation\n)\n{\n\tAsmPrinter asmPrinter(\n\t\tEVMDialect::strictAssemblyForEVMObjects(_settings.evmVersion, _settings.eofVersion),\n\t\t_debugData.sourceNames,\n\t\tDebugInfoSelection::All()\n\t);\n\n\tbytes rawKey;\n\t// NOTE: AsmPrinter never prints nativeLocations included in debug data, so ASTs differing only\n\t// in that regard are considered equal here.  This is fine because the optimizer does not keep\n\t// them up to date across AST transformations anyway so in any use where they need to be reliable,\n\t// we just regenerate them by reparsing the object.\n\trawKey += keccak256(asmPrinter(_ast)).asBytes();\n\trawKey += keccak256(_debugData.formatUseSrcComment()).asBytes();\n\tstatic_assert(static_cast<uint8_t>(static_cast<bool>(2)) == 1);\n\trawKey += FixedHash<1>(static_cast<uint8_t>(_settings.optimizeStackAllocation)).asBytes();\n\trawKey += h256(u256(_settings.expectedExecutionsPerDeployment)).asBytes();\n\trawKey += FixedHash<1>(static_cast<uint8_t>(_isCreation)).asBytes();\n\trawKey += keccak256(_settings.evmVersion.name()).asBytes();\n\tyulAssert(!_settings.eofVersion.has_value() || *_settings.eofVersion > 0);\n\trawKey += FixedHash<1>(static_cast<uint8_t>(_settings.eofVersion ? *_settings.eofVersion : 0)).asBytes();\n\trawKey += keccak256(_settings.yulOptimiserSteps).asBytes();\n\trawKey += keccak256(_settings.yulOptimiserCleanupSteps).asBytes();\n\n\treturn h256(keccak256(rawKey));\n}\n"
  },
  {
    "path": "libyul/ObjectOptimizer.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/Object.h>\n\n#include <liblangutil/EVMVersion.h>\n\n#include <libsolutil/FixedHash.h>\n\n#include <map>\n#include <memory>\n#include <optional>\n\nnamespace solidity::yul\n{\n\n/// Encapsulates logic for applying @a yul::OptimiserSuite to a whole hierarchy of Yul objects.\n/// Also, acts as a transparent cache for optimized objects.\n///\n/// The cache is designed to allow sharing its instances widely across the compiler, without the\n/// need to invalidate entries due to changing settings or context.\n/// Caching is performed at the granularity of individual ASTs rather than whole object trees,\n/// which means that reuse is possible even within a single hierarchy, e.g. when creation and\n/// deployed objects have common dependencies.\nclass ObjectOptimizer\n{\npublic:\n\t/// Optimization settings and context information.\n\t/// This information becomes a part of the cache key and, together with the object content,\n\t/// must uniquely determine the result of optimization.\n\tstruct Settings\n\t{\n\t\tlangutil::EVMVersion evmVersion;\n\t\tstd::optional<uint8_t> eofVersion;\n\t\tbool optimizeStackAllocation;\n\t\tstd::string yulOptimiserSteps;\n\t\tstd::string yulOptimiserCleanupSteps;\n\t\tsize_t expectedExecutionsPerDeployment;\n\t};\n\n\t/// Recursively optimizes a Yul object with given settings, reusing cached ASTs where possible\n\t/// or caching the result otherwise. The object is modified in-place.\n\t/// Automatically accounts for the difference between creation and deployed objects.\n\t/// @warning Does not ensure that nativeLocations in the resulting AST match the optimized code.\n\tvoid optimize(Object& _object, Settings const& _settings);\n\n\tsize_t size() const { return m_cachedObjects.size(); }\n\nprivate:\n\tstruct CachedObject\n\t{\n\t\tstd::shared_ptr<Block const> optimizedAST;\n\t\tDialect const* dialect;\n\t};\n\n\tvoid optimize(Object& _object, Settings const& _settings, bool _isCreation);\n\n\tvoid storeOptimizedObject(util::h256 _cacheKey, Object const& _optimizedObject, Dialect const& _dialect);\n\tvoid overwriteWithOptimizedObject(util::h256 _cacheKey, Object& _object) const;\n\n\tstatic std::optional<util::h256> calculateCacheKey(\n\t\tBlock const& _ast,\n\t\tObjectDebugData const& _debugData,\n\t\tSettings const& _settings,\n\t\tbool _isCreation\n\t);\n\n\tstd::map<util::h256, CachedObject> m_cachedObjects;\n};\n\n}\n"
  },
  {
    "path": "libyul/ObjectParser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Parser for Yul code and data object container.\n */\n\n#include <libyul/AST.h>\n#include <libyul/ObjectParser.h>\n\n#include <libyul/AsmParser.h>\n#include <libyul/Exceptions.h>\n\n#include <liblangutil/Token.h>\n#include <liblangutil/Scanner.h>\n\n#include <libsolutil/StringUtils.h>\n\n#include <regex>\n\nusing namespace std::string_literals;\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\n\nstd::shared_ptr<Object> ObjectParser::parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner)\n{\n\tm_recursionDepth = 0;\n\ttry\n\t{\n\t\tstd::shared_ptr<Object> object;\n\t\tm_scanner = _scanner;\n\n\t\tif (currentToken() == Token::LBrace)\n\t\t{\n\t\t\t// Special case: Code-only form.\n\t\t\tobject = std::make_shared<Object>();\n\t\t\tobject->name = \"object\";\n\t\t\tauto sourceNameMapping = tryParseSourceNameMapping();\n\t\t\tobject->debugData = std::make_shared<ObjectDebugData>(ObjectDebugData{sourceNameMapping});\n\t\t\tobject->setCode(parseBlock(sourceNameMapping));\n\t\t\tif (!object->hasCode())\n\t\t\t\treturn nullptr;\n\t\t}\n\t\telse\n\t\t\tobject = parseObject();\n\t\tif (!_reuseScanner)\n\t\t\texpectToken(Token::EOS);\n\t\treturn object;\n\t}\n\tcatch (FatalError const&)\n\t{\n\t\tif (!m_errorReporter.hasErrors())\n\t\t{\n\t\t\tstd::cerr << \"Unreported fatal error:\" << std::endl;\n\t\t\tstd::cerr << boost::current_exception_diagnostic_information() << std::endl;\n\t\t\tyulAssert(false, \"Unreported fatal error.\");\n\t\t}\n\t}\n\treturn nullptr;\n}\n\nstd::shared_ptr<Object> ObjectParser::parseObject(Object* _containingObject)\n{\n\tRecursionGuard guard(*this);\n\n\tstd::shared_ptr<Object> ret = std::make_shared<Object>();\n\n\tauto sourceNameMapping = tryParseSourceNameMapping();\n\tret->debugData = std::make_shared<ObjectDebugData>(ObjectDebugData{sourceNameMapping});\n\n\tif (currentToken() != Token::Identifier || currentLiteral() != \"object\")\n\t\tfatalParserError(4294_error, \"Expected keyword \\\"object\\\".\");\n\tadvance();\n\n\tret->name = parseUniqueName(_containingObject);\n\n\texpectToken(Token::LBrace);\n\n\tret->setCode(parseCode(std::move(sourceNameMapping)));\n\n\twhile (currentToken() != Token::RBrace)\n\t{\n\t\tif (currentToken() == Token::Identifier && currentLiteral() == \"object\")\n\t\t\tparseObject(ret.get());\n\t\telse if (currentToken() == Token::Identifier && currentLiteral() == \"data\")\n\t\t\tparseData(*ret);\n\t\telse\n\t\t\tfatalParserError(8143_error, \"Expected keyword \\\"data\\\" or \\\"object\\\" or \\\"}\\\".\");\n\t}\n\tif (_containingObject)\n\t\taddNamedSubObject(*_containingObject, ret->name, ret);\n\n\texpectToken(Token::RBrace);\n\n\treturn ret;\n}\n\nstd::shared_ptr<AST> ObjectParser::parseCode(std::optional<SourceNameMap> _sourceNames)\n{\n\tif (currentToken() != Token::Identifier || currentLiteral() != \"code\")\n\t\tfatalParserError(4846_error, \"Expected keyword \\\"code\\\".\");\n\tadvance();\n\n\treturn parseBlock(std::move(_sourceNames));\n}\n\nstd::optional<SourceNameMap> ObjectParser::tryParseSourceNameMapping() const\n{\n\t// @use-src 0:\"abc.sol\", 1:\"foo.sol\", 2:\"bar.sol\"\n\t//\n\t// UseSrcList := UseSrc (',' UseSrc)*\n\t// UseSrc     := [0-9]+ ':' FileName\n\t// FileName   := \"(([^\\\"]|\\.)*)\"\n\n\t// Matches some \"@use-src TEXT\".\n\tstatic std::regex const lineRE = std::regex(\n\t\t\"(^|\\\\s)@use-src\\\\b\",\n\t\tstd::regex_constants::ECMAScript | std::regex_constants::optimize\n\t);\n\tstd::smatch sm;\n\tif (!std::regex_search(m_scanner->currentCommentLiteral(), sm, lineRE))\n\t\treturn std::nullopt;\n\n\tsolAssert(sm.size() == 2, \"\");\n\tauto text = m_scanner->currentCommentLiteral().substr(static_cast<size_t>(sm.position() + sm.length()));\n\tCharStream charStream(text, \"\");\n\tScanner scanner(charStream);\n\tif (scanner.currentToken() == Token::EOS)\n\t\treturn SourceNameMap{};\n\tSourceNameMap sourceNames;\n\n\twhile (scanner.currentToken() != Token::EOS)\n\t{\n\t\tif (scanner.currentToken() != Token::Number)\n\t\t\tbreak;\n\t\tauto sourceIndex = toUnsignedInt(scanner.currentLiteral());\n\t\tif (!sourceIndex)\n\t\t\tbreak;\n\t\tif (scanner.next() != Token::Colon)\n\t\t\tbreak;\n\t\tif (scanner.next() != Token::StringLiteral)\n\t\t\tbreak;\n\t\tsourceNames[*sourceIndex] = std::make_shared<std::string const>(scanner.currentLiteral());\n\n\t\tToken const next = scanner.next();\n\t\tif (next == Token::EOS)\n\t\t\treturn {std::move(sourceNames)};\n\t\tif (next != Token::Comma)\n\t\t\tbreak;\n\t\tscanner.next();\n\t}\n\n\tm_errorReporter.syntaxError(\n\t\t9804_error,\n\t\tm_scanner->currentCommentLocation(),\n\t\t\"Error parsing arguments to @use-src. Expected: <number> \\\":\\\" \\\"<filename>\\\", ...\"\n\t);\n\treturn std::nullopt;\n}\n\nstd::shared_ptr<AST> ObjectParser::parseBlock(std::optional<SourceNameMap> _sourceNames)\n{\n\tParser parser(m_errorReporter, m_dialect, std::move(_sourceNames));\n\tauto ast = parser.parseInline(m_scanner);\n\tyulAssert(ast || m_errorReporter.hasErrors(), \"Invalid block but no error!\");\n\treturn ast;\n}\n\nvoid ObjectParser::parseData(Object& _containingObject)\n{\n\tyulAssert(\n\t\tcurrentToken() == Token::Identifier && currentLiteral() == \"data\",\n\t\t\"parseData called on wrong input.\"\n\t);\n\tadvance();\n\n\tauto const name = parseUniqueName(&_containingObject);\n\n\tif (currentToken() == Token::HexStringLiteral)\n\t\texpectToken(Token::HexStringLiteral, false);\n\telse\n\t\texpectToken(Token::StringLiteral, false);\n\taddNamedSubObject(_containingObject, name, std::make_shared<Data>(name, asBytes(currentLiteral())));\n\tadvance();\n}\n\nstd::string ObjectParser::parseUniqueName(Object const* _containingObject)\n{\n\texpectToken(Token::StringLiteral, false);\n\tstd::string const name{currentLiteral()};\n\tif (name.empty())\n\t\tparserError(3287_error, \"Object name cannot be empty.\");\n\telse if (_containingObject && _containingObject->name == name)\n\t\tparserError(8311_error, \"Object name cannot be the same as the name of the containing object.\");\n\telse if (_containingObject && _containingObject->subIndexByName.count(name))\n\t\tparserError(8794_error, \"Object name \\\"\" + name + \"\\\" already exists inside the containing object.\");\n\tadvance();\n\treturn name;\n}\n\nvoid ObjectParser::addNamedSubObject(Object& _container, std::string_view const _name, std::shared_ptr<ObjectNode> _subObject)\n{\n\t_container.subIndexByName.emplace(\n\t\tstd::piecewise_construct,\n\t\tstd::forward_as_tuple(_name),\n\t\tstd::forward_as_tuple(_container.subObjects.size())\n\t);\n\t_container.subObjects.emplace_back(std::move(_subObject));\n}\n"
  },
  {
    "path": "libyul/ObjectParser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Parser for Yul code and data object container.\n */\n\n#pragma once\n\n#include <libyul/Object.h>\n#include <libyul/Dialect.h>\n\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/ParserBase.h>\n\n#include <libsolutil/Common.h>\n\n#include <memory>\n\nnamespace solidity::langutil\n{\nclass Scanner;\n}\n\nnamespace solidity::yul\n{\n\n/**\n * Yul object parser. Invokes the inline assembly parser.\n */\nclass ObjectParser: public langutil::ParserBase\n{\npublic:\n\texplicit ObjectParser(langutil::ErrorReporter& _errorReporter, Dialect const& _dialect):\n\t\tParserBase(_errorReporter), m_dialect(_dialect) {}\n\n\t/// Parses a Yul object.\n\t/// Falls back to code-only parsing if the source starts with `{`.\n\t/// @param _reuseScanner if true, do check for end of input after the last `}`.\n\t/// @returns an empty shared pointer on error.\n\tstd::shared_ptr<Object> parse(std::shared_ptr<langutil::Scanner> const& _scanner, bool _reuseScanner);\n\nprivate:\n\tstd::optional<SourceNameMap> tryParseSourceNameMapping() const;\n\tstd::shared_ptr<Object> parseObject(Object* _containingObject = nullptr);\n\tstd::shared_ptr<AST> parseCode(std::optional<SourceNameMap> _sourceNames);\n\tstd::shared_ptr<AST> parseBlock(std::optional<SourceNameMap> _sourceNames);\n\tvoid parseData(Object& _containingObject);\n\n\t/// Tries to parse a name that is non-empty and unique inside the containing object.\n\tstd::string parseUniqueName(Object const* _containingObject);\n\tvoid addNamedSubObject(Object& _container, std::string_view _name, std::shared_ptr<ObjectNode> _subObject);\n\n\tDialect const& m_dialect;\n};\n\n}\n"
  },
  {
    "path": "libyul/Scope.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Scopes for identifiers.\n */\n\n#include <libyul/Scope.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nbool Scope::registerVariable(YulName _name)\n{\n\tif (exists(_name))\n\t\treturn false;\n\tVariable variable;\n\tvariable.name = _name;\n\tidentifiers[_name] = variable;\n\treturn true;\n}\n\nbool Scope::registerFunction(YulName _name, size_t _numArguments, size_t _numReturns)\n{\n\tif (exists(_name))\n\t\treturn false;\n\tidentifiers[_name] = Function{_numArguments, _numReturns, _name};\n\treturn true;\n}\n\nScope::Identifier* Scope::lookup(YulName _name)\n{\n\tbool crossedFunctionBoundary = false;\n\tfor (Scope* s = this; s; s = s->superScope)\n\t{\n\t\tauto id = s->identifiers.find(_name);\n\t\tif (id != s->identifiers.end())\n\t\t{\n\t\t\tif (crossedFunctionBoundary && std::holds_alternative<Scope::Variable>(id->second))\n\t\t\t\treturn nullptr;\n\t\t\telse\n\t\t\t\treturn &id->second;\n\t\t}\n\n\t\tif (s->functionScope)\n\t\t\tcrossedFunctionBoundary = true;\n\t}\n\treturn nullptr;\n}\n\nbool Scope::exists(YulName _name) const\n{\n\tif (identifiers.count(_name))\n\t\treturn true;\n\telse if (superScope)\n\t\treturn superScope->exists(_name);\n\telse\n\t\treturn false;\n}\n\nsize_t Scope::numberOfVariables() const\n{\n\tsize_t count = 0;\n\tfor (auto const& identifier: identifiers)\n\t\tif (std::holds_alternative<Scope::Variable>(identifier.second))\n\t\t\tcount++;\n\treturn count;\n}\n\nbool Scope::insideFunction() const\n{\n\tfor (Scope const* s = this; s; s = s->superScope)\n\t\tif (s->functionScope)\n\t\t\treturn true;\n\treturn false;\n}\n"
  },
  {
    "path": "libyul/Scope.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Scopes for identifiers.\n */\n\n#pragma once\n\n#include <liblangutil/Exceptions.h>\n\n#include <libyul/YulName.h>\n\n#include <functional>\n#include <memory>\n#include <optional>\n#include <variant>\n\nnamespace solidity::yul\n{\n\nstruct Scope\n{\n\tstruct Variable\n\t{\n\t\tYulName name;\n\t};\n\tstruct Function\n\t{\n\t\tsize_t numArguments;\n\t\tsize_t numReturns;\n\t\tYulName name;\n\t};\n\n\tusing Identifier = std::variant<Variable, Function>;\n\n\tbool registerVariable(YulName _name);\n\tbool registerFunction(\n\t\tYulName _name,\n\t\tsize_t _numArguments,\n\t\tsize_t _numReturns\n\t);\n\n\t/// Looks up the identifier in this or super scopes and returns a valid pointer if found\n\t/// or a nullptr if not found. Variable lookups up across function boundaries will fail, as\n\t/// will any lookups across assembly boundaries.\n\t/// The pointer will be invalidated if the scope is modified.\n\t/// @param _crossedFunction if true, we already crossed a function boundary during recursive lookup\n\tIdentifier* lookup(YulName _name);\n\t/// Looks up the identifier in this and super scopes (will not find variables across function\n\t/// boundaries and generally stops at assembly boundaries) and calls the visitor, returns\n\t/// false if not found.\n\ttemplate <class V>\n\tbool lookup(YulName _name, V const& _visitor)\n\t{\n\t\tif (Identifier* id = lookup(_name))\n\t\t{\n\t\t\tstd::visit(_visitor, *id);\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\t/// @returns true if the name exists in this scope or in super scopes (also searches\n\t/// across function and assembly boundaries).\n\tbool exists(YulName _name) const;\n\n\t/// @returns the number of variables directly registered inside the scope.\n\tsize_t numberOfVariables() const;\n\t/// @returns true if this scope is inside a function.\n\tbool insideFunction() const;\n\n\tScope* superScope = nullptr;\n\t/// If true, variables from the super scope are not visible here (other identifiers are),\n\t/// but they are still taken into account to prevent shadowing.\n\tbool functionScope = false;\n\tstd::map<YulName, Identifier> identifiers;\n};\n\n}\n"
  },
  {
    "path": "libyul/ScopeFiller.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Module responsible for registering identifiers inside their scopes.\n */\n\n#include <libyul/ScopeFiller.h>\n\n#include <libyul/AST.h>\n#include <libyul/Scope.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/Exceptions.h>\n\n#include <liblangutil/ErrorReporter.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <memory>\n#include <functional>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\n\nScopeFiller::ScopeFiller(AsmAnalysisInfo& _info, ErrorReporter& _errorReporter):\n\tm_info(_info), m_errorReporter(_errorReporter)\n{\n\tm_currentScope = &scope(nullptr);\n}\n\nbool ScopeFiller::operator()(ExpressionStatement const& _expr)\n{\n\treturn std::visit(*this, _expr.expression);\n}\n\nbool ScopeFiller::operator()(VariableDeclaration const& _varDecl)\n{\n\tfor (auto const& variable: _varDecl.variables)\n\t\tif (!registerVariable(variable, nativeLocationOf(_varDecl), *m_currentScope))\n\t\t\treturn false;\n\treturn true;\n}\n\nbool ScopeFiller::operator()(FunctionDefinition const& _funDef)\n{\n\tauto virtualBlock = m_info.virtualBlocks[&_funDef] = std::make_shared<Block>();\n\tScope& varScope = scope(virtualBlock.get());\n\tvarScope.superScope = m_currentScope;\n\tm_currentScope = &varScope;\n\tvarScope.functionScope = true;\n\n\tbool success = true;\n\tfor (auto const& var: _funDef.parameters + _funDef.returnVariables)\n\t\tif (!registerVariable(var, nativeLocationOf(_funDef), varScope))\n\t\t\tsuccess = false;\n\n\tif (!(*this)(_funDef.body))\n\t\tsuccess = false;\n\n\tyulAssert(m_currentScope == &varScope, \"\");\n\tm_currentScope = m_currentScope->superScope;\n\n\treturn success;\n}\n\nbool ScopeFiller::operator()(If const& _if)\n{\n\treturn (*this)(_if.body);\n}\n\nbool ScopeFiller::operator()(Switch const& _switch)\n{\n\tbool success = true;\n\tfor (auto const& _case: _switch.cases)\n\t\tif (!(*this)(_case.body))\n\t\t\tsuccess = false;\n\treturn success;\n}\n\nbool ScopeFiller::operator()(ForLoop const& _forLoop)\n{\n\tScope* originalScope = m_currentScope;\n\n\tbool success = true;\n\tif (!(*this)(_forLoop.pre))\n\t\tsuccess = false;\n\tm_currentScope = &scope(&_forLoop.pre);\n\tif (!std::visit(*this, *_forLoop.condition))\n\t\tsuccess = false;\n\tif (!(*this)(_forLoop.body))\n\t\tsuccess = false;\n\tif (!(*this)(_forLoop.post))\n\t\tsuccess = false;\n\n\tm_currentScope = originalScope;\n\n\treturn success;\n}\n\nbool ScopeFiller::operator()(Block const& _block)\n{\n\tbool success = true;\n\tscope(&_block).superScope = m_currentScope;\n\tm_currentScope = &scope(&_block);\n\n\t// First visit all functions to make them create\n\t// an entry in the scope according to their visibility.\n\tfor (auto const& s: _block.statements)\n\t\tif (std::holds_alternative<FunctionDefinition>(s))\n\t\t\tif (!registerFunction(std::get<FunctionDefinition>(s)))\n\t\t\t\tsuccess = false;\n\tfor (auto const& s: _block.statements)\n\t\tif (!std::visit(*this, s))\n\t\t\tsuccess = false;\n\n\tm_currentScope = m_currentScope->superScope;\n\treturn success;\n}\n\nbool ScopeFiller::registerVariable(NameWithDebugData const& _name, SourceLocation const& _location, Scope& _scope)\n{\n\tif (!_scope.registerVariable(_name.name))\n\t{\n\t\t//@TODO secondary location\n\t\tm_errorReporter.declarationError(\n\t\t\t1395_error,\n\t\t\t_location,\n\t\t\t\"Variable name \" + _name.name.str() + \" already taken in this scope.\"\n\t\t);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nbool ScopeFiller::registerFunction(FunctionDefinition const& _funDef)\n{\n\tif (!m_currentScope->registerFunction(_funDef.name, _funDef.parameters.size(), _funDef.returnVariables.size()))\n\t{\n\t\t//@TODO secondary location\n\t\tm_errorReporter.declarationError(\n\t\t\t6052_error,\n\t\t\tnativeLocationOf(_funDef),\n\t\t\t\"Function name \" + _funDef.name.str() + \" already taken in this scope.\"\n\t\t);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nScope& ScopeFiller::scope(Block const* _block)\n{\n\tauto& scope = m_info.scopes[_block];\n\tif (!scope)\n\t\tscope = std::make_shared<Scope>();\n\treturn *scope;\n}\n"
  },
  {
    "path": "libyul/ScopeFiller.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Module responsible for registering identifiers inside their scopes.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n\n#include <functional>\n#include <memory>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\nstruct SourceLocation;\n}\n\nnamespace solidity::yul\n{\n\nstruct NameWithDebugData;\nstruct Scope;\nstruct AsmAnalysisInfo;\n\n/**\n * Fills scopes with identifiers and checks for name clashes.\n * Does not resolve references.\n */\nclass ScopeFiller\n{\npublic:\n\tScopeFiller(AsmAnalysisInfo& _info, langutil::ErrorReporter& _errorReporter);\n\n\tbool operator()(Literal const&) { return true; }\n\tbool operator()(Identifier const&) { return true; }\n\tbool operator()(ExpressionStatement const& _expr);\n\tbool operator()(Assignment const&) { return true; }\n\tbool operator()(VariableDeclaration const& _variableDeclaration);\n\tbool operator()(FunctionDefinition const& _functionDefinition);\n\tbool operator()(FunctionCall const&) { return true; }\n\tbool operator()(If const& _if);\n\tbool operator()(Switch const& _switch);\n\tbool operator()(ForLoop const& _forLoop);\n\tbool operator()(Break const&) { return true; }\n\tbool operator()(Continue const&) { return true; }\n\tbool operator()(Leave const&) { return true; }\n\tbool operator()(Block const& _block);\n\nprivate:\n\tbool registerVariable(\n\t\tNameWithDebugData const& _name,\n\t\tlangutil::SourceLocation const& _location,\n\t\tScope& _scope\n\t);\n\tbool registerFunction(FunctionDefinition const& _funDef);\n\n\tScope& scope(Block const* _block);\n\n\tScope* m_currentScope = nullptr;\n\tAsmAnalysisInfo& m_info;\n\tlangutil::ErrorReporter& m_errorReporter;\n};\n\n}\n"
  },
  {
    "path": "libyul/SideEffects.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <algorithm>\n#include <set>\n\nnamespace solidity::yul\n{\n\n/**\n * Side effects of code.\n *\n * The default-constructed value applies to the \"empty code\".\n */\nstruct SideEffects\n{\n\t/// Corresponds to the effect that a Yul-builtin has on a generic data location (storage, memory\n\t/// and other blockchain state).\n\tenum Effect\n\t{\n\t\tNone,\n\t\tRead,\n\t\tWrite\n\t};\n\n\tfriend Effect operator+(Effect const& _a, Effect const& _b)\n\t{\n\t\treturn static_cast<Effect>(std::max(static_cast<int>(_a), static_cast<int>(_b)));\n\t}\n\n\t/// If true, expressions in this code can be freely moved and copied without altering the\n\t/// semantics.\n\t/// At statement level, it means that functions containing this code can be\n\t/// called multiple times, their calls can be rearranged and calls can also be\n\t/// deleted without changing the semantics.\n\t/// This means it cannot depend on storage, memory or transient storage, cannot have any side-effects,\n\t/// but it can depend on state that is constant across an EVM-call.\n\tbool movable = true;\n\t/// If true, the expressions in this code can be moved or copied (together with their arguments)\n\t/// across control flow branches and instructions as long as these instructions' 'effects' do\n\t/// not influence the 'effects' of the aforementioned expressions.\n\tbool movableApartFromEffects = true;\n\t/// If true, the code can be removed without changing the semantics.\n\tbool canBeRemoved = true;\n\t/// If true, the code can be removed without changing the semantics as long as\n\t/// the whole program does not contain the msize instruction.\n\tbool canBeRemovedIfNoMSize = true;\n\t/// If false, the code calls a for-loop or a recursive function, and therefore potentially loops\n\t/// infinitely. All builtins are set to true by default, even `invalid()`.\n\tbool cannotLoop = true;\n\t/// Can write, read or have no effect on the blockchain state, when the value of `otherState` is\n\t/// `Write`, `Read` or `None` respectively.\n\tEffect otherState = None;\n\t/// Can write, read or have no effect on storage, when the value of `storage` is `Write`, `Read`\n\t/// or `None` respectively. When the value is `Write`, the expression can invalidate storage,\n\t/// potentially indirectly through external calls.\n\tEffect storage = None;\n\t/// Can write, read or have no effect on memory, when the value of `memory` is `Write`, `Read`\n\t/// or `None` respectively. Note that, when the value is `Read`, the expression can have an\n\t/// effect on `msize()`.\n\tEffect memory = None;\n\t/// Can write, read or have no effect on transient storage, when the value of `transientStorage` is `Write`, `Read`\n\t/// or `None` respectively.  When the value is `Write`, the expression can invalidate transient storage,\n\t/// potentially indirectly through external calls.\n\tEffect transientStorage = None;\n\n\t/// @returns the worst-case side effects.\n\tstatic SideEffects worst()\n\t{\n\t\treturn SideEffects{false, false, false, false, false, Write, Write, Write, Write};\n\t}\n\n\t/// @returns the combined side effects of two pieces of code.\n\tSideEffects operator+(SideEffects const& _other)\n\t{\n\t\treturn SideEffects{\n\t\t\tmovable && _other.movable,\n\t\t\tmovableApartFromEffects && _other.movableApartFromEffects,\n\t\t\tcanBeRemoved && _other.canBeRemoved,\n\t\t\tcanBeRemovedIfNoMSize && _other.canBeRemovedIfNoMSize,\n\t\t\tcannotLoop && _other.cannotLoop,\n\t\t\totherState + _other.otherState,\n\t\t\tstorage + _other.storage,\n\t\t\tmemory + _other.memory,\n\t\t\ttransientStorage + _other.transientStorage\n\t\t};\n\t}\n\n\t/// Adds the side effects of another piece of code to this side effect.\n\tSideEffects& operator+=(SideEffects const& _other)\n\t{\n\t\t*this = *this + _other;\n\t\treturn *this;\n\t}\n\n\tbool operator==(SideEffects const& _other) const\n\t{\n\t\treturn\n\t\t\tmovable == _other.movable &&\n\t\t\tmovableApartFromEffects == _other.movableApartFromEffects &&\n\t\t\tcanBeRemoved == _other.canBeRemoved &&\n\t\t\tcanBeRemovedIfNoMSize == _other.canBeRemovedIfNoMSize &&\n\t\t\tcannotLoop == _other.cannotLoop &&\n\t\t\totherState == _other.otherState &&\n\t\t\tstorage == _other.storage &&\n\t\t\tmemory == _other.memory &&\n\t\t\ttransientStorage == _other.transientStorage;\n\t}\n};\n\n}\n"
  },
  {
    "path": "libyul/Utilities.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Some useful snippets for the optimiser.\n */\n\n#include <libyul/Utilities.h>\n\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/Exceptions.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/FixedHash.h>\n#include <libsolutil/Visitor.h>\n\n#include <boost/algorithm/string.hpp>\n\n#include <algorithm>\n#include <sstream>\n#include <vector>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nstd::string solidity::yul::reindent(std::string const& _code)\n{\n\tint constexpr indentationWidth = 4;\n\n\tauto constexpr static countBraces = [](std::string const& _s) noexcept -> int\n\t{\n\t\tauto const i = _s.find(\"//\");\n\t\tauto const e = i == _s.npos ? end(_s) : next(begin(_s), static_cast<ptrdiff_t>(i));\n\t\tauto const opening = count_if(begin(_s), e, [](auto ch) { return ch == '{' || ch == '('; });\n\t\tauto const closing = count_if(begin(_s), e, [](auto ch) { return ch == '}' || ch == ')'; });\n\t\treturn int(opening - closing);\n\t};\n\n\tstd::vector<std::string> lines;\n\tboost::split(lines, _code, boost::is_any_of(\"\\n\"));\n\tfor (std::string& line: lines)\n\t\tboost::trim(line);\n\n\t// Reduce multiple consecutive empty lines.\n\tlines = fold(lines, std::vector<std::string>{}, [](auto&& _lines, auto&& _line) {\n\t\tif (!(_line.empty() && !_lines.empty() && _lines.back().empty()))\n\t\t\t_lines.emplace_back(std::move(_line));\n\t\treturn std::move(_lines);\n\t});\n\n\tstd::stringstream out;\n\tint depth = 0;\n\n\tfor (std::string const& line: lines)\n\t{\n\t\tint const diff = countBraces(line);\n\t\tif (diff < 0)\n\t\t\tdepth += diff;\n\n\t\tif (!line.empty())\n\t\t{\n\t\t\tfor (int i = 0; i < depth * indentationWidth; ++i)\n\t\t\t\tout << ' ';\n\t\t\tout << line;\n\t\t}\n\t\tout << '\\n';\n\n\t\tif (diff > 0)\n\t\t\tdepth += diff;\n\t}\n\n\treturn out.str();\n}\n\nLiteralValue solidity::yul::valueOfNumberLiteral(std::string_view const _literal)\n{\n\treturn LiteralValue{LiteralValue::Data(_literal), std::string(_literal)};\n}\n\nLiteralValue solidity::yul::valueOfStringLiteral(std::string_view const _literal)\n{\n\tstd::string const s(_literal);\n\treturn LiteralValue{u256(h256(s, h256::FromBinary, h256::AlignLeft)), s};\n}\n\nLiteralValue solidity::yul::valueOfBuiltinStringLiteralArgument(std::string_view _literal)\n{\n\treturn LiteralValue{std::string(_literal)};\n}\n\nLiteralValue solidity::yul::valueOfBoolLiteral(std::string_view const _literal)\n{\n\tif (_literal == \"true\")\n\t\treturn LiteralValue{true};\n\telse if (_literal == \"false\")\n\t\treturn LiteralValue{false};\n\n\tyulAssert(false, \"Unexpected bool literal value!\");\n}\n\nLiteralValue solidity::yul::valueOfLiteral(std::string_view const _literal, LiteralKind const& _kind, bool const _unlimitedLiteralArgument)\n{\n\tswitch (_kind)\n\t{\n\tcase LiteralKind::Number:\n\t\treturn valueOfNumberLiteral(_literal);\n\tcase LiteralKind::Boolean:\n\t\treturn valueOfBoolLiteral(_literal);\n\tcase LiteralKind::String:\n\t\treturn _unlimitedLiteralArgument ? valueOfBuiltinStringLiteralArgument(_literal) : valueOfStringLiteral(_literal);\n\t}\n\tutil::unreachable();\n}\n\nstd::string solidity::yul::formatLiteral(solidity::yul::Literal const& _literal, bool const _validated)\n{\n\tif (_validated)\n\t\tyulAssert(validLiteral(_literal), \"Encountered invalid literal in formatLiteral.\");\n\n\tif (_literal.value.unlimited())\n\t\treturn _literal.value.builtinStringLiteralValue();\n\n\tif (_literal.value.hint())\n\t\treturn *_literal.value.hint();\n\n\tif (_literal.kind == LiteralKind::Boolean)\n\t\treturn _literal.value.value() == false ? \"false\" : \"true\";\n\n\t// if there is no hint and it is not a boolean, just stringify the u256 word\n\treturn _literal.value.value().str();\n}\n\nbool solidity::yul::validLiteral(solidity::yul::Literal const& _literal)\n{\n\tswitch (_literal.kind)\n\t{\n\tcase LiteralKind::Number:\n\t\treturn validNumberLiteral(_literal);\n\tcase LiteralKind::Boolean:\n\t\treturn validBoolLiteral(_literal);\n\tcase LiteralKind::String:\n\t\treturn validStringLiteral(_literal);\n\t}\n\tutil::unreachable();\n}\n\nbool solidity::yul::validStringLiteral(solidity::yul::Literal const& _literal)\n{\n\tif (_literal.kind != LiteralKind::String)\n\t\treturn false;\n\n\tif (_literal.value.unlimited())\n\t\treturn true;\n\n\tif (_literal.value.hint())\n\t\treturn _literal.value.hint()->size() <= 32 && _literal.value.value() == valueOfLiteral(*_literal.value.hint(), _literal.kind).value();\n\n\treturn true;\n}\n\nbool solidity::yul::validNumberLiteral(solidity::yul::Literal const& _literal)\n{\n\tif (_literal.kind != LiteralKind::Number || _literal.value.unlimited())\n\t\treturn false;\n\n\tif (!_literal.value.hint())\n\t\treturn true;\n\n\tauto const& repr = *_literal.value.hint();\n\n\tif (!isValidDecimal(repr) && !isValidHex(repr))\n\t\treturn false;\n\n\tif (bigint(repr) > u256(-1))\n\t\treturn false;\n\n\tif (_literal.value.value() != valueOfLiteral(repr, _literal.kind).value())\n\t\treturn false;\n\n\treturn true;\n}\n\nbool solidity::yul::validBoolLiteral(solidity::yul::Literal const& _literal)\n{\n\tif (_literal.kind != LiteralKind::Boolean || _literal.value.unlimited())\n\t\treturn false;\n\n\tif (_literal.value.hint() && !(*_literal.value.hint() == \"true\" || *_literal.value.hint() == \"false\"))\n\t\treturn false;\n\n\tyulAssert(u256(0) == u256(false));\n\tyulAssert(u256(1) == u256(true));\n\n\tif (_literal.value.hint())\n\t{\n\t\tif (*_literal.value.hint() == \"false\")\n\t\t\treturn _literal.value.value() == false;\n\t\telse\n\t\t\treturn _literal.value.value() == true;\n\t}\n\n\treturn _literal.value.value() == true || _literal.value.value() == false;\n}\n\ntemplate<>\nbool Less<Literal>::operator()(Literal const& _lhs, Literal const& _rhs) const\n{\n\tif (_lhs.kind != _rhs.kind)\n\t\treturn _lhs.kind < _rhs.kind;\n\n\tif (_lhs.value.unlimited() && _rhs.value.unlimited())\n\t\tyulAssert(\n\t\t\t_lhs.kind == LiteralKind::String && _rhs.kind == LiteralKind::String,\n\t\t\t\"Cannot have unlimited value that is not of String kind.\"\n\t\t);\n\n\treturn _lhs.value < _rhs.value;\n\n}\n\nbool SwitchCaseCompareByLiteralValue::operator()(Case const* _lhs, Case const* _rhs) const\n{\n\tyulAssert(_lhs && _rhs, \"\");\n\treturn Less<Literal*>{}(_lhs->value.get(), _rhs->value.get());\n}\n\nstd::string_view yul::resolveFunctionName(FunctionName const& _functionName, Dialect const& _dialect)\n{\n\tGenericVisitor visitor{\n\t\t[&](Identifier const& _identifier) -> std::string const& { return _identifier.name.str(); },\n\t\t[&](BuiltinName const& _builtin) -> std::string const& { return _dialect.builtin(_builtin.handle).name; }\n\t};\n\treturn std::visit(visitor, _functionName);\n}\n\nBuiltinFunction const* yul::resolveBuiltinFunction(FunctionName const& _functionName, Dialect const& _dialect)\n{\n\tGenericVisitor visitor{\n\t\t[&](Identifier const&) -> BuiltinFunction const* { return nullptr; },\n\t\t[&](BuiltinName const& _builtin) -> BuiltinFunction const* { return &_dialect.builtin(_builtin.handle); }\n\t};\n\treturn std::visit(visitor, _functionName);\n}\n\nBuiltinFunctionForEVM const* yul::resolveBuiltinFunctionForEVM(FunctionName const& _functionName, EVMDialect const& _dialect)\n{\n\tGenericVisitor visitor{\n\t\t[&](Identifier const&) -> BuiltinFunctionForEVM const* { return nullptr; },\n\t\t[&](BuiltinName const& _builtin) -> BuiltinFunctionForEVM const* { return &_dialect.builtin(_builtin.handle); }\n\t};\n\treturn std::visit(visitor, _functionName);\n}\n\nFunctionHandle yul::functionNameToHandle(FunctionName const& _functionName)\n{\n\tGenericVisitor visitor{\n\t\t[&](Identifier const& _identifier) -> FunctionHandle { return _identifier.name; },\n\t\t[&](BuiltinName const& _builtin) -> FunctionHandle { return _builtin.handle; }\n\t};\n\treturn std::visit(visitor, _functionName);\n}\n\n"
  },
  {
    "path": "libyul/Utilities.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Small useful snippets for the optimiser.\n */\n\n#pragma once\n\n#include <libsolutil/Common.h>\n#include <libsolutil/Numeric.h>\n#include <libyul/ASTForward.h>\n\n#include <string_view>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\nclass EVMDialect;\nstruct BuiltinFunction;\nstruct BuiltinFunctionForEVM;\n\nstd::string reindent(std::string const& _code);\n\nLiteralValue valueOfNumberLiteral(std::string_view _literal);\nLiteralValue valueOfStringLiteral(std::string_view _literal);\nLiteralValue valueOfBuiltinStringLiteralArgument(std::string_view _literal);\nLiteralValue valueOfBoolLiteral(std::string_view _literal);\nLiteralValue valueOfLiteral(std::string_view _literal, LiteralKind const& _kind, bool _unlimitedLiteralArgument = false);\nbool validLiteral(Literal const& _literal);\nbool validStringLiteral(Literal const& _literal);\nbool validNumberLiteral(Literal const& _literal);\nbool validBoolLiteral(Literal const& _literal);\n\n/// Produces a string representation of a Literal instance.\n/// @param _literal the Literal to be formatted\n/// @param _validated whether the Literal was already validated, i.e., assumptions are asserted in the method\n/// @returns the literal's string representation\nstd::string formatLiteral(Literal const& _literal, bool _validated = true);\n\n/**\n * Linear order on Yul AST nodes.\n *\n * Defines a linear order on Yul AST nodes to be used in maps and sets.\n * Note: the order is total and deterministic, but independent of the semantics, e.g.\n * it is not guaranteed that the false Literal is \"less\" than the true Literal.\n */\ntemplate<typename T>\nstruct Less\n{\n\tbool operator()(T const& _lhs, T const& _rhs) const;\n};\n\ntemplate<typename T>\nstruct Less<T*>\n{\n\tbool operator()(T const* _lhs, T const* _rhs) const\n\t{\n\t\tif (_lhs && _rhs)\n\t\t\treturn Less<T>{}(*_lhs, *_rhs);\n\t\telse\n\t\t\treturn _lhs < _rhs;\n\t}\n};\n\ntemplate<> bool Less<Literal>::operator()(Literal const& _lhs, Literal const& _rhs) const;\nextern template struct Less<Literal>;\n\n// This can only be used for cases within one switch statement and\n// relies on the fact that there are no duplicate cases.\nstruct SwitchCaseCompareByLiteralValue\n{\n\tbool operator()(Case const* _lhsCase, Case const* _rhsCase) const;\n};\n\nstd::string_view resolveFunctionName(FunctionName const& _functionName, Dialect const& _dialect);\n\nBuiltinFunction const* resolveBuiltinFunction(FunctionName const& _functionName, Dialect const& _dialect);\nBuiltinFunctionForEVM const* resolveBuiltinFunctionForEVM(FunctionName const& _functionName, EVMDialect const& _dialect);\nFunctionHandle functionNameToHandle(FunctionName const& _functionName);\n\n}\n"
  },
  {
    "path": "libyul/YulName.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/YulString.h>\n\nnamespace solidity::yul\n{\nusing YulName = YulString;\n}\n"
  },
  {
    "path": "libyul/YulStack.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/YulStack.h>\n\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/backends/evm/ssa/SSACFGBuilder.h>\n#include <libyul/backends/evm/ssa/io/JSONExporter.h>\n#include <libyul/backends/evm/EthAssemblyAdapter.h>\n#include <libyul/backends/evm/EVMCodeTransform.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/backends/evm/EVMObjectCompiler.h>\n#include <libyul/ObjectParser.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/Suite.h>\n#include <libevmasm/Assembly.h>\n#include <libevmasm/Ethdebug.h>\n#include <liblangutil/Scanner.h>\n#include <liblangutil/SourceReferenceFormatter.h>\n\n#include <boost/algorithm/string.hpp>\n\n#include <optional>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\nusing namespace solidity::yul;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\n\nCharStream const& YulStack::charStream(std::string const& _sourceName) const\n{\n\tyulAssert(m_charStream, \"\");\n\tyulAssert(m_charStream->name() == _sourceName, \"\");\n\treturn *m_charStream;\n}\n\nbool YulStack::parse(std::string const& _sourceName, std::string const& _source)\n{\n\tyulAssert(m_stackState == Empty);\n\ttry\n\t{\n\t\tm_charStream = std::make_unique<CharStream>(_source, _sourceName);\n\t\tstd::shared_ptr<Scanner> scanner = std::make_shared<Scanner>(*m_charStream);\n\t\tm_parserResult = ObjectParser(m_errorReporter, EVMDialect::strictAssemblyForEVMObjects(m_evmVersion, m_eofVersion)).parse(scanner, false);\n\t}\n\tcatch (UnimplementedFeatureError const& _error)\n\t{\n\t\treportUnimplementedFeatureError(_error);\n\t\treturn false;\n\t}\n\n\tif (!m_errorReporter.hasErrors())\n\t\tm_stackState = Parsed;\n\n\treturn m_stackState == Parsed;\n}\n\nbool YulStack::parseAndAnalyze(std::string const& _sourceName, std::string const& _source)\n{\n\tm_errors.clear();\n\tyulAssert(m_stackState == Empty);\n\n\tif (!parse(_sourceName, _source))\n\t\treturn false;\n\n\tyulAssert(m_stackState == Parsed);\n\tyulAssert(m_parserResult, \"\");\n\tyulAssert(m_parserResult->hasCode());\n\n\treturn analyzeParsed();\n}\n\nvoid YulStack::optimize()\n{\n\tyulAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\tyulAssert(m_parserResult);\n\n\ttry\n\t{\n\t\tif (\n\t\t\t!m_optimiserSettings.runYulOptimiser &&\n\t\t\tyul::MSizeFinder::containsMSize(*m_parserResult)\n\t\t)\n\t\t\treturn;\n\n\t\tauto [optimizeStackAllocation, yulOptimiserSteps, yulOptimiserCleanupSteps] = [&]() -> std::tuple<bool, std::string, std::string>\n\t\t{\n\t\t\tif (!m_optimiserSettings.runYulOptimiser)\n\t\t\t{\n\t\t\t\t// Yul optimizer disabled, but empty sequence (:) explicitly provided\n\t\t\t\tif (OptimiserSuite::isEmptyOptimizerSequence(m_optimiserSettings.yulOptimiserSteps + \":\" + m_optimiserSettings.yulOptimiserCleanupSteps))\n\t\t\t\t\treturn std::make_tuple(true, \"\", \"\");\n\t\t\t\t// Yul optimizer disabled, and no sequence explicitly provided (assumes default sequence)\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tyulAssert(\n\t\t\t\t\t\tm_optimiserSettings.yulOptimiserSteps == OptimiserSettings::DefaultYulOptimiserSteps &&\n\t\t\t\t\t\tm_optimiserSettings.yulOptimiserCleanupSteps == OptimiserSettings::DefaultYulOptimiserCleanupSteps\n\t\t\t\t\t);\n\t\t\t\t\t// Defaults are the minimum necessary to avoid running into \"Stack too deep\" constantly.\n\t\t\t\t\treturn std::make_tuple(true, \"u\", \"\");\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn std::make_tuple(\n\t\t\t\tm_optimiserSettings.optimizeStackAllocation,\n\t\t\t\tm_optimiserSettings.yulOptimiserSteps,\n\t\t\t\tm_optimiserSettings.yulOptimiserCleanupSteps\n\t\t\t);\n\t\t}();\n\n\t\tm_stackState = Parsed;\n\t\tsolAssert(m_objectOptimizer);\n\t\tm_objectOptimizer->optimize(\n\t\t\t*m_parserResult,\n\t\t\tObjectOptimizer::Settings{\n\t\t\t\tm_evmVersion,\n\t\t\t\tm_eofVersion,\n\t\t\t\toptimizeStackAllocation,\n\t\t\t\tyulOptimiserSteps,\n\t\t\t\tyulOptimiserCleanupSteps,\n\t\t\t\tm_optimiserSettings.expectedExecutionsPerDeployment\n\t\t\t}\n\t\t);\n\n\t\t// Optimizer does not maintain correct native source locations in the AST.\n\t\t// We can work around it by regenerating the AST from scratch from optimized IR.\n\t\treparse();\n\t}\n\tcatch (UnimplementedFeatureError const& _error)\n\t{\n\t\treportUnimplementedFeatureError(_error);\n\t}\n}\n\nbool YulStack::analyzeParsed()\n{\n\tyulAssert(m_stackState >= Parsed);\n\tyulAssert(m_parserResult, \"\");\n\treturn analyzeParsed(*m_parserResult);\n}\n\nbool YulStack::analyzeParsed(Object& _object)\n{\n\tyulAssert(m_stackState >= Parsed);\n\tyulAssert(_object.hasCode());\n\t_object.analysisInfo = std::make_shared<AsmAnalysisInfo>();\n\n\tAsmAnalyzer analyzer(\n\t\t*_object.analysisInfo,\n\t\tm_errorReporter,\n\t\tEVMDialect::strictAssemblyForEVMObjects(m_evmVersion, m_eofVersion),\n\t\t{},\n\t\t_object.summarizeStructure()\n\t);\n\n\tbool success = false;\n\ttry\n\t{\n\t\tsuccess = analyzer.analyze(_object.code()->root());\n\t\tfor (auto& subNode: _object.subObjects)\n\t\t\tif (auto subObject = dynamic_cast<Object*>(subNode.get()))\n\t\t\t\tif (!analyzeParsed(*subObject))\n\t\t\t\t\tsuccess = false;\n\t}\n\tcatch (UnimplementedFeatureError const& _error)\n\t{\n\t\treportUnimplementedFeatureError(_error);\n\t\tsuccess = false;\n\t}\n\n\tif (success)\n\t\tm_stackState = AnalysisSuccessful;\n\n\treturn success;\n}\n\nvoid YulStack::compileEVM(AbstractAssembly& _assembly, bool _optimize, bool _viaSSACFG) const\n{\n\tEVMObjectCompiler::compile(*m_parserResult, _assembly, _optimize, _viaSSACFG);\n}\n\nvoid YulStack::reparse()\n{\n\tyulAssert(m_parserResult);\n\tyulAssert(m_charStream);\n\n\t// NOTE: it is important for the source printed here to exactly match what the compiler will\n\t// eventually output to the user. In particular, debug info must be exactly the same.\n\t// Otherwise source locations will be off.\n\tstd::string source = print();\n\n\tYulStack cleanStack(\n\t\tm_evmVersion,\n\t\tm_eofVersion,\n\t\tm_optimiserSettings,\n\t\tm_debugInfoSelection,\n\t\tm_soliditySourceProvider,\n\t\tm_objectOptimizer\n\t);\n\tbool reanalysisSuccessful = cleanStack.parseAndAnalyze(m_charStream->name(), source);\n\tyulAssert(\n\t\treanalysisSuccessful,\n\t\tsource + \"\\n\\n\"\n\t\t\"Invalid IR generated:\\n\" +\n\t\tSourceReferenceFormatter::formatErrorInformation(cleanStack.errors(), cleanStack) + \"\\n\"\n\t);\n\n\tm_stackState = AnalysisSuccessful;\n\tm_parserResult = std::move(cleanStack.m_parserResult);\n\n\t// NOTE: We keep the char stream, and errors, even though they no longer match the object,\n\t// because it's the original source that matters to the user. Optimized code may have different\n\t// locations and fewer warnings.\n}\n\nMachineAssemblyObject YulStack::assemble(Machine _machine, bool _viaSSACFG)\n{\n\tyulAssert(m_stackState >= AnalysisSuccessful);\n\tyulAssert(m_parserResult, \"\");\n\tyulAssert(m_parserResult->hasCode(), \"\");\n\tyulAssert(m_parserResult->analysisInfo, \"\");\n\n\tswitch (_machine)\n\t{\n\tcase Machine::EVM:\n\t\treturn assembleWithDeployed({}, _viaSSACFG).first;\n\t}\n\tunreachable();\n}\n\nstd::pair<MachineAssemblyObject, MachineAssemblyObject>\nYulStack::assembleWithDeployed(std::optional<std::string_view> _deployName, bool _viaSSACFG)\n{\n\tyulAssert(m_charStream);\n\n\tauto [creationAssembly, deployedAssembly] = assembleEVMWithDeployed(_deployName, _viaSSACFG);\n\tif (!creationAssembly)\n\t{\n\t\tyulAssert(!deployedAssembly);\n\t\treturn {MachineAssemblyObject{}, MachineAssemblyObject{}};\n\t}\n\n\tMachineAssemblyObject creationObject;\n\tMachineAssemblyObject deployedObject;\n\ttry\n\t{\n\t\tcreationObject.bytecode = std::make_shared<evmasm::LinkerObject>(creationAssembly->assemble());\n\t\tyulAssert(creationObject.bytecode->immutableReferences.empty(), \"Leftover immutables.\");\n\t\tcreationObject.assembly = creationAssembly;\n\t\tcreationObject.sourceMappings = std::make_unique<std::string>();\n\t\tfor (auto const& codeSection: creationAssembly->codeSections())\n\t\t{\n\t\t\t*creationObject.sourceMappings += evmasm::AssemblyItem::computeSourceMapping(\n\t\t\t\tcodeSection.items,\n\t\t\t\t{{m_charStream->name(), 0}}\n\t\t\t);\n\t\t}\n\t\tif (debugInfoSelection().ethdebug)\n\t\t\tcreationObject.ethdebug = evmasm::ethdebug::program(creationObject.assembly->name(), 0, *creationObject.assembly, *creationObject.bytecode);\n\n\t\tif (deployedAssembly)\n\t\t{\n\t\t\tdeployedObject.bytecode = std::make_shared<evmasm::LinkerObject>(deployedAssembly->assemble());\n\t\t\tdeployedObject.assembly = deployedAssembly;\n\t\t\tif (debugInfoSelection().ethdebug)\n\t\t\t\tdeployedObject.ethdebug = evmasm::ethdebug::program(deployedObject.assembly->name(), 0, *deployedObject.assembly, *deployedObject.bytecode);\n\t\t\tsolAssert(deployedAssembly->codeSections().size() == 1);\n\t\t\tdeployedObject.sourceMappings = std::make_unique<std::string>(\n\t\t\t\tevmasm::AssemblyItem::computeSourceMapping(\n\t\t\t\t\tdeployedAssembly->codeSections().front().items,\n\t\t\t\t\t{{m_charStream->name(), 0}}\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n\tcatch (Error const& _error)\n\t{\n\t\tm_errorReporter.codeGenerationError(_error);\n\t\treturn {MachineAssemblyObject{}, MachineAssemblyObject{}};\n\t}\n\tcatch (UnimplementedFeatureError const& _error)\n\t{\n\t\treportUnimplementedFeatureError(_error);\n\t\treturn {MachineAssemblyObject{}, MachineAssemblyObject{}};\n\t}\n\n\treturn {std::move(creationObject), std::move(deployedObject)};\n}\n\nstd::pair<std::shared_ptr<evmasm::Assembly>, std::shared_ptr<evmasm::Assembly>>\nYulStack::assembleEVMWithDeployed(std::optional<std::string_view> _deployName, bool _viaSSACFG)\n{\n\tyulAssert(m_stackState >= AnalysisSuccessful);\n\tyulAssert(m_parserResult, \"\");\n\tyulAssert(m_parserResult->hasCode(), \"\");\n\tyulAssert(m_parserResult->analysisInfo, \"\");\n\n\tevmasm::Assembly assembly(m_evmVersion, true, m_eofVersion, {});\n\tEthAssemblyAdapter adapter(assembly);\n\n\t// NOTE: We always need stack optimization when Yul optimizer is disabled (unless code contains\n\t// msize). It being disabled just means that we don't use the full step sequence. We still run\n\t// it with the minimal steps required to avoid \"stack too deep\".\n\tbool optimize = m_optimiserSettings.optimizeStackAllocation || (\n\t\t!m_optimiserSettings.runYulOptimiser &&\n\t\t!yul::MSizeFinder::containsMSize(*m_parserResult)\n\t);\n\ttry\n\t{\n\t\tcompileEVM(adapter, optimize, _viaSSACFG);\n\n\t\tassembly.optimise(evmasm::Assembly::OptimiserSettings::translateSettings(m_optimiserSettings));\n\n\t\tstd::optional<evmasm::SubAssemblyID> subIndex;\n\n\t\t// Pick matching assembly if name was given\n\t\tif (_deployName.has_value())\n\t\t{\n\t\t\tfor (size_t i = 0; i < assembly.numSubs(); i++)\n\t\t\t\tif (assembly.sub({i}).name() == _deployName)\n\t\t\t\t{\n\t\t\t\t\tsubIndex = {i};\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\tsolAssert(subIndex.has_value(), \"Failed to find object to be deployed.\");\n\t\t}\n\t\t// Otherwise use heuristic: If there is a single sub-assembly, this is likely the object to be deployed.\n\t\telse if (assembly.numSubs() == 1)\n\t\t\tsubIndex = {0};\n\n\t\tif (subIndex.has_value())\n\t\t{\n\t\t\tevmasm::Assembly& runtimeAssembly = assembly.sub(*subIndex);\n\t\t\treturn {std::make_shared<evmasm::Assembly>(assembly), std::make_shared<evmasm::Assembly>(runtimeAssembly)};\n\t\t}\n\t}\n\tcatch (Error const& _error)\n\t{\n\t\tm_errorReporter.codeGenerationError(_error);\n\t\treturn {nullptr, nullptr};\n\t}\n\tcatch (UnimplementedFeatureError const& _error)\n\t{\n\t\treportUnimplementedFeatureError(_error);\n\t\treturn {nullptr, nullptr};\n\t}\n\n\treturn {std::make_shared<evmasm::Assembly>(assembly), nullptr};\n}\n\nstd::string YulStack::print() const\n{\n\tyulAssert(m_stackState >= Parsed);\n\tyulAssert(m_parserResult, \"\");\n\tyulAssert(m_parserResult->hasCode(), \"\");\n\treturn (m_debugInfoSelection.ethdebug ? \"/// ethdebug: enabled\\n\" : \"\") + m_parserResult->toString(\n\t\tm_debugInfoSelection,\n\t\tm_soliditySourceProvider\n\t) + \"\\n\";\n}\n\nJson YulStack::astJson() const\n{\n\tyulAssert(m_stackState >= Parsed);\n\tyulAssert(m_parserResult, \"\");\n\tyulAssert(m_parserResult->hasCode(), \"\");\n\treturn  m_parserResult->toJson();\n}\n\nJson YulStack::cfgJson() const\n{\n\tyulAssert(m_parserResult, \"\");\n\tyulAssert(m_parserResult->hasCode(), \"\");\n\tyulAssert(m_parserResult->analysisInfo, \"\");\n\t// FIXME: we should not regenerate the cfg, but for now this is sufficient for testing purposes\n\tauto exportCFGFromObject = [&](Object const& _object) -> Json {\n\t\t// with this set to `true`, assignments of the type `let x := 42` are preserved and added as assignment\n\t\t// operations to the control flow graphs\n\t\tbool constexpr keepLiteralAssignments = true;\n\t\t// NOTE: The block Ids are reset for each object\n\t\tstd::unique_ptr<ssa::ControlFlow> controlFlow = ssa::SSACFGBuilder::build(\n\t\t\t*_object.analysisInfo,\n\t\t\tEVMDialect::strictAssemblyForEVMObjects(m_evmVersion, m_eofVersion),\n\t\t\t_object.code()->root(),\n\t\t\tkeepLiteralAssignments\n\t\t);\n\t\tstd::unique_ptr<ssa::ControlFlowLiveness> liveness = std::make_unique<ssa::ControlFlowLiveness>(*controlFlow);\n\t\treturn ssa::io::json::exportControlFlow(*controlFlow, liveness.get());\n\t};\n\n\tstd::function<Json(std::vector<std::shared_ptr<ObjectNode>>)> exportCFGFromSubObjects;\n\texportCFGFromSubObjects = [&](std::vector<std::shared_ptr<ObjectNode>> _subObjects) -> Json {\n\t\tJson subObjectsJson = Json::object();\n\t\tfor (std::shared_ptr<ObjectNode> const& subObjectNode: _subObjects)\n\t\t\tif (Object const* subObject = dynamic_cast<Object const*>(subObjectNode.get()))\n\t\t\t{\n\t\t\t\tsubObjectsJson[subObject->name] = exportCFGFromObject(*subObject);\n\t\t\t\tsubObjectsJson[\"type\"] = \"subObject\";\n\t\t\t\tif (!subObject->subObjects.empty())\n\t\t\t\t\tsubObjectsJson[subObject->name][\"subObjects\"] = exportCFGFromSubObjects(subObject->subObjects);\n\t\t\t}\n\t\treturn subObjectsJson;\n\t};\n\n\tObject const& object = *m_parserResult.get();\n\tJson jsonObject = Json::object();\n\tjsonObject[object.name] = exportCFGFromObject(object);\n\tjsonObject[\"type\"] = \"Object\";\n\tif (!object.subObjects.empty())\n\t\tjsonObject[object.name][\"subObjects\"] = exportCFGFromSubObjects(object.subObjects);\n\treturn jsonObject;\n}\n\nstd::shared_ptr<Object> YulStack::parserResult() const\n{\n\tyulAssert(m_stackState >= AnalysisSuccessful, \"Analysis was not successful.\");\n\tyulAssert(m_parserResult, \"\");\n\tyulAssert(m_parserResult->hasCode(), \"\");\n\treturn m_parserResult;\n}\n\nDialect const& YulStack::dialect() const\n{\n\tyulAssert(m_stackState >= AnalysisSuccessful);\n\tyulAssert(m_parserResult && m_parserResult->dialect());\n\treturn *m_parserResult->dialect();\n}\n\nvoid YulStack::reportUnimplementedFeatureError(UnimplementedFeatureError const& _error)\n{\n\tyulAssert(m_charStream);\n\tyulAssert(_error.comment(), \"Errors must include a message for the user.\");\n\tif (_error.sourceLocation().sourceName)\n\t\tyulAssert(*_error.sourceLocation().sourceName == m_charStream->name());\n\tm_errorReporter.unimplementedFeatureError(1920_error, _error.sourceLocation(), *_error.comment());\n}\n"
  },
  {
    "path": "libyul/YulStack.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Full assembly stack that can support Yul as input.\n */\n\n#pragma once\n\n#include <liblangutil/CharStreamProvider.h>\n#include <liblangutil/DebugInfoSelection.h>\n#include <liblangutil/ErrorReporter.h>\n#include <liblangutil/EVMVersion.h>\n#include <liblangutil/Exceptions.h>\n\n#include <libsolutil/JSON.h>\n\n#include <libyul/Object.h>\n#include <libyul/ObjectOptimizer.h>\n#include <libyul/ObjectParser.h>\n\n#include <libsolidity/interface/OptimiserSettings.h>\n\n#include <libevmasm/LinkerObject.h>\n\n#include <memory>\n#include <string>\n\nnamespace solidity::evmasm\n{\nclass Assembly;\n}\n\nnamespace solidity::langutil\n{\nclass Scanner;\n}\n\nnamespace solidity::yul\n{\nclass AbstractAssembly;\n\n\nstruct MachineAssemblyObject\n{\n\tstd::shared_ptr<evmasm::LinkerObject> bytecode;\n\tstd::shared_ptr<evmasm::Assembly> assembly;\n\tstd::unique_ptr<std::string> sourceMappings;\n\tJson ethdebug = Json::object();\n};\n\n/*\n * Full assembly stack that can support EVM-assembly and Yul as input and EVM as output.\n */\nclass YulStack: public langutil::CharStreamProvider\n{\npublic:\n\tenum class Machine { EVM };\n\tenum State {\n\t\tEmpty,\n\t\tParsed,\n\t\tAnalysisSuccessful\n\t};\n\n\tYulStack():\n\t\tYulStack(\n\t\t\tlangutil::EVMVersion{},\n\t\t\tstd::nullopt,\n\t\t\tsolidity::frontend::OptimiserSettings::none(),\n\t\t\tlangutil::DebugInfoSelection::Default()\n\t\t)\n\t{}\n\n\tYulStack(\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tsolidity::frontend::OptimiserSettings _optimiserSettings,\n\t\tlangutil::DebugInfoSelection const& _debugInfoSelection,\n\t\tlangutil::CharStreamProvider const* _soliditySourceProvider = nullptr,\n\t\tstd::shared_ptr<ObjectOptimizer> _objectOptimizer = nullptr\n\t):\n\t\tm_evmVersion(_evmVersion),\n\t\tm_eofVersion(_eofVersion),\n\t\tm_optimiserSettings(std::move(_optimiserSettings)),\n\t\tm_debugInfoSelection(_debugInfoSelection),\n\t\tm_soliditySourceProvider(_soliditySourceProvider),\n\t\tm_errorReporter(m_errors),\n\t\tm_objectOptimizer(_objectOptimizer ? std::move(_objectOptimizer) : std::make_shared<ObjectOptimizer>())\n\t{}\n\n\t/// @returns the char stream used during parsing\n\tlangutil::CharStream const& charStream(std::string const& _sourceName) const override;\n\n\t/// Runs parsing and analysis steps, returns false if input cannot be assembled.\n\t/// Multiple calls overwrite the previous state.\n\tbool parseAndAnalyze(std::string const& _sourceName, std::string const& _source);\n\n\t/// Run the optimizer suite. Can only be used with Yul or strict assembly.\n\t/// If the settings (see constructor) disabled the optimizer, nothing is done here.\n\tvoid optimize();\n\n\t/// Run the assembly step (should only be called after parseAndAnalyze).\n\tMachineAssemblyObject assemble(Machine _machine, bool _viaSSACFG = false);\n\n\t/// Run the assembly step (should only be called after parseAndAnalyze).\n\t/// In addition to the value returned by @a assemble, returns\n\t/// a second object that is the runtime code.\n\t/// Only available for EVM.\n\tstd::pair<MachineAssemblyObject, MachineAssemblyObject>\n\tassembleWithDeployed(\n\t\tstd::optional<std::string_view> _deployName = {},\n\t\tbool _viaSSACFG = false\n\t);\n\n\t/// Run the assembly step (should only be called after parseAndAnalyze).\n\t/// Similar to @a assemblyWithDeployed, but returns EVM assembly objects.\n\t/// Only available for EVM.\n\tstd::pair<std::shared_ptr<evmasm::Assembly>, std::shared_ptr<evmasm::Assembly>>\n\tassembleEVMWithDeployed(\n\t\tstd::optional<std::string_view> _deployName = {},\n\t\tbool _viaSSACFG = false\n\t);\n\n\t/// @returns the errors generated during parsing, analysis (and potentially assembly).\n\tlangutil::ErrorList const& errors() const { return m_errors; }\n\tbool hasErrors() const { return m_errorReporter.hasErrors(); }\n\tbool hasErrorsWarningsOrInfos() const { return m_errorReporter.hasErrorsWarningsOrInfos(); }\n\n\t/// Pretty-print the input after having parsed it.\n\tstd::string print() const;\n\tJson astJson() const;\n\n\t// return the JSON representation of the YuL CFG (experimental)\n\tJson cfgJson() const;\n\n\t/// Return the parsed and analyzed object.\n\tstd::shared_ptr<Object> parserResult() const;\n\n\tDialect const& dialect() const;\n\n\tlangutil::DebugInfoSelection debugInfoSelection() const { return m_debugInfoSelection; }\n\nprivate:\n\tbool parse(std::string const& _sourceName, std::string const& _source);\n\tbool analyzeParsed();\n\tbool analyzeParsed(yul::Object& _object);\n\n\tvoid compileEVM(yul::AbstractAssembly& _assembly, bool _optimize, bool _viaSSACFG) const;\n\n\t/// Prints the Yul object stored internally and parses it again.\n\t/// This ensures that the debug info in the AST matches the source that printing would produce\n\t/// rather than the initial source.\n\t/// @warning Does not update the error list or the original source (@a m_charStream) to make\n\t/// it possible to report errors to the user even after the optimization has been performed.\n\tvoid reparse();\n\n\tvoid reportUnimplementedFeatureError(langutil::UnimplementedFeatureError const& _error);\n\n\tlangutil::EVMVersion m_evmVersion;\n\tstd::optional<uint8_t> m_eofVersion;\n\tsolidity::frontend::OptimiserSettings m_optimiserSettings;\n\tlangutil::DebugInfoSelection m_debugInfoSelection{};\n\n\t/// Provider of the Solidity sources that the Yul code was generated from.\n\t/// Necessary when code snippets are requested as a part of debug info. When null, code snippets are omitted.\n\t/// NOTE: Not owned by YulStack, the user must ensure that it is not destroyed before the stack is.\n\tlangutil::CharStreamProvider const* m_soliditySourceProvider{};\n\n\tstd::unique_ptr<langutil::CharStream> m_charStream;\n\n\tState m_stackState = Empty;\n\tstd::shared_ptr<yul::Object> m_parserResult;\n\tlangutil::ErrorList m_errors;\n\tlangutil::ErrorReporter m_errorReporter;\n\n\tstd::shared_ptr<ObjectOptimizer> m_objectOptimizer;\n};\n\n}\n"
  },
  {
    "path": "libyul/YulString.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * String abstraction that avoids copies.\n */\n\n#pragma once\n\n#include <fmt/format.h>\n\n#include <unordered_map>\n#include <memory>\n#include <vector>\n#include <string>\n#include <string_view>\n#include <functional>\n\nnamespace solidity::yul\n{\n\n/// Repository for YulStrings.\n/// Owns the string data for all YulStrings, which can be referenced by a Handle.\n/// A Handle consists of an ID (that depends on the insertion order of YulStrings and is potentially\n/// non-deterministic) and a deterministic string hash.\nclass YulStringRepository\n{\npublic:\n\tstruct Handle\n\t{\n\t\tsize_t id;\n\t\tstd::uint64_t hash;\n\t};\n\n\tstatic YulStringRepository& instance()\n\t{\n\t\tstatic YulStringRepository inst;\n\t\treturn inst;\n\t}\n\n\tHandle stringToHandle(std::string_view const _string)\n\t{\n\t\tif (_string.empty())\n\t\t\treturn { 0, emptyHash() };\n\t\tstd::uint64_t h = hash(_string);\n\t\tauto range = m_hashToID.equal_range(h);\n\t\tfor (auto it = range.first; it != range.second; ++it)\n\t\t\tif (*m_strings[it->second] == _string)\n\t\t\t\treturn Handle{it->second, h};\n\t\tm_strings.emplace_back(std::make_shared<std::string>(_string));\n\t\tsize_t id = m_strings.size() - 1;\n\t\tm_hashToID.emplace_hint(range.second, std::make_pair(h, id));\n\n\t\treturn Handle{id, h};\n\t}\n\tstd::string const& idToString(size_t _id) const { return *m_strings.at(_id); }\n\n\tstatic std::uint64_t hash(std::string_view const v)\n\t{\n\t\t// FNV hash - can be replaced by a better one, e.g. xxhash64\n\t\tstd::uint64_t hash = emptyHash();\n\t\tfor (char c: v)\n\t\t{\n\t\t\thash *= 1099511628211u;\n\t\t\thash ^= static_cast<uint64_t>(c);\n\t\t}\n\n\t\treturn hash;\n\t}\n\tstatic constexpr std::uint64_t emptyHash() { return 14695981039346656037u; }\n\t/// Clear the repository.\n\t/// Use with care - there cannot be any dangling YulString references.\n\t/// If references need to be cleared manually, register the callback via\n\t/// resetCallback.\n\tstatic void reset()\n\t{\n\t\tfor (auto const& cb: resetCallbacks())\n\t\t\tcb();\n\t\tinstance() = YulStringRepository{};\n\t}\n\t/// Struct that registers a reset callback as a side-effect of its construction.\n\t/// Useful as static local variable to register a reset callback once.\n\tstruct ResetCallback\n\t{\n\t\tResetCallback(std::function<void()> _fun)\n\t\t{\n\t\t\tYulStringRepository::resetCallbacks().emplace_back(std::move(_fun));\n\t\t}\n\t};\n\nprivate:\n\tYulStringRepository() = default;\n\tYulStringRepository(YulStringRepository const&) = delete;\n\tYulStringRepository(YulStringRepository&&) = default;\n\tYulStringRepository& operator=(YulStringRepository const& _rhs) = delete;\n\tYulStringRepository& operator=(YulStringRepository&& _rhs) = default;\n\n\tstatic std::vector<std::function<void()>>& resetCallbacks()\n\t{\n\t\tstatic std::vector<std::function<void()>> callbacks;\n\t\treturn callbacks;\n\t}\n\n\tstd::vector<std::shared_ptr<std::string>> m_strings = {std::make_shared<std::string>()};\n\tstd::unordered_multimap<std::uint64_t, size_t> m_hashToID = {{emptyHash(), 0}};\n};\n\n/// Wrapper around handles into the YulString repository.\n/// Equality of two YulStrings is determined by comparing their ID.\n/// The <-operator depends on the string hash and is not consistent\n/// with string comparisons (however, it is still deterministic).\nclass YulString\n{\npublic:\n\tYulString() = default;\n\texplicit YulString(std::string_view const _s): m_handle(YulStringRepository::instance().stringToHandle(_s)) {}\n\tYulString(YulString const&) = default;\n\tYulString(YulString&&) = default;\n\tYulString& operator=(YulString const&) = default;\n\tYulString& operator=(YulString&&) = default;\n\n\t/// This is not consistent with the string <-operator!\n\t/// First compares the string hashes. If they are equal\n\t/// it checks for identical IDs (only identical strings have\n\t/// identical IDs and identical strings do not compare as \"less\").\n\t/// If the hashes are identical and the strings are distinct, it\n\t/// falls back to string comparison.\n\tbool operator<(YulString const& _other) const\n\t{\n\t\tif (m_handle.hash < _other.m_handle.hash) return true;\n\t\tif (_other.m_handle.hash < m_handle.hash) return false;\n\t\tif (m_handle.id == _other.m_handle.id) return false;\n\t\treturn str() < _other.str();\n\t}\n\t/// Equality is determined based on the string ID.\n\tbool operator==(YulString const& _other) const { return m_handle.id == _other.m_handle.id; }\n\tbool operator!=(YulString const& _other) const { return m_handle.id != _other.m_handle.id; }\n\n\tbool empty() const { return m_handle.id == 0; }\n\tstd::string const& str() const\n\t{\n\t\treturn YulStringRepository::instance().idToString(m_handle.id);\n\t}\n\n\tuint64_t hash() const { return m_handle.hash; }\n\nprivate:\n\t/// Handle of the string. Assumes that the empty string has ID zero.\n\tYulStringRepository::Handle m_handle{ 0, YulStringRepository::emptyHash() };\n};\n\ninline YulString operator\"\"_yulname(char const* _string, std::size_t _size)\n{\n\treturn YulString(std::string_view(_string, _size));\n}\n\n}\n\nnamespace std\n{\ntemplate<> struct hash<solidity::yul::YulString>\n{\n\tsize_t operator()(solidity::yul::YulString const& x) const\n\t{\n\t\treturn static_cast<size_t>(x.hash());\n\t}\n};\n}\n"
  },
  {
    "path": "libyul/backends/evm/AbstractAssembly.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @date 2017\n * Abstract assembly interface, subclasses of which are to be used with the generic\n * bytecode generator.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n\n#include <libevmasm/SubAssemblyID.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Numeric.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <functional>\n#include <memory>\n#include <optional>\n\nnamespace solidity::langutil\n{\nstruct SourceLocation;\n}\n\nnamespace solidity::evmasm\n{\nenum class Instruction: uint8_t;\n}\n\nnamespace solidity::yul\n{\nstruct Identifier;\n\n///\n/// Assembly class that abstracts both the libevmasm assembly and the new Yul assembly.\n///\nclass AbstractAssembly\n{\npublic:\n\tusing LabelID = size_t;\n\tusing SubID = evmasm::SubAssemblyID;\n\tusing ContainerID = uint8_t;\n\tusing FunctionID = uint16_t;\n\tenum class JumpType { Ordinary, IntoFunction, OutOfFunction };\n\n\tvirtual ~AbstractAssembly() = default;\n\n\t/// Set a new source location valid starting from the next instruction.\n\tvirtual void setSourceLocation(langutil::SourceLocation const& _location) = 0;\n\t/// Retrieve the current height of the stack. This does not have to be zero\n\t/// at the beginning.\n\tvirtual int stackHeight() const = 0;\n\tvirtual void setStackHeight(int height) = 0;\n\t/// Append an EVM instruction.\n\tvirtual void appendInstruction(evmasm::Instruction _instruction) = 0;\n\t/// Append a constant.\n\tvirtual void appendConstant(u256 const& _constant) = 0;\n\t/// Append a label.\n\tvirtual void appendLabel(LabelID _labelId) = 0;\n\t/// Append a label reference.\n\tvirtual void appendLabelReference(LabelID _labelId) = 0;\n\t/// Generate a new unique label.\n\tvirtual LabelID newLabelId() = 0;\n\t/// Returns a label identified by the given name. Creates it if it does not yet exist.\n\tvirtual LabelID namedLabel(std::string const& _name, size_t _params, size_t _returns, std::optional<size_t> _sourceID) = 0;\n\t/// Append a reference to a to-be-linked symbol.\n\t/// Currently, we assume that the value is always a 20 byte number.\n\tvirtual void appendLinkerSymbol(std::string const& _name) = 0;\n\n\t/// Append raw bytes that stay untouched by the optimizer.\n\tvirtual void appendVerbatim(bytes _data, size_t _arguments, size_t _returnVariables) = 0;\n\n\t/// Append a jump instruction.\n\t/// @param _stackDiffAfter the stack adjustment after this instruction.\n\t/// This is helpful to stack height analysis if there is no continuing control flow.\n\tvirtual void appendJump(int _stackDiffAfter, JumpType _jumpType = JumpType::Ordinary) = 0;\n\n\t/// Append a jump-to-immediate operation.\n\t/// @param _stackDiffAfter the stack adjustment after this instruction.\n\tvirtual void appendJumpTo(LabelID _labelId, int _stackDiffAfter = 0, JumpType _jumpType = JumpType::Ordinary) = 0;\n\t/// Append a jump-to-if-immediate operation.\n\tvirtual void appendJumpToIf(LabelID _labelId, JumpType _jumpType = JumpType::Ordinary) = 0;\n\n\t/// Append the assembled size as a constant.\n\tvirtual void appendAssemblySize() = 0;\n\t/// Creates a new sub-assembly, which can be referenced using dataSize and dataOffset.\n\tvirtual std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(bool _creation, std::string _name = \"\") = 0;\n\n\t/// Registers a new function with given signature and returns its ID.\n\t/// The function is initially empty and its body must be filled with instructions.\n\t/// `_rets` even for non-returning function matters in case of stack height calculation.\n\tvirtual FunctionID registerFunction(uint8_t _args, uint8_t _rets, bool _nonReturning) = 0;\n\t/// Selects a function as a target for newly appended instructions.\n\t/// May only be called after the main code section is already filled and\n\t/// must not be called when another function is already selected.\n\t/// Filling the same function more than once is not allowed.\n\t/// @a endFunction() must be called at the end to finalize the function.\n\tvirtual void beginFunction(FunctionID _functionID) = 0;\n\t/// Finalizes the process of filling a function body and switches back to the main code section.\n\t/// Must not be called if no function is selected.\n\t/// Must be called after filling the main yul section\n\tvirtual void endFunction() = 0;\n\t/// Appends function call to a function under given ID\n\tvirtual void appendFunctionCall(FunctionID _functionID) = 0;\n\t/// Appends an instruction that returns values from the current function.\n\t/// Only allowed inside a function body.\n\tvirtual void appendFunctionReturn() = 0;\n\n\t/// Appends the offset of the given sub-assembly or data.\n\tvirtual void appendDataOffset(std::vector<SubID> const& _subPath) = 0;\n\t/// Appends the size of the given sub-assembly or data.\n\tvirtual void appendDataSize(std::vector<SubID> const& _subPath) = 0;\n\t/// Appends the given data to the assembly and returns its ID.\n\tvirtual SubID appendData(bytes const& _data) = 0;\n\n\t/// Appends loading an immutable variable.\n\tvirtual void appendImmutable(std::string const& _identifier) = 0;\n\t/// Appends an assignment to an immutable variable.\n\tvirtual void appendImmutableAssignment(std::string const& _identifier) = 0;\n\n\t/// Appends an operation that loads 32 bytes of data from a known offset relative to the start of the static_aux_data area of the EOF data section.\n\t/// Note that static_aux_data is only a part or the data section.\n\t/// It is preceded by the pre_deploy_data, whose size is not determined before the bytecode is assembled, and which cannot be accessed using this function.\n\t/// The function is meant to allow indexing into static_aux_data in a way that's independent of the size of pre_deploy_data.\n\tvirtual void appendAuxDataLoadN(uint16_t _offset) = 0;\n\n\t/// Appends EOF contract creation instruction which takes creation code from subcontainer with _containerID.\n\tvirtual void appendEOFCreate(ContainerID _containerID) = 0;\n\t/// Appends EOF contract return instruction which returns a subcontainer ID (_containerID) with auxiliary data filled in.\n\tvirtual void appendReturnContract(ContainerID _containerID) = 0;\n\t/// Appends data to the very end of the bytecode. Repeated calls concatenate.\n\t/// EOF auxiliary data in data section and the auxiliary data are different things.\n\tvirtual void appendToAuxiliaryData(bytes const& _data) = 0;\n\n\t/// Appends a SWAPN with 1-based indexing for @arg _depth. I.e. a depth of 1 would be equivalent to emitting SWAP1.\n\t/// @arg _depth ranges from 1 to 256.\n\tvirtual void appendSwapN(size_t _depth) = 0;\n\t/// Appends a DUPN with 1-based indexing for @arg _depth. I.e. a depth of 1 would be equivalent to emitting DUP1.\n\t/// @arg _depth ranges from 1 to 256.\n\tvirtual void appendDupN(size_t _depth) = 0;\n\n\t/// Mark this assembly as invalid. Any attempt to request bytecode from it should throw.\n\tvirtual void markAsInvalid() = 0;\n\n\t/// @returns the EVM version the assembly targets.\n\tvirtual langutil::EVMVersion evmVersion() const = 0;\n};\n\nenum class IdentifierContext { LValue, RValue, VariableDeclaration, NonExternal };\n\n/// Object that is used to resolve references and generate code for access to identifiers external\n/// to inline assembly (not used in standalone assembly mode).\nstruct ExternalIdentifierAccess\n{\n\tusing Resolver = std::function<bool(Identifier const&, IdentifierContext, bool /*_crossesFunctionBoundary*/)>;\n\t/// Resolve an external reference given by the identifier in the given context.\n\t/// @returns the size of the value (number of stack slots) or size_t(-1) if not found.\n\tResolver resolve;\n\tusing CodeGenerator = std::function<void(Identifier const&, IdentifierContext, yul::AbstractAssembly&)>;\n\t/// Generate code for retrieving the value (rvalue context) or storing the value (lvalue context)\n\t/// of an identifier. The code should be appended to the assembly. In rvalue context, the value is supposed\n\t/// to be put onto the stack, in lvalue context, the value is assumed to be at the top of the stack.\n\tCodeGenerator generateCode;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/AsmCodeGen.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Helper to compile Yul code using libevmasm.\n */\n\n#include <libyul/backends/evm/AsmCodeGen.h>\n\n#include <libyul/backends/evm/EthAssemblyAdapter.h>\n#include <libyul/backends/evm/EVMCodeTransform.h>\n#include <libyul/AST.h>\n#include <libyul/AsmAnalysisInfo.h>\n\n#include <libsolutil/StackTooDeepString.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\n\nvoid CodeGenerator::assemble(\n\tBlock const& _parsedData,\n\tAsmAnalysisInfo& _analysisInfo,\n\tevmasm::Assembly& _assembly,\n\tlangutil::EVMVersion _evmVersion,\n\tstd::optional<uint8_t> _eofVersion,\n\tExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen,\n\tbool _useNamedLabelsForFunctions,\n\tbool _optimizeStackAllocation\n)\n{\n\tEthAssemblyAdapter assemblyAdapter(_assembly);\n\tBuiltinContext builtinContext;\n\tCodeTransform transform(\n\t\tassemblyAdapter,\n\t\t_analysisInfo,\n\t\t_parsedData,\n\t\tEVMDialect::strictAssemblyForEVM(_evmVersion, _eofVersion),\n\t\tbuiltinContext,\n\t\t_optimizeStackAllocation,\n\t\t_identifierAccessCodeGen,\n\t\t\t_useNamedLabelsForFunctions ?\n\t\t\tCodeTransform::UseNamedLabels::YesAndForceUnique :\n\t\t\tCodeTransform::UseNamedLabels::Never\n\t);\n\ttransform(_parsedData);\n\tif (!transform.stackErrors().empty())\n\t\tassertThrow(\n\t\t\tfalse,\n\t\t\tlangutil::StackTooDeepError,\n\t\t\tutil::stackTooDeepString + \" When compiling inline assembly\" +\n\t\t\t(transform.stackErrors().front().comment() ? \": \" + *transform.stackErrors().front().comment() : \".\")\n\t\t);\n}\n"
  },
  {
    "path": "libyul/backends/evm/AsmCodeGen.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Helper to compile Yul code using libevmasm.\n */\n\n#pragma once\n\n#include <libyul/backends/evm/AbstractAssembly.h>\n#include <libyul/AsmAnalysis.h>\n#include <liblangutil/EVMVersion.h>\n\nnamespace solidity::evmasm\n{\nclass Assembly;\n}\n\nnamespace solidity::yul\n{\nstruct Block;\nstruct AsmAnalysisInfo;\n\nclass CodeGenerator\n{\npublic:\n\t/// Performs code generation and appends generated to _assembly.\n\tstatic void assemble(\n\t\tBlock const& _parsedData,\n\t\tAsmAnalysisInfo& _analysisInfo,\n\t\tevmasm::Assembly& _assembly,\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tExternalIdentifierAccess::CodeGenerator _identifierAccess = {},\n\t\tbool _useNamedLabelsForFunctions = false,\n\t\tbool _optimizeStackAllocation = false\n\t);\n};\n}\n"
  },
  {
    "path": "libyul/backends/evm/ConstantOptimiser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that replaces constants by expressions that compute them.\n */\n\n#include <libyul/backends/evm/ConstantOptimiser.h>\n\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/backends/evm/EVMMetrics.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <variant>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nusing Representation = ConstantOptimiser::Representation;\n\nnamespace\n{\nstruct MiniEVMInterpreter\n{\n\texplicit MiniEVMInterpreter(EVMDialect const& _dialect): m_dialect(_dialect) {}\n\n\tu256 eval(Expression const& _expr)\n\t{\n\t\treturn std::visit(*this, _expr);\n\t}\n\n\tu256 eval(evmasm::Instruction _instr, std::vector<Expression> const& _arguments)\n\t{\n\t\tstd::vector<u256> args;\n\t\tfor (auto const& arg: _arguments)\n\t\t\targs.emplace_back(eval(arg));\n\t\tswitch (_instr)\n\t\t{\n\t\tcase evmasm::Instruction::ADD:\n\t\t\treturn args.at(0) + args.at(1);\n\t\tcase evmasm::Instruction::SUB:\n\t\t\treturn args.at(0) - args.at(1);\n\t\tcase evmasm::Instruction::MUL:\n\t\t\treturn args.at(0) * args.at(1);\n\t\tcase evmasm::Instruction::EXP:\n\t\t\treturn exp256(args.at(0), args.at(1));\n\t\tcase evmasm::Instruction::SHL:\n\t\t\treturn args.at(0) > 255 ? 0 : (args.at(1) << unsigned(args.at(0)));\n\t\tcase evmasm::Instruction::NOT:\n\t\t\treturn ~args.at(0);\n\t\tdefault:\n\t\t\tyulAssert(false, \"Invalid operation generated in constant optimizer.\");\n\t\t}\n\t\treturn 0;\n\t}\n\n\tu256 operator()(FunctionCall const& _funCall)\n\t{\n\t\tBuiltinFunctionForEVM const* builtin = resolveBuiltinFunctionForEVM(_funCall.functionName, m_dialect);\n\t\tyulAssert(builtin, \"Expected builtin function.\");\n\t\tyulAssert(builtin->instruction, \"Expected EVM instruction.\");\n\t\treturn eval(*builtin->instruction, _funCall.arguments);\n\t}\n\tu256 operator()(Literal const& _literal)\n\t{\n\t\treturn _literal.value.value();\n\t}\n\tu256 operator()(Identifier const&) { yulAssert(false, \"\"); }\n\n\tEVMDialect const& m_dialect;\n};\n}\n\nvoid ConstantOptimiser::visit(Expression& _e)\n{\n\tif (std::holds_alternative<Literal>(_e))\n\t{\n\t\tLiteral const& literal = std::get<Literal>(_e);\n\t\tif (literal.kind != LiteralKind::Number)\n\t\t\treturn;\n\n\t\tif (\n\t\t\tExpression const* repr =\n\t\t\t\tRepresentationFinder(m_dialect, m_meter, debugDataOf(_e), m_cache)\n\t\t\t\t.tryFindRepresentation(literal.value.value())\n\t\t)\n\t\t\t_e = ASTCopier{}.translate(*repr);\n\t}\n\telse\n\t\tASTModifier::visit(_e);\n}\n\nExpression const* RepresentationFinder::tryFindRepresentation(u256 const& _value)\n{\n\tif (_value < 0x10000)\n\t\treturn nullptr;\n\n\tRepresentation const& repr = findRepresentation(_value);\n\tif (std::holds_alternative<Literal>(*repr.expression))\n\t\treturn nullptr;\n\telse\n\t\treturn repr.expression.get();\n}\n\nRepresentation const& RepresentationFinder::findRepresentation(u256 const& _value)\n{\n\tif (m_cache.count(_value))\n\t\treturn m_cache.at(_value);\n\n\tyulAssert(m_dialect.auxiliaryBuiltinHandles().not_);\n\tyulAssert(m_dialect.auxiliaryBuiltinHandles().exp);\n\tyulAssert(m_dialect.auxiliaryBuiltinHandles().mul);\n\tyulAssert(m_dialect.auxiliaryBuiltinHandles().add);\n\tyulAssert(m_dialect.auxiliaryBuiltinHandles().sub);\n\n\tauto const& auxHandles = m_dialect.auxiliaryBuiltinHandles();\n\n\tRepresentation routine = represent(_value);\n\n\tif (numberEncodingSize(~_value) < numberEncodingSize(_value))\n\t\t// Negated is shorter to represent\n\t\troutine = min(std::move(routine), represent(*auxHandles.not_, findRepresentation(~_value)));\n\n\t// Decompose value into a * 2**k + b where abs(b) << 2**k\n\tfor (unsigned bits = 255; bits > 8 && m_maxSteps > 0; --bits)\n\t{\n\t\tunsigned gapDetector = unsigned((_value >> (bits - 8)) & 0x1ff);\n\t\tif (gapDetector != 0xff && gapDetector != 0x100)\n\t\t\tcontinue;\n\n\t\tu256 powerOfTwo = u256(1) << bits;\n\t\tu256 upperPart = _value >> bits;\n\t\tbigint lowerPart = _value & (powerOfTwo - 1);\n\t\tif ((powerOfTwo - lowerPart) < lowerPart)\n\t\t{\n\t\t\tlowerPart = lowerPart - powerOfTwo; // make it negative\n\t\t\tupperPart++;\n\t\t}\n\t\tif (upperPart == 0)\n\t\t\tcontinue;\n\t\tif (abs(lowerPart) >= (powerOfTwo >> 8))\n\t\t\tcontinue;\n\t\tRepresentation newRoutine;\n\t\tif (m_dialect.evmVersion().hasBitwiseShifting())\n\t\t\tnewRoutine = represent(*auxHandles.shl, represent(bits), findRepresentation(upperPart));\n\t\telse\n\t\t{\n\t\t\tnewRoutine = represent(*auxHandles.exp, represent(2), represent(bits));\n\t\t\tif (upperPart != 1)\n\t\t\t\tnewRoutine = represent(*auxHandles.mul, findRepresentation(upperPart), newRoutine);\n\t\t}\n\n\t\tif (newRoutine.cost >= routine.cost)\n\t\t\tcontinue;\n\n\t\tif (lowerPart > 0)\n\t\t\tnewRoutine = represent(*auxHandles.add, newRoutine, findRepresentation(u256(abs(lowerPart))));\n\t\telse if (lowerPart < 0)\n\t\t\tnewRoutine = represent(*auxHandles.sub, newRoutine, findRepresentation(u256(abs(lowerPart))));\n\n\t\tif (m_maxSteps > 0)\n\t\t\tm_maxSteps--;\n\t\troutine = min(std::move(routine), std::move(newRoutine));\n\t}\n\tyulAssert(MiniEVMInterpreter{m_dialect}.eval(*routine.expression) == _value, \"Invalid expression generated.\");\n\treturn m_cache[_value] = std::move(routine);\n}\n\nRepresentation RepresentationFinder::represent(u256 const& _value) const\n{\n\tRepresentation repr;\n\trepr.expression = std::make_unique<Expression>(Literal{m_debugData, LiteralKind::Number, LiteralValue{_value, formatNumber(_value)}});\n\trepr.cost = m_meter.costs(*repr.expression);\n\treturn repr;\n}\n\nRepresentation RepresentationFinder::represent(\n\tBuiltinHandle const& _instruction,\n\tRepresentation const& _argument\n) const\n{\n\tRepresentation repr;\n\trepr.expression = std::make_unique<Expression>(FunctionCall{\n\t\tm_debugData,\n\t\tBuiltinName{m_debugData, _instruction},\n\t\t{ASTCopier{}.translate(*_argument.expression)}\n\t});\n\trepr.cost = _argument.cost + m_meter.instructionCosts(*m_dialect.builtin(_instruction).instruction);\n\treturn repr;\n}\n\nRepresentation RepresentationFinder::represent(\n\tBuiltinHandle const& _instruction,\n\tRepresentation const& _arg1,\n\tRepresentation const& _arg2\n) const\n{\n\tRepresentation repr;\n\trepr.expression = std::make_unique<Expression>(FunctionCall{\n\t\tm_debugData,\n\t\tBuiltinName{m_debugData, _instruction},\n\t\t{ASTCopier{}.translate(*_arg1.expression), ASTCopier{}.translate(*_arg2.expression)}\n\t});\n\trepr.cost = m_meter.instructionCosts(*m_dialect.builtin(_instruction).instruction) + _arg1.cost + _arg2.cost;\n\treturn repr;\n}\n\nRepresentation RepresentationFinder::min(Representation _a, Representation _b)\n{\n\tif (_a.cost <= _b.cost)\n\t\treturn _a;\n\telse\n\t\treturn _b;\n}\n"
  },
  {
    "path": "libyul/backends/evm/ConstantOptimiser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that replaces constants by expressions that compute them.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/YulName.h>\n#include <libyul/Dialect.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/ASTForward.h>\n\n#include <liblangutil/DebugData.h>\n\n#include <libsolutil/Common.h>\n\n#include <tuple>\n#include <map>\n#include <memory>\n\nnamespace solidity::yul\n{\nclass Dialect;\nclass GasMeter;\n\n/**\n * Optimisation stage that replaces constants by expressions that compute them.\n *\n * Prerequisite: None\n */\nclass ConstantOptimiser: public ASTModifier\n{\npublic:\n\tConstantOptimiser(EVMDialect const& _dialect, GasMeter const& _meter):\n\t\tm_dialect(_dialect),\n\t\tm_meter(_meter)\n\t{}\n\n\tvoid visit(Expression& _e) override;\n\n\tstruct Representation\n\t{\n\t\tstd::unique_ptr<Expression> expression;\n\t\tbigint cost;\n\t};\n\nprivate:\n\tEVMDialect const& m_dialect;\n\tGasMeter const& m_meter;\n\tstd::map<u256, Representation> m_cache;\n};\n\nclass RepresentationFinder\n{\npublic:\n\tusing Representation = ConstantOptimiser::Representation;\n\tRepresentationFinder(\n\t\tEVMDialect const& _dialect,\n\t\tGasMeter const& _meter,\n\t\tlangutil::DebugData::ConstPtr _debugData,\n\t\tstd::map<u256, Representation>& _cache\n\t):\n\t\tm_dialect(_dialect),\n\t\tm_meter(_meter),\n\t\tm_debugData(std::move(_debugData)),\n\t\tm_cache(_cache)\n\t{}\n\n\t/// @returns a cheaper representation for the number than its representation\n\t/// as a literal or nullptr otherwise.\n\tExpression const* tryFindRepresentation(u256 const& _value);\n\nprivate:\n\t/// Recursively try to find the cheapest representation of the given number,\n\t/// literal if necessary.\n\tRepresentation const& findRepresentation(u256 const& _value);\n\n\tRepresentation represent(u256 const& _value) const;\n\tRepresentation represent(BuiltinHandle const& _instruction, Representation const& _arg) const;\n\tRepresentation represent(BuiltinHandle const& _instruction, Representation const& _arg1, Representation const& _arg2) const;\n\n\tRepresentation min(Representation _a, Representation _b);\n\n\tEVMDialect const& m_dialect;\n\tGasMeter const& m_meter;\n\tlangutil::DebugData::ConstPtr m_debugData;\n\t/// Counter for the complexity of optimization, will stop when it reaches zero.\n\tsize_t m_maxSteps = 10000;\n\tstd::map<u256, Representation>& m_cache;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ControlFlowGraph.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Control flow graph and stack layout structures used during code generation.\n */\n\n#pragma once\n\n#include <libyul/AST.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/Dialect.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Scope.h>\n\n#include <libsolutil/Numeric.h>\n\n#include <functional>\n#include <list>\n#include <vector>\n\nnamespace solidity::yul\n{\n\n/// The following structs describe different kinds of stack slots.\n/// Each stack slot is equality- and less-than-comparable and\n/// specifies an attribute ``canBeFreelyGenerated`` that is true,\n/// if a slot of this kind always has a known value at compile time and\n/// therefore can safely be removed from the stack at any time and then\n/// regenerated later.\n\n/// The label pushed as return label before a function call, i.e. the label the call is supposed to return to.\nstruct FunctionCallReturnLabelSlot\n{\n\tstd::reference_wrapper<yul::FunctionCall const> call;\n\tbool operator==(FunctionCallReturnLabelSlot const& _rhs) const { return &call.get() == &_rhs.call.get(); }\n\tbool operator<(FunctionCallReturnLabelSlot const& _rhs) const { return &call.get() < &_rhs.call.get(); }\n\tstatic constexpr bool canBeFreelyGenerated = true;\n};\n/// The return jump target of a function while generating the code of the function body.\n/// I.e. the caller of a function pushes a ``FunctionCallReturnLabelSlot`` (see above) before jumping to the function and\n/// this very slot is viewed as ``FunctionReturnLabelSlot`` inside the function body and jumped to when returning from\n/// the function.\nstruct FunctionReturnLabelSlot\n{\n\tstd::reference_wrapper<Scope::Function const> function;\n\tbool operator==(FunctionReturnLabelSlot const& _rhs) const\n\t{\n\t\t// There can never be return label slots of different functions on stack simultaneously.\n\t\tyulAssert(&function.get() == &_rhs.function.get(), \"\");\n\t\treturn true;\n\t}\n\tbool operator<(FunctionReturnLabelSlot const& _rhs) const\n\t{\n\t\t// There can never be return label slots of different functions on stack simultaneously.\n\t\tyulAssert(&function.get() == &_rhs.function.get(), \"\");\n\t\treturn false;\n\t}\n\tstatic constexpr bool canBeFreelyGenerated = false;\n};\n/// A slot containing the current value of a particular variable.\nstruct VariableSlot\n{\n\tstd::reference_wrapper<Scope::Variable const> variable;\n\tlangutil::DebugData::ConstPtr debugData{};\n\tbool operator==(VariableSlot const& _rhs) const { return &variable.get() == &_rhs.variable.get(); }\n\tbool operator<(VariableSlot const& _rhs) const { return &variable.get() < &_rhs.variable.get(); }\n\tstatic constexpr bool canBeFreelyGenerated = false;\n};\n/// A slot containing a literal value.\nstruct LiteralSlot\n{\n\tu256 value;\n\tlangutil::DebugData::ConstPtr debugData{};\n\tbool operator==(LiteralSlot const& _rhs) const { return value == _rhs.value; }\n\tbool operator<(LiteralSlot const& _rhs) const { return value < _rhs.value; }\n\tstatic constexpr bool canBeFreelyGenerated = true;\n};\n/// A slot containing the index-th return value of a previous call.\nstruct TemporarySlot\n{\n\t/// The call that returned this slot.\n\tstd::reference_wrapper<yul::FunctionCall const> call;\n\t/// Specifies to which of the values returned by the call this slot refers.\n\t/// index == 0 refers to the slot deepest in the stack after the call.\n\tsize_t index = 0;\n\tbool operator==(TemporarySlot const& _rhs) const { return &call.get() == &_rhs.call.get() && index == _rhs.index; }\n\tbool operator<(TemporarySlot const& _rhs) const { return std::make_pair(&call.get(), index) < std::make_pair(&_rhs.call.get(), _rhs.index); }\n\tstatic constexpr bool canBeFreelyGenerated = false;\n};\n/// A slot containing an arbitrary value that is always eventually popped and never used.\n/// Used to maintain stack balance on control flow joins.\nstruct JunkSlot\n{\n\tbool operator==(JunkSlot const&) const { return true; }\n\tbool operator<(JunkSlot const&) const { return false; }\n\tstatic constexpr bool canBeFreelyGenerated = true;\n};\nusing StackSlot = std::variant<FunctionCallReturnLabelSlot, FunctionReturnLabelSlot, VariableSlot, LiteralSlot, TemporarySlot, JunkSlot>;\n/// The stack top is usually the last element of the vector.\nusing Stack = std::vector<StackSlot>;\n\n/// @returns true if @a _slot can be generated on the stack at any time.\ninline bool canBeFreelyGenerated(StackSlot const& _slot)\n{\n\treturn std::visit([](auto const& _typedSlot) { return std::decay_t<decltype(_typedSlot)>::canBeFreelyGenerated; }, _slot);\n}\n\n/// Control flow graph consisting of ``CFG::BasicBlock``s connected by control flow.\nstruct CFG\n{\n\texplicit CFG() {}\n\tCFG(CFG const&) = delete;\n\tCFG(CFG&&) = delete;\n\tCFG& operator=(CFG const&) = delete;\n\tCFG& operator=(CFG&&) = delete;\n\t~CFG() = default;\n\n\tstruct BuiltinCall\n\t{\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\tstd::reference_wrapper<BuiltinFunction const> builtin;\n\t\tstd::reference_wrapper<yul::FunctionCall const> functionCall;\n\t\t/// Number of proper arguments with a position on the stack, excluding literal arguments.\n\t\t/// Literal arguments (like the literal string in ``datasize``) do not have a location on the stack,\n\t\t/// but are handled internally by the builtin's code generation function.\n\t\tsize_t arguments = 0;\n\t};\n\tstruct FunctionCall\n\t{\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\tstd::reference_wrapper<Scope::Function const> function;\n\t\tstd::reference_wrapper<yul::FunctionCall const> functionCall;\n\t\t/// True, if the call is recursive, i.e. entering the function involves a control flow path (potentially involving\n\t\t/// more intermediate function calls) that leads back to this very call.\n\t\tbool recursive = false;\n\t\t/// True, if the call can return.\n\t\tbool canContinue = true;\n\t};\n\tstruct Assignment\n\t{\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\t/// The variables being assigned to also occur as ``output`` in the ``Operation`` containing\n\t\t/// the assignment, but are also stored here for convenience.\n\t\tstd::vector<VariableSlot> variables;\n\t};\n\n\tstruct Operation\n\t{\n\t\t/// Stack slots this operation expects at the top of the stack and consumes.\n\t\tStack input;\n\t\t/// Stack slots this operation leaves on the stack as output.\n\t\tStack output;\n\t\tstd::variant<FunctionCall, BuiltinCall, Assignment> operation;\n\t};\n\n\tstruct FunctionInfo;\n\t/// A basic control flow block containing ``Operation``s acting on the stack.\n\t/// Maintains a list of entry blocks and a typed exit.\n\tstruct BasicBlock\n\t{\n\t\tstruct MainExit {};\n\t\tstruct ConditionalJump\n\t\t{\n\t\t\tlangutil::DebugData::ConstPtr debugData;\n\t\t\tStackSlot condition;\n\t\t\tBasicBlock* nonZero = nullptr;\n\t\t\tBasicBlock* zero = nullptr;\n\t\t};\n\t\tstruct Jump\n\t\t{\n\t\t\tlangutil::DebugData::ConstPtr debugData;\n\t\t\tBasicBlock* target = nullptr;\n\t\t\t/// The only backwards jumps are jumps from loop post to loop condition.\n\t\t\tbool backwards = false;\n\t\t};\n\t\tstruct FunctionReturn\n\t\t{\n\t\t\tlangutil::DebugData::ConstPtr debugData;\n\t\t\tCFG::FunctionInfo* info = nullptr;\n\t\t};\n\t\tstruct Terminated {};\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\tstd::vector<BasicBlock*> entries;\n\t\tstd::vector<Operation> operations;\n\t\t/// True, if the block is the beginning of a disconnected subgraph. That is, if no block that is reachable\n\t\t/// from this block is an ancestor of this block. In other words, this is true, if this block is the target\n\t\t/// of a cut-edge/bridge in the CFG or if the block itself terminates.\n\t\tbool isStartOfSubGraph = false;\n\t\t/// True, if there is a path from this block to a function return.\n\t\tbool needsCleanStack = false;\n\t\t/// If the block starts a sub-graph and does not lead to a function return, we are free to add junk to it.\n\t\tbool allowsJunk() const { return isStartOfSubGraph && !needsCleanStack; }\n\t\tstd::variant<MainExit, Jump, ConditionalJump, FunctionReturn, Terminated> exit = MainExit{};\n\t};\n\n\tstruct FunctionInfo\n\t{\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\tScope::Function const& function;\n\t\tFunctionDefinition const& functionDefinition;\n\t\tBasicBlock* entry = nullptr;\n\t\tstd::vector<VariableSlot> parameters;\n\t\tstd::vector<VariableSlot> returnVariables;\n\t\tstd::vector<BasicBlock*> exits;\n\t\tbool canContinue = true;\n\t};\n\n\t/// The main entry point, i.e. the start of the outermost Yul block.\n\tBasicBlock* entry = nullptr;\n\t/// Subgraphs for functions.\n\tstd::map<Scope::Function const*, FunctionInfo> functionInfo;\n\t/// List of functions in order of declaration.\n\tstd::list<Scope::Function const*> functions;\n\n\t/// Container for blocks for explicit ownership.\n\tstd::list<BasicBlock> blocks;\n\t/// Container for generated variables for explicit ownership.\n\t/// Ghost variables are generated to store switch conditions when transforming the control flow\n\t/// of a switch to a sequence of conditional jumps.\n\tstd::list<Scope::Variable> ghostVariables;\n\t/// Container for generated calls for explicit ownership.\n\t/// Ghost calls are used for the equality comparisons of the switch condition ghost variable with\n\t/// the switch case literals when transforming the control flow of a switch to a sequence of conditional jumps.\n\tstd::list<yul::FunctionCall> ghostCalls;\n\n\tBasicBlock& makeBlock(langutil::DebugData::ConstPtr _debugData)\n\t{\n\t\treturn blocks.emplace_back(BasicBlock{std::move(_debugData), {}, {}});\n\t}\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ControlFlowGraphBuilder.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Transformation of a Yul AST into a control flow graph.\n */\n\n#include <libyul/backends/evm/ControlFlowGraphBuilder.h>\n#include <libyul/AST.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Utilities.h>\n#include <libyul/ControlFlowSideEffectsCollector.h>\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <libsolutil/Visitor.h>\n#include <libsolutil/Algorithms.h>\n\n#include <range/v3/action/push_back.hpp>\n#include <range/v3/action/erase.hpp>\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/concat.hpp>\n#include <range/v3/view/drop_last.hpp>\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/filter.hpp>\n#include <range/v3/view/iota.hpp>\n#include <range/v3/view/map.hpp>\n#include <range/v3/view/reverse.hpp>\n#include <range/v3/view/single.hpp>\n#include <range/v3/view/take_last.hpp>\n#include <range/v3/view/transform.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nnamespace\n{\n/// Removes edges to blocks that are not reachable.\nvoid cleanUnreachable(CFG& _cfg)\n{\n\t// If operation is a function call it adds the callee entry as child\n\tauto const addFunctionsEntries = [&_cfg](CFG::BasicBlock* _node, auto&& _addChild)\n\t{\n\t\tfor (auto const& operation: _node->operations)\n\t\t{\n\t\t\tif (auto const* functionCall = std::get_if<CFG::FunctionCall>(&operation.operation))\n\t\t\t{\n\t\t\t\tauto const functionInfo = _cfg.functionInfo.at(&(functionCall->function.get()));\n\t\t\t\t_addChild(functionInfo.entry);\n\t\t\t}\n\t\t}\n\t};\n\n\t// Determine which blocks are reachable from the entry.\n\tutil::BreadthFirstSearch<CFG::BasicBlock*> reachabilityCheck{{_cfg.entry}};\n\treachabilityCheck.run([&](CFG::BasicBlock* _node, auto&& _addChild) {\n\t\taddFunctionsEntries(_node, _addChild);\n\t\tvisit(util::GenericVisitor{\n\t\t\t[&](CFG::BasicBlock::Jump const& _jump) {\n\t\t\t\t_addChild(_jump.target);\n\t\t\t},\n\t\t\t[&](CFG::BasicBlock::ConditionalJump const& _jump) {\n\t\t\t\t_addChild(_jump.zero);\n\t\t\t\t_addChild(_jump.nonZero);\n\t\t\t},\n\t\t\t[](CFG::BasicBlock::FunctionReturn const&) {},\n\t\t\t[](CFG::BasicBlock::Terminated const&) {},\n\t\t\t[](CFG::BasicBlock::MainExit const&) {}\n\t\t}, _node->exit);\n\t});\n\n\t// Remove all entries from unreachable nodes from the graph.\n\tfor (CFG::BasicBlock* node: reachabilityCheck.visited)\n\t\tstd::erase_if(node->entries, [&](CFG::BasicBlock* entry) -> bool {\n\t\t\treturn !reachabilityCheck.visited.count(entry);\n\t\t});\n\n\t// Remove functions which are never referenced.\n\t_cfg.functions.erase(std::remove_if(_cfg.functions.begin(), _cfg.functions.end(), [&](auto const& item) {\n\t\treturn !reachabilityCheck.visited.count(_cfg.functionInfo.at(item).entry);\n\t}), _cfg.functions.end());\n\n\t// Remove functionInfos which are never referenced.\n\tstd::erase_if(_cfg.functionInfo, [&](auto const& entry) -> bool {\n\t\treturn !reachabilityCheck.visited.count(entry.second.entry);\n\t});\n}\n\n/// Sets the ``recursive`` member to ``true`` for all recursive function calls.\nvoid markRecursiveCalls(CFG& _cfg)\n{\n\tstd::map<CFG::BasicBlock*, std::vector<CFG::FunctionCall*>> callsPerBlock;\n\tauto const& findCalls = [&](CFG::BasicBlock* _block)\n\t{\n\t\tif (auto* calls = util::valueOrNullptr(callsPerBlock, _block))\n\t\t\treturn *calls;\n\t\tstd::vector<CFG::FunctionCall*>& calls = callsPerBlock[_block];\n\t\tutil::BreadthFirstSearch<CFG::BasicBlock*>{{_block}}.run([&](CFG::BasicBlock* _block, auto _addChild) {\n\t\t\tfor (auto& operation: _block->operations)\n\t\t\t\tif (auto* functionCall = std::get_if<CFG::FunctionCall>(&operation.operation))\n\t\t\t\t\tcalls.emplace_back(functionCall);\n\t\t\tstd::visit(util::GenericVisitor{\n\t\t\t\t[&](CFG::BasicBlock::MainExit const&) {},\n\t\t\t\t[&](CFG::BasicBlock::Jump const& _jump)\n\t\t\t\t{\n\t\t\t\t\t_addChild(_jump.target);\n\t\t\t\t},\n\t\t\t\t[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump)\n\t\t\t\t{\n\t\t\t\t\t_addChild(_conditionalJump.zero);\n\t\t\t\t\t_addChild(_conditionalJump.nonZero);\n\t\t\t\t},\n\t\t\t\t[&](CFG::BasicBlock::FunctionReturn const&) {},\n\t\t\t\t[&](CFG::BasicBlock::Terminated const&) {},\n\t\t\t}, _block->exit);\n\t\t});\n\t\treturn calls;\n\t};\n\tfor (auto& functionInfo: _cfg.functionInfo | ranges::views::values)\n\t\tfor (CFG::FunctionCall* call: findCalls(functionInfo.entry))\n\t\t{\n\t\t\tutil::BreadthFirstSearch<CFG::FunctionCall*> breadthFirstSearch{{call}};\n\t\t\tbreadthFirstSearch.run([&](CFG::FunctionCall* _call, auto _addChild) {\n\t\t\t\tauto& calledFunctionInfo = _cfg.functionInfo.at(&_call->function.get());\n\t\t\t\tif (&calledFunctionInfo == &functionInfo)\n\t\t\t\t{\n\t\t\t\t\tcall->recursive = true;\n\t\t\t\t\tbreadthFirstSearch.abort();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (CFG::FunctionCall* nestedCall: findCalls(_cfg.functionInfo.at(&_call->function.get()).entry))\n\t\t\t\t\t_addChild(nestedCall);\n\t\t\t});\n\t\t}\n}\n\n/// Marks each cut-vertex in the CFG, i.e. each block that begins a disconnected sub-graph of the CFG.\n/// Entering such a block means that control flow will never return to a previously visited block.\nvoid markStartsOfSubGraphs(CFG& _cfg)\n{\n\tstd::vector<CFG::BasicBlock*> entries;\n\tentries.emplace_back(_cfg.entry);\n\tfor (auto&& functionInfo: _cfg.functionInfo | ranges::views::values)\n\t\tentries.emplace_back(functionInfo.entry);\n\tfor (auto& entry: entries)\n\t{\n\t\t/**\n\t\t * Detect bridges following Algorithm 1 in https://arxiv.org/pdf/2108.07346.pdf\n\t\t * and mark the bridge targets as starts of sub-graphs.\n\t\t */\n\t\tstd::set<CFG::BasicBlock*> visited;\n\t\tstd::map<CFG::BasicBlock*, size_t> disc;\n\t\tstd::map<CFG::BasicBlock*, size_t> low;\n\t\tstd::map<CFG::BasicBlock*, CFG::BasicBlock*> parent;\n\t\tsize_t time = 0;\n\t\tauto dfs = [&](CFG::BasicBlock* _u, auto _recurse) -> void {\n\t\t\tvisited.insert(_u);\n\t\t\tdisc[_u] = low[_u] = time;\n\t\t\ttime++;\n\n\t\t\tstd::vector<CFG::BasicBlock*> children = _u->entries;\n\t\t\tvisit(util::GenericVisitor{\n\t\t\t\t[&](CFG::BasicBlock::Jump const& _jump) {\n\t\t\t\t\tchildren.emplace_back(_jump.target);\n\t\t\t\t},\n\t\t\t\t[&](CFG::BasicBlock::ConditionalJump const& _jump) {\n\t\t\t\t\tchildren.emplace_back(_jump.zero);\n\t\t\t\t\tchildren.emplace_back(_jump.nonZero);\n\t\t\t\t},\n\t\t\t\t[&](CFG::BasicBlock::FunctionReturn const&) {},\n\t\t\t\t[&](CFG::BasicBlock::Terminated const&) { _u->isStartOfSubGraph = true; },\n\t\t\t\t[&](CFG::BasicBlock::MainExit const&) { _u->isStartOfSubGraph = true; }\n\t\t\t}, _u->exit);\n\t\t\tyulAssert(!util::contains(children, _u));\n\n\t\t\tfor (CFG::BasicBlock* v: children)\n\t\t\t\tif (!visited.count(v))\n\t\t\t\t{\n\t\t\t\t\tparent[v] = _u;\n\t\t\t\t\t_recurse(v, _recurse);\n\t\t\t\t\tlow[_u] = std::min(low[_u], low[v]);\n\t\t\t\t\tif (low[v] > disc[_u])\n\t\t\t\t\t{\n\t\t\t\t\t\t// _u <-> v is a cut edge in the undirected graph\n\t\t\t\t\t\tbool edgeVtoU = util::contains(_u->entries, v);\n\t\t\t\t\t\tbool edgeUtoV = util::contains(v->entries, _u);\n\t\t\t\t\t\tif (edgeVtoU && !edgeUtoV)\n\t\t\t\t\t\t\t// Cut edge v -> _u\n\t\t\t\t\t\t\t_u->isStartOfSubGraph = true;\n\t\t\t\t\t\telse if (edgeUtoV && !edgeVtoU)\n\t\t\t\t\t\t\t// Cut edge _u -> v\n\t\t\t\t\t\t\tv->isStartOfSubGraph = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (v != parent[_u])\n\t\t\t\t\tlow[_u] = std::min(low[_u], disc[v]);\n\t\t};\n\t\tdfs(entry, dfs);\n\t}\n}\n\n/// Marks each block that needs to maintain a clean stack. That is each block that has an outgoing\n/// path to a function return.\nvoid markNeedsCleanStack(CFG& _cfg)\n{\n\tfor (auto& functionInfo: _cfg.functionInfo | ranges::views::values)\n\t\tfor (CFG::BasicBlock* exit: functionInfo.exits)\n\t\t\tutil::BreadthFirstSearch<CFG::BasicBlock*>{{exit}}.run([&](CFG::BasicBlock* _block, auto _addChild) {\n\t\t\t\t_block->needsCleanStack = true;\n\t\t\t\tfor (CFG::BasicBlock* entry: _block->entries)\n\t\t\t\t\t_addChild(entry);\n\t\t\t});\n}\n}\n\nstd::unique_ptr<CFG> ControlFlowGraphBuilder::build(\n\tAsmAnalysisInfo const& _analysisInfo,\n\tDialect const& _dialect,\n\tBlock const& _block\n)\n{\n\tstd::optional<uint8_t> eofVersion;\n\tif (EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&_dialect))\n\t\teofVersion = evmDialect->eofVersion();\n\n\tauto result = std::make_unique<CFG>();\n\tresult->entry = &result->makeBlock(debugDataOf(_block));\n\n\tControlFlowSideEffectsCollector sideEffects(_dialect, _block);\n\tControlFlowGraphBuilder builder(*result, _analysisInfo, sideEffects.functionSideEffects(), _dialect);\n\tbuilder.m_currentBlock = result->entry;\n\tbuilder(_block);\n\n\tcleanUnreachable(*result);\n\tmarkRecursiveCalls(*result);\n\tmarkStartsOfSubGraphs(*result);\n\tmarkNeedsCleanStack(*result);\n\n\t// TODO: It might be worthwhile to run some further simplifications on the graph itself here.\n\t// E.g. if there is a jump to a node that has the jumping node as its only entry, the nodes can be fused, etc.\n\n\treturn result;\n}\n\nControlFlowGraphBuilder::ControlFlowGraphBuilder(\n\tCFG& _graph,\n\tAsmAnalysisInfo const& _analysisInfo,\n\tstd::unordered_map<FunctionDefinition const*, ControlFlowSideEffects> const& _functionSideEffects,\n\tDialect const& _dialect\n):\n\tm_graph(_graph),\n\tm_info(_analysisInfo),\n\tm_functionSideEffects(_functionSideEffects),\n\tm_dialect(_dialect)\n{\n\tif (EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&m_dialect))\n\t\tm_simulateFunctionsWithJumps = !evmDialect->eofVersion().has_value();\n}\n\nStackSlot ControlFlowGraphBuilder::operator()(Literal const& _literal)\n{\n\treturn LiteralSlot{_literal.value.value(), _literal.debugData};\n}\n\nStackSlot ControlFlowGraphBuilder::operator()(Identifier const& _identifier)\n{\n\treturn VariableSlot{lookupVariable(_identifier.name), _identifier.debugData};\n}\n\nStackSlot ControlFlowGraphBuilder::operator()(Expression const& _expression)\n{\n\treturn std::visit(*this, _expression);\n}\n\nStackSlot ControlFlowGraphBuilder::operator()(FunctionCall const& _call)\n{\n\tStack const& output = visitFunctionCall(_call);\n\tyulAssert(output.size() == 1, \"\");\n\treturn output.front();\n}\n\nvoid ControlFlowGraphBuilder::operator()(VariableDeclaration const& _varDecl)\n{\n\tyulAssert(m_currentBlock, \"\");\n\tauto declaredVariables = _varDecl.variables | ranges::views::transform([&](NameWithDebugData const& _var) {\n\t\treturn VariableSlot{lookupVariable(_var.name), _var.debugData};\n\t}) | ranges::to<std::vector<VariableSlot>>;\n\tStack input;\n\tif (_varDecl.value)\n\t\tinput = visitAssignmentRightHandSide(*_varDecl.value, declaredVariables.size());\n\telse\n\t\tinput = Stack(_varDecl.variables.size(), LiteralSlot{0, _varDecl.debugData});\n\tm_currentBlock->operations.emplace_back(CFG::Operation{\n\t\tstd::move(input),\n\t\tdeclaredVariables | ranges::to<Stack>,\n\t\tCFG::Assignment{_varDecl.debugData, declaredVariables}\n\t});\n}\nvoid ControlFlowGraphBuilder::operator()(Assignment const& _assignment)\n{\n\tauto assignedVariables = _assignment.variableNames | ranges::views::transform([&](Identifier const& _var) {\n\t\treturn VariableSlot{lookupVariable(_var.name), _var.debugData};\n\t}) | ranges::to<std::vector<VariableSlot>>;\n\n\tStack input = visitAssignmentRightHandSide(*_assignment.value, assignedVariables.size());\n\tyulAssert(m_currentBlock);\n\tm_currentBlock->operations.emplace_back(CFG::Operation{\n\t\tstd::move(input),\n\t\t// output\n\t\tassignedVariables | ranges::to<Stack>,\n\t\t// operation\n\t\tCFG::Assignment{_assignment.debugData, assignedVariables}\n\t});\n}\nvoid ControlFlowGraphBuilder::operator()(ExpressionStatement const& _exprStmt)\n{\n\tstd::visit(util::GenericVisitor{\n\t\t[&](FunctionCall const& _call) {\n\t\t\tStack const& output = visitFunctionCall(_call);\n\t\t\tyulAssert(output.empty(), \"\");\n\t\t},\n\t\t[&](auto const&) { yulAssert(false, \"\"); }\n\t}, _exprStmt.expression);\n}\n\nvoid ControlFlowGraphBuilder::operator()(Block const& _block)\n{\n\tScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get());\n\tfor (auto const& statement: _block.statements)\n\t\tif (auto const* function = std::get_if<FunctionDefinition>(&statement))\n\t\t\tregisterFunction(*function);\n\tfor (auto const& statement: _block.statements)\n\t\tstd::visit(*this, statement);\n}\n\nvoid ControlFlowGraphBuilder::operator()(If const& _if)\n{\n\tauto& ifBranch = m_graph.makeBlock(debugDataOf(_if.body));\n\tauto& afterIf = m_graph.makeBlock(debugDataOf(*m_currentBlock));\n\tStackSlot condition = std::visit(*this, *_if.condition);\n\tmakeConditionalJump(debugDataOf(_if), std::move(condition), ifBranch, afterIf);\n\tm_currentBlock = &ifBranch;\n\t(*this)(_if.body);\n\tjump(debugDataOf(_if.body), afterIf);\n}\n\nvoid ControlFlowGraphBuilder::operator()(Switch const& _switch)\n{\n\tyulAssert(m_currentBlock, \"\");\n\tlangutil::DebugData::ConstPtr preSwitchDebugData = debugDataOf(_switch);\n\n\tauto ghostVariableId = m_graph.ghostVariables.size();\n\tYulName ghostVariableName(\"GHOST[\" + std::to_string(ghostVariableId) + \"]\");\n\tauto& ghostVar = m_graph.ghostVariables.emplace_back(Scope::Variable{ghostVariableName});\n\n\t// Artificially generate:\n\t// let <ghostVariable> := <switchExpression>\n\tVariableSlot ghostVarSlot{ghostVar, debugDataOf(*_switch.expression)};\n\tStackSlot expression = std::visit(*this, *_switch.expression);\n\tm_currentBlock->operations.emplace_back(CFG::Operation{\n\t\tStack{std::move(expression)},\n\t\tStack{ghostVarSlot},\n\t\tCFG::Assignment{_switch.debugData, {ghostVarSlot}}\n\t});\n\n\tstd::optional<BuiltinHandle> const& equalityBuiltinHandle = m_dialect.equalityFunctionHandle();\n\tyulAssert(equalityBuiltinHandle);\n\n\t// Artificially generate:\n\t// eq(<literal>, <ghostVariable>)\n\tauto makeValueCompare = [&](Case const& _case) {\n\t\tyul::FunctionCall const& ghostCall = m_graph.ghostCalls.emplace_back(yul::FunctionCall{\n\t\t\tdebugDataOf(_case),\n\t\t\tBuiltinName{{}, *equalityBuiltinHandle},\n\t\t\t{*_case.value, Identifier{{}, ghostVariableName}}\n\t\t});\n\t\tBuiltinFunction const& equalityBuiltin = m_dialect.builtin(*equalityBuiltinHandle);\n\t\tCFG::Operation& operation = m_currentBlock->operations.emplace_back(CFG::Operation{\n\t\t\tStack{ghostVarSlot, LiteralSlot{_case.value->value.value(), debugDataOf(*_case.value)}},\n\t\t\tStack{TemporarySlot{ghostCall, 0}},\n\t\t\tCFG::BuiltinCall{debugDataOf(_case), equalityBuiltin, ghostCall, 2},\n\t\t});\n\t\treturn operation.output.front();\n\t};\n\tCFG::BasicBlock& afterSwitch = m_graph.makeBlock(preSwitchDebugData);\n\tyulAssert(!_switch.cases.empty(), \"\");\n\tfor (auto const& switchCase: _switch.cases | ranges::views::drop_last(1))\n\t{\n\t\tyulAssert(switchCase.value, \"\");\n\t\tauto& caseBranch = m_graph.makeBlock(debugDataOf(switchCase.body));\n\t\tauto& elseBranch = m_graph.makeBlock(debugDataOf(_switch));\n\t\tmakeConditionalJump(debugDataOf(switchCase), makeValueCompare(switchCase), caseBranch, elseBranch);\n\t\tm_currentBlock = &caseBranch;\n\t\t(*this)(switchCase.body);\n\t\tjump(debugDataOf(switchCase.body), afterSwitch);\n\t\tm_currentBlock = &elseBranch;\n\t}\n\tCase const& switchCase = _switch.cases.back();\n\tif (switchCase.value)\n\t{\n\t\tCFG::BasicBlock& caseBranch = m_graph.makeBlock(debugDataOf(switchCase.body));\n\t\tmakeConditionalJump(debugDataOf(switchCase), makeValueCompare(switchCase), caseBranch, afterSwitch);\n\t\tm_currentBlock = &caseBranch;\n\t}\n\t(*this)(switchCase.body);\n\tjump(debugDataOf(switchCase.body), afterSwitch);\n}\n\nvoid ControlFlowGraphBuilder::operator()(ForLoop const& _loop)\n{\n\tlangutil::DebugData::ConstPtr preLoopDebugData = debugDataOf(_loop);\n\tScopedSaveAndRestore scopeRestore(m_scope, m_info.scopes.at(&_loop.pre).get());\n\t(*this)(_loop.pre);\n\n\tstd::optional<bool> constantCondition;\n\tif (auto const* literalCondition = std::get_if<yul::Literal>(_loop.condition.get()))\n\t\tconstantCondition = literalCondition->value.value() != 0;\n\n\tCFG::BasicBlock& loopCondition = m_graph.makeBlock(debugDataOf(*_loop.condition));\n\tCFG::BasicBlock& loopBody = m_graph.makeBlock(debugDataOf(_loop.body));\n\tCFG::BasicBlock& post = m_graph.makeBlock(debugDataOf(_loop.post));\n\tCFG::BasicBlock& afterLoop = m_graph.makeBlock(preLoopDebugData);\n\n\tScopedSaveAndRestore scopedSaveAndRestore(m_forLoopInfo, ForLoopInfo{afterLoop, post});\n\n\tif (constantCondition.has_value())\n\t{\n\t\tif (*constantCondition)\n\t\t{\n\t\t\tjump(debugDataOf(_loop.pre), loopBody);\n\t\t\t(*this)(_loop.body);\n\t\t\tjump(debugDataOf(_loop.body), post);\n\t\t\t(*this)(_loop.post);\n\t\t\tjump(debugDataOf(_loop.post), loopBody, true);\n\t\t}\n\t\telse\n\t\t\tjump(debugDataOf(_loop.pre), afterLoop);\n\t}\n\telse\n\t{\n\t\tjump(debugDataOf(_loop.pre), loopCondition);\n\t\tStackSlot condition = std::visit(*this, *_loop.condition);\n\t\tmakeConditionalJump(debugDataOf(*_loop.condition), std::move(condition), loopBody, afterLoop);\n\t\tm_currentBlock = &loopBody;\n\t\t(*this)(_loop.body);\n\t\tjump(debugDataOf(_loop.body), post);\n\t\t(*this)(_loop.post);\n\t\tjump(debugDataOf(_loop.post), loopCondition, true);\n\t}\n\n\tm_currentBlock = &afterLoop;\n}\n\nvoid ControlFlowGraphBuilder::operator()(Break const& _break)\n{\n\tyulAssert(m_forLoopInfo.has_value(), \"\");\n\tjump(debugDataOf(_break), m_forLoopInfo->afterLoop);\n\tm_currentBlock = &m_graph.makeBlock(debugDataOf(*m_currentBlock));\n}\n\nvoid ControlFlowGraphBuilder::operator()(Continue const& _continue)\n{\n\tyulAssert(m_forLoopInfo.has_value(), \"\");\n\tjump(debugDataOf(_continue), m_forLoopInfo->post);\n\tm_currentBlock = &m_graph.makeBlock(debugDataOf(*m_currentBlock));\n}\n\n// '_leave' and '__leave' are reserved in VisualStudio\nvoid ControlFlowGraphBuilder::operator()(Leave const& leave_)\n{\n\tyulAssert(m_currentFunction.has_value(), \"\");\n\tm_currentBlock->exit = CFG::BasicBlock::FunctionReturn{debugDataOf(leave_), *m_currentFunction};\n\t(*m_currentFunction)->exits.emplace_back(m_currentBlock);\n\tm_currentBlock = &m_graph.makeBlock(debugDataOf(*m_currentBlock));\n}\n\nvoid ControlFlowGraphBuilder::operator()(FunctionDefinition const& _function)\n{\n\tyulAssert(m_scope, \"\");\n\tyulAssert(m_scope->identifiers.count(_function.name), \"\");\n\tScope::Function& function = std::get<Scope::Function>(m_scope->identifiers.at(_function.name));\n\tm_graph.functions.emplace_back(&function);\n\n\tCFG::FunctionInfo& functionInfo = m_graph.functionInfo.at(&function);\n\n\tControlFlowGraphBuilder builder{m_graph, m_info, m_functionSideEffects, m_dialect};\n\tbuilder.m_currentFunction = &functionInfo;\n\tbuilder.m_currentBlock = functionInfo.entry;\n\tbuilder(_function.body);\n\tfunctionInfo.exits.emplace_back(builder.m_currentBlock);\n\tbuilder.m_currentBlock->exit = CFG::BasicBlock::FunctionReturn{debugDataOf(_function), &functionInfo};\n}\n\nvoid ControlFlowGraphBuilder::registerFunction(FunctionDefinition const& _functionDefinition)\n{\n\tyulAssert(m_scope, \"\");\n\tyulAssert(m_scope->identifiers.count(_functionDefinition.name), \"\");\n\tScope::Function& function = std::get<Scope::Function>(m_scope->identifiers.at(_functionDefinition.name));\n\n\tyulAssert(m_info.scopes.at(&_functionDefinition.body), \"\");\n\tScope* virtualFunctionScope = m_info.scopes.at(m_info.virtualBlocks.at(&_functionDefinition).get()).get();\n\tyulAssert(virtualFunctionScope, \"\");\n\n\tbool inserted = m_graph.functionInfo.emplace(std::make_pair(&function, CFG::FunctionInfo{\n\t\t_functionDefinition.debugData,\n\t\tfunction,\n\t\t_functionDefinition,\n\t\t&m_graph.makeBlock(debugDataOf(_functionDefinition.body)),\n\t\t_functionDefinition.parameters | ranges::views::transform([&](auto const& _param) {\n\t\t\treturn VariableSlot{\n\t\t\t\tstd::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_param.name)),\n\t\t\t\t_param.debugData\n\t\t\t};\n\t\t}) | ranges::to<std::vector>,\n\t\t_functionDefinition.returnVariables | ranges::views::transform([&](auto const& _retVar) {\n\t\t\treturn VariableSlot{\n\t\t\t\tstd::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_retVar.name)),\n\t\t\t\t_retVar.debugData\n\t\t\t};\n\t\t}) | ranges::to<std::vector>,\n\t\t{},\n\t\tm_functionSideEffects.at(&_functionDefinition).canContinue\n\t})).second;\n\tyulAssert(inserted);\n}\n\nStack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call)\n{\n\tyulAssert(m_scope, \"\");\n\tyulAssert(m_currentBlock, \"\");\n\n\tStack const* output = nullptr;\n\tbool canContinue = true;\n\tif (BuiltinFunction const* builtin = resolveBuiltinFunction(_call.functionName, m_dialect))\n\t{\n\t\tStack inputs;\n\t\tfor (auto&& [idx, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse)\n\t\t\tif (!builtin->literalArgument(idx).has_value())\n\t\t\t\tinputs.emplace_back(std::visit(*this, arg));\n\t\tCFG::BuiltinCall builtinCall{_call.debugData, *builtin, _call, inputs.size()};\n\t\toutput = &m_currentBlock->operations.emplace_back(CFG::Operation{\n\t\t\t// input\n\t\t\tstd::move(inputs),\n\t\t\t// output\n\t\t\tranges::views::iota(0u, builtin->numReturns) | ranges::views::transform([&](size_t _i) {\n\t\t\t\treturn TemporarySlot{_call, _i};\n\t\t\t}) | ranges::to<Stack>,\n\t\t\t// operation\n\t\t\tstd::move(builtinCall)\n\t\t}).output;\n\t\tcanContinue = builtin->controlFlowSideEffects.canContinue;\n\t}\n\telse\n\t{\n\t\tyulAssert(std::holds_alternative<Identifier>(_call.functionName));\n\t\tScope::Function const& function = lookupFunction(std::get<Identifier>(_call.functionName).name);\n\t\tcanContinue = m_graph.functionInfo.at(&function).canContinue;\n\t\tStack inputs;\n\t\t// For EOF (m_simulateFunctionsWithJumps == false) we do not have to put return label on stack.\n\t\tif (m_simulateFunctionsWithJumps && canContinue)\n\t\t\tinputs.emplace_back(FunctionCallReturnLabelSlot{_call});\n\t\tfor (auto const& arg: _call.arguments | ranges::views::reverse)\n\t\t\tinputs.emplace_back(std::visit(*this, arg));\n\t\toutput = &m_currentBlock->operations.emplace_back(CFG::Operation{\n\t\t\t// input\n\t\t\tstd::move(inputs),\n\t\t\t// output\n\t\t\tranges::views::iota(0u, function.numReturns) | ranges::views::transform([&](size_t _i) {\n\t\t\t\treturn TemporarySlot{_call, _i};\n\t\t\t}) | ranges::to<Stack>,\n\t\t\t// operation\n\t\t\tCFG::FunctionCall{_call.debugData, function, _call, /* recursive */ false, canContinue}\n\t\t}).output;\n\t}\n\tif (!canContinue)\n\t{\n\t\tm_currentBlock->exit = CFG::BasicBlock::Terminated{};\n\t\tm_currentBlock = &m_graph.makeBlock(debugDataOf(*m_currentBlock));\n\t}\n\treturn *output;\n}\n\nStack ControlFlowGraphBuilder::visitAssignmentRightHandSide(Expression const& _expression, size_t _expectedSlotCount)\n{\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](FunctionCall const& _call) -> Stack {\n\t\t\tStack const& output = visitFunctionCall(_call);\n\t\t\tyulAssert(_expectedSlotCount == output.size(), \"\");\n\t\t\treturn output;\n\t\t},\n\t\t[&](auto const& _identifierOrLiteral) -> Stack {\n\t\t\tyulAssert(_expectedSlotCount == 1, \"\");\n\t\t\treturn {(*this)(_identifierOrLiteral)};\n\t\t}\n\t}, _expression);\n}\n\nScope::Function const& ControlFlowGraphBuilder::lookupFunction(YulName _name) const\n{\n\tScope::Function const* function = nullptr;\n\tyulAssert(m_scope->lookup(_name, util::GenericVisitor{\n\t\t[](Scope::Variable&) { yulAssert(false, \"Expected function name.\"); },\n\t\t[&](Scope::Function& _function) { function = &_function; }\n\t}), \"Function name not found.\");\n\tyulAssert(function, \"\");\n\treturn *function;\n}\n\nScope::Variable const& ControlFlowGraphBuilder::lookupVariable(YulName _name) const\n{\n\tyulAssert(m_scope, \"\");\n\tScope::Variable const* var = nullptr;\n\tif (m_scope->lookup(_name, util::GenericVisitor{\n\t\t[&](Scope::Variable& _var) { var = &_var; },\n\t\t[](Scope::Function&)\n\t\t{\n\t\t\tyulAssert(false, \"Function not removed during desugaring.\");\n\t\t}\n\t}))\n\t{\n\t\tyulAssert(var, \"\");\n\t\treturn *var;\n\t};\n\tyulAssert(false, \"External identifier access unimplemented.\");\n}\n\nvoid ControlFlowGraphBuilder::makeConditionalJump(\n\tlangutil::DebugData::ConstPtr _debugData,\n\tStackSlot _condition,\n\tCFG::BasicBlock& _nonZero,\n\tCFG::BasicBlock& _zero\n)\n{\n\tyulAssert(m_currentBlock, \"\");\n\tm_currentBlock->exit = CFG::BasicBlock::ConditionalJump{\n\t\tstd::move(_debugData),\n\t\tstd::move(_condition),\n\t\t&_nonZero,\n\t\t&_zero\n\t};\n\t_nonZero.entries.emplace_back(m_currentBlock);\n\t_zero.entries.emplace_back(m_currentBlock);\n\tm_currentBlock = nullptr;\n}\n\nvoid ControlFlowGraphBuilder::jump(\n\tlangutil::DebugData::ConstPtr _debugData,\n\tCFG::BasicBlock& _target,\n\tbool backwards\n)\n{\n\tyulAssert(m_currentBlock, \"\");\n\tm_currentBlock->exit = CFG::BasicBlock::Jump{std::move(_debugData), &_target, backwards};\n\t_target.entries.emplace_back(m_currentBlock);\n\tm_currentBlock = &_target;\n}\n"
  },
  {
    "path": "libyul/backends/evm/ControlFlowGraphBuilder.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Transformation of a Yul AST into a control flow graph.\n */\n#pragma once\n\n#include <libyul/backends/evm/ControlFlowGraph.h>\n#include <libyul/ControlFlowSideEffects.h>\n\n#include <unordered_map>\n\nnamespace solidity::yul\n{\n\nclass ControlFlowGraphBuilder\n{\npublic:\n\tControlFlowGraphBuilder(ControlFlowGraphBuilder const&) = delete;\n\tControlFlowGraphBuilder& operator=(ControlFlowGraphBuilder const&) = delete;\n\tstatic std::unique_ptr<CFG> build(AsmAnalysisInfo const& _analysisInfo, Dialect const& _dialect, Block const& _block);\n\n\tStackSlot operator()(Expression const& _expression);\n\tStackSlot operator()(Literal const& _literal);\n\tStackSlot operator()(Identifier const& _identifier);\n\tStackSlot operator()(FunctionCall const&);\n\n\tvoid operator()(VariableDeclaration const& _varDecl);\n\tvoid operator()(Assignment const& _assignment);\n\tvoid operator()(ExpressionStatement const& _statement);\n\n\tvoid operator()(Block const& _block);\n\n\tvoid operator()(If const& _if);\n\tvoid operator()(Switch const& _switch);\n\tvoid operator()(ForLoop const&);\n\tvoid operator()(Break const&);\n\tvoid operator()(Continue const&);\n\tvoid operator()(Leave const&);\n\tvoid operator()(FunctionDefinition const&);\n\nprivate:\n\tControlFlowGraphBuilder(\n\t\tCFG& _graph,\n\t\tAsmAnalysisInfo const& _analysisInfo,\n\t\tstd::unordered_map<FunctionDefinition const*, ControlFlowSideEffects> const& _functionSideEffects,\n\t\tDialect const& _dialect\n\t);\n\tvoid registerFunction(FunctionDefinition const& _function);\n\tStack const& visitFunctionCall(FunctionCall const&);\n\tStack visitAssignmentRightHandSide(Expression const& _expression, size_t _expectedSlotCount);\n\n\tScope::Function const& lookupFunction(YulName _name) const;\n\tScope::Variable const& lookupVariable(YulName _name) const;\n\t/// Resets m_currentBlock to enforce a subsequent explicit reassignment.\n\tvoid makeConditionalJump(\n\t\tlangutil::DebugData::ConstPtr _debugData,\n\t\tStackSlot _condition,\n\t\tCFG::BasicBlock& _nonZero,\n\t\tCFG::BasicBlock& _zero\n\t);\n\tvoid jump(\n\t\tlangutil::DebugData::ConstPtr _debugData,\n\t\tCFG::BasicBlock& _target,\n\t\tbool _backwards = false\n\t);\n\tCFG& m_graph;\n\tAsmAnalysisInfo const& m_info;\n\tstd::unordered_map<FunctionDefinition const*, ControlFlowSideEffects> const& m_functionSideEffects;\n\tDialect const& m_dialect;\n\tCFG::BasicBlock* m_currentBlock = nullptr;\n\tScope* m_scope = nullptr;\n\tstruct ForLoopInfo\n\t{\n\t\tstd::reference_wrapper<CFG::BasicBlock> afterLoop;\n\t\tstd::reference_wrapper<CFG::BasicBlock> post;\n\t};\n\tstd::optional<ForLoopInfo> m_forLoopInfo;\n\tstd::optional<CFG::FunctionInfo*> m_currentFunction;\n\t/// True if control flow graph simulates functions with jumps. False otherwise. True for legacy bytecode\n\tbool m_simulateFunctionsWithJumps = true;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/EVMBuiltins.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/EVMBuiltins.h>\n\n#include <libyul/AST.h>\n#include <libyul/Object.h>\n#include <libyul/Utilities.h>\n\n#include <libevmasm/AssemblyItem.h>\n\n#include <libsolutil/StringUtils.h>\n\n#include <range/v3/algorithm/all_of.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nnamespace\n{\n\nBuiltinFunctionForEVM createFunction(\n\tstd::string const& _name,\n\tsize_t _params,\n\tsize_t _returns,\n\tSideEffects _sideEffects,\n\tControlFlowSideEffects _controlFlowSideEffects,\n\tstd::vector<std::optional<LiteralKind>> _literalArguments,\n\tstd::function<void(FunctionCall const&, AbstractAssembly&, BuiltinContext&)> _generateCode\n)\n{\n\tyulAssert(_literalArguments.size() == _params || _literalArguments.empty(), \"\");\n\n\tBuiltinFunctionForEVM f;\n\tf.name = _name;\n\tf.numParameters = _params;\n\tf.numReturns = _returns;\n\tf.sideEffects = _sideEffects;\n\tf.controlFlowSideEffects = _controlFlowSideEffects;\n\tf.literalArguments = std::move(_literalArguments);\n\tf.isMSize = false;\n\tf.instruction = {};\n\tf.generateCode = std::move(_generateCode);\n\treturn f;\n}\n\nBuiltinFunctionForEVM instructionBuiltin(evmasm::Instruction const& _instruction, langutil::EVMVersion const& _evmVersion)\n{\n\tevmasm::InstructionInfo const info = evmasm::instructionInfo(_instruction, _evmVersion);\n\tBuiltinFunctionForEVM f;\n\tf.name = util::toLower(info.name);\n\tf.numParameters = static_cast<size_t>(info.args);\n\tf.numReturns = static_cast<size_t>(info.ret);\n\tf.sideEffects = EVMBuiltins::sideEffectsOfInstruction(_instruction);\n\tf.controlFlowSideEffects = ControlFlowSideEffects::fromInstruction(_instruction);\n\tf.isMSize = _instruction == evmasm::Instruction::MSIZE;\n\tf.literalArguments.clear();\n\tf.instruction = _instruction;\n\tf.generateCode = [_instruction](\n\t\tFunctionCall const&,\n\t\tAbstractAssembly& _assembly,\n\t\tBuiltinContext&\n\t)\n\t{\n\t\t_assembly.appendInstruction(_instruction);\n\t};\n\treturn f;\n}\n\nBuiltinFunctionForEVM linkersymbolBuiltin()\n{\n\treturn createFunction(\n\t\t\"linkersymbol\",\n\t\t1,\n\t\t1,\n\t\tSideEffects{},\n\t\tControlFlowSideEffects{},\n\t\t{LiteralKind::String},\n\t\t[](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) {\n\t\t\tyulAssert(_call.arguments.size() == 1, \"\");\n\t\t\tExpression const& arg = _call.arguments.front();\n\t\t\t_assembly.appendLinkerSymbol(formatLiteral(std::get<Literal>(arg)));\n\t\t}\n\t);\n}\n\nBuiltinFunctionForEVM memoryguardBuiltin()\n{\n\treturn createFunction(\n\t\t\"memoryguard\",\n\t\t1,\n\t\t1,\n\t\tSideEffects{},\n\t\tControlFlowSideEffects{},\n\t\t{LiteralKind::Number},\n\t\t[](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&) {\n\t\t\tyulAssert(_call.arguments.size() == 1, \"\");\n\t\t\tLiteral const* literal = std::get_if<Literal>(&_call.arguments.front());\n\t\t\tyulAssert(literal, \"\");\n\t\t\t_assembly.appendConstant(literal->value.value());\n\t\t}\n\t);\n}\n\nBuiltinFunctionForEVM datasizeBuiltin()\n{\n\treturn createFunction(\n\t\t\"datasize\",\n\t\t1,\n\t\t1,\n\t\tSideEffects{},\n\t\tControlFlowSideEffects{},\n\t\t{LiteralKind::String},\n\t\t[](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext& _context) {\n\t\t\tyulAssert(_context.currentObject, \"No object available.\");\n\t\t\tyulAssert(_call.arguments.size() == 1, \"\");\n\t\t\tExpression const& arg = _call.arguments.front();\n\t\t\tYulName const dataName (formatLiteral(std::get<Literal>(arg)));\n\t\t\tif (_context.currentObject->name == dataName.str())\n\t\t\t\t_assembly.appendAssemblySize();\n\t\t\telse\n\t\t\t{\n\t\t\t\tstd::vector<AbstractAssembly::SubID> subIdPath =\n\t\t\t\t\t_context.subIDs.count(dataName.str()) == 0 ?\n\t\t\t\t\t\t_context.currentObject->pathToSubObject(dataName.str()) :\n\t\t\t\t\t\tstd::vector{_context.subIDs.at(dataName.str())};\n\t\t\t\tyulAssert(!subIdPath.empty(), \"Could not find assembly object <\" + dataName.str() + \">.\");\n\t\t\t\t_assembly.appendDataSize(subIdPath);\n\t\t\t}\n\t\t}\n\t);\n}\n\nBuiltinFunctionForEVM dataoffsetBuiltin()\n{\n\treturn createFunction(\"dataoffset\", 1, 1, SideEffects{}, ControlFlowSideEffects{}, {LiteralKind::String}, [](\n\t\tFunctionCall const& _call,\n\t\tAbstractAssembly& _assembly,\n\t\tBuiltinContext& _context\n\t) {\n\t\tyulAssert(_context.currentObject, \"No object available.\");\n\t\tyulAssert(_call.arguments.size() == 1, \"\");\n\t\tExpression const& arg = _call.arguments.front();\n\t\tYulName const dataName (formatLiteral(std::get<Literal>(arg)));\n\t\tif (_context.currentObject->name == dataName.str())\n\t\t\t_assembly.appendConstant(0);\n\t\telse\n\t\t{\n\t\t\tstd::vector<AbstractAssembly::SubID> subIdPath =\n\t\t\t\t_context.subIDs.count(dataName.str()) == 0 ?\n\t\t\t\t\t_context.currentObject->pathToSubObject(dataName.str()) :\n\t\t\t\t\tstd::vector{_context.subIDs.at(dataName.str())};\n\t\t\tyulAssert(!subIdPath.empty(), \"Could not find assembly object <\" + dataName.str() + \">.\");\n\t\t\t_assembly.appendDataOffset(subIdPath);\n\t\t}\n\t});\n}\n\nBuiltinFunctionForEVM datacopyBuiltin()\n{\n\treturn createFunction(\n\t\t\"datacopy\",\n\t\t3,\n\t\t0,\n\t\tEVMBuiltins::sideEffectsOfInstruction(evmasm::Instruction::CODECOPY),\n\t\tControlFlowSideEffects::fromInstruction(evmasm::Instruction::CODECOPY),\n\t\t{},\n\t\t[](\n\t\t\tFunctionCall const&,\n\t\t\tAbstractAssembly& _assembly,\n\t\t\tBuiltinContext&\n\t\t) {\n\t\t\t_assembly.appendInstruction(evmasm::Instruction::CODECOPY);\n\t\t}\n\t);\n}\n\nBuiltinFunctionForEVM setimmutableBuiltin()\n{\n\treturn createFunction(\n\t\t\"setimmutable\",\n\t\t3,\n\t\t0,\n\t\tSideEffects{\n\t\t\tfalse,               // movable\n\t\t\tfalse,               // movableApartFromEffects\n\t\t\tfalse,               // canBeRemoved\n\t\t\tfalse,               // canBeRemovedIfNotMSize\n\t\t\ttrue,                // cannotLoop\n\t\t\tSideEffects::None,   // otherState\n\t\t\tSideEffects::None,   // storage\n\t\t\tSideEffects::Write,  // memory\n\t\t\tSideEffects::None    // transientStorage\n\t\t},\n\t\tControlFlowSideEffects{},\n\t\t{std::nullopt, LiteralKind::String, std::nullopt},\n\t\t[](\n\t\t\tFunctionCall const& _call,\n\t\t\tAbstractAssembly& _assembly,\n\t\t\tBuiltinContext&\n\t\t) {\n\t\t\tyulAssert(_call.arguments.size() == 3, \"\");\n\t\t\tauto const identifier = (formatLiteral(std::get<Literal>(_call.arguments[1])));\n\t\t\t_assembly.appendImmutableAssignment(identifier);\n\t\t}\n\t);\n}\n\nBuiltinFunctionForEVM loadimmutableBuiltin()\n{\n\treturn createFunction(\n\t\t\"loadimmutable\",\n\t\t1,\n\t\t1,\n\t\tSideEffects{},\n\t\tControlFlowSideEffects{},\n\t\t{LiteralKind::String},\n\t\t[](\n\t\t\tFunctionCall const& _call,\n\t\t\tAbstractAssembly& _assembly,\n\t\t\tBuiltinContext&\n\t\t) {\n\t\t\tyulAssert(_call.arguments.size() == 1, \"\");\n\t\t\t_assembly.appendImmutable(formatLiteral(std::get<Literal>(_call.arguments.front())));\n\t\t}\n\t);\n}\n\nBuiltinFunctionForEVM auxdataloadnBuiltin()\n{\n\treturn createFunction(\n\t\t\"auxdataloadn\",\n\t\t1,\n\t\t1,\n\t\tEVMBuiltins::sideEffectsOfInstruction(evmasm::Instruction::DATALOADN),\n\t\tControlFlowSideEffects::fromInstruction(evmasm::Instruction::DATALOADN),\n\t\t{LiteralKind::Number},\n\t\t[](\n\t\t\tFunctionCall const& _call,\n\t\t\tAbstractAssembly& _assembly,\n\t\t\tBuiltinContext&\n\t\t) {\n\t\t\tyulAssert(_call.arguments.size() == 1);\n\t\t\tLiteral const* literal = std::get_if<Literal>(&_call.arguments.front());\n\t\t\tyulAssert(literal, \"\");\n\t\t\tyulAssert(literal->value.value() <= std::numeric_limits<uint16_t>::max());\n\t\t\t_assembly.appendAuxDataLoadN(static_cast<uint16_t>(literal->value.value()));\n\t\t}\n\t);\n}\n\nBuiltinFunctionForEVM eofcreateBuiltin()\n{\n\treturn createFunction(\n\t\t\"eofcreate\",\n\t\t5,\n\t\t1,\n\t\tEVMBuiltins::sideEffectsOfInstruction(evmasm::Instruction::EOFCREATE),\n\t\tControlFlowSideEffects::fromInstruction(evmasm::Instruction::EOFCREATE),\n\t\t{LiteralKind::String, std::nullopt, std::nullopt, std::nullopt, std::nullopt},\n\t\t[](\n\t\t\tFunctionCall const& _call,\n\t\t\tAbstractAssembly& _assembly,\n\t\t\tBuiltinContext& context\n\t\t) {\n\t\t\tyulAssert(_call.arguments.size() == 5);\n\t\t\tLiteral const* literal = std::get_if<Literal>(&_call.arguments.front());\n\t\t\tauto const formattedLiteral = formatLiteral(*literal);\n\t\t\tyulAssert(!util::contains(formattedLiteral, '.'));\n\t\t\tauto const* containerID = util::valueOrNullptr(context.subIDs, formattedLiteral);\n\t\t\tyulAssert(containerID != nullptr);\n\t\t\tyulAssert(containerID->value <= std::numeric_limits<AbstractAssembly::ContainerID>::max());\n\t\t\t_assembly.appendEOFCreate(static_cast<AbstractAssembly::ContainerID>(containerID->value));\n\t\t}\n\t);\n}\n\nBuiltinFunctionForEVM returncontractBuiltin()\n{\n\treturn createFunction(\n\t\t\"returncontract\",\n\t\t3,\n\t\t0,\n\t\tEVMBuiltins::sideEffectsOfInstruction(evmasm::Instruction::RETURNCONTRACT),\n\t\tControlFlowSideEffects::fromInstruction(evmasm::Instruction::RETURNCONTRACT),\n\t\t{LiteralKind::String, std::nullopt, std::nullopt},\n\t\t[](\n\t\t\tFunctionCall const& _call,\n\t\t\tAbstractAssembly& _assembly,\n\t\t\tBuiltinContext& context\n\t\t) {\n\t\t\tyulAssert(_call.arguments.size() == 3);\n\t\t\tLiteral const* literal = std::get_if<Literal>(&_call.arguments.front());\n\t\t\tyulAssert(literal);\n\t\t\tauto const formattedLiteral = formatLiteral(*literal);\n\t\t\tyulAssert(!util::contains(formattedLiteral, '.'));\n\t\t\tauto const* containerID = util::valueOrNullptr(context.subIDs, formattedLiteral);\n\t\t\tyulAssert(containerID != nullptr);\n\t\t\tyulAssert(containerID->value <= std::numeric_limits<AbstractAssembly::ContainerID>::max());\n\t\t\t_assembly.appendReturnContract(static_cast<AbstractAssembly::ContainerID>(containerID->value));\n\t\t}\n\t);\n}\n\n}\n\nEVMBuiltins::EVMBuiltins()\n{\n\tfor (auto const& [name, opcode]: evmasm::c_instructions)\n\t{\n\t\tif (\n\t\t\topcode == evmasm::Instruction::SWAPN ||\n\t\t\topcode == evmasm::Instruction::DUPN ||\n\t\t\tevmasm::SemanticInformation::isSwapInstruction(opcode) ||\n\t\t\tevmasm::SemanticInformation::isDupInstruction(opcode)\n\t\t)\n\t\t\tcontinue;\n\n\t\t// difficulty was replaced by prevrandao after london\n\t\tif (opcode == evmasm::Instruction::PREVRANDAO && name == \"DIFFICULTY\")\n\t\t\tm_scopesAndFunctions.emplace_back(instruction, instructionBuiltin(opcode, langutil::EVMVersion::london()));\n\t\telse\n\t\t\tm_scopesAndFunctions.emplace_back(instruction, instructionBuiltin(opcode, langutil::EVMVersion::current()));\n\n\t\t// these are replaced by 'proper' builtin functions\n\t\tif (\n\t\t\topcode == evmasm::Instruction::DATALOADN ||\n\t\t\topcode == evmasm::Instruction::EOFCREATE ||\n\t\t\topcode == evmasm::Instruction::RETURNCONTRACT\n\t\t)\n\t\t\tstd::get<0>(m_scopesAndFunctions.back()) |= replaced;\n\t}\n\n\tm_scopesAndFunctions.emplace_back(objectAccess, linkersymbolBuiltin());\n\tm_scopesAndFunctions.emplace_back(objectAccess, memoryguardBuiltin());\n\n\tm_scopesAndFunctions.emplace_back(objectAccess | requiresNonEOF, datasizeBuiltin());\n\tm_scopesAndFunctions.emplace_back(objectAccess | requiresNonEOF, dataoffsetBuiltin());\n\tm_scopesAndFunctions.emplace_back(objectAccess | requiresNonEOF, datacopyBuiltin());\n\tm_scopesAndFunctions.emplace_back(objectAccess | requiresNonEOF, setimmutableBuiltin());\n\tm_scopesAndFunctions.emplace_back(objectAccess | requiresNonEOF, loadimmutableBuiltin());\n\n\tm_scopesAndFunctions.emplace_back(objectAccess | requiresEOF, auxdataloadnBuiltin());\n\tm_scopesAndFunctions.emplace_back(objectAccess | requiresEOF, eofcreateBuiltin());\n\tm_scopesAndFunctions.emplace_back(objectAccess | requiresEOF, returncontractBuiltin());\n\n\tstatic size_t constexpr verbatimPrefixLength = std::char_traits<char>::length(\"verbatim_\");\n\tfor (auto const& [scope, builtin]: m_scopesAndFunctions)\n\t{\n\t\tyulAssert(\n\t\t\tbuiltin.name.substr(0, verbatimPrefixLength) != \"verbatim_\",\n\t\t\t\"Builtin functions besides verbatim should not start with the verbatim_ prefix.\"\n\t\t);\n\t\tyulAssert(!(scope.requiresEOF() && scope.requiresNonEOF()), \"Mutually exclusive scopes\");\n\t}\n}\n\nBuiltinFunctionForEVM EVMBuiltins::createVerbatimFunction(size_t const _arguments, size_t const _returnVariables)\n{\n\tBuiltinFunctionForEVM builtinFunction = createFunction(\n\t\t\"verbatim_\" + std::to_string(_arguments) + \"i_\" + std::to_string(_returnVariables) + \"o\",\n\t\t1 + _arguments,\n\t\t_returnVariables,\n\t\tSideEffects::worst(),\n\t\tControlFlowSideEffects::worst(), // Worst control flow side effects because verbatim can do anything.\n\t\tstd::vector<std::optional<LiteralKind>>{LiteralKind::String} + std::vector<std::optional<LiteralKind>>(_arguments),\n\t\t[=](\n\t\t\tFunctionCall const& _call,\n\t\t\tAbstractAssembly& _assembly,\n\t\t\tBuiltinContext&\n\t\t) {\n\t\t\tyulAssert(_call.arguments.size() == (1 + _arguments), \"\");\n\t\t\tExpression const& bytecode = _call.arguments.front();\n\n\t\t\t_assembly.appendVerbatim(\n\t\t\t\tutil::asBytes(formatLiteral(std::get<Literal>(bytecode))),\n\t\t\t\t_arguments,\n\t\t\t\t_returnVariables\n\t\t\t);\n\t\t}\n\t);\n\tbuiltinFunction.isMSize = true;\n\treturn builtinFunction;\n}\n\nSideEffects EVMBuiltins::sideEffectsOfInstruction(evmasm::Instruction _instruction)\n{\n\tauto translate = [](evmasm::SemanticInformation::Effect _e) -> SideEffects::Effect\n\t{\n\t\treturn static_cast<SideEffects::Effect>(_e);\n\t};\n\n\treturn SideEffects{\n\t\tevmasm::SemanticInformation::movable(_instruction),\n\t\tevmasm::SemanticInformation::movableApartFromEffects(_instruction),\n\t\tevmasm::SemanticInformation::canBeRemoved(_instruction),\n\t\tevmasm::SemanticInformation::canBeRemovedIfNoMSize(_instruction),\n\t\ttrue, // cannotLoop\n\t\ttranslate(evmasm::SemanticInformation::otherState(_instruction)),\n\t\ttranslate(evmasm::SemanticInformation::storage(_instruction)),\n\t\ttranslate(evmasm::SemanticInformation::memory(_instruction)),\n\t\ttranslate(evmasm::SemanticInformation::transientStorage(_instruction)),\n\t};\n}\n"
  },
  {
    "path": "libyul/backends/evm/EVMBuiltins.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/AbstractAssembly.h>\n\n#include <libyul/Dialect.h>\n#include <libyul/Scope.h>\n\n#include <bitset>\n#include <cstddef>\n#include <map>\n#include <optional>\n#include <tuple>\n#include <vector>\n\nnamespace solidity::yul\n{\n\nclass Object;\n\n/// Context used during code generation.\nstruct BuiltinContext\n{\n\tObject const* currentObject = nullptr;\n\t/// Mapping from named objects to abstract assembly sub IDs.\n\tstd::map<std::string, AbstractAssembly::SubID> subIDs;\n\n\tstd::map<Scope::Function const*, AbstractAssembly::FunctionID> functionIDs;\n};\n\nstruct BuiltinFunctionForEVM: public BuiltinFunction\n{\n\tstd::optional<evmasm::Instruction> instruction;\n\t/// Function to generate code for the given function call and append it to the abstract\n\t/// assembly. Expects all non-literal arguments of the call to be on stack in reverse order\n\t/// (i.e. right-most argument pushed first).\n\t/// Expects the caller to set the source location.\n\tstd::function<void(FunctionCall const&, AbstractAssembly&, BuiltinContext&)> generateCode;\n};\n\n/// Collection of all possible EVM builtin functions.\n/// Each builtin can have one (or multiple) scopes, which define whether, e.g., it requires object access.\n/// Using this class as single source of truth for builtin functions makes sure that these are consistent over\n/// EVM dialects. If the order were to depend on the EVM dialect - which can easily happen using conditionals -,\n/// different dialects' builtin handles become inherently incompatible.\nclass EVMBuiltins\n{\n\tstatic std::size_t constexpr instructionBit = 0;\n\tstatic std::size_t constexpr replacedInstructionBit = 1;\n\tstatic std::size_t constexpr objectAccessBit = 2;\n\tstatic std::size_t constexpr requiresEOFBit = 3;\n\tstatic std::size_t constexpr requiresNonEOFBit = 4;\n\npublic:\n\tstruct Scopes\n\t{\n\t\t/// whether the corresponding evm builtin function is an instruction builtin\n\t\tbool instruction() const { return value.test(instructionBit); }\n\t\t/// whether the corresponding evm builtin has been replaced by another builtin, ie, should be skipped\n\t\tbool replaced() const { return value.test(replacedInstructionBit); }\n\t\t/// if true, the evm builtin function is only valid when object access is given\n\t\tbool requiresObjectAccess() const { return value.test(objectAccessBit); }\n\t\t/// if true, the evm builtin function is only valid if EOF is enabled\n\t\tbool requiresEOF() const { return value.test(requiresEOFBit); }\n\t\t/// if true, the evm builtin function is only valid if EOF is not enabled\n\t\tbool requiresNonEOF() const { return value.test(requiresNonEOFBit); }\n\n\t\tScopes operator|(Scopes const& _other) const\n\t\t{\n\t\t\tScopes result = *this;\n\t\t\tresult |= _other;\n\t\t\treturn result;\n\t\t}\n\n\t\tScopes& operator|=(Scopes const& _other)\n\t\t{\n\t\t\tvalue |= _other.value;\n\t\t\treturn *this;\n\t\t}\n\n\t\tstd::bitset<5> value;\n\t};\n\n\tEVMBuiltins();\n\n\tstd::vector<std::tuple<Scopes, BuiltinFunctionForEVM>> const& functions() const { return m_scopesAndFunctions; }\n\n\t/// Creates a verbatim builtin function. These are not part of the usual builtin functions collection and\n\t/// must be cached in the dialect creating them.\n\tstatic BuiltinFunctionForEVM createVerbatimFunction(size_t _arguments, size_t _returnVariables);\n\tstatic SideEffects sideEffectsOfInstruction(evmasm::Instruction _instruction);\n\nprivate:\n\tstatic Scopes constexpr instruction{1 << instructionBit};\n\tstatic Scopes constexpr replaced{1 << replacedInstructionBit};\n\tstatic Scopes constexpr objectAccess{1 << objectAccessBit};\n\tstatic Scopes constexpr requiresEOF{1 << requiresEOFBit};\n\tstatic Scopes constexpr requiresNonEOF{1 << requiresNonEOFBit};\n\n\tstd::vector<std::tuple<Scopes, BuiltinFunctionForEVM>> m_scopesAndFunctions;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/EVMCodeTransform.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Code generator for translating Yul / inline assembly to EVM.\n */\n\n#include <libyul/backends/evm/EVMCodeTransform.h>\n\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/Visitor.h>\n#include <libsolutil/StackTooDeepString.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <libevmasm/Instruction.h>\n\n#include <range/v3/view/reverse.hpp>\n\n#include <range/v3/algorithm/max.hpp>\n#include <range/v3/algorithm/none_of.hpp>\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/transform.hpp>\n\n#include <utility>\n#include <variant>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nCodeTransform::CodeTransform(\n\tAbstractAssembly& _assembly,\n\tAsmAnalysisInfo& _analysisInfo,\n\tBlock const& _block,\n\tbool _allowStackOpt,\n\tEVMDialect const& _dialect,\n\tBuiltinContext& _builtinContext,\n\tExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen,\n\tUseNamedLabels _useNamedLabelsForFunctions,\n\tstd::shared_ptr<Context> _context,\n\tstd::vector<NameWithDebugData> _delayedReturnVariables,\n\tstd::optional<AbstractAssembly::LabelID> _functionExitLabel\n):\n\tm_assembly(_assembly),\n\tm_info(_analysisInfo),\n\tm_dialect(_dialect),\n\tm_builtinContext(_builtinContext),\n\tm_allowStackOpt(_allowStackOpt),\n\tm_useNamedLabelsForFunctions(_useNamedLabelsForFunctions),\n\tm_identifierAccessCodeGen(std::move(_identifierAccessCodeGen)),\n\tm_context(std::move(_context)),\n\tm_delayedReturnVariables(std::move(_delayedReturnVariables)),\n\tm_functionExitLabel(_functionExitLabel)\n{\n\tif (!m_context)\n\t{\n\t\t// initialize\n\t\tm_context = std::make_shared<Context>();\n\t\tif (m_allowStackOpt)\n\t\t\tm_context->variableReferences = VariableReferenceCounter::run(m_info, _block);\n\t}\n}\n\nvoid CodeTransform::decreaseReference(YulName, Scope::Variable const& _var)\n{\n\tif (!m_allowStackOpt)\n\t\treturn;\n\n\tunsigned& ref = m_context->variableReferences.at(&_var);\n\tyulAssert(ref >= 1, \"\");\n\t--ref;\n\tif (ref == 0)\n\t\tm_variablesScheduledForDeletion.insert(&_var);\n}\n\nbool CodeTransform::unreferenced(Scope::Variable const& _var) const\n{\n\treturn !m_context->variableReferences.count(&_var) || m_context->variableReferences[&_var] == 0;\n}\n\nvoid CodeTransform::freeUnusedVariables(bool _popUnusedSlotsAtStackTop)\n{\n\tif (!m_allowStackOpt)\n\t\treturn;\n\n\tfor (auto const& identifier: m_scope->identifiers)\n\t\tif (Scope::Variable const* var = std::get_if<Scope::Variable>(&identifier.second))\n\t\t\tif (m_variablesScheduledForDeletion.count(var))\n\t\t\t\tdeleteVariable(*var);\n\t// Directly in a function body block, we can also delete the function arguments,\n\t// which live in the virtual function scope.\n\t// However, doing so after the return variables are already allocated, seems to have an adverse\n\t// effect, so we only do it before that.\n\tif (!returnVariablesAndFunctionExitAreSetup() && !m_scope->functionScope && m_scope->superScope && m_scope->superScope->functionScope)\n\t\tfor (auto const& identifier: m_scope->superScope->identifiers)\n\t\t\tif (Scope::Variable const* var = std::get_if<Scope::Variable>(&identifier.second))\n\t\t\t\tif (m_variablesScheduledForDeletion.count(var))\n\t\t\t\t\tdeleteVariable(*var);\n\n\tif (_popUnusedSlotsAtStackTop)\n\t\twhile (m_unusedStackSlots.count(m_assembly.stackHeight() - 1))\n\t\t{\n\t\t\tyulAssert(m_unusedStackSlots.erase(m_assembly.stackHeight() - 1), \"\");\n\t\t\tm_assembly.appendInstruction(evmasm::Instruction::POP);\n\t\t}\n}\n\nvoid CodeTransform::deleteVariable(Scope::Variable const& _var)\n{\n\tyulAssert(m_allowStackOpt, \"\");\n\tyulAssert(m_context->variableStackHeights.count(&_var) > 0, \"\");\n\tm_unusedStackSlots.insert(static_cast<int>(m_context->variableStackHeights[&_var]));\n\tm_context->variableStackHeights.erase(&_var);\n\tm_context->variableReferences.erase(&_var);\n\tm_variablesScheduledForDeletion.erase(&_var);\n}\n\nvoid CodeTransform::operator()(VariableDeclaration const& _varDecl)\n{\n\tyulAssert(m_scope, \"\");\n\n\tsize_t const numVariables = _varDecl.variables.size();\n\tauto heightAtStart = static_cast<size_t>(m_assembly.stackHeight());\n\tif (_varDecl.value)\n\t{\n\t\tstd::visit(*this, *_varDecl.value);\n\t\texpectDeposit(static_cast<int>(numVariables), static_cast<int>(heightAtStart));\n\t\tfreeUnusedVariables(false);\n\t}\n\telse\n\t{\n\t\tm_assembly.setSourceLocation(originLocationOf(_varDecl));\n\t\tsize_t variablesLeft = numVariables;\n\t\twhile (variablesLeft--)\n\t\t\tm_assembly.appendConstant(u256(0));\n\t}\n\n\tm_assembly.setSourceLocation(originLocationOf(_varDecl));\n\tbool atTopOfStack = true;\n\tfor (size_t varIndex = 0; varIndex < numVariables; ++varIndex)\n\t{\n\t\tsize_t varIndexReverse = numVariables - 1 - varIndex;\n\t\tYulName varName = _varDecl.variables[varIndexReverse].name;\n\t\tauto& var = std::get<Scope::Variable>(m_scope->identifiers.at(varName));\n\t\tm_context->variableStackHeights[&var] = heightAtStart + varIndexReverse;\n\t\tif (!m_allowStackOpt)\n\t\t\tcontinue;\n\n\t\tif (unreferenced(var))\n\t\t{\n\t\t\tif (atTopOfStack)\n\t\t\t{\n\t\t\t\tm_context->variableStackHeights.erase(&var);\n\t\t\t\tm_assembly.appendInstruction(evmasm::Instruction::POP);\n\t\t\t}\n\t\t\telse\n\t\t\t\tm_variablesScheduledForDeletion.insert(&var);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbool foundUnusedSlot = false;\n\t\t\tfor (auto it = m_unusedStackSlots.begin(); it != m_unusedStackSlots.end(); ++it)\n\t\t\t{\n\t\t\t\tif (m_assembly.stackHeight() - *it > static_cast<int>(m_dialect.reachableStackDepth() + 1))\n\t\t\t\t\tcontinue;\n\t\t\t\tfoundUnusedSlot = true;\n\t\t\t\tauto slot = static_cast<size_t>(*it);\n\t\t\t\tm_unusedStackSlots.erase(it);\n\t\t\t\tm_context->variableStackHeights[&var] = slot;\n\t\t\t\tif (size_t heightDiff = variableHeightDiff(var, varName, true))\n\t\t\t\t\tm_assembly.appendInstruction(evmasm::swapInstruction(static_cast<unsigned>(heightDiff - 1)));\n\t\t\t\tm_assembly.appendInstruction(evmasm::Instruction::POP);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!foundUnusedSlot)\n\t\t\t\tatTopOfStack = false;\n\t\t}\n\t}\n}\n\nvoid CodeTransform::stackError(StackTooDeepError _error, int _targetStackHeight)\n{\n\tm_assembly.appendInstruction(evmasm::Instruction::INVALID);\n\t// Correct the stack.\n\twhile (m_assembly.stackHeight() > _targetStackHeight)\n\t\tm_assembly.appendInstruction(evmasm::Instruction::POP);\n\twhile (m_assembly.stackHeight() < _targetStackHeight)\n\t\tm_assembly.appendConstant(u256(0));\n\t// Store error.\n\tm_stackErrors.emplace_back(std::move(_error));\n\tm_assembly.markAsInvalid();\n}\n\nvoid CodeTransform::operator()(Assignment const& _assignment)\n{\n\tint height = m_assembly.stackHeight();\n\tstd::visit(*this, *_assignment.value);\n\texpectDeposit(static_cast<int>(_assignment.variableNames.size()), height);\n\n\tm_assembly.setSourceLocation(originLocationOf(_assignment));\n\tgenerateMultiAssignment(_assignment.variableNames);\n}\n\nvoid CodeTransform::operator()(ExpressionStatement const& _statement)\n{\n\tm_assembly.setSourceLocation(originLocationOf(_statement));\n\tstd::visit(*this, _statement.expression);\n}\n\nvoid CodeTransform::operator()(FunctionCall const& _call)\n{\n\tyulAssert(m_scope, \"\");\n\n\tm_assembly.setSourceLocation(originLocationOf(_call));\n\tif (BuiltinFunctionForEVM const* builtin = resolveBuiltinFunctionForEVM(_call.functionName, m_dialect))\n\t{\n\t\tfor (auto&& [i, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse)\n\t\t\tif (!builtin->literalArgument(i))\n\t\t\t\tvisitExpression(arg);\n\t\tm_assembly.setSourceLocation(originLocationOf(_call));\n\t\tbuiltin->generateCode(_call, m_assembly, m_builtinContext);\n\t}\n\telse\n\t{\n\t\tyulAssert(std::holds_alternative<Identifier>(_call.functionName));\n\t\tAbstractAssembly::LabelID returnLabel = m_assembly.newLabelId();\n\t\tm_assembly.appendLabelReference(returnLabel);\n\n\t\tScope::Function* function = nullptr;\n\t\tyulAssert(m_scope->lookup(std::get<Identifier>(_call.functionName).name, GenericVisitor{\n\t\t\t[](Scope::Variable&) { yulAssert(false, \"Expected function name.\"); },\n\t\t\t[&](Scope::Function& _function) { function = &_function; }\n\t\t}), \"Function name not found.\");\n\t\tyulAssert(function, \"\");\n\t\tyulAssert(function->numArguments == _call.arguments.size(), \"\");\n\t\tfor (auto const& arg: _call.arguments | ranges::views::reverse)\n\t\t\tvisitExpression(arg);\n\t\tm_assembly.setSourceLocation(originLocationOf(_call));\n\t\tm_assembly.appendJumpTo(\n\t\t\tfunctionEntryID(*function),\n\t\t\tstatic_cast<int>(function->numReturns) - static_cast<int>(function->numArguments) - 1,\n\t\t\tAbstractAssembly::JumpType::IntoFunction\n\t\t);\n\t\tm_assembly.appendLabel(returnLabel);\n\t}\n}\n\nvoid CodeTransform::operator()(Identifier const& _identifier)\n{\n\tm_assembly.setSourceLocation(originLocationOf(_identifier));\n\t// First search internals, then externals.\n\tyulAssert(m_scope, \"\");\n\tif (m_scope->lookup(_identifier.name, GenericVisitor{\n\t\t[&](Scope::Variable& _var)\n\t\t{\n\t\t\t// TODO: opportunity for optimization: Do not DUP if this is the last reference\n\t\t\t// to the top most element of the stack\n\t\t\tif (size_t heightDiff = variableHeightDiff(_var, _identifier.name, false))\n\t\t\t\tm_assembly.appendInstruction(evmasm::dupInstruction(static_cast<unsigned>(heightDiff)));\n\t\t\telse\n\t\t\t\t// Store something to balance the stack\n\t\t\t\tm_assembly.appendConstant(u256(0));\n\t\t\tdecreaseReference(_identifier.name, _var);\n\t\t},\n\t\t[](Scope::Function&)\n\t\t{\n\t\t\tyulAssert(false, \"Function not removed during desugaring.\");\n\t\t}\n\t}))\n\t{\n\t\treturn;\n\t}\n\tyulAssert(\n\t\tm_identifierAccessCodeGen,\n\t\t\"Identifier not found and no external access available.\"\n\t);\n\tm_identifierAccessCodeGen(_identifier, IdentifierContext::RValue, m_assembly);\n}\n\nvoid CodeTransform::operator()(Literal const& _literal)\n{\n\tm_assembly.setSourceLocation(originLocationOf(_literal));\n\tm_assembly.appendConstant(_literal.value.value());\n}\n\nvoid CodeTransform::operator()(If const& _if)\n{\n\tvisitExpression(*_if.condition);\n\tm_assembly.setSourceLocation(originLocationOf(_if));\n\tm_assembly.appendInstruction(evmasm::Instruction::ISZERO);\n\tAbstractAssembly::LabelID end = m_assembly.newLabelId();\n\tm_assembly.appendJumpToIf(end);\n\t(*this)(_if.body);\n\tm_assembly.setSourceLocation(originLocationOf(_if));\n\tm_assembly.appendLabel(end);\n}\n\nvoid CodeTransform::operator()(Switch const& _switch)\n{\n\tvisitExpression(*_switch.expression);\n\tint expressionHeight = m_assembly.stackHeight();\n\tstd::map<Case const*, AbstractAssembly::LabelID> caseBodies;\n\tAbstractAssembly::LabelID end = m_assembly.newLabelId();\n\tfor (Case const& c: _switch.cases)\n\t{\n\t\tif (c.value)\n\t\t{\n\t\t\t(*this)(*c.value);\n\t\t\tm_assembly.setSourceLocation(originLocationOf(c));\n\t\t\tAbstractAssembly::LabelID bodyLabel = m_assembly.newLabelId();\n\t\t\tcaseBodies[&c] = bodyLabel;\n\t\t\tyulAssert(m_assembly.stackHeight() == expressionHeight + 1, \"\");\n\t\t\tm_assembly.appendInstruction(evmasm::dupInstruction(2));\n\t\t\tm_assembly.appendInstruction(evmasm::Instruction::EQ);\n\t\t\tm_assembly.appendJumpToIf(bodyLabel);\n\t\t}\n\t\telse\n\t\t\t// default case\n\t\t\t(*this)(c.body);\n\t}\n\tm_assembly.setSourceLocation(originLocationOf(_switch));\n\tm_assembly.appendJumpTo(end);\n\n\tsize_t numCases = caseBodies.size();\n\tfor (auto const& c: caseBodies)\n\t{\n\t\tm_assembly.setSourceLocation(originLocationOf(*c.first));\n\t\tm_assembly.appendLabel(c.second);\n\t\t(*this)(c.first->body);\n\t\t// Avoid useless \"jump to next\" for the last case.\n\t\tif (--numCases > 0)\n\t\t{\n\t\t\tm_assembly.setSourceLocation(originLocationOf(*c.first));\n\t\t\tm_assembly.appendJumpTo(end);\n\t\t}\n\t}\n\n\tm_assembly.setSourceLocation(originLocationOf(_switch));\n\tm_assembly.appendLabel(end);\n\tm_assembly.appendInstruction(evmasm::Instruction::POP);\n}\n\nvoid CodeTransform::operator()(FunctionDefinition const& _function)\n{\n\tyulAssert(m_scope, \"\");\n\tyulAssert(m_scope->identifiers.count(_function.name), \"\");\n\tScope::Function& function = std::get<Scope::Function>(m_scope->identifiers.at(_function.name));\n\n\tsize_t height = 1;\n\tyulAssert(m_info.scopes.at(&_function.body), \"\");\n\tScope* virtualFunctionScope = m_info.scopes.at(m_info.virtualBlocks.at(&_function).get()).get();\n\tyulAssert(virtualFunctionScope, \"\");\n\tfor (auto const& v: _function.parameters | ranges::views::reverse)\n\t{\n\t\tauto& var = std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(v.name));\n\t\tm_context->variableStackHeights[&var] = height++;\n\t}\n\n\tm_assembly.setSourceLocation(originLocationOf(_function));\n\tint const stackHeightBefore = m_assembly.stackHeight();\n\n\tm_assembly.appendLabel(functionEntryID(function));\n\n\tm_assembly.setStackHeight(static_cast<int>(height));\n\n\tCodeTransform subTransform(\n\t\tm_assembly,\n\t\tm_info,\n\t\t_function.body,\n\t\tm_allowStackOpt,\n\t\tm_dialect,\n\t\tm_builtinContext,\n\t\tm_identifierAccessCodeGen,\n\t\tm_useNamedLabelsForFunctions,\n\t\tm_context,\n\t\t_function.returnVariables,\n\t\tm_assembly.newLabelId()\n\t);\n\tsubTransform.m_scope = virtualFunctionScope;\n\n\tif (m_allowStackOpt)\n\t\t// Immediately delete entirely unused parameters.\n\t\tfor (auto const& v: _function.parameters | ranges::views::reverse)\n\t\t{\n\t\t\tauto& var = std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(v.name));\n\t\t\tif (util::valueOrDefault(m_context->variableReferences, &var, 0u) == 0)\n\t\t\t\tsubTransform.deleteVariable(var);\n\t\t}\n\n\tif (!m_allowStackOpt)\n\t\tsubTransform.setupReturnVariablesAndFunctionExit();\n\n\tsubTransform.m_assignedNamedLabels = std::move(m_assignedNamedLabels);\n\n\tsubTransform(_function.body);\n\n\tm_assignedNamedLabels = std::move(subTransform.m_assignedNamedLabels);\n\n\tm_assembly.setSourceLocation(originLocationOf(_function));\n\tif (!subTransform.m_stackErrors.empty())\n\t{\n\t\tm_assembly.markAsInvalid();\n\t\tfor (StackTooDeepError& stackError: subTransform.m_stackErrors)\n\t\t{\n\t\t\tif (stackError.functionName.empty())\n\t\t\t\tstackError.functionName = _function.name;\n\t\t\tm_stackErrors.emplace_back(std::move(stackError));\n\t\t}\n\t}\n\n\tif (!subTransform.returnVariablesAndFunctionExitAreSetup())\n\t\tsubTransform.setupReturnVariablesAndFunctionExit();\n\tappendPopUntil(*subTransform.m_functionExitStackHeight);\n\n\tyulAssert(\n\t\tsubTransform.m_functionExitStackHeight &&\n\t\t*subTransform.m_functionExitStackHeight == m_assembly.stackHeight(),\n\t\t\"\"\n\t);\n\n\tm_assembly.appendLabel(*subTransform.m_functionExitLabel);\n\n\t{\n\t\t// The stack layout here is:\n\t\t// <return label>? <arguments...> <return values...>\n\t\t// But we would like it to be:\n\t\t// <return values...> <return label>?\n\t\t// So we have to append some SWAP and POP instructions.\n\n\t\t// This vector holds the desired target positions of all stack slots and is\n\t\t// modified parallel to the actual stack.\n\t\tstd::vector<int> stackLayout(static_cast<size_t>(m_assembly.stackHeight()), -1);\n\t\tstackLayout[0] = static_cast<int>(_function.returnVariables.size()); // Move return label to the top\n\t\tfor (auto&& [n, returnVariable]: ranges::views::enumerate(_function.returnVariables))\n\t\t\tstackLayout.at(m_context->variableStackHeights.at(\n\t\t\t\t&std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(returnVariable.name))\n\t\t\t)) = static_cast<int>(n);\n\n\t\tsize_t const reachableStackDepth = m_dialect.reachableStackDepth();\n\t\tif (stackLayout.size() > reachableStackDepth + 1)\n\t\t{\n\t\t\tsize_t const unreachableSlots = stackLayout.size() - (reachableStackDepth + 1);\n\t\t\tStackTooDeepError error(\n\t\t\t\t_function.name,\n\t\t\t\tYulName{},\n\t\t\t\tstatic_cast<int>(unreachableSlots),\n\t\t\t\t\"The function \" +\n\t\t\t\t_function.name.str() +\n\t\t\t\t\" has \" +\n\t\t\t\tstd::to_string(unreachableSlots) +\n\t\t\t\t\" parameters or return variables too many to fit the stack size.\"\n\t\t\t);\n\t\t\tstackError(std::move(error), m_assembly.stackHeight() - static_cast<int>(_function.parameters.size()));\n\t\t}\n\t\telse\n\t\t{\n\t\t\twhile (!stackLayout.empty() && stackLayout.back() != static_cast<int>(stackLayout.size() - 1))\n\t\t\t\tif (stackLayout.back() < 0)\n\t\t\t\t{\n\t\t\t\t\tm_assembly.appendInstruction(evmasm::Instruction::POP);\n\t\t\t\t\tstackLayout.pop_back();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tm_assembly.appendInstruction(evmasm::swapInstruction(static_cast<unsigned>(stackLayout.size()) - static_cast<unsigned>(stackLayout.back()) - 1u));\n\t\t\t\t\tstd::swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back());\n\t\t\t\t}\n\t\t\tfor (size_t i = 0; i < stackLayout.size(); ++i)\n\t\t\t\tyulAssert(i == static_cast<size_t>(stackLayout[i]), \"Error reshuffling stack.\");\n\t\t}\n\t}\n\tm_assembly.appendJump(\n\t\tstackHeightBefore - static_cast<int>(_function.returnVariables.size()),\n\t\tAbstractAssembly::JumpType::OutOfFunction\n\t);\n\tm_assembly.setStackHeight(stackHeightBefore);\n}\n\nvoid CodeTransform::operator()(ForLoop const& _forLoop)\n{\n\tScope* originalScope = m_scope;\n\t// We start with visiting the block, but not finalizing it.\n\tm_scope = m_info.scopes.at(&_forLoop.pre).get();\n\tint stackStartHeight = m_assembly.stackHeight();\n\n\tvisitStatements(_forLoop.pre.statements);\n\n\tAbstractAssembly::LabelID loopStart = m_assembly.newLabelId();\n\tAbstractAssembly::LabelID postPart = m_assembly.newLabelId();\n\tAbstractAssembly::LabelID loopEnd = m_assembly.newLabelId();\n\n\tm_assembly.setSourceLocation(originLocationOf(_forLoop));\n\tm_assembly.appendLabel(loopStart);\n\n\tvisitExpression(*_forLoop.condition);\n\tm_assembly.setSourceLocation(originLocationOf(_forLoop));\n\tm_assembly.appendInstruction(evmasm::Instruction::ISZERO);\n\tm_assembly.appendJumpToIf(loopEnd);\n\n\tint const stackHeightBody = m_assembly.stackHeight();\n\tm_context->forLoopStack.emplace(Context::ForLoopLabels{ {postPart, stackHeightBody}, {loopEnd, stackHeightBody} });\n\t(*this)(_forLoop.body);\n\n\tm_assembly.setSourceLocation(originLocationOf(_forLoop));\n\tm_assembly.appendLabel(postPart);\n\n\t(*this)(_forLoop.post);\n\n\tm_assembly.setSourceLocation(originLocationOf(_forLoop));\n\tm_assembly.appendJumpTo(loopStart);\n\tm_assembly.appendLabel(loopEnd);\n\n\tfinalizeBlock(_forLoop.pre, stackStartHeight);\n\tm_context->forLoopStack.pop();\n\tm_scope = originalScope;\n}\n\nint CodeTransform::appendPopUntil(int _targetDepth)\n{\n\tint const stackDiffAfter = m_assembly.stackHeight() - _targetDepth;\n\tfor (int i = 0; i < stackDiffAfter; ++i)\n\t\tm_assembly.appendInstruction(evmasm::Instruction::POP);\n\treturn stackDiffAfter;\n}\n\nvoid CodeTransform::operator()(Break const& _break)\n{\n\tyulAssert(!m_context->forLoopStack.empty(), \"Invalid break-statement. Requires surrounding for-loop in code generation.\");\n\tm_assembly.setSourceLocation(originLocationOf(_break));\n\n\tContext::JumpInfo const& jump = m_context->forLoopStack.top().done;\n\tm_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight));\n}\n\nvoid CodeTransform::operator()(Continue const& _continue)\n{\n\tyulAssert(!m_context->forLoopStack.empty(), \"Invalid continue-statement. Requires surrounding for-loop in code generation.\");\n\tm_assembly.setSourceLocation(originLocationOf(_continue));\n\n\tContext::JumpInfo const& jump = m_context->forLoopStack.top().post;\n\tm_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight));\n}\n\nvoid CodeTransform::operator()(Leave const& _leaveStatement)\n{\n\tyulAssert(m_functionExitLabel, \"Invalid leave-statement. Requires surrounding function in code generation.\");\n\tyulAssert(m_functionExitStackHeight, \"\");\n\tm_assembly.setSourceLocation(originLocationOf(_leaveStatement));\n\tm_assembly.appendJumpTo(*m_functionExitLabel, appendPopUntil(*m_functionExitStackHeight));\n}\n\nvoid CodeTransform::operator()(Block const& _block)\n{\n\tScope* originalScope = m_scope;\n\tm_scope = m_info.scopes.at(&_block).get();\n\n\tfor (auto const& statement: _block.statements)\n\t\tif (auto function = std::get_if<FunctionDefinition>(&statement))\n\t\t\tcreateFunctionEntryID(*function);\n\n\tint blockStartStackHeight = m_assembly.stackHeight();\n\tvisitStatements(_block.statements);\n\n\tbool isOutermostFunctionBodyBlock = m_scope && m_scope->superScope && m_scope->superScope->functionScope;\n\tbool performValidation = !m_allowStackOpt || !isOutermostFunctionBodyBlock;\n\tfinalizeBlock(_block, performValidation ? std::make_optional(blockStartStackHeight) : std::nullopt);\n\tm_scope = originalScope;\n}\n\nvoid CodeTransform::createFunctionEntryID(FunctionDefinition const& _function)\n{\n\tScope::Function& scopeFunction = std::get<Scope::Function>(m_scope->identifiers.at(_function.name));\n\tyulAssert(!m_context->functionEntryIDs.count(&scopeFunction), \"\");\n\n\tstd::optional<size_t> astID;\n\tif (_function.debugData)\n\t\tastID = _function.debugData->astID;\n\n\tbool nameAlreadySeen = !m_assignedNamedLabels.insert(_function.name).second;\n\n\tif (m_useNamedLabelsForFunctions == UseNamedLabels::YesAndForceUnique)\n\t\tyulAssert(!nameAlreadySeen);\n\n\tm_context->functionEntryIDs[&scopeFunction] =\n\t\t(\n\t\t\tm_useNamedLabelsForFunctions != UseNamedLabels::Never &&\n\t\t\t!nameAlreadySeen\n\t\t) ?\n\t\tm_assembly.namedLabel(\n\t\t\t_function.name.str(),\n\t\t\t_function.parameters.size(),\n\t\t\t_function.returnVariables.size(),\n\t\t\tastID\n\t\t) :\n\t\tm_assembly.newLabelId();\n}\n\nAbstractAssembly::LabelID CodeTransform::functionEntryID(Scope::Function const& _scopeFunction) const\n{\n\tyulAssert(m_context->functionEntryIDs.count(&_scopeFunction), \"\");\n\treturn m_context->functionEntryIDs.at(&_scopeFunction);\n}\n\nvoid CodeTransform::visitExpression(Expression const& _expression)\n{\n\tint height = m_assembly.stackHeight();\n\tstd::visit(*this, _expression);\n\texpectDeposit(1, height);\n}\n\nvoid CodeTransform::setupReturnVariablesAndFunctionExit()\n{\n\tyulAssert(isInsideFunction(), \"\");\n\tyulAssert(!returnVariablesAndFunctionExitAreSetup(), \"\");\n\tyulAssert(m_scope, \"\");\n\n\tScopeGuard scopeGuard([oldScope = m_scope, this] { m_scope = oldScope; });\n\tif (!m_scope->functionScope)\n\t{\n\t\tyulAssert(m_scope->superScope && m_scope->superScope->functionScope, \"\");\n\t\tm_scope = m_scope->superScope;\n\t}\n\n\t// We could reuse unused slots for return variables, but it turns out this is detrimental in practice.\n\tm_unusedStackSlots.clear();\n\n\tif (m_delayedReturnVariables.empty())\n\t{\n\t\tm_functionExitStackHeight = 1;\n\t\treturn;\n\t}\n\n\t// Allocate slots for return variables as if they were declared as variables in the virtual function scope.\n\tfor (NameWithDebugData const& var: m_delayedReturnVariables)\n\t\t(*this)(VariableDeclaration{var.debugData, {var}, {}});\n\n\tm_functionExitStackHeight = ranges::max(m_delayedReturnVariables | ranges::views::transform([&](NameWithDebugData const& _name) {\n\t\treturn variableStackHeight(_name.name);\n\t})) + 1;\n\tm_delayedReturnVariables.clear();\n}\n\nnamespace\n{\n\nbool statementNeedsReturnVariableSetup(Statement const& _statement, std::vector<NameWithDebugData> const& _returnVariables)\n{\n\tif (std::holds_alternative<FunctionDefinition>(_statement))\n\t\treturn true;\n\tif (\n\t\tstd::holds_alternative<ExpressionStatement>(_statement) ||\n\t\tstd::holds_alternative<Assignment>(_statement)\n\t)\n\t{\n\t\tstd::map<YulName, size_t> references = VariableReferencesCounter::countReferences(_statement);\n\t\tauto isReferenced = [&references](NameWithDebugData const& _returnVariable) {\n\t\t\treturn references.count(_returnVariable.name);\n\t\t};\n\t\tif (ranges::none_of(_returnVariables, isReferenced))\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\n}\n\nvoid CodeTransform::visitStatements(std::vector<Statement> const& _statements)\n{\n\tstd::optional<AbstractAssembly::LabelID> jumpTarget = std::nullopt;\n\n\tfor (auto const& statement: _statements)\n\t{\n\t\tfreeUnusedVariables();\n\t\tif (\n\t\t\tisInsideFunction() &&\n\t\t\t!returnVariablesAndFunctionExitAreSetup() &&\n\t\t\tstatementNeedsReturnVariableSetup(statement, m_delayedReturnVariables)\n\t\t)\n\t\t\tsetupReturnVariablesAndFunctionExit();\n\n\t\tauto const* functionDefinition = std::get_if<FunctionDefinition>(&statement);\n\t\tif (functionDefinition && !jumpTarget)\n\t\t{\n\t\t\tm_assembly.setSourceLocation(originLocationOf(*functionDefinition));\n\t\t\tjumpTarget = m_assembly.newLabelId();\n\t\t\tm_assembly.appendJumpTo(*jumpTarget, 0);\n\t\t}\n\t\telse if (!functionDefinition && jumpTarget)\n\t\t{\n\t\t\tm_assembly.appendLabel(*jumpTarget);\n\t\t\tjumpTarget = std::nullopt;\n\t\t}\n\n\t\tstd::visit(*this, statement);\n\t}\n\t// we may have a leftover jumpTarget\n\tif (jumpTarget)\n\t\tm_assembly.appendLabel(*jumpTarget);\n\n\tfreeUnusedVariables();\n}\n\nvoid CodeTransform::finalizeBlock(Block const& _block, std::optional<int> blockStartStackHeight)\n{\n\tm_assembly.setSourceLocation(originLocationOf(_block));\n\n\tfreeUnusedVariables();\n\n\t// pop variables\n\tyulAssert(m_info.scopes.at(&_block).get() == m_scope, \"\");\n\tfor (auto const& id: m_scope->identifiers)\n\t\tif (std::holds_alternative<Scope::Variable>(id.second))\n\t\t{\n\t\t\tScope::Variable const& var = std::get<Scope::Variable>(id.second);\n\t\t\tif (m_allowStackOpt)\n\t\t\t{\n\t\t\t\tyulAssert(!m_context->variableStackHeights.count(&var), \"\");\n\t\t\t\tyulAssert(!m_context->variableReferences.count(&var), \"\");\n\t\t\t}\n\t\t\telse\n\t\t\t\tm_assembly.appendInstruction(evmasm::Instruction::POP);\n\t\t}\n\n\tif (blockStartStackHeight)\n\t{\n\t\tint deposit = m_assembly.stackHeight() - *blockStartStackHeight;\n\t\tyulAssert(deposit == 0, \"Invalid stack height at end of block: \" + std::to_string(deposit));\n\t}\n}\n\nvoid CodeTransform::generateMultiAssignment(std::vector<Identifier> const& _variableNames)\n{\n\tyulAssert(m_scope, \"\");\n\tfor (auto const& variableName: _variableNames | ranges::views::reverse)\n\t\tgenerateAssignment(variableName);\n}\n\nvoid CodeTransform::generateAssignment(Identifier const& _variableName)\n{\n\tyulAssert(m_scope, \"\");\n\tif (auto var = m_scope->lookup(_variableName.name))\n\t{\n\t\tScope::Variable const& _var = std::get<Scope::Variable>(*var);\n\t\tif (size_t heightDiff = variableHeightDiff(_var, _variableName.name, true))\n\t\t\tm_assembly.appendInstruction(evmasm::swapInstruction(static_cast<unsigned>(heightDiff - 1)));\n\t\tm_assembly.appendInstruction(evmasm::Instruction::POP);\n\t\tdecreaseReference(_variableName.name, _var);\n\t}\n\telse\n\t{\n\t\tyulAssert(\n\t\t\tm_identifierAccessCodeGen,\n\t\t\t\"Identifier not found and no external access available.\"\n\t\t);\n\t\tm_identifierAccessCodeGen(_variableName, IdentifierContext::LValue, m_assembly);\n\t}\n}\n\nsize_t CodeTransform::variableHeightDiff(Scope::Variable const& _var, YulName _varName, bool _forSwap)\n{\n\tyulAssert(m_context->variableStackHeights.count(&_var), \"\");\n\tsize_t heightDiff = static_cast<size_t>(m_assembly.stackHeight()) - m_context->variableStackHeights[&_var];\n\tyulAssert(heightDiff > (_forSwap ? 1 : 0), \"Negative stack difference for variable.\");\n\tsize_t limit = m_dialect.reachableStackDepth() + (_forSwap ? 1 : 0);\n\tif (heightDiff > limit)\n\t{\n\t\tm_stackErrors.emplace_back(\n\t\t\t_varName,\n\t\t\theightDiff - limit,\n\t\t\t\"Variable \" +\n\t\t\t_varName.str() +\n\t\t\t\" is \" +\n\t\t\tstd::to_string(heightDiff - limit) +\n\t\t\t\" slot(s) too deep inside the stack. \" +\n\t\t\tstackTooDeepString\n\t\t);\n\t\tm_assembly.markAsInvalid();\n\t\treturn _forSwap ? 2 : 1;\n\t}\n\treturn heightDiff;\n}\n\nint CodeTransform::variableStackHeight(YulName _name) const\n{\n\tScope::Variable const* var = std::get_if<Scope::Variable>(m_scope->lookup(_name));\n\tyulAssert(var, \"\");\n\treturn static_cast<int>(m_context->variableStackHeights.at(var));\n}\n\nvoid CodeTransform::expectDeposit(int _deposit, int _oldHeight) const\n{\n\tyulAssert(m_assembly.stackHeight() == _oldHeight + _deposit, \"Invalid stack deposit.\");\n}\n"
  },
  {
    "path": "libyul/backends/evm/EVMCodeTransform.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Code generator for translating Yul / inline assembly to EVM.\n */\n\n#pragma once\n\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/backends/evm/VariableReferenceCounter.h>\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/AST.h>\n#include <libyul/Scope.h>\n\n#include <optional>\n#include <stack>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::yul\n{\n\nstruct AsmAnalysisInfo;\n\nstruct CodeTransformContext\n{\n\tstd::map<Scope::Function const*, AbstractAssembly::LabelID> functionEntryIDs;\n\tstd::map<Scope::Variable const*, size_t> variableStackHeights;\n\tstd::map<Scope::Variable const*, unsigned> variableReferences;\n\n\tstruct JumpInfo\n\t{\n\t\tAbstractAssembly::LabelID label;  ///< Jump's LabelID to jump to.\n\t\tint targetStackHeight;            ///< Stack height after the jump.\n\t};\n\n\tstruct ForLoopLabels\n\t{\n\t\tJumpInfo post; ///< Jump info for jumping to post branch.\n\t\tJumpInfo done; ///< Jump info for jumping to done branch.\n\t};\n\n\tstd::stack<ForLoopLabels> forLoopStack;\n};\n\nclass CodeTransform\n{\npublic:\n\t/// Use named labels for functions 1) Yes and check that the names are unique\n\t/// 2) For none of the functions 3) for the first function of each name.\n\tenum class UseNamedLabels { YesAndForceUnique, Never, ForFirstFunctionOfEachName };\n\n\t/// Create the code transformer.\n\t/// @param _identifierAccessCodeGen used to generate code for identifiers external to the inline assembly\n\t/// As a side-effect of its construction, translates the Yul code and appends it to the\n\t/// given assembly.\n\t/// Throws StackTooDeepError if a variable is not accessible or if a function has too\n\t/// many parameters.\n\tCodeTransform(\n\t\tAbstractAssembly& _assembly,\n\t\tAsmAnalysisInfo& _analysisInfo,\n\t\tBlock const& _block,\n\t\tEVMDialect const& _dialect,\n\t\tBuiltinContext& _builtinContext,\n\t\tbool _allowStackOpt = false,\n\t\tExternalIdentifierAccess::CodeGenerator const& _identifierAccessCodeGen = {},\n\t\tUseNamedLabels _useNamedLabelsForFunctions = UseNamedLabels::Never\n\t): CodeTransform(\n\t\t_assembly,\n\t\t_analysisInfo,\n\t\t_block,\n\t\t_allowStackOpt,\n\t\t_dialect,\n\t\t_builtinContext,\n\t\t_identifierAccessCodeGen,\n\t\t_useNamedLabelsForFunctions,\n\t\tnullptr,\n\t\t{},\n\t\tstd::nullopt\n\t)\n\t{\n\t}\n\n\tstd::vector<StackTooDeepError> const& stackErrors() const { return m_stackErrors; }\n\nprotected:\n\tusing Context = CodeTransformContext;\n\n\tCodeTransform(\n\t\tAbstractAssembly& _assembly,\n\t\tAsmAnalysisInfo& _analysisInfo,\n\t\tBlock const& _block,\n\t\tbool _allowStackOpt,\n\t\tEVMDialect const& _dialect,\n\t\tBuiltinContext& _builtinContext,\n\t\tExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen,\n\t\tUseNamedLabels _useNamedLabelsForFunctions,\n\t\tstd::shared_ptr<Context> _context,\n\t\tstd::vector<NameWithDebugData> _delayedReturnVariables,\n\t\tstd::optional<AbstractAssembly::LabelID> _functionExitLabel\n\t);\n\n\tvoid decreaseReference(YulName _name, Scope::Variable const& _var);\n\tbool unreferenced(Scope::Variable const& _var) const;\n\t/// Marks slots of variables that are not used anymore\n\t/// and were defined in the current scope for reuse.\n\t/// Also POPs unused topmost stack slots,\n\t/// unless @a _popUnusedSlotsAtStackTop is set to false.\n\tvoid freeUnusedVariables(bool _popUnusedSlotsAtStackTop = true);\n\t/// Marks the stack slot of @a _var to be reused.\n\tvoid deleteVariable(Scope::Variable const& _var);\n\npublic:\n\tvoid operator()(Literal const& _literal);\n\tvoid operator()(Identifier const& _identifier);\n\tvoid operator()(FunctionCall const&);\n\tvoid operator()(ExpressionStatement const& _statement);\n\tvoid operator()(Assignment const& _assignment);\n\tvoid operator()(VariableDeclaration const& _varDecl);\n\tvoid operator()(If const& _if);\n\tvoid operator()(Switch const& _switch);\n\tvoid operator()(FunctionDefinition const&);\n\tvoid operator()(ForLoop const&);\n\tvoid operator()(Break const&);\n\tvoid operator()(Continue const&);\n\tvoid operator()(Leave const&);\n\tvoid operator()(Block const& _block);\n\nprivate:\n\tAbstractAssembly::LabelID labelFromIdentifier(Identifier const& _identifier);\n\tvoid createFunctionEntryID(FunctionDefinition const& _function);\n\tAbstractAssembly::LabelID functionEntryID(Scope::Function const& _scopeFunction) const;\n\t/// Generates code for an expression that is supposed to return a single value.\n\tvoid visitExpression(Expression const& _expression);\n\n\tvoid visitStatements(std::vector<Statement> const& _statements);\n\n\t/// Pops all variables declared in the block and checks that the stack height is equal\n\t/// to @a _blockStartStackHeight.\n\tvoid finalizeBlock(Block const& _block, std::optional<int> _blockStartStackHeight);\n\n\tvoid generateMultiAssignment(std::vector<Identifier> const& _variableNames);\n\tvoid generateAssignment(Identifier const& _variableName);\n\n\t/// Determines the stack height difference to the given variables. Throws\n\t/// if it is not yet in scope or the height difference is too large. Returns\n\t/// the (positive) stack height difference otherwise.\n\t/// @param _forSwap if true, produces stack error if the difference is invalid for a swap\n\t///                 opcode, otherwise checks for validity for a dup opcode.\n\tsize_t variableHeightDiff(Scope::Variable const& _var, YulName _name, bool _forSwap);\n\n\t/// Determines the stack height of the given variable. Throws if the variable is not in scope.\n\tint variableStackHeight(YulName _name) const;\n\n\tvoid expectDeposit(int _deposit, int _oldHeight) const;\n\n\t/// Stores the stack error in the list of errors, appends an invalid opcode\n\t/// and corrects the stack height to the target stack height.\n\tvoid stackError(StackTooDeepError _error, int _targetStackSize);\n\n\t/// Ensures stack height is down to @p _targetDepth by appending POP instructions to the output assembly.\n\t/// Returns the number of POP statements that have been appended.\n\tint appendPopUntil(int _targetDepth);\n\n\t/// Allocates stack slots for remaining delayed return values and sets the function exit stack height.\n\tvoid setupReturnVariablesAndFunctionExit();\n\tbool returnVariablesAndFunctionExitAreSetup() const\n\t{\n\t\treturn m_functionExitStackHeight.has_value();\n\t}\n\tbool isInsideFunction() const\n\t{\n\t\treturn m_functionExitLabel.has_value();\n\t}\n\n\tAbstractAssembly& m_assembly;\n\tAsmAnalysisInfo& m_info;\n\tScope* m_scope = nullptr;\n\tEVMDialect const& m_dialect;\n\tBuiltinContext& m_builtinContext;\n\tbool const m_allowStackOpt = true;\n\tUseNamedLabels const m_useNamedLabelsForFunctions = UseNamedLabels::Never;\n\tstd::set<YulName> m_assignedNamedLabels;\n\tExternalIdentifierAccess::CodeGenerator m_identifierAccessCodeGen;\n\tstd::shared_ptr<Context> m_context;\n\n\t/// Set of variables whose reference counter has reached zero,\n\t/// and whose stack slot will be marked as unused once we reach\n\t/// statement level in the scope where the variable was defined.\n\tstd::set<Scope::Variable const*> m_variablesScheduledForDeletion;\n\tstd::set<int> m_unusedStackSlots;\n\n\t/// A list of return variables for which no stack slots have been assigned yet.\n\tstd::vector<NameWithDebugData> m_delayedReturnVariables;\n\n\t/// Function exit label. Used as jump target for ``leave``.\n\tstd::optional<AbstractAssembly::LabelID> m_functionExitLabel;\n\t/// The required stack height at the function exit label.\n\t/// This is the minimal stack height covering all return variables. Only set after all\n\t/// return variables were assigned slots.\n\tstd::optional<int> m_functionExitStackHeight;\n\n\tstd::vector<StackTooDeepError> m_stackErrors;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/EVMDialect.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Yul dialects for EVM.\n */\n\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <libevmasm/AssemblyItem.h>\n#include <libevmasm/Instruction.h>\n#include <libevmasm/SemanticInformation.h>\n\n#include <libyul/AST.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Object.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/StringUtils.h>\n\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/map.hpp>\n#include <range/v3/to_container.hpp>\n\n#include <regex>\n#include <utility>\n#include <vector>\n\nusing namespace std::string_literals;\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nnamespace\n{\n\nsize_t constexpr toContinuousVerbatimIndex(size_t _arguments, size_t _returnVariables)\n{\n\treturn _arguments + _returnVariables * EVMDialect::verbatimMaxInputSlots;\n}\n\nstd::tuple<size_t, size_t> constexpr verbatimIndexToArgsAndRets(size_t _index)\n{\n\tsize_t const numRets = _index / EVMDialect::verbatimMaxInputSlots;\n\treturn std::make_tuple(_index - numRets * EVMDialect::verbatimMaxInputSlots, numRets);\n}\n\nbool isLowLevelStackManipulationInstruction(evmasm::Instruction const& _instruction)\n{\n\treturn\n\t\t_instruction == evmasm::Instruction::SWAPN ||\n\t\tevmasm::SemanticInformation::isSwapInstruction(_instruction) ||\n\t\t_instruction == evmasm::Instruction::DUPN ||\n\t\tevmasm::SemanticInformation::isDupInstruction(_instruction) ||\n\t\tisPushInstruction(_instruction);\n}\n\nbool isLowLevelControlFlowInstruction(evmasm::Instruction const& _instruction)\n{\n\tswitch (_instruction)\n\t{\n\tcase evmasm::Instruction::JUMP:\n\tcase evmasm::Instruction::JUMPI:\n\tcase evmasm::Instruction::JUMPDEST:\n\tcase evmasm::Instruction::JUMPF:\n\tcase evmasm::Instruction::RJUMP:\n\tcase evmasm::Instruction::RJUMPI:\n\tcase evmasm::Instruction::RETF:\n\tcase evmasm::Instruction::CALLF:\n\t\treturn true;\n\tdefault:\n\t\treturn false;\n\t}\n}\n\nstd::set<std::string, std::less<>> createReservedIdentifiers(langutil::EVMVersion _evmVersion, std::optional<uint8_t> _eofVersion)\n{\n\t// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name\n\t// basefee for VMs before london.\n\tauto baseFeeException = [&](evmasm::Instruction _instr) -> bool\n\t{\n\t\treturn _instr == evmasm::Instruction::BASEFEE && _evmVersion < langutil::EVMVersion::london();\n\t};\n\n\t// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name\n\t// blobbasefee for VMs before cancun.\n\tauto blobBaseFeeException = [&](evmasm::Instruction _instr) -> bool\n\t{\n\t\treturn _instr == evmasm::Instruction::BLOBBASEFEE && _evmVersion < langutil::EVMVersion::cancun();\n\t};\n\n\t// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name\n\t// mcopy for VMs before london.\n\tauto mcopyException = [&](evmasm::Instruction _instr) -> bool\n\t{\n\t\treturn _instr == evmasm::Instruction::MCOPY && _evmVersion < langutil::EVMVersion::cancun();\n\t};\n\n\t// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name\n\t// prevrandao for VMs before paris.\n\tauto prevRandaoException = [&](std::string const& _instrName) -> bool\n\t{\n\t\t// Using string comparison as the opcode is the same as for \"difficulty\"\n\t\treturn _instrName == \"prevrandao\" && _evmVersion < langutil::EVMVersion::paris();\n\t};\n\n\t// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name\n\t// blobhash for VMs before cancun.\n\tauto blobHashException = [&](evmasm::Instruction _instr) -> bool\n\t{\n\t\treturn _instr == evmasm::Instruction::BLOBHASH && _evmVersion < langutil::EVMVersion::cancun();\n\t};\n\t// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the names\n\t// tstore or tload for VMs before cancun.\n\tauto transientStorageException = [&](evmasm::Instruction _instr) -> bool\n\t{\n\t\treturn\n\t\t\t_evmVersion < langutil::EVMVersion::cancun() &&\n\t\t\t(_instr == evmasm::Instruction::TSTORE || _instr == evmasm::Instruction::TLOAD);\n\t};\n\t// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name\n\t// clz for VMs before osaka.\n\tauto clzException = [&](evmasm::Instruction _instr) -> bool\n\t{\n\t\treturn _instr == evmasm::Instruction::CLZ && !_evmVersion.hasCLZ();\n\t};\n\n\tauto eofIdentifiersException = [&](evmasm::Instruction _instr) -> bool\n\t{\n\t\tsolAssert(!_eofVersion.has_value() || (*_eofVersion == 1 && _evmVersion.supportsEOF()));\n\t\tif (_eofVersion.has_value())\n\t\t\t// For EOF every instruction is reserved identifier.\n\t\t\treturn false;\n\t\treturn langutil::EVMVersion::firstWithEOF().hasOpcode(_instr, 1) &&\n\t\t\t!langutil::EVMVersion::firstWithEOF().hasOpcode(_instr, std::nullopt);\n\t};\n\n\tstd::set<std::string, std::less<>> reserved;\n\tfor (auto const& instr: evmasm::c_instructions)\n\t{\n\t\tstd::string name = toLower(instr.first);\n\t\tif (\n\t\t\t!baseFeeException(instr.second) &&\n\t\t\t!prevRandaoException(name) &&\n\t\t\t!blobHashException(instr.second) &&\n\t\t\t!blobBaseFeeException(instr.second) &&\n\t\t\t!mcopyException(instr.second) &&\n\t\t\t!transientStorageException(instr.second) &&\n\t\t\t!clzException(instr.second) &&\n\t\t\t!eofIdentifiersException(instr.second)\n\t\t)\n\t\t\treserved.emplace(name);\n\t}\n\treserved += std::vector<std::string>{\n\t\t\"linkersymbol\",\n\t\t\"datasize\",\n\t\t\"dataoffset\",\n\t\t\"datacopy\",\n\t\t\"setimmutable\",\n\t\t\"loadimmutable\",\n\t};\n\n\tif (_eofVersion.has_value())\n\t\treserved += std::vector<std::string>{\n\t\t\t\"auxdataloadn\",\n\t\t};\n\n\treturn reserved;\n}\n\nstd::vector<BuiltinFunctionForEVM const*> createDialectBuiltins(\n\tstd::vector<std::tuple<EVMBuiltins::Scopes, BuiltinFunctionForEVM>> const& _allBuiltins,\n\tlangutil::EVMVersion const _evmVersion,\n\tstd::optional<uint8_t> const _eofVersion,\n\tbool const _objectAccess\n)\n{\n\tstd::vector<BuiltinFunctionForEVM const*> builtins;\n\tbuiltins.reserve(_allBuiltins.size());\n\n\tfor (auto const& [scopes, builtin]: _allBuiltins)\n\t{\n\t\tbool builtinShouldBeAdded = true;\n\t\tif (scopes.instruction())\n\t\t{\n\t\t\tif (scopes.replaced())\n\t\t\t\tbuiltinShouldBeAdded = false;\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Exclude prevrandao as builtin for VMs before paris and difficulty for VMs after paris.\n\t\t\t\tauto prevRandaoException = [&](std::string_view const _instrName) -> bool\n\t\t\t\t{\n\t\t\t\t\treturn (_instrName == \"prevrandao\" && _evmVersion < langutil::EVMVersion::paris()) || (_instrName == \"difficulty\" && _evmVersion >= langutil::EVMVersion::paris());\n\t\t\t\t};\n\n\t\t\t\tyulAssert(builtin.instruction);\n\t\t\t\tauto const& _opcode = *builtin.instruction;\n\t\t\t\tbuiltinShouldBeAdded =\n\t\t\t\t\t!isLowLevelControlFlowInstruction(_opcode) &&\n\t\t\t\t\t!isLowLevelStackManipulationInstruction(_opcode) &&\n\t\t\t\t\t_evmVersion.hasOpcode(_opcode, _eofVersion) &&\n\t\t\t\t\t!prevRandaoException(builtin.name);\n\t\t\t}\n\t\t}\n\n\t\tbuiltinShouldBeAdded &= !scopes.requiresObjectAccess() || _objectAccess;\n\t\tbuiltinShouldBeAdded &= !scopes.requiresEOF() || _eofVersion.has_value();\n\t\tbuiltinShouldBeAdded &= !scopes.requiresNonEOF() || !_eofVersion.has_value();\n\n\t\tif (builtinShouldBeAdded)\n\t\t\tbuiltins.emplace_back(&builtin);\n\t\telse\n\t\t\tbuiltins.emplace_back(nullptr);\n\t}\n\n\treturn builtins;\n}\n\nstd::regex const& verbatimPattern()\n{\n\tstd::regex static const pattern{\"([1-9]?[0-9])i_([1-9]?[0-9])o\"};\n\treturn pattern;\n}\n\n}\n\nEVMDialect::EVMDialect(langutil::EVMVersion _evmVersion, std::optional<uint8_t> _eofVersion, bool _objectAccess):\n\tm_objectAccess(_objectAccess),\n\tm_evmVersion(_evmVersion),\n\tm_eofVersion(_eofVersion),\n\tm_functions(createDialectBuiltins(allBuiltins().functions(), _evmVersion, _eofVersion, _objectAccess)),\n\tm_reserved(createReservedIdentifiers(_evmVersion, _eofVersion))\n{\n\tfor (auto const& [index, maybeBuiltin]: m_functions | ranges::views::enumerate)\n\t\tif (maybeBuiltin)\n\t\t\t// ids are offset by the maximum number of verbatim functions\n\t\t\tm_builtinFunctionsByName[maybeBuiltin->name] = BuiltinHandle{index + verbatimIDOffset};\n\n\tm_discardFunction = EVMDialect::findBuiltin(\"pop\");\n\tm_equalityFunction = EVMDialect::findBuiltin(\"eq\");\n\tm_booleanNegationFunction = EVMDialect::findBuiltin(\"iszero\");\n\tm_memoryStoreFunction = EVMDialect::findBuiltin(\"mstore\");\n\tm_memoryLoadFunction = EVMDialect::findBuiltin(\"mload\");\n\tm_storageStoreFunction = EVMDialect::findBuiltin(\"sstore\");\n\tm_storageLoadFunction = EVMDialect::findBuiltin(\"sload\");\n\tm_hashFunction = EVMDialect::findBuiltin(\"keccak256\");\n\n\tm_auxiliaryBuiltinHandles.add = EVMDialect::findBuiltin(\"add\");\n\tm_auxiliaryBuiltinHandles.exp = EVMDialect::findBuiltin(\"exp\");\n\tm_auxiliaryBuiltinHandles.mul = EVMDialect::findBuiltin(\"mul\");\n\tm_auxiliaryBuiltinHandles.not_ = EVMDialect::findBuiltin(\"not\");\n\tm_auxiliaryBuiltinHandles.shl = EVMDialect::findBuiltin(\"shl\");\n\tm_auxiliaryBuiltinHandles.sub = EVMDialect::findBuiltin(\"sub\");\n}\n\nstd::optional<BuiltinHandle> EVMDialect::findBuiltin(std::string_view _name) const\n{\n\tif (m_objectAccess && _name.substr(0, \"verbatim_\"s.size()) == \"verbatim_\")\n\t{\n\t\tstd::smatch match;\n\t\tstd::string name(_name.substr(\"verbatim_\"s.size()));\n\t\tif (regex_match(name, match, verbatimPattern()))\n\t\t\treturn verbatimFunction(stoul(match[1]), stoul(match[2]));\n\t}\n\n\tif (\n\t\tauto it = m_builtinFunctionsByName.find(_name);\n\t\tit != m_builtinFunctionsByName.end()\n\t)\n\t\treturn it->second;\n\n\treturn std::nullopt;\n}\n\nBuiltinFunctionForEVM const& EVMDialect::builtin(BuiltinHandle const& _handle) const\n{\n\tif (isVerbatimHandle(_handle))\n\t{\n\t\tyulAssert(_handle.id < verbatimIDOffset);\n\t\tauto const& verbatimFunctionPtr = m_verbatimFunctions[_handle.id];\n\t\tyulAssert(verbatimFunctionPtr);\n\t\treturn *verbatimFunctionPtr;\n\t}\n\n\tyulAssert(_handle.id - verbatimIDOffset < m_functions.size());\n\tauto const* maybeBuiltin = m_functions[_handle.id - verbatimIDOffset];\n\tyulAssert(maybeBuiltin);\n\treturn *maybeBuiltin;\n}\n\nbool EVMDialect::reservedIdentifier(std::string_view _name) const\n{\n\tif (m_objectAccess)\n\t\tif (_name.substr(0, \"verbatim\"s.size()) == \"verbatim\")\n\t\t\treturn true;\n\treturn m_reserved.contains(_name);\n}\n\nEVMDialect const& EVMDialect::strictAssemblyForEVM(langutil::EVMVersion _evmVersion, std::optional<uint8_t> _eofVersion)\n{\n\tstatic std::map<std::pair<langutil::EVMVersion, std::optional<uint8_t>>, std::unique_ptr<EVMDialect const>> dialects;\n\tstatic YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }};\n\tif (!dialects[{_evmVersion, _eofVersion}])\n\t\tdialects[{_evmVersion, _eofVersion}] = std::make_unique<EVMDialect>(_evmVersion, _eofVersion, false);\n\treturn *dialects[{_evmVersion, _eofVersion}];\n}\n\nEVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _evmVersion, std::optional<uint8_t> _eofVersion)\n{\n\tstatic std::map<std::pair<langutil::EVMVersion, std::optional<uint8_t>>, std::unique_ptr<EVMDialect const>> dialects;\n\tstatic YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }};\n\tif (!dialects[{_evmVersion, _eofVersion}])\n\t\tdialects[{_evmVersion, _eofVersion}] = std::make_unique<EVMDialect>(_evmVersion, _eofVersion, true);\n\treturn *dialects[{_evmVersion, _eofVersion}];\n}\n\nstd::set<std::string_view> EVMDialect::builtinFunctionNames() const\n{\n\treturn ranges::views::keys(m_builtinFunctionsByName) | ranges::to<std::set>;\n}\n\nBuiltinFunctionForEVM EVMDialect::createVerbatimFunctionFromHandle(BuiltinHandle const& _handle)\n{\n\treturn std::apply(EVMBuiltins::createVerbatimFunction, verbatimIndexToArgsAndRets(_handle.id));\n}\n\nBuiltinHandle EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVariables) const\n{\n\tyulAssert(_arguments <= verbatimMaxInputSlots);\n\tyulAssert(_returnVariables <= verbatimMaxOutputSlots);\n\n\tauto const verbatimIndex = toContinuousVerbatimIndex(_arguments, _returnVariables);\n\tyulAssert(verbatimIndex < verbatimIDOffset);\n\n\tif (\n\t\tauto& verbatimFunctionPtr = m_verbatimFunctions[verbatimIndex];\n\t\t!verbatimFunctionPtr\n\t)\n\t\tverbatimFunctionPtr = std::make_unique<BuiltinFunctionForEVM>(EVMBuiltins::createVerbatimFunction(_arguments, _returnVariables));\n\n\treturn {verbatimIndex};\n}\n\nEVMBuiltins const& EVMDialect::allBuiltins()\n{\n\tstatic EVMBuiltins const builtins;\n\treturn builtins;\n}\n"
  },
  {
    "path": "libyul/backends/evm/EVMDialect.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Yul dialects for EVM.\n */\n\n#pragma once\n\n#include <libyul/Dialect.h>\n#include <libyul/Scope.h>\n\n#include <libyul/backends/evm/AbstractAssembly.h>\n#include <libyul/backends/evm/EVMBuiltins.h>\n\n#include <liblangutil/EVMVersion.h>\n\n#include <array>\n#include <optional>\n#include <set>\n#include <unordered_map>\n#include <vector>\n\nnamespace solidity::yul\n{\n\nstruct FunctionCall;\nclass Object;\n\n/**\n * Yul dialect for EVM as a backend.\n * The main difference is that the builtin functions take an AbstractAssembly for the\n * code generation.\n *\n * Builtins are defined so that their handles stay compatible over different dialect flavors - be it with/without\n * object access, with/without EOF, different versions. It may be, of course, that these builtins are no longer defined.\n * The ones that _are_ defined, though, remain under the same handle.\n */\nclass EVMDialect: public Dialect\n{\npublic:\n\t/// Handles to (depending on dialect, potentially existing) builtins, which are not accessible via the\n\t/// `...FunctionHandle` functions of `Dialect` and of which it is statically known, that they are needed in,\n\t/// e.g., certain optimization steps.\n\tstruct AuxiliaryBuiltinHandles\n\t{\n\t\tstd::optional<BuiltinHandle> add;\n\t\tstd::optional<BuiltinHandle> exp;\n\t\tstd::optional<BuiltinHandle> mul;\n\t\tstd::optional<BuiltinHandle> not_;\n\t\tstd::optional<BuiltinHandle> shl;\n\t\tstd::optional<BuiltinHandle> sub;\n\t};\n\t/// Constructor, should only be used internally. Use the factory functions below.\n\tEVMDialect(langutil::EVMVersion _evmVersion, std::optional<uint8_t> _eofVersion, bool _objectAccess);\n\n\tstd::optional<BuiltinHandle> findBuiltin(std::string_view _name) const override;\n\n\tBuiltinFunctionForEVM const& builtin(BuiltinHandle const& _handle) const override;\n\n\tbool reservedIdentifier(std::string_view _name) const override;\n\n\tstd::optional<BuiltinHandle> discardFunctionHandle() const override { return m_discardFunction; }\n\tstd::optional<BuiltinHandle> equalityFunctionHandle() const override { return m_equalityFunction; }\n\tstd::optional<BuiltinHandle> booleanNegationFunctionHandle() const override { return m_booleanNegationFunction; }\n\tstd::optional<BuiltinHandle> memoryStoreFunctionHandle() const override { return m_memoryStoreFunction; }\n\tstd::optional<BuiltinHandle> memoryLoadFunctionHandle() const override { return m_memoryLoadFunction; }\n\tstd::optional<BuiltinHandle> storageStoreFunctionHandle() const override { return m_storageStoreFunction; }\n\tstd::optional<BuiltinHandle> storageLoadFunctionHandle() const override { return m_storageLoadFunction; }\n\tstd::optional<BuiltinHandle> hashFunctionHandle() const override { return m_hashFunction; }\n\tAuxiliaryBuiltinHandles const& auxiliaryBuiltinHandles() const { return m_auxiliaryBuiltinHandles; }\n\n\tstatic EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _evmVersion, std::optional<uint8_t> _eofVersion);\n\t/// Builtins with and without object access are compatible, i.e., builtin handles without object access are not\n\t/// invalidated and still point to the same function.\n\tstatic EVMDialect const& strictAssemblyForEVMObjects(langutil::EVMVersion _evmVersion, std::optional<uint8_t> _eofVersion);\n\n\tlangutil::EVMVersion evmVersion() const { return m_evmVersion; }\n\tstd::optional<uint8_t> eofVersion() const { return m_eofVersion; }\n\tsize_t reachableStackDepth() const { return m_eofVersion.has_value() ? 256 : m_evmVersion.reachableStackDepth(); }\n\n\tbool providesObjectAccess() const { return m_objectAccess; }\n\n\tstatic size_t constexpr verbatimMaxInputSlots = 100;\n\tstatic size_t constexpr verbatimMaxOutputSlots = 100;\n\n\tstd::set<std::string_view> builtinFunctionNames() const;\n\nprotected:\n\tstatic bool constexpr isVerbatimHandle(BuiltinHandle const& _handle) { return _handle.id < verbatimIDOffset; }\n\tstatic BuiltinFunctionForEVM createVerbatimFunctionFromHandle(BuiltinHandle const& _handle);\n\tBuiltinHandle verbatimFunction(size_t _arguments, size_t _returnVariables) const;\n\n\tstatic size_t constexpr verbatimIDOffset = verbatimMaxInputSlots * verbatimMaxOutputSlots;\n\n\tstatic EVMBuiltins const& allBuiltins();\n\n\tbool const m_objectAccess;\n\tlangutil::EVMVersion const m_evmVersion;\n\tstd::optional<uint8_t> m_eofVersion;\n\tstd::unordered_map<std::string_view, BuiltinHandle> m_builtinFunctionsByName;\n\tstd::vector<BuiltinFunctionForEVM const*> m_functions;\n\tstd::array<std::unique_ptr<BuiltinFunctionForEVM>, verbatimIDOffset> mutable m_verbatimFunctions{};\n\tstd::set<std::string, std::less<>> m_reserved;\n\n\tstd::optional<BuiltinHandle> m_discardFunction;\n\tstd::optional<BuiltinHandle> m_equalityFunction;\n\tstd::optional<BuiltinHandle> m_booleanNegationFunction;\n\tstd::optional<BuiltinHandle> m_memoryStoreFunction;\n\tstd::optional<BuiltinHandle> m_memoryLoadFunction;\n\tstd::optional<BuiltinHandle> m_storageStoreFunction;\n\tstd::optional<BuiltinHandle> m_storageLoadFunction;\n\tstd::optional<BuiltinHandle> m_hashFunction;\n\tAuxiliaryBuiltinHandles m_auxiliaryBuiltinHandles;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/EVMMetrics.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n* Module providing metrics for the EVM optimizer.\n*/\n\n#include <libyul/backends/evm/EVMMetrics.h>\n\n#include <libyul/AST.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Utilities.h>\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <libevmasm/Instruction.h>\n#include <libevmasm/GasMeter.h>\n\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nbigint GasMeter::costs(Expression const& _expression) const\n{\n\treturn combineCosts(GasMeterVisitor::costs(_expression, m_dialect, m_isCreation));\n}\n\nbigint GasMeter::instructionCosts(evmasm::Instruction _instruction) const\n{\n\treturn combineCosts(GasMeterVisitor::instructionCosts(_instruction, m_dialect, m_isCreation));\n}\n\nbigint GasMeter::combineCosts(std::pair<bigint, bigint> _costs) const\n{\n\treturn _costs.first * m_runs + _costs.second;\n}\n\n\nstd::pair<bigint, bigint> GasMeterVisitor::costs(\n\tExpression const& _expression,\n\tEVMDialect const& _dialect,\n\tbool _isCreation\n)\n{\n\tGasMeterVisitor gmv(_dialect, _isCreation);\n\tgmv.visit(_expression);\n\treturn {gmv.m_runGas, gmv.m_dataGas};\n}\n\nstd::pair<bigint, bigint> GasMeterVisitor::instructionCosts(\n\tevmasm::Instruction _instruction,\n\tEVMDialect const& _dialect,\n\tbool _isCreation\n)\n{\n\tGasMeterVisitor gmv(_dialect, _isCreation);\n\tgmv.instructionCostsInternal(_instruction);\n\treturn {gmv.m_runGas, gmv.m_dataGas};\n}\n\nvoid GasMeterVisitor::operator()(FunctionCall const& _funCall)\n{\n\tASTWalker::operator()(_funCall);\n\tif (BuiltinFunctionForEVM const* builtin = resolveBuiltinFunctionForEVM(_funCall.functionName, m_dialect))\n\t\tif (builtin->instruction)\n\t\t{\n\t\t\tinstructionCostsInternal(*builtin->instruction);\n\t\t\treturn;\n\t\t}\n\tyulAssert(false, \"Functions not implemented.\");\n}\n\nvoid GasMeterVisitor::operator()(Literal const& _lit)\n{\n\tm_runGas += evmasm::GasMeter::pushGas(_lit.value.value(), m_dialect.evmVersion());\n\n\tm_dataGas += singleByteDataGas();\n\tif (!m_dialect.evmVersion().hasPush0() || _lit.value.value() != u256(0))\n\t\tm_dataGas += evmasm::GasMeter::dataGas(\n\t\t\ttoCompactBigEndian(_lit.value.value(), 1),\n\t\t\tm_isCreation,\n\t\t\tm_dialect.evmVersion()\n\t\t);\n}\n\nvoid GasMeterVisitor::operator()(Identifier const&)\n{\n\tm_runGas += evmasm::GasMeter::runGas(evmasm::Instruction::DUP1, m_dialect.evmVersion());\n\tm_dataGas += singleByteDataGas();\n}\n\nbigint GasMeterVisitor::singleByteDataGas() const\n{\n\tif (m_isCreation)\n\t\treturn evmasm::GasCosts::txDataNonZeroGas(m_dialect.evmVersion());\n\telse\n\t\treturn evmasm::GasCosts::createDataGas;\n}\n\nvoid GasMeterVisitor::instructionCostsInternal(evmasm::Instruction _instruction)\n{\n\tif (_instruction == evmasm::Instruction::EXP)\n\t\tm_runGas += evmasm::GasCosts::expGas + evmasm::GasCosts::expByteGas(m_dialect.evmVersion());\n\telse if (_instruction == evmasm::Instruction::KECCAK256)\n\t\t// Assumes that Keccak-256 is computed on a single word (rounded up).\n\t\tm_runGas += evmasm::GasCosts::keccak256Gas + evmasm::GasCosts::keccak256WordGas;\n\telse\n\t\tm_runGas += evmasm::GasMeter::runGas(_instruction, m_dialect.evmVersion());\n\tm_dataGas += singleByteDataGas();\n}\n"
  },
  {
    "path": "libyul/backends/evm/EVMMetrics.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Module providing metrics for the optimizer.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <liblangutil/EVMVersion.h>\n#include <libsolutil/Numeric.h>\n#include <libevmasm/Instruction.h>\n\nnamespace solidity::yul\n{\n\nclass EVMDialect;\n\n/**\n * Gas meter for expressions only involving literals, identifiers and\n * EVM instructions.\n *\n * Assumes that EXP is not used with exponents larger than a single byte.\n * Is not particularly exact for anything apart from arithmetic.\n *\n * Assumes that Keccak-256 is computed on a single word (rounded up).\n */\nclass GasMeter\n{\npublic:\n\tGasMeter(EVMDialect const& _dialect, bool _isCreation, bigint _runs):\n\t\tm_dialect(_dialect),\n\t\tm_isCreation{_isCreation},\n\t\tm_runs(_isCreation? 1 : _runs)\n\t{}\n\n\t/// @returns the full combined costs of deploying and evaluating the expression.\n\tbigint costs(Expression const& _expression) const;\n\t/// @returns the combined costs of deploying and running the instruction, not including\n\t/// the costs for its arguments.\n\tbigint instructionCosts(evmasm::Instruction _instruction) const;\n\nprivate:\n\tbigint combineCosts(std::pair<bigint, bigint> _costs) const;\n\n\tEVMDialect const& m_dialect;\n\tbool m_isCreation = false;\n\tbigint m_runs;\n};\n\nclass GasMeterVisitor: public ASTWalker\n{\npublic:\n\tstatic std::pair<bigint, bigint> costs(\n\t\tExpression const& _expression,\n\t\tEVMDialect const& _dialect,\n\t\tbool _isCreation\n\t);\n\n\tstatic std::pair<bigint, bigint> instructionCosts(\n\t\tevmasm::Instruction _instruction,\n\t\tEVMDialect const& _dialect,\n\t\tbool _isCreation = false\n\t);\n\npublic:\n\tGasMeterVisitor(EVMDialect const& _dialect, bool _isCreation):\n\t\tm_dialect(_dialect),\n\t\tm_isCreation{_isCreation}\n\t{}\n\n\tvoid operator()(FunctionCall const& _funCall) override;\n\tvoid operator()(Literal const& _literal) override;\n\tvoid operator()(Identifier const& _identifier) override;\n\nprivate:\n\tbigint singleByteDataGas() const;\n\t/// Computes the cost of storing and executing the single instruction (excluding its arguments).\n\t/// For EXP, it assumes that the exponent is at most 255.\n\t/// Does not work particularly exact for anything apart from arithmetic.\n\tvoid instructionCostsInternal(evmasm::Instruction _instruction);\n\n\tEVMDialect const& m_dialect;\n\tbool m_isCreation = false;\n\tbigint m_runGas = 0;\n\tbigint m_dataGas = 0;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/EVMObjectCompiler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Compiler that transforms Yul Objects to EVM bytecode objects.\n */\n\n#include <libyul/backends/evm/EVMObjectCompiler.h>\n\n#include <libyul/backends/evm/ssa/CodeTransform.h>\n#include <libyul/backends/evm/ssa/SSACFGBuilder.h>\n#include <libyul/backends/evm/ssa/ControlFlow.h>\n\n#include <libyul/backends/evm/EVMCodeTransform.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/backends/evm/OptimizedEVMCodeTransform.h>\n\n#include <libyul/optimiser/FunctionCallFinder.h>\n\n#include <libyul/Object.h>\n#include <libyul/Exceptions.h>\n\n#include <boost/algorithm/string.hpp>\n\nusing namespace solidity::yul;\n\nvoid EVMObjectCompiler::compile(\n\tObject const& _object,\n\tAbstractAssembly& _assembly,\n\tbool _optimize,\n\tbool _viaSSACFG\n)\n{\n\tEVMObjectCompiler compiler(_assembly);\n\tcompiler.run(_object, _optimize, _viaSSACFG);\n}\n\nvoid EVMObjectCompiler::run(Object const& _object, bool _optimize, bool _viaSSACFG)\n{\n\tyulAssert(_object.dialect());\n\tauto const* evmDialect = dynamic_cast<EVMDialect const*>(_object.dialect());\n\tyulAssert(evmDialect);\n\n\tBuiltinContext context;\n\tcontext.currentObject = &_object;\n\n\n\tfor (auto const& subNode: _object.subObjects)\n\t\tif (auto* subObject = dynamic_cast<Object*>(subNode.get()))\n\t\t{\n\t\t\tbool isCreation = !boost::ends_with(subObject->name, \"_deployed\");\n\t\t\tauto subAssemblyAndID = m_assembly.createSubAssembly(isCreation, subObject->name);\n\t\t\tcontext.subIDs[subObject->name] = subAssemblyAndID.second;\n\t\t\tsubObject->subId = subAssemblyAndID.second;\n\t\t\tcompile(*subObject, *subAssemblyAndID.first, _optimize, _viaSSACFG);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tData const& data = dynamic_cast<Data const&>(*subNode);\n\t\t\t// Special handling of metadata.\n\t\t\tif (data.name == Object::metadataName())\n\t\t\t\tm_assembly.appendToAuxiliaryData(data.data);\n\t\t\telse\n\t\t\t\tcontext.subIDs[data.name] = m_assembly.appendData(data.data);\n\t\t}\n\n\tyulAssert(_object.analysisInfo, \"No analysis info.\");\n\tyulAssert(_object.hasCode(), \"No code.\");\n\tif (evmDialect->eofVersion().has_value())\n\t{\n\t\tsolUnimplementedAssert(_optimize, \"EOF supported only for optimized compilation via IR.\");\n\t\tyulAssert(evmDialect->evmVersion().supportsEOF());\n\t}\n\tif (_optimize && evmDialect->evmVersion().canOverchargeGasForCall())\n\t{\n\t\tif (_viaSSACFG)\n\t\t{\n\t\t\tstd::unique_ptr<ssa::ControlFlow> controlFlow = ssa::SSACFGBuilder::build(\n\t\t\t\t*_object.analysisInfo,\n\t\t\t\t*_object.dialect(),\n\t\t\t\t_object.code()->root(),\n\t\t\t\tfalse\n\t\t\t);\n\t\t\tssa::ControlFlowLiveness const liveness(*controlFlow);\n\t\t\tssa::CodeTransform::run(\n\t\t\t\tm_assembly,\n\t\t\t\tliveness,\n\t\t\t\tcontext\n\t\t\t);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto stackErrors = OptimizedEVMCodeTransform::run(\n\t\t\t\tm_assembly,\n\t\t\t\t*_object.analysisInfo,\n\t\t\t\t_object.code()->root(),\n\t\t\t\t*evmDialect,\n\t\t\t\tcontext,\n\t\t\t\tOptimizedEVMCodeTransform::UseNamedLabels::ForFirstFunctionOfEachName\n\t\t\t);\n\t\t\tif (!stackErrors.empty())\n\t\t\t{\n\t\t\t\tyulAssert(evmDialect->providesObjectAccess());\n\t\t\t\tauto const memoryGuardHandle = evmDialect->findBuiltin(\"memoryguard\");\n\t\t\t\tyulAssert(memoryGuardHandle, \"Compiling with object access, memoryguard should be available as builtin.\");\n\t\t\t\tstd::vector<FunctionCall const*> memoryGuardCalls = findFunctionCalls(\n\t\t\t\t\t_object.code()->root(),\n\t\t\t\t\t*memoryGuardHandle\n\t\t\t\t);\n\t\t\t\tauto stackError = stackErrors.front();\n\t\t\t\tstd::string msg = stackError.comment() ? *stackError.comment() : \"\";\n\t\t\t\tif (memoryGuardCalls.empty())\n\t\t\t\t\tmsg += \"\\nNo memoryguard was present. \"\n\t\t\t\t\t\t\"Consider using memory-safe assembly only and annotating it via \"\n\t\t\t\t\t\t\"'assembly (\\\"memory-safe\\\") { ... }'.\";\n\t\t\t\telse\n\t\t\t\t\tmsg += \"\\nmemoryguard was present.\";\n\t\t\t\tstackError << util::errinfo_comment(msg);\n\t\t\t\tBOOST_THROW_EXCEPTION(stackError);\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\t// We do not catch and re-throw the stack too deep exception here because it is a YulException,\n\t\t// which should be native to this part of the code.\n\t\tCodeTransform transform{\n\t\t\tm_assembly,\n\t\t\t*_object.analysisInfo,\n\t\t\t_object.code()->root(),\n\t\t\t*evmDialect,\n\t\t\tcontext,\n\t\t\t_optimize,\n\t\t\t{},\n\t\t\tCodeTransform::UseNamedLabels::ForFirstFunctionOfEachName\n\t\t};\n\t\ttransform(_object.code()->root());\n\t\tif (!transform.stackErrors().empty())\n\t\t\tBOOST_THROW_EXCEPTION(transform.stackErrors().front());\n\t}\n}\n"
  },
  {
    "path": "libyul/backends/evm/EVMObjectCompiler.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Compiler that transforms Yul Objects to EVM bytecode objects.\n */\n\n#pragma once\n\n#include <optional>\n#include <cstdint>\n\nnamespace solidity::yul\n{\nclass Object;\nclass AbstractAssembly;\nclass EVMDialect;\n\nclass EVMObjectCompiler\n{\npublic:\n\tstatic void compile(\n\t\tObject const& _object,\n\t\tAbstractAssembly& _assembly,\n\t\tbool _optimize,\n\t\tbool _viaSSACFG = false\n\t);\nprivate:\n\tEVMObjectCompiler(AbstractAssembly& _assembly): m_assembly(_assembly) {}\n\n\tvoid run(Object const& _object, bool _optimize, bool _viaSSACFG);\n\n\tAbstractAssembly& m_assembly;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/EthAssemblyAdapter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Adaptor between AbstractAssembly and libevmasm.\n */\n\n#include <libyul/backends/evm/EthAssemblyAdapter.h>\n\n#include <libyul/backends/evm/AbstractAssembly.h>\n#include <libyul/Exceptions.h>\n\n#include <libevmasm/Assembly.h>\n#include <libevmasm/AssemblyItem.h>\n#include <libevmasm/Instruction.h>\n\n#include <liblangutil/SourceLocation.h>\n\n#include <memory>\n#include <functional>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\n\nEthAssemblyAdapter::EthAssemblyAdapter(evmasm::Assembly& _assembly):\n\tm_assembly(_assembly)\n{\n}\n\nvoid EthAssemblyAdapter::setSourceLocation(SourceLocation const& _location)\n{\n\tm_assembly.setSourceLocation(_location);\n}\n\nint EthAssemblyAdapter::stackHeight() const\n{\n\treturn m_assembly.deposit();\n}\n\nvoid EthAssemblyAdapter::setStackHeight(int height)\n{\n\tm_assembly.setDeposit(height);\n}\n\nvoid EthAssemblyAdapter::appendInstruction(evmasm::Instruction _instruction)\n{\n\tm_assembly.append(_instruction);\n}\n\nvoid EthAssemblyAdapter::appendConstant(u256 const& _constant)\n{\n\tm_assembly.append(_constant);\n}\n\nvoid EthAssemblyAdapter::appendLabel(LabelID _labelId)\n{\n\tm_assembly.append(evmasm::AssemblyItem(evmasm::Tag, _labelId));\n}\n\nvoid EthAssemblyAdapter::appendLabelReference(LabelID _labelId)\n{\n\tm_assembly.append(evmasm::AssemblyItem(evmasm::PushTag, _labelId));\n}\n\nsize_t EthAssemblyAdapter::newLabelId()\n{\n\treturn assemblyTagToIdentifier(m_assembly.newTag());\n}\n\nsize_t EthAssemblyAdapter::namedLabel(std::string const& _name, size_t _params, size_t _returns, std::optional<size_t> _sourceID)\n{\n\treturn assemblyTagToIdentifier(m_assembly.namedTag(_name, _params, _returns, _sourceID));\n}\n\nvoid EthAssemblyAdapter::appendLinkerSymbol(std::string const& _linkerSymbol)\n{\n\tm_assembly.appendLibraryAddress(_linkerSymbol);\n}\n\nvoid EthAssemblyAdapter::appendVerbatim(bytes _data, size_t _arguments, size_t _returnVariables)\n{\n\tm_assembly.appendVerbatim(std::move(_data), _arguments, _returnVariables);\n}\n\nvoid EthAssemblyAdapter::appendJump(int _stackDiffAfter, JumpType _jumpType)\n{\n\tappendJumpInstruction(evmasm::Instruction::JUMP, _jumpType);\n\tm_assembly.adjustDeposit(_stackDiffAfter);\n}\n\nvoid EthAssemblyAdapter::appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType)\n{\n\tif (m_assembly.supportsRelativeJumps())\n\t{\n\t\tm_assembly.append(evmasm::AssemblyItem::relativeJumpTo(evmasm::AssemblyItem(evmasm::Tag, _labelId)));\n\t\tyulAssert(_jumpType == JumpType::Ordinary);\n\t\tm_assembly.adjustDeposit(_stackDiffAfter);\n\t}\n\telse\n\t{\n\t\tappendLabelReference(_labelId);\n\t\tappendJump(_stackDiffAfter, _jumpType);\n\t}\n}\n\nvoid EthAssemblyAdapter::appendJumpToIf(LabelID _labelId, JumpType _jumpType)\n{\n\tif (m_assembly.supportsRelativeJumps())\n\t{\n\t\tm_assembly.append(evmasm::AssemblyItem::conditionalRelativeJumpTo(evmasm::AssemblyItem(evmasm::Tag, _labelId)));\n\t\tyulAssert(_jumpType == JumpType::Ordinary);\n\t}\n\telse\n\t{\n\t\tappendLabelReference(_labelId);\n\t\tappendJumpInstruction(evmasm::Instruction::JUMPI, _jumpType);\n\t}\n}\n\nvoid EthAssemblyAdapter::appendAssemblySize()\n{\n\tm_assembly.appendProgramSize();\n}\n\nstd::pair<std::shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly(bool _creation, std::string _name)\n{\n\tstd::shared_ptr<evmasm::Assembly> assembly{std::make_shared<evmasm::Assembly>(m_assembly.evmVersion(), _creation, m_assembly.eofVersion(), std::move(_name))};\n\tauto sub = m_assembly.newSub(assembly);\n\treturn {std::make_shared<EthAssemblyAdapter>(*assembly), SubID{sub.data()}};\n}\n\nAbstractAssembly::FunctionID EthAssemblyAdapter::registerFunction(uint8_t _args, uint8_t _rets, bool _nonReturning)\n{\n\treturn m_assembly.createFunction(_args, _rets, _nonReturning);\n}\n\nvoid EthAssemblyAdapter::beginFunction(AbstractAssembly::FunctionID _functionID)\n{\n\tm_assembly.beginFunction(_functionID);\n}\n\nvoid EthAssemblyAdapter::endFunction()\n{\n\tm_assembly.endFunction();\n}\n\nvoid EthAssemblyAdapter::appendFunctionReturn()\n{\n\tm_assembly.appendFunctionReturn();\n}\n\nvoid EthAssemblyAdapter::appendFunctionCall(FunctionID _functionID)\n{\n\tm_assembly.appendFunctionCall(_functionID);\n}\n\nvoid EthAssemblyAdapter::appendEOFCreate(ContainerID _containerID)\n{\n\tm_assembly.appendEOFCreate(_containerID);\n}\n\nvoid EthAssemblyAdapter::appendReturnContract(ContainerID _containerID)\n{\n\tm_assembly.appendReturnContract(_containerID);\n}\n\nvoid EthAssemblyAdapter::appendDataOffset(std::vector<AbstractAssembly::SubID> const& _subPath)\n{\n\tif (auto it = m_dataHashBySubId.find(_subPath[0]); it != m_dataHashBySubId.end())\n\t{\n\t\tyulAssert(_subPath.size() == 1, \"\");\n\t\tm_assembly << evmasm::AssemblyItem(evmasm::PushData, it->second);\n\t\treturn;\n\t}\n\n\tm_assembly.pushSubroutineOffset(m_assembly.encodeSubPath(_subPath));\n}\n\nvoid EthAssemblyAdapter::appendDataSize(std::vector<AbstractAssembly::SubID> const& _subPath)\n{\n\tif (auto it = m_dataHashBySubId.find(_subPath[0]); it != m_dataHashBySubId.end())\n\t{\n\t\tyulAssert(_subPath.size() == 1, \"\");\n\t\tm_assembly << u256(m_assembly.data(h256(it->second)).size());\n\t\treturn;\n\t}\n\n\tm_assembly.pushSubroutineSize(m_assembly.encodeSubPath(_subPath));\n}\n\nAbstractAssembly::SubID EthAssemblyAdapter::appendData(bytes const& _data)\n{\n\tevmasm::AssemblyItem pushData = m_assembly.newData(_data);\n\tSubID const subID{m_nextDataCounter++};\n\tm_dataHashBySubId[subID] = pushData.data();\n\treturn subID;\n}\n\nvoid EthAssemblyAdapter::appendToAuxiliaryData(bytes const& _data)\n{\n\tm_assembly.appendToAuxiliaryData(_data);\n}\n\nvoid EthAssemblyAdapter::appendImmutable(std::string const& _identifier)\n{\n\tm_assembly.appendImmutable(_identifier);\n}\n\nvoid EthAssemblyAdapter::appendImmutableAssignment(std::string const& _identifier)\n{\n\tm_assembly.appendImmutableAssignment(_identifier);\n}\n\nvoid EthAssemblyAdapter::appendAuxDataLoadN(uint16_t _offset)\n{\n\tm_assembly.appendAuxDataLoadN(_offset);\n}\n\nvoid EthAssemblyAdapter::appendSwapN(size_t _depth)\n{\n\tm_assembly.appendSwapN(_depth);\n}\n\nvoid EthAssemblyAdapter::appendDupN(size_t _depth)\n{\n\tm_assembly.appendDupN(_depth);\n}\n\n\nvoid EthAssemblyAdapter::markAsInvalid()\n{\n\tm_assembly.markAsInvalid();\n}\n\nlangutil::EVMVersion EthAssemblyAdapter::evmVersion() const\n{\n\treturn m_assembly.evmVersion();\n}\n\nEthAssemblyAdapter::LabelID EthAssemblyAdapter::assemblyTagToIdentifier(evmasm::AssemblyItem const& _tag)\n{\n\tu256 id = _tag.data();\n\tyulAssert(id <= std::numeric_limits<LabelID>::max(), \"Tag id too large.\");\n\treturn LabelID(id);\n}\n\nvoid EthAssemblyAdapter::appendJumpInstruction(evmasm::Instruction _instruction, JumpType _jumpType)\n{\n\tyulAssert(_instruction == evmasm::Instruction::JUMP || _instruction == evmasm::Instruction::JUMPI, \"\");\n\tevmasm::AssemblyItem jump(_instruction);\n\tswitch (_jumpType)\n\t{\n\tcase JumpType::Ordinary:\n\t\tyulAssert(jump.getJumpType() == evmasm::AssemblyItem::JumpType::Ordinary, \"\");\n\t\tbreak;\n\tcase JumpType::IntoFunction:\n\t\tjump.setJumpType(evmasm::AssemblyItem::JumpType::IntoFunction);\n\t\tbreak;\n\tcase JumpType::OutOfFunction:\n\t\tjump.setJumpType(evmasm::AssemblyItem::JumpType::OutOfFunction);\n\t\tbreak;\n\t}\n\tm_assembly.append(std::move(jump));\n}\n"
  },
  {
    "path": "libyul/backends/evm/EthAssemblyAdapter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Adaptor between AbstractAssembly and libevmasm.\n */\n\n#pragma once\n\n#include <libyul/backends/evm/AbstractAssembly.h>\n#include <libyul/AsmAnalysis.h>\n#include <liblangutil/SourceLocation.h>\n\n#include <functional>\n#include <limits>\n\nnamespace solidity::evmasm\n{\nclass Assembly;\nclass AssemblyItem;\n}\n\nnamespace solidity::yul\n{\nclass EthAssemblyAdapter: public AbstractAssembly\n{\npublic:\n\texplicit EthAssemblyAdapter(evmasm::Assembly& _assembly);\n\tvoid setSourceLocation(langutil::SourceLocation const& _location) override;\n\tint stackHeight() const override;\n\tvoid setStackHeight(int height) override;\n\tvoid appendInstruction(evmasm::Instruction _instruction) override;\n\tvoid appendConstant(u256 const& _constant) override;\n\tvoid appendLabel(LabelID _labelId) override;\n\tvoid appendLabelReference(LabelID _labelId) override;\n\tsize_t newLabelId() override;\n\tsize_t namedLabel(std::string const& _name, size_t _params, size_t _returns, std::optional<size_t> _sourceID) override;\n\tvoid appendLinkerSymbol(std::string const& _linkerSymbol) override;\n\tvoid appendVerbatim(bytes _data, size_t _arguments, size_t _returnVariables) override;\n\tvoid appendJump(int _stackDiffAfter, JumpType _jumpType) override;\n\tvoid appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType) override;\n\tvoid appendJumpToIf(LabelID _labelId, JumpType _jumpType) override;\n\tvoid appendAssemblySize() override;\n\tstd::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(bool _creation, std::string _name = {}) override;\n\tAbstractAssembly::FunctionID registerFunction(uint8_t _args, uint8_t _rets, bool _nonReturning) override;\n\tvoid beginFunction(AbstractAssembly::FunctionID _functionID) override;\n\tvoid endFunction() override;\n\tvoid appendFunctionCall(FunctionID _functionID) override;\n\tvoid appendFunctionReturn() override;\n\tvoid appendEOFCreate(ContainerID _containerID) override;\n\tvoid appendReturnContract(ContainerID _containerID) override;\n\tvoid appendDataOffset(std::vector<SubID> const& _subPath) override;\n\tvoid appendDataSize(std::vector<SubID> const& _subPath) override;\n\tSubID appendData(bytes const& _data) override;\n\n\tvoid appendToAuxiliaryData(bytes const& _data) override;\n\n\tvoid appendImmutable(std::string const& _identifier) override;\n\tvoid appendImmutableAssignment(std::string const& _identifier) override;\n\n\tvoid appendAuxDataLoadN(uint16_t _offset) override;\n\n\tvoid appendSwapN(size_t _depth) override;\n\tvoid appendDupN(size_t _depth) override;\n\n\tvoid markAsInvalid() override;\n\n\tlangutil::EVMVersion evmVersion() const override;\n\n\nprivate:\n\tstatic LabelID assemblyTagToIdentifier(evmasm::AssemblyItem const& _tag);\n\tvoid appendJumpInstruction(evmasm::Instruction _instruction, JumpType _jumpType);\n\n\tevmasm::Assembly& m_assembly;\n\tstd::map<SubID, u256> m_dataHashBySubId;\n\tSubID::ValueType m_nextDataCounter = std::numeric_limits<SubID::ValueType>::max() / 2;\n};\n}\n"
  },
  {
    "path": "libyul/backends/evm/NoOutputAssembly.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Assembly interface that ignores everything. Can be used as a backend for a compilation dry-run.\n */\n\n#include <libyul/backends/evm/NoOutputAssembly.h>\n\n#include <libyul/AST.h>\n#include <libyul/Exceptions.h>\n\n#include <libevmasm/Instruction.h>\n\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/iota.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\n\nnamespace\n{\n\nvoid modifyBuiltinToNoOutput(BuiltinFunctionForEVM& _builtin)\n{\n\t_builtin.generateCode = [_builtin](FunctionCall const& _call, AbstractAssembly& _assembly, BuiltinContext&)\n\t{\n\t\tfor (size_t i: ranges::views::iota(0u, _call.arguments.size()))\n\t\t\tif (!_builtin.literalArgument(i))\n\t\t\t\t_assembly.appendInstruction(evmasm::Instruction::POP);\n\n\t\tfor (size_t i = 0; i < _builtin.numReturns; i++)\n\t\t\t_assembly.appendConstant(u256(0));\n\t};\n}\n\n}\n\nvoid NoOutputAssembly::appendInstruction(evmasm::Instruction _instr)\n{\n\tm_stackHeight += instructionInfo(_instr, m_evmVersion).ret - instructionInfo(_instr, m_evmVersion).args;\n}\n\nvoid NoOutputAssembly::appendConstant(u256 const&)\n{\n\tappendInstruction(evmasm::pushInstruction(1));\n}\n\nvoid NoOutputAssembly::appendLabel(LabelID)\n{\n\tappendInstruction(evmasm::Instruction::JUMPDEST);\n}\n\nvoid NoOutputAssembly::appendLabelReference(LabelID)\n{\n\tappendInstruction(evmasm::pushInstruction(1));\n}\n\nNoOutputAssembly::LabelID NoOutputAssembly::newLabelId()\n{\n\treturn 1;\n}\n\nAbstractAssembly::LabelID NoOutputAssembly::namedLabel(std::string const&, size_t, size_t, std::optional<size_t>)\n{\n\treturn 1;\n}\n\nvoid NoOutputAssembly::appendLinkerSymbol(std::string const&)\n{\n\tyulAssert(false, \"Linker symbols not yet implemented.\");\n}\n\nvoid NoOutputAssembly::appendVerbatim(bytes, size_t _arguments, size_t _returnVariables)\n{\n\tm_stackHeight += static_cast<int>(_returnVariables) - static_cast<int>(_arguments);\n}\n\nvoid NoOutputAssembly::appendJump(int _stackDiffAfter, JumpType)\n{\n\tappendInstruction(evmasm::Instruction::JUMP);\n\tm_stackHeight += _stackDiffAfter;\n}\n\nvoid NoOutputAssembly::appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType)\n{\n\tappendLabelReference(_labelId);\n\tappendJump(_stackDiffAfter, _jumpType);\n}\n\nvoid NoOutputAssembly::appendJumpToIf(LabelID _labelId, JumpType)\n{\n\tappendLabelReference(_labelId);\n\tappendInstruction(evmasm::Instruction::JUMPI);\n}\n\nvoid NoOutputAssembly::appendAssemblySize()\n{\n\tappendInstruction(evmasm::Instruction::PUSH1);\n}\n\nvoid NoOutputAssembly::appendDupN(size_t)\n{\n\tm_stackHeight++;\n}\n\nstd::pair<std::shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> NoOutputAssembly::createSubAssembly(bool, std::string)\n{\n\tyulAssert(false, \"Sub assemblies not implemented.\");\n\treturn {};\n}\n\nAbstractAssembly::FunctionID NoOutputAssembly::registerFunction(uint8_t _args, uint8_t _rets, bool)\n{\n\tyulAssert(m_context.numFunctions <= std::numeric_limits<AbstractAssembly::FunctionID>::max());\n\tAbstractAssembly::FunctionID id = static_cast<AbstractAssembly::FunctionID>(m_context.numFunctions++);\n\tm_context.functionSignatures[id] = {_args, _rets};\n\treturn id;\n}\n\nvoid NoOutputAssembly::beginFunction(FunctionID _functionID)\n{\n\tyulAssert(m_currentFunctionID == 0, \"Attempted to begin a function before ending the last one.\");\n\tyulAssert(m_context.functionSignatures.count(_functionID) == 1, \"Filling unregistered function.\");\n\tyulAssert(m_stackHeight == 0, \"Non-empty stack on beginFunction call.\");\n\tm_currentFunctionID = _functionID;\n}\n\nvoid NoOutputAssembly::endFunction()\n{\n\tyulAssert(m_currentFunctionID != 0, \"End function without begin function.\");\n\tauto const [_, rets] = m_context.functionSignatures.at(m_currentFunctionID);\n\tyulAssert(m_stackHeight == rets, \"Stack height mismatch at function end.\");\n\tm_currentFunctionID = 0;\n}\n\nvoid NoOutputAssembly::appendFunctionCall(FunctionID _functionID)\n{\n\tauto [args, rets] = m_context.functionSignatures.at(_functionID);\n\tm_stackHeight += static_cast<int>(rets) - static_cast<int>(args);\n\tsolAssert(m_stackHeight >= 0);\n}\n\nvoid NoOutputAssembly::appendFunctionReturn()\n{\n\tyulAssert(m_currentFunctionID != 0, \"End function without begin function.\");\n\tauto const [_, rets] = m_context.functionSignatures.at(m_currentFunctionID);\n\tyulAssert(m_stackHeight == rets, \"Stack height mismatch at function end.\");\n}\n\nvoid NoOutputAssembly::appendDataOffset(std::vector<AbstractAssembly::SubID> const&)\n{\n\tappendInstruction(evmasm::Instruction::PUSH1);\n}\n\nvoid NoOutputAssembly::appendDataSize(std::vector<AbstractAssembly::SubID> const&)\n{\n\tappendInstruction(evmasm::Instruction::PUSH1);\n}\n\nAbstractAssembly::SubID NoOutputAssembly::appendData(bytes const&)\n{\n\treturn {1};\n}\n\n\nvoid NoOutputAssembly::appendImmutable(std::string const&)\n{\n\tyulAssert(false, \"loadimmutable not implemented.\");\n}\n\nvoid NoOutputAssembly::appendImmutableAssignment(std::string const&)\n{\n\tyulAssert(false, \"setimmutable not implemented.\");\n}\n\nvoid NoOutputAssembly::appendAuxDataLoadN(uint16_t)\n{\n\tyulAssert(false, \"auxdataloadn not implemented.\");\n}\n\nvoid NoOutputAssembly::appendEOFCreate(ContainerID)\n{\n\tyulAssert(false, \"eofcreate not implemented.\");\n\n}\nvoid NoOutputAssembly::appendReturnContract(ContainerID)\n{\n\tyulAssert(false, \"returncontract not implemented.\");\n}\n\nNoOutputEVMDialect::NoOutputEVMDialect(EVMDialect const& _copyFrom):\n\tEVMDialect(_copyFrom.evmVersion(), _copyFrom.eofVersion(), _copyFrom.providesObjectAccess())\n{\n\t// save the modified functions here - note that this only has to be done once because we modify all of\n\t// them in one go, later reference pointers to this static vector\n\tstatic std::vector<BuiltinFunctionForEVM> noOutputBuiltins = defineNoOutputBuiltins();\n\n\tyulAssert(m_functions.size() == noOutputBuiltins.size(), \"Function count mismatch.\");\n\tfor (auto const& [index, builtinFunction]: m_functions | ranges::views::enumerate)\n\t{\n\t\tif (builtinFunction)\n\t\t\tm_functions[index] = &noOutputBuiltins[index];\n\t\telse\n\t\t\tm_functions[index] = nullptr;\n\t}\n}\n\nBuiltinFunctionForEVM const& NoOutputEVMDialect::builtin(BuiltinHandle const& _handle) const\n{\n\tif (isVerbatimHandle(_handle))\n\t\t// for verbatims the modification is performed lazily as they are stored in a lookup table fashion\n\t\tif (\n\t\t\tauto& builtin = m_verbatimFunctions[_handle.id];\n\t\t\t!builtin\n\t\t)\n\t\t{\n\t\t\tbuiltin = std::make_unique<BuiltinFunctionForEVM>(createVerbatimFunctionFromHandle(_handle));\n\t\t\tmodifyBuiltinToNoOutput(*builtin);\n\t\t}\n\treturn EVMDialect::builtin(_handle);\n}\n\nstd::vector<BuiltinFunctionForEVM> NoOutputEVMDialect::defineNoOutputBuiltins()\n{\n\tstd::vector<BuiltinFunctionForEVM> modifiedBuiltins;\n\tmodifiedBuiltins.reserve(allBuiltins().functions().size());\n\n\tfor (auto const& [_, builtin]: allBuiltins().functions())\n\t{\n\t\tauto noOutputFunction = builtin;\n\t\tmodifyBuiltinToNoOutput(noOutputFunction);\n\t\tmodifiedBuiltins.push_back(std::move(noOutputFunction));\n\t}\n\n\treturn modifiedBuiltins;\n}\n"
  },
  {
    "path": "libyul/backends/evm/NoOutputAssembly.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Assembly interface that ignores everything. Can be used as a backend for a compilation dry-run.\n */\n\n#pragma once\n\n#include <libyul/backends/evm/AbstractAssembly.h>\n\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <libevmasm/LinkerObject.h>\n\n#include <map>\n\nnamespace solidity::langutil\n{\nstruct SourceLocation;\n}\n\nnamespace solidity::yul\n{\n\nclass NoOutputAssembly;\n\nstruct NoOutputAssemblyContext\n{\n\tsize_t numFunctions = 0;\n\tstd::map<uint16_t, std::pair<uint8_t, uint8_t>> functionSignatures;\n};\n\n/**\n * Assembly class that just ignores everything and only performs stack counting.\n * The purpose is to use this assembly for compilation dry-runs.\n */\nclass NoOutputAssembly: public AbstractAssembly\n{\npublic:\n\texplicit NoOutputAssembly(langutil::EVMVersion _evmVersion): m_evmVersion(_evmVersion) { }\n\t~NoOutputAssembly() override = default;\n\n\tvoid setSourceLocation(langutil::SourceLocation const&) override {}\n\tint stackHeight() const override { return m_stackHeight; }\n\tvoid setStackHeight(int height) override { m_stackHeight = height; }\n\tvoid appendInstruction(evmasm::Instruction _instruction) override;\n\tvoid appendConstant(u256 const& _constant) override;\n\tvoid appendLabel(LabelID _labelId) override;\n\tvoid appendLabelReference(LabelID _labelId) override;\n\tLabelID newLabelId() override;\n\tLabelID namedLabel(std::string const& _name, size_t _params, size_t _returns, std::optional<size_t> _sourceID) override;\n\tvoid appendLinkerSymbol(std::string const& _name) override;\n\tvoid appendVerbatim(bytes _data, size_t _arguments, size_t _returnVariables) override;\n\n\tvoid appendJump(int _stackDiffAfter, JumpType _jumpType) override;\n\tvoid appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType) override;\n\tvoid appendJumpToIf(LabelID _labelId, JumpType _jumpType) override;\n\n\tvoid appendAssemblySize() override;\n\tstd::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly(bool _creation, std::string _name = \"\") override;\n\tFunctionID registerFunction(uint8_t _args, uint8_t _rets, bool _nonReturning) override;\n\tvoid beginFunction(FunctionID) override;\n\tvoid endFunction() override;\n\tvoid appendFunctionCall(FunctionID _functionID) override;\n\tvoid appendFunctionReturn() override;\n\tvoid appendDataOffset(std::vector<SubID> const& _subPath) override;\n\tvoid appendDataSize(std::vector<SubID> const& _subPath) override;\n\tSubID appendData(bytes const& _data) override;\n\n\tvoid appendToAuxiliaryData(bytes const&) override {}\n\n\tvoid appendImmutable(std::string const& _identifier) override;\n\tvoid appendImmutableAssignment(std::string const& _identifier) override;\n\n\tvoid appendAuxDataLoadN(uint16_t) override;\n\tvoid appendEOFCreate(ContainerID) override;\n\tvoid appendReturnContract(ContainerID) override;\n\tvoid appendSwapN(size_t) override {}\n\tvoid appendDupN(size_t) override;\n\n\tvoid markAsInvalid() override {}\n\n\tlangutil::EVMVersion evmVersion() const override { return m_evmVersion; }\n\nprivate:\n\tNoOutputAssemblyContext m_context = {};\n\tint m_stackHeight = 0;\n\tFunctionID m_currentFunctionID = 0;\n\tlangutil::EVMVersion m_evmVersion;\n};\n\n\n/**\n * EVM dialect that does not generate any code.\n */\nclass NoOutputEVMDialect: public EVMDialect\n{\npublic:\n\texplicit NoOutputEVMDialect(EVMDialect const& _copyFrom);\n\n\tBuiltinFunctionForEVM const& builtin(BuiltinHandle const& _handle) const override;\n\nprivate:\n\tstatic std::vector<BuiltinFunctionForEVM> defineNoOutputBuiltins();\n};\n\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/OptimizedEVMCodeTransform.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libyul/backends/evm/OptimizedEVMCodeTransform.h>\n\n#include <libyul/backends/evm/ControlFlowGraphBuilder.h>\n#include <libyul/backends/evm/StackHelpers.h>\n#include <libyul/backends/evm/StackLayoutGenerator.h>\n\n#include <libyul/Utilities.h>\n\n#include <libevmasm/Assembly.h>\n#include <libevmasm/Instruction.h>\n\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/view/drop.hpp>\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/filter.hpp>\n#include <range/v3/view/iota.hpp>\n#include <range/v3/view/map.hpp>\n#include <range/v3/view/reverse.hpp>\n#include <range/v3/view/take_last.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nstd::vector<StackTooDeepError> OptimizedEVMCodeTransform::run(\n\tAbstractAssembly& _assembly,\n\tAsmAnalysisInfo& _analysisInfo,\n\tBlock const& _block,\n\tEVMDialect const& _dialect,\n\tBuiltinContext& _builtinContext,\n\tUseNamedLabels _useNamedLabelsForFunctions\n)\n{\n\tstd::unique_ptr<CFG> dfg = ControlFlowGraphBuilder::build(_analysisInfo, _dialect, _block);\n\tStackLayout stackLayout = StackLayoutGenerator::run(*dfg, _dialect);\n\n\tif (_dialect.eofVersion().has_value())\n\t{\n\t\tfor (Scope::Function const* function: dfg->functions)\n\t\t{\n\t\t\tauto const& info = dfg->functionInfo.at(function);\n\t\t\tyulAssert(info.parameters.size() <= std::numeric_limits<uint8_t>::max());\n\t\t\tyulAssert(info.returnVariables.size() <= std::numeric_limits<uint8_t>::max());\n\t\t\tauto functionID = _assembly.registerFunction(\n\t\t\t\tstatic_cast<uint8_t>(info.parameters.size()),\n\t\t\t\tstatic_cast<uint8_t>(info.returnVariables.size()),\n\t\t\t\t!info.canContinue\n\t\t\t);\n\t\t\t_builtinContext.functionIDs[function] = functionID;\n\t\t}\n\t}\n\n\tOptimizedEVMCodeTransform optimizedCodeTransform(\n\t\t_assembly,\n\t\t_builtinContext,\n\t\t_useNamedLabelsForFunctions,\n\t\t*dfg,\n\t\tstackLayout,\n\t\t!_dialect.eofVersion().has_value(),\n\t\t_dialect\n\t);\n\t// Create initial entry layout.\n\toptimizedCodeTransform.createStackLayout(debugDataOf(*dfg->entry), stackLayout.blockInfos.at(dfg->entry).entryLayout);\n\toptimizedCodeTransform(*dfg->entry);\n\tfor (Scope::Function const* function: dfg->functions)\n\t\toptimizedCodeTransform(dfg->functionInfo.at(function));\n\treturn std::move(optimizedCodeTransform.m_stackErrors);\n}\n\nvoid OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call)\n{\n\tbool useReturnLabel = m_simulateFunctionsWithJumps && _call.canContinue;\n\t// Validate stack.\n\t{\n\t\tyulAssert(m_assembly.stackHeight() == static_cast<int>(m_stack.size()), \"\");\n\t\tyulAssert(m_stack.size() >= _call.function.get().numArguments + (useReturnLabel ? 1 : 0), \"\");\n\t\t// Assert that we got the correct arguments on stack for the call.\n\t\tfor (auto&& [arg, slot]: ranges::zip_view(\n\t\t\t_call.functionCall.get().arguments | ranges::views::reverse,\n\t\t\tm_stack | ranges::views::take_last(_call.functionCall.get().arguments.size())\n\t\t))\n\t\t\tvalidateSlot(slot, arg);\n\t\t// Assert that we got the correct return label on stack.\n\t\tif (useReturnLabel)\n\t\t{\n\t\t\tauto const* returnLabelSlot = std::get_if<FunctionCallReturnLabelSlot>(\n\t\t\t\t&m_stack.at(m_stack.size() - _call.functionCall.get().arguments.size() - 1)\n\t\t\t);\n\t\t\tyulAssert(returnLabelSlot && &returnLabelSlot->call.get() == &_call.functionCall.get(), \"\");\n\t\t}\n\t}\n\n\t// Emit code.\n\t{\n\t\tm_assembly.setSourceLocation(originLocationOf(_call));\n\t\tif (!m_simulateFunctionsWithJumps)\n\t\t\tm_assembly.appendFunctionCall(m_builtinContext.functionIDs.at(&_call.function.get()));\n\t\telse\n\t\t\tm_assembly.appendJumpTo(\n\t\t\t\tgetFunctionLabel(_call.function),\n\t\t\t\tstatic_cast<int>(_call.function.get().numReturns) - static_cast<int>(_call.function.get().numArguments) - (_call.canContinue ? 1 : 0),\n\t\t\t\tAbstractAssembly::JumpType::IntoFunction\n\t\t\t);\n\t\tif (useReturnLabel)\n\t\t\tm_assembly.appendLabel(m_returnLabels.at(&_call.functionCall.get()));\n\t}\n\n\t// Update stack.\n\t{\n\t\t// Remove arguments and return label from m_stack.\n\t\tfor (size_t i = 0; i < _call.function.get().numArguments + (useReturnLabel ? 1 : 0); ++i)\n\t\t\tm_stack.pop_back();\n\t\t// Push return values to m_stack.\n\t\tfor (size_t index: ranges::views::iota(0u, _call.function.get().numReturns))\n\t\t\tm_stack.emplace_back(TemporarySlot{_call.functionCall, index});\n\t\tyulAssert(m_assembly.stackHeight() == static_cast<int>(m_stack.size()), \"\");\n\t}\n}\n\nvoid OptimizedEVMCodeTransform::operator()(CFG::BuiltinCall const& _call)\n{\n\t// Validate stack.\n\t{\n\t\tyulAssert(m_assembly.stackHeight() == static_cast<int>(m_stack.size()), \"\");\n\t\tyulAssert(m_stack.size() >= _call.arguments, \"\");\n\t\t// Assert that we got a correct stack for the call.\n\t\tfor (auto&& [arg, slot]: ranges::zip_view(\n\t\t\t_call.functionCall.get().arguments |\n\t\t\tranges::views::enumerate |\n\t\t\tranges::views::filter(util::mapTuple([&](size_t idx, auto&) -> bool {\n\t\t\t\treturn !_call.builtin.get().literalArgument(idx);\n\t\t\t})) |\n\t\t\tranges::views::reverse |\n\t\t\tranges::views::values,\n\t\t\tm_stack | ranges::views::take_last(_call.arguments)\n\t\t))\n\t\t\tvalidateSlot(slot, arg);\n\t}\n\n\t// Emit code.\n\t{\n\t\tm_assembly.setSourceLocation(originLocationOf(_call));\n\t\tstatic_cast<BuiltinFunctionForEVM const&>(_call.builtin.get()).generateCode(\n\t\t\t_call.functionCall,\n\t\t\tm_assembly,\n\t\t\tm_builtinContext\n\t\t);\n\t}\n\n\t// Update stack.\n\t{\n\t\t// Remove arguments from m_stack.\n\t\tfor (size_t i = 0; i < _call.arguments; ++i)\n\t\t\tm_stack.pop_back();\n\t\t// Push return values to m_stack.\n\t\tfor (size_t index: ranges::views::iota(0u, _call.builtin.get().numReturns))\n\t\t\tm_stack.emplace_back(TemporarySlot{_call.functionCall, index});\n\t\tyulAssert(m_assembly.stackHeight() == static_cast<int>(m_stack.size()), \"\");\n\t}\n}\n\nvoid OptimizedEVMCodeTransform::operator()(CFG::Assignment const& _assignment)\n{\n\tyulAssert(m_assembly.stackHeight() == static_cast<int>(m_stack.size()), \"\");\n\n\t// Invalidate occurrences of the assigned variables.\n\tfor (auto& currentSlot: m_stack)\n\t\tif (VariableSlot const* varSlot = std::get_if<VariableSlot>(&currentSlot))\n\t\t\tif (util::contains(_assignment.variables, *varSlot))\n\t\t\t\tcurrentSlot = JunkSlot{};\n\n\t// Assign variables to current stack top.\n\tyulAssert(m_stack.size() >= _assignment.variables.size(), \"\");\n\tfor (auto&& [currentSlot, varSlot]: ranges::zip_view(\n\t\tm_stack | ranges::views::take_last(_assignment.variables.size()),\n\t\t_assignment.variables\n\t))\n\t\tcurrentSlot = varSlot;\n}\n\nOptimizedEVMCodeTransform::OptimizedEVMCodeTransform(\n\tAbstractAssembly& _assembly,\n\tBuiltinContext& _builtinContext,\n\tUseNamedLabels _useNamedLabelsForFunctions,\n\tCFG const& _dfg,\n\tStackLayout const& _stackLayout,\n\tbool _simulateFunctionsWithJumps,\n\tEVMDialect const& _dialect\n):\n\tm_assembly(_assembly),\n\tm_builtinContext(_builtinContext),\n\tm_dfg(_dfg),\n\tm_stackLayout(_stackLayout),\n\tm_dialect(_dialect),\n\tm_functionLabels(!_simulateFunctionsWithJumps ? decltype(m_functionLabels)() : [&](){\n\t\tstd::map<CFG::FunctionInfo const*, AbstractAssembly::LabelID> functionLabels;\n\t\tstd::set<YulName> assignedFunctionNames;\n\t\tfor (Scope::Function const* function: m_dfg.functions)\n\t\t{\n\t\t\tCFG::FunctionInfo const& functionInfo = m_dfg.functionInfo.at(function);\n\t\t\tbool nameAlreadySeen = !assignedFunctionNames.insert(function->name).second;\n\t\t\tif (_useNamedLabelsForFunctions == UseNamedLabels::YesAndForceUnique)\n\t\t\t\tyulAssert(!nameAlreadySeen);\n\t\t\tbool useNamedLabel = _useNamedLabelsForFunctions != UseNamedLabels::Never && !nameAlreadySeen;\n\t\t\tfunctionLabels[&functionInfo] = useNamedLabel ?\n\t\t\t\tm_assembly.namedLabel(\n\t\t\t\t\tfunction->name.str(),\n\t\t\t\t\tfunction->numArguments,\n\t\t\t\t\tfunction->numReturns,\n\t\t\t\t\tfunctionInfo.debugData ? functionInfo.debugData->astID : std::nullopt\n\t\t\t\t) :\n\t\t\t\tm_assembly.newLabelId();\n\t\t}\n\t\treturn functionLabels;\n\t}()),\n\tm_simulateFunctionsWithJumps(_simulateFunctionsWithJumps),\n\tm_reachableStackDepth(_dialect.reachableStackDepth())\n{\n}\n\nvoid OptimizedEVMCodeTransform::assertLayoutCompatibility(Stack const& _currentStack, Stack const& _desiredStack)\n{\n\tyulAssert(_currentStack.size() == _desiredStack.size(), \"\");\n\tfor (auto&& [currentSlot, desiredSlot]: ranges::zip_view(_currentStack, _desiredStack))\n\t\tyulAssert(std::holds_alternative<JunkSlot>(desiredSlot) || currentSlot == desiredSlot, \"\");\n}\n\nAbstractAssembly::LabelID OptimizedEVMCodeTransform::getFunctionLabel(Scope::Function const& _function)\n{\n\tyulAssert(m_simulateFunctionsWithJumps);\n\treturn m_functionLabels.at(&m_dfg.functionInfo.at(&_function));\n}\n\nvoid OptimizedEVMCodeTransform::validateSlot(StackSlot const& _slot, Expression const& _expression)\n{\n\tstd::visit(util::GenericVisitor{\n\t\t[&](yul::Literal const& _literal) {\n\t\t\tauto* literalSlot = std::get_if<LiteralSlot>(&_slot);\n\t\t\tyulAssert(literalSlot && _literal.value.value() == literalSlot->value, \"\");\n\t\t},\n\t\t[&](yul::Identifier const& _identifier) {\n\t\t\tauto* variableSlot = std::get_if<VariableSlot>(&_slot);\n\t\t\tyulAssert(variableSlot && variableSlot->variable.get().name == _identifier.name, \"\");\n\t\t},\n\t\t[&](yul::FunctionCall const& _call) {\n\t\t\tauto* temporarySlot = std::get_if<TemporarySlot>(&_slot);\n\t\t\tyulAssert(temporarySlot && &temporarySlot->call.get() == &_call && temporarySlot->index == 0, \"\");\n\t\t}\n\t}, _expression);\n}\n\nvoid OptimizedEVMCodeTransform::createStackLayout(langutil::DebugData::ConstPtr _debugData, Stack _targetStack)\n{\n\tstatic constexpr auto slotVariableName = [](StackSlot const& _slot) {\n\t\treturn std::visit(util::GenericVisitor{\n\t\t\t[](VariableSlot const& _var) { return _var.variable.get().name; },\n\t\t\t[](auto const&) { return YulName{}; }\n\t\t}, _slot);\n\t};\n\n\tyulAssert(m_assembly.stackHeight() == static_cast<int>(m_stack.size()), \"\");\n\t// ::createStackLayout asserts that it has successfully achieved the target layout.\n\tlangutil::SourceLocation sourceLocation = _debugData ? _debugData->originLocation : langutil::SourceLocation{};\n\tm_assembly.setSourceLocation(sourceLocation);\n\t::createStackLayout(\n\t\tm_stack,\n\t\t_targetStack | ranges::to<Stack>,\n\t\t// Swap callback.\n\t\t[&](unsigned _i)\n\t\t{\n\t\t\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight(), \"\");\n\t\t\tyulAssert(_i > 0 && _i < m_stack.size(), \"\");\n\t\t\tif (_i <= m_reachableStackDepth)\n\t\t\t\tappendSwap(_i);\n\t\t\telse\n\t\t\t{\n\t\t\t\tint deficit = static_cast<int>(_i) - static_cast<int>(m_reachableStackDepth);\n\t\t\t\tStackSlot const& deepSlot = m_stack.at(m_stack.size() - _i - 1);\n\t\t\t\tYulName varNameDeep = slotVariableName(deepSlot);\n\t\t\t\tYulName varNameTop = slotVariableName(m_stack.back());\n\t\t\t\tstd::string msg =\n\t\t\t\t\t\"Cannot swap \" + (varNameDeep.empty() ? \"Slot \" + stackSlotToString(deepSlot, m_dialect) : \"Variable \" + varNameDeep.str()) +\n\t\t\t\t\t\" with \" + (varNameTop.empty() ? \"Slot \" + stackSlotToString(m_stack.back(), m_dialect) : \"Variable \" + varNameTop.str()) +\n\t\t\t\t\t\": too deep in the stack by \" + std::to_string(deficit) + \" slots in \" + stackToString(m_stack, m_dialect);\n\t\t\t\tm_stackErrors.emplace_back(StackTooDeepError(\n\t\t\t\t\tm_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulName{},\n\t\t\t\t\tvarNameDeep.empty() ? varNameTop : varNameDeep,\n\t\t\t\t\tdeficit,\n\t\t\t\t\tmsg\n\t\t\t\t) << langutil::errinfo_sourceLocation(sourceLocation));\n\t\t\t\tm_assembly.markAsInvalid();\n\t\t\t}\n\t\t},\n\t\t// Push or dup callback.\n\t\t[&](StackSlot const& _slot)\n\t\t{\n\t\t\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight(), \"\");\n\t\t\t// Dup the slot, if already on stack and reachable.\n\t\t\tif (auto depth = util::findOffset(m_stack | ranges::views::reverse, _slot))\n\t\t\t{\n\t\t\t\tif (*depth < m_reachableStackDepth)\n\t\t\t\t{\n\t\t\t\t\tappendDup(*depth + 1);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if (!canBeFreelyGenerated(_slot))\n\t\t\t\t{\n\t\t\t\t\tint deficit = static_cast<int>(*depth - (m_reachableStackDepth - 1));\n\t\t\t\t\tYulName varName = slotVariableName(_slot);\n\t\t\t\t\tstd::string msg =\n\t\t\t\t\t\t(varName.empty() ? \"Slot \" + stackSlotToString(_slot, m_dialect) : \"Variable \" + varName.str())\n\t\t\t\t\t\t+ \" is \" + std::to_string(*depth - (m_reachableStackDepth - 1)) + \" too deep in the stack \" + stackToString(m_stack, m_dialect);\n\t\t\t\t\tm_stackErrors.emplace_back(StackTooDeepError(\n\t\t\t\t\t\tm_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulName{},\n\t\t\t\t\t\tvarName,\n\t\t\t\t\t\tdeficit,\n\t\t\t\t\t\tmsg\n\t\t\t\t\t));\n\t\t\t\t\tm_assembly.markAsInvalid();\n\t\t\t\t\tm_assembly.appendConstant(u256(0xCAFFEE));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// else: the slot is too deep in stack, but can be freely generated, we fall through to push it again.\n\t\t\t}\n\n\t\t\t// The slot can be freely generated or is an unassigned return variable. Push it.\n\t\t\tstd::visit(util::GenericVisitor{\n\t\t\t\t[&](LiteralSlot const& _literal)\n\t\t\t\t{\n\t\t\t\t\tm_assembly.setSourceLocation(originLocationOf(_literal));\n\t\t\t\t\tm_assembly.appendConstant(_literal.value);\n\t\t\t\t\tm_assembly.setSourceLocation(sourceLocation);\n\t\t\t\t},\n\t\t\t\t[&](FunctionReturnLabelSlot const&)\n\t\t\t\t{\n\t\t\t\t\tyulAssert(false, \"Cannot produce function return label.\");\n\t\t\t\t},\n\t\t\t\t[&](FunctionCallReturnLabelSlot const& _returnLabel)\n\t\t\t\t{\n\t\t\t\t\tif (!m_returnLabels.count(&_returnLabel.call.get()))\n\t\t\t\t\t\tm_returnLabels[&_returnLabel.call.get()] = m_assembly.newLabelId();\n\t\t\t\t\tm_assembly.setSourceLocation(originLocationOf(_returnLabel.call.get()));\n\t\t\t\t\tm_assembly.appendLabelReference(m_returnLabels.at(&_returnLabel.call.get()));\n\t\t\t\t\tm_assembly.setSourceLocation(sourceLocation);\n\t\t\t\t},\n\t\t\t\t[&](VariableSlot const& _variable)\n\t\t\t\t{\n\t\t\t\t\tif (m_currentFunctionInfo && util::contains(m_currentFunctionInfo->returnVariables, _variable))\n\t\t\t\t\t{\n\t\t\t\t\t\tm_assembly.setSourceLocation(originLocationOf(_variable));\n\t\t\t\t\t\tm_assembly.appendConstant(0);\n\t\t\t\t\t\tm_assembly.setSourceLocation(sourceLocation);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tyulAssert(false, \"Variable not found on stack.\");\n\t\t\t\t},\n\t\t\t\t[&](TemporarySlot const&)\n\t\t\t\t{\n\t\t\t\t\tyulAssert(false, \"Function call result requested, but not found on stack.\");\n\t\t\t\t},\n\t\t\t\t[&](JunkSlot const&)\n\t\t\t\t{\n\t\t\t\t\t// Note: this will always be popped, so we can push anything.\n\t\t\t\t\tif (m_assembly.evmVersion().hasPush0())\n\t\t\t\t\t\tm_assembly.appendConstant(0);\n\t\t\t\t\telse\n\t\t\t\t\t\tm_assembly.appendInstruction(evmasm::Instruction::CODESIZE);\n\t\t\t\t}\n\t\t\t}, _slot);\n\t\t},\n\t\t// Pop callback.\n\t\t[&]()\n\t\t{\n\t\t\tm_assembly.appendInstruction(evmasm::Instruction::POP);\n\t\t},\n\t\tm_reachableStackDepth\n\t);\n\tyulAssert(m_assembly.stackHeight() == static_cast<int>(m_stack.size()), \"\");\n}\n\nvoid OptimizedEVMCodeTransform::appendSwap(size_t _depth)\n{\n\tif (_depth <= 16)\n\t\tm_assembly.appendInstruction(evmasm::swapInstruction(static_cast<unsigned>(_depth)));\n\telse\n\t{\n\t\tyulAssert(_depth <= m_reachableStackDepth);\n\t\tm_assembly.appendSwapN(_depth);\n\t}\n}\n\nvoid OptimizedEVMCodeTransform::appendDup(size_t _depth)\n{\n\tif (_depth <= 16)\n\t\tm_assembly.appendInstruction(evmasm::dupInstruction(static_cast<unsigned>(_depth)));\n\telse\n\t{\n\t\tyulAssert(_depth <= m_reachableStackDepth);\n\t\tm_assembly.appendDupN(_depth);\n\t}\n}\n\nvoid OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block)\n{\n\t// Assert that this is the first visit of the block and mark as generated.\n\tyulAssert(m_generated.insert(&_block).second, \"\");\n\n\tm_assembly.setSourceLocation(originLocationOf(_block));\n\tauto const& blockInfo = m_stackLayout.blockInfos.at(&_block);\n\n\t// Assert that the stack is valid for entering the block.\n\tassertLayoutCompatibility(m_stack, blockInfo.entryLayout);\n\tm_stack = blockInfo.entryLayout; // Might set some slots to junk, if not required by the block.\n\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight(), \"\");\n\n\t// Emit jump label, if required.\n\tif (auto label = util::valueOrNullptr(m_blockLabels, &_block))\n\t\tm_assembly.appendLabel(*label);\n\n\tfor (auto const& operation: _block.operations)\n\t{\n\t\t// Create required layout for entering the operation.\n\t\tcreateStackLayout(debugDataOf(operation.operation), m_stackLayout.operationEntryLayout.at(&operation));\n\n\t\t// Assert that we have the inputs of the operation on stack top.\n\t\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight(), \"\");\n\t\tyulAssert(m_stack.size() >= operation.input.size(), \"\");\n\t\tsize_t baseHeight = m_stack.size() - operation.input.size();\n\t\tassertLayoutCompatibility(\n\t\t\tm_stack | ranges::views::take_last(operation.input.size()) | ranges::to<Stack>,\n\t\t\toperation.input\n\t\t);\n\n\t\t// Perform the operation.\n\t\tstd::visit(*this, operation.operation);\n\n\t\t// Assert that the operation produced its proclaimed output.\n\t\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight(), \"\");\n\t\tyulAssert(m_stack.size() == baseHeight + operation.output.size(), \"\");\n\t\tyulAssert(m_stack.size() >= operation.output.size(), \"\");\n\t\tassertLayoutCompatibility(\n\t\t\tm_stack | ranges::views::take_last(operation.output.size()) | ranges::to<Stack>,\n\t\t\toperation.output\n\t\t);\n\t}\n\n\t// Exit the block.\n\tm_assembly.setSourceLocation(originLocationOf(_block));\n\tstd::visit(util::GenericVisitor{\n\t\t[&](CFG::BasicBlock::MainExit const&)\n\t\t{\n\t\t\tm_assembly.appendInstruction(evmasm::Instruction::STOP);\n\t\t},\n\t\t[&](CFG::BasicBlock::Jump const& _jump)\n\t\t{\n\t\t\t// Create the stack expected at the jump target.\n\t\t\tcreateStackLayout(debugDataOf(_jump), m_stackLayout.blockInfos.at(_jump.target).entryLayout);\n\n\t\t\t// If this is the only jump to the block, we do not need a label and can directly continue with the target block.\n\t\t\tif (!m_blockLabels.count(_jump.target) && _jump.target->entries.size() == 1)\n\t\t\t{\n\t\t\t\tyulAssert(!_jump.backwards, \"\");\n\t\t\t\t(*this)(*_jump.target);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Generate a jump label for the target, if not already present.\n\t\t\t\tif (!m_blockLabels.count(_jump.target))\n\t\t\t\t\tm_blockLabels[_jump.target] = m_assembly.newLabelId();\n\n\t\t\t\t// If we already have generated the target block, jump to it, otherwise generate it in place.\n\t\t\t\tif (m_generated.count(_jump.target))\n\t\t\t\t\tm_assembly.appendJumpTo(m_blockLabels[_jump.target]);\n\t\t\t\telse\n\t\t\t\t\t(*this)(*_jump.target);\n\t\t\t}\n\t\t},\n\t\t[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump)\n\t\t{\n\t\t\t// Create the shared entry layout of the jump targets, which is stored as exit layout of the current block.\n\t\t\tcreateStackLayout(debugDataOf(_conditionalJump), blockInfo.exitLayout);\n\n\t\t\t// Create labels for the targets, if not already present.\n\t\t\tif (!m_blockLabels.count(_conditionalJump.nonZero))\n\t\t\t\tm_blockLabels[_conditionalJump.nonZero] = m_assembly.newLabelId();\n\t\t\tif (!m_blockLabels.count(_conditionalJump.zero))\n\t\t\t\tm_blockLabels[_conditionalJump.zero] = m_assembly.newLabelId();\n\n\t\t\t// Assert that we have the correct condition on stack.\n\t\t\tyulAssert(!m_stack.empty(), \"\");\n\t\t\tyulAssert(m_stack.back() == _conditionalJump.condition, \"\");\n\n\t\t\t// Emit the conditional jump to the non-zero label and update the stored stack.\n\t\t\tm_assembly.appendJumpToIf(m_blockLabels[_conditionalJump.nonZero]);\n\t\t\tm_stack.pop_back();\n\n\t\t\t// Assert that we have a valid stack for both jump targets.\n\t\t\tassertLayoutCompatibility(m_stack, m_stackLayout.blockInfos.at(_conditionalJump.nonZero).entryLayout);\n\t\t\tassertLayoutCompatibility(m_stack, m_stackLayout.blockInfos.at(_conditionalJump.zero).entryLayout);\n\n\t\t\t{\n\t\t\t\t// Restore the stack afterwards for the non-zero case below.\n\t\t\t\tScopeGuard stackRestore([storedStack = m_stack, this]() {\n\t\t\t\t\tm_stack = std::move(storedStack);\n\t\t\t\t\tm_assembly.setStackHeight(static_cast<int>(m_stack.size()));\n\t\t\t\t});\n\n\t\t\t\t// If we have already generated the zero case, jump to it, otherwise generate it in place.\n\t\t\t\tif (m_generated.count(_conditionalJump.zero))\n\t\t\t\t\tm_assembly.appendJumpTo(m_blockLabels[_conditionalJump.zero]);\n\t\t\t\telse\n\t\t\t\t\t(*this)(*_conditionalJump.zero);\n\t\t\t}\n\t\t\t// Note that each block visit terminates control flow, so we cannot fall through from the zero case.\n\n\t\t\t// Generate the non-zero block, if not done already.\n\t\t\tif (!m_generated.count(_conditionalJump.nonZero))\n\t\t\t\t(*this)(*_conditionalJump.nonZero);\n\t\t},\n\t\t[&](CFG::BasicBlock::FunctionReturn const& _functionReturn)\n\t\t{\n\t\t\tyulAssert(m_currentFunctionInfo);\n\t\t\tyulAssert(m_currentFunctionInfo == _functionReturn.info);\n\t\t\tyulAssert(m_currentFunctionInfo->canContinue);\n\n\t\t\t// Construct the function return layout, which is fully determined by the function signature.\n\t\t\tStack exitStack = m_currentFunctionInfo->returnVariables | ranges::views::transform([](auto const& _varSlot){\n\t\t\t\treturn StackSlot{_varSlot};\n\t\t\t}) | ranges::to<Stack>;\n\t\t\tif (m_simulateFunctionsWithJumps)\n\t\t\t\texitStack.emplace_back(FunctionReturnLabelSlot{_functionReturn.info->function});\n\n\t\t\t// Create the function return layout and jump.\n\t\t\tcreateStackLayout(debugDataOf(_functionReturn), exitStack);\n\t\t\tif (!m_simulateFunctionsWithJumps)\n\t\t\t\tm_assembly.appendFunctionReturn();\n\t\t\telse\n\t\t\t\tm_assembly.appendJump(0, AbstractAssembly::JumpType::OutOfFunction);\n\t\t},\n\t\t[&](CFG::BasicBlock::Terminated const&)\n\t\t{\n\t\t\tyulAssert(!_block.operations.empty());\n\t\t\tif (CFG::BuiltinCall const* builtinCall = std::get_if<CFG::BuiltinCall>(&_block.operations.back().operation))\n\t\t\t\tyulAssert(builtinCall->builtin.get().controlFlowSideEffects.terminatesOrReverts(), \"\");\n\t\t\telse if (CFG::FunctionCall const* functionCall = std::get_if<CFG::FunctionCall>(&_block.operations.back().operation))\n\t\t\t\tyulAssert(!functionCall->canContinue);\n\t\t\telse\n\t\t\t\tyulAssert(false);\n\t\t}\n\t}, _block.exit);\n\t// TODO: We could assert that the last emitted assembly item terminated or was an (unconditional) jump.\n\t//       But currently AbstractAssembly does not allow peeking at the last emitted assembly item.\n\tm_stack.clear();\n\tm_assembly.setStackHeight(0);\n}\n\nvoid OptimizedEVMCodeTransform::operator()(CFG::FunctionInfo const& _functionInfo)\n{\n\tbool useReturnLabel = m_simulateFunctionsWithJumps && _functionInfo.canContinue;\n\tyulAssert(!m_currentFunctionInfo, \"\");\n\tScopedSaveAndRestore currentFunctionInfoRestore(m_currentFunctionInfo, &_functionInfo);\n\n\tyulAssert(m_stack.empty() && m_assembly.stackHeight() == 0, \"\");\n\n\t// Create function entry layout in m_stack.\n\tif (useReturnLabel)\n\t\tm_stack.emplace_back(FunctionReturnLabelSlot{_functionInfo.function});\n\tfor (auto const& param: _functionInfo.parameters | ranges::views::reverse)\n\t\tm_stack.emplace_back(param);\n\tif (!m_simulateFunctionsWithJumps)\n\t\tm_assembly.beginFunction(m_builtinContext.functionIDs[&_functionInfo.function]);\n\tm_assembly.setStackHeight(static_cast<int>(m_stack.size()));\n\n\tm_assembly.setSourceLocation(originLocationOf(_functionInfo));\n\tif (m_simulateFunctionsWithJumps)\n\t\tm_assembly.appendLabel(getFunctionLabel(_functionInfo.function));\n\n\t// Create the entry layout of the function body block and visit.\n\tcreateStackLayout(debugDataOf(_functionInfo), m_stackLayout.blockInfos.at(_functionInfo.entry).entryLayout);\n\t(*this)(*_functionInfo.entry);\n\n\tm_stack.clear();\n\tif (!m_simulateFunctionsWithJumps)\n\t\tm_assembly.endFunction();\n\tm_assembly.setStackHeight(0);\n}\n"
  },
  {
    "path": "libyul/backends/evm/OptimizedEVMCodeTransform.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Code generator for translating Yul / inline assembly to EVM.\n */\n\n#pragma once\n\n#include <libyul/AST.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/backends/evm/ControlFlowGraph.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Scope.h>\n\n#include <optional>\n#include <stack>\n\nnamespace solidity::langutil\n{\nclass ErrorReporter;\n}\n\nnamespace solidity::yul\n{\nstruct AsmAnalysisInfo;\nstruct StackLayout;\n\nclass OptimizedEVMCodeTransform\n{\npublic:\n\t/// Use named labels for functions 1) Yes and check that the names are unique\n\t/// 2) For none of the functions 3) for the first function of each name.\n\tenum class UseNamedLabels { YesAndForceUnique, Never, ForFirstFunctionOfEachName };\n\n\t[[nodiscard]] static std::vector<StackTooDeepError> run(\n\t\tAbstractAssembly& _assembly,\n\t\tAsmAnalysisInfo& _analysisInfo,\n\t\tBlock const& _block,\n\t\tEVMDialect const& _dialect,\n\t\tBuiltinContext& _builtinContext,\n\t\tUseNamedLabels _useNamedLabelsForFunctions\n\t);\n\n\t/// Generate code for the function call @a _call. Only public for using with std::visit.\n\tvoid operator()(CFG::FunctionCall const& _call);\n\t/// Generate code for the builtin call @a _call. Only public for using with std::visit.\n\tvoid operator()(CFG::BuiltinCall const& _call);\n\t/// Generate code for the assignment @a _assignment. Only public for using with std::visit.\n\tvoid operator()(CFG::Assignment const& _assignment);\nprivate:\n\tOptimizedEVMCodeTransform(\n\t\tAbstractAssembly& _assembly,\n\t\tBuiltinContext& _builtinContext,\n\t\tUseNamedLabels _useNamedLabelsForFunctions,\n\t\tCFG const& _dfg,\n\t\tStackLayout const& _stackLayout,\n\t\tbool _simulateFunctionsWithJumps,\n\t\tEVMDialect const& _dialect\n\t);\n\n\t/// Assert that it is valid to transition from @a _currentStack to @a _desiredStack.\n\t/// That is @a _currentStack matches each slot in @a _desiredStack that is not a JunkSlot exactly.\n\tstatic void assertLayoutCompatibility(Stack const& _currentStack, Stack const& _desiredStack);\n\n\t/// @returns The label of the entry point of the given @a _function.\n\t/// Creates and stores a new label, if none exists already.\n\tAbstractAssembly::LabelID getFunctionLabel(Scope::Function const& _function);\n\t/// Assert that @a _slot contains the value of @a _expression.\n\tstatic void validateSlot(StackSlot const& _slot, Expression const& _expression);\n\n\t/// Shuffles m_stack to the desired @a _targetStack while emitting the shuffling code to m_assembly.\n\t/// Sets the source locations to the one in @a _debugData.\n\tvoid createStackLayout(langutil::DebugData::ConstPtr _debugData, Stack _targetStack);\n\n\tvoid appendSwap(size_t _depth);\n\tvoid appendDup(size_t _depth);\n\n\t/// Generate code for the given block @a _block.\n\t/// Expects the current stack layout m_stack to be a stack layout that is compatible with the\n\t/// entry layout expected by the block.\n\t/// Recursively generates code for blocks that are jumped to.\n\t/// The last emitted assembly instruction is always an unconditional jump or terminating.\n\t/// Always exits with an empty stack layout.\n\tvoid operator()(CFG::BasicBlock const& _block);\n\n\t/// Generate code for the given function.\n\t/// Resets m_stack.\n\tvoid operator()(CFG::FunctionInfo const& _functionInfo);\n\n\tAbstractAssembly& m_assembly;\n\tBuiltinContext& m_builtinContext;\n\tCFG const& m_dfg;\n\tStackLayout const& m_stackLayout;\n\tEVMDialect const& m_dialect;\n\tStack m_stack;\n\tstd::map<yul::FunctionCall const*, AbstractAssembly::LabelID> m_returnLabels;\n\tstd::map<CFG::BasicBlock const*, AbstractAssembly::LabelID> m_blockLabels;\n\t/// Non-empty only if m_dfg.simulateFunctionsWithJumps == true\n\tstd::map<CFG::FunctionInfo const*, AbstractAssembly::LabelID> const m_functionLabels;\n\t/// Set of blocks already generated. If any of the contained blocks is ever jumped to, m_blockLabels should\n\t/// contain a jump label for it.\n\tstd::set<CFG::BasicBlock const*> m_generated;\n\tCFG::FunctionInfo const* m_currentFunctionInfo = nullptr;\n\tstd::vector<StackTooDeepError> m_stackErrors;\n\t/// True if it simulates functions with jumps. False otherwise. True for legacy bytecode\n\tbool m_simulateFunctionsWithJumps = true;\n\tsize_t const m_reachableStackDepth{};\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/StackHelpers.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ControlFlowGraph.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/algorithm/all_of.hpp>\n#include <range/v3/algorithm/any_of.hpp>\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/iota.hpp>\n#include <range/v3/view/reverse.hpp>\n#include <range/v3/view/take.hpp>\n\nnamespace solidity::yul\n{\n\ninline std::string stackSlotToString(StackSlot const& _slot, Dialect const& _dialect)\n{\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](FunctionCallReturnLabelSlot const& _ret) -> std::string { return \"RET[\" + std::string(resolveFunctionName(_ret.call.get().functionName, _dialect)) + \"]\"; },\n\t\t[](FunctionReturnLabelSlot const&) -> std::string { return \"RET\"; },\n\t\t[](VariableSlot const& _var) { return _var.variable.get().name.str(); },\n\t\t[](LiteralSlot const& _lit) { return toCompactHexWithPrefix(_lit.value); },\n\t\t[&](TemporarySlot const& _tmp) -> std::string { return \"TMP[\" + std::string(resolveFunctionName(_tmp.call.get().functionName, _dialect)) + \", \" + std::to_string(_tmp.index) + \"]\"; },\n\t\t[](JunkSlot const&) -> std::string { return \"JUNK\"; }\n\t}, _slot);\n}\n\ninline std::string stackToString(Stack const& _stack, Dialect const& _dialect)\n{\n\tstd::string result(\"[ \");\n\tfor (auto const& slot: _stack)\n\t\tresult += stackSlotToString(slot, _dialect) + ' ';\n\tresult += ']';\n\treturn result;\n}\n\n\n// Used as an interface for the stack shuffler below.\n// The shuffle operation class is expected to internally keep track of a current stack layout (the \"source layout\")\n// that the shuffler is supposed to shuffle to a fixed target stack layout.\n// The shuffler works iteratively. At each iteration it instantiates an instance of the shuffle operations and\n// queries it for various information about the current source stack layout and the target layout, as described\n// in the interface below.\n// Based on that information the shuffler decides which is the next optimal operation to perform on the stack\n// and calls the corresponding entry point in the shuffling operations (swap, pushOrDupTarget or pop).\ntemplate<typename ShuffleOperations>\nconcept ShuffleOperationConcept = requires(ShuffleOperations ops, size_t sourceOffset, size_t targetOffset, size_t depth) {\n\t// Returns true, iff the current slot at sourceOffset in source layout is a suitable slot at targetOffset.\n\t{ ops.isCompatible(sourceOffset, targetOffset) } -> std::convertible_to<bool>;\n\t// Returns true, iff the slots at the two given source offsets are identical.\n\t{ ops.sourceIsSame(sourceOffset, sourceOffset) } -> std::convertible_to<bool>;\n\t// Returns a positive integer n, if the slot at the given source offset needs n more copies.\n\t// Returns a negative integer -n, if the slot at the given source offsets occurs n times too many.\n\t// Returns zero if the amount of occurrences, in the current source layout, of the slot at the given source offset\n\t// matches the desired amount of occurrences in the target.\n\t{ ops.sourceMultiplicity(sourceOffset) } -> std::convertible_to<int>;\n\t// Returns a positive integer n, if the slot at the given target offset needs n more copies.\n\t// Returns a negative integer -n, if the slot at the given target offsets occurs n times too many.\n\t// Returns zero if the amount of occurrences, in the current source layout, of the slot at the given target offset\n\t// matches the desired amount of occurrences in the target.\n\t{ ops.targetMultiplicity(targetOffset) } -> std::convertible_to<int>;\n\t// Returns true, iff any slot is compatible with the given target offset.\n\t{ ops.targetIsArbitrary(targetOffset) } -> std::convertible_to<bool>;\n\t// Returns the number of slots in the source layout.\n\t{ ops.sourceSize() } -> std::convertible_to<size_t>;\n\t// Returns the number of slots in the target layout.\n\t{ ops.targetSize() } -> std::convertible_to<size_t>;\n\t// Swaps the top most slot in the source with the slot `depth` slots below the top.\n\t// In terms of EVM opcodes this is supposed to be a `SWAP<depth>`.\n\t// In terms of vectors this is supposed to be `std::swap(source.at(source.size() - depth - 1, source.top))`.\n\t{ ops.swap(depth) };\n\t// Pops the top most slot in the source, i.e. the slot at offset ops.sourceSize() - 1.\n\t// In terms of EVM opcodes this is `POP`.\n\t// In terms of vectors this is `source.pop();`.\n\t{ ops.pop() };\n\t// Dups or pushes the slot that is supposed to end up at the given target offset.\n\t{ ops.pushOrDupTarget(targetOffset) };\n\t// Maximum reachable depth with swaps and dups.\n\t{ ops.reachableStackDepth } -> std::convertible_to<size_t>;\n};\n\n/// Helper class that can perform shuffling of a source stack layout to a target stack layout via\n/// abstracted shuffle operations.\ntemplate<ShuffleOperationConcept ShuffleOperations>\nclass Shuffler\n{\npublic:\n\t/// Executes the stack shuffling operations. Instantiates an instance of ShuffleOperations\n\t/// in each iteration. Each iteration performs exactly one operation that modifies the stack.\n\t/// After `shuffle`, source and target have the same size and all slots in the source layout are\n\t/// compatible with the slots at the same target offset.\n\ttemplate<typename... Args>\n\tstatic void shuffle(Args&&... args)\n\t{\n\t\tbool needsMoreShuffling = true;\n\t\t// The shuffling algorithm should always terminate in polynomial time, but we provide a limit\n\t\t// in case it does not terminate due to a bug.\n\t\tsize_t iterationCount = 0;\n\t\twhile (iterationCount < 1000 && (needsMoreShuffling = shuffleStep(std::forward<Args>(args)...)))\n\t\t\t++iterationCount;\n\t\tyulAssert(!needsMoreShuffling, \"Could not create stack layout after 1000 iterations.\");\n\t}\nprivate:\n\t// If dupping an ideal slot causes a slot that will still be required to become unreachable, then dup\n\t// the latter slot first.\n\t// @returns true, if it performed a dup.\n\tstatic bool dupDeepSlotIfRequired(ShuffleOperations& _ops)\n\t{\n\t\t// Check if the stack is large enough for anything to potentially become unreachable.\n\t\tif (_ops.sourceSize() < (_ops.reachableStackDepth - 1))\n\t\t\treturn false;\n\t\t// Check whether any deep slot might still be needed later (i.e. we still need to reach it with a DUP or SWAP).\n\t\tfor (size_t sourceOffset: ranges::views::iota(0u, _ops.sourceSize() - (_ops.reachableStackDepth - 1)))\n\t\t{\n\t\t\t// This slot needs to be moved.\n\t\t\tif (!_ops.isCompatible(sourceOffset, sourceOffset))\n\t\t\t{\n\t\t\t\t// If the current top fixes the slot, swap it down now.\n\t\t\t\tif (_ops.isCompatible(_ops.sourceSize() - 1, sourceOffset))\n\t\t\t\t{\n\t\t\t\t\t_ops.swap(_ops.sourceSize() - sourceOffset - 1);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// Bring up a slot to fix this now, if possible.\n\t\t\t\tif (bringUpTargetSlot(_ops, sourceOffset))\n\t\t\t\t\treturn true;\n\t\t\t\t// Otherwise swap up the slot that will fix the offending slot.\n\t\t\t\tfor (auto offset: ranges::views::iota(sourceOffset + 1, _ops.sourceSize()))\n\t\t\t\t\tif (_ops.isCompatible(offset, sourceOffset))\n\t\t\t\t\t{\n\t\t\t\t\t\t_ops.swap(_ops.sourceSize() - offset - 1);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t// Otherwise give up - we will need stack compression or stack limit evasion.\n\t\t\t}\n\t\t\t// We need another copy of this slot.\n\t\t\telse if (_ops.sourceMultiplicity(sourceOffset) > 0)\n\t\t\t{\n\t\t\t\t// If this slot occurs again later, we skip this occurrence.\n\t\t\t\tif (ranges::any_of(\n\t\t\t\t\tranges::views::iota(sourceOffset + 1, _ops.sourceSize()),\n\t\t\t\t\t[&](size_t _offset) { return _ops.sourceIsSame(sourceOffset, _offset); }\n\t\t\t\t))\n\t\t\t\t\tcontinue;\n\t\t\t\t// Bring up the target slot that would otherwise become unreachable.\n\t\t\t\tfor (size_t targetOffset: ranges::views::iota(0u, _ops.targetSize()))\n\t\t\t\t\tif (!_ops.targetIsArbitrary(targetOffset) && _ops.isCompatible(sourceOffset, targetOffset))\n\t\t\t\t\t{\n\t\t\t\t\t\t_ops.pushOrDupTarget(targetOffset);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\t/// Finds a slot to dup or push with the aim of eventually fixing @a _targetOffset in the target.\n\t/// In the simplest case, the slot at @a _targetOffset has a multiplicity > 0, i.e. it can directly be dupped or pushed\n\t/// and the next iteration will fix @a _targetOffset.\n\t/// But, in general, there may already be enough copies of the slot that is supposed to end up at @a _targetOffset\n\t/// on stack, s.t. it cannot be dupped again. In that case there has to be a copy of the desired slot on stack already\n\t/// elsewhere that is not yet in place (`nextOffset` below). The fact that ``nextOffset`` is not in place means that\n\t/// we can (recursively) try bringing up the slot that is supposed to end up at ``nextOffset`` in the *target*.\n\t/// When the target slot at ``nextOffset`` is fixed, the current source slot at ``nextOffset`` will be\n\t/// at the stack top, which is the slot required at @a _targetOffset.\n\tstatic bool bringUpTargetSlot(ShuffleOperations& _ops, size_t _targetOffset)\n\t{\n\t\tstd::list<size_t> toVisit{_targetOffset};\n\t\t// mark on enqueue\n\t\tstd::set<size_t> visited{_targetOffset};\n\n\t\twhile (!toVisit.empty())\n\t\t{\n\t\t\tauto offset = *toVisit.begin();\n\t\t\ttoVisit.erase(toVisit.begin());\n\t\t\tif (_ops.targetMultiplicity(offset) > 0)\n\t\t\t{\n\t\t\t\t_ops.pushOrDupTarget(offset);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t// There must be another slot we can dup/push that will lead to the target slot at ``offset`` to be fixed.\n\t\t\tfor (auto nextOffset: ranges::views::iota(0u, std::min(_ops.sourceSize(), _ops.targetSize())))\n\t\t\t\tif (\n\t\t\t\t\t!_ops.isCompatible(nextOffset, nextOffset) &&\n\t\t\t\t\t_ops.isCompatible(nextOffset, offset)\n\t\t\t\t)\n\t\t\t\t\tif (visited.insert(nextOffset).second)  // insert returns false if already present\n\t\t\t\t\t\ttoVisit.emplace_back(nextOffset);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/// Performs a single stack operation, transforming the source layout closer to the target layout.\n\ttemplate<typename... Args>\n\tstatic bool shuffleStep(Args&&... args)\n\t{\n\t\tShuffleOperations ops{std::forward<Args>(args)...};\n\n\t\t// All source slots are final.\n\t\tif (ranges::all_of(\n\t\t\tranges::views::iota(0u, ops.sourceSize()),\n\t\t\t[&](size_t _index) { return ops.isCompatible(_index, _index); }\n\t\t))\n\t\t{\n\t\t\t// Bring up all remaining target slots, if any, or terminate otherwise.\n\t\t\tif (ops.sourceSize() < ops.targetSize())\n\t\t\t{\n\t\t\t\tif (!dupDeepSlotIfRequired(ops))\n\t\t\t\t\tyulAssert(bringUpTargetSlot(ops, ops.sourceSize()), \"\");\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tsize_t sourceTop = ops.sourceSize() - 1;\n\t\t// If we no longer need the current stack top, we pop it, unless we need an arbitrary slot at this position\n\t\t// in the target.\n\t\tif (\n\t\t\tops.sourceMultiplicity(sourceTop) < 0 &&\n\t\t\t!ops.targetIsArbitrary(sourceTop)\n\t\t)\n\t\t{\n\t\t\tops.pop();\n\t\t\treturn true;\n\t\t}\n\n\t\tyulAssert(ops.targetSize() > 0, \"\");\n\n\t\t// If the top is not supposed to be exactly what is on top right now, try to find a lower position to swap it to.\n\t\tif (!ops.isCompatible(sourceTop, sourceTop) || ops.targetIsArbitrary(sourceTop))\n\t\t\tfor (size_t offset: ranges::views::iota(0u, std::min(ops.sourceSize(), ops.targetSize())))\n\t\t\t\t// It makes sense to swap to a lower position, if\n\t\t\t\tif (\n\t\t\t\t\t!ops.isCompatible(offset, offset) && // The lower slot is not already in position.\n\t\t\t\t\t!ops.sourceIsSame(offset, sourceTop) && // We would not just swap identical slots.\n\t\t\t\t\tops.isCompatible(sourceTop, offset) // The lower position wants to have this slot.\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// We cannot swap that deep.\n\t\t\t\t\tif (ops.sourceSize() - offset - 1 > ops.reachableStackDepth)\n\t\t\t\t\t{\n\t\t\t\t\t\t// If there is a reachable slot to be removed, park the current top there.\n\t\t\t\t\t\tfor (size_t swapDepth: ranges::views::iota(1u, ops.reachableStackDepth + 1u) | ranges::views::reverse)\n\t\t\t\t\t\t\tif (ops.sourceMultiplicity(ops.sourceSize() - 1 - swapDepth) < 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tops.swap(swapDepth);\n\t\t\t\t\t\t\t\tif (ops.targetIsArbitrary(sourceTop))\n\t\t\t\t\t\t\t\t\t// Usually we keep a slot that is to-be-removed, if the current top is arbitrary.\n\t\t\t\t\t\t\t\t\t// However, since we are in a stack-too-deep situation, pop it immediately\n\t\t\t\t\t\t\t\t\t// to compress the stack (we can always push back junk in the end).\n\t\t\t\t\t\t\t\t\tops.pop();\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t// Otherwise we rely on stack compression or stack-to-memory.\n\t\t\t\t\t}\n\t\t\t\t\tops.swap(ops.sourceSize() - offset - 1);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t// ops.sourceSize() > ops.targetSize() cannot be true anymore, since if the source top is no longer required,\n\t\t// we already popped it, and if it is required, we already swapped it down to a suitable target position.\n\t\tyulAssert(ops.sourceSize() <= ops.targetSize(), \"\");\n\n\t\t// If a lower slot should be removed, try to bring up the slot that should end up there and bring it up.\n\t\t// Note that after the cases above, there will always be a target slot to duplicate in this case.\n\t\tfor (size_t offset: ranges::views::iota(0u, ops.sourceSize()))\n\t\t\tif (\n\t\t\t\t!ops.isCompatible(offset, offset) && // The lower slot is not already in position.\n\t\t\t\tops.sourceMultiplicity(offset) < 0 && // We have too many copies of this slot.\n\t\t\t\toffset <= ops.targetSize() && // There is a target slot at this position.\n\t\t\t\t!ops.targetIsArbitrary(offset) // And that target slot is not arbitrary.\n\t\t\t)\n\t\t\t{\n\t\t\t\tif (!dupDeepSlotIfRequired(ops))\n\t\t\t\t\tyulAssert(bringUpTargetSlot(ops, offset), \"\");\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t// At this point we want to keep all slots.\n\t\tfor (size_t i = 0; i < ops.sourceSize(); ++i)\n\t\t\tyulAssert(ops.sourceMultiplicity(i) >= 0, \"\");\n\t\tyulAssert(ops.sourceSize() <= ops.targetSize(), \"\");\n\n\t\t// If the top is not in position, try to find a slot that wants to be at the top and swap it up.\n\t\tif (!ops.isCompatible(sourceTop, sourceTop))\n\t\t\tfor (size_t sourceOffset: ranges::views::iota(0u, ops.sourceSize()))\n\t\t\t\tif (\n\t\t\t\t\t!ops.isCompatible(sourceOffset, sourceOffset) &&\n\t\t\t\t\tops.isCompatible(sourceOffset, sourceTop)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tops.swap(ops.sourceSize() - sourceOffset - 1);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t// If we still need more slots, produce a suitable one.\n\t\tif (ops.sourceSize() < ops.targetSize())\n\t\t{\n\t\t\tif (!dupDeepSlotIfRequired(ops))\n\t\t\t\tyulAssert(bringUpTargetSlot(ops, ops.sourceSize()), \"\");\n\t\t\treturn true;\n\t\t}\n\n\t\t// The stack has the correct size, each slot has the correct number of copies and the top is in position.\n\t\tyulAssert(ops.sourceSize() == ops.targetSize(), \"\");\n\t\tsize_t size = ops.sourceSize();\n\t\tfor (size_t i = 0; i < ops.sourceSize(); ++i)\n\t\t\tyulAssert(ops.sourceMultiplicity(i) == 0 && (ops.targetIsArbitrary(i) || ops.targetMultiplicity(i) == 0), \"\");\n\t\tyulAssert(ops.isCompatible(sourceTop, sourceTop), \"\");\n\n\t\tauto swappableOffsets = ranges::views::iota(size > ops.reachableStackDepth + 1u ? size - (ops.reachableStackDepth + 1u) : 0u, size);\n\n\t\t// If we find a lower slot that is out of position, but also compatible with the top, swap that up.\n\t\tfor (size_t offset: swappableOffsets)\n\t\t\tif (!ops.isCompatible(offset, offset) && ops.isCompatible(sourceTop, offset))\n\t\t\t{\n\t\t\t\tops.swap(size - offset - 1);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t// Swap up any reachable slot that is still out of position.\n\t\tfor (size_t offset: swappableOffsets)\n\t\t\tif (!ops.isCompatible(offset, offset) && !ops.sourceIsSame(offset, sourceTop))\n\t\t\t{\n\t\t\t\tops.swap(size - offset - 1);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t// We are in a stack-too-deep situation and try to reduce the stack size.\n\t\t// If the current top is merely kept since the target slot is arbitrary, pop it.\n\t\tif (ops.targetIsArbitrary(sourceTop) && ops.sourceMultiplicity(sourceTop) <= 0)\n\t\t{\n\t\t\tops.pop();\n\t\t\treturn true;\n\t\t}\n\t\t// If any reachable slot is merely kept, since the target slot is arbitrary, swap it up and pop it.\n\t\tfor (size_t offset: swappableOffsets)\n\t\t\tif (ops.targetIsArbitrary(offset) && ops.sourceMultiplicity(offset) <= 0)\n\t\t\t{\n\t\t\t\tops.swap(size - offset - 1);\n\t\t\t\tops.pop();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t// We cannot avoid a stack-too-deep error. Repeat the above without restricting to reachable slots.\n\t\tfor (size_t offset: ranges::views::iota(0u, size))\n\t\t\tif (!ops.isCompatible(offset, offset) && ops.isCompatible(sourceTop, offset))\n\t\t\t{\n\t\t\t\tops.swap(size - offset - 1);\n\t\t\t\treturn true;\n\t\t\t}\n\t\tfor (size_t offset: ranges::views::iota(0u, size))\n\t\t\tif (!ops.isCompatible(offset, offset) && !ops.sourceIsSame(offset, sourceTop))\n\t\t\t{\n\t\t\t\tops.swap(size - offset - 1);\n\t\t\t\treturn true;\n\t\t\t}\n\t\tyulAssert(false, \"\");\n\n\t\t// FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794)\n\t\tthrow std::exception();\n\t}\n};\n\n/// A simple optimized map for mapping StackSlots to ints.\nclass Multiplicity\n{\npublic:\n\tint& operator[](StackSlot const& _slot)\n\t{\n\t\tif (auto* p = std::get_if<FunctionCallReturnLabelSlot>(&_slot))\n\t\t\treturn m_functionCallReturnLabelSlotMultiplicity[*p];\n\t\tif (std::holds_alternative<FunctionReturnLabelSlot>(_slot))\n\t\t\treturn m_functionReturnLabelSlotMultiplicity;\n\t\tif (auto* p = std::get_if<VariableSlot>(&_slot))\n\t\t\treturn m_variableSlotMultiplicity[*p];\n\t\tif (auto* p = std::get_if<LiteralSlot>(&_slot))\n\t\t\treturn m_literalSlotMultiplicity[*p];\n\t\tif (auto* p = std::get_if<TemporarySlot>(&_slot))\n\t\t\treturn m_temporarySlotMultiplicity[*p];\n\t\tyulAssert(std::holds_alternative<JunkSlot>(_slot));\n\t\treturn m_junkSlotMultiplicity;\n\t}\n\n\tint at(StackSlot const& _slot) const\n\t{\n\t\tif (auto* p = std::get_if<FunctionCallReturnLabelSlot>(&_slot))\n\t\t\treturn m_functionCallReturnLabelSlotMultiplicity.at(*p);\n\t\tif (std::holds_alternative<FunctionReturnLabelSlot>(_slot))\n\t\t\treturn m_functionReturnLabelSlotMultiplicity;\n\t\tif (auto* p = std::get_if<VariableSlot>(&_slot))\n\t\t\treturn m_variableSlotMultiplicity.at(*p);\n\t\tif (auto* p = std::get_if<LiteralSlot>(&_slot))\n\t\t\treturn m_literalSlotMultiplicity.at(*p);\n\t\tif (auto* p = std::get_if<TemporarySlot>(&_slot))\n\t\t\treturn m_temporarySlotMultiplicity.at(*p);\n\t\tyulAssert(std::holds_alternative<JunkSlot>(_slot));\n\t\treturn m_junkSlotMultiplicity;\n\t}\n\nprivate:\n\tstd::map<FunctionCallReturnLabelSlot, int> m_functionCallReturnLabelSlotMultiplicity;\n\tint m_functionReturnLabelSlotMultiplicity = 0;\n\tstd::map<VariableSlot, int> m_variableSlotMultiplicity;\n\tstd::map<LiteralSlot, int> m_literalSlotMultiplicity;\n\tstd::map<TemporarySlot, int> m_temporarySlotMultiplicity;\n\tint m_junkSlotMultiplicity = 0;\n};\n\n/// Transforms @a _currentStack to @a _targetStack, invoking the provided shuffling operations.\n/// Modifies @a _currentStack itself after each invocation of the shuffling operations.\n/// @a _swap is a function with signature void(unsigned) that is called when the top most slot is swapped with\n/// the slot `depth` slots below the top. In terms of EVM opcodes this is supposed to be a `SWAP<depth>`.\n/// @a _pushOrDup is a function with signature void(StackSlot const&) that is called to push or dup the slot given as\n/// its argument to the stack top.\n/// @a _pop is a function with signature void() that is called when the top most slot is popped.\ntemplate<typename Swap, typename PushOrDup, typename Pop>\nvoid createStackLayout(\n\tStack& _currentStack,\n\tStack const& _targetStack,\n\tSwap _swap,\n\tPushOrDup _pushOrDup,\n\tPop _pop,\n\tsize_t _reachableStackDepth\n)\n{\n\tstruct ShuffleOperations\n\t{\n\t\tStack& currentStack;\n\t\tStack const& targetStack;\n\t\tSwap swapCallback;\n\t\tPushOrDup pushOrDupCallback;\n\t\tPop popCallback;\n\t\tMultiplicity multiplicity;\n\t\tsize_t reachableStackDepth;\n\t\tShuffleOperations(\n\t\t\tStack& _currentStack,\n\t\t\tStack const& _targetStack,\n\t\t\tSwap _swap,\n\t\t\tPushOrDup _pushOrDup,\n\t\t\tPop _pop,\n\t\t\tsize_t _reachableStackDepth\n\t\t):\n\t\t\tcurrentStack(_currentStack),\n\t\t\ttargetStack(_targetStack),\n\t\t\tswapCallback(_swap),\n\t\t\tpushOrDupCallback(_pushOrDup),\n\t\t\tpopCallback(_pop),\n\t\t\treachableStackDepth(_reachableStackDepth)\n\t\t{\n\t\t\tfor (auto const& slot: currentStack)\n\t\t\t\t--multiplicity[slot];\n\t\t\tfor (auto&& [offset, slot]: targetStack | ranges::views::enumerate)\n\t\t\t\tif (std::holds_alternative<JunkSlot>(slot) && offset < currentStack.size())\n\t\t\t\t\t++multiplicity[currentStack.at(offset)];\n\t\t\t\telse\n\t\t\t\t\t++multiplicity[slot];\n\t\t}\n\t\tbool isCompatible(size_t _source, size_t _target)\n\t\t{\n\t\t\treturn\n\t\t\t\t_source < currentStack.size() &&\n\t\t\t\t_target < targetStack.size() &&\n\t\t\t\t(\n\t\t\t\t\tstd::holds_alternative<JunkSlot>(targetStack.at(_target)) ||\n\t\t\t\t\tcurrentStack.at(_source) == targetStack.at(_target)\n\t\t\t\t);\n\t\t}\n\t\tbool sourceIsSame(size_t _lhs, size_t _rhs) { return currentStack.at(_lhs) == currentStack.at(_rhs); }\n\t\tint sourceMultiplicity(size_t _offset) { return multiplicity.at(currentStack.at(_offset)); }\n\t\tint targetMultiplicity(size_t _offset) { return multiplicity.at(targetStack.at(_offset)); }\n\t\tbool targetIsArbitrary(size_t offset)\n\t\t{\n\t\t\treturn offset < targetStack.size() && std::holds_alternative<JunkSlot>(targetStack.at(offset));\n\t\t}\n\t\tvoid swap(size_t _i)\n\t\t{\n\t\t\tswapCallback(static_cast<unsigned>(_i));\n\t\t\tstd::swap(currentStack.at(currentStack.size() - _i - 1), currentStack.back());\n\t\t}\n\t\tsize_t sourceSize() { return currentStack.size(); }\n\t\tsize_t targetSize() { return targetStack.size(); }\n\t\tvoid pop()\n\t\t{\n\t\t\tpopCallback();\n\t\t\tcurrentStack.pop_back();\n\t\t}\n\t\tvoid pushOrDupTarget(size_t _offset)\n\t\t{\n\t\t\tauto const& targetSlot = targetStack.at(_offset);\n\t\t\tpushOrDupCallback(targetSlot);\n\t\t\tcurrentStack.push_back(targetSlot);\n\t\t}\n\t};\n\n\tShuffler<ShuffleOperations>::shuffle(_currentStack, _targetStack, _swap, _pushOrDup, _pop, _reachableStackDepth);\n\n\tyulAssert(_currentStack.size() == _targetStack.size(), \"\");\n\tfor (auto&& [current, target]: ranges::zip_view(_currentStack, _targetStack))\n\t\tif (std::holds_alternative<JunkSlot>(target))\n\t\t\tcurrent = JunkSlot{};\n\t\telse\n\t\t\tyulAssert(current == target, \"\");\n}\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/StackLayoutGenerator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Stack layout generator for Yul to EVM code generation.\n */\n\n#include <libyul/backends/evm/StackLayoutGenerator.h>\n\n#include <libyul/backends/evm/StackHelpers.h>\n\n#include <libevmasm/GasMeter.h>\n\n#include <libsolutil/Algorithms.h>\n\n#include <range/v3/algorithm/any_of.hpp>\n#include <range/v3/algorithm/find.hpp>\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/all.hpp>\n#include <range/v3/view/concat.hpp>\n#include <range/v3/view/drop.hpp>\n#include <range/v3/view/drop_last.hpp>\n#include <range/v3/view/filter.hpp>\n#include <range/v3/view/iota.hpp>\n#include <range/v3/view/map.hpp>\n#include <range/v3/view/reverse.hpp>\n#include <range/v3/view/take.hpp>\n#include <range/v3/view/take_last.hpp>\n#include <range/v3/view/transform.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nStackLayout StackLayoutGenerator::run(CFG const& _cfg, EVMDialect const& _evmDialect)\n{\n\tStackLayout stackLayout{{}, {}};\n\tStackLayoutGenerator{\n\t\tstackLayout,\n\t\tnullptr,\n\t\t_evmDialect\n\t}.processEntryPoint(*_cfg.entry);\n\n\tfor (auto& functionInfo: _cfg.functionInfo | ranges::views::values)\n\t\tStackLayoutGenerator{\n\t\t\tstackLayout,\n\t\t\t&functionInfo,\n\t\t\t_evmDialect\n\t\t}.processEntryPoint(*functionInfo.entry, &functionInfo);\n\n\treturn stackLayout;\n}\n\nstd::map<YulName, std::vector<StackLayoutGenerator::StackTooDeep>> StackLayoutGenerator::reportStackTooDeep(\n\tCFG const& _cfg,\n\tEVMDialect const& _evmDialect\n)\n{\n\tstd::map<YulName, std::vector<StackLayoutGenerator::StackTooDeep>> stackTooDeepErrors;\n\tstackTooDeepErrors[YulName{}] = reportStackTooDeep(_cfg, YulName{}, _evmDialect);\n\tfor (auto const& function: _cfg.functions)\n\t\tif (auto errors = reportStackTooDeep(_cfg, function->name, _evmDialect); !errors.empty())\n\t\t\tstackTooDeepErrors[function->name] = std::move(errors);\n\treturn stackTooDeepErrors;\n}\n\nstd::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(\n\tCFG const& _cfg,\n\tYulName _functionName,\n\tEVMDialect const& _evmDialect\n)\n{\n\tStackLayout stackLayout{{}, {}};\n\tCFG::FunctionInfo const* functionInfo = nullptr;\n\tif (!_functionName.empty())\n\t{\n\t\tfunctionInfo = &ranges::find(\n\t\t\t_cfg.functionInfo,\n\t\t\t_functionName,\n\t\t\tutil::mapTuple([](auto&&, auto&& info) { return info.function.name; })\n\t\t)->second;\n\t\tyulAssert(functionInfo, \"Function not found.\");\n\t}\n\n\tStackLayoutGenerator generator{stackLayout, functionInfo, _evmDialect};\n\tCFG::BasicBlock const* entry = functionInfo ? functionInfo->entry : _cfg.entry;\n\tgenerator.processEntryPoint(*entry);\n\treturn generator.reportStackTooDeep(*entry);\n}\n\nStackLayoutGenerator::StackLayoutGenerator(\n\tStackLayout& _layout,\n\tCFG::FunctionInfo const* _functionInfo,\n\tEVMDialect const& _evmDialect\n):\n\tm_layout(_layout),\n\tm_currentFunctionInfo(_functionInfo),\n\tm_evmDialect(_evmDialect)\n{\n}\n\nnamespace\n{\n/// @returns all stack too deep errors that would occur when shuffling @a _source to @a _target.\nstd::vector<StackLayoutGenerator::StackTooDeep> findStackTooDeep(\n\tStack const& _source,\n\tStack const& _target,\n\tsize_t _reachableStackDepth\n)\n{\n\tStack currentStack = _source;\n\tstd::vector<StackLayoutGenerator::StackTooDeep> stackTooDeepErrors;\n\tauto getVariableChoices = [](auto&& _range) {\n\t\tstd::vector<YulName> result;\n\t\tfor (auto const& slot: _range)\n\t\t\tif (auto const* variableSlot = std::get_if<VariableSlot>(&slot))\n\t\t\t\tif (!util::contains(result, variableSlot->variable.get().name))\n\t\t\t\t\tresult.push_back(variableSlot->variable.get().name);\n\t\treturn result;\n\t};\n\t::createStackLayout(\n\t\tcurrentStack,\n\t\t_target,\n\t\t[&](unsigned _i)\n\t\t{\n\t\t\tif (_i > _reachableStackDepth)\n\t\t\t\tstackTooDeepErrors.emplace_back(StackLayoutGenerator::StackTooDeep{\n\t\t\t\t\t_i - _reachableStackDepth,\n\t\t\t\t\tgetVariableChoices(currentStack | ranges::views::take_last(_i + 1))\n\t\t\t\t});\n\t\t},\n\t\t[&](StackSlot const& _slot)\n\t\t{\n\t\t\tif (canBeFreelyGenerated(_slot))\n\t\t\t\treturn;\n\t\t\tif (\n\t\t\t\tauto depth = util::findOffset(currentStack | ranges::views::reverse, _slot);\n\t\t\t\tdepth && *depth >= _reachableStackDepth\n\t\t\t)\n\t\t\t\tstackTooDeepErrors.emplace_back(StackLayoutGenerator::StackTooDeep{\n\t\t\t\t\t*depth - (_reachableStackDepth - 1),\n\t\t\t\t\tgetVariableChoices(currentStack | ranges::views::take_last(*depth + 1))\n\t\t\t\t});\n\t\t},\n\t\t[&]() {},\n\t\t_reachableStackDepth\n\t);\n\treturn stackTooDeepErrors;\n}\n\n/// @returns the ideal stack to have before executing an operation that outputs @a _operationOutput, s.t.\n/// shuffling to @a _post is cheap (excluding the input of the operation itself).\n/// If @a _generateSlotOnTheFly returns true for a slot, this slot should not occur in the ideal stack, but\n/// rather be generated on the fly during shuffling.\ntemplate<typename Callable>\nStack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Callable _generateSlotOnTheFly, size_t _reachableStackDepth)\n{\n\tstruct PreviousSlot { size_t slot; };\n\n\t// Determine the number of slots that have to be on stack before executing the operation (excluding\n\t// the inputs of the operation itself).\n\t// That is slots that should not be generated on the fly and are not outputs of the operation.\n\tsize_t preOperationLayoutSize = _post.size();\n\tfor (auto const& slot: _post)\n\t\tif (util::contains(_operationOutput, slot) || _generateSlotOnTheFly(slot))\n\t\t\t--preOperationLayoutSize;\n\n\t// The symbolic layout directly after the operation has the form\n\t// PreviousSlot{0}, ..., PreviousSlot{n}, [output<0>], ..., [output<m>]\n\tauto layout = ranges::views::iota(0u, preOperationLayoutSize) |\n\t\tranges::views::transform([](size_t _index) { return PreviousSlot{_index}; }) |\n\t\tranges::to<std::vector<std::variant<PreviousSlot, StackSlot>>>;\n\tlayout += _operationOutput;\n\n\t// Shortcut for trivial case.\n\tif (layout.empty())\n\t\treturn Stack{};\n\n\t// Next we will shuffle the layout to the post stack using ShuffleOperations\n\t// that are aware of PreviousSlot's.\n\tstruct ShuffleOperations\n\t{\n\t\tstd::vector<std::variant<PreviousSlot, StackSlot>>& layout;\n\t\tStack const& post;\n\t\tstd::set<StackSlot> outputs;\n\t\tMultiplicity multiplicity;\n\t\tCallable generateSlotOnTheFly;\n\t\tsize_t const reachableStackDepth;\n\t\tShuffleOperations(\n\t\t\tstd::vector<std::variant<PreviousSlot, StackSlot>>& _layout,\n\t\t\tStack const& _post,\n\t\t\tCallable _generateSlotOnTheFly,\n\t\t\tsize_t _reachableStackDepth\n\t\t): layout(_layout), post(_post), generateSlotOnTheFly(_generateSlotOnTheFly), reachableStackDepth(_reachableStackDepth)\n\t\t{\n\t\t\tfor (auto const& layoutSlot: layout)\n\t\t\t\tif (StackSlot const* slot = std::get_if<StackSlot>(&layoutSlot))\n\t\t\t\t\toutputs.insert(*slot);\n\n\t\t\tfor (auto const& layoutSlot: layout)\n\t\t\t\tif (StackSlot const* slot = std::get_if<StackSlot>(&layoutSlot))\n\t\t\t\t\t--multiplicity[*slot];\n\t\t\tfor (auto&& slot: post)\n\t\t\t\tif (outputs.count(slot) || generateSlotOnTheFly(slot))\n\t\t\t\t\t++multiplicity[slot];\n\t\t}\n\t\tbool isCompatible(size_t _source, size_t _target)\n\t\t{\n\t\t\treturn\n\t\t\t\t_source < layout.size() &&\n\t\t\t\t_target < post.size() &&\n\t\t\t\t(\n\t\t\t\t\tstd::holds_alternative<JunkSlot>(post.at(_target)) ||\n\t\t\t\t\tstd::visit(util::GenericVisitor{\n\t\t\t\t\t\t[&](PreviousSlot const&) {\n\t\t\t\t\t\t\treturn !outputs.count(post.at(_target)) && !generateSlotOnTheFly(post.at(_target));\n\t\t\t\t\t\t},\n\t\t\t\t\t\t[&](StackSlot const& _s) { return _s == post.at(_target); }\n\t\t\t\t\t}, layout.at(_source))\n\t\t\t\t);\n\t\t}\n\t\tbool sourceIsSame(size_t _lhs, size_t _rhs)\n\t\t{\n\t\t\treturn std::visit(util::GenericVisitor{\n\t\t\t\t[&](PreviousSlot const&, PreviousSlot const&) { return true; },\n\t\t\t\t[&](StackSlot const& _lhs, StackSlot const& _rhs) { return _lhs == _rhs; },\n\t\t\t\t[&](auto const&, auto const&) { return false; }\n\t\t\t}, layout.at(_lhs), layout.at(_rhs));\n\t\t}\n\t\tint sourceMultiplicity(size_t _offset)\n\t\t{\n\t\t\treturn std::visit(util::GenericVisitor{\n\t\t\t\t[&](PreviousSlot const&) { return 0; },\n\t\t\t\t[&](StackSlot const& _s) { return multiplicity.at(_s); }\n\t\t\t}, layout.at(_offset));\n\t\t}\n\t\tint targetMultiplicity(size_t _offset)\n\t\t{\n\t\t\tif (!outputs.count(post.at(_offset)) && !generateSlotOnTheFly(post.at(_offset)))\n\t\t\t\treturn 0;\n\t\t\treturn multiplicity.at(post.at(_offset));\n\t\t}\n\t\tbool targetIsArbitrary(size_t _offset)\n\t\t{\n\t\t\treturn _offset < post.size() && std::holds_alternative<JunkSlot>(post.at(_offset));\n\t\t}\n\t\tvoid swap(size_t _i)\n\t\t{\n\t\t\tyulAssert(!std::holds_alternative<PreviousSlot>(layout.at(layout.size() - _i - 1)) || !std::holds_alternative<PreviousSlot>(layout.back()), \"\");\n\t\t\tstd::swap(layout.at(layout.size() -  _i - 1), layout.back());\n\t\t}\n\t\tsize_t sourceSize() { return layout.size(); }\n\t\tsize_t targetSize() { return post.size(); }\n\t\tvoid pop() { layout.pop_back(); }\n\t\tvoid pushOrDupTarget(size_t _offset) { layout.push_back(post.at(_offset)); }\n\t};\n\tShuffler<ShuffleOperations>::shuffle(layout, _post, _generateSlotOnTheFly, _reachableStackDepth);\n\n\t// Now we can construct the ideal layout before the operation.\n\t// \"layout\" has shuffled the PreviousSlot{x} to new places using minimal operations to move the operation\n\t// output in place. The resulting permutation of the PreviousSlot yields the ideal positions of slots\n\t// before the operation, i.e. if PreviousSlot{2} is at a position at which _post contains VariableSlot{\"tmp\"},\n\t// then we want the variable tmp in the slot at offset 2 in the layout before the operation.\n\tstd::vector<std::optional<StackSlot>> idealLayout(_post.size(), std::nullopt);\n\tfor (auto&& [slot, idealPosition]: ranges::zip_view(_post, layout))\n\t\tif (PreviousSlot* previousSlot = std::get_if<PreviousSlot>(&idealPosition))\n\t\t\tidealLayout.at(previousSlot->slot) = slot;\n\n\t// The tail of layout must have contained the operation outputs and will not have been assigned slots in the last loop.\n\twhile (!idealLayout.empty() && !idealLayout.back())\n\t\tidealLayout.pop_back();\n\n\tyulAssert(idealLayout.size() == preOperationLayoutSize, \"\");\n\n\treturn idealLayout | ranges::views::transform([](std::optional<StackSlot> s) {\n\t\tyulAssert(s, \"\");\n\t\treturn *s;\n\t}) | ranges::to<Stack>;\n}\n}\n\nStack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG::Operation const& _operation, bool _aggressiveStackCompression)\n{\n\t// Enable aggressive stack compression for recursive calls.\n\tif (auto const* functionCall = std::get_if<CFG::FunctionCall>(&_operation.operation))\n\t\tif (functionCall->recursive)\n\t\t\t_aggressiveStackCompression = true;\n\n\t// This is a huge tradeoff between code size, gas cost and stack size.\n\tauto generateSlotOnTheFly = [&](StackSlot const& _slot) {\n\t\treturn _aggressiveStackCompression && canBeFreelyGenerated(_slot);\n\t};\n\n\t// Determine the ideal permutation of the slots in _exitLayout that are not operation outputs (and not to be\n\t// generated on the fly), s.t. shuffling the `stack + _operation.output` to _exitLayout is cheap.\n\tStack stack = createIdealLayout(_operation.output, _exitStack, generateSlotOnTheFly, reachableStackDepth());\n\n\t// Make sure the resulting previous slots do not overlap with any assigned variables.\n\tif (auto const* assignment = std::get_if<CFG::Assignment>(&_operation.operation))\n\t\tfor (auto& stackSlot: stack)\n\t\t\tif (auto const* varSlot = std::get_if<VariableSlot>(&stackSlot))\n\t\t\t\tyulAssert(!util::contains(assignment->variables, *varSlot), \"\");\n\n\t// Since stack+_operation.output can be easily shuffled to _exitLayout, the desired layout before the operation\n\t// is stack+_operation.input;\n\tstack += _operation.input;\n\n\t// Store the exact desired operation entry layout. The stored layout will be recreated by the code transform\n\t// before executing the operation. However, this recreation can produce slots that can be freely generated or\n\t// are duplicated, i.e. we can compress the stack afterwards without causing problems for code generation later.\n\tm_layout.operationEntryLayout[&_operation] = stack;\n\n\t// Remove anything from the stack top that can be freely generated or dupped from deeper on the stack.\n\twhile (!stack.empty())\n\t{\n\t\tif (canBeFreelyGenerated(stack.back()))\n\t\t\tstack.pop_back();\n\t\telse if (auto offset = util::findOffset(stack | ranges::views::reverse | ranges::views::drop(1), stack.back()))\n\t\t{\n\t\t\tif (*offset + 2 < reachableStackDepth())\n\t\t\t\tstack.pop_back();\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n\n\treturn stack;\n}\n\nStack StackLayoutGenerator::propagateStackThroughBlock(Stack _exitStack, CFG::BasicBlock const& _block, bool _aggressiveStackCompression)\n{\n\tStack stack = _exitStack;\n\tfor (auto&& [idx, operation]: _block.operations | ranges::views::enumerate | ranges::views::reverse)\n\t{\n\t\tStack newStack = propagateStackThroughOperation(stack, operation, _aggressiveStackCompression);\n\t\tif (!_aggressiveStackCompression && !findStackTooDeep(newStack, stack, reachableStackDepth()).empty())\n\t\t\t// If we had stack errors, run again with aggressive stack compression.\n\t\t\treturn propagateStackThroughBlock(std::move(_exitStack), _block, true);\n\t\tstack = std::move(newStack);\n\t}\n\n\treturn stack;\n}\n\nvoid StackLayoutGenerator::processEntryPoint(CFG::BasicBlock const& _entry, CFG::FunctionInfo const* _functionInfo)\n{\n\tstd::list<CFG::BasicBlock const*> toVisit{&_entry};\n\tstd::set<CFG::BasicBlock const*> visited;\n\n\t// TODO: check whether visiting only a subset of these in the outer iteration below is enough.\n\tstd::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps = collectBackwardsJumps(_entry);\n\n\twhile (!toVisit.empty())\n\t{\n\t\t// First calculate stack layouts without walking backwards jumps, i.e. assuming the current preliminary\n\t\t// entry layout of the backwards jump target as the initial exit layout of the backwards-jumping block.\n\t\twhile (!toVisit.empty())\n\t\t{\n\t\t\tCFG::BasicBlock const* block = *toVisit.begin();\n\t\t\ttoVisit.pop_front();\n\n\t\t\tif (visited.count(block))\n\t\t\t\tcontinue;\n\n\t\t\tif (std::optional<Stack> exitLayout = getExitLayoutOrStageDependencies(*block, visited, toVisit))\n\t\t\t{\n\t\t\t\tvisited.emplace(block);\n\t\t\t\tauto& info = m_layout.blockInfos[block];\n\t\t\t\tinfo.exitLayout = *exitLayout;\n\t\t\t\tinfo.entryLayout = propagateStackThroughBlock(info.exitLayout, *block);\n\n\t\t\t\tfor (auto entry: block->entries)\n\t\t\t\t\ttoVisit.emplace_back(entry);\n\t\t\t}\n\t\t\telse\n\t\t\t\tcontinue;\n\t\t}\n\n\t\t// Determine which backwards jumps still require fixing and stage revisits of appropriate nodes.\n\t\tfor (auto [jumpingBlock, target]: backwardsJumps)\n\t\t\t// This block jumps backwards, but does not provide all slots required by the jump target on exit.\n\t\t\t// Therefore we need to visit the subgraph between ``target`` and ``jumpingBlock`` again.\n\t\t\tif (ranges::any_of(\n\t\t\t\tm_layout.blockInfos[target].entryLayout,\n\t\t\t\t[exitLayout = m_layout.blockInfos[jumpingBlock].exitLayout](StackSlot const& _slot) {\n\t\t\t\t\treturn !util::contains(exitLayout, _slot);\n\t\t\t\t}\n\t\t\t))\n\t\t\t{\n\t\t\t\t// In particular we can visit backwards starting from ``jumpingBlock`` and mark all entries to-be-visited-\n\t\t\t\t// again until we hit ``target``.\n\t\t\t\ttoVisit.emplace_front(jumpingBlock);\n\t\t\t\t// Since we are likely to permute the entry layout of ``target``, we also visit its entries again.\n\t\t\t\t// This is not required for correctness, since the set of stack slots will match, but it may move some\n\t\t\t\t// required stack shuffling from the loop condition to outside the loop.\n\t\t\t\tfor (CFG::BasicBlock const* entry: target->entries)\n\t\t\t\t\tvisited.erase(entry);\n\t\t\t\tutil::BreadthFirstSearch<CFG::BasicBlock const*>{{jumpingBlock}}.run(\n\t\t\t\t\t[&visited, target = target](CFG::BasicBlock const* _block, auto _addChild) {\n\t\t\t\t\t\tvisited.erase(_block);\n\t\t\t\t\t\tif (_block == target)\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\tfor (auto const* entry: _block->entries)\n\t\t\t\t\t\t\t_addChild(entry);\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\t// While the shuffled layout for ``target`` will be compatible, it can be worthwhile propagating\n\t\t\t\t// it further up once more.\n\t\t\t\t// This would mean not stopping at _block == target above, resp. even doing visited.clear() here, revisiting the entire graph.\n\t\t\t\t// This is a tradeoff between the runtime of this process and the optimality of the result.\n\t\t\t\t// Also note that while visiting the entire graph again *can* be helpful, it can also be detrimental.\n\t\t\t}\n\t}\n\n\tstitchConditionalJumps(_entry);\n\tfillInJunk(_entry, _functionInfo);\n}\n\nstd::optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(\n\tCFG::BasicBlock const& _block,\n\tstd::set<CFG::BasicBlock const*> const& _visited,\n\tstd::list<CFG::BasicBlock const*>& _toVisit\n) const\n{\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](CFG::BasicBlock::MainExit const&) -> std::optional<Stack>\n\t\t{\n\t\t\t// On the exit of the outermost block the stack can be empty.\n\t\t\treturn Stack{};\n\t\t},\n\t\t[&](CFG::BasicBlock::Jump const& _jump) -> std::optional<Stack>\n\t\t{\n\t\t\tif (_jump.backwards)\n\t\t\t{\n\t\t\t\t// Choose the best currently known entry layout of the jump target as initial exit.\n\t\t\t\t// Note that this may not yet be the final layout.\n\t\t\t\tif (auto* info = util::valueOrNullptr(m_layout.blockInfos, _jump.target))\n\t\t\t\t\treturn info->entryLayout;\n\t\t\t\treturn Stack{};\n\t\t\t}\n\t\t\t// If the current iteration has already visited the jump target, start from its entry layout.\n\t\t\tif (_visited.count(_jump.target))\n\t\t\t\treturn m_layout.blockInfos.at(_jump.target).entryLayout;\n\t\t\t// Otherwise stage the jump target for visit and defer the current block.\n\t\t\t_toVisit.emplace_front(_jump.target);\n\t\t\treturn std::nullopt;\n\t\t},\n\t\t[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump) -> std::optional<Stack>\n\t\t{\n\t\t\tbool zeroVisited = _visited.count(_conditionalJump.zero);\n\t\t\tbool nonZeroVisited = _visited.count(_conditionalJump.nonZero);\n\t\t\tif (zeroVisited && nonZeroVisited)\n\t\t\t{\n\t\t\t\t// If the current iteration has already visited both jump targets, start from its entry layout.\n\t\t\t\tStack stack = combineStack(\n\t\t\t\t\tm_layout.blockInfos.at(_conditionalJump.zero).entryLayout,\n\t\t\t\t\tm_layout.blockInfos.at(_conditionalJump.nonZero).entryLayout,\n\t\t\t\t\treachableStackDepth()\n\t\t\t\t);\n\t\t\t\t// Additionally, the jump condition has to be at the stack top at exit.\n\t\t\t\tstack.emplace_back(_conditionalJump.condition);\n\t\t\t\treturn stack;\n\t\t\t}\n\t\t\t// If one of the jump targets has not been visited, stage it for visit and defer the current block.\n\t\t\tif (!zeroVisited)\n\t\t\t\t_toVisit.emplace_front(_conditionalJump.zero);\n\t\t\tif (!nonZeroVisited)\n\t\t\t\t_toVisit.emplace_front(_conditionalJump.nonZero);\n\t\t\treturn std::nullopt;\n\t\t},\n\t\t[&](CFG::BasicBlock::FunctionReturn const& _functionReturn) -> std::optional<Stack>\n\t\t{\n\t\t\t// A function return needs the return variables and the function return label slot on stack.\n\t\t\tyulAssert(_functionReturn.info, \"\");\n\t\t\tStack stack = _functionReturn.info->returnVariables | ranges::views::transform([](auto const& _varSlot){\n\t\t\t\treturn StackSlot{_varSlot};\n\t\t\t}) | ranges::to<Stack>;\n\n\t\t\tif (simulateFunctionsWithJumps())\n\t\t\t\tstack.emplace_back(FunctionReturnLabelSlot{_functionReturn.info->function});\n\t\t\treturn stack;\n\t\t},\n\t\t[&](CFG::BasicBlock::Terminated const&) -> std::optional<Stack>\n\t\t{\n\t\t\t// A terminating block can have an empty stack on exit.\n\t\t\treturn Stack{};\n\t\t},\n\t}, _block.exit);\n}\n\nstd::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> StackLayoutGenerator::collectBackwardsJumps(CFG::BasicBlock const& _entry) const\n{\n\tstd::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps;\n\tutil::BreadthFirstSearch<CFG::BasicBlock const*>{{&_entry}}.run([&](CFG::BasicBlock const* _block, auto _addChild) {\n\t\tstd::visit(util::GenericVisitor{\n\t\t\t[&](CFG::BasicBlock::MainExit const&) {},\n\t\t\t[&](CFG::BasicBlock::Jump const& _jump)\n\t\t\t{\n\t\t\t\tif (_jump.backwards)\n\t\t\t\t\tbackwardsJumps.emplace_back(_block, _jump.target);\n\t\t\t\t_addChild(_jump.target);\n\t\t\t},\n\t\t\t[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump)\n\t\t\t{\n\t\t\t\t_addChild(_conditionalJump.zero);\n\t\t\t\t_addChild(_conditionalJump.nonZero);\n\t\t\t},\n\t\t\t[&](CFG::BasicBlock::FunctionReturn const&) {},\n\t\t\t[&](CFG::BasicBlock::Terminated const&) {},\n\t\t}, _block->exit);\n\t});\n\treturn backwardsJumps;\n}\n\nvoid StackLayoutGenerator::stitchConditionalJumps(CFG::BasicBlock const& _block)\n{\n\tutil::BreadthFirstSearch<CFG::BasicBlock const*> breadthFirstSearch{{&_block}};\n\tbreadthFirstSearch.run([&](CFG::BasicBlock const* _block, auto _addChild) {\n\t\tauto& info = m_layout.blockInfos.at(_block);\n\t\tstd::visit(util::GenericVisitor{\n\t\t\t[&](CFG::BasicBlock::MainExit const&) {},\n\t\t\t[&](CFG::BasicBlock::Jump const& _jump)\n\t\t\t{\n\t\t\t\tif (!_jump.backwards)\n\t\t\t\t\t_addChild(_jump.target);\n\t\t\t},\n\t\t\t[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump)\n\t\t\t{\n\t\t\t\tauto& zeroTargetInfo = m_layout.blockInfos.at(_conditionalJump.zero);\n\t\t\t\tauto& nonZeroTargetInfo = m_layout.blockInfos.at(_conditionalJump.nonZero);\n\t\t\t\tStack exitLayout = info.exitLayout;\n\n\t\t\t\t// The last block must have produced the condition at the stack top.\n\t\t\t\tyulAssert(!exitLayout.empty(), \"\");\n\t\t\t\tyulAssert(exitLayout.back() == _conditionalJump.condition, \"\");\n\t\t\t\t// The condition is consumed by the jump.\n\t\t\t\texitLayout.pop_back();\n\n\t\t\t\tauto fixJumpTargetEntry = [&](Stack const& _originalEntryLayout) -> Stack {\n\t\t\t\t\tStack newEntryLayout = exitLayout;\n\t\t\t\t\t// Whatever the block being jumped to does not actually require, can be marked as junk.\n\t\t\t\t\tfor (auto& slot: newEntryLayout)\n\t\t\t\t\t\tif (!util::contains(_originalEntryLayout, slot))\n\t\t\t\t\t\t\tslot = JunkSlot{};\n\t\t\t\t\t// Make sure everything the block being jumped to requires is actually present or can be generated.\n\t\t\t\t\tfor (auto const& slot: _originalEntryLayout)\n\t\t\t\t\t\tyulAssert(canBeFreelyGenerated(slot) || util::contains(newEntryLayout, slot), \"\");\n\t\t\t\t\treturn newEntryLayout;\n\t\t\t\t};\n\t\t\t\tzeroTargetInfo.entryLayout = fixJumpTargetEntry(zeroTargetInfo.entryLayout);\n\t\t\t\tnonZeroTargetInfo.entryLayout = fixJumpTargetEntry(nonZeroTargetInfo.entryLayout);\n\t\t\t\t_addChild(_conditionalJump.zero);\n\t\t\t\t_addChild(_conditionalJump.nonZero);\n\t\t\t},\n\t\t\t[&](CFG::BasicBlock::FunctionReturn const&) {},\n\t\t\t[&](CFG::BasicBlock::Terminated const&) { },\n\t\t}, _block->exit);\n\t});\n}\n\nStack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _stack2, size_t _reachableStackDepth)\n{\n\t// TODO: it would be nicer to replace this by a constructive algorithm.\n\t// Currently it uses a reduced version of the Heap Algorithm to partly brute-force, which seems\n\t// to work decently well.\n\n\tStack commonPrefix;\n\tfor (auto&& [slot1, slot2]: ranges::zip_view(_stack1, _stack2))\n\t{\n\t\tif (!(slot1 == slot2))\n\t\t\tbreak;\n\t\tcommonPrefix.emplace_back(slot1);\n\t}\n\n\tStack stack1Tail = _stack1 | ranges::views::drop(commonPrefix.size()) | ranges::to<Stack>;\n\tStack stack2Tail = _stack2 | ranges::views::drop(commonPrefix.size()) | ranges::to<Stack>;\n\n\tif (stack1Tail.empty())\n\t\treturn commonPrefix + compressStack(stack2Tail, _reachableStackDepth);\n\tif (stack2Tail.empty())\n\t\treturn commonPrefix + compressStack(stack1Tail, _reachableStackDepth);\n\n\tStack candidate;\n\tfor (auto slot: stack1Tail)\n\t\tif (!util::contains(candidate, slot))\n\t\t\tcandidate.emplace_back(slot);\n\tfor (auto slot: stack2Tail)\n\t\tif (!util::contains(candidate, slot))\n\t\t\tcandidate.emplace_back(slot);\n\tstd::erase_if(candidate, [](StackSlot const& slot) {\n\t\treturn std::holds_alternative<LiteralSlot>(slot) || std::holds_alternative<FunctionCallReturnLabelSlot>(slot);\n\t});\n\n\tauto evaluate = [&](Stack const& _candidate) -> size_t {\n\t\tsize_t numOps = 0;\n\t\tStack testStack = _candidate;\n\t\tauto swap = [&](unsigned _swapDepth) { ++numOps; if (_swapDepth > _reachableStackDepth) numOps += 1000; };\n\t\tauto dupOrPush = [&](StackSlot const& _slot)\n\t\t{\n\t\t\tif (canBeFreelyGenerated(_slot))\n\t\t\t\treturn;\n\t\t\tauto depth = util::findOffset(ranges::concat_view(commonPrefix, testStack) | ranges::views::reverse, _slot);\n\t\t\tif (depth && *depth >= _reachableStackDepth)\n\t\t\t\tnumOps += 1000;\n\t\t};\n\t\tcreateStackLayout(testStack, stack1Tail, swap, dupOrPush, [&](){}, _reachableStackDepth);\n\t\ttestStack = _candidate;\n\t\tcreateStackLayout(testStack, stack2Tail, swap, dupOrPush, [&](){}, _reachableStackDepth);\n\t\treturn numOps;\n\t};\n\n\t// See https://en.wikipedia.org/wiki/Heap's_algorithm\n\tsize_t n = candidate.size();\n\tStack bestCandidate = candidate;\n\tsize_t bestCost = evaluate(candidate);\n\tstd::vector<size_t> c(n, 0);\n\tsize_t i = 1;\n\twhile (i < n)\n\t{\n\t\tif (c[i] < i)\n\t\t{\n\t\t\tif (i & 1)\n\t\t\t\tstd::swap(candidate.front(), candidate[i]);\n\t\t\telse\n\t\t\t\tstd::swap(candidate[c[i]], candidate[i]);\n\t\t\tsize_t cost = evaluate(candidate);\n\t\t\tif (cost < bestCost)\n\t\t\t{\n\t\t\t\tbestCost = cost;\n\t\t\t\tbestCandidate = candidate;\n\t\t\t}\n\t\t\t++c[i];\n\t\t\t// Note that for a proper implementation of the Heap algorithm this would need to revert back to ``i = 1.``\n\t\t\t// However, the incorrect implementation produces decent result and the proper version would have n!\n\t\t\t// complexity and is thereby not feasible.\n\t\t\t++i;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tc[i] = 0;\n\t\t\t++i;\n\t\t}\n\t}\n\n\treturn commonPrefix + bestCandidate;\n}\n\nstd::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG::BasicBlock const& _entry) const\n{\n\tstd::vector<StackTooDeep> stackTooDeepErrors;\n\tutil::BreadthFirstSearch<CFG::BasicBlock const*> breadthFirstSearch{{&_entry}};\n\tbreadthFirstSearch.run([&](CFG::BasicBlock const* _block, auto _addChild) {\n\t\tStack currentStack = m_layout.blockInfos.at(_block).entryLayout;\n\n\t\tfor (auto const& operation: _block->operations)\n\t\t{\n\t\t\tStack& operationEntry = m_layout.operationEntryLayout.at(&operation);\n\n\t\t\tstackTooDeepErrors += findStackTooDeep(currentStack, operationEntry, reachableStackDepth());\n\t\t\tcurrentStack = operationEntry;\n\t\t\tfor (size_t i = 0; i < operation.input.size(); i++)\n\t\t\t\tcurrentStack.pop_back();\n\t\t\tcurrentStack += operation.output;\n\t\t}\n\t\t// Do not attempt to create the exit layout m_layout.blockInfos.at(_block).exitLayout here,\n\t\t// since the code generator will directly move to the target entry layout.\n\n\t\tstd::visit(util::GenericVisitor{\n\t\t\t[&](CFG::BasicBlock::MainExit const&) {},\n\t\t\t[&](CFG::BasicBlock::Jump const& _jump)\n\t\t\t{\n\t\t\t\tStack const& targetLayout = m_layout.blockInfos.at(_jump.target).entryLayout;\n\t\t\t\tstackTooDeepErrors += findStackTooDeep(currentStack, targetLayout, reachableStackDepth());\n\n\t\t\t\tif (!_jump.backwards)\n\t\t\t\t\t_addChild(_jump.target);\n\t\t\t},\n\t\t\t[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump)\n\t\t\t{\n\t\t\t\tfor (Stack const& targetLayout: {\n\t\t\t\t\tm_layout.blockInfos.at(_conditionalJump.zero).entryLayout,\n\t\t\t\t\tm_layout.blockInfos.at(_conditionalJump.nonZero).entryLayout\n\t\t\t\t})\n\t\t\t\t\tstackTooDeepErrors += findStackTooDeep(currentStack, targetLayout, reachableStackDepth());\n\n\t\t\t\t_addChild(_conditionalJump.zero);\n\t\t\t\t_addChild(_conditionalJump.nonZero);\n\t\t\t},\n\t\t\t[&](CFG::BasicBlock::FunctionReturn const&) {},\n\t\t\t[&](CFG::BasicBlock::Terminated const&) {},\n\t\t}, _block->exit);\n\t});\n\treturn stackTooDeepErrors;\n}\n\nStack StackLayoutGenerator::compressStack(Stack _stack, size_t _reachableStackDepth)\n{\n\tstd::optional<size_t> firstDupOffset;\n\tdo\n\t{\n\t\tif (firstDupOffset)\n\t\t{\n\t\t\tstd::swap(_stack.at(*firstDupOffset), _stack.back());\n\t\t\t_stack.pop_back();\n\t\t\tfirstDupOffset.reset();\n\t\t}\n\t\tfor (auto&& [depth, slot]: _stack | ranges::views::reverse | ranges::views::enumerate)\n\t\t\tif (canBeFreelyGenerated(slot))\n\t\t\t{\n\t\t\t\tfirstDupOffset = _stack.size() - depth - 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (auto dupDepth = util::findOffset(_stack | ranges::views::reverse | ranges::views::drop(depth + 1), slot))\n\t\t\t\tif (depth + *dupDepth <= _reachableStackDepth)\n\t\t\t\t{\n\t\t\t\t\tfirstDupOffset = _stack.size() - depth - 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t}\n\twhile (firstDupOffset);\n\treturn _stack;\n}\n\nvoid StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::FunctionInfo const* _functionInfo)\n{\n\t/// Recursively adds junk to the subgraph starting on @a _entry.\n\t/// Since it is only called on cut-vertices, the full subgraph retains proper stack balance.\n\tauto addJunkRecursive = [&](CFG::BasicBlock const* _entry, size_t _numJunk) {\n\t\tutil::BreadthFirstSearch<CFG::BasicBlock const*> breadthFirstSearch{{_entry}};\n\t\tbreadthFirstSearch.run([&](CFG::BasicBlock const* _block, auto _addChild) {\n\t\t\tauto& blockInfo = m_layout.blockInfos.at(_block);\n\t\t\tblockInfo.entryLayout = Stack{_numJunk, JunkSlot{}} + std::move(blockInfo.entryLayout);\n\t\t\tfor (auto const& operation: _block->operations)\n\t\t\t{\n\t\t\t\tauto& operationEntryLayout = m_layout.operationEntryLayout.at(&operation);\n\t\t\t\toperationEntryLayout = Stack{_numJunk, JunkSlot{}} + std::move(operationEntryLayout);\n\t\t\t}\n\t\t\tblockInfo.exitLayout = Stack{_numJunk, JunkSlot{}} + std::move(blockInfo.exitLayout);\n\n\t\t\tstd::visit(util::GenericVisitor{\n\t\t\t\t[&](CFG::BasicBlock::MainExit const&) {},\n\t\t\t\t[&](CFG::BasicBlock::Jump const& _jump)\n\t\t\t\t{\n\t\t\t\t\t_addChild(_jump.target);\n\t\t\t\t},\n\t\t\t\t[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump)\n\t\t\t\t{\n\t\t\t\t\t_addChild(_conditionalJump.zero);\n\t\t\t\t\t_addChild(_conditionalJump.nonZero);\n\t\t\t\t},\n\t\t\t\t[&](CFG::BasicBlock::FunctionReturn const&) { yulAssert(!simulateFunctionsWithJumps()); },\n\t\t\t\t[&](CFG::BasicBlock::Terminated const&) {},\n\t\t\t}, _block->exit);\n\t\t});\n\t};\n\t/// @returns the number of operations required to transform @a _source to @a _target.\n\tauto evaluateTransform = [&](Stack _source, Stack const& _target) -> size_t {\n\t\tsize_t opGas = 0;\n\t\tauto swap = [&](unsigned _swapDepth)\n\t\t{\n\t\t\tif (_swapDepth > reachableStackDepth())\n\t\t\t\topGas += 1000;\n\t\t\telse\n\t\t\t\topGas += evmasm::GasMeter::swapGas(_swapDepth, m_evmDialect.evmVersion());\n\t\t};\n\t\tauto dupOrPush = [&](StackSlot const& _slot)\n\t\t{\n\t\t\tif (canBeFreelyGenerated(_slot))\n\t\t\t\topGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(32), m_evmDialect.evmVersion());\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (auto depth = util::findOffset(_source | ranges::views::reverse, _slot))\n\t\t\t\t{\n\t\t\t\t\tif (*depth < reachableStackDepth())\n\t\t\t\t\t\topGas += evmasm::GasMeter::dupGas(*depth + 1, m_evmDialect.evmVersion());\n\t\t\t\t\telse\n\t\t\t\t\t\topGas += 1000;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// This has to be a previously unassigned return variable.\n\t\t\t\t\t// We at least sanity-check that it is among the return variables at all.\n\t\t\t\t\tyulAssert(m_currentFunctionInfo && std::holds_alternative<VariableSlot>(_slot));\n\t\t\t\t\tyulAssert(util::contains(m_currentFunctionInfo->returnVariables, std::get<VariableSlot>(_slot)));\n\t\t\t\t\t// Strictly speaking the cost of the PUSH0 depends on the targeted EVM version, but the difference\n\t\t\t\t\t// will not matter here.\n\t\t\t\t\topGas += evmasm::GasMeter::pushGas(u256(0), m_evmDialect.evmVersion());\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tauto pop = [&]() { opGas += evmasm::GasMeter::runGas(evmasm::Instruction::POP, m_evmDialect.evmVersion()); };\n\t\tcreateStackLayout(_source, _target, swap, dupOrPush, pop, reachableStackDepth());\n\t\treturn opGas;\n\t};\n\t/// @returns the number of junk slots to be prepended to @a _targetLayout for an optimal transition from\n\t/// @a _entryLayout to @a _targetLayout.\n\tauto getBestNumJunk = [&](Stack const& _entryLayout, Stack const& _targetLayout) -> size_t {\n\t\tsize_t bestCost = evaluateTransform(_entryLayout, _targetLayout);\n\t\tsize_t bestNumJunk = 0;\n\t\tsize_t maxJunk = _entryLayout.size();\n\t\tfor (size_t numJunk = 1; numJunk <= maxJunk; ++numJunk)\n\t\t{\n\t\t\tsize_t cost = evaluateTransform(_entryLayout, Stack{numJunk, JunkSlot{}} + _targetLayout);\n\t\t\tif (cost < bestCost)\n\t\t\t{\n\t\t\t\tbestCost = cost;\n\t\t\t\tbestNumJunk = numJunk;\n\t\t\t}\n\t\t}\n\t\treturn bestNumJunk;\n\t};\n\n\tif (_functionInfo && !_functionInfo->canContinue && _block.allowsJunk())\n\t{\n\t\tsize_t bestNumJunk = getBestNumJunk(\n\t\t\t_functionInfo->parameters | ranges::views::reverse | ranges::to<Stack>,\n\t\t\tm_layout.blockInfos.at(&_block).entryLayout\n\t\t);\n\t\tif (bestNumJunk > 0)\n\t\t\taddJunkRecursive(&_block, bestNumJunk);\n\t}\n\n\t/// Traverses the CFG and at each block that allows junk, i.e. that is a cut-vertex that never leads to a function\n\t/// return, checks if adding junk reduces the shuffling cost upon entering and if so recursively adds junk\n\t/// to the spanned subgraph.\n\tutil::BreadthFirstSearch<CFG::BasicBlock const*>{{&_block}}.run([&](CFG::BasicBlock const* _block, auto _addChild) {\n\t\tif (_block->allowsJunk())\n\t\t{\n\t\t\tauto& blockInfo = m_layout.blockInfos.at(_block);\n\t\t\tStack entryLayout = blockInfo.entryLayout;\n\t\t\tStack const& nextLayout = _block->operations.empty() ? blockInfo.exitLayout : m_layout.operationEntryLayout.at(&_block->operations.front());\n\t\t\tif (entryLayout != nextLayout)\n\t\t\t{\n\t\t\t\tsize_t bestNumJunk = getBestNumJunk(\n\t\t\t\t\tentryLayout,\n\t\t\t\t\tnextLayout\n\t\t\t\t);\n\t\t\t\tif (bestNumJunk > 0)\n\t\t\t\t{\n\t\t\t\t\taddJunkRecursive(_block, bestNumJunk);\n\t\t\t\t\tblockInfo.entryLayout = entryLayout;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tstd::visit(util::GenericVisitor{\n\t\t\t[&](CFG::BasicBlock::MainExit const&) {},\n\t\t\t[&](CFG::BasicBlock::Jump const& _jump)\n\t\t\t{\n\t\t\t\t_addChild(_jump.target);\n\t\t\t},\n\t\t\t[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump)\n\t\t\t{\n\t\t\t\t_addChild(_conditionalJump.zero);\n\t\t\t\t_addChild(_conditionalJump.nonZero);\n\t\t\t},\n\t\t\t[&](CFG::BasicBlock::FunctionReturn const&) {},\n\t\t\t[&](CFG::BasicBlock::Terminated const&) {},\n\t\t}, _block->exit);\n\t});\n}\n"
  },
  {
    "path": "libyul/backends/evm/StackLayoutGenerator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Stack layout generator for Yul to EVM code generation.\n */\n\n#pragma once\n\n#include <libyul/backends/evm/ControlFlowGraph.h>\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <map>\n\nnamespace solidity::yul\n{\n\nstruct StackLayout\n{\n\tstruct BlockInfo\n\t{\n\t\t/// Complete stack layout that is required for entering a block.\n\t\tStack entryLayout;\n\t\t/// The resulting stack layout after executing the block.\n\t\tStack exitLayout;\n\t};\n\tstd::map<CFG::BasicBlock const*, BlockInfo> blockInfos;\n\t/// For each operation the complete stack layout that:\n\t/// - has the slots required for the operation at the stack top.\n\t/// - will have the operation result in a layout that makes it easy to achieve the next desired layout.\n\tstd::map<CFG::Operation const*, Stack> operationEntryLayout;\n};\n\nclass StackLayoutGenerator\n{\npublic:\n\tstruct StackTooDeep\n\t{\n\t\t/// Number of slots that need to be saved.\n\t\tsize_t deficit = 0;\n\t\t/// Set of variables, eliminating which would decrease the stack deficit.\n\t\tstd::vector<YulName> variableChoices;\n\t};\n\n\tstatic StackLayout run(CFG const& _cfg, EVMDialect const& _evmDialect);\n\t/// @returns a map from function names to the stack too deep errors occurring in that function.\n\t/// Requires @a _cfg to be a control flow graph generated from disambiguated Yul.\n\t/// The empty string is mapped to the stack too deep errors of the main entry point.\n\tstatic std::map<YulName, std::vector<StackTooDeep>> reportStackTooDeep(\n\t\tCFG const& _cfg,\n\t\tEVMDialect const& _evmDialect\n\t);\n\t/// @returns all stack too deep errors in the function named @a _functionName.\n\t/// Requires @a _cfg to be a control flow graph generated from disambiguated Yul.\n\t/// If @a _functionName is empty, the stack too deep errors of the main entry point are reported instead.\n\tstatic std::vector<StackTooDeep> reportStackTooDeep(\n\t\tCFG const& _cfg,\n\t\tYulName _functionName,\n\t\tEVMDialect const& _evmDialect\n\t);\n\nprivate:\n\tStackLayoutGenerator(\n\t\tStackLayout& _context,\n\t\tCFG::FunctionInfo const* _functionInfo,\n\t\tEVMDialect const& _evmDialect\n\t);\n\n\t/// @returns the optimal entry stack layout, s.t. @a _operation can be applied to it and\n\t/// the result can be transformed to @a _exitStack with minimal stack shuffling.\n\t/// Simultaneously stores the entry layout required for executing the operation in m_layout.\n\tStack propagateStackThroughOperation(Stack _exitStack, CFG::Operation const& _operation, bool _aggressiveStackCompression = false);\n\n\t/// @returns the desired stack layout at the entry of @a _block, assuming the layout after\n\t/// executing the block should be @a _exitStack.\n\tStack propagateStackThroughBlock(Stack _exitStack, CFG::BasicBlock const& _block, bool _aggressiveStackCompression = false);\n\n\t/// Main algorithm walking the graph from entry to exit and propagating back the stack layouts to the entries.\n\t/// Iteratively reruns itself along backwards jumps until the layout is stabilized.\n\tvoid processEntryPoint(CFG::BasicBlock const& _entry, CFG::FunctionInfo const* _functionInfo = nullptr);\n\n\t/// @returns the best known exit layout of @a _block, if all dependencies are already @a _visited.\n\t/// If not, adds the dependencies to @a _dependencyList and @returns std::nullopt.\n\tstd::optional<Stack> getExitLayoutOrStageDependencies(\n\t\tCFG::BasicBlock const& _block,\n\t\tstd::set<CFG::BasicBlock const*> const& _visited,\n\t\tstd::list<CFG::BasicBlock const*>& _dependencyList\n\t) const;\n\n\t/// @returns a pair of ``{jumpingBlock, targetBlock}`` for each backwards jump in the graph starting at @a _entry.\n\tstd::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> collectBackwardsJumps(CFG::BasicBlock const& _entry) const;\n\n\t/// After the main algorithms, layouts at conditional jumps are merely compatible, i.e. the exit layout of the\n\t/// jumping block is a superset of the entry layout of the target block. This function modifies the entry layouts\n\t/// of conditional jump targets, s.t. the entry layout of target blocks match the exit layout of the jumping block\n\t/// exactly, except that slots not required after the jump are marked as `JunkSlot`s.\n\tvoid stitchConditionalJumps(CFG::BasicBlock const& _block);\n\n\t/// Calculates the ideal stack layout, s.t. both @a _stack1 and @a _stack2 can be achieved with minimal\n\t/// stack shuffling when starting from the returned layout.\n\tstatic Stack combineStack(Stack const& _stack1, Stack const& _stack2, size_t _reachableStackDepth);\n\n\t/// Walks through the CFG and reports any stack too deep errors that would occur when generating code for it\n\t/// without countermeasures.\n\tstd::vector<StackTooDeep> reportStackTooDeep(CFG::BasicBlock const& _entry) const;\n\n\t/// @returns a copy of @a _stack stripped of all duplicates and slots that can be freely generated.\n\t/// Attempts to create a layout that requires a minimal amount of operations to reconstruct the original\n\t/// stack @a _stack.\n\tstatic Stack compressStack(Stack _stack, size_t _reachableStackDepth);\n\n\t//// Fills in junk when entering branches that do not need a clean stack in case the result is cheaper.\n\tvoid fillInJunk(CFG::BasicBlock const& _block, CFG::FunctionInfo const* _functionInfo = nullptr);\n\n\t/// True if it simulates functions with jumps. False otherwise. True for legacy bytecode.\n\tbool simulateFunctionsWithJumps() const\n\t{\n\t\treturn !m_evmDialect.eofVersion().has_value();\n\t}\n\tsize_t reachableStackDepth() const\n\t{\n\t\treturn m_evmDialect.reachableStackDepth();\n\t}\n\n\tStackLayout& m_layout;\n\tCFG::FunctionInfo const* m_currentFunctionInfo = nullptr;\n\tEVMDialect const& m_evmDialect;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/VariableReferenceCounter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Counts the number of references to a variable.\n */\n#include <libyul/backends/evm/VariableReferenceCounter.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/AST.h>\n\n#include <libsolutil/Visitor.h>\n\nusing namespace solidity::yul;\n\nvoid VariableReferenceCounter::operator()(Identifier const& _identifier)\n{\n\tincreaseRefIfFound(_identifier.name);\n}\n\nvoid VariableReferenceCounter::operator()(FunctionDefinition const& _function)\n{\n\tScope* originalScope = m_scope;\n\n\tyulAssert(m_info.virtualBlocks.at(&_function), \"\");\n\tm_scope = m_info.scopes.at(m_info.virtualBlocks.at(&_function).get()).get();\n\tyulAssert(m_scope, \"Variable scope does not exist.\");\n\n\tfor (auto const& v: _function.returnVariables)\n\t\tincreaseRefIfFound(v.name);\n\n\t(*this)(_function.body);\n\n\tm_scope = originalScope;\n}\n\nvoid VariableReferenceCounter::operator()(ForLoop const& _forLoop)\n{\n\tScope* originalScope = m_scope;\n\t// Special scoping rules.\n\tm_scope = m_info.scopes.at(&_forLoop.pre).get();\n\n\twalkVector(_forLoop.pre.statements);\n\tvisit(*_forLoop.condition);\n\t(*this)(_forLoop.body);\n\t(*this)(_forLoop.post);\n\n\tm_scope = originalScope;\n}\n\nvoid VariableReferenceCounter::operator()(Block const& _block)\n{\n\tScope* originalScope = m_scope;\n\tm_scope = m_info.scopes.at(&_block).get();\n\n\tASTWalker::operator()(_block);\n\n\tm_scope = originalScope;\n}\n\nvoid VariableReferenceCounter::increaseRefIfFound(YulName _variableName)\n{\n\tm_scope->lookup(_variableName, util::GenericVisitor{\n\t\t[&](Scope::Variable const& _var)\n\t\t{\n\t\t\t++m_variableReferences[&_var];\n\t\t},\n\t\t[](Scope::Function const&) { }\n\t});\n}\n"
  },
  {
    "path": "libyul/backends/evm/VariableReferenceCounter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Counts the number of references to a variable.\n */\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/Scope.h>\n\nnamespace solidity::yul\n{\nstruct AsmAnalysisInfo;\n\n/**\n * Counts the number of references to a variable. This includes actual (read) references\n * but also assignments to the variable. It does not include the declaration itself or\n * function parameters, but it does include function return parameters.\n *\n * This component can handle multiple variables of the same name.\n *\n * Can only be applied to strict assembly.\n */\nstruct VariableReferenceCounter: public yul::ASTWalker\n{\npublic:\n\tstatic std::map<Scope::Variable const*, unsigned> run(AsmAnalysisInfo const& _assemblyInfo, Block const& _block)\n\t{\n\t\tVariableReferenceCounter variableReferenceCounter(_assemblyInfo);\n\t\tvariableReferenceCounter(_block);\n\t\treturn std::move(variableReferenceCounter.m_variableReferences);\n\t}\n\nprotected:\n\tvoid operator()(Block const& _block) override;\n\tvoid operator()(Identifier const& _identifier) override;\n\tvoid operator()(FunctionDefinition const&) override;\n\tvoid operator()(ForLoop const&) override;\n\nprivate:\n\texplicit VariableReferenceCounter(\n\t\tAsmAnalysisInfo const& _assemblyInfo\n\t): m_info(_assemblyInfo)\n\t{}\n\n\tvoid increaseRefIfFound(YulName _variableName);\n\n\tAsmAnalysisInfo const& m_info;\n\tScope* m_scope = nullptr;\n\tstd::map<Scope::Variable const*, unsigned> m_variableReferences;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/BridgeFinder.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/SSACFG.h>\n\n#include <range/v3/view/concat.hpp>\n\n#include <cstdint>\n#include <optional>\n#include <vector>\n\nnamespace solidity::yul::ssa\n{\n/// Detect bridges according to Algorithm 1 of https://arxiv.org/pdf/2108.07346.pdf.\n///\n/// A bridge in an undirected graph is an edge whose removal increases the number of connected components. In control\n/// flow analysis, bridge vertices are critical articulation points where removing the vertex would disconnect\n/// reachable code from unreachable code. This implementation adapts the bridge-finding algorithm to directed control\n/// flow graphs by treating them as undirected, then validating edge directionality to identify vertices that gate\n/// access to subsequent blocks.\n///\n/// We use bridges to determine blocks in which it is fine to introduce junk slots on the stack at any point in time.\nclass BridgeFinder\n{\npublic:\n\texplicit BridgeFinder(SSACFG const& _cfg):\n\t\tm_cfg(_cfg),\n\t\tm_bridgeVertex(_cfg.numBlocks()),\n\t\tm_visited(_cfg.numBlocks()),\n\t\tm_disc(_cfg.numBlocks()),\n\t\tm_low(_cfg.numBlocks())\n\t{\n\t\tsize_t time = 0;\n\t\tdfs(time, _cfg.entry, std::nullopt);\n\t}\n\n\tbool bridgeVertex(SSACFG::BlockId const& _blockId) const\n\t{\n\t\treturn m_bridgeVertex[_blockId.value];\n\t}\n\nprivate:\n\tvoid dfs(size_t& _time, SSACFG::BlockId const& _vertex, std::optional<SSACFG::BlockId> const& _parent)\n\t{\n\t\tm_visited[_vertex.value] = true;\n\t\tm_disc[_vertex.value] = _time;\n\t\tm_low[_vertex.value] = _time;\n\t\t++_time;\n\n\t\tauto const& currentBlock = m_cfg.block(_vertex);\n\t\tcurrentBlock.forEachExit([&](SSACFG::BlockId const& _exit)\n\t\t{\n\t\t\tprocessNeighbor(_exit, _time, _vertex, currentBlock.entries, _parent);\n\t\t});\n\n\t\tfor (SSACFG::BlockId const neighbor: currentBlock.entries)\n\t\t\tprocessNeighbor(neighbor, _time, _vertex, currentBlock.entries, _parent);\n\t}\n\n\tvoid processNeighbor(\n\t\tSSACFG::BlockId const& _neighbor,\n\t\tsize_t& _time,\n\t\tSSACFG::BlockId const& _vertex,\n\t\tstd::set<SSACFG::BlockId> const& _vertexEntries,\n\t\tstd::optional<SSACFG::BlockId> const& _parent\n\t)\n\t{\n\t\tif (_neighbor == _parent)\n\t\t\treturn;\n\n\t\tif (!m_visited[_neighbor.value])\n\t\t{\n\t\t\tdfs(_time, _neighbor, _vertex);\n\t\t\tm_low[_vertex.value] = std::min(m_low[_vertex.value], m_low[_neighbor.value]);\n\t\t\tif (m_low[_neighbor.value] > m_disc[_vertex.value])\n\t\t\t{\n\t\t\t\t// vertex <-> neighbor is a bridge in the undirected graph\n\t\t\t\tbool const edgeNeighborToVertex = _vertexEntries.contains(_neighbor);\n\t\t\t\tbool const edgeVertexToNeighbor = m_cfg.block(_neighbor).entries.contains(_vertex);\n\n\t\t\t\t// special case: if it's the entry itself, we mark it as bridge vertex (provided correct orientation),\n\t\t\t\t// so that functions which do nothing but revert have their whole tree marked as such (sans loops)\n\t\t\t\tif (!_parent)\n\t\t\t\t\tm_bridgeVertex[_vertex.value] = edgeVertexToNeighbor;\n\t\t\t\t// Since we are not really undirected, check if we don't have a cycle (u -> v and v -> u) and see,\n\t\t\t\t// which edge really exists here.\n\t\t\t\t// Then record the targeted vertex as bridge vertex.\n\t\t\t\tif (edgeVertexToNeighbor && !edgeNeighborToVertex)\n\t\t\t\t\t// bridge vertex -> neighbor\n\t\t\t\t\tm_bridgeVertex[_neighbor.value] = true;\n\t\t\t\telse if (edgeNeighborToVertex && !edgeVertexToNeighbor)\n\t\t\t\t\t// bridge neighbor -> vertex\n\t\t\t\t\tm_bridgeVertex[_vertex.value] = true;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tm_low[_vertex.value] = std::min(m_low[_vertex.value], m_disc[_neighbor.value]);\n\t}\n\n\tSSACFG const& m_cfg;\n\t// determines whether a vertex is a bridge vertex. optimizing for performance over space with u8.\n\tstd::vector<std::uint8_t> m_bridgeVertex;\n\t// determines whether a vertex is visited. optimizing for performance over space with u8.\n\tstd::vector<std::uint8_t> m_visited;\n\t// vertex discovery time\n\tstd::vector<std::size_t> m_disc;\n\t// minimum discovery time of subtree - if m_low[child] > m_low[parent], we have a bridge\n\tstd::vector<std::size_t> m_low;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/CodeTransform.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/CodeTransform.h>\n\n#include <libyul/backends/evm/ssa/StackLayoutGenerator.h>\n#include <libyul/backends/evm/ssa/StackShuffler.h>\n#include <libyul/backends/evm/ssa/StackUtils.h>\n\n#include <libyul/backends/evm/EVMBuiltins.h>\n\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/view/take_last.hpp>\n#include <range/v3/view/zip.hpp>\n\nusing namespace solidity::yul;\nusing namespace solidity::yul::ssa;\n\nnamespace\n{\nvoid assertLayoutCompatibility(StackData const& _layout1, StackData const& _layout2)\n{\n\tauto const compatibility = checkLayoutCompatibility(_layout1, _layout2);\n\tyulAssert(compatibility.ok(), compatibility.formatErrors());\n}\n}\n\nvoid CodeTransform::run\n(\n\tAbstractAssembly& _assembly,\n\tControlFlowLiveness const& _controlFlowLiveness,\n\tBuiltinContext& _builtinContext\n)\n{\n\tyulAssert(!_controlFlowLiveness.cfgLiveness.empty());\n\tControlFlow const& controlFlow = _controlFlowLiveness.controlFlow.get();\n\tyulAssert(controlFlow.functionGraphs.size() == _controlFlowLiveness.cfgLiveness.size());\n\tFunctionLabels const functionLabels = registerFunctionLabels(_assembly, controlFlow);\n\n\tfor (std::size_t functionIndex = 0; functionIndex < controlFlow.functionGraphMapping.size(); ++functionIndex)\n\t{\n\t\tauto const& [function, cfg] = controlFlow.functionGraphMapping[functionIndex];\n\t\tyulAssert(cfg);\n\t\tauto const callSites = gatherCallSites(*cfg);\n\t\tauto const& liveness = _controlFlowLiveness.cfgLiveness[functionIndex];\n\t\tyulAssert(liveness);\n\t\tauto const graphID = static_cast<ControlFlow::FunctionGraphID>(functionIndex);\n\t\tauto const& stackLayout = StackLayoutGenerator::generate(*liveness, callSites, graphID);\n\t\tCodeTransform transform(\n\t\t\t_assembly,\n\t\t\t_builtinContext,\n\t\t\tfunctionLabels,\n\t\t\tcallSites,\n\t\t\t*cfg,\n\t\t\tstackLayout,\n\t\t\tfunction,\n\t\t\tgraphID\n\t\t);\n\t\ttransform(cfg->entry);\n\t}\n}\n\nCodeTransform::FunctionLabels CodeTransform::registerFunctionLabels(\n\tAbstractAssembly& _assembly, ControlFlow const& _controlFlow)\n{\n\tFunctionLabels functionLabels;\n\tstd::set<YulString> assignedFunctionNames;\n\n\tfor (auto const& [_function, _functionGraph]: _controlFlow.functionGraphMapping)\n\t{\n\t\tif (!_function)\n\t\t\tcontinue;\n\t\tbool nameAlreadySeen = !assignedFunctionNames.insert(_function->name).second;\n\t\tfunctionLabels[_function] = !nameAlreadySeen ?\n\t\t\t_assembly.namedLabel(\n\t\t\t\t_function->name.str(),\n\t\t\t\t_functionGraph->arguments.size(),\n\t\t\t\t_functionGraph->returns.size(),\n\t\t\t\t_functionGraph->debugData ? _functionGraph->debugData->astID : std::nullopt\n\t\t\t) :\n\t\t\t_assembly.newLabelId();\n\t}\n\treturn functionLabels;\n}\n\nCodeTransform::CodeTransform(\n\tAbstractAssembly& _assembly,\n\tBuiltinContext& _builtinContext,\n\tFunctionLabels const& _functionLabels,\n\tCallSites const& _callSites,\n\tSSACFG const& _cfg,\n\tSSACFGStackLayout const& _stackLayout,\n\tScope::Function const* _function,\n\tControlFlow::FunctionGraphID _graphID\n):\n\tm_assembly(_assembly),\n\tm_builtinContext(_builtinContext),\n\tm_functionLabels(_functionLabels),\n\tm_callSites(_callSites),\n\tm_cfg(_cfg),\n\tm_stackLayout(_stackLayout),\n\tm_graphID(_graphID),\n\tm_blockIsTransformed(_cfg.numBlocks(), false),\n\tm_blockLabels([this] {\n\t\tstd::vector<AbstractAssembly::LabelID> blockLabels;\n\t\tblockLabels.reserve(m_cfg.numBlocks());\n\t\tfor (std::size_t i = 0; i < m_cfg.numBlocks(); ++i)\n\t\t\tblockLabels.push_back(m_assembly.newLabelId());\n\t\treturn blockLabels;\n\t}()),\n\tm_assemblyCallbacks{\n\t\t.cfg = &_cfg,\n\t\t.assembly = &_assembly,\n\t\t.callSites = &_callSites,\n\t\t.returnLabels = &m_returnLabels\n\t},\n\tm_stackData([&]\n\t{\n\t\tauto const& entryLayout = m_stackLayout[m_cfg.entry];\n\t\tyulAssert(entryLayout);\n\t\treturn entryLayout->stackIn;\n\t}()),\n\tm_stack(m_stackData, m_assemblyCallbacks)\n{\n\tif (_function)\n\t{\n\t\tauto const findIt = m_functionLabels.find(_function);\n\t\tyulAssert(findIt != m_functionLabels.end());\n\t\tm_assembly.appendLabel(findIt->second);\n\t\tm_assembly.setStackHeight(static_cast<int>(_function->numArguments) + (m_cfg.canContinue ? 1 : 0));\n\t}\n\tStackData expectedStackTop;\n\texpectedStackTop.reserve(m_cfg.arguments.size() + (m_cfg.function && m_cfg.canContinue ? 1 : 0));\n\t\tif (m_cfg.function && m_cfg.canContinue)\n\t\t\texpectedStackTop.push_back(StackSlot::makeFunctionReturnLabel(m_graphID));\n\tfor (auto const& [_, valueID]: m_cfg.arguments | ranges::views::reverse)\n\t\texpectedStackTop.push_back(StackSlot::makeValueID(valueID));\n\tassertLayoutCompatibility(m_stack.data(), expectedStackTop);\n}\n\nvoid CodeTransform::operator()(SSACFG::BlockId const _blockId)\n{\n\tyulAssert(!m_blockIsTransformed[_blockId.value], \"Each block is transformed exactly once.\");\n\tm_blockIsTransformed[_blockId.value] = true;\n\n\tm_assembly.appendLabel(m_blockLabels[_blockId.value]);\n\n\tauto const& blockLayout = m_stackLayout[_blockId];\n\tyulAssert(blockLayout);\n\tassertLayoutCompatibility(m_stack.data(), blockLayout->stackIn);\n\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight());\n\n\tauto const& block = m_cfg.block(_blockId);\n\tyulAssert(block.operations.size() == blockLayout->operationIn.size(), \"We need as many operation stack layouts as we have operations\");\n\n\tfor (std::size_t operationIndex = 0; operationIndex < block.operations.size(); ++operationIndex)\n\t{\n\t\tSSACFG::Operation const& operation = block.operations[operationIndex];\n\t\tauto const& operationInLayout = blockLayout->operationIn[operationIndex];\n\n\t\t// perform the operation\n\t\t(*this)(operation, operationInLayout);\n\t}\n\n\t// Shuffle to the block's exit layout before dispatching the exit.\n\t// This ensures the condition is on top for ConditionalJump, phi pre-images are\n\t// in the right positions for jumps, and return values are accessible for FunctionReturn.\n\tStackShuffler<AssemblyCallbacks>::shuffle(m_stack, blockLayout->stackOut);\n\n\t// handle the block exit\n\tstd::visit(util::GenericVisitor{ [this, &_blockId](auto const& exit) { (*this)(_blockId, exit); } }, block.exit);\n}\n\nvoid CodeTransform::operator()(SSACFG::Operation const& _operation, StackData const& _operationInputLayout)\n{\n\tbool const hasReturnLabel =\n\t\t\tstd::holds_alternative<SSACFG::Call>(_operation.kind) &&\n\t\t\tstd::get<SSACFG::Call>(_operation.kind).canContinue;\n\n\tif (hasReturnLabel)\n\t{\n\t\tauto const [it, inserted] = m_returnLabels.try_emplace(&std::get<SSACFG::Call>(_operation.kind).call.get(), 0);\n\t\tyulAssert(inserted, \"Call sites should be unique.\");\n\t\tit->second = m_assembly.newLabelId();\n\t}\n\n\t// check that the assembly stack height corresponds to the stack size before shuffling\n\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight());\n\n\t// prepare stack for operation\n\tStackShuffler<AssemblyCallbacks>::shuffle(m_stack, _operationInputLayout);\n\n\t// check that the assembly stack height corresponds to the stack size after shuffling\n\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight());\n\n\t// check that the stack is compatible with the operation input layout\n\tassertLayoutCompatibility(m_stack.data(), _operationInputLayout);\n\n\t// Assert that we have the inputs of the operation on stack top.\n\tyulAssert(m_stack.size() >= _operation.inputs.size());\n\tfor (auto const& [stackEntry, input]: ranges::views::zip(\n\t\tm_stack | ranges::views::take_last(_operation.inputs.size()),\n\t\t_operation.inputs\n\t))\n\t\tyulAssert(stackEntry.isValueID() && stackEntry.valueID() == input);\n\n\t// if the function can continue (doesn't always abort), make sure we have the correct return label slot in place\n\tif (hasReturnLabel)\n\t{\n\t\tyulAssert(m_stack.size() > _operation.inputs.size());\n\t\tauto const returnLabelSlot = m_stack.slot(StackDepth{_operation.inputs.size()});\n\t\tyulAssert(std::holds_alternative<SSACFG::Call>(_operation.kind));\n\t\tyulAssert(\n\t\t\treturnLabelSlot.isFunctionCallReturnLabel() &&\n\t\t\t&m_callSites.functionCall(returnLabelSlot.functionCallReturnLabel()) == &std::get<SSACFG::Call>(_operation.kind).call.get()\n\t\t);\n\t}\n\n\t// height of the stack sans function return label and operation inputs\n\tstd::size_t const baseHeight = m_stack.size() - _operation.inputs.size() - (hasReturnLabel ? 1 : 0);\n\n\t// generate code for the operation\n\tstd::visit(util::GenericVisitor{\n\t\t[&](SSACFG::BuiltinCall const& _builtin) {\n\t\t\tm_assembly.setSourceLocation(originLocationOf(_builtin));\n\t\t\tstatic_cast<BuiltinFunctionForEVM const&>(_builtin.builtin.get()).generateCode(\n\t\t\t\t_builtin.call,\n\t\t\t\tm_assembly,\n\t\t\t\tm_builtinContext\n\t\t\t);\n\t\t},\n\t\t[&](SSACFG::Call const& _call) {\n\t\t\tauto const* returnLabel = util::valueOrNullptr(m_returnLabels, &_call.call.get());\n\t\t\t// check that if we have a return label, the call can continue\n\t\t\tyulAssert(!!returnLabel == _call.canContinue);\n\t\t\tm_assembly.setSourceLocation(originLocationOf(_call));\n\t\t\tm_assembly.appendJumpTo(\n\t\t\t\tm_functionLabels.at(&_call.function.get()),\n\t\t\t\tstatic_cast<int>(_call.function.get().numReturns - _call.function.get().numArguments) - (_call.canContinue ? 1 : 0),\n\t\t\t\tAbstractAssembly::JumpType::IntoFunction\n\t\t\t);\n\t\t\t// if we have a return label, append it to assembly and pop the label from the stack\n\t\t\t// it might also be one of the inputs that is popped here but then the label will be popped below with\n\t\t\t// the other inputs\n\t\t\tif (returnLabel)\n\t\t\t{\n\t\t\t\tm_assembly.appendLabel(*returnLabel);\n\t\t\t\tm_stack.pop<false>();\n\t\t\t}\n\t\t},\n\t\t[&](SSACFG::LiteralAssignment const&){}\n\t}, _operation.kind);\n\t// simulate that the inputs are consumed\n\tfor (size_t i = 0; i < _operation.inputs.size(); ++i)\n\t\tm_stack.pop<false>();\n\t// simulate that the outputs are produced\n\tfor (auto value: _operation.outputs)\n\t\tm_stack.push<false>(StackSlot::makeValueID(value));\n\n\t// Assert that the operation produced its proclaimed output.\n\tyulAssert(m_stack.size() == baseHeight + _operation.outputs.size());\n\tfor (auto const& [stackEntry, output]: ranges::views::zip(\n\t\tm_stack.data() | ranges::views::take_last(_operation.outputs.size()),\n\t\t_operation.outputs\n\t))\n\t\tyulAssert(stackEntry.isValueID() && stackEntry.valueID() == output);\n\tyulAssert(\n\t\tstatic_cast<int>(m_stack.size()) == m_assembly.stackHeight(),\n\t\tfmt::format(\"symbolic stack size = {} =/= {} = assembly stack height\", m_stack.size(), m_assembly.stackHeight())\n\t);\n}\n\nvoid CodeTransform::operator()(SSACFG::BlockId const&, SSACFG::BasicBlock::MainExit const&)\n{\n\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight());\n\tm_assembly.appendInstruction(evmasm::Instruction::STOP);\n}\n\nvoid CodeTransform::operator()(SSACFG::BlockId const& _currentBlock, SSACFG::BasicBlock::ConditionalJump const& _conditionalJump)\n{\n\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight());\n\t// condition must be at the top of the stack\n\tyulAssert(m_stack.top().isValueID() && m_stack.top().valueID() == _conditionalJump.condition);\n\t// emit JUMPI to nonZero block\n\tm_assembly.appendJumpToIf(m_blockLabels[_conditionalJump.nonZero.value]);\n\t// update symbolic stack by popping the condition as it'll be consumed by JUMPI\n\tm_stack.pop<false>();\n\n\t{\n\t\t// restore stack to previous state once zero-path is handled\n\t\tScopedSaveAndRestore restoreStack(m_stackData, StackData(m_stackData));\n\t\tyulAssert(m_stackLayout[_conditionalJump.zero]);\n\n\t\t// transform stack to a state in which we can jump to the zero branch\n\t\tprepareBlockExitStack(\n\t\t\tm_stackLayout[_conditionalJump.zero]->stackIn,\n\t\t\tPhiInverse(m_cfg, _currentBlock, _conditionalJump.zero)\n\t\t);\n\t\tassertLayoutCompatibility(m_stack.data(), m_stackLayout[_conditionalJump.zero]->stackIn);\n\t\tm_assembly.appendJumpTo(m_blockLabels[_conditionalJump.zero.value]);\n\n\t\tif (!m_blockIsTransformed[_conditionalJump.zero.value])\n\t\t\t(*this)(_conditionalJump.zero);\n\t}\n\t{\n\t\tyulAssert(m_stackLayout[_conditionalJump.nonZero]);\n\t\tassertLayoutCompatibility(m_stack.data(), m_stackLayout[_conditionalJump.nonZero]->stackIn);\n\n\t\tm_assembly.setStackHeight(static_cast<int>(m_stack.size()));\n\t\tif (!m_blockIsTransformed[_conditionalJump.nonZero.value])\n\t\t\t(*this)(_conditionalJump.nonZero);\n\t}\n}\n\nvoid CodeTransform::operator()(SSACFG::BlockId const& _currentBlock, SSACFG::BasicBlock::Jump const& _jump)\n{\n\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight());\n\tyulAssert(m_stackLayout[_jump.target]);\n\tprepareBlockExitStack(m_stackLayout[_jump.target]->stackIn, PhiInverse(m_cfg, _currentBlock, _jump.target));\n\tassertLayoutCompatibility(m_stack.data(), m_stackLayout[_jump.target]->stackIn);\n\tm_assembly.appendJumpTo(m_blockLabels[_jump.target.value]);\n\tif (!m_blockIsTransformed[_jump.target.value])\n\t\t(*this)(_jump.target);\n}\n\nvoid CodeTransform::operator()(SSACFG::BlockId const&, SSACFG::BasicBlock::FunctionReturn const& _functionReturn)\n{\n\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight());\n\t// Each CodeTransform instance handles exactly one function's CFG, so a FunctionReturn exit\n\t// here necessarily belongs to m_cfg.function. No identity cross-check is needed.\n\tyulAssert(m_cfg.function);\n\tyulAssert(m_cfg.canContinue);\n\tyulAssert(m_stack.size() == _functionReturn.returnValues.size() + 1, \"There must be at least the function return label element on stack\");\n\tyulAssert(m_stack.top().isFunctionReturnLabel());\n\tyulAssert(m_stack.top().functionReturnLabel() == m_graphID);\n\tfor (std::size_t i = 0; i < _functionReturn.returnValues.size(); ++i)\n\t{\n\t\tauto const& returnValueSlot = m_stack.slot(StackOffset{i});\n\t\tyulAssert(returnValueSlot.isValueID());\n\t\tyulAssert(returnValueSlot.valueID() == _functionReturn.returnValues[i]);\n\t}\n\tm_assembly.appendJump(0, AbstractAssembly::JumpType::OutOfFunction);\n}\n\nvoid CodeTransform::operator()(SSACFG::BlockId const& _blockId, SSACFG::BasicBlock::Terminated const&)\n{\n\tyulAssert(static_cast<int>(m_stack.size()) == m_assembly.stackHeight());\n\tauto const& block = m_cfg.block(_blockId);\n\tyulAssert(!block.operations.empty(), \"Terminated block must have at least one operation.\");\n\tstd::visit(util::GenericVisitor{\n\t\t[](SSACFG::BuiltinCall const& _builtin) {\n\t\t\tyulAssert(_builtin.builtin.get().controlFlowSideEffects.terminatesOrReverts(), \"Last operation of Terminated block must terminate or revert.\");\n\t\t},\n\t\t[](SSACFG::Call const& _call) {\n\t\t\tyulAssert(!_call.canContinue, \"Last operation of Terminated block must be a non-continuable call.\");\n\t\t},\n\t\t[](SSACFG::LiteralAssignment const&) {\n\t\t\tyulAssert(false, \"Terminated block cannot end with a literal assignment.\");\n\t\t}\n\t}, block.operations.back().kind);\n\t// To be sure just emit another INVALID - should be removed by optimizer.\n\tm_assembly.appendInstruction(evmasm::Instruction::INVALID);\n}\n\nvoid CodeTransform::prepareBlockExitStack(StackData const& _target, PhiInverse const& _phiInverse)\n{\n\t// pull back target to live in current variable space\n\tauto const pulledBackTarget = stackPreImage(_target, _phiInverse);\n\t// shuffle to target\n\tStackShuffler<AssemblyCallbacks>::shuffle(m_stack, pulledBackTarget);\n\t// check that shuffling was successful\n\tassertLayoutCompatibility(m_stack.data(), pulledBackTarget);\n\t// now we can simply set the target to the actual one which will take care of the application of phi functions\n\tm_stackData = _target;\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/CodeTransform.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/PhiInverse.h>\n#include <libyul/backends/evm/ssa/Stack.h>\n#include <libyul/backends/evm/ssa/StackLayout.h>\n\n#include <libyul/backends/evm/AbstractAssembly.h>\n\n#include <libevmasm/Instruction.h>\n\nnamespace solidity::yul\n{\nstruct BuiltinContext;\n}\nnamespace solidity::yul::ssa\n{\n\nstruct AssemblyCallbacks\n{\n\tvoid swap(StackDepth const _depth)\n\t{\n\t\tassembly->appendInstruction(evmasm::swapInstruction(static_cast<unsigned>(_depth.value)));\n\t}\n\n\tvoid pop()\n\t{\n\t\tassembly->appendInstruction(evmasm::Instruction::POP);\n\t}\n\n\tvoid push(StackSlot const& _slot)\n\t{\n\t\tswitch (_slot.kind())\n\t\t{\n\t\tcase StackSlot::Kind::ValueID:\n\t\t{\n\t\t\tauto const id = _slot.valueID();\n\t\t\tyulAssert(id.isLiteral(), fmt::format(\"Tried bringing up v{}\", id.value()));\n\t\t\tassembly->appendConstant(cfg->literalInfo(id).value);\n\t\t\treturn;\n\t\t}\n\t\tcase StackSlot::Kind::Junk:\n\t\t{\n\t\t\tif (assembly->evmVersion().hasPush0())\n\t\t\t\tassembly->appendConstant(0);\n\t\t\telse\n\t\t\t\tassembly->appendInstruction(evmasm::Instruction::CODESIZE);\n\t\t\treturn;\n\t\t}\n\t\tcase StackSlot::Kind::FunctionCallReturnLabel:\n\t\t{\n\t\t\tauto const& call = callSites->functionCall(_slot.functionCallReturnLabel());\n\t\t\tyulAssert(returnLabels->count(&call), \"FunctionCallReturnLabel not pre-registered before shuffle.\");\n\t\t\tassembly->appendLabelReference(returnLabels->at(&call));\n\t\t\treturn;\n\t\t}\n\t\tcase StackSlot::Kind::FunctionReturnLabel:\n\t\t{\n\t\t\tyulAssert(false, \"Cannot produce function return label.\");\n\t\t}\n\t\t}\n\t}\n\n\tvoid dup(StackDepth const _depth)\n\t{\n\t\tassembly->appendInstruction(evmasm::dupInstruction(static_cast<unsigned>(_depth.value)));\n\t}\n\n\tSSACFG const* cfg{};\n\tAbstractAssembly* assembly{};\n\tCallSites const* callSites{};\n\tstd::map<FunctionCall const*, AbstractAssembly::LabelID> const* returnLabels{};\n};\nstatic_assert(StackManipulationCallbackConcept<AssemblyCallbacks>);\n\nclass CodeTransform\n{\npublic:\n\tstatic void run(\n\t\tAbstractAssembly& _assembly,\n\t\tControlFlowLiveness const& _liveness,\n\t\tBuiltinContext& _builtinContext\n\t);\n\nprivate:\n\tusing FunctionLabels = std::map<Scope::Function const*, AbstractAssembly::LabelID>;\n\n\tstatic FunctionLabels registerFunctionLabels(\n\t\tAbstractAssembly& _assembly,\n\t\tControlFlow const& _controlFlow\n\t);\n\n\tCodeTransform(\n\t\tAbstractAssembly& _assembly,\n\t\tBuiltinContext& _builtinContext,\n\t\tFunctionLabels const& _functionLabels,\n\t\tCallSites const& _callSites,\n\t\tSSACFG const& _cfg,\n\t\tSSACFGStackLayout const& _stackLayout,\n\t\tScope::Function const* _function,\n\t\tControlFlow::FunctionGraphID _graphID);\n\n\tvoid operator()(SSACFG::BlockId _blockId);\n\tvoid operator()(SSACFG::Operation const& _operation, StackData const& _operationInputLayout);\n\tvoid operator()(SSACFG::BlockId const& _currentBlock, SSACFG::BasicBlock::MainExit const& _mainExit);\n\tvoid operator()(SSACFG::BlockId const& _currentBlock, SSACFG::BasicBlock::ConditionalJump const& _conditionalJump);\n\tvoid operator()(SSACFG::BlockId const& _currentBlock, SSACFG::BasicBlock::Jump const& _jump);\n\tvoid operator()(SSACFG::BlockId const& _currentBlock, SSACFG::BasicBlock::FunctionReturn const& _functionReturn);\n\tvoid operator()(SSACFG::BlockId const& _currentBlock, SSACFG::BasicBlock::Terminated const& _terminated);\n\n\tvoid prepareBlockExitStack(StackData const& _target, PhiInverse const& _phiInverse);\n\n\tAbstractAssembly& m_assembly;\n\tBuiltinContext& m_builtinContext;\n\tFunctionLabels const& m_functionLabels;\n\tCallSites const& m_callSites;\n\tSSACFG const& m_cfg;\n\tSSACFGStackLayout const& m_stackLayout;\n\tControlFlow::FunctionGraphID const m_graphID;\n\n\tstd::vector<std::uint8_t> m_blockIsTransformed;\n\tstd::vector<AbstractAssembly::LabelID> m_blockLabels;\n\tAssemblyCallbacks m_assemblyCallbacks;\n\tStackData m_stackData;\n\tStack<AssemblyCallbacks> m_stack;\n\tstd::map<FunctionCall const*, AbstractAssembly::LabelID> m_returnLabels;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/ControlFlow.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/ControlFlow.h>\n\n#include <range/v3/range/conversion.hpp>\n\nusing namespace solidity::yul::ssa;\n\nControlFlowLiveness::ControlFlowLiveness(ControlFlow const& _controlFlow):\n\tcontrolFlow(_controlFlow),\n\tcfgLiveness(_controlFlow.functionGraphs | ranges::views::transform([](auto const& _cfg) { return std::make_unique<LivenessAnalysis>(*_cfg); }) | ranges::to<std::vector>)\n{ }\n\nstd::string ControlFlowLiveness::toDot() const\n{\n\treturn controlFlow.get().toDot(this);\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/ControlFlow.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/LivenessAnalysis.h>\n#include <libyul/backends/evm/ssa/SSACFG.h>\n\n#include <libyul/AST.h>\n#include <libyul/Scope.h>\n\n#include <range/v3/algorithm/find_if.hpp>\n\nnamespace solidity::yul::ssa\n{\n\nstruct ControlFlow;\n\nstruct ControlFlowLiveness{\n\texplicit ControlFlowLiveness(ControlFlow const& _controlFlow);\n\n\tstd::reference_wrapper<ControlFlow const> controlFlow;\n\tstd::vector<std::unique_ptr<LivenessAnalysis>> cfgLiveness;\n\n\tstd::string toDot() const;\n};\n\nstruct ControlFlow\n{\n\tusing FunctionGraphID = std::uint32_t;\n\n\tstatic FunctionGraphID constexpr mainGraphID() noexcept { return 0; }\n\n\tSSACFG const* mainGraph() const { return functionGraph(mainGraphID()); }\n\n\tSSACFG const* functionGraph(Scope::Function const* _function) const\n\t{\n\t\tauto it = ranges::find_if(functionGraphMapping, [_function](auto const& tup) { return _function == std::get<0>(tup); });\n\t\tif (it != functionGraphMapping.end())\n\t\t\treturn std::get<1>(*it);\n\t\treturn nullptr;\n\t}\n\n\tSSACFG const* functionGraph(FunctionGraphID const _id) const\n\t{\n\t\treturn functionGraphs.at(_id).get();\n\t}\n\n\tstd::string toDot(ControlFlowLiveness const* _liveness=nullptr) const\n\t{\n\t\tif (_liveness)\n\t\t\tyulAssert(&_liveness->controlFlow.get() == this);\n\t\tstd::ostringstream output;\n\t\toutput << \"digraph SSACFG {\\nnodesep=0.7;\\ngraph[fontname=\\\"DejaVu Sans\\\"]\\nnode[shape=box,fontname=\\\"DejaVu Sans\\\"];\\n\\n\";\n\n\t\tfor (size_t index=0; index < functionGraphs.size(); ++index)\n\t\t\toutput << functionGraphs[index]->toDot(\n\t\t\t\tfalse,\n\t\t\t\tindex,\n\t\t\t\t_liveness ? _liveness->cfgLiveness[index].get() : nullptr\n\t\t\t);\n\n\t\toutput << \"}\\n\";\n\t\treturn output.str();\n\t}\n\n\tstd::vector<std::unique_ptr<SSACFG>> functionGraphs{};\n\tstd::vector<std::tuple<Scope::Function const*, SSACFG const*>> functionGraphMapping{};\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/JunkAdmittingBlocksFinder.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/JunkAdmittingBlocksFinder.h>\n\n#include <libyul/backends/evm/ssa/BridgeFinder.h>\n\nnamespace solidity::yul::ssa\n{\n\nJunkAdmittingBlocksFinder::JunkAdmittingBlocksFinder(SSACFG const& _cfg, traversal::ForwardTopologicalSort const& _topologicalSort):\n\tm_blockAllowsJunk(_cfg.numBlocks(), false)\n{\n\t// special case: only one block here, we mark it as junkable in case it's not a function return\n\tif (_topologicalSort.preOrder().size() == 1)\n\t{\n\t\tSSACFG::BlockId const id {_topologicalSort.preOrder().front()};\n\t\tm_blockAllowsJunk[id.value] = !_cfg.block(id).isFunctionReturnBlock();\n\t\treturn;\n\t}\n\n\t// Find all bridges, i.e., vertices, which upon removal increase the number of connected components.\n\t// Translated to SSA CFGs this means:\n\t//   - control flow that enters a bridge vertex never returns to a previously visited block\n\t//   - there is no parallel path to a child of the vertex, ie, adding junk is fine in terms of stack balance\n\tBridgeFinder const bridgeFinder(_cfg);\n\n\t// of the bridge vertices, we have the exclude the ones that can lead to a function return\n\tstd::vector<SSACFG::BlockId> toVisit;\n\tfor (auto const blockIndex: _topologicalSort.preOrder())\n\t{\n\t\tSSACFG::BlockId const blockId {blockIndex};\n\t\tm_blockAllowsJunk[blockIndex] = bridgeFinder.bridgeVertex(blockId) || _cfg.block(blockId).isTerminationBlock();\n\t\tif (_cfg.block(blockId).isFunctionReturnBlock())\n\t\t\ttoVisit.emplace_back(SSACFG::BlockId{blockIndex});\n\t}\n\n\tstd::vector<uint8_t> visited(_cfg.numBlocks(), false);\n\twhile (!toVisit.empty())\n\t{\n\t\tauto const blockId = toVisit.back();\n\t\tauto const& block = _cfg.block(blockId);\n\t\ttoVisit.pop_back();\n\n\t\tm_blockAllowsJunk[blockId.value] = false;\n\t\tvisited[blockId.value] = true;\n\t\tfor (auto const& entry: block.entries)\n\t\t\tif (!visited[entry.value])\n\t\t\t\ttoVisit.emplace_back(entry);\n\t}\n}\n\nbool JunkAdmittingBlocksFinder::allowsAdditionOfJunk(SSACFG::BlockId const& _blockId) const\n{\n\treturn m_blockAllowsJunk[_blockId.value];\n}\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/JunkAdmittingBlocksFinder.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/traversal/ForwardTopologicalSort.h>\n#include <libyul/backends/evm/ssa/SSACFG.h>\n\n#include <cstdint>\n#include <vector>\n\nnamespace solidity::yul::ssa\n{\n\n/// Identifies blocks where stack balance constraints can be relaxed.\n/// These are blocks that inevitably terminate down the line (i.e., there is no path to a function return exit) and\n/// which are \"bridge vertices\". For a bridge, the graph decomposes into `G1` and `G2` with a singular edge `e=(v1->v2)`\n/// between them. Therefore, traversal into `G2` cannot escape back into `G1` and in particular there cannot be a\n/// parallel path into G2 that has relaxed constraints with respect to introducing junk. Consequently, there cannot be\n/// a situation in which a junk-bloated stack has to be unified with a slimmer stack layout stemming from another path\n/// into `G2`.\nclass JunkAdmittingBlocksFinder\n{\npublic:\n\texplicit JunkAdmittingBlocksFinder(SSACFG const& _cfg, traversal::ForwardTopologicalSort const& _topologicalSort);\n\tbool allowsAdditionOfJunk(SSACFG::BlockId const& _blockId) const;\nprivate:\n\tstd::vector<std::uint8_t> m_blockAllowsJunk;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/LivenessAnalysis.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/LivenessAnalysis.h>\n\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/algorithm/find.hpp>\n#include <range/v3/algorithm/find_if.hpp>\n#include <range/v3/range/conversion.hpp>\n\n#include <range/v3/view/filter.hpp>\n#include <range/v3/view/reverse.hpp>\n\nusing namespace solidity::yul::ssa;\n\nnamespace\n{\nconstexpr auto excludingLiteralsFilter()\n{\n\treturn [](LivenessAnalysis::LivenessData::Value const& _valueId) -> bool\n\t{\n\t\treturn !_valueId.isLiteral();\n\t};\n}\n}\n\nbool LivenessAnalysis::LivenessData::contains(Value const& _valueId) const\n{\n\treturn findEntry(_valueId) != m_liveCounts.end();\n}\n\nLivenessAnalysis::LivenessData::Count LivenessAnalysis::LivenessData::count(Value const& _valueId) const\n{\n\tif (\n\t\tauto const it = findEntry(_valueId);\n\t\tit != m_liveCounts.end()\n\t)\n\t\treturn it->second;\n\treturn 0;\n}\n\nLivenessAnalysis::LivenessData::LiveCounts::const_iterator LivenessAnalysis::LivenessData::begin() const\n{\n\treturn m_liveCounts.begin();\n}\n\nLivenessAnalysis::LivenessData::LiveCounts::const_iterator LivenessAnalysis::LivenessData::end() const\n{\n\treturn m_liveCounts.end();\n}\n\nLivenessAnalysis::LivenessData::LiveCounts::size_type LivenessAnalysis::LivenessData::size() const\n{\n\treturn m_liveCounts.size();\n}\n\nbool LivenessAnalysis::LivenessData::empty() const { return m_liveCounts.empty(); }\n\nvoid LivenessAnalysis::LivenessData::insert(Value const& _value, Count _count)\n{\n\tif (_count == 0)\n\t\treturn;\n\n\tauto it = findEntry(_value);\n\tif (it != m_liveCounts.end())\n\t\tit->second += _count;\n\telse\n\t\tm_liveCounts.emplace_back(_value, _count);\n}\n\nLivenessAnalysis::LivenessData& LivenessAnalysis::LivenessData::maxUnion(LivenessData const& _other)\n{\n\tfor (auto const& [value, count]: _other.m_liveCounts)\n\t{\n\t\tauto it = findEntry(value);\n\t\tif (it != m_liveCounts.end())\n\t\t\tit->second = std::max(it->second, count);\n\t\telse\n\t\t\tm_liveCounts.emplace_back(value, count);\n\t}\n\treturn *this;\n}\n\nLivenessAnalysis::LivenessData& LivenessAnalysis::LivenessData::operator+=(LivenessData const& _other)\n{\n\tfor (auto const& [valueId, count]: _other.m_liveCounts)\n\t\tinsert(valueId, count);\n\treturn *this;\n}\n\nLivenessAnalysis::LivenessData& LivenessAnalysis::LivenessData::operator-=(LivenessData const& _other)\n{\n\tstd::erase_if(m_liveCounts, [&](auto const& entry) { return _other.contains(entry.first); });\n\treturn *this;\n}\n\nvoid LivenessAnalysis::LivenessData::erase(Value const& _value)\n{\n\tif (\n\t\tauto const it = findEntry(_value);\n\t\tit != m_liveCounts.end()\n\t)\n\t\tm_liveCounts.erase(it);\n}\n\nvoid LivenessAnalysis::LivenessData::remove(Value const& _value, Count _count)\n{\n\tif (_count == 0)\n\t\treturn;\n\n\tauto it = findEntry(_value);\n\tif (it != m_liveCounts.end())\n\t{\n\t\tif (it->second <= _count)\n\t\t\tm_liveCounts.erase(it);\n\t\telse\n\t\t\tit->second -= _count;\n\t}\n}\n\n\nLivenessAnalysis::LivenessData LivenessAnalysis::blockExitValues(SSACFG::BlockId const& _blockId) const\n{\n\tLivenessData result;\n\tutil::GenericVisitor exitVisitor{\n\t\t[](SSACFG::BasicBlock::MainExit const&) {},\n\t\t[&](SSACFG::BasicBlock::FunctionReturn const& _functionReturn)\n\t\t{\n\t\t\tfor (auto const& valueId: _functionReturn.returnValues | ranges::views::filter(excludingLiteralsFilter()))\n\t\t\t\tresult.insert(valueId);\n\t\t},\n\t\t[](SSACFG::BasicBlock::Jump const&) {},\n\t\t[&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump)\n\t\t{\n\t\t\tif (excludingLiteralsFilter()(_conditionalJump.condition))\n\t\t\t\tresult.insert(_conditionalJump.condition);\n\t\t},\n\t\t[](SSACFG::BasicBlock::Terminated const&) {}};\n\tstd::visit(exitVisitor, m_cfg.block(_blockId).exit);\n\treturn result;\n}\n\n\nLivenessAnalysis::LivenessData::LiveCounts::iterator LivenessAnalysis::LivenessData::findEntry(Value const& _value)\n{\n\treturn ranges::find_if(m_liveCounts, [&](auto const& _entry) { return _entry.first == _value; });\n}\n\nLivenessAnalysis::LivenessData::LiveCounts::const_iterator LivenessAnalysis::LivenessData::findEntry(Value const& _value) const\n{\n\treturn ranges::find_if(m_liveCounts, [&](auto const& _entry) { return _entry.first == _value; });\n}\n\nLivenessAnalysis::LivenessAnalysis(SSACFG const& _cfg):\n\tm_cfg(_cfg),\n\tm_topologicalSort(_cfg),\n\tm_loopNestingForest(m_topologicalSort),\n\tm_liveIns(_cfg.numBlocks()),\n\tm_liveOuts(_cfg.numBlocks()),\n\tm_operationLiveOuts(_cfg.numBlocks())\n{\n\trunDagDfs();\n\tfor (auto const loopRootNode: m_loopNestingForest.loopRootNodes())\n\t\trunLoopTreeDfs(loopRootNode);\n\n\tfillOperationsLiveOut();\n}\n\nLivenessAnalysis::LivenessData LivenessAnalysis::used(SSACFG::BlockId const _blockId) const\n{\n\tauto used = liveIn(_blockId);\n\tfor (auto const& [valueId, count]: liveOut(_blockId))\n\t\tused.remove(valueId, count);\n\treturn used;\n}\n\nvoid LivenessAnalysis::runDagDfs()\n{\n\t// SSA Book, Algorithm 9.2\n\tfor (auto const blockIdValue: m_topologicalSort.postOrder())\n\t{\n\t\t// post-order traversal\n\t\tSSACFG::BlockId blockId{blockIdValue};\n\t\tauto const& block = m_cfg.block(blockId);\n\n\t\t// live <- PhiUses(B)\n\t\tLivenessData live{};\n\t\tblock.forEachExit(\n\t\t\t[&](SSACFG::BlockId const& _successor)\n\t\t\t{\n\t\t\t\tfor (auto const& phi: m_cfg.block(_successor).phis)\n\t\t\t\t{\n\t\t\t\t\tauto const& info = m_cfg.phiInfo(phi);\n\t\t\t\t\tauto const& argIndex = m_cfg.phiArgumentIndex(blockId, _successor);\n\t\t\t\t\tyulAssert(argIndex < info.arguments.size());\n\t\t\t\t\tauto const& arg = info.arguments.at(argIndex);\n\t\t\t\t\tif (!arg.isLiteral())\n\t\t\t\t\t\tlive.insert(arg);\n\t\t\t\t}\n\t\t\t});\n\n\t\t// for each S \\in succs(B) s.t. (B, S) not a back edge: live <- live \\cup (LiveIn(S) - PhiDefs(S))\n\t\tblock.forEachExit(\n\t\t\t[&](SSACFG::BlockId const& _successor) {\n\t\t\t\tif (!m_topologicalSort.backEdge(blockId, _successor))\n\t\t\t\t{\n\t\t\t\t\t// LiveIn(S) - PhiDefs(S)\n\t\t\t\t\tauto liveInWithoutPhiDefs = m_liveIns[_successor.value];\n\t\t\t\t\tfor (auto const& phiId: m_cfg.block(_successor).phis)\n\t\t\t\t\t\tliveInWithoutPhiDefs.erase(phiId);\n\t\t\t\t\tlive.maxUnion(liveInWithoutPhiDefs);\n\t\t\t\t}\n\t\t\t});\n\n\t\tif (std::holds_alternative<SSACFG::BasicBlock::FunctionReturn>(block.exit))\n\t\t\tfor (auto const& returnValue: std::get<SSACFG::BasicBlock::FunctionReturn>(block.exit).returnValues | ranges::views::filter(excludingLiteralsFilter()))\n\t\t\t\tlive.insert(returnValue);\n\n\t\t// clean out unreachables\n\t\tlive.eraseIf([&](auto const& _entry) { return _entry.first.isUnreachable(); });\n\n\t\t// LiveOut(B) <- live\n\t\tm_liveOuts[blockId.value] = live;\n\n\t\t// for each program point p in B, backwards, do:\n\t\t{\n\t\t\t// add value ids to the live set that are used in exit blocks\n\t\t\tlive += blockExitValues(blockId);\n\n\t\t\tfor (auto const& op: block.operations | ranges::views::reverse)\n\t\t\t{\n\t\t\t\t// remove variables defined at p from live\n\t\t\t\tlive.eraseAll(op.outputs | ranges::views::filter(excludingLiteralsFilter()) | ranges::to<std::vector>);\n\t\t\t\t// add uses at p to live\n\t\t\t\tlive.insertAll(op.inputs | ranges::views::filter(excludingLiteralsFilter()) | ranges::to<std::vector>);\n\t\t\t}\n\t\t}\n\n\t\t// livein(b) <- live \\cup PhiDefs(B)\n\t\tfor (auto const& phi: block.phis)\n\t\t\tlive.insert(phi);\n\t\tm_liveIns[blockId.value] = live;\n\t}\n}\n\nvoid LivenessAnalysis::runLoopTreeDfs(SSACFG::BlockId::ValueType const _loopHeader)\n{\n\t// SSA Book, Algorithm 9.3\n\tif (m_loopNestingForest.loopNodes().contains(_loopHeader))\n\t{\n\t\t// the loop header block id\n\t\tauto const& block = m_cfg.block(SSACFG::BlockId{_loopHeader});\n\t\t// LiveLoop <- LiveIn(B_N) - PhiDefs(B_N)\n\t\tauto liveLoop = m_liveIns[_loopHeader];\n\t\tfor (auto const& phi: block.phis)\n\t\t\tliveLoop.erase(phi);\n\t\t// must be live out of header if live in of children\n\t\tm_liveOuts[_loopHeader].maxUnion(liveLoop);\n\t\t// for each blockId \\in children(loopHeader)\n\t\tfor (SSACFG::BlockId::ValueType blockIdValue = 0u; blockIdValue < m_cfg.numBlocks(); ++blockIdValue)\n\t\t\tif (m_loopNestingForest.loopParents()[blockIdValue] == _loopHeader)\n\t\t\t{\n\t\t\t\t// propagate loop liveness information down to the loop header's children\n\t\t\t\tm_liveIns[blockIdValue].maxUnion(liveLoop);\n\t\t\t\tm_liveOuts[blockIdValue].maxUnion(liveLoop);\n\n\t\t\t\trunLoopTreeDfs(blockIdValue);\n\t\t\t}\n\t}\n}\n\nvoid LivenessAnalysis::fillOperationsLiveOut()\n{\n\tfor (SSACFG::BlockId blockId{0}; blockId.value < m_cfg.numBlocks(); ++blockId.value)\n\t{\n\t\tauto const& operations = m_cfg.block(blockId).operations;\n\t\tauto& liveOuts = m_operationLiveOuts[blockId.value];\n\t\tliveOuts.resize(operations.size());\n\t\tif (!operations.empty())\n\t\t{\n\t\t\tauto live = m_liveOuts[blockId.value];\n\t\t\tlive += blockExitValues(blockId);\n\t\t\tauto rit = liveOuts.rbegin();\n\t\t\tfor (auto const& op: operations | ranges::views::reverse)\n\t\t\t{\n\t\t\t\t*rit = live;\n\t\t\t\tfor (auto const& output: op.outputs | ranges::views::filter(excludingLiteralsFilter()))\n\t\t\t\t\tlive.erase(output);\n\t\t\t\tfor (auto const& input: op.inputs | ranges::views::filter(excludingLiteralsFilter()))\n\t\t\t\t\tlive.insert(input);\n\t\t\t\t++rit;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/LivenessAnalysis.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/traversal/ForwardTopologicalSort.h>\n#include <libyul/backends/evm/ssa/SSACFG.h>\n#include <libyul/backends/evm/ssa/SSACFGLoopNestingForest.h>\n\n#include <vector>\n\nnamespace solidity::yul::ssa\n{\n\n/// Performs liveness analysis on a reducible SSA CFG following Algorithm 9.1 in [1].\n///\n/// [1] Rastello, Fabrice, and Florent Bouchez Tichadou, eds. SSA-based Compiler Design. Springer, 2022.\nclass LivenessAnalysis\n{\npublic:\n\tclass LivenessData\n\t{\n\tpublic:\n\t\tusing Count = std::uint32_t;\n\t\tusing Value = SSACFG::ValueId;\n\t\tusing LiveCounts = std::vector<std::pair<Value, Count>>;\n\n\t\tLivenessData() = default;\n\t\ttemplate<std::input_iterator Iter, std::sentinel_for<Iter> Sentinel>\n\t\tLivenessData(Iter begin, Sentinel end): m_liveCounts(begin, end) {}\n\t\texplicit LivenessData(LiveCounts&& _liveCounts): m_liveCounts(std::move(_liveCounts)) {}\n\n\t\tbool contains(Value const& _valueId) const;\n\t\tCount count(Value const& _valueId) const;\n\t\tLiveCounts::const_iterator begin() const;\n\t\tLiveCounts::const_iterator end() const;\n\t\tLiveCounts::size_type size() const;\n\t\tbool empty() const;\n\n\t\t// Core modification\n\t\t/// Add value with count (default 1), incrementing if already present\n\t\tvoid insert(Value const& _value, Count _count = 1);\n\t\t/// Remove value completely regardless of count\n\t\tvoid erase(Value const& _value);\n\t\t/// Decrement value count, removing if count reaches zero\n\t\tvoid remove(Value const& _value, Count _count = 1);\n\n\t\t// Set operations\n\t\t/// Add all entries from other, summing counts\n\t\tLivenessData& operator+=(LivenessData const& _other);\n\t\t/// Remove all values present in other\n\t\tLivenessData& operator-=(LivenessData const& _other);\n\t\t/// Union with other, taking max count for each value\n\t\tLivenessData& maxUnion(LivenessData const& _other);\n\n\t\t// Bulk operations\n\t\t/// Insert all values from range with count 1 each\n\t\ttemplate<typename Range>\n\t\tvoid insertAll(Range const& _values)\n\t\t{\n\t\t\tfor (auto const& value: _values)\n\t\t\t\tinsert(value);\n\t\t}\n\n\t\t/// Erase all values from range\n\t\ttemplate<typename Range>\n\t\tvoid eraseAll(Range const& _values)\n\t\t{\n\t\t\tfor (auto const& value: _values)\n\t\t\t\terase(value);\n\t\t}\n\n\t\t// Conditional removal\n\t\t/// Remove all entries matching predicate\n\t\ttemplate<typename Predicate>\n\t\tvoid eraseIf(Predicate&& _predicate)\n\t\t{\n\t\t\tstd::erase_if(m_liveCounts, std::forward<Predicate>(_predicate));\n\t\t}\n\n\tprivate:\n\t\tLiveCounts::iterator findEntry(Value const& _value);\n\t\tLiveCounts::const_iterator findEntry(Value const& _value) const;\n\n\t\t/// Usage counts represent the total number of times each variable will be used\n\t\t/// downstream across all possible execution paths from this program point.\n\t\tLiveCounts m_liveCounts;\n\t};\n\texplicit LivenessAnalysis(SSACFG const& _cfg);\n\n\tLivenessData const& liveIn(SSACFG::BlockId const _blockId) const { return m_liveIns[_blockId.value]; }\n\tLivenessData const& liveOut(SSACFG::BlockId const _blockId) const { return m_liveOuts[_blockId.value]; }\n\tLivenessData used(SSACFG::BlockId _blockId) const;\n\tstd::vector<LivenessData> const& operationsLiveOut(SSACFG::BlockId _blockId) const { return m_operationLiveOuts[_blockId.value]; }\n\ttraversal::ForwardTopologicalSort const& topologicalSort() const { return m_topologicalSort; }\n\tSSACFG const& cfg() const { return m_cfg; }\n\nprivate:\n\tvoid runDagDfs();\n\tvoid runLoopTreeDfs(SSACFG::BlockId::ValueType _loopHeader);\n\tvoid fillOperationsLiveOut();\n\tLivenessData blockExitValues(SSACFG::BlockId const& _blockId) const;\n\n\tSSACFG const& m_cfg;\n\ttraversal::ForwardTopologicalSort m_topologicalSort;\n\tSSACFGLoopNestingForest m_loopNestingForest;\n\tstd::vector<LivenessData> m_liveIns;\n\tstd::vector<LivenessData> m_liveOuts;\n\tstd::vector<std::vector<LivenessData>> m_operationLiveOuts;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/PhiInverse.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/PhiInverse.h>\n\nusing namespace solidity::yul::ssa;\n\nPhiInverse::PhiInverse(SSACFG const& _cfg, SSACFG::BlockId const& _from, SSACFG::BlockId const& _to)\n{\n\tauto const argIndex = _cfg.phiArgumentIndex(_from, _to);\n\tfor (auto const& phiId: _cfg.block(_to).phis)\n\t{\n\t\tauto const& phiInfo = _cfg.phiInfo(phiId);\n\t\tm_phiToPreImage[phiId] = phiInfo.arguments[argIndex];\n\t}\n}\n\nbool PhiInverse::noOp() const\n{\n\treturn m_phiToPreImage.empty();\n}\n\nSSACFG::ValueId PhiInverse::operator()(SSACFG::ValueId _valueId) const\n{\n\treturn util::valueOrDefault(m_phiToPreImage, _valueId, _valueId);\n}\n\nstd::map<SSACFG::ValueId, SSACFG::ValueId> const& PhiInverse::data() const\n{\n\treturn m_phiToPreImage;\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/PhiInverse.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/SSACFG.h>\n\n#include <map>\n\nnamespace solidity::yul::ssa\n{\n\n/// If Block `_from` -> Block `_to` and `_to` has phi functions `v_k := phi(..., _from => v_i, ...)`, this transform\n/// pulls values `v_k` back to `v_i`.\nclass PhiInverse\n{\npublic:\n\tPhiInverse() = default;\n\tPhiInverse(SSACFG const& _cfg, SSACFG::BlockId const& _from, SSACFG::BlockId const& _to);\n\n\t/// whether the transform is guaranteed to be a no-op, ie, there is no phi function in `_to`\n\tbool noOp() const;\n\tSSACFG::ValueId operator()(SSACFG::ValueId _valueId) const;\n\n\tstd::map<SSACFG::ValueId, SSACFG::ValueId> const& data() const;\n\nprivate:\n\tstd::map<SSACFG::ValueId, SSACFG::ValueId> m_phiToPreImage = {};\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/SSACFG.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/SSACFG.h>\n\n#include <libyul/backends/evm/ssa/LivenessAnalysis.h>\n#include <libyul/backends/evm/ssa/JunkAdmittingBlocksFinder.h>\n#include <libyul/backends/evm/ssa/io/DotExporterBase.h>\n\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/Visitor.h>\n\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wtautological-compare\"\n#include <fmt/ranges.h>\n#pragma GCC diagnostic pop\n\n#include <range/v3/view/zip.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::yul;\nusing namespace solidity::yul::ssa;\n\nnamespace\n{\n\nstd::string formatPhi(SSACFG const& _cfg, SSACFG::PhiValue const& _phiValue)\n{\n\tauto const transform = [&](SSACFG::ValueId const& valueId) { return valueId.str(_cfg); };\n\tstd::vector<std::string> formattedArgs;\n\tformattedArgs.reserve(_phiValue.arguments.size());\n\tfor (auto const& [arg, entry]: ranges::zip_view(_phiValue.arguments | ranges::views::transform(transform), _cfg.block(_phiValue.block).entries))\n\t\tformattedArgs.push_back(fmt::format(\"Block {} => {}\", entry.value, arg));\n\tif (!formattedArgs.empty())\n\t\treturn fmt::format(\"φ(\\\\l\\\\\\n\\t{}\\\\l\\\\\\n)\", fmt::join(formattedArgs, \",\\\\l\\\\\\n\\t\"));\n\telse\n\t\treturn \"φ()\";\n}\n\nclass SSACFGDotExporter: public io::DotExporterBase\n{\npublic:\n\tSSACFGDotExporter(SSACFG const& _cfg, size_t _functionIndex, LivenessAnalysis const* _liveness):\n\t\tDotExporterBase(_cfg, _functionIndex),\n\t\tm_liveness(_liveness)\n\t{\n\t\tif (_liveness)\n\t\t\tm_junkAdmittingBlocks = std::make_unique<JunkAdmittingBlocksFinder>(_cfg, _liveness->topologicalSort());\n\t}\n\nprotected:\n\tvoid writeBlockLabel(std::ostream& _out, SSACFG::BlockId _blockId) override\n\t{\n\t\tauto const& block = m_cfg.block(_blockId);\n\t\tauto const valueToString = [&](SSACFG::ValueId const& valueId) { return valueId.str(m_cfg); };\n\n\t\tif (m_liveness)\n\t\t{\n\t\t\t_out << fmt::format(\n\t\t\t\t\"\\\\\\nBlock {}; ({}, max {})\\\\n\",\n\t\t\t\t_blockId.value,\n\t\t\t\tm_liveness->topologicalSort().preOrderIndexOf(_blockId.value),\n\t\t\t\tm_liveness->topologicalSort().maxSubtreePreOrderIndexOf(_blockId.value)\n\t\t\t);\n\t\t\t_out << fmt::format(\n\t\t\t\t\"LiveIn: {}\\\\l\\\\\\n\",\n\t\t\t\tfmt::join(m_liveness->liveIn(_blockId) | ranges::views::transform([&](auto const& liveIn) { return valueToString(SSACFG::ValueId{liveIn.first}) + fmt::format(\"[{}]\", liveIn.second); }), \", \")\n\t\t\t);\n\t\t\t_out << fmt::format(\n\t\t\t\t\"LiveOut: {}\\\\l\\\\n\",\n\t\t\t\tfmt::join(m_liveness->liveOut(_blockId) | ranges::views::transform([&](auto const& liveOut) { return valueToString(SSACFG::ValueId{liveOut.first}) + fmt::format(\"[{}]\", liveOut.second); }), \", \")\n\t\t\t);\n\t\t\tauto const usedVariables = m_liveness->used(_blockId);\n\t\t\t_out << fmt::format(\n\t\t\t\t\"Used: {}\\\\l\\\\n\",\n\t\t\t\tfmt::join(usedVariables | ranges::views::transform([&](auto const& used) { return valueToString(SSACFG::ValueId{used.first}) + fmt::format(\"[{}]\", used.second); }), \", \")\n\t\t\t);\n\t\t}\n\t\telse\n\t\t\t_out << fmt::format(\"\\\\\\nBlock {}\\\\n\", _blockId.value);\n\n\t\tfor (auto const& phi: block.phis)\n\t\t{\n\t\t\tauto const& phiInfo = m_cfg.phiInfo(phi);\n\t\t\t_out << fmt::format(\"phi{} := {}\\\\l\\\\\\n\", phi.value(), formatPhi(m_cfg, phiInfo));\n\t\t}\n\t\tfor (auto const& operation: block.operations)\n\t\t{\n\t\t\tstd::string const label = std::visit(GenericVisitor{\n\t\t\t\t[&](SSACFG::Call const& _call) {\n\t\t\t\t\treturn _call.function.get().name.str();\n\t\t\t\t},\n\t\t\t\t[&](SSACFG::BuiltinCall const& _call) {\n\t\t\t\t\treturn _call.builtin.get().name;\n\t\t\t\t},\n\t\t\t\t[&](SSACFG::LiteralAssignment const&)\n\t\t\t\t{\n\t\t\t\t\tyulAssert(operation.inputs.size() == 1);\n\t\t\t\t\treturn operation.inputs.back().str(m_cfg);\n\t\t\t\t}\n\t\t\t}, operation.kind);\n\t\t\tif (!operation.outputs.empty())\n\t\t\t\t_out << fmt::format(\n\t\t\t\t\t\"{} := \",\n\t\t\t\t\tfmt::join(operation.outputs | ranges::views::transform(valueToString), \", \")\n\t\t\t\t);\n\t\t\tif (std::holds_alternative<SSACFG::LiteralAssignment>(operation.kind))\n\t\t\t\t_out << fmt::format(\n\t\t\t\t\t\"{}\\\\l\\\\\\n\",\n\t\t\t\t\tescapeLabel(label)\n\t\t\t\t);\n\t\t\telse\n\t\t\t\t_out << fmt::format(\n\t\t\t\t\t\"{}({})\\\\l\\\\\\n\",\n\t\t\t\t\tescapeLabel(label),\n\t\t\t\t\tfmt::join(operation.inputs | ranges::views::transform(valueToString), \", \")\n\t\t\t\t);\n\t\t}\n\t}\n\n\tstd::vector<std::pair<std::string, std::string>> blockNodeAttributes(SSACFG::BlockId _blockId) override\n\t{\n\t\tif (m_junkAdmittingBlocks && m_junkAdmittingBlocks->allowsAdditionOfJunk(_blockId))\n\t\t\treturn {{\"fillcolor\", \"\\\"#FF746C\\\"\"}, {\"style\", \"filled\"}};\n\t\treturn {};\n\t}\n\n\tEdgeStyle edgeStyle(SSACFG::BlockId _source, SSACFG::BlockId _target) override\n\t{\n\t\tif (m_liveness && m_liveness->topologicalSort().backEdge(_source, _target))\n\t\t\treturn EdgeStyle::Dashed;\n\t\treturn EdgeStyle::Solid;\n\t}\n\nprivate:\n\tLivenessAnalysis const* m_liveness;\n\tstd::unique_ptr<JunkAdmittingBlocksFinder> m_junkAdmittingBlocks;\n};\n\n}\n\nstd::string SSACFG::ValueId::str(SSACFG const& _cfg) const\n{\n\tif (!hasValue())\n\t\treturn \"INVALID\";\n\tswitch (kind())\n\t{\n\t\tcase Kind::Literal:  return toCompactHexWithPrefix(_cfg.literalInfo(*this).value);\n\t\tcase Kind::Variable: return fmt::format(\"v{}\", value());\n\t\tcase Kind::Phi: return fmt::format(\"phi{}\", value());\n\t\tcase Kind::Unreachable: return \"[unreachable]\";\n\t}\n\tunreachable();\n}\n\n\nstd::string SSACFG::toDot(\n\tbool _includeDiGraphDefinition,\n\tstd::optional<size_t> _functionIndex,\n\tLivenessAnalysis const* _liveness\n) const\n{\n\tSSACFGDotExporter exporter(*this, _functionIndex.value_or(function ? 1 : 0), _liveness);\n\tif (function)\n\t\treturn exporter.exportFunction(*function, _includeDiGraphDefinition);\n\telse\n\t\treturn exporter.exportBlocks(entry, _includeDiGraphDefinition);\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/SSACFG.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Control flow graph and stack layout structures used during code generation.\n */\n\n#pragma once\n\n#include <libyul/AST.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/Dialect.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Scope.h>\n\n#include <libsolutil/Numeric.h>\n\n#include <range/v3/view/map.hpp>\n#include <deque>\n#include <functional>\n#include <list>\n#include <vector>\n\nnamespace solidity::yul::ssa\n{\nclass LivenessAnalysis;\n\nclass SSACFG\n{\npublic:\n\tSSACFG() = default;\n\tSSACFG(SSACFG const&) = delete;\n\tSSACFG(SSACFG&&) = delete;\n\tSSACFG& operator=(SSACFG const&) = delete;\n\tSSACFG& operator=(SSACFG&&) = delete;\n\t~SSACFG() = default;\n\n\tstruct BlockId\n\t{\n\t\tusing ValueType = std::uint32_t;\n\t\tValueType value = std::numeric_limits<ValueType>::max();\n\t\tbool hasValue() const { return value != std::numeric_limits<ValueType>::max(); }\n\t\tauto operator<=>(BlockId const&) const = default;\n\t};\n\tclass ValueId\n\t{\n\tpublic:\n\t\tenum class Kind: std::uint8_t\n\t\t{\n\t\t\tLiteral,\n\t\t\tVariable,\n\t\t\tPhi,\n\t\t\tUnreachable\n\t\t};\n\t\tusing ValueType = std::uint32_t;\n\n\t\tconstexpr ValueId() = default;\n\t\tconstexpr ValueId(ValueType const _value, Kind const _kind): m_value(_value), m_kind(_kind) {}\n\t\tconstexpr ValueId(ValueId const&) = default;\n\t\tconstexpr ValueId(ValueId&&) = default;\n\t\tconstexpr ValueId& operator=(ValueId const&) = default;\n\t\tconstexpr ValueId& operator=(ValueId&&) = default;\n\n\t\tstatic ValueId constexpr makeLiteral(ValueType const& _value) { return ValueId{_value, Kind::Literal}; }\n\t\tstatic ValueId constexpr makeVariable(ValueType const& _value) { return ValueId{_value, Kind::Variable}; }\n\t\tstatic ValueId constexpr makePhi(ValueType const& _value) { return ValueId{_value, Kind::Phi}; }\n\t\tstatic ValueId constexpr makeUnreachable() { return ValueId{0u, Kind::Unreachable}; }\n\n\t\tbool constexpr isLiteral() const noexcept { return m_kind == Kind::Literal; }\n\t\tbool constexpr isVariable() const noexcept { return m_kind == Kind::Variable; }\n\t\tbool constexpr isPhi() const noexcept { return m_kind == Kind::Phi; }\n\t\tbool constexpr isUnreachable() const noexcept { return m_kind == Kind::Unreachable; }\n\n\t\tbool constexpr hasValue() const { return m_value != std::numeric_limits<ValueType>::max(); }\n\t\tValueType constexpr value() const noexcept { return m_value; }\n\t\tKind constexpr kind() const noexcept { return m_kind; }\n\t\tstd::string str(SSACFG const& _cfg) const;\n\n\t\tauto operator<=>(ValueId const&) const = default;\n\n\tprivate:\n\t\tValueType m_value{std::numeric_limits<ValueType>::max()};\n\t\tKind m_kind{Kind::Unreachable};\n\t};\n\n\tstruct BuiltinCall\n\t{\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\tstd::reference_wrapper<BuiltinFunction const> builtin;\n\t\tstd::reference_wrapper<FunctionCall const> call;\n\t};\n\tstruct Call\n\t{\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\tstd::reference_wrapper<Scope::Function const> function;\n\t\tstd::reference_wrapper<FunctionCall const> call;\n\t\tbool canContinue;\n\t};\n\tstruct LiteralAssignment\n\t{\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t};\n\n\tstruct Operation {\n\t\tstd::vector<ValueId> outputs{};\n\t\tstd::variant<BuiltinCall, Call, LiteralAssignment> kind;\n\t\tstd::vector<ValueId> inputs{};\n\t};\n\tstruct BasicBlock\n\t{\n\t\tstruct MainExit {};\n\t\tstruct ConditionalJump\n\t\t{\n\t\t\tlangutil::DebugData::ConstPtr debugData{};\n\t\t\tValueId condition;\n\t\t\tBlockId nonZero;\n\t\t\tBlockId zero;\n\t\t};\n\t\tstruct Jump\n\t\t{\n\t\t\tlangutil::DebugData::ConstPtr debugData{};\n\t\t\tBlockId target;\n\t\t};\n\t\tstruct FunctionReturn\n\t\t{\n\t\t\tlangutil::DebugData::ConstPtr debugData{};\n\t\t\tstd::vector<ValueId> returnValues;\n\t\t};\n\t\tstruct Terminated {};\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\tstd::set<BlockId> entries;\n\t\tstd::set<ValueId> phis;\n\t\tstd::vector<Operation> operations;\n\t\tstd::variant<MainExit, Jump, ConditionalJump, FunctionReturn, Terminated> exit = MainExit{};\n\t\ttemplate<typename Callable>\n\t\tvoid forEachExit(Callable&& _callable) const\n\t\t{\n\t\t\tif (auto* jump = std::get_if<Jump>(&exit))\n\t\t\t\t_callable(jump->target);\n\t\t\telse if (auto* conditionalJump = std::get_if<ConditionalJump>(&exit))\n\t\t\t{\n\t\t\t\t_callable(conditionalJump->nonZero);\n\t\t\t\t_callable(conditionalJump->zero);\n\t\t\t}\n\t\t}\n\n\t\tbool isMainExitBlock() const\n\t\t{\n\t\t\treturn std::holds_alternative<MainExit>(exit);\n\t\t}\n\n\t\tbool isTerminationBlock() const\n\t\t{\n\t\t\treturn std::holds_alternative<Terminated>(exit);\n\t\t}\n\n\t\tbool isFunctionReturnBlock() const\n\t\t{\n\t\t\treturn std::holds_alternative<FunctionReturn>(exit);\n\t\t}\n\n\t\tbool isJumpBlock() const\n\t\t{\n\t\t\treturn std::holds_alternative<Jump>(exit);\n\t\t}\n\t};\n\tBlockId makeBlock(langutil::DebugData::ConstPtr _debugData)\n\t{\n\t\tBlockId blockId { static_cast<BlockId::ValueType>(m_blocks.size()) };\n\t\tm_blocks.emplace_back(BasicBlock{std::move(_debugData), {}, {}, {}, BasicBlock::Terminated{}});\n\t\treturn blockId;\n\t}\n\tBasicBlock& block(BlockId _id) { return m_blocks.at(_id.value); }\n\tBasicBlock const& block(BlockId _id) const { return m_blocks.at(_id.value); }\n\tsize_t numBlocks() const { return m_blocks.size(); }\n\nprivate:\n\tstd::vector<BasicBlock> m_blocks;\npublic:\n\tstruct LiteralValue {\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\tu256 value;\n\t};\n\tstruct VariableValue {\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\tBlockId definingBlock;\n\t};\n\tstruct PhiValue {\n\t\tlangutil::DebugData::ConstPtr debugData;\n\t\tBlockId block;\n\t\tstd::vector<ValueId> arguments;\n\t};\n\tstruct UnreachableValue {};\n\tValueId newPhi(BlockId const _definingBlock)\n\t{\n\t\tauto const& block = m_blocks.at(_definingBlock.value);\n\t\tm_phis.emplace_back(PhiValue{debugDataOf(block), _definingBlock, std::vector<ValueId>{}});\n\t\tauto const value = m_phis.size() - 1;\n\t\tyulAssert(value < std::numeric_limits<ValueId::ValueType>::max());\n\t\treturn ValueId::makePhi(static_cast<ValueId::ValueType>(value));\n\t}\n\tValueId newVariable(BlockId const _definingBlock)\n\t{\n\t\tauto const& block = m_blocks.at(_definingBlock.value);\n\t\tm_variables.emplace_back(VariableValue{debugDataOf(block), _definingBlock});\n\t\tauto const value = m_variables.size() - 1;\n\t\tyulAssert(value < std::numeric_limits<ValueId::ValueType>::max());\n\t\treturn ValueId::makeVariable(static_cast<ValueId::ValueType>(value));\n\t}\n\n\tValueId unreachableValue()\n\t{\n\t\tif (!m_unreachableValue)\n\t\t\tm_unreachableValue = ValueId::makeUnreachable();\n\t\treturn *m_unreachableValue;\n\t}\n\n\tValueId newLiteral(langutil::DebugData::ConstPtr _debugData, u256 _value)\n\t{\n\t\tauto const it = m_literalMapping.find(_value);\n\t\tif (it != m_literalMapping.end())\n\t\t{\n\t\t\tValueId const& valueId = it->second;\n\t\t\tyulAssert(valueId.hasValue() && m_literals[valueId.value()].value == _value);\n\t\t\treturn valueId;\n\t\t}\n\n\n\t\tm_literals.emplace_back(LiteralValue{std::move(_debugData), std::move(_value)});\n\t\tauto const value = m_literals.size() - 1;\n\t\tyulAssert(value < std::numeric_limits<ValueId::ValueType>::max());\n\t\tauto const literalId = ValueId::makeLiteral(static_cast<ValueId::ValueType>(value));\n\t\tm_literalMapping.emplace(_value, literalId);\n\t\treturn literalId;\n\t}\n\n\tsize_t phiArgumentIndex(BlockId const _source, BlockId const _target) const\n\t{\n\t\tauto const& targetBlock = block(_target);\n\t\tauto idx = util::findOffset(targetBlock.entries, _source);\n\t\tyulAssert(idx, fmt::format(\"Target block {} not found as entry in one of the exits of the current block {}.\", _target.value, _source.value));\n\t\treturn *idx;\n\t}\n\n\tstd::string toDot(\n\t\tbool _includeDiGraphDefinition=true,\n\t\tstd::optional<size_t> _functionIndex=std::nullopt,\n\t\tLivenessAnalysis const* _liveness=nullptr\n\t) const;\n\n\tPhiValue const& phiInfo(ValueId const& _valueId) const\n\t{\n\t\tyulAssert(_valueId.hasValue() && _valueId.isPhi());\n\t\treturn m_phis.at(_valueId.value());\n\t}\n\tPhiValue& phiInfo(ValueId const& _valueId)\n\t{\n\t\tyulAssert(_valueId.hasValue() && _valueId.isPhi());\n\t\treturn m_phis.at(_valueId.value());\n\t}\n\tLiteralValue const& literalInfo(ValueId const& _valueId) const\n\t{\n\t\tyulAssert(_valueId.hasValue() && _valueId.isLiteral());\n\t\treturn m_literals.at(_valueId.value());\n\t}\n\tVariableValue const& variableInfo(ValueId const& _valueId) const\n\t{\n\t\tyulAssert(_valueId.hasValue() && _valueId.isVariable());\n\t\treturn m_variables.at(_valueId.value());\n\t}\n\nprivate:\n\tstd::vector<LiteralValue> m_literals;\n\tstd::map<u256, ValueId> m_literalMapping;\n\tstd::vector<PhiValue> m_phis;\n\tstd::vector<VariableValue> m_variables;\n\tstd::optional<ValueId> m_unreachableValue;\npublic:\n\tlangutil::DebugData::ConstPtr debugData;\n\tBlockId entry = BlockId{0};\n\tstd::set<BlockId> exits;\n\tScope::Function const* function = nullptr;\n\tbool canContinue = true;\n\tstd::vector<std::tuple<std::reference_wrapper<Scope::Variable const>, ValueId>> arguments;\n\tstd::vector<std::reference_wrapper<Scope::Variable const>> returns;\n\tstd::vector<std::reference_wrapper<Scope::Function const>> functions;\n\t// Container for artificial calls generated for switch statements.\n\tstd::list<FunctionCall> ghostCalls;\n};\n\n}\n\ntemplate<>\nstruct fmt::formatter<solidity::yul::ssa::SSACFG::BlockId>\n{\n\tstatic auto constexpr parse(format_parse_context& ctx) -> decltype(ctx.begin()) { return ctx.begin(); }\n\n\ttemplate<typename FormatContext>\n\tauto format(solidity::yul::ssa::SSACFG::BlockId const& _blockId, FormatContext& _ctx) const -> decltype(_ctx.out())\n\t{\n\t\tif (!_blockId.hasValue())\n\t\t\treturn fmt::format_to(_ctx.out(), \"empty\");\n\t\treturn fmt::format_to(_ctx.out(), \"{}\", _blockId.value);\n\t}\n};\n\ntemplate<>\nstruct fmt::formatter<solidity::yul::ssa::SSACFG::ValueId>\n{\n\tstatic auto constexpr parse(format_parse_context& ctx) -> decltype(ctx.begin()) { return ctx.begin(); }\n\n\ttemplate<typename FormatContext>\n\tauto format(solidity::yul::ssa::SSACFG::ValueId const& _valueId, FormatContext& _ctx) const -> decltype(_ctx.out())\n\t{\n\t\tif (!_valueId.hasValue())\n\t\t\treturn fmt::format_to(_ctx.out(), \"empty\");\n\t\tswitch (_valueId.kind())\n\t\t{\n\t\tcase solidity::yul::ssa::SSACFG::ValueId::Kind::Literal:\n\t\t\treturn fmt::format_to(_ctx.out(), \"lit{}\", _valueId.value());\n\t\tcase solidity::yul::ssa::SSACFG::ValueId::Kind::Variable:\n\t\t\treturn fmt::format_to(_ctx.out(), \"v{}\", _valueId.value());\n\t\tcase solidity::yul::ssa::SSACFG::ValueId::Kind::Phi:\n\t\t\treturn fmt::format_to(_ctx.out(), \"phi{}\", _valueId.value());\n\t\tcase solidity::yul::ssa::SSACFG::ValueId::Kind::Unreachable:\n\t\t\treturn fmt::format_to(_ctx.out(), \"unreachable\");\n\t\t}\n\t\tsolidity::util::unreachable();\n\t}\n};\n"
  },
  {
    "path": "libyul/backends/evm/ssa/SSACFGBuilder.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Transformation of a Yul AST into a control flow graph.\n */\n\n#include <libyul/backends/evm/ssa/SSACFGBuilder.h>\n\n#include <libyul/backends/evm/ssa/ControlFlow.h>\n\n#include <libyul/AST.h>\n#include <libyul/ControlFlowSideEffectsCollector.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/StringUtils.h>\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/algorithm/replace.hpp>\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/drop_last.hpp>\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/filter.hpp>\n#include <range/v3/view/reverse.hpp>\n#include <range/v3/view/transform.hpp>\n#include <range/v3/view/zip.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::yul::ssa;\n\nSSACFGBuilder::SSACFGBuilder(\n\tControlFlow& _controlFlow,\n\tSSACFG& _graph,\n\tAsmAnalysisInfo const& _analysisInfo,\n\tControlFlowSideEffectsCollector const& _sideEffects,\n\tDialect const& _dialect,\n\tbool _keepLiteralAssignments\n):\n\tm_controlFlow(_controlFlow),\n\tm_graph(_graph),\n\tm_info(_analysisInfo),\n\tm_sideEffects(_sideEffects),\n\tm_dialect(_dialect),\n\tm_keepLiteralAssignments(_keepLiteralAssignments)\n{\n}\n\nstd::unique_ptr<ControlFlow> SSACFGBuilder::build(\n\tAsmAnalysisInfo const& _analysisInfo,\n\tDialect const& _dialect,\n\tBlock const& _block,\n\tbool _keepLiteralAssignments\n)\n{\n\tControlFlowSideEffectsCollector sideEffects(_dialect, _block);\n\n\tauto controlFlow = std::make_unique<ControlFlow>();\n\tcontrolFlow->functionGraphs.emplace_back(std::make_unique<SSACFG>());\n\tcontrolFlow->functionGraphMapping.emplace_back(nullptr, controlFlow->functionGraphs.back().get());\n\tSSACFG& mainGraph = *controlFlow->functionGraphs.back();\n\tSSACFGBuilder builder(*controlFlow, mainGraph, _analysisInfo, sideEffects, _dialect, _keepLiteralAssignments);\n\tbuilder.m_currentBlock = mainGraph.makeBlock(debugDataOf(_block));\n\tbuilder.sealBlock(builder.m_currentBlock);\n\tbuilder(_block);\n\tif (!builder.blockInfo(builder.m_currentBlock).sealed)\n\t\tbuilder.sealBlock(builder.m_currentBlock);\n\tmainGraph.block(builder.m_currentBlock).exit = SSACFG::BasicBlock::MainExit{};\n\tbuilder.cleanUnreachable();\n\treturn controlFlow;\n}\n\nSSACFG::ValueId SSACFGBuilder::tryRemoveTrivialPhi(SSACFG::ValueId _phi)\n{\n\t// TODO: double-check if this is sane\n\tauto const& phiInfo = m_graph.phiInfo(_phi);\n\tyulAssert(blockInfo(phiInfo.block).sealed);\n\n\tSSACFG::ValueId same;\n\tfor (SSACFG::ValueId arg: phiInfo.arguments)\n\t{\n\t\tif (arg == same || arg == _phi)\n\t\t\tcontinue;  // unique value or self-reference\n\t\tif (same.hasValue())\n\t\t\treturn _phi;  // phi merges at least two distinct values -> not trivial\n\t\tsame = arg;\n\t}\n\tif (!same.hasValue())\n\t{\n\t\t// This will happen for unreachable paths.\n\t\t// TODO: check how best to deal with this\n\t\tsame = m_graph.unreachableValue();\n\t}\n\n\tm_graph.block(phiInfo.block).phis.erase(_phi);\n\n\tstd::vector<SSACFG::ValueId> phiUses;\n\tfor (SSACFG::BlockId::ValueType blockIdValue = 0; blockIdValue < m_graph.numBlocks(); ++blockIdValue)\n\t{\n\t\tauto& block = m_graph.block(SSACFG::BlockId{blockIdValue});\n\t\tfor (auto blockPhi: block.phis)\n\t\t{\n\t\t\tyulAssert(blockPhi.hasValue());\n\t\t\tyulAssert(blockPhi != _phi, \"Phis should be defined in exactly one block, _phi was erased.\");\n\t\t\tauto& blockPhiInfo = m_graph.phiInfo(blockPhi);\n\t\t\tbool usedInPhi = false;\n\t\t\tfor (auto& arg: blockPhiInfo.arguments)\n\t\t\t\tif (arg == _phi)\n\t\t\t\t{\n\t\t\t\t\targ = same;\n\t\t\t\t\tusedInPhi = true;\n\t\t\t\t}\n\t\t\tif (usedInPhi)\n\t\t\t\tphiUses.push_back(blockPhi);\n\t\t}\n\t\tfor (auto& op: block.operations)\n\t\t\tranges::replace(op.inputs, _phi, same);\n\t\tstd::visit(util::GenericVisitor{\n\t\t\t[_phi, same](SSACFG::BasicBlock::FunctionReturn& _functionReturn) {\n\t\t\t\tranges::replace(_functionReturn.returnValues,_phi, same);\n\t\t\t},\n\t\t\t[_phi, same](SSACFG::BasicBlock::ConditionalJump& _condJump) {\n\t\t\t\tif (_condJump.condition == _phi)\n\t\t\t\t\t_condJump.condition = same;\n\t\t\t},\n\t\t\t[](SSACFG::BasicBlock::Jump&) {},\n\t\t\t[](SSACFG::BasicBlock::MainExit&) {},\n\t\t\t[](SSACFG::BasicBlock::Terminated&) {}\n\t\t}, block.exit);\n\t}\n\tfor (auto& currentVariableDefs: m_currentDef | ranges::views::values)\n\t\tranges::replace(currentVariableDefs, _phi, same);\n\n\tfor (auto phiUse: phiUses)\n\t\ttryRemoveTrivialPhi(phiUse);\n\n\treturn same;\n}\n\n/// Removes edges to blocks that are not reachable.\nvoid SSACFGBuilder::cleanUnreachable()\n{\n\t// Determine which blocks are reachable from the entry.\n\tutil::BreadthFirstSearch<SSACFG::BlockId> reachabilityCheck{{m_graph.entry}};\n\treachabilityCheck.run([&](SSACFG::BlockId _blockId, auto&& _addChild) {\n\t\tauto const& block = m_graph.block(_blockId);\n\t\tvisit(util::GenericVisitor{\n\t\t\t\t[&](SSACFG::BasicBlock::Jump const& _jump) {\n\t\t\t\t\t_addChild(_jump.target);\n\t\t\t\t},\n\t\t\t\t[&](SSACFG::BasicBlock::ConditionalJump const& _jump) {\n\t\t\t\t\t_addChild(_jump.zero);\n\t\t\t\t\t_addChild(_jump.nonZero);\n\t\t\t\t},\n\t\t\t\t[](SSACFG::BasicBlock::FunctionReturn const&) {},\n\t\t\t\t[](SSACFG::BasicBlock::Terminated const&) {},\n\t\t\t\t[](SSACFG::BasicBlock::MainExit const&) {}\n\t\t\t}, block.exit);\n\t});\n\n\t// Remove all entries from unreachable nodes from the graph.\n\tfor (SSACFG::BlockId blockId: reachabilityCheck.visited)\n\t{\n\t\tauto& block = m_graph.block(blockId);\n\n\t\tstd::vector<SSACFG::ValueId> maybeTrivialPhi;\n\t\tstd::erase_if(block.entries, [&](auto const& entry) { return !reachabilityCheck.visited.contains(entry); });\n\t\tfor (auto phi: block.phis)\n\t\t{\n\t\t\tyulAssert(phi.hasValue());\n\t\t\tauto& phiInfo = m_graph.phiInfo(phi);\n\t\t\tauto const erasedCount = std::erase_if(phiInfo.arguments, [&](SSACFG::ValueId const _arg) {\n\t\t\t\treturn _arg.isUnreachable();\n\t\t\t});\n\t\t\tif (erasedCount > 0)\n\t\t\t\tmaybeTrivialPhi.push_back(phi);\n\t\t}\n\n\t\t// After removing a phi argument, we might end up with a trivial phi that can be removed.\n\t\tfor (auto phi: maybeTrivialPhi)\n\t\t\ttryRemoveTrivialPhi(phi);\n\t}\n}\n\nvoid SSACFGBuilder::buildFunctionGraph(\n\tScope::Function const* _function,\n\tFunctionDefinition const* _functionDefinition\n)\n{\n\tm_controlFlow.functionGraphs.emplace_back(std::make_unique<SSACFG>());\n\tauto& cfg = *m_controlFlow.functionGraphs.back();\n\tm_controlFlow.functionGraphMapping.emplace_back(_function, &cfg);\n\n\tyulAssert(m_info.scopes.at(&_functionDefinition->body), \"\");\n\tScope* virtualFunctionScope = m_info.scopes.at(m_info.virtualBlocks.at(_functionDefinition).get()).get();\n\tyulAssert(virtualFunctionScope, \"\");\n\n\tcfg.entry = cfg.makeBlock(debugDataOf(_functionDefinition->body));\n\tauto arguments = _functionDefinition->parameters | ranges::views::transform([&](auto const& _param) {\n\t\tauto const& var = std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_param.name));\n\t\t// Note: cannot use std::make_tuple since it unwraps reference wrappers.\n\t\treturn std::tuple{std::cref(var), cfg.newVariable(cfg.entry)};\n\t}) | ranges::to<std::vector>;\n\tauto returns = _functionDefinition->returnVariables | ranges::views::transform([&](auto const& _param) {\n\t\treturn std::cref(std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_param.name)));\n\t}) | ranges::to<std::vector>;\n\n\tcfg.debugData = _functionDefinition->debugData;\n\tcfg.function = _function;\n\tcfg.canContinue = m_sideEffects.functionSideEffects().at(_functionDefinition).canContinue;\n\tcfg.arguments = arguments;\n\tcfg.returns = returns;\n\n\tSSACFGBuilder builder(m_controlFlow, cfg, m_info, m_sideEffects, m_dialect, m_keepLiteralAssignments);\n\tbuilder.m_currentBlock = cfg.entry;\n\tbuilder.m_functionDefinitions = m_functionDefinitions;\n\tfor (auto&& [var, varId]: cfg.arguments)\n\t\tbuilder.currentDef(var, cfg.entry) = varId;\n\tfor (auto const& var: cfg.returns)\n\t\tbuilder.currentDef(var.get(), cfg.entry) = builder.zero();\n\tbuilder.sealBlock(cfg.entry);\n\tbuilder(_functionDefinition->body);\n\tcfg.exits.insert(builder.m_currentBlock);\n\t// Artificial explicit function exit (`leave`) at the end of the body.\n\tbuilder(Leave{debugDataOf(*_functionDefinition)});\n\tbuilder.cleanUnreachable();\n}\n\nvoid SSACFGBuilder::operator()(ExpressionStatement const& _expressionStatement)\n{\n\tauto const* functionCall = std::get_if<FunctionCall>(&_expressionStatement.expression);\n\tyulAssert(functionCall);\n\tauto results = visitFunctionCall(*functionCall);\n\tyulAssert(results.empty());\n}\n\nvoid SSACFGBuilder::operator()(Assignment const& _assignment)\n{\n\tassign(\n\t\t_assignment.variableNames | ranges::views::transform([&](auto& _var) { return std::ref(lookupVariable(_var.name)); }) | ranges::to<std::vector>,\n\t\t_assignment.value.get()\n\t);\n}\n\nvoid SSACFGBuilder::operator()(VariableDeclaration const& _variableDeclaration)\n{\n\tassign(\n\t\t_variableDeclaration.variables | ranges::views::transform([&](auto& _var) { return std::ref(lookupVariable(_var.name)); }) | ranges::to<std::vector>,\n\t\t_variableDeclaration.value.get()\n\t);\n}\n\nvoid SSACFGBuilder::operator()(FunctionDefinition const& _functionDefinition)\n{\n\tScope::Function const& function = lookupFunction(_functionDefinition.name);\n\tbuildFunctionGraph(&function, &_functionDefinition);\n}\n\nvoid SSACFGBuilder::operator()(If const& _if)\n{\n\tstd::optional<bool> constantCondition;\n\tif (auto const* literalCondition = std::get_if<Literal>(_if.condition.get()))\n\t\tconstantCondition = literalCondition->value.value() != 0;\n\t// deal with literal (constant) conditions explicitly\n\tif (constantCondition)\n\t{\n\t\tif (*constantCondition)\n\t\t\t// Always true - skip conditional, just execute if branch\n\t\t\t(*this)(_if.body);\n\t}\n\telse\n\t{\n\t\tauto condition = std::visit(*this, *_if.condition);\n\t\tauto ifBranch = m_graph.makeBlock(debugDataOf(_if.body));\n\t\tauto afterIf = m_graph.makeBlock(debugDataOf(currentBlock()));\n\t\tconditionalJump(\n\t\t\tdebugDataOf(_if),\n\t\t\tcondition,\n\t\t\tifBranch,\n\t\t\tafterIf\n\t\t);\n\t\tsealBlock(ifBranch);\n\t\tm_currentBlock = ifBranch;\n\t\t(*this)(_if.body);\n\t\tjump(debugDataOf(_if.body), afterIf);\n\t\tsealBlock(afterIf);\n\t}\n}\n\nvoid SSACFGBuilder::operator()(Switch const& _switch)\n{\n\tauto expression = std::visit(*this, *_switch.expression);\n\n\tif (auto const* constantExpression = std::get_if<Literal>(_switch.expression.get()))\n\t{\n\t\tCase const* matchedCase = nullptr;\n\t\t// select case that matches (or default if available)\n\t\tfor (auto const& switchCase: _switch.cases)\n\t\t{\n\t\t\tif (!switchCase.value)\n\t\t\t\tmatchedCase = &switchCase;\n\t\t\tif (switchCase.value && switchCase.value->value.value() == constantExpression->value.value())\n\t\t\t{\n\t\t\t\tmatchedCase = &switchCase;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (matchedCase)\n\t\t{\n\t\t\t// inject directly into the current block\n\t\t\t(*this)(matchedCase->body);\n\t\t}\n\t\treturn;\n\t}\n\n\tstd::optional<BuiltinHandle> equalityBuiltinHandle = m_dialect.equalityFunctionHandle();\n\tyulAssert(equalityBuiltinHandle);\n\n\tauto makeValueCompare = [&](Case const& _case) {\n\t\tFunctionCall const& ghostCall = m_graph.ghostCalls.emplace_back(FunctionCall{\n\t\t\tdebugDataOf(_case),\n\t\t\tBuiltinName{{}, *equalityBuiltinHandle},\n\t\t\t{*_case.value /* skip second argument */ }\n\t\t});\n\t\tauto outputValue = m_graph.newVariable(m_currentBlock);\n\t\tcurrentBlock().operations.emplace_back(SSACFG::Operation{\n\t\t\t{outputValue},\n\t\t\tSSACFG::BuiltinCall{\n\t\t\t\tdebugDataOf(_case),\n\t\t\t\tm_dialect.builtin(*equalityBuiltinHandle),\n\t\t\t\tghostCall\n\t\t\t},\n\t\t\t{m_graph.newLiteral(debugDataOf(_case), _case.value->value.value()), expression}\n\t\t});\n\t\treturn outputValue;\n\t};\n\n\tauto afterSwitch = m_graph.makeBlock(debugDataOf(currentBlock()));\n\tyulAssert(!_switch.cases.empty(), \"\");\n\tfor (auto const& switchCase: _switch.cases | ranges::views::drop_last(1))\n\t{\n\t\tyulAssert(switchCase.value, \"\");\n\t\tauto caseBranch = m_graph.makeBlock(debugDataOf(switchCase.body));\n\t\tauto elseBranch = m_graph.makeBlock(debugDataOf(_switch));\n\n\t\tconditionalJump(debugDataOf(switchCase), makeValueCompare(switchCase), caseBranch, elseBranch);\n\t\tsealBlock(caseBranch);\n\t\tsealBlock(elseBranch);\n\t\tm_currentBlock = caseBranch;\n\t\t(*this)(switchCase.body);\n\t\tjump(debugDataOf(switchCase.body), afterSwitch);\n\t\tm_currentBlock = elseBranch;\n\t}\n\tCase const& switchCase = _switch.cases.back();\n\tif (switchCase.value)\n\t{\n\t\tauto caseBranch = m_graph.makeBlock(debugDataOf(switchCase.body));\n\t\tconditionalJump(debugDataOf(switchCase), makeValueCompare(switchCase), caseBranch, afterSwitch);\n\t\tsealBlock(caseBranch);\n\t\tm_currentBlock = caseBranch;\n\t}\n\t(*this)(switchCase.body);\n\tjump(debugDataOf(switchCase.body), afterSwitch);\n\tsealBlock(afterSwitch);\n}\nvoid SSACFGBuilder::operator()(ForLoop const& _loop)\n{\n\tScopedSaveAndRestore scopeRestore(m_scope, m_info.scopes.at(&_loop.pre).get());\n\t(*this)(_loop.pre);\n\tauto preLoopDebugData = debugDataOf(currentBlock());\n\n\tstd::optional<bool> constantCondition;\n\tif (auto const* literalCondition = std::get_if<Literal>(_loop.condition.get()))\n\t\tconstantCondition = literalCondition->value.value() != 0;\n\n\tSSACFG::BlockId loopCondition = m_graph.makeBlock(debugDataOf(*_loop.condition));\n\tSSACFG::BlockId loopBody = m_graph.makeBlock(debugDataOf(_loop.body));\n\tSSACFG::BlockId post = m_graph.makeBlock(debugDataOf(_loop.post));\n\tSSACFG::BlockId afterLoop = m_graph.makeBlock(preLoopDebugData);\n\n\tclass ForLoopInfoScope {\n\tpublic:\n\t\tForLoopInfoScope(std::stack<ForLoopInfo>& _info, SSACFG::BlockId _breakBlock, SSACFG::BlockId _continueBlock): m_info(_info)\n\t\t{\n\t\t\tm_info.push(ForLoopInfo{_breakBlock, _continueBlock});\n\t\t}\n\t\t~ForLoopInfoScope() {\n\t\t\tm_info.pop();\n\t\t}\n\tprivate:\n\t\tstd::stack<ForLoopInfo>& m_info;\n\t} forLoopInfoScope(m_forLoopInfo, afterLoop, post);\n\n\tif (constantCondition.has_value())\n\t{\n\t\tstd::visit(*this, *_loop.condition);\n\t\tif (*constantCondition)\n\t\t{\n\t\t\tjump(debugDataOf(*_loop.condition), loopBody);\n\t\t\t(*this)(_loop.body);\n\t\t\tjump(debugDataOf(_loop.body), post);\n\t\t\tsealBlock(post);\n\t\t\t(*this)(_loop.post);\n\t\t\tjump(debugDataOf(_loop.post), loopBody);\n\t\t\tsealBlock(loopBody);\n\t\t}\n\t\telse\n\t\t\tjump(debugDataOf(*_loop.condition), afterLoop);\n\t}\n\telse\n\t{\n\t\tjump(debugDataOf(_loop.pre), loopCondition);\n\t\tauto condition = std::visit(*this, *_loop.condition);\n\t\tconditionalJump(debugDataOf(*_loop.condition), condition, loopBody, afterLoop);\n\t\tsealBlock(loopBody);\n\t\tm_currentBlock = loopBody;\n\t\t(*this)(_loop.body);\n\t\tjump(debugDataOf(_loop.body), post);\n\t\tsealBlock(post);\n\t\t(*this)(_loop.post);\n\t\tjump(debugDataOf(_loop.post), loopCondition);\n\t\tsealBlock(loopCondition);\n\t}\n\n\tsealBlock(afterLoop);\n\tm_currentBlock = afterLoop;\n}\n\nvoid SSACFGBuilder::operator()(Break const& _break)\n{\n\tyulAssert(!m_forLoopInfo.empty());\n\tauto currentBlockDebugData = debugDataOf(currentBlock());\n\tjump(debugDataOf(_break), m_forLoopInfo.top().breakBlock);\n\tm_currentBlock = m_graph.makeBlock(currentBlockDebugData);\n\tsealBlock(m_currentBlock);\n}\n\nvoid SSACFGBuilder::operator()(Continue const& _continue)\n{\n\tyulAssert(!m_forLoopInfo.empty());\n\tauto currentBlockDebugData = debugDataOf(currentBlock());\n\tjump(debugDataOf(_continue), m_forLoopInfo.top().continueBlock);\n\tm_currentBlock = m_graph.makeBlock(currentBlockDebugData);\n\tsealBlock(m_currentBlock);\n}\n\nvoid SSACFGBuilder::operator()(Leave const& _leaveStatement)\n{\n\tauto currentBlockDebugData = debugDataOf(currentBlock());\n\tcurrentBlock().exit = SSACFG::BasicBlock::FunctionReturn{\n\t\tdebugDataOf(_leaveStatement),\n\t\tm_graph.returns | ranges::views::transform([&](auto _var) {\n\t\t\treturn readVariable(_var, m_currentBlock);\n\t\t}) | ranges::to<std::vector>\n\t};\n\tm_currentBlock = m_graph.makeBlock(currentBlockDebugData);\n\tsealBlock(m_currentBlock);\n}\n\nvoid SSACFGBuilder::registerFunctionDefinition(FunctionDefinition const& _functionDefinition)\n{\n\tyulAssert(m_scope, \"\");\n\tyulAssert(m_scope->identifiers.count(_functionDefinition.name), \"\");\n\tauto& function = std::get<Scope::Function>(m_scope->identifiers.at(_functionDefinition.name));\n\tm_graph.functions.emplace_back(function);\n\tm_functionDefinitions.emplace_back(&function, &_functionDefinition);\n}\n\nvoid SSACFGBuilder::operator()(Block const& _block)\n{\n\tScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get());\n\t// gather all function definitions so that they are visible to each other's subgraphs\n\tstatic constexpr auto functionDefinitionFilter = ranges::views::filter(\n\t\t[](auto const& _statement) { return std::holds_alternative<FunctionDefinition>(_statement); }\n\t);\n\tfor (auto const& statement: _block.statements | functionDefinitionFilter)\n\t\tregisterFunctionDefinition(std::get<FunctionDefinition>(statement));\n\t// now visit the rest\n\tfor (auto const& statement: _block.statements)\n\t\tstd::visit(*this, statement);\n}\n\nSSACFG::ValueId SSACFGBuilder::operator()(FunctionCall const& _call)\n{\n\tauto results = visitFunctionCall(_call);\n\tyulAssert(results.size() == 1);\n\treturn results.front();\n}\n\nSSACFG::ValueId SSACFGBuilder::operator()(Identifier const& _identifier)\n{\n\tauto const& var = lookupVariable(_identifier.name);\n\treturn readVariable(var, m_currentBlock);\n}\n\nSSACFG::ValueId SSACFGBuilder::operator()(Literal const& _literal)\n{\n\treturn m_graph.newLiteral(debugDataOf(currentBlock()), _literal.value.value());\n}\n\nvoid SSACFGBuilder::assign(std::vector<std::reference_wrapper<Scope::Variable const>> _variables, Expression const* _expression)\n{\n\tauto rhs = [&]() -> std::vector<SSACFG::ValueId> {\n\t\tif (auto const* functionCall = std::get_if<FunctionCall>(_expression))\n\t\t\treturn visitFunctionCall(*functionCall);\n\t\tif (_expression)\n\t\t\treturn {std::visit(*this, *_expression)};\n\t\treturn {_variables.size(), zero()};\n\t}();\n\tyulAssert(rhs.size() == _variables.size());\n\n\tfor (auto const& [var, value]: ranges::zip_view(_variables, rhs))\n\t{\n\t\tif (m_keepLiteralAssignments && value.isLiteral())\n\t\t{\n\t\t\tSSACFG::Operation assignment{\n\t\t\t\t.outputs = {m_graph.newVariable(m_currentBlock)},\n\t\t\t\t.kind = SSACFG::LiteralAssignment{},\n\t\t\t\t.inputs = {value}\n\t\t\t};\n\t\t\tcurrentBlock().operations.emplace_back(assignment);\n\t\t\twriteVariable(var, m_currentBlock, assignment.outputs.back());\n\t\t}\n\t\telse\n\t\t\twriteVariable(var, m_currentBlock, value);\n\t}\n\n}\n\nstd::vector<SSACFG::ValueId> SSACFGBuilder::visitFunctionCall(FunctionCall const& _call)\n{\n\tbool canContinue = true;\n\tSSACFG::Operation operation = std::visit(util::GenericVisitor{\n\t\t[&](BuiltinName const& _builtinName)\n\t\t{\n\t\t\tauto const& builtin = m_dialect.builtin(_builtinName.handle);\n\t\t\tSSACFG::Operation result{{}, SSACFG::BuiltinCall{_call.debugData, builtin, _call}, {}};\n\t\t\tfor (auto&& [idx, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse)\n\t\t\t\tif (!builtin.literalArgument(idx).has_value())\n\t\t\t\t\tresult.inputs.emplace_back(std::visit(*this, arg));\n\t\t\tfor (size_t i = 0; i < builtin.numReturns; ++i)\n\t\t\t\tresult.outputs.emplace_back(m_graph.newVariable(m_currentBlock));\n\t\t\tcanContinue = builtin.controlFlowSideEffects.canContinue;\n\t\t\treturn result;\n\t\t},\n\t\t[&](Identifier const& _identifier)\n\t\t{\n\t\t\tYulName const& functionName = _identifier.name;\n\t\t\tScope::Function const& function = lookupFunction(functionName);\n\t\t\tauto const* definition = findFunctionDefinition(&function);\n\t\t\tyulAssert(definition);\n\t\t\tcanContinue = m_sideEffects.functionSideEffects().at(definition).canContinue;\n\t\t\tSSACFG::Operation result{{}, SSACFG::Call{debugDataOf(_call), function, _call, canContinue}, {}};\n\t\t\tfor (auto const& arg: _call.arguments | ranges::views::reverse)\n\t\t\t\tresult.inputs.emplace_back(std::visit(*this, arg));\n\t\t\tfor (size_t i = 0; i < function.numReturns; ++i)\n\t\t\t\tresult.outputs.emplace_back(m_graph.newVariable(m_currentBlock));\n\t\t\treturn result;\n\t\t}\n\t}, _call.functionName);\n\tauto results = operation.outputs;\n\tcurrentBlock().operations.emplace_back(std::move(operation));\n\tif (!canContinue)\n\t{\n\t\tcurrentBlock().exit = SSACFG::BasicBlock::Terminated{};\n\t\tm_currentBlock = m_graph.makeBlock(debugDataOf(currentBlock()));\n\t\tsealBlock(m_currentBlock);\n\t}\n\treturn results;\n}\n\nSSACFG::ValueId SSACFGBuilder::zero()\n{\n\treturn m_graph.newLiteral(debugDataOf(currentBlock()), 0u);\n}\n\nSSACFG::ValueId SSACFGBuilder::readVariable(Scope::Variable const& _variable, SSACFG::BlockId _block)\n{\n\tif (auto const& def = currentDef(_variable, _block))\n\t\treturn *def;\n\treturn readVariableRecursive(_variable, _block);\n}\n\nSSACFG::ValueId SSACFGBuilder::readVariableRecursive(Scope::Variable const& _variable, SSACFG::BlockId _block)\n{\n\tauto& block = m_graph.block(_block);\n\tauto& info = blockInfo(_block);\n\n\tSSACFG::ValueId val;\n\tif (!info.sealed)\n\t{\n\t\t// incomplete block\n\t\tval = m_graph.newPhi(_block);\n\t\tblock.phis.insert(val);\n\t\tinfo.incompletePhis.emplace_back(val, _variable);\n\t}\n\telse if (block.entries.size() == 1)\n\t\t// one predecessor: no phi needed\n\t\tval = readVariable(_variable, *block.entries.begin());\n\telse\n\t{\n\t\t// Break potential cycles with operandless phi\n\t\tval = m_graph.newPhi(_block);\n\t\tblock.phis.insert(val);\n\t\twriteVariable(_variable, _block, val);\n\t\t// we call tryRemoveTrivialPhi explicitly opposed to what is presented in Algorithm 2, as our implementation\n\t\t// does not call it in addPhiOperands to avoid removing phis in unsealed blocks\n\t\tval = tryRemoveTrivialPhi(addPhiOperands(_variable, val));\n\t}\n\twriteVariable(_variable, _block, val);\n\treturn val;\n}\n\nSSACFG::ValueId SSACFGBuilder::addPhiOperands(Scope::Variable const& _variable, SSACFG::ValueId _phi)\n{\n\tfor (auto const& pred: m_graph.block(m_graph.phiInfo(_phi).block).entries)\n\t{\n\t\tauto const var = readVariable(_variable, pred);\n\t\tm_graph.phiInfo(_phi).arguments.emplace_back(var);\n\t}\n\t// we call tryRemoveTrivialPhi explicitly to avoid removing trivial phis in unsealed blocks\n\treturn _phi;\n}\n\nvoid SSACFGBuilder::writeVariable(Scope::Variable const& _variable, SSACFG::BlockId _block, SSACFG::ValueId _value)\n{\n\tcurrentDef(_variable, _block) = _value;\n}\n\nScope::Function const& SSACFGBuilder::lookupFunction(YulName _name) const\n{\n\tScope::Function const* function = nullptr;\n\tyulAssert(m_scope->lookup(_name, util::GenericVisitor{\n\t\t[](Scope::Variable&) { yulAssert(false, \"Expected function name.\"); },\n\t\t[&](Scope::Function& _function) { function = &_function; }\n\t}), \"Function name not found.\");\n\tyulAssert(function, \"\");\n\treturn *function;\n}\n\nScope::Variable const& SSACFGBuilder::lookupVariable(YulName _name) const\n{\n\tyulAssert(m_scope, \"\");\n\tScope::Variable const* var = nullptr;\n\tif (m_scope->lookup(_name, util::GenericVisitor{\n\t\t[&](Scope::Variable const& _var) { var = &_var; },\n\t\t[](Scope::Function const&)\n\t\t{\n\t\t\tyulAssert(false, \"Function not removed during desugaring.\");\n\t\t}\n\t}))\n\t{\n\t\tyulAssert(var);\n\t\treturn *var;\n\t};\n\tyulAssert(false, \"External identifier access unimplemented.\");\n}\n\nvoid SSACFGBuilder::sealBlock(SSACFG::BlockId _block)\n{\n\t// this method deviates from Algorithm 4 in the reference paper,\n\t// as it would lead to tryRemoveTrivialPhi being called on unsealed blocks\n\tauto& info = blockInfo(_block);\n\tyulAssert(!info.sealed, \"Trying to seal already sealed block.\");\n\tfor (auto&& [phi, variable] : info.incompletePhis)\n\t\taddPhiOperands(variable, phi);\n\tinfo.sealed = true;\n\tfor (auto& [phi, _]: info.incompletePhis)\n\t\tphi = tryRemoveTrivialPhi(phi);\n}\n\n\nvoid SSACFGBuilder::conditionalJump(\n\tlangutil::DebugData::ConstPtr _debugData,\n\tSSACFG::ValueId _condition,\n\tSSACFG::BlockId _nonZero,\n\tSSACFG::BlockId _zero\n)\n{\n\tcurrentBlock().exit = SSACFG::BasicBlock::ConditionalJump{\n\t\tstd::move(_debugData),\n\t\t_condition,\n\t\t_nonZero,\n\t\t_zero\n\t};\n\tm_graph.block(_nonZero).entries.insert(m_currentBlock);\n\tm_graph.block(_zero).entries.insert(m_currentBlock);\n\tm_currentBlock = {};\n}\n\nvoid SSACFGBuilder::jump(\n\tlangutil::DebugData::ConstPtr _debugData,\n\tSSACFG::BlockId _target\n)\n{\n\tcurrentBlock().exit = SSACFG::BasicBlock::Jump{std::move(_debugData), _target};\n\tyulAssert(!blockInfo(_target).sealed);\n\tm_graph.block(_target).entries.insert(m_currentBlock);\n\tm_currentBlock = _target;\n}\n\nFunctionDefinition const* SSACFGBuilder::findFunctionDefinition(Scope::Function const* _function) const\n{\n\tauto it = std::find_if(\n\t\t\tm_functionDefinitions.begin(),\n\t\t\tm_functionDefinitions.end(),\n\t\t\t[&_function](auto const& _entry) { return std::get<0>(_entry) == _function; }\n\t\t);\n\tif (it != m_functionDefinitions.end())\n\t\treturn std::get<1>(*it);\n\treturn nullptr;\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/SSACFGBuilder.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n* Transformation of a Yul AST into a control flow graph.\n*\n* Based on https://doi.org/10.1007/978-3-642-37051-9_6\n* Braun, Matthias, et al. \"Simple and efficient construction of static single assignment form.\"\n* Compiler Construction: 22nd International Conference, CC 2013,\n* ETAPS 2013, Rome, Italy, March 16-24, 2013. Proceedings 22. Springer Berlin Heidelberg, 2013.\n*\n* We have small deviations in Algorithms 2 and 4, as the paper's presentation leads to trivial phis being spuriously\n* removed from not yet sealed blocks via a call to addPhiOperands in Algorithm 4. Instead, we perform the deletion\n* of trivial phis only after a block has been sealed, i.e., all block's predecessors are present.\n*/\n#pragma once\n\n#include <libyul/backends/evm/ssa/ControlFlow.h>\n#include <libyul/ControlFlowSideEffectsCollector.h>\n#include <libyul/backends/evm/ssa/SSACFG.h>\n#include <stack>\n\nnamespace solidity::yul::ssa\n{\n\nclass SSACFGBuilder\n{\n\tSSACFGBuilder(\n\t\tControlFlow& _controlFlow,\n\t\tSSACFG& _graph,\n\t\tAsmAnalysisInfo const& _analysisInfo,\n\t\tControlFlowSideEffectsCollector const& _sideEffects,\n\t\tDialect const& _dialect,\n\t\tbool _keepLiteralAssignments\n\t);\npublic:\n\tSSACFGBuilder(SSACFGBuilder const&) = delete;\n\tSSACFGBuilder& operator=(SSACFGBuilder const&) = delete;\n\tstatic std::unique_ptr<ControlFlow> build(\n\t\tAsmAnalysisInfo const& _analysisInfo,\n\t\tDialect const& _dialect,\n\t\tBlock const& _block,\n\t\tbool _keepLiteralAssignments\n\t);\n\n\tvoid operator()(ExpressionStatement const& _statement);\n\tvoid operator()(Assignment const& _assignment);\n\tvoid operator()(VariableDeclaration const& _varDecl);\n\n\tvoid operator()(FunctionDefinition const&);\n\tvoid operator()(If const& _if);\n\tvoid operator()(Switch const& _switch);\n\tvoid operator()(ForLoop const&);\n\tvoid operator()(Break const&);\n\tvoid operator()(Continue const&);\n\tvoid operator()(Leave const&);\n\n\tvoid operator()(Block const& _block);\n\n\tSSACFG::ValueId operator()(FunctionCall const& _call);\n\tSSACFG::ValueId operator()(Identifier const& _identifier);\n\tSSACFG::ValueId operator()(Literal const& _literal);\n\nprivate:\n\tvoid cleanUnreachable();\n\tSSACFG::ValueId tryRemoveTrivialPhi(SSACFG::ValueId _phi);\n\tvoid assign(std::vector<std::reference_wrapper<Scope::Variable const>> _variables, Expression const* _expression);\n\tstd::vector<SSACFG::ValueId> visitFunctionCall(FunctionCall const& _call);\n\tvoid registerFunctionDefinition(FunctionDefinition const& _functionDefinition);\n\tvoid buildFunctionGraph(Scope::Function const* _function, FunctionDefinition const* _functionDefinition);\n\n\tSSACFG::ValueId zero();\n\tSSACFG::ValueId readVariable(Scope::Variable const& _variable, SSACFG::BlockId _block);\n\tSSACFG::ValueId readVariableRecursive(Scope::Variable const& _variable, SSACFG::BlockId _block);\n\tSSACFG::ValueId addPhiOperands(Scope::Variable const& _variable, SSACFG::ValueId _phi);\n\tvoid writeVariable(Scope::Variable const& _variable, SSACFG::BlockId _block, SSACFG::ValueId _value);\n\n\tControlFlow& m_controlFlow;\n\tSSACFG& m_graph;\n\tAsmAnalysisInfo const& m_info;\n\tControlFlowSideEffectsCollector const& m_sideEffects;\n\tDialect const& m_dialect;\n\tbool const m_keepLiteralAssignments;\n\tstd::vector<std::tuple<Scope::Function const*, FunctionDefinition const*>> m_functionDefinitions;\n\tSSACFG::BlockId m_currentBlock;\n\tSSACFG::BasicBlock& currentBlock() { return m_graph.block(m_currentBlock); }\n\tScope* m_scope = nullptr;\n\tScope::Function const& lookupFunction(YulName _name) const;\n\tScope::Variable const& lookupVariable(YulName _name) const;\n\n\tstruct BlockInfo {\n\t\tbool sealed = false;\n\t\tstd::vector<std::tuple<SSACFG::ValueId, std::reference_wrapper<Scope::Variable const>>> incompletePhis;\n\t};\n\tstd::vector<BlockInfo> m_blockInfo;\n\n\tBlockInfo& blockInfo(SSACFG::BlockId _block)\n\t{\n\t\tif (_block.value >= m_blockInfo.size())\n\t\t\tm_blockInfo.resize(_block.value + 1, {});\n\t\treturn m_blockInfo[_block.value];\n\t}\n\tvoid sealBlock(SSACFG::BlockId _block);\n\n\tstd::map<\n\t\tScope::Variable const*,\n\t\tstd::vector<std::optional<SSACFG::ValueId>>\n\t> m_currentDef;\n\n\tstruct ForLoopInfo {\n\t\tSSACFG::BlockId breakBlock;\n\t\tSSACFG::BlockId continueBlock;\n\t};\n\tstd::stack<ForLoopInfo> m_forLoopInfo;\n\n\tstd::optional<SSACFG::ValueId>& currentDef(Scope::Variable const& _variable, SSACFG::BlockId _block)\n\t{\n\t\tauto& varDefs = m_currentDef[&_variable];\n\t\tif (varDefs.size() <= _block.value)\n\t\t\tvarDefs.resize(_block.value + 1);\n\t\treturn varDefs.at(_block.value);\n\t}\n\n\tvoid conditionalJump(\n\t\tlangutil::DebugData::ConstPtr _debugData,\n\t\tSSACFG::ValueId _condition,\n\t\tSSACFG::BlockId _nonZero,\n\t\tSSACFG::BlockId _zero\n\t);\n\n\tvoid jump(\n\t\tlangutil::DebugData::ConstPtr _debugData,\n\t\tSSACFG::BlockId _target\n\t);\n\n\tFunctionDefinition const* findFunctionDefinition(Scope::Function const* _function) const;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/SSACFGLoopNestingForest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/SSACFGLoopNestingForest.h>\n\n#include <range/v3/algorithm/reverse.hpp>\n\nusing namespace solidity::yul::ssa;\n\nSSACFGLoopNestingForest::SSACFGLoopNestingForest(traversal::ForwardTopologicalSort const& _sort):\n\tm_sort(_sort),\n\tm_cfg(_sort.cfg()),\n\tm_vertexPartition(m_cfg.numBlocks()),\n\tm_loopParents(m_cfg.numBlocks(), std::numeric_limits<BlockIdValue>::max())\n{\n\tauto dfsOrder = m_sort.preOrder();\n\t// we go from innermost to outermost\n\tranges::reverse(dfsOrder);\n\n\tfor (auto const& blockId: dfsOrder)\n\t\tfindLoop(blockId);\n\n\t// get the root nodes\n\tfor (auto loopHeader: m_loopNodes)\n\t{\n\t\twhile (m_loopParents[loopHeader] != std::numeric_limits<BlockIdValue>::max())\n\t\t\tloopHeader = m_loopParents[loopHeader];\n\t\tm_loopRootNodes.insert(loopHeader);\n\t}\n}\n\nvoid SSACFGLoopNestingForest::findLoop(BlockIdValue const _potentialHeader)\n{\n\tif (m_sort.backEdgeTargets().contains(_potentialHeader))\n\t{\n\t\tstd::set<BlockIdValue> loopBody;\n\t\tstd::set<BlockIdValue> workList;\n\t\tfor (auto const pred: m_cfg.block(SSACFG::BlockId{_potentialHeader}).entries)\n\t\t{\n\t\t\tauto const representative = m_vertexPartition.find(pred.value);\n\t\t\tif (\n\t\t\t\trepresentative != _potentialHeader &&\n\t\t\t\tm_sort.backEdge(SSACFG::BlockId{pred}, SSACFG::BlockId{_potentialHeader})\n\t\t\t)\n\t\t\t\tworkList.insert(representative);\n\t\t}\n\n\t\twhile (!workList.empty())\n\t\t{\n\t\t\tauto const y = workList.extract(workList.begin()).value();\n\t\t\tloopBody.insert(y);\n\n\t\t\tfor (auto const& predecessor: m_cfg.block(SSACFG::BlockId{y}).entries)\n\t\t\t{\n\t\t\t\tif (!m_sort.backEdge(SSACFG::BlockId{predecessor}, SSACFG::BlockId{y}))\n\t\t\t\t{\n\t\t\t\t\tauto const predecessorHeader = m_vertexPartition.find(predecessor.value);\n\t\t\t\t\tif (predecessorHeader != _potentialHeader && loopBody.count(predecessorHeader) == 0)\n\t\t\t\t\t\tworkList.insert(predecessorHeader);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!loopBody.empty())\n\t\t\tcollapse(loopBody, _potentialHeader);\n\t}\n}\nvoid SSACFGLoopNestingForest::collapse(std::set<BlockIdValue> const& _loopBody, BlockIdValue _loopHeader)\n{\n\tfor (auto const z: _loopBody)\n\t{\n\t\tm_loopParents[z] = _loopHeader;\n\t\tm_vertexPartition.merge(_loopHeader, z, false);  // don't merge by size, loop header should be representative\n\t}\n\tyulAssert(m_vertexPartition.find(_loopHeader) == _loopHeader);  // representative was preserved\n\tm_loopNodes.insert(_loopHeader);\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/SSACFGLoopNestingForest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/traversal/ForwardTopologicalSort.h>\n#include <libyul/backends/evm/ssa/SSACFG.h>\n\n#include <libsolutil/DisjointSet.h>\n\n#include <cstddef>\n#include <set>\n#include <vector>\n\nnamespace solidity::yul::ssa\n{\n\n/// Constructs a loop nesting forest for an SSACFG using Tarjan's algorithm [1].\n///\n/// [1] Ramalingam, Ganesan. \"Identifying loops in almost linear time.\"\n///     ACM Transactions on Programming Languages and Systems (TOPLAS) 21.2 (1999): 175-188.\nclass SSACFGLoopNestingForest\n{\n\tusing BlockIdValue = SSACFG::BlockId::ValueType;\n\npublic:\n\texplicit SSACFGLoopNestingForest(traversal::ForwardTopologicalSort const& _sort);\n\n\t/// blocks which are not contained in a loop get assigned the loop parent numeric_limit<size_t>::max()\n\tstd::vector<BlockIdValue> const& loopParents() const { return m_loopParents; }\n\t/// all loop nodes (entry blocks for loops), also nested ones\n\tstd::set<BlockIdValue> const& loopNodes() const { return m_loopNodes; }\n\t/// root loop nodes in the forest for outer-most loops\n\tstd::set<BlockIdValue> const& loopRootNodes() const { return m_loopRootNodes; }\nprivate:\n\tvoid findLoop(BlockIdValue _potentialHeader);\n\tvoid collapse(std::set<BlockIdValue> const& _loopBody, BlockIdValue _loopHeader);\n\n\ttraversal::ForwardTopologicalSort const& m_sort;\n\tSSACFG const& m_cfg;\n\n\tutil::ContiguousDisjointSet<BlockIdValue> m_vertexPartition;\n\tstd::vector<BlockIdValue> m_loopParents;\n\tstd::set<BlockIdValue> m_loopNodes;\n\tstd::set<BlockIdValue> m_loopRootNodes;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/Stack.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/Stack.h>\n\n#include <fmt/format.h>\n#include <fmt/ranges.h>\n\nnamespace solidity::yul::ssa\n{\n\nstd::string slotToString(StackSlot const& _slot)\n{\n\tswitch (_slot.kind())\n\t{\n\tcase StackSlot::Kind::ValueID:\n\t\treturn fmt::format(\"{}\", _slot.valueID());\n\tcase StackSlot::Kind::Junk:\n\t\treturn \"JUNK\";\n\tcase StackSlot::Kind::FunctionCallReturnLabel:\n\t\treturn fmt::format(\"FunctionCallReturnLabel[{}]\", _slot.functionCallReturnLabel());\n\tcase StackSlot::Kind::FunctionReturnLabel:\n\t\treturn fmt::format(\"ReturnLabel[{}]\", _slot.functionReturnLabel());\n\t}\n\tutil::unreachable();\n}\n\nstd::string stackToString(StackData const& _stackData)\n{\n\treturn fmt::format(\n\t\t\"[{}]\",\n\t\tfmt::join(_stackData | ranges::views::transform([&](auto const& _slot) { return slotToString(_slot); }), \", \")\n\t);\n}\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/Stack.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/ControlFlow.h>\n#include <libyul/backends/evm/ssa/SSACFG.h>\n\n#include <range/v3/algorithm/find.hpp>\n#include <range/v3/view/reverse.hpp>\n\n#include <cstdint>\n#include <type_traits>\n\nnamespace solidity::yul\n{\n\nstruct FunctionCall;\n\nnamespace ssa\n{\n\n/// Registry for tracking function call sites.\n///\n/// Maps FunctionCall AST nodes to unique numeric IDs. These IDs are used\n/// to generate return labels for function calls in the EVM bytecode.\nclass CallSites\n{\npublic:\n\tusing CallSiteID = std::uint32_t;\n\n\tstd::optional<CallSiteID> callSiteID(FunctionCall const* _functionCall) const\n\t{\n\t\tif (auto const it = ranges::find(m_data, _functionCall); it != m_data.end())\n\t\t\treturn static_cast<CallSiteID>(std::distance(m_data.begin(), it));\n\t\treturn std::nullopt;\n\t}\n\n\tFunctionCall const& functionCall(CallSiteID _callSite) const\n\t{\n\t\tyulAssert(_callSite < m_data.size());\n\t\treturn *m_data[_callSite];\n\t}\n\n\tCallSiteID addCallSite(FunctionCall const* _functionCall)\n\t{\n\t\tif (auto const id = callSiteID(_functionCall))\n\t\t\treturn *id;\n\t\tyulAssert(_functionCall);\n\t\tm_data.emplace_back(_functionCall);\n\t\treturn static_cast<CallSiteID>(m_data.size() - 1);\n\t}\nprivate:\n\tstd::vector<FunctionCall const*> m_data;\n};\n\n/// A discriminated union corresponding to a single EVM stack slot.\n/// Can represent:\n///\t\t- ValueID: SSA values (including literals)\n///\t\t- Junk: Placeholder/unused values\n///     - FunctionCallReturnLabel: Return addresses for function calls\n///     - FunctionReturnLabel: Identifies the calling function's graph\n///\n/// Memory layout is optimized: 8 bytes size for cache efficiency, trivially copyable, standard layout, trivial\nclass StackSlot\n{\npublic:\n\tenum struct Kind: std::uint8_t\n\t{\n\t\tValueID, // u32\n\t\tJunk, // empty\n\t\tFunctionCallReturnLabel, // index into corresponding stack layout's call sites\n\t\tFunctionReturnLabel // identifying the function graph via ControlFlow\n\t};\n\n\tconstexpr StackSlot() = default;\n\tconstexpr StackSlot(StackSlot const&) = default;\n\tconstexpr StackSlot(StackSlot&&) = default;\n\tconstexpr StackSlot& operator=(StackSlot const&) = default;\n\tconstexpr StackSlot& operator=(StackSlot&&) = default;\n\n\tconstexpr bool isValueID() const noexcept { return kind() == Kind::ValueID; }\n\tconstexpr bool isLiteralValueID() const noexcept { return m_valueIdKind == SSACFG::ValueId::Kind::Literal; }\n\tconstexpr bool isFunctionReturnLabel() const noexcept { return kind() == Kind::FunctionReturnLabel; }\n\tconstexpr bool isFunctionCallReturnLabel() const noexcept { return kind() == Kind::FunctionCallReturnLabel; }\n\tconstexpr bool isJunk() const noexcept { return kind() == Kind::Junk; }\n\tconstexpr Kind kind() const noexcept { return m_kind; }\n\n\tControlFlow::FunctionGraphID functionReturnLabel() const { yulAssert(isFunctionReturnLabel()); return m_payload; }\n\tCallSites::CallSiteID functionCallReturnLabel() const { yulAssert(isFunctionCallReturnLabel()); return m_payload; }\n\tSSACFG::ValueId valueID() const { yulAssert(isValueID()); return {m_payload, m_valueIdKind}; }\n\n\tstatic constexpr StackSlot makeJunk() { return {0, Kind::Junk}; }\n\tstatic constexpr StackSlot makeValueID(SSACFG::ValueId const& _valueID) { return {_valueID.value(), Kind::ValueID, _valueID.kind()}; }\n\tstatic constexpr StackSlot makeFunctionReturnLabel(ControlFlow::FunctionGraphID const _graphID) { return {_graphID, Kind::FunctionReturnLabel}; }\n\tstatic constexpr StackSlot makeFunctionCallReturnLabel(CallSites::CallSiteID const _callSiteID) { return {_callSiteID, Kind::FunctionCallReturnLabel};\t}\n\n\tauto operator<=>(StackSlot const&) const = default;\nprivate:\n\tconstexpr StackSlot(std::uint32_t const _payload, Kind const _kind, SSACFG::ValueId::Kind const _valueIdKind = SSACFG::ValueId::Kind::Unreachable):\n\t\tm_payload(_payload),\n\t\tm_kind(_kind),\n\t\tm_valueIdKind(_valueIdKind)\n\t{}\n\n\t/// interpretation depends on kind\n\tstd::uint32_t m_payload;\n\tKind m_kind;\n\tSSACFG::ValueId::Kind m_valueIdKind;\n};\nstatic_assert(sizeof(StackSlot) == 8, \"Want cache efficiency, benchmark this if you go beyond 8 bytes\");\nstatic_assert(std::is_trivially_copyable_v<StackSlot>, \"Should be able to use memcpy semantics\");\nstatic_assert(std::is_standard_layout_v<StackSlot>, \"Want to have a predictable layout\");\nstatic_assert(std::is_trivial_v<StackSlot>, \"Want to have no init/cpy overhead\");\n\nusing StackData = std::vector<StackSlot>;\nstd::string slotToString(StackSlot const& _slot);\nstd::string stackToString(StackData const& _stackData);\n\n/// Array index into stack from the bottom (offset 0 = bottom).\n/// Natural for array-like access and iteration; used when treating the stack as a data structure.\nstruct StackOffset\n{\n\texplicit constexpr StackOffset(size_t _value) : value(_value) {}\n\tsize_t value;\n\tauto operator<=>(StackOffset const&) const = default;\n};\n// comparison operations with size_t\nconstexpr auto operator<=>(StackOffset const lhs, size_t const rhs) noexcept { return lhs.value <=> rhs; }\nconstexpr auto operator<=>(size_t const lhs, StackOffset const rhs) noexcept { return lhs <=> rhs.value; }\n\n/// Distance from the stack top (depth 0 = top).\n/// Natural for stack operations (SWAP1 = swap with depth 1); used for operations that\n/// conceptually work \"from the top\".\nstruct StackDepth\n{\n\texplicit constexpr StackDepth(size_t _value) : value(_value) {}\n\tsize_t value;\n\tauto operator<=>(StackDepth const&) const = default;\n};\n// comparison operations with size_t\nconstexpr auto operator<=>(StackDepth const lhs, size_t const rhs) noexcept { return lhs.value <=> rhs; }\nconstexpr auto operator<=>(size_t const lhs, StackDepth const rhs) noexcept { return lhs <=> rhs.value; }\n\ntemplate<typename StackManipulationCallback>\nconcept StackManipulationCallbackConcept = requires(\n\tStackManipulationCallback& _callback,\n\tStackSlot _slot,\n\tStackDepth _depth\n)\n{\n\t{ _callback.swap(_depth) } -> std::same_as<void>;\n\t{ _callback.dup(_depth) } -> std::same_as<void>;\n\t{ _callback.push(_slot) } -> std::same_as<void>;\n\t{ _callback.pop() } -> std::same_as<void>;\n};\n\nstruct NoOpStackManipulationCallbacks\n{\n\tstatic void swap(StackDepth) {}\n\tstatic void dup(StackDepth) {}\n\tstatic void push(StackSlot const&) {}\n\tstatic void pop() {}\n};\nstatic_assert(StackManipulationCallbackConcept<NoOpStackManipulationCallbacks>);\n\ntemplate<\n\tStackManipulationCallbackConcept CallbacksType = NoOpStackManipulationCallbacks\n>\nclass Stack\n{\n\tstatic size_t constexpr reachableStackDepth = 16;\npublic:\n\tusing Callbacks = CallbacksType;\n\n\tusing Slot = StackSlot;\n\tusing Data = StackData;\n\tusing Depth = StackDepth;\n\tusing Offset = StackOffset;\n\n\tStack(\n\t\tData& _data,\n\t\tCallbacks _callbacks\n\t):\n\t\tm_data(&_data),\n\t\tm_callbacks(std::move(_callbacks))\n\t{}\n\n\tSlot const& top() const\n\t{\n\t\tyulAssert(!m_data->empty());\n\t\treturn m_data->back();\n\t}\n\n\tvoid swap(Depth const& _depth) { swap(depthToOffset(_depth)); }\n\tvoid swap(Offset const& _offset)\n\t{\n\t\tyulAssert(swapReachable(_offset), \"Stack too deep\");\n\t\tstd::swap((*m_data)[_offset.value], m_data->back());\n\t\tif constexpr (!std::is_same_v<Callbacks, NoOpStackManipulationCallbacks>)\n\t\t\tm_callbacks.swap(offsetToDepth(_offset));\n\t}\n\n\t/// if the stack state needs to be updated without notifying the callback, the template parameter can be set to false\n\ttemplate<bool callback=true>\n\tvoid pop()\n\t{\n\t\tyulAssert(!m_data->empty());\n\t\tm_data->pop_back();\n\t\tif constexpr (callback && !std::is_same_v<Callbacks, NoOpStackManipulationCallbacks>)\n\t\t\tm_callbacks.pop();\n\t}\n\n\t/// if the stack state needs to be updated without notifying the callback, the template parameter can be set to false\n\ttemplate<bool callback=true>\n\tvoid push(Slot const& _slot)\n\t{\n\t\tyulAssert(!_slot.isFunctionReturnLabel(), \"Cannot push function return label\");\n\t\tm_data->emplace_back(_slot);\n\t\tif constexpr (callback && !std::is_same_v<Callbacks, NoOpStackManipulationCallbacks>)\n\t\t\tm_callbacks.push(_slot);\n\t}\n\n\tvoid dup(Depth const& _depth) { dup(depthToOffset(_depth)); }\n\tvoid dup(Offset const& _offset)\n\t{\n\t\tauto const depth = offsetToDepth(_offset);\n\t\tyulAssert(dupReachable(depth), \"Stack too deep\");\n\t\tauto const slot = (*m_data)[_offset.value];\n\t\tyulAssert(!slot.isFunctionReturnLabel(), \"Cannot dup function return label\");\n\t\tm_data->push_back(slot);\n\t\tif constexpr (!std::is_same_v<Callbacks, NoOpStackManipulationCallbacks>)\n\t\t\tm_callbacks.dup(StackDepth{depth.value + 1});\n\t}\n\n\tbool dupReachable(Offset const& _offset) const noexcept { return dupReachable(offsetToDepth(_offset)); }\n\tbool dupReachable(Depth const& _depth) const noexcept { return _depth < size() && _depth.value + 1 <= reachableStackDepth; }\n\tbool swapReachable(Offset const& _offset) const noexcept { return swapReachable(offsetToDepth(_offset)); }\n\tbool swapReachable(Depth const& _depth) const noexcept { return _depth < size() && 1 <= _depth.value && _depth.value <= reachableStackDepth; }\n\n\tvoid declareJunk(Offset const& _offset) { (*m_data)[_offset.value] = Slot::makeJunk(); }\n\tvoid declareJunk(Depth const& _depth) { declareJunk(depthToOffset(_depth)); }\n\n\tSlot const& slot(Depth const& _depth) const { return (*m_data)[depthToOffset(_depth).value]; }\n\tSlot const& slot(Offset const& _offset) const { return slot(offsetToDepth(_offset)); }\n\tbool empty() const noexcept { return size() == 0; }\n\tsize_t size() const noexcept { return m_data->size(); }\n\n\tstd::optional<Depth> findSlotDepth(Slot const& _value) const\n\t{\n\t\tauto rview = *this | ranges::views::reverse;\n\t\tauto it = ranges::find(rview, _value);\n\n\t\tif (it == ranges::end(rview))\n\t\t\treturn std::nullopt;\n\n\t\treturn Depth{static_cast<size_t>(std::distance(ranges::begin(rview), it))};\n\t}\n\n\tstatic bool constexpr canBeFreelyGenerated(Slot const& _slot)\n\t{\n\t\treturn _slot.isLiteralValueID() || _slot.isJunk() || _slot.isFunctionCallReturnLabel();\n\t}\n\n\tSlot const& operator[](Offset const& _index) const noexcept { return (*m_data)[_index.value]; }\n\tauto begin() const { return ranges::begin(*m_data); }\n\tauto end() const { return ranges::end(*m_data); }\n\n\tData const& data() const\n\t{\n\t\treturn *m_data;\n\t}\n\n\tCallbacks const& callbacks() const { return m_callbacks; }\n\n\t/// index scheme conversion offset -> depth\n\tDepth offsetToDepth(Offset const& _offset) const\n\t{\n\t\tyulAssert(_offset < size(), \"Offset out of range\");\n\t\treturn Depth{size() - _offset.value - 1};\n\t}\n\t/// index scheme conversion depth -> offset\n\tOffset depthToOffset(Depth const& _depth) const\n\t{\n\t\tyulAssert(_depth < size(), \"Depth out of range\");\n\t\treturn Offset{size() - _depth.value - 1};\n\t}\n\nprivate:\n\tData* m_data;\n\tCallbacks m_callbacks;\n};\n\n}\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/StackLayout.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/Stack.h>\n\n#include <vector>\n\nnamespace solidity::yul::ssa\n{\n\nstruct BlockLayout\n{\n\t// stack layout required to enter the block\n\tStackData stackIn;\n\t// stack layout required to execute the i-th operation in the block\n\tstd::vector<StackData> operationIn;\n\t// stack after the block was executed\n\tStackData stackOut;\n};\n\n/// For each (reachable) block in the SSACFG one block layout\nclass SSACFGStackLayout\n{\npublic:\n\tSSACFGStackLayout(std::size_t const _numBlocks): m_blockLayouts(_numBlocks) {}\n\n\tstd::optional<BlockLayout>& operator[](SSACFG::BlockId const& _blockId)\n\t{\n\t\tyulAssert(_blockId.hasValue() && _blockId.value < m_blockLayouts.size());\n\t\treturn m_blockLayouts[_blockId.value];\n\t}\n\n\tstd::optional<BlockLayout> const& operator[](SSACFG::BlockId const& _blockId) const\n\t{\n\t\tyulAssert(_blockId.hasValue() && _blockId.value < m_blockLayouts.size());\n\t\treturn m_blockLayouts[_blockId.value];\n\t}\n\nprivate:\n\tstd::vector<std::optional<BlockLayout>> m_blockLayouts;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/StackLayoutGenerator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/StackLayoutGenerator.h>\n\n#include <libyul/backends/evm/ssa/JunkAdmittingBlocksFinder.h>\n#include <libyul/backends/evm/ssa/PhiInverse.h>\n#include <libyul/backends/evm/ssa/StackShuffler.h>\n#include <libyul/backends/evm/ssa/StackUtils.h>\n\n#include <range/v3/algorithm/count.hpp>\n#include <range/v3/algorithm/min_element.hpp>\n#include <range/v3/algorithm/replace.hpp>\n#include <range/v3/view/transform.hpp>\n#include <range/v3/to_container.hpp>\n\n#include <boost/container/flat_map.hpp>\n#include <queue>\n\nusing namespace solidity::yul::ssa;\n\nnamespace\n{\nvoid handlePhiFunctions(StackData& _stackData, PhiInverse const& _phiInverse, LivenessAnalysis::LivenessData const& _liveness)\n{\n\t// add any phi function values here that are not already contained in the stack\n\tfor (auto const& [phi, preImage]: _phiInverse.data())\n\t{\n\t\tauto reversedStackData = _stackData | ranges::views::reverse;\n\t\tauto it = ranges::find(reversedStackData, StackSlot::makeValueID(preImage));\n\t\tif (_liveness.contains(preImage))\n\t\t{\n\t\t\t// Both the phi function and the preimage are part of the live-in set.\n\t\t\t// If the preimage occurs more than once on the stack, one occurrence is\n\t\t\t// symbolically replaced by the phi function; otherwise, we push the phi value.\n\t\t\tif (ranges::count(_stackData, StackSlot::makeValueID(preImage)) > 1)\n\t\t\t\t*it = StackSlot::makeValueID(phi);\n\t\t\telse\n\t\t\t\t_stackData.emplace_back(StackSlot::makeValueID(phi));\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// replace all occurrences of the preimage with the phi value\n\t\t\tranges::replace(_stackData, StackSlot::makeValueID(preImage), StackSlot::makeValueID(phi));\n\t\t\t// if it's not contained, push it (could be derived from a literal)\n\t\t\tif (it == ranges::end(reversedStackData))\n\t\t\t\t_stackData.emplace_back(StackSlot::makeValueID(phi));\n\t\t}\n\t}\n}\n\nusing StackType = Stack<CountingInstructionsCallbacks>;\n\nvoid declareJunk(StackType& _stack, LivenessAnalysis::LivenessData const& _live)\n{\n\tfor (StackOffset offset{0}; offset < _stack.size(); ++offset.value)\n\t{\n\t\tauto const& slot = _stack[offset];\n\t\tif (slot.isValueID() && !_live.contains(slot.valueID()))\n\t\t\t_stack.declareJunk(offset);\n\t}\n}\n\n}\n\nSSACFGStackLayout StackLayoutGenerator::generate(\n\tLivenessAnalysis const& _liveness,\n\tCallSites const& _callSites,\n\tControlFlow::FunctionGraphID const _graphID\n)\n{\n\treturn StackLayoutGenerator(_liveness, _callSites, _graphID).m_resultLayout;\n}\n\nStackLayoutGenerator::StackLayoutGenerator(\n\tLivenessAnalysis const& _liveness,\n\tCallSites const& _callSites,\n\tControlFlow::FunctionGraphID const _graphID\n):\n\tm_cfg(_liveness.cfg()),\n\tm_liveness(_liveness),\n\tm_callSites(_callSites),\n\tm_graphID(_graphID),\n\tm_hasFunctionReturnLabel(_liveness.cfg().function && _liveness.cfg().canContinue),\n\tm_junkAdmittingBlocksFinder(std::make_unique<JunkAdmittingBlocksFinder>(_liveness.cfg(), _liveness.topologicalSort())),\n\tm_resultLayout(m_cfg.numBlocks())\n{\n\t// traverse the cfg layer-wise using Kahn's algorithm:\n\t// if a block is visited, the predecessors of that block have already their exit layouts defined\n\t// with minor exceptions when dealing with back-edges\n\t{\n\t\t// Future optimization: it might be beneficial to revisit the loop heads (back edge targets) after the first iteration\n\t\tstd::vector<std::size_t> inDegreesIgnoringBackedges(m_cfg.numBlocks(), 0);\n\n\t\tfor (SSACFG::BlockId id{0}; id.value < m_cfg.numBlocks(); ++id.value)\n\t\t\tfor (auto const& entry: m_cfg.block(id).entries)\n\t\t\t\tif (!m_liveness.topologicalSort().backEdge(entry, id))\n\t\t\t\t\tinDegreesIgnoringBackedges[id.value] += 1;\n\n\t\tstd::queue<SSACFG::BlockId> traversalQueue;\n\t\ttraversalQueue.push(m_cfg.entry);\n\n\t\tstd::size_t numVisited = 0;\n\t\twhile (!traversalQueue.empty())\n\t\t{\n\t\t\tauto currentBlockId = traversalQueue.front();\n\t\t\ttraversalQueue.pop();\n\n\t\t\tvisitBlock(currentBlockId);\n\n\t\t\tm_cfg.block(currentBlockId).forEachExit([&](SSACFG::BlockId const& _exit){\n\t\t\t\tif (--inDegreesIgnoringBackedges[_exit.value] == 0)\n\t\t\t\t\ttraversalQueue.push(_exit);\n\t\t\t});\n\t\t\t++numVisited;\n\t\t}\n\t\tyulAssert(numVisited == m_liveness.topologicalSort().preOrder().size());\n\t}\n}\n\nvoid StackLayoutGenerator::defineStackIn(SSACFG::BlockId const& _blockId)\n{\n\t// we already have an input layout defined, return\n\tif (m_resultLayout[_blockId])\n\t\treturn;\n\tBlockLayout blockLayout{};\n\n\tif (_blockId == m_cfg.entry)\n\t{\n\t\tif (m_cfg.function)\n\t\t{\n\t\t\tblockLayout.stackIn.reserve(m_cfg.arguments.size() + (m_hasFunctionReturnLabel ? 1u : 0u));\n\t\t\tif (m_hasFunctionReturnLabel)\n\t\t\t\tblockLayout.stackIn.push_back(Slot::makeFunctionReturnLabel(m_graphID));\n\t\t\tfor (auto const& [_, valueID]: m_cfg.arguments | ranges::views::reverse)\n\t\t\t\tblockLayout.stackIn.push_back(Slot::makeValueID(valueID));\n\t\t}\n\t\tm_resultLayout[_blockId] = blockLayout;\n\t\treturn;\n\t}\n\n\tauto const& block = m_cfg.block(_blockId);\n\n\tstd::vector<std::pair<SSACFG::BlockId, StackData const*>> parentExits;\n\tfor (auto const& entry: block.entries)\n\t\tif (m_resultLayout[entry])\n\t\t\tparentExits.emplace_back(entry, &m_resultLayout[entry]->stackOut);\n\n\tyulAssert(!parentExits.empty(), fmt::format(\"None of the parents of block {} were generated\", _blockId));\n\n\tif (block.entries.size() == 1)\n\t{\n\t\t// pass through\n\t\tyulAssert(parentExits.size() == 1);\n\t\tblockLayout.stackIn = *parentExits[0].second;\n\n\t\tif (!block.phis.empty())\n\t\t\thandlePhiFunctions(blockLayout.stackIn, PhiInverse(m_cfg, parentExits[0].first, _blockId), m_liveness.liveIn(_blockId));\n\t}\n\telse\n\t{\n\t\t// we have more than one entry and need to unify or at the very least apply phi fct.\n\t\tauto const& liveIn = m_liveness.liveIn(_blockId);\n\t\t// Pre-compute each parent's phi-term proposal (declareJunk + handlePhiFunctions) once\n\t\tstd::vector<StackData> proposals(parentExits.size());\n\t\tfor (std::size_t i = 0; i < parentExits.size(); ++i)\n\t\t{\n\t\t\tif (!parentExits[i].second)\n\t\t\t\tcontinue;\n\t\t\tproposals[i] = *parentExits[i].second;\n\t\t\t{\n\t\t\t\tStackType stack(proposals[i], {});\n\t\t\t\tdeclareJunk(stack, liveIn);\n\t\t\t}\n\t\t\thandlePhiFunctions(proposals[i], PhiInverse(m_cfg, parentExits[i].first, _blockId), liveIn);\n\t\t}\n\t\tstd::vector cumulativeCosts(parentExits.size(), std::numeric_limits<std::size_t>::max());\n\t\tfor (std::size_t i = 0; i < parentExits.size(); ++i)\n\t\t{\n\t\t\tif (!parentExits[i].second)\n\t\t\t\tcontinue;\n\t\t\tstd::size_t cumulativeCost = 0;\n\t\t\tfor (std::size_t j = 0; j < parentExits.size(); ++j)\n\t\t\t{\n\t\t\t\tif (j == i || !parentExits[j].second)\n\t\t\t\t\tcontinue;\n\t\t\t\tauto proposalCopy = proposals[j];\n\t\t\t\tStackType stack(proposalCopy, {});\n\t\t\t\tStackShuffler<StackType::Callbacks>::shuffle(\n\t\t\t\t\tstack,\n\t\t\t\t\tproposals[i],\n\t\t\t\t\t{},\n\t\t\t\t\tproposals[i].size()\n\t\t\t\t);\n\t\t\t\tcumulativeCost += stack.callbacks().numOps;\n\t\t\t}\n\t\t\tcumulativeCosts[i] = cumulativeCost;\n\t\t}\n\t\tauto const argMin = static_cast<std::size_t>(\n\t\t\tstd::distance(cumulativeCosts.begin(), ranges::min_element(cumulativeCosts))\n\t\t);\n\t\tyulAssert(parentExits[argMin].second);\n\t\tblockLayout.stackIn = std::move(proposals[argMin]);\n\t}\n\tm_resultLayout[_blockId] = blockLayout;\n}\n\nvoid StackLayoutGenerator::visitBlock(SSACFG::BlockId const& _blockId)\n{\n\tdefineStackIn(_blockId);\n\tyulAssert(m_resultLayout[_blockId]);\n\tBlockLayout& blockLayout = *m_resultLayout[_blockId];\n\n\tSSACFG::BasicBlock const& block = m_cfg.block(_blockId);\n\n\tStackData currentStackData = blockLayout.stackIn;\n\tStackType stack(currentStackData, {});\n\tbool const junkCanBeAdded = m_junkAdmittingBlocksFinder->allowsAdditionOfJunk(_blockId);\n\n\tauto const& operationsLiveOut = m_liveness.operationsLiveOut(_blockId);\n\tblockLayout.operationIn.reserve(block.operations.size());\n\tfor (std::size_t operationIndex = 0; operationIndex < block.operations.size(); ++operationIndex)\n\t{\n\t\tSSACFG::Operation const& operation = block.operations[operationIndex];\n\t\tLivenessAnalysis::LivenessData opLiveOut = operationsLiveOut[operationIndex];\n\t\tauto opLiveOutWithoutOutputs = opLiveOut;\n\t\tfor (auto const& output: operation.outputs)\n\t\t\topLiveOutWithoutOutputs.erase(output);\n\n\t\tstd::vector<Slot> requiredStackTop;\n\t\tif (auto const* call = std::get_if<SSACFG::Call>(&operation.kind))\n\t\t\tif (call->canContinue)\n\t\t\t{\n\t\t\t\tauto const callSiteID = m_callSites.callSiteID(&call->call.get());\n\t\t\t\tyulAssert(callSiteID.has_value());\n\t\t\t\trequiredStackTop.emplace_back(Slot::makeFunctionCallReturnLabel(*callSiteID));\n\t\t\t}\n\t\trequiredStackTop += operation.inputs | ranges::views::transform(Slot::makeValueID);\n\n\t\tfor (StackType::Depth depth{0}; depth < stack.size(); ++depth.value)\n\t\t\tif (\n\t\t\t\tstack.slot(depth).isValueID() &&\n\t\t\t\t!opLiveOutWithoutOutputs.contains(stack.slot(depth).valueID()) &&\n\t\t\t\tranges::find(requiredStackTop, stack.slot(depth)) == ranges::end(requiredStackTop)\n\t\t\t)\n\t\t\t\tstack.declareJunk(depth);\n\n\t\tstd::size_t const targetSize = findOptimalTargetSize(stack.data(), requiredStackTop, opLiveOutWithoutOutputs, junkCanBeAdded, m_hasFunctionReturnLabel);\n\t\tStackShuffler<StackType::Callbacks>::shuffle(\n\t\t\tstack,\n\t\t\trequiredStackTop,\n\t\t\topLiveOutWithoutOutputs,\n\t\t\ttargetSize\n\t\t);\n\n\t\tblockLayout.operationIn.push_back(currentStackData);\n\t\tfor (std::size_t i = 0; i < requiredStackTop.size(); ++i)\n\t\t\tstack.pop();\n\t\tfor (auto const& val: operation.outputs)\n\t\t\tstack.push(Slot::makeValueID(val));\n\t}\n\n\tif (auto const* cjump = std::get_if<SSACFG::BasicBlock::ConditionalJump>(&block.exit))\n\t{\n\t\tauto const& zeroLiveIn = m_liveness.liveIn(cjump->zero);\n\t\tauto const& blockLiveOut = m_liveness.liveOut(_blockId);\n\n\t\t// check if we have to do anything (dup the condition, bring it to the top etc)\n\t\tbool const conditionSlotAlreadyFinal =\n\t\t\t!blockLiveOut.contains(cjump->condition) &&  // if our live out does not contain the condition (ie we dont have to dup it)\n\t\t\t!stack.empty() &&   // our stack is not empty\n\t\t\tstack.top().isValueID() && stack.top().valueID() == cjump->condition;  // and the condition is already on top\n\t\tif (!conditionSlotAlreadyFinal)\n\t\t{\n\t\t\tauto const condition = Slot::makeValueID(cjump->condition);\n\t\t\tauto const targetSize = findOptimalTargetSize(stack.data(), {condition}, blockLiveOut, false, m_hasFunctionReturnLabel);\n\t\t\tStackShuffler<StackType::Callbacks>::shuffle(\n\t\t\t\tstack, {condition}, blockLiveOut, targetSize\n\t\t\t);\n\t\t}\n\n\t\tyulAssert(!stack.empty() && stack.top().isValueID() && stack.top().valueID() == cjump->condition);\n\t\tyulAssert(m_cfg.block(cjump->nonZero).phis.empty());\n\n\t\t// define zero and non-zero stack in layouts\n\t\t{\n\t\t\tstd::optional<BlockLayout>& nonZeroLayout = m_resultLayout[cjump->nonZero];\n\t\t\tyulAssert(!nonZeroLayout, \"There should be no way to reach this block other than by going through the parent.\");\n\t\t\tnonZeroLayout = BlockLayout{};\n\t\t\tnonZeroLayout->stackIn = currentStackData;\n\t\t\t// Remove condition; consumed by JUMPI\n\t\t\tnonZeroLayout->stackIn.pop_back();\n\n\t\t\tif (\n\t\t\t\tstd::optional<BlockLayout>& zeroLayout = m_resultLayout[cjump->zero];\n\t\t\t\t!zeroLayout\n\t\t\t)\n\t\t\t{\n\t\t\t\t// same as nonzero stack in initially\n\t\t\t\tzeroLayout = nonZeroLayout;\n\t\t\t\thandlePhiFunctions(zeroLayout->stackIn, PhiInverse(m_cfg, _blockId, cjump->zero), zeroLiveIn);\n\t\t\t\tStackType zeroStack(zeroLayout->stackIn, {});\n\t\t\t\tdeclareJunk(zeroStack, zeroLiveIn);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (auto const* functionReturn = std::get_if<SSACFG::BasicBlock::FunctionReturn>(&block.exit))\n\t{\n\t\tyulAssert(m_hasFunctionReturnLabel, \"When there is a proper function return, we need to have a label for it\");\n\t\t// in case there are return values, let's bring the function return label to the top\n\t\tStackData returnStack = functionReturn->returnValues | ranges::views::transform(StackSlot::makeValueID) | ranges::to<std::vector>;\n\t\treturnStack.push_back(StackSlot::makeFunctionReturnLabel(m_graphID));\n\t\tStackShuffler<StackType::Callbacks>::shuffle(stack, returnStack);\n\t}\n\n\tblockLayout.stackOut = currentStackData;\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/StackLayoutGenerator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/Stack.h>\n#include <libyul/backends/evm/ssa/StackLayout.h>\n\n#include <memory>\n\nnamespace solidity::yul::ssa\n{\n\nclass JunkAdmittingBlocksFinder;\n\nclass StackLayoutGenerator\n{\npublic:\n\tusing Slot = StackSlot;\n\tstatic SSACFGStackLayout generate(\n\t\tLivenessAnalysis const& _liveness,\n\t\tCallSites const& _callSites,\n\t\tControlFlow::FunctionGraphID _graphID\n\t);\n\nprivate:\n\texplicit StackLayoutGenerator(\n\t\tLivenessAnalysis const& _liveness,\n\t\tCallSites const& _callSites,\n\t\tControlFlow::FunctionGraphID _graphID\n\t);\n\n\tvoid defineStackIn(SSACFG::BlockId const& _blockId);\n\tvoid visitBlock(SSACFG::BlockId const& _blockId);\n\n\tSSACFG const& m_cfg;\n\tLivenessAnalysis const& m_liveness;\n\tCallSites const& m_callSites;\n\tControlFlow::FunctionGraphID m_graphID;\n\tbool m_hasFunctionReturnLabel;\n\n\tstd::unique_ptr<JunkAdmittingBlocksFinder> m_junkAdmittingBlocksFinder;\n\tSSACFGStackLayout m_resultLayout;\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/StackShuffler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/StackShuffler.h>\n\n#include <range/v3/algorithm/count.hpp>\n#include <range/v3/view/enumerate.hpp>\n\nusing namespace solidity::yul::ssa;\nusing namespace solidity::yul::ssa::detail;\n\nTarget::Target(StackData const& _args, LivenessAnalysis::LivenessData const& _liveOut, std::size_t const _targetSize):\n\targs(_args),\n\tliveOut(_liveOut),\n\tsize(_targetSize),\n\ttailSize(_targetSize - _args.size())\n{\n\tminCount.reserve(_args.size() + _liveOut.size());\n\tfor (auto const& arg: _args)\n\t\tif (!arg.isJunk())\n\t\t\t++minCount[arg];\n\tfor (auto const& _liveValueId: _liveOut | ranges::views::keys)\n\t\t++minCount[StackSlot::makeValueID(_liveValueId)];\n}\n\nState::State(StackData const& _stackData, Target const& _target, std::size_t const _reachableStackDepth):\n\tm_stackData(_stackData),\n\tm_target(_target),\n\tm_reachableStackDepth(_reachableStackDepth)\n{\n\tm_histogram.reserve(_stackData.size());\n\tm_histogramReachable.reserve(_stackData.size());\n\tm_histogramTail.reserve(_stackData.size());\n\tm_histogramArgs.reserve(_target.args.size());\n\tfor (auto const& [i, slot]: _stackData | ranges::views::enumerate)\n\t{\n\t\t// we don't care about junk in the tail\n\t\tif (i < _target.tailSize && slot.isJunk())\n\t\t\tcontinue;\n\t\t// we purposefully skip over junk in the target args as they are always 'correct'\n\t\tif (i >= _target.tailSize && i < _target.size && _target.args[i - _target.tailSize].isJunk())\n\t\t\tcontinue;\n\n\t\t++m_histogram[slot];\n\t\tif (i < _target.tailSize)\n\t\t\t++m_histogramTail[slot];\n\t\telse if (i < _target.size)\n\t\t\t++m_histogramArgs[slot];\n\t\tif (_stackData.size() - i - 1 < _reachableStackDepth)\n\t\t\t++m_histogramReachable[slot];\n\t}\n}\n\nstd::size_t State::size() const\n{\n\treturn m_stackData.size();\n}\n\nstd::size_t State::count(StackSlot const& _slot) const\n{\n\treturn util::valueOrDefault(m_histogram, _slot, static_cast<size_t>(0));\n}\n\nstd::size_t State::countInArgs(StackSlot const& _slot) const\n{\n\treturn util::valueOrDefault(m_histogramArgs, _slot, static_cast<size_t>(0));\n}\n\nstd::size_t State::countInTail(StackSlot const& _slot) const\n{\n\treturn util::valueOrDefault(m_histogramTail, _slot, static_cast<size_t>(0));\n}\n\nstd::size_t State::countReachable(StackSlot const& _slot) const\n{\n\treturn util::valueOrDefault(m_histogramReachable, _slot, static_cast<size_t>(0));\n}\n\nstd::size_t State::targetMinCount(StackSlot const& _slot) const\n{\n\treturn util::valueOrDefault(m_target.minCount, _slot, static_cast<size_t>(0));\n}\n\nstd::size_t State::targetArgsCount(StackSlot const& _slot) const\n{\n\treturn static_cast<size_t>(ranges::count(m_target.args, _slot));\n}\n\nbool State::admissible() const\n{\n\tif (m_target.size != m_stackData.size())\n\t\treturn false;\n\n\t// check if the args are correct\n\tfor (size_t i = 0; i < m_target.args.size(); ++i)\n\t\tif (!isArgsCompatible(StackOffset{m_stackData.size() - i - 1}, StackOffset{m_stackData.size() - i - 1}))\n\t\t\treturn false;\n\n\t// check if the distribution is correct (implying that the stack is admissible as JUNK target args are not counted)\n\tfor (auto const& [targetSlot, targetMinCount]: m_target.minCount)\n\t\tif (count(targetSlot) < targetMinCount)\n\t\t\treturn false;\n\treturn true;\n}\n\nbool State::requiredInArgs(StackSlot const& _slot) const\n{\n\treturn ranges::find(m_target.args, _slot) != ranges::end(m_target.args);\n}\n\nbool State::requiredInTail(StackSlot const& _slot) const\n{\n\treturn _slot.isValueID() && m_target.liveOut.contains(_slot.valueID());\n}\n\nbool State::offsetInTargetArgsRegion(StackOffset const _offset) const\n{\n\treturn _offset.value >= m_target.size - m_target.args.size() && _offset.value < m_target.size;\n}\n\nStackSlot const& State::targetArg(StackOffset const _targetOffset) const\n{\n\tyulAssert(offsetInTargetArgsRegion(_targetOffset));\n\treturn m_target.args[_targetOffset.value - m_target.tailSize];\n}\n\nbool State::isArgsCompatible(StackOffset const _sourceOffset, StackOffset const _targetOffset) const\n{\n\tif (_sourceOffset >= m_stackData.size() || !offsetInTargetArgsRegion(_targetOffset))\n\t\treturn false;\n\tauto const& arg = targetArg(_targetOffset);\n\treturn arg.isJunk() || m_stackData[_sourceOffset.value] == arg;\n}\n\nbool State::targetArbitrary(StackOffset const _targetOffset) const\n{\n\treturn targetArg(_targetOffset).isJunk();\n}\n\nbool State::isSourceCompatible(StackOffset const _sourceOffset1, StackOffset const _sourceOffset2) const\n{\n\treturn _sourceOffset1 < m_stackData.size() &&\n\t\t_sourceOffset2 < m_stackData.size() &&\n\t\tm_stackData[_sourceOffset1.value] == m_stackData[_sourceOffset2.value];\n}\n\nbool State::isSafeToSwapWithTop(StackOffset const _offset) const\n{\n\tauto const& top = m_stackData.back();\n\tyulAssert(_offset.value < size());\n\tauto const& slot = m_stackData[_offset.value];\n\treturn !isArgsCompatible(_offset, _offset) && // the offset isn't already in the right position wrt args\n\t\t!isArgsCompatible(StackOffset{size() - 1}, StackOffset{size() - 1}) && // the top isn't already in the right position wrt args\n\t\t(\n\t\t\t!requiredInArgs(top) || // current top can go into tail, ie it's not required as arg or\n\t\t\tcountReachable(top) > 1 // there's more of it in reachable stack depth\n\t\t) &&\n\t\t(\n\t\t\ttarget().tailSize <= _offset.value ||  // sourceOffset not in tail\n\t\t\t!requiredInTail(slot) ||  // we're in tail but sourceOffset not needed in tail\n\t\t\t(countInTail(slot) > 1 && requiredInTail(slot))  // swapping source offset away from tail doesn't decrease tail correctness\n\t\t);\n}\n\nTarget const& State::target() const\n{\n\treturn m_target;\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/StackShuffler.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/LivenessAnalysis.h>\n#include <libyul/backends/evm/ssa/Stack.h>\n\n#include <boost/container/flat_map.hpp>\n\n#include <range/v3/view/iota.hpp>\n\n#include <cstddef>\n#include <optional>\n\nnamespace solidity::yul::ssa\n{\n\nnamespace detail\n{\n/// Contains information about the shuffling target, aggregates over args and live out to\n/// provide a lower bound for the slot distribution.\nstruct Target\n{\n\tTarget(StackData const& _args, LivenessAnalysis::LivenessData const& _liveOut, std::size_t _targetSize);\n\n\tStackData const& args;\n\tLivenessAnalysis::LivenessData const& liveOut;\n\tstd::size_t const size;\n\tstd::size_t const tailSize;\n\tboost::container::flat_map<StackSlot, size_t> minCount;\n};\n/// Current state of the stack vs the shuffling target.\nclass State\n{\npublic:\n\tState(StackData const& _stackData, Target const& _target, std::size_t _reachableStackDepth);\n\n\tstd::size_t size() const;\n\t/// How many of `_slot` do we have on stack\n\tstd::size_t count(StackSlot const& _slot) const;\n\t/// How many of `_slot` do we have in the args section of the stack\n\tstd::size_t countInArgs(StackSlot const& _slot) const;\n\t/// How many of `_slot` do we have in the tail section of the stack\n\tstd::size_t countInTail(StackSlot const& _slot) const;\n\t/// How many of `_slot` are (dup) reachable on stack\n\tstd::size_t countReachable(StackSlot const& _slot) const;\n\n\t/// Obtain the amount of the provided slot that is required for distribution correctness\n\tstd::size_t targetMinCount(StackSlot const& _slot) const;\n\t/// Obtain the amount of the provided slot that is required in target args\n\tstd::size_t targetArgsCount(StackSlot const& _slot) const;\n\n\t/// Checks if the state is compatible with the target\n\tbool admissible() const;\n\n\t/// Checks if a particular slot is required in the target args\n\tbool requiredInArgs(StackSlot const& _slot) const;\n\t/// Checks if a particular slot is required in the target tail\n\tbool requiredInTail(StackSlot const& _slot) const;\n\n\t/// Checks if an offset is in the target args (bounded from below by tail size, from above by target size)\n\tbool offsetInTargetArgsRegion(StackOffset _offset) const;\n\t/// Retrieves the required argument slot for a specific stack offset\n\tStackSlot const& targetArg(StackOffset _targetOffset) const;\n\t/// Checks the current stack offset is args-compatible with a target stack offset, meaning the target offset is\n\t/// in the target args region and either a wildcard slot (JUNK) or a precise match for the slot at `_sourceOffset`\n\tbool isArgsCompatible(StackOffset _sourceOffset, StackOffset _targetOffset) const;\n\t/// Checks if the slot at `_targetOffset` admits any slot\n\tbool targetArbitrary(StackOffset _targetOffset) const;\n\t/// Yields whether two slots on the current stack are same, respecting stack size limits\n\tbool isSourceCompatible(StackOffset _sourceOffset1, StackOffset _sourceOffset2) const;\n\t/// Checks if swapping the current offset with top makes progress toward target\n\tbool isSafeToSwapWithTop(StackOffset _offset) const;\n\t/// Shuffling target information\n\tTarget const& target() const;\n\n\t/// A range of offsets `[argsBegin, argsEnd)` intersected with the current stack size\n\tauto stackArgsRange() const\n\t{\n\t\treturn ranges::views::iota(std::min(m_target.tailSize, m_stackData.size()), std::min(m_target.size, m_stackData.size())) | ranges::views::transform([](auto _i) { return StackOffset{_i}; });\n\t}\n\n\t/// A range of offsets `[0, argsBegin)` intersected with the current stack size\n\tauto stackTailRange() const\n\t{\n\t\treturn ranges::views::iota(0u, std::min(m_target.tailSize, m_stackData.size())) | ranges::views::transform([](auto _i) { return StackOffset{_i}; });\n\t}\n\n\t/// A range of offsets `[0, stackSize)`\n\tauto stackRange() const\n\t{\n\t\treturn ranges::views::iota(0u, m_stackData.size()) | ranges::views::transform([&](auto _i) { return StackOffset{_i}; });\n\t}\n\n\t/// A reversed range of offsets `[stackSize - reachableStackDepth - 1, stackSize)`\n\tauto stackSwapReachableRange() const\n\t{\n\t\treturn ranges::views::iota(0u, std::min(m_stackData.size(), m_reachableStackDepth + 1)) | ranges::views::transform([&](auto _i) { return StackOffset{m_stackData.size() - _i - 1}; });\n\t}\n\n\t/// A reversed range of offsets `[stackSize - reachableStackDepth - 1, stackSize)`\n\tauto stackDupReachableRange() const\n\t{\n\t\treturn ranges::views::iota(0u, std::min(m_stackData.size(), m_reachableStackDepth)) | ranges::views::transform([&](auto _i) { return StackOffset{m_stackData.size() - _i - 1}; });\n\t}\n\nprivate:\n\tStackData const& m_stackData;\n\tTarget const& m_target;\n\tstd::size_t const m_reachableStackDepth;\n\tboost::container::flat_map<StackSlot, size_t> m_histogramTail;\n\tboost::container::flat_map<StackSlot, size_t> m_histogramArgs;\n\tboost::container::flat_map<StackSlot, size_t> m_histogramReachable;\n\tboost::container::flat_map<StackSlot, size_t> m_histogram;\n};\n}\n\ntemplate<StackManipulationCallbackConcept Callback, std::size_t ReachableStackDepth=16>\nclass StackShuffler\n{\n\tusing Slot = StackSlot;\n\npublic:\n\tstatic void shuffle(\n\t\tStack<Callback>& _stack,\n\t\tStackData const& _args,\n\t\tLivenessAnalysis::LivenessData const& _liveOut,\n\t\tstd::size_t _targetStackSize\n\t)\n\t{\n\t\tdetail::Target const target(_args, _liveOut, _targetStackSize);\n\t\tyulAssert(_liveOut.size() <= target.size, \"not enough tail space\");\n\t\t{\n\t\t\t// check that all required values are on stack\n\t\t\tdetail::State const state(_stack.data(), target, ReachableStackDepth);\n\t\t\tfor (auto const& liveVariable: _liveOut | ranges::views::keys | ranges::views::transform(Slot::makeValueID))\n\t\t\t\tyulAssert(_stack.canBeFreelyGenerated(liveVariable) || ranges::find(_stack.data(), liveVariable) != ranges::end(_stack.data()));\n\t\t\tfor (auto const& arg: _args)\n\t\t\t\tyulAssert(_stack.canBeFreelyGenerated(arg) || ranges::find(_stack.data(), arg) != ranges::end(_stack.data()));\n\t\t}\n\n\t\tstatic std::size_t constexpr maxIterations = 1000;\n\t\tstd::size_t i = 0;\n\t\twhile (i < maxIterations)\n\t\t{\n\t\t\tdetail::State const state(_stack.data(), target, ReachableStackDepth);\n\t\t\tif (!shuffleStep(_stack, state))\n\t\t\t{\n\t\t\t\tyulAssert(state.admissible());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t++i;\n\t\t}\n\n\t\tyulAssert(i < maxIterations, fmt::format(\"Maximum iterations reached on {}\", stackToString(_stack.data())));\n\t}\n\n\tstatic void shuffle(\n\t\tStack<Callback>& _stack,\n\t\tStackData const& _target\n\t)\n\t{\n\t\tshuffle(_stack, _target, {}, _target.size());\n\t}\n\nprivate:\n\t/// Make a local step in stack space that should bring us closer to the target. Returns true if more shuffling\n\t/// is required, returns false if finished.\n\tstatic bool shuffleStep(Stack<Callback>& _stack, detail::State const& _state)\n\t{\n\t\t// if the stack is too large, we try to shrink it\n\t\tif (_stack.size() > _state.target().size)\n\t\t{\n\t\t\tif (shrinkStack(_stack, _state))\n\t\t\t\treturn true;\n\t\t\t// couldn't shrink to required size, need to spill to memory or increase target size\n\t\t\tyulAssert(false, \"stack too deep\");\n\t\t}\n\t\tyulAssert(_stack.size() <= _state.target().size, \"I1 violated: Stack size too large\");\n\n\t\t// after this, all current slots are either in acceptable positions or at least dup-reachable\n\t\tif (auto unreachableOffset = allNecessarySlotsReachableOrFinal(_stack, _state))\n\t\t{\n\t\t\t// !allNecessarySlotsReachableOrFinal(ops) ≡ ¬(∀s: reachable(s) ∨ final(s)) ≡ ∃s: ¬reachable(s) ∧ ¬final(s)\n\t\t\tif (shrinkStack(_stack, _state))\n\t\t\t\treturn true;\n\n\t\t\tyulAssert(false, fmt::format(\"stack too deep, couldn't reach offset {}\", unreachableOffset->value));\n\t\t}\n\n\t\t// this will either grow the tail as needed, swap down something from args that needs to be in the tail,\n\t\t// or return false when there's nothing to be done\n\t\tif (fixTailSlot(_stack, _state))\n\t\t\treturn true;\n\n\t\t// fixing tail slot fills up the tail so that now the stack must reach into the args region but also not\n\t\t// exceed it as per our first invariant\n\t\tyulAssert(_state.target().tailSize <= _stack.size() && _stack.size() <= _state.target().size);\n\n\t\t// if the stack reaches into the args region try fixing a slot in there until there's nothing left to be fixed\n\t\t// within the target size constraints\n\t\tif (fixArgsSlot(_stack, _state))\n\t\t\treturn true;\n\n\t\t// if there are no args, we should be done now\n\t\tif (_state.target().args.empty())\n\t\t\treturn false;\n\t\tyulAssert(_stack.size() == _state.target().size);\n\n\t\t// check whether we are done\n\t\tif (_state.admissible())\n\t\t\treturn false;\n\n\t\t// We couldn't improve the args tail or args situation, and we are not admissible yet, so try to reduce the\n\t\t// stack size and pop something that we don't need so we make space to dup/push stuff within target size\n\t\tif (shrinkStack(_stack, _state))\n\t\t\treturn true;\n\n\t\tyulAssert(false, \"reached final and forbidden state\");\n\t}\n\n\t/// Select an optimal slot to dup based on liveness analysis.\n\t/// Prioritizes slots that have the highest deficit with respect to liveOut counts.\n\tstatic std::optional<StackDepth> selectOptimalSlotToDup(Stack<Callback> const& _stack, detail::State const& _state)\n\t{\n\t\tstd::optional<StackDepth> bestSlot;\n\t\tint bestDeficit = 0; // Only consider positive deficits\n\n\t\t// Iterate through all slots on the stack that can be DUPed\n\t\tfor (StackOffset offset: _state.stackDupReachableRange() | ranges::views::reverse)\n\t\t{\n\t\t\tSlot const& slot = _stack[offset];\n\n\t\t\t// Skip junk slots\n\t\t\tif (slot.isJunk())\n\t\t\t\tcontinue;\n\n\t\t\t// Calculate deficit: how many more of this slot do we need?\n\t\t\t// Uses the deficit of slots which we need to produce more of based on usage counts in liveness.\n\t\t\t// Prioritizes slots that need more copies to be consumed down the line.\n\t\t\tint currentCount = static_cast<int>(_state.count(slot));\n\n\t\t\tint liveOutCount = 0;\n\t\t\tif (slot.isValueID() && _state.target().liveOut.contains(slot.valueID()))\n\t\t\t\tliveOutCount = static_cast<int>(_state.target().liveOut.count(slot.valueID()));\n\t\t\tint deficit = liveOutCount - currentCount;\n\n\t\t\t// Update best if this deficit is higher\n\t\t\tif (deficit > bestDeficit)\n\t\t\t{\n\t\t\t\tbestDeficit = deficit;\n\t\t\t\tbestSlot = _stack.offsetToDepth(offset);\n\t\t\t}\n\t\t}\n\n\t\treturn bestSlot;\n\t}\n\n\t/// Dups the deepest reachable slot in the tail that is required in args\n\tstatic bool dupDeepestRelevantTailSlot(Stack<Callback>& _stack, detail::State const& _state)\n\t{\n\t\t// dup up the deepest slot that is required in args (or compress if unreachable)\n\t\tfor (StackOffset offset: _state.stackRange())\n\t\t{\n\t\t\t// if we need the slot in args and there's no slot of the same kind further up\n\t\t\tif (\n\t\t\t\t_state.requiredInArgs(_stack[offset]) &&\n\t\t\t\tranges::find(ranges::begin(_stack) + static_cast<std::ptrdiff_t>(offset.value) + 1, ranges::end(_stack), _stack[offset]) == ranges::end(_stack)\n\t\t\t)\n\t\t\t{\n\t\t\t\t// dup if we can\n\t\t\t\tif (_stack.dupReachable(offset))\n\t\t\t\t{\n\t\t\t\t\t_stack.dup(offset);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// try to compress\n\t\t\t\tif (shrinkStack(_stack, _state))\n\t\t\t\t\treturn true;\n\n\t\t\t\tyulAssert(false, fmt::format(\"Stack too deep: can't reach slot at offset {}\", offset.value));\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/// If dupping an ideal slot causes a slot that will still be required to become unreachable, then dup\n\t/// the latter slot first\n\tstatic bool dupDeepSlotIfRequired(Stack<Callback>& _stack, detail::State const& _state)\n\t{\n\t\t// Check if the stack is large enough for anything to potentially become unreachable.\n\t\tif (_stack.size() < ReachableStackDepth - 1)\n\t\t\treturn false;\n\t\t// Check whether any deep slot might still be needed later (i.e. we still need to reach it with a DUP or SWAP).\n\t\tfor (StackOffset sourceOffset{0u}; sourceOffset < _stack.size() - (ReachableStackDepth - 1); ++sourceOffset.value)\n\t\t{\n\t\t\t// This slot needs to be moved into args and there is no tail slot of the same kind further up in the stack.\n\t\t\tauto const& endangeredSlot = _stack[sourceOffset];\n\t\t\t// no need to dup deep junk\n\t\t\tif (endangeredSlot.isJunk())\n\t\t\t\tcontinue;\n\t\t\tbool const neededInArgs = _state.targetArgsCount(endangeredSlot) > _state.countInArgs(endangeredSlot);\n\t\t\tbool const needMore = _state.targetMinCount(endangeredSlot) > _state.count(endangeredSlot);\n\t\t\tif (!neededInArgs && !needMore)\n\t\t\t\tcontinue;\n\t\t\t// if we ever need more of a slot then this can only happen if it is something we require in the arguments\n\t\t\tyulAssert(_state.requiredInArgs(endangeredSlot));\n\t\t\t// if there's a shallower slot with the same info that is reachable, skip this one\n\t\t\tstd::optional<StackDepth> depth = _stack.findSlotDepth(endangeredSlot);\n\t\t\tyulAssert(depth);\n\t\t\tbool const haveMoreAbove = *depth < _stack.offsetToDepth(sourceOffset);\n\t\t\tif (haveMoreAbove)\n\t\t\t\tcontinue;\n\n\t\t\tif (_stack.dupReachable(sourceOffset))\n\t\t\t{\n\t\t\t\t// if we can safely swap the current stack top with the endangered slot, we do that instead of DUP\n\t\t\t\tif (_state.isSafeToSwapWithTop(sourceOffset))\n\t\t\t\t{\n\t\t\t\t\t// top can go into the tail bit, swap it down\n\t\t\t\t\t_stack.swap(sourceOffset);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// we need more of the slot that is about to go out of reach, dup it\n\t\t\t\t\t_stack.dup(sourceOffset);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// even if it is not dup reachable, it still might be swappable\n\t\t\t\tif (_stack.swapReachable(sourceOffset) && _state.isSafeToSwapWithTop(sourceOffset))\n\t\t\t\t{\n\t\t\t\t\t_stack.swap(sourceOffset);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// the slot we need something in the args region of is unreachable, try compressing the stack,\n\t\t\t\t// first looking at the top\n\t\t\t\tif (shrinkStack(_stack, _state))\n\t\t\t\t\treturn true;\n\n\t\t\t\tyulAssert(false, fmt::format(\"Stack too deep, can't reach slot at depth {}\", depth->value));\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/// Tries to fix a slot in the args section of the stack\n\tstatic bool fixArgsSlot(Stack<Callback>& _stack, detail::State const& _state)\n\t{\n\t\tyulAssert(_stack.size() <= _state.target().size, \"this method assumes that the stack isn't too large\");\n\t\tif (_stack.size() < _state.target().tailSize)\n\t\t\treturn false;\n\n\t\t// if we have at least one slot in the args section, try to fix something there\n\t\tif (_stack.size() > _state.target().tailSize)\n\t\t{\n\t\t\tStackOffset const stackTop{_stack.size() - 1};\n\t\t\t// if the stack top isn't where it likes to be right now, try to put it somewhere more sensible\n\t\t\tif (!_state.isArgsCompatible(stackTop, stackTop))\n\t\t\t{\n\t\t\t\t// if the stack top should go into the tail but isn't there yet and we have enough of it in args\n\t\t\t\tif (\n\t\t\t\t\t_state.requiredInTail(_stack[stackTop]) &&\n\t\t\t\t\t_state.countInTail(_stack[stackTop]) == 0 &&\n\t\t\t\t\t_state.countInArgs(_stack[stackTop]) > _state.targetArgsCount(_stack[stackTop])\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// try swapping it with something in the tail that also fixes the top\n\t\t\t\t\tfor (StackOffset offset: _state.stackTailRange())\n\t\t\t\t\t\tif (_stack.swapReachable(offset) && _state.isArgsCompatible(offset, stackTop))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t// otherwise try swapping it with something that needs to go into args\n\t\t\t\t\tfor (StackOffset offset: _state.stackTailRange())\n\t\t\t\t\t\tif (_stack.swapReachable(offset) && _state.countInArgs(_stack[offset]) < _state.targetArgsCount(_stack[offset]))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t// otherwise try swapping it with something that can be popped\n\t\t\t\t\tfor (StackOffset offset: _state.stackTailRange())\n\t\t\t\t\t\tif (_stack.swapReachable(offset) && _stack.canBeFreelyGenerated(_stack[offset]) && !_stack[offset].isLiteralValueID())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t// otherwise try swapping it with a literal\n\t\t\t\t\tfor (StackOffset offset: _state.stackTailRange())\n\t\t\t\t\t\tif (_stack.swapReachable(offset) && _stack[offset].isLiteralValueID())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// try finding a slot that is compatible with the top and also admits the current top:\n\t\t\t\t//\t\t- could be that the top slot is used elsewhere in the args (exclude junk)\n\t\t\t\t//\t\t- could be that the top slot is something that is only required in the tail\n\t\t\t\tfor (StackOffset offset: _state.stackArgsRange())\n\t\t\t\t\tif (\n\t\t\t\t\t\toffset != stackTop &&\n\t\t\t\t\t\t_stack[offset] != _stack[stackTop] &&  // don't swap identical values (no-op)\n\t\t\t\t\t\t_stack.swapReachable(offset) &&\n\t\t\t\t\t\t_state.isArgsCompatible(offset, stackTop) &&\n\t\t\t\t\t\t_state.isArgsCompatible(stackTop, offset) &&\n\t\t\t\t\t\t!_state.targetArbitrary(offset)\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t// try finding a slot in args that wants to have the top, swap that\n\t\t\t\tfor (StackOffset offset: _state.stackArgsRange())\n\t\t\t\t\tif (\n\t\t\t\t\t\toffset != stackTop &&\n\t\t\t\t\t\t_stack[offset] != _stack[stackTop] &&  // don't swap identical values (no-op)\n\t\t\t\t\t\t_stack.swapReachable(offset) &&\n\t\t\t\t\t\t!_state.isArgsCompatible(offset, offset) &&\n\t\t\t\t\t\t_state.isArgsCompatible(stackTop, offset)\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t// try swapping top with a tail slot that has what we need at top\n\t\t\t\tfor (StackOffset tailOffset: _state.stackTailRange())\n\t\t\t\t\tif (\n\t\t\t\t\t\t_stack.swapReachable(tailOffset) &&\n\t\t\t\t\t\t_state.isArgsCompatible(tailOffset, stackTop) &&\n\t\t\t\t\t\t(!_state.requiredInTail(_stack[tailOffset]) || _state.countInTail(_stack[tailOffset]) > 1) &&\n\t\t\t\t\t\t// current top can safely go to tail (not needed in args, or we have excess)\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t!_state.requiredInArgs(_stack[stackTop]) ||\n\t\t\t\t\t\t\t_state.countInArgs(_stack[stackTop]) > _state.targetArgsCount(_stack[stackTop])\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t_stack.swap(tailOffset);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t}\n\n\t\t\t// swap up any slot in args that is out of position and has a slot available in args that it can occupy\n\t\t\tfor (StackOffset offset: _state.stackArgsRange())\n\t\t\t{\n\t\t\t\tbool const reachable = _stack.swapReachable(offset);\n\t\t\t\tbool const identical = _state.isArgsCompatible(offset, stackTop) && !_state.targetArbitrary(stackTop);\n\t\t\t\tif (\n\t\t\t\t\treachable &&\n\t\t\t\t\t!identical && // we wouldn't just be swapping identical things\n\t\t\t\t\t(\n\t\t\t\t\t\t!_state.isArgsCompatible(offset, offset) || // the slot at offset isn't final\n\t\t\t\t\t\t(_state.targetArbitrary(offset) && !_stack.slot(offset).isJunk()) // or the target is arbitrary and the current slot isn't already junk\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// for each `targetOffset` in target args, see if we can't swap the out of position `offset` to `targetOffset`\n\t\t\t\t\tfor (StackOffset targetOffset: _state.stackArgsRange())\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\ttargetOffset != offset &&  // we shouldn't be looking at the very same offset\n\t\t\t\t\t\t\t_stack.swapReachable(targetOffset) &&  // the target offset should be within reach\n\t\t\t\t\t\t\t_state.isArgsCompatible(offset, targetOffset) &&  // we can put offset -> targetOffset\n\t\t\t\t\t\t\t!_state.isArgsCompatible(targetOffset, targetOffset)  // targetOffset doesn't like where it is\n\t\t\t\t\t\t)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (offset != stackTop)\n\t\t\t\t\t\t\t\t// swap up slot at offset\n\t\t\t\t\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t\t\t\t// bring slot at offset into fixed position\n\t\t\t\t\t\t\t_stack.swap(targetOffset);\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// dup up whatever is missing\n\t\tif (_stack.size() < _state.target().size)\n\t\t{\n\t\t\tif (dupDeepSlotIfRequired(_stack, _state))\n\t\t\t\treturn true;\n\n\t\t\t{\n\t\t\t\tStackOffset const targetOffset{_stack.size()};\n\t\t\t\tif (_state.count(_state.targetArg(targetOffset)) < _state.targetMinCount(_state.targetArg(targetOffset)))\n\t\t\t\t{\n\t\t\t\t\tauto const sourceDepth = _stack.findSlotDepth(_state.targetArg(targetOffset));\n\t\t\t\t\tif (!sourceDepth)\n\t\t\t\t\t{\n\t\t\t\t\t\t_stack.push(_state.targetArg(targetOffset));\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!_stack.dupReachable(*sourceDepth))\n\t\t\t\t\t\tyulAssert(false, fmt::format(\"todo: stack too deep handling, couldn't dup up arg {}\", slotToString(_state.targetArg(_stack.depthToOffset(*sourceDepth)))));\n\t\t\t\t\t_stack.dup(*sourceDepth);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// if we can't directly produce targetOffset, take the deepest arg that we don't have enough of and dup/push that\n\t\t\t// First, prioritize duping args that are on the stack over pushing freely-generatable ones\n\t\t\tfor (StackOffset offset{_state.target().tailSize}; offset < _state.target().size; ++offset.value)\n\t\t\t{\n\t\t\t\tSlot const& arg = _state.targetArg(offset);\n\t\t\t\tif (!arg.isJunk() && (_state.count(arg) < _state.targetMinCount(arg) || _state.countInArgs(arg) < _state.targetArgsCount(arg)))\n\t\t\t\t{\n\t\t\t\t\tif (auto sourceDepth = _stack.findSlotDepth(arg))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (_stack.dupReachable(*sourceDepth))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_stack.dup(*sourceDepth);\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tyulAssert(false, \"stack too deep handling\");\n\t\t\t\t\t}\n\t\t\t\t\tyulAssert(_stack.canBeFreelyGenerated(arg));\n\t\t\t\t\t_stack.push(arg);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Try to dup the optimal slot based on liveness analysis\n\t\t\tif (auto slotToDup = selectOptimalSlotToDup(_stack, _state))\n\t\t\t\t_stack.dup(*slotToDup);\n\t\t\telse\n\t\t\t\t// If no suitable slot found, push junk\n\t\t\t\t_stack.push(Slot::makeJunk());\n\t\t\treturn true;\n\t\t}\n\n\t\t// if we're at size and have to push or dup something to satisfy args\n\t\tif (_stack.size() == _state.target().size)\n\t\t{\n\t\t\tfor (auto const& arg: _state.target().args)\n\t\t\t\tif (_state.count(arg) < _state.targetMinCount(arg))\n\t\t\t\t{\n\t\t\t\t\t// we have asserted that all relevant slots are reachable or final, so the arg must either be\n\t\t\t\t\t// within dup-reach or we can just push it\n\t\t\t\t\tif (auto depth = _stack.findSlotDepth(arg))\n\t\t\t\t\t{\n\t\t\t\t\t\tyulAssert(depth->value == 0 || _stack.swapReachable(*depth));\n\t\t\t\t\t\t// if we can't outright dup the slot, let's shrink the stack first\n\t\t\t\t\t\tif (!_stack.dupReachable(*depth))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tyulAssert(shrinkStack(_stack, _state), \"stack too deep, need to spill arg to memory\");\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t_stack.dup(*depth);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tyulAssert(_stack.canBeFreelyGenerated(arg));\n\t\t\t\t\t\tif (!dupDeepSlotIfRequired(_stack, _state))\n\t\t\t\t\t\t\t_stack.push(arg);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/// Grows the tail if too small, otherwise tries swapping something down from args if its required in tail but not\n\t/// there yet.\n\tstatic bool fixTailSlot(Stack<Callback>& _stack, detail::State const& _state)\n\t{\n\t\tyulAssert(_stack.size() <= _state.target().size, \"this method assumes that the stack isn't exceeding target size\");\n\t\tfor (StackOffset offset: _state.stackArgsRange() | ranges::views::reverse)\n\t\t{\n\t\t\tSlot const& slotAtOffset = _stack[offset];\n\t\t\tif (\n\t\t\t\t_state.requiredInTail(slotAtOffset) &&  // if we need the slot in tail\n\t\t\t\t_state.countInTail(slotAtOffset) == 0  // if we don't have the slot in tail right now\n\t\t\t)\n\t\t\t{\n\t\t\t\t// If we don't have enough copies of this slot, dup first instead of swapping.\n\t\t\t\tif (_state.count(slotAtOffset) < _state.targetMinCount(slotAtOffset))\n\t\t\t\t{\n\t\t\t\t\tif (_stack.dupReachable(offset))\n\t\t\t\t\t{\n\t\t\t\t\t\t_stack.dup(offset);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// find the lowest swappable slot in tail that needs to go to args, swap\n\t\t\t\tfor (StackOffset tailOffset: _state.stackTailRange())\n\t\t\t\t{\n\t\t\t\t\tauto const& slotAtTailOffset = _stack[tailOffset];\n\t\t\t\t\tif (\n\t\t\t\t\t\t_stack.swapReachable(tailOffset) &&  // we can swap that deep\n\t\t\t\t\t\t(!_state.requiredInTail(slotAtTailOffset) || _state.countInTail(slotAtTailOffset) > 1) &&  // dont need it in tail or it's available more than once\n\t\t\t\t\t\t_state.requiredInArgs(slotAtTailOffset) &&  // we need the tail offset slot in args\n\t\t\t\t\t\t_state.targetArgsCount(slotAtTailOffset) > _state.countInArgs(slotAtTailOffset)  // we don't already have enough of it in args\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// bring up offset slot if necessary\n\t\t\t\t\t\tif (offset != StackOffset{_stack.size() - 1})\n\t\t\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t\t\t// swap offset slot down into tail\n\t\t\t\t\t\t_stack.swap(tailOffset);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// find the lowest swappable slot in tail that can be popped but is no literal, swap\n\t\t\t\tfor (StackOffset tailOffset: _state.stackTailRange())\n\t\t\t\t\tif (\n\t\t\t\t\t\t_stack.swapReachable(tailOffset) &&\n\t\t\t\t\t\t_stack.canBeFreelyGenerated(_stack[tailOffset]) &&\n\t\t\t\t\t\t!_stack[tailOffset].isLiteralValueID()\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// bring up offset slot if necessary\n\t\t\t\t\t\tif (offset != StackOffset{_stack.size() - 1})\n\t\t\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t\t\t// swap offset slot down into tail\n\t\t\t\t\t\t_stack.swap(tailOffset);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t// find the lowest swappable slot in tail that is a literal, swap\n\t\t\t\tfor (StackOffset tailOffset: _state.stackTailRange())\n\t\t\t\t\tif (\n\t\t\t\t\t\t_stack.swapReachable(tailOffset) &&\n\t\t\t\t\t\t_stack[tailOffset].isLiteralValueID()\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// bring up offset slot if necessary\n\t\t\t\t\t\tif (offset != StackOffset{_stack.size() - 1})\n\t\t\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t\t\t// swap offset slot down into tail\n\t\t\t\t\t\t_stack.swap(tailOffset);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t// we needed to bring the slot into tail but couldn't, not enough stack target space -> spill to memory\n\t\t\t\tyulAssert(false, \"stack too deep: couldn't swap args slot into tail without moving something else out that is required there\");\n\t\t\t}\n\t\t}\n\n\t\tif (_stack.size() < _state.target().tailSize)\n\t\t{\n\t\t\t// if something is on the verge of going out of scope by duping something, dup that first\n\t\t\tif (dupDeepSlotIfRequired(_stack, _state))\n\t\t\t\treturn true;\n\n\t\t\t// dup up the deepest slot that needs to go into args so we avoid having to fish it back up later\n\t\t\tif (dupDeepestRelevantTailSlot(_stack, _state))\n\t\t\t\treturn true;\n\n\t\t\t// Try to dup the optimal slot based on liveness analysis\n\t\t\tif (auto slotToDup = selectOptimalSlotToDup(_stack, _state))\n\t\t\t\t_stack.dup(*slotToDup);\n\t\t\telse\n\t\t\t\t// If no suitable slot found, push junk\n\t\t\t\t_stack.push(Slot::makeJunk());\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/// Tries to compress the stack\n\tstatic bool shrinkStack(Stack<Callback>& _stack, detail::State const& _state)\n\t{\n\t\tyulAssert(!_stack.empty(), \"Stack is empty, can't shrink\");\n\n\t\tStackOffset const stackTop{_stack.size() - 1};\n\t\t// pop top if it is junk (ie actual junk, not in args, not in live out)\n\t\tif (\n\t\t\t_stack[stackTop].isJunk() ||\n\t\t\t(!_state.requiredInArgs(_stack[stackTop]) && !_state.requiredInTail(_stack[stackTop]))\n\t\t)\n\t\t{\n\t\t\t_stack.pop();\n\t\t\treturn true;\n\t\t}\n\n\t\t// swap top to suitable position, prioritizing args region\n\t\t{\n\t\t\tif (_state.requiredInArgs(_stack[stackTop]))\n\t\t\t{\n\t\t\t\tfor (StackOffset argsOffset: _state.stackArgsRange())\n\t\t\t\t\tif (\n\t\t\t\t\t\t_stack[argsOffset] != _stack[stackTop] &&  // don't swap identical values (no-op)\n\t\t\t\t\t\t_stack.swapReachable(argsOffset) &&\n\t\t\t\t\t\t_state.isArgsCompatible(stackTop, argsOffset) &&\n\t\t\t\t\t\t!_state.isArgsCompatible(argsOffset, argsOffset)\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t_stack.swap(argsOffset);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t}\n\t\t\t// we don't need it in args but in tail\n\t\t\tif (!_state.requiredInArgs(_stack[stackTop]) && _state.requiredInTail(_stack[stackTop]))\n\t\t\t{\n\t\t\t\t// pop when at least one of the two conditions is fulfilled\n\t\t\t\t//\t- the top slot is contained in tail, and we're in args or excess region\n\t\t\t\t//\t- there's more than one in tail\n\t\t\t\tif (\n\t\t\t\t\t(\n\t\t\t\t\t\t_state.countInTail(_stack[stackTop]) >= 1 &&\n\t\t\t\t\t\t(_state.offsetInTargetArgsRegion(stackTop) || _stack.size() > _state.target().size)\n\t\t\t\t\t) || _state.countInTail(_stack[stackTop]) > 1\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t_stack.pop();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// if we need it down there, try to swap down\n\t\t\t\tfor (StackOffset tailOffset: _state.stackTailRange() | ranges::views::reverse)\n\t\t\t\t\tif (\n\t\t\t\t\t\t_stack[tailOffset] != _stack[stackTop] &&  // don't swap identical values (no-op)\n\t\t\t\t\t\t_stack.swapReachable(tailOffset) &&  // we can reach the offset\n\t\t\t\t\t\t!(_state.requiredInTail(_stack[tailOffset]) && _state.countInTail(_stack[tailOffset]) <= 1)  // it's okay to swap the tail offset out\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t_stack.swap(tailOffset);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// pop junk (but not if JUNK is exactly what's needed at that position)\n\t\tfor (StackOffset offset: _state.stackSwapReachableRange())\n\t\t\tif (_stack[offset].isJunk() && !_state.isArgsCompatible(offset, offset))\n\t\t\t{\n\t\t\t\tif (offset != stackTop && _stack[offset] != _stack[stackTop])\n\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t_stack.pop();\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t// pop something that can be freely generated except for literals\n\t\t// (but not if it's already in a compatible position)\n\t\tfor (StackOffset offset: _state.stackSwapReachableRange())\n\t\t\tif (\n\t\t\t\t_stack.canBeFreelyGenerated(_stack[offset]) &&\n\t\t\t\t!_stack[offset].isLiteralValueID() &&\n\t\t\t\t!_state.isArgsCompatible(offset, offset)\n\t\t\t)\n\t\t\t{\n\t\t\t\tif (offset != stackTop && _stack[offset] != _stack[stackTop])\n\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t_stack.pop();\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t// pop anything that isn't in position and we have more than one of\n\t\tfor (StackOffset offset: _state.stackSwapReachableRange())\n\t\t\tif (_state.count(_stack[offset]) > _state.targetMinCount(_stack[offset]))\n\t\t\t{\n\t\t\t\tif (offset != stackTop && _stack[offset] != _stack[stackTop])\n\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t_stack.pop();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t// pop anything that can be freely generated\n\t\tfor (StackOffset offset: _state.stackSwapReachableRange())\n\t\t\tif (_stack.canBeFreelyGenerated(_stack[offset]))\n\t\t\t{\n\t\t\t\tif (offset != stackTop && _stack[offset] != _stack[stackTop])\n\t\t\t\t\t_stack.swap(offset);\n\t\t\t\t_stack.pop();\n\t\t\t\treturn true;\n\t\t\t}\n\t\treturn false;\n\t}\n\n\t/// Checks if all current slots are either in a position that is compatible with the target or, if not, are dup-reachable.\n\tstatic std::optional<StackOffset> allNecessarySlotsReachableOrFinal(Stack<Callback> const& _stack, detail::State const& _state)\n\t{\n\t\t// check that args are either in position or reachable\n\t\tfor (StackOffset offset{_state.target().tailSize}; offset < _state.target().size; ++offset.value)\n\t\t\tif (\n\t\t\t\toffset < _state.size() &&\n\t\t\t\t!_state.isArgsCompatible(offset, offset)\n\t\t\t)\n\t\t\t{\n\t\t\t\t// find first occurrence of the slot\n\t\t\t\tstd::optional<StackDepth> depth = _stack.findSlotDepth(_state.targetArg(offset));\n\n\t\t\t\tif (!depth)\n\t\t\t\t{\n\t\t\t\t\t// if there is no occurrence of the slot anywhere, we must be able to freely generate it\n\t\t\t\t\tyulAssert(_stack.canBeFreelyGenerated(_state.targetArg(offset)));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!_stack.swapReachable(*depth))\n\t\t\t\t\t\treturn _stack.depthToOffset(*depth);\n\t\t\t\t}\n\t\t\t}\n\t\t// distribution check: all we have to dup can be duped\n\t\tfor (StackOffset const offset: _state.stackRange())\n\t\t{\n\t\t\tauto const& slotAtOffset = _stack[offset];\n\t\t\t// we don't have enough of the slot\n\t\t\tif (\n\t\t\t\t_state.count(slotAtOffset) < _state.targetMinCount(slotAtOffset) &&\n\t\t\t\t!_stack.dupReachable(offset)\n\t\t\t)\n\t\t\t{\n\t\t\t\t// find first occurrence of the slot\n\t\t\t\tstd::optional<StackDepth> depth = _stack.findSlotDepth(slotAtOffset);\n\t\t\t\t// it must exist\n\t\t\t\tyulAssert(depth);\n\t\t\t\tif (!_stack.dupReachable(*depth))\n\t\t\t\t\treturn _stack.depthToOffset(*depth);\n\t\t\t}\n\t\t}\n\n\t\treturn std::nullopt;\n\t}\n};\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/StackUtils.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/StackUtils.h>\n\n#include <libyul/backends/evm/ssa/StackShuffler.h>\n\n#include <range/v3/numeric/accumulate.hpp>\n#include <range/v3/view/iota.hpp>\n#include <range/v3/view/zip.hpp>\n\n#include <boost/container/flat_map.hpp>\n\n#include <fmt/ranges.h>\n\nusing namespace solidity::yul::ssa;\n\nStackData solidity::yul::ssa::stackPreImage(StackData _stack, PhiInverse const& _phiInverse)\n{\n\tif (!_phiInverse.noOp())\n\t\tfor (auto& slot: _stack)\n\t\t\tif (slot.isValueID())\n\t\t\t\tslot = StackSlot::makeValueID(_phiInverse(slot.valueID()));\n\treturn _stack;\n}\n\nstd::size_t solidity::yul::ssa::findOptimalTargetSize\n(\n\tStackData const& _stackData,\n\tStackData const& _targetArgs,\n\tLivenessAnalysis::LivenessData const& _targetLiveOut,\n\tbool const _canIntroduceJunk,\n\tbool const _hasFunctionReturnLabel\n)\n{\n\tstd::size_t const minSize = _targetLiveOut.size() + _targetArgs.size() + (_hasFunctionReturnLabel ? 1 : 0);\n\tboost::container::flat_map<StackSlot, std::size_t> deficit;\n\tfor (auto const& v: _targetLiveOut | ranges::views::keys)\n\t\tdeficit[StackSlot::makeValueID(v)]++;\n\tfor (auto const& arg: _targetArgs)\n\t\tdeficit[arg]++;\n\tfor (auto const& slot: _stackData)\n\t\tif (auto it = deficit.find(slot); it != deficit.end())\n\t\t\tit->second = it->second > 0 ? it->second - 1 : 0;\n\n\tstd::size_t const pivot = _canIntroduceJunk ? _stackData.size() + _targetArgs.size() : _stackData.size() + ranges::accumulate(deficit | ranges::views::values, 0u);\n\tstd::size_t const startSize = std::max(pivot, minSize);\n\tstatic std::size_t constexpr maxUpwardExpansion = 32;\n\n\tStackData data;\n\tdata.reserve(startSize + maxUpwardExpansion);\n\tauto const evaluateCost = [&](std::size_t const _targetSize) -> std::size_t\n\t{\n\t\tdata = _stackData;\n\t\tStack<CountingInstructionsCallbacks> countOpsStack(data, {});\n\t\tStackShuffler<CountingInstructionsCallbacks>::shuffle(countOpsStack, _targetArgs, _targetLiveOut, _targetSize);\n\t\tyulAssert(countOpsStack.size() == _targetSize);\n\t\treturn countOpsStack.callbacks().numOps;\n\t};\n\n\tstd::size_t bestCost = evaluateCost(startSize);\n\tauto result = startSize;\n\n\t// On non-reverting paths, only search downward from pivot to avoid growing the stack.\n\t// On reverting paths, search in both directions since stack cleanup doesn't matter.\n\tstatic std::size_t constexpr stopAfter = 3;\n\tstd::size_t consecutiveIncreases = 0;\n\t// search downward\n\t{\n\t\tstd::size_t size = startSize;\n\t\twhile (size > minSize)\n\t\t{\n\t\t\t--size;\n\t\t\tauto const cost = evaluateCost(size);\n\t\t\tif (cost < bestCost)\n\t\t\t{\n\t\t\t\tbestCost = cost;\n\t\t\t\tresult = size;\n\t\t\t\tconsecutiveIncreases = 0;\n\t\t\t}\n\t\t\telse if (++consecutiveIncreases >= stopAfter)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\t// search upward (only on reverting paths)\n\tif (_canIntroduceJunk)\n\t{\n\t\tconsecutiveIncreases = 0;\n\t\tfor (std::size_t size = startSize + 1; size <= startSize + maxUpwardExpansion; ++size)\n\t\t{\n\t\t\tauto const cost = evaluateCost(size);\n\t\t\tif (cost < bestCost)\n\t\t\t{\n\t\t\t\tbestCost = cost;\n\t\t\t\tresult = size;\n\t\t\t\tconsecutiveIncreases = 0;\n\t\t\t}\n\t\t\telse if (++consecutiveIncreases >= stopAfter)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\treturn result;\n}\n\nCallSites solidity::yul::ssa::gatherCallSites(SSACFG const& _cfg)\n{\n\tCallSites result;\n\tstd::vector<std::uint8_t> visited(_cfg.numBlocks(), false);\n\tvisited[_cfg.entry.value] = true;\n\tstd::vector<SSACFG::BlockId> toVisit;\n\ttoVisit.reserve(_cfg.numBlocks());\n\ttoVisit.push_back(_cfg.entry);\n\n\twhile (!toVisit.empty())\n\t{\n\t\tauto const blockId = toVisit.back();\n\t\ttoVisit.pop_back();\n\t\tauto const& block = _cfg.block(blockId);\n\t\tblock.forEachExit([&toVisit, &visited](SSACFG::BlockId const& _exitBlockId){\n\t\t\tif (!visited[_exitBlockId.value])\n\t\t\t{\n\t\t\t\tvisited[_exitBlockId.value] = true;\n\t\t\t\ttoVisit.push_back(_exitBlockId);\n\t\t\t}\n\t\t});\n\n\t\tfor (auto const& operation: block.operations)\n\t\t\tif (auto const* call = std::get_if<SSACFG::Call>(&operation.kind))\n\t\t\t\tif (call->canContinue)\n\t\t\t\t\tresult.addCallSite(&call->call.get());\n\t}\n\treturn result;\n}\n\nstd::string ValidationResult::formatErrors() const\n{\n\treturn fmt::format(\"{}\", fmt::join(m_errors, \"\\n\"));\n}\n\nValidationResult solidity::yul::ssa::checkLayoutCompatibility(StackData const& _current, StackData const& _desired)\n{\n\tValidationResult result;\n\tif (_current.size() != _desired.size())\n\t\treturn result.addError(fmt::format(\n\t\t\t\"size mismatch: {} = len({}) =/= len({}) = {}\",\n\t\t\t_current.size(), stackToString(_current), stackToString(_desired), _desired.size()\n\t\t));\n\tfor (auto&& [index, currentSlot, desiredSlot]: ranges::zip_view(ranges::views::iota(0), _current, _desired))\n\t\tif (!desiredSlot.isJunk() && currentSlot != desiredSlot)\n\t\t\tresult.addError(fmt::format(\n\t\t\t\t\"stack element mismatch: {} = {}[{}] =/= {}[{}] = {}\",\n\t\t\t\tslotToString(currentSlot),\n\t\t\t\tstackToString(_current),\n\t\t\t\tindex,\n\t\t\t\tstackToString(_desired),\n\t\t\t\tindex,\n\t\t\t\tslotToString(desiredSlot)\n\t\t\t));\n\treturn result;\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/StackUtils.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/PhiInverse.h>\n#include <libyul/backends/evm/ssa/Stack.h>\n\n#include <string>\n#include <vector>\n\nnamespace solidity::yul::ssa\n{\n\nclass ValidationResult\n{\npublic:\n\tbool ok() const { return m_errors.empty(); }\n\tstd::string formatErrors() const;\n\tValidationResult& addError(std::string _msg) { m_errors.push_back(std::move(_msg)); return *this; }\n\tstd::vector<std::string> const& errors() const { return m_errors; }\nprivate:\n\tstd::vector<std::string> m_errors;\n};\n\nstruct CountingInstructionsCallbacks\n{\n\tstd::size_t numOps = 0;\n\tvoid swap(StackDepth) { ++numOps; }\n\tvoid dup(StackDepth) { ++numOps; }\n\tvoid push(StackSlot const&) { ++numOps; }\n\tvoid pop() { ++numOps; }\n};\n\n/// Transform stack data by replacing all its phi variables with their respective preimages.\nStackData stackPreImage(StackData _stack, PhiInverse const& _phiInverse);\n\nstd::size_t findOptimalTargetSize(StackData const& _stackData, StackData const& _targetArgs, LivenessAnalysis::LivenessData const& _targetLiveOut, bool _canIntroduceJunk, bool _hasFunctionReturnLabel);\n\nCallSites gatherCallSites(SSACFG const& _cfg);\n\n/// Checks that _current and _desired have the same size and that each slot matches,\n/// treating junk slots in _desired as wildcards.\nValidationResult checkLayoutCompatibility(StackData const& _current, StackData const& _desired);\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/io/DotExporterBase.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/io/DotExporterBase.h>\n\n#include <libsolutil/Numeric.h>\n#include <libsolutil/Visitor.h>\n\n#include <fmt/ranges.h>\n\n#include <deque>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::yul;\nusing namespace solidity::yul::ssa;\nusing namespace solidity::yul::ssa::io;\n\nDotExporterBase::DotExporterBase(SSACFG const& _cfg, size_t const _functionIndex, RankDir const _rankDir):\n\tm_cfg(_cfg),\n\tm_functionIndex(_functionIndex),\n\tm_rankDir(_rankDir)\n{\n}\n\nstd::string DotExporterBase::escapeId(std::string_view const _str)\n{\n\tstd::string result;\n\tresult.reserve(_str.size());\n\tfor (auto const c: _str)\n\t{\n\t\tif (std::isalnum(static_cast<unsigned char>(c)) || c == '_')\n\t\t\tresult += c;\n\t\telse\n\t\t\tresult += '_';\n\t}\n\treturn result;\n}\n\nstd::string DotExporterBase::escapeLabel(std::string_view const _str)\n{\n\tstd::string result;\n\tresult.reserve(_str.size());\n\tfor (auto const c: _str)\n\t{\n\t\tif (c == '\"' || c == '\\\\')\n\t\t\tresult += '\\\\';\n\t\tresult += c;\n\t}\n\treturn result;\n}\n\nstd::string DotExporterBase::formatBlockHandle(SSACFG::BlockId _id) const\n{\n\treturn fmt::format(\"Block{}_{}\", m_functionIndex, _id.value);\n}\n\nstd::string DotExporterBase::formatEdge(SSACFG::BlockId _source, SSACFG::BlockId _target, std::optional<std::string> const& _exitPort)\n{\n\tstd::string const style = edgeStyle(_source, _target) == EdgeStyle::Dashed ? \"dashed\" : \"solid\";\n\tif (_exitPort)\n\t\treturn fmt::format(\"{}Exit:{} -> {} [style=\\\"{}\\\"];\\n\", formatBlockHandle(_source), *_exitPort, formatBlockHandle(_target), style);\n\telse\n\t\treturn fmt::format(\"{}Exit -> {} [style=\\\"{}\\\"];\\n\", formatBlockHandle(_source), formatBlockHandle(_target), style);\n}\n\nvoid DotExporterBase::writeBlock(std::ostream& _out, SSACFG::BlockId const _id)\n{\n\tauto const& block = m_cfg.block(_id);\n\n\tauto const attributes = blockNodeAttributes(_id);\n\tstd::string attrStr;\n\tfor (auto const& [name, value]: attributes)\n\t\tattrStr += fmt::format(\"{}={}, \", name, value);\n\t_out << fmt::format(\"{} [{}label=\\\"\", formatBlockHandle(_id), attrStr);\n\twriteBlockLabel(_out, _id);\n\t_out << \"\\\"];\\n\";\n\n\tstd::visit(GenericVisitor{\n\t\t[&](SSACFG::BasicBlock::MainExit const&)\n\t\t{\n\t\t\t_out << fmt::format(\"{}Exit [label=\\\"MainExit\\\"];\\n\", formatBlockHandle(_id));\n\t\t\t_out << fmt::format(\"{} -> {}Exit;\\n\", formatBlockHandle(_id), formatBlockHandle(_id));\n\t\t},\n\t\t[&](SSACFG::BasicBlock::Jump const& _jump)\n\t\t{\n\t\t\t_out << fmt::format(\"{} -> {}Exit [arrowhead=none];\\n\", formatBlockHandle(_id), formatBlockHandle(_id));\n\t\t\t_out << fmt::format(\"{}Exit [label=\\\"Jump\\\" shape=oval];\\n\", formatBlockHandle(_id));\n\t\t\t_out << formatEdge(_id, _jump.target);\n\t\t},\n\t\t[&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump)\n\t\t{\n\t\t\t_out << fmt::format(\"{} -> {}Exit;\\n\", formatBlockHandle(_id), formatBlockHandle(_id));\n\t\t\t_out << fmt::format(\n\t\t\t\t\"{}Exit [label=\\\"{{ If {} | {{ <0> Zero | <1> NonZero }}}}\\\" shape=Mrecord];\\n\",\n\t\t\t\tformatBlockHandle(_id), _conditionalJump.condition.str(m_cfg)\n\t\t\t);\n\t\t\t_out << formatEdge(_id, _conditionalJump.zero, \"0\");\n\t\t\t_out << formatEdge(_id, _conditionalJump.nonZero, \"1\");\n\t\t},\n\t\t[&](SSACFG::BasicBlock::FunctionReturn const& fr)\n\t\t{\n\t\t\tauto const valueToString = [&](SSACFG::ValueId const& valueId) { return valueId.str(m_cfg); };\n\t\t\t_out << fmt::format(\"{}Exit [label=\\\"FunctionReturn[{}]\\\"];\\n\",\n\t\t\t\tformatBlockHandle(_id),\n\t\t\t\tfmt::join(fr.returnValues | ranges::views::transform(valueToString), \", \")\n\t\t\t);\n\t\t\t_out << fmt::format(\"{} -> {}Exit;\\n\", formatBlockHandle(_id), formatBlockHandle(_id));\n\t\t},\n\t\t[&](SSACFG::BasicBlock::Terminated const&)\n\t\t{\n\t\t\t_out << fmt::format(\"{}Exit [label=\\\"Terminated\\\"];\\n\", formatBlockHandle(_id));\n\t\t\t_out << fmt::format(\"{} -> {}Exit;\\n\", formatBlockHandle(_id), formatBlockHandle(_id));\n\t\t}\n\t}, block.exit);\n}\n\nvoid DotExporterBase::traverse(std::ostream& _out, SSACFG::BlockId _entry)\n{\n\tstd::vector<std::uint8_t> explored(m_cfg.numBlocks(), false);\n\texplored[_entry.value] = true;\n\n\tstd::deque<SSACFG::BlockId> toVisit{};\n\ttoVisit.emplace_back(_entry);\n\n\twhile (!toVisit.empty())\n\t{\n\t\tauto const id = toVisit.front();\n\t\ttoVisit.pop_front();\n\t\twriteBlock(_out, id);\n\t\tm_cfg.block(id).forEachExit(\n\t\t\t[&](SSACFG::BlockId const& _exitBlock)\n\t\t\t{\n\t\t\t\tif (!explored[_exitBlock.value])\n\t\t\t\t{\n\t\t\t\t\texplored[_exitBlock.value] = true;\n\t\t\t\t\ttoVisit.emplace_back(_exitBlock);\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n}\n\nstd::string DotExporterBase::exportBlocks(SSACFG::BlockId _entry, bool _wrapInDigraph)\n{\n\tstd::ostringstream out;\n\tif (_wrapInDigraph)\n\t\tout << fmt::format(\"digraph SSACFG {{\\nnodesep=0.7;\\ngraph[fontname=\\\"DejaVu Sans\\\", rankdir={}]\\nnode[shape=box,fontname=\\\"DejaVu Sans\\\"];\\n\\n\", m_rankDir);\n\tout << fmt::format(\"Entry [label=\\\"Entry\\\"];\\n\");\n\tout << fmt::format(\"Entry -> {};\\n\", formatBlockHandle(_entry));\n\ttraverse(out, _entry);\n\tif (_wrapInDigraph)\n\t\tout << \"}\\n\";\n\treturn out.str();\n}\n\nstd::string DotExporterBase::exportFunction(Scope::Function const& _function, bool _wrapInDigraph)\n{\n\tstd::ostringstream out;\n\tif (_wrapInDigraph)\n\t\tout << fmt::format(\"digraph SSACFG {{\\nnodesep=0.7;\\ngraph[fontname=\\\"DejaVu Sans\\\", rankdir={}]\\nnode[shape=box,fontname=\\\"DejaVu Sans\\\"];\\n\\n\", m_rankDir);\n\n\tstatic auto constexpr returnsTransform = [](auto const& functionReturnValue) { return escapeLabel(functionReturnValue.get().name.str()); };\n\tstatic auto constexpr argsTransform = [](auto const& arg) { return fmt::format(\"v{}\", std::get<1>(arg).value()); };\n\tauto const entryHandle = fmt::format(\"FunctionEntry_{}_{}\", escapeId(_function.name.str()), m_cfg.entry.value);\n\tif (!m_cfg.returns.empty())\n\t\tout << fmt::format(\"{} [label=\\\"function {}:\\n {} := {}({})\\\"];\\n\",\n\t\t\tentryHandle, escapeLabel(_function.name.str()),\n\t\t\tfmt::join(m_cfg.returns | ranges::views::transform(returnsTransform), \", \"),\n\t\t\tescapeLabel(_function.name.str()),\n\t\t\tfmt::join(m_cfg.arguments | ranges::views::transform(argsTransform), \", \"));\n\telse\n\t\tout << fmt::format(\"{} [label=\\\"function {}:\\n {}({})\\\"];\\n\",\n\t\t\tentryHandle, escapeLabel(_function.name.str()),\n\t\t\tescapeLabel(_function.name.str()),\n\t\t\tfmt::join(m_cfg.arguments | ranges::views::transform(argsTransform), \", \"));\n\tout << fmt::format(\"{} -> {};\\n\", entryHandle, formatBlockHandle(m_cfg.entry));\n\ttraverse(out, m_cfg.entry);\n\n\tif (_wrapInDigraph)\n\t\tout << \"}\\n\";\n\treturn out.str();\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/io/DotExporterBase.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/SSACFG.h>\n\n#include <fmt/format.h>\n\n#include <optional>\n#include <string>\n#include <utility>\n#include <vector>\n\nnamespace solidity::yul::ssa::io\n{\n\n/// Base class for exporting an SSACFG to Graphviz dot format.\n/// Handles graph structure (BFS traversal, edges, exit nodes, entry nodes) and\n/// delegates block content rendering to derived classes via writeBlockLabel().\nclass DotExporterBase\n{\npublic:\n\tenum class EdgeStyle { Solid, Dashed };\n\tenum class RankDir { TB, BT, LR, RL };\n\n\tDotExporterBase(SSACFG const& _cfg, size_t _functionIndex, RankDir _rankDir = RankDir::LR);\n\tvirtual ~DotExporterBase() = default;\n\n\tstd::string exportBlocks(SSACFG::BlockId _entry, bool _wrapInDigraph = true);\n\tstd::string exportFunction(Scope::Function const& _function, bool _wrapInDigraph = true);\n\nprotected:\n\t/// Override to write the content inside a block's dot label.\n\t/// Everything between the opening `label=\"` and the closing `\"` is the responsibility of this method.\n\tvirtual void writeBlockLabel(std::ostream& _out, SSACFG::BlockId _blockId) = 0;\n\n\t/// Override to provide extra node attributes (e.g., fillcolor).\n\tvirtual std::vector<std::pair<std::string, std::string>> blockNodeAttributes(SSACFG::BlockId) { return {}; }\n\n\t/// Override to customize edge style (e.g., dashed for back edges).\n\tvirtual EdgeStyle edgeStyle(SSACFG::BlockId, SSACFG::BlockId) { return EdgeStyle::Solid; }\n\n\tstd::string formatBlockHandle(SSACFG::BlockId _id) const;\n\t/// Escapes a string for use in dot node IDs (replaces non-alphanumeric characters with underscores).\n\tstatic std::string escapeId(std::string_view _str);\n\t/// Escapes a string for use inside dot label text (escapes quotes and backslashes).\n\tstatic std::string escapeLabel(std::string_view _str);\n\n\tSSACFG const& m_cfg;\n\tsize_t m_functionIndex;\n\tRankDir m_rankDir;\n\nprivate:\n\tvoid writeBlock(std::ostream& _out, SSACFG::BlockId _id);\n\tstd::string formatEdge(SSACFG::BlockId _source, SSACFG::BlockId _target, std::optional<std::string> const& _exitPort = std::nullopt);\n\tvoid traverse(std::ostream& _out, SSACFG::BlockId _entry);\n};\n\n}\n\ntemplate<>\nstruct fmt::formatter<solidity::yul::ssa::io::DotExporterBase::RankDir>: fmt::formatter<std::string_view>\n{\n\tauto format(solidity::yul::ssa::io::DotExporterBase::RankDir _rankDir, fmt::format_context& _ctx) const\n\t{\n\t\tusing RankDir = solidity::yul::ssa::io::DotExporterBase::RankDir;\n\t\tstd::string_view name;\n\t\tswitch (_rankDir)\n\t\t{\n\t\t\tcase RankDir::TB: name = \"TB\"; break;\n\t\t\tcase RankDir::BT: name = \"BT\"; break;\n\t\t\tcase RankDir::LR: name = \"LR\"; break;\n\t\t\tcase RankDir::RL: name = \"RL\"; break;\n\t\t}\n\t\treturn fmt::formatter<std::string_view>::format(name, _ctx);\n\t}\n};\n"
  },
  {
    "path": "libyul/backends/evm/ssa/io/JSONExporter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/io/JSONExporter.h>\n\n#include <libyul/Utilities.h>\n\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/Numeric.h>\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/view/drop.hpp>\n#include <range/v3/view/enumerate.hpp>\n#include <range/v3/view/transform.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::yul::ssa;\nusing namespace solidity::yul::ssa::io::json;\n\nnamespace\n{\nJson toJson(SSACFG const& _cfg, std::vector<SSACFG::ValueId> const& _values)\n{\n\tJson ret = Json::array();\n\tfor (auto const& value: _values)\n\t\tret.push_back(value.str(_cfg));\n\treturn ret;\n}\n\nJson toJson(Json& _ret, SSACFG const& _cfg, SSACFG::Operation const& _operation)\n{\n\tJson opJson = Json::object();\n\tstd::visit(util::GenericVisitor{\n\t\t[&](SSACFG::Call const& _call) {\n\t\t\t_ret[\"type\"] = \"FunctionCall\";\n\t\t\topJson[\"op\"] = _call.function.get().name.str();\n\t\t},\n\t\t[&](SSACFG::LiteralAssignment const&) {\n\t\t\tyulAssert(_operation.inputs.size() == 1);\n\t\t\tyulAssert(_operation.inputs.back().isLiteral());\n\t\t\topJson[\"op\"] = \"LiteralAssignment\";\n\t\t},\n\t\t[&](SSACFG::BuiltinCall const& _call) {\n\t\t\t_ret[\"type\"] = \"BuiltinCall\";\n\t\t\tJson builtinArgsJson = Json::array();\n\t\t\tauto const& builtin = _call.builtin.get();\n\t\t\tif (!builtin.literalArguments.empty())\n\t\t\t{\n\t\t\t\tauto const& functionCallArgs = _call.call.get().arguments;\n\t\t\t\tfor (size_t i = 0; i < builtin.literalArguments.size(); ++i)\n\t\t\t\t{\n\t\t\t\t\tstd::optional<LiteralKind> const& argument = builtin.literalArguments[i];\n\t\t\t\t\tif (argument.has_value() && i < functionCallArgs.size())\n\t\t\t\t\t{\n\t\t\t\t\t\t// The function call argument at index i must be a literal if builtin.literalArguments[i] is not nullopt\n\t\t\t\t\t\tyulAssert(std::holds_alternative<Literal>(functionCallArgs[i]));\n\t\t\t\t\t\tbuiltinArgsJson.push_back(formatLiteral(std::get<Literal>(functionCallArgs[i])));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!builtinArgsJson.empty())\n\t\t\t\topJson[\"literalArgs\"] = builtinArgsJson;\n\n\t\t\topJson[\"op\"] = _call.builtin.get().name;\n\t\t},\n\t}, _operation.kind);\n\n\topJson[\"in\"] = toJson(_cfg, _operation.inputs);\n\topJson[\"out\"] = toJson(_cfg, _operation.outputs);\n\n\treturn opJson;\n}\n\nJson toJson(SSACFG const& _cfg, SSACFG::BlockId _blockId, LivenessAnalysis const* _liveness)\n{\n\tauto const valueToString = [&](LivenessAnalysis::LivenessData::LiveCounts::value_type const& _live) { return _live.first.str(_cfg); };\n\n\tJson blockJson = Json::object();\n\tauto const& block = _cfg.block(_blockId);\n\n\tblockJson[\"id\"] = \"Block\" + std::to_string(_blockId.value);\n\tif (_liveness)\n\t{\n\t\tJson livenessJson = Json::object();\n\t\tlivenessJson[\"in\"] = _liveness->liveIn(_blockId)\n\t\t\t| ranges::views::transform(valueToString)\n\t\t\t| ranges::to<Json::array_t>();\n\t\tlivenessJson[\"out\"] = _liveness->liveOut(_blockId)\n\t\t\t| ranges::views::transform(valueToString)\n\t\t\t| ranges::to<Json::array_t>();\n\t\tblockJson[\"liveness\"] = livenessJson;\n\t}\n\tblockJson[\"instructions\"] = Json::array();\n\tif (!block.phis.empty())\n\t{\n\t\tblockJson[\"entries\"] = block.entries\n\t\t\t| ranges::views::transform([](auto const& entry) { return \"Block\" + std::to_string(entry.value); })\n\t\t\t| ranges::to<Json::array_t>();\n\t\tfor (auto const& phi: block.phis)\n\t\t{\n\t\t\tauto const& phiInfo = _cfg.phiInfo(phi);\n\t\t\tJson phiJson = Json::object();\n\t\t\tphiJson[\"op\"] = \"PhiFunction\";\n\t\t\tphiJson[\"in\"] = toJson(_cfg, phiInfo.arguments);\n\t\t\tphiJson[\"out\"] = toJson(_cfg, std::vector{phi});\n\t\t\tblockJson[\"instructions\"].push_back(phiJson);\n\t\t}\n\t}\n\tfor (auto const& operation: block.operations)\n\t\tblockJson[\"instructions\"].push_back(toJson(blockJson, _cfg, operation));\n\n\treturn blockJson;\n}\n\nJson exportBlock(SSACFG const& _cfg, SSACFG::BlockId _entryId, LivenessAnalysis const* _liveness)\n{\n\tJson blocksJson = Json::array();\n\tutil::BreadthFirstSearch<SSACFG::BlockId> bfs{{{_entryId}}};\n\tbfs.run([&](SSACFG::BlockId _blockId, auto _addChild) {\n\t\tJson blockJson = toJson(_cfg, _blockId, _liveness);\n\n\t\tJson exitBlockJson = Json::object();\n\t\tstd::visit(util::GenericVisitor{\n\t\t\t[&](SSACFG::BasicBlock::MainExit const&) {\n\t\t\t\texitBlockJson[\"type\"] = \"MainExit\";\n\t\t\t},\n\t\t\t[&](SSACFG::BasicBlock::Jump const& _jump){\n\t\t\t\texitBlockJson[\"targets\"] = { \"Block\" + std::to_string(_jump.target.value) };\n\t\t\t\texitBlockJson[\"type\"] = \"Jump\";\n\t\t\t\t_addChild(_jump.target);\n\t\t\t},\n\t\t\t[&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) {\n\t\t\t\texitBlockJson[\"targets\"] = { \"Block\" + std::to_string(_conditionalJump.zero.value), \"Block\" + std::to_string(_conditionalJump.nonZero.value) };\n\t\t\t\texitBlockJson[\"cond\"] = _conditionalJump.condition.str(_cfg);\n\t\t\t\texitBlockJson[\"type\"] = \"ConditionalJump\";\n\n\t\t\t\t_addChild(_conditionalJump.zero);\n\t\t\t\t_addChild(_conditionalJump.nonZero);\n\t\t\t},\n\t\t\t[&](SSACFG::BasicBlock::FunctionReturn const& _return) {\n\t\t\t\texitBlockJson[\"returnValues\"] = toJson(_cfg, _return.returnValues);\n\t\t\t\texitBlockJson[\"type\"] = \"FunctionReturn\";\n\t\t\t},\n\t\t\t[&](SSACFG::BasicBlock::Terminated const&) {\n\t\t\t\texitBlockJson[\"type\"] = \"Terminated\";\n\t\t\t}\n\t\t}, _cfg.block(_blockId).exit);\n\t\tblockJson[\"exit\"] = exitBlockJson;\n\t\tblocksJson.emplace_back(blockJson);\n\t});\n\n\treturn blocksJson;\n}\n\nJson exportFunction(SSACFG const& _cfg, LivenessAnalysis const* _liveness)\n{\n\tJson functionJson = Json::object();\n\tfunctionJson[\"type\"] = \"Function\";\n\tfunctionJson[\"entry\"] = \"Block\" + std::to_string(_cfg.entry.value);\n\tstatic auto constexpr argsTransform = [](auto const& _arg) { return fmt::format(\"v{}\", std::get<1>(_arg).value()); };\n\tfunctionJson[\"arguments\"] = _cfg.arguments | ranges::views::transform(argsTransform) | ranges::to<std::vector>;\n\tfunctionJson[\"numReturns\"] = _cfg.returns.size();\n\tfunctionJson[\"blocks\"] = exportBlock(_cfg, _cfg.entry, _liveness);\n\treturn functionJson;\n}\n\n}\n\nJson io::json::exportControlFlow(ControlFlow const& _controlFlow, ControlFlowLiveness const* _liveness)\n{\n\tif (_liveness)\n\t\tyulAssert(&_liveness->controlFlow.get() == &_controlFlow);\n\n\tJson yulObjectJson = Json::object();\n\tyulObjectJson[\"blocks\"] = exportBlock(*_controlFlow.mainGraph(), SSACFG::BlockId{0}, _liveness ? _liveness->cfgLiveness.front().get() : nullptr);\n\n\tJson functionsJson = Json::object();\n\tsize_t index = 1;\n\tfor (auto const& [function, functionGraph]: _controlFlow.functionGraphMapping | ranges::views::drop(1))\n\t{\n\t\tfunctionsJson[function->name.str()] = exportFunction(*functionGraph, _liveness ? _liveness->cfgLiveness[index++].get() : nullptr);\n\t}\n\tyulObjectJson[\"functions\"] = functionsJson;\n\n\treturn yulObjectJson;\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/io/JSONExporter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/ControlFlow.h>\n#include <libsolutil/JSON.h>\n\nnamespace solidity::yul::ssa::io::json\n{\n\nJson exportControlFlow(ControlFlow const& _controlFlow, ControlFlowLiveness const* _liveness);\n\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/traversal/ForwardTopologicalSort.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/backends/evm/ssa/traversal/ForwardTopologicalSort.h>\n\nusing namespace solidity::yul::ssa::traversal;\n\nForwardTopologicalSort::ForwardTopologicalSort(SSACFG const& _cfg):\n\tm_cfg(_cfg),\n\tm_explored(m_cfg.numBlocks(), false), m_blockWisePreOrder(m_cfg.numBlocks(), 0),\n\tm_blockWiseMaxSubtreePreOrder(m_cfg.numBlocks(), 0)\n{\n\tyulAssert(m_cfg.entry.value == 0);\n\tm_preOrder.reserve(m_cfg.numBlocks());\n\tm_postOrder.reserve(m_cfg.numBlocks());\n\tdfs(0);\n\n\tfor (auto const& [v1, v2]: m_potentialBackEdges)\n\t\tif (ancestor(v2, v1))\n\t\t\tm_backEdgeTargets.insert(v2);\n}\n\nvoid ForwardTopologicalSort::dfs(SSACFG::BlockId::ValueType const _vertex) {\n\tyulAssert(!m_explored[_vertex]);\n\tm_explored[_vertex] = true;\n\tm_blockWisePreOrder[_vertex] = static_cast<SSACFG::BlockId::ValueType>(m_preOrder.size());\n\tm_blockWiseMaxSubtreePreOrder[_vertex] = m_blockWisePreOrder[_vertex];\n\tm_preOrder.push_back(_vertex);\n\n\tm_cfg.block(SSACFG::BlockId{_vertex}).forEachExit([&](SSACFG::BlockId const& _exitBlock){\n\t\tif (!m_explored[_exitBlock.value])\n\t\t{\n\t\t\tdfs(_exitBlock.value);\n\t\t\tm_blockWiseMaxSubtreePreOrder[_vertex] = std::max(m_blockWiseMaxSubtreePreOrder[_vertex], m_blockWiseMaxSubtreePreOrder[_exitBlock.value]);\n\t\t}\n\t\telse\n\t\t\tm_potentialBackEdges.emplace_back(_vertex, _exitBlock.value);\n\t});\n\n\tm_postOrder.push_back(_vertex);\n}\n\nbool ForwardTopologicalSort::ancestor(SSACFG::BlockId::ValueType const _block1, SSACFG::BlockId::ValueType const _block2) const {\n\tyulAssert(_block1 < m_blockWisePreOrder.size());\n\tyulAssert(_block2 < m_blockWisePreOrder.size());\n\n\tauto const preOrderIndex1 = m_blockWisePreOrder[_block1];\n\tauto const preOrderIndex2 = m_blockWisePreOrder[_block2];\n\n\tbool const node1VisitedBeforeNode2 = preOrderIndex1 <= preOrderIndex2;\n\tbool const node2InSubtreeOfNode1 = preOrderIndex2 <= m_blockWiseMaxSubtreePreOrder[_block1];\n\treturn node1VisitedBeforeNode2 && node2InSubtreeOfNode1;\n}\n\nbool ForwardTopologicalSort::backEdge(SSACFG::BlockId const& _block1, SSACFG::BlockId const& _block2) const\n{\n\tif (ancestor(_block2.value, _block1.value))\n\t{\n\t\t// check that block1 -> block2 is indeed an edge in the cfg\n\t\tbool isEdge = false;\n\t\tm_cfg.block(_block1).forEachExit([&_block2, &isEdge](SSACFG::BlockId const& _exit) { isEdge |= _block2 == _exit; });\n\t\treturn isEdge;\n\t}\n\treturn false;\n}\n"
  },
  {
    "path": "libyul/backends/evm/ssa/traversal/ForwardTopologicalSort.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/backends/evm/ssa/SSACFG.h>\n\n#include <cstddef>\n#include <set>\n#include <vector>\n\nnamespace solidity::yul::ssa::traversal\n{\n\n/// Performs a topological sort on the forward CFG (no back/cross edges)\nclass ForwardTopologicalSort\n{\npublic:\n\texplicit ForwardTopologicalSort(SSACFG const& _cfg);\n\n\tstd::vector<SSACFG::BlockId::ValueType> const& preOrder() const { return m_preOrder; }\n\tstd::vector<SSACFG::BlockId::ValueType> const& postOrder() const { return m_postOrder; }\n\tstd::set<SSACFG::BlockId::ValueType> const& backEdgeTargets() const { return m_backEdgeTargets; }\n\tSSACFG const& cfg() const { return m_cfg; }\n\tbool backEdge(SSACFG::BlockId const& _block1, SSACFG::BlockId const& _block2) const;\n\tSSACFG::BlockId::ValueType preOrderIndexOf(SSACFG::BlockId::ValueType _block) const { return m_blockWisePreOrder[_block]; }\n\tSSACFG::BlockId::ValueType maxSubtreePreOrderIndexOf(SSACFG::BlockId::ValueType _block) const { return m_blockWiseMaxSubtreePreOrder[_block]; }\n\nprivate:\n\tvoid dfs(SSACFG::BlockId::ValueType _vertex);\n\t/// Checks if block1 is an ancestor of block2, ie there's a path from block1 to block2 in the dfs tree\n\tbool ancestor(SSACFG::BlockId::ValueType _block1, SSACFG::BlockId::ValueType _block2) const;\n\n\tSSACFG const& m_cfg;\n\tstd::vector<char> m_explored{};\n\tstd::vector<SSACFG::BlockId::ValueType> m_postOrder{};\n\tstd::vector<SSACFG::BlockId::ValueType> m_preOrder{};\n\tstd::vector<SSACFG::BlockId::ValueType> m_blockWisePreOrder{};\n\tstd::vector<SSACFG::BlockId::ValueType> m_blockWiseMaxSubtreePreOrder{};\n\tstd::vector<std::tuple<SSACFG::BlockId::ValueType, SSACFG::BlockId::ValueType>> m_potentialBackEdges{};\n\tstd::set<SSACFG::BlockId::ValueType> m_backEdgeTargets{};\n};\n}\n"
  },
  {
    "path": "libyul/optimiser/ASTCopier.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Creates an independent copy of an AST, renaming identifiers to be unique.\n */\n\n#include <libyul/optimiser/ASTCopier.h>\n\n#include <libyul/AST.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/Visitor.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nStatement ASTCopier::operator()(ExpressionStatement const& _statement)\n{\n\treturn ExpressionStatement{ _statement.debugData, translate(_statement.expression) };\n}\n\nStatement ASTCopier::operator()(VariableDeclaration const& _varDecl)\n{\n\treturn VariableDeclaration{\n\t\t_varDecl.debugData,\n\t\ttranslateVector(_varDecl.variables),\n\t\ttranslate(_varDecl.value)\n\t};\n}\n\nStatement ASTCopier::operator()(Assignment const& _assignment)\n{\n\treturn Assignment{\n\t\t_assignment.debugData,\n\t\ttranslateVector(_assignment.variableNames),\n\t\ttranslate(_assignment.value)\n\t};\n}\n\nExpression ASTCopier::operator()(FunctionCall const& _call)\n{\n\treturn FunctionCall{\n\t\t_call.debugData,\n\t\ttranslate(_call.functionName),\n\t\ttranslateVector(_call.arguments)\n\t};\n}\n\nExpression ASTCopier::operator()(Identifier const& _identifier)\n{\n\treturn translate(_identifier);\n}\n\nExpression ASTCopier::operator()(Literal const& _literal)\n{\n\treturn translate(_literal);\n}\n\nStatement ASTCopier::operator()(If const& _if)\n{\n\treturn If{_if.debugData, translate(_if.condition), translate(_if.body)};\n}\n\nStatement ASTCopier::operator()(Switch const& _switch)\n{\n\treturn Switch{_switch.debugData, translate(_switch.expression), translateVector(_switch.cases)};\n}\n\nStatement ASTCopier::operator()(FunctionDefinition const& _function)\n{\n\tYulName translatedName = translateIdentifier(_function.name);\n\n\tenterFunction(_function);\n\tScopeGuard g([&]() { this->leaveFunction(_function); });\n\n\treturn FunctionDefinition{\n\t\t_function.debugData,\n\t\ttranslatedName,\n\t\ttranslateVector(_function.parameters),\n\t\ttranslateVector(_function.returnVariables),\n\t\ttranslate(_function.body)\n\t};\n}\n\nStatement ASTCopier::operator()(ForLoop const& _forLoop)\n{\n\tenterScope(_forLoop.pre);\n\tScopeGuard g([&]() { this->leaveScope(_forLoop.pre); });\n\n\treturn ForLoop{\n\t\t_forLoop.debugData,\n\t\ttranslate(_forLoop.pre),\n\t\ttranslate(_forLoop.condition),\n\t\ttranslate(_forLoop.post),\n\t\ttranslate(_forLoop.body)\n\t};\n}\nStatement ASTCopier::operator()(Break const& _break)\n{\n\treturn Break{ _break };\n}\n\nStatement ASTCopier::operator()(Continue const& _continue)\n{\n\treturn Continue{ _continue };\n}\n\nStatement ASTCopier::operator()(Leave const& _leaveStatement)\n{\n\treturn Leave{_leaveStatement};\n}\n\nStatement ASTCopier::operator ()(Block const& _block)\n{\n\treturn translate(_block);\n}\n\nExpression ASTCopier::translate(Expression const& _expression)\n{\n\treturn std::visit(static_cast<ExpressionCopier&>(*this), _expression);\n}\n\nStatement ASTCopier::translate(Statement const& _statement)\n{\n\treturn std::visit(static_cast<StatementCopier&>(*this), _statement);\n}\n\nBlock ASTCopier::translate(Block const& _block)\n{\n\tenterScope(_block);\n\tScopeGuard g([&]() { this->leaveScope(_block); });\n\n\treturn Block{_block.debugData, translateVector(_block.statements)};\n}\n\nCase ASTCopier::translate(Case const& _case)\n{\n\treturn Case{_case.debugData, translate(_case.value), translate(_case.body)};\n}\n\nFunctionName ASTCopier::translate(FunctionName const& _functionName)\n{\n\tGenericVisitor visitor{\n\t\t[&](Identifier const& _identifier) -> FunctionName { return translate(_identifier); },\n\t\t[](BuiltinName const& _builtin) -> FunctionName { return _builtin; }\n\t};\n\treturn std::visit(visitor, _functionName);\n}\n\nIdentifier ASTCopier::translate(Identifier const& _identifier)\n{\n\treturn Identifier{_identifier.debugData, translateIdentifier(_identifier.name)};\n}\n\nLiteral ASTCopier::translate(Literal const& _literal)\n{\n\treturn _literal;\n}\n\nNameWithDebugData ASTCopier::translate(NameWithDebugData const& _typedName)\n{\n\treturn NameWithDebugData{_typedName.debugData, translateIdentifier(_typedName.name)};\n}\n\nYulName FunctionCopier::translateIdentifier(YulName _name)\n{\n\treturn util::valueOrDefault(m_translations, _name, _name);\n}\n"
  },
  {
    "path": "libyul/optimiser/ASTCopier.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Creates an independent copy of an AST, renaming identifiers to be unique.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n\n#include <libyul/YulName.h>\n\n#include <memory>\n#include <optional>\n#include <set>\n#include <vector>\n#include <map>\n\nnamespace solidity::yul\n{\n\nclass ExpressionCopier\n{\npublic:\n\tvirtual ~ExpressionCopier() = default;\n\tvirtual Expression operator()(Literal const& _literal) = 0;\n\tvirtual Expression operator()(Identifier const& _identifier) = 0;\n\tvirtual Expression operator()(FunctionCall const&) = 0;\n};\n\nclass StatementCopier\n{\npublic:\n\tvirtual ~StatementCopier() = default;\n\tvirtual Statement operator()(ExpressionStatement const& _statement) = 0;\n\tvirtual Statement operator()(Assignment const& _assignment) = 0;\n\tvirtual Statement operator()(VariableDeclaration const& _varDecl) = 0;\n\tvirtual Statement operator()(If const& _if) = 0;\n\tvirtual Statement operator()(Switch const& _switch) = 0;\n\tvirtual Statement operator()(FunctionDefinition const&) = 0;\n\tvirtual Statement operator()(ForLoop const&) = 0;\n\tvirtual Statement operator()(Break const&) = 0;\n\tvirtual Statement operator()(Continue const&) = 0;\n\tvirtual Statement operator()(Leave const&) = 0;\n\tvirtual Statement operator()(Block const& _block) = 0;\n};\n\n/**\n * Creates a copy of a Yul AST potentially replacing identifier names.\n * Base class to be extended.\n */\nclass ASTCopier: public ExpressionCopier, public StatementCopier\n{\npublic:\n\t~ASTCopier() override = default;\n\tExpression operator()(Literal const& _literal) override;\n\tExpression operator()(Identifier const& _identifier) override;\n\tExpression operator()(FunctionCall const&) override;\n\tStatement operator()(ExpressionStatement const& _statement) override;\n\tStatement operator()(Assignment const& _assignment) override;\n\tStatement operator()(VariableDeclaration const& _varDecl) override;\n\tStatement operator()(If const& _if) override;\n\tStatement operator()(Switch const& _switch) override;\n\tStatement operator()(FunctionDefinition const&) override;\n\tStatement operator()(ForLoop const&) override;\n\tStatement operator()(Break const&) override;\n\tStatement operator()(Continue const&) override;\n\tStatement operator()(Leave const&) override;\n\tStatement operator()(Block const& _block) override;\n\n\tvirtual Expression translate(Expression const& _expression);\n\tvirtual Statement translate(Statement const& _statement);\n\n\tBlock translate(Block const& _block);\nprotected:\n\ttemplate <typename T>\n\tstd::vector<T> translateVector(std::vector<T> const& _values);\n\n\ttemplate <typename T>\n\tstd::unique_ptr<T> translate(std::unique_ptr<T> const& _v)\n\t{\n\t\treturn _v ? std::make_unique<T>(translate(*_v)) : nullptr;\n\t}\n\n\tCase translate(Case const& _case);\n\tvirtual Identifier translate(Identifier const& _identifier);\n\tLiteral translate(Literal const& _literal);\n\tFunctionName translate(FunctionName const& _functionName);\n\tNameWithDebugData translate(NameWithDebugData const& _typedName);\n\n\tvirtual void enterScope(Block const&) { }\n\tvirtual void leaveScope(Block const&) { }\n\tvirtual void enterFunction(FunctionDefinition const&) { }\n\tvirtual void leaveFunction(FunctionDefinition const&) { }\n\tvirtual YulName translateIdentifier(YulName _name) { return _name; }\n};\n\ntemplate <typename T>\nstd::vector<T> ASTCopier::translateVector(std::vector<T> const& _values)\n{\n\tstd::vector<T> translated;\n\tfor (auto const& v: _values)\n\t\ttranslated.emplace_back(translate(v));\n\treturn translated;\n}\n\n/// Helper class that creates a copy of the function definition, replacing the names of the variable\n/// declarations with new names.\nclass FunctionCopier: public ASTCopier\n{\npublic:\n\tFunctionCopier(\n\t\tstd::map<YulName, YulName> const& _translations\n\t):\n\t\tm_translations(_translations)\n\t{}\n\tusing ASTCopier::operator();\n\tYulName translateIdentifier(YulName _name) override;\nprivate:\n\t/// A mapping between old and new names. We replace the names of variable declarations contained\n\t/// in the mapping with their new names.\n\tstd::map<YulName, YulName> const& m_translations;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/ASTWalker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Generic AST walker.\n */\n\n#include <libyul/optimiser/ASTWalker.h>\n\n#include <libyul/AST.h>\n\n#include <range/v3/view/reverse.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nvoid ASTWalker::operator()(FunctionCall const& _funCall)\n{\n\t// Does not visit _funCall.functionName on purpose\n\twalkVector(_funCall.arguments | ranges::views::reverse);\n}\n\nvoid ASTWalker::operator()(ExpressionStatement const& _statement)\n{\n\tvisit(_statement.expression);\n}\n\nvoid ASTWalker::operator()(Assignment const& _assignment)\n{\n\tfor (auto const& name: _assignment.variableNames)\n\t\t(*this)(name);\n\tvisit(*_assignment.value);\n}\n\nvoid ASTWalker::operator()(VariableDeclaration const& _varDecl)\n{\n\tif (_varDecl.value)\n\t\tvisit(*_varDecl.value);\n}\n\nvoid ASTWalker::operator()(If const& _if)\n{\n\tvisit(*_if.condition);\n\t(*this)(_if.body);\n}\n\nvoid ASTWalker::operator()(Switch const& _switch)\n{\n\tvisit(*_switch.expression);\n\tfor (auto const& _case: _switch.cases)\n\t{\n\t\tif (_case.value)\n\t\t\t(*this)(*_case.value);\n\t\t(*this)(_case.body);\n\t}\n}\n\nvoid ASTWalker::operator()(FunctionDefinition const& _fun)\n{\n\t(*this)(_fun.body);\n}\n\nvoid ASTWalker::operator()(ForLoop const& _for)\n{\n\t(*this)(_for.pre);\n\tvisit(*_for.condition);\n\t(*this)(_for.body);\n\t(*this)(_for.post);\n}\n\nvoid ASTWalker::operator()(Block const& _block)\n{\n\twalkVector(_block.statements);\n}\n\nvoid ASTWalker::visit(Statement const& _st)\n{\n\tstd::visit(*this, _st);\n}\n\nvoid ASTWalker::visit(Expression const& _e)\n{\n\tstd::visit(*this, _e);\n}\n\nvoid ASTModifier::operator()(FunctionCall& _funCall)\n{\n\t// Does not visit _funCall.functionName on purpose\n\twalkVector(_funCall.arguments | ranges::views::reverse);\n}\n\nvoid ASTModifier::operator()(ExpressionStatement& _statement)\n{\n\tvisit(_statement.expression);\n}\n\nvoid ASTModifier::operator()(Assignment& _assignment)\n{\n\tfor (auto& name: _assignment.variableNames)\n\t\t(*this)(name);\n\tvisit(*_assignment.value);\n}\n\nvoid ASTModifier::operator()(VariableDeclaration& _varDecl)\n{\n\tif (_varDecl.value)\n\t\tvisit(*_varDecl.value);\n}\n\nvoid ASTModifier::operator()(If& _if)\n{\n\tvisit(*_if.condition);\n\t(*this)(_if.body);\n}\n\nvoid ASTModifier::operator()(Switch& _switch)\n{\n\tvisit(*_switch.expression);\n\tfor (auto& _case: _switch.cases)\n\t{\n\t\tif (_case.value)\n\t\t\t(*this)(*_case.value);\n\t\t(*this)(_case.body);\n\t}\n}\n\nvoid ASTModifier::operator()(FunctionDefinition& _fun)\n{\n\t(*this)(_fun.body);\n}\n\nvoid ASTModifier::operator()(ForLoop& _for)\n{\n\t(*this)(_for.pre);\n\tvisit(*_for.condition);\n\t(*this)(_for.post);\n\t(*this)(_for.body);\n}\n\nvoid ASTModifier::operator()(Break&)\n{\n}\n\nvoid ASTModifier::operator()(Continue&)\n{\n}\n\nvoid ASTModifier::operator()(Leave&)\n{\n}\n\nvoid ASTModifier::operator()(Block& _block)\n{\n\twalkVector(_block.statements);\n}\n\nvoid ASTModifier::visit(Statement& _st)\n{\n\tstd::visit(*this, _st);\n}\n\nvoid ASTModifier::visit(Expression& _e)\n{\n\tstd::visit(*this, _e);\n}\n"
  },
  {
    "path": "libyul/optimiser/ASTWalker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Generic AST walker.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n\n#include <libyul/Exceptions.h>\n#include <libyul/YulName.h>\n\n#include <map>\n#include <optional>\n#include <set>\n#include <vector>\n\nnamespace solidity::yul\n{\n\n/**\n * Generic AST walker.\n */\nclass ASTWalker\n{\npublic:\n\tvirtual ~ASTWalker() = default;\n\tvirtual void operator()(Literal const&) {}\n\tvirtual void operator()(Identifier const&) {}\n\tvirtual void operator()(FunctionCall const& _funCall);\n\tvirtual void operator()(ExpressionStatement const& _statement);\n\tvirtual void operator()(Assignment const& _assignment);\n\tvirtual void operator()(VariableDeclaration const& _varDecl);\n\tvirtual void operator()(If const& _if);\n\tvirtual void operator()(Switch const& _switch);\n\tvirtual void operator()(FunctionDefinition const&);\n\tvirtual void operator()(ForLoop const&);\n\tvirtual void operator()(Break const&) {}\n\tvirtual void operator()(Continue const&) {}\n\tvirtual void operator()(Leave const&) {}\n\tvirtual void operator()(Block const& _block);\n\n\tvirtual void visit(Statement const& _st);\n\tvirtual void visit(Expression const& _e);\n\nprotected:\n\ttemplate <class T>\n\tvoid walkVector(T const& _statements)\n\t{\n\t\tfor (auto const& statement: _statements)\n\t\t\tvisit(statement);\n\t}\n};\n\n/**\n * Generic AST modifier (i.e. non-const version of ASTWalker).\n */\nclass ASTModifier\n{\npublic:\n\tvirtual ~ASTModifier() = default;\n\tvirtual void operator()(Literal&) {}\n\tvirtual void operator()(Identifier&) {}\n\tvirtual void operator()(FunctionCall& _funCall);\n\tvirtual void operator()(ExpressionStatement& _statement);\n\tvirtual void operator()(Assignment& _assignment);\n\tvirtual void operator()(VariableDeclaration& _varDecl);\n\tvirtual void operator()(If& _if);\n\tvirtual void operator()(Switch& _switch);\n\tvirtual void operator()(FunctionDefinition&);\n\tvirtual void operator()(ForLoop&);\n\tvirtual void operator()(Break&);\n\tvirtual void operator()(Continue&);\n\tvirtual void operator()(Leave&);\n\tvirtual void operator()(Block& _block);\n\n\tvirtual void visit(Statement& _st);\n\tvirtual void visit(Expression& _e);\n\nprotected:\n\ttemplate <class T>\n\tvoid walkVector(T&& _statements)\n\t{\n\t\tfor (auto& st: _statements)\n\t\t\tvisit(st);\n\t}\n};\n\nnamespace detail\n{\ntemplate <\n\ttypename Node,\n\ttypename Visitor,\n\ttypename Base = std::conditional_t<std::is_const_v<Node>, ASTWalker, ASTModifier>\n>\nstruct ForEach: Base\n{\n\tForEach(Visitor& _visitor): visitor(_visitor) {}\n\n\tusing Base::operator();\n\tvoid operator()(Node& _node) override\n\t{\n\t\tvisitor(_node);\n\t\tBase::operator()(_node);\n\t}\n\n\tVisitor& visitor;\n};\n}\n\n/// Helper function that traverses the AST and calls the visitor for each\n/// node of a specific type.\ntemplate<typename Node, typename Entry, typename Visitor>\nvoid forEach(Entry&& _entry, Visitor&& _visitor)\n{\n\tdetail::ForEach<Node, Visitor&>{_visitor}(_entry);\n}\n\n}\n"
  },
  {
    "path": "libyul/optimiser/BlockFlattener.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/optimiser/BlockFlattener.h>\n#include <libyul/AST.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <functional>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nvoid BlockFlattener::operator()(Block& _block)\n{\n\tASTModifier::operator()(_block);\n\n\titerateReplacing(\n\t\t_block.statements,\n\t\t[](Statement& _s) -> std::optional<std::vector<Statement>>\n\t\t{\n\t\t\tif (std::holds_alternative<Block>(_s))\n\t\t\t\treturn std::move(std::get<Block>(_s).statements);\n\t\t\telse\n\t\t\t\treturn {};\n\t\t}\n\t);\n}\n\nvoid BlockFlattener::run(OptimiserStepContext&, Block& _ast)\n{\n\tBlockFlattener flattener;\n\tfor (auto& statement: _ast.statements)\n\t\tif (auto* block = std::get_if<Block>(&statement))\n\t\t\tflattener(*block);\n\t\telse if (auto* function = std::get_if<FunctionDefinition>(&statement))\n\t\t\tflattener(function->body);\n\t\telse\n\t\t\tyulAssert(false, \"BlockFlattener requires the FunctionGrouper.\");\n}\n"
  },
  {
    "path": "libyul/optimiser/BlockFlattener.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\nnamespace solidity::yul\n{\n\nclass BlockFlattener: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"BlockFlattener\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\tBlockFlattener() = default;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/BlockHasher.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that calculates hash values for block prefixes.\n */\n\n#include <libyul/optimiser/BlockHasher.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/Visitor.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nnamespace\n{\nstatic constexpr uint64_t compileTimeLiteralHash(char const* _literal, size_t _n)\n{\n\treturn (_n == 0) ? BlockHasher::fnvEmptyHash : (static_cast<uint64_t>(_literal[0]) * BlockHasher::fnvPrime) ^ compileTimeLiteralHash(_literal + 1, _n - 1);\n}\n\ntemplate<size_t N>\nstatic constexpr uint64_t compileTimeLiteralHash(char const (&_literal)[N])\n{\n\treturn compileTimeLiteralHash(_literal, N);\n}\n}\n\nvoid ASTHasherBase::hashLiteral(solidity::yul::Literal const& _literal)\n{\n\thash64(compileTimeLiteralHash(\"Literal\"));\n\tif (!_literal.value.unlimited())\n\t\thash64(std::hash<u256>{}(_literal.value.value()));\n\telse\n\t\thash64(std::hash<std::string>{}(_literal.value.builtinStringLiteralValue()));\n\thash8(_literal.value.unlimited());\n}\n\nvoid ASTHasherBase::hashFunctionCall(FunctionCall const& _funCall)\n{\n\thash64(compileTimeLiteralHash(\"FunctionCall\"));\n\tGenericVisitor visitor{\n\t\t[&](BuiltinName const& _builtin)\n\t\t{\n\t\t\thash64(compileTimeLiteralHash(\"Builtin\"));\n\t\t\thash64(_builtin.handle.id);\n\t\t},\n\t\t[&](Identifier const& _identifier)\n\t\t{\n\t\t\thash64(compileTimeLiteralHash(\"UserDefined\"));\n\t\t\thash64(_identifier.name.hash());\n\t\t}\n\t};\n\tstd::visit(visitor, _funCall.functionName);\n}\n\nstd::map<Block const*, uint64_t> BlockHasher::run(Block const& _block)\n{\n\tstd::map<Block const*, uint64_t> result;\n\tBlockHasher blockHasher(result);\n\tblockHasher(_block);\n\treturn result;\n}\n\nvoid BlockHasher::operator()(Literal const& _literal)\n{\n\thashLiteral(_literal);\n}\n\nvoid BlockHasher::operator()(Identifier const& _identifier)\n{\n\thash64(compileTimeLiteralHash(\"Identifier\"));\n\tauto it = m_variableReferences.find(_identifier.name);\n\tif (it == m_variableReferences.end())\n\t{\n\t\tit = m_variableReferences.emplace(_identifier.name, VariableReference {\n\t\t\tm_externalIdentifierCount++,\n\t\t\ttrue\n\t\t}).first;\n\t\tm_externalReferences.emplace_back(_identifier.name);\n\t}\n\tif (it->second.isExternal)\n\t\thash64(compileTimeLiteralHash(\"external\"));\n\telse\n\t\thash64(compileTimeLiteralHash(\"internal\"));\n\thash64(it->second.id);\n}\n\nvoid BlockHasher::operator()(FunctionCall const& _funCall)\n{\n\thashFunctionCall(_funCall);\n\tASTWalker::operator()(_funCall);\n}\n\nvoid BlockHasher::operator()(ExpressionStatement const& _statement)\n{\n\thash64(compileTimeLiteralHash(\"ExpressionStatement\"));\n\tASTWalker::operator()(_statement);\n}\n\nvoid BlockHasher::operator()(Assignment const& _assignment)\n{\n\thash64(compileTimeLiteralHash(\"Assignment\"));\n\thash64(_assignment.variableNames.size());\n\tfor (auto const& name: _assignment.variableNames)\n\t\t(*this)(name);\n\tvisit(*_assignment.value);\n}\n\nvoid BlockHasher::operator()(VariableDeclaration const& _varDecl)\n{\n\thash64(compileTimeLiteralHash(\"VariableDeclaration\"));\n\thash64(_varDecl.variables.size());\n\tfor (auto const& var: _varDecl.variables)\n\t{\n\t\tyulAssert(!m_variableReferences.count(var.name), \"\");\n\t\tm_variableReferences[var.name] = VariableReference{\n\t\t\tm_internalIdentifierCount++,\n\t\t\tfalse\n\t\t};\n\t}\n\tASTWalker::operator()(_varDecl);\n}\n\nvoid BlockHasher::operator()(If const& _if)\n{\n\thash64(compileTimeLiteralHash(\"If\"));\n\tASTWalker::operator()(_if);\n}\n\nvoid BlockHasher::operator()(Switch const& _switch)\n{\n\thash64(compileTimeLiteralHash(\"Switch\"));\n\thash64(_switch.cases.size());\n\t// Instead of sorting we could consider to combine\n\t// the case hashes using a commutative operation here.\n\tstd::set<Case const*, SwitchCaseCompareByLiteralValue> cases;\n\tfor (auto const& _case: _switch.cases)\n\t\tcases.insert(&_case);\n\n\tvisit(*_switch.expression);\n\tfor (auto const& _case: cases)\n\t{\n\t\tif (_case->value)\n\t\t\t(*this)(*_case->value);\n\t\t(*this)(_case->body);\n\t}\n}\n\nvoid BlockHasher::operator()(FunctionDefinition const& _funDef)\n{\n\thash64(compileTimeLiteralHash(\"FunctionDefinition\"));\n\tASTWalker::operator()(_funDef);\n}\n\nvoid BlockHasher::operator()(ForLoop const& _loop)\n{\n\tyulAssert(_loop.pre.statements.empty(), \"\");\n\n\thash64(compileTimeLiteralHash(\"ForLoop\"));\n\tASTWalker::operator()(_loop);\n}\n\nvoid BlockHasher::operator()(Break const& _break)\n{\n\thash64(compileTimeLiteralHash(\"Break\"));\n\tASTWalker::operator()(_break);\n}\n\nvoid BlockHasher::operator()(Continue const& _continue)\n{\n\thash64(compileTimeLiteralHash(\"Continue\"));\n\tASTWalker::operator()(_continue);\n}\n\nvoid BlockHasher::operator()(Leave const& _leaveStatement)\n{\n\thash64(compileTimeLiteralHash(\"Leave\"));\n\tASTWalker::operator()(_leaveStatement);\n}\n\nvoid BlockHasher::operator()(Block const& _block)\n{\n\thash64(compileTimeLiteralHash(\"Block\"));\n\thash64(_block.statements.size());\n\tif (_block.statements.empty())\n\t\treturn;\n\n\tBlockHasher subBlockHasher(m_blockHashes);\n\tfor (auto const& statement: _block.statements)\n\t\tsubBlockHasher.visit(statement);\n\n\tm_blockHashes[&_block] = subBlockHasher.m_hash;\n\n\thash64(subBlockHasher.m_hash);\n\thash64(subBlockHasher.m_externalReferences.size());\n\n\tfor (auto& externalReference: subBlockHasher.m_externalReferences)\n\t\t(*this)(Identifier{{}, externalReference});\n}\n\nuint64_t ExpressionHasher::run(Expression const& _e)\n{\n\tExpressionHasher expressionHasher;\n\texpressionHasher.visit(_e);\n\treturn expressionHasher.m_hash;\n}\n\nvoid ExpressionHasher::operator()(Literal const& _literal)\n{\n\thashLiteral(_literal);\n}\n\nvoid ExpressionHasher::operator()(Identifier const& _identifier)\n{\n\thash64(compileTimeLiteralHash(\"Identifier\"));\n\thash64(_identifier.name.hash());\n}\n\nvoid ExpressionHasher::operator()(FunctionCall const& _funCall)\n{\n\thashFunctionCall(_funCall);\n\tASTWalker::operator()(_funCall);\n}\n"
  },
  {
    "path": "libyul/optimiser/BlockHasher.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that calculates hash values for blocks.\n */\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/ASTForward.h>\n#include <libyul/YulName.h>\n\nnamespace solidity::yul\n{\n\nclass HasherBase\n{\npublic:\n\tstatic constexpr uint64_t fnvPrime = 1099511628211u;\n\tstatic constexpr uint64_t fnvEmptyHash = 14695981039346656037u;\n\nprotected:\n\tvoid hash8(uint8_t _value)\n\t{\n\t\tm_hash *= fnvPrime;\n\t\tm_hash ^= _value;\n\t}\n\tvoid hash16(uint16_t _value)\n\t{\n\t\thash8(static_cast<uint8_t>(_value & 0xFF));\n\t\thash8(static_cast<uint8_t>(_value >> 8));\n\t}\n\tvoid hash32(uint32_t _value)\n\t{\n\t\thash16(static_cast<uint16_t>(_value & 0xFFFF));\n\t\thash16(static_cast<uint16_t>(_value >> 16));\n\t}\n\tvoid hash64(uint64_t _value)\n\t{\n\t\thash32(static_cast<uint32_t>(_value & 0xFFFFFFFF));\n\t\thash32(static_cast<uint32_t>(_value >> 32));\n\t}\n\n\tuint64_t m_hash = fnvEmptyHash;\n};\n\nclass ASTHasherBase: public HasherBase\n{\nprotected:\n\tvoid hashLiteral(solidity::yul::Literal const& _literal);\n\tvoid hashFunctionCall(FunctionCall const& _functionCall);\n};\n\n/**\n * Optimiser component that calculates hash values for blocks.\n * Syntactically equal blocks will have identical hashes and\n * blocks with equal hashes will likely be syntactically equal.\n *\n * The names of internally declared variables are replaced by\n * a simple counter, so differing names are not taken into account,\n * but only the order of references to declared variables.\n *\n * Similarly, the names of referenced external variables are not considered,\n * but replaced by a (distinct) counter as well.\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter\n */\nclass BlockHasher: public ASTWalker, public ASTHasherBase\n{\npublic:\n\n\tusing ASTWalker::operator();\n\n\tvoid operator()(Literal const&) override;\n\tvoid operator()(Identifier const&) override;\n\tvoid operator()(FunctionCall const& _funCall) override;\n\tvoid operator()(ExpressionStatement const& _statement) override;\n\tvoid operator()(Assignment const& _assignment) override;\n\tvoid operator()(VariableDeclaration const& _varDecl) override;\n\tvoid operator()(If const& _if) override;\n\tvoid operator()(Switch const& _switch) override;\n\tvoid operator()(FunctionDefinition const&) override;\n\tvoid operator()(ForLoop const&) override;\n\tvoid operator()(Break const&) override;\n\tvoid operator()(Continue const&) override;\n\tvoid operator()(Leave const&) override;\n\tvoid operator()(Block const& _block) override;\n\n\tstatic std::map<Block const*, uint64_t> run(Block const& _block);\n\n\nprivate:\n\tBlockHasher(std::map<Block const*, uint64_t>& _blockHashes): m_blockHashes(_blockHashes) {}\n\n\tstd::map<Block const*, uint64_t>& m_blockHashes;\n\n\tstruct VariableReference\n\t{\n\t\tsize_t id = 0;\n\t\tbool isExternal = false;\n\t};\n\tstd::map<YulName, VariableReference> m_variableReferences;\n\tstd::vector<YulName> m_externalReferences;\n\tsize_t m_externalIdentifierCount = 0;\n\tsize_t m_internalIdentifierCount = 0;\n};\n\n\n/**\n * Computes hashes of expressions that are likely different for syntactically different expressions.\n * In contrast to the BlockHasher, hashes of identifiers are likely different if the identifiers\n * have a different name and the same if the name matches.\n * This means this hasher should only be used on disambiguated sources.\n */\nclass ExpressionHasher: public ASTWalker, public ASTHasherBase\n{\npublic:\n\t/// Computes a hash of an expression that (in contrast to the behaviour of the class)\n\t/// distinguishes (up to hash collisions) variables with different names.\n\tstatic uint64_t run(Expression const& _e);\n\n\tusing ASTWalker::operator();\n\n\tvoid operator()(Literal const&) override;\n\tvoid operator()(Identifier const&) override;\n\tvoid operator()(FunctionCall const& _funCall) override;\n};\n\nstruct ExpressionHash\n{\n\tuint64_t operator()(Expression const& _expression) const\n\t{\n\t\treturn ExpressionHasher::run(_expression);\n\t}\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/CallGraphGenerator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Specific AST walker that generates the call graph.\n */\n\n#include <libyul/AST.h>\n#include <libyul/optimiser/CallGraphGenerator.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Visitor.h>\n\n#include <stack>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nnamespace\n{\n// TODO: This algorithm is non-optimal.\nstruct CallGraphCycleFinder\n{\n\tCallGraph const& callGraph;\n\tstd::set<FunctionHandle> containedInCycle{};\n\tstd::set<FunctionHandle> visited{};\n\tstd::vector<FunctionHandle> currentPath{};\n\n\tvoid visit(FunctionHandle const& _function)\n\t{\n\t\tif (visited.count(_function))\n\t\t\treturn;\n\t\tif (\n\t\t\tauto it = find(currentPath.begin(), currentPath.end(), _function);\n\t\t\tit != currentPath.end()\n\t\t)\n\t\t\tcontainedInCycle.insert(it, currentPath.end());\n\t\telse\n\t\t{\n\t\t\tcurrentPath.emplace_back(_function);\n\t\t\tif (callGraph.functionCalls.count(_function))\n\t\t\t\tfor (auto const& child: callGraph.functionCalls.at(_function))\n\t\t\t\t\tvisit(child);\n\t\t\tcurrentPath.pop_back();\n\t\t\tvisited.insert(_function);\n\t\t}\n\t}\n};\n}\n\nstd::set<FunctionHandle> CallGraph::recursiveFunctions() const\n{\n\tCallGraphCycleFinder cycleFinder{*this};\n\t// Visiting the root only is not enough, since there may be disconnected recursive functions.\n\tfor (auto const& call: functionCalls)\n\t\tcycleFinder.visit(call.first);\n\treturn cycleFinder.containedInCycle;\n}\n\nCallGraph CallGraphGenerator::callGraph(Block const& _ast)\n{\n\tCallGraphGenerator gen;\n\tgen(_ast);\n\treturn std::move(gen.m_callGraph);\n}\n\nvoid CallGraphGenerator::operator()(FunctionCall const& _functionCall)\n{\n\tauto& functionCalls = m_callGraph.functionCalls[m_currentFunction];\n\tFunctionHandle identifier = std::visit(GenericVisitor{\n\t\t[](BuiltinName const& _builtin) -> FunctionHandle { return _builtin.handle; },\n\t\t[](Identifier const& _identifier) -> FunctionHandle { return _identifier.name; },\n\t}, _functionCall.functionName);\n\tif (!util::contains(functionCalls, identifier))\n\t\tfunctionCalls.emplace_back(identifier);\n\tASTWalker::operator()(_functionCall);\n}\n\nvoid CallGraphGenerator::operator()(ForLoop const& _forLoop)\n{\n\tm_callGraph.functionsWithLoops.insert(m_currentFunction);\n\tASTWalker::operator()(_forLoop);\n}\n\nvoid CallGraphGenerator::operator()(FunctionDefinition const& _functionDefinition)\n{\n\tYulName previousFunction = m_currentFunction;\n\tm_currentFunction = _functionDefinition.name;\n\tyulAssert(m_callGraph.functionCalls.count(m_currentFunction) == 0, \"\");\n\tm_callGraph.functionCalls[m_currentFunction] = {};\n\tASTWalker::operator()(_functionDefinition);\n\tm_currentFunction = previousFunction;\n}\n\nCallGraphGenerator::CallGraphGenerator()\n{\n\tm_callGraph.functionCalls[YulName{}] = {};\n}\n\n"
  },
  {
    "path": "libyul/optimiser/CallGraphGenerator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Specific AST walker that generates the call graph.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/AST.h>\n\n#include <map>\n#include <set>\n\nnamespace solidity::yul\n{\n\nstruct CallGraph\n{\n\t/// Map function definition name -> function name\n\tstd::map<FunctionHandle, std::vector<FunctionHandle>> functionCalls;\n\tstd::set<YulName> functionsWithLoops;\n\t/// @returns the set of functions contained in cycles in the call graph, i.e.\n\t/// functions that are part of a (mutual) recursion.\n\t/// Note that this does not include functions that merely call recursive functions.\n\tstd::set<FunctionHandle> recursiveFunctions() const;\n};\n\n/**\n * Specific AST walker that generates the call graph.\n *\n * It also generates information about which functions contain for loops.\n *\n * The outermost (non-function) context is denoted by the empty string.\n */\nclass CallGraphGenerator: public ASTWalker\n{\npublic:\n\tstatic CallGraph callGraph(Block const& _ast);\n\n\tusing ASTWalker::operator();\n\tvoid operator()(FunctionCall const& _functionCall) override;\n\tvoid operator()(ForLoop const& _forLoop) override;\n\tvoid operator()(FunctionDefinition const& _functionDefinition) override;\n\nprivate:\n\tCallGraphGenerator();\n\n\tCallGraph m_callGraph;\n\t/// The name of the function we are currently visiting during traversal.\n\tYulName m_currentFunction;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/CircularReferencesPruner.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libyul/optimiser/CircularReferencesPruner.h>\n\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/optimiser/FunctionGrouper.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/AST.h>\n\n#include <libsolutil/Algorithms.h>\n\nusing namespace solidity::yul;\n\nvoid CircularReferencesPruner::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tCircularReferencesPruner{_context.reservedIdentifiers}(_ast);\n\tFunctionGrouper::run(_context, _ast);\n}\n\nvoid CircularReferencesPruner::operator()(Block& _block)\n{\n\tstd::set<YulName> functionsToKeep =\n\t\tfunctionsCalledFromOutermostContext(CallGraphGenerator::callGraph(_block));\n\n\tfor (auto&& statement: _block.statements)\n\t\tif (std::holds_alternative<FunctionDefinition>(statement))\n\t\t{\n\t\t\tFunctionDefinition const& funDef = std::get<FunctionDefinition>(statement);\n\t\t\tif (!functionsToKeep.count(funDef.name))\n\t\t\t\tstatement = Block{};\n\t\t}\n\n\tremoveEmptyBlocks(_block);\n}\n\nstd::set<YulName> CircularReferencesPruner::functionsCalledFromOutermostContext(CallGraph const& _callGraph)\n{\n\tstd::set<YulName> verticesToTraverse = m_reservedIdentifiers;\n\tverticesToTraverse.insert(YulName(\"\"));\n\n\treturn util::BreadthFirstSearch<YulName>{{verticesToTraverse.begin(), verticesToTraverse.end()}}.run(\n\t\t[&_callGraph](YulName _function, auto&& _addChild) {\n\t\t\tif (_callGraph.functionCalls.count(_function))\n\t\t\t\tfor (auto const& callee: _callGraph.functionCalls.at(_function))\n\t\t\t\t\tif (std::holds_alternative<YulName>(callee) && _callGraph.functionCalls.count(std::get<YulName>(callee)))\n\t\t\t\t\t\t_addChild(std::get<YulName>(callee));\n\t\t}).visited;\n}\n"
  },
  {
    "path": "libyul/optimiser/CircularReferencesPruner.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimization stage that removes functions that call each other but are\n * otherwise unreferenced.\n *\n *  Prerequisites: Disambiguator, FunctionHoister.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/YulName.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Optimization stage that removes functions that call each other but are\n * neither externally referenced nor referenced from the outermost context.\n */\nclass CircularReferencesPruner: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"CircularReferencesPruner\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(Block& _block) override;\nprivate:\n\tCircularReferencesPruner(std::set<YulName> const& _reservedIdentifiers):\n\t\tm_reservedIdentifiers(_reservedIdentifiers)\n\t{}\n\n\t/// Run a breadth-first search starting from the outermost context and\n\t/// externally referenced functions to find all the functions that are\n\t/// called from there either directly or indirectly.\n\tstd::set<YulName> functionsCalledFromOutermostContext(CallGraph const& _callGraph);\n\n\tstd::set<YulName> const& m_reservedIdentifiers;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/CommonSubexpressionEliminator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * Optimisation stage that replaces expressions known to be the current value of a variable\n * in scope by a reference to that variable.\n */\n\n#include <libyul/optimiser/CommonSubexpressionEliminator.h>\n\n#include <libyul/optimiser/SyntacticalEquality.h>\n#include <libyul/optimiser/BlockHasher.h>\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/SideEffects.h>\n#include <libyul/Exceptions.h>\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/Utilities.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nvoid CommonSubexpressionEliminator::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tCommonSubexpressionEliminator cse{\n\t\t_context.dialect,\n\t\tSideEffectsPropagator::sideEffects(_context.dialect, CallGraphGenerator::callGraph(_ast))\n\t};\n\tcse(_ast);\n}\n\nCommonSubexpressionEliminator::CommonSubexpressionEliminator(\n\tDialect const& _dialect,\n\tstd::map<FunctionHandle, SideEffects> _functionSideEffects\n):\n\tDataFlowAnalyzer(_dialect, MemoryAndStorage::Ignore, std::move(_functionSideEffects))\n{\n}\n\nvoid CommonSubexpressionEliminator::operator()(FunctionDefinition& _fun)\n{\n\tScopedSaveAndRestore returnVariables(m_returnVariables, {});\n\tScopedSaveAndRestore replacementCandidates(m_replacementCandidates, {});\n\n\tfor (auto const& v: _fun.returnVariables)\n\t\tm_returnVariables.insert(v.name);\n\n\tDataFlowAnalyzer::operator()(_fun);\n}\n\nvoid CommonSubexpressionEliminator::visit(Expression& _e)\n{\n\tbool descend = true;\n\t// If this is a function call to a function that requires literal arguments,\n\t// do not try to simplify there.\n\tif (std::holds_alternative<FunctionCall>(_e))\n\t{\n\t\tFunctionCall& funCall = std::get<FunctionCall>(_e);\n\n\t\tif (BuiltinFunction const* builtin = resolveBuiltinFunction(funCall.functionName, m_dialect))\n\t\t{\n\t\t\tfor (size_t i = funCall.arguments.size(); i > 0; i--)\n\t\t\t\t// We should not modify function arguments that have to be literals\n\t\t\t\t// Note that replacing the function call entirely is fine,\n\t\t\t\t// if the function call is movable.\n\t\t\t\tif (!builtin->literalArgument(i - 1))\n\t\t\t\t\tvisit(funCall.arguments[i - 1]);\n\n\t\t\tdescend = false;\n\t\t}\n\t}\n\n\t// We visit the inner expression first to first simplify inner expressions,\n\t// which hopefully allows more matches.\n\t// Note that the DataFlowAnalyzer itself only has code for visiting Statements,\n\t// so this basically invokes the AST walker directly and thus post-visiting\n\t// is also fine with regards to data flow analysis.\n\tif (descend)\n\t\tDataFlowAnalyzer::visit(_e);\n\n\tif (Identifier const* identifier = std::get_if<Identifier>(&_e))\n\t{\n\t\tYulName identifierName = identifier->name;\n\t\tif (AssignedValue const* assignedValue = variableValue(identifierName))\n\t\t{\n\t\t\tassertThrow(assignedValue->value, OptimizerException, \"\");\n\t\t\tif (Identifier const* value = std::get_if<Identifier>(assignedValue->value))\n\t\t\t\tif (inScope(value->name))\n\t\t\t\t\t_e = Identifier{debugDataOf(_e), value->name};\n\t\t}\n\t}\n\telse if (auto const* candidates = util::valueOrNullptr(m_replacementCandidates, _e))\n\t\tfor (auto const& variable: *candidates)\n\t\t\tif (AssignedValue const* value = variableValue(variable))\n\t\t\t{\n\t\t\t\tassertThrow(value->value, OptimizerException, \"\");\n\t\t\t\t// Prevent using the default value of return variables\n\t\t\t\t// instead of literal zeros.\n\t\t\t\tif (\n\t\t\t\t\tm_returnVariables.count(variable) &&\n\t\t\t\t\tstd::holds_alternative<Literal>(*value->value) &&\n\t\t\t\t\tstd::get<Literal>(*value->value).value.value() == 0\n\t\t\t\t)\n\t\t\t\t\tcontinue;\n\t\t\t\t// We check for syntactic equality again because the value might have changed.\n\t\t\t\tif (inScope(variable) && SyntacticallyEqual{}(_e, *value->value))\n\t\t\t\t{\n\t\t\t\t\t_e = Identifier{debugDataOf(_e), variable};\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n}\n\nvoid CommonSubexpressionEliminator::assignValue(YulName _variable, Expression const* _value)\n{\n\tif (_value)\n\t\tm_replacementCandidates[*_value].insert(_variable);\n\tDataFlowAnalyzer::assignValue(_variable, _value);\n}\n"
  },
  {
    "path": "libyul/optimiser/CommonSubexpressionEliminator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that replaces expressions known to be the current value of a variable\n * in scope by a reference to that variable.\n */\n\n#pragma once\n\n#include <libyul/optimiser/DataFlowAnalyzer.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/optimiser/SyntacticalEquality.h>\n#include <libyul/optimiser/BlockHasher.h>\n\n#include <set>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\nstruct SideEffects;\n\n/**\n * Optimisation stage that replaces expressions known to be the current value of a variable\n * in scope by a reference to that variable.\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter.\n */\nclass CommonSubexpressionEliminator: public DataFlowAnalyzer\n{\npublic:\n\tstatic constexpr char const* name{\"CommonSubexpressionEliminator\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\tusing DataFlowAnalyzer::operator();\n\tvoid operator()(FunctionDefinition&) override;\n\nprivate:\n\tCommonSubexpressionEliminator(\n\t\tDialect const& _dialect,\n\t\tstd::map<FunctionHandle, SideEffects> _functionSideEffects\n\t);\n\nprotected:\n\tusing ASTModifier::visit;\n\tvoid visit(Expression& _e) override;\n\n\tvoid assignValue(YulName _variable, Expression const* _value) override;\nprivate:\n\tstd::set<YulName> m_returnVariables;\n\tstd::unordered_map<\n\t\tstd::reference_wrapper<Expression const>,\n\t\tstd::set<YulName>,\n\t\tExpressionHash,\n\t\tSyntacticallyEqualExpression\n\t> m_replacementCandidates;\n};\n\n\n}\n"
  },
  {
    "path": "libyul/optimiser/ConditionalSimplifier.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libyul/optimiser/ConditionalSimplifier.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/AST.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/ControlFlowSideEffectsCollector.h>\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nvoid ConditionalSimplifier::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tConditionalSimplifier{\n\t\t_context.dialect,\n\t\tControlFlowSideEffectsCollector{_context.dialect, _ast}.functionSideEffectsNamed()\n\t}(_ast);\n}\n\nvoid ConditionalSimplifier::operator()(Switch& _switch)\n{\n\tvisit(*_switch.expression);\n\tif (!std::holds_alternative<Identifier>(*_switch.expression))\n\t{\n\t\tASTModifier::operator()(_switch);\n\t\treturn;\n\t}\n\tYulName expr = std::get<Identifier>(*_switch.expression).name;\n\tfor (auto& _case: _switch.cases)\n\t{\n\t\tif (_case.value)\n\t\t{\n\t\t\t(*this)(*_case.value);\n\t\t\t_case.body.statements.insert(_case.body.statements.begin(),\n\t\t\t\tAssignment{\n\t\t\t\t\t_case.body.debugData,\n\t\t\t\t\t{Identifier{_case.body.debugData, expr}},\n\t\t\t\t\tstd::make_unique<Expression>(*_case.value)\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t\t(*this)(_case.body);\n\t}\n}\n\nvoid ConditionalSimplifier::operator()(Block& _block)\n{\n\titerateReplacing(\n\t\t_block.statements,\n\t\t[&](Statement& _s) -> std::optional<std::vector<Statement>>\n\t\t{\n\t\t\tvisit(_s);\n\t\t\tif (std::holds_alternative<If>(_s))\n\t\t\t{\n\t\t\t\tIf& _if = std::get<If>(_s);\n\t\t\t\tif (\n\t\t\t\t\tstd::holds_alternative<Identifier>(*_if.condition) &&\n\t\t\t\t\t!_if.body.statements.empty() &&\n\t\t\t\t\tTerminationFinder(m_dialect, &m_functionSideEffects).controlFlowKind(_if.body.statements.back()) !=\n\t\t\t\t\t\tTerminationFinder::ControlFlow::FlowOut\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tYulName condition = std::get<Identifier>(*_if.condition).name;\n\t\t\t\t\tlangutil::DebugData::ConstPtr debugData = _if.debugData;\n\t\t\t\t\treturn make_vector<Statement>(\n\t\t\t\t\t\tstd::move(_s),\n\t\t\t\t\t\tAssignment{\n\t\t\t\t\t\t\tdebugData,\n\t\t\t\t\t\t\t{Identifier{debugData, condition}},\n\t\t\t\t\t\t\tstd::make_unique<Expression>(m_dialect.zeroLiteral())\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {};\n\t\t}\n\t);\n}\n"
  },
  {
    "path": "libyul/optimiser/ConditionalSimplifier.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/ASTForward.h>\n#include <libyul/Dialect.h>\n#include <libsolutil/Common.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Conditional simplifier.\n *\n * Inserts assignments to condition variables if the value can be determined\n * from the control-flow.\n *\n * Destroys SSA form.\n *\n * Currently, this tool is very limited, mostly because we do not yet have support\n * for boolean types. Since conditions only check for expressions being nonzero,\n * we cannot assign a specific value.\n *\n * Current features:\n *  - switch cases: insert \"<condition> := <caseLabel>\"\n *  - after if statement with terminating control-flow, insert \"<condition> := 0\"\n *\n * Future features:\n *  - allow replacements by \"1\"\n *\n * Works best with SSA form and if dead code removal has run before.\n *\n * Prerequisite: Disambiguator.\n */\nclass ConditionalSimplifier: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"ConditionalSimplifier\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(Switch& _switch) override;\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\texplicit ConditionalSimplifier(\n\t\tDialect const& _dialect,\n\t\tstd::map<YulName, ControlFlowSideEffects> _sideEffects\n\t):\n\t\tm_dialect(_dialect), m_functionSideEffects(std::move(_sideEffects))\n\t{}\n\tDialect const& m_dialect;\n\tstd::map<YulName, ControlFlowSideEffects> m_functionSideEffects;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/ConditionalUnsimplifier.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libyul/optimiser/ConditionalUnsimplifier.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/ControlFlowSideEffectsCollector.h>\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nvoid ConditionalUnsimplifier::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tConditionalUnsimplifier{\n\t\t_context.dialect,\n\t\tControlFlowSideEffectsCollector{_context.dialect, _ast}.functionSideEffectsNamed()\n\t}(_ast);\n}\n\nvoid ConditionalUnsimplifier::operator()(Switch& _switch)\n{\n\tvisit(*_switch.expression);\n\tif (!std::holds_alternative<Identifier>(*_switch.expression))\n\t{\n\t\tASTModifier::operator()(_switch);\n\t\treturn;\n\t}\n\tYulName expr = std::get<Identifier>(*_switch.expression).name;\n\tfor (auto& _case: _switch.cases)\n\t{\n\t\tif (_case.value)\n\t\t{\n\t\t\t(*this)(*_case.value);\n\t\t\tif (\n\t\t\t\t!_case.body.statements.empty() &&\n\t\t\t\tstd::holds_alternative<Assignment>(_case.body.statements.front())\n\t\t\t)\n\t\t\t{\n\t\t\t\tAssignment const& assignment = std::get<Assignment>(_case.body.statements.front());\n\t\t\t\tif (\n\t\t\t\t\tassignment.variableNames.size() == 1 &&\n\t\t\t\t\tassignment.variableNames.front().name == expr &&\n\t\t\t\t\tstd::holds_alternative<Literal>(*assignment.value) &&\n\t\t\t\t\tstd::get<Literal>(*assignment.value).value == _case.value->value\n\t\t\t\t)\n\t\t\t\t\t_case.body.statements.erase(_case.body.statements.begin());\n\t\t\t}\n\t\t}\n\t\t(*this)(_case.body);\n\t}\n}\n\nvoid ConditionalUnsimplifier::operator()(Block& _block)\n{\n\twalkVector(_block.statements);\n\titerateReplacingWindow<2>(\n\t\t_block.statements,\n\t\t[&](Statement& _stmt1, Statement& _stmt2) -> std::optional<std::vector<Statement>>\n\t\t{\n\t\t\tif (std::holds_alternative<If>(_stmt1))\n\t\t\t{\n\t\t\t\tIf& _if = std::get<If>(_stmt1);\n\t\t\t\tif (\n\t\t\t\t\tstd::holds_alternative<Identifier>(*_if.condition) &&\n\t\t\t\t\t!_if.body.statements.empty()\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tYulName condition = std::get<Identifier>(*_if.condition).name;\n\t\t\t\t\tif (\n\t\t\t\t\t\tstd::holds_alternative<Assignment>(_stmt2) &&\n\t\t\t\t\t\tTerminationFinder(m_dialect, &m_functionSideEffects).controlFlowKind(_if.body.statements.back()) !=\n\t\t\t\t\t\t\tTerminationFinder::ControlFlow::FlowOut\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\tAssignment const& assignment = std::get<Assignment>(_stmt2);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tassignment.variableNames.size() == 1 &&\n\t\t\t\t\t\t\tassignment.variableNames.front().name == condition &&\n\t\t\t\t\t\t\tstd::holds_alternative<Literal>(*assignment.value) &&\n\t\t\t\t\t\t\tstd::get<Literal>(*assignment.value).value.value() == 0\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn {make_vector<Statement>(std::move(_stmt1))};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {};\n\t\t}\n\t);\n}\n"
  },
  {
    "path": "libyul/optimiser/ConditionalUnsimplifier.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/Dialect.h>\n#include <libsolutil/Common.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Reverse of conditional simplifier.\n *\n */\nclass ConditionalUnsimplifier: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"ConditionalUnsimplifier\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(Switch& _switch) override;\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\texplicit ConditionalUnsimplifier(\n\t\tDialect const& _dialect,\n\t\tstd::map<YulName, ControlFlowSideEffects> const& _sideEffects\n\t):\n\t\tm_dialect(_dialect), m_functionSideEffects(_sideEffects)\n\t{}\n\tDialect const& m_dialect;\n\tstd::map<YulName, ControlFlowSideEffects> const& m_functionSideEffects;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/ControlFlowSimplifier.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libyul/optimiser/ControlFlowSimplifier.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n#include <libyul/Dialect.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/action/remove_if.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::yul;\n\nusing OptionalStatements = std::optional<std::vector<Statement>>;\n\nnamespace\n{\n\nExpressionStatement makeDiscardCall(\n\tlangutil::DebugData::ConstPtr const& _debugData,\n\tBuiltinHandle const& _discardFunction,\n\tExpression&& _expression\n)\n{\n\treturn {_debugData, FunctionCall{\n\t\t_debugData,\n\t\tBuiltinName{_debugData, _discardFunction},\n\t\t{std::move(_expression)}\n\t}};\n}\n\nvoid removeEmptyDefaultFromSwitch(Switch& _switchStmt)\n{\n\tranges::actions::remove_if(\n\t\t_switchStmt.cases,\n\t\t[](Case const& _case) { return !_case.value && _case.body.statements.empty(); }\n\t);\n}\n\nvoid removeEmptyCasesFromSwitch(Switch& _switchStmt)\n{\n\tif (hasDefaultCase(_switchStmt))\n\t\treturn;\n\n\tranges::actions::remove_if(\n\t\t_switchStmt.cases,\n\t\t[](Case const& _case) { return _case.body.statements.empty(); }\n\t);\n}\n\n}\n\nvoid ControlFlowSimplifier::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tControlFlowSimplifier{_context.dialect}(_ast);\n}\n\nvoid ControlFlowSimplifier::operator()(Block& _block)\n{\n\tsimplify(_block.statements);\n}\n\nvoid ControlFlowSimplifier::operator()(FunctionDefinition& _funDef)\n{\n\tASTModifier::operator()(_funDef);\n\tif (!_funDef.body.statements.empty() && std::holds_alternative<Leave>(_funDef.body.statements.back()))\n\t\t_funDef.body.statements.pop_back();\n}\n\nvoid ControlFlowSimplifier::visit(Statement& _st)\n{\n\tif (std::holds_alternative<ForLoop>(_st))\n\t{\n\t\tForLoop& forLoop = std::get<ForLoop>(_st);\n\t\tyulAssert(forLoop.pre.statements.empty(), \"\");\n\n\t\tsize_t outerBreak = m_numBreakStatements;\n\t\tsize_t outerContinue = m_numContinueStatements;\n\t\tm_numBreakStatements = 0;\n\t\tm_numContinueStatements = 0;\n\n\t\tASTModifier::visit(_st);\n\n\t\tif (!forLoop.body.statements.empty())\n\t\t{\n\t\t\tbool isTerminating = false;\n\t\t\tTerminationFinder::ControlFlow controlFlow = TerminationFinder{m_dialect}.controlFlowKind(forLoop.body.statements.back());\n\t\t\tif (controlFlow == TerminationFinder::ControlFlow::Break)\n\t\t\t{\n\t\t\t\tisTerminating = true;\n\t\t\t\t--m_numBreakStatements;\n\t\t\t}\n\t\t\telse if (\n\t\t\t\tcontrolFlow == TerminationFinder::ControlFlow::Terminate ||\n\t\t\t\tcontrolFlow == TerminationFinder::ControlFlow::Leave\n\t\t\t)\n\t\t\t\tisTerminating = true;\n\n\t\t\tif (isTerminating && m_numContinueStatements == 0 && m_numBreakStatements == 0)\n\t\t\t{\n\t\t\t\tIf replacement{forLoop.debugData, std::move(forLoop.condition), std::move(forLoop.body)};\n\t\t\t\tif (controlFlow == TerminationFinder::ControlFlow::Break)\n\t\t\t\t\treplacement.body.statements.resize(replacement.body.statements.size() - 1);\n\t\t\t\t_st = std::move(replacement);\n\t\t\t}\n\t\t}\n\n\t\tm_numBreakStatements = outerBreak;\n\t\tm_numContinueStatements = outerContinue;\n\t}\n\telse\n\t\tASTModifier::visit(_st);\n}\n\nvoid ControlFlowSimplifier::simplify(std::vector<yul::Statement>& _statements)\n{\n\tGenericVisitor visitor{\n\t\tVisitorFallback<OptionalStatements>{},\n\t\t[&](If& _ifStmt) -> OptionalStatements {\n\t\t\tif (_ifStmt.body.statements.empty() && m_dialect.discardFunctionHandle())\n\t\t\t{\n\t\t\t\tOptionalStatements s = std::vector<Statement>{};\n\t\t\t\ts->emplace_back(makeDiscardCall(\n\t\t\t\t\t_ifStmt.debugData,\n\t\t\t\t\t*m_dialect.discardFunctionHandle(),\n\t\t\t\t\tstd::move(*_ifStmt.condition)\n\t\t\t\t));\n\t\t\t\treturn s;\n\t\t\t}\n\t\t\treturn {};\n\t\t},\n\t\t[&](Switch& _switchStmt) -> OptionalStatements {\n\t\t\tremoveEmptyDefaultFromSwitch(_switchStmt);\n\t\t\tremoveEmptyCasesFromSwitch(_switchStmt);\n\n\t\t\tif (_switchStmt.cases.empty())\n\t\t\t\treturn reduceNoCaseSwitch(_switchStmt);\n\t\t\telse if (_switchStmt.cases.size() == 1)\n\t\t\t\treturn reduceSingleCaseSwitch(_switchStmt);\n\n\t\t\treturn {};\n\t\t}\n\t};\n\titerateReplacing(\n\t\t_statements,\n\t\t[&](Statement& _stmt) -> OptionalStatements\n\t\t{\n\t\t\tOptionalStatements result = std::visit(visitor, _stmt);\n\t\t\tif (result)\n\t\t\t\tsimplify(*result);\n\t\t\telse\n\t\t\t\tvisit(_stmt);\n\t\t\treturn result;\n\t\t}\n\t);\n}\n\nOptionalStatements ControlFlowSimplifier::reduceNoCaseSwitch(Switch& _switchStmt) const\n{\n\tyulAssert(_switchStmt.cases.empty(), \"Expected no case!\");\n\tstd::optional<BuiltinHandle> discardFunctionHandle =\n\t\tm_dialect.discardFunctionHandle();\n\tif (!discardFunctionHandle)\n\t\treturn {};\n\n\treturn make_vector<Statement>(makeDiscardCall(\n\t\tdebugDataOf(*_switchStmt.expression),\n\t\t*discardFunctionHandle,\n\t\tstd::move(*_switchStmt.expression)\n\t));\n}\n\nOptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switchStmt) const\n{\n\tyulAssert(_switchStmt.cases.size() == 1, \"Expected only one case!\");\n\n\tauto& switchCase = _switchStmt.cases.front();\n\tlangutil::DebugData::ConstPtr debugData = debugDataOf(*_switchStmt.expression);\n\tif (switchCase.value)\n\t{\n\t\tif (!m_dialect.equalityFunctionHandle())\n\t\t\treturn {};\n\t\tBuiltinName const builtinName{debugData, *m_dialect.equalityFunctionHandle()};\n\t\treturn make_vector<Statement>(If{\n\t\t\tstd::move(_switchStmt.debugData),\n\t\t\tstd::make_unique<Expression>(FunctionCall{\n\t\t\t\tdebugData,\n\t\t\t\tbuiltinName,\n\t\t\t\t{std::move(*switchCase.value), std::move(*_switchStmt.expression)}\n\t\t\t}),\n\t\t\tstd::move(switchCase.body)\n\t\t});\n\t}\n\telse\n\t{\n\t\tif (!m_dialect.discardFunctionHandle())\n\t\t\treturn {};\n\n\t\treturn make_vector<Statement>(\n\t\t\tmakeDiscardCall(\n\t\t\t\tdebugData,\n\t\t\t\t*m_dialect.discardFunctionHandle(),\n\t\t\t\tstd::move(*_switchStmt.expression)\n\t\t\t),\n\t\t\tstd::move(switchCase.body)\n\t\t);\n\t}\n}\n\n"
  },
  {
    "path": "libyul/optimiser/ControlFlowSimplifier.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\nnamespace solidity::yul\n{\nclass Dialect;\nstruct OptimiserStepContext;\n\n/**\n * Simplifies several control-flow structures:\n * - replace if with empty body with pop(condition)\n * - remove empty default switch case\n * - remove empty switch case if no default case exists\n * - replace switch with no cases with pop(expression)\n * - turn switch with single case into if\n * - replace switch with only default case with pop(expression) and body\n * - replace switch with const expr with matching case body\n * - replace ``for`` with terminating control flow and without other break/continue by ``if``\n * - remove ``leave`` at the end of a function.\n *\n * None of these operations depend on the data flow. The StructuralSimplifier\n * performs similar tasks that do depend on data flow.\n *\n * The ControlFlowSimplifier does record the presence or absence of ``break``\n * and ``continue`` statements during its traversal.\n *\n * Prerequisite: Disambiguator, FunctionHoister, ForLoopInitRewriter.\n *\n * Important: Introduces EVM opcodes and thus can only be used on EVM code for now.\n */\nclass ControlFlowSimplifier: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"ControlFlowSimplifier\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(Break&) override { ++m_numBreakStatements; }\n\tvoid operator()(Continue&) override { ++m_numContinueStatements; }\n\tvoid operator()(Block& _block) override;\n\tvoid operator()(FunctionDefinition& _funDef) override;\n\n\tvoid visit(Statement& _st) override;\n\nprivate:\n\texplicit ControlFlowSimplifier(Dialect const& _dialect):\n\t\tm_dialect(_dialect)\n\t{}\n\n\tvoid simplify(std::vector<Statement>& _statements);\n\n\tstd::optional<std::vector<Statement>> reduceNoCaseSwitch(Switch& _switchStmt) const;\n\tstd::optional<std::vector<Statement>> reduceSingleCaseSwitch(Switch& _switchStmt) const;\n\n\tDialect const& m_dialect;\n\tsize_t m_numBreakStatements = 0;\n\tsize_t m_numContinueStatements = 0;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/DataFlowAnalyzer.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * Base class to perform data flow analysis during AST walks.\n * Tracks assignments and is used as base class for both Rematerialiser and\n * Common Subexpression Eliminator.\n */\n\n#include <libyul/optimiser/DataFlowAnalyzer.h>\n\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/optimiser/KnowledgeBase.h>\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <variant>\n\n#include <range/v3/view/reverse.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::yul;\n\nDataFlowAnalyzer::DataFlowAnalyzer(\n\tDialect const& _dialect,\n\tMemoryAndStorage _analyzeStores,\n\tstd::map<FunctionHandle, SideEffects> _functionSideEffects\n):\n\tm_dialect(_dialect),\n\tm_functionSideEffects(std::move(_functionSideEffects)),\n\tm_knowledgeBase([this](YulName _var) { return variableValue(_var); }, _dialect),\n\tm_analyzeStores(_analyzeStores == MemoryAndStorage::Analyze)\n{\n\tif (m_analyzeStores)\n\t{\n\t\tm_storeFunctionName[static_cast<unsigned>(StoreLoadLocation::Memory)] = _dialect.memoryStoreFunctionHandle();\n\t\tm_loadFunctionName[static_cast<unsigned>(StoreLoadLocation::Memory)] = _dialect.memoryLoadFunctionHandle();\n\t\tm_storeFunctionName[static_cast<unsigned>(StoreLoadLocation::Storage)] = _dialect.storageStoreFunctionHandle();\n\t\tm_loadFunctionName[static_cast<unsigned>(StoreLoadLocation::Storage)] = _dialect.storageLoadFunctionHandle();\n\t}\n}\n\nvoid DataFlowAnalyzer::operator()(ExpressionStatement& _statement)\n{\n\tif (m_analyzeStores)\n\t{\n\t\tif (auto vars = isSimpleStore(StoreLoadLocation::Storage, _statement))\n\t\t{\n\t\t\tASTModifier::operator()(_statement);\n\t\t\tstd::erase_if(m_state.environment.storage, mapTuple([&](auto&& key, auto&& value) {\n\t\t\t\treturn\n\t\t\t\t\t!m_knowledgeBase.knownToBeDifferent(vars->first, key) &&\n\t\t\t\t\tvars->second != value;\n\t\t\t}));\n\t\t\tm_state.environment.storage[vars->first] = vars->second;\n\t\t\treturn;\n\t\t}\n\t\telse if (auto vars = isSimpleStore(StoreLoadLocation::Memory, _statement))\n\t\t{\n\t\t\tASTModifier::operator()(_statement);\n\t\t\tstd::erase_if(m_state.environment.memory, mapTuple([&](auto&& key, auto&& /* value */) {\n\t\t\t\treturn !m_knowledgeBase.knownToBeDifferentByAtLeast32(vars->first, key);\n\t\t\t}));\n\t\t\t// TODO erase keccak knowledge, but in a more clever way\n\t\t\tm_state.environment.keccak = {};\n\t\t\tm_state.environment.memory[vars->first] = vars->second;\n\t\t\treturn;\n\t\t}\n\t}\n\tclearKnowledgeIfInvalidated(_statement.expression);\n\tASTModifier::operator()(_statement);\n}\n\nvoid DataFlowAnalyzer::operator()(Assignment& _assignment)\n{\n\tstd::set<YulName> names;\n\tfor (auto const& var: _assignment.variableNames)\n\t\tnames.emplace(var.name);\n\tassertThrow(_assignment.value, OptimizerException, \"\");\n\tclearKnowledgeIfInvalidated(*_assignment.value);\n\tvisit(*_assignment.value);\n\thandleAssignment(names, _assignment.value.get(), false);\n}\n\nvoid DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl)\n{\n\tstd::set<YulName> names;\n\tfor (auto const& var: _varDecl.variables)\n\t\tnames.emplace(var.name);\n\tm_variableScopes.back().variables += names;\n\n\tif (_varDecl.value)\n\t{\n\t\tclearKnowledgeIfInvalidated(*_varDecl.value);\n\t\tvisit(*_varDecl.value);\n\t}\n\n\thandleAssignment(names, _varDecl.value.get(), true);\n}\n\nvoid DataFlowAnalyzer::operator()(If& _if)\n{\n\tclearKnowledgeIfInvalidated(*_if.condition);\n\tEnvironment preEnvironment = m_state.environment;\n\n\tASTModifier::operator()(_if);\n\tjoinKnowledge(preEnvironment);\n\n\tclearValues(assignedVariableNames(_if.body));\n}\n\nvoid DataFlowAnalyzer::operator()(Switch& _switch)\n{\n\tclearKnowledgeIfInvalidated(*_switch.expression);\n\tvisit(*_switch.expression);\n\tstd::set<YulName> assignedVariables;\n\tfor (auto& _case: _switch.cases)\n\t{\n\t\tEnvironment preEnvironment = m_state.environment;\n\t\t(*this)(_case.body);\n\t\tjoinKnowledge(preEnvironment);\n\n\t\tstd::set<YulName> variables = assignedVariableNames(_case.body);\n\t\tassignedVariables += variables;\n\t\t// This is a little too destructive, we could retain the old values.\n\t\tclearValues(variables);\n\t\tclearKnowledgeIfInvalidated(_case.body);\n\t}\n\tfor (auto& _case: _switch.cases)\n\t\tclearKnowledgeIfInvalidated(_case.body);\n\tclearValues(assignedVariables);\n}\n\nvoid DataFlowAnalyzer::operator()(FunctionDefinition& _fun)\n{\n\t// Save all information. We might rather reinstantiate this class,\n\t// but this could be difficult if it is subclassed.\n\tScopedSaveAndRestore stateResetter(m_state, {});\n\tScopedSaveAndRestore loopDepthResetter(m_loopDepth, 0u);\n\tpushScope(true);\n\n\tfor (auto const& parameter: _fun.parameters)\n\t\tm_variableScopes.back().variables.emplace(parameter.name);\n\tfor (auto const& var: _fun.returnVariables)\n\t{\n\t\tm_variableScopes.back().variables.emplace(var.name);\n\t\thandleAssignment({var.name}, nullptr, true);\n\t}\n\tASTModifier::operator()(_fun);\n\n\t// Note that the contents of return variables, storage and memory at this point\n\t// might be incorrect due to the fact that the DataFlowAnalyzer ignores the ``leave``\n\t// statement.\n\n\tpopScope();\n}\n\nvoid DataFlowAnalyzer::operator()(ForLoop& _for)\n{\n\t// If the pre block was not empty,\n\t// we would have to deal with more complicated scoping rules.\n\tassertThrow(_for.pre.statements.empty(), OptimizerException, \"\");\n\n\t++m_loopDepth;\n\n\tAssignmentsSinceContinue assignmentsSinceCont;\n\tassignmentsSinceCont(_for.body);\n\n\tstd::set<YulName> assignedVariables =\n\t\tassignedVariableNames(_for.body) + assignedVariableNames(_for.post);\n\tclearValues(assignedVariables);\n\n\t// break/continue are tricky for storage and thus we almost always clear here.\n\tclearKnowledgeIfInvalidated(*_for.condition);\n\tclearKnowledgeIfInvalidated(_for.post);\n\tclearKnowledgeIfInvalidated(_for.body);\n\n\tvisit(*_for.condition);\n\t(*this)(_for.body);\n\tclearValues(assignmentsSinceCont.names());\n\tclearKnowledgeIfInvalidated(_for.body);\n\t(*this)(_for.post);\n\tclearValues(assignedVariables);\n\tclearKnowledgeIfInvalidated(*_for.condition);\n\tclearKnowledgeIfInvalidated(_for.post);\n\tclearKnowledgeIfInvalidated(_for.body);\n\n\t--m_loopDepth;\n}\n\nvoid DataFlowAnalyzer::operator()(Block& _block)\n{\n\tsize_t numScopes = m_variableScopes.size();\n\tpushScope(false);\n\tASTModifier::operator()(_block);\n\tpopScope();\n\tassertThrow(numScopes == m_variableScopes.size(), OptimizerException, \"\");\n}\n\nstd::optional<YulName> DataFlowAnalyzer::storageValue(YulName _key) const\n{\n\tif (YulName const* value = valueOrNullptr(m_state.environment.storage, _key))\n\t\treturn *value;\n\telse\n\t\treturn std::nullopt;\n}\n\nstd::optional<YulName> DataFlowAnalyzer::memoryValue(YulName _key) const\n{\n\tif (YulName const* value = valueOrNullptr(m_state.environment.memory, _key))\n\t\treturn *value;\n\telse\n\t\treturn std::nullopt;\n}\n\nstd::optional<YulName> DataFlowAnalyzer::keccakValue(YulName _start, YulName _length) const\n{\n\tif (YulName const* value = valueOrNullptr(m_state.environment.keccak, std::make_pair(_start, _length)))\n\t\treturn *value;\n\telse\n\t\treturn std::nullopt;\n}\n\nvoid DataFlowAnalyzer::handleAssignment(std::set<YulName> const& _variables, Expression* _value, bool _isDeclaration)\n{\n\tif (!_isDeclaration)\n\t\tclearValues(_variables);\n\n\tMovableChecker movableChecker{m_dialect, &m_functionSideEffects};\n\tif (_value)\n\t\tmovableChecker.visit(*_value);\n\telse\n\t\tfor (auto const& var: _variables)\n\t\t\tassignValue(var, &m_zero);\n\n\tif (_value && _variables.size() == 1)\n\t{\n\t\tYulName name = *_variables.begin();\n\t\t// Expression has to be movable and cannot contain a reference\n\t\t// to the variable that will be assigned to.\n\t\tif (movableChecker.movable() && !movableChecker.referencedVariables().count(name))\n\t\t\tassignValue(name, _value);\n\t}\n\n\tauto const& referencedVariables = movableChecker.referencedVariables();\n\tstd::vector const referencedVariablesSorted(referencedVariables.begin(), referencedVariables.end());\n\tfor (auto const& name: _variables)\n\t{\n\t\tm_state.sortedReferences[name] = referencedVariablesSorted;\n\t\tif (!_isDeclaration)\n\t\t{\n\t\t\t// assignment to slot denoted by \"name\"\n\t\t\tm_state.environment.storage.erase(name);\n\t\t\t// assignment to slot contents denoted by \"name\"\n\t\t\tstd::erase_if(m_state.environment.storage, mapTuple([&name](auto&& /* key */, auto&& value) { return value == name; }));\n\t\t\t// assignment to slot denoted by \"name\"\n\t\t\tm_state.environment.memory.erase(name);\n\t\t\t// assignment to slot contents denoted by \"name\"\n\t\t\tstd::erase_if(m_state.environment.keccak, [&name](auto&& _item) {\n\t\t\t\treturn _item.first.first == name || _item.first.second == name || _item.second == name;\n\t\t\t});\n\t\t\tstd::erase_if(m_state.environment.memory, mapTuple([&name](auto&& /* key */, auto&& value) { return value == name; }));\n\t\t}\n\t}\n\n\tif (_value && _variables.size() == 1)\n\t{\n\t\tYulName variable = *_variables.begin();\n\t\tif (!movableChecker.referencedVariables().count(variable))\n\t\t{\n\t\t\t// This might erase additional knowledge about the slot.\n\t\t\t// On the other hand, if we knew the value in the slot\n\t\t\t// already, then the sload() / mload() would have been replaced by a variable anyway.\n\t\t\tif (auto key = isSimpleLoad(StoreLoadLocation::Memory, *_value))\n\t\t\t\tm_state.environment.memory[*key] = variable;\n\t\t\telse if (auto key = isSimpleLoad(StoreLoadLocation::Storage, *_value))\n\t\t\t\tm_state.environment.storage[*key] = variable;\n\t\t\telse if (auto arguments = isKeccak(*_value))\n\t\t\t\tm_state.environment.keccak[*arguments] = variable;\n\t\t}\n\t}\n}\n\nvoid DataFlowAnalyzer::pushScope(bool _functionScope)\n{\n\tm_variableScopes.emplace_back(_functionScope);\n}\n\nvoid DataFlowAnalyzer::popScope()\n{\n\tfor (auto const& name: m_variableScopes.back().variables)\n\t{\n\t\tm_state.value.erase(name);\n\t\tm_state.sortedReferences.erase(name);\n\t}\n\tm_variableScopes.pop_back();\n}\n\nvoid DataFlowAnalyzer::clearValues(std::set<YulName> const& _variablesToClear)\n{\n\t// All variables that reference variables to be cleared also have to be\n\t// cleared, but not recursively, since only the value of the original\n\t// variables changes. Example:\n\t// let a := 1\n\t// let b := a\n\t// let c := b\n\t// a := 2\n\t// add(b, c)\n\t// In the last line, we can replace c by b, but not b by a.\n\t//\n\t// This cannot be easily tested since the substitutions will be done\n\t// one by one on the fly, and the last line will just be add(1, 1)\n\n\t// First clear storage knowledge, because we do not have to clear\n\t// storage knowledge of variables whose expression has changed,\n\t// since the value is still unchanged.\n\tauto eraseCondition = mapTuple([&_variablesToClear](auto&& key, auto&& value) {\n\t\treturn _variablesToClear.count(key) || _variablesToClear.count(value);\n\t});\n\tstd::erase_if(m_state.environment.storage, eraseCondition);\n\tstd::erase_if(m_state.environment.memory, eraseCondition);\n\tstd::erase_if(m_state.environment.keccak, [&_variablesToClear](auto&& _item) {\n\t\treturn\n\t\t\t_variablesToClear.count(_item.first.first) ||\n\t\t\t_variablesToClear.count(_item.first.second) ||\n\t\t\t_variablesToClear.count(_item.second);\n\t});\n\n\t// Also clear variables that reference variables to be cleared.\n\tstd::set<YulName> referencingVariablesToClear;\n\tstd::vector const sortedVariablesToClear(_variablesToClear.begin(), _variablesToClear.end());\n\tfor (auto const& [referencingVariable, referencedVariables]: m_state.sortedReferences)\n\t\t// instead of checking each variable in `referencedVariables`, we check if there is any intersection making use of the\n\t\t// sortedness of the vectors, which can increase performance by up to 50% in pathological cases\n\t\tif (hasNonemptyIntersectionSorted(referencedVariables, sortedVariablesToClear))\n\t\t\treferencingVariablesToClear.emplace(referencingVariable);\n\n\t// Clear the value and update the reference relation.\n\tfor (auto const& name: _variablesToClear + referencingVariablesToClear)\n\t{\n\t\tm_state.value.erase(name);\n\t\tm_state.sortedReferences.erase(name);\n\t}\n}\n\nvoid DataFlowAnalyzer::assignValue(YulName _variable, Expression const* _value)\n{\n\tm_state.value[_variable] = {_value, m_loopDepth};\n}\n\nvoid DataFlowAnalyzer::clearKnowledgeIfInvalidated(Block const& _block)\n{\n\tif (!m_analyzeStores)\n\t\treturn;\n\tSideEffectsCollector sideEffects(m_dialect, _block, &m_functionSideEffects);\n\tif (sideEffects.invalidatesStorage())\n\t\tm_state.environment.storage.clear();\n\tif (sideEffects.invalidatesMemory())\n\t{\n\t\tm_state.environment.memory.clear();\n\t\tm_state.environment.keccak.clear();\n\t}\n}\n\nvoid DataFlowAnalyzer::clearKnowledgeIfInvalidated(Expression const& _expr)\n{\n\tif (!m_analyzeStores)\n\t\treturn;\n\tSideEffectsCollector sideEffects(m_dialect, _expr, &m_functionSideEffects);\n\tif (sideEffects.invalidatesStorage())\n\t\tm_state.environment.storage.clear();\n\tif (sideEffects.invalidatesMemory())\n\t{\n\t\tm_state.environment.memory.clear();\n\t\tm_state.environment.keccak.clear();\n\t}\n}\n\nbool DataFlowAnalyzer::inScope(YulName _variableName) const\n{\n\tfor (auto const& scope: m_variableScopes | ranges::views::reverse)\n\t{\n\t\tif (scope.variables.count(_variableName))\n\t\t\treturn true;\n\t\tif (scope.isFunction)\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n\nstd::optional<u256> DataFlowAnalyzer::valueOfIdentifier(YulName const& _name) const\n{\n\tif (AssignedValue const* value = variableValue(_name))\n\t\tif (Literal const* literal = std::get_if<Literal>(value->value))\n\t\t\treturn literal->value.value();\n\treturn std::nullopt;\n}\n\nstd::optional<std::pair<YulName, YulName>> DataFlowAnalyzer::isSimpleStore(\n\tStoreLoadLocation _location,\n\tExpressionStatement const& _statement\n) const\n{\n\tif (FunctionCall const* funCall = std::get_if<FunctionCall>(&_statement.expression))\n\t\tif (\n\t\t\tstd::holds_alternative<BuiltinName>(funCall->functionName) &&\n\t\t\tstd::get<BuiltinName>(funCall->functionName).handle == m_storeFunctionName[static_cast<unsigned>(_location)]\n\t\t)\n\t\t\tif (Identifier const* key = std::get_if<Identifier>(&funCall->arguments.front()))\n\t\t\t\tif (Identifier const* value = std::get_if<Identifier>(&funCall->arguments.back()))\n\t\t\t\t\treturn std::make_pair(key->name, value->name);\n\treturn {};\n}\n\nstd::optional<YulName> DataFlowAnalyzer::isSimpleLoad(\n\tStoreLoadLocation _location,\n\tExpression const& _expression\n) const\n{\n\tif (FunctionCall const* funCall = std::get_if<FunctionCall>(&_expression))\n\t\tif (\n\t\t\tstd::holds_alternative<BuiltinName>(funCall->functionName) &&\n\t\t\tstd::get<BuiltinName>(funCall->functionName).handle == m_loadFunctionName[static_cast<unsigned>(_location)]\n\t\t)\n\t\t\tif (Identifier const* key = std::get_if<Identifier>(&funCall->arguments.front()))\n\t\t\t\treturn key->name;\n\treturn {};\n}\n\nstd::optional<std::pair<YulName, YulName>> DataFlowAnalyzer::isKeccak(Expression const& _expression) const\n{\n\tif (FunctionCall const* funCall = std::get_if<FunctionCall>(&_expression))\n\t\tif (\n\t\t\tstd::holds_alternative<BuiltinName>(funCall->functionName) &&\n\t\t\tstd::get<BuiltinName>(funCall->functionName).handle == m_dialect.hashFunctionHandle()\n\t\t)\n\t\t\tif (Identifier const* start = std::get_if<Identifier>(&funCall->arguments.at(0)))\n\t\t\t\tif (Identifier const* length = std::get_if<Identifier>(&funCall->arguments.at(1)))\n\t\t\t\t\treturn std::make_pair(start->name, length->name);\n\treturn std::nullopt;\n}\n\nvoid DataFlowAnalyzer::joinKnowledge(Environment const& _olderEnvironment)\n{\n\tif (!m_analyzeStores)\n\t\treturn;\n\tjoinKnowledgeHelper(m_state.environment.storage, _olderEnvironment.storage);\n\tjoinKnowledgeHelper(m_state.environment.memory, _olderEnvironment.memory);\n\tstd::erase_if(m_state.environment.keccak, mapTuple([&_olderEnvironment](auto&& key, auto&& currentValue) {\n\t\tYulName const* oldValue = valueOrNullptr(_olderEnvironment.keccak, key);\n\t\treturn !oldValue || *oldValue != currentValue;\n\t}));\n}\n\nvoid DataFlowAnalyzer::joinKnowledgeHelper(\n\tstd::unordered_map<YulName, YulName>& _this,\n\tstd::unordered_map<YulName, YulName> const& _older\n)\n{\n\t// We clear if the key does not exist in the older map or if the value is different.\n\t// This also works for memory because _older is an \"older version\"\n\t// of m_state.environment.memory and thus any overlapping write would have cleared the keys\n\t// that are not known to be different inside m_state.environment.memory already.\n\tstd::erase_if(_this, mapTuple([&_older](auto&& key, auto&& currentValue){\n\t\tYulName const* oldValue = valueOrNullptr(_older, key);\n\t\treturn !oldValue || *oldValue != currentValue;\n\t}));\n}\n"
  },
  {
    "path": "libyul/optimiser/DataFlowAnalyzer.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Base class to perform data flow analysis during AST walks.\n * Tracks assignments and is used as base class for both Rematerialiser and\n * Common Subexpression Eliminator.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/KnowledgeBase.h>\n#include <libyul/YulName.h>\n#include <libyul/AST.h> // Needed for m_zero below.\n#include <libyul/SideEffects.h>\n\n#include <libsolutil/Numeric.h>\n#include <libsolutil/Common.h>\n\n#include <map>\n#include <set>\n\nnamespace solidity::yul\n{\nclass Dialect;\nstruct SideEffects;\nclass KnowledgeBase;\n\n/// Value assigned to a variable.\nstruct AssignedValue\n{\n\tExpression const* value{nullptr};\n\t/// Loop nesting depth of the definition of the variable.\n\tsize_t loopDepth{0};\n};\n\n/**\n * Base class to perform data flow analysis during AST walks.\n * Tracks assignments and is used as base class for both Rematerialiser and\n * Common Subexpression Eliminator.\n *\n * A special zero constant expression is used for the default value of variables.\n *\n * The class also tracks contents in storage and memory. Both keys and values\n * are names of variables. Whenever such a variable is re-assigned, the knowledge\n * is cleared.\n *\n * For elementary statements, we check if it is an SSTORE(x, y) / MSTORE(x, y)\n * If yes, visit the statement. Then record that fact and clear all storage slots t\n *   where we cannot prove x != t or y == m_storage[t] using the current values of the variables x and t.\n * Otherwise, determine if the statement invalidates storage/memory. If yes, clear all knowledge\n * about storage/memory before visiting the statement. Then visit the statement.\n *\n * For forward-joining control flow, storage/memory information from the branches is combined.\n * If the keys or values are different or non-existent in one branch, the key is deleted.\n * This works also for memory (where addresses overlap) because one branch is always an\n * older version of the other and thus overlapping contents would have been deleted already\n * at the point of assignment.\n *\n * The DataFlowAnalyzer currently does not deal with the ``leave`` statement. This is because\n * it only matters at the end of a function body, which is a point in the code a derived class\n * can not easily deal with.\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter.\n */\nclass DataFlowAnalyzer: public ASTModifier\n{\npublic:\n\tenum class MemoryAndStorage { Analyze, Ignore };\n\t/// @param _functionSideEffects\n\t///            Side-effects of user-defined functions. Worst-case side-effects are assumed\n\t///            if this is not provided or the function is not found.\n\t///            The parameter is mostly used to determine movability of expressions.\n\texplicit DataFlowAnalyzer(\n\t\tDialect const& _dialect,\n\t\tMemoryAndStorage _analyzeStores,\n\t\tstd::map<FunctionHandle, SideEffects> _functionSideEffects = {}\n\t);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(ExpressionStatement& _statement) override;\n\tvoid operator()(Assignment& _assignment) override;\n\tvoid operator()(VariableDeclaration& _varDecl) override;\n\tvoid operator()(If& _if) override;\n\tvoid operator()(Switch& _switch) override;\n\tvoid operator()(FunctionDefinition&) override;\n\tvoid operator()(ForLoop&) override;\n\tvoid operator()(Block& _block) override;\n\n\t/// @returns the current value of the given variable, if known - always movable.\n\tAssignedValue const* variableValue(YulName _variable) const { return util::valueOrNullptr(m_state.value, _variable); }\n\tstd::vector<YulName> const* sortedReferences(YulName _variable) const { return util::valueOrNullptr(m_state.sortedReferences, _variable); }\n\tstd::map<YulName, AssignedValue> const& allValues() const { return m_state.value; }\n\tstd::optional<YulName> storageValue(YulName _key) const;\n\tstd::optional<YulName> memoryValue(YulName _key) const;\n\tstd::optional<YulName> keccakValue(YulName _start, YulName _length) const;\n\nprotected:\n\t/// Registers the assignment.\n\tvoid handleAssignment(std::set<YulName> const& _names, Expression* _value, bool _isDeclaration);\n\n\t/// Creates a new inner scope.\n\tvoid pushScope(bool _functionScope);\n\n\t/// Removes the innermost scope and clears all variables in it.\n\tvoid popScope();\n\n\t/// Clears information about the values assigned to the given variables,\n\t/// for example at points where control flow is merged.\n\tvoid clearValues(std::set<YulName> const& _variablesToClear);\n\n\tvirtual void assignValue(YulName _variable, Expression const* _value);\n\n\t/// Clears knowledge about storage or memory if they may be modified inside the block.\n\tvoid clearKnowledgeIfInvalidated(Block const& _block);\n\n\t/// Clears knowledge about storage or memory if they may be modified inside the expression.\n\tvoid clearKnowledgeIfInvalidated(Expression const& _expression);\n\n\t/// Returns true iff the variable is in scope.\n\tbool inScope(YulName _variableName) const;\n\n\t/// Returns the literal value of the identifier, if it exists.\n\tstd::optional<u256> valueOfIdentifier(YulName const& _name) const;\n\n\tenum class StoreLoadLocation {\n\t\tMemory = 0,\n\t\tStorage = 1,\n\t\tLast = Storage\n\t};\n\n\t/// Checks if the statement is sstore(a, b) / mstore(a, b)\n\t/// where a and b are variables and returns these variables in that case.\n\tstd::optional<std::pair<YulName, YulName>> isSimpleStore(\n\t\tStoreLoadLocation _location,\n\t\tExpressionStatement const& _statement\n\t) const;\n\n\t/// Checks if the expression is sload(a) / mload(a)\n\t/// where a is a variable and returns the variable in that case.\n\tstd::optional<YulName> isSimpleLoad(\n\t\tStoreLoadLocation _location,\n\t\tExpression const& _expression\n\t) const;\n\n\t/// Checks if the expression is keccak256(s, l)\n\t/// where s and l are variables and returns these variables in that case.\n\tstd::optional<std::pair<YulName, YulName>> isKeccak(Expression const& _expression) const;\n\n\tDialect const& m_dialect;\n\t/// Side-effects of user-defined functions. Worst-case side-effects are assumed\n\t/// if this is not provided or the function is not found.\n\tstd::map<FunctionHandle, SideEffects> m_functionSideEffects;\n\nprivate:\n\tstruct Environment\n\t{\n\t\tstd::unordered_map<YulName, YulName> storage;\n\t\tstd::unordered_map<YulName, YulName> memory;\n\t\t/// If keccak[s, l] = y then y := keccak256(s, l) occurs in the code.\n\t\tstd::map<std::pair<YulName, YulName>, YulName> keccak;\n\t};\n\tstruct State\n\t{\n\t\t/// Current values of variables, always movable.\n\t\tstd::map<YulName, AssignedValue> value;\n\t\t/// m_references[a].contains(b) <=> the current expression assigned to a references b\n\t\t/// The mapped vectors _must always_ be sorted\n\t\tstd::unordered_map<YulName, std::vector<YulName>> sortedReferences;\n\n\t\tEnvironment environment;\n\t};\n\n\t/// Joins knowledge about storage and memory with an older point in the control-flow.\n\t/// This only works if the current state is a direct successor of the older point,\n\t/// i.e. `_olderState.storage` and `_olderState.memory` cannot have additional changes.\n\t/// Does nothing if memory and storage analysis is disabled / ignored.\n\tvoid joinKnowledge(Environment const& _olderEnvironment);\n\n\tstatic void joinKnowledgeHelper(\n\t\tstd::unordered_map<YulName, YulName>& _thisData,\n\t\tstd::unordered_map<YulName, YulName> const& _olderData\n\t);\n\n\tState m_state;\n\nprotected:\n\tKnowledgeBase m_knowledgeBase;\n\n\t/// If true, analyzes memory and storage content via mload/mstore and sload/sstore.\n\tbool m_analyzeStores = true;\n\tstd::optional<BuiltinHandle> m_storeFunctionName[static_cast<unsigned>(StoreLoadLocation::Last) + 1];\n\tstd::optional<BuiltinHandle> m_loadFunctionName[static_cast<unsigned>(StoreLoadLocation::Last) + 1];\n\n\t/// Current nesting depth of loops.\n\tsize_t m_loopDepth{0};\n\n\tstruct Scope\n\t{\n\t\texplicit Scope(bool _isFunction): isFunction(_isFunction) {}\n\t\tstd::set<YulName> variables;\n\t\tbool isFunction;\n\t};\n\t/// Special expression whose address will be used in m_value.\n\t/// YulName does not need to be reset because DataFlowAnalyzer is short-lived.\n\tExpression const m_zero{Literal{{}, LiteralKind::Number, LiteralValue{0, std::nullopt}}};\n\t/// List of scopes.\n\tstd::vector<Scope> m_variableScopes;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/DeadCodeEliminator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that removes unreachable code.\n */\n\n#include <libyul/optimiser/DeadCodeEliminator.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/ControlFlowSideEffectsCollector.h>\n#include <libyul/AST.h>\n\n#include <libevmasm/SemanticInformation.h>\n\n#include <algorithm>\n#include <limits>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::yul;\n\nvoid DeadCodeEliminator::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tControlFlowSideEffectsCollector sideEffects(_context.dialect, _ast);\n\tDeadCodeEliminator{\n\t\t_context.dialect,\n\t\tsideEffects.functionSideEffectsNamed()\n\t}(_ast);\n}\n\nvoid DeadCodeEliminator::operator()(ForLoop& _for)\n{\n\tyulAssert(_for.pre.statements.empty(), \"DeadCodeEliminator needs ForLoopInitRewriter as a prerequisite.\");\n\tASTModifier::operator()(_for);\n}\n\nvoid DeadCodeEliminator::operator()(Block& _block)\n{\n\tTerminationFinder::ControlFlow controlFlowChange;\n\tsize_t index;\n\tstd::tie(controlFlowChange, index) = TerminationFinder{m_dialect, &m_functionSideEffects}.firstUnconditionalControlFlowChange(_block.statements);\n\n\t// Erase everything after the terminating statement that is not a function definition.\n\tif (controlFlowChange != TerminationFinder::ControlFlow::FlowOut && index != std::numeric_limits<size_t>::max())\n\t\t_block.statements.erase(\n\t\t\tremove_if(\n\t\t\t\t_block.statements.begin() + static_cast<ptrdiff_t>(index) + 1,\n\t\t\t\t_block.statements.end(),\n\t\t\t\t[] (Statement const& _s) { return !std::holds_alternative<yul::FunctionDefinition>(_s); }\n\t\t\t),\n\t\t\t_block.statements.end()\n\t\t);\n\n\tASTModifier::operator()(_block);\n}\n"
  },
  {
    "path": "libyul/optimiser/DeadCodeEliminator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that removes unused variables and functions.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/YulName.h>\n#include <libyul/ControlFlowSideEffects.h>\n\n#include <map>\n#include <set>\n\nnamespace solidity::yul\n{\nclass Dialect;\nstruct OptimiserStepContext;\n\n/**\n * Optimisation stage that removes unreachable code\n *\n * Unreachable code is any code within a block which is preceded by a\n * leave, return, invalid, break, continue, selfdestruct or revert or\n * a call to a user-defined function that never returns (either due to\n * recursion or a call to return / revert / stop).\n *\n * Function definitions are retained as they might be called by earlier\n * code and thus are considered reachable.\n *\n * Because variables declared in a for loop's init block have their scope extended to the loop body,\n * we require ForLoopInitRewriter to run before this step.\n *\n * Prerequisite: ForLoopInitRewriter, Function Hoister, Function Grouper\n */\nclass DeadCodeEliminator: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"DeadCodeEliminator\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(ForLoop& _for) override;\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\tDeadCodeEliminator(\n\t\tDialect const& _dialect,\n\t\tstd::map<YulName, ControlFlowSideEffects> _sideEffects\n\t): m_dialect(_dialect), m_functionSideEffects(std::move(_sideEffects)) {}\n\n\tDialect const& m_dialect;\n\tstd::map<YulName, ControlFlowSideEffects> m_functionSideEffects;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/Disambiguator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that makes all identifiers unique.\n */\n\n#include <libyul/optimiser/Disambiguator.h>\n\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Scope.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nYulName Disambiguator::translateIdentifier(YulName const _originalName)\n{\n\tif (m_externallyUsedIdentifiers.contains(_originalName))\n\t\treturn _originalName;\n\n\tassertThrow(!m_scopes.empty() && m_scopes.back(), OptimizerException, \"\");\n\tScope::Identifier const* id = m_scopes.back()->lookup(_originalName);\n\tassertThrow(id, OptimizerException, \"\");\n\tif (!m_translations.contains(id))\n\t\tm_translations[id] = m_nameDispenser.newName(_originalName);\n\treturn m_translations.at(id);\n}\n\nvoid Disambiguator::enterScope(Block const& _block)\n{\n\tenterScopeInternal(*m_info.scopes.at(&_block));\n}\n\nvoid Disambiguator::leaveScope(Block const& _block)\n{\n\tleaveScopeInternal(*m_info.scopes.at(&_block));\n}\n\nvoid Disambiguator::enterFunction(FunctionDefinition const& _function)\n{\n\tenterScopeInternal(*m_info.scopes.at(m_info.virtualBlocks.at(&_function).get()));\n}\n\nvoid Disambiguator::leaveFunction(FunctionDefinition const& _function)\n{\n\tleaveScopeInternal(*m_info.scopes.at(m_info.virtualBlocks.at(&_function).get()));\n}\n\nvoid Disambiguator::enterScopeInternal(Scope& _scope)\n{\n\tm_scopes.push_back(&_scope);\n}\n\nvoid Disambiguator::leaveScopeInternal(Scope& _scope)\n{\n\tassertThrow(!m_scopes.empty(), OptimizerException, \"\");\n\tassertThrow(m_scopes.back() == &_scope, OptimizerException, \"\");\n\tm_scopes.pop_back();\n}\n"
  },
  {
    "path": "libyul/optimiser/Disambiguator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that makes all identifiers unique.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/optimiser/NameDispenser.h>\n\n#include <optional>\n#include <set>\n\nnamespace solidity::yul\n{\nclass Dialect;\n\n/**\n * Creates a copy of a Yul AST replacing all identifiers by unique names.\n */\nclass Disambiguator: public ASTCopier\n{\npublic:\n\texplicit Disambiguator(\n\t\tDialect const& _dialect,\n\t\tAsmAnalysisInfo const& _analysisInfo,\n\t\tstd::set<YulName> const& _externallyUsedIdentifiers = {}\n\t):\n\t\tm_info(_analysisInfo),\n\t\tm_dialect(_dialect),\n\t\tm_externallyUsedIdentifiers(_externallyUsedIdentifiers),\n\t\tm_nameDispenser(_dialect, m_externallyUsedIdentifiers)\n\t{\n\t}\n\nprotected:\n\tvoid enterScope(Block const& _block) override;\n\tvoid leaveScope(Block const& _block) override;\n\tvoid enterFunction(FunctionDefinition const& _function) override;\n\tvoid leaveFunction(FunctionDefinition const& _function) override;\n\tYulName translateIdentifier(YulName _originalName) override;\n\n\tvoid enterScopeInternal(Scope& _scope);\n\tvoid leaveScopeInternal(Scope& _scope);\n\n\tAsmAnalysisInfo const& m_info;\n\tDialect const& m_dialect;\n\tstd::set<YulName> const& m_externallyUsedIdentifiers;\n\n\tstd::vector<Scope*> m_scopes;\n\tstd::map<void const*, YulName> m_translations;\n\tNameDispenser m_nameDispenser;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/EqualStoreEliminator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that removes mstore and sstore operations if they store the same\n * value that is already known to be in that slot.\n */\n\n#include <libyul/optimiser/EqualStoreEliminator.h>\n\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::evmasm;\nusing namespace solidity::yul;\n\nvoid EqualStoreEliminator::run(OptimiserStepContext const& _context, Block& _ast)\n{\n\tEqualStoreEliminator eliminator{\n\t\t_context.dialect,\n\t\tSideEffectsPropagator::sideEffects(_context.dialect, CallGraphGenerator::callGraph(_ast))\n\t};\n\teliminator(_ast);\n\n\tStatementRemover remover{eliminator.m_pendingRemovals};\n\tremover(_ast);\n}\n\nvoid EqualStoreEliminator::visit(Statement& _statement)\n{\n\t// No need to consider potential changes through complex arguments since\n\t// isSimpleStore only returns something if the arguments are identifiers.\n\tif (ExpressionStatement const* expression = std::get_if<ExpressionStatement>(&_statement))\n\t{\n\t\tif (auto vars = isSimpleStore(StoreLoadLocation::Storage, *expression))\n\t\t{\n\t\t\tif (std::optional<YulName> currentValue = storageValue(vars->first))\n\t\t\t\tif (*currentValue == vars->second)\n\t\t\t\t\tm_pendingRemovals.insert(&_statement);\n\t\t}\n\t\telse if (auto vars = isSimpleStore(StoreLoadLocation::Memory, *expression))\n\t\t{\n\t\t\tif (std::optional<YulName> currentValue = memoryValue(vars->first))\n\t\t\t\tif (*currentValue == vars->second)\n\t\t\t\t\tm_pendingRemovals.insert(&_statement);\n\t\t}\n\t}\n\n\tDataFlowAnalyzer::visit(_statement);\n}\n"
  },
  {
    "path": "libyul/optimiser/EqualStoreEliminator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that removes mstore and sstore operations if they store the same\n * value that is already known to be in that slot.\n */\n\n#pragma once\n\n#include <libyul/optimiser/DataFlowAnalyzer.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Optimisation stage that removes mstore and sstore operations if they store the same\n * value that is already known to be in that slot.\n *\n * Works best if the code is in SSA form - without literal arguments.\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter.\n */\nclass EqualStoreEliminator: public DataFlowAnalyzer\n{\npublic:\n\tstatic constexpr char const* name{\"EqualStoreEliminator\"};\n\tstatic void run(OptimiserStepContext const&, Block& _ast);\n\nprivate:\n\tEqualStoreEliminator(\n\t\tDialect const& _dialect,\n\t\tstd::map<FunctionHandle, SideEffects> _functionSideEffects\n\t):\n\t\tDataFlowAnalyzer(_dialect, MemoryAndStorage::Analyze, std::move(_functionSideEffects))\n\t{}\n\nprotected:\n\tusing ASTModifier::visit;\n\tvoid visit(Statement& _statement) override;\n\n\tstd::set<Statement const*> m_pendingRemovals;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/EquivalentFunctionCombiner.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that combines syntactically equivalent functions.\n */\n\n#include <libyul/optimiser/EquivalentFunctionCombiner.h>\n#include <libyul/AST.h>\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid EquivalentFunctionCombiner::run(OptimiserStepContext&, Block& _ast)\n{\n\tEquivalentFunctionCombiner{EquivalentFunctionDetector::run(_ast)}(_ast);\n}\n\nvoid EquivalentFunctionCombiner::operator()(FunctionCall& _funCall)\n{\n\tif (!isBuiltinFunctionCall(_funCall))\n\t{\n\t\tauto* identifier = std::get_if<Identifier>(&_funCall.functionName);\n\t\tyulAssert(identifier);\n\t\tauto it = m_duplicates.find(identifier->name);\n\t\tif (it != m_duplicates.end())\n\t\t\tidentifier->name = it->second->name;\n\t}\n\tASTModifier::operator()(_funCall);\n}\n"
  },
  {
    "path": "libyul/optimiser/EquivalentFunctionCombiner.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that combines syntactically equivalent functions.\n */\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/EquivalentFunctionDetector.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/ASTForward.h>\n\nnamespace solidity::yul\n{\n\nstruct OptimiserStepContext;\n\n/**\n * Optimiser component that detects syntactically equivalent functions and replaces all calls to any of them by calls\n * to one particular of them.\n *\n * Prerequisite: Disambiguator, Function Hoister\n */\nclass EquivalentFunctionCombiner: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"EquivalentFunctionCombiner\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(FunctionCall& _funCall) override;\n\nprivate:\n\tEquivalentFunctionCombiner(std::map<YulName, FunctionDefinition const*> _duplicates): m_duplicates(std::move(_duplicates)) {}\n\tstd::map<YulName, FunctionDefinition const*> m_duplicates;\n};\n\n\n}\n"
  },
  {
    "path": "libyul/optimiser/EquivalentFunctionDetector.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that combines syntactically equivalent functions.\n */\n\n#include <libyul/optimiser/EquivalentFunctionDetector.h>\n#include <libyul/optimiser/SyntacticalEquality.h>\n\n#include <libyul/AST.h>\n#include <libyul/optimiser/Metrics.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid EquivalentFunctionDetector::operator()(FunctionDefinition const& _fun)\n{\n\tuint64_t bodyHash = m_blockHashes[&_fun.body];\n\tauto& candidates = m_candidates[bodyHash];\n\tfor (auto const& candidate: candidates)\n\t\tif (SyntacticallyEqual{}.statementEqual(_fun, *candidate))\n\t\t{\n\t\t\tm_duplicates[_fun.name] = candidate;\n\t\t\treturn;\n\t\t}\n\tcandidates.push_back(&_fun);\n}\n"
  },
  {
    "path": "libyul/optimiser/EquivalentFunctionDetector.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that combines syntactically equivalent functions.\n */\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/BlockHasher.h>\n#include <libyul/ASTForward.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Optimiser component that detects syntactically equivalent functions.\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter\n */\nclass EquivalentFunctionDetector: public ASTWalker\n{\npublic:\n\tstatic std::map<YulName, FunctionDefinition const*> run(Block& _block)\n\t{\n\t\tEquivalentFunctionDetector detector{BlockHasher::run(_block)};\n\t\tdetector(_block);\n\t\treturn std::move(detector.m_duplicates);\n\t}\n\n\tusing ASTWalker::operator();\n\tvoid operator()(FunctionDefinition const& _fun) override;\n\nprivate:\n\tEquivalentFunctionDetector(std::map<Block const*, uint64_t> _blockHashes): m_blockHashes(std::move(_blockHashes)) {}\n\n\tstd::map<Block const*, uint64_t> m_blockHashes;\n\tstd::map<uint64_t, std::vector<FunctionDefinition const*>> m_candidates;\n\tstd::map<YulName, FunctionDefinition const*> m_duplicates;\n};\n\n\n}\n"
  },
  {
    "path": "libyul/optimiser/ExpressionInliner.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that performs function inlining inside expressions.\n */\n\n#include <libyul/optimiser/ExpressionInliner.h>\n\n#include <libyul/optimiser/InlinableExpressionFunctionFinder.h>\n#include <libyul/optimiser/Metrics.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/Substitution.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid ExpressionInliner::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tInlinableExpressionFunctionFinder funFinder;\n\tfunFinder(_ast);\n\tExpressionInliner inliner{_context.dialect, funFinder.inlinableFunctions()};\n\tinliner(_ast);\n}\n\nvoid ExpressionInliner::operator()(FunctionDefinition& _fun)\n{\n\tASTModifier::operator()(_fun);\n}\n\nvoid ExpressionInliner::visit(Expression& _expression)\n{\n\tASTModifier::visit(_expression);\n\tif (std::holds_alternative<FunctionCall>(_expression))\n\t{\n\t\tFunctionCall& funCall = std::get<FunctionCall>(_expression);\n\t\tYulString const functionName{resolveFunctionName(funCall.functionName, m_dialect)};\n\t\tif (!m_inlinableFunctions.count(functionName))\n\t\t\treturn;\n\t\tFunctionDefinition const& fun = *m_inlinableFunctions.at(functionName);\n\n\t\tstd::map<YulName, Expression const*> substitutions;\n\t\tfor (size_t i = 0; i < funCall.arguments.size(); i++)\n\t\t{\n\t\t\tExpression const& arg = funCall.arguments[i];\n\t\t\tYulName paraName = fun.parameters[i].name;\n\n\t\t\tif (!SideEffectsCollector(m_dialect, arg).movable())\n\t\t\t\treturn;\n\n\t\t\tsize_t refs = ReferencesCounter::countReferences(fun.body)[paraName];\n\t\t\tsize_t cost = CodeCost::codeCost(m_dialect, arg);\n\n\t\t\tif (refs > 1 && cost > 1)\n\t\t\t\treturn;\n\n\t\t\tsubstitutions[paraName] = &arg;\n\t\t}\n\n\t\t_expression = Substitution(substitutions).translate(*std::get<Assignment>(fun.body.statements.front()).value);\n\t}\n}\n"
  },
  {
    "path": "libyul/optimiser/ExpressionInliner.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that performs function inlining.\n */\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/ASTForward.h>\n#include <libyul/YulName.h>\n\n#include <optional>\n#include <set>\n\nnamespace solidity::yul\n{\nclass Dialect;\nstruct OptimiserStepContext;\n\n/**\n * Optimiser component that modifies an AST in place, inlining functions that can be\n * inlined inside functional expressions, i.e. functions that\n *  - return a single value\n *  - have a body like r := <functional expression>\n *  - neither reference themselves nor r in the right hand side\n *\n * Furthermore, for all parameters, all of the following need to be true\n *  - the argument is movable\n *  - the parameter is either referenced less than twice in the function body, or the argument is rather cheap\n *    (\"cost\" of at most 1 like a constant up to 0xff)\n *\n * This component can only be used on sources with unique names.\n */\nclass ExpressionInliner: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"ExpressionInliner\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(FunctionDefinition& _fun) override;\n\n\tvoid visit(Expression& _expression) override;\n\nprivate:\n\tExpressionInliner(\n\t\tDialect const& _dialect,\n\t\tstd::map<YulName, FunctionDefinition const*> const& _inlinableFunctions\n\t): m_dialect(_dialect), m_inlinableFunctions(_inlinableFunctions)\n\t{}\n\n\tDialect const& m_dialect;\n\tstd::map<YulName, FunctionDefinition const*> const& m_inlinableFunctions;\n\n\tstd::map<YulName, YulName> m_varReplacements;\n\t/// Set of functions we are currently visiting inside.\n\tstd::set<YulName> m_currentFunctions;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/ExpressionJoiner.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that undoes what the ExpressionSplitter did, i.e.\n * it more or less inlines variable declarations.\n */\n\n#include <libyul/optimiser/ExpressionJoiner.h>\n\n#include <libyul/optimiser/FunctionGrouper.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/Exceptions.h>\n#include <libyul/AST.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <range/v3/view/reverse.hpp>\n\n#include <limits>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid ExpressionJoiner::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tExpressionJoiner{_ast}(_ast);\n\tFunctionGrouper::run(_context, _ast);\n}\n\n\nvoid ExpressionJoiner::operator()(FunctionCall& _funCall)\n{\n\thandleArguments(_funCall.arguments);\n}\n\nvoid ExpressionJoiner::operator()(Block& _block)\n{\n\tresetLatestStatementPointer();\n\tfor (size_t i = 0; i < _block.statements.size(); ++i)\n\t{\n\t\tvisit(_block.statements[i]);\n\t\tm_currentBlock = &_block;\n\t\tm_latestStatementInBlock = i;\n\t}\n\n\tremoveEmptyBlocks(_block);\n\tresetLatestStatementPointer();\n}\n\nvoid ExpressionJoiner::visit(Expression& _e)\n{\n\tif (std::holds_alternative<Identifier>(_e))\n\t{\n\t\tIdentifier const& identifier = std::get<Identifier>(_e);\n\t\tif (isLatestStatementVarDeclJoinable(identifier))\n\t\t{\n\t\t\tVariableDeclaration& varDecl = std::get<VariableDeclaration>(*latestStatement());\n\t\t\t_e = std::move(*varDecl.value);\n\n\t\t\t// Delete the variable declaration (also get the moved-from structure back into a sane state)\n\t\t\t*latestStatement() = Block();\n\n\t\t\tdecrementLatestStatementPointer();\n\t\t}\n\t}\n\telse\n\t\tASTModifier::visit(_e);\n}\n\nExpressionJoiner::ExpressionJoiner(Block& _ast)\n{\n\tm_references = VariableReferencesCounter::countReferences(_ast);\n}\n\nvoid ExpressionJoiner::handleArguments(std::vector<Expression>& _arguments)\n{\n\t// We have to fill from left to right, but we can only\n\t// fill if everything to the right is just an identifier\n\t// or a literal.\n\t// Also we only descend into function calls if everything\n\t// on the right is an identifier or literal.\n\n\tsize_t i = _arguments.size();\n\tfor (Expression const& arg: _arguments | ranges::views::reverse)\n\t{\n\t\t--i;\n\t\tif (!std::holds_alternative<Identifier>(arg) && !std::holds_alternative<Literal>(arg))\n\t\t\tbreak;\n\t}\n\t// i points to the last element that is neither an identifier nor a literal,\n\t// or to the first element if all of them are identifiers or literals.\n\n\tfor (; i < _arguments.size(); ++i)\n\t\tvisit(_arguments.at(i));\n}\n\nvoid ExpressionJoiner::decrementLatestStatementPointer()\n{\n\tif (!m_currentBlock)\n\t\treturn;\n\tif (m_latestStatementInBlock > 0)\n\t\t--m_latestStatementInBlock;\n\telse\n\t\tresetLatestStatementPointer();\n}\n\nvoid ExpressionJoiner::resetLatestStatementPointer()\n{\n\tm_currentBlock = nullptr;\n\tm_latestStatementInBlock = std::numeric_limits<size_t>::max();\n}\n\nStatement* ExpressionJoiner::latestStatement()\n{\n\tif (!m_currentBlock)\n\t\treturn nullptr;\n\telse\n\t\treturn &m_currentBlock->statements.at(m_latestStatementInBlock);\n}\n\nbool ExpressionJoiner::isLatestStatementVarDeclJoinable(Identifier const& _identifier)\n{\n\tStatement const* statement = latestStatement();\n\tif (!statement || !std::holds_alternative<VariableDeclaration>(*statement))\n\t\treturn false;\n\tVariableDeclaration const& varDecl = std::get<VariableDeclaration>(*statement);\n\tif (varDecl.variables.size() != 1 || !varDecl.value)\n\t\treturn false;\n\tassertThrow(varDecl.variables.size() == 1, OptimizerException, \"\");\n\tassertThrow(varDecl.value, OptimizerException, \"\");\n\treturn varDecl.variables.at(0).name == _identifier.name && m_references[_identifier.name] == 1;\n}\n"
  },
  {
    "path": "libyul/optimiser/ExpressionJoiner.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that undoes what the ExpressionSplitter did, i.e.\n * it more or less inlines variable declarations.\n */\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/optimiser/ASTWalker.h>\n\n#include <map>\n\nnamespace solidity::yul\n{\n\nclass NameCollector;\nstruct OptimiserStepContext;\n\n/**\n * Optimiser component that modifies an AST in place, turning sequences\n * of variable declarations into complex expressions, if the variables\n * are declared in the right order. This component does the opposite\n * of ExpressionSplitter.\n * Since the order of opcode or function evaluation is unchanged,\n * this transformation does not need to care about conflicting opcodes.\n *\n * Code of the form\n *\n * let a1 := mload(y)\n * let a2 := mul(x, 4)\n * sstore(a2, a1)\n *\n * is transformed into\n *\n * sstore(mul(x, 4), mload(y))\n *\n * The transformation is not applied to loop conditions, because those are\n * evaluated with each loop.\n *\n * The component can be applied to sub-blocks of the AST, you do not\n * need to pass a full AST.\n *\n * Prerequisites: Disambiguator\n *\n * Implementation note: We visit the AST, modifying it in place.\n * The class starts counting references and will only replace variables\n * that have exactly one reference. It keeps a \"latest statement pointer\"\n * which always points to the statement right before the current statement.\n * Any function call or opcode will reset this pointer. If an identifier\n * is encountered that was declared in the \"latest statement\", it is replaced\n * by the value of the declaration, the \"latest statement\" is replaced\n * by an empty block and the pointer is decremented.\n * A block also resets the latest statement pointer.\n */\nclass ExpressionJoiner: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"ExpressionJoiner\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\nprivate:\n\texplicit ExpressionJoiner(Block& _ast);\n\n\tvoid operator()(Block& _block) override;\n\tvoid operator()(FunctionCall&) override;\n\n\tusing ASTModifier::visit;\n\tvoid visit(Expression& _e) override;\n\n\tvoid handleArguments(std::vector<Expression>& _arguments);\n\n\tvoid decrementLatestStatementPointer();\n\tvoid resetLatestStatementPointer();\n\tStatement* latestStatement();\n\tbool isLatestStatementVarDeclJoinable(Identifier const& _identifier);\n\nprivate:\n\tBlock* m_currentBlock = nullptr;            ///< Pointer to current block holding the statement being visited.\n\tsize_t m_latestStatementInBlock = 0;        ///< Offset to m_currentBlock's statements of the last visited statement.\n\tstd::map<YulName, size_t> m_references;   ///< Holds reference counts to all variable declarations in current block.\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/ExpressionSimplifier.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that uses the simplification rules to simplify expressions.\n */\n\n#include <libyul/optimiser/ExpressionSimplifier.h>\n\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/optimiser/SimplificationRules.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n\n#include <libevmasm/SemanticInformation.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid ExpressionSimplifier::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tExpressionSimplifier{_context.dialect}(_ast);\n}\n\nvoid ExpressionSimplifier::visit(Expression& _expression)\n{\n\tASTModifier::visit(_expression);\n\n\twhile (auto const* match = SimplificationRules::findFirstMatch(\n\t\t_expression,\n\t\tm_dialect,\n\t\t[this](YulName const& _var) -> AssignedValue const* {\n\t\t\tAssignedValue const* value = variableValue(_var);\n\t\t\tif (!value || !value->value)\n\t\t\t\treturn nullptr;\n\n\t\t\t// check that all variables in the value expression are in current scope\n\t\t\tMovableChecker const checker(m_dialect, *value->value);\n\t\t\tfor (YulName const& referencedVar: checker.referencedVariables())\n\t\t\t\tif (!inScope(referencedVar))\n\t\t\t\t\treturn nullptr;  // don't substitute if any referenced var is out of scope\n\n\t\t\treturn value;\n\t\t}\n\t))\n\t{\n\t\tauto const* evmDialect = dynamic_cast<EVMDialect const*>(&m_dialect);\n\t\tyulAssert(evmDialect);\n\t\t_expression = match->action().toExpression(debugDataOf(_expression), *evmDialect);\n\t}\n\n\tif (auto* functionCall = std::get_if<FunctionCall>(&_expression))\n\t\tif (std::optional<evmasm::Instruction> instruction = toEVMInstruction(m_dialect, functionCall->functionName))\n\t\t\tfor (auto op: evmasm::SemanticInformation::readWriteOperations(*instruction))\n\t\t\t\tif (op.startParameter && op.lengthParameter)\n\t\t\t\t{\n\t\t\t\t\tExpression& startArgument = functionCall->arguments.at(*op.startParameter);\n\t\t\t\t\tExpression const& lengthArgument = functionCall->arguments.at(*op.lengthParameter);\n\t\t\t\t\tif (\n\t\t\t\t\t\tknownToBeZero(lengthArgument) &&\n\t\t\t\t\t\t!knownToBeZero(startArgument) &&\n\t\t\t\t\t\t!std::holds_alternative<FunctionCall>(startArgument)\n\t\t\t\t\t)\n\t\t\t\t\t\tstartArgument = Literal{debugDataOf(startArgument), LiteralKind::Number, LiteralValue{0, std::nullopt}};\n\t\t\t\t}\n}\n\nbool ExpressionSimplifier::knownToBeZero(Expression const& _expression) const\n{\n\tif (auto const* literal = std::get_if<Literal>(&_expression))\n\t\treturn literal->value.value() == 0;\n\telse if (auto const* identifier = std::get_if<Identifier>(&_expression))\n\t\treturn valueOfIdentifier(identifier->name) == 0;\n\telse\n\t\treturn false;\n}\n"
  },
  {
    "path": "libyul/optimiser/ExpressionSimplifier.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that uses the simplification rules to simplify expressions.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n\n#include <libyul/optimiser/DataFlowAnalyzer.h>\n\nnamespace solidity::yul\n{\nclass Dialect;\nstruct OptimiserStepContext;\n\n/**\n * Applies simplification rules to all expressions.\n * The component will work best if the code is in SSA form, but\n * this is not required for correctness. Using CommonSubexpressionEliminator\n * also helps this component track equivalent sub-expressions.\n *\n * It tracks the current values of variables using the DataFlowAnalyzer\n * and takes them into account for replacements.\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter.\n */\nclass ExpressionSimplifier: public DataFlowAnalyzer\n{\npublic:\n\tstatic constexpr char const* name{\"ExpressionSimplifier\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid visit(Expression& _expression) override;\n\nprivate:\n\texplicit ExpressionSimplifier(Dialect const& _dialect):\n\t\tDataFlowAnalyzer(_dialect, MemoryAndStorage::Ignore)\n\t{}\n\tbool knownToBeZero(Expression const& _expression) const;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/ExpressionSplitter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that turns complex expressions into multiple variable\n * declarations.\n */\n\n#include <libyul/optimiser/ExpressionSplitter.h>\n\n#include <libyul/optimiser/OptimiserStep.h>\n\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\n\nExpressionSplitter::ExpressionSplitter(Dialect const& _dialect, NameDispenser& _nameDispenser):\n\tm_dialect(_dialect),\n\tm_nameDispenser(_nameDispenser)\n{}\n\nExpressionSplitter::~ExpressionSplitter() = default;\n\nvoid ExpressionSplitter::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tExpressionSplitter{_context.dialect, _context.dispenser}(_ast);\n}\n\nvoid ExpressionSplitter::operator()(FunctionCall& _funCall)\n{\n\tBuiltinFunction const* builtin = resolveBuiltinFunction(_funCall.functionName, m_dialect);\n\n\tfor (size_t i = _funCall.arguments.size(); i > 0; i--)\n\t\tif (!builtin || !builtin->literalArgument(i - 1))\n\t\t\toutlineExpression(_funCall.arguments[i - 1]);\n}\n\nvoid ExpressionSplitter::operator()(If& _if)\n{\n\toutlineExpression(*_if.condition);\n\t(*this)(_if.body);\n}\n\nvoid ExpressionSplitter::operator()(Switch& _switch)\n{\n\toutlineExpression(*_switch.expression);\n\tfor (auto& _case: _switch.cases)\n\t\t// Do not visit the case expression, nothing to split there.\n\t\t(*this)(_case.body);\n}\n\nvoid ExpressionSplitter::operator()(ForLoop& _loop)\n{\n\t(*this)(_loop.pre);\n\t// Do not visit the condition because we cannot split expressions there.\n\t(*this)(_loop.post);\n\t(*this)(_loop.body);\n}\n\nvoid ExpressionSplitter::operator()(Block& _block)\n{\n\tstd::vector<Statement> saved;\n\tswap(saved, m_statementsToPrefix);\n\n\tstd::function<std::optional<std::vector<Statement>>(Statement&)> f =\n\t\t\t[&](Statement& _statement) -> std::optional<std::vector<Statement>> {\n\t\tm_statementsToPrefix.clear();\n\t\tvisit(_statement);\n\t\tif (m_statementsToPrefix.empty())\n\t\t\treturn {};\n\t\tm_statementsToPrefix.emplace_back(std::move(_statement));\n\t\treturn std::move(m_statementsToPrefix);\n\t};\n\titerateReplacing(_block.statements, f);\n\n\tswap(saved, m_statementsToPrefix);\n}\n\nvoid ExpressionSplitter::outlineExpression(Expression& _expr)\n{\n\tif (std::holds_alternative<Identifier>(_expr))\n\t\treturn;\n\n\tvisit(_expr);\n\n\tlangutil::DebugData::ConstPtr debugData = debugDataOf(_expr);\n\tYulName var = m_nameDispenser.newName({});\n\tm_statementsToPrefix.emplace_back(VariableDeclaration{\n\t\tdebugData,\n\t\t{{NameWithDebugData{debugData, var}}},\n\t\tstd::make_unique<Expression>(std::move(_expr))\n\t});\n\t_expr = Identifier{debugData, var};\n}\n\n"
  },
  {
    "path": "libyul/optimiser/ExpressionSplitter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that turns complex expressions into multiple variable\n * declarations.\n */\n#pragma once\n\n#include <libyul/ASTForward.h>\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/NameDispenser.h>\n\n#include <vector>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\nstruct OptimiserStepContext;\n\n/**\n * Optimiser component that modifies an AST in place, turning complex\n * expressions into simple expressions and multiple variable declarations.\n *\n * Code of the form\n *\n * sstore(mul(x, 4), mload(y))\n *\n * is transformed into\n *\n * let a1 := mload(y)\n * let a2 := mul(x, 4)\n * sstore(a2, a1)\n *\n * The transformation is not applied to loop conditions, because the loop control flow\n * does not allow \"outlining\" the inner expressions in all cases.\n *\n * The final program should be in a form such that with the exception of a loop condition,\n * function calls can only appear in the right-hand side of a variable declaration,\n * assignments or expression statements and all arguments have to be constants or variables.\n */\nclass ExpressionSplitter: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"ExpressionSplitter\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\tvoid operator()(FunctionCall&) override;\n\tvoid operator()(If&) override;\n\tvoid operator()(Switch&) override;\n\tvoid operator()(ForLoop&) override;\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\tExpressionSplitter(\n\t\tDialect const& _dialect,\n\t\tNameDispenser& _nameDispenser\n\t);\n\t~ExpressionSplitter() override;\n\n\t/// Replaces the expression by a variable if it is a function call or functional\n\t/// instruction. The declaration of the variable is appended to m_statementsToPrefix.\n\t/// Recurses via visit().\n\tvoid outlineExpression(Expression& _expr);\n\n\t/// List of statements that should go in front of the currently visited AST element,\n\t/// at the statement level.\n\tstd::vector<Statement> m_statementsToPrefix;\n\tDialect const& m_dialect;\n\tNameDispenser& m_nameDispenser;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/ForLoopConditionIntoBody.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/optimiser/ForLoopConditionIntoBody.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/AST.h>\n\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid ForLoopConditionIntoBody::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tForLoopConditionIntoBody{_context.dialect}(_ast);\n}\n\nvoid ForLoopConditionIntoBody::operator()(ForLoop& _forLoop)\n{\n\tstd::optional<BuiltinHandle> booleanNegationFunctionHandle = m_dialect.booleanNegationFunctionHandle();\n\tif (\n\t\tbooleanNegationFunctionHandle &&\n\t\t!std::holds_alternative<Literal>(*_forLoop.condition) &&\n\t\t!std::holds_alternative<Identifier>(*_forLoop.condition)\n\t)\n\t{\n\t\tlangutil::DebugData::ConstPtr debugData = debugDataOf(*_forLoop.condition);\n\n\t\t_forLoop.body.statements.emplace(\n\t\t\tbegin(_forLoop.body.statements),\n\t\t\tIf {\n\t\t\t\tdebugData,\n\t\t\t\tstd::make_unique<Expression>(\n\t\t\t\t\tFunctionCall {\n\t\t\t\t\t\tdebugData,\n\t\t\t\t\t\tBuiltinName{debugData, *booleanNegationFunctionHandle},\n\t\t\t\t\t\tutil::make_vector<Expression>(std::move(*_forLoop.condition))\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t\tBlock {debugData, util::make_vector<Statement>(Break{{}})}\n\t\t\t}\n\t\t);\n\t\t_forLoop.condition = std::make_unique<Expression>(\n\t\t\tLiteral {\n\t\t\t\tdebugData,\n\t\t\t\tLiteralKind::Boolean,\n\t\t\t\tLiteralValue{true}\n\t\t\t}\n\t\t);\n\t}\n\tASTModifier::operator()(_forLoop);\n}\n\n"
  },
  {
    "path": "libyul/optimiser/ForLoopConditionIntoBody.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/Dialect.h>\n\nnamespace solidity::yul\n{\n\nstruct OptimiserStepContext;\n\n/**\n * Rewrites ForLoop by moving iteration condition into the ForLoop body.\n * For example, `for {} lt(a, b) {} { mstore(1, 2) }` will become\n * `for {} 1 {} { if iszero(lt(a, b)) { break } mstore(1, 2) }`\n *\n * By moving the iteration check part into the ForLoop body, we can apply expression splitter\n * to the condition expression.\n *\n * This rewriter will skip loops that already have literal constant as iteration condition.\n *\n * Requirements:\n * - The Disambiguator must be run upfront.\n * - To avoid unnecessary rewrite, it is recommended to run this rewriter after StructuralSimplifier.\n * - Only works for dialects with a builtin boolean negation function.\n */\nclass ForLoopConditionIntoBody: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"ForLoopConditionIntoBody\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(ForLoop& _forLoop) override;\n\nprivate:\n\tForLoopConditionIntoBody(Dialect const& _dialect): m_dialect(_dialect) {}\n\n\tDialect const& m_dialect;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/ForLoopConditionOutOfBody.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/optimiser/ForLoopConditionOutOfBody.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid ForLoopConditionOutOfBody::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tForLoopConditionOutOfBody{_context.dialect}(_ast);\n}\n\nvoid ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop)\n{\n\tASTModifier::operator()(_forLoop);\n\n\tif (\n\t\t!m_dialect.booleanNegationFunctionHandle() ||\n\t\t!std::holds_alternative<Literal>(*_forLoop.condition) ||\n\t\tstd::get<Literal>(*_forLoop.condition).value.value() == 0 ||\n\t\t_forLoop.body.statements.empty() ||\n\t\t!std::holds_alternative<If>(_forLoop.body.statements.front())\n\t)\n\t\treturn;\n\n\tIf& firstStatement = std::get<If>(_forLoop.body.statements.front());\n\tif (\n\t\tfirstStatement.body.statements.empty() ||\n\t\t!std::holds_alternative<Break>(firstStatement.body.statements.front())\n\t)\n\t\treturn;\n\tif (!SideEffectsCollector(m_dialect, *firstStatement.condition).movable())\n\t\treturn;\n\n\tstd::optional<BuiltinHandle> iszero = m_dialect.booleanNegationFunctionHandle();\n\tyulAssert(iszero.has_value());\n\tauto const& isZeroHandle = *iszero;\n\tlangutil::DebugData::ConstPtr debugData = debugDataOf(*firstStatement.condition);\n\n\tif (\n\t\tstd::holds_alternative<FunctionCall>(*firstStatement.condition) &&\n\t\tstd::holds_alternative<BuiltinName>(std::get<FunctionCall>(*firstStatement.condition).functionName) &&\n\t\tstd::get<BuiltinName>(std::get<FunctionCall>(*firstStatement.condition).functionName).handle == isZeroHandle\n\t)\n\t\t_forLoop.condition = std::make_unique<Expression>(std::move(std::get<FunctionCall>(*firstStatement.condition).arguments.front()));\n\telse\n\t\t_forLoop.condition = std::make_unique<Expression>(FunctionCall{\n\t\t\tdebugData,\n\t\t\tBuiltinName{debugData, isZeroHandle},\n\t\t\tutil::make_vector<Expression>(\n\t\t\t\tstd::move(*firstStatement.condition)\n\t\t\t)\n\t\t});\n\n\t_forLoop.body.statements.erase(_forLoop.body.statements.begin());\n}\n\n"
  },
  {
    "path": "libyul/optimiser/ForLoopConditionOutOfBody.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/Dialect.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Reverses the transformation of ForLoopConditionIntoBody.\n *\n * For any movable ``c``, it turns\n *\n * for { ... } 1 { ... } {\n *   if iszero(c) { break }\n *   ...\n * }\n *\n * into\n *\n * for { ... } c { ... } {\n *   ...\n * }\n *\n * and it turns\n *\n * for { ... } 1 { ... } {\n *   if c { break }\n *   ...\n * }\n *\n * into\n *\n * for { ... } iszero(c) { ... } {\n *   ...\n * }\n *\n * The LiteralRematerialiser should be run before this step.\n */\nclass ForLoopConditionOutOfBody: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"ForLoopConditionOutOfBody\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(ForLoop& _forLoop) override;\n\nprivate:\n\tForLoopConditionOutOfBody(Dialect const& _dialect):\n\t\tm_dialect(_dialect)\n\t{}\n\n\tDialect const& m_dialect;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/ForLoopInitRewriter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libyul/optimiser/ForLoopInitRewriter.h>\n#include <libyul/AST.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <functional>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid ForLoopInitRewriter::operator()(Block& _block)\n{\n\tutil::iterateReplacing(\n\t\t_block.statements,\n\t\t[&](Statement& _stmt) -> std::optional<std::vector<Statement>>\n\t\t{\n\t\t\tif (std::holds_alternative<ForLoop>(_stmt))\n\t\t\t{\n\t\t\t\tauto& forLoop = std::get<ForLoop>(_stmt);\n\t\t\t\t(*this)(forLoop.pre);\n\t\t\t\t(*this)(forLoop.body);\n\t\t\t\t(*this)(forLoop.post);\n\t\t\t\tstd::vector<Statement> rewrite;\n\t\t\t\tswap(rewrite, forLoop.pre.statements);\n\t\t\t\trewrite.emplace_back(std::move(forLoop));\n\t\t\t\treturn { std::move(rewrite) };\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvisit(_stmt);\n\t\t\t\treturn {};\n\t\t\t}\n\t\t}\n\t);\n}\n"
  },
  {
    "path": "libyul/optimiser/ForLoopInitRewriter.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Rewrites ForLoop by moving the pre statement block in front of the ForLoop.\n * Requirements:\n * - The Disambiguator must be run upfront.\n */\nclass ForLoopInitRewriter: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"ForLoopInitRewriter\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast)\n\t{\n\t\tForLoopInitRewriter{}(_ast);\n\t}\n\n\tusing ASTModifier::operator();\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\tForLoopInitRewriter() = default;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/FullInliner.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that performs function inlining for arbitrary functions.\n */\n\n#include <libyul/optimiser/FullInliner.h>\n\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/optimiser/FunctionCallFinder.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/Metrics.h>\n#include <libyul/optimiser/SSAValueTracker.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/Exceptions.h>\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Visitor.h>\n\n#include <range/v3/action/remove.hpp>\n#include <range/v3/view/reverse.hpp>\n#include <range/v3/view/zip.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid FullInliner::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tFullInliner inliner{_ast, _context.dispenser, _context.dialect};\n\tinliner.run(Pass::InlineTiny);\n\tinliner.run(Pass::InlineRest);\n}\n\nFullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser, Dialect const& _dialect):\n\tm_ast(_ast),\n\tm_recursiveFunctions(CallGraphGenerator::callGraph(_ast).recursiveFunctions()),\n\tm_nameDispenser(_dispenser),\n\tm_dialect(_dialect)\n{\n\n\t// Determine constants\n\tSSAValueTracker tracker;\n\ttracker(m_ast);\n\tfor (auto const& ssaValue: tracker.values())\n\t\tif (ssaValue.second && std::holds_alternative<Literal>(*ssaValue.second))\n\t\t\tm_constants.emplace(ssaValue.first);\n\n\t// Store size of global statements.\n\tm_functionSizes[YulName{}] = CodeSize::codeSize(_ast);\n\tstd::map<FunctionHandle, size_t> references = ReferencesCounter::countReferences(m_ast);\n\tfor (auto& statement: m_ast.statements)\n\t{\n\t\tif (!std::holds_alternative<FunctionDefinition>(statement))\n\t\t\tcontinue;\n\t\tFunctionDefinition& fun = std::get<FunctionDefinition>(statement);\n\t\tm_functions[fun.name] = &fun;\n\t\tif (LeaveFinder::containsLeave(fun))\n\t\t\tm_noInlineFunctions.insert(fun.name);\n\t\t// Always inline functions that are only called once.\n\t\tif (references[fun.name] == 1)\n\t\t\tm_singleUse.emplace(fun.name);\n\t\tupdateCodeSize(fun);\n\t}\n\n\t// Check for memory guard.\n\tif (auto const memoryGuard = m_dialect.findBuiltin(\"memoryguard\"))\n\t{\n\t\tstd::vector<FunctionCall*> memoryGuardCalls = findFunctionCalls(_ast, *memoryGuard);\n\t\t// We will perform less aggressive inlining, if no ``memoryguard`` call is found.\n\t\tif (!memoryGuardCalls.empty())\n\t\t\tm_hasMemoryGuard = true;\n\t}\n}\n\nvoid FullInliner::run(Pass _pass)\n{\n\tm_pass = _pass;\n\n\t// Note that the order of inlining can result in very different code.\n\t// Since AST IDs and thus function names depend on whether or not a contract\n\t// is compiled together with other source files, a change in AST IDs\n\t// should have as little an impact as possible. This is the case\n\t// if we handle inlining in source (and thus, for the IR generator,\n\t// function name) order.\n\t// We use stable_sort below to keep the inlining order of two functions\n\t// with the same depth.\n\tstd::map<FunctionHandle, size_t> depths = callDepths();\n\tstd::vector<FunctionDefinition*> functions;\n\tfor (auto& statement: m_ast.statements)\n\t\tif (std::holds_alternative<FunctionDefinition>(statement))\n\t\t\tfunctions.emplace_back(&std::get<FunctionDefinition>(statement));\n\tstd::stable_sort(functions.begin(), functions.end(), [&depths](\n\t\tFunctionDefinition const* _a,\n\t\tFunctionDefinition const* _b\n\t) {\n\t\treturn depths.at(_a->name) < depths.at(_b->name);\n\t});\n\tfor (FunctionDefinition* fun: functions)\n\t{\n\t\thandleBlock(fun->name, fun->body);\n\t\tupdateCodeSize(*fun);\n\t}\n\n\tfor (auto& statement: m_ast.statements)\n\t\tif (std::holds_alternative<Block>(statement))\n\t\t\thandleBlock({}, std::get<Block>(statement));\n}\n\nstd::map<FunctionHandle, size_t> FullInliner::callDepths() const\n{\n\tCallGraph cg = CallGraphGenerator::callGraph(m_ast);\n\tcg.functionCalls.erase(\"\"_yulname);\n\n\t// Remove calls to builtin functions.\n\tfor (auto& call: cg.functionCalls)\n\t\tfor (auto it = call.second.begin(); it != call.second.end();)\n\t\t\tif (std::holds_alternative<BuiltinHandle>(*it))\n\t\t\t\tit = call.second.erase(it);\n\t\t\telse\n\t\t\t\t++it;\n\n\tstd::map<FunctionHandle, size_t> depths;\n\tsize_t currentDepth = 0;\n\n\twhile (true)\n\t{\n\t\tstd::vector<FunctionHandle> removed;\n\t\tfor (auto it = cg.functionCalls.begin(); it != cg.functionCalls.end();)\n\t\t{\n\t\t\tauto const& [fun, callees] = *it;\n\t\t\tif (callees.empty())\n\t\t\t{\n\t\t\t\tremoved.emplace_back(fun);\n\t\t\t\tdepths[fun] = currentDepth;\n\t\t\t\tit = cg.functionCalls.erase(it);\n\t\t\t}\n\t\t\telse\n\t\t\t\t++it;\n\t\t}\n\n\t\tfor (auto& call: cg.functionCalls)\n\t\t\tfor (FunctionHandle toBeRemoved: removed)\n\t\t\t\tranges::actions::remove(call.second, toBeRemoved);\n\n\t\tcurrentDepth++;\n\n\t\tif (removed.empty())\n\t\t\tbreak;\n\t}\n\n\t// Only recursive functions left here.\n\tfor (auto const& fun: cg.functionCalls)\n\t\tdepths[fun.first] = currentDepth;\n\n\treturn depths;\n}\n\nbool FullInliner::shallInline(FunctionCall const& _funCall, YulName _callSite)\n{\n\tif (isBuiltinFunctionCall(_funCall))\n\t\treturn false;\n\tyulAssert(std::holds_alternative<Identifier>(_funCall.functionName));\n\tauto const& functionName = std::get<Identifier>(_funCall.functionName).name;\n\t// No recursive inlining\n\tif (functionName == _callSite)\n\t\treturn false;\n\n\tFunctionDefinition* calledFunction = function(functionName);\n\tif (!calledFunction)\n\t\treturn false;\n\n\tif (m_noInlineFunctions.count(functionName) || recursive(*calledFunction))\n\t\treturn false;\n\n\t// No inlining of calls where argument expressions may have side-effects.\n\t// To avoid running into this, make sure that ExpressionSplitter runs before FullInliner.\n\tfor (auto const& argument: _funCall.arguments)\n\t\tif (!std::holds_alternative<Literal>(argument) && !std::holds_alternative<Identifier>(argument))\n\t\t\treturn false;\n\n\t// Inline really, really tiny functions\n\tsize_t size = m_functionSizes.at(calledFunction->name);\n\tif (size <= 1)\n\t\treturn true;\n\n\t// In the first pass, only inline tiny functions.\n\tif (m_pass == Pass::InlineTiny)\n\t\treturn false;\n\n\tbool aggressiveInlining = true;\n\n\tif (\n\t\tEVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&m_dialect);\n\t\t!evmDialect || !evmDialect->providesObjectAccess() || evmDialect->evmVersion() <= langutil::EVMVersion::homestead()\n\t)\n\t\t// No aggressive inlining with the old code transform.\n\t\taggressiveInlining = false;\n\n\t// No aggressive inlining, if we cannot perform stack-to-memory.\n\tif (!m_hasMemoryGuard || m_recursiveFunctions.count(_callSite))\n\t\taggressiveInlining = false;\n\n\tif (!aggressiveInlining && m_functionSizes.at(_callSite) > 45)\n\t\treturn false;\n\n\tif (m_singleUse.count(calledFunction->name))\n\t\treturn true;\n\n\t// Constant arguments might provide a means for further optimization, so they cause a bonus.\n\tbool constantArg = false;\n\tfor (auto const& argument: _funCall.arguments)\n\t\tif (std::holds_alternative<Literal>(argument) || (\n\t\t\tstd::holds_alternative<Identifier>(argument) &&\n\t\t\tm_constants.count(std::get<Identifier>(argument).name)\n\t\t))\n\t\t{\n\t\t\tconstantArg = true;\n\t\t\tbreak;\n\t\t}\n\n\treturn (size < (aggressiveInlining ? 8u : 6u) || (constantArg && size < (aggressiveInlining ? 16u : 12u)));\n}\n\nvoid FullInliner::tentativelyUpdateCodeSize(YulName _function, YulName _callSite)\n{\n\tm_functionSizes.at(_callSite) += m_functionSizes.at(_function);\n}\n\nvoid FullInliner::updateCodeSize(FunctionDefinition const& _fun)\n{\n\tm_functionSizes[_fun.name] = CodeSize::codeSize(_fun.body);\n}\n\nvoid FullInliner::handleBlock(YulName _currentFunctionName, Block& _block)\n{\n\tInlineModifier{*this, m_nameDispenser, _currentFunctionName, m_dialect}(_block);\n}\n\nbool FullInliner::recursive(FunctionDefinition const& _fun) const\n{\n\tstd::map<FunctionHandle, size_t> references = ReferencesCounter::countReferences(_fun);\n\treturn references[_fun.name] > 0;\n}\n\nvoid InlineModifier::operator()(Block& _block)\n{\n\tstd::function<std::optional<std::vector<Statement>>(Statement&)> f = [&](Statement& _statement) -> std::optional<std::vector<Statement>> {\n\t\tvisit(_statement);\n\t\treturn tryInlineStatement(_statement);\n\t};\n\tutil::iterateReplacing(_block.statements, f);\n}\n\nstd::optional<std::vector<Statement>> InlineModifier::tryInlineStatement(Statement& _statement)\n{\n\t// Only inline for expression statements, assignments and variable declarations.\n\tExpression* e = std::visit(util::GenericVisitor{\n\t\tutil::VisitorFallback<Expression*>{},\n\t\t[](ExpressionStatement& _s) { return &_s.expression; },\n\t\t[](Assignment& _s) { return _s.value.get(); },\n\t\t[](VariableDeclaration& _s) { return _s.value.get(); }\n\t}, _statement);\n\tif (e)\n\t{\n\t\t// Only inline direct function calls.\n\t\tFunctionCall* funCall = std::visit(util::GenericVisitor{\n\t\t\tutil::VisitorFallback<FunctionCall*>{},\n\t\t\t[](FunctionCall& _e) { return &_e; }\n\t\t}, *e);\n\t\tif (funCall && m_driver.shallInline(*funCall, m_currentFunction))\n\t\t\treturn performInline(_statement, *funCall);\n\t}\n\treturn {};\n}\n\nstd::vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionCall& _funCall)\n{\n\tstd::vector<Statement> newStatements;\n\tstd::map<YulName, YulName> variableReplacements;\n\n\tyulAssert(std::holds_alternative<Identifier>(_funCall.functionName));\n\tFunctionDefinition* function = m_driver.function(std::get<Identifier>(_funCall.functionName).name);\n\tassertThrow(!!function, OptimizerException, \"Attempt to inline invalid function.\");\n\n\tm_driver.tentativelyUpdateCodeSize(function->name, m_currentFunction);\n\n\t// helper function to create a new variable that is supposed to model\n\t// an existing variable.\n\tauto newVariable = [&](NameWithDebugData const& _existingVariable, Expression* _value) {\n\t\tYulName newName = m_nameDispenser.newName(_existingVariable.name);\n\t\tvariableReplacements[_existingVariable.name] = newName;\n\t\tVariableDeclaration varDecl{_funCall.debugData, {{_funCall.debugData, newName}}, {}};\n\t\tif (_value)\n\t\t\tvarDecl.value = std::make_unique<Expression>(std::move(*_value));\n\t\telse\n\t\t\tvarDecl.value = std::make_unique<Expression>(m_dialect.zeroLiteral());\n\t\tnewStatements.emplace_back(std::move(varDecl));\n\t};\n\n\tfor (auto&& [parameter, argument]: ranges::views::zip(function->parameters, _funCall.arguments) | ranges::views::reverse)\n\t\tnewVariable(parameter, &argument);\n\tfor (auto const& var: function->returnVariables)\n\t\tnewVariable(var, nullptr);\n\n\tStatement newBody = BodyCopier(m_nameDispenser, variableReplacements)(function->body);\n\tnewStatements += std::move(std::get<Block>(newBody).statements);\n\n\tstd::visit(util::GenericVisitor{\n\t\tutil::VisitorFallback<>{},\n\t\t[&](Assignment& _assignment)\n\t\t{\n\t\t\tfor (size_t i = 0; i < _assignment.variableNames.size(); ++i)\n\t\t\t\tnewStatements.emplace_back(Assignment{\n\t\t\t\t\t_assignment.debugData,\n\t\t\t\t\t{_assignment.variableNames[i]},\n\t\t\t\t\tstd::make_unique<Expression>(Identifier{\n\t\t\t\t\t\t_assignment.debugData,\n\t\t\t\t\t\tvariableReplacements.at(function->returnVariables[i].name)\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t},\n\t\t[&](VariableDeclaration& _varDecl)\n\t\t{\n\t\t\tfor (size_t i = 0; i < _varDecl.variables.size(); ++i)\n\t\t\t\tnewStatements.emplace_back(VariableDeclaration{\n\t\t\t\t\t_varDecl.debugData,\n\t\t\t\t\t{std::move(_varDecl.variables[i])},\n\t\t\t\t\tstd::make_unique<Expression>(Identifier{\n\t\t\t\t\t\t_varDecl.debugData,\n\t\t\t\t\t\tvariableReplacements.at(function->returnVariables[i].name)\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t}\n\t\t// nothing to be done for expression statement\n\t}, _statement);\n\treturn newStatements;\n}\n\nStatement BodyCopier::operator()(VariableDeclaration const& _varDecl)\n{\n\tfor (auto const& var: _varDecl.variables)\n\t\tm_variableReplacements[var.name] = m_nameDispenser.newName(var.name);\n\treturn ASTCopier::operator()(_varDecl);\n}\n\nStatement BodyCopier::operator()(FunctionDefinition const&)\n{\n\tassertThrow(false, OptimizerException, \"Function hoisting has to be done before function inlining.\");\n\treturn {};\n}\n\nYulName BodyCopier::translateIdentifier(YulName _name)\n{\n\treturn util::valueOrDefault(m_variableReplacements, _name, _name);\n}\n"
  },
  {
    "path": "libyul/optimiser/FullInliner.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that performs function inlining for arbitrary functions.\n */\n#pragma once\n\n#include <libyul/ASTForward.h>\n\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/NameDispenser.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/Exceptions.h>\n\n#include <liblangutil/SourceLocation.h>\n\n#include <optional>\n#include <set>\n#include <utility>\n\nnamespace solidity::yul\n{\n\nclass NameCollector;\n\n\n/**\n * Optimiser component that modifies an AST in place, inlining functions.\n * Expressions are expected to be split, i.e. the component will only inline\n * function calls that are at the root of the expression and that only contains\n * variables or literals as arguments. More specifically, it will inline\n *  - let x1, ..., xn := f(a1, ..., am)\n *  - x1, ..., xn := f(a1, ..., am)\n *  - f(a1, ..., am)\n *\n * The transform changes code of the form\n *\n * function f(a, b) -> c { ... }\n * let z := f(x, y)\n *\n * into\n *\n * function f(a, b) -> c { ... }\n *\n * let f_b := y\n * let f_a := x\n * let f_c\n * code of f, with replacements: a -> f_a, b -> f_b, c -> f_c\n * let z := f_c\n *\n * Prerequisites: Disambiguator\n * More efficient if run after: Function Hoister, Expression Splitter\n */\nclass FullInliner: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"FullInliner\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast);\n\n\t/// Inlining heuristic.\n\t/// @param _callSite the name of the function in which the function call is located.\n\tbool shallInline(FunctionCall const& _funCall, YulName _callSite);\n\n\tFunctionDefinition* function(YulName _name)\n\t{\n\t\tauto it = m_functions.find(_name);\n\t\tif (it != m_functions.end())\n\t\t\treturn it->second;\n\t\treturn nullptr;\n\t}\n\n\t/// Adds the size of _funCall to the size of _callSite. This is just\n\t/// a rough estimate that is done during inlining. The proper size\n\t/// should be determined after inlining is completed.\n\tvoid tentativelyUpdateCodeSize(YulName _function, YulName _callSite);\n\nprivate:\n\tenum Pass { InlineTiny, InlineRest };\n\n\tFullInliner(Block& _ast, NameDispenser& _dispenser, Dialect const& _dialect);\n\tvoid run(Pass _pass);\n\n\t/// @returns a map containing the maximum depths of a call chain starting at each\n\t/// function. For recursive functions, the value is one larger than for all others.\n\tstd::map<FunctionHandle, size_t> callDepths() const;\n\n\tvoid updateCodeSize(FunctionDefinition const& _fun);\n\tvoid handleBlock(YulName _currentFunctionName, Block& _block);\n\tbool recursive(FunctionDefinition const& _fun) const;\n\n\tPass m_pass;\n\t/// The AST to be modified. The root block itself will not be modified, because\n\t/// we store pointers to functions.\n\tBlock& m_ast;\n\tstd::map<YulName, FunctionDefinition*> m_functions;\n\t/// Functions not to be inlined (because they contain the ``leave`` statement).\n\tstd::set<YulName> m_noInlineFunctions;\n\t/// True, if the code contains a ``memoryguard`` and we can expect to be able to move variables to memory later.\n\tbool m_hasMemoryGuard = false;\n\t/// Set of recursive functions.\n\tstd::set<FunctionHandle> m_recursiveFunctions;\n\t/// Names of functions to always inline.\n\tstd::set<YulName> m_singleUse;\n\t/// Variables that are constants (used for inlining heuristic)\n\tstd::set<YulName> m_constants;\n\tstd::map<YulName, size_t> m_functionSizes;\n\tNameDispenser& m_nameDispenser;\n\tDialect const& m_dialect;\n};\n\n/**\n * Class that walks the AST of a block that does not contain function definitions and perform\n * the actual code modifications.\n */\nclass InlineModifier: public ASTModifier\n{\npublic:\n\tInlineModifier(FullInliner& _driver, NameDispenser& _nameDispenser, YulName _functionName, Dialect const& _dialect):\n\t\tm_currentFunction(std::move(_functionName)),\n\t\tm_driver(_driver),\n\t\tm_nameDispenser(_nameDispenser),\n\t\tm_dialect(_dialect)\n\t{ }\n\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\tstd::optional<std::vector<Statement>> tryInlineStatement(Statement& _statement);\n\tstd::vector<Statement> performInline(Statement& _statement, FunctionCall& _funCall);\n\n\tYulName m_currentFunction;\n\tFullInliner& m_driver;\n\tNameDispenser& m_nameDispenser;\n\tDialect const& m_dialect;\n};\n\n/**\n * Creates a copy of a block that is supposed to be the body of a function.\n * Applies replacements to referenced variables and creates new names for\n * variable declarations.\n */\nclass BodyCopier: public ASTCopier\n{\npublic:\n\tBodyCopier(\n\t\tNameDispenser& _nameDispenser,\n\t\tstd::map<YulName, YulName> _variableReplacements\n\t):\n\t\tm_nameDispenser(_nameDispenser),\n\t\tm_variableReplacements(std::move(_variableReplacements))\n\t{}\n\n\tusing ASTCopier::operator ();\n\n\tStatement operator()(VariableDeclaration const& _varDecl) override;\n\tStatement operator()(FunctionDefinition const& _funDef) override;\n\n\tYulName translateIdentifier(YulName _name) override;\n\n\tNameDispenser& m_nameDispenser;\n\tstd::map<YulName, YulName> m_variableReplacements;\n};\n\n\n}\n"
  },
  {
    "path": "libyul/optimiser/FunctionCallFinder.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <libyul/optimiser/FunctionCallFinder.h>\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nnamespace\n{\ntemplate<typename Base, typename ResultType>\nclass MaybeConstFunctionCallFinder: Base\n{\npublic:\n\tusing MaybeConstBlock = std::conditional_t<std::is_const_v<ResultType>, Block const, Block>;\n\tstatic std::vector<ResultType*> run(MaybeConstBlock& _block, FunctionHandle const& _functionHandle)\n\t{\n\t\tMaybeConstFunctionCallFinder functionCallFinder(_functionHandle);\n\t\tfunctionCallFinder(_block);\n\t\treturn functionCallFinder.m_calls;\n\t}\nprivate:\n\texplicit MaybeConstFunctionCallFinder(FunctionHandle const& _functionHandle):\n\t\tm_functionHandle(_functionHandle), m_calls() {}\n\n\tusing Base::operator();\n\tvoid operator()(ResultType& _functionCall) override\n\t{\n\t\tBase::operator()(_functionCall);\n\t\tif (functionNameToHandle(_functionCall.functionName) == m_functionHandle)\n\t\t\tm_calls.emplace_back(&_functionCall);\n\t}\n\tFunctionHandle const& m_functionHandle;\n\tstd::vector<ResultType*> m_calls;\n};\n}\n\nstd::vector<FunctionCall*> yul::findFunctionCalls(Block& _block, FunctionHandle const& _functionHandle)\n{\n\treturn MaybeConstFunctionCallFinder<ASTModifier, FunctionCall>::run(_block, _functionHandle);\n}\n\nstd::vector<FunctionCall const*> yul::findFunctionCalls(Block const& _block, FunctionHandle const& _functionHandle)\n{\n\treturn MaybeConstFunctionCallFinder<ASTWalker, FunctionCall const>::run(_block, _functionHandle);\n}\n"
  },
  {
    "path": "libyul/optimiser/FunctionCallFinder.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * AST walker that finds all calls to a function of a given name.\n */\n\n#pragma once\n\n#include <libyul/AST.h>\n\n#include <vector>\n\nnamespace solidity::yul\n{\n\n/**\n * Finds all calls to a function of a given name using an ASTModifier.\n *\n * Prerequisite: Disambiguator\n */\nstd::vector<FunctionCall*> findFunctionCalls(Block& _block, FunctionHandle const& _functionHandle);\n\n/**\n * Finds all calls to a function of a given name using an ASTWalker.\n *\n * Prerequisite: Disambiguator\n */\nstd::vector<FunctionCall const*> findFunctionCalls(Block const& _block, FunctionHandle const& _functionHandle);\n\n}\n"
  },
  {
    "path": "libyul/optimiser/FunctionGrouper.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that changes the code of a block so that all non-function definition\n * statements are moved to a block of their own followed by all function definitions.\n */\n\n#include <libyul/optimiser/FunctionGrouper.h>\n\n#include <libyul/AST.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\n\nvoid FunctionGrouper::operator()(Block& _block)\n{\n\tif (alreadyGrouped(_block))\n\t\treturn;\n\n\tstd::vector<Statement> reordered;\n\treordered.emplace_back(Block{_block.debugData, {}});\n\n\tfor (auto&& statement: _block.statements)\n\t{\n\t\tif (std::holds_alternative<FunctionDefinition>(statement))\n\t\t\treordered.emplace_back(std::move(statement));\n\t\telse\n\t\t\tstd::get<Block>(reordered.front()).statements.emplace_back(std::move(statement));\n\t}\n\t_block.statements = std::move(reordered);\n}\n\nbool FunctionGrouper::alreadyGrouped(Block const& _block)\n{\n\tif (_block.statements.empty())\n\t\treturn false;\n\tif (!std::holds_alternative<Block>(_block.statements.front()))\n\t\treturn false;\n\tfor (size_t i = 1; i < _block.statements.size(); ++i)\n\t\tif (!std::holds_alternative<FunctionDefinition>(_block.statements.at(i)))\n\t\t\treturn false;\n\treturn true;\n}\n"
  },
  {
    "path": "libyul/optimiser/FunctionGrouper.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that changes the code of a block so that all non-function definition\n * instructions are moved to a block of their own followed by all function definitions.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n\nnamespace solidity::yul\n{\n\nstruct OptimiserStepContext;\n\n/**\n * Moves all instructions in a block into a new block at the start of the block, followed by\n * all function definitions.\n *\n * After this step, a block is of the form\n * { { I... } F... }\n * Where I are (non-function-definition) instructions and F are function definitions.\n */\nclass FunctionGrouper\n{\npublic:\n\tstatic constexpr char const* name{\"FunctionGrouper\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast) { FunctionGrouper{}(_ast); }\n\n\tvoid operator()(Block& _block);\n\nprivate:\n\tFunctionGrouper() = default;\n\n\tbool alreadyGrouped(Block const& _block);\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/FunctionHoister.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that changes the code so that it consists of a block starting with\n * a single block followed only by function definitions and with no functions defined\n * anywhere else.\n */\n\n#include <libyul/optimiser/FunctionHoister.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/AST.h>\n\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nFunctionHoister::FunctionHoister() = default;\nFunctionHoister::~FunctionHoister() = default;\n\nvoid FunctionHoister::operator()(Block& _block)\n{\n\tbool topLevel = m_isTopLevel;\n\tm_isTopLevel = false;\n\tfor (auto&& statement: _block.statements)\n\t{\n\t\tstd::visit(*this, statement);\n\t\tif (std::holds_alternative<FunctionDefinition>(statement))\n\t\t{\n\t\t\tm_functions.emplace_back(std::move(statement));\n\t\t\tstatement = Block{_block.debugData, {}};\n\t\t}\n\t}\n\tremoveEmptyBlocks(_block);\n\tif (topLevel)\n\t\t_block.statements += std::move(m_functions);\n}\n"
  },
  {
    "path": "libyul/optimiser/FunctionHoister.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that changes the code so that all function definitions are at the top\n * level block.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/optimiser/ASTWalker.h>\n\nnamespace solidity::yul\n{\nstruct OptimiserStepContext;\n\n/**\n * Moves all functions to the top-level scope.\n * Applying this transformation to source code that has ambiguous identifiers might\n * lead to invalid code.\n *\n * Prerequisites: Disambiguator\n */\nclass FunctionHoister: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"FunctionHoister\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast) { FunctionHoister{}(_ast); }\n\n\tusing ASTModifier::operator();\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\tFunctionHoister();\n\t~FunctionHoister() override;\n\n\tbool m_isTopLevel = true;\n\tstd::vector<Statement> m_functions;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/FunctionSpecializer.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/optimiser/FunctionSpecializer.h>\n\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/NameDispenser.h>\n\n#include <libyul/AST.h>\n#include <libyul/YulName.h>\n#include <libsolutil/CommonData.h>\n\n#include <range/v3/algorithm/any_of.hpp>\n#include <range/v3/view/enumerate.hpp>\n\n#include <variant>\n\nusing namespace solidity::util;\nusing namespace solidity::yul;\n\nFunctionSpecializer::LiteralArguments FunctionSpecializer::specializableArguments(\n\tFunctionCall const& _f\n)\n{\n\tauto heuristic = [&](Expression const& _e) -> std::optional<Expression>\n\t{\n\t\tif (std::holds_alternative<Literal>(_e))\n\t\t\treturn ASTCopier{}.translate(_e);\n\t\treturn std::nullopt;\n\t};\n\n\treturn applyMap(_f.arguments, heuristic);\n}\n\nvoid FunctionSpecializer::operator()(FunctionCall& _f)\n{\n\tASTModifier::operator()(_f);\n\n\t// TODO When backtracking is implemented, the restriction of recursive functions can be lifted.\n\tif (\n\t\tisBuiltinFunctionCall(_f) ||\n\t\t(std::holds_alternative<Identifier>(_f.functionName) && m_recursiveFunctions.count(std::get<Identifier>(_f.functionName).name))\n\t)\n\t\treturn;\n\tyulAssert(std::holds_alternative<Identifier>(_f.functionName));\n\tauto& identifier = std::get<Identifier>(_f.functionName);\n\n\tLiteralArguments arguments = specializableArguments(_f);\n\n\tif (ranges::any_of(arguments, [](auto& _a) { return _a.has_value(); }))\n\t{\n\t\tYulName oldName = std::move(identifier.name);\n\t\tauto newName = m_nameDispenser.newName(oldName);\n\n\t\tm_oldToNewMap[oldName].emplace_back(std::make_pair(newName, arguments));\n\n\t\tidentifier.name = newName;\n\t\t_f.arguments = util::filter(\n\t\t\t_f.arguments,\n\t\t\tapplyMap(arguments, [](auto& _a) { return !_a; })\n\t\t);\n\t}\n}\n\nFunctionDefinition FunctionSpecializer::specialize(\n\tFunctionDefinition const& _f,\n\tYulName _newName,\n\tFunctionSpecializer::LiteralArguments _arguments\n)\n{\n\tyulAssert(_arguments.size() == _f.parameters.size(), \"\");\n\n\tstd::map<YulName, YulName> translatedNames = applyMap(\n\t\tNameCollector{_f, NameCollector::OnlyVariables}.names(),\n\t\t[&](auto& _name) -> std::pair<YulName, YulName>\n\t\t{\n\t\t\treturn std::make_pair(_name, m_nameDispenser.newName(_name));\n\t\t},\n\t\tstd::map<YulName, YulName>{}\n\t);\n\n\tFunctionDefinition newFunction = std::get<FunctionDefinition>(FunctionCopier{translatedNames}(_f));\n\n\t// Function parameters that will be specialized inside the body are converted into variable\n\t// declarations.\n\tstd::vector<Statement> missingVariableDeclarations;\n\tfor (auto&& [index, argument]: _arguments | ranges::views::enumerate)\n\t\tif (argument)\n\t\t\tmissingVariableDeclarations.emplace_back(\n\t\t\t\tVariableDeclaration{\n\t\t\t\t\t_f.debugData,\n\t\t\t\t\tstd::vector<NameWithDebugData>{newFunction.parameters[index]},\n\t\t\t\t\tstd::make_unique<Expression>(std::move(*argument))\n\t\t\t\t}\n\t\t\t);\n\n\tnewFunction.body.statements =\n\t\tstd::move(missingVariableDeclarations) + std::move(newFunction.body.statements);\n\n\t// Only take those indices that cannot be specialized, i.e., whose value is `nullopt`.\n\tnewFunction.parameters =\n\t\tutil::filter(\n\t\t\tnewFunction.parameters,\n\t\t\tapplyMap(_arguments, [&](auto const& _v) { return !_v; })\n\t\t);\n\n\tnewFunction.name = std::move(_newName);\n\n\treturn newFunction;\n}\n\nvoid FunctionSpecializer::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tFunctionSpecializer f{\n\t\tCallGraphGenerator::callGraph(_ast).recursiveFunctions(),\n\t\t_context.dispenser\n\t};\n\tf(_ast);\n\n\titerateReplacing(_ast.statements, [&](Statement& _s) -> std::optional<std::vector<Statement>>\n\t{\n\t\tif (std::holds_alternative<FunctionDefinition>(_s))\n\t\t{\n\t\t\tauto& functionDefinition = std::get<FunctionDefinition>(_s);\n\n\t\t\tif (f.m_oldToNewMap.count(functionDefinition.name))\n\t\t\t{\n\t\t\t\tstd::vector<Statement> out = applyMap(\n\t\t\t\t\tf.m_oldToNewMap.at(functionDefinition.name),\n\t\t\t\t\t[&](auto& _p) -> Statement\n\t\t\t\t\t{\n\t\t\t\t\t\treturn f.specialize(functionDefinition, std::move(_p.first), std::move(_p.second));\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\treturn std::move(out) + make_vector<Statement>(std::move(functionDefinition));\n\t\t\t}\n\t\t}\n\n\t\treturn std::nullopt;\n\t});\n}\n"
  },
  {
    "path": "libyul/optimiser/FunctionSpecializer.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/NameDispenser.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\n#include <libyul/AST.h>\n\n#include <map>\n#include <optional>\n#include <vector>\n\nnamespace solidity::yul\n{\n\n/**\n * FunctionSpecializer: Optimiser step that specializes the function with its literal arguments.\n *\n * If a function, say, `function f(a, b) { sstore (a, b)}`, is called with literal arguments, for\n * example, `f(x, 5)`, where `x` is an identifier, it could be specialized by creating a new\n * function `f_1` that takes only one argument, i.e.,\n *\n *   function f_1(a_1) {\n *     let b_1 := 5\n *     sstore(a_1, b_1)\n *   }\n *\n * Other optimization steps will be able to make more simplifications to the function. The\n * optimization step is mainly useful for functions that would not be inlined.\n *\n * Prerequisites: Disambiguator, FunctionHoister\n *\n * LiteralRematerialiser is recommended as a prerequisite, even though it's not required for\n * correctness.\n */\nclass FunctionSpecializer: public ASTModifier\n{\npublic:\n\t/// A vector of function-call arguments. An element 'has value' if it's a literal, and the\n\t/// corresponding Expression would be the literal.\n\tusing LiteralArguments = std::vector<std::optional<Expression>>;\n\n\tstatic constexpr char const* name{\"FunctionSpecializer\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(FunctionCall& _f) override;\n\nprivate:\n\texplicit FunctionSpecializer(\n\t\tstd::set<FunctionHandle> _recursiveFunctions,\n\t\tNameDispenser& _nameDispenser\n\t):\n\t\tm_recursiveFunctions(std::move(_recursiveFunctions)),\n\t\tm_nameDispenser(_nameDispenser)\n\t{}\n\t/// Returns a vector of Expressions, where the index `i` is an expression if the function's\n\t/// `i`-th argument can be specialized, nullopt otherwise.\n\tLiteralArguments specializableArguments(FunctionCall const& _f);\n\t/// Given a function definition `_f` and its arguments `_arguments`, of which, at least one is a\n\t/// literal, this function returns a new function with the literal arguments specialized.\n\t///\n\t/// Note that the returned function definition will have new (and unique) names, for both the\n\t/// function and variable declarations to retain the properties enforced by the Disambiguator.\n\t///\n\t/// For example, if `_f` is the function `function f(a, b, c) -> d { sstore(a, b) }`,\n\t/// `_arguments` is the vector of literals `{1, 2, nullopt}` and the @param, `_newName` has\n\t/// value `f_1`, the returned function could be:\n\t///\n\t///   function f_1(c_2) -> d_3 {\n\t///     let a_4 := 1\n\t///     let b_5 := 2\n\t///     sstore(a_4, b_5)\n\t///   }\n\t///\n\tFunctionDefinition specialize(\n\t\tFunctionDefinition const& _f,\n\t\tYulName _newName,\n\t\tFunctionSpecializer::LiteralArguments _arguments\n\t);\n\n\t/// A mapping between the old function name and a pair of new function name and its arguments.\n\t/// Note that at least one of the argument will have a literal value.\n\tstd::map<YulName, std::vector<std::pair<YulName, LiteralArguments>>> m_oldToNewMap;\n\t/// We skip specializing recursive functions. Need backtracking to properly deal with them.\n\tstd::set<FunctionHandle> const m_recursiveFunctions;\n\n\tNameDispenser& m_nameDispenser;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/InlinableExpressionFunctionFinder.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that identifies functions to be inlined.\n */\n\n#include <libyul/optimiser/InlinableExpressionFunctionFinder.h>\n\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/AST.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid InlinableExpressionFunctionFinder::operator()(Identifier const& _identifier)\n{\n\tcheckAllowed(_identifier);\n\tASTWalker::operator()(_identifier);\n}\n\nvoid InlinableExpressionFunctionFinder::operator()(FunctionCall const& _funCall)\n{\n\tcheckAllowed(_funCall.functionName);\n\tASTWalker::operator()(_funCall);\n}\n\nvoid InlinableExpressionFunctionFinder::operator()(FunctionDefinition const& _function)\n{\n\tif (_function.returnVariables.size() == 1 && _function.body.statements.size() == 1)\n\t{\n\t\tYulName retVariable = _function.returnVariables.front().name;\n\t\tStatement const& bodyStatement = _function.body.statements.front();\n\t\tif (std::holds_alternative<Assignment>(bodyStatement))\n\t\t{\n\t\t\tAssignment const& assignment = std::get<Assignment>(bodyStatement);\n\t\t\tif (assignment.variableNames.size() == 1 && assignment.variableNames.front().name == retVariable)\n\t\t\t{\n\t\t\t\t// TODO: use code size metric here\n\n\t\t\t\t// We cannot overwrite previous settings, because this function definition\n\t\t\t\t// would not be valid here if we were searching inside a functionally inlinable\n\t\t\t\t// function body.\n\t\t\t\tassertThrow(m_disallowedIdentifiers.empty() && !m_foundDisallowedIdentifier, OptimizerException, \"\");\n\t\t\t\tm_disallowedIdentifiers = std::set<YulName>{retVariable, _function.name};\n\t\t\t\tstd::visit(*this, *assignment.value);\n\t\t\t\tif (!m_foundDisallowedIdentifier)\n\t\t\t\t\tm_inlinableFunctions[_function.name] = &_function;\n\t\t\t\tm_disallowedIdentifiers.clear();\n\t\t\t\tm_foundDisallowedIdentifier = false;\n\t\t\t}\n\t\t}\n\t}\n\tASTWalker::operator()(_function.body);\n}\nvoid InlinableExpressionFunctionFinder::checkAllowed(FunctionName const& _name)\n{\n\t// disallowed function names can only ever be user-defined `yul::Identifier`s, not builtins\n\tif (std::holds_alternative<Identifier>(_name) && m_disallowedIdentifiers.count(std::get<Identifier>(_name).name) != 0)\n\t\tm_foundDisallowedIdentifier = true;\n}\n"
  },
  {
    "path": "libyul/optimiser/InlinableExpressionFunctionFinder.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that identifies functions to be inlined.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/optimiser/ASTWalker.h>\n\n#include <set>\n\nnamespace solidity::yul\n{\n\n/**\n * Optimiser component that finds functions that can be\n * inlined inside functional expressions, i.e. functions that\n *  - have a single return parameter r\n *  - have a body like r := <functional expression>\n *  - neither reference themselves nor r in the right hand side\n *\n * This component can only be used on sources with unique names.\n */\nclass InlinableExpressionFunctionFinder: public ASTWalker\n{\npublic:\n\n\tstd::map<YulName, FunctionDefinition const*> const& inlinableFunctions() const\n\t{\n\t\treturn m_inlinableFunctions;\n\t}\n\n\tusing ASTWalker::operator();\n\tvoid operator()(Identifier const& _identifier) override;\n\tvoid operator()(FunctionCall const& _funCall) override;\n\tvoid operator()(FunctionDefinition const& _function) override;\n\nprivate:\n\tvoid checkAllowed(FunctionName const& _name);\n\n\tbool m_foundDisallowedIdentifier = false;\n\tstd::set<YulName> m_disallowedIdentifiers;\n\tstd::map<YulName, FunctionDefinition const*> m_inlinableFunctions;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/KnowledgeBase.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Class that can answer questions about values of variables and their relations.\n */\n\n#include <libyul/optimiser/KnowledgeBase.h>\n\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n#include <libyul/optimiser/DataFlowAnalyzer.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <variant>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nKnowledgeBase::KnowledgeBase(std::map<YulName, AssignedValue> const& _ssaValues, Dialect const& _dialect):\n\tm_valuesAreSSA(true),\n\tm_variableValues([_ssaValues](YulName _var) { return util::valueOrNullptr(_ssaValues, _var); }),\n\tm_addBuiltinHandle(_dialect.findBuiltin(\"add\")),\n\tm_subBuiltinHandle(_dialect.findBuiltin(\"sub\"))\n{}\n\nbool KnowledgeBase::knownToBeDifferent(YulName _a, YulName _b)\n{\n\tif (std::optional<u256> difference = differenceIfKnownConstant(_a, _b))\n\t\treturn difference != 0;\n\treturn false;\n}\n\nstd::optional<u256> KnowledgeBase::differenceIfKnownConstant(YulName _a, YulName _b)\n{\n\tVariableOffset offA = explore(_a);\n\tVariableOffset offB = explore(_b);\n\tif (offA.reference == offB.reference)\n\t\treturn offA.offset - offB.offset;\n\telse\n\t\treturn std::nullopt;\n}\n\n\nbool KnowledgeBase::knownToBeDifferentByAtLeast32(YulName _a, YulName _b)\n{\n\tif (std::optional<u256> difference = differenceIfKnownConstant(_a, _b))\n\t\treturn difference >= 32 && difference <= u256(0) - 32;\n\n\treturn false;\n}\n\nbool KnowledgeBase::knownToBeZero(YulName _a)\n{\n\treturn valueIfKnownConstant(_a) == 0;\n}\n\nstd::optional<u256> KnowledgeBase::valueIfKnownConstant(YulName _a)\n{\n\treturn explore(_a).absoluteValue();\n}\n\nstd::optional<u256> KnowledgeBase::valueIfKnownConstant(Expression const& _expression)\n{\n\tif (Identifier const* ident = std::get_if<Identifier>(&_expression))\n\t\treturn valueIfKnownConstant(ident->name);\n\telse if (Literal const* lit = std::get_if<Literal>(&_expression))\n\t\treturn lit->value.value();\n\telse\n\t\treturn std::nullopt;\n}\n\nKnowledgeBase::VariableOffset KnowledgeBase::explore(YulName _var)\n{\n\tExpression const* value = nullptr;\n\tif (m_valuesAreSSA)\n\t{\n\t\t// In SSA, a once determined offset is always valid, so we first see\n\t\t// if we already computed it.\n\t\tif (VariableOffset const* varOff = util::valueOrNullptr(m_offsets, _var))\n\t\t\treturn *varOff;\n\t\tvalue = valueOf(_var);\n\t}\n\telse\n\t{\n\t\t// For non-SSA, we query the value first so that the variable is reset if it has changed\n\t\t// since the last call.\n\t\tvalue = valueOf(_var);\n\t\tif (VariableOffset const* varOff = util::valueOrNullptr(m_offsets, _var))\n\t\t\treturn *varOff;\n\t}\n\n\tif (value)\n\t\tif (std::optional<VariableOffset> offset = explore(*value))\n\t\t\treturn setOffset(_var, *offset);\n\treturn setOffset(_var, VariableOffset{_var, 0});\n\n}\n\nstd::optional<KnowledgeBase::VariableOffset> KnowledgeBase::explore(Expression const& _value)\n{\n\tif (Literal const* literal = std::get_if<Literal>(&_value))\n\t\treturn VariableOffset{YulName{}, literal->value.value()};\n\telse if (Identifier const* identifier = std::get_if<Identifier>(&_value))\n\t\treturn explore(identifier->name);\n\telse if (\n\t\tFunctionCall const* f = std::get_if<FunctionCall>(&_value);\n\t\tf && isBuiltinFunctionCall(*f)\n\t)\n\t{\n\t\tif (std::get<BuiltinName>(f->functionName).handle == m_addBuiltinHandle)\n\t\t{\n\t\t\tif (std::optional<VariableOffset> a = explore(f->arguments[0]))\n\t\t\t\tif (std::optional<VariableOffset> b = explore(f->arguments[1]))\n\t\t\t\t{\n\t\t\t\t\tu256 offset = a->offset + b->offset;\n\t\t\t\t\tif (a->isAbsolute())\n\t\t\t\t\t\t// a is constant\n\t\t\t\t\t\treturn VariableOffset{b->reference, offset};\n\t\t\t\t\telse if (b->isAbsolute())\n\t\t\t\t\t\t// b is constant\n\t\t\t\t\t\treturn VariableOffset{a->reference, offset};\n\t\t\t\t}\n\t\t}\n\t\telse if (std::get<BuiltinName>(f->functionName).handle == m_subBuiltinHandle)\n\t\t\tif (std::optional<VariableOffset> a = explore(f->arguments[0]))\n\t\t\t\tif (std::optional<VariableOffset> b = explore(f->arguments[1]))\n\t\t\t\t{\n\t\t\t\t\tu256 offset = a->offset - b->offset;\n\t\t\t\t\tif (a->reference == b->reference)\n\t\t\t\t\t\treturn VariableOffset{YulName{}, offset};\n\t\t\t\t\telse if (b->isAbsolute())\n\t\t\t\t\t\t// b is constant\n\t\t\t\t\t\treturn VariableOffset{a->reference, offset};\n\t\t\t\t}\n\t}\n\n\treturn std::nullopt;\n}\n\nExpression const* KnowledgeBase::valueOf(YulName _var)\n{\n\tAssignedValue const* assignedValue = m_variableValues(_var);\n\tExpression const* currentValue = assignedValue ? assignedValue->value : nullptr;\n\tif (m_valuesAreSSA)\n\t\treturn currentValue;\n\n\tExpression const* lastValue = m_lastKnownValue[_var];\n\tif (lastValue != currentValue)\n\t\treset(_var);\n\tm_lastKnownValue[_var] = currentValue;\n\treturn currentValue;\n}\n\nvoid KnowledgeBase::reset(YulName _var)\n{\n\tyulAssert(!m_valuesAreSSA);\n\n\tm_lastKnownValue.erase(_var);\n\tif (VariableOffset const* offset = util::valueOrNullptr(m_offsets, _var))\n\t{\n\t\t// Remove var from its group\n\t\tif (!offset->isAbsolute())\n\t\t\tm_groupMembers[offset->reference].erase(_var);\n\t\tm_offsets.erase(_var);\n\t}\n\tif (std::set<YulName>* group = util::valueOrNullptr(m_groupMembers, _var))\n\t{\n\t\t// _var was a representative, we might have to find a new one.\n\t\tif (!group->empty())\n\t\t{\n\t\t\tYulName newRepresentative = *group->begin();\n\t\t\tyulAssert(newRepresentative != _var);\n\t\t\tu256 newOffset = m_offsets[newRepresentative].offset;\n\t\t\t// newOffset = newRepresentative - _var\n\t\t\tfor (YulName groupMember: *group)\n\t\t\t{\n\t\t\t\tyulAssert(m_offsets[groupMember].reference == _var);\n\t\t\t\tm_offsets[groupMember].reference = newRepresentative;\n\t\t\t\t// groupMember = _var + m_offsets[groupMember].offset (old)\n\t\t\t\t//             = newRepresentative - newOffset + m_offsets[groupMember].offset (old)\n\t\t\t\t// so subtracting newOffset from .offset yields the original relation again,\n\t\t\t\t// just with _var replaced by newRepresentative\n\t\t\t\tm_offsets[groupMember].offset -= newOffset;\n\t\t\t}\n\t\t\tm_groupMembers[newRepresentative] = std::move(*group);\n\n\t\t}\n\t\tm_groupMembers.erase(_var);\n\t}\n}\n\nKnowledgeBase::VariableOffset KnowledgeBase::setOffset(YulName _variable, VariableOffset _value)\n{\n\tm_offsets[_variable] = _value;\n\t// Constants are not tracked in m_groupMembers because\n\t// the \"representative\" can never be reset.\n\tif (!_value.reference.empty())\n\t\tm_groupMembers[_value.reference].insert(_variable);\n\treturn _value;\n}\n"
  },
  {
    "path": "libyul/optimiser/KnowledgeBase.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Class that can answer questions about values of variables and their relations.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/Dialect.h>\n#include <libyul/YulName.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/Numeric.h>\n\n#include <map>\n#include <functional>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\nstruct AssignedValue;\n\n/**\n * Class that can answer questions about values of variables and their relations.\n *\n * Requires a callback that returns the current value of the variable.\n * The value can change any time during the lifetime of the KnowledgeBase,\n * it will update its internal data structure accordingly.\n *\n * This means that the code the KnowledgeBase is used on does not need to be in SSA\n * form.\n * The only requirement is that the assigned values are movable expressions.\n *\n * There is a constructor to provide all SSA values right at the beginning.\n * If you use this, the KnowledgeBase will be slightly more efficient.\n *\n * Internally, tries to find groups of variables that have a mutual constant\n * difference and stores these differences always relative to a specific\n * representative variable of the group.\n *\n * There is a special group which is the constant values. Those use the\n * empty YulName as representative \"variable\".\n */\nclass KnowledgeBase\n{\npublic:\n\t/// Constructor for arbitrary value callback that allows for variable values\n\t/// to change in between calls to functions of this class.\n\texplicit KnowledgeBase(std::function<AssignedValue const*(YulName)> _variableValues, Dialect const& _dialect):\n\t\tm_variableValues(std::move(_variableValues)),\n\t\tm_addBuiltinHandle(_dialect.findBuiltin(\"add\")),\n\t\tm_subBuiltinHandle(_dialect.findBuiltin(\"sub\"))\n\t{}\n\t/// Constructor to use if source code is in SSA form and values are constant.\n\texplicit KnowledgeBase(std::map<YulName, AssignedValue> const& _ssaValues, Dialect const& _dialect);\n\n\tbool knownToBeDifferent(YulName _a, YulName _b);\n\tstd::optional<u256> differenceIfKnownConstant(YulName _a, YulName _b);\n\tbool knownToBeDifferentByAtLeast32(YulName _a, YulName _b);\n\tbool knownToBeZero(YulName _a);\n\tstd::optional<u256> valueIfKnownConstant(YulName _a);\n\tstd::optional<u256> valueIfKnownConstant(Expression const& _expression);\n\nprivate:\n\t/**\n\t * Constant offset relative to a reference variable, or absolute constant if the\n\t * reference variable is the empty YulName.\n\t */\n\tstruct VariableOffset\n\t{\n\t\tYulName reference;\n\t\tu256 offset;\n\n\t\tbool isAbsolute() const\n\t\t{\n\t\t\treturn reference.empty();\n\t\t}\n\n\t\tstd::optional<u256> absoluteValue() const\n\t\t{\n\t\t\tif (isAbsolute())\n\t\t\t\treturn offset;\n\t\t\telse\n\t\t\t\treturn std::nullopt;\n\t\t}\n\t};\n\n\tVariableOffset explore(YulName _var);\n\tstd::optional<VariableOffset> explore(Expression const& _value);\n\n\t/// Retrieves the current value of a variable and potentially resets the variable if it is not up to date.\n\tExpression const* valueOf(YulName _var);\n\n\t/// Resets all information about the variable and removes it from its group,\n\t/// potentially finding a new representative.\n\tvoid reset(YulName _var);\n\n\tVariableOffset setOffset(YulName _variable, VariableOffset _value);\n\n\t/// If true, we can assume that variable values never change and skip some steps.\n\tbool m_valuesAreSSA = false;\n\t/// Callback to retrieve the current value of a variable.\n\tstd::function<AssignedValue const*(YulName)> m_variableValues;\n\tstd::optional<BuiltinHandle> m_addBuiltinHandle;\n\tstd::optional<BuiltinHandle> m_subBuiltinHandle;\n\n\t/// Offsets for each variable to one representative per group.\n\t/// The empty string is the representative of the constant value zero.\n\tstd::map<YulName, VariableOffset> m_offsets;\n\t/// Last known value of each variable we queried.\n\tstd::map<YulName, Expression const*> m_lastKnownValue;\n\t/// For each representative, variables that use it to offset from.\n\tstd::map<YulName, std::set<YulName>> m_groupMembers;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/LabelIDDispenser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/optimiser/LabelIDDispenser.h>\n\n#include <libyul/optimiser/OptimizerUtilities.h>\n\n#include <fmt/compile.h>\n\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/filter.hpp>\n#include <range/v3/view/iota.hpp>\n\nusing namespace solidity::yul;\n\nnamespace\n{\nbool isInvalidLabel(\n\tstd::string_view const _label,\n\tstd::set<std::string, std::less<>> const& _reservedLabels,\n\tDialect const& _dialect\n)\n{\n\treturn isRestrictedIdentifier(_dialect, _label) || _reservedLabels.contains(_label);\n}\n}\n\nLabelIDDispenser::LabelIDDispenser(ASTLabelRegistry const& _labels, std::set<std::string> const& _reservedLabels):\n\tm_labels(_labels),\n\tm_reservedLabels(_reservedLabels.begin(), _reservedLabels.end())\n{}\n\nLabelIDDispenser::LabelID LabelIDDispenser::newID(LabelID const _parent)\n{\n\tauto const parentLabelID = resolveParentLabelID(_parent);\n\tyulAssert(!m_labels.ghost(parentLabelID), \"Use newGhost to add new ghosts.\");\n\tm_idToLabelMapping.push_back(parentLabelID);\n\treturn m_idToLabelMapping.size() + m_labels.maxID();\n}\n\nLabelIDDispenser::LabelID LabelIDDispenser::newGhost()\n{\n\tm_idToLabelMapping.push_back(ASTLabelRegistry::ghostLabelIndex());\n\treturn m_idToLabelMapping.size() + m_labels.maxID();\n}\n\nLabelIDDispenser::LabelID LabelIDDispenser::resolveParentLabelID(LabelID _id) const\n{\n\tyulAssert(_id < m_idToLabelMapping.size() + m_labels.maxID() + 1, \"ID exceeds bounds.\");\n\t// bigger than maxID means that the input label id was spawned by this dispenser\n\tif (_id > m_labels.maxID())\n\t\t_id = m_idToLabelMapping[_id - m_labels.maxID() - 1];\n\tyulAssert(\n\t\t_id <= m_labels.maxID() && !m_labels.unused(_id),\n\t\t\"We can have at most one level of indirection and the derived-from label cannot be unused.\"\n\t);\n\treturn _id;\n}\n\nbool LabelIDDispenser::ghost(LabelID const _id) const\n{\n\tyulAssert(_id < m_idToLabelMapping.size() + m_labels.maxID() + 1, \"ID exceeds bounds.\");\n\tif (_id > m_labels.maxID())\n\t\treturn m_idToLabelMapping[_id - m_labels.maxID() - 1] == ASTLabelRegistry::ghostLabelIndex();\n\n\treturn m_labels.ghost(_id);\n}\n\nASTLabelRegistry LabelIDDispenser::generateNewLabels(Dialect const& _dialect) const\n{\n\tauto const usedIDs =\n\t\tranges::views::iota(static_cast<size_t>(1), m_idToLabelMapping.size() + m_labels.maxID() + 1) |\n\t\tranges::to<std::set>;\n\treturn generateNewLabels(usedIDs, _dialect);\n}\n\nASTLabelRegistry LabelIDDispenser::generateNewLabels(std::set<LabelID> const& _usedIDs, Dialect const& _dialect) const\n{\n\tif (_usedIDs.empty())\n\t\treturn {};\n\n\tauto const& originalLabels = m_labels.labels();\n\n\tstd::vector<uint8_t> reusedLabels (originalLabels.size());\n\t// this means that everything that is derived from empty needs to be generated\n\treusedLabels[0] = true;\n\n\t// start with the empty label\n\tstd::vector<std::string> labels{\"\"};\n\tlabels.reserve(originalLabels.size()+1);\n\n\t// 0 maps to \"\"\n\tyulAssert(!_usedIDs.empty());\n\tstd::vector<size_t> idToLabelMap (*std::prev(_usedIDs.end()) + 1);\n\n\tstd::set<std::string, std::less<>> alreadyDefinedLabels = m_reservedLabels;\n\n\t// we record which labels have to be newly generated, some we can just take over from the existing registry\n\tstd::vector<LabelID> toGenerate;\n\tfor (auto const& id: _usedIDs)\n\t{\n\t\tif (ghost(id))\n\t\t{\n\t\t\tidToLabelMap[id] = ASTLabelRegistry::ghostLabelIndex();\n\t\t\tcontinue;\n\t\t}\n\n\t\tauto const parentLabelID = resolveParentLabelID(id);\n\n\t\tauto const originalLabelIndex = m_labels.idToLabelIndex(parentLabelID);\n\t\tstd::string const& originalLabel = originalLabels[originalLabelIndex];\n\n\t\t// It is important that the used ids are in ascending order to ensure that ids which occur in the provided AST\n\t\t// and have unchanged IDs will have their labels reused first, before anything derived from it gets assigned\n\t\t// said label.\n\t\tstatic_assert(std::is_same_v<std::decay_t<decltype(_usedIDs)>, std::set<LabelID>>);\n\n\t\t// if we haven't already reused the label, check that either the id didn't change, then we can just\n\t\t// take over the old label, otherwise check that it is a valid label and then reuse\n\t\tif (!reusedLabels[originalLabelIndex] && (parentLabelID == id || !isInvalidLabel(originalLabel, m_reservedLabels, _dialect)))\n\t\t{\n\t\t\tlabels.push_back(originalLabel);\n\t\t\tidToLabelMap[id] = labels.size() - 1;\n\t\t\talreadyDefinedLabels.insert(originalLabel);\n\t\t\treusedLabels[originalLabelIndex] = true;\n\t\t}\n\t\telse\n\t\t\ttoGenerate.push_back(id);\n\t}\n\n\tstd::vector<size_t> labelSuffixes(m_labels.maxID() + 1, 1);\n\tfor (auto const& id: toGenerate)\n\t{\n\t\tyulAssert(!ghost(id));\n\n\t\tauto const parentLabelID = resolveParentLabelID(id);\n\t\tauto const parentLabelIndex = m_labels.idToLabelIndex(parentLabelID);\n\t\tauto const& parentLabel = originalLabels[parentLabelIndex];\n\n\t\tstd::string generatedLabel = parentLabel;\n\t\tdo\n\t\t{\n\t\t\tgeneratedLabel = format(FMT_COMPILE(\"{}_{}\"), parentLabel, labelSuffixes[parentLabelID]++);\n\t\t} while (isInvalidLabel(generatedLabel, alreadyDefinedLabels, _dialect));\n\n\t\tlabels.push_back(generatedLabel);\n\t\tidToLabelMap[id] = labels.size() - 1;\n\t\talreadyDefinedLabels.insert(generatedLabel);\n\t}\n\n\treturn ASTLabelRegistry{std::move(labels), std::move(idToLabelMap)};\n}\n"
  },
  {
    "path": "libyul/optimiser/LabelIDDispenser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/ASTLabelRegistry.h>\n\n#include <functional>\n#include <set>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\n\n/// Can spawn new `LabelID`s which depend on `LabelID`s from a parent label registry. Once generation is completed,\n/// a new `ASTLabelRegistry` can be generated based on the used subset of spawned and original IDs.\nclass LabelIDDispenser\n{\npublic:\n\tusing LabelID = ASTLabelRegistry::LabelID;\n\t/// A set of reserved labels may be provided, which is excluded when generating new labels. If a reserved label\n\t/// already appears in the label registry and is used as-is in the AST, it will be reused despite it being\n\t/// provided here.\n\t/// Original labels will always be preserved even if they are not valid Yul identifiers.\n\texplicit LabelIDDispenser(\n\t\tASTLabelRegistry const& _labels,\n\t\tstd::set<std::string> const& _reserved = {}\n\t);\n\n\tASTLabelRegistry const& labels() const { return m_labels; }\n\n\t/// Spawns a new LabelID which depends on a parent LabelID that will be used for its string representation.\n\t/// Parent must not be unused. For spawning new ghost labels, `newGhost` must be used.\n\tLabelID newID(LabelID _parent = 0);\n\t/// Spawns a new ghost label.\n\tLabelID newGhost();\n\n\t/// Creates a new label registry based on the added labels.\n\t/// Ghost IDs are always preserved, as these are not referenced in the AST.\n\t/// Labels are guaranteed to be valid and not reserved if and only if they were valid and not reserved in the\n\t/// original registry. No new invalid and/or reserved labels are introduced.\n\tASTLabelRegistry generateNewLabels(std::set<LabelID> const& _usedIDs, Dialect const& _dialect) const;\n\tASTLabelRegistry generateNewLabels(Dialect const& _dialect) const;\nprivate:\n\t/// For newly added label IDs, this yields the parent ID which is contained in the provided registry.\n\t/// For label IDs which already are not new, this function is the identity.\n\tLabelID resolveParentLabelID(LabelID _id) const;\n\tbool ghost(LabelID _id) const;\n\n\tASTLabelRegistry const& m_labels;\n\t/// Reserved labels, equipped with the transparent less comparison operator to be able to handle string_view.\n\tstd::set<std::string, std::less<>> m_reservedLabels;\n\t/// Contains references to parent label IDs. Indices are new IDs offset by `m_labels.maxID() + 1`.\n\tstd::vector<LabelID> m_idToLabelMapping;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/LoadResolver.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that replaces expressions of type ``sload(x)`` by the value\n * currently stored in storage, if known.\n */\n\n#include <libyul/optimiser/LoadResolver.h>\n\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/backends/evm/EVMMetrics.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/SideEffects.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n\n#include <libevmasm/GasMeter.h>\n#include <libsolutil/Keccak256.h>\n\n#include <limits>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::evmasm;\nusing namespace solidity::yul;\n\nvoid LoadResolver::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tbool containsMSize = MSizeFinder::containsMSize(_context.dialect, _ast);\n\tLoadResolver{\n\t\t_context.dialect,\n\t\tSideEffectsPropagator::sideEffects(_context.dialect, CallGraphGenerator::callGraph(_ast)),\n\t\tcontainsMSize,\n\t\t_context.expectedExecutionsPerDeployment\n\t}(_ast);\n}\n\nvoid LoadResolver::visit(Expression& _e)\n{\n\tDataFlowAnalyzer::visit(_e);\n\n\tif (\n\t\tFunctionCall const* funCall = std::get_if<FunctionCall>(&_e);\n\t\tfunCall && std::holds_alternative<BuiltinName>(funCall->functionName)\n\t)\n\t{\n\t\tauto const& builtinHandle = std::get<BuiltinName>(funCall->functionName).handle;\n\t\tif (builtinHandle == m_loadFunctionName[static_cast<unsigned>(StoreLoadLocation::Memory)])\n\t\t\ttryResolve(_e, StoreLoadLocation::Memory, funCall->arguments);\n\t\telse if (builtinHandle == m_loadFunctionName[static_cast<unsigned>(StoreLoadLocation::Storage)])\n\t\t\ttryResolve(_e, StoreLoadLocation::Storage, funCall->arguments);\n\t\telse if (!m_containsMSize && builtinHandle == m_dialect.hashFunctionHandle())\n\t\t{\n\t\t\tIdentifier const* start = std::get_if<Identifier>(&funCall->arguments.at(0));\n\t\t\tIdentifier const* length = std::get_if<Identifier>(&funCall->arguments.at(1));\n\t\t\tif (start && length)\n\t\t\t\tif (auto const& value = keccakValue(start->name, length->name))\n\t\t\t\t\tif (inScope(*value))\n\t\t\t\t\t{\n\t\t\t\t\t\t_e = Identifier{debugDataOf(_e), *value};\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\ttryEvaluateKeccak(_e, funCall->arguments);\n\t\t}\n\t}\n}\n\nvoid LoadResolver::tryResolve(\n\tExpression& _e,\n\tStoreLoadLocation _location,\n\tstd::vector<Expression> const& _arguments\n)\n{\n\tif (_arguments.empty() || !std::holds_alternative<Identifier>(_arguments.at(0)))\n\t\treturn;\n\n\tYulName key = std::get<Identifier>(_arguments.at(0)).name;\n\tif (_location == StoreLoadLocation::Storage)\n\t{\n\t\tif (auto value = storageValue(key))\n\t\t\tif (inScope(*value))\n\t\t\t\t_e = Identifier{debugDataOf(_e), *value};\n\t}\n\telse if (!m_containsMSize && _location == StoreLoadLocation::Memory)\n\t\tif (auto value = memoryValue(key))\n\t\t\tif (inScope(*value))\n\t\t\t\t_e = Identifier{debugDataOf(_e), *value};\n}\n\nvoid LoadResolver::tryEvaluateKeccak(\n\tExpression& _e,\n\tstd::vector<Expression> const& _arguments\n)\n{\n\tyulAssert(_arguments.size() == 2, \"\");\n\tIdentifier const* memoryKey = std::get_if<Identifier>(&_arguments.at(0));\n\tIdentifier const* length = std::get_if<Identifier>(&_arguments.at(1));\n\n\tif (!memoryKey || !length)\n\t\treturn;\n\n\t// The costs are only correct for hashes of 32 bytes or 1 word (when rounded up).\n\tGasMeter gasMeter{\n\t\tdynamic_cast<EVMDialect const&>(m_dialect),\n\t\t!m_expectedExecutionsPerDeployment,\n\t\tm_expectedExecutionsPerDeployment ? *m_expectedExecutionsPerDeployment : 1\n\t};\n\n\tbigint costOfKeccak = gasMeter.costs(_e);\n\tbigint costOfLiteral = gasMeter.costs(\n\t\tLiteral{\n\t\t\t{},\n\t\t\tLiteralKind::Number,\n\t\t\t// a dummy 256-bit number to represent the Keccak256 hash.\n\t\t\tLiteralValue{std::numeric_limits<u256>::max()}\n\t\t}\n\t);\n\n\t// We skip if there are no net gas savings.\n\t// Note that for default `m_runs = 200`, the values are\n\t// `costOfLiteral = 7200` and `costOfKeccak = 9000` for runtime context.\n\t// For creation context: `costOfLiteral = 531` and `costOfKeccak = 90`.\n\tif (costOfLiteral > costOfKeccak)\n\t\treturn;\n\n\tstd::optional<YulName> value = memoryValue(memoryKey->name);\n\tif (value && inScope(*value))\n\t{\n\t\tstd::optional<u256> memoryContent = valueOfIdentifier(*value);\n\t\tstd::optional<u256> byteLength = valueOfIdentifier(length->name);\n\t\tif (memoryContent && byteLength && *byteLength <= 32)\n\t\t{\n\t\t\tbytes contentAsBytes = toBigEndian(*memoryContent);\n\t\t\tcontentAsBytes.resize(static_cast<size_t>(*byteLength));\n\t\t\tu256 const contentHash (keccak256(contentAsBytes));\n\t\t\t_e = Literal{\n\t\t\t\tdebugDataOf(_e),\n\t\t\t\tLiteralKind::Number,\n\t\t\t\tLiteralValue{contentHash}\n\t\t\t};\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "libyul/optimiser/LoadResolver.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that replaces expressions of type ``sload(x)`` by the value\n * currently stored in storage, if known.\n */\n\n#pragma once\n\n#include <libyul/optimiser/DataFlowAnalyzer.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Optimisation stage that replaces expressions of type ``sload(x)`` and ``mload(x)`` by the value\n * currently stored in storage resp. memory, if known.\n *\n * Also evaluates simple ``keccak256(a, c)`` when the value at memory location `a` is known and `c`\n * is a constant `<= 32`.\n *\n * Works best if the code is in SSA form.\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter.\n */\nclass LoadResolver: public DataFlowAnalyzer\n{\npublic:\n\tstatic constexpr char const* name{\"LoadResolver\"};\n\t/// Run the load resolver on the given complete AST.\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\nprivate:\n\tLoadResolver(\n\t\tDialect const& _dialect,\n\t\tstd::map<FunctionHandle, SideEffects> _functionSideEffects,\n\t\tbool _containsMSize,\n\t\tstd::optional<size_t> _expectedExecutionsPerDeployment\n\t):\n\t\tDataFlowAnalyzer(_dialect, MemoryAndStorage::Analyze, std::move(_functionSideEffects)),\n\t\tm_containsMSize(_containsMSize),\n\t\tm_expectedExecutionsPerDeployment(std::move(_expectedExecutionsPerDeployment))\n\t{}\n\nprotected:\n\tusing ASTModifier::visit;\n\tvoid visit(Expression& _e) override;\n\n\tvoid tryResolve(\n\t\tExpression& _e,\n\t\tStoreLoadLocation _location,\n\t\tstd::vector<Expression> const& _arguments\n\t);\n\n\t/// Evaluates simple ``keccak256(a, c)`` when the value at memory location ``a`` is known and\n\t/// `c` is a constant `<= 32`.\n\tvoid tryEvaluateKeccak(\n\t\tExpression& _e,\n\t\tstd::vector<Expression> const& _arguments\n\t);\n\n\t/// If the AST contains `msize`, then we skip resolving `mload` and `keccak256`.\n\tbool m_containsMSize = false;\n\t/// The --optimize-runs parameter. Value `nullopt` represents creation code.\n\tstd::optional<size_t> m_expectedExecutionsPerDeployment;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/LoopInvariantCodeMotion.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/optimiser/LoopInvariantCodeMotion.h>\n\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/SSAValueTracker.h>\n#include <libyul/AST.h>\n#include <libsolutil/CommonData.h>\n\n#include <utility>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid LoopInvariantCodeMotion::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tstd::map<FunctionHandle, SideEffects> functionSideEffects =\n\t\tSideEffectsPropagator::sideEffects(_context.dialect, CallGraphGenerator::callGraph(_ast));\n\tbool containsMSize = MSizeFinder::containsMSize(_context.dialect, _ast);\n\tstd::set<YulName> ssaVars = SSAValueTracker::ssaVariables(_ast);\n\tLoopInvariantCodeMotion{_context.dialect, ssaVars, functionSideEffects, containsMSize}(_ast);\n}\n\nvoid LoopInvariantCodeMotion::operator()(Block& _block)\n{\n\tutil::iterateReplacing(\n\t\t_block.statements,\n\t\t[&](Statement& _s) -> std::optional<std::vector<Statement>>\n\t\t{\n\t\t\tvisit(_s);\n\t\t\tif (std::holds_alternative<ForLoop>(_s))\n\t\t\t\treturn rewriteLoop(std::get<ForLoop>(_s));\n\t\t\telse\n\t\t\t\treturn {};\n\t\t}\n\t);\n}\n\nbool LoopInvariantCodeMotion::canBePromoted(\n\tVariableDeclaration const& _varDecl,\n\tstd::set<YulName> const& _varsDefinedInCurrentScope,\n\tSideEffects const& _forLoopSideEffects\n) const\n{\n\t// A declaration can be promoted iff\n\t// 1. Its LHS is a SSA variable\n\t// 2. Its RHS only references SSA variables declared outside of the current scope\n\t// 3. Its RHS is movable\n\n\tfor (auto const& var: _varDecl.variables)\n\t\tif (!m_ssaVariables.count(var.name))\n\t\t\treturn false;\n\tif (_varDecl.value)\n\t{\n\t\tfor (auto const& ref: VariableReferencesCounter::countReferences(*_varDecl.value))\n\t\t\tif (_varsDefinedInCurrentScope.count(ref.first) || !m_ssaVariables.count(ref.first))\n\t\t\t\treturn false;\n\t\tSideEffectsCollector sideEffects{m_dialect, *_varDecl.value, &m_functionSideEffects};\n\t\tif (!sideEffects.movableRelativeTo(_forLoopSideEffects, m_containsMSize))\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\nstd::optional<std::vector<Statement>> LoopInvariantCodeMotion::rewriteLoop(ForLoop& _for)\n{\n\tassertThrow(_for.pre.statements.empty(), OptimizerException, \"\");\n\n\tauto forLoopSideEffects =\n\t\tSideEffectsCollector{m_dialect, _for, &m_functionSideEffects}.sideEffects();\n\n\tstd::vector<Statement> replacement;\n\tfor (Block* block: {&_for.post, &_for.body})\n\t{\n\t\tstd::set<YulName> varsDefinedInScope;\n\t\tutil::iterateReplacing(\n\t\t\tblock->statements,\n\t\t\t[&](Statement& _s) -> std::optional<std::vector<Statement>>\n\t\t\t{\n\t\t\t\tif (std::holds_alternative<VariableDeclaration>(_s))\n\t\t\t\t{\n\t\t\t\t\tVariableDeclaration const& varDecl = std::get<VariableDeclaration>(_s);\n\t\t\t\t\tif (canBePromoted(varDecl, varsDefinedInScope, forLoopSideEffects))\n\t\t\t\t\t{\n\t\t\t\t\t\treplacement.emplace_back(std::move(_s));\n\t\t\t\t\t\t// Do not add the variables declared here to varsDefinedInScope because we are moving them.\n\t\t\t\t\t\treturn std::vector<Statement>{};\n\t\t\t\t\t}\n\t\t\t\t\tfor (auto const& var: varDecl.variables)\n\t\t\t\t\t\tvarsDefinedInScope.insert(var.name);\n\t\t\t\t}\n\t\t\t\treturn {};\n\t\t\t}\n\t\t);\n\t}\n\tif (replacement.empty())\n\t\treturn {};\n\telse\n\t{\n\t\treplacement.emplace_back(std::move(_for));\n\t\treturn { std::move(replacement) };\n\t}\n}\n"
  },
  {
    "path": "libyul/optimiser/LoopInvariantCodeMotion.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Loop-invariant code motion.\n *\n * This optimization moves movable SSA variable declarations outside the loop.\n *\n * Only statements at the top level in a loop's body or post block are considered, i.e variable\n * declarations inside conditional branches will not be moved out of the loop.\n *\n * Requirements:\n * - The Disambiguator, ForLoopInitRewriter and FunctionHoister must be run upfront.\n * - Expression splitter and SSA transform should be run upfront to obtain better result.\n */\n\nclass LoopInvariantCodeMotion: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"LoopInvariantCodeMotion\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast);\n\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\texplicit LoopInvariantCodeMotion(\n\t\tDialect const& _dialect,\n\t\tstd::set<YulName> const& _ssaVariables,\n\t\tstd::map<FunctionHandle, SideEffects> const& _functionSideEffects,\n\t\tbool _containsMSize\n\t):\n\t\tm_containsMSize(_containsMSize),\n\t\tm_dialect(_dialect),\n\t\tm_ssaVariables(_ssaVariables),\n\t\tm_functionSideEffects(_functionSideEffects)\n\t{ }\n\n\t/// @returns true if the given variable declaration can be moved to in front of the loop.\n\tbool canBePromoted(\n\t\tVariableDeclaration const& _varDecl,\n\t\tstd::set<YulName> const& _varsDefinedInCurrentScope,\n\t\tSideEffects const& _forLoopSideEffects\n\t) const;\n\tstd::optional<std::vector<Statement>> rewriteLoop(ForLoop& _for);\n\n\tbool m_containsMSize = true;\n\tDialect const& m_dialect;\n\tstd::set<YulName> const& m_ssaVariables;\n\tstd::map<FunctionHandle, SideEffects> const& m_functionSideEffects;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/Metrics.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n* Module providing metrics for the optimizer.\n*/\n\n#include <libyul/optimiser/Metrics.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <libyul/AST.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Utilities.h>\n\n#include <libevmasm/Instruction.h>\n\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nsize_t CodeWeights::costOf(Statement const& _statement) const\n{\n\tif (std::holds_alternative<ExpressionStatement>(_statement))\n\t\treturn expressionStatementCost;\n\telse if (std::holds_alternative<Assignment>(_statement))\n\t\treturn assignmentCost;\n\telse if (std::holds_alternative<VariableDeclaration>(_statement))\n\t\treturn variableDeclarationCost;\n\telse if (std::holds_alternative<FunctionDefinition>(_statement))\n\t\treturn functionDefinitionCost;\n\telse if (std::holds_alternative<If>(_statement))\n\t\treturn ifCost;\n\telse if (std::holds_alternative<Switch>(_statement))\n\t\treturn switchCost + caseCost * std::get<Switch>(_statement).cases.size();\n\telse if (std::holds_alternative<ForLoop>(_statement))\n\t\treturn forLoopCost;\n\telse if (std::holds_alternative<Break>(_statement))\n\t\treturn breakCost;\n\telse if (std::holds_alternative<Continue>(_statement))\n\t\treturn continueCost;\n\telse if (std::holds_alternative<Leave>(_statement))\n\t\treturn leaveCost;\n\telse if (std::holds_alternative<Block>(_statement))\n\t\treturn blockCost;\n\telse\n\t\tyulAssert(false, \"If you add a new statement type, you must update CodeWeights.\");\n}\n\nsize_t CodeWeights::costOf(Expression const& _expression) const\n{\n\tif (std::holds_alternative<FunctionCall>(_expression))\n\t\treturn functionCallCost;\n\telse if (std::holds_alternative<Identifier>(_expression))\n\t\treturn identifierCost;\n\telse if (Literal const* literal = std::get_if<Literal>(&_expression))\n\t{\n\t\t// Avoid strings because they could be longer than 32 bytes.\n\t\tif (literal->kind != LiteralKind::String && literal->value.value() == 0)\n\t\t\treturn literalZeroCost;\n\t\telse\n\t\t\treturn literalCost;\n\t}\n\telse\n\t\tyulAssert(false, \"If you add a new expression type, you must update CodeWeights.\");\n}\n\n\nsize_t CodeSize::codeSize(Statement const& _statement, CodeWeights const& _weights)\n{\n\tCodeSize cs(true, _weights);\n\tcs.visit(_statement);\n\treturn cs.m_size;\n}\n\nsize_t CodeSize::codeSize(Expression const& _expression, CodeWeights const& _weights)\n{\n\tCodeSize cs(true, _weights);\n\tcs.visit(_expression);\n\treturn cs.m_size;\n}\n\nsize_t CodeSize::codeSize(Block const& _block, CodeWeights const& _weights)\n{\n\tCodeSize cs(true, _weights);\n\tcs(_block);\n\treturn cs.m_size;\n}\n\nsize_t CodeSize::codeSizeIncludingFunctions(Block const& _block, CodeWeights const& _weights)\n{\n\tCodeSize cs(false, _weights);\n\tcs(_block);\n\treturn cs.m_size;\n}\n\nvoid CodeSize::visit(Statement const& _statement)\n{\n\tif (std::holds_alternative<FunctionDefinition>(_statement) && m_ignoreFunctions)\n\t\treturn;\n\n\tm_size += m_weights.costOf(_statement);\n\tASTWalker::visit(_statement);\n}\n\nvoid CodeSize::visit(Expression const& _expression)\n{\n\tm_size += m_weights.costOf(_expression);\n\tASTWalker::visit(_expression);\n}\n\n\nsize_t CodeCost::codeCost(Dialect const& _dialect, Expression const& _expr)\n{\n\tCodeCost cc(_dialect);\n\tcc.visit(_expr);\n\treturn cc.m_cost;\n}\n\n\nvoid CodeCost::operator()(FunctionCall const& _funCall)\n{\n\tASTWalker::operator()(_funCall);\n\n\tif (auto instruction = toEVMInstruction(m_dialect, _funCall.functionName))\n\t{\n\t\taddInstructionCost(*instruction);\n\t\treturn;\n\t}\n\n\tm_cost += 49;\n}\n\nvoid CodeCost::operator()(Literal const& _literal)\n{\n\tyulAssert(m_cost >= 1, \"Should assign cost one in visit(Expression).\");\n\tsize_t cost = 0;\n\tswitch (_literal.kind)\n\t{\n\tcase LiteralKind::Boolean:\n\t\tbreak;\n\tcase LiteralKind::Number:\n\t\tfor (u256 n = _literal.value.value(); n >= 0x100; n >>= 8)\n\t\t\tcost++;\n\t\tif (_literal.value.value() == 0)\n\t\t\tif (auto evmDialect = dynamic_cast<EVMDialect const*>(&m_dialect))\n\t\t\t\tif (evmDialect->evmVersion().hasPush0())\n\t\t\t\t\t--m_cost;\n\t\tbreak;\n\tcase LiteralKind::String:\n\t\tcost = formatLiteral(_literal).size();\n\t\tbreak;\n\t}\n\n\tm_cost += cost;\n}\n\nvoid CodeCost::visit(Statement const& _statement)\n{\n\t++m_cost;\n\tASTWalker::visit(_statement);\n}\n\nvoid CodeCost::visit(Expression const& _expression)\n{\n\t++m_cost;\n\tASTWalker::visit(_expression);\n}\n\nvoid CodeCost::addInstructionCost(evmasm::Instruction _instruction)\n{\n\tevmasm::Tier gasPriceTier = evmasm::instructionInfo(_instruction, evmVersionFromDialect(m_dialect)).gasPriceTier;\n\tif (gasPriceTier < evmasm::Tier::VeryLow)\n\t\tm_cost -= 1;\n\telse if (gasPriceTier < evmasm::Tier::High)\n\t\tm_cost += 1;\n\telse\n\t\tm_cost += 49;\n}\n\nvoid AssignmentCounter::operator()(Assignment const& _assignment)\n{\n\tfor (auto const& variable: _assignment.variableNames)\n\t\t++m_assignmentCounters[variable.name];\n}\n\nsize_t AssignmentCounter::assignmentCount(YulName _name) const\n{\n\tauto it = m_assignmentCounters.find(_name);\n\treturn (it == m_assignmentCounters.end()) ? 0 : it->second;\n}\n"
  },
  {
    "path": "libyul/optimiser/Metrics.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Module providing metrics for the optimizer.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <liblangutil/EVMVersion.h>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\nclass EVMDialect;\n\n/**\n * Weights to be assigned to specific yul statements and expressions by a metric.\n *\n * The default values are meant to reflect specifically the number of AST nodes.\n *\n * The following AST elements have a default cost of zero (because the cleanup phase would\n * remove them anyway or they are just wrappers around something else that will be counted instead):\n *  - expression statement (only the expression inside has a cost)\n *  - block (only the statements inside have a cost)\n *  - variable references\n *  - variable declarations (only the right hand side has a cost)\n *  - assignments (only the value has a cost)\n *  - literal zeros (we optimistically assume they can be copied from somewhere else)\n *\n * Each statement incurs and additional cost of one\n * per jump/branch. This means if, break and continue statements have a cost of 2,\n * switch statements have a cost of 1 plus the number of cases times two,\n * and for loops cost 3.\n*/\nstruct CodeWeights\n{\n\t// Statements\n\tsize_t expressionStatementCost = 0;\n\tsize_t assignmentCost = 0;\n\tsize_t variableDeclarationCost = 0;\n\tsize_t functionDefinitionCost = 1;\n\tsize_t ifCost = 2;\n\tsize_t switchCost = 1;\n\tsize_t caseCost = 2;\n\tsize_t forLoopCost = 3;\n\tsize_t breakCost = 2;\n\tsize_t continueCost = 2;\n\tsize_t leaveCost = 2;\n\tsize_t blockCost = 0;\n\n\t// Expressions\n\tsize_t functionCallCost = 1;\n\tsize_t identifierCost = 0;\n\tsize_t literalCost = 1;\n\tsize_t literalZeroCost = 0;\n\n\tsize_t costOf(Statement const& _statement) const;\n\tsize_t costOf(Expression const& _expression) const;\n};\n\n/**\n * Metric for the size of code.\n * Ignores function definitions while traversing the AST by default.\n * If you want to know the size of a function, you have to invoke this on its body.\n *\n * The cost of each statement and expression type is configurable via CodeWeights.\n */\nclass CodeSize: public ASTWalker\n{\npublic:\n\tstatic size_t codeSize(Statement const& _statement, CodeWeights const& _weights = {});\n\tstatic size_t codeSize(Expression const& _expression, CodeWeights const& _weights = {});\n\tstatic size_t codeSize(Block const& _block, CodeWeights const& _weights = {});\n\tstatic size_t codeSizeIncludingFunctions(Block const& _block, CodeWeights const& _weights = {});\n\nprivate:\n\tCodeSize(bool _ignoreFunctions = true, CodeWeights const& _weights = {}):\n\t\tm_ignoreFunctions(_ignoreFunctions),\n\t\tm_weights(_weights) {}\n\n\tvoid visit(Statement const& _statement) override;\n\tvoid visit(Expression const& _expression) override;\n\nprivate:\n\tbool m_ignoreFunctions;\n\tsize_t m_size = 0;\n\tCodeWeights m_weights;\n};\n\n/**\n * Very rough cost that takes the size and execution cost of code into account.\n * The cost per AST element is one, except for literals where it is the byte size.\n * Function calls cost 50. Instructions cost 0 for 3 or less gas (same as DUP),\n * 2 for up to 10 and 50 otherwise.\n */\nclass CodeCost: public ASTWalker\n{\npublic:\n\tstatic size_t codeCost(Dialect const& _dialect, Expression const& _expression);\n\nprivate:\n\tCodeCost(Dialect const& _dialect): m_dialect(_dialect) {}\n\n\tvoid operator()(FunctionCall const& _funCall) override;\n\tvoid operator()(Literal const& _literal) override;\n\tvoid visit(Statement const& _statement) override;\n\tvoid visit(Expression const& _expression) override;\n\nprivate:\n\tvoid addInstructionCost(evmasm::Instruction _instruction);\n\n\tDialect const& m_dialect;\n\tsize_t m_cost = 0;\n};\n\n/**\n * Counts the number of assignments to every variable.\n * Only works after running the Disambiguator.\n */\nclass AssignmentCounter: public ASTWalker\n{\npublic:\n\tusing ASTWalker::operator();\n\tvoid operator()(Assignment const& _assignment) override;\n\tstd::size_t assignmentCount(YulName _name) const;\nprivate:\n\tstd::map<YulName, size_t> m_assignmentCounters;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/NameCollector.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Specific AST walker that collects all defined names.\n */\n\n#include <libyul/optimiser/NameCollector.h>\n\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nvoid NameCollector::operator()(VariableDeclaration const& _varDecl)\n{\n\tif (m_collectWhat != OnlyFunctions)\n\t\tfor (auto const& var: _varDecl.variables)\n\t\t\tm_names.emplace(var.name);\n}\n\nvoid NameCollector::operator()(FunctionDefinition const& _funDef)\n{\n\tif (m_collectWhat != OnlyVariables)\n\t\tm_names.emplace(_funDef.name);\n\tif (m_collectWhat != OnlyFunctions)\n\t{\n\t\tfor (auto const& arg: _funDef.parameters)\n\t\t\tm_names.emplace(arg.name);\n\t\tfor (auto const& ret: _funDef.returnVariables)\n\t\t\tm_names.emplace(ret.name);\n\t}\n\tASTWalker::operator ()(_funDef);\n}\n\nvoid ReferencesCounter::operator()(Identifier const& _identifier)\n{\n\t++m_references[_identifier.name];\n}\n\nvoid ReferencesCounter::operator()(FunctionCall const& _funCall)\n{\n\t++m_references[functionNameToHandle(_funCall.functionName)];\n\tASTWalker::operator()(_funCall);\n}\n\nstd::map<FunctionHandle, size_t> ReferencesCounter::countReferences(Block const& _block)\n{\n\tReferencesCounter counter;\n\tcounter(_block);\n\treturn std::move(counter.m_references);\n}\n\nstd::map<FunctionHandle, size_t> ReferencesCounter::countReferences(FunctionDefinition const& _function)\n{\n\tReferencesCounter counter;\n\tcounter(_function);\n\treturn std::move(counter.m_references);\n}\n\nstd::map<FunctionHandle, size_t> ReferencesCounter::countReferences(Expression const& _expression)\n{\n\tReferencesCounter counter;\n\tcounter.visit(_expression);\n\treturn std::move(counter.m_references);\n}\n\nvoid VariableReferencesCounter::operator()(Identifier const& _identifier)\n{\n\t++m_references[_identifier.name];\n}\n\nstd::map<YulName, size_t> VariableReferencesCounter::countReferences(Block const& _block)\n{\n\tVariableReferencesCounter counter;\n\tcounter(_block);\n\treturn std::move(counter.m_references);\n}\n\nstd::map<YulName, size_t> VariableReferencesCounter::countReferences(FunctionDefinition const& _function)\n{\n\tVariableReferencesCounter counter;\n\tcounter(_function);\n\treturn std::move(counter.m_references);\n}\n\nstd::map<YulName, size_t> VariableReferencesCounter::countReferences(Expression const& _expression)\n{\n\tVariableReferencesCounter counter;\n\tcounter.visit(_expression);\n\treturn std::move(counter.m_references);\n}\n\nstd::map<YulName, size_t> VariableReferencesCounter::countReferences(Statement const& _statement)\n{\n\tVariableReferencesCounter counter;\n\tcounter.visit(_statement);\n\treturn std::move(counter.m_references);\n}\n\nvoid AssignmentsSinceContinue::operator()(ForLoop const& _forLoop)\n{\n\tm_forLoopDepth++;\n\tASTWalker::operator()(_forLoop);\n\tm_forLoopDepth--;\n}\n\nvoid AssignmentsSinceContinue::operator()(Continue const&)\n{\n\tif (m_forLoopDepth == 0)\n\t\tm_continueFound = true;\n}\n\nvoid AssignmentsSinceContinue::operator()(Assignment const& _assignment)\n{\n\tif (m_continueFound)\n\t\tfor (auto const& var: _assignment.variableNames)\n\t\t\tm_names.emplace(var.name);\n}\n\nvoid AssignmentsSinceContinue::operator()(FunctionDefinition const&)\n{\n\tyulAssert(false, \"\");\n}\n\nstd::set<YulName> solidity::yul::assignedVariableNames(Block const& _code)\n{\n\tstd::set<YulName> names;\n\tforEach<Assignment const>(_code, [&](Assignment const& _assignment) {\n\t\tfor (auto const& var: _assignment.variableNames)\n\t\t\tnames.emplace(var.name);\n\t});\n\treturn names;\n}\n\nstd::map<YulName, FunctionDefinition const*> solidity::yul::allFunctionDefinitions(Block const& _block)\n{\n\tstd::map<YulName, FunctionDefinition const*> result;\n\tforEach<FunctionDefinition const>(_block, [&](FunctionDefinition const& _function) {\n\t\tresult[_function.name] = &_function;\n\t});\n\treturn result;\n}\n"
  },
  {
    "path": "libyul/optimiser/NameCollector.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Specific AST walkers that collect facts about identifiers and definitions.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/YulName.h>\n\n#include <map>\n#include <set>\n\nnamespace solidity::yul\n{\n\n/**\n * Specific AST walker that collects all defined names.\n */\nclass NameCollector: public ASTWalker\n{\npublic:\n\tenum CollectWhat { VariablesAndFunctions, OnlyVariables, OnlyFunctions };\n\n\texplicit NameCollector(\n\t\tBlock const& _block,\n\t\tCollectWhat _collectWhat = VariablesAndFunctions\n\t):\n\t\tm_collectWhat(_collectWhat)\n\t{\n\t\t(*this)(_block);\n\t}\n\n\texplicit NameCollector(\n\t\tFunctionDefinition const& _functionDefinition,\n\t\tCollectWhat _collectWhat = VariablesAndFunctions\n\t):\n\t\tm_collectWhat(_collectWhat)\n\t{\n\t\t(*this)(_functionDefinition);\n\t}\n\n\tusing ASTWalker::operator ();\n\tvoid operator()(VariableDeclaration const& _varDecl) override;\n\tvoid operator()(FunctionDefinition const& _funDef) override;\n\n\tstd::set<YulName> names() const { return m_names; }\nprivate:\n\tstd::set<YulName> m_names;\n\tCollectWhat m_collectWhat = VariablesAndFunctions;\n};\n\n/**\n * Specific AST walker that counts all references to all declarations.\n */\nclass ReferencesCounter: public ASTWalker\n{\npublic:\n\tusing ASTWalker::operator ();\n\tvoid operator()(Identifier const& _identifier) override;\n\tvoid operator()(FunctionCall const& _funCall) override;\n\n\tstatic std::map<FunctionHandle, size_t> countReferences(Block const& _block);\n\tstatic std::map<FunctionHandle, size_t> countReferences(FunctionDefinition const& _function);\n\tstatic std::map<FunctionHandle, size_t> countReferences(Expression const& _expression);\n\nprivate:\n\tstd::map<FunctionHandle, size_t> m_references;\n};\n\n/**\n * Specific AST walker that counts all references to all variable declarations.\n */\nclass VariableReferencesCounter: public ASTWalker\n{\npublic:\n\tusing ASTWalker::operator ();\n\tvoid operator()(Identifier const& _identifier) override;\n\n\tstatic std::map<YulName, size_t> countReferences(Block const& _block);\n\tstatic std::map<YulName, size_t> countReferences(FunctionDefinition const& _function);\n\tstatic std::map<YulName, size_t> countReferences(Expression const& _expression);\n\tstatic std::map<YulName, size_t> countReferences(Statement const& _statement);\n\nprivate:\n\tstd::map<YulName, size_t> m_references;\n};\n\n/**\n * Collects all names from a given continue statement on onwards.\n *\n * It makes only sense to be invoked from within a body of an outer for loop, that is,\n * it will only collect all names from the beginning of the first continue statement\n * of the outer-most ForLoop.\n */\nclass AssignmentsSinceContinue: public ASTWalker\n{\npublic:\n\tusing ASTWalker::operator();\n\tvoid operator()(ForLoop const& _forLoop) override;\n\tvoid operator()(Continue const&) override;\n\tvoid operator()(Assignment const& _assignment) override;\n\tvoid operator()(FunctionDefinition const& _funDef) override;\n\n\tstd::set<YulName> const& names() const { return m_names; }\n\tbool empty() const noexcept { return m_names.empty(); }\n\nprivate:\n\tsize_t m_forLoopDepth = 0;\n\tbool m_continueFound = false;\n\tstd::set<YulName> m_names;\n};\n\n/// @returns the names of all variables that are assigned to inside @a _code.\n/// (ignores variable declarations)\nstd::set<YulName> assignedVariableNames(Block const& _code);\n\n/// @returns all function definitions anywhere in the AST.\n/// Requires disambiguated source.\nstd::map<YulName, FunctionDefinition const*> allFunctionDefinitions(Block const& _block);\n\n}\n"
  },
  {
    "path": "libyul/optimiser/NameDispenser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that can create new unique names.\n */\n\n#include <libyul/optimiser/NameDispenser.h>\n\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::util;\n\nNameDispenser::NameDispenser(Dialect const& _dialect, Block const& _ast, std::set<YulName> _reservedNames):\n\tNameDispenser(_dialect, NameCollector(_ast).names() + _reservedNames)\n{\n\tm_reservedNames = std::move(_reservedNames);\n}\n\nNameDispenser::NameDispenser(Dialect const& _dialect, std::set<YulName> _usedNames):\n\tm_dialect(_dialect),\n\tm_usedNames(std::move(_usedNames))\n{\n}\n\nYulName NameDispenser::newName(YulName _nameHint)\n{\n\tYulName name = _nameHint;\n\twhile (illegalName(name))\n\t{\n\t\tm_counter++;\n\t\tname = YulName(_nameHint.str() + \"_\" + std::to_string(m_counter));\n\t}\n\tm_usedNames.emplace(name);\n\treturn name;\n}\n\nbool NameDispenser::illegalName(YulName _name)\n{\n\treturn isRestrictedIdentifier(m_dialect, _name.str()) || m_usedNames.contains(_name);\n}\n\nvoid NameDispenser::reset(Block const& _ast)\n{\n\tm_usedNames = NameCollector(_ast).names() + m_reservedNames;\n\tm_counter = 0;\n}\n"
  },
  {
    "path": "libyul/optimiser/NameDispenser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that can create new unique names.\n */\n#pragma once\n\n#include <libyul/ASTForward.h>\n\n#include <libyul/YulName.h>\n\n#include <set>\n\nnamespace solidity::yul\n{\nclass Dialect;\n\n/**\n * Optimizer component that can be used to generate new names that\n * do not conflict with existing names.\n *\n * Tries to keep names short and appends decimals to disambiguate.\n */\nclass NameDispenser\n{\npublic:\n\t/// Initialize the name dispenser with all the names used in the given AST.\n\texplicit NameDispenser(Dialect const& _dialect, Block const& _ast, std::set<YulName> _reservedNames = {});\n\t/// Initialize the name dispenser with the given used names.\n\texplicit NameDispenser(Dialect const& _dialect, std::set<YulName> _usedNames);\n\n\t/// @returns a currently unused name that should be similar to _nameHint.\n\tYulName newName(YulName _nameHint);\n\n\t/// Mark @a _name as used, i.e. the dispenser's newName function will not\n\t/// return it.\n\tvoid markUsed(YulName _name) { m_usedNames.insert(_name); }\n\n\tstd::set<YulName> const& usedNames() { return m_usedNames; }\n\n\t/// Returns true if `_name` is either used or is a restricted identifier.\n\tbool illegalName(YulName _name);\n\n\t/// Resets `m_usedNames` with *only* the names that are used in the AST. Also resets value of\n\t/// `m_counter` to zero.\n\tvoid reset(Block const& _ast);\n\nprivate:\n\tDialect const& m_dialect;\n\tstd::set<YulName> m_usedNames;\n\tstd::set<YulName> m_reservedNames;\n\tsize_t m_counter = 0;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/NameDisplacer.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that renames identifiers to free up certain names.\n */\n\n#include <libyul/optimiser/NameDisplacer.h>\n\n#include <libyul/AST.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid NameDisplacer::operator()(Identifier& _identifier)\n{\n\tcheckAndReplace(_identifier.name);\n}\n\nvoid NameDisplacer::operator()(VariableDeclaration& _varDecl)\n{\n\tfor (NameWithDebugData& var: _varDecl.variables)\n\t\tcheckAndReplaceNew(var.name);\n\n\tASTModifier::operator()(_varDecl);\n}\n\nvoid NameDisplacer::operator()(FunctionDefinition& _function)\n{\n\t// Should have been done in the block already.\n\tyulAssert(!m_namesToFree.count(_function.name), \"\");\n\n\tfor (auto& param: _function.parameters)\n\t\tcheckAndReplaceNew(param.name);\n\tfor (auto& retVar: _function.returnVariables)\n\t\tcheckAndReplaceNew(retVar.name);\n\n\tASTModifier::operator()(_function);\n}\n\nvoid NameDisplacer::operator()(FunctionCall& _funCall)\n{\n\tif (std::holds_alternative<Identifier>(_funCall.functionName))\n\t\tcheckAndReplace(std::get<Identifier>(_funCall.functionName).name);\n\tASTModifier::operator()(_funCall);\n}\n\nvoid NameDisplacer::operator()(Block& _block)\n{\n\t// First replace all the names of function definitions\n\t// because of scoping.\n\tfor (auto& st: _block.statements)\n\t\tif (std::holds_alternative<FunctionDefinition>(st))\n\t\t\tcheckAndReplaceNew(std::get<FunctionDefinition>(st).name);\n\n\tASTModifier::operator()(_block);\n}\n\nvoid NameDisplacer::checkAndReplaceNew(YulName& _name)\n{\n\tyulAssert(!m_translations.count(_name), \"\");\n\tif (m_namesToFree.count(_name))\n\t\t_name = (m_translations[_name] = m_nameDispenser.newName(_name));\n}\n\nvoid NameDisplacer::checkAndReplace(YulName& _name) const\n{\n\tif (m_translations.count(_name))\n\t\t_name = m_translations.at(_name);\n}\n\n"
  },
  {
    "path": "libyul/optimiser/NameDisplacer.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that renames identifiers to free up certain names.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/NameDispenser.h>\n\n#include <set>\n#include <map>\n\nnamespace solidity::yul\n{\nclass Dialect;\n\n/**\n * Optimiser component that renames identifiers to free up certain names.\n *\n * Only replaces names that have been defined inside the code. If the code uses\n * names to be freed but does not define them, they remain unchanged.\n *\n * Prerequisites: Disambiguator\n */\nclass NameDisplacer: public ASTModifier\n{\npublic:\n\texplicit NameDisplacer(\n\t\tNameDispenser& _dispenser,\n\t\tstd::set<YulName> const& _namesToFree\n\t):\n\t\tm_nameDispenser(_dispenser),\n\t\tm_namesToFree(_namesToFree)\n\t{\n\t\tfor (YulName n: _namesToFree)\n\t\t\tm_nameDispenser.markUsed(n);\n\t}\n\n\tusing ASTModifier::operator();\n\tvoid operator()(Identifier& _identifier) override;\n\tvoid operator()(VariableDeclaration& _varDecl) override;\n\tvoid operator()(FunctionDefinition& _function) override;\n\tvoid operator()(FunctionCall& _funCall) override;\n\tvoid operator()(Block& _block) override;\n\n\tstd::map<YulName, YulName> const& translations() const { return m_translations; }\n\nprotected:\n\t/// Check if the newly introduced identifier @a _name has to be replaced.\n\tvoid checkAndReplaceNew(YulName& _name);\n\t/// Replace the identifier @a _name if it is in the translation map.\n\tvoid checkAndReplace(YulName& _name) const;\n\n\tNameDispenser& m_nameDispenser;\n\tstd::set<YulName> const& m_namesToFree;\n\tstd::map<YulName, YulName> m_translations;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/NameSimplifier.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <libyul/optimiser/NameSimplifier.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/YulName.h>\n#include <libyul/optimiser/NameDispenser.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <regex>\n\nusing namespace solidity::yul;\n\nNameSimplifier::NameSimplifier(OptimiserStepContext& _context, Block const& _ast):\n\tm_context(_context)\n{\n\tfor (YulName name: _context.reservedIdentifiers)\n\t\tm_translations[name] = name;\n\n\tfor (YulName const& name: NameCollector(_ast).names())\n\t\tfindSimplification(name);\n}\n\nvoid NameSimplifier::operator()(FunctionDefinition& _funDef)\n{\n\ttranslate(_funDef.name);\n\trenameVariables(_funDef.parameters);\n\trenameVariables(_funDef.returnVariables);\n\tASTModifier::operator()(_funDef);\n}\n\nvoid NameSimplifier::operator()(VariableDeclaration& _varDecl)\n{\n\trenameVariables(_varDecl.variables);\n\tASTModifier::operator()(_varDecl);\n}\n\nvoid NameSimplifier::renameVariables(std::vector<NameWithDebugData>& _variables)\n{\n\tfor (NameWithDebugData& typedName: _variables)\n\t\ttranslate(typedName.name);\n}\n\nvoid NameSimplifier::operator()(Identifier& _identifier)\n{\n\ttranslate(_identifier.name);\n}\n\nvoid NameSimplifier::operator()(FunctionCall& _funCall)\n{\n\t// The visitor on its own does not visit the function name.\n\tif (!isBuiltinFunctionCall(_funCall))\n\t{\n\t\tyulAssert(std::holds_alternative<Identifier>(_funCall.functionName));\n\t\t(*this)(std::get<Identifier>(_funCall.functionName));\n\t}\n\tASTModifier::operator()(_funCall);\n}\n\nvoid NameSimplifier::findSimplification(YulName const& _name)\n{\n\tif (m_translations.count(_name))\n\t\treturn;\n\n\tstd::string name = _name.str();\n\n\tstatic auto replacements = std::vector<std::pair<std::regex, std::string>>{\n\t\t{std::regex(\"_\\\\$|\\\\$_\"), \"_\"}, // remove type mangling delimiters\n\t\t{std::regex(\"_[0-9]+([^0-9a-fA-Fx])\"), \"$1\"}, // removes AST IDs that are not hex.\n\t\t{std::regex(\"_[0-9]+$\"), \"\"}, // removes AST IDs that are not hex.\n\t\t{std::regex(\"_t_\"), \"_\"}, // remove type prefixes\n\t\t{std::regex(\"__\"), \"_\"},\n\t\t{std::regex(\"(abi_..code.*)_to_.*\"), \"$1\"}, // removes _to... for abi functions\n\t\t{std::regex(\"(stringliteral_?[0-9a-f][0-9a-f][0-9a-f][0-9a-f])[0-9a-f]*\"), \"$1\"}, // shorten string literal\n\t\t{std::regex(\"tuple_\"), \"\"},\n\t\t{std::regex(\"_memory_ptr\"), \"\"},\n\t\t{std::regex(\"_calldata_ptr\"), \"_calldata\"},\n\t\t{std::regex(\"_fromStack\"), \"\"},\n\t\t{std::regex(\"_storage_storage\"), \"_storage\"},\n\t\t{std::regex(\"(storage.*)_?storage\"), \"$1\"},\n\t\t{std::regex(\"_memory_memory\"), \"_memory\"},\n\t\t{std::regex(\"_contract\\\\$_([^_]*)_?\"), \"$1_\"},\n\t\t{std::regex(\"index_access_(t_)?array\"), \"index_access\"},\n\t\t{std::regex(\"[0-9]*_$\"), \"\"}\n\t};\n\n\tfor (auto const& [pattern, substitute]: replacements)\n\t{\n\t\tstd::string candidate = regex_replace(name, pattern, substitute);\n\t\tif (!candidate.empty() && !m_context.dispenser.illegalName(YulName(candidate)))\n\t\t\tname = candidate;\n\t}\n\n\tif (name != _name.str())\n\t{\n\t\tYulName newName{name};\n\t\tm_context.dispenser.markUsed(newName);\n\t\tm_translations[_name] = std::move(newName);\n\t}\n}\n\nvoid NameSimplifier::translate(YulName& _name)\n{\n\tauto it = m_translations.find(_name);\n\tif (it != m_translations.end())\n\t\t_name = it->second;\n}\n"
  },
  {
    "path": "libyul/optimiser/NameSimplifier.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/YulName.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\n#include <map>\n#include <set>\n#include <string>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\n\n/**\n * Pass to \"simplify\" all identifier names.\n *\n * The purpose of this is to make generated code more readable, but also\n * to remove AST identifiers that could lead to a different sorting order\n * and thus influence e.g. the order of function inlining.\n *\n * Prerequisites: Disambiguator, FunctionHoister, FunctionGrouper\n */\nclass NameSimplifier: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"NameSimplifier\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast)\n\t{\n\t\tNameSimplifier{_context, _ast}(_ast);\n\t}\n\n\tusing ASTModifier::operator();\n\tvoid operator()(VariableDeclaration& _varDecl) override;\n\tvoid operator()(Identifier& _identifier) override;\n\tvoid operator()(FunctionCall& _funCall) override;\n\tvoid operator()(FunctionDefinition& _funDef) override;\n\nprivate:\n\tNameSimplifier(OptimiserStepContext& _context, Block const& _ast);\n\n\t/// Tries to rename a list of variables.\n\tvoid renameVariables(std::vector<NameWithDebugData>& _variables);\n\n\tvoid findSimplification(YulName const& _name);\n\tvoid translate(YulName& _name);\n\n\tOptimiserStepContext& m_context;\n\tstd::map<YulName, YulName> m_translations;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/OptimiserStep.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/Exceptions.h>\n\n#include <optional>\n#include <string>\n#include <set>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\nstruct Block;\nclass NameDispenser;\n\nstruct OptimiserStepContext\n{\n\tDialect const& dialect;\n\tNameDispenser& dispenser;\n\tstd::set<YulName> const& reservedIdentifiers;\n\t/// The value nullopt represents creation code\n\tstd::optional<size_t> expectedExecutionsPerDeployment;\n};\n\n\n/**\n * Construction to create dynamically callable objects out of the\n * statically callable optimiser steps.\n */\nstruct OptimiserStep\n{\n\texplicit OptimiserStep(std::string _name): name(std::move(_name)) {}\n\tvirtual ~OptimiserStep() = default;\n\n\tvirtual void run(OptimiserStepContext&, Block&) const = 0;\n\t/// @returns non-nullopt if the step cannot be run, for example because it requires\n\t/// an SMT solver to be loaded, but none is available. In that case, the string\n\t/// contains a human-readable reason.\n\tvirtual std::optional<std::string> invalidInCurrentEnvironment() const = 0;\n\tstd::string name;\n};\n\ntemplate <class Step>\nstruct OptimiserStepInstance: public OptimiserStep\n{\nprivate:\n\ttemplate<typename T>\n\tstruct HasInvalidInCurrentEnvironmentMethod\n\t{\n\tprivate:\n\t\ttemplate<typename U> static auto test(int) -> decltype(U::invalidInCurrentEnvironment(), std::true_type());\n\t\ttemplate<typename> static std::false_type test(...);\n\n\tpublic:\n\t\tstatic constexpr bool value = decltype(test<T>(0))::value;\n\t};\n\npublic:\n\tOptimiserStepInstance(): OptimiserStep{Step::name} {}\n\tvoid run(OptimiserStepContext& _context, Block& _ast) const override\n\t{\n\t\tStep::run(_context, _ast);\n\t}\n\tstd::optional<std::string> invalidInCurrentEnvironment() const override\n\t{\n\t\tif constexpr (HasInvalidInCurrentEnvironmentMethod<Step>::value)\n\t\t\treturn Step::invalidInCurrentEnvironment();\n\t\telse\n\t\t\treturn std::nullopt;\n\t}\n};\n\n\n}\n"
  },
  {
    "path": "libyul/optimiser/OptimizerUtilities.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Some useful snippets for the optimiser.\n */\n\n#include <libyul/optimiser/OptimizerUtilities.h>\n\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/Utilities.h>\n\n#include <liblangutil/Token.h>\n#include <libsolutil/CommonData.h>\n\n#include <range/v3/action/remove_if.hpp>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\nusing namespace solidity::yul;\n\nnamespace\n{\n\nbool hasLeadingOrTrailingDot(std::string_view const _s)\n{\n\tyulAssert(!_s.empty());\n\treturn _s.front() == '.' || _s.back() == '.';\n}\n\n}\n\nvoid yul::removeEmptyBlocks(Block& _block)\n{\n\tauto isEmptyBlock = [](Statement const& _st) -> bool {\n\t\treturn std::holds_alternative<Block>(_st) && std::get<Block>(_st).statements.empty();\n\t};\n\tranges::actions::remove_if(_block.statements, isEmptyBlock);\n}\n\nbool yul::isRestrictedIdentifier(Dialect const& _dialect, std::string_view const _identifier)\n{\n\treturn _identifier.empty() || hasLeadingOrTrailingDot(_identifier) || TokenTraits::isYulKeyword(_identifier) || _dialect.reservedIdentifier(_identifier);\n}\n\nstd::optional<evmasm::Instruction> yul::toEVMInstruction(Dialect const& _dialect, FunctionName const& _name)\n{\n\tif (auto const* dialect = dynamic_cast<EVMDialect const*>(&_dialect))\n\t\tif (BuiltinFunctionForEVM const* builtin = resolveBuiltinFunctionForEVM(_name, *dialect))\n\t\t\treturn builtin->instruction;\n\treturn std::nullopt;\n}\n\nlangutil::EVMVersion const yul::evmVersionFromDialect(Dialect const& _dialect)\n{\n\tif (auto const* dialect = dynamic_cast<EVMDialect const*>(&_dialect))\n\t\treturn dialect->evmVersion();\n\treturn langutil::EVMVersion();\n}\n\nvoid StatementRemover::operator()(Block& _block)\n{\n\tutil::iterateReplacing(\n\t\t_block.statements,\n\t\t[&](Statement& _statement) -> std::optional<std::vector<Statement>>\n\t\t{\n\t\t\tif (m_toRemove.count(&_statement))\n\t\t\t\treturn {std::vector<Statement>{}};\n\t\t\telse\n\t\t\t\treturn std::nullopt;\n\t\t}\n\t);\n\tASTModifier::operator()(_block);\n}\n"
  },
  {
    "path": "libyul/optimiser/OptimizerUtilities.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Small useful snippets for the optimiser.\n */\n\n#pragma once\n\n#include <libsolutil/Common.h>\n#include <libyul/ASTForward.h>\n#include <libyul/Dialect.h>\n#include <libyul/optimiser/ASTWalker.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <optional>\n#include <string_view>\n\nnamespace solidity::evmasm\n{\nenum class Instruction: uint8_t;\n}\n\nnamespace solidity::yul\n{\n\n/// Removes statements that are just empty blocks (non-recursive).\n/// If this is run on the outermost block, the FunctionGrouper should be run afterwards to keep\n/// the canonical form.\nvoid removeEmptyBlocks(Block& _block);\n\n/// Returns true if a given literal can not be used as an identifier.\n/// This includes Yul keywords and builtins of the given dialect.\nbool isRestrictedIdentifier(Dialect const& _dialect, std::string_view _identifier);\n\n/// Helper function that returns the instruction, if the `_name` is a BuiltinFunction\nstd::optional<evmasm::Instruction> toEVMInstruction(Dialect const& _dialect, FunctionName const& _name);\n\n/// Helper function that returns the EVM version from a dialect.\n/// It returns the default EVM version if dialect is not an EVMDialect.\nlangutil::EVMVersion const evmVersionFromDialect(Dialect const& _dialect);\n\nclass StatementRemover: public ASTModifier\n{\npublic:\n\texplicit StatementRemover(std::set<Statement const*> const& _toRemove): m_toRemove(_toRemove) {}\n\n\tvoid operator()(Block& _block) override;\nprivate:\n\tstd::set<Statement const*> const& m_toRemove;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/README.md",
    "content": "# Yul-Based Optimizer\n\nThe documentation of the Yul-based optimizer module has been moved to the official Solidity documentation.\n\nPlease refer to the [optimizer documentation](/docs/internals/optimizer.rst) for a description of all optimization stages and how to use the optimizer and to the [Yul documentation](/docs/yul.rst#optimization-step-sequence) for more information on the optimization step sequence and a list of abbreviations for each step."
  },
  {
    "path": "libyul/optimiser/Rematerialiser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * Optimisation stage that replaces variables by their most recently assigned expressions.\n */\n\n#include <libyul/optimiser/Rematerialiser.h>\n\n#include <libyul/optimiser/Metrics.h>\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/Exceptions.h>\n#include <libyul/AST.h>\n\n#include <range/v3/algorithm/all_of.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid Rematerialiser::run(Dialect const& _dialect, Block& _ast, std::set<YulName> _varsToAlwaysRematerialize, bool _onlySelectedVariables)\n{\n\tRematerialiser{_dialect, _ast, std::move(_varsToAlwaysRematerialize), _onlySelectedVariables}(_ast);\n}\n\nRematerialiser::Rematerialiser(\n\tDialect const& _dialect,\n\tBlock& _ast,\n\tstd::set<YulName> _varsToAlwaysRematerialize,\n\tbool _onlySelectedVariables\n):\n\tDataFlowAnalyzer(_dialect, MemoryAndStorage::Ignore),\n\tm_referenceCounts(VariableReferencesCounter::countReferences(_ast)),\n\tm_varsToAlwaysRematerialize(std::move(_varsToAlwaysRematerialize)),\n\tm_onlySelectedVariables(_onlySelectedVariables)\n{\n}\n\nvoid Rematerialiser::visit(Expression& _e)\n{\n\tif (std::holds_alternative<Identifier>(_e))\n\t{\n\t\tIdentifier& identifier = std::get<Identifier>(_e);\n\t\tYulName name = identifier.name;\n\t\tif (AssignedValue const* value = variableValue(name))\n\t\t{\n\t\t\tassertThrow(value->value, OptimizerException, \"\");\n\t\t\tsize_t refs = m_referenceCounts[name];\n\t\t\tsize_t cost = CodeCost::codeCost(m_dialect, *value->value);\n\t\t\tif (\n\t\t\t\t(\n\t\t\t\t\t!m_onlySelectedVariables && (\n\t\t\t\t\t\t(refs <= 1 && value->loopDepth == m_loopDepth) ||\n\t\t\t\t\t\tcost == 0 ||\n\t\t\t\t\t\t(refs <= 5 && cost <= 1 && m_loopDepth == 0)\n\t\t\t\t\t)\n\t\t\t\t) || m_varsToAlwaysRematerialize.count(name)\n\t\t\t)\n\t\t\t{\n\t\t\t\tassertThrow(m_referenceCounts[name] > 0, OptimizerException, \"\");\n\t\t\t\tauto variableReferences = sortedReferences(name);\n\t\t\t\tif (!variableReferences || ranges::all_of(*variableReferences, [&](auto const& ref) { return inScope(ref); }))\n\t\t\t\t{\n\t\t\t\t\t// update reference counts\n\t\t\t\t\tm_referenceCounts[name]--;\n\t\t\t\t\tfor (auto const& ref: VariableReferencesCounter::countReferences(\n\t\t\t\t\t\t*value->value\n\t\t\t\t\t))\n\t\t\t\t\t\tm_referenceCounts[ref.first] += ref.second;\n\t\t\t\t\t_e = (ASTCopier{}).translate(*value->value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tDataFlowAnalyzer::visit(_e);\n}\n\nvoid LiteralRematerialiser::visit(Expression& _e)\n{\n\tif (std::holds_alternative<Identifier>(_e))\n\t{\n\t\tIdentifier& identifier = std::get<Identifier>(_e);\n\t\tYulName name = identifier.name;\n\t\tif (AssignedValue const* value = variableValue(name))\n\t\t{\n\t\t\tassertThrow(value->value, OptimizerException, \"\");\n\t\t\tif (std::holds_alternative<Literal>(*value->value))\n\t\t\t\t_e = *value->value;\n\t\t}\n\t}\n\tDataFlowAnalyzer::visit(_e);\n}\n"
  },
  {
    "path": "libyul/optimiser/Rematerialiser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that replaces variables by their most recently assigned expressions.\n */\n\n#pragma once\n\n#include <libyul/optimiser/DataFlowAnalyzer.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Optimisation stage that replaces variable references by those expressions\n * that are most recently assigned to the referenced variables,\n * but only if the expression is movable and one of the following holds:\n *  - the variable is referenced exactly once (and definition-to-reference does not cross a loop boundary)\n *  - the value is extremely cheap (\"cost\" of zero like ``caller()``)\n *  - the variable is referenced at most 5 times and the value is rather cheap\n *    (\"cost\" of at most 1 like a constant up to 0xff) and we are not in a loop\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter.\n */\nclass Rematerialiser: public DataFlowAnalyzer\n{\npublic:\n\tstatic constexpr char const* name{\"Rematerialiser\"};\n\tstatic void run(\n\t\tOptimiserStepContext& _context,\n\t\tBlock& _ast\n\t) { run(_context.dialect, _ast); }\n\n\tstatic void run(\n\t\tDialect const& _dialect,\n\t\tBlock& _ast,\n\t\tstd::set<YulName> _varsToAlwaysRematerialize = {},\n\t\tbool _onlySelectedVariables = false\n\t);\n\nprotected:\n\tRematerialiser(\n\t\tDialect const& _dialect,\n\t\tBlock& _ast,\n\t\tstd::set<YulName> _varsToAlwaysRematerialize = {},\n\t\tbool _onlySelectedVariables = false\n\t);\n\n\tusing DataFlowAnalyzer::operator();\n\n\tusing ASTModifier::visit;\n\tvoid visit(Expression& _e) override;\n\n\tstd::map<YulName, size_t> m_referenceCounts;\n\tstd::set<YulName> m_varsToAlwaysRematerialize;\n\tbool m_onlySelectedVariables = false;\n};\n\n/**\n * If a variable is referenced that is known to have a literal\n * value at that point, replace it by a literal.\n *\n * This is mostly used so that other components do not have to rely\n * on the data flow analyzer.\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter.\n */\nclass LiteralRematerialiser: public DataFlowAnalyzer\n{\npublic:\n\tstatic constexpr char const* name{\"LiteralRematerialiser\"};\n\tstatic void run(\n\t\tOptimiserStepContext& _context,\n\t\tBlock& _ast\n\t) { LiteralRematerialiser{_context.dialect}(_ast); }\n\n\tusing ASTModifier::visit;\n\tvoid visit(Expression& _e) override;\n\nprivate:\n\tLiteralRematerialiser(Dialect const& _dialect):\n\t\tDataFlowAnalyzer(_dialect, MemoryAndStorage::Ignore)\n\t{}\n};\n\n\n}\n"
  },
  {
    "path": "libyul/optimiser/SSAReverser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libyul/optimiser/SSAReverser.h>\n#include <libyul/optimiser/Metrics.h>\n#include <libyul/AST.h>\n#include <libsolutil/CommonData.h>\n\n#include <variant>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid SSAReverser::run(OptimiserStepContext&, Block& _block)\n{\n\tAssignmentCounter assignmentCounter;\n\tassignmentCounter(_block);\n\tSSAReverser{assignmentCounter}(_block);\n}\n\nvoid SSAReverser::operator()(Block& _block)\n{\n\twalkVector(_block.statements);\n\tutil::iterateReplacingWindow<2>(\n\t\t_block.statements,\n\t\t[&](Statement& _stmt1, Statement& _stmt2) -> std::optional<std::vector<Statement>>\n\t\t{\n\t\t\tauto* varDecl = std::get_if<VariableDeclaration>(&_stmt1);\n\n\t\t\tif (!varDecl || varDecl->variables.size() != 1 || !varDecl->value)\n\t\t\t\treturn {};\n\n\t\t\t// Replaces\n\t\t\t//   let a_1 := E\n\t\t\t//   a := a_1\n\t\t\t// with\n\t\t\t//   a := E\n\t\t\t//   let a_1 := a\n\t\t\tif (auto* assignment = std::get_if<Assignment>(&_stmt2))\n\t\t\t{\n\t\t\t\tauto* identifier = std::get_if<Identifier>(assignment->value.get());\n\t\t\t\tif (\n\t\t\t\t\tassignment->variableNames.size() == 1 &&\n\t\t\t\t\tidentifier &&\n\t\t\t\t\tidentifier->name == varDecl->variables.front().name\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// in the special case a == a_1, just remove the assignment\n\t\t\t\t\tif (assignment->variableNames.front().name == identifier->name)\n\t\t\t\t\t\treturn util::make_vector<Statement>(std::move(_stmt1));\n\t\t\t\t\telse\n\t\t\t\t\t\treturn util::make_vector<Statement>(\n\t\t\t\t\t\t\tAssignment{\n\t\t\t\t\t\t\t\tstd::move(assignment->debugData),\n\t\t\t\t\t\t\t\tassignment->variableNames,\n\t\t\t\t\t\t\t\tstd::move(varDecl->value)\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tVariableDeclaration{\n\t\t\t\t\t\t\t\tstd::move(varDecl->debugData),\n\t\t\t\t\t\t\t\tstd::move(varDecl->variables),\n\t\t\t\t\t\t\t\tstd::make_unique<Expression>(assignment->variableNames.front())\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Replaces\n\t\t\t//   let a_1 := E\n\t\t\t//   let a := a_1\n\t\t\t// with\n\t\t\t//   let a := E\n\t\t\t//   let a_1 := a\n\t\t\telse if (auto* varDecl2 = std::get_if<VariableDeclaration>(&_stmt2))\n\t\t\t{\n\t\t\t\tauto* identifier = std::get_if<Identifier>(varDecl2->value.get());\n\t\t\t\tif (\n\t\t\t\t\tvarDecl2->variables.size() == 1 &&\n\t\t\t\t\tidentifier &&\n\t\t\t\t\tidentifier->name == varDecl->variables.front().name && (\n\t\t\t\t\t\tm_assignmentCounter.assignmentCount(varDecl2->variables.front().name) >\n\t\t\t\t\t\tm_assignmentCounter.assignmentCount(varDecl->variables.front().name)\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tauto varIdentifier2 = std::make_unique<Expression>(Identifier{\n\t\t\t\t\t\tvarDecl2->variables.front().debugData,\n\t\t\t\t\t\tvarDecl2->variables.front().name\n\t\t\t\t\t});\n\t\t\t\t\treturn util::make_vector<Statement>(\n\t\t\t\t\t\tVariableDeclaration{\n\t\t\t\t\t\t\tstd::move(varDecl2->debugData),\n\t\t\t\t\t\t\tstd::move(varDecl2->variables),\n\t\t\t\t\t\t\tstd::move(varDecl->value)\n\t\t\t\t\t\t},\n\t\t\t\t\t\tVariableDeclaration{\n\t\t\t\t\t\t\tstd::move(varDecl->debugData),\n\t\t\t\t\t\t\tstd::move(varDecl->variables),\n\t\t\t\t\t\t\tstd::move(varIdentifier2)\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {};\n\t\t}\n\t);\n}\n"
  },
  {
    "path": "libyul/optimiser/SSAReverser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\nnamespace solidity::yul\n{\n\nclass AssignmentCounter;\n\n/**\n * Reverses the SSA transformation.\n *\n * In particular, the SSA transform will rewrite\n *\n *     a := E\n *\n * to\n *\n *     let a_1 := E\n *     a := a_1\n *\n * To undo this kind of transformation, the SSAReverser changes this back to\n *\n *     a := E\n *     let a_1 := a\n *\n * In the special case\n *     let a := E\n *     a := a\n *\n * the redundant assignment \"a := a\" is removed.\n *\n *\n * Secondly, the SSA transform will rewrite\n *\n *     let a := E\n * to\n *\n *     let a_1 := E\n *     let a := a_1\n *\n * To undo this kind of transformation, the SSAReverser changes this back to\n *\n *     let a := E\n *     let a_1 := a\n *\n * After that the CSE can replace references of a_1 by references to a,\n * after which the unused pruner can remove the declaration of a_1.\n *\n * Prerequisites: Disambiguator\n *\n */\nclass SSAReverser: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"SSAReverser\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\texplicit SSAReverser(AssignmentCounter const& _assignmentCounter): m_assignmentCounter(_assignmentCounter) {}\n\n\tAssignmentCounter const& m_assignmentCounter;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/SSATransform.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that turns subsequent assignments to variable declarations\n * and assignments.\n */\n\n#include <libyul/optimiser/SSATransform.h>\n\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/NameDispenser.h>\n#include <libyul/AST.h>\n\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::langutil;\n\nnamespace\n{\n\n/**\n * First step of SSA transform: Introduces new SSA variables for each assignment or\n * declaration of a variable to be replaced.\n */\nclass IntroduceSSA: public ASTModifier\n{\npublic:\n\texplicit IntroduceSSA(\n\t\tNameDispenser& _nameDispenser,\n\t\tstd::set<YulName> const& _variablesToReplace\n\t):\n\t\tm_nameDispenser(_nameDispenser),\n\t\tm_variablesToReplace(_variablesToReplace)\n\t{ }\n\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\tNameDispenser& m_nameDispenser;\n\tstd::set<YulName> const& m_variablesToReplace;\n};\n\n\nvoid IntroduceSSA::operator()(Block& _block)\n{\n\tutil::iterateReplacing(\n\t\t_block.statements,\n\t\t[&](Statement& _s) -> std::optional<std::vector<Statement>>\n\t\t{\n\t\t\tif (std::holds_alternative<VariableDeclaration>(_s))\n\t\t\t{\n\t\t\t\tVariableDeclaration& varDecl = std::get<VariableDeclaration>(_s);\n\t\t\t\tif (varDecl.value)\n\t\t\t\t\tvisit(*varDecl.value);\n\n\t\t\t\tbool needToReplaceSome = false;\n\t\t\t\tfor (auto const& var: varDecl.variables)\n\t\t\t\t\tif (m_variablesToReplace.count(var.name))\n\t\t\t\t\t\tneedToReplaceSome = true;\n\t\t\t\tif (!needToReplaceSome)\n\t\t\t\t\treturn {};\n\n\t\t\t\t// Replace \"let a := v\" by \"let a_1 := v  let a := a_1\"\n\t\t\t\t// Replace \"let a, b := v\" by \"let a_1, b_1 := v  let a := a_1 let b := b_2\"\n\t\t\t\tlangutil::DebugData::ConstPtr debugData = varDecl.debugData;\n\t\t\t\tstd::vector<Statement> statements;\n\t\t\t\tstatements.emplace_back(VariableDeclaration{debugData, {}, std::move(varDecl.value)});\n\t\t\t\tNameWithDebugDataList newVariables;\n\t\t\t\tfor (auto const& var: varDecl.variables)\n\t\t\t\t{\n\t\t\t\t\tYulName oldName = var.name;\n\t\t\t\t\tYulName newName = m_nameDispenser.newName(oldName);\n\t\t\t\t\tnewVariables.emplace_back(NameWithDebugData{debugData, newName});\n\t\t\t\t\tstatements.emplace_back(VariableDeclaration{\n\t\t\t\t\t\tdebugData,\n\t\t\t\t\t\t{NameWithDebugData{debugData, oldName}},\n\t\t\t\t\t\tstd::make_unique<Expression>(Identifier{debugData, newName})\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tstd::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables);\n\t\t\t\treturn { std::move(statements) };\n\t\t\t}\n\t\t\telse if (std::holds_alternative<Assignment>(_s))\n\t\t\t{\n\t\t\t\tAssignment& assignment = std::get<Assignment>(_s);\n\t\t\t\tvisit(*assignment.value);\n\t\t\t\tfor (auto const& var: assignment.variableNames)\n\t\t\t\t\tassertThrow(m_variablesToReplace.count(var.name), OptimizerException, \"\");\n\n\t\t\t\t// Replace \"a := v\" by \"let a_1 := v  a := v\"\n\t\t\t\t// Replace \"a, b := v\" by \"let a_1, b_1 := v  a := a_1 b := b_2\"\n\t\t\t\tlangutil::DebugData::ConstPtr debugData = assignment.debugData;\n\t\t\t\tstd::vector<Statement> statements;\n\t\t\t\tstatements.emplace_back(VariableDeclaration{debugData, {}, std::move(assignment.value)});\n\t\t\t\tNameWithDebugDataList newVariables;\n\t\t\t\tfor (auto const& var: assignment.variableNames)\n\t\t\t\t{\n\t\t\t\t\tYulName oldName = var.name;\n\t\t\t\t\tYulName newName = m_nameDispenser.newName(oldName);\n\t\t\t\t\tnewVariables.emplace_back(NameWithDebugData{debugData, newName});\n\t\t\t\t\tstatements.emplace_back(Assignment{\n\t\t\t\t\t\tdebugData,\n\t\t\t\t\t\t{Identifier{debugData, oldName}},\n\t\t\t\t\t\tstd::make_unique<Expression>(Identifier{debugData, newName})\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tstd::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables);\n\t\t\t\treturn { std::move(statements) };\n\t\t\t}\n\t\t\telse\n\t\t\t\tvisit(_s);\n\t\t\treturn {};\n\t\t}\n\t);\n}\n\n/**\n * Second step of SSA transform: Introduces new SSA variables at each control-flow join\n * and at the beginning of functions.\n */\nclass IntroduceControlFlowSSA: public ASTModifier\n{\npublic:\n\texplicit IntroduceControlFlowSSA(\n\t\tNameDispenser& _nameDispenser,\n\t\tstd::set<YulName> const& _variablesToReplace\n\t):\n\t\tm_nameDispenser(_nameDispenser),\n\t\tm_variablesToReplace(_variablesToReplace)\n\t{ }\n\n\tvoid operator()(FunctionDefinition& _function) override;\n\tvoid operator()(ForLoop& _forLoop) override;\n\tvoid operator()(Switch& _switch) override;\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\tNameDispenser& m_nameDispenser;\n\tstd::set<YulName> const& m_variablesToReplace;\n\t/// Variables (that are to be replaced) currently in scope.\n\tstd::set<YulName> m_variablesInScope;\n\t/// Variables that do not have a specific value.\n\tutil::UniqueVector<YulName> m_variablesToReassign;\n};\n\nvoid IntroduceControlFlowSSA::operator()(FunctionDefinition& _function)\n{\n\tstd::set<YulName> varsInScope;\n\tstd::swap(varsInScope, m_variablesInScope);\n\tutil::UniqueVector<YulName> toReassign;\n\tstd::swap(toReassign, m_variablesToReassign);\n\n\tfor (auto const& param: _function.parameters)\n\t\tif (m_variablesToReplace.count(param.name))\n\t\t{\n\t\t\tm_variablesInScope.insert(param.name);\n\t\t\tm_variablesToReassign.pushBack(param.name);\n\t\t}\n\n\tASTModifier::operator()(_function);\n\n\tm_variablesInScope = std::move(varsInScope);\n\tm_variablesToReassign = std::move(toReassign);\n}\n\nvoid IntroduceControlFlowSSA::operator()(ForLoop& _for)\n{\n\tyulAssert(_for.pre.statements.empty(), \"For loop init rewriter not run.\");\n\n\tfor (auto const& var: assignedVariableNames(_for.body) + assignedVariableNames(_for.post))\n\t\tif (util::contains(m_variablesInScope,var))\n\t\t\tm_variablesToReassign.pushBack(var);\n\n\t(*this)(_for.body);\n\t(*this)(_for.post);\n}\n\nvoid IntroduceControlFlowSSA::operator()(Switch& _switch)\n{\n\tyulAssert(m_variablesToReassign.empty(), \"\");\n\n\tutil::UniqueVector<YulName> toReassign;\n\tfor (auto& c: _switch.cases)\n\t{\n\t\t(*this)(c.body);\n\t\ttoReassign.pushBack(m_variablesToReassign);\n\t}\n\n\tm_variablesToReassign.pushBack(toReassign);\n}\n\nvoid IntroduceControlFlowSSA::operator()(Block& _block)\n{\n\tutil::UniqueVector<YulName> variablesDeclaredHere;\n\tutil::UniqueVector<YulName> assignedVariables;\n\n\tutil::iterateReplacing(\n\t\t_block.statements,\n\t\t[&](Statement& _s) -> std::optional<std::vector<Statement>>\n\t\t{\n\t\t\tstd::vector<Statement> toPrepend;\n\t\t\tfor (YulName toReassign: m_variablesToReassign)\n\t\t\t{\n\t\t\t\tYulName newName = m_nameDispenser.newName(toReassign);\n\t\t\t\ttoPrepend.emplace_back(VariableDeclaration{\n\t\t\t\t\tdebugDataOf(_s),\n\t\t\t\t\t{NameWithDebugData{debugDataOf(_s), newName}},\n\t\t\t\t\tstd::make_unique<Expression>(Identifier{debugDataOf(_s), toReassign})\n\t\t\t\t});\n\t\t\t\tassignedVariables.pushBack(toReassign);\n\t\t\t}\n\t\t\tm_variablesToReassign.clear();\n\n\t\t\tif (std::holds_alternative<VariableDeclaration>(_s))\n\t\t\t{\n\t\t\t\tVariableDeclaration& varDecl = std::get<VariableDeclaration>(_s);\n\t\t\t\tfor (auto const& var: varDecl.variables)\n\t\t\t\t\tif (m_variablesToReplace.count(var.name))\n\t\t\t\t\t{\n\t\t\t\t\t\tvariablesDeclaredHere.pushBack(var.name);\n\t\t\t\t\t\tm_variablesInScope.insert(var.name);\n\t\t\t\t\t}\n\t\t\t}\n\t\t\telse if (std::holds_alternative<Assignment>(_s))\n\t\t\t{\n\t\t\t\tAssignment& assignment = std::get<Assignment>(_s);\n\t\t\t\tfor (auto const& var: assignment.variableNames)\n\t\t\t\t\tif (m_variablesToReplace.count(var.name))\n\t\t\t\t\t\tassignedVariables.pushBack(var.name);\n\t\t\t}\n\t\t\telse\n\t\t\t\tvisit(_s);\n\n\t\t\tif (toPrepend.empty())\n\t\t\t\treturn {};\n\t\t\telse\n\t\t\t{\n\t\t\t\ttoPrepend.emplace_back(std::move(_s));\n\t\t\t\treturn {std::move(toPrepend)};\n\t\t\t}\n\t\t}\n\t);\n\n\tm_variablesToReassign.pushBack(assignedVariables);\n\tm_variablesInScope -= variablesDeclaredHere.contents();\n\tm_variablesToReassign.removeAll(variablesDeclaredHere.contents());\n}\n\n/**\n * Third step of SSA transform: Replace the references to variables-to-be-replaced\n * by their current values.\n */\nclass PropagateValues: public ASTModifier\n{\npublic:\n\texplicit PropagateValues(std::set<YulName> const& _variablesToReplace):\n\t\tm_variablesToReplace(_variablesToReplace)\n\t{ }\n\n\tvoid operator()(Identifier& _identifier) override;\n\tvoid operator()(VariableDeclaration& _varDecl) override;\n\tvoid operator()(Assignment& _assignment) override;\n\tvoid operator()(ForLoop& _for) override;\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\t/// This is a set of all variables that are assigned to anywhere in the code.\n\t/// Variables that are only declared but never re-assigned are not touched.\n\tstd::set<YulName> const& m_variablesToReplace;\n\tstd::map<YulName, YulName> m_currentVariableValues;\n\tstd::set<YulName> m_clearAtEndOfBlock;\n};\n\nvoid PropagateValues::operator()(Identifier& _identifier)\n{\n\tif (m_currentVariableValues.count(_identifier.name))\n\t\t_identifier.name = m_currentVariableValues[_identifier.name];\n}\n\nvoid PropagateValues::operator()(VariableDeclaration& _varDecl)\n{\n\tASTModifier::operator()(_varDecl);\n\n\tif (_varDecl.variables.size() != 1)\n\t\treturn;\n\n\tYulName variable = _varDecl.variables.front().name;\n\tif (m_variablesToReplace.count(variable))\n\t{\n\t\t// `let a := a_1` - regular declaration of non-SSA variable\n\t\tyulAssert(std::holds_alternative<Identifier>(*_varDecl.value), \"\");\n\t\tm_currentVariableValues[variable] = std::get<Identifier>(*_varDecl.value).name;\n\t\tm_clearAtEndOfBlock.insert(variable);\n\t}\n\telse if (_varDecl.value && std::holds_alternative<Identifier>(*_varDecl.value))\n\t{\n\t\t// `let a_1 := a` - assignment to SSA variable after a branch.\n\t\tYulName value = std::get<Identifier>(*_varDecl.value).name;\n\t\tif (m_variablesToReplace.count(value))\n\t\t{\n\t\t\t// This is safe because `a_1` is not a \"variable to replace\" and thus\n\t\t\t// will not be re-assigned.\n\t\t\tm_currentVariableValues[value] = variable;\n\t\t\tm_clearAtEndOfBlock.insert(value);\n\t\t}\n\t}\n}\n\n\nvoid PropagateValues::operator()(Assignment& _assignment)\n{\n\tvisit(*_assignment.value);\n\n\tif (_assignment.variableNames.size() != 1)\n\t\treturn;\n\tYulName name = _assignment.variableNames.front().name;\n\tif (!m_variablesToReplace.count(name))\n\t\treturn;\n\n\tyulAssert(_assignment.value && std::holds_alternative<Identifier>(*_assignment.value), \"\");\n\tm_currentVariableValues[name] = std::get<Identifier>(*_assignment.value).name;\n\tm_clearAtEndOfBlock.insert(name);\n}\n\nvoid PropagateValues::operator()(ForLoop& _for)\n{\n\tyulAssert(_for.pre.statements.empty(), \"For loop init rewriter not run.\");\n\n\tfor (auto const& var: assignedVariableNames(_for.body) + assignedVariableNames(_for.post))\n\t\tm_currentVariableValues.erase(var);\n\n\tvisit(*_for.condition);\n\t(*this)(_for.body);\n\t(*this)(_for.post);\n}\n\nvoid PropagateValues::operator()(Block& _block)\n{\n\tstd::set<YulName> clearAtParentBlock = std::move(m_clearAtEndOfBlock);\n\tm_clearAtEndOfBlock.clear();\n\n\tASTModifier::operator()(_block);\n\n\tfor (auto const& var: m_clearAtEndOfBlock)\n\t\tm_currentVariableValues.erase(var);\n\n\tm_clearAtEndOfBlock = std::move(clearAtParentBlock);\n}\n\n}\n\nvoid SSATransform::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tstd::set<YulName> assignedVariables = assignedVariableNames(_ast);\n\tIntroduceSSA{_context.dispenser, assignedVariables}(_ast);\n\tIntroduceControlFlowSSA{_context.dispenser, assignedVariables}(_ast);\n\tPropagateValues{assignedVariables}(_ast);\n}\n\n\n"
  },
  {
    "path": "libyul/optimiser/SSATransform.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that turns subsequent assignments to variable declarations\n * and assignments.\n */\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\n#include <liblangutil/SourceLocation.h>\n\n#include <vector>\n\nnamespace solidity::yul\n{\n\nclass NameDispenser;\n\n/**\n * Optimizer stage that tries to replace repeated assignments to\n * existing variables by declarations of new variables as much as\n * possible.\n * The reassignments are still there, but all references to the\n * reassigned variables are replaced by the newly declared variables.\n *\n * Example:\n * {\n *   let a := 1\n *   mstore(a, 2)\n *   a := 3\n * }\n * is transformed to\n * {\n *   let a_1 := 1\n *   let a := a_1\n *   mstore(a_1, 2)\n *   let a_3 := 3\n *   a := a_3\n * }\n *\n * Exact semantics:\n *\n * For any variable a that is assigned to somewhere in the code (assignment with\n * declaration does not count) perform the following transforms:\n *  - replace \"let a := v\" by \"let a_1 := v   let a := a_1\"\n *  - replace \"a := v\" by \"let a_1 := v   a := a_1\"\n * Furthermore, always note the current variable/value assigned to a and replace each\n * reference to a by this variable.\n * The current value mapping is cleared for a variable a at the end of each block\n * in which it was assigned. We compensate that by appending a declaration\n * of the form of \"let a_1 := a\" right after the location where control flow joins so\n * variable references can use the SSA variable. The only exception to this rule is\n * for loop conditions, as we cannot insert a variable declaration there.\n *\n * After this stage, UnusedAssignmentEliminator is recommended to remove the unnecessary\n * intermediate assignments.\n *\n * This stage provides best results if CSE is run right before it, because\n * then it does not generate excessive amounts of variables.\n *\n * The transform is implemented in three stages. All stages are only concerned\n * with variables that are assigned somewhere in the code (excluding declarations).\n * The first stage inserts new SSA variables for each declaration and assignment of\n * such variables.\n * The second stage inserts new SSA variables at control flow joins.\n * The last stage replaces references to variables that are assigned to somewhere in the\n * code by their current SSA variable.\n *\n * TODO Which transforms are required to keep this idempotent?\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter.\n */\nclass SSATransform: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"SSATransform\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast);\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/SSAValueTracker.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that collects variables that are never assigned to and their\n * initial values.\n */\n\n#include <libyul/optimiser/SSAValueTracker.h>\n\n#include <libyul/AST.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid SSAValueTracker::operator()(Assignment const& _assignment)\n{\n\tfor (auto const& var: _assignment.variableNames)\n\t\tm_values.erase(var.name);\n}\n\nvoid SSAValueTracker::operator()(FunctionDefinition const& _funDef)\n{\n\tfor (auto const& var: _funDef.returnVariables)\n\t\tsetValue(var.name, nullptr);\n\tASTWalker::operator()(_funDef);\n}\n\nvoid SSAValueTracker::operator()(VariableDeclaration const& _varDecl)\n{\n\tif (!_varDecl.value)\n\t\tfor (auto const& var: _varDecl.variables)\n\t\t\tsetValue(var.name, nullptr);\n\telse if (_varDecl.variables.size() == 1)\n\t\tsetValue(_varDecl.variables.front().name, _varDecl.value.get());\n}\n\nstd::set<YulName> SSAValueTracker::ssaVariables(Block const& _ast)\n{\n\tSSAValueTracker t;\n\tt(_ast);\n\tstd::set<YulName> ssaVars;\n\tfor (auto const& value: t.values())\n\t\tssaVars.insert(value.first);\n\treturn ssaVars;\n}\n\nvoid SSAValueTracker::setValue(YulName _name, Expression const* _value)\n{\n\tassertThrow(\n\t\tm_values.count(_name) == 0,\n\t\tOptimizerException,\n\t\t\"Source needs to be disambiguated.\"\n\t);\n\tif (!_value)\n\t\t_value = &m_zero;\n\tm_values[_name] = _value;\n}\n"
  },
  {
    "path": "libyul/optimiser/SSAValueTracker.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that collects variables that are never assigned to and their\n * initial values.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/AST.h> // Needed for m_zero below.\n\n#include <map>\n#include <set>\n\nnamespace solidity::yul\n{\n\n/**\n * Class that walks the AST and stores the initial value of each variable\n * that is never assigned to.\n *\n * A special zero constant expression is used for the default value of variables.\n *\n * Prerequisite: Disambiguator\n */\nclass SSAValueTracker: public ASTWalker\n{\npublic:\n\tusing ASTWalker::operator();\n\tvoid operator()(FunctionDefinition const& _funDef) override;\n\tvoid operator()(VariableDeclaration const& _varDecl) override;\n\tvoid operator()(Assignment const& _assignment) override;\n\n\tstd::map<YulName, Expression const*> const& values() const { return m_values; }\n\tExpression const* value(YulName _name) const { return m_values.at(_name); }\n\n\tstatic std::set<YulName> ssaVariables(Block const& _ast);\n\nprivate:\n\tvoid setValue(YulName _name, Expression const* _value);\n\n\t/// Special expression whose address will be used in m_values.\n\t/// YulName does not need to be reset because SSAValueTracker is short-lived.\n\tExpression const m_zero{Literal{{}, LiteralKind::Number, LiteralValue(u256{0})}};\n\tstd::map<YulName, Expression const*> m_values;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/Semantics.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Specific AST walkers that collect semantical facts.\n */\n\n#include <libyul/optimiser/Semantics.h>\n\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/Exceptions.h>\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/Utilities.h>\n\n#include <libevmasm/SemanticInformation.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Algorithms.h>\n\n#include <limits>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\n\nSideEffectsCollector::SideEffectsCollector(\n\t\tDialect const& _dialect,\n\t\tExpression const& _expression,\n\t\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects\n):\n\tSideEffectsCollector(_dialect, _functionSideEffects)\n{\n\tvisit(_expression);\n}\n\nSideEffectsCollector::SideEffectsCollector(Dialect const& _dialect, Statement const& _statement):\n\tSideEffectsCollector(_dialect)\n{\n\tvisit(_statement);\n}\n\nSideEffectsCollector::SideEffectsCollector(\n\tDialect const& _dialect,\n\tBlock const& _ast,\n\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects\n):\n\tSideEffectsCollector(_dialect, _functionSideEffects)\n{\n\toperator()(_ast);\n}\n\nSideEffectsCollector::SideEffectsCollector(\n\tDialect const& _dialect,\n\tForLoop const& _ast,\n\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects\n):\n\tSideEffectsCollector(_dialect, _functionSideEffects)\n{\n\toperator()(_ast);\n}\n\nvoid SideEffectsCollector::operator()(FunctionCall const& _functionCall)\n{\n\tASTWalker::operator()(_functionCall);\n\n\tFunctionHandle functionHandle = functionNameToHandle(_functionCall.functionName);\n\tif (BuiltinFunction const* builtin = resolveBuiltinFunction(_functionCall.functionName, m_dialect))\n\t\tm_sideEffects += builtin->sideEffects;\n\telse if (m_functionSideEffects && m_functionSideEffects->count(functionHandle))\n\t\tm_sideEffects += m_functionSideEffects->at(functionHandle);\n\telse\n\t\tm_sideEffects += SideEffects::worst();\n}\n\nbool MSizeFinder::containsMSize(Dialect const& _dialect, Block const& _ast)\n{\n\tMSizeFinder finder(_dialect);\n\tfinder(_ast);\n\treturn finder.m_msizeFound;\n}\n\nbool MSizeFinder::containsMSize(Object const& _object)\n{\n\tyulAssert(_object.dialect());\n\tif (containsMSize(*_object.dialect(), _object.code()->root()))\n\t\treturn true;\n\n\tfor (std::shared_ptr<ObjectNode> const& node: _object.subObjects)\n\t\tif (auto const* object = dynamic_cast<Object const*>(node.get()))\n\t\t\tif (containsMSize(*object))\n\t\t\t\treturn true;\n\n\treturn false;\n}\n\nvoid MSizeFinder::operator()(FunctionCall const& _functionCall)\n{\n\tASTWalker::operator()(_functionCall);\n\n\tif (BuiltinFunction const* builtin = resolveBuiltinFunction(_functionCall.functionName, m_dialect))\n\t\tif (builtin->isMSize)\n\t\t\tm_msizeFound = true;\n}\n\nstd::map<FunctionHandle, SideEffects> SideEffectsPropagator::sideEffects(\n\tDialect const& _dialect,\n\tCallGraph const& _directCallGraph\n)\n{\n\t// Any loop currently makes a function non-movable, because\n\t// it could be a non-terminating loop.\n\t// The same is true for any function part of a call cycle.\n\t// In the future, we should refine that, because the property\n\t// is actually a bit different from \"not movable\".\n\n\tstd::map<FunctionHandle, SideEffects> ret;\n\tfor (auto const& function: _directCallGraph.functionsWithLoops)\n\t{\n\t\tret[function].movable = false;\n\t\tret[function].canBeRemoved = false;\n\t\tret[function].canBeRemovedIfNoMSize = false;\n\t\tret[function].cannotLoop = false;\n\t}\n\n\tfor (auto const& function: _directCallGraph.recursiveFunctions())\n\t{\n\t\tret[function].movable = false;\n\t\tret[function].canBeRemoved = false;\n\t\tret[function].canBeRemovedIfNoMSize = false;\n\t\tret[function].cannotLoop = false;\n\t}\n\n\tfor (auto const& call: _directCallGraph.functionCalls)\n\t{\n\t\tFunctionHandle funName = call.first;\n\t\tSideEffects sideEffects;\n\t\tauto _visit = [&, visited = std::set<FunctionHandle>{}](FunctionHandle _function, auto&& _recurse) mutable {\n\t\t\tif (!visited.insert(_function).second)\n\t\t\t\treturn;\n\t\t\tif (sideEffects == SideEffects::worst())\n\t\t\t\treturn;\n\t\t\tif (BuiltinHandle const* builtinHandle = std::get_if<BuiltinHandle>(&_function))\n\t\t\t\tsideEffects += _dialect.builtin(*builtinHandle).sideEffects;\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (ret.count(_function))\n\t\t\t\t\tsideEffects += ret[_function];\n\t\t\t\tfor (FunctionHandle const& callee: _directCallGraph.functionCalls.at(_function))\n\t\t\t\t\t_recurse(callee, _recurse);\n\t\t\t}\n\t\t};\n\t\tfor (auto const& _v: call.second)\n\t\t\t_visit(_v, _visit);\n\t\tret[funName] += sideEffects;\n\t}\n\treturn ret;\n}\n\nMovableChecker::MovableChecker(Dialect const& _dialect, Expression const& _expression):\n\tMovableChecker(_dialect)\n{\n\tvisit(_expression);\n}\n\nvoid MovableChecker::operator()(Identifier const& _identifier)\n{\n\tSideEffectsCollector::operator()(_identifier);\n\tm_variableReferences.emplace(_identifier.name);\n}\n\nvoid MovableChecker::visit(Statement const&)\n{\n\tassertThrow(false, OptimizerException, \"Movability for statement requested.\");\n}\n\nstd::pair<TerminationFinder::ControlFlow, size_t> TerminationFinder::firstUnconditionalControlFlowChange(\n\tstd::vector<Statement> const& _statements\n)\n{\n\tfor (size_t i = 0; i < _statements.size(); ++i)\n\t{\n\t\tControlFlow controlFlow = controlFlowKind(_statements[i]);\n\t\tif (controlFlow != ControlFlow::FlowOut)\n\t\t\treturn {controlFlow, i};\n\t}\n\treturn {ControlFlow::FlowOut, std::numeric_limits<size_t>::max()};\n}\n\nTerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement const& _statement)\n{\n\tif (\n\t\tstd::holds_alternative<VariableDeclaration>(_statement) &&\n\t\tstd::get<VariableDeclaration>(_statement).value &&\n\t\tcontainsNonContinuingFunctionCall(*std::get<VariableDeclaration>(_statement).value)\n\t)\n\t\treturn ControlFlow::Terminate;\n\telse if (\n\t\tstd::holds_alternative<Assignment>(_statement) &&\n\t\tcontainsNonContinuingFunctionCall(*std::get<Assignment>(_statement).value)\n\t)\n\t\treturn ControlFlow::Terminate;\n\telse if (\n\t\tstd::holds_alternative<ExpressionStatement>(_statement) &&\n\t\tcontainsNonContinuingFunctionCall(std::get<ExpressionStatement>(_statement).expression)\n\t)\n\t\treturn ControlFlow::Terminate;\n\telse if (std::holds_alternative<Break>(_statement))\n\t\treturn ControlFlow::Break;\n\telse if (std::holds_alternative<Continue>(_statement))\n\t\treturn ControlFlow::Continue;\n\telse if (std::holds_alternative<Leave>(_statement))\n\t\treturn ControlFlow::Leave;\n\telse\n\t\treturn ControlFlow::FlowOut;\n}\n\nbool TerminationFinder::containsNonContinuingFunctionCall(Expression const& _expr)\n{\n\tif (auto functionCall = std::get_if<FunctionCall>(&_expr))\n\t{\n\t\tfor (auto const& arg: functionCall->arguments)\n\t\t\tif (containsNonContinuingFunctionCall(arg))\n\t\t\t\treturn true;\n\n\t\tif (BuiltinFunction const* builtin = resolveBuiltinFunction(functionCall->functionName, m_dialect))\n\t\t\treturn !builtin->controlFlowSideEffects.canContinue;\n\n\t\tyulAssert(std::holds_alternative<Identifier>(functionCall->functionName));\n\t\tauto const& name = std::get<Identifier>(functionCall->functionName).name;\n\t\tif (m_functionSideEffects && m_functionSideEffects->count(name))\n\t\t\treturn !m_functionSideEffects->at(name).canContinue;\n\t}\n\treturn false;\n}\n"
  },
  {
    "path": "libyul/optimiser/Semantics.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Specific AST walkers that collect semantical facts.\n */\n\n#pragma once\n\n#include <libyul/AST.h>\n#include <libyul/Object.h>\n#include <libyul/SideEffects.h>\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/CallGraphGenerator.h>\n\n#include <set>\n\nnamespace solidity::yul\n{\nclass Dialect;\n\n/**\n * Specific AST walker that determines side-effect free-ness and movability of code.\n * Enters into function definitions.\n */\nclass SideEffectsCollector: public ASTWalker\n{\npublic:\n\texplicit SideEffectsCollector(\n\t\tDialect const& _dialect,\n\t\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects = nullptr\n\t): m_dialect(_dialect), m_functionSideEffects(_functionSideEffects) {}\n\tSideEffectsCollector(\n\t\tDialect const& _dialect,\n\t\tExpression const& _expression,\n\t\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects = nullptr\n\t);\n\tSideEffectsCollector(Dialect const& _dialect, Statement const& _statement);\n\tSideEffectsCollector(\n\t\tDialect const& _dialect,\n\t\tBlock const& _ast,\n\t\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects = nullptr\n\t);\n\tSideEffectsCollector(\n\t\tDialect const& _dialect,\n\t\tForLoop const& _ast,\n\t\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects = nullptr\n\t);\n\n\tusing ASTWalker::operator();\n\tvoid operator()(FunctionCall const& _functionCall) override;\n\n\tbool movable() const { return m_sideEffects.movable; }\n\n\tbool movableRelativeTo(SideEffects const& _other, bool _codeContainsMSize)\n\t{\n\t\tif (!m_sideEffects.cannotLoop)\n\t\t\treturn false;\n\n\t\tif (m_sideEffects.movable)\n\t\t\treturn true;\n\n\t\tif (\n\t\t\t!m_sideEffects.movableApartFromEffects ||\n\t\t\tm_sideEffects.storage == SideEffects::Write ||\n\t\t\tm_sideEffects.otherState == SideEffects::Write ||\n\t\t\tm_sideEffects.memory == SideEffects::Write ||\n\t\t\tm_sideEffects.transientStorage == SideEffects::Write\n\t\t)\n\t\t\treturn false;\n\n\t\tif (m_sideEffects.otherState == SideEffects::Read)\n\t\t\tif (_other.otherState == SideEffects::Write)\n\t\t\t\treturn false;\n\n\t\tif (m_sideEffects.storage == SideEffects::Read)\n\t\t\tif (_other.storage == SideEffects::Write)\n\t\t\t\treturn false;\n\n\t\tif (m_sideEffects.memory == SideEffects::Read)\n\t\t\tif (_codeContainsMSize || _other.memory == SideEffects::Write)\n\t\t\t\treturn false;\n\n\t\tif (m_sideEffects.transientStorage == SideEffects::Read)\n\t\t\tif (_other.transientStorage == SideEffects::Write)\n\t\t\t\treturn false;\n\n\t\treturn true;\n\t}\n\n\tbool canBeRemoved(bool _allowMSizeModification = false) const\n\t{\n\t\tif (_allowMSizeModification)\n\t\t\treturn m_sideEffects.canBeRemovedIfNoMSize;\n\t\telse\n\t\t\treturn m_sideEffects.canBeRemoved;\n\t}\n\tbool cannotLoop() const { return m_sideEffects.cannotLoop; }\n\tbool invalidatesStorage() const { return m_sideEffects.storage == SideEffects::Write; }\n\tbool invalidatesMemory() const { return m_sideEffects.memory == SideEffects::Write; }\n\n\tSideEffects sideEffects() { return m_sideEffects; }\n\nprivate:\n\tDialect const& m_dialect;\n\tstd::map<FunctionHandle, SideEffects> const* m_functionSideEffects = nullptr;\n\tSideEffects m_sideEffects;\n};\n\n/**\n * This class can be used to determine the side-effects of user-defined functions.\n *\n * It is given a dialect and a mapping that represents the direct calls from user-defined\n * functions to other user-defined functions and built-in functions.\n */\nclass SideEffectsPropagator\n{\npublic:\n\tstatic std::map<FunctionHandle, SideEffects> sideEffects(\n\t\tDialect const& _dialect,\n\t\tCallGraph const& _directCallGraph\n\t);\n};\n\n/**\n * Class that can be used to find out if certain code contains the MSize instruction\n * or a verbatim bytecode builtin (which is always assumed that it could contain MSize).\n *\n * Note that this is a purely syntactic property meaning that even if this is false,\n * the code can still contain calls to functions that contain the msize instruction.\n *\n * The only safe way to determine this is by passing the full AST.\n */\nclass MSizeFinder: public ASTWalker\n{\npublic:\n\tstatic bool containsMSize(Dialect const& _dialect, Block const& _ast);\n\tstatic bool containsMSize(Object const& _object);\n\n\tusing ASTWalker::operator();\n\tvoid operator()(FunctionCall const& _funCall) override;\n\nprivate:\n\tMSizeFinder(Dialect const& _dialect): m_dialect(_dialect) {}\n\tDialect const& m_dialect;\n\tbool m_msizeFound = false;\n};\n\n/**\n * Class that can be used to find out if the given function contains the ``leave`` statement.\n *\n * Returns true even in the case where the function definition contains another function definition\n * that contains the leave statement.\n */\nclass LeaveFinder: public ASTWalker\n{\npublic:\n\tstatic bool containsLeave(FunctionDefinition const& _fun)\n\t{\n\t\tLeaveFinder f;\n\t\tf(_fun);\n\t\treturn f.m_leaveFound;\n\t}\n\n\tusing ASTWalker::operator();\n\tvoid operator()(Leave const&) override { m_leaveFound = true; }\n\nprivate:\n\tLeaveFinder() = default;\n\n\tbool m_leaveFound = false;\n};\n\n/**\n * Specific AST walker that determines whether an expression is movable\n * and collects the referenced variables.\n * Can only be used on expressions.\n */\nclass MovableChecker: public SideEffectsCollector\n{\npublic:\n\texplicit MovableChecker(\n\t\tDialect const& _dialect,\n\t\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects = nullptr\n\t): SideEffectsCollector(_dialect, _functionSideEffects) {}\n\tMovableChecker(Dialect const& _dialect, Expression const& _expression);\n\n\tvoid operator()(Identifier const& _identifier) override;\n\n\t/// Disallow visiting anything apart from Expressions (this throws).\n\tvoid visit(Statement const&) override;\n\tusing ASTWalker::visit;\n\n\tstd::set<YulName> const& referencedVariables() const { return m_variableReferences; }\n\nprivate:\n\t/// Which variables the current expression references.\n\tstd::set<YulName> m_variableReferences;\n};\n\nstruct ControlFlowSideEffects;\n\n/**\n * Helper class to find \"irregular\" control flow.\n * This includes termination, break, continue and leave.\n * In general, it is applied only to \"simple\" statements. The control-flow\n * of loops, switches and if statements is always \"FlowOut\" with the assumption\n * that the caller will descend into them.\n */\nclass TerminationFinder\n{\npublic:\n\t/// \"Terminate\" here means that there is no continuing control-flow.\n\t/// If this is applied to a function that can revert or stop, but can also\n\t/// exit regularly, the property is set to \"FlowOut\".\n\tenum class ControlFlow { FlowOut, Break, Continue, Terminate, Leave };\n\n\tTerminationFinder(\n\t\tDialect const& _dialect,\n\t\tstd::map<YulName, ControlFlowSideEffects> const* _functionSideEffects = nullptr\n\t): m_dialect(_dialect), m_functionSideEffects(_functionSideEffects) {}\n\n\t/// @returns the index of the first statement in the provided sequence\n\t/// that is an unconditional ``break``, ``continue``, ``leave`` or a\n\t/// call to a terminating function.\n\t/// If control flow can continue at the end of the list,\n\t/// returns `FlowOut` and ``size_t(-1)``.\n\t/// The function might return ``FlowOut`` even though control\n\t/// flow cannot actually continue.\n\tstd::pair<ControlFlow, size_t> firstUnconditionalControlFlowChange(\n\t\tstd::vector<Statement> const& _statements\n\t);\n\n\t/// @returns the control flow type of the given statement.\n\t/// This function could return FlowOut even if control flow never continues.\n\tControlFlow controlFlowKind(Statement const& _statement);\n\n\t/// @returns true if the expression contains a\n\t/// call to a terminating function, i.e. a function that does not have\n\t/// a regular \"flow out\" control-flow (it might also be recursive).\n\tbool containsNonContinuingFunctionCall(Expression const& _expr);\n\nprivate:\n\tDialect const& m_dialect;\n\tstd::map<YulName, ControlFlowSideEffects> const* m_functionSideEffects;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/SimplificationRules.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Module for applying replacement rules against Expressions.\n */\n\n#include <libyul/optimiser/SimplificationRules.h>\n\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/optimiser/DataFlowAnalyzer.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/SyntacticalEquality.h>\n\n#include <libevmasm/RuleList.h>\n#include <libsolutil/StringUtils.h>\n\nusing namespace solidity;\nusing namespace solidity::evmasm;\nusing namespace solidity::langutil;\nusing namespace solidity::yul;\n\nSimplificationRules::Rule const* SimplificationRules::findFirstMatch(\n\tExpression const& _expr,\n\tDialect const& _dialect,\n\tstd::function<AssignedValue const*(YulName)> const& _ssaValues\n)\n{\n\tauto instruction = instructionAndArguments(_dialect, _expr);\n\tif (!instruction)\n\t\treturn nullptr;\n\n\tstatic std::map<std::optional<EVMVersion>, std::unique_ptr<SimplificationRules>> evmRules;\n\n\tstd::optional<EVMVersion> version;\n\tif (yul::EVMDialect const* evmDialect = dynamic_cast<yul::EVMDialect const*>(&_dialect))\n\t\tversion = evmDialect->evmVersion();\n\n\tif (!evmRules[version])\n\t\tevmRules[version] = std::make_unique<SimplificationRules>(version);\n\n\tSimplificationRules& rules = *evmRules[version];\n\tassertThrow(rules.isInitialized(), OptimizerException, \"Rule list not properly initialized.\");\n\n\tfor (auto const& rule: rules.m_rules[uint8_t(instruction->first)])\n\t{\n\t\trules.resetMatchGroups();\n\t\tif (rule.pattern.matches(_expr, _dialect, _ssaValues))\n\t\t\tif (!rule.feasible || rule.feasible())\n\t\t\t\treturn &rule;\n\t}\n\treturn nullptr;\n}\n\nbool SimplificationRules::isInitialized() const\n{\n\treturn !m_rules[uint8_t(evmasm::Instruction::ADD)].empty();\n}\n\nstd::optional<std::pair<evmasm::Instruction, std::vector<Expression> const*>>\n\tSimplificationRules::instructionAndArguments(Dialect const& _dialect, Expression const& _expr)\n{\n\tif (std::holds_alternative<FunctionCall>(_expr))\n\t\tif (auto const* dialect = dynamic_cast<EVMDialect const*>(&_dialect))\n\t\t\tif (auto const* builtin = resolveBuiltinFunctionForEVM(std::get<FunctionCall>(_expr).functionName, *dialect))\n\t\t\t\tif (builtin->instruction)\n\t\t\t\t\treturn std::make_pair(*builtin->instruction, &std::get<FunctionCall>(_expr).arguments);\n\n\treturn {};\n}\n\nvoid SimplificationRules::addRules(std::vector<Rule> const& _rules)\n{\n\tfor (auto const& r: _rules)\n\t\taddRule(r);\n}\n\nvoid SimplificationRules::addRule(Rule const& _rule)\n{\n\tm_rules[uint8_t(_rule.pattern.instruction())].push_back(_rule);\n}\n\nSimplificationRules::SimplificationRules(std::optional<langutil::EVMVersion> _evmVersion)\n{\n\t// Multiple occurrences of one of these inside one rule must match the same equivalence class.\n\t// Constants.\n\tPattern A(PatternKind::Constant);\n\tPattern B(PatternKind::Constant);\n\tPattern C(PatternKind::Constant);\n\t// Anything.\n\tPattern W;\n\tPattern X;\n\tPattern Y;\n\tPattern Z;\n\tA.setMatchGroup(1, m_matchGroups);\n\tB.setMatchGroup(2, m_matchGroups);\n\tC.setMatchGroup(3, m_matchGroups);\n\tW.setMatchGroup(4, m_matchGroups);\n\tX.setMatchGroup(5, m_matchGroups);\n\tY.setMatchGroup(6, m_matchGroups);\n\tZ.setMatchGroup(7, m_matchGroups);\n\n\taddRules(simplificationRuleList(_evmVersion, A, B, C, W, X, Y, Z));\n\tassertThrow(isInitialized(), OptimizerException, \"Rule list not properly initialized.\");\n}\n\nyul::Pattern::Pattern(evmasm::Instruction _instruction, std::initializer_list<Pattern> _arguments):\n\tm_kind(PatternKind::Operation),\n\tm_instruction(_instruction),\n\tm_arguments(_arguments)\n{\n}\n\nvoid Pattern::setMatchGroup(unsigned _group, std::map<unsigned, Expression const*>& _matchGroups)\n{\n\tm_matchGroup = _group;\n\tm_matchGroups = &_matchGroups;\n}\n\nbool Pattern::matches(\n\tExpression const& _expr,\n\tDialect const& _dialect,\n\tstd::function<AssignedValue const*(YulName)> const& _ssaValues\n) const\n{\n\tExpression const* expr = &_expr;\n\n\t// Resolve the variable if possible.\n\t// Do not do it for \"Any\" because we can check identity better for variables.\n\tif (m_kind != PatternKind::Any && std::holds_alternative<Identifier>(_expr))\n\t{\n\t\tYulName varName = std::get<Identifier>(_expr).name;\n\t\tif (AssignedValue const* value = _ssaValues(varName))\n\t\t\tif (Expression const* new_expr = value->value)\n\t\t\t\texpr = new_expr;\n\t}\n\tassertThrow(expr, OptimizerException, \"\");\n\n\tif (m_kind == PatternKind::Constant)\n\t{\n\t\tif (!std::holds_alternative<Literal>(*expr))\n\t\t\treturn false;\n\t\tLiteral const& literal = std::get<Literal>(*expr);\n\t\tif (literal.kind != LiteralKind::Number)\n\t\t\treturn false;\n\t\tif (m_data && *m_data != literal.value.value())\n\t\t\treturn false;\n\t\tassertThrow(m_arguments.empty(), OptimizerException, \"\");\n\t}\n\telse if (m_kind == PatternKind::Operation)\n\t{\n\t\tauto instrAndArgs = SimplificationRules::instructionAndArguments(_dialect, *expr);\n\t\tif (!instrAndArgs || m_instruction != instrAndArgs->first)\n\t\t\treturn false;\n\t\tassertThrow(m_arguments.size() == instrAndArgs->second->size(), OptimizerException, \"\");\n\t\tfor (size_t i = 0; i < m_arguments.size(); ++i)\n\t\t{\n\t\t\tExpression const& arg = instrAndArgs->second->at(i);\n\t\t\t// If this is a direct function call instead of a variable or literal,\n\t\t\t// we reject the match because side-effects could prevent us from\n\t\t\t// arbitrarily modifying the code.\n\t\t\tif (\n\t\t\t\tstd::holds_alternative<FunctionCall>(arg) ||\n\t\t\t\t!m_arguments[i].matches(arg, _dialect, _ssaValues)\n\t\t\t)\n\t\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t{\n\t\tassertThrow(m_arguments.empty(), OptimizerException, \"\\\"Any\\\" should not have arguments.\");\n\t\tassertThrow(!std::holds_alternative<FunctionCall>(*expr), OptimizerException, \"\\\"Any\\\" at top-level.\");\n\t}\n\n\tif (m_matchGroup)\n\t{\n\t\t// We support matching multiple expressions that require the same value\n\t\t// based on identical ASTs, which have to be movable.\n\n\t\t// TODO: add tests:\n\t\t// - { let x := mload(0) let y := and(x, x) }\n\t\t// - { let x := 4 let y := and(x, y) }\n\n\t\t// This code uses `_expr` again for \"Any\", because we want the comparison to be done\n\t\t// on the variables and not their values.\n\t\t// The assumption is that CSE or local value numbering has been done prior to this step.\n\n\t\tif (m_matchGroups->count(m_matchGroup))\n\t\t{\n\t\t\tassertThrow(m_kind == PatternKind::Any, OptimizerException, \"Match group repetition for non-any.\");\n\t\t\tExpression const* firstMatch = (*m_matchGroups)[m_matchGroup];\n\t\t\tassertThrow(firstMatch, OptimizerException, \"Match set but to null.\");\n\t\t\tassertThrow(\n\t\t\t\t!std::holds_alternative<FunctionCall>(_expr) &&\n\t\t\t\t!std::holds_alternative<FunctionCall>(*firstMatch),\n\t\t\t\tOptimizerException,\n\t\t\t\t\"Group matches have to be literals or variables.\"\n\t\t\t);\n\n\t\t\treturn SyntacticallyEqual{}(*firstMatch, _expr);\n\t\t}\n\t\telse if (m_kind == PatternKind::Any)\n\t\t\t(*m_matchGroups)[m_matchGroup] = &_expr;\n\t\telse\n\t\t{\n\t\t\tassertThrow(m_kind == PatternKind::Constant, OptimizerException, \"Match group set for operation.\");\n\t\t\t// We do not use _expr here, because we want the actual number.\n\t\t\t(*m_matchGroups)[m_matchGroup] = expr;\n\t\t}\n\t}\n\treturn true;\n}\n\nevmasm::Instruction Pattern::instruction() const\n{\n\tassertThrow(m_kind == PatternKind::Operation, OptimizerException, \"\");\n\treturn m_instruction;\n}\n\nExpression Pattern::toExpression(langutil::DebugData::ConstPtr const& _debugData, EVMDialect const& _dialect) const\n{\n\tif (matchGroup())\n\t\treturn ASTCopier().translate(matchGroupValue());\n\tif (m_kind == PatternKind::Constant)\n\t{\n\t\tassertThrow(m_data, OptimizerException, \"No match group and no constant value given.\");\n\t\treturn Literal{_debugData, LiteralKind::Number, LiteralValue{*m_data, formatNumber(*m_data)}};\n\t}\n\telse if (m_kind == PatternKind::Operation)\n\t{\n\t\tstd::vector<Expression> arguments;\n\t\tfor (auto const& arg: m_arguments)\n\t\t\targuments.emplace_back(arg.toExpression(_debugData, _dialect));\n\n\t\tif (!m_instructionBuiltinHandle)\n\t\t{\n\t\t\tstd::string name = util::toLower(instructionInfo(m_instruction, _dialect.evmVersion()).name);\n\t\t\tstd::optional<BuiltinHandle> handle = _dialect.findBuiltin(name);\n\t\t\tyulAssert(handle);\n\t\t\tm_instructionBuiltinHandle = *handle;\n\t\t}\n\n\t\treturn FunctionCall{_debugData,\n\t\t\tBuiltinName{_debugData, *m_instructionBuiltinHandle},\n\t\t\tstd::move(arguments)\n\t\t};\n\t}\n\tassertThrow(false, OptimizerException, \"Pattern of kind 'any', but no match group.\");\n}\n\nu256 Pattern::d() const\n{\n\treturn std::get<Literal>(matchGroupValue()).value.value();\n}\n\nExpression const& Pattern::matchGroupValue() const\n{\n\tassertThrow(m_matchGroup > 0, OptimizerException, \"\");\n\tassertThrow(!!m_matchGroups, OptimizerException, \"\");\n\tassertThrow((*m_matchGroups)[m_matchGroup], OptimizerException, \"\");\n\treturn *(*m_matchGroups)[m_matchGroup];\n}\n"
  },
  {
    "path": "libyul/optimiser/SimplificationRules.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Module for applying replacement rules against Expressions.\n */\n\n#pragma once\n\n#include <libevmasm/SimplificationRule.h>\n\n#include <libyul/ASTForward.h>\n#include <libyul/Builtins.h>\n#include <libyul/YulName.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Numeric.h>\n\n#include <liblangutil/EVMVersion.h>\n#include <liblangutil/DebugData.h>\n\n#include <functional>\n#include <optional>\n#include <vector>\n\nnamespace solidity::yul\n{\nstruct AssignedValue;\nclass Dialect;\nclass EVMDialect;\nclass Pattern;\n\nusing DebugData = langutil::DebugData;\n\n/**\n * Container for all simplification rules.\n */\nclass SimplificationRules\n{\npublic:\n\t/// Noncopiable.\n\tSimplificationRules(SimplificationRules const&) = delete;\n\tSimplificationRules& operator=(SimplificationRules const&) = delete;\n\n\tusing Rule = evmasm::SimplificationRule<Pattern>;\n\n\texplicit SimplificationRules(std::optional<langutil::EVMVersion> _evmVersion = std::nullopt);\n\n\t/// @returns a pointer to the first matching pattern and sets the match\n\t/// groups accordingly.\n\t/// @param _ssaValues values of variables that are assigned exactly once.\n\tstatic Rule const* findFirstMatch(\n\t\tExpression const& _expr,\n\t\tDialect const& _dialect,\n\t\tstd::function<AssignedValue const*(YulName)> const& _ssaValues\n\t);\n\n\t/// Checks whether the rulelist is non-empty. This is usually enforced\n\t/// by the constructor, but we had some issues with static initialization.\n\tbool isInitialized() const;\n\n\tstatic std::optional<std::pair<evmasm::Instruction, std::vector<Expression> const*>>\n\tinstructionAndArguments(Dialect const& _dialect, Expression const& _expr);\n\nprivate:\n\tvoid addRules(std::vector<Rule> const& _rules);\n\tvoid addRule(Rule const& _rule);\n\n\tvoid resetMatchGroups() { m_matchGroups.clear(); }\n\n\tstd::map<unsigned, Expression const*> m_matchGroups;\n\tstd::vector<evmasm::SimplificationRule<Pattern>> m_rules[256];\n};\n\nenum class PatternKind\n{\n\tOperation,\n\tConstant,\n\tAny\n};\n\n/**\n * Pattern to match against an expression.\n * Also stores matched expressions to retrieve them later, for constructing new expressions using\n * ExpressionTemplate.\n */\nclass Pattern\n{\npublic:\n\tusing Builtins = evmasm::EVMBuiltins<Pattern>;\n\tstatic constexpr size_t WordSize = 256;\n\tusing Word = u256;\n\n\t/// Matches any expression.\n\tPattern(PatternKind _kind = PatternKind::Any): m_kind(_kind) {}\n\t// Matches a specific constant value.\n\tPattern(unsigned _value): Pattern(u256(_value)) {}\n\tPattern(int _value): Pattern(u256(_value)) {}\n\tPattern(long unsigned _value): Pattern(u256(_value)) {}\n\t// Matches a specific constant value.\n\tPattern(u256 const& _value): m_kind(PatternKind::Constant), m_data(std::make_shared<u256>(_value)) {}\n\t// Matches a given instruction with given arguments\n\tPattern(evmasm::Instruction _instruction, std::initializer_list<Pattern> _arguments = {});\n\t/// Sets this pattern to be part of the match group with the identifier @a _group.\n\t/// Inside one rule, all patterns in the same match group have to match expressions from the\n\t/// same expression equivalence class.\n\tvoid setMatchGroup(unsigned _group, std::map<unsigned, Expression const*>& _matchGroups);\n\tunsigned matchGroup() const { return m_matchGroup; }\n\tbool matches(\n\t\tExpression const& _expr,\n\t\tDialect const& _dialect,\n\t\tstd::function<AssignedValue const*(YulName)> const& _ssaValues\n\t) const;\n\n\tstd::vector<Pattern> arguments() const { return m_arguments; }\n\n\t/// @returns the data of the matched expression if this pattern is part of a match group.\n\tu256 d() const;\n\n\tevmasm::Instruction instruction() const;\n\n\t/// Turns this pattern into an actual expression. Should only be called\n\t/// for patterns resulting from an action, i.e. with match groups assigned.\n\tExpression toExpression(langutil::DebugData::ConstPtr const& _debugData, EVMDialect const& _dialect) const;\n\nprivate:\n\tExpression const& matchGroupValue() const;\n\n\tPatternKind m_kind = PatternKind::Any;\n\tevmasm::Instruction m_instruction; ///< Only valid if m_kind is Operation\n\tstd::optional<BuiltinHandle> mutable m_instructionBuiltinHandle; ///< Builtin handle cache for instructions\n\tstd::shared_ptr<u256> m_data; ///< Only valid if m_kind is Constant\n\tstd::vector<Pattern> m_arguments;\n\tunsigned m_matchGroup = 0;\n\tstd::map<unsigned, Expression const*>* m_matchGroups = nullptr;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/StackCompressor.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * Optimisation stage that aggressively rematerializes certain variables in a function to free\n * space on the stack until it is compilable.\n */\n\n#include <libyul/optimiser/StackCompressor.h>\n\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/Rematerialiser.h>\n#include <libyul/optimiser/UnusedPruner.h>\n#include <libyul/optimiser/Metrics.h>\n#include <libyul/optimiser/Semantics.h>\n\n#include <libyul/backends/evm/ControlFlowGraphBuilder.h>\n#include <libyul/backends/evm/StackHelpers.h>\n#include <libyul/backends/evm/StackLayoutGenerator.h>\n\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AsmAnalysisInfo.h>\n\n#include <libyul/CompilabilityChecker.h>\n\n#include <libyul/AST.h>\n\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nnamespace\n{\n\n/**\n * Class that discovers all variables that can be fully eliminated by rematerialization,\n * and the corresponding approximate costs.\n *\n * Prerequisite: Disambiguator, Function Grouper\n */\nclass RematCandidateSelector: public DataFlowAnalyzer\n{\npublic:\n\texplicit RematCandidateSelector(Dialect const& _dialect): DataFlowAnalyzer(_dialect, MemoryAndStorage::Ignore) {}\n\n\t/// @returns a map from function name to rematerialisation costs to a vector of variables to rematerialise\n\t/// and variables that occur in their expression.\n\t/// While the map is sorted by cost, the contained vectors are sorted by the order of occurrence.\n\tstd::map<YulName, std::map<size_t, std::vector<YulName>>> candidates()\n\t{\n\t\tstd::map<YulName, std::map<size_t, std::vector<YulName>>> cand;\n\t\tfor (auto const& [functionName, candidate]: m_candidates)\n\t\t{\n\t\t\tif (size_t const* cost = util::valueOrNullptr(m_expressionCodeCost, candidate))\n\t\t\t{\n\t\t\t\tsize_t numRef = m_numReferences[candidate];\n\t\t\t\tcand[functionName][*cost * numRef].emplace_back(candidate);\n\t\t\t}\n\t\t}\n\t\treturn cand;\n\t}\n\n\tusing DataFlowAnalyzer::operator();\n\tvoid operator()(FunctionDefinition& _function) override\n\t{\n\t\tyulAssert(m_currentFunctionName.empty());\n\t\tm_currentFunctionName = _function.name;\n\t\tDataFlowAnalyzer::operator()(_function);\n\t\tm_currentFunctionName = {};\n\t}\n\n\tvoid operator()(VariableDeclaration& _varDecl) override\n\t{\n\t\tDataFlowAnalyzer::operator()(_varDecl);\n\t\tif (_varDecl.variables.size() == 1)\n\t\t{\n\t\t\tYulName varName = _varDecl.variables.front().name;\n\t\t\tif (AssignedValue const* value = variableValue(varName))\n\t\t\t{\n\t\t\t\tyulAssert(!m_expressionCodeCost.count(varName), \"\");\n\t\t\t\tm_candidates.emplace_back(m_currentFunctionName, varName);\n\t\t\t\tm_expressionCodeCost[varName] = CodeCost::codeCost(m_dialect, *value->value);\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid operator()(Assignment& _assignment) override\n\t{\n\t\tfor (auto const& var: _assignment.variableNames)\n\t\t\trematImpossible(var.name);\n\t\tDataFlowAnalyzer::operator()(_assignment);\n\t}\n\n\t// We use visit(Expression) because operator()(Identifier) would also\n\t// get called on left-hand-sides of assignments.\n\tvoid visit(Expression& _e) override\n\t{\n\t\tif (std::holds_alternative<Identifier>(_e))\n\t\t{\n\t\t\tYulName name = std::get<Identifier>(_e).name;\n\t\t\tif (m_expressionCodeCost.count(name))\n\t\t\t{\n\t\t\t\tif (!variableValue(name))\n\t\t\t\t\trematImpossible(name);\n\t\t\t\telse\n\t\t\t\t\t++m_numReferences[name];\n\t\t\t}\n\t\t}\n\t\tDataFlowAnalyzer::visit(_e);\n\t}\n\n\t/// Remove the variable from the candidate set.\n\tvoid rematImpossible(YulName _variable)\n\t{\n\t\tm_numReferences.erase(_variable);\n\t\tm_expressionCodeCost.erase(_variable);\n\t}\n\n\tYulName m_currentFunctionName = {};\n\n\t/// All candidate variables by function name, in order of occurrence.\n\tstd::vector<std::pair<YulName, YulName>> m_candidates;\n\t/// Candidate variables and the code cost of their value.\n\tstd::map<YulName, size_t> m_expressionCodeCost;\n\t/// Number of references to each candidate variable.\n\tstd::map<YulName, size_t> m_numReferences;\n};\n\n/// Selects at most @a _numVariables among @a _candidates.\nstd::set<YulName> chooseVarsToEliminate(\n\tstd::map<size_t, std::vector<YulName>> const& _candidates,\n\tsize_t _numVariables\n)\n{\n\tstd::set<YulName> varsToEliminate;\n\tfor (auto&& [cost, candidates]: _candidates)\n\t\tfor (auto&& candidate: candidates)\n\t\t{\n\t\t\tif (varsToEliminate.size() >= _numVariables)\n\t\t\t\treturn varsToEliminate;\n\t\t\tvarsToEliminate.insert(candidate);\n\t\t}\n\treturn varsToEliminate;\n}\n\nvoid eliminateVariables(\n\tDialect const& _dialect,\n\tBlock& _ast,\n\tstd::map<YulName, int> const& _numVariables,\n\tbool _allowMSizeOptimization\n)\n{\n\tRematCandidateSelector selector{_dialect};\n\tselector(_ast);\n\tstd::map<YulName, std::map<size_t, std::vector<YulName>>> candidates = selector.candidates();\n\n\tstd::set<YulName> varsToEliminate;\n\tfor (auto const& [functionName, numVariables]: _numVariables)\n\t{\n\t\tyulAssert(numVariables > 0);\n\t\tvarsToEliminate += chooseVarsToEliminate(candidates[functionName], static_cast<size_t>(numVariables));\n\t}\n\n\tRematerialiser::run(_dialect, _ast, std::move(varsToEliminate));\n\t// Do not remove functions.\n\tstd::set<YulName> allFunctions = NameCollector{_ast, NameCollector::OnlyFunctions}.names();\n\tUnusedPruner::runUntilStabilised(_dialect, _ast, _allowMSizeOptimization, nullptr, allFunctions);\n}\n\nvoid eliminateVariablesOptimizedCodegen(\n\tDialect const& _dialect,\n\tBlock& _ast,\n\tstd::map<YulName, std::vector<StackLayoutGenerator::StackTooDeep>> const& _unreachables,\n\tbool _allowMSizeOptimization\n)\n{\n\tif (std::all_of(_unreachables.begin(), _unreachables.end(), [](auto const& _item) { return _item.second.empty(); }))\n\t\treturn;\n\n\tRematCandidateSelector selector{_dialect};\n\tselector(_ast);\n\n\tstd::map<YulName, size_t> candidates;\n\tfor (auto const& [functionName, candidatesInFunction]: selector.candidates())\n\t\tfor (auto [cost, candidatesWithCost]: candidatesInFunction)\n\t\t\tfor (auto candidate: candidatesWithCost)\n\t\t\t\tcandidates[candidate] = cost;\n\n\tstd::set<YulName> varsToEliminate;\n\n\t// TODO: this currently ignores the fact that variables may reference other variables we want to eliminate.\n\tfor (auto const& [functionName, unreachables]: _unreachables)\n\t\tfor (auto const& unreachable: unreachables)\n\t\t{\n\t\t\tstd::map<size_t, std::vector<YulName>> suitableCandidates;\n\t\t\tsize_t neededSlots = unreachable.deficit;\n\t\t\tfor (auto varName: unreachable.variableChoices)\n\t\t\t{\n\t\t\t\tif (varsToEliminate.count(varName))\n\t\t\t\t\t--neededSlots;\n\t\t\t\telse if (size_t* cost = util::valueOrNullptr(candidates, varName))\n\t\t\t\t\tif (!util::contains(suitableCandidates[*cost], varName))\n\t\t\t\t\t\tsuitableCandidates[*cost].emplace_back(varName);\n\t\t\t}\n\t\t\tfor (auto candidatesByCost: suitableCandidates)\n\t\t\t{\n\t\t\t\tfor (auto candidate: candidatesByCost.second)\n\t\t\t\t\tif (neededSlots--)\n\t\t\t\t\t\tvarsToEliminate.emplace(candidate);\n\t\t\t\t\telse\n\t\t\t\t\t\tbreak;\n\t\t\t\tif (!neededSlots)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\tRematerialiser::run(_dialect, _ast, std::move(varsToEliminate), true);\n\t// Do not remove functions.\n\tstd::set<YulName> allFunctions = NameCollector{_ast, NameCollector::OnlyFunctions}.names();\n\tUnusedPruner::runUntilStabilised(_dialect, _ast, _allowMSizeOptimization, nullptr, allFunctions);\n}\n\n}\n\nstd::tuple<bool, Block> StackCompressor::run(\n\tObject const& _object,\n\tbool _optimizeStackAllocation,\n\tsize_t _maxIterations)\n{\n\tyulAssert(_object.hasCode());\n\tyulAssert(_object.dialect(), \"No dialect\");\n\tyulAssert(\n\t\t!_object.code()->root().statements.empty() && std::holds_alternative<Block>(_object.code()->root().statements.at(0)),\n\t\t\"Need to run the function grouper before the stack compressor.\"\n\t);\n\tbool usesOptimizedCodeGenerator = false;\n\tauto evmDialect = dynamic_cast<EVMDialect const*>(_object.dialect());\n\tif (evmDialect)\n\t{\n\t\tyulAssert(!evmDialect->eofVersion().has_value(), \"StackCompressor does not support EOF.\");\n\t\tusesOptimizedCodeGenerator =\n\t\t\t_optimizeStackAllocation &&\n\t\t\tevmDialect->evmVersion().canOverchargeGasForCall() &&\n\t\t\tevmDialect->providesObjectAccess();\n\t}\n\tbool allowMSizeOptimization = !MSizeFinder::containsMSize(*_object.dialect(), _object.code()->root());\n\tBlock astRoot = std::get<Block>(ASTCopier{}(_object.code()->root()));\n\tif (usesOptimizedCodeGenerator)\n\t{\n\t\tyul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(\n\t\t\t*_object.dialect(),\n\t\t\tastRoot,\n\t\t\t_object.summarizeStructure()\n\t\t);\n\t\tstd::unique_ptr<CFG> cfg = ControlFlowGraphBuilder::build(analysisInfo, *_object.dialect(), astRoot);\n\t\tyulAssert(evmDialect);\n\t\teliminateVariablesOptimizedCodegen(\n\t\t\t*_object.dialect(),\n\t\t\tastRoot,\n\t\t\tStackLayoutGenerator::reportStackTooDeep(*cfg, *evmDialect),\n\t\t\tallowMSizeOptimization\n\t\t);\n\t}\n\telse\n\t{\n\t\tfor (size_t iterations = 0; iterations < _maxIterations; iterations++)\n\t\t{\n\t\t\tObject object(_object);\n\t\t\tobject.setCode(std::make_shared<AST>(*_object.dialect(), std::get<Block>(ASTCopier{}(astRoot))));\n\t\t\tstd::map<YulName, int> stackSurplus = CompilabilityChecker(object, _optimizeStackAllocation).stackDeficit;\n\t\t\tif (stackSurplus.empty())\n\t\t\t\treturn std::make_tuple(true, std::move(astRoot));\n\t\t\teliminateVariables(\n\t\t\t\t*object.dialect(),\n\t\t\t\tastRoot,\n\t\t\t\tstackSurplus,\n\t\t\t\tallowMSizeOptimization\n\t\t\t);\n\t\t}\n\t}\n\treturn std::make_tuple(false, std::move(astRoot));\n}\n\n"
  },
  {
    "path": "libyul/optimiser/StackCompressor.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that aggressively rematerializes certain variables in a function to free\n * space on the stack until it is compilable.\n */\n\n#pragma once\n\n#include <libyul/Object.h>\n\n#include <memory>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\nclass Object;\nstruct FunctionDefinition;\n\n/**\n * Optimisation stage that aggressively rematerializes certain variables in a function to free\n * space on the stack until it is compilable.\n *\n * Only runs on the code of the object itself, does not descend into sub-objects.\n *\n * Prerequisite: Disambiguator, Function Grouper\n */\nclass StackCompressor\n{\npublic:\n\t/// Try to remove local variables until the AST is compilable.\n\t/// @returns tuple with true if it was successful as first element, second element is the modified AST.\n\tstatic std::tuple<bool, Block> run(\n\t\tObject const& _object,\n\t\tbool _optimizeStackAllocation,\n\t\tsize_t _maxIterations\n\t);\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/StackLimitEvader.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/optimiser/StackLimitEvader.h>\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/optimiser/FunctionCallFinder.h>\n#include <libyul/optimiser/NameDispenser.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/StackToMemoryMover.h>\n#include <libyul/backends/evm/ControlFlowGraphBuilder.h>\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AST.h>\n#include <libyul/CompilabilityChecker.h>\n#include <libyul/Exceptions.h>\n#include <libyul/Object.h>\n#include <libyul/Utilities.h>\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/CommonData.h>\n\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/concat.hpp>\n#include <range/v3/view/take.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nnamespace\n{\n/**\n * Walks the call graph using a Depth-First-Search assigning memory slots to variables.\n * - The leaves of the call graph will get the lowest slot, increasing towards the root.\n * - ``slotsRequiredForFunction`` maps a function to the number of slots it requires (which is also the\n *   next available slot that can be used by another function that calls this function).\n * - For each function starting from the root of the call graph:\n * - Visit all children that are not already visited.\n * - Determine the maximum value ``n`` of the values of ``slotsRequiredForFunction`` among the children.\n * - If the function itself contains variables that need memory slots, but is contained in a cycle,\n *   abort the process as failure.\n * - If not, assign each variable its slot starting from ``n`` (incrementing it).\n * - Assign ``n`` to ``slotsRequiredForFunction`` of the function.\n */\nstruct MemoryOffsetAllocator\n{\n\tuint64_t run(FunctionHandle _function = YulName{})\n\t{\n\t\tif (slotsRequiredForFunction.count(_function))\n\t\t\treturn slotsRequiredForFunction[_function];\n\n\t\t// Assign to zero early to guard against recursive calls.\n\t\tslotsRequiredForFunction[_function] = 0;\n\n\t\tif (!std::holds_alternative<YulName>(_function))\n\t\t\treturn 0;\n\n\t\tuint64_t requiredSlots = 0;\n\t\tif (callGraph.count(std::get<YulName>(_function)))\n\t\t\tfor (FunctionHandle const& child: callGraph.at(std::get<YulName>(_function)))\n\t\t\t\trequiredSlots = std::max(run(child), requiredSlots);\n\n\t\tif (auto const* unreachables = util::valueOrNullptr(unreachableVariables, std::get<YulName>(_function)))\n\t\t{\n\t\t\tif (FunctionDefinition const* functionDefinition = util::valueOrDefault(functionDefinitions, std::get<YulName>(_function), nullptr, util::allow_copy))\n\t\t\t\tif (\n\t\t\t\t\tsize_t totalArgCount = functionDefinition->returnVariables.size() + functionDefinition->parameters.size();\n\t\t\t\t\ttotalArgCount > reachableStackDepth\n\t\t\t\t)\n\t\t\t\t\tfor (NameWithDebugData const& var: ranges::concat_view(\n\t\t\t\t\t\tfunctionDefinition->parameters,\n\t\t\t\t\t\tfunctionDefinition->returnVariables\n\t\t\t\t\t) | ranges::views::take(totalArgCount - reachableStackDepth))\n\t\t\t\t\t\tslotAllocations[var.name] = requiredSlots++;\n\n\t\t\t// Assign slots for all variables that become unreachable in the function body, if the above did not\n\t\t\t// assign a slot for them already.\n\t\t\tfor (YulName variable: *unreachables)\n\t\t\t\t// The empty case is a function with too many arguments or return values,\n\t\t\t\t// which was already handled above.\n\t\t\t\tif (!variable.empty() && !slotAllocations.count(variable))\n\t\t\t\t\tslotAllocations[variable] = requiredSlots++;\n\t\t}\n\n\t\treturn slotsRequiredForFunction[_function] = requiredSlots;\n\t}\n\n\t/// Maps function names to the set of unreachable variables in that function.\n\t/// An empty variable name means that the function has too many arguments or return variables.\n\tstd::map<YulName, std::vector<YulName>> const& unreachableVariables;\n\t/// The graph of immediate function calls of all functions.\n\tstd::map<FunctionHandle, std::vector<FunctionHandle>> const& callGraph;\n\t/// Maps the name of each user-defined function to its definition.\n\tstd::map<YulName, FunctionDefinition const*> const& functionDefinitions;\n\t/// Max stack slots reachable via DUP/SWAP for the current backend configuration.\n\tsize_t reachableStackDepth;\n\n\t/// Maps variable names to the memory slot the respective variable is assigned.\n\tstd::map<YulName, uint64_t> slotAllocations{};\n\t/// Maps function names to the number of memory slots the respective function requires.\n\tstd::map<FunctionHandle, uint64_t> slotsRequiredForFunction{};\n};\n\nu256 literalArgumentValue(FunctionCall const& _call)\n{\n\tyulAssert(_call.arguments.size() == 1, \"\");\n\tLiteral const* literal = std::get_if<Literal>(&_call.arguments.front());\n\tyulAssert(literal && literal->kind == LiteralKind::Number, \"\");\n\treturn literal->value.value();\n}\n}\n\nBlock StackLimitEvader::run(\n\tOptimiserStepContext& _context,\n\tObject const& _object\n)\n{\n\tyulAssert(_object.hasCode());\n\tauto const* evmDialect = dynamic_cast<EVMDialect const*>(&_context.dialect);\n\tyulAssert(\n\t\tevmDialect && evmDialect->providesObjectAccess(),\n\t\t\"StackLimitEvader can only be run on objects using the EVMDialect with object access.\"\n\t);\n\tyulAssert(\n\t\t!evmDialect->eofVersion().has_value(),\n\t\t\"StackLimitEvader does not support EOF.\"\n\t);\n\tauto astRoot = std::get<Block>(ASTCopier{}(_object.code()->root()));\n\tif (evmDialect && evmDialect->evmVersion().canOverchargeGasForCall())\n\t{\n\t\tyul::AsmAnalysisInfo analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(\n\t\t\t*evmDialect,\n\t\t\tastRoot,\n\t\t\t_object.summarizeStructure()\n\t\t);\n\t\tstd::unique_ptr<CFG> cfg = ControlFlowGraphBuilder::build(analysisInfo, *evmDialect, astRoot);\n\t\trun(_context, astRoot, StackLayoutGenerator::reportStackTooDeep(*cfg, *evmDialect));\n\t}\n\telse\n\t{\n\t\trun(_context, astRoot, CompilabilityChecker{\n\t\t\t_object,\n\t\t\ttrue,\n\t\t}.unreachableVariables);\n\t}\n\treturn astRoot;\n}\n\nvoid StackLimitEvader::run(\n\tOptimiserStepContext& _context,\n\tBlock& _astRoot,\n\tstd::map<YulName, std::vector<StackLayoutGenerator::StackTooDeep>> const& _stackTooDeepErrors\n)\n{\n\tauto const* evmDialect = dynamic_cast<EVMDialect const*>(&_context.dialect);\n\tyulAssert(\n\t\tevmDialect && evmDialect->providesObjectAccess(),\n\t\t\"StackLimitEvader can only be run on objects using the EVMDialect with object access.\"\n\t);\n\tyulAssert(\n\t\t!evmDialect->eofVersion().has_value(),\n\t\t\"StackLimitEvader does not support EOF.\"\n\t);\n\tstd::map<YulName, std::vector<YulName>> unreachableVariables;\n\tfor (auto&& [function, stackTooDeepErrors]: _stackTooDeepErrors)\n\t{\n\t\tauto& unreachables = unreachableVariables[function];\n\t\t// TODO: choose wisely.\n\t\tfor (auto const& stackTooDeepError: stackTooDeepErrors)\n\t\t\tfor (auto variable: stackTooDeepError.variableChoices | ranges::views::take(stackTooDeepError.deficit))\n\t\t\t\tif (!util::contains(unreachables, variable))\n\t\t\t\t\tunreachables.emplace_back(variable);\n\t}\n\trun(_context, _astRoot, unreachableVariables);\n}\n\nvoid StackLimitEvader::run(\n\tOptimiserStepContext& _context,\n\tBlock& _astRoot,\n\tstd::map<YulName, std::vector<YulName>> const& _unreachableVariables\n)\n{\n\tauto const* evmDialect = dynamic_cast<EVMDialect const*>(&_context.dialect);\n\tyulAssert(\n\t\tevmDialect && evmDialect->providesObjectAccess(),\n\t\t\"StackLimitEvader can only be run on objects using the EVMDialect with object access.\"\n\t);\n\tyulAssert(\n\t\t!evmDialect->eofVersion().has_value(),\n\t\t\"StackLimitEvader does not support EOF.\"\n\t);\n\n\tauto const memoryGuardHandle = evmDialect->findBuiltin(\"memoryguard\");\n\tyulAssert(memoryGuardHandle, \"Compiling with object access, memoryguard should be available as builtin.\");\n\tstd::vector<FunctionCall*> const memoryGuardCalls = findFunctionCalls(_astRoot, *memoryGuardHandle);\n\t// Do not optimise, if no ``memoryguard`` call is found.\n\tif (memoryGuardCalls.empty())\n\t\treturn;\n\n\t// Make sure all calls to ``memoryguard`` we found have the same value as argument (otherwise, abort).\n\tu256 reservedMemory = literalArgumentValue(*memoryGuardCalls.front());\n\tyulAssert(reservedMemory < u256(1) << 32 - 1, \"\");\n\n\tfor (FunctionCall const* memoryGuardCall: memoryGuardCalls)\n\t\tif (reservedMemory != literalArgumentValue(*memoryGuardCall))\n\t\t\treturn;\n\n\tCallGraph callGraph = CallGraphGenerator::callGraph(_astRoot);\n\n\t// We cannot move variables in recursive functions to fixed memory offsets.\n\tfor (FunctionHandle function: callGraph.recursiveFunctions())\n\t{\n\t\tyulAssert(std::holds_alternative<YulName>(function), \"Builtins are not recursive.\");\n\t\tif (_unreachableVariables.count(std::get<YulName>(function)))\n\t\t\treturn;\n\t}\n\n\tstd::map<YulName, FunctionDefinition const*> functionDefinitions = allFunctionDefinitions(_astRoot);\n\n\tMemoryOffsetAllocator memoryOffsetAllocator{\n\t\t_unreachableVariables,\n\t\tcallGraph.functionCalls,\n\t\tfunctionDefinitions,\n\t\tevmDialect->reachableStackDepth()\n\t};\n\tuint64_t requiredSlots = memoryOffsetAllocator.run();\n\tyulAssert(requiredSlots < (uint64_t(1) << 32) - 1, \"\");\n\n\tStackToMemoryMover::run(_context, reservedMemory, memoryOffsetAllocator.slotAllocations, requiredSlots, _astRoot);\n\n\treservedMemory += 32 * requiredSlots;\n\tfor (FunctionCall* memoryGuardCall: findFunctionCalls(_astRoot, *memoryGuardHandle))\n\t{\n\t\tLiteral* literal = std::get_if<Literal>(&memoryGuardCall->arguments.front());\n\t\tyulAssert(literal && literal->kind == LiteralKind::Number, \"\");\n\t\tliteral->value = LiteralValue{reservedMemory, toCompactHexWithPrefix(reservedMemory)};\n\t}\n}\n"
  },
  {
    "path": "libyul/optimiser/StackLimitEvader.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * Optimisation stage that assigns memory offsets to variables that would become unreachable if\n * assigned a stack slot as usual and replaces references and assignments to them by mload and mstore calls.\n */\n\n#pragma once\n\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/backends/evm/StackLayoutGenerator.h>\n\nnamespace solidity::yul\n{\n\nclass Object;\n\n/**\n * Optimisation stage that assigns memory offsets to variables that would become unreachable if\n * assigned a stack slot as usual.\n *\n * Uses CompilabilityChecker to determine which variables in which functions are unreachable.\n *\n * Only variables outside of functions contained in cycles in the call graph are considered. Thereby it is possible\n * to assign globally fixed memory offsets to the variable. If a variable in a function contained in a cycle in the\n * call graph is reported as unreachable, the process is aborted.\n *\n * Offsets are assigned to the variables, s.t. on every path through the call graph each variable gets a unique offset\n * in memory. However, distinct paths through the call graph can use the same memory offsets for their variables.\n *\n * The current arguments to the ``memoryguard`` calls are used as base memory offset and then replaced by the offset past\n * the last memory offset used for a variable on any path through the call graph.\n *\n * Finally, the StackToMemoryMover is called to actually move the variables to their offsets in memory.\n *\n * Prerequisite: Disambiguator\n */\nclass StackLimitEvader\n{\npublic:\n\t/// @a _unreachableVariables can be determined by the CompilabilityChecker.\n\t/// Can only be run on the EVM dialect with objects.\n\t/// Abort and do nothing, if no ``memoryguard`` call or several ``memoryguard`` calls\n\t/// with non-matching arguments are found, or if any of the @a _unreachableVariables\n\t/// are contained in a recursive function.\n\tstatic void run(\n\t\tOptimiserStepContext& _context,\n\t\tBlock& _astRoot,\n\t\tstd::map<YulName, std::vector<YulName>> const& _unreachableVariables\n\t);\n\t/// @a _stackTooDeepErrors can be determined by the StackLayoutGenerator.\n\t/// Can only be run on the EVM dialect with objects.\n\t/// Abort and do nothing, if no ``memoryguard`` call or several ``memoryguard`` calls\n\t/// with non-matching arguments are found, or if any of the @a _stackTooDeepErrors\n\t/// are contained in a recursive function.\n\tstatic void run(\n\t\tOptimiserStepContext& _context,\n\t\tBlock& _astRoot,\n\t\tstd::map<YulName, std::vector<StackLayoutGenerator::StackTooDeep>> const& _stackTooDeepErrors\n\t);\n\t/// Determines stack too deep errors using the appropriate code generation backend.\n\t/// Can only be run on the EVM dialect with objects.\n\t/// Abort and do nothing, if no ``memoryguard`` call or several ``memoryguard`` calls\n\t/// with non-matching arguments are found, or if any of the unreachable variables\n\t/// are contained in a recursive function.\n\tstatic Block run(\n\t\tOptimiserStepContext& _context,\n\t\tObject const& _object\n\t);\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/StackToMemoryMover.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n#include <libyul/optimiser/StackToMemoryMover.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/NameDispenser.h>\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <range/v3/algorithm/none_of.hpp>\n#include <range/v3/view/filter.hpp>\n#include <range/v3/view/transform.hpp>\n#include <range/v3/view/zip.hpp>\n#include <range/v3/range/conversion.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nnamespace\n{\nstd::vector<Statement> generateMemoryStore(\n\tDialect const& _dialect,\n\tlangutil::DebugData::ConstPtr const& _debugData,\n\tLiteralValue const& _mpos,\n\tExpression _value\n)\n{\n\tstd::optional<BuiltinHandle> memoryStoreFunctionHandle = _dialect.memoryStoreFunctionHandle();\n\tyulAssert(memoryStoreFunctionHandle);\n\tstd::vector<Statement> result;\n\tresult.emplace_back(ExpressionStatement{_debugData, FunctionCall{\n\t\t_debugData,\n\t\tBuiltinName{_debugData, *memoryStoreFunctionHandle},\n\t\t{\n\t\t\tLiteral{_debugData, LiteralKind::Number, _mpos},\n\t\t\tstd::move(_value)\n\t\t}\n\t}});\n\treturn result;\n}\n\nFunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::DebugData::ConstPtr const& _debugData, LiteralValue const& _mpos)\n{\n\tstd::optional<BuiltinHandle> const& memoryLoadHandle = _dialect.memoryLoadFunctionHandle();\n\tyulAssert(memoryLoadHandle);\n\treturn FunctionCall{\n\t\t_debugData,\n\t\tBuiltinName{_debugData, *memoryLoadHandle}, {\n\t\t\tLiteral{\n\t\t\t\t_debugData,\n\t\t\t\tLiteralKind::Number,\n\t\t\t\t_mpos\n\t\t\t}\n\t\t}\n\t};\n}\n}\n\nvoid StackToMemoryMover::run(\n\tOptimiserStepContext& _context,\n\tu256 _reservedMemory,\n\tstd::map<YulName, uint64_t> const& _memorySlots,\n\tuint64_t _numRequiredSlots,\n\tBlock& _block\n)\n{\n\tVariableMemoryOffsetTracker memoryOffsetTracker(_reservedMemory, _memorySlots, _numRequiredSlots);\n\tStackToMemoryMover stackToMemoryMover(\n\t\t_context,\n\t\tmemoryOffsetTracker,\n\t\tutil::applyMap(\n\t\t\tallFunctionDefinitions(_block),\n\t\t\tutil::mapTuple([](YulName _name, FunctionDefinition const* _funDef) {\n\t\t\t\treturn make_pair(_name, _funDef->returnVariables);\n\t\t\t}),\n\t\t\tstd::map<YulName, NameWithDebugDataList>{}\n\t\t)\n\t);\n\tstackToMemoryMover(_block);\n\t_block.statements += std::move(stackToMemoryMover.m_newFunctionDefinitions);\n}\n\nStackToMemoryMover::StackToMemoryMover(\n\tOptimiserStepContext& _context,\n\tVariableMemoryOffsetTracker const& _memoryOffsetTracker,\n\tstd::map<YulName, NameWithDebugDataList> _functionReturnVariables\n):\nm_context(_context),\nm_memoryOffsetTracker(_memoryOffsetTracker),\nm_nameDispenser(_context.dispenser),\nm_functionReturnVariables(std::move(_functionReturnVariables))\n{\n\tauto const* evmDialect = dynamic_cast<EVMDialect const*>(&_context.dialect);\n\tyulAssert(\n\t\tevmDialect && evmDialect->providesObjectAccess(),\n\t\t\"StackToMemoryMover can only be run on objects using the EVMDialect with object access.\"\n\t);\n}\n\nvoid StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition)\n{\n\t// It is important to first visit the function body, so that it doesn't replace the memory inits for\n\t// variable arguments we might generate below.\n\tASTModifier::operator()(_functionDefinition);\n\n\tstd::vector<Statement> memoryVariableInits;\n\n\t// All function parameters with a memory slot are moved at the beginning of the function body.\n\tfor (NameWithDebugData const& param: _functionDefinition.parameters)\n\t\tif (auto slot = m_memoryOffsetTracker(param.name))\n\t\t\tmemoryVariableInits += generateMemoryStore(\n\t\t\t\tm_context.dialect,\n\t\t\t\tparam.debugData,\n\t\t\t\t*slot,\n\t\t\t\tIdentifier{param.debugData, param.name}\n\t\t\t);\n\n\t// All memory return variables have to be initialized to zero in memory.\n\tfor (NameWithDebugData const& returnVariable: _functionDefinition.returnVariables)\n\t\tif (auto slot = m_memoryOffsetTracker(returnVariable.name))\n\t\t\tmemoryVariableInits += generateMemoryStore(\n\t\t\t\tm_context.dialect,\n\t\t\t\treturnVariable.debugData,\n\t\t\t\t*slot,\n\t\t\t\tLiteral{returnVariable.debugData, LiteralKind::Number, LiteralValue(u256{0})}\n\t\t\t);\n\n\t// Special case of a function with a single return argument that needs to move to memory.\n\tif (_functionDefinition.returnVariables.size() == 1 && m_memoryOffsetTracker(_functionDefinition.returnVariables.front().name))\n\t{\n\t\tNameWithDebugDataList stackParameters = _functionDefinition.parameters | ranges::views::filter(\n\t\t\tstd::not_fn(m_memoryOffsetTracker)\n\t\t) | ranges::to<NameWithDebugDataList>;\n\t\t// Generate new function without return variable and with only the non-moved parameters.\n\t\tYulName newFunctionName = m_context.dispenser.newName(_functionDefinition.name);\n\t\tm_newFunctionDefinitions.emplace_back(FunctionDefinition{\n\t\t\t_functionDefinition.debugData,\n\t\t\tnewFunctionName,\n\t\t\tstackParameters,\n\t\t\t{},\n\t\t\tstd::move(_functionDefinition.body)\n\t\t});\n\t\t// Generate new names for the arguments to maintain disambiguation.\n\t\tstd::map<YulName, YulName> newArgumentNames;\n\t\tfor (NameWithDebugData const& _var: stackParameters)\n\t\t\tnewArgumentNames[_var.name] = m_context.dispenser.newName(_var.name);\n\t\tfor (auto& parameter: _functionDefinition.parameters)\n\t\t\tparameter.name = util::valueOrDefault(newArgumentNames, parameter.name, parameter.name);\n\t\t// Replace original function by a call to the new function and an assignment to the return variable from memory.\n\t\t_functionDefinition.body = Block{_functionDefinition.debugData, std::move(memoryVariableInits)};\n\t\t_functionDefinition.body.statements.emplace_back(ExpressionStatement{\n\t\t\t_functionDefinition.debugData,\n\t\t\tFunctionCall{\n\t\t\t\t_functionDefinition.debugData,\n\t\t\t\tIdentifier{_functionDefinition.debugData, newFunctionName},\n\t\t\t\tstackParameters | ranges::views::transform([&](NameWithDebugData const& _arg) {\n\t\t\t\t\treturn Expression{Identifier{_arg.debugData, newArgumentNames.at(_arg.name)}};\n\t\t\t\t}) | ranges::to<std::vector<Expression>>\n\t\t\t}\n\t\t});\n\t\t_functionDefinition.body.statements.emplace_back(Assignment{\n\t\t\t_functionDefinition.debugData,\n\t\t\t{Identifier{_functionDefinition.debugData, _functionDefinition.returnVariables.front().name}},\n\t\t\tstd::make_unique<Expression>(generateMemoryLoad(\n\t\t\t\tm_context.dialect,\n\t\t\t\t_functionDefinition.debugData,\n\t\t\t\t*m_memoryOffsetTracker(_functionDefinition.returnVariables.front().name)\n\t\t\t))\n\t\t});\n\t\treturn;\n\t}\n\n\tif (!memoryVariableInits.empty())\n\t\t_functionDefinition.body.statements = std::move(memoryVariableInits) + std::move(_functionDefinition.body.statements);\n\n\t_functionDefinition.returnVariables = _functionDefinition.returnVariables | ranges::views::filter(\n\t\tstd::not_fn(m_memoryOffsetTracker)\n\t) | ranges::to<NameWithDebugDataList>;\n}\n\nvoid StackToMemoryMover::operator()(Block& _block)\n{\n\tusing OptionalStatements = std::optional<std::vector<Statement>>;\n\n\tauto rewriteAssignmentOrVariableDeclarationLeftHandSide = [this](\n\t\tauto& _stmt,\n\t\tauto& _lhsVars\n\t) -> OptionalStatements {\n\t\tusing StatementType = std::decay_t<decltype(_stmt)>;\n\n\t\tauto debugData = _stmt.debugData;\n\t\tif (_lhsVars.size() == 1)\n\t\t{\n\t\t\tif (auto offset = m_memoryOffsetTracker(_lhsVars.front().name))\n\t\t\t\treturn generateMemoryStore(\n\t\t\t\t\tm_context.dialect,\n\t\t\t\t\tdebugData,\n\t\t\t\t\t*offset,\n\t\t\t\t\t_stmt.value ? *std::move(_stmt.value) : Literal{debugData, LiteralKind::Number, LiteralValue(u256{0})}\n\t\t\t\t);\n\t\t\telse\n\t\t\t\treturn {};\n\t\t}\n\t\tstd::vector<std::optional<LiteralValue>> rhsMemorySlots;\n\t\tif (_stmt.value)\n\t\t{\n\t\t\tFunctionCall const* functionCall = std::get_if<FunctionCall>(_stmt.value.get());\n\t\t\tyulAssert(functionCall, \"\");\n\t\t\tif (isBuiltinFunctionCall(*functionCall))\n\t\t\t\trhsMemorySlots = std::vector<std::optional<LiteralValue>>(_lhsVars.size(), std::nullopt);\n\t\t\telse\n\t\t\t{\n\t\t\t\tyulAssert(std::holds_alternative<Identifier>(functionCall->functionName));\n\t\t\t\trhsMemorySlots =\n\t\t\t\t\tm_functionReturnVariables.at(std::get<Identifier>(functionCall->functionName).name) |\n\t\t\t\t\tranges::views::transform(m_memoryOffsetTracker) |\n\t\t\t\t\tranges::to<std::vector<std::optional<LiteralValue>>>;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\trhsMemorySlots = std::vector<std::optional<LiteralValue>>(_lhsVars.size(), std::nullopt);\n\n\t\t// Nothing to do, if the right-hand-side remains entirely on the stack and\n\t\t// none of the variables in the left-hand-side are moved.\n\t\tif (\n\t\t\tranges::none_of(rhsMemorySlots, [](std::optional<LiteralValue> const& _slot) { return _slot.has_value(); }) &&\n\t\t\t!util::contains_if(_lhsVars, m_memoryOffsetTracker)\n\t\t)\n\t\t\treturn {};\n\n\t\tstd::vector<Statement> memoryAssignments;\n\t\tstd::vector<Statement> variableAssignments;\n\t\tVariableDeclaration tempDecl{debugData, {}, std::move(_stmt.value)};\n\n\t\tyulAssert(rhsMemorySlots.size() == _lhsVars.size(), \"\");\n\t\tfor (auto&& [lhsVar, rhsSlot]: ranges::views::zip(_lhsVars, rhsMemorySlots))\n\t\t{\n\t\t\tstd::unique_ptr<Expression> rhs;\n\t\t\tif (rhsSlot)\n\t\t\t\trhs = std::make_unique<Expression>(generateMemoryLoad(m_context.dialect, debugData, *rhsSlot));\n\t\t\telse\n\t\t\t{\n\t\t\t\tYulName tempVarName = m_nameDispenser.newName(lhsVar.name);\n\t\t\t\ttempDecl.variables.emplace_back(NameWithDebugData{lhsVar.debugData, tempVarName});\n\t\t\t\trhs = std::make_unique<Expression>(Identifier{debugData, tempVarName});\n\t\t\t}\n\n\t\t\tif (auto offset = m_memoryOffsetTracker(lhsVar.name))\n\t\t\t\tmemoryAssignments += generateMemoryStore(\n\t\t\t\t\tm_context.dialect,\n\t\t\t\t\t_stmt.debugData,\n\t\t\t\t\t*offset,\n\t\t\t\t\tstd::move(*rhs)\n\t\t\t\t);\n\t\t\telse\n\t\t\t\tvariableAssignments.emplace_back(StatementType{\n\t\t\t\t\tdebugData,\n\t\t\t\t\t{ std::move(lhsVar) },\n\t\t\t\t\tstd::move(rhs)\n\t\t\t\t});\n\t\t}\n\n\t\tstd::vector<Statement> result;\n\t\tif (tempDecl.variables.empty())\n\t\t\tresult.emplace_back(ExpressionStatement{debugData, *std::move(tempDecl.value)});\n\t\telse\n\t\t\tresult.emplace_back(std::move(tempDecl));\n\t\treverse(memoryAssignments.begin(), memoryAssignments.end());\n\t\tresult += std::move(memoryAssignments);\n\t\treverse(variableAssignments.begin(), variableAssignments.end());\n\t\tresult += std::move(variableAssignments);\n\t\treturn OptionalStatements{std::move(result)};\n\t};\n\n\tutil::iterateReplacing(\n\t\t_block.statements,\n\t\t[&](Statement& _statement) -> OptionalStatements\n\t\t{\n\t\t\tvisit(_statement);\n\t\t\tif (auto* assignment = std::get_if<Assignment>(&_statement))\n\t\t\t\treturn rewriteAssignmentOrVariableDeclarationLeftHandSide(*assignment, assignment->variableNames);\n\t\t\telse if (auto* varDecl = std::get_if<VariableDeclaration>(&_statement))\n\t\t\t\treturn rewriteAssignmentOrVariableDeclarationLeftHandSide(*varDecl, varDecl->variables);\n\t\t\treturn {};\n\t\t}\n\t);\n}\n\nvoid StackToMemoryMover::visit(Expression& _expression)\n{\n\tASTModifier::visit(_expression);\n\tif (Identifier* identifier = std::get_if<Identifier>(&_expression))\n\t\tif (auto offset = m_memoryOffsetTracker(identifier->name))\n\t\t\t_expression = generateMemoryLoad(m_context.dialect, identifier->debugData, *offset);\n}\n\nstd::optional<LiteralValue> StackToMemoryMover::VariableMemoryOffsetTracker::operator()(YulName const& _variable) const\n{\n\tif (m_memorySlots.count(_variable))\n\t{\n\t\tuint64_t slot = m_memorySlots.at(_variable);\n\t\tyulAssert(slot < m_numRequiredSlots, \"\");\n\t\tauto const memoryOffset = m_reservedMemory + 32 * (m_numRequiredSlots - slot - 1);\n\t\treturn valueOfNumberLiteral(toCompactHexWithPrefix(memoryOffset));\n\t}\n\telse\n\t\treturn std::nullopt;\n}\n\nstd::optional<LiteralValue> StackToMemoryMover::VariableMemoryOffsetTracker::operator()(NameWithDebugData const& _variable) const\n{\n\treturn (*this)(_variable.name);\n}\n\nstd::optional<LiteralValue> StackToMemoryMover::VariableMemoryOffsetTracker::operator()(Identifier const& _variable) const\n{\n\treturn (*this)(_variable.name);\n}\n"
  },
  {
    "path": "libyul/optimiser/StackToMemoryMover.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * Optimisation stage that moves Yul variables from stack to memory.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/ASTForward.h>\n#include <libyul/YulName.h>\n\n#include <liblangutil/SourceLocation.h>\n#include <libsolutil/Common.h>\n#include <libsolutil/Numeric.h>\n\n#include <list>\n\nnamespace solidity::yul\n{\n\n/**\n * Optimisation stage that moves Yul variables from stack to memory.\n * It takes a map from functions names and variable names to memory offsets.\n * It then transforms the AST as follows:\n *\n * Single variable declarations are replaced by mstore's as follows:\n *   If a is in the map, replace\n *     let a\n *   by\n *     mstore(<memory offset for a>, 0)\n *   respectively, replace\n *     let a := expr\n *   by\n *     mstore(<memory offset for a>, expr)\n *\n * In a multi-variable declaration, variables to be moved are replaced by fresh variables and then moved to memory:\n *   If b and d are in the map, replace\n *     let a, b, c, d := f()\n *   by\n *     let _1, _2, _3, _4 := f()\n *     mstore(<memory offset for d>, _4)\n *     mstore(<memory offset for b>, _2)\n *     let c := _3\n *     let a := _1\n *\n * In case f has return parameters that are moved to memory, fewer variables are returned and the return values read\n * from memory instead. Assume the third return parameter of f (i.e. c) has to be moved to memory:\n *     let a, b, c, d := f()\n *   then it is replaced by\n *     let _1, _2, _4 := f()\n *     mstore(<memory offset for d>, _4)\n *     mstore(<memory offset for b>, _2)\n *     let c := mload(<memory offset of third return parameter of f>)\n *     let a := _1\n *\n * Assignments to single variables are replaced by mstore's:\n *   If a is in the map, replace\n *     a := expr\n *   by\n *     mstore(<memory offset for a>, expr)\n *\n * Assignments to multiple variables are split up similarly to multi-variable declarations:\n *   If b and d are in the map, replace\n *     a, b, c, d := f()\n *   by\n *     let _1, _2, _3, _4 := f()\n *     mstore(<memory offset for d>, _4)\n *     mstore(<memory offset for b>, _2)\n *     c := _3\n *     a := _1\n *\n * Replace all references to a variable ``a`` in the map by ``mload(<memory offset for a>)``.\n *\n * Function arguments are moved at the beginning of a function body:\n *   If a1 is in the map, replace\n *     function f(a1, a2, ..., a17)\n *     {\n *       ...\n *       sstore(a1, a17)\n *     }\n *   by\n *     function f(a1, a2, ..., a17)\n *     {\n *       mstore(<memory offset for a1>, a1)\n *       ...\n *       sstore(mload(<memory offset for a1>, a17)\n *     }\n * This relies on the code transform popping arguments that are no longer used, if they are on the stack top.\n *\n * Functions with only one return argument that has to be moved are encapsulated in a wrapper function as follows:\n *   Suppose b and r need to be moved in:\n *     function f(a, b) -> r\n *     {\n *       ...body of f...\n *       r := b\n *       ...body of f continued...\n *     }\n *   then replace by:\n *     function f(a, b) -> r\n *     {\n *       mstore(<memory offset of b>, b)\n *       mstore(<memory offset of r>, 0)\n *       f_1(a)\n *       r := mload(<memory offset of r>)\n *     }\n *     function f_1(a)\n *     {\n *       ...body of f...\n *       mstore(<memory offset of r>, mload(<memory offset of b>))\n *       ...body of f continued...\n *     }\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter, FunctionHoister.\n */\nclass StackToMemoryMover: ASTModifier\n{\npublic:\n\t/**\n\t * Runs the stack to memory mover.\n\t * @param _reservedMemory Is the amount of previously reserved memory,\n\t *                        i.e. the lowest memory offset to which variables can be moved.\n\t * @param _memorySlots A map from variables to a slot in memory. Based on the slot a unique offset in the memory range\n\t *                     between _reservedMemory and _reservedMemory + 32 * _numRequiredSlots is calculated for each\n\t *                     variable.\n\t * @param _numRequiredSlots The number of slots required in total. The maximum value that may occur in @a _memorySlots.\n\t */\n\tstatic void run(\n\t\tOptimiserStepContext& _context,\n\t\tu256 _reservedMemory,\n\t\tstd::map<YulName, uint64_t> const& _memorySlots,\n\t\tuint64_t _numRequiredSlots,\n\t\tBlock& _block\n\t);\n\tusing ASTModifier::operator();\n\n\tvoid operator()(FunctionDefinition& _functionDefinition) override;\n\tvoid operator()(Block& _block) override;\n\tusing ASTModifier::visit;\n\tvoid visit(Expression& _expression) override;\nprivate:\n\tclass VariableMemoryOffsetTracker\n\t{\n\tpublic:\n\t\tVariableMemoryOffsetTracker(\n\t\t\tu256 _reservedMemory,\n\t\t\tstd::map<YulName, uint64_t> const& _memorySlots,\n\t\t\tuint64_t _numRequiredSlots\n\t\t): m_reservedMemory(_reservedMemory), m_memorySlots(_memorySlots), m_numRequiredSlots(_numRequiredSlots)\n\t\t{}\n\n\t\t/// @returns a YulName containing the memory offset to be assigned to @a _variable as number literal\n\t\t/// or std::nullopt if the variable should not be moved.\n\t\tstd::optional<LiteralValue> operator()(YulName const& _variable) const;\n\t\t/// @returns a YulName containing the memory offset to be assigned to @a _variable as number literal\n\t\t/// or std::nullopt if the variable should not be moved.\n\t\tstd::optional<LiteralValue> operator()(NameWithDebugData const& _variable) const;\n\t\t/// @returns a YulName containing the memory offset to be assigned to @a _variable as number literal\n\t\t/// or std::nullopt if the variable should not be moved.\n\t\tstd::optional<LiteralValue> operator()(Identifier const& _variable) const;\n\n\tprivate:\n\t\tu256 m_reservedMemory;\n\t\tstd::map<YulName, uint64_t> const& m_memorySlots;\n\t\tuint64_t m_numRequiredSlots = 0;\n\t};\n\tstruct FunctionMoveInfo\n\t{\n\t\tstd::vector<std::optional<YulName>> returnVariableSlots;\n\t};\n\n\tStackToMemoryMover(\n\t\tOptimiserStepContext& _context,\n\t\tVariableMemoryOffsetTracker const& _memoryOffsetTracker,\n\t\tstd::map<YulName, std::vector<NameWithDebugData>> _functionReturnVariables\n\t);\n\n\tOptimiserStepContext& m_context;\n\tVariableMemoryOffsetTracker const& m_memoryOffsetTracker;\n\tNameDispenser& m_nameDispenser;\n\t/// Map from function names to the return variables of the function with that name.\n\tstd::map<YulName, std::vector<NameWithDebugData>> m_functionReturnVariables;\n\t/// List of functions generated while running this step that are to be appended to the code in the end.\n\tstd::list<Statement> m_newFunctionDefinitions;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/StructuralSimplifier.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#include <libyul/optimiser/StructuralSimplifier.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Visitor.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nusing OptionalStatements = std::optional<std::vector<Statement>>;\n\nnamespace\n{\n\nOptionalStatements replaceConstArgSwitch(Switch& _switchStmt, u256 const& _constExprVal)\n{\n\tBlock* matchingCaseBlock = nullptr;\n\tCase* defaultCase = nullptr;\n\n\tfor (auto& _case: _switchStmt.cases)\n\t{\n\t\tif (_case.value && _case.value->value.value() == _constExprVal)\n\t\t{\n\t\t\tmatchingCaseBlock = &_case.body;\n\t\t\tbreak;\n\t\t}\n\t\telse if (!_case.value)\n\t\t\tdefaultCase = &_case;\n\t}\n\n\tif (!matchingCaseBlock && defaultCase)\n\t\tmatchingCaseBlock = &defaultCase->body;\n\n\tif (matchingCaseBlock)\n\t\treturn util::make_vector<Statement>(std::move(*matchingCaseBlock));\n\telse\n\t\treturn std::optional<std::vector<Statement>>{std::vector<Statement>{}};\n}\n\nstd::optional<u256> hasLiteralValue(Expression const& _expression)\n{\n\tif (std::holds_alternative<Literal>(_expression))\n\t\treturn std::get<Literal>(_expression).value.value();\n\telse\n\t\treturn std::nullopt;\n}\n\nbool expressionAlwaysTrue(Expression const& _expression)\n{\n\tif (std::optional<u256> value = hasLiteralValue(_expression))\n\t\treturn *value != 0;\n\telse\n\t\treturn false;\n}\n\nbool expressionAlwaysFalse(Expression const& _expression)\n{\n\tif (std::optional<u256> value = hasLiteralValue(_expression))\n\t\treturn *value == 0;\n\telse\n\t\treturn false;\n}\n\n}\n\nvoid StructuralSimplifier::run(OptimiserStepContext&, Block& _ast)\n{\n\tStructuralSimplifier{}(_ast);\n}\n\nvoid StructuralSimplifier::operator()(Block& _block)\n{\n\tsimplify(_block.statements);\n}\n\nvoid StructuralSimplifier::simplify(std::vector<yul::Statement>& _statements)\n{\n\tutil::GenericVisitor visitor{\n\t\tutil::VisitorFallback<OptionalStatements>{},\n\t\t[&](If& _ifStmt) -> OptionalStatements {\n\t\t\tif (expressionAlwaysTrue(*_ifStmt.condition))\n\t\t\t\treturn {std::move(_ifStmt.body.statements)};\n\t\t\telse if (expressionAlwaysFalse(*_ifStmt.condition))\n\t\t\t\treturn {std::vector<Statement>{}};\n\t\t\treturn {};\n\t\t},\n\t\t[&](Switch& _switchStmt) -> OptionalStatements {\n\t\t\tif (std::optional<u256> const constExprVal = hasLiteralValue(*_switchStmt.expression))\n\t\t\t\treturn replaceConstArgSwitch(_switchStmt, constExprVal.value());\n\t\t\treturn {};\n\t\t},\n\t\t[&](ForLoop& _forLoop) -> OptionalStatements {\n\t\t\tif (expressionAlwaysFalse(*_forLoop.condition))\n\t\t\t\treturn {std::move(_forLoop.pre.statements)};\n\t\t\treturn {};\n\t\t}\n\t};\n\n\tutil::iterateReplacing(\n\t\t_statements,\n\t\t[&](Statement& _stmt) -> OptionalStatements\n\t\t{\n\t\t\tOptionalStatements result = std::visit(visitor, _stmt);\n\t\t\tif (result)\n\t\t\t\tsimplify(*result);\n\t\t\telse\n\t\t\t\tvisit(_stmt);\n\t\t\treturn result;\n\t\t}\n\t);\n}\n"
  },
  {
    "path": "libyul/optimiser/StructuralSimplifier.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libsolutil/Common.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Structural simplifier. Performs the following simplification steps:\n * - replace if with true condition with its body\n * - remove if with false condition\n * - replace switch with const expr with matching case body\n * - replace for with false condition by its initialization part\n *\n * The LiteralRematerialiser should be run before this.\n *\n * Prerequisite: Disambiguator.\n *\n * Important: Can only be used on EVM code.\n */\nclass StructuralSimplifier: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"StructuralSimplifier\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(Block& _block) override;\nprivate:\n\tStructuralSimplifier() = default;\n\n\tvoid simplify(std::vector<Statement>& _statements);\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/Substitution.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Specific AST copier that replaces certain identifiers with expressions.\n */\n\n#include <libyul/optimiser/Substitution.h>\n\n#include <libyul/AST.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nExpression Substitution::translate(Expression const& _expression)\n{\n\tif (std::holds_alternative<Identifier>(_expression))\n\t{\n\t\tYulName name = std::get<Identifier>(_expression).name;\n\t\tif (m_substitutions.count(name))\n\t\t\t// No recursive substitution\n\t\t\treturn ASTCopier().translate(*m_substitutions.at(name));\n\t}\n\treturn ASTCopier::translate(_expression);\n}\n"
  },
  {
    "path": "libyul/optimiser/Substitution.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Specific AST copier that replaces certain identifiers with expressions.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTCopier.h>\n#include <libyul/YulName.h>\n\n#include <map>\n\nnamespace solidity::yul\n{\n\n/**\n * Specific AST copier that replaces certain identifiers with expressions.\n */\nclass Substitution: public ASTCopier\n{\npublic:\n\tSubstitution(std::map<YulName, Expression const*> const& _substitutions):\n\t\tm_substitutions(_substitutions)\n\t{}\n\tExpression translate(Expression const& _expression) override;\n\nprivate:\n\tstd::map<YulName, Expression const*> const& m_substitutions;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/Suite.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser suite that combines all steps and also provides the settings for the heuristics.\n */\n\n#include <libyul/optimiser/Suite.h>\n\n#include <libyul/optimiser/Disambiguator.h>\n#include <libyul/optimiser/VarDeclInitializer.h>\n#include <libyul/optimiser/BlockFlattener.h>\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/optimiser/CircularReferencesPruner.h>\n#include <libyul/optimiser/ControlFlowSimplifier.h>\n#include <libyul/optimiser/ConditionalSimplifier.h>\n#include <libyul/optimiser/ConditionalUnsimplifier.h>\n#include <libyul/optimiser/DeadCodeEliminator.h>\n#include <libyul/optimiser/FunctionGrouper.h>\n#include <libyul/optimiser/FunctionHoister.h>\n#include <libyul/optimiser/EqualStoreEliminator.h>\n#include <libyul/optimiser/EquivalentFunctionCombiner.h>\n#include <libyul/optimiser/ExpressionSplitter.h>\n#include <libyul/optimiser/ExpressionJoiner.h>\n#include <libyul/optimiser/ExpressionInliner.h>\n#include <libyul/optimiser/FullInliner.h>\n#include <libyul/optimiser/ForLoopConditionIntoBody.h>\n#include <libyul/optimiser/ForLoopConditionOutOfBody.h>\n#include <libyul/optimiser/ForLoopInitRewriter.h>\n#include <libyul/optimiser/ForLoopConditionIntoBody.h>\n#include <libyul/optimiser/FunctionSpecializer.h>\n#include <libyul/optimiser/Rematerialiser.h>\n#include <libyul/optimiser/UnusedFunctionParameterPruner.h>\n#include <libyul/optimiser/UnusedPruner.h>\n#include <libyul/optimiser/ExpressionSimplifier.h>\n#include <libyul/optimiser/CommonSubexpressionEliminator.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/SSAReverser.h>\n#include <libyul/optimiser/SSATransform.h>\n#include <libyul/optimiser/StackCompressor.h>\n#include <libyul/optimiser/StackLimitEvader.h>\n#include <libyul/optimiser/StructuralSimplifier.h>\n#include <libyul/optimiser/SyntacticalEquality.h>\n#include <libyul/optimiser/UnusedAssignEliminator.h>\n#include <libyul/optimiser/UnusedStoreEliminator.h>\n#include <libyul/optimiser/VarNameCleaner.h>\n#include <libyul/optimiser/LoadResolver.h>\n#include <libyul/optimiser/LoopInvariantCodeMotion.h>\n#include <libyul/optimiser/Metrics.h>\n#include <libyul/optimiser/NameSimplifier.h>\n#include <libyul/backends/evm/ConstantOptimiser.h>\n#include <libyul/AsmAnalysis.h>\n#include <libyul/AsmAnalysisInfo.h>\n#include <libyul/AsmPrinter.h>\n#include <libyul/AST.h>\n#include <libyul/Object.h>\n\n#include <libyul/backends/evm/NoOutputAssembly.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Profiler.h>\n\n#include <libyul/CompilabilityChecker.h>\n\n#include <range/v3/view/map.hpp>\n#include <range/v3/action/remove.hpp>\n#include <range/v3/algorithm/count.hpp>\n#include <range/v3/algorithm/none_of.hpp>\n\n#include <limits>\n#include <tuple>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace std::string_literals;\n\nvoid OptimiserSuite::run(\n\tGasMeter const* _meter,\n\tObject& _object,\n\tbool _optimizeStackAllocation,\n\tstd::string_view _optimisationSequence,\n\tstd::string_view _optimisationCleanupSequence,\n\tstd::optional<size_t> _expectedExecutionsPerDeployment,\n\tstd::set<YulName> const& _externallyUsedIdentifiers\n)\n{\n\tyulAssert(_object.dialect());\n\tauto const& dialect = *_object.dialect();\n\tEVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(_object.dialect());\n\tbool usesOptimizedCodeGenerator =\n\t\t_optimizeStackAllocation &&\n\t\tevmDialect &&\n\t\tevmDialect->evmVersion().canOverchargeGasForCall() &&\n\t\tevmDialect->providesObjectAccess();\n\tstd::set<YulName> reservedIdentifiers = _externallyUsedIdentifiers;\n\n\tBlock astRoot;\n\t{\n\t\tPROFILER_PROBE(\"Disambiguator\", probe);\n\t\tastRoot = std::get<Block>(Disambiguator(\n\t\t\tdialect,\n\t\t\t*_object.analysisInfo,\n\t\t\treservedIdentifiers\n\t\t)(_object.code()->root()));\n\t}\n\n\tNameDispenser dispenser{dialect, astRoot, reservedIdentifiers};\n\tOptimiserStepContext context{dialect, dispenser, reservedIdentifiers, _expectedExecutionsPerDeployment};\n\n\tOptimiserSuite suite(context, Debug::None);\n\n\t// Some steps depend on properties ensured by FunctionHoister, BlockFlattener, FunctionGrouper and\n\t// ForLoopInitRewriter. Run them first to be able to run arbitrary sequences safely.\n\tsuite.runSequence(\"hgfo\", astRoot);\n\n\t// Now the user-supplied part\n\tsuite.runSequence(_optimisationSequence, astRoot);\n\n\t// This is a tuning parameter, but actually just prevents infinite loops.\n\tsize_t stackCompressorMaxIterations = 16;\n\tsuite.runSequence(\"g\", astRoot);\n\n\t// We ignore the return value because we will get a much better error\n\t// message once we perform code generation.\n\tif (!usesOptimizedCodeGenerator)\n\t{\n\t\tPROFILER_PROBE(\"StackCompressor\", probe);\n\t\t_object.setCode(std::make_shared<AST>(dialect, std::move(astRoot)));\n\t\tastRoot = std::get<1>(StackCompressor::run(\n\t\t\t_object,\n\t\t\t_optimizeStackAllocation,\n\t\t\tstackCompressorMaxIterations\n\t\t));\n\t}\n\n\t// Run the user-supplied clean up sequence\n\tsuite.runSequence(_optimisationCleanupSequence, astRoot);\n\t// Hard-coded FunctionGrouper step is used to bring the AST into a canonical form required by the StackCompressor\n\t// and StackLimitEvader. This is hard-coded as the last step, as some previously executed steps may break the\n\t// aforementioned form, thus causing the StackCompressor/StackLimitEvader to throw.\n\tsuite.runSequence(\"g\", astRoot);\n\n\tif (evmDialect)\n\t{\n\t\tyulAssert(_meter, \"\");\n\t\t{\n\t\t\tPROFILER_PROBE(\"ConstantOptimiser\", probe);\n\t\t\tConstantOptimiser{*evmDialect, *_meter}(astRoot);\n\t\t}\n\t\tif (usesOptimizedCodeGenerator)\n\t\t{\n\t\t\tif (!evmDialect->eofVersion().has_value())\n\t\t\t{\n\t\t\t\t{\n\t\t\t\t\tPROFILER_PROBE(\"StackCompressor\", probe);\n\t\t\t\t\t_object.setCode(std::make_shared<AST>(dialect, std::move(astRoot)));\n\t\t\t\t\tastRoot = std::get<1>(StackCompressor::run(\n\t\t\t\t\t\t_object,\n\t\t\t\t\t\t_optimizeStackAllocation,\n\t\t\t\t\t\tstackCompressorMaxIterations\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t\tif (evmDialect->providesObjectAccess())\n\t\t\t\t{\n\t\t\t\t\tPROFILER_PROBE(\"StackLimitEvader\", probe);\n\t\t\t\t\t_object.setCode(std::make_shared<AST>(dialect, std::move(astRoot)));\n\t\t\t\t\tastRoot = StackLimitEvader::run(suite.m_context, _object);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (evmDialect->providesObjectAccess() && _optimizeStackAllocation)\n\t\t{\n\t\t\tPROFILER_PROBE(\"StackLimitEvader\", probe);\n\t\t\tyulAssert(!evmDialect->eofVersion().has_value(), \"\");\n\t\t\t_object.setCode(std::make_shared<AST>(dialect, std::move(astRoot)));\n\t\t\tastRoot = StackLimitEvader::run(suite.m_context, _object);\n\t\t}\n\t}\n\n\tdispenser.reset(astRoot);\n\t{\n\t\tPROFILER_PROBE(\"NameSimplifier\", probe);\n\t\tNameSimplifier::run(suite.m_context, astRoot);\n\t}\n\t{\n\t\tPROFILER_PROBE(\"VarNameCleaner\", probe);\n\t\tVarNameCleaner::run(suite.m_context, astRoot);\n\t}\n\n\t_object.setCode(std::make_shared<AST>(dialect, std::move(astRoot)));\n\t_object.analysisInfo = std::make_shared<AsmAnalysisInfo>(AsmAnalyzer::analyzeStrictAssertCorrect(_object));\n}\n\nnamespace\n{\n\ntemplate <class... Step>\nstd::map<std::string, std::unique_ptr<OptimiserStep>> optimiserStepCollection()\n{\n\tstd::map<std::string, std::unique_ptr<OptimiserStep>> ret;\n\tfor (std::unique_ptr<OptimiserStep>& s: util::make_vector<std::unique_ptr<OptimiserStep>>(\n\t\t(std::make_unique<OptimiserStepInstance<Step>>())...\n\t))\n\t{\n\t\tyulAssert(!ret.count(s->name), \"\");\n\t\tret[s->name] = std::move(s);\n\t}\n\treturn ret;\n}\n\n}\n\nstd::map<std::string, std::unique_ptr<OptimiserStep>> const& OptimiserSuite::allSteps()\n{\n\tstatic std::map<std::string, std::unique_ptr<OptimiserStep>> instance;\n\tif (instance.empty())\n\t\tinstance = optimiserStepCollection<\n\t\t\tBlockFlattener,\n\t\t\tCircularReferencesPruner,\n\t\t\tCommonSubexpressionEliminator,\n\t\t\tConditionalSimplifier,\n\t\t\tConditionalUnsimplifier,\n\t\t\tControlFlowSimplifier,\n\t\t\tDeadCodeEliminator,\n\t\t\tEqualStoreEliminator,\n\t\t\tEquivalentFunctionCombiner,\n\t\t\tExpressionInliner,\n\t\t\tExpressionJoiner,\n\t\t\tExpressionSimplifier,\n\t\t\tExpressionSplitter,\n\t\t\tForLoopConditionIntoBody,\n\t\t\tForLoopConditionOutOfBody,\n\t\t\tForLoopInitRewriter,\n\t\t\tFullInliner,\n\t\t\tFunctionGrouper,\n\t\t\tFunctionHoister,\n\t\t\tFunctionSpecializer,\n\t\t\tLiteralRematerialiser,\n\t\t\tLoadResolver,\n\t\t\tLoopInvariantCodeMotion,\n\t\t\tUnusedAssignEliminator,\n\t\t\tUnusedStoreEliminator,\n\t\t\tRematerialiser,\n\t\t\tSSAReverser,\n\t\t\tSSATransform,\n\t\t\tStructuralSimplifier,\n\t\t\tUnusedFunctionParameterPruner,\n\t\t\tUnusedPruner,\n\t\t\tVarDeclInitializer\n\t\t>();\n\t// Does not include VarNameCleaner because it destroys the property of unique names.\n\t// Does not include NameSimplifier.\n\treturn instance;\n}\n\nstd::map<std::string, char> const& OptimiserSuite::stepNameToAbbreviationMap()\n{\n\tstatic std::map<std::string, char> lookupTable{\n\t\t{BlockFlattener::name,                'f'},\n\t\t{CircularReferencesPruner::name,      'l'},\n\t\t{CommonSubexpressionEliminator::name, 'c'},\n\t\t{ConditionalSimplifier::name,         'C'},\n\t\t{ConditionalUnsimplifier::name,       'U'},\n\t\t{ControlFlowSimplifier::name,         'n'},\n\t\t{DeadCodeEliminator::name,            'D'},\n\t\t{EqualStoreEliminator::name,          'E'},\n\t\t{EquivalentFunctionCombiner::name,    'v'},\n\t\t{ExpressionInliner::name,             'e'},\n\t\t{ExpressionJoiner::name,              'j'},\n\t\t{ExpressionSimplifier::name,          's'},\n\t\t{ExpressionSplitter::name,            'x'},\n\t\t{ForLoopConditionIntoBody::name,      'I'},\n\t\t{ForLoopConditionOutOfBody::name,     'O'},\n\t\t{ForLoopInitRewriter::name,           'o'},\n\t\t{FullInliner::name,                   'i'},\n\t\t{FunctionGrouper::name,               'g'},\n\t\t{FunctionHoister::name,               'h'},\n\t\t{FunctionSpecializer::name,           'F'},\n\t\t{LiteralRematerialiser::name,         'T'},\n\t\t{LoadResolver::name,                  'L'},\n\t\t{LoopInvariantCodeMotion::name,       'M'},\n\t\t{UnusedAssignEliminator::name,        'r'},\n\t\t{UnusedStoreEliminator::name,         'S'},\n\t\t{Rematerialiser::name,                'm'},\n\t\t{SSAReverser::name,                   'V'},\n\t\t{SSATransform::name,                  'a'},\n\t\t{StructuralSimplifier::name,          't'},\n\t\t{UnusedFunctionParameterPruner::name, 'p'},\n\t\t{UnusedPruner::name,                  'u'},\n\t\t{VarDeclInitializer::name,            'd'},\n\t};\n\tyulAssert(lookupTable.size() == allSteps().size(), \"\");\n\tyulAssert((\n\t\t\tutil::convertContainer<std::set<char>>(std::string(NonStepAbbreviations)) -\n\t\t\tutil::convertContainer<std::set<char>>(lookupTable | ranges::views::values)\n\t\t).size() == std::string(NonStepAbbreviations).size(),\n\t\t\"Step abbreviation conflicts with a character reserved for another syntactic element\"\n\t);\n\n\treturn lookupTable;\n}\n\nstd::map<char, std::string> const& OptimiserSuite::stepAbbreviationToNameMap()\n{\n\tstatic std::map<char, std::string> lookupTable = util::invertMap(stepNameToAbbreviationMap());\n\n\treturn lookupTable;\n}\n\nvoid OptimiserSuite::validateSequence(std::string_view _stepAbbreviations)\n{\n\tint8_t nestingLevel = 0;\n\tint8_t colonDelimiters = 0;\n\tfor (char abbreviation: _stepAbbreviations)\n\t\tswitch (abbreviation)\n\t\t{\n\t\tcase ' ':\n\t\tcase '\\n':\n\t\t\tbreak;\n\t\tcase '[':\n\t\t\tassertThrow(nestingLevel < std::numeric_limits<int8_t>::max(), OptimizerException, \"Brackets nested too deep\");\n\t\t\tnestingLevel++;\n\t\t\tbreak;\n\t\tcase ']':\n\t\t\tnestingLevel--;\n\t\t\tassertThrow(nestingLevel >= 0, OptimizerException, \"Unbalanced brackets\");\n\t\t\tbreak;\n\t\tcase ':':\n\t\t\t++colonDelimiters;\n\t\t\tassertThrow(nestingLevel == 0, OptimizerException, \"Cleanup sequence delimiter cannot be placed inside the brackets\");\n\t\t\tassertThrow(colonDelimiters <= 1, OptimizerException, \"Too many cleanup sequence delimiters\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t{\n\t\t\tyulAssert(\n\t\t\t\tstd::string(NonStepAbbreviations).find(abbreviation) == std::string::npos,\n\t\t\t\t\"Unhandled syntactic element in the abbreviation sequence\"\n\t\t\t);\n\t\t\tassertThrow(\n\t\t\t\tstepAbbreviationToNameMap().find(abbreviation) != stepAbbreviationToNameMap().end(),\n\t\t\t\tOptimizerException,\n\t\t\t\t\"'\"s + abbreviation + \"' is not a valid step abbreviation\"\n\t\t\t);\n\t\t\tstd::optional<std::string> invalid = allSteps().at(stepAbbreviationToNameMap().at(abbreviation))->invalidInCurrentEnvironment();\n\t\t\tassertThrow(\n\t\t\t\t!invalid.has_value(),\n\t\t\t\tOptimizerException,\n\t\t\t\t\"'\"s + abbreviation + \"' is invalid in the current environment: \" + *invalid\n\t\t\t);\n\t\t}\n\t\t}\n\tassertThrow(nestingLevel == 0, OptimizerException, \"Unbalanced brackets\");\n}\n\nbool OptimiserSuite::isEmptyOptimizerSequence(std::string const& _sequence)\n{\n\treturn\n\t\tranges::count(_sequence, ':') == 1 &&\n\t\tranges::none_of(_sequence, [](auto _step) { return _step != ':' && _step != ' ' && _step != '\\n'; });\n}\n\nvoid OptimiserSuite::runSequence(std::string_view _stepAbbreviations, Block& _ast, bool _repeatUntilStable)\n{\n\tvalidateSequence(_stepAbbreviations);\n\n\t// This splits 'aaa[bbb]ccc...' into 'aaa' and '[bbb]ccc...'.\n\tauto extractNonNestedPrefix = [](std::string_view _tail) -> std::tuple<std::string_view, std::string_view>\n\t{\n\t\tfor (size_t i = 0; i < _tail.size(); ++i)\n\t\t{\n\t\t\tyulAssert(_tail[i] != ']');\n\t\t\tif (_tail[i] == '[')\n\t\t\t\treturn {_tail.substr(0, i), _tail.substr(i)};\n\t\t}\n\t\treturn {_tail, {}};\n\t};\n\n\t// This splits '[bbb]ccc...' into 'bbb' and 'ccc...'.\n\tauto extractBracketContent = [](std::string_view _tail) -> std::tuple<std::string_view, std::string_view>\n\t{\n\t\tyulAssert(!_tail.empty() && _tail[0] == '[');\n\n\t\tsize_t contentLength = 0;\n\t\tint8_t nestingLevel = 1;\n\t\tfor (char abbreviation: _tail.substr(1))\n\t\t{\n\t\t\tif (abbreviation == '[')\n\t\t\t{\n\t\t\t\tyulAssert(nestingLevel < std::numeric_limits<int8_t>::max());\n\t\t\t\t++nestingLevel;\n\t\t\t}\n\t\t\telse if (abbreviation == ']')\n\t\t\t{\n\t\t\t\t--nestingLevel;\n\t\t\t\tif (nestingLevel == 0)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t++contentLength;\n\t\t}\n\t\tyulAssert(nestingLevel == 0);\n\t\tyulAssert(_tail[contentLength + 1] == ']');\n\n\t\treturn {_tail.substr(1, contentLength), _tail.substr(contentLength + 2)};\n\t};\n\n\tauto abbreviationsToSteps = [](std::string_view _sequence) -> std::vector<std::string>\n\t{\n\t\tstd::vector<std::string> steps;\n\t\tfor (char abbreviation: _sequence)\n\t\t\tif (abbreviation != ' ' && abbreviation != '\\n')\n\t\t\t\tsteps.emplace_back(stepAbbreviationToNameMap().at(abbreviation));\n\t\treturn steps;\n\t};\n\n\tstd::vector<std::tuple<std::string_view, bool>> subsequences;\n\tstd::string_view tail = _stepAbbreviations;\n\twhile (!tail.empty())\n\t{\n\t\tstd::string_view subsequence;\n\t\ttie(subsequence, tail) = extractNonNestedPrefix(tail);\n\t\tif (subsequence.size() > 0)\n\t\t\tsubsequences.push_back({subsequence, false});\n\n\t\tif (tail.empty())\n\t\t\tbreak;\n\n\t\ttie(subsequence, tail) = extractBracketContent(tail);\n\t\tif (subsequence.size() > 0)\n\t\t\tsubsequences.push_back({subsequence, true});\n\t}\n\n\t// NOTE: If _repeatUntilStable is false, the value will not be used so do not calculate it.\n\tsize_t codeSize = (_repeatUntilStable ? CodeSize::codeSizeIncludingFunctions(_ast) : 0);\n\n\tfor (size_t round = 0; round < MaxRounds; ++round)\n\t{\n\t\tfor (auto const& [subsequence, repeat]: subsequences)\n\t\t{\n\t\t\tif (repeat)\n\t\t\t\trunSequence(subsequence, _ast, true);\n\t\t\telse\n\t\t\t\trunSequence(abbreviationsToSteps(subsequence), _ast);\n\t\t}\n\n\t\tif (!_repeatUntilStable)\n\t\t\tbreak;\n\n\t\tsize_t newSize = CodeSize::codeSizeIncludingFunctions(_ast);\n\t\tif (newSize == codeSize)\n\t\t\tbreak;\n\t\tcodeSize = newSize;\n\t}\n}\n\nvoid OptimiserSuite::runSequence(std::vector<std::string> const& _steps, Block& _ast)\n{\n\tstd::unique_ptr<Block> copy;\n\tif (m_debug == Debug::PrintChanges)\n\t\tcopy = std::make_unique<Block>(std::get<Block>(ASTCopier{}(_ast)));\n\tfor (std::string const& step: _steps)\n\t{\n\t\tif (m_debug == Debug::PrintStep)\n\t\t\tstd::cout << \"Running \" << step << std::endl;\n\n\t\t{\n\t\t\tPROFILER_PROBE(step, probe);\n\t\t\tallSteps().at(step)->run(m_context, _ast);\n\t\t}\n\n\t\tif (m_debug == Debug::PrintChanges)\n\t\t{\n\t\t\t// TODO should add switch to also compare variable names!\n\t\t\tif (SyntacticallyEqual{}.statementEqual(_ast, *copy))\n\t\t\t\tstd::cout << \"== Running \" << step << \" did not cause changes.\" << std::endl;\n\t\t\telse\n\t\t\t{\n\t\t\t\tstd::cout << \"== Running \" << step << \" changed the AST.\" << std::endl;\n\t\t\t\tstd::cout << AsmPrinter{m_context.dialect}(_ast) << std::endl;\n\t\t\t\tcopy = std::make_unique<Block>(std::get<Block>(ASTCopier{}(_ast)));\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "libyul/optimiser/Suite.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser suite that combines all steps and also provides the settings for the heuristics.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/YulName.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/optimiser/NameDispenser.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <set>\n#include <string>\n#include <string_view>\n#include <memory>\n\nnamespace solidity::yul\n{\n\nstruct AsmAnalysisInfo;\nclass Dialect;\nclass GasMeter;\nclass Object;\n\n/**\n * Optimiser suite that combines all steps and also provides the settings for the heuristics.\n * Only optimizes the code of the provided object, does not descend into the sub-objects.\n */\nclass OptimiserSuite\n{\npublic:\n\tstatic constexpr size_t MaxRounds = 12;\n\n\t/// Special characters that do not represent optimiser steps but are allowed in abbreviation sequences.\n\t/// Some of them (like whitespace) are ignored, others (like brackets) are a part of the syntax.\n\tstatic constexpr char NonStepAbbreviations[] = \" \\n[]:\";\n\n\tenum class Debug\n\t{\n\t\tNone,\n\t\tPrintStep,\n\t\tPrintChanges\n\t};\n\tOptimiserSuite(OptimiserStepContext& _context, Debug _debug = Debug::None): m_context(_context), m_debug(_debug) {}\n\n\t/// The value nullopt for `_expectedExecutionsPerDeployment` represents creation code.\n\tstatic void run(\n\t\tGasMeter const* _meter,\n\t\tObject& _object,\n\t\tbool _optimizeStackAllocation,\n\t\tstd::string_view _optimisationSequence,\n\t\tstd::string_view _optimisationCleanupSequence,\n\t\tstd::optional<size_t> _expectedExecutionsPerDeployment,\n\t\tstd::set<YulName> const& _externallyUsedIdentifiers = {}\n\t);\n\n\t/// Ensures that specified sequence of step abbreviations is well-formed and can be executed.\n\t/// @throw OptimizerException if the sequence is invalid\n\tstatic void validateSequence(std::string_view _stepAbbreviations);\n\t/// Check whether the provided sequence is empty provided that the allowed characters are\n\t/// whitespace, newline and :\n\tstatic bool isEmptyOptimizerSequence(std::string const& _sequence);\n\n\n\tvoid runSequence(std::vector<std::string> const& _steps, Block& _ast);\n\tvoid runSequence(std::string_view _stepAbbreviations, Block& _ast, bool _repeatUntilStable = false);\n\n\tstatic std::map<std::string, std::unique_ptr<OptimiserStep>> const& allSteps();\n\tstatic std::map<std::string, char> const& stepNameToAbbreviationMap();\n\tstatic std::map<char, std::string> const& stepAbbreviationToNameMap();\n\nprivate:\n\tOptimiserStepContext& m_context;\n\tDebug m_debug;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/SyntacticalEquality.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * Component that can compare ASTs for equality on a syntactic basis.\n */\n\n#include <libyul/optimiser/SyntacticalEquality.h>\n\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n#include <libyul/Exceptions.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Visitor.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nbool SyntacticallyEqual::operator()(Expression const& _lhs, Expression const& _rhs)\n{\n\treturn std::visit([this](auto&& _lhsExpr, auto&& _rhsExpr) -> bool {\n\t\t// ``this->`` is redundant, but required to work around a bug present in gcc 6.x.\n\t\treturn this->expressionEqual(_lhsExpr, _rhsExpr);\n\t}, _lhs, _rhs);\n}\n\nbool SyntacticallyEqual::operator()(Statement const& _lhs, Statement const& _rhs)\n{\n\treturn std::visit([this](auto&& _lhsStmt, auto&& _rhsStmt) -> bool {\n\t\t// ``this->`` is redundant, but required to work around a bug present in gcc 6.x.\n\t\treturn this->statementEqual(_lhsStmt, _rhsStmt);\n\t}, _lhs, _rhs);\n}\n\nbool SyntacticallyEqual::expressionEqual(FunctionCall const& _lhs, FunctionCall const& _rhs)\n{\n\treturn\n\t\texpressionEqual(_lhs.functionName, _rhs.functionName) &&\n\t\tutil::containerEqual(_lhs.arguments, _rhs.arguments, [this](Expression const& _lhsExpr, Expression const& _rhsExpr) -> bool {\n\t\t\treturn (*this)(_lhsExpr, _rhsExpr);\n\t\t});\n}\n\nbool SyntacticallyEqual::expressionEqual(FunctionName const& _lhs, FunctionName const& _rhs)\n{\n\treturn std::visit(util::GenericVisitor{\n\t\t[&](BuiltinName const& _builtin) { return std::holds_alternative<BuiltinName>(_rhs) && _builtin.handle == std::get<BuiltinName>(_rhs).handle; },\n\t\t[&](Identifier const& _identifier) { return std::holds_alternative<Identifier>(_rhs) && expressionEqual(_identifier, std::get<Identifier>(_rhs)); },\n\t}, _lhs);\n}\n\nbool SyntacticallyEqual::expressionEqual(Identifier const& _lhs, Identifier const& _rhs)\n{\n\tauto lhsIt = m_identifiersLHS.find(_lhs.name);\n\tauto rhsIt = m_identifiersRHS.find(_rhs.name);\n\treturn\n\t\t(lhsIt == m_identifiersLHS.end() && rhsIt == m_identifiersRHS.end() && _lhs.name == _rhs.name) ||\n\t\t(lhsIt != m_identifiersLHS.end() && rhsIt != m_identifiersRHS.end() && lhsIt->second == rhsIt->second);\n}\nbool SyntacticallyEqual::expressionEqual(Literal const& _lhs, Literal const& _rhs)\n{\n\tassert(validLiteral(_lhs));\n\tassert(validLiteral(_rhs));\n\treturn _lhs.value == _rhs.value;\n}\n\nbool SyntacticallyEqual::statementEqual(ExpressionStatement const& _lhs, ExpressionStatement const& _rhs)\n{\n\treturn (*this)(_lhs.expression, _rhs.expression);\n}\nbool SyntacticallyEqual::statementEqual(Assignment const& _lhs, Assignment const& _rhs)\n{\n\treturn util::containerEqual(\n\t\t_lhs.variableNames,\n\t\t_rhs.variableNames,\n\t\t[this](Identifier const& _lhsVarName, Identifier const& _rhsVarName) -> bool {\n\t\t\treturn this->expressionEqual(_lhsVarName, _rhsVarName);\n\t\t}\n\t) && (*this)(*_lhs.value, *_rhs.value);\n}\n\nbool SyntacticallyEqual::statementEqual(VariableDeclaration const& _lhs, VariableDeclaration const& _rhs)\n{\n\t// first visit expression, then variable declarations\n\tif (!compareUniquePtr<Expression, &SyntacticallyEqual::operator()>(_lhs.value, _rhs.value))\n\t\treturn false;\n\treturn util::containerEqual(_lhs.variables, _rhs.variables, [this](NameWithDebugData const& _lhsVarName, NameWithDebugData const& _rhsVarName) -> bool {\n\t\treturn this->visitDeclaration(_lhsVarName, _rhsVarName);\n\t});\n}\n\nbool SyntacticallyEqual::statementEqual(FunctionDefinition const& _lhs, FunctionDefinition const& _rhs)\n{\n\tauto compare = [this](NameWithDebugData const& _lhsVarName, NameWithDebugData const& _rhsVarName) -> bool {\n\t\treturn this->visitDeclaration(_lhsVarName, _rhsVarName);\n\t};\n\t// first visit parameter declarations, then body\n\tif (!util::containerEqual(_lhs.parameters, _rhs.parameters, compare))\n\t\treturn false;\n\tif (!util::containerEqual(_lhs.returnVariables, _rhs.returnVariables, compare))\n\t\treturn false;\n\treturn statementEqual(_lhs.body, _rhs.body);\n}\n\nbool SyntacticallyEqual::statementEqual(If const& _lhs, If const& _rhs)\n{\n\treturn\n\t\tcompareUniquePtr<Expression, &SyntacticallyEqual::operator()>(_lhs.condition, _rhs.condition) &&\n\t\tstatementEqual(_lhs.body, _rhs.body);\n}\n\nbool SyntacticallyEqual::statementEqual(Switch const& _lhs, Switch const& _rhs)\n{\n\tstd::set<Case const*, SwitchCaseCompareByLiteralValue> lhsCases;\n\tstd::set<Case const*, SwitchCaseCompareByLiteralValue> rhsCases;\n\tfor (auto const& lhsCase: _lhs.cases)\n\t\tlhsCases.insert(&lhsCase);\n\tfor (auto const& rhsCase: _rhs.cases)\n\t\trhsCases.insert(&rhsCase);\n\treturn\n\t\tcompareUniquePtr<Expression, &SyntacticallyEqual::operator()>(_lhs.expression, _rhs.expression) &&\n\t\tutil::containerEqual(lhsCases, rhsCases, [this](Case const* _lhsCase, Case const* _rhsCase) -> bool {\n\t\t\treturn this->switchCaseEqual(*_lhsCase, *_rhsCase);\n\t\t});\n}\n\n\nbool SyntacticallyEqual::switchCaseEqual(Case const& _lhs, Case const& _rhs)\n{\n\treturn\n\t\tcompareUniquePtr<Literal, &SyntacticallyEqual::expressionEqual>(_lhs.value, _rhs.value) &&\n\t\tstatementEqual(_lhs.body, _rhs.body);\n}\n\nbool SyntacticallyEqual::statementEqual(ForLoop const& _lhs, ForLoop const& _rhs)\n{\n\treturn\n\t\tstatementEqual(_lhs.pre, _rhs.pre) &&\n\t\tcompareUniquePtr<Expression, &SyntacticallyEqual::operator()>(_lhs.condition, _rhs.condition) &&\n\t\tstatementEqual(_lhs.body, _rhs.body) &&\n\t\tstatementEqual(_lhs.post, _rhs.post);\n}\n\nbool SyntacticallyEqual::statementEqual(Block const& _lhs, Block const& _rhs)\n{\n\treturn util::containerEqual(_lhs.statements, _rhs.statements, [this](Statement const& _lhsStmt, Statement const& _rhsStmt) -> bool {\n\t\treturn (*this)(_lhsStmt, _rhsStmt);\n\t});\n}\n\nbool SyntacticallyEqual::visitDeclaration(NameWithDebugData const& _lhs, NameWithDebugData const& _rhs)\n{\n\tstd::size_t id = m_idsUsed++;\n\tm_identifiersLHS[_lhs.name] = id;\n\tm_identifiersRHS[_rhs.name] = id;\n\treturn true;\n}\n\nbool SyntacticallyEqualExpression::operator()(Expression const& _lhs, Expression const& _rhs) const\n{\n\treturn SyntacticallyEqual{}(_lhs, _rhs);\n}\n\n"
  },
  {
    "path": "libyul/optimiser/SyntacticalEquality.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Component that can compare ASTs for equality on a syntactic basis.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/YulName.h>\n\n#include <map>\n#include <type_traits>\n\nnamespace solidity::yul\n{\n\n\n/**\n * Component that can compare ASTs for equality on a syntactic basis.\n * Ignores source locations and allows for different variable names but requires exact matches otherwise.\n * Literals are compared based on their values, e.g., `0x01`, `1`, `\"\\x01\"` and `true` all evaluate as equal.\n * Note that this does not apply to unlimited literal strings, which are never considered equal to normal literals,\n * even when the values would look like identical strings in the source.\n *\n * Prerequisite: Disambiguator (unless only expressions are compared)\n */\nclass SyntacticallyEqual\n{\npublic:\n\tbool operator()(Expression const& _lhs, Expression const& _rhs);\n\tbool operator()(Statement const& _lhs, Statement const& _rhs);\n\n\tbool expressionEqual(FunctionCall const& _lhs, FunctionCall const& _rhs);\n\tbool expressionEqual(Identifier const& _lhs, Identifier const& _rhs);\n\tbool expressionEqual(FunctionName const& _lhs, FunctionName const& _rhs);\n\tbool expressionEqual(Literal const& _lhs, Literal const& _rhs);\n\n\tbool statementEqual(ExpressionStatement const& _lhs, ExpressionStatement const& _rhs);\n\tbool statementEqual(Assignment const& _lhs, Assignment const& _rhs);\n\tbool statementEqual(VariableDeclaration const& _lhs, VariableDeclaration const& _rhs);\n\tbool statementEqual(FunctionDefinition const& _lhs, FunctionDefinition const& _rhs);\n\tbool statementEqual(If const& _lhs, If const& _rhs);\n\tbool statementEqual(Switch const& _lhs, Switch const& _rhs);\n\tbool switchCaseEqual(Case const& _lhs, Case const& _rhs);\n\tbool statementEqual(ForLoop const& _lhs, ForLoop const& _rhs);\n\tbool statementEqual(Break const&, Break const&) { return true; }\n\tbool statementEqual(Continue const&, Continue const&) { return true; }\n\tbool statementEqual(Leave const&, Leave const&) { return true; }\n\tbool statementEqual(Block const& _lhs, Block const& _rhs);\nprivate:\n\tbool visitDeclaration(NameWithDebugData const& _lhs, NameWithDebugData const& _rhs);\n\n\ttemplate<typename U, typename V>\n\tbool expressionEqual(U const&, V const&, std::enable_if_t<!std::is_same<U, V>::value>* = nullptr)\n\t{\n\t\treturn false;\n\t}\n\n\ttemplate<typename U, typename V>\n\tbool statementEqual(U const&, V const&, std::enable_if_t<!std::is_same<U, V>::value>* = nullptr)\n\t{\n\t\treturn false;\n\t}\n\n\ttemplate<typename T, bool (SyntacticallyEqual::*CompareMember)(T const&, T const&)>\n\tbool compareUniquePtr(std::unique_ptr<T> const& _lhs, std::unique_ptr<T> const& _rhs)\n\t{\n\t\treturn (_lhs == _rhs) || (_lhs && _rhs && (this->*CompareMember)(*_lhs, *_rhs));\n\t}\n\n\tstd::size_t m_idsUsed = 0;\n\tstd::map<YulName, std::size_t> m_identifiersLHS;\n\tstd::map<YulName, std::size_t> m_identifiersRHS;\n};\n\n/**\n * Does the same as SyntacticallyEqual just that the operator() function is const.\n */\nstruct SyntacticallyEqualExpression\n{\n\tbool operator()(Expression const& _lhs, Expression const& _rhs) const;\n};\n\n\n}\n"
  },
  {
    "path": "libyul/optimiser/UnusedAssignEliminator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that removes assignments to variables that are not used\n * until they go out of scope or are re-assigned.\n */\n\n#include <libyul/optimiser/UnusedAssignEliminator.h>\n\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/ControlFlowSideEffectsCollector.h>\n#include <libyul/Utilities.h>\n#include <libyul/AST.h>\n#include <libyul/AsmPrinter.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <range/v3/action/remove_if.hpp>\n\n#include <iostream>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid UnusedAssignEliminator::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tUnusedAssignEliminator uae{\n\t\t_context.dialect,\n\t\tControlFlowSideEffectsCollector{_context.dialect, _ast}.functionSideEffectsNamed()\n\t};\n\tuae(_ast);\n\n\tuae.m_storesToRemove += uae.m_allStores - uae.m_usedStores;\n\n\tstd::set<Statement const*> toRemove{uae.m_storesToRemove.begin(), uae.m_storesToRemove.end()};\n\tStatementRemover remover{toRemove};\n\tremover(_ast);\n}\n\nvoid UnusedAssignEliminator::operator()(Identifier const& _identifier)\n{\n\tmarkUsed(_identifier.name);\n}\n\nvoid UnusedAssignEliminator::operator()(Assignment const& _assignment)\n{\n\tvisit(*_assignment.value);\n\t// Do not visit the variables because they are Identifiers\n}\n\n\nvoid UnusedAssignEliminator::operator()(FunctionDefinition const& _functionDefinition)\n{\n\tScopedSaveAndRestore outerReturnVariables(m_returnVariables, {});\n\n\tfor (auto const& retParam: _functionDefinition.returnVariables)\n\t\tm_returnVariables.insert(retParam.name);\n\n\tUnusedStoreBase::operator()(_functionDefinition);\n}\n\nvoid UnusedAssignEliminator::operator()(FunctionCall const& _functionCall)\n{\n\tUnusedStoreBase::operator()(_functionCall);\n\n\tControlFlowSideEffects sideEffects;\n\tif (BuiltinFunction const* builtin = resolveBuiltinFunction(_functionCall.functionName, m_dialect))\n\t\tsideEffects = builtin->controlFlowSideEffects;\n\telse\n\t{\n\t\tyulAssert(std::holds_alternative<Identifier>(_functionCall.functionName));\n\t\tsideEffects = m_controlFlowSideEffects.at(std::get<Identifier>(_functionCall.functionName).name);\n\t}\n\n\tif (!sideEffects.canContinue)\n\t\t// We do not return from the current function, so it is OK to also\n\t\t// clear the return variables.\n\t\tm_activeStores.clear();\n}\n\nvoid UnusedAssignEliminator::operator()(Leave const&)\n{\n\tfor (YulName name: m_returnVariables)\n\t\tmarkUsed(name);\n\tm_activeStores.clear();\n}\n\nvoid UnusedAssignEliminator::operator()(Block const& _block)\n{\n\tUnusedStoreBase::operator()(_block);\n\n\tfor (auto const& statement: _block.statements)\n\t\tif (auto const* varDecl = std::get_if<VariableDeclaration>(&statement))\n\t\t\tfor (auto const& var: varDecl->variables)\n\t\t\t\tm_activeStores.erase(var.name);\n}\n\nvoid UnusedAssignEliminator::visit(Statement const& _statement)\n{\n\tUnusedStoreBase::visit(_statement);\n\n\tif (auto const* assignment = std::get_if<Assignment>(&_statement))\n\t{\n\t\t// We do not remove assignments whose values might have side-effects,\n\t\t// but clear the active stores to the assigned variables in any case.\n\t\tif (SideEffectsCollector{m_dialect, *assignment->value}.movable())\n\t\t{\n\t\t\tm_allStores.insert(&_statement);\n\t\t\tfor (auto const& var: assignment->variableNames)\n\t\t\t\tm_activeStores[var.name] = {&_statement};\n\t\t}\n\t\telse\n\t\t\tfor (auto const& var: assignment->variableNames)\n\t\t\t\tm_activeStores[var.name].clear();\n\t}\n}\n\nvoid UnusedAssignEliminator::shortcutNestedLoop(ActiveStores const& _zeroRuns)\n{\n\t// Shortcut to avoid horrible runtime:\n\t// Change all assignments that were newly introduced in the for loop to \"used\".\n\t// We do not have to do that with the \"break\" or \"continue\" paths, because\n\t// they will be joined later anyway.\n\n\tfor (auto& [variable, stores]: m_activeStores)\n\t{\n\t\tauto zeroIt = _zeroRuns.find(variable);\n\t\tfor (auto& assignment: stores)\n\t\t{\n\t\t\tif (zeroIt != _zeroRuns.end() && zeroIt->second.count(assignment))\n\t\t\t\tcontinue;\n\t\t\tm_usedStores.insert(assignment);\n\t\t}\n\t}\n}\n\nvoid UnusedAssignEliminator::finalizeFunctionDefinition(FunctionDefinition const& _functionDefinition)\n{\n\tfor (auto const& retParam: _functionDefinition.returnVariables)\n\t\tmarkUsed(retParam.name);\n}\n\nvoid UnusedAssignEliminator::markUsed(YulName _variable)\n{\n\tfor (auto& assignment: m_activeStores[_variable])\n\t\tm_usedStores.insert(assignment);\n\tm_activeStores.erase(_variable);\n}\n"
  },
  {
    "path": "libyul/optimiser/UnusedAssignEliminator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that removes assignments to variables that are not used\n * until they go out of scope or are re-assigned.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/optimiser/UnusedStoreBase.h>\n#include <libyul/optimiser/Semantics.h>\n\n#include <map>\n#include <vector>\n\nnamespace solidity::yul\n{\nclass Dialect;\n\n/**\n * Optimiser component that removes assignments to variables that are not used\n * until they go out of scope or are re-assigned. This component\n * respects the control-flow and takes it into account for removal.\n *\n * Example:\n *\n * {\n *   let a\n *   a := 1\n *   a := 2\n *   b := 2\n *   if calldataload(0)\n *   {\n *     b := mload(a)\n *   }\n *   a := b\n * }\n *\n * In the example, \"a := 1\" can be removed because the value from this assignment\n * is not used in any control-flow branch (it is replaced right away).\n * The assignment \"a := 2\" is also overwritten by \"a := b\" at the end,\n * but there is a control-flow path (through the condition body) which uses\n * the value from \"a := 2\" and thus, this assignment cannot be removed.\n *\n * Detailed rules:\n *\n * The AST is traversed twice: in an information gathering step and in the\n * actual removal step. During information gathering, assignment statements\n * can be marked as \"potentially unused\" or as \"used\".\n *\n * When an assignment is visited, it is stored in the \"set of all stores\" and\n * added to the branch-dependent \"active\" sets for the assigned variables. This active\n * set for a variable contains all statements where that variable was last assigned to, i.e.\n * where a read from that variable could read from.\n * Furthermore, all other active sets for the assigned variables are cleared.\n *\n * When a reference to a variable is visited, the active assignments to that variable\n * in the current branch are marked as \"used\". This mark is permanent.\n * Also, the active set for this variable in the current branch is cleared.\n *\n * At points where control-flow splits, we maintain a copy of the active set\n * (all other data structures are shared across branches).\n *\n * At control-flow joins, we combine the sets of active stores for each variable.\n *\n * In the example above, the active set right after the assignment \"b := mload(a)\" (but before\n * the control-flow join) is \"b := mload(a)\"; the assignment \"b := 2\" was removed.\n * After the control-flow join it will contain both \"b := mload(a)\" and \"b := 2\", coming from\n * the two branches.\n *\n * For for-loops, the condition, body and post-part are visited twice, taking\n * the joining control-flow at the condition into account.\n * In other words, we create three control flow paths: Zero runs of the loop,\n * one run and two runs and then combine them at the end.\n * Running at most twice is enough because this takes into account all possible control-flow connections.\n *\n * Since this algorithm has exponential runtime in the nesting depth of for loops,\n * a shortcut is taken at a certain nesting level: We only use the zero- and\n * once-run of the for loop and change any assignment that was newly introduced\n * in the for loop from to \"used\".\n *\n * For switch statements that have a \"default\"-case, there is no control-flow\n * part that skips the switch.\n *\n * At ``leave`` statements, all return variables are set to \"used\" and the set of active statements\n * is cleared.\n *\n * If a function or builtin is called that does not continue, the set of active statements is\n * cleared for all variables.\n *\n * In the second traversal, all assignments that are not marked as \"used\" are removed.\n *\n * This step is usually run right after the SSA transform to complete\n * the generation of the pseudo-SSA.\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter.\n */\nclass UnusedAssignEliminator: public UnusedStoreBase<YulName>\n{\npublic:\n\tstatic constexpr char const* name{\"UnusedAssignEliminator\"};\n\tstatic void run(OptimiserStepContext&, Block& _ast);\n\n\texplicit UnusedAssignEliminator(\n\t\tDialect const& _dialect,\n\t\tstd::map<YulName, ControlFlowSideEffects> _controlFlowSideEffects\n\t):\n\t\tUnusedStoreBase(_dialect),\n\t\tm_controlFlowSideEffects(_controlFlowSideEffects)\n\t{}\n\n\tvoid operator()(Identifier const& _identifier) override;\n\tvoid operator()(Assignment const& _assignment) override;\n\tvoid operator()(FunctionDefinition const&) override;\n\tvoid operator()(FunctionCall const& _functionCall) override;\n\tvoid operator()(Leave const&) override;\n\tvoid operator()(Block const& _block) override;\n\n\tusing UnusedStoreBase::visit;\n\tvoid visit(Statement const& _statement) override;\n\nprivate:\n\tvoid shortcutNestedLoop(ActiveStores const& _beforeLoop) override;\n\tvoid finalizeFunctionDefinition(FunctionDefinition const& _functionDefinition) override;\n\n\tvoid markUsed(YulName _variable);\n\n\tstd::set<YulName> m_returnVariables;\n\tstd::map<YulName, ControlFlowSideEffects> m_controlFlowSideEffects;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/UnusedFunctionParameterPruner.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * UnusedFunctionParameterPruner: Optimiser step that removes unused parameters from function\n * definition.\n */\n\n#include <libyul/optimiser/UnusedFunctionParameterPruner.h>\n#include <libyul/optimiser/UnusedFunctionsCommon.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/NameDisplacer.h>\n#include <libyul/optimiser/NameDispenser.h>\n#include <libyul/YulName.h>\n#include <libyul/AST.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <range/v3/algorithm/all_of.hpp>\n\n#include <optional>\n#include <variant>\n\nusing namespace solidity::util;\nusing namespace solidity::yul;\nusing namespace solidity::yul::unusedFunctionsCommon;\n\nvoid UnusedFunctionParameterPruner::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tstd::map<YulName, size_t> references = VariableReferencesCounter::countReferences(_ast);\n\tauto used = [&](auto v) -> bool { return references.count(v.name); };\n\n\t// Function name and a pair of boolean masks, the first corresponds to parameters and the second\n\t// corresponds to returnVariables.\n\t//\n\t// For the first vector in the pair, a value `false` at index `i` indicates that the function\n\t// argument at index `i` in `FunctionDefinition::parameters` is unused inside the function body.\n\t//\n\t// Similarly for the second vector in the pair, a value `false` at index `i` indicates that the\n\t// return parameter at index `i` in `FunctionDefinition::returnVariables` is unused inside\n\t// function body.\n\tstd::map<YulName, std::pair<std::vector<bool>, std::vector<bool>>> usedParametersAndReturnVariables;\n\n\t// Step 1 of UnusedFunctionParameterPruner: Find functions whose parameters (both arguments and\n\t// return-parameters) are not used in its body.\n\tfor (auto const& statement: _ast.statements)\n\t\tif (std::holds_alternative<FunctionDefinition>(statement))\n\t\t{\n\t\t\tFunctionDefinition const& f = std::get<FunctionDefinition>(statement);\n\n\t\t\tif (tooSimpleToBePruned(f) || ranges::all_of(f.parameters + f.returnVariables, used))\n\t\t\t\tcontinue;\n\n\t\t\tusedParametersAndReturnVariables[f.name] = {\n\t\t\t\tapplyMap(f.parameters, used),\n\t\t\t\tapplyMap(f.returnVariables, used)\n\t\t\t};\n\t\t}\n\n\tstd::set<YulName> functionNamesToFree = util::keys(usedParametersAndReturnVariables);\n\n\t// Step 2 of UnusedFunctionParameterPruner: Renames the function and replaces all references to\n\t// the function, say `f`, by its new name, say `f_1`.\n\tNameDisplacer replace{_context.dispenser, functionNamesToFree};\n\treplace(_ast);\n\n\t// Inverse-Map of the above translations. In the above example, this will store an element with\n\t// key `f_1` and value `f`.\n\tstd::map<YulName, YulName> newToOriginalNames = invertMap(replace.translations());\n\n\t// Step 3 of UnusedFunctionParameterPruner: introduce a new function in the block with body of\n\t// the old one. Replace the body of the old one with a function call to the new one with reduced\n\t// parameters.\n\t//\n\t// For example: introduce a new 'linking' function `f` with the same the body as `f_1`, but with\n\t// reduced parameters, i.e., `function f() -> y { y := 1 }`. Now replace the body of `f_1` with\n\t// a call to `f`, i.e., `f_1(x) -> y { y := f() }`.\n\titerateReplacing(_ast.statements, [&](Statement& _s) -> std::optional<std::vector<Statement>> {\n\t\tif (std::holds_alternative<FunctionDefinition>(_s))\n\t\t{\n\t\t\t// The original function except that it has a new name (e.g., `f_1`)\n\t\t\tFunctionDefinition& originalFunction = std::get<FunctionDefinition>(_s);\n\t\t\tif (newToOriginalNames.count(originalFunction.name))\n\t\t\t{\n\n\t\t\t\tYulName linkingFunctionName = originalFunction.name;\n\t\t\t\tYulName originalFunctionName = newToOriginalNames.at(linkingFunctionName);\n\t\t\t\tstd::pair<std::vector<bool>, std::vector<bool>> used =\n\t\t\t\t\tusedParametersAndReturnVariables.at(originalFunctionName);\n\n\t\t\t\tFunctionDefinition linkingFunction = createLinkingFunction(\n\t\t\t\t\toriginalFunction,\n\t\t\t\t\tused,\n\t\t\t\t\toriginalFunctionName,\n\t\t\t\t\tlinkingFunctionName,\n\t\t\t\t\t_context.dispenser\n\t\t\t\t);\n\n\t\t\t\toriginalFunction.name = originalFunctionName;\n\t\t\t\toriginalFunction.parameters =\n\t\t\t\t\tfilter(originalFunction.parameters, used.first);\n\t\t\t\toriginalFunction.returnVariables =\n\t\t\t\t\tfilter(originalFunction.returnVariables, used.second);\n\n\t\t\t\treturn make_vector<Statement>(std::move(originalFunction), std::move(linkingFunction));\n\t\t\t}\n\t\t}\n\n\t\treturn std::nullopt;\n\t});\n}\n"
  },
  {
    "path": "libyul/optimiser/UnusedFunctionParameterPruner.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/optimiser/OptimiserStep.h>\n\nnamespace solidity::yul\n{\n\n/**\n * UnusedFunctionParameterPruner: Optimiser step that removes unused parameters in a function.\n *\n * If a parameter is unused, like `c` and `y` in, `function f(a,b,c) -> x, y { x := div(a,b) }`\n *\n * We remove the parameter and create a new \"linking\" function as follows:\n *\n * `function f(a,b) -> x { x := div(a,b) }`\n * `function f2(a,b,c) -> x, y { x := f(a,b) }`\n *\n * and replace all references to `f` by `f2`.\n * The inliner should be run afterwards to make sure that all references to `f2` are replaced by\n * `f`.\n *\n * Prerequisites: Disambiguator, FunctionHoister, LiteralRematerialiser\n *\n * The step LiteralRematerialiser is not required for correctness. It helps deal with cases such as:\n * `function f(x) -> y { revert(y, y} }` where the literal `y` will be replaced by its value `0`,\n * allowing us to rewrite the function.\n */\nstruct UnusedFunctionParameterPruner\n{\n\tstatic constexpr char const* name{\"UnusedFunctionParameterPruner\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast);\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/UnusedFunctionsCommon.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/optimiser/UnusedFunctionsCommon.h>\n\n#include <libyul/Dialect.h>\n\n#include <libsolutil/CommonData.h>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::yul;\nusing namespace solidity::yul::unusedFunctionsCommon;\n\nFunctionDefinition unusedFunctionsCommon::createLinkingFunction(\n\tFunctionDefinition const& _original,\n\tstd::pair<std::vector<bool>, std::vector<bool>> const& _usedParametersAndReturns,\n\tYulName const& _originalFunctionName,\n\tYulName const& _linkingFunctionName,\n\tNameDispenser& _nameDispenser\n)\n{\n\tauto generateTypedName = [&](NameWithDebugData t)\n\t{\n\t\treturn NameWithDebugData{\n\t\t\tt.debugData,\n\t\t\t_nameDispenser.newName(t.name)\n\t\t};\n\t};\n\n\tFunctionDefinition linkingFunction{\n\t\t_original.debugData,\n\t\t_linkingFunctionName,\n\t\tutil::applyMap(_original.parameters, generateTypedName),\n\t\tutil::applyMap(_original.returnVariables, generateTypedName),\n\t\t{_original.debugData, {}} // body\n\t};\n\n\tFunctionCall call{_original.debugData, Identifier{_original.debugData, _originalFunctionName}, {}};\n\tfor (auto const& p: filter(linkingFunction.parameters, _usedParametersAndReturns.first))\n\t\tcall.arguments.emplace_back(Identifier{_original.debugData, p.name});\n\n\tAssignment assignment{_original.debugData, {}, nullptr};\n\n\tfor (auto const& r: filter(linkingFunction.returnVariables, _usedParametersAndReturns.second))\n\t\tassignment.variableNames.emplace_back(Identifier{_original.debugData, r.name});\n\n\tif (assignment.variableNames.empty())\n\t\tlinkingFunction.body.statements.emplace_back(ExpressionStatement{_original.debugData, std::move(call)});\n\telse\n\t{\n\t\tassignment.value = std::make_unique<Expression>(std::move(call));\n\t\tlinkingFunction.body.statements.emplace_back(std::move(assignment));\n\t}\n\n\treturn linkingFunction;\n}\n"
  },
  {
    "path": "libyul/optimiser/UnusedFunctionsCommon.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n#pragma once\n\n#include <libyul/optimiser/Metrics.h>\n#include <libyul/optimiser/NameDispenser.h>\n\n#include <libyul/AST.h>\n\nnamespace solidity::yul::unusedFunctionsCommon\n{\n\n/// Returns true if applying UnusedFunctionParameterPruner is not helpful or redundant because the\n/// inliner will be able to handle it anyway.\ninline bool tooSimpleToBePruned(FunctionDefinition const& _f)\n{\n\treturn _f.body.statements.size() <= 1 && CodeSize::codeSize(_f.body) <= 1;\n}\n\n/// Given a function definition `_original`, this function returns a 'linking' function that calls\n/// `_originalFunctionName` (with reduced parameters and return values).\n///\n/// The parameter `_usedParametersAndReturnVariables` is a pair of boolean-vectors. Its `.first`\n/// corresponds to function parameters and its `.second` corresponds to function return-variables. A\n/// false value at index `i` means that the corresponding function parameter / return-variable at\n/// index `i` is unused.\n///\n/// Example:\n///\n/// Let `_original` be the function `function f_1() -> y { }`. (In practice, this function usually cannot\n/// be inlined and has parameters / return-variables that are unused.)\n/// Let `_usedParametersAndReturnVariables` be `({}, {false})`\n/// Let `_originalFunctionName` be `f`.\n/// Let `_linkingFunctionName` be `f_1`.\n///\n/// Then the returned linking function would be `function f_1() -> y_1 { f() }`\nFunctionDefinition createLinkingFunction(\n\tFunctionDefinition const& _original,\n\tstd::pair<std::vector<bool>, std::vector<bool>> const& _usedParametersAndReturns,\n\tYulName const& _originalFunctionName,\n\tYulName const& _linkingFunctionName,\n\tNameDispenser& _nameDispenser\n);\n\n}\n"
  },
  {
    "path": "libyul/optimiser/UnusedPruner.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * Optimisation stage that removes unused variables and functions.\n */\n\n#include <libyul/optimiser/UnusedPruner.h>\n\n#include <libyul/optimiser/CallGraphGenerator.h>\n#include <libyul/optimiser/FunctionGrouper.h>\n#include <libyul/optimiser/NameCollector.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/Exceptions.h>\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n#include <libyul/SideEffects.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid UnusedPruner::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tUnusedPruner::runUntilStabilisedOnFullAST(_context.dialect, _ast, _context.reservedIdentifiers);\n\tFunctionGrouper::run(_context, _ast);\n}\n\nUnusedPruner::UnusedPruner(\n\tDialect const& _dialect,\n\tBlock& _ast,\n\tbool _allowMSizeOptimization,\n\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects,\n\tstd::set<YulName> const& _externallyUsedFunctions\n):\n\tm_dialect(_dialect),\n\tm_allowMSizeOptimization(_allowMSizeOptimization),\n\tm_functionSideEffects(_functionSideEffects)\n{\n\tm_references = ReferencesCounter::countReferences(_ast);\n\tfor (auto const& f: _externallyUsedFunctions)\n\t\t++m_references[f];\n}\n\nvoid UnusedPruner::operator()(Block& _block)\n{\n\tfor (auto&& statement: _block.statements)\n\t\tif (std::holds_alternative<FunctionDefinition>(statement))\n\t\t{\n\t\t\tFunctionDefinition& funDef = std::get<FunctionDefinition>(statement);\n\t\t\tif (!used(funDef.name))\n\t\t\t{\n\t\t\t\tsubtractReferences(ReferencesCounter::countReferences(funDef.body));\n\t\t\t\tstatement = Block{std::move(funDef.debugData), {}};\n\t\t\t}\n\t\t}\n\t\telse if (std::holds_alternative<VariableDeclaration>(statement))\n\t\t{\n\t\t\tVariableDeclaration& varDecl = std::get<VariableDeclaration>(statement);\n\t\t\t// Multi-variable declarations are special. We can only remove it\n\t\t\t// if all variables are unused and the right-hand-side is either\n\t\t\t// movable or it returns a single value. In the latter case, we\n\t\t\t// replace `let a := f()` by `pop(f())` (in pure Yul, this will be\n\t\t\t// `drop(f())`).\n\t\t\tif (std::none_of(\n\t\t\t\tvarDecl.variables.begin(),\n\t\t\t\tvarDecl.variables.end(),\n\t\t\t\t[&](NameWithDebugData const& _typedName) { return used(_typedName.name); }\n\t\t\t))\n\t\t\t{\n\t\t\t\tstd::optional<BuiltinHandle> discardFunctionHandle = m_dialect.discardFunctionHandle();\n\t\t\t\tif (!varDecl.value)\n\t\t\t\t\tstatement = Block{std::move(varDecl.debugData), {}};\n\t\t\t\telse if (\n\t\t\t\t\tSideEffectsCollector(m_dialect, *varDecl.value, m_functionSideEffects).\n\t\t\t\t\tcanBeRemoved(m_allowMSizeOptimization)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tsubtractReferences(ReferencesCounter::countReferences(*varDecl.value));\n\t\t\t\t\tstatement = Block{std::move(varDecl.debugData), {}};\n\t\t\t\t}\n\t\t\t\telse if (varDecl.variables.size() == 1 && discardFunctionHandle)\n\t\t\t\t\tstatement = ExpressionStatement{varDecl.debugData, FunctionCall{\n\t\t\t\t\t\tvarDecl.debugData,\n\t\t\t\t\t\tBuiltinName{varDecl.debugData, *discardFunctionHandle},\n\t\t\t\t\t\t{*std::move(varDecl.value)}\n\t\t\t\t\t}};\n\t\t\t}\n\t\t}\n\t\telse if (std::holds_alternative<ExpressionStatement>(statement))\n\t\t{\n\t\t\tExpressionStatement& exprStmt = std::get<ExpressionStatement>(statement);\n\t\t\tif (\n\t\t\t\tSideEffectsCollector(m_dialect, exprStmt.expression, m_functionSideEffects).\n\t\t\t\tcanBeRemoved(m_allowMSizeOptimization)\n\t\t\t)\n\t\t\t{\n\t\t\t\tsubtractReferences(ReferencesCounter::countReferences(exprStmt.expression));\n\t\t\t\tstatement = Block{std::move(exprStmt.debugData), {}};\n\t\t\t}\n\t\t}\n\n\tremoveEmptyBlocks(_block);\n\n\tASTModifier::operator()(_block);\n}\n\nvoid UnusedPruner::runUntilStabilised(\n\tDialect const& _dialect,\n\tBlock& _ast,\n\tbool _allowMSizeOptimization,\n\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects,\n\tstd::set<YulName> const& _externallyUsedFunctions\n)\n{\n\twhile (true)\n\t{\n\t\tUnusedPruner pruner(\n\t\t\t_dialect,\n\t\t\t_ast,\n\t\t\t_allowMSizeOptimization,\n\t\t\t_functionSideEffects,\n\t\t\t_externallyUsedFunctions\n\t\t);\n\t\tpruner(_ast);\n\t\tif (!pruner.shouldRunAgain())\n\t\t\treturn;\n\t}\n}\n\nvoid UnusedPruner::runUntilStabilisedOnFullAST(\n\tDialect const& _dialect,\n\tBlock& _ast,\n\tstd::set<YulName> const& _externallyUsedFunctions\n)\n{\n\tstd::map<FunctionHandle, SideEffects> functionSideEffects =\n\t\tSideEffectsPropagator::sideEffects(_dialect, CallGraphGenerator::callGraph(_ast));\n\tbool allowMSizeOptimization = !MSizeFinder::containsMSize(_dialect, _ast);\n\trunUntilStabilised(_dialect, _ast, allowMSizeOptimization, &functionSideEffects, _externallyUsedFunctions);\n}\n\nbool UnusedPruner::used(YulName _name) const\n{\n\treturn m_references.count(_name) && m_references.at(_name) > 0;\n}\n\nvoid UnusedPruner::subtractReferences(std::map<FunctionHandle, size_t> const& _subtrahend)\n{\n\tfor (auto const& ref: _subtrahend)\n\t{\n\t\tassertThrow(m_references.count(ref.first), OptimizerException, \"\");\n\t\tassertThrow(m_references.at(ref.first) >= ref.second, OptimizerException, \"\");\n\t\tm_references[ref.first] -= ref.second;\n\t\tm_shouldRunAgain = true;\n\t}\n}\n"
  },
  {
    "path": "libyul/optimiser/UnusedPruner.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimisation stage that removes unused variables and functions.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/YulName.h>\n\n#include <map>\n#include <set>\n\nnamespace solidity::yul\n{\nclass Dialect;\nstruct SideEffects;\n\n/**\n * Optimisation stage that removes unused variables and functions and also\n * removes side-effect-free expression statements.\n *\n * If msize is used, we cannot remove any statements that access memory.\n * Because of that, the Unused Pruner should only be invoked on full ASTs,\n * such that it can check for the presence of msize itself, or\n * the `_allowMSizeOptimization` needs to be passed.\n *\n * Note that this does not remove circular references.\n *\n * Prerequisite: Disambiguator\n */\nclass UnusedPruner: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"UnusedPruner\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast);\n\n\tusing ASTModifier::operator();\n\tvoid operator()(Block& _block) override;\n\n\t// @returns true iff the code changed in the previous run.\n\tbool shouldRunAgain() const { return m_shouldRunAgain; }\n\n\t// Run the pruner until the code does not change anymore.\n\tstatic void runUntilStabilised(\n\t\tDialect const& _dialect,\n\t\tBlock& _ast,\n\t\tbool _allowMSizeOptimization,\n\t\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects = nullptr,\n\t\tstd::set<YulName> const& _externallyUsedFunctions = {}\n\t);\n\n\t/// Run the pruner until the code does not change anymore.\n\t/// The provided block has to be a full AST.\n\t/// The pruner itself determines if msize is used and which user-defined functions\n\t/// are side-effect free.\n\tstatic void runUntilStabilisedOnFullAST(\n\t\tDialect const& _dialect,\n\t\tBlock& _ast,\n\t\tstd::set<YulName> const& _externallyUsedFunctions = {}\n\t);\n\nprivate:\n\tUnusedPruner(\n\t\tDialect const& _dialect,\n\t\tBlock& _ast,\n\t\tbool _allowMSizeOptimization,\n\t\tstd::map<FunctionHandle, SideEffects> const* _functionSideEffects = nullptr,\n\t\tstd::set<YulName> const& _externallyUsedFunctions = {}\n\t);\n\n\tbool used(YulName _name) const;\n\tvoid subtractReferences(std::map<FunctionHandle, size_t> const& _subtrahend);\n\n\tDialect const& m_dialect;\n\tbool m_allowMSizeOptimization = false;\n\tstd::map<FunctionHandle, SideEffects> const* m_functionSideEffects = nullptr;\n\tbool m_shouldRunAgain = false;\n\tstd::map<FunctionHandle, size_t> m_references;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/UnusedStoreBase.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Base class for both UnusedAssignEliminator and UnusedStoreEliminator.\n */\n\n#include <libyul/optimiser/UnusedStoreBase.h>\n\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/AST.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <range/v3/action/remove_if.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\ntemplate<typename ActiveStoresKeyType>\nvoid UnusedStoreBase<ActiveStoresKeyType>::operator()(If const& _if)\n{\n\tvisit(*_if.condition);\n\n\tActiveStores skipBranch{m_activeStores};\n\t(*this)(_if.body);\n\n\tmerge(m_activeStores, std::move(skipBranch));\n}\n\ntemplate<typename ActiveStoresKeyType>\nvoid UnusedStoreBase<ActiveStoresKeyType>::operator()(Switch const& _switch)\n{\n\tvisit(*_switch.expression);\n\n\tActiveStores const preState{m_activeStores};\n\n\tbool hasDefault = false;\n\tstd::vector<ActiveStores> branches;\n\tfor (auto const& c: _switch.cases)\n\t{\n\t\tif (!c.value)\n\t\t\thasDefault = true;\n\t\t(*this)(c.body);\n\t\tbranches.emplace_back(std::move(m_activeStores));\n\t\tm_activeStores = preState;\n\t}\n\n\tif (hasDefault)\n\t{\n\t\tm_activeStores = std::move(branches.back());\n\t\tbranches.pop_back();\n\t}\n\tfor (auto& branch: branches)\n\t\tmerge(m_activeStores, std::move(branch));\n}\n\ntemplate<typename ActiveStoresKeyType>\nvoid UnusedStoreBase<ActiveStoresKeyType>::operator()(FunctionDefinition const& _functionDefinition)\n{\n\tScopedSaveAndRestore allStores(m_allStores, {});\n\tScopedSaveAndRestore usedStores(m_usedStores, {});\n\tScopedSaveAndRestore outerAssignments(m_activeStores, {});\n\tScopedSaveAndRestore forLoopInfo(m_forLoopInfo, {});\n\tScopedSaveAndRestore forLoopNestingDepth(m_forLoopNestingDepth, 0);\n\n\t(*this)(_functionDefinition.body);\n\n\tfinalizeFunctionDefinition(_functionDefinition);\n\tm_storesToRemove += m_allStores - m_usedStores;\n}\n\ntemplate<typename ActiveStoresKeyType>\nvoid UnusedStoreBase<ActiveStoresKeyType>::operator()(ForLoop const& _forLoop)\n{\n\tScopedSaveAndRestore outerForLoopInfo(m_forLoopInfo, {});\n\tScopedSaveAndRestore forLoopNestingDepth(m_forLoopNestingDepth, m_forLoopNestingDepth + 1);\n\n\t// If the pre block was not empty,\n\t// we would have to deal with more complicated scoping rules.\n\tassertThrow(_forLoop.pre.statements.empty(), OptimizerException, \"\");\n\n\t// We just run the loop twice to account for the back edge.\n\t// There need not be more runs because we only have three different states.\n\n\tvisit(*_forLoop.condition);\n\n\tActiveStores zeroRuns{m_activeStores};\n\n\t(*this)(_forLoop.body);\n\tmerge(m_activeStores, std::move(m_forLoopInfo.pendingContinueStmts));\n\tm_forLoopInfo.pendingContinueStmts = {};\n\t(*this)(_forLoop.post);\n\n\tvisit(*_forLoop.condition);\n\n\tif (m_forLoopNestingDepth < 6)\n\t{\n\t\t// Do the second run only for small nesting depths to avoid horrible runtime.\n\t\tActiveStores oneRun{m_activeStores};\n\n\t\t(*this)(_forLoop.body);\n\n\t\tmerge(m_activeStores, std::move(m_forLoopInfo.pendingContinueStmts));\n\t\tm_forLoopInfo.pendingContinueStmts.clear();\n\t\t(*this)(_forLoop.post);\n\n\t\tvisit(*_forLoop.condition);\n\t\t// Order of merging does not matter because \"max\" is commutative and associative.\n\t\tmerge(m_activeStores, std::move(oneRun));\n\t}\n\telse\n\t\t// Shortcut to avoid horrible runtime.\n\t\tshortcutNestedLoop(zeroRuns);\n\n\t// Order of merging does not matter because \"max\" is commutative and associative.\n\tmerge(m_activeStores, std::move(zeroRuns));\n\tmerge(m_activeStores, std::move(m_forLoopInfo.pendingBreakStmts));\n\tm_forLoopInfo.pendingBreakStmts.clear();\n}\n\ntemplate<typename ActiveStoresKeyType>\nvoid UnusedStoreBase<ActiveStoresKeyType>::operator()(Break const&)\n{\n\tm_forLoopInfo.pendingBreakStmts.emplace_back(std::move(m_activeStores));\n\tm_activeStores.clear();\n}\n\ntemplate<typename ActiveStoresKeyType>\nvoid UnusedStoreBase<ActiveStoresKeyType>::operator()(Continue const&)\n{\n\tm_forLoopInfo.pendingContinueStmts.emplace_back(std::move(m_activeStores));\n\tm_activeStores.clear();\n}\n\ntemplate<typename ActiveStoresKeyType>\nvoid UnusedStoreBase<ActiveStoresKeyType>::merge(ActiveStores& _target, ActiveStores&& _other)\n{\n\tutil::joinMap(_target, std::move(_other), [](\n\t\tstd::set<Statement const*>& _storesHere,\n\t\tstd::set<Statement const*>&& _storesThere\n\t)\n\t{\n\t\t_storesHere += _storesThere;\n\t});\n}\n\ntemplate<typename ActiveStoresKeyType>\nvoid UnusedStoreBase<ActiveStoresKeyType>::merge(ActiveStores& _target, std::vector<ActiveStores>&& _source)\n{\n\tfor (ActiveStores& ts: _source)\n\t\tmerge(_target, std::move(ts));\n\t_source.clear();\n}\n\ntemplate class solidity::yul::UnusedStoreBase<UnusedStoreEliminatorKey>;\ntemplate class solidity::yul::UnusedStoreBase<YulName>;\n"
  },
  {
    "path": "libyul/optimiser/UnusedStoreBase.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Base class for both UnusedAssignEliminator and UnusedStoreEliminator.\n */\n\n#pragma once\n\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/AST.h>\n\n#include <range/v3/action/remove_if.hpp>\n\n#include <variant>\n\n\nnamespace solidity::yul\n{\nclass Dialect;\n\n/**\n * Base class for both UnusedAssignEliminator and UnusedStoreEliminator.\n *\n * The class tracks the state of abstract \"stores\" (assignments or mstore/sstore\n * statements) across the control-flow. It is the job of the derived class to create\n * the stores and track references, but the base class manages control-flow splits and joins.\n *\n * In general, active stores are those where it has not yet been determined if they are used\n * or not. Those are split and joined at control-flow forks. Once a store has been deemed\n * used, it is removed from the active set and marked as used and this will never change.\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter.\n */\ntemplate<typename ActiveStoreKeyType>\nclass UnusedStoreBase: public ASTWalker\n{\npublic:\n\texplicit UnusedStoreBase(Dialect const& _dialect): m_dialect(_dialect) {}\n\n\tusing ASTWalker::operator();\n\tvoid operator()(If const& _if) override;\n\tvoid operator()(Switch const& _switch) override;\n\tvoid operator()(FunctionDefinition const&) override;\n\tvoid operator()(ForLoop const&) override;\n\tvoid operator()(Break const&) override;\n\tvoid operator()(Continue const&) override;\n\nprotected:\n\tusing ActiveStores = std::map<ActiveStoreKeyType, std::set<Statement const*>>;\n\n\t/// This function is called for a loop that is nested too deep to avoid\n\t/// horrible runtime and should just resolve the situation in a pragmatic\n\t/// and correct manner.\n\tvirtual void shortcutNestedLoop(ActiveStores const& _beforeLoop) = 0;\n\n\t/// This function is called right before the scoped restore of the function definition.\n\tvirtual void finalizeFunctionDefinition(FunctionDefinition const& /*_functionDefinition*/) {}\n\n\t/// Joins the assignment mapping of @a _source into @a _target according to the rules laid out\n\t/// above.\n\t/// Will destroy @a _source.\n\tstatic void merge(ActiveStores& _target, ActiveStores&& _source);\n\tstatic void merge(ActiveStores& _target, std::vector<ActiveStores>&& _source);\n\n\tDialect const& m_dialect;\n\t/// Set of all stores encountered during the traversal (in the current function).\n\tstd::set<Statement const*> m_allStores;\n\t/// Set of stores that are marked as being used (in the current function).\n\tstd::set<Statement const*> m_usedStores;\n\t/// List of stores that can be removed (globally).\n\tstd::vector<Statement const*> m_storesToRemove;\n\t/// Active (undecided) stores in the current branch.\n\tActiveStores m_activeStores;\n\n\t/// Working data for traversing for-loops.\n\tstruct ForLoopInfo\n\t{\n\t\t/// Tracked assignment states for each break statement.\n\t\tstd::vector<ActiveStores> pendingBreakStmts;\n\t\t/// Tracked assignment states for each continue statement.\n\t\tstd::vector<ActiveStores> pendingContinueStmts;\n\t};\n\tForLoopInfo m_forLoopInfo;\n\tsize_t m_forLoopNestingDepth = 0;\n};\n\nenum class UnusedStoreEliminatorKey { Memory, Storage };\nextern template class UnusedStoreBase<YulString>;\nextern template class UnusedStoreBase<UnusedStoreEliminatorKey>;\n}\n"
  },
  {
    "path": "libyul/optimiser/UnusedStoreEliminator.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that removes stores to memory and storage slots that are not used\n * or overwritten later on.\n */\n\n#include <libyul/optimiser/UnusedStoreEliminator.h>\n\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/SSAValueTracker.h>\n#include <libyul/optimiser/DataFlowAnalyzer.h>\n#include <libyul/optimiser/KnowledgeBase.h>\n#include <libyul/ControlFlowSideEffectsCollector.h>\n#include <libyul/AST.h>\n#include <libyul/Utilities.h>\n\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <libevmasm/Instruction.h>\n#include <libevmasm/SemanticInformation.h>\n\n#include <range/v3/algorithm/all_of.hpp>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid UnusedStoreEliminator::run(OptimiserStepContext& _context, Block& _ast)\n{\n\tstd::map<FunctionHandle, SideEffects> functionSideEffects = SideEffectsPropagator::sideEffects(\n\t\t_context.dialect,\n\t\tCallGraphGenerator::callGraph(_ast)\n\t);\n\n\tSSAValueTracker ssaValues;\n\tssaValues(_ast);\n\tstd::map<YulName, AssignedValue> values;\n\tfor (auto const& [name, expression]: ssaValues.values())\n\t\tvalues[name] = AssignedValue{expression, {}};\n\n\tbool const ignoreMemory = MSizeFinder::containsMSize(_context.dialect, _ast);\n\tUnusedStoreEliminator rse{\n\t\t_context.dialect,\n\t\tfunctionSideEffects,\n\t\tControlFlowSideEffectsCollector{_context.dialect, _ast}.functionSideEffectsNamed(),\n\t\tvalues,\n\t\tignoreMemory\n\t};\n\trse(_ast);\n\n\tauto evmDialect = dynamic_cast<EVMDialect const*>(&_context.dialect);\n\tif (evmDialect && evmDialect->providesObjectAccess())\n\t\trse.clearActive(Location::Memory);\n\telse\n\t\trse.markActiveAsUsed(Location::Memory);\n\trse.markActiveAsUsed(Location::Storage);\n\trse.m_storesToRemove += rse.m_allStores - rse.m_usedStores;\n\n\tstd::set<Statement const*> toRemove{rse.m_storesToRemove.begin(), rse.m_storesToRemove.end()};\n\tStatementRemover remover{toRemove};\n\tremover(_ast);\n}\n\nUnusedStoreEliminator::UnusedStoreEliminator(\n\tDialect const& _dialect,\n\tstd::map<FunctionHandle, SideEffects> const& _functionSideEffects,\n\tstd::map<YulName, ControlFlowSideEffects> _controlFlowSideEffects,\n\tstd::map<YulName, AssignedValue> const& _ssaValues,\n\tbool _ignoreMemory\n):\n\tUnusedStoreBase(_dialect),\n\tm_ignoreMemory(_ignoreMemory),\n\tm_functionSideEffects(_functionSideEffects),\n\tm_controlFlowSideEffects(std::move(_controlFlowSideEffects)),\n\tm_ssaValues(_ssaValues),\n\tm_knowledgeBase(_ssaValues, _dialect)\n{}\n\nvoid UnusedStoreEliminator::operator()(FunctionCall const& _functionCall)\n{\n\tUnusedStoreBase::operator()(_functionCall);\n\n\tfor (Operation const& op: operationsFromFunctionCall(_functionCall))\n\t\tapplyOperation(op);\n\n\tControlFlowSideEffects sideEffects;\n\tif (auto builtin = resolveBuiltinFunction(_functionCall.functionName, m_dialect))\n\t\tsideEffects = builtin->controlFlowSideEffects;\n\telse\n\t{\n\t\tyulAssert(std::holds_alternative<Identifier>(_functionCall.functionName));\n\t\tsideEffects = m_controlFlowSideEffects.at(std::get<Identifier>(_functionCall.functionName).name);\n\t}\n\n\tif (sideEffects.canTerminate)\n\t\tmarkActiveAsUsed(Location::Storage);\n\tif (!sideEffects.canContinue)\n\t{\n\t\tclearActive(Location::Memory);\n\t\tif (!sideEffects.canTerminate)\n\t\t\tclearActive(Location::Storage);\n\t}\n}\n\nvoid UnusedStoreEliminator::operator()(FunctionDefinition const& _functionDefinition)\n{\n\tScopedSaveAndRestore storeOperations(m_storeOperations, {});\n\tUnusedStoreBase::operator()(_functionDefinition);\n}\n\n\nvoid UnusedStoreEliminator::operator()(Leave const&)\n{\n\tmarkActiveAsUsed();\n}\n\nvoid UnusedStoreEliminator::visit(Statement const& _statement)\n{\n\tusing evmasm::Instruction;\n\n\tUnusedStoreBase::visit(_statement);\n\n\tauto const* exprStatement = std::get_if<ExpressionStatement>(&_statement);\n\tif (!exprStatement)\n\t\treturn;\n\n\tFunctionCall const* funCall = std::get_if<FunctionCall>(&exprStatement->expression);\n\tyulAssert(funCall);\n\tstd::optional<Instruction> instruction = toEVMInstruction(m_dialect, funCall->functionName);\n\tif (!instruction)\n\t\treturn;\n\n\tif (!ranges::all_of(funCall->arguments, [](Expression const& _expr) -> bool {\n\t\treturn std::get_if<Identifier>(&_expr) || std::get_if<Literal>(&_expr);\n\t}))\n\t\treturn;\n\n\t// We determine if this is a store instruction without additional side-effects\n\t// both by querying a combination of semantic information and by listing the instructions.\n\t// This way the assert below should be triggered on any change.\n\tusing evmasm::SemanticInformation;\n\tbool isStorageWrite = (*instruction == Instruction::SSTORE);\n\tbool isMemoryWrite =\n\t\t*instruction == Instruction::EXTCODECOPY ||\n\t\t*instruction == Instruction::CODECOPY ||\n\t\t*instruction == Instruction::CALLDATACOPY ||\n\t\t*instruction == Instruction::RETURNDATACOPY ||\n\t\t// TODO: Removing MCOPY is complicated because it's not just a store but also a load.\n\t\t//*instruction == Instruction::MCOPY ||\n\t\t*instruction == Instruction::MSTORE ||\n\t\t*instruction == Instruction::MSTORE8;\n\tbool isCandidateForRemoval =\n\t\t*instruction != Instruction::MCOPY &&\n\t\tSemanticInformation::otherState(*instruction) != SemanticInformation::Write && (\n\t\t\tSemanticInformation::storage(*instruction) == SemanticInformation::Write ||\n\t\t\t(!m_ignoreMemory && SemanticInformation::memory(*instruction) == SemanticInformation::Write)\n\t\t);\n\tyulAssert(isCandidateForRemoval == (isStorageWrite || (!m_ignoreMemory && isMemoryWrite)));\n\tif (isCandidateForRemoval)\n\t{\n\t\tif (*instruction == Instruction::RETURNDATACOPY)\n\t\t{\n\t\t\t// Out-of-bounds access to the returndata buffer results in a revert,\n\t\t\t// so we are careful not to remove a potentially reverting call to a builtin.\n\t\t\t// The only way the Solidity compiler uses `returndatacopy` is\n\t\t\t// `returndatacopy(X, 0, returndatasize())`, so we only allow to remove this pattern\n\t\t\t// (which is guaranteed to never cause an out-of-bounds revert).\n\t\t\tbool allowReturndatacopyToBeRemoved = false;\n\t\t\tauto startOffset = identifierNameIfSSA(funCall->arguments.at(1));\n\t\t\tauto length = identifierNameIfSSA(funCall->arguments.at(2));\n\t\t\tif (length && startOffset)\n\t\t\t{\n\t\t\t\tFunctionCall const* lengthCall = std::get_if<FunctionCall>(m_ssaValues.at(*length).value);\n\t\t\t\tif (\n\t\t\t\t\tm_knowledgeBase.knownToBeZero(*startOffset) &&\n\t\t\t\t\tlengthCall &&\n\t\t\t\t\ttoEVMInstruction(m_dialect, lengthCall->functionName) == Instruction::RETURNDATASIZE\n\t\t\t\t)\n\t\t\t\t\tallowReturndatacopyToBeRemoved = true;\n\t\t\t}\n\t\t\tif (!allowReturndatacopyToBeRemoved)\n\t\t\t\treturn;\n\t\t}\n\t\tm_allStores.insert(&_statement);\n\t\tstd::vector<Operation> operations = operationsFromFunctionCall(*funCall);\n\t\tyulAssert(operations.size() == 1, \"\");\n\t\tif (operations.front().location == Location::Storage)\n\t\t\tactiveStorageStores().insert(&_statement);\n\t\telse\n\t\t{\n\t\t\tyulAssert(operations.front().location == Location::Memory, \"\");\n\t\t\tactiveMemoryStores().insert(&_statement);\n\t\t}\n\t\tm_storeOperations[&_statement] = std::move(operations.front());\n\t}\n}\n\nstd::vector<UnusedStoreEliminator::Operation> UnusedStoreEliminator::operationsFromFunctionCall(\n\tFunctionCall const& _functionCall\n) const\n{\n\tusing evmasm::Instruction;\n\n\tSideEffects sideEffects;\n\tif (BuiltinFunction const* f = resolveBuiltinFunction(_functionCall.functionName, m_dialect))\n\t\tsideEffects = f->sideEffects;\n\telse\n\t{\n\t\tyulAssert(std::holds_alternative<Identifier>(_functionCall.functionName));\n\t\tsideEffects = m_functionSideEffects.at(std::get<Identifier>(_functionCall.functionName).name);\n\t}\n\n\tstd::optional<Instruction> instruction = toEVMInstruction(m_dialect, _functionCall.functionName);\n\tif (!instruction)\n\t{\n\t\tstd::vector<Operation> result;\n\t\t// Unknown read is worse than unknown write.\n\t\tif (sideEffects.memory != SideEffects::Effect::None)\n\t\t\tresult.emplace_back(Operation{Location::Memory, Effect::Read, {}, {}});\n\t\tif (sideEffects.storage != SideEffects::Effect::None)\n\t\t\tresult.emplace_back(Operation{Location::Storage, Effect::Read, {}, {}});\n\t\treturn result;\n\t}\n\n\tusing evmasm::SemanticInformation;\n\n\treturn util::applyMap(\n\t\tSemanticInformation::readWriteOperations(*instruction),\n\t\t[&](SemanticInformation::Operation const& _op) -> Operation\n\t\t{\n\t\t\tyulAssert(!(_op.lengthParameter && _op.lengthConstant));\n\t\t\tyulAssert(_op.effect != Effect::None);\n\t\t\tOperation ourOp{_op.location, _op.effect, {}, {}};\n\t\t\tif (_op.startParameter)\n\t\t\t\tourOp.start = identifierNameIfSSA(_functionCall.arguments.at(*_op.startParameter));\n\t\t\tif (_op.lengthParameter)\n\t\t\t\tourOp.length = identifierNameIfSSA(_functionCall.arguments.at(*_op.lengthParameter));\n\t\t\tif (_op.lengthConstant)\n\t\t\t\tswitch (*_op.lengthConstant)\n\t\t\t\t{\n\t\t\t\tcase 1: ourOp.length = u256(1); break;\n\t\t\t\tcase 32: ourOp.length = u256(32); break;\n\t\t\t\tdefault: yulAssert(false);\n\t\t\t\t}\n\t\t\treturn ourOp;\n\t\t}\n\t);\n}\n\nvoid UnusedStoreEliminator::applyOperation(UnusedStoreEliminator::Operation const& _operation)\n{\n\tstd::set<Statement const*>& active =\n\t\t_operation.location == Location::Storage ?\n\t\tactiveStorageStores() :\n\t\tactiveMemoryStores();\n\n\n\tfor (auto it = active.begin(); it != active.end();)\n\t{\n\t\tStatement const* statement = *it;\n\t\tOperation const& storeOperation = m_storeOperations.at(statement);\n\t\tif (_operation.effect == Effect::Read && !knownUnrelated(storeOperation, _operation))\n\t\t{\n\t\t\t// This store is read from, mark it as used and remove it from the active set.\n\t\t\tm_usedStores.insert(statement);\n\t\t\tit = active.erase(it);\n\t\t}\n\t\telse if (_operation.effect == Effect::Write && knownCovered(storeOperation, _operation))\n\t\t\t// This store is overwritten before being read, remove it from the active set.\n\t\t\tit = active.erase(it);\n\t\telse\n\t\t\t++it;\n\t}\n}\n\nbool UnusedStoreEliminator::knownUnrelated(\n\tUnusedStoreEliminator::Operation const& _op1,\n\tUnusedStoreEliminator::Operation const& _op2\n) const\n{\n\tif (_op1.location != _op2.location)\n\t\treturn true;\n\tif (_op1.location == Location::Storage)\n\t{\n\t\tif (_op1.start && _op2.start)\n\t\t{\n\t\t\tyulAssert(\n\t\t\t\t_op1.length &&\n\t\t\t\t_op2.length &&\n\t\t\t\tlengthValue(*_op1.length) == 1 &&\n\t\t\t\tlengthValue(*_op2.length) == 1\n\t\t\t);\n\t\t\treturn m_knowledgeBase.knownToBeDifferent(*_op1.start, *_op2.start);\n\t\t}\n\t}\n\telse\n\t{\n\t\tyulAssert(_op1.location == Location::Memory, \"\");\n\t\tif (\n\t\t\t(_op1.length && lengthValue(*_op1.length) == 0) ||\n\t\t\t(_op2.length && lengthValue(*_op2.length) == 0)\n\t\t)\n\t\t\treturn true;\n\n\t\tif (_op1.start && _op1.length && _op2.start)\n\t\t{\n\t\t\tstd::optional<u256> length1 = lengthValue(*_op1.length);\n\t\t\tstd::optional<u256> start1 = m_knowledgeBase.valueIfKnownConstant(*_op1.start);\n\t\t\tstd::optional<u256> start2 = m_knowledgeBase.valueIfKnownConstant(*_op2.start);\n\t\t\tif (\n\t\t\t\t(length1 && start1 && start2) &&\n\t\t\t\t*start1 + *length1 >= *start1 && // no overflow\n\t\t\t\t*start1 + *length1 <= *start2\n\t\t\t)\n\t\t\t\treturn true;\n\t\t}\n\t\tif (_op2.start && _op2.length && _op1.start)\n\t\t{\n\t\t\tstd::optional<u256> length2 = lengthValue(*_op2.length);\n\t\t\tstd::optional<u256> start2 = m_knowledgeBase.valueIfKnownConstant(*_op2.start);\n\t\t\tstd::optional<u256> start1 = m_knowledgeBase.valueIfKnownConstant(*_op1.start);\n\t\t\tif (\n\t\t\t\t(length2 && start2 && start1) &&\n\t\t\t\t*start2 + *length2 >= *start2 && // no overflow\n\t\t\t\t*start2 + *length2 <= *start1\n\t\t\t)\n\t\t\t\treturn true;\n\t\t}\n\n\t\tif (_op1.start && _op1.length && _op2.start && _op2.length)\n\t\t{\n\t\t\tstd::optional<u256> length1 = lengthValue(*_op1.length);\n\t\t\tstd::optional<u256> length2 = lengthValue(*_op2.length);\n\t\t\tif (\n\t\t\t\t(length1 && *length1 <= 32) &&\n\t\t\t\t(length2 && *length2 <= 32) &&\n\t\t\t\tm_knowledgeBase.knownToBeDifferentByAtLeast32(*_op1.start, *_op2.start)\n\t\t\t)\n\t\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nbool UnusedStoreEliminator::knownCovered(\n\tUnusedStoreEliminator::Operation const& _covered,\n\tUnusedStoreEliminator::Operation const& _covering\n) const\n{\n\tif (_covered.location != _covering.location)\n\t\treturn false;\n\tif (\n\t\t(_covered.start && _covered.start == _covering.start) &&\n\t\t(_covered.length && _covered.length == _covering.length)\n\t)\n\t\treturn true;\n\tif (_covered.location == Location::Memory)\n\t{\n\t\tif (_covered.length && lengthValue(*_covered.length) == 0)\n\t\t\treturn true;\n\n\t\t// Condition (i = cover_i_ng, e = cover_e_d):\n\t\t// i.start <= e.start && e.start + e.length <= i.start + i.length\n\t\tif (!_covered.start || !_covering.start || !_covered.length || !_covering.length)\n\t\t\treturn false;\n\t\tstd::optional<u256> coveredLength = lengthValue(*_covered.length);\n\t\tstd::optional<u256> coveringLength = lengthValue(*_covering.length);\n\t\tif (*_covered.start == *_covering.start)\n\t\t\tif (coveredLength && coveringLength && *coveredLength <= *coveringLength)\n\t\t\t\treturn true;\n\t\tstd::optional<u256> coveredStart = m_knowledgeBase.valueIfKnownConstant(*_covered.start);\n\t\tstd::optional<u256> coveringStart = m_knowledgeBase.valueIfKnownConstant(*_covering.start);\n\t\tif (coveredStart && coveringStart && coveredLength && coveringLength)\n\t\t\tif (\n\t\t\t\t*coveringStart <= *coveredStart &&\n\t\t\t\t*coveringStart + *coveringLength >= *coveringStart && // no overflow\n\t\t\t\t*coveredStart + *coveredLength >= *coveredStart && // no overflow\n\t\t\t\t*coveredStart + *coveredLength <= *coveringStart + *coveringLength\n\t\t\t)\n\t\t\t\treturn true;\n\n\t\t// TODO for this we probably need a non-overflow assumption as above.\n\t\t// Condition (i = cover_i_ng, e = cover_e_d):\n\t\t// i.start <= e.start && e.start + e.length <= i.start + i.length\n\t}\n\treturn false;\n}\n\nvoid UnusedStoreEliminator::markActiveAsUsed(\n\tstd::optional<UnusedStoreEliminator::Location> _onlyLocation\n)\n{\n\tif (_onlyLocation == std::nullopt || _onlyLocation == Location::Memory)\n\t\tfor (Statement const* statement: activeMemoryStores())\n\t\t\tm_usedStores.insert(statement);\n\tif (_onlyLocation == std::nullopt || _onlyLocation == Location::Storage)\n\t\tfor (Statement const* statement: activeStorageStores())\n\t\t\tm_usedStores.insert(statement);\n\tclearActive(_onlyLocation);\n}\n\nvoid UnusedStoreEliminator::clearActive(\n\tstd::optional<UnusedStoreEliminator::Location> _onlyLocation\n)\n{\n\tif (_onlyLocation == std::nullopt || _onlyLocation == Location::Memory)\n\t\tactiveMemoryStores() = {};\n\tif (_onlyLocation == std::nullopt || _onlyLocation == Location::Storage)\n\t\tactiveStorageStores() = {};\n}\n\nstd::optional<YulName> UnusedStoreEliminator::identifierNameIfSSA(Expression const& _expression) const\n{\n\tif (Identifier const* identifier = std::get_if<Identifier>(&_expression))\n\t\tif (m_ssaValues.count(identifier->name))\n\t\t\treturn {identifier->name};\n\treturn std::nullopt;\n}\n"
  },
  {
    "path": "libyul/optimiser/UnusedStoreEliminator.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Optimiser component that removes stores to memory and storage slots that are not used\n * or overwritten later on.\n */\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n#include <libyul/optimiser/Semantics.h>\n#include <libyul/optimiser/UnusedStoreBase.h>\n#include <libyul/optimiser/KnowledgeBase.h>\n\n#include <libevmasm/SemanticInformation.h>\n\n#include <map>\n#include <vector>\n\nnamespace solidity::yul\n{\nclass Dialect;\nstruct AssignedValue;\n\n/**\n * Optimizer component that removes sstore and memory store statements if conditions are met for their removal.\n * In case of an sstore, if all outgoing code paths revert (due to an explicit revert(), invalid(),\n * or infinite recursion) or lead to another ``sstore`` for which the optimizer can tell that it will overwrite the first store,\n * the statement will be removed.\n *\n * For memory store operations, things are generally simpler, at least in the outermost yul block as all such statements\n * will be removed if they are never read from in any code path. At function analysis level however, the approach is similar\n * to sstore, as we don't know whether the memory location will be read once we leave the function's scope,\n * so the statement will be removed only if all code code paths lead to a memory overwrite.\n *\n * Best run in SSA form.\n *\n * Prerequisite: Disambiguator, ForLoopInitRewriter.\n */\nclass UnusedStoreEliminator: public UnusedStoreBase<UnusedStoreEliminatorKey>\n{\npublic:\n\tstatic constexpr char const* name{\"UnusedStoreEliminator\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast);\n\n\texplicit UnusedStoreEliminator(\n\t\tDialect const& _dialect,\n\t\tstd::map<FunctionHandle, SideEffects> const& _functionSideEffects,\n\t\tstd::map<YulName, ControlFlowSideEffects> _controlFlowSideEffects,\n\t\tstd::map<YulName, AssignedValue> const& _ssaValues,\n\t\tbool _ignoreMemory\n\t);\n\n\tusing UnusedStoreBase::operator();\n\tvoid operator()(FunctionCall const& _functionCall) override;\n\tvoid operator()(FunctionDefinition const&) override;\n\tvoid operator()(Leave const&) override;\n\n\tusing UnusedStoreBase::visit;\n\tvoid visit(Statement const& _statement) override;\n\n\tusing Location = evmasm::SemanticInformation::Location;\n\tusing Effect = evmasm::SemanticInformation::Effect;\n\tusing OperationLength = std::variant<YulName, u256>;\n\tstruct Operation\n\t{\n\t\tLocation location;\n\t\tEffect effect;\n\t\t/// Start of affected area. Unknown if not provided.\n\t\tstd::optional<YulName> start;\n\t\t/// Length of affected area, unknown if not provided.\n\t\t/// Unused for storage.\n\t\tstd::optional<OperationLength> length;\n\t};\n\nprivate:\n\tstd::set<Statement const*>& activeMemoryStores() { return m_activeStores[UnusedStoreEliminatorKey::Memory]; }\n\tstd::set<Statement const*>& activeStorageStores() { return m_activeStores[UnusedStoreEliminatorKey::Storage]; }\n\tstd::optional<u256> lengthValue(OperationLength const& _length) const\n\t{\n\t\tif (YulName const* length = std::get_if<YulName>(&_length))\n\t\t\treturn m_knowledgeBase.valueIfKnownConstant(*length);\n\t\telse\n\t\t\treturn std::get<u256>(_length);\n\t}\n\n\tvoid shortcutNestedLoop(ActiveStores const&) override\n\t{\n\t\t// We might only need to do this for newly introduced stores in the loop.\n\t\tmarkActiveAsUsed();\n\t}\n\tvoid finalizeFunctionDefinition(FunctionDefinition const&) override\n\t{\n\t\tmarkActiveAsUsed();\n\t}\n\n\tstd::vector<Operation> operationsFromFunctionCall(FunctionCall const& _functionCall) const;\n\tvoid applyOperation(Operation const& _operation);\n\tbool knownUnrelated(Operation const& _op1, Operation const& _op2) const;\n\tbool knownCovered(Operation const& _covered, Operation const& _covering) const;\n\n\tvoid markActiveAsUsed(std::optional<Location> _onlyLocation = std::nullopt);\n\tvoid clearActive(std::optional<Location> _onlyLocation = std::nullopt);\n\n\tstd::optional<YulName> identifierNameIfSSA(Expression const& _expression) const;\n\n\tbool const m_ignoreMemory;\n\tstd::map<FunctionHandle, SideEffects> const& m_functionSideEffects;\n\tstd::map<YulName, ControlFlowSideEffects> m_controlFlowSideEffects;\n\tstd::map<YulName, AssignedValue> const& m_ssaValues;\n\n\tstd::map<Statement const*, Operation> m_storeOperations;\n\n\tKnowledgeBase mutable m_knowledgeBase;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/VarDeclInitializer.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/optimiser/VarDeclInitializer.h>\n#include <libyul/AST.h>\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/Visitor.h>\n#include <libyul/Dialect.h>\n\nusing namespace solidity;\nusing namespace solidity::yul;\n\nvoid VarDeclInitializer::operator()(Block& _block)\n{\n\tASTModifier::operator()(_block);\n\n\tusing OptionalStatements = std::optional<std::vector<Statement>>;\n\tutil::GenericVisitor visitor{\n\t\tutil::VisitorFallback<OptionalStatements>{},\n\t\t[this](VariableDeclaration& _varDecl) -> OptionalStatements\n\t\t{\n\t\t\tif (_varDecl.value)\n\t\t\t\treturn {};\n\n\t\t\tif (_varDecl.variables.size() == 1)\n\t\t\t{\n\t\t\t\t_varDecl.value = std::make_unique<Expression>(m_dialect.zeroLiteral());\n\t\t\t\treturn {};\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tOptionalStatements ret{std::vector<Statement>{}};\n\t\t\t\tfor (auto& var: _varDecl.variables)\n\t\t\t\t{\n\t\t\t\t\tstd::unique_ptr<Expression> expr = std::make_unique<Expression>(m_dialect.zeroLiteral());\n\t\t\t\t\tret->emplace_back(VariableDeclaration{std::move(_varDecl.debugData), {std::move(var)}, std::move(expr)});\n\t\t\t\t}\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t}\n\t};\n\n\tutil::iterateReplacing(_block.statements, [&](auto&& _statement) { return std::visit(visitor, _statement); });\n}\n"
  },
  {
    "path": "libyul/optimiser/VarDeclInitializer.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libyul/ASTForward.h>\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\nnamespace solidity::yul\n{\n\n/**\n * Rewrites variable declarations so that all of them are initialized.\n * Declarations like ``let x, y`` are split into multiple declaration\n * statements.\n * Only supports initializing with the zero literal for now.\n */\nclass VarDeclInitializer: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"VarDeclInitializer\"};\n\tstatic void run(OptimiserStepContext& _ctx, Block& _ast) { VarDeclInitializer{_ctx.dialect}(_ast); }\n\n\tvoid operator()(Block& _block) override;\n\nprivate:\n\texplicit VarDeclInitializer(Dialect const& _dialect): m_dialect(_dialect) {}\n\n\tDialect const& m_dialect;\n};\n\n}\n"
  },
  {
    "path": "libyul/optimiser/VarNameCleaner.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <libyul/optimiser/VarNameCleaner.h>\n#include <libyul/optimiser/OptimizerUtilities.h>\n#include <libyul/AST.h>\n#include <libyul/Dialect.h>\n\n#include <algorithm>\n#include <cctype>\n#include <climits>\n#include <iterator>\n#include <string>\n#include <regex>\n#include <limits>\n\nusing namespace solidity::yul;\n\nVarNameCleaner::VarNameCleaner(\n\tBlock const& _ast,\n\tDialect const& _dialect,\n\tstd::set<YulName> _namesToKeep\n):\n\tm_dialect{_dialect},\n\tm_namesToKeep{std::move(_namesToKeep)},\n\tm_translatedNames{}\n{\n\tfor (auto const& statement: _ast.statements)\n\t\tif (std::holds_alternative<FunctionDefinition>(statement))\n\t\t\tm_namesToKeep.insert(std::get<FunctionDefinition>(statement).name);\n\tm_usedNames = m_namesToKeep;\n}\n\nvoid VarNameCleaner::operator()(FunctionDefinition& _funDef)\n{\n\tyulAssert(!m_insideFunction, \"\");\n\tm_insideFunction = true;\n\n\tstd::set<YulName> globalUsedNames = std::move(m_usedNames);\n\tm_usedNames = m_namesToKeep;\n\tstd::map<YulName, YulName> globalTranslatedNames;\n\tswap(globalTranslatedNames, m_translatedNames);\n\n\trenameVariables(_funDef.parameters);\n\trenameVariables(_funDef.returnVariables);\n\tASTModifier::operator()(_funDef);\n\n\tswap(globalUsedNames, m_usedNames);\n\tswap(globalTranslatedNames, m_translatedNames);\n\n\tm_insideFunction = false;\n}\n\nvoid VarNameCleaner::operator()(VariableDeclaration& _varDecl)\n{\n\trenameVariables(_varDecl.variables);\n\tASTModifier::operator()(_varDecl);\n}\n\nvoid VarNameCleaner::renameVariables(std::vector<NameWithDebugData>& _variables)\n{\n\tfor (NameWithDebugData& variable: _variables)\n\t{\n\t\tauto newName = findCleanName(variable.name);\n\t\tif (newName != variable.name)\n\t\t{\n\t\t\tm_translatedNames[variable.name] = newName;\n\t\t\tvariable.name = newName;\n\t\t}\n\t\tm_usedNames.insert(variable.name);\n\t}\n}\n\nvoid VarNameCleaner::operator()(Identifier& _identifier)\n{\n\tauto name = m_translatedNames.find(_identifier.name);\n\tif (name != m_translatedNames.end())\n\t\t_identifier.name = name->second;\n}\n\nYulName VarNameCleaner::findCleanName(YulName const& _name) const\n{\n\tauto newName = stripSuffix(_name);\n\tif (!isUsedName(newName))\n\t\treturn newName;\n\n\t// create new name with suffix (by finding a free identifier)\n\tfor (size_t i = 1; i < std::numeric_limits<decltype(i)>::max(); ++i)\n\t{\n\t\tYulName newNameSuffixed = YulName{newName.str() + \"_\" + std::to_string(i)};\n\t\tif (!isUsedName(newNameSuffixed))\n\t\t\treturn newNameSuffixed;\n\t}\n\tyulAssert(false, \"Exhausted by attempting to find an available suffix.\");\n}\n\nbool VarNameCleaner::isUsedName(YulName const& _name) const\n{\n\treturn isRestrictedIdentifier(m_dialect, _name.str()) || m_usedNames.contains(_name);\n}\n\nYulName VarNameCleaner::stripSuffix(YulName const& _name) const\n{\n\tstatic std::regex const suffixRegex(\"(_+[0-9]+)+$\");\n\n\tstd::smatch suffixMatch;\n\tif (regex_search(_name.str(), suffixMatch, suffixRegex))\n\t\treturn {YulName{suffixMatch.prefix().str()}};\n\treturn _name;\n}\n"
  },
  {
    "path": "libyul/optimiser/VarNameCleaner.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n\n#include <libyul/ASTForward.h>\n#include <libyul/optimiser/ASTWalker.h>\n#include <libyul/YulName.h>\n#include <libyul/optimiser/OptimiserStep.h>\n\n#include <map>\n#include <set>\n#include <string>\n\nnamespace solidity::yul\n{\n\nclass Dialect;\n\n/**\n * Pass to normalize identifier suffixes.\n *\n * That is, for each function scope, nested suffixes get flattened and all suffixes\n * renumbered by their base name.\n * Function names are not modified.\n *\n * NOTE: This step destroys the promise of the Disambiguator and thus cannot\n * be used in the main loop of the optimizer without running the disambiguator again.\n * Because of that, it is not included in the step list of the Optimizer Suite.\n *\n * Prerequisites: Disambiguator, FunctionHoister, FunctionGrouper\n */\nclass VarNameCleaner: public ASTModifier\n{\npublic:\n\tstatic constexpr char const* name{\"VarNameCleaner\"};\n\tstatic void run(OptimiserStepContext& _context, Block& _ast)\n\t{\n\t\tVarNameCleaner{_ast, _context.dialect, _context.reservedIdentifiers}(_ast);\n\t}\n\n\tusing ASTModifier::operator();\n\tvoid operator()(VariableDeclaration& _varDecl) override;\n\tvoid operator()(Identifier& _identifier) override;\n\tvoid operator()(FunctionDefinition& _funDef) override;\n\nprivate:\n\tVarNameCleaner(\n\t\tBlock const& _ast,\n\t\tDialect const& _dialect,\n\t\tstd::set<YulName> _namesToKeep = {}\n\t);\n\n\t/// Tries to rename a list of variables.\n\tvoid renameVariables(std::vector<NameWithDebugData>& _variables);\n\n\t/// @returns suffix-stripped name, if a suffix was detected, none otherwise.\n\tYulName stripSuffix(YulName const& _name) const;\n\n\t/// Looks out for a \"clean name\" the given @p name could be trimmed down to.\n\t/// @returns a trimmed down and \"clean name\" in case it found one, none otherwise.\n\tYulName findCleanName(YulName const& name) const;\n\n\t/// Tests whether a given name was already used within this pass\n\t/// or was set to be kept.\n\tbool isUsedName(YulName const& _name) const;\n\n\tDialect const& m_dialect;\n\n\t/// These names will not be modified.\n\tstd::set<YulName> m_namesToKeep;\n\n\t/// Set of names that are in use.\n\tstd::set<YulName> m_usedNames;\n\n\t/// Maps old to new names.\n\tstd::map<YulName, YulName> m_translatedNames;\n\n\t/// Whether the traverse is inside a function definition.\n\t/// Used to assert that a function definition cannot be inside another.\n\tbool m_insideFunction = false;\n};\n\n}\n"
  },
  {
    "path": "scripts/ASTImportTest.sh",
    "content": "#!/usr/bin/env bash\n# ------------------------------------------------------------------------------\n# vim:ts=4:et\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) solidity contributors.\n# ------------------------------------------------------------------------------\n# Bash script to test the import/exports.\n#\n# ast import/export tests:\n#   - first exporting a .sol file to JSON, then loading it into the compiler\n#     and exporting it again. The second JSON should be identical to the first.\n#\n# evm-assembly import/export tests:\n#   - first a .sol file will be compiled and the EVM Assembly will be exported\n#     to JSON format using --asm-json command-line option.\n#     The EVM Assembly JSON output is then imported with --import-asm-json\n#     and compiled again. The binary generated initially and after the import\n#     should be identical.\n\nset -euo pipefail\n\nREADLINK=readlink\nif [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n    READLINK=greadlink\nfi\nEXPR=\"expr\"\nif [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n    EXPR=\"gexpr\"\nfi\n\nREPO_ROOT=$(${READLINK} -f \"$(dirname \"$0\")\"/..)\nSOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${REPO_ROOT}/build}\nSOLC=\"${SOLIDITY_BUILD_DIR}/solc/solc\"\nSPLITSOURCES=\"${REPO_ROOT}/scripts/splitSources.py\"\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n# shellcheck source=scripts/common_cmdline.sh\nsource \"${REPO_ROOT}/scripts/common_cmdline.sh\"\n\nfunction print_usage\n{\n    echo \"Usage: ${0} ast|evm-assembly [--exit-on-error|--help].\"\n}\n\nfunction print_used_commands\n{\n    local test_directory=\"$1\"\n    local export_command=\"$2\"\n    local import_command=\"$3\"\n    echo\n    printError \"You can find the files used for this test in ${test_directory}\"\n    printError \"Commands used in the test:\"\n    printError \"# export\"\n    echo \"$ ${export_command}\" >&2\n    printError \"# import\"\n    echo \"$ ${import_command}\" >&2\n}\n\nfunction print_stderr_stdout\n{\n    local error_message=\"$1\"\n    local stderr_file=\"$2\"\n    local stdout_file=\"$3\"\n    printError \"$error_message\"\n    printError \"\"\n    printError \"stderr:\"\n    cat \"$stderr_file\" >&2\n    printError \"\"\n    printError \"stdout:\"\n    cat \"$stdout_file\" >&2\n}\n\nfunction check_import_test_type_unset\n{\n    [[ -z \"$IMPORT_TEST_TYPE\" ]] || fail \"ERROR: Import test type can only be set once. Aborting.\"\n}\n\nIMPORT_TEST_TYPE=\nEXIT_ON_ERROR=0\nfor PARAM in \"$@\"\ndo\n    case \"$PARAM\" in\n        ast) check_import_test_type_unset ; IMPORT_TEST_TYPE=\"ast\" ;;\n        evm-assembly) check_import_test_type_unset ; IMPORT_TEST_TYPE=\"evm-assembly\" ;;\n        --help) print_usage ; exit 0 ;;\n        --exit-on-error) EXIT_ON_ERROR=1 ;;\n        *) fail \"Unknown option '$PARAM'. Aborting. $(print_usage)\" ;;\n    esac\ndone\n\nSYNTAXTESTS_DIR=\"${REPO_ROOT}/test/libsolidity/syntaxTests\"\nASTJSONTESTS_DIR=\"${REPO_ROOT}/test/libsolidity/ASTJSON\"\nSEMANTICTESTS_DIR=\"${REPO_ROOT}/test/libsolidity/semanticTests\"\n\nFAILED=0\nUNCOMPILABLE=0\nTESTED=0\n\nfunction test_ast_import_export_equivalence\n{\n    local sol_file=\"$1\"\n    local input_files=( \"${@:2}\" )\n\n    local export_command=(\"$SOLC\" --combined-json ast --pretty-json --json-indent 4 \"${input_files[@]}\")\n    local import_command=(\"$SOLC\" --experimental --import-ast --combined-json ast --pretty-json --json-indent 4 expected.json)\n    local import_via_standard_json_command=(\"$SOLC\" --combined-json ast --pretty-json --json-indent 4 --standard-json standard_json_input.json)\n\n    # export ast - save ast json as expected result (silently)\n    if ! \"${export_command[@]}\" > expected.json 2> stderr_export.txt\n    then\n        print_stderr_stdout \"ERROR: AST reimport failed (export) for input file ${sol_file}.\" ./stderr_export.txt ./expected.json\n        print_used_commands \"$(pwd)\" \"${export_command[*]} > expected.json\" \"${import_command[*]}\"\n        return 1\n    fi\n\n    # (re)import ast - and export it again as obtained result (silently)\n    if ! \"${import_command[@]}\" > obtained.json 2> stderr_import.txt\n    then\n        print_stderr_stdout \"ERROR: AST reimport failed (import) for input file ${sol_file}.\" ./stderr_import.txt ./obtained.json\n        print_used_commands \"$(pwd)\" \"${export_command[*]} > expected.json\" \"${import_command[*]}\"\n        return 1\n    fi\n\n    echo \". += {\\\"sources\\\":\" > _ast_json.json\n    jq .sources expected.json >> _ast_json.json\n    echo \"}\" >> _ast_json.json\n    echo \"{\\\"language\\\": \\\"SolidityAST\\\", \\\"settings\\\": {\\\"experimental\\\": true, \\\"outputSelection\\\": {\\\"*\\\": {\\\"\\\": [\\\"ast\\\"]}}}}\" > standard_json.json\n    jq --from-file _ast_json.json standard_json.json > standard_json_input.json\n\n    # (re)import ast via standard json - and export it again as obtained result (silently)\n    if ! \"${import_via_standard_json_command[@]}\" > obtained_standard_json.json 2> stderr_import.txt\n    then\n        print_stderr_stdout \"ERROR: AST reimport failed (import) for input file ${sol_file}.\" ./stderr_import.txt ./obtained_standard_json.json\n        print_used_commands \"$(pwd)\" \"${export_command[*]} > expected.json\" \"${import_command[*]}\"\n        return 1\n    fi\n\n    jq .sources expected.json > expected_standard_json.json\n    jq .sources obtained_standard_json.json >  obtained_standard_json_.json\n    jq 'walk(if type == \"object\" and has(\"ast\") then .AST = .ast | del(.ast) else . end)' < obtained_standard_json_.json > obtained_standard_json.json\n    jq --sort-keys . < obtained_standard_json.json > obtained_standard_json_.json\n    mv obtained_standard_json_.json obtained_standard_json.json\n\n    # compare expected and obtained ASTs\n    if ! diff_files expected.json obtained.json || ! diff_files expected_standard_json.json obtained_standard_json.json\n    then\n        printError \"ERROR: AST reimport failed for ${sol_file}\"\n        if (( EXIT_ON_ERROR == 1 ))\n        then\n            print_used_commands \"$(pwd)\" \"${export_command[*]}\" \"${import_command[*]}\"\n            return 1\n        fi\n        FAILED=$((FAILED + 1))\n    fi\n    TESTED=$((TESTED + 1))\n}\n\nfunction run_solc\n{\n    local parameters=( \"${@}\" )\n\n    if ! \"${SOLC}\" \"${parameters[@]}\" > /dev/null 2> solc_stderr\n    then\n        printError \"ERROR: ${parameters[*]}\"\n        printError \"${PWD}\"\n        # FIXME: EXIT_ON_ERROR seems to be ignored here and in some other places.\n        # We just exit unconditionally instead.\n        fail \"$(cat solc_stderr)\"\n    fi\n    rm solc_stderr\n}\n\nfunction run_solc_store_stdout\n{\n    local output_file=$1\n    local parameters=( \"${@:2}\" )\n\n    if ! \"${SOLC}\" \"${parameters[@]}\" > \"${output_file}\" 2> \"${output_file}.error\"\n    then\n        printError \"ERROR: ${parameters[*]}\"\n        printError \"${PWD}\"\n        fail \"$(cat \"${output_file}.error\")\"\n    fi\n    rm \"${output_file}.error\"\n}\n\nfunction test_evmjson_import_export_equivalence\n{\n    local sol_file=\"$1\"\n    local input_files=( \"${@:2}\" )\n\n    # Generate bytecode and EVM assembly JSON through normal complication\n    mkdir -p export/\n    local export_options=(--bin --asm-json \"${input_files[@]}\" --output-dir export/)\n    run_solc \"${export_options[@]}\"\n\n    # NOTE: If there is no bytecode, the compiler produces a JSON file that contains just 'null'.\n    # This is not accepted by assembly import though so we must skip such contracts.\n    echo -n null > null\n    find export/ -name '*.json' -exec cmp --quiet --bytes=4 {} null \\; -delete\n\n    find export/ -name '*.bin' -size 0 -delete\n\n    for asm_json_file in export/*.json\n    do\n        mv \"${asm_json_file}\" \"${asm_json_file/_evm/}\"\n    done\n\n    # Import EVM assembly JSON\n    mkdir -p import/\n    for asm_json_file in export/*.json\n    do\n        local bin_file_from_asm_import\n        bin_file_from_asm_import=\"import/$(basename \"${asm_json_file}\" .json).bin\"\n\n        local import_options=(--experimental --bin --import-asm-json \"${asm_json_file}\")\n        run_solc_store_stdout \"${bin_file_from_asm_import}\" \"${import_options[@]}\"\n\n        stripCLIDecorations < \"$bin_file_from_asm_import\" > tmpfile\n        mv tmpfile \"$bin_file_from_asm_import\"\n    done\n\n    # Compare bytecode from compilation with bytecode from import\n    for bin_file in export/*.bin\n    do\n        local bin_file_from_asm_import=${bin_file/export/import}\n        if ! diff --strip-trailing-cr --ignore-all-space \"${bin_file}\" \"${bin_file_from_asm_import}\" > diff_error\n        then\n            printError \"ERROR: Bytecode from compilation (${bin_file}) differs from bytecode from EVM asm import (${bin_file_from_asm_import}):\"\n            printError \"    $(cat diff_error)\"\n            if (( EXIT_ON_ERROR == 1 ))\n            then\n                # NOTE: The import_options we print here refers to the wrong file (the last one\n                # processed by the previous loop) - but it's still a good starting point for debugging ;)\n                print_used_commands \"${PWD}\" \"${SOLC} ${export_options[*]}\" \"${SOLC} ${import_options[*]}\"\n                return 1\n            fi\n            FAILED=$((FAILED + 1))\n        fi\n    done\n    TESTED=$((TESTED + 1))\n}\n\n# function tests whether exporting and importing again is equivalent.\n# Results are recorded by incrementing the FAILED or UNCOMPILABLE global variable.\n# Also, in case of a mismatch a diff is printed\n# Expected parameters:\n# $1 name of the file to be exported and imported\n# $2 any files needed to do so that might be in parent directories\nfunction test_import_export_equivalence {\n    local sol_file=\"$1\"\n    local input_files=( \"${@:2}\" )\n    local output\n    local solc_return_code\n    local compile_test\n\n    case \"$IMPORT_TEST_TYPE\" in\n        ast) compile_test=\"--ast-compact-json\" ;;\n        evm-assembly) compile_test=\"--bin\" ;;\n        *) assertFail \"Unknown import test type '${IMPORT_TEST_TYPE}'. Aborting.\" ;;\n    esac\n\n    set +e\n    output=$(\"$SOLC\" \"${compile_test}\" \"${input_files[@]}\" 2>&1)\n    solc_return_code=$?\n    set -e\n\n    # if input files where compilable with success\n    if (( solc_return_code == 0 ))\n    then\n        case \"$IMPORT_TEST_TYPE\" in\n            ast) test_ast_import_export_equivalence \"${sol_file}\" \"${input_files[@]}\" ;;\n            evm-assembly) test_evmjson_import_export_equivalence \"${sol_file}\" \"${input_files[@]}\" ;;\n            *) assertFail \"Unknown import test type '${IMPORT_TEST_TYPE}'. Aborting.\" ;;\n        esac\n    else\n        UNCOMPILABLE=$((UNCOMPILABLE + 1))\n\n        # solc will return exit code 2, if it was terminated by an uncaught exception.\n        # This should normally not happen, so we terminate the test execution here\n        # and print some details about the corresponding solc invocation.\n        if (( solc_return_code == 2 ))\n        then\n            # For the evm-assembly import/export tests, this script uses only the old code generator.\n            # Some semantic tests can only be compiled with --via-ir (some need to be additionally\n            # compiled with --optimize). The tests that are meant to be compiled with --via-ir are\n            # throwing an UnimplementedFeatureError exception, e.g.:\n            # \"Copying of type struct C.S memory[] memory to storage not yet supported\",\n            # \"Copying nested calldata dynamic arrays to storage is not implemented in the old code generator\".\n            # We will just ignore these kind of exceptions for now. However, any other exception\n            # will be treated as a fatal error and the script execution will be terminated with an error.\n            if [[ \"${output}\" != *\"UnimplementedFeatureError\"* ]]\n            then\n                fail \"\\n\\nERROR: Uncaught exception while executing '${SOLC} ${compile_test} ${input_files[*]}':\\n${output}\\n\"\n            fi\n        fi\n    fi\n}\n\ncommand_available \"$SOLC\" --version\ncommand_available jq --version\ncommand_available \"$EXPR\" --version\ncommand_available \"$READLINK\" --version\n\ncase \"$IMPORT_TEST_TYPE\" in\n    ast) TEST_DIRS=(\"${SYNTAXTESTS_DIR}\" \"${ASTJSONTESTS_DIR}\") ;;\n    evm-assembly) TEST_DIRS=(\"${SEMANTICTESTS_DIR}\") ;;\n    *) assertFail \"Import test type not defined. $(print_usage)\" ;;\nesac\n\n# boost_filesystem_bug specifically tests a local fix for a boost::filesystem\n# bug. Since the test involves a malformed path, there is no point in running\n# tests on it. See https://github.com/boostorg/filesystem/issues/176\n# In addition, exclude all experimental Solidity tests (new type inference system)\nEXCLUDE_FILES=(\n  boost_filesystem_bug.sol\n  pragma_experimental_solidity.sol\n)\nEXCLUDE_FILES_JOINED=$(printf \"! -name %s \" \"${EXCLUDE_FILES[@]}\")\n# shellcheck disable=SC2086\nIMPORT_TEST_FILES=$(find \"${TEST_DIRS[@]}\" -name \"*.sol\" -and $EXCLUDE_FILES_JOINED -not -path \"*/experimental/*\")\n\nNSOURCES=\"$(echo \"${IMPORT_TEST_FILES}\" | wc -l)\"\necho \"Looking at ${NSOURCES} .sol files...\"\n\nCOUNTER=0\nTEST_DIR=$(mktemp -d -t \"import-export-test-XXXXXX\")\npushd \"$TEST_DIR\" > /dev/null\n\nfor solfile in $IMPORT_TEST_FILES\ndo\n    echo -n \"·\"\n\n    TEST_SUBDIR=\"$(printf \"%05d\" \"$COUNTER\")-$(basename \"$solfile\")\"\n    mkdir \"$TEST_SUBDIR\"\n    pushd \"$TEST_SUBDIR\" > /dev/null\n\n    set +e\n    OUTPUT=$(\"$SPLITSOURCES\" \"$solfile\")\n    SPLITSOURCES_RC=$?\n    set -e\n\n    if (( SPLITSOURCES_RC == 0 ))\n    then\n        IFS=' ' read -ra OUTPUT_ARRAY <<< \"$OUTPUT\"\n        test_import_export_equivalence \"$solfile\" \"${OUTPUT_ARRAY[@]}\"\n    elif (( SPLITSOURCES_RC == 1 ))\n    then\n        test_import_export_equivalence \"$solfile\" \"$solfile\"\n    elif (( SPLITSOURCES_RC == 2 ))\n    then\n        # The script will exit with return code 2, if an UnicodeDecodeError occurred.\n        # This is the case if e.g. some tests are using invalid utf-8 sequences. We will ignore\n        # these errors, but print the actual output of the script.\n        printError \"\\n\\n${OUTPUT}\\n\\n\"\n        test_import_export_equivalence \"$solfile\" \"$solfile\"\n    else\n        # All other return codes will be treated as critical errors. The script will exit.\n        printError \"\\n\\nGot unexpected return code ${SPLITSOURCES_RC} from '${SPLITSOURCES} ${solfile}'. Aborting.\"\n        printError \"\\n\\n${OUTPUT}\\n\\n\"\n        exit 1\n    fi\n\n    popd > /dev/null\n    ((++COUNTER))\ndone\n\npopd > /dev/null\nrm -r \"$TEST_DIR\"\n\necho\n\nif (( FAILED == 0 ))\nthen\n    echo \"SUCCESS: ${TESTED} tests passed, ${FAILED} failed, ${UNCOMPILABLE} could not be compiled (${NSOURCES} sources total).\"\nelse\n    fail \"FAILURE: Out of ${NSOURCES} sources, ${FAILED} failed, (${UNCOMPILABLE} could not be compiled).\"\nfi\n"
  },
  {
    "path": "scripts/AntlrBatchTestRig.java",
    "content": "import org.antlr.v4.runtime.*;\nimport java.io.*;\nimport java.nio.file.*;\n\npublic class AntlrBatchTestRig {\n    public static void main(String[] args) throws Exception {\n        if (args.length < 1) {\n            System.err.println(\"Usage: AntlrBatchTestRig <file1> [file2] ...\");\n            System.exit(1);\n        }\n\n        int exitCode = 0;\n        for (String filePath: args) {\n            try {\n                if (!testFile(filePath))\n                    exitCode = 1;\n            } catch (Exception e) {\n                System.err.println(\"ERROR:\" + filePath + \":\" + e.getMessage());\n                exitCode = 1;\n            }\n        }\n        System.exit(exitCode);\n    }\n\n    private static boolean testFile(String filePath) throws Exception {\n        // Detect mode based on file extension\n        String mode = filePath.endsWith(\".yul\") ? \"yul\" : \"sol\";\n        String content = new String(Files.readAllBytes(Paths.get(filePath)));\n\n        // Check if file expects parser error\n        boolean expectsError = content.contains(\"// ParserError\");\n\n        CharStream input;\n        if (mode.equals(\"sol\")) {\n            // Remove ExternalSource lines for Solidity files\n            content = content.replaceAll(\"(?m)^==== ExternalSource:.*$\", \"\");\n            input = CharStreams.fromString(content);\n        } else {\n            // Wrap Yul in assembly statement\n            input = CharStreams.fromString(\"assembly \" + content);\n        }\n\n        SolidityLexer lexer = new SolidityLexer(input);\n        CommonTokenStream tokens = new CommonTokenStream(lexer);\n        SolidityParser parser = new SolidityParser(tokens);\n\n        // Remove default error listeners and add custom one\n        parser.removeErrorListeners();\n        lexer.removeErrorListeners();\n\n        ErrorCollector errorCollector = new ErrorCollector();\n        parser.addErrorListener(errorCollector);\n        lexer.addErrorListener(errorCollector);\n\n        // Parse based on mode\n        if (mode.equals(\"sol\")) {\n            parser.sourceUnit();\n        } else {\n            parser.assemblyStatement();\n        }\n\n        boolean hasErrors = errorCollector.hasErrors();\n\n        // Output result\n        if (expectsError) {\n            if (hasErrors) {\n                System.out.println(\"PASS:\" + filePath + \":FAILED_AS_EXPECTED\");\n            } else {\n                System.out.println(\"FAIL:\" + filePath + \":SUCCEEDED_DESPITE_PARSER_ERROR\");\n                return false;\n            }\n        } else {\n            if (!hasErrors) {\n                System.out.println(\"PASS:\" + filePath + \":OK\");\n            } else {\n                System.out.println(\"FAIL:\" + filePath + \":\" + errorCollector.getErrors());\n                return false;\n            }\n        }\n        return true;\n    }\n\n    static class ErrorCollector extends BaseErrorListener {\n        private StringBuilder errors = new StringBuilder();\n        private boolean hasErrors = false;\n\n        @Override\n        public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol,\n                              int line, int charPositionInLine,\n                              String msg, RecognitionException e) {\n            hasErrors = true;\n            errors.append(\"line \").append(line).append(\":\").append(charPositionInLine)\n                  .append(\" \").append(msg).append(\"\\n\");\n        }\n\n        public boolean hasErrors() {\n            return hasErrors;\n        }\n\n        public String getErrors() {\n            return errors.toString();\n        }\n    }\n}\n"
  },
  {
    "path": "scripts/Dockerfile",
    "content": "FROM alpine AS build\n\n#Establish working directory as solidity\nWORKDIR /solidity\n\n# Build dependencies\nRUN apk update && apk add boost-dev boost-static build-base cmake git clang\n\n#Copy working directory to the image\nCOPY . /solidity\n\n# Number of parallel jobs during build\n# or 0 for auto-computing (max(1, CPU_core_count * 2/3), a greedy value)\nARG BUILD_CONCURRENCY=\"0\"\n\n#Install dependencies, eliminate annoying warnings\nRUN sed -i -E -e 's/include <sys\\/poll.h>/include <poll.h>/' /usr/include/boost/asio/detail/socket_types.hpp\nRUN cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DTESTS=0 -DSOLC_LINK_STATIC=1\nRUN make solc \\\n    -j$(awk \"BEGIN {                                       \\\n        if (${BUILD_CONCURRENCY} != 0) {                   \\\n            print(${BUILD_CONCURRENCY});                   \\\n        } else {                                           \\\n            x=($(grep -c ^processor /proc/cpuinfo) * 2/3); \\\n            if (x > 1) {                                   \\\n                printf(\\\"%d\\n\\\", x);                       \\\n            } else {                                       \\\n                print(1);                                  \\\n            }                                              \\\n        }                                                  \\\n    }\")\nRUN strip solc/solc\n\nFROM scratch\nLABEL org.opencontainers.image.source=https://github.com/argotorg/solidity\nLABEL maintainer=\"Solidity Team <solidity@argot.org>\"\nCOPY --from=build /solidity/solc/solc /usr/bin/solc\nENTRYPOINT [\"/usr/bin/solc\"]\n"
  },
  {
    "path": "scripts/Dockerfile_alpine",
    "content": "FROM alpine\nLABEL org.opencontainers.image.source=https://github.com/argotorg/solidity\nLABEL maintainer=\"Solidity Team <solidity@argot.org>\"\n\nCOPY upload/solc-static-linux /usr/local/bin/solc\nENTRYPOINT [\"/usr/local/bin/solc\"]\n"
  },
  {
    "path": "scripts/build.sh",
    "content": "#!/usr/bin/env bash\nset -e\n\nROOTDIR=$(dirname \"$0\")/..\nBUILDDIR=\"${ROOTDIR}/build\"\n\nif (( $# == 0 )); then\n    BUILD_TYPE=Release\nelse\n    BUILD_TYPE=\"$1\"\nfi\n\n# Intentionally not using prerelease_suffix.sh here. We do not want lingering prerelease.txt in\n# dev builds, accidentally overriding version when someone runs the build manually.\nif [[ $(git tag --points-at HEAD 2> /dev/null) =~ ^v[0-9.]+$ ]]; then\n    echo -n > prerelease.txt\nfi\n\nmkdir -p \"$BUILDDIR\"\ncd \"$BUILDDIR\"\n\ncmake .. -DCMAKE_BUILD_TYPE=\"$BUILD_TYPE\" \"${@:2}\"\nmake -j2\n\nif [[ $CI == \"\" ]]; then\n    echo \"Installing ...\"\n    sudo make install\nfi\n"
  },
  {
    "path": "scripts/build_emscripten.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Bash script for building Solidity for emscripten.\n#\n# The documentation for solidity is hosted at:\n#\n#     https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nparams=\"\"\nif (( $# != 0 )); then\n    params=\"$(printf \"%q \" \"${@}\")\"\nfi\n\n# ghcr.io/argotorg/solidity-buildpack-deps:emscripten-22\n# NOTE: Without `safe.directory` git would assume it's not safe to operate on /root/project since it's owned by a different user.\n# See https://github.blog/2022-04-12-git-security-vulnerability-announced/\ndocker run -v \"$(pwd):/root/project\" -w /root/project \\\n    ghcr.io/argotorg/solidity-buildpack-deps@sha256:b9c953144d82cca5553f65626bc43b8af456dbc8966f8732ff9522f33ca8d722 \\\n    /bin/bash -c \"git config --global --add safe.directory /root/project && ./scripts/ci/build_emscripten.sh ${params}\"\n"
  },
  {
    "path": "scripts/bytecodecompare/prepare_report.js",
    "content": "#!/usr/bin/env node\nconst process = require('process')\nconst fs = require('fs')\n\nconst compiler = require('solc')\n\nconst SETTINGS_PRESETS = {\n    'legacy-optimize':    {optimize: true,  viaIR: false},\n    'legacy-no-optimize': {optimize: false, viaIR: false},\n    'via-ir-optimize':    {optimize: true,  viaIR: true},\n    'via-ir-no-optimize': {optimize: false, viaIR: true},\n}\n\nfunction loadSource(sourceFileName, stripSMTPragmas)\n{\n    source = fs.readFileSync(sourceFileName).toString()\n\n    if (stripSMTPragmas)\n        // NOTE: replace() with string parameter replaces only the first occurrence.\n        return source.replace('pragma experimental SMTChecker;', '');\n\n    return source\n}\n\nfunction cleanString(string)\n{\n    if (string !== undefined)\n        string = string.trim()\n    return (string !== '' ? string : undefined)\n}\n\nlet inputFiles = []\nlet stripSMTPragmas = false\nlet presets = []\nlet reportFilePath = undefined\n\nfor (let i = 2; i < process.argv.length; ++i)\n{\n    if (process.argv[i] === '--strip-smt-pragmas')\n        stripSMTPragmas = true\n    else if (process.argv[i] === '--preset')\n    {\n        if (i + 1 === process.argv.length)\n            throw Error(\"Option --preset was used, but no preset name given.\")\n\n        presets.push(process.argv[i + 1])\n        ++i;\n    }\n    else if (process.argv[i] === '--report-file')\n    {\n        if (reportFilePath !== undefined)\n            throw Error(\"Option --report-file was specified multiple times.\")\n\n        if (i + 1 === process.argv.length)\n            throw Error(\"Option --report-file was used, but no file name given.\")\n\n        reportFilePath = process.argv[i + 1]\n        ++i;\n    }\n    else\n        inputFiles.push(process.argv[i])\n}\n\nif (reportFilePath === undefined)\n    throw Error(\"Use --report-file option to specify the report file path.\")\n\nlet reportFile = fs.createWriteStream(reportFilePath, {flags : 'w'});\n\nif (presets.length === 0)\n    presets = ['legacy-no-optimize', 'legacy-optimize']\n\nfor (const preset of presets)\n    if (!(preset in SETTINGS_PRESETS))\n        throw Error(`Invalid preset name: ${preset}.`)\n\nfor (const preset of presets)\n{\n    settings = SETTINGS_PRESETS[preset]\n\n    for (const filename of inputFiles)\n    {\n        let input = {\n            language: 'Solidity',\n            sources: {\n                [filename]: {content: loadSource(filename, stripSMTPragmas)}\n            },\n            settings: {\n                optimizer: {enabled: settings.optimize},\n                // NOTE: We omit viaIR rather than set it to false to handle older versions that don't have it.\n                viaIR: settings.viaIR ? true : undefined,\n                outputSelection: {'*': {'*': ['evm.bytecode.object', 'metadata']}}\n            }\n        }\n        if (!stripSMTPragmas)\n            input['settings']['modelChecker'] = {engine: 'none'}\n\n        let serializedOutput\n        let result\n        const serializedInput = JSON.stringify(input)\n\n        let internalCompilerError = false\n        try\n        {\n            serializedOutput = compiler.compile(serializedInput)\n        }\n        catch (exception)\n        {\n            internalCompilerError = true\n        }\n\n        if (!internalCompilerError)\n        {\n            result = JSON.parse(serializedOutput)\n\n            if ('errors' in result)\n                for (const error of result['errors'])\n                    // JSON interface still returns contract metadata in case of an internal compiler error while\n                    // CLI interface does not. To make reports comparable we must force this case to be detected as\n                    // an error in both cases.\n                    if (['UnimplementedFeatureError', 'CompilerError', 'CodeGenerationError', 'YulException'].includes(error['type']))\n                    {\n                        internalCompilerError = true\n                        break\n                    }\n        }\n\n        if (\n            internalCompilerError ||\n            !('contracts' in result) ||\n            Object.keys(result['contracts']).length === 0 ||\n            Object.keys(result['contracts']).every(file => Object.keys(result['contracts'][file]).length === 0)\n        )\n        {\n            // NOTE: do not exit here because this may be run on source which cannot be compiled\n            reportFile.write(filename + ': <ERROR>\\n')\n            process.stdout.write('E')\n        }\n        else\n            for (const contractFile in result['contracts'])\n                for (const contractName in result['contracts'][contractFile])\n                {\n                    const contractResults = result['contracts'][contractFile][contractName]\n\n                    let bytecode = '<NO BYTECODE>'\n                    let metadata = '<NO METADATA>'\n                    let progressIndicator = '.'\n\n                    if ('metadata' in contractResults && cleanString(contractResults.metadata) !== undefined)\n                        metadata = contractResults.metadata\n                    else\n                        progressIndicator = 'M'\n\n                    if (\n                        'evm' in contractResults &&\n                        'bytecode' in contractResults['evm'] &&\n                        'object' in contractResults['evm']['bytecode'] &&\n                        cleanString(contractResults.evm.bytecode.object) !== undefined\n                    )\n                        bytecode = cleanString(contractResults.evm.bytecode.object)\n                    else\n                        progressIndicator = 'B'\n\n                    reportFile.write(filename + ':' + contractName + ' ' + bytecode + '\\n')\n                    reportFile.write(filename + ':' + contractName + ' ' + metadata + '\\n')\n                    process.stdout.write(progressIndicator)\n                }\n    }\n}\n"
  },
  {
    "path": "scripts/bytecodecompare/prepare_report.py",
    "content": "#!/usr/bin/env python3\n\nimport sys\nimport subprocess\nimport json\nimport re\nfrom argparse import ArgumentParser\nfrom dataclasses import dataclass\nfrom enum import Enum\nfrom glob import glob\nfrom pathlib import Path\nfrom tempfile import TemporaryDirectory\nfrom typing import List, Optional, Tuple, Union\n\n\nCONTRACT_SEPARATOR_PATTERN = re.compile(\n    r'^ *======= +(?:(?P<file_name>.+) *:)? *(?P<contract_name>[^:]+) +======= *$',\n    re.MULTILINE\n)\nBYTECODE_REGEX = re.compile(r'^ *Binary: *\\n(?P<bytecode>.*[0-9a-f$_]+.*)$', re.MULTILINE)\nMETADATA_REGEX = re.compile(r'^ *Metadata: *\\n *(?P<metadata>\\{.*\\}) *$', re.MULTILINE)\n\n\nclass CompilerInterface(Enum):\n    CLI = 'cli'\n    STANDARD_JSON = 'standard-json'\n\n\nclass ExecutionArchitecture(Enum):\n    NATIVE = 'native'\n    OSX_INTEL = 'osx_intel'\n\n\nclass SettingsPreset(Enum):\n    LEGACY_OPTIMIZE = 'legacy-optimize'\n    LEGACY_NO_OPTIMIZE = 'legacy-no-optimize'\n    VIA_IR_OPTIMIZE = 'via-ir-optimize'\n    VIA_IR_NO_OPTIMIZE = 'via-ir-no-optimize'\n\n\nclass SMTUse(Enum):\n    PRESERVE = 'preserve'\n    DISABLE = 'disable'\n    STRIP_PRAGMAS = 'strip-pragmas'\n\n\n@dataclass(frozen=True)\nclass CompilerSettings:\n    optimize: bool\n    via_ir: bool\n\n    @staticmethod\n    def from_preset(preset: SettingsPreset):\n        return {\n            SettingsPreset.LEGACY_OPTIMIZE:    CompilerSettings(optimize=True,  via_ir=False),\n            SettingsPreset.LEGACY_NO_OPTIMIZE: CompilerSettings(optimize=False, via_ir=False),\n            SettingsPreset.VIA_IR_OPTIMIZE:    CompilerSettings(optimize=True,  via_ir=True),\n            SettingsPreset.VIA_IR_NO_OPTIMIZE: CompilerSettings(optimize=False, via_ir=True),\n        }[preset]\n\n\n@dataclass(frozen=True)\nclass ContractReport:\n    contract_name: str\n    file_name: Optional[Path]\n    bytecode: Optional[str]\n    metadata: Optional[str]\n\n\n@dataclass\nclass FileReport:\n    file_name: Path\n    contract_reports: Optional[List[ContractReport]]\n\n    def format_report(self) -> str:\n        report = \"\"\n\n        if self.contract_reports is None:\n            return f\"{self.file_name.as_posix()}: <ERROR>\\n\"\n\n        for contract_report in self.contract_reports:\n            bytecode = contract_report.bytecode if contract_report.bytecode is not None else '<NO BYTECODE>'\n            metadata = contract_report.metadata if contract_report.metadata is not None else '<NO METADATA>'\n\n            # NOTE: Ignoring contract_report.file_name because it should always be either the same\n            # as self.file_name (for Standard JSON) or just the '<stdin>' placeholder (for CLI).\n            report += f\"{self.file_name.as_posix()}:{contract_report.contract_name} {bytecode}\\n\"\n            report += f\"{self.file_name.as_posix()}:{contract_report.contract_name} {metadata}\\n\"\n\n        return report\n\n    def format_summary(self, verbose: bool) -> str:\n        error = (self.contract_reports is None)\n        contract_reports = self.contract_reports if self.contract_reports is not None else []\n        no_bytecode = any(bytecode is None for bytecode in contract_reports)\n        no_metadata = any(metadata is None for metadata in contract_reports)\n\n        if verbose:\n            flags = ('E' if error else ' ') + ('B' if no_bytecode else ' ') + ('M' if no_metadata else ' ')\n            contract_count = '?' if self.contract_reports is None else str(len(self.contract_reports))\n            return f\"{contract_count} {flags} {self.file_name}\"\n        else:\n            if error:\n                return 'E'\n            if no_bytecode:\n                return 'B'\n            if no_metadata:\n                return 'M'\n\n            return '.'\n\n\n@dataclass\nclass Statistics:\n    file_count: int = 0\n    contract_count: int = 0\n    error_count: int = 0\n    missing_bytecode_count: int = 0\n    missing_metadata_count: int = 0\n\n    def aggregate(self, report: FileReport):\n        contract_reports = report.contract_reports if report.contract_reports is not None else []\n\n        self.file_count += 1\n        self.contract_count += len(contract_reports)\n        self.error_count += (1 if report.contract_reports is None else 0)\n        self.missing_bytecode_count += sum(1 for c in contract_reports if c.bytecode is None)\n        self.missing_metadata_count += sum(1 for c in contract_reports if c.metadata is None)\n\n    def __str__(self) -> str:\n        contract_count = str(self.contract_count) + ('+' if self.error_count > 0 else '')\n        return (\n            f\"test cases: {self.file_count}, \"\n            f\"contracts: {contract_count}, \"\n            f\"errors: {self.error_count}, \"\n            f\"missing bytecode: {self.missing_bytecode_count}, \"\n            f\"missing metadata: {self.missing_metadata_count}\"\n        )\n\n\ndef load_source(path: Union[Path, str], smt_use: SMTUse) -> str:\n    # NOTE: newline='' disables newline conversion.\n    # We want the file exactly as is because changing even a single byte in the source affects metadata.\n    with open(path, mode='r', encoding='utf8', newline='') as source_file:\n        file_content = source_file.read()\n\n    if smt_use == SMTUse.STRIP_PRAGMAS:\n        return file_content.replace('pragma experimental SMTChecker;', '', 1)\n\n    return file_content\n\n\ndef clean_string(value: Optional[str]) -> Optional[str]:\n    value = value.strip() if value is not None else None\n    return value if value != '' else None\n\n\ndef parse_standard_json_output(source_file_name: Path, standard_json_output: str) -> FileReport:\n    decoded_json_output = json.loads(standard_json_output.strip())\n\n    # JSON interface still returns contract metadata in case of an internal compiler error while\n    # CLI interface does not. To make reports comparable we must force this case to be detected as\n    # an error in both cases.\n    internal_compiler_error = any(\n        error['type'] in ['UnimplementedFeatureError', 'CompilerError', 'CodeGenerationError', 'YulException']\n        for error in decoded_json_output.get('errors', {})\n    )\n\n    if (\n        'contracts' not in decoded_json_output or\n        len(decoded_json_output['contracts']) == 0 or\n        all(len(file_results) == 0 for file_name, file_results in decoded_json_output['contracts'].items()) or\n        internal_compiler_error\n    ):\n        return FileReport(file_name=source_file_name, contract_reports=None)\n\n    file_report = FileReport(file_name=source_file_name, contract_reports=[])\n    for file_name, file_results in sorted(decoded_json_output['contracts'].items()):\n        for contract_name, contract_results in sorted(file_results.items()):\n            assert file_report.contract_reports is not None\n            file_report.contract_reports.append(ContractReport(\n                contract_name=contract_name,\n                file_name=Path(file_name),\n                bytecode=clean_string(contract_results.get('evm', {}).get('bytecode', {}).get('object')),\n                metadata=clean_string(contract_results.get('metadata')),\n            ))\n\n    return file_report\n\n\ndef parse_cli_output(source_file_name: Path, cli_output: str, exit_code: int) -> FileReport:\n    if exit_code != 0:\n        return FileReport(file_name=source_file_name, contract_reports=None)\n\n    # re.split() returns a list containing the text between pattern occurrences but also inserts the\n    # content of matched groups in between. It also never omits the empty elements so the number of\n    # list items is predictable (3 per match + the text before the first match)\n    output_segments = re.split(CONTRACT_SEPARATOR_PATTERN, cli_output)\n    assert len(output_segments) % 3 == 1\n\n    if len(output_segments) == 1:\n        return FileReport(file_name=source_file_name, contract_reports=None)\n\n    file_report = FileReport(file_name=source_file_name, contract_reports=[])\n    for file_name, contract_name, contract_output in zip(output_segments[1::3], output_segments[2::3], output_segments[3::3]):\n        bytecode_match = re.search(BYTECODE_REGEX, contract_output)\n        metadata_match = re.search(METADATA_REGEX, contract_output)\n\n        assert file_report.contract_reports is not None\n        file_report.contract_reports.append(ContractReport(\n            contract_name=contract_name.strip(),\n            file_name=Path(file_name.strip()) if file_name is not None else None,\n            bytecode=clean_string(bytecode_match['bytecode'] if bytecode_match is not None else None),\n            metadata=clean_string(metadata_match['metadata'] if metadata_match is not None else None),\n        ))\n\n    return file_report\n\n\ndef prepare_compiler_input(\n    compiler_path: Path,\n    execution_arch: ExecutionArchitecture,\n    source_file_name: Path,\n    force_no_optimize_yul: bool,\n    interface: CompilerInterface,\n    preset: SettingsPreset,\n    smt_use: SMTUse,\n    metadata_option_supported: bool,\n) -> Tuple[List[str], str]:\n\n    settings = CompilerSettings.from_preset(preset)\n\n    command_line = []\n    if execution_arch == ExecutionArchitecture.OSX_INTEL:\n        command_line = [\"/usr/bin/arch\", \"-64\", \"-x86_64\"]\n    else:\n        assert execution_arch == ExecutionArchitecture.NATIVE\n\n    if interface == CompilerInterface.STANDARD_JSON:\n        json_input: dict = {\n            'language': 'Solidity',\n            'sources': {\n                str(source_file_name): {'content': load_source(source_file_name, smt_use)}\n            },\n            'settings': {\n                'optimizer': {'enabled': settings.optimize},\n                # NOTE: We omit viaIR rather than set it to false to handle older versions that don't have it.\n                **({'viaIR': True} if settings.via_ir else {}),\n                'outputSelection': {'*': {'*': ['evm.bytecode.object', 'metadata']}},\n            }\n        }\n\n        if smt_use == SMTUse.DISABLE:\n            json_input['settings']['modelChecker'] = {'engine': 'none'}\n\n        command_line += [str(compiler_path), '--standard-json']\n        compiler_input = json.dumps(json_input)\n    else:\n        assert interface == CompilerInterface.CLI\n\n        compiler_options = [str(source_file_name), '--bin']\n        if metadata_option_supported:\n            compiler_options.append('--metadata')\n        if settings.optimize:\n            compiler_options.append('--optimize')\n        elif force_no_optimize_yul:\n            compiler_options.append('--no-optimize-yul')\n        if settings.via_ir:\n            compiler_options.append('--via-ir')\n        if smt_use == SMTUse.DISABLE:\n            compiler_options += ['--model-checker-engine', 'none']\n\n        command_line += [str(compiler_path)] + compiler_options\n        compiler_input = load_source(source_file_name, smt_use)\n\n    return (command_line, compiler_input)\n\n\ndef detect_metadata_cli_option_support(compiler_path: Path):\n    process = subprocess.run(\n        [str(compiler_path.absolute()), '--metadata', '-'],\n        input=\"contract C {}\",\n        encoding='utf8',\n        capture_output=True,\n        check=False,\n    )\n\n    negative_response = \"unrecognised option '--metadata'\".strip()\n    if (process.returncode == 0) != (process.stderr.strip() != negative_response):\n        # If the error is other than expected or there's an error message but no error, don't try\n        # to guess. Just fail.\n        print(\n            f\"Compiler exit code: {process.returncode}\\n\"\n            f\"Compiler output:\\n{process.stderr}\\n\",\n            file=sys.stderr\n        )\n        raise RuntimeError(\"Failed to determine if the compiler supports the --metadata option.\")\n\n    return process.returncode == 0\n\n\ndef run_compiler(\n    compiler_path: Path,\n    execution_arch: ExecutionArchitecture,\n    source_file_name: Path,\n    force_no_optimize_yul: bool,\n    interface: CompilerInterface,\n    preset: SettingsPreset,\n    smt_use: SMTUse,\n    metadata_option_supported: bool,\n    tmp_dir: Path,\n    exit_on_error: bool,\n) -> FileReport:\n    if interface == CompilerInterface.STANDARD_JSON:\n        (command_line, compiler_input) = prepare_compiler_input(\n            compiler_path,\n            execution_arch,\n            Path(source_file_name.name),\n            force_no_optimize_yul,\n            interface,\n            preset,\n            smt_use,\n            metadata_option_supported,\n        )\n\n        process = subprocess.run(\n            command_line,\n            input=compiler_input,\n            encoding='utf8',\n            capture_output=True,\n            check=True,\n        )\n\n        return parse_standard_json_output(Path(source_file_name), process.stdout)\n    else:\n        assert interface == CompilerInterface.CLI\n        assert tmp_dir is not None\n\n        (command_line, compiler_input) = prepare_compiler_input(\n            compiler_path.absolute(),\n            execution_arch,\n            Path(source_file_name.name),\n            force_no_optimize_yul,\n            interface,\n            preset,\n            smt_use,\n            metadata_option_supported,\n        )\n\n        # Create a copy that we can use directly with the CLI interface\n        modified_source_path = tmp_dir / source_file_name.name\n        # NOTE: newline='' disables newline conversion.\n        # We want the file exactly as is because changing even a single byte in the source affects metadata.\n        with open(modified_source_path, 'w', encoding='utf8', newline='') as modified_source_file:\n            modified_source_file.write(compiler_input)\n\n        process = subprocess.run(\n            command_line,\n            cwd=tmp_dir,\n            encoding='utf8',\n            capture_output=True,\n            check=exit_on_error,\n        )\n\n        return parse_cli_output(Path(source_file_name), process.stdout, process.returncode)\n\n\ndef generate_report(\n    source_file_names: List[str],\n    compiler_path: Path,\n    execution_arch: ExecutionArchitecture,\n    interface: CompilerInterface,\n    presets: List[SettingsPreset],\n    smt_use: SMTUse,\n    force_no_optimize_yul: bool,\n    report_file_path: Path,\n    verbose: bool,\n    exit_on_error: bool,\n):\n    statistics = Statistics()\n    metadata_option_supported = detect_metadata_cli_option_support(compiler_path)\n\n    try:\n        with open(report_file_path, mode='w', encoding='utf8', newline='\\n') as report_file:\n            for preset in presets:\n                with TemporaryDirectory(prefix='prepare_report-') as tmp_dir:\n                    for source_file_name in sorted(source_file_names):\n                        try:\n                            report = run_compiler(\n                                compiler_path,\n                                execution_arch,\n                                Path(source_file_name),\n                                force_no_optimize_yul,\n                                interface,\n                                preset,\n                                smt_use,\n                                metadata_option_supported,\n                                Path(tmp_dir),\n                                exit_on_error,\n                            )\n\n                            statistics.aggregate(report)\n                            print(report.format_summary(verbose), end=('\\n' if verbose else ''), flush=True)\n\n                            report_file.write(report.format_report())\n                        except subprocess.CalledProcessError as exception:\n                            print(\n                                f\"\\n\\nInterrupted by an exception while processing file \"\n                                f\"'{source_file_name}' with preset={preset}\\n\\n\"\n                                f\"COMPILER STDOUT:\\n{exception.stdout}\\n\"\n                                f\"COMPILER STDERR:\\n{exception.stderr}\\n\",\n                                file=sys.stderr\n                            )\n                            raise\n                        except:\n                            print(\n                                f\"\\n\\nInterrupted by an exception while processing file \"\n                                f\"'{source_file_name}' with preset={preset}\\n\\n\",\n                                file=sys.stderr\n                            )\n                            raise\n    finally:\n        print('\\n', statistics, '\\n', sep='')\n\n\ndef commandline_parser() -> ArgumentParser:\n    script_description = (\n        \"Generates a report listing bytecode and metadata obtained by compiling all the \"\n        \"*.sol files found in the current working directory using the provided binary.\"\n    )\n\n    parser = ArgumentParser(description=script_description)\n    parser.add_argument(dest='compiler_path', help=\"Solidity compiler executable\")\n    parser.add_argument(\n        '--interface',\n        dest='interface',\n        default=CompilerInterface.STANDARD_JSON.value,\n        choices=[c.value for c in CompilerInterface],\n        help=\"Compiler interface to use.\",\n    )\n    parser.add_argument(\n        '--execution-arch',\n        dest='execution_arch',\n        default=ExecutionArchitecture.NATIVE.value,\n        choices=[c.value for c in ExecutionArchitecture],\n        help=\"Select the architecture of the universal binary that should be executed. (Only relevant for macOS)\",\n    )\n    parser.add_argument(\n        '--preset',\n        dest='presets',\n        default=None,\n        nargs='+',\n        action='append',\n        choices=[p.value for p in SettingsPreset],\n        help=\"Predefined set of settings to pass to the compiler. More than one can be selected.\",\n    )\n    parser.add_argument(\n        '--smt-use',\n        dest='smt_use',\n        default=SMTUse.DISABLE.value,\n        choices=[s.value for s in SMTUse],\n        help=\"What to do about contracts that use the experimental SMT checker.\"\n    )\n    parser.add_argument(\n        '--force-no-optimize-yul',\n        dest='force_no_optimize_yul',\n        default=False,\n        action='store_true',\n        help=\"Explicitly disable Yul optimizer in CLI runs without optimization to work around a bug in solc 0.6.0 and 0.6.1.\"\n    )\n    parser.add_argument('--report-file', dest='report_file', default='report.txt', help=\"The file to write the report to.\")\n    parser.add_argument('--verbose', dest='verbose', default=False, action='store_true', help=\"More verbose output.\")\n    parser.add_argument(\n        '--exit-on-error',\n        dest='exit_on_error',\n        default=False,\n        action='store_true',\n        help=\"Immediately exit and print compiler output if the compiler exits with an error.\",\n    )\n    return parser\n\n\nif __name__ == \"__main__\":\n    options = commandline_parser().parse_args()\n\n    if options.presets is None:\n        # NOTE: Can't put it in add_argument()'s default because then it would be always present.\n        # See https://github.com/python/cpython/issues/60603\n        presets = [[SettingsPreset.LEGACY_NO_OPTIMIZE.value, SettingsPreset.LEGACY_OPTIMIZE.value]]\n    else:\n        presets = options.presets\n\n    generate_report(\n        glob(\"*.sol\"),\n        Path(options.compiler_path),\n        ExecutionArchitecture(options.execution_arch),\n        CompilerInterface(options.interface),\n        [SettingsPreset(p) for preset_group in presets for p in preset_group],\n        SMTUse(options.smt_use),\n        options.force_no_optimize_yul,\n        Path(options.report_file),\n        options.verbose,\n        options.exit_on_error,\n    )\n"
  },
  {
    "path": "scripts/check_style.sh",
    "content": "#!/usr/bin/env bash\n\nset -eu\n\nERROR_LOG=\"$(mktemp -t check_style_XXXXXX.log)\"\n\nEXCLUDE_FILES=(\n    # The line below is left unquoted to allow the shell globbing path expansion\n    deps/*\n    test/cmdlineTests/*/{err,output}\n    \"libsolutil/picosha2.h\"\n    \"test/cmdlineTests/strict_asm_only_cr/input.yul\"\n    \"test/libsolutil/UTF8.cpp\"\n    \"test/libsolidity/syntaxTests/license/license_cr_endings.sol\"\n    \"test/libsolidity/syntaxTests/license/license_crlf_endings.sol\"\n    \"test/libsolidity/syntaxTests/license/license_whitespace_trailing.sol\"\n    \"test/scripts/fixtures/smt_contract_with_crlf_newlines.sol\"\n    \"test/scripts/fixtures/smt_contract_with_cr_newlines.sol\"\n    \"test/scripts/fixtures/smt_contract_with_mixed_newlines.sol\"\n)\nEXCLUDE_FILES_JOINED=$(printf \"%s\\|\" \"${EXCLUDE_FILES[@]}\")\nEXCLUDE_FILES_JOINED=${EXCLUDE_FILES_JOINED%??}\n\n(\nREPO_ROOT=\"$(dirname \"$0\")\"/..\ncd \"$REPO_ROOT\" || exit 1\n\nWHITESPACE=$(git grep -n -I -E \"^.*[[:space:]]+$\" |\n    grep -v \"test/libsolidity/ASTJSON\\|test/compilationTests/zeppelin/LICENSE\\|${EXCLUDE_FILES_JOINED}\" || true\n)\n\nif [[ \"$WHITESPACE\" != \"\" ]]\nthen\n    echo \"Error: Trailing whitespace found:\" | tee -a \"$ERROR_LOG\"\n    echo \"$WHITESPACE\" | tee -a \"$ERROR_LOG\"\n    scripts/ci/post_style_errors_on_github.sh \"$ERROR_LOG\"\n    exit 1\nfi\n\nfunction preparedGrep\n{\n    git grep -nIE \"$1\" -- '*.h' '*.cpp' | grep -v \"${EXCLUDE_FILES_JOINED}\"\n    return $?\n}\n\nFORMATERROR=$(\n(\n    preparedGrep \"#include \\\"\" | grep -E -v -e \"license.h\" -e \"BuildInfo.h\"  # Use include with <> characters\n    preparedGrep \"\\<(if|for|while|switch)\\(\" # no space after \"if\", \"for\", \"while\" or \"switch\"\n    preparedGrep \"\\<for\\>[[:space:]]*\\([^=]*\\>[[:space:]]:[[:space:]].*\\)\" # no space before range based for-loop\n    preparedGrep \"\\<if\\>[[:space:]]*\\(.*\\)[[:space:]]*\\{[[:space:]]*$\" # \"{\\n\" on same line as \"if\"\n    preparedGrep \"namespace .*\\{\"\n    preparedGrep \"[,\\(<][[:space:]]*const \" # const on left side of type\n    preparedGrep \"^[[:space:]]*(static)?[[:space:]]*const \" # const on left side of type (beginning of line)\n    preparedGrep \"^ [^*]|[^*] \t|\t [^*]\" # uses spaces for indentation or mixes spaces and tabs\n    preparedGrep \"[a-zA-Z0-9_][[:space:]]*[&][a-zA-Z_]\" | grep -E -v \"return [&]\" # right-aligned reference ampersand (needs to exclude return)\n    # right-aligned reference pointer star (needs to exclude return and comments)\n    preparedGrep \"[a-zA-Z0-9_][[:space:]]*[*][a-zA-Z_]\" | grep -E -v -e \"return [*]\" -e \":[0-9]+:[[:space:]]*\\*[[:space:]]\" -e \"//\"\n    # unqualified move()/forward() checks, i.e. make sure that std::move() and std::forward() are used instead of move() and forward()\n    preparedGrep \"move\\(.+\\)\" | grep -v \"std::move\" | grep -E \"[^a-z]move\"\n    preparedGrep \"forward\\(.+\\)\" | grep -v \"std::forward\" | grep -E \"[^a-z]forward\"\n) | grep -E -v -e \"^[a-zA-Z./]*:[0-9]*:[[:space:]]*/[/*]\" -e \"^test/\" || true\n)\n\n# Special error handling for `using namespace std;` exclusion, since said statement can be present in the test directory\n# and its subdirectories, but is excluded in the above ruleset. In order to have consistent codestyle with regards to\n# std namespace usage, test directory must also be covered.\nFORMATSTDERROR=$(\n(\n    git grep -nIE \"using namespace std;\" -- '*.h' '*.cpp'\n) || true\n)\n\n# Merge errors into single string\nFORMATEDERRORS=\"$FORMATERROR$FORMATSTDERROR\"\n\nif [[ \"$FORMATEDERRORS\" != \"\" ]]\nthen\n    echo \"Coding style error:\" | tee -a \"$ERROR_LOG\"\n    echo \"$FORMATEDERRORS\" | tee -a \"$ERROR_LOG\"\n    scripts/ci/post_style_errors_on_github.sh \"$ERROR_LOG\"\n    exit 1\nfi\n)\n"
  },
  {
    "path": "scripts/check_symlinks.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nREPO_ROOT=\"$(dirname \"$0\")\"/..\nREPO_ROOT=$(realpath \"${REPO_ROOT}\")\n\nBROKEN_LINKS=$(find -L \"${REPO_ROOT}\" -type l -ls)\nif [ -z \"${BROKEN_LINKS}\" ]\nthen\n  exit 0\nelse\n  echo \"broken symbolic link(s) found:\"\n  echo \"${BROKEN_LINKS}\"\n\n  exit 1\nfi\n"
  },
  {
    "path": "scripts/chk_shellscripts/chk_shellscripts.sh",
    "content": "#!/usr/bin/env bash\n\nset -eu\n\nREPO_ROOT=\"$(dirname \"$0\")\"/../..\nREPO_ROOT=$(realpath \"${REPO_ROOT}\")\n\ncd \"${REPO_ROOT}\"\n\nSHELLCHECK=${SHELLCHECK:-\"$(command -v -- shellcheck)\"}\nif [ ! -f \"${SHELLCHECK}\" ]; then\n    echo \"error: shellcheck '${SHELLCHECK}' not found.\"\n    exit 1\nfi\n\nmapfile -t FILES < <(find . -type f -name \"*.sh\" -not -path \"./deps/*\")\n\"${SHELLCHECK}\" \"${FILES[@]}\"\n"
  },
  {
    "path": "scripts/ci/base64DecToArr.js",
    "content": "function base64DecToArr (sBase64) {\n/*\\\n|*|\n|*|  Base64 / binary data / UTF-8 strings utilities\n|*|\n|*|  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding\n|*|\n\\*/\n\n/* Array of bytes to Base64 string decoding */\n\nfunction b64ToUint6 (nChr) {\n\n  return nChr > 64 && nChr < 91 ?\n      nChr - 65\n    : nChr > 96 && nChr < 123 ?\n      nChr - 71\n    : nChr > 47 && nChr < 58 ?\n      nChr + 4\n    : nChr === 43 ?\n      62\n    : nChr === 47 ?\n      63\n    :\n      0;\n\n}\n\n  var\n    nInLen = sBase64.length,\n    nOutLen = nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen);\n\n  for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {\n    nMod4 = nInIdx & 3;\n    nUint24 |= b64ToUint6(sBase64.charCodeAt(nInIdx)) << 6 * (3 - nMod4);\n    if (nMod4 === 3 || nInLen - nInIdx === 1) {\n      for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {\n        taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;\n      }\n      nUint24 = 0;\n\n    }\n  }\n\n  return taBytes;\n}\n"
  },
  {
    "path": "scripts/ci/build.sh",
    "content": "#!/usr/bin/env bash\nset -ex\n\nROOTDIR=\"$(realpath \"$(dirname \"$0\")/../..\")\"\n# shellcheck source=scripts/common.sh\nsource \"${ROOTDIR}/scripts/common.sh\"\n\nprerelease_source=\"${1:-ci}\"\n\ncd \"${ROOTDIR}\"\n\n\"${ROOTDIR}/scripts/prerelease_suffix.sh\" \"$prerelease_source\" \"$CIRCLE_TAG\" > prerelease.txt\n\nmkdir -p build\ncd build\n\n[[ -n $COVERAGE && -z $CIRCLE_TAG ]] && CMAKE_OPTIONS=\"$CMAKE_OPTIONS -DCOVERAGE=ON\"\n\nexport CCACHE_DIR=\"$HOME/.ccache\"\nexport CCACHE_BASEDIR=\"$ROOTDIR\"\nexport CCACHE_NOHASHDIR=1\nCMAKE_OPTIONS=\"${CMAKE_OPTIONS:-} -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache\"\nmkdir -p \"$CCACHE_DIR\"\n\n# shellcheck disable=SC2086\ncmake .. -DCMAKE_BUILD_TYPE=\"${CMAKE_BUILD_TYPE:-Release}\" $CMAKE_OPTIONS\n\nccache -z\n\ncmake --build .\n\nccache -s\n"
  },
  {
    "path": "scripts/ci/build_emscripten.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# This script builds the solidity binary using Emscripten.\n# Emscripten is a way to compile C/C++ to JavaScript.\n#\n# http://kripken.github.io/emscripten-site/\n#\n# First run install_dep.sh OUTSIDE of docker and then\n# run this script inside a docker image trzeci/emscripten\n#\n# The documentation for solidity is hosted at:\n#\n# https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -ev\n\nSCRIPT_DIR=\"$(realpath \"$(dirname \"$0\")/..\")\"\n# shellcheck source=scripts/common.sh\nsource \"${SCRIPT_DIR}/common.sh\"\nROOT_DIR=\"${SCRIPT_DIR}/..\"\n\nfunction build() {\n    local build_dir=\"$1\"\n    local prerelease_source=\"${2:-ci}\"\n\n    cd \"${ROOT_DIR}\"\n\n    \"${SCRIPT_DIR}/prerelease_suffix.sh\" \"$prerelease_source\" \"$(git tag --points-at HEAD 2> /dev/null)\" > prerelease.txt\n\n    # Disable warnings for unqualified `move()` calls, introduced and enabled by\n    # default in clang-16 which is what the emscripten docker image uses.\n    # Additionally, disable the warning for unknown warnings here, as this script is\n    # also used with earlier clang versions.\n    # TODO: This can be removed if and when all usages of `move()` in our codebase use the `std::` qualifier.\n    CMAKE_CXX_FLAGS=\"-Wno-unqualified-std-cast-call\"\n\n    export CCACHE_DIR=\"$HOME/.ccache\"\n    CCACHE_BASEDIR=\"$(pwd)\"\n    export CCACHE_BASEDIR\n    export CCACHE_NOHASHDIR=1\n    mkdir -p \"$CCACHE_DIR\"\n    ccache -z\n\n    mkdir -p \"$build_dir\"\n    cd \"$build_dir\"\n    emcmake cmake \\\n        -DCMAKE_BUILD_TYPE=Release \\\n        -DBoost_USE_STATIC_LIBS=1 \\\n        -DBoost_USE_STATIC_RUNTIME=1 \\\n        -DCMAKE_CXX_FLAGS=\"${CMAKE_CXX_FLAGS}\" \\\n        -DTESTS=0 \\\n    ..\n    make soljson\n    ccache -s\n\n    cd ..\n    mkdir -p upload\n    scripts/ci/pack_soljson.sh \"$build_dir/libsolc/soljson.js\" \"$build_dir/libsolc/soljson.wasm\" upload/soljson.js\n    cp upload/soljson.js ./\n\n    OUTPUT_SIZE=$(ls -la soljson.js)\n\n    echo \"Emscripten output size: $OUTPUT_SIZE\"\n}\n\nfunction show_help() {\ncat << EOF\nUsage: ${0##*/} [-h|--help] [--build-dir DIR] [--prerelease-source prerelease_source]\nBuild Solidity emscripten binary\n    -h | --help          Display this help message\n    --build-dir          The emscripten build directory\n    --prerelease-source  The prerelease source string. E.g. 'nightly' or 'ci'.\nEOF\n}\n\nfunction main() {\n    local build_dir=\"emscripten_build\"\n    local prerelease_source=\"\"\n\n    while (( $# > 0 )); do\n        case \"$1\" in\n            -h|--help)\n                show_help\n                exit 0\n                ;;\n            --build-dir)\n                [[ -n \"$2\" ]] || fail \"Option --build-dir cannot be empty\"\n                build_dir=\"$2\"\n                shift 2\n                ;;\n            --prerelease-source)\n                [[ -n \"$2\" ]] || fail \"Option --prerelease-source cannot be empty\"\n                prerelease_source=\"$2\"\n                shift 2\n                ;;\n            *) fail \"Invalid option: $1\" ;;\n        esac\n    done\n    build \"$build_dir\" \"$prerelease_source\"\n}\n\nmain \"$@\"\n"
  },
  {
    "path": "scripts/ci/build_ossfuzz.sh",
    "content": "#!/usr/bin/env bash\nset -ex\n\nROOTDIR=\"$(realpath \"$(dirname \"$0\")/../..\")\"\nBUILDDIR=\"${ROOTDIR}/build\"\nmkdir -p \"${BUILDDIR}\" && mkdir -p \"$BUILDDIR/deps\"\n\nfunction generate_protobuf_bindings\n{\n  cd \"${ROOTDIR}\"/test/tools/ossfuzz\n  # Generate protobuf C++ bindings\n  for protoName in yul abiV2 sol;\n  do\n    protoc \"${protoName}\"Proto.proto --cpp_out .\n  done\n}\n\nfunction build_fuzzers\n{\n  cd \"${BUILDDIR}\"\n  export CCACHE_DIR=\"$HOME/.ccache\"\n  export CCACHE_BASEDIR=\"$ROOTDIR\"\n  export CCACHE_NOHASHDIR=1\n  CMAKE_OPTIONS=\"${CMAKE_OPTIONS:-} -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache\"\n  mkdir -p \"$CCACHE_DIR\"\n  # shellcheck disable=SC2086\n  cmake .. -DCMAKE_BUILD_TYPE=\"${CMAKE_BUILD_TYPE:-Release}\" \\\n    -DCMAKE_TOOLCHAIN_FILE=\"${ROOTDIR}\"/cmake/toolchains/libfuzzer.cmake \\\n    $CMAKE_OPTIONS\n  ccache -z\n  make ossfuzz ossfuzz_proto ossfuzz_abiv2 -j 4\n  ccache -s\n}\n\ngenerate_protobuf_bindings\nbuild_fuzzers\n"
  },
  {
    "path": "scripts/ci/build_win.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n(( $# <= 1 )) || { >&2 echo \"Usage: $0 [PRERELEASE_SOURCE]\"; exit 1; }\nprerelease_source=\"${1:-ci}\"\nROOTDIR=\"$(realpath \"$(dirname \"$0\")/../../\")\"\nFORCE_RELEASE=\"${FORCE_RELEASE:-}\"\nCIRCLE_TAG=\"${CIRCLE_TAG:-}\"\nCMAKE_VS_GLOBALS_ARG=()\n\ncd \"$ROOTDIR\"\n\"${ROOTDIR}/scripts/prerelease_suffix.sh\" \"$prerelease_source\" \"$CIRCLE_TAG\" > prerelease.txt\n\nexport CCACHE_DIR=\"$HOME/.ccache\"\nexport CCACHE_BASEDIR=\"$ROOTDIR\"\nexport CCACHE_NOHASHDIR=1\nexport CCACHE_COMPILERTYPE=msvc\nVSWHERE=\"${VSWHERE:-C:/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe}\"\nVS_INSTALL=\"$(\"$VSWHERE\" -latest -products \"*\" \\\n  -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 \\\n  -property installationPath | tr -d '\\r')\"\nVCTOOLS_VERSION=\"$(tr -d '\\r' < \"$VS_INSTALL/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt\")\"\nCCACHE_COMPILER=\"$VS_INSTALL/VC/Tools/MSVC/$VCTOOLS_VERSION/bin/Hostx64/x64/cl.exe\"\nCCACHE_COMPILER=\"${CCACHE_COMPILER//\\\\//}\"\nexport CCACHE_COMPILER\nPATH=\"$ROOTDIR/deps/ccache:$(dirname \"$CCACHE_COMPILER\"):$PATH\"\nexport PATH\n# Use a Windows-style path for Visual Studio globals.\nWIN_PWD=\"$(pwd -W)\"\n# Visual Studio generator doesn't use compiler launchers; use ccache masquerade.\n# See https://github.com/ccache/ccache/wiki/MS-Visual-Studio\nCMAKE_VS_GLOBALS=\"CLToolPath=${WIN_PWD}/deps/ccache;UseMultiToolTask=true\"\nCMAKE_VS_GLOBALS_ARG=(-DCMAKE_VS_GLOBALS=\"$CMAKE_VS_GLOBALS\")\nmkdir -p \"$CCACHE_DIR\"\n\nmkdir -p build/\ncd build/\n\n# NOTE: Using an array to force Bash to do wildcard expansion\nboost_dir=(\"${ROOTDIR}/deps/boost/lib/cmake/Boost-\"*)\n\n # shellcheck disable=SC2086\n \"${ROOTDIR}/deps/cmake/bin/cmake\" \\\n    -G \"Visual Studio 16 2019\" \\\n    -DBoost_DIR=\"${boost_dir[*]}\" \\\n    -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded \\\n    -DCMAKE_INSTALL_PREFIX=\"${ROOTDIR}/uploads/\" \\\n    \"${CMAKE_VS_GLOBALS_ARG[@]}\" \\\n    ${CMAKE_OPTIONS:-} \\\n    ..\nccache -z\nMSBuild.exe solidity.sln \\\n    -property:Configuration=Release \\\n    -maxCpuCount:10 \\\n    -verbosity:minimal\n\"${ROOTDIR}/deps/cmake/bin/cmake\" \\\n    --build . \\\n    -j 10 \\\n    --target install \\\n    --config Release\nccache -s\n"
  },
  {
    "path": "scripts/ci/docker_upgrade.sh",
    "content": "#!/usr/bin/env bash\nset -e\n\nfunction error\n{\n  echo >&2 \"ERROR: ${1} Aborting.\" && false\n}\n\nfunction warning\n{\n  echo >&2 \"WARNING: ${1}\"\n}\n\n[[ $# == 3 ]] || error \"Expected exactly 3 parameters: '${0} <IMAGE_NAME> <IMAGE_VARIANT> <DOCKER_REPOSITORY>'.\"\n\nIMAGE_NAME=\"${1}\"\nIMAGE_VARIANT=\"${2}\"\nDOCKER_REPOSITORY=\"${3}\"\nDOCKERFILE=\"scripts/docker/${IMAGE_NAME}/Dockerfile.${IMAGE_VARIANT}\"\n\necho \"-- check_dockerfile_was_changed\"\n\n# exit, if the dockerfile was not changed.\nif git diff --quiet origin/develop HEAD -- \"${DOCKERFILE}\"; then\n  echo \"${DOCKERFILE} was not changed. Nothing to do.\"\n  exit 0\nfi\n\necho \"-- check_version\"\n\nPREV_VERSION=$(git diff origin/develop HEAD -- \"${DOCKERFILE}\" | grep -e '^\\s*-LABEL\\s\\+version=\".*\"\\s*$' | awk -F'\"' '{ print $2 }')\nNEXT_VERSION=$(git diff origin/develop HEAD -- \"${DOCKERFILE}\" | grep -e '^\\s*+LABEL\\s\\+version=\".*\"\\s*$' | awk -F'\"' '{ print $2 }')\n\n[[ $NEXT_VERSION != \"\" ]] || error \"No version label defined in Dockerfile. You may need to add 'LABEL version' in '${DOCKERFILE}'.\"\n\n[[ $PREV_VERSION != \"\" ]] || {\n  warning \"no previous version found. Will set \\$PREV_VERSION = 0.\"\n  PREV_VERSION=0\n}\n\nif [[ $((PREV_VERSION + 1)) != $((NEXT_VERSION)) ]]; then\n  error \"Version label in Dockerfile was not incremented. You may need to change 'LABEL version' in '${DOCKERFILE}'.\"\nfi\n\necho \"-- build_docker\"\n\n# This is a workaround: we run `docker build` twice to prevent the `layer does not exist` problem.\n# See https://github.com/moby/moby/issues/37965.\ndocker build \"scripts/docker/${IMAGE_NAME}\" --file \"scripts/docker/${IMAGE_NAME}/Dockerfile.${IMAGE_VARIANT}\" --tag \"${IMAGE_NAME}\" ||\n  docker build \"scripts/docker/${IMAGE_NAME}\" --file \"scripts/docker/${IMAGE_NAME}/Dockerfile.${IMAGE_VARIANT}\" --tag \"${IMAGE_NAME}\"\n\necho \"-- test_docker @ '${PWD}'\"\n\ndocker run \\\n  --rm \\\n  --volume \"${PWD}:/project\" \\\n  -u \"$(id -u \"${USER}\"):$(id -g \"${USER}\")\" \\\n  -e CCACHE_DIR=/tmp/ccache \\\n  \"${IMAGE_NAME}\" \\\n  bash -c \"/project/scripts/ci/${IMAGE_NAME}_test_${IMAGE_VARIANT}.sh\"\n\necho \"-- push_docker\"\n\nVERSION=$(docker inspect --format='{{.Config.Labels.version}}' \"${IMAGE_NAME}\")\nDOCKER_IMAGE_ID=\"${DOCKER_REPOSITORY}:${IMAGE_VARIANT}\"\n\ndocker tag \"${IMAGE_NAME}\" \"${DOCKER_IMAGE_ID}-${VERSION}\"\ndocker push \"${DOCKER_IMAGE_ID}-${VERSION}\"\n\nREPO_DIGEST=$(docker inspect --format='{{.RepoDigests}}' \"${DOCKER_IMAGE_ID}-${VERSION}\")\n\necho \"DOCKER_IMAGE=${DOCKER_IMAGE_ID}-${VERSION}\" >> \"$GITHUB_ENV\"\necho \"DOCKER_REPO_DIGEST=${REPO_DIGEST}\" >> \"$GITHUB_ENV\"\n"
  },
  {
    "path": "scripts/ci/install_and_check_minimum_requirements.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# These versions must be kept in sync with the docs in `docs/installing-solidity.rst#building-from-source`.\n\n# minimum boost version\nBOOST_VERSION=1.83\n\n# minimum cmake version\nCMAKE_MAJOR=3\nCMAKE_MINOR=13\nCMAKE_PATCH=0\nCMAKE_FULL_VERSION=\"${CMAKE_MAJOR}.${CMAKE_MINOR}.${CMAKE_PATCH}\"\n\n# minimum gcc/clang versions\nGCC_VERSION=13.3.0\nCLANG_VERSION=18.1.3\n\n# which compiler version to check in this script\ncheck_gcc=false\ncheck_clang=false\n\nwhile (( $# > 0 )); do\n    case \"$1\" in\n        --gcc)\n            check_gcc=true\n            shift\n            ;;\n        --clang)\n            check_clang=true\n            shift\n            ;;\n        *)\n            echo \"Unknown option: $1\"\n            echo \"Usage: $0 [--gcc] [--clang]\"\n            exit 1\n            ;;\n    esac\ndone\n\necho \"-- Removing boost and CMake from the system\"\nsudo apt-get --quiet=2 remove --purge 'libboost*'\nsudo apt-get --quiet=2 remove --purge cmake\n\necho \"-- Installing Boost ${BOOST_VERSION}\"\nsudo apt-get --quiet=2 update\nsudo apt-get --quiet=2 install libboost${BOOST_VERSION}-all-dev\ninstalled_boost_version=$(dpkg-query --showformat='${Version}' --show libboost${BOOST_VERSION}-all-dev 2>/dev/null || echo \"none\")\nif [[ $installed_boost_version != ${BOOST_VERSION}* ]]; then\n    echo \"Error: installed version of boost is $installed_boost_version, expected $BOOST_VERSION\"\n    exit 1\nfi\n\necho \"-- Installing CMake ${CMAKE_FULL_VERSION}\"\nwget \"https://cmake.org/files/v${CMAKE_MAJOR}.${CMAKE_MINOR}/cmake-${CMAKE_FULL_VERSION}-Linux-x86_64.tar.gz\"\ntar --extract --gzip --file \"cmake-${CMAKE_FULL_VERSION}-Linux-x86_64.tar.gz\"\nsudo mv \"cmake-${CMAKE_FULL_VERSION}-Linux-x86_64\" \"/opt/cmake-${CMAKE_FULL_VERSION}\"\nsudo ln --symbolic \"/opt/cmake-${CMAKE_FULL_VERSION}/bin/\"* /usr/local/bin/\necho \"-- Installed $(cmake --version)\"\n\nif [[ \"$check_gcc\" == true ]]; then\n    installed_gcc_version=$(gcc -dumpfullversion -dumpversion || echo \"none\")\n    if [[ \"$installed_gcc_version\" != \"$GCC_VERSION\" ]]; then\n        echo \"Error: installed version of gcc is $installed_gcc_version, expected $GCC_VERSION\"\n        exit 1\n    fi\n    echo \"-- gcc version check passed: $installed_gcc_version\"\nfi\n\nif [[ \"$check_clang\" == true ]]; then\n    installed_clang_version=$(clang -dumpfullversion -dumpversion || echo \"none\")\n    if [[ \"$installed_clang_version\" != \"$CLANG_VERSION\" ]]; then\n        echo \"Error: installed version of clang is $installed_clang_version, expected $CLANG_VERSION\"\n        exit 1\n    fi\n    echo \"-- clang version check passed: $installed_clang_version\"\nfi\n"
  },
  {
    "path": "scripts/ci/mini-lz4.js",
    "content": "function uncompress(source, uncompressedSize) {\n/*\nbased off https://github.com/emscripten-core/emscripten/blob/main/third_party/mini-lz4.js\nThe license only applies to the body of this function (``uncompress``).\n====\nMiniLZ4: Minimal LZ4 block decoding and encoding.\n\nbased off of node-lz4, https://github.com/pierrec/node-lz4\n\n====\nCopyright (c) 2012 Pierre Curto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n====\n\nchanges have the same license\n*/\n/**\n * Decode a block. Assumptions: input contains all sequences of a\n * chunk, output is large enough to receive the decoded data.\n * If the output buffer is too small, an error will be thrown.\n * If the returned value is negative, an error occurred at the returned offset.\n *\n * @param {ArrayBufferView} input input data\n * @param {ArrayBufferView} output output data\n * @param {number=} sIdx\n * @param {number=} eIdx\n * @return {number} number of decoded bytes\n * @private\n */\nfunction uncompressBlock (input, output, sIdx, eIdx) {\n\tsIdx = sIdx || 0\n\teIdx = eIdx || (input.length - sIdx)\n\t// Process each sequence in the incoming data\n\tfor (var i = sIdx, n = eIdx, j = 0; i < n;) {\n\t\tvar token = input[i++]\n\n\t\t// Literals\n\t\tvar literals_length = (token >> 4)\n\t\tif (literals_length > 0) {\n\t\t\t// length of literals\n\t\t\tvar l = literals_length + 240\n\t\t\twhile (l === 255) {\n\t\t\t\tl = input[i++]\n\t\t\t\tliterals_length += l\n\t\t\t}\n\n\t\t\t// Copy the literals\n\t\t\tvar end = i + literals_length\n\t\t\twhile (i < end) output[j++] = input[i++]\n\n\t\t\t// End of buffer?\n\t\t\tif (i === n) return j\n\t\t}\n\n\t\t// Match copy\n\t\t// 2 bytes offset (little endian)\n\t\tvar offset = input[i++] | (input[i++] << 8)\n\n\t\t// XXX 0 is an invalid offset value\n\t\tif (offset === 0) return j\n\t\tif (offset > j) return -(i-2)\n\n\t\t// length of match copy\n\t\tvar match_length = (token & 0xf)\n\t\tvar l = match_length + 240\n\t\twhile (l === 255) {\n\t\t\tl = input[i++]\n\t\t\tmatch_length += l\n\t\t}\n\t\t// Copy the match\n\t\tvar pos = j - offset // position of the match copy in the current output\n\t\tvar end = j + match_length + 4 // minmatch = 4\n\t\twhile (j < end) output[j++] = output[pos++]\n\t}\n\n\treturn j\n}\nvar result = new ArrayBuffer(uncompressedSize);\nvar sourceIndex = 0;\nvar destIndex = 0;\nvar blockSize;\nwhile((blockSize = (source[sourceIndex] | (source[sourceIndex + 1] << 8) | (source[sourceIndex + 2] << 16) | (source[sourceIndex + 3] << 24))) > 0)\n{\n\tsourceIndex += 4;\n\tif (blockSize & 0x80000000)\n\t{\n\t\tblockSize &= 0x7FFFFFFFF;\n\t\tfor (var i = 0; i < blockSize; i++) {\n\t\t\tresult[destIndex++] = source[sourceIndex++];\n\t\t}\n\t}\n\telse\n\t{\n\t\tdestIndex += uncompressBlock(source, new Uint8Array(result, destIndex, uncompressedSize - destIndex), sourceIndex, sourceIndex + blockSize);\n\t\tsourceIndex += blockSize;\n\t}\n}\nreturn new Uint8Array(result, 0, uncompressedSize);\n}\n"
  },
  {
    "path": "scripts/ci/notification/matrix_notification.sh",
    "content": "#!/bin/bash\n\nset -euo pipefail\n\nSCRIPT_DIR=\"$(dirname \"$0\")\"\n\nfunction fail() {\n    printf '%s\\n' \"$1\" >&2\n    exit 1\n}\n\nfunction notify() {\n    [[ -z \"$1\" ]] && fail \"Event type not provided.\"\n    [[ \"$1\" != \"failure\" && \"$1\" != \"success\" && \"$1\" != \"release\" ]] && fail \"Wrong event type.\"\n    local event=\"$1\"\n    local formatted_message\n\n    # FIXME: Checking $CIRCLE_PULL_REQUEST would be better than hard-coding branch names\n    # but it's broken. CircleCI associates runs on develop/breaking with random old PRs.\n    [[ \"$BRANCH\" == \"develop\" || \"$BRANCH\" == \"breaking\" ]] || { echo \"Running on a PR or a feature branch - notification skipped.\"; exit 0; }\n\n    # The release notification only makes sense on tagged commits. If the commit is untagged, just bail out.\n    [[ \"$event\" == \"release\" ]] && { [[ $TAG != \"\" ]] || { echo \"Not a tagged commit - notification skipped.\"; exit 0; } }\n\n    formatted_message=\"$(format_predefined_message \"$event\")\"\n\n    curl \"https://${MATRIX_SERVER}/_matrix/client/v3/rooms/${MATRIX_NOTIFY_ROOM_ID}/send/m.room.message\" \\\n        --request POST \\\n        --include \\\n        --fail \\\n        --header \"Content-Type: application/json\" \\\n        --header \"Accept: application/json\" \\\n        --header \"Authorization: Bearer ${MATRIX_ACCESS_TOKEN}\" \\\n        --data \"$formatted_message\"\n}\n\nfunction circleci_workflow_name() {\n    # Workflow name is not exposed as an env variable. Has to be queried from the API.\n    # The name is not critical so if anything fails, use the raw workflow ID as a fallback.\n    local workflow_info\n    workflow_info=$(curl --silent \"https://circleci.com/api/v2/workflow/${CIRCLE_WORKFLOW_ID}\") || true\n    echo \"$workflow_info\" | grep -E '\"\\s*name\"\\s*:\\s*\".*\"' | cut -d \\\" -f 4 || echo \"$CIRCLE_WORKFLOW_ID\"\n}\n\nfunction circleci_job_name() {\n    (( CIRCLE_NODE_TOTAL == 1 )) && echo \"${CIRCLE_JOB}\" && return\n    (( CIRCLE_NODE_TOTAL != 1 )) && echo \"${CIRCLE_JOB} (run $((CIRCLE_NODE_INDEX + 1))/${CIRCLE_NODE_TOTAL})\"\n}\n\n# Currently matrix only supports html formatted body,\n# see: https://spec.matrix.org/v1.6/client-server-api/#mtext\n#\n# Eventually, the matrix api will have support for better format options and `formatted_body` may not be necessary anymore:\n# https://github.com/matrix-org/matrix-spec-proposals/pull/1767\nfunction format_predefined_message() {\n    [[ -z \"$1\" ]] && fail \"Event type not provided.\"\n    local event=\"$1\"\n    local template\n\n    [[ \"$event\" == \"failure\" ]] && template=\"${SCRIPT_DIR}/templates/build_fail.json\"\n    [[ \"$event\" == \"success\" ]] && template=\"${SCRIPT_DIR}/templates/build_success.json\"\n    [[ \"$event\" == \"release\" ]] && template=\"${SCRIPT_DIR}/templates/build_release.json\"\n\n    [[ -z \"$template\" ]] && fail \"Message template for event [$event] not defined.\"\n\n    # shellcheck disable=SC2016\n    sed -e 's|${WORKFLOW_NAME}|'\"${WORKFLOW_NAME}\"'|' \\\n        -e 's|${JOB}|'\"${JOB}\"'|' \\\n        -e 's|${BRANCH}|'\"${BRANCH}\"'|' \\\n        -e 's|${TAG}|'\"${TAG}\"'|' \\\n        -e 's|${BUILD_URL}|'\"${BUILD_URL}\"'|' \\\n        -e 's|${BUILD_NUM}|'\"${BUILD_NUM}\"'|' \\\n        \"$template\"\n}\n\n# Set message environment variables based on CI backend\nif [[ \"$CIRCLECI\" = true ]] ; then\n    BRANCH=\"$CIRCLE_BRANCH\"\n    TAG=\"${CIRCLE_TAG:-}\"\n    BUILD_URL=\"$CIRCLE_BUILD_URL\"\n    BUILD_NUM=\"$CIRCLE_BUILD_NUM\"\n    WORKFLOW_NAME=\"$(circleci_workflow_name)\"\n    JOB=\"$(circleci_job_name)\"\nfi\n\nnotify \"$@\"\n"
  },
  {
    "path": "scripts/ci/notification/templates/build_fail.json",
    "content": "{\n    \"msgtype\": \"m.text\",\n    \"body\": \" ❌ [${WORKFLOW_NAME}] Job ${JOB} failed on ${BRANCH}. Please see ${BUILD_URL} for details.\",\n    \"format\": \"org.matrix.custom.html\",\n    \"formatted_body\": \" ❌ [${WORKFLOW_NAME}] Job <strong>${JOB}</strong> failed on <strong>${BRANCH}</strong>. Please see <a href=\\\"${BUILD_URL}\\\">build ${BUILD_NUM}</a> for details.\"\n}\n"
  },
  {
    "path": "scripts/ci/notification/templates/build_release.json",
    "content": "{\n    \"msgtype\": \"m.text\",\n    \"body\": \" 📦 Release binaries for version ${TAG} are ready and attached as artifacts to ${BUILD_URL}. Please make sure the whole workflow succeeded before using them.\",\n    \"format\": \"org.matrix.custom.html\",\n    \"formatted_body\": \" 📦 Release binaries for version <strong>${TAG}</strong> are ready and attached as artifacts to <a href=\\\"${BUILD_URL}\\\">build ${BUILD_NUM}</a>. <strong>Please make sure the whole workflow succeeded before using them.</strong>\"\n}\n"
  },
  {
    "path": "scripts/ci/notification/templates/build_success.json",
    "content": "{\n    \"msgtype\": \"m.text\",\n    \"body\": \" ✅ [${WORKFLOW_NAME}] Job ${JOB} succeeded on ${BRANCH}. Please see ${BUILD_URL} for details.\",\n    \"format\": \"org.matrix.custom.html\",\n    \"formatted_body\":\" ✅ [${WORKFLOW_NAME}] Job <strong>${JOB}</strong> succeeded on <strong>${BRANCH}</strong>. Please see <a href=\\\"${BUILD_URL}\\\">build ${BUILD_NUM}</a> for details.\"\n}\n"
  },
  {
    "path": "scripts/ci/pack_soljson.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\nscript_dir=\"$(realpath \"$(dirname \"$0\")\")\"\nsoljson_js=\"$1\"\nsoljson_wasm=\"$2\"\nsoljson_wasm_size=$(wc -c \"${soljson_wasm}\" | cut -d ' ' -f 1)\noutput=\"$3\"\n\n(( $# == 3 )) || { >&2 echo \"Usage: $0 soljson.js soljson.wasm packed_soljson.js\"; exit 1; }\n\n# If this changes in an emscripten update, it's probably nothing to worry about,\n# but we should double-check when it happens and adjust the tail command below.\n[[ $(head -c 5 \"${soljson_js}\") == \"null;\" ]] || { >&2 echo 'Expected soljson.js to start with \"null;\"'; exit 1; }\n\necho \"Packing $soljson_js and $soljson_wasm to $output.\"\n(\n    echo -n 'var Module = Module || {}; Module[\"wasmBinary\"] = '\n    echo -n '(function(source, uncompressedSize) {'\n    # Note that base64DecToArr assumes no trailing equals signs.\n    cpp \"${script_dir}/base64DecToArr.js\" | grep -v \"^#.*\"\n    # Note that mini-lz4.js assumes no file header and no frame crc checksums.\n    cpp \"${script_dir}/mini-lz4.js\" | grep -v \"^#.*\"\n    echo 'return uncompress(base64DecToArr(source), uncompressedSize);})('\n    echo -n '\"'\n    # We fix lz4 format settings, remove the 8 bytes file header and remove the trailing equals signs of the base64 encoding.\n    lz4c --no-frame-crc --best --favor-decSpeed \"${soljson_wasm}\" - | tail -c +8 | base64 -w 0 | sed 's/[^A-Za-z0-9\\+\\/]//g'\n    echo '\",'\n    echo -n \"${soljson_wasm_size});\"\n    # Remove \"null;\" from the js wrapper.\n    tail -c +6 \"${soljson_js}\"\n) > \"$output\"\n\necho \"Testing $output.\"\necho \"process.stdout.write(require('$(realpath \"${output}\")').wasmBinary)\" | node | cmp \"${soljson_wasm}\" && echo \"Binaries match.\"\n# Allow the wasm binary to be garbage collected after compilation.\necho 'Module[\"wasmBinary\"] = undefined;' >> \"${output}\"\n"
  },
  {
    "path": "scripts/ci/post_style_errors_on_github.sh",
    "content": "#!/usr/bin/env bash\n\nERROR_LOG=\"$1\"\n\nfunction report_error_to_github\n{\n    [[ $CIRCLE_PR_NUMBER != \"\" ]] || CIRCLE_PR_NUMBER=\"${CIRCLE_PULL_REQUEST//[^0-9]/}\"\n\n    if [[ $CI == \"true\" ]]\n    then\n        echo \"posting error message to github\"\n        post_error_to_github\n        post_review_comment_to_github\n    fi\n}\n\nfunction post_error_to_github\n{\n    GITHUB_API_URL=\"https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/issues/$CIRCLE_PR_NUMBER/comments\"\n\n    ESCAPED_ERROR_MSG=$(cat -e \"$ERROR_LOG\" | sed 's/\\\\/\\\\\\\\/g' | sed 's/\"/\\\\\\\"/g')\n\n    FORMATTED_ERROR_MSG=$(echo \"$ESCAPED_ERROR_MSG\" | sed 's/\\$/\\\\n/g' | tr -d '\\n')\n\n    curl --request POST \\\n        --url \"$GITHUB_API_URL\" \\\n        --header 'accept: application/vnd.github.v3+json' \\\n        --header 'content-type: application/json' \\\n        -u \"stackenbotten3000:$GITHUB_ACCESS_TOKEN\" \\\n        --data \"{\\\"body\\\": \\\"There was an error when running \\`$CIRCLE_JOB\\` for commit \\`$CIRCLE_SHA1\\`:\\n\\`\\`\\`\\n$FORMATTED_ERROR_MSG\\n\\`\\`\\`\\nPlease check that your changes are working as intended.\\\"}\"\n}\n\nfunction post_review_comment_to_github\n{\n    GITHUB_API_URL=\"https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$CIRCLE_PR_NUMBER/comments\"\n\n    sed -i 1d \"$ERROR_LOG\"\n\n    while read -r line\n    do\n        ERROR_PATH=$(echo \"$line\" | grep -oE \".*\\.cpp\")\n        ERROR_LINE=$(echo \"$line\" | grep -oE \"[0-9]*\")\n        [[ $ERROR_PATH != \"\" ]] || { echo \"ERROR: Error message does not contain file path.\"; exit 1; }\n        [[ $ERROR_LINE != \"\" ]] || { echo \"ERROR: Error message does not contain line number.\"; exit 1; }\n\n        curl --request POST \\\n            --url \"$GITHUB_API_URL\" \\\n            --header 'accept: application/vnd.github.v3+json, application/vnd.github.comfort-fade-preview+json' \\\n            --header 'content-type: application/json' \\\n            -u \"stackenbotten3000:$GITHUB_ACCESS_TOKEN\" \\\n            --data \"{\\\"commit_id\\\": \\\"$CIRCLE_SHA1\\\", \\\"path\\\": \\\"$ERROR_PATH\\\", \\\"line\\\": $ERROR_LINE, \\\"side\\\": \\\"RIGHT\\\", \\\"body\\\": \\\"Coding style error\\\"}\"\n    done < \"$ERROR_LOG\"\n}\n\nreport_error_to_github\n"
  },
  {
    "path": "scripts/codespell_ignored_lines.txt",
    "content": "    A constant BT = BU;\n    A constant BU = BV;\n    A constant FN = FO;\n    A constant FO = FP;\n    struct BT { BU m; }\n    struct BU { BV m; }\n    struct FN { FO m; }\n    struct FO { FP m; }\n// encode_inline_asm(bytes): 0x20, 2, \"fo\" -> 0x20, 4, \"Zm8=\"\n// encode_no_asm(bytes): 0x20, 2, \"fo\" -> 0x20, 4, \"Zm8=\"\n\tBOOST_TEST(mutation(chromosome) == Chromosome(\"fo\"));\ndocker run --rm -v \"${OUTPUTDIR}\":/tmp/output -v \"${SCRIPTDIR}\":/tmp/scripts:ro -it trzeci/emscripten:sdk-tag-1.39.3-64bit /tmp/scripts/docker-scripts/rebuild_tags.sh \"${TAGS}\" /tmp/output \"$@\"\n\t\t\t\t<assignEnd>\n\t\t\t\t\t<assignEnd>\n\t\t\t\t\t\t<assignEnd>\n\t\ttempl(\"assignEnd\", dynamic ? \"end := pos\" : \"\");\n\t\t\ttempl(\"assignEnd\", dynamic ? \"end := pos\" : \"\");\n\t\t\ttempl(\"assignEnd\", \"end := pos\");\n\t\t\ttempl(\"assignEnd\", \"end := tail\");\n\t\t\ttempl(\"assignEnd\", \"\");\n        self.assertIn('401 Client Error: Unauthorized', str(manager.exception))\n        a = abd;\n"
  },
  {
    "path": "scripts/codespell_whitelist.txt",
    "content": "nd\ncompilability\nkeypair\nwast\nslippy\n"
  },
  {
    "path": "scripts/common/cmdline_helpers.py",
    "content": "import os\nimport subprocess\nfrom pathlib import Path\nfrom shutil import rmtree\nfrom tempfile import mkdtemp\nfrom textwrap import dedent\nfrom typing import List\nfrom typing import Optional\n\nfrom bytecodecompare.prepare_report import FileReport\nfrom bytecodecompare.prepare_report import parse_cli_output\n\n\nDEFAULT_PREAMBLE = dedent(\n    \"\"\"\n    // SPDX-License-Identifier: UNLICENSED\n    pragma solidity >=0.0;\n\"\"\"\n)\n\n\ndef inside_temporary_dir(prefix):\n    \"\"\"\n    Creates a temporary directory, enters the directory and executes the function inside it.\n    Restores the previous working directory after executing the function.\n    \"\"\"\n\n    def tmp_dir_decorator(fn):\n        previous_dir = os.getcwd()\n\n        def f(*args, **kwargs):\n            try:\n                tmp_dir = mkdtemp(prefix=prefix)\n                os.chdir(tmp_dir)\n                result = fn(*args, **kwargs)\n                rmtree(tmp_dir)\n                return result\n            finally:\n                os.chdir(previous_dir)\n\n        return f\n\n    return tmp_dir_decorator\n\n\ndef solc_bin_report(\n    solc_binary: str,\n    input_files: List[Path],\n    via_ir: bool,\n    optimize: bool = False,\n    yul_optimizations: Optional[str] = None,\n) -> FileReport:\n    \"\"\"\n    Runs the solidity compiler binary\n    \"\"\"\n\n    output = subprocess.check_output(\n        [solc_binary, \"--bin\"]\n        + input_files\n        + ([\"--via-ir\"] if via_ir else [])\n        + ([\"--optimize\"] if optimize else [])\n        + ([\"--yul-optimizations\", yul_optimizations] if yul_optimizations else []),\n        encoding=\"utf8\",\n    )\n    return parse_cli_output(\"\", output, 0)\n\n\ndef save_bytecode(\n    bytecode_path: Path, reports: FileReport, contract: Optional[str] = None\n):\n    with open(bytecode_path, \"w\", encoding=\"utf8\") as f:\n        for report in reports.contract_reports:\n            if contract is None or report.contract_name == contract:\n                bytecode = (\n                    report.bytecode if report.bytecode is not None else \"<NO BYTECODE>\"\n                )\n                f.write(f\"{report.contract_name}: {bytecode}\\n\")\n\n\ndef add_preamble(source_path: Path, preamble: str = DEFAULT_PREAMBLE):\n    for source in source_path.glob(\"**/*.sol\"):\n        with open(source, \"r+\", encoding=\"utf8\") as f:\n            content = f.read()\n            f.seek(0, 0)\n            f.write(preamble + content)\n"
  },
  {
    "path": "scripts/common/git_helpers.py",
    "content": "import subprocess\nfrom pathlib import Path\nfrom shutil import which\n\n\ndef run_git_command(command):\n    process = subprocess.run(\n        command,\n        encoding='utf8',\n        capture_output=True,\n        check=True,\n    )\n    return process.stdout.strip()\n\n\ndef git_current_branch():\n    return run_git_command(['git', 'symbolic-ref', 'HEAD', '--short'])\n\n\ndef git_commit_hash(ref: str = 'HEAD'):\n    return run_git_command(['git', 'rev-parse', '--verify', ref])\n\n\ndef git_diff(file_a: Path, file_b: Path) -> int:\n    if which('git') is None:\n        raise RuntimeError('git not found.')\n\n    return subprocess.run([\n        'git',\n        'diff',\n        '--color',\n        '--word-diff=plain',\n        '--word-diff-regex=.',\n        '--ignore-space-change',\n        '--ignore-blank-lines',\n        '--exit-code',\n        file_a,\n        file_b,\n    ], encoding='utf8', check=False).returncode\n"
  },
  {
    "path": "scripts/common/rest_api_helpers.py",
    "content": "from os import environ\nfrom pathlib import Path\nfrom typing import List, Mapping, Optional\nimport functools\nimport json\nimport operator\nimport shutil\n\nimport requests\n\n\nclass APIHelperError(Exception):\n    pass\n\nclass JobNotSuccessful(APIHelperError):\n    def __init__(self, name: str, status: str):\n        assert status != 'success'\n\n        self.name = name\n        self.status = status\n        self.job_finished = (status in ['failed', 'blocked'])\n\n        if status == 'not_running':\n            message = f\"Job {name} has not started yet.\"\n        elif status == 'blocked':\n            message = f\"Job {name} will not run because one of its dependencies failed.\"\n        elif status == 'running':\n            message = f\"Job {name} is still running.\"\n        elif status == 'failed':\n            message = f\"Job {name} failed.\"\n        else:\n            message = f\"Job {name} did not finish successfully. Current status: {status}.\"\n\n        super().__init__(message)\n\nclass JobMissing(APIHelperError):\n    pass\n\nclass InvalidResponse(APIHelperError):\n    pass\n\nclass FileAlreadyExists(APIHelperError):\n    pass\n\n\ndef query_api(url: str, params: Mapping[str, str], headers: dict, debug_requests=False) -> dict:\n    if debug_requests:\n        print(f'REQUEST URL: {url}')\n        if len(params) > 0:\n            print(f'QUERY: {params}')\n\n    response = requests.get(url, params=params, headers=headers, timeout=60)\n    response.raise_for_status()\n\n    if debug_requests:\n        json_response = response.json()\n        print('========== RESPONSE ==========')\n        if json_response is not None:\n            print(json.dumps(json_response, indent=4))\n        else:\n            print(response.content)\n        print('==============================')\n\n    return response.json()\n\n\ndef download_file(url: str, target_path: Path, headers: dict, overwrite=False):\n    if not overwrite and target_path.exists():\n        raise FileAlreadyExists(f\"Refusing to overwrite existing file: '{target_path}'.\")\n\n    with requests.get(url, headers, stream=True, timeout=60) as request:\n        with open(target_path, 'wb') as target_file:\n            shutil.copyfileobj(request.raw, target_file)\n\n\nclass Github:\n    BASE_URL = 'https://api.github.com'\n\n    project_slug: str\n    debug_requests: bool\n\n    def __init__(self, project_slug: str, debug_requests: bool):\n        self.project_slug = project_slug\n        self.debug_requests = debug_requests\n\n    def pull_request(self, pr_id: int) -> dict:\n        # GITHUB_READ_TOKEN should be a PAT with read-only permissions\n        # This is used by CircleCI and local scripts to avoid GitHub API rate limits\n        headers = {'Authorization': f'Bearer {environ.get(\"GITHUB_READ_TOKEN\")}'} if 'GITHUB_READ_TOKEN' in environ else {}\n        return query_api(\n            f'{self.BASE_URL}/repos/{self.project_slug}/pulls/{pr_id}',\n            {},\n            headers,\n            self.debug_requests\n        )\n\n\nclass CircleCI:\n    # None might be a more logical default for max_pages but in most cases we'll actually\n    # want some limit to prevent flooding the API with requests in case of a bug.\n    DEFAULT_MAX_PAGES = 10\n    BASE_URL = 'https://circleci.com/api/v2'\n\n    project_slug: str\n    debug_requests: bool\n\n    def __init__(self, project_slug: str, debug_requests: bool):\n        self.project_slug = project_slug\n        self.debug_requests = debug_requests\n\n    def paginated_query_api_iterator(self, url: str, params: Mapping[str, str], max_pages: int = DEFAULT_MAX_PAGES):\n        assert 'page-token' not in params\n\n        page_count = 0\n        next_page_token = None\n        headers = {'Circle-Token': str(environ.get('CIRCLECI_TOKEN'))} if 'CIRCLECI_TOKEN' in environ else {}\n        while max_pages is None or page_count < max_pages:\n            if next_page_token is not None:\n                params = {**params, 'page-token': next_page_token}\n\n            json_response = query_api(url, params, headers, self.debug_requests)\n\n            yield json_response['items']\n            next_page_token = json_response['next_page_token']\n            page_count += 1\n            if next_page_token is None:\n                break\n\n    def paginated_query_api(self, url: str, params: Mapping[str, str], max_pages: int = DEFAULT_MAX_PAGES):\n        return functools.reduce(operator.add, self.paginated_query_api_iterator(url, params, max_pages), [])\n\n    def pipelines(\n        self,\n        branch: Optional[str] = None,\n        commit_hash: Optional[str] = None,\n        excluded_trigger_types: List[str] = None,\n    ) -> List[dict]:\n        if excluded_trigger_types is None:\n            excluded_trigger_types = []\n\n        for items in self.paginated_query_api_iterator(\n            f'{self.BASE_URL}/project/gh/{self.project_slug}/pipeline',\n            {'branch': branch} if branch is not None else {},\n            max_pages=10,\n        ):\n            matching_items = [\n                item\n                for item in items\n                if (\n                    (commit_hash is None or item['vcs']['revision'] == commit_hash) and\n                    item['trigger']['type'] not in excluded_trigger_types\n                )\n            ]\n            if len(matching_items) > 0:\n                return matching_items\n\n        return []\n\n    def workflows(self, pipeline_id: str) -> dict:\n        return self.paginated_query_api(f'{self.BASE_URL}/pipeline/{pipeline_id}/workflow', {})\n\n    def jobs(self, workflow_id: str) -> Mapping[str, dict]:\n        items = self.paginated_query_api(f'{self.BASE_URL}/workflow/{workflow_id}/job', {})\n        jobs_by_name = {job['name']: job for job in items}\n\n        assert len(jobs_by_name) <= len(items)\n        if len(jobs_by_name) < len(items):\n            raise InvalidResponse(\"Job names in the workflow are not unique.\")\n\n        return jobs_by_name\n\n    def job(self, workflow_id: str, name: str, require_success: bool = False) -> dict:\n        jobs = self.jobs(workflow_id)\n        if name not in jobs:\n            raise JobMissing(f\"Job {name} is not present in the workflow.\")\n\n        if require_success and jobs[name]['status'] != 'success':\n            raise JobNotSuccessful(name, jobs[name]['status'])\n\n        return jobs[name]\n\n    def artifacts(self, job_number: int) -> Mapping[str, dict]:\n        items = self.paginated_query_api(f'{self.BASE_URL}/project/gh/{self.project_slug}/{job_number}/artifacts', {})\n        artifacts_by_name = {artifact['path']: artifact for artifact in items}\n\n        assert len(artifacts_by_name) <= len(items)\n        if len(artifacts_by_name) < len(items):\n            raise InvalidResponse(\"Names of artifacts attached to the job are not unique.\")\n\n        return artifacts_by_name\n\n    @staticmethod\n    def latest_item(items: dict) -> dict:\n        sorted_items = sorted(items, key=lambda item: item['created_at'], reverse=True)\n        return sorted_items[0] if len(sorted_items) > 0 else None\n"
  },
  {
    "path": "scripts/common.sh",
    "content": "#!/usr/bin/env bash\n# ------------------------------------------------------------------------------\n# vim:ts=4:et\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016-2019 solidity contributors.\n# ------------------------------------------------------------------------------\n\n# The fail() function defined below requires set -e to be enabled.\nset -e\n\n# Save the initial working directory so that printStackTrace() can access it even if the sourcing\n# changes directory. The paths returned by `caller` are relative to it.\n_initial_work_dir=$(pwd)\n\nif [[ -n ${CIRCLECI:-} ]]\nthen\n    export TERM=\"${TERM:-xterm}\"\n    function printTask { echo -e \"$(tput bold)$(tput setaf 2)$1$(tput setaf 7)\"; }\n    function printError { >&2 echo -e \"$(tput setaf 1)$1$(tput setaf 7)\"; }\n    function printWarning { >&2 echo -e \"$(tput setaf 11)$1$(tput setaf 7)\"; }\n    function printLog { echo -e \"$(tput setaf 3)$1$(tput setaf 7)\"; }\nelse\n    function printTask { echo -e \"$(tput bold)$(tput setaf 2)$1$(tput sgr0)\"; }\n    function printError { >&2 echo -e \"$(tput setaf 1)$1$(tput sgr0)\"; }\n    function printWarning { >&2 echo -e \"$(tput setaf 11)$1$(tput sgr0)\"; }\n    function printLog { echo -e \"$(tput setaf 3)$1$(tput sgr0)\"; }\nfi\n\nfunction printStackTrace\n{\n    printWarning \"\"\n    printWarning \"Stack trace:\"\n\n    local frame=1\n    while caller \"$frame\" > /dev/null\n    do\n        local lineNumber line file function\n\n        # `caller` returns something that could already be printed as a stacktrace but we can make\n        # it more readable by rearranging the components.\n        # NOTE: This assumes that paths do not contain spaces.\n        lineNumber=$(caller \"$frame\" | cut -d \" \" -f 1)\n        function=$(caller \"$frame\" | cut -d \" \" -f 2)\n        file=$(caller \"$frame\" | cut -d \" \" -f 3)\n\n        # Paths in the output from `caller` can be relative or absolute (depends on how the path\n        # with which the script was invoked) and if they're relative, they're not necessarily\n        # relative to the current working dir. This is a heuristic that will work if they're absolute,\n        # relative to current dir, or relative to the dir that was current when the script started.\n        # If neither works, it gives up.\n        line=$(\n            {\n                tail \"--lines=+${lineNumber}\" \"$file\" ||\n                tail \"--lines=+${lineNumber}\" \"${_initial_work_dir}/${file}\"\n            } 2> /dev/null |\n            head --lines=1 |\n            sed -e 's/^[[:space:]]*//'\n        ) || line=\"<failed to find source line>\"\n\n        >&2 printf \"    %s:%d in function %s()\\n\" \"$file\" \"$lineNumber\" \"$function\"\n        >&2 printf \"        %s\\n\" \"$line\"\n\n        ((frame++))\n    done\n}\n\nfunction fail\n{\n    printError \"$@\"\n\n    # Using return rather than exit lets the invoking code handle the failure by suppressing the exit code.\n    return 1\n}\n\nfunction assertFail\n{\n    printError \"\"\n    (( $# == 0 )) && printError \"Assertion failed.\"\n    (( $# == 1 )) && printError \"Assertion failed: $1\"\n    printStackTrace\n\n    # Intentionally using exit here because assertion failures are not supposed to be handled.\n    exit 2\n}\n\nfunction msg_on_error\n{\n    local error_message=\"\"\n    local no_stdout=false\n    local no_stderr=false\n\n    while [[ $1 =~ ^-- ]]\n    do\n        case \"$1\" in\n            --msg)\n                error_message=\"$2\"\n                shift\n                shift\n                ;;\n            --no-stdout)\n                no_stdout=true\n                shift\n                ;;\n            --no-stderr)\n                no_stderr=true\n                shift\n                ;;\n            --silent)\n                no_stdout=true\n                no_stderr=true\n                shift\n                ;;\n            *)\n                assertFail \"Invalid option for msg_on_error: $1\"\n                ;;\n        esac\n    done\n\n    local command=(\"$@\")\n\n    local stdout_file stderr_file\n    stdout_file=\"$(mktemp -t cmdline_test_command_stdout_XXXXXX.txt)\"\n    stderr_file=\"$(mktemp -t cmdline_test_command_stderr_XXXXXX.txt)\"\n\n    if \"${command[@]}\" > \"$stdout_file\" 2> \"$stderr_file\"\n    then\n        [[ $no_stdout == \"true\" ]] || cat \"$stdout_file\"\n        [[ $no_stderr == \"true\" ]] || >&2 cat \"$stderr_file\"\n        rm \"$stdout_file\" \"$stderr_file\"\n        return 0\n    else\n        printError \"\"\n        printError \"Command failed: ${error_message}\"\n        printError \"    command: $SOLC ${command[*]}\"\n        if [[ -s \"$stdout_file\" ]]\n        then\n            printError \"--- stdout ---\"\n            printError \"-----------\"\n            >&2 cat \"$stdout_file\"\n            printError \"--------------\"\n        else\n            printError \"    stdout: <EMPTY>\"\n        fi\n        if [[ -s \"$stderr_file\" ]]\n        then\n            printError \"--- stderr ---\"\n            >&2 cat \"$stderr_file\"\n            printError \"--------------\"\n        else\n            printError \"    stderr: <EMPTY>\"\n        fi\n\n        rm \"$stdout_file\" \"$stderr_file\"\n\n        printStackTrace\n        return 1\n    fi\n}\n\n\nfunction diff_values\n{\n    (( $# >= 2 )) || fail \"diff_values requires at least 2 arguments.\"\n\n    local value1=\"$1\"\n    local value2=\"$2\"\n    shift 2\n\n    if ! diff --unified=0 <(echo \"$value1\") <(echo \"$value2\") \"$@\"\n    then\n        if [[ -n ${DIFFVIEW:-} ]]\n        then\n            # Use user supplied diff view binary\n            \"$DIFFVIEW\" <(echo \"$value1\") <(echo \"$value2\")\n        fi\n        return 1\n    fi\n}\n\nfunction diff_files\n{\n    (( $# >= 2 )) || fail \"diff_files requires at least 2 arguments.\"\n\n    local file1=\"$1\"\n    local file2=\"$2\"\n\n    if ! diff \"${file1}\" \"${file2}\"\n    then\n        if [[ -n ${DIFFVIEW:-} ]]\n        then\n            # Use user supplied diff view binary\n            \"$DIFFVIEW\" \"${file1}\" \"${file2}\"\n        fi\n        return 1\n    fi\n}\n\nfunction safe_kill\n{\n    local PID=${1}\n    local NAME=${2:-${1}}\n    local n=1\n\n    # only proceed if $PID does exist\n    kill -0 \"$PID\" 2>/dev/null || return\n\n    echo \"Sending SIGTERM to ${NAME} (${PID}) ...\"\n    kill \"$PID\"\n\n    # wait until process terminated gracefully\n    while kill -0 \"$PID\" 2>/dev/null && [[ $n -le 4 ]]; do\n        echo \"Waiting ($n) ...\"\n        sleep 1\n        n=$((n + 1))\n    done\n\n    # process still alive? then hard-kill\n    if kill -0 \"$PID\" 2>/dev/null; then\n        echo \"Sending SIGKILL to ${NAME} (${PID}) ...\"\n        kill -9 \"$PID\"\n    fi\n}\n\nfunction circleci_select_steps\n{\n    # We expect multiple lines in $all_steps, one step per line\n    local all_steps=\"$1\"\n    (( $# == 1 )) || assertFail\n\n    if (( CIRCLE_NODE_TOTAL )) && (( CIRCLE_NODE_TOTAL > 1 ))\n    then\n        echo \"$all_steps\" | circleci tests split | xargs\n    else\n        echo \"$all_steps\" | xargs\n    fi\n}\n\nfunction circleci_select_steps_multiarg\n{\n    # We expect multiple arguments, one step per argument.\n    circleci_select_steps \"$(printf '%s\\n' \"$@\")\"\n}\n\nfunction circleci_step_selected\n{\n    local selected_steps=\"$1\"\n    local step=\"$2\"\n    (( $# == 2 )) || assertFail\n    [[ $step != *\" \"* ]] || assertFail \"Step names must not contain spaces.\"\n\n    [[ \" $selected_steps \" == *\" $step \"* ]] || return 1\n}\n\nfunction first_word\n{\n    local words=\"$1\"\n    (( $# == 1 )) || assertFail\n\n    echo \"$words\" | cut -d \" \" -f 1\n}\n\n# Function reads from stdin. Therefore it has to be used with pipes.\nfunction split_on_empty_lines_into_numbered_files\n{\n    path_prefix=\"${1}\"\n    path_suffix=\"${2}\"\n\n    awk -v RS= \"{print > (\\\"${path_prefix}_\\\"NR \\\"${path_suffix}\\\")}\"\n}\n\nfunction command_available\n{\n    local program=\"$1\"\n    local parameters=( \"${@:2}\" )\n    if ! \"${program}\" \"${parameters[@]}\" > /dev/null 2>&1\n    then\n        fail \"'${program}' not found or not executed successfully with parameter(s) '${parameters[*]}'. aborting.\"\n    fi\n}\n\nfunction gnu_grep\n{\n    if [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n        command_available ggrep --version\n        ggrep \"$@\"\n    else\n        command_available grep --version\n        grep \"$@\"\n    fi\n}\n\nfunction time_to_json_file\n{\n    local time_file=\"$1\"\n    local cmd=(\"${@:2}\")\n    (( $# >= 2 )) || assertFail\n\n    # $TIMEFORMAT is the format used by built-in `time`. Description is in `man bash`.\n    local original_timeformat=\"$TIMEFORMAT\"\n    TIMEFORMAT='{\"real\": %R, \"user\": %U, \"sys\": %S}'\n\n    # We temporarily use descriptors 3 and 4 to preserve stdout and stderr of the original command.\n    # This allows us to store `time`'s own stderr in a file. Then we restore initial descriptors.\n    {\n        {\n            time { \"${cmd[@]}\" 1>&3 2>&4; }\n        } 2> \"$time_file\"\n    } 3>&1 4>&2\n\n    # Restore original format so that it does not spill outside of the function.\n    TIMEFORMAT=\"$original_timeformat\"\n}\n\nfunction gnu_time_to_json_file\n{\n    local time_file=\"$1\"\n    local cmd=(\"${@:2}\")\n    (( $# >= 2 )) || assertFail\n\n    local gnu_time_path\n    gnu_time_path=$(type -P time)\n\n    \"$gnu_time_path\" \\\n        --output \"$time_file\" \\\n        --quiet \\\n        --format '{\"real\": %e, \"user\": %U, \"sys\": %S, \"mem\": %M, \"exit\": %x}' \\\n            \"${cmd[@]}\"\n}\n"
  },
  {
    "path": "scripts/common_cmdline.sh",
    "content": "#!/usr/bin/env bash\n# ------------------------------------------------------------------------------\n# vim:ts=4:et\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016-2019 solidity contributors.\n# ------------------------------------------------------------------------------\n\nYULARGS=(--strict-assembly)\nFULLARGS=(--optimize --combined-json \"abi,asm,ast,bin,bin-runtime,devdoc,hashes,metadata,opcodes,srcmap,srcmap-runtime,userdoc\")\nOLDARGS=(--optimize --combined-json \"abi,asm,ast,bin,bin-runtime,devdoc,interface,metadata,opcodes,srcmap,srcmap-runtime,userdoc\")\n\nfunction compileFull\n{\n    local expected_exit_code=0\n    local expect_output='none'\n\n    case \"$1\" in\n        '--expect-errors')\n            expected_exit_code=1\n            expect_output='warnings-or-errors'\n            shift;\n            ;;\n        '--expect-warnings')\n            expect_output='warnings-or-errors'\n            shift;\n            ;;\n        '--ignore-warnings')\n            expect_output='any'\n            shift;\n            ;;\n    esac\n\n    local args=(\"${FULLARGS[@]}\")\n    if [[ $1 = '-v' ]]; then\n        if (echo \"$2\" | grep -Po '(?<=0.4.)\\d+' >/dev/null); then\n            patch=$(echo \"$2\" | grep -Po '(?<=0.4.)\\d+')\n            if (( patch < 22 )); then\n                args=(\"${OLDARGS[@]}\")\n            fi\n        fi\n        shift 2\n    fi\n\n    local files=(\"$@\")\n\n    local stderr_path; stderr_path=$(mktemp)\n\n    if [ \"${files: -4}\" == \".yul\" ]\n    then\n        args=(\"${YULARGS[@]}\")\n    fi\n\n    set +e\n    \"$SOLC\" \"${args[@]}\" \"${files[@]}\" >/dev/null 2>\"$stderr_path\"\n    local exit_code=$?\n    local errors; errors=$(grep -v -E \\\n        -e 'Warning: This is a pre-release compiler version|Warning: Experimental features are turned on|pragma experimental ABIEncoderV2|^ +--> |^ +\\||^[0-9]+ +\\| ' \\\n        -e '^No text representation found.$' < \"$stderr_path\"\n    )\n\n    set -e\n    rm \"$stderr_path\"\n\n    if [[\n        $exit_code != \"$expected_exit_code\" ||\n        $errors != \"\" && $expect_output == 'none' ||\n        $errors == \"\" && $expect_output != 'none' && $expect_output != 'any' && $expected_exit_code == 0\n    ]]\n    then\n        printError \"TEST FAILURE\"\n        printError \"Actual exit code:   $exit_code\"\n        printError \"Expected exit code: $expected_exit_code\"\n        printError \"==== Output ====\"\n        echo \"$errors\"\n        printError \"== Output end ==\"\n        printError \"\"\n        case \"$expect_output\" in\n            'none') printError \"No output was expected.\" ;;\n            'warnings-or-errors') printError \"Expected warnings or errors.\" ;;\n        esac\n\n        printError \"\"\n        printError \"While calling:\"\n        echo      \"\\\"$SOLC\\\" ${args[*]} ${files[*]}\"\n        printError \"Inside directory:\"\n        echo \"    $(pwd)\"\n        printError \"Input was:\"\n        echo \"${files[@]}\"\n        false\n    fi\n}\n\nfunction singleContractOutputViaStandardJSON\n{\n    (( $# == 4 )) || assertFail\n    local language=\"$1\"\n    local selected_output=\"$2\"\n    local extra_settings=\"$3\"\n    local input_file=\"$4\"\n    [[ $selected_output != \"*\" ]] || assertFail\n\n    json_output=$(\n        \"$SOLC\" --standard-json --allow-paths \"$(basename \"$input_file\")\" - <<EOF\n        {\n            \"language\": \"${language}\",\n            \"sources\": {\"${input_file}\": {\"urls\": [\"${input_file}\"]}},\n            \"settings\": {\n                \"outputSelection\": {\"*\": { \"*\": [\"${selected_output}\"]}},\n                ${extra_settings}\n            }\n        }\nEOF\n    )\n\n    local error_list output has_contract_level_outputs\n\n    error_list=$(echo \"$json_output\" | jq '.errors[] | select(.severity==\"error\")')\n    [[ $error_list == '' ]] || \\\n        fail \"Failed to compile ${input_file} via Standard JSON. Errors: ${error_list}\"\n\n    has_contract_level_outputs=$(echo \"$json_output\" | jq 'has(\"contracts\")')\n    [[ $has_contract_level_outputs == true ]] || \\\n        fail \"Standard JSON output ${selected_output} was ignored by the compiler.\"\n\n    output=$(echo \"$json_output\" | jq --raw-output \".contracts[\\\"${input_file}\\\"][].${selected_output}\")\n    [[ $output != null ]] || \\\n        fail \"Compiler failed to produce the ${selected_output} output when compiling ${input_file} via Standard JSON.\"\n\n    echo \"$output\"\n}\n\nfunction stripCLIDecorations\n{\n    sed -e '/^=======.*=======$/d' \\\n        -e '/^Binary:$/d' \\\n        -e '/^Binary of the runtime part:$/d' \\\n        -e '/^Opcodes:$/d' \\\n        -e '/^IR:$/d' \\\n        -e '/^Optimized IR:$/d' \\\n        -e '/^EVM assembly:$/d' \\\n        -e '/^Yul Control Flow Graph:$/d' \\\n        -e '/^JSON AST (compact format):$/d' \\\n        -e '/^Function signatures:$/d' \\\n        -e '/^Contract Storage Layout:$/d' \\\n        -e '/^Developer Documentation$/d' \\\n        -e '/^User Documentation$/d' \\\n        -e '/^Contract JSON ABI$/d' \\\n        -e '/^Metadata:$/d' \\\n        -e '/^EVM$/d' \\\n        -e '/^Pretty printed source:$/d' \\\n        -e '/^Text representation:$/d' \\\n        -e '/^Binary representation:$/d'\n}\n\nfunction stripEmptyLines\n{\n    sed -e '/^\\s*$/d'\n}\n\n# Calculates the total size of bytecode of one or more contracts in bytes.\n# Expects the output from `solc --bin` on standard input.\nfunction bytecode_size {\n    local bytecode_chars\n    bytecode_chars=$(stripCLIDecorations | stripEmptyLines | wc --chars)\n    echo $(( bytecode_chars / 2 ))\n}\n"
  },
  {
    "path": "scripts/create_source_tarball.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\nREPO_ROOT=\"$(dirname \"$0\")\"/..\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\ncd \"$REPO_ROOT\"\nversion=$(scripts/get_version.sh)\ncommit_hash=$(git rev-parse --short=8 HEAD)\n\nif [[ -e prerelease.txt ]]; then\n    prerelease_suffix=$(cat prerelease.txt)\n    if [[ $prerelease_suffix == \"\" ]]; then\n        # File exists and has zero size -> not a prerelease\n        version_string=\"$version\"\n    elif [[ $prerelease_suffix == pre.* ]]; then\n        # Tagged prerelease -> unambiguous, so commit hash not needed\n        version_string=\"${version}-${prerelease_suffix}\"\n    else\n        # Nightly/develop/other prerelease -> include commit hash\n        version_string=\"${version}-${prerelease_suffix}-${commit_hash}\"\n    fi\nelse\n    # Nightly/develop/other prerelease -> include commit hash + default prerelease suffix\n    commit_date=$(TZ=UTC git show --quiet --date=\"format-local:%Y.%-m.%-d\" --format=\"%cd\")\n    version_string=\"${version}-nightly-${commit_date}-${commit_hash}\"\nfi\n\n# The only purpose of commit_hash.txt is to make it possible to build the compiler without git.\n# It is not meant as an override of the real hash.\n[[ ! -e commit_hash.txt ]] || \\\n    fail \"commit_hash.txt is present in the repository root, but will not be used to override the commit hash for the source package.\"\n\nTEMPDIR=$(mktemp -d -t \"solc-src-tarball-XXXXXX\")\nSOLDIR=\"${TEMPDIR}/solidity_${version_string}/\"\nmkdir \"$SOLDIR\"\n\n# Ensure that submodules are initialized.\ngit submodule update --init --recursive\n# Store the current source\ngit checkout-index --all --prefix=\"$SOLDIR\"\n# shellcheck disable=SC2016\nSOLDIR=\"$SOLDIR\" git submodule foreach 'git checkout-index --all --prefix=\"${SOLDIR}/${sm_path}/\"'\n\n# Documentation is pretty heavy and not necessary to build the compiler.\n# Especially nlohmann-json has several huge images, which blow up the size of the compressed tarball.\n# shellcheck disable=SC2016\nSOLDIR=\"$SOLDIR\" git submodule foreach 'rm -rf \"${SOLDIR}/${sm_path}/\"doc/; rm -rf \"${SOLDIR}/${sm_path}/\"docs/'\n\n# Include the commit hash and prerelease suffix in the tarball\necho \"$commit_hash\" > \"${SOLDIR}/commit_hash.txt\"\n[[ -e prerelease.txt ]] && cp prerelease.txt \"${SOLDIR}/\"\n\nmkdir -p \"$REPO_ROOT/upload\"\ntar \\\n    --owner 0 \\\n    --group 0 \\\n    --create \\\n    --gzip \\\n    --file \"${REPO_ROOT}/upload/solidity_${version_string}.tar.gz\" \\\n    --directory \"$TEMPDIR\" \\\n    \"solidity_${version_string}\"\nrm -r \"$TEMPDIR\"\n"
  },
  {
    "path": "scripts/docker/buildpack-deps/Dockerfile.emscripten",
    "content": "# vim:syntax=dockerfile\n#------------------------------------------------------------------------------\n# Dockerfile for building and testing Solidity Compiler on CI\n# Target: Emscripten\n# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps\n#\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016-2019 solidity contributors.\n#------------------------------------------------------------------------------\n#\n# The Emscripten SDK at https://github.com/emscripten-core/emsdk/\n# contains a Makefile in the docker/ subdirectory that can be used to create the\n# required base image using:\n#\n#   make version=2.0.33 build\n#\n# Note that emscripten is supposed to automatically install to $(em-config CACHE)/sysroot, but\n# apparently this currently breaks due to conflicting compatibility headers.\n# Using $(em-config CACHE)/sysroot/usr seems to work, though, and still has cmake find the\n# dependencies automatically.\nFROM emscripten/emsdk:3.1.19 AS base\nLABEL version=\"22\"\n\nADD emscripten.jam /usr/src\nRUN <<-EOF\n    set -ex\n\tapt-get update\n\tapt-get install -qqy --no-install-recommends \\\n\t\tlsof \\\n\t\tccache \\\n\t\tlz4 \\\n\t\tpython3 \\\n\t\tpython3-pip \\\n\t\tsudo && \\\n\tpip3 install requests\nEOF\n\n# Install Z3\nRUN <<-EOF\n    set -ex\n\tcd /usr/src\n\tgit clone https://github.com/Z3Prover/z3.git -b z3-4.13.3 --depth 1\n\tcd z3\n\tmkdir build\n\tcd build\n\temcmake cmake \\\n\t\t-DCMAKE_INSTALL_PREFIX=$(em-config CACHE)/sysroot/usr \\\n\t\t-DCMAKE_BUILD_TYPE=MinSizeRel \\\n\t\t-DZ3_BUILD_LIBZ3_SHARED=OFF \\\n\t\t-DZ3_ENABLE_EXAMPLE_TARGETS=OFF \\\n\t\t-DZ3_BUILD_TEST_EXECUTABLES=OFF \\\n\t\t-DZ3_BUILD_EXECUTABLE=OFF \\\n\t\t-DZ3_SINGLE_THREADED=ON \\\n\t\t-DCMAKE_CXX_FLAGS=\"-s DISABLE_EXCEPTION_CATCHING=0\" \\\n\t\t..\n\tmake\n\tmake install\n\trm -r /usr/src/z3\nEOF\n\n# Install Boost\nRUN <<-EOF\n    set -ex\n\tcd /usr/src\n\twget -q 'https://archives.boost.io/release/1.83.0/source/boost_1_83_0.tar.bz2' -O boost.tar.bz2\n\ttest \"$(sha256sum boost.tar.bz2)\" = \"6478edfe2f3305127cffe8caf73ea0176c53769f4bf1585be237eb30798c3b8e  boost.tar.bz2\"\n\ttar -xf boost.tar.bz2\n\trm boost.tar.bz2\n\tcd boost_1_83_0\n\tmv ../emscripten.jam .\n\t./bootstrap.sh\n\techo \"using emscripten : : em++ ;\" >> project-config.jam\n\t./b2 toolset=emscripten link=static variant=release threading=single runtime-link=static \\\n\t\t--with-system --with-filesystem --with-test --with-program_options \\\n\t\tcxxflags=\"-s DISABLE_EXCEPTION_CATCHING=0 -Wno-unused-local-typedef -Wno-variadic-macros -Wno-c99-extensions -Wno-all\" \\\n\t       --prefix=$(em-config CACHE)/sysroot/usr install\n\trm -r /usr/src/boost_1_83_0\nEOF\n\n# CVC5\nRUN <<-EOF\n    set -ex\n    cvc5_version=\"1.2.0\"\n    cvc5_archive_name=\"cvc5-Linux-x86_64-static\"\n    wget \"https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip\" -O /opt/cvc5.zip\n    test \"$(sha256sum /opt/cvc5.zip)\" = \"d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e  /opt/cvc5.zip\"\n    unzip -j /opt/cvc5.zip \"${cvc5_archive_name}/bin/cvc5\" -d /usr/bin\n    rm -f /opt/cvc5.zip\nEOF\n"
  },
  {
    "path": "scripts/docker/buildpack-deps/Dockerfile.ubuntu.clang.ossfuzz",
    "content": "# vim:syntax=dockerfile\n#------------------------------------------------------------------------------\n# Dockerfile for building and testing Solidity Compiler on CI\n# Target: Ubuntu ossfuzz Clang variant\n# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps\n#\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016-2021 solidity contributors.\n#------------------------------------------------------------------------------\nFROM gcr.io/oss-fuzz-base/base-builder AS base\nLABEL version=\"13\"\n\nARG DEBIAN_FRONTEND=noninteractive\n\nRUN apt-get update; \\\n\tapt-get -qqy install --no-install-recommends \\\n\t\tautomake \\\n\t\tbison \\\n\t\tbuild-essential \\\n\t\tccache \\\n\t\tcurl \\\n\t\tgit \\\n\t\tjq \\\n\t\tlibbz2-dev \\\n\t\tlibc++-18-dev \\\n\t\tlibc++abi-18-dev \\\n\t\tliblzma-dev \\\n\t\tlibtool \\\n\t\tlsof \\\n\t\tm4 \\\n\t\tmlton \\\n\t\tninja-build \\\n\t\topenjdk-8-jdk \\\n\t\tpkg-config \\\n\t\tpython3-pip \\\n\t\tpython3-dev \\\n\t\tsoftware-properties-common \\\n\t\tsudo \\\n\t\ttexinfo \\\n\t\tunzip \\\n\t\tuuid-dev \\\n\t\twget \\\n\t\tzlib1g-dev; \\\n\tpip3 install \\\n\t\tcodecov \\\n\t\tcolorama \\\n\t\tdeepdiff \\\n\t\tparsec \\\n\t\tpygments-lexer-solidity \\\n\t\tpylint \\\n\t\trequests \\\n\t\ttabulate;\n\nFROM base AS libraries\n\n# Boost\nRUN set -ex; \\\n\tcd /usr/src; \\\n\twget -q 'https://archives.boost.io/release/1.83.0/source/boost_1_83_0.tar.bz2' -O boost.tar.bz2; \\\n\ttest \"$(sha256sum boost.tar.bz2)\" = \"6478edfe2f3305127cffe8caf73ea0176c53769f4bf1585be237eb30798c3b8e  boost.tar.bz2\" && \\\n\ttar -xf boost.tar.bz2; \\\n\trm boost.tar.bz2; \\\n\tcd boost_1_83_0; \\\n\texport CXXFLAGS=\"$CXXFLAGS -std=c++20 -nostdinc++ -I/usr/local/include/c++/v1 -I/usr/local/include/x86_64-unknown-linux-gnu/c++/v1 -pthread\"; \\\n\texport LDFLAGS=\"$LDFLAGS -stdlib=libc++ -lpthread\"; \\\n\t./bootstrap.sh --with-toolset=clang --prefix=/usr; \\\n\t./b2 toolset=clang \\\n\t\tcxxflags=\"${CXXFLAGS}\" \\\n\t\tlinkflags=\"${LDFLAGS}\" \\\n\t\theaders; \\\n\t./b2 toolset=clang \\\n\t\tcxxflags=\"${CXXFLAGS}\" \\\n\t\tlinkflags=\"${LDFLAGS}\" \\\n\t\tlink=static variant=release runtime-link=static \\\n\t\tsystem filesystem unit_test_framework program_options \\\n\t\tinstall -j $(($(nproc)/2)); \\\n\trm -rf /usr/src/boost_1_83_0\n\n# Z3\nRUN set -ex; \\\n\tz3_version=\"4.13.3\"; \\\n\tz3_archive_name=\"z3-${z3_version}-x64-glibc-2.35\"; \\\n\twget \"https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_archive_name}.zip\" -O /opt/z3.zip; \\\n\ttest \"$(sha256sum /opt/z3.zip)\" = \"32c7377026733c9d7b33c21cd77a68f50ba682367207b031a6bfd80140a8722f  /opt/z3.zip\"; \\\n\tunzip -j /opt/z3.zip \"${z3_archive_name}/bin/z3\" -d /usr/bin; \\\n\trm -f /opt/z3.zip;\n\n# Eldarica\nRUN set -ex; \\\n\tapt-get update; \\\n\tapt-get install -qqy openjdk-11-jre; \\\n\teldarica_version=\"2.1\"; \\\n\twget \"https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip\" -O /opt/eld_binaries.zip; \\\n\ttest \"$(sha256sum /opt/eld_binaries.zip)\" = \"0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c  /opt/eld_binaries.zip\"; \\\n\tunzip /opt/eld_binaries.zip -d /opt; \\\n\trm -f /opt/eld_binaries.zip;\n\n# CVC5\nRUN set -ex; \\\n\tcvc5_version=\"1.2.0\"; \\\n\tcvc5_archive_name=\"cvc5-Linux-x86_64-static\"; \\\n\twget \"https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip\" -O /opt/cvc5.zip; \\\n\ttest \"$(sha256sum /opt/cvc5.zip)\" = \"d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e  /opt/cvc5.zip\"; \\\n\tunzip -j /opt/cvc5.zip \"${cvc5_archive_name}/bin/cvc5\" -d /usr/bin; \\\n\trm -f /opt/cvc5.zip;\n\n# OSSFUZZ: libprotobuf-mutator\n# Use commit prior to libprotobuf upgrade that broke solidity build\n# See https://github.com/google/oss-fuzz/issues/10237\nRUN set -ex; \\\n\tgit clone https://github.com/google/libprotobuf-mutator.git /usr/src/libprotobuf-mutator; \\\n\tcd /usr/src/libprotobuf-mutator; \\\n\tgit reset --hard 212a7be1eb08e7f9c79732d2aab9b2097085d936; \\\n\tmkdir build; \\\n\tcd build; \\\n\tcmake .. -GNinja -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON \\\n\t\t-DLIB_PROTO_MUTATOR_TESTING=OFF -DCMAKE_BUILD_TYPE=Release \\\n\t\t-DCMAKE_INSTALL_PREFIX=\"/usr\"; \\\n\tninja; \\\n\tcp -vpr external.protobuf/bin/* /usr/bin/; \\\n\tcp -vpr external.protobuf/include/* /usr/include/; \\\n\tcp -vpr external.protobuf/lib/* /usr/lib/; \\\n\tninja install/strip; \\\n\trm -rf /usr/src/libprotobuf-mutator\n\n# EVMONE\nRUN set -ex; \\\n\tcd /usr/src; \\\n\tgit clone --branch=\"v0.16.0\" --recurse-submodules https://github.com/ipsilon/evmone.git; \\\n\tcd evmone; \\\n\tmkdir build; \\\n\tcd build; \\\n\tCXX=clang++ cmake .. -G Ninja \\\n\t\t-DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_FLAGS=\"-stdlib=libc++\" \\\n\t\t-DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=\"/usr\"; \\\n\tninja; \\\n\tninja install/strip; \\\n\trm -rf /usr/src/evmone\n\n# gmp\nRUN set -ex; \\\n\t# Replace system installed libgmp static library\n\t# with sanitized version. Do not perform apt\n\t# remove because it removes mlton as well that\n\t# we need for building libabicoder\n\tcd /usr/src/; \\\n\tgit clone --depth 1 --branch gmp-6.2.1 https://github.com/gmp-mirror/gmp-6.2 gmp/; \\\n\trm -r gmp/.git/; \\\n\ttest \\\n\t\t\"$(tar --create gmp/ --sort=name --mtime=1970-01-01Z --owner=0 --group=0 --numeric-owner | sha256sum)\" = \\\n\t\t\"d606ff6a4ce98692f9920031e85ea8fcf4a65ce1426f6f0048b8794aefed174b  -\"; \\\n\t# NOTE: This removes also libgmp.so, which git depends on\n\trm -f /usr/lib/x86_64-linux-gnu/libgmp.*; \\\n\trm -f /usr/include/x86_64-linux-gnu/gmp.h; \\\n\tcd gmp/; \\\n\tautoreconf -i; \\\n\t./configure --prefix=/usr --enable-static=yes --enable-maintainer-mode; \\\n\tmake -j; \\\n\tmake check; \\\n\tmake install; \\\n\trm -rf /usr/src/gmp/\n\n# libabicoder\nRUN set -ex; \\\n\tcd /usr/src; \\\n\tgit clone https://github.com/ekpyron/Yul-Isabelle; \\\n\tcd Yul-Isabelle; \\\n\tcd libabicoder; \\\n\tCXX=clang++ CXXFLAGS=\"-stdlib=libc++ -pthread\" make; \\\n\tcp libabicoder.a /usr/lib; \\\n\tcp abicoder.hpp /usr/include; \\\n\trm -rf /usr/src/Yul-Isabelle\n\nFROM base\nCOPY --from=libraries /usr/lib /usr/lib\nCOPY --from=libraries /usr/bin /usr/bin\nCOPY --from=libraries /usr/include /usr/include\nCOPY --from=libraries /opt/eldarica /opt/eldarica\nENV PATH=\"$PATH:/opt/eldarica\"\n"
  },
  {
    "path": "scripts/docker/buildpack-deps/Dockerfile.ubuntu2404",
    "content": "# vim:syntax=dockerfile\n#------------------------------------------------------------------------------\n# Dockerfile for building and testing Solidity Compiler on CI\n# Target: Ubuntu 19.04 (Disco Dingo)\n# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps\n#\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016-2024 solidity contributors.\n#------------------------------------------------------------------------------\nFROM buildpack-deps:noble AS base\nLABEL version=\"7\"\n\nARG DEBIAN_FRONTEND=noninteractive\n\n# From Python3.11, pip requires a virtual environment, and will thus terminate when installing packages globally.\n# Since we're building this image from scratch, it's perfectly fine to use the below flag.\nENV PIP_BREAK_SYSTEM_PACKAGES=1\n\nRUN set -ex; \\\n\tz3_version=\"4.13.3\"; \\\n\tdist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \\\n\techo \"deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main\" >> /etc/apt/sources.list ; \\\n\tapt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \\\n\tapt-get update; \\\n\tapt-get install -qqy --no-install-recommends \\\n\t\tbuild-essential \\\n\t\tcmake \\\n\t\tccache \\\n\t\tjq \\\n\t\tlibboost-filesystem-dev \\\n\t\tlibboost-program-options-dev \\\n\t\tlibboost-system-dev \\\n\t\tlibboost-test-dev \\\n\t\tlibcln-dev \\\n\t\tlocales-all \\\n\t\tlsof \\\n\t\tninja-build \\\n\t\tpython3-pip \\\n\t\tpython3-sphinx \\\n\t\tsoftware-properties-common \\\n\t\tsudo \\\n\t\tunzip \\\n\t\tzip; \\\n\tpip3 install \\\n\t\tcodecov \\\n\t\tcolorama \\\n\t\tdeepdiff \\\n\t\tparsec \\\n\t\tpygments-lexer-solidity \\\n\t\tpylint \\\n\t\trequests \\\n\t\ttabulate \\\n\t\tz3-solver==\"${z3_version}\";\n\n# Eldarica\nRUN set -ex; \\\n\tapt-get update; \\\n\tapt-get install -qqy \\\n\t\topenjdk-11-jre; \\\n\teldarica_version=\"2.1\"; \\\n\twget \"https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip\" -O /opt/eld_binaries.zip; \\\n\ttest \"$(sha256sum /opt/eld_binaries.zip)\" = \"0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c  /opt/eld_binaries.zip\"; \\\n\tunzip /opt/eld_binaries.zip -d /opt; \\\n\trm -f /opt/eld_binaries.zip;\n\n# CVC5\nRUN set -ex; \\\n\tcvc5_version=\"1.2.0\"; \\\n\tcvc5_archive_name=\"cvc5-Linux-x86_64-static\"; \\\n\twget \"https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip\" -O /opt/cvc5.zip; \\\n\ttest \"$(sha256sum /opt/cvc5.zip)\" = \"d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e  /opt/cvc5.zip\"; \\\n\tunzip -j /opt/cvc5.zip \"${cvc5_archive_name}/bin/cvc5\" -d /usr/bin; \\\n\trm -f /opt/cvc5.zip;\n\nFROM base AS libraries\n\n# EVMONE\nRUN set -ex; \\\n\twget -O /usr/src/evmone.tar.gz https://github.com/ipsilon/evmone/releases/download/v0.16.0/evmone-0.16.0-linux-x86_64.tar.gz; \\\n\ttest \"$(sha256sum /usr/src/evmone.tar.gz)\" = \"09a59e07bde21bbf08b821db9097ef4db9ff06f1484b7b14497a16a701e72233  /usr/src/evmone.tar.gz\"; \\\n\tcd /usr; \\\n\ttar -xf /usr/src/evmone.tar.gz; \\\n\trm -rf /usr/src/evmone.tar.gz\n\nFROM base\nCOPY --from=libraries /usr/lib /usr/lib\nCOPY --from=libraries /usr/bin /usr/bin\nCOPY --from=libraries /usr/include /usr/include\nCOPY --from=libraries /opt/eldarica /opt/eldarica\nENV PATH=\"$PATH:/opt/eldarica\"\n"
  },
  {
    "path": "scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.arm",
    "content": "# vim:syntax=dockerfile\n#------------------------------------------------------------------------------\n# Dockerfile for building and testing Solidity Compiler on CI\n# Target: Ubuntu 24.04 (Noble)\n# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps\n#\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016-2025 solidity contributors.\n#------------------------------------------------------------------------------\nFROM --platform=linux/arm64 buildpack-deps:noble AS base\nLABEL version=\"3\"\n\nARG DEBIAN_FRONTEND=noninteractive\n\n# From Python3.11, pip requires a virtual environment, and will thus terminate when installing packages globally.\n# Since we're building this image from scratch, it's perfectly fine to use the below flag.\nENV PIP_BREAK_SYSTEM_PACKAGES=1\n\nRUN <<-EOF\n    set -ex\n    z3_version=\"4.13.3\"\n    dist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2)\n    echo \"deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main\" >> /etc/apt/sources.list\n    apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9\n    apt-get update\n    apt-get install --quiet=2 --no-install-recommends \\\n        build-essential \\\n        cmake \\\n        ccache \\\n        jq \\\n        libboost-filesystem-dev \\\n        libboost-program-options-dev \\\n        libboost-system-dev \\\n        libboost-test-dev \\\n        libcln-dev \\\n        locales-all \\\n        lsof \\\n        ninja-build \\\n        python3-pip \\\n        python3-sphinx \\\n        software-properties-common \\\n        sudo \\\n        unzip \\\n        zip\n    pip3 install \\\n        codecov \\\n        colorama \\\n        deepdiff \\\n        parsec \\\n        pygments-lexer-solidity \\\n        pylint \\\n        requests \\\n        tabulate \\\n        z3-solver==\"${z3_version}\"\nEOF\n\n# Eldarica\nRUN <<-EOF\n    set -ex\n    apt-get update\n    apt-get install --quiet=2 openjdk-11-jre\n    eldarica_version=\"2.1\"\n    wget \"https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip\" -O /opt/eld_binaries.zip\n    test \"$(sha256sum /opt/eld_binaries.zip)\" = \"0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c  /opt/eld_binaries.zip\"\n    unzip /opt/eld_binaries.zip -d /opt\n    rm -f /opt/eld_binaries.zip\nEOF\n\n# CVC5\nRUN <<-EOF\n    set -ex\n    cvc5_version=\"1.2.0\"\n    cvc5_archive_name=\"cvc5-Linux-arm64-static\"\n    wget \"https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip\" -O /opt/cvc5.zip\n    test \"$(sha256sum /opt/cvc5.zip)\" = \"142ac177af1ce37922308f69fe519d06e6cb4d0a62a312f28c25001e94c2fb56  /opt/cvc5.zip\"\n    unzip -j /opt/cvc5.zip \"${cvc5_archive_name}/bin/cvc5\" -d /usr/bin\n    rm -f /opt/cvc5.zip\nEOF\n\nFROM base AS libraries\n\n# EVMONE (built from source, no arm release available)\nRUN <<-EOF\n    set -ex\n    git clone --depth=1 --recurse-submodules --branch v0.16.0 https://github.com/ipsilon/evmone.git /tmp/evmone\n    mkdir -p /tmp/evmone/build\n    cd /tmp/evmone/build\n    cmake ..\n    make -j\n    make install\nEOF\n\nFROM base\nCOPY --from=libraries /usr/local/lib/libevmone* /usr/lib\nCOPY --from=libraries /usr/lib /usr/lib\nCOPY --from=libraries /usr/bin /usr/bin\nCOPY --from=libraries /usr/include /usr/include\nCOPY --from=libraries /opt/eldarica /opt/eldarica\nENV PATH=\"$PATH:/opt/eldarica\"\n"
  },
  {
    "path": "scripts/docker/buildpack-deps/Dockerfile.ubuntu2404.clang",
    "content": "# vim:syntax=dockerfile\n#------------------------------------------------------------------------------\n# Dockerfile for building and testing Solidity Compiler on CI\n# Target: Ubuntu 19.04 (Disco Dingo) Clang variant\n# URL: https://hub.docker.com/r/ethereum/solidity-buildpack-deps\n#\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016-2024 solidity contributors.\n#------------------------------------------------------------------------------\nFROM buildpack-deps:noble AS base\nLABEL version=\"8\"\n\nARG DEBIAN_FRONTEND=noninteractive\n\n# From Python3.11, pip requires a virtual environment, and will thus terminate when installing packages globally.\n# Since we're building this image from scratch, it's perfectly fine to use the below flag.\nENV PIP_BREAK_SYSTEM_PACKAGES=1\n\nRUN set -ex; \\\n\tz3_version=\"4.13.3\"; \\\n\tdist=$(grep DISTRIB_CODENAME /etc/lsb-release | cut -d= -f2); \\\n\techo \"deb http://ppa.launchpad.net/ethereum/cpp-build-deps/ubuntu $dist main\" >> /etc/apt/sources.list ; \\\n\tapt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1c52189c923f6ca9 ; \\\n\tapt-get update; \\\n\tapt-get install -qqy --no-install-recommends \\\n\t\tbuild-essential \\\n\t\tclang \\\n\t\tcmake \\\n\t\tccache \\\n\t\tjq \\\n\t\tlibboost-filesystem-dev \\\n\t\tlibboost-program-options-dev \\\n\t\tlibboost-system-dev \\\n\t\tlibboost-test-dev \\\n\t\tlibclang-rt-dev \\\n\t\tlibcln-dev \\\n\t\tlsof \\\n\t\tninja-build \\\n\t\tpython3-pip \\\n\t\tsoftware-properties-common \\\n\t\tsudo; \\\n\tpip3 install \\\n\t\tcodecov \\\n\t\tcolorama \\\n\t\tdeepdiff \\\n\t\tparsec \\\n\t\tpygments-lexer-solidity \\\n\t\tpylint \\\n\t\trequests \\\n\t\ttabulate \\\n\t\tz3-solver==\"${z3_version}\";\n\n# Eldarica\nRUN set -ex; \\\n\tapt-get update; \\\n\tapt-get install -qy \\\n\t\topenjdk-11-jre \\\n\t\tunzip; \\\n\teldarica_version=\"2.1\"; \\\n\twget \"https://github.com/uuverifiers/eldarica/releases/download/v${eldarica_version}/eldarica-bin-${eldarica_version}.zip\" -O /opt/eld_binaries.zip; \\\n\ttest \"$(sha256sum /opt/eld_binaries.zip)\" = \"0ac43f45c0925383c9d2077f62bbb515fd792375f3b2b101b30c9e81dcd7785c  /opt/eld_binaries.zip\"; \\\n\tunzip /opt/eld_binaries.zip -d /opt; \\\n\trm -f /opt/eld_binaries.zip;\n\n# CVC5\nRUN set -ex; \\\n\tcvc5_version=\"1.2.0\"; \\\n\tcvc5_archive_name=\"cvc5-Linux-x86_64-static\"; \\\n\twget \"https://github.com/cvc5/cvc5/releases/download/cvc5-${cvc5_version}/${cvc5_archive_name}.zip\" -O /opt/cvc5.zip; \\\n\ttest \"$(sha256sum /opt/cvc5.zip)\" = \"d18f174ff9a11923c32c3f871f844ed16bd77a28f51050b8e7c8d821c98a1c2e  /opt/cvc5.zip\"; \\\n\tunzip -j /opt/cvc5.zip \"${cvc5_archive_name}/bin/cvc5\" -d /usr/bin; \\\n\trm -f /opt/cvc5.zip;\n\nFROM base AS libraries\n\nENV CC clang\nENV CXX clang++\n\n# EVMONE\nRUN set -ex; \\\n\twget -O /usr/src/evmone.tar.gz https://github.com/ipsilon/evmone/releases/download/v0.16.0/evmone-0.16.0-linux-x86_64.tar.gz; \\\n\ttest \"$(sha256sum /usr/src/evmone.tar.gz)\" = \"09a59e07bde21bbf08b821db9097ef4db9ff06f1484b7b14497a16a701e72233  /usr/src/evmone.tar.gz\"; \\\n\tcd /usr; \\\n\ttar -xf /usr/src/evmone.tar.gz; \\\n\trm -rf /usr/src/evmone.tar.gz\n\nFROM base\nCOPY --from=libraries /usr/lib /usr/lib\nCOPY --from=libraries /usr/bin /usr/bin\nCOPY --from=libraries /usr/include /usr/include\nCOPY --from=libraries /opt/eldarica /opt/eldarica\nENV PATH=\"$PATH:/opt/eldarica\"\n"
  },
  {
    "path": "scripts/docker/buildpack-deps/README.md",
    "content": "# buildpack-deps docker images\n\nThe `buildpack-deps` docker images are used to compile and test solidity within our CI.\n\n## GitHub Workflow\n\nThe creation of the images is triggered by a single workflow, defined in `.github/workflows/buildpack-deps.yml`.\nFor each resulting `buildpack-deps` docker image a strategy is defined in the workflow file - the image variant.\nThe workflow gets triggered, if any Dockerfile defined in `scripts/docker/buildpack-deps/Dockerfile.*` was changed\nwithin the PR.\n\n### Versioning\n\nThe version of the docker images can be defined within the Dockerfile with `LABEL version`. A new docker image\nwill only be created and pushed, if the new version is incremented by `1` compared with the version of the Dockerfile\nlocated in `develop`.\n\n### Build, Test & Push\n\nNote that the whole workflow - including all defined strategies (image variants) - will be triggered,\neven if only a single Dockerfile was changed. The full workflow will only get executed, if the corresponding\nDockerfile was changed. The execution of workflows of unchanged Dockerfiles will not continue and just return success.\nSee `scripts/ci/docker_upgrade.sh`.\n\nIf the version check was successful, the docker image will be built using the Dockerfile located in\n`scripts/docker/buildpack-deps/Dockerfile.*`.\n\nThe resulting docker image will be tested by executing the corresponding `scripts/ci/buildpack-deps_test_*` scripts.\nSome of these scripts are symlinked to `scripts/ci/build.sh`, except the following two:\n * `buildpack-deps-ubuntu.clang.ossfuzz` => `scripts/ci/build_ossfuzz.sh`\n * `buildpack-deps_test_emscripten.sh` => `scripts/ci/build_emscripten.sh`\n\nThese scripts `scripts/ci/build.sh` and `scripts/ci/build_ossfuzz.sh` are also used by CircleCI, see `.circleci/config.yml`.\n\nIf the tests passed successfully, the docker image will get tagged by the version defined within the corresponding `Dockerfile`.\nFinally, a comment will be added to the PR that contains the full repository, version and repository digest\nof the freshly created docker image.\n\nThe files `.circleci/config.yml` and `scripts/build_emscripten.sh` need to be updated with the new hash posted in the comment.\n"
  },
  {
    "path": "scripts/docker/buildpack-deps/emscripten.jam",
    "content": "# Modified version of emscripten.jam from https://github.com/tee3/boost-build-emscripten\n# which is released under the following license:\n#\n# Boost Software License - Version 1.0 - August 17th, 2003\n#\n# Permission is hereby granted, free of charge, to any person or organization\n# obtaining a copy of the software and accompanying documentation covered by\n# this license (the \"Software\") to use, reproduce, display, distribute,\n# execute, and transmit the Software, and to prepare derivative works of the\n# Software, and to permit third-parties to whom the Software is furnished to\n# do so, all subject to the following:\n#\n# The copyright notices in the Software and this entire statement, including\n# the above license grant, this restriction and the following disclaimer,\n# must be included in all copies of the Software, in whole or in part, and\n# all derivative works of the Software, unless such copies or derivative\n# works are solely in the form of machine-executable object code generated by\n# a source language processor.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\n# SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\n# FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\n# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n# DEALINGS IN THE SOFTWARE.\n#\n# Boost.Build support for Emscripten.\n#\n# @todo add support for dynamic linking\n# @todo add support for --js-library, --pre-js, and --post-js options\n\nimport generators ;\nimport type ;\nimport toolset ;\nimport feature ;\nimport common ;\nimport errors ;\n\nif [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]\n{\n  .debug-configuration = true ;\n}\n\n# add an emscripten toolset\nfeature.extend toolset : emscripten ;\n\n# extend the target-os list to include emscripten\nfeature.extend target-os : emscripten ;\n# make emscripten the default target-os when compiling with the emscripten toolset\nfeature.set-default target-os : emscripten ;\n\n# initialize the emscripten toolset\nrule init ( version ? : command * : options * )\n{\n  command = [ common.get-invocation-command emscripten : em++ : $(command) ] ;\n\n  if $(command)\n  {\n    version ?= [ MATCH \"^([0-9.]+)\" : [ SHELL \\\"\"$(command)\\\" --version\" ] ] ;\n    if $(version)\n    {\n      local actual_version = [ MATCH \"^([0-9.]+)\" : [ SHELL \\\"\"$(command)\\\" --version\" ] ] ;\n      if $(actual_version) != $(version)\n      {\n        errors.user-error \"emscripten: detected version $(actual_version) does not match desired $(version)\" ;\n      }\n    }\n  }\n  else\n  {\n    errors.user-error \"emscripten: em++ not found\" ;\n  }\n\n  local condition = [ common.check-init-parameters emscripten : version $(version) ] ;\n\n  common.handle-options emscripten : $(condition) : $(command) : $(options) ;\n\n  # @todo this seems to be the right way, but this is a list somehow\n  toolset.add-requirements <toolset>emscripten:<testing.launcher>node ;\n\n  toolset.flags emscripten.compile STDHDRS $(condition) : /emsdk/upstream/emscripten/system/include ;\n  toolset.flags emscripten.link STDLIBPATH $(condition) : /emsdk/upstream/emscripten/system/lib ;\n  toolset.flags emscripten AR $(condition) : /emsdk/upstream/emscripten/emar ;\n  toolset.flags emscripten RANLIB $(condition) : /emsdk/upstream/emscripten/emranlib ;\n}\n\ntype.set-generated-target-suffix EXE : <toolset>emscripten : js ;\n#type.set-generated-target-suffix STATIC_LIB : <toolset>emscripten : bc ;\n#type.set-generated-target-suffix SHARED_LIB : <toolset>emscripten : bc ;\n#type.set-generated-target-suffix OBJ : <toolset>emscripten : bc ;\n\ngenerators.register-linker emscripten.link : OBJ STATIC_LIB : EXE : <toolset>emscripten ;\n\ngenerators.register-archiver emscripten.archive : OBJ : STATIC_LIB : <toolset>emscripten ;\n\ngenerators.register-c-compiler emscripten.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>emscripten ;\ngenerators.register-c-compiler emscripten.compile.c.preprocess   : C   : PREPROCESSED_C   : <toolset>emscripten ;\ngenerators.register-c-compiler emscripten.compile.c++ : CPP : OBJ : <toolset>emscripten ;\ngenerators.register-c-compiler emscripten.compile.c : C : OBJ : <toolset>emscripten ;\n\n# Declare flags\n\ntoolset.flags emscripten.compile OPTIONS <optimization>off   : -O0 ;\ntoolset.flags emscripten.compile OPTIONS <optimization>speed : -O3 ;\ntoolset.flags emscripten.compile OPTIONS <optimization>space : -Os ;\n\ntoolset.flags emscripten.compile OPTIONS <inlining>off  : -fno-inline ;\ntoolset.flags emscripten.compile OPTIONS <inlining>on   : -Wno-inline ;\ntoolset.flags emscripten.compile OPTIONS <inlining>full : -finline-functions -Wno-inline ;\n\ntoolset.flags emscripten.compile OPTIONS <warnings>off : -w ;\ntoolset.flags emscripten.compile OPTIONS <warnings>on  : -Wall ;\ntoolset.flags emscripten.compile OPTIONS <warnings>all : -Wall -pedantic ;\ntoolset.flags emscripten.compile OPTIONS <warnings-as-errors>on : -Werror ;\n\ntoolset.flags emscripten.compile OPTIONS <debug-symbols>on : -g ;\ntoolset.flags emscripten.compile OPTIONS <profiling>on : -pg ;\n\ntoolset.flags emscripten.compile.c++ OPTIONS <rtti>off : -fno-rtti ;\ntoolset.flags emscripten.compile.c++ OPTIONS <exception-handling>off : -fno-exceptions ;\n\ntoolset.flags emscripten.compile USER_OPTIONS <cflags> ;\ntoolset.flags emscripten.compile.c++ USER_OPTIONS <cxxflags> ;\ntoolset.flags emscripten.compile DEFINES <define> ;\ntoolset.flags emscripten.compile INCLUDES <include> ;\ntoolset.flags emscripten.compile.c++ TEMPLATE_DEPTH <c++-template-depth> ;\ntoolset.flags emscripten.compile.fortran USER_OPTIONS <fflags> ;\n\ntoolset.flags emscripten.link DEFAULTS : -Wno-warn-absolute-paths ;\n\ntoolset.flags emscripten.link LIBRARY_PATH <library-path> ;\ntoolset.flags emscripten.link FINDLIBS_ST <find-static-library> ;\ntoolset.flags emscripten.link FINDLIBS_SA <find-shared-library> ;\ntoolset.flags emscripten.link LIBRARIES <library-file> ;\n\ntoolset.flags emscripten.link OPTIONS <linkflags> ;\n\ntoolset.flags emscripten.archive AROPTIONS <archiveflags> ;\n\nrule compile.c++ ( targets * : sources * : properties * )\n{\n    # Some extensions are compiled as C++ by default. For others, we need to\n    # pass -x c++. We could always pass -x c++ but distcc does not work with it.\n    if ! $(>:S) in .cc .cp .cxx .cpp .c++ .C\n    {\n        LANG on $(<) = \"-x c++\" ;\n    }\n}\n\nrule compile.c ( targets * : sources * : properties * )\n{\n    LANG on $(<) = \"-x c\" ;\n}\n\nactions compile.c++\n{\n    \"$(CONFIG_COMMAND)\" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I\"$(INCLUDES)\" -c -o \"$(<:W)\" \"$(>:W)\"\n}\n\nactions compile.c\n{\n    \"$(CONFIG_COMMAND)\" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I\"$(INCLUDES)\" -c -o \"$(<)\" \"$(>)\"\n}\n\nactions compile.c++.preprocess\n{\n    \"$(CONFIG_COMMAND)\" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I\"$(INCLUDES)\" \"$(>:W)\" -E >\"$(<:W)\"\n}\n\nactions compile.c.preprocess\n{\n    \"$(CONFIG_COMMAND)\" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I\"$(INCLUDES)\" \"$(>)\" -E >$(<)\n}\n\nactions link\n{\n  \"$(CONFIG_COMMAND)\" $(DEFAULTS) $(OPTIONS) -L\"$(LIBRARY_PATH:W)\" -L\"$(STDLIBPATH:W)\" -o \"$(<:W)\" \"$(>:W)\" -l\"$(LIBRARIES:W)\" -l\"$(STDLIBRARIES:W)\"\n}\n\nRM = [ common.rm-command ] ;\nactions piecemeal archive\n{\n  $(RM) \"$(<)\"\n  $(AR) $(AROPTIONS) rc \"$(<:W)\" \"$(>:W)\"\n}\n"
  },
  {
    "path": "scripts/docker_deploy_manual.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nREPO_ROOT=\"$(dirname \"$0\")/..\"\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\nimage=\"ghcr.io/argotorg/solc\"\n\nif (( $# < 1 || $# > 3 )); then\n    fail \"Usage: $0 <tag/branch> [repo URL] [--no-push]\"\nfi\n\nbranch=\"$1\"\nrepo_url=\"${2:-https://github.com/argotorg/solidity.git}\"\n\nif (( $# >= 3 )); then\n    [[ $3 == --no-push ]] || fail \"Invalid flag: $3. Expected --no-push.\"\n    publish=false\nelse\n    publish=true\nfi\n\n# NOTE: Login to GHCR before running this script with a PAT:\n# echo $GHCR_TOKEN | docker login ghcr.io -u USERNAME --password-stdin\n#\n# Create a classic PAT with write:packages scope by visiting the following URL:\n# https://github.com/settings/tokens/new?scopes=write:packages\n\nDIR=$(mktemp -d)\n(\ncd \"$DIR\"\n\ngit clone --recursive --depth 2 \"$repo_url\" -b \"$branch\" solidity\ncd solidity\ncommithash=$(git rev-parse --short=8 HEAD)\necho -n \"$commithash\" > commit_hash.txt\nversion=$(\"$(dirname \"$0\")/get_version.sh\")\nif [ \"$branch\" = v\"$version\" ]\nthen\n    echo -n > prerelease.txt\nelse\n    date -u +\"nightly.%Y.%-m.%-d\" > prerelease.txt\nfi\n\nfunction tag_and_push\n{\n    docker tag \"$image:$1\" \"$image:$2\"\n    [[ $publish == false ]] || docker push \"$image:$2\"\n}\n\nrm -rf .git\ndocker buildx build -t \"$image\":build -f scripts/Dockerfile . --progress=plain\ntmp_container=$(docker create \"$image\":build sh)\n\n# Alpine image\nmkdir -p upload\ndocker cp \"${tmp_container}\":/usr/bin/solc upload/solc-static-linux\ndocker buildx build -t \"$image\":build-alpine -f scripts/Dockerfile_alpine . --progress=plain\n\nif [ \"$branch\" = \"develop\" ]\nthen\n    tag_and_push build nightly\n    tag_and_push build nightly-\"$version\"-\"$commithash\"\n    tag_and_push build-alpine nightly-alpine\n    tag_and_push build-alpine nightly-alpine-\"$version\"-\"$commithash\"\nelif [ \"$branch\" = v\"$version\" ]\nthen\n    tag_and_push build stable\n    tag_and_push build \"$version\"\n    tag_and_push build-alpine stable-alpine\n    tag_and_push build-alpine \"$version\"-alpine\nelse\n    echo \"Not publishing docker image from branch or tag $branch\"\nfi\n)\nrm -rf \"$DIR\"\n"
  },
  {
    "path": "scripts/docs_version_pragma_check.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016 solidity contributors.\n#------------------------------------------------------------------------------\n\n# This script verifies that the examples compile with the oldest version mentioned in the pragma.\n# It does not verify that it cannot be compiled with an older version\n# and it also does not verify that it can be compiled with the newest version compatible with the pragma.\n\nset -e\n\n## GLOBAL VARIABLES\n\nREPO_ROOT=$(cd \"$(dirname \"$0\")/..\" && pwd)\nSOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${REPO_ROOT}/build}\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n# shellcheck source=scripts/common_cmdline.sh\nsource \"${REPO_ROOT}/scripts/common_cmdline.sh\"\n\ndevelopmentVersion=$(\"$REPO_ROOT/scripts/get_version.sh\")\n\nfunction versionGreater\n{\n    v1=$1\n    v2=$2\n    # shellcheck disable=SC2206\n    ver1=( ${v1//./ } )\n    # shellcheck disable=SC2206\n    ver2=( ${v2//./ } )\n\n    if (( \"${ver1[0]}\" > \"${ver2[0]}\" ))\n    then\n        return 0\n    elif (( \"${ver1[0]}\" == \"${ver2[0]}\" )) && (( \"${ver1[1]}\" > \"${ver2[1]}\" ))\n    then\n        return 0\n    elif (( \"${ver1[0]}\" == \"${ver2[0]}\" )) && (( \"${ver1[1]}\" == \"${ver2[1]}\" )) && (( \"${ver1[2]}\" > \"${ver2[2]}\" ))\n    then\n        return 0\n    fi\n    return 1\n}\n\nfunction versionEqual\n{\n    if [[ \"$1\" == \"$2\" ]]\n    then\n        return 0\n    fi\n    return 1\n}\n\nfunction getAllAvailableVersions\n{\n    allVersions=()\n    local allListedVersions\n    mapfile -t allListedVersions <<< \"$(\n        wget -q -O- https://binaries.soliditylang.org/bin/list.txt |\n        grep -Po '(?<=soljson-v)\\d+.\\d+.\\d+(?=\\+commit)' |\n        sort -V\n    )\"\n    for listed in \"${allListedVersions[@]}\"\n    do\n        if versionGreater \"$listed\" \"0.4.10\"\n        then\n            allVersions+=( \"$listed\" )\n        fi\n    done\n}\n\nfunction findMinimalVersion\n{\n    local f=$1\n    local greater=false\n    local pragmaVersion\n\n    # Get minimum compiler version defined by pragma\n    if (grep -Po '(?<=pragma solidity >=)\\d+.\\d+.\\d+' \"$f\" >/dev/null)\n    then\n        pragmaVersion=\"$(grep -Po '(?<=pragma solidity >=)\\d+.\\d+.\\d+' \"$f\")\"\n        sign=\">=\"\n    elif (grep -Po '(?<=pragma solidity \\^)\\d+.\\d+.\\d+' \"$f\" >/dev/null)\n    then\n        pragmaVersion=\"$(grep -Po '(?<=pragma solidity \\^)\\d+.\\d+.\\d+' \"$f\")\"\n        sign=\"^\"\n    elif (grep -Po '(?<=pragma solidity >)\\d+.\\d+.\\d+' \"$f\" >/dev/null)\n    then\n        pragmaVersion=\"$(grep -Po '(?<=pragma solidity >)\\d+.\\d+.\\d+' \"$f\")\"\n        sign=\">\"\n        greater=true;\n    else\n        printError \"No valid pragma statement in file. Skipping...\"\n        return\n    fi\n\n    version=\"\"\n    for ver in \"${allVersions[@]}\" \"$developmentVersion\"\n    do\n        if versionGreater \"$ver\" \"$pragmaVersion\"\n        then\n            version=\"$ver\"\n            break\n        elif [[ \"$greater\" == false ]] && versionEqual \"$ver\" \"$pragmaVersion\"\n        then\n            version=\"$ver\"\n            break\n        fi\n    done\n\n    if [[ \"$version\" == \"\" ]]\n    then\n        printError \"No release ${sign}${pragmaVersion} was listed in available releases!\"\n        exit 1\n    fi\n}\n\nprintTask \"Verifying that all examples from the documentation have the correct version range...\"\nSOLTMPDIR=$(mktemp -d)\n(\n    set -e\n    cd \"$SOLTMPDIR\"\n    \"$REPO_ROOT\"/scripts/isolate_tests.py \"$REPO_ROOT\"/docs/\n\n    getAllAvailableVersions\n\n    for f in *.sol\n    do\n        # The contributors guide uses syntax tests, but we cannot\n        # really handle them here.\n        if grep -E 'DeclarationError:|// ----' \"$f\" >/dev/null\n        then\n            continue\n        fi\n        echo \"$f\"\n\n        opts=()\n        # We expect errors if explicitly stated, or if imports\n        # are used (in the style guide)\n        if ( ! grep -E \"This will not compile after\" \"$f\" >/dev/null && \\\n            grep -E \"This will not compile|import \\\"\" \"$f\" >/dev/null || \\\n            grep -R \"This will only compile via IR\" \"$f\" >/dev/null )\n        then\n            opts=(--expect-errors)\n        fi\n\n        # ignore warnings in this case\n        opts+=(--ignore-warnings)\n\n        findMinimalVersion \"$f\"\n        if [[ \"$version\" == \"\" ]]\n        then\n            continue\n        fi\n        if [[ \"$version\" == \"$developmentVersion\" ]]\n        then\n            printWarning \"Skipping unreleased development version $developmentVersion\"\n            continue\n        fi\n\n        opts+=(-v \"$version\")\n\n        solc_bin=\"solc-$version\"\n        echo \"$solc_bin\"\n        if [[ ! -f \"$solc_bin\" ]]\n        then\n            echo \"Downloading release from github...\"\n            if wget -q \"https://github.com/argotorg/solidity/releases/download/v$version/solc-static-linux\" >/dev/null\n            then\n                mv solc-static-linux \"$solc_bin\"\n            else\n                printError \"No release $version was found on github!\"\n                continue\n            fi\n        fi\n\n        ln -sf \"$solc_bin\" \"solc\"\n        chmod a+x solc\n\n        SOLC=\"$SOLTMPDIR/solc\" compileFull \"${opts[@]}\" \"$SOLTMPDIR/$f\"\n    done\n)\nrm -rf \"$SOLTMPDIR\"\necho \"Done.\"\n"
  },
  {
    "path": "scripts/download_ossfuzz_corpus.sh",
    "content": "#!/usr/bin/env sh\nset -e\ncd /tmp\ngit clone --depth 1 https://github.com/argotorg/solidity-fuzzing-corpus.git\n"
  },
  {
    "path": "scripts/error_codes.py",
    "content": "#! /usr/bin/env python3\nimport random\nimport re\nimport os\nimport getopt\nimport sys\nfrom os import path\n\nENCODING = \"utf-8\"\nSOURCE_FILE_PATTERN = r\"\\b\\d+_error\\b\"\n\n\ndef read_file(file_name):\n    content = None\n    _, tail = path.split(file_name)\n    is_latin = tail == \"invalid_utf8_sequence.sol\"\n    try:\n        with open(file_name, \"r\", encoding=\"latin-1\" if is_latin else ENCODING) as f:\n            content = f.read()\n    finally:\n        if content is None:\n            print(f\"Error reading: {file_name}\")\n    return content\n\n\ndef write_file(file_name, content):\n    with open(file_name, \"w\", encoding=ENCODING) as f:\n        f.write(content)\n\n\ndef in_comment(source, pos):\n    slash_slash_pos = source.rfind(\"//\", 0, pos)\n    lf_pos = source.rfind(\"\\n\", 0, pos)\n    if slash_slash_pos > lf_pos:\n        return True\n    slash_star_pos = source.rfind(\"/*\", 0, pos)\n    star_slash_pos = source.rfind(\"*/\", 0, pos)\n    return slash_star_pos > star_slash_pos\n\n\ndef find_ids_in_source_file(file_name, id_to_file_names):\n    source = read_file(file_name)\n    for m in re.finditer(SOURCE_FILE_PATTERN, source):\n        if in_comment(source, m.start()):\n            continue\n        underscore_pos = m.group(0).index(\"_\")\n        error_id = m.group(0)[0:underscore_pos]\n        if error_id in id_to_file_names:\n            id_to_file_names[error_id].append(file_name)\n        else:\n            id_to_file_names[error_id] = [file_name]\n\n\ndef find_ids_in_source_files(file_names):\n    \"\"\"Returns a dictionary with list of source files for every appearance of every id\"\"\"\n\n    id_to_file_names = {}\n    for file_name in file_names:\n        find_ids_in_source_file(file_name, id_to_file_names)\n    return id_to_file_names\n\n\ndef get_next_id(available_ids):\n    assert len(available_ids) > 0, \"Out of IDs\"\n    next_id = random.choice(list(available_ids))\n    available_ids.remove(next_id)\n    return next_id\n\n\ndef fix_ids_in_source_file(file_name, id_to_count, available_ids):\n    source = read_file(file_name)\n\n    k = 0\n    destination = []\n    for m in re.finditer(SOURCE_FILE_PATTERN, source):\n        destination.extend(source[k:m.start()])\n\n        underscore_pos = m.group(0).index(\"_\")\n        error_id = m.group(0)[0:underscore_pos]\n\n        # incorrect id or id has a duplicate somewhere\n        if not in_comment(source, m.start()) and (len(error_id) != 4 or error_id[0] == \"0\" or id_to_count[error_id] > 1):\n            assert error_id in id_to_count\n            new_id = get_next_id(available_ids)\n            assert new_id not in id_to_count\n            id_to_count[error_id] -= 1\n        else:\n            new_id = error_id\n\n        destination.extend(new_id + \"_error\")\n        k = m.end()\n\n    destination.extend(source[k:])\n\n    destination = ''.join(destination)\n    if source != destination:\n        write_file(file_name, destination)\n        print(f\"Fixed file: {file_name}\")\n\n\ndef fix_ids_in_source_files(file_names, id_to_count):\n    \"\"\"\n    Fixes ids in given source files;\n    id_to_count contains number of appearances of every id in sources\n    \"\"\"\n\n    available_ids = {str(error_id) for error_id in range(1000, 10000)} - id_to_count.keys()\n    for file_name in file_names:\n        fix_ids_in_source_file(file_name, id_to_count, available_ids)\n\n\ndef find_files(top_dir, sub_dirs, extensions):\n    \"\"\"Builds a list of files with given extensions in specified subdirectories\"\"\"\n\n    source_file_names = []\n    for directory in sub_dirs:\n        for root, _, file_names in os.walk(os.path.join(top_dir, directory), onerror=lambda e: sys.exit(f\"Walk error: {e}\")):\n            for file_name in file_names:\n                _, ext = path.splitext(file_name)\n                if ext in extensions:\n                    source_file_names.append(path.join(root, file_name))\n\n    return source_file_names\n\n\ndef find_ids_in_test_file(file_name):\n    source = read_file(file_name)\n    pattern = r\"^// (.*Error|Warning|Info) \\d\\d\\d\\d:\"\n    return {m.group(0)[-5:-1] for m in re.finditer(pattern, source, flags=re.MULTILINE)}\n\n\ndef find_ids_in_test_files(file_names):\n    \"\"\"Returns a set containing all ids in tests\"\"\"\n\n    ids = set()\n    for file_name in file_names:\n        ids |= find_ids_in_test_file(file_name)\n    return ids\n\n\ndef find_ids_in_cmdline_test_err(file_name):\n    source = read_file(file_name)\n    pattern = r' \\(\\d\\d\\d\\d\\):'\n    return {m.group(0)[-6:-2] for m in re.finditer(pattern, source, flags=re.MULTILINE)}\n\n\ndef print_ids(ids):\n    for k, error_id in enumerate(sorted(ids)):\n        if k % 10 > 0:\n            print(\" \", end=\"\")\n        elif k > 0:\n            print()\n        print(error_id, end=\"\")\n\n\ndef print_ids_per_file(ids, id_to_file_names, top_dir):\n    file_name_to_ids = {}\n    for error_id in ids:\n        for file_name in id_to_file_names[error_id]:\n            relpath = path.relpath(file_name, top_dir)\n            if relpath not in file_name_to_ids:\n                file_name_to_ids[relpath] = []\n            file_name_to_ids[relpath].append(error_id)\n\n    for file_name in sorted(file_name_to_ids):\n        print(file_name)\n        for error_id in sorted(file_name_to_ids[file_name]):\n            print(f\" {error_id}\", end=\"\")\n        print()\n\n\ndef examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False):\n    test_sub_dirs = [\n        path.join(\"test\", \"libsolidity\", \"natspecJSON\"),\n        path.join(\"test\", \"libsolidity\", \"smtCheckerTests\"),\n        path.join(\"test\", \"libsolidity\", \"syntaxTests\"),\n        path.join(\"test\", \"libyul\", \"yulSyntaxTests\")\n    ]\n    test_file_names = find_files(\n        top_dir,\n        test_sub_dirs,\n        [\".sol\", \".yul\"]\n    )\n    source_ids = source_id_to_file_names.keys()\n    test_ids = find_ids_in_test_files(test_file_names)\n\n    # special case, we are interested in warnings which are ignored by regular tests:\n    # Warning (1878): SPDX license identifier not provided in source file. ....\n    # Warning (3420): Source file does not specify required compiler version!\n    test_ids |= find_ids_in_cmdline_test_err(path.join(top_dir, \"test\", \"cmdlineTests\", \"error_codes\", \"err\"))\n\n    # white list of ids which are not covered by tests\n    white_ids = {\n        \"9804\", # Tested in test/libyul/ObjectParser.cpp.\n        \"1544\",\n        \"1749\",\n        \"2674\",\n        \"6367\",\n        \"8387\",\n        \"3805\", # \"This is a pre-release compiler version, please do not use it in production.\"\n                # The warning may or may not exist in a compiler build.\n        \"4591\", # \"There are more than 256 warnings. Ignoring the rest.\"\n                # Due to 3805, the warning lists look different for different compiler builds.\n        \"1920\", # Unimplemented feature error from YulStack (currently there are no UnimplementedFeatureErrors thrown by libyul)\n        \"7053\", # Unimplemented feature error (parsing stage), currently has no tests\n        \"2339\", # SMTChecker, covered by CL tests\n        \"6240\", # SMTChecker, covered by CL tests\n        \"2788\", # SMTChecker: BMC: verification condition(s) could not be proved\n        \"1733\", # AsmAnalysis: expecting bool expression (everything is implicitly bool without types in Yul)\n        \"9547\", # AsmAnalysis: assigning incompatible types in Yul (whitelisted as there are currently no types)\n        \"5026\", # ContractLevelChecker: too difficult to exceed transient storage max size due to only value types supported.\n    }\n    assert len(test_ids & white_ids) == 0, \"The sets are not supposed to intersect\"\n    test_ids |= white_ids\n\n    test_only_ids = test_ids - source_ids\n    source_only_ids = source_ids - test_ids\n\n    if not new_ids_only:\n        print(f\"IDs in source files: {len(source_ids)}\")\n        print(f\"IDs in test files  : {len(test_ids)} ({len(test_ids) - len(source_ids)})\")\n        print()\n\n        if len(test_only_ids) != 0:\n            print(\"Error. The following error codes found in tests, but not in sources:\")\n            print_ids(test_only_ids)\n            return False\n\n        if len(source_only_ids) != 0:\n            print(\"The following error codes found in sources, but not in tests:\")\n            print_ids_per_file(source_only_ids, source_id_to_file_names, top_dir)\n            print(\"\\n\\nPlease make sure to add appropriate tests.\")\n            return False\n\n    old_source_only_ids = {\n        \"1218\",\n        \"1584\",\n        \"1823\",\n        \"1988\",\n        \"2066\",\n        \"2833\",\n        \"3356\",\n        \"3893\",\n        \"3996\",\n        \"4010\",\n        \"4458\",\n        \"4802\",\n        \"4902\",\n        \"5272\",\n        \"5798\",\n        \"5840\",\n        \"7128\",\n        \"7400\",\n        \"7589\",\n        \"7593\",\n        \"7649\",\n        \"7710\",\n        \"8065\",\n        \"8084\",\n        \"8140\",\n        \"8158\",\n        \"8312\",\n        \"8592\",\n        \"9134\",\n        \"9609\",\n    }\n\n    # TODO Cover these with tests and remove from this list as the development of experimental\n    # TODO Solidity progresses. The aim should be to completely get rid of `experimental_source_only_ids`.\n    experimental_source_only_ids = {\n        \"1017\",\n        \"1439\",\n        \"1723\",\n        \"1741\",\n        \"1801\",\n        \"1807\",\n        \"2015\",\n        \"2345\",\n        \"2399\",\n        \"2599\",\n        \"2655\",\n        \"2934\",\n        \"3101\",\n        \"3111\",\n        \"3195\",\n        \"3520\",\n        \"3573\",\n        \"3654\",\n        \"4316\",\n        \"4337\",\n        \"4496\",\n        \"4504\",\n        \"4686\",\n        \"4767\",\n        \"4873\",\n        \"4955\",\n        \"5044\",\n        \"5094\",\n        \"5096\",\n        \"5104\",\n        \"5195\",\n        \"5262\",\n        \"5348\",\n        \"5360\",\n        \"5387\",\n        \"5577\",\n        \"5714\",\n        \"5731\",\n        \"5755\",\n        \"5904\",\n        \"6175\",\n        \"6387\",\n        \"6388\",\n        \"6460\",\n        \"6620\",\n        \"6739\",\n        \"6948\",\n        \"7341\",\n        \"7428\",\n        \"7531\",\n        \"8379\",\n        \"8809\",\n        \"8953\",\n        \"9159\",\n        \"9173\",\n        \"9282\",\n        \"9603\",\n        \"9658\",\n        \"9988\",\n    }\n\n    new_source_only_ids = source_only_ids - old_source_only_ids - experimental_source_only_ids\n    if len(new_source_only_ids) != 0:\n        print(\"The following new error code(s), not covered by tests, found:\")\n        print_ids(new_source_only_ids)\n        print(\n            \"\\nYou can:\\n\"\n            \"- create appropriate test(s);\\n\"\n            \"- add the error code(s) to old_source_only_ids in error_codes.py\\n\"\n            \"  (to silence the checking script, with a promise to add a test later);\\n\"\n            \"- add the error code(s) to white_ids in error_codes.py\\n\"\n            \"  (for rare cases when the error is not supposed to be tested)\"\n        )\n        return False\n\n    return True\n\n\ndef main(argv):\n    check = False\n    fix = False\n    no_confirm = False\n    examine_coverage = False\n    next_id = False\n    opts, _args = getopt.getopt(argv, \"\", [\"check\", \"fix\", \"no-confirm\", \"examine-coverage\", \"next\"])\n\n    for opt, _arg in opts:\n        if opt == \"--check\":\n            check = True\n        elif opt == \"--fix\":\n            fix = True\n        elif opt == \"--no-confirm\":\n            no_confirm = True\n        elif opt == \"--examine-coverage\":\n            examine_coverage = True\n        elif opt == \"--next\":\n            next_id = True\n\n    if [check, fix, examine_coverage, next_id].count(True) != 1:\n        print(\"usage: python error_codes.py --check | --fix [--no-confirm] | --examine-coverage | --next\")\n        sys.exit(1)\n\n    cwd = os.getcwd()\n\n    source_file_names = find_files(\n        cwd,\n        [\"libevmasm\", \"liblangutil\", \"libsolc\", \"libsolidity\", \"libsolutil\", \"libyul\", \"solc\"],\n        [\".h\", \".cpp\"]\n    )\n    source_id_to_file_names = find_ids_in_source_files(source_file_names)\n\n    ok = True\n    for error_id in sorted(source_id_to_file_names):\n        if len(error_id) != 4:\n            print(f\"ID {error_id} length != 4\")\n            ok = False\n        if error_id[0] == \"0\":\n            print(f\"ID {error_id} starts with zero\")\n            ok = False\n        if len(source_id_to_file_names[error_id]) > 1:\n            print(f\"ID {error_id} appears {len(source_id_to_file_names[error_id])} times\")\n            ok = False\n\n    if examine_coverage:\n        if not ok:\n            print(\"Incorrect IDs have to be fixed before applying --examine-coverage\")\n            sys.exit(1)\n        res = 0 if examine_id_coverage(cwd, source_id_to_file_names) else 1\n        sys.exit(res)\n\n    ok &= examine_id_coverage(cwd, source_id_to_file_names, new_ids_only=True)\n\n    random.seed()\n\n    if next_id:\n        if not ok:\n            print(\"Incorrect IDs have to be fixed before applying --next\")\n            sys.exit(1)\n        available_ids = {str(error_id) for error_id in range(1000, 10000)} - source_id_to_file_names.keys()\n        next_id = get_next_id(available_ids)\n        print(f\"Next ID: {next_id}\")\n        sys.exit(0)\n\n    if ok:\n        print(\"No incorrect IDs found\")\n        sys.exit(0)\n\n    if check:\n        sys.exit(1)\n\n    assert fix, \"Unexpected state, should not come here without --fix\"\n\n    if not no_confirm:\n        answer = input(\n            \"\\nDo you want to fix incorrect IDs?\\n\"\n            \"Please commit current changes first, and review the results when the script finishes.\\n\"\n            \"[Y/N]? \"\n        )\n        while len(answer) == 0 or answer not in \"YNyn\":\n            answer = input(\"[Y/N]? \")\n        if answer not in \"yY\":\n            sys.exit(1)\n\n    # number of appearances for every id\n    source_id_to_count = { error_id: len(file_names) for error_id, file_names in source_id_to_file_names.items() }\n\n    fix_ids_in_source_files(source_file_names, source_id_to_count)\n    print(\"Fixing completed\")\n    sys.exit(2)\n\n\nif __name__ == \"__main__\":\n    main(sys.argv[1:])\n"
  },
  {
    "path": "scripts/externalTests/benchmark_diff.py",
    "content": "#!/usr/bin/env python3\n\nfrom argparse import ArgumentParser\nfrom dataclasses import dataclass\nfrom enum import Enum\nfrom pathlib import Path\nfrom textwrap import dedent\nfrom typing import Any, Mapping, Optional, Set, Sequence, Union\nimport json\nimport sys\n\n\nclass DiffMode(Enum):\n    IN_PLACE = 'inplace'\n    TABLE = 'table'\n\n\nclass DifferenceStyle(Enum):\n    ABSOLUTE = 'absolute'\n    RELATIVE = 'relative'\n    HUMANIZED = 'humanized'\n\n\nclass OutputFormat(Enum):\n    JSON = 'json'\n    CONSOLE = 'console'\n    MARKDOWN = 'markdown'\n\n\nDEFAULT_RELATIVE_PRECISION = 4\n\nDEFAULT_DIFFERENCE_STYLE = {\n    DiffMode.IN_PLACE: DifferenceStyle.ABSOLUTE,\n    DiffMode.TABLE: DifferenceStyle.HUMANIZED,\n}\nassert all(t in DiffMode for t in DEFAULT_DIFFERENCE_STYLE)\nassert all(d in DifferenceStyle for d in DEFAULT_DIFFERENCE_STYLE.values())\n\nDEFAULT_OUTPUT_FORMAT = {\n    DiffMode.IN_PLACE: OutputFormat.JSON,\n    DiffMode.TABLE: OutputFormat.CONSOLE,\n}\nassert all(m in DiffMode for m in DEFAULT_OUTPUT_FORMAT)\nassert all(o in OutputFormat for o in DEFAULT_OUTPUT_FORMAT.values())\n\n\nclass ValidationError(Exception):\n    pass\n\n\nclass CommandLineError(ValidationError):\n    pass\n\n\nclass BenchmarkDiffer:\n    difference_style: DifferenceStyle\n    relative_precision: Optional[int]\n    output_format: OutputFormat\n\n    def __init__(\n        self,\n        difference_style: DifferenceStyle,\n        relative_precision: Optional[int],\n        output_format: OutputFormat,\n    ):\n        self.difference_style = difference_style\n        self.relative_precision = relative_precision\n        self.output_format = output_format\n\n    def run(self, before: Any, after: Any) -> Optional[Union[dict, str, int, float]]:\n        if not isinstance(before, dict) or not isinstance(after, dict):\n            return self._diff_scalars(before, after)\n\n        if before.get('version') != after.get('version'):\n            return self._humanize_diff('!V')\n\n        diff = {}\n        for key in (set(before) | set(after)) - {'version'}:\n            value_diff = self.run(before.get(key), after.get(key))\n            if value_diff not in [None, {}]:\n                diff[key] = value_diff\n\n        return diff\n\n    def _diff_scalars(self, before: Any, after: Any) -> Optional[Union[str, int, float, dict]]:\n        assert not isinstance(before, dict) or not isinstance(after, dict)\n\n        if before is None and after is None:\n            return {}\n        if before is None:\n            return self._humanize_diff('!B')\n        if after is None:\n            return self._humanize_diff('!A')\n        if not isinstance(before, (int, float)) or not isinstance(after, (int, float)):\n            return self._humanize_diff('!T')\n\n        number_diff = self._diff_numbers(before, after)\n        if self.difference_style != DifferenceStyle.HUMANIZED:\n            return number_diff\n\n        return self._humanize_diff(number_diff)\n\n    def _diff_numbers(self, value_before: Union[int, float], value_after: Union[int, float]) -> Union[str, int, float]:\n        diff: Union[str, int, float]\n\n        if self.difference_style == DifferenceStyle.ABSOLUTE:\n            diff = value_after - value_before\n            if isinstance(diff, float) and diff.is_integer():\n                diff = int(diff)\n\n            return diff\n\n        if value_before == 0:\n            if value_after > 0:\n                return '+INF'\n            elif value_after < 0:\n                return '-INF'\n            else:\n                return 0\n\n        diff = (value_after - value_before) / abs(value_before)\n        if self.relative_precision is not None:\n            rounded_diff = round(diff, self.relative_precision)\n            if rounded_diff == 0 and diff < 0:\n                diff = '-0'\n            elif rounded_diff == 0 and diff > 0:\n                diff = '+0'\n            else:\n                diff = rounded_diff\n\n        if isinstance(diff, float) and diff.is_integer():\n            diff = int(diff)\n\n        return diff\n\n    def _humanize_diff(self, diff: Union[str, int, float]) -> str:\n        def wrap(value: str, symbol: str):\n            return f\"{symbol}{value}{symbol}\"\n\n        markdown = (self.output_format == OutputFormat.MARKDOWN)\n\n        if isinstance(diff, str) and diff.startswith('!'):\n            return wrap(diff, '`' if markdown else '')\n\n        value: Union[str, int, float]\n        if isinstance(diff, (int, float)):\n            value = diff * 100\n            if isinstance(value, float) and self.relative_precision is not None:\n                # The multiplication can result in new significant digits appearing. We need to reround.\n                # NOTE: round() works fine with negative precision.\n                value = round(value, self.relative_precision - 2)\n                if isinstance(value, float) and value.is_integer():\n                    value = int(value)\n            suffix = ''\n            prefix = ''\n            if diff < 0:\n                prefix = ''\n                if markdown:\n                    suffix += ' ✅'\n            elif diff > 0:\n                prefix = '+'\n                if markdown:\n                    suffix += ' ❌'\n            important = (diff != 0)\n        else:\n            value = diff\n            important = False\n            prefix = ''\n            suffix = ''\n\n        return wrap(\n            wrap(\n                f\"{prefix}{value}%{suffix}\",\n                '`' if markdown else ''\n            ),\n            '**' if important and markdown else ''\n        )\n\n\n@dataclass(frozen=True)\nclass DiffTable:\n    columns: Mapping[str, Sequence[Union[int, float, str]]]\n\n\nclass DiffTableSet:\n    table_headers: Sequence[str]\n    row_headers: Sequence[str]\n    column_headers: Sequence[str]\n\n    # Cells is a nested dict rather than a 3D array so that conversion to JSON is straightforward\n    cells: Mapping[str, Mapping[str, Mapping[str, Union[int, float, str]]]] # preset -> project -> attribute\n\n    def __init__(self, diff: dict):\n        self.table_headers = sorted(self._find_all_preset_names(diff))\n        self.column_headers = sorted(self._find_all_attribute_names(diff))\n        self.row_headers = sorted(project for project in diff)\n\n        # All dimensions must have unique values\n        assert len(self.table_headers) == len(set(self.table_headers))\n        assert len(self.column_headers) == len(set(self.column_headers))\n        assert len(self.row_headers) == len(set(self.row_headers))\n\n        self.cells = {\n            preset: {\n                project: {\n                    attribute: self._cell_content(diff, project, preset, attribute)\n                    for attribute in self.column_headers\n                }\n                for project in self.row_headers\n            }\n            for preset in self.table_headers\n        }\n\n    def calculate_row_column_width(self) -> int:\n        return max(len(h) for h in self.row_headers)\n\n    def calculate_column_widths(self, table_header: str) -> Sequence[int]:\n        assert table_header in self.table_headers\n\n        return [\n            max(\n                len(column_header),\n                max(\n                    len(str(self.cells[table_header][row_header][column_header]))\n                    for row_header in self.row_headers\n                )\n            )\n            for column_header in self.column_headers\n        ]\n\n    @classmethod\n    def _find_all_preset_names(cls, diff: dict) -> Set[str]:\n        return {\n            preset\n            for project, project_diff in diff.items()\n            if isinstance(project_diff, dict)\n            for preset in project_diff\n        }\n\n    @classmethod\n    def _find_all_attribute_names(cls, diff: dict) -> Set[str]:\n        return {\n            attribute\n            for project, project_diff in diff.items()\n            if isinstance(project_diff, dict)\n            for preset, preset_diff in project_diff.items()\n            if isinstance(preset_diff, dict)\n            for attribute in preset_diff\n        }\n\n    @classmethod\n    def _cell_content(cls, diff: dict, project: str, preset: str, attribute: str) -> str:\n        assert project in diff\n\n        if isinstance(diff[project], str):\n            return diff[project]\n        if preset not in diff[project]:\n            return ''\n        if isinstance(diff[project][preset], str):\n            return diff[project][preset]\n        if attribute not in diff[project][preset]:\n            return ''\n\n        return diff[project][preset][attribute]\n\n\nclass DiffTableFormatter:\n    LEGEND = dedent(\"\"\"\n        `!V` = version mismatch\n        `!B` = no value in the \"before\" version\n        `!A` = no value in the \"after\" version\n        `!T` = one or both values were not numeric and could not be compared\n        `-0` = very small negative value rounded to zero\n        `+0` = very small positive value rounded to zero\n    \"\"\")\n\n    @classmethod\n    def run(cls, diff_table_set: DiffTableSet, output_format: OutputFormat):\n        if output_format == OutputFormat.JSON:\n            return json.dumps(diff_table_set.cells, indent=4, sort_keys=True)\n        else:\n            assert output_format in {OutputFormat.CONSOLE, OutputFormat.MARKDOWN}\n\n            output = ''\n            for table_header in diff_table_set.table_headers:\n                column_widths = ([\n                    diff_table_set.calculate_row_column_width(),\n                    *diff_table_set.calculate_column_widths(table_header)\n                ])\n\n                if output_format == OutputFormat.MARKDOWN:\n                    output += f'\\n### `{table_header}`\\n'\n                else:\n                    output += f'\\n{table_header.upper()}\\n'\n\n                if output_format == OutputFormat.CONSOLE:\n                    output += cls._format_separator_row(column_widths, output_format) + '\\n'\n                output += cls._format_data_row(['project', *diff_table_set.column_headers], column_widths) + '\\n'\n                output += cls._format_separator_row(column_widths, output_format) + '\\n'\n\n                for row_header in diff_table_set.row_headers:\n                    row = [\n                        diff_table_set.cells[table_header][row_header][column_header]\n                        for column_header in diff_table_set.column_headers\n                    ]\n                    output += cls._format_data_row([row_header, *row], column_widths) + '\\n'\n\n                if output_format == OutputFormat.CONSOLE:\n                    output += cls._format_separator_row(column_widths, output_format) + '\\n'\n\n            if output_format == OutputFormat.MARKDOWN:\n                output += f'\\n{cls.LEGEND}\\n'\n            return output\n\n    @classmethod\n    def _format_separator_row(cls, widths: Sequence[int], output_format: OutputFormat):\n        assert output_format in {OutputFormat.CONSOLE, OutputFormat.MARKDOWN}\n\n        if output_format == OutputFormat.MARKDOWN:\n            return '|:' + ':|-'.join('-' * width for width in widths) + ':|'\n        else:\n            return '|-' + '-|-'.join('-' * width for width in widths) + '-|'\n\n    @classmethod\n    def _format_data_row(cls, cells: Sequence[Union[int, float, str]], widths: Sequence[int]):\n        assert len(cells) == len(widths)\n\n        return '| ' + ' | '.join(str(cell).rjust(width) for cell, width in zip(cells, widths)) + ' |'\n\n\n@dataclass(frozen=True)\nclass CommandLineOptions:\n    diff_mode: DiffMode\n    report_before: Path\n    report_after: Path\n    difference_style: DifferenceStyle\n    relative_precision: int\n    output_format: OutputFormat\n\n\ndef process_commandline() -> CommandLineOptions:\n    script_description = (\n        \"Compares summarized benchmark reports and outputs JSON with the same structure but listing only differences. \"\n        \"Can also print the output as markdown table and format the values to make differences stand out more.\"\n    )\n\n    parser = ArgumentParser(description=script_description)\n    parser.add_argument(\n        dest='diff_mode',\n        choices=[m.value for m in DiffMode],\n        help=(\n            \"Diff mode: \"\n            f\"'{DiffMode.IN_PLACE.value}' preserves input JSON structure and replace values with differences; \"\n            f\"'{DiffMode.TABLE.value}' creates a table assuming 3-level project/preset/attribute structure.\"\n        )\n    )\n    parser.add_argument(dest='report_before', help=\"Path to a JSON file containing original benchmark results.\")\n    parser.add_argument(dest='report_after', help=\"Path to a JSON file containing new benchmark results.\")\n    parser.add_argument(\n        '--style',\n        dest='difference_style',\n        choices=[s.value for s in DifferenceStyle],\n        help=(\n            \"How to present numeric differences: \"\n            f\"'{DifferenceStyle.ABSOLUTE.value}' subtracts new from original; \"\n            f\"'{DifferenceStyle.RELATIVE.value}' also divides by the original; \"\n            f\"'{DifferenceStyle.HUMANIZED.value}' is like relative but value is a percentage and \"\n            \"positive/negative changes are emphasized. \"\n            f\"(default: '{DEFAULT_DIFFERENCE_STYLE[DiffMode.IN_PLACE]}' in '{DiffMode.IN_PLACE.value}' mode, \"\n            f\"'{DEFAULT_DIFFERENCE_STYLE[DiffMode.TABLE]}' in '{DiffMode.TABLE.value}' mode)\"\n        )\n    )\n    # NOTE: Negative values are valid for precision. round() handles them in a sensible way.\n    parser.add_argument(\n        '--precision',\n        dest='relative_precision',\n        type=int,\n        default=DEFAULT_RELATIVE_PRECISION,\n        help=(\n            \"Number of significant digits for relative differences. \"\n            f\"Note that with --style={DifferenceStyle.HUMANIZED.value} the rounding is applied \"\n            \"**before** converting the value to a percentage so you need to add 2. \"\n            f\"Has no effect when used together with --style={DifferenceStyle.ABSOLUTE.value}. \"\n            f\"(default: {DEFAULT_RELATIVE_PRECISION})\"\n        )\n    )\n    parser.add_argument(\n        '--output-format',\n        dest='output_format',\n        choices=[o.value for o in OutputFormat],\n        help=(\n            \"The format to use for the diff: \"\n            f\"'{OutputFormat.JSON.value}' is raw JSON; \"\n            f\"'{OutputFormat.CONSOLE.value}' is a table with human-readable values that will look good in the console output. \"\n            f\"'{OutputFormat.MARKDOWN.value}' is similar '{OutputFormat.CONSOLE.value}' but adjusted to \"\n            \"render as proper markdown and with extra elements (legend, emoji to make non-zero values stand out more, etc).\"\n            f\"(default: '{DEFAULT_OUTPUT_FORMAT[DiffMode.IN_PLACE]}' in '{DiffMode.IN_PLACE.value}' mode, \"\n            f\"'{DEFAULT_OUTPUT_FORMAT[DiffMode.TABLE]}' in '{DiffMode.TABLE.value}' mode)\"\n        )\n    )\n\n    options = parser.parse_args()\n\n    if options.difference_style is not None:\n        difference_style = DifferenceStyle(options.difference_style)\n    else:\n        difference_style = DEFAULT_DIFFERENCE_STYLE[DiffMode(options.diff_mode)]\n\n    if options.output_format is not None:\n        output_format = OutputFormat(options.output_format)\n    else:\n        output_format = DEFAULT_OUTPUT_FORMAT[DiffMode(options.diff_mode)]\n\n    processed_options = CommandLineOptions(\n        diff_mode=DiffMode(options.diff_mode),\n        report_before=Path(options.report_before),\n        report_after=Path(options.report_after),\n        difference_style=difference_style,\n        relative_precision=options.relative_precision,\n        output_format=output_format,\n    )\n\n    if processed_options.diff_mode == DiffMode.IN_PLACE and processed_options.output_format != OutputFormat.JSON:\n        raise CommandLineError(\n            f\"Only the '{OutputFormat.JSON.value}' output format is supported in the '{DiffMode.IN_PLACE.value}' mode.\"\n        )\n\n    return processed_options\n\n\ndef main():\n    try:\n        options = process_commandline()\n\n        differ = BenchmarkDiffer(options.difference_style, options.relative_precision, options.output_format)\n        diff = differ.run(\n            json.loads(options.report_before.read_text('utf-8')),\n            json.loads(options.report_after.read_text('utf-8')),\n        )\n\n        if options.diff_mode == DiffMode.IN_PLACE:\n            print(json.dumps(diff, indent=4, sort_keys=True))\n        else:\n            assert options.diff_mode == DiffMode.TABLE\n            print(DiffTableFormatter.run(DiffTableSet(diff), options.output_format))\n\n        return 0\n    except CommandLineError as exception:\n        print(f\"ERROR: {exception}\", file=sys.stderr)\n        return 1\n\nif __name__ == \"__main__\":\n    sys.exit(main())\n"
  },
  {
    "path": "scripts/externalTests/common.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2019 solidity contributors.\n#------------------------------------------------------------------------------\nset -eo pipefail\n\n# Requires $REPO_ROOT to be defined and \"${REPO_ROOT}/scripts/common.sh\" to be included before.\n\nCURRENT_EVM_VERSION=osaka\n\nAVAILABLE_PRESETS=(\n    legacy-no-optimize\n    ir-no-optimize\n    legacy-optimize-evm-only\n    ir-optimize-evm-only\n    legacy-optimize-evm+yul\n    ir-optimize-evm+yul\n)\n\nfunction print_presets_or_exit\n{\n    local selected_presets=\"$1\"\n\n    [[ $selected_presets != \"\" ]] || { printWarning \"No presets to run. Exiting.\"; exit 0; }\n\n    printLog \"Selected settings presets: ${selected_presets}\"\n}\n\nfunction verify_input\n{\n    local binary_type=\"$1\"\n    local binary_path=\"$2\"\n    local selected_presets=\"$3\"\n\n    (( $# >= 2 && $# <= 3 )) || fail \"Usage: $0 native|solcjs <path to solc or soljson.js> [preset]\"\n    [[ $binary_type == native || $binary_type == solcjs ]] || fail \"Invalid binary type: '${binary_type}'. Must be either 'native' or 'solcjs'.\"\n    [[ -f \"$binary_path\" ]] || fail \"The compiler binary does not exist at '${binary_path}'\"\n\n    if [[ $selected_presets != \"\" ]]\n    then\n        for preset in $selected_presets\n        do\n            if [[ \" ${AVAILABLE_PRESETS[*]} \" != *\" $preset \"* ]]\n            then\n                fail \"Preset '${preset}' does not exist. Available presets: ${AVAILABLE_PRESETS[*]}.\"\n            fi\n        done\n    fi\n}\n\nfunction setup_solc\n{\n    local test_dir=\"$1\"\n    local binary_type=\"$2\"\n    local binary_path=\"$3\"\n    local solcjs_branch=\"${4:-master}\"\n    local install_dir=\"${5:-solc/}\"\n    local solcjs_dir=\"$6\"\n\n    [[ $binary_type == native || $binary_type == solcjs ]] || assertFail\n    [[ $binary_type == solcjs || $solcjs_dir == \"\" ]] || assertFail\n\n    cd \"$test_dir\"\n\n    if [[ $binary_type == solcjs ]]\n    then\n        printLog \"Setting up solc-js...\"\n        if [[ $solcjs_dir == \"\" ]]; then\n            printLog \"Cloning branch ${solcjs_branch}...\"\n            git clone --depth 1 -b \"$solcjs_branch\" https://github.com/argotorg/solc-js.git \"$install_dir\"\n        else\n            printLog \"Using local solc-js from ${solcjs_dir}...\"\n            cp -ra \"$solcjs_dir\" solc\n        fi\n\n        pushd \"$install_dir\"\n        npm install\n        cp \"$binary_path\" soljson.js\n        npm run build\n        SOLCVERSION=$(dist/solc.js --version)\n        popd\n    else\n        printLog \"Setting up solc...\"\n        SOLCVERSION=$(\"$binary_path\" --version | tail -n 1 | sed -n -E 's/^Version: (.*)$/\\1/p')\n    fi\n\n    SOLCVERSION_SHORT=$(echo \"$SOLCVERSION\" | sed -En 's/^([0-9.]+).*\\+commit\\.[0-9a-f]+.*$/\\1/p')\n    printLog \"Using compiler version $SOLCVERSION\"\n}\n\nfunction download_project\n{\n    local repo_url=\"$1\"\n    local ref=\"$2\"\n    local test_dir=\"$3\"\n\n    printLog \"Cloning ${repo_url}...\"\n    # Clone the repo ignoring all blobs until needed by git.\n    # This allows access to commit history but with a fast initial clone\n    git clone --filter=blob:none \"$repo_url\" \"$test_dir/ext\"\n    cd \"$test_dir/ext\"\n\n    # If the ref is '<latest-release>' try to use the latest tag as ref\n    # NOTE: Sadly this will not work with monorepos and may not always\n    # return the latest tag.\n    if [[ \"$ref\" == \"<latest-release>\" ]]; then\n        ref=$(git tag --sort=-v:refname | head --lines=1)\n    fi\n\n    [[ $ref != \"\" ]] || assertFail\n\n    printLog \"Using ref: ${ref}\"\n    git checkout \"$ref\"\n\n    echo \"Current commit hash: $(git rev-parse HEAD)\"\n}\n\nfunction force_truffle_version\n{\n    local version=\"$1\"\n\n    sed -i 's/\"truffle\":\\s*\".*\"/\"truffle\": \"'\"$version\"'\"/g' package.json\n}\n\nfunction replace_version_pragmas\n{\n    # Replace fixed-version pragmas (part of Consensys best practice).\n    # Include all directories to also cover node dependencies.\n    printLog \"Replacing fixed-version pragmas...\"\n    find . test -name '*.sol' -type f -print0 | xargs -0 sed -i -E -e 's/pragma solidity [^;]+;/pragma solidity >=0.0;/'\n}\n\nfunction neutralize_package_lock\n{\n    # Remove lock files (if they exist) to prevent them from overriding our changes in package.json\n    printLog \"Removing package lock files...\"\n    rm --force --verbose yarn.lock\n    rm --force --verbose package-lock.json\n}\n\nfunction neutralize_package_json_hooks\n{\n    printLog \"Disabling package.json hooks...\"\n    [[ -f package.json ]] || fail \"package.json not found\"\n    sed -i 's|\"prepublish\": *\".*\"|\"prepublish\": \"\"|g' package.json\n    sed -i 's|\"prepare\": *\".*\"|\"prepare\": \"\"|g' package.json\n}\n\nfunction neutralize_packaged_contracts\n{\n    # Frameworks will build contracts from any package that contains a configuration file.\n    # This is both unnecessary (any files imported from these packages will get compiled again as a\n    # part of the main project anyway) and trips up our version check because it won't use our\n    # custom compiler binary.\n    printLog \"Removing framework config and artifacts from npm packages...\"\n    find node_modules/ -type f '(' -name 'hardhat.config.*' -o -name 'truffle-config.*' ')' -delete\n\n    # Some npm packages also come packaged with pre-built artifacts.\n    find node_modules/ -path '*artifacts/build-info/*.json' -delete\n}\n\nfunction force_solc_modules\n{\n    local custom_solcjs_path=\"${1:-solc/}\"\n\n    [[ -d node_modules/ ]] || assertFail\n\n    printLog \"Replacing all installed solc-js with a link to the latest version...\"\n    soljson_binaries=$(find node_modules -type f -path \"*/solc/soljson.js\")\n    for soljson_binary in $soljson_binaries\n    do\n        local solc_module_path\n        solc_module_path=$(dirname \"$soljson_binary\")\n\n        printLog \"Found and replaced solc-js in $solc_module_path\"\n        rm -r \"$solc_module_path\"\n        ln -s \"$custom_solcjs_path\" \"$solc_module_path\"\n    done\n}\n\nfunction force_truffle_compiler_settings\n{\n    local config_file=\"$1\"\n    local binary_type=\"$2\"\n    local solc_path=\"$3\"\n    local preset=\"$4\"\n    local evm_version=\"${5:-\"$CURRENT_EVM_VERSION\"}\"\n    local extra_settings=\"$6\"\n    local extra_optimizer_settings=\"$7\"\n\n    [[ $binary_type == native || $binary_type == solcjs ]] || assertFail\n\n    [[ $binary_type == native ]] && local solc_path=\"native\"\n\n    printLog \"Forcing Truffle compiler settings...\"\n    echo \"-------------------------------------\"\n    echo \"Config file: $config_file\"\n    echo \"Binary type: $binary_type\"\n    echo \"Compiler path: $solc_path\"\n    echo \"Settings preset: ${preset}\"\n    echo \"Settings: $(settings_from_preset \"$preset\" \"$evm_version\" \"$extra_settings\" \"$extra_optimizer_settings\")\"\n    echo \"EVM version: $evm_version\"\n    echo \"Compiler version: ${SOLCVERSION_SHORT}\"\n    echo \"Compiler version (full): ${SOLCVERSION}\"\n    echo \"-------------------------------------\"\n\n    local compiler_settings gas_reporter_settings\n    compiler_settings=$(truffle_compiler_settings \"$solc_path\" \"$preset\" \"$evm_version\" \"$extra_settings\" \"$extra_optimizer_settings\")\n    gas_reporter_settings=$(eth_gas_reporter_settings \"$preset\")\n\n    {\n        echo \"require('eth-gas-reporter');\"\n        echo \"module.exports['mocha'] = {\"\n        echo \"    reporter: 'eth-gas-reporter',\"\n        echo \"    reporterOptions: ${gas_reporter_settings}\"\n        echo \"};\"\n\n        echo \"module.exports['compilers'] = ${compiler_settings};\"\n    } >> \"$config_file\"\n}\n\nfunction name_hardhat_default_export\n{\n    local config_file=\"$1\"\n    local import=\"import {HardhatUserConfig} from 'hardhat/types/config';\"\n    local config=\"const config: HardhatUserConfig = {\"\n    sed -i \"s|^\\s*export\\s*default\\s*{|${import}\\n${config}|g\" \"$config_file\"\n    echo \"export default config;\" >> \"$config_file\"\n}\n\nfunction force_hardhat_timeout\n{\n    local config_file=\"$1\"\n    local config_var_name=\"$2\"\n    local new_timeout=\"$3\"\n\n    printLog \"Configuring Hardhat...\"\n    echo \"-------------------------------------\"\n    echo \"Timeout: ${new_timeout}\"\n    echo \"-------------------------------------\"\n\n    if [[ $config_file == *\\.js ]]; then\n        [[ $config_var_name == \"\" ]] || assertFail\n        echo \"module.exports.mocha = module.exports.mocha || {timeout: ${new_timeout}}\"\n        echo \"module.exports.mocha.timeout =  ${new_timeout}\"\n    else\n        [[ $config_file == *\\.ts ]] || assertFail\n        [[ $config_var_name != \"\" ]] || assertFail\n        echo \"${config_var_name}.mocha = ${config_var_name}.mocha ?? {timeout: ${new_timeout}};\"\n        echo \"${config_var_name}.mocha!.timeout = ${new_timeout}\"\n    fi >> \"$config_file\"\n}\n\nfunction force_hardhat_compiler_binary\n{\n    local config_file=\"$1\"\n    local binary_type=\"$2\"\n    local solc_path=\"$3\"\n\n    printLog \"Configuring Hardhat...\"\n    echo \"-------------------------------------\"\n    echo \"Config file: ${config_file}\"\n    echo \"Binary type: ${binary_type}\"\n    echo \"Compiler path: ${solc_path}\"\n\n    local language=\"${config_file##*.}\"\n    hardhat_solc_build_subtask \"$SOLCVERSION_SHORT\" \"$SOLCVERSION\" \"$binary_type\" \"$solc_path\" \"$language\" >> \"$config_file\"\n}\n\nfunction force_hardhat_unlimited_contract_size\n{\n    local config_file=\"$1\"\n    local config_var_name=\"$2\"\n\n    printLog \"Configuring Hardhat...\"\n    echo \"-------------------------------------\"\n    echo \"Allow unlimited contract size: true\"\n    echo \"-------------------------------------\"\n\n    if [[ $config_file == *\\.js ]]; then\n        [[ $config_var_name == \"\" ]] || assertFail\n        echo \"module.exports.networks.hardhat = module.exports.networks.hardhat || {allowUnlimitedContractSize: undefined}\"\n        echo \"module.exports.networks.hardhat.allowUnlimitedContractSize = true\"\n    else\n        [[ $config_file == *\\.ts ]] || assertFail\n        [[ $config_var_name != \"\" ]] || assertFail\n        echo \"${config_var_name}.networks!.hardhat = ${config_var_name}.networks!.hardhat ?? {allowUnlimitedContractSize: undefined};\"\n        echo \"${config_var_name}.networks!.hardhat!.allowUnlimitedContractSize = true\"\n    fi >> \"$config_file\"\n}\n\nfunction force_hardhat_compiler_settings\n{\n    local config_file=\"$1\"\n    local preset=\"$2\"\n    local config_var_name=\"$3\"\n    local evm_version=\"${4:-\"$CURRENT_EVM_VERSION\"}\"\n    local extra_settings=\"$5\"\n    local extra_optimizer_settings=\"$6\"\n\n    printLog \"Configuring Hardhat...\"\n    echo \"-------------------------------------\"\n    echo \"Config file: ${config_file}\"\n    echo \"Settings preset: ${preset}\"\n    echo \"Settings: $(settings_from_preset \"$preset\" \"$evm_version\" \"$extra_settings\" \"$extra_optimizer_settings\")\"\n    echo \"EVM version: ${evm_version}\"\n    echo \"Compiler version: ${SOLCVERSION_SHORT}\"\n    echo \"Compiler version (full): ${SOLCVERSION}\"\n    echo \"-------------------------------------\"\n\n    local compiler_settings gas_reporter_settings\n    compiler_settings=$(hardhat_compiler_settings \"$SOLCVERSION_SHORT\" \"$preset\" \"$evm_version\" \"$extra_settings\" \"$extra_optimizer_settings\")\n    gas_reporter_settings=$(eth_gas_reporter_settings \"$preset\")\n    if [[ $config_file == *\\.js ]]; then\n        [[ $config_var_name == \"\" ]] || assertFail\n        echo \"require('hardhat-gas-reporter');\"\n        echo \"module.exports.gasReporter = ${gas_reporter_settings};\"\n        echo \"module.exports.solidity = ${compiler_settings};\"\n        echo \"module.exports.networks.hardhat = module.exports.networks.hardhat || { hardfork: '${evm_version}' }\"\n        echo \"module.exports.networks.hardhat.hardfork = '${evm_version}'\"\n        if [[ $evm_version == \"osaka\" ]]; then\n            # Transaction gas limit introduced by EIP-7825; the default value is 30_000_000\n            # and should be automatically handled by EDR - however, EDR with the relevant change\n            # was not released in time.\n            echo \"module.exports.networks.hardhat.blockGasLimit = 16_777_216\"\n        fi\n    else\n        [[ $config_file == *\\.ts ]] || assertFail\n        [[ $config_var_name != \"\" ]] || assertFail\n        echo 'import \"hardhat-gas-reporter\";'\n        echo \"${config_var_name}.gasReporter = ${gas_reporter_settings};\"\n        echo \"${config_var_name}.solidity = {compilers: [${compiler_settings}]};\"\n        echo \"${config_var_name}.networks!.hardhat = ${config_var_name}.networks!.hardhat ?? { hardfork: '${evm_version}' };\"\n        echo \"${config_var_name}.networks!.hardhat!.hardfork = '${evm_version}'\"\n        if [[ $evm_version == \"osaka\" ]]; then\n            # Transaction gas limit introduced by EIP-7825; the default value is 30_000_000\n            # and should be automatically handled by EDR - however, EDR with the relevant change\n            # was not released in time.\n            echo \"${config_var_name}.networks!.hardhat!.blockGasLimit = 16_777_216\"\n        fi\n    fi >> \"$config_file\"\n}\n\nfunction truffle_verify_compiler_version\n{\n    local solc_version=\"$1\"\n    local full_solc_version=\"$2\"\n\n    printLog \"Verify that the correct version (${solc_version}/${full_solc_version}) of the compiler was used to compile the contracts...\"\n    grep \"$full_solc_version\" --recursive --quiet build/contracts || fail \"Wrong compiler version detected.\"\n}\n\nfunction hardhat_verify_compiler_version\n{\n    local solc_version=\"$1\"\n    local full_solc_version=\"$2\"\n\n    printLog \"Verify that the correct version (${solc_version}/${full_solc_version}) of the compiler was used to compile the contracts...\"\n    local build_info_files\n    build_info_files=$(find . -path '*artifacts/build-info/*.json')\n    for build_info_file in $build_info_files; do\n        grep '\"solcVersion\":[[:blank:]]*\"'\"${solc_version}\"'\"' --quiet \"$build_info_file\" || fail \"Wrong compiler version detected in ${build_info_file}.\"\n        grep '\"solcLongVersion\":[[:blank:]]*\"'\"${full_solc_version}\"'\"' --quiet \"$build_info_file\" || fail \"Wrong compiler version detected in ${build_info_file}.\"\n    done\n}\n\nfunction truffle_clean\n{\n    rm -rf build/\n}\n\nfunction hardhat_clean\n{\n    rm -rf build/ artifacts/ cache/\n}\n\nfunction settings_from_preset\n{\n    local preset=\"$1\"\n    local evm_version=\"$2\"\n    local extra_settings=\"$3\"\n    local extra_optimizer_settings=\"$4\"\n\n    [[ \" ${AVAILABLE_PRESETS[*]} \" == *\" $preset \"* ]] || assertFail\n\n    [[ $extra_settings == \"\" ]] || extra_settings=\"${extra_settings}, \"\n    [[ $extra_optimizer_settings == \"\" ]] || extra_optimizer_settings=\"${extra_optimizer_settings}, \"\n\n    case \"$preset\" in\n        # NOTE: Remember to update `parallelism` of `t_ems_ext` job in CI config if you add/remove presets\n        legacy-no-optimize)       echo \"{${extra_settings}evmVersion: '${evm_version}', viaIR: false, optimizer: {${extra_optimizer_settings}enabled: false}}\" ;;\n        ir-no-optimize)           echo \"{${extra_settings}evmVersion: '${evm_version}', viaIR: true,  optimizer: {${extra_optimizer_settings}enabled: false}}\" ;;\n        legacy-optimize-evm-only) echo \"{${extra_settings}evmVersion: '${evm_version}', viaIR: false, optimizer: {${extra_optimizer_settings}enabled: true, details: {yul: false}}}\" ;;\n        ir-optimize-evm-only)     echo \"{${extra_settings}evmVersion: '${evm_version}', viaIR: true,  optimizer: {${extra_optimizer_settings}enabled: true, details: {yul: false}}}\" ;;\n        legacy-optimize-evm+yul)  echo \"{${extra_settings}evmVersion: '${evm_version}', viaIR: false, optimizer: {${extra_optimizer_settings}enabled: true, details: {yul: true}}}\" ;;\n        ir-optimize-evm+yul)      echo \"{${extra_settings}evmVersion: '${evm_version}', viaIR: true,  optimizer: {${extra_optimizer_settings}enabled: true, details: {yul: true}}}\" ;;\n        *)\n            fail \"Unknown settings preset: '${preset}'.\"\n            ;;\n    esac\n}\n\nfunction replace_global_solc\n{\n    local solc_path=\"$1\"\n\n    [[ ! -e solc ]] || fail \"A file named 'solc' already exists in '${PWD}'.\"\n\n    ln -s \"$solc_path\" solc\n    export PATH=\"$PWD:$PATH\"\n}\n\nfunction eth_gas_reporter_settings\n{\n    local preset=\"$1\"\n\n    echo \"{\"\n    echo \"    enabled: true,\"\n    echo \"    gasPrice: 1,\"                           # Gas price does not matter to us at all. Set to whatever to avoid API call.\n    echo \"    noColors: true,\"\n    echo \"    showUncalledMethods: false,\"            # Exclude entries with no gas for shorter report\n    echo \"    showMethodSig: true,\"                   # Should make diffs more stable if there are overloaded functions\n    echo \"    reportFormat: 'legacy',\"                # Use v1.x format for compatibility with parse_eth_gas_report.py\n    echo \"    outputFile: \\\"$(gas_report_path \"$preset\")\\\"\"\n    echo \"}\"\n}\n\nfunction truffle_compiler_settings\n{\n    local solc_path=\"$1\"\n    local preset=\"$2\"\n    local evm_version=\"$3\"\n    local extra_settings=\"$4\"\n    local extra_optimizer_settings=\"$5\"\n\n    echo \"{\"\n    echo \"    solc: {\"\n    echo \"        version: \\\"${solc_path}\\\",\"\n    echo \"        settings: $(settings_from_preset \"$preset\" \"$evm_version\" \"$extra_settings\" \"$extra_optimizer_settings\")\"\n    echo \"    }\"\n    echo \"}\"\n}\n\nfunction hardhat_solc_build_subtask {\n    local solc_version=\"$1\"\n    local full_solc_version=\"$2\"\n    local binary_type=\"$3\"\n    local solc_path=\"$4\"\n    local language=\"$5\"\n\n    [[ $binary_type == native || $binary_type == solcjs ]] || assertFail\n\n    [[ $binary_type == native ]] && local is_solcjs=false\n    [[ $binary_type == solcjs ]] && local is_solcjs=true\n\n    if [[ $language == js ]]; then\n        echo \"const {TASK_COMPILE_SOLIDITY_GET_SOLC_BUILD} = require('hardhat/builtin-tasks/task-names');\"\n        echo \"const assert = require('assert');\"\n        echo\n        echo \"subtask(TASK_COMPILE_SOLIDITY_GET_SOLC_BUILD, async (args, hre, runSuper) => {\"\n    else\n        [[ $language == ts ]] || assertFail\n        echo \"import {TASK_COMPILE_SOLIDITY_GET_SOLC_BUILD} from 'hardhat/builtin-tasks/task-names';\"\n        echo \"import assert = require('assert');\"\n        echo \"import {subtask} from 'hardhat/config';\"\n        echo\n        echo \"subtask(TASK_COMPILE_SOLIDITY_GET_SOLC_BUILD, async (args: any, _hre: any, _runSuper: any) => {\"\n    fi\n\n    echo \"    assert(args.solcVersion == '${solc_version}', 'Unexpected solc version: ' + args.solcVersion)\"\n    echo \"    return {\"\n    echo \"        compilerPath: '$(realpath \"$solc_path\")',\"\n    echo \"        isSolcJs: ${is_solcjs},\"\n    echo \"        version: args.solcVersion,\"\n    echo \"        longVersion: '${full_solc_version}'\"\n    echo \"    }\"\n    echo \"})\"\n}\n\nfunction hardhat_compiler_settings {\n    local solc_version=\"$1\"\n    local preset=\"$2\"\n    local evm_version=\"$3\"\n    local extra_settings=\"$4\"\n    local extra_optimizer_settings=\"$5\"\n\n    echo \"{\"\n    echo \"    version: '${solc_version}',\"\n    echo \"    settings: $(settings_from_preset \"$preset\" \"$evm_version\" \"$extra_settings\" \"$extra_optimizer_settings\")\"\n    echo \"}\"\n}\n\nfunction compile_and_run_test\n{\n    local compile_fn=\"$1\"\n    local test_fn=\"$2\"\n    local verify_fn=\"$3\"\n    local preset=\"$4\"\n    local compile_only_presets=\"$5\"\n\n    [[ $preset != *\" \"* ]] || assertFail \"Preset names must not contain spaces.\"\n\n    printLog \"Running compile function...\"\n    time_to_json_file \"$(compilation_time_report_path \"$preset\")\" \"$compile_fn\"\n    \"$verify_fn\" \"$SOLCVERSION_SHORT\" \"$SOLCVERSION\"\n\n    if [[ \"$COMPILE_ONLY\" == 1 || \" $compile_only_presets \" == *\" $preset \"* ]]; then\n        printLog \"Skipping test function...\"\n    else\n        printLog \"Running test function...\"\n        \"$test_fn\"\n    fi\n}\n\nfunction truffle_run_test\n{\n    local config_file=\"$1\"\n    local binary_type=\"$2\"\n    local solc_path=\"$3\"\n    local preset=\"$4\"\n    local compile_only_presets=\"$5\"\n    local compile_fn=\"$6\"\n    local test_fn=\"$7\"\n    local extra_settings=\"$8\"\n    local extra_optimizer_settings=\"$9\"\n\n    truffle_clean\n    force_truffle_compiler_settings \"$config_file\" \"$binary_type\" \"$solc_path\" \"$preset\" \"$CURRENT_EVM_VERSION\" \"$extra_settings\" \"$extra_optimizer_settings\"\n    compile_and_run_test compile_fn test_fn truffle_verify_compiler_version \"$preset\" \"$compile_only_presets\"\n}\n\nfunction hardhat_run_test\n{\n    local config_file=\"$1\"\n    local preset=\"$2\"\n    local compile_only_presets=\"$3\"\n    local compile_fn=\"$4\"\n    local test_fn=\"$5\"\n    local config_var_name=\"$6\"\n    local extra_settings=\"$7\"\n    local extra_optimizer_settings=\"$8\"\n\n    hardhat_clean\n    force_hardhat_compiler_settings \"$config_file\" \"$preset\" \"$config_var_name\" \"$CURRENT_EVM_VERSION\" \"$extra_settings\" \"$extra_optimizer_settings\"\n    compile_and_run_test compile_fn test_fn hardhat_verify_compiler_version \"$preset\" \"$compile_only_presets\"\n}\n\nfunction external_test\n{\n    local name=\"$1\"\n    local main_fn=\"$2\"\n\n    printTask \"Testing $name...\"\n    echo \"===========================\"\n    DIR=$(mktemp -d -t \"ext-test-${name}-XXXXXX\")\n    (\n        [[ \"$main_fn\" != \"\" ]] || fail \"Test main function not defined.\"\n        $main_fn\n    )\n    rm -rf \"$DIR\"\n    echo \"Done.\"\n}\n\nfunction gas_report_path\n{\n    local preset=\"$1\"\n\n    echo \"${DIR}/gas-report-${preset}.rst\"\n}\n\nfunction compilation_time_report_path\n{\n    local preset=\"$1\"\n\n    echo \"${DIR}/compilation-time-report-${preset}.json\"\n}\n\nfunction gas_report_to_json\n{\n    cat - | \"${REPO_ROOT}/scripts/externalTests/parse_eth_gas_report.py\" | jq '{gas: .}'\n}\n\nfunction detect_hardhat_artifact_dirs\n{\n    # NOTE: The artifacts path is a configured parameter in Hardhat, so the below may fail for new external tests\n    # See: https://hardhat.org/hardhat-runner/docs/config#path-configuration\n    local artifact_dir=()\n    [[ -e build/artifacts ]] && artifact_dir+=(\"build/artifacts\")\n    [[ -e artifacts/ ]] && artifact_dir+=(\"artifacts\")\n    (( ${#artifact_dir[@]} != 0 )) || assertFail\n    echo -n \"${artifact_dir[@]}\"\n}\n\nfunction bytecode_size_json_from_truffle_artifacts\n{\n    # NOTE: The output of this function is a series of concatenated JSON dicts rather than a list.\n\n    for artifact in build/contracts/*.json; do\n        if [[ $(jq '. | has(\"unlinked_binary\")' \"$artifact\") == false ]]; then\n            # Each artifact represents compilation output for a single contract. Some top-level keys contain\n            # bits of Standard JSON output while others are generated by Truffle. Process it into a dict\n            # of the form `{\"<file>\": {\"<contract>\": <size>}}`.\n            # NOTE: The `bytecode` field starts with 0x, which is why we subtract 1 from size.\n            jq '{\n                (.ast.absolutePath): {\n                    (.contractName): (.bytecode | length / 2 - 1)\n                }\n            }' \"$artifact\"\n        fi\n    done\n}\n\nfunction bytecode_size_json_from_hardhat_artifacts\n{\n    # NOTE: The output of this function is a series of concatenated JSON dicts rather than a list.\n    for artifact_dir in $(detect_hardhat_artifact_dirs); do\n        for artifact in \"$artifact_dir\"/build-info/*.json; do\n            # Each artifact contains Standard JSON output under the `output` key.\n            # Process it into a dict of the form `{\"<file>\": {\"<contract>\": <size>}}`,\n            # Note that one Hardhat artifact often represents multiple input files.\n            jq '.output.contracts | to_entries[] | {\n                \"\\(.key)\": .value | to_entries[] | {\n                    \"\\(.key)\": (.value.evm.bytecode.object | length / 2)\n                }\n            }' \"$artifact\"\n        done\n    done\n}\n\nfunction combine_artifact_json\n{\n    # Combine all dicts into a list with `jq --slurp` and then use `reduce` to merge them into one\n    # big dict with keys of the form `\"<file>:<contract>\"`. Then run jq again to filter out items\n    # with zero size and put the rest under under a top-level `bytecode_size` key. Also add another\n    # key with total bytecode size.\n    # NOTE: The extra inner `bytecode_size` key is there only to make diffs more readable.\n    cat - |\n        jq --slurp 'reduce (.[] | to_entries[]) as {$key, $value} ({}; . + {\n            ($key + \":\" + ($value | to_entries[].key)): {\n                bytecode_size: $value | to_entries[].value\n            }\n        })' |\n        jq --indent 4 --sort-keys '{\n            bytecode_size: [. | to_entries[] | select(.value.bytecode_size > 0)] | from_entries,\n            total_bytecode_size: (reduce (. | to_entries[]) as {$key, $value} (0; . + $value.bytecode_size))\n        }'\n}\n\nfunction project_info_json\n{\n    local project_url=\"$1\"\n\n    echo \"{\"\n    echo \"    \\\"project\\\": {\"\n    # NOTE: Given that we clone with `--depth 1`, we'll only get useful output out of `git describe`\n    # if we directly check out a tag. Still better than nothing.\n    echo \"        \\\"version\\\": \\\"$(git describe --always)\\\",\"\n    echo \"        \\\"commit\\\": \\\"$(git rev-parse HEAD)\\\",\"\n    echo \"        \\\"url\\\": \\\"${project_url}\\\"\"\n    echo \"    }\"\n    echo \"}\"\n}\n\nfunction store_benchmark_report\n{\n    local framework=\"$1\"\n    local project_name=\"$2\"\n    local project_url=\"$3\"\n    local preset=\"$4\"\n\n    [[ $framework == truffle || $framework == hardhat ]] || assertFail\n    [[ \" ${AVAILABLE_PRESETS[*]} \" == *\" $preset \"* ]] || assertFail\n\n    local report_dir=\"${REPO_ROOT}/reports/externalTests\"\n    local output_file=\"${report_dir}/benchmark-${project_name}-${preset}.json\"\n    mkdir -p \"$report_dir\"\n\n    {\n        if [[ -e $(gas_report_path \"$preset\") ]]; then\n            gas_report_to_json < \"$(gas_report_path \"$preset\")\"\n        fi\n\n        \"bytecode_size_json_from_${framework}_artifacts\" | combine_artifact_json\n        project_info_json \"$project_url\"\n        echo \"{\\\"compilation_time\\\": $(cat \"$(compilation_time_report_path \"$preset\")\")}\"\n    } | jq --slurp \"{\\\"${project_name}\\\": {\\\"${preset}\\\": add}}\" --indent 4 --sort-keys > \"$output_file\"\n}\n"
  },
  {
    "path": "scripts/externalTests/download_benchmarks.py",
    "content": "#!/usr/bin/env python3\n\nfrom argparse import ArgumentParser, Namespace\nfrom enum import Enum, unique\nfrom os import environ\nfrom pathlib import Path\nfrom textwrap import dedent\nfrom typing import Mapping, Optional\nimport sys\n\nimport requests\n\n# Our scripts/ is not a proper Python package so we need to modify PYTHONPATH to import from it\n# pragma pylint: disable=import-error,wrong-import-position\nSCRIPTS_DIR = Path(__file__).parent.parent\nsys.path.insert(0, str(SCRIPTS_DIR))\n\nfrom common.git_helpers import git_current_branch, git_commit_hash\nfrom common.rest_api_helpers import APIHelperError, JobNotSuccessful, CircleCI, Github, download_file\n# pragma pylint: enable=import-error,wrong-import-position\n\n\n@unique\nclass Status(Enum):\n    OK = 0            # Benchmarks downloaded successfully\n    ERROR = 1         # Error in the script, bad API response, unexpected data, etc.\n    NO_BENCHMARK = 2  # Benchmark collector job did not finish successfully and/or benchmark artifacts are missing.\n    PENDING = 3       # Benchmark collector job has not finished yet.\n\n\ndef process_commandline() -> Namespace:\n    script_description = (\n        \"\"\"\n        Downloads benchmark results attached as artifacts to the c_ext_benchmarks job on CircleCI.\n        If no options are specified, downloads results for the currently checked out git branch.\n\n        The script requires the CIRCLECI_TOKEN environment variable to be set with a valid CircleCI API token.\n        You can generate a new token at https://app.circleci.com/settings/user/tokens.\n        \"\"\"\n    )\n\n    parser = ArgumentParser(description=script_description)\n\n    target_definition = parser.add_mutually_exclusive_group()\n    target_definition.add_argument(\n        '--branch',\n        dest='branch',\n        help=\"Git branch that the job ran on.\",\n    )\n    target_definition.add_argument(\n        '--pr',\n        dest='pull_request_id',\n        type=int,\n        help=\"Github PR ID that the job ran on.\",\n    )\n    target_definition.add_argument(\n        '--base-of-pr',\n        dest='base_of_pr',\n        type=int,\n        help=\"ID of a Github PR that's based on top of the branch we're interested in.\"\n    )\n\n    parser.add_argument(\n        '--any-commit',\n        dest='ignore_commit_hash',\n        default=False,\n        action='store_true',\n        help=\"Include pipelines that ran on a different commit as long as branch/PR matches.\"\n    )\n    parser.add_argument(\n        '--overwrite',\n        dest='overwrite',\n        default=False,\n        action='store_true',\n        help=\"If artifacts already exist on disk, overwrite them.\",\n    )\n    parser.add_argument(\n        '--debug-requests',\n        dest='debug_requests',\n        default=False,\n        action='store_true',\n        help=\"Print detailed info about performed API requests and received responses.\",\n    )\n\n    return parser.parse_args()\n\n\ndef download_benchmark_artifact(\n    artifacts: Mapping[str, dict],\n    benchmark_name: str,\n    branch: str,\n    commit_hash: str,\n    overwrite: bool,\n    silent: bool = False\n) -> bool:\n    if not silent:\n        print(f\"Downloading artifact: {benchmark_name}-{branch}-{commit_hash[:8]}.json.\")\n\n    artifact_path = f'reports/externalTests/{benchmark_name}.json'\n\n    if artifact_path not in artifacts:\n        if not silent:\n            print(f\"Missing artifact: {artifact_path}.\")\n        return False\n\n    headers = {'Circle-Token': str(environ.get('CIRCLECI_TOKEN'))} if 'CIRCLECI_TOKEN' in environ else {}\n    download_file(\n        artifacts[artifact_path]['url'],\n        Path(f'{benchmark_name}-{branch}-{commit_hash[:8]}.json'),\n        headers,\n        overwrite,\n    )\n\n    return True\n\n\ndef download_benchmarks(\n    branch: Optional[str],\n    pull_request_id: Optional[int],\n    base_of_pr: Optional[int],\n    ignore_commit_hash: bool = False,\n    overwrite: bool = False,\n    debug_requests: bool = False,\n    silent: bool = False,\n) -> Status:\n    github = Github('argotorg/solidity', debug_requests)\n    circleci = CircleCI('argotorg/solidity', debug_requests)\n\n    expected_commit_hash = None\n    if branch is None and pull_request_id is None and base_of_pr is None:\n        branch = git_current_branch()\n        expected_commit_hash = git_commit_hash()\n    elif branch is not None:\n        expected_commit_hash = git_commit_hash(branch)\n    elif pull_request_id is not None:\n        pr_info = github.pull_request(pull_request_id)\n        branch = pr_info['head']['ref']\n        expected_commit_hash = pr_info['head']['sha']\n    elif base_of_pr is not None:\n        pr_info = github.pull_request(base_of_pr)\n        branch = pr_info['base']['ref']\n        expected_commit_hash = pr_info['base']['sha']\n\n    if not silent:\n        print(\n            f\"Looking for pipelines that ran on branch {branch}\" +\n            (f\", commit {expected_commit_hash}.\" if not ignore_commit_hash else \" (any commit).\")\n        )\n\n    pipeline = circleci.latest_item(circleci.pipelines(\n        branch,\n        expected_commit_hash if not ignore_commit_hash else None,\n        # Skip nightly workflows. They don't have the c_ext_benchmarks job and even if they did,\n        # they would likely be running a different set of external tests.\n        excluded_trigger_types=['schedule'],\n    ))\n    if pipeline is None:\n        raise RuntimeError(\"No matching pipelines found.\")\n\n    actual_commit_hash = pipeline['vcs']['revision']\n    workflow_id = circleci.latest_item(circleci.workflows(pipeline['id']))['id']\n    benchmark_collector_job = circleci.job(workflow_id, 'c_ext_benchmarks', require_success=True)\n\n    artifacts = circleci.artifacts(int(benchmark_collector_job['job_number']))\n\n    got_summary = download_benchmark_artifact(artifacts, 'summarized-benchmarks', branch, actual_commit_hash, overwrite, silent)\n    got_full = download_benchmark_artifact(artifacts, 'all-benchmarks', branch, actual_commit_hash, overwrite, silent)\n\n    return Status.OK if got_summary and got_full else Status.NO_BENCHMARK\n\n\ndef main():\n    try:\n        if 'CIRCLECI_TOKEN' not in environ:\n            raise RuntimeError(\n               dedent(\"\"\" \\\n                   CIRCLECI_TOKEN environment variable required but not set.\n                   Please generate a new token at https://app.circleci.com/settings/user/tokens and set CIRCLECI_TOKEN.\n                   \"\"\")\n            )\n        options = process_commandline()\n        return download_benchmarks(\n            options.branch,\n            options.pull_request_id,\n            options.base_of_pr,\n            options.ignore_commit_hash,\n            options.overwrite,\n            options.debug_requests,\n        ).value\n    except JobNotSuccessful as exception:\n        print(f\"[ERROR] {exception}\", file=sys.stderr)\n        if not exception.job_finished:\n            print(\"Please wait for the workflow to finish and try again.\", file=sys.stderr)\n            return Status.PENDING.value\n        else:\n            print(\"Benchmarks from this run of the pipeline are not available.\", file=sys.stderr)\n            return Status.NO_BENCHMARK.value\n    except APIHelperError as exception:\n        print(f\"[ERROR] {exception}\", file=sys.stderr)\n        return Status.ERROR.value\n    except requests.exceptions.HTTPError as exception:\n        print(f\"[ERROR] {exception}\", file=sys.stderr)\n        return Status.ERROR.value\n    except RuntimeError as exception:\n        print(f\"[ERROR] {exception}\", file=sys.stderr)\n        return Status.ERROR.value\n\n\nif __name__ == '__main__':\n    sys.exit(main())\n"
  },
  {
    "path": "scripts/externalTests/merge_benchmarks.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# Reads multiple individual benchmark reports produced by scripts from\n# test/externalTests/ from standard input and creates a combined report.\n#\n# Usage:\n#    <script name>.sh < <CONCATENATED_REPORTS>\n#\n# CONCATENATED_REPORTS: JSON report files concatenated into a single stream (e.g. using cat).\n#\n# Example:\n#    cat reports/externalTests/benchmark-*.json | <script name>.sh\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2021 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -euo pipefail\n\n# We expect a series of dicts of the form {\"<project>\": {\"<preset>\": {...}}}.\n# Unfortunately jq's built-in `add` filter can't handle nested dicts and\n# would just overwrite values sharing a project name instead of merging them.\n\n# This is done by first grouping the dicts into an array of the form\n# [\n#     [{\"key\": \"<project1>\", \"value\": {\"<preset1>\": {...}}}, {\"key\": \"<project1>\", \"value\": {\"<preset2>\": {...}}, ...],\n#     [{\"key\": \"<project2>\", \"value\": {\"<preset1>\": {...}}}, {\"key\": \"<project2>\", \"value\": {\"<preset2>\": {...}}, ...],\n#     ...\n# ]\n# and then using reduce() on each group sharing the same project name to convert it into a\n# dict having preset names as keys.\njq --slurp  --indent 4 --sort-keys '\n    map(to_entries[]) |\n    group_by(.key) |\n    map({\n        (.[0].key): (\n            reduce (.[].value | to_entries[]) as {$key, $value} (\n                {}; . + {\n                    ($key): $value\n                }\n            )\n        )\n    }) |\n    add\n'\n"
  },
  {
    "path": "scripts/externalTests/parse_eth_gas_report.py",
    "content": "#!/usr/bin/env python3\n# coding=utf-8\n\nfrom dataclasses import asdict, dataclass, field\nfrom typing import Dict, Optional, Tuple\nimport json\nimport re\nimport sys\n\nREPORT_HEADER_REGEX = re.compile(r'''\n    ^[|\\s]+ Solc[ ]version:\\s*(?P<solc_version>[\\w\\d.]+)\n    [|\\s]+ Optimizer[ ]enabled:\\s*(?P<optimize>[\\w]+)\n    [|\\s]+ Runs:\\s*(?P<runs>[\\d,]+)\n    [|\\s]+ Block[ ]limit:\\s*(?P<block_limit>[\\d,]+)\\s*gas\n    [|\\s]+$\n''', re.VERBOSE)\nMETHOD_HEADER_REGEX = re.compile(r'^[|\\s]+Methods[|\\s]+$')\nMETHOD_COLUMN_HEADERS_REGEX = re.compile(r'''\n    ^[|\\s]+ Contract\n    [|\\s]+ Method\n    [|\\s]+ Min\n    [|\\s]+ Max\n    [|\\s]+ Avg\n    [|\\s]+ \\#[ ]calls\n    [|\\s]+ \\w+[ ]\\(avg\\)\n    [|\\s]+$\n''', re.VERBOSE)\nMETHOD_ROW_REGEX = re.compile(r'''\n    ^[|\\s]+ (?P<contract>[^|]+)\n    [|\\s]+ (?P<method>[^|]+)\n    [|\\s]+ (?P<min>[^|]+)\n    [|\\s]+ (?P<max>[^|]+)\n    [|\\s]+ (?P<avg>[^|]+)\n    [|\\s]+ (?P<call_count>[^|]+)\n    [|\\s]+ (?P<eur_avg>[^|]+)\n    [|\\s]+$\n''', re.VERBOSE)\nFRAME_REGEX = re.compile(r'^[-|\\s]+$')\nDEPLOYMENT_HEADER_REGEX = re.compile(r'^[|\\s]+Deployments[|\\s]+% of limit[|\\s]+$')\nDEPLOYMENT_ROW_REGEX = re.compile(r'''\n    ^[|\\s]+ (?P<contract>[^|]+)\n    [|\\s]+ (?P<min>[^|]+)\n    [|\\s]+ (?P<max>[^|]+)\n    [|\\s]+ (?P<avg>[^|]+)\n    [|\\s]+ (?P<percent_of_limit>[^|]+)\\s*%\n    [|\\s]+ (?P<eur_avg>[^|]+)\n    [|\\s]+$\n''', re.VERBOSE)\n\n\nclass ReportError(Exception):\n    pass\n\nclass ReportValidationError(ReportError):\n    pass\n\nclass ReportParsingError(Exception):\n    def __init__(self, message: str, line: str, line_number: int):\n        # pylint: disable=useless-super-delegation  # It's not useless, it adds type annotations.\n        super().__init__(message, line, line_number)\n\n    def __str__(self):\n        return f\"Parsing error on line {self.args[2] + 1}: {self.args[0]}\\n{self.args[1]}\"\n\n\n@dataclass(frozen=True)\nclass MethodGasReport:\n    min_gas: int\n    max_gas: int\n    avg_gas: int\n    call_count: int\n    total_gas: int = field(init=False)\n\n    def __post_init__(self):\n        object.__setattr__(self, 'total_gas', self.avg_gas * self.call_count)\n\n\n@dataclass(frozen=True)\nclass ContractGasReport:\n    min_deployment_gas: Optional[int]\n    max_deployment_gas: Optional[int]\n    avg_deployment_gas: Optional[int]\n    methods: Optional[Dict[str, MethodGasReport]]\n    total_method_gas: int = field(init=False, default=0)\n\n    def __post_init__(self):\n        if self.methods is not None:\n            object.__setattr__(self, 'total_method_gas', sum(method.total_gas for method in self.methods.values()))\n\n\n@dataclass(frozen=True)\nclass GasReport:\n    solc_version: str\n    optimize: bool\n    runs: int\n    block_limit: int\n    contracts: Dict[str, ContractGasReport]\n    total_method_gas: int = field(init=False)\n    total_deployment_gas: int = field(init=False)\n\n    def __post_init__(self):\n        object.__setattr__(self, 'total_method_gas', sum(\n            total_method_gas\n            for total_method_gas in (contract.total_method_gas for contract in self.contracts.values())\n            if total_method_gas is not None\n        ))\n        object.__setattr__(self, 'total_deployment_gas', sum(\n            contract.avg_deployment_gas\n            for contract in self.contracts.values()\n            if contract.avg_deployment_gas is not None\n        ))\n\n    def to_json(self):\n        return json.dumps(asdict(self), indent=4, sort_keys=True)\n\n\ndef parse_bool(input_string: str) -> bool:\n    if input_string not in ('true', 'false'):\n        raise ValueError(f\"Invalid boolean value: '{input_string}'\")\n\n    return input_string == 'true'\n\n\ndef parse_optional_int(input_string: str, default: Optional[int] = None) -> Optional[int]:\n    stripped = input_string.strip().replace(',', '')\n    if stripped == '-':\n        return default\n\n    return int(stripped)\n\n\ndef parse_report_header(line: str) -> Optional[dict]:\n    match = REPORT_HEADER_REGEX.match(line)\n    if match is None:\n        return None\n\n    return {\n        'solc_version': match.group('solc_version'),\n        'optimize': parse_bool(match.group('optimize')),\n        'runs': int(match.group('runs').replace(',', '')),\n        'block_limit': int(match.group('block_limit').replace(',', '')),\n    }\n\n\ndef parse_method_row(line: str, line_number: int) -> Optional[Tuple[str, str, MethodGasReport]]:\n    match = METHOD_ROW_REGEX.match(line)\n    if match is None:\n        raise ReportParsingError(\"Expected a table row with method details.\", line, line_number)\n\n    avg_gas = parse_optional_int(match['avg'])\n    call_count = int(match['call_count'].strip().replace(',', ''))\n\n    if avg_gas is None and call_count == 0:\n        # No calls, no gas values. Uninteresting. Skip the row.\n        return None\n\n    return (\n        match['contract'].strip(),\n        match['method'].strip(),\n        MethodGasReport(\n            min_gas=parse_optional_int(match['min'], avg_gas),\n            max_gas=parse_optional_int(match['max'], avg_gas),\n            avg_gas=avg_gas,\n            call_count=call_count,\n        )\n    )\n\n\ndef parse_deployment_row(line: str, line_number: int) -> Tuple[str, int, int, int]:\n    match = DEPLOYMENT_ROW_REGEX.match(line)\n    if match is None:\n        raise ReportParsingError(\"Expected a table row with deployment details.\", line, line_number)\n\n    return (\n        match['contract'].strip(),\n        parse_optional_int(match['min'].strip()),\n        parse_optional_int(match['max'].strip()),\n        int(match['avg'].strip().replace(',', '')),\n    )\n\n\ndef preprocess_unicode_frames(input_string: str) -> str:\n    # The report has a mix of normal pipe chars and its unicode variant.\n    # Let's just replace all frame chars with normal pipes for easier parsing.\n    return input_string.replace('\\u2502', '|').replace('·', '|')\n\n\ndef parse_report(rst_report: str) -> GasReport:\n    report_params = None\n    methods_by_contract = {}\n    deployment_costs = {}\n    expected_row_type = None\n\n    for line_number, line in enumerate(preprocess_unicode_frames(rst_report).splitlines()):\n        try:\n            if (\n                line.strip() == \"\" or\n                FRAME_REGEX.match(line) is not None or\n                METHOD_COLUMN_HEADERS_REGEX.match(line) is not None\n            ):\n                continue\n            if METHOD_HEADER_REGEX.match(line) is not None:\n                expected_row_type = 'method'\n                continue\n            if DEPLOYMENT_HEADER_REGEX.match(line) is not None:\n                expected_row_type = 'deployment'\n                continue\n\n            new_report_params = parse_report_header(line)\n            if new_report_params is not None:\n                if report_params is not None:\n                    raise ReportParsingError(\"Duplicate report header.\", line, line_number)\n\n                report_params = new_report_params\n                continue\n\n            if expected_row_type == 'method':\n                parsed_row = parse_method_row(line, line_number)\n                if parsed_row is None:\n                    continue\n\n                (contract, method, method_report) = parsed_row\n\n                if contract not in methods_by_contract:\n                    methods_by_contract[contract] = {}\n\n                if method in methods_by_contract[contract]:\n                    # Report must be generated with full signatures for method names to be unambiguous.\n                    raise ReportParsingError(f\"Duplicate method row for '{contract}.{method}'.\", line, line_number)\n\n                methods_by_contract[contract][method] = method_report\n            elif expected_row_type == 'deployment':\n                (contract, min_gas, max_gas, avg_gas) = parse_deployment_row(line, line_number)\n\n                if contract in deployment_costs:\n                    raise ReportParsingError(f\"Duplicate contract deployment row for '{contract}'.\", line, line_number)\n\n                deployment_costs[contract] = (min_gas, max_gas, avg_gas)\n            else:\n                assert expected_row_type is None\n                raise ReportParsingError(\"Found data row without a section header.\", line, line_number)\n\n        except ValueError as error:\n            raise ReportParsingError(error.args[0], line, line_number) from error\n\n    if report_params is None:\n        raise ReportValidationError(\"Report header not found.\")\n\n    report_params['contracts'] = {\n        contract: ContractGasReport(\n            min_deployment_gas=deployment_costs.get(contract, (None, None, None))[0],\n            max_deployment_gas=deployment_costs.get(contract, (None, None, None))[1],\n            avg_deployment_gas=deployment_costs.get(contract, (None, None, None))[2],\n            methods=methods_by_contract.get(contract),\n        )\n        for contract in methods_by_contract.keys() | deployment_costs.keys()\n    }\n\n    return GasReport(**report_params)\n\n\nif __name__ == \"__main__\":\n    try:\n        report = parse_report(sys.stdin.read())\n        print(report.to_json())\n    except ReportError as exception:\n        print(f\"{exception}\", file=sys.stderr)\n        sys.exit(1)\n"
  },
  {
    "path": "scripts/externalTests/runners/base.py",
    "content": "#!/usr/bin/env python3\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2023 solidity contributors.\n# ------------------------------------------------------------------------------\n\nimport os\nimport subprocess\nfrom abc import ABCMeta\nfrom abc import abstractmethod\nfrom dataclasses import dataclass\nfrom dataclasses import field\nfrom pathlib import Path\nfrom shutil import rmtree\nfrom tempfile import mkdtemp\nfrom textwrap import dedent\nfrom typing import List\nfrom typing import Set\n\nfrom test_helpers import download_project\nfrom test_helpers import get_solc_short_version\nfrom test_helpers import parse_command_line\nfrom test_helpers import parse_custom_presets\nfrom test_helpers import parse_solc_version\nfrom test_helpers import replace_version_pragmas\nfrom test_helpers import settings_from_preset\nfrom test_helpers import SettingsPreset\n\nCURRENT_EVM_VERSION: str = \"osaka\"\n\n@dataclass\nclass TestConfig:\n    name: str\n    repo_url: str\n    ref: str\n    compile_only_presets: List[SettingsPreset] = field(default_factory=list)\n    settings_presets: List[SettingsPreset] = field(default_factory=lambda: list(SettingsPreset))\n    evm_version: str = field(default=CURRENT_EVM_VERSION)\n\n    def selected_presets(self) -> Set[SettingsPreset]:\n        return set(self.compile_only_presets + self.settings_presets)\n\n\nclass BaseRunner(metaclass=ABCMeta):\n    config: TestConfig\n    solc_binary_type: str\n    solc_binary_path: Path\n    presets: Set[SettingsPreset]\n\n    def __init__(self, argv, config: TestConfig):\n        args = parse_command_line(f\"{config.name} external tests\", argv)\n        self.config = config\n        self.solc_binary_type = args.solc_binary_type\n        self.solc_binary_path = args.solc_binary_path\n        self.presets = parse_custom_presets(args.selected_presets) if args.selected_presets else config.selected_presets()\n        self.env = os.environ.copy()\n        self.tmp_dir = mkdtemp(prefix=f\"ext-test-{config.name}-\")\n        self.test_dir = Path(self.tmp_dir) / \"ext\"\n\n    def setup_solc(self) -> str:\n        if self.solc_binary_type == \"solcjs\":\n            # TODO: add support for solc-js\n            raise NotImplementedError()\n        print(\"Setting up solc...\")\n        solc_version_output = subprocess.check_output(\n            [self.solc_binary_path, \"--version\"],\n            shell=False,\n            encoding=\"utf-8\"\n        ).split(\":\")[1]\n        return parse_solc_version(solc_version_output)\n\n    @staticmethod\n    def enter_test_dir(fn):\n        \"\"\"Run a function inside the test directory\"\"\"\n\n        previous_dir = os.getcwd()\n        def f(self, *args, **kwargs):\n            try:\n                assert self.test_dir is not None\n                os.chdir(self.test_dir)\n                return fn(self, *args, **kwargs)\n            finally:\n                # Restore the previous directory after execute fn\n                os.chdir(previous_dir)\n        return f\n\n    def setup_environment(self):\n        \"\"\"Configure the project build environment\"\"\"\n        print(\"Configuring Runner building environment...\")\n        replace_version_pragmas(self.test_dir)\n\n    @enter_test_dir\n    def clean(self):\n        \"\"\"Clean temporary directories\"\"\"\n        rmtree(self.tmp_dir)\n\n    @enter_test_dir\n    @abstractmethod\n    def configure(self):\n        raise NotImplementedError()\n\n    @enter_test_dir\n    @abstractmethod\n    def compile(self, preset: SettingsPreset):\n        raise NotImplementedError()\n\n    @enter_test_dir\n    @abstractmethod\n    def run_test(self):\n        raise NotImplementedError()\n\ndef run_test(runner: BaseRunner):\n    print(f\"Testing {runner.config.name}...\\n===========================\")\n    print(f\"Selected settings presets: {' '.join(p.value for p in runner.presets)}\")\n\n    # Configure solc compiler\n    solc_version = runner.setup_solc()\n    print(f\"Using compiler version {solc_version}\")\n\n    # Download project\n    download_project(runner.test_dir, runner.config.repo_url, runner.config.ref)\n\n    # Configure run environment\n    runner.setup_environment()\n\n    # Configure TestRunner instance\n    print(dedent(f\"\"\"\\\n        Configuring runner's profiles with:\n        -------------------------------------\n        Binary type: {runner.solc_binary_type}\n        Compiler path: {runner.solc_binary_path}\n        -------------------------------------\n    \"\"\"))\n    runner.configure()\n    for preset in runner.presets:\n        print(\"Running compile function...\")\n        settings = settings_from_preset(preset, runner.config.evm_version)\n        print(dedent(f\"\"\"\\\n            -------------------------------------\n            Settings preset: {preset.value}\n            Settings: {settings}\n            EVM version: {runner.config.evm_version}\n            Compiler version: {get_solc_short_version(solc_version)}\n            Compiler version (full): {solc_version}\n            -------------------------------------\n        \"\"\"))\n        runner.compile(preset)\n        # TODO: COMPILE_ONLY should be a command-line option\n        if os.environ.get(\"COMPILE_ONLY\") == \"1\" or preset in runner.config.compile_only_presets:\n            print(\"Skipping test function...\")\n        else:\n            print(\"Running test function...\")\n            runner.run_test()\n        # TODO: store_benchmark_report\n    runner.clean()\n    print(\"Done.\")\n"
  },
  {
    "path": "scripts/externalTests/runners/foundry.py",
    "content": "#!/usr/bin/env python3\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2023 solidity contributors.\n# ------------------------------------------------------------------------------\n\nimport os\nimport re\nimport subprocess\nfrom shutil import which\nfrom textwrap import dedent\nfrom typing import Optional\n\nfrom runners.base import BaseRunner\nfrom test_helpers import SettingsPreset\nfrom test_helpers import settings_from_preset\n\ndef run_forge_command(command: str, env: Optional[dict] = None):\n    subprocess.run(\n        command.split(),\n        env=env if env is not None else os.environ.copy(),\n        check=True\n    )\n\n\nclass FoundryRunner(BaseRunner):\n    \"\"\"Configure and run Foundry-based projects\"\"\"\n\n    FOUNDRY_CONFIG_FILE = \"foundry.toml\"\n\n    def setup_environment(self):\n        super().setup_environment()\n        if which(\"forge\") is None:\n            raise RuntimeError(\"Forge not found.\")\n\n    @staticmethod\n    def profile_name(preset: SettingsPreset):\n        \"\"\"Returns foundry profile name\"\"\"\n        # Replace - or + by underscore to avoid invalid toml syntax\n        return re.sub(r\"(\\-|\\+)+\", \"_\", preset.value)\n\n    @staticmethod\n    def profile_section(profile_fields: dict) -> str:\n        return dedent(\"\"\"\\\n            [profile.{name}]\n            gas_reports = [\"*\"]\n            auto_detect_solc = false\n            solc = \"{solc}\"\n            evm_version = \"{evm_version}\"\n            optimizer = {optimizer}\n            via_ir = {via_ir}\n\n            [profile.{name}.optimizer_details]\n            yul = {yul}\n        \"\"\").format(**profile_fields)\n\n    def setup_presets_profiles(self):\n        \"\"\"Configure forge tests profiles\"\"\"\n\n        profiles = []\n        for preset in self.presets:\n            settings = settings_from_preset(preset, self.config.evm_version)\n            profiles.append(self.profile_section({\n                \"name\": self.profile_name(preset),\n                \"solc\": self.solc_binary_path,\n                \"evm_version\": self.config.evm_version,\n                \"optimizer\": str(settings[\"optimizer\"][\"enabled\"]).lower(),\n                \"via_ir\": str(settings[\"viaIR\"]).lower(),\n                \"yul\": str(settings[\"optimizer\"][\"details\"][\"yul\"]).lower(),\n            }))\n\n        with open(\n            file=self.test_dir / self.FOUNDRY_CONFIG_FILE,\n            mode=\"a\",\n            encoding=\"utf-8\",\n        ) as f:\n            for profile in profiles:\n                f.write(profile)\n\n    @BaseRunner.enter_test_dir\n    def configure(self):\n        \"\"\"Install project dependencies\"\"\"\n        self.setup_presets_profiles()\n        run_forge_command(\"forge install\", self.env)\n\n    @BaseRunner.enter_test_dir\n    def compile(self, preset: SettingsPreset):\n        \"\"\"Compile project\"\"\"\n\n        # Set the Foundry profile environment variable\n        self.env.update({\"FOUNDRY_PROFILE\": self.profile_name(preset)})\n        run_forge_command(\"forge build\", self.env)\n\n    @BaseRunner.enter_test_dir\n    def run_test(self):\n        \"\"\"Run project tests\"\"\"\n\n        run_forge_command(\"forge test --gas-report\", self.env)\n"
  },
  {
    "path": "scripts/externalTests/summarize_benchmarks.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# Reads a combined benchmark report from standard input and outputs an abbreviated\n# report containing only totals. Can handle individual reports coming directly\n# from scripts in test/externalTests/ as well as combined report from merge_benchmarks.sh.\n#\n# Usage:\n#    <script name>.sh < <CONCATENATED_REPORTS>\n#\n# CONCATENATED_REPORTS: JSON report files concatenated into a single stream (e.g. using cat).\n#\n# Example:\n#    cat reports/externalTests/benchmark-*.json | <script name>.sh\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2021 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -euo pipefail\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\n# Iterates over presets in a dict of the form {\"<project>\": {\"<preset>\": {...}}} and for each\n# one preserves only the few keys with totals that we want to see in the summary.\nexec \"${REPO_ROOT}/scripts/externalTests/merge_benchmarks.sh\" | jq --indent 4 --sort-keys '\n    with_entries({\n        key: .key,\n        value: .value | with_entries({\n            key: .key,\n            value: {\n                bytecode_size: .value.total_bytecode_size,\n                method_gas: .value.gas.total_method_gas,\n                deployment_gas: .value.gas.total_deployment_gas,\n                version: .value.project.version\n            }\n        })\n    })\n'\n"
  },
  {
    "path": "scripts/externalTests/test_helpers.py",
    "content": "#!/usr/bin/env python3\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2023 solidity contributors.\n# ------------------------------------------------------------------------------\n\nimport os\nimport re\nimport subprocess\nimport sys\nfrom argparse import ArgumentParser\nfrom enum import Enum\nfrom pathlib import Path\nfrom typing import List\nfrom typing import Set\n\n# Our scripts/ is not a proper Python package so we need to modify PYTHONPATH to import from it\n# pragma pylint: disable=import-error,wrong-import-position\nPROJECT_ROOT = Path(__file__).parents[2]\nsys.path.insert(0, f\"{PROJECT_ROOT}/scripts/common\")\n\nfrom git_helpers import git_commit_hash\n\nSOLC_FULL_VERSION_REGEX = re.compile(r\"^[a-zA-Z: ]*(.*)$\")\nSOLC_SHORT_VERSION_REGEX = re.compile(r\"^([0-9.]+).*\\+|\\-$\")\n\n\nclass SettingsPreset(Enum):\n    LEGACY_NO_OPTIMIZE = 'legacy-no-optimize'\n    IR_NO_OPTIMIZE = 'ir-no-optimize'\n    LEGACY_OPTIMIZE_EVM_ONLY = 'legacy-optimize-evm-only'\n    IR_OPTIMIZE_EVM_ONLY = 'ir-optimize-evm-only'\n    LEGACY_OPTIMIZE_EVM_YUL = 'legacy-optimize-evm+yul'\n    IR_OPTIMIZE_EVM_YUL = 'ir-optimize-evm+yul'\n\n\ndef compiler_settings(evm_version: str, via_ir: bool = False, optimizer: bool = False, yul: bool = False) -> dict:\n    return {\n        \"optimizer\": {\"enabled\": optimizer, \"details\": {\"yul\": yul}},\n        \"evmVersion\": evm_version,\n        \"viaIR\": via_ir,\n    }\n\n\ndef settings_from_preset(preset: SettingsPreset, evm_version: str) -> dict:\n    return {\n        SettingsPreset.LEGACY_NO_OPTIMIZE:       compiler_settings(evm_version),\n        SettingsPreset.IR_NO_OPTIMIZE:           compiler_settings(evm_version, via_ir=True),\n        SettingsPreset.LEGACY_OPTIMIZE_EVM_ONLY: compiler_settings(evm_version, optimizer=True),\n        SettingsPreset.IR_OPTIMIZE_EVM_ONLY:     compiler_settings(evm_version, via_ir=True, optimizer=True),\n        SettingsPreset.LEGACY_OPTIMIZE_EVM_YUL:  compiler_settings(evm_version, optimizer=True, yul=True),\n        SettingsPreset.IR_OPTIMIZE_EVM_YUL:      compiler_settings(evm_version, via_ir=True, optimizer=True, yul=True),\n    }[preset]\n\n\ndef parse_custom_presets(presets: List[str]) -> Set[SettingsPreset]:\n    return {SettingsPreset(p) for p in presets}\n\ndef parse_command_line(description: str, args: List[str]):\n    arg_parser = ArgumentParser(description)\n    arg_parser.add_argument(\n        \"solc_binary_type\",\n        metavar=\"solc-binary-type\",\n        type=str,\n        default=\"native\",\n        choices=[\"native\", \"solcjs\"],\n        help=\"\"\"Solidity compiler binary type\"\"\",\n    )\n    arg_parser.add_argument(\n        \"solc_binary_path\",\n        metavar=\"solc-binary-path\",\n        type=Path,\n        help=\"\"\"Path to solc binary\"\"\",\n    )\n    arg_parser.add_argument(\n        \"selected_presets\",\n        metavar=\"selected-presets\",\n        help=\"\"\"List of compiler settings presets\"\"\",\n        nargs='*',\n    )\n    return arg_parser.parse_args(args)\n\n\ndef download_project(test_dir: Path, repo_url: str, ref: str = \"<latest-release>\"):\n    print(f\"Cloning {repo_url}...\")\n    # Clone the repo ignoring all blobs until needed by git.\n    # This allows access to commit history but with a fast initial clone\n    subprocess.run([\"git\", \"clone\", \"--filter\", \"blob:none\", repo_url, test_dir.resolve()], check=True)\n    if not test_dir.exists():\n        raise RuntimeError(\"Failed to clone the project.\")\n    os.chdir(test_dir)\n\n    # If the ref is '<latest-release>' try to use the latest tag as ref\n    # NOTE: Sadly this will not work with monorepos and may not always\n    # return the latest tag.\n    if ref == \"<latest-release>\":\n        tags = subprocess.check_output(\n            [\"git\", \"tag\", \"--sort\", \"-v:refname\"],\n            encoding=\"ascii\"\n        ).strip().split('\\n')\n        if len(tags) == 0:\n            raise RuntimeError(\"Failed to retrieve latest release tag.\")\n        ref = tags[0]\n\n    print(f\"Using ref: {ref}\")\n    subprocess.run([\"git\", \"checkout\", ref], check=True)\n\n    if (test_dir / \".gitmodules\").exists():\n        subprocess.run([\"git\", \"submodule\", \"update\", \"--init\"], check=True)\n\n    print(f\"Current commit hash: {git_commit_hash()}\")\n\n\ndef parse_solc_version(solc_version_string: str) -> str:\n    solc_version_match = re.search(SOLC_FULL_VERSION_REGEX, solc_version_string)\n    if solc_version_match is None:\n        raise RuntimeError(f\"Solc version could not be found in: {solc_version_string}.\")\n    return solc_version_match.group(1)\n\n\ndef get_solc_short_version(solc_full_version: str) -> str:\n    solc_short_version_match = re.search(SOLC_SHORT_VERSION_REGEX, solc_full_version)\n    if solc_short_version_match is None:\n        raise RuntimeError(f\"Error extracting short version string from: {solc_full_version}.\")\n    return solc_short_version_match.group(1)\n\n\ndef store_benchmark_report(self):\n    raise NotImplementedError()\n\n\ndef replace_version_pragmas(test_dir: Path):\n    \"\"\"\n    Replace fixed-version pragmas (part of Consensys best practice).\n    Include all directories to also cover node dependencies.\n    \"\"\"\n    print(\"Replacing fixed-version pragmas...\")\n    for source in test_dir.glob(\"**/*.sol\"):\n        content = source.read_text(encoding=\"utf-8\")\n        content = re.sub(r\"pragma solidity [^;]+;\", r\"pragma solidity >=0.0;\", content)\n        with open(source, \"w\", encoding=\"utf-8\") as f:\n            f.write(content)\n"
  },
  {
    "path": "scripts/externalTests/update_external_repos.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Clones external test repositories from solidity-external-tests organization\n# and for each of them pulls latest upstream changes from the main branch and\n# pushes them to our fork.\n#\n# The script assumes that the current user has write access to\n# solidity-external-tests and that git is configured to be able to push there\n# without specifying the password (e.g. with the key already unlocked and loaded\n# into ssh-agent). Otherwise git will keep asking for password for each repository.\n#\n# Usage:\n#\n#    ./update_external_repos.sh [<target_dir>]\n#\n# <target_dir>: directory where the clones of the repositories are stored.\n#               If omitted, a temporary directory will be created.\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2022 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -euo pipefail\n\ntarget_dir=\"${1:-$(mktemp -d -t update_external_repos_XXXXXX)}\"\n\nfunction clone_repo\n{\n    local upstream_user=\"$1\"\n    local upstream_repo=\"$2\"\n    local fork_name=\"${3:-$upstream_repo}\"\n\n    if [[ ! -d $fork_name ]]; then\n        git clone \"git@github.com:solidity-external-tests/${fork_name}.git\" --no-checkout\n    else\n        echo \"Reusing existing repo: ${fork_name}.\"\n    fi\n\n    pushd \"$fork_name\" > /dev/null\n    git remote rm upstream 2> /dev/null || true\n    git remote add upstream \"https://github.com/${upstream_user}/${upstream_repo}\"\n    popd > /dev/null\n}\n\nfunction sync_branch\n{\n    local fork_name=\"$1\"\n    local branch=\"$2\"\n\n    echo \"${fork_name}: syncing branch ${branch}...\"\n    pushd \"$fork_name\" > /dev/null\n    git fetch upstream \"$branch\" --quiet\n    git checkout -B \"$branch\" --track \"upstream/$branch\" --quiet\n    git merge \"upstream/${branch}\" --ff-only --quiet\n    git push origin \"$branch\"\n    popd > /dev/null\n}\n\nmkdir -p \"$target_dir\"\n\necho \"Entering ${target_dir}\"\ncd \"$target_dir\"\n\nclone_repo brinktrade        brink-core\nclone_repo dapphub           dappsys-monolithic\nclone_repo element-fi        elf-contracts\nclone_repo ensdomains        ens-contracts\nclone_repo euler-xyz         euler-contracts\nclone_repo cowprotocol       contracts                 gp2-contracts\nclone_repo gnosis            mock-contract\nclone_repo gnosis            util-contracts\nclone_repo JoinColony        colonyNetwork\nclone_repo mycelium-ethereum perpetual-pools-contracts\nclone_repo OpenZeppelin      openzeppelin-contracts\nclone_repo paulrberg         prb-math\nclone_repo pooltogether      v4-core                   pooltogether-v4-core\nclone_repo safe-global       safe-contracts\nclone_repo smartcontractkit  chainlink\nclone_repo sushiswap         trident\nclone_repo Uniswap           v2-core                   uniswap-v2-core\nclone_repo Uniswap           v3-core                   uniswap-v3-core\nclone_repo wighawag          bleeps\nclone_repo yieldprotocol     yield-liquidator-v2\n\nsync_branch brink-core                master\nsync_branch dappsys-monolithic        master\nsync_branch elf-contracts             main\nsync_branch ens-contracts             master\nsync_branch euler-contracts           master\nsync_branch gp2-contracts             main\nsync_branch mock-contract             master\nsync_branch util-contracts            main\nsync_branch colonyNetwork             develop\nsync_branch perpetual-pools-contracts develop\nsync_branch openzeppelin-contracts    master\nsync_branch prb-math                  main\nsync_branch pooltogether-v4-core      master\nsync_branch safe-contracts            main\nsync_branch chainlink                 develop\nsync_branch trident                   master\nsync_branch uniswap-v2-core           master\nsync_branch uniswap-v3-core           main\nsync_branch bleeps                    main\nsync_branch yield-liquidator-v2       master\n"
  },
  {
    "path": "scripts/extract_test_cases.py",
    "content": "#!/usr/bin/env python3\n#\n# This script reads C++ or RST source files and writes all\n# multi-line strings into individual files.\n# This can be used to extract the Solidity test cases\n# into files for e.g. fuzz testing as\n# scripts/isolate_tests.py test/libsolidity/*\n\nimport sys\nimport re\n\ndef extract_test_cases(_path):\n    with open(_path, mode='rb', encoding='utf8') as f:\n        lines = f.read().splitlines()\n\n    inside = False\n    delimiter = ''\n    test = ''\n\n    ctr = 1\n    test_name = ''\n\n    for l in lines:\n        if inside:\n            if l.strip().endswith(')' + delimiter + '\";'):\n                with open(f'{ctr:03d}_{test_name}.sol', mode='wb', encoding='utf8') as f:\n                    f.write(test)\n                ctr += 1\n                inside = False\n                test = ''\n            else:\n                l = re.sub('^\\t\\t', '', l)\n                l = l.replace('\\t', '        ')\n                test += l + '\\n'\n        else:\n            m = re.search(r'BOOST_AUTO_TEST_CASE\\(([^(]*)\\)', l.strip())\n            if m:\n                test_name = m.group(1)\n            m = re.search(r'R\"([^(]*)\\($', l.strip())\n            if m:\n                inside = True\n                delimiter = m.group(1)\n\nif __name__ == '__main__':\n    extract_test_cases(sys.argv[1])\n"
  },
  {
    "path": "scripts/gas_diff_stats.py",
    "content": "#!/usr/bin/env python3\n\"\"\"Summarizes gas differences from semantic test diff.\n\nThe script collects all gas differences present in git diff of semantic tests\nand summarizes them in the form of a table that's ready to post in a GitHub comment.\nOnly changes that are already committed are taken into account.\nChanges that are only staged or not staged or committed at all are ignored.\n\nUseful for reviewing the gas impact of a specific PR / branch.\nInstead of tediously going through each individual change, it's recommended to review the table.\n\nDependencies: parsec, tabulate\n\"\"\"\n\nimport subprocess\nimport sys\nfrom argparse import ArgumentParser, RawDescriptionHelpFormatter\nfrom pathlib import Path\nfrom enum import Enum\nfrom parsec import generate, ParseError, regex, string, optional\nfrom tabulate import tabulate\n\nclass Kind(Enum):\n    Ir = 1\n    IrOptimized = 2\n    Legacy = 3\n    LegacyOptimized = 4\n    SsaCFGOptimized = 5\n\nclass Diff(Enum):\n    Minus = 1\n    Plus = 2\n\nSEMANTIC_TEST_DIR = Path(\"test/libsolidity/semanticTests/\")\n\nminus = string(\"-\").result(Diff.Minus)\nplus = string(\"+\").result(Diff.Plus)\n\nspace = string(\" \")\ncomment = string(\"//\")\ncolon = string(\":\")\n\ngas_ir = string(\"gas ir\").result(Kind.Ir)\ngas_ir_optimized = string(\"gas irOptimized\").result(Kind.IrOptimized)\ngas_legacy_optimized = string(\"gas legacyOptimized\").result(Kind.LegacyOptimized)\ngas_legacy = string(\"gas legacy\").result(Kind.Legacy)\ngas_ssa_cfg_optimized = string(\"gas ssaCFGOptimized\").result(Kind.SsaCFGOptimized)\ncode_suffix = string(\"code\")\n\ndef number() -> int:\n    \"\"\"Parse number.\"\"\"\n    return regex(r\"([0-9]*)\").parsecmap(int)\n\n@generate\ndef diff_string() -> (Kind, Diff, int):\n    \"\"\"Usage: diff_string.parse(string)\n\n    Example string:\n\n    -// gas irOptimized: 138070\n\n    \"\"\"\n    diff_kind = yield minus | plus\n    yield comment\n    yield space\n    codegen_kind = yield gas_ssa_cfg_optimized ^ gas_ir_optimized ^ gas_ir ^ gas_legacy_optimized ^ gas_legacy\n    yield optional(space)\n    yield optional(code_suffix)\n    yield colon\n    yield space\n    val = yield number()\n    return (diff_kind, codegen_kind, val)\n\ndef collect_statistics(lines) -> (int, int, int, int, int, int, int, int):\n    \"\"\"Returns\n\n    (old_ir_optimized, old_legacy_optimized, old_legacy, old_ssa_cfg_optimized,\n    new_ir_optimized, new_legacy_optimized, new_legacy, new_ssa_cfg_optimized)\n\n    All the values in the same file (in the diff) are summed up.\n\n    \"\"\"\n    if not lines:\n        raise RuntimeError(\"Empty list\")\n\n    out = [\n        parsed\n        for line in lines\n        if line.startswith('+// gas ') or line.startswith('-// gas ')\n        if (parsed := diff_string.parse(line)) is not None\n    ]\n    diff_kinds = [Diff.Minus, Diff.Plus]\n    codegen_kinds = [Kind.IrOptimized, Kind.LegacyOptimized, Kind.Legacy, Kind.SsaCFGOptimized]\n    return tuple(\n        sum(\n            val\n            for (diff_kind, codegen_kind, val) in out\n            if diff_kind == _diff_kind and codegen_kind == _codegen_kind\n        )\n        for _diff_kind in diff_kinds\n        for _codegen_kind in codegen_kinds\n    )\n\ndef semantictest_statistics(base_branch: str):\n    \"\"\"Prints the tabulated statistics that can be pasted in github.\"\"\"\n    def parse_git_diff(fname):\n        diff_output = subprocess.check_output(\n            [\"git\", \"diff\", \"--unified=0\", base_branch, \"HEAD\", fname],\n            universal_newlines=True\n        ).splitlines()\n        if len(diff_output) == 0:\n            return None\n        return collect_statistics(diff_output)\n\n    def percent(old, new):\n        return (int(new) - int(old)) / int(old) * 100 if int(old) != 0 else None\n\n    def percent_or_zero(old, new):\n        result = percent(old, new)\n        return result if result is not None else 0\n\n    def format_percent(percentage):\n        if percentage is None:\n            return ''\n        prefix = (\n            # Distinguish actual zero from very small differences\n            '+' if round(percentage) == 0 and percentage > 0 else\n            '-' if round(percentage) == 0 and percentage < 0 else\n            ''\n        )\n        return f'{prefix}{round(percentage)}%'\n\n    def stat(old, new):\n        return format_percent(percent(old, new))\n\n    table = []\n\n    if not SEMANTIC_TEST_DIR.is_dir():\n        sys.exit(f\"Semantic tests not found. '{SEMANTIC_TEST_DIR.absolute()}' is missing or not a directory.\")\n\n    for path in SEMANTIC_TEST_DIR.rglob(\"*.sol\"):\n        fname = path.as_posix()\n        parsed = parse_git_diff(fname)\n        if parsed is None:\n            continue\n        assert len(parsed) == 8\n        ir_optimized = stat(parsed[0], parsed[4])\n        legacy_optimized = stat(parsed[1], parsed[5])\n        legacy = stat(parsed[2], parsed[6])\n        ssa_cfg_optimized = stat(parsed[3], parsed[7])\n        fname = f\"`{fname.split('/', 3)[-1]}`\"\n        average = ((\n            percent_or_zero(parsed[0], parsed[4]) +\n            percent_or_zero(parsed[1], parsed[5]) +\n            percent_or_zero(parsed[2], parsed[6]) +\n            percent_or_zero(parsed[3], parsed[7])\n        ) / 4)\n        table += [[average, fname, ir_optimized, legacy_optimized, legacy, ssa_cfg_optimized]]\n\n    sorted_table = [row[1:] for row in sorted(table, reverse=True)]\n\n    if table:\n        print(\"<details><summary>Click for a table of gas differences</summary>\\n\")\n        table_header = [\"File name\", \"IR optimized\", \"Legacy optimized\", \"Legacy\", \"SSA CFG optimized\"]\n        print(tabulate(sorted_table, headers=table_header, tablefmt=\"github\"))\n        print(\"</details>\")\n    else:\n        print(\"No differences found.\")\n\ndef main():\n    parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter)\n    parser.add_argument(\n        '--base',\n        dest='base_branch',\n        default='origin/develop',\n        help='The base branch to diff against. default: origin/develop',\n    )\n    options = parser.parse_args()\n\n    try:\n        semantictest_statistics(options.base_branch)\n    except subprocess.CalledProcessError as exception:\n        sys.exit(f\"Error in the git diff:\\n{exception.output}\")\n    except ParseError as exception:\n        sys.exit(\n            f\"ParseError: {exception}\\n\\n\"\n            f\"{exception.text}\\n\"\n            f\"{' ' * exception.index}^\\n\"\n        )\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "scripts/get_nightly_version.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Prints the exact version string that would be used to describe a nightly\n# build of the compiler.\n#\n# The documentation for solidity is hosted at:\n#\n#     https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2017 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nscript_dir=\"$(dirname \"$0\")\"\n\nsolidity_version=$(\"${script_dir}/get_version.sh\")\nlast_commit_timestamp=$(git log -1 --date=iso --format=%ad HEAD)\nlast_commit_date=$(date --date=\"$last_commit_timestamp\" --utc +%Y.%-m.%-d)\nlast_commit_hash=$(git rev-parse --short=8 HEAD)\n\necho \"v${solidity_version}-nightly.${last_commit_date}+commit.${last_commit_hash}\"\n"
  },
  {
    "path": "scripts/get_version.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Prints version of the Solidity compiler that the source code corresponds to.\n#\n# The documentation for solidity is hosted at:\n#\n#     https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2017 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -eu\n\nversion=$(sed -n -E -e 's/^\\s*set\\(PROJECT_VERSION \"([0-9.]+)\"\\)\\s*$/\\1/p' \"$(dirname \"$0\")/../CMakeLists.txt\")\n\n# Sanity check. Sed does not fail if it does not find a match or finds more than one.\n[[ $version =~ ^[0-9.]+$ ]] || { echo \"Failed to find version in CMakeLists.txt\"; exit 1; }\n\necho \"$version\"\n"
  },
  {
    "path": "scripts/install_deps.ps1",
    "content": "$ErrorActionPreference = \"Stop\"\n\n# Needed for Invoke-WebRequest to work via CI.\n$progressPreference = \"silentlyContinue\"\n\nif ( -not (Test-Path \"$PSScriptRoot\\..\\deps\\boost\") ) {\n  New-Item -ItemType Directory -Force -Path \"$PSScriptRoot\\..\\deps\"\n\n  Invoke-WebRequest -URI \"https://github.com/Kitware/CMake/releases/download/v3.27.4/cmake-3.27.4-windows-x86_64.zip\" -OutFile cmake.zip\n  if ((Get-FileHash cmake.zip).Hash -ne \"e5e060756444d0b2070328a8821c1ceb62bd6d267aae61bfff06f96c7ec943a6\") {\n    throw 'Downloaded CMake source package has wrong checksum.'\n  }\n  tar -xf cmake.zip\n  mv cmake-3.27.4-windows-x86_64 \"$PSScriptRoot\\..\\deps\\cmake\"\n  Remove-Item cmake.zip\n\n  Invoke-WebRequest -URI \"https://github.com/ccache/ccache/releases/download/v4.12.2/ccache-4.12.2-windows-x86_64.zip\" -OutFile ccache.zip\n  if ((Get-FileHash ccache.zip).Hash -ne \"82c1b130b25cc162531dc7a062dc5ea99349cd536bc9eba8a66d976802d66516\") {\n    throw 'Downloaded ccache package has wrong checksum.'\n  }\n  tar -xf ccache.zip\n  mv ccache-4.12.2-windows-x86_64 \"$PSScriptRoot\\..\\deps\\ccache\"\n  # ccache MSVC guide: https://github.com/ccache/ccache/wiki/MS-Visual-Studio\n  # Replace ccache.exe as cl.exe so MSBuild still sees \"cl.exe\" while ccache wraps the real compiler.\n  Copy-Item -Force \"$PSScriptRoot\\..\\deps\\ccache\\ccache.exe\" \"$PSScriptRoot\\..\\deps\\ccache\\cl.exe\"\n  Remove-Item ccache.zip\n\n  # FIXME: The default user agent results in Artifactory treating Invoke-WebRequest as a browser\n  # and serving it a page that requires JavaScript.\n  Invoke-WebRequest -URI \"https://archives.boost.io/release/1.83.0/source/boost_1_83_0.zip\" -OutFile boost.zip -UserAgent \"\"\n  if ((Get-FileHash boost.zip).Hash -ne \"c86bd9d9eef795b4b0d3802279419fde5221922805b073b9bd822edecb1ca28e\") {\n    throw 'Downloaded Boost source package has wrong checksum.'\n  }\n  tar -xf boost.zip\n  Remove-Item boost.zip\n  cd boost_1_83_0\n  .\\bootstrap.bat\n  .\\b2 -j4 -d0 link=static runtime-link=static variant=release threading=multi address-model=64 --with-filesystem --with-system --with-program_options --with-test --prefix=\"$PSScriptRoot\\..\\deps\\boost\" install\n  if ( -not $? ) { throw \"Error building boost.\" }\n  cd ..\n  Remove-Item -LiteralPath .\\boost_1_83_0 -Force -Recurse\n}\n"
  },
  {
    "path": "scripts/install_evmone.ps1",
    "content": "$ErrorActionPreference = \"Stop\"\n\n# Needed for Invoke-WebRequest to work via CI.\n$progressPreference = \"silentlyContinue\"\n\nInvoke-WebRequest -URI \"https://github.com/ipsilon/evmone/releases/download/v0.16.0/evmone-0.16.0-windows-amd64.zip\" -OutFile \"evmone.zip\"\ntar -xf evmone.zip \"bin/evmone.dll\"\nmv bin/evmone.dll deps/\n"
  },
  {
    "path": "scripts/isolate_tests.py",
    "content": "#!/usr/bin/env python3\n#\n# This script reads C++ or RST source files and writes all\n# multi-line strings into individual files.\n# This can be used to extract the Solidity test cases\n# into files for e.g. fuzz testing as\n# scripts/isolate_tests.py test/libsolidity/*\n\nimport re\nimport os\nimport hashlib\nfrom os.path import join, isfile, basename\nfrom argparse import ArgumentParser\nfrom textwrap import indent, dedent\n\ndef extract_test_cases(path):\n    with open(path, encoding=\"utf8\", errors='ignore', mode='r', newline='') as file:\n        lines = file.read().splitlines()\n\n    inside = False\n    delimiter = ''\n    tests = []\n\n    for l in lines:\n        if inside:\n            if l.strip().endswith(')' + delimiter + '\";'):\n                inside = False\n            else:\n                tests[-1] += l + '\\n'\n        else:\n            m = re.search(r'R\"([^(]*)\\($', l.strip())\n            if m:\n                inside = True\n                delimiter = m.group(1)\n                tests += ['']\n\n    return tests\n\ndef extract_solidity_docs_cases(path):\n    tests = extract_docs_cases(path, [\".. code-block:: solidity\", '::'])\n\n    codeStart = \"(// SPDX-License-Identifier:|pragma solidity|contract.*{|library.*{|interface.*{)\"\n\n    # Filter out tests that are not supposed to be compilable.\n    return [\n        test.lstrip(\"\\n\")\n        for test in tests\n        if re.search(r'^\\s{4}' + codeStart, test, re.MULTILINE) is not None\n    ]\n\ndef extract_yul_docs_cases(path):\n    tests = extract_docs_cases(path, [\".. code-block:: yul\"])\n\n    def wrap_in_object(code):\n        for line in code.splitlines():\n            line = line.lstrip()\n            if line.startswith(\"//\"):\n                continue\n            if not line.startswith(\"object\") and not line.startswith(\"{\"):\n                return indent(f\"{{\\n{code.rstrip()}\\n}}\\n\\n\", \"    \")\n            break\n\n        return code\n\n    return [\n        wrap_in_object(test)\n        for test in tests\n        if test.strip() != \"\"\n    ]\n\n# Extract code examples based on the 'beginMarker' parameter\n# up until we reach EOF or a line that is not empty and doesn't start with 4\n# spaces.\ndef extract_docs_cases(path, beginMarkers):\n    immediatelyAfterMarker = False\n    insideBlock = False\n    tests = []\n\n    # Collect all snippets of indented blocks\n    with open(path, mode='r', errors='ignore', encoding='utf8', newline='') as f:\n        lines = f.read().splitlines()\n\n    for line in lines:\n        if insideBlock:\n            if immediatelyAfterMarker:\n                # Skip Sphinx instructions and empty lines between them\n                if line == '' or line.lstrip().startswith(\":\"):\n                    continue\n\n            if line == '' or line.startswith(\" \"):\n                tests[-1] += line + \"\\n\"\n                immediatelyAfterMarker = False\n                continue\n\n            insideBlock = False\n        if any(map(line.lower().startswith, beginMarkers)):\n            insideBlock = True\n            immediatelyAfterMarker = True\n            tests += ['']\n\n    return tests\n\ndef write_cases(f, solidityTests, yulTests):\n    cleaned_filename = f.replace(\".\",\"_\").replace(\"-\",\"_\").replace(\" \",\"_\").lower()\n    for language, test in [(\"sol\", t) for t in solidityTests] + [(\"yul\", t) for t in yulTests]:\n        # When code examples are extracted they are indented by 8 spaces, which violates the style guide,\n        # so before checking remove 4 spaces from each line.\n        remainder = dedent(test)\n        source_code_hash = hashlib.sha256(test.encode(\"utf-8\")).hexdigest()\n        sol_filename = f'test_{source_code_hash}_{cleaned_filename}.{language}'\n        with open(sol_filename, mode='w', encoding='utf8', newline='') as fi:\n            fi.write(remainder)\n\ndef extract_and_write(path, language):\n    assert language in [\"solidity\", \"yul\", \"\"]\n    yulCases = []\n    cases = []\n\n    if path.lower().endswith('.rst'):\n        if language in (\"solidity\", \"\"):\n            cases = extract_solidity_docs_cases(path)\n\n        if language in (\"yul\", \"\"):\n            yulCases  = extract_yul_docs_cases(path)\n    elif path.endswith('.sol'):\n        if language in (\"solidity\", \"\"):\n            with open(path, mode='r', encoding='utf8', newline='') as f:\n                cases = [f.read()]\n    else:\n        cases = extract_test_cases(path)\n\n    write_cases(basename(path), cases, yulCases)\n\nif __name__ == '__main__':\n    script_description = (\n        \"Reads Solidity, C++ or RST source files and extracts compilable solidity and yul code blocks from them. \"\n        \"Can be used to generate test cases to validate code examples. \"\n    )\n\n    parser = ArgumentParser(description=script_description)\n    parser.add_argument(dest='path', help='Path to file or directory to look for code in.')\n    parser.add_argument(\n        '-l', '--language',\n        dest='language',\n        choices=[\"yul\", \"solidity\"],\n        default=\"\",\n        action='store',\n        help=\"Extract only code blocks in the given language\"\n    )\n    options = parser.parse_args()\n    path = options.path\n\n    if isfile(path):\n        extract_and_write(path, options.language)\n    else:\n        for root, subdirs, files in os.walk(path):\n            if '_build' in subdirs:\n                subdirs.remove('_build')\n            if 'compilationTests' in subdirs:\n                subdirs.remove('compilationTests')\n            for f in files:\n                if basename(f) == \"invalid_utf8_sequence.sol\":\n                    continue  # ignore the test with broken utf-8 encoding\n                path = join(root, f)\n                extract_and_write(path, options.language)\n"
  },
  {
    "path": "scripts/isoltest.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nREPO_ROOT=\"$(dirname \"$0\")\"/..\nexec \"${REPO_ROOT}/build/test/tools/isoltest\" --testpath \"${REPO_ROOT}/test\"\n"
  },
  {
    "path": "scripts/list_contributors.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# Creates a list containing names of people who contributed to the project, for use\n# in release notes. The names come from the author field on the commits between\n# the current revision and the one specified as argument.\n#\n# Note that the output often requires extra manual processing to remove entries\n# that refer to the same person (diacritics vs no diacritics, name vs nickname, etc.).\n#\n# Usage:\n#    <script name>.sh <revision>\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2023 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -euo pipefail\n\nscript_dir=$(dirname \"$0\")\n# shellcheck source=scripts/common.sh\nsource \"${script_dir}/common.sh\"\n\n(( $# == 1)) || fail \"Wrong number of arguments. Usage: $0 <revision>.\"\n\nrevision=\"$1\"\n\n# NOTE: Commas are removed from any names containing them. It would look confusing otherwise, given\n# that the list is delimited by commas. Hopefully no contributor uses a comma as their nickname.\ngit shortlog --summary \"${revision}..origin/develop\" |\n    cut --field 2 |\n    tr --delete , |\n    sort |\n    uniq |\n    paste --serial --delimiter=, |\n    sed -e 's/,/, /g'\n"
  },
  {
    "path": "scripts/prerelease_suffix.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n(( $# <= 2 )) || { >&2 echo \"Usage: $0 [PRERELEASE_SOURCE] [GIT_TAG]\"; exit 1; }\nprerelease_source=\"${1:-nightly}\"\ngit_tag=\"${2:-}\"\nFORCE_RELEASE=\"${FORCE_RELEASE:-}\"\n\nGNU_DATE=\"date\"\nif [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n    GNU_DATE=gdate\nfi\n\nif [[ $FORCE_RELEASE != \"\" || $git_tag =~ ^v[0-9.]+$ ]]; then\n    echo -n\nelif [[ $git_tag =~ ^v[0-9.]+-pre. ]]; then\n    echo -n \"pre.${git_tag#*-pre.}\"\nelse\n    # Use last commit date rather than build date to avoid ending up with builds for\n    # different platforms having different version strings (and therefore producing different bytecode)\n    # if the CI is triggered just before midnight.\n    # NOTE: The -local suffix makes git not use the timezone from the commit but instead convert to\n    # local one, which we explicitly set to UTC.\n    # NOTE: git --date is supposed to support the %-m/%-d format too, but it does not seem to\n    # work on Windows. Without it we get leading zeros for month and day.\n    last_commit_date=$(TZ=UTC git show --quiet --date=\"format-local:%Y-%m-%d\" --format=\"%cd\")\n    last_commit_date_stripped=$(\"$GNU_DATE\" --date \"$last_commit_date\" \"+%Y.%-m.%-d\")\n    echo -n \"${prerelease_source}.${last_commit_date_stripped}\"\nfi\n"
  },
  {
    "path": "scripts/pylint_all.py",
    "content": "#! /usr/bin/env python3\n\n\"\"\"\nRuns pylint on all Python files in project directories known to contain Python scripts.\n\"\"\"\n\nfrom argparse import ArgumentParser\nfrom os import path, walk\nfrom textwrap import dedent\nimport subprocess\nimport sys\n\nPROJECT_ROOT = path.dirname(path.dirname(path.realpath(__file__)))\nPYLINT_RCFILE = f\"{PROJECT_ROOT}/scripts/pylintrc\"\n\nSGR_INFO = \"\\033[1;32m\"\nSGR_CLEAR = \"\\033[0m\"\n\ndef pylint_all_filenames(dev_mode, rootdirs):\n    \"\"\" Performs pylint on all python files within given root directory (recursively).  \"\"\"\n\n    BARE_COMMAND = [\n        \"pylint\",\n        f\"--rcfile={PYLINT_RCFILE}\",\n        \"--output-format=colorized\",\n        \"--score=n\"\n    ]\n\n    filenames = []\n    for rootdir in rootdirs:\n        for rootpath, _, filenames_w in walk(rootdir):\n            for filename in filenames_w:\n                if filename.endswith('.py'):\n                    filenames.append(path.join(rootpath, filename))\n\n    if not dev_mode:\n        # NOTE: We could just give pylint the directories and it would find the files on its\n        # own but it would treat them as packages, which would result in lots of import errors.\n        command_line = BARE_COMMAND + filenames\n        return subprocess.run(command_line, check=False).returncode == 0\n\n    for i, filename in enumerate(filenames):\n        command_line = BARE_COMMAND + [filename]\n        print(\n            f\"{SGR_INFO}\"\n            f\"[{i + 1}/{len(filenames)}] \"\n            f\"Running pylint on file: {filename}{SGR_CLEAR}\"\n        )\n\n        process = subprocess.run(command_line, check=False)\n\n        if process.returncode != 0:\n            return False\n\n    print()\n    return True\n\n\ndef parse_command_line():\n    script_description = dedent(\"\"\"\n        Runs pylint on all Python files in project directories known to contain Python scripts.\n\n        This script is meant to be run from the CI but can also be easily used in the local dev\n        environment.\n    \"\"\")\n\n    parser = ArgumentParser(description=script_description)\n    parser.add_argument(\n        '-d', '--dev-mode',\n        dest='dev_mode',\n        default=False,\n        action='store_true',\n        help=(\n            \"Abort on first error. \"\n            \"In this mode every script is passed to pylint separately. \"\n        )\n    )\n    return parser.parse_args()\n\n\ndef main():\n    options = parse_command_line()\n\n    rootdirs = [\n        f\"{PROJECT_ROOT}/docs\",\n        f\"{PROJECT_ROOT}/scripts\",\n        f\"{PROJECT_ROOT}/test\",\n    ]\n    success = pylint_all_filenames(options.dev_mode, rootdirs)\n\n    if not success:\n        sys.exit(1)\n    else:\n        print(\"No problems found.\")\n\n\nif __name__ == \"__main__\":\n    try:\n        main()\n    except KeyboardInterrupt:\n        sys.exit(\"Interrupted by user. Exiting.\")\n"
  },
  {
    "path": "scripts/pylintrc",
    "content": "# vim:et:ts=4\n[MESSAGES CONTROL]\n\n# Disable the message, report, category or checker with the given id(s). You\n# can either give multiple identifiers separated by comma (,) or put this\n# option multiple times (only on the command line, not in the configuration\n# file where it should appear only once).You can also use \"--disable=all\" to\n# disable everything first and then re-enable specific checks. For example, if\n# you want to run only the similarities checker, you can use \"--disable=all\n# --enable=similarities\". If you want to run only the classes checker, but have\n# no Warning level messages displayed, use\"--disable=all --enable=classes\n# --disable=W\"\n\n# ATTENTION: This list should be extended with care, consider using NOLINT comments inside your\n# python files instead, as the goal is actually to reduce the list of globally disabled checks.\n#\n# TODO: What could be eliminated in future PRs: invalid-name, pointless-string-statement, redefined-outer-name.\ndisable=\n    bad-indentation,\n    duplicate-code,\n    invalid-name,\n    missing-docstring,\n    no-else-return,\n    pointless-string-statement,\n    redefined-outer-name,\n    superfluous-parens,\n    too-few-public-methods,\n    too-many-arguments,\n    too-many-branches,\n    too-many-instance-attributes,\n    too-many-locals,\n    too-many-positional-arguments,\n    too-many-public-methods,\n    too-many-statements,\n    ungrouped-imports\n\n[BASIC]\n\n# Good variable names which should always be accepted, separated by a comma\n# added: f, h, x, a, b, p\ngood-names=\n    Run,\n    _,\n    a,\n    b,\n    ex,\n    f,\n    f,\n    h,\n    h,\n    i,\n    j,\n    k,\n    l,\n    m,\n    n,\n    p,\n    x\n\n[FORMAT]\n\n# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.\nexpected-line-ending-format=LF\n\n# Maximum number of characters on a single line.\nmax-line-length=130\n\n[MISCELLANEOUS]\n\nnotes=XXX,TMP\n"
  },
  {
    "path": "scripts/regressions.py",
    "content": "#!/usr/bin/env python3\n\nfrom argparse import ArgumentParser\nimport sys\nimport os\nimport subprocess\nimport re\nimport glob\nimport threading\nimport time\n\nDESCRIPTION = \"\"\"Regressor is a tool to run regression tests in a CI env.\"\"\"\n\nclass PrintDotsThread:\n    \"\"\"Prints a dot every \"interval\" (default is 300) seconds\"\"\"\n\n    def __init__(self, interval=300):\n        self.interval = interval\n\n        thread = threading.Thread(target=self.run, args=())\n        thread.daemon = True\n        thread.start()\n\n    def run(self):\n        \"\"\" Run indefinitely until the main Python thread exits. \"\"\"\n        ## Print an initial newline at the very beginning.\n        print(\"\")\n        while True:\n            # Print dot\n            print(\".\")\n            time.sleep(self.interval)\n\nclass Regressor:\n    _re_sanitizer_log = re.compile(r\"\"\"ERROR: (libFuzzer|UndefinedBehaviorSanitizer)\"\"\")\n\n    def __init__(self, description, args):\n        self._description = description\n        self._args = self.parseCmdLine(description, args)\n        self._repo_root = os.path.dirname(sys.path[0])\n        self._fuzzer_path = os.path.join(self._repo_root,\n                                         \"build/test/tools/ossfuzz\")\n        self._logpath = os.path.join(self._repo_root, \"test_results\")\n\n    @classmethod\n    def parseCmdLine(cls, description, args):\n        argParser = ArgumentParser(description)\n        argParser.add_argument('-o', '--out-dir', required=True, type=str,\n                               help=\"\"\"Directory where test results will be written\"\"\")\n        return argParser.parse_args(args)\n\n    @staticmethod\n    def run_cmd(command, logfile=None, env=None):\n        \"\"\"\n        Args:\n            command (str): command to run\n            logfile (str): log file name\n            env (dict): dictionary holding key-value pairs for bash environment\n                    variables\n\n        Returns:\n            int: The exit status of the command. Exit status codes are:\n                0       -> Success\n                1-255   -> Failure\n        \"\"\"\n        if not logfile:\n            logfile = os.devnull\n\n        if not env:\n            env = os.environ.copy()\n\n        with open(logfile, 'w', encoding='utf8') as logfh:\n            with subprocess.Popen(command, shell=True, executable='/bin/bash',\n                                    env=env, stdout=logfh,\n                                    stderr=subprocess.STDOUT) as proc:\n                ret = proc.wait()\n                logfh.close()\n                return ret\n\n    def process_log(self, logfile):\n        \"\"\"\n        Args:\n            logfile (str): log file name\n\n        Returns:\n            bool: Test status.\n                True       -> Success\n                False      -> Failure\n        \"\"\"\n\n        ## Log may contain non-ASCII characters, so we simply stringify them\n        ## since they don't matter for regular expression matching\n        with open(logfile, 'rb', encoding=None) as f:\n            rawtext = str(f.read())\n        return not re.search(self._re_sanitizer_log, rawtext)\n\n    def run(self):\n        \"\"\"\n        Returns:\n            bool: Test status.\n                True       -> All tests succeeded\n                False      -> At least one test failed\n        \"\"\"\n\n        testStatus = []\n        for fuzzer in glob.iglob(f\"{self._fuzzer_path}/*_ossfuzz\"):\n            basename = os.path.basename(fuzzer)\n            logfile = os.path.join(self._logpath, f\"{basename}.log\")\n            corpus_dir = f\"/tmp/solidity-fuzzing-corpus/{basename}_seed_corpus\"\n            cmd = f\"find {corpus_dir} -type f | xargs -n1 sh -c '{fuzzer} $0 || exit 255'\"\n            self.run_cmd(cmd, logfile=logfile)\n            ret = self.process_log(logfile)\n            if not ret:\n                print(\n                    f\"\\t[-] libFuzzer reported failure for {basename}. \"\n                    \"Failure logged to test_results\")\n                testStatus.append(False)\n            else:\n                print(f\"\\t[+] {basename} passed regression tests.\")\n                testStatus.append(True)\n        return all(testStatus)\n\n\nif __name__ == '__main__':\n    dotprinter = PrintDotsThread()\n    tool = Regressor(DESCRIPTION, sys.argv[1:])\n    sys.exit(not tool.run())\n"
  },
  {
    "path": "scripts/run_proofs.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\n(\nREPO_ROOT=\"$(dirname \"$0\")\"/..\ncd \"$REPO_ROOT\"\n\ngit fetch origin\nerror=0\nfor new_proof in $(git diff origin/develop --name-only test/formal/)\ndo\n\tif [[ -e \"$new_proof\" ]] && [[ \"$new_proof\" == *.py ]]; then\n\t\tset +e\n\t\techo \"Proving $new_proof...\"\n\t\toutput=$(python3 \"$new_proof\")\n\t\tresult=$?\n\t\tset -e\n\n\t\tif [[ \"$result\" != 0 ]]\n\t\tthen\n\t\t\techo \"Proof $(basename \"$new_proof\" \".py\") failed: $output.\"\n\t\t\terror=1\n\t\tfi\n\tfi\ndone\n\nif [[ \"error\" -eq 0 ]]\nthen\n\techo \"All proofs succeeded.\"\nfi\n\nexit $error\n)\n"
  },
  {
    "path": "scripts/solc-bin/bytecode_reports_for_modified_binaries.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# Determines versions of all release binaries from solc-bin repo modified in the\n# specified commit range, finds all release binaries from one, selected platform\n# that match these versions and uses them to produce bytecode reports.\n#\n# The script is meant to be backwards-compatible with older versions of the\n# compiler. Reports are generated via the CLI interface (rather than Standard\n# JSON) in case of native binaries because the JSON interface was not available\n# in very old versions.\n#\n# The script creates one report per binary and file names follow the pattern\n# 'report-<binary name>.txt'.\n#\n# Usage:\n#    <script name>.sh <PLATFORM> <BASE_REF> <TOP_REF> <SOLC_BIN_DIR> <SOLIDITY_DIR>\n#\n# PLATFORM: Platform name, corresponding the one of the top-level directories\n#     in solc-bin.\n# BASE_REF..TOP_REF: Commit range in the solc-bin repository to search for\n#     modified binaries.\n# SOLC_BIN_DIR: Directory containing a checkout of the ethereum/solc-bin\n#    repository with full history. Must be an absolute path.\n# SOLIDITY_DIR: Directory containing a checkout of the ethereum/solidity\n#    repository with full history. Bytecode report will be generated using\n#    scripts from the currently checked out revision. Must be an absolute path.\n#\n# Example:\n#    <script name>.sh linux-amd64 gh-pages pr-branch \"$PWD/solc-bin\" \"$PWD/solidity\"\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2020 solidity contributors.\n#------------------------------------------------------------------------------\n\n# FIXME: Can't use set -u because the old Bash on macOS treats empty arrays as unbound variables\nset -eo pipefail\n\nfunction die\n{\n    # shellcheck disable=SC2059\n    >&2 printf \"ERROR: $1\\n\" \"${@:2}\"\n    exit 1\n}\n\nfunction get_reported_solc_version\n{\n    local solc_binary=\"$1\"\n\n    local version_banner; version_banner=$(\"$solc_binary\" --version)\n\n    if [[ ! $(echo \"$version_banner\" | head -n 1) =~ ^solc,.*$ ]]; then\n        die \"%s\\nFULL OUTPUT:\\n\" \"Invalid format of --version output\" \"$version_banner\"\n    fi\n\n    echo \"$version_banner\" | tail -n 1 | sed -n -E 's/^Version: (.*)$/\\1/p'\n}\n\nfunction validate_reported_version\n{\n    local reported_version=\"$1\"\n    local expected_version_and_commit=\"$2\"\n\n    if [[ $reported_version =~ [\\-.]mod\\. ]]; then\n        die \"Version '%s' reported by the '%s' binary indicates that it was built from modified source.\" \"$reported_version\" \"$expected_version_and_commit\"\n    fi\n\n    local actual_version_and_commit; actual_version_and_commit=$(\n        echo \"$reported_version\" |\n        sed -E 's/^[[:space:]]*([0-9.]+\\+commit\\.[0-9a-f]+)\\..+\\..+$/\\1/'\n    )\n\n    if [[ $actual_version_and_commit != \"$expected_version_and_commit\" ]]; then\n        die \"Binary identifies itself as version '%s' which does not match '%s' present in its name.\" \"$actual_version_and_commit\" \"$expected_version_and_commit\"\n    fi\n\n    echo \"Binary for version ${expected_version_and_commit} reports correct version.\"\n}\n\n(( $# == 5 )) || die \"ERROR: Not enough arguments.\"\n\nplatform=\"$1\"\nbase_ref=\"$2\"\ntop_ref=\"$3\"\nsolc_bin_dir=\"$4\"\nsolidity_dir=\"$5\"\n\nreport_dir=\"$PWD\"\ntmp_dir=$(mktemp -d -t bytecode-reports-XXXXXX)\nsolcjs_dir=\"$tmp_dir/solcjs\"\nscript_dir=\"$solidity_dir/scripts\"\n\n# Set locale to C to prevent it from affecting glob sort order.\nexport LC_ALL=C\n\ncd \"$tmp_dir\"\n\ngit clone https://github.com/argotorg/solc-js.git \"$solcjs_dir\"\ncd \"$solcjs_dir\"\nnpm install\nnpm run build\n\ncd \"${solc_bin_dir}/${platform}/\"\necho \"Commit range: ${base_ref}..${top_ref}\"\n\nmodified_release_versions=$(\n    git diff --name-only \"${base_ref}\" \"${top_ref}\" |\n    sed -n -E 's/^[^\\/]+\\/(solc|soljson)-[0-9a-zA-Z-]+-v([0-9.]+)\\+commit\\.[0-9a-f]+(.[^.]+)?$/\\2/p' |\n    sort -V |\n    uniq\n)\necho \"Release versions modified in the commit range:\"\nif [[ $modified_release_versions != \"\" ]]; then\n    echo \"$modified_release_versions\"\nelse\n    echo \"No modified binaries found.\"\n    exit 0\nfi\n\n# NOTE: We want perform the check when the soljson-* files in bin/ and wasm/ are modified too\n# because in that case the symlinks in emscripten-wasm32/ and emscripten-asmjs/ might remain\n# unchanged but were're assuming that these directories are never directly used as a platform name.\n[[ $platform != bin && $platform != wasm ]] || die \"Invalid platform name.\"\n\nplatform_binaries=\"$(git ls-files \"solc-${platform}-v*+commit.*\" | sort -V)\"\n\nfor binary_name in $platform_binaries; do\n    solidity_version_and_commit=$(echo \"$binary_name\" | sed -n -E 's/^solc-'\"${platform}\"'-v([0-9.]+\\+commit\\.[0-9a-f]+).*$/\\1/p')\n    solidity_version=$(echo \"$solidity_version_and_commit\" | sed -n -E 's/^([0-9.]+).*$/\\1/p')\n\n    if echo \"$modified_release_versions\" | grep -x \"$solidity_version\"; then\n        echo \"Binary ${binary_name} (version ${solidity_version}) matches one of the modified versions.\"\n\n        work_dir=\"${tmp_dir}/${binary_name}\"\n        mkdir \"$work_dir\"\n        cd \"$work_dir\"\n\n        # While bytecode scripts come from the latest compiler, the test files should come from\n        # the Solidity version we're running them against to avoid errors due to breaking syntax changes.\n        git clone --branch \"v${solidity_version}\" \"$solidity_dir\" \"${work_dir}/solidity/\"\n        \"${script_dir}/isolate_tests.py\" \"${work_dir}/solidity/test/\"\n\n        if [[ $platform == emscripten-wasm32 ]] || [[ $platform == emscripten-asmjs ]]; then\n            ln -sf \"${solc_bin_dir}/${platform}/${binary_name}\" \"${solcjs_dir}/soljson.js\"\n            ln -sf \"${solc_bin_dir}/${platform}/${binary_name}\" \"${solcjs_dir}/dist/soljson.js\"\n            npm install \"${solcjs_dir}/dist\"\n            cp \"${script_dir}/bytecodecompare/prepare_report.js\" prepare_report.js\n\n            validate_reported_version \\\n                \"$(node_modules/solc/solc.js --version)\" \\\n                \"$solidity_version_and_commit\"\n\n            # shellcheck disable=SC2035\n            ./prepare_report.js --strip-smt-pragmas *.sol --report-file \"${report_dir}/report-${binary_name}.txt\"\n        else\n            yul_optimizer_flags=()\n            if [[ $solidity_version == 0.6.0 ]] || [[ $solidity_version == 0.6.1 ]]; then\n                yul_optimizer_flags+=(--force-no-optimize-yul)\n            fi\n\n            validate_reported_version \\\n                \"$(get_reported_solc_version \"${solc_bin_dir}/${platform}/${binary_name}\")\" \\\n                \"$solidity_version_and_commit\"\n\n            \"${script_dir}/bytecodecompare/prepare_report.py\" \"${solc_bin_dir}/${platform}/${binary_name}\" \\\n                --interface cli \\\n                --smt-use strip-pragmas \\\n                --report-file \"${report_dir}/report-${binary_name}.txt\" \\\n                \"${yul_optimizer_flags[@]}\"\n        fi\n\n        rm -r \"${work_dir}/solidity/\"\n    else\n        echo \"Binary ${binary_name} (version ${solidity_version}) does not match any modified version. Skipping.\"\n    fi\ndone\n\nrm -r \"$tmp_dir\"\n"
  },
  {
    "path": "scripts/solc-bin/compare_bytecode_reports.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# Compares bytecode reports from multiple compiler versions and platforms to\n# determine if there are any differences.\n#\n# The script does not accept any arguments.\n#\n# The reports should be placed in subdirectories of the current working\n# directory and their names should follow one of the following patterns:\n#\n#     report-solc-<platform>-v<solidity version>+commit.<commit hash>.txt\n#     report-soljson-<platform>-v<solidity version>+commit.<commit hash>.js.txt\n#\n# Reports corresponding to the same version and commit hash are grouped together\n# and the script succeeds only if the files within each group are identical.\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2020 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -euo pipefail\n\nreport_files=\"$(find . -type f -name 'report-*.txt')\"\n[[ $report_files != \"\" ]] || { echo \"No reports found in the working directory.\"; exit 0; }\n\necho \"Available reports:\"\necho \"$report_files\"\n\nversions_in_report_names=$(\n    echo \"$report_files\" |\n    sed -n -E 's/^\\.\\/[^\\/]+\\/report-(solc|soljson)-[0-9a-zA-Z-]+-v([0-9.]+\\+commit\\.[0-9a-f]+)(.[^.]+)?\\.txt$/\\2/p' |\n    sort -V |\n    uniq\n)\n\nnum_failed_comparisons=0\nfor solidity_version_and_commit in $versions_in_report_names; do\n    echo \"Comparing reports for Solidity ${solidity_version_and_commit}:\"\n    mapfile -t report_files_for_version < <(\n        echo \"$report_files\" |\n        sed -n -E '/^\\.\\/[^\\/]+\\/report-(solc|soljson)-[0-9a-zA-Z-]+-v'\"${solidity_version_and_commit//\\+/\\\\+}\"'+(.[^.]+)?\\.txt$/p'\n    )\n\n    diff --report-identical-files --brief --from-file \"${report_files_for_version[@]}\" || ((++num_failed_comparisons))\n    echo\ndone\n\n(( num_failed_comparisons == 0 )) || { echo \"Found bytecode differences in ${num_failed_comparisons} versions\"; exit 1; }\necho \"No bytecode differences found.\"\n"
  },
  {
    "path": "scripts/soltest.sh",
    "content": "#!/usr/bin/env bash\nset -eu\n\nREPO_ROOT=\"$(dirname \"$0\")\"/..\nUSE_DEBUGGER=0\nDEBUGGER=\"gdb --args\"\nBOOST_OPTIONS=()\nSOLTEST_OPTIONS=()\nSOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${REPO_ROOT}/build}\n\nfunction usage\n{\n\techo 2>&1 \"\nUsage: $0 [options] [soltest-options]\nRuns BOOST C++ unit test program, soltest.\n\nOptions:\n  --debug                  soltest invocation prefaced with: \\\"$DEBUGGER\\\"\n  --debugger *dbg-cmd*     soltest prefaced with your own debugger command.\n  --run_test | -t  *name*  filters test unit(s) to include or exclude from test.\n                           This  option can be given several times.\n  --boost-options *x*      Set BOOST option *x*.\n  --show-progress | -p     Set BOOST option --show-progress.\n\nImportant environment variables:\n\nSOLIDITY_BUILD_DIR: Sets directory where test/soltest should be found.\n           The default is \\\"${SOLIDITY_BUILD_DIR}\\\".\n\"\n}\n\nwhile [ $# -gt 0 ]\ndo\n\tcase \"$1\" in\n\t\t--debugger)\n\t\t\tshift\n\t\t\tDEBUGGER=\"$1\"\n\t\t\tUSE_DEBUGGER=1\n\t\t\t;;\n\t\t--debug)\n\t\t\tUSE_DEBUGGER=1\n\t\t\t;;\n\t\t--boost-options)\n\t\t\tshift\n\t\t\tBOOST_OPTIONS+=(\"$1\")\n\t\t\t;;\n\t\t--help)\n\t\t\tusage\n\t\t\texit 0\n\t\t\t;;\n\t\t--run_test | -t )\n\t\t\tshift\n\t\t\tBOOST_OPTIONS+=(-t \"$1\")\n\t\t\t;;\n\t\t--show-progress | -p)\n\t\t\tBOOST_OPTIONS+=(\"$1\")\n\t\t\t;;\n\t\t*)\n\t\t\tSOLTEST_OPTIONS+=(\"$1\")\n\t\t\t;;\n\tesac\n\tshift\ndone\n\nSOLTEST_COMMAND=(\"${SOLIDITY_BUILD_DIR}/test/soltest\" \"${BOOST_OPTIONS[@]}\" -- --testpath \"${REPO_ROOT}/test\" \"${SOLTEST_OPTIONS[@]}\")\n\nif [ \"$USE_DEBUGGER\" -ne \"0\" ]; then\n\t# shellcheck disable=SC2086\n\texec ${DEBUGGER} \"${SOLTEST_COMMAND[@]}\"\nelse\n\texec \"${SOLTEST_COMMAND[@]}\"\nfi\n"
  },
  {
    "path": "scripts/splitSources.py",
    "content": "#!/usr/bin/env python3\n#\n# This script reads a syntaxTest file and writes all\n# sources into separate files. If a source name specifies subdirectories,\n# those will be created too.\n\n# Usage: scripts/splitSources.py pathToTestfile\n# as a result prints\n# -  string of created files separated by whitespaces\n# -  'false' if the file only had one source\n\nimport sys\nimport os\nimport traceback\n\n\ndef uncaught_exception_hook(exc_type, exc_value, exc_traceback):\n    # The script `scripts/ASTImportTest.sh` will interpret return code 3\n    # as a critical error (because of the uncaught exception) and will\n    # terminate further execution.\n    print(\"Unhandled exception: \" + \"\".join(traceback.format_exception(exc_type, exc_value, exc_traceback)))\n    sys.exit(3)\n\n\ndef extractSourceName(line):\n    if line.find(\"/\") > -1:\n        filePath = line[13: line.rindex(\"/\")]\n        # fileName = line[line.rindex(\"/\")+1: line.find(\" ====\")]\n        srcName = line[line.find(\":\")+2: line.find(\" ====\")]\n        return filePath, srcName\n    return False, line[line.find(\":\")+2 : line.find(\" ====\")]\n\n\n# expects the first line of lines to be \"==== Source: sourceName ====\"\n# writes the following source into a file named sourceName\ndef writeSourceToFile(lines):\n    filePath, srcName = extractSourceName(lines[0])\n    # print(\"sourceName is \", srcName)\n    # print(\"filePath is\", filePath)\n    if filePath:\n        os.system(\"mkdir -p \" + filePath)\n    with open(srcName, mode='a+', encoding='utf8', newline='') as f:\n        for idx, line in enumerate(lines[1:]):\n            # write to file\n            if not line.startswith(\"==== Source:\"):\n                f.write(line + '\\n')\n\n            # recursive call if there is another source\n            else:\n                return [srcName] + writeSourceToFile(lines[1+idx:])\n\n    return [srcName]\n\ndef split_sources(filePath, suppress_output = False):\n    sys.excepthook = uncaught_exception_hook\n\n    try:\n        # decide if file has multiple sources\n        with open(filePath, mode='r', encoding='utf8', newline='') as f:\n            lines = f.read().splitlines()\n        if len(lines) >= 1 and lines[0][:12] == \"==== Source:\":\n            srcString = \"\"\n            for src in writeSourceToFile(lines):\n                srcString += src + ' '\n            if not suppress_output:\n                print(srcString)\n            return 0\n        return 1\n\n    except UnicodeDecodeError as ude:\n        print(\"UnicodeDecodeError in '\" + filePath + \"': \" + str(ude))\n        print(\"This is expected for some tests containing invalid utf8 sequences. \"\n              \"Exception will be ignored.\")\n        return 2\n\n\nif __name__ == '__main__':\n    sys.exit(split_sources(sys.argv[1]))\n"
  },
  {
    "path": "scripts/test_antlr_grammar.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nREADLINK=readlink\nif [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n    READLINK=greadlink\nfi\nROOT_DIR=$(${READLINK} -f \"$(dirname \"$0\")\"/..)\nWORKDIR=\"${ROOT_DIR}/build/antlr\"\nANTLR_JAR=\"${ROOT_DIR}/build/deps/antlr4.jar\"\nANTLR_JAR_URI=\"https://www.antlr.org/download/antlr-4.8-complete.jar\"\nBATCH_SIZE=100  # Process 100 files per JVM invocation\n\nSGR_RESET=\"\\033[0m\"\nSGR_BOLD=\"\\033[1m\"\nSGR_GREEN=\"\\033[32m\"\nSGR_RED=\"\\033[31m\"\nSGR_BLUE=\"\\033[34m\"\n\nfunction download_antlr4\n{\n  if [[ ! -e \"$ANTLR_JAR\" ]]\n  then\n    curl -o \"${ANTLR_JAR}\" \"${ANTLR_JAR_URI}\"\n  fi\n}\n\nfunction prepare_workdir\n{\n  mkdir -p \"${ROOT_DIR}/build/deps\"\n  mkdir -p \"${WORKDIR}\"\n  mkdir -p \"${WORKDIR}/src\"\n  mkdir -p \"${WORKDIR}/target\"\n}\n\nprepare_workdir\ndownload_antlr4\n\necho \"Creating parser\"\n(\ncd \"${ROOT_DIR}\"/docs/grammar\n# Create lexer/parser from grammar\njava -jar \"${ANTLR_JAR}\" SolidityParser.g4 SolidityLexer.g4 -o \"${WORKDIR}/src/\"\n\n# Compile lexer/parser sources\njavac -classpath \"${ANTLR_JAR}\" \"${WORKDIR}/src/\"*.java -d \"${WORKDIR}/target/\"\n\n# Compile AntlrBatchTestRig\njavac -classpath \"${ANTLR_JAR}:${WORKDIR}/target/\" \"${ROOT_DIR}/scripts/AntlrBatchTestRig.java\" -d \"${WORKDIR}/target/\"\n)\n\n# we only want to use files that do not contain excluded parser errors, analysis errors or multi-source files.\nSOL_FILES=()\nwhile IFS='' read -r line\ndo\n  SOL_FILES+=(\"$line\")\ndone < <(\n  grep --include \"*.sol\" -riL -E \\\n    \"^\\/\\/ (Syntax|Type|Declaration)Error|^\\/\\/ ParserError (1684|2837|3716|3997|5333|6275|6281|6933|7319|8185|7637)|^==== Source:|^pragma experimental solidity;\" \\\n    \"${ROOT_DIR}/test/libsolidity/syntaxTests\" \\\n    \"${ROOT_DIR}/test/libsolidity/semanticTests\" |\n      # Skipping the unicode tests as I couldn't adapt the lexical grammar to recursively counting RLO/LRO/PDF's.\n      grep -v -E 'comments/.*_direction_override.*.sol' |\n      grep -v -E 'literals/.*_direction_override.*.sol' |\n      # Skipping a test with \"revert E;\" because ANTLR cannot distinguish it from\n      # a variable declaration.\n      grep -v -E 'revertStatement/non_called.sol' |\n      # Skipping a test with \"let basefee := ...\"\n      grep -v -E 'inlineAssembly/basefee_berlin_function.sol' |\n      # Skipping a test with \"let blobbasefee := ...\"\n      grep -v -E 'inlineAssembly/blobbasefee_shanghai_function.sol' |\n      # Skipping a test with \"let mcopy := ...\"\n      grep -v -E 'inlineAssembly/mcopy_as_identifier_pre_cancun.sol' |\n      # Skipping tests with \"let prevrandao := ...\"\n      grep -v -E 'inlineAssembly/prevrandao_allowed_function_pre_paris.sol' |\n      grep -v -E 'inlineAssembly/prevrandao_disallowed_function_post_paris.sol' |\n      # Skipping a test with \"let blobhash := ...\"\n      grep -v -E 'inlineAssembly/blobhash_pre_cancun.sol' |\n      grep -v -E 'inlineAssembly/blobhash_pre_cancun_not_reserved.sol' |\n      # Skipping a test with \"let clz := ...\"\n      grep -v -E 'inlineAssembly/clz_pre_osaka.sol' |\n      # Skipping tests with \"let tstore/tload := ...\"\n      grep -v -E 'inlineAssembly/tload_tstore_not_reserved_before_cancun.sol' |\n      # Skipping license error, unrelated to the grammar\n      grep -v -E 'license/license_double5.sol' |\n      grep -v -E 'license/license_hidden_unicode.sol' |\n      grep -v -E 'license/license_unicode.sol' |\n      # Skipping tests with 'something.address' as 'address' as the grammar fails on those\n      grep -v -E 'inlineAssembly/external_function_pointer_address.*.sol'\n)\n\nYUL_FILES=()\n# Add all yul optimizer tests without objects and types.\nwhile IFS='' read -r line\ndo\n  YUL_FILES+=(\"$line\")\ndone < <(\n  grep -riL -E \\\n    \"object|\\:[ ]*[uib]\" \\\n    \"${ROOT_DIR}/test/libyul/yulOptimizerTests\"\n)\n\n# Combine all files into one array\nALL_FILES=(\"${SOL_FILES[@]}\" \"${YUL_FILES[@]}\")\nnum_tests=${#ALL_FILES[@]}\nfailed_count=0\ntest_count=0\n\necho \"Testing $num_tests files...\"\n\n# Process all files in batches\nfor ((i=0; i<${#ALL_FILES[@]}; i+=BATCH_SIZE)); do\n  batch=(\"${ALL_FILES[@]:i:BATCH_SIZE}\")\n  batch_size=${#batch[@]}\n\n  echo \"Processing batch $((i/BATCH_SIZE + 1)) (${batch_size} files)...\"\n\n  # Run batch\n  output=$(java -classpath \"${ANTLR_JAR}:${WORKDIR}/target/\" AntlrBatchTestRig \"${batch[@]}\" 2>&1) || true\n\n  # Parse output\n  while IFS= read -r line; do\n    if [[ -z \"$line\" ]]; then\n      continue\n    fi\n\n    test_count=$((test_count + 1))\n\n    if [[ \"$line\" =~ ^PASS:(.+):(.*) ]]; then\n      file=\"${BASH_REMATCH[1]}\"\n      status=\"${BASH_REMATCH[2]}\"\n      if [[ \"$status\" == \"FAILED_AS_EXPECTED\" ]]; then\n        echo -e \"${SGR_BLUE}[${test_count}/${num_tests}] ${file}${SGR_RESET} ${SGR_BOLD}${SGR_GREEN}FAILED AS EXPECTED${SGR_RESET}\"\n      else\n        echo -e \"${SGR_BLUE}[${test_count}/${num_tests}] ${file}${SGR_RESET} ${SGR_BOLD}${SGR_GREEN}OK${SGR_RESET}\"\n      fi\n    elif [[ \"$line\" =~ ^FAIL:(.+):(.*) ]]; then\n      file=\"${BASH_REMATCH[1]}\"\n      error=\"${BASH_REMATCH[2]}\"\n      echo -e \"${SGR_BLUE}[${test_count}/${num_tests}] ${file}${SGR_RESET} ${SGR_BOLD}${SGR_RED}FAILED${SGR_RESET}\"\n      echo \"$error\"\n      failed_count=$((failed_count + 1))\n    elif [[ \"$line\" =~ ^ERROR:(.+):(.*) ]]; then\n      file=\"${BASH_REMATCH[1]}\"\n      error=\"${BASH_REMATCH[2]}\"\n      echo -e \"${SGR_BLUE}[${test_count}/${num_tests}] ${file}${SGR_RESET} ${SGR_BOLD}${SGR_RED}ERROR${SGR_RESET}\"\n      echo \"$error\"\n      failed_count=$((failed_count + 1))\n    fi\n  done <<< \"$output\"\ndone\n\necho \"Summary: ${failed_count} of $num_tests sources failed.\"\nexit ${failed_count}\n"
  },
  {
    "path": "scripts/test_emscripten.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Bash script to execute the Solidity tests using the emscripten binary.\n#\n# The documentation for solidity is hosted at:\n#\n#     https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2017 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nif test -z \"$1\"; then\n\tBUILD_DIR=\"emscripten_build\"\nelse\n\tBUILD_DIR=\"$1\"\nfi\n\nREPO_ROOT=$(cd \"$(dirname \"$0\")/..\" && pwd)\nSOLJSON=\"$REPO_ROOT/$BUILD_DIR/libsolc/soljson.js\"\nVERSION=$(\"$REPO_ROOT\"/scripts/get_version.sh)\n\necho \"Running solcjs tests....\"\n\"$REPO_ROOT/test/externalTests/solc-js/solc-js.sh\" \"$SOLJSON\" \"$VERSION\"\n"
  },
  {
    "path": "scripts/tests.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Bash script to execute the Solidity tests.\n#\n# The documentation for solidity is hosted at:\n#\n#     https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nREPO_ROOT=\"$(dirname \"$0\")/..\"\nSOLIDITY_BUILD_DIR=\"${SOLIDITY_BUILD_DIR:-${REPO_ROOT}/build}\"\nIFS=\" \" read -r -a SMT_FLAGS <<< \"$SMT_FLAGS\"\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\nWORKDIR=$(mktemp -d)\nCMDLINE_PID=\n\nfunction cleanup\n{\n    # ensure failing commands don't cause termination during cleanup (especially within safe_kill)\n    set +e\n\n    if [[ -n \"$CMDLINE_PID\" ]]\n    then\n        safe_kill \"$CMDLINE_PID\" \"Commandline tests\"\n    fi\n\n    echo \"Cleaning up working directory ${WORKDIR} ...\"\n    rm -rf \"$WORKDIR\" || true\n}\ntrap cleanup INT TERM\n\nlog_directory=\"\"\nno_smt=\"\"\nwhile [[ $# -gt 0 ]]\ndo\n    case \"$1\" in\n        --junit_report)\n            if [ -z \"$2\" ]\n            then\n                echo \"Usage: $0 [--junit_report <report_directory>] [--no-smt]\"\n                exit 1\n            else\n                log_directory=\"$2\"\n            fi\n            shift\n            shift\n            ;;\n        --no-smt)\n            no_smt=\"--no-smt\"\n            SMT_FLAGS+=(--no-smt)\n            shift\n            ;;\n        *)\n            echo \"Usage: $0 [--junit_report <report_directory>] [--no-smt]\"\n            exit 1\n    esac\ndone\n\nprintTask \"Testing Python scripts...\"\n\"$REPO_ROOT/test/pyscriptTests.py\"\n\nprintTask \"Testing LSP...\"\n\"$REPO_ROOT/test/lsp.py\" \"${SOLIDITY_BUILD_DIR}/solc/solc\"\n\nprintTask \"Running commandline tests...\"\n# Only run in parallel if this is run on CI infrastructure\nif [[ -n \"$CI\" ]]\nthen\n    \"$REPO_ROOT/test/cmdlineTests.sh\" &\n    CMDLINE_PID=$!\nelse\n    if ! \"$REPO_ROOT/test/cmdlineTests.sh\" \"$no_smt\"\n    then\n        printError \"Commandline tests FAILED\"\n        exit 1\n    fi\nfi\n\n\nEVM_VERSIONS=\"homestead byzantium\"\n\nif [ -z \"$CI\" ]\nthen\n    EVM_VERSIONS+=\" constantinople petersburg istanbul berlin london paris shanghai cancun prague osaka\"\nfi\n\n# And then run the Solidity unit-tests in the matrix combination of optimizer / no optimizer\n# and homestead / byzantium VM\nfor optimize in \"\" \"--optimize\"\ndo\n    for vm in $EVM_VERSIONS\n    do\n        FORCE_ABIV1_RUNS=\"no\"\n        if [[ \"$vm\" == \"osaka\" ]]\n        then\n            FORCE_ABIV1_RUNS=\"no yes\" # run both when testing the current EVM version\n        fi\n        for abiv1 in $FORCE_ABIV1_RUNS\n        do\n            force_abiv1_flag=()\n            if [[ \"$abiv1\" == \"yes\" ]]\n            then\n                force_abiv1_flag=(--abiencoderv1)\n            fi\n            printTask \"--> Running tests using $optimize --evm-version $vm ${force_abiv1_flag[*]}...\"\n\n            log=()\n            if [ -n \"$log_directory\" ]\n            then\n                if [ -n \"$optimize\" ]\n                then\n                    log+=(\"--logger=JUNIT,error,$log_directory/opt_$vm.xml\")\n                else\n                    log+=(\"--logger=JUNIT,error,$log_directory/noopt_$vm.xml\")\n                fi\n            fi\n\n            set +e\n            \"${SOLIDITY_BUILD_DIR}\"/test/soltest --show-progress \"${log[@]}\" -- --testpath \"$REPO_ROOT\"/test \"$optimize\" --evm-version \"$vm\" \"${SMT_FLAGS[@]}\" \"${force_abiv1_flag[@]}\"\n\n            if test \"0\" -ne \"$?\"; then\n                exit 1\n            fi\n            set -e\n\n        done\n    done\ndone\n\nif [[ -n $CMDLINE_PID ]] && ! wait $CMDLINE_PID\nthen\n    printError \"Commandline tests FAILED\"\n    CMDLINE_PID=\n    exit 1\nfi\n\ncleanup\n"
  },
  {
    "path": "scripts/uniqueErrors.sh",
    "content": "#!/usr/bin/env bash\n\nREPO=\"$(dirname \"$0\")/..\"\n\necho \"Finding unique failures...\"\n(\nfor x in \"$@\"\ndo\n    echo -n \"$x\" \" # \"\n    # This subshell is a workaround to prevent the shell from printing\n    # \"Aborted\"\n    (\"$REPO\"/build/test/tools/solfuzzer < \"$x\" || true) 2>&1 | head -n 1\ndone\n) | sort -u -t'#' -k 2\n"
  },
  {
    "path": "scripts/update_bugs_by_version.py",
    "content": "#!/usr/bin/env python3\n#\n# This script is used to generate the list of bugs per compiler version\n# from the list of bugs.\n# It updates the list in place and signals failure if there were changes.\n# This makes it possible to use this script as part of CI to check\n# that the list is up to date.\n\nimport json\nimport re\nfrom pathlib import Path\n\ndef comp(version_string):\n    return [int(c) for c in version_string.split('.')]\n\nroot_path = Path(__file__).resolve().parent.parent\n\nbugs = json.loads((root_path / 'docs/bugs.json').read_text(encoding='utf8'))\n\nversions = {}\nwith (root_path / 'Changelog.md').open(encoding='utf8') as changelog:\n    for line in changelog:\n        m = re.search(r'^### (\\S+) \\((\\d+-\\d+-\\d+)\\)$', line)\n        if m:\n            versions[m.group(1)] = {}\n            versions[m.group(1)]['released'] = m.group(2)\n\nfor key, value in versions.items():\n    value['bugs'] = []\n    for bug in bugs:\n        if 'introduced' in bug and comp(bug['introduced']) > comp(key):\n            continue\n        if comp(bug['fixed']) <= comp(key):\n            continue\n        value['bugs'] += [bug['name']]\n\n(root_path / 'docs/bugs_by_version.json').write_text(json.dumps(\n    versions,\n    sort_keys=True,\n    indent=4,\n    separators=(',', ': ')\n), encoding='utf8')\n"
  },
  {
    "path": "scripts/wasm-rebuild/README",
    "content": "This directory contains scripts that we used to rebuild historic releases to webassembly.\nThe rebuild took place at the time of Solidity version 0.6.1 and was used to rebuild all versions from 0.3.6 to 0.6.1.\nThe scripts are not actively tested or maintained, but we keep them for future reference in case we want to rebuild\nhistoric releases again at a later point.\n"
  },
  {
    "path": "scripts/wasm-rebuild/docker-scripts/genbytecode.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Script used for cross-platform comparison as part of the travis automation.\n# Splits all test source code into multiple files, generates bytecode and\n# uploads the bytecode into github.com/ethereum/solidity-test-bytecode where\n# another travis job is triggered to do the actual comparison.\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2017 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nSCRIPTDIR=$(dirname \"$0\")\nSCRIPTDIR=$(realpath \"${SCRIPTDIR}\")\n\n\necho \"Compiling all test contracts into bytecode...\"\nTMPDIR=$(mktemp -d)\n(\n    cd \"${TMPDIR}\"\n    \"${SCRIPTDIR}/isolate_tests.py\" /src/test/\n\n    cat > solc <<EOF\n#!/usr/bin/env node\nvar process = require('process')\nvar fs = require('fs')\n\nvar compiler = require('/root/solc-js/wrapper.js')(require(\"${1}\"))\n\nfor (var optimize of [false, true])\n{\n    for (var filename of process.argv.slice(2))\n    {\n        if (filename !== undefined)\n        {\n            var inputs = {}\n            inputs[filename] = { content: fs.readFileSync(filename).toString() }\n            var input = {\n                language: 'Solidity',\n                sources: inputs,\n                settings: {\n                    optimizer: { enabled: optimize },\n                    outputSelection: { '*': { '*': ['*'] } }\n                }\n            }\n            try {\n                var result = JSON.parse(compiler.compile(JSON.stringify(input)))\n                if (\n                    !('contracts' in result) ||\n                    Object.keys(result['contracts']).length === 0\n                )\n                {\n                    // NOTE: do not exit here because this may be run on source which cannot be compiled\n                    console.log(filename + ': ERROR')\n                }\n                else\n                {\n                    for (var outputName in result['contracts'])\n                        for (var contractName in result['contracts'][outputName])\n                        {\n                            var contractData = result['contracts'][outputName][contractName];\n                            if (contractData.evm !== undefined && contractData.evm.bytecode !== undefined)\n                                console.log(filename + ':' + contractName + ' ' + contractData.evm.bytecode.object)\n                            else\n                                console.log(filename + ':' + contractName + ' NO BYTECODE')\n                            console.log(filename + ':' + contractName + ' ' + contractData.metadata)\n                        }\n                }\n            } catch (e) {\n                console.log(filename + ': FATAL ERROR')\n                console.error(filename)\n                console.error(inputs)\n            }\n        }\n    }\n}\nEOF\n    chmod +x solc\n    ./solc -- *.sol > /tmp/report.txt\n)\nrm -rf \"$TMPDIR\"\n"
  },
  {
    "path": "scripts/wasm-rebuild/docker-scripts/isolate_tests.py",
    "content": "#!/usr/bin/env python2\n#\n# Not actively tested or maintained. Exists in case we want to rebuild an\n# ancient release.\n\nimport sys\nimport re\nimport os\nimport hashlib\nfrom os.path import join\n\n\ndef extract_test_cases(path):\n    with open(path, encoding=\"utf8\", errors='ignore', mode='rb') as f:\n        lines = f.read().splitlines()\n\n    inside = False\n    delimiter = ''\n    tests = []\n\n    for l in lines:\n      if inside:\n        if l.strip().endswith(')' + delimiter + '\";'):\n          tests[-1] += l.strip()[:-(3 + len(delimiter))]\n          inside = False\n        else:\n          tests[-1] += l + '\\n'\n      else:\n        m = re.search(r'R\"([^(]*)\\((.*)$', l.strip())\n        if m:\n          inside = True\n          delimiter = m.group(1)\n          tests += [m.group(2)]\n\n    return tests\n\ndef extract_and_write(f, path):\n    if f.endswith('.sol'):\n        with open(path, 'r', encoding='utf8') as _f:\n            cases = [_f.read()]\n    else:\n        cases = extract_test_cases(path)\n    write_cases(f, cases)\n\ndef write_cases(f, tests):\n    cleaned_filename = f.replace(\".\",\"_\").replace(\"-\",\"_\").replace(\" \",\"_\").lower()\n    for test in tests:\n        remainder = re.sub(r'^ {4}', '', test, count=0, flags=re.MULTILINE)\n        source_code_hash = hashlib.sha256(test).hexdigest()\n        with open(f'test_{source_code_hash}_{cleaned_filename}.sol', 'w', encoding='utf8') as _f:\n            _f.write(remainder)\n\n\nif __name__ == '__main__':\n    path = sys.argv[1]\n\n    for root, subdirs, files in os.walk(path):\n        if '_build' in subdirs:\n            subdirs.remove('_build')\n        for f in files:\n            path = join(root, f)\n            extract_and_write(f, path)\n"
  },
  {
    "path": "scripts/wasm-rebuild/docker-scripts/patch.sh",
    "content": "#!/bin/bash\n\n# If we ever want to patch the binaries e.g. for compatibility with older solc-js versions,\n# we can do that here.\n#\n# This script gets the following parameters:\n# - TAG\n# - SOLJSON_JS\n"
  },
  {
    "path": "scripts/wasm-rebuild/docker-scripts/rebuild_current.sh",
    "content": "#!/bin/bash -e\n\n# Do not call this script directly.\n\n# This script is expected to be run inside the docker image trzeci/emscripten:sdk-tag-1.39.3-64bit and\n# be called by ./rebuild_tags.sh.\n\necho \"========== STAGE 1: PREPARE ========== ($(date))\"\nCOMMIT_DATE=\"$(git show -s --format=%cI HEAD)\"\ngit rev-parse --short=8 HEAD >commit_hash.txt\necho -e \"\" >prerelease.txt\nsed -i -e 's/-Wl,--gc-sections//' cmake/EthCompilerSettings.cmake\necho \"set(CMAKE_CXX_FLAGS \\\"\\${CMAKE_CXX_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS=['cwrap','addFunction','removeFunction','UTF8ToString','lengthBytesUTF8','_malloc','stringToUTF8','setValue'] -s WASM=1 -s WASM_ASYNC_COMPILATION=0 -s SINGLE_FILE=1 -Wno-almost-asm\\\")\" >>cmake/EthCompilerSettings.cmake\n# Needed for < 0.5.0.\nsed -i -e 's/-Werror/-Wno-error/' cmake/EthCompilerSettings.cmake\n\necho \"========== STAGE 2: BUILD ========== ($(date))\"\nscripts/travis-emscripten/install_deps.sh\nif [ -d cryptopp ]; then\n  # Needed for < 0.4.4. Will not affect >= 0.4.5.\n  # Unfortunately we need to update to the latest\n  # release in the 5.6 series for it to build.\n  # Hopefully we don't miss any bugs.\n  rm -rf cryptopp\n  git clone https://github.com/weidai11/cryptopp/\n  (\n    set -e\n    cd cryptopp\n    git checkout CRYPTOPP_5_6_5\n    ln -s . src\n  )\nfi\nif [ -d jsoncpp ]; then\n  # Needed for < 0.4.4. Will not affect >= 0.4.5.\n  (\n    set -e\n    cd jsoncpp\n    # Checkout the latest commit at the time of our release.\n    git checkout \"$(git rev-list -1 --before=\"$COMMIT_DATE\" master)\"\n  )\nfi\n\nset +e\n\nif [ -e scripts/ci/build_emscripten.sh ]; then\n  scripts/ci/build_emscripten.sh\nelse\n  # The script used to be in scripts/travis-emscripten/ in earlier versions.\n  scripts/travis-emscripten/build_emscripten.sh\nfi\n\nset -e\n\nmkdir -p upload\n\nif [ ! -f upload/soljson.js ]; then\n  if [ -f build/solc/soljson.js ]; then\n    cp build/solc/soljson.js upload\n  elif [ -f build/libsolc/soljson.js ]; then\n    cp build/libsolc/soljson.js upload\n  elif [ -f emscripten_build/solc/soljson.js ]; then\n    cp emscripten_build/solc/soljson.js upload\n  elif [ -f emscripten_build/libsolc/soljson.js ]; then\n    cp emscripten_build/libsolc/soljson.js upload\n  fi\nfi\n\nif [ -f upload/soljson.js ]; then\n  echo \"========== SUCCESS ========== ($(date))\"\n  exit 0\nelse\n  echo \"========== FAILURE ========== ($(date))\"\n  exit 1\nfi\n"
  },
  {
    "path": "scripts/wasm-rebuild/docker-scripts/rebuild_tags.sh",
    "content": "#!/bin/bash -e\n\n# This script is expected to be run inside the docker image trzeci/emscripten:sdk-tag-1.39.3-64bit.\n# Its main purpose is to be called by ../rebuild.sh.\n\n# Usage: $0 [tagFilter] [outputDirectory]\n\n# The output directory must be outside the repository,\n# since the script will prune the repository directory after\n# each build.\n\nTAG_FILTER=\"$1\"\nOUTPUTDIR=\"$2\"\nRETEST=0\nshift\nshift\nwhile (( \"$#\" )); do\n  if [[ \"$1\" == \"--retest\" ]]; then\n    RETEST=1\n  else\n    echo \"Unrecognized option: $1\"\n    exit 1\n  fi\n  shift\ndone\n\nSOLIDITY_REPO_URL=\"https://github.com/argotorg/solidity\"\nSOLC_JS_REPO_URL=\"https://github.com/argotorg/solc-js\"\nSOLC_JS_BRANCH=wasmRebuildTests\nRELEASE_URL=\"https://binaries.soliditylang.org/bin\"\nRELEASE_COMMIT_LIST_URL=\"$RELEASE_URL/list.txt\"\n\nSCRIPTDIR=$(dirname \"$0\")\nSCRIPTDIR=$(realpath \"${SCRIPTDIR}\")\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nORANGE='\\033[0;33m'\nCYAN='\\033[0;36m'\nRESET='\\033[0m'\n\nfunction generate_bytecode_report\n{\n  rm -rf /tmp/report.txt\n\n  local EXIT_STATUS\n\n  if semver -r \"<0.4.12\" \"$3\" > /dev/null; then\n    set +e\n    \"${SCRIPTDIR}/genbytecode.sh\" \"$1\" >/dev/null 2>&1\n    EXIT_STATUS=$?\n    set -e\n  else\n    set +e\n    (\n      set -e\n\n      git reset --hard HEAD --quiet\n      git clean -f -d -x --quiet\n\n      for dir in build/solc build/libsolc emscripten_build/libsolc; do\n        mkdir -p $dir\n        rm -rf $dir/soljson.js\n        ln -sf \"$1\" $dir/soljson.js\n      done\n\n       /tmp/storebytecode.sh >/dev/null 2>&1\n    )\n    EXIT_STATUS=$?\n  fi\n\n  if [ $EXIT_STATUS -eq 0 ] && [ -f /tmp/report.txt ] && grep -q -v -c -e \"ERROR\" -e \"NO BYTECODE\" /tmp/report.txt; then\n    mv /tmp/report.txt \"$2\"\n    echo -e \"${GREEN}SUCCESS${RESET}\"\n  else\n    echo -e \"${RED}FAILURE${RESET}\"\n  fi\n}\nfunction clean_git_checkout\n{\n  git submodule deinit --all -q\n  git reset --hard HEAD --quiet\n  git clean -f -d -x --quiet\n  git checkout \"$1\" --quiet\n  git submodule init -q\n  git submodule update -q\n}\nfunction process_tag\n{\n  local TAG=$1\n  cd /src\n  # Checkout the historic commit instead of the tag directly.\n  local HISTORIC_COMMIT_HASH; HISTORIC_COMMIT_HASH=\"$(grep \"${TAG}+\" /tmp/release_commit_list.txt | cut -d '+' -f 2 | cut -d '.' -f 2)\"\n  if [ \"$(git cat-file -t \"${HISTORIC_COMMIT_HASH}\" 2>/dev/null)\" == \"commit\" ]; then\n    clean_git_checkout \"$HISTORIC_COMMIT_HASH\"\n  else\n    clean_git_checkout \"${TAG}\"\n  fi\n\n  # compatibility symlink\n  ln -s . solidity\n\n  local VERSION\n  if [ -f ./scripts/get_version.sh ]; then\n    VERSION=$(./scripts/get_version.sh)\n  else\n    VERSION=$(echo \"$TAG\" | cut -d v -f 2)\n  fi\n\n  local COMMIT_HASH; COMMIT_HASH=$(git rev-parse --short=8 HEAD)\n  local FULL_VERSION_SUFFIX=\"${TAG}+commit.${COMMIT_HASH}\"\n  local HISTORIC_VERSION_SUFFIX=\"${TAG}+commit.${HISTORIC_COMMIT_HASH}\"\n\n  if [ ! -f \"${OUTPUTDIR}/bin/soljson-${FULL_VERSION_SUFFIX}.js\" ]; then\n    echo -ne \"BUILDING ${CYAN}${TAG}${RESET}... \"\n    set +e\n    (\n      set -e\n      \"${SCRIPTDIR}/rebuild_current.sh\" \"${VERSION}\" >\"${OUTPUTDIR}/log/running/build-$TAG.txt\" 2>&1\n      \"${SCRIPTDIR}/patch.sh\" \"$TAG\" upload/soljson.js\n      cp upload/soljson.js \"${OUTPUTDIR}/bin/soljson-${FULL_VERSION_SUFFIX}.js\"\n      rm upload/soljson.js\n    )\n    local EXIT_STATUS=$?\n    set -e\n    rm -f \"${OUTPUTDIR}/log/success/build-$TAG.txt\"\n    rm -f \"${OUTPUTDIR}/log/fail/build-$TAG.txt\"\n    if [ $EXIT_STATUS -eq 0 ]; then\n      mv \"${OUTPUTDIR}/log/running/build-$TAG.txt\" \"${OUTPUTDIR}/log/success\"\n      echo -e \"${GREEN}SUCCESS${RESET}\"\n    else\n      mv \"${OUTPUTDIR}/log/running/build-$TAG.txt\" \"${OUTPUTDIR}/log/fail\"\n      echo -e \"${RED}FAIL${RESET}\"\n    fi\n  else\n    echo -e \"${CYAN}${TAG}${RESET} ALREADY EXISTS.\"\n    if [ $RETEST -eq 0 ]; then\n      return 0\n    fi\n  fi\n\n  if [ -f \"${OUTPUTDIR}/bin/soljson-${FULL_VERSION_SUFFIX}.js\" ]; then\n\n    echo -ne \"GENERATE BYTECODE REPORT FOR ${CYAN}${TAG}${RESET}... \"\n    generate_bytecode_report \"${OUTPUTDIR}/bin/soljson-${FULL_VERSION_SUFFIX}.js\" \"${OUTPUTDIR}/log/reports/report-${TAG}.txt\" \"${TAG}\"\n    echo -ne \"GENERATE BYTECODE REPORT FOR HISTORIC ${CYAN}${TAG}${RESET}... \"\n    rm -rf /tmp/soljson.js\n    if wget -q \"$RELEASE_URL/soljson-${HISTORIC_VERSION_SUFFIX}.js\" -O /tmp/soljson.js; then\n      generate_bytecode_report /tmp/soljson.js \"${OUTPUTDIR}/log/reports/report-historic-${TAG}.txt\" \"${TAG}\"\n    else\n      echo -e \"${ORANGE}CANNOT FETCH RELEASE${RESET}\"\n    fi\n    rm -rf /tmp/soljson.js\n\n    if [ -f \"${OUTPUTDIR}/log/reports/report-${TAG}.txt\" ] && [ -f \"${OUTPUTDIR}/log/reports/report-historic-${TAG}.txt\" ]; then\n      rm -rf \"${OUTPUTDIR}/log/success/bytecode-${TAG}.txt\"\n      rm -rf \"${OUTPUTDIR}/log/fail/bytecode-${TAG}.txt\"\n      if diff -q \"${OUTPUTDIR}/log/reports/report-${TAG}.txt\" \"${OUTPUTDIR}/log/reports/report-historic-${TAG}.txt\" >/dev/null 2>&1; then\n        echo -e \"${GREEN}BYTECODE MATCHES FOR ${CYAN}${TAG}${RESET}\"\n        grep -v -c -e \"ERROR\" -e \"NO BYTECODE\" \"${OUTPUTDIR}/log/reports/report-${TAG}.txt\" >\"${OUTPUTDIR}/log/success/bytecode-${TAG}.txt\"\n      else\n        echo -e \"${RED}BYTECODE DOES NOT MATCH FOR ${CYAN}${TAG}${RESET}\"\n        echo \"MISMATCH\" >\"${OUTPUTDIR}/log/fail/bytecode-${TAG}.txt\"\n      fi\n    fi\n\n    echo -ne \"TESTING ${CYAN}${TAG}${RESET}... \"\n    cd /root/solc-js\n    npm version --allow-same-version --no-git-tag-version \"${VERSION}\" >/dev/null\n    sed -i -e \"s/runTests(solc, .*)/runTests(solc, '${FULL_VERSION_SUFFIX}')/\" test/compiler.js\n    ln -sf \"${OUTPUTDIR}/bin/soljson-${FULL_VERSION_SUFFIX}.js\" soljson.js\n    rm -f \"${OUTPUTDIR}/log/success/test-$TAG.txt\"\n    rm -f \"${OUTPUTDIR}/log/fail/test-$TAG.txt\"\n    if npm test >\"${OUTPUTDIR}/log/running/test-$TAG.txt\" 2>&1; then\n      mv \"${OUTPUTDIR}/log/running/test-$TAG.txt\" \"${OUTPUTDIR}/log/success\"\n      echo -e \"${GREEN}SUCCESS${RESET}\"\n    else\n      mv \"${OUTPUTDIR}/log/running/test-$TAG.txt\" \"${OUTPUTDIR}/log/fail\"\n      echo -e \"${RED}FAIL${RESET}\"\n    fi\n  fi\n}\n\ncd /tmp\n\necho \"Check out solidity repository...\"\nif [ -d /root/project ]; then\n  echo \"Solidity repo checkout already exists.\"\nelse\n  git clone \"${SOLIDITY_REPO_URL}\" /root/project --quiet\nfi\n\necho \"Extract bytecode comparison scripts from v0.6.1...\"\ncd /root/project\ngit checkout v0.6.1 --quiet\ncp scripts/bytecodecompare/storebytecode.sh /tmp\n# shellcheck disable=SC2016\nsed -i -e 's/rm -rf \"\\$TMPDIR\"/cp \"\\$TMPDIR\"\\/report.txt \\/tmp\\/report.txt ; rm -rf \"\\$TMPDIR\"/' /tmp/storebytecode.sh\nsed -i -e 's/REPO_ROOT=.*/REPO_ROOT=\\/src/' /tmp/storebytecode.sh\nsed -i -e 's/git clone/git clone --branch '\"${SOLC_JS_BRANCH}\"'/' /tmp/storebytecode.sh\nexport SOLC_EMSCRIPTEN=\"On\"\n\necho \"Check out solc-js repository...\"\nif [ -d /root/solc-js ]; then\n  echo \"solc-js repo checkout already exists.\"\nelse\n  git clone --branch \"${SOLC_JS_BRANCH}\" \"${SOLC_JS_REPO_URL}\" /root/solc-js --quiet\nfi\n\necho \"Create symbolic links for backwards compatibility with older emscripten docker images.\"\nln -sf /emsdk_portable/node/current/* /emsdk_portable/node/\nln -sf /emsdk_portable/emscripten/sdk/ /emsdk_portable/\nln -sf sdk /emsdk_portable/emscripten/bin\nln -sf /emsdk_portable/emscripten/bin/* /usr/local/bin\nrm -rf /src\nln -sf /root/project /src\n\necho \"Install dependencies and upgrade system packages.\"\napt-get -qq update >/dev/null 2>&1\napt-get -qq upgrade >/dev/null 2>&1\napt-get -qq install cmake >/dev/null 2>&1\n\necho \"Create output directories.\"\nmkdir -p \"${OUTPUTDIR}\"\nmkdir -p \"${OUTPUTDIR}\"/log\nmkdir -p \"${OUTPUTDIR}\"/log/success\nmkdir -p \"${OUTPUTDIR}\"/log/fail\nmkdir -p \"${OUTPUTDIR}\"/log/running\nmkdir -p \"${OUTPUTDIR}\"/log/reports\nmkdir -p \"${OUTPUTDIR}\"/bin\n\necho \"Prepare solc-js.\"\ncd /root/solc-js\nnpm install >/dev/null 2>&1\n\necho \"Install semver helper.\"\nnpm install -g semver >/dev/null 2>&1\n\necho \"Fetching release commit list.\"\nwget -q \"${RELEASE_COMMIT_LIST_URL}\" -O /tmp/release_commit_list.txt\n\ncd /src\nTAGS=$(git tag --list \"${TAG_FILTER}\" | tac)\necho \"Matching tags: ${TAGS}\"\nfor TAG in ${TAGS}; do\n  process_tag \"${TAG}\"\ndone\n"
  },
  {
    "path": "scripts/wasm-rebuild/rebuild.sh",
    "content": "#!/bin/sh\n\n# This script is expected to produce working builds for all compiler versions >= 0.3.6 and\n# succeeding solc-js test runs for all compiler versions >= 0.5.0.\n\nif [ $# -lt 2 ]; then\n  echo \"Usage: $0 [tagFilter] [outputDirectory] [options...]\"\n  echo\n  echo \"  [tagFilter] will be passed to \"git tag --list\" to filter the tags to be built.\"\n  echo \"  [outputDirectory] will contain log files and the resulting soljson.js builds.\"\n  echo \"  --retest will re-run tests and bytecode comparisons, even if soljson.js is already built.\"\n  exit 1\nfi\n\nTAGS=\"$1\"\nOUTPUTDIR=\"$2\"\nshift\nshift\nSCRIPTDIR=$(dirname \"$0\")\nSCRIPTDIR=$(realpath \"${SCRIPTDIR}\")\n\nif [ ! -d \"${OUTPUTDIR}\" ]; then\n  echo \"Output directory ${OUTPUTDIR} does not exist!.\"\n  exit 1\nfi\nOUTPUTDIR=$(realpath \"${OUTPUTDIR}\")\n\ndocker run --rm -v \"${OUTPUTDIR}\":/tmp/output -v \"${SCRIPTDIR}\":/tmp/scripts:ro -it trzeci/emscripten:sdk-tag-1.39.3-64bit /tmp/scripts/docker-scripts/rebuild_tags.sh \"${TAGS}\" /tmp/output \"$@\"\n"
  },
  {
    "path": "scripts/yul_coverage.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Bash script to determine the percentage of tests that are compilable via Yul.\n#\n# Usage:\n#  ./yul_coverage.sh [--no-stats] [--successful] [--internal-compiler-errors]\n#                                 [--unimplemented-feature-errors] [--other-errors] [--list-files]\n#\n#    --no-stats                     will not print the stats to stdout\n#    --successful                   print output of successful test-case compilations to stdout\n#    --internal-compiler-errors     print output of test-case compilations that resulted in\n#                                   internal compilation errors to stdout\n#    --unimplemented-feature-errors print output of test-case compilations that resulted in\n#                                   unimplemented feature errors to stdout\n#    --other-errors                 print output of test-case compilations that resulted in\n#                                   errors that where not internal compiler errors or unimplemented feature errors\n#                                   to stdout\n#    --list-files                   will not print the compiler output to stdout, it will just print the files\n#                                   e.g. ./yul_coverage.sh --successful --list-files will just return a list of\n#                                   files where it's compilation result was successful\n#   Environment Variables\n#     SOLC can be set to change the used compiler.\n#\n#   ./yul_coverage.sh\n#   run the script without any parameters to execute the tests will return stats.\n#\n#   SOLC=<path-to-solc> ./yul_coverage.sh\n#   To change the used compiler, just set the SOLC environment variable.\n#\n# The documentation for solidity is hosted at:\n#\n#     https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2020 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nROOT_DIR=\"$(dirname \"$0\")\"/..\n\nfor arg in \"$@\"; do\n  case \"$arg\" in\n  --no-stats) NO_STATS=1 ;;\n  --successful) SHOW_SUCCESSFUL=1 ;;\n  --internal-compiler-errors) SHOW_INTERNAL_COMPILER_ERRORS=1 ;;\n  --unimplemented-feature-errors) SHOW_UNIMPLEMENTED_FEATURE_ERRORS=1 ;;\n  --other-errors) SHOW_OTHER_ERRORS=1 ;;\n  --list-files) ONLY_LIST_FILES=1 ;;\n  *)\n    echo \"Usage:\"\n    echo \"  $(basename \"${0}\") [--no-stats] [--successful] [--internal-compiler-errors] [--unimplemented-feature-errors] [--other-errors] [--list-files]\"\n    echo \"  --no-stats                     will not print the stats to stdout\"\n    echo \"  --successful                   print output of successful test-case compilations to stdout\"\n    echo \"  --internal-compiler-errors     print output of test-case compilations that resulted in\"\n    echo \"                                 internal compilation errors to stdout\"\n    echo \"  --unimplemented-feature-errors print output of test-case compilations that resulted in\"\n    echo \"                                 unimplemented feature errors to stdout\"\n    echo \"  --other-errors                 print output of test-case compilations that resulted in\"\n    echo \"                                 errors that where not internal compiler errors or unimplemented feature errors\"\n    echo \"                                 to stdout\"\n    echo \"  --list-files                   will not print the compiler output to stdout, it will just print the files\"\n    echo \"                                 e.g. './yul_coverage.sh --successful --list-files' will just return a list of\"\n    echo \"                                 files where it's compilation result was successful\"\n    exit 0\n    ;;\n  esac\ndone\n\nfunction show_output_if\n{\n  local VAR=${1}\n  if [ -n \"${VAR}\" ]; then\n    echo \"${SOL_FILE}\"\n    if [ -z \"${ONLY_LIST_FILES}\" ]; then\n      echo \"${OUTPUT}\"\n      echo \"\"\n    fi\n  fi\n}\n\nFAILED=()\nSUCCESS=()\nSOLC=${SOLC:-\"$(command -v -- solc)\"}\nif [ ! -f \"${SOLC}\" ]; then\n  echo \"error: solc '${SOLC}' not found.\"\n  exit 1\nfi\n\nfunction test_file\n{\n  local SOL_FILE\n  local OUTPUT\n  SOL_FILE=${1}\n\n  if OUTPUT=$(\"${SOLC}\" --ir \"${SOL_FILE}\" 2>&1); then\n    SUCCESS+=(\"${SOL_FILE}\")\n    show_output_if \"${SHOW_SUCCESSFUL}\"\n  else\n    FAILED+=(\"${SOL_FILE}\")\n    if [[ ${OUTPUT} == *\"UnimplementedFeatureError\"* ]]; then\n      UNIMPLEMENTED_FEATURE_ERRORS+=(\"${SOL_FILE}\")\n      show_output_if \"${SHOW_UNIMPLEMENTED_FEATURE_ERRORS}\"\n    elif [[ ${OUTPUT} == *\"InternalCompilerError\"* ]]; then\n      INTERNAL_COMPILER_ERRORS+=(\"${SOL_FILE}\")\n      show_output_if \"${SHOW_INTERNAL_COMPILER_ERRORS}\"\n    else\n      OTHER_ERRORS+=(\"${SOL_FILE}\")\n      show_output_if \"${SHOW_OTHER_ERRORS}\"\n    fi\n  fi\n}\n\n# we only want to use files that do not contain errors or multi-source files.\nSOL_FILES=()\nwhile IFS='' read -r line; do\n  SOL_FILES+=(\"$line\")\ndone < <(\n  grep -riL -E \\\n    \"^\\/\\/ (DocstringParsing|Syntax|Type|Parser|Declaration)Error|^==== Source:\" \\\n    \"${ROOT_DIR}/test/libsolidity/syntaxTests\" \\\n    \"${ROOT_DIR}/test/libsolidity/semanticTests\"\n)\n\nfor SOL_FILE in \"${SOL_FILES[@]}\"; do\n  test_file \"${SOL_FILE}\"\ndone\n\nif [ -z \"${NO_STATS}\" ]; then\n  SUM=$((${#SUCCESS[@]} + ${#FAILED[@]}))\n  PERCENTAGE=$(echo \"scale=4; ${#SUCCESS[@]} / ${SUM}\" | bc)\n  echo \"${#SUCCESS[@]} / ${SUM} = ${PERCENTAGE}\"\n  echo \"UnimplementedFeatureError(s): ${#UNIMPLEMENTED_FEATURE_ERRORS[@]}\"\n  echo \"InternalCompilerError(s): ${#INTERNAL_COMPILER_ERRORS[@]}\"\n  echo \"OtherError(s): ${#OTHER_ERRORS[@]}\"\nfi\n"
  },
  {
    "path": "snap/snapcraft.yaml",
    "content": "name: solc\nversion: develop\nversion-script: git describe --exact-match --tags 2> /dev/null || echo \"develop\"\nsummary: The Solidity Contract-Oriented Programming Language\ndescription: |\n  Solidity is a contract-oriented, high-level language whose syntax is similar\n  to that of JavaScript and it is designed to target the Ethereum Virtual\n  Machine (EVM).\n\n  Solidity is statically typed, supports inheritance, libraries and complex\n  user-defined types among other features.\n\n  It is possible to create contracts for voting, crowdfunding, blind auctions,\n  multi-signature wallets and more.\n\nbase: core20\ngrade: stable\nconfinement: strict\n\napps:\n  solc:\n    command: usr/local/bin/solc\n    plugs: [home]\n\nparts:\n  solidity:\n    source: .\n    source-type: git\n    plugin: cmake\n    build-packages: [build-essential, libboost-all-dev]\n    stage-packages: [libicu66]\n    override-build: |\n      if git describe --exact-match --tags 2> /dev/null\n      then\n        echo -n > ../src/prerelease.txt\n      fi\n      snapcraftctl build\n    after: [z3, cvc4]\n  z3:\n    source: https://github.com/Z3Prover/z3.git\n    source-tag: z3-4.8.4\n    plugin: make\n    build-packages: [python3]\n    stage-packages: [libstdc++6, libgomp1]\n    override-build: |\n      python3 scripts/mk_make.py\n      cd build\n      make -j -l $(grep -c \"^processor\" /proc/cpuinfo)\n      make install DESTDIR=$SNAPCRAFT_PART_INSTALL\n  cvc4:\n    source: https://github.com/CVC4/CVC4.git\n    source-tag: \"1.8\"\n    plugin: nil\n    build-packages: [python3, python3-toml, cmake, openjdk-11-jre, libgmp-dev, wget, antlr3, libantlr3c-3.4-0, libantlr3c-dev]\n    override-build: |\n      ./configure.sh --python3 --prefix=$SNAPCRAFT_STAGE/usr\n      cd build\n      make -j -l $(grep -c \"^processor\" /proc/cpuinfo)\n      make install\n      mkdir -p $SNAPCRAFT_PART_INSTALL/usr/lib/\n      cp $SNAPCRAFT_STAGE/usr/lib/libcvc4.so.7 $SNAPCRAFT_PART_INSTALL/usr/lib/\n"
  },
  {
    "path": "solc/CMakeLists.txt",
    "content": "set(libsolcli_sources\n\tCommandLineInterface.cpp CommandLineInterface.h\n\tCommandLineParser.cpp CommandLineParser.h\n\tExceptions.h\n)\n\nadd_library(solcli ${libsolcli_sources})\ntarget_link_libraries(solcli PUBLIC solidity Boost::boost Boost::program_options)\n\nset(sources main.cpp)\n\nadd_executable(solc ${sources})\ntarget_link_libraries(solc PRIVATE solcli)\n\ninclude(GNUInstallDirs)\ninstall(TARGETS solc DESTINATION \"${CMAKE_INSTALL_BINDIR}\")\n\nif(SOLC_LINK_STATIC AND UNIX AND NOT APPLE)\n\t# Produce solc as statically linked binary (includes C/C++ standard libraries)\n\t# This is not supported on macOS, see\n\t# https://developer.apple.com/library/content/qa/qa1118/_index.html.\n\tset_target_properties(\n\t\tsolc PROPERTIES\n\t\tLINK_FLAGS -static\n\t\tLINK_SEARCH_START_STATIC ON\n\t\tLINK_SEARCH_END_STATIC ON\n\t)\nelseif(SOLC_STATIC_STDLIBS AND UNIX AND NOT APPLE)\n\tset_target_properties(\n\t\tsolc PROPERTIES\n\t\tLINK_FLAGS \"-static-libgcc -static-libstdc++\"\n\t)\nendif()\n"
  },
  {
    "path": "solc/CommandLineInterface.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Lefteris <lefteris@ethdev.com>\n * @author Gav Wood <g@ethdev.com>\n * @date 2014\n * Solidity command line interface.\n */\n#include <solc/CommandLineInterface.h>\n\n#include <solc/Exceptions.h>\n\n#include \"license.h\"\n#include \"solidity/BuildInfo.h\"\n\n#include <libsolidity/interface/Version.h>\n#include <libsolidity/ast/ASTJsonExporter.h>\n#include <libsolidity/ast/ASTJsonImporter.h>\n#include <libsolidity/analysis/NameAndTypeResolver.h>\n#include <libsolidity/interface/CompilerStack.h>\n#include <libsolidity/interface/StandardCompiler.h>\n#include <libsolidity/interface/GasEstimator.h>\n#include <libsolidity/interface/DebugSettings.h>\n#include <libsolidity/interface/ImportRemapper.h>\n#include <libsolidity/interface/StorageLayout.h>\n#include <libsolidity/lsp/LanguageServer.h>\n#include <libsolidity/lsp/Transport.h>\n\n#include <libyul/YulStack.h>\n\n#include <libevmasm/Ethdebug.h>\n#include <libevmasm/Disassemble.h>\n\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/SourceReferenceFormatter.h>\n\n#include <libsmtutil/Exceptions.h>\n\n#include <libsolutil/Common.h>\n#include <libsolutil/CommonData.h>\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/JSON.h>\n\n#include <algorithm>\n#include <fstream>\n#include <memory>\n\n#include <range/v3/view/map.hpp>\n\n#include <boost/filesystem.hpp>\n#include <boost/filesystem/operations.hpp>\n#include <boost/algorithm/string.hpp>\n\n#ifdef _WIN32 // windows\n\t#include <io.h>\n\t#define isatty _isatty\n\t#define fileno _fileno\n#else // unix\n\t#include <unistd.h>\n#endif\n\n#include <fstream>\n\n#if !defined(STDERR_FILENO)\n\t#define STDERR_FILENO 2\n#endif\n\nusing namespace std::string_literals;\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\n\nnamespace\n{\n\nstd::set<frontend::InputMode> const CompilerInputModes{\n\tfrontend::InputMode::Compiler,\n\tfrontend::InputMode::CompilerWithASTImport,\n};\n\n} // anonymous namespace\n\nnamespace solidity::frontend\n{\n\nstd::ostream& CommandLineInterface::sout(bool _markAsUsed)\n{\n\tif (_markAsUsed)\n\t\tm_hasOutput = true;\n\treturn m_sout;\n}\n\nstd::ostream& CommandLineInterface::serr(bool _markAsUsed)\n{\n\tif (_markAsUsed)\n\t\tm_hasOutput = true;\n\treturn m_serr;\n}\n\n#define cin\n#define cout\n#define cerr\n\nstatic std::string const g_stdinFileName = \"<stdin>\";\nstatic std::string const g_strAbi = \"abi\";\nstatic std::string const g_strAsm = \"asm\";\nstatic std::string const g_strBinary = \"bin\";\nstatic std::string const g_strBinaryRuntime = \"bin-runtime\";\nstatic std::string const g_strContracts = \"contracts\";\nstatic std::string const g_strFunDebug = \"function-debug\";\nstatic std::string const g_strFunDebugRuntime = \"function-debug-runtime\";\nstatic std::string const g_strGeneratedSources = \"generated-sources\";\nstatic std::string const g_strGeneratedSourcesRuntime = \"generated-sources-runtime\";\nstatic std::string const g_strNatspecDev = \"devdoc\";\nstatic std::string const g_strNatspecUser = \"userdoc\";\nstatic std::string const g_strOpcodes = \"opcodes\";\nstatic std::string const g_strSignatureHashes = \"hashes\";\nstatic std::string const g_strSourceList = \"sourceList\";\nstatic std::string const g_strSources = \"sources\";\nstatic std::string const g_strSrcMap = \"srcmap\";\nstatic std::string const g_strSrcMapRuntime = \"srcmap-runtime\";\nstatic std::string const g_strStorageLayout = \"storage-layout\";\nstatic std::string const g_strTransientStorageLayout = \"transient-storage-layout\";\nstatic std::string const g_strVersion = \"version\";\n\nstatic bool needsHumanTargetedStdout(CommandLineOptions const& _options)\n{\n\tif (_options.compiler.estimateGas)\n\t\treturn true;\n\tif (!_options.output.dir.empty())\n\t\treturn false;\n\treturn\n\t\t_options.compiler.outputs.abi ||\n\t\t_options.compiler.outputs.asm_ ||\n\t\t_options.compiler.outputs.asmJson ||\n\t\t_options.compiler.outputs.yulCFGJson ||\n\t\t_options.compiler.outputs.binary ||\n\t\t_options.compiler.outputs.binaryRuntime ||\n\t\t_options.compiler.outputs.ethdebug ||\n\t\t_options.compiler.outputs.ethdebugRuntime ||\n\t\t_options.compiler.outputs.metadata ||\n\t\t_options.compiler.outputs.natspecUser ||\n\t\t_options.compiler.outputs.natspecDev ||\n\t\t_options.compiler.outputs.opcodes ||\n\t\t_options.compiler.outputs.signatureHashes ||\n\t\t_options.compiler.outputs.storageLayout ||\n\t\t_options.compiler.outputs.transientStorageLayout;\n}\n\nstatic bool coloredOutput(CommandLineOptions const& _options)\n{\n\treturn\n\t\t(!_options.formatting.coloredOutput.has_value() && isatty(STDERR_FILENO)) ||\n\t\t(_options.formatting.coloredOutput.has_value() && _options.formatting.coloredOutput.value());\n}\n\nvoid CommandLineInterface::handleEVMAssembly(std::string const& _contract)\n{\n\tsolAssert(m_assemblyStack);\n\tsolAssert(\n\t\tCompilerInputModes.count(m_options.input.mode) == 1 ||\n\t\tm_options.input.mode == frontend::InputMode::EVMAssemblerJSON\n\t);\n\n\tif (!m_options.compiler.outputs.asm_ && !m_options.compiler.outputs.asmJson)\n\t\treturn;\n\n\tstd::string assembly;\n\tif (m_options.compiler.outputs.asmJson)\n\t\tassembly = util::jsonPrint(m_assemblyStack->assemblyJSON(_contract), m_options.formatting.json);\n\telse\n\t\tassembly = m_assemblyStack->assemblyString(_contract, m_fileReader.sourceUnits());\n\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(\n\t\t\tm_compiler->filesystemFriendlyName(_contract) +\n\t\t\t(m_options.compiler.outputs.asmJson ? \"_evm.json\" : \".evm\"),\n\t\t\tassembly\n\t\t);\n\telse\n\t\tsout() << \"EVM assembly:\" << std::endl << assembly << std::endl;\n}\n\nvoid CommandLineInterface::handleBinary(std::string const& _contract)\n{\n\tsolAssert(m_assemblyStack);\n\tsolAssert(\n\t\tCompilerInputModes.count(m_options.input.mode) == 1 ||\n\t\tm_options.input.mode == frontend::InputMode::EVMAssemblerJSON\n\t);\n\n\tstd::string binary;\n\tstd::string binaryRuntime;\n\tif (m_options.compiler.outputs.binary)\n\t\tbinary = objectWithLinkRefsHex(m_assemblyStack->object(_contract));\n\tif (m_options.compiler.outputs.binaryRuntime)\n\t\tbinaryRuntime = objectWithLinkRefsHex(m_assemblyStack->runtimeObject(_contract));\n\n\tif (m_options.compiler.outputs.binary)\n\t{\n\t\tif (!m_options.output.dir.empty())\n\t\t\tcreateFile(m_assemblyStack->filesystemFriendlyName(_contract) + \".bin\", binary);\n\t\telse\n\t\t{\n\t\t\tsout() << \"Binary:\" << std::endl;\n\t\t\tsout() << binary << std::endl;\n\t\t}\n\t}\n\tif (m_options.compiler.outputs.binaryRuntime)\n\t{\n\t\tif (!m_options.output.dir.empty())\n\t\t\tcreateFile(m_assemblyStack->filesystemFriendlyName(_contract) + \".bin-runtime\", binaryRuntime);\n\t\telse\n\t\t{\n\t\t\tsout() << \"Binary of the runtime part:\" << std::endl;\n\t\t\tsout() << binaryRuntime << std::endl;\n\t\t}\n\t}\n}\n\nvoid CommandLineInterface::handleOpcode(std::string const& _contract)\n{\n\tsolAssert(m_assemblyStack);\n\tsolAssert(\n\t\tCompilerInputModes.count(m_options.input.mode) == 1 ||\n\t\tm_options.input.mode == frontend::InputMode::EVMAssemblerJSON\n\t);\n\n\tstd::string opcodes{evmasm::disassemble(m_assemblyStack->object(_contract).bytecode, m_options.output.evmVersion)};\n\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(m_assemblyStack->filesystemFriendlyName(_contract) + \".opcode\", opcodes);\n\telse\n\t{\n\t\tsout() << \"Opcodes:\" << std::endl;\n\t\tsout() << std::uppercase << opcodes;\n\t\tsout() << std::endl;\n\t}\n}\n\nvoid CommandLineInterface::handleIR(std::string const& _contractName)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!m_options.compiler.outputs.ir)\n\t\treturn;\n\n\tstd::optional<std::string> const& ir = m_compiler->yulIR(_contractName);\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(m_compiler->filesystemFriendlyName(_contractName) + \".yul\", ir.value_or(\"\"));\n\telse\n\t{\n\t\tsout() << \"IR:\\n\";\n\t\tsout() << ir.value_or(\"\") << std::endl;\n\t}\n}\n\nvoid CommandLineInterface::handleIRAst(std::string const& _contractName)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!m_options.compiler.outputs.irAstJson)\n\t\treturn;\n\n\tstd::optional<Json> const& yulIRAst = m_compiler->yulIRAst(_contractName);\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(\n\t\t\tm_compiler->filesystemFriendlyName(_contractName) + \"_yul_ast.json\",\n\t\t\tutil::jsonPrint(\n\t\t\t\tyulIRAst.value_or(Json{}),\n\t\t\t\tm_options.formatting.json\n\t\t\t)\n\t\t);\n\telse\n\t{\n\t\tsout() << \"IR AST:\" << std::endl;\n\t\tsout() << util::jsonPrint(\n\t\t\tyulIRAst.value_or(Json{}),\n\t\t\tm_options.formatting.json\n\t\t) << std::endl;\n\t}\n}\n\nvoid CommandLineInterface::handleYulCFGExport(std::string const& _contractName)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!m_options.compiler.outputs.yulCFGJson)\n\t\treturn;\n\n\tstd::optional<Json> const& yulCFGJson = m_compiler->yulCFGJson(_contractName);\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(\n\t\t\tm_compiler->filesystemFriendlyName(_contractName) + \"_yul_cfg.json\",\n\t\t\tutil::jsonPrint(\n\t\t\t\tyulCFGJson.value_or(Json{}),\n\t\t\t\tm_options.formatting.json\n\t\t\t)\n\t\t);\n\telse\n\t{\n\t\tsout() << \"Yul Control Flow Graph:\" << std::endl;\n\t\tsout() << util::jsonPrint(\n\t\t\tyulCFGJson.value_or(Json{}),\n\t\t\tm_options.formatting.json\n\t\t) << std::endl;\n\t}\n}\n\nvoid CommandLineInterface::handleIROptimized(std::string const& _contractName)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!m_options.compiler.outputs.irOptimized)\n\t\treturn;\n\n\tstd::optional<std::string> const& irOptimized = m_compiler->yulIROptimized(_contractName);\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(\n\t\t\tm_compiler->filesystemFriendlyName(_contractName) + \"_opt.yul\",\n\t\t\tirOptimized.value_or(\"\")\n\t\t);\n\telse\n\t{\n\t\tsout() << \"Optimized IR:\" << std::endl;\n\t\tsout() << irOptimized.value_or(\"\") << std::endl;\n\t}\n}\n\nvoid CommandLineInterface::handleIROptimizedAst(std::string const& _contractName)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!m_options.compiler.outputs.irOptimizedAstJson)\n\t\treturn;\n\n\tstd::optional<Json> const& yulIROptimizedAst = m_compiler->yulIROptimizedAst(_contractName);\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(\n\t\t\tm_compiler->filesystemFriendlyName(_contractName) + \"_opt_yul_ast.json\",\n\t\t\tutil::jsonPrint(\n\t\t\t\tyulIROptimizedAst.value_or(Json{}),\n\t\t\t\tm_options.formatting.json\n\t\t\t)\n\t\t);\n\telse\n\t{\n\t\tsout() << \"Optimized IR AST:\" << std::endl;\n\t\tsout() << util::jsonPrint(\n\t\t\tyulIROptimizedAst.value_or(Json{}),\n\t\t\tm_options.formatting.json\n\t\t) << std::endl;\n\t}\n}\n\nvoid CommandLineInterface::handleBytecode(std::string const& _contract)\n{\n\tsolAssert(\n\t\tCompilerInputModes.count(m_options.input.mode) == 1 ||\n\t\tm_options.input.mode == frontend::InputMode::EVMAssemblerJSON\n\t);\n\n\tif (m_options.compiler.outputs.opcodes)\n\t\thandleOpcode(_contract);\n\tif (m_options.compiler.outputs.binary || m_options.compiler.outputs.binaryRuntime)\n\t\thandleBinary(_contract);\n}\n\nvoid CommandLineInterface::handleSignatureHashes(std::string const& _contract)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!m_options.compiler.outputs.signatureHashes)\n\t\treturn;\n\n\tJson interfaceSymbols = m_compiler->interfaceSymbols(_contract);\n\tstd::string out = \"Function signatures:\\n\";\n\tfor (auto const& [name, value]: interfaceSymbols[\"methods\"].items())\n\t\tout += value.get<std::string>() + \": \" + name + \"\\n\";\n\n\tif (interfaceSymbols.contains(\"errors\"))\n\t{\n\t\tout += \"\\nError signatures:\\n\";\n\t\tfor (auto const& [name, value]: interfaceSymbols[\"errors\"].items())\n\t\t\tout += value.get<std::string>() + \": \" + name + \"\\n\";\n\t}\n\n\tif (interfaceSymbols.contains(\"events\"))\n\t{\n\t\tout += \"\\nEvent signatures:\\n\";\n\t\tfor (auto const& [name, value]: interfaceSymbols[\"events\"].items())\n\t\t\tout += value.get<std::string>() + \": \" + name + \"\\n\";\n\t}\n\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(m_compiler->filesystemFriendlyName(_contract) + \".signatures\", out);\n\telse\n\t\tsout() << out;\n}\n\nvoid CommandLineInterface::handleMetadata(std::string const& _contract)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!m_options.compiler.outputs.metadata)\n\t\treturn;\n\n\tstd::string data = m_compiler->metadata(_contract);\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(m_compiler->filesystemFriendlyName(_contract) + \"_meta.json\", data);\n\telse\n\t\tsout() << \"Metadata:\" << std::endl << data << std::endl;\n}\n\nvoid CommandLineInterface::handleABI(std::string const& _contract)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!m_options.compiler.outputs.abi)\n\t\treturn;\n\n\tstd::string data = jsonPrint(removeNullMembers(m_compiler->contractABI(_contract)), m_options.formatting.json);\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(m_compiler->filesystemFriendlyName(_contract) + \".abi\", data);\n\telse\n\t\tsout() << \"Contract JSON ABI\" << std::endl << data << std::endl;\n}\n\nvoid CommandLineInterface::handleStorageLayout(std::string const& _contract)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!m_options.compiler.outputs.storageLayout)\n\t\treturn;\n\n\tstd::string data = jsonPrint(removeNullMembers(m_compiler->storageLayout(_contract)), m_options.formatting.json);\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(m_compiler->filesystemFriendlyName(_contract) + \"_storage.json\", data);\n\telse\n\t\tsout() << \"Contract Storage Layout:\" << std::endl << data << std::endl;\n}\n\nvoid CommandLineInterface::handleTransientStorageLayout(std::string const& _contract)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!m_options.compiler.outputs.transientStorageLayout)\n\t\treturn;\n\tstd::string data = jsonPrint(removeNullMembers(m_compiler->transientStorageLayout(_contract)), m_options.formatting.json);\n\tif (!m_options.output.dir.empty())\n\t\tcreateFile(m_compiler->filesystemFriendlyName(_contract) + \"_transient_storage.json\", data);\n\telse\n\t\tsout() << \"Contract Transient Storage Layout:\" << std::endl << data << std::endl;\n}\n\nvoid CommandLineInterface::handleNatspec(bool _natspecDev, std::string const& _contract)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tbool enabled = false;\n\tstd::string suffix;\n\tstd::string title;\n\n\tif (_natspecDev)\n\t{\n\t\tenabled = m_options.compiler.outputs.natspecDev;\n\t\tsuffix = \".docdev\";\n\t\ttitle = \"Developer Documentation\";\n\t}\n\telse\n\t{\n\t\tenabled = m_options.compiler.outputs.natspecUser;\n\t\tsuffix = \".docuser\";\n\t\ttitle = \"User Documentation\";\n\t}\n\n\tif (enabled)\n\t{\n\t\tstd::string output = jsonPrint(\n\t\t\tremoveNullMembers(\n\t\t\t\t_natspecDev ?\n\t\t\t\tm_compiler->natspecDev(_contract) :\n\t\t\t\tm_compiler->natspecUser(_contract)\n\t\t\t),\n\t\t\tm_options.formatting.json\n\t\t);\n\n\t\tif (!m_options.output.dir.empty())\n\t\t\tcreateFile(m_compiler->filesystemFriendlyName(_contract) + suffix, output);\n\t\telse\n\t\t{\n\t\t\tsout() << title << std::endl;\n\t\t\tsout() << output << std::endl;\n\t\t}\n\n\t}\n}\n\nvoid CommandLineInterface::handleGasEstimation(std::string const& _contract)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tJson estimates = m_compiler->gasEstimates(_contract);\n\tsout() << \"Gas estimation:\" << std::endl;\n\n\tif (estimates[\"creation\"].is_object())\n\t{\n\t\tJson creation = estimates[\"creation\"];\n\t\tsout() << \"construction:\" << std::endl;\n\t\tsout() << \"   \" << creation[\"executionCost\"].get<std::string>();\n\t\tsout() << \" + \" << creation[\"codeDepositCost\"].get<std::string>();\n\t\tsout() << \" = \" << creation[\"totalCost\"].get<std::string>() << std::endl;\n\t}\n\n\tif (estimates[\"external\"].is_object())\n\t{\n\t\tJson externalFunctions = estimates[\"external\"];\n\t\tsout() << \"external:\" << std::endl;\n\t\tfor (auto const& [name, value]: externalFunctions.items())\n\t\t{\n\t\t\tif (name.empty())\n\t\t\t\tsout() << \"   fallback:\\t\";\n\t\t\telse\n\t\t\t\tsout() << \"   \" << name << \":\\t\";\n\t\t\tsout() << value.get<std::string>() << std::endl;\n\t\t}\n\t}\n\n\tif (estimates[\"internal\"].is_object())\n\t{\n\t\tJson internalFunctions = estimates[\"internal\"];\n\t\tsout() << \"internal:\" << std::endl;\n\t\tfor (auto const& [name, value]: internalFunctions.items())\n\t\t{\n\t\t\tsout() << \"   \" << name << \":\\t\";\n\t\t\tsout() << value.get<std::string>() << std::endl;\n\t\t}\n\t}\n}\n\nvoid CommandLineInterface::handleEthdebug()\n{\n\tif (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime)\n\t{\n\t\tstd::string ethdebug{jsonPrint(removeNullMembers(m_compiler->ethdebug()), m_options.formatting.json)};\n\t\tif (!m_options.output.dir.empty())\n\t\t\tcreateFile(\"ethdebug.json\", ethdebug);\n\t\telse\n\t\t\tsout() << \"======= Debug Data (ethdebug/format/info/resources) =======\" << std::endl << ethdebug << std::endl;\n\t}\n}\n\nvoid CommandLineInterface::handleEthdebug(std::string const& _contract)\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!(m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime))\n\t\treturn;\n\n\tif (m_options.compiler.outputs.ethdebug)\n\t{\n\t\tstd::string ethdebug{jsonPrint(removeNullMembers(m_compiler->ethdebug(_contract)), m_options.formatting.json)};\n\t\tif (!m_options.output.dir.empty())\n\t\t\tcreateFile(m_compiler->filesystemFriendlyName(_contract) + \"_ethdebug.json\", ethdebug);\n\t\telse\n\t\t\tsout() << \"Debug Data (ethdebug/format/program):\" << std::endl << ethdebug << std::endl;\n\t}\n\n\tif (m_options.compiler.outputs.ethdebugRuntime)\n\t{\n\t\tstd::string ethdebugRuntime{jsonPrint(removeNullMembers(m_compiler->ethdebugRuntime(_contract)), m_options.formatting.json)};\n\t\tif (!m_options.output.dir.empty())\n\t\t\tcreateFile(m_compiler->filesystemFriendlyName(_contract) + \"_ethdebug-runtime.json\", ethdebugRuntime);\n\t\telse\n\t\t\tsout() << \"Debug Data of the runtime part (ethdebug/format/program):\" << std::endl << ethdebugRuntime << std::endl;\n\t}\n}\n\nvoid CommandLineInterface::readInputFiles()\n{\n\tsolAssert(!m_standardJsonInput.has_value());\n\n\tif (m_options.input.noImportCallback)\n\t\tm_universalCallback.resetImportCallback();\n\n\tstatic std::set<frontend::InputMode> const noInputFiles{\n\t\tfrontend::InputMode::Help,\n\t\tfrontend::InputMode::License,\n\t\tfrontend::InputMode::Version\n\t};\n\n\tif (noInputFiles.count(m_options.input.mode) == 1)\n\t\treturn;\n\n\tm_fileReader.setBasePath(m_options.input.basePath);\n\n\tif (m_fileReader.basePath() != \"\")\n\t{\n\t\tif (!boost::filesystem::exists(m_fileReader.basePath()))\n\t\t\tsolThrow(CommandLineValidationError, \"Base path does not exist: \\\"\" + m_fileReader.basePath().string() + '\"');\n\n\t\tif (!boost::filesystem::is_directory(m_fileReader.basePath()))\n\t\t\tsolThrow(CommandLineValidationError, \"Base path is not a directory: \\\"\" + m_fileReader.basePath().string() + '\"');\n\t}\n\n\tfor (boost::filesystem::path const& includePath: m_options.input.includePaths)\n\t\tm_fileReader.addIncludePath(includePath);\n\n\tfor (boost::filesystem::path const& allowedDirectory: m_options.input.allowedDirectories)\n\t\tm_fileReader.allowDirectory(allowedDirectory);\n\n\tstd::map<std::string, std::set<boost::filesystem::path>> collisions =\n\t\tm_fileReader.detectSourceUnitNameCollisions(m_options.input.paths);\n\tif (!collisions.empty())\n\t{\n\t\tauto pathToQuotedString = [](boost::filesystem::path const& _path){ return \"\\\"\" + _path.string() + \"\\\"\"; };\n\n\t\tstd::string message =\n\t\t\t\"Source unit name collision detected. \"\n\t\t\t\"The specified values of base path and/or include paths would result in multiple \"\n\t\t\t\"input files being assigned the same source unit name:\\n\";\n\n\t\tfor (auto const& [sourceUnitName, normalizedInputPaths]: collisions)\n\t\t{\n\t\t\tmessage += sourceUnitName + \" matches: \";\n\t\t\tmessage += util::joinHumanReadable(normalizedInputPaths | ranges::views::transform(pathToQuotedString)) + \"\\n\";\n\t\t}\n\n\t\tsolThrow(CommandLineValidationError, message);\n\t}\n\n\tfor (boost::filesystem::path const& infile: m_options.input.paths)\n\t{\n\t\tif (!boost::filesystem::exists(infile))\n\t\t{\n\t\t\tif (!m_options.input.ignoreMissingFiles)\n\t\t\t\tsolThrow(CommandLineValidationError, '\"' + infile.string() + \"\\\" is not found.\");\n\t\t\telse\n\t\t\t\treport(Error::Severity::Info, fmt::format(\"\\\"{}\\\" is not found. Skipping.\", infile.string()));\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!boost::filesystem::is_regular_file(infile))\n\t\t{\n\t\t\tif (!m_options.input.ignoreMissingFiles)\n\t\t\t\tsolThrow(CommandLineValidationError, '\"' + infile.string() + \"\\\" is not a valid file.\");\n\t\t\telse\n\t\t\t\treport(Error::Severity::Info, fmt::format(\"\\\"{}\\\" is not a valid file. Skipping.\", infile.string()));\n\n\t\t\tcontinue;\n\t\t}\n\n\t\t// NOTE: we ignore the FileNotFound exception as we manually check above\n\t\tstd::string fileContent = readFileAsString(infile);\n\t\tif (m_options.input.mode == InputMode::StandardJson)\n\t\t{\n\t\t\tsolAssert(!m_standardJsonInput.has_value());\n\t\t\tm_standardJsonInput = std::move(fileContent);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_fileReader.addOrUpdateFile(infile, std::move(fileContent));\n\t\t\tm_fileReader.allowDirectory(boost::filesystem::canonical(infile).remove_filename());\n\t\t}\n\t}\n\n\tif (m_options.input.addStdin)\n\t{\n\t\tif (m_options.input.mode == InputMode::StandardJson)\n\t\t{\n\t\t\tsolAssert(!m_standardJsonInput.has_value());\n\t\t\tm_standardJsonInput = readUntilEnd(m_sin);\n\t\t}\n\t\telse\n\t\t\tm_fileReader.setStdin(readUntilEnd(m_sin));\n\t}\n\n\tif (\n\t\tm_options.input.mode != InputMode::LanguageServer &&\n\t\tm_fileReader.sourceUnits().empty() &&\n\t\t!m_standardJsonInput.has_value()\n\t)\n\t\tsolThrow(CommandLineValidationError, \"All specified input files either do not exist or are not regular files.\");\n}\n\nstd::map<std::string, Json> CommandLineInterface::parseAstFromInput()\n{\n\tsolAssert(m_options.input.mode == InputMode::CompilerWithASTImport);\n\n\tstd::map<std::string, Json> sourceJsons;\n\tstd::map<std::string, std::string> tmpSources;\n\n\tfor (SourceCode const& sourceCode: m_fileReader.sourceUnits() | ranges::views::values)\n\t{\n\t\tJson ast;\n\t\tastAssert(jsonParseStrict(sourceCode, ast), \"Input file could not be parsed to JSON\");\n\t\tastAssert(ast.contains(\"sources\"), \"Invalid Format for import-JSON: Must have 'sources'-object\");\n\n\t\tfor (auto const& [src, value]: ast[\"sources\"].items())\n\t\t{\n\t\t\tstd::string astKey = value.contains(\"ast\") ? \"ast\" : \"AST\";\n\n\t\t\tastAssert(ast[\"sources\"][src].contains(astKey), \"astkey is not member\");\n\t\t\tastAssert(ast[\"sources\"][src][astKey][\"nodeType\"].get<std::string>() == \"SourceUnit\",  \"Top-level node should be a 'SourceUnit'\");\n\t\t\tastAssert(sourceJsons.count(src) == 0, \"All sources must have unique names\");\n\t\t\tsourceJsons.emplace(src, std::move(value[astKey]));\n\t\t\ttmpSources[src] = util::jsonCompactPrint(ast);\n\t\t}\n\t}\n\n\tm_fileReader.setSourceUnits(tmpSources);\n\n\treturn sourceJsons;\n}\n\nvoid CommandLineInterface::createFile(std::string const& _fileName, std::string const& _data)\n{\n\tnamespace fs = boost::filesystem;\n\n\tsolAssert(!m_options.output.dir.empty());\n\n\t// NOTE: create_directories() raises an exception if the path consists solely of '.' or '..'\n\t// (or equivalent such as './././.'). Paths like 'a/b/.' and 'a/b/..' are fine though.\n\t// The simplest workaround is to use an absolute path.\n\tfs::create_directories(fs::absolute(m_options.output.dir));\n\n\tstd::string pathName = (m_options.output.dir / _fileName).string();\n\tif (fs::exists(pathName) && !m_options.output.overwriteFiles)\n\t\tsolThrow(CommandLineOutputError, \"Refusing to overwrite existing file \\\"\" + pathName + \"\\\" (use --overwrite to force).\");\n\n\tstd::ofstream outFile(pathName);\n\toutFile << _data;\n\tif (!outFile)\n\t\tsolThrow(CommandLineOutputError, \"Could not write to file \\\"\" + pathName + \"\\\".\");\n}\n\nvoid CommandLineInterface::createJson(std::string const& _fileName, std::string const& _json)\n{\n\tcreateFile(boost::filesystem::path(_fileName).stem().string() + std::string(\".json\"), _json);\n}\n\nbool CommandLineInterface::run(int _argc, char const* const* _argv)\n{\n\ttry\n\t{\n\t\tif (!parseArguments(_argc, _argv))\n\t\t\treturn false;\n\n\t\treadInputFiles();\n\t\tprocessInput();\n\t\treturn true;\n\t}\n\tcatch (CommandLineError const& _exception)\n\t{\n\t\tm_hasOutput = true;\n\n\t\t// There might be no message in the exception itself if the error output is bulky and has\n\t\t// already been printed to stderr (this happens e.g. for compiler errors).\n\t\tif (_exception.what() != \"\"s)\n\t\t\treport(Error::Severity::Error, _exception.what());\n\n\t\treturn false;\n\t}\n\tcatch (UnimplementedFeatureError const& _error)\n\t{\n\t\tsolAssert(_error.comment(), \"Unimplemented feature errors must include a message for the user\");\n\t\treport(Error::Severity::Error, stringOrDefault(_error.comment(), \"Unimplemented feature\"));\n\t\treturn false;\n\t}\n}\n\nbool CommandLineInterface::parseArguments(int _argc, char const* const* _argv)\n{\n\tCommandLineParser parser;\n\n\tif (isatty(fileno(stdin)) && _argc == 1)\n\t{\n\t\t// If the terminal is taking input from the user, provide more user-friendly output.\n\t\tCommandLineParser::printHelp(sout());\n\n\t\t// In this case we want to exit with an error but not display any error message.\n\t\treturn false;\n\t}\n\n\ttry\n\t{\n\t\tparser.parse(_argc, _argv);\n\t}\n\tcatch (...)\n\t{\n\t\t// Even if the overall CLI parsing fails, the --color/--no-color options may have been\n\t\t// successfully parsed, and if so, should be taken into account when printing errors.\n\t\t// If no value is present, it's possible that --no-color is still there but parsing failed\n\t\t// due to other, unrecognized options so play it safe and disable color in that case.\n\t\tm_options.formatting.coloredOutput = parser.options().formatting.coloredOutput.value_or(false);\n\t\tthrow;\n\t}\n\tm_options = parser.options();\n\n\treturn true;\n}\n\nvoid CommandLineInterface::processInput()\n{\n\tif (m_options.output.evmVersion < EVMVersion::constantinople())\n\t\treport(\n\t\t\tError::Severity::Warning,\n\t\t\t\"Support for EVM versions older than constantinople is deprecated and will be removed in the future.\"\n\t\t);\n\n\tswitch (m_options.input.mode)\n\t{\n\tcase InputMode::Help:\n\t\tCommandLineParser::printHelp(sout());\n\t\tbreak;\n\tcase InputMode::License:\n\t\tprintLicense();\n\t\tbreak;\n\tcase InputMode::Version:\n\t\tprintVersion();\n\t\tbreak;\n\tcase InputMode::StandardJson:\n\t{\n\t\tsolAssert(m_standardJsonInput.has_value());\n\n\t\tStandardCompiler compiler(m_universalCallback.callback(), m_options.formatting.json);\n\t\tsout() << compiler.compile(std::move(m_standardJsonInput.value())) << std::endl;\n\t\tm_standardJsonInput.reset();\n\t\tbreak;\n\t}\n\tcase InputMode::LanguageServer:\n\t\tserveLSP();\n\t\tbreak;\n\tcase InputMode::Assembler:\n\t\tassembleYul(m_options.assembly.targetMachine);\n\t\tbreak;\n\tcase InputMode::Linker:\n\t\tlink();\n\t\twriteLinkedFiles();\n\t\tbreak;\n\tcase InputMode::Compiler:\n\tcase InputMode::CompilerWithASTImport:\n\t\tcompile();\n\t\toutputCompilationResults();\n\t\tbreak;\n\tcase InputMode::EVMAssemblerJSON:\n\t\tassembleFromEVMAssemblyJSON();\n\t\thandleCombinedJSON();\n\t\thandleBytecode(m_assemblyStack->contractNames().front());\n\t\thandleEVMAssembly(m_assemblyStack->contractNames().front());\n\t\tbreak;\n\t}\n}\n\nvoid CommandLineInterface::printVersion()\n{\n\tsout() << \"solc, the solidity compiler commandline interface\" << std::endl;\n\tsout() << \"Version: \" << solidity::frontend::VersionString << std::endl;\n}\n\nvoid CommandLineInterface::printLicense()\n{\n\tsout() << otherLicenses << std::endl;\n\t// This is a static variable generated by cmake from LICENSE.txt\n\tsout() << licenseText << std::endl;\n}\n\nvoid CommandLineInterface::assembleFromEVMAssemblyJSON()\n{\n\tsolAssert(m_options.input.mode == InputMode::EVMAssemblerJSON);\n\tsolAssert(!m_assemblyStack);\n\tsolAssert(!m_evmAssemblyStack && !m_compiler);\n\n\tsolAssert(m_fileReader.sourceUnits().size() == 1);\n\tauto&& [sourceUnitName, source] = *m_fileReader.sourceUnits().begin();\n\n\tauto evmAssemblyStack = std::make_unique<evmasm::EVMAssemblyStack>(\n\t\tm_options.output.evmVersion,\n\t\tm_options.output.eofVersion,\n\t\tevmasm::Assembly::OptimiserSettings::translateSettings(\n\t\t\tm_options.optimiserSettings()\n\t\t)\n\t);\n\ttry\n\t{\n\t\tevmAssemblyStack->parseAndAnalyze(sourceUnitName, source);\n\t}\n\tcatch (evmasm::AssemblyImportException const& _exception)\n\t{\n\t\tsolThrow(CommandLineExecutionError, \"Assembly Import Error: \"s + _exception.what());\n\t}\n\n\tif (m_options.output.debugInfoSelection.has_value())\n\t\tevmAssemblyStack->selectDebugInfo(m_options.output.debugInfoSelection.value());\n\tevmAssemblyStack->assemble();\n\n\tm_evmAssemblyStack = std::move(evmAssemblyStack);\n\tm_assemblyStack = m_evmAssemblyStack.get();\n}\n\nvoid CommandLineInterface::compile()\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\tsolAssert(!m_assemblyStack);\n\tsolAssert(!m_evmAssemblyStack && !m_compiler);\n\n\tm_compiler = std::make_unique<CompilerStack>(m_universalCallback.callback());\n\tm_assemblyStack = m_compiler.get();\n\n\tSourceReferenceFormatter formatter(serr(false), *m_compiler, coloredOutput(m_options), m_options.formatting.withErrorIds);\n\n\ttry\n\t{\n\t\tm_compiler->setExperimental(m_options.experimental);\n\t\tif (m_options.metadata.literalSources)\n\t\t\tm_compiler->useMetadataLiteralSources(true);\n\t\tm_compiler->setMetadataFormat(m_options.metadata.format);\n\t\tm_compiler->setMetadataHash(m_options.metadata.hash);\n\t\tif (m_options.modelChecker.initialize)\n\t\t\tm_compiler->setModelCheckerSettings(m_options.modelChecker.settings);\n\t\tm_compiler->setRemappings(m_options.input.remappings);\n\t\tm_compiler->setLibraries(m_options.linker.libraries);\n\t\tm_compiler->setViaIR(m_options.output.viaIR);\n\t\tm_compiler->setViaSSACFG(m_options.output.viaSSACFG);\n\t\tm_compiler->setEVMVersion(m_options.output.evmVersion);\n\t\tm_compiler->setEOFVersion(m_options.output.eofVersion);\n\t\tm_compiler->setRevertStringBehaviour(m_options.output.revertStrings);\n\t\tif (m_options.output.debugInfoSelection.has_value())\n\t\t\tm_compiler->selectDebugInfo(m_options.output.debugInfoSelection.value());\n\n\t\tCompilerStack::PipelineConfig pipelineConfig;\n\t\tpipelineConfig.irOptimization =\n\t\t\tm_options.compiler.outputs.irOptimized ||\n\t\t\tm_options.compiler.outputs.irOptimizedAstJson ||\n\t\t\tm_options.compiler.outputs.yulCFGJson;\n\t\tpipelineConfig.irCodegen =\n\t\t\tpipelineConfig.irOptimization ||\n\t\t\tm_options.compiler.outputs.ir ||\n\t\t\tm_options.compiler.outputs.irAstJson;\n\t\tpipelineConfig.bytecode =\n\t\t\tm_options.compiler.estimateGas ||\n\t\t\tm_options.compiler.outputs.asm_ ||\n\t\t\tm_options.compiler.outputs.asmJson ||\n\t\t\tm_options.compiler.outputs.opcodes ||\n\t\t\tm_options.compiler.outputs.binary ||\n\t\t\tm_options.compiler.outputs.binaryRuntime ||\n\t\t\tm_options.compiler.outputs.ethdebug ||\n\t\t\tm_options.compiler.outputs.ethdebugRuntime ||\n\t\t\t(m_options.compiler.combinedJsonRequests && (\n\t\t\t\tm_options.compiler.combinedJsonRequests->binary ||\n\t\t\t\tm_options.compiler.combinedJsonRequests->binaryRuntime ||\n\t\t\t\tm_options.compiler.combinedJsonRequests->opcodes ||\n\t\t\t\tm_options.compiler.combinedJsonRequests->asm_ ||\n\t\t\t\tm_options.compiler.combinedJsonRequests->generatedSources ||\n\t\t\t\tm_options.compiler.combinedJsonRequests->generatedSourcesRuntime ||\n\t\t\t\tm_options.compiler.combinedJsonRequests->srcMap ||\n\t\t\t\tm_options.compiler.combinedJsonRequests->srcMapRuntime ||\n\t\t\t\tm_options.compiler.combinedJsonRequests->funDebug ||\n\t\t\t\tm_options.compiler.combinedJsonRequests->funDebugRuntime\n\t\t\t));\n\n\t\tm_compiler->selectContracts({{\"\", {{\"\", pipelineConfig}}}});\n\n\t\tm_compiler->setOptimiserSettings(m_options.optimiserSettings());\n\n\t\tif (m_options.input.mode == InputMode::CompilerWithASTImport)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tm_compiler->importASTs(parseAstFromInput());\n\n\t\t\t\tif (!m_compiler->analyze())\n\t\t\t\t{\n\t\t\t\t\tformatter.printErrorInformation(m_compiler->errors());\n\t\t\t\t\tastAssert(false, \"Analysis of the AST failed\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception const& _exc)\n\t\t\t{\n\t\t\t\t// FIXME: AST import is missing proper validations. This hack catches failing\n\t\t\t\t// assertions and presents them as if they were compiler errors.\n\t\t\t\tsolThrow(CommandLineExecutionError, \"Failed to import AST: \"s + _exc.what());\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tm_compiler->setSources(m_fileReader.sourceUnits());\n\n\t\tbool successful = m_compiler->compile(m_options.output.stopAfter);\n\n\t\tfor (auto const& error: m_compiler->errors())\n\t\t{\n\t\t\tm_hasOutput = true;\n\t\t\tformatter.printErrorInformation(*error);\n\t\t}\n\n\t\tif (!successful)\n\t\t\tsolThrow(CommandLineExecutionError, \"\");\n\t}\n\t// NOTE: This includes langutil::StackTooDeepError.\n\tcatch (CompilerError const& _exception)\n\t{\n\t\tm_hasOutput = true;\n\t\tformatter.printExceptionInformation(\n\t\t\t_exception,\n\t\t\tError::errorSeverity(Error::Type::CompilerError)\n\t\t);\n\t\tsolThrow(CommandLineExecutionError, \"\");\n\t}\n\tcatch (yul::StackTooDeepError const& _exception)\n\t{\n\t\tm_hasOutput = true;\n\t\tformatter.printExceptionInformation(\n\t\t\t_exception,\n\t\t\tError::errorSeverity(Error::Type::YulException)\n\t\t);\n\t\tsolThrow(CommandLineExecutionError, \"\");\n\t}\n}\n\nvoid CommandLineInterface::handleCombinedJSON()\n{\n\tsolAssert(m_assemblyStack);\n\tsolAssert(\n\t\tCompilerInputModes.count(m_options.input.mode) == 1 ||\n\t\tm_options.input.mode == frontend::InputMode::EVMAssemblerJSON\n\t);\n\n\tif (!m_options.compiler.combinedJsonRequests.has_value())\n\t\treturn;\n\n\tJson output;\n\n\toutput[g_strVersion] = frontend::VersionString;\n\tstd::vector<std::string> contracts = m_assemblyStack->contractNames();\n\n\tif (!contracts.empty())\n\t\toutput[g_strContracts] = Json::object();\n\tfor (std::string const& contractName: contracts)\n\t{\n\t\tJson& contractData = output[g_strContracts][contractName] = Json::object();\n\n\t\t// NOTE: The state checks here are more strict that in Standard JSON. There we allow\n\t\t// requesting certain outputs even if compilation fails as long as analysis went ok.\n\t\tif (m_compiler && m_compiler->compilationSuccessful())\n\t\t{\n\t\t\tif (m_options.compiler.combinedJsonRequests->abi)\n\t\t\t\tcontractData[g_strAbi] = m_compiler->contractABI(contractName);\n\t\t\tif (m_options.compiler.combinedJsonRequests->metadata)\n\t\t\t\tcontractData[\"metadata\"] = m_compiler->metadata(contractName);\n\t\t\tif (m_options.compiler.combinedJsonRequests->storageLayout)\n\t\t\t\tcontractData[g_strStorageLayout] = m_compiler->storageLayout(contractName);\n\t\t\tif (m_options.compiler.combinedJsonRequests->transientStorageLayout)\n\t\t\t\tcontractData[g_strTransientStorageLayout] = m_compiler->transientStorageLayout(contractName);\n\t\t\tif (m_options.compiler.combinedJsonRequests->generatedSources)\n\t\t\t\tcontractData[g_strGeneratedSources] = m_compiler->generatedSources(contractName, false);\n\t\t\tif (m_options.compiler.combinedJsonRequests->generatedSourcesRuntime)\n\t\t\t\tcontractData[g_strGeneratedSourcesRuntime] = m_compiler->generatedSources(contractName, true);\n\t\t\tif (m_options.compiler.combinedJsonRequests->signatureHashes)\n\t\t\t\tcontractData[g_strSignatureHashes] = m_compiler->interfaceSymbols(contractName)[\"methods\"];\n\t\t\tif (m_options.compiler.combinedJsonRequests->natspecDev)\n\t\t\t\tcontractData[g_strNatspecDev] = m_compiler->natspecDev(contractName);\n\t\t\tif (m_options.compiler.combinedJsonRequests->natspecUser)\n\t\t\t\tcontractData[g_strNatspecUser] = m_compiler->natspecUser(contractName);\n\t\t}\n\n\t\tif (m_assemblyStack->compilationSuccessful())\n\t\t{\n\t\t\tif (m_options.compiler.combinedJsonRequests->binary)\n\t\t\t\tcontractData[g_strBinary] = m_assemblyStack->object(contractName).toHex();\n\t\t\tif (m_options.compiler.combinedJsonRequests->binaryRuntime)\n\t\t\t\tcontractData[g_strBinaryRuntime] = m_assemblyStack->runtimeObject(contractName).toHex();\n\t\t\tif (m_options.compiler.combinedJsonRequests->opcodes)\n\t\t\t\tcontractData[g_strOpcodes] = evmasm::disassemble(m_assemblyStack->object(contractName).bytecode, m_options.output.evmVersion);\n\t\t\tif (m_options.compiler.combinedJsonRequests->asm_)\n\t\t\t\tcontractData[g_strAsm] = m_assemblyStack->assemblyJSON(contractName);\n\t\t\tif (m_options.compiler.combinedJsonRequests->srcMap)\n\t\t\t{\n\t\t\t\tauto map = m_assemblyStack->sourceMapping(contractName);\n\t\t\t\tcontractData[g_strSrcMap] = map ? *map : \"\";\n\t\t\t}\n\t\t\tif (m_options.compiler.combinedJsonRequests->srcMapRuntime)\n\t\t\t{\n\t\t\t\tauto map = m_assemblyStack->runtimeSourceMapping(contractName);\n\t\t\t\tcontractData[g_strSrcMapRuntime] = map ? *map : \"\";\n\t\t\t}\n\t\t\tif (m_options.compiler.combinedJsonRequests->funDebug)\n\t\t\t\tcontractData[g_strFunDebug] = StandardCompiler::formatFunctionDebugData(\n\t\t\t\t\tm_assemblyStack->object(contractName).functionDebugData\n\t\t\t\t);\n\t\t\tif (m_options.compiler.combinedJsonRequests->funDebugRuntime)\n\t\t\t\tcontractData[g_strFunDebugRuntime] = StandardCompiler::formatFunctionDebugData(\n\t\t\t\t\tm_assemblyStack->runtimeObject(contractName).functionDebugData\n\t\t\t\t);\n\t\t}\n\t}\n\n\tbool needsSourceList =\n\t\tm_options.compiler.combinedJsonRequests->ast ||\n\t\tm_options.compiler.combinedJsonRequests->srcMap ||\n\t\tm_options.compiler.combinedJsonRequests->srcMapRuntime;\n\tif (needsSourceList)\n\t{\n\t\t// Indices into this array are used to abbreviate source names in source locations.\n\t\toutput[g_strSourceList] = Json::array();\n\n\t\tfor (auto const& source: m_assemblyStack->sourceNames())\n\t\t\toutput[g_strSourceList].emplace_back(source);\n\t}\n\n\tif (m_options.compiler.combinedJsonRequests->ast)\n\t{\n\t\tsolAssert(m_compiler);\n\t\toutput[g_strSources] = Json::object();\n\t\tfor (auto const& sourceCode: m_fileReader.sourceUnits())\n\t\t{\n\t\t\toutput[g_strSources][sourceCode.first] = Json::object();\n\t\t\toutput[g_strSources][sourceCode.first][\"AST\"] = ASTJsonExporter(\n\t\t\t\tm_compiler->state(),\n\t\t\t\tm_compiler->sourceIndices()\n\t\t\t).toJson(m_compiler->ast(sourceCode.first));\n\t\t\toutput[g_strSources][sourceCode.first][\"id\"] = m_compiler->sourceIndices().at(sourceCode.first);\n\t\t}\n\t}\n\n\tstd::string json = jsonPrint(removeNullMembers(std::move(output)), m_options.formatting.json);\n\tif (!m_options.output.dir.empty())\n\t\tcreateJson(\"combined\", json);\n\telse\n\t\tsout() << json << std::endl;\n}\n\nvoid CommandLineInterface::handleAst()\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\tif (!m_options.compiler.outputs.astCompactJson)\n\t\treturn;\n\n\tstd::vector<ASTNode const*> asts;\n\tfor (auto const& sourceCode: m_fileReader.sourceUnits())\n\t\tasts.push_back(&m_compiler->ast(sourceCode.first));\n\n\tif (!m_options.output.dir.empty())\n\t{\n\t\tfor (auto const& sourceCode: m_fileReader.sourceUnits())\n\t\t{\n\t\t\tstd::stringstream data;\n\t\t\tstd::string postfix = \"\";\n\t\t\tASTJsonExporter(m_compiler->state(), m_compiler->sourceIndices()).print(data, m_compiler->ast(sourceCode.first), m_options.formatting.json);\n\t\t\tpostfix += \"_json\";\n\t\t\tboost::filesystem::path path(sourceCode.first);\n\t\t\tcreateFile(path.filename().string() + postfix + \".ast\", data.str());\n\t\t}\n\t}\n\telse\n\t{\n\t\tsout() << \"JSON AST (compact format):\" << std::endl << std::endl;\n\t\tfor (auto const& sourceCode: m_fileReader.sourceUnits())\n\t\t{\n\t\t\tsout() << std::endl << \"======= \" << sourceCode.first << \" =======\" << std::endl;\n\t\t\tASTJsonExporter(m_compiler->state(), m_compiler->sourceIndices()).print(sout(), m_compiler->ast(sourceCode.first), m_options.formatting.json);\n\t\t}\n\t}\n}\n\nvoid CommandLineInterface::serveLSP()\n{\n\tlsp::StdioTransport transport;\n\tif (!lsp::LanguageServer{transport}.run())\n\t\tsolThrow(CommandLineExecutionError, \"LSP terminated abnormally.\");\n}\n\nvoid CommandLineInterface::link()\n{\n\tsolAssert(m_options.input.mode == InputMode::Linker);\n\n\t// Map from how the libraries will be named inside the bytecode to their addresses.\n\tstd::map<std::string, h160> librariesReplacements;\n\tint const placeholderSize = 40; // 20 bytes or 40 hex characters\n\tfor (auto const& library: m_options.linker.libraries)\n\t{\n\t\tstd::string const& name = library.first;\n\t\t// Library placeholders are 40 hex digits (20 bytes) that start and end with '__'.\n\t\t// This leaves 36 characters for the library identifier. The identifier used to\n\t\t// be just the cropped or '_'-padded library name, but this changed to\n\t\t// the cropped hex representation of the hash of the library name.\n\t\t// We support both ways of linking here.\n\t\tlibrariesReplacements[\"__\" + evmasm::LinkerObject::libraryPlaceholder(name) + \"__\"] = library.second;\n\n\t\tstd::string replacement = \"__\";\n\t\tfor (size_t i = 0; i < placeholderSize - 4; ++i)\n\t\t\treplacement.push_back(i < name.size() ? name[i] : '_');\n\t\treplacement += \"__\";\n\t\tlibrariesReplacements[replacement] = library.second;\n\t}\n\n\tFileReader::StringMap sourceCodes = m_fileReader.sourceUnits();\n\tfor (auto& src: sourceCodes)\n\t{\n\t\tauto end = src.second.end();\n\t\tfor (auto it = src.second.begin(); it != end;)\n\t\t{\n\t\t\twhile (it != end && *it != '_') ++it;\n\t\t\tif (it == end) break;\n\t\t\tif (\n\t\t\t\tend - it < placeholderSize ||\n\t\t\t\t*(it + 1) != '_' ||\n\t\t\t\t*(it + placeholderSize - 2) != '_' ||\n\t\t\t\t*(it + placeholderSize - 1) != '_'\n\t\t\t)\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineExecutionError,\n\t\t\t\t\t\"Error in binary object file \" + src.first + \" at position \" + std::to_string(it - src.second.begin()) + \"\\n\" +\n\t\t\t\t\t'\"' + std::string(it, it + std::min(placeholderSize, static_cast<int>(end - it))) + \"\\\" is not a valid link reference.\"\n\t\t\t\t);\n\n\t\t\tstd::string foundPlaceholder(it, it + placeholderSize);\n\t\t\tif (librariesReplacements.count(foundPlaceholder))\n\t\t\t{\n\t\t\t\tstd::string hexStr(util::toHex(librariesReplacements.at(foundPlaceholder).asBytes()));\n\t\t\t\tcopy(hexStr.begin(), hexStr.end(), it);\n\t\t\t}\n\t\t\telse\n\t\t\t\treport(\n\t\t\t\t\tError::Severity::Warning,\n\t\t\t\t\tfmt::format(\"Reference \\\"{}\\\" in file \\\"{}\\\" still unresolved.\", foundPlaceholder, src.first)\n\t\t\t\t);\n\t\t\tit += placeholderSize;\n\t\t}\n\t\t// Remove hints for resolved libraries.\n\t\tfor (auto const& library: m_options.linker.libraries)\n\t\t\tboost::algorithm::erase_all(src.second, \"\\n\" + libraryPlaceholderHint(library.first));\n\t\twhile (!src.second.empty() && *prev(src.second.end()) == '\\n')\n\t\t\tsrc.second.resize(src.second.size() - 1);\n\t}\n\tm_fileReader.setSourceUnits(std::move(sourceCodes));\n}\n\nvoid CommandLineInterface::writeLinkedFiles()\n{\n\tsolAssert(m_options.input.mode == InputMode::Linker);\n\n\tfor (auto const& src: m_fileReader.sourceUnits())\n\t\tif (src.first == g_stdinFileName)\n\t\t\tsout() << src.second << std::endl;\n\t\telse\n\t\t{\n\t\t\tstd::ofstream outFile(src.first);\n\t\t\toutFile << src.second;\n\t\t\tif (!outFile)\n\t\t\t\tsolThrow(CommandLineOutputError, \"Could not write to file \" + src.first + \". Aborting.\");\n\t\t}\n\tsout() << \"Linking completed.\" << std::endl;\n}\n\nstd::string CommandLineInterface::libraryPlaceholderHint(std::string const& _libraryName)\n{\n\treturn \"// \" + evmasm::LinkerObject::libraryPlaceholder(_libraryName) + \" -> \" + _libraryName;\n}\n\nstd::string CommandLineInterface::objectWithLinkRefsHex(evmasm::LinkerObject const& _obj)\n{\n\tstd::string out = _obj.toHex();\n\tif (!_obj.linkReferences.empty())\n\t{\n\t\tout += \"\\n\";\n\t\tfor (auto const& linkRef: _obj.linkReferences)\n\t\t\tout += \"\\n\" + libraryPlaceholderHint(linkRef.second);\n\t}\n\treturn out;\n}\n\nvoid CommandLineInterface::assembleYul(yul::YulStack::Machine _targetMachine)\n{\n\tsolAssert(m_options.input.mode == InputMode::Assembler);\n\n\tbool successful = true;\n\tstd::map<std::string, yul::YulStack> yulStacks;\n\tstd::map<std::string, yul::MachineAssemblyObject> objects;\n\tfor (auto const& [sourceUnitName, yulSource]: m_fileReader.sourceUnits())\n\t{\n\t\tauto& stack = yulStacks[sourceUnitName] = yul::YulStack(\n\t\t\tm_options.output.evmVersion,\n\t\t\tm_options.output.eofVersion,\n\t\t\tm_options.optimiserSettings(),\n\t\t\tm_options.output.debugInfoSelection.has_value() ?\n\t\t\t\tm_options.output.debugInfoSelection.value() :\n\t\t\t\tDebugInfoSelection::Default()\n\t\t);\n\n\t\tsuccessful = successful && stack.parseAndAnalyze(sourceUnitName, yulSource);\n\t\tif (!successful)\n\t\t\tsolAssert(stack.hasErrors(), \"No error reported, but parsing/analysis failed.\");\n\t\telse\n\t\t{\n\t\t\tif (\n\t\t\t\tm_options.compiler.outputs.asmJson &&\n\t\t\t\tstack.parserResult() &&\n\t\t\t\t!stack.parserResult()->hasContiguousSourceIndices()\n\t\t\t)\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineExecutionError,\n\t\t\t\t\t\"Generating the assembly JSON output was not possible. \"\n\t\t\t\t\t\"Source indices provided in the @use-src annotation in the Yul input do not start at 0 or are not contiguous.\"\n\t\t\t\t);\n\n\t\t\tstack.optimize();\n\n\t\t\tyul::MachineAssemblyObject object = stack.assemble(_targetMachine, m_options.output.viaSSACFG);\n\t\t\tif (object.bytecode)\n\t\t\t\tobject.bytecode->link(m_options.linker.libraries);\n\t\t\tobjects.insert({sourceUnitName, std::move(object)});\n\t\t}\n\t}\n\n\tfor (auto const& sourceAndStack: yulStacks)\n\t{\n\t\tauto const& stack = sourceAndStack.second;\n\t\tSourceReferenceFormatter formatter(serr(false), stack, coloredOutput(m_options), m_options.formatting.withErrorIds);\n\n\t\tfor (auto const& error: stack.errors())\n\t\t{\n\t\t\tm_hasOutput = true;\n\t\t\tformatter.printErrorInformation(*error);\n\t\t}\n\t\tif (Error::containsErrors(stack.errors()))\n\t\t\tsuccessful = false;\n\t}\n\n\tif (!successful)\n\t{\n\t\tsolAssert(m_hasOutput);\n\t\tsolThrow(CommandLineExecutionError, \"\");\n\t}\n\n\tfor (auto const& [sourceUnitName, yulSource]: m_fileReader.sourceUnits())\n\t{\n\t\tsolAssert(_targetMachine == yul::YulStack::Machine::EVM);\n\n\t\tyul::YulStack const& stack = yulStacks[sourceUnitName];\n\t\tyul::MachineAssemblyObject const& object = objects[sourceUnitName];\n\n\t\tif (m_options.compiler.outputs.ethdebug)\n\t\t{\n\t\t\tsout() << \"======= Debug Data (ethdebug/format/info/resources) =======\" << std::endl;\n\t\t\tsout() << util::jsonPrint(\n\t\t\t\t\tevmasm::ethdebug::resources({{sourceUnitName}}, VersionString),\n\t\t\t\t\tm_options.formatting.json\n\t\t\t) << std::endl;\n\t\t}\n\n\t\tstd::string machine = \"EVM\";\n\t\tsout() << std::endl << \"======= \" << sourceUnitName << \" (\" << machine << \") =======\" << std::endl;\n\n\t\tif (m_options.compiler.outputs.irOptimized)\n\t\t{\n\t\t\t// NOTE: This actually outputs unoptimized code when the optimizer is disabled but\n\t\t\t// 'ir' output in StandardCompiler works the same way.\n\t\t\tsout() << std::endl << \"Pretty printed source:\" << std::endl;\n\t\t\tsout() << stack.print() << std::endl;\n\t\t}\n\n\t\tif (m_options.compiler.outputs.binary)\n\t\t{\n\t\t\tsout() << std::endl << \"Binary representation:\" << std::endl;\n\t\t\tif (object.bytecode)\n\t\t\t\tsout() << object.bytecode->toHex() << std::endl;\n\t\t\telse\n\t\t\t\treport(Error::Severity::Info, \"No binary representation found.\");\n\t\t}\n\t\tif (m_options.compiler.outputs.astCompactJson)\n\t\t{\n\t\t\tsout() << \"AST:\" << std::endl << std::endl;\n\t\t\tsout() << util::jsonPrint(stack.astJson(), m_options.formatting.json) << std::endl;\n\t\t}\n\t\tif (m_options.compiler.outputs.yulCFGJson)\n\t\t{\n\t\t\tsout() << \"Yul Control Flow Graph:\" << std::endl << std::endl;\n\t\t\tsout() << util::jsonPrint(stack.cfgJson(), m_options.formatting.json) << std::endl;\n\t\t}\n\t\tsolAssert(_targetMachine == yul::YulStack::Machine::EVM, \"\");\n\t\tif (m_options.compiler.outputs.asm_)\n\t\t{\n\t\t\tsout() << std::endl << \"Text representation:\" << std::endl;\n\t\t\tstd::string assemblyText{object.assembly->assemblyString(stack.debugInfoSelection())};\n\t\t\tif (!assemblyText.empty())\n\t\t\t\tsout() << assemblyText << std::endl;\n\t\t\telse\n\t\t\t\treport(Error::Severity::Info, \"No text representation found.\");\n\t\t}\n\t\tif (m_options.compiler.outputs.asmJson)\n\t\t{\n\t\t\tsout() << std::endl << \"EVM assembly:\" << std::endl;\n\t\t\tstd::map<std::string, unsigned> sourceIndices;\n\t\t\tstack.parserResult()->collectSourceIndices(sourceIndices);\n\t\t\tsout() << util::jsonPrint(\n\t\t\t\tobject.assembly->assemblyJSON(sourceIndices),\n\t\t\t\tm_options.formatting.json\n\t\t\t) << std::endl;\n\t\t}\n\t\tif (m_options.compiler.outputs.ethdebug)\n\t\t{\n\t\t\tsout() << std::endl << \"Debug Data (ethdebug/format/program):\" << std::endl;\n\t\t\tsout() << util::jsonPrint(\n\t\t\t\tobject.ethdebug,\n\t\t\t\tm_options.formatting.json\n\t\t\t) << std::endl;\n\t\t}\n\t}\n}\n\nvoid CommandLineInterface::outputCompilationResults()\n{\n\tsolAssert(CompilerInputModes.count(m_options.input.mode) == 1);\n\n\thandleCombinedJSON();\n\n\t// do we need AST output?\n\thandleAst();\n\n\thandleEthdebug();\n\n\tCompilerOutputs astOutputSelection;\n\tastOutputSelection.astCompactJson = true;\n\tif (m_options.compiler.outputs != CompilerOutputs() && m_options.compiler.outputs != astOutputSelection)\n\t{\n\t\t// Currently AST is the only output allowed with --stop-after parsing. For all of the others\n\t\t// we can safely assume that full compilation was performed and successful.\n\t\tsolAssert(m_options.output.stopAfter >= CompilerStack::State::CompilationSuccessful);\n\n\t\tfor (std::string const& contract: m_compiler->contractNames())\n\t\t{\n\t\t\tif (needsHumanTargetedStdout(m_options))\n\t\t\t\tsout() << std::endl << \"======= \" << contract << \" =======\" << std::endl;\n\n\t\t\thandleEVMAssembly(contract);\n\n\t\t\tif (m_options.compiler.estimateGas)\n\t\t\t\thandleGasEstimation(contract);\n\n\t\t\thandleBytecode(contract);\n\t\t\thandleIR(contract);\n\t\t\thandleIRAst(contract);\n\t\t\thandleIROptimized(contract);\n\t\t\thandleIROptimizedAst(contract);\n\t\t\thandleYulCFGExport(contract);\n\t\t\thandleSignatureHashes(contract);\n\t\t\thandleMetadata(contract);\n\t\t\thandleABI(contract);\n\t\t\thandleStorageLayout(contract);\n\t\t\thandleTransientStorageLayout(contract);\n\t\t\thandleNatspec(true, contract);\n\t\t\thandleNatspec(false, contract);\n\t\t\thandleEthdebug(contract);\n\t\t} // end of contracts iteration\n\t}\n\n\tif (!m_hasOutput)\n\t{\n\t\tif (!m_options.output.dir.empty())\n\t\t\tsout() << \"Compiler run successful. Artifact(s) can be found in directory \" << m_options.output.dir << \".\" << std::endl;\n\t\telse if (m_compiler->contractNames().empty())\n\t\t\tsout() << \"Compiler run successful. No contracts to compile.\" << std::endl;\n\t\telse\n\t\t\tsout() << \"Compiler run successful. No output generated.\" << std::endl;\n\t}\n}\n\nvoid CommandLineInterface::report(langutil::Error::Severity _severity, std::string _message)\n{\n\tSourceReferenceFormatter::printPrimaryMessage(\n\t\tserr(),\n\t\t_message,\n\t\t_severity,\n\t\tstd::nullopt,\n\t\tcoloredOutput(m_options),\n\t\tm_options.formatting.withErrorIds\n\t);\n}\n\n}\n"
  },
  {
    "path": "solc/CommandLineInterface.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Lefteris <lefteris@ethdev.com>\n * @date 2014\n * Solidity command line interface.\n */\n#pragma once\n\n#include <solc/CommandLineParser.h>\n\n#include <libevmasm/AbstractAssemblyStack.h>\n#include <libevmasm/EVMAssemblyStack.h>\n#include <libsolidity/interface/CompilerStack.h>\n#include <libsolidity/interface/DebugSettings.h>\n#include <libsolidity/interface/FileReader.h>\n#include <libsolidity/interface/SMTSolverCommand.h>\n#include <libsolidity/interface/UniversalCallback.h>\n#include <libyul/YulStack.h>\n\n#include <iostream>\n#include <memory>\n#include <string>\n\nnamespace solidity::frontend\n{\n\nclass CommandLineInterface\n{\npublic:\n\texplicit CommandLineInterface(\n\t\tstd::istream& _sin,\n\t\tstd::ostream& _sout,\n\t\tstd::ostream& _serr,\n\t\tCommandLineOptions const& _options = CommandLineOptions{}\n\t):\n\t\tm_sin(_sin),\n\t\tm_sout(_sout),\n\t\tm_serr(_serr),\n\t\tm_options(_options)\n\t{}\n\n\t/// Parses command-line arguments, executes the requested operation and handles validation and\n\t/// execution errors.\n\t/// @returns false if it catches a @p CommandLineValidationError or if the application is\n\t/// expected to exit with a non-zero exit code despite there being no error.\n\tbool run(int _argc, char const* const* _argv);\n\n\t/// Parses command line arguments and stores the result in @p m_options.\n\t/// @throws CommandLineValidationError if command-line arguments are invalid.\n\t/// @returns false if the application is expected to exit with a non-zero exit code despite\n\t/// there being no error.\n\tbool parseArguments(int _argc, char const* const* _argv);\n\n\t/// Reads the content of all input files and initializes the file reader.\n\t/// @throws CommandLineValidationError if it fails to read the input files (invalid paths,\n\t/// non-existent files, not enough or too many input files, etc.).\n\tvoid readInputFiles();\n\n\t/// Executes the requested operation (compilation, assembling, standard JSON, etc.) and prints\n\t/// results to the terminal.\n\t/// @throws CommandLineExecutionError if execution fails due to errors in the input files.\n\t/// @throws CommandLineOutputError if creating output files or writing to them fails.\n\tvoid processInput();\n\n\tCommandLineOptions const& options() const { return m_options; }\n\tFileReader const& fileReader() const { return m_fileReader; }\n\tstd::optional<std::string> const& standardJsonInput() const { return m_standardJsonInput; }\n\nprivate:\n\tvoid printVersion();\n\tvoid printLicense();\n\tvoid compile();\n\tvoid assembleFromEVMAssemblyJSON();\n\tvoid serveLSP();\n\tvoid link();\n\tvoid writeLinkedFiles();\n\t/// @returns the ``// <identifier> -> name`` hint for library placeholders.\n\tstatic std::string libraryPlaceholderHint(std::string const& _libraryName);\n\t/// @returns the full object with library placeholder hints in hex.\n\tstatic std::string objectWithLinkRefsHex(evmasm::LinkerObject const& _obj);\n\n\tvoid assembleYul(yul::YulStack::Machine _targetMachine);\n\n\tvoid outputCompilationResults();\n\n\tvoid handleCombinedJSON();\n\tvoid handleAst();\n\tvoid handleEthdebug();\n\tvoid handleEVMAssembly(std::string const& _contract);\n\tvoid handleBinary(std::string const& _contract);\n\tvoid handleOpcode(std::string const& _contract);\n\tvoid handleIR(std::string const& _contract);\n\tvoid handleIRAst(std::string const& _contract);\n\tvoid handleIROptimized(std::string const& _contract);\n\tvoid handleIROptimizedAst(std::string const& _contract);\n\tvoid handleYulCFGExport(std::string const& _contract);\n\tvoid handleBytecode(std::string const& _contract);\n\tvoid handleSignatureHashes(std::string const& _contract);\n\tvoid handleMetadata(std::string const& _contract);\n\tvoid handleABI(std::string const& _contract);\n\tvoid handleNatspec(bool _natspecDev, std::string const& _contract);\n\tvoid handleGasEstimation(std::string const& _contract);\n\tvoid handleStorageLayout(std::string const& _contract);\n\tvoid handleTransientStorageLayout(std::string const& _contract);\n\tvoid handleEthdebug(std::string const& _contract);\n\n\t/// Tries to read @ m_sourceCodes as a JSONs holding ASTs\n\t/// such that they can be imported into the compiler  (importASTs())\n\t/// (produced by --combined-json ast <file.sol>\n\t/// or standard-json output\n\tstd::map<std::string, Json> parseAstFromInput();\n\n\t/// Create a file in the given directory\n\t/// @arg _fileName the name of the file\n\t/// @arg _data to be written\n\tvoid createFile(std::string const& _fileName, std::string const& _data);\n\n\t/// Create a json file in the given directory\n\t/// @arg _fileName the name of the file (the extension will be replaced with .json)\n\t/// @arg _json json string to be written\n\tvoid createJson(std::string const& _fileName, std::string const& _json);\n\n\t/// Returns the stream that should receive normal output. Sets m_hasOutput to true if the\n\t/// stream has ever been used unless @arg _markAsUsed is set to false.\n\tstd::ostream& sout(bool _markAsUsed = true);\n\n\t/// Returns the stream that should receive error output. Sets m_hasOutput to true if the\n\t/// stream has ever been used unless @arg _markAsUsed is set to false.\n\tstd::ostream& serr(bool _markAsUsed = true);\n\n\tvoid report(langutil::Error::Severity _severity, std::string _message);\n\n\tstd::istream& m_sin;\n\tstd::ostream& m_sout;\n\tstd::ostream& m_serr;\n\tbool m_hasOutput = false;\n\tFileReader m_fileReader;\n\tSMTSolverCommand m_solverCommand;\n\tUniversalCallback m_universalCallback{&m_fileReader, m_solverCommand};\n\tstd::optional<std::string> m_standardJsonInput;\n\tstd::unique_ptr<frontend::CompilerStack> m_compiler;\n\tstd::unique_ptr<evmasm::EVMAssemblyStack> m_evmAssemblyStack;\n\tevmasm::AbstractAssemblyStack* m_assemblyStack = nullptr;\n\tCommandLineOptions m_options;\n};\n\n}\n"
  },
  {
    "path": "solc/CommandLineParser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <solc/CommandLineParser.h>\n\n#include <solc/Exceptions.h>\n\n#include <libyul/optimiser/Suite.h>\n\n#include <liblangutil/EVMVersion.h>\n\n#include <boost/algorithm/string.hpp>\n\n#include <range/v3/view/transform.hpp>\n#include <range/v3/view/filter.hpp>\n#include <range/v3/range/conversion.hpp>\n\n#include <fmt/format.h>\n\nusing namespace solidity::langutil;\nusing namespace solidity::yul;\n\nnamespace po = boost::program_options;\n\nnamespace solidity::frontend\n{\n\nstatic std::string const g_strAllowPaths = \"allow-paths\";\nstatic std::string const g_strBasePath = \"base-path\";\nstatic std::string const g_strIncludePath = \"include-path\";\nstatic std::string const g_strAssemble = \"assemble\";\nstatic std::string const g_strCombinedJson = \"combined-json\";\nstatic std::string const g_strEVM = \"evm\";\nstatic std::string const g_strEVMVersion = \"evm-version\";\nstatic std::string const g_strEOFVersion = \"experimental-eof-version\";\nstatic std::string const g_strViaIR = \"via-ir\";\nstatic std::string const g_strViaSSACFG = \"via-ssa-cfg\";\nstatic std::string const g_strExperimentalViaIR = \"experimental-via-ir\";\nstatic std::string const g_strExperimental = \"experimental\";\nstatic std::string const g_strGas = \"gas\";\nstatic std::string const g_strHelp = \"help\";\nstatic std::string const g_strImportAst = \"import-ast\";\nstatic std::string const g_strImportEvmAssemblerJson = \"import-asm-json\";\nstatic std::string const g_strInputFile = \"input-file\";\nstatic std::string const g_strYul = \"yul\";\nstatic std::string const g_strYulDialect = \"yul-dialect\";\nstatic std::string const g_strDebugInfo = \"debug-info\";\nstatic std::string const g_strIPFS = \"ipfs\";\nstatic std::string const g_strLicense = \"license\";\nstatic std::string const g_strLibraries = \"libraries\";\nstatic std::string const g_strLink = \"link\";\nstatic std::string const g_strLSP = \"lsp\";\nstatic std::string const g_strMachine = \"machine\";\nstatic std::string const g_strNoCBORMetadata = \"no-cbor-metadata\";\nstatic std::string const g_strMetadataHash = \"metadata-hash\";\nstatic std::string const g_strMetadataLiteral = \"metadata-literal\";\nstatic std::string const g_strModelCheckerContracts = \"model-checker-contracts\";\nstatic std::string const g_strModelCheckerDivModNoSlacks = \"model-checker-div-mod-no-slacks\";\nstatic std::string const g_strModelCheckerEngine = \"model-checker-engine\";\nstatic std::string const g_strModelCheckerExtCalls = \"model-checker-ext-calls\";\nstatic std::string const g_strModelCheckerInvariants = \"model-checker-invariants\";\nstatic std::string const g_strModelCheckerPrintQuery = \"model-checker-print-query\";\nstatic std::string const g_strModelCheckerShowProvedSafe = \"model-checker-show-proved-safe\";\nstatic std::string const g_strModelCheckerShowUnproved = \"model-checker-show-unproved\";\nstatic std::string const g_strModelCheckerShowUnsupported = \"model-checker-show-unsupported\";\nstatic std::string const g_strModelCheckerSolvers = \"model-checker-solvers\";\nstatic std::string const g_strModelCheckerTargets = \"model-checker-targets\";\nstatic std::string const g_strModelCheckerTimeout = \"model-checker-timeout\";\nstatic std::string const g_strModelCheckerBMCLoopIterations = \"model-checker-bmc-loop-iterations\";\nstatic std::string const g_strNone = \"none\";\nstatic std::string const g_strNoOptimizeYul = \"no-optimize-yul\";\nstatic std::string const g_strNoImportCallback = \"no-import-callback\";\nstatic std::string const g_strOptimize = \"optimize\";\nstatic std::string const g_strOptimizeRuns = \"optimize-runs\";\nstatic std::string const g_strOptimizeYul = \"optimize-yul\";\nstatic std::string const g_strYulOptimizations = \"yul-optimizations\";\nstatic std::string const g_strOutputDir = \"output-dir\";\nstatic std::string const g_strOverwrite = \"overwrite\";\nstatic std::string const g_strRevertStrings = \"revert-strings\";\nstatic std::string const g_strStopAfter = \"stop-after\";\n\n/// Possible arguments to for --revert-strings\nstatic std::set<std::string> const g_revertStringsArgs\n{\n\trevertStringsToString(RevertStrings::Default),\n\trevertStringsToString(RevertStrings::Strip),\n\trevertStringsToString(RevertStrings::Debug),\n\trevertStringsToString(RevertStrings::VerboseDebug)\n};\n\nstatic std::string const g_strStandardJSON = \"standard-json\";\nstatic std::string const g_strStrictAssembly = \"strict-assembly\";\nstatic std::string const g_strSwarm = \"swarm\";\nstatic std::string const g_strPrettyJson = \"pretty-json\";\nstatic std::string const g_strJsonIndent = \"json-indent\";\nstatic std::string const g_strVersion = \"version\";\nstatic std::string const g_strIgnoreMissingFiles = \"ignore-missing\";\nstatic std::string const g_strColor = \"color\";\nstatic std::string const g_strNoColor = \"no-color\";\nstatic std::string const g_strErrorIds = \"error-codes\";\n\n/// Possible arguments to for --machine\nstatic std::set<std::string> const g_machineArgs\n{\n\tg_strEVM\n};\n\n/// Possible arguments to for --yul-dialect\nstatic std::set<std::string> const g_yulDialectArgs\n{\n\tg_strEVM\n};\n\n/// Possible arguments to for --metadata-hash\nstatic std::set<std::string> const g_metadataHashArgs\n{\n\tg_strIPFS,\n\tg_strSwarm,\n\tg_strNone\n};\n\nstatic std::map<InputMode, std::string> const g_inputModeName = {\n\t{InputMode::Help, \"help\"},\n\t{InputMode::License, \"license\"},\n\t{InputMode::Version, \"version\"},\n\t{InputMode::Compiler, \"compiler\"},\n\t{InputMode::CompilerWithASTImport, \"compiler (AST import)\"},\n\t{InputMode::Assembler, \"assembler\"},\n\t{InputMode::StandardJson, \"standard JSON\"},\n\t{InputMode::Linker, \"linker\"},\n\t{InputMode::LanguageServer, \"language server (LSP)\"},\n\t{InputMode::EVMAssemblerJSON, \"EVM assembler (JSON format)\"},\n};\n\nvoid CommandLineParser::checkMutuallyExclusive(std::vector<std::string> const& _optionNames)\n{\n\tif (countEnabledOptions(_optionNames) > 1)\n\t{\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\t\"The following options are mutually exclusive: \" + joinOptionNames(_optionNames) + \". \" +\n\t\t\t\"Select at most one.\"\n\t\t);\n\t}\n}\n\nstd::vector<std::string> const& CommandLineParser::experimentalOptionNames()\n{\n\tstatic std::vector<std::string> const names{\n\t\tg_strLSP,\n\t\tg_strImportAst,\n\t\tg_strImportEvmAssemblerJson,\n\t\t\"ir-ast-json\",\n\t\t\"ir-optimized-ast-json\",\n\t\t\"yul-cfg-json\",\n\t\t\"ethdebug\",\n\t\t\"ethdebug-runtime\",\n\t\tg_strEOFVersion,\n\t\tg_strViaSSACFG,\n\t};\n\treturn names;\n}\n\nvoid CommandLineParser::checkExperimental(std::vector<std::string> const& _optionNames) const\n{\n\tif (!m_args.contains(g_strExperimental) && countEnabledOptions(_optionNames) > 0)\n\t{\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\tfmt::format(\n\t\t\t\t\"The following options are only available in experimental mode: {}. \"\n\t\t\t\t\"To enable experimental mode, use the --{} flag.\",\n\t\t\t\tjoinOptionNames(enabledOptions(_optionNames)),\n\t\t\t\tg_strExperimental\n\t\t\t)\n\t\t);\n\t}\n\n\tif (m_args.contains(g_strEVMVersion))\n\t{\n\t\tstd::string versionOptionStr = m_args[g_strEVMVersion].as<std::string>();\n\t\tstd::optional<langutil::EVMVersion> versionOption = langutil::EVMVersion::fromString(versionOptionStr);\n\n\t\tif (versionOption.has_value() && versionOption->isExperimental())\n\t\t\t// TODO: Cover with test when the Amsterdam version is introduced\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"EVM version '{}' is experimental and can only be selected in experimental mode. \"\n\t\t\t\t\t\"To enable experimental mode, use the --{} flag\",\n\t\t\t\t\tm_options.output.evmVersion.name(),\n\t\t\t\t\tg_strExperimental\n\t\t\t\t)\n\t\t\t);\n\t}\n}\n\nstd::ostream& operator<<(std::ostream& _out, CompilerOutputs const& _selection)\n{\n\tstd::vector<std::string> serializedSelection;\n\tfor (auto&& [componentName, component]: CompilerOutputs::componentMap())\n\t\tif (_selection.*component)\n\t\t\tserializedSelection.push_back(CompilerOutputs::componentName(component));\n\n\treturn _out << util::joinHumanReadable(serializedSelection, \",\");\n}\n\nstd::string const& CompilerOutputs::componentName(bool CompilerOutputs::* _component)\n{\n\tsolAssert(_component, \"\");\n\n\t// NOTE: Linear search is not optimal but it's simpler than getting pointers-to-members to work as map keys.\n\tfor (auto const& [componentName, component]: CompilerOutputs::componentMap())\n\t\tif (component == _component)\n\t\t\treturn componentName;\n\n\tsolAssert(false, \"\");\n}\n\nstd::ostream& operator<<(std::ostream& _out, CombinedJsonRequests const& _requests)\n{\n\tstd::vector<std::string> serializedRequests;\n\tfor (auto&& [componentName, component]: CombinedJsonRequests::componentMap())\n\t\tif (_requests.*component)\n\t\t\tserializedRequests.push_back(CombinedJsonRequests::componentName(component));\n\n\treturn _out << util::joinHumanReadable(serializedRequests, \",\");\n}\n\nstd::string const& CombinedJsonRequests::componentName(bool CombinedJsonRequests::* _component)\n{\n\tsolAssert(_component, \"\");\n\n\tfor (auto const& [componentName, component]: CombinedJsonRequests::componentMap())\n\t\tif (component == _component)\n\t\t\treturn componentName;\n\n\tsolAssert(false, \"\");\n}\n\nOptimiserSettings CommandLineOptions::optimiserSettings() const\n{\n\tOptimiserSettings settings;\n\n\tif (optimizer.optimizeEvmasm)\n\t\tsettings = OptimiserSettings::standard();\n\telse\n\t\tif (input.mode == InputMode::EVMAssemblerJSON)\n\t\t\tsettings = OptimiserSettings::none();\n\t\telse\n\t\t\tsettings = OptimiserSettings::minimal();\n\n\tsettings.runYulOptimiser = optimizer.optimizeYul;\n\tif (optimizer.optimizeYul)\n\t\t// NOTE: Standard JSON disables optimizeStackAllocation by default when yul optimizer is disabled.\n\t\t// --optimize --no-optimize-yul on the CLI does not have that effect.\n\t\tsettings.optimizeStackAllocation = true;\n\n\tif (optimizer.expectedExecutionsPerDeployment.has_value())\n\t\tsettings.expectedExecutionsPerDeployment = optimizer.expectedExecutionsPerDeployment.value();\n\n\tif (optimizer.yulSteps.has_value())\n\t{\n\t\tstd::string const fullSequence = optimizer.yulSteps.value();\n\t\tauto const delimiterPos = fullSequence.find(\":\");\n\t\tsettings.yulOptimiserSteps = fullSequence.substr(0, delimiterPos);\n\n\t\tif (delimiterPos != std::string::npos)\n\t\t\tsettings.yulOptimiserCleanupSteps = fullSequence.substr(delimiterPos + 1);\n\t\telse\n\t\t\tsolAssert(settings.yulOptimiserCleanupSteps == OptimiserSettings::DefaultYulOptimiserCleanupSteps);\n\t}\n\n\treturn settings;\n}\n\nvoid CommandLineParser::parse(int _argc, char const* const* _argv)\n{\n\tparseArgs(_argc, _argv);\n\tprocessArgs();\n}\n\nvoid CommandLineParser::parseInputPathsAndRemappings()\n{\n\tm_options.input.ignoreMissingFiles = (m_args.count(g_strIgnoreMissingFiles) > 0);\n\n\tif (m_args.count(g_strInputFile))\n\t\tfor (std::string const& positionalArg: m_args[g_strInputFile].as<std::vector<std::string>>())\n\t\t{\n\t\t\tif (ImportRemapper::isRemapping(positionalArg))\n\t\t\t{\n\t\t\t\tstd::optional<ImportRemapper::Remapping> remapping = ImportRemapper::parseRemapping(positionalArg);\n\t\t\t\tif (!remapping.has_value())\n\t\t\t\t\tsolThrow(CommandLineValidationError, \"Invalid remapping: \\\"\" + positionalArg + \"\\\".\");\n\n\t\t\t\tif (m_options.input.mode == InputMode::StandardJson)\n\t\t\t\t\tsolThrow(\n\t\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\t\t\"Import remappings are not accepted on the command line in Standard JSON mode.\\n\"\n\t\t\t\t\t\t\"Please put them under 'settings.remappings' in the JSON input.\"\n\t\t\t\t\t);\n\n\t\t\t\tif (!remapping->target.empty())\n\t\t\t\t{\n\t\t\t\t\t// If the target is a directory, whitelist it. Otherwise whitelist containing dir.\n\t\t\t\t\t// NOTE: /a/b/c/ is a directory while /a/b/c is not.\n\t\t\t\t\tboost::filesystem::path remappingDir = remapping->target;\n\t\t\t\t\tif (remappingDir.filename() != \"..\")\n\t\t\t\t\t\t// As an exception we'll treat /a/b/c/.. as a directory too. It would be\n\t\t\t\t\t\t// unintuitive to whitelist /a/b/c when the target is equivalent to /a/b/.\n\t\t\t\t\t\tremappingDir.remove_filename();\n\t\t\t\t\tm_options.input.allowedDirectories.insert(remappingDir.empty() ? \".\" : remappingDir);\n\t\t\t\t}\n\n\t\t\t\tm_options.input.remappings.emplace_back(std::move(remapping.value()));\n\t\t\t}\n\t\t\telse if (positionalArg == \"-\")\n\t\t\t\tm_options.input.addStdin = true;\n\t\t\telse\n\t\t\t\tm_options.input.paths.insert(positionalArg);\n\t\t}\n\n\tif (m_options.input.mode == InputMode::StandardJson)\n\t{\n\t\tif (m_options.input.paths.size() > 1 || (m_options.input.paths.size() == 1 && m_options.input.addStdin))\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\t\"Too many input files for --\" + g_strStandardJSON + \".\\n\"\n\t\t\t\t\"Please either specify a single file name or provide its content on standard input.\"\n\t\t\t);\n\t\telse if (m_options.input.paths.size() == 0)\n\t\t\t// Standard JSON mode input used to be handled separately and zero files meant \"read from stdin\".\n\t\t\t// Keep it working that way for backwards-compatibility.\n\t\t\tm_options.input.addStdin = true;\n\t}\n\telse if (m_options.input.paths.size() == 0 && !m_options.input.addStdin)\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\t\"No input files given. If you wish to use the standard input please specify \\\"-\\\" explicitly.\"\n\t\t);\n}\n\nvoid CommandLineParser::parseLibraryOption(std::string const& _input)\n{\n\tnamespace fs = boost::filesystem;\n\tstd::string data = _input;\n\ttry\n\t{\n\t\tif (fs::is_regular_file(_input))\n\t\t\tdata = util::readFileAsString(_input);\n\t}\n\tcatch (fs::filesystem_error const&)\n\t{\n\t\t// Thrown e.g. if path is too long.\n\t}\n\tcatch (util::FileNotFound const&)\n\t{\n\t\t// Should not happen if `fs::is_regular_file` is correct.\n\t}\n\tcatch (util::NotAFile const&)\n\t{\n\t\t// Should not happen if `fs::is_regular_file` is correct.\n\t}\n\n\tstd::vector<std::string> libraries;\n\tboost::split(libraries, data, boost::is_space() || boost::is_any_of(\",\"), boost::token_compress_on);\n\tfor (std::string const& lib: libraries)\n\t\tif (!lib.empty())\n\t\t{\n\t\t\t//search for equal sign or last colon in string as our binaries output placeholders in the form of file=Name or file:Name\n\t\t\t//so we need to search for `=` or `:` in the string\n\t\t\tauto separator = lib.rfind('=');\n\t\t\tbool isSeparatorEqualSign = true;\n\t\t\tif (separator == std::string::npos)\n\t\t\t{\n\t\t\t\tseparator = lib.rfind(':');\n\t\t\t\tif (separator == std::string::npos)\n\t\t\t\t\tsolThrow(\n\t\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\t\t\"Equal sign separator missing in library address specifier \\\"\" + lib + \"\\\"\"\n\t\t\t\t\t);\n\t\t\t\telse\n\t\t\t\t\tisSeparatorEqualSign = false; // separator is colon\n\t\t\t}\n\t\t\telse\n\t\t\t\tif (lib.rfind('=') != lib.find('='))\n\t\t\t\t\tsolThrow(\n\t\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\t\t\"Only one equal sign \\\"=\\\" is allowed in the address string \\\"\" + lib + \"\\\".\"\n\t\t\t\t\t);\n\n\t\t\tstd::string libName(lib.begin(), lib.begin() + static_cast<ptrdiff_t>(separator));\n\t\t\tboost::trim(libName);\n\t\t\tif (m_options.linker.libraries.count(libName))\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\t\"Address specified more than once for library \\\"\" + libName + \"\\\".\"\n\t\t\t\t);\n\n\t\t\tstd::string addrString(lib.begin() + static_cast<ptrdiff_t>(separator) + 1, lib.end());\n\t\t\tboost::trim(addrString);\n\t\t\tif (addrString.empty())\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\t\"Empty address provided for library \\\"\" + libName + \"\\\".\\n\"\n\t\t\t\t\t\"Note that there should not be any whitespace after the \" +\n\t\t\t\t\t(isSeparatorEqualSign ? \"equal sign\" : \"colon\") + \".\"\n\t\t\t\t);\n\n\t\t\tif (addrString.substr(0, 2) == \"0x\")\n\t\t\t\taddrString = addrString.substr(2);\n\t\t\telse\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\t\"The address \" + addrString + \" is not prefixed with \\\"0x\\\".\\n\"\n\t\t\t\t\t\"Note that the address must be prefixed with \\\"0x\\\".\"\n\t\t\t\t);\n\n\t\t\tif (addrString.length() != 40)\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\t\"Invalid length for address for library \\\"\" + libName + \"\\\": \" +\n\t\t\t\t\tstd::to_string(addrString.length()) + \" instead of 40 characters.\"\n\t\t\t\t);\n\t\t\tif (!util::passesAddressChecksum(addrString, false))\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\t\"Invalid checksum on address for library \\\"\" + libName + \"\\\": \" + addrString + \"\\n\"\n\t\t\t\t\t\"The correct checksum is \" + util::getChecksummedAddress(addrString)\n\t\t\t\t);\n\t\t\tbytes binAddr = util::fromHex(addrString);\n\t\t\tutil::h160 address(binAddr, util::h160::AlignRight);\n\t\t\tif (binAddr.size() > 20 || address == util::h160())\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\t\"Invalid address for library \\\"\" + libName + \"\\\": \" + addrString\n\t\t\t\t);\n\t\t\tm_options.linker.libraries[libName] = address;\n\t\t}\n}\n\nstd::vector<std::string> CommandLineParser::enabledOptions(std::vector<std::string> const& _optionList) const\n{\n\tauto optionEnabled = [&](std::string const& _option) { return m_args.contains(_option); };\n\treturn _optionList | ranges::views::filter(optionEnabled) | ranges::to_vector;\n}\n\nvoid CommandLineParser::parseOutputSelection()\n{\n\tstatic auto outputSupported = [](InputMode _mode, std::string_view _outputName)\n\t{\n\t\tstatic std::set<std::string> const compilerModeOutputs = (\n\t\t\tCompilerOutputs::componentMap() |\n\t\t\tranges::views::keys |\n\t\t\tranges::to<std::set>()\n\t\t);\n\t\tstatic std::set<std::string> const assemblerModeOutputs = {\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::asm_),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::binary),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::irOptimized),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::astCompactJson),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::asmJson),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::yulCFGJson),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::ethdebug),\n\t\t};\n\t\tstatic std::set<std::string> const evmAssemblyJsonImportModeOutputs = {\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::asm_),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::binary),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::binaryRuntime),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::opcodes),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::asmJson),\n\t\t};\n\t\tswitch (_mode)\n\t\t{\n\t\tcase InputMode::Help:\n\t\tcase InputMode::License:\n\t\tcase InputMode::Version:\n\t\tcase InputMode::LanguageServer:\n\t\t\tsolAssert(false);\n\t\tcase InputMode::Compiler:\n\t\tcase InputMode::CompilerWithASTImport:\n\t\t\treturn util::contains(compilerModeOutputs, _outputName);\n\t\tcase InputMode::EVMAssemblerJSON:\n\t\t\treturn util::contains(evmAssemblyJsonImportModeOutputs, _outputName);\n\t\tcase InputMode::Assembler:\n\t\t\treturn util::contains(assemblerModeOutputs, _outputName);\n\t\tcase InputMode::StandardJson:\n\t\tcase InputMode::Linker:\n\t\t\treturn false;\n\t\t}\n\n\t\tsolAssert(false, \"\");\n\t};\n\n\tfor (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap())\n\t\tm_options.compiler.outputs.*outputComponent = (m_args.count(optionName) > 0);\n\n\tif (m_options.input.mode == InputMode::Assembler && m_options.compiler.outputs == CompilerOutputs{})\n\t{\n\t\t// In assembly mode keep the default outputs enabled for backwards-compatibility.\n\t\t// TODO: Remove this (must be done in a breaking release).\n\t\tm_options.compiler.outputs.asm_ = true;\n\t\tm_options.compiler.outputs.binary = true;\n\t\tm_options.compiler.outputs.irOptimized = true;\n\t}\n\n\tstd::vector<std::string> unsupportedOutputs;\n\tfor (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap())\n\t\tif (m_options.compiler.outputs.*outputComponent && !outputSupported(m_options.input.mode, optionName))\n\t\t\tunsupportedOutputs.push_back(optionName);\n\n\tif (!unsupportedOutputs.empty())\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\t\"The following outputs are not supported in \" + g_inputModeName.at(m_options.input.mode) + \" mode: \" +\n\t\t\tjoinOptionNames(unsupportedOutputs) + \".\"\n\t\t);\n\n\t// TODO: restrict EOF version to correct EVM version.\n}\n\npo::options_description CommandLineParser::optionsDescription()\n{\n\t// Declare the supported options.\n\tpo::options_description desc((R\"(solc, the Solidity commandline compiler.\n\nThis program comes with ABSOLUTELY NO WARRANTY. This is free software, and you\nare welcome to redistribute it under certain conditions. See 'solc --)\" + g_strLicense + R\"('\nfor details.\n\nUsage: solc [options] [input_file...]\nCompiles the given Solidity input files (or the standard input if \"-\" is\nused as a file name) and outputs the components specified in the options\nat standard output or in files in the output directory, if specified.\nImports are automatically read from the filesystem, but it is also possible to\nremap paths using the context:prefix=path syntax.\nExample:\nsolc --)\" + CompilerOutputs::componentName(&CompilerOutputs::binary) + R\"( -o /tmp/solcoutput dapp-bin=/usr/local/lib/dapp-bin contract.sol\n\nGeneral Information)\").c_str(),\n\t\tpo::options_description::m_default_line_length,\n\t\tpo::options_description::m_default_line_length - 23\n\t);\n\tdesc.add_options()\n\t\t(g_strHelp.c_str(), \"Show help message and exit.\")\n\t\t(g_strVersion.c_str(), \"Show version and exit.\")\n\t\t(g_strLicense.c_str(), \"Show licensing information and exit.\")\n\t;\n\n\tpo::options_description inputOptions(\"Input Options\");\n\tinputOptions.add_options()\n\t\t(\n\t\t\tg_strBasePath.c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"path\"),\n\t\t\t\"Use the given path as the root of the source tree instead of the root of the filesystem.\"\n\t\t)\n\t\t(\n\t\t\tg_strIncludePath.c_str(),\n\t\t\tpo::value<std::vector<std::string>>()->value_name(\"path\"),\n\t\t\t\"Make an additional source directory available to the default import callback. \"\n\t\t\t\"Use this option if you want to import contracts whose location is not fixed in relation \"\n\t\t\t\"to your main source tree, e.g. third-party libraries installed using a package manager. \"\n\t\t\t\"Can be used multiple times. \"\n\t\t\t\"Can only be used if base path has a non-empty value.\"\n\t\t)\n\t\t(\n\t\t\tg_strAllowPaths.c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"path(s)\"),\n\t\t\t\"Allow a given path for imports. A list of paths can be supplied by separating them with a comma.\"\n\t\t)\n\t\t(\n\t\t\tg_strIgnoreMissingFiles.c_str(),\n\t\t\t\"Ignore missing files.\"\n\t\t)\n\t\t(\n\t\t\tg_strNoImportCallback.c_str(),\n\t\t\t\"Disable the default import callback to prevent the compiler from loading any source \"\n\t\t\t\"files not listed on the command line or given in the Standard JSON input.\"\n\t\t)\n\t;\n\tdesc.add(inputOptions);\n\n\tauto const annotateEVMVersion = [](EVMVersion const& _version) {\n\t\treturn _version.name() + (_version.isExperimental() ? \" (experimental)\" : \"\");\n\t};\n\tstatic auto constexpr allEVMVersions = EVMVersion::allVersions();\n\tstd::string annotatedEVMVersions = util::joinHumanReadable(\n\t\tallEVMVersions | ranges::views::transform(annotateEVMVersion),\n\t\t\", \",\n\t\t\", or \"\n\t);\n\n\tpo::options_description outputOptions(\"Output Options\");\n\toutputOptions.add_options()\n\t\t(\n\t\t\t(g_strOutputDir + \",o\").c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"path\"),\n\t\t\t\"If given, creates one file per output component and contract/file at the specified directory.\"\n\t\t)\n\t\t(\n\t\t\tg_strOverwrite.c_str(),\n\t\t\t\"Overwrite existing files (used together with -o).\"\n\t\t)\n\t\t(\n\t\t\tg_strEVMVersion.c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"version\")->default_value(EVMVersion{}.name()),\n\t\t\t(\"Select desired EVM version: \" + annotatedEVMVersions + \".\").c_str()\n\t\t)\n\t;\n\toutputOptions.add_options()\n\t\t(\n\t\t\tg_strEOFVersion.c_str(),\n\t\t\t// Declared as uint64_t, since uint8_t will be parsed as character by boost.\n\t\t\tpo::value<uint64_t>()->value_name(\"version\")->implicit_value(1),\n\t\t\t\"(experimental) Select desired EOF version. Currently the only valid value is 1. \"\n\t\t\t\"If not specified, non-EOF bytecode will be generated.\"\n\t\t)\n\t\t(\n\t\t\tg_strExperimentalViaIR.c_str(),\n\t\t\t\"Deprecated synonym of --via-ir.\"\n\t\t)\n\t\t(\n\t\t\tg_strViaIR.c_str(),\n\t\t\t\"Turn on compilation via IR.\"\n\t\t)\n\t\t(\n\t\t\tg_strViaSSACFG.c_str(),\n\t\t\t\"(experimental) Turn on SSA CFG-based code generation. Implies compilation via IR.\"\n\t\t)\n\t\t(\n\t\t\tg_strRevertStrings.c_str(),\n\t\t\tpo::value<std::string>()->value_name(util::joinHumanReadable(g_revertStringsArgs, \",\")),\n\t\t\t\"Strip revert (and require) reason strings or add additional debugging information.\"\n\t\t)\n\t\t(\n\t\t\tg_strDebugInfo.c_str(),\n\t\t\tpo::value<std::string>()->default_value(util::toString(DebugInfoSelection::Default())),\n\t\t\t(\"Debug info components to be included in the produced EVM assembly and Yul code. \"\n\t\t\t\"Value can be 'all', 'none' or a comma-separated list containing one or more of the \"\n\t\t\t\"following components: \" + util::joinHumanReadable(DebugInfoSelection::AllExceptExperimental().selectedNames()) +\n\t\t\t\", or ethdebug (experimental). \"\n\t\t\t\"Note that 'all' does not include experimental components.\").c_str()\n\t\t)\n\t\t(\n\t\t\tg_strStopAfter.c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"stage\"),\n\t\t\t\"Stop execution after the given compiler stage. Valid options: \\\"parsing\\\".\"\n\t\t)\n\t;\n\tdesc.add(outputOptions);\n\n\tpo::options_description alternativeInputModes(\"Alternative Input Modes\");\n\talternativeInputModes.add_options()\n\t\t(\n\t\t\tg_strStandardJSON.c_str(),\n\t\t\t\"Switch to Standard JSON input / output mode, ignoring all options. \"\n\t\t\t\"It reads from standard input, if no input file was given, otherwise it reads from the provided input file. The result will be written to standard output.\"\n\t\t)\n\t\t(\n\t\t\tg_strLink.c_str(),\n\t\t\t(\"Switch to linker mode, ignoring all options apart from --\" + g_strLibraries + \" \"\n\t\t\t\"and modify binaries in place.\").c_str()\n\t\t)\n\t\t(\n\t\t\tg_strStrictAssembly.c_str(),\n\t\t\t\"Switch to strict assembly mode and assume input is strict assembly.\"\n\t\t)\n\t\t(\n\t\t\tg_strImportAst.c_str(),\n\t\t\t(\"(experimental) Resume compilation from an abstract syntax tree (AST) representing already parsed and analyzed Solidity code. \"\n\t\t\t\"In this mode the compiler expects exactly one input file, containing an AST in compact JSON format, as produced by\"\n\t\t\t\" --\" + CompilerOutputs::componentName(&CompilerOutputs::astCompactJson) + \", --\" +\n\t\t\tCombinedJsonRequests::componentName(&CombinedJsonRequests::ast) + \" ast or the 'ast' output in Standard JSON.\").c_str()\n\t\t)\n\t\t(\n\t\t\tg_strImportEvmAssemblerJson.c_str(),\n\t\t\t(\"(experimental) Resume compilation from EVM assembly. \"\n\t\t\t\"In this mode the compiler expects exactly one input file, containing assembly in JSON format, \"\n\t\t\t\"as produced by --\" + g_strImportEvmAssemblerJson + \"or the 'evm.legacyAssembly' output in Standard JSON. \"\n\t\t\t\"WARNING: --\" + g_strImportEvmAssemblerJson + \" output is already optimized according to settings stored in metadata. \"\n\t\t\t\"Using --\" + g_strOptimize + \" in this mode is allowed, but not necessary under normal circumstances. \"\n\t\t\t\"--\" + g_strOptimize + \" forces the optimizer to run again and can produce bytecode that is not reproducible from metadata.\").c_str()\n\t\t)\n\t\t(\n\t\t\tg_strLSP.c_str(),\n\t\t\t\"(experimental) Switch to the language server mode. \"\n\t\t\t\"Allows the compiler to be used as an analysis backend for your favourite IDE. \"\n\t\t\t\"In this mode no input files are accepted and the compiler expects language server protocol (LSP) messages on standard input.\"\n\t\t)\n\t;\n\tdesc.add(alternativeInputModes);\n\n\tpo::options_description assemblyModeOptions(\"Assembly Mode Options\");\n\tassemblyModeOptions.add_options()\n\t\t(\n\t\t\tg_strMachine.c_str(),\n\t\t\tpo::value<std::string>()->value_name(util::joinHumanReadable(g_machineArgs, \",\")),\n\t\t\t\"Target machine in assembly or Yul mode.\"\n\t\t)\n\t\t(\n\t\t\tg_strYulDialect.c_str(),\n\t\t\tpo::value<std::string>()->value_name(util::joinHumanReadable(g_yulDialectArgs, \",\")),\n\t\t\t\"Input dialect to use in assembly or yul mode.\"\n\t\t)\n\t;\n\tdesc.add(assemblyModeOptions);\n\n\tpo::options_description linkerModeOptions(\"Linker Mode Options\");\n\tlinkerModeOptions.add_options()\n\t\t(\n\t\t\tg_strLibraries.c_str(),\n\t\t\tpo::value<std::vector<std::string>>()->value_name(\"libs\"),\n\t\t\t\"Direct string or file containing library addresses. Syntax: \"\n\t\t\t\"<libraryName>=<address> [, or whitespace] ...\\n\"\n\t\t\t\"Address is interpreted as a hex string prefixed by 0x.\"\n\t\t)\n\t;\n\tdesc.add(linkerModeOptions);\n\n\tpo::options_description outputFormatting(\"Output Formatting\");\n\toutputFormatting.add_options()\n\t\t(\n\t\t\tg_strPrettyJson.c_str(),\n\t\t\t\"Output JSON in pretty format.\"\n\t\t)\n\t\t(\n\t\t\tg_strJsonIndent.c_str(),\n\t\t\tpo::value<uint32_t>()->value_name(\"N\")->default_value(util::JsonFormat::defaultIndent),\n\t\t\t\"Indent pretty-printed JSON with N spaces. Enables '--pretty-json' automatically.\"\n\t\t)\n\t\t(\n\t\t\tg_strColor.c_str(),\n\t\t\t\"Force colored output.\"\n\t\t)\n\t\t(\n\t\t\tg_strNoColor.c_str(),\n\t\t\t\"Explicitly disable colored output, disabling terminal auto-detection.\"\n\t\t)\n\t\t(\n\t\t\tg_strErrorIds.c_str(),\n\t\t\t\"Output error codes.\"\n\t\t)\n\t;\n\tdesc.add(outputFormatting);\n\n\tpo::options_description outputComponents(\"Output Components\");\n\toutputComponents.add_options()\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::astCompactJson).c_str(), \"AST of all source files in a compact JSON format.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::asm_).c_str(), \"EVM assembly of the contracts.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::asmJson).c_str(), \"EVM assembly of the contracts in JSON format.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::opcodes).c_str(), \"Opcodes of the contracts.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::binary).c_str(), \"Binary of the contracts in hex.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::binaryRuntime).c_str(), \"Binary of the runtime part of the contracts in hex.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::abi).c_str(), \"ABI specification of the contracts.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::ir).c_str(), \"Intermediate Representation (IR) of all contracts.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::irAstJson).c_str(), \"(experimental) AST of Intermediate Representation (IR) of all contracts in a compact JSON format.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::irOptimized).c_str(), \"Optimized Intermediate Representation (IR) of all contracts.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::irOptimizedAstJson).c_str(), \"(experimental) AST of optimized Intermediate Representation (IR) of all contracts in a compact JSON format.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::signatureHashes).c_str(), \"Function signature hashes of the contracts.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::natspecUser).c_str(), \"Natspec user documentation of all contracts.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::natspecDev).c_str(), \"Natspec developer documentation of all contracts.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::metadata).c_str(), \"Combined Metadata JSON whose IPFS hash is stored on-chain.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::storageLayout).c_str(), \"Slots, offsets and types of the contract's state variables located in storage.\")\n\t\t(CompilerOutputs::componentName(&CompilerOutputs::transientStorageLayout).c_str(), \"Slots, offsets and types of the contract's state variables located in transient storage.\")\n\t(\n\t\tCompilerOutputs::componentName(&CompilerOutputs::yulCFGJson).c_str(),\n\t\t\"(experimental) Control Flow Graph (CFG) of Yul code in Static Single Assignment (SSA) form in JSON format.\"\n\t)\n\t(\n\t\tCompilerOutputs::componentName(&CompilerOutputs::ethdebug).c_str(),\n\t\t\"(experimental) Debug information in ethdebug format for all contracts (ethdebug/format/program schema). \"\n\t\t\"When enabled, an extra global output containing the ethdebug/format/info/resources schema with information shared by all contracts is automatically enabled as well.\"\n\t)\n\t(\n\t\tCompilerOutputs::componentName(&CompilerOutputs::ethdebugRuntime).c_str(),\n\t\t(\"(experimental) Like --\" + CompilerOutputs::componentName(&CompilerOutputs::ethdebug) + \", but for the runtime part of the contracts.\").c_str()\n\t);\n\tdesc.add(outputComponents);\n\n\tpo::options_description extraOutput(\"Extra Output\");\n\textraOutput.add_options()\n\t\t(\n\t\t\tg_strGas.c_str(),\n\t\t\t\"Print an estimate of the maximal gas usage for each function.\"\n\t\t)\n\t\t(\n\t\t\tg_strCombinedJson.c_str(),\n\t\t\tpo::value<std::string>()->value_name(util::joinHumanReadable(CombinedJsonRequests::componentMap() | ranges::views::keys, \",\")),\n\t\t\t\"Output a single json document containing the specified information.\"\n\t\t)\n\t;\n\tdesc.add(extraOutput);\n\n\tpo::options_description metadataOptions(\"Metadata Options\");\n\tmetadataOptions.add_options()\n\t\t(\n\t\t\tg_strNoCBORMetadata.c_str(),\n\t\t\t\"Do not append CBOR metadata to the end of the bytecode.\"\n\t\t)\n\t\t(\n\t\t\tg_strMetadataHash.c_str(),\n\t\t\tpo::value<std::string>()->value_name(util::joinHumanReadable(g_metadataHashArgs, \",\")),\n\t\t\t\"Choose hash method for the bytecode metadata or disable it.\"\n\t\t)\n\t\t(\n\t\t\tg_strMetadataLiteral.c_str(),\n\t\t\t\"Store referenced sources as literal data in the metadata output.\"\n\t\t)\n\t;\n\tdesc.add(metadataOptions);\n\n\tpo::options_description optimizerOptions(\"Optimizer Options\");\n\toptimizerOptions.add_options()\n\t\t(\n\t\t\tg_strOptimize.c_str(),\n\t\t\t\"Enable optimizer.\"\n\t\t)\n\t\t(\n\t\t\tg_strOptimizeRuns.c_str(),\n\t\t\t// TODO: The type in OptimiserSettings is size_t but we only accept values up to 2**32-1\n\t\t\t// on the CLI and in Standard JSON. We should just switch to uint32_t everywhere.\n\t\t\tpo::value<unsigned>()->value_name(\"n\")->default_value(static_cast<unsigned>(OptimiserSettings{}.expectedExecutionsPerDeployment)),\n\t\t\t\"The number of runs specifies roughly how often each opcode of the deployed code will be executed across the lifetime of the contract. \"\n\t\t\t\"Lower values will optimize more for initial deployment cost, higher values will optimize more for high-frequency usage.\"\n\t\t)\n\t\t(\n\t\t\tg_strOptimizeYul.c_str(),\n\t\t\t(\"Enable Yul optimizer (independently of the EVM assembly optimizer). \"\n\t\t\t\"The general --\" + g_strOptimize + \" option automatically enables this unless --\" +\n\t\t\tg_strNoOptimizeYul + \" is specified.\").c_str()\n\t\t)\n\t\t(\n\t\t\tg_strNoOptimizeYul.c_str(),\n\t\t\t\"Disable Yul optimizer (independently of the EVM assembly optimizer).\"\n\t\t)\n\t\t(\n\t\t\tg_strYulOptimizations.c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"steps\"),\n\t\t\t\"Forces Yul optimizer to use the specified sequence of optimization steps instead of the built-in one.\"\n\t\t)\n\t;\n\tdesc.add(optimizerOptions);\n\n\tpo::options_description smtCheckerOptions(\"Model Checker Options\");\n\tsmtCheckerOptions.add_options()\n\t\t(\n\t\t\tg_strModelCheckerContracts.c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"default,<source>:<contract>\")->default_value(\"default\"),\n\t\t\t\"Select which contracts should be analyzed using the form <source>:<contract>.\"\n\t\t\t\"Multiple pairs <source>:<contract> can be selected at the same time, separated by a comma \"\n\t\t\t\"and no spaces.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerDivModNoSlacks.c_str(),\n\t\t\t\"Encode division and modulo operations with their precise operators\"\n\t\t\t\" instead of multiplication with slack variables.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerEngine.c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"all,bmc,chc,none\")->default_value(\"none\"),\n\t\t\t\"Select model checker engine.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerExtCalls.c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"untrusted,trusted\")->default_value(\"untrusted\"),\n\t\t\t\"Select whether to assume (trusted) that external calls always invoke\"\n\t\t\t\" the code given by the type of the contract, if that code is available.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerInvariants.c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"default,all,contract,reentrancy\")->default_value(\"default\"),\n\t\t\t\"Select whether to report inferred contract inductive invariants.\"\n\t\t\t\" Multiple types of invariants can be selected at the same time, separated by a comma and no spaces.\"\n\t\t\t\" By default no invariants are reported.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerPrintQuery.c_str(),\n\t\t\t\"Print the queries created by the SMTChecker in the SMTLIB2 format.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerShowProvedSafe.c_str(),\n\t\t\t\"Show all targets that were proved safe separately.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerShowUnproved.c_str(),\n\t\t\t\"Show all unproved targets separately.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerShowUnsupported.c_str(),\n\t\t\t\"Show all unsupported language features separately.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerSolvers.c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"cvc5,eld,z3,smtlib2\")->default_value(\"z3\"),\n\t\t\t\"Select model checker solvers.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerTargets.c_str(),\n\t\t\tpo::value<std::string>()->value_name(\"default,all,constantCondition,underflow,overflow,divByZero,balance,assert,popEmptyArray,outOfBounds\")->default_value(\"default\"),\n\t\t\t\"Select model checker verification targets.\"\n\t\t\t\"Multiple targets can be selected at the same time, separated by a comma and no spaces.\"\n\t\t\t\" By default all targets except underflow and overflow are selected.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerTimeout.c_str(),\n\t\t\tpo::value<unsigned>()->value_name(\"ms\"),\n\t\t\t\"Set model checker timeout per query in milliseconds.\"\n\t\t\t\"The default is a deterministic resource limit.\"\n\t\t\t\"A timeout of 0 means no resource/time restrictions for any query.\"\n\t\t)\n\t\t(\n\t\t\tg_strModelCheckerBMCLoopIterations.c_str(),\n\t\t\tpo::value<unsigned>(),\n\t\t\t\"Set loop unrolling depth for BMC engine.\"\n\t\t\t\"Default is 1.\"\n\t\t)\n\t;\n\tdesc.add(smtCheckerOptions);\n\n\tpo::options_description experimentalOptions(\"Experimental options\");\n\texperimentalOptions.add_options()\n\t\t(\n\t\t\tg_strExperimental.c_str(),\n\t\t\t\"Enable experimental mode. \"\n\t\t\t\"This flag does not activate any experimental features on its own - \"\n\t\t\t\"it unlocks the ability to use them through the usual flags and pragmas.\"\n\t\t)\n\t;\n\tdesc.add(experimentalOptions);\n\n\tdesc.add_options()(g_strInputFile.c_str(), po::value<std::vector<std::string>>(), \"input file\");\n\treturn desc;\n}\n\npo::positional_options_description CommandLineParser::positionalOptionsDescription()\n{\n\t// All positional options should be interpreted as input files\n\tpo::positional_options_description filesPositions;\n\tfilesPositions.add(g_strInputFile.c_str(), -1);\n\treturn filesPositions;\n}\n\nvoid CommandLineParser::parseArgs(int _argc, char const* const* _argv)\n{\n\tpo::options_description allOptions = optionsDescription();\n\t// Disabled options: still accepted for parsing so that we can produce a proper error message,\n\t// but hidden from --help output.\n\tallOptions.add_options()\n\t\t(g_strAssemble.c_str(), \"\")\n\t\t(g_strYul.c_str(), \"\")\n\t;\n\tpo::positional_options_description filesPositions = positionalOptionsDescription();\n\n\tm_options = {};\n\tm_args = {};\n\n\t// parse the compiler arguments\n\ttry\n\t{\n\t\tpo::command_line_parser cmdLineParser(_argc, _argv);\n\t\tcmdLineParser.style(po::command_line_style::default_style & (~po::command_line_style::allow_guessing));\n\t\tcmdLineParser.options(allOptions).positional(filesPositions);\n\t\tpo::store(cmdLineParser.run(), m_args);\n\t}\n\tcatch (po::error const& _exception)\n\t{\n\t\tsolThrow(CommandLineValidationError, _exception.what());\n\t}\n\n\tpo::notify(m_args);\n}\n\nvoid CommandLineParser::processArgs()\n{\n\tif (m_args.count(g_strNoColor) > 0)\n\t\tm_options.formatting.coloredOutput = false;\n\telse if (m_args.count(g_strColor) > 0)\n\t\tm_options.formatting.coloredOutput = true;\n\n\tif (m_args.contains(g_strExperimental))\n\t\tm_options.experimental = true;\n\n\tcheckMutuallyExclusive({\n\t\tg_strHelp,\n\t\tg_strLicense,\n\t\tg_strVersion,\n\t\tg_strStandardJSON,\n\t\tg_strLink,\n\t\tg_strStrictAssembly,\n\t\tg_strImportAst,\n\t\tg_strLSP,\n\t\tg_strImportEvmAssemblerJson,\n\t});\n\n\tcheckExperimental(experimentalOptionNames());\n\n\tif (m_args.count(g_strHelp) > 0)\n\t\tm_options.input.mode = InputMode::Help;\n\telse if (m_args.count(g_strLicense) > 0)\n\t\tm_options.input.mode = InputMode::License;\n\telse if (m_args.count(g_strVersion) > 0)\n\t\tm_options.input.mode = InputMode::Version;\n\telse if (m_args.count(g_strStandardJSON) > 0)\n\t\tm_options.input.mode = InputMode::StandardJson;\n\telse if (m_args.count(g_strLSP))\n\t\tm_options.input.mode = InputMode::LanguageServer;\n\telse if (m_args.contains(g_strStrictAssembly))\n\t\tm_options.input.mode = InputMode::Assembler;\n\telse if (m_args.count(g_strLink) > 0)\n\t\tm_options.input.mode = InputMode::Linker;\n\telse if (m_args.count(g_strImportAst) > 0)\n\t\tm_options.input.mode = InputMode::CompilerWithASTImport;\n\telse if (m_args.count(g_strImportEvmAssemblerJson) > 0)\n\t\tm_options.input.mode = InputMode::EVMAssemblerJSON;\n\telse\n\t\tm_options.input.mode = InputMode::Compiler;\n\n\tif (\n\t\tm_options.input.mode == InputMode::Help ||\n\t\tm_options.input.mode == InputMode::License ||\n\t\tm_options.input.mode == InputMode::Version\n\t)\n\t\treturn;\n\n\tif (m_options.experimental && m_options.input.mode == InputMode::StandardJson)\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\t\"Standard JSON input mode is incompatible with the --\" + g_strExperimental + \" flag. \"\n\t\t\t\"Instead, please use the 'settings.experimental' setting in your Standard JSON input file to \"\n\t\t\t\"enable experimental mode.\"\n\t\t);\n\n\tif (m_args.count(g_strYul) > 0)\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\t\"The typed Yul dialect formerly accessible via --yul is no longer supported, \"\n\t\t\t\"please use --strict-assembly instead.\"\n\t\t);\n\n\tif (m_args.contains(g_strAssemble))\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\t\"The assembly input mode formerly accessible via --assemble is no longer supported, \"\n\t\t\t\"please use --strict-assembly instead.\"\n\t\t);\n\n\tstd::map<std::string, std::set<InputMode>> validOptionInputModeCombinations = {\n\t\t// TODO: This should eventually contain all options.\n\t\t{g_strExperimentalViaIR, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strViaIR, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strMetadataLiteral, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strNoCBORMetadata, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strMetadataHash, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerContracts, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerDivModNoSlacks, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerEngine, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerInvariants, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerPrintQuery, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerShowProvedSafe, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerShowUnproved, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerShowUnsupported, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerSolvers, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerTimeout, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerBMCLoopIterations, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerContracts, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strModelCheckerTargets, {InputMode::Compiler, InputMode::CompilerWithASTImport}},\n\t\t{g_strViaSSACFG, {InputMode::Compiler, InputMode::CompilerWithASTImport, InputMode::Assembler}}\n\t};\n\tstd::vector<std::string> invalidOptionsForCurrentInputMode;\n\tfor (auto const& [optionName, inputModes]: validOptionInputModeCombinations)\n\t{\n\t\tif (\n\t\t\tm_args.count(optionName) > 0 &&\n\t\t\tinputModes.count(m_options.input.mode) == 0 &&\n\t\t\t!m_args[optionName].defaulted()\n\t\t)\n\t\t\tinvalidOptionsForCurrentInputMode.push_back(optionName);\n\t}\n\n\tif (!invalidOptionsForCurrentInputMode.empty())\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\t\"The following options are not supported in the current input mode: \" +\n\t\t\tjoinOptionNames(invalidOptionsForCurrentInputMode)\n\t\t);\n\n\tif (m_options.input.mode == InputMode::LanguageServer)\n\t\treturn;\n\n\tcheckMutuallyExclusive({g_strColor, g_strNoColor});\n\tcheckMutuallyExclusive({g_strStopAfter, g_strGas});\n\n\tfor (std::string const& option: CompilerOutputs::componentMap() | ranges::views::keys)\n\t\tif (option != CompilerOutputs::componentName(&CompilerOutputs::astCompactJson))\n\t\t\tcheckMutuallyExclusive({g_strStopAfter, option});\n\n\tif (m_options.input.mode == InputMode::EVMAssemblerJSON)\n\t{\n\t\tstatic std::set<std::string> const supportedByEvmAsmJsonImport{\n\t\t\tg_strImportEvmAssemblerJson,\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::asm_),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::binary),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::binaryRuntime),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::asmJson),\n\t\t\tCompilerOutputs::componentName(&CompilerOutputs::opcodes),\n\t\t\tg_strCombinedJson,\n\t\t\tg_strInputFile,\n\t\t\tg_strJsonIndent,\n\t\t\tg_strOptimize,\n\t\t\tg_strPrettyJson,\n\t\t\t\"srcmap\",\n\t\t\t\"srcmap-runtime\",\n\t\t\tg_strExperimental,\n\t\t};\n\n\t\tfor (auto const& [optionName, optionValue]: m_args)\n\t\t\tif (!optionValue.defaulted() && !supportedByEvmAsmJsonImport.count(optionName))\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\"Option --{} is not supported with --{}.\",\n\t\t\t\t\t\toptionName,\n\t\t\t\t\t\tg_strImportEvmAssemblerJson\n\t\t\t\t\t)\n\t\t\t\t);\n\t}\n\n\tif (\n\t\tm_options.input.mode != InputMode::Compiler &&\n\t\tm_options.input.mode != InputMode::CompilerWithASTImport &&\n\t\tm_options.input.mode != InputMode::EVMAssemblerJSON &&\n\t\tm_options.input.mode != InputMode::Assembler\n\t)\n\t{\n\t\tif (!m_args[g_strOptimizeRuns].defaulted())\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\t\"Option --\" + g_strOptimizeRuns + \" is only valid in compiler and assembler modes.\"\n\t\t\t);\n\n\t\tfor (std::string const& option: {g_strOptimize, g_strNoOptimizeYul, g_strOptimizeYul, g_strYulOptimizations})\n\t\t\tif (m_args.count(option) > 0)\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\t\"Option --\" + option + \" is only valid in compiler and assembler modes.\"\n\t\t\t\t);\n\n\t\tif (!m_args[g_strDebugInfo].defaulted())\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\t\"Option --\" + g_strDebugInfo + \" is only valid in compiler and assembler modes.\"\n\t\t\t);\n\t}\n\n\tm_options.formatting.withErrorIds = m_args.count(g_strErrorIds);\n\n\tif (m_args.count(g_strRevertStrings))\n\t{\n\t\tstd::string revertStringsString = m_args[g_strRevertStrings].as<std::string>();\n\t\tstd::optional<RevertStrings> revertStrings = revertStringsFromString(revertStringsString);\n\t\tif (!revertStrings)\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\t\"Invalid option for --\" + g_strRevertStrings + \": \" + revertStringsString\n\t\t\t);\n\t\tif (*revertStrings == RevertStrings::VerboseDebug)\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\t\"Only \\\"default\\\", \\\"strip\\\" and \\\"debug\\\" are implemented for --\" + g_strRevertStrings + \" for now.\"\n\t\t\t);\n\t\tm_options.output.revertStrings = *revertStrings;\n\t}\n\n\tif (!m_args[g_strDebugInfo].defaulted())\n\t{\n\t\tstd::string optionValue = m_args[g_strDebugInfo].as<std::string>();\n\t\tm_options.output.debugInfoSelection = DebugInfoSelection::fromString(optionValue);\n\t\tif (!m_options.output.debugInfoSelection.has_value())\n\t\t\tsolThrow(CommandLineValidationError, \"Invalid value for --\" + g_strDebugInfo + \" option: \" + optionValue);\n\n\t\tif (!m_options.experimental && m_options.output.debugInfoSelection->ethdebug)\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\tfmt::format(\n\t\t\t\t\t\"Ethdebug annotations are experimental and can only be included in --{} in experimental mode. To enable experimental mode, use the --{} flag.\",\n\t\t\t\t\tg_strDebugInfo,\n\t\t\t\t\tg_strExperimental\n\t\t\t\t)\n\t\t\t);\n\n\t\tif (m_options.output.debugInfoSelection->snippet && !m_options.output.debugInfoSelection->location)\n\t\t\tsolThrow(CommandLineValidationError, \"To use 'snippet' with --\" + g_strDebugInfo + \" you must select also 'location'.\");\n\t}\n\n\tparseCombinedJsonOption();\n\n\tif (m_args.count(g_strOutputDir))\n\t\tm_options.output.dir = m_args.at(g_strOutputDir).as<std::string>();\n\n\tm_options.output.overwriteFiles = (m_args.count(g_strOverwrite) > 0);\n\n\tif (m_args.count(g_strPrettyJson) > 0)\n\t{\n\t\tm_options.formatting.json.format = util::JsonFormat::Pretty;\n\t}\n\tif (!m_args[g_strJsonIndent].defaulted())\n\t{\n\t\tm_options.formatting.json.format = util::JsonFormat::Pretty;\n\t\tm_options.formatting.json.indent = m_args[g_strJsonIndent].as<uint32_t>();\n\t}\n\n\tparseOutputSelection();\n\n\tm_options.compiler.estimateGas = (m_args.count(g_strGas) > 0);\n\n\tif (m_args.count(g_strBasePath))\n\t\tm_options.input.basePath = m_args[g_strBasePath].as<std::string>();\n\n\tif (m_args.count(g_strIncludePath) > 0)\n\t{\n\t\tif (m_options.input.basePath.empty())\n\t\t\tsolThrow(CommandLineValidationError, \"--\" + g_strIncludePath + \" option requires a non-empty base path.\");\n\n\t\tfor (std::string const& includePath: m_args[g_strIncludePath].as<std::vector<std::string>>())\n\t\t{\n\t\t\tif (includePath.empty())\n\t\t\t\tsolThrow(CommandLineValidationError, \"Empty values are not allowed in --\" + g_strIncludePath + \".\");\n\n\t\t\tm_options.input.includePaths.push_back(includePath);\n\t\t}\n\t}\n\n\tcheckMutuallyExclusive({g_strNoImportCallback, g_strAllowPaths});\n\n\tif (m_args.count(g_strNoImportCallback))\n\t\tm_options.input.noImportCallback = true;\n\n\tif (m_args.count(g_strAllowPaths))\n\t{\n\t\tstd::vector<std::string> paths;\n\t\tfor (std::string const& allowedPath: boost::split(paths, m_args[g_strAllowPaths].as<std::string>(), boost::is_any_of(\",\")))\n\t\t\tif (!allowedPath.empty())\n\t\t\t\tm_options.input.allowedDirectories.insert(allowedPath);\n\t}\n\n\tif (m_args.count(g_strStopAfter))\n\t{\n\t\tif (m_args[g_strStopAfter].as<std::string>() != \"parsing\")\n\t\t\tsolThrow(CommandLineValidationError, \"Valid options for --\" + g_strStopAfter + \" are: \\\"parsing\\\".\\n\");\n\t\telse\n\t\t\tm_options.output.stopAfter = CompilerStack::State::Parsed;\n\t}\n\n\tparseInputPathsAndRemappings();\n\n\tif (m_options.input.mode == InputMode::StandardJson)\n\t\treturn;\n\n\tif (m_args.count(g_strLibraries))\n\t\tfor (std::string const& library: m_args[g_strLibraries].as<std::vector<std::string>>())\n\t\t\tparseLibraryOption(library);\n\n\tif (m_options.input.mode == InputMode::Linker)\n\t\treturn;\n\n\tif (m_args.count(g_strEVMVersion))\n\t{\n\t\tstd::string versionOptionStr = m_args[g_strEVMVersion].as<std::string>();\n\t\tstd::optional<langutil::EVMVersion> versionOption = langutil::EVMVersion::fromString(versionOptionStr);\n\t\tif (!versionOption)\n\t\t\tsolThrow(CommandLineValidationError, \"Invalid option for --\" + g_strEVMVersion + \": \" + versionOptionStr);\n\t\tm_options.output.evmVersion = *versionOption;\n\t}\n\n\tif (m_args.count(g_strEOFVersion))\n\t{\n\t\t// Request as uint64_t, since uint8_t will be parsed as character by boost.\n\t\tuint64_t versionOption = m_args[g_strEOFVersion].as<uint64_t>();\n\t\tif (versionOption != 1)\n\t\t\tsolThrow(CommandLineValidationError, \"Invalid option for --\" + g_strEOFVersion + \": \" + std::to_string(versionOption));\n\t\tm_options.output.eofVersion = 1;\n\t}\n\n\tif (m_options.output.eofVersion.has_value() && !m_options.output.evmVersion.supportsEOF())\n\t\tsolThrow(CommandLineValidationError, \"EOF is not supported by EVM versions earlier than \" + EVMVersion::firstWithEOF().name() + \".\");\n\n\tif (m_args.count(g_strNoOptimizeYul) > 0 && m_args.count(g_strOptimizeYul) > 0)\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\t\"Options --\" + g_strOptimizeYul + \" and --\" + g_strNoOptimizeYul + \" cannot be used together.\"\n\t\t);\n\n\tm_options.optimizer.optimizeEvmasm = (m_args.count(g_strOptimize) > 0);\n\tm_options.optimizer.optimizeYul = (\n\t\t(m_args.count(g_strOptimize) > 0 && m_args.count(g_strNoOptimizeYul) == 0) ||\n\t\tm_args.count(g_strOptimizeYul) > 0\n\t);\n\tif (!m_args[g_strOptimizeRuns].defaulted())\n\t\tm_options.optimizer.expectedExecutionsPerDeployment = m_args.at(g_strOptimizeRuns).as<unsigned>();\n\n\tif (m_args.count(g_strYulOptimizations))\n\t{\n\t\tOptimiserSettings optimiserSettings = m_options.optimiserSettings();\n\t\tif (\n\t\t\t!optimiserSettings.runYulOptimiser &&\n\t\t\t!OptimiserSuite::isEmptyOptimizerSequence(m_args[g_strYulOptimizations].as<std::string>())\n\t\t)\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\t\"--\" + g_strYulOptimizations + \" is invalid with a non-empty sequence if Yul optimizer is disabled.\"\n\t\t\t\t\" Note that the empty optimizer sequence is properly denoted by \\\":\\\".\"\n\t\t\t);\n\n\t\ttry\n\t\t{\n\t\t\tyul::OptimiserSuite::validateSequence(m_args[g_strYulOptimizations].as<std::string>());\n\t\t}\n\t\tcatch (yul::OptimizerException const& _exception)\n\t\t{\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\t\"Invalid optimizer step sequence in --\" + g_strYulOptimizations + \": \" + _exception.what()\n\t\t\t);\n\t\t}\n\n\t\tm_options.optimizer.yulSteps = m_args[g_strYulOptimizations].as<std::string>();\n\t}\n\n\tif (m_options.input.mode == InputMode::Assembler)\n\t{\n\t\tstd::vector<std::string> const nonAssemblyModeOptions = {\n\t\t\t// TODO: The list is not complete. Add more.\n\t\t\tg_strOutputDir,\n\t\t\tg_strGas,\n\t\t\tg_strCombinedJson,\n\t\t};\n\t\tif (countEnabledOptions(nonAssemblyModeOptions) >= 1)\n\t\t{\n\t\t\tauto optionEnabled = [&](std::string const& name){ return m_args.count(name) > 0; };\n\t\t\tauto enabledOptions = nonAssemblyModeOptions | ranges::views::filter(optionEnabled) | ranges::to_vector;\n\n\t\t\tstd::string message = \"The following options are invalid in assembly mode: \" + joinOptionNames(enabledOptions) + \".\";\n\t\t\tsolThrow(CommandLineValidationError, message);\n\t\t}\n\n\t\t// switch to assembly mode\n\t\tusing Machine = yul::YulStack::Machine;\n\n\t\tif (m_args.count(g_strMachine))\n\t\t{\n\t\t\tstd::string machine = m_args[g_strMachine].as<std::string>();\n\t\t\tif (machine == g_strEVM)\n\t\t\t\tm_options.assembly.targetMachine = Machine::EVM;\n\t\t\telse\n\t\t\t\tsolThrow(CommandLineValidationError, \"Invalid option for --\" + g_strMachine + \": \" + machine);\n\t\t}\n\t\tif (m_args.contains(g_strYulDialect))\n\t\t{\n\t\t\tauto const& dialect = m_args[g_strYulDialect].as<std::string>();\n\t\t\tif (dialect != g_strEVM)\n\t\t\t\tsolThrow(CommandLineValidationError, \"Invalid option for --\" + g_strYulDialect + \": \" + dialect);\n\t\t}\n\n\t\tm_options.output.viaSSACFG = m_args.contains(g_strViaSSACFG);\n\n\t\tif (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime)\n\t\t{\n\t\t\tif (m_options.output.viaSSACFG)\n\t\t\t\tsolUnimplemented(\"ethdebug is not yet supported with --\" + g_strViaSSACFG + \".\");\n\t\t\tif (m_options.optimiserSettings().runYulOptimiser)\n\t\t\t\tsolUnimplemented(\n\t\t\t\t\t\"Optimization (using --\" + g_strOptimize + \") is not yet supported with ethdebug.\"\n\t\t\t\t);\n\n\t\t\tif (!m_options.output.debugInfoSelection.has_value())\n\t\t\t{\n\t\t\t\tm_options.output.debugInfoSelection = DebugInfoSelection::Default();\n\t\t\t\tm_options.output.debugInfoSelection->enable(\"ethdebug\");\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\telse if (countEnabledOptions({g_strYulDialect, g_strMachine}) >= 1)\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\t\"--\" + g_strYulDialect + \" and --\" + g_strMachine + \" are only valid in assembly mode.\"\n\t\t);\n\n\tif (m_args.count(g_strMetadataHash))\n\t{\n\t\tstd::string hashStr = m_args[g_strMetadataHash].as<std::string>();\n\t\tif (hashStr == g_strIPFS)\n\t\t\tm_options.metadata.hash = CompilerStack::MetadataHash::IPFS;\n\t\telse if (hashStr == g_strSwarm)\n\t\t\tm_options.metadata.hash = CompilerStack::MetadataHash::Bzzr1;\n\t\telse if (hashStr == g_strNone)\n\t\t\tm_options.metadata.hash = CompilerStack::MetadataHash::None;\n\t\telse\n\t\t\tsolThrow(CommandLineValidationError, \"Invalid option for --\" + g_strMetadataHash + \": \" + hashStr);\n\t}\n\n\tif (m_args.count(g_strNoCBORMetadata))\n\t{\n\t\tif (\n\t\t\tm_args.count(g_strMetadataHash) &&\n\t\t\tm_options.metadata.hash != CompilerStack::MetadataHash::None\n\t\t)\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\t\"Cannot specify a metadata hashing method when --\" +\n\t\t\t\tg_strNoCBORMetadata + \" is set.\"\n\t\t\t);\n\n\t\tm_options.metadata.format = CompilerStack::MetadataFormat::NoMetadata;\n\t}\n\n\tif (m_args.count(g_strModelCheckerContracts))\n\t{\n\t\tstd::string contractsStr = m_args[g_strModelCheckerContracts].as<std::string>();\n\t\tstd::optional<ModelCheckerContracts> contracts = ModelCheckerContracts::fromString(contractsStr);\n\t\tif (!contracts)\n\t\t\tsolThrow(CommandLineValidationError, \"Invalid option for --\" + g_strModelCheckerContracts + \": \" + contractsStr);\n\t\tm_options.modelChecker.settings.contracts = std::move(*contracts);\n\t}\n\n\tif (m_args.count(g_strModelCheckerDivModNoSlacks))\n\t\tm_options.modelChecker.settings.divModNoSlacks = true;\n\n\tif (m_args.count(g_strModelCheckerEngine))\n\t{\n\t\tstd::string engineStr = m_args[g_strModelCheckerEngine].as<std::string>();\n\t\tstd::optional<ModelCheckerEngine> engine = ModelCheckerEngine::fromString(engineStr);\n\t\tif (!engine)\n\t\t\tsolThrow(CommandLineValidationError, \"Invalid option for --\" + g_strModelCheckerEngine + \": \" + engineStr);\n\t\tm_options.modelChecker.settings.engine = *engine;\n\t}\n\n\tif (m_args.count(g_strModelCheckerExtCalls))\n\t{\n\t\tstd::string mode = m_args[g_strModelCheckerExtCalls].as<std::string>();\n\t\tstd::optional<ModelCheckerExtCalls> extCallsMode = ModelCheckerExtCalls::fromString(mode);\n\t\tif (!extCallsMode)\n\t\t\tsolThrow(CommandLineValidationError, \"Invalid option for --\" + g_strModelCheckerExtCalls + \": \" + mode);\n\t\tm_options.modelChecker.settings.externalCalls = *extCallsMode;\n\t}\n\n\tif (m_args.count(g_strModelCheckerInvariants))\n\t{\n\t\tstd::string invsStr = m_args[g_strModelCheckerInvariants].as<std::string>();\n\t\tstd::optional<ModelCheckerInvariants> invs = ModelCheckerInvariants::fromString(invsStr);\n\t\tif (!invs)\n\t\t\tsolThrow(CommandLineValidationError, \"Invalid option for --\" + g_strModelCheckerInvariants + \": \" + invsStr);\n\t\tm_options.modelChecker.settings.invariants = *invs;\n\t}\n\n\tif (m_args.count(g_strModelCheckerShowProvedSafe))\n\t\tm_options.modelChecker.settings.showProvedSafe = true;\n\n\tif (m_args.count(g_strModelCheckerShowUnproved))\n\t\tm_options.modelChecker.settings.showUnproved = true;\n\n\tif (m_args.count(g_strModelCheckerShowUnsupported))\n\t\tm_options.modelChecker.settings.showUnsupported = true;\n\n\tif (m_args.count(g_strModelCheckerSolvers))\n\t{\n\t\tstd::string solversStr = m_args[g_strModelCheckerSolvers].as<std::string>();\n\t\tstd::optional<smtutil::SMTSolverChoice> solvers = smtutil::SMTSolverChoice::fromString(solversStr);\n\t\tif (!solvers)\n\t\t\tsolThrow(CommandLineValidationError, \"Invalid option for --\" + g_strModelCheckerSolvers + \": \" + solversStr);\n\t\tm_options.modelChecker.settings.solvers = *solvers;\n\t}\n\n\tif (m_args.count(g_strModelCheckerPrintQuery))\n\t\tm_options.modelChecker.settings.printQuery = true;\n\n\tif (m_args.count(g_strModelCheckerTargets))\n\t{\n\t\tstd::string targetsStr = m_args[g_strModelCheckerTargets].as<std::string>();\n\t\tstd::optional<ModelCheckerTargets> targets = ModelCheckerTargets::fromString(targetsStr);\n\t\tif (!targets)\n\t\t\tsolThrow(CommandLineValidationError, \"Invalid option for --\" + g_strModelCheckerTargets + \": \" + targetsStr);\n\t\tm_options.modelChecker.settings.targets = *targets;\n\t}\n\n\tif (m_args.count(g_strModelCheckerTimeout))\n\t\tm_options.modelChecker.settings.timeout = m_args[g_strModelCheckerTimeout].as<unsigned>();\n\n\tif (m_args.count(g_strModelCheckerBMCLoopIterations))\n\t{\n\t\tif (!m_options.modelChecker.settings.engine.bmc)\n\t\t\tsolThrow(CommandLineValidationError, \"BMC loop unrolling requires the BMC engine to be enabled\");\n\t\tm_options.modelChecker.settings.bmcLoopIterations = m_args[g_strModelCheckerBMCLoopIterations].as<unsigned>();\n\t}\n\n\tm_options.metadata.literalSources = (m_args.count(g_strMetadataLiteral) > 0);\n\tm_options.modelChecker.initialize =\n\t\tm_args.count(g_strModelCheckerContracts) ||\n\t\tm_args.count(g_strModelCheckerDivModNoSlacks) ||\n\t\tm_args.count(g_strModelCheckerEngine) ||\n\t\tm_args.count(g_strModelCheckerExtCalls) ||\n\t\tm_args.count(g_strModelCheckerInvariants) ||\n\t\tm_args.count(g_strModelCheckerShowProvedSafe) ||\n\t\tm_args.count(g_strModelCheckerShowUnproved) ||\n\t\tm_args.count(g_strModelCheckerShowUnsupported) ||\n\t\tm_args.count(g_strModelCheckerSolvers) ||\n\t\tm_args.count(g_strModelCheckerTargets) ||\n\t\tm_args.count(g_strModelCheckerTimeout);\n\tm_options.output.viaIR = (m_args.count(g_strExperimentalViaIR) > 0 || m_args.count(g_strViaIR) > 0);\n\tm_options.output.viaSSACFG = m_args.contains(g_strViaSSACFG);\n\tif (m_options.output.viaSSACFG)\n\t\tm_options.output.viaIR = true;\n\n\tsolAssert(\n\t\tm_options.input.mode == InputMode::Compiler ||\n\t\tm_options.input.mode == InputMode::CompilerWithASTImport ||\n\t\tm_options.input.mode == InputMode::EVMAssemblerJSON\n\t);\n\n\tbool incompatibleEthdebugOutputs =\n\t\tm_options.compiler.outputs.asmJson || m_options.compiler.outputs.irAstJson || m_options.compiler.outputs.irOptimizedAstJson ||\n\t\tm_options.optimizer.optimizeYul || m_options.optimizer.optimizeEvmasm;\n\n\tbool incompatibleEthdebugInputs = m_options.input.mode != InputMode::Compiler;\n\n\tstatic std::string enableEthdebugMessage =\n\t\t\"--\" + CompilerOutputs::componentName(&CompilerOutputs::ethdebug) + \" / --\" + CompilerOutputs::componentName(&CompilerOutputs::ethdebugRuntime);\n\n\tstatic std::string enableIrMessage = \"--\" + CompilerOutputs::componentName(&CompilerOutputs::ir) + \" / --\" + CompilerOutputs::componentName(&CompilerOutputs::irOptimized);\n\n\tif (m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime)\n\t{\n\t\tif (!m_options.output.viaIR)\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\tenableEthdebugMessage + \" output can only be selected, if --via-ir was specified.\"\n\t\t\t);\n\n\t\tif (m_options.output.viaSSACFG)\n\t\t\tsolUnimplemented(\"ethdebug is not yet supported with --\" + g_strViaSSACFG + \".\");\n\n\t\tif (incompatibleEthdebugOutputs)\n\t\t\tsolThrow(\n\t\t\t\tCommandLineValidationError,\n\t\t\t\tenableEthdebugMessage + \" output can only be used with \" + enableIrMessage + \". Optimization (using --\" + g_strOptimize + \") is not yet supported with ethdebug.\"\n\t\t\t);\n\n\t\tif (!m_options.output.debugInfoSelection.has_value())\n\t\t{\n\t\t\tm_options.output.debugInfoSelection = DebugInfoSelection::Default();\n\t\t\tm_options.output.debugInfoSelection->enable(\"ethdebug\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (!m_options.output.debugInfoSelection->ethdebug)\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\t\"--debug-info must contain ethdebug, when compiling with \" + enableEthdebugMessage + \".\"\n\t\t\t\t);\n\t\t}\n\t}\n\n\tif (\n\t\tm_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug &&\n\t\t(!(m_options.compiler.outputs.ir || m_options.compiler.outputs.ethdebug || m_options.compiler.outputs.ethdebugRuntime) || incompatibleEthdebugOutputs)\n\t)\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\t\"--debug-info ethdebug can only be used with \" + enableIrMessage + \" and/or \" + enableEthdebugMessage + \". Optimization (using --\" + g_strOptimize + \") is not yet supported with ethdebug.\"\n\t\t);\n\n\tif (m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug && incompatibleEthdebugInputs)\n\t\tsolThrow(\n\t\t\tCommandLineValidationError,\n\t\t\t\"Invalid input mode for --debug-info ethdebug / --ethdebug / --ethdebug-runtime.\"\n\t\t);\n}\n\nvoid CommandLineParser::parseCombinedJsonOption()\n{\n\tif (!m_args.count(g_strCombinedJson))\n\t\treturn;\n\n\tstd::set<std::string> requests;\n\tfor (std::string const& item: boost::split(requests, m_args[g_strCombinedJson].as<std::string>(), boost::is_any_of(\",\")))\n\t\tif (CombinedJsonRequests::componentMap().count(item) == 0)\n\t\t\tsolThrow(CommandLineValidationError, \"Invalid option to --\" + g_strCombinedJson + \": \" + item);\n\n\tm_options.compiler.combinedJsonRequests = CombinedJsonRequests{};\n\tfor (auto&& [componentName, component]: CombinedJsonRequests::componentMap())\n\t\tm_options.compiler.combinedJsonRequests.value().*component = (requests.count(componentName) > 0);\n\n\tif (m_options.input.mode == InputMode::EVMAssemblerJSON && m_options.compiler.combinedJsonRequests.has_value())\n\t{\n\t\tstatic bool CombinedJsonRequests::* invalidOptions[]{\n\t\t\t&CombinedJsonRequests::abi,\n\t\t\t&CombinedJsonRequests::ast,\n\t\t\t&CombinedJsonRequests::funDebug,\n\t\t\t&CombinedJsonRequests::funDebugRuntime,\n\t\t\t&CombinedJsonRequests::generatedSources,\n\t\t\t&CombinedJsonRequests::generatedSourcesRuntime,\n\t\t\t&CombinedJsonRequests::metadata,\n\t\t\t&CombinedJsonRequests::natspecDev,\n\t\t\t&CombinedJsonRequests::natspecUser,\n\t\t\t&CombinedJsonRequests::signatureHashes,\n\t\t\t&CombinedJsonRequests::storageLayout,\n\t\t\t&CombinedJsonRequests::transientStorageLayout\n\t\t};\n\n\t\tfor (auto const invalidOption: invalidOptions)\n\t\t\tif (m_options.compiler.combinedJsonRequests.value().*invalidOption)\n\t\t\t\tsolThrow(\n\t\t\t\t\tCommandLineValidationError,\n\t\t\t\t\tfmt::format(\n\t\t\t\t\t\t\"The --{} {} output is not available in EVM assembly import mode.\",\n\t\t\t\t\t\tg_strCombinedJson,\n\t\t\t\t\t\tCombinedJsonRequests::componentName(invalidOption)\n\t\t\t\t\t)\n\t\t\t\t);\n\t}\n}\n\nsize_t CommandLineParser::countEnabledOptions(std::vector<std::string> const& _optionNames) const\n{\n\tsize_t count = 0;\n\tfor (std::string const& _option: _optionNames)\n\t\tcount += m_args.count(_option);\n\n\treturn count;\n}\n\nstd::string CommandLineParser::joinOptionNames(std::vector<std::string> const& _optionNames, std::string _separator)\n{\n\treturn util::joinHumanReadable(\n\t\t_optionNames | ranges::views::transform([](std::string const& _option){ return \"--\" + _option; }),\n\t\t_separator\n\t);\n}\n\n} // namespace solidity::frontend\n"
  },
  {
    "path": "solc/CommandLineParser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Validates and parses command-line options into an internal representation.\n */\n#pragma once\n\n#include <libsolidity/interface/CompilerStack.h>\n#include <libsolidity/interface/DebugSettings.h>\n#include <libsolidity/interface/FileReader.h>\n#include <libsolidity/interface/ImportRemapper.h>\n\n#include <libyul/YulStack.h>\n\n#include <liblangutil/DebugInfoSelection.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <libsolutil/JSON.h>\n\n#include <boost/program_options.hpp>\n#include <boost/filesystem/path.hpp>\n\n#include <map>\n#include <memory>\n#include <optional>\n#include <ostream>\n#include <set>\n#include <string>\n#include <vector>\n\nnamespace solidity::frontend\n{\n\nenum class InputMode\n{\n\tHelp,\n\tLicense,\n\tVersion,\n\tCompiler,\n\tCompilerWithASTImport,\n\tStandardJson,\n\tLinker,\n\tAssembler,\n\tLanguageServer,\n\tEVMAssemblerJSON\n};\n\nstruct CompilerOutputs\n{\n\tbool operator!=(CompilerOutputs const& _other) const noexcept = default;\n\tbool operator==(CompilerOutputs const& _other) const noexcept = default;\n\tfriend std::ostream& operator<<(std::ostream& _out, CompilerOutputs const& _requests);\n\n\tstatic std::string const& componentName(bool CompilerOutputs::* _component);\n\tstatic auto const& componentMap()\n\t{\n\t\tstatic std::map<std::string, bool CompilerOutputs::*> const components = {\n\t\t\t{\"ast-compact-json\", &CompilerOutputs::astCompactJson},\n\t\t\t{\"asm\", &CompilerOutputs::asm_},\n\t\t\t{\"asm-json\", &CompilerOutputs::asmJson},\n\t\t\t{\"opcodes\", &CompilerOutputs::opcodes},\n\t\t\t{\"bin\", &CompilerOutputs::binary},\n\t\t\t{\"bin-runtime\", &CompilerOutputs::binaryRuntime},\n\t\t\t{\"abi\", &CompilerOutputs::abi},\n\t\t\t{\"ir\", &CompilerOutputs::ir},\n\t\t\t{\"ir-ast-json\", &CompilerOutputs::irAstJson},\n\t\t\t{\"ir-optimized\", &CompilerOutputs::irOptimized},\n\t\t\t{\"ir-optimized-ast-json\", &CompilerOutputs::irOptimizedAstJson},\n\t\t\t{\"hashes\", &CompilerOutputs::signatureHashes},\n\t\t\t{\"userdoc\", &CompilerOutputs::natspecUser},\n\t\t\t{\"devdoc\", &CompilerOutputs::natspecDev},\n\t\t\t{\"metadata\", &CompilerOutputs::metadata},\n\t\t\t{\"storage-layout\", &CompilerOutputs::storageLayout},\n\t\t\t{\"transient-storage-layout\", &CompilerOutputs::transientStorageLayout},\n\t\t\t{\"yul-cfg-json\", &CompilerOutputs::yulCFGJson},\n\t\t\t{\"ethdebug\", &CompilerOutputs::ethdebug},\n\t\t\t{\"ethdebug-runtime\", &CompilerOutputs::ethdebugRuntime},\n\t\t};\n\t\treturn components;\n\t}\n\n\tbool astCompactJson = false;\n\tbool asm_ = false;\n\tbool asmJson = false;\n\tbool opcodes = false;\n\tbool binary = false;\n\tbool binaryRuntime = false;\n\tbool abi = false;\n\tbool ir = false;\n\tbool irAstJson = false;\n\tbool yulCFGJson = false;\n\tbool irOptimized = false;\n\tbool irOptimizedAstJson = false;\n\tbool signatureHashes = false;\n\tbool natspecUser = false;\n\tbool natspecDev = false;\n\tbool metadata = false;\n\tbool storageLayout = false;\n\tbool transientStorageLayout = false;\n\tbool ethdebug = false;\n\tbool ethdebugRuntime = false;\n};\n\nstruct CombinedJsonRequests\n{\n\tbool operator!=(CombinedJsonRequests const& _other) const noexcept = default;\n\tbool operator==(CombinedJsonRequests const& _other) const noexcept = default;\n\tfriend std::ostream& operator<<(std::ostream& _out, CombinedJsonRequests const& _requests);\n\n\tstatic std::string const& componentName(bool CombinedJsonRequests::* _component);\n\tstatic auto const& componentMap()\n\t{\n\t\tstatic std::map<std::string, bool CombinedJsonRequests::*> const components = {\n\t\t\t{\"abi\", &CombinedJsonRequests::abi},\n\t\t\t{\"metadata\", &CombinedJsonRequests::metadata},\n\t\t\t{\"bin\", &CombinedJsonRequests::binary},\n\t\t\t{\"bin-runtime\", &CombinedJsonRequests::binaryRuntime},\n\t\t\t{\"opcodes\", &CombinedJsonRequests::opcodes},\n\t\t\t{\"asm\", &CombinedJsonRequests::asm_},\n\t\t\t{\"storage-layout\", &CombinedJsonRequests::storageLayout},\n\t\t\t{\"transient-storage-layout\", &CombinedJsonRequests::transientStorageLayout},\n\t\t\t{\"generated-sources\", &CombinedJsonRequests::generatedSources},\n\t\t\t{\"generated-sources-runtime\", &CombinedJsonRequests::generatedSourcesRuntime},\n\t\t\t{\"srcmap\", &CombinedJsonRequests::srcMap},\n\t\t\t{\"srcmap-runtime\", &CombinedJsonRequests::srcMapRuntime},\n\t\t\t{\"function-debug\", &CombinedJsonRequests::funDebug},\n\t\t\t{\"function-debug-runtime\", &CombinedJsonRequests::funDebugRuntime},\n\t\t\t{\"hashes\", &CombinedJsonRequests::signatureHashes},\n\t\t\t{\"devdoc\", &CombinedJsonRequests::natspecDev},\n\t\t\t{\"userdoc\", &CombinedJsonRequests::natspecUser},\n\t\t\t{\"ast\", &CombinedJsonRequests::ast},\n\t\t};\n\t\treturn components;\n\t}\n\n\tbool abi = false;\n\tbool metadata = false;\n\tbool binary = false;\n\tbool binaryRuntime = false;\n\tbool opcodes = false;\n\tbool asm_ = false;\n\tbool storageLayout = false;\n\tbool transientStorageLayout = false;\n\tbool generatedSources = false;\n\tbool generatedSourcesRuntime = false;\n\tbool srcMap = false;\n\tbool srcMapRuntime = false;\n\tbool funDebug = false;\n\tbool funDebugRuntime = false;\n\tbool signatureHashes = false;\n\tbool natspecDev = false;\n\tbool natspecUser = false;\n\tbool ast = false;\n};\n\nstruct CommandLineOptions\n{\n\tbool operator==(CommandLineOptions const& _other) const noexcept = default;\n\tbool operator!=(CommandLineOptions const& _other) const noexcept = default;\n\n\tOptimiserSettings optimiserSettings() const;\n\n\tstruct Input\n\t{\n\t\tbool operator==(Input const&) const noexcept = default;\n\t\tbool operator!=(Input const&) const noexcept = default;\n\n\t\tInputMode mode = InputMode::Compiler;\n\t\tstd::set<boost::filesystem::path> paths;\n\t\tstd::vector<ImportRemapper::Remapping> remappings;\n\t\tbool addStdin = false;\n\t\tboost::filesystem::path basePath = \"\";\n\t\tstd::vector<boost::filesystem::path> includePaths;\n\t\tFileReader::FileSystemPathSet allowedDirectories;\n\t\tbool ignoreMissingFiles = false;\n\t\tbool noImportCallback = false;\n\t} input;\n\n\tstruct Output\n\t{\n\t\tbool operator==(Output const&) const noexcept = default;\n\t\tbool operator!=(Output const&) const noexcept = default;\n\n\t\tboost::filesystem::path dir;\n\t\tbool overwriteFiles = false;\n\t\tlangutil::EVMVersion evmVersion;\n\t\tbool viaIR = false;\n\t\tbool viaSSACFG = false;\n\t\tRevertStrings revertStrings = RevertStrings::Default;\n\t\tstd::optional<langutil::DebugInfoSelection> debugInfoSelection;\n\t\tCompilerStack::State stopAfter = CompilerStack::State::CompilationSuccessful;\n\t\tstd::optional<uint8_t> eofVersion;\n\t} output;\n\n\tstruct Assembly\n\t{\n\t\tbool operator==(Assembly const&) const noexcept = default;\n\t\tbool operator!=(Assembly const&) const noexcept = default;\n\n\t\tyul::YulStack::Machine targetMachine = yul::YulStack::Machine::EVM;\n\t} assembly;\n\n\tstruct Linker\n\t{\n\t\tbool operator==(Linker const&) const noexcept = default;\n\t\tbool operator!=(Linker const&) const noexcept = default;\n\n\t\tstd::map<std::string, util::h160> libraries; // library name -> address\n\t} linker;\n\n\tstruct Formatting\n\t{\n\t\tbool operator==(Formatting const&) const noexcept = default;\n\t\tbool operator!=(Formatting const&) const noexcept = default;\n\n\t\tutil::JsonFormat json;\n\t\tstd::optional<bool> coloredOutput;\n\t\tbool withErrorIds = false;\n\t} formatting;\n\n\tstruct Compiler\n\t{\n\t\tbool operator==(Compiler const&) const noexcept = default;\n\t\tbool operator!=(Compiler const&) const noexcept = default;\n\n\t\tCompilerOutputs outputs;\n\t\tbool estimateGas = false;\n\t\tstd::optional<CombinedJsonRequests> combinedJsonRequests;\n\t} compiler;\n\n\tstruct Metadata\n\t{\n\t\tbool operator==(Metadata const&) const noexcept = default;\n\t\tbool operator!=(Metadata const&) const noexcept = default;\n\n\t\tCompilerStack::MetadataFormat format = CompilerStack::defaultMetadataFormat();\n\t\tCompilerStack::MetadataHash hash = CompilerStack::MetadataHash::IPFS;\n\t\tbool literalSources = false;\n\t} metadata;\n\n\tstruct Optimizer\n\t{\n\t\tbool operator==(Optimizer const&) const noexcept = default;\n\t\tbool operator!=(Optimizer const&) const noexcept = default;\n\n\t\tbool optimizeEvmasm = false;\n\t\tbool optimizeYul = false;\n\t\tstd::optional<unsigned> expectedExecutionsPerDeployment;\n\t\tstd::optional<std::string> yulSteps;\n\t} optimizer;\n\n\tstruct ModelChecker\n\t{\n\t\tbool operator==(ModelChecker const&) const noexcept = default;\n\t\tbool operator!=(ModelChecker const&) const noexcept = default;\n\n\t\tbool initialize = false;\n\t\tModelCheckerSettings settings;\n\t} modelChecker;\n\n\tbool experimental = false;\n};\n\n/// Parses the command-line arguments and produces a filled-out CommandLineOptions structure.\n/// Validates provided values and reports errors by throwing @p CommandLineValidationErrors.\nclass CommandLineParser\n{\npublic:\n\t/// Parses the command-line arguments and fills out the internal CommandLineOptions structure.\n\t/// @throws CommandLineValidationError if the arguments cannot be properly parsed or are invalid.\n\t/// When an exception is thrown, the @p CommandLineOptions may be only partially filled out.\n\tvoid parse(int _argc, char const* const* _argv);\n\n\tCommandLineOptions const& options() const { return m_options; }\n\n\t/// yields CLI option names (without leading \"--\") that require --experimental.\n\tstatic std::vector<std::string> const& experimentalOptionNames();\n\n\tstatic void printHelp(std::ostream& _out) { _out << optionsDescription(); }\n\nprivate:\n\t/// @returns a specification of all named command-line options accepted by the compiler.\n\t/// The object can be used to parse command-line arguments or to generate the help screen.\n\tstatic boost::program_options::options_description optionsDescription();\n\n\t/// @returns a specification of all positional command-line arguments accepted by the compiler.\n\t/// The object can be used to parse command-line arguments or to generate the help screen.\n\tstatic boost::program_options::positional_options_description positionalOptionsDescription();\n\n\t/// Uses boost::program_options to parse the command-line arguments and leaves the result in @a m_args.\n\t/// Also handles the arguments that result in information being printed followed by immediate exit.\n\t/// @returns false if parsing fails due to syntactical errors or the arguments not matching the description.\n\tvoid parseArgs(int _argc, char const* const* _argv);\n\n\t/// Validates parsed arguments stored in @a m_args and fills out the internal CommandLineOptions\n\t/// structure.\n\t/// @throws CommandLineValidationError in case of validation errors.\n\tvoid processArgs();\n\n\t/// Parses the value supplied to --combined-json.\n\t/// @throws CommandLineValidationError in case of validation errors.\n\tvoid parseCombinedJsonOption();\n\n\t/// Parses the names of the input files, remappings. Does not check if the files actually exist.\n\t/// @throws CommandLineValidationError in case of validation errors.\n\tvoid parseInputPathsAndRemappings();\n\n\t/// Tries to read from the file @a _input or interprets @a _input literally if that fails.\n\t/// It then tries to parse the contents and appends to @a m_options.libraries.\n\t/// @throws CommandLineValidationError in case of validation errors.\n\tvoid parseLibraryOption(std::string const& _input);\n\n\tvoid parseOutputSelection();\n\n\t/// Returns a list of enabled options from @_optionList\n\tstd::vector<std::string> enabledOptions(std::vector<std::string> const& _optionList) const;\n\n\tvoid checkMutuallyExclusive(std::vector<std::string> const& _optionNames);\n\tvoid checkExperimental(std::vector<std::string> const& _optionNames) const;\n\tsize_t countEnabledOptions(std::vector<std::string> const& _optionNames) const;\n\tstatic std::string joinOptionNames(std::vector<std::string> const& _optionNames, std::string _separator = \", \");\n\n\tCommandLineOptions m_options;\n\n\t/// Map of command-line arguments produced by boost::program_options.\n\t/// Serves as input for filling out m_options.\n\tboost::program_options::variables_map m_args;\n};\n\n} // namespace solidity::frontend\n"
  },
  {
    "path": "solc/Exceptions.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Exceptions used by the command-line interface.\n */\n\n#pragma once\n\n#include <liblangutil/Exceptions.h>\n\nnamespace solidity::frontend\n{\n\nstruct CommandLineError: virtual util::Exception {};\nstruct CommandLineExecutionError: virtual CommandLineError {};\nstruct CommandLineValidationError: virtual CommandLineError {};\nstruct CommandLineOutputError: virtual CommandLineError {};\n\n}\n"
  },
  {
    "path": "solc/main.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Solidity commandline compiler.\n */\n\n#include <solc/CommandLineInterface.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <boost/exception/all.hpp>\n\n#include <iostream>\n\nusing namespace solidity;\n\n\nint main(int argc, char** argv)\n{\n\ttry\n\t{\n\t\tsolidity::frontend::CommandLineInterface cli(std::cin, std::cout, std::cerr);\n\t\treturn cli.run(argc, argv) ? 0 : 1;\n\t}\n\tcatch (smtutil::SMTLogicError const& _exception)\n\t{\n\t\tstd::cerr << \"SMT logic error:\" << std::endl;\n\t\tstd::cerr << boost::diagnostic_information(_exception);\n\t\treturn 2;\n\t}\n\tcatch (langutil::InternalCompilerError const& _exception)\n\t{\n\t\tstd::cerr << \"Internal compiler error:\" << std::endl;\n\t\tstd::cerr << boost::diagnostic_information(_exception);\n\t\treturn 2;\n\t}\n\tcatch (yul::YulAssertion const& _exception)\n\t{\n\t\tstd::cerr << \"Yul assertion failed:\" << std::endl;\n\t\tstd::cerr << boost::diagnostic_information(_exception);\n\t\treturn 2;\n\t}\n\tcatch (...)\n\t{\n\t\tstd::cerr << \"Uncaught exception:\" << std::endl;\n\t\tstd::cerr << boost::current_exception_diagnostic_information() << std::endl;\n\t\treturn 2;\n\t}\n}\n"
  },
  {
    "path": "test/.solhint.json",
    "content": "{\n    \"extends\": \"solhint:default\",\n    \"plugins\": [],\n    \"rules\": {\n        \"compiler-fixed\": \"off\",\n        \"no-inline-assembly\": \"off\"\n    }\n}\n"
  },
  {
    "path": "test/.solhintignore",
    "content": "*contributing_rst*\n"
  },
  {
    "path": "test/CMakeLists.txt",
    "content": "set(sources\n    soltest.cpp\n    Common.cpp\n    Common.h\n    CommonSyntaxTest.cpp\n    CommonSyntaxTest.h\n    EVMHost.cpp\n    EVMHost.h\n    ExecutionFramework.cpp\n    ExecutionFramework.h\n    FilesystemUtils.cpp\n    FilesystemUtils.h\n    InteractiveTests.h\n    Metadata.cpp\n    Metadata.h\n    TestCase.cpp\n    TestCase.h\n    TestCaseReader.cpp\n    TestCaseReader.h\n)\ndetect_stray_source_files(\"${sources}\" \".\")\n\nset(contracts_sources\n    contracts/AuctionRegistrar.cpp\n    contracts/ContractInterface.h\n    contracts/Wallet.cpp\n)\ndetect_stray_source_files(\"${contracts_sources}\" \"contracts/\")\n\nset(libsolutil_sources\n    libsolutil/Checksum.cpp\n    libsolutil/CommonData.cpp\n    libsolutil/CommonIO.cpp\n    libsolutil/DisjointSet.cpp\n    libsolutil/DominatorFinderTest.cpp\n    libsolutil/FixedHash.cpp\n    libsolutil/FunctionSelector.cpp\n    libsolutil/IpfsHash.cpp\n    libsolutil/IterateReplacing.cpp\n    libsolutil/JSON.cpp\n    libsolutil/Keccak256.cpp\n    libsolutil/LazyInit.cpp\n    libsolutil/LEB128.cpp\n    libsolutil/StringUtils.cpp\n    libsolutil/SwarmHash.cpp\n    libsolutil/TemporaryDirectoryTest.cpp\n    libsolutil/UTF8.cpp\n    libsolutil/Whiskers.cpp\n)\ndetect_stray_source_files(\"${libsolutil_sources}\" \"libsolutil/\")\n\nset(libevmasm_sources\n    libevmasm/Assembler.cpp\n    libevmasm/EVMAssemblyTest.cpp\n    libevmasm/EVMAssemblyTest.h\n    libevmasm/Optimiser.cpp\n    libevmasm/PlainAssemblyParser.cpp\n    libevmasm/PlainAssemblyParser.h\n)\ndetect_stray_source_files(\"${libevmasm_sources}\" \"libevmasm/\")\n\nset(liblangutil_sources\n    liblangutil/CharStream.cpp\n    liblangutil/Scanner.cpp\n    liblangutil/SourceLocation.cpp\n)\ndetect_stray_source_files(\"${liblangutil_sources}\" \"liblangutil/\")\n\nset(libsolidity_sources\n    libsolidity/ABIDecoderTests.cpp\n    libsolidity/ABIEncoderTests.cpp\n    libsolidity/ABIJsonTest.cpp\n    libsolidity/ABIJsonTest.h\n    libsolidity/ABITestsCommon.h\n    libsolidity/AnalysisFramework.cpp\n    libsolidity/AnalysisFramework.h\n    libsolidity/Assembly.cpp\n    libsolidity/ASTJSONTest.cpp\n    libsolidity/ASTJSONTest.h\n    libsolidity/ErrorCheck.cpp\n    libsolidity/ErrorCheck.h\n    libsolidity/FunctionDependencyGraphTest.cpp\n    libsolidity/FunctionDependencyGraphTest.h\n    libsolidity/GasCosts.cpp\n    libsolidity/GasMeter.cpp\n    libsolidity/GasTest.cpp\n    libsolidity/GasTest.h\n    libsolidity/Imports.cpp\n    libsolidity/InlineAssembly.cpp\n    libsolidity/LibSolc.cpp\n    libsolidity/Metadata.cpp\n    libsolidity/MemoryGuardTest.cpp\n    libsolidity/MemoryGuardTest.h\n    libsolidity/NatspecJSONTest.cpp\n    libsolidity/NatspecJSONTest.h\n    libsolidity/OptimizedIRCachingTest.cpp\n    libsolidity/OptimizedIRCachingTest.h\n    libsolidity/SemanticTest.cpp\n    libsolidity/SemanticTest.h\n    libsolidity/SemVerMatcher.cpp\n    libsolidity/SMTCheckerTest.cpp\n    libsolidity/SMTCheckerTest.h\n    libsolidity/SolidityCompiler.cpp\n    libsolidity/SolidityEndToEndTest.cpp\n    libsolidity/SolidityExecutionFramework.cpp\n    libsolidity/SolidityExecutionFramework.h\n    libsolidity/SolidityExpressionCompiler.cpp\n    libsolidity/SolidityNameAndTypeResolution.cpp\n    libsolidity/SolidityOptimizer.cpp\n    libsolidity/SolidityParser.cpp\n    libsolidity/SolidityTypes.cpp\n    libsolidity/StandardCompiler.cpp\n    libsolidity/SyntaxTest.cpp\n    libsolidity/SyntaxTest.h\n    libsolidity/ViewPureChecker.cpp\n    libsolidity/analysis/FunctionCallGraph.cpp\n    libsolidity/interface/FileReader.cpp\n    libsolidity/ASTPropertyTest.h\n    libsolidity/ASTPropertyTest.cpp\n)\ndetect_stray_source_files(\"${libsolidity_sources}\" \"libsolidity/\")\n\nset(libsolidity_util_sources\n    libsolidity/util/BytesUtils.cpp\n    libsolidity/util/BytesUtilsTests.cpp\n    libsolidity/util/BytesUtils.h\n    libsolidity/util/Common.cpp\n    libsolidity/util/Common.h\n    libsolidity/util/ContractABIUtils.cpp\n    libsolidity/util/ContractABIUtils.h\n    libsolidity/util/SoltestErrors.h\n    libsolidity/util/SoltestTypes.h\n    libsolidity/util/TestFileParser.cpp\n    libsolidity/util/TestFileParser.h\n    libsolidity/util/TestFileParserTests.cpp\n    libsolidity/util/TestFunctionCall.cpp\n    libsolidity/util/TestFunctionCall.h\n    libsolidity/util/TestFunctionCallTests.cpp\n)\ndetect_stray_source_files(\"${libsolidity_util_sources}\" \"libsolidity/util/\")\n\nset(libyul_sources\n    libyul/Common.cpp\n    libyul/Common.h\n    libyul/CompilabilityChecker.cpp\n    libyul/ControlFlowGraphTest.cpp\n    libyul/ControlFlowGraphTest.h\n    libyul/ControlFlowSideEffectsTest.cpp\n    libyul/ControlFlowSideEffectsTest.h\n    libyul/EVMCodeTransformTest.cpp\n    libyul/EVMCodeTransformTest.h\n    libyul/EVMDialectCompatibility.cpp\n    libyul/FunctionSideEffects.cpp\n    libyul/FunctionSideEffects.h\n    libyul/Inliner.cpp\n    libyul/KnowledgeBaseTest.cpp\n    libyul/Metrics.cpp\n    libyul/ObjectCompilerTest.cpp\n    libyul/ObjectCompilerTest.h\n    libyul/ObjectParser.cpp\n    libyul/Parser.cpp\n    libyul/SSAControlFlowGraphTest.cpp\n    libyul/SSAControlFlowGraphTest.h\n    libyul/StackLayoutGeneratorTest.cpp\n    libyul/StackLayoutGeneratorTest.h\n    libyul/StackShufflingTest.cpp\n    libyul/StackShufflingTest.h\n    libyul/SyntaxTest.h\n    libyul/SyntaxTest.cpp\n    libyul/YulInterpreterTest.cpp\n    libyul/YulInterpreterTest.h\n    libyul/YulOptimizerTest.cpp\n    libyul/YulOptimizerTest.h\n    libyul/YulOptimizerTestCommon.cpp\n    libyul/YulOptimizerTestCommon.h\n    libyul/ssa/StackLayoutGeneratorTest.cpp\n    libyul/ssa/StackLayoutGeneratorTest.h\n    libyul/ssa/StackShufflerTest.cpp\n    libyul/ssa/StackShufflerTest.h\n)\ndetect_stray_source_files(\"${libyul_sources}\" \"libyul/\")\n\nset(solcli_sources\n    solc/Common.cpp\n    solc/Common.h\n    solc/CommandLineInterface.cpp\n    solc/CommandLineInterfaceAllowPaths.cpp\n    solc/CommandLineParser.cpp\n)\ndetect_stray_source_files(\"${solcli_sources}\" \"solc/\")\n\nset(yul_phaser_sources\n    yulPhaser/TestHelpers.h\n    yulPhaser/TestHelpers.cpp\n    yulPhaser/TestHelpersTest.cpp\n    yulPhaser/Common.cpp\n    yulPhaser/Chromosome.cpp\n    yulPhaser/FitnessMetrics.cpp\n    yulPhaser/AlgorithmRunner.cpp\n    yulPhaser/GeneticAlgorithms.cpp\n    yulPhaser/Mutations.cpp\n    yulPhaser/PairSelections.cpp\n    yulPhaser/Phaser.cpp\n    yulPhaser/Population.cpp\n    yulPhaser/Program.cpp\n    yulPhaser/ProgramCache.cpp\n    yulPhaser/Selections.cpp\n    yulPhaser/SimulationRNG.cpp\n)\ndetect_stray_source_files(\"${yul_phaser_sources}\" \"yulPhaser/\")\n\nadd_executable(soltest ${sources}\n    ${contracts_sources}\n    ${libsolutil_sources}\n    ${liblangutil_sources}\n    ${libevmasm_sources}\n    ${libyul_sources}\n    ${libsolidity_sources}\n    ${libsolidity_util_sources}\n    ${solcli_sources}\n    ${yul_phaser_sources}\n)\ntarget_link_libraries(soltest PRIVATE solcli libsolc yul solidity smtutil solutil phaser Boost::boost yulInterpreter evmasm Boost::filesystem Boost::program_options Boost::unit_test_framework evmc)\n\n\n# Special compilation flag for Visual Studio (version 2019 at least affected)\n# in order to compile SolidityEndToEndTest.cpp, which is quite huge.\n# We can remove this flag once we've extracted the tests.\n# TODO: Remove this option as soon as we have reduced the SLoC's in SolidityEndToEndTest.cpp\nif (MSVC)\n    target_compile_options(soltest PUBLIC \"/bigobj\")\nendif()\n\nif (NOT Boost_USE_STATIC_LIBS)\n    target_compile_definitions(soltest PUBLIC -DBOOST_TEST_DYN_LINK)\nendif()\n\nadd_subdirectory(tools)\nadd_subdirectory(evmc)\n"
  },
  {
    "path": "test/Common.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/Common.h>\n\n#include <test/EVMHost.h>\n#include <test/libsolidity/util/SoltestErrors.h>\n\n#include <libyul/backends/evm/EVMDialect.h>\n\n#include <libsolutil/Assertions.h>\n#include <libsolutil/StringUtils.h>\n\n#include <boost/algorithm/string.hpp>\n#include <boost/filesystem.hpp>\n#include <boost/program_options.hpp>\n\n#include <range/v3/all.hpp>\n\n#include <iostream>\n#include <stdexcept>\n\nnamespace fs = boost::filesystem;\nnamespace po = boost::program_options;\n\nnamespace solidity::test\n{\n\nnamespace\n{\n\n/// If non-empty returns the value of the env. variable ETH_TEST_PATH, otherwise\n/// it tries to find a path that contains the directories \"libsolidity/syntaxTests\"\n/// and returns it if found.\n/// The routine searches in the current directory, and inside the \"test\" directory\n/// starting from the current directory and up to three levels up.\n/// @returns the path of the first match or an empty path if not found.\nboost::filesystem::path testPath()\n{\n\tif (auto path = getenv(\"ETH_TEST_PATH\"))\n\t\treturn path;\n\n\tauto const searchPath =\n\t{\n\t\tfs::current_path() / \"..\" / \"..\" / \"..\" / \"test\",\n\t\tfs::current_path() / \"..\" / \"..\" / \"test\",\n\t\tfs::current_path() / \"..\" / \"test\",\n\t\tfs::current_path() / \"test\",\n\t\tfs::current_path()\n\t};\n\tfor (auto const& basePath: searchPath)\n\t{\n\t\tfs::path syntaxTestPath = basePath / \"libsolidity\" / \"syntaxTests\";\n\t\tif (fs::exists(syntaxTestPath) && fs::is_directory(syntaxTestPath))\n\t\t\treturn basePath;\n\t}\n\treturn {};\n}\n\nstd::optional<fs::path> findInDefaultPath(std::string const& lib_name)\n{\n\tauto const searchPath =\n\t{\n\t\tfs::current_path() / \"deps\",\n\t\tfs::current_path() / \"deps\" / \"lib\",\n\t\tfs::current_path() / \"..\" / \"deps\",\n\t\tfs::current_path() / \"..\" / \"deps\" / \"lib\",\n\t\tfs::current_path() / \"..\" / \"..\" / \"deps\",\n\t\tfs::current_path() / \"..\" / \"..\" / \"deps\" / \"lib\",\n\t\tfs::current_path(),\n#ifdef __APPLE__\n\t\tfs::current_path().root_path() / fs::path(\"usr\") / \"local\" / \"lib\",\n#endif\n\t};\n\tfor (auto const& basePath: searchPath)\n\t{\n\t\tfs::path p = basePath / lib_name;\n\t\tif (fs::exists(p))\n\t\t\treturn p;\n\t}\n\treturn std::nullopt;\n}\n\n}\n\nCommonOptions::CommonOptions(std::string _caption):\n\toptions(_caption,\n\t\tpo::options_description::m_default_line_length,\n\t\tpo::options_description::m_default_line_length - 23\n\t)\n{\n\n}\n\nvoid CommonOptions::addOptions()\n{\n\toptions.add_options()\n\t\t(\"evm-version\", po::value(&evmVersionString), \"which EVM version to use\")\n\t\t// \"eof-version\" is declared as uint64_t, since uint8_t will be parsed as character by boost.\n\t\t(\"eof-version\", po::value<uint64_t>()->implicit_value(1u), \"which EOF version to use\")\n\t\t(\"testpath\", po::value<fs::path>(&this->testPath)->default_value(solidity::test::testPath()), \"path to test files\")\n\t\t(\"vm\", po::value<std::vector<fs::path>>(&vmPaths), \"path to evmc library, can be supplied multiple times.\")\n\t\t(\"batches\", po::value<size_t>(&this->batches)->default_value(1), \"set number of batches to split the tests into\")\n\t\t(\"selected-batch\", po::value<size_t>(&this->selectedBatch)->default_value(0), \"zero-based number of batch to execute\")\n\t\t(\"no-semantic-tests\", po::bool_switch(&disableSemanticTests)->default_value(disableSemanticTests), \"disable semantic tests\")\n\t\t(\"no-smt\", po::bool_switch(&disableSMT)->default_value(disableSMT), \"disable SMT checker\")\n\t\t(\"optimize\", po::bool_switch(&optimize)->default_value(optimize), \"enables optimization\")\n\t\t(\"enforce-gas-cost\", po::value<bool>(&enforceGasTest)->default_value(enforceGasTest)->implicit_value(true), \"Enforce checking gas cost in semantic tests.\")\n\t\t(\"enforce-gas-cost-min-value\", po::value(&enforceGasTestMinValue)->default_value(enforceGasTestMinValue), \"Threshold value to enforce adding gas checks to a test.\")\n\t\t(\"abiencoderv1\", po::bool_switch(&useABIEncoderV1)->default_value(useABIEncoderV1), \"enables abi encoder v1\")\n\t\t(\"show-messages\", po::bool_switch(&showMessages)->default_value(showMessages), \"enables message output\")\n\t\t(\"show-metadata\", po::bool_switch(&showMetadata)->default_value(showMetadata), \"enables metadata output\");\n}\n\nvoid CommonOptions::validate() const\n{\n\tsolRequire(\n\t\t!testPath.empty(),\n\t\tConfigException,\n\t\t\"No test path specified. The --testpath argument must not be empty when given.\"\n\t);\n\tsolRequire(\n\t\tfs::exists(testPath),\n\t\tConfigException,\n\t\t\"Invalid test path specified.\"\n\t);\n\tsolRequire(\n\t\tbatches > 0,\n\t\tConfigException,\n\t\t\"Batches needs to be at least 1.\"\n\t);\n\tsolRequire(\n\t\tselectedBatch < batches,\n\t\tConfigException,\n\t\t\"Selected batch has to be less than number of batches.\"\n\t);\n\n\tif (!enforceGasTest)\n\t\tstd::cout << std::endl << \"WARNING :: Gas cost expectations are not being enforced\" << std::endl << std::endl;\n\telse if (evmVersion() != langutil::EVMVersion{} || useABIEncoderV1)\n\t{\n\t\tstd::cout << std::endl << \"WARNING :: Enforcing gas cost expectations with non-standard settings:\" << std::endl;\n\t\tif (evmVersion() != langutil::EVMVersion{})\n\t\t\tstd::cout << \"- EVM version: \" << evmVersion().name() << \" (default: \" << langutil::EVMVersion{}.name() << \")\" << std::endl;\n\t\tif (useABIEncoderV1)\n\t\t\tstd::cout << \"- ABI coder: v1 (default: v2)\" << std::endl;\n\t\tstd::cout << std::endl << \"DO NOT COMMIT THE UPDATED EXPECTATIONS.\" << std::endl << std::endl;\n\t}\n\n\tsolRequire(\n\t\t!eofVersion().has_value() || evmVersion().supportsEOF(),\n\t\tConfigException,\n\t\t\"EOF is not supported by EVM versions earlier than \" + langutil::EVMVersion::firstWithEOF().name() + \".\"\n\t);\n}\n\nbool CommonOptions::parse(int argc, char const* const* argv)\n{\n\tpo::variables_map arguments;\n\taddOptions();\n\n\ttry\n\t{\n\t\tpo::command_line_parser cmdLineParser(argc, argv);\n\t\tcmdLineParser.options(options);\n\t\tauto parsedOptions = cmdLineParser.run();\n\t\tpo::store(parsedOptions, arguments);\n\t\tpo::notify(arguments);\n\t\tif (arguments.count(\"eof-version\"))\n\t\t{\n\t\t\t// Request as uint64_t, since uint8_t will be parsed as character by boost.\n\t\t\tuint64_t eofVersion = arguments[\"eof-version\"].as<uint64_t>();\n\t\t\tif (eofVersion != 1)\n\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid EOF version: \" + std::to_string(eofVersion)));\n\t\t\tm_eofVersion = 1;\n\t\t}\n\n\t\tfor (auto const& parsedOption: parsedOptions.options)\n\t\t\tif (parsedOption.position_key >= 0)\n\t\t\t{\n\t\t\t\tif (\n\t\t\t\t\tparsedOption.original_tokens.empty() ||\n\t\t\t\t\t(parsedOption.original_tokens.size() == 1 && parsedOption.original_tokens.front().empty())\n\t\t\t\t)\n\t\t\t\t\tcontinue; // ignore empty options\n\t\t\t\tstd::stringstream errorMessage;\n\t\t\t\terrorMessage << \"Unrecognized option: \";\n\t\t\t\tfor (auto const& token: parsedOption.original_tokens)\n\t\t\t\t\terrorMessage << token;\n\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(errorMessage.str()));\n\t\t\t}\n\t}\n\tcatch (po::error const& exception)\n\t{\n\t\tsolThrow(ConfigException, exception.what());\n\t}\n\n\tif (vmPaths.empty())\n\t{\n\t\tif (auto envPath = getenv(\"ETH_EVMONE\"))\n\t\t\tvmPaths.emplace_back(envPath);\n\t\telse if (auto repoPath = findInDefaultPath(evmoneFilename))\n\t\t\tvmPaths.emplace_back(*repoPath);\n\t\telse\n\t\t\tvmPaths.emplace_back(evmoneFilename);\n\t}\n\n\treturn true;\n}\n\nstd::string CommonOptions::toString(std::vector<std::string> const& _selectedOptions) const\n{\n\tif (_selectedOptions.empty())\n\t\treturn \"\";\n\n\tauto boolToString = [](bool _value) -> std::string { return _value ? \"true\" : \"false\"; };\n\t// Using std::map to avoid if-else/switch-case block\n\tstd::map<std::string, std::string> optionValueMap = {\n\t\t{\"evmVersion\", evmVersion().name()},\n\t\t{\"optimize\", boolToString(optimize)},\n\t\t{\"useABIEncoderV1\", boolToString(useABIEncoderV1)},\n\t\t{\"batch\", std::to_string(selectedBatch + 1) + \"/\" + std::to_string(batches)},\n\t\t{\"enforceGasTest\", boolToString(enforceGasTest)},\n\t\t{\"enforceGasTestMinValue\", enforceGasTestMinValue.str()},\n\t\t{\"disableSemanticTests\", boolToString(disableSemanticTests)},\n\t\t{\"disableSMT\", boolToString(disableSMT)},\n\t\t{\"showMessages\", boolToString(showMessages)},\n\t\t{\"showMetadata\", boolToString(showMetadata)}\n\t};\n\n\tsoltestAssert(ranges::all_of(_selectedOptions, [&optionValueMap](std::string const& _option) { return optionValueMap.count(_option) > 0; }));\n\n\tstd::vector<std::string> optionsWithValues = _selectedOptions |\n\t\tranges::views::transform([&optionValueMap](std::string const& _option) { return _option + \"=\" + optionValueMap.at(_option); }) |\n\t\tranges::to<std::vector>();\n\n\treturn solidity::util::joinHumanReadable(optionsWithValues);\n}\n\nvoid CommonOptions::printSelectedOptions(std::ostream& _stream, std::string const& _linePrefix, std::vector<std::string> const& _selectedOptions) const\n{\n\t_stream << _linePrefix << \"Run Settings: \" << toString(_selectedOptions) << std::endl;\n}\n\nlangutil::EVMVersion CommonOptions::evmVersion() const\n{\n\tif (!evmVersionString.empty())\n\t{\n\t\tauto version = langutil::EVMVersion::fromString(evmVersionString);\n\t\tif (!version)\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid EVM version: \" + evmVersionString));\n\t\treturn *version;\n\t}\n\telse\n\t\treturn langutil::EVMVersion();\n}\n\nyul::EVMDialect const& CommonOptions::evmDialect() const\n{\n\treturn yul::EVMDialect::strictAssemblyForEVMObjects(evmVersion(), eofVersion());\n}\n\n\nCommonOptions const& CommonOptions::get()\n{\n\tif (!m_singleton)\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Options not yet constructed!\"));\n\n\treturn *m_singleton;\n}\n\nvoid CommonOptions::setSingleton(std::unique_ptr<CommonOptions const>&& _instance)\n{\n\tm_singleton = std::move(_instance);\n}\n\nstd::unique_ptr<CommonOptions const> CommonOptions::m_singleton = nullptr;\n\nbool isValidSemanticTestPath(boost::filesystem::path const& _testPath)\n{\n\tbool insideSemanticTests = false;\n\tfs::path testPathPrefix;\n\tfor (auto const& element: _testPath)\n\t{\n\t\ttestPathPrefix /= element;\n\t\tif (boost::ends_with(canonical(testPathPrefix).generic_string(), \"/test/libsolidity/semanticTests\"))\n\t\t\tinsideSemanticTests = true;\n\t\tif (insideSemanticTests && boost::starts_with(element.string(), \"_\"))\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\nboost::unit_test::precondition::predicate_t nonEOF()\n{\n\treturn [](boost::unit_test::test_unit_id) {\n\t\treturn !solidity::test::CommonOptions::get().eofVersion().has_value();\n\t};\n}\n\nboost::unit_test::precondition::predicate_t onEOF()\n{\n\treturn [](boost::unit_test::test_unit_id) {\n\t\treturn solidity::test::CommonOptions::get().eofVersion().has_value();\n\t};\n}\n\nboost::unit_test::precondition::predicate_t minEVMVersionCheck(langutil::EVMVersion _minEVMVersion)\n{\n\treturn [_minEVMVersion](boost::unit_test::test_unit_id) {\n\t\treturn test::CommonOptions::get().evmVersion() >= _minEVMVersion;\n\t};\n}\n\nbool loadVMs(CommonOptions const& _options)\n{\n\tif (_options.disableSemanticTests)\n\t\treturn true;\n\n\tbool evmSupported = solidity::test::EVMHost::checkVmPaths(_options.vmPaths);\n\tif (!_options.disableSemanticTests && !evmSupported)\n\t{\n\t\tstd::cerr << \"Unable to find \" << solidity::test::evmoneFilename;\n\t\tstd::cerr << \". Please disable semantics tests with --no-semantic-tests or provide a path using --vm <path>.\" << std::endl;\n\t\tstd::cerr << \"You can download it at\" << std::endl;\n\t\tstd::cerr << solidity::test::evmoneDownloadLink << std::endl;\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n}\n"
  },
  {
    "path": "test/Common.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/Exceptions.h>\n#include <liblangutil/EVMVersion.h>\n#include <liblangutil/Exceptions.h>\n#include <libsolutil/Numeric.h>\n\n#include <test/evmc/evmc.h>\n\n#include <boost/filesystem/path.hpp>\n#include <boost/program_options.hpp>\n#include <boost/test/unit_test.hpp>\n\nnamespace solidity::yul\n{\nclass EVMDialect;\n}\n\nnamespace solidity::test\n{\n\n#ifdef _WIN32\nstatic constexpr auto evmoneFilename = \"evmone.dll\";\nstatic constexpr auto evmoneDownloadLink = \"https://github.com/ipsilon/evmone/releases/download/v0.16.0/evmone-0.16.0-windows-amd64.zip\";\n#elif defined(__APPLE__)\nstatic constexpr auto evmoneFilename = \"libevmone.dylib\";\nstatic constexpr auto evmoneDownloadLink = \"https://github.com/ipsilon/evmone/releases/download/v0.16.0/evmone-0.16.0-darwin-arm64.tar.gz\";\n#else\nstatic constexpr auto evmoneFilename = \"libevmone.so\";\nstatic constexpr auto evmoneDownloadLink = \"https://github.com/ipsilon/evmone/releases/download/v0.16.0/evmone-0.16.0-linux-x86_64.tar.gz\";\n#endif\n\nstruct ConfigException: public util::Exception {};\n\nstruct CommonOptions\n{\n\t/// Noncopyable.\n\tCommonOptions(CommonOptions const&) = delete;\n\tCommonOptions& operator=(CommonOptions const&) = delete;\n\n\tstd::vector<boost::filesystem::path> vmPaths;\n\tboost::filesystem::path testPath;\n\tbool optimize = false;\n\tbool enforceGasTest = false;\n\tu256 enforceGasTestMinValue = 100000;\n\tbool disableSemanticTests = false;\n\tbool disableSMT = false;\n\tbool useABIEncoderV1 = false;\n\tbool showMessages = false;\n\tbool showMetadata = false;\n\tsize_t batches = 1;\n\tsize_t selectedBatch = 0;\n\n\tlangutil::EVMVersion evmVersion() const;\n\tstd::optional<uint8_t> eofVersion() const { return m_eofVersion; }\n\tyul::EVMDialect const& evmDialect() const;\n\n\tvirtual void addOptions();\n\t// @returns true if the program should continue, false if it should exit immediately without\n\t// reporting an error.\n\t// Throws ConfigException or std::runtime_error if parsing fails.\n\tvirtual bool parse(int argc, char const* const* argv);\n\t// Throws a ConfigException on error\n\tvirtual void validate() const;\n\n\t/// @returns string with a key=value list of the options separated by comma\n\t/// Ex.: \"evmVersion=london, optimize=true, useABIEncoderV1=false\"\n\tvirtual std::string toString(std::vector<std::string> const& _selectedOptions) const;\n\t/// Helper to print the value of settings used\n\tvirtual void printSelectedOptions(std::ostream& _stream, std::string const& _linePrefix, std::vector<std::string> const& _selectedOptions) const;\n\n\tstatic CommonOptions const& get();\n\tstatic void setSingleton(std::unique_ptr<CommonOptions const>&& _instance);\n\n\tCommonOptions(std::string caption = \"\");\n\tvirtual ~CommonOptions() {}\n\nprotected:\n\tboost::program_options::options_description options;\n\nprivate:\n\tstd::string evmVersionString;\n\tstd::optional<uint8_t> m_eofVersion;\n\tstatic std::unique_ptr<CommonOptions const> m_singleton;\n};\n\n/// @return true if it is ok to treat the file located under the specified path as a semantic test.\n/// I.e. if the test is located in the semantic test directory and is not excluded due to being a part of external sources.\n/// Note: @p _testPath can be relative but must include at least the `/test/libsolidity/semanticTests/` part\nbool isValidSemanticTestPath(boost::filesystem::path const& _testPath);\n\n/// Helper that can be used to skip tests when the EVM version selected on the command line\n/// is older than @p _minEVMVersion.\n/// @return A predicate (function) that can be passed into @a boost::unit_test::precondition().\nboost::unit_test::precondition::predicate_t minEVMVersionCheck(langutil::EVMVersion _minEVMVersion);\n\n/// Helper that can be used to skip tests when the EOF is not supported by the test case.\n/// @return A predicate (function) that can be passed into @a boost::unit_test::precondition().\nboost::unit_test::precondition::predicate_t nonEOF();\n\n/// Helper that can be used to skip tests when the legacy bytecode is not supported by the test case.\n/// @return A predicate (function) that can be passed into @a boost::unit_test::precondition().\nboost::unit_test::precondition::predicate_t onEOF();\n\nbool loadVMs(CommonOptions const& _options);\n\n/**\n * Component to help with splitting up all tests into batches.\n */\nclass Batcher\n{\npublic:\n\tBatcher(size_t _offset, size_t _batches):\n\t\tm_offset(_offset),\n\t\tm_batches(_batches)\n\t{\n\t\tsolAssert(m_batches > 0 && m_offset < m_batches);\n\t}\n\tBatcher(Batcher const&) = delete;\n\tBatcher& operator=(Batcher const&) = delete;\n\n\tbool checkAndAdvance() { return (m_counter++) % m_batches == m_offset; }\n\nprivate:\n\tsize_t const m_offset;\n\tsize_t const m_batches;\n\tsize_t m_counter = 0;\n};\n\n}\n"
  },
  {
    "path": "test/CommonSyntaxTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/CommonSyntaxTest.h>\n#include <test/Common.h>\n#include <test/TestCase.h>\n\n#include <liblangutil/SourceReferenceFormatter.h>\n\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/StringUtils.h>\n\n#include <boost/algorithm/string.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n#include <boost/test/unit_test.hpp>\n#include <boost/throw_exception.hpp>\n\n#include <fstream>\n#include <memory>\n#include <stdexcept>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::util::formatting;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\nusing namespace solidity::test;\nusing namespace boost::unit_test;\nnamespace fs = boost::filesystem;\n\nnamespace\n{\n\nint parseUnsignedInteger(std::string::iterator& _it, std::string::iterator _end)\n{\n\tif (_it == _end || !util::isDigit(*_it))\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid test expectation. Source location expected.\"));\n\tint result = 0;\n\twhile (_it != _end && util::isDigit(*_it))\n\t{\n\t\tresult *= 10;\n\t\tresult += *_it - '0';\n\t\t++_it;\n\t}\n\treturn result;\n}\n\n}\n\nCommonSyntaxTest::CommonSyntaxTest(std::string const& _filename, langutil::EVMVersion _evmVersion):\n\tEVMVersionRestrictedTestCase(_filename),\n\tm_sources(m_reader.sources()),\n\tm_expectations(parseExpectations(m_reader.stream())),\n\tm_evmVersion(_evmVersion)\n{\n}\n\nTestCase::TestResult CommonSyntaxTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted)\n{\n\tparseCustomExpectations(m_reader.stream());\n\tparseAndAnalyze();\n\n\treturn conclude(_stream, _linePrefix, _formatted);\n}\n\nTestCase::TestResult CommonSyntaxTest::conclude(std::ostream& _stream, std::string const& _linePrefix, bool _formatted)\n{\n\tif (expectationsMatch())\n\t\treturn TestResult::Success;\n\n\tprintExpectationAndError(_stream, _linePrefix, _formatted);\n\treturn TestResult::Failure;\n}\n\nvoid CommonSyntaxTest::printExpectationAndError(std::ostream& _stream, std::string const& _linePrefix, bool _formatted)\n{\n\tstd::string nextIndentLevel = _linePrefix + \"  \";\n\tutil::AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << \"Expected result:\" << std::endl;\n\tprintExpectedResult(_stream, nextIndentLevel, _formatted);\n\tutil::AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << \"Obtained result:\" << std::endl;\n\tprintObtainedResult(_stream, nextIndentLevel, _formatted);\n}\n\nvoid CommonSyntaxTest::printSource(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const\n{\n\tif (m_sources.sources.empty())\n\t\treturn;\n\n\tassert(m_sources.externalSources.empty());\n\tbool outputSourceNames = (m_sources.sources.size() != 1 || !m_sources.sources.begin()->first.empty());\n\n\tfor (auto const& [name, source]: m_sources.sources)\n\t\tif (_formatted)\n\t\t{\n\t\t\tif (source.empty())\n\t\t\t\tcontinue;\n\n\t\t\tif (outputSourceNames)\n\t\t\t\t_stream << _linePrefix << util::formatting::CYAN << \"==== Source: \" << name << \" ====\" << util::formatting::RESET << std::endl;\n\t\t\tstd::vector<char const*> sourceFormatting(source.length(), util::formatting::RESET);\n\t\t\tfor (auto const& error: m_errorList)\n\t\t\t\tif (error.sourceName == name && error.locationStart >= 0 && error.locationEnd >= 0)\n\t\t\t\t{\n\t\t\t\t\tassert(static_cast<size_t>(error.locationStart) <= source.length());\n\t\t\t\t\tassert(static_cast<size_t>(error.locationEnd) <= source.length());\n\t\t\t\t\tfor (int i = error.locationStart; i < error.locationEnd; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tchar const*& cellFormat = sourceFormatting[static_cast<size_t>(i)];\n\t\t\t\t\t\tchar const* infoBgColor = SourceReferenceFormatter::errorHighlightColor(Error::Severity::Info);\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(error.type != Error::Type::Warning && error.type != Error::Type::Info) ||\n\t\t\t\t\t\t\t(error.type == Error::Type::Warning && (cellFormat == RESET || cellFormat == infoBgColor)) ||\n\t\t\t\t\t\t\t(error.type == Error::Type::Info && cellFormat == RESET)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\tcellFormat = SourceReferenceFormatter::errorHighlightColor(Error::errorSeverity(error.type));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t_stream << _linePrefix << sourceFormatting.front() << source.front();\n\t\t\tfor (size_t i = 1; i < source.length(); i++)\n\t\t\t{\n\t\t\t\tif (sourceFormatting[i] != sourceFormatting[i - 1])\n\t\t\t\t\t_stream << sourceFormatting[i];\n\t\t\t\tif (source[i] != '\\n')\n\t\t\t\t\t_stream << source[i];\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t_stream << util::formatting::RESET << std::endl;\n\t\t\t\t\tif (i + 1 < source.length())\n\t\t\t\t\t\t_stream << _linePrefix << sourceFormatting[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\t_stream << util::formatting::RESET;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (outputSourceNames)\n\t\t\t\tprintPrefixed(_stream, \"==== Source: \" + name + \" ====\", _linePrefix);\n\t\t\tprintPrefixed(_stream, source, _linePrefix);\n\t\t}\n}\n\nvoid CommonSyntaxTest::parseCustomExpectations(std::istream& _stream)\n{\n\tstd::string remainingExpectations = boost::trim_copy(readUntilEnd(_stream));\n\tsoltestAssert(\n\t\tremainingExpectations.empty(),\n\t\t\"Found custom expectations not supported by the test case:\\n\" + remainingExpectations\n\t);\n}\n\nbool CommonSyntaxTest::expectationsMatch()\n{\n\treturn m_expectations == m_errorList;\n}\n\nvoid CommonSyntaxTest::printExpectedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const\n{\n\tprintErrorList(_stream, m_expectations, _linePrefix, _formatted);\n}\n\nvoid CommonSyntaxTest::printObtainedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const\n{\n\tprintErrorList(_stream, m_errorList, _linePrefix, _formatted);\n}\n\nvoid CommonSyntaxTest::printErrorList(\n\tstd::ostream& _stream,\n\tstd::vector<SyntaxTestError> const& _errorList,\n\tstd::string const& _linePrefix,\n\tbool _formatted\n)\n{\n\tif (_errorList.empty())\n\t{\n\t\tif (_formatted)\n\t\t\tutil::AnsiColorized(_stream, _formatted, {BOLD, GREEN}) << _linePrefix << \"Success\" << std::endl;\n\t}\n\telse\n\t\tfor (auto const& error: _errorList)\n\t\t{\n\t\t\t{\n\t\t\t\tutil::AnsiColorized formattedStream(\n\t\t\t\t\t_stream,\n\t\t\t\t\t_formatted,\n\t\t\t\t\t{BOLD, SourceReferenceFormatter::errorTextColor(Error::errorSeverity(error.type))}\n\t\t\t\t);\n\t\t\t\tformattedStream << _linePrefix << Error::formatErrorType(error.type);\n\t\t\t\tif (error.errorId.has_value())\n\t\t\t\t\tformattedStream << ' ' << error.errorId->error;\n\t\t\t\tformattedStream << \": \";\n\t\t\t}\n\t\t\tif (!error.sourceName.empty() || error.locationStart >= 0 || error.locationEnd >= 0)\n\t\t\t{\n\t\t\t\t_stream << \"(\";\n\t\t\t\tif (!error.sourceName.empty())\n\t\t\t\t\t_stream << error.sourceName << \":\";\n\t\t\t\tif (error.locationStart >= 0)\n\t\t\t\t\t_stream << error.locationStart;\n\t\t\t\t_stream << \"-\";\n\t\t\t\tif (error.locationEnd >= 0)\n\t\t\t\t\t_stream << error.locationEnd;\n\t\t\t\t_stream << \"): \";\n\t\t\t}\n\t\t\t_stream << error.message << std::endl;\n\t\t}\n}\n\nstd::string CommonSyntaxTest::errorMessage(util::Exception const& _e)\n{\n\tif (_e.comment() && !_e.comment()->empty())\n\t\treturn boost::replace_all_copy(*_e.comment(), \"\\n\", \"\\\\n\");\n\telse\n\t\treturn \"NONE\";\n}\n\nstd::vector<SyntaxTestError> CommonSyntaxTest::parseExpectations(std::istream& _stream)\n{\n\tstatic std::string const customExpectationsDelimiter(\"// ----\");\n\n\tstd::vector<SyntaxTestError> expectations;\n\tstd::string line;\n\twhile (std::getline(_stream, line))\n\t{\n\t\tauto it = line.begin();\n\n\t\t// Anything below the delimiter is left up to the derived class to process in a custom way.\n\t\t// The delimiter is optional and identical to the one that starts error expectations in\n\t\t// TestCaseReader::parseSourcesAndSettingsWithLineNumber().\n\t\tif (boost::algorithm::starts_with(line, customExpectationsDelimiter))\n\t\t\tbreak;\n\n\t\tskipSlashes(it, line.end());\n\t\tskipWhitespace(it, line.end());\n\n\t\tif (it == line.end()) continue;\n\n\t\tauto typeBegin = it;\n\t\twhile (it != line.end() && isalpha(*it, std::locale::classic()))\n\t\t\t++it;\n\n\t\tstd::string errorTypeStr(typeBegin, it);\n\t\tstd::optional<Error::Type> errorType = Error::parseErrorType(errorTypeStr);\n\t\tif (!errorType.has_value())\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid error type: \" + errorTypeStr));\n\n\t\tskipWhitespace(it, line.end());\n\n\t\tstd::optional<ErrorId> errorId;\n\t\tif (it != line.end() && util::isDigit(*it))\n\t\t\terrorId = ErrorId{static_cast<unsigned long long>(parseUnsignedInteger(it, line.end()))};\n\n\t\texpect(it, line.end(), ':');\n\t\tskipWhitespace(it, line.end());\n\n\t\tint locationStart = -1;\n\t\tint locationEnd = -1;\n\t\tstd::string sourceName;\n\n\t\tif (it != line.end() && *it == '(')\n\t\t{\n\t\t\t++it;\n\t\t\tif (it != line.end() && !util::isDigit(*it))\n\t\t\t{\n\t\t\t\tauto sourceNameStart = it;\n\t\t\t\twhile (it != line.end() && *it != ':')\n\t\t\t\t\t++it;\n\t\t\t\tsourceName = std::string(sourceNameStart, it);\n\t\t\t\texpect(it, line.end(), ':');\n\t\t\t}\n\t\t\tlocationStart = parseUnsignedInteger(it, line.end());\n\t\t\texpect(it, line.end(), '-');\n\t\t\tlocationEnd = parseUnsignedInteger(it, line.end());\n\t\t\texpect(it, line.end(), ')');\n\t\t\texpect(it, line.end(), ':');\n\t\t}\n\n\t\tskipWhitespace(it, line.end());\n\n\t\tstd::string errorMessage(it, line.end());\n\t\texpectations.emplace_back(SyntaxTestError{\n\t\t\terrorType.value(),\n\t\t\tstd::move(errorId),\n\t\t\tstd::move(errorMessage),\n\t\t\tstd::move(sourceName),\n\t\t\tlocationStart,\n\t\t\tlocationEnd\n\t\t});\n\t}\n\treturn expectations;\n}\n"
  },
  {
    "path": "test/CommonSyntaxTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <test/libsolidity/AnalysisFramework.h>\n#include <test/TestCase.h>\n#include <test/TestCaseReader.h>\n#include <liblangutil/Exceptions.h>\n#include <libsolutil/AnsiColorized.h>\n\n#include <iosfwd>\n#include <string>\n#include <vector>\n#include <utility>\n\nnamespace solidity::test\n{\n\nstruct SyntaxTestError\n{\n\tlangutil::Error::Type type;\n\tstd::optional<langutil::ErrorId> errorId;\n\tstd::string message;\n\tstd::string sourceName;\n\tint locationStart = -1;\n\tint locationEnd = -1;\n\tbool operator==(SyntaxTestError const& _rhs) const\n\t{\n\t\treturn type == _rhs.type &&\n\t\t\terrorId == _rhs.errorId &&\n\t\t\tmessage == _rhs.message &&\n\t\t\tsourceName == _rhs.sourceName &&\n\t\t\tlocationStart == _rhs.locationStart &&\n\t\t\tlocationEnd == _rhs.locationEnd;\n\t}\n};\n\n\nclass CommonSyntaxTest: public frontend::test::EVMVersionRestrictedTestCase\n{\npublic:\n\tCommonSyntaxTest(std::string const& _filename, langutil::EVMVersion _evmVersion);\n\n\tTestResult run(std::ostream& _stream, std::string const& _linePrefix = \"\", bool _formatted = false) override;\n\n\tvoid printSource(std::ostream& _stream, std::string const &_linePrefix = \"\", bool _formatted = false) const override;\n\tvoid printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override\n\t{\n\t\tprintObtainedResult(_stream, _linePrefix, false);\n\t}\n\n\tstatic std::string errorMessage(util::Exception const& _e);\nprotected:\n\t/// Should be implemented by those derived test cases that want to allow extra expectations\n\t/// after the error/warning expectations. The default implementation does not allow them and\n\t/// fails instead.\n\t/// @param _stream Input stream positioned at the beginning of the extra expectations.\n\tvirtual void parseCustomExpectations(std::istream& _stream);\n\n\tvirtual void parseAndAnalyze() = 0;\n\n\t/// Should return true if obtained values match expectations.\n\t/// The default implementation only compares the error list. Derived classes that support\n\t/// custom expectations should override this to include them in the comparison.\n\tvirtual bool expectationsMatch();\n\n\tvirtual void printExpectedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const;\n\tvirtual void printObtainedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const;\n\n\tstatic void printErrorList(\n\t\tstd::ostream& _stream,\n\t\tstd::vector<SyntaxTestError> const& _errors,\n\t\tstd::string const& _linePrefix,\n\t\tbool _formatted = false\n\t);\n\n\tTestResult conclude(std::ostream& _stream, std::string const& _linePrefix = \"\", bool _formatted = false);\n\tvoid printExpectationAndError(std::ostream& _stream, std::string const& _linePrefix = \"\", bool _formatted = false);\n\n\tstatic std::vector<SyntaxTestError> parseExpectations(std::istream& _stream);\n\n\tfrontend::test::SourceMap m_sources;\n\tstd::vector<SyntaxTestError> m_expectations;\n\tstd::vector<SyntaxTestError> m_errorList;\n\tlangutil::EVMVersion const m_evmVersion;\n};\n\n}\n"
  },
  {
    "path": "test/EVMHost.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * EVM execution host, i.e. component that implements a simulated Ethereum blockchain\n * for testing purposes.\n */\n\n// Weird issue when compiling with O3 on gcc 12 and later due to usage of vector<uint8_t> (aka bytes) as std::map key\n// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98465\n// also clang doesn't know stringop-overread\n#if defined(__GNUC__) && !defined(__clang__) // GCC-specific pragma\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wstringop-overread\"\n#endif\n\n#include <test/EVMHost.h>\n#include <test/libsolidity/util/SoltestErrors.h>\n\n#if defined(__GNUC__) && !defined(__clang__) // GCC-specific pragma\n#pragma GCC diagnostic pop\n#endif\n\n#include <test/evmc/loader.h>\n\n#include <libevmasm/GasMeter.h>\n\n#include <libsolutil/Exceptions.h>\n#include <libsolutil/Assertions.h>\n#include <libsolutil/Keccak256.h>\n#include <libsolutil/picosha2.h>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::test;\nusing namespace evmc::literals;\n\nevmc::VM& EVMHost::getVM(std::string const& _path)\n{\n\tstatic evmc::VM NullVM{nullptr};\n\tstatic std::map<std::string, std::unique_ptr<evmc::VM>> vms;\n\tif (vms.count(_path) == 0)\n\t{\n\t\tevmc_loader_error_code errorCode = {};\n\t\tauto vm = evmc::VM{evmc_load_and_configure(_path.c_str(), &errorCode)};\n\t\tif (vm && errorCode == EVMC_LOADER_SUCCESS)\n\t\t{\n\t\t\tif (vm.get_capabilities() & (EVMC_CAPABILITY_EVM1))\n\t\t\t\tvms[_path] = std::make_unique<evmc::VM>(evmc::VM(std::move(vm)));\n\t\t\telse\n\t\t\t\tstd::cerr << \"VM loaded does not support EVM1\" << std::endl;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstd::cerr << \"Error loading VM from \" << _path;\n\t\t\tif (char const* errorMsg = evmc_last_error_msg())\n\t\t\t\tstd::cerr << \":\" << std::endl << errorMsg;\n\t\t\tstd::cerr << std::endl;\n\t\t}\n\t\tvms[_path]->set_option(\"validate_eof\", \"1\");\n\t}\n\n\tif (vms.count(_path) > 0)\n\t\treturn *vms[_path];\n\n\treturn NullVM;\n}\n\nbool EVMHost::checkVmPaths(std::vector<boost::filesystem::path> const& _vmPaths)\n{\n\tbool evmVmFound = false;\n\tfor (auto const& path: _vmPaths)\n\t{\n\t\tevmc::VM& vm = EVMHost::getVM(path.string());\n\t\tif (!vm)\n\t\t\tcontinue;\n\n\t\tif (vm.has_capability(EVMC_CAPABILITY_EVM1))\n\t\t{\n\t\t\tif (evmVmFound)\n\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Multiple evm1 evmc vms defined. Please only define one evm1 evmc vm.\"));\n\t\t\tevmVmFound = true;\n\t\t}\n\t}\n\treturn evmVmFound;\n}\n\nEVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):\n\tm_vm(_vm),\n\tm_evmVersion(_evmVersion)\n{\n\tif (!m_vm)\n\t{\n\t\tstd::cerr << \"Unable to find evmone library\" << std::endl;\n\t\tsolRequire(false, Exception, \"\");\n\t}\n\n\tif (_evmVersion == langutil::EVMVersion::homestead())\n\t\tm_evmRevision = EVMC_HOMESTEAD;\n\telse if (_evmVersion == langutil::EVMVersion::tangerineWhistle())\n\t\tm_evmRevision = EVMC_TANGERINE_WHISTLE;\n\telse if (_evmVersion == langutil::EVMVersion::spuriousDragon())\n\t\tm_evmRevision = EVMC_SPURIOUS_DRAGON;\n\telse if (_evmVersion == langutil::EVMVersion::byzantium())\n\t\tm_evmRevision = EVMC_BYZANTIUM;\n\telse if (_evmVersion == langutil::EVMVersion::constantinople())\n\t\tm_evmRevision = EVMC_CONSTANTINOPLE;\n\telse if (_evmVersion == langutil::EVMVersion::petersburg())\n\t\tm_evmRevision = EVMC_PETERSBURG;\n\telse if (_evmVersion == langutil::EVMVersion::istanbul())\n\t\tm_evmRevision = EVMC_ISTANBUL;\n\telse if (_evmVersion == langutil::EVMVersion::berlin())\n\t\tm_evmRevision = EVMC_BERLIN;\n\telse if (_evmVersion == langutil::EVMVersion::london())\n\t\tm_evmRevision = EVMC_LONDON;\n\telse if (_evmVersion == langutil::EVMVersion::paris())\n\t\tm_evmRevision = EVMC_PARIS;\n\telse if (_evmVersion == langutil::EVMVersion::shanghai())\n\t\tm_evmRevision = EVMC_SHANGHAI;\n\telse if (_evmVersion == langutil::EVMVersion::cancun())\n\t\tm_evmRevision = EVMC_CANCUN;\n\telse if (_evmVersion == langutil::EVMVersion::prague())\n\t\tm_evmRevision = EVMC_PRAGUE;\n\telse if (_evmVersion == langutil::EVMVersion::osaka())\n\t\tm_evmRevision = EVMC_OSAKA;\n\telse\n\t\tsolRequire(false, Exception, \"Unsupported EVM version\");\n\n\tif (m_evmRevision >= EVMC_PARIS)\n\t\t// This is the value from the merge block.\n\t\ttx_context.block_prev_randao = 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777_bytes32;\n\telse\n\t\ttx_context.block_prev_randao = evmc::uint256be{200000000};\n\ttx_context.block_gas_limit = 20000000;\n\ttx_context.block_coinbase = 0x7878787878787878787878787878787878787878_address;\n\ttx_context.tx_gas_price = evmc::uint256be{3000000000};\n\ttx_context.tx_origin = 0x9292929292929292929292929292929292929292_address;\n\t// Mainnet according to EIP-155\n\ttx_context.chain_id = evmc::uint256be{1};\n\t// The minimum value of basefee\n\ttx_context.block_base_fee = evmc::bytes32{7};\n\t// The minimum value of blobbasefee\n\ttx_context.blob_base_fee = evmc::bytes32{1};\n\n\tstatic evmc_bytes32 const blob_hashes_array[] = {\n\t\t0x0100000000000000000000000000000000000000000000000000000000000001_bytes32,\n\t\t0x0100000000000000000000000000000000000000000000000000000000000002_bytes32\n\t};\n\ttx_context.blob_hashes = blob_hashes_array;\n\ttx_context.blob_hashes_count = sizeof(blob_hashes_array) / sizeof(blob_hashes_array[0]);\n\n\t// Reserve space for recording calls.\n\tif (!recorded_calls.capacity())\n\t\trecorded_calls.reserve(max_recorded_calls);\n\n\treset();\n}\n\nvoid EVMHost::reset()\n{\n\taccounts.clear();\n\t// Clear self destruct records\n\trecorded_selfdestructs.clear();\n\t// Clear call records\n\trecorded_calls.clear();\n\t// Clear EIP-2929 account access indicator\n\trecorded_account_accesses.clear();\n\tm_newlyCreatedAccounts.clear();\n\tm_totalCodeDepositGas = 0;\n\n\t// Mark all precompiled contracts as existing. Existing here means to have a balance (as per EIP-161).\n\t// NOTE: keep this in sync with `EVMHost::call` below.\n\t//\n\t// A lot of precompile addresses had a balance before they became valid addresses for precompiles.\n\t// For example all the precompile addresses allocated in Byzantium had a 1 wei balance sent to them\n\t// roughly 22 days before the update went live.\n\tfor (unsigned precompiledAddress = 1; precompiledAddress <= 8; precompiledAddress++)\n\t{\n\t\tevmc::address address{precompiledAddress};\n\t\t// 1wei\n\t\taccounts[address].balance = evmc::uint256be{1};\n\t\t// Set according to EIP-1052.\n\t\tif (precompiledAddress < 5 || m_evmVersion >= langutil::EVMVersion::byzantium())\n\t\t\taccounts[address].codehash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470_bytes32;\n\t}\n}\n\nvoid EVMHost::newTransactionFrame()\n{\n\t// Clear EIP-2929 account access indicator\n\trecorded_account_accesses.clear();\n\n\tfor (auto& [address, account]: accounts)\n\t{\n\t\tfor (auto& [slot, value]: account.storage)\n\t\t{\n\t\t\tvalue.access_status = EVMC_ACCESS_COLD; // Clear EIP-2929 storage access indicator\n\t\t\tvalue.original = value.current;         // Clear EIP-2200 dirty slot\n\t\t}\n\n\t\t// Clear transient storage according to EIP 1153\n\t\taccount.transient_storage.clear();\n\t}\n\t// Process selfdestruct list\n\tfor (auto& [address, _]: recorded_selfdestructs)\n\t\tif (m_evmVersion < langutil::EVMVersion::cancun() || m_newlyCreatedAccounts.count(address))\n\t\t\t// EIP-6780: If SELFDESTRUCT is executed in a transaction different from the one\n\t\t\t// in which it was created, we do NOT record it or clear any data.\n\t\t\t// Otherwise, the previous behavior (pre-Cancun) is maintained.\n\t\t\taccounts.erase(address);\n\tm_newlyCreatedAccounts.clear();\n\tm_totalCodeDepositGas = 0;\n\trecorded_selfdestructs.clear();\n}\n\nvoid EVMHost::transfer(evmc::MockedAccount& _sender, evmc::MockedAccount& _recipient, u256 const& _value) noexcept\n{\n\tsolRequire(u256(convertFromEVMC(_sender.balance)) >= _value, Exception, \"Insufficient balance for transfer\");\n\t_sender.balance = convertToEVMC(u256(convertFromEVMC(_sender.balance)) - _value);\n\t_recipient.balance = convertToEVMC(u256(convertFromEVMC(_recipient.balance)) + _value);\n}\n\nbool EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept\n{\n\t// TODO actual selfdestruct is even more complicated.\n\n\t// NOTE: EIP-6780: The transfer of the entire account balance to the beneficiary should still happen\n\t// after cancun.\n\ttransfer(accounts[_addr], accounts[_beneficiary], convertFromEVMC(accounts[_addr].balance));\n\n\t// Record self destructs. Clearing will be done in newTransactionFrame().\n\treturn MockedHost::selfdestruct(_addr, _beneficiary);\n}\n\nvoid EVMHost::recordCalls(evmc_message const& _message) noexcept\n{\n\tif (recorded_calls.size() < max_recorded_calls)\n\t\trecorded_calls.emplace_back(_message);\n}\n\n// NOTE: this is used for both internal and external calls.\n// External calls are triggered from ExecutionFramework and contain only EVMC_CREATE or EVMC_CALL.\nevmc::Result EVMHost::call(evmc_message const& _message) noexcept\n{\n\trecordCalls(_message);\n\tif (_message.recipient == 0x0000000000000000000000000000000000000001_address)\n\t\treturn precompileECRecover(_message);\n\telse if (_message.recipient == 0x0000000000000000000000000000000000000002_address)\n\t\treturn precompileSha256(_message);\n\telse if (_message.recipient == 0x0000000000000000000000000000000000000003_address)\n\t\treturn precompileRipeMD160(_message);\n\telse if (_message.recipient == 0x0000000000000000000000000000000000000004_address)\n\t\treturn precompileIdentity(_message);\n\telse if (_message.recipient == 0x0000000000000000000000000000000000000005_address && m_evmVersion >= langutil::EVMVersion::byzantium())\n\t\treturn precompileModExp(_message);\n\telse if (_message.recipient == 0x0000000000000000000000000000000000000006_address && m_evmVersion >= langutil::EVMVersion::byzantium())\n\t{\n\t\tif (m_evmVersion <= langutil::EVMVersion::istanbul())\n\t\t\treturn precompileALTBN128G1Add<EVMC_ISTANBUL>(_message);\n\t\telse\n\t\t\treturn precompileALTBN128G1Add<EVMC_LONDON>(_message);\n\t}\n\telse if (_message.recipient == 0x0000000000000000000000000000000000000007_address && m_evmVersion >= langutil::EVMVersion::byzantium())\n\t{\n\t\tif (m_evmVersion <= langutil::EVMVersion::istanbul())\n\t\t\treturn precompileALTBN128G1Mul<EVMC_ISTANBUL>(_message);\n\t\telse\n\t\t\treturn precompileALTBN128G1Mul<EVMC_LONDON>(_message);\n\t}\n\telse if (_message.recipient == 0x0000000000000000000000000000000000000008_address && m_evmVersion >= langutil::EVMVersion::byzantium())\n\t{\n\t\tif (m_evmVersion <= langutil::EVMVersion::istanbul())\n\t\t\treturn precompileALTBN128PairingProduct<EVMC_ISTANBUL>(_message);\n\t\telse\n\t\t\treturn precompileALTBN128PairingProduct<EVMC_LONDON>(_message);\n\t}\n\telse if (_message.recipient == 0x0000000000000000000000000000000000000009_address && m_evmVersion >= langutil::EVMVersion::istanbul())\n\t\treturn precompileBlake2f(_message);\n\n\tauto const stateBackup = accounts;\n\n\tu256 value{convertFromEVMC(_message.value)};\n\tauto& sender = accounts[_message.sender];\n\n\tevmc::bytes code;\n\n\tevmc_message message = _message;\n\tif (message.depth == 0)\n\t{\n\t\tmessage.gas -= message.kind == EVMC_CREATE ? evmasm::GasCosts::txCreateGas : evmasm::GasCosts::txGas;\n\t\tfor (size_t i = 0; i < message.input_size; ++i)\n\t\t\tmessage.gas -= message.input_data[i] == 0 ? evmasm::GasCosts::txDataZeroGas : evmasm::GasCosts::txDataNonZeroGas(m_evmVersion);\n\t\tif (message.gas < 0)\n\t\t{\n\t\t\tevmc::Result result;\n\t\t\tresult.status_code = EVMC_OUT_OF_GAS;\n\t\t\taccounts = stateBackup;\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tif (message.kind == EVMC_CREATE)\n\t{\n\t\t// TODO is the nonce incremented on failure, too?\n\t\t// NOTE: nonce for creation from contracts starts at 1\n\t\t// TODO: check if sender is an EOA and do not pre-increment\n\t\tsender.nonce++;\n\n\t\tauto encodeRlpInteger = [](int value) -> bytes {\n\t\t\tif (value == 0) {\n\t\t\t\treturn bytes{128};\n\t\t\t} else if (value <= 127) {\n\t\t\t\treturn bytes{static_cast<uint8_t>(value)};\n\t\t\t} else if (value <= 0xff) {\n\t\t\t\treturn bytes{128 + 1, static_cast<uint8_t>(value)};\n\t\t\t} else if (value <= 0xffff) {\n\t\t\t\treturn bytes{128 + 55 + 2, static_cast<uint8_t>(value >> 8), static_cast<uint8_t>(value)};\n\t\t\t} else {\n\t\t\t\tsolUnimplemented(\"Can only encode RLP numbers <= 0xffff\");\n\t\t\t}\n\t\t};\n\n\t\tbytes encodedNonce = encodeRlpInteger(sender.nonce);\n\n\t\th160 createAddress(keccak256(\n\t\t\tbytes{static_cast<uint8_t>(0xc0 + 21 + encodedNonce.size())} +\n\t\t\tbytes{0x94} +\n\t\t\tbytes(std::begin(message.sender.bytes), std::end(message.sender.bytes)) +\n\t\t\tencodedNonce\n\t\t), h160::AlignRight);\n\n\t\tmessage.recipient = convertToEVMC(createAddress);\n\t\tsoltestAssert(accounts.count(message.recipient) == 0, \"Account cannot exist\");\n\n\t\tcode = evmc::bytes(message.input_data, message.input_data + message.input_size);\n\t}\n\telse if (message.kind == EVMC_CREATE2 || message.kind == EVMC_EOFCREATE)\n\t{\n\t\th160 createAddress(keccak256(\n\t\t\tbytes{0xff} +\n\t\t\tbytes(std::begin(message.sender.bytes), std::end(message.sender.bytes)) +\n\t\t\tbytes(std::begin(message.create2_salt.bytes), std::end(message.create2_salt.bytes)) +\n\t\t\tkeccak256(\n\t\t\t\tmessage.kind == EVMC_CREATE2 ?\n\t\t\t\tbytes(message.input_data, message.input_data + message.input_size) :\n\t\t\t\tbytes(message.code, message.code + message.code_size)\n\t\t\t).asBytes()\n\t\t), h160::AlignRight);\n\n\t\tmessage.recipient = convertToEVMC(createAddress);\n\t\tif (accounts.count(message.recipient) && (\n\t\t\taccounts[message.recipient].nonce > 0 ||\n\t\t\t!accounts[message.recipient].code.empty()\n\t\t))\n\t\t{\n\t\t\tevmc::Result result;\n\t\t\tresult.status_code = EVMC_OUT_OF_GAS;\n\t\t\taccounts = stateBackup;\n\t\t\treturn result;\n\t\t}\n\n\t\tif (message.kind == EVMC_CREATE2)\n\t\t\tcode = evmc::bytes(message.input_data, message.input_data + message.input_size);\n\t\telse // EOFCREATE\n\t\t\tcode = evmc::bytes(message.code, message.code + message.code_size);\n\t}\n\telse\n\t\tcode = accounts[message.code_address].code;\n\n\tauto& destination = accounts[message.recipient];\n\tif (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2 || message.kind == EVMC_EOFCREATE)\n\t\t// Mark account as created if it is a CREATE or CREATE2 call\n\t\t// TODO: Should we roll changes back on failure like we do for `accounts`?\n\t\tm_newlyCreatedAccounts.emplace(message.recipient);\n\n\tif (value != 0 && message.kind != EVMC_DELEGATECALL && message.kind != EVMC_CALLCODE)\n\t{\n\t\tif (value > convertFromEVMC(sender.balance))\n\t\t{\n\t\t\tevmc::Result result;\n\t\t\tresult.status_code = EVMC_INSUFFICIENT_BALANCE;\n\t\t\taccounts = stateBackup;\n\t\t\treturn result;\n\t\t}\n\t\ttransfer(sender, destination, value);\n\t}\n\n\t// Populate the access list (enabled since Berlin).\n\t// Note, this will also properly touch the created address.\n\t// TODO: support a user supplied access list too\n\tif (m_evmRevision >= EVMC_BERLIN)\n\t{\n\t\taccess_account(message.sender);\n\t\taccess_account(message.recipient);\n\n\t\t// EIP-3651 rule\n\t\tif (m_evmRevision >= EVMC_SHANGHAI)\n\t\t\taccess_account(tx_context.block_coinbase);\n\t}\n\n\tif (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2)\n\t{\n\t\tmessage.input_data = nullptr;\n\t\tmessage.input_size = 0;\n\t}\n\tevmc::Result result = m_vm.execute(*this, m_evmRevision, message, code.data(), code.size());\n\n\tif (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2 || message.kind == EVMC_EOFCREATE)\n\t{\n\t\tint64_t codeDepositGas = static_cast<int64_t>(evmasm::GasCosts::createDataGas * result.output_size);\n\t\tresult.gas_left -= codeDepositGas;\n\t\tif (result.gas_left < 0)\n\t\t{\n\t\t\tm_totalCodeDepositGas += -result.gas_left;\n\t\t\tresult.gas_left = 0;\n\t\t\tresult.status_code = EVMC_OUT_OF_GAS;\n\t\t\t// TODO clear some fields?\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// TODO: Add proper codehash calculation for EOF.\n\t\t\tm_totalCodeDepositGas += codeDepositGas;\n\t\t\tresult.create_address = message.recipient;\n\t\t\tdestination.code = evmc::bytes(result.output_data, result.output_data + result.output_size);\n\t\t\tdestination.codehash = convertToEVMC(keccak256({result.output_data, result.output_size}));\n\t\t}\n\t}\n\n\tif (result.status_code != EVMC_SUCCESS)\n\t\taccounts = stateBackup;\n\n\treturn result;\n}\n\nevmc::bytes32 EVMHost::get_block_hash(int64_t _number) const noexcept\n{\n\treturn convertToEVMC(u256(\"0x3737373737373737373737373737373737373737373737373737373737373737\") + _number);\n}\n\nh160 EVMHost::convertFromEVMC(evmc::address const& _addr)\n{\n\treturn h160(bytes(std::begin(_addr.bytes), std::end(_addr.bytes)));\n}\n\nevmc::address EVMHost::convertToEVMC(h160 const& _addr)\n{\n\tevmc::address a;\n\tfor (unsigned i = 0; i < 20; ++i)\n\t\ta.bytes[i] = _addr[i];\n\treturn a;\n}\n\nh256 EVMHost::convertFromEVMC(evmc::bytes32 const& _data)\n{\n\treturn h256(bytes(std::begin(_data.bytes), std::end(_data.bytes)));\n}\n\nevmc::bytes32 EVMHost::convertToEVMC(h256 const& _data)\n{\n\tevmc::bytes32 d;\n\tfor (unsigned i = 0; i < 32; ++i)\n\t\td.bytes[i] = _data[i];\n\treturn d;\n}\n\nevmc::Result EVMHost::precompileECRecover(evmc_message const& _message) noexcept\n{\n\t// NOTE this is a partial implementation for some inputs.\n\n\t// Fixed cost of 3000 gas.\n\tconstexpr int64_t gas_cost = 3000;\n\n\tstatic std::map<bytes, EVMPrecompileOutput> const inputOutput{\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c\"\n\t\t\t\t\"000000000000000000000000000000000000000000000000000000000000001c\"\n\t\t\t\t\"73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f\"\n\t\t\t\t\"eeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b\"),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad\"\n\t\t\t\t\"000000000000000000000000000000000000000000000000000000000000001c\"\n\t\t\t\t\"debaaa0cddb321b2dcaaf846d39605de7b97e77ba6106587855b9106cb104215\"\n\t\t\t\t\"61a22d94fa8b8a687ff9c911c844d1c016d1a685a9166858f9c7c1bc85128aca\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000008743523d96a1b2cbe0c6909653a56da18ed484af\"),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000001\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000002\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000003\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"\"),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t\"6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4\"\n\t\t\t\t\"ef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"\"),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t}\n\t};\n\tevmc::Result result = precompileGeneric(_message, inputOutput, true /* _ignoresTrailingInput */);\n\t// ECRecover will return success with empty response in case of failure\n\tif (result.status_code != EVMC_SUCCESS && result.status_code != EVMC_OUT_OF_GAS)\n\t\treturn resultWithGas(_message.gas, gas_cost, {});\n\treturn result;\n}\n\nevmc::Result EVMHost::precompileSha256(evmc_message const& _message) noexcept\n{\n\t// static data so that we do not need a release routine...\n\tbytes static hash;\n\thash = picosha2::hash256(bytes(\n\t\t_message.input_data,\n\t\t_message.input_data + _message.input_size\n\t));\n\n\t// Base 60 gas + 12 gas / word.\n\tint64_t gas_cost = 60 + 12 * ((static_cast<int64_t>(_message.input_size) + 31) / 32);\n\n\treturn resultWithGas(_message.gas, gas_cost, hash);\n}\n\nevmc::Result EVMHost::precompileRipeMD160(evmc_message const& _message) noexcept\n{\n\t// NOTE this is a partial implementation for some inputs.\n\n\t// Base 600 gas + 120 gas / word.\n\tconstexpr auto calc_cost = [](int64_t size) -> int64_t {\n\t\treturn 600 + 120 * ((size + 31) / 32);\n\t};\n\n\tstatic std::map<bytes, EVMPrecompileOutput> const inputOutput{\n\t\t{\n\t\t\tbytes{},\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31\"),\n\t\t\t\tcalc_cost(0)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\"0000000000000000000000000000000000000000000000000000000000000004\"),\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000001b0f3c404d12075c68c938f9f60ebea4f74941a0\"),\n\t\t\t\tcalc_cost(32)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\"0000000000000000000000000000000000000000000000000000000000000005\"),\n\t\t\t{\n\t\t\t\tfromHex(\"000000000000000000000000ee54aa84fc32d8fed5a5fe160442ae84626829d9\"),\n\t\t\t\tcalc_cost(32)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"),\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000001cf4e77f5966e13e109703cd8a0df7ceda7f3dc3\"),\n\t\t\t\tcalc_cost(32)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\"0000000000000000000000000000000000000000000000000000000000000000\"),\n\t\t\t{\n\t\t\t\tfromHex(\"000000000000000000000000f93175303eba2a7b372174fc9330237f5ad202fc\"),\n\t\t\t\tcalc_cost(32)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0800000000000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t\"0401000000000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t\"0000000400000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t\"00000100\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"000000000000000000000000f93175303eba2a7b372174fc9330237f5ad202fc\"),\n\t\t\t\tcalc_cost(100)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0800000000000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t\"0501000000000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t\"0000000500000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t\"00000100\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000004f4fc112e2bfbe0d38f896a46629e08e2fcfad5\"),\n\t\t\t\tcalc_cost(100)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n\t\t\t\t\"ff010000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n\t\t\t\t\"ffffffff00000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t\"00000100\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"000000000000000000000000c0a2e4b1f3ff766a9a0089e7a410391730872495\"),\n\t\t\t\tcalc_cost(100)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"6162636465666768696a6b6c6d6e6f707172737475767778797a414243444546\"\n\t\t\t\t\"4748494a4b4c4d4e4f505152535455565758595a303132333435363738393f21\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"00000000000000000000000036c6b90a49e17d4c1e1b0e634ec74124d9b207da\"),\n\t\t\t\tcalc_cost(64)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\"6162636465666768696a6b6c6d6e6f707172737475767778797a414243444546\"),\n\t\t\t{\n\t\t\t\tfromHex(\"000000000000000000000000ac5ab22e07b0fb80c69b6207902f725e2507e546\"),\n\t\t\t\tcalc_cost(32)\n\t\t\t}\n\t\t}\n\t};\n\treturn precompileGeneric(_message, inputOutput);\n}\n\nevmc::Result EVMHost::precompileIdentity(evmc_message const& _message) noexcept\n{\n\t// static data so that we do not need a release routine...\n\tbytes static data;\n\tdata = bytes(_message.input_data, _message.input_data + _message.input_size);\n\n\t// Base 15 gas + 3 gas / word.\n\tint64_t gas_cost = 15 + 3 * ((static_cast<int64_t>(_message.input_size) + 31) / 32);\n\n\treturn resultWithGas(_message.gas, gas_cost, data);\n}\n\nevmc::Result EVMHost::precompileModExp(evmc_message const&) noexcept\n{\n\t// TODO implement\n\treturn resultWithFailure();\n}\n\ntemplate <evmc_revision Revision>\nevmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noexcept\n{\n\t// NOTE this is a partial implementation for some inputs.\n\n\t// Fixed 500 or 150 gas.\n\tint64_t gas_cost = (Revision < EVMC_ISTANBUL) ? 500 : 150;\n\n\tstatic std::map<bytes, EVMPrecompileOutput> const inputOutput{\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t\"1385281136ff5b2c326807ff0a824b6ca4f21fcc7c8764e9801bc4ad497d5012\"\n\t\t\t\t\"02254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"1385281136ff5b2c326807ff0a824b6ca4f21fcc7c8764e9801bc4ad497d5012\"\n\t\t\t\t\t\"02254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000001\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000002\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000001\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000002\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3\"\n\t\t\t\t\t\"15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000001\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000002\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000001\"\n\t\t\t\t\"30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000000\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"10b4876441e14a6be92a7fe66550848c01c676a12ac31d7cc13b21f49c4307c8\"\n\t\t\t\t\"09f5528bdb0ef9354837a0f4b4c9da973bd5b805d359976f719ab0b74e0a7368\"\n\t\t\t\t\"28d3c57516712e7843a5b3cfa7d7274a037943f5bd57c227620ad207728e4283\"\n\t\t\t\t\"2795fa9df21d4b8b329a45bae120f1fd9df9049ecacaa9dd1eca18bc6a55cd2f\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"16aed5ed486df6b2fb38015ded41400009ed4f34bef65b87b1f90f47052f8d94\"\n\t\t\t\t\t\"16dabf21b3f25b9665269d98dc17b1da6118251dc0b403ae50e96dfe91239375\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"1385281136ff5b2c326807ff0a824b6ca4f21fcc7c8764e9801bc4ad497d5012\"\n\t\t\t\t\"02254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c\"\n\t\t\t\t\"1644e84fef7b7fdc98254f0654580173307a3bc44db990581e7ab55a22446dcf\"\n\t\t\t\t\"28c2916b7e875692b195831945805438fcd30d2693d8a80cf8c88ec6ef4c315d\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"1e018816fc9bbd91313301ae9c254bb7d64d6cd54f3b49b92925e43e256b5faa\"\n\t\t\t\t\t\"1d1f2259c715327bedb42c095af6c0267e4e1be836b4e04b3f0502552f93cca9\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"16aed5ed486df6b2fb38015ded41400009ed4f34bef65b87b1f90f47052f8d94\"\n\t\t\t\t\"16dabf21b3f25b9665269d98dc17b1da6118251dc0b403ae50e96dfe91239375\"\n\t\t\t\t\"25ff95a3abccf32adc6a4c3c8caddca67723d8ada802e9b9f612e3ddb40b2005\"\n\t\t\t\t\"0d82b09bb4ec927bbf182bdc402790429322b7e2f285f2aad8ea135cbf7143d8\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"29d160febeef9770d47a32ee3b763850eb0594844fa57dd31b8ed02c78fdb797\"\n\t\t\t\t\t\"2c7cdf62c2498486fd52646e577a06723ce97737b3c958262d78c4a413661e8a\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"18014701594179c6b9ccae848e3d15c1f76f8a68b8092578296520e46c9bae0c\"\n\t\t\t\t\"1b5ed0e9e8f3ff35589ea81a45cf63887d4a92c099a3be1d97b26f0db96323dd\"\n\t\t\t\t\"16a1d378d1a98cf5383cdc512011234287ca43b6a078d1842d5c58c5b1f475cc\"\n\t\t\t\t\"1309377a7026d08ca1529eab74381a7e0d3a4b79d80bacec207cd52fc8e3769c\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"2583ed10e418133e44619c336f1be5ddae9e20d634a7683d9661401c750d7df4\"\n\t\t\t\t\t\"0185fbba22de9e698262925665735dbc4d6e8288bc3fc39fae10ca58e16e77f7\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59\"\n\t\t\t\t\"3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41\"\n\t\t\t\t\"0f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd2\"\n\t\t\t\t\"16da2f5cb6be7a0aa72c440c53c9bbdfec6c36c7d515536431b3a865468acbba\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"1496064626ba8bffeb7805f0d16143a65649bb0850333ea512c03fcdaf31e254\"\n\t\t\t\t\t\"07b4f210ab542533f1ee5633ae4406cd16c63494b537ce3f1cf4afff6f76a48f\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"1e018816fc9bbd91313301ae9c254bb7d64d6cd54f3b49b92925e43e256b5faa\"\n\t\t\t\t\"1d1f2259c715327bedb42c095af6c0267e4e1be836b4e04b3f0502552f93cca9\"\n\t\t\t\t\"2364294faf6b89fedeede9986aa777c4f6c2f5c4a4559ee93dfec9b7b94ef80b\"\n\t\t\t\t\"05aeae62655ea23865ae6661ae371a55c12098703d0f2301f4223e708c92efc6\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"2801b21090cbc48409e352647f3857134d373f81741f9d5e3d432f336d76f517\"\n\t\t\t\t\t\"13cf106acf943c2a331de21c7d5e3351354e7412f2dba2918483a6593a6828d4\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"2583ed10e418133e44619c336f1be5ddae9e20d634a7683d9661401c750d7df4\"\n\t\t\t\t\"0185fbba22de9e698262925665735dbc4d6e8288bc3fc39fae10ca58e16e77f7\"\n\t\t\t\t\"258f1faa356e470cca19c928afa5ceed6215c756912af5725b8db5777cc8f3b6\"\n\t\t\t\t\"175ced8a58d0c132c2b95ba14c16dde93e7f7789214116ff69da6f44daa966e6\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"10b4876441e14a6be92a7fe66550848c01c676a12ac31d7cc13b21f49c4307c8\"\n\t\t\t\t\t\"09f5528bdb0ef9354837a0f4b4c9da973bd5b805d359976f719ab0b74e0a7368\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"26dcfbc2e0bc9d82efb4acd73cb3e99730e27e10177fcfb78b6399a4bfcdf391\"\n\t\t\t\t\"27c440dbd5053253a3a692f9bf89b9b6e9612127cf97db1e11ffa9679acc933b\"\n\t\t\t\t\"1496064626ba8bffeb7805f0d16143a65649bb0850333ea512c03fcdaf31e254\"\n\t\t\t\t\"07b4f210ab542533f1ee5633ae4406cd16c63494b537ce3f1cf4afff6f76a48f\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"186bac5188a98c45e6016873d107f5cd131f3a3e339d0375e58bd6219347b008\"\n\t\t\t\t\t\"1e396bc242de0214898b0f68035f53ad5a6f96c6c8390ac56ed6ec9561d23159\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"26dcfbc2e0bc9d82efb4acd73cb3e99730e27e10177fcfb78b6399a4bfcdf391\"\n\t\t\t\t\"27c440dbd5053253a3a692f9bf89b9b6e9612127cf97db1e11ffa9679acc933b\"\n\t\t\t\t\"1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59\"\n\t\t\t\t\"3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"20a754d2071d4d53903e3b31a7e98ad6882d58aec240ef981fdf0a9d22c5926a\"\n\t\t\t\t\t\"29c853fcea789887315916bbeb89ca37edb355b4f980c9a12a94f30deeed3021\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"27231d5cdd0011259ff75678cf5a8f7840c22cb71d52b25e21e071205e8d9bc4\"\n\t\t\t\t\"26dd3d225c9a71476db0cf834232eba84020f3073c6d20c519963e0b98f235e1\"\n\t\t\t\t\"2174f0221490cd9c15b0387f3251ec3d49517a51c37a8076eac12afb4a95a707\"\n\t\t\t\t\"1d1c3fcd3161e2a417b4df0955f02db1fffa9005210fb30c5aa3755307e9d1f5\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"18014701594179c6b9ccae848e3d15c1f76f8a68b8092578296520e46c9bae0c\"\n\t\t\t\t\t\"1b5ed0e9e8f3ff35589ea81a45cf63887d4a92c099a3be1d97b26f0db96323dd\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"2801b21090cbc48409e352647f3857134d373f81741f9d5e3d432f336d76f517\"\n\t\t\t\t\"13cf106acf943c2a331de21c7d5e3351354e7412f2dba2918483a6593a6828d4\"\n\t\t\t\t\"2a49621e12910cd90f3e731083d454255bf1c533d6e15b8699156778d0f27f5d\"\n\t\t\t\t\"2590ee31824548d159aa2d22296bf149d564c0872f41b89b7dc5c6e6e3cd1c4d\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"27231d5cdd0011259ff75678cf5a8f7840c22cb71d52b25e21e071205e8d9bc4\"\n\t\t\t\t\t\"26dd3d225c9a71476db0cf834232eba84020f3073c6d20c519963e0b98f235e1\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"29d160febeef9770d47a32ee3b763850eb0594844fa57dd31b8ed02c78fdb797\"\n\t\t\t\t\"2c7cdf62c2498486fd52646e577a06723ce97737b3c958262d78c4a413661e8a\"\n\t\t\t\t\"0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a\"\n\t\t\t\t\"044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"26dcfbc2e0bc9d82efb4acd73cb3e99730e27e10177fcfb78b6399a4bfcdf391\"\n\t\t\t\t\t\"27c440dbd5053253a3a692f9bf89b9b6e9612127cf97db1e11ffa9679acc933b\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t}\n\t};\n\treturn precompileGeneric(_message, inputOutput, true /* _ignoresTrailingInput */);\n}\n\ntemplate <evmc_revision Revision>\nevmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noexcept\n{\n\t// NOTE this is a partial implementation for some inputs.\n\n\t// Fixed 40000 or 6000 gas.\n\tint64_t gas_cost = (Revision < EVMC_ISTANBUL) ? 40000 : 6000;\n\n\tstatic std::map<bytes, EVMPrecompileOutput> const inputOutput{\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000001\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000002\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000002\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3\"\n\t\t\t\t\t\"15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000001\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000002\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000005\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9\"\n\t\t\t\t\t\"01e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe\"\n\t\t\t\t\"18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4\"\n\t\t\t\t\"030f7b0c405c888aff922307ea2cd1c70f64664bab76899500341f4260a20929\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"16a1d378d1a98cf5383cdc512011234287ca43b6a078d1842d5c58c5b1f475cc\"\n\t\t\t\t\t\"1309377a7026d08ca1529eab74381a7e0d3a4b79d80bacec207cd52fc8e3769c\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a\"\n\t\t\t\t\"04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e\"\n\t\t\t\t\"1551dcd4965285ef049512d2d30cbfc1a91acd5baad4a6e19e22e93176197f17\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"28d3c57516712e7843a5b3cfa7d7274a037943f5bd57c227620ad207728e4283\"\n\t\t\t\t\t\"2795fa9df21d4b8b329a45bae120f1fd9df9049ecacaa9dd1eca18bc6a55cd2f\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a\"\n\t\t\t\t\"18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e\"\n\t\t\t\t\"0c692b41f1acc961f6ea83bae2c3a1a55c54f766c63ba76989f52c149c17b5e7\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"258f1faa356e470cca19c928afa5ceed6215c756912af5725b8db5777cc8f3b6\"\n\t\t\t\t\t\"175ced8a58d0c132c2b95ba14c16dde93e7f7789214116ff69da6f44daa966e6\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d\"\n\t\t\t\t\"0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b\"\n\t\t\t\t\"0ea71d0abb524cac7cfff5323e1d0b14ab705842426c978f96753ccce258ed93\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"2a49621e12910cd90f3e731083d454255bf1c533d6e15b8699156778d0f27f5d\"\n\t\t\t\t\t\"2590ee31824548d159aa2d22296bf149d564c0872f41b89b7dc5c6e6e3cd1c4d\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f\"\n\t\t\t\t\"1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30\"\n\t\t\t\t\"00000000000000000000000000000000000000e40800000000000000008cdcbc\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"25ff95a3abccf32adc6a4c3c8caddca67723d8ada802e9b9f612e3ddb40b2005\"\n\t\t\t\t\t\"0d82b09bb4ec927bbf182bdc402790429322b7e2f285f2aad8ea135cbf7143d8\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5\"\n\t\t\t\t\"02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1\"\n\t\t\t\t\"1887420878c0c8e37605291c626585eabbec8d8b97a848fe8d58a37b00458351\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"2364294faf6b89fedeede9986aa777c4f6c2f5c4a4559ee93dfec9b7b94ef80b\"\n\t\t\t\t\t\"05aeae62655ea23865ae6661ae371a55c12098703d0f2301f4223e708c92efc6\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f\"\n\t\t\t\t\"042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db\"\n\t\t\t\t\"016086cc934d5cab679c6991a4efcedbab26d7e4fb23b6a1ad4e6b5c2fb59ce5\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"1644e84fef7b7fdc98254f0654580173307a3bc44db990581e7ab55a22446dcf\"\n\t\t\t\t\t\"28c2916b7e875692b195831945805438fcd30d2693d8a80cf8c88ec6ef4c315d\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc\"\n\t\t\t\t\"2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb\"\n\t\t\t\t\"1eec35a0e955cad4bee5846ae0f1d0b742d8636b278450c534e38e06a60509f9\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"1385281136ff5b2c326807ff0a824b6ca4f21fcc7c8764e9801bc4ad497d5012\"\n\t\t\t\t\t\"02254594be8473dcf018a2aa66ea301e38fc865823acf75a9901721d1fc6bf4c\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8\"\n\t\t\t\t\"2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7\"\n\t\t\t\t\"0689c3dc4311426ee11707866b2cbdf9751dacd07245bf99d2113d3f5a8cac47\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\n\t\t\t\t\t\"2174f0221490cd9c15b0387f3251ec3d49517a51c37a8076eac12afb4a95a707\"\n\t\t\t\t\t\"1d1c3fcd3161e2a417b4df0955f02db1fffa9005210fb30c5aa3755307e9d1f5\"\n\t\t\t\t),\n\t\t\t\tgas_cost\n\t\t\t}\n\t\t}\n\t};\n\treturn precompileGeneric(_message, inputOutput, true /* _ignoresTrailingInput */);\n}\n\ntemplate <evmc_revision Revision>\nevmc::Result EVMHost::precompileALTBN128PairingProduct(evmc_message const& _message) noexcept\n{\n\t// Base + per pairing gas.\n\tconstexpr auto calc_cost = [](unsigned points) -> int64_t {\n\t\t// Number of 192-byte points.\n\t\treturn (Revision < EVMC_ISTANBUL) ?\n\t\t\t(100000 + 80000 * points):\n\t\t\t(45000 + 34000 * points);\n\t};\n\n\t// NOTE this is a partial implementation for some inputs.\n\tstatic std::map<bytes, EVMPrecompileOutput> const inputOutput{\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa9\"\n\t\t\t\t\"01e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c\"\n\t\t\t\t\"198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2\"\n\t\t\t\t\"1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed\"\n\t\t\t\t\"090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b\"\n\t\t\t\t\"12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000001\"\n\t\t\t\t\"30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45\"\n\t\t\t\t\"0a09ccf561b55fd99d1c1208dee1162457b57ac5af3759d50671e510e428b2a1\"\n\t\t\t\t\"2e539c423b302d13f4e5773c603948eaf5db5df8ae8a9a9113708390a06410d8\"\n\t\t\t\t\"19b763513924a736e4eebd0d78c91c1bc1d657fee4214057d21414011cfcc763\"\n\t\t\t\t\"2f8d9f9ab83727c77a2fec063cb7b6e5eb23044ccf535ad49d46d394fb6f6bf6\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000000000000000000000000000000000000000000001\"),\n\t\t\t\tcalc_cost(2)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000001\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000002\"\n\t\t\t\t\"198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2\"\n\t\t\t\t\"1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed\"\n\t\t\t\t\"090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b\"\n\t\t\t\t\"12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa\"\n\t\t\t\t\"0000000000000000000000000000000000000000000000000000000000000001\"\n\t\t\t\t\"30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45\"\n\t\t\t\t\"198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2\"\n\t\t\t\t\"1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed\"\n\t\t\t\t\"090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b\"\n\t\t\t\t\"12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000000000000000000000000000000000000000000001\"),\n\t\t\t\tcalc_cost(2)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59\"\n\t\t\t\t\"3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41\"\n\t\t\t\t\"209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7\"\n\t\t\t\t\"04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678\"\n\t\t\t\t\"2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d\"\n\t\t\t\t\"120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550\"\n\t\t\t\t\"111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c\"\n\t\t\t\t\"2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411\"\n\t\t\t\t\"198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2\"\n\t\t\t\t\"1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed\"\n\t\t\t\t\"090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b\"\n\t\t\t\t\"12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000000000000000000000000000000000000000000001\"),\n\t\t\t\tcalc_cost(2)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02\"\n\t\t\t\t\"03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84\"\n\t\t\t\t\"1213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee\"\n\t\t\t\t\"2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f\"\n\t\t\t\t\"21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237\"\n\t\t\t\t\"096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f\"\n\t\t\t\t\"06967a1237ebfeca9aaae0d6d0bab8e28c198c5a339ef8a2407e31cdac516db9\"\n\t\t\t\t\"22160fa257a5fd5b280642ff47b65eca77e626cb685c84fa6d3b6882a283ddd1\"\n\t\t\t\t\"198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2\"\n\t\t\t\t\"1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed\"\n\t\t\t\t\"090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b\"\n\t\t\t\t\"12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000000000000000000000000000000000000000000001\"),\n\t\t\t\tcalc_cost(2)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"0f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd2\"\n\t\t\t\t\"16da2f5cb6be7a0aa72c440c53c9bbdfec6c36c7d515536431b3a865468acbba\"\n\t\t\t\t\"2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb\"\n\t\t\t\t\"01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3\"\n\t\t\t\t\"14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713\"\n\t\t\t\t\"178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590\"\n\t\t\t\t\"1b9e027bd5cfc2cb5db82d4dc9677ac795ec500ecd47deee3b5da006d6d049b8\"\n\t\t\t\t\"11d7511c78158de484232fc68daf8a45cf217d1c2fae693ff5871e8752d73b21\"\n\t\t\t\t\"198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2\"\n\t\t\t\t\"1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed\"\n\t\t\t\t\"090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b\"\n\t\t\t\t\"12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000000000000000000000000000000000000000000001\"),\n\t\t\t\tcalc_cost(2)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"2f2ea0b3da1e8ef11914acf8b2e1b32d99df51f5f4f206fc6b947eae860eddb6\"\n\t\t\t\t\"068134ddb33dc888ef446b648d72338684d678d2eb2371c61a50734d78da4b72\"\n\t\t\t\t\"25f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb1\"\n\t\t\t\t\"22acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d\"\n\t\t\t\t\"065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf68\"\n\t\t\t\t\"06d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb\"\n\t\t\t\t\"186bac5188a98c45e6016873d107f5cd131f3a3e339d0375e58bd6219347b008\"\n\t\t\t\t\"122ae2b09e539e152ec5364e7e2204b03d11d3caa038bfc7cd499f8176aacbee\"\n\t\t\t\t\"1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e\"\n\t\t\t\t\"283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39\"\n\t\t\t\t\"140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e\"\n\t\t\t\t\"0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd4\"\n\t\t\t\t\"15794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f21\"\n\t\t\t\t\"1b88da1679b0b64a63b7e0e7bfe52aae524f73a55be7fe70c7e9bfc94b4cf0da\"\n\t\t\t\t\"1213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee\"\n\t\t\t\t\"2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f\"\n\t\t\t\t\"21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237\"\n\t\t\t\t\"096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000000000000000000000000000000000000000000001\"),\n\t\t\t\tcalc_cost(3)\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tfromHex(\n\t\t\t\t\"20a754d2071d4d53903e3b31a7e98ad6882d58aec240ef981fdf0a9d22c5926a\"\n\t\t\t\t\"29c853fcea789887315916bbeb89ca37edb355b4f980c9a12a94f30deeed3021\"\n\t\t\t\t\"1213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee\"\n\t\t\t\t\"2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f\"\n\t\t\t\t\"21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237\"\n\t\t\t\t\"096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f\"\n\t\t\t\t\"1abb4a25eb9379ae96c84fff9f0540abcfc0a0d11aeda02d4f37e4baf74cb0c1\"\n\t\t\t\t\"1073b3ff2cdbb38755f8691ea59e9606696b3ff278acfc098fa8226470d03869\"\n\t\t\t\t\"217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac29\"\n\t\t\t\t\"0a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c\"\n\t\t\t\t\"26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a9855\"\n\t\t\t\t\"2fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d7\"\n\t\t\t\t\"0f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd2\"\n\t\t\t\t\"198a1f162a73261f112401aa2db79c7dab1533c9935c77290a6ce3b191f2318d\"\n\t\t\t\t\"198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2\"\n\t\t\t\t\"1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed\"\n\t\t\t\t\"090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b\"\n\t\t\t\t\"12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa\"\n\t\t\t),\n\t\t\t{\n\t\t\t\tfromHex(\"0000000000000000000000000000000000000000000000000000000000000001\"),\n\t\t\t\tcalc_cost(3)\n\t\t\t}\n\t\t}\n\t};\n\n\treturn precompileGeneric(_message, inputOutput);\n}\n\nevmc::Result EVMHost::precompileBlake2f(evmc_message const&) noexcept\n{\n\t// TODO implement\n\treturn resultWithFailure();\n}\n\nevmc::Result EVMHost::precompileGeneric(\n\tevmc_message const& _message,\n\tstd::map<bytes, EVMPrecompileOutput> const& _inOut,\n\tbool _ignoresTrailingInput\n) noexcept\n{\n\tsize_t meaningfulInputSize = _message.input_size;\n\tif (_ignoresTrailingInput && !_inOut.empty())\n\t{\n\t\t// _ignoresTrailingInput only implemented for the case where all inputs have same size.\n\t\t// Simpler to implement and it's all we need for now.\n\t\tfor (auto const& [input, output]: _inOut)\n\t\t\tsolAssert(input.size() == _inOut.begin()->first.size());\n\n\t\t// If there is more input that expected, precompiles tend to simply ignore it.\n\t\tmeaningfulInputSize = std::min(_message.input_size, _inOut.begin()->first.size());\n\t}\n\n\tbytes input(_message.input_data, _message.input_data + meaningfulInputSize);\n\tif (_inOut.count(input))\n\t{\n\t\tauto const& ret = _inOut.at(input);\n\t\treturn resultWithGas(_message.gas, ret.gas_used, ret.output);\n\t}\n\telse\n\t\t// FIXME: We're in a noexcept function; this will result in terminate() and then abort().\n\t\t// Still better than nothing - can't be mistaken for revert and Boost will report test name.\n\t\tsolThrow(\n\t\t\tException,\n\t\t\t\"Test output for a precompile not defined for input: \" + toHex(input, HexPrefix::Add)\n\t\t);\n}\n\nevmc::Result EVMHost::resultWithFailure() noexcept\n{\n\tevmc::Result result;\n\tresult.status_code = EVMC_FAILURE;\n\treturn result;\n}\n\nevmc::Result EVMHost::resultWithGas(\n\tint64_t gas_limit,\n\tint64_t gas_required,\n\tbytes const& _data\n) noexcept\n{\n\tevmc::Result result;\n\tif (gas_limit < gas_required)\n\t{\n\t\tresult.status_code = EVMC_OUT_OF_GAS;\n\t\tresult.gas_left = 0;\n\t}\n\telse\n\t{\n\t\tresult.status_code = EVMC_SUCCESS;\n\t\tresult.gas_left = gas_limit - gas_required;\n\t}\n\tresult.output_data = _data.empty() ? nullptr : _data.data();\n\tresult.output_size = _data.size();\n\treturn result;\n}\n\nStorageMap const& EVMHost::get_address_storage(evmc::address const& _addr)\n{\n\tsoltestAssert(account_exists(_addr), \"Account does not exist.\");\n\treturn accounts[_addr].storage;\n}\n\nstd::string EVMHostPrinter::state()\n{\n\t// Print state and execution trace.\n\tif (m_host.account_exists(m_account))\n\t{\n\t\tstorage();\n\t\tbalance();\n\t}\n\telse\n\t\tselfdestructRecords();\n\n\tcallRecords();\n\treturn m_stateStream.str();\n}\n\nvoid EVMHostPrinter::storage()\n{\n\tfor (auto const& [slot, value]: m_host.get_address_storage(m_account))\n\t\tif (m_host.get_storage(m_account, slot))\n\t\t\tm_stateStream << \"  \"\n\t\t\t\t<< m_host.convertFromEVMC(slot)\n\t\t\t\t<< \": \"\n\t\t\t\t<< m_host.convertFromEVMC(value.current)\n\t\t\t\t<< std::endl;\n}\n\nvoid EVMHostPrinter::balance()\n{\n\tm_stateStream << \"BALANCE \"\n\t\t<< m_host.convertFromEVMC(m_host.get_balance(m_account))\n\t\t<< std::endl;\n}\n\nvoid EVMHostPrinter::selfdestructRecords()\n{\n\tfor (auto const& record: m_host.recorded_selfdestructs)\n\t\tfor (auto const& beneficiary: record.second)\n\t\t\tm_stateStream << \"SELFDESTRUCT\"\n\t\t\t\t<< \" BENEFICIARY \"\n\t\t\t\t<< m_host.convertFromEVMC(beneficiary)\n\t\t\t\t<< std::endl;\n}\n\nvoid EVMHostPrinter::callRecords()\n{\n\tstatic auto constexpr callKind = [](evmc_call_kind _kind) -> std::string\n\t{\n\t\tswitch (_kind)\n\t\t{\n\t\t\tcase evmc_call_kind::EVMC_CALL:\n\t\t\t\treturn \"CALL\";\n\t\t\tcase evmc_call_kind::EVMC_DELEGATECALL:\n\t\t\t\treturn \"DELEGATECALL\";\n\t\t\tcase evmc_call_kind::EVMC_CALLCODE:\n\t\t\t\treturn \"CALLCODE\";\n\t\t\tcase evmc_call_kind::EVMC_CREATE:\n\t\t\t\treturn \"CREATE\";\n\t\t\tcase evmc_call_kind::EVMC_CREATE2:\n\t\t\t\treturn \"CREATE2\";\n\t\t\tcase evmc_call_kind::EVMC_EOFCREATE:\n\t\t\t\treturn \"EOFCREATE\";\n\t\t}\n\t\tunreachable();\n\t};\n\n\tfor (auto const& record: m_host.recorded_calls)\n\t\tm_stateStream << callKind(record.kind)\n\t\t\t<< \" VALUE \"\n\t\t\t<< m_host.convertFromEVMC(record.value)\n\t\t\t<< std::endl;\n}\n"
  },
  {
    "path": "test/EVMHost.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * EVM execution host, i.e. component that implements a simulated Ethereum blockchain\n * for testing purposes.\n */\n\n#pragma once\n\n#include <test/evmc/mocked_host.hpp>\n#include <test/evmc/evmc.hpp>\n#include <test/evmc/evmc.h>\n\n#include <liblangutil/EVMVersion.h>\n\n#include <libsolutil/FixedHash.h>\n\n#include <boost/filesystem.hpp>\n\n#include<unordered_set>\n\nnamespace solidity::test\n{\nusing Address = util::h160;\nusing StorageMap = std::map<evmc::bytes32, evmc::StorageValue>;\n\nstruct EVMPrecompileOutput {\n\tbytes const output;\n\tint64_t gas_used;\n};\n\nclass EVMHost: public evmc::MockedHost\n{\npublic:\n\t// Verbatim features of MockedHost.\n\tusing MockedHost::account_exists;\n\tusing MockedHost::get_storage;\n\tusing MockedHost::set_storage;\n\tusing MockedHost::get_balance;\n\tusing MockedHost::get_code_size;\n\tusing MockedHost::get_code_hash;\n\tusing MockedHost::copy_code;\n\tusing MockedHost::get_tx_context;\n\tusing MockedHost::emit_log;\n\tusing MockedHost::access_account;\n\tusing MockedHost::access_storage;\n\n\t// Modified features of MockedHost.\n\tbool selfdestruct(evmc::address const& _addr, evmc::address const& _beneficiary) noexcept final;\n\tevmc::Result call(evmc_message const& _message) noexcept final;\n\tevmc::bytes32 get_block_hash(int64_t number) const noexcept final;\n\n\t// Solidity testing specific features.\n\n\t/// Tries to dynamically load an evmc vm supporting evm1 and caches the loaded VM.\n\t/// @returns vmc::VM(nullptr) on failure.\n\tstatic evmc::VM& getVM(std::string const& _path = {});\n\n\t/// Tries to load all defined evmc vm shared libraries.\n\t/// @param _vmPaths paths to multiple evmc shared libraries.\n\t/// @throw Exception if multiple evm1 vms where loaded.\n\t/// @returns true, if an evmc vm supporting evm1 was loaded properly,\n\tstatic bool checkVmPaths(std::vector<boost::filesystem::path> const& _vmPaths);\n\n\texplicit EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm);\n\n\t/// Reset entire state (including accounts).\n\tvoid reset();\n\n\t/// Start new block.\n\tvoid newBlock()\n\t{\n\t\ttx_context.block_number++;\n\t\ttx_context.block_timestamp += 15;\n\t\trecorded_logs.clear();\n\t\tnewTransactionFrame();\n\t}\n\n\t/// @returns contents of storage at @param _addr.\n\tStorageMap const& get_address_storage(evmc::address const& _addr);\n\n\tu256 totalCodeDepositGas() const { return m_totalCodeDepositGas; }\n\n\tstatic Address convertFromEVMC(evmc::address const& _addr);\n\tstatic evmc::address convertToEVMC(Address const& _addr);\n\tstatic util::h256 convertFromEVMC(evmc::bytes32 const& _data);\n\tstatic evmc::bytes32 convertToEVMC(util::h256 const& _data);\nprivate:\n\t/// Transfer value between accounts. Checks for sufficient balance.\n\tvoid transfer(evmc::MockedAccount& _sender, evmc::MockedAccount& _recipient, u256 const& _value) noexcept;\n\n\t/// Start a new transaction frame.\n\t/// This will perform selfdestructs, apply storage status changes across all accounts,\n\t/// and clear account/storage access indicator for EIP-2929.\n\tvoid newTransactionFrame();\n\n\t/// Records calls made via @param _message.\n\tvoid recordCalls(evmc_message const& _message) noexcept;\n\n\tstatic evmc::Result precompileECRecover(evmc_message const& _message) noexcept;\n\tstatic evmc::Result precompileSha256(evmc_message const& _message) noexcept;\n\tstatic evmc::Result precompileRipeMD160(evmc_message const& _message) noexcept;\n\tstatic evmc::Result precompileIdentity(evmc_message const& _message) noexcept;\n\tstatic evmc::Result precompileModExp(evmc_message const& _message) noexcept;\n\ttemplate <evmc_revision Revision>\n\tstatic evmc::Result precompileALTBN128G1Add(evmc_message const& _message) noexcept;\n\ttemplate <evmc_revision Revision>\n\tstatic evmc::Result precompileALTBN128G1Mul(evmc_message const& _message) noexcept;\n\ttemplate <evmc_revision Revision>\n\tstatic evmc::Result precompileALTBN128PairingProduct(evmc_message const& _message) noexcept;\n\tstatic evmc::Result precompileBlake2f(evmc_message const& _message) noexcept;\n\t/// Generic implementation of a precompile for testing, with hard-coded answers for hard-coded inputs.\n\t/// @param _message EVM message to handle.\n\t/// @param _inOut Hard-coded inputs and corresponding outputs to be returned.\n\t/// @param _ignoresTrailingInput Enable if the precompile only cares about the initial part of\n\t///     its input and works exactly the same, regardless of what's in the remaining part. The message will\n\t///     be considered a match for a test input even if it's longer.\n\tstatic evmc::Result precompileGeneric(\n\t\tevmc_message const& _message,\n\t\tstd::map<bytes, EVMPrecompileOutput> const& _inOut,\n\t\tbool _ignoresTrailingInput = false\n\t) noexcept;\n\t/// @returns a result object with gas usage and result data taken from @a _data.\n\t/// The outcome will be a failure if the limit < required.\n\t/// @note The return value is only valid as long as @a _data is alive!\n\tstatic evmc::Result resultWithGas(int64_t gas_limit, int64_t gas_required, bytes const& _data) noexcept;\n\tstatic evmc::Result resultWithFailure() noexcept;\n\n\tevmc::VM& m_vm;\n\t/// EVM version requested by the testing tool\n\tlangutil::EVMVersion m_evmVersion;\n\t/// EVM version requested from EVMC (matches the above)\n\tevmc_revision m_evmRevision;\n\n\t/// Store the accounts that have been created in the current transaction.\n\tstd::unordered_set<evmc::address> m_newlyCreatedAccounts;\n\n\t/// The part of the total cost of the current transaction that paid for the code deposits.\n\t/// I.e. GAS_CODE_DEPOSIT times the total size of deployed code of all newly created contracts,\n\t/// including the current contract itself if it was a creation transaction.\n\tu256 m_totalCodeDepositGas;\n};\n\nclass EVMHostPrinter\n{\npublic:\n\t/// Constructs a host printer object for state at @param _address.\n\texplicit EVMHostPrinter(EVMHost& _host, evmc::address _address):\n\t\tm_host(_host),\n\t\tm_account(_address)\n\t{}\n\t/// @returns state at account maintained by host.\n\tstd::string state();\nprivate:\n\t/// Outputs storage at account to stateStream.\n\tvoid storage();\n\t/// Outputs call records for account to stateStream.\n\tvoid callRecords();\n\t/// Outputs balance of account to stateStream.\n\tvoid balance();\n\t/// Outputs self-destruct record for account to stateStream.\n\tvoid selfdestructRecords();\n\n\tstd::ostringstream m_stateStream;\n\tEVMHost& m_host;\n\tevmc::address m_account;\n};\n\n}\n"
  },
  {
    "path": "test/ExecutionFramework.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2016\n * Framework for executing contracts and testing them using RPC.\n */\n\n#include <test/ExecutionFramework.h>\n\n#include <test/EVMHost.h>\n\n#include <test/evmc/evmc.hpp>\n\n#include <test/libsolidity/util/SoltestTypes.h>\n\n#include <libsolutil/CommonIO.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <boost/test/framework.hpp>\n#include <boost/algorithm/string/replace.hpp>\n#include <range/v3/range.hpp>\n#include <range/v3/view/transform.hpp>\n\n#include <cstdlib>\n#include <limits>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::test;\nusing namespace solidity::frontend::test;\n\nExecutionFramework::ExecutionFramework():\n\tExecutionFramework(solidity::test::CommonOptions::get().evmVersion(), solidity::test::CommonOptions::get().vmPaths)\n{\n}\n\nExecutionFramework::ExecutionFramework(langutil::EVMVersion _evmVersion, std::vector<boost::filesystem::path> const& _vmPaths):\n\tm_evmVersion(_evmVersion),\n\tm_optimiserSettings(solidity::frontend::OptimiserSettings::minimal()),\n\tm_showMessages(solidity::test::CommonOptions::get().showMessages),\n\tm_vmPaths(_vmPaths)\n{\n\tif (solidity::test::CommonOptions::get().optimize)\n\t\tm_optimiserSettings = solidity::frontend::OptimiserSettings::standard();\n\tselectVM(evmc_capabilities::EVMC_CAPABILITY_EVM1);\n}\n\nvoid ExecutionFramework::selectVM(evmc_capabilities _cap)\n{\n\tm_evmcHost.reset();\n\tfor (auto const& path: m_vmPaths)\n\t{\n\t\tevmc::VM& vm = EVMHost::getVM(path.string());\n\t\tif (vm.has_capability(_cap))\n\t\t{\n\t\t\tm_evmcHost = std::make_unique<EVMHost>(m_evmVersion, vm);\n\t\t\tbreak;\n\t\t}\n\t}\n\tsolAssert(m_evmcHost != nullptr, \"\");\n\treset();\n}\n\nvoid ExecutionFramework::reset()\n{\n\tm_evmcHost->reset();\n\tfor (size_t i = 0; i < 10; i++)\n\t\tm_evmcHost->accounts[EVMHost::convertToEVMC(account(i))].balance =\n\t\t\tEVMHost::convertToEVMC(u256(1) << 100);\n}\n\nstd::pair<bool, std::string> ExecutionFramework::compareAndCreateMessage(\n\tbytes const& _result,\n\tbytes const& _expectation\n)\n{\n\tif (_result == _expectation)\n\t\treturn std::make_pair(true, std::string{});\n\tstd::string message =\n\t\t\t\"Invalid encoded data\\n\"\n\t\t\t\"   Result                                                           Expectation\\n\";\n\tauto resultHex = boost::replace_all_copy(util::toHex(_result), \"0\", \".\");\n\tauto expectedHex = boost::replace_all_copy(util::toHex(_expectation), \"0\", \".\");\n\tfor (size_t i = 0; i < std::max(resultHex.size(), expectedHex.size()); i += 0x40)\n\t{\n\t\tstd::string result{i >= resultHex.size() ? std::string{} : resultHex.substr(i, 0x40)};\n\t\tstd::string expected{i > expectedHex.size() ? std::string{} : expectedHex.substr(i, 0x40)};\n\t\tmessage +=\n\t\t\t(result == expected ? \"   \" : \" X \") +\n\t\t\tresult +\n\t\t\tstd::string(0x41 - result.size(), ' ') +\n\t\t\texpected +\n\t\t\t\"\\n\";\n\t}\n\treturn make_pair(false, message);\n}\n\nbytes ExecutionFramework::panicData(util::PanicCode _code)\n{\n\treturn\n\t\tm_evmVersion.supportsReturndata() ?\n\t\ttoCompactBigEndian(selectorFromSignatureU32(\"Panic(uint256)\"), 4) + encode(u256(static_cast<unsigned>(_code))) :\n\t\tbytes();\n}\n\nu256 ExecutionFramework::gasLimit() const\n{\n\treturn {m_evmcHost->tx_context.block_gas_limit};\n}\n\nu256 ExecutionFramework::gasPrice() const\n{\n\t// here and below we use \"return u256{....}\" instead of just \"return {....}\"\n\t// to please MSVC and avoid unexpected\n\t// warning C4927 : illegal conversion; more than one user - defined conversion has been implicitly applied\n\treturn u256{EVMHost::convertFromEVMC(m_evmcHost->tx_context.tx_gas_price)};\n}\n\nu256 ExecutionFramework::blockHash(u256 const& _number) const\n{\n\treturn u256{EVMHost::convertFromEVMC(\n\t\tm_evmcHost->get_block_hash(static_cast<int64_t>(_number & std::numeric_limits<uint64_t>::max()))\n\t)};\n}\n\nu256 ExecutionFramework::blockNumber() const\n{\n\treturn m_evmcHost->tx_context.block_number;\n}\n\nvoid ExecutionFramework::sendMessage(bytes const& _bytecode, bytes const& _arguments, bool _isCreation, u256 const& _value)\n{\n\tauto const eof = _bytecode.size() > 1 && _bytecode[0] == 0xef && _bytecode[1] == 0x00;\n\tm_evmcHost->newBlock();\n\n\tauto const data = _bytecode + _arguments;\n\n\tif (m_showMessages)\n\t{\n\t\tif (_isCreation)\n\t\t\tstd::cout << \"CREATE \" << m_sender.hex() << \":\" << std::endl;\n\t\telse\n\t\t\tstd::cout << \"CALL   \" << m_sender.hex() << \" -> \" << m_contractAddress.hex() << \":\" << std::endl;\n\t\tif (_value > 0)\n\t\t\tstd::cout << \" value: \" << _value << std::endl;\n\t\tstd::cout << \" in:      \" << util::toHex(data) << std::endl;\n\t}\n\tevmc_message message{};\n\tmessage.input_data = eof ? _arguments.data() : data.data();\n\tmessage.input_size = eof ? _arguments.size() : data.size();\n\tif (eof)\n\t{\n\t\tmessage.code = _bytecode.data();\n\t\tmessage.code_size = _bytecode.size();\n\t}\n\tmessage.sender = EVMHost::convertToEVMC(m_sender);\n\tmessage.value = EVMHost::convertToEVMC(_value);\n\n\tif (_isCreation)\n\t{\n\t\tmessage.kind = eof ? EVMC_EOFCREATE : EVMC_CREATE;\n\t\tmessage.recipient = {};\n\t\tmessage.code_address = {};\n\t}\n\telse\n\t{\n\t\tmessage.kind = EVMC_CALL;\n\t\tmessage.recipient = EVMHost::convertToEVMC(m_contractAddress);\n\t\tmessage.code_address = message.recipient;\n\t}\n\n\tmessage.gas = InitialGas.convert_to<int64_t>();\n\n\tevmc::Result result = m_evmcHost->call(message);\n\n\tm_output = bytes(result.output_data, result.output_data + result.output_size);\n\tif (_isCreation)\n\t\tm_contractAddress = EVMHost::convertFromEVMC(result.create_address);\n\n\tunsigned const refundRatio = (m_evmVersion >= langutil::EVMVersion::london() ? 5 : 2);\n\tauto const totalGasUsed = InitialGas - result.gas_left;\n\tauto const gasRefund = std::min(u256(result.gas_refund), totalGasUsed / refundRatio);\n\n\tm_gasUsed = totalGasUsed - gasRefund;\n\tm_gasUsedForCodeDeposit = m_evmcHost->totalCodeDepositGas();\n\tm_transactionSuccessful = (result.status_code == EVMC_SUCCESS);\n\n\tif (m_showMessages)\n\t{\n\t\tstd::cout << \" out:                       \" << util::toHex(m_output) << std::endl;\n\t\tstd::cout << \" result:                    \" << static_cast<size_t>(result.status_code) << std::endl;\n\t\tstd::cout << \" gas used:                  \" << m_gasUsed.str() << std::endl;\n\t\tstd::cout << \" gas used (without refund): \" << totalGasUsed.str() << std::endl;\n\t\tstd::cout << \"     code deposits only:    \" << m_gasUsedForCodeDeposit.str() << std::endl;\n\t\tstd::cout << \" gas refund (total):        \" << result.gas_refund << std::endl;\n\t\tstd::cout << \" gas refund (bound):        \" << gasRefund.str() << std::endl;\n\t}\n}\n\nvoid ExecutionFramework::sendEther(h160 const& _addr, u256 const& _amount)\n{\n\tm_evmcHost->newBlock();\n\n\tif (m_showMessages)\n\t{\n\t\tstd::cout << \"SEND_ETHER   \" << m_sender.hex() << \" -> \" << _addr.hex() << \":\" << std::endl;\n\t\tif (_amount > 0)\n\t\t\tstd::cout << \" value: \" << _amount << std::endl;\n\t}\n\tevmc_message message{};\n\tmessage.sender = EVMHost::convertToEVMC(m_sender);\n\tmessage.value = EVMHost::convertToEVMC(_amount);\n\tmessage.kind = EVMC_CALL;\n\tmessage.recipient = EVMHost::convertToEVMC(_addr);\n\tmessage.code_address = message.recipient;\n\tmessage.gas = InitialGas.convert_to<int64_t>();\n\n\tm_evmcHost->call(message);\n}\n\nsize_t ExecutionFramework::currentTimestamp()\n{\n\treturn static_cast<size_t>(m_evmcHost->tx_context.block_timestamp);\n}\n\nsize_t ExecutionFramework::blockTimestamp(u256 _block)\n{\n\tif (_block > blockNumber())\n\t\treturn 0;\n\telse\n\t\treturn static_cast<size_t>((currentTimestamp() / blockNumber()) * _block);\n}\n\nh160 ExecutionFramework::account(size_t _idx)\n{\n\treturn h160(h256(u256{\"0x1212121212121212121212121212120000000012\"} + _idx * 0x1000), h160::AlignRight);\n}\n\nbool ExecutionFramework::addressHasCode(h160 const& _addr) const\n{\n\treturn m_evmcHost->get_code_size(EVMHost::convertToEVMC(_addr)) != 0;\n}\n\nsize_t ExecutionFramework::numLogs() const\n{\n\treturn m_evmcHost->recorded_logs.size();\n}\n\nsize_t ExecutionFramework::numLogTopics(size_t _logIdx) const\n{\n\treturn m_evmcHost->recorded_logs.at(_logIdx).topics.size();\n}\n\nh256 ExecutionFramework::logTopic(size_t _logIdx, size_t _topicIdx) const\n{\n\treturn EVMHost::convertFromEVMC(m_evmcHost->recorded_logs.at(_logIdx).topics.at(_topicIdx));\n}\n\nh160 ExecutionFramework::logAddress(size_t _logIdx) const\n{\n\treturn EVMHost::convertFromEVMC(m_evmcHost->recorded_logs.at(_logIdx).creator);\n}\n\nbytes ExecutionFramework::logData(size_t _logIdx) const\n{\n\tauto const& data = m_evmcHost->recorded_logs.at(_logIdx).data;\n\t// TODO: Return a copy of log data, because this is expected from REQUIRE_LOG_DATA(),\n\t//       but reference type like string_view would be preferable.\n\treturn {data.begin(), data.end()};\n}\n\nu256 ExecutionFramework::balanceAt(h160 const& _addr) const\n{\n\treturn u256(EVMHost::convertFromEVMC(m_evmcHost->get_balance(EVMHost::convertToEVMC(_addr))));\n}\n\nbool ExecutionFramework::storageEmpty(h160 const& _addr) const\n{\n\tconst auto it = m_evmcHost->accounts.find(EVMHost::convertToEVMC(_addr));\n\tif (it != m_evmcHost->accounts.end())\n\t{\n\t\tfor (auto const& entry: it->second.storage)\n\t\t\tif (entry.second.current != evmc::bytes32{})\n\t\t\t\treturn false;\n\t}\n\treturn true;\n}\n\nstd::vector<solidity::frontend::test::LogRecord> ExecutionFramework::recordedLogs() const\n{\n\tstd::vector<LogRecord> logs;\n\tfor (evmc::MockedHost::log_record const& logRecord: m_evmcHost->recorded_logs)\n\t\tlogs.emplace_back(\n\t\t\tEVMHost::convertFromEVMC(logRecord.creator),\n\t\t\tbytes{logRecord.data.begin(), logRecord.data.end()},\n\t\t\tlogRecord.topics | ranges::views::transform([](evmc::bytes32 _bytes) { return EVMHost::convertFromEVMC(_bytes); }) | ranges::to<std::vector>\n\t\t);\n\treturn logs;\n}\n"
  },
  {
    "path": "test/ExecutionFramework.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Framework for executing contracts and testing them using RPC.\n */\n\n#pragma once\n\n#include <test/Common.h>\n#include <test/EVMHost.h>\n\n#include <libsolidity/interface/OptimiserSettings.h>\n#include <libsolidity/interface/DebugSettings.h>\n\n#include <liblangutil/EVMVersion.h>\n\n#include <libsolutil/FunctionSelector.h>\n#include <libsolutil/ErrorCodes.h>\n\n#include <functional>\n\n#include <boost/rational.hpp>\n#include <boost/test/unit_test.hpp>\n\nnamespace solidity::frontend::test\n{\nstruct LogRecord;\n} // namespace solidity::frontend::test\n\nnamespace solidity::test\n{\nusing rational = boost::rational<bigint>;\n\n// The ether and gwei denominations; here for ease of use where needed within code.\nstatic u256 const gwei = u256(1) << 9;\nstatic u256 const ether = u256(1) << 18;\nclass ExecutionFramework\n{\n\npublic:\n\tExecutionFramework();\n\tExecutionFramework(langutil::EVMVersion _evmVersion, std::vector<boost::filesystem::path> const& _vmPaths);\n\tvirtual ~ExecutionFramework() = default;\n\n\tvirtual bytes const& compileAndRunWithoutCheck(\n\t\tstd::map<std::string, std::string> const& _sourceCode,\n\t\tu256 const& _value = 0,\n\t\tstd::string const& _contractName = \"\",\n\t\tbytes const& _arguments = {},\n\t\tstd::map<std::string, util::h160> const& _libraryAddresses = {},\n\t\tstd::optional<std::string> const& _sourceName = std::nullopt\n\t) = 0;\n\n\tbytes const& compileAndRun(\n\t\tstd::string const& _sourceCode,\n\t\tu256 const& _value = 0,\n\t\tstd::string const& _contractName = \"\",\n\t\tbytes const& _arguments = {},\n\t\tstd::map<std::string, util::h160> const& _libraryAddresses = {}\n\t)\n\t{\n\t\tcompileAndRunWithoutCheck(\n\t\t\t{{\"\", _sourceCode}},\n\t\t\t_value,\n\t\t\t_contractName,\n\t\t\t_arguments,\n\t\t\t_libraryAddresses\n\t\t);\n\t\tBOOST_REQUIRE(m_transactionSuccessful);\n\t\tBOOST_REQUIRE(!m_output.empty());\n\t\treturn m_output;\n\t}\n\n\tbytes const& callFallbackWithValue(u256 const& _value)\n\t{\n\t\tsendMessage(bytes(), bytes(), false, _value);\n\t\treturn m_output;\n\t}\n\n\tbytes const & callFallback()\n\t{\n\t\treturn callFallbackWithValue(0);\n\t}\n\n\tbytes const& callLowLevel(bytes const& _data, u256 const& _value)\n\t{\n\t\tsendMessage(_data, bytes(), false, _value);\n\t\treturn m_output;\n\t}\n\n\tbytes const& callContractFunctionWithValueNoEncoding(std::string _sig, u256 const& _value, bytes const& _arguments)\n\t{\n\t\tsendMessage(util::selectorFromSignatureH32(_sig).asBytes(), _arguments, false, _value);\n\t\treturn m_output;\n\t}\n\n\tbytes const& callContractFunctionNoEncoding(std::string _sig, bytes const& _arguments)\n\t{\n\t\treturn callContractFunctionWithValueNoEncoding(_sig, 0, _arguments);\n\t}\n\n\ttemplate <class... Args>\n\tbytes const& callContractFunctionWithValue(std::string _sig, u256 const& _value, Args const&... _arguments)\n\t{\n\t\treturn callContractFunctionWithValueNoEncoding(_sig, _value, encodeArgs(_arguments...));\n\t}\n\n\ttemplate <class... Args>\n\tbytes const& callContractFunction(std::string _sig, Args const&... _arguments)\n\t{\n\t\treturn callContractFunctionWithValue(_sig, 0, _arguments...);\n\t}\n\n\ttemplate <class CppFunction, class... Args>\n\tvoid testContractAgainstCpp(std::string _sig, CppFunction const& _cppFunction, Args const&... _arguments)\n\t{\n\t\tbytes contractResult = callContractFunction(_sig, _arguments...);\n\t\tbytes cppResult = callCppAndEncodeResult(_cppFunction, _arguments...);\n\t\tBOOST_CHECK_MESSAGE(\n\t\t\tcontractResult == cppResult,\n\t\t\t\"Computed values do not match.\\nContract: \" +\n\t\t\t\tutil::toHex(contractResult) +\n\t\t\t\t\"\\nC++:      \" +\n\t\t\t\tutil::toHex(cppResult)\n\t\t);\n\t}\n\n\ttemplate <class CppFunction, class... Args>\n\tvoid testContractAgainstCppOnRange(std::string _sig, CppFunction const& _cppFunction, u256 const& _rangeStart, u256 const& _rangeEnd)\n\t{\n\t\tfor (u256 argument = _rangeStart; argument < _rangeEnd; ++argument)\n\t\t{\n\t\t\tbytes contractResult = callContractFunction(_sig, argument);\n\t\t\tbytes cppResult = callCppAndEncodeResult(_cppFunction, argument);\n\t\t\tBOOST_CHECK_MESSAGE(\n\t\t\t\tcontractResult == cppResult,\n\t\t\t\t\"Computed values do not match.\\nContract: \" +\n\t\t\t\t\tutil::toHex(contractResult) +\n\t\t\t\t\t\"\\nC++:      \" +\n\t\t\t\t\tutil::toHex(cppResult) +\n\t\t\t\t\t\"\\nArgument: \" +\n\t\t\t\t\tutil::toHex(encode(argument))\n\t\t\t);\n\t\t}\n\t}\n\n\tstatic std::pair<bool, std::string> compareAndCreateMessage(bytes const& _result, bytes const& _expectation);\n\n\tstatic bytes encode(bool _value) { return encode(uint8_t(_value)); }\n\tstatic bytes encode(int _value) { return encode(u256(_value)); }\n\tstatic bytes encode(size_t _value) { return encode(u256(_value)); }\n\tstatic bytes encode(char const* _value) { return encode(std::string(_value)); }\n\tstatic bytes encode(uint8_t _value) { return bytes(31, 0) + bytes{_value}; }\n\tstatic bytes encode(u256 const& _value) { return toBigEndian(_value); }\n\t/// @returns the fixed-point encoding of a rational number with a given\n\t/// number of fractional bits.\n\tstatic bytes encode(std::pair<rational, int> const& _valueAndPrecision)\n\t{\n\t\trational const& value = _valueAndPrecision.first;\n\t\tint fractionalBits = _valueAndPrecision.second;\n\t\treturn encode(u256((value.numerator() << fractionalBits) / value.denominator()));\n\t}\n\tstatic bytes encode(util::h256 const& _value) { return _value.asBytes(); }\n\tstatic bytes encode(util::h160 const& _value) { return encode(util::h256(_value, util::h256::AlignRight)); }\n\tstatic bytes encode(bytes const& _value, bool _padLeft = true)\n\t{\n\t\tbytes padding = bytes((32 - _value.size() % 32) % 32, 0);\n\t\treturn _padLeft ? padding + _value : _value + padding;\n\t}\n\tstatic bytes encode(std::string const& _value) { return encode(util::asBytes(_value), false); }\n\ttemplate <class T>\n\tstatic bytes encode(std::vector<T> const& _value)\n\t{\n\t\tbytes ret;\n\t\tfor (auto const& v: _value)\n\t\t\tret += encode(v);\n\t\treturn ret;\n\t}\n\n\ttemplate <class FirstArg, class... Args>\n\tstatic bytes encodeArgs(FirstArg const& _firstArg, Args const&... _followingArgs)\n\t{\n\t\treturn encode(_firstArg) + encodeArgs(_followingArgs...);\n\t}\n\tstatic bytes encodeArgs()\n\t{\n\t\treturn bytes();\n\t}\n\t/// @returns error returndata corresponding to the Panic(uint256) error code,\n\t/// if REVERT is supported by the current EVM version and the empty string otherwise.\n\tbytes panicData(util::PanicCode _code);\n\n\t//@todo might be extended in the future\n\ttemplate <class Arg>\n\tstatic bytes encodeDyn(Arg const& _arg)\n\t{\n\t\treturn encodeArgs(u256(0x20), u256(_arg.size()), _arg);\n\t}\n\n\tu256 gasLimit() const;\n\tu256 gasPrice() const;\n\tu256 blockHash(u256 const& _blockNumber) const;\n\tu256 blockNumber() const;\n\n\ttemplate<typename Range>\n\tstatic bytes encodeArray(bool _dynamicallySized, bool _dynamicallyEncoded, Range const& _elements)\n\t{\n\t\tbytes result;\n\t\tif (_dynamicallySized)\n\t\t\tresult += encode(u256(_elements.size()));\n\t\tif (_dynamicallyEncoded)\n\t\t{\n\t\t\tu256 offset = u256(_elements.size()) * 32;\n\t\t\tstd::vector<bytes> subEncodings;\n\t\t\tfor (auto const& element: _elements)\n\t\t\t{\n\t\t\t\tresult += encode(offset);\n\t\t\t\tsubEncodings.emplace_back(encode(element));\n\t\t\t\toffset += subEncodings.back().size();\n\t\t\t}\n\t\t\tfor (auto const& subEncoding: subEncodings)\n\t\t\t\tresult += subEncoding;\n\t\t}\n\t\telse\n\t\t\tfor (auto const& element: _elements)\n\t\t\t\tresult += encode(element);\n\t\treturn result;\n\t}\n\n\tutil::h160 setAccount(size_t _accountNumber)\n\t{\n\t\tm_sender = account(_accountNumber);\n\t\treturn m_sender;\n\t}\n\n\tsize_t numLogs() const;\n\tsize_t numLogTopics(size_t _logIdx) const;\n\tutil::h256 logTopic(size_t _logIdx, size_t _topicIdx) const;\n\tutil::h160 logAddress(size_t _logIdx) const;\n\tbytes logData(size_t _logIdx) const;\n\nprivate:\n\ttemplate <class CppFunction, class... Args>\n\tauto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)\n\t-> typename std::enable_if<std::is_void<decltype(_cppFunction(_arguments...))>::value, bytes>::type\n\t{\n\t\t_cppFunction(_arguments...);\n\t\treturn bytes();\n\t}\n\ttemplate <class CppFunction, class... Args>\n\tauto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)\n\t-> typename std::enable_if<!std::is_void<decltype(_cppFunction(_arguments...))>::value, bytes>::type\n\t{\n\t\treturn encode(_cppFunction(_arguments...));\n\t}\n\nprotected:\n\tu256 const InitialGas = 100000000;\n\n\tvoid selectVM(evmc_capabilities _cap = evmc_capabilities::EVMC_CAPABILITY_EVM1);\n\tvoid reset();\n\n\tvoid sendMessage(bytes const& _bytecode, bytes const& _argument, bool _isCreation, u256 const& _value = 0);\n\tvoid sendEther(util::h160 const& _to, u256 const& _value);\n\tsize_t currentTimestamp();\n\tsize_t blockTimestamp(u256 _number);\n\n\t/// @returns the (potentially newly created) _ith address.\n\tutil::h160 account(size_t _i);\n\n\tu256 balanceAt(util::h160 const& _addr) const;\n\tbool storageEmpty(util::h160 const& _addr) const;\n\tbool addressHasCode(util::h160 const& _addr) const;\n\n\tstd::vector<frontend::test::LogRecord> recordedLogs() const;\n\n\tlangutil::EVMVersion m_evmVersion;\n\tsolidity::frontend::RevertStrings m_revertStrings = solidity::frontend::RevertStrings::Default;\n\tsolidity::frontend::OptimiserSettings m_optimiserSettings = solidity::frontend::OptimiserSettings::minimal();\n\tbool m_showMessages = false;\n\tstd::unique_ptr<EVMHost> m_evmcHost;\n\n\tstd::vector<boost::filesystem::path> m_vmPaths;\n\n\tbool m_transactionSuccessful = true;\n\tutil::h160 m_sender = account(0);\n\tutil::h160 m_contractAddress;\n\tbytes m_output;\n\n\t/// Total gas used by the transaction, after refund.\n\tu256 m_gasUsed;\n\n\t/// The portion of @a m_gasUsed spent on code deposits of newly created contracts.\n\t/// May exceed @a m_gasUsed in rare corner cases due to refunds.\n\tu256 m_gasUsedForCodeDeposit;\n};\n\n#define ABI_CHECK(result, expectation) do { \\\n\tauto abiCheckResult = ExecutionFramework::compareAndCreateMessage((result), (expectation)); \\\n\tBOOST_CHECK_MESSAGE(abiCheckResult.first, abiCheckResult.second); \\\n} while (0)\n\n\n} // end namespaces\n"
  },
  {
    "path": "test/FilesystemUtils.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/FilesystemUtils.h>\n\n#include <test/libsolidity/util/SoltestErrors.h>\n\n#include <fstream>\n\nusing namespace solidity;\nusing namespace solidity::test;\n\nvoid solidity::test::createFilesWithParentDirs(std::set<boost::filesystem::path> const& _paths, std::string const& _content)\n{\n\tfor (boost::filesystem::path const& path: _paths)\n\t{\n\t\tif (!path.parent_path().empty())\n\t\t\tboost::filesystem::create_directories(path.parent_path());\n\n\t\t// Use binary mode to avoid line ending conversion on Windows.\n\t\tstd::ofstream newFile(path.string(), std::ofstream::binary);\n\t\tnewFile << _content;\n\n\t\tif (newFile.fail() || !boost::filesystem::exists(path))\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Failed to create an empty file: \\\"\" + path.string() + \"\\\".\"));\n\t}\n}\n\nvoid solidity::test::createFileWithContent(boost::filesystem::path const& _path, std::string const& _content)\n{\n\tif (boost::filesystem::is_regular_file(_path))\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"File already exists: \\\"\" + _path.string() + \"\\\".\"));\n\n\t// Use binary mode to avoid line ending conversion on Windows.\n\tstd::ofstream newFile(_path.string(), std::ofstream::binary);\n\tif (newFile.fail() || !boost::filesystem::is_regular_file(_path))\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Failed to create a file: \\\"\" + _path.string() + \"\\\".\"));\n\n\tnewFile << _content;\n}\n\nbool solidity::test::createSymlinkIfSupportedByFilesystem(\n\tboost::filesystem::path _targetPath,\n\tboost::filesystem::path const& _linkName,\n\tbool _directorySymlink\n)\n{\n\tboost::system::error_code symlinkCreationError;\n\n\t// NOTE: On Windows / works as a separator in a symlink target only if the target is absolute.\n\t// Convert path separators to native ones to avoid this problem.\n\t_targetPath.make_preferred();\n\n\tif (_directorySymlink)\n\t\tboost::filesystem::create_directory_symlink(_targetPath, _linkName, symlinkCreationError);\n\telse\n\t\tboost::filesystem::create_symlink(_targetPath, _linkName, symlinkCreationError);\n\n\tif (!symlinkCreationError)\n\t\treturn true;\n\telse if (\n\t\tsymlinkCreationError == boost::system::errc::not_supported ||\n\t\tsymlinkCreationError == boost::system::errc::operation_not_supported\n\t)\n\t\treturn false;\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\n\t\t\t\"Failed to create a symbolic link: \\\"\" + _linkName.string() + \"\\\"\"\n\t\t\t\" -> \" + _targetPath.string() + \"\\\".\"\n\t\t\t\" \" + symlinkCreationError.message() + \".\"\n\t\t));\n}\n"
  },
  {
    "path": "test/FilesystemUtils.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Helpers for common filesystem operations used in multiple tests.\n */\n\n#pragma once\n\n#include <boost/filesystem.hpp>\n\n#include <set>\n#include <string>\n\nnamespace solidity::test\n{\n\n/// Creates all the specified files and fills them with the specifiedcontent. Creates their parent\n/// directories if they do not exist. Throws an exception if any part of the operation does not succeed.\nvoid createFilesWithParentDirs(std::set<boost::filesystem::path> const& _paths, std::string const& _content = \"\");\n\n/// Creates a file with the exact content specified in the second argument.\n/// Throws an exception if the file already exists or if the parent directory of the file does not.\nvoid createFileWithContent(boost::filesystem::path const& _path, std::string const& _content);\n\n/// Creates a symlink between two paths.\n/// The target does not have to exist.\n/// If @p directorySymlink is true, indicate to the operating system that this is a directory\n/// symlink. On some systems (e.g. Windows) it's possible to create a non-directory symlink pointing\n/// at a directory, which makes such a symlinks unusable.\n/// @returns true if the symlink has been successfully created, false if the filesystem does not\n/// support symlinks.\n/// Throws an exception of the operation fails for a different reason.\nbool createSymlinkIfSupportedByFilesystem(\n\tboost::filesystem::path _targetPath,\n\tboost::filesystem::path const& _linkName,\n\tbool _directorySymlink\n);\n\n}\n"
  },
  {
    "path": "test/InteractiveTests.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <test/TestCase.h>\n#include <test/libsolidity/ABIJsonTest.h>\n#include <test/libsolidity/ASTJSONTest.h>\n#include <test/libsolidity/ASTPropertyTest.h>\n#include <libsolidity/FunctionDependencyGraphTest.h>\n#include <test/libsolidity/GasTest.h>\n#include <test/libsolidity/MemoryGuardTest.h>\n#include <test/libsolidity/NatspecJSONTest.h>\n#include <test/libsolidity/OptimizedIRCachingTest.h>\n#include <test/libsolidity/SyntaxTest.h>\n#include <test/libsolidity/SemanticTest.h>\n#include <test/libsolidity/SMTCheckerTest.h>\n\n#include <test/libyul/ssa/StackLayoutGeneratorTest.h>\n#include <test/libyul/ssa/StackShufflerTest.h>\n#include <test/libyul/ControlFlowGraphTest.h>\n#include <test/libyul/SSAControlFlowGraphTest.h>\n#include <test/libyul/EVMCodeTransformTest.h>\n#include <test/libyul/YulOptimizerTest.h>\n#include <test/libyul/YulInterpreterTest.h>\n#include <test/libyul/ObjectCompilerTest.h>\n#include <test/libyul/ControlFlowSideEffectsTest.h>\n#include <test/libyul/FunctionSideEffects.h>\n#include <test/libyul/StackLayoutGeneratorTest.h>\n#include <test/libyul/StackShufflingTest.h>\n#include <test/libyul/SyntaxTest.h>\n\n#include <test/libevmasm/EVMAssemblyTest.h>\n\n#include <boost/filesystem.hpp>\n\nnamespace solidity::frontend::test\n{\n\n/** Container for all information regarding a testsuite */\nstruct Testsuite\n{\n\tchar const* title;\n\tboost::filesystem::path const path;\n\tboost::filesystem::path const subpath;\n\tbool smt;\n\tbool needsVM;\n\tTestCase::TestCaseCreator testCaseCreator;\n\tstd::vector<std::string> labels{};\n};\n\n\n/// Array of testsuits that can be run interactively as well as automatically\nTestsuite const g_interactiveTestsuites[] = {\n/*\n\tTitle                           Path           Subpath                          SMT   NeedsVM Creator function */\n\t{\"EVM Assembly\",                \"libevmasm\",   \"evmAssemblyTests\",              false, false, &evmasm::test::EVMAssemblyTest::create},\n\t{\"Yul Optimizer\",               \"libyul\",      \"yulOptimizerTests\",             false, false, &yul::test::YulOptimizerTest::create},\n\t{\"Yul Interpreter\",             \"libyul\",      \"yulInterpreterTests\",           false, false, &yul::test::YulInterpreterTest::create},\n\t{\"Yul Object Compiler\",         \"libyul\",      \"objectCompiler\",                false, false, &yul::test::ObjectCompilerTest::create},\n\t{\"Yul Control Flow Graph\",      \"libyul\",      \"yulControlFlowGraph\",           false, false, &yul::test::ControlFlowGraphTest::create},\n\t{\"Yul SSA Control Flow Graph\",  \"libyul\",      \"yulSSAControlFlowGraph\",        false, false, &yul::test::SSAControlFlowGraphTest::create},\n\t{\"Yul SSA StackShuffling\",      \"libyul\",      \"ssa/stackShuffler\",             false, false, &yul::test::ssa::ShufflingTest::create},\n\t{\"Yul SSA StackLayoutGenerator\",\"libyul\",      \"ssa/stackLayoutGenerator\",      false, false, &yul::test::ssa::StackLayoutGeneratorTest::create},\n\t{\"Yul Stack Layout\",            \"libyul\",      \"yulStackLayout\",                false, false, &yul::test::StackLayoutGeneratorTest::create},\n\t{\"Yul Stack Shuffling\",         \"libyul\",      \"yulStackShuffling\",             false, false, &yul::test::StackShufflingTest::create},\n\t{\"Control Flow Side Effects\",   \"libyul\",      \"controlFlowSideEffects\",        false, false, &yul::test::ControlFlowSideEffectsTest::create},\n\t{\"Function Side Effects\",       \"libyul\",      \"functionSideEffects\",           false, false, &yul::test::FunctionSideEffects::create},\n\t{\"Yul Syntax\",                  \"libyul\",      \"yulSyntaxTests\",                false, false, &yul::test::SyntaxTest::create},\n\t{\"EVM Code Transform\",          \"libyul\",      \"evmCodeTransform\",              false, false, &yul::test::EVMCodeTransformTest::create, {\"nooptions\"}},\n\t{\"Syntax\",                      \"libsolidity\", \"syntaxTests\",                   false, false, &SyntaxTest::create},\n\t{\"Semantic\",                    \"libsolidity\", \"semanticTests\",                 false, true,  &SemanticTest::create},\n\t{\"JSON AST\",                    \"libsolidity\", \"ASTJSON\",                       false, false, &ASTJSONTest::create},\n\t{\"JSON ABI\",                    \"libsolidity\", \"ABIJson\",                       false, false, &ABIJsonTest::create},\n\t{\"JSON Natspec\",                \"libsolidity\", \"natspecJSON\",                   false, false, &NatspecJSONTest::create},\n\t{\"SMT Checker\",                 \"libsolidity\", \"smtCheckerTests\",               true,  false, &SMTCheckerTest::create},\n\t{\"Gas Estimates\",               \"libsolidity\", \"gasTests\",                      false, false, &GasTest::create},\n\t{\"Memory Guard\",                \"libsolidity\", \"memoryGuardTests\",              false, false, &MemoryGuardTest::create},\n\t{\"AST Properties\",              \"libsolidity\", \"astPropertyTests\",              false, false, &ASTPropertyTest::create},\n\t{\"Function Dependency Graph\",   \"libsolidity\", \"functionDependencyGraphTests\",  false, false, &FunctionDependencyGraphTest::create},\n\t{\"Optimized IR Caching\",        \"libsolidity\", \"optimizedIRCaching\",            false, false, &OptimizedIRCachingTest::create},\n};\n\n}\n"
  },
  {
    "path": "test/Metadata.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @date 2017\n * Metadata processing helpers.\n */\n\n#include <test/Metadata.h>\n\n#include <test/libsolidity/util/SoltestErrors.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <libsolutil/Assertions.h>\n#include <libsolutil/CommonData.h>\n\n#include <iostream>\n#include <string>\n\nnamespace solidity::test\n{\n\nbytes onlyMetadata(bytes const& _bytecode)\n{\n\tsize_t size = _bytecode.size();\n\tif (size < 5)\n\t\treturn bytes{};\n\tsize_t metadataSize = (static_cast<size_t>(_bytecode[size - 2]) << 8ul) + static_cast<size_t>(_bytecode[size - 1]);\n\tif (size < (metadataSize + 2))\n\t\treturn bytes{};\n\t// Sanity check: assume the first byte is a fixed-size CBOR array with 1, 2 or 3 entries\n\tunsigned char firstByte = _bytecode[size - metadataSize - 2];\n\tif (firstByte != 0xa1 && firstByte != 0xa2 && firstByte != 0xa3)\n\t\treturn bytes{};\n\treturn bytes(_bytecode.end() - static_cast<ptrdiff_t>(metadataSize) - 2, _bytecode.end() - 2);\n}\n\nbytes bytecodeSansMetadata(bytes const& _bytecode)\n{\n\tsize_t metadataSize = onlyMetadata(_bytecode).size();\n\tif (metadataSize == 0)\n\t\treturn bytes{};\n\treturn bytes(_bytecode.begin(), _bytecode.end() - static_cast<ptrdiff_t>(metadataSize) - 2);\n}\n\nstd::string bytecodeSansMetadata(std::string const& _bytecode)\n{\n\treturn util::toHex(bytecodeSansMetadata(fromHex(_bytecode, util::WhenError::Throw)));\n}\n\nDEV_SIMPLE_EXCEPTION(CBORException);\n\nclass TinyCBORParser\n{\npublic:\n\texplicit TinyCBORParser(bytes const& _metadata): m_pos(0), m_metadata(_metadata)\n\t{\n\t\tsolRequire((m_pos + 1) < _metadata.size(), CBORException, \"Input too short.\");\n\t}\n\tunsigned mapItemCount()\n\t{\n\t\tsolRequire(nextType() == MajorType::Map, CBORException, \"Fixed-length map expected.\");\n\t\treturn readLength();\n\t}\n\tstd::string readKey()\n\t{\n\t\treturn readString();\n\t}\n\tstd::string readValue()\n\t{\n\t\tswitch(nextType())\n\t\t{\n\t\t\tcase MajorType::ByteString:\n\t\t\t\treturn util::toHex(readBytes(readLength()));\n\t\t\tcase MajorType::TextString:\n\t\t\t\treturn readString();\n\t\t\tcase MajorType::SimpleData:\n\t\t\t{\n\t\t\t\tunsigned value = nextImmediate();\n\t\t\t\tm_pos++;\n\t\t\t\tif (value == 20)\n\t\t\t\t\treturn \"false\";\n\t\t\t\tif (value == 21)\n\t\t\t\t\treturn \"true\";\n\t\t\t\tsolUnimplemented(\"Unsupported simple value (not a boolean).\");\n\t\t\t}\n\t\t\tcase MajorType::Map:\n\t\t\t\tsolUnimplemented(\"Nested maps not supported.\");\n\t\t}\n\t\tutil::unreachable();\n\t}\nprivate:\n\tenum class MajorType\n\t{\n\t\tByteString,\n\t\tTextString,\n\t\tMap,\n\t\tSimpleData\n\t};\n\tMajorType nextType() const\n\t{\n\t\tunsigned value = (m_metadata.at(m_pos) >> 5) & 0x7;\n\t\tswitch (value)\n\t\t{\n\t\t\tcase 2: return MajorType::ByteString;\n\t\t\tcase 3: return MajorType::TextString;\n\t\t\tcase 5: return MajorType::Map;\n\t\t\tcase 7: return MajorType::SimpleData;\n\t\t\tdefault: solUnimplemented(\"Unsupported major type.\");\n\t\t}\n\t}\n\tunsigned nextImmediate() const { return m_metadata.at(m_pos) & 0x1f; }\n\tunsigned readLength()\n\t{\n\t\tunsigned length = m_metadata.at(m_pos++) & 0x1f;\n\t\tif (length < 24)\n\t\t\treturn length;\n\t\tif (length == 24)\n\t\t\treturn m_metadata.at(m_pos++);\n\t\t// Unsupported length kind. (Only by this parser.)\n\t\tsolUnimplemented(std::string(\"Unsupported length \") + std::to_string(length));\n\t}\n\tbytes readBytes(unsigned length)\n\t{\n\t\tbytes ret{m_metadata.begin() + static_cast<int>(m_pos), m_metadata.begin() + static_cast<int>(m_pos + length)};\n\t\tm_pos += length;\n\t\treturn ret;\n\t}\n\tstd::string readString()\n\t{\n\t\t// Expect a text string.\n\t\tsoltestAssert(nextType() == MajorType::TextString, \"String expected.\");\n\t\tbytes tmp{readBytes(readLength())};\n\t\treturn std::string{tmp.begin(), tmp.end()};\n\t}\n\tunsigned m_pos;\n\tbytes const& m_metadata;\n};\n\nstd::optional<std::map<std::string, std::string>> parseCBORMetadata(bytes const& _metadata)\n{\n\ttry\n\t{\n\t\tTinyCBORParser parser(_metadata);\n\t\tstd::map<std::string, std::string> ret;\n\t\tunsigned count = parser.mapItemCount();\n\t\tfor (unsigned i = 0; i < count; i++)\n\t\t{\n\t\t\tstd::string key = parser.readKey();\n\t\t\tstd::string value = parser.readValue();\n\t\t\tret[std::move(key)] = std::move(value);\n\t\t}\n\t\treturn ret;\n\t}\n\tcatch (CBORException const&)\n\t{\n\t\treturn {};\n\t}\n}\n\nbool isValidMetadata(std::string const& _serialisedMetadata)\n{\n\tJson metadata;\n\tif (!util::jsonParseStrict(_serialisedMetadata, metadata))\n\t\treturn false;\n\n\treturn isValidMetadata(metadata);\n}\n\nbool isValidMetadata(Json const& _metadata)\n{\n\tif (\n\t\t!_metadata.is_object() ||\n\t\t!_metadata.contains(\"version\") ||\n\t\t!_metadata.contains(\"language\") ||\n\t\t!_metadata.contains(\"compiler\") ||\n\t\t!_metadata.contains(\"settings\") ||\n\t\t!_metadata.contains(\"sources\") ||\n\t\t!_metadata.contains(\"output\") ||\n\t\t!_metadata[\"settings\"].contains(\"evmVersion\") ||\n\t\t!_metadata[\"settings\"].contains(\"metadata\") ||\n\t\t!_metadata[\"settings\"][\"metadata\"].contains(\"bytecodeHash\")\n\t)\n\t\treturn false;\n\n\tif (!_metadata[\"version\"].is_number() || _metadata[\"version\"] != 1)\n\t\treturn false;\n\n\tif (!_metadata[\"language\"].is_string() || _metadata[\"language\"].get<std::string>() != \"Solidity\")\n\t\treturn false;\n\n\t/// @TODO add more strict checks\n\n\treturn true;\n}\n\n} // end namespaces\n"
  },
  {
    "path": "test/Metadata.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @date 2017\n * Metadata processing helpers.\n */\n\n#include <libsolutil/CommonData.h>\n#include <libsolutil/JSON.h>\n\n#include <map>\n#include <optional>\n#include <string>\n\nnamespace solidity::test\n{\n\n/// Returns only the CBOR metadata.\nbytes onlyMetadata(bytes const& _bytecode);\n\n/// Returns the bytecode with the metadata hash stripped out.\nbytes bytecodeSansMetadata(bytes const& _bytecode);\n\n/// Returns the bytecode with the metadata hash stripped out.\n/// Throws exception on invalid hex string.\nstd::string bytecodeSansMetadata(std::string const& _bytecode);\n\n/// Parse CBOR metadata into a map. Expects the input CBOR to be a\n/// fixed length map, with each key being a string. The values\n/// are parsed as follows:\n/// - strings into strings\n/// - bytes into hex strings\n/// - booleans into \"true\"/\"false\" strings\n/// - everything else is invalid\nstd::optional<std::map<std::string, std::string>> parseCBORMetadata(bytes const& _metadata);\n\n/// Expects a serialised metadata JSON and returns true if the content is valid metadata.\nbool isValidMetadata(std::string const& _serialisedMetadata);\n\n/// Expects a deserialised metadata JSON and returns true if the content is valid metadata.\nbool isValidMetadata(Json const& _metadata);\n\n} // end namespaces\n"
  },
  {
    "path": "test/TestCase.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/Common.h>\n#include <test/TestCase.h>\n\n#include <libsolutil/AnsiColorized.h>\n#include <libsolutil/StringUtils.h>\n\n#include <boost/algorithm/string/predicate.hpp>\n\n#include <iostream>\n#include <stdexcept>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\nusing namespace solidity::util;\n\nvoid TestCase::printSettings(std::ostream& _stream, const std::string& _linePrefix, const bool)\n{\n\tauto& settings = m_reader.settings();\n\tif (settings.empty())\n\t\treturn;\n\n\t_stream << _linePrefix << \"// ====\" << std::endl;\n\tfor (auto const& setting: settings)\n\t\t_stream << _linePrefix << \"// \" << setting.first << \": \" << setting.second << std::endl;\n}\n\nvoid TestCase::printUpdatedSettings(std::ostream& _stream, std::string const& _linePrefix)\n{\n\tprintSettings(_stream, _linePrefix);\n}\n\nbool TestCase::isTestFilename(boost::filesystem::path const& _filename)\n{\n\tstd::string extension = _filename.extension().string();\n\t// NOTE: .asmjson rather than .json because JSON files that do not represent test cases exist in some test dirs.\n\treturn (extension == \".sol\" || extension == \".yul\" || extension == \".asm\" || extension == \".asmjson\" || extension == \".stack\") &&\n\t\t!_filename.string().starts_with('~') &&\n\t\t!_filename.string().starts_with('.');\n}\n\nbool TestCase::shouldRun()\n{\n\tm_reader.ensureAllSettingsRead();\n\treturn m_shouldRun;\n}\n\nvoid TestCase::expect(std::string::iterator& _it, std::string::iterator _end, std::string::value_type _c)\n{\n\tif (_it == _end || *_it != _c)\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(std::string(\"Invalid test expectation. Expected: \\\"\") + _c + \"\\\".\"));\n\t++_it;\n}\n\nvoid TestCase::printSource(std::ostream& _stream, std::string const& _linePrefix, bool const) const\n{\n\tprintPrefixed(_stream, m_source, _linePrefix);\n}\n\nvoid TestCase::printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const\n{\n\tprintPrefixed(_stream, m_obtainedResult, _linePrefix);\n}\n\nTestCase::TestResult TestCase::checkResult(std::ostream& _stream, const std::string& _linePrefix, bool const _formatted)\n{\n\tif (m_expectation != m_obtainedResult)\n\t{\n\t\tstd::string nextIndentLevel = _linePrefix + \"  \";\n\t\tutil::AnsiColorized(_stream, _formatted, {util::formatting::BOLD, util::formatting::CYAN})\n\t\t\t<< _linePrefix << \"Expected result:\" << std::endl;\n\t\t// TODO could compute a simple diff with highlighted lines\n\t\tprintPrefixed(_stream, m_expectation, nextIndentLevel);\n\t\tutil::AnsiColorized(_stream, _formatted, {util::formatting::BOLD, util::formatting::CYAN})\n\t\t\t<< _linePrefix << \"Obtained result:\" << std::endl;\n\t\tprintPrefixed(_stream, m_obtainedResult, nextIndentLevel);\n\t\treturn TestResult::Failure;\n\t}\n\treturn TestResult::Success;\n}\n\nvoid EVMVersionRestrictedTestCase::processEVMVersionSetting()\n{\n\tstd::string versionString = m_reader.stringSetting(\"EVMVersion\", \"any\");\n\tif (versionString == \"any\")\n\t\treturn;\n\n\tstd::string comparator;\n\tsize_t versionBegin = 0;\n\tfor (auto character: versionString)\n\t\tif (!isalpha(character, std::locale::classic()))\n\t\t{\n\t\t\tcomparator += character;\n\t\t\tversionBegin++;\n\t\t}\n\t\telse\n\t\t\tbreak;\n\n\tversionString = versionString.substr(versionBegin);\n\tstd::optional<langutil::EVMVersion> version;\n\tif (versionString == \"current\")\n\t\tversion = std::make_optional<langutil::EVMVersion>();\n\telse\n\t\tversion = langutil::EVMVersion::fromString(versionString);\n\tif (!version)\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error{\"Invalid EVM version: \\\"\" + versionString + \"\\\"\"});\n\n\tlangutil::EVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion();\n\tbool comparisonResult;\n\tif (comparator == \">\")\n\t\tcomparisonResult = evmVersion > version;\n\telse if (comparator == \">=\")\n\t\tcomparisonResult = evmVersion >= version;\n\telse if (comparator == \"<\")\n\t\tcomparisonResult = evmVersion < version;\n\telse if (comparator == \"<=\")\n\t\tcomparisonResult = evmVersion <= version;\n\telse if (comparator == \"=\")\n\t\tcomparisonResult = evmVersion == version;\n\telse if (comparator == \"!\")\n\t\tcomparisonResult = !(evmVersion == version);\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error{\"Invalid EVM comparator: \\\"\" + comparator + \"\\\"\"});\n\n\tif (!comparisonResult)\n\t\tm_shouldRun = false;\n}\n\nvoid EVMVersionRestrictedTestCase::processBytecodeFormatSetting()\n{\n\tstd::optional<uint8_t> eofVersion = solidity::test::CommonOptions::get().eofVersion();\n\t// EOF only available since Osaka\n\tsolAssert(!eofVersion.has_value() || solidity::test::CommonOptions::get().evmVersion().supportsEOF());\n\n\tstd::string bytecodeFormatString = m_reader.stringSetting(\"bytecodeFormat\", \"legacy,>=EOFv1\");\n\tif (bytecodeFormatString == \"legacy,>=EOFv1\" || bytecodeFormatString == \">=EOFv1,legacy\")\n\t\treturn;\n\n\t// TODO: This is naive implementation because for now we support only one EOF version.\n\tif (bytecodeFormatString == \"legacy\" && eofVersion.has_value())\n\t\tm_shouldRun = false;\n\telse if (bytecodeFormatString == \">=EOFv1\" && !eofVersion.has_value())\n\t\tm_shouldRun = false;\n\telse if (bytecodeFormatString != \"legacy\" && bytecodeFormatString != \">=EOFv1\" )\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error{\"Invalid bytecodeFormat flag: \\\"\" + bytecodeFormatString + \"\\\"\"});\n}\n\nEVMVersionRestrictedTestCase::EVMVersionRestrictedTestCase(std::string const& _filename):\n\tTestCase(_filename)\n{\n\tprocessEVMVersionSetting();\n\tprocessBytecodeFormatSetting();\n}\n"
  },
  {
    "path": "test/TestCase.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <test/TestCaseReader.h>\n\n#include <liblangutil/EVMVersion.h>\n\n#include <boost/filesystem.hpp>\n\n#include <string>\n\nnamespace solidity::frontend::test\n{\n\n/**\n * Common superclass of anything that can be run via isoltest.\n */\nclass TestCase\n{\npublic:\n\tstruct Config\n\t{\n\t\tstd::string filename;\n\t\tlangutil::EVMVersion evmVersion;\n\t\tstd::optional<uint8_t> eofVersion;\n\t\tstd::vector<boost::filesystem::path> vmPaths;\n\t\tbool enforceGasCost = false;\n\t\tu256 enforceGasCostMinValue;\n\t};\n\n\tenum class TestResult { Success, Failure, FatalError };\n\n\tusing TestCaseCreator = std::unique_ptr<TestCase>(*)(Config const&);\n\n\tvirtual ~TestCase() = default;\n\n\t/// Runs the test case.\n\t/// Outputs error messages to @arg _stream. Each line of output is prefixed with @arg _linePrefix.\n\t/// Optionally, color-coding can be enabled (if @arg _formatted is set to true).\n\t/// @returns true, if the test case succeeds, false otherwise\n\tvirtual TestResult run(std::ostream& _stream, std::string const& _linePrefix = \"\", bool const _formatted = false) = 0;\n\n\t/// Outputs the test contract to @arg _stream.\n\t/// Each line of output is prefixed with @arg _linePrefix.\n\t/// If @arg _formatted is true, color-coding may be used to indicate\n\t/// error locations in the contract, if applicable.\n\tvirtual void printSource(std::ostream &_stream, std::string const &_linePrefix = \"\", bool const _formatted = false) const;\n\t/// Outputs settings.\n\tvirtual void printSettings(std::ostream &_stream, std::string const &_linePrefix = \"\", bool const _formatted = false);\n\t/// Outputs updated settings\n\tvirtual void printUpdatedSettings(std::ostream& _stream, std::string const& _linePrefix = \"\");\n\t/// Outputs test expectations to @arg _stream that match the actual results of the test.\n\t/// Each line of output is prefixed with @arg _linePrefix.\n\tvirtual void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const;\n\n\tstatic bool isTestFilename(boost::filesystem::path const& _filename);\n\n\t/// Returns true, if the test case is supported in the current environment and false\n\t/// otherwise which causes this test to be skipped.\n\t/// This might check e.g. for restrictions on the EVM version.\n\t/// The function throws an exception if there are unread settings.\n\tbool shouldRun();\n\nprotected:\n\t// Used by ASTJSONTest, the only TestCase class with a custom parser of the test files.\n\tTestCase() = default;\n\n\tTestCase(std::string const& _filename): m_reader(_filename) {}\n\n\tstatic void expect(std::string::iterator& _it, std::string::iterator _end, std::string::value_type _c);\n\n\ttemplate<typename IteratorType>\n\tstatic void skipWhitespace(IteratorType& _it, IteratorType _end)\n\t{\n\t\twhile (_it != _end && std::isspace<char>(*_it, std::locale::classic()))\n\t\t\t++_it;\n\t}\n\n\ttemplate<typename IteratorType>\n\tstatic void skipSlashes(IteratorType& _it, IteratorType _end)\n\t{\n\t\twhile (_it != _end && *_it == '/')\n\t\t\t++_it;\n\t}\n\n\tTestCase::TestResult checkResult(std::ostream& _stream, const std::string& _linePrefix, bool const _formatted);\n\n\tstd::string m_source;\n\tstd::string m_obtainedResult;\n\tstd::string m_expectation;\n\n\tTestCaseReader m_reader;\n\tbool m_shouldRun = true;\n};\n\nclass EVMVersionRestrictedTestCase: public TestCase\n{\nprivate:\n\tvoid processEVMVersionSetting();\n\tvoid processBytecodeFormatSetting();\n\nprotected:\n\tEVMVersionRestrictedTestCase(std::string const& _filename);\n};\n\n}\n"
  },
  {
    "path": "test/TestCaseReader.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/TestCaseReader.h>\n\n#include <libsolutil/CommonIO.h>\n\n#include <boost/algorithm/string.hpp>\n#include <boost/filesystem.hpp>\n\nusing namespace solidity::frontend::test;\n\nnamespace fs = boost::filesystem;\n\nTestCaseReader::TestCaseReader(std::string const& _filename): m_fileStream(_filename), m_fileName(_filename)\n{\n\tif (!m_fileStream)\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Cannot open file: \\\"\" + _filename + \"\\\".\"));\n\tm_fileStream.exceptions(std::ios::badbit);\n\n\tstd::tie(m_sources, m_lineNumber) = parseSourcesAndSettingsWithLineNumber(m_fileStream);\n\tm_unreadSettings = m_settings;\n}\n\nTestCaseReader::TestCaseReader(std::istringstream const& _str)\n{\n\tstd::tie(m_sources, m_lineNumber) = parseSourcesAndSettingsWithLineNumber(\n\t\tstatic_cast<std::istream&>(const_cast<std::istringstream&>(_str))\n\t);\n}\n\nstd::string const& TestCaseReader::source() const\n{\n\tif (m_sources.sources.size() != 1)\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Expected single source definition, but got multiple sources.\"));\n\treturn m_sources.sources.at(m_sources.mainSourceFile);\n}\n\nstd::string TestCaseReader::simpleExpectations()\n{\n\treturn parseSimpleExpectations(m_fileStream);\n}\n\nbool TestCaseReader::boolSetting(std::string const& _name, bool _defaultValue)\n{\n\tif (m_settings.count(_name) == 0)\n\t\treturn _defaultValue;\n\n\tm_unreadSettings.erase(_name);\n\tstd::string value = m_settings.at(_name);\n\tif (value == \"false\")\n\t\treturn false;\n\tif (value == \"true\")\n\t\treturn true;\n\n\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid Boolean value: \" + value + \".\"));\n}\n\nsize_t TestCaseReader::sizetSetting(std::string const& _name, size_t _defaultValue)\n{\n\tif (m_settings.count(_name) == 0)\n\t\treturn _defaultValue;\n\n\tm_unreadSettings.erase(_name);\n\n\tstatic_assert(sizeof(unsigned long) <= sizeof(size_t));\n\treturn stoul(m_settings.at(_name));\n}\n\nstd::string TestCaseReader::stringSetting(std::string const& _name, std::string const& _defaultValue)\n{\n\tif (m_settings.count(_name) == 0)\n\t\treturn _defaultValue;\n\n\tm_unreadSettings.erase(_name);\n\treturn m_settings.at(_name);\n}\n\nvoid TestCaseReader::ensureAllSettingsRead() const\n{\n\tif (!m_unreadSettings.empty())\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\n\t\t\t\"Unknown setting(s): \" +\n\t\t\tutil::joinHumanReadable(m_unreadSettings | ranges::views::keys)\n\t\t));\n}\n\nstd::pair<SourceMap, size_t> TestCaseReader::parseSourcesAndSettingsWithLineNumber(std::istream& _stream)\n{\n\tstd::map<std::string, std::string> sources;\n\tstd::map<std::string, boost::filesystem::path> externalSources;\n\tstd::string currentSourceName;\n\tstd::string currentSource;\n\tstd::string line;\n\tsize_t lineNumber = 1;\n\tstatic std::string const externalSourceDelimiterStart(\"==== ExternalSource:\");\n\tstatic std::string const sourceDelimiterStart(\"==== Source:\");\n\tstatic std::string const sourceDelimiterEnd(\"====\");\n\tstatic std::string const comment(\"// \");\n\tstatic std::string const settingsDelimiter(\"// ====\");\n\tstatic std::string const expectationsDelimiter(\"// ----\");\n\tbool sourcePart = true;\n\twhile (getline(_stream, line))\n\t{\n\t\tlineNumber++;\n\n\t\t// Anything below the delimiter is left up to the test case to process in a custom way.\n\t\tif (boost::algorithm::starts_with(line, expectationsDelimiter))\n\t\t\tbreak;\n\n\t\tif (boost::algorithm::starts_with(line, settingsDelimiter))\n\t\t\tsourcePart = false;\n\t\telse if (sourcePart)\n\t\t{\n\t\t\tif (boost::algorithm::starts_with(line, sourceDelimiterStart) && boost::algorithm::ends_with(line, sourceDelimiterEnd))\n\t\t\t{\n\t\t\t\tif (!(currentSourceName.empty() && currentSource.empty()))\n\t\t\t\t\tsources[currentSourceName] = std::move(currentSource);\n\t\t\t\tcurrentSource = {};\n\t\t\t\tcurrentSourceName = boost::trim_copy(line.substr(\n\t\t\t\t\tsourceDelimiterStart.size(),\n\t\t\t\t\tline.size() - sourceDelimiterEnd.size() - sourceDelimiterStart.size()\n\t\t\t\t));\n\t\t\t\tif (sources.count(currentSourceName))\n\t\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Multiple definitions of test source \\\"\" + currentSourceName + \"\\\".\"));\n\t\t\t}\n\t\t\telse if (boost::algorithm::starts_with(line, externalSourceDelimiterStart) && boost::algorithm::ends_with(line, sourceDelimiterEnd))\n\t\t\t{\n\t\t\t\tstd::string externalSourceString = boost::trim_copy(line.substr(\n\t\t\t\t\texternalSourceDelimiterStart.size(),\n\t\t\t\t\tline.size() - sourceDelimiterEnd.size() - externalSourceDelimiterStart.size()\n\t\t\t\t));\n\n\t\t\t\tstd::string externalSourceName;\n\t\t\t\tsize_t remappingPos = externalSourceString.find('=');\n\t\t\t\t// Does the external source define a remapping?\n\t\t\t\tif (remappingPos != std::string::npos)\n\t\t\t\t{\n\t\t\t\t\texternalSourceName = boost::trim_copy(externalSourceString.substr(0, remappingPos));\n\t\t\t\t\texternalSourceString = boost::trim_copy(externalSourceString.substr(remappingPos + 1));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\texternalSourceName = externalSourceString;\n\n\t\t\t\tsoltestAssert(!externalSourceName.empty(), \"\");\n\t\t\t\tfs::path externalSourceTarget(externalSourceString);\n\t\t\t\tfs::path testCaseParentDir = m_fileName.parent_path();\n\t\t\t\tif (!externalSourceTarget.is_relative() || !externalSourceTarget.root_path().empty())\n\t\t\t\t\t// NOTE: UNC paths (ones starting with // or \\\\) are considered relative by Boost\n\t\t\t\t\t// since they have an empty root directory (but non-empty root name).\n\t\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"External Source paths need to be relative to the location of the test case.\"));\n\t\t\t\tfs::path externalSourceFullPath = testCaseParentDir / externalSourceTarget;\n\t\t\t\tstd::string externalSourceContent;\n\t\t\t\tif (!fs::exists(externalSourceFullPath))\n\t\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"External Source '\" + externalSourceTarget.string() + \"' not found.\"));\n\t\t\t\telse\n\t\t\t\t\texternalSourceContent = util::readFileAsString(externalSourceFullPath);\n\n\t\t\t\tif (sources.count(externalSourceName))\n\t\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Multiple definitions of test source \\\"\" + externalSourceName + \"\\\".\"));\n\t\t\t\tsources[externalSourceName] = externalSourceContent;\n\t\t\t\texternalSources[externalSourceName] = externalSourceTarget;\n\t\t\t}\n\t\t\telse\n\t\t\t\tcurrentSource += line + \"\\n\";\n\t\t}\n\t\telse if (boost::algorithm::starts_with(line, comment))\n\t\t{\n\t\t\tsize_t colon = line.find(':');\n\t\t\tif (colon == std::string::npos)\n\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(std::string(\"Expected \\\":\\\" inside setting.\")));\n\t\t\tstd::string key = line.substr(comment.size(), colon - comment.size());\n\t\t\tstd::string value = line.substr(colon + 1);\n\t\t\tboost::algorithm::trim(key);\n\t\t\tboost::algorithm::trim(value);\n\t\t\tm_settings[key] = value;\n\t\t}\n\t\telse\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(std::string(\"Expected \\\"//\\\" or \\\"// ---\\\" to terminate settings and source.\")));\n\t}\n\t// Register the last source as the main one\n\tsources[currentSourceName] = currentSource;\n\treturn {{std::move(sources), std::move(externalSources), std::move(currentSourceName)}, lineNumber};\n}\n\nstd::string TestCaseReader::parseSimpleExpectations(std::istream& _file)\n{\n\tstd::string result;\n\tstd::string line;\n\twhile (std::getline(_file, line))\n\t\tif (boost::algorithm::starts_with(line, \"// \"))\n\t\t\tresult += line.substr(3) + \"\\n\";\n\t\telse if (line == \"//\")\n\t\t\tresult += \"\\n\";\n\t\telse\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Test expectations must start with \\\"// \\\".\"));\n\treturn result;\n}\n"
  },
  {
    "path": "test/TestCaseReader.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <test/libsolidity/util/SoltestErrors.h>\n\n#include <libsolutil/StringUtils.h>\n\n#include <range/v3/view/map.hpp>\n\n#include <boost/filesystem.hpp>\n#include <boost/throw_exception.hpp>\n\n#include <fstream>\n#include <map>\n#include <string>\n\nnamespace solidity::frontend::test\n{\n\n/**\n * A map for registering source names that also contains the main source name in a test case.\n */\nstruct SourceMap\n{\n\tstd::map<std::string, std::string> sources;\n\tstd::map<std::string, boost::filesystem::path> externalSources;\n\tstd::string mainSourceFile;\n};\n\n/**\n * A reader for test case data file, which parses source, settings and (optionally) simple expectations.\n */\nclass TestCaseReader\n{\npublic:\n\tTestCaseReader() = default;\n\texplicit TestCaseReader(std::string const& _filename);\n\texplicit TestCaseReader(std::istringstream const& _testCode);\n\n\tSourceMap const& sources() const { return m_sources; }\n\tstd::string const& source() const;\n\tstd::size_t lineNumber() const { return m_lineNumber; }\n\tstd::map<std::string, std::string> const& settings() const { return m_settings; }\n\tstd::ifstream& stream() { return m_fileStream; }\n\tboost::filesystem::path const& fileName() const { return m_fileName; }\n\n\tstd::string simpleExpectations();\n\n\tbool boolSetting(std::string const& _name, bool _defaultValue);\n\tsize_t sizetSetting(std::string const& _name, size_t _defaultValue);\n\tstd::string stringSetting(std::string const& _name, std::string const& _defaultValue);\n\n\ttemplate <typename E>\n\tE enumSetting(std::string const& _name, std::map<std::string, E> const& _choices, std::string const& _defaultChoice);\n\n\tvoid ensureAllSettingsRead() const;\n\nprivate:\n\tstd::pair<SourceMap, std::size_t> parseSourcesAndSettingsWithLineNumber(std::istream& _file);\n\tstatic std::string parseSimpleExpectations(std::istream& _file);\n\n\tstd::ifstream m_fileStream;\n\tboost::filesystem::path m_fileName;\n\tSourceMap m_sources;\n\tstd::size_t m_lineNumber = 0;\n\tstd::map<std::string, std::string> m_settings;\n\tstd::map<std::string, std::string> m_unreadSettings; ///< tracks which settings are left unread\n};\n\ntemplate <typename E>\nE TestCaseReader::enumSetting(std::string const& _name, std::map<std::string, E> const& _choices, std::string const& _defaultChoice)\n{\n\tsoltestAssert(_choices.count(_defaultChoice) > 0, \"\");\n\n\tstd::string value = stringSetting(_name, _defaultChoice);\n\n\tif (_choices.count(value) == 0)\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\n\t\t\t\"Invalid Enum value: \" + value + \". Available choices: \" + util::joinHumanReadable(_choices | ranges::views::keys) + \".\"\n\t\t));\n\n\treturn _choices.at(value);\n}\n\n}\n"
  },
  {
    "path": "test/benchmarks/OptimizorClub.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n// Compressed form of https://github.com/OptimizorClub/optimizor and its dependencies\n\nlibrary Base64 {\n    bytes private constant TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n    function encode(bytes memory data) internal pure returns (string memory result) {\n        uint256 len = data.length;\n        if (len == 0) return \"\";\n        uint256 encodedLen;\n        unchecked {\n            encodedLen = 4 * ((len + 2) / 3);\n        }\n        unchecked {\n            result = new string(encodedLen + 32);\n        }\n        bytes memory table = TABLE;\n        assembly (\"memory-safe\") {\n            let tablePtr := add(table, 1)\n            let resultPtr := add(result, 32)\n            for { let i := 0 } lt(i, len) {} {\n                i := add(i, 3)\n                let input := and(mload(add(data, i)), 0xffffff)\n                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))\n                out := shl(8, out)\n                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))\n                out := shl(8, out)\n                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))\n                out := shl(8, out)\n                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))\n                out := shl(224, out)\n                mstore(resultPtr, out)\n                resultPtr := add(resultPtr, 4)\n            }\n            switch mod(len, 3)\n            case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }\n            case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }\n            mstore(result, encodedLen)\n        }\n        return result;\n    }\n}\nlibrary Puretea {\n    function isMutating(bytes memory code) internal pure returns (bool) {\n        return check(code, 0xe43f0000000000000000001fffffffffffffffff0fff01ffffff00013fff0fff);\n    }\n    function isView(bytes memory code) internal pure returns (bool) {\n        return check(code, 0x640800000000000000000000ffffffffffffffff0fdf01ffffff00013fff0fff);\n    }\n    function isPureGlobal(bytes memory code) internal pure returns (bool) {\n        return check(code, 0x600800000000000000000000ffffffffffffffff0fdf01ff67ff00013fff0fff);\n    }\n    function isPureLocal(bytes memory code) internal pure returns (bool) {\n        return check(code, 0x600800000000000000000000ffffffffffffffff0fcf01ffffff00013fff0fff);\n    }\n    function check(bytes memory _code, uint256 _mask) internal pure returns (bool satisfied) {\n        assembly (\"memory-safe\") {\n            function matchesMask(mask, opcode) -> ret {\n                ret := and(mask, shl(opcode, 1))\n            }\n            function isPush(opcode) -> ret {\n                ret := and(gt(opcode, 0x5f), lt(opcode, 0x80))\n            }\n            function perform(mask, code) -> ret {\n                for {\n                    let offset := add(code, 32)\n                    let end := add(offset, mload(code ))\n                } lt(offset, end) {\n                    offset := add(offset, 1)\n                } {\n                    let opcode := byte(0, mload(offset))\n                    if iszero(matchesMask(mask, opcode)) {\n                        leave\n                    }\n                    if isPush(opcode) {\n                        let immLen := sub(opcode, 0x5f)\n                        offset := add(offset, immLen)\n                        if iszero(lt(offset, end)) {\n                            leave\n                        }\n                    }\n                }\n                ret := 1\n            }\n            satisfied := perform(_mask, _code)\n        }\n    }\n}\nabstract contract PurityChecker {\n    uint256 private constant acceptedOpcodesMask = 0x600800000000000000000000ffffffffffffffff0fdf01ff67ff00013fff0fff;\n    function check(address account) external view returns (bool) {\n        return Puretea.check(account.code, acceptedOpcodesMask);\n    }\n}\ninterface IChallenge {\n    function run(address target, uint256 seed) external view returns (uint32);\n    function svg(uint256 tokenId) external view returns (string memory);\n    function name() external view returns (string memory);\n    function description() external view returns (string memory);\n}\nstruct TokenDetails {\n    uint256 challengeId;\n    IChallenge challenge;\n    uint32 leaderGas;\n    uint32 leaderSolutionId;\n    address leaderSolver;\n    address leaderOwner;\n    address leaderSubmission;\n    uint32 gas;\n    uint32 solutionId;\n    uint32 rank;\n    uint32 improvementPercentage;\n    address solver;\n    address owner;\n    address submission;\n}\nlibrary HexString {\n    error HexLengthInsufficient();\n    bytes16 private constant ALPHABET = \"0123456789abcdef\";\n    function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length);\n        unchecked {\n            for (uint256 i = buffer.length; i > 0; --i) {\n                buffer[i - 1] = ALPHABET[value & 0xf];\n                value >>= 4;\n            }\n        }\n        if (value != 0) revert HexLengthInsufficient();\n        return string(buffer);\n    }\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        unchecked {\n            for (uint256 i = 2 * length + 1; i > 1; --i) {\n                buffer[i] = ALPHABET[value & 0xf];\n                value >>= 4;\n            }\n        }\n        if (value != 0) revert HexLengthInsufficient();\n        return string(buffer);\n    }\n}\nfunction packTokenId(uint256 challengeId, uint32 solutionId) pure returns (uint256) {\n    return (challengeId << 32) | solutionId;\n}\nfunction unpackTokenId(uint256 tokenId) pure returns (uint256 challengeId, uint32 solutionId) {\n    challengeId = tokenId >> 32;\n    solutionId = uint32(tokenId);\n}\nlibrary NFTSVG {\n    struct SVGParams {\n        string projectName;\n        string challengeName;\n        string solverAddr;\n        string challengeAddr;\n        uint256 gasUsed;\n        uint256 gasOpti;\n        uint256 tokenId;\n        uint32 rank;\n        uint32 participants;\n        string color;\n        uint256 x1;\n        uint256 y1;\n        uint256 x2;\n        uint256 y2;\n        uint256 x3;\n        uint256 y3;\n    }\n    function generateSVG(SVGParams memory params, string memory challengeSVG)\n        internal\n        pure\n        returns (string memory svg)\n    {\n        return string.concat(\n            generateSVGDefs(params),\n            generateSVGBorderText(params.projectName, params.challengeName, params.solverAddr, params.challengeAddr),\n            generateSVGCardMantle(params.challengeName, params.rank, params.participants),\n            generateRankBorder(params.rank),\n            generateSvgCurve(challengeSVG),\n            generateSVGPositionDataAndLocationCurve(LibString.toString(params.tokenId), params.gasUsed, params.gasOpti),\n            generateOptimizorIcon(),\n            \"</svg>\"\n        );\n    }\n    function generateSVGDefs(SVGParams memory params) private pure returns (string memory svg) {\n        svg = string.concat(\n            '<svg width=\"290\" height=\"500\" viewBox=\"0 0 290 500\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">'\n            \"<defs>\"\n            '<filter id=\"icon\"><feImage result=\"icon\" xlink:href=\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTY2LjU5NyIgaGVpZ2h0PSIxMjguOTQxIiB2aWV3Qm94PSIwIDAgNDQuMDc5IDM0LjExNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjAuNzkzIDEzLjMyMWgtLjYyM1YxMi43aC02LjIyNXYuNjIyaC42MjJ2LjYyM2gtLjYyMnYuNjIyaC0uNjIzdi0uNjIySDEyLjd2Ni4yMjVoLjYyMnYuNjIzaC42MjN2LjYyMmg2LjIyNXYtLjYyMmguNjIzdi0uNjIzaC42MjJ2LTYuMjI1aC0uNjIyem0tMy43MzUgNS42MDN2LTQuMzU4aDEuODY3djQuMzU4em0xMy42OTgtNi4yMjVoLTYuODQ4di42MjJoLjYyM3YuNjIzaC0uNjIzdi42MjJoLS42MjJ2LS42MjJoLS42MjN2Ni4yMjVoLjYyM3YuNjIzaC42MjJ2LjYyMmg2Ljg0OHYtLjYyMmguNjIydi0xLjI0NWgtLjYyMnYtLjYyM0gyNy4wMnYtNC4zNThoMy43MzV2LS42MjJoLjYyMnYtLjYyM2gtLjYyMnoiIHN0eWxlPSJmaWxsOiM2NjYiLz48L3N2Zz4=\"/></filter>'\n            '<filter id=\"f1\"><feImage result=\"p0\" xlink:href=\"data:image/svg+xml;base64,',\n            Base64.encode(\n                bytes(\n                    string.concat(\n                        \"<svg width='290' height='500' viewBox='0 0 290 500' xmlns='http://www.w3.org/2000/svg'><rect width='290' height='500' fill='#\",\n                        params.color,\n                        \"'/></svg>\"\n                    )\n                )\n            ),\n            '\"/><feImage result=\"p1\" xlink:href=\"data:image/svg+xml;base64,',\n            Base64.encode(\n                bytes(\n                    string.concat(\n                        \"<svg width='290' height='500' viewBox='0 0 290 500' xmlns='http://www.w3.org/2000/svg'><circle cx='\",\n                        LibString.toString(params.x1),\n                        \"' cy='\",\n                        LibString.toString(params.y1),\n                        \"' r='120' fill='#\",\n                        params.color,\n                        \"'/></svg>\"\n                    )\n                )\n            ),\n            '\"/><feImage result=\"p2\" xlink:href=\"data:image/svg+xml;base64,',\n            Base64.encode(\n                bytes(\n                    string.concat(\n                        \"<svg width='290' height='500' viewBox='0 0 290 500' xmlns='http://www.w3.org/2000/svg'><circle cx='\",\n                        LibString.toString(params.x2),\n                        \"' cy='\",\n                        LibString.toString(params.y2),\n                        \"' r='120' fill='#\",\n                        params.color,\n                        \"'/></svg>\"\n                    )\n                )\n            ),\n            '\" />',\n            '<feImage result=\"p3\" xlink:href=\"data:image/svg+xml;base64,',\n            Base64.encode(\n                bytes(\n                    string.concat(\n                        \"<svg width='290' height='500' viewBox='0 0 290 500' xmlns='http://www.w3.org/2000/svg'><circle cx='\",\n                        LibString.toString(params.x3),\n                        \"' cy='\",\n                        LibString.toString(params.y3),\n                        \"' r='100' fill='#\",\n                        params.color,\n                        \"'/></svg>\"\n                    )\n                )\n            ),\n            '\"/><feBlend mode=\"overlay\" in=\"p0\" in2=\"p1\"/><feBlend mode=\"exclusion\" in2=\"p2\"/><feBlend mode=\"overlay\" in2=\"p3\" result=\"blendOut\"/><feGaussianBlur '\n            'in=\"blendOut\" stdDeviation=\"42\"/></filter><clipPath id=\"corners\"><rect width=\"290\" height=\"500\" rx=\"42\" ry=\"42\"/></clipPath>'\n            '<path id=\"text-path-a\" d=\"M40 12 H250 A28 28 0 0 1 278 40 V460 A28 28 0 0 1 250 488 H40 A28 28 0 0 1 12 460 V40 A28 28 0 0 1 40 12 z\"/>'\n            '<path id=\"minimap\" d=\"M234 444C234 457.949 242.21 463 253 463\"/>'\n            '<filter id=\"top-region-blur\"><feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"24\"/></filter>'\n            '<linearGradient id=\"grad-up\" x1=\"1\" x2=\"0\" y1=\"1\" y2=\"0\"><stop offset=\"0.0\" stop-color=\"#fff\" stop-opacity=\"1\"/>'\n            '<stop offset=\".9\" stop-color=\"#fff\" stop-opacity=\"0\"/></linearGradient>'\n            '<linearGradient id=\"grad-down\" x1=\"0\" x2=\"1\" y1=\"0\" y2=\"1\"><stop offset=\"0.0\" stop-color=\"#fff\" stop-opacity=\"1\"/><stop offset=\"0.9\" stop-color=\"#fff\" stop-opacity=\"0\"/></linearGradient>'\n            '<mask id=\"fade-up\" maskContentUnits=\"objectBoundingBox\"><rect width=\"1\" height=\"1\" fill=\"url(#grad-up)\"/></mask>'\n            '<mask id=\"fade-down\" maskContentUnits=\"objectBoundingBox\"><rect width=\"1\" height=\"1\" fill=\"url(#grad-down)\"/></mask>'\n            '<mask id=\"none\" maskContentUnits=\"objectBoundingBox\"><rect width=\"1\" height=\"1\" fill=\"#fff\"/></mask>'\n            '<linearGradient id=\"grad-symbol\"><stop offset=\"0.7\" stop-color=\"#fff\" stop-opacity=\"1\"/><stop offset=\".95\" stop-color=\"#fff\" stop-opacity=\"0\"/></linearGradient>'\n            '<mask id=\"fade-symbol\" maskContentUnits=\"userSpaceOnUse\"><rect width=\"290\" height=\"200\" fill=\"url(#grad-symbol)\"/></mask></defs>'\n            '<g clip-path=\"url(#corners)\">' '<rect fill=\"',\n            params.color,\n            '\" x=\"0\" y=\"0\" width=\"290\" height=\"500\"/>'\n            '<rect style=\"filter: url(#f1)\" x=\"0\" y=\"0\" width=\"290\" height=\"500\"/>'\n            '<g style=\"filter:url(#top-region-blur); transform:scale(1.5); transform-origin:center top;\">'\n            '<rect fill=\"none\" x=\"0\" y=\"0\" width=\"290\" height=\"500\"/>'\n            '<ellipse cx=\"50%\" cy=\"0\" rx=\"180\" ry=\"120\" fill=\"#000\" opacity=\"0.85\"/></g>'\n            '<rect x=\"0\" y=\"0\" width=\"290\" height=\"500\" rx=\"42\" ry=\"42\" fill=\"rgba(0,0,0,0)\" stroke=\"rgba(255,255,255,0.2)\"/></g>'\n        );\n    }\n    function generateSVGBorderText(\n        string memory projectName,\n        string memory challengeName,\n        string memory solverAddr,\n        string memory challengeAddr\n    ) private pure returns (string memory svg) {\n        svg = string.concat(\n            '<text text-rendering=\"optimizeSpeed\">'\n            '<textPath startOffset=\"-100%\" fill=\"#fff\" font-family=\"\\'Courier New\\', monospace\" font-size=\"10px\" xlink:href=\"#text-path-a\">',\n            challengeName,\n            unicode\" • \",\n            challengeAddr,\n            '<animate additive=\"sum\" attributeName=\"startOffset\" from=\"0%\" to=\"100%\" begin=\"0s\" dur=\"30s\" repeatCount=\"indefinite\"/>'\n            '</textPath> <textPath startOffset=\"0%\" fill=\"#fff\" font-family=\"\\'Courier New\\', monospace\" font-size=\"10px\" xlink:href=\"#text-path-a\">',\n            challengeName,\n            unicode\" • \",\n            challengeAddr,\n            '<animate additive=\"sum\" attributeName=\"startOffset\" from=\"0%\" to=\"100%\" begin=\"0s\" dur=\"30s\" repeatCount=\"indefinite\"/></textPath>'\n            '<textPath startOffset=\"50%\" fill=\"#fff\" font-family=\"\\'Courier New\\', monospace\" font-size=\"10px\" xlink:href=\"#text-path-a\">',\n            projectName,\n            unicode\" • \",\n            solverAddr,\n            '<animate additive=\"sum\" attributeName=\"startOffset\" from=\"0%\" to=\"100%\" begin=\"0s\" dur=\"30s\"'\n            ' repeatCount=\"indefinite\"/></textPath><textPath startOffset=\"-50%\" fill=\"#fff\" font-family=\"\\'Courier New\\', monospace\" font-size=\"10px\" xlink:href=\"#text-path-a\">',\n            projectName,\n            unicode\" • \",\n            solverAddr,\n            '<animate additive=\"sum\" attributeName=\"startOffset\" from=\"0%\" to=\"100%\" begin=\"0s\" dur=\"30s\" repeatCount=\"indefinite\"/></textPath></text>'\n        );\n    }\n    function generateSVGCardMantle(string memory challengeName, uint32 rank, uint32 participants)\n        private\n        pure\n        returns (string memory svg)\n    {\n        svg = string.concat(\n            '<g mask=\"url(#fade-symbol)\"><rect fill=\"none\" x=\"0\" y=\"0\" width=\"290\" height=\"200\"/><text y=\"70\" x=\"32\" fill=\"#fff\" font-family=\"\\'Courier New\\', monospace\" font-weight=\"200\" font-size=\"28px\">',\n            challengeName,\n            '</text><text y=\"115\" x=\"32\" fill=\"#fff\" font-family=\"\\'Courier New\\', monospace\" font-weight=\"200\" font-size=\"20px\">'\n            \"Rank \",\n            LibString.toString(rank),\n            \" of \",\n            LibString.toString(participants),\n            \"</text></g>\"\n        );\n    }\n    function generateRankBorder(uint32 rank) private pure returns (string memory svg) {\n        string memory color;\n        if (rank == 1) {\n            color = \"rgba(255,215,0,1.0)\";\n        } else if (rank == 2) {\n            color = \"rgba(255,255,255,1.0)\";\n        } else if (rank == 3) {\n            color = \"rgba(205,127,50,1.0)\";\n        } else {\n            color = \"rgba(255,255,255,0.2)\";\n        }\n        svg = string.concat(\n            '<rect x=\"16\" y=\"16\" width=\"258\" height=\"468\" rx=\"26\" ry=\"26\" fill=\"rgba(0,0,0,0)\" stroke=\"', color, '\"/>'\n        );\n    }\n    function generateSvgCurve(string memory challengeSVG) private pure returns (string memory svg) {\n        svg = string.concat('<g mask=\"url(#none)\"', ' style=\"transform:translate(30px,130px)\">', challengeSVG, \"</g>\");\n    }\n    function generateSVGPositionDataAndLocationCurve(string memory tokenId, uint256 gasUsed, uint256 gasOpti)\n        private\n        pure\n        returns (string memory svg)\n    {\n        string memory gasUsedStr = LibString.toString(gasUsed);\n        string memory gasOptiStr = LibString.toString(gasOpti);\n        uint256 str1length = bytes(tokenId).length + 4;\n        uint256 str2length = bytes(gasUsedStr).length + 10;\n        uint256 str3length = bytes(gasOptiStr).length + 14;\n        svg = string.concat(\n            '<g font-family=\"\\'Courier New\\', monospace\" font-size=\"12\" fill=\"#fff\">'\n            '<g style=\"transform:translate(29px, 384px)\">' '<rect width=\"',\n            LibString.toString(uint256(7 * (str1length + 4))),\n            string.concat('\" height=\"26\" rx=\"8\" ry=\"8\" fill=\"rgba(0,0,0,0.6)\"/>' '<text x=\"12\" y=\"17\"><tspan fill=\"#999\">ID: </tspan>'),\n            tokenId,\n            \"</text></g>\" '<g style=\"transform:translate(29px, 414px)\">' '<rect width=\"',\n            LibString.toString(uint256(7 * (str2length + 4))),\n            '\" height=\"26\" rx=\"8\" ry=\"8\" fill=\"rgba(0,0,0,0.6)\"/>'\n            '<text x=\"12\" y=\"17\"><tspan fill=\"#999\">Gas used: </tspan>',\n            gasUsedStr,\n            \"</text></g>\" '<g style=\"transform:translate(29px, 444px)\">' '<rect width=\"',\n            LibString.toString(uint256(7 * (str3length + 4))),\n            '\" height=\"26\" rx=\"8\" ry=\"8\" fill=\"rgba(0,0,0,0.6)\"/>'\n            '<text x=\"12\" y=\"17\"><tspan fill=\"#999\">Improvement: </tspan>',\n            gasOptiStr,\n            \"%\" \"</text></g></g>\"\n        );\n    }\n    function generateOptimizorIcon() private pure returns (string memory svg) {\n        return\n        '<g style=\"transform:translate(180px, 365px)\"><rect style=\"filter: url(#icon)\" x=\"0\" y=\"0\" width=\"83\" height=\"64\"/></g>';\n    }\n    function getCircleCoord(address tokenAddress, uint256 offset, uint256 tokenId) internal pure returns (uint8) {\n        unchecked {\n            return uint8((((uint256(uint160(tokenAddress)) >> offset) & 0xFF) * tokenId) % 255);\n        }\n    }\n}\nlibrary LibString {\n    function toString(uint256 value) internal pure returns (string memory str) {\n        assembly {\n            let newFreeMemoryPointer := add(mload(0x40), 160)\n            mstore(0x40, newFreeMemoryPointer)\n            str := sub(newFreeMemoryPointer, 32)\n            mstore(str, 0)\n            let end := str\n            for { let temp := value } 1 {} {\n                str := sub(str, 1)\n                mstore8(str, add(48, mod(temp, 10)))\n                temp := div(temp, 10)\n                if iszero(temp) { break }\n            }\n            let length := sub(end, str)\n            str := sub(str, 32)\n            mstore(str, length)\n        }\n    }\n}\nabstract contract Owned {\n    event OwnershipTransferred(address indexed user, address indexed newOwner);\n    address public owner;\n    modifier onlyOwner() virtual {\n        require(msg.sender == owner, \"UNAUTHORIZED\");\n        _;\n    }\n    constructor(address _owner) {\n        owner = _owner;\n        emit OwnershipTransferred(address(0), _owner);\n    }\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        owner = newOwner;\n        emit OwnershipTransferred(msg.sender, newOwner);\n    }\n}\nabstract contract ERC721 {\n    event Transfer(address indexed from, address indexed to, uint256 indexed id);\n    event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n    string public name;\n    string public symbol;\n    function tokenURI(uint256 id) public view virtual returns (string memory);\n    mapping(uint256 => address) internal _ownerOf;\n    mapping(address => uint256) internal _balanceOf;\n    function ownerOf(uint256 id) public view virtual returns (address owner) {\n        require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n    }\n    function balanceOf(address owner) public view virtual returns (uint256) {\n        require(owner != address(0), \"ZERO_ADDRESS\");\n        return _balanceOf[owner];\n    }\n    mapping(uint256 => address) public getApproved;\n    mapping(address => mapping(address => bool)) public isApprovedForAll;\n    constructor(string memory _name, string memory _symbol) {\n        name = _name;\n        symbol = _symbol;\n    }\n    function approve(address spender, uint256 id) public virtual {\n        address owner = _ownerOf[id];\n        require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n        getApproved[id] = spender;\n        emit Approval(owner, spender, id);\n    }\n    function setApprovalForAll(address operator, bool approved) public virtual {\n        isApprovedForAll[msg.sender][operator] = approved;\n        emit ApprovalForAll(msg.sender, operator, approved);\n    }\n    function transferFrom(\n        address from,\n        address to,\n        uint256 id\n    ) public virtual {\n        require(from == _ownerOf[id], \"WRONG_FROM\");\n        require(to != address(0), \"INVALID_RECIPIENT\");\n        require(\n            msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\n            \"NOT_AUTHORIZED\"\n        );\n        unchecked {\n            _balanceOf[from]--;\n            _balanceOf[to]++;\n        }\n        _ownerOf[id] = to;\n        delete getApproved[id];\n        emit Transfer(from, to, id);\n    }\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 id\n    ) public virtual {\n        transferFrom(from, to, id);\n        require(\n            to.code.length == 0 ||\n                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n                ERC721TokenReceiver.onERC721Received.selector,\n            \"UNSAFE_RECIPIENT\"\n        );\n    }\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 id,\n        bytes calldata data\n    ) public virtual {\n        transferFrom(from, to, id);\n        require(\n            to.code.length == 0 ||\n                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n                ERC721TokenReceiver.onERC721Received.selector,\n            \"UNSAFE_RECIPIENT\"\n        );\n    }\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return\n            interfaceId == 0x01ffc9a7 ||\n            interfaceId == 0x80ac58cd ||\n            interfaceId == 0x5b5e139f;\n    }\n    function _mint(address to, uint256 id) internal virtual {\n        require(to != address(0), \"INVALID_RECIPIENT\");\n        require(_ownerOf[id] == address(0), \"ALREADY_MINTED\");\n        unchecked {\n            _balanceOf[to]++;\n        }\n        _ownerOf[id] = to;\n        emit Transfer(address(0), to, id);\n    }\n    function _burn(uint256 id) internal virtual {\n        address owner = _ownerOf[id];\n        require(owner != address(0), \"NOT_MINTED\");\n        unchecked {\n            _balanceOf[owner]--;\n        }\n        delete _ownerOf[id];\n        delete getApproved[id];\n        emit Transfer(owner, address(0), id);\n    }\n    function _safeMint(address to, uint256 id) internal virtual {\n        _mint(to, id);\n        require(\n            to.code.length == 0 ||\n                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n                ERC721TokenReceiver.onERC721Received.selector,\n            \"UNSAFE_RECIPIENT\"\n        );\n    }\n    function _safeMint(\n        address to,\n        uint256 id,\n        bytes memory data\n    ) internal virtual {\n        _mint(to, id);\n        require(\n            to.code.length == 0 ||\n                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n                ERC721TokenReceiver.onERC721Received.selector,\n            \"UNSAFE_RECIPIENT\"\n        );\n    }\n}\nabstract contract ERC721TokenReceiver {\n    function onERC721Received(\n        address,\n        address,\n        uint256,\n        bytes calldata\n    ) external virtual returns (bytes4) {\n        return ERC721TokenReceiver.onERC721Received.selector;\n    }\n}\nabstract contract OptimizorNFT is ERC721 {\n    error InvalidSolutionId(uint256 challengeId, uint32 solutionId);\n    error ChallengeNotFound(uint256 challengeId);\n    struct ChallengeInfo {\n        IChallenge target;\n        uint32 solutions;\n    }\n    struct ExtraDetails {\n        address code;\n        address solver;\n        uint32 gas;\n    }\n    mapping(uint256 => ChallengeInfo) public challenges;\n    mapping(uint256 => ExtraDetails) public extraDetails;\n    constructor() ERC721(\"Optimizor Club\", \"OC\") {}\n    function contractURI() external pure returns (string memory) {\n        return\n        \"data:application/json;base64,eyJuYW1lIjoiT3B0aW1pem9yIENsdWIiLCJkZXNjcmlwdGlvbiI6IlRoZSBPcHRpbWl6b3IgQ2x1YiBORlQgY29sbGVjdGlvbiByZXdhcmRzIGdhcyBlZmZpY2llbnQgcGVvcGxlIGFuZCBtYWNoaW5lcyBieSBtaW50aW5nIG5ldyBpdGVtcyB3aGVuZXZlciBhIGNoZWFwZXIgc29sdXRpb24gaXMgc3VibWl0dGVkIGZvciBhIGNlcnRhaW4gY2hhbGxlbmdlLiIsImltYWdlIjoiZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCM2FXUjBhRDBpTVRZMkxqVTVOeUlnYUdWcFoyaDBQU0l4TWpndU9UUXhJaUIyYVdWM1FtOTRQU0l3SURBZ05EUXVNRGM1SURNMExqRXhOaUlnZUcxc2JuTTlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5Mekl3TURBdmMzWm5JajQ4Y0dGMGFDQmtQU0pOTWpBdU56a3pJREV6TGpNeU1XZ3RMall5TTFZeE1pNDNhQzAyTGpJeU5YWXVOakl5YUM0Mk1qSjJMall5TTJndExqWXlNbll1TmpJeWFDMHVOakl6ZGkwdU5qSXlTREV5TGpkMk5pNHlNalZvTGpZeU1uWXVOakl6YUM0Mk1qTjJMall5TW1nMkxqSXlOWFl0TGpZeU1tZ3VOakl6ZGkwdU5qSXphQzQyTWpKMkxUWXVNakkxYUMwdU5qSXllbTB0TXk0M016VWdOUzQyTUROMkxUUXVNelU0YURFdU9EWTNkalF1TXpVNGVtMHhNeTQyT1RndE5pNHlNalZvTFRZdU9EUTRkaTQyTWpKb0xqWXlNM1l1TmpJemFDMHVOakl6ZGk0Mk1qSm9MUzQyTWpKMkxTNDJNakpvTFM0Mk1qTjJOaTR5TWpWb0xqWXlNM1l1TmpJemFDNDJNakoyTGpZeU1tZzJMamcwT0hZdExqWXlNbWd1TmpJeWRpMHhMakkwTldndExqWXlNbll0TGpZeU0wZ3lOeTR3TW5ZdE5DNHpOVGhvTXk0M016VjJMUzQyTWpKb0xqWXlNbll0TGpZeU0yZ3RMall5TW5vaUlITjBlV3hsUFNKbWFXeHNPaU0yTmpZaUx6NDhMM04yWno0PSIsImV4dGVybmFsX2xpbmsiOiJodHRwczovL29wdGltaXpvci5jbHViLyJ9\";\n    }\n    function tokenDetails(uint256 tokenId) public view returns (TokenDetails memory) {\n        (uint256 challengeId, uint32 solutionId) = unpackTokenId(tokenId);\n        if (solutionId == 0) revert InvalidSolutionId(challengeId, solutionId);\n        ChallengeInfo storage chl = challenges[challengeId];\n        if (address(chl.target) == address(0)) revert ChallengeNotFound(challengeId);\n        if (solutionId > chl.solutions) revert InvalidSolutionId(challengeId, solutionId);\n        ExtraDetails storage details = extraDetails[tokenId];\n        uint256 leaderTokenId = packTokenId(challengeId, chl.solutions);\n        ExtraDetails storage leaderDetails = extraDetails[leaderTokenId];\n        uint32 leaderSolutionId = chl.solutions;\n        uint32 rank = leaderSolutionId - solutionId + 1;\n        uint32 percentage = 0;\n        if (solutionId > 1) {\n            ExtraDetails storage prevDetails = extraDetails[tokenId - 1];\n            percentage = (details.gas * 100) / prevDetails.gas;\n        }\n        return TokenDetails({\n            challengeId: challengeId,\n            challenge: chl.target,\n            leaderGas: leaderDetails.gas,\n            leaderSolutionId: leaderSolutionId,\n            leaderSolver: leaderDetails.solver,\n            leaderOwner: _ownerOf[leaderTokenId],\n            leaderSubmission: leaderDetails.code,\n            gas: details.gas,\n            solutionId: solutionId,\n            rank: rank,\n            improvementPercentage: percentage,\n            solver: details.solver,\n            owner: _ownerOf[tokenId],\n            submission: details.code\n        });\n    }\n    function tokenURI(uint256 tokenId) public view override returns (string memory) {\n        TokenDetails memory details = tokenDetails(tokenId);\n        string memory description = string.concat(details.challenge.description(), \"\\\\n\\\\n\", leaderboardString(tokenId));\n        return string.concat(\n            \"data:application/json;base64,\",\n            Base64.encode(\n                bytes(\n                    string.concat(\n                        '{\"name\":\"Optimizor Club: ',\n                        details.challenge.name(),\n                        '\",\"description\":\"',\n                        description,\n                        '\",\"attributes\":',\n                        attributesJSON(details),\n                        ',\"image\":\"data:image/svg+xml;base64,',\n                        Base64.encode(bytes(svg(tokenId, details))),\n                        '\"}'\n                    )\n                )\n            )\n        );\n    }\n    function leaderboard(uint256 tokenId) public view returns (address[] memory board) {\n        (uint256 challengeId,) = unpackTokenId(tokenId);\n        uint32 winners = challenges[challengeId].solutions;\n        board = new address[](winners);\n        unchecked {\n            for (uint32 i = 1; i <= winners; ++i) {\n                ExtraDetails storage details = extraDetails[packTokenId(challengeId, i)];\n                board[i - 1] = details.solver;\n            }\n        }\n    }\n    function leaderboardString(uint256 tokenId) private view returns (string memory) {\n        address[] memory leaders = leaderboard(tokenId);\n        string memory leadersStr = \"\";\n        uint256 lIdx = leaders.length;\n        unchecked {\n            for (uint256 i = 0; i < leaders.length; ++i) {\n                leadersStr = string.concat(\n                    \"\\\\n\",\n                    LibString.toString(lIdx),\n                    \". \",\n                    HexString.toHexString(uint256(uint160(leaders[i])), 20),\n                    leadersStr\n                );\n                --lIdx;\n            }\n        }\n        return string.concat(\"Leaderboard:\\\\n\", leadersStr);\n    }\n    function attributesJSON(TokenDetails memory details) private view returns (string memory attributes) {\n        uint32 rank = details.rank;\n        attributes = string.concat(\n            '[{\"trait_type\":\"Challenge\",\"value\":\"',\n            details.challenge.name(),\n            '\"},{\"trait_type\":\"Gas used\",\"value\":',\n            LibString.toString(details.gas),\n            ',\"display_type\":\"number\"},{\"trait_type\":\"Code size\",\"value\":',\n            LibString.toString(details.submission.code.length),\n            ',\"display_type\":\"number\"},{\"trait_type\":\"Improvement percentage\",\"value\":\"',\n            LibString.toString(details.improvementPercentage),\n            '%\"},{\"trait_type\":\"Solver\",\"value\":\"',\n            HexString.toHexString(uint256(uint160(details.solver)), 20),\n            '\"},{\"trait_type\":\"Rank\",\"value\":',\n            LibString.toString(rank),\n            ',\"display_type\":\"number\"},{\"trait_type\":\"Leader\",\"value\":\"',\n            (rank == 1) ? \"Yes\" : \"No\",\n            '\"},{\"trait_type\":\"Top 3\",\"value\":\"',\n            (rank <= 3) ? \"Yes\" : \"No\",\n            '\"},{\"trait_type\":\"Top 10\",\"value\":\"',\n            (rank <= 10) ? \"Yes\" : \"No\",\n            '\"}]'\n        );\n    }\n    function scale(uint8 value, uint256 minOut, uint256 maxOut) private pure returns (uint256) {\n        unchecked {\n            return ((uint256(value) * (maxOut - minOut)) / 255) + minOut;\n        }\n    }\n    function svg(uint256 tokenId, TokenDetails memory details) private view returns (string memory) {\n        uint256 gradRgb = 0;\n        if (details.rank > 10) {\n            gradRgb = 0xbebebe;\n        } else if (details.rank > 3) {\n            uint256 fRank;\n            uint256 init = 40;\n            uint256 factor = 15;\n            unchecked {\n                fRank = init + details.rank * factor;\n            }\n            gradRgb = (uint256(fRank) << 16) | (uint256(fRank) << 8) | uint256(fRank);\n        }\n        NFTSVG.SVGParams memory svgParams = NFTSVG.SVGParams({\n            projectName: \"Optimizor Club\",\n            challengeName: details.challenge.name(),\n            solverAddr: HexString.toHexString(uint256(uint160(address(details.owner))), 20),\n            challengeAddr: HexString.toHexString(uint256(uint160(address(details.challenge))), 20),\n            gasUsed: details.gas,\n            gasOpti: details.improvementPercentage,\n            tokenId: tokenId,\n            rank: details.rank,\n            participants: details.leaderSolutionId,\n            color: HexString.toHexStringNoPrefix(gradRgb, 3),\n            x1: scale(NFTSVG.getCircleCoord(address(details.challenge), 16, tokenId), 16, 274),\n            y1: scale(NFTSVG.getCircleCoord(address(details.solver), 16, tokenId), 100, 484),\n            x2: scale(NFTSVG.getCircleCoord(address(details.challenge), 32, tokenId), 16, 274),\n            y2: scale(NFTSVG.getCircleCoord(address(details.solver), 32, tokenId), 100, 484),\n            x3: scale(NFTSVG.getCircleCoord(address(details.challenge), 48, tokenId), 16, 274),\n            y3: scale(NFTSVG.getCircleCoord(address(details.solver), 48, tokenId), 100, 484)\n        });\n        return NFTSVG.generateSVG(svgParams, details.challenge.svg(tokenId));\n    }\n}\nabstract contract OptimizorAdmin is OptimizorNFT, Owned {\n    PurityChecker public purityChecker;\n    error ChallengeExists(uint256 challengeId);\n    event PurityCheckerUpdated(PurityChecker newPurityChecker);\n    event ChallengeAdded(uint256 challengeId, IChallenge);\n    constructor(PurityChecker _purityChecker) Owned(msg.sender) {\n        updatePurityChecker(_purityChecker);\n    }\n    function updatePurityChecker(PurityChecker _purityChecker) public onlyOwner {\n        purityChecker = _purityChecker;\n        emit PurityCheckerUpdated(_purityChecker);\n    }\n    function addChallenge(uint256 id, IChallenge challenge) external onlyOwner {\n        ChallengeInfo storage chl = challenges[id];\n        if (address(chl.target) != address(0)) {\n            revert ChallengeExists(id);\n        }\n        chl.target = challenge;\n        emit ChallengeAdded(id, challenge);\n    }\n}\nuint256 constant EPOCH = 64;\ncontract Optimizor is OptimizorAdmin {\n    struct Submission {\n        address sender;\n        uint96 blockNumber;\n    }\n    mapping(bytes32 => Submission) public submissions;\n    error CodeAlreadySubmitted();\n    error TooEarlyToChallenge();\n    error InvalidRecipient();\n    error CodeNotSubmitted();\n    error NotPure();\n    error NotOptimizor();\n    constructor(PurityChecker _purityChecker) OptimizorAdmin(_purityChecker) {}\n    function commit(bytes32 key) external {\n        if (submissions[key].sender != address(0)) {\n            revert CodeAlreadySubmitted();\n        }\n        submissions[key] = Submission({sender: msg.sender, blockNumber: uint96(block.number)});\n    }\n    function challenge(uint256 id, address target, address recipient, uint256 salt) external {\n        ChallengeInfo storage chl = challenges[id];\n        bytes32 key = keccak256(abi.encode(msg.sender, target.codehash, salt));\n        if (submissions[key].blockNumber + EPOCH >= block.number) {\n            revert TooEarlyToChallenge();\n        }\n        if (submissions[key].sender == address(0)) {\n            revert CodeNotSubmitted();\n        }\n        if (address(chl.target) == address(0)) {\n            revert ChallengeNotFound(id);\n        }\n        if (recipient == address(0)) {\n            revert InvalidRecipient();\n        }\n        if (!purityChecker.check(target)) {\n            revert NotPure();\n        }\n        uint32 gas = chl.target.run(target, block.difficulty);\n        uint256 leaderTokenId = packTokenId(id, chl.solutions);\n        uint32 leaderGas = extraDetails[leaderTokenId].gas;\n        if ((leaderGas != 0) && (leaderGas <= gas)) {\n            revert NotOptimizor();\n        }\n        unchecked {\n            ++chl.solutions;\n        }\n        uint256 tokenId = packTokenId(id, chl.solutions);\n        ERC721._mint(recipient, tokenId);\n        extraDetails[tokenId] = ExtraDetails(target, recipient, gas);\n    }\n}"
  },
  {
    "path": "test/benchmarks/chains.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n// This is an adapted version of StdCheats by foundry:\n// https://github.com/foundry-rs/forge-std/blob/master/src/StdCheats.sol\ncontract StdCheatsSafe {\n    struct Chain {\n        string name;\n        uint256 chainId;\n        string rpcUrl;\n    }\n\n    struct Chains {\n        Chain Anvil;\n        Chain Hardhat;\n        Chain Mainnet;\n        Chain Goerli;\n        Chain Sepolia;\n        Chain Optimism;\n        Chain OptimismGoerli;\n        Chain ArbitrumOne;\n        Chain ArbitrumOneGoerli;\n        Chain ArbitrumNova;\n        Chain Polygon;\n        Chain PolygonMumbai;\n        Chain Avalanche;\n        Chain AvalancheFuji;\n        Chain BnbSmartChain;\n        Chain BnbSmartChainTestnet;\n        Chain GnosisChain;\n    }\n\n    Chains stdChains;\n\n    function f(string[2][] memory rpcs) public returns (uint256) {\n        stdChains = Chains({\n            Anvil: Chain(\"Anvil\", 31337, \"http://127.0.0.1:8545\"),\n            Hardhat: Chain(\"Hardhat\", 31337, \"http://127.0.0.1:8545\"),\n            Mainnet: Chain(\"Mainnet\", 1, \"https://api.mycryptoapi.com/eth\"),\n            Goerli: Chain(\"Goerli\", 5, \"https://goerli.infura.io/v3/84842078b09946638c03157f83405213\"),\n            Sepolia: Chain(\"Sepolia\", 11155111, \"https://rpc.sepolia.dev\"),\n            Optimism: Chain(\"Optimism\", 10, \"https://mainnet.optimism.io\"),\n            OptimismGoerli: Chain(\"OptimismGoerli\", 420, \"https://goerli.optimism.io\"),\n            ArbitrumOne: Chain(\"ArbitrumOne\", 42161, \"https://arb1.arbitrum.io/rpc\"),\n            ArbitrumOneGoerli: Chain(\"ArbitrumOneGoerli\", 421613, \"https://goerli-rollup.arbitrum.io/rpc\"),\n            ArbitrumNova: Chain(\"ArbitrumNova\", 42170, \"https://nova.arbitrum.io/rpc\"),\n            Polygon: Chain(\"Polygon\", 137, \"https://polygon-rpc.com\"),\n            PolygonMumbai: Chain(\"PolygonMumbai\", 80001, \"https://rpc-mumbai.matic.today\"),\n            Avalanche: Chain(\"Avalanche\", 43114, \"https://api.avax.network/ext/bc/C/rpc\"),\n            AvalancheFuji: Chain(\"AvalancheFuji\", 43113, \"https://api.avax-test.network/ext/bc/C/rpc\"),\n            BnbSmartChain: Chain(\"BnbSmartChain\", 56, \"https://bsc-dataseed1.binance.org\"),\n            BnbSmartChainTestnet: Chain(\"BnbSmartChainTestnet\", 97, \"https://data-seed-prebsc-1-s1.binance.org:8545\"),\n            GnosisChain: Chain(\"GnosisChain\", 100, \"https://rpc.gnosischain.com\")\n        });\n\n        for (uint256 i = 0; i < rpcs.length; i++) {\n            (string memory name, string memory rpcUrl) = (rpcs[i][0], rpcs[i][1]);\n            // forgefmt: disable-start\n            if (isEqual(name, \"anvil\")) stdChains.Anvil.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"hardhat\")) stdChains.Hardhat.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"mainnet\")) stdChains.Mainnet.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"goerli\")) stdChains.Goerli.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"sepolia\")) stdChains.Sepolia.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"optimism\")) stdChains.Optimism.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"optimism_goerli\", \"optimism-goerli\")) stdChains.OptimismGoerli.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"arbitrum_one\", \"arbitrum-one\")) stdChains.ArbitrumOne.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"arbitrum_one_goerli\", \"arbitrum-one-goerli\")) stdChains.ArbitrumOneGoerli.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"arbitrum_nova\", \"arbitrum-nova\")) stdChains.ArbitrumNova.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"polygon\")) stdChains.Polygon.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"polygon_mumbai\", \"polygon-mumbai\")) stdChains.PolygonMumbai.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"avalanche\")) stdChains.Avalanche.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"avalanche_fuji\", \"avalanche-fuji\")) stdChains.AvalancheFuji.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"bnb_smart_chain\", \"bnb-smart-chain\")) stdChains.BnbSmartChain.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"bnb_smart_chain_testnet\", \"bnb-smart-chain-testnet\")) stdChains.BnbSmartChainTestnet.rpcUrl = rpcUrl;\n            else if (isEqual(name, \"gnosis_chain\", \"gnosis-chain\")) stdChains.GnosisChain.rpcUrl = rpcUrl;\n            // forgefmt: disable-end\n        }\n        return 0;\n    }\n\n    function isEqual(string memory a, string memory b) private pure returns (bool) {\n        return keccak256(abi.encode(a)) == keccak256(abi.encode(b));\n    }\n\n    function isEqual(string memory a, string memory b, string memory c) private pure returns (bool) {\n        return keccak256(abi.encode(a)) == keccak256(abi.encode(b))\n            || keccak256(abi.encode(a)) == keccak256(abi.encode(c));\n    }\n}\n\n\n"
  },
  {
    "path": "test/benchmarks/external-setup.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Downloads and configures external projects used for benchmarking by external.sh.\n#\n# By default the download location is the benchmarks/ dir at the repository root.\n# A different directory can be provided via the BENCHMARK_DIR variable.\n#\n# Dependencies: foundry, git.\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2024 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -euo pipefail\n\nrepo_root=$(cd \"$(dirname \"$0\")/../../\" && pwd)\nBENCHMARK_DIR=\"${BENCHMARK_DIR:-${repo_root}/benchmarks}\"\n\nfunction neutralize_version_pragmas {\n    find . -name '*.sol' -type f -print0 | xargs -0 \\\n        sed -i -E -e 's/pragma solidity [^;]+;/pragma solidity *;/'\n}\n\nfunction neutralize_via_ir {\n    sed -i '/^via_ir\\s*=.*$/d' foundry.toml\n}\n\nfunction setup_foundry_project {\n    local subdir=\"$1\"\n    local ref_type=\"$2\"\n    local ref=\"$3\"\n    local repo_url=\"$4\"\n    local install_function=\"${5:-}\"\n\n    printf \">>> %-22s | \" \"$subdir\"\n\n    [[ $ref_type == commit || $ref_type == tag ]] || assertFail\n\n    [[ ! -e \"$subdir\" ]] || { printf \"already exists\\n\"; return; }\n    printf \"downloading...\\n\\n\"\n\n    if [[ $ref_type == tag ]]; then\n        git clone --depth=1 \"$repo_url\" \"$subdir\" --branch \"$ref\"\n        pushd \"$subdir\"\n    else\n        git clone \"$repo_url\" \"$subdir\"\n        pushd \"$subdir\"\n        git checkout \"$ref\"\n    fi\n    if [[ -z $install_function ]]; then\n        forge install\n    else\n        \"$install_function\"\n    fi\n\n    [[ ! -e foundry.toml ]] || neutralize_via_ir\n    neutralize_version_pragmas\n    popd\n    echo\n}\n\nfunction install_liquity {\n    sed -i -e 's|git@github.com:|https://github.com/|g' .gitmodules\n    forge install\n}\n\nfunction install_old_uniswap {\n    openzeppelin_version=$(sed -n 's|\\s\\+\"@openzeppelin/contracts\": \"\\([0-9.]\\+\\)\"|\\1|p' package.json)\n    rm package.json\n    rm yarn.lock\n    npm install \"@openzeppelin/contracts@${openzeppelin_version}\"\n}\n\nfunction install_sablier {\n    # NOTE: To avoid hard-coding dependency versions here we'd have to install them from npm\n    forge install --no-commit \\\n        foundry-rs/forge-std@v1.8.2 \\\n        OpenZeppelin/openzeppelin-contracts@v5.0.2 \\\n        PaulRBerg/prb-math@v4.0.3 \\\n        evmcheb/solarray@a547630 \\\n        Vectorized/solady@v0.0.208\n   cat <<EOF > remappings.txt\n@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\nforge-std/=lib/forge-std/\n@prb/math/=lib/prb-math/\nsolarray/=lib/solarray/\nsolady/=lib/solady/\nEOF\n}\n\nmkdir -p \"$BENCHMARK_DIR\"\ncd \"$BENCHMARK_DIR\"\n\nsetup_foundry_project openzeppelin-5.0.2/ tag v5.0.2 https://github.com/OpenZeppelin/openzeppelin-contracts\nsetup_foundry_project openzeppelin-4.9.0/ tag v4.9.0 https://github.com/OpenZeppelin/openzeppelin-contracts\nsetup_foundry_project openzeppelin-4.8.0/ tag v4.8.0 https://github.com/OpenZeppelin/openzeppelin-contracts\nsetup_foundry_project openzeppelin-4.7.0/ tag v4.7.0 https://github.com/OpenZeppelin/openzeppelin-contracts\n\nsetup_foundry_project liquity-2024-10-30/ commit 7f93a3f1781dfce2c4e0b6a7262deddd8a10e45b https://github.com/liquity/V2-gov install_liquity\n\nsetup_foundry_project uniswap-v4-2024-06-06/ commit ae86975b058d386c9be24e8994236f662affacdb https://github.com/Uniswap/v4-core\nsetup_foundry_project uniswap-v4-2022-06-16/ commit 9aeddf76e1b8646908fbcc7519c882bf458b794d https://github.com/Uniswap/v4-core install_old_uniswap\n\nsetup_foundry_project farcaster-3.1.0/ tag v3.1.0 https://github.com/farcasterxyz/contracts\n\n# NOTE: Can't select the tag with `git clone` because a branch of the same name exists.\nsetup_foundry_project seaport-1.6/ commit tags/1.6 https://github.com/ProjectOpenSea/seaport\n\nsetup_foundry_project eigenlayer-0.3.0/ tag v0.3.0-holesky-rewards https://github.com/Layr-Labs/eigenlayer-contracts\n\nsetup_foundry_project sablier-v2-1.2.0/ tag v1.2.0 https://github.com/sablier-labs/v2-core install_sablier\n"
  },
  {
    "path": "test/benchmarks/external.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Benchmarks a solc binary by compiling several external projects, with and without IR.\n#\n# The script expects each project to be already downloaded and set up by external-setup.sh.\n# A different directory can be provided via the BENCHMARK_DIR variable.\n#\n# The script will by default attempt to use a solc from the default build directory,\n# relative to the script directory. To use a different binary you can provide a different\n# location of the build directory (via SOLIDITY_BUILD_DIR variable) or simply specify\n# the full path to the binary as the script argument.\n#\n# Dependencies: foundry, time.\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2024 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -euo pipefail\n\nrepo_root=$(cd \"$(dirname \"$0\")/../../\" && pwd)\nSOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${repo_root}/build}\nBENCHMARK_DIR=\"${BENCHMARK_DIR:-${repo_root}/benchmarks}\"\n\n# shellcheck source=scripts/common.sh\nsource \"${repo_root}/scripts/common.sh\"\n# shellcheck source=scripts/common_cmdline.sh\nsource \"${repo_root}/scripts/common_cmdline.sh\"\n\n(( $# <= 2 )) || fail \"Too many arguments. Usage: external.sh [<solc-path>] [<num-repeats>]\"\n\nsolc=\"${1:-${SOLIDITY_BUILD_DIR}/solc/solc}\"\nnum_repeats=\"${2:-1}\"\ncommand_available \"$solc\" --version\ncommand_available \"$(type -P time)\" --version\n\nfunction benchmark_project {\n    local pipeline=\"$1\"\n    local project=\"$2\"\n    [[ $pipeline == legacy || $pipeline == ir ]] || assertFail\n\n    cd \"$project\"\n    local foundry_command=(forge build --use \"$solc\" --optimize --offline --no-cache)\n    [[ $pipeline == ir ]] && foundry_command+=(--via-ir)\n    local time_file=\"../time-and-status-${project}-${pipeline}.txt\"\n\n    # NOTE: The pipeline may fail with \"Stack too deep\" in some cases. That's fine.\n    # We note the exit code and will later show full output.\n    gnu_time_to_json_file \"$time_file\" \\\n        \"${foundry_command[@]}\" \\\n        > /dev/null \\\n        2> \"../stderr-${project}-${pipeline}.log\" || true\n\n    printf '| %-21s | %8s | %6.2f s | %9d MiB | %9d |\\n' \\\n        \"$project\" \\\n        \"$pipeline\" \\\n        \"$(jq '(.user + .sys) * 100 | round / 100' \"$time_file\")\" \\\n        \"$(jq '.mem / 1024 | round' \"$time_file\")\" \\\n        \"$(jq '.exit' \"$time_file\")\"\n    cd ..\n}\n\nbenchmarks=(\n    # Fastest ones first so that we get *some* output quickly\n    uniswap-v4-2022-06-16  # compiles via IR with solc >=0.8.12\n    openzeppelin-5.0.2     # compiles via IR with solc >=0.8.26\n    openzeppelin-4.9.0     # compiles via IR with solc 0.8.10-0.8.14 and >=0.8.26\n    liquity-2024-10-30     # compiles via IR with solc >=0.8.24\n    openzeppelin-4.7.0     # compiles via IR with solc >=0.8.10\n    openzeppelin-4.8.0     # compiles via IR with solc >=0.8.10\n    uniswap-v4-2024-06-06  # compiles via IR with solc >=0.8.24\n    eigenlayer-0.3.0       # compiles via IR with solc >=0.8.18\n    sablier-v2-1.2.0       # compiles via IR with solc >=0.8.28 (maybe >=0.8.26)\n    seaport-1.6            # StackTooDeep via IR\n    farcaster-3.1.0        # StackTooDeep via IR\n)\n\nmkdir -p \"$BENCHMARK_DIR\"\ncd \"$BENCHMARK_DIR\"\n\necho \"|         File          | Pipeline |   Time   | Memory (peak) | Exit code |\"\necho \"|-----------------------|----------|---------:|--------------:|----------:|\"\n\nfor project in \"${benchmarks[@]}\"; do\n    for ((i=0; i<num_repeats; i++)); do\n        benchmark_project legacy \"$project\"\n    done\n    for ((i=0; i<num_repeats; i++)); do\n        benchmark_project ir \"$project\"\n    done\ndone\n\nfor project in \"${benchmarks[@]}\"; do\n    for pipeline in legacy ir; do\n        if [[ -s stderr-${project}-${pipeline}.log ]]; then\n            echo\n            echo \"==================================\"\n            echo \"stderr for ${project} via ${pipeline}\"\n            echo \"==================================\"\n            cat \"stderr-${project}-${pipeline}.log\"\n        fi\n    done\ndone\n"
  },
  {
    "path": "test/benchmarks/local.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Bash script to run optimizer performance tests.\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2022 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -euo pipefail\n\nREPO_ROOT=$(cd \"$(dirname \"$0\")/../../\" && pwd)\nSOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${REPO_ROOT}/build}\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n# shellcheck source=scripts/common_cmdline.sh\nsource \"${REPO_ROOT}/scripts/common_cmdline.sh\"\n\n(( $# <= 1 )) || fail \"Too many arguments. Usage: local.sh [<solc-path>]\"\n\nsolc=\"${1:-${SOLIDITY_BUILD_DIR}/solc/solc}\"\ncommand_available \"$solc\" --version\ncommand_available \"$(type -P time)\" --version\n\noutput_dir=$(mktemp -d -t solc-benchmark-XXXXXX)\n\nfunction cleanup() {\n    rm -r \"${output_dir}\"\n    exit\n}\n\ntrap cleanup SIGINT SIGTERM\n\nfunction benchmark_contract {\n    local pipeline=\"$1\"\n    local input_path=\"$2\"\n\n    local solc_command=(\"${solc}\" --optimize --bin --color \"${input_path}\")\n    [[ $pipeline == ir ]] && solc_command+=(--via-ir)\n    local time_file=\"${output_dir}/time-and-status-${pipeline}.txt\"\n\n    # NOTE: Legacy pipeline may fail with \"Stack too deep\" in some cases. That's fine.\n    gnu_time_to_json_file \"$time_file\" \\\n        \"${solc_command[@]}\" \\\n        > \"${output_dir}/bytecode-${pipeline}.bin\" \\\n        2>> \"${output_dir}/benchmark-warn-err.txt\" || [[ $pipeline == legacy ]]\n\n    printf '| %-20s | %8s | %7d bytes | %6.2f s | %9d MiB | %9d |\\n' \\\n        '`'\"$input_file\"'`' \\\n        \"$pipeline\" \\\n        \"$(bytecode_size < \"${output_dir}/bytecode-${pipeline}.bin\")\" \\\n        \"$(jq '(.user + .sys) * 100 | round / 100' \"$time_file\")\" \\\n        \"$(jq '.mem / 1024 | round' \"$time_file\")\" \\\n        \"$(jq '.exit' \"$time_file\")\"\n}\n\nbenchmarks=(\"verifier.sol\" \"OptimizorClub.sol\" \"chains.sol\")\n\necho \"|         File         | Pipeline | Bytecode size |   Time   | Memory (peak) | Exit code |\"\necho \"|----------------------|----------|--------------:|---------:|--------------:|----------:|\"\n\nfor input_file in \"${benchmarks[@]}\"\ndo\n    benchmark_contract legacy \"${REPO_ROOT}/test/benchmarks/${input_file}\"\n    benchmark_contract ir     \"${REPO_ROOT}/test/benchmarks/${input_file}\"\ndone\n\necho\necho \"=======================================================\"\necho \"Warnings and errors generated during run:\"\necho \"=======================================================\"\necho \"$(< \"${output_dir}/benchmark-warn-err.txt\")\"\n\ncleanup\n"
  },
  {
    "path": "test/benchmarks/verifier.sol",
    "content": "// This file is MIT Licensed.\n//\n// Copyright 2017 Christian Reitwiessner\n// 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:\n// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n// 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.\npragma solidity ^0.8.0;\nlibrary Pairing {\n    struct G1Point {\n        uint X;\n        uint Y;\n    }\n    // Encoding of field elements is: X[0] * z + X[1]\n    struct G2Point {\n        uint[2] X;\n        uint[2] Y;\n    }\n    /// @return the generator of G1\n    function P1() pure internal returns (G1Point memory) {\n        return G1Point(1, 2);\n    }\n    /// @return the generator of G2\n    function P2() pure internal returns (G2Point memory) {\n        return G2Point(\n            [10857046999023057135944570762232829481370756359578518086990519993285655852781,\n             11559732032986387107991004021392285783925812861821192530917403151452391805634],\n            [8495653923123431417604973247489272438418190587263600148770280649306958101930,\n             4082367875863433681332203403145435568316851327593401208105741076214120093531]\n        );\n    }\n    /// @return the negation of p, i.e. p.addition(p.negate()) should be zero.\n    function negate(G1Point memory p) pure internal returns (G1Point memory) {\n        // The prime q in the base field F_q for G1\n        uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n        if (p.X == 0 && p.Y == 0)\n            return G1Point(0, 0);\n        return G1Point(p.X, q - (p.Y % q));\n    }\n    /// @return r the sum of two points of G1\n    function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) {\n        uint[4] memory input;\n        input[0] = p1.X;\n        input[1] = p1.Y;\n        input[2] = p2.X;\n        input[3] = p2.Y;\n        bool success;\n        assembly {\n            success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)\n            // Use \"invalid\" to make gas estimation work\n            switch success case 0 { invalid() }\n        }\n        require(success);\n    }\n\n\n    /// @return r the product of a point on G1 and a scalar, i.e.\n    /// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p.\n    function scalar_mul(G1Point memory p, uint s) internal view returns (G1Point memory r) {\n        uint[3] memory input;\n        input[0] = p.X;\n        input[1] = p.Y;\n        input[2] = s;\n        bool success;\n        assembly {\n            success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)\n            // Use \"invalid\" to make gas estimation work\n            switch success case 0 { invalid() }\n        }\n        require (success);\n    }\n    /// @return the result of computing the pairing check\n    /// e(p1[0], p2[0]) *  .... * e(p1[n], p2[n]) == 1\n    /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should\n    /// return true.\n    function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) {\n        require(p1.length == p2.length);\n        uint elements = p1.length;\n        uint inputSize = elements * 6;\n        uint[] memory input = new uint[](inputSize);\n        for (uint i = 0; i < elements; i++)\n        {\n            input[i * 6 + 0] = p1[i].X;\n            input[i * 6 + 1] = p1[i].Y;\n            input[i * 6 + 2] = p2[i].X[1];\n            input[i * 6 + 3] = p2[i].X[0];\n            input[i * 6 + 4] = p2[i].Y[1];\n            input[i * 6 + 5] = p2[i].Y[0];\n        }\n        uint[1] memory out;\n        bool success;\n        assembly {\n            success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)\n            // Use \"invalid\" to make gas estimation work\n            switch success case 0 { invalid() }\n        }\n        require(success);\n        return out[0] != 0;\n    }\n    /// Convenience method for a pairing check for two pairs.\n    function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal view returns (bool) {\n        G1Point[] memory p1 = new G1Point[](2);\n        G2Point[] memory p2 = new G2Point[](2);\n        p1[0] = a1;\n        p1[1] = b1;\n        p2[0] = a2;\n        p2[1] = b2;\n        return pairing(p1, p2);\n    }\n    /// Convenience method for a pairing check for three pairs.\n    function pairingProd3(\n            G1Point memory a1, G2Point memory a2,\n            G1Point memory b1, G2Point memory b2,\n            G1Point memory c1, G2Point memory c2\n    ) internal view returns (bool) {\n        G1Point[] memory p1 = new G1Point[](3);\n        G2Point[] memory p2 = new G2Point[](3);\n        p1[0] = a1;\n        p1[1] = b1;\n        p1[2] = c1;\n        p2[0] = a2;\n        p2[1] = b2;\n        p2[2] = c2;\n        return pairing(p1, p2);\n    }\n    /// Convenience method for a pairing check for four pairs.\n    function pairingProd4(\n            G1Point memory a1, G2Point memory a2,\n            G1Point memory b1, G2Point memory b2,\n            G1Point memory c1, G2Point memory c2,\n            G1Point memory d1, G2Point memory d2\n    ) internal view returns (bool) {\n        G1Point[] memory p1 = new G1Point[](4);\n        G2Point[] memory p2 = new G2Point[](4);\n        p1[0] = a1;\n        p1[1] = b1;\n        p1[2] = c1;\n        p1[3] = d1;\n        p2[0] = a2;\n        p2[1] = b2;\n        p2[2] = c2;\n        p2[3] = d2;\n        return pairing(p1, p2);\n    }\n}\n\ncontract Verifier {\n    using Pairing for *;\n    struct VerifyingKey {\n        Pairing.G1Point alpha;\n        Pairing.G2Point beta;\n        Pairing.G2Point gamma;\n        Pairing.G2Point delta;\n        Pairing.G1Point[] gamma_abc;\n    }\n    struct Proof {\n        Pairing.G1Point a;\n        Pairing.G2Point b;\n        Pairing.G1Point c;\n    }\n    function verifyingKey() pure internal returns (VerifyingKey memory vk) {\n        vk.alpha = Pairing.G1Point(uint256(0x1e19a8a58ad52243374aeded373b7e89656ea339b9fa8ace98dd5fb221885ea2), uint256(0x2e66a9a67f1a9060a51da039c91c3402d1f46b71bbf10c7348ac4f13c3906736));\n        vk.beta = Pairing.G2Point([uint256(0x1ca3e556290187c64a1057061f419a078dc71353f6af1066c03d7e1448bbc119), uint256(0x2bbc1b80e59743b489ec811b4ebf30a1ff540c2c37ced63d360b94f92f0a41fb)], [uint256(0x07eceb98d2fb10fa7363b45f51aa3d3ef3d511b482790645039a2562e2070f30), uint256(0x1c3e076d2aaf914abd6a49b72c4205669d3d1cbe4a4bf97b9ee49ac0fbbdbda9)]);\n        vk.gamma = Pairing.G2Point([uint256(0x222c0019521d3e52881431be17cacaf8a7379398dd0833f60a2ac45f1c3fcd42), uint256(0x1018dbb94cd920bd55af4e2b12a9f740c6b38748a163b5dbd37c5ef6cf74708f)], [uint256(0x18bf34dc86b549a92f316f7a32070a3ce45a0f38fa45dda1162c4b6498baf286), uint256(0x12848d5a670b6102d5bd45d2b8250d50361001ea335ff6a1405a52504c22b8ac)]);\n        vk.delta = Pairing.G2Point([uint256(0x13b8e16c40a6a299ea42107a97f881f9fa89986dcd5234ecb6919caf756ac1cb), uint256(0x25b64e4978690cd7cb531dbab0119148c96f5fc0c984c0cafb290bb75f033a09)], [uint256(0x1758eaa970929deff5e96e5852d21790c32591dbb13bc63e3df046f0271479a4), uint256(0x14d0b4222ad1710c6330e4bd8ad8f0d7b8f4cff0a37793d53001800e49f41192)]);\n        vk.gamma_abc = new Pairing.G1Point[](9);\n        vk.gamma_abc[0] = Pairing.G1Point(uint256(0x0925dc800d3a577859439a049f8ed0ae7a37dcd36652de478d662c08907a7626), uint256(0x1f7f76e299220ebf3da17bb415d25e6574e142391972dbd1513cf81341975cb5));\n        vk.gamma_abc[1] = Pairing.G1Point(uint256(0x0e67dddfd91adad72376c56cbd98d5cfa4df5217d6115ff26ec741d0154f0bd8), uint256(0x0b97b2ddfdf4c31916d98e384bee3b24bfa0fc59a21ab489153f4dcd1a9a48ca));\n        vk.gamma_abc[2] = Pairing.G1Point(uint256(0x1416b354665883cbbc5f5541012d1f8dd87ebb4415b3ee431be0804fff290bbf), uint256(0x1a284dd2eff43e6cb5aaea43dd9bee022ef0c91d90d0803cf5f7e4677e94a271));\n        vk.gamma_abc[3] = Pairing.G1Point(uint256(0x2526852e7f009b4afa1fe0e1d30334c6e516fac223866b81a830b472164bdfe7), uint256(0x28adf6fbe54ba40afa91555c18477ad3a2f0a460f68d55a15b4e0c264b9c11c2));\n        vk.gamma_abc[4] = Pairing.G1Point(uint256(0x22feae4a12bfb751638cd76b2373e84884ba4adef575ea14ed50c5954d31d410), uint256(0x108c3da0ffd7eda1fe7789e41693146beb979bd1644b19bbd517742ca3841348));\n        vk.gamma_abc[5] = Pairing.G1Point(uint256(0x081477a5c52f41533cf6ca4f778ab922d59ba44b5a5e3fbdbf34ed8dc1a47a8d), uint256(0x0f2624780bd75b9f6c47f7bee582d02f1f983529b8aa9493ca848e38f2ec8447));\n        vk.gamma_abc[6] = Pairing.G1Point(uint256(0x0603e7413c605d1e9b9352a62f0208e2bbd247d3cf3b3721f72c3a9407d679b9), uint256(0x0ce2d2dca8ae14ac4fd2f3fd89e602cdb45de815cf3ba183a25a47d877d9f6f5));\n        vk.gamma_abc[7] = Pairing.G1Point(uint256(0x05bbe6b58285021fb843123971f8e2cfdd207b02c0aef5923ffe7ac841ee0cc9), uint256(0x2da1d3c2049546a7b46aaf89a8a7de493470087ce9af8ba37673f5ee8c35eb1b));\n        vk.gamma_abc[8] = Pairing.G1Point(uint256(0x2c721270df9ba8884d309140f3a4b150a8e53a6c9d09bd8fc7c9aa3c4901aa8d), uint256(0x0de2cb1684759e693e855711fa1c381ae737e463447c3817df507a02064b470f));\n    }\n    function verify(uint[] memory input, Proof memory proof) internal view returns (uint) {\n        uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n        VerifyingKey memory vk = verifyingKey();\n        require(input.length + 1 == vk.gamma_abc.length);\n        // Compute the linear combination vk_x\n        Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\n        for (uint i = 0; i < input.length; i++) {\n            require(input[i] < snark_scalar_field);\n            vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.gamma_abc[i + 1], input[i]));\n        }\n        vk_x = Pairing.addition(vk_x, vk.gamma_abc[0]);\n        if(!Pairing.pairingProd4(\n             proof.a, proof.b,\n             Pairing.negate(vk_x), vk.gamma,\n             Pairing.negate(proof.c), vk.delta,\n             Pairing.negate(vk.alpha), vk.beta)) return 1;\n        return 0;\n    }\n    function verifyTx(\n            Proof memory proof, uint[8] memory input\n        ) public view returns (bool r) {\n        uint[] memory inputValues = new uint[](8);\n\n        for(uint i = 0; i < input.length; i++){\n            inputValues[i] = input[i];\n        }\n        if (verify(inputValues, proof) == 0) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "test/buglistTests.js",
    "content": "#!/usr/bin/env node\n\n\"use strict\";\n\nvar util = require('util')\nvar exec = util.promisify(require('child_process').exec)\nvar mktemp = require('mktemp');\nvar download = require('download')\nvar JSONPath = require('JSONPath')\nvar fs = require('fs')\nvar bugs = JSON.parse(fs.readFileSync(__dirname + '/../docs/bugs.json', 'utf8'))\n\nvar bugsByName = {}\nfor (var i in bugs)\n{\n    if (bugs[i].name in bugsByName)\n    {\n        throw \"Duplicate bug name: \" + bugs[i].name\n    }\n    bugsByName[bugs[i].name] = bugs[i]\n}\n\nvar tests = fs.readFileSync(__dirname + '/buglist_test_vectors.md', 'utf8')\n\nvar testVectorParser = /\\s*#\\s+(\\S+)\\s+## buggy\\n([^#]*)## fine\\n([^#]*)/g\n\nrunTests()\n\nasync function runTests()\n{\n\tvar result;\n\twhile ((result = testVectorParser.exec(tests)) !== null)\n\t{\n\t\tvar name = result[1]\n\t\tvar buggy = result[2].split('\\n--\\n')\n\t\tvar fine = result[3].split('\\n--\\n')\n\t\tconsole.log(\"Testing \" + name + \" with \" + buggy.length + \" buggy and \" + fine.length + \" fine instances\")\n\n\t\ttry {\n\t\t\tawait checkRegex(name, buggy, fine)\n\t\t\tawait checkJSONPath(name, buggy, fine)\n\t\t} catch (err) {\n\t\t\tconsole.error(\"Error: \" + err)\n\t\t}\n\t}\n}\n\nfunction checkRegex(name, buggy, fine)\n{\n    return new Promise(function(resolve, reject) {\n\t\tvar regexStr = bugsByName[name].check['regex-source']\n\t\tif (regexStr !== undefined)\n\t\t{\n\t\t\tvar regex = RegExp(regexStr)\n\t\t\tfor (var i in buggy)\n\t\t\t{\n\t\t\t\tif (!regex.exec(buggy[i]))\n\t\t\t\t{\n\t\t\t\t\treject(\"Bug \" + name + \": Buggy source does not match: \" + buggy[i])\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (var i in fine)\n\t\t\t{\n\t\t\t\tif (regex.exec(fine[i]))\n\t\t\t\t{\n\t\t\t\t\treject(\"Bug \" + name + \": Non-buggy source matches: \" + fine[i])\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tresolve()\n\t})\n}\n\nasync function checkJSONPath(name, buggy, fine)\n{\n\tvar jsonPath = bugsByName[name].check['ast-compact-json-path']\n\tif (jsonPath !== undefined)\n\t{\n\t\tvar url = \"https://github.com/argotorg/solidity/releases/download/v\" + bugsByName[name].introduced + \"/solc-static-linux\"\n\t\ttry {\n\t\t\tvar tmpdir = await mktemp.createDir('XXXXX')\n\t\t\tvar binary = tmpdir + \"/solc-static-linux\"\n\t\t\tawait download(url, tmpdir)\n\t\t\texec(\"chmod +x \" + binary)\n\t\t\tfor (var i in buggy)\n\t\t\t{\n\t\t\t\tvar result = await checkJsonPathTest(buggy[i], tmpdir, binary, jsonPath, i)\n\t\t\t\tif (!result)\n\t\t\t\t\tthrow \"Bug \" + name + \": Buggy source does not contain path: \" + buggy[i]\n\t\t\t}\n\t\t\tfor (var i in fine)\n\t\t\t{\n\t\t\t\tvar result = await checkJsonPathTest(fine[i], tmpdir, binary, jsonPath, i + buggy.length)\n\t\t\t\tif (result)\n\t\t\t\t\tthrow \"Bug \" + name + \": Non-buggy source contains path: \" + fine[i]\n\t\t\t}\n\t\t\texec(\"rm -r \" + tmpdir)\n\t\t} catch (err) {\n\t\t\tthrow err\n\t\t}\n\t}\n}\n\nfunction checkJsonPathTest(code, tmpdir, binary, query, idx) {\n    return new Promise(function(resolve, reject) {\n        var solFile = tmpdir + \"/jsonPath\" + idx + \".sol\"\n        var astFile = tmpdir + \"/ast\" + idx + \".json\"\n        writeFilePromise(solFile, code)\n        .then(() => {\n            return exec(binary + \" --ast-compact-json \" + solFile + \" > \" + astFile)\n        })\n        .then(() => {\n            var jsonRE = /(\\{[\\s\\S]*\\})/\n            var ast = JSON.parse(jsonRE.exec(fs.readFileSync(astFile, 'utf8'))[0])\n            var result = JSONPath({json: ast, path: query})\n            if (result.length > 0)\n                resolve(true)\n            else\n                resolve(false)\n        })\n        .catch((err) => {\n            reject(err)\n        })\n    })\n}\n\nfunction writeFilePromise(filename, data) {\n    return new Promise(function(resolve, reject) {\n        fs.writeFile(filename, data, 'utf8', function(err) {\n            if (err) reject(err)\n            else resolve(data)\n        })\n    })\n}\n"
  },
  {
    "path": "test/buglist_test_vectors.md",
    "content": "# NestedArrayFunctionCallDecoder\n\n## buggy\n\nfunction f() pure returns (uint[2][2]) { }\n\n--\n\nfunction f() returns (uint[2][2] a) { }\n\n--\n\nfunction f() returns (uint x, uint[200][2] a) { }\n\n--\n\nfunction f() returns (uint[200][2] a, uint x) { }\n\n--\n\nfunction f() returns (uint[200][2] a, uint x);\n\n--\n\nfunction f() returns (\n    uint\n    [\n    200\n    ]\n    [2]\n    a, uint x);\n\n--\n\nfunction f() returns (\n    uint\n    [\n    ContractName.ConstantName\n    ]\n    [2]\n    a, uint x);\n\n## fine\n\nfunction f() returns (uint[2]) { }\n\n--\n\nfunction f() public pure returns (uint[2][] a) { }\n\n--\n\nfunction f() public pure returns (uint[ 2 ] [ ]  a) { }\n\n--\n\nfunction f() public pure  returns (uint x, uint[] a) { }\n\n--\n\nfunction f(uint[2][2]) { }\n\n--\n\nfunction f() m(uint[2][2]) { }\n\n--\n\nfunction f() returns (uint, uint) { uint[2][2] memory x; }\n\n# ExpExponentCleanup\n\n## buggy\n\nx ** y\n\n--\n\nx ** uint8(y)\n\n--\n\nx**y\n\n## fine\n\nx ** 2\n\n--\n\nx**2\n\n--\n\nx**200\n\n--\n\n/** bla **/\n\n--\n\n/**/\n\n# EventStructWrongData\n\n## buggy\n\npragma experimental ABIEncoderV2;\ncontract C\n{\n\tstruct S { uint x; }\n\tevent E(S);\n\tevent F(S);\n\tenum A { B, C }\n\tevent G(A);\n\tfunction f(S s);\n}\n\n--\n\npragma experimental ABIEncoderV2;\ncontract C\n{\n\tstruct S { uint x; }\n\tevent E(S indexed);\n\tevent F(uint, S, bool);\n}\n\n## fine\n\npragma experimental ABIEncoderV2;\ncontract C\n{\n\tstruct S { uint x; }\n\tenum A { B, C }\n\tevent G(A);\n}\n\n--\n\npragma experimental ABIEncoderV2;\ncontract C\n{\n\tstruct S { uint x; }\n\tfunction f(S s);\n\tS s1;\n}\n"
  },
  {
    "path": "test/cmdlineTests/abi_via_ir/args",
    "content": "--abi --via-ir --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/abi_via_ir/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nerror fileLevelError(uint z);\n\nlibrary L {\n\tevent libraryEvent(uint r);\n\terror libraryError(uint r);\n\terror libraryErrorUnused(uint u);\n\tevent libraryEventUnused(uint u);\n}\n\ncontract C {\n\tstruct S { uint x; }\n\n\tevent ev(uint y);\n\tevent anon_ev(uint y) anonymous;\n\n\terror err(uint z, uint w);\n\n\tfunction f(S memory s) public {\n\t\temit L.libraryEvent(3);\n\t\tif (s.x > 1)\n\t\t\trevert fileLevelError(3);\n\t\telse\n\t\t\trevert L.libraryError(4);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/abi_via_ir/output",
    "content": "\n======= input.sol:C =======\nContract JSON ABI\n[\n    {\n        \"inputs\": [\n            {\n                \"internalType\": \"uint256\",\n                \"name\": \"z\",\n                \"type\": \"uint256\"\n            },\n            {\n                \"internalType\": \"uint256\",\n                \"name\": \"w\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"err\",\n        \"type\": \"error\"\n    },\n    {\n        \"inputs\": [\n            {\n                \"internalType\": \"uint256\",\n                \"name\": \"z\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"fileLevelError\",\n        \"type\": \"error\"\n    },\n    {\n        \"inputs\": [\n            {\n                \"internalType\": \"uint256\",\n                \"name\": \"r\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"libraryError\",\n        \"type\": \"error\"\n    },\n    {\n        \"anonymous\": true,\n        \"inputs\": [\n            {\n                \"indexed\": false,\n                \"internalType\": \"uint256\",\n                \"name\": \"y\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"anon_ev\",\n        \"type\": \"event\"\n    },\n    {\n        \"anonymous\": false,\n        \"inputs\": [\n            {\n                \"indexed\": false,\n                \"internalType\": \"uint256\",\n                \"name\": \"y\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"ev\",\n        \"type\": \"event\"\n    },\n    {\n        \"anonymous\": false,\n        \"inputs\": [\n            {\n                \"indexed\": false,\n                \"internalType\": \"uint256\",\n                \"name\": \"r\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"libraryEvent\",\n        \"type\": \"event\"\n    },\n    {\n        \"inputs\": [\n            {\n                \"components\": [\n                    {\n                        \"internalType\": \"uint256\",\n                        \"name\": \"x\",\n                        \"type\": \"uint256\"\n                    }\n                ],\n                \"internalType\": \"struct C.S\",\n                \"name\": \"s\",\n                \"type\": \"tuple\"\n            }\n        ],\n        \"name\": \"f\",\n        \"outputs\": [],\n        \"stateMutability\": \"nonpayable\",\n        \"type\": \"function\"\n    }\n]\n\n======= input.sol:L =======\nContract JSON ABI\n[\n    {\n        \"inputs\": [\n            {\n                \"internalType\": \"uint256\",\n                \"name\": \"r\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"libraryError\",\n        \"type\": \"error\"\n    },\n    {\n        \"inputs\": [\n            {\n                \"internalType\": \"uint256\",\n                \"name\": \"u\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"libraryErrorUnused\",\n        \"type\": \"error\"\n    },\n    {\n        \"anonymous\": false,\n        \"inputs\": [\n            {\n                \"indexed\": false,\n                \"internalType\": \"uint256\",\n                \"name\": \"r\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"libraryEvent\",\n        \"type\": \"event\"\n    },\n    {\n        \"anonymous\": false,\n        \"inputs\": [\n            {\n                \"indexed\": false,\n                \"internalType\": \"uint256\",\n                \"name\": \"u\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"libraryEventUnused\",\n        \"type\": \"event\"\n    }\n]\n"
  },
  {
    "path": "test/cmdlineTests/abiencoderv2_no_warning/args",
    "content": "--hashes"
  },
  {
    "path": "test/cmdlineTests/abiencoderv2_no_warning/err",
    "content": "\n"
  },
  {
    "path": "test/cmdlineTests/abiencoderv2_no_warning/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma abicoder v2;\n\ncontract C {\n    struct S { uint x; }\n    function f(S memory) public pure {\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/abiencoderv2_no_warning/output",
    "content": "\n======= input.sol:C =======\nFunction signatures:\n3fc03eeb: f((uint256))\n"
  },
  {
    "path": "test/cmdlineTests/asm_json/args",
    "content": "--asm-json --pretty-json\n"
  },
  {
    "path": "test/cmdlineTests/asm_json/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f(uint x) public pure {\n        x += 42;\n        require(x > 100);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/asm_json/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n{\n  \".code\": [\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"PUSH\",\n      \"source\": 0,\n      \"value\": \"80\"\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"PUSH\",\n      \"source\": 0,\n      \"value\": \"40\"\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"MSTORE\",\n      \"source\": 0\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"CALLVALUE\",\n      \"source\": 0\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"DUP1\",\n      \"source\": 0\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"ISZERO\",\n      \"source\": 0\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"PUSH [tag]\",\n      \"source\": 0,\n      \"value\": \"1\"\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"JUMPI\",\n      \"source\": 0\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"PUSH\",\n      \"source\": 0,\n      \"value\": \"0\"\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"PUSH\",\n      \"source\": 0,\n      \"value\": \"0\"\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"REVERT\",\n      \"source\": 0\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"tag\",\n      \"source\": 0,\n      \"value\": \"1\"\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"JUMPDEST\",\n      \"source\": 0\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"POP\",\n      \"source\": 0\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"PUSH #[$]\",\n      \"source\": 0,\n      \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"DUP1\",\n      \"source\": 0\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"PUSH [$]\",\n      \"source\": 0,\n      \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"PUSH\",\n      \"source\": 0,\n      \"value\": \"0\"\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"CODECOPY\",\n      \"source\": 0\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"PUSH\",\n      \"source\": 0,\n      \"value\": \"0\"\n    },\n    {\n      \"begin\": 60,\n      \"end\": 160,\n      \"name\": \"RETURN\",\n      \"source\": 0\n    }\n  ],\n  \".data\": {\n    \"0\": {\n      \".auxdata\": \"<BYTECODE REMOVED>\",\n      \".code\": [\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"80\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"40\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"MSTORE\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"CALLVALUE\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"DUP1\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"ISZERO\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 0,\n          \"value\": \"1\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"JUMPI\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"REVERT\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"tag\",\n          \"source\": 0,\n          \"value\": \"1\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"JUMPDEST\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"POP\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"4\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"CALLDATASIZE\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"LT\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 0,\n          \"value\": \"2\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"JUMPI\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"CALLDATALOAD\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"E0\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"SHR\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"DUP1\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"B3DE648B\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"EQ\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 0,\n          \"value\": \"3\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"JUMPI\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"tag\",\n          \"source\": 0,\n          \"value\": \"2\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"JUMPDEST\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 60,\n          \"end\": 160,\n          \"name\": \"REVERT\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"tag\",\n          \"source\": 0,\n          \"value\": \"3\"\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"JUMPDEST\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 0,\n          \"value\": \"4\"\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"4\"\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"DUP1\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"CALLDATASIZE\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"SUB\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"DUP2\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"ADD\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"SWAP1\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 0,\n          \"value\": \"5\"\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"SWAP2\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"SWAP1\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 0,\n          \"value\": \"6\"\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"jumpType\": \"[in]\",\n          \"name\": \"JUMP\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"tag\",\n          \"source\": 0,\n          \"value\": \"5\"\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"JUMPDEST\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 0,\n          \"value\": \"7\"\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"jumpType\": \"[in]\",\n          \"name\": \"JUMP\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"tag\",\n          \"source\": 0,\n          \"value\": \"4\"\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"JUMPDEST\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"STOP\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"tag\",\n          \"source\": 0,\n          \"value\": \"7\"\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"JUMPDEST\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 123,\n          \"end\": 125,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"2A\"\n        },\n        {\n          \"begin\": 118,\n          \"end\": 125,\n          \"name\": \"DUP2\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 118,\n          \"end\": 125,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 0,\n          \"value\": \"9\"\n        },\n        {\n          \"begin\": 118,\n          \"end\": 125,\n          \"name\": \"SWAP2\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 118,\n          \"end\": 125,\n          \"name\": \"SWAP1\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 118,\n          \"end\": 125,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 0,\n          \"value\": \"10\"\n        },\n        {\n          \"begin\": 118,\n          \"end\": 125,\n          \"jumpType\": \"[in]\",\n          \"name\": \"JUMP\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 118,\n          \"end\": 125,\n          \"name\": \"tag\",\n          \"source\": 0,\n          \"value\": \"9\"\n        },\n        {\n          \"begin\": 118,\n          \"end\": 125,\n          \"name\": \"JUMPDEST\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 118,\n          \"end\": 125,\n          \"name\": \"SWAP1\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 118,\n          \"end\": 125,\n          \"name\": \"POP\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 147,\n          \"end\": 150,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"64\"\n        },\n        {\n          \"begin\": 143,\n          \"end\": 144,\n          \"name\": \"DUP2\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 143,\n          \"end\": 150,\n          \"name\": \"GT\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 135,\n          \"end\": 151,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 0,\n          \"value\": \"11\"\n        },\n        {\n          \"begin\": 135,\n          \"end\": 151,\n          \"name\": \"JUMPI\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 135,\n          \"end\": 151,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 135,\n          \"end\": 151,\n          \"name\": \"PUSH\",\n          \"source\": 0,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 135,\n          \"end\": 151,\n          \"name\": \"REVERT\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 135,\n          \"end\": 151,\n          \"name\": \"tag\",\n          \"source\": 0,\n          \"value\": \"11\"\n        },\n        {\n          \"begin\": 135,\n          \"end\": 151,\n          \"name\": \"JUMPDEST\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"name\": \"POP\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 77,\n          \"end\": 158,\n          \"jumpType\": \"[out]\",\n          \"name\": \"JUMP\",\n          \"source\": 0\n        },\n        {\n          \"begin\": 88,\n          \"end\": 205,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"13\"\n        },\n        {\n          \"begin\": 88,\n          \"end\": 205,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 197,\n          \"end\": 198,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 194,\n          \"end\": 195,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 187,\n          \"end\": 199,\n          \"name\": \"REVERT\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 334,\n          \"end\": 411,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"15\"\n        },\n        {\n          \"begin\": 334,\n          \"end\": 411,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 371,\n          \"end\": 378,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 400,\n          \"end\": 405,\n          \"name\": \"DUP2\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 389,\n          \"end\": 405,\n          \"name\": \"SWAP1\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 389,\n          \"end\": 405,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 334,\n          \"end\": 411,\n          \"name\": \"SWAP2\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 334,\n          \"end\": 411,\n          \"name\": \"SWAP1\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 334,\n          \"end\": 411,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 334,\n          \"end\": 411,\n          \"jumpType\": \"[out]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 417,\n          \"end\": 539,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"16\"\n        },\n        {\n          \"begin\": 417,\n          \"end\": 539,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 490,\n          \"end\": 514,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"25\"\n        },\n        {\n          \"begin\": 508,\n          \"end\": 513,\n          \"name\": \"DUP2\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 490,\n          \"end\": 514,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"15\"\n        },\n        {\n          \"begin\": 490,\n          \"end\": 514,\n          \"jumpType\": \"[in]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 490,\n          \"end\": 514,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"25\"\n        },\n        {\n          \"begin\": 490,\n          \"end\": 514,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 483,\n          \"end\": 488,\n          \"name\": \"DUP2\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 480,\n          \"end\": 515,\n          \"name\": \"EQ\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 470,\n          \"end\": 533,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"26\"\n        },\n        {\n          \"begin\": 470,\n          \"end\": 533,\n          \"name\": \"JUMPI\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 529,\n          \"end\": 530,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 526,\n          \"end\": 527,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 519,\n          \"end\": 531,\n          \"name\": \"REVERT\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 470,\n          \"end\": 533,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"26\"\n        },\n        {\n          \"begin\": 470,\n          \"end\": 533,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 417,\n          \"end\": 539,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 417,\n          \"end\": 539,\n          \"jumpType\": \"[out]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 545,\n          \"end\": 684,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"17\"\n        },\n        {\n          \"begin\": 545,\n          \"end\": 684,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 591,\n          \"end\": 596,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 629,\n          \"end\": 635,\n          \"name\": \"DUP2\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 616,\n          \"end\": 636,\n          \"name\": \"CALLDATALOAD\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 607,\n          \"end\": 636,\n          \"name\": \"SWAP1\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 607,\n          \"end\": 636,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 645,\n          \"end\": 678,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"28\"\n        },\n        {\n          \"begin\": 672,\n          \"end\": 677,\n          \"name\": \"DUP2\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 645,\n          \"end\": 678,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"16\"\n        },\n        {\n          \"begin\": 645,\n          \"end\": 678,\n          \"jumpType\": \"[in]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 645,\n          \"end\": 678,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"28\"\n        },\n        {\n          \"begin\": 645,\n          \"end\": 678,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 545,\n          \"end\": 684,\n          \"name\": \"SWAP3\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 545,\n          \"end\": 684,\n          \"name\": \"SWAP2\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 545,\n          \"end\": 684,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 545,\n          \"end\": 684,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 545,\n          \"end\": 684,\n          \"jumpType\": \"[out]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 690,\n          \"end\": 1019,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"6\"\n        },\n        {\n          \"begin\": 690,\n          \"end\": 1019,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 749,\n          \"end\": 755,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 798,\n          \"end\": 800,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"20\"\n        },\n        {\n          \"begin\": 786,\n          \"end\": 795,\n          \"name\": \"DUP3\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 777,\n          \"end\": 784,\n          \"name\": \"DUP5\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 773,\n          \"end\": 796,\n          \"name\": \"SUB\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 769,\n          \"end\": 801,\n          \"name\": \"SLT\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 766,\n          \"end\": 885,\n          \"name\": \"ISZERO\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 766,\n          \"end\": 885,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"30\"\n        },\n        {\n          \"begin\": 766,\n          \"end\": 885,\n          \"name\": \"JUMPI\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 804,\n          \"end\": 883,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"31\"\n        },\n        {\n          \"begin\": 804,\n          \"end\": 883,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"13\"\n        },\n        {\n          \"begin\": 804,\n          \"end\": 883,\n          \"jumpType\": \"[in]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 804,\n          \"end\": 883,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"31\"\n        },\n        {\n          \"begin\": 804,\n          \"end\": 883,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 766,\n          \"end\": 885,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"30\"\n        },\n        {\n          \"begin\": 766,\n          \"end\": 885,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 924,\n          \"end\": 925,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 949,\n          \"end\": 1002,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"32\"\n        },\n        {\n          \"begin\": 994,\n          \"end\": 1001,\n          \"name\": \"DUP5\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 985,\n          \"end\": 991,\n          \"name\": \"DUP3\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 974,\n          \"end\": 983,\n          \"name\": \"DUP6\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 970,\n          \"end\": 992,\n          \"name\": \"ADD\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 949,\n          \"end\": 1002,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"17\"\n        },\n        {\n          \"begin\": 949,\n          \"end\": 1002,\n          \"jumpType\": \"[in]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 949,\n          \"end\": 1002,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"32\"\n        },\n        {\n          \"begin\": 949,\n          \"end\": 1002,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 939,\n          \"end\": 1002,\n          \"name\": \"SWAP2\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 939,\n          \"end\": 1002,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 895,\n          \"end\": 1012,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 690,\n          \"end\": 1019,\n          \"name\": \"SWAP3\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 690,\n          \"end\": 1019,\n          \"name\": \"SWAP2\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 690,\n          \"end\": 1019,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 690,\n          \"end\": 1019,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 690,\n          \"end\": 1019,\n          \"jumpType\": \"[out]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1025,\n          \"end\": 1205,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"18\"\n        },\n        {\n          \"begin\": 1025,\n          \"end\": 1205,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1073,\n          \"end\": 1150,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"4E487B7100000000000000000000000000000000000000000000000000000000\"\n        },\n        {\n          \"begin\": 1070,\n          \"end\": 1071,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 1063,\n          \"end\": 1151,\n          \"name\": \"MSTORE\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1170,\n          \"end\": 1174,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"11\"\n        },\n        {\n          \"begin\": 1167,\n          \"end\": 1168,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"4\"\n        },\n        {\n          \"begin\": 1160,\n          \"end\": 1175,\n          \"name\": \"MSTORE\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1194,\n          \"end\": 1198,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"24\"\n        },\n        {\n          \"begin\": 1191,\n          \"end\": 1192,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 1184,\n          \"end\": 1199,\n          \"name\": \"REVERT\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1211,\n          \"end\": 1402,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"10\"\n        },\n        {\n          \"begin\": 1211,\n          \"end\": 1402,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1251,\n          \"end\": 1254,\n          \"name\": \"PUSH\",\n          \"source\": 1,\n          \"value\": \"0\"\n        },\n        {\n          \"begin\": 1270,\n          \"end\": 1290,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"35\"\n        },\n        {\n          \"begin\": 1288,\n          \"end\": 1289,\n          \"name\": \"DUP3\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1270,\n          \"end\": 1290,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"15\"\n        },\n        {\n          \"begin\": 1270,\n          \"end\": 1290,\n          \"jumpType\": \"[in]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1270,\n          \"end\": 1290,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"35\"\n        },\n        {\n          \"begin\": 1270,\n          \"end\": 1290,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1265,\n          \"end\": 1290,\n          \"name\": \"SWAP2\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1265,\n          \"end\": 1290,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1304,\n          \"end\": 1324,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"36\"\n        },\n        {\n          \"begin\": 1322,\n          \"end\": 1323,\n          \"name\": \"DUP4\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1304,\n          \"end\": 1324,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"15\"\n        },\n        {\n          \"begin\": 1304,\n          \"end\": 1324,\n          \"jumpType\": \"[in]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1304,\n          \"end\": 1324,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"36\"\n        },\n        {\n          \"begin\": 1304,\n          \"end\": 1324,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1299,\n          \"end\": 1324,\n          \"name\": \"SWAP3\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1299,\n          \"end\": 1324,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1347,\n          \"end\": 1348,\n          \"name\": \"DUP3\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1344,\n          \"end\": 1345,\n          \"name\": \"DUP3\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1340,\n          \"end\": 1349,\n          \"name\": \"ADD\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1333,\n          \"end\": 1349,\n          \"name\": \"SWAP1\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1333,\n          \"end\": 1349,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1368,\n          \"end\": 1371,\n          \"name\": \"DUP1\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1365,\n          \"end\": 1366,\n          \"name\": \"DUP3\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1362,\n          \"end\": 1372,\n          \"name\": \"GT\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1359,\n          \"end\": 1395,\n          \"name\": \"ISZERO\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1359,\n          \"end\": 1395,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"37\"\n        },\n        {\n          \"begin\": 1359,\n          \"end\": 1395,\n          \"name\": \"JUMPI\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1375,\n          \"end\": 1393,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"38\"\n        },\n        {\n          \"begin\": 1375,\n          \"end\": 1393,\n          \"name\": \"PUSH [tag]\",\n          \"source\": 1,\n          \"value\": \"18\"\n        },\n        {\n          \"begin\": 1375,\n          \"end\": 1393,\n          \"jumpType\": \"[in]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1375,\n          \"end\": 1393,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"38\"\n        },\n        {\n          \"begin\": 1375,\n          \"end\": 1393,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1359,\n          \"end\": 1395,\n          \"name\": \"tag\",\n          \"source\": 1,\n          \"value\": \"37\"\n        },\n        {\n          \"begin\": 1359,\n          \"end\": 1395,\n          \"name\": \"JUMPDEST\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1211,\n          \"end\": 1402,\n          \"name\": \"SWAP3\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1211,\n          \"end\": 1402,\n          \"name\": \"SWAP2\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1211,\n          \"end\": 1402,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1211,\n          \"end\": 1402,\n          \"name\": \"POP\",\n          \"source\": 1\n        },\n        {\n          \"begin\": 1211,\n          \"end\": 1402,\n          \"jumpType\": \"[out]\",\n          \"name\": \"JUMP\",\n          \"source\": 1\n        }\n      ]\n    }\n  },\n  \"sourceList\": [\n    \"input.sol\",\n    \"#utility.yul\"\n  ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/args",
    "content": "--pretty-json --json-indent 4 --experimental --import-asm-json -\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/err",
    "content": "Error: Assembly Import Error: The 'sourceList' array contains invalid 'null' item.\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_import_sourcelist_with_null_elements/stdin",
    "content": "{\n    \".code\":\n    [\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"STOP\",\n            \"source\": -1\n        }\n    ],\n    \"sourceList\":\n    [\n        null,\n        null,\n        \"L0.sol\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_no_pretty_print/args",
    "content": "--asm-json\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_no_pretty_print/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f(uint x) public pure {\n        x += 42;\n        require(x > 100);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_no_pretty_print/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n{\".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\":\"<BYTECODE REMOVED>\",\".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\"]}\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_subassembly_id_representation/args",
    "content": "--asm-json --pretty-json --strict-assembly --json-indent 4"
  },
  {
    "path": "test/cmdlineTests/asm_json_subassembly_id_representation/input.yul",
    "content": "object \"root\" {\n    code {\n        // this produces non-zero PUSH #[$] assembly item values\n        mstore(42, datasize(\"sub1.sub1_2\"))\n        mstore(42, datasize(\"sub2.sub2_2\"))\n    }\n    object \"sub1\" {\n        code {}\n        object \"sub1_2\" {\n            code {}\n        }\n    }\n    object \"sub2\" {\n        code {}\n        object \"sub2_2\" {\n            code {}\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_subassembly_id_representation/output",
    "content": "\n======= input.yul (EVM) =======\n\nEVM assembly:\n{\n    \".code\": [\n        {\n            \"begin\": 60,\n            \"end\": 83,\n            \"name\": \"PUSH #[$]\",\n            \"source\": -1,\n            \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n        },\n        {\n            \"begin\": 56,\n            \"end\": 58,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"2A\"\n        },\n        {\n            \"begin\": 49,\n            \"end\": 84,\n            \"name\": \"MSTORE\",\n            \"source\": -1\n        },\n        {\n            \"begin\": 108,\n            \"end\": 131,\n            \"name\": \"PUSH #[$]\",\n            \"source\": -1,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffe\"\n        },\n        {\n            \"begin\": 104,\n            \"end\": 106,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"2A\"\n        },\n        {\n            \"begin\": 97,\n            \"end\": 132,\n            \"name\": \"MSTORE\",\n            \"source\": -1\n        },\n        {\n            \"begin\": 25,\n            \"end\": 148,\n            \"name\": \"STOP\",\n            \"source\": -1\n        }\n    ],\n    \".data\": {\n        \"0\": {\n            \".code\": [\n                {\n                    \"begin\": 182,\n                    \"end\": 189,\n                    \"name\": \"STOP\",\n                    \"source\": -1\n                }\n            ],\n            \".data\": {\n                \"0\": {\n                    \".code\": [\n                        {\n                            \"begin\": 233,\n                            \"end\": 240,\n                            \"name\": \"STOP\",\n                            \"source\": -1\n                        }\n                    ]\n                }\n            }\n        },\n        \"1\": {\n            \".code\": [\n                {\n                    \"begin\": 290,\n                    \"end\": 297,\n                    \"name\": \"STOP\",\n                    \"source\": -1\n                }\n            ],\n            \".data\": {\n                \"0\": {\n                    \".code\": [\n                        {\n                            \"begin\": 341,\n                            \"end\": 348,\n                            \"name\": \"STOP\",\n                            \"source\": -1\n                        }\n                    ]\n                }\n            }\n        }\n    },\n    \"sourceList\": []\n}\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_yul_export_evm_asm_import/args",
    "content": "--experimental --import-asm-json - --opcodes --asm --bin --asm-json --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_yul_export_evm_asm_import/output",
    "content": "Opcodes:\nPUSH1 0x5 PUSH0 SSTORE STOP \nBinary:\n60055f5500\nEVM assembly:\n{\n    \".code\": [\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSHSIZE\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"SSTORE\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"STOP\",\n            \"source\": -1\n        }\n    ],\n    \"sourceList\": [\n        \"L0.sol\",\n        \"L1.sol\",\n        \"L2.sol\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/asm_json_yul_export_evm_asm_import/stdin",
    "content": "{\n    \".code\":\n    [\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSHSIZE\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"SSTORE\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"STOP\",\n            \"source\": -1\n        }\n    ],\n    \"sourceList\":\n    [\n        \"L0.sol\",\n        \"L1.sol\",\n        \"L2.sol\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/ast_compact_json_no_pretty_json/args",
    "content": "--ast-compact-json --allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/ast_compact_json_no_pretty_json/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/ast_compact_json_no_pretty_json/output",
    "content": "JSON AST (compact format):\n\n\n======= input.sol =======\n{\"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\"}\n"
  },
  {
    "path": "test/cmdlineTests/ast_compact_json_storage_layout_specifier/args",
    "content": "--ast-compact-json --pretty-json --json-indent 4 --allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/ast_compact_json_storage_layout_specifier/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C layout at 1234 + 4567 {}\n"
  },
  {
    "path": "test/cmdlineTests/ast_compact_json_storage_layout_specifier/output",
    "content": "JSON AST (compact format):\n\n\n======= input.sol =======\n{\n    \"absolutePath\": \"input.sol\",\n    \"exportedSymbols\": {\n        \"C\": [\n            6\n        ]\n    },\n    \"id\": 7,\n    \"license\": \"GPL-3.0\",\n    \"nodeType\": \"SourceUnit\",\n    \"nodes\": [\n        {\n            \"id\": 1,\n            \"literals\": [\n                \"solidity\",\n                \">=\",\n                \"0.0\"\n            ],\n            \"nodeType\": \"PragmaDirective\",\n            \"src\": \"36:22:0\"\n        },\n        {\n            \"abstract\": false,\n            \"baseContracts\": [],\n            \"canonicalName\": \"C\",\n            \"contractDependencies\": [],\n            \"contractKind\": \"contract\",\n            \"fullyImplemented\": true,\n            \"id\": 6,\n            \"linearizedBaseContracts\": [\n                6\n            ],\n            \"name\": \"C\",\n            \"nameLocation\": \"69:1:0\",\n            \"nodeType\": \"ContractDefinition\",\n            \"nodes\": [],\n            \"scope\": 7,\n            \"src\": \"60:35:0\",\n            \"storageLayout\": {\n                \"baseSlotExpression\": {\n                    \"commonType\": {\n                        \"typeIdentifier\": \"t_rational_5801_by_1\",\n                        \"typeString\": \"int_const 5801\"\n                    },\n                    \"id\": 4,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"lValueRequested\": false,\n                    \"leftExpression\": {\n                        \"hexValue\": \"31323334\",\n                        \"id\": 2,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": true,\n                        \"kind\": \"number\",\n                        \"lValueRequested\": false,\n                        \"nodeType\": \"Literal\",\n                        \"src\": \"81:4:0\",\n                        \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_rational_1234_by_1\",\n                            \"typeString\": \"int_const 1234\"\n                        },\n                        \"value\": \"1234\"\n                    },\n                    \"nodeType\": \"BinaryOperation\",\n                    \"operator\": \"+\",\n                    \"rightExpression\": {\n                        \"hexValue\": \"34353637\",\n                        \"id\": 3,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": true,\n                        \"kind\": \"number\",\n                        \"lValueRequested\": false,\n                        \"nodeType\": \"Literal\",\n                        \"src\": \"88:4:0\",\n                        \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_rational_4567_by_1\",\n                            \"typeString\": \"int_const 4567\"\n                        },\n                        \"value\": \"4567\"\n                    },\n                    \"src\": \"81:11:0\",\n                    \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_rational_5801_by_1\",\n                        \"typeString\": \"int_const 5801\"\n                    }\n                },\n                \"id\": 5,\n                \"nodeType\": \"StorageLayoutSpecifier\",\n                \"src\": \"71:21:0\"\n            },\n            \"usedErrors\": [],\n            \"usedEvents\": []\n        }\n    ],\n    \"src\": \"36:60:0\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/ast_compact_json_with_base_path/args",
    "content": "--ast-compact-json --pretty-json --base-path . --allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/ast_compact_json_with_base_path/c.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/ast_compact_json_with_base_path/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nimport \"./c.sol\";\n"
  },
  {
    "path": "test/cmdlineTests/ast_compact_json_with_base_path/output",
    "content": "JSON AST (compact format):\n\n\n======= c.sol =======\n{\n  \"absolutePath\": \"c.sol\",\n  \"exportedSymbols\": {\n    \"C\": [\n      5\n    ]\n  },\n  \"id\": 6,\n  \"license\": \"GPL-3.0\",\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"id\": 4,\n      \"literals\": [\n        \"solidity\",\n        \">=\",\n        \"0.0\"\n      ],\n      \"nodeType\": \"PragmaDirective\",\n      \"src\": \"36:22:0\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"69:1:0\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 6,\n      \"src\": \"60:13:0\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"36:38:0\"\n}\n======= input.sol =======\n{\n  \"absolutePath\": \"input.sol\",\n  \"exportedSymbols\": {\n    \"C\": [\n      5\n    ]\n  },\n  \"id\": 3,\n  \"license\": \"GPL-3.0\",\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"id\": 1,\n      \"literals\": [\n        \"solidity\",\n        \">=\",\n        \"0.0\"\n      ],\n      \"nodeType\": \"PragmaDirective\",\n      \"src\": \"36:22:1\"\n    },\n    {\n      \"absolutePath\": \"c.sol\",\n      \"file\": \"./c.sol\",\n      \"id\": 2,\n      \"nameLocation\": \"-1:-1:-1\",\n      \"nodeType\": \"ImportDirective\",\n      \"scope\": 3,\n      \"sourceUnit\": 6,\n      \"src\": \"60:17:1\",\n      \"symbolAliases\": [],\n      \"unitAlias\": \"\"\n    }\n  ],\n  \"src\": \"36:42:1\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/ast_ir/args",
    "content": "--experimental --ir-ast-json --ir-optimized-ast-json --optimize --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/ast_ir/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/ast_ir/output",
    "content": "IR AST:\n{\n    \"code\": {\n        \"block\": {\n            \"nativeSrc\": \"52:790:0\",\n            \"nodeType\": \"YulBlock\",\n            \"src\": \"-1:-1:0\",\n            \"statements\": [\n                {\n                    \"expression\": {\n                        \"arguments\": [\n                            {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"111:2:0\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"60:13:0\",\n                                \"type\": \"\",\n                                \"value\": \"64\"\n                            },\n                            {\n                                \"arguments\": [\n                                    {\n                                        \"kind\": \"number\",\n                                        \"nativeSrc\": \"127:3:0\",\n                                        \"nodeType\": \"YulLiteral\",\n                                        \"src\": \"60:13:0\",\n                                        \"type\": \"\",\n                                        \"value\": \"128\"\n                                    }\n                                ],\n                                \"functionName\": {\n                                    \"name\": \"memoryguard\",\n                                    \"nativeSrc\": \"115:11:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"115:16:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            }\n                        ],\n                        \"functionName\": {\n                            \"name\": \"mstore\",\n                            \"nativeSrc\": \"104:6:0\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"60:13:0\"\n                        },\n                        \"nativeSrc\": \"104:28:0\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"60:13:0\"\n                    },\n                    \"nativeSrc\": \"104:28:0\",\n                    \"nodeType\": \"YulExpressionStatement\",\n                    \"src\": \"60:13:0\"\n                },\n                {\n                    \"body\": {\n                        \"nativeSrc\": \"156:83:0\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"60:13:0\",\n                        \"statements\": [\n                            {\n                                \"expression\": {\n                                    \"arguments\": [],\n                                    \"functionName\": {\n                                        \"name\": \"revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb\",\n                                        \"nativeSrc\": \"158:77:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"60:13:0\"\n                                    },\n                                    \"nativeSrc\": \"158:79:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"158:79:0\",\n                                \"nodeType\": \"YulExpressionStatement\",\n                                \"src\": \"60:13:0\"\n                            }\n                        ]\n                    },\n                    \"condition\": {\n                        \"arguments\": [],\n                        \"functionName\": {\n                            \"name\": \"callvalue\",\n                            \"nativeSrc\": \"144:9:0\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"60:13:0\"\n                        },\n                        \"nativeSrc\": \"144:11:0\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"60:13:0\"\n                    },\n                    \"nativeSrc\": \"141:98:0\",\n                    \"nodeType\": \"YulIf\",\n                    \"src\": \"60:13:0\"\n                },\n                {\n                    \"expression\": {\n                        \"arguments\": [],\n                        \"functionName\": {\n                            \"name\": \"constructor_C_2\",\n                            \"nativeSrc\": \"249:15:0\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"60:13:0\"\n                        },\n                        \"nativeSrc\": \"249:17:0\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"60:13:0\"\n                    },\n                    \"nativeSrc\": \"249:17:0\",\n                    \"nodeType\": \"YulExpressionStatement\",\n                    \"src\": \"60:13:0\"\n                },\n                {\n                    \"nativeSrc\": \"276:30:0\",\n                    \"nodeType\": \"YulVariableDeclaration\",\n                    \"src\": \"60:13:0\",\n                    \"value\": {\n                        \"arguments\": [],\n                        \"functionName\": {\n                            \"name\": \"allocate_unbounded\",\n                            \"nativeSrc\": \"286:18:0\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"60:13:0\"\n                        },\n                        \"nativeSrc\": \"286:20:0\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"60:13:0\"\n                    },\n                    \"variables\": [\n                        {\n                            \"name\": \"_1\",\n                            \"nativeSrc\": \"280:2:0\",\n                            \"nodeType\": \"YulTypedName\",\n                            \"src\": \"60:13:0\",\n                            \"type\": \"\"\n                        }\n                    ]\n                },\n                {\n                    \"expression\": {\n                        \"arguments\": [\n                            {\n                                \"name\": \"_1\",\n                                \"nativeSrc\": \"324:2:0\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"60:13:0\"\n                            },\n                            {\n                                \"arguments\": [\n                                    {\n                                        \"hexValue\": \"435f325f6465706c6f796564\",\n                                        \"kind\": \"string\",\n                                        \"nativeSrc\": \"339:14:0\",\n                                        \"nodeType\": \"YulLiteral\",\n                                        \"src\": \"60:13:0\",\n                                        \"type\": \"\",\n                                        \"value\": \"C_2_deployed\"\n                                    }\n                                ],\n                                \"functionName\": {\n                                    \"name\": \"dataoffset\",\n                                    \"nativeSrc\": \"328:10:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"328:26:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            },\n                            {\n                                \"arguments\": [\n                                    {\n                                        \"hexValue\": \"435f325f6465706c6f796564\",\n                                        \"kind\": \"string\",\n                                        \"nativeSrc\": \"365:14:0\",\n                                        \"nodeType\": \"YulLiteral\",\n                                        \"src\": \"60:13:0\",\n                                        \"type\": \"\",\n                                        \"value\": \"C_2_deployed\"\n                                    }\n                                ],\n                                \"functionName\": {\n                                    \"name\": \"datasize\",\n                                    \"nativeSrc\": \"356:8:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"356:24:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            }\n                        ],\n                        \"functionName\": {\n                            \"name\": \"codecopy\",\n                            \"nativeSrc\": \"315:8:0\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"60:13:0\"\n                        },\n                        \"nativeSrc\": \"315:66:0\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"60:13:0\"\n                    },\n                    \"nativeSrc\": \"315:66:0\",\n                    \"nodeType\": \"YulExpressionStatement\",\n                    \"src\": \"60:13:0\"\n                },\n                {\n                    \"expression\": {\n                        \"arguments\": [\n                            {\n                                \"name\": \"_1\",\n                                \"nativeSrc\": \"398:2:0\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"60:13:0\"\n                            },\n                            {\n                                \"arguments\": [\n                                    {\n                                        \"hexValue\": \"435f325f6465706c6f796564\",\n                                        \"kind\": \"string\",\n                                        \"nativeSrc\": \"411:14:0\",\n                                        \"nodeType\": \"YulLiteral\",\n                                        \"src\": \"60:13:0\",\n                                        \"type\": \"\",\n                                        \"value\": \"C_2_deployed\"\n                                    }\n                                ],\n                                \"functionName\": {\n                                    \"name\": \"datasize\",\n                                    \"nativeSrc\": \"402:8:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"402:24:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            }\n                        ],\n                        \"functionName\": {\n                            \"name\": \"return\",\n                            \"nativeSrc\": \"391:6:0\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"60:13:0\"\n                        },\n                        \"nativeSrc\": \"391:36:0\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"60:13:0\"\n                    },\n                    \"nativeSrc\": \"391:36:0\",\n                    \"nodeType\": \"YulExpressionStatement\",\n                    \"src\": \"60:13:0\"\n                },\n                {\n                    \"body\": {\n                        \"nativeSrc\": \"477:43:0\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"60:13:0\",\n                        \"statements\": [\n                            {\n                                \"nativeSrc\": \"491:19:0\",\n                                \"nodeType\": \"YulAssignment\",\n                                \"src\": \"60:13:0\",\n                                \"value\": {\n                                    \"arguments\": [\n                                        {\n                                            \"kind\": \"number\",\n                                            \"nativeSrc\": \"507:2:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"60:13:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"64\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"mload\",\n                                        \"nativeSrc\": \"501:5:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"60:13:0\"\n                                    },\n                                    \"nativeSrc\": \"501:9:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"variableNames\": [\n                                    {\n                                        \"name\": \"memPtr\",\n                                        \"nativeSrc\": \"491:6:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"60:13:0\"\n                                    }\n                                ]\n                            }\n                        ]\n                    },\n                    \"name\": \"allocate_unbounded\",\n                    \"nativeSrc\": \"437:83:0\",\n                    \"nodeType\": \"YulFunctionDefinition\",\n                    \"returnVariables\": [\n                        {\n                            \"name\": \"memPtr\",\n                            \"nativeSrc\": \"470:6:0\",\n                            \"nodeType\": \"YulTypedName\",\n                            \"src\": \"60:13:0\",\n                            \"type\": \"\"\n                        }\n                    ],\n                    \"src\": \"60:13:0\"\n                },\n                {\n                    \"body\": {\n                        \"nativeSrc\": \"619:36:0\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"60:13:0\",\n                        \"statements\": [\n                            {\n                                \"expression\": {\n                                    \"arguments\": [\n                                        {\n                                            \"kind\": \"number\",\n                                            \"nativeSrc\": \"640:1:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"60:13:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"0\"\n                                        },\n                                        {\n                                            \"kind\": \"number\",\n                                            \"nativeSrc\": \"643:1:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"60:13:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"0\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"revert\",\n                                        \"nativeSrc\": \"633:6:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"60:13:0\"\n                                    },\n                                    \"nativeSrc\": \"633:12:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"633:12:0\",\n                                \"nodeType\": \"YulExpressionStatement\",\n                                \"src\": \"60:13:0\"\n                            }\n                        ]\n                    },\n                    \"name\": \"revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb\",\n                    \"nativeSrc\": \"530:125:0\",\n                    \"nodeType\": \"YulFunctionDefinition\",\n                    \"src\": \"60:13:0\"\n                },\n                {\n                    \"body\": {\n                        \"nativeSrc\": \"734:59:0\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"60:13:0\",\n                        \"statements\": []\n                    },\n                    \"name\": \"constructor_C_2\",\n                    \"nativeSrc\": \"707:86:0\",\n                    \"nodeType\": \"YulFunctionDefinition\",\n                    \"src\": \"60:13:0\"\n                }\n            ]\n        },\n        \"nodeType\": \"YulCode\"\n    },\n    \"name\": \"C_2\",\n    \"nodeType\": \"YulObject\",\n    \"subObjects\": [\n        {\n            \"code\": {\n                \"block\": {\n                    \"nativeSrc\": \"915:588:0\",\n                    \"nodeType\": \"YulBlock\",\n                    \"src\": \"-1:-1:0\",\n                    \"statements\": [\n                        {\n                            \"expression\": {\n                                \"arguments\": [\n                                    {\n                                        \"kind\": \"number\",\n                                        \"nativeSrc\": \"982:2:0\",\n                                        \"nodeType\": \"YulLiteral\",\n                                        \"src\": \"60:13:0\",\n                                        \"type\": \"\",\n                                        \"value\": \"64\"\n                                    },\n                                    {\n                                        \"arguments\": [\n                                            {\n                                                \"kind\": \"number\",\n                                                \"nativeSrc\": \"998:3:0\",\n                                                \"nodeType\": \"YulLiteral\",\n                                                \"src\": \"60:13:0\",\n                                                \"type\": \"\",\n                                                \"value\": \"128\"\n                                            }\n                                        ],\n                                        \"functionName\": {\n                                            \"name\": \"memoryguard\",\n                                            \"nativeSrc\": \"986:11:0\",\n                                            \"nodeType\": \"YulIdentifier\",\n                                            \"src\": \"60:13:0\"\n                                        },\n                                        \"nativeSrc\": \"986:16:0\",\n                                        \"nodeType\": \"YulFunctionCall\",\n                                        \"src\": \"60:13:0\"\n                                    }\n                                ],\n                                \"functionName\": {\n                                    \"name\": \"mstore\",\n                                    \"nativeSrc\": \"975:6:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"975:28:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            },\n                            \"nativeSrc\": \"975:28:0\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"60:13:0\"\n                        },\n                        {\n                            \"expression\": {\n                                \"arguments\": [],\n                                \"functionName\": {\n                                    \"name\": \"revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74\",\n                                    \"nativeSrc\": \"1017:77:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"1017:79:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            },\n                            \"nativeSrc\": \"1017:79:0\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"60:13:0\"\n                        },\n                        {\n                            \"body\": {\n                                \"nativeSrc\": \"1163:77:0\",\n                                \"nodeType\": \"YulBlock\",\n                                \"src\": \"60:13:0\",\n                                \"statements\": [\n                                    {\n                                        \"nativeSrc\": \"1181:44:0\",\n                                        \"nodeType\": \"YulAssignment\",\n                                        \"src\": \"60:13:0\",\n                                        \"value\": {\n                                            \"arguments\": [\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"1214:3:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"60:13:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"224\"\n                                                },\n                                                {\n                                                    \"name\": \"value\",\n                                                    \"nativeSrc\": \"1219:5:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"60:13:0\"\n                                                }\n                                            ],\n                                            \"functionName\": {\n                                                \"name\": \"shr\",\n                                                \"nativeSrc\": \"1210:3:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"60:13:0\"\n                                            },\n                                            \"nativeSrc\": \"1210:15:0\",\n                                            \"nodeType\": \"YulFunctionCall\",\n                                            \"src\": \"60:13:0\"\n                                        },\n                                        \"variableNames\": [\n                                            {\n                                                \"name\": \"newValue\",\n                                                \"nativeSrc\": \"1181:8:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"60:13:0\"\n                                            }\n                                        ]\n                                    }\n                                ]\n                            },\n                            \"name\": \"shift_right_224_unsigned\",\n                            \"nativeSrc\": \"1110:130:0\",\n                            \"nodeType\": \"YulFunctionDefinition\",\n                            \"parameters\": [\n                                {\n                                    \"name\": \"value\",\n                                    \"nativeSrc\": \"1144:5:0\",\n                                    \"nodeType\": \"YulTypedName\",\n                                    \"src\": \"60:13:0\",\n                                    \"type\": \"\"\n                                }\n                            ],\n                            \"returnVariables\": [\n                                {\n                                    \"name\": \"newValue\",\n                                    \"nativeSrc\": \"1154:8:0\",\n                                    \"nodeType\": \"YulTypedName\",\n                                    \"src\": \"60:13:0\",\n                                    \"type\": \"\"\n                                }\n                            ],\n                            \"src\": \"60:13:0\"\n                        },\n                        {\n                            \"body\": {\n                                \"nativeSrc\": \"1294:51:0\",\n                                \"nodeType\": \"YulBlock\",\n                                \"src\": \"60:13:0\",\n                                \"statements\": [\n                                    {\n                                        \"nativeSrc\": \"1312:19:0\",\n                                        \"nodeType\": \"YulAssignment\",\n                                        \"src\": \"60:13:0\",\n                                        \"value\": {\n                                            \"arguments\": [\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"1328:2:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"60:13:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"64\"\n                                                }\n                                            ],\n                                            \"functionName\": {\n                                                \"name\": \"mload\",\n                                                \"nativeSrc\": \"1322:5:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"60:13:0\"\n                                            },\n                                            \"nativeSrc\": \"1322:9:0\",\n                                            \"nodeType\": \"YulFunctionCall\",\n                                            \"src\": \"60:13:0\"\n                                        },\n                                        \"variableNames\": [\n                                            {\n                                                \"name\": \"memPtr\",\n                                                \"nativeSrc\": \"1312:6:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"60:13:0\"\n                                            }\n                                        ]\n                                    }\n                                ]\n                            },\n                            \"name\": \"allocate_unbounded\",\n                            \"nativeSrc\": \"1254:91:0\",\n                            \"nodeType\": \"YulFunctionDefinition\",\n                            \"returnVariables\": [\n                                {\n                                    \"name\": \"memPtr\",\n                                    \"nativeSrc\": \"1287:6:0\",\n                                    \"nodeType\": \"YulTypedName\",\n                                    \"src\": \"60:13:0\",\n                                    \"type\": \"\"\n                                }\n                            ],\n                            \"src\": \"60:13:0\"\n                        },\n                        {\n                            \"body\": {\n                                \"nativeSrc\": \"1448:44:0\",\n                                \"nodeType\": \"YulBlock\",\n                                \"src\": \"60:13:0\",\n                                \"statements\": [\n                                    {\n                                        \"expression\": {\n                                            \"arguments\": [\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"1473:1:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"60:13:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"0\"\n                                                },\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"1476:1:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"60:13:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"0\"\n                                                }\n                                            ],\n                                            \"functionName\": {\n                                                \"name\": \"revert\",\n                                                \"nativeSrc\": \"1466:6:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"60:13:0\"\n                                            },\n                                            \"nativeSrc\": \"1466:12:0\",\n                                            \"nodeType\": \"YulFunctionCall\",\n                                            \"src\": \"60:13:0\"\n                                        },\n                                        \"nativeSrc\": \"1466:12:0\",\n                                        \"nodeType\": \"YulExpressionStatement\",\n                                        \"src\": \"60:13:0\"\n                                    }\n                                ]\n                            },\n                            \"name\": \"revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74\",\n                            \"nativeSrc\": \"1359:133:0\",\n                            \"nodeType\": \"YulFunctionDefinition\",\n                            \"src\": \"60:13:0\"\n                        }\n                    ]\n                },\n                \"nodeType\": \"YulCode\"\n            },\n            \"name\": \"C_2_deployed\",\n            \"nodeType\": \"YulObject\",\n            \"subObjects\": [\n                {\n                    \"nodeType\": \"YulData\",\n                    \"value\": \"<BYTECODE REMOVED>\"\n                }\n            ]\n        }\n    ]\n}\nOptimized IR AST:\n{\n    \"code\": {\n        \"block\": {\n            \"nativeSrc\": \"51:315:0\",\n            \"nodeType\": \"YulBlock\",\n            \"src\": \"-1:-1:0\",\n            \"statements\": [\n                {\n                    \"nativeSrc\": \"61:299:0\",\n                    \"nodeType\": \"YulBlock\",\n                    \"src\": \"-1:-1:0\",\n                    \"statements\": [\n                        {\n                            \"nativeSrc\": \"121:27:0\",\n                            \"nodeType\": \"YulVariableDeclaration\",\n                            \"src\": \"60:13:0\",\n                            \"value\": {\n                                \"arguments\": [\n                                    {\n                                        \"kind\": \"number\",\n                                        \"nativeSrc\": \"143:4:0\",\n                                        \"nodeType\": \"YulLiteral\",\n                                        \"src\": \"60:13:0\",\n                                        \"type\": \"\",\n                                        \"value\": \"0x80\"\n                                    }\n                                ],\n                                \"functionName\": {\n                                    \"name\": \"memoryguard\",\n                                    \"nativeSrc\": \"131:11:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"131:17:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            },\n                            \"variables\": [\n                                {\n                                    \"name\": \"_1\",\n                                    \"nativeSrc\": \"125:2:0\",\n                                    \"nodeType\": \"YulTypedName\",\n                                    \"src\": \"60:13:0\",\n                                    \"type\": \"\"\n                                }\n                            ]\n                        },\n                        {\n                            \"expression\": {\n                                \"arguments\": [\n                                    {\n                                        \"kind\": \"number\",\n                                        \"nativeSrc\": \"168:2:0\",\n                                        \"nodeType\": \"YulLiteral\",\n                                        \"src\": \"60:13:0\",\n                                        \"type\": \"\",\n                                        \"value\": \"64\"\n                                    },\n                                    {\n                                        \"name\": \"_1\",\n                                        \"nativeSrc\": \"172:2:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"60:13:0\"\n                                    }\n                                ],\n                                \"functionName\": {\n                                    \"name\": \"mstore\",\n                                    \"nativeSrc\": \"161:6:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"161:14:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            },\n                            \"nativeSrc\": \"161:14:0\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"60:13:0\"\n                        },\n                        {\n                            \"body\": {\n                                \"nativeSrc\": \"203:16:0\",\n                                \"nodeType\": \"YulBlock\",\n                                \"src\": \"60:13:0\",\n                                \"statements\": [\n                                    {\n                                        \"expression\": {\n                                            \"arguments\": [\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"212:1:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"60:13:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"0\"\n                                                },\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"215:1:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"60:13:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"0\"\n                                                }\n                                            ],\n                                            \"functionName\": {\n                                                \"name\": \"revert\",\n                                                \"nativeSrc\": \"205:6:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"60:13:0\"\n                                            },\n                                            \"nativeSrc\": \"205:12:0\",\n                                            \"nodeType\": \"YulFunctionCall\",\n                                            \"src\": \"60:13:0\"\n                                        },\n                                        \"nativeSrc\": \"205:12:0\",\n                                        \"nodeType\": \"YulExpressionStatement\",\n                                        \"src\": \"60:13:0\"\n                                    }\n                                ]\n                            },\n                            \"condition\": {\n                                \"arguments\": [],\n                                \"functionName\": {\n                                    \"name\": \"callvalue\",\n                                    \"nativeSrc\": \"191:9:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"191:11:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            },\n                            \"nativeSrc\": \"188:31:0\",\n                            \"nodeType\": \"YulIf\",\n                            \"src\": \"60:13:0\"\n                        },\n                        {\n                            \"nativeSrc\": \"232:34:0\",\n                            \"nodeType\": \"YulVariableDeclaration\",\n                            \"src\": \"60:13:0\",\n                            \"value\": {\n                                \"arguments\": [\n                                    {\n                                        \"hexValue\": \"435f325f6465706c6f796564\",\n                                        \"kind\": \"string\",\n                                        \"nativeSrc\": \"251:14:0\",\n                                        \"nodeType\": \"YulLiteral\",\n                                        \"src\": \"60:13:0\",\n                                        \"type\": \"\",\n                                        \"value\": \"C_2_deployed\"\n                                    }\n                                ],\n                                \"functionName\": {\n                                    \"name\": \"datasize\",\n                                    \"nativeSrc\": \"242:8:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"242:24:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            },\n                            \"variables\": [\n                                {\n                                    \"name\": \"_2\",\n                                    \"nativeSrc\": \"236:2:0\",\n                                    \"nodeType\": \"YulTypedName\",\n                                    \"src\": \"60:13:0\",\n                                    \"type\": \"\"\n                                }\n                            ]\n                        },\n                        {\n                            \"expression\": {\n                                \"arguments\": [\n                                    {\n                                        \"name\": \"_1\",\n                                        \"nativeSrc\": \"288:2:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"60:13:0\"\n                                    },\n                                    {\n                                        \"arguments\": [\n                                            {\n                                                \"hexValue\": \"435f325f6465706c6f796564\",\n                                                \"kind\": \"string\",\n                                                \"nativeSrc\": \"303:14:0\",\n                                                \"nodeType\": \"YulLiteral\",\n                                                \"src\": \"60:13:0\",\n                                                \"type\": \"\",\n                                                \"value\": \"C_2_deployed\"\n                                            }\n                                        ],\n                                        \"functionName\": {\n                                            \"name\": \"dataoffset\",\n                                            \"nativeSrc\": \"292:10:0\",\n                                            \"nodeType\": \"YulIdentifier\",\n                                            \"src\": \"60:13:0\"\n                                        },\n                                        \"nativeSrc\": \"292:26:0\",\n                                        \"nodeType\": \"YulFunctionCall\",\n                                        \"src\": \"60:13:0\"\n                                    },\n                                    {\n                                        \"name\": \"_2\",\n                                        \"nativeSrc\": \"320:2:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"60:13:0\"\n                                    }\n                                ],\n                                \"functionName\": {\n                                    \"name\": \"codecopy\",\n                                    \"nativeSrc\": \"279:8:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"279:44:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            },\n                            \"nativeSrc\": \"279:44:0\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"60:13:0\"\n                        },\n                        {\n                            \"expression\": {\n                                \"arguments\": [\n                                    {\n                                        \"name\": \"_1\",\n                                        \"nativeSrc\": \"343:2:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"60:13:0\"\n                                    },\n                                    {\n                                        \"name\": \"_2\",\n                                        \"nativeSrc\": \"347:2:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"60:13:0\"\n                                    }\n                                ],\n                                \"functionName\": {\n                                    \"name\": \"return\",\n                                    \"nativeSrc\": \"336:6:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:13:0\"\n                                },\n                                \"nativeSrc\": \"336:14:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:13:0\"\n                            },\n                            \"nativeSrc\": \"336:14:0\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"60:13:0\"\n                        }\n                    ]\n                }\n            ]\n        },\n        \"nodeType\": \"YulCode\"\n    },\n    \"name\": \"C_2\",\n    \"nodeType\": \"YulObject\",\n    \"subObjects\": [\n        {\n            \"code\": {\n                \"block\": {\n                    \"nativeSrc\": \"439:118:0\",\n                    \"nodeType\": \"YulBlock\",\n                    \"src\": \"-1:-1:0\",\n                    \"statements\": [\n                        {\n                            \"nativeSrc\": \"453:94:0\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"-1:-1:0\",\n                            \"statements\": [\n                                {\n                                    \"expression\": {\n                                        \"arguments\": [\n                                            {\n                                                \"kind\": \"number\",\n                                                \"nativeSrc\": \"528:1:0\",\n                                                \"nodeType\": \"YulLiteral\",\n                                                \"src\": \"60:13:0\",\n                                                \"type\": \"\",\n                                                \"value\": \"0\"\n                                            },\n                                            {\n                                                \"kind\": \"number\",\n                                                \"nativeSrc\": \"531:1:0\",\n                                                \"nodeType\": \"YulLiteral\",\n                                                \"src\": \"60:13:0\",\n                                                \"type\": \"\",\n                                                \"value\": \"0\"\n                                            }\n                                        ],\n                                        \"functionName\": {\n                                            \"name\": \"revert\",\n                                            \"nativeSrc\": \"521:6:0\",\n                                            \"nodeType\": \"YulIdentifier\",\n                                            \"src\": \"60:13:0\"\n                                        },\n                                        \"nativeSrc\": \"521:12:0\",\n                                        \"nodeType\": \"YulFunctionCall\",\n                                        \"src\": \"60:13:0\"\n                                    },\n                                    \"nativeSrc\": \"521:12:0\",\n                                    \"nodeType\": \"YulExpressionStatement\",\n                                    \"src\": \"60:13:0\"\n                                }\n                            ]\n                        }\n                    ]\n                },\n                \"nodeType\": \"YulCode\"\n            },\n            \"name\": \"C_2_deployed\",\n            \"nodeType\": \"YulObject\",\n            \"subObjects\": [\n                {\n                    \"nodeType\": \"YulData\",\n                    \"value\": \"<BYTECODE REMOVED>\"\n                }\n            ]\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/ast_json_import_wrong_evmVersion/args",
    "content": "--experimental --evm-version=homestead --import-ast --combined-json ast --pretty-json\n"
  },
  {
    "path": "test/cmdlineTests/ast_json_import_wrong_evmVersion/err",
    "content": "Warning: Support for EVM versions older than constantinople is deprecated and will be removed in the future.\nError: Failed to import AST: Imported tree evm version differs from configured evm version!\n"
  },
  {
    "path": "test/cmdlineTests/ast_json_import_wrong_evmVersion/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/ast_json_import_wrong_evmVersion/input.sol",
    "content": "{\n  \"contracts\":\n  {\n    \"test/cmdlineTests/ast_json_import_wrong_evmVersion/input.sol:C\": {}\n  },\n  \"sourceList\":\n  [\n    \"test/cmdlineTests/ast_json_import_wrong_evmVersion/input.sol\"\n  ],\n  \"sources\":\n  {\n    \"test/cmdlineTests/ast_json_import_wrong_evmVersion/input.sol\":\n    {\n      \"AST\":\n      {\n        \"absolutePath\": \"test/cmdlineTests/ast_json_import_wrong_evmVersion/input.sol\",\n        \"exportedSymbols\":\n        {\n          \"C\":\n          [\n            7\n          ]\n        },\n        \"id\": 8,\n        \"nodeType\": \"SourceUnit\",\n        \"nodes\":\n        [\n          {\n            \"id\": 1,\n            \"literals\":\n            [\n              \"solidity\",\n              \">=\",\n              \"0.0\"\n            ],\n            \"nodeType\": \"PragmaDirective\",\n            \"src\": \"0:22:0\"\n          },\n          {\n            \"abstract\": false,\n            \"baseContracts\": [],\n            \"contractDependencies\": [],\n            \"contractKind\": \"contract\",\n            \"documentation\": null,\n            \"fullyImplemented\": true,\n            \"id\": 7,\n            \"linearizedBaseContracts\":\n            [\n              7\n            ],\n            \"name\": \"C\",\n            \"nameLocation\": \"27:1:0\",\n            \"nodeType\": \"ContractDefinition\",\n            \"nodes\":\n            [\n              {\n                \"body\":\n                {\n                  \"id\": 5,\n                  \"nodeType\": \"Block\",\n                  \"src\": \"65:21:0\",\n                  \"statements\":\n                  [\n                    {\n                      \"AST\":\n                      {\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"78:2:0\",\n                        \"statements\": []\n                      },\n                      \"evmVersion\": \"istanbul\",\n                      \"externalReferences\": [],\n                      \"id\": 4,\n                      \"nodeType\": \"InlineAssembly\",\n                      \"src\": \"69:11:0\"\n                    }\n                  ]\n                },\n                \"documentation\": null,\n                \"functionSelector\": \"26121ff0\",\n                \"id\": 6,\n                \"implemented\": true,\n                \"kind\": \"function\",\n                \"modifiers\": [],\n                \"name\": \"f\",\n                \"nameLocation\": \"45:4:0\",\n                \"nodeType\": \"FunctionDefinition\",\n                \"overrides\": null,\n                \"parameters\":\n                {\n                  \"id\": 2,\n                  \"nodeType\": \"ParameterList\",\n                  \"parameters\": [],\n                  \"src\": \"50:2:0\"\n                },\n                \"returnParameters\":\n                {\n                  \"id\": 3,\n                  \"nodeType\": \"ParameterList\",\n                  \"parameters\": [],\n                  \"src\": \"65:0:0\"\n                },\n                \"scope\": 7,\n                \"src\": \"40:46:0\",\n                \"stateMutability\": \"pure\",\n                \"virtual\": false,\n                \"visibility\": \"public\"\n              }\n            ],\n            \"scope\": 8,\n            \"src\": \"23:65:0\"\n          }\n        ],\n        \"src\": \"0:89:0\"\n      }\n    }\n  },\n  \"version\": \"0.6.2-develop.2020.1.14+commit.e8556fa1.mod.Linux.g++\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_abi/args",
    "content": "--combined-json abi --pretty-json --json-indent 3\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_abi/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_abi/output",
    "content": "{\n   \"contracts\": {\n      \"input.sol:C\": {\n         \"abi\": []\n      }\n   },\n   \"version\": \"<VERSION REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_generated_sources/args",
    "content": "--combined-json generated-sources,generated-sources-runtime --pretty-json\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_generated_sources/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma abicoder v2;\n\ncontract C {\n  function f(uint[] calldata) pure external {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_generated_sources/output",
    "content": "{\n  \"contracts\": {\n    \"input.sol:C\": {\n      \"generated-sources\": [],\n      \"generated-sources-runtime\": [\n        {\n          \"ast\": {\n            \"nativeSrc\": \"0:1856:1\",\n            \"nodeType\": \"YulBlock\",\n            \"src\": \"0:1856:1\",\n            \"statements\": [\n              {\n                \"body\": {\n                  \"nativeSrc\": \"47:35:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"47:35:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"57:19:1\",\n                      \"nodeType\": \"YulAssignment\",\n                      \"src\": \"57:19:1\",\n                      \"value\": {\n                        \"arguments\": [\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"73:2:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"73:2:1\",\n                            \"type\": \"\",\n                            \"value\": \"64\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"mload\",\n                          \"nativeSrc\": \"67:5:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"67:5:1\"\n                        },\n                        \"nativeSrc\": \"67:9:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"67:9:1\"\n                      },\n                      \"variableNames\": [\n                        {\n                          \"name\": \"memPtr\",\n                          \"nativeSrc\": \"57:6:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"57:6:1\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"name\": \"allocate_unbounded\",\n                \"nativeSrc\": \"7:75:1\",\n                \"nodeType\": \"YulFunctionDefinition\",\n                \"returnVariables\": [\n                  {\n                    \"name\": \"memPtr\",\n                    \"nativeSrc\": \"40:6:1\",\n                    \"nodeType\": \"YulTypedName\",\n                    \"src\": \"40:6:1\",\n                    \"type\": \"\"\n                  }\n                ],\n                \"src\": \"7:75:1\"\n              },\n              {\n                \"body\": {\n                  \"nativeSrc\": \"177:28:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"177:28:1\",\n                  \"statements\": [\n                    {\n                      \"expression\": {\n                        \"arguments\": [\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"194:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"194:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          },\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"197:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"197:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"revert\",\n                          \"nativeSrc\": \"187:6:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"187:6:1\"\n                        },\n                        \"nativeSrc\": \"187:12:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"187:12:1\"\n                      },\n                      \"nativeSrc\": \"187:12:1\",\n                      \"nodeType\": \"YulExpressionStatement\",\n                      \"src\": \"187:12:1\"\n                    }\n                  ]\n                },\n                \"name\": \"revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b\",\n                \"nativeSrc\": \"88:117:1\",\n                \"nodeType\": \"YulFunctionDefinition\",\n                \"src\": \"88:117:1\"\n              },\n              {\n                \"body\": {\n                  \"nativeSrc\": \"300:28:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"300:28:1\",\n                  \"statements\": [\n                    {\n                      \"expression\": {\n                        \"arguments\": [\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"317:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"317:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          },\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"320:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"320:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"revert\",\n                          \"nativeSrc\": \"310:6:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"310:6:1\"\n                        },\n                        \"nativeSrc\": \"310:12:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"310:12:1\"\n                      },\n                      \"nativeSrc\": \"310:12:1\",\n                      \"nodeType\": \"YulExpressionStatement\",\n                      \"src\": \"310:12:1\"\n                    }\n                  ]\n                },\n                \"name\": \"revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db\",\n                \"nativeSrc\": \"211:117:1\",\n                \"nodeType\": \"YulFunctionDefinition\",\n                \"src\": \"211:117:1\"\n              },\n              {\n                \"body\": {\n                  \"nativeSrc\": \"423:28:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"423:28:1\",\n                  \"statements\": [\n                    {\n                      \"expression\": {\n                        \"arguments\": [\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"440:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"440:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          },\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"443:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"443:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"revert\",\n                          \"nativeSrc\": \"433:6:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"433:6:1\"\n                        },\n                        \"nativeSrc\": \"433:12:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"433:12:1\"\n                      },\n                      \"nativeSrc\": \"433:12:1\",\n                      \"nodeType\": \"YulExpressionStatement\",\n                      \"src\": \"433:12:1\"\n                    }\n                  ]\n                },\n                \"name\": \"revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d\",\n                \"nativeSrc\": \"334:117:1\",\n                \"nodeType\": \"YulFunctionDefinition\",\n                \"src\": \"334:117:1\"\n              },\n              {\n                \"body\": {\n                  \"nativeSrc\": \"546:28:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"546:28:1\",\n                  \"statements\": [\n                    {\n                      \"expression\": {\n                        \"arguments\": [\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"563:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"563:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          },\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"566:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"566:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"revert\",\n                          \"nativeSrc\": \"556:6:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"556:6:1\"\n                        },\n                        \"nativeSrc\": \"556:12:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"556:12:1\"\n                      },\n                      \"nativeSrc\": \"556:12:1\",\n                      \"nodeType\": \"YulExpressionStatement\",\n                      \"src\": \"556:12:1\"\n                    }\n                  ]\n                },\n                \"name\": \"revert_error_15abf5612cd996bc235ba1e55a4a30ac60e6bb601ff7ba4ad3f179b6be8d0490\",\n                \"nativeSrc\": \"457:117:1\",\n                \"nodeType\": \"YulFunctionDefinition\",\n                \"src\": \"457:117:1\"\n              },\n              {\n                \"body\": {\n                  \"nativeSrc\": \"669:28:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"669:28:1\",\n                  \"statements\": [\n                    {\n                      \"expression\": {\n                        \"arguments\": [\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"686:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"686:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          },\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"689:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"689:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"revert\",\n                          \"nativeSrc\": \"679:6:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"679:6:1\"\n                        },\n                        \"nativeSrc\": \"679:12:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"679:12:1\"\n                      },\n                      \"nativeSrc\": \"679:12:1\",\n                      \"nodeType\": \"YulExpressionStatement\",\n                      \"src\": \"679:12:1\"\n                    }\n                  ]\n                },\n                \"name\": \"revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef\",\n                \"nativeSrc\": \"580:117:1\",\n                \"nodeType\": \"YulFunctionDefinition\",\n                \"src\": \"580:117:1\"\n              },\n              {\n                \"body\": {\n                  \"nativeSrc\": \"810:478:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"810:478:1\",\n                  \"statements\": [\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"859:83:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"859:83:1\",\n                        \"statements\": [\n                          {\n                            \"expression\": {\n                              \"arguments\": [],\n                              \"functionName\": {\n                                \"name\": \"revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d\",\n                                \"nativeSrc\": \"861:77:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"861:77:1\"\n                              },\n                              \"nativeSrc\": \"861:79:1\",\n                              \"nodeType\": \"YulFunctionCall\",\n                              \"src\": \"861:79:1\"\n                            },\n                            \"nativeSrc\": \"861:79:1\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"861:79:1\"\n                          }\n                        ]\n                      },\n                      \"condition\": {\n                        \"arguments\": [\n                          {\n                            \"arguments\": [\n                              {\n                                \"arguments\": [\n                                  {\n                                    \"name\": \"offset\",\n                                    \"nativeSrc\": \"838:6:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"838:6:1\"\n                                  },\n                                  {\n                                    \"kind\": \"number\",\n                                    \"nativeSrc\": \"846:4:1\",\n                                    \"nodeType\": \"YulLiteral\",\n                                    \"src\": \"846:4:1\",\n                                    \"type\": \"\",\n                                    \"value\": \"0x1f\"\n                                  }\n                                ],\n                                \"functionName\": {\n                                  \"name\": \"add\",\n                                  \"nativeSrc\": \"834:3:1\",\n                                  \"nodeType\": \"YulIdentifier\",\n                                  \"src\": \"834:3:1\"\n                                },\n                                \"nativeSrc\": \"834:17:1\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"834:17:1\"\n                              },\n                              {\n                                \"name\": \"end\",\n                                \"nativeSrc\": \"853:3:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"853:3:1\"\n                              }\n                            ],\n                            \"functionName\": {\n                              \"name\": \"slt\",\n                              \"nativeSrc\": \"830:3:1\",\n                              \"nodeType\": \"YulIdentifier\",\n                              \"src\": \"830:3:1\"\n                            },\n                            \"nativeSrc\": \"830:27:1\",\n                            \"nodeType\": \"YulFunctionCall\",\n                            \"src\": \"830:27:1\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"iszero\",\n                          \"nativeSrc\": \"823:6:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"823:6:1\"\n                        },\n                        \"nativeSrc\": \"823:35:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"823:35:1\"\n                      },\n                      \"nativeSrc\": \"820:122:1\",\n                      \"nodeType\": \"YulIf\",\n                      \"src\": \"820:122:1\"\n                    },\n                    {\n                      \"nativeSrc\": \"951:30:1\",\n                      \"nodeType\": \"YulAssignment\",\n                      \"src\": \"951:30:1\",\n                      \"value\": {\n                        \"arguments\": [\n                          {\n                            \"name\": \"offset\",\n                            \"nativeSrc\": \"974:6:1\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"974:6:1\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"calldataload\",\n                          \"nativeSrc\": \"961:12:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"961:12:1\"\n                        },\n                        \"nativeSrc\": \"961:20:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"961:20:1\"\n                      },\n                      \"variableNames\": [\n                        {\n                          \"name\": \"length\",\n                          \"nativeSrc\": \"951:6:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"951:6:1\"\n                        }\n                      ]\n                    },\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"1024:83:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"1024:83:1\",\n                        \"statements\": [\n                          {\n                            \"expression\": {\n                              \"arguments\": [],\n                              \"functionName\": {\n                                \"name\": \"revert_error_15abf5612cd996bc235ba1e55a4a30ac60e6bb601ff7ba4ad3f179b6be8d0490\",\n                                \"nativeSrc\": \"1026:77:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"1026:77:1\"\n                              },\n                              \"nativeSrc\": \"1026:79:1\",\n                              \"nodeType\": \"YulFunctionCall\",\n                              \"src\": \"1026:79:1\"\n                            },\n                            \"nativeSrc\": \"1026:79:1\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"1026:79:1\"\n                          }\n                        ]\n                      },\n                      \"condition\": {\n                        \"arguments\": [\n                          {\n                            \"name\": \"length\",\n                            \"nativeSrc\": \"996:6:1\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"996:6:1\"\n                          },\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"1004:18:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"1004:18:1\",\n                            \"type\": \"\",\n                            \"value\": \"0xffffffffffffffff\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"gt\",\n                          \"nativeSrc\": \"993:2:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"993:2:1\"\n                        },\n                        \"nativeSrc\": \"993:30:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"993:30:1\"\n                      },\n                      \"nativeSrc\": \"990:117:1\",\n                      \"nodeType\": \"YulIf\",\n                      \"src\": \"990:117:1\"\n                    },\n                    {\n                      \"nativeSrc\": \"1116:29:1\",\n                      \"nodeType\": \"YulAssignment\",\n                      \"src\": \"1116:29:1\",\n                      \"value\": {\n                        \"arguments\": [\n                          {\n                            \"name\": \"offset\",\n                            \"nativeSrc\": \"1132:6:1\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"1132:6:1\"\n                          },\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"1140:4:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"1140:4:1\",\n                            \"type\": \"\",\n                            \"value\": \"0x20\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"add\",\n                          \"nativeSrc\": \"1128:3:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"1128:3:1\"\n                        },\n                        \"nativeSrc\": \"1128:17:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"1128:17:1\"\n                      },\n                      \"variableNames\": [\n                        {\n                          \"name\": \"arrayPos\",\n                          \"nativeSrc\": \"1116:8:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"1116:8:1\"\n                        }\n                      ]\n                    },\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"1199:83:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"1199:83:1\",\n                        \"statements\": [\n                          {\n                            \"expression\": {\n                              \"arguments\": [],\n                              \"functionName\": {\n                                \"name\": \"revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef\",\n                                \"nativeSrc\": \"1201:77:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"1201:77:1\"\n                              },\n                              \"nativeSrc\": \"1201:79:1\",\n                              \"nodeType\": \"YulFunctionCall\",\n                              \"src\": \"1201:79:1\"\n                            },\n                            \"nativeSrc\": \"1201:79:1\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"1201:79:1\"\n                          }\n                        ]\n                      },\n                      \"condition\": {\n                        \"arguments\": [\n                          {\n                            \"arguments\": [\n                              {\n                                \"name\": \"arrayPos\",\n                                \"nativeSrc\": \"1164:8:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"1164:8:1\"\n                              },\n                              {\n                                \"arguments\": [\n                                  {\n                                    \"name\": \"length\",\n                                    \"nativeSrc\": \"1178:6:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"1178:6:1\"\n                                  },\n                                  {\n                                    \"kind\": \"number\",\n                                    \"nativeSrc\": \"1186:4:1\",\n                                    \"nodeType\": \"YulLiteral\",\n                                    \"src\": \"1186:4:1\",\n                                    \"type\": \"\",\n                                    \"value\": \"0x20\"\n                                  }\n                                ],\n                                \"functionName\": {\n                                  \"name\": \"mul\",\n                                  \"nativeSrc\": \"1174:3:1\",\n                                  \"nodeType\": \"YulIdentifier\",\n                                  \"src\": \"1174:3:1\"\n                                },\n                                \"nativeSrc\": \"1174:17:1\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"1174:17:1\"\n                              }\n                            ],\n                            \"functionName\": {\n                              \"name\": \"add\",\n                              \"nativeSrc\": \"1160:3:1\",\n                              \"nodeType\": \"YulIdentifier\",\n                              \"src\": \"1160:3:1\"\n                            },\n                            \"nativeSrc\": \"1160:32:1\",\n                            \"nodeType\": \"YulFunctionCall\",\n                            \"src\": \"1160:32:1\"\n                          },\n                          {\n                            \"name\": \"end\",\n                            \"nativeSrc\": \"1194:3:1\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"1194:3:1\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"gt\",\n                          \"nativeSrc\": \"1157:2:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"1157:2:1\"\n                        },\n                        \"nativeSrc\": \"1157:41:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"1157:41:1\"\n                      },\n                      \"nativeSrc\": \"1154:128:1\",\n                      \"nodeType\": \"YulIf\",\n                      \"src\": \"1154:128:1\"\n                    }\n                  ]\n                },\n                \"name\": \"abi_decode_t_array$_t_uint256_$dyn_calldata_ptr\",\n                \"nativeSrc\": \"720:568:1\",\n                \"nodeType\": \"YulFunctionDefinition\",\n                \"parameters\": [\n                  {\n                    \"name\": \"offset\",\n                    \"nativeSrc\": \"777:6:1\",\n                    \"nodeType\": \"YulTypedName\",\n                    \"src\": \"777:6:1\",\n                    \"type\": \"\"\n                  },\n                  {\n                    \"name\": \"end\",\n                    \"nativeSrc\": \"785:3:1\",\n                    \"nodeType\": \"YulTypedName\",\n                    \"src\": \"785:3:1\",\n                    \"type\": \"\"\n                  }\n                ],\n                \"returnVariables\": [\n                  {\n                    \"name\": \"arrayPos\",\n                    \"nativeSrc\": \"793:8:1\",\n                    \"nodeType\": \"YulTypedName\",\n                    \"src\": \"793:8:1\",\n                    \"type\": \"\"\n                  },\n                  {\n                    \"name\": \"length\",\n                    \"nativeSrc\": \"803:6:1\",\n                    \"nodeType\": \"YulTypedName\",\n                    \"src\": \"803:6:1\",\n                    \"type\": \"\"\n                  }\n                ],\n                \"src\": \"720:568:1\"\n              },\n              {\n                \"body\": {\n                  \"nativeSrc\": \"1395:458:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"1395:458:1\",\n                  \"statements\": [\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"1441:83:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"1441:83:1\",\n                        \"statements\": [\n                          {\n                            \"expression\": {\n                              \"arguments\": [],\n                              \"functionName\": {\n                                \"name\": \"revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b\",\n                                \"nativeSrc\": \"1443:77:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"1443:77:1\"\n                              },\n                              \"nativeSrc\": \"1443:79:1\",\n                              \"nodeType\": \"YulFunctionCall\",\n                              \"src\": \"1443:79:1\"\n                            },\n                            \"nativeSrc\": \"1443:79:1\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"1443:79:1\"\n                          }\n                        ]\n                      },\n                      \"condition\": {\n                        \"arguments\": [\n                          {\n                            \"arguments\": [\n                              {\n                                \"name\": \"dataEnd\",\n                                \"nativeSrc\": \"1416:7:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"1416:7:1\"\n                              },\n                              {\n                                \"name\": \"headStart\",\n                                \"nativeSrc\": \"1425:9:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"1425:9:1\"\n                              }\n                            ],\n                            \"functionName\": {\n                              \"name\": \"sub\",\n                              \"nativeSrc\": \"1412:3:1\",\n                              \"nodeType\": \"YulIdentifier\",\n                              \"src\": \"1412:3:1\"\n                            },\n                            \"nativeSrc\": \"1412:23:1\",\n                            \"nodeType\": \"YulFunctionCall\",\n                            \"src\": \"1412:23:1\"\n                          },\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"1437:2:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"1437:2:1\",\n                            \"type\": \"\",\n                            \"value\": \"32\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"slt\",\n                          \"nativeSrc\": \"1408:3:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"1408:3:1\"\n                        },\n                        \"nativeSrc\": \"1408:32:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"1408:32:1\"\n                      },\n                      \"nativeSrc\": \"1405:119:1\",\n                      \"nodeType\": \"YulIf\",\n                      \"src\": \"1405:119:1\"\n                    },\n                    {\n                      \"nativeSrc\": \"1534:312:1\",\n                      \"nodeType\": \"YulBlock\",\n                      \"src\": \"1534:312:1\",\n                      \"statements\": [\n                        {\n                          \"nativeSrc\": \"1549:45:1\",\n                          \"nodeType\": \"YulVariableDeclaration\",\n                          \"src\": \"1549:45:1\",\n                          \"value\": {\n                            \"arguments\": [\n                              {\n                                \"arguments\": [\n                                  {\n                                    \"name\": \"headStart\",\n                                    \"nativeSrc\": \"1580:9:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"1580:9:1\"\n                                  },\n                                  {\n                                    \"kind\": \"number\",\n                                    \"nativeSrc\": \"1591:1:1\",\n                                    \"nodeType\": \"YulLiteral\",\n                                    \"src\": \"1591:1:1\",\n                                    \"type\": \"\",\n                                    \"value\": \"0\"\n                                  }\n                                ],\n                                \"functionName\": {\n                                  \"name\": \"add\",\n                                  \"nativeSrc\": \"1576:3:1\",\n                                  \"nodeType\": \"YulIdentifier\",\n                                  \"src\": \"1576:3:1\"\n                                },\n                                \"nativeSrc\": \"1576:17:1\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"1576:17:1\"\n                              }\n                            ],\n                            \"functionName\": {\n                              \"name\": \"calldataload\",\n                              \"nativeSrc\": \"1563:12:1\",\n                              \"nodeType\": \"YulIdentifier\",\n                              \"src\": \"1563:12:1\"\n                            },\n                            \"nativeSrc\": \"1563:31:1\",\n                            \"nodeType\": \"YulFunctionCall\",\n                            \"src\": \"1563:31:1\"\n                          },\n                          \"variables\": [\n                            {\n                              \"name\": \"offset\",\n                              \"nativeSrc\": \"1553:6:1\",\n                              \"nodeType\": \"YulTypedName\",\n                              \"src\": \"1553:6:1\",\n                              \"type\": \"\"\n                            }\n                          ]\n                        },\n                        {\n                          \"body\": {\n                            \"nativeSrc\": \"1641:83:1\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"1641:83:1\",\n                            \"statements\": [\n                              {\n                                \"expression\": {\n                                  \"arguments\": [],\n                                  \"functionName\": {\n                                    \"name\": \"revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db\",\n                                    \"nativeSrc\": \"1643:77:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"1643:77:1\"\n                                  },\n                                  \"nativeSrc\": \"1643:79:1\",\n                                  \"nodeType\": \"YulFunctionCall\",\n                                  \"src\": \"1643:79:1\"\n                                },\n                                \"nativeSrc\": \"1643:79:1\",\n                                \"nodeType\": \"YulExpressionStatement\",\n                                \"src\": \"1643:79:1\"\n                              }\n                            ]\n                          },\n                          \"condition\": {\n                            \"arguments\": [\n                              {\n                                \"name\": \"offset\",\n                                \"nativeSrc\": \"1613:6:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"1613:6:1\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"1621:18:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"1621:18:1\",\n                                \"type\": \"\",\n                                \"value\": \"0xffffffffffffffff\"\n                              }\n                            ],\n                            \"functionName\": {\n                              \"name\": \"gt\",\n                              \"nativeSrc\": \"1610:2:1\",\n                              \"nodeType\": \"YulIdentifier\",\n                              \"src\": \"1610:2:1\"\n                            },\n                            \"nativeSrc\": \"1610:30:1\",\n                            \"nodeType\": \"YulFunctionCall\",\n                            \"src\": \"1610:30:1\"\n                          },\n                          \"nativeSrc\": \"1607:117:1\",\n                          \"nodeType\": \"YulIf\",\n                          \"src\": \"1607:117:1\"\n                        },\n                        {\n                          \"nativeSrc\": \"1738:98:1\",\n                          \"nodeType\": \"YulAssignment\",\n                          \"src\": \"1738:98:1\",\n                          \"value\": {\n                            \"arguments\": [\n                              {\n                                \"arguments\": [\n                                  {\n                                    \"name\": \"headStart\",\n                                    \"nativeSrc\": \"1808:9:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"1808:9:1\"\n                                  },\n                                  {\n                                    \"name\": \"offset\",\n                                    \"nativeSrc\": \"1819:6:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"1819:6:1\"\n                                  }\n                                ],\n                                \"functionName\": {\n                                  \"name\": \"add\",\n                                  \"nativeSrc\": \"1804:3:1\",\n                                  \"nodeType\": \"YulIdentifier\",\n                                  \"src\": \"1804:3:1\"\n                                },\n                                \"nativeSrc\": \"1804:22:1\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"1804:22:1\"\n                              },\n                              {\n                                \"name\": \"dataEnd\",\n                                \"nativeSrc\": \"1828:7:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"1828:7:1\"\n                              }\n                            ],\n                            \"functionName\": {\n                              \"name\": \"abi_decode_t_array$_t_uint256_$dyn_calldata_ptr\",\n                              \"nativeSrc\": \"1756:47:1\",\n                              \"nodeType\": \"YulIdentifier\",\n                              \"src\": \"1756:47:1\"\n                            },\n                            \"nativeSrc\": \"1756:80:1\",\n                            \"nodeType\": \"YulFunctionCall\",\n                            \"src\": \"1756:80:1\"\n                          },\n                          \"variableNames\": [\n                            {\n                              \"name\": \"value0\",\n                              \"nativeSrc\": \"1738:6:1\",\n                              \"nodeType\": \"YulIdentifier\",\n                              \"src\": \"1738:6:1\"\n                            },\n                            {\n                              \"name\": \"value1\",\n                              \"nativeSrc\": \"1746:6:1\",\n                              \"nodeType\": \"YulIdentifier\",\n                              \"src\": \"1746:6:1\"\n                            }\n                          ]\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"name\": \"abi_decode_tuple_t_array$_t_uint256_$dyn_calldata_ptr\",\n                \"nativeSrc\": \"1294:559:1\",\n                \"nodeType\": \"YulFunctionDefinition\",\n                \"parameters\": [\n                  {\n                    \"name\": \"headStart\",\n                    \"nativeSrc\": \"1357:9:1\",\n                    \"nodeType\": \"YulTypedName\",\n                    \"src\": \"1357:9:1\",\n                    \"type\": \"\"\n                  },\n                  {\n                    \"name\": \"dataEnd\",\n                    \"nativeSrc\": \"1368:7:1\",\n                    \"nodeType\": \"YulTypedName\",\n                    \"src\": \"1368:7:1\",\n                    \"type\": \"\"\n                  }\n                ],\n                \"returnVariables\": [\n                  {\n                    \"name\": \"value0\",\n                    \"nativeSrc\": \"1380:6:1\",\n                    \"nodeType\": \"YulTypedName\",\n                    \"src\": \"1380:6:1\",\n                    \"type\": \"\"\n                  },\n                  {\n                    \"name\": \"value1\",\n                    \"nativeSrc\": \"1388:6:1\",\n                    \"nodeType\": \"YulTypedName\",\n                    \"src\": \"1388:6:1\",\n                    \"type\": \"\"\n                  }\n                ],\n                \"src\": \"1294:559:1\"\n              }\n            ]\n          },\n          \"contents\": \"{\\n\\n    function allocate_unbounded() -> memPtr {\\n        memPtr := mload(64)\\n    }\\n\\n    function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\\n        revert(0, 0)\\n    }\\n\\n    function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\\n        revert(0, 0)\\n    }\\n\\n    function revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() {\\n        revert(0, 0)\\n    }\\n\\n    function revert_error_15abf5612cd996bc235ba1e55a4a30ac60e6bb601ff7ba4ad3f179b6be8d0490() {\\n        revert(0, 0)\\n    }\\n\\n    function revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef() {\\n        revert(0, 0)\\n    }\\n\\n    // uint256[]\\n    function abi_decode_t_array$_t_uint256_$dyn_calldata_ptr(offset, end) -> arrayPos, length {\\n        if iszero(slt(add(offset, 0x1f), end)) { revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() }\\n        length := calldataload(offset)\\n        if gt(length, 0xffffffffffffffff) { revert_error_15abf5612cd996bc235ba1e55a4a30ac60e6bb601ff7ba4ad3f179b6be8d0490() }\\n        arrayPos := add(offset, 0x20)\\n        if gt(add(arrayPos, mul(length, 0x20)), end) { revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef() }\\n    }\\n\\n    function abi_decode_tuple_t_array$_t_uint256_$dyn_calldata_ptr(headStart, dataEnd) -> value0, value1 {\\n        if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\\n\\n        {\\n\\n            let offset := calldataload(add(headStart, 0))\\n            if gt(offset, 0xffffffffffffffff) { revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() }\\n\\n            value0, value1 := abi_decode_t_array$_t_uint256_$dyn_calldata_ptr(add(headStart, offset), dataEnd)\\n        }\\n\\n    }\\n\\n}\\n\",\n          \"id\": 1,\n          \"language\": \"Yul\",\n          \"name\": \"#utility.yul\"\n        }\n      ]\n    }\n  },\n  \"version\": \"<VERSION REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_no_pretty_print/args",
    "content": "--combined-json abi\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_no_pretty_print/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_no_pretty_print/output",
    "content": "{\"contracts\":{\"input.sol:C\":{\"abi\":[]}},\"version\": \"<VERSION REMOVED>\"}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_stop_after_parsing/args",
    "content": "--pretty-json --json-indent 4 --stop-after parsing --combined-json abi,asm,ast,bin,bin-runtime,devdoc,function-debug,function-debug-runtime,generated-sources,generated-sources-runtime,hashes,metadata,opcodes,srcmap,srcmap-runtime,storage-layout,userdoc\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_stop_after_parsing/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_stop_after_parsing/output",
    "content": "{\n    \"contracts\": {\n        \"input.sol:C\": {}\n    },\n    \"sourceList\": [\n        \"input.sol\"\n    ],\n    \"sources\": {\n        \"input.sol\": {\n            \"AST\": {\n                \"absolutePath\": \"input.sol\",\n                \"id\": 3,\n                \"license\": \"GPL-3.0\",\n                \"nodeType\": \"SourceUnit\",\n                \"nodes\": [\n                    {\n                        \"id\": 1,\n                        \"literals\": [\n                            \"solidity\",\n                            \"*\"\n                        ],\n                        \"nodeType\": \"PragmaDirective\",\n                        \"src\": \"36:18:0\"\n                    },\n                    {\n                        \"abstract\": false,\n                        \"baseContracts\": [],\n                        \"contractDependencies\": [],\n                        \"contractKind\": \"contract\",\n                        \"id\": 2,\n                        \"name\": \"C\",\n                        \"nameLocation\": \"65:1:0\",\n                        \"nodeType\": \"ContractDefinition\",\n                        \"nodes\": [],\n                        \"src\": \"56:13:0\",\n                        \"usedErrors\": [],\n                        \"usedEvents\": []\n                    }\n                ],\n                \"src\": \"36:34:0\"\n            },\n            \"id\": 0\n        }\n    },\n    \"version\": \"<VERSION REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_with_base_path/args",
    "content": "--combined-json ast --pretty-json --base-path . --allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_with_base_path/c.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_with_base_path/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nimport \"./c.sol\";\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_with_base_path/output",
    "content": "{\n  \"contracts\": {\n    \"c.sol:C\": {}\n  },\n  \"sourceList\": [\n    \"c.sol\",\n    \"input.sol\"\n  ],\n  \"sources\": {\n    \"c.sol\": {\n      \"AST\": {\n        \"absolutePath\": \"c.sol\",\n        \"exportedSymbols\": {\n          \"C\": [\n            5\n          ]\n        },\n        \"id\": 6,\n        \"license\": \"GPL-3.0\",\n        \"nodeType\": \"SourceUnit\",\n        \"nodes\": [\n          {\n            \"id\": 4,\n            \"literals\": [\n              \"solidity\",\n              \">=\",\n              \"0.0\"\n            ],\n            \"nodeType\": \"PragmaDirective\",\n            \"src\": \"36:22:0\"\n          },\n          {\n            \"abstract\": false,\n            \"baseContracts\": [],\n            \"canonicalName\": \"C\",\n            \"contractDependencies\": [],\n            \"contractKind\": \"contract\",\n            \"fullyImplemented\": true,\n            \"id\": 5,\n            \"linearizedBaseContracts\": [\n              5\n            ],\n            \"name\": \"C\",\n            \"nameLocation\": \"69:1:0\",\n            \"nodeType\": \"ContractDefinition\",\n            \"nodes\": [],\n            \"scope\": 6,\n            \"src\": \"60:13:0\",\n            \"usedErrors\": [],\n            \"usedEvents\": []\n          }\n        ],\n        \"src\": \"36:38:0\"\n      },\n      \"id\": 0\n    },\n    \"input.sol\": {\n      \"AST\": {\n        \"absolutePath\": \"input.sol\",\n        \"exportedSymbols\": {\n          \"C\": [\n            5\n          ]\n        },\n        \"id\": 3,\n        \"license\": \"GPL-3.0\",\n        \"nodeType\": \"SourceUnit\",\n        \"nodes\": [\n          {\n            \"id\": 1,\n            \"literals\": [\n              \"solidity\",\n              \">=\",\n              \"0.0\"\n            ],\n            \"nodeType\": \"PragmaDirective\",\n            \"src\": \"36:22:1\"\n          },\n          {\n            \"absolutePath\": \"c.sol\",\n            \"file\": \"./c.sol\",\n            \"id\": 2,\n            \"nameLocation\": \"-1:-1:-1\",\n            \"nodeType\": \"ImportDirective\",\n            \"scope\": 3,\n            \"sourceUnit\": 6,\n            \"src\": \"60:17:1\",\n            \"symbolAliases\": [],\n            \"unitAlias\": \"\"\n          }\n        ],\n        \"src\": \"36:42:1\"\n      },\n      \"id\": 1\n    }\n  },\n  \"version\": \"<VERSION REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_with_devdoc/args",
    "content": "--combined-json devdoc --pretty-json --allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_with_devdoc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\n/// @dev This is devdoc.\ncontract C {}\n\n/// And this is a notice.\ncontract D {}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_with_devdoc/output",
    "content": "{\n  \"contracts\": {\n    \"input.sol:C\": {\n      \"devdoc\": {\n        \"details\": \"This is devdoc.\",\n        \"kind\": \"dev\",\n        \"methods\": {},\n        \"version\": 1\n      }\n    },\n    \"input.sol:D\": {\n      \"devdoc\": {\n        \"kind\": \"dev\",\n        \"methods\": {},\n        \"version\": 1\n      }\n    }\n  },\n  \"version\": \"<VERSION REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_with_userdoc/args",
    "content": "--combined-json userdoc --pretty-json --allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_with_userdoc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\n/// @notice Description for users.\ncontract C {}\n\n/// @dev Description for developers.\ncontract D {}\n"
  },
  {
    "path": "test/cmdlineTests/combined_json_with_userdoc/output",
    "content": "{\n  \"contracts\": {\n    \"input.sol:C\": {\n      \"userdoc\": {\n        \"kind\": \"user\",\n        \"methods\": {},\n        \"notice\": \"Description for users.\",\n        \"version\": 1\n      }\n    },\n    \"input.sol:D\": {\n      \"userdoc\": {\n        \"kind\": \"user\",\n        \"methods\": {},\n        \"version\": 1\n      }\n    }\n  },\n  \"version\": \"<VERSION REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/constant_optimizer_yul/args",
    "content": "--optimize --ir-optimized --optimize-runs 1000000\n"
  },
  {
    "path": "test/cmdlineTests/constant_optimizer_yul/err",
    "content": "\n"
  },
  {
    "path": "test/cmdlineTests/constant_optimizer_yul/input.sol",
    "content": "// SPDX-License-Identifier: GPL-v3\npragma solidity >= 0.0.0;\ncontract C {\n    constructor () {\n        assembly {\n            // This shl should not be evaluated for all values of optimize-runs\n            sstore(0, shl(180, 1))\n        }\n    }\n    fallback() external {\n        assembly {\n            // This shl would be evaluated for high values of optimize-runs\n            sstore(0, shl(180, 1))\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/constant_optimizer_yul/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_12\" {\n    code {\n        {\n            /// @src 0:61:418  \"contract C {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            /// @src 0:103:238  \"assembly {...\"\n            sstore(0, shl(180, 1))\n            /// @src 0:61:418  \"contract C {...\"\n            let _2 := datasize(\"C_12_deployed\")\n            codecopy(_1, dataoffset(\"C_12_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_12_deployed\" {\n        code {\n            {\n                /// @src 0:61:418  \"contract C {...\"\n                if callvalue() { revert(0, 0) }\n                /// @src 0:279:410  \"assembly {...\"\n                sstore(0, 0x1000000000000000000000000000000000000000000000)\n                /// @src 0:61:418  \"contract C {...\"\n                stop()\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/args",
    "content": "--ir --ir-optimized --asm --optimize --debug-info all\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/input.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":60:101  contract C {... */\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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        /* \"input.sol\":60:101  contract C {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \"input.sol\":77:99  function f() public {} */\n    tag_3:\n      stop\n\n    auxdata: <AUXDATA REMOVED>\n}\n\nIR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_6\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_6()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))\n\n        return(_1, datasize(\"C_6_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:60:101  \"contract C {...\"\n        function constructor_C_6() {\n\n            /// @src 0:60:101  \"contract C {...\"\n\n        }\n        /// @src 0:60:101  \"contract C {...\"\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_6_deployed\" {\n        code {\n            /// @src 0:60:101  \"contract C {...\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_5()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_5() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                fun_f_5()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            /// @ast-id 5\n            /// @src 0:77:99  \"function f() public {}\"\n            function fun_f_5() {\n\n            }\n            /// @src 0:60:101  \"contract C {...\"\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n\n\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_6\" {\n    code {\n        {\n            /// @src 0:60:101  \"contract C {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_6_deployed\")\n            codecopy(_1, dataoffset(\"C_6_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_6_deployed\" {\n        code {\n            {\n                /// @src 0:60:101  \"contract C {...\"\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        return(0, 0)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all_and_none/args",
    "content": "--ir --ir-optimized --asm --optimize --debug-info location,all,none\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all_and_none/err",
    "content": "Error: Invalid value for --debug-info option: location,all,none\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all_and_none/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_all_and_none/input.sol",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/args",
    "content": "--ir --ir-optimized --asm --optimize --debug-info location\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/input.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_location_only/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":60:101 */\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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        /* \"input.sol\":60:101 */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \"input.sol\":77:99 */\n    tag_3:\n      stop\n\n    auxdata: <AUXDATA REMOVED>\n}\n\nIR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_6\" {\n    code {\n        /// @src 0:60:101\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_6()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))\n\n        return(_1, datasize(\"C_6_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:60:101\n        function constructor_C_6() {\n\n            /// @src 0:60:101\n\n        }\n        /// @src 0:60:101\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_6_deployed\" {\n        code {\n            /// @src 0:60:101\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_5()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_5() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                fun_f_5()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            /// @src 0:77:99\n            function fun_f_5() {\n\n            }\n            /// @src 0:60:101\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n\n\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_6\" {\n    code {\n        {\n            /// @src 0:60:101\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_6_deployed\")\n            codecopy(_1, dataoffset(\"C_6_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_6_deployed\" {\n        code {\n            {\n                /// @src 0:60:101\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        return(0, 0)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/args",
    "content": "--ir --ir-optimized --asm --optimize --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/input.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_none/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n    tag_3:\n      stop\n\n    auxdata: <AUXDATA REMOVED>\n}\n\nIR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_6\" {\n    code {\n\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_6()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))\n\n        return(_1, datasize(\"C_6_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function constructor_C_6() {\n\n        }\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_6_deployed\" {\n        code {\n\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_5()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_5() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                fun_f_5()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function fun_f_5() {\n\n            }\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n\n\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_6\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_6_deployed\")\n            codecopy(_1, dataoffset(\"C_6_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_6_deployed\" {\n        code {\n            {\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        return(0, 0)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_snippet_only/args",
    "content": "--ir --ir-optimized --asm --optimize --debug-info snippet\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_snippet_only/err",
    "content": "Error: To use 'snippet' with --debug-info you must select also 'location'.\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_snippet_only/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_and_evm_asm_print_snippet_only/input.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_snippet_escaping/args",
    "content": "--ir-optimized --ir --optimize\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_snippet_escaping/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\n// Intentionally badly wrapped and commented in weird places to get source locations inside code\n// snippets in generated Yul. Also contains stuff that could break the assembly if not escaped properly.\n\ncontract C {} contract D /** @src 0:96:165  \"contract D {...\" */ {\n    function f() /* @use-src 0:\"input.sol\", 1:\"#utility.yul\" @ast-id 15 */ public returns (string memory) { C c = new /// @src 0:149:156  \"new C()\"\n        C(); c;\n        string memory s = \"/*\"; s; return \"/** @src 0:96:165  \\\"contract D {...\\\" */\"\n        ;\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/debug_info_in_yul_snippet_escaping/output",
    "content": "IR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_2\" {\n    code {\n        /// @src 0:265:278  \"contract C {}\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_2()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_2_deployed\"), datasize(\"C_2_deployed\"))\n\n        return(_1, datasize(\"C_2_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:265:278  \"contract C {}\"\n        function constructor_C_2() {\n\n            /// @src 0:265:278  \"contract C {}\"\n\n        }\n        /// @src 0:265:278  \"contract C {}\"\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_2_deployed\" {\n        code {\n            /// @src 0:265:278  \"contract C {}\"\n            mstore(64, memoryguard(128))\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n\n\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_2\" {\n    code {\n        {\n            /// @src 0:265:278  \"contract C {}\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_2_deployed\")\n            codecopy(_1, dataoffset(\"C_2_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_2_deployed\" {\n        code {\n            {\n                /// @src 0:265:278  \"contract C {}\"\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n\nIR:\n\n/// @use-src 0:\"input.sol\"\nobject \"D_27\" {\n    code {\n        /// @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_D_27()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"D_27_deployed\"), datasize(\"D_27_deployed\"))\n\n        return(_1, datasize(\"D_27_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\"\n        function constructor_D_27() {\n\n            /// @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\"\n\n        }\n        /// @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\"\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"D_27_deployed\" {\n        code {\n            /// @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_26()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function array_length_t_string_memory_ptr(value) -> length {\n\n                length := mload(value)\n\n            }\n\n            function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos {\n                mstore(pos, length)\n                updated_pos := add(pos, 0x20)\n            }\n\n            function copy_memory_to_memory_with_cleanup(src, dst, length) {\n\n                mcopy(dst, src, length)\n                mstore(add(dst, length), 0)\n\n            }\n\n            function round_up_to_mul_of_32(value) -> result {\n                result := and(add(value, 31), not(31))\n            }\n\n            function abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value, pos) -> end {\n                let length := array_length_t_string_memory_ptr(value)\n                pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length)\n                copy_memory_to_memory_with_cleanup(add(value, 0x20), pos, length)\n                end := add(pos, round_up_to_mul_of_32(length))\n            }\n\n            function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 32)\n\n                mstore(add(headStart, 0), sub(tail, headStart))\n                tail := abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value0,  tail)\n\n            }\n\n            function external_fun_f_26() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  fun_f_26()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function zero_value_for_split_t_string_memory_ptr() -> ret {\n                ret := 96\n            }\n\n            function panic_error_0x41() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x41)\n                revert(0, 0x24)\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function revert_forward_1() {\n                let pos := allocate_unbounded()\n                returndatacopy(pos, 0, returndatasize())\n                revert(pos, returndatasize())\n            }\n\n            function finalize_allocation(memPtr, size) {\n                let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n                // protect against overflow\n                if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n                mstore(64, newFreePtr)\n            }\n\n            function allocate_memory(size) -> memPtr {\n                memPtr := allocate_unbounded()\n                finalize_allocation(memPtr, size)\n            }\n\n            function array_allocation_size_t_string_memory_ptr(length) -> size {\n                // Make sure we can allocate memory without overflow\n                if gt(length, 0xffffffffffffffff) { panic_error_0x41() }\n\n                size := round_up_to_mul_of_32(length)\n\n                // add length slot\n                size := add(size, 0x20)\n\n            }\n\n            function allocate_memory_array_t_string_memory_ptr(length) -> memPtr {\n                let allocSize := array_allocation_size_t_string_memory_ptr(length)\n                memPtr := allocate_memory(allocSize)\n\n                mstore(memPtr, length)\n\n            }\n\n            function store_literal_in_memory_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50(memPtr) {\n\n                mstore(add(memPtr, 0), \"/*\")\n\n            }\n\n            function copy_literal_to_memory_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50() -> memPtr {\n                memPtr := allocate_memory_array_t_string_memory_ptr(2)\n                store_literal_in_memory_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50(add(memPtr, 32))\n            }\n\n            function convert_t_stringliteral_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50_to_t_string_memory_ptr() -> converted {\n                converted := copy_literal_to_memory_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50()\n            }\n\n            function store_literal_in_memory_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b(memPtr) {\n\n                mstore(add(memPtr, 0), 0x2f2a2a204073726320303a39363a313635202022636f6e74726163742044207b)\n\n                mstore(add(memPtr, 32), 0x2e2e2e22202a2f00000000000000000000000000000000000000000000000000)\n\n            }\n\n            function copy_literal_to_memory_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b() -> memPtr {\n                memPtr := allocate_memory_array_t_string_memory_ptr(39)\n                store_literal_in_memory_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b(add(memPtr, 32))\n            }\n\n            function convert_t_stringliteral_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b_to_t_string_memory_ptr() -> converted {\n                converted := copy_literal_to_memory_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b()\n            }\n\n            /// @ast-id 26\n            /// @src 0:336:597  \"function f() /* @use-src 0:\\\"input.sol\\\", 1:\\\"#utility.yul\\\" @ast-id 15 *\\/ public returns (string memory) { C c = new /// @src 0:149:156  \\\"new C()\\\"...\"\n            function fun_f_26() -> var__5_mpos {\n                /// @src 0:423:436  \"string memory\"\n                let zero_t_string_memory_ptr_1_mpos := zero_value_for_split_t_string_memory_ptr()\n                var__5_mpos := zero_t_string_memory_ptr_1_mpos\n\n                /// @src 0:446:491  \"new /// @src 0:149:156  \\\"new C()\\\"...\"\n\n                let _2 := allocate_unbounded()\n                let _3 := add(_2, datasize(\"C_2\"))\n                if or(gt(_3, 0xffffffffffffffff), lt(_3, _2)) { panic_error_0x41() }\n                datacopy(_2, dataoffset(\"C_2\"), datasize(\"C_2\"))\n                _3 := abi_encode_tuple__to__fromStack(_3)\n\n                let expr_13_address := create(0, _2, sub(_3, _2))\n\n                if iszero(expr_13_address) { revert_forward_1() }\n\n                /// @src 0:440:491  \"C c = new /// @src 0:149:156  \\\"new C()\\\"...\"\n                let var_c_9_address := expr_13_address\n                /// @src 0:493:494  \"c\"\n                let _4_address := var_c_9_address\n                let expr_15_address := _4_address\n                /// @src 0:504:526  \"string memory s = \\\"/*\\\"\"\n                let var_s_18_mpos := convert_t_stringliteral_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50_to_t_string_memory_ptr()\n                /// @src 0:528:529  \"s\"\n                let _5_mpos := var_s_18_mpos\n                let expr_21_mpos := _5_mpos\n                /// @src 0:531:581  \"return \\\"/** @src 0:96:165  \\\\\\\"contract D {...\\\\\\\" *\\/\\\"\"\n                var__5_mpos := convert_t_stringliteral_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b_to_t_string_memory_ptr()\n                leave\n\n            }\n            /// @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\"\n\n        }\n\n        /// @use-src 0:\"input.sol\"\n        object \"C_2\" {\n            code {\n                /// @src 0:265:278  \"contract C {}\"\n                mstore(64, memoryguard(128))\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n                constructor_C_2()\n\n                let _1 := allocate_unbounded()\n                codecopy(_1, dataoffset(\"C_2_deployed\"), datasize(\"C_2_deployed\"))\n\n                return(_1, datasize(\"C_2_deployed\"))\n\n                function allocate_unbounded() -> memPtr {\n                    memPtr := mload(64)\n                }\n\n                function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                    revert(0, 0)\n                }\n\n                /// @src 0:265:278  \"contract C {}\"\n                function constructor_C_2() {\n\n                    /// @src 0:265:278  \"contract C {}\"\n\n                }\n                /// @src 0:265:278  \"contract C {}\"\n\n            }\n            /// @use-src 0:\"input.sol\"\n            object \"C_2_deployed\" {\n                code {\n                    /// @src 0:265:278  \"contract C {}\"\n                    mstore(64, memoryguard(128))\n\n                    revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n                    function shift_right_224_unsigned(value) -> newValue {\n                        newValue :=\n\n                        shr(224, value)\n\n                    }\n\n                    function allocate_unbounded() -> memPtr {\n                        memPtr := mload(64)\n                    }\n\n                    function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                        revert(0, 0)\n                    }\n\n                }\n\n                data \".metadata\" hex\"<BYTECODE REMOVED>\"\n            }\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n\n\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"D_27\" {\n    code {\n        {\n            /// @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"D_27_deployed\")\n            codecopy(_1, dataoffset(\"D_27_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"D_27_deployed\" {\n        code {\n            {\n                /// @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\"\n                let _1 := memoryguard(0x80)\n                mstore(64, _1)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        /// @src 0:446:491  \"new /// @src 0:149:156  \\\"new C()\\\"...\"\n                        let _2 := datasize(\"C_2\")\n                        let _3 := add(_1, _2)\n                        if or(gt(_3, 0xffffffffffffffff), lt(_3, _1))\n                        {\n                            /// @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\"\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 0x24)\n                        }\n                        /// @src 0:446:491  \"new /// @src 0:149:156  \\\"new C()\\\"...\"\n                        datacopy(_1, dataoffset(\"C_2\"), _2)\n                        if iszero(create(/** @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\" */ 0, /** @src 0:446:491  \"new /// @src 0:149:156  \\\"new C()\\\"...\" */ _1, sub(_3, _1)))\n                        {\n                            /// @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\"\n                            let pos := mload(64)\n                            returndatacopy(pos, 0, returndatasize())\n                            revert(pos, returndatasize())\n                        }\n                        let memPtr := 0\n                        let size := 0\n                        size := 0\n                        let memPtr_1 := mload(64)\n                        let newFreePtr := add(memPtr_1, 64)\n                        if or(gt(newFreePtr, /** @src 0:446:491  \"new /// @src 0:149:156  \\\"new C()\\\"...\" */ 0xffffffffffffffff), /** @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\" */ lt(newFreePtr, memPtr_1))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 0x24)\n                        }\n                        mstore(64, newFreePtr)\n                        memPtr := memPtr_1\n                        mstore(memPtr_1, 2)\n                        mstore(add(memPtr_1, 32), \"/*\")\n                        let memPtr_2 := 0\n                        let size_1 := 0\n                        size_1 := 0\n                        let memPtr_3 := mload(64)\n                        let newFreePtr_1 := add(memPtr_3, 96)\n                        if or(gt(newFreePtr_1, /** @src 0:446:491  \"new /// @src 0:149:156  \\\"new C()\\\"...\" */ 0xffffffffffffffff), /** @src 0:279:599  \"contract D /** @src 0:96:165  \\\"contract D {...\\\" *\\/ {...\" */ lt(newFreePtr_1, memPtr_3))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 0x24)\n                        }\n                        mstore(64, newFreePtr_1)\n                        memPtr_2 := memPtr_3\n                        mstore(memPtr_3, 39)\n                        let _4 := add(memPtr_3, 32)\n                        mstore(_4, 0x2f2a2a204073726320303a39363a313635202022636f6e74726163742044207b)\n                        mstore(add(memPtr_3, 64), shl(200, 0x2e2e2e22202a2f))\n                        let memPos := mload(64)\n                        mstore(memPos, 32)\n                        let length := mload(memPtr_3)\n                        mstore(add(memPos, 32), length)\n                        mcopy(add(memPos, 64), _4, length)\n                        mstore(add(add(memPos, length), 64), 0)\n                        return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), 64))\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        /// @use-src 0:\"input.sol\"\n        object \"C_2\" {\n            code {\n                {\n                    /// @src 0:265:278  \"contract C {}\"\n                    let _1 := memoryguard(0x80)\n                    mstore(64, _1)\n                    if callvalue() { revert(0, 0) }\n                    let _2 := datasize(\"C_2_deployed\")\n                    codecopy(_1, dataoffset(\"C_2_deployed\"), _2)\n                    return(_1, _2)\n                }\n            }\n            /// @use-src 0:\"input.sol\"\n            object \"C_2_deployed\" {\n                code {\n                    {\n                        /// @src 0:265:278  \"contract C {}\"\n                        revert(0, 0)\n                    }\n                }\n                data \".metadata\" hex\"<BYTECODE REMOVED>\"\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/dup_opt_peephole/args",
    "content": "--asm"
  },
  {
    "path": "test/cmdlineTests/dup_opt_peephole/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n\tfallback() external {\n\t\tassembly {\n\t\t\tlet x := calldataload(0)\n\t\t\tx := x\n\t\t\tsstore(0, x)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/dup_opt_peephole/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":60:171  contract C {... */\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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        /* \"input.sol\":60:171  contract C {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_3\n      jumpi\n      revert(0x00, 0x00)\n    tag_3:\n      pop\n        /* \"input.sol\":134:135  0 */\n      0x00\n        /* \"input.sol\":121:136  calldataload(0) */\n      calldataload\n        /* \"input.sol\":160:161  x */\n      dup1\n        /* \"input.sol\":157:158  0 */\n      0x00\n        /* \"input.sol\":150:162  sstore(0, x) */\n      sstore\n        /* \"input.sol\":107:166  {... */\n      stop\n\n    auxdata: <AUXDATA REMOVED>\n}\n"
  },
  {
    "path": "test/cmdlineTests/eof_unavailable_before_osaka/args",
    "content": "--experimental --optimize --experimental-eof-version 1 --evm-version cancun\n"
  },
  {
    "path": "test/cmdlineTests/eof_unavailable_before_osaka/err",
    "content": "Error: EOF is not supported by EVM versions earlier than osaka.\n"
  },
  {
    "path": "test/cmdlineTests/eof_unavailable_before_osaka/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/eof_unavailable_before_osaka/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/error_codes/args",
    "content": "--error-codes\n"
  },
  {
    "path": "test/cmdlineTests/error_codes/err",
    "content": "Warning (1878): SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n--> input.sol\n\nError (4937): No visibility specified. Did you intend to add \"public\"?\n --> input.sol:2:5:\n  |\n2 |     function f() {\n  |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (3420): Source file does not specify required compiler version!\n--> input.sol\n\nError (4247): Expression has to be an lvalue.\n --> input.sol:3:9:\n  |\n3 |         2=0;\n  |         ^\n\nError (7407): Type int_const 0 is not implicitly convertible to expected type int_const 2.\n --> input.sol:3:11:\n  |\n3 |         2=0;\n  |           ^\n\nError (2614): Indexed expression has to be a type, mapping or array (is literal_string \"\")\n --> input.sol:4:9:\n  |\n4 |         \"\"[2];\n  |         ^^\n"
  },
  {
    "path": "test/cmdlineTests/error_codes/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/error_codes/input.sol",
    "content": "contract C {\n    function f() {\n        2=0;\n        \"\"[2];\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_debuginfo_without_experimental_flag/args",
    "content": "--debug-info ethdebug\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_debuginfo_without_experimental_flag/err",
    "content": "Error: Ethdebug annotations are experimental and can only be included in --debug-info in experimental mode. To enable experimental mode, use the --experimental flag.\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_debuginfo_without_experimental_flag/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_debuginfo_without_experimental_flag/input.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_eof_container_osaka/args",
    "content": "--experimental --experimental-eof-version 1 --evm-version osaka --ethdebug --via-ir --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_eof_container_osaka/input.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_eof_container_osaka/output",
    "content": "======= Debug Data (ethdebug/format/info/resources) =======\n{\n    \"compilation\": {\n        \"compiler\": {\n            \"name\": \"solc\",\n            \"version\": \"<VERSION REMOVED>\"\n        },\n        \"sources\": [\n            {\n                \"id\": 0,\n                \"path\": \"input.sol\"\n            }\n        ]\n    }\n}\n\n======= input.sol:C =======\nDebug Data (ethdebug/format/program):\n{\n    \"contract\": {\n        \"definition\": {\n            \"source\": {\n                \"id\": 0\n            }\n        },\n        \"name\": \"C\"\n    },\n    \"environment\": \"create\",\n    \"instructions\": [\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 30,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x80\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 32,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x40\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 34,\n            \"operation\": {\n                \"mnemonic\": \"MSTORE\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 35,\n            \"operation\": {\n                \"mnemonic\": \"CALLVALUE\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 36,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x0005\"\n                ],\n                \"mnemonic\": \"RJUMPI\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 39,\n            \"operation\": {\n                \"mnemonic\": \"PUSH0\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 40,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x80\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 42,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x00\"\n                ],\n                \"mnemonic\": \"RETURNCONTRACT\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 44,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x0001\"\n                ],\n                \"mnemonic\": \"JUMPF\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 47,\n            \"operation\": {\n                \"mnemonic\": \"PUSH0\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 48,\n            \"operation\": {\n                \"mnemonic\": \"DUP1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 41,\n                        \"offset\": 60\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 49,\n            \"operation\": {\n                \"mnemonic\": \"REVERT\"\n            }\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_on_abstract/args",
    "content": "--experimental --ethdebug --via-ir --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_on_abstract/input.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\nabstract contract C {\n    function f() public virtual returns (bytes32);\n}\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_on_abstract/output",
    "content": "======= Debug Data (ethdebug/format/info/resources) =======\n{\n    \"compilation\": {\n        \"compiler\": {\n            \"name\": \"solc\",\n            \"version\": \"<VERSION REMOVED>\"\n        },\n        \"sources\": [\n            {\n                \"id\": 0,\n                \"path\": \"input.sol\"\n            }\n        ]\n    }\n}\n\n======= input.sol:C =======\nDebug Data (ethdebug/format/program):\nnull\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_on_interface/args",
    "content": "--experimental --ethdebug --via-ir --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_on_interface/input.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ninterface C {\n    function f() external;\n}\n"
  },
  {
    "path": "test/cmdlineTests/ethdebug_on_interface/output",
    "content": "======= Debug Data (ethdebug/format/info/resources) =======\n{\n    \"compilation\": {\n        \"compiler\": {\n            \"name\": \"solc\",\n            \"version\": \"<VERSION REMOVED>\"\n        },\n        \"sources\": [\n            {\n                \"id\": 0,\n                \"path\": \"input.sol\"\n            }\n        ]\n    }\n}\n\n======= input.sol:C =======\nDebug Data (ethdebug/format/program):\nnull\n"
  },
  {
    "path": "test/cmdlineTests/events_in_abi/args",
    "content": "--abi --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/events_in_abi/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\nlibrary L {\n    event e1(uint b);\n}\n\nfunction f() {\n    emit L.e1(5);\n}\n\ncontract C {\n    event e1(uint indexed a);\n    function g() public {\n        f();\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/events_in_abi/output",
    "content": "\n======= input.sol:C =======\nContract JSON ABI\n[\n    {\n        \"anonymous\": false,\n        \"inputs\": [\n            {\n                \"indexed\": false,\n                \"internalType\": \"uint256\",\n                \"name\": \"b\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"e1\",\n        \"type\": \"event\"\n    },\n    {\n        \"anonymous\": false,\n        \"inputs\": [\n            {\n                \"indexed\": true,\n                \"internalType\": \"uint256\",\n                \"name\": \"a\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"e1\",\n        \"type\": \"event\"\n    },\n    {\n        \"inputs\": [],\n        \"name\": \"g\",\n        \"outputs\": [],\n        \"stateMutability\": \"nonpayable\",\n        \"type\": \"function\"\n    }\n]\n\n======= input.sol:L =======\nContract JSON ABI\n[\n    {\n        \"anonymous\": false,\n        \"inputs\": [\n            {\n                \"indexed\": false,\n                \"internalType\": \"uint256\",\n                \"name\": \"b\",\n                \"type\": \"uint256\"\n            }\n        ],\n        \"name\": \"e1\",\n        \"type\": \"event\"\n    }\n]\n"
  },
  {
    "path": "test/cmdlineTests/evm_version_byzantium/args",
    "content": "--evm-version byzantium\n"
  },
  {
    "path": "test/cmdlineTests/evm_version_byzantium/err",
    "content": "Warning: Support for EVM versions older than constantinople is deprecated and will be removed in the future.\nWarning: Source file does not specify required compiler version!\n--> input.sol\n"
  },
  {
    "path": "test/cmdlineTests/evm_version_byzantium/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\n"
  },
  {
    "path": "test/cmdlineTests/evm_version_constantinople/args",
    "content": "--evm-version constantinople\n"
  },
  {
    "path": "test/cmdlineTests/evm_version_constantinople/err",
    "content": "Warning: Source file does not specify required compiler version!\n--> input.sol\n"
  },
  {
    "path": "test/cmdlineTests/evm_version_constantinople/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_difficulty_post_paris/args",
    "content": "--no-cbor-metadata --via-ir --optimize --opcodes --asm --debug-info none --evm-version paris\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_difficulty_post_paris/err",
    "content": "Warning: Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n --> input.sol:6:21:\n  |\n6 |         uint256 x = block.difficulty;\n  |                     ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_difficulty_post_paris/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    constructor() payable {\n        uint256 x = block.difficulty;\n        assembly {\n            sstore(0, x)\n            stop()\n        }\n    }\n\n    fallback() external payable {\n        assembly {\n            stop()\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_difficulty_post_paris/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n  sstore(0x00, prevrandao)\n  stop\nstop\n\nsub_0: assembly {\n      stop\n}\n\nOpcodes:\nPREVRANDAO PUSH1 0x0 SSTORE STOP INVALID \n"
  },
  {
    "path": "test/cmdlineTests/evmasm_difficulty_pre_paris/args",
    "content": "--no-cbor-metadata --via-ir --optimize --opcodes --asm --debug-info none --evm-version london\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_difficulty_pre_paris/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    constructor() payable {\n        uint256 x = block.difficulty;\n        assembly {\n            sstore(0, x)\n            stop()\n        }\n    }\n\n    fallback() external payable {\n        assembly {\n            stop()\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_difficulty_pre_paris/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n  sstore(0x00, difficulty)\n  stop\nstop\n\nsub_0: assembly {\n      stop\n}\n\nOpcodes:\nDIFFICULTY PUSH1 0x0 SSTORE STOP INVALID \n"
  },
  {
    "path": "test/cmdlineTests/evmasm_prevrandao_post_paris/args",
    "content": "--no-cbor-metadata --via-ir --optimize --opcodes --asm --debug-info none --evm-version paris\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_prevrandao_post_paris/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    constructor() payable {\n        uint256 x = block.prevrandao;\n        assembly {\n            sstore(0, x)\n            stop()\n        }\n    }\n\n    fallback() external payable {\n        assembly {\n            stop()\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_prevrandao_post_paris/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n  sstore(0x00, prevrandao)\n  stop\nstop\n\nsub_0: assembly {\n      stop\n}\n\nOpcodes:\nPREVRANDAO PUSH1 0x0 SSTORE STOP INVALID \n"
  },
  {
    "path": "test/cmdlineTests/evmasm_prevrandao_pre_paris/args",
    "content": "--no-cbor-metadata --via-ir --optimize --opcodes --asm --debug-info none --evm-version london\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_prevrandao_pre_paris/err",
    "content": "Warning: \"prevrandao\" is not supported by the VM version and will be treated as \"difficulty\".\n --> input.sol:6:21:\n  |\n6 |         uint256 x = block.prevrandao;\n  |                     ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_prevrandao_pre_paris/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    constructor() payable {\n        uint256 x = block.prevrandao;\n        assembly {\n            sstore(0, x)\n            stop()\n        }\n    }\n\n    fallback() external payable {\n        assembly {\n            stop()\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_prevrandao_pre_paris/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n  sstore(0x00, difficulty)\n  stop\nstop\n\nsub_0: assembly {\n      stop\n}\n\nOpcodes:\nDIFFICULTY PUSH1 0x0 SSTORE STOP INVALID \n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_inline_assembly/args",
    "content": "--no-cbor-metadata --optimize --opcodes --asm --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_inline_assembly/err",
    "content": "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.\n --> input.sol:7:13:\n  |\n7 |             tstore(0, 123)\n  |             ^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_inline_assembly/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    fallback() external {\n        assembly {\n            tstore(0, 123)\n            sstore(0, tload(0))\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_inline_assembly/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_3\n      jumpi\n      revert(0x00, 0x00)\n    tag_3:\n      pop\n      0x7b\n      0x00\n      tstore\n      0x00\n      tload\n      0x00\n      sstore\n      stop\n}\n\nOpcodes:\nPUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xE JUMPI PUSH0 PUSH0 REVERT JUMPDEST POP PUSH1 0x19 DUP1 PUSH1 0x1A PUSH0 CODECOPY PUSH0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xE JUMPI PUSH0 PUSH0 REVERT JUMPDEST POP PUSH1 0x7B PUSH0 TSTORE PUSH0 TLOAD PUSH0 SSTORE STOP \n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/args",
    "content": "--no-cbor-metadata --via-ir --optimize --opcodes --asm --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/err",
    "content": "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.\n --> input.sol:7:13:\n  |\n7 |             tstore(0, 123)\n  |             ^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    fallback() external {\n        assembly {\n            tstore(0, 123)\n            sstore(0, tload(0))\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_inline_assembly_via_ir/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n  0x80\n  dup1\n  0x40\n  mstore\n  jumpi(tag_1, callvalue)\n  dataSize(sub_0)\n  swap1\n  dup2\n  dataOffset(sub_0)\n  dup3\n  codecopy\n  return\ntag_1:\n  0x00\n  dup1\n  revert\nstop\n\nsub_0: assembly {\n      jumpi(tag_1, callvalue)\n      tstore(0x00, 0x7b)\n      sstore(0x00, tload(0x00))\n      stop\n    tag_1:\n      0x00\n      dup1\n      revert\n}\n\nOpcodes:\nPUSH1 0x80 DUP1 PUSH1 0x40 MSTORE CALLVALUE PUSH1 0x13 JUMPI PUSH1 0x11 SWAP1 DUP2 PUSH1 0x18 DUP3 CODECOPY RETURN JUMPDEST PUSH0 DUP1 REVERT INVALID CALLVALUE PUSH1 0xD JUMPI PUSH1 0x7B PUSH0 TSTORE PUSH0 TLOAD PUSH0 SSTORE STOP JUMPDEST PUSH0 DUP1 REVERT \n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_state_variable/args",
    "content": "--no-cbor-metadata --optimize --asm --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_state_variable/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    uint transient x;\n    function f() public {\n        x = x + 1;\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_state_variable/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n    tag_3:\n      tag_4\n      tag_5\n      jump\t// in\n    tag_4:\n      stop\n    tag_5:\n      tag_7\n      tload(0x00)\n      0x01\n      tag_8\n      jump\t// in\n    tag_7:\n      dup1\n      0x00\n      tstore\n      pop\n      jump\t// out\n    tag_8:\n      dup1\n      dup3\n      add\n      dup1\n      dup3\n      gt\n      iszero\n      tag_11\n      jumpi\n      0x4e487b71\n      0xe0\n      shl\n      0x00\n      mstore\n      0x11\n      0x04\n      mstore\n      0x24\n      0x00\n      revert\n    tag_11:\n      swap3\n      swap2\n      pop\n      pop\n      jump\t// out\n}\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/args",
    "content": "--no-cbor-metadata --via-ir --optimize --asm --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    uint transient x;\n    function f() public {\n        x = x + 1;\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/evmasm_transient_storage_state_variable_via_ir/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n  0x80\n  dup1\n  0x40\n  mstore\n  jumpi(tag_1, callvalue)\n  dataSize(sub_0)\n  swap1\n  dup2\n  dataOffset(sub_0)\n  dup3\n  codecopy\n  return\ntag_1:\n  0x00\n  dup1\n  revert\nstop\n\nsub_0: assembly {\n      jumpi(tag_1, iszero(lt(calldatasize, 0x04)))\n      0x00\n      dup1\n      revert\n    tag_1:\n      jumpi(tag_3, eq(0x26121ff0, shr(0xe0, calldataload(0x00))))\n      0x00\n      dup1\n      revert\n    tag_3:\n      jumpi(tag_7, callvalue)\n      jumpi(tag_7, slt(add(not(0x03), calldatasize), 0x00))\n      tload(0x00)\n      0x01\n      dup2\n      add\n      dup1\n      swap2\n      gt\n      tag_9\n      jumpi\n      0x00\n      tstore\n      stop\n    tag_9:\n      mstore(0x00, shl(0xe0, 0x4e487b71))\n      mstore(0x04, 0x11)\n      revert(0x00, 0x24)\n    tag_7:\n      0x00\n      dup1\n      revert\n}\n"
  },
  {
    "path": "test/cmdlineTests/exp_base_literal/args",
    "content": "--ir\n"
  },
  {
    "path": "test/cmdlineTests/exp_base_literal/err",
    "content": "\n"
  },
  {
    "path": "test/cmdlineTests/exp_base_literal/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity > 0.7.1;\npragma abicoder v2;\n\ncontract C {\n\tfunction f(uint a, uint b, uint c, uint d) public pure returns (uint, int, uint, uint) {\n\t\tuint w = 2**a;\n\t\tint x = (-2)**b;\n\t\tuint y = 10**c;\n\t\tuint z = (2**256 -1 )**d;\n\n\t\t// Special cases: 0, 1, and -1\n\t\tw = (0)**a;\n\t\tx = (-1)**b;\n\t\ty = 1**c;\n\n\t\treturn (w, x, y, z);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/exp_base_literal/output",
    "content": "IR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_81\" {\n    code {\n        /// @src 0:82:370  \"contract C {...\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_81()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_81_deployed\"), datasize(\"C_81_deployed\"))\n\n        return(_1, datasize(\"C_81_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:82:370  \"contract C {...\"\n        function constructor_C_81() {\n\n            /// @src 0:82:370  \"contract C {...\"\n\n        }\n        /// @src 0:82:370  \"contract C {...\"\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_81_deployed\" {\n        code {\n            /// @src 0:82:370  \"contract C {...\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x70cb9605\n                {\n                    // f(uint256,uint256,uint256,uint256)\n\n                    external_fun_f_80()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256t_uint256t_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2, value3 {\n                if slt(sub(dataEnd, headStart), 128) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n                {\n\n                    let offset := 32\n\n                    value1 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n                {\n\n                    let offset := 64\n\n                    value2 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n                {\n\n                    let offset := 96\n\n                    value3 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_t_uint256_to_t_uint256_fromStack(value, pos) {\n                mstore(pos, cleanup_t_uint256(value))\n            }\n\n            function cleanup_t_int256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function abi_encode_t_int256_to_t_int256_fromStack(value, pos) {\n                mstore(pos, cleanup_t_int256(value))\n            }\n\n            function abi_encode_tuple_t_uint256_t_int256_t_uint256_t_uint256__to_t_uint256_t_int256_t_uint256_t_uint256__fromStack(headStart , value0, value1, value2, value3) -> tail {\n                tail := add(headStart, 128)\n\n                abi_encode_t_uint256_to_t_uint256_fromStack(value0,  add(headStart, 0))\n\n                abi_encode_t_int256_to_t_int256_fromStack(value1,  add(headStart, 32))\n\n                abi_encode_t_uint256_to_t_uint256_fromStack(value2,  add(headStart, 64))\n\n                abi_encode_t_uint256_to_t_uint256_fromStack(value3,  add(headStart, 96))\n\n            }\n\n            function external_fun_f_80() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0, param_1, param_2, param_3 :=  abi_decode_tuple_t_uint256t_uint256t_uint256t_uint256(4, calldatasize())\n                let ret_0, ret_1, ret_2, ret_3 :=  fun_f_80(param_0, param_1, param_2, param_3)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_uint256_t_int256_t_uint256_t_uint256__to_t_uint256_t_int256_t_uint256_t_uint256__fromStack(memPos , ret_0, ret_1, ret_2, ret_3)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function zero_value_for_split_t_uint256() -> ret {\n                ret := 0\n            }\n\n            function zero_value_for_split_t_int256() -> ret {\n                ret := 0\n            }\n\n            function cleanup_t_rational_2_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_2_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_2_by_1(value)))\n            }\n\n            function panic_error_0x11() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x11)\n                revert(0, 0x24)\n            }\n\n            function checked_exp_t_rational_2_by_1_t_uint256(exponent) -> power {\n                exponent := cleanup_t_uint256(exponent)\n\n                if gt(exponent, 255) { panic_error_0x11() }\n\n                power := exp(2, exponent)\n            }\n\n            function cleanup_t_rational_minus_2_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function convert_t_rational_minus_2_by_1_to_t_int256(value) -> converted {\n                converted := cleanup_t_int256(identity(cleanup_t_rational_minus_2_by_1(value)))\n            }\n\n            function checked_exp_t_rational_minus_2_by_1_t_uint256(exponent) -> power {\n                exponent := cleanup_t_uint256(exponent)\n\n                if gt(exponent, 255) { panic_error_0x11() }\n\n                power := exp(115792089237316195423570985008687907853269984665640564039457584007913129639934, exponent)\n            }\n\n            function cleanup_t_rational_10_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function convert_t_rational_10_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_10_by_1(value)))\n            }\n\n            function checked_exp_t_rational_10_by_1_t_uint256(exponent) -> power {\n                exponent := cleanup_t_uint256(exponent)\n\n                if gt(exponent, 77) { panic_error_0x11() }\n\n                power := exp(10, exponent)\n            }\n\n            function cleanup_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function convert_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1(value)))\n            }\n\n            function checked_exp_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1_t_uint256(exponent) -> power {\n                exponent := cleanup_t_uint256(exponent)\n\n                if gt(exponent, 1) { panic_error_0x11() }\n\n                power := exp(115792089237316195423570985008687907853269984665640564039457584007913129639935, exponent)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function checked_exp_t_rational_0_by_1_t_uint256(exponent) -> power {\n                exponent := cleanup_t_uint256(exponent)\n\n                power := exp(0, exponent)\n            }\n\n            function cleanup_t_rational_minus_1_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function convert_t_rational_minus_1_by_1_to_t_int256(value) -> converted {\n                converted := cleanup_t_int256(identity(cleanup_t_rational_minus_1_by_1(value)))\n            }\n\n            function checked_exp_t_rational_minus_1_by_1_t_uint256(exponent) -> power {\n                exponent := cleanup_t_uint256(exponent)\n\n                power := exp(115792089237316195423570985008687907853269984665640564039457584007913129639935, exponent)\n            }\n\n            function cleanup_t_rational_1_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function convert_t_rational_1_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_1_by_1(value)))\n            }\n\n            function checked_exp_t_rational_1_by_1_t_uint256(exponent) -> power {\n                exponent := cleanup_t_uint256(exponent)\n\n                power := exp(1, exponent)\n            }\n\n            /// @ast-id 80\n            /// @src 0:96:368  \"function f(uint a, uint b, uint c, uint d) public pure returns (uint, int, uint, uint) {...\"\n            function fun_f_80(var_a_4, var_b_6, var_c_8, var_d_10) -> var__13, var__15, var__17, var__19 {\n                /// @src 0:160:164  \"uint\"\n                let zero_t_uint256_1 := zero_value_for_split_t_uint256()\n                var__13 := zero_t_uint256_1\n                /// @src 0:166:169  \"int\"\n                let zero_t_int256_2 := zero_value_for_split_t_int256()\n                var__15 := zero_t_int256_2\n                /// @src 0:171:175  \"uint\"\n                let zero_t_uint256_3 := zero_value_for_split_t_uint256()\n                var__17 := zero_t_uint256_3\n                /// @src 0:177:181  \"uint\"\n                let zero_t_uint256_4 := zero_value_for_split_t_uint256()\n                var__19 := zero_t_uint256_4\n\n                /// @src 0:196:197  \"2\"\n                let expr_23 := 0x02\n                /// @src 0:199:200  \"a\"\n                let _5 := var_a_4\n                let expr_24 := _5\n                /// @src 0:196:200  \"2**a\"\n                let _6 := convert_t_rational_2_by_1_to_t_uint256(expr_23)\n                let expr_25 := checked_exp_t_rational_2_by_1_t_uint256(expr_24)\n                /// @src 0:187:200  \"uint w = 2**a\"\n                let var_w_22 := expr_25\n                /// @src 0:213:215  \"-2\"\n                let expr_30 := 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n                /// @src 0:212:216  \"(-2)\"\n                let expr_31 := expr_30\n                /// @src 0:218:219  \"b\"\n                let _7 := var_b_6\n                let expr_32 := _7\n                /// @src 0:212:219  \"(-2)**b\"\n                let _8 := convert_t_rational_minus_2_by_1_to_t_int256(expr_31)\n                let expr_33 := checked_exp_t_rational_minus_2_by_1_t_uint256(expr_32)\n                /// @src 0:204:219  \"int x = (-2)**b\"\n                let var_x_28 := expr_33\n                /// @src 0:232:234  \"10\"\n                let expr_37 := 0x0a\n                /// @src 0:236:237  \"c\"\n                let _9 := var_c_8\n                let expr_38 := _9\n                /// @src 0:232:237  \"10**c\"\n                let _10 := convert_t_rational_10_by_1_to_t_uint256(expr_37)\n                let expr_39 := checked_exp_t_rational_10_by_1_t_uint256(expr_38)\n                /// @src 0:223:237  \"uint y = 10**c\"\n                let var_y_36 := expr_39\n                /// @src 0:251:260  \"2**256 -1\"\n                let expr_47 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n                /// @src 0:250:262  \"(2**256 -1 )\"\n                let expr_48 := expr_47\n                /// @src 0:264:265  \"d\"\n                let _11 := var_d_10\n                let expr_49 := _11\n                /// @src 0:250:265  \"(2**256 -1 )**d\"\n                let _12 := convert_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1_to_t_uint256(expr_48)\n                let expr_50 := checked_exp_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1_t_uint256(expr_49)\n                /// @src 0:241:265  \"uint z = (2**256 -1 )**d\"\n                let var_z_42 := expr_50\n                /// @src 0:308:309  \"0\"\n                let expr_53 := 0x00\n                /// @src 0:307:310  \"(0)\"\n                let expr_54 := expr_53\n                /// @src 0:312:313  \"a\"\n                let _13 := var_a_4\n                let expr_55 := _13\n                /// @src 0:307:313  \"(0)**a\"\n                let _14 := convert_t_rational_0_by_1_to_t_uint256(expr_54)\n                let expr_56 := checked_exp_t_rational_0_by_1_t_uint256(expr_55)\n                /// @src 0:303:313  \"w = (0)**a\"\n                var_w_22 := expr_56\n                let expr_57 := expr_56\n                /// @src 0:322:324  \"-1\"\n                let expr_61 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n                /// @src 0:321:325  \"(-1)\"\n                let expr_62 := expr_61\n                /// @src 0:327:328  \"b\"\n                let _15 := var_b_6\n                let expr_63 := _15\n                /// @src 0:321:328  \"(-1)**b\"\n                let _16 := convert_t_rational_minus_1_by_1_to_t_int256(expr_62)\n                let expr_64 := checked_exp_t_rational_minus_1_by_1_t_uint256(expr_63)\n                /// @src 0:317:328  \"x = (-1)**b\"\n                var_x_28 := expr_64\n                let expr_65 := expr_64\n                /// @src 0:336:337  \"1\"\n                let expr_68 := 0x01\n                /// @src 0:339:340  \"c\"\n                let _17 := var_c_8\n                let expr_69 := _17\n                /// @src 0:336:340  \"1**c\"\n                let _18 := convert_t_rational_1_by_1_to_t_uint256(expr_68)\n                let expr_70 := checked_exp_t_rational_1_by_1_t_uint256(expr_69)\n                /// @src 0:332:340  \"y = 1**c\"\n                var_y_36 := expr_70\n                let expr_71 := expr_70\n                /// @src 0:353:354  \"w\"\n                let _19 := var_w_22\n                let expr_73 := _19\n                /// @src 0:352:364  \"(w, x, y, z)\"\n                let expr_77_component_1 := expr_73\n                /// @src 0:356:357  \"x\"\n                let _20 := var_x_28\n                let expr_74 := _20\n                /// @src 0:352:364  \"(w, x, y, z)\"\n                let expr_77_component_2 := expr_74\n                /// @src 0:359:360  \"y\"\n                let _21 := var_y_36\n                let expr_75 := _21\n                /// @src 0:352:364  \"(w, x, y, z)\"\n                let expr_77_component_3 := expr_75\n                /// @src 0:362:363  \"z\"\n                let _22 := var_z_42\n                let expr_76 := _22\n                /// @src 0:352:364  \"(w, x, y, z)\"\n                let expr_77_component_4 := expr_76\n                /// @src 0:345:364  \"return (w, x, y, z)\"\n                var__13 := expr_77_component_1\n                var__15 := expr_77_component_2\n                var__17 := expr_77_component_3\n                var__19 := expr_77_component_4\n                leave\n\n            }\n            /// @src 0:82:370  \"contract C {...\"\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n"
  },
  {
    "path": "test/cmdlineTests/experimental_feature_without_experimental_flag/args",
    "content": "--ir-ast-json\n"
  },
  {
    "path": "test/cmdlineTests/experimental_feature_without_experimental_flag/err",
    "content": "Error: The following options are only available in experimental mode: --ir-ast-json. To enable experimental mode, use the --experimental flag.\n"
  },
  {
    "path": "test/cmdlineTests/experimental_feature_without_experimental_flag/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/experimental_feature_without_experimental_flag/input.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n\tfunction f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/experimental_flag_with_standard_json/args",
    "content": "--experimental\n"
  },
  {
    "path": "test/cmdlineTests/experimental_flag_with_standard_json/err",
    "content": "Error: Standard JSON input mode is incompatible with the --experimental flag. Instead, please use the 'settings.experimental' setting in your Standard JSON input file to enable experimental mode.\n"
  },
  {
    "path": "test/cmdlineTests/experimental_flag_with_standard_json/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/experimental_flag_with_standard_json/input.json",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/function_debug_info/args",
    "content": "--optimize --combined-json function-debug,function-debug-runtime --pretty-json\n"
  },
  {
    "path": "test/cmdlineTests/function_debug_info/err",
    "content": "\n"
  },
  {
    "path": "test/cmdlineTests/function_debug_info/input.sol",
    "content": "pragma solidity >=0.0;\n// SPDX-License-Identifier: GPL-3.0\ncontract C {\n    function f(uint[] calldata x) pure external returns (uint) { return x[0]; }\n    // This will be optimized out\n    function g() pure internal {}\n    mapping(uint => uint) public t;\n    constructor(uint x) {\n        t[0] = x;\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/function_debug_info/output",
    "content": "{\n  \"contracts\": {\n    \"input.sol:C\": {\n      \"function-debug\": {\n        \"@_34\": {\n          \"id\": 34,\n          \"parameterSlots\": 1,\n          \"returnSlots\": 0\n        },\n        \"abi_decode_tuple_t_uint256_fromMemory\": {\n          \"entryPoint\": 88,\n          \"parameterSlots\": 2,\n          \"returnSlots\": 1\n        }\n      },\n      \"function-debug-runtime\": {\n        \"@f_14\": {\n          \"entryPoint\": 124,\n          \"id\": 14,\n          \"parameterSlots\": 2,\n          \"returnSlots\": 1\n        },\n        \"@t_22\": {\n          \"id\": 22,\n          \"parameterSlots\": 0,\n          \"returnSlots\": 0\n        },\n        \"abi_decode_tuple_t_array$_t_uint256_$dyn_calldata_ptr\": {\n          \"entryPoint\": 158,\n          \"parameterSlots\": 2,\n          \"returnSlots\": 2\n        },\n        \"abi_decode_tuple_t_uint256\": {\n          \"entryPoint\": 271,\n          \"parameterSlots\": 2,\n          \"returnSlots\": 1\n        },\n        \"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed\": {\n          \"parameterSlots\": 2,\n          \"returnSlots\": 1\n        },\n        \"panic_error_0x32\": {\n          \"entryPoint\": 294,\n          \"parameterSlots\": 0,\n          \"returnSlots\": 0\n        }\n      }\n    }\n  },\n  \"version\": \"<VERSION REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/function_debug_info_via_yul/args",
    "content": "--via-ir --optimize --combined-json function-debug,function-debug-runtime --pretty-json\n"
  },
  {
    "path": "test/cmdlineTests/function_debug_info_via_yul/err",
    "content": "\n"
  },
  {
    "path": "test/cmdlineTests/function_debug_info_via_yul/input.sol",
    "content": "pragma solidity >=0.0;\n// SPDX-License-Identifier: GPL-3.0\ncontract C {\n    function f(uint[] calldata x) pure external returns (uint) { return x[0]; }\n    // This will be optimized out\n    function g() pure internal {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/function_debug_info_via_yul/output",
    "content": "{\n  \"contracts\": {\n    \"input.sol:C\": {\n      \"function-debug\": {},\n      \"function-debug-runtime\": {}\n    }\n  },\n  \"version\": \"<VERSION REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/hashes/args",
    "content": "--hashes"
  },
  {
    "path": "test/cmdlineTests/hashes/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nerror fileLevelError(uint z);\n\nlibrary L {\n\tevent libraryEvent(uint r);\n\terror libraryError(uint r);\n\terror libraryErrorUnused(uint u);\n\tevent libraryEventUnused(uint u);\n}\n\ncontract C {\n\tstruct S { uint x; }\n\n\tevent ev(uint y);\n\tevent anon_ev(uint y) anonymous;\n\n\terror err(uint z, uint w);\n\n\tfunction f(S memory s) public {\n\t\temit L.libraryEvent(3);\n\t\tif (s.x > 1)\n\t\t\trevert fileLevelError(3);\n\t\telse\n\t\t\trevert L.libraryError(4);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/hashes/output",
    "content": "\n======= input.sol:C =======\nFunction signatures:\n3fc03eeb: f((uint256))\n\nError signatures:\n619a0bb7: err(uint256,uint256)\n82b5f64f: fileLevelError(uint256)\n8c41f45c: libraryError(uint256)\n\nEvent signatures:\n2d4dd5fe18ada5a020a9f5591539a8dc3010a5c074ba6a70e1c956659f02786a: ev(uint256)\n81f3fb02f88d32d3bb08c80c9a622ca3b3223292f131c6ad049811f9a8a606dc: libraryEvent(uint256)\n\n======= input.sol:L =======\nFunction signatures:\n\nError signatures:\n8c41f45c: libraryError(uint256)\nc61c03f5: libraryErrorUnused(uint256)\n\nEvent signatures:\n81f3fb02f88d32d3bb08c80c9a622ca3b3223292f131c6ad049811f9a8a606dc: libraryEvent(uint256)\n0a994ad3600197f16ffe1ea1101caea3174efe5ebd9ba9a75d6d5524c5de28cd: libraryEventUnused(uint256)\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_all_valid_flags/args",
    "content": "--experimental --pretty-json --json-indent 4 --combined-json bin,bin-runtime,opcodes,asm,srcmap,srcmap-runtime --asm --bin --bin-runtime --asm-json --import-asm-json -\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_all_valid_flags/output",
    "content": "{\n    \"contracts\": {\n        \"<stdin>\": {\n            \"asm\": {\n                \".code\": [\n                    {\n                        \"begin\": -1,\n                        \"end\": -1,\n                        \"name\": \"PUSH\",\n                        \"source\": -1,\n                        \"value\": \"0\"\n                    }\n                ],\n                \".data\": {\n                    \"0\": {\n                        \".code\": [\n                            {\n                                \"begin\": -1,\n                                \"end\": -1,\n                                \"name\": \"PUSH\",\n                                \"source\": -1,\n                                \"value\": \"1\"\n                            }\n                        ]\n                    }\n                },\n                \"sourceList\": [\n                    \"contract.sol\",\n                    \"#utility.yul\"\n                ]\n            },\n            \"bin\": \"5ffe\",\n            \"bin-runtime\": \"6001\",\n            \"opcodes\": \"PUSH0 INVALID \",\n            \"srcmap\": \":::-:0\",\n            \"srcmap-runtime\": \":::-:0\"\n        }\n    },\n    \"sourceList\": [\n        \"contract.sol\",\n        \"#utility.yul\"\n    ],\n    \"version\": \"<VERSION REMOVED>\"\n}\nBinary:\n5ffe\nBinary of the runtime part:\n6001\nEVM assembly:\n{\n    \".code\": [\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"0\"\n        }\n    ],\n    \".data\": {\n        \"0\": {\n            \".code\": [\n                {\n                    \"begin\": -1,\n                    \"end\": -1,\n                    \"name\": \"PUSH\",\n                    \"source\": -1,\n                    \"value\": \"1\"\n                }\n            ]\n        }\n    },\n    \"sourceList\": [\n        \"contract.sol\",\n        \"#utility.yul\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_all_valid_flags/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"name\": \"PUSH\",\n            \"value\": \"0\"\n        }\n    ],\n    \".data\": {\n        \"0\": {\n            \".code\": [\n                {\n                    \"name\": \"PUSH\",\n                    \"value\": \"1\"\n                }\n            ]\n        }\n    },\n    \"sourceList\": [\n        \"contract.sol\",\n        \"#utility.yul\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_difficulty_prevrandao/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_difficulty_prevrandao/output",
    "content": "Opcodes:\nPREVRANDAO PREVRANDAO \nEVM assembly:\n  prevrandao\n  prevrandao\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_difficulty_prevrandao/stdin",
    "content": "{\n    \".code\": [\n        {\"name\": \"DIFFICULTY\"},\n        {\"name\": \"PREVRANDAO\"}\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/args",
    "content": "--experimental --import-asm-json --experimental-eof-version 1 --evm-version cancun\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/err",
    "content": "Error: Option --evm-version is not supported with --import-asm-json.\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_eof_unavailable_before_osaka/stdin",
    "content": "{}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_hex_subassembly_indices/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_hex_subassembly_indices/output",
    "content": "Opcodes:\nPUSH0 INVALID \nEVM assembly:\n  0x00\nstop\n\nsub_0: assembly {\n}\n\nsub_1: assembly {\n}\n\nsub_2: assembly {\n}\n\nsub_3: assembly {\n}\n\nsub_4: assembly {\n}\n\nsub_5: assembly {\n}\n\nsub_6: assembly {\n}\n\nsub_7: assembly {\n}\n\nsub_8: assembly {\n}\n\nsub_9: assembly {\n}\n\nsub_10: assembly {\n}\n\nsub_11: assembly {\n}\n\nsub_12: assembly {\n}\n\nsub_13: assembly {\n}\n\nsub_14: assembly {\n}\n\nsub_15: assembly {\n}\n\nsub_16: assembly {\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_hex_subassembly_indices/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"name\": \"PUSH\",\n            \"value\": \"0\"\n        }\n    ],\n    \".data\": {\n        \"0\": {\".code\": []},\n        \"1\": {\".code\": []},\n        \"2\": {\".code\": []},\n        \"3\": {\".code\": []},\n        \"4\": {\".code\": []},\n        \"5\": {\".code\": []},\n        \"6\": {\".code\": []},\n        \"7\": {\".code\": []},\n        \"8\": {\".code\": []},\n        \"9\": {\".code\": []},\n        \"a\": {\".code\": []},\n        \"b\": {\".code\": []},\n        \"c\": {\".code\": []},\n        \"d\": {\".code\": []},\n        \"e\": {\".code\": []},\n        \"f\": {\".code\": []},\n        \"10\": {\".code\": []}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_data_not_hex/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_data_not_hex/err",
    "content": "Error: Assembly Import Error: The value for key '0' inside '.data' is not a valid hexadecimal string.\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_data_not_hex/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_data_not_hex/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"name\": \"PUSH\",\n            \"value\": \"0\"\n        }\n    ],\n    \".data\": {\n        \"0\": \"no-hex-string\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_data_not_object/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_data_not_object/err",
    "content": "Error: Assembly Import Error: The value of key '0' inside '.data' is neither a hex string nor an object.\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_data_not_object/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_data_not_object/stdin",
    "content": "{\n    \".code\": [\n        {\n          \"name\": \"PUSH\",\n          \"value\": \"0\"\n        }\n    ],\n    \".data\": {\n        \"0\": [0, 1, 2, 3]\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/err",
    "content": "Error: Assembly Import Error: Member 'jumpType' set on instruction different from JUMP or JUMPI (was set on instruction 'PUSH')\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_jumptype_instruction/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"name\": \"PUSH\",\n            \"value\": \"0\",\n            \"jumpType\": \"[in]\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_value/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_value/err",
    "content": "Error: Assembly Import Error: Member 'value' defined for instruction 'DIFFICULTY', but the instruction does not need a value.\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_value/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_invalid_value/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"name\": \"DIFFICULTY\",\n            \"value\": \"0\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_missing_subobject_indices/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_missing_subobject_indices/err",
    "content": "Error: Assembly Import Error: Invalid subassembly indices in '.data'. Not all numbers between 0 and 8 are present.\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_missing_subobject_indices/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_missing_subobject_indices/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"name\": \"PUSH\",\n            \"value\": \"0\"\n        }\n    ],\n    \".data\": {\n        \"2\": {\".code\": []},\n        \"0\": {\".code\": []},\n        \"4\": {\".code\": []},\n        \"5\": {\".code\": []},\n        \"7\": {\".code\": []},\n        \"6\": {\".code\": []},\n        \"9\": {\".code\": []},\n        \"1\": {\".code\": []},\n        \"8\": {\".code\": []}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_no_optimize/args",
    "content": "--experimental --import-asm-json - --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_no_optimize/output",
    "content": "EVM assembly:\n  0x00\n  0x00\n  0x00\n  0x00\n  0x00\n  0x00\n  0x00\n  0x00\n  0x00\n  pop(0x00)\n  pop\n  pop\n  pop\n  pop\n  pop\n  pop\n  pop\n  revert\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_no_optimize/stdin",
    "content": "{\n    \".code\": [\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"REVERT\" }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_no_value/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_no_value/err",
    "content": "Error: Assembly Import Error: Member 'value' is missing for instruction 'PUSH', but the instruction needs a value.\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_no_value/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_no_value/stdin",
    "content": "{\n    \".code\": [\n        {\"name\": \"PUSH\"}\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_non_unique_sources/args",
    "content": "--experimental --asm-json --import-asm-json -\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_non_unique_sources/err",
    "content": "Error: Assembly Import Error: Items in 'sourceList' array are not unique.\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_non_unique_sources/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_non_unique_sources/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"name\": \"PUSH\",\n            \"value\": \"0\"\n        }\n    ],\n    \".data\": {\n        \"0\": {\n          \".code\": [\n              {\n                  \"name\": \"PUSH\",\n                  \"value\": \"1\"\n              }\n          ]\n        }\n    },\n    \"sourceList\": [\n        \"contract.sol\",\n        \"contract.sol\",\n        \"#utility.yul\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_optimize/args",
    "content": "--experimental --optimize --import-asm-json - --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_optimize/exit",
    "content": "0\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_optimize/output",
    "content": "EVM assembly:\n  revert(0x00, 0x00)\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_optimize/stdin",
    "content": "{\n    \".code\": [\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"PUSH\", \"value\": \"0\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"POP\" },\n        { \"name\": \"REVERT\" }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_out_of_range_data_index/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_out_of_range_data_index/err",
    "content": "Error: Assembly Import Error: The key '18446744073709551615' inside '.data' is out of the supported integer range.\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_out_of_range_data_index/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_out_of_range_data_index/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"name\": \"PUSH\",\n            \"value\": \"0\"\n        }\n    ],\n    \".data\": {\n        \"18446744073709551615\": {\n            \".code\": []\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_random_order_data_index/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_random_order_data_index/output",
    "content": "Opcodes:\nPUSH0 INVALID \nEVM assembly:\n  0x00\nstop\n\nsub_0: assembly {\n}\n\nsub_1: assembly {\n    stop\n\n    sub_0: assembly {\n    }\n\n    sub_1: assembly {\n    }\n\n    sub_2: assembly {\n    }\n}\n\nsub_2: assembly {\n    stop\n\n    sub_0: assembly {\n    }\n\n    sub_1: assembly {\n    }\n}\n\nsub_3: assembly {\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_random_order_data_index/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"name\": \"PUSH\",\n            \"value\": \"0\"\n        }\n    ],\n    \".data\": {\n        \"2\": {\n            \".code\": [],\n            \".data\": {\n                \"1\": {\".code\": []},\n                \"0\": {\".code\": []}\n            }\n        },\n        \"0\": {\".code\": []},\n        \"1\": {\n            \".code\": [],\n            \".data\": {\n                \"1\": {\".code\": []},\n                \"2\": {\".code\": []},\n                \"0\": {\".code\": []}\n            }\n        },\n        \"3\": {\".code\": []}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_unrecognized_field/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_unrecognized_field/err",
    "content": "Error: Assembly Import Error: Unknown member '_name'. Valid members are: begin, end, jumpType, modifierDepth, name, source, value.\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_unrecognized_field/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_unrecognized_field/stdin",
    "content": "{\n    \".code\": [\n        {\"_name\": \"DIFFICULTY\"}\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_untagged_jumpdest/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_untagged_jumpdest/err",
    "content": "Error: Assembly Import Error: JUMPDEST instruction without a tag\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_untagged_jumpdest/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_untagged_jumpdest/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"name\": \"tag\",\n            \"value\": \"0x00\"\n        },\n        {\"name\": \"JUMPDEST\"},\n        {\"name\": \"JUMPDEST\"}\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_verbatim/args",
    "content": "--experimental --import-asm-json - --opcodes --asm\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_verbatim/output",
    "content": "Opcodes:\nPUSH0 CALLDATALOAD PUSH1 0x14 DUP1 DUP3 SSTORE PUSH1 0x20 CALLDATALOAD ISZERO PUSH1 0x1C JUMPI DUP1 DUP3 SSTORE PUSH0 DUP1 PUSH0 DUP1 PUSH0 DUP1 STATICCALL POP PUSH25 0x797A5B80825550500000000000000000000000000000000000 \nEVM assembly:\n    /* \"<stdin>\":28:29    */\n  0x00\n    /* \"<stdin>\":15:30  [... */\n  calldataload\n    /* \"<stdin>\":44:46  n\" */\n  0x14\n    /* \"<stdin>\":61:62    */\n  dup1\n    /* \"<stdin>\":58:59    */\n  dup3\n    /* \"<stdin>\":51:63  ... */\n  sstore\n    /* \"<stdin>\":84:86     */\n  0x20\n    /* \"<stdin>\":71:87  29,... */\n  calldataload\n    /* \"<stdin>\":68:188  \": 29,... */\n  iszero\n  tag_1\n  jumpi\n    /* \"<stdin>\":108:109    */\n  dup1\n    /* \"<stdin>\":105:106    */\n  dup3\n    /* \"<stdin>\":98:110  SH\",... */\n  sstore\n    /* \"<stdin>\":149:150  \" */\n  0x00\n    /* \"<stdin>\":146:147  \" */\n  dup1\n    /* \"<stdin>\":143:144  l */\n  0x00\n    /* \"<stdin>\":140:141  \" */\n  dup1\n    /* \"<stdin>\":137:138    */\n  0x00\n    /* \"<stdin>\":134:135    */\n  dup1\n    /* \"<stdin>\":123:151  : 0,... */\n  staticcall\n    /* \"<stdin>\":119:152  rce\": 0,... */\n  pop\n    /* \"<stdin>\":161:182  },... */\n  verbatimbytecode_78797a\n    /* \"<stdin>\":68:188  \": 29,... */\ntag_1:\n    /* \"<stdin>\":203:204    */\n  dup1\n    /* \"<stdin>\":200:201    */\n  dup3\n    /* \"<stdin>\":193:205  : 15,... */\n  sstore\n    /* \"<stdin>\":0:207  {... */\n  pop\n  pop\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_verbatim/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"begin\": 28,\n            \"end\": 29,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": 15,\n            \"end\": 30,\n            \"name\": \"CALLDATALOAD\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 44,\n            \"end\": 46,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"14\"\n        },\n        {\n            \"begin\": 61,\n            \"end\": 62,\n            \"name\": \"DUP1\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 58,\n            \"end\": 59,\n            \"name\": \"DUP3\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 51,\n            \"end\": 63,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 84,\n            \"end\": 86,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"20\"\n        },\n        {\n            \"begin\": 71,\n            \"end\": 87,\n            \"name\": \"CALLDATALOAD\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 68,\n            \"end\": 188,\n            \"name\": \"ISZERO\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 68,\n            \"end\": 188,\n            \"name\": \"PUSH [tag]\",\n            \"source\": 0,\n            \"value\": \"1\"\n        },\n        {\n            \"begin\": 68,\n            \"end\": 188,\n            \"name\": \"JUMPI\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 108,\n            \"end\": 109,\n            \"name\": \"DUP1\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 105,\n            \"end\": 106,\n            \"name\": \"DUP3\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 98,\n            \"end\": 110,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 149,\n            \"end\": 150,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": 146,\n            \"end\": 147,\n            \"name\": \"DUP1\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 143,\n            \"end\": 144,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": 140,\n            \"end\": 141,\n            \"name\": \"DUP1\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 137,\n            \"end\": 138,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": 134,\n            \"end\": 135,\n            \"name\": \"DUP1\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 123,\n            \"end\": 151,\n            \"name\": \"STATICCALL\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 119,\n            \"end\": 152,\n            \"name\": \"POP\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 161,\n            \"end\": 182,\n            \"name\": \"VERBATIM\",\n            \"source\": 0,\n            \"value\": \"78797a\"\n        },\n        {\n            \"begin\": 68,\n            \"end\": 188,\n            \"name\": \"tag\",\n            \"source\": 0,\n            \"value\": \"1\"\n        },\n        {\n            \"begin\": 68,\n            \"end\": 188,\n            \"name\": \"JUMPDEST\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 203,\n            \"end\": 204,\n            \"name\": \"DUP1\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 200,\n            \"end\": 201,\n            \"name\": \"DUP3\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 193,\n            \"end\": 205,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 207,\n            \"name\": \"POP\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 207,\n            \"name\": \"POP\",\n            \"source\": 0\n        }\n    ],\n    \"sourceList\": [\n        \"<stdin>\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_yul_more_subobjects/args",
    "content": "--experimental --import-asm-json - --opcodes\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_yul_more_subobjects/output",
    "content": "Opcodes:\nPUSH1 0x1E PUSH0 SSTORE PUSH1 0x1A PUSH1 0x1 SSTORE PUSH1 0x15 PUSH1 0x2 SSTORE PUSH1 0x1 PUSH1 0x3 SSTORE PUSH1 0x1 PUSH1 0x4 SSTORE PUSH1 0x1 PUSH1 0x5 SSTORE INVALID \n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_yul_more_subobjects/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"begin\": 37,\n            \"end\": 51,\n            \"name\": \"PUSHSIZE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 34,\n            \"end\": 35,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": 27,\n            \"end\": 52,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 67,\n            \"end\": 81,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n        },\n        {\n            \"begin\": 64,\n            \"end\": 65,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"1\"\n        },\n        {\n            \"begin\": 57,\n            \"end\": 82,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 97,\n            \"end\": 114,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n        },\n        {\n            \"begin\": 94,\n            \"end\": 95,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"2\"\n        },\n        {\n            \"begin\": 87,\n            \"end\": 115,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 130,\n            \"end\": 152,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffe\"\n        },\n        {\n            \"begin\": 127,\n            \"end\": 128,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"3\"\n        },\n        {\n            \"begin\": 120,\n            \"end\": 153,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 168,\n            \"end\": 190,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffd\"\n        },\n        {\n            \"begin\": 165,\n            \"end\": 166,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"4\"\n        },\n        {\n            \"begin\": 158,\n            \"end\": 191,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 206,\n            \"end\": 228,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffc\"\n        },\n        {\n            \"begin\": 203,\n            \"end\": 204,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"5\"\n        },\n        {\n            \"begin\": 196,\n            \"end\": 229,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        }\n    ],\n    \".data\": {\n        \"0\": {\n            \".code\": [\n                {\n                    \"begin\": 278,\n                    \"end\": 292,\n                    \"name\": \"PUSHSIZE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 275,\n                    \"end\": 276,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"6\"\n                },\n                {\n                    \"begin\": 268,\n                    \"end\": 293,\n                    \"name\": \"SSTORE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 310,\n                    \"end\": 324,\n                    \"name\": \"PUSH #[$]\",\n                    \"source\": 0,\n                    \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n                },\n                {\n                    \"begin\": 307,\n                    \"end\": 308,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"7\"\n                },\n                {\n                    \"begin\": 300,\n                    \"end\": 325,\n                    \"name\": \"SSTORE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 342,\n                    \"end\": 361,\n                    \"name\": \"PUSH #[$]\",\n                    \"source\": 0,\n                    \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n                },\n                {\n                    \"begin\": 339,\n                    \"end\": 340,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"8\"\n                },\n                {\n                    \"begin\": 332,\n                    \"end\": 362,\n                    \"name\": \"SSTORE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 379,\n                    \"end\": 398,\n                    \"name\": \"PUSH #[$]\",\n                    \"source\": 0,\n                    \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffe\"\n                },\n                {\n                    \"begin\": 376,\n                    \"end\": 377,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"9\"\n                },\n                {\n                    \"begin\": 369,\n                    \"end\": 399,\n                    \"name\": \"SSTORE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 417,\n                    \"end\": 436,\n                    \"name\": \"PUSH #[$]\",\n                    \"source\": 0,\n                    \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffd\"\n                },\n                {\n                    \"begin\": 413,\n                    \"end\": 415,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"A\"\n                },\n                {\n                    \"begin\": 406,\n                    \"end\": 437,\n                    \"name\": \"SSTORE\",\n                    \"source\": 0\n                }\n            ],\n            \".data\": {\n                \"0\": {\n                    \".code\": [\n                        {\n                            \"begin\": 494,\n                            \"end\": 508,\n                            \"name\": \"PUSHSIZE\",\n                            \"source\": 0\n                        },\n                        {\n                            \"begin\": 490,\n                            \"end\": 492,\n                            \"name\": \"PUSH\",\n                            \"source\": 0,\n                            \"value\": \"B\"\n                        },\n                        {\n                            \"begin\": 483,\n                            \"end\": 509,\n                            \"name\": \"SSTORE\",\n                            \"source\": 0\n                        },\n                        {\n                            \"begin\": 529,\n                            \"end\": 545,\n                            \"name\": \"PUSH #[$]\",\n                            \"source\": 0,\n                            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n                        },\n                        {\n                            \"begin\": 525,\n                            \"end\": 527,\n                            \"name\": \"PUSH\",\n                            \"source\": 0,\n                            \"value\": \"C\"\n                        },\n                        {\n                            \"begin\": 518,\n                            \"end\": 546,\n                            \"name\": \"SSTORE\",\n                            \"source\": 0\n                        },\n                        {\n                            \"begin\": 566,\n                            \"end\": 582,\n                            \"name\": \"PUSH #[$]\",\n                            \"source\": 0,\n                            \"value\": \"0000000000000000000000000000000000000000000000000000000000000001\"\n                        },\n                        {\n                            \"begin\": 562,\n                            \"end\": 564,\n                            \"name\": \"PUSH\",\n                            \"source\": 0,\n                            \"value\": \"D\"\n                        },\n                        {\n                            \"begin\": 555,\n                            \"end\": 583,\n                            \"name\": \"SSTORE\",\n                            \"source\": 0\n                        },\n                        {\n                            \"begin\": 603,\n                            \"end\": 619,\n                            \"name\": \"PUSH #[$]\",\n                            \"source\": 0,\n                            \"value\": \"0000000000000000000000000000000000000000000000000000000000000002\"\n                        },\n                        {\n                            \"begin\": 599,\n                            \"end\": 601,\n                            \"name\": \"PUSH\",\n                            \"source\": 0,\n                            \"value\": \"E\"\n                        },\n                        {\n                            \"begin\": 592,\n                            \"end\": 620,\n                            \"name\": \"SSTORE\",\n                            \"source\": 0\n                        }\n                    ],\n                    \".data\": {\n                        \"0\": {\n                            \".code\": [\n                                {\n                                    \"begin\": 676,\n                                    \"end\": 685,\n                                    \"name\": \"INVALID\",\n                                    \"source\": 0\n                                }\n                            ]\n                        },\n                        \"1\": {\n                            \".code\": [\n                                {\n                                    \"begin\": 751,\n                                    \"end\": 760,\n                                    \"name\": \"INVALID\",\n                                    \"source\": 0\n                                }\n                            ]\n                        },\n                        \"2\": {\n                            \".code\": [\n                                {\n                                    \"begin\": 826,\n                                    \"end\": 835,\n                                    \"name\": \"INVALID\",\n                                    \"source\": 0\n                                }\n                            ]\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sourceList\": [\n        \"<stdin>\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_yul_subobjects/args",
    "content": "--experimental --import-asm-json - --opcodes\n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_yul_subobjects/output",
    "content": "Opcodes:\nPUSH0 DUP1 SSTORE PUSH1 0x6A PUSH1 0x1 SSTORE PUSH1 0x31 PUSH1 0x2 SSTORE PUSH1 0x2C PUSH1 0x3 SSTORE PUSH1 0x5E PUSH1 0x4 SSTORE PUSH1 0xC PUSH1 0x5 SSTORE PUSH1 0x5D PUSH1 0x6 SSTORE PUSH1 0x1 PUSH1 0x7 SSTORE PUSH1 0x5D PUSH1 0x8 SSTORE PUSH1 0x1 PUSH1 0x9 SSTORE INVALID PUSH1 0x1F PUSH1 0xA SSTORE PUSH1 0xC PUSH1 0xB SSTORE PUSH1 0x2B PUSH1 0xC SSTORE PUSH1 0x1 PUSH1 0xD SSTORE PUSH1 0x2B PUSH1 0xE SSTORE PUSH1 0x1 PUSH1 0xF SSTORE INVALID PUSH1 0xB PUSH1 0x10 SSTORE PUSH1 0x1 PUSH1 0x11 SSTORE INVALID INVALID INVALID INVALID PUSH1 0xB PUSH1 0x10 SSTORE PUSH1 0x1 PUSH1 0x11 SSTORE INVALID INVALID \n"
  },
  {
    "path": "test/cmdlineTests/import_asm_json_yul_subobjects/stdin",
    "content": "{\n    \".code\": [\n        {\n            \"begin\": 36,\n            \"end\": 51,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": 33,\n            \"end\": 34,\n            \"name\": \"DUP1\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 26,\n            \"end\": 52,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 67,\n            \"end\": 80,\n            \"name\": \"PUSHSIZE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 64,\n            \"end\": 65,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"1\"\n        },\n        {\n            \"begin\": 57,\n            \"end\": 81,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 96,\n            \"end\": 111,\n            \"name\": \"PUSH [$]\",\n            \"source\": 0,\n            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n        },\n        {\n            \"begin\": 93,\n            \"end\": 94,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"2\"\n        },\n        {\n            \"begin\": 86,\n            \"end\": 112,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 127,\n            \"end\": 140,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n        },\n        {\n            \"begin\": 124,\n            \"end\": 125,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"3\"\n        },\n        {\n            \"begin\": 117,\n            \"end\": 141,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 156,\n            \"end\": 173,\n            \"name\": \"PUSH [$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n        },\n        {\n            \"begin\": 153,\n            \"end\": 154,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"4\"\n        },\n        {\n            \"begin\": 146,\n            \"end\": 174,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 189,\n            \"end\": 204,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n        },\n        {\n            \"begin\": 186,\n            \"end\": 187,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"5\"\n        },\n        {\n            \"begin\": 179,\n            \"end\": 205,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 220,\n            \"end\": 237,\n            \"name\": \"PUSH [$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffe\"\n        },\n        {\n            \"begin\": 217,\n            \"end\": 218,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"6\"\n        },\n        {\n            \"begin\": 210,\n            \"end\": 238,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 253,\n            \"end\": 268,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffe\"\n        },\n        {\n            \"begin\": 250,\n            \"end\": 251,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"7\"\n        },\n        {\n            \"begin\": 243,\n            \"end\": 269,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 284,\n            \"end\": 303,\n            \"name\": \"PUSH [$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffd\"\n        },\n        {\n            \"begin\": 281,\n            \"end\": 282,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"8\"\n        },\n        {\n            \"begin\": 274,\n            \"end\": 304,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 319,\n            \"end\": 336,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffd\"\n        },\n        {\n            \"begin\": 316,\n            \"end\": 317,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"9\"\n        },\n        {\n            \"begin\": 309,\n            \"end\": 337,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        }\n    ],\n    \".data\": {\n        \"0\": {\n            \".code\": [\n                {\n                    \"begin\": 418,\n                    \"end\": 433,\n                    \"name\": \"PUSH [$]\",\n                    \"source\": 0,\n                    \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n                },\n                {\n                    \"begin\": 414,\n                    \"end\": 416,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"A\"\n                },\n                {\n                    \"begin\": 407,\n                    \"end\": 434,\n                    \"name\": \"SSTORE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 452,\n                    \"end\": 465,\n                    \"name\": \"PUSH #[$]\",\n                    \"source\": 0,\n                    \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n                },\n                {\n                    \"begin\": 448,\n                    \"end\": 450,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"B\"\n                },\n                {\n                    \"begin\": 441,\n                    \"end\": 466,\n                    \"name\": \"SSTORE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 484,\n                    \"end\": 499,\n                    \"name\": \"PUSH [$]\",\n                    \"source\": 0,\n                    \"value\": \"0000000000000000000000000000000000000000000000000000000000000001\"\n                },\n                {\n                    \"begin\": 480,\n                    \"end\": 482,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"C\"\n                },\n                {\n                    \"begin\": 473,\n                    \"end\": 500,\n                    \"name\": \"SSTORE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 518,\n                    \"end\": 531,\n                    \"name\": \"PUSH #[$]\",\n                    \"source\": 0,\n                    \"value\": \"0000000000000000000000000000000000000000000000000000000000000001\"\n                },\n                {\n                    \"begin\": 514,\n                    \"end\": 516,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"D\"\n                },\n                {\n                    \"begin\": 507,\n                    \"end\": 532,\n                    \"name\": \"SSTORE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 550,\n                    \"end\": 567,\n                    \"name\": \"PUSH [$]\",\n                    \"source\": 0,\n                    \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n                },\n                {\n                    \"begin\": 546,\n                    \"end\": 548,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"E\"\n                },\n                {\n                    \"begin\": 539,\n                    \"end\": 568,\n                    \"name\": \"SSTORE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 586,\n                    \"end\": 601,\n                    \"name\": \"PUSH #[$]\",\n                    \"source\": 0,\n                    \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n                },\n                {\n                    \"begin\": 582,\n                    \"end\": 584,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"F\"\n                },\n                {\n                    \"begin\": 575,\n                    \"end\": 602,\n                    \"name\": \"SSTORE\",\n                    \"source\": 0\n                }\n            ],\n            \".data\": {\n                \"0\": {\n                    \".code\": [\n                        {\n                            \"begin\": 658,\n                            \"end\": 673,\n                            \"name\": \"PUSH [$]\",\n                            \"source\": 0,\n                            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n                        },\n                        {\n                            \"begin\": 654,\n                            \"end\": 656,\n                            \"name\": \"PUSH\",\n                            \"source\": 0,\n                            \"value\": \"10\"\n                        },\n                        {\n                            \"begin\": 647,\n                            \"end\": 674,\n                            \"name\": \"SSTORE\",\n                            \"source\": 0\n                        },\n                        {\n                            \"begin\": 694,\n                            \"end\": 707,\n                            \"name\": \"PUSH #[$]\",\n                            \"source\": 0,\n                            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n                        },\n                        {\n                            \"begin\": 690,\n                            \"end\": 692,\n                            \"name\": \"PUSH\",\n                            \"source\": 0,\n                            \"value\": \"11\"\n                        },\n                        {\n                            \"begin\": 683,\n                            \"end\": 708,\n                            \"name\": \"SSTORE\",\n                            \"source\": 0\n                        }\n                    ],\n                    \".data\": {\n                        \"0\": {\n                            \".code\": [\n                                {\n                                    \"begin\": 761,\n                                    \"end\": 770,\n                                    \"name\": \"INVALID\",\n                                    \"source\": 0\n                                }\n                            ]\n                        }\n                    }\n                },\n                \"1\": {\n                    \".code\": [\n                        {\n                            \"begin\": 833,\n                            \"end\": 842,\n                            \"name\": \"INVALID\",\n                            \"source\": 0\n                        }\n                    ]\n                }\n            }\n        },\n        \"ACAF3289D7B601CBD114FB36C4D29C85BBFD5E133F14CB355C3FD8D99367964F\": \"48656c6c6f2c20576f726c6421\"\n    },\n    \"sourceList\": [\n        \"<stdin>\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/inheritance_repeated_definition_error/args",
    "content": "-"
  },
  {
    "path": "test/cmdlineTests/inheritance_repeated_definition_error/err",
    "content": "Error: More than one inheritance list.\n --> <stdin>:9:20:\n  |\n9 | contract C is A, B is B {\n  |                    ^^\nNote: Previous list:\n --> <stdin>:9:15:\n  |\n9 | contract C is A, B is B {\n  |               ^\n"
  },
  {
    "path": "test/cmdlineTests/inheritance_repeated_definition_error/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/inheritance_repeated_definition_error/stdin",
    "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A {\n}\n\ncontract B {\n}\n\ncontract C is A, B is B {\n}"
  },
  {
    "path": "test/cmdlineTests/inline_assembly_function_name_clash/args",
    "content": "--via-ir --combined-json function-debug-runtime --pretty-json --json-indent 4"
  },
  {
    "path": "test/cmdlineTests/inline_assembly_function_name_clash/err",
    "content": "Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n--> input.sol\n\nWarning: Source file does not specify required compiler version!\n--> input.sol\n"
  },
  {
    "path": "test/cmdlineTests/inline_assembly_function_name_clash/input.sol",
    "content": "contract C {\n  uint x;\n  modifier m() {\n    uint t;\n    assembly {\n      function f() -> x { x := 8 }\n      t := f()\n    }\n    x = t;\n    _;\n  }\n  function f() m m public returns (uint r) {\n    assembly { function f() -> x { x := 1 } r := f() }\n  }\n  function g() m m public returns (uint r) {\n    assembly { function f() -> x { x := 2 } r := f() }\n  }\n}"
  },
  {
    "path": "test/cmdlineTests/inline_assembly_function_name_clash/output",
    "content": "{\n    \"contracts\": {\n        \"input.sol:C\": {\n            \"function-debug-runtime\": {\n                \"abi_decode\": {\n                    \"entryPoint\": 80,\n                    \"parameterSlots\": 2,\n                    \"returnSlots\": 0\n                },\n                \"abi_encode_uint256\": {\n                    \"entryPoint\": 111,\n                    \"parameterSlots\": 2,\n                    \"returnSlots\": 1\n                },\n                \"abi_encode_uint256_to_uint256\": {\n                    \"entryPoint\": 98,\n                    \"parameterSlots\": 2,\n                    \"returnSlots\": 0\n                },\n                \"allocate_unbounded\": {\n                    \"entryPoint\": 66,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 1\n                },\n                \"cleanup_uint256\": {\n                    \"entryPoint\": 95,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"convert_uint256_to_uint256\": {\n                    \"entryPoint\": 276,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"external_fun_f\": {\n                    \"entryPoint\": 132,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 0\n                },\n                \"external_fun_g\": {\n                    \"entryPoint\": 185,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 0\n                },\n                \"fun_f\": {\n                    \"entryPoint\": 442,\n                    \"id\": 25,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 1\n                },\n                \"fun_f_inner\": {\n                    \"entryPoint\": 430,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"fun_g\": {\n                    \"entryPoint\": 564,\n                    \"id\": 36,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 1\n                },\n                \"fun_g_inner\": {\n                    \"entryPoint\": 552,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"identity\": {\n                    \"entryPoint\": 273,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"modifier_m\": {\n                    \"entryPoint\": 509,\n                    \"id\": 14,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"modifier_m_17\": {\n                    \"entryPoint\": 344,\n                    \"id\": 14,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"modifier_m_19\": {\n                    \"entryPoint\": 387,\n                    \"id\": 14,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"modifier_m_28\": {\n                    \"entryPoint\": 466,\n                    \"id\": 14,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"prepare_store_uint256\": {\n                    \"entryPoint\": 304,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74\": {\n                    \"entryPoint\": 238,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 0\n                },\n                \"revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb\": {\n                    \"entryPoint\": 72,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 0\n                },\n                \"revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b\": {\n                    \"entryPoint\": 76,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 0\n                },\n                \"shift_left\": {\n                    \"entryPoint\": 246,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"shift_right_unsigned\": {\n                    \"entryPoint\": 60,\n                    \"parameterSlots\": 1,\n                    \"returnSlots\": 1\n                },\n                \"update_byte_slice_shift\": {\n                    \"entryPoint\": 251,\n                    \"parameterSlots\": 2,\n                    \"returnSlots\": 1\n                },\n                \"update_storage_value_offset_uint256_to_uint256\": {\n                    \"entryPoint\": 307,\n                    \"parameterSlots\": 2,\n                    \"returnSlots\": 0\n                },\n                \"usr$f\": {\n                    \"entryPoint\": 339,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 1\n                },\n                \"usr$f_17\": {\n                    \"entryPoint\": 382,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 1\n                },\n                \"usr$f_22\": {\n                    \"entryPoint\": 425,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 1\n                },\n                \"usr$f_26\": {\n                    \"entryPoint\": 461,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 1\n                },\n                \"usr$f_32\": {\n                    \"entryPoint\": 504,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 1\n                },\n                \"usr$f_37\": {\n                    \"entryPoint\": 547,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 1\n                },\n                \"zero_value_for_split_uint256\": {\n                    \"entryPoint\": 242,\n                    \"parameterSlots\": 0,\n                    \"returnSlots\": 1\n                }\n            }\n        }\n    },\n    \"version\": \"<VERSION REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_compiler_inheritance_nosubobjects/args",
    "content": "--ir-optimized --optimize"
  },
  {
    "path": "test/cmdlineTests/ir_compiler_inheritance_nosubobjects/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.6.0;\npragma abicoder v2;\n\ncontract C {\n    constructor() {}\n}\ncontract D is C {\n}"
  },
  {
    "path": "test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_7\" {\n    code {\n        {\n            /// @src 0:82:117  \"contract C {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_7_deployed\")\n            codecopy(_1, dataoffset(\"C_7_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_7_deployed\" {\n        code {\n            {\n                /// @src 0:82:117  \"contract C {...\"\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"D_10\" {\n    code {\n        {\n            /// @src 0:118:137  \"contract D is C {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"D_10_deployed\")\n            codecopy(_1, dataoffset(\"D_10_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"D_10_deployed\" {\n        code {\n            {\n                /// @src 0:118:137  \"contract D is C {...\"\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_compiler_subobjects/args",
    "content": "--ir-optimized --optimize"
  },
  {
    "path": "test/cmdlineTests/ir_compiler_subobjects/err",
    "content": "Warning: Unused local variable.\n --> input.sol:8:9:\n  |\n8 |         C c = new C();\n  |         ^^^\n"
  },
  {
    "path": "test/cmdlineTests/ir_compiler_subobjects/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.6.0;\npragma abicoder v2;\n\ncontract C {}\ncontract D {\n    function f() public {\n        C c = new C();\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_compiler_subobjects/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_3\" {\n    code {\n        {\n            /// @src 0:82:95  \"contract C {}\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_3_deployed\")\n            codecopy(_1, dataoffset(\"C_3_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_3_deployed\" {\n        code {\n            {\n                /// @src 0:82:95  \"contract C {}\"\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"D_16\" {\n    code {\n        {\n            /// @src 0:96:165  \"contract D {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"D_16_deployed\")\n            codecopy(_1, dataoffset(\"D_16_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"D_16_deployed\" {\n        code {\n            {\n                /// @src 0:96:165  \"contract D {...\"\n                let _1 := memoryguard(0x80)\n                mstore(64, _1)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        /// @src 0:149:156  \"new C()\"\n                        let _2 := datasize(\"C_3\")\n                        let _3 := add(_1, _2)\n                        if or(gt(_3, 0xffffffffffffffff), lt(_3, _1))\n                        {\n                            /// @src 0:96:165  \"contract D {...\"\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 0x24)\n                        }\n                        /// @src 0:149:156  \"new C()\"\n                        datacopy(_1, dataoffset(\"C_3\"), _2)\n                        if iszero(create(/** @src 0:96:165  \"contract D {...\" */ 0, /** @src 0:149:156  \"new C()\" */ _1, sub(_3, _1)))\n                        {\n                            /// @src 0:96:165  \"contract D {...\"\n                            let pos := mload(64)\n                            returndatacopy(pos, 0, returndatasize())\n                            revert(pos, returndatasize())\n                        }\n                        return(0, 0)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        /// @use-src 0:\"input.sol\"\n        object \"C_3\" {\n            code {\n                {\n                    /// @src 0:82:95  \"contract C {}\"\n                    let _1 := memoryguard(0x80)\n                    mstore(64, _1)\n                    if callvalue() { revert(0, 0) }\n                    let _2 := datasize(\"C_3_deployed\")\n                    codecopy(_1, dataoffset(\"C_3_deployed\"), _2)\n                    return(_1, _2)\n                }\n            }\n            /// @use-src 0:\"input.sol\"\n            object \"C_3_deployed\" {\n                code {\n                    {\n                        /// @src 0:82:95  \"contract C {}\"\n                        revert(0, 0)\n                    }\n                }\n                data \".metadata\" hex\"<BYTECODE REMOVED>\"\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_optimized_transient_storage_value_type/args",
    "content": "--via-ir --no-cbor-metadata --ir-optimized --optimize --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/ir_optimized_transient_storage_value_type/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    uint transient x;\n    function f() public {\n        x = x + 1;\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_optimized_transient_storage_value_type/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_14\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_14_deployed\")\n            codecopy(_1, dataoffset(\"C_14_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_14_deployed\" {\n        code {\n            {\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let _1 := tload(0)\n                        let sum := add(_1, 0x01)\n                        if gt(_1, sum)\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x11)\n                            revert(0, 0x24)\n                        }\n                        tstore(0, sum)\n                        return(0, 0)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_optimized_with_optimize/args",
    "content": "--ir-optimized --optimize --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/ir_optimized_with_optimize/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/ir_optimized_with_optimize/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_2\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_2_deployed\")\n            codecopy(_1, dataoffset(\"C_2_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_2_deployed\" {\n        code { { revert(0, 0) } }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_subobject_order/args",
    "content": "--ir-optimized --optimize --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/ir_subobject_order/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >0.0.0;\n\ncontract B { constructor() payable { assembly { revert(0,0) } } }\ncontract A { constructor() payable { assembly { revert(0,0) } } }\ncontract C {\n    // The subobject order should be determined by reference, not AST ID,\n    // So the subobject for A should precede the subobject for B.\n\tA a = new A();\n\tB b = new B();\n\tfallback() external payable {\n\t\tassembly { revert(0,0) }\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_subobject_order/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"A_13\" {\n    code { { revert(0, 0) } }\n    /// @use-src 0:\"input.sol\"\n    object \"A_13_deployed\" {\n        code { { revert(0, 0) } }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"B_7\" {\n    code { { revert(0, 0) } }\n    /// @use-src 0:\"input.sol\"\n    object \"B_7_deployed\" {\n        code { { revert(0, 0) } }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_33\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"A_13\")\n            let _3 := add(_1, _2)\n            if or(gt(_3, sub(shl(64, 1), 1)), lt(_3, _1))\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x41)\n                revert(0, 0x24)\n            }\n            datacopy(_1, dataoffset(\"A_13\"), _2)\n            let expr_address := create(0, _1, sub(_3, _1))\n            if iszero(expr_address)\n            {\n                let pos := mload(64)\n                returndatacopy(pos, 0, returndatasize())\n                revert(pos, returndatasize())\n            }\n            sstore(0, or(and(sload(0), not(sub(shl(160, 1), 1))), and(expr_address, sub(shl(160, 1), 1))))\n            let _4 := mload(64)\n            let _5 := datasize(\"B_7\")\n            let _6 := add(_4, _5)\n            if or(gt(_6, sub(shl(64, 1), 1)), lt(_6, _4))\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x41)\n                revert(0, 0x24)\n            }\n            datacopy(_4, dataoffset(\"B_7\"), _5)\n            let expr_address_1 := create(0, _4, sub(_6, _4))\n            if iszero(expr_address_1)\n            {\n                let pos_1 := mload(64)\n                returndatacopy(pos_1, 0, returndatasize())\n                revert(pos_1, returndatasize())\n            }\n            sstore(0x01, or(and(sload(0x01), not(sub(shl(160, 1), 1))), and(expr_address_1, sub(shl(160, 1), 1))))\n            let _7 := mload(64)\n            let _8 := datasize(\"C_33_deployed\")\n            codecopy(_7, dataoffset(\"C_33_deployed\"), _8)\n            return(_7, _8)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_33_deployed\" {\n        code { { revert(0, 0) } }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"A_13\" {\n        code { { revert(0, 0) } }\n        /// @use-src 0:\"input.sol\"\n        object \"A_13_deployed\" {\n            code { { revert(0, 0) } }\n            data \".metadata\" hex\"<BYTECODE REMOVED>\"\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"B_7\" {\n        code { { revert(0, 0) } }\n        /// @use-src 0:\"input.sol\"\n        object \"B_7_deployed\" {\n            code { { revert(0, 0) } }\n            data \".metadata\" hex\"<BYTECODE REMOVED>\"\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_unoptimized_with_optimize/args",
    "content": "--ir --optimize --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/ir_unoptimized_with_optimize/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/ir_unoptimized_with_optimize/output",
    "content": "IR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_2\" {\n    code {\n\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_2()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_2_deployed\"), datasize(\"C_2_deployed\"))\n\n        return(_1, datasize(\"C_2_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function constructor_C_2() {\n\n        }\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_2_deployed\" {\n        code {\n\n            mstore(64, memoryguard(128))\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/args",
    "content": "--ir --optimize --via-ir --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/ir_unoptimized_with_optimize_via_ir/output",
    "content": "IR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_2\" {\n    code {\n\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_2()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_2_deployed\"), datasize(\"C_2_deployed\"))\n\n        return(_1, datasize(\"C_2_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function constructor_C_2() {\n\n        }\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_2_deployed\" {\n        code {\n\n            mstore(64, memoryguard(128))\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/args",
    "content": "--ir-optimized --optimize"
  },
  {
    "path": "test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\npragma abicoder v2;\n\ncontract D {\n    constructor() { assembly { mstore(0,0) } }\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"D_12\" {\n    code {\n        {\n            /// @src 0:82:175  \"contract D {...\"\n            if callvalue() { revert(0, 0) }\n            let _1 := datasize(\"D_12_deployed\")\n            codecopy(128, dataoffset(\"D_12_deployed\"), _1)\n            return(128, _1)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"D_12_deployed\" {\n        code {\n            {\n                /// @src 0:82:175  \"contract D {...\"\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        return(0, 0)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/args",
    "content": "--ir-optimized --optimize"
  },
  {
    "path": "test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\npragma abicoder v2;\n\ncontract D {\n    function f() public pure {\n        assembly { mstore(0,0) }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"D_8\" {\n    code {\n        {\n            /// @src 0:82:166  \"contract D {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"D_8_deployed\")\n            codecopy(_1, dataoffset(\"D_8_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"D_8_deployed\" {\n        code {\n            {\n                /// @src 0:82:166  \"contract D {...\"\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        return(0, 0)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/keccak_optimization_deploy_code/args",
    "content": "--ir-optimized --optimize --optimize-runs 50000\n"
  },
  {
    "path": "test/cmdlineTests/keccak_optimization_deploy_code/err",
    "content": "\n"
  },
  {
    "path": "test/cmdlineTests/keccak_optimization_deploy_code/input.sol",
    "content": "// SPDX-License-Identifier: GPL-v3\npragma solidity >= 0.0.0;\n\ncontract C {\n    constructor() {\n        assembly {\n            mstore(0, 100)\n            // because this is part of deploy code, the keccak will not be evaluated\n            sstore(0, keccak256(0, 32))\n        }\n    }\n\n    fallback() external {\n        assembly {\n            mstore(0, 100)\n            // The keccak here would be evaluated\n            sstore(0, keccak256(0, 32))\n        }\n\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/keccak_optimization_deploy_code/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_12\" {\n    code {\n        {\n            /// @src 0:62:463  \"contract C {...\"\n            if callvalue() { revert(0, 0) }\n            /// @src 0:103:275  \"assembly {...\"\n            mstore(0, 100)\n            sstore(0, keccak256(0, 32))\n            /// @src 0:62:463  \"contract C {...\"\n            let _1 := datasize(\"C_12_deployed\")\n            codecopy(128, dataoffset(\"C_12_deployed\"), _1)\n            return(128, _1)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_12_deployed\" {\n        code {\n            {\n                /// @src 0:62:463  \"contract C {...\"\n                if callvalue() { revert(0, 0) }\n                /// @src 0:317:454  \"assembly {...\"\n                sstore(0, 17385872270140913825666367956517731270094621555228275961425792378517567244498)\n                /// @src 0:62:463  \"contract C {...\"\n                stop()\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/keccak_optimization_low_runs/args",
    "content": "--ir-optimized --optimize --optimize-runs 1\n"
  },
  {
    "path": "test/cmdlineTests/keccak_optimization_low_runs/err",
    "content": "\n"
  },
  {
    "path": "test/cmdlineTests/keccak_optimization_low_runs/input.sol",
    "content": "// SPDX-License-Identifier: GPL-v3\npragma solidity >= 0.0.0;\n\ncontract C {\n    fallback() external {\n        assembly {\n            mstore(0, 100)\n            // because of the low runs value, the constant will not be optimized\n            sstore(0, keccak256(0, 32))\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/keccak_optimization_low_runs/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_7\" {\n    code {\n        {\n            /// @src 0:62:285  \"contract C {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_7_deployed\")\n            codecopy(_1, dataoffset(\"C_7_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_7_deployed\" {\n        code {\n            {\n                /// @src 0:62:285  \"contract C {...\"\n                if callvalue() { revert(0, 0) }\n                /// @src 0:109:277  \"assembly {...\"\n                mstore(0, 100)\n                sstore(0, keccak256(0, 32))\n                /// @src 0:62:285  \"contract C {...\"\n                stop()\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_no_optimize_yul/args",
    "content": "--no-optimize-yul --link --libraries input.sol:L=0x1234567890123456789012345678901234567890\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_no_optimize_yul/err",
    "content": "Error: Option --no-optimize-yul is only valid in compiler and assembler modes.\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_no_optimize_yul/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_optimize/args",
    "content": "--optimize --link --libraries input.sol:L=0x1234567890123456789012345678901234567890\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_optimize/err",
    "content": "Error: Option --optimize is only valid in compiler and assembler modes.\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_optimize/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_optimize_runs/args",
    "content": "--optimize-runs 1000 --link --libraries input.sol:L=0x1234567890123456789012345678901234567890\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_optimize_runs/err",
    "content": "Error: Option --optimize-runs is only valid in compiler and assembler modes.\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_optimize_runs/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_optimize_yul/args",
    "content": "--optimize-yul --link --libraries input.sol:L=0x1234567890123456789012345678901234567890\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_optimize_yul/err",
    "content": "Error: Option --optimize-yul is only valid in compiler and assembler modes.\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_optimize_yul/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_yul_optimizations/args",
    "content": "--yul-optimizations a --link --libraries input.sol:L=0x1234567890123456789012345678901234567890\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_yul_optimizations/err",
    "content": "Error: Option --yul-optimizations is only valid in compiler and assembler modes.\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_invalid_option_yul_optimizations/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_output_selection_invalid/args",
    "content": "--link --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --hashes --userdoc --devdoc --metadata --storage-layout\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_output_selection_invalid/err",
    "content": "Error: The following outputs are not supported in linker mode: --abi, --asm, --asm-json, --bin, --bin-runtime, --devdoc, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc.\n"
  },
  {
    "path": "test/cmdlineTests/linker_mode_output_selection_invalid/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/linking_qualified_library_name/args",
    "content": "contract1.sol --bin --libraries math.sol:Log:0x7777777777777777777777777777777777777777\n"
  },
  {
    "path": "test/cmdlineTests/linking_qualified_library_name/contract1.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nimport \"math.sol\";\n\ncontract C {\n    function foo() public {\n        Log.log10();\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_qualified_library_name/math.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nlibrary Log {\n    function log10() external {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_qualified_library_name/output",
    "content": "\n======= contract1.sol:C =======\nBinary:\n<BYTECODE REMOVED>\n\n======= math.sol:Log =======\nBinary:\n<BYTECODE REMOVED>\n"
  },
  {
    "path": "test/cmdlineTests/linking_solidity/args",
    "content": "--bin --bin-runtime --libraries input.sol:L=0x1234567890123456789012345678901234567890\n"
  },
  {
    "path": "test/cmdlineTests/linking_solidity/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nlibrary L {\n    function f() external {}\n}\n\ncontract C {\n    function foo() public {\n        L.f();\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_solidity/output",
    "content": "\n======= input.sol:C =======\nBinary:\n<BYTECODE REMOVED>\nBinary of the runtime part:\n<BYTECODE REMOVED>\n\n======= input.sol:L =======\nBinary:\n<BYTECODE REMOVED>\nBinary of the runtime part:\n<BYTECODE REMOVED>\n"
  },
  {
    "path": "test/cmdlineTests/linking_solidity_unresolved_references/args",
    "content": "--bin --bin-runtime --libraries input.sol:L1=0x1234567890123456789012345678901234567890\n"
  },
  {
    "path": "test/cmdlineTests/linking_solidity_unresolved_references/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nlibrary L1 {\n    function f() external {}\n}\n\nlibrary L2 {\n    function f() external {}\n}\n\ncontract C {\n    function foo() public {\n        L1.f();\n        L2.f();\n        L1.f();\n        L2.f();\n        L1.f();\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_solidity_unresolved_references/output",
    "content": "\n======= input.sol:C =======\nBinary:\n<BYTECODE REMOVED>__$a7fb54ac3bf4ba657d4a55d066b3521d62$__<BYTECODE REMOVED>__$a7fb54ac3bf4ba657d4a55d066b3521d62$__<BYTECODE REMOVED>\n\n// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2\n// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2\nBinary of the runtime part:\n<BYTECODE REMOVED>__$a7fb54ac3bf4ba657d4a55d066b3521d62$__<BYTECODE REMOVED>__$a7fb54ac3bf4ba657d4a55d066b3521d62$__<BYTECODE REMOVED>\n\n// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2\n// $a7fb54ac3bf4ba657d4a55d066b3521d62$ -> input.sol:L2\n\n======= input.sol:L1 =======\nBinary:\n<BYTECODE REMOVED>\nBinary of the runtime part:\n<BYTECODE REMOVED>\n\n======= input.sol:L2 =======\nBinary:\n<BYTECODE REMOVED>\nBinary of the runtime part:\n<BYTECODE REMOVED>\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_solidity/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\n\t\t\t\"content\": \"\n\t\t\t\t// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\n\t\t\t\tlibrary L {\n\t\t\t\t\tfunction f() external {}\n\t\t\t\t}\n\n\t\t\t\tcontract C {\n\t\t\t\t\tfunction foo() public {\n\t\t\t\t\t\tL.f();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"libraries\": {\n\t\t\t\"A\": {\n\t\t\t\t\"L\": \"0x1234567890123456789012345678901234567890\"\n\t\t\t}\n\t\t},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"C\": [\"evm.bytecode.object\", \"evm.bytecode.linkReferences\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_solidity/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_solidity_quote_in_file_name/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\\\"B\": {\n\t\t\t\"content\": \"\n\t\t\t\t// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\n\t\t\t\tlibrary L {\n\t\t\t\t\tfunction f() external {}\n\t\t\t\t}\n\n\t\t\t\tcontract C {\n\t\t\t\t\tfunction foo() public {\n\t\t\t\t\t\tL.f();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"libraries\": {\n\t\t\t\"A\\\"B\": {\n\t\t\t\t\"L\": \"0x1234567890123456789012345678901234567890\"\n\t\t\t}\n\t\t},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"C\": [\"evm.bytecode.object\", \"evm.bytecode.linkReferences\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_solidity_quote_in_file_name/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\\\"B\": {\n            \"C\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"A\\\"B\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_solidity_unresolved_references/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\n\t\t\t\"content\": \"\n\t\t\t\t// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\n\t\t\t\tlibrary L1 {\n\t\t\t\t\tfunction f() external {}\n\t\t\t\t}\n\n\t\t\t\tlibrary L2 {\n\t\t\t\t\tfunction f() external {}\n\t\t\t\t}\n\n\t\t\t\tcontract C {\n\t\t\t\t\tfunction foo() public {\n\t\t\t\t\t\tL1.f();\n\t\t\t\t\t\tL2.f();\n\t\t\t\t\t\tL1.f();\n\t\t\t\t\t\tL2.f();\n\t\t\t\t\t\tL1.f();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"libraries\": {\n\t\t\t\"A\": {\n\t\t\t\t\"L1\": \"0x1234567890123456789012345678901234567890\"\n\t\t\t}\n\t\t},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"C\": [\"evm.bytecode.object\", \"evm.bytecode.linkReferences\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_solidity_unresolved_references/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"linkReferences\": {\n                            \"A\": {\n                                \"L2\": [\n                                    {\n                                        \"length\": 20,\n                                        \"start\": 173\n                                    },\n                                    {\n                                        \"length\": 20,\n                                        \"start\": 349\n                                    }\n                                ]\n                            }\n                        },\n                        \"object\": \"<BYTECODE REMOVED>__$622b2f540b6a16ff5db7bea656ad8fcf4f$__<BYTECODE REMOVED>__$622b2f540b6a16ff5db7bea656ad8fcf4f$__<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_yul/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"A\": {\n\t\t\t\"content\": \"object \\\"a\\\" { code { let addr := linkersymbol(\\\"contract/test.sol:L\\\") sstore(0, addr) } }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"libraries\": {\n\t\t\t\"contract/test.sol\": {\n\t\t\t\t\"L\": \"0x1234567890123456789012345678901234567890\"\n\t\t\t}\n\t\t},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"*\": [\"evm.bytecode.object\", \"evm.bytecode.linkReferences\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_yul/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"a\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_yul_quote_in_file_name/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"A\": {\n\t\t\t\"content\": \"object \\\"a\\\" { code { let addr := linkersymbol(\\\"contract/test\\\\\\\".sol:L\\\") sstore(0, addr) } }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"libraries\": {\n\t\t\t\"contract/test\\\".sol\": {\n\t\t\t\t\"L\": \"0x1234567890123456789012345678901234567890\"\n\t\t\t}\n\t\t},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"*\": [\"evm.bytecode.object\", \"evm.bytecode.linkReferences\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_yul_quote_in_file_name/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"a\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_yul_unresolved_references/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"A\": {\n\t\t\t\"content\": \"object \\\"a\\\" { code { let addr1 := linkersymbol(\\\"contract/test.sol:L1\\\") let addr2 := linkersymbol(\\\"contract/test.sol:L2\\\") sstore(0, addr1) sstore(1, addr2) } }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"libraries\": {\n\t\t\t\"contract/test.sol\": {\n\t\t\t\t\"L1\": \"0x1234567890123456789012345678901234567890\"\n\t\t\t}\n\t\t},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"*\": [\"evm.bytecode.object\", \"evm.bytecode.linkReferences\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_standard_yul_unresolved_references/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"a\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"linkReferences\": {\n                            \"contract/test.sol\": {\n                                \"L2\": [\n                                    {\n                                        \"length\": 20,\n                                        \"start\": 22\n                                    }\n                                ]\n                            }\n                        },\n                        \"object\": \"<BYTECODE REMOVED>__$fb58009a6b1ecea3b9d99bedd645df4ec3$__<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly/args",
    "content": "--strict-assembly --libraries contract/test.sol:L=0x1234567890123456789012345678901234567890\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly/input.yul",
    "content": "object \"a\" {\n    code {\n        let addr := linkersymbol(\"contract/test.sol:L\")\n        sstore(0, addr)\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"a\" {\n    code {\n        {\n            let addr := linkersymbol(\"contract/test.sol:L\")\n            sstore(0, addr)\n        }\n    }\n}\n\n\nBinary representation:\n7312345678901234567890123456789012345678905f5500\n\nText representation:\n    /* \"input.yul\":58:93   */\n  linkerSymbol(\"f919ba91ac99f96129544b80b9516b27a80e376b9dc693819d0b18b7e0395612\")\n    /* \"input.yul\":113:114   */\n  0x00\n    /* \"input.yul\":106:121   */\n  sstore\n    /* \"input.yul\":22:137   */\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_duplicate_library_name/args",
    "content": "--strict-assembly --libraries library.sol:L=0x1234567890123456789012345678901234567890,library.sol:L=0x0987654321098765432109876543210987654321\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_duplicate_library_name/err",
    "content": "Error: Address specified more than once for library \"library.sol:L\".\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_duplicate_library_name/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_duplicate_library_name/input.yul",
    "content": "object \"a\" {\n    code {\n        let addr := linkersymbol(\"library.sol:L\")\n        sstore(0, addr)\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/args",
    "content": "--strict-assembly --libraries :L=0x1234567890123456789012345678901234567890 --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/input.yul",
    "content": "object \"a\" {\n    code {\n        let addr := linkersymbol(\":L\")\n        sstore(0, addr)\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_qualified_library_qualified_reference/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"a\" {\n    code {\n        {\n            let addr := linkersymbol(\":L\")\n            sstore(0, addr)\n        }\n    }\n}\n\n\nBinary representation:\n7312345678901234567890123456789012345678905f5500\n\nText representation:\n  linkerSymbol(\"20a18a9bf97d889dcf77111b674da319a4e9e3e05d3f4df9e0bf5c588dd4f0f8\")\n  0x00\n  sstore\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/args",
    "content": "--strict-assembly --libraries :L=0x1234567890123456789012345678901234567890 --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/input.yul",
    "content": "object \"a\" {\n    code {\n        let addr := linkersymbol(\"L\")\n        sstore(0, addr)\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_qualified_library_unqualified_reference/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"a\" {\n    code {\n        {\n            let addr := linkersymbol(\"L\")\n            sstore(0, addr)\n        }\n    }\n}\n\n\nBinary representation:\n73__$8aa64f937099b65a4febc243a5ae0f2d64$__5f5500\n\nText representation:\n  linkerSymbol(\"8aa64f937099b65a4febc243a5ae0f2d6416bb9e473c30dd29c1ee498fb7c5a8\")\n  0x00\n  sstore\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/args",
    "content": "--strict-assembly --libraries library1.sol:L=0x1111111111111111111111111111111111111111,library2.sol:L=0x2222222222222222222222222222222222222222\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/input.yul",
    "content": "object \"a\" {\n    code {\n        let addr1 := linkersymbol(\"library1.sol:L\")\n        let addr2 := linkersymbol(\"library2.sol:L\")\n        sstore(0, addr1)\n        sstore(1, addr2)\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_same_library_name_different_files/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"a\" {\n    code {\n        {\n            let addr1 := linkersymbol(\"library1.sol:L\")\n            let addr2 := linkersymbol(\"library2.sol:L\")\n            sstore(0, addr1)\n            sstore(1, addr2)\n        }\n    }\n}\n\n\nBinary representation:\n731111111111111111111111111111111111111111732222222222222222222222222222222222222222905f5560015500\n\nText representation:\n    /* \"input.yul\":59:89   */\n  linkerSymbol(\"f3ffc10c396a7cc41ae954b050792839d20947bf73497d30c49a9fda1ea477ec\")\n    /* \"input.yul\":115:145   */\n  linkerSymbol(\"c3523432985587641d17c68161d2f700c57aaf4ed21cda4f25d76193c831f97f\")\n    /* \"input.yul\":158:174   */\n  swap1\n    /* \"input.yul\":165:166   */\n  0x00\n    /* \"input.yul\":158:174   */\n  sstore\n    /* \"input.yul\":194:195   */\n  0x01\n    /* \"input.yul\":187:203   */\n  sstore\n    /* \"input.yul\":22:219   */\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/args",
    "content": "--strict-assembly --libraries library1.sol:L=0x1234567890123456789012345678901234567890\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/input.yul",
    "content": "object \"a\" {\n    code {\n        let addr1 := linkersymbol(\"library1.sol:L\")\n        let addr2 := linkersymbol(\"library2.sol:L\")\n        sstore(0, addr1)\n        sstore(1, addr2)\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_same_library_name_different_files_in_link_references/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"a\" {\n    code {\n        {\n            let addr1 := linkersymbol(\"library1.sol:L\")\n            let addr2 := linkersymbol(\"library2.sol:L\")\n            sstore(0, addr1)\n            sstore(1, addr2)\n        }\n    }\n}\n\n\nBinary representation:\n73123456789012345678901234567890123456789073__$c3523432985587641d17c68161d2f700c5$__905f5560015500\n\nText representation:\n    /* \"input.yul\":59:89   */\n  linkerSymbol(\"f3ffc10c396a7cc41ae954b050792839d20947bf73497d30c49a9fda1ea477ec\")\n    /* \"input.yul\":115:145   */\n  linkerSymbol(\"c3523432985587641d17c68161d2f700c57aaf4ed21cda4f25d76193c831f97f\")\n    /* \"input.yul\":158:174   */\n  swap1\n    /* \"input.yul\":165:166   */\n  0x00\n    /* \"input.yul\":158:174   */\n  sstore\n    /* \"input.yul\":194:195   */\n  0x01\n    /* \"input.yul\":187:203   */\n  sstore\n    /* \"input.yul\":22:219   */\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/args",
    "content": "--strict-assembly --libraries L=0x1234567890123456789012345678901234567890 --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/input.yul",
    "content": "object \"a\" {\n    code {\n        let addr := linkersymbol(\":L\")\n        sstore(0, addr)\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_unqualified_library_qualified_reference/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"a\" {\n    code {\n        {\n            let addr := linkersymbol(\":L\")\n            sstore(0, addr)\n        }\n    }\n}\n\n\nBinary representation:\n73__$20a18a9bf97d889dcf77111b674da319a4$__5f5500\n\nText representation:\n  linkerSymbol(\"20a18a9bf97d889dcf77111b674da319a4e9e3e05d3f4df9e0bf5c588dd4f0f8\")\n  0x00\n  sstore\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/args",
    "content": "--strict-assembly --libraries L=0x1234567890123456789012345678901234567890 --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/input.yul",
    "content": "object \"a\" {\n    code {\n        let addr := linkersymbol(\"L\")\n        sstore(0, addr)\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_unqualified_library_unqualified_reference/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"a\" {\n    code {\n        {\n            let addr := linkersymbol(\"L\")\n            sstore(0, addr)\n        }\n    }\n}\n\n\nBinary representation:\n7312345678901234567890123456789012345678905f5500\n\nText representation:\n  linkerSymbol(\"8aa64f937099b65a4febc243a5ae0f2d6416bb9e473c30dd29c1ee498fb7c5a8\")\n  0x00\n  sstore\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_unresolved_references/args",
    "content": "--strict-assembly --libraries contract/test.sol:L1=0x1234567890123456789012345678901234567890\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_unresolved_references/input.yul",
    "content": "object \"a\" {\n    code {\n        let addr1 := linkersymbol(\"contract/test.sol:L1\")\n        let addr2 := linkersymbol(\"contract/test.sol:L2\")\n        sstore(0, addr1)\n        sstore(1, addr2)\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_strict_assembly_unresolved_references/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"a\" {\n    code {\n        {\n            let addr1 := linkersymbol(\"contract/test.sol:L1\")\n            let addr2 := linkersymbol(\"contract/test.sol:L2\")\n            sstore(0, addr1)\n            sstore(1, addr2)\n        }\n    }\n}\n\n\nBinary representation:\n73123456789012345678901234567890123456789073__$fb58009a6b1ecea3b9d99bedd645df4ec3$__905f5560015500\n\nText representation:\n    /* \"input.yul\":59:95   */\n  linkerSymbol(\"05b0326038374a21e0895480a58bda0768cdcc04c8d18f154362d1ca5223d245\")\n    /* \"input.yul\":121:157   */\n  linkerSymbol(\"fb58009a6b1ecea3b9d99bedd645df4ec308f17bc0087e5f39d078f77f809177\")\n    /* \"input.yul\":170:186   */\n  swap1\n    /* \"input.yul\":177:178   */\n  0x00\n    /* \"input.yul\":170:186   */\n  sstore\n    /* \"input.yul\":206:207   */\n  0x01\n    /* \"input.yul\":199:215   */\n  sstore\n    /* \"input.yul\":22:231   */\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/linking_unqualified_library_name/args",
    "content": "contract1.sol contract2.sol --bin --libraries Log:0x7777777777777777777777777777777777777777\n"
  },
  {
    "path": "test/cmdlineTests/linking_unqualified_library_name/contract1.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\n\nimport \"error.sol\";\n\ncontract C {\n    function foo() public {\n        Log.print();\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_unqualified_library_name/contract2.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nimport \"math.sol\";\n\ncontract C {\n    function foo() public {\n        Log.log10();\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_unqualified_library_name/error.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nlibrary Log {\n    function print() external {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_unqualified_library_name/math.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nlibrary Log {\n    function log10() external {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/linking_unqualified_library_name/output",
    "content": "\n======= contract1.sol:C =======\nBinary:\n<BYTECODE REMOVED>__$4a937a7d3d68a205b3b2520e23ccff31ea$__<BYTECODE REMOVED>\n\n// $4a937a7d3d68a205b3b2520e23ccff31ea$ -> error.sol:Log\n\n======= contract2.sol:C =======\nBinary:\n<BYTECODE REMOVED>__$b77e1024bb5d89efefbab5fb1f7cb8fde7$__<BYTECODE REMOVED>\n\n// $b77e1024bb5d89efefbab5fb1f7cb8fde7$ -> math.sol:Log\n\n======= error.sol:Log =======\nBinary:\n<BYTECODE REMOVED>\n\n======= math.sol:Log =======\nBinary:\n<BYTECODE REMOVED>\n"
  },
  {
    "path": "test/cmdlineTests/mcopy_bytes_array_abi_decode/args",
    "content": "--no-cbor-metadata --via-ir --ir --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/mcopy_bytes_array_abi_decode/err",
    "content": "Warning: Statement has no effect.\n --> input.sol:7:9:\n  |\n7 |         abi.decode(\"abcd\", (bytes));\n  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/mcopy_bytes_array_abi_decode/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    function foo() external pure\n    {\n        abi.decode(\"abcd\", (bytes));\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/mcopy_bytes_array_abi_decode/output",
    "content": "IR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_15\" {\n    code {\n\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_15()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_15_deployed\"), datasize(\"C_15_deployed\"))\n\n        return(_1, datasize(\"C_15_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function constructor_C_15() {\n\n        }\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_15_deployed\" {\n        code {\n\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xc2985578\n                {\n                    // foo()\n\n                    external_fun_foo_14()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_foo_14() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                fun_foo_14()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function round_up_to_mul_of_32(value) -> result {\n                result := and(add(value, 31), not(31))\n            }\n\n            function panic_error_0x41() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x41)\n                revert(0, 0x24)\n            }\n\n            function finalize_allocation(memPtr, size) {\n                let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n                // protect against overflow\n                if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n                mstore(64, newFreePtr)\n            }\n\n            function allocate_memory(size) -> memPtr {\n                memPtr := allocate_unbounded()\n                finalize_allocation(memPtr, size)\n            }\n\n            function array_allocation_size_t_string_memory_ptr(length) -> size {\n                // Make sure we can allocate memory without overflow\n                if gt(length, 0xffffffffffffffff) { panic_error_0x41() }\n\n                size := round_up_to_mul_of_32(length)\n\n                // add length slot\n                size := add(size, 0x20)\n\n            }\n\n            function allocate_memory_array_t_string_memory_ptr(length) -> memPtr {\n                let allocSize := array_allocation_size_t_string_memory_ptr(length)\n                memPtr := allocate_memory(allocSize)\n\n                mstore(memPtr, length)\n\n            }\n\n            function store_literal_in_memory_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77(memPtr) {\n\n                mstore(add(memPtr, 0), \"abcd\")\n\n            }\n\n            function copy_literal_to_memory_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77() -> memPtr {\n                memPtr := allocate_memory_array_t_string_memory_ptr(4)\n                store_literal_in_memory_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77(add(memPtr, 32))\n            }\n\n            function convert_t_stringliteral_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77_to_t_bytes_memory_ptr() -> converted {\n                converted := copy_literal_to_memory_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77()\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() {\n                revert(0, 0)\n            }\n\n            function revert_error_987264b3b1d58a9c7f8255e93e81c77d86d6299019c33110a076957a3e06e2ae() {\n                revert(0, 0)\n            }\n\n            function array_allocation_size_t_bytes_memory_ptr(length) -> size {\n                // Make sure we can allocate memory without overflow\n                if gt(length, 0xffffffffffffffff) { panic_error_0x41() }\n\n                size := round_up_to_mul_of_32(length)\n\n                // add length slot\n                size := add(size, 0x20)\n\n            }\n\n            function copy_memory_to_memory_with_cleanup(src, dst, length) {\n\n                mcopy(dst, src, length)\n                mstore(add(dst, length), 0)\n\n            }\n\n            function abi_decode_available_length_t_bytes_memory_ptr_fromMemory(src, length, end) -> array {\n                array := allocate_memory(array_allocation_size_t_bytes_memory_ptr(length))\n                mstore(array, length)\n                let dst := add(array, 0x20)\n                if gt(add(src, length), end) { revert_error_987264b3b1d58a9c7f8255e93e81c77d86d6299019c33110a076957a3e06e2ae() }\n                copy_memory_to_memory_with_cleanup(src, dst, length)\n            }\n\n            // bytes\n            function abi_decode_t_bytes_memory_ptr_fromMemory(offset, end) -> array {\n                if iszero(slt(add(offset, 0x1f), end)) { revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() }\n                let length := mload(offset)\n                array := abi_decode_available_length_t_bytes_memory_ptr_fromMemory(add(offset, 0x20), length, end)\n            }\n\n            function abi_decode_tuple_t_bytes_memory_ptr_fromMemory(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := mload(add(headStart, 0))\n                    if gt(offset, 0xffffffffffffffff) { revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() }\n\n                    value0 := abi_decode_t_bytes_memory_ptr_fromMemory(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function array_length_t_bytes_memory_ptr(value) -> length {\n\n                length := mload(value)\n\n            }\n\n            function fun_foo_14() {\n\n                let _1_mpos := convert_t_stringliteral_48bed44d1bcd124a28c27f343a817e5f5243190d3c52bf347daf876de1dbbf77_to_t_bytes_memory_ptr()\n\n                let expr_11_mpos :=  abi_decode_tuple_t_bytes_memory_ptr_fromMemory(add(_1_mpos, 32), add(add(_1_mpos, 32), array_length_t_bytes_memory_ptr(_1_mpos)))\n\n            }\n\n        }\n\n        data \".metadata\" hex\"\"\n    }\n\n}\n"
  },
  {
    "path": "test/cmdlineTests/mcopy_bytes_array_returned_from_function/args",
    "content": "--no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/mcopy_bytes_array_returned_from_function/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    function foo() external pure returns (bytes memory)\n    {\n        bytes memory ret = \"aaaaa\";\n        return ret;\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/mcopy_bytes_array_returned_from_function/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_14\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_14_deployed\")\n            codecopy(_1, dataoffset(\"C_14_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_14_deployed\" {\n        code {\n            {\n                let _1 := memoryguard(0x80)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0xc2985578, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let newFreePtr := add(_1, 64)\n                        if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _1))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 36)\n                        }\n                        mstore(64, newFreePtr)\n                        mstore(_1, 5)\n                        let _2 := add(_1, 32)\n                        mstore(_2, \"aaaaa\")\n                        let memPos := mload(64)\n                        mstore(memPos, 32)\n                        let length := mload(_1)\n                        mstore(add(memPos, 32), length)\n                        mcopy(add(memPos, 64), _2, length)\n                        mstore(add(add(memPos, length), 64), 0)\n                        return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), 64))\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/mcopy_string_literal_returned_from_function/args",
    "content": "--no-cbor-metadata --via-ir --optimize --ir-optimized --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/mcopy_string_literal_returned_from_function/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C {\n    function foo() external pure returns (string memory)\n    {\n        return \"MCOPY on Cancun vacation.\";\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/mcopy_string_literal_returned_from_function/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_10\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_10_deployed\")\n            codecopy(_1, dataoffset(\"C_10_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_10_deployed\" {\n        code {\n            {\n                let _1 := memoryguard(0x80)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0xc2985578, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let newFreePtr := add(_1, 64)\n                        if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _1))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 0x24)\n                        }\n                        mstore(64, newFreePtr)\n                        mstore(_1, 25)\n                        let _2 := add(_1, 32)\n                        mstore(_2, \"MCOPY on Cancun vacation.\")\n                        let memPos := mload(64)\n                        mstore(memPos, 32)\n                        let length := mload(_1)\n                        mstore(add(memPos, 32), length)\n                        mcopy(add(memPos, 64), _2, length)\n                        mstore(add(add(memPos, length), 64), 0)\n                        return(memPos, add(sub(add(memPos, and(add(length, 31), not(31))), memPos), 64))\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/args",
    "content": "--ir --debug-info none"
  },
  {
    "path": "test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {\n        // NOTE: memoryguard is a builtin but only in pure Yul, not inline assembly.\n        // NOTE: memoryguard is not a reserved identifier.\n        // The expectation of this test is to not see the shadowed memoryguard within the generated Yul code but rather\n        // a mangled version of it\n        assembly { function memoryguard() {} }\n        assembly { function f(memoryguard) {} }\n        assembly { function f() -> memoryguard {} }\n        assembly { let memoryguard }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/memoryguard_shadowing_by_inline_assembly_identifiers/output",
    "content": "IR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_10\" {\n    code {\n\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_10()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_10_deployed\"), datasize(\"C_10_deployed\"))\n\n        return(_1, datasize(\"C_10_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function constructor_C_10() {\n\n        }\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_10_deployed\" {\n        code {\n\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_9()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_9() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                fun_f_9()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function fun_f_9() {\n\n                {\n                    function usr$memoryguard()\n                    { }\n                }\n\n                {\n                    function usr$f(usr$memoryguard)\n                    { }\n                }\n\n                {\n                    function usr$f() -> usr$memoryguard\n                    { }\n                }\n\n                { let usr$memoryguard }\n\n            }\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n"
  },
  {
    "path": "test/cmdlineTests/message_format/err",
    "content": "Warning: Source file does not specify required compiler version!\n--> input.sol\n\nWarning: Unused local variable.\n --> input.sol:9:27:\n  |\n9 |     function f() public { int x; }\n  |                           ^^^^^\n\nWarning: Unused local variable.\n  --> input.sol:10:27:\n   |\n10 |     function g() public { int x; }\n   |                           ^^^^^\n\nWarning: Unused local variable.\n  --> input.sol:99:14:\n   |\n99 |         /**/ int a; /**/\n   |              ^^^^^\n\nWarning: Unused local variable.\n   --> input.sol:100:14:\n    |\n100 |         /**/ int b; /**/\n    |              ^^^^^\n\nWarning: Unused local variable.\n   --> input.sol:101:14:\n    |\n101 |         /**/ int c; /**/\n    |              ^^^^^\n\nWarning: Function state mutability can be restricted to pure\n --> input.sol:9:5:\n  |\n9 |     function f() public { int x; }\n  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning: Function state mutability can be restricted to pure\n  --> input.sol:10:5:\n   |\n10 |     function g() public { int x; }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning: Function state mutability can be restricted to pure\n  --> input.sol:11:5:\n   |\n11 |     function h() public {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n"
  },
  {
    "path": "test/cmdlineTests/message_format/input.sol",
    "content": "// checks that error messages around power-or-10 lines are formatted correctly\n// SPDX-License-Identifier: GPL-3.0\n\n\n\n\n\ncontract C {\n    function f() public { int x; }\n    function g() public { int x; }\n    function h() public {\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n        /**/ int a; /**/\n        /**/ int b; /**/\n        /**/ int c; /**/\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/message_format_utf8/err",
    "content": "Warning: Statement has no effect.\n --> input.sol:5:51:\n  |\n5 | /* ©©©©ﾩ©©©©© 2017 */ constructor () { unicode\"©©©©ﾩ©©©©©\" ; }\n  |                                        ^^^^^^^^^^^^^^^^^^^\n\nWarning: Statement has no effect.\n --> input.sol:9:25:\n  |\n9 |                         unicode\"S = π × r²\";\n  |                         ^^^^^^^^^^^^^^^^^^^\n\nWarning: Statement has no effect.\n  --> input.sol:10:39:\n   |\n10 | /* ₀₁₂₃₄⁵⁶⁷⁸⁹ */\t\tunicode\"∑ 1/n! ≈ 2.7\";                 // tabs in-between\n   |                 \t\t^^^^^^^^^^^^^^^^^^^^^\n\nWarning: Statement has no effect.\n  --> input.sol:11:30:\n   |\n11 | /* Ŀŏŗėɯ ïƥŝʉɱ */\t\tunicode\"μὴ\t\tχεῖρον\t\tβέλτιστον\"; // tabs in-between and inside\n   |                  \t\t^^^^^^^^^^\t\t^^^^^^\t\t^^^^^^^^^^\n\nWarning: Function state mutability can be restricted to pure\n  --> input.sol:15:2:\n   |\n15 | \tfunction selector() public returns(uint) { // starts with tab\n   | \t^ (Relevant source part starts here and spans across multiple lines).\n"
  },
  {
    "path": "test/cmdlineTests/message_format_utf8/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract Foo {\n/* ©©©©ﾩ©©©©© 2017 */ constructor () { unicode\"©©©©ﾩ©©©©©\" ; }\n\n    function f() public pure {\n\n                        unicode\"S = π × r²\";\n/* ₀₁₂₃₄⁵⁶⁷⁸⁹ */\t\tunicode\"∑ 1/n! ≈ 2.7\";                 // tabs in-between\n/* Ŀŏŗėɯ ïƥŝʉɱ */\t\tunicode\"μὴ\t\tχεῖρον\t\tβέλτιστον\"; // tabs in-between and inside\n\n    }\n\n\tfunction selector() public returns(uint) { // starts with tab\n\t\treturn 0;\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/metadata/args",
    "content": "--metadata\n"
  },
  {
    "path": "test/cmdlineTests/metadata/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/metadata/output",
    "content": "\n======= input.sol:C =======\nMetadata:\n{\"compiler\":{\"version\": \"<VERSION REMOVED>\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"input.sol\":\"C\"},\"evmVersion\":\"osaka\",\"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}\n"
  },
  {
    "path": "test/cmdlineTests/metadata_experimental/args",
    "content": "--metadata --experimental --via-ir --ethdebug --no-cbor-metadata --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/metadata_experimental/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/metadata_experimental/output",
    "content": "======= Debug Data (ethdebug/format/info/resources) =======\n{\n    \"compilation\": {\n        \"compiler\": {\n            \"name\": \"solc\",\n            \"version\": \"<VERSION REMOVED>\"\n        },\n        \"sources\": [\n            {\n                \"id\": 0,\n                \"path\": \"input.sol\"\n            }\n        ]\n    }\n}\n\n======= input.sol:C =======\nMetadata:\n{\"compiler\":{\"version\": \"<VERSION REMOVED>\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"input.sol\":\"C\"},\"evmVersion\":\"osaka\",\"experimental\":true,\"libraries\":{},\"metadata\":{\"appendCBOR\":false,\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[],\"viaIR\":true},\"sources\":{\"input.sol\":{\"keccak256\":\"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2\",\"dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS\"]}},\"version\":1}\nDebug Data (ethdebug/format/program):\n{\n    \"contract\": {\n        \"definition\": {\n            \"source\": {\n                \"id\": 0\n            }\n        },\n        \"name\": \"C\"\n    },\n    \"environment\": \"create\",\n    \"instructions\": [\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 0,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x80\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 2,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x40\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 4,\n            \"operation\": {\n                \"mnemonic\": \"MSTORE\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 5,\n            \"operation\": {\n                \"mnemonic\": \"CALLVALUE\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 6,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x19\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 8,\n            \"operation\": {\n                \"mnemonic\": \"JUMPI\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 9,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x0e\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 11,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x1d\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 13,\n            \"operation\": {\n                \"mnemonic\": \"JUMP\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 14,\n            \"operation\": {\n                \"mnemonic\": \"JUMPDEST\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 15,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x08\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 17,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x28\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 19,\n            \"operation\": {\n                \"mnemonic\": \"DUP3\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 20,\n            \"operation\": {\n                \"mnemonic\": \"CODECOPY\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 21,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x08\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 23,\n            \"operation\": {\n                \"mnemonic\": \"SWAP1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 24,\n            \"operation\": {\n                \"mnemonic\": \"RETURN\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 25,\n            \"operation\": {\n                \"mnemonic\": \"JUMPDEST\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 26,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x23\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 28,\n            \"operation\": {\n                \"mnemonic\": \"JUMP\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 29,\n            \"operation\": {\n                \"mnemonic\": \"JUMPDEST\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 30,\n            \"operation\": {\n                \"arguments\": [\n                    \"0x40\"\n                ],\n                \"mnemonic\": \"PUSH1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 32,\n            \"operation\": {\n                \"mnemonic\": \"MLOAD\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 33,\n            \"operation\": {\n                \"mnemonic\": \"SWAP1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 34,\n            \"operation\": {\n                \"mnemonic\": \"JUMP\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 35,\n            \"operation\": {\n                \"mnemonic\": \"JUMPDEST\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 36,\n            \"operation\": {\n                \"mnemonic\": \"PUSH0\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 37,\n            \"operation\": {\n                \"mnemonic\": \"DUP1\"\n            }\n        },\n        {\n            \"context\": {\n                \"code\": {\n                    \"range\": {\n                        \"length\": 13,\n                        \"offset\": 56\n                    },\n                    \"source\": {\n                        \"id\": 0\n                    }\n                }\n            },\n            \"offset\": 38,\n            \"operation\": {\n                \"mnemonic\": \"REVERT\"\n            }\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/metadata_via_ssa_cfg/args",
    "content": "--metadata --experimental --via-ssa-cfg\n"
  },
  {
    "path": "test/cmdlineTests/metadata_via_ssa_cfg/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/metadata_via_ssa_cfg/output",
    "content": "\n======= input.sol:C =======\nMetadata:\n{\"compiler\":{\"version\": \"<VERSION REMOVED>\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"input.sol\":\"C\"},\"evmVersion\":\"osaka\",\"experimental\":true,\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[],\"viaIR\":true,\"viaSSACFG\":true},\"sources\":{\"input.sol\":{\"keccak256\":\"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2\",\"dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS\"]}},\"version\":1}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_bmc_loop_iterations/args",
    "content": "--model-checker-engine bmc --model-checker-bmc-loop-iterations 3"
  },
  {
    "path": "test/cmdlineTests/model_checker_bmc_loop_iterations/err",
    "content": "Warning: BMC: Assertion violation happens here.\n  --> input.sol:10:3:\n   |\n10 | \t\tassert(x == 3);\n   | \t\t^^^^^^^^^^^^^^\nNote: Counterexample:\n  x = 2\n\nNote: Callstack:\nNote: False negatives are possible when unrolling loops.\nThis is due to the possibility that the BMC loop iteration setting is smaller than the actual number of iterations needed to complete a loop.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_bmc_loop_iterations/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\tdo {\n\t\t\t++x;\n\t\t} while (x < 2);\n\t\tassert(x == 3);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_bmc_loop_iterations_invalid_arg/args",
    "content": "--model-checker-engine bmc --model-checker-bmc-loop-iterations bmc"
  },
  {
    "path": "test/cmdlineTests/model_checker_bmc_loop_iterations_invalid_arg/err",
    "content": "Error: the argument ('bmc') for option '--model-checker-bmc-loop-iterations' is invalid\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_bmc_loop_iterations_invalid_arg/exit",
    "content": "1"
  },
  {
    "path": "test/cmdlineTests/model_checker_bmc_loop_iterations_invalid_arg/input.sol",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/args",
    "content": "--model-checker-engine bmc --model-checker-bmc-loop-iterations"
  },
  {
    "path": "test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/err",
    "content": "Error: the argument ('input.sol') for option '--model-checker-bmc-loop-iterations' is invalid\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/exit",
    "content": "1"
  },
  {
    "path": "test/cmdlineTests/model_checker_bmc_loop_iterations_no_argument/input.sol",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_all/args",
    "content": "--model-checker-engine all\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_all/err",
    "content": "Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nB.constructor()\nB.f(0)\n --> input.sol:5:9:\n  |\n5 |         assert(x > 0);\n  |         ^^^^^^^^^^^^^\n\nWarning: CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0\n\nTransaction trace:\nA.constructor()\nA.g(0)\n  --> input.sol:10:9:\n   |\n10 |         assert(y > 0);\n   |         ^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_all/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract B {\n    function f(uint x) public pure {\n        assert(x > 0);\n    }\n}\ncontract A is B {\n    function g(uint y) public pure {\n        assert(y > 0);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_all_explicit/args",
    "content": "--model-checker-engine all --model-checker-contracts input.sol:B,input.sol:A\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_all_explicit/err",
    "content": "Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nB.constructor()\nB.f(0)\n --> input.sol:5:3:\n  |\n5 | \t\tassert(x > 0);\n  | \t\t^^^^^^^^^^^^^\n\nWarning: CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0\n\nTransaction trace:\nA.constructor()\nA.g(0)\n  --> input.sol:10:3:\n   |\n10 | \t\tassert(y > 0);\n   | \t\t^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_all_explicit/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract B {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}\ncontract A is B {\n    function g(uint y) public pure {\n\t\tassert(y > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_contract_missing/args",
    "content": "--model-checker-engine all --model-checker-contracts model_checker_contracts_inexistent_contract/input.sol:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_contract_missing/err",
    "content": "Error: Invalid option for --model-checker-contracts: model_checker_contracts_inexistent_contract/input.sol:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_contract_missing/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_contract_missing/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract B {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}\ncontract A is B {\n    function g(uint y) public pure {\n\t\tassert(y > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_empty_contract/args",
    "content": "--model-checker-engine all --model-checker-contracts a.sol:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_empty_contract/err",
    "content": "Error: Invalid option for --model-checker-contracts: a.sol:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_empty_contract/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_empty_contract/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract B {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}\ncontract A is B {\n    function g(uint y) public pure {\n\t\tassert(y > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_empty_source/args",
    "content": "--model-checker-engine all --model-checker-contracts :A\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_empty_source/err",
    "content": "Error: Invalid option for --model-checker-contracts: :A\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_empty_source/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_empty_source/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract B {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}\ncontract A is B {\n    function g(uint y) public pure {\n\t\tassert(y > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_inexistent_contract/args",
    "content": "--model-checker-engine all --model-checker-contracts input.sol:C\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_inexistent_contract/err",
    "content": "Warning: Requested contract \"C\" does not exist in source \"input.sol\".\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_inexistent_contract/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract B {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}\ncontract A is B {\n    function g(uint y) public pure {\n\t\tassert(y > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_inexistent_source/args",
    "content": "--model-checker-engine all --model-checker-contracts A.sol:A\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_inexistent_source/err",
    "content": "Warning: Requested source \"A.sol\" does not exist.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_inexistent_source/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract B {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}\ncontract A is B {\n    function g(uint y) public pure {\n\t\tassert(y > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_one_contract_missing/args",
    "content": "--model-checker-engine all --model-checker-contracts input.sol:,input.sol:A\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_one_contract_missing/err",
    "content": "Error: Invalid option for --model-checker-contracts: input.sol:,input.sol:A\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_one_contract_missing/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_one_contract_missing/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract B {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}\ncontract A is B {\n    function g(uint y) public pure {\n\t\tassert(y > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_only_one/args",
    "content": "--model-checker-engine all --model-checker-contracts input.sol:A\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_only_one/err",
    "content": "Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nA.constructor()\nB.f(0)\n --> input.sol:5:3:\n  |\n5 | \t\tassert(x > 0);\n  | \t\t^^^^^^^^^^^^^\n\nWarning: CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0\n\nTransaction trace:\nA.constructor()\nA.g(0)\n  --> input.sol:10:3:\n   |\n10 | \t\tassert(y > 0);\n   | \t\t^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_only_one/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract B {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}\ncontract A is B {\n    function g(uint y) public pure {\n\t\tassert(y > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_source_missing/args",
    "content": "--model-checker-engine all --model-checker-contracts :C\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_source_missing/err",
    "content": "Error: Invalid option for --model-checker-contracts: :C\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_source_missing/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_contracts_source_missing/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract B {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}\ncontract A is B {\n    function g(uint y) public pure {\n\t\tassert(y > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_default_all/args",
    "content": "--model-checker-engine all\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_default_all/err",
    "content": "Info: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_default_all/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\trequire(b != 0);\n\t\treturn (a / b, a % b);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_default_bmc/args",
    "content": "--model-checker-engine bmc\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_default_bmc/err",
    "content": "Info: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_default_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\trequire(b != 0);\n\t\treturn (a / b, a % b);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_default_chc/args",
    "content": "--model-checker-engine chc\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_default_chc/err",
    "content": "Info: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_default_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\trequire(b != 0);\n\t\treturn (a / b, a % b);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_false_all/args",
    "content": "--model-checker-engine all --model-checker-div-mod-no-slacks\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_false_all/err",
    "content": "Warning: CHC: 2 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\nInfo: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_false_all/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\trequire(b != 0);\n\t\treturn (a / b, a % b);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_false_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-div-mod-no-slacks\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_false_bmc/err",
    "content": "Info: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_false_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\trequire(b != 0);\n\t\treturn (a / b, a % b);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_false_chc/args",
    "content": "--model-checker-engine chc --model-checker-div-mod-no-slacks\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_false_chc/err",
    "content": "Warning: CHC: 2 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_divModSlacks_false_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\trequire(b != 0);\n\t\treturn (a / b, a % b);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_engine_all/args",
    "content": "--model-checker-engine all\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_engine_all/err",
    "content": "Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\ntest.constructor()\ntest.f(0)\n --> input.sol:5:3:\n  |\n5 | \t\tassert(x > 0);\n  | \t\t^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_engine_all/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_engine_bmc/args",
    "content": "--model-checker-engine bmc\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_engine_bmc/err",
    "content": "Warning: BMC: Assertion violation happens here.\n --> input.sol:5:3:\n  |\n5 | \t\tassert(x > 0);\n  | \t\t^^^^^^^^^^^^^\nNote: Counterexample:\n  x = 0\n\nNote: Callstack:\nNote:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_engine_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_engine_chc/args",
    "content": "--model-checker-engine chc\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_engine_chc/err",
    "content": "Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\ntest.constructor()\ntest.f(0)\n --> input.sol:5:3:\n  |\n5 | \t\tassert(x > 0);\n  | \t\t^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_engine_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n    function f(uint x) public pure {\n\t\tassert(x > 0);\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_engine_none/args",
    "content": "--model-checker-engine none\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_engine_none/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test {\n\tfunction f(uint x) public pure {\n\t\tassert(x > 0);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_empty_arg/args",
    "content": "--model-checker-engine chc --model-checker-ext-calls\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_empty_arg/err",
    "content": "Error: No input files given. If you wish to use the standard input please specify \"-\" explicitly.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_empty_arg/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_empty_arg/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract Ext {\n\tfunction f() public view returns (uint) {\n\t\treturn 42;\n\t}\n}\n\ncontract test {\n\tfunction g(Ext e) public view {\n\t\tuint x = e.f();\n\t\tassert(x == 42);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_trusted_chc/args",
    "content": "--model-checker-engine chc --model-checker-ext-calls trusted\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_trusted_chc/err",
    "content": "Warning: Function state mutability can be restricted to pure\n --> input.sol:5:2:\n  |\n5 | \tfunction f() public view returns (uint) {\n  | \t^ (Relevant source part starts here and spans across multiple lines).\n\nInfo: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_trusted_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract Ext {\n\tfunction f() public view returns (uint) {\n\t\treturn 42;\n\t}\n}\n\ncontract test {\n\tfunction g(Ext e) public view {\n\t\tuint x = e.f();\n\t\tassert(x == 42);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_untrusted_chc/args",
    "content": "--model-checker-engine chc --model-checker-ext-calls untrusted\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_untrusted_chc/err",
    "content": "Warning: CHC: Assertion violation happens here.\nCounterexample:\n\ne = 0\nx = 1\n\nTransaction trace:\ntest.constructor()\ntest.g(0)\n    e.f() -- untrusted external call\n  --> input.sol:11:3:\n   |\n11 | \t\tassert(x == 0);\n   | \t\t^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_untrusted_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nabstract contract Ext {\n\tfunction f() virtual public view returns (uint);\n}\n\ncontract test {\n\tfunction g(Ext e) public view {\n\t\tuint x = e.f();\n\t\tassert(x == 0);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_wrong_arg/args",
    "content": "--model-checker-engine chc --model-checker-ext-calls what\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_wrong_arg/err",
    "content": "Error: Invalid option for --model-checker-ext-calls: what\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_wrong_arg/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_ext_calls_wrong_arg/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract Ext {\n\tfunction f() public view returns (uint) {\n\t\treturn 42;\n\t}\n}\n\ncontract test {\n\tfunction g(Ext e) public view {\n\t\tuint x = e.f();\n\t\tassert(x == 42);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_all/args",
    "content": "--model-checker-engine chc --model-checker-invariants all\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_all/err",
    "content": "Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n\nInfo: Contract invariant(s) for input.sol:test:\n(true || !(x >= 1))\nReentrancy property(ies) for input.sol:test:\n(((<errorCode> = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true)\n<errorCode> = 0 -> no errors\n<errorCode> = 1 -> Assertion failed at assert(x == 0)\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_all/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint x;\n\tfunction f() public view {\n\t\tassert(x == 0);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_contract/args",
    "content": "--model-checker-engine chc --model-checker-invariants contract\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_contract/err",
    "content": "Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n\nInfo: Contract invariant(s) for input.sol:test:\n(true || !(x >= 1))\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_contract/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint x;\n\tfunction f() public view {\n\t\tassert(x == 0);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_contract_eld/args",
    "content": "--model-checker-engine chc --model-checker-invariants contract --model-checker-solvers eld\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_contract_eld/err",
    "content": "Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n\nInfo: Contract invariant(s) for input.sol:test:\n(x = 0)\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_contract_eld/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint x;\n\tfunction f() public view {\n\t\tassert(x < 10);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_contract_reentrancy/args",
    "content": "--model-checker-engine chc --model-checker-invariants contract,reentrancy\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_contract_reentrancy/err",
    "content": "Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n\nInfo: Contract invariant(s) for input.sol:test:\n(true || !(x >= 1))\nReentrancy property(ies) for input.sol:test:\n(((<errorCode> = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true)\n<errorCode> = 0 -> no errors\n<errorCode> = 1 -> Assertion failed at assert(x == 0)\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_contract_reentrancy/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint x;\n\tfunction f() public view {\n\t\tassert(x == 0);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_reentrancy/args",
    "content": "--model-checker-engine chc --model-checker-invariants reentrancy\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_reentrancy/err",
    "content": "Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n\nInfo: Reentrancy property(ies) for input.sol:test:\n(((<errorCode> = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true)\n<errorCode> = 0 -> no errors\n<errorCode> = 1 -> Assertion failed at assert(x == 0)\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_reentrancy/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint x;\n\tfunction f() public view {\n\t\tassert(x == 0);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_wrong/args",
    "content": "--model-checker-engine chc --model-checker-invariants what\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_wrong/err",
    "content": "Error: Invalid option for --model-checker-invariants: what\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_wrong/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_invariants_wrong/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint x;\n\tfunction g() public view {\n\t\tassert(x < 10);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_print_query_all/args",
    "content": "--model-checker-engine all --model-checker-print-query --model-checker-solvers smtlib2 --model-checker-timeout 1000\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_print_query_all/err",
    "content": "Info: CHC: Requested query:\n(set-option :timeout 1000)\n(set-logic HORN)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool)\n(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool)\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int))\n(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))\n)\n(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))\n)\n(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))\n)\n(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int))\n(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |error_target_3| () Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))\n)(assert\n(forall ((UNUSED Bool))\n(=> error_target_3 false)))\n(check-sat)\n\n\nWarning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\nInfo: BMC: Requested query:\n(set-option :produce-models true)\n(set-option :timeout 1000)\n(set-logic ALL)\n(declare-fun |x_5_3| () Int)\n(declare-fun |error_0| () Int)\n(declare-fun |this_0| () Int)\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |tx_0| () |tx_type|)\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-fun |crypto_0| () |crypto_type|)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-fun |abi_0| () |abi_type|)\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |state_0| () |state_type|)\n(declare-fun |x_5_4| () Int)\n(declare-fun |x_5_0| () Int)\n(declare-fun |expr_6_0| () Int)\n(declare-fun |x_5_1| () Int)\n(declare-fun |expr_9_0| () Int)\n(declare-fun |expr_10_0| () Int)\n(declare-fun |expr_11_1| () Bool)\n(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1)))\n(declare-const |EVALEXPR_0| Int)\n(assert (= |EVALEXPR_0| x_5_1))\n(check-sat)\n(get-value (|EVALEXPR_0| ))\n\n\nWarning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_print_query_all/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C\n{\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tassert(x == 0);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_print_query_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-print-query --model-checker-solvers smtlib2\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_print_query_bmc/err",
    "content": "Info: BMC: Requested query:\n(set-option :produce-models true)\n(set-logic ALL)\n(declare-fun |error_0| () Int)\n(declare-fun |this_0| () Int)\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |tx_0| () |tx_type|)\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-fun |crypto_0| () |crypto_type|)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-fun |abi_0| () |abi_type|)\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |state_0| () |state_type|)\n(declare-fun |x_5_0| () Int)\n(declare-fun |expr_6_0| () Int)\n(declare-fun |x_5_1| () Int)\n(declare-fun |expr_9_0| () Int)\n(declare-fun |expr_10_0| () Int)\n(declare-fun |expr_11_1| () Bool)\n(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1)))\n(declare-const |EVALEXPR_0| Int)\n(assert (= |EVALEXPR_0| x_5_1))\n(check-sat)\n(get-value (|EVALEXPR_0| ))\n\n\nWarning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_print_query_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C\n{\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tassert(x == 0);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_print_query_chc/args",
    "content": "--model-checker-engine chc --model-checker-print-query --model-checker-solvers smtlib2 --model-checker-timeout 1000\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_print_query_chc/err",
    "content": "Info: CHC: Requested query:\n(set-option :timeout 1000)\n(set-logic HORN)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool)\n(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool)\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int))\n(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))\n)\n(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))\n)\n(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))\n)\n(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int))\n(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |error_target_3| () Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))\n)(assert\n(forall ((UNUSED Bool))\n(=> error_target_3 false)))\n(check-sat)\n\n\nWarning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_print_query_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C\n{\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tassert(x == 0);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_default_all_engines/args",
    "content": "--model-checker-engine all\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_default_all_engines/err",
    "content": "Warning: Function state mutability can be restricted to pure\n --> input.sol:4:5:\n  |\n4 |     function f(uint8 x) public {\n  |     ^ (Relevant source part starts here and spans across multiple lines).\n\nInfo: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_default_all_engines/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f(uint8 x) public {\n        assert(x >= 0);\n        assert(x < 1000);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_default_bmc/args",
    "content": "--model-checker-engine bmc\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_default_bmc/err",
    "content": "Warning: Function state mutability can be restricted to pure\n --> input.sol:4:5:\n  |\n4 |     function f(uint8 x) public {\n  |     ^ (Relevant source part starts here and spans across multiple lines).\n\nInfo: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_default_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f(uint8 x) public {\n        assert(x >= 0);\n        assert(x < 1000);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_default_chc/args",
    "content": "--model-checker-engine chc\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_default_chc/err",
    "content": "Warning: Function state mutability can be restricted to pure\n --> input.sol:4:5:\n  |\n4 |     function f(uint8 x) public {\n  |     ^ (Relevant source part starts here and spans across multiple lines).\n\nInfo: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_default_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f(uint8 x) public {\n        assert(x >= 0);\n        assert(x < 1000);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_true_all_engines/args",
    "content": "--model-checker-engine all --model-checker-show-proved-safe\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_true_all_engines/err",
    "content": "Warning: Function state mutability can be restricted to pure\n --> input.sol:4:5:\n  |\n4 |     function f(uint8 x) public {\n  |     ^ (Relevant source part starts here and spans across multiple lines).\n\nInfo: CHC: Assertion violation check is safe!\n --> input.sol:5:9:\n  |\n5 |         assert(x >= 0);\n  |         ^^^^^^^^^^^^^^\n\nInfo: CHC: Assertion violation check is safe!\n --> input.sol:6:9:\n  |\n6 |         assert(x < 1000);\n  |         ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_true_all_engines/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f(uint8 x) public {\n        assert(x >= 0);\n        assert(x < 1000);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_true_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-show-proved-safe\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_true_bmc/err",
    "content": "Warning: Function state mutability can be restricted to pure\n --> input.sol:4:5:\n  |\n4 |     function f(uint8 x) public {\n  |     ^ (Relevant source part starts here and spans across multiple lines).\n\nInfo: BMC: Assertion violation check is safe!\n --> input.sol:5:9:\n  |\n5 |         assert(x >= 0);\n  |         ^^^^^^^^^^^^^^\n\nInfo: BMC: Assertion violation check is safe!\n --> input.sol:6:9:\n  |\n6 |         assert(x < 1000);\n  |         ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_true_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f(uint8 x) public {\n        assert(x >= 0);\n        assert(x < 1000);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_true_chc/args",
    "content": "--model-checker-engine chc --model-checker-show-proved-safe\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_true_chc/err",
    "content": "Warning: Function state mutability can be restricted to pure\n --> input.sol:4:5:\n  |\n4 |     function f(uint8 x) public {\n  |     ^ (Relevant source part starts here and spans across multiple lines).\n\nInfo: CHC: Assertion violation check is safe!\n --> input.sol:5:9:\n  |\n5 |         assert(x >= 0);\n  |         ^^^^^^^^^^^^^^\n\nInfo: CHC: Assertion violation check is safe!\n --> input.sol:6:9:\n  |\n6 |         assert(x < 1000);\n  |         ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_proved_safe_true_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f(uint8 x) public {\n        assert(x >= 0);\n        assert(x < 1000);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_default_all_engines/args",
    "content": "--model-checker-engine all\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_default_all_engines/err",
    "content": "Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\nInfo: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_default_all_engines/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    struct S {\n        uint x;\n    }\n    S s;\n    function f(bool b) public {\n        s.x |= b ? 1 : 2;\n        assert(s.x > 0);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_default_bmc/args",
    "content": "--model-checker-engine bmc\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_default_bmc/err",
    "content": "Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_default_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    struct S {\n        uint x;\n    }\n    S s;\n    function f(bool b) public {\n        s.x |= b ? 1 : 2;\n        assert(s.x > 0);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_default_chc/args",
    "content": "--model-checker-engine chc\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_default_chc/err",
    "content": "Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_default_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    struct S {\n        uint x;\n    }\n    S s;\n    function f(bool b) public {\n        s.x |= b ? 1 : 2;\n        assert(s.x > 0);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_true_all_engines/args",
    "content": "--model-checker-engine all --model-checker-show-unproved\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_true_all_engines/err",
    "content": "Warning: CHC: Assertion violation might happen here.\n  --> input.sol:10:9:\n   |\n10 |         assert(s.x > 0);\n   |         ^^^^^^^^^^^^^^^\n\nInfo: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_true_all_engines/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    struct S {\n        uint x;\n    }\n    S s;\n    function f(bool b) public {\n        s.x |= b ? 1 : 2;\n        assert(s.x > 0);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_true_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-show-unproved\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_true_bmc/err",
    "content": "Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_true_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    struct S {\n        uint x;\n    }\n    S s;\n    function f(bool b) public {\n        s.x |= b ? 1 : 2;\n        assert(s.x > 0);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_true_chc/args",
    "content": "--model-checker-engine chc --model-checker-show-unproved\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_true_chc/err",
    "content": "Warning: CHC: Assertion violation might happen here.\n  --> input.sol:10:9:\n   |\n10 |         assert(s.x > 0);\n   |         ^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unproved_true_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    struct S {\n        uint x;\n    }\n    S s;\n    function f(bool b) public {\n        s.x |= b ? 1 : 2;\n        assert(s.x > 0);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_default_all_engines/args",
    "content": "--model-checker-engine all\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_default_all_engines/err",
    "content": "Warning: SMTChecker: 1 unsupported language feature(s). Enable the model checker option \"show unsupported\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_default_all_engines/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f() external pure {\n        assembly {}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_default_bmc/args",
    "content": "--model-checker-engine bmc\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_default_bmc/err",
    "content": "Warning: SMTChecker: 1 unsupported language feature(s). Enable the model checker option \"show unsupported\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_default_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f() external pure {\n        assembly {}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_default_chc/args",
    "content": "--model-checker-engine chc\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_default_chc/err",
    "content": "Warning: SMTChecker: 1 unsupported language feature(s). Enable the model checker option \"show unsupported\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_default_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f() external pure {\n        assembly {}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_true_all_engines/args",
    "content": "--model-checker-engine all --model-checker-show-unsupported\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_true_all_engines/err",
    "content": "Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n --> input.sol:5:9:\n  |\n5 |         assembly {}\n  |         ^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_true_all_engines/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f() external pure {\n        assembly {}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_true_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-show-unsupported\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_true_bmc/err",
    "content": "Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n --> input.sol:5:9:\n  |\n5 |         assembly {}\n  |         ^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_true_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f() external pure {\n        assembly {}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_true_chc/args",
    "content": "--model-checker-engine chc --model-checker-show-unsupported\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_true_chc/err",
    "content": "Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n --> input.sol:5:9:\n  |\n5 |         assembly {}\n  |         ^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_show_unsupported_true_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f() external pure {\n        assembly {}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_cvc5/args",
    "content": "--model-checker-engine bmc --model-checker-solvers cvc5\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_cvc5/err",
    "content": "Warning: BMC: Assertion violation happens here.\n --> input.sol:5:3:\n  |\n5 | \t\tassert(x > 0);\n  | \t\t^^^^^^^^^^^^^\nNote: Counterexample:\n  x = 0\n\nNote: Callstack:\nNote:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_cvc5/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f(uint x) public pure {\n\t\tassert(x > 0);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_cvc5_eld/args",
    "content": "--model-checker-engine all --model-checker-solvers cvc5,eld\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_cvc5_eld/err",
    "content": "Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n\nWarning: BMC: Condition is always false.\n --> input.sol:6:7:\n  |\n6 | \t\tif (y == 0)\n  | \t\t    ^^^^^^\nNote: Callstack:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_cvc5_eld/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f() public pure {\n\t\tuint y = 1;\n\t\tif (y == 0)\n\t\t\trevert();\n\t\tassert(y > 0);\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_eld/args",
    "content": "--model-checker-engine chc --model-checker-solvers eld\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_eld/err",
    "content": "Warning: CHC: Assertion violation happens here.\n --> input.sol:5:3:\n  |\n5 | \t\tassert(x > 0);\n  | \t\t^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_eld/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f(uint x) public pure {\n\t\tassert(x > 0);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_smtlib2/args",
    "content": "--model-checker-engine all --model-checker-solvers smtlib2\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_smtlib2/err",
    "content": "Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\nWarning: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled.\n\nWarning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\nWarning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_smtlib2/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f(uint x) public pure {\n\t\tassert(x > 0);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_wrong/args",
    "content": "--model-checker-engine all --model-checker-solvers ultraSolver\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_wrong/err",
    "content": "Error: Invalid option for --model-checker-solvers: ultraSolver\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_wrong/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_wrong/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f(uint x) public pure {\n\t\tassert(x > 0);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_wrong2/args",
    "content": "--model-checker-engine all --model-checker-solvers z3, smtlib2\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_wrong2/err",
    "content": "Error: \"smtlib2\" is not found.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_wrong2/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_wrong2/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f(uint x) public pure {\n\t\tassert(x > 0);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_z3/args",
    "content": "--model-checker-engine all --model-checker-solvers z3\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_z3/err",
    "content": "Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\ntest.constructor()\ntest.f(0)\n --> input.sol:5:3:\n  |\n5 | \t\tassert(x > 0);\n  | \t\t^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_z3/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f(uint x) public pure {\n\t\tassert(x > 0);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_z3_implicit/args",
    "content": "--model-checker-engine all\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_z3_implicit/err",
    "content": "Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\ntest.constructor()\ntest.f(0)\n --> input.sol:5:3:\n  |\n5 | \t\tassert(x > 0);\n  | \t\t^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_z3_implicit/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f(uint x) public pure {\n\t\tassert(x > 0);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_z3_smtlib2/args",
    "content": "--model-checker-engine all --model-checker-solvers z3,smtlib2\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_z3_smtlib2/err",
    "content": "Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\ntest.constructor()\ntest.f(0)\n --> input.sol:5:3:\n  |\n5 | \t\tassert(x > 0);\n  | \t\t^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_solvers_z3_smtlib2/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f(uint x) public pure {\n\t\tassert(x > 0);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_all_all_engines/args",
    "content": "--model-checker-engine all --model-checker-targets all\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_all_all_engines/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 0)\n --> input.sol:7:3:\n  |\n7 | \t\t--x;\n  | \t\t^^^\n\nWarning: CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 1\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 2)\n --> input.sol:8:3:\n  |\n8 | \t\tx + type(uint).max;\n  | \t\t^^^^^^^^^^^^^^^^^^\n\nWarning: CHC: Division by zero happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n --> input.sol:9:3:\n  |\n9 | \t\t2 / x;\n  | \t\t^^^^^\n\nWarning: CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:11:3:\n   |\n11 | \t\tassert(x > 0);\n   | \t\t^^^^^^^^^^^^^\n\nWarning: CHC: Empty array \"pop\" happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:12:3:\n   |\n12 | \t\tarr.pop();\n   | \t\t^^^^^^^^^\n\nWarning: CHC: Out of bounds access happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:13:3:\n   |\n13 | \t\tarr[x];\n   | \t\t^^^^^^\n\nInfo: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n\nWarning: BMC: Condition is always true.\n --> input.sol:6:11:\n  |\n6 | \t\trequire(x >= 0);\n  | \t\t        ^^^^^^\nNote: Callstack:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_all_all_engines/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_all_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets all\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_all_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: BMC: Condition is always true.\n --> input.sol:6:11:\n  |\n6 | \t\trequire(x >= 0);\n  | \t\t        ^^^^^^\nNote: Callstack:\n\nWarning: BMC: Underflow (resulting value less than 0) happens here.\n --> input.sol:7:3:\n  |\n7 | \t\t--x;\n  | \t\t^^^\nNote: Counterexample:\n  <result> = (- 1)\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\nWarning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n --> input.sol:8:3:\n  |\n8 | \t\tx + type(uint).max;\n  | \t\t^^^^^^^^^^^^^^^^^^\nNote: Counterexample:\n  <result> = 2**256\n  a = 0\n  x = 1\n\nNote: Callstack:\nNote:\n\nWarning: BMC: Division by zero happens here.\n --> input.sol:9:3:\n  |\n9 | \t\t2 / x;\n  | \t\t^^^^^\nNote: Counterexample:\n  <result> = 0\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\nWarning: BMC: Insufficient funds happens here.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\nWarning: BMC: Assertion violation happens here.\n  --> input.sol:11:3:\n   |\n11 | \t\tassert(x > 0);\n   | \t\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_all_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_all_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets all\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_all_chc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 0)\n --> input.sol:7:3:\n  |\n7 | \t\t--x;\n  | \t\t^^^\n\nWarning: CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 1\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 2)\n --> input.sol:8:3:\n  |\n8 | \t\tx + type(uint).max;\n  | \t\t^^^^^^^^^^^^^^^^^^\n\nWarning: CHC: Division by zero happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n --> input.sol:9:3:\n  |\n9 | \t\t2 / x;\n  | \t\t^^^^^\n\nWarning: CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:11:3:\n   |\n11 | \t\tassert(x > 0);\n   | \t\t^^^^^^^^^^^^^\n\nWarning: CHC: Empty array \"pop\" happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:12:3:\n   |\n12 | \t\tarr.pop();\n   | \t\t^^^^^^^^^\n\nWarning: CHC: Out of bounds access happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:13:3:\n   |\n13 | \t\tarr[x];\n   | \t\t^^^^^^\n\nInfo: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_all_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_assert_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets assert\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_assert_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: BMC: Assertion violation happens here.\n  --> input.sol:11:3:\n   |\n11 | \t\tassert(x > 0);\n   | \t\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_assert_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_assert_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets assert\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_assert_chc/err",
    "content": "Warning: CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\"\") -- untrusted external call\n  --> input.sol:12:3:\n   |\n12 | \t\tassert(x > 0);\n   | \t\t^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_assert_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\t(bool success, ) = a.call{value: x}(\"\");\n\t\trequire(success);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_balance_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets balance\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_balance_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: BMC: Insufficient funds happens here.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_balance_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_balance_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets balance\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_balance_chc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:11:3:\n   |\n11 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nInfo: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_balance_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test {\n\tuint[] arr;\n\tfunction f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_constant_condition_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets constantCondition\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_constant_condition_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: BMC: Condition is always true.\n --> input.sol:6:11:\n  |\n6 | \t\trequire(x >= 0);\n  | \t\t        ^^^^^^\nNote: Callstack:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_constant_condition_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_constant_condition_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets constantCondition\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_constant_condition_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test {\n\tuint[] arr;\n\tfunction f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\t(bool success, ) = a.call{value: x}(\"\");\n\t\trequire(success);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_default_all_engines/args",
    "content": "--model-checker-engine all --model-checker-targets default\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_default_all_engines/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: CHC: Division by zero happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n --> input.sol:9:3:\n  |\n9 | \t\t2 / x;\n  | \t\t^^^^^\n\nWarning: CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:11:3:\n   |\n11 | \t\tassert(x > 0);\n   | \t\t^^^^^^^^^^^^^\n\nWarning: CHC: Empty array \"pop\" happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:12:3:\n   |\n12 | \t\tarr.pop();\n   | \t\t^^^^^^^^^\n\nWarning: CHC: Out of bounds access happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:13:3:\n   |\n13 | \t\tarr[x];\n   | \t\t^^^^^^\n\nInfo: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n\nWarning: BMC: Condition is always true.\n --> input.sol:6:11:\n  |\n6 | \t\trequire(x >= 0);\n  | \t\t        ^^^^^^\nNote: Callstack:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_default_all_engines/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n\tfunction f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_default_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets default\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_default_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: BMC: Condition is always true.\n --> input.sol:6:11:\n  |\n6 | \t\trequire(x >= 0);\n  | \t\t        ^^^^^^\nNote: Callstack:\n\nWarning: BMC: Division by zero happens here.\n --> input.sol:9:3:\n  |\n9 | \t\t2 / x;\n  | \t\t^^^^^\nNote: Counterexample:\n  <result> = 0\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\nWarning: BMC: Insufficient funds happens here.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\nWarning: BMC: Assertion violation happens here.\n  --> input.sol:11:3:\n   |\n11 | \t\tassert(x > 0);\n   | \t\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_default_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n\tfunction f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_default_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets default\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_default_chc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: CHC: Division by zero happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n --> input.sol:9:3:\n  |\n9 | \t\t2 / x;\n  | \t\t^^^^^\n\nWarning: CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:11:3:\n   |\n11 | \t\tassert(x > 0);\n   | \t\t^^^^^^^^^^^^^\n\nWarning: CHC: Empty array \"pop\" happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:12:3:\n   |\n12 | \t\tarr.pop();\n   | \t\t^^^^^^^^^\n\nWarning: CHC: Out of bounds access happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> input.sol:13:3:\n   |\n13 | \t\tarr[x];\n   | \t\t^^^^^^\n\nInfo: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_default_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n\tfunction f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_div_by_zero_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets divByZero\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_div_by_zero_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: BMC: Division by zero happens here.\n --> input.sol:9:3:\n  |\n9 | \t\t2 / x;\n  | \t\t^^^^^\nNote: Counterexample:\n  <result> = 0\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_div_by_zero_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_div_by_zero_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets divByZero\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_div_by_zero_chc/err",
    "content": "Warning: CHC: Division by zero happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n --> input.sol:9:3:\n  |\n9 | \t\t2 / x;\n  | \t\t^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_div_by_zero_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\t(bool success, ) = a.call{value: x}(\"\");\n\t\trequire(success);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_error/args",
    "content": "--model-checker-engine all --model-checker-targets aaa,bbb\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_error/err",
    "content": "Error: Invalid option for --model-checker-targets: aaa,bbb\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_error/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_error/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\t(bool success, ) = a.call{value: x}(\"\");\n\t\trequire(success);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_out_of_bounds_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets outOfBounds\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_out_of_bounds_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:11:3:\n   |\n11 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_out_of_bounds_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test {\n\tuint[] arr;\n\tfunction f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_out_of_bounds_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets outOfBounds\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_out_of_bounds_chc/err",
    "content": "Warning: CHC: Out of bounds access happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\"\") -- untrusted external call\n  --> input.sol:14:3:\n   |\n14 | \t\tarr[x];\n   | \t\t^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_out_of_bounds_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\t(bool success, ) = a.call{value: x}(\"\");\n\t\trequire(success);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_overflow_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets overflow\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_overflow_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n --> input.sol:8:3:\n  |\n8 | \t\tx + type(uint).max;\n  | \t\t^^^^^^^^^^^^^^^^^^\nNote: Counterexample:\n  <result> = 2**256\n  a = 0\n  x = 1\n\nNote: Callstack:\nNote:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_overflow_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_overflow_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets overflow\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_overflow_chc/err",
    "content": "Warning: CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 1\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 2)\n --> input.sol:8:3:\n  |\n8 | \t\tx + type(uint).max;\n  | \t\t^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_overflow_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\t(bool success, ) = a.call{value: x}(\"\");\n\t\trequire(success);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_pop_empty_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets popEmptyArray\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_pop_empty_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:11:3:\n   |\n11 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_pop_empty_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract test {\n\tuint[] arr;\n\tfunction f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_pop_empty_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets popEmptyArray\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_pop_empty_chc/err",
    "content": "Warning: CHC: Empty array \"pop\" happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\"\") -- untrusted external call\n  --> input.sol:13:3:\n   |\n13 | \t\tarr.pop();\n   | \t\t^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_pop_empty_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\t(bool success, ) = a.call{value: x}(\"\");\n\t\trequire(success);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets underflow\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: BMC: Underflow (resulting value less than 0) happens here.\n --> input.sol:7:3:\n  |\n7 | \t\t--x;\n  | \t\t^^^\nNote: Counterexample:\n  <result> = (- 1)\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets underflow\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_chc/err",
    "content": "Warning: CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 0)\n --> input.sol:7:3:\n  |\n7 | \t\t--x;\n  | \t\t^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\t(bool success, ) = a.call{value: x}(\"\");\n\t\trequire(success);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_assert_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets underflow,overflow,assert\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_assert_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: BMC: Underflow (resulting value less than 0) happens here.\n --> input.sol:7:3:\n  |\n7 | \t\t--x;\n  | \t\t^^^\nNote: Counterexample:\n  <result> = (- 1)\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\nWarning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n --> input.sol:8:3:\n  |\n8 | \t\tx + type(uint).max;\n  | \t\t^^^^^^^^^^^^^^^^^^\nNote: Counterexample:\n  <result> = 2**256\n  a = 0\n  x = 1\n\nNote: Callstack:\nNote:\n\nWarning: BMC: Assertion violation happens here.\n  --> input.sol:11:3:\n   |\n11 | \t\tassert(x > 0);\n   | \t\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_assert_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_assert_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets underflow,overflow,assert\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_assert_chc/err",
    "content": "Warning: CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 0)\n --> input.sol:7:3:\n  |\n7 | \t\t--x;\n  | \t\t^^^\n\nWarning: CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 1\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 2)\n --> input.sol:8:3:\n  |\n8 | \t\tx + type(uint).max;\n  | \t\t^^^^^^^^^^^^^^^^^^\n\nWarning: CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\"\") -- untrusted external call\n  --> input.sol:12:3:\n   |\n12 | \t\tassert(x > 0);\n   | \t\t^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_assert_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\t(bool success, ) = a.call{value: x}(\"\");\n\t\trequire(success);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-targets underflow,overflow\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_bmc/err",
    "content": "Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n  --> input.sol:10:3:\n   |\n10 | \t\ta.transfer(x);\n   | \t\t^^^^^^^^^^\n\nWarning: BMC: Underflow (resulting value less than 0) happens here.\n --> input.sol:7:3:\n  |\n7 | \t\t--x;\n  | \t\t^^^\nNote: Counterexample:\n  <result> = (- 1)\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\nWarning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n --> input.sol:8:3:\n  |\n8 | \t\tx + type(uint).max;\n  | \t\t^^^^^^^^^^^^^^^^^^\nNote: Counterexample:\n  <result> = 2**256\n  a = 0\n  x = 1\n\nNote: Callstack:\nNote:\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\ta.transfer(x);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_chc/args",
    "content": "--model-checker-engine chc --model-checker-targets underflow,overflow\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_chc/err",
    "content": "Warning: CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 0)\n --> input.sol:7:3:\n  |\n7 | \t\t--x;\n  | \t\t^^^\n\nWarning: CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 1\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 2)\n --> input.sol:8:3:\n  |\n8 | \t\tx + type(uint).max;\n  | \t\t^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_targets_underflow_overflow_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tuint[] arr;\n    function f(address payable a, uint x) public {\n\t\trequire(x >= 0);\n\t\t--x;\n\t\tx + type(uint).max;\n\t\t2 / x;\n\t\t(bool success, ) = a.call{value: x}(\"\");\n\t\trequire(success);\n\t\tassert(x > 0);\n\t\tarr.pop();\n\t\tarr[x];\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_timeout_all/args",
    "content": "--model-checker-engine all --model-checker-timeout 1000\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_timeout_all/err",
    "content": "Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\nInfo: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n\nWarning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_timeout_all/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f(uint x, uint y, uint k) public pure {\n\t\trequire(k > 0);\n\t\trequire(x % k == 0);\n\t\trequire(y % k == 0);\n\t\tuint r = mulmod(x, y, k);\n\t\tassert(r % k == 0);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_timeout_bmc/args",
    "content": "--model-checker-engine bmc --model-checker-timeout 1000\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_timeout_bmc/err",
    "content": "Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\nInfo: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_timeout_bmc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f(uint x, uint y, uint k) public pure {\n\t\trequire(k > 0);\n\t\trequire(x % k == 0);\n\t\trequire(y % k == 0);\n\t\tuint r = mulmod(x, y, k);\n\t\tassert(r % k == 0);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/model_checker_timeout_chc/args",
    "content": "--model-checker-engine chc --model-checker-timeout 1000\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_timeout_chc/err",
    "content": "Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \"show unproved\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\nInfo: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/cmdlineTests/model_checker_timeout_chc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract test {\n\tfunction f(uint x, uint y, uint k) public pure {\n\t\trequire(k > 0);\n\t\trequire(x % k == 0);\n\t\trequire(y % k == 0);\n\t\tuint r = mulmod(x, y, k);\n\t\tassert(r % k == 0);\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/name_simplifier/args",
    "content": "--optimize --ir-optimized\n"
  },
  {
    "path": "test/cmdlineTests/name_simplifier/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma abicoder v2;\n\n// The point of this test is to check that the\n// AST IDs are removed from the optimized IR\n// so that they do not have a big effect on the\n// optimizer if it has a bug that makes it\n// depen on the actual identifiers.\n\nstruct S { uint x; }\nstruct T { uint[2] y; }\n\ncontract C {\n\tS[2] values;\n\tT t;\n\n\tfunction sumArray(S[] memory _s) public returns (uint, string memory) {\n\t\tvalues[0].x = _s[0].x;\n\t\tt.y[0] = _s[1].x;\n\t\treturn (t.y[0], \"longstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstring\");\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/name_simplifier/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_59\" {\n    code {\n        {\n            /// @src 0:346:625  \"contract C {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_59_deployed\")\n            codecopy(_1, dataoffset(\"C_59_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_59_deployed\" {\n        code {\n            {\n                /// @src 0:346:625  \"contract C {...\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0xf8eddcc6, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) }\n                        let offset := calldataload(4)\n                        if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n                        if iszero(slt(add(offset, 35), calldatasize())) { revert(0, 0) }\n                        let length := calldataload(add(4, offset))\n                        if gt(length, 0xffffffffffffffff)\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 36)\n                        }\n                        let _1 := shl(5, length)\n                        let memPtr := 0\n                        memPtr := mload(64)\n                        let newFreePtr := add(memPtr, and(add(_1, 63), not(31)))\n                        if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 36)\n                        }\n                        mstore(64, newFreePtr)\n                        let dst := memPtr\n                        mstore(memPtr, length)\n                        dst := add(memPtr, 32)\n                        let dst_1 := dst\n                        let srcEnd := add(add(offset, _1), 36)\n                        if gt(srcEnd, calldatasize()) { revert(0, 0) }\n                        let src := add(offset, 36)\n                        for { } lt(src, srcEnd) { src := add(src, 32) }\n                        {\n                            if slt(sub(calldatasize(), src), 32) { revert(0, 0) }\n                            let memPtr_1 := 0\n                            memPtr_1 := mload(64)\n                            let newFreePtr_1 := add(memPtr_1, 32)\n                            if or(gt(newFreePtr_1, 0xffffffffffffffff), lt(newFreePtr_1, memPtr_1))\n                            {\n                                mstore(0, shl(224, 0x4e487b71))\n                                mstore(4, 0x41)\n                                revert(0, 36)\n                            }\n                            mstore(64, newFreePtr_1)\n                            mstore(memPtr_1, calldataload(src))\n                            mstore(dst, memPtr_1)\n                            dst := add(dst, 32)\n                        }\n                        /// @src 0:469:474  \"_s[0]\"\n                        let addr := /** @src 0:346:625  \"contract C {...\" */ 0\n                        if iszero(mload(memPtr))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x32)\n                            revert(0, 36)\n                        }\n                        addr := dst_1\n                        sstore(0, mload(/** @src 0:469:474  \"_s[0]\" */ mload(dst_1)))\n                        /// @src 0:489:494  \"_s[1]\"\n                        let addr_1 := /** @src 0:346:625  \"contract C {...\" */ 0\n                        if iszero(lt(/** @src 0:492:493  \"1\" */ 0x01, /** @src 0:346:625  \"contract C {...\" */ mload(memPtr)))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x32)\n                            revert(0, 36)\n                        }\n                        addr_1 := add(memPtr, 64)\n                        let _2 := mload(/** @src 0:489:494  \"_s[1]\" */ mload(addr_1))\n                        /// @src 0:346:625  \"contract C {...\"\n                        sstore(0x02, _2)\n                        let memPtr_2 := 0\n                        memPtr_2 := mload(64)\n                        let newFreePtr_2 := add(memPtr_2, 160)\n                        if or(gt(newFreePtr_2, 0xffffffffffffffff), lt(newFreePtr_2, memPtr_2))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 36)\n                        }\n                        mstore(64, newFreePtr_2)\n                        mstore(memPtr_2, 100)\n                        let _3 := add(memPtr_2, 32)\n                        mstore(_3, \"longstringlongstringlongstringlo\")\n                        mstore(add(memPtr_2, 64), \"ngstringlongstringlongstringlong\")\n                        mstore(add(memPtr_2, 96), \"stringlongstringlongstringlongst\")\n                        mstore(add(memPtr_2, 128), \"ring\")\n                        let memPos := mload(64)\n                        mstore(memPos, _2)\n                        mstore(add(memPos, 32), 64)\n                        let length_1 := mload(memPtr_2)\n                        mstore(add(memPos, 64), length_1)\n                        mcopy(add(memPos, 96), _3, length_1)\n                        mstore(add(add(memPos, length_1), 96), 0)\n                        return(memPos, add(sub(add(memPos, and(add(length_1, 0x1f), not(31))), memPos), 96))\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/no_cbor_metadata/args",
    "content": "--no-cbor-metadata --bin --via-ir --optimize\n"
  },
  {
    "path": "test/cmdlineTests/no_cbor_metadata/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >= 0.0.0;\n\n// NOTE: The expected output would be the binary with no metadata.\n// The commandline tests would replace bytecode with metadata in it with\n// <BYTECODE REMOVED>\n// Therefore, not having that means success!\n\ncontract C {\n}\n"
  },
  {
    "path": "test/cmdlineTests/no_cbor_metadata/output",
    "content": "\n======= input.sol:C =======\nBinary:\n608080604052346013576003908160188239f35b5f80fdfe5f80fd\n"
  },
  {
    "path": "test/cmdlineTests/no_cbor_metadata_with_metadata_hash/args",
    "content": "--no-cbor-metadata --metadata-hash ipfs\n"
  },
  {
    "path": "test/cmdlineTests/no_cbor_metadata_with_metadata_hash/err",
    "content": "Error: Cannot specify a metadata hashing method when --no-cbor-metadata is set.\n"
  },
  {
    "path": "test/cmdlineTests/no_cbor_metadata_with_metadata_hash/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/no_cbor_metadata_with_metadata_hash/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >= 0.0.0;\n\ncontract Empty {}\n\ncontract C {\n    function f() external returns (bytes memory, bytes memory){\n        return (type(Empty).creationCode, type(Empty).runtimeCode);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/no_contract_combined_json/args",
    "content": "--combined-json ast --pretty-json --json-indent 4"
  },
  {
    "path": "test/cmdlineTests/no_contract_combined_json/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;"
  },
  {
    "path": "test/cmdlineTests/no_contract_combined_json/output",
    "content": "{\n    \"sourceList\": [\n        \"input.sol\"\n    ],\n    \"sources\": {\n        \"input.sol\": {\n            \"AST\": {\n                \"absolutePath\": \"input.sol\",\n                \"exportedSymbols\": {},\n                \"id\": 2,\n                \"license\": \"GPL-3.0\",\n                \"nodeType\": \"SourceUnit\",\n                \"nodes\": [\n                    {\n                        \"id\": 1,\n                        \"literals\": [\n                            \"solidity\",\n                            \">=\",\n                            \"0.0\"\n                        ],\n                        \"nodeType\": \"PragmaDirective\",\n                        \"src\": \"36:22:0\"\n                    }\n                ],\n                \"src\": \"36:22:0\"\n            },\n            \"id\": 0\n        }\n    },\n    \"version\": \"<VERSION REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/no_import_callback/args",
    "content": "--no-import-callback contract_1.sol\n"
  },
  {
    "path": "test/cmdlineTests/no_import_callback/contract_1.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nimport \"contract_2.sol\";\n"
  },
  {
    "path": "test/cmdlineTests/no_import_callback/contract_2.sol",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/no_import_callback/err",
    "content": "Error: Source \"contract_2.sol\" not found: No import callback.\n --> contract_1.sol:4:1:\n  |\n4 | import \"contract_2.sol\";\n  | ^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/no_import_callback/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/object_compiler/args",
    "content": "--strict-assembly --optimize\n"
  },
  {
    "path": "test/cmdlineTests/object_compiler/input.yul",
    "content": "object \"MyContract\" {\n  code {\n    // this is the constructor.\n    // store the creator in the first storage slot\n    sstore(0, caller())\n    // now return the runtime code using the special functions\n    datacopy(0, dataoffset(\"Runtime\"), datasize(\"Runtime\"))\n    return(0, datasize(\"Runtime\"))\n  }\n  object \"Runtime\" {\n    code {\n      // runtime - just return the creator\n      mstore(0, sload(0))\n      return(0, 0x20)\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/object_compiler/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"MyContract\" {\n    code {\n        {\n            sstore(0, caller())\n            let _1 := datasize(\"Runtime\")\n            datacopy(0, dataoffset(\"Runtime\"), _1)\n            return(0, _1)\n        }\n    }\n    object \"Runtime\" {\n        code {\n            {\n                mstore(0, sload(0))\n                return(0, 0x20)\n            }\n        }\n    }\n}\n\n\nBinary representation:\n335f55600880600d5f395ff3fe5f545f5260205ff3\n\nText representation:\n    /* \"input.yul\":65:73   */\n  caller\n    /* \"input.yul\":62:63   */\n  0x00\n    /* \"input.yul\":55:74   */\n  sstore\n    /* \"input.yul\":97:116   */\n  dataSize(sub_0)\n    /* \"input.yul\":141:162   */\n  dup1\n  dataOffset(sub_0)\n    /* \"input.yul\":138:139   */\n  0x00\n    /* \"input.yul\":129:167   */\n  codecopy\n    /* \"input.yul\":187:188   */\n  0x00\n    /* \"input.yul\":180:193   */\n  return\nstop\n\nsub_0: assembly {\n        /* \"input.yul\":294:295   */\n      0x00\n        /* \"input.yul\":288:296   */\n      sload\n        /* \"input.yul\":285:286   */\n      0x00\n        /* \"input.yul\":278:297   */\n      mstore\n        /* \"input.yul\":324:328   */\n      0x20\n        /* \"input.yul\":321:322   */\n      0x00\n        /* \"input.yul\":314:329   */\n      return\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimize_full_storage_write/args",
    "content": "--optimize --asm\n"
  },
  {
    "path": "test/cmdlineTests/optimize_full_storage_write/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract OptimizeFullSlotWrite {\n\tuint64[4] nums;\n\tfunction f() public {\n\t\tnums[0] = 11111;\n\t\tnums[1] = 22222;\n\t\tnums[2] = 33333;\n\t\tnums[3] = 44444;\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimize_full_storage_write/output",
    "content": "\n======= input.sol:OptimizeFullSlotWrite =======\nEVM assembly:\n    /* \"input.sol\":60:213  contract OptimizeFullSlotWrite {... */\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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        /* \"input.sol\":60:213  contract OptimizeFullSlotWrite {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \"input.sol\":111:211  function f() public {... */\n    tag_3:\n      tag_4\n        /* \"input.sol\":192:207  nums[3] = 44444 */\n      0xad9c000000000000823500000000000056ce0000000000002b67\n        /* \"input.sol\":135:139  nums */\n      0x00\n        /* \"input.sol\":192:207  nums[3] = 44444 */\n      sstore\n        /* \"input.sol\":111:211  function f() public {... */\n      jump\n    tag_4:\n      stop\n\n    auxdata: <AUXDATA REMOVED>\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_BlockDeDuplicator/args",
    "content": "--optimize --asm\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_BlockDeDuplicator/err",
    "content": "Warning: Statement has no effect.\n --> input.sol:7:27:\n  |\n7 |     function f() public { true ? 1 : 3;}\n  |                           ^^^^^^^^^^^^\n\nWarning: Function state mutability can be restricted to pure\n --> input.sol:7:5:\n  |\n7 |     function f() public { true ? 1 : 3;}\n  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_BlockDeDuplicator/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function fun_x() public {}\n    function fun_() public {}\n    function f() public { true ? 1 : 3;}\n    function() r = true ? fun_x : f;\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_BlockDeDuplicator/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":60:213  contract C {... */\n  mstore(0x40, 0x80)\n    /* \"input.sol\":179:210  function() r = true ? fun_x : f */\n  0x00\n  dup1\n  sload\n  not(sub(shl(0x40, 0x01), 0x01))\n  and\n    /* \"input.sol\":201:206  fun_x */\n  or(tag_0_7, shl(0x20, tag_2))\n  sub(shl(0x40, 0x01), 0x01)\n    /* \"input.sol\":179:210  function() r = true ? fun_x : f */\n  and\n  or\n  swap1\n  sstore\n    /* \"input.sol\":60:213  contract C {... */\n  callvalue\n  dup1\n  iszero\n  tag_5\n  jumpi\n  revert(0x00, 0x00)\ntag_5:\n  pop\n  jump(tag_6)\n    /* \"input.sol\":138:174  function f() public { true ? 1 : 3;} */\ntag_2:\n  jump\t// out\n    /* \"input.sol\":60:213  contract C {... */\ntag_6:\n  dataSize(sub_0)\n  dup1\n  dataOffset(sub_0)\n  0x00\n  codecopy\n  0x00\n  return\nstop\n\nsub_0: assembly {\n        /* \"input.sol\":60:213  contract C {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n      dup1\n      0x2e1fb2bc\n      eq\n      tag_3\n      jumpi\n      dup1\n      0x4753a67d\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \"input.sol\":138:174  function f() public { true ? 1 : 3;} */\n    tag_3:\n      stop\n    tag_7:\n      jump\t// out\n\n    auxdata: <AUXDATA REMOVED>\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_array_sload/args",
    "content": "--optimize --ir-optimized\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_array_sload/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma abicoder v2;\n\ncontract Arraysum {\n\tuint256[] values;\n\n\tfunction sumArray() public view returns(uint sum) {\n\t\tsum = 0;\n\t\t// The optimizer should read the length of the array only once, because\n\t\t// LoopInvariantCodeMotion can move the `sload` corresponding to the length outside of the\n\t\t// loop.\n\t\tfor(uint i = 0; i < values.length; i++)\n\t\t\tsum += values[i];\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_array_sload/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"Arraysum_34\" {\n    code {\n        {\n            /// @src 0:80:429  \"contract Arraysum {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"Arraysum_34_deployed\")\n            codecopy(_1, dataoffset(\"Arraysum_34_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"Arraysum_34_deployed\" {\n        code {\n            {\n                /// @src 0:80:429  \"contract Arraysum {...\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x81d73423, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let var_sum := 0\n                        /// @src 0:175:182  \"sum = 0\"\n                        var_sum := /** @src 0:80:429  \"contract Arraysum {...\" */ 0\n                        /// @src 0:368:378  \"uint i = 0\"\n                        let var_i := /** @src 0:80:429  \"contract Arraysum {...\" */ 0\n                        let _1 := sload(0)\n                        /// @src 0:364:423  \"for(uint i = 0; i < values.length; i++)...\"\n                        for { }\n                        /** @src 0:80:429  \"contract Arraysum {...\" */ 1\n                        /// @src 0:368:378  \"uint i = 0\"\n                        {\n                            /// @src 0:399:402  \"i++\"\n                            var_i := /** @src 0:80:429  \"contract Arraysum {...\" */ add(/** @src 0:399:402  \"i++\" */ var_i, /** @src 0:80:429  \"contract Arraysum {...\" */ 1)\n                        }\n                        /// @src 0:399:402  \"i++\"\n                        {\n                            /// @src 0:380:397  \"i < values.length\"\n                            let _2 := iszero(lt(var_i, _1))\n                            if _2 { break }\n                            /// @src 0:80:429  \"contract Arraysum {...\"\n                            _2 := 0\n                            mstore(0, 0)\n                            let sum := add(var_sum, sload(add(18569430475105882587588266137607568536673111973893317399460219858819262702947, var_i)))\n                            if gt(var_sum, sum)\n                            {\n                                mstore(0, shl(224, 0x4e487b71))\n                                mstore(4, 0x11)\n                                revert(0, 0x24)\n                            }\n                            /// @src 0:407:423  \"sum += values[i]\"\n                            var_sum := sum\n                        }\n                        /// @src 0:80:429  \"contract Arraysum {...\"\n                        let memPos := mload(64)\n                        mstore(memPos, var_sum)\n                        return(memPos, 0x20)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_enabled_invalid_yul_optimizer_enabled_and_disabled/args",
    "content": "--optimize-yul --no-optimize-yul\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_enabled_invalid_yul_optimizer_enabled_and_disabled/err",
    "content": "Error: Options --optimize-yul and --no-optimize-yul cannot be used together.\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_enabled_invalid_yul_optimizer_enabled_and_disabled/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_enabled_invalid_yul_optimizer_enabled_and_disabled/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_add/args",
    "content": "--optimize --asm\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_add/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nfunction unsafe_add(uint x, uint y) pure returns (uint)\n{\n    unchecked {\n        return x + y;\n    }\n}\n\ncontract C {\n    function f() public pure {\n        for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_add/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":165:305  contract C {... */\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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        /* \"input.sol\":165:305  contract C {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \"input.sol\":182:303  function f() public pure {... */\n    tag_3:\n      tag_4\n      tag_5\n      jump\t// in\n    tag_4:\n      stop\n    tag_5:\n        /* \"input.sol\":221:227  uint x */\n      0x00\n        /* \"input.sol\":217:297  for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */\n    tag_7:\n        /* \"input.sol\":237:239  10 */\n      0x0a\n        /* \"input.sol\":233:234  x */\n      dup2\n        /* \"input.sol\":233:239  x < 10 */\n      lt\n        /* \"input.sol\":217:297  for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */\n      iszero\n      tag_8\n      jumpi\n        /* \"input.sol\":149:154  x + y */\n      dup1\n      add\n        /* \"input.sol\":273:274  1 */\n      0x01\n        /* \"input.sol\":149:154  x + y */\n      add\n        /* \"input.sol\":217:297  for(uint x = 0; x < 10; x = unsafe_add(x, unsafe_add(x, 1)))... */\n      jump(tag_7)\n    tag_8:\n      pop\n        /* \"input.sol\":182:303  function f() public pure {... */\n      jump\t// out\n\n    auxdata: <AUXDATA REMOVED>\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_call_from_constructor/args",
    "content": "--optimize --asm\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_call_from_constructor/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    uint x;\n    constructor() { x = a(); }\n    function a() public pure returns (uint) { return f(); } // this should be inlined\n    function f() internal pure returns (uint) { return 6; }\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_call_from_constructor/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":60:263  contract C {... */\n  mstore(0x40, 0x80)\n    /* \"input.sol\":89:115  constructor() { x = a(); } */\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\n  pop\n    /* \"input.sol\":257:258  6 */\n  0x06\n    /* \"input.sol\":105:106  x */\n  0x00\n    /* \"input.sol\":105:112  x = a() */\n  sstore\n    /* \"input.sol\":60:263  contract C {... */\n  dataSize(sub_0)\n  dup1\n  dataOffset(sub_0)\n  0x00\n  codecopy\n  0x00\n  return\nstop\n\nsub_0: assembly {\n        /* \"input.sol\":60:263  contract C {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x0dbe671f\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \"input.sol\":120:175  function a() public pure returns (uint) { return f(); } */\n    tag_3:\n        /* \"input.sol\":257:258  6 */\n      0x06\n        /* \"input.sol\":120:175  function a() public pure returns (uint) { return f(); } */\n      mload(0x40)\n        /* \"#utility.yul\":160:185   */\n      swap1\n      dup2\n      mstore\n        /* \"#utility.yul\":148:150   */\n      0x20\n        /* \"#utility.yul\":133:151   */\n      add\n        /* \"input.sol\":120:175  function a() public pure returns (uint) { return f(); } */\n      mload(0x40)\n      dup1\n      swap2\n      sub\n      swap1\n      return\n\n    auxdata: <AUXDATA REMOVED>\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_dynamic_reference/args",
    "content": "--optimize --asm\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_dynamic_reference/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function() internal view returns (uint) x;\n\n    function g() public { x = f; }\n    function a() public pure returns (uint) { return f(); } // this should be inlined\n    function h() public view returns (uint) { return x() + 1; }\n    function f() internal pure returns (uint) { return 6; }\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_dynamic_reference/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":60:367  contract C {... */\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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        /* \"input.sol\":60:367  contract C {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x0dbe671f\n      eq\n      tag_3\n      jumpi\n      dup1\n      0xb8c9d365\n      eq\n      tag_4\n      jumpi\n      dup1\n      0xe2179b8e\n      eq\n      tag_5\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \"input.sol\":160:215  function a() public pure returns (uint) { return f(); } */\n    tag_3:\n        /* \"input.sol\":361:362  6 */\n      0x06\n        /* \"input.sol\":160:215  function a() public pure returns (uint) { return f(); } */\n    tag_6:\n      mload(0x40)\n        /* \"#utility.yul\":160:185   */\n      swap1\n      dup2\n      mstore\n        /* \"#utility.yul\":148:150   */\n      0x20\n        /* \"#utility.yul\":133:151   */\n      add\n        /* \"input.sol\":160:215  function a() public pure returns (uint) { return f(); } */\n      mload(0x40)\n      dup1\n      swap2\n      sub\n      swap1\n      return\n        /* \"input.sol\":246:305  function h() public view returns (uint) { return x() + 1; } */\n    tag_4:\n      tag_6\n      tag_11\n      jump\t// in\n        /* \"input.sol\":125:155  function g() public { x = f; } */\n    tag_5:\n        /* \"input.sol\":147:148  x */\n      0x00\n        /* \"input.sol\":147:152  x = f */\n      dup1\n      sload\n      not(0xffffffffffffffff)\n      and\n        /* \"input.sol\":151:152  f */\n      tag_17\n        /* \"input.sol\":147:152  x = f */\n      or\n      swap1\n      sstore\n        /* \"input.sol\":125:155  function g() public { x = f; } */\n      stop\n        /* \"input.sol\":209:212  f() */\n    tag_16:\n        /* \"input.sol\":202:212  return f() */\n      swap1\n      pop\n        /* \"input.sol\":160:215  function a() public pure returns (uint) { return f(); } */\n      swap1\n      jump\t// out\n        /* \"input.sol\":246:305  function h() public view returns (uint) { return x() + 1; } */\n    tag_11:\n        /* \"input.sol\":280:284  uint */\n      0x00\n        /* \"input.sol\":295:296  x */\n      dup1\n      sload\n        /* \"input.sol\":295:298  x() */\n      tag_19\n      swap1\n        /* \"input.sol\":295:296  x */\n      dup1\n      iszero\n      tag_20\n      mul\n      or\n        /* \"input.sol\":295:298  x() */\n      0xffffffff\n      and\n      jump\t// in\n    tag_19:\n        /* \"input.sol\":295:302  x() + 1 */\n      tag_16\n      swap1\n        /* \"input.sol\":301:302  1 */\n      0x01\n        /* \"input.sol\":295:302  x() + 1 */\n      tag_22\n      jump\t// in\n        /* \"input.sol\":310:365  function f() internal pure returns (uint) { return 6; } */\n    tag_17:\n        /* \"input.sol\":361:362  6 */\n      0x06\n      swap1\n        /* \"input.sol\":310:365  function f() internal pure returns (uint) { return 6; } */\n      jump\t// out\n    tag_20:\n      tag_25\n      tag_26\n      jump\t// in\n    tag_25:\n      jump\t// out\n        /* \"#utility.yul\":196:418   */\n    tag_22:\n        /* \"#utility.yul\":261:270   */\n      dup1\n      dup3\n      add\n        /* \"#utility.yul\":282:292   */\n      dup1\n      dup3\n      gt\n        /* \"#utility.yul\":279:412   */\n      iszero\n      tag_30\n      jumpi\n        /* \"#utility.yul\":334:344   */\n      0x4e487b71\n        /* \"#utility.yul\":329:332   */\n      0xe0\n        /* \"#utility.yul\":325:345   */\n      shl\n        /* \"#utility.yul\":322:323   */\n      0x00\n        /* \"#utility.yul\":315:346   */\n      mstore\n        /* \"#utility.yul\":369:373   */\n      0x11\n        /* \"#utility.yul\":366:367   */\n      0x04\n        /* \"#utility.yul\":359:374   */\n      mstore\n        /* \"#utility.yul\":397:401   */\n      0x24\n        /* \"#utility.yul\":394:395   */\n      0x00\n        /* \"#utility.yul\":387:402   */\n      revert\n        /* \"#utility.yul\":279:412   */\n    tag_30:\n        /* \"#utility.yul\":196:418   */\n      swap3\n      swap2\n      pop\n      pop\n      jump\t// out\n        /* \"#utility.yul\":423:550   */\n    tag_26:\n        /* \"#utility.yul\":484:494   */\n      0x4e487b71\n        /* \"#utility.yul\":479:482   */\n      0xe0\n        /* \"#utility.yul\":475:495   */\n      shl\n        /* \"#utility.yul\":472:473   */\n      0x00\n        /* \"#utility.yul\":465:496   */\n      mstore\n        /* \"#utility.yul\":515:519   */\n      0x51\n        /* \"#utility.yul\":512:513   */\n      0x04\n        /* \"#utility.yul\":505:520   */\n      mstore\n        /* \"#utility.yul\":539:543   */\n      0x24\n        /* \"#utility.yul\":536:537   */\n      0x00\n        /* \"#utility.yul\":529:544   */\n      revert\n\n    auxdata: <AUXDATA REMOVED>\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/args",
    "content": "--optimize --asm\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    constructor() { x = f; }\n    function() internal view returns (uint) x;\n\n    function a() public pure returns (uint) { return f(); } // this should be inlined\n    function h() public view returns (uint) { return x() + 1; }\n    function f() internal pure returns (uint) { return 6; }\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_dynamic_reference_constructor/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":60:361  contract C {... */\n  mstore(0x40, 0x80)\n    /* \"input.sol\":77:101  constructor() { x = f; } */\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\n  pop\n    /* \"input.sol\":93:94  x */\n  0x00\n    /* \"input.sol\":93:98  x = f */\n  dup1\n  sload\n  not(sub(shl(0x40, 0x01), 0x01))\n  and\n    /* \"input.sol\":97:98  f */\n  or(tag_0_12, shl(0x20, tag_4))\n  sub(shl(0x40, 0x01), 0x01)\n    /* \"input.sol\":93:98  x = f */\n  and\n  or\n  swap1\n  sstore\n    /* \"input.sol\":60:361  contract C {... */\n  jump(tag_5)\n    /* \"input.sol\":304:359  function f() internal pure returns (uint) { return 6; } */\ntag_4:\n    /* \"input.sol\":355:356  6 */\n  0x06\n  swap1\n    /* \"input.sol\":304:359  function f() internal pure returns (uint) { return 6; } */\n  jump\t// out\n    /* \"input.sol\":60:361  contract C {... */\ntag_5:\n  dataSize(sub_0)\n  dup1\n  dataOffset(sub_0)\n  0x00\n  codecopy\n  0x00\n  return\nstop\n\nsub_0: assembly {\n        /* \"input.sol\":60:361  contract C {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x0dbe671f\n      eq\n      tag_3\n      jumpi\n      dup1\n      0xb8c9d365\n      eq\n      tag_4\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \"input.sol\":154:209  function a() public pure returns (uint) { return f(); } */\n    tag_3:\n        /* \"input.sol\":355:356  6 */\n      0x06\n        /* \"input.sol\":154:209  function a() public pure returns (uint) { return f(); } */\n    tag_5:\n      mload(0x40)\n        /* \"#utility.yul\":160:185   */\n      swap1\n      dup2\n      mstore\n        /* \"#utility.yul\":148:150   */\n      0x20\n        /* \"#utility.yul\":133:151   */\n      add\n        /* \"input.sol\":154:209  function a() public pure returns (uint) { return f(); } */\n      mload(0x40)\n      dup1\n      swap2\n      sub\n      swap1\n      return\n        /* \"input.sol\":240:299  function h() public view returns (uint) { return x() + 1; } */\n    tag_4:\n      tag_5\n      tag_10\n      jump\t// in\n        /* \"input.sol\":203:206  f() */\n    tag_14:\n        /* \"input.sol\":196:206  return f() */\n      swap1\n      pop\n        /* \"input.sol\":154:209  function a() public pure returns (uint) { return f(); } */\n      swap1\n      jump\t// out\n        /* \"input.sol\":240:299  function h() public view returns (uint) { return x() + 1; } */\n    tag_10:\n        /* \"input.sol\":274:278  uint */\n      0x00\n        /* \"input.sol\":289:290  x */\n      dup1\n      sload\n        /* \"input.sol\":289:292  x() */\n      tag_16\n      swap1\n        /* \"input.sol\":289:290  x */\n      dup1\n      iszero\n      tag_17\n      mul\n      or\n        /* \"input.sol\":289:292  x() */\n      0xffffffff\n      and\n      jump\t// in\n    tag_16:\n        /* \"input.sol\":289:296  x() + 1 */\n      tag_14\n      swap1\n        /* \"input.sol\":295:296  1 */\n      0x01\n        /* \"input.sol\":289:296  x() + 1 */\n      tag_19\n      jump\t// in\n        /* \"input.sol\":304:359  function f() internal pure returns (uint) { return 6; } */\n    tag_12:\n        /* \"input.sol\":355:356  6 */\n      0x06\n      swap1\n        /* \"input.sol\":304:359  function f() internal pure returns (uint) { return 6; } */\n      jump\t// out\n    tag_17:\n      tag_21\n      tag_22\n      jump\t// in\n    tag_21:\n      jump\t// out\n        /* \"#utility.yul\":196:418   */\n    tag_19:\n        /* \"#utility.yul\":261:270   */\n      dup1\n      dup3\n      add\n        /* \"#utility.yul\":282:292   */\n      dup1\n      dup3\n      gt\n        /* \"#utility.yul\":279:412   */\n      iszero\n      tag_26\n      jumpi\n        /* \"#utility.yul\":334:344   */\n      0x4e487b71\n        /* \"#utility.yul\":329:332   */\n      0xe0\n        /* \"#utility.yul\":325:345   */\n      shl\n        /* \"#utility.yul\":322:323   */\n      0x00\n        /* \"#utility.yul\":315:346   */\n      mstore\n        /* \"#utility.yul\":369:373   */\n      0x11\n        /* \"#utility.yul\":366:367   */\n      0x04\n        /* \"#utility.yul\":359:374   */\n      mstore\n        /* \"#utility.yul\":397:401   */\n      0x24\n        /* \"#utility.yul\":394:395   */\n      0x00\n        /* \"#utility.yul\":387:402   */\n      revert\n        /* \"#utility.yul\":279:412   */\n    tag_26:\n        /* \"#utility.yul\":196:418   */\n      swap3\n      swap2\n      pop\n      pop\n      jump\t// out\n        /* \"#utility.yul\":423:550   */\n    tag_22:\n        /* \"#utility.yul\":484:494   */\n      0x4e487b71\n        /* \"#utility.yul\":479:482   */\n      0xe0\n        /* \"#utility.yul\":475:495   */\n      shl\n        /* \"#utility.yul\":472:473   */\n      0x00\n        /* \"#utility.yul\":465:496   */\n      mstore\n        /* \"#utility.yul\":515:519   */\n      0x51\n        /* \"#utility.yul\":512:513   */\n      0x04\n        /* \"#utility.yul\":505:520   */\n      mstore\n        /* \"#utility.yul\":539:543   */\n      0x24\n        /* \"#utility.yul\":536:537   */\n      0x00\n        /* \"#utility.yul\":529:544   */\n      revert\n\n    auxdata: <AUXDATA REMOVED>\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_inc/args",
    "content": "--optimize --asm\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_inc/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nfunction unsafe_inc(uint x) pure returns (uint)\n{\n    unchecked {\n        return x + 1;\n    }\n}\n\ncontract C {\n    function f() public pure {\n        for(uint x = 0; x < 10; x = unsafe_inc(x))\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_inc/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":157:279  contract C {... */\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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        /* \"input.sol\":157:279  contract C {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \"input.sol\":174:277  function f() public pure {... */\n    tag_3:\n      tag_4\n      tag_5\n      jump\t// in\n    tag_4:\n      stop\n    tag_5:\n        /* \"input.sol\":213:219  uint x */\n      0x00\n        /* \"input.sol\":209:271  for(uint x = 0; x < 10; x = unsafe_inc(x))... */\n    tag_7:\n        /* \"input.sol\":229:231  10 */\n      0x0a\n        /* \"input.sol\":225:226  x */\n      dup2\n        /* \"input.sol\":225:231  x < 10 */\n      lt\n        /* \"input.sol\":209:271  for(uint x = 0; x < 10; x = unsafe_inc(x))... */\n      iszero\n      tag_8\n      jumpi\n        /* \"input.sol\":145:146  1 */\n      0x01\n        /* \"input.sol\":141:146  x + 1 */\n      add\n        /* \"input.sol\":209:271  for(uint x = 0; x < 10; x = unsafe_inc(x))... */\n      jump(tag_7)\n    tag_8:\n      pop\n        /* \"input.sol\":174:277  function f() public pure {... */\n      jump\t// out\n\n    auxdata: <AUXDATA REMOVED>\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_multireturn/args",
    "content": "--optimize --asm\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_multireturn/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nfunction test(uint x) pure returns (uint, uint)\n{\n    unchecked {\n        return (x + 1, x);\n    }\n}\n\ncontract C {\n    function f() public pure {\n        for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_inliner_multireturn/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":162:298  contract C {... */\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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        /* \"input.sol\":162:298  contract C {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \"input.sol\":179:296  function f() public pure {... */\n    tag_3:\n      tag_4\n      tag_5\n      jump\t// in\n    tag_4:\n      stop\n    tag_5:\n        /* \"input.sol\":219:225  uint x */\n      0x00\n        /* \"input.sol\":241:242  1 */\n      0x01\n        /* \"input.sol\":214:290  for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */\n    tag_7:\n        /* \"input.sol\":249:251  10 */\n      0x0a\n        /* \"input.sol\":245:246  x */\n      dup3\n        /* \"input.sol\":245:251  x < 10 */\n      lt\n        /* \"input.sol\":214:290  for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */\n      iszero\n      tag_8\n      jumpi\n      pop\n        /* \"input.sol\":146:147  1 */\n      0x01\n        /* \"input.sol\":142:147  x + 1 */\n      dup2\n      add\n      swap1\n        /* \"input.sol\":214:290  for((uint x, uint y) = (0, 1); x < 10; (x, y) = test(x))... */\n      jump(tag_7)\n    tag_8:\n      pop\n      pop\n        /* \"input.sol\":179:296  function f() public pure {... */\n      jump\t// out\n\n    auxdata: <AUXDATA REMOVED>\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_user_yul/args",
    "content": "--optimize --asm\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_user_yul/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C\n{\n\tconstructor() payable\n\t{\n\t\tint a;\n\n\t\t// Can't be optimized due to external reference \"a\"\n\t\tassembly\n\t\t{\n\t\t\tlet x,y,z\n\n\t\t\tsstore(0, 1)\n\n\t\t\tfor { } sload(4) { } {\n\t\t\t\tz := exp(x, y)\n\t\t\t}\n\n\t\t\ta := 2\n\t\t}\n\n\t\t// Can be optimized due to no external references\n\t\tassembly\n\t\t{\n\t\t\tlet x,y,z\n\n\t\t\tsstore(2, 3)\n\n\t\t\tfor { } sload(5) { } {\n\t\t\t\t// Expected to be optimized out for yulOptimizer, but not for\n\t\t\t\t// old optimizer\n\t\t\t\tz := exp(x, y)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/optimizer_user_yul/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":60:518  contract C... */\n  mstore(0x40, 0x80)\n    /* \"input.sol\":101:106  int a */\n  0x00\n    /* \"input.sol\":181:190  let x,y,z */\n  0x00\n  0x00\n  0x00\n    /* \"input.sol\":205:206  1 */\n  0x01\n    /* \"input.sol\":202:203  0 */\n  0x00\n    /* \"input.sol\":195:207  sstore(0, 1) */\n  sstore\n    /* \"input.sol\":212:258  for { } sload(4) { } {... */\ntag_3:\n    /* \"input.sol\":226:227  4 */\n  0x04\n    /* \"input.sol\":220:228  sload(4) */\n  sload\n    /* \"input.sol\":212:258  for { } sload(4) { } {... */\n  iszero\n  tag_5\n  jumpi\n  pop\n    /* \"input.sol\":244:253  exp(x, y) */\n  dup1\n  dup3\n  exp\n    /* \"input.sol\":212:258  for { } sload(4) { } {... */\n  jump(tag_3)\ntag_5:\n    /* \"input.sol\":216:219  { } */\n  pop\n  pop\n  pop\n    /* \"input.sol\":268:269  2 */\n  0x02\n    /* \"input.sol\":263:269  a := 2 */\n  swap1\n  pop\n    /* \"input.sol\":369:370  3 */\n  0x03\n    /* \"input.sol\":366:367  2 */\n  0x02\n    /* \"input.sol\":359:371  sstore(2, 3) */\n  sstore\n    /* \"input.sol\":390:391  5 */\n  0x05\n    /* \"input.sol\":384:392  sload(5) */\n  sload\n  iszero\n    /* \"input.sol\":376:509  for { } sload(5) { } {... */\ntag_6:\n    /* \"input.sol\":384:392  sload(5) */\n  dup1\n    /* \"input.sol\":376:509  for { } sload(5) { } {... */\n  iszero\n  tag_6\n  jumpi\n    /* \"input.sol\":380:383  { } */\n  pop\n    /* \"input.sol\":340:513  {... */\n  pop\n    /* \"input.sol\":60:518  contract C... */\n  dataSize(sub_0)\n  dup1\n  dataOffset(sub_0)\n  0x00\n  codecopy\n  0x00\n  return\nstop\n\nsub_0: assembly {\n        /* \"input.sol\":60:518  contract C... */\n      mstore(0x40, 0x80)\n      revert(0x00, 0x00)\n\n    auxdata: <AUXDATA REMOVED>\n}\n"
  },
  {
    "path": "test/cmdlineTests/pretty_json_indent_only/args",
    "content": "--json-indent 7\n"
  },
  {
    "path": "test/cmdlineTests/pretty_json_indent_only/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C {}\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/pretty_json_indent_only/no-pretty-print",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/pretty_json_indent_only/output",
    "content": "\n"
  },
  {
    "path": "test/cmdlineTests/pretty_json_indent_only/output.json",
    "content": "{\n       \"sources\": {\n              \"A\": {\n                     \"id\": 0\n              }\n       }\n}\n"
  },
  {
    "path": "test/cmdlineTests/pretty_json_standard/args",
    "content": "--pretty-json\n"
  },
  {
    "path": "test/cmdlineTests/pretty_json_standard/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C {}\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/pretty_json_standard/no-pretty-print",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/pretty_json_standard/output.json",
    "content": "{\n  \"sources\": {\n    \"A\": {\n      \"id\": 0\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/pretty_json_standard_indent/args",
    "content": "--pretty-json --json-indent 7\n"
  },
  {
    "path": "test/cmdlineTests/pretty_json_standard_indent/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { }\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/pretty_json_standard_indent/no-pretty-print",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/pretty_json_standard_indent/output",
    "content": "{\n       \"sources\":\n       {\n              \"A\":\n              {\n                     \"id\": 0\n              }\n       }\n}\n"
  },
  {
    "path": "test/cmdlineTests/pretty_json_standard_indent/output.json",
    "content": "{\n       \"sources\": {\n              \"A\": {\n                     \"id\": 0\n              }\n       }\n}\n"
  },
  {
    "path": "test/cmdlineTests/require_overload/err",
    "content": "Error: No matching declaration found after argument-dependent lookup.\n --> input.sol:5:9:\n  |\n5 |         require(this);\n  |         ^^^^^^^\nNote: Candidate: function require(bool)\nNote: Candidate: function require(bool, string memory)\nNote: Candidate: function require(bool, error)\n"
  },
  {
    "path": "test/cmdlineTests/require_overload/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/require_overload/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f() public pure {\n        require(this);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/require_with_error_ir/args",
    "content": "--ir --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/require_with_error_ir/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nerror CustomError(uint256, string);\n\ncontract C {\n    function f(bool condition) external pure {\n        require(condition, CustomError(1, \"two\"));\n    }\n\n    function g(bool condition) external pure {\n        require(condition, CustomError(2, \"three\"));\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/require_with_error_ir/output",
    "content": "IR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_36\" {\n    code {\n\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_36()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_36_deployed\"), datasize(\"C_36_deployed\"))\n\n        return(_1, datasize(\"C_36_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function constructor_C_36() {\n\n        }\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_36_deployed\" {\n        code {\n\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x98c3a6c1\n                {\n                    // f(bool)\n\n                    external_fun_f_21()\n                }\n\n                case 0xd48092f7\n                {\n                    // g(bool)\n\n                    external_fun_g_35()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_bool(value) -> cleaned {\n                cleaned := iszero(iszero(value))\n            }\n\n            function validator_revert_t_bool(value) {\n                if iszero(eq(value, cleanup_t_bool(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_bool(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_bool(value)\n            }\n\n            function abi_decode_tuple_t_bool(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_bool(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_21() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_bool(4, calldatasize())\n                fun_f_21(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function external_fun_g_35() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_bool(4, calldatasize())\n                fun_g_35(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_1_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_1_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_1_by_1(value)))\n            }\n\n            function abi_encode_t_rational_1_by_1_to_t_uint256_fromStack(value, pos) {\n                mstore(pos, convert_t_rational_1_by_1_to_t_uint256(value))\n            }\n\n            function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos {\n                mstore(pos, length)\n                updated_pos := add(pos, 0x20)\n            }\n\n            function store_literal_in_memory_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720(memPtr) {\n\n                mstore(add(memPtr, 0), \"two\")\n\n            }\n\n            function abi_encode_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720_to_t_string_memory_ptr_fromStack(pos) -> end {\n                pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, 3)\n                store_literal_in_memory_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720(pos)\n                end := add(pos, 32)\n            }\n\n            function abi_encode_tuple_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720__to_t_uint256_t_string_memory_ptr__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 64)\n\n                abi_encode_t_rational_1_by_1_to_t_uint256_fromStack(value0,  add(headStart, 0))\n\n                mstore(add(headStart, 32), sub(tail, headStart))\n                tail := abi_encode_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720_to_t_string_memory_ptr_fromStack( tail)\n\n            }\n\n            function require_helper_t_error_7_CustomError_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720(condition , expr_15) {\n                if iszero(condition)\n                {\n\n                    let memPtr := allocate_unbounded()\n\n                    mstore(memPtr, 0x97ea5a2f00000000000000000000000000000000000000000000000000000000)\n                    let end := abi_encode_tuple_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720__to_t_uint256_t_string_memory_ptr__fromStack(add(memPtr, 4) , expr_15)\n                    revert(memPtr, sub(end, memPtr))\n                }\n            }\n\n            function fun_f_21(var_condition_9) {\n\n                let _1 := var_condition_9\n                let expr_13 := _1\n\n                let expr_15 := 0x01\n\n                require_helper_t_error_7_CustomError_t_rational_1_by_1_t_stringliteral_332c39dcd398ea34a48b871898d589f55fc4c7bce00562fb670c972e7e1b0720(expr_13, expr_15)\n\n            }\n\n            function cleanup_t_rational_2_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function convert_t_rational_2_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_2_by_1(value)))\n            }\n\n            function abi_encode_t_rational_2_by_1_to_t_uint256_fromStack(value, pos) {\n                mstore(pos, convert_t_rational_2_by_1_to_t_uint256(value))\n            }\n\n            function store_literal_in_memory_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5(memPtr) {\n\n                mstore(add(memPtr, 0), \"three\")\n\n            }\n\n            function abi_encode_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5_to_t_string_memory_ptr_fromStack(pos) -> end {\n                pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, 5)\n                store_literal_in_memory_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5(pos)\n                end := add(pos, 32)\n            }\n\n            function abi_encode_tuple_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5__to_t_uint256_t_string_memory_ptr__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 64)\n\n                abi_encode_t_rational_2_by_1_to_t_uint256_fromStack(value0,  add(headStart, 0))\n\n                mstore(add(headStart, 32), sub(tail, headStart))\n                tail := abi_encode_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5_to_t_string_memory_ptr_fromStack( tail)\n\n            }\n\n            function require_helper_t_error_7_CustomError_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5(condition , expr_29) {\n                if iszero(condition)\n                {\n\n                    let memPtr := allocate_unbounded()\n\n                    mstore(memPtr, 0x97ea5a2f00000000000000000000000000000000000000000000000000000000)\n                    let end := abi_encode_tuple_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5__to_t_uint256_t_string_memory_ptr__fromStack(add(memPtr, 4) , expr_29)\n                    revert(memPtr, sub(end, memPtr))\n                }\n            }\n\n            function fun_g_35(var_condition_23) {\n\n                let _2 := var_condition_23\n                let expr_27 := _2\n\n                let expr_29 := 0x02\n\n                require_helper_t_error_7_CustomError_t_rational_2_by_1_t_stringliteral_89027a4db8d1d3a0787296eb1553fba0dc506f981f9697f1a66994c458d392b5(expr_27, expr_29)\n\n            }\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n"
  },
  {
    "path": "test/cmdlineTests/require_with_string_ir/args",
    "content": "--ir --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/require_with_string_ir/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f(bool condition) external pure {\n        string memory message = \"Condition must be satisfied\";\n        require(condition, message);\n    }\n\n    function g(bool condition) external pure {\n        require(condition, \"Condition must be satisfied\");\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/require_with_string_ir/output",
    "content": "IR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_28\" {\n    code {\n\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_28()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_28_deployed\"), datasize(\"C_28_deployed\"))\n\n        return(_1, datasize(\"C_28_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function constructor_C_28() {\n\n        }\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_28_deployed\" {\n        code {\n\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x98c3a6c1\n                {\n                    // f(bool)\n\n                    external_fun_f_16()\n                }\n\n                case 0xd48092f7\n                {\n                    // g(bool)\n\n                    external_fun_g_27()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_bool(value) -> cleaned {\n                cleaned := iszero(iszero(value))\n            }\n\n            function validator_revert_t_bool(value) {\n                if iszero(eq(value, cleanup_t_bool(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_bool(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_bool(value)\n            }\n\n            function abi_decode_tuple_t_bool(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_bool(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_16() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_bool(4, calldatasize())\n                fun_f_16(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function external_fun_g_27() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_bool(4, calldatasize())\n                fun_g_27(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function round_up_to_mul_of_32(value) -> result {\n                result := and(add(value, 31), not(31))\n            }\n\n            function panic_error_0x41() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x41)\n                revert(0, 0x24)\n            }\n\n            function finalize_allocation(memPtr, size) {\n                let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n                // protect against overflow\n                if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n                mstore(64, newFreePtr)\n            }\n\n            function allocate_memory(size) -> memPtr {\n                memPtr := allocate_unbounded()\n                finalize_allocation(memPtr, size)\n            }\n\n            function array_allocation_size_t_string_memory_ptr(length) -> size {\n                // Make sure we can allocate memory without overflow\n                if gt(length, 0xffffffffffffffff) { panic_error_0x41() }\n\n                size := round_up_to_mul_of_32(length)\n\n                // add length slot\n                size := add(size, 0x20)\n\n            }\n\n            function allocate_memory_array_t_string_memory_ptr(length) -> memPtr {\n                let allocSize := array_allocation_size_t_string_memory_ptr(length)\n                memPtr := allocate_memory(allocSize)\n\n                mstore(memPtr, length)\n\n            }\n\n            function store_literal_in_memory_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46(memPtr) {\n\n                mstore(add(memPtr, 0), \"Condition must be satisfied\")\n\n            }\n\n            function copy_literal_to_memory_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46() -> memPtr {\n                memPtr := allocate_memory_array_t_string_memory_ptr(27)\n                store_literal_in_memory_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46(add(memPtr, 32))\n            }\n\n            function convert_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46_to_t_string_memory_ptr() -> converted {\n                converted := copy_literal_to_memory_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46()\n            }\n\n            function array_length_t_string_memory_ptr(value) -> length {\n\n                length := mload(value)\n\n            }\n\n            function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos {\n                mstore(pos, length)\n                updated_pos := add(pos, 0x20)\n            }\n\n            function copy_memory_to_memory_with_cleanup(src, dst, length) {\n\n                mcopy(dst, src, length)\n                mstore(add(dst, length), 0)\n\n            }\n\n            function abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value, pos) -> end {\n                let length := array_length_t_string_memory_ptr(value)\n                pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length)\n                copy_memory_to_memory_with_cleanup(add(value, 0x20), pos, length)\n                end := add(pos, round_up_to_mul_of_32(length))\n            }\n\n            function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 32)\n\n                mstore(add(headStart, 0), sub(tail, headStart))\n                tail := abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value0,  tail)\n\n            }\n\n            function require_helper_t_string_memory_ptr(condition , expr_12_mpos) {\n                if iszero(condition)\n                {\n\n                    let memPtr := allocate_unbounded()\n\n                    mstore(memPtr, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n                    let end := abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(add(memPtr, 4) , expr_12_mpos)\n                    revert(memPtr, sub(end, memPtr))\n                }\n            }\n\n            function fun_f_16(var_condition_3) {\n\n                let var_message_7_mpos := convert_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46_to_t_string_memory_ptr()\n\n                let _1 := var_condition_3\n                let expr_11 := _1\n\n                let _2_mpos := var_message_7_mpos\n                let expr_12_mpos := _2_mpos\n\n                require_helper_t_string_memory_ptr(expr_11, expr_12_mpos)\n\n            }\n\n            function abi_encode_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46_to_t_string_memory_ptr_fromStack(pos) -> end {\n                pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, 27)\n                store_literal_in_memory_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46(pos)\n                end := add(pos, 32)\n            }\n\n            function abi_encode_tuple_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46__to_t_string_memory_ptr__fromStack(headStart ) -> tail {\n                tail := add(headStart, 32)\n\n                mstore(add(headStart, 0), sub(tail, headStart))\n                tail := abi_encode_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46_to_t_string_memory_ptr_fromStack( tail)\n\n            }\n\n            function require_helper_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46(condition ) {\n                if iszero(condition)\n                {\n\n                    let memPtr := allocate_unbounded()\n\n                    mstore(memPtr, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n                    let end := abi_encode_tuple_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46__to_t_string_memory_ptr__fromStack(add(memPtr, 4) )\n                    revert(memPtr, sub(end, memPtr))\n                }\n            }\n\n            function fun_g_27(var_condition_18) {\n\n                let _3 := var_condition_18\n                let expr_22 := _3\n\n                require_helper_t_stringliteral_b25d43cff48de8365ad132c5f45b74f4593f9e69e5b749d86685f77282c88e46(expr_22)\n\n            }\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n"
  },
  {
    "path": "test/cmdlineTests/revert_strings/args",
    "content": "--revert-strings debug --ir"
  },
  {
    "path": "test/cmdlineTests/revert_strings/input.sol",
    "content": "pragma solidity >=0.0;\n// SPDX-License-Identifier: GPL-3.0\ncontract C {\n    enum E { X }\n    function f(uint[][] memory, E e) public pure {\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/revert_strings/output",
    "content": "IR:\n\n/// @use-src 0:\"input.sol\"\nobject \"C_15\" {\n    code {\n        /// @src 0:59:147  \"contract C {...\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_15()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_15_deployed\"), datasize(\"C_15_deployed\"))\n\n        return(_1, datasize(\"C_15_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n\n            let start := allocate_unbounded()\n            let pos := start\n            mstore(pos, 3963877391197344453575983046348115674221700746820753546331534351508065746944)\n            pos := add(pos, 4)\n            mstore(pos, 0x20)\n            pos := add(pos, 0x20)\n            mstore(pos, 34)\n            pos := add(pos, 0x20)\n\n            mstore(add(pos, 0), \"Ether sent to non-payable functi\")\n\n            mstore(add(pos, 32), \"on\")\n\n            revert(start, 132)\n\n        }\n\n        /// @src 0:59:147  \"contract C {...\"\n        function constructor_C_15() {\n\n            /// @src 0:59:147  \"contract C {...\"\n\n        }\n        /// @src 0:59:147  \"contract C {...\"\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_15_deployed\" {\n        code {\n            /// @src 0:59:147  \"contract C {...\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x02e8cd18\n                {\n                    // f(uint256[][],uint8)\n\n                    external_fun_f_14()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n\n                let start := allocate_unbounded()\n                let pos := start\n                mstore(pos, 3963877391197344453575983046348115674221700746820753546331534351508065746944)\n                pos := add(pos, 4)\n                mstore(pos, 0x20)\n                pos := add(pos, 0x20)\n                mstore(pos, 34)\n                pos := add(pos, 0x20)\n\n                mstore(add(pos, 0), \"Ether sent to non-payable functi\")\n\n                mstore(add(pos, 32), \"on\")\n\n                revert(start, 132)\n\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n\n                let start := allocate_unbounded()\n                let pos := start\n                mstore(pos, 3963877391197344453575983046348115674221700746820753546331534351508065746944)\n                pos := add(pos, 4)\n                mstore(pos, 0x20)\n                pos := add(pos, 0x20)\n                mstore(pos, 34)\n                pos := add(pos, 0x20)\n\n                mstore(add(pos, 0), \"ABI decoding: tuple data too sho\")\n\n                mstore(add(pos, 32), \"rt\")\n\n                revert(start, 132)\n\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n\n                let start := allocate_unbounded()\n                let pos := start\n                mstore(pos, 3963877391197344453575983046348115674221700746820753546331534351508065746944)\n                pos := add(pos, 4)\n                mstore(pos, 0x20)\n                pos := add(pos, 0x20)\n                mstore(pos, 34)\n                pos := add(pos, 0x20)\n\n                mstore(add(pos, 0), \"ABI decoding: invalid tuple offs\")\n\n                mstore(add(pos, 32), \"et\")\n\n                revert(start, 132)\n\n            }\n\n            function revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() {\n\n                let start := allocate_unbounded()\n                let pos := start\n                mstore(pos, 3963877391197344453575983046348115674221700746820753546331534351508065746944)\n                pos := add(pos, 4)\n                mstore(pos, 0x20)\n                pos := add(pos, 0x20)\n                mstore(pos, 43)\n                pos := add(pos, 0x20)\n\n                mstore(add(pos, 0), \"ABI decoding: invalid calldata a\")\n\n                mstore(add(pos, 32), \"rray offset\")\n\n                revert(start, 132)\n\n            }\n\n            function round_up_to_mul_of_32(value) -> result {\n                result := and(add(value, 31), not(31))\n            }\n\n            function panic_error_0x41() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x41)\n                revert(0, 0x24)\n            }\n\n            function finalize_allocation(memPtr, size) {\n                let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n                // protect against overflow\n                if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n                mstore(64, newFreePtr)\n            }\n\n            function allocate_memory(size) -> memPtr {\n                memPtr := allocate_unbounded()\n                finalize_allocation(memPtr, size)\n            }\n\n            function array_allocation_size_t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptr(length) -> size {\n                // Make sure we can allocate memory without overflow\n                if gt(length, 0xffffffffffffffff) { panic_error_0x41() }\n\n                size := mul(length, 0x20)\n\n                // add length slot\n                size := add(size, 0x20)\n\n            }\n\n            function revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef() {\n\n                let start := allocate_unbounded()\n                let pos := start\n                mstore(pos, 3963877391197344453575983046348115674221700746820753546331534351508065746944)\n                pos := add(pos, 4)\n                mstore(pos, 0x20)\n                pos := add(pos, 0x20)\n                mstore(pos, 43)\n                pos := add(pos, 0x20)\n\n                mstore(add(pos, 0), \"ABI decoding: invalid calldata a\")\n\n                mstore(add(pos, 32), \"rray stride\")\n\n                revert(start, 132)\n\n            }\n\n            function array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr(length) -> size {\n                // Make sure we can allocate memory without overflow\n                if gt(length, 0xffffffffffffffff) { panic_error_0x41() }\n\n                size := mul(length, 0x20)\n\n                // add length slot\n                size := add(size, 0x20)\n\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            // uint256[]\n            function abi_decode_available_length_t_array$_t_uint256_$dyn_memory_ptr(offset, length, end) -> array {\n                array := allocate_memory(array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr(length))\n                let dst := array\n\n                mstore(array, length)\n                dst := add(array, 0x20)\n\n                let srcEnd := add(offset, mul(length, 0x20))\n                if gt(srcEnd, end) {\n                    revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef()\n                }\n                for { let src := offset } lt(src, srcEnd) { src := add(src, 0x20) }\n                {\n\n                    let elementPos := src\n\n                    mstore(dst, abi_decode_t_uint256(elementPos, end))\n                    dst := add(dst, 0x20)\n                }\n            }\n\n            // uint256[]\n            function abi_decode_t_array$_t_uint256_$dyn_memory_ptr(offset, end) -> array {\n                if iszero(slt(add(offset, 0x1f), end)) { revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() }\n                let length := calldataload(offset)\n                array := abi_decode_available_length_t_array$_t_uint256_$dyn_memory_ptr(add(offset, 0x20), length, end)\n            }\n\n            // uint256[][]\n            function abi_decode_available_length_t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptr(offset, length, end) -> array {\n                array := allocate_memory(array_allocation_size_t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptr(length))\n                let dst := array\n\n                mstore(array, length)\n                dst := add(array, 0x20)\n\n                let srcEnd := add(offset, mul(length, 0x20))\n                if gt(srcEnd, end) {\n                    revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef()\n                }\n                for { let src := offset } lt(src, srcEnd) { src := add(src, 0x20) }\n                {\n\n                    let innerOffset := calldataload(src)\n                    if gt(innerOffset, 0xffffffffffffffff) { revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() }\n                    let elementPos := add(offset, innerOffset)\n\n                    mstore(dst, abi_decode_t_array$_t_uint256_$dyn_memory_ptr(elementPos, end))\n                    dst := add(dst, 0x20)\n                }\n            }\n\n            // uint256[][]\n            function abi_decode_t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptr(offset, end) -> array {\n                if iszero(slt(add(offset, 0x1f), end)) { revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() }\n                let length := calldataload(offset)\n                array := abi_decode_available_length_t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptr(add(offset, 0x20), length, end)\n            }\n\n            function validator_revert_t_enum$_E_$3(value) {\n                if iszero(lt(value, 1)) { revert(0, 0) }\n            }\n\n            function abi_decode_t_enum$_E_$3(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_enum$_E_$3(value)\n            }\n\n            function abi_decode_tuple_t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptrt_enum$_E_$3(headStart, dataEnd) -> value0, value1 {\n                if slt(sub(dataEnd, headStart), 64) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := calldataload(add(headStart, 0))\n                    if gt(offset, 0xffffffffffffffff) { revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() }\n\n                    value0 := abi_decode_t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptr(add(headStart, offset), dataEnd)\n                }\n\n                {\n\n                    let offset := 32\n\n                    value1 := abi_decode_t_enum$_E_$3(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_14() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0, param_1 :=  abi_decode_tuple_t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptrt_enum$_E_$3(4, calldatasize())\n                fun_f_14(param_0, param_1)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n\n                let start := allocate_unbounded()\n                let pos := start\n                mstore(pos, 3963877391197344453575983046348115674221700746820753546331534351508065746944)\n                pos := add(pos, 4)\n                mstore(pos, 0x20)\n                pos := add(pos, 0x20)\n                mstore(pos, 53)\n                pos := add(pos, 0x20)\n\n                mstore(add(pos, 0), \"Contract does not have fallback \")\n\n                mstore(add(pos, 32), \"nor receive functions\")\n\n                revert(start, 132)\n\n            }\n\n            /// @ast-id 14\n            /// @src 0:93:145  \"function f(uint[][] memory, E e) public pure {...\"\n            function fun_f_14(var__7_mpos, var_e_10) {\n\n            }\n            /// @src 0:59:147  \"contract C {...\"\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n"
  },
  {
    "path": "test/cmdlineTests/stack_too_deep_from_code_transform/args",
    "content": "--via-ir --bin\n"
  },
  {
    "path": "test/cmdlineTests/stack_too_deep_from_code_transform/err",
    "content": "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 ]\nmemoryguard was present.\n --> input.sol:1:1:\n  |\n1 | contract C {\n  | ^ (Relevant source part starts here and spans across multiple lines).\n"
  },
  {
    "path": "test/cmdlineTests/stack_too_deep_from_code_transform/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/stack_too_deep_from_code_transform/input.sol",
    "content": "contract C {\n    function f() public {\n        uint b;\n        abi.encodePacked(\n            b, b, b, b, b, b, b, b,\n            b, b, b, b, b, b, b, b,\n            b, b, b, b, b, b, b, b\n        );\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/args",
    "content": "--experimental --import-ast -\n"
  },
  {
    "path": "test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/err",
    "content": "Error: Failed to import AST: Expected field \"baseSlotExpression\" is missing.\n"
  },
  {
    "path": "test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/standard_cli_import_ast_storage_layout_specifier_missing_expression/stdin",
    "content": "{\n    \"language\": \"SolidityAST\",\n    \"sources\": {\n        \"A\": {\n            \"AST\": {\n                \"absolutePath\": \"A\",\n                \"exportedSymbols\": {\n                    \"C\": [\n                        4\n                    ]\n                },\n                \"id\": 5,\n                \"license\": \"GPL-3.0\",\n                \"nodeType\": \"SourceUnit\",\n                \"nodes\": [\n                    {\n                        \"id\": 1,\n                        \"literals\": [\n                            \"solidity\",\n                            \">=\",\n                            \"0.0\"\n                        ],\n                        \"nodeType\": \"PragmaDirective\",\n                        \"src\": \"36:22:0\"\n                    },\n                    {\n                        \"abstract\": false,\n                        \"baseContracts\": [],\n                        \"canonicalName\": \"C\",\n                        \"contractDependencies\": [],\n                        \"contractKind\": \"contract\",\n                        \"fullyImplemented\": true,\n                        \"id\": 4,\n                        \"linearizedBaseContracts\": [\n                            4\n                        ],\n                        \"name\": \"C\",\n                        \"nameLocation\": \"69:1:0\",\n                        \"nodeType\": \"ContractDefinition\",\n                        \"nodes\": [],\n                        \"scope\": 5,\n                        \"src\": \"60:28:0\",\n                        \"storageLayout\": {\n                            \"id\": 3,\n                            \"nodeType\": \"StorageLayoutSpecifier\",\n                            \"src\": \"71:16:0\"\n                        },\n                        \"usedErrors\": [],\n                        \"usedEvents\": []\n                    }\n                ],\n                \"src\": \"36:53:0\"\n            },\n            \"id\": 0\n        }\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"*\": { \"*\": [] }\n        }\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/standard_cli_output_selection_invalid/args",
    "content": "--ast-compact-json --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --hashes --userdoc --devdoc --metadata --storage-layout\n"
  },
  {
    "path": "test/cmdlineTests/standard_cli_output_selection_invalid/err",
    "content": "Error: The following outputs are not supported in standard JSON mode: --abi, --asm, --asm-json, --ast-compact-json, --bin, --bin-runtime, --devdoc, --hashes, --ir, --ir-optimized, --metadata, --opcodes, --storage-layout, --userdoc.\n"
  },
  {
    "path": "test/cmdlineTests/standard_cli_output_selection_invalid/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/standard_cli_output_selection_invalid/input.json",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"C\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-2.0\\npragma solidity >=0.0;\\npragma abicoder v2;\\n\\ncontract C\\n{\\n    int constant constVar = 41;\\n    int immutable immutVar = 42;\\n    int public stateVar;\\n\\n    constructor(int _init)\\n    {\\n        stateVar = _init;\\n    }\\n\\n    function f() external pure returns (int)\\n    {\\n        return constVar + immutVar;\\n    }\\n    modifier m()\\n    {\\n        stateVar++;\\n        _;\\n    }\\n    function f2() m public returns (int)\\n    {\\n        return stateVar + this.f() + immutVar;\\n    }\\n}\\n\"\n\t\t},\n\t\t\"D\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-2.0\\npragma solidity >=0.0;\\npragma abicoder v2;\\nimport \\\"C\\\";\\n\\ncontract D is C(3)\\n{\\n    constructor(int _init2)\\n    {\\n        stateVar += _init2;\\n    }\\n}\\n\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"viaIR\": true,\n\t\t\"optimizer\": { \"enabled\": true },\n\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"evm.assembly\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_evm_asm_via_ir_location/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"C\\\":79:503  contract C... */\n  0xa0\n  jumpi(tag_5, callvalue)\n  0x1f\n  bytecodeSize\n  codesize\n  dup2\n  swap1\n  sub\n  swap2\n  dup3\n  add\n  not(0x1f)\n  and\n  dup4\n  add\n  swap2\n  sub(shl(0x40, 0x01), 0x01)\n  dup4\n  gt\n  dup5\n  dup5\n  lt\n  or\n  tag_3\n  jumpi\n  dup1\n  dup5\n  swap3\n  0x20\n  swap5\n  0x40\n  mstore\n  dup4\n  codecopy\n  dup2\n  add\n  sub\n  slt\n  tag_5\n  jumpi\n  mload\n    /* \\\"C\\\":153:155  42 */\n  mstore(0x80, 0x2a)\n  0x00\n    /* \\\"C\\\":79:503  contract C... */\n  sstore\n  mload(0x40)\n  dataSize(sub_0)\n  swap1\n  dup2\n  dataOffset(sub_0)\n  dup3\n  codecopy\n    /* \\\"C\\\":153:155  42 */\n  0x80\n    /* \\\"C\\\":79:503  contract C... */\n  mload\n  dup2\n  assignImmutable(\\\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\\\")\n  return\ntag_5:\n  0x00\n  dup1\n  revert\ntag_3:\n  mstore(0x00, shl(0xe0, 0x4e487b71))\n  mstore(0x04, 0x41)\n  revert(0x00, 0x24)\nstop\n\nsub_0: assembly {\n        /* \\\"C\\\":79:503  contract C... */\n      mstore(0x40, 0x80)\n      jumpi(tag_2, iszero(lt(calldatasize, 0x04)))\n      0x00\n      dup1\n      revert\n    tag_2:\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_4\n      jumpi\n      dup1\n      0x793816ec\n      eq\n      tag_6\n      jumpi\n      0x9942ec6f\n      eq\n      tag_8\n      jumpi\n      0x00\n      dup1\n      revert\n    tag_8:\n      jumpi(tag_26, callvalue)\n      jumpi(tag_26, slt(add(not(0x03), calldatasize), 0x00))\n      sload(0x00)\n      sub(shl(0xff, 0x01), 0x01)\n      dup2\n      eq\n      tag_14\n      jumpi\n      0x01\n      add\n      0x00\n      dup2\n      swap1\n      sstore\n      mload(0x40)\n      shl(0xe4, 0x026121ff)\n        /* \\\"C\\\":475:483  this.f() */\n      dup2\n      mstore\n        /* \\\"C\\\":79:503  contract C... */\n      swap1\n        /* \\\"C\\\":475:483  this.f() */\n      0x20\n        /* \\\"C\\\":79:503  contract C... */\n      dup3\n      0x04\n      dup2\n        /* \\\"C\\\":475:479  this */\n      address\n        /* \\\"C\\\":475:483  this.f() */\n      gas\n      staticcall\n      swap2\n      dup3\n      iszero\n      tag_16\n      jumpi\n        /* \\\"C\\\":79:503  contract C... */\n      0x00\n        /* \\\"C\\\":475:483  this.f() */\n      swap3\n      tag_18\n      jumpi\n        /* \\\"C\\\":79:503  contract C... */\n    tag_19:\n        /* \\\"C\\\":475:483  this.f() */\n      0x20\n        /* \\\"C\\\":464:494  stateVar + this.f() + immutVar */\n      tag_20\n        /* \\\"C\\\":464:483  stateVar + this.f() */\n      tag_21\n      dup6\n      dup6\n      tag_1\n      jump\\t// in\n    tag_21:\n        /* \\\"C\\\":486:494  immutVar */\n      immutable(\\\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\\\")\n        /* \\\"C\\\":464:494  stateVar + this.f() + immutVar */\n      swap1\n      tag_1\n      jump\\t// in\n    tag_20:\n        /* \\\"C\\\":79:503  contract C... */\n      mload(0x40)\n      swap1\n      dup2\n      mstore\n      return\n        /* \\\"C\\\":475:483  this.f() */\n    tag_18:\n      swap2\n      pop\n      0x20\n      jumpi(tag_22, gt(0x20, returndatasize))\n    tag_23:\n        /* \\\"C\\\":79:503  contract C... */\n      0x1f\n      dup2\n      add\n      not(0x1f)\n      and\n      dup4\n      add\n      0xffffffffffffffff\n      dup2\n      gt\n      dup5\n      dup3\n      lt\n      or\n      tag_24\n      jumpi\n        /* \\\"C\\\":475:483  this.f() */\n      0x20\n        /* \\\"C\\\":79:503  contract C... */\n      swap2\n      dup5\n      swap2\n      0x40\n      mstore\n        /* \\\"C\\\":475:483  this.f() */\n      dup2\n      add\n        /* \\\"C\\\":79:503  contract C... */\n      sub\n      slt\n      tag_26\n      jumpi\n      swap1\n      mload\n      swap1\n        /* \\\"C\\\":464:483  stateVar + this.f() */\n      tag_21\n        /* \\\"C\\\":475:483  this.f() */\n      jump(tag_19)\n        /* \\\"C\\\":79:503  contract C... */\n    tag_26:\n      0x00\n      dup1\n      revert\n    tag_24:\n        /* \\\"C\\\":120:122  41 */\n      shl(0xe0, 0x4e487b71)\n        /* \\\"C\\\":79:503  contract C... */\n      0x00\n      mstore\n      mstore(0x04, 0x41)\n      revert(0x00, 0x24)\n        /* \\\"C\\\":475:483  this.f() */\n    tag_22:\n      pop\n      returndatasize\n      jump(tag_23)\n    tag_16:\n        /* \\\"C\\\":79:503  contract C... */\n      mload(0x40)\n      returndatasize\n      0x00\n      dup3\n      returndatacopy\n      returndatasize\n      swap1\n      revert\n    tag_14:\n        /* \\\"C\\\":120:122  41 */\n      shl(0xe0, 0x4e487b71)\n        /* \\\"C\\\":79:503  contract C... */\n      0x00\n        /* \\\"C\\\":120:122  41 */\n      mstore\n      0x11\n        /* \\\"C\\\":79:503  contract C... */\n      0x04\n        /* \\\"C\\\":120:122  41 */\n      mstore\n      0x24\n        /* \\\"C\\\":79:503  contract C... */\n      0x00\n        /* \\\"C\\\":120:122  41 */\n      revert\n        /* \\\"C\\\":79:503  contract C... */\n    tag_6:\n      jumpi(tag_26, callvalue)\n      jumpi(tag_26, slt(add(not(0x03), calldatasize), 0x00))\n      0x20\n      sload(0x00)\n      mload(0x40)\n      swap1\n      dup2\n      mstore\n      return\n    tag_4:\n      jumpi(tag_26, callvalue)\n      jumpi(tag_26, slt(add(not(0x03), calldatasize), 0x00))\n        /* \\\"C\\\":326:334  immutVar */\n      immutable(\\\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\\\")\n        /* \\\"C\\\":120:122  41 */\n      dup1\n      0x29\n      add\n      swap1\n      dup2\n      slt\n      0x01\n      and\n      tag_14\n      jumpi\n        /* \\\"C\\\":79:503  contract C... */\n      0x20\n      swap1\n      mload(0x40)\n      swap1\n      dup2\n      mstore\n      return\n        /* \\\"C\\\":120:122  41 */\n    tag_1:\n      swap2\n      swap1\n      swap2\n      0x00\n      dup4\n      dup3\n      add\n      swap4\n      dup5\n      slt\n      swap2\n      slt\n      swap1\n      dup1\n      iszero\n      dup3\n      and\n      swap2\n      iszero\n      and\n      or\n      tag_14\n      jumpi\n      jump\\t// out\n\n    auxdata: <AUXDATA REMOVED>\n}\n\"\n                }\n            }\n        },\n        \"D\": {\n            \"D\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"D\\\":91:181  contract D is C(3)... */\n  0xa0\n  jumpi(tag_5, callvalue)\n  0x1f\n  bytecodeSize\n  codesize\n  dup2\n  swap1\n  sub\n  swap2\n  dup3\n  add\n  not(0x1f)\n  and\n  dup4\n  add\n  swap2\n  sub(shl(0x40, 0x01), 0x01)\n  dup4\n  gt\n  dup5\n  dup5\n  lt\n  or\n  tag_3\n  jumpi\n  dup1\n  dup5\n  swap3\n  0x20\n  swap5\n  0x40\n  mstore\n  dup4\n  codecopy\n  dup2\n  add\n  sub\n  slt\n  tag_5\n  jumpi\n  mload\n    /* \\\"C\\\":153:155  42 */\n  mstore(0x80, 0x2a)\n    /* \\\"D\\\":91:181  contract D is C(3)... */\n  dup1\n    /* \\\"D\\\":107:108  3 */\n  0x03\n    /* \\\"D\\\":91:181  contract D is C(3)... */\n  add\n  swap1\n  dup2\n  slt\n  0x01\n  and\n  tag_7\n  jumpi\n  0x00\n  sstore\n  mload(0x40)\n  dataSize(sub_0)\n  swap1\n  dup2\n  dataOffset(sub_0)\n  dup3\n  codecopy\n    /* \\\"C\\\":153:155  42 */\n  0x80\n    /* \\\"D\\\":91:181  contract D is C(3)... */\n  mload\n  dup2\n  assignImmutable(\\\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\\\")\n  return\ntag_7:\n  mstore(0x00, shl(0xe0, 0x4e487b71))\n  mstore(0x04, 0x11)\n  revert(0x00, 0x24)\ntag_5:\n  0x00\n  dup1\n  revert\ntag_3:\n  mstore(0x00, shl(0xe0, 0x4e487b71))\n  mstore(0x04, 0x41)\n  revert(0x00, 0x24)\nstop\n\nsub_0: assembly {\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      mstore(0x40, 0x80)\n      jumpi(tag_2, iszero(lt(calldatasize, 0x04)))\n      0x00\n      dup1\n      revert\n    tag_2:\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_4\n      jumpi\n      dup1\n      0x793816ec\n      eq\n      tag_6\n      jumpi\n      0x9942ec6f\n      eq\n      tag_8\n      jumpi\n      0x00\n      dup1\n      revert\n    tag_8:\n      jumpi(tag_26, callvalue)\n      jumpi(tag_26, slt(add(not(0x03), calldatasize), 0x00))\n      sload(0x00)\n      sub(shl(0xff, 0x01), 0x01)\n      dup2\n      eq\n      tag_14\n      jumpi\n      0x01\n      add\n      0x00\n      dup2\n      swap1\n      sstore\n      mload(0x40)\n      shl(0xe4, 0x026121ff)\n        /* \\\"C\\\":475:483  this.f() */\n      dup2\n      mstore\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      swap1\n        /* \\\"C\\\":475:483  this.f() */\n      0x20\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      dup3\n      0x04\n      dup2\n        /* \\\"C\\\":475:479  this */\n      address\n        /* \\\"C\\\":475:483  this.f() */\n      gas\n      staticcall\n      swap2\n      dup3\n      iszero\n      tag_16\n      jumpi\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      0x00\n        /* \\\"C\\\":475:483  this.f() */\n      swap3\n      tag_18\n      jumpi\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n    tag_19:\n        /* \\\"C\\\":475:483  this.f() */\n      0x20\n        /* \\\"C\\\":464:494  stateVar + this.f() + immutVar */\n      tag_20\n        /* \\\"C\\\":464:483  stateVar + this.f() */\n      tag_21\n      dup6\n      dup6\n      tag_1\n      jump\\t// in\n    tag_21:\n        /* \\\"C\\\":486:494  immutVar */\n      immutable(\\\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\\\")\n        /* \\\"C\\\":464:494  stateVar + this.f() + immutVar */\n      swap1\n      tag_1\n      jump\\t// in\n    tag_20:\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      mload(0x40)\n      swap1\n      dup2\n      mstore\n      return\n        /* \\\"C\\\":475:483  this.f() */\n    tag_18:\n      swap2\n      pop\n      0x20\n      jumpi(tag_22, gt(0x20, returndatasize))\n    tag_23:\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      0x1f\n      dup2\n      add\n      not(0x1f)\n      and\n      dup4\n      add\n      0xffffffffffffffff\n      dup2\n      gt\n      dup5\n      dup3\n      lt\n      or\n      tag_24\n      jumpi\n        /* \\\"C\\\":475:483  this.f() */\n      0x20\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      swap2\n      dup5\n      swap2\n      0x40\n      mstore\n        /* \\\"C\\\":475:483  this.f() */\n      dup2\n      add\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      sub\n      slt\n      tag_26\n      jumpi\n      swap1\n      mload\n      swap1\n        /* \\\"C\\\":464:483  stateVar + this.f() */\n      tag_21\n        /* \\\"C\\\":475:483  this.f() */\n      jump(tag_19)\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n    tag_26:\n      0x00\n      dup1\n      revert\n    tag_24:\n        /* \\\"C\\\":120:122  41 */\n      shl(0xe0, 0x4e487b71)\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      0x00\n      mstore\n      mstore(0x04, 0x41)\n      revert(0x00, 0x24)\n        /* \\\"C\\\":475:483  this.f() */\n    tag_22:\n      pop\n      returndatasize\n      jump(tag_23)\n    tag_16:\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      mload(0x40)\n      returndatasize\n      0x00\n      dup3\n      returndatacopy\n      returndatasize\n      swap1\n      revert\n    tag_14:\n        /* \\\"C\\\":120:122  41 */\n      shl(0xe0, 0x4e487b71)\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      0x00\n        /* \\\"C\\\":120:122  41 */\n      mstore\n      0x11\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      0x04\n        /* \\\"C\\\":120:122  41 */\n      mstore\n      0x24\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      0x00\n        /* \\\"C\\\":120:122  41 */\n      revert\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n    tag_6:\n      jumpi(tag_26, callvalue)\n      jumpi(tag_26, slt(add(not(0x03), calldatasize), 0x00))\n      0x20\n      sload(0x00)\n      mload(0x40)\n      swap1\n      dup2\n      mstore\n      return\n    tag_4:\n      jumpi(tag_26, callvalue)\n      jumpi(tag_26, slt(add(not(0x03), calldatasize), 0x00))\n        /* \\\"C\\\":326:334  immutVar */\n      immutable(\\\"0xe4b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10\\\")\n        /* \\\"C\\\":120:122  41 */\n      dup1\n      0x29\n      add\n      swap1\n      dup2\n      slt\n      0x01\n      and\n      tag_14\n      jumpi\n        /* \\\"D\\\":91:181  contract D is C(3)... */\n      0x20\n      swap1\n      mload(0x40)\n      swap1\n      dup2\n      mstore\n      return\n        /* \\\"C\\\":120:122  41 */\n    tag_1:\n      swap2\n      swap1\n      swap2\n      0x00\n      dup4\n      dup3\n      add\n      swap4\n      dup5\n      slt\n      swap2\n      slt\n      swap1\n      dup1\n      iszero\n      dup3\n      and\n      swap2\n      iszero\n      and\n      or\n      tag_14\n      jumpi\n      jump\\t// out\n\n    auxdata: <AUXDATA REMOVED>\n}\n\"\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        },\n        \"D\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/in.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"debug\": {\"debugInfo\": [\"*\"]},\n\t\t\"optimizer\": {\"enabled\": true},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"ir\", \"irOptimized\", \"evm.assembly\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_all/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"C\\\":60:101  contract C {... */\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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        /* \\\"C\\\":60:101  contract C {... */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \\\"C\\\":77:99  function f() public {} */\n    tag_3:\n      stop\n\n    auxdata: <AUXDATA REMOVED>\n}\n\"\n                },\n                \"ir\": \"\n/// @use-src 0:\\\"C\\\"\nobject \\\"C_6\\\" {\n    code {\n        /// @src 0:60:101  \\\"contract C {...\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_6()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_6_deployed\\\"), datasize(\\\"C_6_deployed\\\"))\n\n        return(_1, datasize(\\\"C_6_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:60:101  \\\"contract C {...\\\"\n        function constructor_C_6() {\n\n            /// @src 0:60:101  \\\"contract C {...\\\"\n\n        }\n        /// @src 0:60:101  \\\"contract C {...\\\"\n\n    }\n    /// @use-src 0:\\\"C\\\"\n    object \\\"C_6_deployed\\\" {\n        code {\n            /// @src 0:60:101  \\\"contract C {...\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_5()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_5() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                fun_f_5()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            /// @ast-id 5\n            /// @src 0:77:99  \\\"function f() public {}\\\"\n            function fun_f_5() {\n\n            }\n            /// @src 0:60:101  \\\"contract C {...\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\",\n                \"irOptimized\": \"/// @use-src 0:\\\"C\\\"\nobject \\\"C_6\\\" {\n    code {\n        {\n            /// @src 0:60:101  \\\"contract C {...\\\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\\\"C_6_deployed\\\")\n            codecopy(_1, dataoffset(\\\"C_6_deployed\\\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\\\"C\\\"\n    object \\\"C_6_deployed\\\" {\n        code {\n            {\n                /// @src 0:60:101  \\\"contract C {...\\\"\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        return(0, 0)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/in.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"debug\": {\"debugInfo\": [\"location\"]},\n\t\t\"optimizer\": {\"enabled\": true},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"ir\", \"irOptimized\", \"evm.assembly\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_location_only/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"C\\\":60:101 */\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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        /* \\\"C\\\":60:101 */\n      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n        /* \\\"C\\\":77:99 */\n    tag_3:\n      stop\n\n    auxdata: <AUXDATA REMOVED>\n}\n\"\n                },\n                \"ir\": \"\n/// @use-src 0:\\\"C\\\"\nobject \\\"C_6\\\" {\n    code {\n        /// @src 0:60:101\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_6()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_6_deployed\\\"), datasize(\\\"C_6_deployed\\\"))\n\n        return(_1, datasize(\\\"C_6_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:60:101\n        function constructor_C_6() {\n\n            /// @src 0:60:101\n\n        }\n        /// @src 0:60:101\n\n    }\n    /// @use-src 0:\\\"C\\\"\n    object \\\"C_6_deployed\\\" {\n        code {\n            /// @src 0:60:101\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_5()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_5() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                fun_f_5()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            /// @src 0:77:99\n            function fun_f_5() {\n\n            }\n            /// @src 0:60:101\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\",\n                \"irOptimized\": \"/// @use-src 0:\\\"C\\\"\nobject \\\"C_6\\\" {\n    code {\n        {\n            /// @src 0:60:101\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\\\"C_6_deployed\\\")\n            codecopy(_1, dataoffset(\\\"C_6_deployed\\\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\\\"C\\\"\n    object \\\"C_6_deployed\\\" {\n        code {\n            {\n                /// @src 0:60:101\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        return(0, 0)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/in.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"debug\": {\"debugInfo\": []},\n\t\t\"optimizer\": {\"enabled\": true},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"ir\", \"irOptimized\", \"evm.assembly\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_none/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"evm\": {\n                    \"assembly\": \"  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n    tag_3:\n      stop\n\n    auxdata: <AUXDATA REMOVED>\n}\n\"\n                },\n                \"ir\": \"\n/// @use-src 0:\\\"C\\\"\nobject \\\"C_6\\\" {\n    code {\n\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_6()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_6_deployed\\\"), datasize(\\\"C_6_deployed\\\"))\n\n        return(_1, datasize(\\\"C_6_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function constructor_C_6() {\n\n        }\n\n    }\n    /// @use-src 0:\\\"C\\\"\n    object \\\"C_6_deployed\\\" {\n        code {\n\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_5()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_5() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                fun_f_5()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function fun_f_5() {\n\n            }\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\",\n                \"irOptimized\": \"/// @use-src 0:\\\"C\\\"\nobject \\\"C_6\\\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\\\"C_6_deployed\\\")\n            codecopy(_1, dataoffset(\\\"C_6_deployed\\\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\\\"C\\\"\n    object \\\"C_6_deployed\\\" {\n        code {\n            {\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        return(0, 0)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/in.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"debug\": {\"debugInfo\": [\"snippet\"]},\n\t\t\"optimizer\": {\"enabled\": true},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"ir\", \"irOptimized\", \"evm.assembly\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_and_evm_asm_print_snippet_only/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"To use 'snippet' with settings.debug.debugInfo you must select also 'location'.\",\n            \"message\": \"To use 'snippet' with settings.debug.debugInfo you must select also 'location'.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_location/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"C\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-2.0\\npragma solidity >=0.0;\\npragma abicoder v2;\\n\\ncontract C\\n{\\n    int public constant constVar = 41;\\n    int immutable immutVar = 42;\\n    int public stateVar;\\n\\n    constructor(int _init)\\n    {\\n        stateVar = _init;\\n    }\\n\\n    function f() external pure returns (int)\\n    {\\n        return constVar + immutVar;\\n    }\\n    modifier m()\\n    {\\n        stateVar++;\\n        _;\\n    }\\n    function f2() m public returns (int)\\n    {\\n        return stateVar + this.f() + immutVar;\\n    }\\n}\\n\"\n\t\t},\n\t\t\"D\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-2.0\\npragma solidity >=0.0;\\npragma abicoder v2;\\nimport \\\"C\\\";\\n\\ncontract D is C(3)\\n{\\n    constructor(int _init2)\\n    {\\n        stateVar += _init2;\\n    }\\n}\\n\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"ir\", \"irOptimized\"] }\n\t\t},\n\t\t\"optimizer\": { \"enabled\": true }\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_debug_info_in_yul_location/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"ir\": \"\n/// @use-src 0:\\\"C\\\"\nobject \\\"C_54\\\" {\n    code {\n        /// @src 0:79:510  \\\"contract C...\\\"\n        mstore(64, memoryguard(160))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        let _1 := copy_arguments_for_constructor_20_object_C_54()\n        constructor_C_54(_1)\n\n        let _2 := allocate_unbounded()\n        codecopy(_2, dataoffset(\\\"C_54_deployed\\\"), datasize(\\\"C_54_deployed\\\"))\n\n        setimmutable(_2, \\\"8\\\", mload(128))\n\n        return(_2, datasize(\\\"C_54_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function round_up_to_mul_of_32(value) -> result {\n            result := and(add(value, 31), not(31))\n        }\n\n        function panic_error_0x41() {\n            mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n            mstore(4, 0x41)\n            revert(0, 0x24)\n        }\n\n        function finalize_allocation(memPtr, size) {\n            let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n            // protect against overflow\n            if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n            mstore(64, newFreePtr)\n        }\n\n        function allocate_memory(size) -> memPtr {\n            memPtr := allocate_unbounded()\n            finalize_allocation(memPtr, size)\n        }\n\n        function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n            revert(0, 0)\n        }\n\n        function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n            revert(0, 0)\n        }\n\n        function cleanup_t_int256(value) -> cleaned {\n            cleaned := value\n        }\n\n        function validator_revert_t_int256(value) {\n            if iszero(eq(value, cleanup_t_int256(value))) { revert(0, 0) }\n        }\n\n        function abi_decode_t_int256_fromMemory(offset, end) -> value {\n            value := mload(offset)\n            validator_revert_t_int256(value)\n        }\n\n        function abi_decode_tuple_t_int256_fromMemory(headStart, dataEnd) -> value0 {\n            if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            {\n\n                let offset := 0\n\n                value0 := abi_decode_t_int256_fromMemory(add(headStart, offset), dataEnd)\n            }\n\n        }\n\n        function copy_arguments_for_constructor_20_object_C_54() -> ret_param_0 {\n\n            let programSize := datasize(\\\"C_54\\\")\n            let argSize := sub(codesize(), programSize)\n\n            let memoryDataOffset := allocate_memory(argSize)\n            codecopy(memoryDataOffset, programSize, argSize)\n\n            ret_param_0 := abi_decode_tuple_t_int256_fromMemory(memoryDataOffset, add(memoryDataOffset, argSize))\n        }\n\n        function cleanup_t_rational_42_by_1(value) -> cleaned {\n            cleaned := value\n        }\n\n        function identity(value) -> ret {\n            ret := value\n        }\n\n        function convert_t_rational_42_by_1_to_t_int256(value) -> converted {\n            converted := cleanup_t_int256(identity(cleanup_t_rational_42_by_1(value)))\n        }\n\n        function shift_left_0(value) -> newValue {\n            newValue :=\n\n            shl(0, value)\n\n        }\n\n        function update_byte_slice_32_shift_0(value, toInsert) -> result {\n            let mask := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n            toInsert := shift_left_0(toInsert)\n            value := and(value, not(mask))\n            result := or(value, and(toInsert, mask))\n        }\n\n        function convert_t_int256_to_t_int256(value) -> converted {\n            converted := cleanup_t_int256(identity(cleanup_t_int256(value)))\n        }\n\n        function prepare_store_t_int256(value) -> ret {\n            ret := value\n        }\n\n        function update_storage_value_offset_0_t_int256_to_t_int256(slot, value_0) {\n            let convertedValue_0 := convert_t_int256_to_t_int256(value_0)\n            sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0)))\n        }\n\n        /// @ast-id 20\n        /// @src 0:194:254  \\\"constructor(int _init)...\\\"\n        function constructor_C_54(var__init_12) {\n\n            /// @src 0:194:254  \\\"constructor(int _init)...\\\"\n\n            /// @src 0:160:162  \\\"42\\\"\n            let expr_7 := 0x2a\n            let _3 := convert_t_rational_42_by_1_to_t_int256(expr_7)\n            mstore(128, _3)\n\n            /// @src 0:242:247  \\\"_init\\\"\n            let _4 := var__init_12\n            let expr_16 := _4\n            /// @src 0:231:247  \\\"stateVar = _init\\\"\n            update_storage_value_offset_0_t_int256_to_t_int256(0x00, expr_16)\n            let expr_17 := expr_16\n\n        }\n        /// @src 0:79:510  \\\"contract C...\\\"\n\n    }\n    /// @use-src 0:\\\"C\\\"\n    object \\\"C_54_deployed\\\" {\n        code {\n            /// @src 0:79:510  \\\"contract C...\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_30()\n                }\n\n                case 0x793816ec\n                {\n                    // stateVar()\n\n                    external_fun_stateVar_10()\n                }\n\n                case 0x9942ec6f\n                {\n                    // f2()\n\n                    external_fun_f2_53()\n                }\n\n                case 0xa00b982b\n                {\n                    // constVar()\n\n                    external_fun_constVar_5()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function cleanup_t_int256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function abi_encode_t_int256_to_t_int256_fromStack(value, pos) {\n                mstore(pos, cleanup_t_int256(value))\n            }\n\n            function abi_encode_tuple_t_int256__to_t_int256__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 32)\n\n                abi_encode_t_int256_to_t_int256_fromStack(value0,  add(headStart, 0))\n\n            }\n\n            function external_fun_f_30() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  fun_f_30()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_int256__to_t_int256__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function shift_right_unsigned_dynamic(bits, value) -> newValue {\n                newValue :=\n\n                shr(bits, value)\n\n            }\n\n            function cleanup_from_storage_t_int256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value {\n                value := cleanup_from_storage_t_int256(shift_right_unsigned_dynamic(mul(offset, 8), slot_value))\n            }\n\n            function read_from_storage_split_dynamic_t_int256(slot, offset) -> value {\n                value := extract_from_storage_value_dynamict_int256(sload(slot), offset)\n\n            }\n\n            /// @ast-id 10\n            /// @src 0:168:187  \\\"int public stateVar\\\"\n            function getter_fun_stateVar_10() -> ret {\n\n                let slot := 0\n                let offset := 0\n\n                ret := read_from_storage_split_dynamic_t_int256(slot, offset)\n\n            }\n            /// @src 0:79:510  \\\"contract C...\\\"\n\n            function external_fun_stateVar_10() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  getter_fun_stateVar_10()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_int256__to_t_int256__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function external_fun_f2_53() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  fun_f2_53()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_int256__to_t_int256__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function cleanup_t_rational_41_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_41_by_1_to_t_int256(value) -> converted {\n                converted := cleanup_t_int256(identity(cleanup_t_rational_41_by_1(value)))\n            }\n\n            /// @src 0:96:129  \\\"int public constant constVar = 41\\\"\n            function constant_constVar_5() -> ret {\n                /// @src 0:127:129  \\\"41\\\"\n                let expr_4 := 0x29\n                let _1 := convert_t_rational_41_by_1_to_t_int256(expr_4)\n\n                ret := _1\n            }\n\n            /// @ast-id 5\n            /// @src 0:96:129  \\\"int public constant constVar = 41\\\"\n            function getter_fun_constVar_5() -> ret_0 {\n                ret_0 := constant_constVar_5()\n            }\n            /// @src 0:79:510  \\\"contract C...\\\"\n\n            function external_fun_constVar_5() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  getter_fun_constVar_5()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_int256__to_t_int256__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function zero_value_for_split_t_int256() -> ret {\n                ret := 0\n            }\n\n            function panic_error_0x11() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x11)\n                revert(0, 0x24)\n            }\n\n            function checked_add_t_int256(x, y) -> sum {\n                x := cleanup_t_int256(x)\n                y := cleanup_t_int256(y)\n                sum := add(x, y)\n\n                // overflow, if x >= 0 and sum < y\n                // underflow, if x < 0 and sum >= y\n                if or(\n                    and(iszero(slt(x, 0)), slt(sum, y)),\n                    and(slt(x, 0), iszero(slt(sum, y)))\n                ) { panic_error_0x11() }\n\n            }\n\n            /// @ast-id 30\n            /// @src 0:260:348  \\\"function f() external pure returns (int)...\\\"\n            function fun_f_30() -> var__23 {\n                /// @src 0:296:299  \\\"int\\\"\n                let zero_t_int256_2 := zero_value_for_split_t_int256()\n                var__23 := zero_t_int256_2\n\n                /// @src 0:322:330  \\\"constVar\\\"\n                let expr_25 := constant_constVar_5()\n                /// @src 0:333:341  \\\"immutVar\\\"\n                let _3 := loadimmutable(\\\"8\\\")\n                let expr_26 := _3\n                /// @src 0:322:341  \\\"constVar + immutVar\\\"\n                let expr_27 := checked_add_t_int256(expr_25, expr_26)\n\n                /// @src 0:315:341  \\\"return constVar + immutVar\\\"\n                var__23 := expr_27\n                leave\n\n            }\n            /// @src 0:79:510  \\\"contract C...\\\"\n\n            function shift_right_0_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(0, value)\n\n            }\n\n            function extract_from_storage_value_offset_0_t_int256(slot_value) -> value {\n                value := cleanup_from_storage_t_int256(shift_right_0_unsigned(slot_value))\n            }\n\n            function read_from_storage_split_offset_0_t_int256(slot) -> value {\n                value := extract_from_storage_value_offset_0_t_int256(sload(slot))\n\n            }\n\n            function increment_t_int256(value) -> ret {\n                value := cleanup_t_int256(value)\n                if eq(value, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) { panic_error_0x11() }\n                ret := add(value, 1)\n            }\n\n            function shift_left_0(value) -> newValue {\n                newValue :=\n\n                shl(0, value)\n\n            }\n\n            function update_byte_slice_32_shift_0(value, toInsert) -> result {\n                let mask := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n                toInsert := shift_left_0(toInsert)\n                value := and(value, not(mask))\n                result := or(value, and(toInsert, mask))\n            }\n\n            function convert_t_int256_to_t_int256(value) -> converted {\n                converted := cleanup_t_int256(identity(cleanup_t_int256(value)))\n            }\n\n            function prepare_store_t_int256(value) -> ret {\n                ret := value\n            }\n\n            function update_storage_value_offset_0_t_int256_to_t_int256(slot, value_0) {\n                let convertedValue_0 := convert_t_int256_to_t_int256(value_0)\n                sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0)))\n            }\n\n            /// @ast-id 37\n            /// @src 0:353:408  \\\"modifier m()...\\\"\n            function modifier_m_40(var__42) -> _5 {\n                _5 := var__42\n\n                /// @src 0:380:390  \\\"stateVar++\\\"\n                let _7 := read_from_storage_split_offset_0_t_int256(0x00)\n                let _6 := increment_t_int256(_7)\n                update_storage_value_offset_0_t_int256_to_t_int256(0x00, _6)\n                let expr_33 := _7\n                /// @src 0:400:401  \\\"_\\\"\n                _5 := fun_f2_53_inner(var__42)\n\n            }\n            /// @src 0:79:510  \\\"contract C...\\\"\n\n            function cleanup_t_uint160(value) -> cleaned {\n                cleaned := and(value, 0xffffffffffffffffffffffffffffffffffffffff)\n            }\n\n            function convert_t_uint160_to_t_uint160(value) -> converted {\n                converted := cleanup_t_uint160(identity(cleanup_t_uint160(value)))\n            }\n\n            function convert_t_uint160_to_t_address(value) -> converted {\n                converted := convert_t_uint160_to_t_uint160(value)\n            }\n\n            function convert_t_contract$_C_$54_to_t_address(value) -> converted {\n                converted := convert_t_uint160_to_t_address(value)\n            }\n\n            function revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20() {\n                revert(0, 0)\n            }\n\n            function round_up_to_mul_of_32(value) -> result {\n                result := and(add(value, 31), not(31))\n            }\n\n            function panic_error_0x41() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x41)\n                revert(0, 0x24)\n            }\n\n            function finalize_allocation(memPtr, size) {\n                let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n                // protect against overflow\n                if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n                mstore(64, newFreePtr)\n            }\n\n            function shift_left_224(value) -> newValue {\n                newValue :=\n\n                shl(224, value)\n\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function validator_revert_t_int256(value) {\n                if iszero(eq(value, cleanup_t_int256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_int256_fromMemory(offset, end) -> value {\n                value := mload(offset)\n                validator_revert_t_int256(value)\n            }\n\n            function abi_decode_tuple_t_int256_fromMemory(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_int256_fromMemory(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function revert_forward_1() {\n                let pos := allocate_unbounded()\n                returndatacopy(pos, 0, returndatasize())\n                revert(pos, returndatasize())\n            }\n\n            /// @src 0:413:508  \\\"function f2() m public returns (int)...\\\"\n            function fun_f2_53_inner(_8) -> var__42 {\n                var__42 := _8\n\n                /// @src 0:471:479  \\\"stateVar\\\"\n                let _9 := read_from_storage_split_offset_0_t_int256(0x00)\n                let expr_44 := _9\n                /// @src 0:482:486  \\\"this\\\"\n                let expr_45_address := address()\n                /// @src 0:482:488  \\\"this.f\\\"\n                let expr_46_address := convert_t_contract$_C_$54_to_t_address(expr_45_address)\n                let expr_46_functionSelector := 0x26121ff0\n                /// @src 0:482:490  \\\"this.f()\\\"\n\n                // storage for arguments and returned data\n                let _10 := allocate_unbounded()\n                mstore(_10, shift_left_224(expr_46_functionSelector))\n                let _11 := abi_encode_tuple__to__fromStack(add(_10, 4) )\n\n                let _12 := staticcall(gas(), expr_46_address,  _10, sub(_11, _10), _10, 32)\n\n                if iszero(_12) { revert_forward_1() }\n\n                let expr_47\n                if _12 {\n\n                    let _13 := 32\n\n                    if gt(_13, returndatasize()) {\n                        _13 := returndatasize()\n                    }\n\n                    // update freeMemoryPointer according to dynamic return size\n                    finalize_allocation(_10, _13)\n\n                    // decode return parameters from external try-call into retVars\n                    expr_47 :=  abi_decode_tuple_t_int256_fromMemory(_10, add(_10, _13))\n                }\n                /// @src 0:471:490  \\\"stateVar + this.f()\\\"\n                let expr_48 := checked_add_t_int256(expr_44, expr_47)\n\n                /// @src 0:493:501  \\\"immutVar\\\"\n                let _14 := loadimmutable(\\\"8\\\")\n                let expr_49 := _14\n                /// @src 0:471:501  \\\"stateVar + this.f() + immutVar\\\"\n                let expr_50 := checked_add_t_int256(expr_48, expr_49)\n\n                /// @src 0:464:501  \\\"return stateVar + this.f() + immutVar\\\"\n                var__42 := expr_50\n                leave\n\n            }\n            /// @src 0:79:510  \\\"contract C...\\\"\n\n            /// @ast-id 53\n            /// @src 0:413:508  \\\"function f2() m public returns (int)...\\\"\n            function fun_f2_53() -> var__42 {\n                /// @src 0:445:448  \\\"int\\\"\n                let zero_t_int256_4 := zero_value_for_split_t_int256()\n                var__42 := zero_t_int256_4\n\n                var__42 := modifier_m_40(var__42)\n            }\n            /// @src 0:79:510  \\\"contract C...\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\",\n                \"irOptimized\": \"/// @use-src 0:\\\"C\\\"\nobject \\\"C_54\\\" {\n    code {\n        {\n            /// @src 0:79:510  \\\"contract C...\\\"\n            let _1 := memoryguard(0xa0)\n            if callvalue() { revert(0, 0) }\n            let programSize := datasize(\\\"C_54\\\")\n            let argSize := sub(codesize(), programSize)\n            let newFreePtr := add(_1, and(add(argSize, 31), not(31)))\n            if or(gt(newFreePtr, sub(shl(64, 1), 1)), lt(newFreePtr, _1))\n            {\n                mstore(/** @src -1:-1:-1 */ 0, /** @src 0:79:510  \\\"contract C...\\\" */ shl(224, 0x4e487b71))\n                mstore(4, 0x41)\n                revert(/** @src -1:-1:-1 */ 0, /** @src 0:79:510  \\\"contract C...\\\" */ 0x24)\n            }\n            mstore(64, newFreePtr)\n            codecopy(_1, programSize, argSize)\n            if slt(sub(add(_1, argSize), _1), 32)\n            {\n                revert(/** @src -1:-1:-1 */ 0, 0)\n            }\n            /// @src 0:79:510  \\\"contract C...\\\"\n            let value := mload(_1)\n            /// @src 0:160:162  \\\"42\\\"\n            mstore(128, 0x2a)\n            /// @src 0:79:510  \\\"contract C...\\\"\n            sstore(/** @src -1:-1:-1 */ 0, /** @src 0:79:510  \\\"contract C...\\\" */ value)\n            let _2 := mload(64)\n            let _3 := datasize(\\\"C_54_deployed\\\")\n            codecopy(_2, dataoffset(\\\"C_54_deployed\\\"), _3)\n            setimmutable(_2, \\\"8\\\", mload(/** @src 0:160:162  \\\"42\\\" */ 128))\n            /// @src 0:79:510  \\\"contract C...\\\"\n            return(_2, _3)\n        }\n    }\n    /// @use-src 0:\\\"C\\\"\n    object \\\"C_54_deployed\\\" {\n        code {\n            {\n                /// @src 0:79:510  \\\"contract C...\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    switch shr(224, calldataload(0))\n                    case 0x26121ff0 {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        /// @src 0:333:341  \\\"immutVar\\\"\n                        let _1 := loadimmutable(\\\"8\\\")\n                        /// @src 0:322:341  \\\"constVar + immutVar\\\"\n                        let sum := /** @src 0:79:510  \\\"contract C...\\\" */ 0\n                        sum := add(/** @src 0:127:129  \\\"41\\\" */ 0x29, /** @src 0:79:510  \\\"contract C...\\\" */ _1)\n                        if and(1, slt(sum, _1))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x11)\n                            revert(0, 0x24)\n                        }\n                        let memPos := mload(64)\n                        mstore(memPos, sum)\n                        return(memPos, 32)\n                    }\n                    case 0x793816ec {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let _2 := sload(0)\n                        let memPos_1 := mload(64)\n                        mstore(memPos_1, _2)\n                        return(memPos_1, 32)\n                    }\n                    case 0x9942ec6f {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let _3 := sload(0)\n                        if eq(_3, sub(shl(255, 1), 1))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x11)\n                            revert(0, 0x24)\n                        }\n                        let ret := add(_3, 1)\n                        sstore(0, ret)\n                        /// @src 0:482:490  \\\"this.f()\\\"\n                        let _4 := /** @src 0:79:510  \\\"contract C...\\\" */ mload(64)\n                        /// @src 0:482:490  \\\"this.f()\\\"\n                        mstore(_4, /** @src 0:79:510  \\\"contract C...\\\" */ shl(228, 0x026121ff))\n                        /// @src 0:482:490  \\\"this.f()\\\"\n                        let _5 := staticcall(gas(), /** @src 0:482:486  \\\"this\\\" */ address(), /** @src 0:482:490  \\\"this.f()\\\" */ _4, /** @src 0:79:510  \\\"contract C...\\\" */ 4, /** @src 0:482:490  \\\"this.f()\\\" */ _4, 32)\n                        if iszero(_5)\n                        {\n                            /// @src 0:79:510  \\\"contract C...\\\"\n                            let pos := mload(64)\n                            returndatacopy(pos, 0, returndatasize())\n                            revert(pos, returndatasize())\n                        }\n                        /// @src 0:482:490  \\\"this.f()\\\"\n                        let expr := /** @src 0:79:510  \\\"contract C...\\\" */ 0\n                        /// @src 0:482:490  \\\"this.f()\\\"\n                        if _5\n                        {\n                            let _6 := 32\n                            if gt(32, returndatasize()) { _6 := returndatasize() }\n                            /// @src 0:79:510  \\\"contract C...\\\"\n                            let newFreePtr := add(_4, and(add(_6, 31), not(31)))\n                            if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _4))\n                            {\n                                mstore(0, shl(224, 0x4e487b71))\n                                mstore(4, 0x41)\n                                revert(0, 0x24)\n                            }\n                            mstore(64, newFreePtr)\n                            if slt(sub(/** @src 0:482:490  \\\"this.f()\\\" */ add(_4, _6), /** @src 0:79:510  \\\"contract C...\\\" */ _4), /** @src 0:482:490  \\\"this.f()\\\" */ 32)\n                            /// @src 0:79:510  \\\"contract C...\\\"\n                            { revert(0, 0) }\n                            /// @src 0:482:490  \\\"this.f()\\\"\n                            expr := /** @src 0:79:510  \\\"contract C...\\\" */ mload(_4)\n                        }\n                        /// @src 0:471:490  \\\"stateVar + this.f()\\\"\n                        let expr_1 := checked_add_int256(ret, expr)\n                        /// @src 0:464:501  \\\"return stateVar + this.f() + immutVar\\\"\n                        let var := /** @src 0:471:501  \\\"stateVar + this.f() + immutVar\\\" */ checked_add_int256(expr_1, /** @src 0:493:501  \\\"immutVar\\\" */ loadimmutable(\\\"8\\\"))\n                        /// @src 0:79:510  \\\"contract C...\\\"\n                        let memPos_2 := mload(64)\n                        mstore(memPos_2, var)\n                        return(memPos_2, /** @src 0:482:490  \\\"this.f()\\\" */ 32)\n                    }\n                    case /** @src 0:79:510  \\\"contract C...\\\" */ 0xa00b982b {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let memPos_3 := mload(64)\n                        mstore(memPos_3, /** @src 0:127:129  \\\"41\\\" */ 0x29)\n                        /// @src 0:79:510  \\\"contract C...\\\"\n                        return(memPos_3, 32)\n                    }\n                }\n                revert(0, 0)\n            }\n            function checked_add_int256(x, y) -> sum\n            {\n                sum := add(x, y)\n                let _1 := slt(sum, y)\n                let _2 := slt(x, 0)\n                if or(and(iszero(_2), _1), and(_2, iszero(_1)))\n                {\n                    mstore(0, shl(224, 0x4e487b71))\n                    mstore(4, 0x11)\n                    revert(0, 0x24)\n                }\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        },\n        \"D\": {\n            \"D\": {\n                \"ir\": \"\n/// @use-src 0:\\\"C\\\", 1:\\\"D\\\"\nobject \\\"D_72\\\" {\n    code {\n        /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n        mstore(64, memoryguard(160))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        let _1 := copy_arguments_for_constructor_71_object_D_72()\n        constructor_D_72(_1)\n\n        let _2 := allocate_unbounded()\n        codecopy(_2, dataoffset(\\\"D_72_deployed\\\"), datasize(\\\"D_72_deployed\\\"))\n\n        setimmutable(_2, \\\"8\\\", mload(128))\n\n        return(_2, datasize(\\\"D_72_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function round_up_to_mul_of_32(value) -> result {\n            result := and(add(value, 31), not(31))\n        }\n\n        function panic_error_0x41() {\n            mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n            mstore(4, 0x41)\n            revert(0, 0x24)\n        }\n\n        function finalize_allocation(memPtr, size) {\n            let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n            // protect against overflow\n            if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n            mstore(64, newFreePtr)\n        }\n\n        function allocate_memory(size) -> memPtr {\n            memPtr := allocate_unbounded()\n            finalize_allocation(memPtr, size)\n        }\n\n        function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n            revert(0, 0)\n        }\n\n        function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n            revert(0, 0)\n        }\n\n        function cleanup_t_int256(value) -> cleaned {\n            cleaned := value\n        }\n\n        function validator_revert_t_int256(value) {\n            if iszero(eq(value, cleanup_t_int256(value))) { revert(0, 0) }\n        }\n\n        function abi_decode_t_int256_fromMemory(offset, end) -> value {\n            value := mload(offset)\n            validator_revert_t_int256(value)\n        }\n\n        function abi_decode_tuple_t_int256_fromMemory(headStart, dataEnd) -> value0 {\n            if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            {\n\n                let offset := 0\n\n                value0 := abi_decode_t_int256_fromMemory(add(headStart, offset), dataEnd)\n            }\n\n        }\n\n        function copy_arguments_for_constructor_71_object_D_72() -> ret_param_0 {\n\n            let programSize := datasize(\\\"D_72\\\")\n            let argSize := sub(codesize(), programSize)\n\n            let memoryDataOffset := allocate_memory(argSize)\n            codecopy(memoryDataOffset, programSize, argSize)\n\n            ret_param_0 := abi_decode_tuple_t_int256_fromMemory(memoryDataOffset, add(memoryDataOffset, argSize))\n        }\n\n        function cleanup_t_rational_3_by_1(value) -> cleaned {\n            cleaned := value\n        }\n\n        function identity(value) -> ret {\n            ret := value\n        }\n\n        function convert_t_rational_3_by_1_to_t_int256(value) -> converted {\n            converted := cleanup_t_int256(identity(cleanup_t_rational_3_by_1(value)))\n        }\n\n        function shift_right_0_unsigned(value) -> newValue {\n            newValue :=\n\n            shr(0, value)\n\n        }\n\n        function cleanup_from_storage_t_int256(value) -> cleaned {\n            cleaned := value\n        }\n\n        function extract_from_storage_value_offset_0_t_int256(slot_value) -> value {\n            value := cleanup_from_storage_t_int256(shift_right_0_unsigned(slot_value))\n        }\n\n        function read_from_storage_split_offset_0_t_int256(slot) -> value {\n            value := extract_from_storage_value_offset_0_t_int256(sload(slot))\n\n        }\n\n        function panic_error_0x11() {\n            mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n            mstore(4, 0x11)\n            revert(0, 0x24)\n        }\n\n        function checked_add_t_int256(x, y) -> sum {\n            x := cleanup_t_int256(x)\n            y := cleanup_t_int256(y)\n            sum := add(x, y)\n\n            // overflow, if x >= 0 and sum < y\n            // underflow, if x < 0 and sum >= y\n            if or(\n                and(iszero(slt(x, 0)), slt(sum, y)),\n                and(slt(x, 0), iszero(slt(sum, y)))\n            ) { panic_error_0x11() }\n\n        }\n\n        function shift_left_0(value) -> newValue {\n            newValue :=\n\n            shl(0, value)\n\n        }\n\n        function update_byte_slice_32_shift_0(value, toInsert) -> result {\n            let mask := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n            toInsert := shift_left_0(toInsert)\n            value := and(value, not(mask))\n            result := or(value, and(toInsert, mask))\n        }\n\n        function convert_t_int256_to_t_int256(value) -> converted {\n            converted := cleanup_t_int256(identity(cleanup_t_int256(value)))\n        }\n\n        function prepare_store_t_int256(value) -> ret {\n            ret := value\n        }\n\n        function update_storage_value_offset_0_t_int256_to_t_int256(slot, value_0) {\n            let convertedValue_0 := convert_t_int256_to_t_int256(value_0)\n            sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0)))\n        }\n\n        /// @ast-id 71\n        /// @src 1:116:179  \\\"constructor(int _init2)...\\\"\n        function constructor_D_72(var__init2_63) {\n            /// @src 1:107:108  \\\"3\\\"\n            let expr_60 := 0x03\n            let _3 := convert_t_rational_3_by_1_to_t_int256(expr_60)\n\n            /// @src 1:116:179  \\\"constructor(int _init2)...\\\"\n            constructor_C_54(_3)\n\n            /// @src 1:166:172  \\\"_init2\\\"\n            let _4 := var__init2_63\n            let expr_67 := _4\n            /// @src 1:154:172  \\\"stateVar += _init2\\\"\n            let _5 := read_from_storage_split_offset_0_t_int256(0x00)\n            let expr_68 := checked_add_t_int256(_5, expr_67)\n\n            update_storage_value_offset_0_t_int256_to_t_int256(0x00, expr_68)\n\n        }\n        /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n\n        function cleanup_t_rational_42_by_1(value) -> cleaned {\n            cleaned := value\n        }\n\n        function convert_t_rational_42_by_1_to_t_int256(value) -> converted {\n            converted := cleanup_t_int256(identity(cleanup_t_rational_42_by_1(value)))\n        }\n\n        /// @ast-id 20\n        /// @src 0:194:254  \\\"constructor(int _init)...\\\"\n        function constructor_C_54(var__init_12) {\n\n            /// @src 0:194:254  \\\"constructor(int _init)...\\\"\n\n            /// @src 0:160:162  \\\"42\\\"\n            let expr_7 := 0x2a\n            let _6 := convert_t_rational_42_by_1_to_t_int256(expr_7)\n            mstore(128, _6)\n\n            /// @src 0:242:247  \\\"_init\\\"\n            let _7 := var__init_12\n            let expr_16 := _7\n            /// @src 0:231:247  \\\"stateVar = _init\\\"\n            update_storage_value_offset_0_t_int256_to_t_int256(0x00, expr_16)\n            let expr_17 := expr_16\n\n        }\n        /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n\n    }\n    /// @use-src 0:\\\"C\\\", 1:\\\"D\\\"\n    object \\\"D_72_deployed\\\" {\n        code {\n            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_30()\n                }\n\n                case 0x793816ec\n                {\n                    // stateVar()\n\n                    external_fun_stateVar_10()\n                }\n\n                case 0x9942ec6f\n                {\n                    // f2()\n\n                    external_fun_f2_53()\n                }\n\n                case 0xa00b982b\n                {\n                    // constVar()\n\n                    external_fun_constVar_5()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function cleanup_t_int256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function abi_encode_t_int256_to_t_int256_fromStack(value, pos) {\n                mstore(pos, cleanup_t_int256(value))\n            }\n\n            function abi_encode_tuple_t_int256__to_t_int256__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 32)\n\n                abi_encode_t_int256_to_t_int256_fromStack(value0,  add(headStart, 0))\n\n            }\n\n            function external_fun_f_30() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  fun_f_30()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_int256__to_t_int256__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function shift_right_unsigned_dynamic(bits, value) -> newValue {\n                newValue :=\n\n                shr(bits, value)\n\n            }\n\n            function cleanup_from_storage_t_int256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function extract_from_storage_value_dynamict_int256(slot_value, offset) -> value {\n                value := cleanup_from_storage_t_int256(shift_right_unsigned_dynamic(mul(offset, 8), slot_value))\n            }\n\n            function read_from_storage_split_dynamic_t_int256(slot, offset) -> value {\n                value := extract_from_storage_value_dynamict_int256(sload(slot), offset)\n\n            }\n\n            /// @ast-id 10\n            /// @src 0:168:187  \\\"int public stateVar\\\"\n            function getter_fun_stateVar_10() -> ret {\n\n                let slot := 0\n                let offset := 0\n\n                ret := read_from_storage_split_dynamic_t_int256(slot, offset)\n\n            }\n            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n\n            function external_fun_stateVar_10() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  getter_fun_stateVar_10()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_int256__to_t_int256__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function external_fun_f2_53() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  fun_f2_53()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_int256__to_t_int256__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function cleanup_t_rational_41_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_41_by_1_to_t_int256(value) -> converted {\n                converted := cleanup_t_int256(identity(cleanup_t_rational_41_by_1(value)))\n            }\n\n            /// @src 0:96:129  \\\"int public constant constVar = 41\\\"\n            function constant_constVar_5() -> ret {\n                /// @src 0:127:129  \\\"41\\\"\n                let expr_4 := 0x29\n                let _1 := convert_t_rational_41_by_1_to_t_int256(expr_4)\n\n                ret := _1\n            }\n\n            /// @ast-id 5\n            /// @src 0:96:129  \\\"int public constant constVar = 41\\\"\n            function getter_fun_constVar_5() -> ret_0 {\n                ret_0 := constant_constVar_5()\n            }\n            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n\n            function external_fun_constVar_5() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  getter_fun_constVar_5()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_int256__to_t_int256__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function zero_value_for_split_t_int256() -> ret {\n                ret := 0\n            }\n\n            function panic_error_0x11() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x11)\n                revert(0, 0x24)\n            }\n\n            function checked_add_t_int256(x, y) -> sum {\n                x := cleanup_t_int256(x)\n                y := cleanup_t_int256(y)\n                sum := add(x, y)\n\n                // overflow, if x >= 0 and sum < y\n                // underflow, if x < 0 and sum >= y\n                if or(\n                    and(iszero(slt(x, 0)), slt(sum, y)),\n                    and(slt(x, 0), iszero(slt(sum, y)))\n                ) { panic_error_0x11() }\n\n            }\n\n            /// @ast-id 30\n            /// @src 0:260:348  \\\"function f() external pure returns (int)...\\\"\n            function fun_f_30() -> var__23 {\n                /// @src 0:296:299  \\\"int\\\"\n                let zero_t_int256_2 := zero_value_for_split_t_int256()\n                var__23 := zero_t_int256_2\n\n                /// @src 0:322:330  \\\"constVar\\\"\n                let expr_25 := constant_constVar_5()\n                /// @src 0:333:341  \\\"immutVar\\\"\n                let _3 := loadimmutable(\\\"8\\\")\n                let expr_26 := _3\n                /// @src 0:322:341  \\\"constVar + immutVar\\\"\n                let expr_27 := checked_add_t_int256(expr_25, expr_26)\n\n                /// @src 0:315:341  \\\"return constVar + immutVar\\\"\n                var__23 := expr_27\n                leave\n\n            }\n            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n\n            function shift_right_0_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(0, value)\n\n            }\n\n            function extract_from_storage_value_offset_0_t_int256(slot_value) -> value {\n                value := cleanup_from_storage_t_int256(shift_right_0_unsigned(slot_value))\n            }\n\n            function read_from_storage_split_offset_0_t_int256(slot) -> value {\n                value := extract_from_storage_value_offset_0_t_int256(sload(slot))\n\n            }\n\n            function increment_t_int256(value) -> ret {\n                value := cleanup_t_int256(value)\n                if eq(value, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) { panic_error_0x11() }\n                ret := add(value, 1)\n            }\n\n            function shift_left_0(value) -> newValue {\n                newValue :=\n\n                shl(0, value)\n\n            }\n\n            function update_byte_slice_32_shift_0(value, toInsert) -> result {\n                let mask := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n                toInsert := shift_left_0(toInsert)\n                value := and(value, not(mask))\n                result := or(value, and(toInsert, mask))\n            }\n\n            function convert_t_int256_to_t_int256(value) -> converted {\n                converted := cleanup_t_int256(identity(cleanup_t_int256(value)))\n            }\n\n            function prepare_store_t_int256(value) -> ret {\n                ret := value\n            }\n\n            function update_storage_value_offset_0_t_int256_to_t_int256(slot, value_0) {\n                let convertedValue_0 := convert_t_int256_to_t_int256(value_0)\n                sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0)))\n            }\n\n            /// @ast-id 37\n            /// @src 0:353:408  \\\"modifier m()...\\\"\n            function modifier_m_40(var__42) -> _5 {\n                _5 := var__42\n\n                /// @src 0:380:390  \\\"stateVar++\\\"\n                let _7 := read_from_storage_split_offset_0_t_int256(0x00)\n                let _6 := increment_t_int256(_7)\n                update_storage_value_offset_0_t_int256_to_t_int256(0x00, _6)\n                let expr_33 := _7\n                /// @src 0:400:401  \\\"_\\\"\n                _5 := fun_f2_53_inner(var__42)\n\n            }\n            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n\n            function cleanup_t_uint160(value) -> cleaned {\n                cleaned := and(value, 0xffffffffffffffffffffffffffffffffffffffff)\n            }\n\n            function convert_t_uint160_to_t_uint160(value) -> converted {\n                converted := cleanup_t_uint160(identity(cleanup_t_uint160(value)))\n            }\n\n            function convert_t_uint160_to_t_address(value) -> converted {\n                converted := convert_t_uint160_to_t_uint160(value)\n            }\n\n            function convert_t_contract$_C_$54_to_t_address(value) -> converted {\n                converted := convert_t_uint160_to_t_address(value)\n            }\n\n            function revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20() {\n                revert(0, 0)\n            }\n\n            function round_up_to_mul_of_32(value) -> result {\n                result := and(add(value, 31), not(31))\n            }\n\n            function panic_error_0x41() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x41)\n                revert(0, 0x24)\n            }\n\n            function finalize_allocation(memPtr, size) {\n                let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n                // protect against overflow\n                if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n                mstore(64, newFreePtr)\n            }\n\n            function shift_left_224(value) -> newValue {\n                newValue :=\n\n                shl(224, value)\n\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function validator_revert_t_int256(value) {\n                if iszero(eq(value, cleanup_t_int256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_int256_fromMemory(offset, end) -> value {\n                value := mload(offset)\n                validator_revert_t_int256(value)\n            }\n\n            function abi_decode_tuple_t_int256_fromMemory(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_int256_fromMemory(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function revert_forward_1() {\n                let pos := allocate_unbounded()\n                returndatacopy(pos, 0, returndatasize())\n                revert(pos, returndatasize())\n            }\n\n            /// @src 0:413:508  \\\"function f2() m public returns (int)...\\\"\n            function fun_f2_53_inner(_8) -> var__42 {\n                var__42 := _8\n\n                /// @src 0:471:479  \\\"stateVar\\\"\n                let _9 := read_from_storage_split_offset_0_t_int256(0x00)\n                let expr_44 := _9\n                /// @src 0:482:486  \\\"this\\\"\n                let expr_45_address := address()\n                /// @src 0:482:488  \\\"this.f\\\"\n                let expr_46_address := convert_t_contract$_C_$54_to_t_address(expr_45_address)\n                let expr_46_functionSelector := 0x26121ff0\n                /// @src 0:482:490  \\\"this.f()\\\"\n\n                // storage for arguments and returned data\n                let _10 := allocate_unbounded()\n                mstore(_10, shift_left_224(expr_46_functionSelector))\n                let _11 := abi_encode_tuple__to__fromStack(add(_10, 4) )\n\n                let _12 := staticcall(gas(), expr_46_address,  _10, sub(_11, _10), _10, 32)\n\n                if iszero(_12) { revert_forward_1() }\n\n                let expr_47\n                if _12 {\n\n                    let _13 := 32\n\n                    if gt(_13, returndatasize()) {\n                        _13 := returndatasize()\n                    }\n\n                    // update freeMemoryPointer according to dynamic return size\n                    finalize_allocation(_10, _13)\n\n                    // decode return parameters from external try-call into retVars\n                    expr_47 :=  abi_decode_tuple_t_int256_fromMemory(_10, add(_10, _13))\n                }\n                /// @src 0:471:490  \\\"stateVar + this.f()\\\"\n                let expr_48 := checked_add_t_int256(expr_44, expr_47)\n\n                /// @src 0:493:501  \\\"immutVar\\\"\n                let _14 := loadimmutable(\\\"8\\\")\n                let expr_49 := _14\n                /// @src 0:471:501  \\\"stateVar + this.f() + immutVar\\\"\n                let expr_50 := checked_add_t_int256(expr_48, expr_49)\n\n                /// @src 0:464:501  \\\"return stateVar + this.f() + immutVar\\\"\n                var__42 := expr_50\n                leave\n\n            }\n            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n\n            /// @ast-id 53\n            /// @src 0:413:508  \\\"function f2() m public returns (int)...\\\"\n            function fun_f2_53() -> var__42 {\n                /// @src 0:445:448  \\\"int\\\"\n                let zero_t_int256_4 := zero_value_for_split_t_int256()\n                var__42 := zero_t_int256_4\n\n                var__42 := modifier_m_40(var__42)\n            }\n            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\",\n                \"irOptimized\": \"/// @use-src 0:\\\"C\\\", 1:\\\"D\\\"\nobject \\\"D_72\\\" {\n    code {\n        {\n            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n            let _1 := memoryguard(0xa0)\n            if callvalue() { revert(0, 0) }\n            let programSize := datasize(\\\"D_72\\\")\n            let argSize := sub(codesize(), programSize)\n            let newFreePtr := add(_1, and(add(argSize, 31), not(31)))\n            if or(gt(newFreePtr, sub(shl(64, 1), 1)), lt(newFreePtr, _1))\n            {\n                mstore(/** @src -1:-1:-1 */ 0, /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ shl(224, 0x4e487b71))\n                mstore(4, 0x41)\n                revert(/** @src -1:-1:-1 */ 0, /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ 0x24)\n            }\n            mstore(64, newFreePtr)\n            codecopy(_1, programSize, argSize)\n            if slt(sub(add(_1, argSize), _1), 32)\n            {\n                revert(/** @src -1:-1:-1 */ 0, 0)\n            }\n            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n            let value := mload(_1)\n            /// @src 0:160:162  \\\"42\\\"\n            mstore(128, 0x2a)\n            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n            let sum := add(/** @src 1:107:108  \\\"3\\\" */ 0x03, /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ value)\n            if and(1, slt(sum, value))\n            {\n                mstore(/** @src -1:-1:-1 */ 0, /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ shl(224, 0x4e487b71))\n                mstore(4, 0x11)\n                revert(/** @src -1:-1:-1 */ 0, /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ 0x24)\n            }\n            sstore(/** @src -1:-1:-1 */ 0, /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ sum)\n            let _2 := mload(64)\n            let _3 := datasize(\\\"D_72_deployed\\\")\n            codecopy(_2, dataoffset(\\\"D_72_deployed\\\"), _3)\n            setimmutable(_2, \\\"8\\\", mload(/** @src 0:160:162  \\\"42\\\" */ 128))\n            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n            return(_2, _3)\n        }\n    }\n    /// @use-src 0:\\\"C\\\", 1:\\\"D\\\"\n    object \\\"D_72_deployed\\\" {\n        code {\n            {\n                /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    switch shr(224, calldataload(0))\n                    case 0x26121ff0 {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        /// @src 0:333:341  \\\"immutVar\\\"\n                        let _1 := loadimmutable(\\\"8\\\")\n                        /// @src 0:322:341  \\\"constVar + immutVar\\\"\n                        let sum := /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ 0\n                        sum := add(/** @src 0:127:129  \\\"41\\\" */ 0x29, /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ _1)\n                        if and(1, slt(sum, _1))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x11)\n                            revert(0, 0x24)\n                        }\n                        let memPos := mload(64)\n                        mstore(memPos, sum)\n                        return(memPos, 32)\n                    }\n                    case 0x793816ec {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let _2 := sload(0)\n                        let memPos_1 := mload(64)\n                        mstore(memPos_1, _2)\n                        return(memPos_1, 32)\n                    }\n                    case 0x9942ec6f {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let _3 := sload(0)\n                        if eq(_3, sub(shl(255, 1), 1))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x11)\n                            revert(0, 0x24)\n                        }\n                        let ret := add(_3, 1)\n                        sstore(0, ret)\n                        /// @src 0:482:490  \\\"this.f()\\\"\n                        let _4 := /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ mload(64)\n                        /// @src 0:482:490  \\\"this.f()\\\"\n                        mstore(_4, /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ shl(228, 0x026121ff))\n                        /// @src 0:482:490  \\\"this.f()\\\"\n                        let _5 := staticcall(gas(), /** @src 0:482:486  \\\"this\\\" */ address(), /** @src 0:482:490  \\\"this.f()\\\" */ _4, /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ 4, /** @src 0:482:490  \\\"this.f()\\\" */ _4, 32)\n                        if iszero(_5)\n                        {\n                            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n                            let pos := mload(64)\n                            returndatacopy(pos, 0, returndatasize())\n                            revert(pos, returndatasize())\n                        }\n                        /// @src 0:482:490  \\\"this.f()\\\"\n                        let expr := /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ 0\n                        /// @src 0:482:490  \\\"this.f()\\\"\n                        if _5\n                        {\n                            let _6 := 32\n                            if gt(32, returndatasize()) { _6 := returndatasize() }\n                            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n                            let newFreePtr := add(_4, and(add(_6, 31), not(31)))\n                            if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _4))\n                            {\n                                mstore(0, shl(224, 0x4e487b71))\n                                mstore(4, 0x41)\n                                revert(0, 0x24)\n                            }\n                            mstore(64, newFreePtr)\n                            if slt(sub(/** @src 0:482:490  \\\"this.f()\\\" */ add(_4, _6), /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ _4), /** @src 0:482:490  \\\"this.f()\\\" */ 32)\n                            /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n                            { revert(0, 0) }\n                            /// @src 0:482:490  \\\"this.f()\\\"\n                            expr := /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ mload(_4)\n                        }\n                        /// @src 0:471:490  \\\"stateVar + this.f()\\\"\n                        let expr_1 := checked_add_int256(ret, expr)\n                        /// @src 0:464:501  \\\"return stateVar + this.f() + immutVar\\\"\n                        let var := /** @src 0:471:501  \\\"stateVar + this.f() + immutVar\\\" */ checked_add_int256(expr_1, /** @src 0:493:501  \\\"immutVar\\\" */ loadimmutable(\\\"8\\\"))\n                        /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n                        let memPos_2 := mload(64)\n                        mstore(memPos_2, var)\n                        return(memPos_2, /** @src 0:482:490  \\\"this.f()\\\" */ 32)\n                    }\n                    case /** @src 1:91:181  \\\"contract D is C(3)...\\\" */ 0xa00b982b {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let memPos_3 := mload(64)\n                        mstore(memPos_3, /** @src 0:127:129  \\\"41\\\" */ 0x29)\n                        /// @src 1:91:181  \\\"contract D is C(3)...\\\"\n                        return(memPos_3, 32)\n                    }\n                }\n                revert(0, 0)\n            }\n            function checked_add_int256(x, y) -> sum\n            {\n                sum := add(x, y)\n                let _1 := slt(sum, y)\n                let _2 := slt(x, 0)\n                if or(and(iszero(_2), _1), and(_2, iszero(_1)))\n                {\n                    mstore(0, shl(224, 0x4e487b71))\n                    mstore(4, 0x11)\n                    revert(0, 0x24)\n                }\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        },\n        \"D\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_default_success/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_default_success/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_empty_file_name/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; import {A} from \\\".\\\";\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_empty_file_name/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2904\",\n            \"formattedMessage\": \"DeclarationError: Declaration \\\"A\\\" not found in \\\"\\\" (referenced as \\\".\\\").\n --> :2:24:\n  |\n2 | pragma solidity >=0.0; import {A} from \\\".\\\";\n  |                        ^^^^^^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"Declaration \\\"A\\\" not found in \\\"\\\" (referenced as \\\".\\\").\",\n            \"severity\": \"error\",\n            \"sourceLocation\": {\n                \"end\": 79,\n                \"file\": \"\",\n                \"start\": 59\n            },\n            \"type\": \"DeclarationError\"\n        }\n    ],\n    \"sources\": {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_eof_no_experimental/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A.sol\": {\n            \"content\": \"contract A { constructor() { uint x = 2; { uint y = 3; } } }\"\n        }\n    },\n    \"settings\": {\n        \"eofVersion\": 1,\n        \"evmVersion\": \"osaka\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_eof_no_experimental/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"'eofVersion' setting is experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"message\": \"'eofVersion' setting is experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"severity\": \"error\",\n            \"type\": \"FatalError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_eof_unavailable_before_osaka/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"C.sol\": {\"content\": \"contract C {}\"}\n    },\n    \"settings\": {\n        \"eofVersion\": 1,\n        \"evmVersion\": \"cancun\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_eof_unavailable_before_osaka/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"EOF is not supported by EVM versions earlier than osaka.\",\n            \"message\": \"EOF is not supported by EVM versions earlier than osaka.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_evm_version_byzantium/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"input.sol\": {\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"}\n\t},\n\t\"settings\": {\n\t\t\"evmVersion\": \"byzantium\"\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_evm_version_byzantium/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Support for EVM versions older than constantinople is deprecated and will be removed in the future.\",\n            \"message\": \"Support for EVM versions older than constantinople is deprecated and will be removed in the future.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"input.sol\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_evm_version_constantinople/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"input.sol\": {\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"}\n\t},\n\t\"settings\": {\n\t\t\"evmVersion\": \"constantinople\"\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_evm_version_constantinople/output.json",
    "content": "{\n    \"sources\": {\n        \"input.sol\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_file_not_found/args",
    "content": "--standard-json input.sol\n"
  },
  {
    "path": "test/cmdlineTests/standard_file_not_found/err",
    "content": "Error: \"input.sol\" is not found.\n"
  },
  {
    "path": "test/cmdlineTests/standard_file_not_found/exit",
    "content": "1"
  },
  {
    "path": "test/cmdlineTests/standard_function_debug_info/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"a.sol\": {\n            \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; pragma abicoder v2; contract A { function f(uint[] memory x) public pure returns (uint256) { return x[0] + x[1];} }\"\n        }\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"*\": {\n                \"A\": [\n                    \"evm.deployedBytecode.functionDebugData\",\n                    \"evm.bytecode.functionDebugData\"\n                ]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_function_debug_info/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"functionDebugData\": {}\n                    },\n                    \"deployedBytecode\": {\n                        \"functionDebugData\": {\n                            \"@f_19\": {\n                                \"entryPoint\": 93,\n                                \"id\": 19,\n                                \"parameterSlots\": 1,\n                                \"returnSlots\": 1\n                            },\n                            \"abi_decode_available_length_t_array$_t_uint256_$dyn_memory_ptr\": {\n                                \"entryPoint\": 421,\n                                \"id\": null,\n                                \"parameterSlots\": 3,\n                                \"returnSlots\": 1\n                            },\n                            \"abi_decode_t_array$_t_uint256_$dyn_memory_ptr\": {\n                                \"entryPoint\": 525,\n                                \"id\": null,\n                                \"parameterSlots\": 2,\n                                \"returnSlots\": 1\n                            },\n                            \"abi_decode_t_uint256\": {\n                                \"entryPoint\": 401,\n                                \"id\": null,\n                                \"parameterSlots\": 2,\n                                \"returnSlots\": 1\n                            },\n                            \"abi_decode_tuple_t_array$_t_uint256_$dyn_memory_ptr\": {\n                                \"entryPoint\": 570,\n                                \"id\": null,\n                                \"parameterSlots\": 2,\n                                \"returnSlots\": 1\n                            },\n                            \"abi_encode_t_uint256_to_t_uint256_fromStack\": {\n                                \"entryPoint\": 641,\n                                \"id\": null,\n                                \"parameterSlots\": 2,\n                                \"returnSlots\": 0\n                            },\n                            \"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed\": {\n                                \"entryPoint\": 656,\n                                \"id\": null,\n                                \"parameterSlots\": 2,\n                                \"returnSlots\": 1\n                            },\n                            \"allocate_memory\": {\n                                \"entryPoint\": 297,\n                                \"id\": null,\n                                \"parameterSlots\": 1,\n                                \"returnSlots\": 1\n                            },\n                            \"allocate_unbounded\": {\n                                \"entryPoint\": 166,\n                                \"id\": null,\n                                \"parameterSlots\": 0,\n                                \"returnSlots\": 1\n                            },\n                            \"array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr\": {\n                                \"entryPoint\": 323,\n                                \"id\": null,\n                                \"parameterSlots\": 1,\n                                \"returnSlots\": 1\n                            },\n                            \"checked_add_t_uint256\": {\n                                \"entryPoint\": 771,\n                                \"id\": null,\n                                \"parameterSlots\": 2,\n                                \"returnSlots\": 1\n                            },\n                            \"cleanup_t_uint256\": {\n                                \"entryPoint\": 370,\n                                \"id\": null,\n                                \"parameterSlots\": 1,\n                                \"returnSlots\": 1\n                            },\n                            \"finalize_allocation\": {\n                                \"entryPoint\": 248,\n                                \"id\": null,\n                                \"parameterSlots\": 2,\n                                \"returnSlots\": 0\n                            },\n                            \"panic_error_0x11\": {\n                                \"entryPoint\": 726,\n                                \"id\": null,\n                                \"parameterSlots\": 0,\n                                \"returnSlots\": 0\n                            },\n                            \"panic_error_0x32\": {\n                                \"entryPoint\": 681,\n                                \"id\": null,\n                                \"parameterSlots\": 0,\n                                \"returnSlots\": 0\n                            },\n                            \"panic_error_0x41\": {\n                                \"entryPoint\": 203,\n                                \"id\": null,\n                                \"parameterSlots\": 0,\n                                \"returnSlots\": 0\n                            },\n                            \"revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d\": {\n                                \"entryPoint\": 183,\n                                \"id\": null,\n                                \"parameterSlots\": 0,\n                                \"returnSlots\": 0\n                            },\n                            \"revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef\": {\n                                \"entryPoint\": 366,\n                                \"id\": null,\n                                \"parameterSlots\": 0,\n                                \"returnSlots\": 0\n                            },\n                            \"revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db\": {\n                                \"entryPoint\": 179,\n                                \"id\": null,\n                                \"parameterSlots\": 0,\n                                \"returnSlots\": 0\n                            },\n                            \"revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b\": {\n                                \"entryPoint\": 175,\n                                \"id\": null,\n                                \"parameterSlots\": 0,\n                                \"returnSlots\": 0\n                            },\n                            \"round_up_to_mul_of_32\": {\n                                \"entryPoint\": 187,\n                                \"id\": null,\n                                \"parameterSlots\": 1,\n                                \"returnSlots\": 1\n                            },\n                            \"validator_revert_t_uint256\": {\n                                \"entryPoint\": 379,\n                                \"id\": null,\n                                \"parameterSlots\": 1,\n                                \"returnSlots\": 0\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_generatedSources/input.json",
    "content": "{\n \"language\": \"Solidity\",\n \"sources\": {\n  \"a.sol\": {\n   \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma abicoder v2; contract A { function f(uint[] memory) public view returns (uint256) { } }\"\n  }\n },\n \"settings\": {\n  \"evmVersion\": \"petersburg\",\n  \"outputSelection\": {\n   \"*\": {\n    \"A\": [\n     \"evm.bytecode.object\",\n     \"evm.deployedBytecode.generatedSources\",\n     \"evm.bytecode.generatedSources\"\n    ]\n   }\n  }\n }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_generatedSources/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"generatedSources\": [],\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"generatedSources\": [\n                            {\n                                \"ast\": {\n                                    \"nativeSrc\": \"0:3989:1\",\n                                    \"nodeType\": \"YulBlock\",\n                                    \"src\": \"0:3989:1\",\n                                    \"statements\": [\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"47:35:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"47:35:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"nativeSrc\": \"57:19:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"57:19:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"73:2:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"73:2:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"64\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mload\",\n                                                                \"nativeSrc\": \"67:5:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"67:5:1\"\n                                                            },\n                                                            \"nativeSrc\": \"67:9:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"67:9:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"memPtr\",\n                                                                \"nativeSrc\": \"57:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"57:6:1\"\n                                                            }\n                                                        ]\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"allocate_unbounded\",\n                                            \"nativeSrc\": \"7:75:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"memPtr\",\n                                                    \"nativeSrc\": \"40:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"40:6:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"7:75:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"177:28:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"177:28:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"194:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"194:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"197:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"197:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"revert\",\n                                                                \"nativeSrc\": \"187:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"187:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"187:12:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"187:12:1\"\n                                                        },\n                                                        \"nativeSrc\": \"187:12:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"187:12:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b\",\n                                            \"nativeSrc\": \"88:117:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"src\": \"88:117:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"300:28:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"300:28:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"317:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"317:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"320:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"320:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"revert\",\n                                                                \"nativeSrc\": \"310:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"310:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"310:12:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"310:12:1\"\n                                                        },\n                                                        \"nativeSrc\": \"310:12:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"310:12:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db\",\n                                            \"nativeSrc\": \"211:117:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"src\": \"211:117:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"423:28:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"423:28:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"440:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"440:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"443:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"443:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"revert\",\n                                                                \"nativeSrc\": \"433:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"433:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"433:12:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"433:12:1\"\n                                                        },\n                                                        \"nativeSrc\": \"433:12:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"433:12:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d\",\n                                            \"nativeSrc\": \"334:117:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"src\": \"334:117:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"505:54:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"505:54:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"nativeSrc\": \"515:38:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"515:38:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"value\",\n                                                                            \"nativeSrc\": \"533:5:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"533:5:1\"\n                                                                        },\n                                                                        {\n                                                                            \"kind\": \"number\",\n                                                                            \"nativeSrc\": \"540:2:1\",\n                                                                            \"nodeType\": \"YulLiteral\",\n                                                                            \"src\": \"540:2:1\",\n                                                                            \"type\": \"\",\n                                                                            \"value\": \"31\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"add\",\n                                                                        \"nativeSrc\": \"529:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"529:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"529:14:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"529:14:1\"\n                                                                },\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"kind\": \"number\",\n                                                                            \"nativeSrc\": \"549:2:1\",\n                                                                            \"nodeType\": \"YulLiteral\",\n                                                                            \"src\": \"549:2:1\",\n                                                                            \"type\": \"\",\n                                                                            \"value\": \"31\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"not\",\n                                                                        \"nativeSrc\": \"545:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"545:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"545:7:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"545:7:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"and\",\n                                                                \"nativeSrc\": \"525:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"525:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"525:28:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"525:28:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"result\",\n                                                                \"nativeSrc\": \"515:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"515:6:1\"\n                                                            }\n                                                        ]\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"round_up_to_mul_of_32\",\n                                            \"nativeSrc\": \"457:102:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"value\",\n                                                    \"nativeSrc\": \"488:5:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"488:5:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"result\",\n                                                    \"nativeSrc\": \"498:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"498:6:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"457:102:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"593:152:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"593:152:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"610:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"610:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"613:77:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"613:77:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"35408467139433450592217433187231851964531694900788300625387963629091585785856\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mstore\",\n                                                                \"nativeSrc\": \"603:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"603:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"603:88:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"603:88:1\"\n                                                        },\n                                                        \"nativeSrc\": \"603:88:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"603:88:1\"\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"707:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"707:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"4\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"710:4:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"710:4:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0x41\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mstore\",\n                                                                \"nativeSrc\": \"700:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"700:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"700:15:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"700:15:1\"\n                                                        },\n                                                        \"nativeSrc\": \"700:15:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"700:15:1\"\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"731:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"731:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"734:4:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"734:4:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0x24\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"revert\",\n                                                                \"nativeSrc\": \"724:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"724:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"724:15:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"724:15:1\"\n                                                        },\n                                                        \"nativeSrc\": \"724:15:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"724:15:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"panic_error_0x41\",\n                                            \"nativeSrc\": \"565:180:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"src\": \"565:180:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"794:238:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"794:238:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"nativeSrc\": \"804:58:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"804:58:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"memPtr\",\n                                                                    \"nativeSrc\": \"826:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"826:6:1\"\n                                                                },\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"size\",\n                                                                            \"nativeSrc\": \"856:4:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"856:4:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"round_up_to_mul_of_32\",\n                                                                        \"nativeSrc\": \"834:21:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"834:21:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"834:27:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"834:27:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"add\",\n                                                                \"nativeSrc\": \"822:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"822:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"822:40:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"822:40:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"newFreePtr\",\n                                                                \"nativeSrc\": \"808:10:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"808:10:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"973:22:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"973:22:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"panic_error_0x41\",\n                                                                            \"nativeSrc\": \"975:16:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"975:16:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"975:18:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"975:18:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"975:18:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"975:18:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"newFreePtr\",\n                                                                            \"nativeSrc\": \"916:10:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"916:10:1\"\n                                                                        },\n                                                                        {\n                                                                            \"kind\": \"number\",\n                                                                            \"nativeSrc\": \"928:18:1\",\n                                                                            \"nodeType\": \"YulLiteral\",\n                                                                            \"src\": \"928:18:1\",\n                                                                            \"type\": \"\",\n                                                                            \"value\": \"0xffffffffffffffff\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"gt\",\n                                                                        \"nativeSrc\": \"913:2:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"913:2:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"913:34:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"913:34:1\"\n                                                                },\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"newFreePtr\",\n                                                                            \"nativeSrc\": \"952:10:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"952:10:1\"\n                                                                        },\n                                                                        {\n                                                                            \"name\": \"memPtr\",\n                                                                            \"nativeSrc\": \"964:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"964:6:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"lt\",\n                                                                        \"nativeSrc\": \"949:2:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"949:2:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"949:22:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"949:22:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"or\",\n                                                                \"nativeSrc\": \"910:2:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"910:2:1\"\n                                                            },\n                                                            \"nativeSrc\": \"910:62:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"910:62:1\"\n                                                        },\n                                                        \"nativeSrc\": \"907:88:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"907:88:1\"\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1011:2:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"1011:2:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"64\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"newFreePtr\",\n                                                                    \"nativeSrc\": \"1015:10:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1015:10:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mstore\",\n                                                                \"nativeSrc\": \"1004:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1004:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1004:22:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1004:22:1\"\n                                                        },\n                                                        \"nativeSrc\": \"1004:22:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"1004:22:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"finalize_allocation\",\n                                            \"nativeSrc\": \"751:281:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"memPtr\",\n                                                    \"nativeSrc\": \"780:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"780:6:1\",\n                                                    \"type\": \"\"\n                                                },\n                                                {\n                                                    \"name\": \"size\",\n                                                    \"nativeSrc\": \"788:4:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"788:4:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"751:281:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"1079:88:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"1079:88:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"nativeSrc\": \"1089:30:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"1089:30:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [],\n                                                            \"functionName\": {\n                                                                \"name\": \"allocate_unbounded\",\n                                                                \"nativeSrc\": \"1099:18:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1099:18:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1099:20:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1099:20:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"memPtr\",\n                                                                \"nativeSrc\": \"1089:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1089:6:1\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"memPtr\",\n                                                                    \"nativeSrc\": \"1148:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1148:6:1\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"size\",\n                                                                    \"nativeSrc\": \"1156:4:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1156:4:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"finalize_allocation\",\n                                                                \"nativeSrc\": \"1128:19:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1128:19:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1128:33:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1128:33:1\"\n                                                        },\n                                                        \"nativeSrc\": \"1128:33:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"1128:33:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"allocate_memory\",\n                                            \"nativeSrc\": \"1038:129:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"size\",\n                                                    \"nativeSrc\": \"1063:4:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1063:4:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"memPtr\",\n                                                    \"nativeSrc\": \"1072:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1072:6:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"1038:129:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"1255:229:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"1255:229:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"1360:22:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"1360:22:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"panic_error_0x41\",\n                                                                            \"nativeSrc\": \"1362:16:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"1362:16:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"1362:18:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"1362:18:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"1362:18:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"1362:18:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"length\",\n                                                                    \"nativeSrc\": \"1332:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1332:6:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1340:18:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"1340:18:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0xffffffffffffffff\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"gt\",\n                                                                \"nativeSrc\": \"1329:2:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1329:2:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1329:30:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1329:30:1\"\n                                                        },\n                                                        \"nativeSrc\": \"1326:56:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"1326:56:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"1392:25:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"1392:25:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"length\",\n                                                                    \"nativeSrc\": \"1404:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1404:6:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1412:4:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"1412:4:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0x20\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mul\",\n                                                                \"nativeSrc\": \"1400:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1400:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1400:17:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1400:17:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"size\",\n                                                                \"nativeSrc\": \"1392:4:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1392:4:1\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"1454:23:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"1454:23:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"size\",\n                                                                    \"nativeSrc\": \"1466:4:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1466:4:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1472:4:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"1472:4:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0x20\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"add\",\n                                                                \"nativeSrc\": \"1462:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1462:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1462:15:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1462:15:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"size\",\n                                                                \"nativeSrc\": \"1454:4:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1454:4:1\"\n                                                            }\n                                                        ]\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr\",\n                                            \"nativeSrc\": \"1173:311:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"length\",\n                                                    \"nativeSrc\": \"1239:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1239:6:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"size\",\n                                                    \"nativeSrc\": \"1250:4:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1250:4:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"1173:311:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"1579:28:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"1579:28:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1596:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"1596:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1599:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"1599:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"revert\",\n                                                                \"nativeSrc\": \"1589:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1589:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1589:12:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1589:12:1\"\n                                                        },\n                                                        \"nativeSrc\": \"1589:12:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"1589:12:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef\",\n                                            \"nativeSrc\": \"1490:117:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"src\": \"1490:117:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"1658:32:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"1658:32:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"nativeSrc\": \"1668:16:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"1668:16:1\",\n                                                        \"value\": {\n                                                            \"name\": \"value\",\n                                                            \"nativeSrc\": \"1679:5:1\",\n                                                            \"nodeType\": \"YulIdentifier\",\n                                                            \"src\": \"1679:5:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"cleaned\",\n                                                                \"nativeSrc\": \"1668:7:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1668:7:1\"\n                                                            }\n                                                        ]\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"cleanup_t_uint256\",\n                                            \"nativeSrc\": \"1613:77:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"value\",\n                                                    \"nativeSrc\": \"1640:5:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1640:5:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"cleaned\",\n                                                    \"nativeSrc\": \"1650:7:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1650:7:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"1613:77:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"1739:79:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"1739:79:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"1796:16:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"1796:16:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"1805:1:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"1805:1:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0\"\n                                                                            },\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"1808:1:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"1808:1:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"revert\",\n                                                                            \"nativeSrc\": \"1798:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"1798:6:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"1798:12:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"1798:12:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"1798:12:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"1798:12:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"value\",\n                                                                            \"nativeSrc\": \"1762:5:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"1762:5:1\"\n                                                                        },\n                                                                        {\n                                                                            \"arguments\": [\n                                                                                {\n                                                                                    \"name\": \"value\",\n                                                                                    \"nativeSrc\": \"1787:5:1\",\n                                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                                    \"src\": \"1787:5:1\"\n                                                                                }\n                                                                            ],\n                                                                            \"functionName\": {\n                                                                                \"name\": \"cleanup_t_uint256\",\n                                                                                \"nativeSrc\": \"1769:17:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"1769:17:1\"\n                                                                            },\n                                                                            \"nativeSrc\": \"1769:24:1\",\n                                                                            \"nodeType\": \"YulFunctionCall\",\n                                                                            \"src\": \"1769:24:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"eq\",\n                                                                        \"nativeSrc\": \"1759:2:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"1759:2:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"1759:35:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"1759:35:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"iszero\",\n                                                                \"nativeSrc\": \"1752:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1752:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1752:43:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1752:43:1\"\n                                                        },\n                                                        \"nativeSrc\": \"1749:63:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"1749:63:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"validator_revert_t_uint256\",\n                                            \"nativeSrc\": \"1696:122:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"value\",\n                                                    \"nativeSrc\": \"1732:5:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1732:5:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"1696:122:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"1876:87:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"1876:87:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"nativeSrc\": \"1886:29:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"1886:29:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"offset\",\n                                                                    \"nativeSrc\": \"1908:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1908:6:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"calldataload\",\n                                                                \"nativeSrc\": \"1895:12:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1895:12:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1895:20:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1895:20:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"value\",\n                                                                \"nativeSrc\": \"1886:5:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1886:5:1\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"value\",\n                                                                    \"nativeSrc\": \"1951:5:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1951:5:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"validator_revert_t_uint256\",\n                                                                \"nativeSrc\": \"1924:26:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1924:26:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1924:33:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1924:33:1\"\n                                                        },\n                                                        \"nativeSrc\": \"1924:33:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"1924:33:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"abi_decode_t_uint256\",\n                                            \"nativeSrc\": \"1824:139:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"offset\",\n                                                    \"nativeSrc\": \"1854:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1854:6:1\",\n                                                    \"type\": \"\"\n                                                },\n                                                {\n                                                    \"name\": \"end\",\n                                                    \"nativeSrc\": \"1862:3:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1862:3:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"value\",\n                                                    \"nativeSrc\": \"1870:5:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1870:5:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"1824:139:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"2088:608:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"2088:608:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"nativeSrc\": \"2098:90:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"2098:90:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"length\",\n                                                                            \"nativeSrc\": \"2180:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"2180:6:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr\",\n                                                                        \"nativeSrc\": \"2123:56:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"2123:56:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"2123:64:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"2123:64:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"allocate_memory\",\n                                                                \"nativeSrc\": \"2107:15:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2107:15:1\"\n                                                            },\n                                                            \"nativeSrc\": \"2107:81:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"2107:81:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"array\",\n                                                                \"nativeSrc\": \"2098:5:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2098:5:1\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"2197:16:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"2197:16:1\",\n                                                        \"value\": {\n                                                            \"name\": \"array\",\n                                                            \"nativeSrc\": \"2208:5:1\",\n                                                            \"nodeType\": \"YulIdentifier\",\n                                                            \"src\": \"2208:5:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"dst\",\n                                                                \"nativeSrc\": \"2201:3:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"2201:3:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"array\",\n                                                                    \"nativeSrc\": \"2230:5:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"2230:5:1\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"length\",\n                                                                    \"nativeSrc\": \"2237:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"2237:6:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mstore\",\n                                                                \"nativeSrc\": \"2223:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2223:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"2223:21:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"2223:21:1\"\n                                                        },\n                                                        \"nativeSrc\": \"2223:21:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"2223:21:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"2253:23:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"2253:23:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"array\",\n                                                                    \"nativeSrc\": \"2264:5:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"2264:5:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"2271:4:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"2271:4:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0x20\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"add\",\n                                                                \"nativeSrc\": \"2260:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2260:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"2260:16:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"2260:16:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"dst\",\n                                                                \"nativeSrc\": \"2253:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2253:3:1\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"2286:44:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"2286:44:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"offset\",\n                                                                    \"nativeSrc\": \"2304:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"2304:6:1\"\n                                                                },\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"length\",\n                                                                            \"nativeSrc\": \"2316:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"2316:6:1\"\n                                                                        },\n                                                                        {\n                                                                            \"kind\": \"number\",\n                                                                            \"nativeSrc\": \"2324:4:1\",\n                                                                            \"nodeType\": \"YulLiteral\",\n                                                                            \"src\": \"2324:4:1\",\n                                                                            \"type\": \"\",\n                                                                            \"value\": \"0x20\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"mul\",\n                                                                        \"nativeSrc\": \"2312:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"2312:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"2312:17:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"2312:17:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"add\",\n                                                                \"nativeSrc\": \"2300:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2300:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"2300:30:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"2300:30:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"srcEnd\",\n                                                                \"nativeSrc\": \"2290:6:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"2290:6:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"2358:103:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"2358:103:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef\",\n                                                                            \"nativeSrc\": \"2372:77:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"2372:77:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"2372:79:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"2372:79:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"2372:79:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"2372:79:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"srcEnd\",\n                                                                    \"nativeSrc\": \"2345:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"2345:6:1\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"end\",\n                                                                    \"nativeSrc\": \"2353:3:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"2353:3:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"gt\",\n                                                                \"nativeSrc\": \"2342:2:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2342:2:1\"\n                                                            },\n                                                            \"nativeSrc\": \"2342:15:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"2342:15:1\"\n                                                        },\n                                                        \"nativeSrc\": \"2339:122:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"2339:122:1\"\n                                                    },\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"2546:144:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"2546:144:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"nativeSrc\": \"2561:21:1\",\n                                                                    \"nodeType\": \"YulVariableDeclaration\",\n                                                                    \"src\": \"2561:21:1\",\n                                                                    \"value\": {\n                                                                        \"name\": \"src\",\n                                                                        \"nativeSrc\": \"2579:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"2579:3:1\"\n                                                                    },\n                                                                    \"variables\": [\n                                                                        {\n                                                                            \"name\": \"elementPos\",\n                                                                            \"nativeSrc\": \"2565:10:1\",\n                                                                            \"nodeType\": \"YulTypedName\",\n                                                                            \"src\": \"2565:10:1\",\n                                                                            \"type\": \"\"\n                                                                        }\n                                                                    ]\n                                                                },\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"name\": \"dst\",\n                                                                                \"nativeSrc\": \"2603:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"2603:3:1\"\n                                                                            },\n                                                                            {\n                                                                                \"arguments\": [\n                                                                                    {\n                                                                                        \"name\": \"elementPos\",\n                                                                                        \"nativeSrc\": \"2629:10:1\",\n                                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                                        \"src\": \"2629:10:1\"\n                                                                                    },\n                                                                                    {\n                                                                                        \"name\": \"end\",\n                                                                                        \"nativeSrc\": \"2641:3:1\",\n                                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                                        \"src\": \"2641:3:1\"\n                                                                                    }\n                                                                                ],\n                                                                                \"functionName\": {\n                                                                                    \"name\": \"abi_decode_t_uint256\",\n                                                                                    \"nativeSrc\": \"2608:20:1\",\n                                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                                    \"src\": \"2608:20:1\"\n                                                                                },\n                                                                                \"nativeSrc\": \"2608:37:1\",\n                                                                                \"nodeType\": \"YulFunctionCall\",\n                                                                                \"src\": \"2608:37:1\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"mstore\",\n                                                                            \"nativeSrc\": \"2596:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"2596:6:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"2596:50:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"2596:50:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"2596:50:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"2596:50:1\"\n                                                                },\n                                                                {\n                                                                    \"nativeSrc\": \"2659:21:1\",\n                                                                    \"nodeType\": \"YulAssignment\",\n                                                                    \"src\": \"2659:21:1\",\n                                                                    \"value\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"name\": \"dst\",\n                                                                                \"nativeSrc\": \"2670:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"2670:3:1\"\n                                                                            },\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"2675:4:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"2675:4:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0x20\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"add\",\n                                                                            \"nativeSrc\": \"2666:3:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"2666:3:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"2666:14:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"2666:14:1\"\n                                                                    },\n                                                                    \"variableNames\": [\n                                                                        {\n                                                                            \"name\": \"dst\",\n                                                                            \"nativeSrc\": \"2659:3:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"2659:3:1\"\n                                                                        }\n                                                                    ]\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"src\",\n                                                                    \"nativeSrc\": \"2499:3:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"2499:3:1\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"srcEnd\",\n                                                                    \"nativeSrc\": \"2504:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"2504:6:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"lt\",\n                                                                \"nativeSrc\": \"2496:2:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2496:2:1\"\n                                                            },\n                                                            \"nativeSrc\": \"2496:15:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"2496:15:1\"\n                                                        },\n                                                        \"nativeSrc\": \"2470:220:1\",\n                                                        \"nodeType\": \"YulForLoop\",\n                                                        \"post\": {\n                                                            \"nativeSrc\": \"2512:25:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"2512:25:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"nativeSrc\": \"2514:21:1\",\n                                                                    \"nodeType\": \"YulAssignment\",\n                                                                    \"src\": \"2514:21:1\",\n                                                                    \"value\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"name\": \"src\",\n                                                                                \"nativeSrc\": \"2525:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"2525:3:1\"\n                                                                            },\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"2530:4:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"2530:4:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0x20\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"add\",\n                                                                            \"nativeSrc\": \"2521:3:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"2521:3:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"2521:14:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"2521:14:1\"\n                                                                    },\n                                                                    \"variableNames\": [\n                                                                        {\n                                                                            \"name\": \"src\",\n                                                                            \"nativeSrc\": \"2514:3:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"2514:3:1\"\n                                                                        }\n                                                                    ]\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"pre\": {\n                                                            \"nativeSrc\": \"2474:21:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"2474:21:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"nativeSrc\": \"2476:17:1\",\n                                                                    \"nodeType\": \"YulVariableDeclaration\",\n                                                                    \"src\": \"2476:17:1\",\n                                                                    \"value\": {\n                                                                        \"name\": \"offset\",\n                                                                        \"nativeSrc\": \"2487:6:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"2487:6:1\"\n                                                                    },\n                                                                    \"variables\": [\n                                                                        {\n                                                                            \"name\": \"src\",\n                                                                            \"nativeSrc\": \"2480:3:1\",\n                                                                            \"nodeType\": \"YulTypedName\",\n                                                                            \"src\": \"2480:3:1\",\n                                                                            \"type\": \"\"\n                                                                        }\n                                                                    ]\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"src\": \"2470:220:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"abi_decode_available_length_t_array$_t_uint256_$dyn_memory_ptr\",\n                                            \"nativeSrc\": \"1986:710:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"offset\",\n                                                    \"nativeSrc\": \"2058:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"2058:6:1\",\n                                                    \"type\": \"\"\n                                                },\n                                                {\n                                                    \"name\": \"length\",\n                                                    \"nativeSrc\": \"2066:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"2066:6:1\",\n                                                    \"type\": \"\"\n                                                },\n                                                {\n                                                    \"name\": \"end\",\n                                                    \"nativeSrc\": \"2074:3:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"2074:3:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"array\",\n                                                    \"nativeSrc\": \"2082:5:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"2082:5:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"1986:710:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"2796:293:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"2796:293:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"2845:83:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"2845:83:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d\",\n                                                                            \"nativeSrc\": \"2847:77:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"2847:77:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"2847:79:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"2847:79:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"2847:79:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"2847:79:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"arguments\": [\n                                                                                {\n                                                                                    \"name\": \"offset\",\n                                                                                    \"nativeSrc\": \"2824:6:1\",\n                                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                                    \"src\": \"2824:6:1\"\n                                                                                },\n                                                                                {\n                                                                                    \"kind\": \"number\",\n                                                                                    \"nativeSrc\": \"2832:4:1\",\n                                                                                    \"nodeType\": \"YulLiteral\",\n                                                                                    \"src\": \"2832:4:1\",\n                                                                                    \"type\": \"\",\n                                                                                    \"value\": \"0x1f\"\n                                                                                }\n                                                                            ],\n                                                                            \"functionName\": {\n                                                                                \"name\": \"add\",\n                                                                                \"nativeSrc\": \"2820:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"2820:3:1\"\n                                                                            },\n                                                                            \"nativeSrc\": \"2820:17:1\",\n                                                                            \"nodeType\": \"YulFunctionCall\",\n                                                                            \"src\": \"2820:17:1\"\n                                                                        },\n                                                                        {\n                                                                            \"name\": \"end\",\n                                                                            \"nativeSrc\": \"2839:3:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"2839:3:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"slt\",\n                                                                        \"nativeSrc\": \"2816:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"2816:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"2816:27:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"2816:27:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"iszero\",\n                                                                \"nativeSrc\": \"2809:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2809:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"2809:35:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"2809:35:1\"\n                                                        },\n                                                        \"nativeSrc\": \"2806:122:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"2806:122:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"2937:34:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"2937:34:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"offset\",\n                                                                    \"nativeSrc\": \"2964:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"2964:6:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"calldataload\",\n                                                                \"nativeSrc\": \"2951:12:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2951:12:1\"\n                                                            },\n                                                            \"nativeSrc\": \"2951:20:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"2951:20:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"length\",\n                                                                \"nativeSrc\": \"2941:6:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"2941:6:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"2980:103:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"2980:103:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"offset\",\n                                                                            \"nativeSrc\": \"3056:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"3056:6:1\"\n                                                                        },\n                                                                        {\n                                                                            \"kind\": \"number\",\n                                                                            \"nativeSrc\": \"3064:4:1\",\n                                                                            \"nodeType\": \"YulLiteral\",\n                                                                            \"src\": \"3064:4:1\",\n                                                                            \"type\": \"\",\n                                                                            \"value\": \"0x20\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"add\",\n                                                                        \"nativeSrc\": \"3052:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"3052:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"3052:17:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"3052:17:1\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"length\",\n                                                                    \"nativeSrc\": \"3071:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"3071:6:1\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"end\",\n                                                                    \"nativeSrc\": \"3079:3:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"3079:3:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"abi_decode_available_length_t_array$_t_uint256_$dyn_memory_ptr\",\n                                                                \"nativeSrc\": \"2989:62:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2989:62:1\"\n                                                            },\n                                                            \"nativeSrc\": \"2989:94:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"2989:94:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"array\",\n                                                                \"nativeSrc\": \"2980:5:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"2980:5:1\"\n                                                            }\n                                                        ]\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"abi_decode_t_array$_t_uint256_$dyn_memory_ptr\",\n                                            \"nativeSrc\": \"2719:370:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"offset\",\n                                                    \"nativeSrc\": \"2774:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"2774:6:1\",\n                                                    \"type\": \"\"\n                                                },\n                                                {\n                                                    \"name\": \"end\",\n                                                    \"nativeSrc\": \"2782:3:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"2782:3:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"array\",\n                                                    \"nativeSrc\": \"2790:5:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"2790:5:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"2719:370:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"3186:448:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"3186:448:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"3232:83:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"3232:83:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b\",\n                                                                            \"nativeSrc\": \"3234:77:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"3234:77:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"3234:79:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"3234:79:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"3234:79:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"3234:79:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"dataEnd\",\n                                                                            \"nativeSrc\": \"3207:7:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"3207:7:1\"\n                                                                        },\n                                                                        {\n                                                                            \"name\": \"headStart\",\n                                                                            \"nativeSrc\": \"3216:9:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"3216:9:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"sub\",\n                                                                        \"nativeSrc\": \"3203:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"3203:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"3203:23:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"3203:23:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"3228:2:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"3228:2:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"32\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"slt\",\n                                                                \"nativeSrc\": \"3199:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"3199:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"3199:32:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"3199:32:1\"\n                                                        },\n                                                        \"nativeSrc\": \"3196:119:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"3196:119:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"3325:302:1\",\n                                                        \"nodeType\": \"YulBlock\",\n                                                        \"src\": \"3325:302:1\",\n                                                        \"statements\": [\n                                                            {\n                                                                \"nativeSrc\": \"3340:45:1\",\n                                                                \"nodeType\": \"YulVariableDeclaration\",\n                                                                \"src\": \"3340:45:1\",\n                                                                \"value\": {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"arguments\": [\n                                                                                {\n                                                                                    \"name\": \"headStart\",\n                                                                                    \"nativeSrc\": \"3371:9:1\",\n                                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                                    \"src\": \"3371:9:1\"\n                                                                                },\n                                                                                {\n                                                                                    \"kind\": \"number\",\n                                                                                    \"nativeSrc\": \"3382:1:1\",\n                                                                                    \"nodeType\": \"YulLiteral\",\n                                                                                    \"src\": \"3382:1:1\",\n                                                                                    \"type\": \"\",\n                                                                                    \"value\": \"0\"\n                                                                                }\n                                                                            ],\n                                                                            \"functionName\": {\n                                                                                \"name\": \"add\",\n                                                                                \"nativeSrc\": \"3367:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"3367:3:1\"\n                                                                            },\n                                                                            \"nativeSrc\": \"3367:17:1\",\n                                                                            \"nodeType\": \"YulFunctionCall\",\n                                                                            \"src\": \"3367:17:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"calldataload\",\n                                                                        \"nativeSrc\": \"3354:12:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"3354:12:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"3354:31:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"3354:31:1\"\n                                                                },\n                                                                \"variables\": [\n                                                                    {\n                                                                        \"name\": \"offset\",\n                                                                        \"nativeSrc\": \"3344:6:1\",\n                                                                        \"nodeType\": \"YulTypedName\",\n                                                                        \"src\": \"3344:6:1\",\n                                                                        \"type\": \"\"\n                                                                    }\n                                                                ]\n                                                            },\n                                                            {\n                                                                \"body\": {\n                                                                    \"nativeSrc\": \"3432:83:1\",\n                                                                    \"nodeType\": \"YulBlock\",\n                                                                    \"src\": \"3432:83:1\",\n                                                                    \"statements\": [\n                                                                        {\n                                                                            \"expression\": {\n                                                                                \"arguments\": [],\n                                                                                \"functionName\": {\n                                                                                    \"name\": \"revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db\",\n                                                                                    \"nativeSrc\": \"3434:77:1\",\n                                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                                    \"src\": \"3434:77:1\"\n                                                                                },\n                                                                                \"nativeSrc\": \"3434:79:1\",\n                                                                                \"nodeType\": \"YulFunctionCall\",\n                                                                                \"src\": \"3434:79:1\"\n                                                                            },\n                                                                            \"nativeSrc\": \"3434:79:1\",\n                                                                            \"nodeType\": \"YulExpressionStatement\",\n                                                                            \"src\": \"3434:79:1\"\n                                                                        }\n                                                                    ]\n                                                                },\n                                                                \"condition\": {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"offset\",\n                                                                            \"nativeSrc\": \"3404:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"3404:6:1\"\n                                                                        },\n                                                                        {\n                                                                            \"kind\": \"number\",\n                                                                            \"nativeSrc\": \"3412:18:1\",\n                                                                            \"nodeType\": \"YulLiteral\",\n                                                                            \"src\": \"3412:18:1\",\n                                                                            \"type\": \"\",\n                                                                            \"value\": \"0xffffffffffffffff\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"gt\",\n                                                                        \"nativeSrc\": \"3401:2:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"3401:2:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"3401:30:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"3401:30:1\"\n                                                                },\n                                                                \"nativeSrc\": \"3398:117:1\",\n                                                                \"nodeType\": \"YulIf\",\n                                                                \"src\": \"3398:117:1\"\n                                                            },\n                                                            {\n                                                                \"nativeSrc\": \"3529:88:1\",\n                                                                \"nodeType\": \"YulAssignment\",\n                                                                \"src\": \"3529:88:1\",\n                                                                \"value\": {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"arguments\": [\n                                                                                {\n                                                                                    \"name\": \"headStart\",\n                                                                                    \"nativeSrc\": \"3589:9:1\",\n                                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                                    \"src\": \"3589:9:1\"\n                                                                                },\n                                                                                {\n                                                                                    \"name\": \"offset\",\n                                                                                    \"nativeSrc\": \"3600:6:1\",\n                                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                                    \"src\": \"3600:6:1\"\n                                                                                }\n                                                                            ],\n                                                                            \"functionName\": {\n                                                                                \"name\": \"add\",\n                                                                                \"nativeSrc\": \"3585:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"3585:3:1\"\n                                                                            },\n                                                                            \"nativeSrc\": \"3585:22:1\",\n                                                                            \"nodeType\": \"YulFunctionCall\",\n                                                                            \"src\": \"3585:22:1\"\n                                                                        },\n                                                                        {\n                                                                            \"name\": \"dataEnd\",\n                                                                            \"nativeSrc\": \"3609:7:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"3609:7:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"abi_decode_t_array$_t_uint256_$dyn_memory_ptr\",\n                                                                        \"nativeSrc\": \"3539:45:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"3539:45:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"3539:78:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"3539:78:1\"\n                                                                },\n                                                                \"variableNames\": [\n                                                                    {\n                                                                        \"name\": \"value0\",\n                                                                        \"nativeSrc\": \"3529:6:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"3529:6:1\"\n                                                                    }\n                                                                ]\n                                                            }\n                                                        ]\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"abi_decode_tuple_t_array$_t_uint256_$dyn_memory_ptr\",\n                                            \"nativeSrc\": \"3095:539:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"headStart\",\n                                                    \"nativeSrc\": \"3156:9:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"3156:9:1\",\n                                                    \"type\": \"\"\n                                                },\n                                                {\n                                                    \"name\": \"dataEnd\",\n                                                    \"nativeSrc\": \"3167:7:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"3167:7:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"value0\",\n                                                    \"nativeSrc\": \"3179:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"3179:6:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"3095:539:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"3705:53:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"3705:53:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"pos\",\n                                                                    \"nativeSrc\": \"3722:3:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"3722:3:1\"\n                                                                },\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"value\",\n                                                                            \"nativeSrc\": \"3745:5:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"3745:5:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"cleanup_t_uint256\",\n                                                                        \"nativeSrc\": \"3727:17:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"3727:17:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"3727:24:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"3727:24:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mstore\",\n                                                                \"nativeSrc\": \"3715:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"3715:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"3715:37:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"3715:37:1\"\n                                                        },\n                                                        \"nativeSrc\": \"3715:37:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"3715:37:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"abi_encode_t_uint256_to_t_uint256_fromStack\",\n                                            \"nativeSrc\": \"3640:118:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"value\",\n                                                    \"nativeSrc\": \"3693:5:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"3693:5:1\",\n                                                    \"type\": \"\"\n                                                },\n                                                {\n                                                    \"name\": \"pos\",\n                                                    \"nativeSrc\": \"3700:3:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"3700:3:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"3640:118:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"3862:124:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"3862:124:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"nativeSrc\": \"3872:26:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"3872:26:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"headStart\",\n                                                                    \"nativeSrc\": \"3884:9:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"3884:9:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"3895:2:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"3895:2:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"32\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"add\",\n                                                                \"nativeSrc\": \"3880:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"3880:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"3880:18:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"3880:18:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"tail\",\n                                                                \"nativeSrc\": \"3872:4:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"3872:4:1\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"value0\",\n                                                                    \"nativeSrc\": \"3952:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"3952:6:1\"\n                                                                },\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"headStart\",\n                                                                            \"nativeSrc\": \"3965:9:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"3965:9:1\"\n                                                                        },\n                                                                        {\n                                                                            \"kind\": \"number\",\n                                                                            \"nativeSrc\": \"3976:1:1\",\n                                                                            \"nodeType\": \"YulLiteral\",\n                                                                            \"src\": \"3976:1:1\",\n                                                                            \"type\": \"\",\n                                                                            \"value\": \"0\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"add\",\n                                                                        \"nativeSrc\": \"3961:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"3961:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"3961:17:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"3961:17:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"abi_encode_t_uint256_to_t_uint256_fromStack\",\n                                                                \"nativeSrc\": \"3908:43:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"3908:43:1\"\n                                                            },\n                                                            \"nativeSrc\": \"3908:71:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"3908:71:1\"\n                                                        },\n                                                        \"nativeSrc\": \"3908:71:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"3908:71:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed\",\n                                            \"nativeSrc\": \"3764:222:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"headStart\",\n                                                    \"nativeSrc\": \"3834:9:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"3834:9:1\",\n                                                    \"type\": \"\"\n                                                },\n                                                {\n                                                    \"name\": \"value0\",\n                                                    \"nativeSrc\": \"3846:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"3846:6:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"tail\",\n                                                    \"nativeSrc\": \"3857:4:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"3857:4:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"3764:222:1\"\n                                        }\n                                    ]\n                                },\n                                \"contents\": \"{\n\n    function allocate_unbounded() -> memPtr {\n        memPtr := mload(64)\n    }\n\n    function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n        revert(0, 0)\n    }\n\n    function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n        revert(0, 0)\n    }\n\n    function revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() {\n        revert(0, 0)\n    }\n\n    function round_up_to_mul_of_32(value) -> result {\n        result := and(add(value, 31), not(31))\n    }\n\n    function panic_error_0x41() {\n        mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n        mstore(4, 0x41)\n        revert(0, 0x24)\n    }\n\n    function finalize_allocation(memPtr, size) {\n        let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n        // protect against overflow\n        if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n        mstore(64, newFreePtr)\n    }\n\n    function allocate_memory(size) -> memPtr {\n        memPtr := allocate_unbounded()\n        finalize_allocation(memPtr, size)\n    }\n\n    function array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr(length) -> size {\n        // Make sure we can allocate memory without overflow\n        if gt(length, 0xffffffffffffffff) { panic_error_0x41() }\n\n        size := mul(length, 0x20)\n\n        // add length slot\n        size := add(size, 0x20)\n\n    }\n\n    function revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef() {\n        revert(0, 0)\n    }\n\n    function cleanup_t_uint256(value) -> cleaned {\n        cleaned := value\n    }\n\n    function validator_revert_t_uint256(value) {\n        if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n    }\n\n    function abi_decode_t_uint256(offset, end) -> value {\n        value := calldataload(offset)\n        validator_revert_t_uint256(value)\n    }\n\n    // uint256[]\n    function abi_decode_available_length_t_array$_t_uint256_$dyn_memory_ptr(offset, length, end) -> array {\n        array := allocate_memory(array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr(length))\n        let dst := array\n\n        mstore(array, length)\n        dst := add(array, 0x20)\n\n        let srcEnd := add(offset, mul(length, 0x20))\n        if gt(srcEnd, end) {\n            revert_error_81385d8c0b31fffe14be1da910c8bd3a80be4cfa248e04f42ec0faea3132a8ef()\n        }\n        for { let src := offset } lt(src, srcEnd) { src := add(src, 0x20) }\n        {\n\n            let elementPos := src\n\n            mstore(dst, abi_decode_t_uint256(elementPos, end))\n            dst := add(dst, 0x20)\n        }\n    }\n\n    // uint256[]\n    function abi_decode_t_array$_t_uint256_$dyn_memory_ptr(offset, end) -> array {\n        if iszero(slt(add(offset, 0x1f), end)) { revert_error_1b9f4a0a5773e33b91aa01db23bf8c55fce1411167c872835e7fa00a4f17d46d() }\n        let length := calldataload(offset)\n        array := abi_decode_available_length_t_array$_t_uint256_$dyn_memory_ptr(add(offset, 0x20), length, end)\n    }\n\n    function abi_decode_tuple_t_array$_t_uint256_$dyn_memory_ptr(headStart, dataEnd) -> value0 {\n        if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n        {\n\n            let offset := calldataload(add(headStart, 0))\n            if gt(offset, 0xffffffffffffffff) { revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() }\n\n            value0 := abi_decode_t_array$_t_uint256_$dyn_memory_ptr(add(headStart, offset), dataEnd)\n        }\n\n    }\n\n    function abi_encode_t_uint256_to_t_uint256_fromStack(value, pos) {\n        mstore(pos, cleanup_t_uint256(value))\n    }\n\n    function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart , value0) -> tail {\n        tail := add(headStart, 32)\n\n        abi_encode_t_uint256_to_t_uint256_fromStack(value0,  add(headStart, 0))\n\n    }\n\n}\n\",\n                                \"id\": 1,\n                                \"language\": \"Yul\",\n                                \"name\": \"#utility.yul\"\n                            }\n                        ]\n                    }\n                }\n            }\n        }\n    },\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"3420\",\n            \"formattedMessage\": \"Warning: Source file does not specify required compiler version!\n--> a.sol\n\n\",\n            \"message\": \"Source file does not specify required compiler version!\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": -1,\n                \"file\": \"a.sol\",\n                \"start\": -1\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_immutable_references/input.json",
    "content": "{\n \"language\": \"Solidity\",\n \"sources\": {\n  \"a.sol\": {\n   \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { uint256 immutable x = 1 + 3; function f() public pure returns (uint256) { return x; } }\"\n  }\n },\n \"settings\": {\n  \"evmVersion\": \"petersburg\",\n  \"outputSelection\": {\n   \"*\": {\n    \"A\": [\n     \"evm.deployedBytecode.immutableReferences\"\n    ]\n   }\n  }\n }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_immutable_references/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A\": {\n                \"evm\": {\n                    \"deployedBytecode\": {\n                        \"immutableReferences\": {\n                            \"6\": [\n                                {\n                                    \"length\": 32,\n                                    \"start\": 75\n                                }\n                            ]\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"assemblyJson\": {\n                \".code\": [\n                    {\n                        \"begin\": 36,\n                        \"end\": 51,\n                        \"name\": \"PUSH\",\n                        \"source\": 0,\n                        \"value\": \"0\"\n                    }\n                ],\n                \"sourceList\": [\n                    \"<stdin>\"\n                ]\n            }\n        }\n    },\n    \"settings\": {\n        \"experimental\": true,\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\"*\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"<stdin>\\\":36:51   */\n  0x00\n\",\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"functionDebugData\": {},\n                        \"immutableReferences\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"\",\n                        \"opcodes\": \"\",\n                        \"sourceMap\": \"\"\n                    },\n                    \"legacyAssembly\": {\n                        \".code\": [\n                            {\n                                \"begin\": 36,\n                                \"end\": 51,\n                                \"name\": \"PUSH\",\n                                \"source\": 0,\n                                \"value\": \"0\"\n                            }\n                        ],\n                        \"sourceList\": [\n                            \"<stdin>\"\n                        ]\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_eof_unavailable_before_osaka/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"C.sol\": {\"assemblyJson\": {}}\n    },\n    \"settings\": {\n        \"eofVersion\": 1,\n        \"evmVersion\": \"cancun\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_eof_unavailable_before_osaka/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"EOF is not supported by EVM versions earlier than osaka.\",\n            \"message\": \"EOF is not supported by EVM versions earlier than osaka.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_immutable_references/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"assemblyJson\": {\n                \".code\": [\n                    {\n                        \"begin\": 59,\n                        \"end\": 159,\n                        \"name\": \"ASSIGNIMMUTABLE\",\n                        \"source\": 0,\n                        \"value\": \"6\"\n                    }\n                ],\n                \".data\": {\n                    \"0\": {\n                        \".auxdata\": \"a2646970667358221220762f49087b0990aeaac25050c4a08d9057732db3cac345579ad648d92458e09e64736f6c63430008170033\",\n                        \".code\": [\n                            {\n                                \"begin\": 153,\n                                \"end\": 154,\n                                \"name\": \"PUSHIMMUTABLE\",\n                                \"source\": 0,\n                                \"value\": \"6\"\n                            }\n                        ]\n                    }\n                },\n                \"sourceList\": [\n                    \"test.sol\",\n                    \"#utility.yul\"\n                ]\n            }\n        }\n    },\n    \"settings\": {\n        \"experimental\": true,\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\n                    \"evm.bytecode\",\n                    \"evm.deployedBytecode\"\n                ]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_immutable_references/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"functionDebugData\": {},\n                        \"immutableReferences\": {\n                            \"6\": [\n                                {\n                                    \"length\": 32,\n                                    \"start\": 1\n                                }\n                            ]\n                        },\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_input_array/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"assemblyJson\": []\n        }\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\"evm.bytecode\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_input_array/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A\",\n            \"message\": \"Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_key_inside_source/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"invalidAssemblyJsonObject\": {\n                \".code\": [\n                    {\n                        \"begin\": 36,\n                        \"end\": 51,\n                        \"name\": \"PUSH\",\n                        \"source\": 0,\n                        \"value\": \"0\"\n                    }\n                ],\n                \"sourceList\": [\n                    \"<stdin>\"\n                ]\n            }\n        }\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\"evm.bytecode\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_key_inside_source/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A\",\n            \"message\": \"Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_key_other_source/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"keccak256\": \"0x1234\",\n            \"assemblyJson\": {\n                \".code\": [\n                    {\n                        \"begin\": 36,\n                        \"end\": 51,\n                        \"name\": \"PUSH\",\n                        \"source\": 0,\n                        \"value\": \"0\"\n                    }\n                ],\n                \"sourceList\": [\n                    \"<stdin>\"\n                ]\n            }\n        }\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\"evm.bytecode\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_key_other_source/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A\",\n            \"message\": \"Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_no_source/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\"evm.bytecode\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_no_source/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"No input sources specified.\",\n            \"message\": \"No input sources specified.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_opcode/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"assemblyJson\": {\n                \".code\": [\n                    {\n                        \"begin\": 36,\n                        \"end\": 51,\n                        \"name\": \"INVALID_OPCODE\",\n                        \"source\": 0,\n                        \"value\": \"0\"\n                    }\n                ],\n                \"sourceList\": [\n                    \"<stdin>\"\n                ]\n            }\n        }\n    },\n    \"settings\": {\n        \"experimental\": true,\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\"evm.bytecode\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_opcode/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Assembly import error: Invalid opcode (INVALID_OPCODE)\",\n            \"message\": \"Assembly import error: Invalid opcode (INVALID_OPCODE)\",\n            \"severity\": \"error\",\n            \"type\": \"Exception\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_two_sources/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"assemblyJson\": {}\n        },\n        \"B\": {\n            \"assemblyJson\": {}\n        }\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\n                    \"evm.bytecode\"\n                ]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_invalid_two_sources/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"EVMAssembly import only supports exactly one input file.\",\n            \"message\": \"EVMAssembly import only supports exactly one input file.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_link_references/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"assemblyJson\": {\n                \".code\": [],\n                \".data\": {\n                    \"0\": {\n                        \".auxdata\": \"a264697066735822122049fc8a5c547ec9ab3b6a5804732f6ef55e87fdb28a3a8826c23cdeb89c034e3d64736f6c63430008170033\",\n                        \".code\": [\n                            {\n                                \"begin\": 133,\n                                \"end\": 134,\n                                \"name\": \"PUSHLIB\",\n                                \"source\": 0,\n                                \"value\": \"test.sol:L\"\n                            }\n                        ]\n                    }\n                },\n                \"sourceList\": [\n                    \"test.sol\",\n                    \"#utility.yul\"\n                ]\n            }\n        }\n    },\n    \"settings\": {\n        \"experimental\": true,\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\n                    \"evm.bytecode\",\n                    \"evm.deployedBytecode\"\n                ]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_link_references/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\": \"\"\n                    },\n                    \"deployedBytecode\": {\n                        \"functionDebugData\": {},\n                        \"immutableReferences\": {},\n                        \"linkReferences\": {\n                            \"test.sol\": {\n                                \"L\": [\n                                    {\n                                        \"length\": 20,\n                                        \"start\": 1\n                                    }\n                                ]\n                            }\n                        },\n                        \"object\": \"<BYTECODE REMOVED>__$d553ddd21b3d8da0d69a6510c170f4a77b$__<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_multiple_keys_inside_source/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"assemblyJson\": {\n                \".code\": [\n                    {\n                        \"begin\": 36,\n                        \"end\": 51,\n                        \"name\": \"PUSH\",\n                        \"source\": 0,\n                        \"value\": \"0\"\n                    }\n                ],\n                \"sourceList\": [\n                    \"<stdin>\"\n                ]\n            },\n            \"urls\":\n            [\n                \"bzzr://56ab...\"\n            ]\n        }\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\"evm.bytecode\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_multiple_keys_inside_source/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A\",\n            \"message\": \"Invalid input source specified. Expected exactly one object, named 'assemblyJson', inside $.sources.A\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_no_optimize/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"assemblyJson\": {\n                \".code\": [\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"REVERT\" }\n                ]\n            }\n        }\n    },\n    \"settings\": {\n        \"experimental\": true,\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\"evm.assembly\"]\n            }\n        },\n        \"optimizer\": {\n            \"enabled\": true\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_no_optimize/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"\": {\n                \"evm\": {\n                    \"assembly\": \"  revert(0x00, 0x00)\n\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_no_output_selection/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"assemblyJson\": {\n                \".code\": [\n                    {\n                        \"begin\": 36,\n                        \"end\": 51,\n                        \"name\": \"PUSH\",\n                        \"source\": 0,\n                        \"value\": \"0\"\n                    }\n                ],\n                \"sourceList\": [\n                    \"<stdin>\"\n                ]\n            }\n        }\n    },\n    \"settings\": {\n        \"experimental\": true,\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\n                ]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_no_output_selection/output.json",
    "content": "{}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_optimize/input.json",
    "content": "{\n    \"language\": \"EVMAssembly\",\n    \"sources\": {\n        \"A\": {\n            \"assemblyJson\": {\n                \".code\": [\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"PUSH\", \"value\": \"0\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"POP\" },\n                    { \"name\": \"REVERT\" }\n                ]\n            }\n        }\n    },\n    \"settings\": {\n        \"experimental\": true,\n        \"outputSelection\": {\n            \"*\": {\n                \"\": [\"evm.assembly\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_asm_json_optimize/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"\": {\n                \"evm\": {\n                    \"assembly\": \"  0x00\n  0x00\n  0x00\n  0x00\n  0x00\n  0x00\n  0x00\n  0x00\n  0x00\n  pop(0x00)\n  pop\n  pop\n  pop\n  pop\n  pop\n  pop\n  pop\n  revert\n\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_ast/input.json",
    "content": "{\n\t\"language\": \"SolidityAST\",\n\t\"sources\": {\n\t\t\"A\": {\n\t\t\t\"ast\": {\n\t\t\t\t\"absolutePath\": \"A\",\n\t\t\t\t\"exportedSymbols\": {\n\t\t\t\t\t\"C\": [\n\t\t\t\t\t\t6\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t\"id\": 7,\n\t\t\t\t\"license\": \"GPL-3.0\",\n\t\t\t\t\"nodeType\": \"SourceUnit\",\n\t\t\t\t\"nodes\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"id\": 1,\n\t\t\t\t\t\t\"literals\": [\n\t\t\t\t\t\t\t\"solidity\",\n\t\t\t\t\t\t\t\">=\",\n\t\t\t\t\t\t\t\"0.0\"\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"nodeType\": \"PragmaDirective\",\n\t\t\t\t\t\t\"src\": \"36:22:0\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"abstract\": false,\n\t\t\t\t\t\t\"baseContracts\": [],\n\t\t\t\t\t\t\"canonicalName\": \"C\",\n\t\t\t\t\t\t\"contractDependencies\": [],\n\t\t\t\t\t\t\"contractKind\": \"contract\",\n\t\t\t\t\t\t\"fullyImplemented\": true,\n\t\t\t\t\t\t\"id\": 6,\n\t\t\t\t\t\t\"linearizedBaseContracts\": [\n\t\t\t\t\t\t\t6\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"name\": \"C\",\n\t\t\t\t\t\t\"nameLocation\": \"68:1:0\",\n\t\t\t\t\t\t\"nodeType\": \"ContractDefinition\",\n\t\t\t\t\t\t\"nodes\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"id\": 4,\n\t\t\t\t\t\t\t\t\t\"nodeType\": \"Block\",\n\t\t\t\t\t\t\t\t\t\"src\": \"97:2:0\",\n\t\t\t\t\t\t\t\t\t\"statements\": []\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"functionSelector\": \"26121ff0\",\n\t\t\t\t\t\t\t\t\"id\": 5,\n\t\t\t\t\t\t\t\t\"implemented\": true,\n\t\t\t\t\t\t\t\t\"kind\": \"function\",\n\t\t\t\t\t\t\t\t\"modifiers\": [],\n\t\t\t\t\t\t\t\t\"name\": \"f\",\n\t\t\t\t\t\t\t\t\"nameLocation\": \"81:1:0\",\n\t\t\t\t\t\t\t\t\"nodeType\": \"FunctionDefinition\",\n\t\t\t\t\t\t\t\t\"parameters\": {\n\t\t\t\t\t\t\t\t\t\"id\": 2,\n\t\t\t\t\t\t\t\t\t\"nodeType\": \"ParameterList\",\n\t\t\t\t\t\t\t\t\t\"parameters\": [],\n\t\t\t\t\t\t\t\t\t\"src\": \"82:2:0\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"returnParameters\": {\n\t\t\t\t\t\t\t\t\t\"id\": 3,\n\t\t\t\t\t\t\t\t\t\"nodeType\": \"ParameterList\",\n\t\t\t\t\t\t\t\t\t\"parameters\": [],\n\t\t\t\t\t\t\t\t\t\"src\": \"97:0:0\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"scope\": 6,\n\t\t\t\t\t\t\t\t\"src\": \"72:27:0\",\n\t\t\t\t\t\t\t\t\"stateMutability\": \"pure\",\n\t\t\t\t\t\t\t\t\"virtual\": false,\n\t\t\t\t\t\t\t\t\"visibility\": \"public\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"scope\": 7,\n\t\t\t\t\t\t\"src\": \"59:42:0\",\n\t\t\t\t\t\t\"usedErrors\": []\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"src\": \"36:65:0\"\n\t\t\t},\n\t\t\t\"id\": 0\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"\": [\n\t\t\t\t\t\"ast\"\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_ast/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"ast\": {\n                \"absolutePath\": \"A\",\n                \"exportedSymbols\": {\n                    \"C\": [\n                        6\n                    ]\n                },\n                \"id\": 7,\n                \"license\": \"GPL-3.0\",\n                \"nodeType\": \"SourceUnit\",\n                \"nodes\": [\n                    {\n                        \"id\": 1,\n                        \"literals\": [\n                            \"solidity\",\n                            \">=\",\n                            \"0.0\"\n                        ],\n                        \"nodeType\": \"PragmaDirective\",\n                        \"src\": \"36:22:0\"\n                    },\n                    {\n                        \"abstract\": false,\n                        \"baseContracts\": [],\n                        \"canonicalName\": \"C\",\n                        \"contractDependencies\": [],\n                        \"contractKind\": \"contract\",\n                        \"fullyImplemented\": true,\n                        \"id\": 6,\n                        \"linearizedBaseContracts\": [\n                            6\n                        ],\n                        \"name\": \"C\",\n                        \"nameLocation\": \"68:1:0\",\n                        \"nodeType\": \"ContractDefinition\",\n                        \"nodes\": [\n                            {\n                                \"body\": {\n                                    \"id\": 4,\n                                    \"nodeType\": \"Block\",\n                                    \"src\": \"97:2:0\",\n                                    \"statements\": []\n                                },\n                                \"functionSelector\": \"26121ff0\",\n                                \"id\": 5,\n                                \"implemented\": true,\n                                \"kind\": \"function\",\n                                \"modifiers\": [],\n                                \"name\": \"f\",\n                                \"nameLocation\": \"81:1:0\",\n                                \"nodeType\": \"FunctionDefinition\",\n                                \"parameters\": {\n                                    \"id\": 2,\n                                    \"nodeType\": \"ParameterList\",\n                                    \"parameters\": [],\n                                    \"src\": \"82:2:0\"\n                                },\n                                \"returnParameters\": {\n                                    \"id\": 3,\n                                    \"nodeType\": \"ParameterList\",\n                                    \"parameters\": [],\n                                    \"src\": \"97:0:0\"\n                                },\n                                \"scope\": 6,\n                                \"src\": \"72:27:0\",\n                                \"stateMutability\": \"pure\",\n                                \"virtual\": false,\n                                \"visibility\": \"public\"\n                            }\n                        ],\n                        \"scope\": 7,\n                        \"src\": \"59:42:0\",\n                        \"usedErrors\": [],\n                        \"usedEvents\": []\n                    }\n                ],\n                \"src\": \"36:65:0\"\n            },\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_ast_no_experimental/input.json",
    "content": "{\n    \"language\": \"SolidityAST\",\n    \"sources\": {\n        \"A.sol\": {\n            \"content\": \"contract A { constructor() { uint x = 2; { uint y = 3; } } }\"\n        }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_ast_no_experimental/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"'SolidityAST' and 'EVMAssembly' inputs are experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"message\": \"'SolidityAST' and 'EVMAssembly' inputs are experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"severity\": \"error\",\n            \"type\": \"FatalError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_ast_select_bytecode/input.json",
    "content": "{\n  \"language\": \"SolidityAST\",\n  \"sources\": {\n    \"A\": {\n      \"ast\": {\n        \"absolutePath\": \"empty_contract.sol\",\n        \"exportedSymbols\": {\n          \"test\": [\n            1\n          ]\n        },\n        \"id\": 2,\n        \"nodeType\": \"SourceUnit\",\n        \"nodes\": [\n          {\n            \"abstract\": false,\n            \"baseContracts\": [],\n            \"canonicalName\": \"test\",\n            \"contractDependencies\": [],\n            \"contractKind\": \"contract\",\n            \"fullyImplemented\": true,\n            \"id\": 1,\n            \"linearizedBaseContracts\": [\n              1\n            ],\n            \"name\": \"test\",\n            \"nameLocation\": \"9:4:0\",\n            \"nodeType\": \"ContractDefinition\",\n            \"nodes\": [],\n            \"scope\": 2,\n            \"src\": \"0:17:0\",\n            \"usedErrors\": []\n          }\n        ],\n        \"src\": \"0:124:0\"\n      },\n      \"id\": 0\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode\",\n          \"evm.bytecode.sourceMap\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_ast_select_bytecode/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"test\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"generatedSources\": [],\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_with_comments/input.json",
    "content": "{\n\t\"language\": \"SolidityAST\",\n\t\"sources\": { // this is a comment\n\t\t\"A\": {\n\t\t\t\"ast\": {\n\t\t\t\t\"absolutePath\": \"A\",\n\t\t\t\t\"exportedSymbols\": {\n\t\t\t\t\t\"C\": [\n\t\t\t\t\t\t6 /* and this another comment */\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t\"id\": 7,\n\t\t\t\t\"license\": \"GPL-3.0\",\n\t\t\t\t\"nodeType\": \"SourceUnit\",\n\t\t\t\t\"nodes\": /* and this is a comment too */[\n\t\t\t\t\t// this is a comment\n\t\t\t\t\t{\n\t\t\t\t\t\t/*this is a comment*/\"id\"/* and this is another comment too*/: 1,\n\t\t\t\t\t\t\"literals\": [\n\t\t\t\t\t\t\t\"solidity\",\n\t\t\t\t\t\t\t\">=\",\n\t\t\t\t\t\t\t\"0.0\"\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"nodeType\": \"PragmaDirective\",\n\t\t\t\t\t\t\"src\": \"36:22:0\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"abstract\": false,\n\t\t\t\t\t\t\"baseContracts\": [],\n\t\t\t\t\t\t\"canonicalName\": \"C\",\n\t\t\t\t\t\t\"contractDependencies\": [],\n\t\t\t\t\t\t\"contractKind\": \"contract\",\n\t\t\t\t\t\t\"fullyImplemented\": true,\n\t\t\t\t\t\t\"id\": 6,\n\t\t\t\t\t\t\"linearizedBaseContracts\": [\n\t\t\t\t\t\t\t6\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"name\": \"C\",\n\t\t\t\t\t\t\"nameLocation\": \"68:1:0\",\n\t\t\t\t\t\t\"nodeType\": \"ContractDefinition\",\n\t\t\t\t\t\t\"nodes\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"id\": 4,\n\t\t\t\t\t\t\t\t\t\"nodeType\": \"Block\",\n\t\t\t\t\t\t\t\t\t\"src\": \"97:2:0\",\n\t\t\t\t\t\t\t\t\t\"statements\": []\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"functionSelector\": \"26121ff0\",\n\t\t\t\t\t\t\t\t\"id\": 5,\n\t\t\t\t\t\t\t\t\"implemented\": true,\n\t\t\t\t\t\t\t\t\"kind\": \"function\",\n\t\t\t\t\t\t\t\t\"modifiers\": [],\n\t\t\t\t\t\t\t\t\"name\": \"f\",\n\t\t\t\t\t\t\t\t\"nameLocation\": \"81:1:0\",\n\t\t\t\t\t\t\t\t\"nodeType\": \"FunctionDefinition\",\n\t\t\t\t\t\t\t\t\"parameters\": {\n\t\t\t\t\t\t\t\t\t\"id\": 2,\n\t\t\t\t\t\t\t\t\t\"nodeType\": \"ParameterList\",\n\t\t\t\t\t\t\t\t\t\"parameters\": [],\n\t\t\t\t\t\t\t\t\t\"src\": \"82:2:0\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"returnParameters\": {\n\t\t\t\t\t\t\t\t\t\"id\": 3,\n\t\t\t\t\t\t\t\t\t\"nodeType\": \"ParameterList\",\n\t\t\t\t\t\t\t\t\t\"parameters\": [],\n\t\t\t\t\t\t\t\t\t\"src\": \"97:0:0\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"scope\": 6,\n\t\t\t\t\t\t\t\t\"src\": \"72:27:0\",\n\t\t\t\t\t\t\t\t\"stateMutability\": \"pure\",\n\t\t\t\t\t\t\t\t\"virtual\": false,\n\t\t\t\t\t\t\t\t\"visibility\": \"public\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"scope\": 7,\n\t\t\t\t\t\t\"src\": \"59:42:0\",\n\t\t\t\t\t\t\"usedErrors\": []\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"src\": \"36:65:0\"\n\t\t\t},\n\t\t\t\"id\": 0\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"\": [\n\t\t\t\t\t\"ast\"\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_with_comments/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"ast\": {\n                \"absolutePath\": \"A\",\n                \"exportedSymbols\": {\n                    \"C\": [\n                        6\n                    ]\n                },\n                \"id\": 7,\n                \"license\": \"GPL-3.0\",\n                \"nodeType\": \"SourceUnit\",\n                \"nodes\": [\n                    {\n                        \"id\": 1,\n                        \"literals\": [\n                            \"solidity\",\n                            \">=\",\n                            \"0.0\"\n                        ],\n                        \"nodeType\": \"PragmaDirective\",\n                        \"src\": \"36:22:0\"\n                    },\n                    {\n                        \"abstract\": false,\n                        \"baseContracts\": [],\n                        \"canonicalName\": \"C\",\n                        \"contractDependencies\": [],\n                        \"contractKind\": \"contract\",\n                        \"fullyImplemented\": true,\n                        \"id\": 6,\n                        \"linearizedBaseContracts\": [\n                            6\n                        ],\n                        \"name\": \"C\",\n                        \"nameLocation\": \"68:1:0\",\n                        \"nodeType\": \"ContractDefinition\",\n                        \"nodes\": [\n                            {\n                                \"body\": {\n                                    \"id\": 4,\n                                    \"nodeType\": \"Block\",\n                                    \"src\": \"97:2:0\",\n                                    \"statements\": []\n                                },\n                                \"functionSelector\": \"26121ff0\",\n                                \"id\": 5,\n                                \"implemented\": true,\n                                \"kind\": \"function\",\n                                \"modifiers\": [],\n                                \"name\": \"f\",\n                                \"nameLocation\": \"81:1:0\",\n                                \"nodeType\": \"FunctionDefinition\",\n                                \"parameters\": {\n                                    \"id\": 2,\n                                    \"nodeType\": \"ParameterList\",\n                                    \"parameters\": [],\n                                    \"src\": \"82:2:0\"\n                                },\n                                \"returnParameters\": {\n                                    \"id\": 3,\n                                    \"nodeType\": \"ParameterList\",\n                                    \"parameters\": [],\n                                    \"src\": \"97:0:0\"\n                                },\n                                \"scope\": 6,\n                                \"src\": \"72:27:0\",\n                                \"stateMutability\": \"pure\",\n                                \"virtual\": false,\n                                \"visibility\": \"public\"\n                            }\n                        ],\n                        \"scope\": 7,\n                        \"src\": \"59:42:0\",\n                        \"usedErrors\": [],\n                        \"usedEvents\": []\n                    }\n                ],\n                \"src\": \"36:65:0\"\n            },\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_with_comments_simple/input.json",
    "content": "{\n\t\"language\": \"SolidityAST\",\n\t\"sources\": {\n\t\t// this is a comment\n\t\t\"A\": {\n\t\t\t\"ast\": {\n\t\t\t\t\"absolutePath\": \"A\",\n\t\t\t\t\"exportedSymbols\": {\n\t\t\t\t\t\"C\": [6 /* and this another comment */]\n\t\t\t\t},\n\t\t\t\t\"id\": 7,\n\t\t\t\t\"license\": \"GPL-3.0\",\n\t\t\t\t\"nodeType\": \"SourceUnit\",\n\t\t\t\t\"nodes\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"id\": 1,\n\t\t\t\t\t\t\"literals\": [\"solidity\", \">=\", \"0.0\"],\n\t\t\t\t\t\t\"nodeType\": \"PragmaDirective\",\n\t\t\t\t\t\t\"src\": \"36:22:0\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"abstract\": false,\n\t\t\t\t\t\t\"baseContracts\": [],\n\t\t\t\t\t\t\"canonicalName\": \"C\",\n\t\t\t\t\t\t\"contractDependencies\": [],\n\t\t\t\t\t\t\"contractKind\": \"contract\",\n\t\t\t\t\t\t\"fullyImplemented\": true,\n\t\t\t\t\t\t\"id\": 6,\n\t\t\t\t\t\t\"linearizedBaseContracts\": [6],\n\t\t\t\t\t\t\"name\": \"C\",\n\t\t\t\t\t\t\"nameLocation\": \"68:1:0\",\n\t\t\t\t\t\t\"nodeType\": \"ContractDefinition\",\n\t\t\t\t\t\t\"nodes\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"body\": {\n\t\t\t\t\t\t\t\t\t\"id\": 4,\n\t\t\t\t\t\t\t\t\t\"nodeType\": \"Block\",\n\t\t\t\t\t\t\t\t\t\"src\": \"97:2:0\",\n\t\t\t\t\t\t\t\t\t\"statements\": []\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"functionSelector\": \"26121ff0\",\n\t\t\t\t\t\t\t\t\"id\": 5,\n\t\t\t\t\t\t\t\t\"implemented\": true,\n\t\t\t\t\t\t\t\t\"kind\": \"function\",\n\t\t\t\t\t\t\t\t\"modifiers\": [],\n\t\t\t\t\t\t\t\t\"name\": \"f\",\n\t\t\t\t\t\t\t\t\"nameLocation\": \"81:1:0\",\n\t\t\t\t\t\t\t\t\"nodeType\": \"FunctionDefinition\",\n\t\t\t\t\t\t\t\t\"parameters\": {\n\t\t\t\t\t\t\t\t\t\"id\": 2,\n\t\t\t\t\t\t\t\t\t\"nodeType\": \"ParameterList\",\n\t\t\t\t\t\t\t\t\t\"parameters\": [],\n\t\t\t\t\t\t\t\t\t\"src\": \"82:2:0\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"returnParameters\": {\n\t\t\t\t\t\t\t\t\t\"id\": 3,\n\t\t\t\t\t\t\t\t\t\"nodeType\": \"ParameterList\",\n\t\t\t\t\t\t\t\t\t\"parameters\": [],\n\t\t\t\t\t\t\t\t\t\"src\": \"97:0:0\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"scope\": 6,\n\t\t\t\t\t\t\t\t\"src\": \"72:27:0\",\n\t\t\t\t\t\t\t\t\"stateMutability\": \"pure\",\n\t\t\t\t\t\t\t\t\"virtual\": false,\n\t\t\t\t\t\t\t\t\"visibility\": \"public\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"scope\": 7,\n\t\t\t\t\t\t\"src\": \"59:42:0\",\n\t\t\t\t\t\t\"usedErrors\": []\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"src\": \"36:65:0\"\n\t\t\t},\n\t\t\t\"id\": 0\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"\": [\"ast\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_with_comments_simple/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"ast\": {\n                \"absolutePath\": \"A\",\n                \"exportedSymbols\": {\n                    \"C\": [\n                        6\n                    ]\n                },\n                \"id\": 7,\n                \"license\": \"GPL-3.0\",\n                \"nodeType\": \"SourceUnit\",\n                \"nodes\": [\n                    {\n                        \"id\": 1,\n                        \"literals\": [\n                            \"solidity\",\n                            \">=\",\n                            \"0.0\"\n                        ],\n                        \"nodeType\": \"PragmaDirective\",\n                        \"src\": \"36:22:0\"\n                    },\n                    {\n                        \"abstract\": false,\n                        \"baseContracts\": [],\n                        \"canonicalName\": \"C\",\n                        \"contractDependencies\": [],\n                        \"contractKind\": \"contract\",\n                        \"fullyImplemented\": true,\n                        \"id\": 6,\n                        \"linearizedBaseContracts\": [\n                            6\n                        ],\n                        \"name\": \"C\",\n                        \"nameLocation\": \"68:1:0\",\n                        \"nodeType\": \"ContractDefinition\",\n                        \"nodes\": [\n                            {\n                                \"body\": {\n                                    \"id\": 4,\n                                    \"nodeType\": \"Block\",\n                                    \"src\": \"97:2:0\",\n                                    \"statements\": []\n                                },\n                                \"functionSelector\": \"26121ff0\",\n                                \"id\": 5,\n                                \"implemented\": true,\n                                \"kind\": \"function\",\n                                \"modifiers\": [],\n                                \"name\": \"f\",\n                                \"nameLocation\": \"81:1:0\",\n                                \"nodeType\": \"FunctionDefinition\",\n                                \"parameters\": {\n                                    \"id\": 2,\n                                    \"nodeType\": \"ParameterList\",\n                                    \"parameters\": [],\n                                    \"src\": \"82:2:0\"\n                                },\n                                \"returnParameters\": {\n                                    \"id\": 3,\n                                    \"nodeType\": \"ParameterList\",\n                                    \"parameters\": [],\n                                    \"src\": \"97:0:0\"\n                                },\n                                \"scope\": 6,\n                                \"src\": \"72:27:0\",\n                                \"stateMutability\": \"pure\",\n                                \"virtual\": false,\n                                \"visibility\": \"public\"\n                            }\n                        ],\n                        \"scope\": 7,\n                        \"src\": \"59:42:0\",\n                        \"usedErrors\": [],\n                        \"usedEvents\": []\n                    }\n                ],\n                \"src\": \"36:65:0\"\n            },\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_with_invalid_utf8/input.json",
    "content": "{\n\t\"language\": \"EVMAssembly\",\n\t\"sources\": {\n\t\t\"A\": {\n\t\t\t\"assemblyJson\": {\n\t\t\t\t\".code\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"begin\": 36,\n\t\t\t\t\t\t\"end\": 51,\n\t\t\t\t\t\t\"name\": \"PUSH\",\n\t\t\t\t\t\t\"source\": 0,\n\t\t\t\t\t\t\"value\": \"\\ud800\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"sourceList\": [\n\t\t\t\t\t\"<stdin>\"\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"\": [\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_import_with_invalid_utf8/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"parse error at line 12, column 23: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\\\"\\\\ud800\\\"'\",\n            \"message\": \"parse error at line 12, column 23: syntax error while parsing value - invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF; last read: '\\\"\\\\ud800\\\"'\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_no_optimize_yul/args",
    "content": "--no-optimize-yul\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_no_optimize_yul/err",
    "content": "Error: Option --no-optimize-yul is only valid in compiler and assembler modes.\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_no_optimize_yul/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_no_optimize_yul/input.json",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize/args",
    "content": "--optimize\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize/err",
    "content": "Error: Option --optimize is only valid in compiler and assembler modes.\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize/input.json",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize_runs/args",
    "content": "--optimize-runs 1000\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize_runs/err",
    "content": "Error: Option --optimize-runs is only valid in compiler and assembler modes.\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize_runs/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize_runs/input.json",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize_yul/args",
    "content": "--optimize-yul\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize_yul/err",
    "content": "Error: Option --optimize-yul is only valid in compiler and assembler modes.\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize_yul/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_optimize_yul/input.json",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_yul_optimizations/args",
    "content": "--yul-optimizations a\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_yul_optimizations/err",
    "content": "Error: Option --yul-optimizations is only valid in compiler and assembler modes.\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_yul_optimizations/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/standard_invalid_option_yul_optimizations/input.json",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_irOptimized_ast_requested/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/standard_irOptimized_ast_requested/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\"*\": {\"*\": [\"irOptimizedAst\"]}}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_irOptimized_ast_requested/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"irOptimizedAst\": {\n                    \"code\": {\n                        \"block\": {\n                            \"nativeSrc\": \"43:639:0\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"-1:-1:0\",\n                            \"statements\": [\n                                {\n                                    \"nativeSrc\": \"53:421:0\",\n                                    \"nodeType\": \"YulBlock\",\n                                    \"src\": \"-1:-1:0\",\n                                    \"statements\": [\n                                        {\n                                            \"expression\": {\n                                                \"arguments\": [\n                                                    {\n                                                        \"kind\": \"number\",\n                                                        \"nativeSrc\": \"120:2:0\",\n                                                        \"nodeType\": \"YulLiteral\",\n                                                        \"src\": \"56:13:0\",\n                                                        \"type\": \"\",\n                                                        \"value\": \"64\"\n                                                    },\n                                                    {\n                                                        \"arguments\": [\n                                                            {\n                                                                \"kind\": \"number\",\n                                                                \"nativeSrc\": \"136:4:0\",\n                                                                \"nodeType\": \"YulLiteral\",\n                                                                \"src\": \"56:13:0\",\n                                                                \"type\": \"\",\n                                                                \"value\": \"0x80\"\n                                                            }\n                                                        ],\n                                                        \"functionName\": {\n                                                            \"name\": \"memoryguard\",\n                                                            \"nativeSrc\": \"124:11:0\",\n                                                            \"nodeType\": \"YulIdentifier\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"nativeSrc\": \"124:17:0\",\n                                                        \"nodeType\": \"YulFunctionCall\",\n                                                        \"src\": \"56:13:0\"\n                                                    }\n                                                ],\n                                                \"functionName\": {\n                                                    \"name\": \"mstore\",\n                                                    \"nativeSrc\": \"113:6:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"113:29:0\",\n                                                \"nodeType\": \"YulFunctionCall\",\n                                                \"src\": \"56:13:0\"\n                                            },\n                                            \"nativeSrc\": \"113:29:0\",\n                                            \"nodeType\": \"YulExpressionStatement\",\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"182:111:0\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"56:13:0\",\n                                                \"statements\": [\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [],\n                                                            \"functionName\": {\n                                                                \"name\": \"revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb\",\n                                                                \"nativeSrc\": \"200:77:0\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"56:13:0\"\n                                                            },\n                                                            \"nativeSrc\": \"200:79:0\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"nativeSrc\": \"200:79:0\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"56:13:0\"\n                                                    }\n                                                ]\n                                            },\n                                            \"condition\": {\n                                                \"arguments\": [],\n                                                \"functionName\": {\n                                                    \"name\": \"callvalue\",\n                                                    \"nativeSrc\": \"158:9:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"158:11:0\",\n                                                \"nodeType\": \"YulFunctionCall\",\n                                                \"src\": \"56:13:0\"\n                                            },\n                                            \"nativeSrc\": \"155:138:0\",\n                                            \"nodeType\": \"YulIf\",\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        {\n                                            \"nativeSrc\": \"306:30:0\",\n                                            \"nodeType\": \"YulVariableDeclaration\",\n                                            \"src\": \"56:13:0\",\n                                            \"value\": {\n                                                \"arguments\": [],\n                                                \"functionName\": {\n                                                    \"name\": \"allocate_unbounded\",\n                                                    \"nativeSrc\": \"316:18:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"316:20:0\",\n                                                \"nodeType\": \"YulFunctionCall\",\n                                                \"src\": \"56:13:0\"\n                                            },\n                                            \"variables\": [\n                                                {\n                                                    \"name\": \"_1\",\n                                                    \"nativeSrc\": \"310:2:0\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"56:13:0\",\n                                                    \"type\": \"\"\n                                                }\n                                            ]\n                                        },\n                                        {\n                                            \"expression\": {\n                                                \"arguments\": [\n                                                    {\n                                                        \"name\": \"_1\",\n                                                        \"nativeSrc\": \"358:2:0\",\n                                                        \"nodeType\": \"YulIdentifier\",\n                                                        \"src\": \"56:13:0\"\n                                                    },\n                                                    {\n                                                        \"arguments\": [\n                                                            {\n                                                                \"hexValue\": \"435f325f6465706c6f796564\",\n                                                                \"kind\": \"string\",\n                                                                \"nativeSrc\": \"373:14:0\",\n                                                                \"nodeType\": \"YulLiteral\",\n                                                                \"src\": \"56:13:0\",\n                                                                \"type\": \"\",\n                                                                \"value\": \"C_2_deployed\"\n                                                            }\n                                                        ],\n                                                        \"functionName\": {\n                                                            \"name\": \"dataoffset\",\n                                                            \"nativeSrc\": \"362:10:0\",\n                                                            \"nodeType\": \"YulIdentifier\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"nativeSrc\": \"362:26:0\",\n                                                        \"nodeType\": \"YulFunctionCall\",\n                                                        \"src\": \"56:13:0\"\n                                                    },\n                                                    {\n                                                        \"arguments\": [\n                                                            {\n                                                                \"hexValue\": \"435f325f6465706c6f796564\",\n                                                                \"kind\": \"string\",\n                                                                \"nativeSrc\": \"399:14:0\",\n                                                                \"nodeType\": \"YulLiteral\",\n                                                                \"src\": \"56:13:0\",\n                                                                \"type\": \"\",\n                                                                \"value\": \"C_2_deployed\"\n                                                            }\n                                                        ],\n                                                        \"functionName\": {\n                                                            \"name\": \"datasize\",\n                                                            \"nativeSrc\": \"390:8:0\",\n                                                            \"nodeType\": \"YulIdentifier\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"nativeSrc\": \"390:24:0\",\n                                                        \"nodeType\": \"YulFunctionCall\",\n                                                        \"src\": \"56:13:0\"\n                                                    }\n                                                ],\n                                                \"functionName\": {\n                                                    \"name\": \"codecopy\",\n                                                    \"nativeSrc\": \"349:8:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"349:66:0\",\n                                                \"nodeType\": \"YulFunctionCall\",\n                                                \"src\": \"56:13:0\"\n                                            },\n                                            \"nativeSrc\": \"349:66:0\",\n                                            \"nodeType\": \"YulExpressionStatement\",\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        {\n                                            \"expression\": {\n                                                \"arguments\": [\n                                                    {\n                                                        \"name\": \"_1\",\n                                                        \"nativeSrc\": \"435:2:0\",\n                                                        \"nodeType\": \"YulIdentifier\",\n                                                        \"src\": \"56:13:0\"\n                                                    },\n                                                    {\n                                                        \"arguments\": [\n                                                            {\n                                                                \"hexValue\": \"435f325f6465706c6f796564\",\n                                                                \"kind\": \"string\",\n                                                                \"nativeSrc\": \"448:14:0\",\n                                                                \"nodeType\": \"YulLiteral\",\n                                                                \"src\": \"56:13:0\",\n                                                                \"type\": \"\",\n                                                                \"value\": \"C_2_deployed\"\n                                                            }\n                                                        ],\n                                                        \"functionName\": {\n                                                            \"name\": \"datasize\",\n                                                            \"nativeSrc\": \"439:8:0\",\n                                                            \"nodeType\": \"YulIdentifier\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"nativeSrc\": \"439:24:0\",\n                                                        \"nodeType\": \"YulFunctionCall\",\n                                                        \"src\": \"56:13:0\"\n                                                    }\n                                                ],\n                                                \"functionName\": {\n                                                    \"name\": \"return\",\n                                                    \"nativeSrc\": \"428:6:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"428:36:0\",\n                                                \"nodeType\": \"YulFunctionCall\",\n                                                \"src\": \"56:13:0\"\n                                            },\n                                            \"nativeSrc\": \"428:36:0\",\n                                            \"nodeType\": \"YulExpressionStatement\",\n                                            \"src\": \"56:13:0\"\n                                        }\n                                    ]\n                                },\n                                {\n                                    \"body\": {\n                                        \"nativeSrc\": \"531:23:0\",\n                                        \"nodeType\": \"YulBlock\",\n                                        \"src\": \"56:13:0\",\n                                        \"statements\": [\n                                            {\n                                                \"nativeSrc\": \"533:19:0\",\n                                                \"nodeType\": \"YulAssignment\",\n                                                \"src\": \"56:13:0\",\n                                                \"value\": {\n                                                    \"arguments\": [\n                                                        {\n                                                            \"kind\": \"number\",\n                                                            \"nativeSrc\": \"549:2:0\",\n                                                            \"nodeType\": \"YulLiteral\",\n                                                            \"src\": \"56:13:0\",\n                                                            \"type\": \"\",\n                                                            \"value\": \"64\"\n                                                        }\n                                                    ],\n                                                    \"functionName\": {\n                                                        \"name\": \"mload\",\n                                                        \"nativeSrc\": \"543:5:0\",\n                                                        \"nodeType\": \"YulIdentifier\",\n                                                        \"src\": \"56:13:0\"\n                                                    },\n                                                    \"nativeSrc\": \"543:9:0\",\n                                                    \"nodeType\": \"YulFunctionCall\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"variableNames\": [\n                                                    {\n                                                        \"name\": \"memPtr\",\n                                                        \"nativeSrc\": \"533:6:0\",\n                                                        \"nodeType\": \"YulIdentifier\",\n                                                        \"src\": \"56:13:0\"\n                                                    }\n                                                ]\n                                            }\n                                        ]\n                                    },\n                                    \"name\": \"allocate_unbounded\",\n                                    \"nativeSrc\": \"483:71:0\",\n                                    \"nodeType\": \"YulFunctionDefinition\",\n                                    \"returnVariables\": [\n                                        {\n                                            \"name\": \"memPtr\",\n                                            \"nativeSrc\": \"516:6:0\",\n                                            \"nodeType\": \"YulTypedName\",\n                                            \"src\": \"56:13:0\",\n                                            \"type\": \"\"\n                                        }\n                                    ],\n                                    \"src\": \"56:13:0\"\n                                },\n                                {\n                                    \"body\": {\n                                        \"nativeSrc\": \"660:16:0\",\n                                        \"nodeType\": \"YulBlock\",\n                                        \"src\": \"56:13:0\",\n                                        \"statements\": [\n                                            {\n                                                \"expression\": {\n                                                    \"arguments\": [\n                                                        {\n                                                            \"kind\": \"number\",\n                                                            \"nativeSrc\": \"669:1:0\",\n                                                            \"nodeType\": \"YulLiteral\",\n                                                            \"src\": \"56:13:0\",\n                                                            \"type\": \"\",\n                                                            \"value\": \"0\"\n                                                        },\n                                                        {\n                                                            \"kind\": \"number\",\n                                                            \"nativeSrc\": \"672:1:0\",\n                                                            \"nodeType\": \"YulLiteral\",\n                                                            \"src\": \"56:13:0\",\n                                                            \"type\": \"\",\n                                                            \"value\": \"0\"\n                                                        }\n                                                    ],\n                                                    \"functionName\": {\n                                                        \"name\": \"revert\",\n                                                        \"nativeSrc\": \"662:6:0\",\n                                                        \"nodeType\": \"YulIdentifier\",\n                                                        \"src\": \"56:13:0\"\n                                                    },\n                                                    \"nativeSrc\": \"662:12:0\",\n                                                    \"nodeType\": \"YulFunctionCall\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"662:12:0\",\n                                                \"nodeType\": \"YulExpressionStatement\",\n                                                \"src\": \"56:13:0\"\n                                            }\n                                        ]\n                                    },\n                                    \"name\": \"revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb\",\n                                    \"nativeSrc\": \"563:113:0\",\n                                    \"nodeType\": \"YulFunctionDefinition\",\n                                    \"src\": \"56:13:0\"\n                                }\n                            ]\n                        },\n                        \"nodeType\": \"YulCode\"\n                    },\n                    \"name\": \"C_2\",\n                    \"nodeType\": \"YulObject\",\n                    \"subObjects\": [\n                        {\n                            \"code\": {\n                                \"block\": {\n                                    \"nativeSrc\": \"747:361:0\",\n                                    \"nodeType\": \"YulBlock\",\n                                    \"src\": \"-1:-1:0\",\n                                    \"statements\": [\n                                        {\n                                            \"nativeSrc\": \"761:207:0\",\n                                            \"nodeType\": \"YulBlock\",\n                                            \"src\": \"-1:-1:0\",\n                                            \"statements\": [\n                                                {\n                                                    \"expression\": {\n                                                        \"arguments\": [\n                                                            {\n                                                                \"kind\": \"number\",\n                                                                \"nativeSrc\": \"836:2:0\",\n                                                                \"nodeType\": \"YulLiteral\",\n                                                                \"src\": \"56:13:0\",\n                                                                \"type\": \"\",\n                                                                \"value\": \"64\"\n                                                            },\n                                                            {\n                                                                \"arguments\": [\n                                                                    {\n                                                                        \"kind\": \"number\",\n                                                                        \"nativeSrc\": \"852:4:0\",\n                                                                        \"nodeType\": \"YulLiteral\",\n                                                                        \"src\": \"56:13:0\",\n                                                                        \"type\": \"\",\n                                                                        \"value\": \"0x80\"\n                                                                    }\n                                                                ],\n                                                                \"functionName\": {\n                                                                    \"name\": \"memoryguard\",\n                                                                    \"nativeSrc\": \"840:11:0\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"56:13:0\"\n                                                                },\n                                                                \"nativeSrc\": \"840:17:0\",\n                                                                \"nodeType\": \"YulFunctionCall\",\n                                                                \"src\": \"56:13:0\"\n                                                            }\n                                                        ],\n                                                        \"functionName\": {\n                                                            \"name\": \"mstore\",\n                                                            \"nativeSrc\": \"829:6:0\",\n                                                            \"nodeType\": \"YulIdentifier\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"nativeSrc\": \"829:29:0\",\n                                                        \"nodeType\": \"YulFunctionCall\",\n                                                        \"src\": \"56:13:0\"\n                                                    },\n                                                    \"nativeSrc\": \"829:29:0\",\n                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                {\n                                                    \"expression\": {\n                                                        \"arguments\": [],\n                                                        \"functionName\": {\n                                                            \"name\": \"revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74\",\n                                                            \"nativeSrc\": \"875:77:0\",\n                                                            \"nodeType\": \"YulIdentifier\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"nativeSrc\": \"875:79:0\",\n                                                        \"nodeType\": \"YulFunctionCall\",\n                                                        \"src\": \"56:13:0\"\n                                                    },\n                                                    \"nativeSrc\": \"875:79:0\",\n                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                    \"src\": \"56:13:0\"\n                                                }\n                                            ]\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"1082:16:0\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"56:13:0\",\n                                                \"statements\": [\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1091:1:0\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"56:13:0\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1094:1:0\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"56:13:0\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"revert\",\n                                                                \"nativeSrc\": \"1084:6:0\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"56:13:0\"\n                                                            },\n                                                            \"nativeSrc\": \"1084:12:0\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"nativeSrc\": \"1084:12:0\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"56:13:0\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74\",\n                                            \"nativeSrc\": \"981:117:0\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"src\": \"56:13:0\"\n                                        }\n                                    ]\n                                },\n                                \"nodeType\": \"YulCode\"\n                            },\n                            \"name\": \"C_2_deployed\",\n                            \"nodeType\": \"YulObject\",\n                            \"subObjects\": [\n                                {\n                                    \"nodeType\": \"YulData\",\n                                    \"value\": \"<BYTECODE REMOVED>\"\n                                }\n                            ]\n                        }\n                    ]\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_irOptimized_requested/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"irOptimized\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_irOptimized_requested/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"irOptimized\": \"/// @use-src 0:\\\"A\\\"\nobject \\\"C_7\\\" {\n    code {\n        {\n            /// @src 0:79:121  \\\"contract C { function f() public pure {} }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"C_7_deployed\\\"), datasize(\\\"C_7_deployed\\\"))\n            return(_1, datasize(\\\"C_7_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\\\"A\\\"\n    object \\\"C_7_deployed\\\" {\n        code {\n            {\n                /// @src 0:79:121  \\\"contract C { function f() public pure {} }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0x26121ff0 { external_fun_f() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function abi_decode(headStart, dataEnd)\n            {\n                if slt(sub(dataEnd, headStart), 0)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_f()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                abi_decode(4, calldatasize())\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_ir_ast_requested/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/standard_ir_ast_requested/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\"*\": {\"*\": [\"irAst\"]}}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_ir_ast_requested/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"irAst\": {\n                    \"code\": {\n                        \"block\": {\n                            \"nativeSrc\": \"44:790:0\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"-1:-1:0\",\n                            \"statements\": [\n                                {\n                                    \"expression\": {\n                                        \"arguments\": [\n                                            {\n                                                \"kind\": \"number\",\n                                                \"nativeSrc\": \"103:2:0\",\n                                                \"nodeType\": \"YulLiteral\",\n                                                \"src\": \"56:13:0\",\n                                                \"type\": \"\",\n                                                \"value\": \"64\"\n                                            },\n                                            {\n                                                \"arguments\": [\n                                                    {\n                                                        \"kind\": \"number\",\n                                                        \"nativeSrc\": \"119:3:0\",\n                                                        \"nodeType\": \"YulLiteral\",\n                                                        \"src\": \"56:13:0\",\n                                                        \"type\": \"\",\n                                                        \"value\": \"128\"\n                                                    }\n                                                ],\n                                                \"functionName\": {\n                                                    \"name\": \"memoryguard\",\n                                                    \"nativeSrc\": \"107:11:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"107:16:0\",\n                                                \"nodeType\": \"YulFunctionCall\",\n                                                \"src\": \"56:13:0\"\n                                            }\n                                        ],\n                                        \"functionName\": {\n                                            \"name\": \"mstore\",\n                                            \"nativeSrc\": \"96:6:0\",\n                                            \"nodeType\": \"YulIdentifier\",\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        \"nativeSrc\": \"96:28:0\",\n                                        \"nodeType\": \"YulFunctionCall\",\n                                        \"src\": \"56:13:0\"\n                                    },\n                                    \"nativeSrc\": \"96:28:0\",\n                                    \"nodeType\": \"YulExpressionStatement\",\n                                    \"src\": \"56:13:0\"\n                                },\n                                {\n                                    \"body\": {\n                                        \"nativeSrc\": \"148:83:0\",\n                                        \"nodeType\": \"YulBlock\",\n                                        \"src\": \"56:13:0\",\n                                        \"statements\": [\n                                            {\n                                                \"expression\": {\n                                                    \"arguments\": [],\n                                                    \"functionName\": {\n                                                        \"name\": \"revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb\",\n                                                        \"nativeSrc\": \"150:77:0\",\n                                                        \"nodeType\": \"YulIdentifier\",\n                                                        \"src\": \"56:13:0\"\n                                                    },\n                                                    \"nativeSrc\": \"150:79:0\",\n                                                    \"nodeType\": \"YulFunctionCall\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"150:79:0\",\n                                                \"nodeType\": \"YulExpressionStatement\",\n                                                \"src\": \"56:13:0\"\n                                            }\n                                        ]\n                                    },\n                                    \"condition\": {\n                                        \"arguments\": [],\n                                        \"functionName\": {\n                                            \"name\": \"callvalue\",\n                                            \"nativeSrc\": \"136:9:0\",\n                                            \"nodeType\": \"YulIdentifier\",\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        \"nativeSrc\": \"136:11:0\",\n                                        \"nodeType\": \"YulFunctionCall\",\n                                        \"src\": \"56:13:0\"\n                                    },\n                                    \"nativeSrc\": \"133:98:0\",\n                                    \"nodeType\": \"YulIf\",\n                                    \"src\": \"56:13:0\"\n                                },\n                                {\n                                    \"expression\": {\n                                        \"arguments\": [],\n                                        \"functionName\": {\n                                            \"name\": \"constructor_C_2\",\n                                            \"nativeSrc\": \"241:15:0\",\n                                            \"nodeType\": \"YulIdentifier\",\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        \"nativeSrc\": \"241:17:0\",\n                                        \"nodeType\": \"YulFunctionCall\",\n                                        \"src\": \"56:13:0\"\n                                    },\n                                    \"nativeSrc\": \"241:17:0\",\n                                    \"nodeType\": \"YulExpressionStatement\",\n                                    \"src\": \"56:13:0\"\n                                },\n                                {\n                                    \"nativeSrc\": \"268:30:0\",\n                                    \"nodeType\": \"YulVariableDeclaration\",\n                                    \"src\": \"56:13:0\",\n                                    \"value\": {\n                                        \"arguments\": [],\n                                        \"functionName\": {\n                                            \"name\": \"allocate_unbounded\",\n                                            \"nativeSrc\": \"278:18:0\",\n                                            \"nodeType\": \"YulIdentifier\",\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        \"nativeSrc\": \"278:20:0\",\n                                        \"nodeType\": \"YulFunctionCall\",\n                                        \"src\": \"56:13:0\"\n                                    },\n                                    \"variables\": [\n                                        {\n                                            \"name\": \"_1\",\n                                            \"nativeSrc\": \"272:2:0\",\n                                            \"nodeType\": \"YulTypedName\",\n                                            \"src\": \"56:13:0\",\n                                            \"type\": \"\"\n                                        }\n                                    ]\n                                },\n                                {\n                                    \"expression\": {\n                                        \"arguments\": [\n                                            {\n                                                \"name\": \"_1\",\n                                                \"nativeSrc\": \"316:2:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"56:13:0\"\n                                            },\n                                            {\n                                                \"arguments\": [\n                                                    {\n                                                        \"hexValue\": \"435f325f6465706c6f796564\",\n                                                        \"kind\": \"string\",\n                                                        \"nativeSrc\": \"331:14:0\",\n                                                        \"nodeType\": \"YulLiteral\",\n                                                        \"src\": \"56:13:0\",\n                                                        \"type\": \"\",\n                                                        \"value\": \"C_2_deployed\"\n                                                    }\n                                                ],\n                                                \"functionName\": {\n                                                    \"name\": \"dataoffset\",\n                                                    \"nativeSrc\": \"320:10:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"320:26:0\",\n                                                \"nodeType\": \"YulFunctionCall\",\n                                                \"src\": \"56:13:0\"\n                                            },\n                                            {\n                                                \"arguments\": [\n                                                    {\n                                                        \"hexValue\": \"435f325f6465706c6f796564\",\n                                                        \"kind\": \"string\",\n                                                        \"nativeSrc\": \"357:14:0\",\n                                                        \"nodeType\": \"YulLiteral\",\n                                                        \"src\": \"56:13:0\",\n                                                        \"type\": \"\",\n                                                        \"value\": \"C_2_deployed\"\n                                                    }\n                                                ],\n                                                \"functionName\": {\n                                                    \"name\": \"datasize\",\n                                                    \"nativeSrc\": \"348:8:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"348:24:0\",\n                                                \"nodeType\": \"YulFunctionCall\",\n                                                \"src\": \"56:13:0\"\n                                            }\n                                        ],\n                                        \"functionName\": {\n                                            \"name\": \"codecopy\",\n                                            \"nativeSrc\": \"307:8:0\",\n                                            \"nodeType\": \"YulIdentifier\",\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        \"nativeSrc\": \"307:66:0\",\n                                        \"nodeType\": \"YulFunctionCall\",\n                                        \"src\": \"56:13:0\"\n                                    },\n                                    \"nativeSrc\": \"307:66:0\",\n                                    \"nodeType\": \"YulExpressionStatement\",\n                                    \"src\": \"56:13:0\"\n                                },\n                                {\n                                    \"expression\": {\n                                        \"arguments\": [\n                                            {\n                                                \"name\": \"_1\",\n                                                \"nativeSrc\": \"390:2:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"56:13:0\"\n                                            },\n                                            {\n                                                \"arguments\": [\n                                                    {\n                                                        \"hexValue\": \"435f325f6465706c6f796564\",\n                                                        \"kind\": \"string\",\n                                                        \"nativeSrc\": \"403:14:0\",\n                                                        \"nodeType\": \"YulLiteral\",\n                                                        \"src\": \"56:13:0\",\n                                                        \"type\": \"\",\n                                                        \"value\": \"C_2_deployed\"\n                                                    }\n                                                ],\n                                                \"functionName\": {\n                                                    \"name\": \"datasize\",\n                                                    \"nativeSrc\": \"394:8:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"394:24:0\",\n                                                \"nodeType\": \"YulFunctionCall\",\n                                                \"src\": \"56:13:0\"\n                                            }\n                                        ],\n                                        \"functionName\": {\n                                            \"name\": \"return\",\n                                            \"nativeSrc\": \"383:6:0\",\n                                            \"nodeType\": \"YulIdentifier\",\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        \"nativeSrc\": \"383:36:0\",\n                                        \"nodeType\": \"YulFunctionCall\",\n                                        \"src\": \"56:13:0\"\n                                    },\n                                    \"nativeSrc\": \"383:36:0\",\n                                    \"nodeType\": \"YulExpressionStatement\",\n                                    \"src\": \"56:13:0\"\n                                },\n                                {\n                                    \"body\": {\n                                        \"nativeSrc\": \"469:43:0\",\n                                        \"nodeType\": \"YulBlock\",\n                                        \"src\": \"56:13:0\",\n                                        \"statements\": [\n                                            {\n                                                \"nativeSrc\": \"483:19:0\",\n                                                \"nodeType\": \"YulAssignment\",\n                                                \"src\": \"56:13:0\",\n                                                \"value\": {\n                                                    \"arguments\": [\n                                                        {\n                                                            \"kind\": \"number\",\n                                                            \"nativeSrc\": \"499:2:0\",\n                                                            \"nodeType\": \"YulLiteral\",\n                                                            \"src\": \"56:13:0\",\n                                                            \"type\": \"\",\n                                                            \"value\": \"64\"\n                                                        }\n                                                    ],\n                                                    \"functionName\": {\n                                                        \"name\": \"mload\",\n                                                        \"nativeSrc\": \"493:5:0\",\n                                                        \"nodeType\": \"YulIdentifier\",\n                                                        \"src\": \"56:13:0\"\n                                                    },\n                                                    \"nativeSrc\": \"493:9:0\",\n                                                    \"nodeType\": \"YulFunctionCall\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"variableNames\": [\n                                                    {\n                                                        \"name\": \"memPtr\",\n                                                        \"nativeSrc\": \"483:6:0\",\n                                                        \"nodeType\": \"YulIdentifier\",\n                                                        \"src\": \"56:13:0\"\n                                                    }\n                                                ]\n                                            }\n                                        ]\n                                    },\n                                    \"name\": \"allocate_unbounded\",\n                                    \"nativeSrc\": \"429:83:0\",\n                                    \"nodeType\": \"YulFunctionDefinition\",\n                                    \"returnVariables\": [\n                                        {\n                                            \"name\": \"memPtr\",\n                                            \"nativeSrc\": \"462:6:0\",\n                                            \"nodeType\": \"YulTypedName\",\n                                            \"src\": \"56:13:0\",\n                                            \"type\": \"\"\n                                        }\n                                    ],\n                                    \"src\": \"56:13:0\"\n                                },\n                                {\n                                    \"body\": {\n                                        \"nativeSrc\": \"611:36:0\",\n                                        \"nodeType\": \"YulBlock\",\n                                        \"src\": \"56:13:0\",\n                                        \"statements\": [\n                                            {\n                                                \"expression\": {\n                                                    \"arguments\": [\n                                                        {\n                                                            \"kind\": \"number\",\n                                                            \"nativeSrc\": \"632:1:0\",\n                                                            \"nodeType\": \"YulLiteral\",\n                                                            \"src\": \"56:13:0\",\n                                                            \"type\": \"\",\n                                                            \"value\": \"0\"\n                                                        },\n                                                        {\n                                                            \"kind\": \"number\",\n                                                            \"nativeSrc\": \"635:1:0\",\n                                                            \"nodeType\": \"YulLiteral\",\n                                                            \"src\": \"56:13:0\",\n                                                            \"type\": \"\",\n                                                            \"value\": \"0\"\n                                                        }\n                                                    ],\n                                                    \"functionName\": {\n                                                        \"name\": \"revert\",\n                                                        \"nativeSrc\": \"625:6:0\",\n                                                        \"nodeType\": \"YulIdentifier\",\n                                                        \"src\": \"56:13:0\"\n                                                    },\n                                                    \"nativeSrc\": \"625:12:0\",\n                                                    \"nodeType\": \"YulFunctionCall\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"625:12:0\",\n                                                \"nodeType\": \"YulExpressionStatement\",\n                                                \"src\": \"56:13:0\"\n                                            }\n                                        ]\n                                    },\n                                    \"name\": \"revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb\",\n                                    \"nativeSrc\": \"522:125:0\",\n                                    \"nodeType\": \"YulFunctionDefinition\",\n                                    \"src\": \"56:13:0\"\n                                },\n                                {\n                                    \"body\": {\n                                        \"nativeSrc\": \"726:59:0\",\n                                        \"nodeType\": \"YulBlock\",\n                                        \"src\": \"56:13:0\",\n                                        \"statements\": []\n                                    },\n                                    \"name\": \"constructor_C_2\",\n                                    \"nativeSrc\": \"699:86:0\",\n                                    \"nodeType\": \"YulFunctionDefinition\",\n                                    \"src\": \"56:13:0\"\n                                }\n                            ]\n                        },\n                        \"nodeType\": \"YulCode\"\n                    },\n                    \"name\": \"C_2\",\n                    \"nodeType\": \"YulObject\",\n                    \"subObjects\": [\n                        {\n                            \"code\": {\n                                \"block\": {\n                                    \"nativeSrc\": \"899:588:0\",\n                                    \"nodeType\": \"YulBlock\",\n                                    \"src\": \"-1:-1:0\",\n                                    \"statements\": [\n                                        {\n                                            \"expression\": {\n                                                \"arguments\": [\n                                                    {\n                                                        \"kind\": \"number\",\n                                                        \"nativeSrc\": \"966:2:0\",\n                                                        \"nodeType\": \"YulLiteral\",\n                                                        \"src\": \"56:13:0\",\n                                                        \"type\": \"\",\n                                                        \"value\": \"64\"\n                                                    },\n                                                    {\n                                                        \"arguments\": [\n                                                            {\n                                                                \"kind\": \"number\",\n                                                                \"nativeSrc\": \"982:3:0\",\n                                                                \"nodeType\": \"YulLiteral\",\n                                                                \"src\": \"56:13:0\",\n                                                                \"type\": \"\",\n                                                                \"value\": \"128\"\n                                                            }\n                                                        ],\n                                                        \"functionName\": {\n                                                            \"name\": \"memoryguard\",\n                                                            \"nativeSrc\": \"970:11:0\",\n                                                            \"nodeType\": \"YulIdentifier\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"nativeSrc\": \"970:16:0\",\n                                                        \"nodeType\": \"YulFunctionCall\",\n                                                        \"src\": \"56:13:0\"\n                                                    }\n                                                ],\n                                                \"functionName\": {\n                                                    \"name\": \"mstore\",\n                                                    \"nativeSrc\": \"959:6:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"959:28:0\",\n                                                \"nodeType\": \"YulFunctionCall\",\n                                                \"src\": \"56:13:0\"\n                                            },\n                                            \"nativeSrc\": \"959:28:0\",\n                                            \"nodeType\": \"YulExpressionStatement\",\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        {\n                                            \"expression\": {\n                                                \"arguments\": [],\n                                                \"functionName\": {\n                                                    \"name\": \"revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74\",\n                                                    \"nativeSrc\": \"1001:77:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"56:13:0\"\n                                                },\n                                                \"nativeSrc\": \"1001:79:0\",\n                                                \"nodeType\": \"YulFunctionCall\",\n                                                \"src\": \"56:13:0\"\n                                            },\n                                            \"nativeSrc\": \"1001:79:0\",\n                                            \"nodeType\": \"YulExpressionStatement\",\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"1147:77:0\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"56:13:0\",\n                                                \"statements\": [\n                                                    {\n                                                        \"nativeSrc\": \"1165:44:0\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"56:13:0\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1198:3:0\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"56:13:0\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"224\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"value\",\n                                                                    \"nativeSrc\": \"1203:5:0\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"56:13:0\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"shr\",\n                                                                \"nativeSrc\": \"1194:3:0\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"56:13:0\"\n                                                            },\n                                                            \"nativeSrc\": \"1194:15:0\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"newValue\",\n                                                                \"nativeSrc\": \"1165:8:0\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"56:13:0\"\n                                                            }\n                                                        ]\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"shift_right_224_unsigned\",\n                                            \"nativeSrc\": \"1094:130:0\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"value\",\n                                                    \"nativeSrc\": \"1128:5:0\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"56:13:0\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"newValue\",\n                                                    \"nativeSrc\": \"1138:8:0\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"56:13:0\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"1278:51:0\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"56:13:0\",\n                                                \"statements\": [\n                                                    {\n                                                        \"nativeSrc\": \"1296:19:0\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"56:13:0\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1312:2:0\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"56:13:0\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"64\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mload\",\n                                                                \"nativeSrc\": \"1306:5:0\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"56:13:0\"\n                                                            },\n                                                            \"nativeSrc\": \"1306:9:0\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"memPtr\",\n                                                                \"nativeSrc\": \"1296:6:0\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"56:13:0\"\n                                                            }\n                                                        ]\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"allocate_unbounded\",\n                                            \"nativeSrc\": \"1238:91:0\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"memPtr\",\n                                                    \"nativeSrc\": \"1271:6:0\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"56:13:0\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"56:13:0\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"1432:44:0\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"56:13:0\",\n                                                \"statements\": [\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1457:1:0\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"56:13:0\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1460:1:0\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"56:13:0\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"revert\",\n                                                                \"nativeSrc\": \"1450:6:0\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"56:13:0\"\n                                                            },\n                                                            \"nativeSrc\": \"1450:12:0\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"56:13:0\"\n                                                        },\n                                                        \"nativeSrc\": \"1450:12:0\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"56:13:0\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74\",\n                                            \"nativeSrc\": \"1343:133:0\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"src\": \"56:13:0\"\n                                        }\n                                    ]\n                                },\n                                \"nodeType\": \"YulCode\"\n                            },\n                            \"name\": \"C_2_deployed\",\n                            \"nodeType\": \"YulObject\",\n                            \"subObjects\": [\n                                {\n                                    \"nodeType\": \"YulData\",\n                                    \"value\": \"<BYTECODE REMOVED>\"\n                                }\n                            ]\n                        }\n                    ]\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_ir_requested/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"ir\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_ir_requested/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"ir\": \"\n/// @use-src 0:\\\"A\\\"\nobject \\\"C_7\\\" {\n    code {\n        /// @src 0:79:121  \\\"contract C { function f() public pure {} }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_7()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_7_deployed\\\"), datasize(\\\"C_7_deployed\\\"))\n\n        return(_1, datasize(\\\"C_7_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:79:121  \\\"contract C { function f() public pure {} }\\\"\n        function constructor_C_7() {\n\n            /// @src 0:79:121  \\\"contract C { function f() public pure {} }\\\"\n\n        }\n        /// @src 0:79:121  \\\"contract C { function f() public pure {} }\\\"\n\n    }\n    /// @use-src 0:\\\"A\\\"\n    object \\\"C_7_deployed\\\" {\n        code {\n            /// @src 0:79:121  \\\"contract C { function f() public pure {} }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_6()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_6() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                fun_f_6()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            /// @ast-id 6\n            /// @src 0:92:119  \\\"function f() public pure {}\\\"\n            function fun_f_6() {\n\n            }\n            /// @src 0:79:121  \\\"contract C { function f() public pure {} }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_ir_unoptimized_with_optimize/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"C.sol\": {\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity *; contract C {}\"}\n    },\n    \"settings\": {\n        \"outputSelection\": {\"*\": {\"*\": [\"ir\"]}},\n        \"optimizer\": {\"enabled\": true},\n        \"debug\": {\"debugInfo\": []}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_ir_unoptimized_with_optimize/output.json",
    "content": "{\n    \"contracts\": {\n        \"C.sol\": {\n            \"C\": {\n                \"ir\": \"\n/// @use-src 0:\\\"C.sol\\\"\nobject \\\"C_2\\\" {\n    code {\n\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_2()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_2_deployed\\\"), datasize(\\\"C_2_deployed\\\"))\n\n        return(_1, datasize(\\\"C_2_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function constructor_C_2() {\n\n        }\n\n    }\n    /// @use-src 0:\\\"C.sol\\\"\n    object \\\"C_2_deployed\\\" {\n        code {\n\n            mstore(64, memoryguard(128))\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"C.sol\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"C.sol\": {\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity *; contract C {}\"}\n    },\n    \"settings\": {\n        \"outputSelection\": {\"*\": {\"*\": [\"ir\"]}},\n        \"optimizer\": {\"enabled\": true},\n        \"viaIR\": true,\n        \"debug\": {\"debugInfo\": []}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_ir_unoptimized_with_optimize_via_ir/output.json",
    "content": "{\n    \"contracts\": {\n        \"C.sol\": {\n            \"C\": {\n                \"ir\": \"\n/// @use-src 0:\\\"C.sol\\\"\nobject \\\"C_2\\\" {\n    code {\n\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_2()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_2_deployed\\\"), datasize(\\\"C_2_deployed\\\"))\n\n        return(_1, datasize(\\\"C_2_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function constructor_C_2() {\n\n        }\n\n    }\n    /// @use-src 0:\\\"C.sol\\\"\n    object \\\"C_2_deployed\\\" {\n        code {\n\n            mstore(64, memoryguard(128))\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"C.sol\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_json_no_pretty_print/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C {}\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_json_no_pretty_print/no-pretty-print",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_json_no_pretty_print/output.json",
    "content": "{\"sources\":{\"A\":{\"id\":0}}}\n"
  },
  {
    "path": "test/cmdlineTests/standard_metadata/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_metadata/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/standard_metadata/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"metadata\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_metadata/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"metadata\": \"{\\\"compiler\\\":{\\\"version\\\":\\\"<VERSION REMOVED>\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[],\\\"devdoc\\\":{\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"C\\\":\\\"C\\\"},\\\"evmVersion\\\":\\\"osaka\\\",\\\"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}\"\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_metadata_experimental/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_metadata_experimental/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/standard_metadata_experimental/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"viaIR\": true,\n\t\t\"debug\": {\n\t\t\t\"debugInfo\": [\n\t\t\t\t\"ethdebug\"\n\t\t\t]\n\t\t},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"metadata\", \"ir\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_metadata_experimental/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"C\\\"\nobject \\\"C_2\\\" {\n    code {\n        /// @src 0:56:69\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_2()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_2_deployed\\\"), datasize(\\\"C_2_deployed\\\"))\n\n        return(_1, datasize(\\\"C_2_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:56:69\n        function constructor_C_2() {\n\n            /// @src 0:56:69\n\n        }\n        /// @src 0:56:69\n\n    }\n    /// @use-src 0:\\\"C\\\"\n    object \\\"C_2_deployed\\\" {\n        code {\n            /// @src 0:56:69\n            mstore(64, memoryguard(128))\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\",\n                \"metadata\": \"{\\\"compiler\\\":{\\\"version\\\":\\\"<VERSION REMOVED>\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[],\\\"devdoc\\\":{\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"C\\\":\\\"C\\\"},\\\"evmVersion\\\":\\\"osaka\\\",\\\"experimental\\\":true,\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"ipfs\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[],\\\"viaIR\\\":true},\\\"sources\\\":{\\\"C\\\":{\\\"keccak256\\\":\\\"0x5cf617b1707a484e3c4bd59643013dec76ab7d75900b46855214729ae3e0ceb0\\\",\\\"license\\\":\\\"GPL-3.0\\\",\\\"urls\\\":[\\\"bzz-raw://ac418a02dfadf87234150d3568f33269e3f49460345cb39300e017a6d755eff2\\\",\\\"dweb:/ipfs/QmQq3owBu25x2WV46HB1WyKzJpxiAPecU7eMKqtXCF7eeS\\\"]}},\\\"version\\\":1}\"\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_method_identifiers_requested/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"evm.methodIdentifiers\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_method_identifiers_requested/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"evm\": {\n                    \"methodIdentifiers\": {\n                        \"f()\": \"26121ff0\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_method_identifiers_requested_empty/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"evm.methodIdentifiers\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_method_identifiers_requested_empty/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"evm\": {\n                    \"methodIdentifiers\": {}\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_missing_key_useLiteralContent/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true,\n\t\t\t\"runs\": 200\n\t\t},\n\t\t\"evmVersion\": \"byzantium\",\n\t\t\"metadata\": {}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_missing_key_useLiteralContent/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Support for EVM versions older than constantinople is deprecated and will be removed in the future.\",\n            \"message\": \"Support for EVM versions older than constantinople is deprecated and will be removed in the future.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_bmc_loop_iterations/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\tpragma solidity >=0.0;\n\t\t\tcontract C\n\t\t\t{\n\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\trequire(x == 0);\n\t\t\t\t\tdo {\n\t\t\t\t\t\t++x;\n\t\t\t\t\t} while (x < 2);\n\t\t\t\t\tassert(x == 2);\n\t\t\t\t}\n\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n            \"bmcLoopIterations\": 3\n\t\t}\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_bmc_loop_iterations/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"Source\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_bmc_loop_iterations_invalid_arg/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\tpragma solidity >=0.0;\n\t\t\tcontract C\n\t\t\t{\n\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\trequire(x == 0);\n\t\t\t\t\tdo {\n\t\t\t\t\t\t++x;\n\t\t\t\t\t} while (x < 2);\n\t\t\t\t\tassert(x == 2);\n\t\t\t\t}\n\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n            \"bmcLoopIterations\": \"bmc\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_bmc_loop_iterations_invalid_arg/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.bmcLoopIterations must be an unsigned integer.\",\n            \"message\": \"settings.modelChecker.bmcLoopIterations must be an unsigned integer.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_all/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_all/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0\n\nTransaction trace:\nB.constructor()\nB.g(0)\n --> Source:5:7:\n  |\n5 | \\t\\t\\t\\t\\t\\tassert(y > 0);\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0\n\nTransaction trace:\nB.constructor()\nB.g(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 137,\n                \"file\": \"Source\",\n                \"start\": 124\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nA.constructor()\nA.f(0)\n  --> Source:10:7:\n   |\n10 | \\t\\t\\t\\t\\t\\tassert(x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nA.constructor()\nA.f(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 231,\n                \"file\": \"Source\",\n                \"start\": 218\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"Source\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_all_explicit/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"contracts\":\n\t\t\t{\n\t\t\t\t\"Source\": [\"A\", \"B\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_all_explicit/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0\n\nTransaction trace:\nB.constructor()\nB.g(0)\n --> Source:5:7:\n  |\n5 | \\t\\t\\t\\t\\t\\tassert(y > 0);\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0\n\nTransaction trace:\nB.constructor()\nB.g(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 137,\n                \"file\": \"Source\",\n                \"start\": 124\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nA.constructor()\nA.f(0)\n  --> Source:10:7:\n   |\n10 | \\t\\t\\t\\t\\t\\tassert(x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nA.constructor()\nA.f(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 231,\n                \"file\": \"Source\",\n                \"start\": 218\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"Source\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_empty_array/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"contracts\":\n\t\t\t{\n\t\t\t\t\"Source\": []\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_empty_array/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Source contracts must be a non-empty array.\",\n            \"message\": \"Source contracts must be a non-empty array.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_empty_contract/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"contracts\":\n\t\t\t{\n\t\t\t\t\"Source\": [\"\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_empty_contract/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Contract name cannot be empty.\",\n            \"message\": \"Contract name cannot be empty.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_empty_source/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"contracts\":\n\t\t\t{\n\t\t\t\t\"\": [\"A\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_empty_source/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Source name cannot be empty.\",\n            \"message\": \"Source name cannot be empty.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"contracts\":\n\t\t\t{\n\t\t\t\t\"Source\": [\"C\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_inexistent_contract/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"7400\",\n            \"formattedMessage\": \"Warning: Requested contract \\\"C\\\" does not exist in source \\\"Source\\\".\n\n\",\n            \"message\": \"Requested contract \\\"C\\\" does not exist in source \\\"Source\\\".\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"Source\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_multi_source/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t},\n\t\t\"Source2\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\timport 'Source';\n\t\t\t\tcontract C is A {\n\t\t\t\t\tfunction h(uint z) public pure {\n\t\t\t\t\t\tassert(z > 100);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"contracts\":\n\t\t\t{\n\t\t\t\t\"Source\": [\"A\"], \"Source2\": [\"C\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_multi_source/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0\n\nTransaction trace:\nA.constructor()\nB.g(0)\n --> Source:5:7:\n  |\n5 | \\t\\t\\t\\t\\t\\tassert(y > 0);\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0\n\nTransaction trace:\nA.constructor()\nB.g(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 137,\n                \"file\": \"Source\",\n                \"start\": 124\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nA.constructor()\nA.f(0)\n  --> Source:10:7:\n   |\n10 | \\t\\t\\t\\t\\t\\tassert(x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nA.constructor()\nA.f(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 231,\n                \"file\": \"Source\",\n                \"start\": 218\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nz = 0\n\nTransaction trace:\nC.constructor()\nC.h(0)\n --> Source2:6:7:\n  |\n6 | \\t\\t\\t\\t\\t\\tassert(z > 100);\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\nz = 0\n\nTransaction trace:\nC.constructor()\nC.h(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 165,\n                \"file\": \"Source2\",\n                \"start\": 150\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"Source\": {\n            \"id\": 0\n        },\n        \"Source2\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_only_one/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"contracts\":\n\t\t\t{\n\t\t\t\t\"Source\": [\"A\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_only_one/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0\n\nTransaction trace:\nA.constructor()\nB.g(0)\n --> Source:5:7:\n  |\n5 | \\t\\t\\t\\t\\t\\tassert(y > 0);\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\ny = 0\n\nTransaction trace:\nA.constructor()\nB.g(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 137,\n                \"file\": \"Source\",\n                \"start\": 124\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nA.constructor()\nA.f(0)\n  --> Source:10:7:\n   |\n10 | \\t\\t\\t\\t\\t\\tassert(x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nA.constructor()\nA.f(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 231,\n                \"file\": \"Source\",\n                \"start\": 218\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"Source\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"contracts\":\n\t\t\t{\n\t\t\t\t\"Sourceee\": [\"A\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9134\",\n            \"formattedMessage\": \"Warning: Requested source \\\"Sourceee\\\" does not exist.\n\n\",\n            \"message\": \"Requested source \\\"Sourceee\\\" does not exist.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"Source\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_2/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"contracts\": 2\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_2/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.contracts is not a JSON object.\",\n            \"message\": \"settings.modelChecker.contracts is not a JSON object.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_3/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"contracts\":\n\t\t\t{\n\t\t\t\t\"Source\": 2\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_3/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Source contracts must be an array.\",\n            \"message\": \"Source contracts must be an array.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_4/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"Source\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\n\t\t\t\tpragma solidity >=0.0;\n\t\t\t\tcontract B {\n\t\t\t\t\tfunction g(uint y) public pure {\n\t\t\t\t\t\tassert(y > 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract A is B {\n\t\t\t\t\tfunction f(uint x) public pure {\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"contracts\":\n\t\t\t{\n\t\t\t\t\"Source\": [2]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_contracts_wrong_key_sources_4/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Every contract in settings.modelChecker.contracts must be a string.\",\n            \"message\": \"Every contract in settings.modelChecker.contracts must be a string.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_default_all/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C {\n\t\t\t\t\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\t\t\t\t\trequire(b != 0);\n\t\t\t\t\t\treturn (a / b, a % b);\n\t\t\t\t\t}\n\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_default_all/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_default_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C {\n\t\t\t\t\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\t\t\t\t\trequire(b != 0);\n\t\t\t\t\t\treturn (a / b, a % b);\n\t\t\t\t\t}\n\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_default_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_default_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C {\n\t\t\t\t\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\t\t\t\t\trequire(b != 0);\n\t\t\t\t\t\treturn (a / b, a % b);\n\t\t\t\t\t}\n\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_default_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_false_all/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C {\n\t\t\t\t\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\t\t\t\t\trequire(b != 0);\n\t\t\t\t\t\treturn (a / b, a % b);\n\t\t\t\t\t}\n\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"divModNoSlacks\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_false_all/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5840\",\n            \"formattedMessage\": \"Warning: CHC: 2 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"CHC: 2 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_false_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C {\n\t\t\t\t\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\t\t\t\t\trequire(b != 0);\n\t\t\t\t\t\treturn (a / b, a % b);\n\t\t\t\t\t}\n\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"divModNoSlacks\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_false_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_false_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C {\n\t\t\t\t\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\t\t\t\t\trequire(b != 0);\n\t\t\t\t\t\treturn (a / b, a % b);\n\t\t\t\t\t}\n\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"divModNoSlacks\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_false_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5840\",\n            \"formattedMessage\": \"Warning: CHC: 2 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"CHC: 2 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_wrong/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C {\n\t\t\t\t\tfunction f(uint a, uint b) public pure returns (uint, uint) {\n\t\t\t\t\t\trequire(b != 0);\n\t\t\t\t\t\treturn (a / b, a % b);\n\t\t\t\t\t}\n\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"divModNoSlacks\": 42\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_divModSlacks_wrong/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.divModNoSlacks must be a Boolean.\",\n            \"message\": \"settings.modelChecker.divModNoSlacks must be a Boolean.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_engine_all/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C { function f(uint x) public pure { assert(x > 0); } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_engine_all/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.f(0)\n --> A:4:47:\n  |\n4 | contract C { function f(uint x) public pure { assert(x > 0); } }\n  |                                               ^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.f(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 119,\n                \"file\": \"A\",\n                \"start\": 106\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_engine_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C { function f(uint x) public pure { assert(x > 0); } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_engine_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4661\",\n            \"formattedMessage\": \"Warning: BMC: Assertion violation happens here.\n --> A:4:47:\n  |\n4 | contract C { function f(uint x) public pure { assert(x > 0); } }\n  |                                               ^^^^^^^^^^^^^\nNote: Counterexample:\n  x = 0\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Assertion violation happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  x = 0\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 119,\n                \"file\": \"A\",\n                \"start\": 106\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_engine_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C { function f(uint x) public pure { assert(x > 0); } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_engine_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.f(0)\n --> A:4:47:\n  |\n4 | contract C { function f(uint x) public pure { assert(x > 0); } }\n  |                                               ^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.f(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 119,\n                \"file\": \"A\",\n                \"start\": 106\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_engine_none/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C { function f(uint x) public pure { assert(x > 0); } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"none\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_engine_none/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_ext_calls_empty_arg/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\n\t\t\t\t\tcontract Ext {\n\t\t\t\t\t\tfunction f() public view returns (uint) {\n\t\t\t\t\t\t\treturn 42;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcontract test {\n\t\t\t\t\t\tfunction g(Ext e) public view {\n\t\t\t\t\t\t\tuint x = e.f();\n\t\t\t\t\t\t\tassert(x == 42);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"extCalls\": \"\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_ext_calls_empty_arg/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid model checker extCalls requested.\",\n            \"message\": \"Invalid model checker extCalls requested.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_ext_calls_trusted_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\n\t\t\t\t\tcontract Ext {\n\t\t\t\t\t\tfunction f() public view returns (uint) {\n\t\t\t\t\t\t\treturn 42;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcontract test {\n\t\t\t\t\t\tfunction g(Ext e) public view {\n\t\t\t\t\t\t\tuint x = e.f();\n\t\t\t\t\t\t\tassert(x == 42);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"extCalls\": \"trusted\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_ext_calls_trusted_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2018\",\n            \"formattedMessage\": \"Warning: Function state mutability can be restricted to pure\n --> A:4:7:\n  |\n4 | \\t\\t\\t\\t\\t\\tfunction f() public view returns (uint) {\n  | \\t\\t\\t\\t\\t\\t^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Function state mutability can be restricted to pure\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 152,\n                \"file\": \"A\",\n                \"start\": 85\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_ext_calls_untrusted_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\n\t\t\t\t\tabstract contract Ext {\n\t\t\t\t\t\tfunction f() virtual public view returns (uint);\n\t\t\t\t\t}\n\n\t\t\t\t\tcontract test {\n\t\t\t\t\t\tfunction g(Ext e) public view {\n\t\t\t\t\t\t\tuint x = e.f();\n\t\t\t\t\t\t\tassert(x == 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"extCalls\": \"untrusted\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_ext_calls_untrusted_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\ne = 0\nx = 1\n\nTransaction trace:\ntest.constructor()\ntest.g(0)\n    e.f() -- untrusted external call\n  --> A:10:8:\n   |\n10 | \\t\\t\\t\\t\\t\\t\\tassert(x == 0);\n   | \\t\\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\ne = 0\nx = 1\n\nTransaction trace:\ntest.constructor()\ntest.g(0)\n    e.f() -- untrusted external call\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 254,\n                \"file\": \"A\",\n                \"start\": 240\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_1/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\n\t\t\t\t\tcontract Ext {\n\t\t\t\t\t\tfunction f() public view returns (uint) {\n\t\t\t\t\t\t\treturn 42;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcontract test {\n\t\t\t\t\t\tfunction g(Ext e) public view {\n\t\t\t\t\t\t\tuint x = e.f();\n\t\t\t\t\t\t\tassert(x == 42);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"extCalls\": \"what\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_1/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid model checker extCalls requested.\",\n            \"message\": \"Invalid model checker extCalls requested.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_2/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\n\t\t\t\t\tcontract Ext {\n\t\t\t\t\t\tfunction f() public view returns (uint) {\n\t\t\t\t\t\t\treturn 42;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcontract test {\n\t\t\t\t\t\tfunction g(Ext e) public view {\n\t\t\t\t\t\t\tuint x = e.f();\n\t\t\t\t\t\t\tassert(x == 42);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"extCalls\": 2\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_ext_calls_wrong_arg_2/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.extCalls must be a string.\",\n            \"message\": \"settings.modelChecker.extCalls must be a string.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_contract/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint x;\n\t\t\t\t\tfunction f() public view {\n\t\t\t\t\t\tassert(x < 10);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"invariants\": [\"contract\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_contract/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1180\",\n            \"formattedMessage\": \"Info: Contract invariant(s) for A:test:\n(true || !(x >= 1))\n\n\n\",\n            \"message\": \"Contract invariant(s) for A:test:\n(true || !(x >= 1))\n\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint x;\n\t\t\t\t\tfunction f() view public {\n\t\t\t\t\t\tassert(x == 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"invariants\": [\"contract\", \"reentrancy\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_contract_reentrancy/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1180\",\n            \"formattedMessage\": \"Info: Contract invariant(s) for A:test:\n(true || !(x >= 1))\nReentrancy property(ies) for A:test:\n(((<errorCode> = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true)\n<errorCode> = 0 -> no errors\n<errorCode> = 1 -> Assertion failed at assert(x == 0)\n\n\n\",\n            \"message\": \"Contract invariant(s) for A:test:\n(true || !(x >= 1))\nReentrancy property(ies) for A:test:\n(((<errorCode> = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true)\n<errorCode> = 0 -> no errors\n<errorCode> = 1 -> Assertion failed at assert(x == 0)\n\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_reentrancy/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint x;\n\t\t\t\t\tfunction f() public {\n\t\t\t\t\t\tassert(x == 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"invariants\": [\"reentrancy\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_reentrancy/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2018\",\n            \"formattedMessage\": \"Warning: Function state mutability can be restricted to view\n --> A:6:6:\n  |\n6 | \\t\\t\\t\\t\\tfunction f() public {\n  | \\t\\t\\t\\t\\t^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Function state mutability can be restricted to view\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 144,\n                \"file\": \"A\",\n                \"start\": 94\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1180\",\n            \"formattedMessage\": \"Info: Reentrancy property(ies) for A:test:\n(((<errorCode> = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true)\n<errorCode> = 0 -> no errors\n<errorCode> = 1 -> Assertion failed at assert(x == 0)\n\n\n\",\n            \"message\": \"Reentrancy property(ies) for A:test:\n(((<errorCode> = 0) && (x!6 = x!4) && (x' = x)) || true || true || true || true)\n<errorCode> = 0 -> no errors\n<errorCode> = 1 -> Assertion failed at assert(x == 0)\n\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_wrong_key/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint x;\n\t\t\t\t\tfunction f() public view {\n\t\t\t\t\t\tassert(x < 10);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"invariants\": [\"what\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_wrong_key/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid model checker invariants requested.\",\n            \"message\": \"Invalid model checker invariants requested.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_wrong_type/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint x;\n\t\t\t\t\tfunction f() public view {\n\t\t\t\t\t\tassert(x < 10);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"invariants\": [2]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_wrong_type/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Every invariant type in settings.modelChecker.invariants must be a string.\",\n            \"message\": \"Every invariant type in settings.modelChecker.invariants must be a string.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint x;\n\t\t\t\t\tfunction f() public view {\n\t\t\t\t\t\tassert(x < 10);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"invariants\": 2\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_invariants_wrong_type_2/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.invariants must be an array.\",\n            \"message\": \"settings.modelChecker.invariants must be an array.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_print_query_all/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\n                contract C\n                {\n                    function f() public pure {\n                        uint x = 0;\n                        assert(x == 0);\n                    }\n                }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n            \"printQuery\": true,\n\t\t\t\"solvers\": [\"smtlib2\"],\n\t\t\t\"timeout\": 1000\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_print_query_all/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2339\",\n            \"formattedMessage\": \"Info: CHC: Requested query:\n(set-option :timeout 1000)\n(set-logic HORN)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool)\n(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool)\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int))\n(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))\n)\n(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))\n)\n(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))\n)\n(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int))\n(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |error_target_3| () Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))\n)(assert\n(forall ((UNUSED Bool))\n(=> error_target_3 false)))\n(check-sat)\n\n\n\",\n            \"message\": \"CHC: Requested query:\n(set-option :timeout 1000)\n(set-logic HORN)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool)\n(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool)\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int))\n(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))\n)\n(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))\n)\n(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))\n)\n(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int))\n(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |error_target_3| () Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))\n)(assert\n(forall ((UNUSED Bool))\n(=> error_target_3 false)))\n(check-sat)\n\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5840\",\n            \"formattedMessage\": \"Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6240\",\n            \"formattedMessage\": \"Info: BMC: Requested query:\n(set-option :produce-models true)\n(set-option :timeout 1000)\n(set-logic ALL)\n(declare-fun |x_5_3| () Int)\n(declare-fun |error_0| () Int)\n(declare-fun |this_0| () Int)\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |tx_0| () |tx_type|)\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-fun |crypto_0| () |crypto_type|)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-fun |abi_0| () |abi_type|)\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |state_0| () |state_type|)\n(declare-fun |x_5_4| () Int)\n(declare-fun |x_5_0| () Int)\n(declare-fun |expr_6_0| () Int)\n(declare-fun |x_5_1| () Int)\n(declare-fun |expr_9_0| () Int)\n(declare-fun |expr_10_0| () Int)\n(declare-fun |expr_11_1| () Bool)\n(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1)))\n(declare-const |EVALEXPR_0| Int)\n(assert (= |EVALEXPR_0| x_5_1))\n(check-sat)\n(get-value (|EVALEXPR_0| ))\n\n\n\",\n            \"message\": \"BMC: Requested query:\n(set-option :produce-models true)\n(set-option :timeout 1000)\n(set-logic ALL)\n(declare-fun |x_5_3| () Int)\n(declare-fun |error_0| () Int)\n(declare-fun |this_0| () Int)\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |tx_0| () |tx_type|)\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-fun |crypto_0| () |crypto_type|)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-fun |abi_0| () |abi_type|)\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |state_0| () |state_type|)\n(declare-fun |x_5_4| () Int)\n(declare-fun |x_5_0| () Int)\n(declare-fun |expr_6_0| () Int)\n(declare-fun |x_5_1| () Int)\n(declare-fun |expr_9_0| () Int)\n(declare-fun |expr_10_0| () Int)\n(declare-fun |expr_11_1| () Bool)\n(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1)))\n(declare-const |EVALEXPR_0| Int)\n(assert (= |EVALEXPR_0| x_5_1))\n(check-sat)\n(get-value (|EVALEXPR_0| ))\n\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2788\",\n            \"formattedMessage\": \"Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"BMC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_print_query_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\n                contract C\n                {\n                    function f() public pure {\n                        uint x = 0;\n                        assert(x == 0);\n                    }\n                }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n            \"printQuery\": true,\n\t\t\t\"solvers\": [\"smtlib2\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_print_query_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6240\",\n            \"formattedMessage\": \"Info: BMC: Requested query:\n(set-option :produce-models true)\n(set-logic ALL)\n(declare-fun |error_0| () Int)\n(declare-fun |this_0| () Int)\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |tx_0| () |tx_type|)\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-fun |crypto_0| () |crypto_type|)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-fun |abi_0| () |abi_type|)\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |state_0| () |state_type|)\n(declare-fun |x_5_0| () Int)\n(declare-fun |expr_6_0| () Int)\n(declare-fun |x_5_1| () Int)\n(declare-fun |expr_9_0| () Int)\n(declare-fun |expr_10_0| () Int)\n(declare-fun |expr_11_1| () Bool)\n(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1)))\n(declare-const |EVALEXPR_0| Int)\n(assert (= |EVALEXPR_0| x_5_1))\n(check-sat)\n(get-value (|EVALEXPR_0| ))\n\n\n\",\n            \"message\": \"BMC: Requested query:\n(set-option :produce-models true)\n(set-logic ALL)\n(declare-fun |error_0| () Int)\n(declare-fun |this_0| () Int)\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |tx_0| () |tx_type|)\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-fun |crypto_0| () |crypto_type|)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-fun |abi_0| () |abi_type|)\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |state_0| () |state_type|)\n(declare-fun |x_5_0| () Int)\n(declare-fun |expr_6_0| () Int)\n(declare-fun |x_5_1| () Int)\n(declare-fun |expr_9_0| () Int)\n(declare-fun |expr_10_0| () Int)\n(declare-fun |expr_11_1| () Bool)\n(assert (and (and (and true true) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> (and true true) true) (and (= expr_10_0 0) (and (=> (and true true) (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_1) (and (ite (and true true) (= x_5_1 expr_6_0) (= x_5_1 x_5_0)) (and (=> (and true true) true) (and (= expr_6_0 0) (and (= x_5_0 0) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true))))))))))) (not expr_11_1)))\n(declare-const |EVALEXPR_0| Int)\n(assert (= |EVALEXPR_0| x_5_1))\n(check-sat)\n(get-value (|EVALEXPR_0| ))\n\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2788\",\n            \"formattedMessage\": \"Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"BMC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_print_query_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\n                contract C\n                {\n                    function f() public pure {\n                        uint x = 0;\n                        assert(x == 0);\n                    }\n                }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n            \"printQuery\": true,\n\t\t\t\"solvers\": [\"smtlib2\"],\n\t\t\t\"timeout\": 1000\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_print_query_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2339\",\n            \"formattedMessage\": \"Info: CHC: Requested query:\n(set-option :timeout 1000)\n(set-logic HORN)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool)\n(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool)\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int))\n(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))\n)\n(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))\n)\n(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))\n)\n(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int))\n(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |error_target_3| () Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))\n)(assert\n(forall ((UNUSED Bool))\n(=> error_target_3 false)))\n(check-sat)\n\n\n\",\n            \"message\": \"CHC: Requested query:\n(set-option :timeout 1000)\n(set-logic HORN)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |interface_0_C_16| (Int |abi_type| |crypto_type| |state_type|) Bool)\n(declare-fun |nondet_interface_1_C_16| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool)\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |summary_constructor_2_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int))\n(=> (= error_0 0) (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_0)))\n)\n(declare-fun |summary_3_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |summary_4_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (nondet_interface_1_C_16 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2))) (nondet_interface_1_C_16 error_1 this_0 abi_0 crypto_0 state_0 state_2)))\n)\n(declare-fun |block_5_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_6_f_14_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_5_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true)) true) (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1)))\n)\n(declare-fun |block_7_return_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(declare-fun |block_8_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true)))))))))) (and (and true (not expr_11_1)) (= error_1 1))) (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_2 Int))\n(=> (block_8_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2) (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_10_0 Int) (expr_11_1 Bool) (expr_6_0 Int) (expr_9_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int) (x_5_2 Int))\n(=> (and (and (block_6_f_14_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (= error_1 error_0) (and (= expr_11_1 (= expr_9_0 expr_10_0)) (and (=> true true) (and (= expr_10_0 0) (and (=> true (and (>= expr_9_0 0) (<= expr_9_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_9_0 x_5_2) (and (= x_5_2 expr_6_0) (and (=> true true) (and (= expr_6_0 0) (and (= x_5_1 0) true))))))))))) true) (block_7_return_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_7_return_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) true) true) (summary_3_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |block_9_function_f__15_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_5_1 Int))\n(=> (and (and (block_9_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1 x_5_1) (and (summary_3_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_2 state_3) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 638722032)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 38)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 18)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 31)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 240)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true))))))) true) (summary_4_function_f__15_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_3)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |contract_initializer_10_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |contract_initializer_entry_11_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |contract_initializer_after_init_12_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_entry_11_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_after_init_12_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |implicit_constructor_entry_13_C_16| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_16 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (summary_constructor_2_C_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_16 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |error_target_3| () Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (interface_0_C_16 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__15_16 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (= error_0 1))) error_target_3))\n)(assert\n(forall ((UNUSED Bool))\n(=> error_target_3 false)))\n(check-sat)\n\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5840\",\n            \"formattedMessage\": \"Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_print_query_invalid_arg/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\n                contract C\n                {\n                    function f() public pure {\n                        uint x = 0;\n                        assert(x == 0);\n                    }\n                }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n            \"printQuery\": 17\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_print_query_invalid_arg/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.printQuery must be a Boolean value.\",\n            \"message\": \"settings.modelChecker.printQuery must be a Boolean value.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_default_all_engines/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f(uint8 x) public {\n\t\t\t\t\t\tassert(x >= 0);\n\t\t\t\t\t\tassert(x < 1000);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_default_all_engines/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2018\",\n            \"formattedMessage\": \"Warning: Function state mutability can be restricted to pure\n --> A:5:6:\n  |\n5 | \\t\\t\\t\\t\\tfunction f(uint8 x) public {\n  | \\t\\t\\t\\t\\t^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Function state mutability can be restricted to pure\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 162,\n                \"file\": \"A\",\n                \"start\": 81\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_default_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f(uint8 x) public {\n\t\t\t\t\t\tassert(x >= 0);\n\t\t\t\t\t\tassert(x < 1000);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_default_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2018\",\n            \"formattedMessage\": \"Warning: Function state mutability can be restricted to pure\n --> A:5:6:\n  |\n5 | \\t\\t\\t\\t\\tfunction f(uint8 x) public {\n  | \\t\\t\\t\\t\\t^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Function state mutability can be restricted to pure\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 162,\n                \"file\": \"A\",\n                \"start\": 81\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_default_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f(uint8 x) public {\n\t\t\t\t\t\tassert(x >= 0);\n\t\t\t\t\t\tassert(x < 1000);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_default_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2018\",\n            \"formattedMessage\": \"Warning: Function state mutability can be restricted to pure\n --> A:5:6:\n  |\n5 | \\t\\t\\t\\t\\tfunction f(uint8 x) public {\n  | \\t\\t\\t\\t\\t^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Function state mutability can be restricted to pure\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 162,\n                \"file\": \"A\",\n                \"start\": 81\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_false_all_engines/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f(uint8 x) public {\n\t\t\t\t\t\tassert(x >= 0);\n\t\t\t\t\t\tassert(x < 1000);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"showProvedSafe\": false\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_false_all_engines/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2018\",\n            \"formattedMessage\": \"Warning: Function state mutability can be restricted to pure\n --> A:5:6:\n  |\n5 | \\t\\t\\t\\t\\tfunction f(uint8 x) public {\n  | \\t\\t\\t\\t\\t^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Function state mutability can be restricted to pure\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 162,\n                \"file\": \"A\",\n                \"start\": 81\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_false_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f(uint8 x) public {\n\t\t\t\t\t\tassert(x >= 0);\n\t\t\t\t\t\tassert(x < 1000);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"showProvedSafe\": false\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_false_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2018\",\n            \"formattedMessage\": \"Warning: Function state mutability can be restricted to pure\n --> A:5:6:\n  |\n5 | \\t\\t\\t\\t\\tfunction f(uint8 x) public {\n  | \\t\\t\\t\\t\\t^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Function state mutability can be restricted to pure\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 162,\n                \"file\": \"A\",\n                \"start\": 81\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_false_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f(uint8 x) public {\n\t\t\t\t\t\tassert(x >= 0);\n\t\t\t\t\t\tassert(x < 1000);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"showProvedSafe\": false\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_false_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2018\",\n            \"formattedMessage\": \"Warning: Function state mutability can be restricted to pure\n --> A:5:6:\n  |\n5 | \\t\\t\\t\\t\\tfunction f(uint8 x) public {\n  | \\t\\t\\t\\t\\t^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Function state mutability can be restricted to pure\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 162,\n                \"file\": \"A\",\n                \"start\": 81\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 2 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_true_all_engines/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f(uint8 x) public {\n\t\t\t\t\t\tassert(x >= 0);\n\t\t\t\t\t\tassert(x < 1000);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"showProvedSafe\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_true_all_engines/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2018\",\n            \"formattedMessage\": \"Warning: Function state mutability can be restricted to pure\n --> A:5:6:\n  |\n5 | \\t\\t\\t\\t\\tfunction f(uint8 x) public {\n  | \\t\\t\\t\\t\\t^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Function state mutability can be restricted to pure\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 162,\n                \"file\": \"A\",\n                \"start\": 81\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9576\",\n            \"formattedMessage\": \"Info: CHC: Assertion violation check is safe!\n --> A:6:7:\n  |\n6 | \\t\\t\\t\\t\\t\\tassert(x >= 0);\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation check is safe!\",\n            \"severity\": \"info\",\n            \"sourceLocation\": {\n                \"end\": 130,\n                \"file\": \"A\",\n                \"start\": 116\n            },\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9576\",\n            \"formattedMessage\": \"Info: CHC: Assertion violation check is safe!\n --> A:7:7:\n  |\n7 | \\t\\t\\t\\t\\t\\tassert(x < 1000);\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation check is safe!\",\n            \"severity\": \"info\",\n            \"sourceLocation\": {\n                \"end\": 154,\n                \"file\": \"A\",\n                \"start\": 138\n            },\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_true_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f(uint8 x) public {\n\t\t\t\t\t\tassert(x >= 0);\n\t\t\t\t\t\tassert(x < 1000);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"showProvedSafe\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_true_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2018\",\n            \"formattedMessage\": \"Warning: Function state mutability can be restricted to pure\n --> A:5:6:\n  |\n5 | \\t\\t\\t\\t\\tfunction f(uint8 x) public {\n  | \\t\\t\\t\\t\\t^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Function state mutability can be restricted to pure\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 162,\n                \"file\": \"A\",\n                \"start\": 81\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2961\",\n            \"formattedMessage\": \"Info: BMC: Assertion violation check is safe!\n --> A:6:7:\n  |\n6 | \\t\\t\\t\\t\\t\\tassert(x >= 0);\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"BMC: Assertion violation check is safe!\",\n            \"severity\": \"info\",\n            \"sourceLocation\": {\n                \"end\": 130,\n                \"file\": \"A\",\n                \"start\": 116\n            },\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2961\",\n            \"formattedMessage\": \"Info: BMC: Assertion violation check is safe!\n --> A:7:7:\n  |\n7 | \\t\\t\\t\\t\\t\\tassert(x < 1000);\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"BMC: Assertion violation check is safe!\",\n            \"severity\": \"info\",\n            \"sourceLocation\": {\n                \"end\": 154,\n                \"file\": \"A\",\n                \"start\": 138\n            },\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_true_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f(uint8 x) public {\n\t\t\t\t\t\tassert(x >= 0);\n\t\t\t\t\t\tassert(x < 1000);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"showProvedSafe\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_true_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2018\",\n            \"formattedMessage\": \"Warning: Function state mutability can be restricted to pure\n --> A:5:6:\n  |\n5 | \\t\\t\\t\\t\\tfunction f(uint8 x) public {\n  | \\t\\t\\t\\t\\t^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Function state mutability can be restricted to pure\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 162,\n                \"file\": \"A\",\n                \"start\": 81\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9576\",\n            \"formattedMessage\": \"Info: CHC: Assertion violation check is safe!\n --> A:6:7:\n  |\n6 | \\t\\t\\t\\t\\t\\tassert(x >= 0);\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation check is safe!\",\n            \"severity\": \"info\",\n            \"sourceLocation\": {\n                \"end\": 130,\n                \"file\": \"A\",\n                \"start\": 116\n            },\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9576\",\n            \"formattedMessage\": \"Info: CHC: Assertion violation check is safe!\n --> A:7:7:\n  |\n7 | \\t\\t\\t\\t\\t\\tassert(x < 1000);\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation check is safe!\",\n            \"severity\": \"info\",\n            \"sourceLocation\": {\n                \"end\": 154,\n                \"file\": \"A\",\n                \"start\": 138\n            },\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_wrong/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f(uint8 x) public {\n\t\t\t\t\t\tassert(x >= 0);\n\t\t\t\t\t\tassert(x < 1000);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"showProvedSafe\": \"aaa\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_proved_safe_wrong/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.showProvedSafe must be a Boolean value.\",\n            \"message\": \"settings.modelChecker.showProvedSafe must be a Boolean value.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_default_all_engines/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tstruct S {\n\t\t\t\t\t\tuint x;\n\t\t\t\t\t}\n\t\t\t\t\tS s;\n\t\t\t\t\tfunction f(bool b) public {\n\t\t\t\t\t\ts.x |= b ? 1 : 2;\n\t\t\t\t\t\tassert(s.x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_default_all_engines/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5840\",\n            \"formattedMessage\": \"Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_false_all_engines/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tstruct S {\n\t\t\t\t\t\tuint x;\n\t\t\t\t\t}\n\t\t\t\t\tS s;\n\t\t\t\t\tfunction f(bool b) public {\n\t\t\t\t\t\ts.x |= b ? 1 : 2;\n\t\t\t\t\t\tassert(s.x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"showUnproved\": false\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_false_all_engines/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5840\",\n            \"formattedMessage\": \"Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_false_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tstruct S {\n\t\t\t\t\t\tuint x;\n\t\t\t\t\t}\n\t\t\t\t\tS s;\n\t\t\t\t\tfunction f(bool b) public {\n\t\t\t\t\t\ts.x |= b ? 1 : 2;\n\t\t\t\t\t\tassert(s.x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"showUnproved\": false\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_false_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_false_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tstruct S {\n\t\t\t\t\t\tuint x;\n\t\t\t\t\t}\n\t\t\t\t\tS s;\n\t\t\t\t\tfunction f(bool b) public {\n\t\t\t\t\t\ts.x |= b ? 1 : 2;\n\t\t\t\t\t\tassert(s.x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"showUnproved\": false\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_false_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5840\",\n            \"formattedMessage\": \"Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_true_all_engines/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tstruct S {\n\t\t\t\t\t\tuint x;\n\t\t\t\t\t}\n\t\t\t\t\tS s;\n\t\t\t\t\tfunction f(bool b) public {\n\t\t\t\t\t\ts.x |= b ? 1 : 2;\n\t\t\t\t\t\tassert(s.x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"showUnproved\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_true_all_engines/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation might happen here.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\tassert(s.x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation might happen here.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 201,\n                \"file\": \"A\",\n                \"start\": 186\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_true_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tstruct S {\n\t\t\t\t\t\tuint x;\n\t\t\t\t\t}\n\t\t\t\t\tS s;\n\t\t\t\t\tfunction f(bool b) public {\n\t\t\t\t\t\ts.x |= b ? 1 : 2;\n\t\t\t\t\t\tassert(s.x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"showUnproved\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_true_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_true_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tstruct S {\n\t\t\t\t\t\tuint x;\n\t\t\t\t\t}\n\t\t\t\t\tS s;\n\t\t\t\t\tfunction f(bool b) public {\n\t\t\t\t\t\ts.x |= b ? 1 : 2;\n\t\t\t\t\t\tassert(s.x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"showUnproved\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_true_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation might happen here.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\tassert(s.x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation might happen here.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 201,\n                \"file\": \"A\",\n                \"start\": 186\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_wrong/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tstruct S {\n\t\t\t\t\t\tuint x;\n\t\t\t\t\t}\n\t\t\t\t\tS s;\n\t\t\t\t\tfunction f(bool b) public {\n\t\t\t\t\t\ts.x |= b ? 1 : 2;\n\t\t\t\t\t\tassert(s.x > 0);\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"showUnproved\": \"aaa\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unproved_wrong/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.showUnproved must be a Boolean value.\",\n            \"message\": \"settings.modelChecker.showUnproved must be a Boolean value.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_default_all_engines/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f() external pure {\n\t\t\t\t\t\tassembly {}\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_default_all_engines/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5724\",\n            \"formattedMessage\": \"Warning: SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\n\n\",\n            \"message\": \"SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_default_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f() external pure {\n\t\t\t\t\t\tassembly {}\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_default_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5724\",\n            \"formattedMessage\": \"Warning: SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\n\n\",\n            \"message\": \"SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_default_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f() external pure {\n\t\t\t\t\t\tassembly {}\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_default_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5724\",\n            \"formattedMessage\": \"Warning: SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\n\n\",\n            \"message\": \"SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f() external pure {\n\t\t\t\t\t\tassembly {}\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"showUnsupported\": false\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_false_all_engines/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5724\",\n            \"formattedMessage\": \"Warning: SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\n\n\",\n            \"message\": \"SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_false_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f() external pure {\n\t\t\t\t\t\tassembly {}\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"showUnsupported\": false\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_false_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5724\",\n            \"formattedMessage\": \"Warning: SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\n\n\",\n            \"message\": \"SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_false_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f() external pure {\n\t\t\t\t\t\tassembly {}\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"showUnsupported\": false\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_false_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5724\",\n            \"formattedMessage\": \"Warning: SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\n\n\",\n            \"message\": \"SMTChecker: 1 unsupported language feature(s). Enable the model checker option \\\"show unsupported\\\" to see all of them.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_true_all_engines/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f() external pure {\n\t\t\t\t\t\tassembly {}\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"showUnsupported\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_true_all_engines/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"7737\",\n            \"formattedMessage\": \"Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n --> A:6:7:\n  |\n6 | \\t\\t\\t\\t\\t\\tassembly {}\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^\n\n\",\n            \"message\": \"Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 127,\n                \"file\": \"A\",\n                \"start\": 116\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_true_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f() external pure {\n\t\t\t\t\t\tassembly {}\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"showUnsupported\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_true_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"7737\",\n            \"formattedMessage\": \"Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n --> A:6:7:\n  |\n6 | \\t\\t\\t\\t\\t\\tassembly {}\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^\n\n\",\n            \"message\": \"Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 127,\n                \"file\": \"A\",\n                \"start\": 116\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_true_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f() external pure {\n\t\t\t\t\t\tassembly {}\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"showUnsupported\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_true_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"7737\",\n            \"formattedMessage\": \"Warning: Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n --> A:6:7:\n  |\n6 | \\t\\t\\t\\t\\t\\tassembly {}\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^\n\n\",\n            \"message\": \"Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 127,\n                \"file\": \"A\",\n                \"start\": 116\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_wrong/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tfunction f() external pure {\n\t\t\t\t\t\tassembly {}\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"showUnsupported\": \"aaa\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_show_unsupported_wrong/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.showUnsupported must be a Boolean value.\",\n            \"message\": \"settings.modelChecker.showUnsupported must be a Boolean value.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_solvers_none/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C { function f(uint x) public pure { assert(x > 0); } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"solvers\": []\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_solvers_none/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"7649\",\n            \"formattedMessage\": \"Warning: CHC analysis was not possible since no Horn solver was found and enabled. The accepted solvers for CHC are Eldarica and z3.\n\n\",\n            \"message\": \"CHC analysis was not possible since no Horn solver was found and enabled. The accepted solvers for CHC are Eldarica and z3.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"7710\",\n            \"formattedMessage\": \"Warning: BMC analysis was not possible since no SMT solver was found and enabled. The accepted solvers for BMC are cvc5 and z3.\n\n\",\n            \"message\": \"BMC analysis was not possible since no SMT solver was found and enabled. The accepted solvers for BMC are cvc5 and z3.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_solvers_smtlib2/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C { function f(uint x) public pure { assert(x > 0); } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"solvers\": [\"smtlib2\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_solvers_smtlib2/output.json",
    "content": "{\n    \"auxiliaryInputRequested\": {\n        \"smtlib2queries\": {\n            \"0x1b1a2b4161df2f2869bdcd6ee320ef4c54aded9ae9c0441dd2dd4248f5616d97\": \"(set-option :produce-models true)\n(set-logic ALL)\n(declare-fun |x_3_3| () Int)\n(declare-fun |error_0| () Int)\n(declare-fun |this_0| () Int)\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |tx_0| () |tx_type|)\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-fun |crypto_0| () |crypto_type|)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-fun |abi_0| () |abi_type|)\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |state_0| () |state_type|)\n(declare-fun |x_3_4| () Int)\n(declare-fun |x_3_0| () Int)\n(declare-fun |expr_7_0| () Int)\n(declare-fun |expr_8_0| () Int)\n(declare-fun |expr_9_1| () Bool)\n(assert (and (and (and true true) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> (and true true) true) (and (= expr_8_0 0) (and (=> (and true true) (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_0) (and (and (>= x_3_0 0) (<= x_3_0 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 3017696395)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 179)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 222)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 100)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 139)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) true)))))))) (not expr_9_1)))\n(declare-const |EVALEXPR_0| Int)\n(assert (= |EVALEXPR_0| x_3_0))\n(check-sat)\n(get-value (|EVALEXPR_0| ))\n\",\n            \"0xd2654693bf2b4f42bfe922319928772b52430787451450fda29da1ebea716f19\": \"(set-logic HORN)\n(declare-datatypes ((|abi_type| 0)) (((|abi_type|))))\n(declare-datatypes ((|ecrecover_input_type| 0)) (((|ecrecover_input_type| (|hash| Int) (|v| Int) (|r| Int) (|s| Int)))))\n(declare-datatypes ((|bytes_tuple| 0)) (((|bytes_tuple| (|bytes_tuple_accessor_array| (Array Int Int)) (|bytes_tuple_accessor_length| Int)))))\n(declare-datatypes ((|crypto_type| 0)) (((|crypto_type| (|ecrecover| (Array |ecrecover_input_type| Int)) (|keccak256| (Array |bytes_tuple| Int)) (|ripemd160| (Array |bytes_tuple| Int)) (|sha256| (Array |bytes_tuple| Int))))))\n(declare-datatypes ((|state_type| 0)) (((|state_type| (|balances| (Array Int Int))))))\n(declare-fun |interface_0_C_14| (Int |abi_type| |crypto_type| |state_type|) Bool)\n(declare-fun |nondet_interface_1_C_14| (Int Int |abi_type| |crypto_type| |state_type| |state_type|) Bool)\n(declare-datatypes ((|tx_type| 0)) (((|tx_type| (|blobhash| (Array Int Int)) (|block.basefee| Int) (|block.blobbasefee| Int) (|block.chainid| Int) (|block.coinbase| Int) (|block.gaslimit| Int) (|block.number| Int) (|block.prevrandao| Int) (|block.timestamp| Int) (|blockhash| (Array Int Int)) (|msg.data| |bytes_tuple|) (|msg.sender| Int) (|msg.sig| Int) (|msg.value| Int) (|tx.gasprice| Int) (|tx.origin| Int)))))\n(declare-fun |summary_constructor_2_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (this_0 Int))\n(=> (= error_0 0) (nondet_interface_1_C_14 error_0 this_0 abi_0 crypto_0 state_0 state_0)))\n)\n(declare-fun |summary_3_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool)\n(declare-fun |summary_4_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int))\n(=> (and (and (nondet_interface_1_C_14 error_0 this_0 abi_0 crypto_0 state_0 state_1) true) (and (= error_0 0) (summary_4_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 x_3_0 state_2 x_3_1))) (nondet_interface_1_C_14 error_1 this_0 abi_0 crypto_0 state_0 state_2)))\n)\n(declare-fun |block_5_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool)\n(declare-fun |block_6_f_12_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int))\n(block_5_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int))\n(=> (and (and (block_5_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true)) true) (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))\n)\n(declare-fun |block_7_return_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool)\n(declare-fun |block_8_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int))\n(=> (and (and (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> true true) (and (= expr_8_0 0) (and (=> true (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_1) (and (and (>= x_3_1 0) (<= x_3_1 115792089237316195423570985008687907853269984665640564039457584007913129639935)) true))))))) (and (and true (not expr_9_1)) (= error_1 1))) (block_8_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int))\n(=> (block_8_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (summary_3_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (expr_7_0 Int) (expr_8_0 Int) (expr_9_1 Bool) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int))\n(=> (and (and (block_6_f_12_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (= error_1 error_0) (and (= expr_9_1 (> expr_7_0 expr_8_0)) (and (=> true true) (and (= expr_8_0 0) (and (=> true (and (>= expr_7_0 0) (<= expr_7_0 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (= expr_7_0 x_3_1) (and (and (>= x_3_1 0) (<= x_3_1 115792089237316195423570985008687907853269984665640564039457584007913129639935)) true)))))))) true) (block_7_return_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int))\n(=> (and (and (block_7_return_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) true) true) (summary_3_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1)))\n)\n(declare-fun |block_9_function_f__13_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| Int |state_type| Int) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int))\n(block_9_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (funds_2_0 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (state_3 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int) (x_3_2 Int))\n(=> (and (and (block_9_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (and (summary_3_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_2 x_3_1 state_3 x_3_2) (and (= state_2 (|state_type| (store (|balances| state_1) this_0 (+ (select (|balances| state_1) this_0) funds_2_0)))) (and (and (>= (+ (select (|balances| state_1) this_0) funds_2_0) 0) (<= (+ (select (|balances| state_1) this_0) funds_2_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935)) (and (>= funds_2_0 (|msg.value| tx_0)) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (and (and (and (and (and (= (|msg.value| tx_0) 0) (= (|msg.sig| tx_0) 3017696395)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 0) 179)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 1) 222)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 2) 100)) (= (select (|bytes_tuple_accessor_array| (|msg.data| tx_0)) 3) 139)) (>= (|bytes_tuple_accessor_length| (|msg.data| tx_0)) 4))) (and (and (and (and (= state_1 state_0) (= error_0 0)) true) (and true (= x_3_1 x_3_0))) true))))))) true) (summary_4_function_f__13_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_3 x_3_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int))\n(=> (and (and (interface_0_C_14 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (= error_0 0))) (interface_0_C_14 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |contract_initializer_10_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(declare-fun |contract_initializer_entry_11_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (= state_1 state_0) (= error_0 0)) true) (contract_initializer_entry_11_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |contract_initializer_after_init_12_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_entry_11_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_after_init_12_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (contract_initializer_after_init_12_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) true) (contract_initializer_10_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(declare-fun |implicit_constructor_entry_13_C_14| (Int Int |abi_type| |crypto_type| |tx_type| |state_type| |state_type|) Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (and (and (and (= state_1 state_0) (= error_0 0)) true) true) true) (>= (select (|balances| state_1) this_0) (|msg.value| tx_0))) (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (contract_initializer_10_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true)) (> error_1 0)) (summary_constructor_2_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (error_1 Int) (state_0 |state_type|) (state_1 |state_type|) (state_2 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (implicit_constructor_entry_13_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) (and (= error_1 0) (and (contract_initializer_10_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_1 state_2) true))) true) (summary_constructor_2_C_14 error_1 this_0 abi_0 crypto_0 tx_0 state_0 state_2)))\n)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|))\n(=> (and (and (summary_constructor_2_C_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 state_1) true) (and (and (and (and (and (and (and (and (and (and (and (and (and (and (> (|block.prevrandao| tx_0) 18446744073709551616) (and (>= (|block.basefee| tx_0) 0) (<= (|block.basefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.blobbasefee| tx_0) 0) (<= (|block.blobbasefee| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.chainid| tx_0) 0) (<= (|block.chainid| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.coinbase| tx_0) 0) (<= (|block.coinbase| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|block.prevrandao| tx_0) 0) (<= (|block.prevrandao| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.gaslimit| tx_0) 0) (<= (|block.gaslimit| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.number| tx_0) 0) (<= (|block.number| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|block.timestamp| tx_0) 0) (<= (|block.timestamp| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|msg.sender| tx_0) 0) (<= (|msg.sender| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|msg.value| tx_0) 0) (<= (|msg.value| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (and (>= (|tx.origin| tx_0) 0) (<= (|tx.origin| tx_0) 1461501637330902918203684832716283019655932542975))) (and (>= (|tx.gasprice| tx_0) 0) (<= (|tx.gasprice| tx_0) 115792089237316195423570985008687907853269984665640564039457584007913129639935))) (= (|msg.value| tx_0) 0)) (= error_0 0))) (interface_0_C_14 this_0 abi_0 crypto_0 state_1)))\n)\n(declare-fun |error_target_3| () Bool)\n(assert (forall( (abi_0 |abi_type|) (crypto_0 |crypto_type|) (error_0 Int) (state_0 |state_type|) (state_1 |state_type|) (this_0 Int) (tx_0 |tx_type|) (x_3_0 Int) (x_3_1 Int))\n(=> (and (and (interface_0_C_14 this_0 abi_0 crypto_0 state_0) true) (and (summary_4_function_f__13_14 error_0 this_0 abi_0 crypto_0 tx_0 state_0 x_3_0 state_1 x_3_1) (= error_0 1))) error_target_3))\n)(assert\n(forall ((UNUSED Bool))\n(=> error_target_3 false)))\n(check-sat)\n\"\n        }\n    },\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5840\",\n            \"formattedMessage\": \"Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"3996\",\n            \"formattedMessage\": \"Warning: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled.\n\n\",\n            \"message\": \"CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2788\",\n            \"formattedMessage\": \"Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"BMC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"8084\",\n            \"formattedMessage\": \"Warning: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.\n\n\",\n            \"message\": \"BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_solvers_z3/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C { function f(uint x) public pure { assert(x > 0); } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"solvers\": [\"z3\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_solvers_z3/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.f(0)\n --> A:4:47:\n  |\n4 | contract C { function f(uint x) public pure { assert(x > 0); } }\n  |                                               ^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.f(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 119,\n                \"file\": \"A\",\n                \"start\": 106\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_solvers_z3_smtlib2/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C { function f(uint x) public pure { assert(x > 0); } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"solvers\": [\"z3\", \"smtlib2\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_solvers_z3_smtlib2/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.f(0)\n --> A:4:47:\n  |\n4 | contract C { function f(uint x) public pure { assert(x > 0); } }\n  |                                               ^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\n\nx = 0\n\nTransaction trace:\nC.constructor()\nC.f(0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 119,\n                \"file\": \"A\",\n                \"start\": 106\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_assert_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"targets\": [\"assert\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_assert_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4661\",\n            \"formattedMessage\": \"Warning: BMC: Assertion violation happens here.\n  --> A:12:7:\n   |\n12 | \\t\\t\\t\\t\\t\\tassert(x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Assertion violation happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  a = 0\n  x = 0\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 258,\n                \"file\": \"A\",\n                \"start\": 245\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_assert_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"targets\": [\"assert\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_assert_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\\\"\\\") -- untrusted external call\n  --> A:13:7:\n   |\n13 | \\t\\t\\t\\t\\t\\tassert(x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\\\"\\\") -- untrusted external call\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 308,\n                \"file\": \"A\",\n                \"start\": 295\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_balance_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"targets\": [\"balance\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_balance_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1236\",\n            \"formattedMessage\": \"Warning: BMC: Insufficient funds happens here.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Insufficient funds happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  a = 0\n  x = 0\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 237,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_balance_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"targets\": [\"balance\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_balance_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_constantCondition_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"targets\": [\"constantCondition\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_constantCondition_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6838\",\n            \"formattedMessage\": \"Warning: BMC: Condition is always true.\n --> A:7:15:\n  |\n7 | \\t\\t\\t\\t\\t\\trequire(x >= 0);\n  | \\t\\t\\t\\t\\t\\t        ^^^^^^\nNote: Callstack:\n\n\",\n            \"message\": \"BMC: Condition is always true.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Callstack:\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 165,\n                \"file\": \"A\",\n                \"start\": 159\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_constantCondition_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"targets\": [\"constantCondition\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_constantCondition_chc/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_default_all_engines/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_default_all_engines/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4281\",\n            \"formattedMessage\": \"Warning: CHC: Division by zero happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> A:10:7:\n   |\n10 | \\t\\t\\t\\t\\t\\t2 / x;\n   | \\t\\t\\t\\t\\t\\t^^^^^\n\n\",\n            \"message\": \"CHC: Division by zero happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 216,\n                \"file\": \"A\",\n                \"start\": 211\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> A:12:7:\n   |\n12 | \\t\\t\\t\\t\\t\\tassert(x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 258,\n                \"file\": \"A\",\n                \"start\": 245\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2529\",\n            \"formattedMessage\": \"Warning: CHC: Empty array \\\"pop\\\" happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> A:13:7:\n   |\n13 | \\t\\t\\t\\t\\t\\tarr.pop();\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Empty array \\\"pop\\\" happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 275,\n                \"file\": \"A\",\n                \"start\": 266\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6368\",\n            \"formattedMessage\": \"Warning: CHC: Out of bounds access happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> A:14:7:\n   |\n14 | \\t\\t\\t\\t\\t\\tarr[x];\n   | \\t\\t\\t\\t\\t\\t^^^^^^\n\n\",\n            \"message\": \"CHC: Out of bounds access happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 289,\n                \"file\": \"A\",\n                \"start\": 283\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6838\",\n            \"formattedMessage\": \"Warning: BMC: Condition is always true.\n --> A:7:15:\n  |\n7 | \\t\\t\\t\\t\\t\\trequire(x >= 0);\n  | \\t\\t\\t\\t\\t\\t        ^^^^^^\nNote: Callstack:\n\n\",\n            \"message\": \"BMC: Condition is always true.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Callstack:\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 165,\n                \"file\": \"A\",\n                \"start\": 159\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_default_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_default_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6838\",\n            \"formattedMessage\": \"Warning: BMC: Condition is always true.\n --> A:7:15:\n  |\n7 | \\t\\t\\t\\t\\t\\trequire(x >= 0);\n  | \\t\\t\\t\\t\\t\\t        ^^^^^^\nNote: Callstack:\n\n\",\n            \"message\": \"BMC: Condition is always true.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Callstack:\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 165,\n                \"file\": \"A\",\n                \"start\": 159\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"3046\",\n            \"formattedMessage\": \"Warning: BMC: Division by zero happens here.\n  --> A:10:7:\n   |\n10 | \\t\\t\\t\\t\\t\\t2 / x;\n   | \\t\\t\\t\\t\\t\\t^^^^^\nNote: Counterexample:\n  <result> = 0\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Division by zero happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  <result> = 0\n  a = 0\n  x = 0\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 216,\n                \"file\": \"A\",\n                \"start\": 211\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1236\",\n            \"formattedMessage\": \"Warning: BMC: Insufficient funds happens here.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Insufficient funds happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  a = 0\n  x = 0\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 237,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4661\",\n            \"formattedMessage\": \"Warning: BMC: Assertion violation happens here.\n  --> A:12:7:\n   |\n12 | \\t\\t\\t\\t\\t\\tassert(x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Assertion violation happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  a = 0\n  x = 0\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 258,\n                \"file\": \"A\",\n                \"start\": 245\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_default_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_default_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4281\",\n            \"formattedMessage\": \"Warning: CHC: Division by zero happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> A:10:7:\n   |\n10 | \\t\\t\\t\\t\\t\\t2 / x;\n   | \\t\\t\\t\\t\\t\\t^^^^^\n\n\",\n            \"message\": \"CHC: Division by zero happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 216,\n                \"file\": \"A\",\n                \"start\": 211\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> A:12:7:\n   |\n12 | \\t\\t\\t\\t\\t\\tassert(x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 258,\n                \"file\": \"A\",\n                \"start\": 245\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2529\",\n            \"formattedMessage\": \"Warning: CHC: Empty array \\\"pop\\\" happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> A:13:7:\n   |\n13 | \\t\\t\\t\\t\\t\\tarr.pop();\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Empty array \\\"pop\\\" happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 275,\n                \"file\": \"A\",\n                \"start\": 266\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6368\",\n            \"formattedMessage\": \"Warning: CHC: Out of bounds access happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> A:14:7:\n   |\n14 | \\t\\t\\t\\t\\t\\tarr[x];\n   | \\t\\t\\t\\t\\t\\t^^^^^^\n\n\",\n            \"message\": \"CHC: Out of bounds access happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 289,\n                \"file\": \"A\",\n                \"start\": 283\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_div_by_zero_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"targets\": [\"divByZero\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_div_by_zero_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"3046\",\n            \"formattedMessage\": \"Warning: BMC: Division by zero happens here.\n  --> A:10:7:\n   |\n10 | \\t\\t\\t\\t\\t\\t2 / x;\n   | \\t\\t\\t\\t\\t\\t^^^^^\nNote: Counterexample:\n  <result> = 0\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Division by zero happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  <result> = 0\n  a = 0\n  x = 0\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 216,\n                \"file\": \"A\",\n                \"start\": 211\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_div_by_zero_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"targets\": [\"divByZero\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_div_by_zero_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4281\",\n            \"formattedMessage\": \"Warning: CHC: Division by zero happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n  --> A:10:7:\n   |\n10 | \\t\\t\\t\\t\\t\\t2 / x;\n   | \\t\\t\\t\\t\\t\\t^^^^^\n\n\",\n            \"message\": \"CHC: Division by zero happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 216,\n                \"file\": \"A\",\n                \"start\": 211\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_empty_array/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"targets\": []\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_empty_array/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.targets must be a non-empty array.\",\n            \"message\": \"settings.modelChecker.targets must be a non-empty array.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_out_of_bounds_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"targets\": [\"outOfBounds\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_out_of_bounds_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_out_of_bounds_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"targets\": [\"outOfBounds\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_out_of_bounds_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6368\",\n            \"formattedMessage\": \"Warning: CHC: Out of bounds access happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\\\"\\\") -- untrusted external call\n  --> A:15:7:\n   |\n15 | \\t\\t\\t\\t\\t\\tarr[x];\n   | \\t\\t\\t\\t\\t\\t^^^^^^\n\n\",\n            \"message\": \"CHC: Out of bounds access happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\\\"\\\") -- untrusted external call\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 339,\n                \"file\": \"A\",\n                \"start\": 333\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_overflow_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"targets\": [\"overflow\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_overflow_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2661\",\n            \"formattedMessage\": \"Warning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n --> A:9:7:\n  |\n9 | \\t\\t\\t\\t\\t\\tx + type(uint).max;\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^^^^\nNote: Counterexample:\n  <result> = 2**256\n  a = 0\n  x = 1\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  <result> = 2**256\n  a = 0\n  x = 1\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 203,\n                \"file\": \"A\",\n                \"start\": 185\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_overflow_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"targets\": [\"overflow\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_overflow_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4984\",\n            \"formattedMessage\": \"Warning: CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 1\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 2)\n --> A:9:7:\n  |\n9 | \\t\\t\\t\\t\\t\\tx + type(uint).max;\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 1\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 2)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 203,\n                \"file\": \"A\",\n                \"start\": 185\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_pop_empty_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"targets\": [\"popEmptyArray\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_pop_empty_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_pop_empty_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"targets\": [\"popEmptyArray\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_pop_empty_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2529\",\n            \"formattedMessage\": \"Warning: CHC: Empty array \\\"pop\\\" happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\\\"\\\") -- untrusted external call\n  --> A:14:7:\n   |\n14 | \\t\\t\\t\\t\\t\\tarr.pop();\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Empty array \\\"pop\\\" happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\\\"\\\") -- untrusted external call\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 325,\n                \"file\": \"A\",\n                \"start\": 316\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"targets\": [\"underflow\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4144\",\n            \"formattedMessage\": \"Warning: BMC: Underflow (resulting value less than 0) happens here.\n --> A:8:7:\n  |\n8 | \\t\\t\\t\\t\\t\\t--x;\n  | \\t\\t\\t\\t\\t\\t^^^\nNote: Counterexample:\n  <result> = (- 1)\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Underflow (resulting value less than 0) happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  <result> = (- 1)\n  a = 0\n  x = 0\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 177,\n                \"file\": \"A\",\n                \"start\": 174\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"targets\": [\"underflow\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"3944\",\n            \"formattedMessage\": \"Warning: CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 0)\n --> A:8:7:\n  |\n8 | \\t\\t\\t\\t\\t\\t--x;\n  | \\t\\t\\t\\t\\t\\t^^^\n\n\",\n            \"message\": \"CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 177,\n                \"file\": \"A\",\n                \"start\": 174\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"targets\": [\"underflow\", \"overflow\", \"assert\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4144\",\n            \"formattedMessage\": \"Warning: BMC: Underflow (resulting value less than 0) happens here.\n --> A:8:7:\n  |\n8 | \\t\\t\\t\\t\\t\\t--x;\n  | \\t\\t\\t\\t\\t\\t^^^\nNote: Counterexample:\n  <result> = (- 1)\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Underflow (resulting value less than 0) happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  <result> = (- 1)\n  a = 0\n  x = 0\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 177,\n                \"file\": \"A\",\n                \"start\": 174\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2661\",\n            \"formattedMessage\": \"Warning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n --> A:9:7:\n  |\n9 | \\t\\t\\t\\t\\t\\tx + type(uint).max;\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^^^^\nNote: Counterexample:\n  <result> = 2**256\n  a = 0\n  x = 1\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  <result> = 2**256\n  a = 0\n  x = 1\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 203,\n                \"file\": \"A\",\n                \"start\": 185\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4661\",\n            \"formattedMessage\": \"Warning: BMC: Assertion violation happens here.\n  --> A:12:7:\n   |\n12 | \\t\\t\\t\\t\\t\\tassert(x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\nNote: Counterexample:\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Assertion violation happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  a = 0\n  x = 0\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 258,\n                \"file\": \"A\",\n                \"start\": 245\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"targets\": [\"underflow\", \"overflow\", \"assert\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_overflow_assert_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"3944\",\n            \"formattedMessage\": \"Warning: CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 0)\n --> A:8:7:\n  |\n8 | \\t\\t\\t\\t\\t\\t--x;\n  | \\t\\t\\t\\t\\t\\t^^^\n\n\",\n            \"message\": \"CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 177,\n                \"file\": \"A\",\n                \"start\": 174\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4984\",\n            \"formattedMessage\": \"Warning: CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 1\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 2)\n --> A:9:7:\n  |\n9 | \\t\\t\\t\\t\\t\\tx + type(uint).max;\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 1\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 2)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 203,\n                \"file\": \"A\",\n                \"start\": 185\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6328\",\n            \"formattedMessage\": \"Warning: CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\\\"\\\") -- untrusted external call\n  --> A:13:7:\n   |\n13 | \\t\\t\\t\\t\\t\\tassert(x > 0);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Assertion violation happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = true\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 1)\n    a.call{value: x}(\\\"\\\") -- untrusted external call\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 308,\n                \"file\": \"A\",\n                \"start\": 295\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_overflow_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\ta.transfer(x);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"targets\": [\"underflow\", \"overflow\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_overflow_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"9207\",\n            \"formattedMessage\": \"Warning: 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\n  --> A:11:7:\n   |\n11 | \\t\\t\\t\\t\\t\\ta.transfer(x);\n   | \\t\\t\\t\\t\\t\\t^^^^^^^^^^\n\n\",\n            \"message\": \"'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\\\"\\\")' instead.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 234,\n                \"file\": \"A\",\n                \"start\": 224\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4144\",\n            \"formattedMessage\": \"Warning: BMC: Underflow (resulting value less than 0) happens here.\n --> A:8:7:\n  |\n8 | \\t\\t\\t\\t\\t\\t--x;\n  | \\t\\t\\t\\t\\t\\t^^^\nNote: Counterexample:\n  <result> = (- 1)\n  a = 0\n  x = 0\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Underflow (resulting value less than 0) happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  <result> = (- 1)\n  a = 0\n  x = 0\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 177,\n                \"file\": \"A\",\n                \"start\": 174\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2661\",\n            \"formattedMessage\": \"Warning: BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n --> A:9:7:\n  |\n9 | \\t\\t\\t\\t\\t\\tx + type(uint).max;\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^^^^\nNote: Counterexample:\n  <result> = 2**256\n  a = 0\n  x = 1\n\nNote: Callstack:\nNote:\n\n\",\n            \"message\": \"BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"message\": \"Counterexample:\n  <result> = 2**256\n  a = 0\n  x = 1\n\"\n                },\n                {\n                    \"message\": \"Callstack:\"\n                },\n                {\n                    \"message\": \"\"\n                }\n            ],\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 203,\n                \"file\": \"A\",\n                \"start\": 185\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_overflow_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"targets\": [\"underflow\", \"overflow\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_underflow_overflow_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"3944\",\n            \"formattedMessage\": \"Warning: CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 0)\n --> A:8:7:\n  |\n8 | \\t\\t\\t\\t\\t\\t--x;\n  | \\t\\t\\t\\t\\t\\t^^^\n\n\",\n            \"message\": \"CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 0\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 0)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 177,\n                \"file\": \"A\",\n                \"start\": 174\n            },\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"4984\",\n            \"formattedMessage\": \"Warning: CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 1\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 2)\n --> A:9:7:\n  |\n9 | \\t\\t\\t\\t\\t\\tx + type(uint).max;\n  | \\t\\t\\t\\t\\t\\t^^^^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\narr = []\na = 0x0\nx = 1\nsuccess = false\n\nTransaction trace:\ntest.constructor()\nState: arr = []\ntest.f(0x0, 2)\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 203,\n                \"file\": \"A\",\n                \"start\": 185\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_wrong_target_types/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"targets\": [2]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_wrong_target_types/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Every target in settings.modelChecker.targets must be a string.\",\n            \"message\": \"Every target in settings.modelChecker.targets must be a string.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_wrong_target_types_2/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"targets\": \"assert\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_wrong_target_types_2/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.targets must be an array.\",\n            \"message\": \"settings.modelChecker.targets must be an array.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_wrong_targets/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\n\t\t\t\t\tuint[] arr;\n\t\t\t\t\tfunction f(address payable a, uint x) public {\n\t\t\t\t\t\trequire(x >= 0);\n\t\t\t\t\t\t--x;\n\t\t\t\t\t\tx + type(uint).max;\n\t\t\t\t\t\t2 / x;\n\t\t\t\t\t\t(bool success, ) = a.call{value: x}(\\\"\\\");\n\t\t\t\t\t\trequire(success);\n\t\t\t\t\t\tassert(x > 0);\n\t\t\t\t\t\tarr.pop();\n\t\t\t\t\t\tarr[x];\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"targets\": [\"aaa\", \"bbb\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_targets_wrong_targets/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid model checker targets requested.\",\n            \"message\": \"Invalid model checker targets requested.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_timeout_all/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\\nfunction f(uint x, uint y, uint k) public pure {\\nrequire(k > 0); require(x % k == 0); require(y % k == 0); uint r = mulmod(x, y, k); assert(r % k == 0);}}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"timeout\": 1000\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_timeout_all/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5840\",\n            \"formattedMessage\": \"Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 4 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 4 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2788\",\n            \"formattedMessage\": \"Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"BMC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_timeout_bmc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\\nfunction f(uint x, uint y, uint k) public pure {\\nrequire(k > 0); require(x % k == 0); require(y % k == 0); uint r = mulmod(x, y, k); assert(r % k == 0);}}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"bmc\",\n\t\t\t\"timeout\": 1000\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_timeout_bmc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2788\",\n            \"formattedMessage\": \"Warning: BMC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"BMC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6002\",\n            \"formattedMessage\": \"Info: BMC: 4 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"BMC: 4 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_timeout_chc/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {\\nfunction f(uint x, uint y, uint k) public pure {\\nrequire(k > 0); require(x % k == 0); require(y % k == 0); uint r = mulmod(x, y, k); assert(r % k == 0);}}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"timeout\": 1000\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_timeout_chc/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"5840\",\n            \"formattedMessage\": \"Warning: CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\n\n\",\n            \"message\": \"CHC: 1 verification condition(s) could not be proved. Enable the model checker option \\\"show unproved\\\" to see all of them. Consider choosing a specific contract to be verified in order to reduce the solving problems. Consider increasing the timeout per query.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        },\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1391\",\n            \"formattedMessage\": \"Info: CHC: 4 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\n\n\",\n            \"message\": \"CHC: 4 verification condition(s) proved safe! Enable the model checker option \\\"show proved safe\\\" to see all of them.\",\n            \"severity\": \"info\",\n            \"type\": \"Info\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_timeout_wrong_key/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C { function f(uint x) public pure { assert(x > 0); } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"chc\",\n\t\t\t\"atimeout\": 1\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_timeout_wrong_key/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Unknown key \\\"atimeout\\\"\",\n            \"message\": \"Unknown key \\\"atimeout\\\"\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_timeout_wrong_value/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract C { function f(uint x) public pure { assert(x > 0); } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"modelChecker\":\n\t\t{\n\t\t\t\"engine\": \"all\",\n\t\t\t\"timeout\": \"asd\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_model_checker_timeout_wrong_value/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"settings.modelChecker.timeout must be an unsigned integer.\",\n            \"message\": \"settings.modelChecker.timeout must be an unsigned integer.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_no_append_cbor/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"viaIR\": true,\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true\n\t\t},\n\t\t\"metadata\":\n\t\t{\n\t\t\t\"appendCBOR\": false\n\t\t},\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"A\":\n\t\t\t{\n\t\t\t\t\"test\": [\"evm.bytecode\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_no_append_cbor/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"test\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"generatedSources\": [],\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\n\\ncontract test {}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"viaIR\": true,\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true\n\t\t},\n\t\t\"metadata\":\n\t\t{\n\t\t\t\"appendCBOR\": false,\n\t\t\t\"bytecodeHash\": \"ipfs\"\n\t\t},\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"A\":\n\t\t\t{\n\t\t\t\t\"test\": [\"evm.bytecode\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_no_append_cbor_with_metadata_hash/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"When the parameter \\\"appendCBOR\\\" is set to false, the parameter \\\"bytecodeHash\\\" cannot be set to \\\"ipfs\\\". The parameter \\\"bytecodeHash\\\" should either be skipped, or set to \\\"none\\\".\",\n            \"message\": \"When the parameter \\\"appendCBOR\\\" is set to false, the parameter \\\"bytecodeHash\\\" cannot be set to \\\"ipfs\\\". The parameter \\\"bytecodeHash\\\" should either be skipped, or set to \\\"none\\\".\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_no_import_callback/B.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n"
  },
  {
    "path": "test/cmdlineTests/standard_no_import_callback/args",
    "content": "--no-import-callback\n"
  },
  {
    "path": "test/cmdlineTests/standard_no_import_callback/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\n            \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; import 'standard_no_import_callback/B.sol';\"\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_no_import_callback/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"6275\",\n            \"formattedMessage\": \"ParserError: Source \\\"standard_no_import_callback/B.sol\\\" not found: No import callback.\n --> A:2:24:\n  |\n2 | pragma solidity >=0.0; import 'standard_no_import_callback/B.sol';\n  |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"Source \\\"standard_no_import_callback/B.sol\\\" not found: No import callback.\",\n            \"severity\": \"error\",\n            \"sourceLocation\": {\n                \"end\": 102,\n                \"file\": \"A\",\n                \"start\": 59\n            },\n            \"type\": \"ParserError\"\n        }\n    ],\n    \"sources\": {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_non_utf8_filename/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"ir\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_non_utf8_filename/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"parse error at line 5, column 4: syntax error while parsing object key - invalid string: ill-formed UTF-8 byte; last read: '\\\"\\\\xff'; expected string literal\",\n            \"message\": \"parse error at line 5, column 4: syntax error while parsing object key - invalid string: ill-formed UTF-8 byte; last read: '\\\"\\\\xff'; expected string literal\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_non_utf8_filename2/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"ir\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_non_utf8_filename2/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"parse error at line 5, column 4: syntax error while parsing object key - invalid string: ill-formed UTF-8 byte; last read: '\\\"\\\\xff'; expected string literal\",\n            \"message\": \"parse error at line 5, column 4: syntax error while parsing object key - invalid string: ill-formed UTF-8 byte; last read: '\\\"\\\\xff'; expected string literal\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_only_ast_requested/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"\": [\"ast\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_only_ast_requested/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"ast\": {\n                \"absolutePath\": \"A\",\n                \"exportedSymbols\": {\n                    \"C\": [\n                        6\n                    ]\n                },\n                \"id\": 7,\n                \"license\": \"GPL-3.0\",\n                \"nodeType\": \"SourceUnit\",\n                \"nodes\": [\n                    {\n                        \"id\": 1,\n                        \"literals\": [\n                            \"solidity\",\n                            \">=\",\n                            \"0.0\"\n                        ],\n                        \"nodeType\": \"PragmaDirective\",\n                        \"src\": \"36:22:0\"\n                    },\n                    {\n                        \"abstract\": false,\n                        \"baseContracts\": [],\n                        \"canonicalName\": \"C\",\n                        \"contractDependencies\": [],\n                        \"contractKind\": \"contract\",\n                        \"fullyImplemented\": true,\n                        \"id\": 6,\n                        \"linearizedBaseContracts\": [\n                            6\n                        ],\n                        \"name\": \"C\",\n                        \"nameLocation\": \"68:1:0\",\n                        \"nodeType\": \"ContractDefinition\",\n                        \"nodes\": [\n                            {\n                                \"body\": {\n                                    \"id\": 4,\n                                    \"nodeType\": \"Block\",\n                                    \"src\": \"97:2:0\",\n                                    \"statements\": []\n                                },\n                                \"functionSelector\": \"26121ff0\",\n                                \"id\": 5,\n                                \"implemented\": true,\n                                \"kind\": \"function\",\n                                \"modifiers\": [],\n                                \"name\": \"f\",\n                                \"nameLocation\": \"81:1:0\",\n                                \"nodeType\": \"FunctionDefinition\",\n                                \"parameters\": {\n                                    \"id\": 2,\n                                    \"nodeType\": \"ParameterList\",\n                                    \"parameters\": [],\n                                    \"src\": \"82:2:0\"\n                                },\n                                \"returnParameters\": {\n                                    \"id\": 3,\n                                    \"nodeType\": \"ParameterList\",\n                                    \"parameters\": [],\n                                    \"src\": \"97:0:0\"\n                                },\n                                \"scope\": 6,\n                                \"src\": \"72:27:0\",\n                                \"stateMutability\": \"pure\",\n                                \"virtual\": false,\n                                \"visibility\": \"public\"\n                            }\n                        ],\n                        \"scope\": 7,\n                        \"src\": \"59:42:0\",\n                        \"usedErrors\": [],\n                        \"usedEvents\": []\n                    }\n                ],\n                \"src\": \"36:65:0\"\n            },\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_generatedSources/input.json",
    "content": "{\n \"language\": \"Solidity\",\n \"sources\": {\n  \"a.sol\": {\n   \"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\npragma abicoder v2; contract A { function f(uint[] memory) public view returns (uint256) { } }\"\n  }\n },\n \"settings\": {\n  \"evmVersion\": \"petersburg\",\n  \"optimizer\": { \"enabled\": true },\n  \"outputSelection\": {\n   \"*\": {\n    \"A\": [\n     \"evm.bytecode.object\",\n     \"evm.deployedBytecode.generatedSources\",\n     \"evm.bytecode.generatedSources\"\n    ]\n   }\n  }\n }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_generatedSources/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"generatedSources\": [],\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"generatedSources\": [\n                            {\n                                \"ast\": {\n                                    \"nativeSrc\": \"0:1505:1\",\n                                    \"nodeType\": \"YulBlock\",\n                                    \"src\": \"0:1505:1\",\n                                    \"statements\": [\n                                        {\n                                            \"nativeSrc\": \"6:3:1\",\n                                            \"nodeType\": \"YulBlock\",\n                                            \"src\": \"6:3:1\",\n                                            \"statements\": []\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"46:95:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"46:95:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"63:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"63:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                },\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"kind\": \"number\",\n                                                                            \"nativeSrc\": \"70:3:1\",\n                                                                            \"nodeType\": \"YulLiteral\",\n                                                                            \"src\": \"70:3:1\",\n                                                                            \"type\": \"\",\n                                                                            \"value\": \"224\"\n                                                                        },\n                                                                        {\n                                                                            \"kind\": \"number\",\n                                                                            \"nativeSrc\": \"75:10:1\",\n                                                                            \"nodeType\": \"YulLiteral\",\n                                                                            \"src\": \"75:10:1\",\n                                                                            \"type\": \"\",\n                                                                            \"value\": \"0x4e487b71\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"shl\",\n                                                                        \"nativeSrc\": \"66:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"66:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"66:20:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"66:20:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mstore\",\n                                                                \"nativeSrc\": \"56:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"56:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"56:31:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"56:31:1\"\n                                                        },\n                                                        \"nativeSrc\": \"56:31:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"56:31:1\"\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"103:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"103:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"4\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"106:4:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"106:4:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0x41\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mstore\",\n                                                                \"nativeSrc\": \"96:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"96:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"96:15:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"96:15:1\"\n                                                        },\n                                                        \"nativeSrc\": \"96:15:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"96:15:1\"\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"127:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"127:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"130:4:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"130:4:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0x24\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"revert\",\n                                                                \"nativeSrc\": \"120:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"120:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"120:15:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"120:15:1\"\n                                                        },\n                                                        \"nativeSrc\": \"120:15:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"120:15:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"panic_error_0x41\",\n                                            \"nativeSrc\": \"14:127:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"src\": \"14:127:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"241:1080:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"241:1080:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"287:16:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"287:16:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"296:1:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"296:1:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0\"\n                                                                            },\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"299:1:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"299:1:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"revert\",\n                                                                            \"nativeSrc\": \"289:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"289:6:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"289:12:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"289:12:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"289:12:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"289:12:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"dataEnd\",\n                                                                            \"nativeSrc\": \"262:7:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"262:7:1\"\n                                                                        },\n                                                                        {\n                                                                            \"name\": \"headStart\",\n                                                                            \"nativeSrc\": \"271:9:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"271:9:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"sub\",\n                                                                        \"nativeSrc\": \"258:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"258:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"258:23:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"258:23:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"283:2:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"283:2:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"32\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"slt\",\n                                                                \"nativeSrc\": \"254:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"254:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"254:32:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"254:32:1\"\n                                                        },\n                                                        \"nativeSrc\": \"251:52:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"251:52:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"312:37:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"312:37:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"headStart\",\n                                                                    \"nativeSrc\": \"339:9:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"339:9:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"calldataload\",\n                                                                \"nativeSrc\": \"326:12:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"326:12:1\"\n                                                            },\n                                                            \"nativeSrc\": \"326:23:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"326:23:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"offset\",\n                                                                \"nativeSrc\": \"316:6:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"316:6:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"392:16:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"392:16:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"401:1:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"401:1:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0\"\n                                                                            },\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"404:1:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"404:1:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"revert\",\n                                                                            \"nativeSrc\": \"394:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"394:6:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"394:12:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"394:12:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"394:12:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"394:12:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"offset\",\n                                                                    \"nativeSrc\": \"364:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"364:6:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"372:18:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"372:18:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0xffffffffffffffff\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"gt\",\n                                                                \"nativeSrc\": \"361:2:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"361:2:1\"\n                                                            },\n                                                            \"nativeSrc\": \"361:30:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"361:30:1\"\n                                                        },\n                                                        \"nativeSrc\": \"358:50:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"358:50:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"417:32:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"417:32:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"headStart\",\n                                                                    \"nativeSrc\": \"431:9:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"431:9:1\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"offset\",\n                                                                    \"nativeSrc\": \"442:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"442:6:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"add\",\n                                                                \"nativeSrc\": \"427:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"427:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"427:22:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"427:22:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"_1\",\n                                                                \"nativeSrc\": \"421:2:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"421:2:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"497:16:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"497:16:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"506:1:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"506:1:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0\"\n                                                                            },\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"509:1:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"509:1:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"revert\",\n                                                                            \"nativeSrc\": \"499:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"499:6:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"499:12:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"499:12:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"499:12:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"499:12:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"arguments\": [\n                                                                                {\n                                                                                    \"name\": \"_1\",\n                                                                                    \"nativeSrc\": \"476:2:1\",\n                                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                                    \"src\": \"476:2:1\"\n                                                                                },\n                                                                                {\n                                                                                    \"kind\": \"number\",\n                                                                                    \"nativeSrc\": \"480:4:1\",\n                                                                                    \"nodeType\": \"YulLiteral\",\n                                                                                    \"src\": \"480:4:1\",\n                                                                                    \"type\": \"\",\n                                                                                    \"value\": \"0x1f\"\n                                                                                }\n                                                                            ],\n                                                                            \"functionName\": {\n                                                                                \"name\": \"add\",\n                                                                                \"nativeSrc\": \"472:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"472:3:1\"\n                                                                            },\n                                                                            \"nativeSrc\": \"472:13:1\",\n                                                                            \"nodeType\": \"YulFunctionCall\",\n                                                                            \"src\": \"472:13:1\"\n                                                                        },\n                                                                        {\n                                                                            \"name\": \"dataEnd\",\n                                                                            \"nativeSrc\": \"487:7:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"487:7:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"slt\",\n                                                                        \"nativeSrc\": \"468:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"468:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"468:27:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"468:27:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"iszero\",\n                                                                \"nativeSrc\": \"461:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"461:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"461:35:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"461:35:1\"\n                                                        },\n                                                        \"nativeSrc\": \"458:55:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"458:55:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"522:30:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"522:30:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"_1\",\n                                                                    \"nativeSrc\": \"549:2:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"549:2:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"calldataload\",\n                                                                \"nativeSrc\": \"536:12:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"536:12:1\"\n                                                            },\n                                                            \"nativeSrc\": \"536:16:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"536:16:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"length\",\n                                                                \"nativeSrc\": \"526:6:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"526:6:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"595:22:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"595:22:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"panic_error_0x41\",\n                                                                            \"nativeSrc\": \"597:16:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"597:16:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"597:18:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"597:18:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"597:18:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"597:18:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"length\",\n                                                                    \"nativeSrc\": \"567:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"567:6:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"575:18:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"575:18:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"0xffffffffffffffff\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"gt\",\n                                                                \"nativeSrc\": \"564:2:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"564:2:1\"\n                                                            },\n                                                            \"nativeSrc\": \"564:30:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"564:30:1\"\n                                                        },\n                                                        \"nativeSrc\": \"561:56:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"561:56:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"626:24:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"626:24:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"640:1:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"640:1:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"5\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"length\",\n                                                                    \"nativeSrc\": \"643:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"643:6:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"shl\",\n                                                                \"nativeSrc\": \"636:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"636:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"636:14:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"636:14:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"_2\",\n                                                                \"nativeSrc\": \"630:2:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"630:2:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"659:23:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"659:23:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"679:2:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"679:2:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"64\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mload\",\n                                                                \"nativeSrc\": \"673:5:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"673:5:1\"\n                                                            },\n                                                            \"nativeSrc\": \"673:9:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"673:9:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"memPtr\",\n                                                                \"nativeSrc\": \"663:6:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"663:6:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"691:56:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"691:56:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"memPtr\",\n                                                                    \"nativeSrc\": \"713:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"713:6:1\"\n                                                                },\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"arguments\": [\n                                                                                {\n                                                                                    \"name\": \"_2\",\n                                                                                    \"nativeSrc\": \"729:2:1\",\n                                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                                    \"src\": \"729:2:1\"\n                                                                                },\n                                                                                {\n                                                                                    \"kind\": \"number\",\n                                                                                    \"nativeSrc\": \"733:2:1\",\n                                                                                    \"nodeType\": \"YulLiteral\",\n                                                                                    \"src\": \"733:2:1\",\n                                                                                    \"type\": \"\",\n                                                                                    \"value\": \"63\"\n                                                                                }\n                                                                            ],\n                                                                            \"functionName\": {\n                                                                                \"name\": \"add\",\n                                                                                \"nativeSrc\": \"725:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"725:3:1\"\n                                                                            },\n                                                                            \"nativeSrc\": \"725:11:1\",\n                                                                            \"nodeType\": \"YulFunctionCall\",\n                                                                            \"src\": \"725:11:1\"\n                                                                        },\n                                                                        {\n                                                                            \"arguments\": [\n                                                                                {\n                                                                                    \"kind\": \"number\",\n                                                                                    \"nativeSrc\": \"742:2:1\",\n                                                                                    \"nodeType\": \"YulLiteral\",\n                                                                                    \"src\": \"742:2:1\",\n                                                                                    \"type\": \"\",\n                                                                                    \"value\": \"31\"\n                                                                                }\n                                                                            ],\n                                                                            \"functionName\": {\n                                                                                \"name\": \"not\",\n                                                                                \"nativeSrc\": \"738:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"738:3:1\"\n                                                                            },\n                                                                            \"nativeSrc\": \"738:7:1\",\n                                                                            \"nodeType\": \"YulFunctionCall\",\n                                                                            \"src\": \"738:7:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"and\",\n                                                                        \"nativeSrc\": \"721:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"721:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"721:25:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"721:25:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"add\",\n                                                                \"nativeSrc\": \"709:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"709:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"709:38:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"709:38:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"newFreePtr\",\n                                                                \"nativeSrc\": \"695:10:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"695:10:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"822:22:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"822:22:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"panic_error_0x41\",\n                                                                            \"nativeSrc\": \"824:16:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"824:16:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"824:18:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"824:18:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"824:18:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"824:18:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"newFreePtr\",\n                                                                            \"nativeSrc\": \"765:10:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"765:10:1\"\n                                                                        },\n                                                                        {\n                                                                            \"kind\": \"number\",\n                                                                            \"nativeSrc\": \"777:18:1\",\n                                                                            \"nodeType\": \"YulLiteral\",\n                                                                            \"src\": \"777:18:1\",\n                                                                            \"type\": \"\",\n                                                                            \"value\": \"0xffffffffffffffff\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"gt\",\n                                                                        \"nativeSrc\": \"762:2:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"762:2:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"762:34:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"762:34:1\"\n                                                                },\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"newFreePtr\",\n                                                                            \"nativeSrc\": \"801:10:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"801:10:1\"\n                                                                        },\n                                                                        {\n                                                                            \"name\": \"memPtr\",\n                                                                            \"nativeSrc\": \"813:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"813:6:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"lt\",\n                                                                        \"nativeSrc\": \"798:2:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"798:2:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"798:22:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"798:22:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"or\",\n                                                                \"nativeSrc\": \"759:2:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"759:2:1\"\n                                                            },\n                                                            \"nativeSrc\": \"759:62:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"759:62:1\"\n                                                        },\n                                                        \"nativeSrc\": \"756:88:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"756:88:1\"\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"860:2:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"860:2:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"64\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"newFreePtr\",\n                                                                    \"nativeSrc\": \"864:10:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"864:10:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mstore\",\n                                                                \"nativeSrc\": \"853:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"853:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"853:22:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"853:22:1\"\n                                                        },\n                                                        \"nativeSrc\": \"853:22:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"853:22:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"884:17:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"884:17:1\",\n                                                        \"value\": {\n                                                            \"name\": \"memPtr\",\n                                                            \"nativeSrc\": \"895:6:1\",\n                                                            \"nodeType\": \"YulIdentifier\",\n                                                            \"src\": \"895:6:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"dst\",\n                                                                \"nativeSrc\": \"888:3:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"888:3:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"memPtr\",\n                                                                    \"nativeSrc\": \"917:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"917:6:1\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"length\",\n                                                                    \"nativeSrc\": \"925:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"925:6:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mstore\",\n                                                                \"nativeSrc\": \"910:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"910:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"910:22:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"910:22:1\"\n                                                        },\n                                                        \"nativeSrc\": \"910:22:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"910:22:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"941:22:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"941:22:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"memPtr\",\n                                                                    \"nativeSrc\": \"952:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"952:6:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"960:2:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"960:2:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"32\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"add\",\n                                                                \"nativeSrc\": \"948:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"948:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"948:15:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"948:15:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"dst\",\n                                                                \"nativeSrc\": \"941:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"941:3:1\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"972:34:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"972:34:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"arguments\": [\n                                                                        {\n                                                                            \"name\": \"_1\",\n                                                                            \"nativeSrc\": \"994:2:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"994:2:1\"\n                                                                        },\n                                                                        {\n                                                                            \"name\": \"_2\",\n                                                                            \"nativeSrc\": \"998:2:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"998:2:1\"\n                                                                        }\n                                                                    ],\n                                                                    \"functionName\": {\n                                                                        \"name\": \"add\",\n                                                                        \"nativeSrc\": \"990:3:1\",\n                                                                        \"nodeType\": \"YulIdentifier\",\n                                                                        \"src\": \"990:3:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"990:11:1\",\n                                                                    \"nodeType\": \"YulFunctionCall\",\n                                                                    \"src\": \"990:11:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1003:2:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"1003:2:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"32\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"add\",\n                                                                \"nativeSrc\": \"986:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"986:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"986:20:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"986:20:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"srcEnd\",\n                                                                \"nativeSrc\": \"976:6:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"976:6:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"1038:16:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"1038:16:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"1047:1:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"1047:1:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0\"\n                                                                            },\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"1050:1:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"1050:1:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"0\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"revert\",\n                                                                            \"nativeSrc\": \"1040:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"1040:6:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"1040:12:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"1040:12:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"1040:12:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"1040:12:1\"\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"srcEnd\",\n                                                                    \"nativeSrc\": \"1021:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1021:6:1\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"dataEnd\",\n                                                                    \"nativeSrc\": \"1029:7:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1029:7:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"gt\",\n                                                                \"nativeSrc\": \"1018:2:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1018:2:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1018:19:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1018:19:1\"\n                                                        },\n                                                        \"nativeSrc\": \"1015:39:1\",\n                                                        \"nodeType\": \"YulIf\",\n                                                        \"src\": \"1015:39:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"1063:22:1\",\n                                                        \"nodeType\": \"YulVariableDeclaration\",\n                                                        \"src\": \"1063:22:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"_1\",\n                                                                    \"nativeSrc\": \"1078:2:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1078:2:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1082:2:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"1082:2:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"32\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"add\",\n                                                                \"nativeSrc\": \"1074:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1074:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1074:11:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1074:11:1\"\n                                                        },\n                                                        \"variables\": [\n                                                            {\n                                                                \"name\": \"src\",\n                                                                \"nativeSrc\": \"1067:3:1\",\n                                                                \"nodeType\": \"YulTypedName\",\n                                                                \"src\": \"1067:3:1\",\n                                                                \"type\": \"\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"body\": {\n                                                            \"nativeSrc\": \"1150:140:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"1150:140:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"nativeSrc\": \"1164:14:1\",\n                                                                    \"nodeType\": \"YulVariableDeclaration\",\n                                                                    \"src\": \"1164:14:1\",\n                                                                    \"value\": {\n                                                                        \"kind\": \"number\",\n                                                                        \"nativeSrc\": \"1177:1:1\",\n                                                                        \"nodeType\": \"YulLiteral\",\n                                                                        \"src\": \"1177:1:1\",\n                                                                        \"type\": \"\",\n                                                                        \"value\": \"0\"\n                                                                    },\n                                                                    \"variables\": [\n                                                                        {\n                                                                            \"name\": \"value\",\n                                                                            \"nativeSrc\": \"1168:5:1\",\n                                                                            \"nodeType\": \"YulTypedName\",\n                                                                            \"src\": \"1168:5:1\",\n                                                                            \"type\": \"\"\n                                                                        }\n                                                                    ]\n                                                                },\n                                                                {\n                                                                    \"nativeSrc\": \"1191:26:1\",\n                                                                    \"nodeType\": \"YulAssignment\",\n                                                                    \"src\": \"1191:26:1\",\n                                                                    \"value\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"name\": \"src\",\n                                                                                \"nativeSrc\": \"1213:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"1213:3:1\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"calldataload\",\n                                                                            \"nativeSrc\": \"1200:12:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"1200:12:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"1200:17:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"1200:17:1\"\n                                                                    },\n                                                                    \"variableNames\": [\n                                                                        {\n                                                                            \"name\": \"value\",\n                                                                            \"nativeSrc\": \"1191:5:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"1191:5:1\"\n                                                                        }\n                                                                    ]\n                                                                },\n                                                                {\n                                                                    \"expression\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"name\": \"dst\",\n                                                                                \"nativeSrc\": \"1237:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"1237:3:1\"\n                                                                            },\n                                                                            {\n                                                                                \"name\": \"value\",\n                                                                                \"nativeSrc\": \"1242:5:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"1242:5:1\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"mstore\",\n                                                                            \"nativeSrc\": \"1230:6:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"1230:6:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"1230:18:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"1230:18:1\"\n                                                                    },\n                                                                    \"nativeSrc\": \"1230:18:1\",\n                                                                    \"nodeType\": \"YulExpressionStatement\",\n                                                                    \"src\": \"1230:18:1\"\n                                                                },\n                                                                {\n                                                                    \"nativeSrc\": \"1261:19:1\",\n                                                                    \"nodeType\": \"YulAssignment\",\n                                                                    \"src\": \"1261:19:1\",\n                                                                    \"value\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"name\": \"dst\",\n                                                                                \"nativeSrc\": \"1272:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"1272:3:1\"\n                                                                            },\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"1277:2:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"1277:2:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"32\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"add\",\n                                                                            \"nativeSrc\": \"1268:3:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"1268:3:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"1268:12:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"1268:12:1\"\n                                                                    },\n                                                                    \"variableNames\": [\n                                                                        {\n                                                                            \"name\": \"dst\",\n                                                                            \"nativeSrc\": \"1261:3:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"1261:3:1\"\n                                                                        }\n                                                                    ]\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"condition\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"src\",\n                                                                    \"nativeSrc\": \"1105:3:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1105:3:1\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"srcEnd\",\n                                                                    \"nativeSrc\": \"1110:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1110:6:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"lt\",\n                                                                \"nativeSrc\": \"1102:2:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1102:2:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1102:15:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1102:15:1\"\n                                                        },\n                                                        \"nativeSrc\": \"1094:196:1\",\n                                                        \"nodeType\": \"YulForLoop\",\n                                                        \"post\": {\n                                                            \"nativeSrc\": \"1118:23:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"1118:23:1\",\n                                                            \"statements\": [\n                                                                {\n                                                                    \"nativeSrc\": \"1120:19:1\",\n                                                                    \"nodeType\": \"YulAssignment\",\n                                                                    \"src\": \"1120:19:1\",\n                                                                    \"value\": {\n                                                                        \"arguments\": [\n                                                                            {\n                                                                                \"name\": \"src\",\n                                                                                \"nativeSrc\": \"1131:3:1\",\n                                                                                \"nodeType\": \"YulIdentifier\",\n                                                                                \"src\": \"1131:3:1\"\n                                                                            },\n                                                                            {\n                                                                                \"kind\": \"number\",\n                                                                                \"nativeSrc\": \"1136:2:1\",\n                                                                                \"nodeType\": \"YulLiteral\",\n                                                                                \"src\": \"1136:2:1\",\n                                                                                \"type\": \"\",\n                                                                                \"value\": \"32\"\n                                                                            }\n                                                                        ],\n                                                                        \"functionName\": {\n                                                                            \"name\": \"add\",\n                                                                            \"nativeSrc\": \"1127:3:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"1127:3:1\"\n                                                                        },\n                                                                        \"nativeSrc\": \"1127:12:1\",\n                                                                        \"nodeType\": \"YulFunctionCall\",\n                                                                        \"src\": \"1127:12:1\"\n                                                                    },\n                                                                    \"variableNames\": [\n                                                                        {\n                                                                            \"name\": \"src\",\n                                                                            \"nativeSrc\": \"1120:3:1\",\n                                                                            \"nodeType\": \"YulIdentifier\",\n                                                                            \"src\": \"1120:3:1\"\n                                                                        }\n                                                                    ]\n                                                                }\n                                                            ]\n                                                        },\n                                                        \"pre\": {\n                                                            \"nativeSrc\": \"1098:3:1\",\n                                                            \"nodeType\": \"YulBlock\",\n                                                            \"src\": \"1098:3:1\",\n                                                            \"statements\": []\n                                                        },\n                                                        \"src\": \"1094:196:1\"\n                                                    },\n                                                    {\n                                                        \"nativeSrc\": \"1299:16:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"1299:16:1\",\n                                                        \"value\": {\n                                                            \"name\": \"memPtr\",\n                                                            \"nativeSrc\": \"1309:6:1\",\n                                                            \"nodeType\": \"YulIdentifier\",\n                                                            \"src\": \"1309:6:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"value0\",\n                                                                \"nativeSrc\": \"1299:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1299:6:1\"\n                                                            }\n                                                        ]\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"abi_decode_tuple_t_array$_t_uint256_$dyn_memory_ptr\",\n                                            \"nativeSrc\": \"146:1175:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"headStart\",\n                                                    \"nativeSrc\": \"207:9:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"207:9:1\",\n                                                    \"type\": \"\"\n                                                },\n                                                {\n                                                    \"name\": \"dataEnd\",\n                                                    \"nativeSrc\": \"218:7:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"218:7:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"value0\",\n                                                    \"nativeSrc\": \"230:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"230:6:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"146:1175:1\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"nativeSrc\": \"1427:76:1\",\n                                                \"nodeType\": \"YulBlock\",\n                                                \"src\": \"1427:76:1\",\n                                                \"statements\": [\n                                                    {\n                                                        \"nativeSrc\": \"1437:26:1\",\n                                                        \"nodeType\": \"YulAssignment\",\n                                                        \"src\": \"1437:26:1\",\n                                                        \"value\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"headStart\",\n                                                                    \"nativeSrc\": \"1449:9:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1449:9:1\"\n                                                                },\n                                                                {\n                                                                    \"kind\": \"number\",\n                                                                    \"nativeSrc\": \"1460:2:1\",\n                                                                    \"nodeType\": \"YulLiteral\",\n                                                                    \"src\": \"1460:2:1\",\n                                                                    \"type\": \"\",\n                                                                    \"value\": \"32\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"add\",\n                                                                \"nativeSrc\": \"1445:3:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1445:3:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1445:18:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1445:18:1\"\n                                                        },\n                                                        \"variableNames\": [\n                                                            {\n                                                                \"name\": \"tail\",\n                                                                \"nativeSrc\": \"1437:4:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1437:4:1\"\n                                                            }\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"expression\": {\n                                                            \"arguments\": [\n                                                                {\n                                                                    \"name\": \"headStart\",\n                                                                    \"nativeSrc\": \"1479:9:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1479:9:1\"\n                                                                },\n                                                                {\n                                                                    \"name\": \"value0\",\n                                                                    \"nativeSrc\": \"1490:6:1\",\n                                                                    \"nodeType\": \"YulIdentifier\",\n                                                                    \"src\": \"1490:6:1\"\n                                                                }\n                                                            ],\n                                                            \"functionName\": {\n                                                                \"name\": \"mstore\",\n                                                                \"nativeSrc\": \"1472:6:1\",\n                                                                \"nodeType\": \"YulIdentifier\",\n                                                                \"src\": \"1472:6:1\"\n                                                            },\n                                                            \"nativeSrc\": \"1472:25:1\",\n                                                            \"nodeType\": \"YulFunctionCall\",\n                                                            \"src\": \"1472:25:1\"\n                                                        },\n                                                        \"nativeSrc\": \"1472:25:1\",\n                                                        \"nodeType\": \"YulExpressionStatement\",\n                                                        \"src\": \"1472:25:1\"\n                                                    }\n                                                ]\n                                            },\n                                            \"name\": \"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed\",\n                                            \"nativeSrc\": \"1326:177:1\",\n                                            \"nodeType\": \"YulFunctionDefinition\",\n                                            \"parameters\": [\n                                                {\n                                                    \"name\": \"headStart\",\n                                                    \"nativeSrc\": \"1396:9:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1396:9:1\",\n                                                    \"type\": \"\"\n                                                },\n                                                {\n                                                    \"name\": \"value0\",\n                                                    \"nativeSrc\": \"1407:6:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1407:6:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"returnVariables\": [\n                                                {\n                                                    \"name\": \"tail\",\n                                                    \"nativeSrc\": \"1418:4:1\",\n                                                    \"nodeType\": \"YulTypedName\",\n                                                    \"src\": \"1418:4:1\",\n                                                    \"type\": \"\"\n                                                }\n                                            ],\n                                            \"src\": \"1326:177:1\"\n                                        }\n                                    ]\n                                },\n                                \"contents\": \"{\n    { }\n    function panic_error_0x41()\n    {\n        mstore(0, shl(224, 0x4e487b71))\n        mstore(4, 0x41)\n        revert(0, 0x24)\n    }\n    function abi_decode_tuple_t_array$_t_uint256_$dyn_memory_ptr(headStart, dataEnd) -> value0\n    {\n        if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n        let offset := calldataload(headStart)\n        if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n        let _1 := add(headStart, offset)\n        if iszero(slt(add(_1, 0x1f), dataEnd)) { revert(0, 0) }\n        let length := calldataload(_1)\n        if gt(length, 0xffffffffffffffff) { panic_error_0x41() }\n        let _2 := shl(5, length)\n        let memPtr := mload(64)\n        let newFreePtr := add(memPtr, and(add(_2, 63), not(31)))\n        if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n        mstore(64, newFreePtr)\n        let dst := memPtr\n        mstore(memPtr, length)\n        dst := add(memPtr, 32)\n        let srcEnd := add(add(_1, _2), 32)\n        if gt(srcEnd, dataEnd) { revert(0, 0) }\n        let src := add(_1, 32)\n        for { } lt(src, srcEnd) { src := add(src, 32) }\n        {\n            let value := 0\n            value := calldataload(src)\n            mstore(dst, value)\n            dst := add(dst, 32)\n        }\n        value0 := memPtr\n    }\n    function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n    {\n        tail := add(headStart, 32)\n        mstore(headStart, value0)\n    }\n}\",\n                                \"id\": 1,\n                                \"language\": \"Yul\",\n                                \"name\": \"#utility.yul\"\n                            }\n                        ]\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_invalid_detail_type/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_invalid_detail_type/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\"details\": {\"peephole\": 7}}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_invalid_detail_type/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.optimizer.details.peephole\\\" must be Boolean\",\n            \"message\": \"\\\"settings.optimizer.details.peephole\\\" must be Boolean\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_invalid_details/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_invalid_details/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\"details\": {\"notThere\": true}}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_invalid_details/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Unknown key \\\"notThere\\\"\",\n            \"message\": \"Unknown key \\\"notThere\\\"\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_no_yul/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_no_yul/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true,\n\t\t\t\"details\": {\"yul\": false}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_no_yul/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yul/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yul/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yul/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": {}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_no_object/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_no_object/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": 7\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_no_object/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.optimizer.details.yulDetails\\\" must be an object\",\n            \"message\": \"\\\"settings.optimizer.details.yulDetails\\\" must be an object\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": {\n\t\t\t\t\t\"optimizerSteps\": \"dhfoDgvulfnTUtnIf\\n[    xarrscLM\\n]\\njmuljuljul VcTOcul jmul\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"content\": \"\n            // SPDX-License-Identifier: GPL-3.0\n            pragma solidity >=0.0;\n            contract C { }\n        \"}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": false,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \":\"\n                }\n            }\n        },\n        \"outputSelection\": {\n            \"*\": {\n              \"*\": [\"metadata\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_metadata/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"metadata\": \"{\\\"compiler\\\":{\\\"version\\\":\\\"<VERSION REMOVED>\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[],\\\"devdoc\\\":{\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"A\\\":\\\"C\\\"},\\\"evmVersion\\\":\\\"osaka\\\",\\\"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}\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"content\": \"\n            // SPDX-License-Identifier: GPL-3.0\n            pragma solidity >=0.0;\n            contract C { }\n        \"}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": false,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \" :  \"\n                }\n            }\n        },\n        \"outputSelection\": {\n            \"*\": {\n              \"*\": [\"metadata\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_empty_sequence_whitespaces_metadata/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"metadata\": \"{\\\"compiler\\\":{\\\"version\\\":\\\"<VERSION REMOVED>\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[],\\\"devdoc\\\":{\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"A\\\":\\\"C\\\"},\\\"evmVersion\\\":\\\"osaka\\\",\\\"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}\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": {\n\t\t\t\t\t\"optimizerSteps\": \"abcdefg{hijklmno}pqr[st]uvwxyz\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_abbreviation/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": 'b' is not a valid step abbreviation\",\n            \"message\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": 'b' is not a valid step abbreviation\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"urls\": [\"in.sol\"]}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": true,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \"dhfoDgvulfnTUtnIf\\n[    xar:rscLM\\n]\\njmuljuljul VcTOcul jmul\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_invalid_nested_delimiter/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": Cleanup sequence delimiter cannot be placed inside the brackets\",\n            \"message\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": Cleanup sequence delimiter cannot be placed inside the brackets\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"urls\": [\"in.sol\"]}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": true,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \"dhfoDgvu:lfnTUtnIf\\n[    xarrscLM\\n]\\njmuljulj:ul VcTOcul jmul\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_mutliple_delimiters/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": Too many cleanup sequence delimiters\",\n            \"message\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": Too many cleanup sequence delimiters\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": {\n\t\t\t\t\t\"optimizerSteps\": \"a[[a][[aa]aa[aa]][]]aaa[aa[aa[aa]]]a[a][a][a]a[a]\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nested_brackets/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": {\n\t\t\t\t\t\"optimizerSteps\": \"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[a]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_nesting_too_deep/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": Brackets nested too deep\",\n            \"message\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": Brackets nested too deep\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"urls\": [\"in.sol\"]}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": false,\n                    \"yulDetails\": {\n                        \"optimizerSteps\": \"u:fdntOc\"\n                    }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \\\":\\\".\",\n            \"message\": \"If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \\\":\\\".\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"content\": \"\n            // SPDX-License-Identifier: GPL-3.0\n            pragma solidity >=0.0;\n        \"}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": false,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \"\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_empty_string/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \\\":\\\".\",\n            \"message\": \"If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \\\":\\\".\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"content\": \"\n            // SPDX-License-Identifier: GPL-3.0\n            pragma solidity >=0.0;\n        \"}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": false,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \" \"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_no_yul_whitespaces/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \\\":\\\".\",\n            \"message\": \"If Yul optimizer is disabled, only an empty optimizerSteps sequence is accepted. Note that the empty optimizer sequence is properly denoted by \\\":\\\".\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": {\n\t\t\t\t\t\"optimizerSteps\": 42\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_type/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.optimizer.details.optimizerSteps\\\" must be a string\",\n            \"message\": \"\\\"settings.optimizer.details.optimizerSteps\\\" must be a string\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": {\n\t\t\t\t\t\"optimizerSteps\": \"a]a][\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_closing_bracket/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": Unbalanced brackets\",\n            \"message\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": Unbalanced brackets\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": {\n\t\t\t\t\t\"optimizerSteps\": \"a[a][\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_unbalanced_opening_bracket/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": Unbalanced brackets\",\n            \"message\": \"Invalid optimizer step sequence in \\\"settings.optimizer.details.optimizerSteps\\\": Unbalanced brackets\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"urls\": [\"in.sol\"]}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": true,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \"dhfoDgvulfnTUtnIf\\n[    xarrscLM\\n]\\njmuljuljul VcTOcul jmul:fDnTOc\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_cleanup_sequence/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"urls\": [\"in.sol\"]}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": true,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \"dhfoDgvulfnTUtnIf\\n[    xarrscLM\\n]\\njmuljuljul VcTOcul jmul:\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_cleanup_sequence/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"urls\": [\"in.sol\"]}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": true,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \":dhfoDgvulfnTUtnIf\\n[    xarrscLM\\n]\\njmuljuljul VcTOcul jmul\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_optimisation_sequence/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"urls\": [\"in.sol\"]}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": true,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \":\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"urls\": [\"in.sol\"]}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": false,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \":\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_empty_sequence_no_yul/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A\": {\"urls\": [\"in.sol\"]}\n    },\n    \"settings\": {\n        \"optimizer\": {\n            \"details\": {\n                \"yul\": false,\n                \"yulDetails\": {\n                    \"optimizerSteps\": \"\\n  : \"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_optimiserSteps_with_whitespace_newline_sequence_no_yul/output.json",
    "content": "{\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_without_yul/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_without_yul/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\"details\": {\"yulDetails\": 7}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_optimizer_yulDetails_without_yul/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Only optimizerSteps can be set in yulDetails when Yul optimizer is disabled.\",\n            \"message\": \"Only optimizerSteps can be set in yulDetails when Yul optimizer is disabled.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"debug\": {\n      \"debugInfo\": [\n        \"ethdebug\"\n      ]\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"evm.deployedBytecode.ethdebug\",\n          \"ir\",\n          \"irOptimized\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A1_14\\\" {\n    code {\n        /// @src 0:58:123\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A1_14()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A1_14_deployed\\\"), datasize(\\\"A1_14_deployed\\\"))\n\n        return(_1, datasize(\\\"A1_14_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:58:123\n        function constructor_A1_14() {\n\n            /// @src 0:58:123\n\n        }\n        /// @src 0:58:123\n\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A1_14_deployed\\\" {\n        code {\n            /// @src 0:58:123\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xf0fdf834\n                {\n                    // a(uint256)\n\n                    external_fun_a_13()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_a_13() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_a_13(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @src 0:72:121\n            function fun_a_13(var_x_3) {\n\n                /// @src 0:112:113\n                let _1 := var_x_3\n                let expr_7 := _1\n                /// @src 0:116:117\n                let expr_8 := 0x00\n                /// @src 0:112:117\n                let expr_9 := gt(cleanup_t_uint256(expr_7), convert_t_rational_0_by_1_to_t_uint256(expr_8))\n                /// @src 0:105:118\n                assert_helper(expr_9)\n\n            }\n            /// @src 0:58:123\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\",\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A1_14\\\" {\n    code {\n        {\n            /// @src 0:58:123\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A1_14_deployed\\\"), datasize(\\\"A1_14_deployed\\\"))\n            return(_1, datasize(\\\"A1_14_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A1_14_deployed\\\" {\n        code {\n            {\n                /// @src 0:58:123\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xf0fdf834 { external_fun_a() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_a()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_a(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @src 0:72:121\n            function fun_a(var_x)\n            {\n                /// @src 0:112:113\n                let _1 := var_x\n                let expr := _1\n                /// @src 0:116:117\n                let expr_1 := 0x00\n                /// @src 0:112:117\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 0:105:118\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"A2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A2_27\\\" {\n    code {\n        /// @src 0:124:189\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A2_27()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A2_27_deployed\\\"), datasize(\\\"A2_27_deployed\\\"))\n\n        return(_1, datasize(\\\"A2_27_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:124:189\n        function constructor_A2_27() {\n\n            /// @src 0:124:189\n\n        }\n        /// @src 0:124:189\n\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A2_27_deployed\\\" {\n        code {\n            /// @src 0:124:189\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xf0fdf834\n                {\n                    // a(uint256)\n\n                    external_fun_a_26()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_a_26() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_a_26(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @src 0:138:187\n            function fun_a_26(var_x_16) {\n\n                /// @src 0:178:179\n                let _1 := var_x_16\n                let expr_20 := _1\n                /// @src 0:182:183\n                let expr_21 := 0x00\n                /// @src 0:178:183\n                let expr_22 := gt(cleanup_t_uint256(expr_20), convert_t_rational_0_by_1_to_t_uint256(expr_21))\n                /// @src 0:171:184\n                assert_helper(expr_22)\n\n            }\n            /// @src 0:124:189\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\",\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A2_27\\\" {\n    code {\n        {\n            /// @src 0:124:189\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A2_27_deployed\\\"), datasize(\\\"A2_27_deployed\\\"))\n            return(_1, datasize(\\\"A2_27_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A2_27_deployed\\\" {\n        code {\n            {\n                /// @src 0:124:189\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xf0fdf834 { external_fun_a() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_a()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_a(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @src 0:138:187\n            function fun_a(var_x)\n            {\n                /// @src 0:178:179\n                let _1 := var_x\n                let expr := _1\n                /// @src 0:182:183\n                let expr_1 := 0x00\n                /// @src 0:178:183\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 0:171:184\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        },\n        \"b.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"A1_42\\\" {\n    code {\n        /// @src 1:58:123\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A1_42()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A1_42_deployed\\\"), datasize(\\\"A1_42_deployed\\\"))\n\n        return(_1, datasize(\\\"A1_42_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 1:58:123\n        function constructor_A1_42() {\n\n            /// @src 1:58:123\n\n        }\n        /// @src 1:58:123\n\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"A1_42_deployed\\\" {\n        code {\n            /// @src 1:58:123\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xcd580ff3\n                {\n                    // b(uint256)\n\n                    external_fun_b_41()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_b_41() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_b_41(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @src 1:72:121\n            function fun_b_41(var_x_31) {\n\n                /// @src 1:112:113\n                let _1 := var_x_31\n                let expr_35 := _1\n                /// @src 1:116:117\n                let expr_36 := 0x00\n                /// @src 1:112:117\n                let expr_37 := gt(cleanup_t_uint256(expr_35), convert_t_rational_0_by_1_to_t_uint256(expr_36))\n                /// @src 1:105:118\n                assert_helper(expr_37)\n\n            }\n            /// @src 1:58:123\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\",\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"A1_42\\\" {\n    code {\n        {\n            /// @src 1:58:123\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A1_42_deployed\\\"), datasize(\\\"A1_42_deployed\\\"))\n            return(_1, datasize(\\\"A1_42_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"A1_42_deployed\\\" {\n        code {\n            {\n                /// @src 1:58:123\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xcd580ff3 { external_fun_b() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_b()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_b(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @src 1:72:121\n            function fun_b(var_x)\n            {\n                /// @src 1:112:113\n                let _1 := var_x\n                let expr := _1\n                /// @src 1:116:117\n                let expr_1 := 0x00\n                /// @src 1:112:117\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 1:105:118\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"B2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"B2_55\\\" {\n    code {\n        /// @src 1:124:189\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_B2_55()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"B2_55_deployed\\\"), datasize(\\\"B2_55_deployed\\\"))\n\n        return(_1, datasize(\\\"B2_55_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 1:124:189\n        function constructor_B2_55() {\n\n            /// @src 1:124:189\n\n        }\n        /// @src 1:124:189\n\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"B2_55_deployed\\\" {\n        code {\n            /// @src 1:124:189\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xcd580ff3\n                {\n                    // b(uint256)\n\n                    external_fun_b_54()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_b_54() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_b_54(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @src 1:138:187\n            function fun_b_54(var_x_44) {\n\n                /// @src 1:178:179\n                let _1 := var_x_44\n                let expr_48 := _1\n                /// @src 1:182:183\n                let expr_49 := 0x00\n                /// @src 1:178:183\n                let expr_50 := gt(cleanup_t_uint256(expr_48), convert_t_rational_0_by_1_to_t_uint256(expr_49))\n                /// @src 1:171:184\n                assert_helper(expr_50)\n\n            }\n            /// @src 1:124:189\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\",\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"B2_55\\\" {\n    code {\n        {\n            /// @src 1:124:189\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"B2_55_deployed\\\"), datasize(\\\"B2_55_deployed\\\"))\n            return(_1, datasize(\\\"B2_55_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"B2_55_deployed\\\" {\n        code {\n            {\n                /// @src 1:124:189\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xcd580ff3 { external_fun_b() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_b()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_b(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @src 1:138:187\n            function fun_b(var_x)\n            {\n                /// @src 1:178:179\n                let _1 := var_x\n                let expr := _1\n                /// @src 1:182:183\n                let expr_1 := 0x00\n                /// @src 1:178:183\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 1:171:184\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\",\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_debuginfo_ethdebug_compatible/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"viaIR\": true,\n    \"debug\": {\n      \"debugInfo\": [\n        \"ethdebug\"\n      ]\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.assembly\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_debuginfo_ethdebug_incompatible/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Ethdebug annotations are experimental and can only be included in 'settings.debug.debugInfo' by enabling the 'settings.experimental' option.\",\n            \"message\": \"Ethdebug annotations are experimental and can only be included in 'settings.debug.debugInfo' by enabling the 'settings.experimental' option.\",\n            \"severity\": \"error\",\n            \"type\": \"FatalError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"// SPDX-License-Identifier: GPL-2.0\\npragma solidity >=0.0;\\n\\nabstract contract C {\\n    function f() public virtual returns (bytes32);\\n}\\n\"\n    },\n    \"b.sol\": {\n      \"content\": \"// SPDX-License-Identifier: GPL-2.0\\npragma solidity >=0.0;\\n\\ninterface C {\\n    function f() external;\\n}\\n\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"debug\": {\n      \"debugInfo\": [\n        \"ethdebug\"\n      ]\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"evm.deployedBytecode.ethdebug\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_debuginfo_ethdebug_with_interfaces_and_abstracts/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"C\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": null\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": null\n                    }\n                }\n            }\n        },\n        \"b.sol\": {\n            \"C\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": null\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": null\n                    }\n                }\n            }\n        }\n    },\n    \"ethdebug\": {\n        \"compilation\": {\n            \"compiler\": {\n                \"name\": \"solc\",\n                \"version\": \"<VERSION REMOVED>\"\n            },\n            \"sources\": [\n                {\n                    \"id\": 0,\n                    \"path\": \"a.sol\"\n                },\n                {\n                    \"id\": 1,\n                    \"path\": \"b.sol\"\n                }\n            ]\n        }\n    },\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_blank/input.json",
    "content": "{\n \"language\": \"Solidity\",\n \"sources\": {\n  \"a.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n  },\n  \"b.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n  }\n },\n \"settings\": {\n  \"evmVersion\": \"petersburg\",\n  \"outputSelection\": {\n   \"\": {\n    \"\": [\n     \"evm.bytecode.object\"\n    ]\n   }\n  }\n }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_blank/output.json",
    "content": "{\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_sources_blank_contract_named_blank/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"\":  {\"content\": \"contract D {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"*\": {\"content\": \"contract D {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"C\": {\"content\": \"contract D {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"}\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"\": {\"D\": [\"userdoc\"]}\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_sources_blank_contract_named_blank/output.json",
    "content": "{\n    \"contracts\": {\n        \"\": {\n            \"D\": {\n                \"userdoc\": {\n                    \"kind\": \"user\",\n                    \"methods\": {},\n                    \"version\": 1\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"\": {\n            \"id\": 0\n        },\n        \"*\": {\n            \"id\": 1\n        },\n        \"C\": {\n            \"id\": 2\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_sources_single_contract_multiple_matches/input.json",
    "content": "{\n \"language\": \"Solidity\",\n \"sources\": {\n  \"a.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n  },\n  \"b.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n  }\n },\n \"settings\": {\n  \"evmVersion\": \"petersburg\",\n  \"outputSelection\": {\n   \"*\": {\n    \"A2\": [\n     \"evm.bytecode.object\"\n    ]\n   }\n  }\n }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_sources_single_contract_multiple_matches/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_sources_single_contract_single_match/input.json",
    "content": "{\n \"language\": \"Solidity\",\n \"sources\": {\n  \"a.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n  },\n  \"b.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n  }\n },\n \"settings\": {\n  \"evmVersion\": \"petersburg\",\n  \"outputSelection\": {\n   \"*\": {\n    \"A1\": [\n     \"evm.bytecode.object\"\n    ]\n   }\n  }\n }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_sources_single_contract_single_match/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        },\n        \"b.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_sources_star_contract_named_star/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"\":  {\"content\": \"contract D {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"*\": {\"content\": \"contract D {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"C\": {\"content\": \"contract D {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"}\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"*\": {\"D\": [\"userdoc\"]}\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_sources_star_contract_named_star/output.json",
    "content": "{\n    \"contracts\": {\n        \"\": {\n            \"D\": {\n                \"userdoc\": {\n                    \"kind\": \"user\",\n                    \"methods\": {},\n                    \"version\": 1\n                }\n            }\n        },\n        \"*\": {\n            \"D\": {\n                \"userdoc\": {\n                    \"kind\": \"user\",\n                    \"methods\": {},\n                    \"version\": 1\n                }\n            }\n        },\n        \"C\": {\n            \"D\": {\n                \"userdoc\": {\n                    \"kind\": \"user\",\n                    \"methods\": {},\n                    \"version\": 1\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"\": {\n            \"id\": 0\n        },\n        \"*\": {\n            \"id\": 1\n        },\n        \"C\": {\n            \"id\": 2\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_star/input.json",
    "content": "{\n \"language\": \"Solidity\",\n \"sources\": {\n  \"a.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n  },\n  \"b.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n  }\n },\n \"settings\": {\n  \"evmVersion\": \"petersburg\",\n  \"outputSelection\": {\n   \"*\": {\n    \"*\": [\n     \"evm.bytecode.object\"\n    ]\n   }\n  }\n }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_all_star/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            },\n            \"A2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        },\n        \"b.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            },\n            \"B2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_duplicate_matching_source_and_contract_selectors/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"*\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"C\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"D\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"}\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            // Outputs from duplicate keys are not combined. Last value wins.\n            \"*\": {\n                \"*\": [\"userdoc\"],  // Ignored\n                \"*\": [\"devdoc\"]    // Ignored\n            },\n            \"C\": {\n                \"*\": [\"storageLayout\"],          // Ignored\n                \"*\": [\"transientStorageLayout\"]  // Ignored\n            },\n            \"C\": {\n                \"A\": [\"evm.bytecode.linkReferences\"], // Ignored\n                \"A\": [\"evm.bytecode.object\"]\n            },\n            \"*\": {\n                \"A\": [\"evm.deployedBytecode.immutableReferences\"],  // Ignored\n                \"A\": [\"abi\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_duplicate_matching_source_and_contract_selectors/output.json",
    "content": "{\n    \"contracts\": {\n        \"*\": {\n            \"A\": {\n                \"abi\": []\n            }\n        },\n        \"C\": {\n            \"A\": {\n                \"abi\": [],\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        },\n        \"D\": {\n            \"A\": {\n                \"abi\": []\n            }\n        }\n    },\n    \"sources\": {\n        \"*\": {\n            \"id\": 0\n        },\n        \"C\": {\n            \"id\": 1\n        },\n        \"D\": {\n            \"id\": 2\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_empty/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"C\": {\"content\": \"contract A {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"}\n    },\n    \"settings\": {\n        \"outputSelection\": {}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_empty/output.json",
    "content": "{\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"optimizer\": {\n      \"enabled\": false\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"evm.deployedBytecode.ethdebug\",\n          \"ir\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A1_14\\\" {\n    code {\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A1_14()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A1_14_deployed\\\"), datasize(\\\"A1_14_deployed\\\"))\n\n        return(_1, datasize(\\\"A1_14_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A1_14() {\n\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A1_14_deployed\\\" {\n        code {\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xf0fdf834\n                {\n                    // a(uint256)\n\n                    external_fun_a_13()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_a_13() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_a_13(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 13\n            /// @src 0:72:121  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a_13(var_x_3) {\n\n                /// @src 0:112:113  \\\"x\\\"\n                let _1 := var_x_3\n                let expr_7 := _1\n                /// @src 0:116:117  \\\"0\\\"\n                let expr_8 := 0x00\n                /// @src 0:112:117  \\\"x > 0\\\"\n                let expr_9 := gt(cleanup_t_uint256(expr_7), convert_t_rational_0_by_1_to_t_uint256(expr_8))\n                /// @src 0:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_9)\n\n            }\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            },\n            \"A2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A2_27\\\" {\n    code {\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A2_27()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A2_27_deployed\\\"), datasize(\\\"A2_27_deployed\\\"))\n\n        return(_1, datasize(\\\"A2_27_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A2_27() {\n\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A2_27_deployed\\\" {\n        code {\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xf0fdf834\n                {\n                    // a(uint256)\n\n                    external_fun_a_26()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_a_26() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_a_26(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 26\n            /// @src 0:138:187  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a_26(var_x_16) {\n\n                /// @src 0:178:179  \\\"x\\\"\n                let _1 := var_x_16\n                let expr_20 := _1\n                /// @src 0:182:183  \\\"0\\\"\n                let expr_21 := 0x00\n                /// @src 0:178:183  \\\"x > 0\\\"\n                let expr_22 := gt(cleanup_t_uint256(expr_20), convert_t_rational_0_by_1_to_t_uint256(expr_21))\n                /// @src 0:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_22)\n\n            }\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        },\n        \"b.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"A1_42\\\" {\n    code {\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A1_42()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A1_42_deployed\\\"), datasize(\\\"A1_42_deployed\\\"))\n\n        return(_1, datasize(\\\"A1_42_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A1_42() {\n\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"A1_42_deployed\\\" {\n        code {\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xcd580ff3\n                {\n                    // b(uint256)\n\n                    external_fun_b_41()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_b_41() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_b_41(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 41\n            /// @src 1:72:121  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b_41(var_x_31) {\n\n                /// @src 1:112:113  \\\"x\\\"\n                let _1 := var_x_31\n                let expr_35 := _1\n                /// @src 1:116:117  \\\"0\\\"\n                let expr_36 := 0x00\n                /// @src 1:112:117  \\\"x > 0\\\"\n                let expr_37 := gt(cleanup_t_uint256(expr_35), convert_t_rational_0_by_1_to_t_uint256(expr_36))\n                /// @src 1:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_37)\n\n            }\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            },\n            \"B2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"B2_55\\\" {\n    code {\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_B2_55()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"B2_55_deployed\\\"), datasize(\\\"B2_55_deployed\\\"))\n\n        return(_1, datasize(\\\"B2_55_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_B2_55() {\n\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"B2_55_deployed\\\" {\n        code {\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xcd580ff3\n                {\n                    // b(uint256)\n\n                    external_fun_b_54()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_b_54() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_b_54(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 54\n            /// @src 1:138:187  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b_54(var_x_44) {\n\n                /// @src 1:178:179  \\\"x\\\"\n                let _1 := var_x_44\n                let expr_48 := _1\n                /// @src 1:182:183  \\\"0\\\"\n                let expr_49 := 0x00\n                /// @src 1:178:183  \\\"x > 0\\\"\n                let expr_50 := gt(cleanup_t_uint256(expr_48), convert_t_rational_0_by_1_to_t_uint256(expr_49))\n                /// @src 1:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_50)\n\n            }\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\",\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_ir/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"optimizer\": {\n      \"enabled\": false\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"evm.deployedBytecode.ethdebug\",\n          \"irOptimized\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A1_14\\\" {\n    code {\n        {\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A1_14_deployed\\\"), datasize(\\\"A1_14_deployed\\\"))\n            return(_1, datasize(\\\"A1_14_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A1_14_deployed\\\" {\n        code {\n            {\n                /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xf0fdf834 { external_fun_a() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_a()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_a(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 13 @src 0:72:121  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a(var_x)\n            {\n                /// @src 0:112:113  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 0:116:117  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 0:112:117  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 0:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"A2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A2_27\\\" {\n    code {\n        {\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A2_27_deployed\\\"), datasize(\\\"A2_27_deployed\\\"))\n            return(_1, datasize(\\\"A2_27_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A2_27_deployed\\\" {\n        code {\n            {\n                /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xf0fdf834 { external_fun_a() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_a()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_a(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 26 @src 0:138:187  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a(var_x)\n            {\n                /// @src 0:178:179  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 0:182:183  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 0:178:183  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 0:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        },\n        \"b.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"A1_42\\\" {\n    code {\n        {\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A1_42_deployed\\\"), datasize(\\\"A1_42_deployed\\\"))\n            return(_1, datasize(\\\"A1_42_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"A1_42_deployed\\\" {\n        code {\n            {\n                /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xcd580ff3 { external_fun_b() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_b()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_b(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 41 @src 1:72:121  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b(var_x)\n            {\n                /// @src 1:112:113  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 1:116:117  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 1:112:117  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 1:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"B2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"B2_55\\\" {\n    code {\n        {\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"B2_55_deployed\\\"), datasize(\\\"B2_55_deployed\\\"))\n            return(_1, datasize(\\\"B2_55_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"B2_55_deployed\\\" {\n        code {\n            {\n                /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xcd580ff3 { external_fun_b() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_b()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_b(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 54 @src 1:138:187  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b(var_x)\n            {\n                /// @src 1:178:179  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 1:182:183  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 1:178:183  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 1:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\",\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_iroptimized/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"optimizer\": {\n      \"enabled\": true\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"evm.deployedBytecode.ethdebug\",\n          \"irOptimized\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_ir/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Optimization is not yet supported with ethdebug.\",\n            \"message\": \"Optimization is not yet supported with ethdebug.\",\n            \"severity\": \"error\",\n            \"type\": \"UnimplementedFeatureError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"optimizer\": {\n      \"enabled\": true\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"evm.deployedBytecode.ethdebug\",\n          \"irOptimized\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_and_deployedbytecode_optimizer_iroptimized/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Optimization is not yet supported with ethdebug.\",\n            \"message\": \"Optimization is not yet supported with ethdebug.\",\n            \"severity\": \"error\",\n            \"type\": \"UnimplementedFeatureError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"optimizer\": {\n      \"enabled\": false\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"ir\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A1_14\\\" {\n    code {\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A1_14()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A1_14_deployed\\\"), datasize(\\\"A1_14_deployed\\\"))\n\n        return(_1, datasize(\\\"A1_14_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A1_14() {\n\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A1_14_deployed\\\" {\n        code {\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xf0fdf834\n                {\n                    // a(uint256)\n\n                    external_fun_a_13()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_a_13() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_a_13(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 13\n            /// @src 0:72:121  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a_13(var_x_3) {\n\n                /// @src 0:112:113  \\\"x\\\"\n                let _1 := var_x_3\n                let expr_7 := _1\n                /// @src 0:116:117  \\\"0\\\"\n                let expr_8 := 0x00\n                /// @src 0:112:117  \\\"x > 0\\\"\n                let expr_9 := gt(cleanup_t_uint256(expr_7), convert_t_rational_0_by_1_to_t_uint256(expr_8))\n                /// @src 0:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_9)\n\n            }\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            },\n            \"A2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A2_27\\\" {\n    code {\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A2_27()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A2_27_deployed\\\"), datasize(\\\"A2_27_deployed\\\"))\n\n        return(_1, datasize(\\\"A2_27_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A2_27() {\n\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A2_27_deployed\\\" {\n        code {\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xf0fdf834\n                {\n                    // a(uint256)\n\n                    external_fun_a_26()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_a_26() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_a_26(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 26\n            /// @src 0:138:187  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a_26(var_x_16) {\n\n                /// @src 0:178:179  \\\"x\\\"\n                let _1 := var_x_16\n                let expr_20 := _1\n                /// @src 0:182:183  \\\"0\\\"\n                let expr_21 := 0x00\n                /// @src 0:178:183  \\\"x > 0\\\"\n                let expr_22 := gt(cleanup_t_uint256(expr_20), convert_t_rational_0_by_1_to_t_uint256(expr_21))\n                /// @src 0:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_22)\n\n            }\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        },\n        \"b.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"A1_42\\\" {\n    code {\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A1_42()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A1_42_deployed\\\"), datasize(\\\"A1_42_deployed\\\"))\n\n        return(_1, datasize(\\\"A1_42_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A1_42() {\n\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"A1_42_deployed\\\" {\n        code {\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xcd580ff3\n                {\n                    // b(uint256)\n\n                    external_fun_b_41()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_b_41() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_b_41(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 41\n            /// @src 1:72:121  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b_41(var_x_31) {\n\n                /// @src 1:112:113  \\\"x\\\"\n                let _1 := var_x_31\n                let expr_35 := _1\n                /// @src 1:116:117  \\\"0\\\"\n                let expr_36 := 0x00\n                /// @src 1:112:117  \\\"x > 0\\\"\n                let expr_37 := gt(cleanup_t_uint256(expr_35), convert_t_rational_0_by_1_to_t_uint256(expr_36))\n                /// @src 1:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_37)\n\n            }\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            },\n            \"B2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"B2_55\\\" {\n    code {\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_B2_55()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"B2_55_deployed\\\"), datasize(\\\"B2_55_deployed\\\"))\n\n        return(_1, datasize(\\\"B2_55_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_B2_55() {\n\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"B2_55_deployed\\\" {\n        code {\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xcd580ff3\n                {\n                    // b(uint256)\n\n                    external_fun_b_54()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_b_54() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_b_54(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 54\n            /// @src 1:138:187  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b_54(var_x_44) {\n\n                /// @src 1:178:179  \\\"x\\\"\n                let _1 := var_x_44\n                let expr_48 := _1\n                /// @src 1:182:183  \\\"0\\\"\n                let expr_49 := 0x00\n                /// @src 1:178:183  \\\"x > 0\\\"\n                let expr_50 := gt(cleanup_t_uint256(expr_48), convert_t_rational_0_by_1_to_t_uint256(expr_49))\n                /// @src 1:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_50)\n\n            }\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\",\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_ir/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"optimizer\": {\n      \"enabled\": false\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"irOptimized\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A1_14\\\" {\n    code {\n        {\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A1_14_deployed\\\"), datasize(\\\"A1_14_deployed\\\"))\n            return(_1, datasize(\\\"A1_14_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A1_14_deployed\\\" {\n        code {\n            {\n                /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xf0fdf834 { external_fun_a() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_a()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_a(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 13 @src 0:72:121  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a(var_x)\n            {\n                /// @src 0:112:113  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 0:116:117  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 0:112:117  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 0:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"A2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A2_27\\\" {\n    code {\n        {\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A2_27_deployed\\\"), datasize(\\\"A2_27_deployed\\\"))\n            return(_1, datasize(\\\"A2_27_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A2_27_deployed\\\" {\n        code {\n            {\n                /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xf0fdf834 { external_fun_a() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_a()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_a(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 26 @src 0:138:187  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a(var_x)\n            {\n                /// @src 0:178:179  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 0:182:183  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 0:178:183  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 0:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        },\n        \"b.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"A1_42\\\" {\n    code {\n        {\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A1_42_deployed\\\"), datasize(\\\"A1_42_deployed\\\"))\n            return(_1, datasize(\\\"A1_42_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"A1_42_deployed\\\" {\n        code {\n            {\n                /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xcd580ff3 { external_fun_b() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_b()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_b(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 41 @src 1:72:121  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b(var_x)\n            {\n                /// @src 1:112:113  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 1:116:117  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 1:112:117  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 1:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"B2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"B2_55\\\" {\n    code {\n        {\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"B2_55_deployed\\\"), datasize(\\\"B2_55_deployed\\\"))\n            return(_1, datasize(\\\"B2_55_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"B2_55_deployed\\\" {\n        code {\n            {\n                /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xcd580ff3 { external_fun_b() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_b()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_b(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 54 @src 1:138:187  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b(var_x)\n            {\n                /// @src 1:178:179  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 1:182:183  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 1:178:183  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 1:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\",\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_bytecode_iroptimized/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"optimizer\": {\n      \"enabled\": false\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.deployedBytecode.ethdebug\",\n          \"ir\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A1_14\\\" {\n    code {\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A1_14()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A1_14_deployed\\\"), datasize(\\\"A1_14_deployed\\\"))\n\n        return(_1, datasize(\\\"A1_14_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A1_14() {\n\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A1_14_deployed\\\" {\n        code {\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xf0fdf834\n                {\n                    // a(uint256)\n\n                    external_fun_a_13()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_a_13() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_a_13(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 13\n            /// @src 0:72:121  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a_13(var_x_3) {\n\n                /// @src 0:112:113  \\\"x\\\"\n                let _1 := var_x_3\n                let expr_7 := _1\n                /// @src 0:116:117  \\\"0\\\"\n                let expr_8 := 0x00\n                /// @src 0:112:117  \\\"x > 0\\\"\n                let expr_9 := gt(cleanup_t_uint256(expr_7), convert_t_rational_0_by_1_to_t_uint256(expr_8))\n                /// @src 0:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_9)\n\n            }\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            },\n            \"A2\": {\n                \"evm\": {\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A2_27\\\" {\n    code {\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A2_27()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A2_27_deployed\\\"), datasize(\\\"A2_27_deployed\\\"))\n\n        return(_1, datasize(\\\"A2_27_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A2_27() {\n\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A2_27_deployed\\\" {\n        code {\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xf0fdf834\n                {\n                    // a(uint256)\n\n                    external_fun_a_26()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_a_26() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_a_26(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 26\n            /// @src 0:138:187  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a_26(var_x_16) {\n\n                /// @src 0:178:179  \\\"x\\\"\n                let _1 := var_x_16\n                let expr_20 := _1\n                /// @src 0:182:183  \\\"0\\\"\n                let expr_21 := 0x00\n                /// @src 0:178:183  \\\"x > 0\\\"\n                let expr_22 := gt(cleanup_t_uint256(expr_20), convert_t_rational_0_by_1_to_t_uint256(expr_21))\n                /// @src 0:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_22)\n\n            }\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        },\n        \"b.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"A1_42\\\" {\n    code {\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A1_42()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A1_42_deployed\\\"), datasize(\\\"A1_42_deployed\\\"))\n\n        return(_1, datasize(\\\"A1_42_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A1_42() {\n\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"A1_42_deployed\\\" {\n        code {\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xcd580ff3\n                {\n                    // b(uint256)\n\n                    external_fun_b_41()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_b_41() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_b_41(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 41\n            /// @src 1:72:121  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b_41(var_x_31) {\n\n                /// @src 1:112:113  \\\"x\\\"\n                let _1 := var_x_31\n                let expr_35 := _1\n                /// @src 1:116:117  \\\"0\\\"\n                let expr_36 := 0x00\n                /// @src 1:112:117  \\\"x > 0\\\"\n                let expr_37 := gt(cleanup_t_uint256(expr_35), convert_t_rational_0_by_1_to_t_uint256(expr_36))\n                /// @src 1:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_37)\n\n            }\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            },\n            \"B2\": {\n                \"evm\": {\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"B2_55\\\" {\n    code {\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_B2_55()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"B2_55_deployed\\\"), datasize(\\\"B2_55_deployed\\\"))\n\n        return(_1, datasize(\\\"B2_55_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_B2_55() {\n\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"B2_55_deployed\\\" {\n        code {\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xcd580ff3\n                {\n                    // b(uint256)\n\n                    external_fun_b_54()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_b_54() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_b_54(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 54\n            /// @src 1:138:187  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b_54(var_x_44) {\n\n                /// @src 1:178:179  \\\"x\\\"\n                let _1 := var_x_44\n                let expr_48 := _1\n                /// @src 1:182:183  \\\"0\\\"\n                let expr_49 := 0x00\n                /// @src 1:178:183  \\\"x > 0\\\"\n                let expr_50 := gt(cleanup_t_uint256(expr_48), convert_t_rational_0_by_1_to_t_uint256(expr_49))\n                /// @src 1:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_50)\n\n            }\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\",\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_ir/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"optimizer\": {\n      \"enabled\": false\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.deployedBytecode.ethdebug\",\n          \"irOptimized\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A1_14\\\" {\n    code {\n        {\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A1_14_deployed\\\"), datasize(\\\"A1_14_deployed\\\"))\n            return(_1, datasize(\\\"A1_14_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A1_14_deployed\\\" {\n        code {\n            {\n                /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xf0fdf834 { external_fun_a() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_a()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_a(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 13 @src 0:72:121  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a(var_x)\n            {\n                /// @src 0:112:113  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 0:116:117  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 0:112:117  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 0:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"A2\": {\n                \"evm\": {\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A2_27\\\" {\n    code {\n        {\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A2_27_deployed\\\"), datasize(\\\"A2_27_deployed\\\"))\n            return(_1, datasize(\\\"A2_27_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A2_27_deployed\\\" {\n        code {\n            {\n                /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xf0fdf834 { external_fun_a() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_a()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_a(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 26 @src 0:138:187  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a(var_x)\n            {\n                /// @src 0:178:179  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 0:182:183  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 0:178:183  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 0:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        },\n        \"b.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"A1_42\\\" {\n    code {\n        {\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A1_42_deployed\\\"), datasize(\\\"A1_42_deployed\\\"))\n            return(_1, datasize(\\\"A1_42_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"A1_42_deployed\\\" {\n        code {\n            {\n                /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xcd580ff3 { external_fun_b() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_b()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_b(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 41 @src 1:72:121  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b(var_x)\n            {\n                /// @src 1:112:113  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 1:116:117  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 1:112:117  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 1:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"B2\": {\n                \"evm\": {\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"B2_55\\\" {\n    code {\n        {\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"B2_55_deployed\\\"), datasize(\\\"B2_55_deployed\\\"))\n            return(_1, datasize(\\\"B2_55_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"B2_55_deployed\\\" {\n        code {\n            {\n                /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xcd580ff3 { external_fun_b() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_b()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_b(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 54 @src 1:138:187  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b(var_x)\n            {\n                /// @src 1:178:179  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 1:182:183  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 1:178:183  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 1:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\",\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_deployedbytecode_iroptimized/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_ir/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"ir\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_ir/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A1_14\\\" {\n    code {\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A1_14()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A1_14_deployed\\\"), datasize(\\\"A1_14_deployed\\\"))\n\n        return(_1, datasize(\\\"A1_14_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A1_14() {\n\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A1_14_deployed\\\" {\n        code {\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xf0fdf834\n                {\n                    // a(uint256)\n\n                    external_fun_a_13()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_a_13() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_a_13(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 13\n            /// @src 0:72:121  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a_13(var_x_3) {\n\n                /// @src 0:112:113  \\\"x\\\"\n                let _1 := var_x_3\n                let expr_7 := _1\n                /// @src 0:116:117  \\\"0\\\"\n                let expr_8 := 0x00\n                /// @src 0:112:117  \\\"x > 0\\\"\n                let expr_9 := gt(cleanup_t_uint256(expr_7), convert_t_rational_0_by_1_to_t_uint256(expr_8))\n                /// @src 0:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_9)\n\n            }\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            },\n            \"A2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A2_27\\\" {\n    code {\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A2_27()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A2_27_deployed\\\"), datasize(\\\"A2_27_deployed\\\"))\n\n        return(_1, datasize(\\\"A2_27_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A2_27() {\n\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A2_27_deployed\\\" {\n        code {\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xf0fdf834\n                {\n                    // a(uint256)\n\n                    external_fun_a_26()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_a_26() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_a_26(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 26\n            /// @src 0:138:187  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a_26(var_x_16) {\n\n                /// @src 0:178:179  \\\"x\\\"\n                let _1 := var_x_16\n                let expr_20 := _1\n                /// @src 0:182:183  \\\"0\\\"\n                let expr_21 := 0x00\n                /// @src 0:178:183  \\\"x > 0\\\"\n                let expr_22 := gt(cleanup_t_uint256(expr_20), convert_t_rational_0_by_1_to_t_uint256(expr_21))\n                /// @src 0:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_22)\n\n            }\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        },\n        \"b.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"A1_42\\\" {\n    code {\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A1_42()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A1_42_deployed\\\"), datasize(\\\"A1_42_deployed\\\"))\n\n        return(_1, datasize(\\\"A1_42_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_A1_42() {\n\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"A1_42_deployed\\\" {\n        code {\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xcd580ff3\n                {\n                    // b(uint256)\n\n                    external_fun_b_41()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_b_41() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_b_41(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 41\n            /// @src 1:72:121  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b_41(var_x_31) {\n\n                /// @src 1:112:113  \\\"x\\\"\n                let _1 := var_x_31\n                let expr_35 := _1\n                /// @src 1:116:117  \\\"0\\\"\n                let expr_36 := 0x00\n                /// @src 1:112:117  \\\"x > 0\\\"\n                let expr_37 := gt(cleanup_t_uint256(expr_35), convert_t_rational_0_by_1_to_t_uint256(expr_36))\n                /// @src 1:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_37)\n\n            }\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            },\n            \"B2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"B2_55\\\" {\n    code {\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_B2_55()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"B2_55_deployed\\\"), datasize(\\\"B2_55_deployed\\\"))\n\n        return(_1, datasize(\\\"B2_55_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n        function constructor_B2_55() {\n\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n        /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"B2_55_deployed\\\" {\n        code {\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0xcd580ff3\n                {\n                    // b(uint256)\n\n                    external_fun_b_54()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function revert_error_c1322bf8034eace5e0b5c7295db60986aa89aae5e0ea0873e4689e076861a5db() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_uint256(value) -> cleaned {\n                cleaned := value\n            }\n\n            function validator_revert_t_uint256(value) {\n                if iszero(eq(value, cleanup_t_uint256(value))) { revert(0, 0) }\n            }\n\n            function abi_decode_t_uint256(offset, end) -> value {\n                value := calldataload(offset)\n                validator_revert_t_uint256(value)\n            }\n\n            function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0 {\n                if slt(sub(dataEnd, headStart), 32) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n                {\n\n                    let offset := 0\n\n                    value0 := abi_decode_t_uint256(add(headStart, offset), dataEnd)\n                }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_b_54() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                let param_0 :=  abi_decode_tuple_t_uint256(4, calldatasize())\n                fun_b_54(param_0)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function cleanup_t_rational_0_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function identity(value) -> ret {\n                ret := value\n            }\n\n            function convert_t_rational_0_by_1_to_t_uint256(value) -> converted {\n                converted := cleanup_t_uint256(identity(cleanup_t_rational_0_by_1(value)))\n            }\n\n            function panic_error_0x01() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n\n            function assert_helper(condition) {\n                if iszero(condition) { panic_error_0x01() }\n            }\n\n            /// @ast-id 54\n            /// @src 1:138:187  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b_54(var_x_44) {\n\n                /// @src 1:178:179  \\\"x\\\"\n                let _1 := var_x_44\n                let expr_48 := _1\n                /// @src 1:182:183  \\\"0\\\"\n                let expr_49 := 0x00\n                /// @src 1:178:183  \\\"x > 0\\\"\n                let expr_50 := gt(cleanup_t_uint256(expr_48), convert_t_rational_0_by_1_to_t_uint256(expr_49))\n                /// @src 1:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_50)\n\n            }\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\",\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_ir/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"irOptimized\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A1_14\\\" {\n    code {\n        {\n            /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A1_14_deployed\\\"), datasize(\\\"A1_14_deployed\\\"))\n            return(_1, datasize(\\\"A1_14_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A1_14_deployed\\\" {\n        code {\n            {\n                /// @src 0:58:123  \\\"contract A1 { function a(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xf0fdf834 { external_fun_a() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_a()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_a(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 13 @src 0:72:121  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a(var_x)\n            {\n                /// @src 0:112:113  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 0:116:117  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 0:112:117  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 0:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"A2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"a.sol\\\"\nobject \\\"A2_27\\\" {\n    code {\n        {\n            /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A2_27_deployed\\\"), datasize(\\\"A2_27_deployed\\\"))\n            return(_1, datasize(\\\"A2_27_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\\\"a.sol\\\"\n    object \\\"A2_27_deployed\\\" {\n        code {\n            {\n                /// @src 0:124:189  \\\"contract A2 { function a(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xf0fdf834 { external_fun_a() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_a()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_a(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 26 @src 0:138:187  \\\"function a(uint x) public pure { assert(x > 0); }\\\"\n            function fun_a(var_x)\n            {\n                /// @src 0:178:179  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 0:182:183  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 0:178:183  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 0:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        },\n        \"b.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"A1_42\\\" {\n    code {\n        {\n            /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"A1_42_deployed\\\"), datasize(\\\"A1_42_deployed\\\"))\n            return(_1, datasize(\\\"A1_42_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"A1_42_deployed\\\" {\n        code {\n            {\n                /// @src 1:58:123  \\\"contract A1 { function b(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xcd580ff3 { external_fun_b() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_b()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_b(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 41 @src 1:72:121  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b(var_x)\n            {\n                /// @src 1:112:113  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 1:116:117  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 1:112:117  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 1:105:118  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"B2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 1:\\\"b.sol\\\"\nobject \\\"B2_55\\\" {\n    code {\n        {\n            /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\\\"B2_55_deployed\\\"), datasize(\\\"B2_55_deployed\\\"))\n            return(_1, datasize(\\\"B2_55_deployed\\\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 1:\\\"b.sol\\\"\n    object \\\"B2_55_deployed\\\" {\n        code {\n            {\n                /// @src 1:124:189  \\\"contract B2 { function b(uint x) public pure { assert(x > 0); } }\\\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xcd580ff3 { external_fun_b() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function validator_revert_uint256(value)\n            {\n                if iszero(eq(value, cleanup_uint256(value))) { revert(0, 0) }\n            }\n            function abi_decode_uint256(offset, end) -> value\n            {\n                value := calldataload(offset)\n                validator_revert_uint256(value)\n            }\n            function abi_decode_tuple_uint256(headStart, dataEnd) -> value0\n            {\n                if slt(sub(dataEnd, headStart), 32)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n                let offset := 0\n                value0 := abi_decode_uint256(add(headStart, offset), dataEnd)\n            }\n            function abi_encode_tuple(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_b()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                let param := abi_decode_tuple_uint256(4, calldatasize())\n                fun_b(param)\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function panic_error_0x01()\n            {\n                mstore(0, shl(224, 0x4e487b71))\n                mstore(4, 0x01)\n                revert(0, 0x24)\n            }\n            function assert_helper(condition)\n            {\n                if iszero(condition) { panic_error_0x01() }\n            }\n            /// @ast-id 54 @src 1:138:187  \\\"function b(uint x) public pure { assert(x > 0); }\\\"\n            function fun_b(var_x)\n            {\n                /// @src 1:178:179  \\\"x\\\"\n                let _1 := var_x\n                let expr := _1\n                /// @src 1:182:183  \\\"0\\\"\n                let expr_1 := 0x00\n                /// @src 1:178:183  \\\"x > 0\\\"\n                let expr_2 := gt(cleanup_uint256(expr), convert_rational_by_to_uint256(expr_1))\n                /// @src 1:171:184  \\\"assert(x > 0)\\\"\n                assert_helper(expr_2)\n            }\n        }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\",\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_iroptimized/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_no_experimental/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A.sol\": {\n            \"content\": \"contract A { constructor() { uint x = 2; { uint y = 3; } } }\"\n        }\n    },\n    \"settings\": {\n        \"viaIR\": true,\n        \"debug\": {\n            \"debugInfo\": [\"ethdebug\"]\n        },\n        \"outputSelection\": {\n            \"A.sol\": {\n                \"A\": [\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_no_experimental/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Ethdebug annotations are experimental and can only be included in 'settings.debug.debugInfo' by enabling the 'settings.experimental' option.\",\n            \"message\": \"Ethdebug annotations are experimental and can only be included in 'settings.debug.debugInfo' by enabling the 'settings.experimental' option.\",\n            \"severity\": \"error\",\n            \"type\": \"FatalError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_no_viair/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"evm.deployedBytecode.ethdebug\",\n          \"ir\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_no_viair/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.\",\n            \"message\": \"'evm.bytecode.ethdebug' or 'evm.deployedBytecode.ethdebug' can only be selected as output, if 'viaIR' was set.\",\n            \"severity\": \"error\",\n            \"type\": \"FatalError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"optimizer\": {\n      \"enabled\": true\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"ir\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_optimize_ir/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Optimization is not yet supported with ethdebug.\",\n            \"message\": \"Optimization is not yet supported with ethdebug.\",\n            \"severity\": \"error\",\n            \"type\": \"UnimplementedFeatureError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/input.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"optimizer\": {\n      \"enabled\": true\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"irOptimized\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ethdebug_optimize_iroptimized/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Optimization is not yet supported with ethdebug.\",\n            \"message\": \"Optimization is not yet supported with ethdebug.\",\n            \"severity\": \"error\",\n            \"type\": \"UnimplementedFeatureError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ir_ast_no_experimental/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A.sol\": {\n            \"content\": \"contract A { constructor() { uint x = 2; { uint y = 3; } } }\"\n        }\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"A.sol\": {\n                \"A\": [\"irAst\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_ir_ast_no_experimental/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"'irAst', 'irOptimizedAst', 'yulCFGJson', and 'ethdebug' outputs are experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"message\": \"'irAst', 'irOptimizedAst', 'yulCFGJson', and 'ethdebug' outputs are experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"severity\": \"error\",\n            \"type\": \"FatalError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"\":  {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"*\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"C\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"D\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"}\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            // FIXME: Behavior of \"\" is inconsistent. Sometimes it matches everything, sometimes only empty name.\n            \"\": {\n                \"\":  [\"metadata\"],                                 // No matches\n                \"*\": [\"transientStorageLayout\"],                   // All sources, all contracts\n                \"A\": [\"abi\"]                                       // source \"\", contract A\n            },\n            \"*\": {\n                \"\":  [\"evm.deployedBytecode.immutableReferences\"], // No matches\n                \"*\": [\"evm.bytecode.object\"],                      // All sources, all contracts\n                \"A\": [\"evm.bytecode.linkReferences\"]               // All sources, contract A\n            },\n            \"C\": {\n                \"\":  [\"userdoc\"],                                  // No matches\n                \"*\": [\"devdoc\"],                                   // All contracts in source \"C\"\n                \"A\": [\"storageLayout\"]                             // source \"C\", contract A\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors/output.json",
    "content": "{\n    \"contracts\": {\n        \"\": {\n            \"A\": {\n                \"abi\": [],\n                \"evm\": {\n                    \"bytecode\": {\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                },\n                \"transientStorageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                }\n            },\n            \"B\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                },\n                \"transientStorageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                }\n            }\n        },\n        \"*\": {\n            \"A\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            },\n            \"B\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        },\n        \"C\": {\n            \"A\": {\n                \"devdoc\": {\n                    \"kind\": \"dev\",\n                    \"methods\": {},\n                    \"version\": 1\n                },\n                \"evm\": {\n                    \"bytecode\": {\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                },\n                \"storageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                }\n            },\n            \"B\": {\n                \"devdoc\": {\n                    \"kind\": \"dev\",\n                    \"methods\": {},\n                    \"version\": 1\n                },\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        },\n        \"D\": {\n            \"A\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            },\n            \"B\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"\": {\n            \"id\": 0\n        },\n        \"*\": {\n            \"id\": 1\n        },\n        \"C\": {\n            \"id\": 2\n        },\n        \"D\": {\n            \"id\": 3\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors_full_pipeline/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"C\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"D\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"}\n    },\n    \"settings\": {\n        \"optimizer\": {\"enabled\": true},\n        \"debug\": {\"debugInfo\": []},\n        \"outputSelection\": {\n            // This test uses outputs that require all stages of the pipeline to run, possibly via\n            // multiple paths, to make sure the later stages handle more complex output selection correctly.\n            // Currently there are only distinct paths (IR, optimized IR and bytecode generation).\n            \"*\": {\n                \"*\": [\"evm.bytecode.object\"],\n                \"A\": [\"irOptimized\"]\n            },\n            \"C\": {\n                \"A\": [\"ir\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_multiple_matching_source_and_contract_selectors_full_pipeline/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"A\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                },\n                \"ir\": \"\n/// @use-src 0:\\\"C\\\"\nobject \\\"A_1\\\" {\n    code {\n\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_A_1()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"A_1_deployed\\\"), datasize(\\\"A_1_deployed\\\"))\n\n        return(_1, datasize(\\\"A_1_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        function constructor_A_1() {\n\n        }\n\n    }\n    /// @use-src 0:\\\"C\\\"\n    object \\\"A_1_deployed\\\" {\n        code {\n\n            mstore(64, memoryguard(128))\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\",\n                \"irOptimized\": \"/// @use-src 0:\\\"C\\\"\nobject \\\"A_1\\\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\\\"A_1_deployed\\\")\n            codecopy(_1, dataoffset(\\\"A_1_deployed\\\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\\\"C\\\"\n    object \\\"A_1_deployed\\\" {\n        code { { revert(0, 0) } }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"B\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        },\n        \"D\": {\n            \"A\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// @use-src 1:\\\"D\\\"\nobject \\\"A_5\\\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\\\"A_5_deployed\\\")\n            codecopy(_1, dataoffset(\\\"A_5_deployed\\\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 1:\\\"D\\\"\n    object \\\"A_5_deployed\\\" {\n        code { { revert(0, 0) } }\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n}\n\"\n            },\n            \"B\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        },\n        \"D\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_no_output_selected/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"C\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"D\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"E\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"}\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"C\": {},\n            \"D\": {\"A\": []},\n            \"*\": {\"B\": []},\n            \"\": {}\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_no_output_selected/output.json",
    "content": "{\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        },\n        \"D\": {\n            \"id\": 1\n        },\n        \"E\": {\n            \"id\": 2\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_single_all/input.json",
    "content": "{\n \"language\": \"Solidity\",\n \"sources\": {\n  \"a.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n  },\n  \"b.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n  }\n },\n \"settings\": {\n  \"evmVersion\": \"petersburg\",\n  \"outputSelection\": {\n   \"a.sol\": {\n    \"*\": [\n     \"evm.bytecode.object\"\n    ]\n   }\n  }\n }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_single_all/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            },\n            \"A2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_single_source_single_contract_multiple_matches/input.json",
    "content": "{\n \"language\": \"Solidity\",\n \"sources\": {\n  \"a.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n  },\n  \"b.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n  }\n },\n \"settings\": {\n  \"evmVersion\": \"petersburg\",\n  \"outputSelection\": {\n   \"a.sol\": {\n    \"A1\": [\n     \"evm.bytecode.object\"\n    ]\n   }\n  }\n }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_single_source_single_contract_multiple_matches/output.json",
    "content": "{\n    \"contracts\": {\n        \"a.sol\": {\n            \"A1\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_single_source_single_contract_single_match/input.json",
    "content": "{\n \"language\": \"Solidity\",\n \"sources\": {\n  \"a.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n  },\n  \"b.sol\": {\n   \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n  }\n },\n \"settings\": {\n  \"evmVersion\": \"petersburg\",\n  \"outputSelection\": {\n   \"b.sol\": {\n    \"B2\": [\n     \"evm.bytecode.object\"\n    ]\n   }\n  }\n }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_single_source_single_contract_single_match/output.json",
    "content": "{\n    \"contracts\": {\n        \"b.sol\": {\n            \"B2\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"a.sol\": {\n            \"id\": 0\n        },\n        \"b.sol\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_unrecognized_output/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"C\": {\"content\": \"contract A {}\\ncontract B {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"}\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            // Unrecognized outputs are ignored.\n            \"C\": {\n                \"A\": [\n                    \"X\",\n                    \"METADATA\",\n                    \"abi.encode\",\n                    \"userdoc\",  // The only valid one here.\n                    \".\",\n                    \"evm.\",\n                    \"evm.bytecodeObject\",\n                    \"evm.bytecode.object.ir\",\n                    \"evm.bytecode.*\"\n                ]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_unrecognized_output/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"A\": {\n                \"userdoc\": {\n                    \"kind\": \"user\",\n                    \"methods\": {},\n                    \"version\": 1\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_unrecognized_source_and_contract_selectors/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"*\": {\"content\": \"contract A {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"},\n        \"C\": {\"content\": \"contract A {}\\n//SPDX-License-Identifier: GPL-3.0\\npragma solidity *;\"}\n    },\n    \"settings\": {\n        \"outputSelection\": {\n            \"*\": {\n                \"X\": [\"userdoc\"] // No contract X, but no error, just ignored.\n            },\n            \"Y\": {\n                \"*\": [\"devdoc\"], // No source \"Y\", but no error, just ignored.\n                \"Z\": [\"abi\"]     // No source \"Y\", but no error, just ignored.\n            },\n            \"C\": {\n                \"A\": [\"evm.bytecode.object\"]\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_unrecognized_source_and_contract_selectors/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"A\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"*\": {\n            \"id\": 0\n        },\n        \"C\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_wrong_type/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": \"not an object\"\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_wrong_type/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.outputSelection\\\" must be an object\",\n            \"message\": \"\\\"settings.outputSelection\\\" must be an object\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_wrong_type_contract/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": \"it's a contract, but not an array!\",\n\t\t\t\t\"\": [ \"ast\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_wrong_type_contract/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.outputSelection.fileA.A\\\" must be a string array\",\n            \"message\": \"\\\"settings.outputSelection.fileA.A\\\" must be a string array\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_wrong_type_output/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ 1, 2, 3 ,4],\n\t\t\t\t\"\": [ \"ast\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_wrong_type_output/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.outputSelection.fileA.A\\\" must be a string array\",\n            \"message\": \"\\\"settings.outputSelection.fileA.A\\\" must be a string array\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_wrong_type_source/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": \"awesome file!\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_wrong_type_source/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.outputSelection.fileA\\\" must be an object\",\n            \"message\": \"\\\"settings.outputSelection.fileA\\\" must be an object\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_yul_cfg_json_no_experimental/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"{ let x := mload(0) sstore(add(x, 0), 0) }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true\n\t\t},\n\t\t\"viaIR\": true,\n\t\t\"outputSelection\": {\"*\": {\"*\": [\"yulCFGJson\"]}}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_output_selection_yul_cfg_json_no_experimental/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"'irAst', 'irOptimizedAst', 'yulCFGJson', and 'ethdebug' outputs are experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"message\": \"'irAst', 'irOptimizedAst', 'yulCFGJson', and 'ethdebug' outputs are experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"severity\": \"error\",\n            \"type\": \"FatalError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_fatal/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_fatal/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {\n    // This will trigger a fatal error at the analysis stage, of the kind that terminates analysis\n    // immediately without letting the current step finish.\n    constructor(uint[] storage) {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_fatal/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"*\": [\"*\"],\n\t\t\t\t\"\": [\"*\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_fatal/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"3644\",\n            \"formattedMessage\": \"TypeError: This parameter has a type that can only be used internally. You can make the contract abstract to avoid this problem.\n --> C:7:17:\n  |\n7 |     constructor(uint[] storage) {}\n  |                 ^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"This parameter has a type that can only be used internally. You can make the contract abstract to avoid this problem.\",\n            \"severity\": \"error\",\n            \"sourceLocation\": {\n                \"end\": 258,\n                \"file\": \"C\",\n                \"start\": 244\n            },\n            \"type\": \"TypeError\"\n        }\n    ],\n    \"sources\": {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\n// This will trigger a fatal error at the analysis stage, of the kind that lets the current\n// analysis steps finish but terminates analysis after immediately after that step.\nfunction f(uint immutable x) {}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"*\": [\"*\"],\n\t\t\t\t\"\": [\"*\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_fatal_after_current_step/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"8297\",\n            \"formattedMessage\": \"DeclarationError: The \\\"immutable\\\" keyword can only be used for state variables.\n --> C:6:12:\n  |\n6 | function f(uint immutable x) {}\n  |            ^^^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"The \\\"immutable\\\" keyword can only be used for state variables.\",\n            \"severity\": \"error\",\n            \"sourceLocation\": {\n                \"end\": 259,\n                \"file\": \"C\",\n                \"start\": 243\n            },\n            \"type\": \"DeclarationError\"\n        }\n    ],\n    \"sources\": {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {\n    // This will trigger a non-fatal error at the analysis stage.\n    // With this kind of error we still run subsequent analysis stages.\n    uint x;\n    string y = x;\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"*\": [\"*\"],\n\t\t\t\t\"\": [\"*\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_analysis_error_non_fatal/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"7407\",\n            \"formattedMessage\": \"TypeError: Type uint256 is not implicitly convertible to expected type string storage ref.\n --> C:8:16:\n  |\n8 |     string y = x;\n  |                ^\n\n\",\n            \"message\": \"Type uint256 is not implicitly convertible to expected type string storage ref.\",\n            \"severity\": \"error\",\n            \"sourceLocation\": {\n                \"end\": 235,\n                \"file\": \"C\",\n                \"start\": 234\n            },\n            \"type\": \"TypeError\"\n        }\n    ],\n    \"sources\": {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_compilation_error/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_compilation_error/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {\n    // This will trigger an error at the compilation stage.\n    // CodeGenerationError due to immutable initialization in constructor being optimized out.\n    uint immutable public x;\n\n    constructor() {\n        x = 0;\n        while (true) {}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_compilation_error/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"optimizer\": {\"enabled\": true},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"*\": [\"*\"],\n\t\t\t\t\"\": [\"*\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_compilation_error/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"abi\": [\n                    {\n                        \"inputs\": [],\n                        \"stateMutability\": \"nonpayable\",\n                        \"type\": \"constructor\"\n                    },\n                    {\n                        \"inputs\": [],\n                        \"name\": \"x\",\n                        \"outputs\": [\n                            {\n                                \"internalType\": \"uint256\",\n                                \"name\": \"\",\n                                \"type\": \"uint256\"\n                            }\n                        ],\n                        \"stateMutability\": \"view\",\n                        \"type\": \"function\"\n                    }\n                ],\n                \"devdoc\": {\n                    \"kind\": \"dev\",\n                    \"methods\": {},\n                    \"version\": 1\n                },\n                \"evm\": {\n                    \"methodIdentifiers\": {\n                        \"x()\": \"0c55699c\"\n                    }\n                },\n                \"metadata\": \"{\\\"compiler\\\":{\\\"version\\\":\\\"<VERSION REMOVED>\\\"},\\\"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\\\":\\\"osaka\\\",\\\"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}\",\n                \"storageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                },\n                \"transientStorageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                },\n                \"userdoc\": {\n                    \"kind\": \"user\",\n                    \"methods\": {},\n                    \"version\": 1\n                }\n            }\n        }\n    },\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"1284\",\n            \"formattedMessage\": \"CodeGenerationError: Some immutables were read from but never assigned, possibly because of optimization.\n --> C:4:1:\n  |\n4 | contract C {\n  | ^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"Some immutables were read from but never assigned, possibly because of optimization.\",\n            \"severity\": \"error\",\n            \"sourceLocation\": {\n                \"end\": 320,\n                \"file\": \"C\",\n                \"start\": 56\n            },\n            \"type\": \"CodeGenerationError\"\n        }\n    ],\n    \"sources\": {\n        \"C\": {\n            \"ast\": {\n                \"absolutePath\": \"C\",\n                \"exportedSymbols\": {\n                    \"C\": [\n                        15\n                    ]\n                },\n                \"id\": 16,\n                \"license\": \"GPL-3.0\",\n                \"nodeType\": \"SourceUnit\",\n                \"nodes\": [\n                    {\n                        \"id\": 1,\n                        \"literals\": [\n                            \"solidity\",\n                            \"*\"\n                        ],\n                        \"nodeType\": \"PragmaDirective\",\n                        \"src\": \"36:18:0\"\n                    },\n                    {\n                        \"abstract\": false,\n                        \"baseContracts\": [],\n                        \"canonicalName\": \"C\",\n                        \"contractDependencies\": [],\n                        \"contractKind\": \"contract\",\n                        \"fullyImplemented\": true,\n                        \"id\": 15,\n                        \"linearizedBaseContracts\": [\n                            15\n                        ],\n                        \"name\": \"C\",\n                        \"nameLocation\": \"65:1:0\",\n                        \"nodeType\": \"ContractDefinition\",\n                        \"nodes\": [\n                            {\n                                \"constant\": false,\n                                \"functionSelector\": \"0c55699c\",\n                                \"id\": 3,\n                                \"mutability\": \"immutable\",\n                                \"name\": \"x\",\n                                \"nameLocation\": \"250:1:0\",\n                                \"nodeType\": \"VariableDeclaration\",\n                                \"scope\": 15,\n                                \"src\": \"228:23:0\",\n                                \"stateVariable\": true,\n                                \"storageLocation\": \"default\",\n                                \"typeDescriptions\": {\n                                    \"typeIdentifier\": \"t_uint256\",\n                                    \"typeString\": \"uint256\"\n                                },\n                                \"typeName\": {\n                                    \"id\": 2,\n                                    \"name\": \"uint\",\n                                    \"nodeType\": \"ElementaryTypeName\",\n                                    \"src\": \"228:4:0\",\n                                    \"typeDescriptions\": {\n                                        \"typeIdentifier\": \"t_uint256\",\n                                        \"typeString\": \"uint256\"\n                                    }\n                                },\n                                \"visibility\": \"public\"\n                            },\n                            {\n                                \"body\": {\n                                    \"id\": 13,\n                                    \"nodeType\": \"Block\",\n                                    \"src\": \"272:46:0\",\n                                    \"statements\": [\n                                        {\n                                            \"expression\": {\n                                                \"id\": 8,\n                                                \"isConstant\": false,\n                                                \"isLValue\": false,\n                                                \"isPure\": false,\n                                                \"lValueRequested\": false,\n                                                \"leftHandSide\": {\n                                                    \"id\": 6,\n                                                    \"name\": \"x\",\n                                                    \"nodeType\": \"Identifier\",\n                                                    \"overloadedDeclarations\": [],\n                                                    \"referencedDeclaration\": 3,\n                                                    \"src\": \"282:1:0\",\n                                                    \"typeDescriptions\": {\n                                                        \"typeIdentifier\": \"t_uint256\",\n                                                        \"typeString\": \"uint256\"\n                                                    }\n                                                },\n                                                \"nodeType\": \"Assignment\",\n                                                \"operator\": \"=\",\n                                                \"rightHandSide\": {\n                                                    \"hexValue\": \"30\",\n                                                    \"id\": 7,\n                                                    \"isConstant\": false,\n                                                    \"isLValue\": false,\n                                                    \"isPure\": true,\n                                                    \"kind\": \"number\",\n                                                    \"lValueRequested\": false,\n                                                    \"nodeType\": \"Literal\",\n                                                    \"src\": \"286:1:0\",\n                                                    \"typeDescriptions\": {\n                                                        \"typeIdentifier\": \"t_rational_0_by_1\",\n                                                        \"typeString\": \"int_const 0\"\n                                                    },\n                                                    \"value\": \"0\"\n                                                },\n                                                \"src\": \"282:5:0\",\n                                                \"typeDescriptions\": {\n                                                    \"typeIdentifier\": \"t_uint256\",\n                                                    \"typeString\": \"uint256\"\n                                                }\n                                            },\n                                            \"id\": 9,\n                                            \"nodeType\": \"ExpressionStatement\",\n                                            \"src\": \"282:5:0\"\n                                        },\n                                        {\n                                            \"body\": {\n                                                \"id\": 11,\n                                                \"nodeType\": \"Block\",\n                                                \"src\": \"310:2:0\",\n                                                \"statements\": []\n                                            },\n                                            \"condition\": {\n                                                \"hexValue\": \"74727565\",\n                                                \"id\": 10,\n                                                \"isConstant\": false,\n                                                \"isLValue\": false,\n                                                \"isPure\": true,\n                                                \"kind\": \"bool\",\n                                                \"lValueRequested\": false,\n                                                \"nodeType\": \"Literal\",\n                                                \"src\": \"304:4:0\",\n                                                \"typeDescriptions\": {\n                                                    \"typeIdentifier\": \"t_bool\",\n                                                    \"typeString\": \"bool\"\n                                                },\n                                                \"value\": \"true\"\n                                            },\n                                            \"id\": 12,\n                                            \"nodeType\": \"WhileStatement\",\n                                            \"src\": \"297:15:0\"\n                                        }\n                                    ]\n                                },\n                                \"id\": 14,\n                                \"implemented\": true,\n                                \"kind\": \"constructor\",\n                                \"modifiers\": [],\n                                \"name\": \"\",\n                                \"nameLocation\": \"-1:-1:-1\",\n                                \"nodeType\": \"FunctionDefinition\",\n                                \"parameters\": {\n                                    \"id\": 4,\n                                    \"nodeType\": \"ParameterList\",\n                                    \"parameters\": [],\n                                    \"src\": \"269:2:0\"\n                                },\n                                \"returnParameters\": {\n                                    \"id\": 5,\n                                    \"nodeType\": \"ParameterList\",\n                                    \"parameters\": [],\n                                    \"src\": \"272:0:0\"\n                                },\n                                \"scope\": 15,\n                                \"src\": \"258:60:0\",\n                                \"stateMutability\": \"nonpayable\",\n                                \"virtual\": false,\n                                \"visibility\": \"public\"\n                            }\n                        ],\n                        \"scope\": 16,\n                        \"src\": \"56:264:0\",\n                        \"usedErrors\": [],\n                        \"usedEvents\": []\n                    }\n                ],\n                \"src\": \"36:285:0\"\n            },\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_parsing_error/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_parsing_error/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\n// This will trigger an error at the parsing stage\ncontract C {}}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_parsing_error/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"*\": [\"*\"],\n\t\t\t\t\"\": [\"*\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_outputs_on_parsing_error/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"7858\",\n            \"formattedMessage\": \"ParserError: Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition.\n --> C:5:14:\n  |\n5 | contract C {}}\n  |              ^\n\n\",\n            \"message\": \"Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition.\",\n            \"severity\": \"error\",\n            \"sourceLocation\": {\n                \"end\": 121,\n                \"file\": \"C\",\n                \"start\": 120\n            },\n            \"type\": \"ParserError\"\n        }\n    ],\n    \"sources\": {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_parsing_import_absolute_paths/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"/project/../C.sol\": {\"content\": \"//SPDX-License-Identifier: GPL-2.0\\npragma solidity >=0.0;\\nimport \\\"../L.sol\\\";\"},\n        \"/lib/L.sol\": {\"content\": \"//SPDX-License-Identifier: GPL-2.0\\npragma solidity >=0.0;\\n\"}\n    },\n    \"settings\": {\n        \"stopAfter\": \"parsing\",\n        \"remappings\": [\":/project/=/lib/\"],\n        \"outputSelection\": {\"*\": {\"\": [\"ast\"]}}\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_parsing_import_absolute_paths/output.json",
    "content": "{\n    \"sources\": {\n        \"/lib/L.sol\": {\n            \"ast\": {\n                \"absolutePath\": \"/lib/L.sol\",\n                \"id\": 2,\n                \"license\": \"GPL-2.0\",\n                \"nodeType\": \"SourceUnit\",\n                \"nodes\": [\n                    {\n                        \"id\": 1,\n                        \"literals\": [\n                            \"solidity\",\n                            \">=\",\n                            \"0.0\"\n                        ],\n                        \"nodeType\": \"PragmaDirective\",\n                        \"src\": \"35:22:0\"\n                    }\n                ],\n                \"src\": \"35:23:0\"\n            },\n            \"id\": 0\n        },\n        \"/project/../C.sol\": {\n            \"ast\": {\n                \"absolutePath\": \"/project/../C.sol\",\n                \"id\": 5,\n                \"license\": \"GPL-2.0\",\n                \"nodeType\": \"SourceUnit\",\n                \"nodes\": [\n                    {\n                        \"id\": 3,\n                        \"literals\": [\n                            \"solidity\",\n                            \">=\",\n                            \"0.0\"\n                        ],\n                        \"nodeType\": \"PragmaDirective\",\n                        \"src\": \"35:22:1\"\n                    },\n                    {\n                        \"absolutePath\": \"/lib/L.sol\",\n                        \"file\": \"../L.sol\",\n                        \"id\": 4,\n                        \"nameLocation\": \"-1:-1:-1\",\n                        \"nodeType\": \"ImportDirective\",\n                        \"src\": \"58:18:1\",\n                        \"symbolAliases\": [],\n                        \"unitAlias\": \"\"\n                    }\n                ],\n                \"src\": \"35:41:1\"\n            },\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_raw_utf16_filename/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"parse error at line 5, column 4: syntax error while parsing object key - invalid string: control character U+0000 (NUL) must be escaped to \\\\u0000; last read: '\\\"<U+0000>'; expected string literal\",\n            \"message\": \"parse error at line 5, column 4: syntax error while parsing object key - invalid string: control character U+0000 (NUL) must be escaped to \\\\u0000; last read: '\\\"<U+0000>'; expected string literal\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_secondary_source_location/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract A { constructor(uint) {} } contract B is A(2) { } contract C is A(3) {} contract D is B, C {}\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_secondary_source_location/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"3364\",\n            \"formattedMessage\": \"DeclarationError: Base constructor arguments given twice.\n --> A:2:105:\n  |\n2 | pragma solidity >=0.0; contract A { constructor(uint) {} } contract B is A(2) { } contract C is A(3) {} contract D is B, C {}\n  |                                                                                                         ^^^^^^^^^^^^^^^^^^^^^\nNote: First constructor call is here:\n --> A:2:74:\n  |\n2 | pragma solidity >=0.0; contract A { constructor(uint) {} } contract B is A(2) { } contract C is A(3) {} contract D is B, C {}\n  |                                                                          ^^^^\nNote: Second constructor call is here:\n --> A:2:97:\n  |\n2 | pragma solidity >=0.0; contract A { constructor(uint) {} } contract B is A(2) { } contract C is A(3) {} contract D is B, C {}\n  |                                                                                                 ^^^^\n\n\",\n            \"message\": \"Base constructor arguments given twice.\",\n            \"secondarySourceLocations\": [\n                {\n                    \"end\": 112,\n                    \"file\": \"A\",\n                    \"message\": \"First constructor call is here:\",\n                    \"start\": 108\n                },\n                {\n                    \"end\": 135,\n                    \"file\": \"A\",\n                    \"message\": \"Second constructor call is here:\",\n                    \"start\": 131\n                }\n            ],\n            \"severity\": \"error\",\n            \"sourceLocation\": {\n                \"end\": 160,\n                \"file\": \"A\",\n                \"start\": 139\n            },\n            \"type\": \"DeclarationError\"\n        }\n    ],\n    \"sources\": {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stack_too_deep_from_code_transform/in.sol",
    "content": "contract C {\n    function f() public {\n        uint b;\n        abi.encodePacked(\n            b, b, b, b, b, b, b, b,\n            b, b, b, b, b, b, b, b,\n            b, b, b, b, b, b, b, b\n        );\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stack_too_deep_from_code_transform/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"in.sol\": {\"urls\": [\"in.sol\"]}\n    },\n    \"settings\": {\n        \"viaIR\": true,\n        \"outputSelection\": {\n            \"*\": {\"*\": [\"evm.bytecode\"]}\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stack_too_deep_from_code_transform/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"YulException: 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 ]\nmemoryguard was present.\n --> in.sol:1:1:\n  |\n1 | contract C {\n  | ^ (Relevant source part starts here and spans across multiple lines).\n\n\",\n            \"message\": \"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 ]\nmemoryguard was present.\",\n            \"severity\": \"error\",\n            \"sourceLocation\": {\n                \"end\": 206,\n                \"file\": \"in.sol\",\n                \"start\": 0\n            },\n            \"type\": \"YulException\"\n        }\n    ],\n    \"sources\": {\n        \"in.sol\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_ast_requested/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_ast_requested/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\nimport \"A\";\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_ast_requested/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"stopAfter\": \"parsing\",\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"\": [\"ast\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_ast_requested/output.json",
    "content": "{\n    \"sources\": {\n        \"C\": {\n            \"ast\": {\n                \"absolutePath\": \"C\",\n                \"id\": 4,\n                \"license\": \"GPL-3.0\",\n                \"nodeType\": \"SourceUnit\",\n                \"nodes\": [\n                    {\n                        \"id\": 1,\n                        \"literals\": [\n                            \"solidity\",\n                            \"*\"\n                        ],\n                        \"nodeType\": \"PragmaDirective\",\n                        \"src\": \"36:18:0\"\n                    },\n                    {\n                        \"absolutePath\": \"A\",\n                        \"file\": \"A\",\n                        \"id\": 2,\n                        \"nameLocation\": \"-1:-1:-1\",\n                        \"nodeType\": \"ImportDirective\",\n                        \"src\": \"56:11:0\",\n                        \"symbolAliases\": [],\n                        \"unitAlias\": \"\"\n                    },\n                    {\n                        \"abstract\": false,\n                        \"baseContracts\": [],\n                        \"contractDependencies\": [],\n                        \"contractKind\": \"contract\",\n                        \"id\": 3,\n                        \"name\": \"C\",\n                        \"nameLocation\": \"78:1:0\",\n                        \"nodeType\": \"ContractDefinition\",\n                        \"nodes\": [],\n                        \"src\": \"69:13:0\",\n                        \"usedErrors\": [],\n                        \"usedEvents\": []\n                    }\n                ],\n                \"src\": \"36:47:0\"\n            },\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\nimport \"A\";\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"stopAfter\": \"parsing\",\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.bytecode.object\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_bytecode_requested/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Requested output selection conflicts with \\\"settings.stopAfter\\\".\",\n            \"message\": \"Requested output selection conflicts with \\\"settings.stopAfter\\\".\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\nimport \"A\";\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"stopAfter\": \"parsing\",\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\n\t\t\t\t\"abi\",\n\t\t\t\t\"devdoc\",\n\t\t\t\t\"userdoc\",\n\t\t\t\t\"metadata\",\n\t\t\t\t\"storageLayout\",\n\t\t\t\t\"evm.methodIdentifiers\"\n\t\t\t]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_stop_after_parsing_non_binary_output_requested/output.json",
    "content": "{\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_undeployable_contract_all_outputs/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\nabstract contract C {}\ninterface I {}\n"
  },
  {
    "path": "test/cmdlineTests/standard_undeployable_contract_all_outputs/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\n\t\t\t\t\"*\": [\"*\", \"ir\", \"irAst\", \"irOptimized\", \"irOptimizedAst\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_undeployable_contract_all_outputs/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"abi\": [],\n                \"devdoc\": {\n                    \"kind\": \"dev\",\n                    \"methods\": {},\n                    \"version\": 1\n                },\n                \"evm\": {\n                    \"assembly\": \"\",\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"generatedSources\": [],\n                        \"linkReferences\": {},\n                        \"object\": \"\",\n                        \"opcodes\": \"\",\n                        \"sourceMap\": \"\"\n                    },\n                    \"deployedBytecode\": {\n                        \"functionDebugData\": {},\n                        \"generatedSources\": [],\n                        \"immutableReferences\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"\",\n                        \"opcodes\": \"\",\n                        \"sourceMap\": \"\"\n                    },\n                    \"gasEstimates\": null,\n                    \"legacyAssembly\": null,\n                    \"methodIdentifiers\": {}\n                },\n                \"ir\": \"\",\n                \"irAst\": null,\n                \"irOptimized\": \"\",\n                \"irOptimizedAst\": null,\n                \"metadata\": \"{\\\"compiler\\\":{\\\"version\\\":\\\"<VERSION REMOVED>\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[],\\\"devdoc\\\":{\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"C\\\":\\\"C\\\"},\\\"evmVersion\\\":\\\"osaka\\\",\\\"experimental\\\":true,\\\"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}\",\n                \"storageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                },\n                \"transientStorageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                },\n                \"userdoc\": {\n                    \"kind\": \"user\",\n                    \"methods\": {},\n                    \"version\": 1\n                }\n            },\n            \"I\": {\n                \"abi\": [],\n                \"devdoc\": {\n                    \"kind\": \"dev\",\n                    \"methods\": {},\n                    \"version\": 1\n                },\n                \"evm\": {\n                    \"assembly\": \"\",\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"generatedSources\": [],\n                        \"linkReferences\": {},\n                        \"object\": \"\",\n                        \"opcodes\": \"\",\n                        \"sourceMap\": \"\"\n                    },\n                    \"deployedBytecode\": {\n                        \"functionDebugData\": {},\n                        \"generatedSources\": [],\n                        \"immutableReferences\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"\",\n                        \"opcodes\": \"\",\n                        \"sourceMap\": \"\"\n                    },\n                    \"gasEstimates\": null,\n                    \"legacyAssembly\": null,\n                    \"methodIdentifiers\": {}\n                },\n                \"ir\": \"\",\n                \"irAst\": null,\n                \"irOptimized\": \"\",\n                \"irOptimizedAst\": null,\n                \"metadata\": \"{\\\"compiler\\\":{\\\"version\\\":\\\"<VERSION REMOVED>\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[],\\\"devdoc\\\":{\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"C\\\":\\\"I\\\"},\\\"evmVersion\\\":\\\"osaka\\\",\\\"experimental\\\":true,\\\"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}\",\n                \"storageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                },\n                \"transientStorageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                },\n                \"userdoc\": {\n                    \"kind\": \"user\",\n                    \"methods\": {},\n                    \"version\": 1\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_urls_existing_and_missing/contract.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n"
  },
  {
    "path": "test/cmdlineTests/standard_urls_existing_and_missing/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"url_not_found.sol\": {\n            \"urls\": [\n                \"non-existent-contract-1.sol\",\n                \"contract.sol\",\n                \"non-existent-contract-2.sol\"\n            ]\n        }\n    },\n    \"settings\": {\"outputSelection\": {\"*\": { \"*\": [\"metadata\", \"evm.bytecode\"]}}}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_urls_existing_and_missing/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Cannot import url (\\\"non-existent-contract-1.sol\\\"): File not found. Searched the following locations: \\\"\\\".\",\n            \"message\": \"Cannot import url (\\\"non-existent-contract-1.sol\\\"): File not found. Searched the following locations: \\\"\\\".\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"url_not_found.sol\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_urls_missing/contract.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n"
  },
  {
    "path": "test/cmdlineTests/standard_urls_missing/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"url_not_found.sol\": {\n            \"urls\": [\n                \"non-existent-contract-1.sol\",\n                \"non-existent-contract.sol\",\n                \"non-existent-contract-2.sol\"\n            ]\n        }\n    },\n    \"settings\": {\"outputSelection\": {\"*\": { \"*\": [\"metadata\", \"evm.bytecode\"]}}}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_urls_missing/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Cannot import url (\\\"non-existent-contract-1.sol\\\"): File not found. Searched the following locations: \\\"\\\".\",\n            \"message\": \"Cannot import url (\\\"non-existent-contract-1.sol\\\"): File not found. Searched the following locations: \\\"\\\".\",\n            \"severity\": \"error\",\n            \"type\": \"IOError\"\n        },\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Cannot import url (\\\"non-existent-contract.sol\\\"): File not found. Searched the following locations: \\\"\\\".\",\n            \"message\": \"Cannot import url (\\\"non-existent-contract.sol\\\"): File not found. Searched the following locations: \\\"\\\".\",\n            \"severity\": \"error\",\n            \"type\": \"IOError\"\n        },\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Cannot import url (\\\"non-existent-contract-2.sol\\\"): File not found. Searched the following locations: \\\"\\\".\",\n            \"message\": \"Cannot import url (\\\"non-existent-contract-2.sol\\\"): File not found. Searched the following locations: \\\"\\\".\",\n            \"severity\": \"error\",\n            \"type\": \"IOError\"\n        }\n    ],\n    \"sources\": {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_via_ssa_cfg_ethdebug/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A.sol\": {\n\t\t\t\"content\": \"contract A {}\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"viaSSACFG\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.bytecode.ethdebug\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_via_ssa_cfg_ethdebug/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"SSA CFG codegen does not yet support ethdebug.\",\n            \"message\": \"SSA CFG codegen does not yet support ethdebug.\",\n            \"severity\": \"error\",\n            \"type\": \"UnimplementedFeatureError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_via_ssa_cfg_no_experimental/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\": {\n        \"A.sol\": {\n            \"content\": \"contract A { constructor() { uint x = 2; { uint y = 3; } } }\"\n        }\n    },\n    \"settings\": {\n        \"viaSSACFG\": true\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_via_ssa_cfg_no_experimental/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"'viaSSACFG' setting is experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"message\": \"'viaSSACFG' setting is experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"severity\": \"error\",\n            \"type\": \"FatalError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_via_ssa_cfg_via_ir_false/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"A.sol\": {\n\t\t\t\"content\": \"contract A {}\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"viaIR\": false,\n\t\t\"viaSSACFG\": true\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_via_ssa_cfg_via_ir_false/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.viaSSACFG\\\" requires compilation via IR.\",\n            \"message\": \"\\\"settings.viaSSACFG\\\" requires compilation via IR.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_viair_requested/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; pragma abicoder v2; contract C {} contract D { function f() public { C c = new C(); } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true\n\t\t},\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"ir\", \"evm.bytecode.object\", \"evm.bytecode.generatedSources\", \"evm.deployedBytecode.object\"] }\n\t\t},\n\t\t\"viaIR\": true\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_viair_requested/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"generatedSources\": [],\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                },\n                \"ir\": \"\n/// @use-src 0:\\\"A\\\"\nobject \\\"C_3\\\" {\n    code {\n        /// @src 0:79:92  \\\"contract C {}\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_3()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_3_deployed\\\"), datasize(\\\"C_3_deployed\\\"))\n\n        return(_1, datasize(\\\"C_3_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:79:92  \\\"contract C {}\\\"\n        function constructor_C_3() {\n\n            /// @src 0:79:92  \\\"contract C {}\\\"\n\n        }\n        /// @src 0:79:92  \\\"contract C {}\\\"\n\n    }\n    /// @use-src 0:\\\"A\\\"\n    object \\\"C_3_deployed\\\" {\n        code {\n            /// @src 0:79:92  \\\"contract C {}\\\"\n            mstore(64, memoryguard(128))\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            },\n            \"D\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"generatedSources\": [],\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"object\": \"<BYTECODE REMOVED>\"\n                    }\n                },\n                \"ir\": \"\n/// @use-src 0:\\\"A\\\"\nobject \\\"D_16\\\" {\n    code {\n        /// @src 0:93:146  \\\"contract D { function f() public { C c = new C(); } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_D_16()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"D_16_deployed\\\"), datasize(\\\"D_16_deployed\\\"))\n\n        return(_1, datasize(\\\"D_16_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:93:146  \\\"contract D { function f() public { C c = new C(); } }\\\"\n        function constructor_D_16() {\n\n            /// @src 0:93:146  \\\"contract D { function f() public { C c = new C(); } }\\\"\n\n        }\n        /// @src 0:93:146  \\\"contract D { function f() public { C c = new C(); } }\\\"\n\n    }\n    /// @use-src 0:\\\"A\\\"\n    object \\\"D_16_deployed\\\" {\n        code {\n            /// @src 0:93:146  \\\"contract D { function f() public { C c = new C(); } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_15()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function abi_encode_tuple__to__fromStack(headStart ) -> tail {\n                tail := add(headStart, 0)\n\n            }\n\n            function external_fun_f_15() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                fun_f_15()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos  )\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function panic_error_0x41() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x41)\n                revert(0, 0x24)\n            }\n\n            function revert_forward_1() {\n                let pos := allocate_unbounded()\n                returndatacopy(pos, 0, returndatasize())\n                revert(pos, returndatasize())\n            }\n\n            /// @ast-id 15\n            /// @src 0:106:144  \\\"function f() public { C c = new C(); }\\\"\n            function fun_f_15() {\n\n                /// @src 0:134:141  \\\"new C()\\\"\n\n                let _1 := allocate_unbounded()\n                let _2 := add(_1, datasize(\\\"C_3\\\"))\n                if or(gt(_2, 0xffffffffffffffff), lt(_2, _1)) { panic_error_0x41() }\n                datacopy(_1, dataoffset(\\\"C_3\\\"), datasize(\\\"C_3\\\"))\n                _2 := abi_encode_tuple__to__fromStack(_2)\n\n                let expr_12_address := create(0, _1, sub(_2, _1))\n\n                if iszero(expr_12_address) { revert_forward_1() }\n\n                /// @src 0:128:141  \\\"C c = new C()\\\"\n                let var_c_8_address := expr_12_address\n\n            }\n            /// @src 0:93:146  \\\"contract D { function f() public { C c = new C(); } }\\\"\n\n        }\n\n        /// @use-src 0:\\\"A\\\"\n        object \\\"C_3\\\" {\n            code {\n                /// @src 0:79:92  \\\"contract C {}\\\"\n                mstore(64, memoryguard(128))\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n                constructor_C_3()\n\n                let _1 := allocate_unbounded()\n                codecopy(_1, dataoffset(\\\"C_3_deployed\\\"), datasize(\\\"C_3_deployed\\\"))\n\n                return(_1, datasize(\\\"C_3_deployed\\\"))\n\n                function allocate_unbounded() -> memPtr {\n                    memPtr := mload(64)\n                }\n\n                function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                    revert(0, 0)\n                }\n\n                /// @src 0:79:92  \\\"contract C {}\\\"\n                function constructor_C_3() {\n\n                    /// @src 0:79:92  \\\"contract C {}\\\"\n\n                }\n                /// @src 0:79:92  \\\"contract C {}\\\"\n\n            }\n            /// @use-src 0:\\\"A\\\"\n            object \\\"C_3_deployed\\\" {\n                code {\n                    /// @src 0:79:92  \\\"contract C {}\\\"\n                    mstore(64, memoryguard(128))\n\n                    revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n                    function shift_right_224_unsigned(value) -> newValue {\n                        newValue :=\n\n                        shr(224, value)\n\n                    }\n\n                    function allocate_unbounded() -> memPtr {\n                        memPtr := mload(64)\n                    }\n\n                    function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                        revert(0, 0)\n                    }\n\n                }\n\n                data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n            }\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"errorCode\": \"2072\",\n            \"formattedMessage\": \"Warning: Unused local variable.\n --> A:2:93:\n  |\n2 | pragma solidity >=0.0; pragma abicoder v2; contract C {} contract D { function f() public { C c = new C(); } }\n  |                                                                                             ^^^\n\n\",\n            \"message\": \"Unused local variable.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 131,\n                \"file\": \"A\",\n                \"start\": 128\n            },\n            \"type\": \"Warning\"\n        }\n    ],\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_auxiliary_input/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"auxiliaryInput\":\n\t{\n\t\t\"key1\": \"test\"\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_auxiliary_input/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Unknown key \\\"key1\\\"\",\n            \"message\": \"Unknown key \\\"key1\\\"\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_metadata/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true,\n\t\t\t\"runs\": 200\n\t\t},\n\t\t\"evmVersion\": \"byzantium\",\n\t\t\"metadata\": {\n\t\t\t\"key1\": \"test\",\n\t\t\t\"useLiteralContent\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_metadata/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Unknown key \\\"key1\\\"\",\n            \"message\": \"Unknown key \\\"key1\\\"\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_optimizer/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"optimizer\": {\n\t\t\t\"key1\": \"test\",\n\t\t\t\"enabled\": true,\n\t\t\t\"runs\": 200\n\t\t},\n\t\t\"evmVersion\": \"byzantium\",\n\t\t\"metadata\": {\n\t\t\t\"useLiteralContent\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_optimizer/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Unknown key \\\"key1\\\"\",\n            \"message\": \"Unknown key \\\"key1\\\"\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_root/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"key1\": \"test\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_root/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Unknown key \\\"key1\\\"\",\n            \"message\": \"Unknown key \\\"key1\\\"\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_settings/input.json",
    "content": "{\n    \"language\": \"Solidity\",\n    \"sources\":\n    {\n        \"A\":\n        {\n            \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n        }\n    },\n    \"settings\":\n    {\n        \"optimizer\": {\n            \"enabled\": true,\n            \"runs\": 200\n        },\n        \"evmVersion\": \"byzantium\",\n        \"metadata\": {\n            \"useLiteralContent\": true\n        },\n        \"key1\": \"test\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_settings/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Unknown key \\\"key1\\\"\",\n            \"message\": \"Unknown key \\\"key1\\\"\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_source/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"key1\": \"test\",\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_key_source/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Unknown key \\\"key1\\\"\",\n            \"message\": \"Unknown key \\\"key1\\\"\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_auxiliary_input/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"auxiliaryInput\": [1, 2, 3]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_auxiliary_input/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"auxiliaryInput\\\" must be an object\",\n            \"message\": \"\\\"auxiliaryInput\\\" must be an object\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"abi\", \"devdoc\", \"userdoc\", \"evm.bytecode\", \"evm.assembly\", \"evm.gasEstimates\", \"evm.legacyAssembly\", \"metadata\" ],\n\t\t\t\t\"\": [ \"ast\" ]\n\t\t\t}\n\t\t}\n\t},\n\t\"auxiliaryInput\":\n\t{\n\t\t\"smtlib2responses\": \"not an object\"\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"auxiliaryInput.smtlib2responses\\\" must be an object.\",\n            \"message\": \"\\\"auxiliaryInput.smtlib2responses\\\" must be an object.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"abi\", \"devdoc\", \"userdoc\", \"evm.bytecode\", \"evm.assembly\", \"evm.gasEstimates\", \"evm.legacyAssembly\", \"metadata\" ],\n\t\t\t\t\"\": [ \"ast\" ]\n\t\t\t}\n\t\t}\n\t},\n\t\"auxiliaryInput\":\n\t{\n\t\t\"smtlib2responses\":\n\t\t{\n\t\t\t\"abc\": [\"not a string\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"smtlib2Responses.abc\\\" must be a string.\",\n            \"message\": \"\\\"smtlib2Responses.abc\\\" must be a string.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_metadata/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true,\n\t\t\t\"runs\": 200\n\t\t},\n\t\t\"evmVersion\": \"byzantium\",\n\t\t\"metadata\": [\"meta1\", \"meta2\", \"meta3\"]\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_metadata/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.metadata\\\" must be an object\",\n            \"message\": \"\\\"settings.metadata\\\" must be an object\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_optimizer/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"optimizer\": 1,\n\t\t\"evmVersion\": \"byzantium\",\n\t\t\"metadata\": {\n\t\t\t\"useLiteralContent\": true\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_optimizer/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.optimizer\\\" must be an object\",\n            \"message\": \"\\\"settings.optimizer\\\" must be an object\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_remappings/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"abi\", \"devdoc\", \"userdoc\", \"evm.bytecode\", \"evm.assembly\", \"evm.gasEstimates\", \"evm.legacyAssembly\", \"metadata\" ],\n\t\t\t\t\"\": [ \"ast\" ]\n\t\t\t}\n\t\t},\n\t\t\"remappings\": \"not an object\"\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_remappings/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.remappings\\\" must be an array of strings.\",\n            \"message\": \"\\\"settings.remappings\\\" must be an array of strings.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_remappings_entry/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"abi\", \"devdoc\", \"userdoc\", \"evm.bytecode\", \"evm.assembly\", \"evm.gasEstimates\", \"evm.legacyAssembly\", \"metadata\" ],\n\t\t\t\t\"\": [ \"ast\" ]\n\t\t\t}\n\t\t},\n\t\t\"remappings\": [1, 2 ,3 ,4]\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_remappings_entry/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.remappings\\\" must be an array of strings\",\n            \"message\": \"\\\"settings.remappings\\\" must be an array of strings\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_root/input.json",
    "content": "[\"abc\"]\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_root/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Input is not a JSON object.\",\n            \"message\": \"Input is not a JSON object.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_settings/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t[\n\t\t{\n\t\t\t\"optimizer\": {\n\t\t\t\t\"enabled\": true,\n\t\t\t\t\"runs\": 200\n\t\t\t},\n\t\t\t\"evmVersion\": \"byzantium\",\n\t\t\t\"metadata\": {\n\t\t\t\t\"useLiteralContent\": true\n\t\t\t}\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_settings/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings\\\" must be an object\",\n            \"message\": \"\\\"settings\\\" must be an object\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_source/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\": \"not an object :o\",\n\t\t\"B\": [1, 2, 3],\n\t\t\"C\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_source/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"sources.A\\\" must be an object\",\n            \"message\": \"\\\"sources.A\\\" must be an object\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_sources/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": [\"source1\", \"source2\", \"source3\"]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_sources/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"sources\\\" is not a JSON object.\",\n            \"message\": \"\\\"sources\\\" is not a JSON object.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_useLiteralContent/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true,\n\t\t\t\"runs\": 200\n\t\t},\n\t\t\"evmVersion\": \"byzantium\",\n\t\t\"metadata\": {\n\t\t\t\"useLiteralContent\": \"literalContent\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_wrong_type_useLiteralContent/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"\\\"settings.metadata.useLiteralContent\\\" must be Boolean\",\n            \"message\": \"\\\"settings.metadata.useLiteralContent\\\" must be Boolean\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"{ let x := mload(0) sstore(add(x, 0), 0) }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"*\"], \"\": [ \"*\" ] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"object\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"A\\\":99:100   */\n  0x00\n    /* \\\"A\\\":60:68   */\n  dup1\n  dup1\n  mload\n    /* \\\"A\\\":88:97   */\n  add\n    /* \\\"A\\\":81:101   */\n  sstore\n    /* \\\"A\\\":27:117   */\n  stop\n\",\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    }\n                },\n                \"ir\": \"object \\\"object\\\" {\n    code {\n        let x := mload(0)\n        sstore(add(x, 0), 0)\n    }\n}\n\",\n                \"irOptimized\": \"object \\\"object\\\" {\n    code {\n        {\n            let x := mload(0)\n            sstore(add(x, 0), 0)\n        }\n    }\n}\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"ast\": {\n                \"code\": {\n                    \"block\": {\n                        \"nativeSrc\": \"0:42:0\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"0:42:0\",\n                        \"statements\": [\n                            {\n                                \"nativeSrc\": \"2:17:0\",\n                                \"nodeType\": \"YulVariableDeclaration\",\n                                \"src\": \"2:17:0\",\n                                \"value\": {\n                                    \"arguments\": [\n                                        {\n                                            \"kind\": \"number\",\n                                            \"nativeSrc\": \"17:1:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"17:1:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"0\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"mload\",\n                                        \"nativeSrc\": \"11:5:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"11:5:0\"\n                                    },\n                                    \"nativeSrc\": \"11:8:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"11:8:0\"\n                                },\n                                \"variables\": [\n                                    {\n                                        \"name\": \"x\",\n                                        \"nativeSrc\": \"6:1:0\",\n                                        \"nodeType\": \"YulTypedName\",\n                                        \"src\": \"6:1:0\",\n                                        \"type\": \"\"\n                                    }\n                                ]\n                            },\n                            {\n                                \"expression\": {\n                                    \"arguments\": [\n                                        {\n                                            \"arguments\": [\n                                                {\n                                                    \"name\": \"x\",\n                                                    \"nativeSrc\": \"31:1:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"31:1:0\"\n                                                },\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"34:1:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"34:1:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"0\"\n                                                }\n                                            ],\n                                            \"functionName\": {\n                                                \"name\": \"add\",\n                                                \"nativeSrc\": \"27:3:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"27:3:0\"\n                                            },\n                                            \"nativeSrc\": \"27:9:0\",\n                                            \"nodeType\": \"YulFunctionCall\",\n                                            \"src\": \"27:9:0\"\n                                        },\n                                        {\n                                            \"kind\": \"number\",\n                                            \"nativeSrc\": \"38:1:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"38:1:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"0\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"sstore\",\n                                        \"nativeSrc\": \"20:6:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"20:6:0\"\n                                    },\n                                    \"nativeSrc\": \"20:20:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"20:20:0\"\n                                },\n                                \"nativeSrc\": \"20:20:0\",\n                                \"nodeType\": \"YulExpressionStatement\",\n                                \"src\": \"20:20:0\"\n                            }\n                        ]\n                    },\n                    \"nodeType\": \"YulCode\"\n                },\n                \"name\": \"object\",\n                \"nodeType\": \"YulObject\",\n                \"subObjects\": []\n            },\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_cfg_json_export/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ninterface I {\n    function f() external pure returns (uint);\n}\n\ncontract C is I {\n    function f() public pure override returns (uint) {\n        return 42;\n    }\n}\n\ncontract D {\n    function f() public returns (uint) {\n        C c = new C();\n        return c.f();\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_cfg_json_export/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true\n\t\t},\n\t\t\"viaIR\": true,\n\t\t\"outputSelection\": {\"*\": {\"*\": [\"yulCFGJson\"]}}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_cfg_json_export/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C\": {\n                \"yulCFGJson\": {\n                    \"C_19\": {\n                        \"blocks\": [\n                            {\n                                \"exit\": {\n                                    \"cond\": \"v1\",\n                                    \"targets\": [\n                                        \"Block2\",\n                                        \"Block1\"\n                                    ],\n                                    \"type\": \"ConditionalJump\"\n                                },\n                                \"id\": \"Block0\",\n                                \"instructions\": [\n                                    {\n                                        \"in\": [],\n                                        \"literalArgs\": [\n                                            \"0x80\"\n                                        ],\n                                        \"op\": \"memoryguard\",\n                                        \"out\": [\n                                            \"v0\"\n                                        ]\n                                    },\n                                    {\n                                        \"in\": [\n                                            \"v0\",\n                                            \"0x40\"\n                                        ],\n                                        \"op\": \"mstore\",\n                                        \"out\": []\n                                    },\n                                    {\n                                        \"in\": [],\n                                        \"op\": \"callvalue\",\n                                        \"out\": [\n                                            \"v1\"\n                                        ]\n                                    }\n                                ],\n                                \"liveness\": {\n                                    \"in\": [],\n                                    \"out\": [\n                                        \"v0\"\n                                    ]\n                                },\n                                \"type\": \"BuiltinCall\"\n                            },\n                            {\n                                \"exit\": {\n                                    \"type\": \"Terminated\"\n                                },\n                                \"id\": \"Block2\",\n                                \"instructions\": [\n                                    {\n                                        \"in\": [],\n                                        \"literalArgs\": [\n                                            \"C_19_deployed\"\n                                        ],\n                                        \"op\": \"datasize\",\n                                        \"out\": [\n                                            \"v2\"\n                                        ]\n                                    },\n                                    {\n                                        \"in\": [],\n                                        \"literalArgs\": [\n                                            \"C_19_deployed\"\n                                        ],\n                                        \"op\": \"dataoffset\",\n                                        \"out\": [\n                                            \"v3\"\n                                        ]\n                                    },\n                                    {\n                                        \"in\": [\n                                            \"v2\",\n                                            \"v3\",\n                                            \"v0\"\n                                        ],\n                                        \"op\": \"codecopy\",\n                                        \"out\": []\n                                    },\n                                    {\n                                        \"in\": [\n                                            \"v2\",\n                                            \"v0\"\n                                        ],\n                                        \"op\": \"return\",\n                                        \"out\": []\n                                    }\n                                ],\n                                \"liveness\": {\n                                    \"in\": [\n                                        \"v0\"\n                                    ],\n                                    \"out\": []\n                                },\n                                \"type\": \"BuiltinCall\"\n                            },\n                            {\n                                \"exit\": {\n                                    \"type\": \"Terminated\"\n                                },\n                                \"id\": \"Block1\",\n                                \"instructions\": [\n                                    {\n                                        \"in\": [\n                                            \"0x00\",\n                                            \"0x00\"\n                                        ],\n                                        \"op\": \"revert\",\n                                        \"out\": []\n                                    }\n                                ],\n                                \"liveness\": {\n                                    \"in\": [],\n                                    \"out\": []\n                                },\n                                \"type\": \"BuiltinCall\"\n                            }\n                        ],\n                        \"functions\": {},\n                        \"subObjects\": {\n                            \"C_19_deployed\": {\n                                \"blocks\": [\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v3\",\n                                            \"targets\": [\n                                                \"Block2\",\n                                                \"Block1\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block0\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [],\n                                                \"literalArgs\": [\n                                                    \"0x80\"\n                                                ],\n                                                \"op\": \"memoryguard\",\n                                                \"out\": [\n                                                    \"v0\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v0\",\n                                                    \"0x40\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"calldatasize\",\n                                                \"out\": [\n                                                    \"v1\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x04\",\n                                                    \"v1\"\n                                                ],\n                                                \"op\": \"lt\",\n                                                \"out\": [\n                                                    \"v2\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v2\"\n                                                ],\n                                                \"op\": \"iszero\",\n                                                \"out\": [\n                                                    \"v3\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block2\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v6\",\n                                            \"targets\": [\n                                                \"Block4\",\n                                                \"Block3\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block1\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"calldataload\",\n                                                \"out\": [\n                                                    \"v4\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v4\",\n                                                    \"0xe0\"\n                                                ],\n                                                \"op\": \"shr\",\n                                                \"out\": [\n                                                    \"v5\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v5\",\n                                                    \"0x26121ff0\"\n                                                ],\n                                                \"op\": \"eq\",\n                                                \"out\": [\n                                                    \"v6\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"targets\": [\n                                                \"Block2\"\n                                            ],\n                                            \"type\": \"Jump\"\n                                        },\n                                        \"id\": \"Block4\",\n                                        \"instructions\": [],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        }\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v7\",\n                                            \"targets\": [\n                                                \"Block6\",\n                                                \"Block5\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block3\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"callvalue\",\n                                                \"out\": [\n                                                    \"v7\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v11\",\n                                            \"targets\": [\n                                                \"Block9\",\n                                                \"Block8\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block6\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x03\"\n                                                ],\n                                                \"op\": \"not\",\n                                                \"out\": [\n                                                    \"v8\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"calldatasize\",\n                                                \"out\": [\n                                                    \"v9\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v8\",\n                                                    \"v9\"\n                                                ],\n                                                \"op\": \"add\",\n                                                \"out\": [\n                                                    \"v10\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"v10\"\n                                                ],\n                                                \"op\": \"slt\",\n                                                \"out\": [\n                                                    \"v11\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block5\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block9\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x2a\",\n                                                    \"v0\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x20\",\n                                                    \"v0\"\n                                                ],\n                                                \"op\": \"return\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block8\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    }\n                                ],\n                                \"functions\": {},\n                                \"subObjects\": {}\n                            },\n                            \"type\": \"subObject\"\n                        }\n                    },\n                    \"type\": \"Object\"\n                }\n            },\n            \"D\": {\n                \"yulCFGJson\": {\n                    \"D_38\": {\n                        \"blocks\": [\n                            {\n                                \"exit\": {\n                                    \"cond\": \"v1\",\n                                    \"targets\": [\n                                        \"Block2\",\n                                        \"Block1\"\n                                    ],\n                                    \"type\": \"ConditionalJump\"\n                                },\n                                \"id\": \"Block0\",\n                                \"instructions\": [\n                                    {\n                                        \"in\": [],\n                                        \"literalArgs\": [\n                                            \"0x80\"\n                                        ],\n                                        \"op\": \"memoryguard\",\n                                        \"out\": [\n                                            \"v0\"\n                                        ]\n                                    },\n                                    {\n                                        \"in\": [\n                                            \"v0\",\n                                            \"0x40\"\n                                        ],\n                                        \"op\": \"mstore\",\n                                        \"out\": []\n                                    },\n                                    {\n                                        \"in\": [],\n                                        \"op\": \"callvalue\",\n                                        \"out\": [\n                                            \"v1\"\n                                        ]\n                                    }\n                                ],\n                                \"liveness\": {\n                                    \"in\": [],\n                                    \"out\": [\n                                        \"v0\"\n                                    ]\n                                },\n                                \"type\": \"BuiltinCall\"\n                            },\n                            {\n                                \"exit\": {\n                                    \"type\": \"Terminated\"\n                                },\n                                \"id\": \"Block2\",\n                                \"instructions\": [\n                                    {\n                                        \"in\": [],\n                                        \"literalArgs\": [\n                                            \"D_38_deployed\"\n                                        ],\n                                        \"op\": \"datasize\",\n                                        \"out\": [\n                                            \"v2\"\n                                        ]\n                                    },\n                                    {\n                                        \"in\": [],\n                                        \"literalArgs\": [\n                                            \"D_38_deployed\"\n                                        ],\n                                        \"op\": \"dataoffset\",\n                                        \"out\": [\n                                            \"v3\"\n                                        ]\n                                    },\n                                    {\n                                        \"in\": [\n                                            \"v2\",\n                                            \"v3\",\n                                            \"v0\"\n                                        ],\n                                        \"op\": \"codecopy\",\n                                        \"out\": []\n                                    },\n                                    {\n                                        \"in\": [\n                                            \"v2\",\n                                            \"v0\"\n                                        ],\n                                        \"op\": \"return\",\n                                        \"out\": []\n                                    }\n                                ],\n                                \"liveness\": {\n                                    \"in\": [\n                                        \"v0\"\n                                    ],\n                                    \"out\": []\n                                },\n                                \"type\": \"BuiltinCall\"\n                            },\n                            {\n                                \"exit\": {\n                                    \"type\": \"Terminated\"\n                                },\n                                \"id\": \"Block1\",\n                                \"instructions\": [\n                                    {\n                                        \"in\": [\n                                            \"0x00\",\n                                            \"0x00\"\n                                        ],\n                                        \"op\": \"revert\",\n                                        \"out\": []\n                                    }\n                                ],\n                                \"liveness\": {\n                                    \"in\": [],\n                                    \"out\": []\n                                },\n                                \"type\": \"BuiltinCall\"\n                            }\n                        ],\n                        \"functions\": {},\n                        \"subObjects\": {\n                            \"D_38_deployed\": {\n                                \"blocks\": [\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v3\",\n                                            \"targets\": [\n                                                \"Block2\",\n                                                \"Block1\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block0\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [],\n                                                \"literalArgs\": [\n                                                    \"0x80\"\n                                                ],\n                                                \"op\": \"memoryguard\",\n                                                \"out\": [\n                                                    \"v0\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v0\",\n                                                    \"0x40\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"calldatasize\",\n                                                \"out\": [\n                                                    \"v1\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x04\",\n                                                    \"v1\"\n                                                ],\n                                                \"op\": \"lt\",\n                                                \"out\": [\n                                                    \"v2\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v2\"\n                                                ],\n                                                \"op\": \"iszero\",\n                                                \"out\": [\n                                                    \"v3\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block2\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v6\",\n                                            \"targets\": [\n                                                \"Block4\",\n                                                \"Block3\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block1\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"calldataload\",\n                                                \"out\": [\n                                                    \"v4\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v4\",\n                                                    \"0xe0\"\n                                                ],\n                                                \"op\": \"shr\",\n                                                \"out\": [\n                                                    \"v5\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v5\",\n                                                    \"0x26121ff0\"\n                                                ],\n                                                \"op\": \"eq\",\n                                                \"out\": [\n                                                    \"v6\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"targets\": [\n                                                \"Block2\"\n                                            ],\n                                            \"type\": \"Jump\"\n                                        },\n                                        \"id\": \"Block4\",\n                                        \"instructions\": [],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        }\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v7\",\n                                            \"targets\": [\n                                                \"Block6\",\n                                                \"Block5\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block3\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"callvalue\",\n                                                \"out\": [\n                                                    \"v7\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v11\",\n                                            \"targets\": [\n                                                \"Block9\",\n                                                \"Block8\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block6\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x03\"\n                                                ],\n                                                \"op\": \"not\",\n                                                \"out\": [\n                                                    \"v8\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"calldatasize\",\n                                                \"out\": [\n                                                    \"v9\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v8\",\n                                                    \"v9\"\n                                                ],\n                                                \"op\": \"add\",\n                                                \"out\": [\n                                                    \"v10\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"v10\"\n                                                ],\n                                                \"op\": \"slt\",\n                                                \"out\": [\n                                                    \"v11\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block5\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v16\",\n                                            \"targets\": [\n                                                \"Block12\",\n                                                \"Block11\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block9\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [],\n                                                \"literalArgs\": [\n                                                    \"C_19\"\n                                                ],\n                                                \"op\": \"datasize\",\n                                                \"out\": [\n                                                    \"v12\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v12\",\n                                                    \"v0\"\n                                                ],\n                                                \"op\": \"add\",\n                                                \"out\": [\n                                                    \"v13\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v0\",\n                                                    \"v13\"\n                                                ],\n                                                \"op\": \"lt\",\n                                                \"out\": [\n                                                    \"v14\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0xffffffffffffffff\",\n                                                    \"v13\"\n                                                ],\n                                                \"op\": \"gt\",\n                                                \"out\": [\n                                                    \"v15\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v14\",\n                                                    \"v15\"\n                                                ],\n                                                \"op\": \"or\",\n                                                \"out\": [\n                                                    \"v16\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": [\n                                                \"v0\",\n                                                \"v13\",\n                                                \"v12\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block8\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v21\",\n                                            \"targets\": [\n                                                \"Block15\",\n                                                \"Block14\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block12\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [],\n                                                \"literalArgs\": [\n                                                    \"C_19\"\n                                                ],\n                                                \"op\": \"dataoffset\",\n                                                \"out\": [\n                                                    \"v18\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v12\",\n                                                    \"v18\",\n                                                    \"v0\"\n                                                ],\n                                                \"op\": \"datacopy\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v0\",\n                                                    \"v13\"\n                                                ],\n                                                \"op\": \"sub\",\n                                                \"out\": [\n                                                    \"v19\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v19\",\n                                                    \"v0\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"create\",\n                                                \"out\": [\n                                                    \"v20\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v20\"\n                                                ],\n                                                \"op\": \"iszero\",\n                                                \"out\": [\n                                                    \"v21\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\",\n                                                \"v13\",\n                                                \"v12\"\n                                            ],\n                                            \"out\": [\n                                                \"v20\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block11\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x4e487b71\",\n                                                    \"0xe0\"\n                                                ],\n                                                \"op\": \"shl\",\n                                                \"out\": [\n                                                    \"v17\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v17\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x41\",\n                                                    \"0x04\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x24\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v32\",\n                                            \"targets\": [\n                                                \"Block18\",\n                                                \"Block17\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block15\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x40\"\n                                                ],\n                                                \"op\": \"mload\",\n                                                \"out\": [\n                                                    \"v25\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x026121ff\",\n                                                    \"0xe4\"\n                                                ],\n                                                \"op\": \"shl\",\n                                                \"out\": [\n                                                    \"v26\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v26\",\n                                                    \"v25\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x01\",\n                                                    \"0xa0\"\n                                                ],\n                                                \"op\": \"shl\",\n                                                \"out\": [\n                                                    \"v27\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x01\",\n                                                    \"v27\"\n                                                ],\n                                                \"op\": \"sub\",\n                                                \"out\": [\n                                                    \"v28\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v28\",\n                                                    \"v20\"\n                                                ],\n                                                \"op\": \"and\",\n                                                \"out\": [\n                                                    \"v29\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"gas\",\n                                                \"out\": [\n                                                    \"v30\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x20\",\n                                                    \"v25\",\n                                                    \"0x04\",\n                                                    \"v25\",\n                                                    \"v29\",\n                                                    \"v30\"\n                                                ],\n                                                \"op\": \"staticcall\",\n                                                \"out\": [\n                                                    \"v31\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v31\"\n                                                ],\n                                                \"op\": \"iszero\",\n                                                \"out\": [\n                                                    \"v32\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v20\"\n                                            ],\n                                            \"out\": [\n                                                \"v25\",\n                                                \"v31\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block14\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x40\"\n                                                ],\n                                                \"op\": \"mload\",\n                                                \"out\": [\n                                                    \"v22\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"returndatasize\",\n                                                \"out\": [\n                                                    \"v23\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v23\",\n                                                    \"0x00\",\n                                                    \"v22\"\n                                                ],\n                                                \"op\": \"returndatacopy\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"returndatasize\",\n                                                \"out\": [\n                                                    \"v24\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v24\",\n                                                    \"v22\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v31\",\n                                            \"targets\": [\n                                                \"Block21\",\n                                                \"Block20\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block18\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"LiteralAssignment\",\n                                                \"out\": [\n                                                    \"v36\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v25\",\n                                                \"v31\"\n                                            ],\n                                            \"out\": [\n                                                \"v36\",\n                                                \"v25\"\n                                            ]\n                                        }\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block17\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x40\"\n                                                ],\n                                                \"op\": \"mload\",\n                                                \"out\": [\n                                                    \"v33\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"returndatasize\",\n                                                \"out\": [\n                                                    \"v34\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v34\",\n                                                    \"0x00\",\n                                                    \"v33\"\n                                                ],\n                                                \"op\": \"returndatacopy\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"returndatasize\",\n                                                \"out\": [\n                                                    \"v35\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v35\",\n                                                    \"v33\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"entries\": [\n                                            \"Block18\",\n                                            \"Block28\"\n                                        ],\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block21\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"v36\",\n                                                    \"v52\"\n                                                ],\n                                                \"op\": \"PhiFunction\",\n                                                \"out\": [\n                                                    \"phi26\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x40\"\n                                                ],\n                                                \"op\": \"mload\",\n                                                \"out\": [\n                                                    \"v53\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"phi26\",\n                                                    \"v53\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x20\",\n                                                    \"v53\"\n                                                ],\n                                                \"op\": \"return\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"phi26\"\n                                            ],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v39\",\n                                            \"targets\": [\n                                                \"Block23\",\n                                                \"Block22\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block20\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x20\"\n                                                ],\n                                                \"op\": \"LiteralAssignment\",\n                                                \"out\": [\n                                                    \"v37\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"returndatasize\",\n                                                \"out\": [\n                                                    \"v38\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v38\",\n                                                    \"0x20\"\n                                                ],\n                                                \"op\": \"gt\",\n                                                \"out\": [\n                                                    \"v39\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v25\"\n                                            ],\n                                            \"out\": [\n                                                \"v37\",\n                                                \"v25\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"entries\": [\n                                            \"Block20\",\n                                            \"Block22\"\n                                        ],\n                                        \"exit\": {\n                                            \"cond\": \"v47\",\n                                            \"targets\": [\n                                                \"Block25\",\n                                                \"Block24\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block23\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"v37\",\n                                                    \"v40\"\n                                                ],\n                                                \"op\": \"PhiFunction\",\n                                                \"out\": [\n                                                    \"phi14\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x1f\"\n                                                ],\n                                                \"op\": \"not\",\n                                                \"out\": [\n                                                    \"v41\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x1f\",\n                                                    \"phi14\"\n                                                ],\n                                                \"op\": \"add\",\n                                                \"out\": [\n                                                    \"v42\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v41\",\n                                                    \"v42\"\n                                                ],\n                                                \"op\": \"and\",\n                                                \"out\": [\n                                                    \"v43\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v43\",\n                                                    \"v25\"\n                                                ],\n                                                \"op\": \"add\",\n                                                \"out\": [\n                                                    \"v44\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v25\",\n                                                    \"v44\"\n                                                ],\n                                                \"op\": \"lt\",\n                                                \"out\": [\n                                                    \"v45\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0xffffffffffffffff\",\n                                                    \"v44\"\n                                                ],\n                                                \"op\": \"gt\",\n                                                \"out\": [\n                                                    \"v46\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v45\",\n                                                    \"v46\"\n                                                ],\n                                                \"op\": \"or\",\n                                                \"out\": [\n                                                    \"v47\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v25\",\n                                                \"phi14\"\n                                            ],\n                                            \"out\": [\n                                                \"v25\",\n                                                \"phi14\",\n                                                \"v44\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"targets\": [\n                                                \"Block23\"\n                                            ],\n                                            \"type\": \"Jump\"\n                                        },\n                                        \"id\": \"Block22\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"returndatasize\",\n                                                \"out\": [\n                                                    \"v40\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v25\"\n                                            ],\n                                            \"out\": [\n                                                \"v40\",\n                                                \"v25\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v51\",\n                                            \"targets\": [\n                                                \"Block28\",\n                                                \"Block27\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block25\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"v44\",\n                                                    \"0x40\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"phi14\",\n                                                    \"v25\"\n                                                ],\n                                                \"op\": \"add\",\n                                                \"out\": [\n                                                    \"v49\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v25\",\n                                                    \"v49\"\n                                                ],\n                                                \"op\": \"sub\",\n                                                \"out\": [\n                                                    \"v50\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x20\",\n                                                    \"v50\"\n                                                ],\n                                                \"op\": \"slt\",\n                                                \"out\": [\n                                                    \"v51\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v25\",\n                                                \"phi14\",\n                                                \"v44\"\n                                            ],\n                                            \"out\": [\n                                                \"v25\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block24\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x4e487b71\",\n                                                    \"0xe0\"\n                                                ],\n                                                \"op\": \"shl\",\n                                                \"out\": [\n                                                    \"v48\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v48\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x41\",\n                                                    \"0x04\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x24\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"targets\": [\n                                                \"Block21\"\n                                            ],\n                                            \"type\": \"Jump\"\n                                        },\n                                        \"id\": \"Block28\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"v25\"\n                                                ],\n                                                \"op\": \"mload\",\n                                                \"out\": [\n                                                    \"v52\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v25\"\n                                            ],\n                                            \"out\": [\n                                                \"v52\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block27\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    }\n                                ],\n                                \"functions\": {},\n                                \"subObjects\": {\n                                    \"C_19\": {\n                                        \"blocks\": [\n                                            {\n                                                \"exit\": {\n                                                    \"cond\": \"v1\",\n                                                    \"targets\": [\n                                                        \"Block2\",\n                                                        \"Block1\"\n                                                    ],\n                                                    \"type\": \"ConditionalJump\"\n                                                },\n                                                \"id\": \"Block0\",\n                                                \"instructions\": [\n                                                    {\n                                                        \"in\": [],\n                                                        \"literalArgs\": [\n                                                            \"0x80\"\n                                                        ],\n                                                        \"op\": \"memoryguard\",\n                                                        \"out\": [\n                                                            \"v0\"\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"in\": [\n                                                            \"v0\",\n                                                            \"0x40\"\n                                                        ],\n                                                        \"op\": \"mstore\",\n                                                        \"out\": []\n                                                    },\n                                                    {\n                                                        \"in\": [],\n                                                        \"op\": \"callvalue\",\n                                                        \"out\": [\n                                                            \"v1\"\n                                                        ]\n                                                    }\n                                                ],\n                                                \"liveness\": {\n                                                    \"in\": [],\n                                                    \"out\": [\n                                                        \"v0\"\n                                                    ]\n                                                },\n                                                \"type\": \"BuiltinCall\"\n                                            },\n                                            {\n                                                \"exit\": {\n                                                    \"type\": \"Terminated\"\n                                                },\n                                                \"id\": \"Block2\",\n                                                \"instructions\": [\n                                                    {\n                                                        \"in\": [],\n                                                        \"literalArgs\": [\n                                                            \"C_19_deployed\"\n                                                        ],\n                                                        \"op\": \"datasize\",\n                                                        \"out\": [\n                                                            \"v2\"\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"in\": [],\n                                                        \"literalArgs\": [\n                                                            \"C_19_deployed\"\n                                                        ],\n                                                        \"op\": \"dataoffset\",\n                                                        \"out\": [\n                                                            \"v3\"\n                                                        ]\n                                                    },\n                                                    {\n                                                        \"in\": [\n                                                            \"v2\",\n                                                            \"v3\",\n                                                            \"v0\"\n                                                        ],\n                                                        \"op\": \"codecopy\",\n                                                        \"out\": []\n                                                    },\n                                                    {\n                                                        \"in\": [\n                                                            \"v2\",\n                                                            \"v0\"\n                                                        ],\n                                                        \"op\": \"return\",\n                                                        \"out\": []\n                                                    }\n                                                ],\n                                                \"liveness\": {\n                                                    \"in\": [\n                                                        \"v0\"\n                                                    ],\n                                                    \"out\": []\n                                                },\n                                                \"type\": \"BuiltinCall\"\n                                            },\n                                            {\n                                                \"exit\": {\n                                                    \"type\": \"Terminated\"\n                                                },\n                                                \"id\": \"Block1\",\n                                                \"instructions\": [\n                                                    {\n                                                        \"in\": [\n                                                            \"0x00\",\n                                                            \"0x00\"\n                                                        ],\n                                                        \"op\": \"revert\",\n                                                        \"out\": []\n                                                    }\n                                                ],\n                                                \"liveness\": {\n                                                    \"in\": [],\n                                                    \"out\": []\n                                                },\n                                                \"type\": \"BuiltinCall\"\n                                            }\n                                        ],\n                                        \"functions\": {},\n                                        \"subObjects\": {\n                                            \"C_19_deployed\": {\n                                                \"blocks\": [\n                                                    {\n                                                        \"exit\": {\n                                                            \"cond\": \"v3\",\n                                                            \"targets\": [\n                                                                \"Block2\",\n                                                                \"Block1\"\n                                                            ],\n                                                            \"type\": \"ConditionalJump\"\n                                                        },\n                                                        \"id\": \"Block0\",\n                                                        \"instructions\": [\n                                                            {\n                                                                \"in\": [],\n                                                                \"literalArgs\": [\n                                                                    \"0x80\"\n                                                                ],\n                                                                \"op\": \"memoryguard\",\n                                                                \"out\": [\n                                                                    \"v0\"\n                                                                ]\n                                                            },\n                                                            {\n                                                                \"in\": [\n                                                                    \"v0\",\n                                                                    \"0x40\"\n                                                                ],\n                                                                \"op\": \"mstore\",\n                                                                \"out\": []\n                                                            },\n                                                            {\n                                                                \"in\": [],\n                                                                \"op\": \"calldatasize\",\n                                                                \"out\": [\n                                                                    \"v1\"\n                                                                ]\n                                                            },\n                                                            {\n                                                                \"in\": [\n                                                                    \"0x04\",\n                                                                    \"v1\"\n                                                                ],\n                                                                \"op\": \"lt\",\n                                                                \"out\": [\n                                                                    \"v2\"\n                                                                ]\n                                                            },\n                                                            {\n                                                                \"in\": [\n                                                                    \"v2\"\n                                                                ],\n                                                                \"op\": \"iszero\",\n                                                                \"out\": [\n                                                                    \"v3\"\n                                                                ]\n                                                            }\n                                                        ],\n                                                        \"liveness\": {\n                                                            \"in\": [],\n                                                            \"out\": [\n                                                                \"v0\"\n                                                            ]\n                                                        },\n                                                        \"type\": \"BuiltinCall\"\n                                                    },\n                                                    {\n                                                        \"exit\": {\n                                                            \"type\": \"Terminated\"\n                                                        },\n                                                        \"id\": \"Block2\",\n                                                        \"instructions\": [\n                                                            {\n                                                                \"in\": [\n                                                                    \"0x00\",\n                                                                    \"0x00\"\n                                                                ],\n                                                                \"op\": \"revert\",\n                                                                \"out\": []\n                                                            }\n                                                        ],\n                                                        \"liveness\": {\n                                                            \"in\": [],\n                                                            \"out\": []\n                                                        },\n                                                        \"type\": \"BuiltinCall\"\n                                                    },\n                                                    {\n                                                        \"exit\": {\n                                                            \"cond\": \"v6\",\n                                                            \"targets\": [\n                                                                \"Block4\",\n                                                                \"Block3\"\n                                                            ],\n                                                            \"type\": \"ConditionalJump\"\n                                                        },\n                                                        \"id\": \"Block1\",\n                                                        \"instructions\": [\n                                                            {\n                                                                \"in\": [\n                                                                    \"0x00\"\n                                                                ],\n                                                                \"op\": \"calldataload\",\n                                                                \"out\": [\n                                                                    \"v4\"\n                                                                ]\n                                                            },\n                                                            {\n                                                                \"in\": [\n                                                                    \"v4\",\n                                                                    \"0xe0\"\n                                                                ],\n                                                                \"op\": \"shr\",\n                                                                \"out\": [\n                                                                    \"v5\"\n                                                                ]\n                                                            },\n                                                            {\n                                                                \"in\": [\n                                                                    \"v5\",\n                                                                    \"0x26121ff0\"\n                                                                ],\n                                                                \"op\": \"eq\",\n                                                                \"out\": [\n                                                                    \"v6\"\n                                                                ]\n                                                            }\n                                                        ],\n                                                        \"liveness\": {\n                                                            \"in\": [\n                                                                \"v0\"\n                                                            ],\n                                                            \"out\": [\n                                                                \"v0\"\n                                                            ]\n                                                        },\n                                                        \"type\": \"BuiltinCall\"\n                                                    },\n                                                    {\n                                                        \"exit\": {\n                                                            \"targets\": [\n                                                                \"Block2\"\n                                                            ],\n                                                            \"type\": \"Jump\"\n                                                        },\n                                                        \"id\": \"Block4\",\n                                                        \"instructions\": [],\n                                                        \"liveness\": {\n                                                            \"in\": [],\n                                                            \"out\": []\n                                                        }\n                                                    },\n                                                    {\n                                                        \"exit\": {\n                                                            \"cond\": \"v7\",\n                                                            \"targets\": [\n                                                                \"Block6\",\n                                                                \"Block5\"\n                                                            ],\n                                                            \"type\": \"ConditionalJump\"\n                                                        },\n                                                        \"id\": \"Block3\",\n                                                        \"instructions\": [\n                                                            {\n                                                                \"in\": [],\n                                                                \"op\": \"callvalue\",\n                                                                \"out\": [\n                                                                    \"v7\"\n                                                                ]\n                                                            }\n                                                        ],\n                                                        \"liveness\": {\n                                                            \"in\": [\n                                                                \"v0\"\n                                                            ],\n                                                            \"out\": [\n                                                                \"v0\"\n                                                            ]\n                                                        },\n                                                        \"type\": \"BuiltinCall\"\n                                                    },\n                                                    {\n                                                        \"exit\": {\n                                                            \"cond\": \"v11\",\n                                                            \"targets\": [\n                                                                \"Block9\",\n                                                                \"Block8\"\n                                                            ],\n                                                            \"type\": \"ConditionalJump\"\n                                                        },\n                                                        \"id\": \"Block6\",\n                                                        \"instructions\": [\n                                                            {\n                                                                \"in\": [\n                                                                    \"0x03\"\n                                                                ],\n                                                                \"op\": \"not\",\n                                                                \"out\": [\n                                                                    \"v8\"\n                                                                ]\n                                                            },\n                                                            {\n                                                                \"in\": [],\n                                                                \"op\": \"calldatasize\",\n                                                                \"out\": [\n                                                                    \"v9\"\n                                                                ]\n                                                            },\n                                                            {\n                                                                \"in\": [\n                                                                    \"v8\",\n                                                                    \"v9\"\n                                                                ],\n                                                                \"op\": \"add\",\n                                                                \"out\": [\n                                                                    \"v10\"\n                                                                ]\n                                                            },\n                                                            {\n                                                                \"in\": [\n                                                                    \"0x00\",\n                                                                    \"v10\"\n                                                                ],\n                                                                \"op\": \"slt\",\n                                                                \"out\": [\n                                                                    \"v11\"\n                                                                ]\n                                                            }\n                                                        ],\n                                                        \"liveness\": {\n                                                            \"in\": [\n                                                                \"v0\"\n                                                            ],\n                                                            \"out\": [\n                                                                \"v0\"\n                                                            ]\n                                                        },\n                                                        \"type\": \"BuiltinCall\"\n                                                    },\n                                                    {\n                                                        \"exit\": {\n                                                            \"type\": \"Terminated\"\n                                                        },\n                                                        \"id\": \"Block5\",\n                                                        \"instructions\": [\n                                                            {\n                                                                \"in\": [\n                                                                    \"0x00\",\n                                                                    \"0x00\"\n                                                                ],\n                                                                \"op\": \"revert\",\n                                                                \"out\": []\n                                                            }\n                                                        ],\n                                                        \"liveness\": {\n                                                            \"in\": [],\n                                                            \"out\": []\n                                                        },\n                                                        \"type\": \"BuiltinCall\"\n                                                    },\n                                                    {\n                                                        \"exit\": {\n                                                            \"type\": \"Terminated\"\n                                                        },\n                                                        \"id\": \"Block9\",\n                                                        \"instructions\": [\n                                                            {\n                                                                \"in\": [\n                                                                    \"0x2a\",\n                                                                    \"v0\"\n                                                                ],\n                                                                \"op\": \"mstore\",\n                                                                \"out\": []\n                                                            },\n                                                            {\n                                                                \"in\": [\n                                                                    \"0x20\",\n                                                                    \"v0\"\n                                                                ],\n                                                                \"op\": \"return\",\n                                                                \"out\": []\n                                                            }\n                                                        ],\n                                                        \"liveness\": {\n                                                            \"in\": [\n                                                                \"v0\"\n                                                            ],\n                                                            \"out\": []\n                                                        },\n                                                        \"type\": \"BuiltinCall\"\n                                                    },\n                                                    {\n                                                        \"exit\": {\n                                                            \"type\": \"Terminated\"\n                                                        },\n                                                        \"id\": \"Block8\",\n                                                        \"instructions\": [\n                                                            {\n                                                                \"in\": [\n                                                                    \"0x00\",\n                                                                    \"0x00\"\n                                                                ],\n                                                                \"op\": \"revert\",\n                                                                \"out\": []\n                                                            }\n                                                        ],\n                                                        \"liveness\": {\n                                                            \"in\": [],\n                                                            \"out\": []\n                                                        },\n                                                        \"type\": \"BuiltinCall\"\n                                                    }\n                                                ],\n                                                \"functions\": {},\n                                                \"subObjects\": {}\n                                            },\n                                            \"type\": \"subObject\"\n                                        }\n                                    },\n                                    \"type\": \"subObject\"\n                                }\n                            },\n                            \"type\": \"subObject\"\n                        }\n                    },\n                    \"type\": \"Object\"\n                }\n            },\n            \"I\": {\n                \"yulCFGJson\": null\n            }\n        }\n    },\n    \"sources\": {\n        \"C\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_code_generation_error/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_code_generation_error/in.yul",
    "content": "object \"C\" {\n    code {}\n\n    object \"C_deployed\" {\n        code {\n            sstore(0, loadimmutable(\"1\"))\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_code_generation_error/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_code_generation_error/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"CodeGenerationError: Some immutables were read from but never assigned, possibly because of optimization.\n\n\",\n            \"message\": \"Some immutables were read from but never assigned, possibly because of optimization.\",\n            \"severity\": \"error\",\n            \"type\": \"CodeGenerationError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\n\t\t\t\"urls\": [\n\t\t\t\t\"in.yul\"\n\t\t\t]\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"debug\": {\"debugInfo\": [\"ethdebug\"]},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"ir\", \"irOptimized\", \"evm.bytecode.ethdebug\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C_6_deployed\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"input.sol\\\"\nobject \\\"C_6_deployed\\\" {\n    code {\n        /// @src 0:60:101\n        mstore(64, 128)\n        fun_f_5()\n        /// @src 0:77:99\n        function fun_f_5()\n        { sstore(0, 42) }\n    }\n}\n\",\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"input.sol\\\"\nobject \\\"C_6_deployed\\\" {\n    code {\n        {\n            /// @src 0:60:101\n            mstore(64, 128)\n            fun_f()\n        }\n        /// @src 0:77:99\n        function fun_f()\n        { sstore(0, 42) }\n    }\n}\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\n\t\t\t\"urls\": [\n\t\t\t\t\"in.yul\"\n\t\t\t]\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"eofVersion\": 1,\n\t\t\"evmVersion\": \"osaka\",\n\t\t\"debug\": {\"debugInfo\": [\"ethdebug\"]},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"ir\", \"irOptimized\", \"evm.bytecode.ethdebug\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C_6_deployed\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"input.sol\\\"\nobject \\\"C_6_deployed\\\" {\n    code {\n        /// @src 0:60:101\n        mstore(64, 128)\n        fun_f_5()\n        /// @src 0:77:99\n        function fun_f_5()\n        { sstore(0, 42) }\n    }\n}\n\",\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"input.sol\\\"\nobject \\\"C_6_deployed\\\" {\n    code {\n        {\n            /// @src 0:60:101\n            mstore(64, 128)\n            fun_f()\n        }\n        /// @src 0:77:99\n        function fun_f()\n        { sstore(0, 42) }\n    }\n}\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_compatible_output_eof/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\n\t\t\t\"urls\": [\n\t\t\t\t\"in.yul\"\n\t\t\t]\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"debug\": {\"debugInfo\": [\"ethdebug\"]},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.assembly\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_incompatible_output/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.\",\n            \"message\": \"'settings.debug.debugInfo' can only include 'ethdebug', if output 'ir', 'irOptimized', 'evm.bytecode.ethdebug', or 'evm.deployedBytecode.ethdebug' was selected.\",\n            \"severity\": \"error\",\n            \"type\": \"FatalError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/in.yul",
    "content": "{\n    let x := 2\n    let y := sub(x, 2)\n    let t := verbatim_2i_1o(\"abc\", x, y)\n    sstore(t, x)\n    let r := verbatim_0i_1o(\"def\")\n    verbatim_0i_0o(\"xyz\")\n    // more than 32 bytes\n    verbatim_0i_0o(hex\"01020304050607090001020304050607090001020304050607090001020102030405060709000102030405060709000102030405060709000102\")\n    r := 9\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\n\t\t\t\"urls\": [\n\t\t\t\t\"in.yul\"\n\t\t\t]\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"debug\": {\"debugInfo\": [\"ethdebug\"]},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.bytecode.ethdebug\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_ethdebug_verbatim_unimplemented/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"UnimplementedFeatureError: Verbatim bytecode is currently not supported by ethdebug.\n\n\",\n            \"message\": \"Verbatim bytecode is currently not supported by ethdebug.\",\n            \"severity\": \"error\",\n            \"type\": \"UnimplementedFeatureError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_all/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_all/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_all/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"debug\": {\"debugInfo\": [\"*\"]},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.assembly\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_all/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C_6_deployed\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"input.sol\\\":60:101   */\n  mstore(0x40, 0x80)\n  tag_2\n  tag_1\n  jump\\t// in\ntag_2:\n  stop\n    /* \\\"input.sol\\\":77:99   */\ntag_1:\n  sstore(0x00, 0x2a)\n  jump\\t// out\n\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_location_only/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_location_only/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_location_only/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"debug\": {\"debugInfo\": [\"location\"]},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.assembly\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_location_only/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C_6_deployed\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"input.sol\\\":60:101 */\n  mstore(0x40, 0x80)\n  tag_2\n  tag_1\n  jump\\t// in\ntag_2:\n  stop\n    /* \\\"input.sol\\\":77:99 */\ntag_1:\n  sstore(0x00, 0x2a)\n  jump\\t// out\n\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_none/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_none/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_none/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"debug\": {\"debugInfo\": []},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.assembly\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_none/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C_6_deployed\": {\n                \"evm\": {\n                    \"assembly\": \"  mstore(0x40, 0x80)\n  tag_2\n  tag_1\n  jump\\t// in\ntag_2:\n  stop\ntag_1:\n  sstore(0x00, 0x2a)\n  jump\\t// out\n\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_snippet_only/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_snippet_only/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_snippet_only/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"debug\": {\"debugInfo\": [\"snippet\"]},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.assembly\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_debug_info_print_snippet_only/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"To use 'snippet' with settings.debug.debugInfo you must select also 'location'.\",\n            \"message\": \"To use 'snippet' with settings.debug.debugInfo you must select also 'location'.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_embedded_object_name/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"object \\\"NamedObject\\\" { code { let x := dataoffset(\\\"DataName\\\") sstore(add(x, 0), 0) } data \\\"DataName\\\" \\\"abc\\\" object \\\"OtherObject\\\" { code { revert(0, 0) } } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"A\": { \"OtherObject\": [\"*\"], \"\": [ \"*\" ] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_embedded_object_name/output.json",
    "content": "{\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_eof_unavailable_before_osaka/input.json",
    "content": "{\n    \"language\": \"Yul\",\n    \"sources\": {\n        \"C.yul\": {\"content\": \"{}\"}\n    },\n    \"settings\": {\n        \"eofVersion\": 1,\n        \"evmVersion\": \"cancun\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_eof_unavailable_before_osaka/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"EOF is not supported by EVM versions earlier than osaka.\",\n            \"message\": \"EOF is not supported by EVM versions earlier than osaka.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_assign_immutable/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_assign_immutable/in.yul",
    "content": "object \"a\" {\n    code {\n        {\n            setimmutable(0, \"long___name___that___definitely___exceeds___the___thirty___two___byte___limit\", 0x1234567890123456789012345678901234567890)\n        }\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_assign_immutable/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.bytecode.ethdebug\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_assign_immutable/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"a\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": {\n                            \"contract\": {\n                                \"definition\": {\n                                    \"source\": {\n                                        \"id\": 0\n                                    }\n                                },\n                                \"name\": \"\"\n                            },\n                            \"environment\": \"create\",\n                            \"instructions\": [\n                                {\n                                    \"context\": {\n                                        \"code\": {\n                                            \"range\": {\n                                                \"length\": 42,\n                                                \"offset\": 165\n                                            },\n                                            \"source\": {\n                                                \"id\": 0\n                                            }\n                                        }\n                                    },\n                                    \"offset\": 0,\n                                    \"operation\": {\n                                        \"arguments\": [\n                                            \"0x1234567890123456789012345678901234567890\"\n                                        ],\n                                        \"mnemonic\": \"PUSH20\"\n                                    }\n                                },\n                                {\n                                    \"context\": {\n                                        \"code\": {\n                                            \"range\": {\n                                                \"length\": 1,\n                                                \"offset\": 81\n                                            },\n                                            \"source\": {\n                                                \"id\": 0\n                                            }\n                                        }\n                                    },\n                                    \"offset\": 21,\n                                    \"operation\": {\n                                        \"mnemonic\": \"PUSH0\"\n                                    }\n                                },\n                                {\n                                    \"context\": {\n                                        \"code\": {\n                                            \"range\": {\n                                                \"length\": 140,\n                                                \"offset\": 68\n                                            },\n                                            \"source\": {\n                                                \"id\": 0\n                                            }\n                                        }\n                                    },\n                                    \"offset\": 22,\n                                    \"operation\": {\n                                        \"mnemonic\": \"POP\"\n                                    }\n                                },\n                                {\n                                    \"context\": {\n                                        \"code\": {\n                                            \"range\": {\n                                                \"length\": 140,\n                                                \"offset\": 68\n                                            },\n                                            \"source\": {\n                                                \"id\": 0\n                                            }\n                                        }\n                                    },\n                                    \"offset\": 23,\n                                    \"operation\": {\n                                        \"mnemonic\": \"POP\"\n                                    }\n                                },\n                                {\n                                    \"context\": {\n                                        \"code\": {\n                                            \"range\": {\n                                                \"length\": 180,\n                                                \"offset\": 44\n                                            },\n                                            \"source\": {\n                                                \"id\": 0\n                                            }\n                                        }\n                                    },\n                                    \"offset\": 24,\n                                    \"operation\": {\n                                        \"mnemonic\": \"STOP\"\n                                    }\n                                }\n                            ]\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"ethdebug\": {\n        \"compilation\": {\n            \"compiler\": {\n                \"name\": \"solc\",\n                \"version\": \"<VERSION REMOVED>\"\n            },\n            \"sources\": [\n                {\n                    \"id\": 0,\n                    \"path\": \"C\"\n                }\n            ]\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.bytecode.ethdebug\", \"ir\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C_6_deployed\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"input.sol\\\"\nobject \\\"C_6_deployed\\\" {\n    code {\n        /// @src 0:60:101\n        mstore(64, 128)\n        fun_f_5()\n        /// @src 0:77:99\n        function fun_f_5()\n        { sstore(0, 42) }\n    }\n}\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_bytecode_ir/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.bytecode.ethdebug\", \"irOptimized\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C_6_deployed\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"input.sol\\\"\nobject \\\"C_6_deployed\\\" {\n    code {\n        {\n            /// @src 0:60:101\n            mstore(64, 128)\n            fun_f()\n        }\n        /// @src 0:77:99\n        function fun_f()\n        { sstore(0, 42) }\n    }\n}\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_bytecode_iroptimized/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/in.yul",
    "content": "object \"object\" {\n   code {\n        mstore(64, 128)\n        fun_f_5()\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n    }\n\n    object \"object_deployed\" {\n        code {\n            mstore(64, 128)\n            fun_f_5()\n            function fun_f_5() {\n                sstore(0, 42)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.deployedBytecode.ethdebug\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"object\": {\n                \"evm\": {\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/in.yul",
    "content": "object \"object\" {\n   code {\n        mstore(64, 128)\n        fun_f_5()\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n    }\n\n    object \"object_deployed\" {\n        code {\n            mstore(64, 128)\n            fun_f_5()\n            function fun_f_5() {\n                sstore(0, 42)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.deployedBytecode.ethdebug\", \"evm.bytecode.ethdebug\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"object\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_deployed_bytecode_and_bytecode/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_eof/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_eof/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_eof/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"eofVersion\": 1,\n\t\t\"evmVersion\": \"osaka\",\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\", \"ir\", \"irOptimized\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_eof/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C_6_deployed\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"input.sol\\\"\nobject \\\"C_6_deployed\\\" {\n    code {\n        /// @src 0:60:101\n        mstore(64, 128)\n        fun_f_5()\n        /// @src 0:77:99\n        function fun_f_5()\n        { sstore(0, 42) }\n    }\n}\n\",\n                \"irOptimized\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"input.sol\\\"\nobject \\\"C_6_deployed\\\" {\n    code {\n        {\n            /// @src 0:60:101\n            mstore(64, 128)\n            fun_f()\n        }\n        /// @src 0:77:99\n        function fun_f()\n        { sstore(0, 42) }\n    }\n}\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_eof/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_ir/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_ir/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_ir/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.bytecode.ethdebug\", \"ir\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_ir/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C_6_deployed\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                },\n                \"ir\": \"/// ethdebug: enabled\n/// @use-src 0:\\\"input.sol\\\"\nobject \\\"C_6_deployed\\\" {\n    code {\n        /// @src 0:60:101\n        mstore(64, 128)\n        fun_f_5()\n        /// @src 0:77:99\n        function fun_f_5()\n        { sstore(0, 42) }\n    }\n}\n\"\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_ir/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_iroptimize/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_iroptimize/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_iroptimize/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.bytecode.ethdebug\", \"irOptimize\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_iroptimize/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"C_6_deployed\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n                    }\n                }\n            }\n        }\n    },\n    \"ethdebug\": \"<ETHDEBUG DEBUG DATA REMOVED>\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_iroptimize/strip-ethdebug",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_no_experimental/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"{ let x := mload(0) sstore(add(x, 0), 0) }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"viaIR\": true,\n\t\t\"debug\": {\n\t\t\t\"debugInfo\": [\n\t\t\t\t\"ethdebug\"\n\t\t\t]\n\t\t},\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"], \"\": [ \"*\" ] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_no_experimental/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Ethdebug annotations are experimental and can only be included in 'settings.debug.debugInfo' by enabling the 'settings.experimental' option.\",\n            \"message\": \"Ethdebug annotations are experimental and can only be included in 'settings.debug.debugInfo' by enabling the 'settings.experimental' option.\",\n            \"severity\": \"error\",\n            \"type\": \"FatalError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_optimize_ir/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_optimize_ir/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_optimize_ir/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true\n\t\t},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.bytecode.ethdebug\", \"ir\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_optimize_ir/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Optimization is not yet supported with ethdebug.\",\n            \"message\": \"Optimization is not yet supported with ethdebug.\",\n            \"severity\": \"error\",\n            \"type\": \"UnimplementedFeatureError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/in.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t},\n\t\"settings\": {\n\t\t\"experimental\": true,\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true\n\t\t},\n\t\t\"outputSelection\": {\n\t\t\t\"*\": {\"*\": [\"evm.bytecode.ethdebug\", \"irOptimized\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ethdebug_optimize_iroptimized/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Optimization is not yet supported with ethdebug.\",\n            \"message\": \"Optimization is not yet supported with ethdebug.\",\n            \"severity\": \"error\",\n            \"type\": \"UnimplementedFeatureError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_evm_version_byzantium/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"input.yul\": {\"content\": \"{}\"}\n\t},\n\t\"settings\": {\n\t\t\"evmVersion\": \"byzantium\"\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_evm_version_byzantium/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Support for EVM versions older than constantinople is deprecated and will be removed in the future.\",\n            \"message\": \"Support for EVM versions older than constantinople is deprecated and will be removed in the future.\",\n            \"severity\": \"warning\",\n            \"type\": \"Warning\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_evm_version_constantinople/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"input.yul\": {\"content\": \"{}\"}\n\t},\n\t\"settings\": {\n\t\t\"evmVersion\": \"constantinople\"\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_evm_version_constantinople/output.json",
    "content": "{\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_immutable_references/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"object \\\"YulTest\\\" {  code {    let size := datasize(\\\"runtime\\\")    datacopy(0, dataoffset(\\\"runtime\\\"), size)    setimmutable(0, \\\"test\\\", 1)    return(0, size)  }  object \\\"runtime\\\" {    code {      mstore(0, loadimmutable(\\\"test\\\"))      return(0, 0x20)    }  }}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\": {\n\t\t\t\"A\": {\n\t\t\t\t\"*\": [\n\t\t\t\t\t\"evm.deployedBytecode.immutableReferences\",\n\t\t\t\t\t\"evm.bytecode\",\n\t\t\t\t\t\"evm.deployedBytecode\"\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_immutable_references/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"YulTest\": {\n                \"evm\": {\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"functionDebugData\": {},\n                        \"immutableReferences\": {\n                            \"test\": [\n                                {\n                                    \"length\": 32,\n                                    \"start\": 1\n                                }\n                            ]\n                        },\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_invalid_object_name/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"{ let x := mload(0) sstore(add(x, 0), 0) }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"A\": { \"OtherObject\": [\"*\"], \"\": [ \"*\" ] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_invalid_object_name/output.json",
    "content": "{\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ir_ast_no_experimental/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"{ let x := mload(0) sstore(add(x, 0), 0) }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\"*\": {\"*\": [\"irAst\"]}}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_ir_ast_no_experimental/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"'irAst', 'irOptimizedAst', 'yulCFGJson', and 'ethdebug' outputs are experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"message\": \"'irAst', 'irOptimizedAst', 'yulCFGJson', and 'ethdebug' outputs are experimental and can only be used with the 'settings.experimental' option enabled.\",\n            \"severity\": \"error\",\n            \"type\": \"FatalError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_multiple_files/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"{ let x := mload(0) sstore(add(x, 0), 0) }\"\n\t\t},\n\t\t\"B\":\n\t\t{\n\t\t\t\"content\": \"{ let x := mload(0) sstore(add(x, 0), 0) }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"*\"], \"\": [ \"*\" ] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_multiple_files/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Yul mode only supports exactly one input file.\",\n            \"message\": \"Yul mode only supports exactly one input file.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_multiple_files_selected/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"{ let x := mload(0) sstore(add(x, 0), 0) }\"\n\t\t},\n\t\t\"B\":\n\t\t{\n\t\t\t\"content\": \"{ let x := mload(0) sstore(add(x, 0), 0) }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"B\": { \"*\": [\"*\"], \"\": [ \"*\" ] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_multiple_files_selected/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Yul mode only supports exactly one input file.\",\n            \"message\": \"Yul mode only supports exactly one input file.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_object/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"object \\\"NamedObject\\\" { code { let x := dataoffset(\\\"DataName\\\") sstore(add(x, 0), 0) } data \\\"DataName\\\" \\\"abc\\\" }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"*\"], \"\": [ \"*\" ] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_object/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"NamedObject\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"A\\\":118:119   */\n  0x00\n    /* \\\"A\\\":65:87   */\n  dup1\n  data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n    /* \\\"A\\\":107:116   */\n  add\n    /* \\\"A\\\":100:120   */\n  sstore\n    /* \\\"A\\\":32:136   */\n  stop\nstop\ndata_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263\n\",\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    }\n                },\n                \"ir\": \"object \\\"NamedObject\\\" {\n    code {\n        let x := dataoffset(\\\"DataName\\\")\n        sstore(add(x, 0), 0)\n    }\n    data \\\"DataName\\\" hex\\\"616263\\\"\n}\n\",\n                \"irOptimized\": \"object \\\"NamedObject\\\" {\n    code {\n        {\n            let x := dataoffset(\\\"DataName\\\")\n            sstore(add(x, 0), 0)\n        }\n    }\n    data \\\"DataName\\\" hex\\\"616263\\\"\n}\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"ast\": {\n                \"code\": {\n                    \"block\": {\n                        \"nativeSrc\": \"28:56:0\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"28:56:0\",\n                        \"statements\": [\n                            {\n                                \"nativeSrc\": \"30:31:0\",\n                                \"nodeType\": \"YulVariableDeclaration\",\n                                \"src\": \"30:31:0\",\n                                \"value\": {\n                                    \"arguments\": [\n                                        {\n                                            \"hexValue\": \"446174614e616d65\",\n                                            \"kind\": \"string\",\n                                            \"nativeSrc\": \"50:10:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"50:10:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"DataName\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"dataoffset\",\n                                        \"nativeSrc\": \"39:10:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"39:10:0\"\n                                    },\n                                    \"nativeSrc\": \"39:22:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"39:22:0\"\n                                },\n                                \"variables\": [\n                                    {\n                                        \"name\": \"x\",\n                                        \"nativeSrc\": \"34:1:0\",\n                                        \"nodeType\": \"YulTypedName\",\n                                        \"src\": \"34:1:0\",\n                                        \"type\": \"\"\n                                    }\n                                ]\n                            },\n                            {\n                                \"expression\": {\n                                    \"arguments\": [\n                                        {\n                                            \"arguments\": [\n                                                {\n                                                    \"name\": \"x\",\n                                                    \"nativeSrc\": \"73:1:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"73:1:0\"\n                                                },\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"76:1:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"76:1:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"0\"\n                                                }\n                                            ],\n                                            \"functionName\": {\n                                                \"name\": \"add\",\n                                                \"nativeSrc\": \"69:3:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"69:3:0\"\n                                            },\n                                            \"nativeSrc\": \"69:9:0\",\n                                            \"nodeType\": \"YulFunctionCall\",\n                                            \"src\": \"69:9:0\"\n                                        },\n                                        {\n                                            \"kind\": \"number\",\n                                            \"nativeSrc\": \"80:1:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"80:1:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"0\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"sstore\",\n                                        \"nativeSrc\": \"62:6:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"62:6:0\"\n                                    },\n                                    \"nativeSrc\": \"62:20:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"62:20:0\"\n                                },\n                                \"nativeSrc\": \"62:20:0\",\n                                \"nodeType\": \"YulExpressionStatement\",\n                                \"src\": \"62:20:0\"\n                            }\n                        ]\n                    },\n                    \"nodeType\": \"YulCode\"\n                },\n                \"name\": \"NamedObject\",\n                \"nodeType\": \"YulObject\",\n                \"subObjects\": [\n                    {\n                        \"nodeType\": \"YulData\",\n                        \"value\": \"616263\"\n                    }\n                ]\n            },\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_object_invalid_sub/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"object \\\"NamedObject\\\" { code { let x := dataoffset(\\\"NamedObject.\\\") sstore(add(x, 0), 0) } object \\\"OtherObject\\\" { code { revert(0, 0) } } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"*\"], \"\": [ \"*\" ] }\n\t\t}\n\t}\n}"
  },
  {
    "path": "test/cmdlineTests/standard_yul_object_invalid_sub/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"TypeError: Unknown data object \\\"NamedObject.\\\".\n --> A:1:51:\n  |\n1 | object \\\"NamedObject\\\" { code { let x := dataoffset(\\\"NamedObject.\\\") sstore(add(x, 0), 0) } object \\\"OtherObject\\\" { code { revert(0, 0) } } }\n  |                                                   ^^^^^^^^^^^^^^\n\n\",\n            \"message\": \"Unknown data object \\\"NamedObject.\\\".\",\n            \"severity\": \"error\",\n            \"sourceLocation\": {\n                \"end\": 64,\n                \"file\": \"A\",\n                \"start\": 50\n            },\n            \"type\": \"TypeError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_object_name/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"object \\\"NamedObject\\\" { code { let x := dataoffset(\\\"DataName\\\") sstore(add(x, 0), 0) } data \\\"DataName\\\" \\\"abc\\\" object \\\"OtherObject\\\" { code { revert(0, 0) } } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"A\": { \"NamedObject\": [\"*\"], \"\": [ \"*\" ] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_object_name/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"NamedObject\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"A\\\":118:119   */\n  0x00\n    /* \\\"A\\\":65:87   */\n  dup1\n  data_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n    /* \\\"A\\\":107:116   */\n  add\n    /* \\\"A\\\":100:120   */\n  sstore\n    /* \\\"A\\\":32:136   */\n  stop\nstop\ndata_4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 616263\n\nsub_0: assembly {\n        /* \\\"A\\\":223:224   */\n      0x00\n        /* \\\"A\\\":213:225   */\n      dup1\n      revert\n}\n\",\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    },\n                    \"deployedBytecode\": {\n                        \"functionDebugData\": {},\n                        \"immutableReferences\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    }\n                },\n                \"ir\": \"object \\\"NamedObject\\\" {\n    code {\n        let x := dataoffset(\\\"DataName\\\")\n        sstore(add(x, 0), 0)\n    }\n    data \\\"DataName\\\" hex\\\"616263\\\"\n    object \\\"OtherObject\\\" {\n        code { revert(0, 0) }\n    }\n}\n\",\n                \"irOptimized\": \"object \\\"NamedObject\\\" {\n    code {\n        {\n            let x := dataoffset(\\\"DataName\\\")\n            sstore(add(x, 0), 0)\n        }\n    }\n    data \\\"DataName\\\" hex\\\"616263\\\"\n    object \\\"OtherObject\\\" {\n        code { { revert(0, 0) } }\n    }\n}\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"ast\": {\n                \"code\": {\n                    \"block\": {\n                        \"nativeSrc\": \"28:56:0\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"28:56:0\",\n                        \"statements\": [\n                            {\n                                \"nativeSrc\": \"30:31:0\",\n                                \"nodeType\": \"YulVariableDeclaration\",\n                                \"src\": \"30:31:0\",\n                                \"value\": {\n                                    \"arguments\": [\n                                        {\n                                            \"hexValue\": \"446174614e616d65\",\n                                            \"kind\": \"string\",\n                                            \"nativeSrc\": \"50:10:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"50:10:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"DataName\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"dataoffset\",\n                                        \"nativeSrc\": \"39:10:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"39:10:0\"\n                                    },\n                                    \"nativeSrc\": \"39:22:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"39:22:0\"\n                                },\n                                \"variables\": [\n                                    {\n                                        \"name\": \"x\",\n                                        \"nativeSrc\": \"34:1:0\",\n                                        \"nodeType\": \"YulTypedName\",\n                                        \"src\": \"34:1:0\",\n                                        \"type\": \"\"\n                                    }\n                                ]\n                            },\n                            {\n                                \"expression\": {\n                                    \"arguments\": [\n                                        {\n                                            \"arguments\": [\n                                                {\n                                                    \"name\": \"x\",\n                                                    \"nativeSrc\": \"73:1:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"73:1:0\"\n                                                },\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"76:1:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"76:1:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"0\"\n                                                }\n                                            ],\n                                            \"functionName\": {\n                                                \"name\": \"add\",\n                                                \"nativeSrc\": \"69:3:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"69:3:0\"\n                                            },\n                                            \"nativeSrc\": \"69:9:0\",\n                                            \"nodeType\": \"YulFunctionCall\",\n                                            \"src\": \"69:9:0\"\n                                        },\n                                        {\n                                            \"kind\": \"number\",\n                                            \"nativeSrc\": \"80:1:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"80:1:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"0\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"sstore\",\n                                        \"nativeSrc\": \"62:6:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"62:6:0\"\n                                    },\n                                    \"nativeSrc\": \"62:20:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"62:20:0\"\n                                },\n                                \"nativeSrc\": \"62:20:0\",\n                                \"nodeType\": \"YulExpressionStatement\",\n                                \"src\": \"62:20:0\"\n                            }\n                        ]\n                    },\n                    \"nodeType\": \"YulCode\"\n                },\n                \"name\": \"NamedObject\",\n                \"nodeType\": \"YulObject\",\n                \"subObjects\": [\n                    {\n                        \"nodeType\": \"YulData\",\n                        \"value\": \"616263\"\n                    },\n                    {\n                        \"code\": {\n                            \"block\": {\n                                \"nativeSrc\": \"135:16:0\",\n                                \"nodeType\": \"YulBlock\",\n                                \"src\": \"135:16:0\",\n                                \"statements\": [\n                                    {\n                                        \"expression\": {\n                                            \"arguments\": [\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"144:1:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"144:1:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"0\"\n                                                },\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"147:1:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"147:1:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"0\"\n                                                }\n                                            ],\n                                            \"functionName\": {\n                                                \"name\": \"revert\",\n                                                \"nativeSrc\": \"137:6:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"137:6:0\"\n                                            },\n                                            \"nativeSrc\": \"137:12:0\",\n                                            \"nodeType\": \"YulFunctionCall\",\n                                            \"src\": \"137:12:0\"\n                                        },\n                                        \"nativeSrc\": \"137:12:0\",\n                                        \"nodeType\": \"YulExpressionStatement\",\n                                        \"src\": \"137:12:0\"\n                                    }\n                                ]\n                            },\n                            \"nodeType\": \"YulCode\"\n                        },\n                        \"name\": \"OtherObject\",\n                        \"nodeType\": \"YulObject\",\n                        \"subObjects\": []\n                    }\n                ]\n            },\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_optimiserSteps/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"{ let x := mload(0) sstore(add(x, 0), 0) }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true,\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": {\n\t\t\t\t\t\"optimizerSteps\": \"dhfoDgvulfnTUtnIf\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"*\"], \"\": [ \"*\" ] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_optimiserSteps/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"object\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"A\\\":99:100   */\n  0x00\n    /* \\\"A\\\":60:68   */\n  dup1\n  mload\n    /* \\\"A\\\":81:101   */\n  sstore\n    /* \\\"A\\\":27:117   */\n  stop\n\",\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    }\n                },\n                \"ir\": \"object \\\"object\\\" {\n    code {\n        let x := mload(0)\n        sstore(add(x, 0), 0)\n    }\n}\n\",\n                \"irOptimized\": \"object \\\"object\\\" {\n    code {\n        {\n            let x := mload(0)\n            sstore(add(x, 0), 0)\n        }\n    }\n}\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"ast\": {\n                \"code\": {\n                    \"block\": {\n                        \"nativeSrc\": \"0:42:0\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"0:42:0\",\n                        \"statements\": [\n                            {\n                                \"nativeSrc\": \"2:17:0\",\n                                \"nodeType\": \"YulVariableDeclaration\",\n                                \"src\": \"2:17:0\",\n                                \"value\": {\n                                    \"arguments\": [\n                                        {\n                                            \"kind\": \"number\",\n                                            \"nativeSrc\": \"17:1:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"17:1:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"0\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"mload\",\n                                        \"nativeSrc\": \"11:5:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"11:5:0\"\n                                    },\n                                    \"nativeSrc\": \"11:8:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"11:8:0\"\n                                },\n                                \"variables\": [\n                                    {\n                                        \"name\": \"x\",\n                                        \"nativeSrc\": \"6:1:0\",\n                                        \"nodeType\": \"YulTypedName\",\n                                        \"src\": \"6:1:0\",\n                                        \"type\": \"\"\n                                    }\n                                ]\n                            },\n                            {\n                                \"expression\": {\n                                    \"arguments\": [\n                                        {\n                                            \"arguments\": [\n                                                {\n                                                    \"name\": \"x\",\n                                                    \"nativeSrc\": \"31:1:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"31:1:0\"\n                                                },\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"34:1:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"34:1:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"0\"\n                                                }\n                                            ],\n                                            \"functionName\": {\n                                                \"name\": \"add\",\n                                                \"nativeSrc\": \"27:3:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"27:3:0\"\n                                            },\n                                            \"nativeSrc\": \"27:9:0\",\n                                            \"nodeType\": \"YulFunctionCall\",\n                                            \"src\": \"27:9:0\"\n                                        },\n                                        {\n                                            \"kind\": \"number\",\n                                            \"nativeSrc\": \"38:1:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"38:1:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"0\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"sstore\",\n                                        \"nativeSrc\": \"20:6:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"20:6:0\"\n                                    },\n                                    \"nativeSrc\": \"20:20:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"20:20:0\"\n                                },\n                                \"nativeSrc\": \"20:20:0\",\n                                \"nodeType\": \"YulExpressionStatement\",\n                                \"src\": \"20:20:0\"\n                            }\n                        ]\n                    },\n                    \"nodeType\": \"YulCode\"\n                },\n                \"name\": \"object\",\n                \"nodeType\": \"YulObject\",\n                \"subObjects\": []\n            },\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_optimized/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"{ let x := mload(0) sstore(add(x, 0), 0) }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": true,\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true\n\t\t\t}\n\t\t},\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"*\"], \"\": [ \"*\" ] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_optimized/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"object\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"A\\\":48:49   */\n  0x00\n    /* \\\"A\\\":38:46   */\n  dup1\n  mload\n    /* \\\"A\\\":31:50   */\n  sstore\n    /* \\\"A\\\":27:54   */\n  stop\n\",\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    }\n                },\n                \"ir\": \"object \\\"object\\\" {\n    code {\n        let x := mload(0)\n        sstore(add(x, 0), 0)\n    }\n}\n\",\n                \"irOptimized\": \"object \\\"object\\\" {\n    code { { sstore(mload(0), 0) } }\n}\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"ast\": {\n                \"code\": {\n                    \"block\": {\n                        \"nativeSrc\": \"0:42:0\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"0:42:0\",\n                        \"statements\": [\n                            {\n                                \"nativeSrc\": \"2:17:0\",\n                                \"nodeType\": \"YulVariableDeclaration\",\n                                \"src\": \"2:17:0\",\n                                \"value\": {\n                                    \"arguments\": [\n                                        {\n                                            \"kind\": \"number\",\n                                            \"nativeSrc\": \"17:1:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"17:1:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"0\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"mload\",\n                                        \"nativeSrc\": \"11:5:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"11:5:0\"\n                                    },\n                                    \"nativeSrc\": \"11:8:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"11:8:0\"\n                                },\n                                \"variables\": [\n                                    {\n                                        \"name\": \"x\",\n                                        \"nativeSrc\": \"6:1:0\",\n                                        \"nodeType\": \"YulTypedName\",\n                                        \"src\": \"6:1:0\",\n                                        \"type\": \"\"\n                                    }\n                                ]\n                            },\n                            {\n                                \"expression\": {\n                                    \"arguments\": [\n                                        {\n                                            \"arguments\": [\n                                                {\n                                                    \"name\": \"x\",\n                                                    \"nativeSrc\": \"31:1:0\",\n                                                    \"nodeType\": \"YulIdentifier\",\n                                                    \"src\": \"31:1:0\"\n                                                },\n                                                {\n                                                    \"kind\": \"number\",\n                                                    \"nativeSrc\": \"34:1:0\",\n                                                    \"nodeType\": \"YulLiteral\",\n                                                    \"src\": \"34:1:0\",\n                                                    \"type\": \"\",\n                                                    \"value\": \"0\"\n                                                }\n                                            ],\n                                            \"functionName\": {\n                                                \"name\": \"add\",\n                                                \"nativeSrc\": \"27:3:0\",\n                                                \"nodeType\": \"YulIdentifier\",\n                                                \"src\": \"27:3:0\"\n                                            },\n                                            \"nativeSrc\": \"27:9:0\",\n                                            \"nodeType\": \"YulFunctionCall\",\n                                            \"src\": \"27:9:0\"\n                                        },\n                                        {\n                                            \"kind\": \"number\",\n                                            \"nativeSrc\": \"38:1:0\",\n                                            \"nodeType\": \"YulLiteral\",\n                                            \"src\": \"38:1:0\",\n                                            \"type\": \"\",\n                                            \"value\": \"0\"\n                                        }\n                                    ],\n                                    \"functionName\": {\n                                        \"name\": \"sstore\",\n                                        \"nativeSrc\": \"20:6:0\",\n                                        \"nodeType\": \"YulIdentifier\",\n                                        \"src\": \"20:6:0\"\n                                    },\n                                    \"nativeSrc\": \"20:20:0\",\n                                    \"nodeType\": \"YulFunctionCall\",\n                                    \"src\": \"20:20:0\"\n                                },\n                                \"nativeSrc\": \"20:20:0\",\n                                \"nodeType\": \"YulExpressionStatement\",\n                                \"src\": \"20:20:0\"\n                            }\n                        ]\n                    },\n                    \"nodeType\": \"YulCode\"\n                },\n                \"name\": \"object\",\n                \"nodeType\": \"YulObject\",\n                \"subObjects\": []\n            },\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_output_warning/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"C\":\n\t\t{\n\t\t\t\"content\": \"{ let x := tload(0) tstore(add(x, 1), 0) }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": {\n\t\t\t\t\"*\": [\"evm.bytecode\", \"evm.assembly\", \"irOptimized\"],\n\t\t\t\t\"\": [ \"*\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_output_warning/output.json",
    "content": "{\n    \"contracts\": {\n        \"C\": {\n            \"object\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"C\\\":99:100   */\n  0x00\n    /* \\\"C\\\":95:96   */\n  0x01\n    /* \\\"C\\\":60:68   */\n  dup2\n  tload\n    /* \\\"C\\\":88:97   */\n  add\n    /* \\\"C\\\":81:101   */\n  tstore\n    /* \\\"C\\\":27:117   */\n  stop\n\",\n                    \"bytecode\": {\n                        \"functionDebugData\": {},\n                        \"linkReferences\": {},\n                        \"object\": \"<BYTECODE REMOVED>\",\n                        \"opcodes\":\"<OPCODES REMOVED>\",\n                        \"sourceMap\":\"<SOURCEMAP REMOVED>\"\n                    }\n                },\n                \"irOptimized\": \"object \\\"object\\\" {\n    code {\n        {\n            let x := tload(0)\n            tstore(add(x, 1), 0)\n        }\n    }\n}\n\"\n            }\n        }\n    },\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"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.\n --> C:1:21:\n  |\n1 | { let x := tload(0) tstore(add(x, 1), 0) }\n  |                     ^^^^^^\n\n\",\n            \"message\": \"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.\",\n            \"severity\": \"warning\",\n            \"sourceLocation\": {\n                \"end\": 26,\n                \"file\": \"C\",\n                \"start\": 20\n            },\n            \"type\": \"Warning\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_single_file_via_urls/args",
    "content": "--allow-paths .\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_single_file_via_urls/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\": {\n\t\t\"C\": {\"urls\": [\"in.yul\"]}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_single_file_via_urls/output.json",
    "content": "{\n    \"errors\": [\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Cannot import url (\\\"in.yul\\\"): File not found. Searched the following locations: \\\"\\\".\",\n            \"message\": \"Cannot import url (\\\"in.yul\\\"): File not found. Searched the following locations: \\\"\\\".\",\n            \"severity\": \"error\",\n            \"type\": \"IOError\"\n        },\n        {\n            \"component\": \"general\",\n            \"formattedMessage\": \"Yul mode only supports exactly one input file.\",\n            \"message\": \"Yul mode only supports exactly one input file.\",\n            \"severity\": \"error\",\n            \"type\": \"JSONError\"\n        }\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_stack_opt/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"{\n\t{\n\t\tlet x := 1\n\t\tsstore(0, x)\n\t}\n\t{\n\t\tlet y := 2\n\t\tsstore(32, y)\n\t}\n}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": false,\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": {\n\t\t\t\t\t\"stackAllocation\": true,\n\t\t\t\t\t\"optimizerSteps\": \"c\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": {\"*\": [\"evm.assembly\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_stack_opt/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"object\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"A\\\":61:62   */\n  0x01\n    /* \\\"A\\\":58:59   */\n  0x00\n    /* \\\"A\\\":51:63   */\n  sstore\n    /* \\\"A\\\":87:88   */\n  0x02\n    /* \\\"A\\\":83:85   */\n  0x20\n    /* \\\"A\\\":76:89   */\n  sstore\n    /* \\\"A\\\":27:105   */\n  stop\n\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_stack_opt_disabled/input.json",
    "content": "{\n\t\"language\": \"Yul\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"{\n\t{\n\t\tlet x := 1\n\t\tsstore(0, x)\n\t}\n\t{\n\t\tlet y := 2\n\t\tsstore(32, y)\n\t}\n}\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"optimizer\": {\n\t\t\t\"enabled\": false,\n\t\t\t\"details\": {\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"yulDetails\": {\n\t\t\t\t\t\"stackAllocation\": false,\n\t\t\t\t\t\"optimizerSteps\": \"c\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": {\"*\": [\"evm.assembly\"]}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/standard_yul_stack_opt_disabled/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"object\": {\n                \"evm\": {\n                    \"assembly\": \"    /* \\\"A\\\":61:62   */\n  0x01\n    /* \\\"A\\\":58:59   */\n  0x00\n    /* \\\"A\\\":51:63   */\n  sstore\n    /* \\\"A\\\":87:88   */\n  0x02\n    /* \\\"A\\\":83:85   */\n  0x20\n    /* \\\"A\\\":76:89   */\n  sstore\n\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/stdin/args",
    "content": "-\n"
  },
  {
    "path": "test/cmdlineTests/stdin/stdin",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/stop_after_parsing_abi/args",
    "content": "--pretty-json --json-indent 4 --stop-after parsing --abi\n"
  },
  {
    "path": "test/cmdlineTests/stop_after_parsing_abi/err",
    "content": "Error: The following options are mutually exclusive: --stop-after, --abi. Select at most one.\n"
  },
  {
    "path": "test/cmdlineTests/stop_after_parsing_abi/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/stop_after_parsing_abi/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\nimport \"A\";\n\ncontract C {\n    function f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/stop_after_parsing_ast/args",
    "content": "--pretty-json --json-indent 4 --stop-after parsing --ast-compact-json\n"
  },
  {
    "path": "test/cmdlineTests/stop_after_parsing_ast/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\nimport \"A\";\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/stop_after_parsing_ast/output",
    "content": "JSON AST (compact format):\n\n\n======= input.sol =======\n{\n    \"absolutePath\": \"input.sol\",\n    \"id\": 4,\n    \"license\": \"GPL-3.0\",\n    \"nodeType\": \"SourceUnit\",\n    \"nodes\": [\n        {\n            \"id\": 1,\n            \"literals\": [\n                \"solidity\",\n                \"*\"\n            ],\n            \"nodeType\": \"PragmaDirective\",\n            \"src\": \"36:18:0\"\n        },\n        {\n            \"absolutePath\": \"A\",\n            \"file\": \"A\",\n            \"id\": 2,\n            \"nameLocation\": \"-1:-1:-1\",\n            \"nodeType\": \"ImportDirective\",\n            \"src\": \"56:11:0\",\n            \"symbolAliases\": [],\n            \"unitAlias\": \"\"\n        },\n        {\n            \"abstract\": false,\n            \"baseContracts\": [],\n            \"contractDependencies\": [],\n            \"contractKind\": \"contract\",\n            \"id\": 3,\n            \"name\": \"C\",\n            \"nameLocation\": \"78:1:0\",\n            \"nodeType\": \"ContractDefinition\",\n            \"nodes\": [],\n            \"src\": \"69:13:0\",\n            \"usedErrors\": [],\n            \"usedEvents\": []\n        }\n    ],\n    \"src\": \"36:47:0\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_already_defined_in_ancestor/args",
    "content": "-"
  },
  {
    "path": "test/cmdlineTests/storage_layout_already_defined_in_ancestor/err",
    "content": "Error: Cannot inherit from a contract with a custom storage layout.\n --> <stdin>:5:15:\n  |\n5 | contract B is A {}\n  |               ^\nNote: Custom storage layout defined here:\n --> <stdin>:4:12:\n  |\n4 | contract A layout at 0x1234 {}\n  |            ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_already_defined_in_ancestor/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_already_defined_in_ancestor/stdin",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract A layout at 0x1234 {}\ncontract B is A {}\ncontract C layout at 0x1234 is B {}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_bytes/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { bytes s1 = \\\"test\\\"; bytes s2; }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"storageLayout\" ],\n\t\t\t\t\"\": [ \"storageLayout\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_bytes/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 4,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"s1\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_bytes_storage\"\n                        },\n                        {\n                            \"astId\": 6,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"s2\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_bytes_storage\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_bytes_storage\": {\n                            \"encoding\": \"bytes\",\n                            \"label\": \"bytes\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_dyn_array/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { uint[] array1; bool[] array2; }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"storageLayout\" ],\n\t\t\t\t\"\": [ \"storageLayout\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_dyn_array/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 4,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"array1\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_array(t_uint256)dyn_storage\"\n                        },\n                        {\n                            \"astId\": 7,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"array2\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_array(t_bool)dyn_storage\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_array(t_bool)dyn_storage\": {\n                            \"base\": \"t_bool\",\n                            \"encoding\": \"dynamic_array\",\n                            \"label\": \"bool[]\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_array(t_uint256)dyn_storage\": {\n                            \"base\": \"t_uint256\",\n                            \"encoding\": \"dynamic_array\",\n                            \"label\": \"uint256[]\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_bool\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"bool\",\n                            \"numberOfBytes\": \"1\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_many/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { struct S { uint128 a; uint128 b; uint[2] staticArray; uint[] dynArray; } uint x; uint y; S s; address addr; mapping (uint => mapping (address => bool)) map; uint[] array; string s1; bytes b1; }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"storageLayout\" ],\n\t\t\t\t\"\": [ \"storageLayout\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_many/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 15,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"x\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 17,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"y\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 20,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"s\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_struct(S)13_storage\"\n                        },\n                        {\n                            \"astId\": 22,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"addr\",\n                            \"offset\": 0,\n                            \"slot\": \"6\",\n                            \"type\": \"t_address\"\n                        },\n                        {\n                            \"astId\": 28,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"map\",\n                            \"offset\": 0,\n                            \"slot\": \"7\",\n                            \"type\": \"t_mapping(t_uint256,t_mapping(t_address,t_bool))\"\n                        },\n                        {\n                            \"astId\": 31,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"array\",\n                            \"offset\": 0,\n                            \"slot\": \"8\",\n                            \"type\": \"t_array(t_uint256)dyn_storage\"\n                        },\n                        {\n                            \"astId\": 33,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"s1\",\n                            \"offset\": 0,\n                            \"slot\": \"9\",\n                            \"type\": \"t_string_storage\"\n                        },\n                        {\n                            \"astId\": 35,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"b1\",\n                            \"offset\": 0,\n                            \"slot\": \"10\",\n                            \"type\": \"t_bytes_storage\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_array(t_uint256)2_storage\": {\n                            \"base\": \"t_uint256\",\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256[2]\",\n                            \"numberOfBytes\": \"64\"\n                        },\n                        \"t_array(t_uint256)dyn_storage\": {\n                            \"base\": \"t_uint256\",\n                            \"encoding\": \"dynamic_array\",\n                            \"label\": \"uint256[]\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_bool\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"bool\",\n                            \"numberOfBytes\": \"1\"\n                        },\n                        \"t_bytes_storage\": {\n                            \"encoding\": \"bytes\",\n                            \"label\": \"bytes\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_mapping(t_address,t_bool)\": {\n                            \"encoding\": \"mapping\",\n                            \"key\": \"t_address\",\n                            \"label\": \"mapping(address => bool)\",\n                            \"numberOfBytes\": \"32\",\n                            \"value\": \"t_bool\"\n                        },\n                        \"t_mapping(t_uint256,t_mapping(t_address,t_bool))\": {\n                            \"encoding\": \"mapping\",\n                            \"key\": \"t_uint256\",\n                            \"label\": \"mapping(uint256 => mapping(address => bool))\",\n                            \"numberOfBytes\": \"32\",\n                            \"value\": \"t_mapping(t_address,t_bool)\"\n                        },\n                        \"t_string_storage\": {\n                            \"encoding\": \"bytes\",\n                            \"label\": \"string\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_struct(S)13_storage\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"struct A.S\",\n                            \"members\": [\n                                {\n                                    \"astId\": 3,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"a\",\n                                    \"offset\": 0,\n                                    \"slot\": \"0\",\n                                    \"type\": \"t_uint128\"\n                                },\n                                {\n                                    \"astId\": 5,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"b\",\n                                    \"offset\": 16,\n                                    \"slot\": \"0\",\n                                    \"type\": \"t_uint128\"\n                                },\n                                {\n                                    \"astId\": 9,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"staticArray\",\n                                    \"offset\": 0,\n                                    \"slot\": \"1\",\n                                    \"type\": \"t_array(t_uint256)2_storage\"\n                                },\n                                {\n                                    \"astId\": 12,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"dynArray\",\n                                    \"offset\": 0,\n                                    \"slot\": \"3\",\n                                    \"type\": \"t_array(t_uint256)dyn_storage\"\n                                }\n                            ],\n                            \"numberOfBytes\": \"128\"\n                        },\n                        \"t_uint128\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint128\",\n                            \"numberOfBytes\": \"16\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_mapping/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { uint x; uint y; mapping (uint => mapping (address => bool)) map; }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"storageLayout\" ],\n\t\t\t\t\"\": [ \"storageLayout\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_mapping/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 3,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"x\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 5,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"y\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 11,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"map\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_mapping(t_uint256,t_mapping(t_address,t_bool))\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_bool\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"bool\",\n                            \"numberOfBytes\": \"1\"\n                        },\n                        \"t_mapping(t_address,t_bool)\": {\n                            \"encoding\": \"mapping\",\n                            \"key\": \"t_address\",\n                            \"label\": \"mapping(address => bool)\",\n                            \"numberOfBytes\": \"32\",\n                            \"value\": \"t_bool\"\n                        },\n                        \"t_mapping(t_uint256,t_mapping(t_address,t_bool))\": {\n                            \"encoding\": \"mapping\",\n                            \"key\": \"t_uint256\",\n                            \"label\": \"mapping(uint256 => mapping(address => bool))\",\n                            \"numberOfBytes\": \"32\",\n                            \"value\": \"t_mapping(t_address,t_bool)\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_smoke/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"storageLayout\" ],\n\t\t\t\t\"\": [ \"storageLayout\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_smoke/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_smoke_two_contracts/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t},\n\t\t\"fileB\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { uint x; uint y; }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"storageLayout\" ],\n\t\t\t\t\"\": [ \"storageLayout\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_smoke_two_contracts/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        },\n        \"fileB\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_repeated_definition_error/args",
    "content": "-"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_repeated_definition_error/err",
    "content": "Error: More than one storage layout definition.\n --> <stdin>:5:34:\n  |\n5 | contract C layout at 0x1234 is A layout at 0xABCD {\n  |                                  ^^^^^^\nNote: Previous definition:\n --> <stdin>:5:12:\n  |\n5 | contract C layout at 0x1234 is A layout at 0xABCD {\n  |            ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_repeated_definition_error/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_repeated_definition_error/stdin",
    "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A {\n}\ncontract C layout at 0x1234 is A layout at 0xABCD {\n}"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_smoke/args",
    "content": "--no-cbor-metadata --optimize --asm --debug-info none -"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_smoke/output",
    "content": "\n======= <stdin>:C =======\nEVM assembly:\n  mstore(0x40, 0x80)\n  callvalue\n  dup1\n  iszero\n  tag_1\n  jumpi\n  revert(0x00, 0x00)\ntag_1:\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      mstore(0x40, 0x80)\n      callvalue\n      dup1\n      iszero\n      tag_1\n      jumpi\n      revert(0x00, 0x00)\n    tag_1:\n      pop\n      jumpi(tag_2, lt(calldatasize, 0x04))\n      shr(0xe0, calldataload(0x00))\n      dup1\n      0x26121ff0\n      eq\n      tag_3\n      jumpi\n    tag_2:\n      revert(0x00, 0x00)\n    tag_3:\n      tag_4\n      tag_5\n      jump\t// in\n    tag_4:\n      stop\n    tag_5:\n      sload(0x0abc)\n      tag_7\n      swap1\n      0x01\n      tag_8\n      jump\t// in\n    tag_7:\n      0x0abc\n      sstore\n      jump\t// out\n    tag_8:\n      dup1\n      dup3\n      add\n      dup1\n      dup3\n      gt\n      iszero\n      tag_11\n      jumpi\n      0x4e487b71\n      0xe0\n      shl\n      0x00\n      mstore\n      0x11\n      0x04\n      mstore\n      0x24\n      0x00\n      revert\n    tag_11:\n      swap3\n      swap2\n      pop\n      pop\n      jump\t// out\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_smoke/stdin",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0.0;\n\ncontract C layout at 0xABC {\n    uint x;\n    function f() public {\n        x = x + 1;\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/args",
    "content": "--optimize --ir-optimized --debug-info none -"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/output",
    "content": "Optimized IR:\n/// @use-src 0:\"<stdin>\"\nobject \"C_7\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            sstore(0x2a, 0x0a)\n            let _2 := datasize(\"C_7_deployed\")\n            codecopy(_1, dataoffset(\"C_7_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"<stdin>\"\n    object \"C_7_deployed\" {\n        code { { revert(0, 0) } }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_smoke_ir_codegen/stdin",
    "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C layout at 42 {\n    uint x = 10;\n}"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_storage_layout_output/args",
    "content": "--storage-layout --transient-storage-layout --pretty-json --json-indent 4 -"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_storage_layout_output/output",
    "content": "\n======= <stdin>:A =======\nContract Storage Layout:\n{\n    \"storage\": [\n        {\n            \"astId\": 3,\n            \"contract\": \"<stdin>:A\",\n            \"label\": \"x\",\n            \"offset\": 0,\n            \"slot\": \"0\",\n            \"type\": \"t_uint256\"\n        },\n        {\n            \"astId\": 7,\n            \"contract\": \"<stdin>:A\",\n            \"label\": \"y\",\n            \"offset\": 0,\n            \"slot\": \"1\",\n            \"type\": \"t_uint256\"\n        }\n    ],\n    \"types\": {\n        \"t_uint256\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"uint256\",\n            \"numberOfBytes\": \"32\"\n        }\n    }\n}\nContract Transient Storage Layout:\n{\n    \"storage\": [\n        {\n            \"astId\": 5,\n            \"contract\": \"<stdin>:A\",\n            \"label\": \"t1\",\n            \"offset\": 0,\n            \"slot\": \"0\",\n            \"type\": \"t_uint256\"\n        }\n    ],\n    \"types\": {\n        \"t_uint256\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"uint256\",\n            \"numberOfBytes\": \"32\"\n        }\n    }\n}\n\n======= <stdin>:B =======\nContract Storage Layout:\n{\n    \"storage\": [\n        {\n            \"astId\": 12,\n            \"contract\": \"<stdin>:B\",\n            \"label\": \"w\",\n            \"offset\": 0,\n            \"slot\": \"0\",\n            \"type\": \"t_int8\"\n        }\n    ],\n    \"types\": {\n        \"t_int8\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"int8\",\n            \"numberOfBytes\": \"1\"\n        }\n    }\n}\nContract Transient Storage Layout:\n{\n    \"storage\": [\n        {\n            \"astId\": 10,\n            \"contract\": \"<stdin>:B\",\n            \"label\": \"t2\",\n            \"offset\": 0,\n            \"slot\": \"0\",\n            \"type\": \"t_uint256\"\n        },\n        {\n            \"astId\": 14,\n            \"contract\": \"<stdin>:B\",\n            \"label\": \"t3\",\n            \"offset\": 0,\n            \"slot\": \"1\",\n            \"type\": \"t_int8\"\n        }\n    ],\n    \"types\": {\n        \"t_int8\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"int8\",\n            \"numberOfBytes\": \"1\"\n        },\n        \"t_uint256\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"uint256\",\n            \"numberOfBytes\": \"32\"\n        }\n    }\n}\n\n======= <stdin>:C =======\nContract Storage Layout:\n{\n    \"storage\": [\n        {\n            \"astId\": 12,\n            \"contract\": \"<stdin>:C\",\n            \"label\": \"w\",\n            \"offset\": 0,\n            \"slot\": \"0\",\n            \"type\": \"t_int8\"\n        },\n        {\n            \"astId\": 19,\n            \"contract\": \"<stdin>:C\",\n            \"label\": \"z\",\n            \"offset\": 1,\n            \"slot\": \"0\",\n            \"type\": \"t_uint128\"\n        },\n        {\n            \"astId\": 21,\n            \"contract\": \"<stdin>:C\",\n            \"label\": \"b\",\n            \"offset\": 17,\n            \"slot\": \"0\",\n            \"type\": \"t_bool\"\n        }\n    ],\n    \"types\": {\n        \"t_bool\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"bool\",\n            \"numberOfBytes\": \"1\"\n        },\n        \"t_int8\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"int8\",\n            \"numberOfBytes\": \"1\"\n        },\n        \"t_uint128\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"uint128\",\n            \"numberOfBytes\": \"16\"\n        }\n    }\n}\nContract Transient Storage Layout:\n{\n    \"storage\": [\n        {\n            \"astId\": 10,\n            \"contract\": \"<stdin>:C\",\n            \"label\": \"t2\",\n            \"offset\": 0,\n            \"slot\": \"0\",\n            \"type\": \"t_uint256\"\n        },\n        {\n            \"astId\": 14,\n            \"contract\": \"<stdin>:C\",\n            \"label\": \"t3\",\n            \"offset\": 0,\n            \"slot\": \"1\",\n            \"type\": \"t_int8\"\n        },\n        {\n            \"astId\": 23,\n            \"contract\": \"<stdin>:C\",\n            \"label\": \"t4\",\n            \"offset\": 1,\n            \"slot\": \"1\",\n            \"type\": \"t_bool\"\n        }\n    ],\n    \"types\": {\n        \"t_bool\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"bool\",\n            \"numberOfBytes\": \"1\"\n        },\n        \"t_int8\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"int8\",\n            \"numberOfBytes\": \"1\"\n        },\n        \"t_uint256\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"uint256\",\n            \"numberOfBytes\": \"32\"\n        }\n    }\n}\n\n======= <stdin>:D =======\nContract Storage Layout:\n{\n    \"storage\": [\n        {\n            \"astId\": 3,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"x\",\n            \"offset\": 0,\n            \"slot\": \"100\",\n            \"type\": \"t_uint256\"\n        },\n        {\n            \"astId\": 7,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"y\",\n            \"offset\": 0,\n            \"slot\": \"101\",\n            \"type\": \"t_uint256\"\n        },\n        {\n            \"astId\": 12,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"w\",\n            \"offset\": 0,\n            \"slot\": \"102\",\n            \"type\": \"t_int8\"\n        },\n        {\n            \"astId\": 19,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"z\",\n            \"offset\": 1,\n            \"slot\": \"102\",\n            \"type\": \"t_uint128\"\n        },\n        {\n            \"astId\": 21,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"b\",\n            \"offset\": 17,\n            \"slot\": \"102\",\n            \"type\": \"t_bool\"\n        },\n        {\n            \"astId\": 32,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"addr\",\n            \"offset\": 0,\n            \"slot\": \"103\",\n            \"type\": \"t_address\"\n        },\n        {\n            \"astId\": 38,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"array\",\n            \"offset\": 0,\n            \"slot\": \"104\",\n            \"type\": \"t_array(t_uint256)2_storage\"\n        },\n        {\n            \"astId\": 42,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"m\",\n            \"offset\": 0,\n            \"slot\": \"106\",\n            \"type\": \"t_mapping(t_uint256,t_address)\"\n        }\n    ],\n    \"types\": {\n        \"t_address\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"address\",\n            \"numberOfBytes\": \"20\"\n        },\n        \"t_array(t_uint256)2_storage\": {\n            \"base\": \"t_uint256\",\n            \"encoding\": \"inplace\",\n            \"label\": \"uint256[2]\",\n            \"numberOfBytes\": \"64\"\n        },\n        \"t_bool\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"bool\",\n            \"numberOfBytes\": \"1\"\n        },\n        \"t_int8\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"int8\",\n            \"numberOfBytes\": \"1\"\n        },\n        \"t_mapping(t_uint256,t_address)\": {\n            \"encoding\": \"mapping\",\n            \"key\": \"t_uint256\",\n            \"label\": \"mapping(uint256 => address)\",\n            \"numberOfBytes\": \"32\",\n            \"value\": \"t_address\"\n        },\n        \"t_uint128\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"uint128\",\n            \"numberOfBytes\": \"16\"\n        },\n        \"t_uint256\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"uint256\",\n            \"numberOfBytes\": \"32\"\n        }\n    }\n}\nContract Transient Storage Layout:\n{\n    \"storage\": [\n        {\n            \"astId\": 5,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"t1\",\n            \"offset\": 0,\n            \"slot\": \"0\",\n            \"type\": \"t_uint256\"\n        },\n        {\n            \"astId\": 10,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"t2\",\n            \"offset\": 0,\n            \"slot\": \"1\",\n            \"type\": \"t_uint256\"\n        },\n        {\n            \"astId\": 14,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"t3\",\n            \"offset\": 0,\n            \"slot\": \"2\",\n            \"type\": \"t_int8\"\n        },\n        {\n            \"astId\": 23,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"t4\",\n            \"offset\": 1,\n            \"slot\": \"2\",\n            \"type\": \"t_bool\"\n        },\n        {\n            \"astId\": 34,\n            \"contract\": \"<stdin>:D\",\n            \"label\": \"t5\",\n            \"offset\": 2,\n            \"slot\": \"2\",\n            \"type\": \"t_address\"\n        }\n    ],\n    \"types\": {\n        \"t_address\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"address\",\n            \"numberOfBytes\": \"20\"\n        },\n        \"t_bool\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"bool\",\n            \"numberOfBytes\": \"1\"\n        },\n        \"t_int8\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"int8\",\n            \"numberOfBytes\": \"1\"\n        },\n        \"t_uint256\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"uint256\",\n            \"numberOfBytes\": \"32\"\n        }\n    }\n}\n\n======= <stdin>:P =======\nContract Storage Layout:\n{\n    \"storage\": [\n        {\n            \"astId\": 3,\n            \"contract\": \"<stdin>:P\",\n            \"label\": \"x\",\n            \"offset\": 0,\n            \"slot\": \"200\",\n            \"type\": \"t_uint256\"\n        },\n        {\n            \"astId\": 7,\n            \"contract\": \"<stdin>:P\",\n            \"label\": \"y\",\n            \"offset\": 0,\n            \"slot\": \"201\",\n            \"type\": \"t_uint256\"\n        },\n        {\n            \"astId\": 49,\n            \"contract\": \"<stdin>:P\",\n            \"label\": \"q\",\n            \"offset\": 0,\n            \"slot\": \"202\",\n            \"type\": \"t_uint256\"\n        }\n    ],\n    \"types\": {\n        \"t_uint256\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"uint256\",\n            \"numberOfBytes\": \"32\"\n        }\n    }\n}\nContract Transient Storage Layout:\n{\n    \"storage\": [\n        {\n            \"astId\": 5,\n            \"contract\": \"<stdin>:P\",\n            \"label\": \"t1\",\n            \"offset\": 0,\n            \"slot\": \"0\",\n            \"type\": \"t_uint256\"\n        }\n    ],\n    \"types\": {\n        \"t_uint256\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"uint256\",\n            \"numberOfBytes\": \"32\"\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_specifier_storage_layout_output/stdin",
    "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\nabstract contract A {\n    uint x;\n    uint transient t1;\n    uint y;\n}\n\ncontract B {\n    uint transient t2;\n    int8 w;\n    int8 transient t3;\n}\n\ncontract C is B {\n    uint128 z;\n    bool b;\n    bool transient t4;\n}\n\ncontract D is A, C layout at 100 {\n    address addr;\n    address transient t5;\n    uint[2] array;\n    mapping(uint => address) m;\n}\n\ncontract P is A layout at 200 {\n    uint q;\n}"
  },
  {
    "path": "test/cmdlineTests/storage_layout_string/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { string s1 = \\\"test\\\"; string s2; }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"storageLayout\" ],\n\t\t\t\t\"\": [ \"storageLayout\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_string/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 4,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"s1\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_string_storage\"\n                        },\n                        {\n                            \"astId\": 6,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"s2\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_string_storage\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_string_storage\": {\n                            \"encoding\": \"bytes\",\n                            \"label\": \"string\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_struct/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { struct S { uint a; uint b; uint[2] staticArray; uint[] dynArray; } uint x; uint y; S s; address addr; }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"storageLayout\" ],\n\t\t\t\t\"\": [ \"storageLayout\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_struct/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 15,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"x\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 17,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"y\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 20,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"s\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_struct(S)13_storage\"\n                        },\n                        {\n                            \"astId\": 22,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"addr\",\n                            \"offset\": 0,\n                            \"slot\": \"7\",\n                            \"type\": \"t_address\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_array(t_uint256)2_storage\": {\n                            \"base\": \"t_uint256\",\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256[2]\",\n                            \"numberOfBytes\": \"64\"\n                        },\n                        \"t_array(t_uint256)dyn_storage\": {\n                            \"base\": \"t_uint256\",\n                            \"encoding\": \"dynamic_array\",\n                            \"label\": \"uint256[]\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_struct(S)13_storage\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"struct A.S\",\n                            \"members\": [\n                                {\n                                    \"astId\": 3,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"a\",\n                                    \"offset\": 0,\n                                    \"slot\": \"0\",\n                                    \"type\": \"t_uint256\"\n                                },\n                                {\n                                    \"astId\": 5,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"b\",\n                                    \"offset\": 0,\n                                    \"slot\": \"1\",\n                                    \"type\": \"t_uint256\"\n                                },\n                                {\n                                    \"astId\": 9,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"staticArray\",\n                                    \"offset\": 0,\n                                    \"slot\": \"2\",\n                                    \"type\": \"t_array(t_uint256)2_storage\"\n                                },\n                                {\n                                    \"astId\": 12,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"dynArray\",\n                                    \"offset\": 0,\n                                    \"slot\": \"4\",\n                                    \"type\": \"t_array(t_uint256)dyn_storage\"\n                                }\n                            ],\n                            \"numberOfBytes\": \"160\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_struct_packed/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { struct S { uint128 a; uint128 b; uint[2] staticArray; uint[] dynArray; } uint x; uint y; S s; address addr; }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"storageLayout\" ],\n\t\t\t\t\"\": [ \"storageLayout\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_struct_packed/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 15,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"x\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 17,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"y\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 20,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"s\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_struct(S)13_storage\"\n                        },\n                        {\n                            \"astId\": 22,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"addr\",\n                            \"offset\": 0,\n                            \"slot\": \"6\",\n                            \"type\": \"t_address\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_array(t_uint256)2_storage\": {\n                            \"base\": \"t_uint256\",\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256[2]\",\n                            \"numberOfBytes\": \"64\"\n                        },\n                        \"t_array(t_uint256)dyn_storage\": {\n                            \"base\": \"t_uint256\",\n                            \"encoding\": \"dynamic_array\",\n                            \"label\": \"uint256[]\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_struct(S)13_storage\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"struct A.S\",\n                            \"members\": [\n                                {\n                                    \"astId\": 3,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"a\",\n                                    \"offset\": 0,\n                                    \"slot\": \"0\",\n                                    \"type\": \"t_uint128\"\n                                },\n                                {\n                                    \"astId\": 5,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"b\",\n                                    \"offset\": 16,\n                                    \"slot\": \"0\",\n                                    \"type\": \"t_uint128\"\n                                },\n                                {\n                                    \"astId\": 9,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"staticArray\",\n                                    \"offset\": 0,\n                                    \"slot\": \"1\",\n                                    \"type\": \"t_array(t_uint256)2_storage\"\n                                },\n                                {\n                                    \"astId\": 12,\n                                    \"contract\": \"fileA:A\",\n                                    \"label\": \"dynArray\",\n                                    \"offset\": 0,\n                                    \"slot\": \"3\",\n                                    \"type\": \"t_array(t_uint256)dyn_storage\"\n                                }\n                            ],\n                            \"numberOfBytes\": \"128\"\n                        },\n                        \"t_uint128\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint128\",\n                            \"numberOfBytes\": \"16\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_transient_value_types/in.sol",
    "content": "//SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract A {\n    uint transient x;\n    uint y;\n    bytes32 transient b;\n    bytes32 c;\n    address transient a;\n    address z;\n}"
  },
  {
    "path": "test/cmdlineTests/storage_layout_transient_value_types/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [\"storageLayout\", \"transientStorageLayout\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_transient_value_types/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 5,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"y\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 9,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"c\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_bytes32\"\n                        },\n                        {\n                            \"astId\": 13,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"z\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_address\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_bytes32\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"bytes32\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                },\n                \"transientStorageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 3,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"x\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 7,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"b\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_bytes32\"\n                        },\n                        {\n                            \"astId\": 11,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"a\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_address\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_bytes32\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"bytes32\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_user_defined/args",
    "content": "--storage-layout --pretty-json\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_user_defined/err",
    "content": "Warning: Source file does not specify required compiler version!\n--> input.sol\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_user_defined/input.sol",
    "content": "// SPDX-License-Identifier: GPL v3\ntype MyInt128 is int128;\ntype MyInt8 is int8;\ncontract C {\n    // slot 0\n    MyInt128 a;\n    MyInt128 b;\n    // slot 1\n    MyInt128 c;\n    MyInt8 d;\n    MyInt8 e;\n    MyInt8 f;\n    MyInt8 g;\n    // slot 2\n    MyInt8 h;\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_user_defined/output",
    "content": "\n======= input.sol:C =======\nContract Storage Layout:\n{\n  \"storage\": [\n    {\n      \"astId\": 7,\n      \"contract\": \"input.sol:C\",\n      \"label\": \"a\",\n      \"offset\": 0,\n      \"slot\": \"0\",\n      \"type\": \"t_userDefinedValueType(MyInt128)2\"\n    },\n    {\n      \"astId\": 10,\n      \"contract\": \"input.sol:C\",\n      \"label\": \"b\",\n      \"offset\": 16,\n      \"slot\": \"0\",\n      \"type\": \"t_userDefinedValueType(MyInt128)2\"\n    },\n    {\n      \"astId\": 13,\n      \"contract\": \"input.sol:C\",\n      \"label\": \"c\",\n      \"offset\": 0,\n      \"slot\": \"1\",\n      \"type\": \"t_userDefinedValueType(MyInt128)2\"\n    },\n    {\n      \"astId\": 16,\n      \"contract\": \"input.sol:C\",\n      \"label\": \"d\",\n      \"offset\": 16,\n      \"slot\": \"1\",\n      \"type\": \"t_userDefinedValueType(MyInt8)4\"\n    },\n    {\n      \"astId\": 19,\n      \"contract\": \"input.sol:C\",\n      \"label\": \"e\",\n      \"offset\": 17,\n      \"slot\": \"1\",\n      \"type\": \"t_userDefinedValueType(MyInt8)4\"\n    },\n    {\n      \"astId\": 22,\n      \"contract\": \"input.sol:C\",\n      \"label\": \"f\",\n      \"offset\": 18,\n      \"slot\": \"1\",\n      \"type\": \"t_userDefinedValueType(MyInt8)4\"\n    },\n    {\n      \"astId\": 25,\n      \"contract\": \"input.sol:C\",\n      \"label\": \"g\",\n      \"offset\": 19,\n      \"slot\": \"1\",\n      \"type\": \"t_userDefinedValueType(MyInt8)4\"\n    },\n    {\n      \"astId\": 28,\n      \"contract\": \"input.sol:C\",\n      \"label\": \"h\",\n      \"offset\": 20,\n      \"slot\": \"1\",\n      \"type\": \"t_userDefinedValueType(MyInt8)4\"\n    }\n  ],\n  \"types\": {\n    \"t_userDefinedValueType(MyInt128)2\": {\n      \"encoding\": \"inplace\",\n      \"label\": \"MyInt128\",\n      \"numberOfBytes\": \"16\"\n    },\n    \"t_userDefinedValueType(MyInt8)4\": {\n      \"encoding\": \"inplace\",\n      \"label\": \"MyInt8\",\n      \"numberOfBytes\": \"1\"\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_user_defined_no_pretty_print/args",
    "content": "--storage-layout\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_user_defined_no_pretty_print/input.sol",
    "content": "// SPDX-License-Identifier: GPL v3\npragma solidity >=0.0;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_user_defined_no_pretty_print/output",
    "content": "\n======= input.sol:C =======\nContract Storage Layout:\n{\"storage\":[]}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_value_types/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { uint x; uint y; address addr; uint[2] array; }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"storageLayout\" ],\n\t\t\t\t\"\": [ \"storageLayout\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_value_types/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 3,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"x\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 5,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"y\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 7,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"addr\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_address\"\n                        },\n                        {\n                            \"astId\": 11,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"array\",\n                            \"offset\": 0,\n                            \"slot\": \"3\",\n                            \"type\": \"t_array(t_uint256)2_storage\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_array(t_uint256)2_storage\": {\n                            \"base\": \"t_uint256\",\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256[2]\",\n                            \"numberOfBytes\": \"64\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_value_types_packed/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { uint64 x; uint128 y; uint128 z; address addr; uint[2] array; }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [ \"storageLayout\" ],\n\t\t\t\t\"\": [ \"storageLayout\" ]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_layout_value_types_packed/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 3,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"x\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint64\"\n                        },\n                        {\n                            \"astId\": 5,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"y\",\n                            \"offset\": 8,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint128\"\n                        },\n                        {\n                            \"astId\": 7,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"z\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_uint128\"\n                        },\n                        {\n                            \"astId\": 9,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"addr\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_address\"\n                        },\n                        {\n                            \"astId\": 13,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"array\",\n                            \"offset\": 0,\n                            \"slot\": \"3\",\n                            \"type\": \"t_array(t_uint256)2_storage\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_array(t_uint256)2_storage\": {\n                            \"base\": \"t_uint256\",\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256[2]\",\n                            \"numberOfBytes\": \"64\"\n                        },\n                        \"t_uint128\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint128\",\n                            \"numberOfBytes\": \"16\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_uint64\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint64\",\n                            \"numberOfBytes\": \"8\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_transient_storage_collision_ir_output/args",
    "content": "--ir-optimized --evm-version cancun --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/storage_transient_storage_collision_ir_output/input.sol",
    "content": "// SPDX-License-Identifier: GPL-2.0\npragma solidity >=0.0;\n\ncontract C {\n    uint256 transient varTransient;\n    uint256 public varStorage = 0xeeeeeeeeee;\n\n    function foo() external returns (uint256) {\n        varTransient = 0xffffffff;\n        delete varTransient;\n        delete varStorage;\n\n        return varStorage;\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/storage_transient_storage_collision_ir_output/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_25\" {\n    code {\n        {\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            constructor_C()\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\"C_25_deployed\"), datasize(\"C_25_deployed\"))\n            return(_1, datasize(\"C_25_deployed\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n        function shift_left(value) -> newValue\n        { newValue := shl(0, value) }\n        function update_byte_slice_shift(value, toInsert) -> result\n        {\n            let mask := not(0)\n            toInsert := shift_left(toInsert)\n            value := and(value, not(mask))\n            result := or(value, and(toInsert, mask))\n        }\n        function cleanup_rational_by(value) -> cleaned\n        { cleaned := value }\n        function cleanup_uint256(value) -> cleaned\n        { cleaned := value }\n        function identity(value) -> ret\n        { ret := value }\n        function convert_rational_by_to_uint256(value) -> converted\n        {\n            converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n        }\n        function prepare_store_uint256(value) -> ret\n        { ret := value }\n        function update_storage_value_offset_rational_by_to_uint256(slot, value)\n        {\n            let convertedValue := convert_rational_by_to_uint256(value)\n            sstore(slot, update_byte_slice_shift(sload(slot), prepare_store_uint256(convertedValue)))\n        }\n        function constructor_C()\n        {\n            let expr := 0xeeeeeeeeee\n            update_storage_value_offset_rational_by_to_uint256(0x00, expr)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_25_deployed\" {\n        code {\n            {\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xc2985578 { external_fun_foo() }\n                    case 0xff2558ff { external_fun_varStorage() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function abi_decode(headStart, dataEnd)\n            {\n                if slt(sub(dataEnd, headStart), 0)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n            }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function abi_encode_uint256_to_uint256(value, pos)\n            {\n                mstore(pos, cleanup_uint256(value))\n            }\n            function abi_encode_uint256(headStart, value0) -> tail\n            {\n                tail := add(headStart, 32)\n                abi_encode_uint256_to_uint256(value0, add(headStart, 0))\n            }\n            function external_fun_foo()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                abi_decode(4, calldatasize())\n                let ret := fun_foo()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_uint256(memPos, ret)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function shift_right_unsigned_dynamic(bits, value) -> newValue\n            { newValue := shr(bits, value) }\n            function cleanup_from_storage_uint256(value) -> cleaned\n            { cleaned := value }\n            function extract_from_storage_value_dynamict_uint256(slot_value, offset) -> value\n            {\n                value := cleanup_from_storage_uint256(shift_right_unsigned_dynamic(mul(offset, 8), slot_value))\n            }\n            function read_from_storage_split_dynamic_uint256(slot, offset) -> value\n            {\n                value := extract_from_storage_value_dynamict_uint256(sload(slot), offset)\n            }\n            function getter_fun_varStorage() -> ret\n            {\n                let slot := 0\n                let offset := 0\n                ret := read_from_storage_split_dynamic_uint256(slot, offset)\n            }\n            function external_fun_varStorage()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                abi_decode(4, calldatasize())\n                let ret := getter_fun_varStorage()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_uint256(memPos, ret)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function zero_value_for_split_uint256() -> ret\n            { ret := 0 }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            function shift_left(value) -> newValue\n            { newValue := shl(0, value) }\n            function update_byte_slice_shift(value, toInsert) -> result\n            {\n                let mask := not(0)\n                toInsert := shift_left(toInsert)\n                value := and(value, not(mask))\n                result := or(value, and(toInsert, mask))\n            }\n            function convert_uint256_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_uint256(value)))\n            }\n            function prepare_store_uint256(value) -> ret\n            { ret := value }\n            function update_transient_storage_value_offset_uint256_to_uint256(slot, value)\n            {\n                let convertedValue := convert_uint256_to_uint256(value)\n                tstore(slot, update_byte_slice_shift(tload(slot), prepare_store_uint256(convertedValue)))\n            }\n            function shift_left_dynamic(bits, value) -> newValue\n            { newValue := shl(bits, value) }\n            function update_byte_slice_dynamic32(value, shiftBytes, toInsert) -> result\n            {\n                let shiftBits := mul(shiftBytes, 8)\n                let mask := shift_left_dynamic(shiftBits, not(0))\n                toInsert := shift_left_dynamic(shiftBits, toInsert)\n                value := and(value, not(mask))\n                result := or(value, and(toInsert, mask))\n            }\n            function update_transient_storage_value_uint256_to_uint256(slot, offset, value)\n            {\n                let convertedValue := convert_uint256_to_uint256(value)\n                tstore(slot, update_byte_slice_dynamic32(tload(slot), offset, prepare_store_uint256(convertedValue)))\n            }\n            function transient_storage_set_to_zero_uint256(slot, offset)\n            {\n                let zero := zero_value_for_split_uint256()\n                update_transient_storage_value_uint256_to_uint256(slot, offset, zero)\n            }\n            function update_storage_value_uint256_to_uint256(slot, offset, value)\n            {\n                let convertedValue := convert_uint256_to_uint256(value)\n                sstore(slot, update_byte_slice_dynamic32(sload(slot), offset, prepare_store_uint256(convertedValue)))\n            }\n            function storage_set_to_zero_uint256(slot, offset)\n            {\n                let zero := zero_value_for_split_uint256()\n                update_storage_value_uint256_to_uint256(slot, offset, zero)\n            }\n            function shift_right_0_unsigned(value) -> newValue\n            { newValue := shr(0, value) }\n            function extract_from_storage_value_offset_uint256(slot_value) -> value\n            {\n                value := cleanup_from_storage_uint256(shift_right_0_unsigned(slot_value))\n            }\n            function read_from_storage_split_offset_uint256(slot) -> value\n            {\n                value := extract_from_storage_value_offset_uint256(sload(slot))\n            }\n            function fun_foo() -> var\n            {\n                let zero_uint256 := zero_value_for_split_uint256()\n                var := zero_uint256\n                let expr := 0xffffffff\n                let _1 := convert_rational_by_to_uint256(expr)\n                update_transient_storage_value_offset_uint256_to_uint256(0x00, _1)\n                transient_storage_set_to_zero_uint256(0x00, 0)\n                storage_set_to_zero_uint256(0x00, 0)\n                let _2 := read_from_storage_split_offset_uint256(0x00)\n                let expr_1 := _2\n                var := expr_1\n                leave\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/args",
    "content": "--strict-assembly - --asm-json --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/err",
    "content": "Error: Generating the assembly JSON output was not possible. Source indices provided in the @use-src annotation in the Yul input do not start at 0 or are not contiguous.\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_arbitrary_source_index/stdin",
    "content": "/// @use-src 2:\"L0.sol\"\nobject \"L0\" {\n    code {\n        sstore(0, datasize(\"L0\"))\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/args",
    "content": "--strict-assembly - --asm-json --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/output",
    "content": "\n======= <stdin> (EVM) =======\n\nEVM assembly:\n{\n    \".code\": [\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSHSIZE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"1\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH [$]\",\n            \"source\": 0,\n            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"2\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"3\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH [$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"4\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"5\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH [$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffe\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"6\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffe\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"7\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH [$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffd\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"8\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"000000000000000000000000000000000000000000000000fffffffffffffffd\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"9\"\n        },\n        {\n            \"begin\": 41,\n            \"end\": 137,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"STOP\",\n            \"source\": -1\n        }\n    ],\n    \".data\": {\n        \"0\": {\n            \".code\": [\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH [$]\",\n                    \"source\": 1,\n                    \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH\",\n                    \"source\": 1,\n                    \"value\": \"A\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"SSTORE\",\n                    \"source\": 1\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH #[$]\",\n                    \"source\": 1,\n                    \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH\",\n                    \"source\": 1,\n                    \"value\": \"B\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"SSTORE\",\n                    \"source\": 1\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH [$]\",\n                    \"source\": 1,\n                    \"value\": \"0000000000000000000000000000000000000000000000000000000000000001\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH\",\n                    \"source\": 1,\n                    \"value\": \"C\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"SSTORE\",\n                    \"source\": 1\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH #[$]\",\n                    \"source\": 1,\n                    \"value\": \"0000000000000000000000000000000000000000000000000000000000000001\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH\",\n                    \"source\": 1,\n                    \"value\": \"D\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"SSTORE\",\n                    \"source\": 1\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH [$]\",\n                    \"source\": 1,\n                    \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH\",\n                    \"source\": 1,\n                    \"value\": \"E\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"SSTORE\",\n                    \"source\": 1\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH #[$]\",\n                    \"source\": 1,\n                    \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"PUSH\",\n                    \"source\": 1,\n                    \"value\": \"F\"\n                },\n                {\n                    \"begin\": 57,\n                    \"end\": 158,\n                    \"name\": \"SSTORE\",\n                    \"source\": 1\n                },\n                {\n                    \"begin\": -1,\n                    \"end\": -1,\n                    \"name\": \"STOP\",\n                    \"source\": -1\n                }\n            ],\n            \".data\": {\n                \"0\": {\n                    \".code\": [\n                        {\n                            \"begin\": 41,\n                            \"end\": 100,\n                            \"name\": \"PUSH [$]\",\n                            \"source\": 2,\n                            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n                        },\n                        {\n                            \"begin\": 41,\n                            \"end\": 100,\n                            \"name\": \"PUSH\",\n                            \"source\": 2,\n                            \"value\": \"10\"\n                        },\n                        {\n                            \"begin\": 41,\n                            \"end\": 100,\n                            \"name\": \"SSTORE\",\n                            \"source\": 2\n                        },\n                        {\n                            \"begin\": 41,\n                            \"end\": 100,\n                            \"name\": \"PUSH #[$]\",\n                            \"source\": 2,\n                            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n                        },\n                        {\n                            \"begin\": 41,\n                            \"end\": 100,\n                            \"name\": \"PUSH\",\n                            \"source\": 2,\n                            \"value\": \"11\"\n                        },\n                        {\n                            \"begin\": 41,\n                            \"end\": 100,\n                            \"name\": \"SSTORE\",\n                            \"source\": 2\n                        },\n                        {\n                            \"begin\": -1,\n                            \"end\": -1,\n                            \"name\": \"STOP\",\n                            \"source\": -1\n                        }\n                    ],\n                    \".data\": {\n                        \"0\": {\n                            \".code\": [\n                                {\n                                    \"begin\": -1,\n                                    \"end\": -1,\n                                    \"name\": \"INVALID\",\n                                    \"source\": -1\n                                }\n                            ]\n                        }\n                    }\n                },\n                \"1\": {\n                    \".code\": [\n                        {\n                            \"begin\": -1,\n                            \"end\": -1,\n                            \"name\": \"INVALID\",\n                            \"source\": -1\n                        }\n                    ]\n                }\n            }\n        },\n        \"ACAF3289D7B601CBD114FB36C4D29C85BBFD5E133F14CB355C3FD8D99367964F\": \"48656c6c6f2c20576f726c6421\"\n    },\n    \"sourceList\": [\n        \"a.sol\",\n        \"b.sol\",\n        \"c.sol\",\n        \"d.sol\",\n        \"e.sol\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_subobjects_with_debug/stdin",
    "content": "/// @use-src 0:\"a.sol\"\nobject \"A\" {\n    code {\n        /// @src 0:41:137  \"contract A {...\"\n        sstore(0, dataoffset(\"A\"))\n        sstore(1, datasize(\"A\"))\n        sstore(2, dataoffset(\"B\"))\n        sstore(3, datasize(\"B\"))\n        sstore(4, dataoffset(\"B.C\"))\n        sstore(5, datasize(\"B.C\"))\n        sstore(6, dataoffset(\"B.E\"))\n        sstore(7, datasize(\"B.E\"))\n        sstore(8, dataoffset(\"B.C.D\"))\n        sstore(9, datasize(\"B.C.D\"))\n    }\n\n    data \"data1\" \"Hello, World!\"\n\n    /// @use-src 1:\"b.sol\"\n    object \"B\" {\n        code {\n            /// @src 1:57:158  \"contract B {...\"\n            sstore(10, dataoffset(\"C\"))\n            sstore(11, datasize(\"C\"))\n            sstore(12, dataoffset(\"E\"))\n            sstore(13, datasize(\"E\"))\n            sstore(14, dataoffset(\"C.D\"))\n            sstore(15, datasize(\"C.D\"))\n        }\n        /// @use-src 2:\"c.sol\"\n        object \"C\" {\n            code {\n                /// @src 2:41:100  \"contract C {...\"\n                sstore(16, dataoffset(\"D\"))\n                sstore(17, datasize(\"D\"))\n            }\n            /// @use-src 3:\"d.sol\"\n            object \"D\" {\n                code {\n                    invalid()\n                }\n            }\n        }\n        /// @use-src 4:\"e.sol\"\n        object \"E\" {\n            code {\n                invalid()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/args",
    "content": "--strict-assembly - --asm-json --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/output",
    "content": "\n======= <stdin> (EVM) =======\n\nEVM assembly:\n{\n    \".code\": [\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"80\"\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"DUP1\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"40\"\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"MSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"CALLVALUE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"PUSH [tag]\",\n            \"source\": 0,\n            \"value\": \"1\"\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"JUMPI\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 56,\n            \"end\": 57,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"2\"\n        },\n        {\n            \"begin\": 33,\n            \"end\": 34,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 33,\n            \"end\": 34,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": 33,\n            \"end\": 34,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"1\"\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"SSTORE\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"PUSH #[$]\",\n            \"source\": 0,\n            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"SWAP1\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"DUP2\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"PUSH [$]\",\n            \"source\": 0,\n            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"DUP3\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"CODECOPY\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"RETURN\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"tag\",\n            \"source\": 0,\n            \"value\": \"1\"\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"JUMPDEST\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"PUSH\",\n            \"source\": 0,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"DUP1\",\n            \"source\": 0\n        },\n        {\n            \"begin\": 0,\n            \"end\": 125,\n            \"name\": \"REVERT\",\n            \"source\": 0\n        }\n    ],\n    \".data\": {\n        \"0\": {\n            \".auxdata\": \"1234abcd\",\n            \".code\": [\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"80\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"DUP1\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"40\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"MSTORE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"4\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"CALLDATASIZE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"LT\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"ISZERO\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"PUSH [tag]\",\n                    \"source\": 0,\n                    \"value\": \"1\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"JUMPI\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": -1,\n                    \"end\": -1,\n                    \"name\": \"tag\",\n                    \"source\": -1,\n                    \"value\": \"2\"\n                },\n                {\n                    \"begin\": -1,\n                    \"end\": -1,\n                    \"name\": \"JUMPDEST\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"0\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"DUP1\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"REVERT\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"tag\",\n                    \"source\": 0,\n                    \"value\": \"1\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"JUMPDEST\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"0\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"CALLDATALOAD\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"E0\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"SHR\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"B4F40C61\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"SUB\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"PUSH [tag]\",\n                    \"source\": 0,\n                    \"value\": \"2\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"JUMPI\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"20\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"SWAP1\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 40,\n                    \"end\": 57,\n                    \"name\": \"PUSH\",\n                    \"source\": 0,\n                    \"value\": \"1\"\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"SLOAD\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"DUP2\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"MSTORE\",\n                    \"source\": 0\n                },\n                {\n                    \"begin\": 0,\n                    \"end\": 125,\n                    \"name\": \"RETURN\",\n                    \"source\": 0\n                }\n            ]\n        }\n    },\n    \"sourceList\": [\n        \"state_var_initialization.sol\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_with_debug_info_annotations/stdin",
    "content": "/// @use-src 0:\"state_var_initialization.sol\"\nobject \"C_23\" {\n    code {\n        {\n            /// @src 0:0:125  \"contract C {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            sstore(/** @src 0:33:34  \"1\" */ 0x00, /** @src 0:56:57  \"2\" */ 0x02)\n            /// @src 0:0:125  \"contract C {...\"\n            sstore(/** @src 0:33:34  \"1\" */ 0x01, 0x00)\n            /// @src 0:0:125  \"contract C {...\"\n            let _2 := datasize(\"C_23_deployed\")\n            codecopy(_1, dataoffset(\"C_23_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"state_var_initialization.sol\"\n    object \"C_23_deployed\" {\n        code {\n            {\n                /// @src 0:0:125  \"contract C {...\"\n                let _1 := memoryguard(0x80)\n                mstore(64, _1)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let _2 := 0\n                    switch shr(224, calldataload(_2))\n                    case 0xb4f40c61 {\n                        mstore(_1, sload(/** @src 0:40:57  \"uint public k = 2\" */ 1))\n                        /// @src 0:0:125  \"contract C {...\"\n                        return(_1, 32)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"1234abcd\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/args",
    "content": "--strict-assembly - --asm-json --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/output",
    "content": "\n======= <stdin> (EVM) =======\n\nEVM assembly:\n{\n    \".code\": [\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"80\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"DUP1\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"40\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"MSTORE\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"CALLVALUE\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH [tag]\",\n            \"source\": -1,\n            \"value\": \"1\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"JUMPI\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"2\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"SSTORE\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"1\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"SSTORE\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH #[$]\",\n            \"source\": -1,\n            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"SWAP1\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"DUP2\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH [$]\",\n            \"source\": -1,\n            \"value\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"DUP3\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"CODECOPY\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"RETURN\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"tag\",\n            \"source\": -1,\n            \"value\": \"1\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"JUMPDEST\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"PUSH\",\n            \"source\": -1,\n            \"value\": \"0\"\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"DUP1\",\n            \"source\": -1\n        },\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"REVERT\",\n            \"source\": -1\n        }\n    ],\n    \".data\": {\n        \"0\": {\n            \".auxdata\": \"1234abcd\",\n            \".code\": [\n                {\n                    \"begin\": 468,\n                    \"end\": 485,\n                    \"name\": \"PUSH\",\n                    \"source\": -1,\n                    \"value\": \"80\"\n                },\n                {\n                    \"begin\": 502,\n                    \"end\": 516,\n                    \"name\": \"DUP1\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 509,\n                    \"end\": 511,\n                    \"name\": \"PUSH\",\n                    \"source\": -1,\n                    \"value\": \"40\"\n                },\n                {\n                    \"begin\": 502,\n                    \"end\": 516,\n                    \"name\": \"MSTORE\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 562,\n                    \"end\": 563,\n                    \"name\": \"PUSH\",\n                    \"source\": -1,\n                    \"value\": \"4\"\n                },\n                {\n                    \"begin\": 546,\n                    \"end\": 560,\n                    \"name\": \"CALLDATASIZE\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 543,\n                    \"end\": 564,\n                    \"name\": \"LT\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 536,\n                    \"end\": 565,\n                    \"name\": \"ISZERO\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 533,\n                    \"end\": 831,\n                    \"name\": \"PUSH [tag]\",\n                    \"source\": -1,\n                    \"value\": \"1\"\n                },\n                {\n                    \"begin\": 533,\n                    \"end\": 831,\n                    \"name\": \"JUMPI\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 426,\n                    \"end\": 884,\n                    \"name\": \"tag\",\n                    \"source\": -1,\n                    \"value\": \"2\"\n                },\n                {\n                    \"begin\": 426,\n                    \"end\": 884,\n                    \"name\": \"JUMPDEST\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 858,\n                    \"end\": 859,\n                    \"name\": \"PUSH\",\n                    \"source\": -1,\n                    \"value\": \"0\"\n                },\n                {\n                    \"begin\": 848,\n                    \"end\": 860,\n                    \"name\": \"DUP1\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 848,\n                    \"end\": 860,\n                    \"name\": \"REVERT\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 582,\n                    \"end\": 831,\n                    \"name\": \"tag\",\n                    \"source\": -1,\n                    \"value\": \"1\"\n                },\n                {\n                    \"begin\": 582,\n                    \"end\": 831,\n                    \"name\": \"JUMPDEST\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 614,\n                    \"end\": 615,\n                    \"name\": \"PUSH\",\n                    \"source\": -1,\n                    \"value\": \"0\"\n                },\n                {\n                    \"begin\": 652,\n                    \"end\": 668,\n                    \"name\": \"CALLDATALOAD\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 647,\n                    \"end\": 650,\n                    \"name\": \"PUSH\",\n                    \"source\": -1,\n                    \"value\": \"E0\"\n                },\n                {\n                    \"begin\": 643,\n                    \"end\": 669,\n                    \"name\": \"SHR\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 695,\n                    \"end\": 705,\n                    \"name\": \"PUSH\",\n                    \"source\": -1,\n                    \"value\": \"B4F40C61\"\n                },\n                {\n                    \"begin\": 690,\n                    \"end\": 813,\n                    \"name\": \"SUB\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 582,\n                    \"end\": 831,\n                    \"name\": \"PUSH [tag]\",\n                    \"source\": -1,\n                    \"value\": \"2\"\n                },\n                {\n                    \"begin\": 690,\n                    \"end\": 813,\n                    \"name\": \"JUMPI\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 788,\n                    \"end\": 790,\n                    \"name\": \"PUSH\",\n                    \"source\": -1,\n                    \"value\": \"20\"\n                },\n                {\n                    \"begin\": 743,\n                    \"end\": 751,\n                    \"name\": \"SWAP1\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 749,\n                    \"end\": 750,\n                    \"name\": \"PUSH\",\n                    \"source\": -1,\n                    \"value\": \"1\"\n                },\n                {\n                    \"begin\": 743,\n                    \"end\": 751,\n                    \"name\": \"SLOAD\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 732,\n                    \"end\": 752,\n                    \"name\": \"DUP2\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 732,\n                    \"end\": 752,\n                    \"name\": \"MSTORE\",\n                    \"source\": -1\n                },\n                {\n                    \"begin\": 777,\n                    \"end\": 791,\n                    \"name\": \"RETURN\",\n                    \"source\": -1\n                }\n            ]\n        }\n    },\n    \"sourceList\": [\n        \"abc.sol\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_without_debug_info_annotations/stdin",
    "content": "/// @use-src 0: \"abc.sol\"\nobject \"C_23\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            sstore(0x00, 0x02)\n            sstore(0x01, 0x00)\n            let _2 := datasize(\"C_23_deployed\")\n            codecopy(_1, dataoffset(\"C_23_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    object \"C_23_deployed\" {\n        code {\n            {\n                let _1 := memoryguard(0x80)\n                mstore(64, _1)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let _2 := 0\n                    switch shr(224, calldataload(_2))\n                    case 0xb4f40c61 {\n                        mstore(_1, sload(1))\n                        return(_1, 32)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"1234abcd\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_yul_verbatim/args",
    "content": "--strict-assembly - --asm-json --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_yul_verbatim/output",
    "content": "\n======= <stdin> (EVM) =======\n\nEVM assembly:\n{\n    \".code\": [\n        {\n            \"begin\": -1,\n            \"end\": -1,\n            \"name\": \"VERBATIM\",\n            \"source\": -1,\n            \"value\": \"78797a\"\n        }\n    ],\n    \"sourceList\": [\n        \"abc.sol\"\n    ]\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_asm_json_yul_verbatim/stdin",
    "content": "/// @use-src 0: \"abc.sol\"\n{\n    verbatim_0i_0o(\"xyz\")\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_ast_compact_json/args",
    "content": "--strict-assembly --ast-compact-json --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_ast_compact_json/input.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_ast_compact_json/output",
    "content": "\n======= input.yul (EVM) =======\nAST:\n\n{\n    \"code\": {\n        \"block\": {\n            \"nativeSrc\": \"60:85:0\",\n            \"nodeType\": \"YulBlock\",\n            \"src\": \"-1:-1:0\",\n            \"statements\": [\n                {\n                    \"nativeSrc\": \"70:69:0\",\n                    \"nodeType\": \"YulBlock\",\n                    \"src\": \"-1:-1:0\",\n                    \"statements\": [\n                        {\n                            \"expression\": {\n                                \"arguments\": [\n                                    {\n                                        \"kind\": \"number\",\n                                        \"nativeSrc\": \"121:2:0\",\n                                        \"nodeType\": \"YulLiteral\",\n                                        \"src\": \"60:41:0\",\n                                        \"type\": \"\",\n                                        \"value\": \"64\"\n                                    },\n                                    {\n                                        \"kind\": \"number\",\n                                        \"nativeSrc\": \"125:3:0\",\n                                        \"nodeType\": \"YulLiteral\",\n                                        \"src\": \"60:41:0\",\n                                        \"type\": \"\",\n                                        \"value\": \"128\"\n                                    }\n                                ],\n                                \"functionName\": {\n                                    \"name\": \"mstore\",\n                                    \"nativeSrc\": \"114:6:0\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"60:41:0\"\n                                },\n                                \"nativeSrc\": \"114:15:0\",\n                                \"nodeType\": \"YulFunctionCall\",\n                                \"src\": \"60:41:0\"\n                            },\n                            \"nativeSrc\": \"114:15:0\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"60:41:0\"\n                        }\n                    ]\n                }\n            ]\n        },\n        \"nodeType\": \"YulCode\"\n    },\n    \"name\": \"C_6_deployed\",\n    \"nodeType\": \"YulObject\",\n    \"subObjects\": []\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_code_generation_error/args",
    "content": "--strict-assembly --bin\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_code_generation_error/err",
    "content": "Error: Some immutables were read from but never assigned, possibly because of optimization.\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_code_generation_error/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_code_generation_error/input.yul",
    "content": "object \"C\" {\n    code {}\n\n    object \"C_deployed\" {\n        code {\n            sstore(0, loadimmutable(\"1\"))\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_all/args",
    "content": "--strict-assembly --debug-info all\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_all/input.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_all/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\n/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        {\n            /// @src 0:60:101\n            mstore(64, 128)\n            fun_f()\n        }\n        /// @src 0:77:99\n        function fun_f()\n        { sstore(0, 42) }\n    }\n}\n\n\nBinary representation:\n6080604052600a600c565b005b602a5f5556\n\nText representation:\n    /* \"input.sol\":60:101   */\n  mstore(0x40, 0x80)\n  tag_2\n  tag_1\n  jump\t// in\ntag_2:\n  stop\n    /* \"input.sol\":77:99   */\ntag_1:\n  sstore(0x00, 0x2a)\n  jump\t// out\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_location_only/args",
    "content": "--strict-assembly --debug-info location\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_location_only/input.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_location_only/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\n/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        {\n            /// @src 0:60:101\n            mstore(64, 128)\n            fun_f()\n        }\n        /// @src 0:77:99\n        function fun_f()\n        { sstore(0, 42) }\n    }\n}\n\n\nBinary representation:\n6080604052600a600c565b005b602a5f5556\n\nText representation:\n    /* \"input.sol\":60:101 */\n  mstore(0x40, 0x80)\n  tag_2\n  tag_1\n  jump\t// in\ntag_2:\n  stop\n    /* \"input.sol\":77:99 */\ntag_1:\n  sstore(0x00, 0x2a)\n  jump\t// out\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_none/args",
    "content": "--strict-assembly --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_none/input.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_none/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\n/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        {\n            mstore(64, 128)\n            fun_f()\n        }\n        function fun_f()\n        { sstore(0, 42) }\n    }\n}\n\n\nBinary representation:\n6080604052600a600c565b005b602a5f5556\n\nText representation:\n  mstore(0x40, 0x80)\n  tag_2\n  tag_1\n  jump\t// in\ntag_2:\n  stop\ntag_1:\n  sstore(0x00, 0x2a)\n  jump\t// out\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_snippet_only/args",
    "content": "--strict-assembly --debug-info snippet\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_snippet_only/err",
    "content": "Error: To use 'snippet' with --debug-info you must select also 'location'.\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_snippet_only/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_debug_info_print_snippet_only/input.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_6_deployed\" {\n    code {\n        /// @src 0:60:101  \"contract C {...\"\n        mstore(64, 128)\n\n        // f()\n        fun_f_5()\n\n        /// @src 0:77:99  \"function f() public {}\"\n        function fun_f_5() {\n            sstore(0, 42)\n        }\n        /// @src 0:60:101  \"contract C {...\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_eof_container_osaka/args",
    "content": "--experimental  --strict-assembly --experimental-eof-version 1 --evm-version osaka --asm --ir-optimized --bin --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_eof_container_osaka/input.yul",
    "content": "object \"object\" {\n    code {\n        mstore(0, eofcreate(\"sub0\", 0, 0, 0, 0))\n        mstore(32, eofcreate(\"sub1\", 0, 0, 0, 0))\n        return(0, 64)\n    }\n\n    object \"sub0\" {\n        code {\n            returncontract(\"sub00\", 0, 0)\n        }\n        object \"sub00\" {\n            code {\n                mstore(0, 1)\n                revert(0, 32)\n            }\n        }\n    }\n\n    object \"sub1\" {\n        code {\n            returncontract(\"sub10\", 0, 0)\n        }\n        object \"sub10\" {\n            code {\n                mstore(0, 0x20)\n                revert(0, 32)\n            }\n        }\n    }\n    object \"sub2\" {\n        code {\n            mstore(0, 3)\n            revert(0, 32)\n        }\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/strict_asm_eof_container_osaka/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code {\n        {\n            mstore(0, eofcreate(\"sub0\", 0, 0, 0, 0))\n            mstore(32, eofcreate(\"sub1\", 0, 0, 0, 0))\n            return(0, 64)\n        }\n    }\n    object \"sub0\" {\n        code {\n            { returncontract(\"sub00\", 0, 0) }\n        }\n        object \"sub00\" {\n            code {\n                {\n                    mstore(0, 1)\n                    revert(0, 32)\n                }\n            }\n        }\n    }\n    object \"sub1\" {\n        code {\n            { returncontract(\"sub10\", 0, 0) }\n        }\n        object \"sub10\" {\n            code {\n                {\n                    mstore(0, 0x20)\n                    revert(0, 32)\n                }\n            }\n        }\n    }\n    object \"sub2\" {\n        code {\n            {\n                mstore(0, 3)\n                revert(0, 32)\n            }\n        }\n    }\n}\n\n\nBinary representation:\nef000101000402000100150300020037003704000000008000045f808080ec005f525f808080ec0160205260405ff3ef00010100040200010004030001001b04000000008000025f80ee00ef00010100040200010008040000000080000260015f5260205ffdef00010100040200010004030001001b04000000008000025f80ee00ef00010100040200010008040000000080000260205f5260205ffd\n\nText representation:\n  0x00\n  dup1\n  dup1\n  dup1\n  eofcreate{0}\n  0x00\n  mstore\n  0x00\n  dup1\n  dup1\n  dup1\n  eofcreate{1}\n  0x20\n  mstore\n  0x40\n  0x00\n  return\nstop\n\nsub_0: assembly {\n      0x00\n      dup1\n      returncontract{0}\n    stop\n\n    sub_0: assembly {\n          0x01\n          0x00\n          mstore\n          0x20\n          0x00\n          revert\n    }\n}\n\nsub_1: assembly {\n      0x00\n      dup1\n      returncontract{0}\n    stop\n\n    sub_0: assembly {\n          0x20\n          0x00\n          mstore\n          0x20\n          0x00\n          revert\n    }\n}\n\nsub_2: assembly {\n      0x03\n      0x00\n      mstore\n      0x20\n      0x00\n      revert\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_eof_dataloadn_osaka/args",
    "content": "--experimental  --strict-assembly --experimental-eof-version 1 --evm-version osaka --asm --ir-optimized --bin --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_eof_dataloadn_osaka/input.yul",
    "content": "object \"a\" {\n    code {\n        mstore(0, auxdataloadn(0))\n        return(0, 32)\n    }\n\n    data \"data1\" \"Hello, World!\"\n}\n\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_eof_dataloadn_osaka/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"a\" {\n    code {\n        {\n            mstore(0, auxdataloadn(0))\n            return(0, 32)\n        }\n    }\n    data \"data1\" hex\"48656c6c6f2c20576f726c6421\"\n}\n\n\nBinary representation:\nef0001010004020001000904002d0000800002d1000d5f5260205ff348656c6c6f2c20576f726c6421\n\nText representation:\n  auxdataloadn{0}\n  0x00\n  mstore\n  0x20\n  0x00\n  return\nstop\ndata_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/args",
    "content": "--experimental --strict-assembly --experimental-eof-version 1 --evm-version cancun\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/err",
    "content": "Error: EOF is not supported by EVM versions earlier than osaka.\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_eof_unavailable_before_osaka/input.yul",
    "content": "{}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_evm_version_byzantium/args",
    "content": "--strict-assembly --evm-version byzantium\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_evm_version_byzantium/err",
    "content": "Warning: Support for EVM versions older than constantinople is deprecated and will be removed in the future.\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_evm_version_byzantium/input.yul",
    "content": "{}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_evm_version_byzantium/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code { { } }\n}\n\n\nBinary representation:\n00\n\nText representation:\n    /* \"input.yul\":27:34   */\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_evm_version_constantinople/args",
    "content": "--strict-assembly --evm-version constantinople\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_evm_version_constantinople/input.yul",
    "content": "{}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_evm_version_constantinople/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code { { } }\n}\n\n\nBinary representation:\n00\n\nText representation:\n    /* \"input.yul\":27:34   */\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_invalid_option_output_dir/args",
    "content": "--strict-assembly --output-dir /tmp/\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_invalid_option_output_dir/err",
    "content": "Error: The following options are invalid in assembly mode: --output-dir.\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_invalid_option_output_dir/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_invalid_option_output_dir/input.yul",
    "content": "{\n    sstore(0, 1)\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_jump/args",
    "content": "--strict-assembly"
  },
  {
    "path": "test/cmdlineTests/strict_asm_jump/err",
    "content": "Error: Function \"jump\" not found.\n --> input.yul:1:3:\n  |\n1 | { jump(1) }\n  |   ^^^^\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_jump/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_jump/input.yul",
    "content": "{ jump(1) }"
  },
  {
    "path": "test/cmdlineTests/strict_asm_msize_with_optimizer/args",
    "content": "--strict-assembly --debug-info none --optimize\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_msize_with_optimizer/input.yul",
    "content": "{\n    function f() -> x {\n        x := mload(0)\n    }\n\n    // In pure Yul optimization in presence of msize is allowed.\n    // Everything in this file should get optimized out.\n    pop(msize())\n\n    let x := 0\n    let y := x\n    mstore(0, f())\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_msize_with_optimizer/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code { { } }\n}\n\n\nBinary representation:\n00\n\nText representation:\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_msize_without_optimizer/args",
    "content": "--strict-assembly --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_msize_without_optimizer/input.yul",
    "content": "{\n    function f() -> x {\n        x := mload(0)\n    }\n\n    // In pure Yul without optimizer presence of msize disables stack optimization.\n    // This file should remain untouched when passed through the optimizer.\n    pop(msize())\n\n    let x := 0\n    let y := x\n    mstore(0, f())\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_msize_without_optimizer/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code {\n        function f() -> x\n        { x := mload(0) }\n        pop(msize())\n        let x := 0\n        let y := x\n        mstore(0, f())\n    }\n}\n\n\nBinary representation:\n600b565b5f5f51905090565b5f8060136003565b5f525050\n\nText representation:\n  jump(tag_2)\ntag_1:\n  0x00\n  0x00\n  mload\n  swap1\n  pop\n  swap1\n  jump\t// out\ntag_2:\n  0x00\n  dup1\n  tag_4\n  tag_1\n  jump\t// in\ntag_4:\n  0x00\n  mstore\n  pop\n  pop\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_only_cr/args",
    "content": "--strict-assembly\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_only_cr/err",
    "content": "Error: Expected keyword \"object\".\n --> input.yul:1:2:\n  |\n1 | \n  | ^\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_only_cr/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_only_cr/input.yul",
    "content": "\r"
  },
  {
    "path": "test/cmdlineTests/strict_asm_optimizer_invalid_yul_optimizer_enabled_and_disabled/args",
    "content": "--strict-assembly --optimize-yul --no-optimize-yul\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_optimizer_invalid_yul_optimizer_enabled_and_disabled/err",
    "content": "Error: Options --optimize-yul and --no-optimize-yul cannot be used together.\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_optimizer_invalid_yul_optimizer_enabled_and_disabled/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_optimizer_invalid_yul_optimizer_enabled_and_disabled/input.yul",
    "content": "{}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_optimizer_steps/args",
    "content": "--strict-assembly --optimize --yul-optimizations dhfoDgvulfnTUtnIf\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_optimizer_steps/input.yul",
    "content": "object \"C_6\" {\n    code {\n        mstore(64, 128)\n        if callvalue() { revert(0, 0) }\n        codecopy(0, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))\n        return(0, datasize(\"C_6_deployed\"))\n    }\n    object \"C_6_deployed\" {\n        code {\n            {\n                mstore(64, 128)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_224_unsigned(calldataload(0))\n                    pop(selector)\n                }\n                sstore(0, iszero(calldatasize()))\n                revert(0, 0)\n            }\n\n            function shift_right_224_unsigned(value) -> newValue\n            {\n                newValue := shr(224, value)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_optimizer_steps/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"C_6\" {\n    code {\n        {\n            mstore(64, 128)\n            if callvalue() { revert(0, 0) }\n            codecopy(0, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))\n            return(0, datasize(\"C_6_deployed\"))\n        }\n    }\n    object \"C_6_deployed\" {\n        code {\n            {\n                mstore(64, 128)\n                sstore(0, iszero(calldatasize()))\n                revert(0, 0)\n            }\n        }\n    }\n}\n\n\nBinary representation:\n608060405234601357600c60185f39600c5ff35b5f80fdfe608060405236155f555f80fd\n\nText representation:\n    /* \"input.yul\":59:62   */\n  0x80\n    /* \"input.yul\":55:57   */\n  0x40\n    /* \"input.yul\":48:63   */\n  mstore\n    /* \"input.yul\":79:90   */\n  callvalue\n    /* \"input.yul\":76:107   */\n  tag_1\n  jumpi\n    /* \"input.yul\":160:184   */\n  dataSize(sub_0)\n    /* \"input.yul\":132:158   */\n  dataOffset(sub_0)\n    /* \"input.yul\":129:130   */\n  0x00\n    /* \"input.yul\":120:185   */\n  codecopy\n    /* \"input.yul\":208:232   */\n  dataSize(sub_0)\n    /* \"input.yul\":205:206   */\n  0x00\n    /* \"input.yul\":198:233   */\n  return\n    /* \"input.yul\":91:107   */\ntag_1:\n    /* \"input.yul\":103:104   */\n  0x00\n    /* \"input.yul\":93:105   */\n  dup1\n  revert\nstop\n\nsub_0: assembly {\n        /* \"input.yul\":334:337   */\n      0x80\n        /* \"input.yul\":330:332   */\n      0x40\n        /* \"input.yul\":323:338   */\n      mstore\n        /* \"input.yul\":372:386   */\n      calldatasize\n        /* \"input.yul\":365:387   */\n      iszero\n        /* \"input.yul\":362:363   */\n      0x00\n        /* \"input.yul\":355:388   */\n      sstore\n        /* \"input.yul\":415:416   */\n      0x00\n        /* \"input.yul\":405:417   */\n      dup1\n      revert\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_options_in_non_asm_mode/args",
    "content": "--yul-dialect evm --machine evm\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_options_in_non_asm_mode/err",
    "content": "Error: --yul-dialect and --machine are only valid in assembly mode.\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_options_in_non_asm_mode/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_options_in_non_asm_mode/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C\n{\n\tfunction f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_asm_only/args",
    "content": "--strict-assembly --optimize --asm\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_asm_only/input.yul",
    "content": "{\n    let x := 42\n    sstore(0, x)\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_asm_only/output",
    "content": "\n======= input.yul (EVM) =======\n\nText representation:\n    /* \"input.yul\":41:43   */\n  0x2a\n    /* \"input.yul\":38:39   */\n  0x00\n    /* \"input.yul\":31:44   */\n  sstore\n    /* \"input.yul\":27:48   */\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_bin_only/args",
    "content": "--strict-assembly --optimize --bin\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_bin_only/input.yul",
    "content": "{\n    let x := 42\n    sstore(0, x)\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_bin_only/output",
    "content": "\n======= input.yul (EVM) =======\n\nBinary representation:\n602a5f5500\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_invalid/args",
    "content": "--strict-assembly --asm --asm-json --opcodes --bin --bin-runtime --abi --ir --ir-optimized --hashes --userdoc --devdoc --metadata --storage-layout\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_invalid/err",
    "content": "Error: The following outputs are not supported in assembler mode: --abi, --bin-runtime, --devdoc, --hashes, --ir, --metadata, --opcodes, --storage-layout, --userdoc.\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_invalid/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_invalid/input.yul",
    "content": ""
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/args",
    "content": "--strict-assembly --optimize --ir-optimized\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/input.yul",
    "content": "{\n    let x := 42\n    sstore(0, x)\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_output_selection_ir_optimized_only/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code { { sstore(0, 42) } }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning/args",
    "content": "--strict-assembly --ir-optimized\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning/err",
    "content": "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.\n --> input.yul:4:5:\n  |\n4 |     selfdestruct(0)\n  |     ^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning/input.yul",
    "content": "{\n    // The code is valid and will proceed through the whole pipeline, possibly being reparsed multiple times.\n    // This should produce exactly one warning.\n    selfdestruct(0)\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code { { selfdestruct(0) } }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_and_error_optimize/args",
    "content": "--strict-assembly --optimize --ir-optimized\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_and_error_optimize/err",
    "content": "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.\n --> input.yul:4:5:\n  |\n4 |     selfdestruct()\n  |     ^^^^^^^^^^^^\n\nError: Function \"selfdestruct\" expects 1 arguments but got 0.\n --> input.yul:4:5:\n  |\n4 |     selfdestruct()\n  |     ^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_and_error_optimize/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_and_error_optimize/input.yul",
    "content": "{\n    // The code does not compile so the optimizer will not run.\n    // This should generate exactly one warning and one error.\n    selfdestruct()\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_optimize/args",
    "content": "--strict-assembly --optimize --ir-optimized\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_optimize/err",
    "content": "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.\n --> input.yul:4:5:\n  |\n4 |     selfdestruct(0)\n  |     ^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_optimize/input.yul",
    "content": "{\n    // The code is valid and will proceed through the whole pipeline, possibly being reparsed multiple times.\n    // This should produce exactly one warning.\n    selfdestruct(0)\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_optimize/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code { { selfdestruct(0) } }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_optimize_unreachable/args",
    "content": "--strict-assembly --optimize --ir-optimized\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_optimize_unreachable/err",
    "content": "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.\n --> input.yul:7:5:\n  |\n7 |     selfdestruct(0)\n  |     ^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_optimize_unreachable/input.yul",
    "content": "{\n    revert(0, 0)\n\n    // The code is valid and will proceed through the whole pipeline, possibly being reparsed multiple times.\n    // Note that the code is unreachable, so the warning would not appear in the optimized version.\n    // This should produce exactly one warning.\n    selfdestruct(0)\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_warning_optimize_unreachable/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code { { revert(0, 0) } }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_yul_cfg_json_export/args",
    "content": "--experimental --strict-assembly --optimize --yul-cfg-json --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_yul_cfg_json_export/input.yul",
    "content": "/// @use-src 0:\"input.sol\"\nobject \"C_19\" {\n  code {\n    {\n      /// @src 0:124:223  \"contract C is I {...\"\n      let _1 := memoryguard(0x80)\n      mstore(64, _1)\n      if callvalue() { revert(0, 0) }\n      let _2 := datasize(\"C_19_deployed\")\n      codecopy(_1, dataoffset(\"C_19_deployed\"), _2)\n      return(_1, _2)\n    }\n  }\n  /// @use-src 0:\"input.sol\"\n  object \"C_19_deployed\" {\n    code {\n      {\n        /// @src 0:124:223  \"contract C is I {...\"\n        let _1 := memoryguard(0x80)\n        mstore(64, _1)\n        if iszero(lt(calldatasize(), 4))\n        {\n          if eq(0x26121ff0, shr(224, calldataload(0)))\n          {\n            if callvalue() { revert(0, 0) }\n            if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n            mstore(_1, /** @src 0:212:214  \"42\" */ 0x2a)\n            /// @src 0:124:223  \"contract C is I {...\"\n            return(_1, 32)\n          }\n        }\n        revert(0, 0)\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/strict_asm_yul_cfg_json_export/output",
    "content": "\n======= input.yul (EVM) =======\nYul Control Flow Graph:\n\n{\n    \"C_19\": {\n        \"blocks\": [\n            {\n                \"exit\": {\n                    \"cond\": \"v1\",\n                    \"targets\": [\n                        \"Block2\",\n                        \"Block1\"\n                    ],\n                    \"type\": \"ConditionalJump\"\n                },\n                \"id\": \"Block0\",\n                \"instructions\": [\n                    {\n                        \"in\": [],\n                        \"literalArgs\": [\n                            \"0x80\"\n                        ],\n                        \"op\": \"memoryguard\",\n                        \"out\": [\n                            \"v0\"\n                        ]\n                    },\n                    {\n                        \"in\": [\n                            \"v0\",\n                            \"0x40\"\n                        ],\n                        \"op\": \"mstore\",\n                        \"out\": []\n                    },\n                    {\n                        \"in\": [],\n                        \"op\": \"callvalue\",\n                        \"out\": [\n                            \"v1\"\n                        ]\n                    }\n                ],\n                \"liveness\": {\n                    \"in\": [],\n                    \"out\": [\n                        \"v0\"\n                    ]\n                },\n                \"type\": \"BuiltinCall\"\n            },\n            {\n                \"exit\": {\n                    \"type\": \"Terminated\"\n                },\n                \"id\": \"Block2\",\n                \"instructions\": [\n                    {\n                        \"in\": [],\n                        \"literalArgs\": [\n                            \"C_19_deployed\"\n                        ],\n                        \"op\": \"datasize\",\n                        \"out\": [\n                            \"v2\"\n                        ]\n                    },\n                    {\n                        \"in\": [],\n                        \"literalArgs\": [\n                            \"C_19_deployed\"\n                        ],\n                        \"op\": \"dataoffset\",\n                        \"out\": [\n                            \"v3\"\n                        ]\n                    },\n                    {\n                        \"in\": [\n                            \"v2\",\n                            \"v3\",\n                            \"v0\"\n                        ],\n                        \"op\": \"codecopy\",\n                        \"out\": []\n                    },\n                    {\n                        \"in\": [\n                            \"v2\",\n                            \"v0\"\n                        ],\n                        \"op\": \"return\",\n                        \"out\": []\n                    }\n                ],\n                \"liveness\": {\n                    \"in\": [\n                        \"v0\"\n                    ],\n                    \"out\": []\n                },\n                \"type\": \"BuiltinCall\"\n            },\n            {\n                \"exit\": {\n                    \"type\": \"Terminated\"\n                },\n                \"id\": \"Block1\",\n                \"instructions\": [\n                    {\n                        \"in\": [\n                            \"0x00\",\n                            \"0x00\"\n                        ],\n                        \"op\": \"revert\",\n                        \"out\": []\n                    }\n                ],\n                \"liveness\": {\n                    \"in\": [],\n                    \"out\": []\n                },\n                \"type\": \"BuiltinCall\"\n            }\n        ],\n        \"functions\": {},\n        \"subObjects\": {\n            \"C_19_deployed\": {\n                \"blocks\": [\n                    {\n                        \"exit\": {\n                            \"cond\": \"v3\",\n                            \"targets\": [\n                                \"Block2\",\n                                \"Block1\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block0\",\n                        \"instructions\": [\n                            {\n                                \"in\": [],\n                                \"literalArgs\": [\n                                    \"0x80\"\n                                ],\n                                \"op\": \"memoryguard\",\n                                \"out\": [\n                                    \"v0\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v0\",\n                                    \"0x40\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"calldatasize\",\n                                \"out\": [\n                                    \"v1\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x04\",\n                                    \"v1\"\n                                ],\n                                \"op\": \"lt\",\n                                \"out\": [\n                                    \"v2\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v2\"\n                                ],\n                                \"op\": \"iszero\",\n                                \"out\": [\n                                    \"v3\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block2\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v6\",\n                            \"targets\": [\n                                \"Block4\",\n                                \"Block3\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block1\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\"\n                                ],\n                                \"op\": \"calldataload\",\n                                \"out\": [\n                                    \"v4\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v4\",\n                                    \"0xe0\"\n                                ],\n                                \"op\": \"shr\",\n                                \"out\": [\n                                    \"v5\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v5\",\n                                    \"0x26121ff0\"\n                                ],\n                                \"op\": \"eq\",\n                                \"out\": [\n                                    \"v6\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"targets\": [\n                                \"Block2\"\n                            ],\n                            \"type\": \"Jump\"\n                        },\n                        \"id\": \"Block4\",\n                        \"instructions\": [],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        }\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v7\",\n                            \"targets\": [\n                                \"Block6\",\n                                \"Block5\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block3\",\n                        \"instructions\": [\n                            {\n                                \"in\": [],\n                                \"op\": \"callvalue\",\n                                \"out\": [\n                                    \"v7\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v11\",\n                            \"targets\": [\n                                \"Block9\",\n                                \"Block8\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block6\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x03\"\n                                ],\n                                \"op\": \"not\",\n                                \"out\": [\n                                    \"v8\"\n                                ]\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"calldatasize\",\n                                \"out\": [\n                                    \"v9\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v8\",\n                                    \"v9\"\n                                ],\n                                \"op\": \"add\",\n                                \"out\": [\n                                    \"v10\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"v10\"\n                                ],\n                                \"op\": \"slt\",\n                                \"out\": [\n                                    \"v11\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block5\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block9\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x2a\",\n                                    \"v0\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [\n                                    \"0x20\",\n                                    \"v0\"\n                                ],\n                                \"op\": \"return\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block8\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    }\n                ],\n                \"functions\": {}\n            },\n            \"type\": \"subObject\"\n        }\n    },\n    \"type\": \"Object\"\n}\n"
  },
  {
    "path": "test/cmdlineTests/structured_documentation_source_location/err",
    "content": "Error: Documentation tag \"@return No value returned\" does not contain the name of its return parameter.\n --> input.sol:4:5:\n  |\n4 |     /// @param id Some identifier\n  |     ^ (Relevant source part starts here and spans across multiple lines).\n\nError: Documentation tag \"@return No value returned\" does not contain the name of its return parameter.\n --> input.sol:8:5:\n  |\n8 |     /// @return No value returned\n  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/structured_documentation_source_location/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/structured_documentation_source_location/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >= 0.0;\nabstract contract C {\n    /// @param id Some identifier\n    /// @return No value returned\n    function vote(uint id) public virtual returns (uint value);\n\n    /// @return No value returned\n    function unvote(uint id) public virtual returns (uint value);\n}"
  },
  {
    "path": "test/cmdlineTests/too_long_line/err",
    "content": "Error: Identifier not found or not unique.\n --> input.sol:5:164:\n  |\n5 |  ... ffffffffffffffffffffffffffffffffff(announcementType Type, string Announcement, string  ...\n  |                                         ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n   function ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff(announcementType Type, string Announcement, string Link, bool Oppositable, string _str, uint256 _uint, address _addr) onlyOwner external {\n}\n}\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_both_sides_short/err",
    "content": "Error: Identifier not found or not unique.\n --> input.sol:5:15:\n  |\n5 |    function f(announcementTypeXXXXXXXXXXXXXXXXXXX ... XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Type,\n  |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_both_sides_short/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_both_sides_short/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n   function f(announcementTypeXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Type,\n       string Announcement, string Link, bool Oppositable, string _str, uint256 _uint, address _addr) onlyOwner external {\n}\n}\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_edge_in/err",
    "content": "Error: Identifier not found or not unique.\n --> input.sol:5:36:\n  |\n5 |    function ffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Ty, string A) onlyOwner external {\n  |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_edge_in/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_edge_in/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n   function ffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Ty, string A) onlyOwner external {\n}\n}\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_edge_out/err",
    "content": "Error: Identifier not found or not unique.\n --> input.sol:5:37:\n  |\n5 |  ...   function fffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Typ, string A) onlyOwner external  ...\n  |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_edge_out/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_edge_out/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n   function fffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Typ, string A) onlyOwner external {\n}\n}\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_left_short/err",
    "content": "Error: Identifier not found or not unique.\n --> input.sol:5:15:\n  |\n5 |    function f(announcementType Type, string Announcement, string  ...\n  |               ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_left_short/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_left_short/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n   function f(announcementType Type, string Announcement, string Link, bool Oppositable, string _str, uint256 _uint, address _addr) onlyOwner external {\n}\n}\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_multiline/err",
    "content": "Error: No visibility specified. Did you intend to add \"public\"?\n --> input.sol:5:5:\n  |\n5 |     function f() returns (bytes1 _b, by ... _b7, bytes22 _b22, bytes32 _b32)  {\n  |     ^ (Relevant source part starts here and spans across multiple lines).\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_multiline/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_multiline/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n    function f() returns (bytes1 _b, bytes2 _b2, bytes3 _b3, bytes memory _blit, bytes5 _b5, bytes6 _b6, string memory _str, bytes7 _b7, bytes22 _b22, bytes32 _b32)  {\n        _b = 0x12;\n        _b2 = 0x1223;\n        _b5 = hex\"043245\";\n        _b6 = hex\"2345532532\";\n        _b7 = hex\"03252353253253\";\n        _b22 = hex\"325235235325325325235325\";\n        _b32 = hex\"032523532532523532523532523532\";\n        _blit = hex\"123498\";\n        _str = \"heidy\";\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_right_short/err",
    "content": "Error: Identifier not found or not unique.\n --> input.sol:5:164:\n  |\n5 |  ... ffffffffffffffffffffffffffffffffff(announcementType Type,\n  |                                         ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_right_short/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/too_long_line_right_short/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n   function ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff(announcementType Type,\n       string Announcement, string Link, bool Oppositable, string _str, uint256 _uint, address _addr) onlyOwner external {\n}\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout/args",
    "content": "--transient-storage-layout --pretty-json --json-indent 4"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity > 0.0;\n\ncontract D { }\n\ncontract C {\n    uint transient x;\n    uint y;\n    address transient w;\n    int z;\n    bool transient b;\n    D transient d;\n}"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout/output",
    "content": "\n======= input.sol:C =======\nContract Transient Storage Layout:\n{\n    \"storage\": [\n        {\n            \"astId\": 4,\n            \"contract\": \"input.sol:C\",\n            \"label\": \"x\",\n            \"offset\": 0,\n            \"slot\": \"0\",\n            \"type\": \"t_uint256\"\n        },\n        {\n            \"astId\": 8,\n            \"contract\": \"input.sol:C\",\n            \"label\": \"w\",\n            \"offset\": 0,\n            \"slot\": \"1\",\n            \"type\": \"t_address\"\n        },\n        {\n            \"astId\": 12,\n            \"contract\": \"input.sol:C\",\n            \"label\": \"b\",\n            \"offset\": 20,\n            \"slot\": \"1\",\n            \"type\": \"t_bool\"\n        },\n        {\n            \"astId\": 15,\n            \"contract\": \"input.sol:C\",\n            \"label\": \"d\",\n            \"offset\": 0,\n            \"slot\": \"2\",\n            \"type\": \"t_contract(D)2\"\n        }\n    ],\n    \"types\": {\n        \"t_address\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"address\",\n            \"numberOfBytes\": \"20\"\n        },\n        \"t_bool\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"bool\",\n            \"numberOfBytes\": \"1\"\n        },\n        \"t_contract(D)2\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"contract D\",\n            \"numberOfBytes\": \"20\"\n        },\n        \"t_uint256\": {\n            \"encoding\": \"inplace\",\n            \"label\": \"uint256\",\n            \"numberOfBytes\": \"32\"\n        }\n    }\n}\n\n======= input.sol:D =======\nContract Transient Storage Layout:\n{\n    \"storage\": []\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_smoke_empty/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [\"transientStorageLayout\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_smoke_empty/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"transientStorageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_smoke_two_contracts/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A { }\"\n\t\t},\n\t\t\"fileB\": {\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract B { uint transient x; uint transient y; }\"\n\t\t}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [\"transientStorageLayout\"]\n\t\t\t},\n\t\t\t\"fileB\": {\n\t\t\t\t\"B\": [\"transientStorageLayout\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_smoke_two_contracts/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"transientStorageLayout\": {\n                    \"storage\": [],\n                    \"types\": null\n                }\n            }\n        },\n        \"fileB\": {\n            \"B\": {\n                \"transientStorageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 6,\n                            \"contract\": \"fileB:B\",\n                            \"label\": \"x\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 8,\n                            \"contract\": \"fileB:B\",\n                            \"label\": \"y\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_uint256\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        },\n        \"fileB\": {\n            \"id\": 1\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_value_types/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ntype MyInt is int256;\n\nenum MyEnum {\n    None,\n    Something,\n    SomethingElse\n}\n\ncontract C { }\n\ncontract A {\n    uint transient x;\n    int transient y;\n    address transient addr;\n    bool transient b;\n    MyInt transient w;\n    C transient c;\n    MyEnum transient e;\n    function() external transient p;\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_value_types/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [\"transientStorageLayout\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_value_types/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"transientStorageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 10,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"x\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 12,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"y\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_int256\"\n                        },\n                        {\n                            \"astId\": 14,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"addr\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_address\"\n                        },\n                        {\n                            \"astId\": 16,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"b\",\n                            \"offset\": 20,\n                            \"slot\": \"2\",\n                            \"type\": \"t_bool\"\n                        },\n                        {\n                            \"astId\": 19,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"w\",\n                            \"offset\": 0,\n                            \"slot\": \"3\",\n                            \"type\": \"t_userDefinedValueType(MyInt)3\"\n                        },\n                        {\n                            \"astId\": 22,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"c\",\n                            \"offset\": 0,\n                            \"slot\": \"4\",\n                            \"type\": \"t_contract(C)8\"\n                        },\n                        {\n                            \"astId\": 25,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"e\",\n                            \"offset\": 20,\n                            \"slot\": \"4\",\n                            \"type\": \"t_enum(MyEnum)7\"\n                        },\n                        {\n                            \"astId\": 29,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"p\",\n                            \"offset\": 0,\n                            \"slot\": \"5\",\n                            \"type\": \"t_function_external_nonpayable()returns()\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_bool\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"bool\",\n                            \"numberOfBytes\": \"1\"\n                        },\n                        \"t_contract(C)8\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"contract C\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_enum(MyEnum)7\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"enum MyEnum\",\n                            \"numberOfBytes\": \"1\"\n                        },\n                        \"t_function_external_nonpayable()returns()\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"function () external\",\n                            \"numberOfBytes\": \"24\"\n                        },\n                        \"t_int256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"int256\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_userDefinedValueType(MyInt)3\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"MyInt\",\n                            \"numberOfBytes\": \"32\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ntype MyInt is int8;\ncontract A {\n    uint public transient x;\n    uint public y;\n    int private transient z;\n    int private w;\n    address transient addr;\n    address d;\n    bool transient b;\n    bool c;\n    MyInt i;\n    MyInt transient j;\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [\"storageLayout\", \"transientStorageLayout\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_value_types_interleaved_with_storage/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"storageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 7,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"y\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 11,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"w\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_int256\"\n                        },\n                        {\n                            \"astId\": 15,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"d\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_address\"\n                        },\n                        {\n                            \"astId\": 19,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"c\",\n                            \"offset\": 20,\n                            \"slot\": \"2\",\n                            \"type\": \"t_bool\"\n                        },\n                        {\n                            \"astId\": 22,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"i\",\n                            \"offset\": 21,\n                            \"slot\": \"2\",\n                            \"type\": \"t_userDefinedValueType(MyInt)3\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_bool\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"bool\",\n                            \"numberOfBytes\": \"1\"\n                        },\n                        \"t_int256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"int256\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_userDefinedValueType(MyInt)3\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"MyInt\",\n                            \"numberOfBytes\": \"1\"\n                        }\n                    }\n                },\n                \"transientStorageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 5,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"x\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint256\"\n                        },\n                        {\n                            \"astId\": 9,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"z\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_int256\"\n                        },\n                        {\n                            \"astId\": 13,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"addr\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_address\"\n                        },\n                        {\n                            \"astId\": 17,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"b\",\n                            \"offset\": 20,\n                            \"slot\": \"2\",\n                            \"type\": \"t_bool\"\n                        },\n                        {\n                            \"astId\": 25,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"j\",\n                            \"offset\": 21,\n                            \"slot\": \"2\",\n                            \"type\": \"t_userDefinedValueType(MyInt)3\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_bool\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"bool\",\n                            \"numberOfBytes\": \"1\"\n                        },\n                        \"t_int256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"int256\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_uint256\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint256\",\n                            \"numberOfBytes\": \"32\"\n                        },\n                        \"t_userDefinedValueType(MyInt)3\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"MyInt\",\n                            \"numberOfBytes\": \"1\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_value_types_packed/in.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ntype MyInt is int128;\n\nenum MyEnum {\n    None,\n    Something,\n    SomethingElse\n}\n\ncontract C { }\n\ncontract A {\n    uint64 transient x;\n    uint128 transient y;\n    uint128 transient z;\n    address transient addr;\n    bool transient b;\n    MyInt transient w;\n    C transient c;\n    MyEnum transient e;\n    function() external transient p;\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_value_types_packed/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\": {\n\t\t\"fileA\": {\"urls\": [\"in.sol\"]}\n\t},\n\t\"settings\": {\n\t\t\"outputSelection\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"A\": [\"transientStorageLayout\"]\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/transient_storage_layout_value_types_packed/output.json",
    "content": "{\n    \"contracts\": {\n        \"fileA\": {\n            \"A\": {\n                \"transientStorageLayout\": {\n                    \"storage\": [\n                        {\n                            \"astId\": 10,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"x\",\n                            \"offset\": 0,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint64\"\n                        },\n                        {\n                            \"astId\": 12,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"y\",\n                            \"offset\": 8,\n                            \"slot\": \"0\",\n                            \"type\": \"t_uint128\"\n                        },\n                        {\n                            \"astId\": 14,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"z\",\n                            \"offset\": 0,\n                            \"slot\": \"1\",\n                            \"type\": \"t_uint128\"\n                        },\n                        {\n                            \"astId\": 16,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"addr\",\n                            \"offset\": 0,\n                            \"slot\": \"2\",\n                            \"type\": \"t_address\"\n                        },\n                        {\n                            \"astId\": 18,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"b\",\n                            \"offset\": 20,\n                            \"slot\": \"2\",\n                            \"type\": \"t_bool\"\n                        },\n                        {\n                            \"astId\": 21,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"w\",\n                            \"offset\": 0,\n                            \"slot\": \"3\",\n                            \"type\": \"t_userDefinedValueType(MyInt)3\"\n                        },\n                        {\n                            \"astId\": 24,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"c\",\n                            \"offset\": 0,\n                            \"slot\": \"4\",\n                            \"type\": \"t_contract(C)8\"\n                        },\n                        {\n                            \"astId\": 27,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"e\",\n                            \"offset\": 20,\n                            \"slot\": \"4\",\n                            \"type\": \"t_enum(MyEnum)7\"\n                        },\n                        {\n                            \"astId\": 31,\n                            \"contract\": \"fileA:A\",\n                            \"label\": \"p\",\n                            \"offset\": 0,\n                            \"slot\": \"5\",\n                            \"type\": \"t_function_external_nonpayable()returns()\"\n                        }\n                    ],\n                    \"types\": {\n                        \"t_address\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"address\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_bool\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"bool\",\n                            \"numberOfBytes\": \"1\"\n                        },\n                        \"t_contract(C)8\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"contract C\",\n                            \"numberOfBytes\": \"20\"\n                        },\n                        \"t_enum(MyEnum)7\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"enum MyEnum\",\n                            \"numberOfBytes\": \"1\"\n                        },\n                        \"t_function_external_nonpayable()returns()\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"function () external\",\n                            \"numberOfBytes\": \"24\"\n                        },\n                        \"t_uint128\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint128\",\n                            \"numberOfBytes\": \"16\"\n                        },\n                        \"t_uint64\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"uint64\",\n                            \"numberOfBytes\": \"8\"\n                        },\n                        \"t_userDefinedValueType(MyInt)3\": {\n                            \"encoding\": \"inplace\",\n                            \"label\": \"MyInt\",\n                            \"numberOfBytes\": \"16\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"sources\": {\n        \"fileA\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/undeployable_contract_empty_outputs/args",
    "content": "--experimental --bin --bin-runtime --opcodes --asm --ir --ir-ast-json --ir-optimized --ir-optimized-ast-json --gas --asm-json --abi --hashes --optimize --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/undeployable_contract_empty_outputs/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\nabstract contract C {}\ninterface I {}\n"
  },
  {
    "path": "test/cmdlineTests/undeployable_contract_empty_outputs/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\nnull\nGas estimation:\nOpcodes:\n\nBinary:\n\nBinary of the runtime part:\n\nIR:\n\nIR AST:\nnull\nOptimized IR:\n\nOptimized IR AST:\nnull\nFunction signatures:\nContract JSON ABI\n[]\n\n======= input.sol:I =======\nEVM assembly:\nnull\nGas estimation:\nOpcodes:\n\nBinary:\n\nBinary of the runtime part:\n\nIR:\n\nIR AST:\nnull\nOptimized IR:\n\nOptimized IR AST:\nnull\nFunction signatures:\nContract JSON ABI\n[]\n"
  },
  {
    "path": "test/cmdlineTests/via_ssa_cfg_ethdebug/args",
    "content": "--experimental --via-ssa-cfg --ethdebug\n"
  },
  {
    "path": "test/cmdlineTests/via_ssa_cfg_ethdebug/err",
    "content": "Error: ethdebug is not yet supported with --via-ssa-cfg.\n"
  },
  {
    "path": "test/cmdlineTests/via_ssa_cfg_ethdebug/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/via_ssa_cfg_ethdebug/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {}\n"
  },
  {
    "path": "test/cmdlineTests/via_ssa_cfg_without_experimental/args",
    "content": "--via-ssa-cfg\n"
  },
  {
    "path": "test/cmdlineTests/via_ssa_cfg_without_experimental/err",
    "content": "Error: The following options are only available in experimental mode: --via-ssa-cfg. To enable experimental mode, use the --experimental flag.\n"
  },
  {
    "path": "test/cmdlineTests/via_ssa_cfg_without_experimental/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/via_ssa_cfg_without_experimental/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C {\n\tfunction f() public {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/viair_abicoder_v1/args",
    "content": "--ir --error-codes\n"
  },
  {
    "path": "test/cmdlineTests/viair_abicoder_v1/err",
    "content": "Warning (9511): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n --> input.sol:3:1:\n  |\n3 | pragma abicoder v1;\n  | ^^^^^^^^^^^^^^^^^^^\n\nWarning (2066): Contract requests the ABI coder v1, which is incompatible with the IR. Using ABI coder v2 instead.\n --> input.sol:4:1:\n  |\n4 | contract test {\n  | ^ (Relevant source part starts here and spans across multiple lines).\n"
  },
  {
    "path": "test/cmdlineTests/viair_abicoder_v1/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma abicoder v1;\ncontract test {\n    function f() public pure returns (bool) {\n        return true;\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/viair_abicoder_v1/output",
    "content": "IR:\n\n/// @use-src 0:\"input.sol\"\nobject \"test_11\" {\n    code {\n        /// @src 0:79:169  \"contract test {...\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_test_11()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"test_11_deployed\"), datasize(\"test_11_deployed\"))\n\n        return(_1, datasize(\"test_11_deployed\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:79:169  \"contract test {...\"\n        function constructor_test_11() {\n\n            /// @src 0:79:169  \"contract test {...\"\n\n        }\n        /// @src 0:79:169  \"contract test {...\"\n\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"test_11_deployed\" {\n        code {\n            /// @src 0:79:169  \"contract test {...\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_10()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function cleanup_t_bool(value) -> cleaned {\n                cleaned := iszero(iszero(value))\n            }\n\n            function abi_encode_t_bool_to_t_bool_fromStack(value, pos) {\n                mstore(pos, cleanup_t_bool(value))\n            }\n\n            function abi_encode_tuple_t_bool__to_t_bool__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 32)\n\n                abi_encode_t_bool_to_t_bool_fromStack(value0,  add(headStart, 0))\n\n            }\n\n            function external_fun_f_10() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  fun_f_10()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_bool__to_t_bool__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function zero_value_for_split_t_bool() -> ret {\n                ret := 0\n            }\n\n            /// @ast-id 10\n            /// @src 0:99:167  \"function f() public pure returns (bool) {...\"\n            function fun_f_10() -> var__5 {\n                /// @src 0:133:137  \"bool\"\n                let zero_t_bool_1 := zero_value_for_split_t_bool()\n                var__5 := zero_t_bool_1\n\n                /// @src 0:156:160  \"true\"\n                let expr_7 := 0x01\n                /// @src 0:149:160  \"return true\"\n                var__5 := expr_7\n                leave\n\n            }\n            /// @src 0:79:169  \"contract test {...\"\n\n        }\n\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n\n}\n"
  },
  {
    "path": "test/cmdlineTests/viair_msize_without_optimizer/args",
    "content": "--via-ir --ir-optimized --asm --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/viair_msize_without_optimizer/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity *;\n\ncontract C {\n    function f() pure public {\n        assembly (\"memory-safe\") {\n            function f() -> x {\n                x := mload(0)\n            }\n\n            // Presence of msize disables all Yul optimizations, including the minimal steps or\n            // stack optimization that would normally be performed even with the optimizer nominally disabled.\n            // This block should remain untouched when passed through the optimizer.\n            pop(msize())\n\n            let x := 0\n            let y := x\n            mstore(0, f())\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/viair_msize_without_optimizer/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n  mstore(0x40, 0x80)\n  jumpi(tag_4, iszero(callvalue))\n  tag_5\n  tag_2\n  jump\t// in\ntag_5:\ntag_4:\n  tag_6\n  tag_3\n  jump\t// in\ntag_6:\n  tag_7\n  tag_1\n  jump\t// in\ntag_7:\n  dataSize(sub_0)\n  dataOffset(sub_0)\n  dup3\n  codecopy\n  dataSize(sub_0)\n  dup2\n  return\ntag_1:\n  0x00\n  mload(0x40)\n  swap1\n  pop\n  swap1\n  jump\t// out\ntag_2:\n  revert(0x00, 0x00)\ntag_3:\n  jump\t// out\nstop\n\nsub_0: assembly {\n      mstore(0x40, 0x80)\n      jumpi(tag_10, lt(calldatasize, 0x04))\n      tag_11\n      calldataload(0x00)\n      tag_1\n      jump\t// in\n    tag_11:\n      dup1\n      0x26121ff0\n      dup2\n      sub\n      tag_12\n      jumpi\n      tag_14\n      tag_7\n      jump\t// in\n    tag_14:\n    tag_12:\n      pop\n      pop\n    tag_10:\n      tag_15\n      tag_8\n      jump\t// in\n    tag_15:\n      jump(tag_16)\n    tag_1:\n      0x00\n      dup2\n      0xe0\n      shr\n      swap1\n      pop\n      swap2\n      swap1\n      pop\n      jump\t// out\n    tag_2:\n      0x00\n      mload(0x40)\n      swap1\n      pop\n      swap1\n      jump\t// out\n    tag_3:\n      revert(0x00, 0x00)\n    tag_4:\n      revert(0x00, 0x00)\n    tag_5:\n      0x00\n      dup2\n      dup4\n      sub\n      slt\n      iszero\n      tag_22\n      jumpi\n      tag_23\n      tag_4\n      jump\t// in\n    tag_23:\n    tag_22:\n      pop\n      pop\n      jump\t// out\n    tag_6:\n      0x00\n      0x00\n      dup3\n      add\n      swap1\n      pop\n      swap2\n      swap1\n      pop\n      jump\t// out\n    tag_7:\n      jumpi(tag_26, iszero(callvalue))\n      tag_27\n      tag_3\n      jump\t// in\n    tag_27:\n    tag_26:\n      tag_28\n      calldatasize\n      0x04\n      tag_5\n      jump\t// in\n    tag_28:\n      tag_29\n      tag_9\n      jump\t// in\n    tag_29:\n      tag_30\n      tag_2\n      jump\t// in\n    tag_30:\n      tag_31\n      dup2\n      tag_6\n      jump\t// in\n    tag_31:\n      dup2\n      dup2\n      sub\n      dup3\n      return\n    tag_8:\n      revert(0x00, 0x00)\n    tag_9:\n      jump(tag_35)\n    tag_34:\n      0x00\n      mload(0x00)\n      swap1\n      pop\n      swap1\n      jump\t// out\n    tag_35:\n      0x00\n      dup1\n      tag_37\n      tag_34\n      jump\t// in\n    tag_37:\n      0x00\n      mstore\n      pop\n      pop\n      jump\t// out\n    tag_16:\n\n    auxdata: <AUXDATA REMOVED>\n}\n\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_7\" {\n    code {\n        mstore(64, memoryguard(128))\n        if callvalue()\n        {\n            revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        }\n        constructor_C_7()\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\"C_7_deployed\"), datasize(\"C_7_deployed\"))\n        return(_1, datasize(\"C_7_deployed\"))\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n        function constructor_C_7()\n        { }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_7_deployed\" {\n        code {\n            mstore(64, memoryguard(128))\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n                case 0x26121ff0 { external_fun_f_6() }\n                default { }\n            }\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            function shift_right_224_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function abi_decode_tuple_(headStart, dataEnd)\n            {\n                if slt(sub(dataEnd, headStart), 0)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n            }\n            function abi_encode_tuple__to__fromStack(headStart) -> tail\n            { tail := add(headStart, 0) }\n            function external_fun_f_6()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                abi_decode_tuple_(4, calldatasize())\n                fun_f_6()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple__to__fromStack(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function fun_f_6()\n            {\n                {\n                    function usr$f() -> usr$x\n                    { usr$x := mload(0) }\n                    pop(msize())\n                    let usr$x := 0\n                    let usr$y := usr$x\n                    mstore(0, usr$f())\n                }\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/viair_subobject_optimization/args",
    "content": "--experimental-via-ir --optimize --asm"
  },
  {
    "path": "test/cmdlineTests/viair_subobject_optimization/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >0.0.0;\n\ncontract C {\n  constructor(uint x) {\n    // In earlier versions of the compiler, the resulting assembly pushed the constant\n    // 0xFFFFFFFFFFFFFFFF42 directly in the subassembly of D, while it was optimized to\n    // ``sub(shl(0x48, 0x01), 0xbe)`` when C was compiled in isolation.\n    // Now the assembly is expected to contain two instances of ``sub(shl(0x48, 0x01), 0xbe)``,\n    // one in the creation code of ``C`` directly, one in a subassembly of ``D``.\n    // The constant 0xFFFFFFFFFFFFFFFF42 should not occur in the assembly output at all.\n    if (x == 0xFFFFFFFFFFFFFFFF42)\n      revert();\n  }\n}\ncontract D {\n  function f() public pure returns (bytes memory) {\n    return type(C).creationCode;\n  }\n}\n"
  },
  {
    "path": "test/cmdlineTests/viair_subobject_optimization/output",
    "content": "\n======= input.sol:C =======\nEVM assembly:\n    /* \"input.sol\":61:668  contract C {... */\n  0x80\n  jumpi(tag_7, callvalue)\n  0x1f\n  bytecodeSize\n  codesize\n  dup2\n  swap1\n  sub\n  swap2\n  dup3\n  add\n  not(0x1f)\n  and\n  dup4\n  add\n  swap2\n  sub(shl(0x40, 0x01), 0x01)\n  dup4\n  gt\n  dup5\n  dup5\n  lt\n  or\n  tag_3\n  jumpi\n  dup1\n  dup5\n  swap3\n  0x20\n  swap5\n  0x40\n  mstore\n  dup4\n  codecopy\n  dup2\n  add\n  sub\n  slt\n  tag_7\n  jumpi\n  mload\n  sub(shl(0x48, 0x01), 0xbe)\n    /* \"input.sol\":620:645  x == 0xFFFFFFFFFFFFFFFF42 */\n  eq\n    /* \"input.sol\":616:661  if (x == 0xFFFFFFFFFFFFFFFF42)... */\n  tag_7\n  jumpi\n    /* \"input.sol\":61:668  contract C {... */\n  mload(0x40)\n  dataSize(sub_0)\n  swap1\n  dup2\n  dataOffset(sub_0)\n  dup3\n  codecopy\n  return\n    /* \"input.sol\":616:661  if (x == 0xFFFFFFFFFFFFFFFF42)... */\ntag_7:\n  0x00\n    /* \"input.sol\":653:661  revert() */\n  dup1\n  revert\n    /* \"input.sol\":61:668  contract C {... */\ntag_3:\n  mstore(0x00, shl(0xe0, 0x4e487b71))\n  mstore(0x04, 0x41)\n  revert(0x00, 0x24)\nstop\n\nsub_0: assembly {\n        /* \"input.sol\":61:668  contract C {... */\n      0x00\n      dup1\n      revert\n\n    auxdata: <AUXDATA REMOVED>\n}\n\n\n======= input.sol:D =======\nEVM assembly:\n    /* \"input.sol\":669:772  contract D {... */\n  0x80\n  dup1\n  0x40\n  mstore\n  jumpi(tag_1, callvalue)\n  dataSize(sub_0)\n  swap1\n  dup2\n  dataOffset(sub_0)\n  dup3\n  codecopy\n  return\ntag_1:\n  0x00\n  dup1\n  revert\nstop\n\nsub_0: assembly {\n        /* \"input.sol\":669:772  contract D {... */\n      0x80\n      jumpi(tag_1, iszero(lt(calldatasize, 0x04)))\n      0x00\n      dup1\n      revert\n    tag_1:\n      jumpi(tag_3, eq(0x26121ff0, shr(0xe0, calldataload(0x00))))\n      0x00\n      dup1\n      revert\n    tag_3:\n      jumpi(tag_7, callvalue)\n      jumpi(tag_7, slt(add(not(0x03), calldatasize), 0x00))\n        /* \"input.sol\":745:765  type(C).creationCode */\n      dataSize(sub_0)\n      swap1\n        /* \"input.sol\":669:772  contract D {... */\n      0x3f\n      dup3\n      add\n      not(0x1f)\n      and\n      dup2\n      add\n      swap1\n      0xffffffffffffffff\n      dup3\n      gt\n      dup2\n      dup4\n      lt\n      or\n      tag_9\n      jumpi\n      0x40\n      swap2\n      dup3\n      mstore\n        /* \"input.sol\":745:765  type(C).creationCode */\n      dup3\n      dup2\n      mstore\n      0x20\n      dup2\n      add\n      swap3\n      dataOffset(sub_0)\n      dup5\n      codecopy\n        /* \"input.sol\":669:772  contract D {... */\n      dup2\n      mload\n      swap3\n      dup4\n      swap2\n        /* \"input.sol\":745:765  type(C).creationCode */\n      0x20\n        /* \"input.sol\":669:772  contract D {... */\n      dup4\n      mstore\n      mload\n      dup1\n      swap2\n      dup2\n        /* \"input.sol\":745:765  type(C).creationCode */\n      0x20\n        /* \"input.sol\":669:772  contract D {... */\n      dup6\n      add\n      mstore\n      dup5\n      dup5\n      add\n      mcopy\n      0x00\n      dup3\n      dup3\n      add\n      dup5\n      add\n      mstore\n      0x1f\n      add\n      not(0x1f)\n      and\n      dup2\n      add\n      sub\n      add\n      swap1\n      return\n    tag_9:\n      mstore(0x00, shl(0xe0, 0x4e487b71))\n      mstore(0x04, 0x41)\n      revert(0x00, 0x24)\n    tag_7:\n      0x00\n      dup1\n      revert\n    stop\n\n    sub_0: assembly {\n            /* \"input.sol\":61:668  contract C {... */\n          0x80\n          jumpi(tag_7, callvalue)\n          0x1f\n          bytecodeSize\n          codesize\n          dup2\n          swap1\n          sub\n          swap2\n          dup3\n          add\n          not(0x1f)\n          and\n          dup4\n          add\n          swap2\n          sub(shl(0x40, 0x01), 0x01)\n          dup4\n          gt\n          dup5\n          dup5\n          lt\n          or\n          tag_3\n          jumpi\n          dup1\n          dup5\n          swap3\n          0x20\n          swap5\n          0x40\n          mstore\n          dup4\n          codecopy\n          dup2\n          add\n          sub\n          slt\n          tag_7\n          jumpi\n          mload\n          sub(shl(0x48, 0x01), 0xbe)\n            /* \"input.sol\":620:645  x == 0xFFFFFFFFFFFFFFFF42 */\n          eq\n            /* \"input.sol\":616:661  if (x == 0xFFFFFFFFFFFFFFFF42)... */\n          tag_7\n          jumpi\n            /* \"input.sol\":61:668  contract C {... */\n          mload(0x40)\n          dataSize(sub_0)\n          swap1\n          dup2\n          dataOffset(sub_0)\n          dup3\n          codecopy\n          return\n            /* \"input.sol\":616:661  if (x == 0xFFFFFFFFFFFFFFFF42)... */\n        tag_7:\n          0x00\n            /* \"input.sol\":653:661  revert() */\n          dup1\n          revert\n            /* \"input.sol\":61:668  contract C {... */\n        tag_3:\n          mstore(0x00, shl(0xe0, 0x4e487b71))\n          mstore(0x04, 0x41)\n          revert(0x00, 0x24)\n        stop\n\n        sub_0: assembly {\n                /* \"input.sol\":61:668  contract C {... */\n              0x00\n              dup1\n              revert\n\n            auxdata: <AUXDATA REMOVED>\n        }\n    }\n\n    auxdata: <AUXDATA REMOVED>\n}\n"
  },
  {
    "path": "test/cmdlineTests/viair_subobjects/args",
    "content": "--ir-optimized --via-ir --optimize --bin --bin-runtime"
  },
  {
    "path": "test/cmdlineTests/viair_subobjects/err",
    "content": "Warning: Unused local variable.\n --> input.sol:8:9:\n  |\n8 |         C c = new C();\n  |         ^^^\n"
  },
  {
    "path": "test/cmdlineTests/viair_subobjects/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.6.0;\npragma abicoder v2;\n\ncontract C {}\ncontract D {\n    function f() public {\n        C c = new C();\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/viair_subobjects/output",
    "content": "\n======= input.sol:C =======\nBinary:\n<BYTECODE REMOVED>\nBinary of the runtime part:\n<BYTECODE REMOVED>\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_3\" {\n    code {\n        {\n            /// @src 0:82:95  \"contract C {}\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_3_deployed\")\n            codecopy(_1, dataoffset(\"C_3_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_3_deployed\" {\n        code {\n            {\n                /// @src 0:82:95  \"contract C {}\"\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n\n\n======= input.sol:D =======\nBinary:\n<BYTECODE REMOVED>\nBinary of the runtime part:\n<BYTECODE REMOVED>\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"D_16\" {\n    code {\n        {\n            /// @src 0:96:165  \"contract D {...\"\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"D_16_deployed\")\n            codecopy(_1, dataoffset(\"D_16_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"D_16_deployed\" {\n        code {\n            {\n                /// @src 0:96:165  \"contract D {...\"\n                let _1 := memoryguard(0x80)\n                mstore(64, _1)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        /// @src 0:149:156  \"new C()\"\n                        let _2 := datasize(\"C_3\")\n                        let _3 := add(_1, _2)\n                        if or(gt(_3, 0xffffffffffffffff), lt(_3, _1))\n                        {\n                            /// @src 0:96:165  \"contract D {...\"\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 0x24)\n                        }\n                        /// @src 0:149:156  \"new C()\"\n                        datacopy(_1, dataoffset(\"C_3\"), _2)\n                        if iszero(create(/** @src 0:96:165  \"contract D {...\" */ 0, /** @src 0:149:156  \"new C()\" */ _1, sub(_3, _1)))\n                        {\n                            /// @src 0:96:165  \"contract D {...\"\n                            let pos := mload(64)\n                            returndatacopy(pos, 0, returndatasize())\n                            revert(pos, returndatasize())\n                        }\n                        return(0, 0)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        /// @use-src 0:\"input.sol\"\n        object \"C_3\" {\n            code {\n                {\n                    /// @src 0:82:95  \"contract C {}\"\n                    let _1 := memoryguard(0x80)\n                    mstore(64, _1)\n                    if callvalue() { revert(0, 0) }\n                    let _2 := datasize(\"C_3_deployed\")\n                    codecopy(_1, dataoffset(\"C_3_deployed\"), _2)\n                    return(_1, _2)\n                }\n            }\n            /// @use-src 0:\"input.sol\"\n            object \"C_3_deployed\" {\n                code {\n                    {\n                        /// @src 0:82:95  \"contract C {}\"\n                        revert(0, 0)\n                    }\n                }\n                data \".metadata\" hex\"<BYTECODE REMOVED>\"\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_cfg_json_export/args",
    "content": "--experimental --via-ir --optimize --yul-cfg-json --pretty-json --json-indent 4\n"
  },
  {
    "path": "test/cmdlineTests/yul_cfg_json_export/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ninterface I {\n    function f() external pure returns (uint);\n}\n\ncontract C is I {\n    function f() public pure override returns (uint) {\n        return 42;\n    }\n}\n\ncontract D {\n    function f() public returns (uint) {\n        C c = new C();\n        return c.f();\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_cfg_json_export/output",
    "content": "\n======= input.sol:C =======\nYul Control Flow Graph:\n{\n    \"C_19\": {\n        \"blocks\": [\n            {\n                \"exit\": {\n                    \"cond\": \"v1\",\n                    \"targets\": [\n                        \"Block2\",\n                        \"Block1\"\n                    ],\n                    \"type\": \"ConditionalJump\"\n                },\n                \"id\": \"Block0\",\n                \"instructions\": [\n                    {\n                        \"in\": [],\n                        \"literalArgs\": [\n                            \"0x80\"\n                        ],\n                        \"op\": \"memoryguard\",\n                        \"out\": [\n                            \"v0\"\n                        ]\n                    },\n                    {\n                        \"in\": [\n                            \"v0\",\n                            \"0x40\"\n                        ],\n                        \"op\": \"mstore\",\n                        \"out\": []\n                    },\n                    {\n                        \"in\": [],\n                        \"op\": \"callvalue\",\n                        \"out\": [\n                            \"v1\"\n                        ]\n                    }\n                ],\n                \"liveness\": {\n                    \"in\": [],\n                    \"out\": [\n                        \"v0\"\n                    ]\n                },\n                \"type\": \"BuiltinCall\"\n            },\n            {\n                \"exit\": {\n                    \"type\": \"Terminated\"\n                },\n                \"id\": \"Block2\",\n                \"instructions\": [\n                    {\n                        \"in\": [],\n                        \"literalArgs\": [\n                            \"C_19_deployed\"\n                        ],\n                        \"op\": \"datasize\",\n                        \"out\": [\n                            \"v2\"\n                        ]\n                    },\n                    {\n                        \"in\": [],\n                        \"literalArgs\": [\n                            \"C_19_deployed\"\n                        ],\n                        \"op\": \"dataoffset\",\n                        \"out\": [\n                            \"v3\"\n                        ]\n                    },\n                    {\n                        \"in\": [\n                            \"v2\",\n                            \"v3\",\n                            \"v0\"\n                        ],\n                        \"op\": \"codecopy\",\n                        \"out\": []\n                    },\n                    {\n                        \"in\": [\n                            \"v2\",\n                            \"v0\"\n                        ],\n                        \"op\": \"return\",\n                        \"out\": []\n                    }\n                ],\n                \"liveness\": {\n                    \"in\": [\n                        \"v0\"\n                    ],\n                    \"out\": []\n                },\n                \"type\": \"BuiltinCall\"\n            },\n            {\n                \"exit\": {\n                    \"type\": \"Terminated\"\n                },\n                \"id\": \"Block1\",\n                \"instructions\": [\n                    {\n                        \"in\": [\n                            \"0x00\",\n                            \"0x00\"\n                        ],\n                        \"op\": \"revert\",\n                        \"out\": []\n                    }\n                ],\n                \"liveness\": {\n                    \"in\": [],\n                    \"out\": []\n                },\n                \"type\": \"BuiltinCall\"\n            }\n        ],\n        \"functions\": {},\n        \"subObjects\": {\n            \"C_19_deployed\": {\n                \"blocks\": [\n                    {\n                        \"exit\": {\n                            \"cond\": \"v3\",\n                            \"targets\": [\n                                \"Block2\",\n                                \"Block1\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block0\",\n                        \"instructions\": [\n                            {\n                                \"in\": [],\n                                \"literalArgs\": [\n                                    \"0x80\"\n                                ],\n                                \"op\": \"memoryguard\",\n                                \"out\": [\n                                    \"v0\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v0\",\n                                    \"0x40\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"calldatasize\",\n                                \"out\": [\n                                    \"v1\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x04\",\n                                    \"v1\"\n                                ],\n                                \"op\": \"lt\",\n                                \"out\": [\n                                    \"v2\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v2\"\n                                ],\n                                \"op\": \"iszero\",\n                                \"out\": [\n                                    \"v3\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block2\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v6\",\n                            \"targets\": [\n                                \"Block4\",\n                                \"Block3\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block1\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\"\n                                ],\n                                \"op\": \"calldataload\",\n                                \"out\": [\n                                    \"v4\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v4\",\n                                    \"0xe0\"\n                                ],\n                                \"op\": \"shr\",\n                                \"out\": [\n                                    \"v5\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v5\",\n                                    \"0x26121ff0\"\n                                ],\n                                \"op\": \"eq\",\n                                \"out\": [\n                                    \"v6\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"targets\": [\n                                \"Block2\"\n                            ],\n                            \"type\": \"Jump\"\n                        },\n                        \"id\": \"Block4\",\n                        \"instructions\": [],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        }\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v7\",\n                            \"targets\": [\n                                \"Block6\",\n                                \"Block5\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block3\",\n                        \"instructions\": [\n                            {\n                                \"in\": [],\n                                \"op\": \"callvalue\",\n                                \"out\": [\n                                    \"v7\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v11\",\n                            \"targets\": [\n                                \"Block9\",\n                                \"Block8\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block6\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x03\"\n                                ],\n                                \"op\": \"not\",\n                                \"out\": [\n                                    \"v8\"\n                                ]\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"calldatasize\",\n                                \"out\": [\n                                    \"v9\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v8\",\n                                    \"v9\"\n                                ],\n                                \"op\": \"add\",\n                                \"out\": [\n                                    \"v10\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"v10\"\n                                ],\n                                \"op\": \"slt\",\n                                \"out\": [\n                                    \"v11\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block5\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block9\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x2a\",\n                                    \"v0\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [\n                                    \"0x20\",\n                                    \"v0\"\n                                ],\n                                \"op\": \"return\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block8\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    }\n                ],\n                \"functions\": {},\n                \"subObjects\": {}\n            },\n            \"type\": \"subObject\"\n        }\n    },\n    \"type\": \"Object\"\n}\n\n======= input.sol:D =======\nYul Control Flow Graph:\n{\n    \"D_38\": {\n        \"blocks\": [\n            {\n                \"exit\": {\n                    \"cond\": \"v1\",\n                    \"targets\": [\n                        \"Block2\",\n                        \"Block1\"\n                    ],\n                    \"type\": \"ConditionalJump\"\n                },\n                \"id\": \"Block0\",\n                \"instructions\": [\n                    {\n                        \"in\": [],\n                        \"literalArgs\": [\n                            \"0x80\"\n                        ],\n                        \"op\": \"memoryguard\",\n                        \"out\": [\n                            \"v0\"\n                        ]\n                    },\n                    {\n                        \"in\": [\n                            \"v0\",\n                            \"0x40\"\n                        ],\n                        \"op\": \"mstore\",\n                        \"out\": []\n                    },\n                    {\n                        \"in\": [],\n                        \"op\": \"callvalue\",\n                        \"out\": [\n                            \"v1\"\n                        ]\n                    }\n                ],\n                \"liveness\": {\n                    \"in\": [],\n                    \"out\": [\n                        \"v0\"\n                    ]\n                },\n                \"type\": \"BuiltinCall\"\n            },\n            {\n                \"exit\": {\n                    \"type\": \"Terminated\"\n                },\n                \"id\": \"Block2\",\n                \"instructions\": [\n                    {\n                        \"in\": [],\n                        \"literalArgs\": [\n                            \"D_38_deployed\"\n                        ],\n                        \"op\": \"datasize\",\n                        \"out\": [\n                            \"v2\"\n                        ]\n                    },\n                    {\n                        \"in\": [],\n                        \"literalArgs\": [\n                            \"D_38_deployed\"\n                        ],\n                        \"op\": \"dataoffset\",\n                        \"out\": [\n                            \"v3\"\n                        ]\n                    },\n                    {\n                        \"in\": [\n                            \"v2\",\n                            \"v3\",\n                            \"v0\"\n                        ],\n                        \"op\": \"codecopy\",\n                        \"out\": []\n                    },\n                    {\n                        \"in\": [\n                            \"v2\",\n                            \"v0\"\n                        ],\n                        \"op\": \"return\",\n                        \"out\": []\n                    }\n                ],\n                \"liveness\": {\n                    \"in\": [\n                        \"v0\"\n                    ],\n                    \"out\": []\n                },\n                \"type\": \"BuiltinCall\"\n            },\n            {\n                \"exit\": {\n                    \"type\": \"Terminated\"\n                },\n                \"id\": \"Block1\",\n                \"instructions\": [\n                    {\n                        \"in\": [\n                            \"0x00\",\n                            \"0x00\"\n                        ],\n                        \"op\": \"revert\",\n                        \"out\": []\n                    }\n                ],\n                \"liveness\": {\n                    \"in\": [],\n                    \"out\": []\n                },\n                \"type\": \"BuiltinCall\"\n            }\n        ],\n        \"functions\": {},\n        \"subObjects\": {\n            \"D_38_deployed\": {\n                \"blocks\": [\n                    {\n                        \"exit\": {\n                            \"cond\": \"v3\",\n                            \"targets\": [\n                                \"Block2\",\n                                \"Block1\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block0\",\n                        \"instructions\": [\n                            {\n                                \"in\": [],\n                                \"literalArgs\": [\n                                    \"0x80\"\n                                ],\n                                \"op\": \"memoryguard\",\n                                \"out\": [\n                                    \"v0\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v0\",\n                                    \"0x40\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"calldatasize\",\n                                \"out\": [\n                                    \"v1\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x04\",\n                                    \"v1\"\n                                ],\n                                \"op\": \"lt\",\n                                \"out\": [\n                                    \"v2\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v2\"\n                                ],\n                                \"op\": \"iszero\",\n                                \"out\": [\n                                    \"v3\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block2\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v6\",\n                            \"targets\": [\n                                \"Block4\",\n                                \"Block3\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block1\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\"\n                                ],\n                                \"op\": \"calldataload\",\n                                \"out\": [\n                                    \"v4\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v4\",\n                                    \"0xe0\"\n                                ],\n                                \"op\": \"shr\",\n                                \"out\": [\n                                    \"v5\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v5\",\n                                    \"0x26121ff0\"\n                                ],\n                                \"op\": \"eq\",\n                                \"out\": [\n                                    \"v6\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"targets\": [\n                                \"Block2\"\n                            ],\n                            \"type\": \"Jump\"\n                        },\n                        \"id\": \"Block4\",\n                        \"instructions\": [],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        }\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v7\",\n                            \"targets\": [\n                                \"Block6\",\n                                \"Block5\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block3\",\n                        \"instructions\": [\n                            {\n                                \"in\": [],\n                                \"op\": \"callvalue\",\n                                \"out\": [\n                                    \"v7\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v11\",\n                            \"targets\": [\n                                \"Block9\",\n                                \"Block8\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block6\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x03\"\n                                ],\n                                \"op\": \"not\",\n                                \"out\": [\n                                    \"v8\"\n                                ]\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"calldatasize\",\n                                \"out\": [\n                                    \"v9\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v8\",\n                                    \"v9\"\n                                ],\n                                \"op\": \"add\",\n                                \"out\": [\n                                    \"v10\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"v10\"\n                                ],\n                                \"op\": \"slt\",\n                                \"out\": [\n                                    \"v11\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": [\n                                \"v0\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block5\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v16\",\n                            \"targets\": [\n                                \"Block12\",\n                                \"Block11\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block9\",\n                        \"instructions\": [\n                            {\n                                \"in\": [],\n                                \"literalArgs\": [\n                                    \"C_19\"\n                                ],\n                                \"op\": \"datasize\",\n                                \"out\": [\n                                    \"v12\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v12\",\n                                    \"v0\"\n                                ],\n                                \"op\": \"add\",\n                                \"out\": [\n                                    \"v13\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v0\",\n                                    \"v13\"\n                                ],\n                                \"op\": \"lt\",\n                                \"out\": [\n                                    \"v14\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0xffffffffffffffff\",\n                                    \"v13\"\n                                ],\n                                \"op\": \"gt\",\n                                \"out\": [\n                                    \"v15\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v14\",\n                                    \"v15\"\n                                ],\n                                \"op\": \"or\",\n                                \"out\": [\n                                    \"v16\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\"\n                            ],\n                            \"out\": [\n                                \"v0\",\n                                \"v13\",\n                                \"v12\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block8\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v21\",\n                            \"targets\": [\n                                \"Block15\",\n                                \"Block14\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block12\",\n                        \"instructions\": [\n                            {\n                                \"in\": [],\n                                \"literalArgs\": [\n                                    \"C_19\"\n                                ],\n                                \"op\": \"dataoffset\",\n                                \"out\": [\n                                    \"v18\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v12\",\n                                    \"v18\",\n                                    \"v0\"\n                                ],\n                                \"op\": \"datacopy\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [\n                                    \"v0\",\n                                    \"v13\"\n                                ],\n                                \"op\": \"sub\",\n                                \"out\": [\n                                    \"v19\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v19\",\n                                    \"v0\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"create\",\n                                \"out\": [\n                                    \"v20\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v20\"\n                                ],\n                                \"op\": \"iszero\",\n                                \"out\": [\n                                    \"v21\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v0\",\n                                \"v13\",\n                                \"v12\"\n                            ],\n                            \"out\": [\n                                \"v20\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block11\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x4e487b71\",\n                                    \"0xe0\"\n                                ],\n                                \"op\": \"shl\",\n                                \"out\": [\n                                    \"v17\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v17\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [\n                                    \"0x41\",\n                                    \"0x04\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [\n                                    \"0x24\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v32\",\n                            \"targets\": [\n                                \"Block18\",\n                                \"Block17\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block15\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x40\"\n                                ],\n                                \"op\": \"mload\",\n                                \"out\": [\n                                    \"v25\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x026121ff\",\n                                    \"0xe4\"\n                                ],\n                                \"op\": \"shl\",\n                                \"out\": [\n                                    \"v26\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v26\",\n                                    \"v25\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [\n                                    \"0x01\",\n                                    \"0xa0\"\n                                ],\n                                \"op\": \"shl\",\n                                \"out\": [\n                                    \"v27\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x01\",\n                                    \"v27\"\n                                ],\n                                \"op\": \"sub\",\n                                \"out\": [\n                                    \"v28\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v28\",\n                                    \"v20\"\n                                ],\n                                \"op\": \"and\",\n                                \"out\": [\n                                    \"v29\"\n                                ]\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"gas\",\n                                \"out\": [\n                                    \"v30\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x20\",\n                                    \"v25\",\n                                    \"0x04\",\n                                    \"v25\",\n                                    \"v29\",\n                                    \"v30\"\n                                ],\n                                \"op\": \"staticcall\",\n                                \"out\": [\n                                    \"v31\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v31\"\n                                ],\n                                \"op\": \"iszero\",\n                                \"out\": [\n                                    \"v32\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v20\"\n                            ],\n                            \"out\": [\n                                \"v25\",\n                                \"v31\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block14\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x40\"\n                                ],\n                                \"op\": \"mload\",\n                                \"out\": [\n                                    \"v22\"\n                                ]\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"returndatasize\",\n                                \"out\": [\n                                    \"v23\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v23\",\n                                    \"0x00\",\n                                    \"v22\"\n                                ],\n                                \"op\": \"returndatacopy\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"returndatasize\",\n                                \"out\": [\n                                    \"v24\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v24\",\n                                    \"v22\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v31\",\n                            \"targets\": [\n                                \"Block21\",\n                                \"Block20\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block18\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\"\n                                ],\n                                \"op\": \"LiteralAssignment\",\n                                \"out\": [\n                                    \"v36\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v25\",\n                                \"v31\"\n                            ],\n                            \"out\": [\n                                \"v36\",\n                                \"v25\"\n                            ]\n                        }\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block17\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x40\"\n                                ],\n                                \"op\": \"mload\",\n                                \"out\": [\n                                    \"v33\"\n                                ]\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"returndatasize\",\n                                \"out\": [\n                                    \"v34\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v34\",\n                                    \"0x00\",\n                                    \"v33\"\n                                ],\n                                \"op\": \"returndatacopy\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"returndatasize\",\n                                \"out\": [\n                                    \"v35\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v35\",\n                                    \"v33\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"entries\": [\n                            \"Block18\",\n                            \"Block28\"\n                        ],\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block21\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"v36\",\n                                    \"v52\"\n                                ],\n                                \"op\": \"PhiFunction\",\n                                \"out\": [\n                                    \"phi26\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x40\"\n                                ],\n                                \"op\": \"mload\",\n                                \"out\": [\n                                    \"v53\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"phi26\",\n                                    \"v53\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [\n                                    \"0x20\",\n                                    \"v53\"\n                                ],\n                                \"op\": \"return\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"phi26\"\n                            ],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v39\",\n                            \"targets\": [\n                                \"Block23\",\n                                \"Block22\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block20\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x20\"\n                                ],\n                                \"op\": \"LiteralAssignment\",\n                                \"out\": [\n                                    \"v37\"\n                                ]\n                            },\n                            {\n                                \"in\": [],\n                                \"op\": \"returndatasize\",\n                                \"out\": [\n                                    \"v38\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v38\",\n                                    \"0x20\"\n                                ],\n                                \"op\": \"gt\",\n                                \"out\": [\n                                    \"v39\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v25\"\n                            ],\n                            \"out\": [\n                                \"v37\",\n                                \"v25\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"entries\": [\n                            \"Block20\",\n                            \"Block22\"\n                        ],\n                        \"exit\": {\n                            \"cond\": \"v47\",\n                            \"targets\": [\n                                \"Block25\",\n                                \"Block24\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block23\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"v37\",\n                                    \"v40\"\n                                ],\n                                \"op\": \"PhiFunction\",\n                                \"out\": [\n                                    \"phi14\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x1f\"\n                                ],\n                                \"op\": \"not\",\n                                \"out\": [\n                                    \"v41\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x1f\",\n                                    \"phi14\"\n                                ],\n                                \"op\": \"add\",\n                                \"out\": [\n                                    \"v42\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v41\",\n                                    \"v42\"\n                                ],\n                                \"op\": \"and\",\n                                \"out\": [\n                                    \"v43\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v43\",\n                                    \"v25\"\n                                ],\n                                \"op\": \"add\",\n                                \"out\": [\n                                    \"v44\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v25\",\n                                    \"v44\"\n                                ],\n                                \"op\": \"lt\",\n                                \"out\": [\n                                    \"v45\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0xffffffffffffffff\",\n                                    \"v44\"\n                                ],\n                                \"op\": \"gt\",\n                                \"out\": [\n                                    \"v46\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v45\",\n                                    \"v46\"\n                                ],\n                                \"op\": \"or\",\n                                \"out\": [\n                                    \"v47\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v25\",\n                                \"phi14\"\n                            ],\n                            \"out\": [\n                                \"v25\",\n                                \"phi14\",\n                                \"v44\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"targets\": [\n                                \"Block23\"\n                            ],\n                            \"type\": \"Jump\"\n                        },\n                        \"id\": \"Block22\",\n                        \"instructions\": [\n                            {\n                                \"in\": [],\n                                \"op\": \"returndatasize\",\n                                \"out\": [\n                                    \"v40\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v25\"\n                            ],\n                            \"out\": [\n                                \"v40\",\n                                \"v25\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"cond\": \"v51\",\n                            \"targets\": [\n                                \"Block28\",\n                                \"Block27\"\n                            ],\n                            \"type\": \"ConditionalJump\"\n                        },\n                        \"id\": \"Block25\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"v44\",\n                                    \"0x40\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [\n                                    \"phi14\",\n                                    \"v25\"\n                                ],\n                                \"op\": \"add\",\n                                \"out\": [\n                                    \"v49\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v25\",\n                                    \"v49\"\n                                ],\n                                \"op\": \"sub\",\n                                \"out\": [\n                                    \"v50\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"0x20\",\n                                    \"v50\"\n                                ],\n                                \"op\": \"slt\",\n                                \"out\": [\n                                    \"v51\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v25\",\n                                \"phi14\",\n                                \"v44\"\n                            ],\n                            \"out\": [\n                                \"v25\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block24\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x4e487b71\",\n                                    \"0xe0\"\n                                ],\n                                \"op\": \"shl\",\n                                \"out\": [\n                                    \"v48\"\n                                ]\n                            },\n                            {\n                                \"in\": [\n                                    \"v48\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [\n                                    \"0x41\",\n                                    \"0x04\"\n                                ],\n                                \"op\": \"mstore\",\n                                \"out\": []\n                            },\n                            {\n                                \"in\": [\n                                    \"0x24\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"targets\": [\n                                \"Block21\"\n                            ],\n                            \"type\": \"Jump\"\n                        },\n                        \"id\": \"Block28\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"v25\"\n                                ],\n                                \"op\": \"mload\",\n                                \"out\": [\n                                    \"v52\"\n                                ]\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [\n                                \"v25\"\n                            ],\n                            \"out\": [\n                                \"v52\"\n                            ]\n                        },\n                        \"type\": \"BuiltinCall\"\n                    },\n                    {\n                        \"exit\": {\n                            \"type\": \"Terminated\"\n                        },\n                        \"id\": \"Block27\",\n                        \"instructions\": [\n                            {\n                                \"in\": [\n                                    \"0x00\",\n                                    \"0x00\"\n                                ],\n                                \"op\": \"revert\",\n                                \"out\": []\n                            }\n                        ],\n                        \"liveness\": {\n                            \"in\": [],\n                            \"out\": []\n                        },\n                        \"type\": \"BuiltinCall\"\n                    }\n                ],\n                \"functions\": {},\n                \"subObjects\": {\n                    \"C_19\": {\n                        \"blocks\": [\n                            {\n                                \"exit\": {\n                                    \"cond\": \"v1\",\n                                    \"targets\": [\n                                        \"Block2\",\n                                        \"Block1\"\n                                    ],\n                                    \"type\": \"ConditionalJump\"\n                                },\n                                \"id\": \"Block0\",\n                                \"instructions\": [\n                                    {\n                                        \"in\": [],\n                                        \"literalArgs\": [\n                                            \"0x80\"\n                                        ],\n                                        \"op\": \"memoryguard\",\n                                        \"out\": [\n                                            \"v0\"\n                                        ]\n                                    },\n                                    {\n                                        \"in\": [\n                                            \"v0\",\n                                            \"0x40\"\n                                        ],\n                                        \"op\": \"mstore\",\n                                        \"out\": []\n                                    },\n                                    {\n                                        \"in\": [],\n                                        \"op\": \"callvalue\",\n                                        \"out\": [\n                                            \"v1\"\n                                        ]\n                                    }\n                                ],\n                                \"liveness\": {\n                                    \"in\": [],\n                                    \"out\": [\n                                        \"v0\"\n                                    ]\n                                },\n                                \"type\": \"BuiltinCall\"\n                            },\n                            {\n                                \"exit\": {\n                                    \"type\": \"Terminated\"\n                                },\n                                \"id\": \"Block2\",\n                                \"instructions\": [\n                                    {\n                                        \"in\": [],\n                                        \"literalArgs\": [\n                                            \"C_19_deployed\"\n                                        ],\n                                        \"op\": \"datasize\",\n                                        \"out\": [\n                                            \"v2\"\n                                        ]\n                                    },\n                                    {\n                                        \"in\": [],\n                                        \"literalArgs\": [\n                                            \"C_19_deployed\"\n                                        ],\n                                        \"op\": \"dataoffset\",\n                                        \"out\": [\n                                            \"v3\"\n                                        ]\n                                    },\n                                    {\n                                        \"in\": [\n                                            \"v2\",\n                                            \"v3\",\n                                            \"v0\"\n                                        ],\n                                        \"op\": \"codecopy\",\n                                        \"out\": []\n                                    },\n                                    {\n                                        \"in\": [\n                                            \"v2\",\n                                            \"v0\"\n                                        ],\n                                        \"op\": \"return\",\n                                        \"out\": []\n                                    }\n                                ],\n                                \"liveness\": {\n                                    \"in\": [\n                                        \"v0\"\n                                    ],\n                                    \"out\": []\n                                },\n                                \"type\": \"BuiltinCall\"\n                            },\n                            {\n                                \"exit\": {\n                                    \"type\": \"Terminated\"\n                                },\n                                \"id\": \"Block1\",\n                                \"instructions\": [\n                                    {\n                                        \"in\": [\n                                            \"0x00\",\n                                            \"0x00\"\n                                        ],\n                                        \"op\": \"revert\",\n                                        \"out\": []\n                                    }\n                                ],\n                                \"liveness\": {\n                                    \"in\": [],\n                                    \"out\": []\n                                },\n                                \"type\": \"BuiltinCall\"\n                            }\n                        ],\n                        \"functions\": {},\n                        \"subObjects\": {\n                            \"C_19_deployed\": {\n                                \"blocks\": [\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v3\",\n                                            \"targets\": [\n                                                \"Block2\",\n                                                \"Block1\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block0\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [],\n                                                \"literalArgs\": [\n                                                    \"0x80\"\n                                                ],\n                                                \"op\": \"memoryguard\",\n                                                \"out\": [\n                                                    \"v0\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v0\",\n                                                    \"0x40\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"calldatasize\",\n                                                \"out\": [\n                                                    \"v1\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x04\",\n                                                    \"v1\"\n                                                ],\n                                                \"op\": \"lt\",\n                                                \"out\": [\n                                                    \"v2\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v2\"\n                                                ],\n                                                \"op\": \"iszero\",\n                                                \"out\": [\n                                                    \"v3\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block2\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v6\",\n                                            \"targets\": [\n                                                \"Block4\",\n                                                \"Block3\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block1\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"calldataload\",\n                                                \"out\": [\n                                                    \"v4\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v4\",\n                                                    \"0xe0\"\n                                                ],\n                                                \"op\": \"shr\",\n                                                \"out\": [\n                                                    \"v5\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v5\",\n                                                    \"0x26121ff0\"\n                                                ],\n                                                \"op\": \"eq\",\n                                                \"out\": [\n                                                    \"v6\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"targets\": [\n                                                \"Block2\"\n                                            ],\n                                            \"type\": \"Jump\"\n                                        },\n                                        \"id\": \"Block4\",\n                                        \"instructions\": [],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        }\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v7\",\n                                            \"targets\": [\n                                                \"Block6\",\n                                                \"Block5\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block3\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"callvalue\",\n                                                \"out\": [\n                                                    \"v7\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"cond\": \"v11\",\n                                            \"targets\": [\n                                                \"Block9\",\n                                                \"Block8\"\n                                            ],\n                                            \"type\": \"ConditionalJump\"\n                                        },\n                                        \"id\": \"Block6\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x03\"\n                                                ],\n                                                \"op\": \"not\",\n                                                \"out\": [\n                                                    \"v8\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [],\n                                                \"op\": \"calldatasize\",\n                                                \"out\": [\n                                                    \"v9\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"v8\",\n                                                    \"v9\"\n                                                ],\n                                                \"op\": \"add\",\n                                                \"out\": [\n                                                    \"v10\"\n                                                ]\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"v10\"\n                                                ],\n                                                \"op\": \"slt\",\n                                                \"out\": [\n                                                    \"v11\"\n                                                ]\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": [\n                                                \"v0\"\n                                            ]\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block5\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block9\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x2a\",\n                                                    \"v0\"\n                                                ],\n                                                \"op\": \"mstore\",\n                                                \"out\": []\n                                            },\n                                            {\n                                                \"in\": [\n                                                    \"0x20\",\n                                                    \"v0\"\n                                                ],\n                                                \"op\": \"return\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [\n                                                \"v0\"\n                                            ],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    },\n                                    {\n                                        \"exit\": {\n                                            \"type\": \"Terminated\"\n                                        },\n                                        \"id\": \"Block8\",\n                                        \"instructions\": [\n                                            {\n                                                \"in\": [\n                                                    \"0x00\",\n                                                    \"0x00\"\n                                                ],\n                                                \"op\": \"revert\",\n                                                \"out\": []\n                                            }\n                                        ],\n                                        \"liveness\": {\n                                            \"in\": [],\n                                            \"out\": []\n                                        },\n                                        \"type\": \"BuiltinCall\"\n                                    }\n                                ],\n                                \"functions\": {},\n                                \"subObjects\": {}\n                            },\n                            \"type\": \"subObject\"\n                        }\n                    },\n                    \"type\": \"subObject\"\n                }\n            },\n            \"type\": \"subObject\"\n        }\n    },\n    \"type\": \"Object\"\n}\n\n======= input.sol:I =======\nYul Control Flow Graph:\nnull\n"
  },
  {
    "path": "test/cmdlineTests/yul_function_name_clashes/args",
    "content": "--strict-assembly --debug-info none"
  },
  {
    "path": "test/cmdlineTests/yul_function_name_clashes/input.yul",
    "content": "object \"object\" {\n    code {\n        let a\n        let b\n        {\n            function z() -> y\n            { y := calldataload(0) }\n            a := z()\n        }\n        {\n            function z() -> y\n            { y := calldataload(0x20) }\n            b := z()\n        }\n        sstore(a, b)\n    }\n}"
  },
  {
    "path": "test/cmdlineTests/yul_function_name_clashes/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code {\n        {\n            let a\n            let b\n            a := z()\n            b := z_1()\n            sstore(a, b)\n        }\n        function z() -> y\n        { y := calldataload(0) }\n        function z_1() -> y\n        { y := calldataload(0x20) }\n    }\n}\n\n\nBinary representation:\n6005600f565b600b6014565b9055005b5f3590565b6020359056\n\nText representation:\n  tag_3\n  tag_1\n  jump\t// in\ntag_3:\n  tag_4\n  tag_2\n  jump\t// in\ntag_4:\n  swap1\n  sstore\n  stop\ntag_1:\n  0x00\n  calldataload\n  swap1\n  jump\t// out\ntag_2:\n  0x20\n  calldataload\n  swap1\n  jump\t// out\n"
  },
  {
    "path": "test/cmdlineTests/yul_function_name_clashes_different_params/args",
    "content": "--strict-assembly\n"
  },
  {
    "path": "test/cmdlineTests/yul_function_name_clashes_different_params/input.yul",
    "content": "object \"object\" {\n    code {\n        let a\n        let b\n        {\n            function z() -> y\n            { y := calldataload(0) }\n            a := z()\n        }\n        {\n            function z(r) -> y\n            { y := calldataload(r) }\n            b := z(0x70)\n        }\n        sstore(a, b)\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_function_name_clashes_different_params/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code {\n        {\n            let a\n            let b\n            a := z()\n            b := z_1(0x70)\n            sstore(a, b)\n        }\n        function z() -> y\n        { y := calldataload(0) }\n        function z_1(r) -> y\n        { y := calldataload(r) }\n    }\n}\n\n\nBinary representation:\n60056011565b600d60706016565b9055005b5f3590565b359056\n\nText representation:\n    /* \"input.yul\":92:95   */\n  tag_3\n  tag_1\n  jump\t// in\ntag_3:\n    /* \"input.yul\":113:122   */\n  tag_4\n    /* \"input.yul\":117:121   */\n  0x70\n    /* \"input.yul\":113:122   */\n  tag_2\n  jump\t// in\ntag_4:\n    /* \"input.yul\":135:147   */\n  swap1\n  sstore\n    /* \"input.yul\":27:284   */\n  stop\n    /* \"input.yul\":166:216   */\ntag_1:\n    /* \"input.yul\":212:213   */\n  0x00\n    /* \"input.yul\":199:214   */\n  calldataload\n    /* \"input.yul\":166:216   */\n  swap1\n  jump\t// out\n    /* \"input.yul\":225:278   */\ntag_2:\n    /* \"input.yul\":261:276   */\n  calldataload\n    /* \"input.yul\":225:278   */\n  swap1\n  jump\t// out\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimize_runs/args",
    "content": "--strict-assembly --yul-dialect evm --optimize --optimize-runs 10000\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimize_runs/input.yul",
    "content": "object \"RunsTest1\" {\n    code {\n        // Deploy the contract\n        datacopy(0, dataoffset(\"Runtime_deployed\"), datasize(\"Runtime_deployed\"))\n        return(0, datasize(\"Runtime_deployed\"))\n    }\n    object \"Runtime_deployed\" {\n        code {\n            let funcSel := shl(224, 0xabc12345)\n            sstore(0, funcSel)\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimize_runs/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"RunsTest1\" {\n    code {\n        {\n            let _1 := datasize(\"Runtime_deployed\")\n            datacopy(0, dataoffset(\"Runtime_deployed\"), _1)\n            return(0, _1)\n        }\n    }\n    object \"Runtime_deployed\" {\n        code {\n            {\n                sstore(0, 0xabc1234500000000000000000000000000000000000000000000000000000000)\n            }\n        }\n    }\n}\n\n\nBinary representation:\n602480600a5f395ff3fe7fabc12345000000000000000000000000000000000000000000000000000000005f5500\n\nText representation:\n    /* \"input.yul\":64:92   */\n  dataSize(sub_0)\n    /* \"input.yul\":117:147   */\n  dup1\n  dataOffset(sub_0)\n    /* \"input.yul\":114:115   */\n  0x00\n    /* \"input.yul\":105:152   */\n  codecopy\n    /* \"input.yul\":172:173   */\n  0x00\n    /* \"input.yul\":165:178   */\n  return\nstop\n\nsub_0: assembly {\n        /* \"input.yul\":282:348   */\n      0xabc1234500000000000000000000000000000000000000000000000000000000\n        /* \"input.yul\":279:280   */\n      0x00\n        /* \"input.yul\":272:349   */\n      sstore\n        /* \"input.yul\":240:373   */\n      stop\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_disabled_sequence_empty/args",
    "content": "--metadata --yul-optimizations :"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_disabled_sequence_empty/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C { }"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_disabled_sequence_empty/output",
    "content": "\n======= input.sol:C =======\nMetadata:\n{\"compiler\":{\"version\": \"<VERSION REMOVED>\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"input.sol\":\"C\"},\"evmVersion\":\"osaka\",\"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}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_literal_comptime_evaluation/args",
    "content": "--ir-optimized --optimize --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_literal_comptime_evaluation/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f() public pure returns (uint) {\n        // IR output should contain the value calculated in compile time:\n        // 0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500\n        return erc7201(\"example.main\");\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_literal_comptime_evaluation/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_12\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_12_deployed\")\n            codecopy(_1, dataoffset(\"C_12_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_12_deployed\" {\n        code {\n            {\n                let _1 := memoryguard(0x80)\n                mstore(64, _1)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        mstore(_1, 0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500)\n                        return(_1, 32)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_param_calldata/args",
    "content": "--ir-optimized --optimize --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_param_calldata/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f(string calldata id) public pure returns (uint) {\n        // Conversion of input from calldata to memory\n        // requires encoding which will appear in the IR output\n        return erc7201(id);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_param_calldata/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_14\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_14_deployed\")\n            codecopy(_1, dataoffset(\"C_14_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_14_deployed\" {\n        code {\n            {\n                let _1 := memoryguard(0x80)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x91e145ef, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 32) { revert(0, 0) }\n                        let offset := calldataload(4)\n                        if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n                        if iszero(slt(add(offset, 35), calldatasize())) { revert(0, 0) }\n                        let length := calldataload(add(4, offset))\n                        let _2 := gt(length, 0xffffffffffffffff)\n                        if _2 { revert(0, 0) }\n                        let _3 := gt(add(add(offset, length), 36), calldatasize())\n                        if _3 { revert(0, 0) }\n                        _2 := 0\n                        let newFreePtr := add(_1, and(add(and(add(length, 0x1f), not(31)), 63), not(31)))\n                        if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _1))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 36)\n                        }\n                        mstore(64, newFreePtr)\n                        mstore(_1, length)\n                        let dst := add(_1, 32)\n                        _3 := 0\n                        calldatacopy(dst, add(offset, 36), length)\n                        mstore(add(add(_1, length), 32), 0)\n                        mstore(0, add(keccak256(dst, mload(_1)), not(0)))\n                        let slot := and(keccak256(0, 32), not(255))\n                        let memPos := mload(64)\n                        mstore(memPos, slot)\n                        return(memPos, 32)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_param_memory/args",
    "content": "--ir-optimized --optimize --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_param_memory/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    function f() public pure returns (uint) {\n        // No encoding necessary, IR output will show value\n        // loaded directly from memory.\n        string memory namespaceID = \"example.main\";\n        return erc7201(namespaceID);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_param_memory/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_16\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := datasize(\"C_16_deployed\")\n            codecopy(_1, dataoffset(\"C_16_deployed\"), _2)\n            return(_1, _2)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_16_deployed\" {\n        code {\n            {\n                let _1 := memoryguard(0x80)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let newFreePtr := add(_1, 64)\n                        if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _1))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 0x24)\n                        }\n                        mstore(64, newFreePtr)\n                        mstore(_1, 12)\n                        let _2 := add(_1, 32)\n                        mstore(_2, \"example.main\")\n                        mstore(0, add(keccak256(_2, 12), not(0)))\n                        let slot := and(keccak256(0, 32), not(255))\n                        let memPos := mload(64)\n                        mstore(memPos, slot)\n                        return(memPos, 32)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_param_storage/args",
    "content": "--ir-optimized --optimize --debug-info none\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_param_storage/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\ncontract C {\n    string namespace = \"example.main\";\n    function f() public view returns (uint) {\n        // Conversion of input from storage to memory\n        // requires encoding which will appear in the IR output\n        return erc7201(namespace);\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_erc7201_param_storage/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_15\" {\n    code {\n        {\n            let _1 := memoryguard(0x80)\n            mstore(64, _1)\n            if callvalue() { revert(0, 0) }\n            let _2 := sload(0x00)\n            let length := 0x00\n            length := shr(1, _2)\n            let outOfPlaceEncoding := and(_2, 1)\n            if iszero(outOfPlaceEncoding) { length := and(length, 0x7f) }\n            if eq(outOfPlaceEncoding, lt(length, 32))\n            {\n                mstore(0x00, shl(224, 0x4e487b71))\n                mstore(4, 0x22)\n                revert(0x00, 0x24)\n            }\n            if gt(length, 31)\n            {\n                if gt(length, 12)\n                {\n                    mstore(0x00, 0x00)\n                    let data := keccak256(0x00, 32)\n                    let oldSlotCount := shr(5, add(length, 31))\n                    let i := 0x00\n                    for { } lt(i, oldSlotCount) { i := add(i, 1) }\n                    { sstore(add(data, i), 0x00) }\n                }\n            }\n            sstore(0x00, add(\"example.main\", 24))\n            let _3 := datasize(\"C_15_deployed\")\n            codecopy(_1, dataoffset(\"C_15_deployed\"), _3)\n            return(_1, _3)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_15_deployed\" {\n        code {\n            {\n                let _1 := memoryguard(0x80)\n                if iszero(lt(calldatasize(), 4))\n                {\n                    if eq(0x26121ff0, shr(224, calldataload(0)))\n                    {\n                        if callvalue() { revert(0, 0) }\n                        if slt(add(calldatasize(), not(3)), 0) { revert(0, 0) }\n                        let ret := 0\n                        let slotValue := sload(0)\n                        let length := 0\n                        length := shr(1, slotValue)\n                        let outOfPlaceEncoding := and(slotValue, 1)\n                        if iszero(outOfPlaceEncoding) { length := and(length, 0x7f) }\n                        if eq(outOfPlaceEncoding, lt(length, 32))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x22)\n                            revert(0, 0x24)\n                        }\n                        mstore(_1, length)\n                        let updated_pos := add(_1, 32)\n                        switch outOfPlaceEncoding\n                        case 0 {\n                            mstore(updated_pos, and(slotValue, not(255)))\n                            ret := add(add(_1, shl(5, iszero(iszero(length)))), 32)\n                        }\n                        case 1 {\n                            mstore(0, 0)\n                            let dataPos := 18569430475105882587588266137607568536673111973893317399460219858819262702947\n                            let i := 0\n                            for { } lt(i, length) { i := add(i, 32) }\n                            {\n                                mstore(add(add(_1, i), 32), sload(dataPos))\n                                dataPos := add(dataPos, 1)\n                            }\n                            ret := add(add(_1, i), 32)\n                        }\n                        let newFreePtr := add(_1, and(add(sub(ret, _1), 31), not(31)))\n                        if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _1))\n                        {\n                            mstore(0, shl(224, 0x4e487b71))\n                            mstore(4, 0x41)\n                            revert(0, 0x24)\n                        }\n                        mstore(64, newFreePtr)\n                        mstore(0, add(keccak256(updated_pos, mload(_1)), not(0)))\n                        mstore(newFreePtr, and(keccak256(0, 32), not(255)))\n                        return(newFreePtr, 32)\n                    }\n                }\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps/args",
    "content": "--ir-optimized --optimize --yul-optimizations dhfoDgvulfnTUtnIf\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma abicoder v2;\n\ncontract C\n{\n\tconstructor() {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_7\" {\n    code {\n        {\n            /// @src 0:80:112  \"contract C...\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\"C_7_deployed\"), datasize(\"C_7_deployed\"))\n            return(_1, datasize(\"C_7_deployed\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_7_deployed\" {\n        code {\n            {\n                /// @src 0:80:112  \"contract C...\"\n                mstore(64, memoryguard(0x80))\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_disabled/args",
    "content": "--ir-optimized --yul-optimizations dhfoDgvulfnTUtnIf\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_disabled/err",
    "content": "Error: --yul-optimizations is invalid with a non-empty sequence if Yul optimizer is disabled. Note that the empty optimizer sequence is properly denoted by \":\".\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_disabled/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_disabled/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C\n{\n\tfunction f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_invalid_abbreviation/args",
    "content": "--ir-optimized --optimize --yul-optimizations abcdefg{hijklmno}pqr[st]uvwxyz\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_invalid_abbreviation/err",
    "content": "Error: Invalid optimizer step sequence in --yul-optimizations: 'b' is not a valid step abbreviation\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_invalid_abbreviation/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_invalid_abbreviation/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C\n{\n\tfunction f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_invalid_substitution_in_expression_simplifier/args",
    "content": " --optimize --yul-optimizations Md[F]vtDI[jxVpjCDpTnvon]TFSI[v]:Etcns --via-ir --bin\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_invalid_substitution_in_expression_simplifier/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\n// reproducing https://github.com/argotorg/solidity/issues/16155\n\npragma solidity ^0.8.19;\n\ncontract PlaceholderContract {\n    function tZhBDeXU4NnUR6(bool assert_in1) internal virtual returns (int128) {\n        return ((\n            (assert_in1 && false)\n                ? (int128(638) - int128(932))\n                : (assert_in1 ? int128(923) : int128(392))\n        ) / ((int128(517) * int128(573)) / (int128(273) % int128(605))));\n    }\n\n    function QtdPeAwoi7LD(\n        bool assert_in1,\n        bool assert_in2\n    ) internal pure returns (int128) {\n        return ((\n            (assert_in2 || assert_in1)\n                ? (int128(478) % int128(983))\n                : (int128(298) + int128(316))\n        ) +\n            (\n                (assert_in1 && assert_in1)\n                    ? (int128(71) / int128(885))\n                    : (-int128(596))\n            ));\n    }\n\n    function fmMG$apfQ14W86hu_3M(\n        bool assert_out2\n    ) internal virtual returns (bool) {\n        return assert_out2;\n    }\n\n    function check_entrypoint(\n        bool /*assert_in0*/,\n        bool assert_in1,\n        bool assert_in2,\n        bool /*assert_in3*/\n    ) public {\n        unchecked {\n            bool assert_out1 = (tZhBDeXU4NnUR6(assert_in1) <\n                QtdPeAwoi7LD(assert_in1, assert_in2));\n            bool assert_out2 = ((((\n                false\n                    ? (int128(638) - int128(932))\n                    : ((((\n                        (!(!assert_in1))\n                            ? int128(923)\n                            : ((int128(392) + (int128(0) & int128(82))) &\n                                ((int128(0) + int128(392)) & int128(392)))\n                    ) + int128(0)) - (int128(77) & int128(0))) /\n                        (int128(1) | int128(0)))\n            ) /\n                ((int128(573) * int128(517)) /\n                    (-(-(-(int128(0) + (-(int128(273) % int128(605))))))))) <\n                ((\n                    (true && (assert_in2 || assert_in1))\n                        ? (((int128(478) % int128(983)) - int128(76)) +\n                            int128(76))\n                        : (int128(298) + int128(316))\n                ) +\n                    (\n                        assert_in1\n                            ? (int128(73) +\n                                ((((int128(71) - int128(94)) + int128(94)) /\n                                    int128(885)) - int128(73)))\n                            : (-int128(596))\n                    ))) ||\n                ((((int128(0) |\n                    (\n                        false\n                            ? (int128(638) - int128(932))\n                            : ((\n                                (!(!(!(!assert_in1))))\n                                    ? int128(923)\n                                    : (int128(392) &\n                                        ((int128(82) & int128(0)) +\n                                            int128(392)))\n                            ) | int128(0))\n                    )) /\n                    ((int128(573) * int128(517)) /\n                        ((-(-(-(int128(0) - (int128(273) % int128(605)))))) +\n                            int128(0)))) | int128(0)) <\n                    ((\n                        (((assert_in2 || assert_in1) && true) && true)\n                            ? (int128(478) % int128(983))\n                            : (int128(298) + int128(316))\n                    ) +\n                        (\n                            ((true && assert_in1) && assert_in1)\n                                ? (((int128(71) - int128(94)) + int128(94)) /\n                                    int128(885))\n                                : (-int128(596))\n                        ))));\n            assert((assert_out1 == fmMG$apfQ14W86hu_3M(assert_out2)));\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_invalid_substitution_in_expression_simplifier/output",
    "content": "\n======= input.sol:PlaceholderContract =======\nBinary:\n<BYTECODE REMOVED>\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_nested_brackets/args",
    "content": "--ir-optimized --optimize --yul-optimizations a[[a][[aa]aa[aa]][]]aaa[aa[aa[aa]]]a[a][a][a]a[a]\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_nested_brackets/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C\n{\n\tfunction f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_nested_brackets/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_6\" {\n    code {\n        {\n            /// @src 0:60:103  \"contract C...\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))\n            return(_1, datasize(\"C_6_deployed\"))\n        }\n        function allocate_unbounded() -> memPtr\n        {\n            let memPtr_1 := mload(64)\n            memPtr := memPtr_1\n        }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_6_deployed\" {\n        code {\n            {\n                /// @src 0:60:103  \"contract C...\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    if eq(0x26121ff0, selector) { external_fun_f() }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            {\n                let newValue_1 := shr(224, value)\n                newValue := newValue_1\n            }\n            function allocate_unbounded() -> memPtr\n            {\n                let memPtr_1 := mload(64)\n                memPtr := memPtr_1\n            }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function abi_decode(headStart, dataEnd)\n            {\n                if slt(sub(dataEnd, headStart), 0)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n            }\n            function abi_encode_tuple(headStart) -> tail\n            {\n                let tail_1 := add(headStart, 0)\n                tail := tail_1\n            }\n            function external_fun_f()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                abi_decode(4, calldatasize())\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple(memPos)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_nesting_too_deep/args",
    "content": "--ir-optimized --optimize --yul-optimizations [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[a]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_nesting_too_deep/err",
    "content": "Error: Invalid optimizer step sequence in --yul-optimizations: Brackets nested too deep\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_nesting_too_deep/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_nesting_too_deep/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C\n{\n\tfunction f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_short_sequence/args",
    "content": "--ir-optimized --optimize --yul-optimizations iDu\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_short_sequence/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma abicoder v2;\n\ncontract C {\n    constructor() payable {\n        assembly (\"memory-safe\") {\n            let a := 0\n            revert(0, a)\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_short_sequence/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_8\" {\n    code {\n        {\n            /// @src 0:80:221  \"contract C {...\"\n            mstore(64, memoryguard(0x80))\n            /// @src 0:129:213  \"assembly (\\\"memory-safe\\\") {...\"\n            revert(0, 0)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_8_deployed\" {\n        code {\n            {\n                /// @src 0:80:221  \"contract C {...\"\n                mstore(64, memoryguard(0x80))\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_unbalanced_closing_bracket/args",
    "content": "--ir-optimized --optimize --yul-optimizations a]a][\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_unbalanced_closing_bracket/err",
    "content": "Error: Invalid optimizer step sequence in --yul-optimizations: Unbalanced brackets\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_unbalanced_closing_bracket/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_unbalanced_closing_bracket/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C\n{\n\tfunction f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_unbalanced_opening_bracket/args",
    "content": "--ir-optimized --optimize --yul-optimizations a[a][\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_unbalanced_opening_bracket/err",
    "content": "Error: Invalid optimizer step sequence in --yul-optimizations: Unbalanced brackets\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_unbalanced_opening_bracket/exit",
    "content": "1\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_unbalanced_opening_bracket/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C\n{\n\tfunction f() public pure {}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_with_empty_cleanup_sequence/args",
    "content": "--ir-optimized --optimize --yul-optimizations iDu:\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_with_empty_cleanup_sequence/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma abicoder v2;\n\ncontract C {\n    constructor() payable {\n        assembly (\"memory-safe\") {\n            let a := 0\n            // Without the cleanup sequence this will not be simplified to ``revert(a, a)``.\n            revert(0, a)\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_with_empty_cleanup_sequence/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_8\" {\n    code {\n        {\n            /// @src 0:80:314  \"contract C {...\"\n            mstore(64, memoryguard(0x80))\n            /// @src 0:129:306  \"assembly (\\\"memory-safe\\\") {...\"\n            let usr$a := 0\n            revert(0, usr$a)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_8_deployed\" {\n        code {\n            {\n                /// @src 0:80:314  \"contract C {...\"\n                mstore(64, memoryguard(0x80))\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_with_empty_optimization_sequence/args",
    "content": "--ir-optimized --optimize --yul-optimizations :iDu\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_with_empty_optimization_sequence/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\npragma abicoder v2;\n\ncontract C {\n    constructor() payable {\n        assembly (\"memory-safe\") {\n            let a := 0\n            // Without the cleanup sequence this will not be simplified to ``revert(a, a)``.\n            revert(0, a)\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_with_empty_optimization_sequence/output",
    "content": "Optimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_8\" {\n    code {\n        {\n            /// @src 0:80:314  \"contract C {...\"\n            mstore(64, memoryguard(0x80))\n            /// @src 0:129:306  \"assembly (\\\"memory-safe\\\") {...\"\n            let usr$a := 0\n            revert(0, usr$a)\n        }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_8_deployed\" {\n        code {\n            {\n                /// @src 0:80:314  \"contract C {...\"\n                mstore(64, memoryguard(0x80))\n                revert(0, 0)\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/args",
    "content": "--ir-optimized --metadata --yul-optimizations :\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/err",
    "content": "Warning: Unused local variable.\n  --> input.sol:13:9:\n   |\n13 |         uint b = a;\n   |         ^^^^^^\n\nWarning: Unused local variable.\n  --> input.sol:14:9:\n   |\n14 |         uint c = a;\n   |         ^^^^^^\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/input.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0;\n\ncontract C\n{\n    constructor() {}\n\n    function foo() public pure returns (bool)\n    {\n        // given the empty optimizer sequence ``:``, ``b`` and ``c`` should not be removed in the\n        // optimized IR as the ``UnusedPruner`` step will not be run.\n        uint a = 100;\n        uint b = a;\n        uint c = a;\n\n        return a == 100;\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_optimizer_steps_without_optimize_empty_sequence/output",
    "content": "\n======= input.sol:C =======\nOptimized IR:\n/// @use-src 0:\"input.sol\"\nobject \"C_28\" {\n    code {\n        {\n            /// @src 0:60:410  \"contract C...\"\n            mstore(64, memoryguard(0x80))\n            if callvalue()\n            {\n                revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            }\n            constructor_C()\n            let _1 := allocate_unbounded()\n            codecopy(_1, dataoffset(\"C_28_deployed\"), datasize(\"C_28_deployed\"))\n            return(_1, datasize(\"C_28_deployed\"))\n        }\n        function allocate_unbounded() -> memPtr\n        { memPtr := mload(64) }\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n        { revert(0, 0) }\n        /// @ast-id 5 @src 0:77:93  \"constructor() {}\"\n        function constructor_C()\n        { }\n    }\n    /// @use-src 0:\"input.sol\"\n    object \"C_28_deployed\" {\n        code {\n            {\n                /// @src 0:60:410  \"contract C...\"\n                mstore(64, memoryguard(0x80))\n                if iszero(lt(calldatasize(), 4))\n                {\n                    let selector := shift_right_unsigned(calldataload(0))\n                    switch selector\n                    case 0xc2985578 { external_fun_foo() }\n                    default { }\n                }\n                revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            }\n            function shift_right_unsigned(value) -> newValue\n            { newValue := shr(224, value) }\n            function allocate_unbounded() -> memPtr\n            { memPtr := mload(64) }\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n            { revert(0, 0) }\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n            { revert(0, 0) }\n            function abi_decode(headStart, dataEnd)\n            {\n                if slt(sub(dataEnd, headStart), 0)\n                {\n                    revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b()\n                }\n            }\n            function cleanup_bool(value) -> cleaned\n            {\n                cleaned := iszero(iszero(value))\n            }\n            function abi_encode_bool_to_bool(value, pos)\n            {\n                mstore(pos, cleanup_bool(value))\n            }\n            function abi_encode_bool(headStart, value0) -> tail\n            {\n                tail := add(headStart, 32)\n                abi_encode_bool_to_bool(value0, add(headStart, 0))\n            }\n            function external_fun_foo()\n            {\n                if callvalue()\n                {\n                    revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb()\n                }\n                abi_decode(4, calldatasize())\n                let ret := fun_foo()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_bool(memPos, ret)\n                return(memPos, sub(memEnd, memPos))\n            }\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n            { revert(0, 0) }\n            function zero_value_for_split_bool() -> ret\n            { ret := 0 }\n            function cleanup_rational_by(value) -> cleaned\n            { cleaned := value }\n            function cleanup_uint256(value) -> cleaned\n            { cleaned := value }\n            function identity(value) -> ret\n            { ret := value }\n            function convert_rational_by_to_uint256(value) -> converted\n            {\n                converted := cleanup_uint256(identity(cleanup_rational_by(value)))\n            }\n            /// @ast-id 27 @src 0:99:408  \"function foo() public pure returns (bool)...\"\n            function fun_foo() -> var\n            {\n                /// @src 0:135:139  \"bool\"\n                let zero_bool := zero_value_for_split_bool()\n                var := zero_bool\n                /// @src 0:332:335  \"100\"\n                let expr := 0x64\n                /// @src 0:323:335  \"uint a = 100\"\n                let var_a := convert_rational_by_to_uint256(expr)\n                /// @src 0:354:355  \"a\"\n                let _1 := var_a\n                let expr_1 := _1\n                /// @src 0:345:355  \"uint b = a\"\n                let var_b := expr_1\n                /// @src 0:374:375  \"a\"\n                let _2 := var_a\n                let expr_2 := _2\n                /// @src 0:365:375  \"uint c = a\"\n                let var_c := expr_2\n                /// @src 0:393:394  \"a\"\n                let _3 := var_a\n                let expr_3 := _3\n                /// @src 0:398:401  \"100\"\n                let expr_4 := 0x64\n                /// @src 0:393:401  \"a == 100\"\n                let expr_5 := eq(cleanup_uint256(expr_3), convert_rational_by_to_uint256(expr_4))\n                /// @src 0:386:401  \"return a == 100\"\n                var := expr_5\n                leave\n            }\n        }\n        data \".metadata\" hex\"<BYTECODE REMOVED>\"\n    }\n}\n\nMetadata:\n{\"compiler\":{\"version\": \"<VERSION REMOVED>\"},\"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\":\"osaka\",\"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}\n"
  },
  {
    "path": "test/cmdlineTests/yul_string_format_ascii/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() external pure returns (string memory) { return \\\"abcabc\\\"; } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"ir\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_string_format_ascii/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"ir\": \"\n/// @use-src 0:\\\"A\\\"\nobject \\\"C_11\\\" {\n    code {\n        /// @src 0:78:164  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_11()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_11_deployed\\\"), datasize(\\\"C_11_deployed\\\"))\n\n        return(_1, datasize(\\\"C_11_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:78:164  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n        function constructor_C_11() {\n\n            /// @src 0:78:164  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n\n        }\n        /// @src 0:78:164  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n\n    }\n    /// @use-src 0:\\\"A\\\"\n    object \\\"C_11_deployed\\\" {\n        code {\n            /// @src 0:78:164  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_10()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function array_length_t_string_memory_ptr(value) -> length {\n\n                length := mload(value)\n\n            }\n\n            function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos {\n                mstore(pos, length)\n                updated_pos := add(pos, 0x20)\n            }\n\n            function copy_memory_to_memory_with_cleanup(src, dst, length) {\n\n                mcopy(dst, src, length)\n                mstore(add(dst, length), 0)\n\n            }\n\n            function round_up_to_mul_of_32(value) -> result {\n                result := and(add(value, 31), not(31))\n            }\n\n            function abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value, pos) -> end {\n                let length := array_length_t_string_memory_ptr(value)\n                pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length)\n                copy_memory_to_memory_with_cleanup(add(value, 0x20), pos, length)\n                end := add(pos, round_up_to_mul_of_32(length))\n            }\n\n            function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 32)\n\n                mstore(add(headStart, 0), sub(tail, headStart))\n                tail := abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value0,  tail)\n\n            }\n\n            function external_fun_f_10() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  fun_f_10()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function zero_value_for_split_t_string_memory_ptr() -> ret {\n                ret := 96\n            }\n\n            function panic_error_0x41() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x41)\n                revert(0, 0x24)\n            }\n\n            function finalize_allocation(memPtr, size) {\n                let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n                // protect against overflow\n                if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n                mstore(64, newFreePtr)\n            }\n\n            function allocate_memory(size) -> memPtr {\n                memPtr := allocate_unbounded()\n                finalize_allocation(memPtr, size)\n            }\n\n            function array_allocation_size_t_string_memory_ptr(length) -> size {\n                // Make sure we can allocate memory without overflow\n                if gt(length, 0xffffffffffffffff) { panic_error_0x41() }\n\n                size := round_up_to_mul_of_32(length)\n\n                // add length slot\n                size := add(size, 0x20)\n\n            }\n\n            function allocate_memory_array_t_string_memory_ptr(length) -> memPtr {\n                let allocSize := array_allocation_size_t_string_memory_ptr(length)\n                memPtr := allocate_memory(allocSize)\n\n                mstore(memPtr, length)\n\n            }\n\n            function store_literal_in_memory_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21(memPtr) {\n\n                mstore(add(memPtr, 0), \\\"abcabc\\\")\n\n            }\n\n            function copy_literal_to_memory_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21() -> memPtr {\n                memPtr := allocate_memory_array_t_string_memory_ptr(6)\n                store_literal_in_memory_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21(add(memPtr, 32))\n            }\n\n            function convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_string_memory_ptr() -> converted {\n                converted := copy_literal_to_memory_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21()\n            }\n\n            /// @ast-id 10\n            /// @src 0:91:162  \\\"function f() external pure returns (string memory) { return \\\\\\\"abcabc\\\\\\\"; }\\\"\n            function fun_f_10() -> var__5_mpos {\n                /// @src 0:127:140  \\\"string memory\\\"\n                let zero_t_string_memory_ptr_1_mpos := zero_value_for_split_t_string_memory_ptr()\n                var__5_mpos := zero_t_string_memory_ptr_1_mpos\n\n                /// @src 0:144:159  \\\"return \\\\\\\"abcabc\\\\\\\"\\\"\n                var__5_mpos := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_string_memory_ptr()\n                leave\n\n            }\n            /// @src 0:78:164  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_string_format_ascii_bytes32/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() external pure returns (bytes32) { return \\\"abcabc\\\"; } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"ir\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_string_format_ascii_bytes32/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"ir\": \"\n/// @use-src 0:\\\"A\\\"\nobject \\\"C_11\\\" {\n    code {\n        /// @src 0:78:158  \\\"contract C { function f() external pure returns (bytes32) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_11()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_11_deployed\\\"), datasize(\\\"C_11_deployed\\\"))\n\n        return(_1, datasize(\\\"C_11_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:78:158  \\\"contract C { function f() external pure returns (bytes32) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n        function constructor_C_11() {\n\n            /// @src 0:78:158  \\\"contract C { function f() external pure returns (bytes32) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n\n        }\n        /// @src 0:78:158  \\\"contract C { function f() external pure returns (bytes32) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n\n    }\n    /// @use-src 0:\\\"A\\\"\n    object \\\"C_11_deployed\\\" {\n        code {\n            /// @src 0:78:158  \\\"contract C { function f() external pure returns (bytes32) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_10()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function cleanup_t_bytes32(value) -> cleaned {\n                cleaned := value\n            }\n\n            function abi_encode_t_bytes32_to_t_bytes32_fromStack(value, pos) {\n                mstore(pos, cleanup_t_bytes32(value))\n            }\n\n            function abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 32)\n\n                abi_encode_t_bytes32_to_t_bytes32_fromStack(value0,  add(headStart, 0))\n\n            }\n\n            function external_fun_f_10() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  fun_f_10()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function zero_value_for_split_t_bytes32() -> ret {\n                ret := 0\n            }\n\n            function convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_bytes32() -> converted {\n                converted := 0x6162636162630000000000000000000000000000000000000000000000000000\n            }\n\n            /// @ast-id 10\n            /// @src 0:91:156  \\\"function f() external pure returns (bytes32) { return \\\\\\\"abcabc\\\\\\\"; }\\\"\n            function fun_f_10() -> var__5 {\n                /// @src 0:127:134  \\\"bytes32\\\"\n                let zero_t_bytes32_1 := zero_value_for_split_t_bytes32()\n                var__5 := zero_t_bytes32_1\n\n                /// @src 0:138:153  \\\"return \\\\\\\"abcabc\\\\\\\"\\\"\n                var__5 := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_bytes32()\n                leave\n\n            }\n            /// @src 0:78:158  \\\"contract C { function f() external pure returns (bytes32) { return \\\\\\\"abcabc\\\\\\\"; } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"ir\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"ir\": \"\n/// @use-src 0:\\\"A\\\"\nobject \\\"C_11\\\" {\n    code {\n        /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_11()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_11_deployed\\\"), datasize(\\\"C_11_deployed\\\"))\n\n        return(_1, datasize(\\\"C_11_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\\\"\n        function constructor_C_11() {\n\n            /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\\\"\n\n        }\n        /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\\\"\n\n    }\n    /// @use-src 0:\\\"A\\\"\n    object \\\"C_11_deployed\\\" {\n        code {\n            /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_10()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function cleanup_t_bytes4(value) -> cleaned {\n                cleaned := and(value, 0xffffffff00000000000000000000000000000000000000000000000000000000)\n            }\n\n            function abi_encode_t_bytes4_to_t_bytes4_fromStack(value, pos) {\n                mstore(pos, cleanup_t_bytes4(value))\n            }\n\n            function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 32)\n\n                abi_encode_t_bytes4_to_t_bytes4_fromStack(value0,  add(headStart, 0))\n\n            }\n\n            function external_fun_f_10() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  fun_f_10()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function zero_value_for_split_t_bytes4() -> ret {\n                ret := 0\n            }\n\n            function cleanup_t_rational_1633837924_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function shift_left_224(value) -> newValue {\n                newValue :=\n\n                shl(224, value)\n\n            }\n\n            function convert_t_rational_1633837924_by_1_to_t_bytes4(value) -> converted {\n                converted := cleanup_t_bytes4(shift_left_224(cleanup_t_rational_1633837924_by_1(value)))\n            }\n\n            /// @ast-id 10\n            /// @src 0:91:157  \\\"function f() external pure returns (bytes4) { return 0x61626364; }\\\"\n            function fun_f_10() -> var__5 {\n                /// @src 0:127:133  \\\"bytes4\\\"\n                let zero_t_bytes4_1 := zero_value_for_split_t_bytes4()\n                var__5 := zero_t_bytes4_1\n\n                /// @src 0:144:154  \\\"0x61626364\\\"\n                let expr_7 := 0x61626364\n                /// @src 0:137:154  \\\"return 0x61626364\\\"\n                var__5 := convert_t_rational_1633837924_by_1_to_t_bytes4(expr_7)\n                leave\n\n            }\n            /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_string_format_ascii_long/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"ir\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_string_format_ascii_long/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"ir\": \"\n/// @use-src 0:\\\"A\\\"\nobject \\\"C_11\\\" {\n    code {\n        /// @src 0:78:243  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\\\\\"; } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_11()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_11_deployed\\\"), datasize(\\\"C_11_deployed\\\"))\n\n        return(_1, datasize(\\\"C_11_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:78:243  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\\\\\"; } }\\\"\n        function constructor_C_11() {\n\n            /// @src 0:78:243  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\\\\\"; } }\\\"\n\n        }\n        /// @src 0:78:243  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\\\\\"; } }\\\"\n\n    }\n    /// @use-src 0:\\\"A\\\"\n    object \\\"C_11_deployed\\\" {\n        code {\n            /// @src 0:78:243  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\\\\\"; } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_10()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function array_length_t_string_memory_ptr(value) -> length {\n\n                length := mload(value)\n\n            }\n\n            function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos {\n                mstore(pos, length)\n                updated_pos := add(pos, 0x20)\n            }\n\n            function copy_memory_to_memory_with_cleanup(src, dst, length) {\n\n                mcopy(dst, src, length)\n                mstore(add(dst, length), 0)\n\n            }\n\n            function round_up_to_mul_of_32(value) -> result {\n                result := and(add(value, 31), not(31))\n            }\n\n            function abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value, pos) -> end {\n                let length := array_length_t_string_memory_ptr(value)\n                pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length)\n                copy_memory_to_memory_with_cleanup(add(value, 0x20), pos, length)\n                end := add(pos, round_up_to_mul_of_32(length))\n            }\n\n            function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 32)\n\n                mstore(add(headStart, 0), sub(tail, headStart))\n                tail := abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value0,  tail)\n\n            }\n\n            function external_fun_f_10() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  fun_f_10()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function zero_value_for_split_t_string_memory_ptr() -> ret {\n                ret := 96\n            }\n\n            function panic_error_0x41() {\n                mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n                mstore(4, 0x41)\n                revert(0, 0x24)\n            }\n\n            function finalize_allocation(memPtr, size) {\n                let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))\n                // protect against overflow\n                if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n                mstore(64, newFreePtr)\n            }\n\n            function allocate_memory(size) -> memPtr {\n                memPtr := allocate_unbounded()\n                finalize_allocation(memPtr, size)\n            }\n\n            function array_allocation_size_t_string_memory_ptr(length) -> size {\n                // Make sure we can allocate memory without overflow\n                if gt(length, 0xffffffffffffffff) { panic_error_0x41() }\n\n                size := round_up_to_mul_of_32(length)\n\n                // add length slot\n                size := add(size, 0x20)\n\n            }\n\n            function allocate_memory_array_t_string_memory_ptr(length) -> memPtr {\n                let allocSize := array_allocation_size_t_string_memory_ptr(length)\n                memPtr := allocate_memory(allocSize)\n\n                mstore(memPtr, length)\n\n            }\n\n            function store_literal_in_memory_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571(memPtr) {\n\n                mstore(add(memPtr, 0), \\\"abcdabcdcafecafeabcdabcdcafecafe\\\")\n\n                mstore(add(memPtr, 32), \\\"ffffzzzzoooo0123456789,.<,>.?:;'\\\")\n\n                mstore(add(memPtr, 64), \\\"[{]}|`~!@#$%^&*()-_=+\\\")\n\n            }\n\n            function copy_literal_to_memory_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571() -> memPtr {\n                memPtr := allocate_memory_array_t_string_memory_ptr(85)\n                store_literal_in_memory_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571(add(memPtr, 32))\n            }\n\n            function convert_t_stringliteral_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571_to_t_string_memory_ptr() -> converted {\n                converted := copy_literal_to_memory_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571()\n            }\n\n            /// @ast-id 10\n            /// @src 0:91:241  \\\"function f() external pure returns (string memory) { return \\\\\\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\\\\\"; }\\\"\n            function fun_f_10() -> var__5_mpos {\n                /// @src 0:127:140  \\\"string memory\\\"\n                let zero_t_string_memory_ptr_1_mpos := zero_value_for_split_t_string_memory_ptr()\n                var__5_mpos := zero_t_string_memory_ptr_1_mpos\n\n                /// @src 0:144:238  \\\"return \\\\\\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\\\\\"\\\"\n                var__5_mpos := convert_t_stringliteral_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571_to_t_string_memory_ptr()\n                leave\n\n            }\n            /// @src 0:78:243  \\\"contract C { function f() external pure returns (string memory) { return \\\\\\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\\\\\"; } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_string_format_hex/input.json",
    "content": "{\n\t\"language\": \"Solidity\",\n\t\"sources\":\n\t{\n\t\t\"A\":\n\t\t{\n\t\t\t\"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\"\n\t\t}\n\t},\n\t\"settings\":\n\t{\n\t\t\"outputSelection\":\n\t\t{\n\t\t\t\"*\": { \"*\": [\"ir\"] }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_string_format_hex/output.json",
    "content": "{\n    \"contracts\": {\n        \"A\": {\n            \"C\": {\n                \"ir\": \"\n/// @use-src 0:\\\"A\\\"\nobject \\\"C_11\\\" {\n    code {\n        /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\\\"\n        mstore(64, memoryguard(128))\n        if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n\n        constructor_C_11()\n\n        let _1 := allocate_unbounded()\n        codecopy(_1, dataoffset(\\\"C_11_deployed\\\"), datasize(\\\"C_11_deployed\\\"))\n\n        return(_1, datasize(\\\"C_11_deployed\\\"))\n\n        function allocate_unbounded() -> memPtr {\n            memPtr := mload(64)\n        }\n\n        function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n            revert(0, 0)\n        }\n\n        /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\\\"\n        function constructor_C_11() {\n\n            /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\\\"\n\n        }\n        /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\\\"\n\n    }\n    /// @use-src 0:\\\"A\\\"\n    object \\\"C_11_deployed\\\" {\n        code {\n            /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\\\"\n            mstore(64, memoryguard(128))\n\n            if iszero(lt(calldatasize(), 4))\n            {\n                let selector := shift_right_224_unsigned(calldataload(0))\n                switch selector\n\n                case 0x26121ff0\n                {\n                    // f()\n\n                    external_fun_f_10()\n                }\n\n                default {}\n            }\n\n            revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()\n\n            function shift_right_224_unsigned(value) -> newValue {\n                newValue :=\n\n                shr(224, value)\n\n            }\n\n            function allocate_unbounded() -> memPtr {\n                memPtr := mload(64)\n            }\n\n            function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {\n                revert(0, 0)\n            }\n\n            function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {\n                revert(0, 0)\n            }\n\n            function abi_decode_tuple_(headStart, dataEnd)   {\n                if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }\n\n            }\n\n            function cleanup_t_bytes4(value) -> cleaned {\n                cleaned := and(value, 0xffffffff00000000000000000000000000000000000000000000000000000000)\n            }\n\n            function abi_encode_t_bytes4_to_t_bytes4_fromStack(value, pos) {\n                mstore(pos, cleanup_t_bytes4(value))\n            }\n\n            function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack(headStart , value0) -> tail {\n                tail := add(headStart, 32)\n\n                abi_encode_t_bytes4_to_t_bytes4_fromStack(value0,  add(headStart, 0))\n\n            }\n\n            function external_fun_f_10() {\n\n                if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }\n                abi_decode_tuple_(4, calldatasize())\n                let ret_0 :=  fun_f_10()\n                let memPos := allocate_unbounded()\n                let memEnd := abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack(memPos , ret_0)\n                return(memPos, sub(memEnd, memPos))\n\n            }\n\n            function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {\n                revert(0, 0)\n            }\n\n            function zero_value_for_split_t_bytes4() -> ret {\n                ret := 0\n            }\n\n            function cleanup_t_rational_2864434397_by_1(value) -> cleaned {\n                cleaned := value\n            }\n\n            function shift_left_224(value) -> newValue {\n                newValue :=\n\n                shl(224, value)\n\n            }\n\n            function convert_t_rational_2864434397_by_1_to_t_bytes4(value) -> converted {\n                converted := cleanup_t_bytes4(shift_left_224(cleanup_t_rational_2864434397_by_1(value)))\n            }\n\n            /// @ast-id 10\n            /// @src 0:91:157  \\\"function f() external pure returns (bytes4) { return 0xaabbccdd; }\\\"\n            function fun_f_10() -> var__5 {\n                /// @src 0:127:133  \\\"bytes4\\\"\n                let zero_t_bytes4_1 := zero_value_for_split_t_bytes4()\n                var__5 := zero_t_bytes4_1\n\n                /// @src 0:144:154  \\\"0xaabbccdd\\\"\n                let expr_7 := 0xaabbccdd\n                /// @src 0:137:154  \\\"return 0xaabbccdd\\\"\n                var__5 := convert_t_rational_2864434397_by_1_to_t_bytes4(expr_7)\n                leave\n\n            }\n            /// @src 0:78:159  \\\"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\\\"\n\n        }\n\n        data \\\".metadata\\\" hex\\\"<BYTECODE REMOVED>\\\"\n    }\n\n}\n\n\"\n            }\n        }\n    },\n    \"sources\": {\n        \"A\": {\n            \"id\": 0\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_verbatim/args",
    "content": "--strict-assembly\n"
  },
  {
    "path": "test/cmdlineTests/yul_verbatim/input.yul",
    "content": "{\n    let x := 2\n    let y := sub(x, 2)\n    let t := verbatim_2i_1o(\"abc\", x, y)\n    sstore(t, x)\n    let r := verbatim_0i_1o(\"def\")\n    verbatim_0i_0o(\"xyz\")\n    // more than 32 bytes\n    verbatim_0i_0o(hex\"01020304050607090001020304050607090001020304050607090001020102030405060709000102030405060709000102030405060709000102\")\n    r := 9\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_verbatim/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code {\n        let x := 2\n        let y := sub(x, 2)\n        let t := verbatim_2i_1o(\"abc\", x, y)\n        sstore(t, x)\n        let r := verbatim_0i_1o(\"def\")\n        verbatim_0i_0o(\"xyz\")\n        verbatim_0i_0o(\"\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\t\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\t\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\t\\x00\\x01\\x02\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\t\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\t\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\t\\x00\\x01\\x02\")\n        r := 9\n    }\n}\n\n\nBinary representation:\n6002808103808261626382815564656678797a010203040506070900010203040506070900010203040506070900010201020304050607090001020304050607090001020304050607090001026009905050505050\n\nText representation:\n    /* \"input.yul\":15:16   */\n  0x02\n    /* \"input.yul\":37:38   */\n  dup1\n    /* \"input.yul\":34:35   */\n  dup2\n    /* \"input.yul\":30:39   */\n  sub\n    /* \"input.yul\":78:79   */\n  dup1\n    /* \"input.yul\":75:76   */\n  dup3\n    /* \"input.yul\":53:80   */\n  verbatimbytecode_616263\n    /* \"input.yul\":95:96   */\n  dup3\n    /* \"input.yul\":92:93   */\n  dup2\n    /* \"input.yul\":85:97   */\n  sstore\n    /* \"input.yul\":111:132   */\n  verbatimbytecode_646566\n    /* \"input.yul\":137:158   */\n  verbatimbytecode_78797a\n    /* \"input.yul\":189:326   */\n  verbatimbytecode_01020304050607090001020304050607090001020304050607090001020102030405060709000102030405060709000102030405060709000102\n    /* \"input.yul\":336:337   */\n  0x09\n    /* \"input.yul\":331:337   */\n  swap1\n  pop\n    /* \"input.yul\":0:339   */\n  pop\n  pop\n  pop\n  pop\n"
  },
  {
    "path": "test/cmdlineTests/yul_verbatim_msize/args",
    "content": "--strict-assembly --optimize"
  },
  {
    "path": "test/cmdlineTests/yul_verbatim_msize/input.yul",
    "content": "{\n    // The optimizer assumes verbatim could contain msize,\n    // so it cannot optimize the mload away.\n    let x := mload(0x2000)\n    verbatim_0i_0o(\"aa\")\n    sstore(0, 2)\n}\n"
  },
  {
    "path": "test/cmdlineTests/yul_verbatim_msize/output",
    "content": "\n======= input.yul (EVM) =======\n\nPretty printed source:\nobject \"object\" {\n    code {\n        {\n            pop(mload(0x2000))\n            verbatim_0i_0o(\"aa\")\n            sstore(0, 2)\n        }\n    }\n}\n\n\nBinary representation:\n6120005150616160025f5500\n\nText representation:\n    /* \"input.yul\":61:67   */\n  0x2000\n    /* \"input.yul\":55:68   */\n  mload\n    /* \"input.yul\":51:69   */\n  pop\n    /* \"input.yul\":82:102   */\n  verbatimbytecode_6161\n    /* \"input.yul\":125:126   */\n  0x02\n    /* \"input.yul\":122:123   */\n  0x00\n    /* \"input.yul\":115:127   */\n  sstore\n    /* \"input.yul\":27:143   */\n  stop\n"
  },
  {
    "path": "test/cmdlineTests/~assembler_modes/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\nfunction test_solc_assembly_output\n{\n    local input=\"${1}\"\n    local expected=\"${2}\"\n    IFS=\" \" read -r -a solc_args <<< \"${3}\"\n\n    local expected_object=\"object \\\"object\\\" { code ${expected} }\"\n\n    output=$(echo \"${input}\" | msg_on_error --no-stderr \"$SOLC\" - \"${solc_args[@]}\")\n    empty=$(echo \"$output\" | tr '\\n' ' ' | tr -s ' ' | sed -ne \"/${expected_object}/p\")\n    if [ -z \"$empty\" ]\n    then\n        printError \"Incorrect assembly output. Expected: \"\n        >&2 echo -e \"${expected}\"\n        printError \"with arguments ${solc_args[*]}, but got:\"\n        >&2 echo \"${output}\"\n        fail\n    fi\n}\n\necho '{}' | msg_on_error --silent \"$SOLC\" - --strict-assembly\n\n# Test that --assemble triggers an error\nset +e\noutput=$(echo '{}' | \"$SOLC\" - --assemble 2>&1)\nfailed=$?\nexpected=\"Error: The assembly input mode formerly accessible via --assemble is no longer supported, please use --strict-assembly instead.\"\nset -e\nif [[ $output != \"${expected}\" ]] || (( failed == 0 ))\nthen\n    fail \"Incorrect error response to --assemble flag: $output\"\nfi\n\n# Test strict assembly output\n# Non-empty code results in non-empty binary representation with optimizations turned off,\n# while it results in empty binary representation with optimizations turned on.\ntest_solc_assembly_output \"{ let x := 0 mstore(0, x) }\" \"{ { let x := 0 mstore(0, x) } }\" \"--strict-assembly\"\ntest_solc_assembly_output \"{ let x := 0 mstore(0, x) }\" \"{ { } }\" \"--strict-assembly --optimize\"\n\n# Test that --yul triggers an error\nset +e\noutput=$(echo '{}' | \"$SOLC\" - --yul 2>&1)\nfailed=$?\nexpected=\"Error: The typed Yul dialect formerly accessible via --yul is no longer supported, please use --strict-assembly instead.\"\nset -e\nif [[ $output != \"${expected}\" ]] || (( failed == 0 ))\nthen\n    fail \"Incorrect error response to --yul flag: $output\"\nfi\n"
  },
  {
    "path": "test/cmdlineTests/~ast_export_with_stop_after_parsing/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\n\"$REPO_ROOT/test/stopAfterParseTests.sh\"\n"
  },
  {
    "path": "test/cmdlineTests/~ast_import_export/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\nSOLTMPDIR=$(mktemp -d -t \"cmdline-test-ast-import-export-XXXXXX\")\ncd \"$SOLTMPDIR\"\nif ! \"$REPO_ROOT/scripts/ASTImportTest.sh\" ast\nthen\n    rm -r \"$SOLTMPDIR\"\n    fail\nfi\nrm -r \"$SOLTMPDIR\"\n"
  },
  {
    "path": "test/cmdlineTests/~bytecode_equivalence_independent_of_import_discovery_order/inputs.sol",
    "content": "==== Source: A.sol ====\nimport \"@/D.sol\";\nimport \"B.sol\";\n\ncontract A is B {\n    function a() public pure {\n        e();\n    }\n}\n\n==== Source: B.sol ====\nimport \"C.sol\";\n\nabstract contract B is C {}\n\n==== Source: C.sol ====\nabstract contract C {\n    function c() public pure returns (uint) {\n        return 0;\n    }\n}\n\n==== Source: @/D.sol ====\nimport \"@/E.sol\";\n\n==== Source: @/E.sol ====\nfunction e() pure returns (bytes memory returndata) {\n    return \"\";\n}\n"
  },
  {
    "path": "test/cmdlineTests/~bytecode_equivalence_independent_of_import_discovery_order/test.py",
    "content": "#!/usr/bin/env python3\n\nimport os\nimport sys\nfrom pathlib import Path\nfrom textwrap import dedent\n\n# pylint: disable=wrong-import-position\nPROJECT_ROOT = Path(__file__).parents[3]\nsys.path.insert(0, str(PROJECT_ROOT / 'scripts'))\n\nfrom common.cmdline_helpers import add_preamble\nfrom common.cmdline_helpers import inside_temporary_dir\nfrom common.cmdline_helpers import save_bytecode\nfrom common.cmdline_helpers import solc_bin_report\nfrom common.git_helpers import git_diff\nfrom splitSources import split_sources\n\n\n@inside_temporary_dir(Path(__file__).parent.name)\ndef test_bytecode_equivalence():\n    source_file_path = Path(__file__).parent / 'inputs.sol'\n    split_sources(source_file_path, suppress_output=True)\n    add_preamble(Path.cwd())\n\n    solc_binary = os.environ.get('SOLC')\n    if solc_binary is None:\n        raise RuntimeError(dedent(\"\"\"\\\n            `solc` compiler not found.\n            Please ensure you set the SOLC environment variable\n            with the correct path to the compiler's binary.\n        \"\"\"))\n\n    # Whether a file is passed to the compiler explicitly or only discovered when traversing imports\n    # may affect the order in which files are processed and result in different AST IDs.\n    # This, however, must not result in different bytecode being generated.\n    save_bytecode(Path('A.bin'), solc_bin_report(solc_binary, [Path('A.sol')], via_ir=True))\n    save_bytecode(Path('AB.bin'), solc_bin_report(solc_binary, [Path('A.sol'), Path('B.sol')], via_ir=True))\n    return git_diff(Path('A.bin'), Path('AB.bin'))\n\n\nif __name__ == '__main__':\n    sys.exit(test_bytecode_equivalence())\n"
  },
  {
    "path": "test/cmdlineTests/~bytecode_equivalence_with_unused_contracts/inputs.sol",
    "content": "==== Source: A.sol ====\ncontract DummyContract1 {}\ncontract DummyContract2 {}\ncontract DummyContract3 {}\n\n==== Source: B.sol ====\ncontract B {\n    function f(uint8 a_0, uint8 a_1, uint8 a_2) public pure {\n        a_1 = 1;\n        a_2 = 2;\n        a_0;\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/~bytecode_equivalence_with_unused_contracts/test.py",
    "content": "#!/usr/bin/env python3\n\nimport os\nimport sys\nfrom pathlib import Path\nfrom textwrap import dedent\n\n# pylint: disable=wrong-import-position\nPROJECT_ROOT = Path(__file__).parents[3]\nsys.path.insert(0, str(PROJECT_ROOT / \"scripts\"))\n\nfrom common.cmdline_helpers import add_preamble\nfrom common.cmdline_helpers import inside_temporary_dir\nfrom common.cmdline_helpers import save_bytecode\nfrom common.cmdline_helpers import solc_bin_report\nfrom common.git_helpers import git_diff\nfrom splitSources import split_sources\n\n\n@inside_temporary_dir(Path(__file__).parent.name)\ndef test_bytecode_equivalence():\n    source_file_path = Path(__file__).parent / \"inputs.sol\"\n    split_sources(source_file_path, suppress_output=True)\n    add_preamble(Path.cwd())\n\n    solc_binary = os.environ.get(\"SOLC\")\n    if solc_binary is None:\n        raise RuntimeError(\n            dedent(\n                \"\"\"\\\n            `solc` compiler not found.\n            Please ensure you set the SOLC environment variable\n            with the correct path to the compiler's binary.\n        \"\"\"\n            )\n        )\n\n    # Repro for https://github.com/argotorg/solidity/issues/14829\n    save_bytecode(\n        Path(\"B.bin\"),\n        solc_bin_report(\n            solc_binary,\n            [Path(\"B.sol\")],\n            via_ir=True,\n            optimize=True,\n            yul_optimizations=\"a:\",\n        ),\n        contract=\"B\",\n    )\n    save_bytecode(\n        Path(\"AB.bin\"),\n        solc_bin_report(\n            solc_binary,\n            [Path(\"A.sol\"), Path(\"B.sol\")],\n            via_ir=True,\n            optimize=True,\n            yul_optimizations=\"a:\",\n        ),\n        contract=\"B\",\n    )\n    return git_diff(Path(\"B.bin\"), Path(\"AB.bin\"))\n\n\nif __name__ == \"__main__\":\n    sys.exit(test_bytecode_equivalence())\n"
  },
  {
    "path": "test/cmdlineTests/~cli_and_standard_json_equivalence/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n# shellcheck source=scripts/common_cmdline.sh\nsource \"${REPO_ROOT}/scripts/common_cmdline.sh\"\n\nfunction test_cli_and_standard_json_equivalence\n{\n    (( $# == 5 )) || assertFail\n    local cli_options=\"$1\"\n    local selected_cli_output=\"$2\"\n    local standard_json_settings=\"$3\"\n    local selected_standard_json_output=\"$4\"\n    local input_file_relative_path=\"$5\"\n\n    # CLI normalizes paths, Standard JSON uses them as is. Using paths that would change under this\n    # normalization will make the comparison fail. To avoid this use already normalized paths.\n    # The sanity check below should reject most of these by disallowing absolute paths, relative\n    # paths with ./ or ../ segments and paths with redundant slashes, but keep in mind it's not foolproof.\n    [[ $input_file_relative_path =~ ^/|^\\.$|\\./|^\\.\\.$|\\.\\./|// ]] && assertfail\n\n    local cli_output standard_json_output\n    cli_output=$(\n        # shellcheck disable=SC2086 # Intentionally unquoted. May contain multiple options.\n        msg_on_error --no-stderr \\\n            \"$SOLC\" $cli_options \"$selected_cli_output\" \"$input_file_relative_path\"\n    )\n    standard_json_output=$(\n        singleContractOutputViaStandardJSON \\\n            Solidity \\\n            \"$selected_standard_json_output\" \\\n            \"$standard_json_settings\" \\\n            \"$input_file_relative_path\"\n    )\n\n    diff_values \\\n        \"$(echo \"$cli_output\" | stripCLIDecorations | stripEmptyLines)\" \\\n        \"$(echo \"$standard_json_output\" | stripEmptyLines)\" \\\n        --ignore-space-change \\\n        --ignore-blank-lines\n}\n\ncd \"$REPO_ROOT\"\n\nprintTask \"    - --optimize vs optimizer.enabled: true (--asm output)\"\ntest_cli_and_standard_json_equivalence \\\n    '--optimize' \\\n    '--asm' \\\n    '\"optimizer\": {\"enabled\": true}' \\\n    'evm.assembly' \\\n    \"test/libsolidity/semanticTests/various/erc20.sol\"\n\nprintTask \"    - --optimize-yul vs optimizer.details.yul: true (--asm output)\"\ntest_cli_and_standard_json_equivalence \\\n    '--optimize-yul' \\\n    '--asm' \\\n    '\"optimizer\": {\"enabled\": false, \"details\": {\"yul\": true}}' \\\n    'evm.assembly' \\\n    \"test/libsolidity/semanticTests/various/erc20.sol\"\n"
  },
  {
    "path": "test/cmdlineTests/~compilation_tests/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n# shellcheck source=scripts/common_cmdline.sh\nsource \"${REPO_ROOT}/scripts/common_cmdline.sh\"\n\ncd \"$REPO_ROOT\"/test/compilationTests/\nfor dir in */\ndo\n    echo \"    - $dir\"\n    cd \"$dir\"\n    # shellcheck disable=SC2046 # These file names are not supposed to contain spaces.\n    compileFull --expect-warnings $(find . -name '*.sol')\n    cd ..\ndone\n"
  },
  {
    "path": "test/cmdlineTests/~deduplicator-verbatim-bug/test.sh",
    "content": "#!/usr/bin/env bash\nset -eo pipefail\n\n# This is a regression test against https://github.com/argotorg/solidity/issues/14640\n# The bug caused the block deduplicator to incorrectly merge two blocks which have\n# verbatim items surrounded by identical opcodes. Due to the bug, the contents of\n# the verbatim were ignored and the blocks merged into a single one.\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n# shellcheck source=scripts/common_cmdline.sh\nsource \"${REPO_ROOT}/scripts/common_cmdline.sh\"\n\nSCRIPT_DIR=$(cd \"$(dirname \"$0\")\" && pwd)\nYUL_SOURCE=\"${SCRIPT_DIR}/verbatim_inside_identical_blocks.yul\"\n\nVERBATIM_OCCURRENCES=$(< \"$YUL_SOURCE\" \"$SOLC\" --strict-assembly - --optimize --asm | grep -e \"verbatim\" -c)\n\n[[ $VERBATIM_OCCURRENCES == 2 ]] || assertFail \"Incorrect number of verbatim items in assembly.\"\n"
  },
  {
    "path": "test/cmdlineTests/~deduplicator-verbatim-bug/verbatim_inside_identical_blocks.yul",
    "content": "{\n  let special := 0xFFFFFFFFFFFF\n  let input := sload(0)\n  let output\n\n  switch input\n  case 0x00 {\n      output := verbatim_1i_1o(hex\"506000\", special)\n  }\n  case 0x01 {\n      output := 1\n  }\n  case 0x02 {\n      output := verbatim_1i_1o(hex\"506002\", special)\n  }\n  case 0x03 {\n      output := 3\n  }\n\n  sstore(0, output)\n}\n"
  },
  {
    "path": "test/cmdlineTests/~documentation_examples/test.sh",
    "content": "#!/usr/bin/env bash\nset -eo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n# shellcheck source=scripts/common_cmdline.sh\nsource \"${REPO_ROOT}/scripts/common_cmdline.sh\"\n\nSOLTMPDIR=$(mktemp -d -t \"cmdline-test-docs-examples-XXXXXX\")\ncd \"$SOLTMPDIR\"\n\n\"$REPO_ROOT\"/scripts/isolate_tests.py \"$REPO_ROOT\"/docs/\n\ndevelopmentVersion=$(\"$REPO_ROOT/scripts/get_version.sh\")\n\nfor f in *.yul *.sol\ndo\n    # The contributors guide uses syntax tests, but we cannot\n    # really handle them here.\n    if grep -E 'DeclarationError:|// ----' \"$f\" >/dev/null\n    then\n        continue\n    fi\n    echo \"    - Compiling example $f\"\n\n    opts=()\n    # We expect errors if explicitly stated, or if imports\n    # are used (in the style guide)\n    if grep -E \"// This will not compile\" \"$f\" >/dev/null ||\n        sed -e 's|//.*||g' \"$f\" | grep -E \"import \\\"\" >/dev/null\n    then\n        opts=(--expect-errors)\n    fi\n    if grep \"// This will report a warning\" \"$f\" >/dev/null\n    then\n        opts+=(--expect-warnings)\n    fi\n    if grep \"// This may report a warning\" \"$f\" >/dev/null\n    then\n        opts+=(--ignore-warnings)\n    fi\n    if grep \"// This will only compile via IR\" \"$f\" >/dev/null\n    then\n        opts+=(--via-ir)\n    fi\n\n    # Disable the version pragma in code snippets that only work with the current development version.\n    # It's necessary because x.y.z won't match `^x.y.z` or `>=x.y.z` pragmas until it's officially released.\n    sed -i.bak -E -e 's/pragma[[:space:]]+solidity[[:space:]]*(\\^|>=)[[:space:]]*'\"$developmentVersion\"'/pragma solidity >0.0.1/' \"$f\"\n    compileFull \"${opts[@]}\" \"$SOLTMPDIR/$f\"\ndone\nrm -r \"$SOLTMPDIR\"\n"
  },
  {
    "path": "test/cmdlineTests/~evmasm_import_export/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\nSOLTMPDIR=$(mktemp -d -t \"cmdline-test-evmasm-import-export-XXXXXX\")\ncd \"$SOLTMPDIR\"\nif ! \"$REPO_ROOT/scripts/ASTImportTest.sh\" evm-assembly\nthen\n    rm -r \"$SOLTMPDIR\"\n    fail\nfi\nrm -r \"$SOLTMPDIR\"\n"
  },
  {
    "path": "test/cmdlineTests/~library_checksum/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\necho '' | msg_on_error --no-stdout \"$SOLC\" - --link --libraries a=0x90f20564390eAe531E810af625A22f51385Cd222\necho '' | \"$SOLC\" - --link --libraries a=0x80f20564390eAe531E810af625A22f51385Cd222 &>/dev/null && \\\n    fail \"solc --link did not reject a library address with an invalid checksum.\"\n\nexit 0\n"
  },
  {
    "path": "test/cmdlineTests/~library_long_names/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\necho '' | msg_on_error --no-stdout \"$SOLC\" - --link --libraries aveeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeerylonglibraryname=0x90f20564390eAe531E810af625A22f51385Cd222\n"
  },
  {
    "path": "test/cmdlineTests/~linking/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\nSOLTMPDIR=$(mktemp -d -t \"cmdline-test-linking-XXXXXX\")\ncd \"$SOLTMPDIR\"\n\necho 'library L { function f() public pure {} } contract C { function f() public pure { L.f(); } }' > x.sol\nmsg_on_error --no-stderr \"$SOLC\" --bin -o . x.sol\n\n# Explanation and placeholder should be there\ngrep -q '//' C.bin && grep -q '__' C.bin\n\n# But not in library file.\ngrep -q -v '[/_]' L.bin\n\n# Now link\nprintf \"    \"\nmsg_on_error \"$SOLC\" --link --libraries x.sol:L=0x90f20564390eAe531E810af625A22f51385Cd222 C.bin\n\n# Now the placeholder and explanation should be gone.\ngrep -q -v '[/_]' C.bin\n\nrm -r \"$SOLTMPDIR\"\n"
  },
  {
    "path": "test/cmdlineTests/~name_dependent_cse_bug/cse_bug.yul",
    "content": "object \"C\" {\n    code {}\n\n    object \"C_deployed\" {\n        code {\n            main(0, 0)\n\n            function main(a, b) {\n                for {} 1 {}\n                {\n                    if iszero(a) { break }\n\n                    let mid := avg(a, a)\n                    switch a\n                    case 0 {\n                        a := mid\n                    }\n                    default {\n                        sstore(0, mid)\n                    }\n                }\n            }\n\n            function avg(x, y) -> var {\n                let __placeholder__ := add(x, y)\n                var := add(__placeholder__, __placeholder__)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "test/cmdlineTests/~name_dependent_cse_bug/test.sh",
    "content": "#!/usr/bin/env bash\nset -eo pipefail\n\n# This is a regression test against https://github.com/argotorg/solidity/issues/14494\n# Due to the bug, a decision about which variable to use to replace a subexpression in CSE would\n# depend on sorting order of variable names. A variable not being used as a replacement could lead\n# to it being unused in general and removed by Unused Pruner. This would show up as a difference\n# in the bytecode.\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n# shellcheck source=scripts/common_cmdline.sh\nsource \"${REPO_ROOT}/scripts/common_cmdline.sh\"\n\nSCRIPT_DIR=$(cd \"$(dirname \"$0\")\" && pwd)\n\nfunction assemble_with_variable_name {\n    local input_file=\"$1\"\n    local variable_name=\"$2\"\n\n    sed -e \"s|__placeholder__|${variable_name}|g\" \"$input_file\" | msg_on_error --no-stderr \\\n        \"$SOLC\" --strict-assembly - --optimize --debug-info none --asm |\n            stripCLIDecorations\n}\n\ndiff_values \\\n    \"$(assemble_with_variable_name \"${SCRIPT_DIR}/cse_bug.yul\" _1)\" \\\n    \"$(assemble_with_variable_name \"${SCRIPT_DIR}/cse_bug.yul\" _2)\"\n"
  },
  {
    "path": "test/cmdlineTests/~overwriting_files/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\nSOLTMPDIR=$(mktemp -d -t \"cmdline-test-overwriting-files-XXXXXX\")\n\n# First time it works\necho 'contract C {}' | msg_on_error --no-stderr \"$SOLC\" - --bin -o \"$SOLTMPDIR/non-existing-stuff-to-create\"\n\n# Second time it fails\necho 'contract C {}' | \"$SOLC\" - --bin -o \"$SOLTMPDIR/non-existing-stuff-to-create\" 2>/dev/null && \\\n    fail \"solc did not refuse to overwrite $SOLTMPDIR/non-existing-stuff-to-create.\"\n\n# Unless we force\necho 'contract C {}' | msg_on_error --no-stderr \"$SOLC\" - --overwrite --bin -o \"$SOLTMPDIR/non-existing-stuff-to-create\"\n\nrm -r \"$SOLTMPDIR\"\n"
  },
  {
    "path": "test/cmdlineTests/~soljson_via_fuzzer/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\nSOLTMPDIR=$(mktemp -d -t \"cmdline-test-soljson-via-fuzzer-XXXXXX\")\ncd \"$SOLTMPDIR\"\n\n\"$REPO_ROOT\"/scripts/isolate_tests.py \"$REPO_ROOT\"/test/\n\"$REPO_ROOT\"/scripts/isolate_tests.py \"$REPO_ROOT\"/docs/\n\ngnu_grep -L --include=\"*.sol\" \"^pragma experimental solidity;$\" ./* | xargs -P 4 -n 50 \"${SOLIDITY_BUILD_DIR}/test/tools/solfuzzer\" --quiet --input-files\ngnu_grep -L --include=\"*.sol\" \"^pragma experimental solidity;$\" ./* | xargs -P 4 -n 50 \"${SOLIDITY_BUILD_DIR}/test/tools/solfuzzer\" --without-optimizer --quiet --input-files\n\nrm -r \"$SOLTMPDIR\"\n"
  },
  {
    "path": "test/cmdlineTests/~standard_input/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\nset +e\noutput=$(\"$SOLC\" --bin 2>&1)\nresult=$?\nset -e\n\n# This should fail\nif [[ ! (\"$output\" =~ \"No input files given\") || ($result == 0) ]]\nthen\n    fail \"Incorrect response to empty input arg list: $output\"\nfi\n\n# The contract should be compiled\nif ! echo 'contract C {}' | msg_on_error --no-stderr \"$SOLC\" - --bin | grep -q \"<stdin>:C\"\nthen\n    fail \"Failed to compile a simple contract from standard input\"\nfi\n\n# This should not fail\necho '' | msg_on_error --silent --msg \"Incorrect response to --ast-compact-json option with empty stdin\" \\\n    \"$SOLC\" --ast-compact-json -\n"
  },
  {
    "path": "test/cmdlineTests/~unknown_options/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\nset +e\noutput=$(\"$SOLC\" --allow=test 2>&1)\nfailed=$?\nset -e\n\nif [[ $output != \"Error: unrecognised option '--allow=test'\" ]] || (( failed == 0 ))\nthen\n    fail \"Incorrect response to unknown options: $output\"\nfi\n"
  },
  {
    "path": "test/cmdlineTests/~update_bugs_by_version/test.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n\nSOLTMPDIR=$(mktemp -d -t \"cmdline-test-update-bugs-by-version-XXXXXX\")\n\ncp \"${REPO_ROOT}/docs/bugs_by_version.json\" \"${SOLTMPDIR}/original_bugs_by_version.json\"\n\"${REPO_ROOT}/scripts/update_bugs_by_version.py\"\n\ndiff --unified \"${SOLTMPDIR}/original_bugs_by_version.json\" \"${REPO_ROOT}/docs/bugs_by_version.json\" || \\\n    fail \"The bug list in bugs_by_version.json was out of date and has been updated. Please investigate and submit a bugfix if necessary.\"\n\nrm -r \"$SOLTMPDIR\"\n"
  },
  {
    "path": "test/cmdlineTests/~via_ir_equivalence/test.sh",
    "content": "#!/usr/bin/env bash\nset -eo pipefail\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n# shellcheck source=scripts/common_cmdline.sh\nsource \"${REPO_ROOT}/scripts/common_cmdline.sh\"\n\nfunction test_via_ir_equivalence()\n{\n    (( $# <= 2 )) || fail \"This function accepts at most two arguments.\"\n    local solidity_file=\"$1\"\n    local optimize_flag=\"$2\"\n    [[ $optimize_flag == --optimize || $optimize_flag == \"\" ]] || assertFail \"The second argument must be --optimize if present.\"\n\n    local output_file_prefix\n    output_file_prefix=$(basename \"$solidity_file\" .sol)\n\n    SOLTMPDIR=$(mktemp -d -t \"cmdline-test-via-ir-equivalence-${output_file_prefix}-XXXXXX\")\n    pushd \"$SOLTMPDIR\" > /dev/null\n\n    local optimizer_flags=()\n    [[ $optimize_flag == \"\" ]] || optimizer_flags+=(\"$optimize_flag\")\n    [[ $optimize_flag == \"\" ]] || output_file_prefix+=\"_optimize\"\n\n    msg_on_error --no-stderr \\\n        \"$SOLC\" --ir-optimized --debug-info location \"${optimizer_flags[@]}\" \"$solidity_file\" |\n            stripCLIDecorations |\n            split_on_empty_lines_into_numbered_files \"$output_file_prefix\" \".yul\"\n\n    local asm_output_two_stage asm_output_via_ir\n\n    for yul_file in $(find . -name \"${output_file_prefix}*.yul\" | sort -V); do\n        asm_output_two_stage+=$(\n            msg_on_error --no-stderr \\\n                \"$SOLC\" --strict-assembly --asm \"${optimizer_flags[@]}\" --no-optimize-yul \"$yul_file\" |\n                    stripCLIDecorations\n        )\n    done\n\n    asm_output_via_ir=$(\n        msg_on_error --no-stderr \\\n            \"$SOLC\" --via-ir --asm --debug-info location \"${optimizer_flags[@]}\" \"$solidity_file\" |\n                stripCLIDecorations\n    )\n\n    diff_values \"$asm_output_two_stage\" \"$asm_output_via_ir\" --ignore-space-change --ignore-blank-lines\n\n    local bin_output_two_stage bin_output_via_ir\n\n    for yul_file in $(find . -name \"${output_file_prefix}*.yul\" | sort -V); do\n        bin_output_two_stage+=$(\n            msg_on_error --no-stderr \\\n                \"$SOLC\" --strict-assembly --bin \"${optimizer_flags[@]}\" \"$yul_file\" --no-optimize-yul |\n                    stripCLIDecorations\n        )\n    done\n\n    bin_output_via_ir=$(\n        msg_on_error --no-stderr \\\n            \"$SOLC\" --via-ir --bin \"${optimizer_flags[@]}\" \"$solidity_file\" | stripCLIDecorations\n    )\n\n    diff_values \"$bin_output_two_stage\" \"$bin_output_via_ir\" --ignore-space-change --ignore-blank-lines\n\n    popd > /dev/null\n    rm -r \"$SOLTMPDIR\"\n}\n\nexternalContracts=(\n    externalTests/solc-js/DAO/TokenCreation.sol\n    libsolidity/semanticTests/externalContracts/_prbmath/PRBMathSD59x18.sol\n    libsolidity/semanticTests/externalContracts/_prbmath/PRBMathUD60x18.sol\n    libsolidity/semanticTests/externalContracts/_stringutils/stringutils.sol\n    libsolidity/semanticTests/externalContracts/deposit_contract.sol\n    libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol\n    libsolidity/semanticTests/externalContracts/snark.sol\n)\n\nrequiresOptimizer=(\n    externalTests/solc-js/DAO/TokenCreation.sol\n    libsolidity/semanticTests/externalContracts/deposit_contract.sol\n    libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol\n    libsolidity/semanticTests/externalContracts/snark.sol\n)\n\nfor contractFile in \"${externalContracts[@]}\"\ndo\n    if ! [[ \" ${requiresOptimizer[*]} \" == *\" $contractFile \"* ]]\n    then\n        printTask \"    - ${contractFile}\"\n        test_via_ir_equivalence \"${REPO_ROOT}/test/${contractFile}\"\n    fi\n\n    printTask \"    - ${contractFile} (optimized)\"\n    test_via_ir_equivalence \"${REPO_ROOT}/test/${contractFile}\" --optimize\ndone\n"
  },
  {
    "path": "test/cmdlineTests.sh",
    "content": "#!/usr/bin/env bash\n\n#------------------------------------------------------------------------------\n# Bash script to run commandline Solidity tests.\n#\n# The documentation for solidity is hosted at:\n#\n#     https://docs.soliditylang.org\n#\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2016 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -eo pipefail\n\n## GLOBAL VARIABLES\n\nREPO_ROOT=$(cd \"$(dirname \"$0\")/..\" && pwd)\nSOLIDITY_BUILD_DIR=${SOLIDITY_BUILD_DIR:-${REPO_ROOT}/build}\nexport REPO_ROOT SOLIDITY_BUILD_DIR\n\n# shellcheck source=scripts/common.sh\nsource \"${REPO_ROOT}/scripts/common.sh\"\n# shellcheck source=scripts/common_cmdline.sh\nsource \"${REPO_ROOT}/scripts/common_cmdline.sh\"\n\npushd \"${REPO_ROOT}/test/cmdlineTests\" > /dev/null\nautoupdate=false\nno_smt=false\ndeclare -a included_test_patterns\ndeclare -a excluded_test_patterns\nwhile [[ $# -gt 0 ]]\ndo\n    case \"$1\" in\n        --update)\n            autoupdate=true\n            shift\n            ;;\n        --no-smt)\n            no_smt=true\n            shift\n            ;;\n        --exclude)\n            [[ $2 != '' ]] || fail \"No pattern given to --exclude option or the pattern is empty.\"\n            excluded_test_patterns+=(\"$2\")\n            shift\n            shift\n            ;;\n        *)\n            included_test_patterns+=(\"$1\")\n            shift\n            ;;\n    esac\ndone\n\n(( ${#included_test_patterns[@]} > 0 )) || included_test_patterns+=('*')\n\ntest_name_filter=('(' -name \"${included_test_patterns[0]}\")\nfor pattern in \"${included_test_patterns[@]:1}\"\ndo\n    test_name_filter+=(-or -name \"$pattern\")\ndone\ntest_name_filter+=(')')\n\nfor pattern in \"${excluded_test_patterns[@]}\"\ndo\n    test_name_filter+=(-and -not -name \"$pattern\")\ndone\n\n# NOTE: We want leading symbols in names to affect the sort order but without\n# LC_COLLATE=C sort seems to ignore them.\n# shellcheck disable=SC2207 # We do not support test names containing spaces.\nselected_tests=($(find . -mindepth 1 -maxdepth 1 -type d \"${test_name_filter[@]}\" | cut -c 3- | LC_COLLATE=C sort))\n\nif (( ${#selected_tests[@]} == 0 ))\nthen\n    printWarning \"The pattern '${test_name_filter[*]}' did not match any tests.\"\n    exit 0;\nelse\n    test_count=$(find . -mindepth 1 -maxdepth 1 -type d | wc -l)\n    printLog \"Selected ${#selected_tests[@]} out of ${test_count} tests.\"\nfi\n\npopd > /dev/null\n\ncase \"$OSTYPE\" in\n    msys)\n        SOLC=\"${SOLIDITY_BUILD_DIR}/solc/Release/solc.exe\"\n\n        # prevents msys2 path translation for a remapping test\n        export MSYS2_ARG_CONV_EXCL=\"=\"\n        ;;\n    *)\n        SOLC=\"${SOLIDITY_BUILD_DIR}/solc/solc\"\n        ;;\nesac\necho \"Using solc binary at ${SOLC}\"\nexport SOLC\n\nINTERACTIVE=true\nif ! tty -s || [ \"$CI\" ]\nthen\n    INTERACTIVE=false\nfi\n\n# extend stack size in case we run via ASAN\nif [[ -n \"${CIRCLECI}\" ]] || [[ -n \"$CI\" ]]\nthen\n    ulimit -s 16384\n    ulimit -a\nfi\n\n## FUNCTIONS\n\nfunction update_expectation {\n    local newExpectation=\"${1}\"\n    local expectationFile=\"${2}\"\n\n    if [[ $newExpectation == '' || $newExpectation == '0' && $expectationFile == */exit ]]\n    then\n        if [[ -f $expectationFile ]]\n        then\n            rm \"$expectationFile\"\n        fi\n        return\n    fi\n\n    echo \"$newExpectation\" > \"$expectationFile\"\n    printLog \"File $expectationFile updated to match the expectation.\"\n}\n\nfunction ask_expectation_update\n{\n    if [[ $INTERACTIVE == true ]]\n    then\n        local newExpectation=\"${1}\"\n        local expectationFile=\"${2}\"\n\n        if [[ $autoupdate == true ]]\n        then\n            update_expectation \"$newExpectation\" \"$expectationFile\"\n        else\n            local editor=\"${FCEDIT:-${VISUAL:-${EDITOR:-vi}}}\"\n\n            while true\n            do\n                read -r -n 1 -p \"(e)dit/(u)pdate expectations/(s)kip/(q)uit? \"\n                echo\n                case $REPLY in\n                    e*) \"$editor\" \"$expectationFile\"; break;;\n                    u*) update_expectation \"$newExpectation\" \"$expectationFile\"; break;;\n                    s*) return;;\n                    q*) fail;;\n                esac\n            done\n        fi\n    else\n        [[ $INTERACTIVE == false ]] || assertFail\n        fail\n    fi\n}\n\n# General helper function for testing SOLC behaviour, based on file name, compile opts, exit code, stdout and stderr.\n# An failure is expected.\nfunction test_solc_behaviour\n{\n    local filename=\"${1}\"\n    local solc_args\n    IFS=\" \" read -r -a solc_args <<< \"${2}\"\n    local solc_stdin=\"${3}\"\n    [ -z \"$solc_stdin\"  ] && solc_stdin=\"/dev/stdin\"\n    local stdout_expected=\"${4}\"\n    local exit_code_expected=\"${5}\"\n    local exit_code_expectation_file=\"${6}\"\n    local stderr_expected=\"${7}\"\n    local stdout_expectation_file=\"${8}\" # the file to write to when user chooses to update stdout expectation\n    local stderr_expectation_file=\"${9}\" # the file to write to when user chooses to update stderr expectation\n    local stdout_path; stdout_path=$(mktemp -t \"cmdline-test-stdout-XXXXXX\")\n    local stderr_path; stderr_path=$(mktemp -t \"cmdline-test-stderr-XXXXXX\")\n\n    # shellcheck disable=SC2064\n    trap \"rm -f $stdout_path $stderr_path\" EXIT\n\n    if [[ \"$exit_code_expected\" = \"\" ]]\n    then\n        exit_code_expected=\"0\"\n    fi\n\n    [[ $filename == \"\" ]] || solc_args+=(\"$filename\")\n\n    local solc_command=\"$SOLC ${solc_args[*]} <$solc_stdin\"\n    set +e\n    \"$SOLC\" \"${solc_args[@]}\" <\"$solc_stdin\" >\"$stdout_path\" 2>\"$stderr_path\"\n    exitCode=$?\n    set -e\n\n    if [[ \" ${solc_args[*]} \" == *\" --standard-json \"* ]] && [[ -s $stdout_path ]]\n    then\n        python3 - <<EOF\nimport re, sys\njson = open(\"$stdout_path\", \"r\").read()\njson = re.sub(r\"{[^{}]*Warning: This is a pre-release compiler version[^{}]*},?\", \"\", json)\njson = re.sub(r\"\\\"errors\\\":\\s*\\[\\s*\\],?\",\"\\n\" if json[1] == \" \" else \"\",json)       # Remove \"errors\" array if it's not empty\njson = re.sub(r\"\\n\\s*\\n\", \"\\n\", json)                                               # Remove trailing whitespace\njson = re.sub(r\"},(\\n{0,1})\\n*(\\s*(]|}))\", r\"}\\1\\2\", json)                          # Remove trailing comma\nopen(\"$stdout_path\", \"w\").write(json)\nEOF\n        # Only do this to files that actually contain ethdebug output, because jq will reformat\n        # the whole file and its formatting differs from `solc --pretty-json`\n        if jq 'has(\"ethdebug\")' \"$stdout_path\" --exit-status > /dev/null; then\n            local temporary_file\n            temporary_file=$(mktemp -t cmdline-ethdebug-XXXXXX.tmp)\n            if [[ -e strip-ethdebug ]]; then\n                jq --indent 4 '\n                    (. | .. | objects | select(has(\"ethdebug\"))) |= (.ethdebug = \"<ETHDEBUG DEBUG DATA REMOVED>\")\n                ' \"$stdout_path\" > \"$temporary_file\"\n            else\n                jq --indent 4 '\n                    if .ethdebug.compilation.compiler.version? != null then\n                        .ethdebug.compilation.compiler.version = \"<VERSION REMOVED>\"\n                    else\n                        .\n                    end\n                ' \"$stdout_path\" > \"$temporary_file\"\n            fi\n            mv \"$temporary_file\" \"$stdout_path\"\n        fi\n\n        sed -i.bak -E -e 's/ Consider adding \\\\\"pragma solidity \\^[0-9.]*;\\\\\"//g' \"$stdout_path\"\n        sed -i.bak -E -e 's/\\\"opcodes\\\":[[:space:]]*\\\"[^\"]+\\\"/\\\"opcodes\\\":\\\"<OPCODES REMOVED>\\\"/g' \"$stdout_path\"\n        sed -i.bak -E -e 's/\\\"sourceMap\\\":[[:space:]]*\\\"[0-9:;-]+\\\"/\\\"sourceMap\\\":\\\"<SOURCEMAP REMOVED>\\\"/g' \"$stdout_path\"\n\n        # Remove bytecode (but not linker references).\n        sed -i.bak -E -e 's/(\\\"object\\\":[[:space:]]*\\\")[0-9a-f]+([^\"]*\\\")/\\1<BYTECODE REMOVED>\\2/g' \"$stdout_path\"\n        # shellcheck disable=SC2016\n        sed -i.bak -E -e 's/(\\\"object\\\":[[:space:]]*\\\"[^\"]+\\$__)[0-9a-f]+(\\\")/\\1<BYTECODE REMOVED>\\2/g' \"$stdout_path\"\n        # shellcheck disable=SC2016\n        sed -i.bak -E -e 's/([0-9a-f]{34}\\$__)[0-9a-f]+(__\\$[0-9a-f]{17})/\\1<BYTECODE REMOVED>\\2/g' \"$stdout_path\"\n        # Remove metadata in assembly output (see below about the magic numbers)\n        sed -i.bak -E -e 's/\"[0-9a-f]+64697066735822[0-9a-f]+64736f6c63[0-9a-f]+/\"<BYTECODE REMOVED>/g' \"$stdout_path\"\n\n        # Replace escaped newlines by actual newlines for readability\n        # shellcheck disable=SC1003\n        sed -i.bak -E -e 's/\\\\n/\\'$'\\n/g' \"$stdout_path\"\n        sed -i.bak -e 's/\\(^[ ]*auxdata:[[:space:]]\\)0x[0-9a-f]*$/\\1<AUXDATA REMOVED>/' \"$stdout_path\"\n        sed -i.bak -e 's/\\(\\\\\"version\\\\\":[ ]*\\\\\"\\)[^\"\\\\]*\\(\\\\\"\\)/\\1<VERSION REMOVED>\\2/' \"$stdout_path\"\n        rm \"$stdout_path.bak\"\n    else\n        sed -i.bak -e '/^Warning: This is a pre-release compiler version, please do not use it in production./,+1d' \"$stderr_path\"\n        sed -i.bak -e '/^Compiler run successful, no output requested\\.$/d' \"$stderr_path\"\n        sed -i.bak -e '/^Warning (3805): This is a pre-release compiler version, please do not use it in production./,+1d' \"$stderr_path\"\n        sed -i.bak -e 's/\\(^[ ]*auxdata: \\)0x[0-9a-f]*$/\\1<AUXDATA REMOVED>/' \"$stdout_path\"\n        sed -i.bak -e 's/ Consider adding \"pragma .*$//' \"$stderr_path\"\n        sed -i.bak -e 's/\\(Unimplemented feature error.* in \\).*$/\\1<FILENAME REMOVED>/' \"$stderr_path\"\n        sed -i.bak -e 's/\"version\":[ ]*\"[^\"]*\"/\"version\": \"<VERSION REMOVED>\"/' \"$stdout_path\"\n    if [[ $stdout_expectation_file != \"\" &&  $stderr_expectation_file != \"\" ]]\n    then\n        sed -i.bak -e '/^Compiler run successful\\. No contracts to compile\\.$/d' \"$stdout_path\"\n        sed -i.bak -e '/^Compiler run successful\\. No output generated\\.$/d' \"$stdout_path\"\n    fi\n\n        # Remove bytecode (but not linker references). Since non-JSON output is unstructured,\n        # use metadata markers for detection to have some confidence that it's actually bytecode\n        # and not some random word.\n        # 64697066735822 = hex encoding of 0x64 'i' 'p' 'f' 's' 0x58 0x22\n        # 64736f6c63     = hex encoding of 0x64 's' 'o' 'l' 'c'\n        sed -i.bak -E -e 's/[0-9a-f]*64697066735822[0-9a-f]+64736f6c63[0-9a-f]+/<BYTECODE REMOVED>/g' \"$stdout_path\"\n        # shellcheck disable=SC2016\n        sed -i.bak -E -e 's/([0-9a-f]{17}\\$__)[0-9a-f]+(__\\$[0-9a-f]{17})/\\1<BYTECODE REMOVED>\\2/g' \"$stdout_path\"\n        # shellcheck disable=SC2016\n        sed -i.bak -E -e 's/[0-9a-f]+((__\\$[0-9a-f]{34}\\$__)*<BYTECODE REMOVED>)/<BYTECODE REMOVED>\\1/g' \"$stdout_path\"\n\n        # Remove trailing empty lines. Needs a line break to make OSX sed happy.\n        sed -i.bak -e '1{/^$/d\n}' \"$stderr_path\"\n        rm \"$stderr_path.bak\" \"$stdout_path.bak\"\n    fi\n    # Remove path to cpp file\n    sed -i.bak -e 's/^\\(Exception while assembling:\\).*/\\1/' \"$stderr_path\"\n    # Remove exception class name.\n    sed -i.bak -e 's/^\\(Dynamic exception type:\\).*/\\1/' \"$stderr_path\"\n    rm \"$stderr_path.bak\"\n\n    if [[ \"$(cat \"$stderr_path\")\" != \"${stderr_expected}\" ]]\n    then\n        printError \"Incorrect output on stderr received. Expected:\"\n        echo -e \"${stderr_expected}\"\n\n        printError \"But got:\"\n        echo -e \"$(cat \"$stderr_path\")\"\n\n        printError \"When running $solc_command\"\n\n        [[ $stderr_expectation_file != \"\" ]] && ask_expectation_update \"$(cat \"$stderr_path\")\" \"$stderr_expectation_file\"\n        [[ $stderr_expectation_file == \"\" ]] && fail\n    fi\n\n    if [[ \"$(cat \"$stdout_path\")\" != \"${stdout_expected}\" ]]\n    then\n        printError \"Incorrect output on stdout received. Expected:\"\n        echo -e \"${stdout_expected}\"\n\n        printError \"But got:\"\n        echo -e \"$(cat \"$stdout_path\")\"\n\n        printError \"When running $solc_command\"\n\n        [[ $stdout_expectation_file != \"\" ]] && ask_expectation_update \"$(cat \"$stdout_path\")\" \"$stdout_expectation_file\"\n        [[ $stdout_expectation_file == \"\" ]] && fail\n    fi\n\n    if [[ $exitCode -ne \"$exit_code_expected\" ]]\n    then\n        printError \"Incorrect exit code. Expected $exit_code_expected but got $exitCode.\"\n\n        [[ $exit_code_expectation_file != \"\" ]] && ask_expectation_update \"$exitCode\" \"$exit_code_expectation_file\"\n        [[ $exit_code_expectation_file == \"\" ]] && fail\n    fi\n\n    rm \"$stdout_path\" \"$stderr_path\"\n}\n\n\n## RUN\n\nprintTask \"Testing passing files that are not found...\"\ntest_solc_behaviour \"file_not_found.sol\" \"\" \"\" \"\" 1 \"\" \"Error: \\\"file_not_found.sol\\\" is not found.\" \"\" \"\"\n\nprintTask \"Testing passing files that are not files...\"\ntest_solc_behaviour \".\" \"\" \"\" \"\" 1 \"\" \"Error: \\\".\\\" is not a valid file.\" \"\" \"\"\n\nprintTask \"Testing passing empty remappings...\"\ntest_solc_behaviour \"${0}\" \"=/some/remapping/target\" \"\" \"\" 1 \"\" \"Error: Invalid remapping: \\\"=/some/remapping/target\\\".\" \"\" \"\"\ntest_solc_behaviour \"${0}\" \"ctx:=/some/remapping/target\" \"\" \"\" 1 \"\" \"Error: Invalid remapping: \\\"ctx:=/some/remapping/target\\\".\" \"\" \"\"\n\nprintTask \"Running general commandline tests...\"\n(\n    for tdir in \"${selected_tests[@]}\"\n    do\n        # go back to the test root dir\n        cd \"$REPO_ROOT\"/test/cmdlineTests/\n\n        if ! [[ -d $tdir ]]\n        then\n            fail \"Test directory not found: $tdir\"\n        fi\n\n        printTask \" - ${tdir}\"\n\n        if [[ $(ls -A \"$tdir\") == \"\" ]]\n        then\n            printWarning \"   ---> skipped (test dir empty)\"\n            continue\n        fi\n\n        # Strip trailing slash from $tdir.\n        tdir=$(basename \"${tdir}\")\n        if [[ $no_smt == true ]]\n        then\n            if [[ $tdir =~ .*model_checker_.* ]]\n            then\n                printWarning \"   ---> skipped (SMT test)\"\n                continue\n            fi\n        fi\n\n        # jump into test dir\n        cd \"${tdir}\"\n\n        scriptFiles=\"$(ls -1 \"test.\"* 2> /dev/null || true)\"\n        scriptCount=\"$(echo \"${scriptFiles}\" | wc -w)\"\n\n        inputFiles=\"$(ls -1 \"input.\"* 2> /dev/null || true)\"\n        inputCount=\"$(echo \"${inputFiles}\" | wc -w)\"\n        (( inputCount <= 1 )) || fail \"Ambiguous input. Found input files in multiple formats:\"$'\\n'\"${inputFiles}\"\n        (( scriptCount <= 1 )) || fail \"Ambiguous input. Found script files in multiple formats:\"$'\\n'\"${scriptFiles}\"\n        (( inputCount == 0 || scriptCount == 0 )) || fail \"Ambiguous input. Found both input and script files:\"$'\\n'\"${inputFiles}\"$'\\n'\"${scriptFiles}\"\n\n        if (( scriptCount == 1 ))\n        then\n            if ! \"./$scriptFiles\"\n            then\n                fail \"Test script ${scriptFiles} failed.\"\n            fi\n\n            continue\n        fi\n\n        # Use printf to get rid of the trailing newline\n        inputFile=$(printf \"%s\" \"${inputFiles}\")\n\n        if [ \"${inputFile}\" = \"input.json\" ]\n        then\n            ! [ -e \"stdin\" ] || fail \"Found a file called 'stdin' but redirecting standard input in JSON mode is not allowed.\"\n\n            stdin=\"${inputFile}\"\n            inputFile=\"\"\n            stdout=\"$(cat \"output.json\" 2>/dev/null || true)\"\n            stdoutExpectationFile=\"output.json\"\n            prettyPrintFlags=\"\"\n            if [[ ! -f \"no-pretty-print\" ]]\n            then\n                prettyPrintFlags=\"--pretty-json --json-indent 4\"\n            fi\n\n            command_args=\"--standard-json ${prettyPrintFlags} \"$(cat \"args\" 2>/dev/null || true)\n        else\n            if [ -e \"stdin\" ]\n            then\n                stdin=\"stdin\"\n                [ -f \"stdin\" ] || fail \"'stdin' is not a regular file.\"\n            else\n                stdin=\"\"\n            fi\n\n            stdout=\"$(cat \"output\" 2>/dev/null || true)\"\n            stdoutExpectationFile=\"output\"\n            command_args=$(cat \"args\" 2>/dev/null || true)\n        fi\n        exitCodeExpectationFile=\"exit\"\n        exitCode=$(cat \"$exitCodeExpectationFile\" 2>/dev/null || true)\n        err=\"$(cat \"err\" 2>/dev/null || true)\"\n        stderrExpectationFile=\"err\"\n        test_solc_behaviour \"$inputFile\" \\\n                            \"$command_args\" \\\n                            \"$stdin\" \\\n                            \"$stdout\" \\\n                            \"$exitCode\" \\\n                            \"$exitCodeExpectationFile\" \\\n                            \"$err\" \\\n                            \"$stdoutExpectationFile\" \\\n                            \"$stderrExpectationFile\"\n    done\n)\n\necho \"Commandline tests successful.\"\n"
  },
  {
    "path": "test/compilationTests/MultiSigWallet/Factory.sol",
    "content": "contract Factory {\n\n    event ContractInstantiation(address sender, address instantiation);\n\n    mapping(address => bool) public isInstantiation;\n    mapping(address => address[]) public instantiations;\n\n    /// @dev Returns number of instantiations by creator.\n    /// @param creator Contract creator.\n    /// @return Returns number of instantiations by creator.\n    function getInstantiationCount(address creator)\n        public\n        view\n        returns (uint)\n    {\n        return instantiations[creator].length;\n    }\n\n    /// @dev Registers contract in factory registry.\n    /// @param instantiation Address of contract instantiation.\n    function register(address instantiation)\n        internal\n    {\n        isInstantiation[instantiation] = true;\n        instantiations[msg.sender].push(instantiation);\n        emit ContractInstantiation(msg.sender, instantiation);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/MultiSigWallet/LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "test/compilationTests/MultiSigWallet/MultiSigWallet.sol",
    "content": "pragma solidity >=0.0;\n\n\n/// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.\n/// @author Stefan George - <stefan.george@consensys.net>\ncontract MultiSigWallet {\n\n    uint constant public MAX_OWNER_COUNT = 50;\n\n    event Confirmation(address indexed sender, uint indexed transactionId);\n    event Revocation(address indexed sender, uint indexed transactionId);\n    event Submission(uint indexed transactionId);\n    event Execution(uint indexed transactionId);\n    event ExecutionFailure(uint indexed transactionId);\n    event Deposit(address indexed sender, uint value);\n    event OwnerAddition(address indexed owner);\n    event OwnerRemoval(address indexed owner);\n    event RequirementChange(uint required);\n\n    mapping (uint => Transaction) public transactions;\n    mapping (uint => mapping (address => bool)) public confirmations;\n    mapping (address => bool) public isOwner;\n    address[] public owners;\n    uint public required;\n    uint public transactionCount;\n\n    struct Transaction {\n        address destination;\n        uint value;\n        bytes data;\n        bool executed;\n    }\n\n    modifier onlyWallet() {\n        if (msg.sender != address(this))\n            revert();\n        _;\n    }\n\n    modifier ownerDoesNotExist(address owner) {\n        if (isOwner[owner])\n            revert();\n        _;\n    }\n\n    modifier ownerExists(address owner) {\n        if (!isOwner[owner])\n            revert();\n        _;\n    }\n\n    modifier transactionExists(uint transactionId) {\n        if (transactions[transactionId].destination == address(0))\n            revert();\n        _;\n    }\n\n    modifier confirmed(uint transactionId, address owner) {\n        if (!confirmations[transactionId][owner])\n            revert();\n        _;\n    }\n\n    modifier notConfirmed(uint transactionId, address owner) {\n        if (confirmations[transactionId][owner])\n            revert();\n        _;\n    }\n\n    modifier notExecuted(uint transactionId) {\n        if (transactions[transactionId].executed)\n            revert();\n        _;\n    }\n\n    modifier notNull(address _address) {\n        if (_address == address(0))\n            revert();\n        _;\n    }\n\n    modifier validRequirement(uint ownerCount, uint _required) {\n        if (   ownerCount > MAX_OWNER_COUNT\n            || _required > ownerCount\n            || _required == 0\n            || ownerCount == 0)\n            revert();\n        _;\n    }\n\n    /// @dev Contract constructor sets initial owners and required number of confirmations.\n    /// @param _owners List of initial owners.\n    /// @param _required Number of required confirmations.\n    constructor(address[] memory _owners, uint _required)\n        validRequirement(_owners.length, _required)\n    {\n        for (uint i=0; i<_owners.length; i++) {\n            if (isOwner[_owners[i]] || _owners[i] == address(0))\n                revert();\n            isOwner[_owners[i]] = true;\n        }\n        owners = _owners;\n        required = _required;\n    }\n\n    /// @dev Receive function allows to deposit ether.\n    receive()\n        external\n        payable\n    {\n        if (msg.value > 0)\n            emit Deposit(msg.sender, msg.value);\n    }\n\n    /*\n     * Public functions\n     */\n\n    /// @dev Allows to add a new owner. Transaction has to be sent by wallet.\n    /// @param owner Address of new owner.\n    function addOwner(address owner)\n        public\n        onlyWallet\n        ownerDoesNotExist(owner)\n        notNull(owner)\n        validRequirement(owners.length + 1, required)\n    {\n        isOwner[owner] = true;\n        owners.push(owner);\n        emit OwnerAddition(owner);\n    }\n\n    /// @dev Allows to remove an owner. Transaction has to be sent by wallet.\n    /// @param owner Address of owner.\n    function removeOwner(address owner)\n        public\n        onlyWallet\n        ownerExists(owner)\n    {\n        isOwner[owner] = false;\n        for (uint i=0; i<owners.length - 1; i++)\n            if (owners[i] == owner) {\n                owners[i] = owners[owners.length - 1];\n                break;\n            }\n        owners.pop();\n        if (required > owners.length)\n            changeRequirement(owners.length);\n        emit OwnerRemoval(owner);\n    }\n\n    /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.\n    /// @param owner Address of owner to be replaced.\n    /// @param owner Address of new owner.\n    function replaceOwner(address owner, address newOwner)\n        public\n        onlyWallet\n        ownerExists(owner)\n        ownerDoesNotExist(newOwner)\n    {\n        for (uint i=0; i<owners.length; i++)\n            if (owners[i] == owner) {\n                owners[i] = newOwner;\n                break;\n            }\n        isOwner[owner] = false;\n        isOwner[newOwner] = true;\n        emit OwnerRemoval(owner);\n        emit OwnerAddition(newOwner);\n    }\n\n    /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.\n    /// @param _required Number of required confirmations.\n    function changeRequirement(uint _required)\n        public\n        onlyWallet\n        validRequirement(owners.length, _required)\n    {\n        required = _required;\n        emit RequirementChange(_required);\n    }\n\n    /// @dev Allows an owner to submit and confirm a transaction.\n    /// @param destination Transaction target address.\n    /// @param value Transaction ether value.\n    /// @param data Transaction data payload.\n    /// @return transactionId Returns transaction ID.\n    function submitTransaction(address destination, uint value, bytes memory data)\n        public\n        returns (uint transactionId)\n    {\n        transactionId = addTransaction(destination, value, data);\n        confirmTransaction(transactionId);\n    }\n\n    /// @dev Allows an owner to confirm a transaction.\n    /// @param transactionId Transaction ID.\n    function confirmTransaction(uint transactionId)\n        public\n        ownerExists(msg.sender)\n        transactionExists(transactionId)\n        notConfirmed(transactionId, msg.sender)\n    {\n        confirmations[transactionId][msg.sender] = true;\n        emit Confirmation(msg.sender, transactionId);\n        executeTransaction(transactionId);\n    }\n\n    /// @dev Allows an owner to revoke a confirmation for a transaction.\n    /// @param transactionId Transaction ID.\n    function revokeConfirmation(uint transactionId)\n        public\n        ownerExists(msg.sender)\n        confirmed(transactionId, msg.sender)\n        notExecuted(transactionId)\n    {\n        confirmations[transactionId][msg.sender] = false;\n        emit Revocation(msg.sender, transactionId);\n    }\n\n    /// @dev Allows anyone to execute a confirmed transaction.\n    /// @param transactionId Transaction ID.\n    function executeTransaction(uint transactionId)\n        virtual\n        public\n        notExecuted(transactionId)\n    {\n        if (isConfirmed(transactionId)) {\n            Transaction storage transaction = transactions[transactionId];\n            (transaction.executed,) = transaction.destination.call{value: transaction.value}(transaction.data);\n            if (transaction.executed)\n                emit Execution(transactionId);\n            else\n                emit ExecutionFailure(transactionId);\n        }\n    }\n\n    /// @dev Returns the confirmation status of a transaction.\n    /// @param transactionId Transaction ID.\n    /// @return Confirmation status.\n    function isConfirmed(uint transactionId)\n        public\n        view\n        returns (bool)\n    {\n        uint count = 0;\n        for (uint i=0; i<owners.length; i++) {\n            if (confirmations[transactionId][owners[i]])\n                count += 1;\n            if (count == required)\n                return true;\n        }\n        return false;\n    }\n\n    /*\n     * Web3 call functions\n     */\n    /// @dev Returns number of confirmations of a transaction.\n    /// @param transactionId Transaction ID.\n    /// @return count Number of confirmations.\n    function getConfirmationCount(uint transactionId)\n        public\n        view\n        returns (uint count)\n    {\n        for (uint i=0; i<owners.length; i++)\n            if (confirmations[transactionId][owners[i]])\n                count += 1;\n    }\n\n    /// @dev Returns total number of transactions after filers are applied.\n    /// @param pending Include pending transactions.\n    /// @param executed Include executed transactions.\n    /// @return count Total number of transactions after filters are applied.\n    function getTransactionCount(bool pending, bool executed)\n        public\n        view\n        returns (uint count)\n    {\n        for (uint i=0; i<transactionCount; i++)\n            if (   pending && !transactions[i].executed\n                || executed && transactions[i].executed)\n                count += 1;\n    }\n\n    /// @dev Returns list of owners.\n    /// @return List of owner addresses.\n    function getOwners()\n        public\n        view\n        returns (address[] memory)\n    {\n        return owners;\n    }\n\n    /// @dev Returns array with owner addresses, which confirmed transaction.\n    /// @param transactionId Transaction ID.\n    /// @return _confirmations Returns array of owner addresses.\n    function getConfirmations(uint transactionId)\n        public\n        view\n        returns (address[] memory _confirmations)\n    {\n        address[] memory confirmationsTemp = new address[](owners.length);\n        uint count = 0;\n        uint i;\n        for (i=0; i<owners.length; i++)\n            if (confirmations[transactionId][owners[i]]) {\n                confirmationsTemp[count] = owners[i];\n                count += 1;\n            }\n        _confirmations = new address[](count);\n        for (i=0; i<count; i++)\n            _confirmations[i] = confirmationsTemp[i];\n    }\n\n    /// @dev Returns list of transaction IDs in defined range.\n    /// @param from Index start position of transaction array.\n    /// @param to Index end position of transaction array.\n    /// @param pending Include pending transactions.\n    /// @param executed Include executed transactions.\n    /// @return _transactionIds Returns array of transaction IDs.\n    function getTransactionIds(uint from, uint to, bool pending, bool executed)\n        public\n        view\n        returns (uint[] memory _transactionIds)\n    {\n        uint[] memory transactionIdsTemp = new uint[](transactionCount);\n        uint count = 0;\n        uint i;\n        for (i=0; i<transactionCount; i++)\n            if (   pending && !transactions[i].executed\n                || executed && transactions[i].executed)\n            {\n                transactionIdsTemp[count] = i;\n                count += 1;\n            }\n        _transactionIds = new uint[](to - from);\n        for (i=from; i<to; i++)\n            _transactionIds[i - from] = transactionIdsTemp[i];\n    }\n    /*\n     * Internal functions\n     */\n    /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.\n    /// @param destination Transaction target address.\n    /// @param value Transaction ether value.\n    /// @param data Transaction data payload.\n    /// @return transactionId Returns transaction ID.\n    function addTransaction(address destination, uint value, bytes memory data)\n        internal\n        notNull(destination)\n        returns (uint transactionId)\n    {\n        transactionId = transactionCount;\n        transactions[transactionId] = Transaction({\n            destination: destination,\n            value: value,\n            data: data,\n            executed: false\n        });\n        transactionCount += 1;\n        emit Submission(transactionId);\n    }\n}"
  },
  {
    "path": "test/compilationTests/MultiSigWallet/MultiSigWalletFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"Factory.sol\";\nimport \"MultiSigWallet.sol\";\n\n\n/// @title Multisignature wallet factory - Allows creation of multisig wallet.\n/// @author Stefan George - <stefan.george@consensys.net>\ncontract MultiSigWalletFactory is Factory {\n\n    /// @dev Allows verified creation of multisignature wallet.\n    /// @param _owners List of initial owners.\n    /// @param _required Number of required confirmations.\n    /// @return wallet Returns wallet address.\n    function create(address[] memory _owners, uint _required)\n        public\n        returns (address wallet)\n    {\n        wallet = address(new MultiSigWallet(_owners, _required));\n        register(wallet);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimit.sol",
    "content": "pragma solidity >=0.0;\nimport \"MultiSigWallet.sol\";\n\n\n/// @title Multisignature wallet with daily limit - Allows an owner to withdraw a daily limit without multisig.\n/// @author Stefan George - <stefan.george@consensys.net>\ncontract MultiSigWalletWithDailyLimit is MultiSigWallet {\n\n    event DailyLimitChange(uint dailyLimit);\n\n    uint public dailyLimit;\n    uint public lastDay;\n    uint public spentToday;\n\n    /*\n     * Public functions\n     */\n    /// @dev Contract constructor sets initial owners, required number of confirmations and daily withdraw limit.\n    /// @param _owners List of initial owners.\n    /// @param _required Number of required confirmations.\n    /// @param _dailyLimit Amount in wei, which can be withdrawn without confirmations on a daily basis.\n    constructor(address[] memory _owners, uint _required, uint _dailyLimit)\n        MultiSigWallet(_owners, _required)\n    {\n        dailyLimit = _dailyLimit;\n    }\n\n    /// @dev Allows to change the daily limit. Transaction has to be sent by wallet.\n    /// @param _dailyLimit Amount in wei.\n    function changeDailyLimit(uint _dailyLimit)\n        public\n        onlyWallet\n    {\n        dailyLimit = _dailyLimit;\n        emit DailyLimitChange(_dailyLimit);\n    }\n\n    /// @dev Allows anyone to execute a confirmed transaction or ether withdraws until daily limit is reached.\n    /// @param transactionId Transaction ID.\n    function executeTransaction(uint transactionId)\n        public\n        override\n        notExecuted(transactionId)\n    {\n        Transaction storage tx = transactions[transactionId];\n        bool confirmed = isConfirmed(transactionId);\n        if (confirmed || tx.data.length == 0 && isUnderLimit(tx.value)) {\n            if (!confirmed)\n                spentToday += tx.value;\n            (tx.executed,) = tx.destination.call{value: tx.value}(tx.data);\n            if (tx.executed)\n                emit Execution(transactionId);\n            else {\n                emit ExecutionFailure(transactionId);\n                if (!confirmed)\n                    spentToday -= tx.value;\n            }\n        }\n    }\n\n    /*\n     * Internal functions\n     */\n    /// @dev Returns if amount is within daily limit and resets spentToday after one day.\n    /// @param amount Amount to withdraw.\n    /// @return Returns if amount is under daily limit.\n    function isUnderLimit(uint amount)\n        internal\n        returns (bool)\n    {\n        if (block.timestamp > lastDay + 24 hours) {\n            lastDay = block.timestamp;\n            spentToday = 0;\n        }\n        if (spentToday + amount > dailyLimit || spentToday + amount < spentToday)\n            return false;\n        return true;\n    }\n\n    /*\n     * Web3 call functions\n     */\n    /// @dev Returns maximum withdraw amount.\n    /// @return Returns amount.\n    function calcMaxWithdraw()\n        public\n        view\n        returns (uint)\n    {\n        if (block.timestamp > lastDay + 24 hours)\n            return dailyLimit;\n        if (dailyLimit < spentToday)\n            return 0;\n        return dailyLimit - spentToday;\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimitFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"Factory.sol\";\nimport \"MultiSigWalletWithDailyLimit.sol\";\n\n\n/// @title Multisignature wallet factory for daily limit version - Allows creation of multisig wallet.\n/// @author Stefan George - <stefan.george@consensys.net>\ncontract MultiSigWalletWithDailyLimitFactory is Factory {\n\n    /// @dev Allows verified creation of multisignature wallet.\n    /// @param _owners List of initial owners.\n    /// @param _required Number of required confirmations.\n    /// @param _dailyLimit Amount in wei, which can be withdrawn without confirmations on a daily basis.\n    /// @return wallet Returns wallet address.\n    function create(address[] memory _owners, uint _required, uint _dailyLimit)\n        public\n        returns (address wallet)\n    {\n        wallet = address(new MultiSigWalletWithDailyLimit(_owners, _required, _dailyLimit));\n        register(wallet);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/MultiSigWallet/README.md",
    "content": "MultiSigWallet contracts, originally from\n\nhttps://github.com/ConsenSys/MultiSigWallet\n"
  },
  {
    "path": "test/compilationTests/MultiSigWallet/TestToken.sol",
    "content": "pragma solidity >=0.0;\n\n\n/// @title Test token contract - Allows testing of token transfers with multisig wallet.\ncontract TestToken {\n\n    event Transfer(address indexed from, address indexed to, uint256 value);\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    mapping (address => uint256) balances;\n    mapping (address => mapping (address => uint256)) allowed;\n    uint256 public totalSupply;\n\n    string constant public name = \"Test Token\";\n    string constant public symbol = \"TT\";\n    uint8 constant public decimals = 1;\n\n    function issueTokens(address _to, uint256 _value)\n        public\n    {\n        balances[_to] += _value;\n        totalSupply += _value;\n    }\n\n    function transfer(address _to, uint256 _value)\n        public\n        returns (bool success)\n    {\n        if (balances[msg.sender] < _value) {\n            revert();\n        }\n        balances[msg.sender] -= _value;\n        balances[_to] += _value;\n        emit Transfer(msg.sender, _to, _value);\n        return true;\n    }\n\n    function transferFrom(address _from, address _to, uint256 _value)\n        public\n        returns (bool success)\n    {\n        if (balances[_from] < _value || allowed[_from][msg.sender] < _value) {\n            revert();\n        }\n        balances[_to] += _value;\n        balances[_from] -= _value;\n        allowed[_from][msg.sender] -= _value;\n        emit Transfer(_from, _to, _value);\n        return true;\n    }\n\n    function approve(address _spender, uint256 _value)\n        public\n        returns (bool success)\n    {\n        allowed[msg.sender][_spender] = _value;\n        emit Approval(msg.sender, _spender, _value);\n        return true;\n    }\n\n    function allowance(address _owner, address _spender)\n        view\n        public\n        returns (uint256 remaining)\n    {\n        return allowed[_owner][_spender];\n    }\n\n    function balanceOf(address _owner)\n        view\n        public\n        returns (uint256 balance)\n    {\n        return balances[_owner];\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/README.md",
    "content": "This directory contains various Solidity contract source code files\nthat are compiled as part of the regular tests.\n\nThese contracts are externally contributed and their presence in this\nrepository does not make any statement about their quality or usefulness.\n"
  },
  {
    "path": "test/compilationTests/corion/LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    {one line to give the program's name and a brief idea of what it does.}\n    Copyright (C) {year}  {name of author}\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    {project}  Copyright (C) {year}  {fullname}\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "test/compilationTests/corion/README.md",
    "content": "CORION contracts, originally from\n\nhttps://github.com/CORIONplatform/solidity\n"
  },
  {
    "path": "test/compilationTests/corion/announcementTypes.sol",
    "content": "pragma solidity >=0.0;\n\ncontract announcementTypes {\n\n    enum announcementType {\n        /*\n            type of announcements\n        */\n        newModule,\n        dropModule,\n        replaceModule,\n        replaceModuleHandler,\n        question,\n        transactionFeeRate,\n        transactionFeeMin,\n        transactionFeeMax,\n        transactionFeeBurn,\n        providerPublicFunds,\n        providerPrivateFunds,\n        providerPrivateClientLimit,\n        providerPublicMinRate,\n        providerPublicMaxRate,\n        providerPrivateMinRate,\n        providerPrivateMaxRate,\n        providerGasProtect,\n        providerInterestMinFunds,\n        providerRentRate,\n        schellingRoundBlockDelay,\n        schellingCheckRounds,\n        schellingCheckAboves,\n        schellingRate,\n        publisherMinAnnouncementDelay,\n        publisherOppositeRate\n    }\n}"
  },
  {
    "path": "test/compilationTests/corion/ico.sol",
    "content": "pragma solidity >=0.0;\n\nimport \"./safeMath.sol\";\nimport \"./token.sol\";\nimport \"./premium.sol\";\nimport \"./moduleHandler.sol\";\n\ncontract ico is safeMath {\n\n    struct icoLevels_s {\n        uint256 block;\n        uint8 rate;\n    }\n    struct affiliate_s {\n        uint256 weight;\n        uint256 paid;\n    }\n    struct interest_s {\n        uint256 amount;\n        bool empty;\n    }\n    struct brought_s {\n        uint256 eth;\n        uint256 cor;\n        uint256 corp;\n    }\n\n    uint256 constant oneSegment = 40320;\n\n    address payable public owner;\n    address payable public tokenAddr;\n    address payable public premiumAddr;\n    uint256 public startBlock;\n    uint256 public icoDelay;\n    address payable public foundationAddress;\n    address public icoEtcPriceAddr;\n    uint256 public icoExchangeRate;\n    uint256 public icoExchangeRateSetBlock;\n    uint256 constant icoExchangeRateM = 1e4;\n    uint256 constant interestOnICO   = 25;\n    uint256 constant interestOnICOM  = 1e3;\n    uint256 constant interestBlockDelay = 720;\n    uint256 constant exchangeRateDelay = 125;\n    bool public aborted;\n    bool public closed;\n    icoLevels_s[] public icoLevels;\n    mapping (address => affiliate_s) public affiliate;\n    mapping (address => brought_s) public brought;\n    mapping (address => mapping(uint256 => interest_s)) public interestDB;\n    uint256 public totalMint;\n    uint256 public totalPremiumMint;\n\n    constructor(address payable foundation, address priceSet, uint256 exchangeRate, uint256 startBlockNum, address[] memory genesisAddr, uint256[] memory genesisValue) {\n        /*\n            Installation function.\n\n            @foundation     The ETC address of the foundation\n            @priceSet       The address which will be able to make changes on the rate later on.\n            @exchangeRate   The current ETC/USD rate multiplied by 1e4. For example: 2.5 USD/ETC = 25000\n            @startBlockNum  The height (level) of the beginning of the ICO. If it is 0 then it will be the current array’s height.\n            @genesisAddr    Array of Genesis addresses\n            @genesisValue   Array of balance of genesis addresses\n        */\n        foundationAddress = foundation;\n        icoExchangeRate = exchangeRate;\n        icoExchangeRateSetBlock = block.number + exchangeRateDelay;\n        icoEtcPriceAddr = priceSet;\n        owner = payable(msg.sender);\n        if ( startBlockNum > 0 ) {\n            require( startBlockNum >= block.number );\n            startBlock = startBlockNum;\n        } else {\n            startBlock = block.number;\n        }\n        icoLevels.push(icoLevels_s(startBlock + oneSegment * 1, 3));\n        icoLevels.push(icoLevels_s(startBlock + oneSegment / 7, 5));\n        icoLevels.push(icoLevels_s(startBlock, 10));\n        icoDelay = startBlock + oneSegment * 3;\n        for ( uint256 a=0 ; a<genesisAddr.length ; a++ ) {\n            interestDB[genesisAddr[a]][0].amount = genesisValue[a];\n        }\n    }\n\n    function ICObonus() public view returns(uint256 bonus) {\n        /*\n            Query of current bonus\n\n            @bonus  Bonus %\n        */\n        for ( uint8 a=0 ; a<icoLevels.length ; a++ ) {\n            if ( block.number > icoLevels[a].block ) {\n                return icoLevels[a].rate;\n            }\n        }\n    }\n\n    function setInterestDB(address addr, uint256 balance) external returns(bool success) {\n        /*\n            Setting interest database. It can be requested by Token contract only.\n            A database has to be built in order  that after ICO closed everybody can get their compound interest on their capital accumulated\n\n            @addr       Sender\n            @balance    Quantity\n\n            @success    Was the process successful or not\n        */\n        require( msg.sender == tokenAddr );\n        uint256 _num = (block.number - startBlock) / interestBlockDelay;\n        interestDB[addr][_num].amount = balance;\n        if ( balance == 0 ) {\n            interestDB[addr][_num].empty = true;\n        }\n        return true;\n    }\n\n    function checkInterest(address addr) public view returns(uint256 amount) {\n        /*\n            Query of compound interest\n\n            @addr       Address\n\n            @amount     Amount of compound interest\n        */\n        uint256 _lastBal;\n        uint256 _tamount;\n        bool _empty;\n        interest_s memory _idb;\n        uint256 _to = (block.number - startBlock) / interestBlockDelay;\n\n        if ( _to == 0 || aborted ) { return 0; }\n\n        for ( uint256 r=0 ; r < _to ; r++ ) {\n            if ( r*interestBlockDelay+startBlock >= icoDelay ) { break; }\n            _idb = interestDB[addr][r];\n            if ( _idb.amount > 0 ) {\n                if ( _empty ) {\n                    _lastBal = _idb.amount + amount;\n                } else {\n                    _lastBal = _idb.amount;\n                }\n            }\n            if ( _idb.empty ) {\n                _lastBal = 0;\n                _empty = _idb.empty;\n            }\n            _lastBal += _tamount;\n            _tamount = _lastBal * interestOnICO / interestOnICOM / 100;\n            amount += _tamount;\n        }\n    }\n\n    function getInterest(address beneficiary) external {\n        /*\n            Request of  compound interest. This is deleted  from the database after the ICO closed and following the query of the compound interest.\n\n            @beneficiary    Beneficiary who will receive the interest\n        */\n        uint256 _lastBal;\n        uint256 _tamount;\n        uint256 _amount;\n        bool _empty;\n        interest_s memory _idb;\n        address _addr = beneficiary;\n        uint256 _to = (block.number - startBlock) / interestBlockDelay;\n        if ( _addr == address(0x00) ) { _addr = msg.sender; }\n\n        require( block.number > icoDelay );\n        require( ! aborted );\n\n        for ( uint256 r=0 ; r < _to ; r++ ) {\n            if ( r*interestBlockDelay+startBlock >= icoDelay ) { break; }\n            _idb = interestDB[msg.sender][r];\n            if ( _idb.amount > 0 ) {\n                if ( _empty ) {\n                    _lastBal = _idb.amount + _amount;\n                } else {\n                    _lastBal = _idb.amount;\n                }\n            }\n            if ( _idb.empty ) {\n                _lastBal = 0;\n                _empty = _idb.empty;\n            }\n            _lastBal += _tamount;\n            _tamount = _lastBal * interestOnICO / interestOnICOM / 100;\n            _amount += _tamount;\n            delete interestDB[msg.sender][r];\n        }\n\n        require( _amount > 0 );\n        token(tokenAddr).mint(_addr, _amount);\n    }\n\n    function setICOEthPrice(uint256 value) external {\n        /*\n            Setting of the ICO ETC USD rates which can only be called by a pre-defined address.\n            After this function is completed till the call of the next function (which is at least an exchangeRateDelay array) this rate counts.\n            With this process avoiding the sudden rate changes.\n\n            @value  The ETC/USD rate multiplied by 1e4. For example: 2.5 USD/ETC = 25000\n        */\n        require( isICO() );\n        require( icoEtcPriceAddr == msg.sender );\n        require( icoExchangeRateSetBlock < block.number);\n        icoExchangeRateSetBlock = block.number + exchangeRateDelay;\n        icoExchangeRate = value;\n    }\n\n    function extendICO() external {\n        /*\n            Extend the period of the ICO with one segment.\n\n            It is only possible during the ICO and only callable by the owner.\n        */\n        require( isICO() );\n        require( msg.sender == owner );\n        icoDelay += oneSegment;\n    }\n\n    function closeICO() external {\n        /*\n            Closing the ICO.\n            It is only possible when the ICO period passed and only by the owner.\n            The 96% of the whole amount of the token is generated to the address of the foundation.\n            Ethers which are situated in this contract will be sent to the address of the foundation.\n        */\n        require( msg.sender == owner );\n        require( block.number > icoDelay );\n        require( ! closed );\n        closed = true;\n        require( ! aborted );\n        require( token(tokenAddr).mint(foundationAddress, token(tokenAddr).totalSupply() * 96 / 100) );\n        require( premium(premiumAddr).mint(foundationAddress, totalMint / 5000 - totalPremiumMint) );\n        require( foundationAddress.send(address(this).balance) );\n        require( token(tokenAddr).closeIco() );\n        require( premium(premiumAddr).closeIco() );\n    }\n\n    function abortICO() external {\n        /*\n            Withdrawal of the ICO.\n            It is only possible during the ICO period.\n            Only callable by the owner.\n            After this process only the receiveFunds function will be available for the customers.\n        */\n        require( isICO() );\n        require( msg.sender == owner );\n        aborted = true;\n    }\n\n    function connectTokens(address payable tokenContractAddr, address payable premiumContractAddr) external {\n        /*\n            Installation function which joins the two token contracts with this contract.\n            Only callable by the owner\n\n            @tokenContractAddr      Address of the corion token contract.\n            @premiumContractAddr    Address of the corion premium token contract\n        */\n        require( msg.sender == owner );\n        require( tokenAddr == address(0x00) && premiumAddr == address(0x00) );\n        tokenAddr = tokenContractAddr;\n        premiumAddr = premiumContractAddr;\n    }\n\n    function receiveFunds() external {\n        /*\n            Refund the amount which was purchased during the ICO period.\n            This one is only callable if the ICO is withdrawn.\n            In this case the address gets back the 90% of the amount which was spent for token during the ICO period.\n        */\n        require( aborted );\n        require( brought[msg.sender].eth > 0 );\n        uint256 _val = brought[msg.sender].eth * 90 / 100;\n        delete brought[msg.sender];\n        require( payable(msg.sender).send(_val) );\n    }\n\n    receive () external payable {\n        /*\n            Callback function. Simply calls the buy function as a beneficiary and there is no affiliate address.\n            If they call the contract without any function then this process will be taken place.\n        */\n        require( isICO() );\n        require( buy(payable(msg.sender), address(0x00)) );\n    }\n\n    function buy(address payable beneficiaryAddress, address affiliateAddress) public payable returns (bool success) {\n        /*\n            Buying a token\n\n            If there is not at least 0.2 ether balance on the beneficiaryAddress then the amount of the ether which was intended for the purchase will be reduced by 0.2 and that will be sent to the address of the beneficiary.\n            From the remaining amount calculate the reward with the help of the getIcoReward function.\n            Only that affiliate address is valid which has some token on it’s account.\n            If there is a valid affiliate address then calculate and credit the reward as well in the following way:\n            With more than 1e12 token contract credit 5% reward based on the calculation that how many tokens did they buy when he was added as an affiliate.\n                More than 1e11 token: 4%\n                More than 1e10 token: 3%\n                More than 1e9 token: 2% below 1%\n            @beneficiaryAddress     The address of the accredited where the token will be sent.\n            @affiliateAddress        The address of the person who offered who will get the referral reward. It can not be equal with the beneficiaryAddress.\n        */\n        require( isICO() );\n        if ( beneficiaryAddress == address(0x00)) { beneficiaryAddress = payable(msg.sender); }\n        if ( beneficiaryAddress == affiliateAddress ) {\n            affiliateAddress = address(0x00);\n        }\n        uint256 _value = msg.value;\n        if ( beneficiaryAddress.balance < 0.2 ether ) {\n            require( beneficiaryAddress.send(0.2 ether) );\n            _value = safeSub(_value, 0.2 ether);\n        }\n        uint256 _reward = getIcoReward(_value);\n        require( _reward > 0 );\n        require( token(tokenAddr).mint(beneficiaryAddress, _reward) );\n        brought[beneficiaryAddress].eth = safeAdd(brought[beneficiaryAddress].eth, _value);\n        brought[beneficiaryAddress].cor = safeAdd(brought[beneficiaryAddress].cor, _reward);\n        totalMint = safeAdd(totalMint, _reward);\n        require( foundationAddress.send(_value * 10 / 100) );\n        uint256 extra;\n        if ( affiliateAddress != address(0x00) && ( brought[affiliateAddress].eth > 0 || interestDB[affiliateAddress][0].amount > 0 ) ) {\n            affiliate[affiliateAddress].weight = safeAdd(affiliate[affiliateAddress].weight, _reward);\n            extra = affiliate[affiliateAddress].weight;\n            uint256 rate;\n            if (extra >= 1e12) {\n                rate = 5;\n            } else if (extra >= 1e11) {\n                rate = 4;\n            } else if (extra >= 1e10) {\n                rate = 3;\n            } else if (extra >= 1e9) {\n                rate = 2;\n            } else {\n                rate = 1;\n            }\n            extra = safeSub(extra * rate / 100, affiliate[affiliateAddress].paid);\n            affiliate[affiliateAddress].paid = safeAdd(affiliate[affiliateAddress].paid, extra);\n            token(tokenAddr).mint(affiliateAddress, extra);\n        }\n        checkPremium(beneficiaryAddress);\n        emit EICO(beneficiaryAddress, _reward, affiliateAddress, extra);\n        return true;\n    }\n\n    function checkPremium(address owner) internal {\n        /*\n            Crediting the premium token\n\n            @owner The corion token balance of this address will be set based on the calculation which shows that how many times can be the amount of the purchased tokens divided by 5000. So after each 5000 token we give 1 premium token.\n        */\n        uint256 _reward = (brought[owner].cor / 5e9) - brought[owner].corp;\n        if ( _reward > 0 ) {\n            require( premium(premiumAddr).mint(owner, _reward) );\n            brought[owner].corp = safeAdd(brought[owner].corp, _reward);\n            totalPremiumMint = safeAdd(totalPremiumMint, _reward);\n        }\n    }\n\n    function getIcoReward(uint256 value) public view returns (uint256 reward) {\n        /*\n            Expected token volume at token purchase\n\n            @value The amount of ether for the purchase\n            @reward Amount of the token\n                x = (value * 1e6 * USD_ETC_exchange rate / 1e4 / 1e18) * bonus percentage\n                2.700000 token = (1e18 * 1e6 * 22500 / 1e4 / 1e18) * 1.20\n        */\n        reward = (value * 1e6 * icoExchangeRate / icoExchangeRateM / 1 ether) * (ICObonus() + 100) / 100;\n        if ( reward < 5e6) { return 0; }\n    }\n\n    function isICO() public view returns (bool success) {\n        return startBlock <= block.number && block.number <= icoDelay && ( ! aborted ) && ( ! closed );\n    }\n\n    event EICO(address indexed Address, uint256 indexed value, address Affiliate, uint256 AffiliateValue);\n}\n"
  },
  {
    "path": "test/compilationTests/corion/module.sol",
    "content": "pragma solidity >=0.0;\n\ncontract abstractModuleHandler {\n    function transfer(address payable from, address payable to, uint256 value, bool fee) external returns (bool success) {}\n    function balanceOf(address payable owner) public view returns (bool success, uint256 value) {}\n}\n\ncontract module {\n    /*\n        Module\n    */\n\n    enum status {\n        New,\n        Connected,\n        Disconnected,\n        Disabled\n    }\n\n    status public moduleStatus;\n    uint256 public disabledUntil;\n    address payable public moduleHandlerAddress;\n\n    function disableModule(bool forever) external onlyForModuleHandler returns (bool success) {\n        _disableModule(forever);\n        return true;\n    }\n    function _disableModule(bool forever) internal {\n        /*\n            Disable the module for one week, if the forever true then for forever.\n            This function calls the Publisher module.\n\n            @forever    For forever or not\n        */\n        if ( forever ) { moduleStatus = status.Disabled; }\n        else { disabledUntil = block.number + 5760; }\n    }\n\n    function replaceModuleHandler(address payable newModuleHandlerAddress) external onlyForModuleHandler returns (bool success) {\n        _replaceModuleHandler(newModuleHandlerAddress);\n        return true;\n    }\n    function _replaceModuleHandler(address payable newModuleHandlerAddress) internal {\n        /*\n            Replace the ModuleHandler address.\n            This function calls the Publisher module.\n\n            @newModuleHandlerAddress    New module handler address\n        */\n        require( moduleStatus == status.Connected );\n        moduleHandlerAddress = newModuleHandlerAddress;\n    }\n\n    function connectModule() virtual external onlyForModuleHandler returns (bool success) {\n        _connectModule();\n        return true;\n    }\n    function _connectModule() internal {\n        /*\n            Registering and/or connecting-to ModuleHandler.\n            This function is called by ModuleHandler load or by Publisher.\n        */\n        require( moduleStatus == status.New );\n        moduleStatus = status.Connected;\n    }\n\n    function disconnectModule() external onlyForModuleHandler returns (bool success) {\n        _disconnectModule();\n        return true;\n    }\n    function _disconnectModule() internal {\n        /*\n            Disconnect the module from the ModuleHandler.\n            This function calls the Publisher module.\n        */\n        require( moduleStatus != status.New && moduleStatus != status.Disconnected );\n        moduleStatus = status.Disconnected;\n    }\n\n    function replaceModule(address payable newModuleAddress) virtual external onlyForModuleHandler returns (bool success) {\n        _replaceModule(newModuleAddress);\n        return true;\n    }\n    function _replaceModule(address payable newModuleAddress) internal {\n        /*\n            Replace the module for an another new module.\n            This function calls the Publisher module.\n            We send every Token and ether to the new module.\n\n            @newModuleAddress   New module handler address\n        */\n        require( moduleStatus != status.New && moduleStatus != status.Disconnected);\n        (bool _success, uint256 _balance) = abstractModuleHandler(moduleHandlerAddress).balanceOf(payable(this));\n        require( _success );\n        if ( _balance > 0 ) {\n            require( abstractModuleHandler(moduleHandlerAddress).transfer(payable(this), newModuleAddress, _balance, false) );\n        }\n        if ( address(this).balance > 0 ) {\n            require( newModuleAddress.send(address(this).balance) );\n        }\n        moduleStatus = status.Disconnected;\n    }\n\n    function transferEvent(address payable from, address payable to, uint256\nvalue) virtual external onlyForModuleHandler returns (bool success) {\n        return true;\n    }\n    function newSchellingRoundEvent(uint256 roundID, uint256 reward) virtual external onlyForModuleHandler returns (bool success) {\n        return true;\n    }\n\n    function registerModuleHandler(address payable _moduleHandlerAddress) internal {\n        /*\n            Module constructor function for registering ModuleHandler address.\n        */\n        moduleHandlerAddress = _moduleHandlerAddress;\n    }\n    function isModuleHandler(address payable addr) internal returns (bool ret) {\n        /*\n            Test for ModuleHandler address.\n            If the module is not connected then returns always false.\n\n            @addr   Address to check\n\n            @ret    This is the module handler address or not\n        */\n        if ( moduleHandlerAddress == address(0x00) ) { return true; }\n        if ( moduleStatus != status.Connected ) { return false; }\n        return addr == moduleHandlerAddress;\n    }\n    function isActive() public view returns (bool success, bool active) {\n        /*\n            Check self for ready for functions or not.\n\n            @success    Function call was successful or not\n            @active     Ready for functions or not\n        */\n        return (true, moduleStatus == status.Connected && block.number >= disabledUntil);\n    }\n    modifier onlyForModuleHandler() {\n        require( msg.sender == moduleHandlerAddress );\n        _;\n    }\n    receive() external payable {\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/corion/moduleHandler.sol",
    "content": "pragma solidity >=0.0;\n\nimport \"./module.sol\";\nimport \"./announcementTypes.sol\";\nimport \"./multiOwner.sol\";\n\nimport \"./publisher.sol\";\nimport \"./token.sol\";\nimport \"./provider.sol\";\nimport \"./schelling.sol\";\nimport \"./premium.sol\";\nimport \"./ico.sol\";\n\ncontract abstractModule {\n    function connectModule() external returns (bool success) {}\n    function disconnectModule() external returns (bool success) {}\n    function replaceModule(address addr) external returns (bool success) {}\n    function disableModule(bool forever) external returns (bool success) {}\n    function isActive() public view returns (bool success) {}\n    function replaceModuleHandler(address newHandler) external returns (bool success) {}\n    function transferEvent(address from, address to, uint256 value) external returns (bool success) {}\n    function newSchellingRoundEvent(uint256 roundID, uint256 reward) external returns (bool success) {}\n}\n\ncontract moduleHandler is multiOwner, announcementTypes {\n\n    struct modules_s {\n        address payable addr;\n        bytes32 name;\n        bool schellingEvent;\n        bool transferEvent;\n    }\n\n    modules_s[] public modules;\n    address public foundationAddress;\n    uint256 debugModeUntil = block.number + 1000000;\n\n\n    constructor(address[] memory newOwners) multiOwner(newOwners) {}\n    function load(address payable foundation, bool forReplace, address payable Token, address payable Premium, address payable Publisher, address payable Schelling, address payable Provider) public {\n        /*\n            Loading modulest to ModuleHandler.\n\n            This module can be called only once and only by the owner, if every single module and its database are already put on the blockchain.\n            If forReaplace is true, than the ModuleHandler will be replaced. Before the publishing of its replace, the new contract must be already on the blockchain.\n\n            @foundation     Address of foundation.\n            @forReplace     Is it for replace or not. If not, it will be connected to the module.\n            @Token          address of token.\n            @Publisher      address of publisher.\n            @Schelling      address of Schelling.\n            @Provider       address of provider\n        */\n        require( owners[msg.sender] );\n        require( modules.length == 0 );\n        foundationAddress = foundation;\n        addModule( modules_s(Token,      keccak256('Token'),      false, false),  ! forReplace);\n        addModule( modules_s(Premium,    keccak256('Premium'),    false, false),  ! forReplace);\n        addModule( modules_s(Publisher,  keccak256('Publisher'),  false, true),   ! forReplace);\n        addModule( modules_s(Schelling,  keccak256('Schelling'),  false, true),   ! forReplace);\n        addModule( modules_s(Provider,   keccak256('Provider'),   true, true),    ! forReplace);\n    }\n    function addModule(modules_s memory input, bool call) internal {\n        /*\n            Inside function for registration of the modules in the database.\n            If the call is false, won't happen any direct call.\n\n            @input  _Structure of module.\n            @call   Is connect to the module or not.\n        */\n        if ( call ) { require( abstractModule(input.addr).connectModule() ); }\n        (bool success, bool found, uint256 id) = getModuleIDByAddress(input.addr);\n        require( success && ! found );\n        (success, found, id) = getModuleIDByHash(input.name);\n        require( success && ! found );\n        (success, found, id) = getModuleIDByAddress(address(0x00));\n        require( success );\n        if ( ! found ) {\n            id = modules.length;\n            modules.push();\n        }\n        modules[id] = input;\n    }\n    function getModuleAddressByName(string memory name) public view returns( bool success, bool found, address addr ) {\n        /*\n            Search by name for module. The result is an Ethereum address.\n\n            @name       Name of module.\n            @addr       Address of module.\n            @found      Is there any result.\n            @success    Was the transaction successful or not.\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByName(name);\n        if ( _success && _found ) { return (true, true, modules[_id].addr); }\n        return (true, false, address(0x00));\n    }\n    function getModuleIDByHash(bytes32 hashOfName) public view returns( bool success, bool found, uint256 id ) {\n        /*\n            Search by hash of name in the module array. The result is an index array.\n\n            @name       Name of module.\n            @id         Index of module.\n            @found      Was there any result or not.\n        */\n        for ( uint256 a=0 ; a<modules.length ; a++ ) {\n            if ( modules[a].name == hashOfName ) {\n                return (true, true, a);\n            }\n        }\n        return (true, false, 0);\n    }\n    function getModuleIDByName(string memory name) public view returns( bool success, bool found, uint256 id ) {\n        /*\n            Search by name for module. The result is an index array.\n\n            @name       Name of module.\n            @id         Index of module.\n            @found      Was there any result or not.\n        */\n        bytes32 _name = keccak256(bytes(name));\n        for ( uint256 a=0 ; a<modules.length ; a++ ) {\n            if ( modules[a].name == _name ) {\n                return (true, true, a);\n            }\n        }\n        return (true, false, 0);\n    }\n    function getModuleIDByAddress(address addr) public view returns( bool success, bool found, uint256 id ) {\n        /*\n            Search by ethereum address for module. The result is an index array.\n\n            @name       Name of module.\n            @id         Index of module.\n            @found      Was there any result or not.\n        */\n        for ( uint256 a=0 ; a<modules.length ; a++ ) {\n            if ( modules[a].addr == addr ) {\n                return (true, true, a);\n            }\n        }\n        return (true, false, 0);\n    }\n    function replaceModule(string calldata name, address payable addr, bool callCallback) external returns (bool success) {\n        /*\n            Module replace, can be called only by the Publisher contract.\n\n            @name           Name of module.\n            @addr           Address of module.\n            @bool           Was there any result or not.\n            @callCallback   Call the replaceable module to confirm replacement or not.\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender);\n        require( _success );\n        if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) {\n            require( block.number < debugModeUntil );\n            if ( ! insertAndCheckDo(calcDoHash(\"replaceModule\", keccak256(abi.encodePacked(name, addr, callCallback)))) ) {\n                return true;\n            }\n        }\n        (_success, _found, _id) = getModuleIDByName(name);\n        require( _success && _found );\n        if ( callCallback ) {\n            require( abstractModule(modules[_id].addr).replaceModule(addr) );\n        }\n        require( abstractModule(addr).connectModule() );\n        modules[_id].addr = addr;\n        return true;\n    }\n\n    function callReplaceCallback(string calldata moduleName, address newModule) external returns (bool success) {\n        require( block.number < debugModeUntil );\n        if ( ! insertAndCheckDo(calcDoHash(\"callReplaceCallback\", keccak256(abi.encodePacked(moduleName, newModule)))) ) {\n            return true;\n        }\n        (bool _success, bool _found, uint256 _id) = getModuleIDByName(moduleName);\n        require( _success);\n        require( abstractModule(modules[_id].addr).replaceModule(newModule) );\n        return true;\n    }\n\n    function newModule(string calldata name, address payable addr, bool schellingEvent, bool transferEvent) external returns (bool success) {\n        /*\n            Adding new module to the database. Can be called only by the Publisher contract.\n\n            @name               Name of module.\n            @addr               Address of module.\n            @schellingEvent     Gets it new Schelling round notification?\n            @transferEvent      Gets it new transaction notification?\n            @bool               Was there any result or not.\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender);\n        require( _success );\n        if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) {\n            require( block.number < debugModeUntil );\n            if ( ! insertAndCheckDo(calcDoHash(\"newModule\", keccak256(abi.encodePacked(name, addr, schellingEvent, transferEvent)))) ) {\n                return true;\n            }\n        }\n        addModule( modules_s(addr, keccak256(bytes(name)), schellingEvent, transferEvent), true);\n        return true;\n    }\n    function dropModule(string calldata name, bool callCallback) external returns (bool success) {\n        /*\n            Deleting module from the database. Can be called only by the Publisher contract.\n\n            @name           Name of module to delete.\n            @bool           Was the function successful?\n            @callCallback   Call the replaceable module to confirm replacement or not.\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender);\n        require( _success );\n        if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) {\n            require( block.number < debugModeUntil );\n            if ( ! insertAndCheckDo(calcDoHash(\"replaceModule\", keccak256(abi.encodePacked(name, callCallback)))) ) {\n                return true;\n            }\n        }\n        (_success, _found, _id) = getModuleIDByName(name);\n        require( _success && _found );\n        if( callCallback ) {\n            abstractModule(modules[_id].addr).disableModule(true);\n        }\n        delete modules[_id];\n        return true;\n    }\n\n    function callDisableCallback(string calldata moduleName) external returns (bool success) {\n        require( block.number < debugModeUntil );\n        if ( ! insertAndCheckDo(calcDoHash(\"callDisableCallback\", keccak256(bytes(moduleName)))) ) {\n            return true;\n        }\n        (bool _success, bool _found, uint256 _id) = getModuleIDByName(moduleName);\n        require( _success);\n        require( abstractModule(modules[_id].addr).disableModule(true) );\n        return true;\n    }\n\n    function broadcastTransfer(address from, address to, uint256 value) external returns (bool success) {\n        /*\n            Announcing transactions for the modules.\n\n            Can be called only by the token module.\n            Only the configured modules get notifications.( transferEvent )\n\n            @from       from who.\n            @to         to who.\n            @value      amount.\n            @bool       Was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender);\n        require( _success && _found && modules[_id].name == keccak256('Token') );\n        for ( uint256 a=0 ; a<modules.length ; a++ ) {\n            if ( modules[a].transferEvent && abstractModule(modules[a].addr).isActive() ) {\n                require( abstractModule(modules[a].addr).transferEvent(from, to, value) );\n            }\n        }\n        return true;\n    }\n    function broadcastSchellingRound(uint256 roundID, uint256 reward) external returns (bool success) {\n        /*\n            Announcing new Schelling round for the modules.\n            Can be called only by the Schelling module.\n            Only the configured modules get notifications( schellingEvent ).\n\n            @roundID        Number of Schelling round.\n            @reward         Coin emission in this Schelling round.\n            @bool           Was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender);\n        require( _success && _found && modules[_id].name == keccak256('Schelling') );\n        for ( uint256 a=0 ; a<modules.length ; a++ ) {\n            if ( modules[a].schellingEvent && abstractModule(modules[a].addr).isActive() ) {\n                require( abstractModule(modules[a].addr).newSchellingRoundEvent(roundID, reward) );\n            }\n        }\n        return true;\n    }\n    function replaceModuleHandler(address newHandler) external returns (bool success) {\n        /*\n            Replacing ModuleHandler.\n\n            Can be called only by the publisher.\n            Every module will be informed about the ModuleHandler replacement.\n\n            @newHandler     Address of the new ModuleHandler.\n            @bool           Was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender);\n        require( _success );\n        if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) {\n            require( block.number < debugModeUntil );\n            if ( ! insertAndCheckDo(calcDoHash(\"replaceModuleHandler\", keccak256(abi.encodePacked(newHandler)))) ) {\n                return true;\n            }\n        }\n        for ( uint256 a=0 ; a<modules.length ; a++ ) {\n            require( abstractModule(modules[a].addr).replaceModuleHandler(newHandler) );\n        }\n        return true;\n    }\n    function balanceOf(address owner) public view returns (bool success, uint256 value) {\n        /*\n            Query of token balance.\n\n            @owner     address\n            @value      balance.\n            @success    was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByName('Token');\n        require( _success && _found );\n        return (true, token(modules[_id].addr).balanceOf(owner));\n    }\n    function totalSupply() public view returns (bool success, uint256 value) {\n        /*\n            Query of the whole token amount.\n\n            @value      amount.\n            @success    was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByName('Token');\n        require( _success && _found );\n        return (true, token(modules[_id].addr).totalSupply());\n    }\n    function isICO() public view returns (bool success, bool ico) {\n        /*\n            Query of ICO state\n\n            @ico        Is ICO in progress?.\n            @success    was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByName('Token');\n        require( _success && _found );\n        return (true, token(modules[_id].addr).isICO());\n    }\n    function getCurrentSchellingRoundID() public view returns (bool success, uint256 round) {\n        /*\n            Query of number of the actual Schelling round.\n\n            @round      Schelling round.\n            @success    was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByName('Schelling');\n        require( _success && _found );\n        return (true, schelling(modules[_id].addr).getCurrentSchellingRoundID());\n    }\n    function mint(address to, uint256 value) external returns (bool success) {\n        /*\n            Token emission request. Can be called only by the provider.\n\n            @to         Place of new token\n            @value      Token amount\n\n            @success    Was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender);\n        require( _success && _found && modules[_id].name == keccak256('Provider') );\n        (_success, _found, _id) = getModuleIDByName('Token');\n        require( _success && _found );\n        require( token(modules[_id].addr).mint(to, value) );\n        return true;\n    }\n    function transfer(address from, address to, uint256 value, bool fee) external returns (bool success) {\n        /*\n            Token transaction request. Can be called only by a module.\n\n            @from       from who.\n            @to         To who.\n            @value      Token amount.\n            @fee        Transaction fee will be charged or not?\n            @success    Was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender);\n        require( _success && _found );\n        (_success, _found, _id) = getModuleIDByName('Token');\n        require( _success && _found );\n        require( token(modules[_id].addr).transferFromByModule(from, to, value, fee) );\n        return true;\n    }\n    function processTransactionFee(address from, uint256 value) external returns (bool success) {\n        /*\n            Token transaction fee. Can be called only by the provider.\n\n            @from       From who.\n            @value      Token amount.\n            @success    Was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender);\n        require( _success && _found && modules[_id].name == keccak256('Provider') );\n        (_success, _found, _id) = getModuleIDByName('Token');\n        require( _success && _found );\n        require( token(modules[_id].addr).processTransactionFee(from, value) );\n        return true;\n    }\n    function burn(address from, uint256 value) external returns (bool success) {\n        /*\n            Token burn. Can be called only by Schelling.\n\n            @from       From who.\n            @value      Token amount.\n            @success    Was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender);\n        require( _success && _found && modules[_id].name == keccak256('Schelling') );\n        (_success, _found, _id) = getModuleIDByName('Token');\n        require( _success && _found );\n        require( token(modules[_id].addr).burn(from, value) );\n        return true;\n    }\n    function configureModule(string calldata moduleName, announcementType aType, uint256 value) external returns (bool success) {\n        /*\n            Changing configuration of a module. Can be called only by Publisher or while debug mode by owners.\n\n            @moduleName Module name which will be configured\n            @aType      Type of variable (announcementType).\n            @value      New value\n            @success    Was the function successful?\n        */\n        (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender);\n        require( _success );\n        if ( ! ( _found && modules[_id].name == keccak256('Publisher') )) {\n            require( block.number < debugModeUntil );\n            if ( ! insertAndCheckDo(calcDoHash(\"configureModule\", keccak256(abi.encodePacked(moduleName, aType, value)))) ) {\n                return true;\n            }\n        }\n        (_success, _found, _id) = getModuleIDByName(moduleName);\n        require( _success && _found );\n        require( schelling(modules[_id].addr).configure(aType, value) );\n        return true;\n    }\n    function freezing(bool forever) external {\n        /*\n            Freezing CORION Platform. Can be called only by the owner.\n            Freeze can not be recalled!\n\n            @forever    Is it forever or not?\n        */\n        require( owners[msg.sender] );\n        if ( forever ) {\n            if ( ! insertAndCheckDo(calcDoHash(\"freezing\", keccak256(abi.encodePacked(forever)))) ) {\n                return;\n            }\n        }\n        for ( uint256 a=0 ; a<modules.length ; a++ ) {\n            require( abstractModule(modules[a].addr).disableModule(forever) );\n        }\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/corion/multiOwner.sol",
    "content": "pragma solidity >=0.0;\n\nimport \"./safeMath.sol\";\n\ncontract multiOwner is safeMath {\n\n    mapping(address => bool) public owners;\n    uint256 public ownerCount;\n\n    mapping(bytes32 => address[]) public doDB;\n\n    /*\n        Constructor\n    */\n    constructor(address[] memory newOwners) {\n        for ( uint256 a=0 ; a<newOwners.length ; a++ ) {\n            _addOwner(newOwners[a]);\n        }\n    }\n    /*\n        Externals\n    */\n    function insertOwner(address addr) external {\n        if ( insertAndCheckDo(calcDoHash(\"insertOwner\", keccak256(abi.encodePacked(addr)))) ) {\n            _addOwner(addr);\n        }\n    }\n    function dropOwner(address addr) external {\n        if ( insertAndCheckDo(calcDoHash(\"dropOwner\", keccak256(abi.encodePacked(addr)))) ) {\n            _delOwner(addr);\n        }\n    }\n    function cancelDo(bytes32 doHash) external {\n        if ( insertAndCheckDo(calcDoHash(\"cancelDo\", doHash)) ) {\n            delete doDB[doHash];\n        }\n    }\n    /*\n        Constants\n    */\n    function ownersForChange() public view returns (uint256 owners) {\n        return ownerCount * 75 / 100;\n    }\n    function calcDoHash(string memory job, bytes32 data) public pure returns (bytes32 hash) {\n        return keccak256(abi.encodePacked(job, data));\n    }\n    function validDoHash(bytes32 doHash) public view returns (bool valid) {\n        return doDB[doHash].length > 0;\n    }\n    /*\n        Internals\n    */\n    function insertAndCheckDo(bytes32 doHash) internal returns (bool success) {\n        require( owners[msg.sender] );\n        if (doDB[doHash].length >= ownersForChange()) {\n            delete doDB[doHash];\n            return true;\n        }\n        for ( uint256 a=0 ; a<doDB[doHash].length ; a++ ) {\n            require( doDB[doHash][a] != msg.sender );\n        }\n        if ( doDB[doHash].length+1 >= ownersForChange() ) {\n            delete doDB[doHash];\n            return true;\n        } else {\n            doDB[doHash].push(msg.sender);\n            return false;\n        }\n    }\n    /*\n        Privates\n    */\n    function _addOwner(address addr) private {\n        if ( owners[addr] ) { return; }\n        owners[addr] = true;\n        ownerCount = safeAdd(ownerCount, 1);\n    }\n    function _delOwner(address addr) private {\n        if ( ! owners[addr] ) { return; }\n        delete owners[addr];\n        ownerCount = safeSub(ownerCount, 1);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/corion/owned.sol",
    "content": "pragma solidity >=0.0;\n\ncontract ownedDB {\n    address private owner;\n\n    function replaceOwner(address newOwner) external returns(bool) {\n        /*\n            Owner replace.\n\n            @newOwner   Address of new owner.\n        */\n        require( isOwner() );\n        owner = newOwner;\n        return true;\n    }\n\n    function isOwner() internal returns(bool) {\n        /*\n            Check of owner address.\n\n            @bool   Owner has called the contract or not\n        */\n        if ( owner == address(0x00) ) {\n            return true;\n        }\n        return owner == msg.sender;\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/corion/premium.sol",
    "content": "pragma solidity >=0.0;\n\nimport \"./safeMath.sol\";\nimport \"./tokenDB.sol\";\nimport \"./module.sol\";\n\ncontract thirdPartyPContractAbstract {\n    function receiveCorionPremiumToken(address, uint256, bytes calldata) external returns (bool, uint256) {}\n    function approvedCorionPremiumToken(address, uint256, bytes calldata) external returns (bool) {}\n}\n\ncontract ptokenDB is tokenDB {}\n\n/**\n *\n * @title Corion Platform Premium Token\n * @author iFA @ Corion Platform\n *\n */\ncontract premium is module, safeMath {\n    function replaceModule(address payable addr) external override returns (bool success) {\n        require( super.isModuleHandler(payable(msg.sender)) );\n        require( db.replaceOwner(addr) );\n        super._replaceModule(addr);\n        return true;\n    }\n    modifier isReady {\n        (bool _success, bool _active) = super.isActive();\n        require( _success && _active );\n        _;\n    }\n\n    string public name = \"Corion Premium\";\n    string public symbol = \"CORP\";\n    uint8 public decimals = 0;\n\n    address public icoAddr;\n    tokenDB public db;\n    bool    public  isICO;\n\n    mapping(address => bool) public genesis;\n\n    constructor(bool forReplace, address payable moduleHandler, address dbAddress, address icoContractAddr, address[] memory genesisAddr, uint256[] memory genesisValue) {\n        /*\n            Setup function.\n            If an ICOaddress is defined then the balance of the genesis addresses will be set as well.\n\n            @forReplace         This address will be replaced with the old one or not.\n            @moduleHandler      Modulhandler’s address\n            @dbAddress          Address of database\n            @icoContractAddr    Address of ico contract.\n            @genesisAddr        Array of the genesis addresses.\n            @genesisValue       Array of the balance of the genesis addresses\n        */\n        super.registerModuleHandler(moduleHandler);\n        require( dbAddress != address(0x00) );\n        db = ptokenDB(dbAddress);\n        if ( ! forReplace ) {\n            require( db.replaceOwner(address(this)) );\n            isICO = true;\n            icoAddr = icoContractAddr;\n            assert( genesisAddr.length == genesisValue.length );\n            for ( uint256 a=0 ; a<genesisAddr.length ; a++ ) {\n                genesis[genesisAddr[a]] = true;\n                require( db.increase(genesisAddr[a], genesisValue[a]) );\n                emit Mint(genesisAddr[a], genesisValue[a]);\n            }\n        }\n    }\n\n    function closeIco() external returns (bool success) {\n        /*\n            Finishing the ICO. Can be invited only by an ICO contract.\n\n            @success    If the function was successful.\n        */\n        require( isICO );\n        isICO = false;\n        return true;\n    }\n\n    /**\n     * @notice `msg.sender` approves `spender` to spend `amount` tokens on its behalf.\n     * @param spender The address of the account able to transfer the tokens\n     * @param amount The amount of tokens to be approved for transfer\n     * @param nonce The transaction count of the authorised address\n     * @return success True if the approval was successful\n     */\n    function approve(address spender, uint256 amount, uint256 nonce) isReady external returns (bool success) {\n        /*\n            Authorize another address to use an exact amount of the principal’s balance.\n\n            @spender    Address of authorised party\n            @amount     Token quantity\n            @nonce      Transaction count\n\n            @success    Was the Function successful?\n        */\n        _approve(spender, amount, nonce);\n        return true;\n    }\n\n    /**\n     * @notice `msg.sender` approves `spender` to spend `amount` tokens on its behalf and notify the spender from your approve with your `extraData` data.\n     * @param spender The address of the account able to transfer the tokens\n     * @param amount The amount of tokens to be approved for transfer\n     * @param nonce The transaction count of the authorised address\n     * @param extraData Data to give forward to the receiver\n     * @return success True if the approval was successful\n     */\n    function approveAndCall(address spender, uint256 amount, uint256 nonce, bytes calldata extraData) isReady external returns (bool success) {\n        /*\n            Authorize another address to use an exact amount of the principal’s balance.\n            After the transaction the approvedCorionPremiumToken function of the address will be called with the given data.\n\n            @spender        Authorized address\n            @amount         Token quantity\n            @extraData      Extra data to be received by the receiver\n            @nonce          Transaction count\n\n            @success         Was the Function successful?\n        */\n        _approve(spender, amount, nonce);\n        require( thirdPartyPContractAbstract(spender).approvedCorionPremiumToken(msg.sender, amount, extraData) );\n        return true;\n    }\n\n    function _approve(address spender, uint256 amount, uint256 nonce) isReady internal {\n        /*\n            Inner function to authorize another address to use an exact amount of the principal’s balance.\n            If the transaction count not match the authorise fails.\n\n            @spender    Address of authorised party\n            @amount     Token quantity\n            @nonce      Transaction count\n        */\n        require( msg.sender != spender );\n        require( db.balanceOf(msg.sender) >= amount );\n        require( db.setAllowance(msg.sender, spender, amount, nonce) );\n        emit Approval(msg.sender, spender, amount);\n    }\n\n    function allowance(address owner, address spender) public view returns (uint256 remaining, uint256 nonce) {\n        /*\n            Get the quantity of tokens given to be used\n\n            @owner          Authorising address\n            @spender        Authorised address\n\n            @remaining      Tokens to be spent\n            @nonce          Transaction count\n        */\n        (bool _success, uint256 _remaining, uint256 _nonce) = db.getAllowance(owner, spender);\n        require( _success );\n        return (_remaining, _nonce);\n    }\n\n    /**\n     * @notice Send `amount` Corion tokens to `to` from `msg.sender`\n     * @param to The address of the recipient\n     * @param amount The amount of tokens to be transferred\n     * @return success Whether the transfer was successful or not\n     */\n    function transfer(address to, uint256 amount) isReady external returns (bool success) {\n        /*\n            Launch a transaction where the token is sent from the sender’s address to the receiver’s address.\n            Transaction fee is going to be added as well.\n            If the receiver is not a natural address but also a person then she/he will be invited as well.\n\n            @to         For who\n            @amount     Amount\n\n            @success    Was the function successful?\n        */\n        bytes memory _data;\n        if ( isContract(to) ) {\n            transferToContract(msg.sender, to, amount, _data);\n        } else {\n            _transfer(msg.sender, to, amount);\n        }\n        emit Transfer(msg.sender, to, amount, _data);\n        return true;\n    }\n\n    /**\n     * @notice Send `amount` tokens to `to` from `from` on the condition it is approved by `from`\n     * @param from The address holding the tokens being transferred\n     * @param to The address of the recipient\n     * @param amount The amount of tokens to be transferred\n     * @return success True if the transfer was successful\n     */\n    function transferFrom(address from, address to, uint256 amount) isReady external returns (bool success) {\n        /*\n            Launch a transaction where we transfer from a given address to another one. It can only be called by an address which was allowed before.\n            Transaction fee will be charged too.\n            If the receiver is not a natural address but also a person then she/he will be invited as well\n\n            @from       From who?\n            @to         For who?\n            @amount     Amount\n\n            @success    If the function was successful.\n        */\n        if ( from != msg.sender ) {\n            (bool _success, uint256 _remaining, uint256 _nonce) = db.getAllowance(from, msg.sender);\n            require( _success );\n            _remaining = safeSub(_remaining, amount);\n            _nonce = safeAdd(_nonce, 1);\n            require( db.setAllowance(from, msg.sender, _remaining, _nonce) );\n            emit AllowanceUsed(msg.sender, from, amount);\n        }\n        bytes memory _data;\n        if ( isContract(to) ) {\n            transferToContract(from, to, amount, _data);\n        } else {\n            _transfer( from, to, amount);\n        }\n        emit Transfer(from, to, amount, _data);\n        return true;\n    }\n\n    /**\n     * @notice Send `amount` Corion tokens to `to` from `msg.sender` and notify the receiver from your transaction with your `extraData` data\n     * @param to The contract address of the recipient\n     * @param amount The amount of tokens to be transferred\n     * @param extraData Data to give forward to the receiver\n     * @return success Whether the transfer was successful or not\n     */\n    function transfer(address to, uint256 amount, bytes calldata extraData) isReady external returns (bool success) {\n        /*\n            Launch a transaction where we transfer from a given address to another one.\n            After the transaction the approvedCorionPremiumToken function of the receiver’s address is going to be called with the given data.\n\n            @to         For who?\n            @amount     Amount\n            @extraData  Extra data that will be given to the receiver\n\n            @success    If the function was successful.\n        */\n        if ( isContract(to) ) {\n            transferToContract(msg.sender, to, amount, extraData);\n        } else {\n            _transfer( msg.sender, to, amount);\n        }\n        emit Transfer(msg.sender, to, amount, extraData);\n        return true;\n    }\n\n    function transferToContract(address from, address to, uint256 amount, bytes memory extraData) internal {\n        /*\n            Inner function in order to transact a contract.\n\n            @to             For who?\n            @amount         Amount\n            @extraData      Extra data that will be given to the receiver\n        */\n        _transfer(from, to, amount);\n        (bool _success, uint256 _back) = thirdPartyPContractAbstract(to).receiveCorionPremiumToken(from, amount, extraData);\n        require( _success );\n        require( amount > _back );\n        if ( _back > 0 ) {\n            _transfer(to, from, _back);\n        }\n    }\n\n    function _transfer(address from, address to, uint256 amount) isReady internal {\n        /*\n            Inner function to launch a transaction.\n            During the ICO transactions are only possible from the genesis address.\n            0xa636a97578d26a3b76b060bbc18226d954cf3757 address is blacklisted.\n\n            @from      From how?\n            @to        For who?\n            @amount    Amount\n        */\n        require( from != address(0x00) && to != address(0x00) && to != 0xa636A97578d26A3b76B060Bbc18226d954cf3757 );\n        require( ( ! isICO) || genesis[from] );\n        require( db.decrease(from, amount) );\n        require( db.increase(to, amount) );\n    }\n\n    function mint(address owner, uint256 value) external returns (bool success) {\n        /*\n            Generating tokens. It can be called only by ICO contract.\n\n            @owner      Address\n            @value      Amount.\n\n            @success    Was the Function successful?\n        */\n        require( msg.sender == icoAddr || isICO );\n        _mint(owner, value);\n        return true;\n    }\n\n    function _mint(address owner, uint256 value) isReady internal {\n        /*\n            Inner function to create a token.\n\n            @owner     Address of crediting the token.\n            @value     Amount\n        */\n        require( db.increase(owner, value) );\n        emit Mint(owner, value);\n    }\n\n    function isContract(address addr) internal returns (bool success) {\n        /*\n            Inner function in order to check if the given address is a natural address or a contract.\n\n            @addr       The address which is needed to be checked.\n\n            @success    Is the address contract or not\n        */\n        uint256 _codeLength;\n        assembly {\n            _codeLength := extcodesize(addr)\n        }\n        return _codeLength > 0;\n    }\n\n    function balanceOf(address owner) public view returns (uint256 value) {\n        /*\n            Token balance query\n\n            @owner      Address\n            @value      Balance of address\n        */\n        return db.balanceOf(owner);\n    }\n\n    function totalSupply() public view returns (uint256 value) {\n        /*\n            Total token quantity query\n\n            @value      Total token quantity\n        */\n        return db.totalSupply();\n    }\n\n    event AllowanceUsed(address indexed spender, address indexed owner, uint256 indexed value);\n    event Mint(address indexed addr, uint256 indexed value);\n    event Burn(address indexed addr, uint256 indexed value);\n    event Approval(address indexed _owner, address indexed _spender, uint256 _value);\n    event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes _extraData);\n}\n"
  },
  {
    "path": "test/compilationTests/corion/provider.sol",
    "content": "pragma solidity >=0.0;\n\nimport \"./module.sol\";\nimport \"./moduleHandler.sol\";\nimport \"./safeMath.sol\";\nimport \"./announcementTypes.sol\";\n\ncontract provider is module, safeMath, announcementTypes {\n    /*\n        module callbacks\n    */\n    function connectModule() external override returns (bool success) {\n        require( super.isModuleHandler(payable(msg.sender)) );\n        super._connectModule();\n        (bool _success, uint256 currentSchellingRound) = moduleHandler(moduleHandlerAddress).getCurrentSchellingRoundID();\n        require( _success );\n        return true;\n    }\n    function transferEvent(address payable from, address payable to, uint256 value) external override returns (bool success) {\n        /*\n            Transaction completed. This function is only available for the modulehandler.\n            It should be checked if the sender or the acceptor does not connect to the provider or it is not a provider itself if so than the change should be recorded.\n\n            @from       From whom?\n            @to         For who?\n            @value      amount\n            @bool       Was the function successful?\n        */\n        require( super.isModuleHandler(payable(msg.sender)) );\n        transferEvent_(from, value, true);\n        transferEvent_(to, value, false);\n        return true;\n    }\n    function newSchellingRoundEvent(uint256 roundID, uint256 reward) external override returns (bool success) {\n        /*\n            New schelling round. This function is only available for the moduleHandler.\n            We are recording the new schelling round and we are storing the whole current quantity of the tokens.\n            We generate a reward quantity of tokens directed to the providers address. The collected interest will be transferred from this contract.\n\n            @roundID        Number of the schelling round.\n            @reward         token emission\n            @bool           Was the function successful?\n        */\n        require( super.isModuleHandler(payable(msg.sender)) );\n        globalFunds[roundID].reward = reward;\n        globalFunds[roundID].supply = globalFunds[roundID-1].supply;\n        currentSchellingRound = roundID;\n        require( moduleHandler(moduleHandlerAddress).mint(address(this), reward) );\n        return true;\n    }\n    modifier isReady {\n        (bool _success, bool _active) = super.isActive();\n        require( _success && _active );\n        _;\n    }\n    /*\n        Provider module\n    */\n    uint256 private minFundsForPublic   = 3000;\n    uint256 private minFundsForPrivate  = 8000;\n    uint256 private privateProviderLimit  = 250;\n    uint8 private publicMinRate     = 30;\n    uint8 private privateMinRate    = 0;\n    uint8 private publicMaxRate     = 70;\n    uint8 private privateMaxRate    = 100;\n    uint256 private gasProtectMaxRounds = 630;\n    uint256 private interestMinFunds = 25000;\n    uint256 private rentRate = 20;\n\n    struct _rate {\n        uint8 value;\n        bool valid;\n    }\n    struct __providers {\n        address admin;\n        string name;\n        string website;\n        string country;\n        string info;\n        bool isForRent;\n        mapping(uint256 => _rate) rateHistory;\n        uint8 currentRate;\n        bool priv;\n        uint256 clientsCount;\n        mapping(address => bool) allowedUsers;\n        mapping(uint256 => uint256) supply;\n        uint256 lastSupplyID;\n        mapping(uint256 => uint256) ownSupply;\n        uint256 lastOwnSupplyID;\n        uint256 paidUpTo;\n        uint8 lastPaidRate;\n        uint256 create;\n        uint256 close;\n        bool valid;\n    }\n    struct _providers {\n        mapping(uint256 => __providers) data;\n        uint256 currentHeight;\n    }\n    mapping(address => _providers) private providers;\n\n    struct _globalFunds {\n        uint256 reward;\n        uint256 supply;\n    }\n    mapping(uint256 => _globalFunds) private globalFunds;\n\n    struct _client{\n        address providerAddress;\n        uint256 providerHeight;\n        uint256 providerConnected;\n        uint8 lastRate;\n        mapping(uint256 => uint256) supply;\n        uint256 lastSupplyID;\n        uint256 paidUpTo;\n    }\n    mapping(address => _client) private clients;\n\n    uint256 private currentSchellingRound = 1;\n\n    constructor(address payable _moduleHandler) {\n        /*\n            Install function.\n\n            @_moduleHandler     Address of the moduleHandler.\n        */\n        super.registerModuleHandler(_moduleHandler);\n    }\n    function configure(announcementType a, uint256 b) external returns(bool) {\n        /*\n            Configuration of the provider. Can be invited just by the moduleHandler.\n\n            @a      Type of the setting\n            @b      value\n        */\n        require( super.isModuleHandler(payable(msg.sender)) );\n        if      ( a == announcementType.providerPublicFunds )          { minFundsForPublic = b; }\n        else if ( a == announcementType.providerPrivateFunds )         { minFundsForPrivate = b; }\n        else if ( a == announcementType.providerPrivateClientLimit )   { privateProviderLimit = b; }\n        else if ( a == announcementType.providerPublicMinRate )        { publicMinRate = uint8(b); }\n        else if ( a == announcementType.providerPublicMaxRate )        { publicMaxRate = uint8(b); }\n        else if ( a == announcementType.providerPrivateMinRate )       { privateMinRate = uint8(b); }\n        else if ( a == announcementType.providerPrivateMaxRate )       { privateMaxRate = uint8(b); }\n        else if ( a == announcementType.providerGasProtect )           { gasProtectMaxRounds = b; }\n        else if ( a == announcementType.providerInterestMinFunds )     { interestMinFunds = b; }\n        else if ( a == announcementType.providerRentRate )             { rentRate = b; }\n        else { return false; }\n        return true;\n    }\n    function getUserDetails(address payable addr, uint256 schellingRound) public view returns (address ProviderAddress, uint256 ProviderHeight, uint256 ConnectedOn, uint256 value) {\n        /*\n            Collecting the data of the client.\n\n            @addr               Address of the client.\n            @schellingRound     Number of the schelling round. If it is not defined then the current one.\n            @ProviderAddress    Address of the provider the one where connected to\n            @ProviderHeight     The height (level) of the provider where is connected.\n            @ConnectedOn        Time of connection\n            @value              Quantity of the client’s token\n        */\n        if ( schellingRound == 0 ) {\n            schellingRound = currentSchellingRound;\n        }\n        if ( clients[addr].providerAddress != address(0x00) ) {\n            ProviderAddress = clients[addr].providerAddress;\n            ProviderHeight  = clients[addr].providerHeight;\n            ConnectedOn     = clients[addr].providerConnected;\n            value           = clients[addr].supply[schellingRound];\n        }\n    }\n    function rightForInterest(uint256 value, bool priv) internal view returns (bool) {\n        /*\n            the share from the token emission.\n            In case is a private provider it has to be checked if it has enough connected capital to be able to accept share from the token emission.\n            The provider’s account counts as a capital for the emission as well.\n\n            @value      amount of the connected capital\n            @priv       Is the provider private or not?\n            @bool       Gets the share from the token emission.\n        */\n        if ( priv ) {\n            return ( value >= interestMinFunds );\n        }\n        return true;\n    }\n    function setRightForInterest(uint256 oldValue, uint256 newValue, bool priv) internal {\n        /*\n            It checks if the provider has enough connected capital to be able to get from the token emission.\n            In case the provider is not able to get the share from the token emission then the connected capital will not count to the value of the globalFunds, to the current schelling round.\n\n            @oldValue       old\n            @newValue       new\n            @priv           Is the provider private?\n        */\n        bool a = rightForInterest(oldValue, priv);\n        bool b = rightForInterest(newValue, priv);\n        if ( a && b ) {\n            globalFunds[currentSchellingRound].supply = globalFunds[currentSchellingRound].supply - oldValue + newValue;\n        } else if ( a && ! b ) {\n            globalFunds[currentSchellingRound].supply -= oldValue;\n        } else if ( ! a && b ) {\n            globalFunds[currentSchellingRound].supply += newValue;\n        }\n    }\n    function checkCorrectRate(bool priv, uint8 rate) internal returns(bool) {\n        /*\n            Inner function which checks if the amount of interest what is given by the provider is fits to the criteria.\n\n            @priv       Is the provider private or not?\n            @rate       Percentage/rate of the interest\n            @bool       Correct or not?\n        */\n        return ( ! priv && ( rate >= publicMinRate && rate <= publicMaxRate ) ) ||\n                ( priv && ( rate >= privateMinRate && rate <= privateMaxRate ) );\n    }\n    function createProvider(bool priv, string calldata name, string calldata website, string calldata country, string calldata info, uint8 rate, bool isForRent, address payable admin) isReady external {\n        /*\n            Creating a provider.\n            During the ICO its not allowed to create provider.\n            To one address only one provider can belong to.\n            Address, how is connected to the provider can not create a provider.\n            For opening, has to have enough capital.\n            All the functions of the provider except of the closing are going to be handled by the admin.\n            The provider can be start as a rent as well, in this case the isForRent has to be true/correct. In case it runs as a rent the 20% of the profit will belong to the leser and the rest goes to the admin.\n\n            @priv           Privat szolgaltato e. Is private provider?\n            @name           Provider’s name.\n            @website        Provider’s website\n            @country        Provider’s country\n            @info           Provider’s short introduction.\n            @rate           Rate of the emission what is going to be transferred to the client by the provider.\n            @isForRent      is for Rent or not?\n            @admin          The admin’s address\n        */\n        require( ! providers[msg.sender].data[providers[msg.sender].currentHeight].valid );\n        require( clients[msg.sender].providerAddress == address(0x00) );\n        require( ! checkICO() );\n        if ( priv ) {\n            require( getTokenBalance(msg.sender) >= minFundsForPrivate );\n        } else {\n            require( getTokenBalance(msg.sender) >= minFundsForPublic );\n        }\n        require( checkCorrectRate(priv, rate) );\n\n        providers[msg.sender].currentHeight++;\n        uint256 currHeight = providers[msg.sender].currentHeight;\n        providers[msg.sender].data[currHeight].valid           = true;\n        if ( admin == address(0x00) ) {\n            providers[msg.sender].data[currHeight].admin      = msg.sender;\n        } else {\n            providers[msg.sender].data[currHeight].admin      = admin;\n        }\n        providers[msg.sender].data[currHeight].name            = name;\n        providers[msg.sender].data[currHeight].website         = website;\n        providers[msg.sender].data[currHeight].isForRent       = isForRent;\n        providers[msg.sender].data[currHeight].country         = country;\n        providers[msg.sender].data[currHeight].info            = info;\n        providers[msg.sender].data[currHeight].currentRate     = rate;\n        providers[msg.sender].data[currHeight].create          = block.timestamp;\n        providers[msg.sender].data[currHeight].lastPaidRate    = rate;\n        providers[msg.sender].data[currHeight].priv            = priv;\n        providers[msg.sender].data[currHeight].lastSupplyID    = currentSchellingRound;\n        providers[msg.sender].data[currHeight].paidUpTo        = currentSchellingRound;\n        if ( priv ) {\n            providers[msg.sender].data[currHeight].supply[currentSchellingRound]        = getTokenBalance(msg.sender);\n            providers[msg.sender].data[currHeight].ownSupply[currentSchellingRound]     = getTokenBalance(msg.sender);\n            providers[msg.sender].data[currHeight].lastOwnSupplyID                      = currentSchellingRound;\n        } else {\n            delete providers[msg.sender].data[currHeight].supply[currentSchellingRound];\n        }\n        emit EProviderOpen(msg.sender, currHeight);\n    }\n    function setProviderDetails(address payable addr, string calldata website, string calldata country, string calldata info, uint8 rate, address payable admin) isReady external {\n        /*\n            Modifying the data of the provider.\n            This can only be invited by the provider’s admin.\n            The emission rate is only valid for the next schelling round for this one it is not.\n            The admin can only be changed by the address of the provider.\n\n            @addr               Address of the provider.\n            @website            Website.\n            @admin              The new address of the admin. If we do not want to set it then we should enter 0X00.\n            @country            Country\n            @info               Short intro.\n            @rate               Rate of the emission what will be given to the client.\n        */\n        uint256 currHeight = providers[addr].currentHeight;\n        require( providers[addr].data[currHeight].valid );\n        require( checkCorrectRate(providers[addr].data[currHeight].priv, rate) );\n        require( providers[addr].data[currHeight].admin == msg.sender || msg.sender == addr );\n        if ( admin != address(0x00) ) {\n            require( msg.sender == addr );\n            providers[addr].data[currHeight].admin = admin;\n        }\n        providers[addr].data[currHeight].rateHistory[currentSchellingRound] = _rate( rate, true );\n        providers[addr].data[currHeight].website         = website;\n        providers[addr].data[currHeight].country         = country;\n        providers[addr].data[currHeight].info            = info;\n        providers[addr].data[currHeight].currentRate     = rate;\n        emit EProviderDetailsChanged(addr, currHeight, website, country, info, rate, admin);\n    }\n    function getProviderInfo(address addr, uint256 height) public view returns (string memory name, string memory website, string memory country, string memory info, uint256 create) {\n        /*\n            for the infos of the provider.\n            In case the height is unknown then the system will use the last known height.\n\n            @addr           Addr of the provider\n            @height         Height\n            @name           Name of the provider.\n            @website        Website of the provider.\n            @country        Country of the provider.\n            @info           Short intro of the provider.\n            @create         Timestamp of creating the provider\n        */\n        if ( height == 0 ) {\n            height = providers[addr].currentHeight;\n        }\n        name            = providers[addr].data[height].name;\n        website         = providers[addr].data[height].website;\n        country         = providers[addr].data[height].country;\n        info            = providers[addr].data[height].info;\n        create          = providers[addr].data[height].create;\n    }\n    function getProviderDetails(address payable addr, uint256 height) public view returns (uint8 rate, bool isForRent, uint256 clientsCount, bool priv, bool getInterest, bool valid) {\n        /*\n            Asking for the data of the provider.\n            In case the height is unknown then the system will use the last known height.\n\n            @addr           Address of the provider\n            @height         Height\n            @rate           The rate of the emission which will be transferred to the client.\n            @isForRent      Rent or not.\n            @clientsCount   Number of the clients.\n            @priv           Private or not?\n            @getInterest    Does get from the token emission?\n            @valid          Is an active provider?\n        */\n        if ( height == 0 ) {\n            height = providers[addr].currentHeight;\n        }\n        rate            = providers[addr].data[height].currentRate;\n        isForRent       = providers[addr].data[height].isForRent;\n        clientsCount    = providers[addr].data[height].clientsCount;\n        priv            = providers[addr].data[height].priv;\n        getInterest     = rightForInterest(getProviderCurrentSupply(addr), providers[addr].data[height].priv );\n        valid           = providers[addr].data[height].valid;\n    }\n    function getProviderCurrentSupply(address addr) internal view returns (uint256) {\n        /*\n            Inner function for polling the current height and the current quantity of the connected capital of the schelling round.\n\n            @addr           Provider’s address.\n            @uint256        Amount of the connected capital\n        */\n        return providers[addr].data[providers[addr].currentHeight].supply[currentSchellingRound];\n    }\n    function closeProvider() isReady external {\n        /*\n            Closing and deactivating the provider.\n            It is only possible to close that active provider which is owned by the sender itself after calling the whole share of the emission.\n            Whom were connected to the provider those clients will have to disconnect after they’ve called their share of emission which was not called before.\n        */\n        uint256 currHeight = providers[msg.sender].currentHeight;\n        require( providers[msg.sender].data[currHeight].valid );\n        require( providers[msg.sender].data[currHeight].paidUpTo == currentSchellingRound );\n\n        providers[msg.sender].data[currHeight].valid = false;\n        providers[msg.sender].data[currHeight].close = currentSchellingRound;\n        setRightForInterest(getProviderCurrentSupply(msg.sender), 0, providers[msg.sender].data[currHeight].priv);\n        emit EProviderClose(msg.sender, currHeight);\n    }\n    function allowUsers(address provider, address[] calldata addr) isReady external {\n        /*\n            Permission of the user to be able to connect to the provider.\n            This can only be invited by the provider’s admin.\n            With this kind of call only 100 address can be permitted.\n\n            @addr       Array of the addresses for whom the connection is allowed.\n        */\n        uint256 currHeight = providers[provider].currentHeight;\n        require( providers[provider].data[currHeight].valid );\n        require( providers[provider].data[currHeight].priv );\n        require( providers[provider].data[currHeight].admin == msg.sender );\n        require( addr.length <= 100 );\n\n        for ( uint256 a=0 ; a<addr.length ; a++ ) {\n            providers[provider].data[currHeight].allowedUsers[addr[a]] = true;\n        }\n    }\n    function disallowUsers(address provider, address[] calldata addr) isReady external {\n        /*\n            Disable of the user not to be able to connect to the provider.\n            It is can called only for the admin of the provider.\n            With this kind of call only 100 address can be permitted.\n\n            @addr      Array of the addresses for whom the connection is allowed.\n        */\n        uint256 currHeight = providers[provider].currentHeight;\n        require( providers[provider].data[currHeight].valid );\n        require( providers[provider].data[currHeight].priv );\n        require( providers[provider].data[currHeight].admin == msg.sender );\n        require( addr.length <= 100 );\n\n        for ( uint256 a=0 ; a<addr.length ; a++ ) {\n            delete providers[provider].data[currHeight].allowedUsers[addr[a]];\n        }\n    }\n    function joinProvider(address provider) isReady external {\n        /*\n            Connection to the provider.\n            Providers can not connect to other providers.\n            If is a client at any provider, then it is not possible to connect to other provider one.\n            It is only possible to connect to valid and active providers.\n            If is an active provider then the client can only connect, if address is permitted at the provider (Whitelist).\n            At private providers, the number of the client is restricted. If it reaches the limit no further clients are allowed to connect.\n            This process has a transaction fee based on the senders whole token quantity.\n\n            @provider       Address of the provider.\n        */\n        uint256 currHeight = providers[provider].currentHeight;\n        require( ! providers[msg.sender].data[currHeight].valid );\n        require( clients[msg.sender].providerAddress == address(0x00) );\n        require( providers[provider].data[currHeight].valid );\n        if ( providers[provider].data[currHeight].priv ) {\n            require( providers[provider].data[currHeight].allowedUsers[msg.sender] &&\n                     providers[provider].data[currHeight].clientsCount < privateProviderLimit );\n        }\n        uint256 bal = getTokenBalance(msg.sender);\n        require( moduleHandler(moduleHandlerAddress).processTransactionFee(msg.sender, bal) );\n\n        checkFloatingSupply(provider, currHeight, false, bal);\n        providers[provider].data[currHeight].clientsCount++;\n        clients[msg.sender].providerAddress = provider;\n        clients[msg.sender].providerHeight = currHeight;\n        clients[msg.sender].supply[currentSchellingRound] = bal;\n        clients[msg.sender].lastSupplyID = currentSchellingRound;\n        clients[msg.sender].paidUpTo = currentSchellingRound;\n        clients[msg.sender].lastRate = providers[provider].data[currHeight].currentRate;\n        clients[msg.sender].providerConnected = block.timestamp;\n        emit ENewClient(msg.sender, provider, currHeight, bal);\n    }\n    function partProvider() isReady external {\n        /*\n            Disconnecting from the provider.\n            Before disconnecting we should poll our share from the token emission even if there was nothing factually.\n            It is only possible to disconnect those providers who were connected by us before.\n        */\n        address provider = clients[msg.sender].providerAddress;\n        require( provider != address(0x00) );\n        uint256 currHeight = clients[msg.sender].providerHeight;\n        bool providerHasClosed = false;\n        if ( providers[provider].data[currHeight].close > 0 ) {\n            providerHasClosed = true;\n            require( clients[msg.sender].paidUpTo == providers[provider].data[currHeight].close );\n        } else {\n            require( clients[msg.sender].paidUpTo == currentSchellingRound );\n        }\n\n        uint256 bal = getTokenBalance(msg.sender);\n        if ( ! providerHasClosed ) {\n            providers[provider].data[currHeight].clientsCount--;\n            checkFloatingSupply(provider, currHeight, true, bal);\n        }\n        delete clients[msg.sender].providerAddress;\n        delete clients[msg.sender].providerHeight;\n        delete clients[msg.sender].lastSupplyID;\n        delete clients[msg.sender].paidUpTo;\n        delete clients[msg.sender].lastRate;\n        delete clients[msg.sender].providerConnected;\n        emit EClientLost(msg.sender, provider, currHeight, bal);\n    }\n    function checkReward(address addr) public returns (uint256 reward) {\n        /*\n            Polling the share from the token emission for clients and for providers.\n\n            @addr           The address want to check.\n            @reward         Accumulated amount.\n        */\n        if ( providers[addr].data[providers[addr].currentHeight].valid ) {\n            uint256 a;\n            (reward, a) = getProviderReward(addr, 0);\n        } else if ( clients[addr].providerAddress != address(0x00) ) {\n            reward = getClientReward(0);\n        }\n    }\n    function getReward(address beneficiary, uint256 limit, address provider) isReady external returns (uint256 reward) {\n        /*\n            Polling the share from the token emission token emission for clients and for providers.\n\n            It is optionally possible to give an address of a beneficiary for whom we can transfer the accumulated amount. In case we don’t enter any address then the amount will be transferred to the caller’s address.\n            As the interest should be checked at each schelling round in order to get the share from that so to avoid the overflow of the gas the number of the check-rounds should be limited.\n            Opcionalisan megadhato az ellenorzes koreinek szama. It is possible to enter optionally the number of the check-rounds.  If it is 0 then it is automatic.\n            Provider variable should only be entered if the real owner of the provider is not the caller’s address.\n            In case the client/provider was far behind then it is possible that this function should be called several times to check the total generated schelling rounds and to collect the share.\n            If is neither a client nor a provider then the function is not available.\n            The tokens will be sent to the beneficiary from the address of the provider without any transaction fees.\n\n            @beneficiary        Address of the beneficiary\n            @limit              Quota of the check-rounds.\n            @provider           Address of the provider\n            @reward             Accumulated amount from the previous rounds.\n        */\n        uint256 _limit = limit;\n        address _beneficiary = beneficiary;\n        address _provider = provider;\n        if ( _limit == 0 ) { _limit = gasProtectMaxRounds; }\n        if ( _beneficiary == address(0x00) ) { _beneficiary = msg.sender; }\n        if ( _provider == address(0x00) ) { _provider = msg.sender; }\n        uint256 clientReward;\n        uint256 providerReward;\n        if ( providers[_provider].data[providers[_provider].currentHeight].valid ) {\n            require( providers[_provider].data[providers[_provider].currentHeight].admin == msg.sender || msg.sender == _provider );\n            (providerReward, clientReward) = getProviderReward(_provider, _limit);\n        } else if ( clients[msg.sender].providerAddress != address(0x00) ) {\n            clientReward = getClientReward(_limit);\n        } else {\n            revert();\n        }\n        if ( clientReward > 0 ) {\n            require( moduleHandler(moduleHandlerAddress).transfer(address(this), _beneficiary, clientReward, false) );\n        }\n        if ( providerReward > 0 ) {\n            require( moduleHandler(moduleHandlerAddress).transfer(address(this), provider, providerReward, false) );\n        }\n        emit EReward(msg.sender, provider, clientReward, providerReward);\n    }\n    function getClientReward(uint256 limit) internal returns (uint256 reward) {\n        /*\n            Inner function for the client in order to collect the share from the token emission\n\n            @limit          Quota of checking the schelling-rounds.\n            @reward         Collected token amount from the checked rounds.\n        */\n        uint256 value;\n        uint256 steps;\n        address provAddr;\n        uint256 provHeight;\n        bool interest = false;\n        uint256 a;\n        uint8 rate = clients[msg.sender].lastRate;\n        for ( a = (clients[msg.sender].paidUpTo + 1) ; a <= currentSchellingRound ; a++ ) {\n            if (globalFunds[a].reward > 0 && globalFunds[a].supply > 0) {\n                provAddr = clients[msg.sender].providerAddress;\n                provHeight = clients[msg.sender].providerHeight;\n                if ( providers[provAddr].data[provHeight].rateHistory[a].valid ) {\n                    rate = providers[provAddr].data[provHeight].rateHistory[a].value;\n                }\n                if ( rate > 0 ) {\n                    if ( a > providers[provAddr].data[provHeight].lastSupplyID ) {\n                        interest = rightForInterest(providers[provAddr].data[provHeight].supply[providers[provAddr].data[provHeight].lastSupplyID], providers[provAddr].data[provHeight].priv);\n                    } else {\n                        interest = rightForInterest(providers[provAddr].data[provHeight].supply[a], providers[provAddr].data[provHeight].priv);\n                    }\n                    if ( interest ) {\n                        if ( limit > 0 && steps > limit ) {\n                            a--;\n                            break;\n                        }\n                        if (clients[msg.sender].lastSupplyID < a) {\n                            value = clients[msg.sender].supply[clients[msg.sender].lastSupplyID];\n                        } else {\n                            value = clients[msg.sender].supply[a];\n                        }\n                        if ( globalFunds[a].supply > 0) {\n                            reward += value * globalFunds[a].reward / globalFunds[a].supply * uint256(rate) / 100;\n                        }\n                        steps++;\n                    }\n                }\n            }\n        }\n        clients[msg.sender].lastRate = rate;\n        clients[msg.sender].paidUpTo = a-1;\n    }\n    function getProviderReward(address addr, uint256 limit) internal returns (uint256 providerReward, uint256 adminReward) {\n        /*\n            Inner function for the provider in order to collect the share from the token emission\n            @addr               Address of the provider.\n            @limit              Quota of the check-rounds.\n            @providerReward     The reward of the provider’s address from the checked rounds.\n            @adminReward        Admin’s reward from the checked rounds.\n        */\n        uint256 reward;\n        uint256 ownReward;\n        uint256 value;\n        uint256 steps;\n        uint256 currHeight = providers[addr].currentHeight;\n        uint256 LTSID = providers[addr].data[currHeight].lastSupplyID;\n        uint256 a;\n        uint8 rate = providers[addr].data[currHeight].lastPaidRate;\n        for ( a = (providers[addr].data[currHeight].paidUpTo + 1) ; a <= currentSchellingRound ; a++ ) {\n            if (globalFunds[a].reward > 0 && globalFunds[a].supply > 0) {\n                if ( providers[addr].data[currHeight].rateHistory[a].valid ) {\n                    rate = providers[addr].data[currHeight].rateHistory[a].value;\n                }\n                if ( rate > 0 ) {\n                    if ( ( a > LTSID && rightForInterest(providers[addr].data[currHeight].supply[LTSID], providers[addr].data[currHeight].priv) ||\n                        rightForInterest(providers[addr].data[currHeight].supply[a], providers[addr].data[currHeight].priv) ) ) {\n                        if ( limit > 0 && steps > limit ) {\n                            a--;\n                            break;\n                        }\n                        if ( LTSID < a ) {\n                            value = providers[addr].data[currHeight].supply[LTSID];\n                        } else {\n                            value = providers[addr].data[currHeight].supply[a];\n                        }\n                        if ( globalFunds[a].supply > 0) {\n                            reward += value * globalFunds[a].reward / globalFunds[a].supply * ( 100 - uint256(rate) ) / 100;\n                            if ( providers[addr].data[currHeight].priv ) {\n                                LTSID = providers[addr].data[currHeight].lastOwnSupplyID;\n                                if ( LTSID < a ) {\n                                    value = providers[addr].data[currHeight].ownSupply[LTSID];\n                                } else {\n                                    value = providers[addr].data[currHeight].ownSupply[a];\n                                }\n                                ownReward += value * globalFunds[a].reward / globalFunds[a].supply;\n                            }\n                        }\n                        steps++;\n                    }\n                }\n            }\n        }\n        providers[addr].data[currHeight].lastPaidRate = uint8(rate);\n        providers[addr].data[currHeight].paidUpTo = a-1;\n        if ( providers[addr].data[currHeight].isForRent ) {\n            providerReward = reward * rentRate / 100;\n            adminReward = reward - providerReward;\n            if ( providers[addr].data[currHeight].priv ) { providerReward += ownReward; }\n        } else {\n            providerReward = reward + ownReward;\n        }\n    }\n    function checkFloatingSupply(address providerAddress, uint256 providerHeight, bool neg, uint256 value) internal {\n        /*\n            Inner function for updating the database when some token change has happened.\n            In this case we are checking if despite the changes the provider is still entitled to the token emission. In case the legitimacy changes then the global supply should be set as well.\n\n            @providerAddress        Provider address.\n            @providerHeight         Provider height.\n            @neg                    the change was negative or not\n            @value                  Rate of the change\n        */\n        uint256 LSID = providers[providerAddress].data[providerHeight].lastSupplyID;\n        if ( currentSchellingRound != LSID ) {\n            if ( neg ) {\n                setRightForInterest(\n                    providers[providerAddress].data[providerHeight].supply[LSID],\n                    providers[providerAddress].data[providerHeight].supply[LSID] - value,\n                    providers[providerAddress].data[providerHeight].priv\n                );\n                providers[providerAddress].data[providerHeight].supply[currentSchellingRound] = providers[providerAddress].data[providerHeight].supply[LSID] - value;\n            } else {\n                setRightForInterest(\n                    providers[providerAddress].data[providerHeight].supply[LSID],\n                    providers[providerAddress].data[providerHeight].supply[LSID] + value,\n                    providers[providerAddress].data[providerHeight].priv\n                );\n                providers[providerAddress].data[providerHeight].supply[currentSchellingRound] = providers[providerAddress].data[providerHeight].supply[LSID] + value;\n            }\n            providers[providerAddress].data[providerHeight].lastSupplyID = currentSchellingRound;\n        } else {\n            if ( neg ) {\n                setRightForInterest(\n                    getProviderCurrentSupply(providerAddress),\n                    getProviderCurrentSupply(providerAddress) - value,\n                    providers[providerAddress].data[providerHeight].priv\n                );\n                providers[providerAddress].data[providerHeight].supply[currentSchellingRound] -= value;\n            } else {\n                setRightForInterest(\n                    getProviderCurrentSupply(providerAddress),\n                    getProviderCurrentSupply(providerAddress) + value,\n                    providers[providerAddress].data[providerHeight].priv\n                );\n                providers[providerAddress].data[providerHeight].supply[currentSchellingRound] += value;\n            }\n        }\n    }\n    function checkFloatingOwnSupply(address providerAddress, uint256 providerHeight, bool neg, uint256 value) internal {\n        /*\n            Inner function for updating the database in case token change has happened.\n            In this case we check if the provider despite the changes is still entitled to the token emission.\n            We just call this only if the private provider and it’s own capital bears emission.\n\n            @providerAddress        Provider address.\n            @providerHeight         Provider height.\n            @neg                    Was the change negative?\n            @value                  Rate of the change.\n        */\n        uint256 LSID = providers[providerAddress].data[providerHeight].lastOwnSupplyID;\n        if ( currentSchellingRound != LSID ) {\n            if ( neg ) {\n                setRightForInterest(\n                    providers[providerAddress].data[providerHeight].ownSupply[LSID],\n                    providers[providerAddress].data[providerHeight].ownSupply[LSID] - value,\n                    true\n                );\n                providers[providerAddress].data[providerHeight].ownSupply[currentSchellingRound] = providers[providerAddress].data[providerHeight].ownSupply[LSID] - value;\n            } else {\n                setRightForInterest(\n                    providers[providerAddress].data[providerHeight].ownSupply[LSID],\n                    providers[providerAddress].data[providerHeight].ownSupply[LSID] + value,\n                    true\n                );\n                providers[providerAddress].data[providerHeight].ownSupply[currentSchellingRound] = providers[providerAddress].data[providerHeight].ownSupply[LSID] + value;\n            }\n            providers[providerAddress].data[providerHeight].lastOwnSupplyID = currentSchellingRound;\n        } else {\n            if ( neg ) {\n                setRightForInterest(\n                    getProviderCurrentSupply(providerAddress),\n                    getProviderCurrentSupply(providerAddress) - value,\n                    true\n                );\n                providers[providerAddress].data[providerHeight].ownSupply[currentSchellingRound] -= value;\n            } else {\n                setRightForInterest(\n                    getProviderCurrentSupply(providerAddress),\n                    getProviderCurrentSupply(providerAddress) + value,\n                    true\n                );\n                providers[providerAddress].data[providerHeight].ownSupply[currentSchellingRound] += value;\n            }\n        }\n    }\n    function TEMath(uint256 a, uint256 b, bool neg) internal returns (uint256) {\n        /*\n            Inner function for the changes of the numbers\n\n            @a      First number\n            @b      2nd number\n            @neg    Operation with numbers. If it is TRUE then subtraction, if it is FALSE then addition.\n        */\n        if ( neg ) { return a-b; }\n        else { return a+b; }\n    }\n    function transferEvent_(address addr, uint256 value, bool neg) internal {\n        /*\n            Inner function for perceiving the changes of the balance and updating the database.\n            If the address is a provider and the balance is decreasing than can not let it go under the minimum level.\n\n            @addr       The address where the change happened.\n            @value      Rate of the change.\n            @neg        ype of the change. If it is TRUE then the balance has been decreased if it is FALSE then it has been increased.\n        */\n        if ( clients[addr].providerAddress != address(0x00) ) {\n            checkFloatingSupply(clients[addr].providerAddress, providers[clients[addr].providerAddress].currentHeight, ! neg, value);\n            if (clients[addr].lastSupplyID != currentSchellingRound) {\n                clients[addr].supply[currentSchellingRound] = TEMath(clients[addr].supply[clients[addr].lastSupplyID], value, neg);\n                clients[addr].lastSupplyID = currentSchellingRound;\n            } else {\n                clients[addr].supply[currentSchellingRound] = TEMath(clients[addr].supply[currentSchellingRound], value, neg);\n            }\n        } else if ( providers[addr].data[providers[addr].currentHeight].valid ) {\n            uint256 currentHeight = providers[addr].currentHeight;\n            if ( neg ) {\n                uint256 balance = getTokenBalance(addr);\n                if ( providers[addr].data[currentHeight].priv ) {\n                    require( balance-value >= minFundsForPrivate );\n                } else {\n                    require( balance-value >= minFundsForPublic );\n                }\n            }\n            if ( providers[addr].data[currentHeight].priv ) {\n                checkFloatingOwnSupply(addr, currentHeight, ! neg, value);\n            }\n        }\n    }\n    function getTokenBalance(address addr) internal returns (uint256 balance) {\n        /*\n            Inner function in order to poll the token balance of the address.\n\n            @addr       Address\n\n            @balance    Balance of the address.\n        */\n        (bool _success, uint256 _balance) = moduleHandler(moduleHandlerAddress).balanceOf(addr);\n        require( _success );\n        return _balance;\n    }\n    function checkICO() internal returns (bool isICO) {\n        /*\n            Inner function to check the ICO status.\n\n            @isICO      Is the ICO in process or not?\n        */\n        (bool _success, bool _isICO) = moduleHandler(moduleHandlerAddress).isICO();\n        require( _success );\n        return _isICO;\n    }\n    event EProviderOpen(address addr, uint256 height);\n    event EClientLost(address indexed client, address indexed provider, uint256 height, uint256 indexed value);\n    event ENewClient(address indexed client, address indexed provider, uint256 height, uint256 indexed value);\n    event EProviderClose(address indexed addr, uint256 height);\n    event EProviderDetailsChanged(address indexed addr, uint256 height, string website, string country, string info, uint8 rate, address admin);\n    event EReward(address indexed client, address indexed provider, uint256 clientreward, uint256 providerReward);\n}\n"
  },
  {
    "path": "test/compilationTests/corion/publisher.sol",
    "content": "pragma solidity >=0.0;\n\nimport \"./announcementTypes.sol\";\nimport \"./module.sol\";\nimport \"./moduleHandler.sol\";\nimport \"./safeMath.sol\";\n\ncontract publisher is announcementTypes, module, safeMath {\n    /*\n        module callbacks\n    */\n    function transferEvent(address payable from, address payable to, uint256 value) external override returns (bool success) {\n        /*\n            Transaction completed. This function is available only for moduleHandler\n            If a transaction is carried out from or to an address which participated in the objection of an announcement, its objection purport is automatically set\n        */\n        require( super.isModuleHandler(payable(msg.sender)) );\n        uint256 announcementID;\n\t\tuint256 a;\n\t\t// need reverse lookup\n        for ( a=0 ; a<opponents[from].length ; a++ ) {\n            announcementID = opponents[msg.sender][a];\n            if ( announcements[announcementID].end < block.number && announcements[announcementID].open ) {\n                announcements[announcementID].oppositionWeight = safeSub(announcements[a].oppositionWeight, value);\n            }\n        }\n        for ( a=0 ; a<opponents[to].length ; a++ ) {\n            announcementID = opponents[msg.sender][a];\n            if ( announcements[announcementID].end < block.number && announcements[announcementID].open ) {\n                announcements[announcementID].oppositionWeight = safeAdd(announcements[a].oppositionWeight, value);\n            }\n        }\n        return true;\n    }\n\n    /*\n        Pool\n    */\n\n    uint256 public  minAnnouncementDelay = 40320;\n    uint256 public minAnnouncementDelayOnICO = 17280;\n    uint8 public oppositeRate = 33;\n\n    struct announcements_s {\n        announcementType Type;\n        uint256 start;\n        uint256 end;\n        bool open;\n        string announcement;\n        string link;\n        bool oppositable;\n        uint256 oppositionWeight;\n        bool result;\n\n        string _str;\n        uint256 _uint;\n        address payable _addr;\n    }\n    mapping(uint256 => announcements_s) public announcements;\n    uint256 announcementsLength = 1;\n\n    mapping (address => uint256[]) public opponents;\n\n    constructor(address payable moduleHandler) {\n        /*\n            Installation function.  The installer will be registered in the admin list automatically\n\n            @moduleHandler      Address of moduleHandler\n        */\n        super.registerModuleHandler(moduleHandler);\n    }\n\n    function Announcements(uint256 id) public view returns (uint256 Type, uint256 Start, uint256 End, bool Closed, string memory Announcement, string memory Link, bool Opposited, string memory _str, uint256 _uint, address _addr) {\n        /*\n            Announcement data query\n\n            @id             Its identification\n\n            @Type           Subject of announcement\n            @Start          Height of announcement block\n            @End            Planned completion of announcement\n            @Closed         Closed or not\n            @Announcement   Announcement text\n            @Link           Link  perhaps to a Forum\n            @Opposited      Objected or not\n            @_str           Text value\n            @_uint          Number value\n            @_addr          Address value\n        */\n        Type = uint256(announcements[id].Type);\n        Start = announcements[id].start;\n        End = announcements[id].end;\n        Closed = ! announcements[id].open;\n        Announcement = announcements[id].announcement;\n        Link = announcements[id].link;\n        if ( checkOpposited(announcements[id].oppositionWeight, announcements[id].oppositable) ) {\n            Opposited = true;\n        }\n        _str = announcements[id]._str;\n        _uint = announcements[id]._uint;\n        _addr = announcements[id]._addr;\n    }\n\n    function checkOpposited(uint256 weight, bool oppositable) public view returns (bool success) {\n        /*\n            Veto check\n\n            @weight         Purport of objections so far\n            @oppositable    Opposable at all\n\n            @success        Opposed or not\n        */\n        if ( ! oppositable ) { return false; }\n        (bool _success, uint256 _amount) = moduleHandler(moduleHandlerAddress).totalSupply();\n        require( _success );\n        return _amount * oppositeRate / 100 > weight;\n    }\n\n    function newAnnouncement(announcementType Type, string calldata Announcement, string calldata Link, bool Oppositable, string calldata _str, uint256 _uint, address payable _addr) onlyOwner external {\n        /*\n            New announcement. Can be called  only by those in the admin list\n\n            @Type           Topic of announcement\n            @Start          height of announcement block\n            @End            planned completion of announcement\n            @Closed         Completed or not\n            @Announcement   Announcement text\n            @Link           link to a Forum\n            @Opposition     opposed or not\n            @_str           text box\n            @_uint          number box\n            @_addr          address box\n        */\n        announcementsLength++;\n        announcements[announcementsLength].Type = Type;\n        announcements[announcementsLength].start = block.number;\n        if ( checkICO() ) {\n            announcements[announcementsLength].end = block.number + minAnnouncementDelayOnICO;\n        } else {\n            announcements[announcementsLength].end = block.number + minAnnouncementDelay;\n        }\n        announcements[announcementsLength].open = true;\n        announcements[announcementsLength].announcement = Announcement;\n        announcements[announcementsLength].link = Link;\n        announcements[announcementsLength].oppositable = Oppositable;\n        announcements[announcementsLength].oppositionWeight = 0;\n        announcements[announcementsLength].result = false;\n        announcements[announcementsLength]._str = _str;\n        announcements[announcementsLength]._uint = _uint;\n        announcements[announcementsLength]._addr = _addr;\n        emit ENewAnnouncement(announcementsLength, Type);\n    }\n\n    function closeAnnouncement(uint256 id) onlyOwner external {\n        /*\n            Close announcement. It can be closed only by those in the admin list. Windup is allowed only after the announcement is completed.\n\n            @id     Announcement identification\n        */\n        require( announcements[id].open && announcements[id].end < block.number );\n        if ( ! checkOpposited(announcements[id].oppositionWeight, announcements[id].oppositable) ) {\n            announcements[id].result = true;\n            if ( announcements[id].Type == announcementType.newModule ) {\n                require( moduleHandler(moduleHandlerAddress).newModule(announcements[id]._str, announcements[id]._addr, true, true) );\n            } else if ( announcements[id].Type == announcementType.dropModule ) {\n                require( moduleHandler(moduleHandlerAddress).dropModule(announcements[id]._str, true) );\n            } else if ( announcements[id].Type == announcementType.replaceModule ) {\n                require( moduleHandler(moduleHandlerAddress).replaceModule(announcements[id]._str, announcements[id]._addr, true) );\n            } else if ( announcements[id].Type == announcementType.replaceModuleHandler) {\n                require( moduleHandler(moduleHandlerAddress).replaceModuleHandler(announcements[id]._addr) );\n            } else if ( announcements[id].Type == announcementType.transactionFeeRate ||\n                        announcements[id].Type == announcementType.transactionFeeMin ||\n                        announcements[id].Type == announcementType.transactionFeeMax ||\n                        announcements[id].Type == announcementType.transactionFeeBurn ) {\n                require( moduleHandler(moduleHandlerAddress).configureModule(\"token\", announcements[id].Type, announcements[id]._uint) );\n            } else if ( announcements[id].Type == announcementType.providerPublicFunds ||\n                        announcements[id].Type == announcementType.providerPrivateFunds ||\n                        announcements[id].Type == announcementType.providerPrivateClientLimit ||\n                        announcements[id].Type == announcementType.providerPublicMinRate ||\n                        announcements[id].Type == announcementType.providerPublicMaxRate ||\n                        announcements[id].Type == announcementType.providerPrivateMinRate ||\n                        announcements[id].Type == announcementType.providerPrivateMaxRate ||\n                        announcements[id].Type == announcementType.providerGasProtect ||\n                        announcements[id].Type == announcementType.providerInterestMinFunds ||\n                        announcements[id].Type == announcementType.providerRentRate ) {\n                require( moduleHandler(moduleHandlerAddress).configureModule(\"provider\", announcements[id].Type, announcements[id]._uint) );\n            } else if ( announcements[id].Type == announcementType.schellingRoundBlockDelay ||\n                        announcements[id].Type == announcementType.schellingCheckRounds ||\n                        announcements[id].Type == announcementType.schellingCheckAboves ||\n                        announcements[id].Type == announcementType.schellingRate ) {\n                require( moduleHandler(moduleHandlerAddress).configureModule(\"schelling\", announcements[id].Type, announcements[id]._uint) );\n            } else if ( announcements[id].Type == announcementType.publisherMinAnnouncementDelay) {\n                minAnnouncementDelay = announcements[id]._uint;\n            } else if ( announcements[id].Type == announcementType.publisherOppositeRate) {\n                oppositeRate = uint8(announcements[id]._uint);\n            }\n        }\n        announcements[id].end = block.number;\n        announcements[id].open = false;\n    }\n\n    function oppositeAnnouncement(uint256 id) external {\n        /*\n            Opposition of announcement\n            If announcement is opposable, anyone owning a token can oppose it\n            Opposition is automatically with the total amount of tokens\n            If the quantity of his tokens changes, the purport of his opposition changes automatically\n            The prime time is the windup of the announcement, because this is the moment when the number of tokens in opposition are counted.\n            One address is entitled to be in opposition only once. An opposition cannot be withdrawn.\n            Running announcements can be opposed only.\n\n            @id     Announcement identification\n        */\n        uint256 newArrayID = 0;\n        bool foundEmptyArrayID = false;\n        require( announcements[id].open );\n        require( announcements[id].oppositable );\n        for ( uint256 a=0 ; a<opponents[msg.sender].length ; a++ ) {\n            require( opponents[msg.sender][a] != id );\n            if ( ! announcements[opponents[msg.sender][a]].open) {\n                delete opponents[msg.sender][a];\n                if ( ! foundEmptyArrayID ) {\n                    foundEmptyArrayID = true;\n                    newArrayID = a;\n                }\n            }\n            if ( ! foundEmptyArrayID ) {\n                foundEmptyArrayID = true;\n                newArrayID = a;\n            }\n        }\n        (bool _success, uint256 _balance) = moduleHandler(moduleHandlerAddress).balanceOf(msg.sender);\n        require( _success );\n        require( _balance > 0);\n        if ( foundEmptyArrayID ) {\n            opponents[msg.sender][newArrayID] = id;\n        } else {\n            opponents[msg.sender].push(id);\n        }\n        announcements[id].oppositionWeight += _balance;\n        emit EOppositeAnnouncement(id, msg.sender, _balance);\n    }\n\n    function invalidateAnnouncement(uint256 id) onlyOwner external {\n        /*\n            Withdraw announcement. Only those in the admin list can withdraw it.\n\n            @id     Announcement identification\n        */\n        require( announcements[id].open );\n        announcements[id].end = block.number;\n        announcements[id].open = false;\n        emit EInvalidateAnnouncement(id);\n    }\n\n    modifier onlyOwner() {\n        /*\n            Only the owner  is allowed to call it.\n        */\n        require( moduleHandler(moduleHandlerAddress).owners(msg.sender) );\n        _;\n    }\n\n    function checkICO() internal returns (bool isICO) {\n        /*\n            Inner function to check the ICO status.\n            @bool       Is the ICO in process or not?\n        */\n        (bool _success, bool _isICO) = moduleHandler(moduleHandlerAddress).isICO();\n        require( _success );\n        return _isICO;\n    }\n\n    event ENewAnnouncement(uint256 id, announcementType typ);\n    event EOppositeAnnouncement(uint256 id, address addr, uint256 value);\n    event EInvalidateAnnouncement(uint256 id);\n    event ECloseAnnouncement(uint256 id);\n}\n"
  },
  {
    "path": "test/compilationTests/corion/safeMath.sol",
    "content": "pragma solidity >=0.0;\n\ncontract safeMath {\n    function safeAdd(uint256 a, uint256 b) internal returns(uint256) {\n        /*\n            Biztonsagos hozzadas. Tulcsordulas elleni vedelem.\n            A vegeredmeny nem lehet kevesebb mint az @a, ha igen megall a kod.\n\n            @a          Amihez hozzaadni kell\n            @b          Amennyit hozzaadni kell.\n            @uint256    Vegeredmeny.\n        */\n        if ( b > 0 ) {\n            assert( a + b > a );\n        }\n        return a + b;\n    }\n\n    function safeSub(uint256 a, uint256 b) internal returns(uint256) {\n        /*\n            Biztonsagos kivonas. Tulcsordulas elleni vedelem.\n            A vegeredmeny nem lehet tobb mint az @a, ha igen megall a kod.\n\n            @a          Amibol kivonni kell.\n            @b          Amennyit kivonni kell.\n            @uint256    Vegeredmeny.\n        */\n        if ( b > 0 ) {\n            assert( a - b < a );\n        }\n        return a - b;\n    }\n}"
  },
  {
    "path": "test/compilationTests/corion/schelling.sol",
    "content": "pragma solidity >=0.0;\n\nimport \"./announcementTypes.sol\";\nimport \"./module.sol\";\nimport \"./moduleHandler.sol\";\nimport \"./safeMath.sol\";\n\ncontract schellingVars {\n    /*\n        Common enumerations and structures of the Schelling and Database contract.\n    */\n    enum voterStatus {\n        base,\n        afterPrepareVote,\n        afterSendVoteOk,\n        afterSendVoteBad\n    }\n    struct _rounds {\n        uint256 totalAboveWeight;\n        uint256 totalBelowWeight;\n        uint256 reward;\n        uint256 blockHeight;\n        bool voted;\n    }\n    struct _voter {\n        uint256 roundID;\n        bytes32 hash;\n        voterStatus status;\n        bool voteResult;\n        uint256 rewards;\n    }\n}\n\ncontract schellingDB is safeMath, schellingVars {\n    /*\n        Schelling database contract.\n    */\n    address private owner;\n    function replaceOwner(address newOwner) external returns(bool) {\n        require( owner == address(0x00) || msg.sender == owner );\n        owner = newOwner;\n        return true;\n    }\n    modifier isOwner { require( msg.sender == owner ); _; }\n    /*\n        Constructor\n    */\n    constructor() {\n        rounds.push();\n        rounds.push();\n        rounds[0].blockHeight = block.number;\n        currentSchellingRound = 1;\n    }\n    /*\n        Funds\n    */\n    mapping(address => uint256) private funds;\n    function getFunds(address _owner) public view returns(bool, uint256) {\n        return (true, funds[_owner]);\n    }\n    function setFunds(address _owner, uint256 _amount) isOwner external returns(bool) {\n        funds[_owner] = _amount;\n        return true;\n    }\n    /*\n        Rounds\n    */\n    _rounds[] private rounds;\n    function getRound(uint256 _id) public view returns(bool, uint256, uint256, uint256, uint256, bool) {\n        if ( rounds.length <= _id ) { return (false, 0, 0, 0, 0, false); }\n        else { return (true, rounds[_id].totalAboveWeight, rounds[_id].totalBelowWeight, rounds[_id].reward, rounds[_id].blockHeight, rounds[_id].voted); }\n    }\n    function pushRound(uint256 _totalAboveWeight, uint256 _totalBelowWeight, uint256 _reward, uint256 _blockHeight, bool _voted) isOwner external returns(bool, uint256) {\n        rounds.push(_rounds(_totalAboveWeight, _totalBelowWeight, _reward, _blockHeight, _voted));\n        return (true, rounds.length);\n    }\n    function setRound(uint256 _id, uint256 _totalAboveWeight, uint256 _totalBelowWeight, uint256 _reward, uint256 _blockHeight, bool _voted) isOwner external returns(bool) {\n        rounds[_id] = _rounds(_totalAboveWeight, _totalBelowWeight, _reward, _blockHeight, _voted);\n        return true;\n    }\n    function getCurrentRound() public view returns(bool, uint256) {\n        return (true, rounds.length-1);\n    }\n    /*\n        Voter\n    */\n    mapping(address => _voter) private voter;\n    function getVoter(address _owner) public view returns(bool success, uint256 roundID,\n        bytes32 hash, voterStatus status, bool voteResult, uint256 rewards) {\n        roundID         = voter[_owner].roundID;\n        hash            = voter[_owner].hash;\n        status          = voter[_owner].status;\n        voteResult      = voter[_owner].voteResult;\n        rewards         = voter[_owner].rewards;\n        success         = true;\n    }\n    function setVoter(address _owner, uint256 _roundID, bytes32 _hash, voterStatus _status, bool _voteResult, uint256 _rewards) isOwner external returns(bool) {\n        voter[_owner] = _voter(\n            _roundID,\n            _hash,\n            _status,\n            _voteResult,\n            _rewards\n            );\n        return true;\n    }\n    /*\n        Schelling Token emission\n    */\n    mapping(uint256 => uint256) private schellingExpansion;\n    function getSchellingExpansion(uint256 _id) public view returns(bool, uint256) {\n        return (true, schellingExpansion[_id]);\n    }\n    function setSchellingExpansion(uint256 _id, uint256 _expansion) isOwner external returns(bool) {\n        schellingExpansion[_id] = _expansion;\n        return true;\n    }\n    /*\n        Current Schelling Round\n    */\n    uint256 private currentSchellingRound;\n    function setCurrentSchellingRound(uint256 _id) isOwner external returns(bool) {\n        currentSchellingRound = _id;\n        return true;\n    }\n    function getCurrentSchellingRound() public view returns(bool, uint256) {\n        return (true, currentSchellingRound);\n    }\n}\n\ncontract schelling is module, announcementTypes, schellingVars {\n    /*\n        Schelling contract\n    */\n    /*\n        module callbacks\n    */\n    function replaceModule(address payable addr) external override returns (bool) {\n        require( super.isModuleHandler(payable(msg.sender)) );\n        require( db.replaceOwner(addr) );\n        super._replaceModule(addr);\n        return true;\n    }\n    function transferEvent(address payable from, address payable to, uint256 value) external override returns (bool) {\n        /*\n            Transaction completed. This function can be called only by the ModuleHandler.\n            If this contract is the receiver, the amount will be added to the prize pool of the current round.\n\n            @from      From who\n            @to        To who\n            @value     Amount\n            @bool      Was the transaction successful?\n        */\n        require( super.isModuleHandler(payable(msg.sender)) );\n        if ( to == address(this) ) {\n            uint256 currentRound = getCurrentRound();\n            schellingVars._rounds memory round = getRound(currentRound);\n            round.reward += value;\n            setRound(currentRound, round);\n        }\n        return true;\n    }\n    modifier isReady {\n        (bool _success, bool _active) = super.isActive();\n        require( _success && _active );\n        _;\n    }\n    /*\n        Schelling database functions.\n    */\n    function getFunds(address addr) internal returns (uint256) {\n        (bool a, uint256 b) = db.getFunds(addr);\n        require( a );\n        return b;\n    }\n    function setFunds(address addr, uint256 amount) internal {\n        require( db.setFunds(addr, amount) );\n    }\n    function setVoter(address owner, _voter memory voter) internal {\n        require( db.setVoter(owner,\n            voter.roundID,\n            voter.hash,\n            voter.status,\n            voter.voteResult,\n            voter.rewards\n            ) );\n    }\n    function getVoter(address addr) internal view returns (_voter memory) {\n        (bool a, uint256 b, bytes32 c, schellingVars.voterStatus d, bool e, uint256 f) = db.getVoter(addr);\n        require( a );\n        return _voter(b, c, d, e, f);\n    }\n    function setRound(uint256 id, _rounds memory round) internal {\n        require( db.setRound(id,\n            round.totalAboveWeight,\n            round.totalBelowWeight,\n            round.reward,\n            round.blockHeight,\n            round.voted\n            ) );\n    }\n    function pushRound(_rounds memory round) internal returns (uint256) {\n        (bool a, uint256 b) = db.pushRound(\n            round.totalAboveWeight,\n            round.totalBelowWeight,\n            round.reward,\n            round.blockHeight,\n            round.voted\n            );\n        require( a );\n        return b;\n    }\n    function getRound(uint256 id) internal returns (_rounds memory) {\n        (bool a, uint256 b, uint256 c, uint256 d, uint256 e, bool f) = db.getRound(id);\n        require( a );\n        return _rounds(b, c, d, e, f);\n    }\n    function getCurrentRound() internal returns (uint256) {\n        (bool a, uint256 b) = db.getCurrentRound();\n        require( a );\n        return b;\n    }\n    function setCurrentSchellingRound(uint256 id) internal {\n        require( db.setCurrentSchellingRound(id) );\n    }\n    function getCurrentSchellingRound() internal view returns(uint256) {\n        (bool a, uint256 b) = db.getCurrentSchellingRound();\n        require( a );\n        return b;\n    }\n    function setSchellingExpansion(uint256 id, uint256 amount) internal {\n        require( db.setSchellingExpansion(id, amount) );\n    }\n    function getSchellingExpansion(uint256 id) internal view returns(uint256) {\n        (bool a, uint256 b) = db.getSchellingExpansion(id);\n        require( a );\n        return b;\n    }\n    /*\n        Schelling module\n    */\n    uint256 private roundBlockDelay     = 720;\n    uint8 private interestCheckRounds   = 7;\n    uint8 private interestCheckAboves   = 4;\n    uint256 private interestRate        = 300;\n    uint256 private interestRateM       = 1e3;\n\n    bytes1 public aboveChar = 0x31;\n    bytes1 public belowChar = 0x30;\n    schellingDB private db;\n\n    constructor(address payable _moduleHandler, address _db, bool _forReplace) {\n        /*\n            Installation function.\n\n            @_moduleHandler         Address of ModuleHandler.\n            @_db                    Address of the database.\n            @_forReplace            This address will be replaced with the old one or not.\n            @_icoExpansionAddress   This address can turn schelling funds during ICO.\n        */\n        db = schellingDB(_db);\n        super.registerModuleHandler(_moduleHandler);\n        if ( ! _forReplace ) {\n            require( db.replaceOwner(address(this)) );\n        }\n    }\n    function configure(announcementType a, uint256 b) external returns(bool) {\n        /*\n            Can be called only by the ModuleHandler.\n\n            @a      Sort of configuration\n            @b      Value\n        */\n        require( super.isModuleHandler(payable(msg.sender)) );\n        if      ( a == announcementType.schellingRoundBlockDelay )     { roundBlockDelay = b; }\n        else if ( a == announcementType.schellingCheckRounds )         { interestCheckRounds = uint8(b); }\n        else if ( a == announcementType.schellingCheckAboves )         { interestCheckAboves = uint8(b); }\n        else if ( a == announcementType.schellingRate )                { interestRate = b; }\n        else { return false; }\n        return true;\n    }\n    function prepareVote(bytes32 votehash, uint256 roundID) isReady noContract external {\n        /*\n            Initializing manual vote.\n            Only the hash of vote will be sent. (Envelope sending).\n            The address must be in default state, that is there are no vote in progress.\n            Votes can be sent only on the actually Schelling round.\n\n            @votehash               Hash of the vote\n            @roundID                Number of Schelling round\n        */\n        nextRound();\n\n        uint256 currentRound = getCurrentRound();\n        schellingVars._rounds memory round = getRound(currentRound);\n        _voter memory voter;\n        uint256 funds;\n\n        require( roundID == currentRound );\n\n        voter = getVoter(msg.sender);\n        funds = getFunds(msg.sender);\n\n        require( funds > 0 );\n        require( voter.status == voterStatus.base );\n        voter.roundID = currentRound;\n        voter.hash = votehash;\n        voter.status = voterStatus.afterPrepareVote;\n\n        setVoter(msg.sender, voter);\n        round.voted = true;\n\n        setRound(currentRound, round);\n    }\n    function sendVote(string calldata vote) isReady noContract external {\n        /*\n            Check vote (Envelope opening)\n            Only the sent “envelopes” can be opened.\n            Envelope opening only in the next Schelling round.\n            If the vote invalid, the deposit will be lost.\n            If the “envelope” was opened later than 1,5 Schelling round, the vote is automatically invalid, and deposit can be lost.\n            Lost deposits will be 100% burned.\n\n            @vote      Hash of the content of the vote.\n        */\n        nextRound();\n\n        uint256 currentRound = getCurrentRound();\n        _rounds memory round;\n        _voter memory voter;\n        uint256 funds;\n\n        bool lostEverything;\n        voter = getVoter(msg.sender);\n        round = getRound(voter.roundID);\n        funds = getFunds(msg.sender);\n\n        require( voter.status == voterStatus.afterPrepareVote );\n        require( voter.roundID < currentRound );\n        if ( keccak256(bytes(vote)) == voter.hash ) {\n            delete voter.hash;\n            if (round.blockHeight+roundBlockDelay/2 >= block.number) {\n                if ( bytes(vote)[0] == aboveChar ) {\n                    voter.status = voterStatus.afterSendVoteOk;\n                    round.totalAboveWeight += funds;\n                    voter.voteResult = true;\n                } else if ( bytes(vote)[0] == belowChar ) {\n                    voter.status = voterStatus.afterSendVoteOk;\n                    round.totalBelowWeight += funds;\n                } else { lostEverything = true; }\n            } else {\n                voter.status = voterStatus.afterSendVoteBad;\n            }\n        } else { lostEverything = true; }\n        if ( lostEverything ) {\n            require( moduleHandler(moduleHandlerAddress).burn(address(this), funds) );\n            delete funds;\n            delete voter.status;\n        }\n\n        setVoter(msg.sender, voter);\n        setRound(voter.roundID, round);\n        setFunds(msg.sender, funds);\n    }\n    function checkVote() isReady noContract external {\n        /*\n            Checking votes.\n            Vote checking only after the envelope opening Schelling round.\n            Deposit will be lost, if the vote wrong, or invalid.\n            The right votes take share of deposits.\n        */\n        nextRound();\n\n        uint256 currentRound = getCurrentRound();\n        _rounds memory round;\n        _voter memory voter;\n        uint256 funds;\n\n        voter = getVoter(msg.sender);\n        round = getRound(voter.roundID);\n        funds = getFunds(msg.sender);\n\n        require( voter.status == voterStatus.afterSendVoteOk ||\n            voter.status == voterStatus.afterSendVoteBad );\n        if ( round.blockHeight+roundBlockDelay/2 <= block.number ) {\n            if ( isWinner(round, voter.voteResult) && voter.status == voterStatus.afterSendVoteOk ) {\n                voter.rewards += funds * round.reward / getRoundWeight(round.totalAboveWeight, round.totalBelowWeight);\n            } else {\n                require( moduleHandler(moduleHandlerAddress).burn(address(this), funds) );\n                delete funds;\n            }\n            delete voter.status;\n            delete voter.roundID;\n        } else { revert(); }\n\n        setVoter(msg.sender, voter);\n        setFunds(msg.sender, funds);\n    }\n    function getRewards(address beneficiary) isReady noContract external {\n        /*\n            Redeem of prize.\n            The prizes will be collected here, and with this function can be transferred to the account of the user.\n            Optionally there can be an address of a beneficiary added, which address the prize will be sent to. Without beneficiary, the owner is the default address.\n            Prize will be sent from the Schelling address without any transaction fee.\n\n            @beneficiary        Address of the beneficiary\n        */\n        schellingVars._voter memory voter = getVoter(msg.sender);\n        uint256 funds = getFunds(msg.sender);\n\n        address _beneficiary = msg.sender;\n        if (beneficiary != address(0x00)) { _beneficiary = beneficiary; }\n        uint256 reward;\n        require( voter.rewards > 0 );\n        require( voter.status == voterStatus.base );\n        reward = voter.rewards;\n        delete voter.rewards;\n        require( moduleHandler(moduleHandlerAddress).transfer(address(this), _beneficiary, reward, false) );\n\n        setVoter(msg.sender, voter);\n    }\n    function checkReward() public view returns (uint256 reward) {\n        /*\n            Withdraw of the amount of the prize (it’s only information).\n\n            @reward         Prize\n        */\n        schellingVars._voter memory voter = getVoter(msg.sender);\n        return voter.rewards;\n    }\n    function nextRound() internal returns (bool) {\n        /*\n            Inside function, checks the time of the Schelling round and if its needed, creates a new Schelling round.\n        */\n        uint256 currentRound = getCurrentRound();\n        _rounds memory round = getRound(currentRound);\n        _rounds memory newRound;\n        _rounds memory prevRound;\n        uint256 currentSchellingRound = getCurrentSchellingRound();\n\n        if ( round.blockHeight+roundBlockDelay > block.number) { return false; }\n\n        newRound.blockHeight = block.number;\n        if ( ! round.voted ) {\n            newRound.reward = round.reward;\n        }\n        uint256 above;\n        for ( uint256 a=currentRound ; a>=currentRound-interestCheckRounds ; a-- ) {\n            if (a == 0) { break; }\n            prevRound = getRound(a);\n            if ( prevRound.totalAboveWeight > prevRound.totalBelowWeight ) { above++; }\n        }\n        uint256 expansion;\n        if ( above >= interestCheckAboves ) {\n            expansion = getTotalSupply() * interestRate / interestRateM / 100;\n        }\n\n        currentSchellingRound++;\n\n        pushRound(newRound);\n        setSchellingExpansion(currentSchellingRound, expansion);\n        require( moduleHandler(moduleHandlerAddress).broadcastSchellingRound(currentSchellingRound, expansion) );\n        return true;\n    }\n    function addFunds(uint256 amount) isReady noContract external {\n        /*\n            Deposit taking.\n            Every participant entry with his own deposit.\n            In case of wrong vote only this amount of deposit will be burn.\n            The deposit will be sent to the address of Schelling, charged with transaction fee.\n\n            @amount          Amount of deposit.\n        */\n        _voter memory voter = getVoter(msg.sender);\n        uint256 funds = getFunds(msg.sender);\n\n        (bool a, bool b) = moduleHandler(moduleHandlerAddress).isICO();\n        require( b && b );\n        require( voter.status == voterStatus.base );\n        require( amount > 0 );\n        require( moduleHandler(moduleHandlerAddress).transfer(msg.sender, address(this), amount, true) );\n        funds += amount;\n\n        setFunds(msg.sender, funds);\n    }\n    function getFunds() isReady noContract external {\n        /*\n            Deposit withdrawn.\n            If the deposit isn’t lost, it can be withdrawn.\n            By withdrawn, the deposit will be sent from Schelling address to the users address, charged with transaction fee..\n        */\n        _voter memory voter = getVoter(msg.sender);\n        uint256 funds = getFunds(msg.sender);\n\n        require( funds > 0 );\n        require( voter.status == voterStatus.base );\n        setFunds(msg.sender, 0);\n\n        require( moduleHandler(moduleHandlerAddress).transfer(address(this), msg.sender, funds, true) );\n    }\n    function getCurrentSchellingRoundID() public view returns (uint256) {\n        /*\n            Number of actual Schelling round.\n\n            @uint256        Schelling round.\n        */\n        return getCurrentSchellingRound();\n    }\n    function getSchellingRound(uint256 id) public view returns (uint256 expansion) {\n        /*\n            Amount of token emission of the Schelling round.\n\n            @id             Number of Schelling round\n            @expansion      Amount of token emission\n        */\n        return getSchellingExpansion(id);\n    }\n    function getRoundWeight(uint256 aboveW, uint256 belowW) internal returns (uint256) {\n        /*\n            Inside function for calculating the weights of the votes.\n\n            @aboveW     Weight of votes: ABOVE\n            @belowW     Weight of votes: BELOW\n            @uint256    Calculate weight\n        */\n        if ( aboveW == belowW ) {\n            return aboveW + belowW;\n        } else if ( aboveW > belowW ) {\n            return aboveW;\n        } else if ( aboveW < belowW) {\n            return belowW;\n        }\n    }\n    function isWinner(_rounds memory round, bool aboveVote) internal returns (bool) {\n        /*\n            Inside function for calculating the result of the game.\n\n            @round      Structure of Schelling round.\n            @aboveVote  Is the vote = ABOVE or not\n            @bool       Result\n        */\n        if ( round.totalAboveWeight == round.totalBelowWeight ||\n            ( round.totalAboveWeight > round.totalBelowWeight && aboveVote ) ) {\n            return true;\n        }\n        return false;\n    }\n\n    function getTotalSupply() internal returns (uint256 amount) {\n        /*\n            Inside function for querying the whole amount of the tokens.\n\n            @uint256        Whole token amount\n        */\n        (bool _success, uint256 _amount) = moduleHandler(moduleHandlerAddress).totalSupply();\n        require( _success );\n        return _amount;\n    }\n\n    function getTokenBalance(address addr) internal returns (uint256 balance) {\n        /*\n            Inner function in order to poll the token balance of the address.\n\n            @addr       Address\n\n            @balance    Balance of the address.\n        */\n        (bool _success, uint256 _balance) = moduleHandler(moduleHandlerAddress).balanceOf(addr);\n        require( _success );\n        return _balance;\n    }\n\n    modifier noContract {\n        /*\n            Contract can’t call this function, only a natural address.\n        */\n        require( msg.sender == tx.origin ); _;\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/corion/token.sol",
    "content": "pragma solidity >=0.0;\n\nimport \"./announcementTypes.sol\";\nimport \"./safeMath.sol\";\nimport \"./module.sol\";\nimport \"./moduleHandler.sol\";\nimport \"./tokenDB.sol\";\n\ncontract thirdPartyContractAbstract {\n    function receiveCorionToken(address, uint256, bytes calldata) external returns (bool, uint256) {}\n    function approvedCorionToken(address, uint256, bytes calldata) external returns (bool) {}\n}\n\n/**\n *\n * @title Corion Platform Token\n * @author iFA @ Corion Platform\n *\n */\ncontract token is safeMath, module, announcementTypes {\n    /*\n        module callbacks\n    */\n    function replaceModule(address payable addr) external override returns (bool success) {\n        require( super.isModuleHandler(payable(msg.sender)) );\n        require( db.replaceOwner(addr) );\n        super._replaceModule(addr);\n        return true;\n    }\n    modifier isReady {\n        (bool _success, bool _active) = super.isActive();\n        require( _success && _active );\n        _;\n    }\n\n    string public name = \"Corion\";\n    string public symbol = \"COR\";\n    uint8 public decimals = 6;\n\n    tokenDB public db;\n    address payable public icoAddr;\n    uint256 public transactionFeeRate      = 20;\n    uint256 public transactionFeeRateM     = 1e3;\n    uint256 public transactionFeeMin       =   20000;\n    uint256 public transactionFeeMax       = 5000000;\n    uint256 public transactionFeeBurn      = 80;\n    address payable public exchangeAddress;\n    bool    public isICO                   = true;\n\n    mapping(address => bool) public genesis;\n\n    constructor(bool forReplace, address payable moduleHandler, address dbAddr, address payable icoContractAddr, address payable exchangeContractAddress, address payable[] memory genesisAddr, uint256[] memory genesisValue) payable {\n        /*\n            Installation function\n\n            When _icoAddr is defined, 0.2 ether has to be attached  as many times  as many genesis addresses are given\n\n            @forReplace                 This address will be replaced with the old one or not.\n            @moduleHandler              Modulhandler's address\n            @dbAddr                     Address of database\n            @icoContractAddr            Address of ICO contract\n            @exchangeContractAddress    Address of Market in order to buy gas during ICO\n            @genesisAddr                Array of Genesis addresses\n            @genesisValue               Array of balance of genesis addresses\n        */\n        super.registerModuleHandler(moduleHandler);\n        require( dbAddr != address(0x00) );\n        require( icoContractAddr != address(0x00) );\n        require( exchangeContractAddress != address(0x00) );\n        db = tokenDB(dbAddr);\n        icoAddr = icoContractAddr;\n        exchangeAddress = exchangeContractAddress;\n        isICO = ! forReplace;\n        if ( ! forReplace ) {\n            require( db.replaceOwner(address(this)) );\n            assert( genesisAddr.length == genesisValue.length );\n            require( address(this).balance >= genesisAddr.length * 0.2 ether );\n            for ( uint256 a=0 ; a<genesisAddr.length ; a++ ) {\n                genesis[genesisAddr[a]] = true;\n                require( db.increase(genesisAddr[a], genesisValue[a]) );\n                if ( ! genesisAddr[a].send(0.2 ether) ) {}\n                emit Mint(genesisAddr[a], genesisValue[a]);\n            }\n        }\n    }\n\n    function closeIco() external returns (bool success) {\n        /*\n            ICO finished. It can be called only by ICO contract\n\n            @success    Was the Function successful?\n        */\n        require( msg.sender == icoAddr );\n        isICO = false;\n        return true;\n    }\n\n    /**\n     * @notice `msg.sender` approves `spender` to spend `amount` tokens on its behalf.\n     * @param spender The address of the account able to transfer the tokens\n     * @param amount The amount of tokens to be approved for transfer\n     * @param nonce The transaction count of the authorised address\n     * @return success True if the approval was successful\n     */\n    function approve(address spender, uint256 amount, uint256 nonce) isReady external returns (bool success) {\n        /*\n            Authorise another address to use a certain quantity of the authorising owner’s balance\n\n            @spender            Address of authorised party\n            @amount             Token quantity\n            @nonce              Transaction count\n\n            @success            Was the Function successful?\n        */\n        _approve(spender, amount, nonce);\n        return true;\n    }\n\n    /**\n     * @notice `msg.sender` approves `spender` to spend `amount` tokens on its behalf and notify the spender from your approve with your `extraData` data.\n     * @param spender The address of the account able to transfer the tokens\n     * @param amount The amount of tokens to be approved for transfer\n     * @param nonce The transaction count of the authorised address\n     * @param extraData Data to give forward to the receiver\n     * @return success True if the approval was successful\n     */\n    function approveAndCall(address spender, uint256 amount, uint256 nonce, bytes calldata extraData) isReady external returns (bool success) {\n        /*\n            Authorise another address to use a certain quantity of the authorising  owner’s balance\n            Following the transaction the receiver address `approvedCorionToken` function is called by the given data\n\n            @spender            Authorized address\n            @amount             Token quantity\n            @extraData          Extra data to be received by the receiver\n            @nonce              Transaction count\n\n            @success            Was the Function successful?\n        */\n        _approve(spender, amount, nonce);\n        require( thirdPartyContractAbstract(spender).approvedCorionToken(msg.sender, amount, extraData) );\n        return true;\n    }\n\n    function _approve(address spender, uint256 amount, uint256 nonce) internal {\n        /*\n            Internal Function to authorise another address to use a certain quantity of the authorising owner’s balance.\n            If the transaction count not match the authorise fails.\n\n            @spender           Address of authorised party\n            @amount            Token quantity\n            @nonce             Transaction count\n        */\n        require( msg.sender != spender );\n        require( db.balanceOf(msg.sender) >= amount );\n        require( db.setAllowance(msg.sender, spender, amount, nonce) );\n        emit Approval(msg.sender, spender, amount);\n    }\n\n    function allowance(address owner, address spender) public view returns (uint256 remaining, uint256 nonce) {\n        /*\n            Get the quantity of tokens given to be used\n\n            @owner         Authorising address\n            @spender       Authorised address\n\n            @remaining     Tokens to be spent\n            @nonce         Transaction count\n        */\n        (bool _success, uint256 _remaining, uint256 _nonce) = db.getAllowance(owner, spender);\n        require( _success );\n        return (_remaining, _nonce);\n    }\n\n    /**\n     * @notice Send `amount` Corion tokens to `to` from `msg.sender`\n     * @param to The address of the recipient\n     * @param amount The amount of tokens to be transferred\n     * @return success Whether the transfer was successful or not\n     */\n    function transfer(address to, uint256 amount) isReady external returns (bool success) {\n        /*\n            Start transaction, token is sent from caller’s address to receiver’s address\n            Transaction fee is to be deducted.\n            If receiver is not a natural address but a person, he will be called\n\n            @to         To who\n            @amount     Quantity\n\n            @success    Was the Function successful?\n        */\n        bytes memory _data;\n        if ( isContract(to) ) {\n            _transferToContract(msg.sender, to, amount, _data);\n        } else {\n            _transfer( msg.sender, to, amount, true);\n        }\n        emit Transfer(msg.sender, to, amount, _data);\n        return true;\n    }\n\n    /**\n     * @notice Send `amount` tokens to `to` from `from` on the condition it is approved by `from`\n     * @param from The address holding the tokens being transferred\n     * @param to The address of the recipient\n     * @param amount The amount of tokens to be transferred\n     * @return success True if the transfer was successful\n     */\n    function transferFrom(address from, address to, uint256 amount) isReady external returns (bool success) {\n        /*\n            Start transaction to send a quantity from a given address to another address. (approve / allowance). This can be called only by the address approved in advance\n            Transaction fee is to be deducted\n            If receiver is not a natural address but a person, he will be called\n\n            @from       From who.\n            @to         To who\n            @amount     Quantity\n\n            @success    Was the Function successful?\n        */\n        if ( from != msg.sender ) {\n            (bool _success, uint256 _remaining, uint256 _nonce) = db.getAllowance(from, msg.sender);\n            require( _success );\n            _remaining = safeSub(_remaining, amount);\n            _nonce = safeAdd(_nonce, 1);\n            require( db.setAllowance(from, msg.sender, _remaining, _nonce) );\n            emit AllowanceUsed(msg.sender, from, amount);\n        }\n        bytes memory _data;\n        if ( isContract(to) ) {\n            _transferToContract(from, to, amount, _data);\n        } else {\n            _transfer( from, to, amount, true);\n        }\n        emit Transfer(from, to, amount, _data);\n        return true;\n    }\n\n    /**\n     * @notice Send `amount` tokens to `to` from `from` on the condition it is approved by `from`\n     * @param from The address holding the tokens being transferred\n     * @param to The address of the recipient\n     * @param amount The amount of tokens to be transferred\n     * @return success True if the transfer was successful\n     */\n    function transferFromByModule(address from, address to, uint256 amount, bool fee) isReady external returns (bool success) {\n        /*\n            Start transaction to send a quantity from a given address to another address\n            Only ModuleHandler can call it\n\n            @from       From who\n            @to         To who.\n            @amount     Quantity\n            @fee        Deduct transaction fee - yes or no?\n\n            @success    Was the Function successful?\n        */\n        bytes memory _data;\n        require( super.isModuleHandler(payable(msg.sender)) );\n        _transfer( from, to, amount, fee);\n        emit Transfer(from, to, amount, _data);\n        return true;\n    }\n\n    /**\n     * @notice Send `amount` Corion tokens to `to` from `msg.sender` and notify the receiver from your transaction with your `extraData` data\n     * @param to The contract address of the recipient\n     * @param amount The amount of tokens to be transferred\n     * @param extraData Data to give forward to the receiver\n     * @return success Whether the transfer was successful or not\n     */\n    function transfer(address to, uint256 amount, bytes calldata extraData) isReady external returns (bool success) {\n        /*\n            Start transaction to send a quantity from a given address to another address\n            After transaction the function `receiveCorionToken`of the receiver is called  by the given data\n            When sending an amount, it is possible the total amount cannot be processed, the remaining amount is sent back with no fee charged\n\n            @to             To who.\n            @amount         Quantity\n            @extraData      Extra data the receiver will get\n\n            @success        Was the Function successful?\n        */\n        if ( isContract(to) ) {\n            _transferToContract(msg.sender, to, amount, extraData);\n        } else {\n            _transfer( msg.sender, to, amount, true);\n        }\n        emit Transfer(msg.sender, to, amount, extraData);\n        return true;\n    }\n\n    function _transferToContract(address from, address to, uint256 amount, bytes memory extraData) internal {\n        /*\n            Internal function to start transactions to a contract\n\n            @from           From who\n            @to             To who.\n            @amount         Quantity\n            @extraData      Extra data the receiver will get\n        */\n        _transfer(from, to, amount, exchangeAddress == to);\n        (bool _success, uint256 _back) = thirdPartyContractAbstract(to).receiveCorionToken(from, amount, extraData);\n        require( _success );\n        require( amount > _back );\n        if ( _back > 0 ) {\n            _transfer(to, from, _back, false);\n        }\n        _processTransactionFee(from, amount - _back);\n    }\n\n    function _transfer(address from, address to, uint256 amount, bool fee) internal {\n        /*\n            Internal function to start transactions. When Tokens are sent, transaction fee is charged\n            During ICO transactions are allowed only from genesis addresses.\n            After sending the tokens, the ModuleHandler is notified and it will broadcast the fact among members\n\n            The 0xa636a97578d26a3b76b060bbc18226d954cf3757 address are blacklisted.\n\n            @from       From who\n            @to         To who\n            @amount     Quantity\n            @fee        Deduct transaction fee - yes or no?\n        */\n        if( fee ) {\n            (bool success, uint256 _fee) = getTransactionFee(amount);\n            require( success );\n            require( db.balanceOf(from) >= amount + _fee );\n        }\n        require( from != address(0x00) && to != address(0x00) && to != 0xa636A97578d26A3b76B060Bbc18226d954cf3757 );\n        require( ( ! isICO) || genesis[from] );\n        require( db.decrease(from, amount) );\n        require( db.increase(to, amount) );\n        if ( fee ) { _processTransactionFee(from, amount); }\n        if ( isICO ) {\n            require( ico(icoAddr).setInterestDB(from, db.balanceOf(from)) );\n            require( ico(icoAddr).setInterestDB(to, db.balanceOf(to)) );\n        }\n        require( moduleHandler(moduleHandlerAddress).broadcastTransfer(from, to, amount) );\n    }\n\n    /**\n     * @notice Transaction fee will be deduced from `owner` for transacting `value`\n     * @param owner The address where will the transaction fee deduced\n     * @param value The base for calculating the fee\n     * @return success True if the transfer was successful\n     */\n    function processTransactionFee(address owner, uint256 value) isReady external returns (bool success) {\n        /*\n            Charge transaction fee. It can be called only by moduleHandler\n\n            @owner      From who.\n            @value      Quantity to calculate the fee\n\n            @success    Was the Function successful?\n        */\n        require( super.isModuleHandler(payable(msg.sender)) );\n        _processTransactionFee(owner, value);\n        return true;\n    }\n\n    function _processTransactionFee(address owner, uint256 value) internal {\n        /*\n            Internal function to charge the transaction fee. A certain quantity is burnt, the rest is sent to the Schelling game prize pool.\n            No transaction fee during ICO.\n\n            @owner      From who\n            @value      Quantity to calculate the fee\n        */\n        if ( isICO ) { return; }\n        (bool _success, uint256 _fee) = getTransactionFee(value);\n        require( _success );\n        uint256 _forBurn = _fee * transactionFeeBurn / 100;\n        uint256 _forSchelling = _fee - _forBurn;\n        bool _found;\n        address _schellingAddr;\n        (_success, _found, _schellingAddr) = moduleHandler(moduleHandlerAddress).getModuleAddressByName('Schelling');\n        require( _success );\n        if ( _schellingAddr != address(0x00) && _found) {\n            require( db.decrease(owner, _forSchelling) );\n            require( db.increase(_schellingAddr, _forSchelling) );\n            _burn(owner, _forBurn);\n            bytes memory _data;\n            emit Transfer(owner, _schellingAddr, _forSchelling, _data);\n            require( moduleHandler(moduleHandlerAddress).broadcastTransfer(owner, _schellingAddr, _forSchelling) );\n        } else {\n            _burn(owner, _fee);\n        }\n    }\n\n    function getTransactionFee(uint256 value) public view returns (bool success, uint256 fee) {\n        /*\n            Transaction fee query.\n\n            @value      Quantity to calculate the fee\n\n            @success    Was the Function successful?\n            @fee        Amount of Transaction fee\n        */\n        if ( isICO ) { return (true, 0); }\n        fee = value * transactionFeeRate / transactionFeeRateM / 100;\n        if ( fee > transactionFeeMax ) { fee = transactionFeeMax; }\n        else if ( fee < transactionFeeMin ) { fee = transactionFeeMin; }\n        return (true, fee);\n    }\n\n    function mint(address owner, uint256 value) isReady external returns (bool success) {\n        /*\n            Generating tokens. It can be called only by ICO contract or the moduleHandler.\n\n            @owner      Address\n            @value      Amount.\n\n            @success    Was the Function successful?\n        */\n        require( super.isModuleHandler(payable(msg.sender)) || msg.sender == icoAddr );\n        _mint(owner, value);\n        return true;\n    }\n\n    function _mint(address owner, uint256 value) internal {\n        /*\n            Internal function to generate tokens\n\n            @owner     Token is credited to this address\n            @value     Quantity\n        */\n        require( db.increase(owner, value) );\n        require( moduleHandler(moduleHandlerAddress).broadcastTransfer(address(0x00), owner, value) );\n        if ( isICO ) {\n            require( ico(icoAddr).setInterestDB(owner, db.balanceOf(owner)) );\n        }\n        emit Mint(owner, value);\n    }\n\n    function burn(address owner, uint256 value) isReady external returns (bool success) {\n        /*\n            Burning the token. Can call only modulehandler\n\n            @owner     Burn the token from this address\n            @value     Quantity\n\n            @success    Was the Function successful?\n        */\n        require( super.isModuleHandler(payable(msg.sender)) );\n        _burn(owner, value);\n        return true;\n    }\n\n    function _burn(address owner, uint256 value) internal {\n        /*\n            Internal function to burn the token\n\n            @owner     Burn the token from this address\n            @value     Quantity\n        */\n        require( db.decrease(owner, value) );\n        require( moduleHandler(moduleHandlerAddress).broadcastTransfer(owner, address(0x00), value) );\n        emit Burn(owner, value);\n    }\n\n    function isContract(address addr) internal returns (bool success) {\n        /*\n            Internal function to check if the given address is natural, or a contract\n\n            @addr       Address to be checked\n\n            @success    Is the address contract or not\n        */\n        uint256 _codeLength;\n        assembly {\n            _codeLength := extcodesize(addr)\n        }\n        return _codeLength > 0;\n    }\n\n    function balanceOf(address owner) public view returns (uint256 value) {\n        /*\n            Token balance query\n\n            @owner      Address\n\n            @value      Balance of address\n        */\n        return db.balanceOf(owner);\n    }\n\n    function totalSupply() public view returns (uint256 value) {\n        /*\n            Total token quantity query\n\n            @value      Total token quantity\n        */\n        return db.totalSupply();\n    }\n\n    function configure(announcementType aType, uint256 value) isReady external returns(bool success) {\n        /*\n            Token settings configuration.It  can be call only by moduleHandler\n\n            @aType      Type of setting\n            @value      Value\n\n            @success    Was the Function successful?\n        */\n        require( super.isModuleHandler(payable(msg.sender)) );\n        if      ( aType == announcementType.transactionFeeRate )    { transactionFeeRate = value; }\n        else if ( aType == announcementType.transactionFeeMin )     { transactionFeeMin = value; }\n        else if ( aType == announcementType.transactionFeeMax )     { transactionFeeMax = value; }\n        else if ( aType == announcementType.transactionFeeBurn )    { transactionFeeBurn = value; }\n        else { return false; }\n        return true;\n    }\n\n    event AllowanceUsed(address indexed spender, address indexed owner, uint256 indexed value);\n    event Mint(address indexed addr, uint256 indexed value);\n    event Burn(address indexed addr, uint256 indexed value);\n    event Approval(address indexed _owner, address indexed _spender, uint256 _value);\n    event Transfer(address indexed _from, address indexed _to, uint256 indexed _value, bytes _extraData);\n}\n"
  },
  {
    "path": "test/compilationTests/corion/tokenDB.sol",
    "content": "pragma solidity >=0.0;\n\nimport \"./safeMath.sol\";\nimport \"./owned.sol\";\n\ncontract tokenDB is safeMath, ownedDB {\n\n    struct allowance_s {\n        uint256 amount;\n        uint256 nonce;\n    }\n\n    mapping(address => mapping(address => allowance_s)) public allowance;\n    mapping (address => uint256) public balanceOf;\n    uint256 public totalSupply;\n\n    function increase(address owner, uint256 value) external returns(bool success) {\n        /*\n            Increase of balance of the address in database. Only owner can call it.\n\n            @owner          Address\n            @value          Quantity\n\n            @success        Was the Function successful?\n        */\n        require( isOwner() );\n        balanceOf[owner] = safeAdd(balanceOf[owner], value);\n        totalSupply = safeAdd(totalSupply, value);\n        return true;\n    }\n\n    function decrease(address owner, uint256 value) external returns(bool success) {\n        /*\n            Decrease of balance of the address in database. Only owner can call it.\n\n            @owner          Address\n            @value          Quantity\n\n            @success        Was the Function successful?\n        */\n        require( isOwner() );\n        balanceOf[owner] = safeSub(balanceOf[owner], value);\n        totalSupply = safeSub(totalSupply, value);\n        return true;\n    }\n\n    function setAllowance(address owner, address spender, uint256 amount, uint256 nonce) external returns(bool success) {\n        /*\n            Set allowance in the database. Only owner can call it.\n\n            @owner          Owner address\n            @spender        Spender address\n            @amount         Amount to set\n            @nonce          Transaction count\n\n            @success        Was the Function successful?\n        */\n        require( isOwner() );\n        allowance[owner][spender].amount = amount;\n        allowance[owner][spender].nonce = nonce;\n        return true;\n    }\n\n    function getAllowance(address owner, address spender) public view returns(bool success, uint256 remaining, uint256 nonce) {\n        /*\n            Get allowance from the database.\n\n            @owner          Owner address\n            @spender        Spender address\n\n            @success        Was the Function successful?\n            @remaining      Remaining amount of the allowance\n            @nonce          Transaction count\n        */\n        return ( true, allowance[owner][spender].amount, allowance[owner][spender].nonce );\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Events/CategoricalEvent.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Events/Event.sol\";\n\n\n/// @title Categorical event contract - Categorical events resolve to an outcome from a set of outcomes\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract CategoricalEvent is Event {\n\n    /*\n     *  Public functions\n     */\n    /// @dev Contract constructor validates and sets basic event properties\n    /// @param _collateralToken Tokens used as collateral in exchange for outcome tokens\n    /// @param _oracle Oracle contract used to resolve the event\n    /// @param outcomeCount Number of event outcomes\n    constructor(\n        Token _collateralToken,\n        Oracle _oracle,\n        uint8 outcomeCount\n    )\n        Event(_collateralToken, _oracle, outcomeCount)\n    {\n\n    }\n\n    /// @dev Exchanges sender's winning outcome tokens for collateral tokens\n    /// @return winnings Sender's winnings\n    function redeemWinnings()\n        public\n        override\n        returns (uint winnings)\n    {\n        // Winning outcome has to be set\n        require(isOutcomeSet);\n        // Calculate winnings\n        winnings = outcomeTokens[uint(outcome)].balanceOf(msg.sender);\n        // Revoke tokens from winning outcome\n        outcomeTokens[uint(outcome)].revoke(msg.sender, winnings);\n        // Payout winnings\n        require(collateralToken.transfer(msg.sender, winnings));\n        emit WinningsRedemption(msg.sender, winnings);\n    }\n\n    /// @dev Calculates and returns event hash\n    /// @return Event hash\n    function getEventHash()\n        public\n        override\n        view\n        returns (bytes32)\n    {\n        return keccak256(abi.encodePacked(collateralToken, oracle, outcomeTokens.length));\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Events/Event.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Tokens/Token.sol\";\nimport \"../Tokens/OutcomeToken.sol\";\nimport \"../Oracles/Oracle.sol\";\n\n\n/// @title Event contract - Provide basic functionality required by different event types\n/// @author Stefan George - <stefan@gnosis.pm>\nabstract contract Event {\n\n    /*\n     *  Events\n     */\n    event OutcomeTokenCreation(OutcomeToken outcomeToken, uint8 index);\n    event OutcomeTokenSetIssuance(address indexed buyer, uint collateralTokenCount);\n    event OutcomeTokenSetRevocation(address indexed seller, uint outcomeTokenCount);\n    event OutcomeAssignment(int outcome);\n    event WinningsRedemption(address indexed receiver, uint winnings);\n\n    /*\n     *  Storage\n     */\n    Token public collateralToken;\n    Oracle public oracle;\n    bool public isOutcomeSet;\n    int public outcome;\n    OutcomeToken[] public outcomeTokens;\n\n    /*\n     *  Public functions\n     */\n    /// @dev Contract constructor validates and sets basic event properties\n    /// @param _collateralToken Tokens used as collateral in exchange for outcome tokens\n    /// @param _oracle Oracle contract used to resolve the event\n    /// @param outcomeCount Number of event outcomes\n    constructor(Token _collateralToken, Oracle _oracle, uint8 outcomeCount)\n    {\n        // Validate input\n        require(address(_collateralToken) != address(0) && address(_oracle) != address(0) && outcomeCount >= 2);\n        collateralToken = _collateralToken;\n        oracle = _oracle;\n        // Create an outcome token for each outcome\n        for (uint8 i = 0; i < outcomeCount; i++) {\n            OutcomeToken outcomeToken = new OutcomeToken();\n            outcomeTokens.push(outcomeToken);\n            emit OutcomeTokenCreation(outcomeToken, i);\n        }\n    }\n\n    /// @dev Buys equal number of tokens of all outcomes, exchanging collateral tokens and sets of outcome tokens 1:1\n    /// @param collateralTokenCount Number of collateral tokens\n    function buyAllOutcomes(uint collateralTokenCount)\n        public\n    {\n        // Transfer collateral tokens to events contract\n        require(collateralToken.transferFrom(msg.sender, address(this), collateralTokenCount));\n        // Issue new outcome tokens to sender\n        for (uint8 i = 0; i < outcomeTokens.length; i++)\n            outcomeTokens[i].issue(msg.sender, collateralTokenCount);\n        emit OutcomeTokenSetIssuance(msg.sender, collateralTokenCount);\n    }\n\n    /// @dev Sells equal number of tokens of all outcomes, exchanging collateral tokens and sets of outcome tokens 1:1\n    /// @param outcomeTokenCount Number of outcome tokens\n    function sellAllOutcomes(uint outcomeTokenCount)\n        public\n    {\n        // Revoke sender's outcome tokens of all outcomes\n        for (uint8 i = 0; i < outcomeTokens.length; i++)\n            outcomeTokens[i].revoke(msg.sender, outcomeTokenCount);\n        // Transfer collateral tokens to sender\n        require(collateralToken.transfer(msg.sender, outcomeTokenCount));\n        emit OutcomeTokenSetRevocation(msg.sender, outcomeTokenCount);\n    }\n\n    /// @dev Sets winning event outcome\n    function setOutcome()\n        public\n    {\n        // Winning outcome is not set yet in event contract but in oracle contract\n        require(!isOutcomeSet && oracle.isOutcomeSet());\n        // Set winning outcome\n        outcome = oracle.getOutcome();\n        isOutcomeSet = true;\n        emit OutcomeAssignment(outcome);\n    }\n\n    /// @dev Returns outcome count\n    /// @return Outcome count\n    function getOutcomeCount()\n        public\n        view\n        returns (uint8)\n    {\n        return uint8(outcomeTokens.length);\n    }\n\n    /// @dev Returns outcome tokens array\n    /// @return Outcome tokens\n    function getOutcomeTokens()\n        public\n        view\n        returns (OutcomeToken[] memory)\n    {\n        return outcomeTokens;\n    }\n\n    /// @dev Returns the amount of outcome tokens held by owner\n    /// @return outcomeTokenDistribution Outcome token distribution\n    function getOutcomeTokenDistribution(address owner)\n        public\n        view\n        returns (uint[] memory outcomeTokenDistribution)\n    {\n        outcomeTokenDistribution = new uint[](outcomeTokens.length);\n        for (uint8 i = 0; i < outcomeTokenDistribution.length; i++)\n            outcomeTokenDistribution[i] = outcomeTokens[i].balanceOf(owner);\n    }\n\n    /// @dev Calculates and returns event hash\n    /// @return Event hash\n    function getEventHash() virtual public view returns (bytes32);\n\n    /// @dev Exchanges sender's winning outcome tokens for collateral tokens\n    /// @return Sender's winnings\n    function redeemWinnings() virtual public returns (uint);\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Events/EventFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Events/CategoricalEvent.sol\";\nimport \"../Events/ScalarEvent.sol\";\n\n\n/// @title Event factory contract - Allows creation of categorical and scalar events\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract EventFactory {\n\n    /*\n     *  Events\n     */\n    event CategoricalEventCreation(address indexed creator, CategoricalEvent categoricalEvent, Token collateralToken, Oracle oracle, uint8 outcomeCount);\n    event ScalarEventCreation(address indexed creator, ScalarEvent scalarEvent, Token collateralToken, Oracle oracle, int lowerBound, int upperBound);\n\n    /*\n     *  Storage\n     */\n    mapping (bytes32 => CategoricalEvent) public categoricalEvents;\n    mapping (bytes32 => ScalarEvent) public scalarEvents;\n\n    /*\n     *  Public functions\n     */\n    /// @dev Creates a new categorical event and adds it to the event mapping\n    /// @param collateralToken Tokens used as collateral in exchange for outcome tokens\n    /// @param oracle Oracle contract used to resolve the event\n    /// @param outcomeCount Number of event outcomes\n    /// @return eventContract Event contract\n    function createCategoricalEvent(\n        Token collateralToken,\n        Oracle oracle,\n        uint8 outcomeCount\n    )\n        public\n        returns (CategoricalEvent eventContract)\n    {\n        bytes32 eventHash = keccak256(abi.encodePacked(collateralToken, oracle, outcomeCount));\n        // Event should not exist yet\n        require(address(categoricalEvents[eventHash]) == address(0));\n        // Create event\n        eventContract = new CategoricalEvent(\n            collateralToken,\n            oracle,\n            outcomeCount\n        );\n        categoricalEvents[eventHash] = eventContract;\n        emit CategoricalEventCreation(msg.sender, eventContract, collateralToken, oracle, outcomeCount);\n    }\n\n    /// @dev Creates a new scalar event and adds it to the event mapping\n    /// @param collateralToken Tokens used as collateral in exchange for outcome tokens\n    /// @param oracle Oracle contract used to resolve the event\n    /// @param lowerBound Lower bound for event outcome\n    /// @param upperBound Lower bound for event outcome\n    /// @return eventContract Event contract\n    function createScalarEvent(\n        Token collateralToken,\n        Oracle oracle,\n        int lowerBound,\n        int upperBound\n    )\n        public\n        returns (ScalarEvent eventContract)\n    {\n        bytes32 eventHash = keccak256(abi.encodePacked(collateralToken, oracle, lowerBound, upperBound));\n        // Event should not exist yet\n        require(address(scalarEvents[eventHash]) == address(0));\n        // Create event\n        eventContract = new ScalarEvent(\n            collateralToken,\n            oracle,\n            lowerBound,\n            upperBound\n        );\n        scalarEvents[eventHash] = eventContract;\n        emit ScalarEventCreation(msg.sender, eventContract, collateralToken, oracle, lowerBound, upperBound);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Events/ScalarEvent.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Events/Event.sol\";\n\n\n/// @title Scalar event contract - Scalar events resolve to a number within a range\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract ScalarEvent is Event {\n    using Math for *;\n\n    /*\n     *  Constants\n     */\n    uint8 public constant SHORT = 0;\n    uint8 public constant LONG = 1;\n    uint24 public constant OUTCOME_RANGE = 1000000;\n\n    /*\n     *  Storage\n     */\n    int public lowerBound;\n    int public upperBound;\n\n    /*\n     *  Public functions\n     */\n    /// @dev Contract constructor validates and sets basic event properties\n    /// @param _collateralToken Tokens used as collateral in exchange for outcome tokens\n    /// @param _oracle Oracle contract used to resolve the event\n    /// @param _lowerBound Lower bound for event outcome\n    /// @param _upperBound Lower bound for event outcome\n    constructor(\n        Token _collateralToken,\n        Oracle _oracle,\n        int _lowerBound,\n        int _upperBound\n    )\n        Event(_collateralToken, _oracle, 2)\n    {\n        // Validate bounds\n        require(_upperBound > _lowerBound);\n        lowerBound = _lowerBound;\n        upperBound = _upperBound;\n    }\n\n    /// @dev Exchanges sender's winning outcome tokens for collateral tokens\n    /// @return winnings Sender's winnings\n    function redeemWinnings()\n        public\n        override\n        returns (uint winnings)\n    {\n        // Winning outcome has to be set\n        require(isOutcomeSet);\n        // Calculate winnings\n        uint24 convertedWinningOutcome;\n        // Outcome is lower than defined lower bound\n        if (outcome < lowerBound)\n            convertedWinningOutcome = 0;\n        // Outcome is higher than defined upper bound\n        else if (outcome > upperBound)\n            convertedWinningOutcome = OUTCOME_RANGE;\n        // Map outcome to outcome range\n        else\n            convertedWinningOutcome = uint24(uint(int(uint(OUTCOME_RANGE)) * (outcome - lowerBound) / (upperBound - lowerBound)));\n        uint factorShort = OUTCOME_RANGE - convertedWinningOutcome;\n        uint factorLong = OUTCOME_RANGE - factorShort;\n        uint shortOutcomeTokenCount = outcomeTokens[SHORT].balanceOf(msg.sender);\n        uint longOutcomeTokenCount = outcomeTokens[LONG].balanceOf(msg.sender);\n        winnings = shortOutcomeTokenCount.mul(factorShort).add(longOutcomeTokenCount.mul(factorLong)) / OUTCOME_RANGE;\n        // Revoke all outcome tokens\n        outcomeTokens[SHORT].revoke(msg.sender, shortOutcomeTokenCount);\n        outcomeTokens[LONG].revoke(msg.sender, longOutcomeTokenCount);\n        // Payout winnings to sender\n        require(collateralToken.transfer(msg.sender, winnings));\n        emit WinningsRedemption(msg.sender, winnings);\n    }\n\n    /// @dev Calculates and returns event hash\n    /// @return Event hash\n    function getEventHash()\n        public\n        override\n        view\n        returns (bytes32)\n    {\n        return keccak256(abi.encodePacked(collateralToken, oracle, lowerBound, upperBound));\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    Decentralized prediction markets and decentralized oracle system\n    #Copyright (C) 2015 Forecast Foundation OU, full GPL notice in LICENSE\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    Decentralized prediction markets and decentralized oracle system\n    Copyright (C) 2015 Forecast Foundation OU\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>."
  },
  {
    "path": "test/compilationTests/gnosis/MarketMakers/LMSRMarketMaker.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Utils/Math.sol\";\nimport \"../MarketMakers/MarketMaker.sol\";\n\n\n/// @title LMSR market maker contract - Calculates share prices based on share distribution and initial funding\n/// @author Alan Lu - <alan.lu@gnosis.pm>\ncontract LMSRMarketMaker is MarketMaker {\n    using Math for *;\n\n    /*\n     *  Constants\n     */\n    uint constant ONE = 0x10000000000000000;\n    int constant EXP_LIMIT = 2352680790717288641401;\n\n    /*\n     *  Public functions\n     */\n    /// @dev Returns cost to buy given number of outcome tokens\n    /// @param market Market contract\n    /// @param outcomeTokenIndex Index of outcome to buy\n    /// @param outcomeTokenCount Number of outcome tokens to buy\n    /// @return cost Cost\n    function calcCost(Market market, uint8 outcomeTokenIndex, uint outcomeTokenCount)\n        public\n        override\n        view\n        returns (uint cost)\n    {\n        require(market.eventContract().getOutcomeCount() > 1);\n        int[] memory netOutcomeTokensSold = getNetOutcomeTokensSold(market);\n        // Calculate cost level based on net outcome token balances\n        int logN = Math.ln(netOutcomeTokensSold.length * ONE);\n        uint funding = market.funding();\n        int costLevelBefore = calcCostLevel(logN, netOutcomeTokensSold, funding);\n        // Add outcome token count to net outcome token balance\n        require(int(outcomeTokenCount) >= 0);\n        netOutcomeTokensSold[outcomeTokenIndex] = netOutcomeTokensSold[outcomeTokenIndex].add(int(outcomeTokenCount));\n        // Calculate cost level after balance was updated\n        int costLevelAfter = calcCostLevel(logN, netOutcomeTokensSold, funding);\n        // Calculate cost as cost level difference\n        require(costLevelAfter >= costLevelBefore);\n        cost = uint(costLevelAfter - costLevelBefore);\n        // Take the ceiling to account for rounding\n        if (cost / ONE * ONE == cost)\n            cost /= ONE;\n        else\n            // Integer division by ONE ensures there is room to (+ 1)\n            cost = cost / ONE + 1;\n        // Make sure cost is not bigger than 1 per share\n        if (cost > outcomeTokenCount)\n            cost = outcomeTokenCount;\n    }\n\n    /// @dev Returns profit for selling given number of outcome tokens\n    /// @param market Market contract\n    /// @param outcomeTokenIndex Index of outcome to sell\n    /// @param outcomeTokenCount Number of outcome tokens to sell\n    /// @return profit Profit\n    function calcProfit(Market market, uint8 outcomeTokenIndex, uint outcomeTokenCount)\n        public\n        override\n        view\n        returns (uint profit)\n    {\n        require(market.eventContract().getOutcomeCount() > 1);\n        int[] memory netOutcomeTokensSold = getNetOutcomeTokensSold(market);\n        // Calculate cost level based on net outcome token balances\n        int logN = Math.ln(netOutcomeTokensSold.length * ONE);\n        uint funding = market.funding();\n        int costLevelBefore = calcCostLevel(logN, netOutcomeTokensSold, funding);\n        // Subtract outcome token count from the net outcome token balance\n        require(int(outcomeTokenCount) >= 0);\n        netOutcomeTokensSold[outcomeTokenIndex] = netOutcomeTokensSold[outcomeTokenIndex].sub(int(outcomeTokenCount));\n        // Calculate cost level after balance was updated\n        int costLevelAfter = calcCostLevel(logN, netOutcomeTokensSold, funding);\n        // Calculate profit as cost level difference\n        require(costLevelBefore >= costLevelAfter);\n        // Take the floor\n        profit = uint(costLevelBefore - costLevelAfter) / ONE;\n    }\n\n    /// @dev Returns marginal price of an outcome\n    /// @param market Market contract\n    /// @param outcomeTokenIndex Index of outcome to determine marginal price of\n    /// @return price Marginal price of an outcome as a fixed point number\n    function calcMarginalPrice(Market market, uint8 outcomeTokenIndex)\n        public\n        override\n        view\n        returns (uint price)\n    {\n        require(market.eventContract().getOutcomeCount() > 1);\n        int[] memory netOutcomeTokensSold = getNetOutcomeTokensSold(market);\n        int logN = Math.ln(netOutcomeTokensSold.length * ONE);\n        uint funding = market.funding();\n        // The price function is exp(quantities[i]/b) / sum(exp(q/b) for q in quantities)\n        // To avoid overflow, calculate with\n        // exp(quantities[i]/b - offset) / sum(exp(q/b - offset) for q in quantities)\n        (uint256 sum, , uint256 outcomeExpTerm) = sumExpOffset(logN, netOutcomeTokensSold, funding, outcomeTokenIndex);\n        return outcomeExpTerm / (sum / ONE);\n    }\n\n    /*\n     *  Private functions\n     */\n    /// @dev Calculates the result of the LMSR cost function which is used to\n    ///      derive prices from the market state\n    /// @param logN Logarithm of the number of outcomes\n    /// @param netOutcomeTokensSold Net outcome tokens sold by market\n    /// @param funding Initial funding for market\n    /// @return costLevel Cost level\n    function calcCostLevel(int logN, int[] memory netOutcomeTokensSold, uint funding)\n        private\n        view\n        returns(int costLevel)\n    {\n        // The cost function is C = b * log(sum(exp(q/b) for q in quantities)).\n        // To avoid overflow, we need to calc with an exponent offset:\n        // C = b * (offset + log(sum(exp(q/b - offset) for q in quantities)))\n        (uint256 sum, int256 offset, ) = sumExpOffset(logN, netOutcomeTokensSold, funding, 0);\n        costLevel = Math.ln(sum);\n        costLevel = costLevel.add(offset);\n        costLevel = (costLevel.mul(int(ONE)) / logN).mul(int(funding));\n    }\n\n    /// @dev Calculates sum(exp(q/b - offset) for q in quantities), where offset is set\n    ///      so that the sum fits in 248-256 bits\n    /// @param logN Logarithm of the number of outcomes\n    /// @param netOutcomeTokensSold Net outcome tokens sold by market\n    /// @param funding Initial funding for market\n    /// @param outcomeIndex Index of exponential term to extract (for use by marginal price function)\n    /// @return sum The sum of the outcomes\n    /// @return offset The offset that is used for all\n    /// @return outcomeExpTerm The summand associated with the supplied index\n    function sumExpOffset(int logN, int[] memory netOutcomeTokensSold, uint funding, uint8 outcomeIndex)\n        private\n        view\n        returns (uint sum, int offset, uint outcomeExpTerm)\n    {\n        // Naive calculation of this causes an overflow\n        // since anything above a bit over 133*ONE supplied to exp will explode\n        // as exp(133) just about fits into 192 bits of whole number data.\n\n        // The choice of this offset is subject to another limit:\n        // computing the inner sum successfully.\n        // Since the index is 8 bits, there has to be 8 bits of headroom for\n        // each summand, meaning q/b - offset <= exponential_limit,\n        // where that limit can be found with `mp.floor(mp.log((2**248 - 1) / ONE) * ONE)`\n        // That is what EXP_LIMIT is set to: it is about 127.5\n\n        // finally, if the distribution looks like [BIG, tiny, tiny...], using a\n        // BIG offset will cause the tiny quantities to go really negative\n        // causing the associated exponentials to vanish.\n\n        int maxQuantity = Math.max(netOutcomeTokensSold);\n        require(logN >= 0 && int(funding) >= 0);\n        offset = maxQuantity.mul(logN) / int(funding);\n        offset = offset.sub(EXP_LIMIT);\n        uint term;\n        for (uint8 i = 0; i < netOutcomeTokensSold.length; i++) {\n            term = Math.exp((netOutcomeTokensSold[i].mul(logN) / int(funding)).sub(offset));\n            if (i == outcomeIndex)\n                outcomeExpTerm = term;\n            sum = sum.add(term);\n        }\n    }\n\n    /// @dev Gets net outcome tokens sold by market. Since all sets of outcome tokens are backed by\n    ///      corresponding collateral tokens, the net quantity of a token sold by the market is the\n    ///      number of collateral tokens (which is the same as the number of outcome tokens the\n    ///      market created) subtracted by the quantity of that token held by the market.\n    /// @param market Market contract\n    /// @return quantities Net outcome tokens sold by market\n    function getNetOutcomeTokensSold(Market market)\n        private\n        view\n        returns (int[] memory quantities)\n    {\n        quantities = new int[](market.eventContract().getOutcomeCount());\n        for (uint8 i = 0; i < quantities.length; i++)\n            quantities[i] = market.netOutcomeTokensSold(i);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/MarketMakers/MarketMaker.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Markets/Market.sol\";\n\n\n/// @title Abstract market maker contract - Functions to be implemented by market maker contracts\nabstract contract MarketMaker {\n\n    /*\n     *  Public functions\n     */\n    function calcCost(Market market, uint8 outcomeTokenIndex, uint outcomeTokenCount) virtual public view returns (uint);\n    function calcProfit(Market market, uint8 outcomeTokenIndex, uint outcomeTokenCount) virtual public view returns (uint);\n    function calcMarginalPrice(Market market, uint8 outcomeTokenIndex) virtual public view returns (uint);\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Markets/Campaign.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Events/Event.sol\";\nimport \"../Markets/StandardMarketFactory.sol\";\nimport \"../Utils/Math.sol\";\n\n\n/// @title Campaign contract - Allows to crowdfund a market\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract Campaign {\n    using Math for *;\n\n    /*\n     *  Events\n     */\n    event CampaignFunding(address indexed sender, uint funding);\n    event CampaignRefund(address indexed sender, uint refund);\n    event MarketCreation(Market indexed market);\n    event MarketClosing();\n    event FeeWithdrawal(address indexed receiver, uint fees);\n\n     /*\n     *  Constants\n     */\n    uint24 public constant FEE_RANGE = 1000000; // 100%\n\n    /*\n     *  Storage\n     */\n    Event public eventContract;\n    MarketFactory public marketFactory;\n    MarketMaker public marketMaker;\n    Market public market;\n    uint24 public fee;\n    uint public funding;\n    uint public deadline;\n    uint public finalBalance;\n    mapping (address => uint) public contributions;\n    Stages public stage;\n\n    enum Stages {\n        AuctionStarted,\n        AuctionSuccessful,\n        AuctionFailed,\n        MarketCreated,\n        MarketClosed\n    }\n\n    /*\n     *  Modifiers\n     */\n    modifier atStage(Stages _stage) {\n        // Contract has to be in given stage\n        require(stage == _stage);\n        _;\n    }\n\n    modifier timedTransitions() {\n        if (stage == Stages.AuctionStarted && deadline < block.timestamp)\n            stage = Stages.AuctionFailed;\n        _;\n    }\n\n    /*\n     *  Public functions\n     */\n    /// @dev Constructor validates and sets campaign properties\n    /// @param _eventContract Event contract\n    /// @param _marketFactory Market factory contract\n    /// @param _marketMaker Market maker contract\n    /// @param _fee Market fee\n    /// @param _funding Initial funding for market\n    /// @param _deadline Campaign deadline\n    constructor(\n        Event _eventContract,\n        MarketFactory _marketFactory,\n        MarketMaker _marketMaker,\n        uint24 _fee,\n        uint _funding,\n        uint _deadline\n    )\n    {\n        // Validate input\n        require(   address(_eventContract) != address(0)\n                && address(_marketFactory) != address(0)\n                && address(_marketMaker) != address(0)\n                && _fee < FEE_RANGE\n                && _funding > 0\n                && block.timestamp < _deadline);\n        eventContract = _eventContract;\n        marketFactory = _marketFactory;\n        marketMaker = _marketMaker;\n        fee = _fee;\n        funding = _funding;\n        deadline = _deadline;\n    }\n\n    /// @dev Allows to contribute to required market funding\n    /// @param amount Amount of collateral tokens\n    function fund(uint amount)\n        public\n        timedTransitions\n        atStage(Stages.AuctionStarted)\n    {\n        uint raisedAmount = eventContract.collateralToken().balanceOf(address(this));\n        uint maxAmount = funding.sub(raisedAmount);\n        if (maxAmount < amount)\n            amount = maxAmount;\n        // Collect collateral tokens\n        require(eventContract.collateralToken().transferFrom(msg.sender, address(this), amount));\n        contributions[msg.sender] = contributions[msg.sender].add(amount);\n        if (amount == maxAmount)\n            stage = Stages.AuctionSuccessful;\n        emit CampaignFunding(msg.sender, amount);\n    }\n\n    /// @dev Withdraws refund amount\n    /// @return refundAmount Refund amount\n    function refund()\n        public\n        timedTransitions\n        atStage(Stages.AuctionFailed)\n        returns (uint refundAmount)\n    {\n        refundAmount = contributions[msg.sender];\n        contributions[msg.sender] = 0;\n        // Refund collateral tokens\n        require(eventContract.collateralToken().transfer(msg.sender, refundAmount));\n        emit CampaignRefund(msg.sender, refundAmount);\n    }\n\n    /// @dev Allows to create market after successful funding\n    /// @return Market address\n    function createMarket()\n        public\n        timedTransitions\n        atStage(Stages.AuctionSuccessful)\n        returns (Market)\n    {\n        market = marketFactory.createMarket(eventContract, marketMaker, fee);\n        require(eventContract.collateralToken().approve(address(market), funding));\n        market.fund(funding);\n        stage = Stages.MarketCreated;\n        emit MarketCreation(market);\n        return market;\n    }\n\n    /// @dev Allows to withdraw fees from market contract to campaign contract\n    function closeMarket()\n        public\n        atStage(Stages.MarketCreated)\n    {\n        // Winning outcome should be set\n        require(eventContract.isOutcomeSet());\n        market.close();\n        market.withdrawFees();\n        eventContract.redeemWinnings();\n        finalBalance = eventContract.collateralToken().balanceOf(address(this));\n        stage = Stages.MarketClosed;\n        emit MarketClosing();\n    }\n\n    /// @dev Allows to withdraw fees from campaign contract to contributor\n    /// @return fees Fee amount\n    function withdrawFees()\n        public\n        atStage(Stages.MarketClosed)\n        returns (uint fees)\n    {\n        fees = finalBalance.mul(contributions[msg.sender]) / funding;\n        contributions[msg.sender] = 0;\n        // Send fee share to contributor\n        require(eventContract.collateralToken().transfer(msg.sender, fees));\n        emit FeeWithdrawal(msg.sender, fees);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Markets/CampaignFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Markets/Campaign.sol\";\n\n\n/// @title Campaign factory contract - Allows to create campaign contracts\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract CampaignFactory {\n\n    /*\n     *  Events\n     */\n    event CampaignCreation(address indexed creator, Campaign campaign, Event eventContract, MarketFactory marketFactory, MarketMaker marketMaker, uint24 fee, uint funding, uint deadline);\n\n    /*\n     *  Public functions\n     */\n    /// @dev Creates a new campaign contract\n    /// @param eventContract Event contract\n    /// @param marketFactory Market factory contract\n    /// @param marketMaker Market maker contract\n    /// @param fee Market fee\n    /// @param funding Initial funding for market\n    /// @param deadline Campaign deadline\n    /// @return campaign Market contract\n    function createCampaigns(\n        Event eventContract,\n        MarketFactory marketFactory,\n        MarketMaker marketMaker,\n        uint24 fee,\n        uint funding,\n        uint deadline\n    )\n        public\n        returns (Campaign campaign)\n    {\n        campaign = new Campaign(eventContract, marketFactory, marketMaker, fee, funding, deadline);\n        emit CampaignCreation(msg.sender, campaign, eventContract, marketFactory, marketMaker, fee, funding, deadline);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Markets/Market.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Events/Event.sol\";\nimport \"../MarketMakers/MarketMaker.sol\";\n\n\n/// @title Abstract market contract - Functions to be implemented by market contracts\nabstract contract Market {\n\n    /*\n     *  Events\n     */\n    event MarketFunding(uint funding);\n    event MarketClosing();\n    event FeeWithdrawal(uint fees);\n    event OutcomeTokenPurchase(address indexed buyer, uint8 outcomeTokenIndex, uint outcomeTokenCount, uint cost);\n    event OutcomeTokenSale(address indexed seller, uint8 outcomeTokenIndex, uint outcomeTokenCount, uint profit);\n    event OutcomeTokenShortSale(address indexed buyer, uint8 outcomeTokenIndex, uint outcomeTokenCount, uint cost);\n\n    /*\n     *  Storage\n     */\n    address public creator;\n    uint public createdAtBlock;\n    Event public eventContract;\n    MarketMaker public marketMaker;\n    uint24 public fee;\n    uint public funding;\n    int[] public netOutcomeTokensSold;\n    Stages public stage;\n\n    enum Stages {\n        MarketCreated,\n        MarketFunded,\n        MarketClosed\n    }\n\n    /*\n     *  Public functions\n     */\n    function fund(uint _funding) virtual public;\n    function close() virtual public;\n    function withdrawFees() virtual public returns (uint);\n    function buy(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint maxCost) virtual public returns (uint);\n    function sell(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint minProfit) virtual public returns (uint);\n    function shortSell(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint minProfit) virtual public returns (uint);\n    function calcMarketFee(uint outcomeTokenCost) virtual public view returns (uint);\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Markets/MarketFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Events/Event.sol\";\nimport \"../MarketMakers/MarketMaker.sol\";\nimport \"../Markets/Market.sol\";\n\n\n/// @title Abstract market factory contract - Functions to be implemented by market factories\nabstract contract MarketFactory {\n\n    /*\n     *  Events\n     */\n    event MarketCreation(address indexed creator, Market market, Event eventContract, MarketMaker marketMaker, uint24 fee);\n\n    /*\n     *  Public functions\n     */\n    function createMarket(Event eventContract, MarketMaker marketMaker, uint24\nfee) virtual public returns (Market);\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Markets/StandardMarket.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Markets/Market.sol\";\nimport \"../Tokens/Token.sol\";\nimport \"../Events/Event.sol\";\nimport \"../MarketMakers/MarketMaker.sol\";\n\n\n/// @title Market factory contract - Allows to create market contracts\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract StandardMarket is Market {\n    using Math for *;\n\n    /*\n     *  Constants\n     */\n    uint24 public constant FEE_RANGE = 1000000; // 100%\n\n    /*\n     *  Modifiers\n     */\n    modifier isCreator () {\n        // Only creator is allowed to proceed\n        require(msg.sender == creator);\n        _;\n    }\n\n    modifier atStage(Stages _stage) {\n        // Contract has to be in given stage\n        require(stage == _stage);\n        _;\n    }\n\n    /*\n     *  Public functions\n     */\n    /// @dev Constructor validates and sets market properties\n    /// @param _creator Market creator\n    /// @param _eventContract Event contract\n    /// @param _marketMaker Market maker contract\n    /// @param _fee Market fee\n    constructor(address _creator, Event _eventContract, MarketMaker _marketMaker, uint24 _fee)\n    {\n        // Validate inputs\n        require(address(_eventContract) != address(0) && address(_marketMaker) != address(0) && _fee < FEE_RANGE);\n        creator = _creator;\n        createdAtBlock = block.number;\n        eventContract = _eventContract;\n        netOutcomeTokensSold = new int[](eventContract.getOutcomeCount());\n        fee = _fee;\n        marketMaker = _marketMaker;\n        stage = Stages.MarketCreated;\n    }\n\n    /// @dev Allows to fund the market with collateral tokens converting them into outcome tokens\n    /// @param _funding Funding amount\n    function fund(uint _funding)\n        public\n        override\n        isCreator\n        atStage(Stages.MarketCreated)\n    {\n        // Request collateral tokens and allow event contract to transfer them to buy all outcomes\n        require(   eventContract.collateralToken().transferFrom(msg.sender, address(this), _funding)\n                && eventContract.collateralToken().approve(address(eventContract), _funding));\n        eventContract.buyAllOutcomes(_funding);\n        funding = _funding;\n        stage = Stages.MarketFunded;\n        emit MarketFunding(funding);\n    }\n\n    /// @dev Allows market creator to close the markets by transferring all remaining outcome tokens to the creator\n    function close()\n        override\n        public\n        isCreator\n        atStage(Stages.MarketFunded)\n    {\n        uint8 outcomeCount = eventContract.getOutcomeCount();\n        for (uint8 i = 0; i < outcomeCount; i++)\n            require(eventContract.outcomeTokens(i).transfer(creator, eventContract.outcomeTokens(i).balanceOf(address(this))));\n        stage = Stages.MarketClosed;\n        emit MarketClosing();\n    }\n\n    /// @dev Allows market creator to withdraw fees generated by trades\n    /// @return fees Fee amount\n    function withdrawFees()\n        public\n        override\n        isCreator\n        returns (uint fees)\n    {\n        fees = eventContract.collateralToken().balanceOf(address(this));\n        // Transfer fees\n        require(eventContract.collateralToken().transfer(creator, fees));\n        emit FeeWithdrawal(fees);\n    }\n\n    /// @dev Allows to buy outcome tokens from market maker\n    /// @param outcomeTokenIndex Index of the outcome token to buy\n    /// @param outcomeTokenCount Amount of outcome tokens to buy\n    /// @param maxCost The maximum cost in collateral tokens to pay for outcome tokens\n    /// @return cost Cost in collateral tokens\n    function buy(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint maxCost)\n        public\n        override\n        atStage(Stages.MarketFunded)\n        returns (uint cost)\n    {\n        // Calculate cost to buy outcome tokens\n        uint outcomeTokenCost = marketMaker.calcCost(this, outcomeTokenIndex, outcomeTokenCount);\n        // Calculate fees charged by market\n        uint fees = calcMarketFee(outcomeTokenCost);\n        cost = outcomeTokenCost.add(fees);\n        // Check cost doesn't exceed max cost\n        require(cost > 0 && cost <= maxCost);\n        // Transfer tokens to markets contract and buy all outcomes\n        require(   eventContract.collateralToken().transferFrom(msg.sender, address(this), cost)\n                && eventContract.collateralToken().approve(address(eventContract), outcomeTokenCost));\n        // Buy all outcomes\n        eventContract.buyAllOutcomes(outcomeTokenCost);\n        // Transfer outcome tokens to buyer\n        require(eventContract.outcomeTokens(outcomeTokenIndex).transfer(msg.sender, outcomeTokenCount));\n        // Add outcome token count to market maker net balance\n        require(int(outcomeTokenCount) >= 0);\n        netOutcomeTokensSold[outcomeTokenIndex] = netOutcomeTokensSold[outcomeTokenIndex].add(int(outcomeTokenCount));\n        emit OutcomeTokenPurchase(msg.sender, outcomeTokenIndex, outcomeTokenCount, cost);\n    }\n\n    /// @dev Allows to sell outcome tokens to market maker\n    /// @param outcomeTokenIndex Index of the outcome token to sell\n    /// @param outcomeTokenCount Amount of outcome tokens to sell\n    /// @param minProfit The minimum profit in collateral tokens to earn for outcome tokens\n    /// @return profit Profit in collateral tokens\n    function sell(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint minProfit)\n        public\n        override\n        atStage(Stages.MarketFunded)\n        returns (uint profit)\n    {\n        // Calculate profit for selling outcome tokens\n        uint outcomeTokenProfit = marketMaker.calcProfit(this, outcomeTokenIndex, outcomeTokenCount);\n        // Calculate fee charged by market\n        uint fees = calcMarketFee(outcomeTokenProfit);\n        profit = outcomeTokenProfit.sub(fees);\n        // Check profit is not too low\n        require(profit > 0 && profit >= minProfit);\n        // Transfer outcome tokens to markets contract to sell all outcomes\n        require(eventContract.outcomeTokens(outcomeTokenIndex).transferFrom(msg.sender, address(this), outcomeTokenCount));\n        // Sell all outcomes\n        eventContract.sellAllOutcomes(outcomeTokenProfit);\n        // Transfer profit to seller\n        require(eventContract.collateralToken().transfer(msg.sender, profit));\n        // Subtract outcome token count from market maker net balance\n        require(int(outcomeTokenCount) >= 0);\n        netOutcomeTokensSold[outcomeTokenIndex] = netOutcomeTokensSold[outcomeTokenIndex].sub(int(outcomeTokenCount));\n        emit OutcomeTokenSale(msg.sender, outcomeTokenIndex, outcomeTokenCount, profit);\n    }\n\n    /// @dev Buys all outcomes, then sells all shares of selected outcome which were bought, keeping\n    ///      shares of all other outcome tokens.\n    /// @param outcomeTokenIndex Index of the outcome token to short sell\n    /// @param outcomeTokenCount Amount of outcome tokens to short sell\n    /// @param minProfit The minimum profit in collateral tokens to earn for short sold outcome tokens\n    /// @return cost Cost to short sell outcome in collateral tokens\n    function shortSell(uint8 outcomeTokenIndex, uint outcomeTokenCount, uint minProfit)\n        public\n        override\n        returns (uint cost)\n    {\n        // Buy all outcomes\n        require(   eventContract.collateralToken().transferFrom(msg.sender, address(this), outcomeTokenCount)\n                && eventContract.collateralToken().approve(address(eventContract), outcomeTokenCount));\n        eventContract.buyAllOutcomes(outcomeTokenCount);\n        // Short sell selected outcome\n        eventContract.outcomeTokens(outcomeTokenIndex).approve(address(this), outcomeTokenCount);\n        uint profit = this.sell(outcomeTokenIndex, outcomeTokenCount, minProfit);\n        cost = outcomeTokenCount - profit;\n        // Transfer outcome tokens to buyer\n        uint8 outcomeCount = eventContract.getOutcomeCount();\n        for (uint8 i = 0; i < outcomeCount; i++)\n            if (i != outcomeTokenIndex)\n                require(eventContract.outcomeTokens(i).transfer(msg.sender, outcomeTokenCount));\n        // Send change back to buyer\n        require(eventContract.collateralToken().transfer(msg.sender, profit));\n        emit OutcomeTokenShortSale(msg.sender, outcomeTokenIndex, outcomeTokenCount, cost);\n    }\n\n    /// @dev Calculates fee to be paid to market maker\n    /// @param outcomeTokenCost Cost for buying outcome tokens\n    /// @return Fee for trade\n    function calcMarketFee(uint outcomeTokenCost)\n        public\n        override\n        view\n        returns (uint)\n    {\n        return outcomeTokenCost * fee / FEE_RANGE;\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Markets/StandardMarketFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Markets/MarketFactory.sol\";\nimport \"../Markets/StandardMarket.sol\";\n\n\n/// @title Market factory contract - Allows to create market contracts\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract StandardMarketFactory is MarketFactory {\n\n    /*\n     *  Public functions\n     */\n    /// @dev Creates a new market contract\n    /// @param eventContract Event contract\n    /// @param marketMaker Market maker contract\n    /// @param fee Market fee\n    /// @return market Market contract\n    function createMarket(Event eventContract, MarketMaker marketMaker, uint24 fee)\n        public\n        override\n        returns (Market market)\n    {\n        market = new StandardMarket(msg.sender, eventContract, marketMaker, fee);\n        emit MarketCreation(msg.sender, market, eventContract, marketMaker, fee);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Migrations.sol",
    "content": "pragma solidity >=0.0;\n\ncontract Migrations {\n  address public owner;\n  uint public last_completed_migration;\n\n  modifier restricted() {\n    if (msg.sender == owner) _;\n  }\n\n  constructor() {\n    owner = msg.sender;\n  }\n\n  function setCompleted(uint completed) public restricted {\n    last_completed_migration = completed;\n  }\n\n  function upgrade(address new_address) public restricted {\n    Migrations upgraded = Migrations(new_address);\n    upgraded.setCompleted(last_completed_migration);\n  }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/CentralizedOracle.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/Oracle.sol\";\n\n\n/// @title Centralized oracle contract - Allows the contract owner to set an outcome\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract CentralizedOracle is Oracle {\n\n    /*\n     *  Events\n     */\n    event OwnerReplacement(address indexed newOwner);\n    event OutcomeAssignment(int outcome);\n\n    /*\n     *  Storage\n     */\n    address public owner;\n    bytes public ipfsHash;\n    bool public isSet;\n    int public outcome;\n\n    /*\n     *  Modifiers\n     */\n    modifier isOwner () {\n        // Only owner is allowed to proceed\n        require(msg.sender == owner);\n        _;\n    }\n\n    /*\n     *  Public functions\n     */\n    /// @dev Constructor sets owner address and IPFS hash\n    /// @param _ipfsHash Hash identifying off chain event description\n    constructor(address _owner, bytes memory _ipfsHash)\n    {\n        // Description hash cannot be null\n        require(_ipfsHash.length == 46);\n        owner = _owner;\n        ipfsHash = _ipfsHash;\n    }\n\n    /// @dev Replaces owner\n    /// @param newOwner New owner\n    function replaceOwner(address newOwner)\n        public\n        isOwner\n    {\n        // Result is not set yet\n        require(!isSet);\n        owner = newOwner;\n        emit OwnerReplacement(newOwner);\n    }\n\n    /// @dev Sets event outcome\n    /// @param _outcome Event outcome\n    function setOutcome(int _outcome)\n        public\n        isOwner\n    {\n        // Result is not set yet\n        require(!isSet);\n        isSet = true;\n        outcome = _outcome;\n        emit OutcomeAssignment(_outcome);\n    }\n\n    /// @dev Returns if winning outcome is set\n    /// @return Is outcome set?\n    function isOutcomeSet()\n        public\n        override\n        view\n        returns (bool)\n    {\n        return isSet;\n    }\n\n    /// @dev Returns outcome\n    /// @return Outcome\n    function getOutcome()\n        public\n        override\n        view\n        returns (int)\n    {\n        return outcome;\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/CentralizedOracleFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/CentralizedOracle.sol\";\n\n\n/// @title Centralized oracle factory contract - Allows to create centralized oracle contracts\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract CentralizedOracleFactory {\n\n    /*\n     *  Events\n     */\n    event CentralizedOracleCreation(address indexed creator, CentralizedOracle centralizedOracle, bytes ipfsHash);\n\n    /*\n     *  Public functions\n     */\n    /// @dev Creates a new centralized oracle contract\n    /// @param ipfsHash Hash identifying off chain event description\n    /// @return centralizedOracle Oracle contract\n    function createCentralizedOracle(bytes memory ipfsHash)\n        public\n        returns (CentralizedOracle centralizedOracle)\n    {\n        centralizedOracle = new CentralizedOracle(msg.sender, ipfsHash);\n        emit CentralizedOracleCreation(msg.sender, centralizedOracle, ipfsHash);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/DifficultyOracle.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/Oracle.sol\";\n\n\n/// @title Difficulty oracle contract - Oracle to resolve difficulty events at given block\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract DifficultyOracle is Oracle {\n\n    /*\n     *  Events\n     */\n    event OutcomeAssignment(uint difficulty);\n\n    /*\n     *  Storage\n     */\n    uint public blockNumber;\n    uint public difficulty;\n\n    /*\n     *  Public functions\n     */\n    /// @dev Contract constructor validates and sets target block number\n    /// @param _blockNumber Target block number\n    constructor(uint _blockNumber)\n    {\n        // Block has to be in the future\n        require(_blockNumber > block.number);\n        blockNumber = _blockNumber;\n    }\n\n    /// @dev Sets difficulty as winning outcome for specified block\n    function setOutcome()\n        public\n    {\n        // Block number was reached and outcome was not set yet\n        require(block.number >= blockNumber && difficulty == 0);\n        difficulty = block.difficulty;\n        emit OutcomeAssignment(difficulty);\n    }\n\n    /// @dev Returns if difficulty is set\n    /// @return Is outcome set?\n    function isOutcomeSet()\n        public\n        override\n        view\n        returns (bool)\n    {\n        // Difficulty is always bigger than 0\n        return difficulty > 0;\n    }\n\n    /// @dev Returns difficulty\n    /// @return Outcome\n    function getOutcome()\n        public\n        override\n        view\n        returns (int)\n    {\n        return int(difficulty);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/DifficultyOracleFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/DifficultyOracle.sol\";\n\n\n/// @title Difficulty oracle factory contract - Allows to create difficulty oracle contracts\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract DifficultyOracleFactory {\n\n    /*\n     *  Events\n     */\n    event DifficultyOracleCreation(address indexed creator, DifficultyOracle difficultyOracle, uint blockNumber);\n\n    /*\n     *  Public functions\n     */\n    /// @dev Creates a new difficulty oracle contract\n    /// @param blockNumber Target block number\n    /// @return difficultyOracle Oracle contract\n    function createDifficultyOracle(uint blockNumber)\n        public\n        returns (DifficultyOracle difficultyOracle)\n    {\n        difficultyOracle = new DifficultyOracle(blockNumber);\n        emit DifficultyOracleCreation(msg.sender, difficultyOracle, blockNumber);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/FutarchyOracle.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/Oracle.sol\";\nimport \"../Events/EventFactory.sol\";\nimport \"../Markets/MarketFactory.sol\";\n\n\n/// @title Futarchy oracle contract - Allows to create an oracle based on market behaviour\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract FutarchyOracle is Oracle {\n    using Math for *;\n\n    /*\n     *  Events\n     */\n    event FutarchyFunding(uint funding);\n    event FutarchyClosing();\n    event OutcomeAssignment(uint winningMarketIndex);\n\n    /*\n     *  Constants\n     */\n    uint8 public constant LONG = 1;\n\n    /*\n     *  Storage\n     */\n    address creator;\n    Market[] public markets;\n    CategoricalEvent public categoricalEvent;\n    uint public deadline;\n    uint public winningMarketIndex;\n    bool public isSet;\n\n    /*\n     *  Modifiers\n     */\n    modifier isCreator () {\n        // Only creator is allowed to proceed\n        require(msg.sender == creator);\n        _;\n    }\n\n    /*\n     *  Public functions\n     */\n    /// @dev Constructor creates events and markets for futarchy oracle\n    /// @param _creator Oracle creator\n    /// @param eventFactory Event factory contract\n    /// @param collateralToken Tokens used as collateral in exchange for outcome tokens\n    /// @param oracle Oracle contract used to resolve the event\n    /// @param outcomeCount Number of event outcomes\n    /// @param lowerBound Lower bound for event outcome\n    /// @param upperBound Lower bound for event outcome\n    /// @param marketFactory Market factory contract\n    /// @param marketMaker Market maker contract\n    /// @param fee Market fee\n    /// @param _deadline Decision deadline\n    constructor(\n        address _creator,\n        EventFactory eventFactory,\n        Token collateralToken,\n        Oracle oracle,\n        uint8 outcomeCount,\n        int lowerBound,\n        int upperBound,\n        MarketFactory marketFactory,\n        MarketMaker marketMaker,\n        uint24 fee,\n        uint _deadline\n    )\n    {\n        // Deadline is in the future\n        require(_deadline > block.timestamp);\n        // Create decision event\n        categoricalEvent = eventFactory.createCategoricalEvent(collateralToken, this, outcomeCount);\n        // Create outcome events\n        for (uint8 i = 0; i < categoricalEvent.getOutcomeCount(); i++) {\n            ScalarEvent scalarEvent = eventFactory.createScalarEvent(\n                categoricalEvent.outcomeTokens(i),\n                oracle,\n                lowerBound,\n                upperBound\n            );\n            markets.push(marketFactory.createMarket(scalarEvent, marketMaker, fee));\n        }\n        creator = _creator;\n        deadline = _deadline;\n    }\n\n    /// @dev Funds all markets with equal amount of funding\n    /// @param funding Amount of funding\n    function fund(uint funding)\n        public\n        isCreator\n    {\n        // Buy all outcomes\n        require(   categoricalEvent.collateralToken().transferFrom(creator, address(this), funding)\n                && categoricalEvent.collateralToken().approve(address(categoricalEvent), funding));\n        categoricalEvent.buyAllOutcomes(funding);\n        // Fund each market with outcome tokens from categorical event\n        for (uint8 i = 0; i < markets.length; i++) {\n            Market market = markets[i];\n            // Approve funding for market\n            require(market.eventContract().collateralToken().approve(address(market), funding));\n            market.fund(funding);\n        }\n        emit FutarchyFunding(funding);\n    }\n\n    /// @dev Closes market for winning outcome and redeems winnings and sends all collateral tokens to creator\n    function close()\n        public\n        isCreator\n    {\n        // Winning outcome has to be set\n        Market market = markets[uint(getOutcome())];\n        require(categoricalEvent.isOutcomeSet() && market.eventContract().isOutcomeSet());\n        // Close market and transfer all outcome tokens from winning outcome to this contract\n        market.close();\n        market.eventContract().redeemWinnings();\n        market.withdrawFees();\n        // Redeem collateral token for winning outcome tokens and transfer collateral tokens to creator\n        categoricalEvent.redeemWinnings();\n        require(categoricalEvent.collateralToken().transfer(creator, categoricalEvent.collateralToken().balanceOf(address(this))));\n        emit FutarchyClosing();\n    }\n\n    /// @dev Allows to set the oracle outcome based on the market with largest long position\n    function setOutcome()\n        public\n    {\n        // Outcome is not set yet and deadline has passed\n        require(!isSet && deadline <= block.timestamp);\n        // Find market with highest marginal price for long outcome tokens\n        uint highestMarginalPrice = markets[0].marketMaker().calcMarginalPrice(markets[0], LONG);\n        uint highestIndex = 0;\n        for (uint8 i = 1; i < markets.length; i++) {\n            uint marginalPrice = markets[i].marketMaker().calcMarginalPrice(markets[i], LONG);\n            if (marginalPrice > highestMarginalPrice) {\n                highestMarginalPrice = marginalPrice;\n                highestIndex = i;\n            }\n        }\n        winningMarketIndex = highestIndex;\n        isSet = true;\n        emit OutcomeAssignment(winningMarketIndex);\n    }\n\n    /// @dev Returns if winning outcome is set\n    /// @return Is outcome set?\n    function isOutcomeSet()\n        public\n        override\n        view\n        returns (bool)\n    {\n        return isSet;\n    }\n\n    /// @dev Returns winning outcome\n    /// @return Outcome\n    function getOutcome()\n        public\n        override\n        view\n        returns (int)\n    {\n        return int(winningMarketIndex);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/FutarchyOracleFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/FutarchyOracle.sol\";\n\n\n/// @title Futarchy oracle factory contract - Allows to create Futarchy oracle contracts\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract FutarchyOracleFactory {\n\n    /*\n     *  Events\n     */\n    event FutarchyOracleCreation(\n        address indexed creator,\n        FutarchyOracle futarchyOracle,\n        Token collateralToken,\n        Oracle oracle,\n        uint8 outcomeCount,\n        int lowerBound,\n        int upperBound,\n        MarketFactory marketFactory,\n        MarketMaker marketMaker,\n        uint24 fee,\n        uint deadline\n    );\n\n    /*\n     *  Storage\n     */\n    EventFactory eventFactory;\n\n    /*\n     *  Public functions\n     */\n    /// @dev Constructor sets event factory contract\n    /// @param _eventFactory Event factory contract\n    constructor(EventFactory _eventFactory)\n    {\n        require(address(_eventFactory) != address(0));\n        eventFactory = _eventFactory;\n    }\n\n    /// @dev Creates a new Futarchy oracle contract\n    /// @param collateralToken Tokens used as collateral in exchange for outcome tokens\n    /// @param oracle Oracle contract used to resolve the event\n    /// @param outcomeCount Number of event outcomes\n    /// @param lowerBound Lower bound for event outcome\n    /// @param upperBound Lower bound for event outcome\n    /// @param marketFactory Market factory contract\n    /// @param marketMaker Market maker contract\n    /// @param fee Market fee\n    /// @param deadline Decision deadline\n    /// @return futarchyOracle Oracle contract\n    function createFutarchyOracle(\n        Token collateralToken,\n        Oracle oracle,\n        uint8 outcomeCount,\n        int lowerBound,\n        int upperBound,\n        MarketFactory marketFactory,\n        MarketMaker marketMaker,\n        uint24 fee,\n        uint deadline\n    )\n        public\n        returns (FutarchyOracle futarchyOracle)\n    {\n        futarchyOracle = new FutarchyOracle(\n            msg.sender,\n            eventFactory,\n            collateralToken,\n            oracle,\n            outcomeCount,\n            lowerBound,\n            upperBound,\n            marketFactory,\n            marketMaker,\n            fee,\n            deadline\n        );\n        emit FutarchyOracleCreation(\n            msg.sender,\n            futarchyOracle,\n            collateralToken,\n            oracle,\n            outcomeCount,\n            lowerBound,\n            upperBound,\n            marketFactory,\n            marketMaker,\n            fee,\n            deadline\n        );\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/MajorityOracle.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/Oracle.sol\";\n\n\n/// @title Majority oracle contract - Allows to resolve an event based on multiple oracles with majority vote\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract MajorityOracle is Oracle {\n\n    /*\n     *  Storage\n     */\n    Oracle[] public oracles;\n\n    /*\n     *  Public functions\n     */\n    /// @dev Allows to create an oracle for a majority vote based on other oracles\n    /// @param _oracles List of oracles taking part in the majority vote\n    constructor(Oracle[] memory _oracles)\n    {\n        // At least 2 oracles should be defined\n        require(_oracles.length > 2);\n        for (uint i = 0; i < _oracles.length; i++)\n            // Oracle address cannot be null\n            require(address(_oracles[i]) != address(0));\n        oracles = _oracles;\n    }\n\n    /// @dev Allows to registers oracles for a majority vote\n    /// @return outcomeSet Is outcome set?\n    /// @return outcome Outcome\n    function getStatusAndOutcome()\n        public\n        view\n        returns (bool outcomeSet, int outcome)\n    {\n        uint i;\n        int[] memory outcomes = new int[](oracles.length);\n        uint[] memory validations = new uint[](oracles.length);\n        for (i = 0; i < oracles.length; i++)\n            if (oracles[i].isOutcomeSet()) {\n                int _outcome = oracles[i].getOutcome();\n                for (uint j = 0; j <= i; j++)\n                    if (_outcome == outcomes[j]) {\n                        validations[j] += 1;\n                        break;\n                    }\n                    else if (validations[j] == 0) {\n                        outcomes[j] = _outcome;\n                        validations[j] = 1;\n                        break;\n                    }\n            }\n        uint outcomeValidations = 0;\n        uint outcomeIndex = 0;\n        for (i = 0; i < oracles.length; i++)\n            if (validations[i] > outcomeValidations) {\n                outcomeValidations = validations[i];\n                outcomeIndex = i;\n            }\n        // There is a majority vote\n        if (outcomeValidations * 2 > oracles.length) {\n            outcomeSet = true;\n            outcome = outcomes[outcomeIndex];\n        }\n    }\n\n    /// @dev Returns if winning outcome is set\n    /// @return Is outcome set?\n    function isOutcomeSet()\n        public\n        override\n        view\n        returns (bool)\n    {\n        (bool outcomeSet, ) = getStatusAndOutcome();\n        return outcomeSet;\n    }\n\n    /// @dev Returns winning outcome\n    /// @return Outcome\n    function getOutcome()\n        public\n        override\n        view\n        returns (int)\n    {\n        (, int winningOutcome) = getStatusAndOutcome();\n        return winningOutcome;\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/MajorityOracleFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/MajorityOracle.sol\";\n\n\n/// @title Majority oracle factory contract - Allows to create majority oracle contracts\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract MajorityOracleFactory {\n\n    /*\n     *  Events\n     */\n    event MajorityOracleCreation(address indexed creator, MajorityOracle majorityOracle, Oracle[] oracles);\n\n    /*\n     *  Public functions\n     */\n    /// @dev Creates a new majority oracle contract\n    /// @param oracles List of oracles taking part in the majority vote\n    /// @return majorityOracle Oracle contract\n    function createMajorityOracle(Oracle[] memory oracles)\n        public\n        returns (MajorityOracle majorityOracle)\n    {\n        majorityOracle = new MajorityOracle(oracles);\n        emit MajorityOracleCreation(msg.sender, majorityOracle, oracles);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/Oracle.sol",
    "content": "pragma solidity >=0.0;\n\n\n/// @title Abstract oracle contract - Functions to be implemented by oracles\nabstract contract Oracle {\n\n    function isOutcomeSet() virtual public view returns (bool);\n    function getOutcome() virtual public view returns (int);\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/SignedMessageOracle.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/Oracle.sol\";\n\n\n/// @title Signed message oracle contract - Allows to set an outcome with a signed message\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract SignedMessageOracle is Oracle {\n\n    /*\n     *  Events\n     */\n    event SignerReplacement(address indexed newSigner);\n    event OutcomeAssignment(int outcome);\n\n    /*\n     *  Storage\n     */\n    address public signer;\n    bytes32 public descriptionHash;\n    uint nonce;\n    bool public isSet;\n    int public outcome;\n\n    /*\n     *  Modifiers\n     */\n    modifier isSigner () {\n        // Only signer is allowed to proceed\n        require(msg.sender == signer);\n        _;\n    }\n\n    /*\n     *  Public functions\n     */\n    /// @dev Constructor sets signer address based on signature\n    /// @param _descriptionHash Hash identifying off chain event description\n    /// @param v Signature parameter\n    /// @param r Signature parameter\n    /// @param s Signature parameter\n    constructor(bytes32 _descriptionHash, uint8 v, bytes32 r, bytes32 s)\n    {\n        signer = ecrecover(_descriptionHash, v, r, s);\n        descriptionHash = _descriptionHash;\n    }\n\n    /// @dev Replaces signer\n    /// @param newSigner New signer\n    /// @param _nonce Unique nonce to prevent replay attacks\n    /// @param v Signature parameter\n    /// @param r Signature parameter\n    /// @param s Signature parameter\n    function replaceSigner(address newSigner, uint _nonce, uint8 v, bytes32 r, bytes32 s)\n        public\n        isSigner\n    {\n        // Result is not set yet and nonce and signer are valid\n        require(   !isSet\n                && _nonce > nonce\n                && signer == ecrecover(keccak256(abi.encodePacked(descriptionHash, newSigner, _nonce)), v, r, s));\n        nonce = _nonce;\n        signer = newSigner;\n        emit SignerReplacement(newSigner);\n    }\n\n    /// @dev Sets outcome based on signed message\n    /// @param _outcome Signed event outcome\n    /// @param v Signature parameter\n    /// @param r Signature parameter\n    /// @param s Signature parameter\n    function setOutcome(int _outcome, uint8 v, bytes32 r, bytes32 s)\n        public\n    {\n        // Result is not set yet and signer is valid\n        require(   !isSet\n                && signer == ecrecover(keccak256(abi.encodePacked(descriptionHash, _outcome)), v, r, s));\n        isSet = true;\n        outcome = _outcome;\n        emit OutcomeAssignment(_outcome);\n    }\n\n    /// @dev Returns if winning outcome\n    /// @return Is outcome set?\n    function isOutcomeSet()\n        public\n        override\n        view\n        returns (bool)\n    {\n        return isSet;\n    }\n\n    /// @dev Returns winning outcome\n    /// @return Outcome\n    function getOutcome()\n        public\n        override\n        view\n        returns (int)\n    {\n        return outcome;\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/SignedMessageOracleFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/SignedMessageOracle.sol\";\n\n\n/// @title Signed message oracle factory contract - Allows to create signed message oracle contracts\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract SignedMessageOracleFactory {\n\n    /*\n     *  Events\n     */\n    event SignedMessageOracleCreation(address indexed creator, SignedMessageOracle signedMessageOracle, address oracle);\n\n    /*\n     *  Public functions\n     */\n    /// @dev Creates a new signed message oracle contract\n    /// @param descriptionHash Hash identifying off chain event description\n    /// @param v Signature parameter\n    /// @param r Signature parameter\n    /// @param s Signature parameter\n    /// @return signedMessageOracle Oracle contract\n    function createSignedMessageOracle(bytes32 descriptionHash, uint8 v, bytes32 r, bytes32 s)\n        public\n        returns (SignedMessageOracle signedMessageOracle)\n    {\n        signedMessageOracle = new SignedMessageOracle(descriptionHash, v, r, s);\n        address oracle = ecrecover(descriptionHash, v, r, s);\n        emit SignedMessageOracleCreation(msg.sender, signedMessageOracle, oracle);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/UltimateOracle.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/Oracle.sol\";\nimport \"../Tokens/Token.sol\";\nimport \"../Utils/Math.sol\";\n\n\n/// @title Ultimate oracle contract - Allows to swap oracle result for ultimate oracle result\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract UltimateOracle is Oracle {\n    using Math for *;\n\n    /*\n     *  Events\n     */\n    event ForwardedOracleOutcomeAssignment(int outcome);\n    event OutcomeChallenge(address indexed sender, int outcome);\n    event OutcomeVote(address indexed sender, int outcome, uint amount);\n    event Withdrawal(address indexed sender, uint amount);\n\n    /*\n     *  Storage\n     */\n    Oracle public forwardedOracle;\n    Token public collateralToken;\n    uint8 public spreadMultiplier;\n    uint public challengePeriod;\n    uint public challengeAmount;\n    uint public frontRunnerPeriod;\n\n    int public forwardedOutcome;\n    uint public forwardedOutcomeSetTimestamp;\n    int public frontRunner;\n    uint public frontRunnerSetTimestamp;\n\n    uint public totalAmount;\n    mapping (int => uint) public totalOutcomeAmounts;\n    mapping (address => mapping (int => uint)) public outcomeAmounts;\n\n    /*\n     *  Public functions\n     */\n    /// @dev Constructor sets ultimate oracle properties\n    /// @param _forwardedOracle Oracle address\n    /// @param _collateralToken Collateral token address\n    /// @param _spreadMultiplier Defines the spread as a multiple of the money bet on other outcomes\n    /// @param _challengePeriod Time to challenge oracle outcome\n    /// @param _challengeAmount Amount to challenge the outcome\n    /// @param _frontRunnerPeriod Time to overbid the front-runner\n    constructor(\n        Oracle _forwardedOracle,\n        Token _collateralToken,\n        uint8 _spreadMultiplier,\n        uint _challengePeriod,\n        uint _challengeAmount,\n        uint _frontRunnerPeriod\n    )\n    {\n        // Validate inputs\n        require(   address(_forwardedOracle) != address(0)\n                && address(_collateralToken) != address(0)\n                && _spreadMultiplier >= 2\n                && _challengePeriod > 0\n                && _challengeAmount > 0\n                && _frontRunnerPeriod > 0);\n        forwardedOracle = _forwardedOracle;\n        collateralToken = _collateralToken;\n        spreadMultiplier = _spreadMultiplier;\n        challengePeriod = _challengePeriod;\n        challengeAmount = _challengeAmount;\n        frontRunnerPeriod = _frontRunnerPeriod;\n    }\n\n    /// @dev Allows to set oracle outcome\n    function setForwardedOutcome()\n        public\n    {\n        // There was no challenge and the outcome was not set yet in the ultimate oracle but in the forwarded oracle\n        require(   !isChallenged()\n                && forwardedOutcomeSetTimestamp == 0\n                && forwardedOracle.isOutcomeSet());\n        forwardedOutcome = forwardedOracle.getOutcome();\n        forwardedOutcomeSetTimestamp = block.timestamp;\n        emit ForwardedOracleOutcomeAssignment(forwardedOutcome);\n    }\n\n    /// @dev Allows to challenge the oracle outcome\n    /// @param _outcome Outcome to bid on\n    function challengeOutcome(int _outcome)\n        public\n    {\n        // There was no challenge yet or the challenge period expired\n        require(   !isChallenged()\n                && !isChallengePeriodOver()\n                && collateralToken.transferFrom(msg.sender, address(this), challengeAmount));\n        outcomeAmounts[msg.sender][_outcome] = challengeAmount;\n        totalOutcomeAmounts[_outcome] = challengeAmount;\n        totalAmount = challengeAmount;\n        frontRunner = _outcome;\n        frontRunnerSetTimestamp = block.timestamp;\n        emit OutcomeChallenge(msg.sender, _outcome);\n    }\n\n    /// @dev Allows to challenge the oracle outcome\n    /// @param _outcome Outcome to bid on\n    /// @param amount Amount to bid\n    function voteForOutcome(int _outcome, uint amount)\n        public\n    {\n        uint maxAmount = (totalAmount - totalOutcomeAmounts[_outcome]).mul(spreadMultiplier);\n        if (amount > maxAmount)\n            amount = maxAmount;\n        // Outcome is challenged and front runner period is not over yet and tokens can be transferred\n        require(   isChallenged()\n                && !isFrontRunnerPeriodOver()\n                && collateralToken.transferFrom(msg.sender, address(this), amount));\n        outcomeAmounts[msg.sender][_outcome] = outcomeAmounts[msg.sender][_outcome].add(amount);\n        totalOutcomeAmounts[_outcome] = totalOutcomeAmounts[_outcome].add(amount);\n        totalAmount = totalAmount.add(amount);\n        if (_outcome != frontRunner && totalOutcomeAmounts[_outcome] > totalOutcomeAmounts[frontRunner])\n        {\n            frontRunner = _outcome;\n            frontRunnerSetTimestamp = block.timestamp;\n        }\n        emit OutcomeVote(msg.sender, _outcome, amount);\n    }\n\n    /// @dev Withdraws winnings for user\n    /// @return amount Winnings\n    function withdraw()\n        public\n        returns (uint amount)\n    {\n        // Outcome was challenged and ultimate outcome decided\n        require(isFrontRunnerPeriodOver());\n        amount = totalAmount.mul(outcomeAmounts[msg.sender][frontRunner]) / totalOutcomeAmounts[frontRunner];\n        outcomeAmounts[msg.sender][frontRunner] = 0;\n        // Transfer earnings to contributor\n        require(collateralToken.transfer(msg.sender, amount));\n        emit Withdrawal(msg.sender, amount);\n    }\n\n    /// @dev Checks if time to challenge the outcome is over\n    /// @return Is challenge period over?\n    function isChallengePeriodOver()\n        public\n        view\n        returns (bool)\n    {\n        return forwardedOutcomeSetTimestamp != 0 && (block.timestamp).sub(forwardedOutcomeSetTimestamp) > challengePeriod;\n    }\n\n    /// @dev Checks if time to overbid the front runner is over\n    /// @return Is front runner period over?\n    function isFrontRunnerPeriodOver()\n        public\n        view\n        returns (bool)\n    {\n        return frontRunnerSetTimestamp != 0 && (block.timestamp).sub(frontRunnerSetTimestamp) > frontRunnerPeriod;\n    }\n\n    /// @dev Checks if outcome was challenged\n    /// @return Is challenged?\n    function isChallenged()\n        public\n        view\n        returns (bool)\n    {\n        return frontRunnerSetTimestamp != 0;\n    }\n\n    /// @dev Returns if winning outcome is set\n    /// @return Is outcome set?\n    function isOutcomeSet()\n        public\n        override\n        view\n        returns (bool)\n    {\n        return    isChallengePeriodOver() && !isChallenged()\n               || isFrontRunnerPeriodOver();\n    }\n\n    /// @dev Returns winning outcome\n    /// @return Outcome\n    function getOutcome()\n        public\n        override\n        view\n        returns (int)\n    {\n        if (isFrontRunnerPeriodOver())\n            return frontRunner;\n        return forwardedOutcome;\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Oracles/UltimateOracleFactory.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Oracles/UltimateOracle.sol\";\n\n\n/// @title Ultimate oracle factory contract - Allows to create ultimate oracle contracts\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract UltimateOracleFactory {\n\n    /*\n     *  Events\n     */\n    event UltimateOracleCreation(\n        address indexed creator,\n        UltimateOracle ultimateOracle,\n        Oracle oracle,\n        Token collateralToken,\n        uint8 spreadMultiplier,\n        uint challengePeriod,\n        uint challengeAmount,\n        uint frontRunnerPeriod\n    );\n\n    /*\n     *  Public functions\n     */\n    /// @dev Creates a new ultimate Oracle contract\n    /// @param oracle Oracle address\n    /// @param collateralToken Collateral token address\n    /// @param spreadMultiplier Defines the spread as a multiple of the money bet on other outcomes\n    /// @param challengePeriod Time to challenge oracle outcome\n    /// @param challengeAmount Amount to challenge the outcome\n    /// @param frontRunnerPeriod Time to overbid the front-runner\n    /// @return ultimateOracle Oracle contract\n    function createUltimateOracle(\n        Oracle oracle,\n        Token collateralToken,\n        uint8 spreadMultiplier,\n        uint challengePeriod,\n        uint challengeAmount,\n        uint frontRunnerPeriod\n    )\n        public\n        returns (UltimateOracle ultimateOracle)\n    {\n        ultimateOracle = new UltimateOracle(\n            oracle,\n            collateralToken,\n            spreadMultiplier,\n            challengePeriod,\n            challengeAmount,\n            frontRunnerPeriod\n        );\n        emit UltimateOracleCreation(\n            msg.sender,\n            ultimateOracle,\n            oracle,\n            collateralToken,\n            spreadMultiplier,\n            challengePeriod,\n            challengeAmount,\n            frontRunnerPeriod\n        );\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/README.md",
    "content": "Gnosis contracts, originally from\n\nhttps://github.com/gnosis/gnosis-contracts\n"
  },
  {
    "path": "test/compilationTests/gnosis/Tokens/EtherToken.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Tokens/StandardToken.sol\";\n\n\n/// @title Token contract - Token exchanging Ether 1:1\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract EtherToken is StandardToken {\n    using Math for *;\n\n    /*\n     *  Events\n     */\n    event Deposit(address indexed sender, uint value);\n    event Withdrawal(address indexed receiver, uint value);\n\n    /*\n     *  Constants\n     */\n    string public constant name = \"Ether Token\";\n    string public constant symbol = \"ETH\";\n    uint8 public constant decimals = 18;\n\n    /*\n     *  Public functions\n     */\n    /// @dev Buys tokens with Ether, exchanging them 1:1\n    function deposit()\n        public\n        payable\n    {\n        balances[msg.sender] = balances[msg.sender].add(msg.value);\n        totalTokens = totalTokens.add(msg.value);\n        emit Deposit(msg.sender, msg.value);\n    }\n\n    /// @dev Sells tokens in exchange for Ether, exchanging them 1:1\n    /// @param value Number of tokens to sell\n    function withdraw(uint value)\n        public\n    {\n        // Balance covers value\n        balances[msg.sender] = balances[msg.sender].sub(value);\n        totalTokens = totalTokens.sub(value);\n        payable(msg.sender).transfer(value);\n        emit Withdrawal(msg.sender, value);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Tokens/OutcomeToken.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Tokens/StandardToken.sol\";\n\n\n/// @title Outcome token contract - Issuing and revoking outcome tokens\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract OutcomeToken is StandardToken {\n    using Math for *;\n\n    /*\n     *  Events\n     */\n    event Issuance(address indexed owner, uint amount);\n    event Revocation(address indexed owner, uint amount);\n\n    /*\n     *  Storage\n     */\n    address public eventContract;\n\n    /*\n     *  Modifiers\n     */\n    modifier isEventContract () {\n        // Only event contract is allowed to proceed\n        require(msg.sender == eventContract);\n        _;\n    }\n\n    /*\n     *  Public functions\n     */\n    /// @dev Constructor sets events contract address\n    constructor()\n    {\n        eventContract = msg.sender;\n    }\n\n    /// @dev Events contract issues new tokens for address. Returns success\n    /// @param _for Address of receiver\n    /// @param outcomeTokenCount Number of tokens to issue\n    function issue(address _for, uint outcomeTokenCount)\n        public\n        isEventContract\n    {\n        balances[_for] = balances[_for].add(outcomeTokenCount);\n        totalTokens = totalTokens.add(outcomeTokenCount);\n        emit Issuance(_for, outcomeTokenCount);\n    }\n\n    /// @dev Events contract revokes tokens for address. Returns success\n    /// @param _for Address of token holder\n    /// @param outcomeTokenCount Number of tokens to revoke\n    function revoke(address _for, uint outcomeTokenCount)\n        public\n        isEventContract\n    {\n        balances[_for] = balances[_for].sub(outcomeTokenCount);\n        totalTokens = totalTokens.sub(outcomeTokenCount);\n        emit Revocation(_for, outcomeTokenCount);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Tokens/StandardToken.sol",
    "content": "pragma solidity >=0.0;\nimport \"../Tokens/Token.sol\";\nimport \"../Utils/Math.sol\";\n\n\n/// @title Standard token contract with overflow protection\ncontract StandardToken is Token {\n    using Math for *;\n\n    /*\n     *  Storage\n     */\n    mapping (address => uint) balances;\n    mapping (address => mapping (address => uint)) allowances;\n    uint totalTokens;\n\n    /*\n     *  Public functions\n     */\n    /// @dev Transfers sender's tokens to a given address. Returns success\n    /// @param to Address of token receiver\n    /// @param value Number of tokens to transfer\n    /// @return Was transfer successful?\n    function transfer(address to, uint value)\n        public\n        override\n        returns (bool)\n    {\n        if (   !balances[msg.sender].safeToSub(value)\n            || !balances[to].safeToAdd(value))\n            return false;\n        balances[msg.sender] -= value;\n        balances[to] += value;\n        emit Transfer(msg.sender, to, value);\n        return true;\n    }\n\n    /// @dev Allows allowed third party to transfer tokens from one address to another. Returns success\n    /// @param from Address from where tokens are withdrawn\n    /// @param to Address to where tokens are sent\n    /// @param value Number of tokens to transfer\n    /// @return Was transfer successful?\n    function transferFrom(address from, address to, uint value)\n        public\n        override\n        returns (bool)\n    {\n        if (   !balances[from].safeToSub(value)\n            || !allowances[from][msg.sender].safeToSub(value)\n            || !balances[to].safeToAdd(value))\n            return false;\n        balances[from] -= value;\n        allowances[from][msg.sender] -= value;\n        balances[to] += value;\n        emit Transfer(from, to, value);\n        return true;\n    }\n\n    /// @dev Sets approved amount of tokens for spender. Returns success\n    /// @param spender Address of allowed account\n    /// @param value Number of approved tokens\n    /// @return Was approval successful?\n    function approve(address spender, uint value)\n        public\n        override\n        returns (bool)\n    {\n        allowances[msg.sender][spender] = value;\n        emit Approval(msg.sender, spender, value);\n        return true;\n    }\n\n    /// @dev Returns number of allowed tokens for given address\n    /// @param owner Address of token owner\n    /// @param spender Address of token spender\n    /// @return Remaining allowance for spender\n    function allowance(address owner, address spender)\n        public\n        override\n        view\n        returns (uint)\n    {\n        return allowances[owner][spender];\n    }\n\n    /// @dev Returns number of tokens owned by given address\n    /// @param owner Address of token owner\n    /// @return Balance of owner\n    function balanceOf(address owner)\n        public\n        override\n        view\n        returns (uint)\n    {\n        return balances[owner];\n    }\n\n    /// @dev Returns total supply of tokens\n    /// @return Total supply\n    function totalSupply()\n        public\n        override\n        view\n        returns (uint)\n    {\n        return totalTokens;\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Tokens/Token.sol",
    "content": "/// Implements ERC 20 Token standard: https://github.com/ethereum/EIPs/issues/20\npragma solidity >=0.0;\n\n\n/// @title Abstract token contract - Functions to be implemented by token contracts\nabstract contract Token {\n\n    /*\n     *  Events\n     */\n    event Transfer(address indexed from, address indexed to, uint value);\n    event Approval(address indexed owner, address indexed spender, uint value);\n\n    /*\n     *  Public functions\n     */\n    function transfer(address to, uint value) virtual public returns (bool);\n    function transferFrom(address from, address to, uint value) virtual public returns (bool);\n    function approve(address spender, uint value) virtual public returns (bool);\n    function balanceOf(address owner) virtual public view returns (uint);\n    function allowance(address owner, address spender) virtual public view returns (uint);\n    function totalSupply() virtual public view returns (uint);\n}\n"
  },
  {
    "path": "test/compilationTests/gnosis/Utils/Math.sol",
    "content": "pragma solidity >=0.0;\n\n\n/// @title Math library - Allows calculation of logarithmic and exponential functions\n/// @author Alan Lu - <alan.lu@gnosis.pm>\n/// @author Stefan George - <stefan@gnosis.pm>\nlibrary Math {\n\n    /*\n     *  Constants\n     */\n    // This is equal to 1 in our calculations\n    uint public constant ONE =  0x10000000000000000;\n    uint public constant LN2 = 0xb17217f7d1cf79ac;\n    uint public constant LOG2_E = 0x171547652b82fe177;\n\n    /*\n     *  Public functions\n     */\n    /// @dev Returns natural exponential function value of given x\n    /// @param x x\n    /// @return e**x\n    function exp(int x)\n        public\n        pure\n        returns (uint)\n    {\n        // revert if x is > MAX_POWER, where\n        // MAX_POWER = int(mp.floor(mp.log(mpf(2**256 - 1) / ONE) * ONE))\n        require(x <= 2454971259878909886679);\n        // return 0 if exp(x) is tiny, using\n        // MIN_POWER = int(mp.floor(mp.log(mpf(1) / ONE) * ONE))\n        if (x < -818323753292969962227)\n            return 0;\n        // Transform so that e^x -> 2^x\n        x = x * int(ONE) / int(LN2);\n        // 2^x = 2^whole(x) * 2^frac(x)\n        //       ^^^^^^^^^^ is a bit shift\n        // so Taylor expand on z = frac(x)\n        int shift;\n        uint z;\n        if (x >= 0) {\n            shift = x / int(ONE);\n            z = uint(x % int(ONE));\n        }\n        else {\n            shift = x / int(ONE) - 1;\n            z = ONE - uint(-x % int(ONE));\n        }\n        // 2^x = 1 + (ln 2) x + (ln 2)^2/2! x^2 + ...\n        //\n        // Can generate the z coefficients using mpmath and the following lines\n        // >>> from mpmath import mp\n        // >>> mp.dps = 100\n        // >>> ONE =  0x10000000000000000\n        // >>> print('\\n'.join(hex(int(mp.log(2)**i / mp.factorial(i) * ONE)) for i in range(1, 7)))\n        // 0xb17217f7d1cf79ab\n        // 0x3d7f7bff058b1d50\n        // 0xe35846b82505fc5\n        // 0x276556df749cee5\n        // 0x5761ff9e299cc4\n        // 0xa184897c363c3\n        uint zpow = z;\n        uint result = ONE;\n        result += 0xb17217f7d1cf79ab * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0x3d7f7bff058b1d50 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0xe35846b82505fc5 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0x276556df749cee5 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0x5761ff9e299cc4 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0xa184897c363c3 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0xffe5fe2c4586 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0x162c0223a5c8 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0x1b5253d395e * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0x1e4cf5158b * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0x1e8cac735 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0x1c3bd650 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0x1816193 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0x131496 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0xe1b7 * zpow / ONE;\n        zpow = zpow * z / ONE;\n        result += 0x9c7 * zpow / ONE;\n        if (shift >= 0) {\n            if (result >> uint(256 - shift) > 0)\n                return (2 ** 256 - 1);\n            return result << uint(shift);\n        }\n        else\n            return result >> uint(-shift);\n    }\n\n    /// @dev Returns natural logarithm value of given x\n    /// @param x x\n    /// @return ln(x)\n    function ln(uint x)\n        public\n        pure\n        returns (int)\n    {\n        require(x > 0);\n        // binary search for floor(log2(x))\n        int ilog2 = floorLog2(x);\n        int z;\n        if (ilog2 < 0)\n            z = int(x << uint(-ilog2));\n        else\n            z = int(x >> uint(ilog2));\n        // z = x * 2^-⌊log₂x⌋\n        // so 1 <= z < 2\n        // and ln z = ln x - ⌊log₂x⌋/log₂e\n        // so just compute ln z using artanh series\n        // and calculate ln x from that\n        int term = (z - int(ONE)) * int(ONE) / (z + int(ONE));\n        int halflnz = term;\n        int termpow = term * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 3;\n        termpow = termpow * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 5;\n        termpow = termpow * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 7;\n        termpow = termpow * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 9;\n        termpow = termpow * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 11;\n        termpow = termpow * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 13;\n        termpow = termpow * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 15;\n        termpow = termpow * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 17;\n        termpow = termpow * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 19;\n        termpow = termpow * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 21;\n        termpow = termpow * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 23;\n        termpow = termpow * term / int(ONE) * term / int(ONE);\n        halflnz += termpow / 25;\n        return (ilog2 * int(ONE)) * int(ONE) / int(LOG2_E) + 2 * halflnz;\n    }\n\n    /// @dev Returns base 2 logarithm value of given x\n    /// @param x x\n    /// @return lo logarithmic value\n    function floorLog2(uint x)\n        public\n        pure\n        returns (int lo)\n    {\n        lo = -64;\n        int hi = 193;\n        // I use a shift here instead of / 2 because it floors instead of rounding towards 0\n        int mid = (hi + lo) >> 1;\n        while((lo + 1) < hi) {\n            if (mid < 0 && x << uint(-mid) < ONE || mid >= 0 && x >> uint(mid) < ONE)\n                hi = mid;\n            else\n                lo = mid;\n            mid = (hi + lo) >> 1;\n        }\n    }\n\n    /// @dev Returns maximum of an array\n    /// @param nums Numbers to look through\n    /// @return max Maximum number\n    function max(int[] memory nums)\n        public\n        pure\n        returns (int max)\n    {\n        require(nums.length > 0);\n        max = -2**255;\n        for (uint i = 0; i < nums.length; i++)\n            if (nums[i] > max)\n                max = nums[i];\n    }\n\n    /// @dev Returns whether an add operation causes an overflow\n    /// @param a First addend\n    /// @param b Second addend\n    /// @return Did no overflow occur?\n    function safeToAdd(uint a, uint b)\n        public\n        pure\n        returns (bool)\n    {\n        return a + b >= a;\n    }\n\n    /// @dev Returns whether a subtraction operation causes an underflow\n    /// @param a Minuend\n    /// @param b Subtrahend\n    /// @return Did no underflow occur?\n    function safeToSub(uint a, uint b)\n        public\n        pure\n        returns (bool)\n    {\n        return a >= b;\n    }\n\n    /// @dev Returns whether a multiply operation causes an overflow\n    /// @param a First factor\n    /// @param b Second factor\n    /// @return Did no overflow occur?\n    function safeToMul(uint a, uint b)\n        public\n        pure\n        returns (bool)\n    {\n        return b == 0 || a * b / b == a;\n    }\n\n    /// @dev Returns sum if no overflow occurred\n    /// @param a First addend\n    /// @param b Second addend\n    /// @return Sum\n    function add(uint a, uint b)\n        public\n        pure\n        returns (uint)\n    {\n        require(safeToAdd(a, b));\n        return a + b;\n    }\n\n    /// @dev Returns difference if no overflow occurred\n    /// @param a Minuend\n    /// @param b Subtrahend\n    /// @return Difference\n    function sub(uint a, uint b)\n        public\n        pure\n        returns (uint)\n    {\n        require(safeToSub(a, b));\n        return a - b;\n    }\n\n    /// @dev Returns product if no overflow occurred\n    /// @param a First factor\n    /// @param b Second factor\n    /// @return Product\n    function mul(uint a, uint b)\n        public\n        pure\n        returns (uint)\n    {\n        require(safeToMul(a, b));\n        return a * b;\n    }\n\n    /// @dev Returns whether an add operation causes an overflow\n    /// @param a First addend\n    /// @param b Second addend\n    /// @return Did no overflow occur?\n    function safeToAdd(int a, int b)\n        public\n        pure\n        returns (bool)\n    {\n        return (b >= 0 && a + b >= a) || (b < 0 && a + b < a);\n    }\n\n    /// @dev Returns whether a subtraction operation causes an underflow\n    /// @param a Minuend\n    /// @param b Subtrahend\n    /// @return Did no underflow occur?\n    function safeToSub(int a, int b)\n        public\n        pure\n        returns (bool)\n    {\n        return (b >= 0 && a - b <= a) || (b < 0 && a - b > a);\n    }\n\n    /// @dev Returns whether a multiply operation causes an overflow\n    /// @param a First factor\n    /// @param b Second factor\n    /// @return Did no overflow occur?\n    function safeToMul(int a, int b)\n        public\n        pure\n        returns (bool)\n    {\n        return (b == 0) || (a * b / b == a);\n    }\n\n    /// @dev Returns sum if no overflow occurred\n    /// @param a First addend\n    /// @param b Second addend\n    /// @return Sum\n    function add(int a, int b)\n        public\n        pure\n        returns (int)\n    {\n        require(safeToAdd(a, b));\n        return a + b;\n    }\n\n    /// @dev Returns difference if no overflow occurred\n    /// @param a Minuend\n    /// @param b Subtrahend\n    /// @return Difference\n    function sub(int a, int b)\n        public\n        pure\n        returns (int)\n    {\n        require(safeToSub(a, b));\n        return a - b;\n    }\n\n    /// @dev Returns product if no overflow occurred\n    /// @param a First factor\n    /// @param b Second factor\n    /// @return Product\n    function mul(int a, int b)\n        public\n        pure\n        returns (int)\n    {\n        require(safeToMul(a, b));\n        return a * b;\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/milestonetracker/LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    {one line to give the program's name and a brief idea of what it does.}\n    Copyright (C) {year}  {name of author}\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    {project}  Copyright (C) {year}  {fullname}\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n\n"
  },
  {
    "path": "test/compilationTests/milestonetracker/MilestoneTracker.sol",
    "content": "pragma solidity >=0.0;\n\n/*\n    Copyright 2016, Jordi Baylina\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n/// @title MilestoneTracker Contract\n/// @author Jordi Baylina\n/// @dev This contract tracks the\n\n\n/// is rules the relation between a donor and a recipient\n///  in order to guaranty to the donor that the job will be done and to guaranty\n///  to the recipient that he will be paid\n\n\n/// @dev We use the RLP library to decode RLP so that the donor can approve one\n///  set of milestone changes at a time.\n///  https://github.com/androlo/standard-contracts/blob/master/contracts/src/codec/RLP.sol\nimport \"RLP.sol\";\n\n\n\n/// @dev This contract allows for `recipient` to set and modify milestones\ncontract MilestoneTracker {\n    using RLP for RLP.RLPItem;\n    using RLP for RLP.Iterator;\n    using RLP for bytes;\n\n    struct Milestone {\n        string description;     // Description of this milestone\n        string url;             // A link to more information (swarm gateway)\n        uint minCompletionDate; // Earliest UNIX time the milestone can be paid\n        uint maxCompletionDate; // Latest UNIX time the milestone can be paid\n        address milestoneLeadLink;\n                                // Similar to `recipient`but for this milestone\n        address reviewer;       // Can reject the completion of this milestone\n        uint reviewTime;        // How many seconds the reviewer has to review\n        address paymentSource;  // Where the milestone payment is sent from\n        bytes payData;          // Data defining how much ether is sent where\n\n        MilestoneStatus status; // Current status of the milestone\n                                // (Completed, AuthorizedForPayment...)\n        uint doneTime;          // UNIX time when the milestone was marked DONE\n    }\n\n    // The list of all the milestones.\n    Milestone[] public milestones;\n\n    address public recipient;   // Calls functions in the name of the recipient\n    address public donor;       // Calls functions in the name of the donor\n    address public arbitrator;  // Calls functions in the name of the arbitrator\n\n    enum MilestoneStatus {\n        AcceptedAndInProgress,\n        Completed,\n        AuthorizedForPayment,\n        Canceled\n    }\n\n    // True if the campaign has been canceled\n    bool public campaignCanceled;\n\n    // True if an approval on a change to `milestones` is a pending\n    bool public changingMilestones;\n\n    // The pending change to `milestones` encoded in RLP\n    bytes public proposedMilestones;\n\n\n    /// @dev The following modifiers only allow specific roles to call functions\n    /// with these modifiers\n    modifier onlyRecipient { if (msg.sender !=  recipient) revert(); _; }\n    modifier onlyArbitrator { if (msg.sender != arbitrator) revert(); _; }\n    modifier onlyDonor { if (msg.sender != donor) revert(); _; }\n\n    /// @dev The following modifiers prevent functions from being called if the\n    /// campaign has been canceled or if new milestones are being proposed\n    modifier campaignNotCanceled { if (campaignCanceled) revert(); _; }\n    modifier notChanging { if (changingMilestones) revert(); _; }\n\n // @dev Events to make the payment movements easy to find on the blockchain\n    event NewMilestoneListProposed();\n    event NewMilestoneListUnproposed();\n    event NewMilestoneListAccepted();\n    event ProposalStatusChanged(uint idProposal, MilestoneStatus newProposal);\n    event CampaignCanceled();\n\n\n///////////\n// Constructor\n///////////\n\n    /// @notice The Constructor creates the Milestone contract on the blockchain\n    /// @param _arbitrator Address assigned to be the arbitrator\n    /// @param _donor Address assigned to be the donor\n    /// @param _recipient Address assigned to be the recipient\n    constructor (\n        address _arbitrator,\n        address _donor,\n        address _recipient\n    ) {\n        arbitrator = _arbitrator;\n        donor = _donor;\n        recipient = _recipient;\n    }\n\n\n/////////\n// Helper functions\n/////////\n\n    /// @return The number of milestones ever created even if they were canceled\n    function numberOfMilestones() public view returns (uint) {\n        return milestones.length;\n    }\n\n\n////////\n// Change players\n////////\n\n    /// @notice `onlyArbitrator` Reassigns the arbitrator to a new address\n    /// @param _newArbitrator The new arbitrator\n    function changeArbitrator(address _newArbitrator) public onlyArbitrator {\n        arbitrator = _newArbitrator;\n    }\n\n    /// @notice `onlyDonor` Reassigns the `donor` to a new address\n    /// @param _newDonor The new donor\n    function changeDonor(address _newDonor) public onlyDonor {\n        donor = _newDonor;\n    }\n\n    /// @notice `onlyRecipient` Reassigns the `recipient` to a new address\n    /// @param _newRecipient The new recipient\n    function changeRecipient(address _newRecipient) public onlyRecipient {\n        recipient = _newRecipient;\n    }\n\n\n////////////\n// Creation and modification of Milestones\n////////////\n\n    /// @notice `onlyRecipient` Proposes new milestones or changes old\n    ///  milestones, this will require a user interface to be built up to\n    ///  support this functionality as asks for RLP encoded bytecode to be\n    ///  generated, until this interface is built you can use this script:\n    ///  https://github.com/Giveth/milestonetracker/blob/master/js/milestonetracker_helper.js\n    ///  the functions milestones2bytes and bytes2milestones will enable the\n    ///  recipient to encode and decode a list of milestones, also see\n    ///  https://github.com/Giveth/milestonetracker/blob/master/README.md\n    /// @param _newMilestones The RLP encoded list of milestones; each milestone\n    ///  has these fields:\n    ///       string description,\n    ///       string url,\n    ///       uint minCompletionDate,  // seconds since 1/1/1970 (UNIX time)\n    ///       uint maxCompletionDate,  // seconds since 1/1/1970 (UNIX time)\n    ///       address milestoneLeadLink,\n    ///       address reviewer,\n    ///       uint reviewTime\n    ///       address paymentSource,\n    ///       bytes payData,\n    function proposeMilestones(bytes memory _newMilestones\n    ) public onlyRecipient campaignNotCanceled {\n        proposedMilestones = _newMilestones;\n        changingMilestones = true;\n        emit NewMilestoneListProposed();\n    }\n\n\n////////////\n// Normal actions that will change the state of the milestones\n////////////\n\n    /// @notice `onlyRecipient` Cancels the proposed milestones and reactivates\n    ///  the previous set of milestones\n    function unproposeMilestones() public onlyRecipient campaignNotCanceled {\n        delete proposedMilestones;\n        changingMilestones = false;\n        emit NewMilestoneListUnproposed();\n    }\n\n    /// @notice `onlyDonor` Approves the proposed milestone list\n    /// @param _hashProposals The keccak256() of the proposed milestone list's\n    ///  bytecode; this confirms that the `donor` knows the set of milestones\n    ///  they are approving\n    function acceptProposedMilestones(bytes32 _hashProposals\n    ) public onlyDonor campaignNotCanceled {\n\n        uint i;\n\n        if (!changingMilestones) revert();\n        if (keccak256(proposedMilestones) != _hashProposals) revert();\n\n        // Cancel all the unfinished milestones\n        for (i=0; i<milestones.length; i++) {\n            if (milestones[i].status != MilestoneStatus.AuthorizedForPayment) {\n                milestones[i].status = MilestoneStatus.Canceled;\n            }\n        }\n        // Decode the RLP encoded milestones and add them to the milestones list\n        bytes memory mProposedMilestones = proposedMilestones;\n\n        RLP.RLPItem memory itmProposals = mProposedMilestones.toRLPItem(true);\n\n        if (!itmProposals.isList()) revert();\n\n        RLP.Iterator memory itrProposals = itmProposals.iterator();\n\n        while(itrProposals.hasNext()) {\n\n\n            RLP.RLPItem memory itmProposal = itrProposals.next();\n\n            Milestone storage milestone = milestones.push();\n\n            if (!itmProposal.isList()) revert();\n\n            RLP.Iterator memory itrProposal = itmProposal.iterator();\n\n            milestone.description = itrProposal.next().toAscii();\n            milestone.url = itrProposal.next().toAscii();\n            milestone.minCompletionDate = itrProposal.next().toUint();\n            milestone.maxCompletionDate = itrProposal.next().toUint();\n            milestone.milestoneLeadLink = itrProposal.next().toAddress();\n            milestone.reviewer = itrProposal.next().toAddress();\n            milestone.reviewTime = itrProposal.next().toUint();\n            milestone.paymentSource = itrProposal.next().toAddress();\n            milestone.payData = itrProposal.next().toData();\n\n            milestone.status = MilestoneStatus.AcceptedAndInProgress;\n\n        }\n\n        delete proposedMilestones;\n        changingMilestones = false;\n        emit NewMilestoneListAccepted();\n    }\n\n    /// @notice `onlyRecipientOrLeadLink`Marks a milestone as DONE and\n    ///  ready for review\n    /// @param _idMilestone ID of the milestone that has been completed\n    function markMilestoneComplete(uint _idMilestone)\n        public campaignNotCanceled notChanging\n    {\n        if (_idMilestone >= milestones.length) revert();\n        Milestone storage milestone = milestones[_idMilestone];\n        if (  (msg.sender != milestone.milestoneLeadLink)\n            &&(msg.sender != recipient))\n            revert();\n        if (milestone.status != MilestoneStatus.AcceptedAndInProgress) revert();\n        if (block.timestamp < milestone.minCompletionDate) revert();\n        if (block.timestamp > milestone.maxCompletionDate) revert();\n        milestone.status = MilestoneStatus.Completed;\n        milestone.doneTime = block.timestamp;\n        emit ProposalStatusChanged(_idMilestone, milestone.status);\n    }\n\n    /// @notice `onlyReviewer` Approves a specific milestone\n    /// @param _idMilestone ID of the milestone that is approved\n    function approveCompletedMilestone(uint _idMilestone)\n        public campaignNotCanceled notChanging\n    {\n        if (_idMilestone >= milestones.length) revert();\n        Milestone storage milestone = milestones[_idMilestone];\n        if ((msg.sender != milestone.reviewer) ||\n            (milestone.status != MilestoneStatus.Completed)) revert();\n\n        authorizePayment(_idMilestone);\n    }\n\n    /// @notice `onlyReviewer` Rejects a specific milestone's completion and\n    ///  reverts the `milestone.status` back to the `AcceptedAndInProgress`\n    ///  state\n    /// @param _idMilestone ID of the milestone that is being rejected\n    function rejectMilestone(uint _idMilestone)\n        public campaignNotCanceled notChanging\n    {\n        if (_idMilestone >= milestones.length) revert();\n        Milestone storage milestone = milestones[_idMilestone];\n        if ((msg.sender != milestone.reviewer) ||\n            (milestone.status != MilestoneStatus.Completed)) revert();\n\n        milestone.status = MilestoneStatus.AcceptedAndInProgress;\n        emit ProposalStatusChanged(_idMilestone, milestone.status);\n    }\n\n    /// @notice `onlyRecipientOrLeadLink` Sends the milestone payment as\n    ///  specified in `payData`; the recipient can only call this after the\n    ///  `reviewTime` has elapsed\n    /// @param _idMilestone ID of the milestone to be paid out\n    function requestMilestonePayment(uint _idMilestone\n        ) public campaignNotCanceled notChanging {\n        if (_idMilestone >= milestones.length) revert();\n        Milestone storage milestone = milestones[_idMilestone];\n        if (  (msg.sender != milestone.milestoneLeadLink)\n            &&(msg.sender != recipient))\n            revert();\n        if  ((milestone.status != MilestoneStatus.Completed) ||\n             (block.timestamp < milestone.doneTime + milestone.reviewTime))\n            revert();\n\n        authorizePayment(_idMilestone);\n    }\n\n    /// @notice `onlyRecipient` Cancels a previously accepted milestone\n    /// @param _idMilestone ID of the milestone to be canceled\n    function cancelMilestone(uint _idMilestone)\n        public onlyRecipient campaignNotCanceled notChanging\n    {\n        if (_idMilestone >= milestones.length) revert();\n        Milestone storage milestone = milestones[_idMilestone];\n        if  ((milestone.status != MilestoneStatus.AcceptedAndInProgress) &&\n             (milestone.status != MilestoneStatus.Completed))\n            revert();\n\n        milestone.status = MilestoneStatus.Canceled;\n        emit ProposalStatusChanged(_idMilestone, milestone.status);\n    }\n\n    /// @notice `onlyArbitrator` Forces a milestone to be paid out as long as it\n    /// has not been paid or canceled\n    /// @param _idMilestone ID of the milestone to be paid out\n    function arbitrateApproveMilestone(uint _idMilestone\n    ) public onlyArbitrator campaignNotCanceled notChanging {\n        if (_idMilestone >= milestones.length) revert();\n        Milestone storage milestone = milestones[_idMilestone];\n        if  ((milestone.status != MilestoneStatus.AcceptedAndInProgress) &&\n             (milestone.status != MilestoneStatus.Completed))\n           revert();\n        authorizePayment(_idMilestone);\n    }\n\n    /// @notice `onlyArbitrator` Cancels the entire campaign voiding all\n    ///  milestones.\n    function arbitrateCancelCampaign() public onlyArbitrator campaignNotCanceled {\n        campaignCanceled = true;\n        emit CampaignCanceled();\n    }\n\n    // @dev This internal function is executed when the milestone is paid out\n    function authorizePayment(uint _idMilestone) internal {\n        if (_idMilestone >= milestones.length) revert();\n        Milestone storage milestone = milestones[_idMilestone];\n        // Recheck again to not pay twice\n        if (milestone.status == MilestoneStatus.AuthorizedForPayment) revert();\n        milestone.status = MilestoneStatus.AuthorizedForPayment;\n        (bool success,) = milestone.paymentSource.call{value: 0}(milestone.payData);\n        require(success);\n        emit ProposalStatusChanged(_idMilestone, milestone.status);\n    }\n}\n"
  },
  {
    "path": "test/compilationTests/milestonetracker/README.md",
    "content": "Giveth milestone tracker, originally from\n\nhttps://github.com/Giveth/milestonetracker/\n"
  },
  {
    "path": "test/compilationTests/milestonetracker/RLP.sol",
    "content": "pragma solidity >=0.0;\n\n/**\n* @title RLPReader\n*\n* RLPReader is used to read and parse RLP encoded data in memory.\n*\n* @author Andreas Olofsson (androlo1980@gmail.com)\n*/\nlibrary RLP {\n\n uint constant DATA_SHORT_START = 0x80;\n uint constant DATA_LONG_START = 0xB8;\n uint constant LIST_SHORT_START = 0xC0;\n uint constant LIST_LONG_START = 0xF8;\n\n uint constant DATA_LONG_OFFSET = 0xB7;\n uint constant LIST_LONG_OFFSET = 0xF7;\n\n\n struct RLPItem {\n     uint _unsafe_memPtr;    // Pointer to the RLP-encoded bytes.\n     uint _unsafe_length;    // Number of bytes. This is the full length of the string.\n }\n\n struct Iterator {\n     RLPItem _unsafe_item;   // Item that's being iterated over.\n     uint _unsafe_nextPtr;   // Position of the next item in the list.\n }\n\n /* Iterator */\n\n function next(Iterator memory self) internal view returns (RLPItem memory subItem) {\n     if(hasNext(self)) {\n         uint ptr = self._unsafe_nextPtr;\n         uint itemLength = _itemLength(ptr);\n         subItem._unsafe_memPtr = ptr;\n         subItem._unsafe_length = itemLength;\n         self._unsafe_nextPtr = ptr + itemLength;\n     }\n     else\n         revert();\n }\n\n function next(Iterator memory self, bool strict) internal view returns (RLPItem memory subItem) {\n     subItem = next(self);\n     if(strict && !_validate(subItem))\n         revert();\n }\n\n function hasNext(Iterator memory self) internal view returns (bool) {\n     RLPItem memory item = self._unsafe_item;\n     return self._unsafe_nextPtr < item._unsafe_memPtr + item._unsafe_length;\n }\n\n /* RLPItem */\n\n /// @dev Creates an RLPItem from an array of RLP encoded bytes.\n /// @param self The RLP encoded bytes.\n /// @return An RLPItem\n function toRLPItem(bytes memory self) internal view returns (RLPItem memory) {\n     uint len = self.length;\n     if (len == 0) {\n         return RLPItem(0, 0);\n     }\n     uint memPtr;\n     assembly {\n         memPtr := add(self, 0x20)\n     }\n     return RLPItem(memPtr, len);\n }\n\n /// @dev Creates an RLPItem from an array of RLP encoded bytes.\n /// @param self The RLP encoded bytes.\n /// @param strict Will throw if the data is not RLP encoded.\n /// @return An RLPItem\n function toRLPItem(bytes memory self, bool strict) internal view returns (RLPItem memory) {\n     RLPItem memory item = toRLPItem(self);\n     if(strict) {\n         uint len = self.length;\n         if(_payloadOffset(item) > len)\n             revert();\n         if(_itemLength(item._unsafe_memPtr) != len)\n             revert();\n         if(!_validate(item))\n             revert();\n     }\n     return item;\n }\n\n /// @dev Check if the RLP item is null.\n /// @param self The RLP item.\n /// @return ret 'true' if the item is null.\n function isNull(RLPItem memory self) internal view returns (bool ret) {\n     return self._unsafe_length == 0;\n }\n\n /// @dev Check if the RLP item is a list.\n /// @param self The RLP item.\n /// @return ret 'true' if the item is a list.\n function isList(RLPItem memory self) internal view returns (bool ret) {\n     if (self._unsafe_length == 0)\n         return false;\n     uint memPtr = self._unsafe_memPtr;\n     assembly {\n         ret := iszero(lt(byte(0, mload(memPtr)), 0xC0))\n     }\n }\n\n /// @dev Check if the RLP item is data.\n /// @param self The RLP item.\n /// @return ret 'true' if the item is data.\n function isData(RLPItem memory self) internal view returns (bool ret) {\n     if (self._unsafe_length == 0)\n         return false;\n     uint memPtr = self._unsafe_memPtr;\n     assembly {\n         ret := lt(byte(0, mload(memPtr)), 0xC0)\n     }\n }\n\n /// @dev Check if the RLP item is empty (string or list).\n /// @param self The RLP item.\n /// @return ret 'true' if the item is null.\n function isEmpty(RLPItem memory self) internal view returns (bool ret) {\n     if(isNull(self))\n         return false;\n     uint b0;\n     uint memPtr = self._unsafe_memPtr;\n     assembly {\n         b0 := byte(0, mload(memPtr))\n     }\n     return (b0 == DATA_SHORT_START || b0 == LIST_SHORT_START);\n }\n\n /// @dev Get the number of items in an RLP encoded list.\n /// @param self The RLP item.\n /// @return The number of items.\n function items(RLPItem memory self) internal view returns (uint) {\n     if (!isList(self))\n         return 0;\n     uint b0;\n     uint memPtr = self._unsafe_memPtr;\n     assembly {\n         b0 := byte(0, mload(memPtr))\n     }\n     uint pos = memPtr + _payloadOffset(self);\n     uint last = memPtr + self._unsafe_length - 1;\n     uint itms;\n     while(pos <= last) {\n         pos += _itemLength(pos);\n         itms++;\n     }\n     return itms;\n }\n\n /// @dev Create an iterator.\n /// @param self The RLP item.\n /// @return it An 'Iterator' over the item.\n function iterator(RLPItem memory self) internal view returns (Iterator memory it) {\n     if (!isList(self))\n         revert();\n     uint ptr = self._unsafe_memPtr + _payloadOffset(self);\n     it._unsafe_item = self;\n     it._unsafe_nextPtr = ptr;\n }\n\n /// @dev Return the RLP encoded bytes.\n /// @param self The RLPItem.\n /// @return bts The bytes.\n function toBytes(RLPItem memory self) internal returns (bytes memory bts) {\n     uint len = self._unsafe_length;\n     if (len != 0)\n     {\n         bts = new bytes(len);\n         _copyToBytes(self._unsafe_memPtr, bts, len);\n     }\n }\n\n /// @dev Decode an RLPItem into bytes. This will not work if the\n /// RLPItem is a list.\n /// @param self The RLPItem.\n /// @return bts The decoded string.\n function toData(RLPItem memory self) internal returns (bytes memory bts) {\n     if(!isData(self))\n         revert();\n     (uint rStartPos, uint len) = _decode(self);\n     bts = new bytes(len);\n     _copyToBytes(rStartPos, bts, len);\n }\n\n /// @dev Get the list of sub-items from an RLP encoded list.\n /// Warning: This is inefficient, as it requires that the list is read twice.\n /// @param self The RLP item.\n /// @return list Array of RLPItems.\n function toList(RLPItem memory self) internal view returns (RLPItem[] memory list) {\n     if(!isList(self))\n         revert();\n     uint numItems = items(self);\n     list = new RLPItem[](numItems);\n     Iterator memory it = iterator(self);\n     uint idx;\n     while(hasNext(it)) {\n         list[idx] = next(it);\n         idx++;\n     }\n }\n\n /// @dev Decode an RLPItem into an ascii string. This will not work if the\n /// RLPItem is a list.\n /// @param self The RLPItem.\n /// @return str The decoded string.\n function toAscii(RLPItem memory self) internal returns (string memory str) {\n     if(!isData(self))\n         revert();\n     (uint rStartPos, uint len) = _decode(self);\n     bytes memory bts = new bytes(len);\n     _copyToBytes(rStartPos, bts, len);\n     str = string(bts);\n }\n\n /// @dev Decode an RLPItem into a uint. This will not work if the\n /// RLPItem is a list.\n /// @param self The RLPItem.\n /// @return data The decoded string.\n function toUint(RLPItem memory self) internal view returns (uint data) {\n     if(!isData(self))\n         revert();\n     (uint rStartPos, uint len) = _decode(self);\n     if (len > 32 || len == 0)\n         revert();\n     assembly {\n         data := div(mload(rStartPos), exp(256, sub(32, len)))\n     }\n }\n\n /// @dev Decode an RLPItem into a boolean. This will not work if the\n /// RLPItem is a list.\n /// @param self The RLPItem.\n /// @return data The decoded string.\n function toBool(RLPItem memory self) internal view returns (bool data) {\n     if(!isData(self))\n         revert();\n     (uint rStartPos, uint len) = _decode(self);\n     if (len != 1)\n         revert();\n     uint temp;\n     assembly {\n         temp := byte(0, mload(rStartPos))\n     }\n     if (temp > 1)\n         revert();\n     return temp == 1 ? true : false;\n }\n\n /// @dev Decode an RLPItem into a byte. This will not work if the\n /// RLPItem is a list.\n /// @param self The RLPItem.\n /// @return data The decoded string.\n function toByte(RLPItem memory self) internal view returns (bytes1 data) {\n     if(!isData(self))\n         revert();\n     (uint rStartPos, uint len) = _decode(self);\n     if (len != 1)\n         revert();\n     uint8 temp;\n     assembly {\n         temp := byte(0, mload(rStartPos))\n     }\n     return bytes1(temp);\n }\n\n /// @dev Decode an RLPItem into an int. This will not work if the\n /// RLPItem is a list.\n /// @param self The RLPItem.\n /// @return data The decoded string.\n function toInt(RLPItem memory self) internal view returns (int data) {\n     return int(toUint(self));\n }\n\n /// @dev Decode an RLPItem into a bytes32. This will not work if the\n /// RLPItem is a list.\n /// @param self The RLPItem.\n /// @return data The decoded string.\n function toBytes32(RLPItem memory self) internal view returns (bytes32 data) {\n     return bytes32(toUint(self));\n }\n\n /// @dev Decode an RLPItem into an address. This will not work if the\n /// RLPItem is a list.\n /// @param self The RLPItem.\n /// @return data The decoded string.\n function toAddress(RLPItem memory self) internal view returns (address data) {\n     if(!isData(self))\n         revert();\n     (uint rStartPos, uint len) = _decode(self);\n     if (len != 20)\n         revert();\n     assembly {\n         data := div(mload(rStartPos), exp(256, 12))\n     }\n }\n\n // Get the payload offset.\n function _payloadOffset(RLPItem memory self) private view returns (uint) {\n     if(self._unsafe_length == 0)\n         return 0;\n     uint b0;\n     uint memPtr = self._unsafe_memPtr;\n     assembly {\n         b0 := byte(0, mload(memPtr))\n     }\n     if(b0 < DATA_SHORT_START)\n         return 0;\n     if(b0 < DATA_LONG_START || (b0 >= LIST_SHORT_START && b0 < LIST_LONG_START))\n         return 1;\n     if(b0 < LIST_SHORT_START)\n         return b0 - DATA_LONG_OFFSET + 1;\n     return b0 - LIST_LONG_OFFSET + 1;\n }\n\n // Get the full length of an RLP item.\n function _itemLength(uint memPtr) private view returns (uint len) {\n     uint b0;\n     assembly {\n         b0 := byte(0, mload(memPtr))\n     }\n     if (b0 < DATA_SHORT_START)\n         len = 1;\n     else if (b0 < DATA_LONG_START)\n         len = b0 - DATA_SHORT_START + 1;\n     else if (b0 < LIST_SHORT_START) {\n         assembly {\n             let bLen := sub(b0, 0xB7) // bytes length (DATA_LONG_OFFSET)\n             let dLen := div(mload(add(memPtr, 1)), exp(256, sub(32, bLen))) // data length\n             len := add(1, add(bLen, dLen)) // total length\n         }\n     }\n     else if (b0 < LIST_LONG_START)\n         len = b0 - LIST_SHORT_START + 1;\n     else {\n         assembly {\n             let bLen := sub(b0, 0xF7) // bytes length (LIST_LONG_OFFSET)\n             let dLen := div(mload(add(memPtr, 1)), exp(256, sub(32, bLen))) // data length\n             len := add(1, add(bLen, dLen)) // total length\n         }\n     }\n }\n\n // Get start position and length of the data.\n function _decode(RLPItem memory self) private view returns (uint memPtr, uint len) {\n     if(!isData(self))\n         revert();\n     uint b0;\n     uint start = self._unsafe_memPtr;\n     assembly {\n         b0 := byte(0, mload(start))\n     }\n     if (b0 < DATA_SHORT_START) {\n         memPtr = start;\n         len = 1;\n     }\n     else if (b0 < DATA_LONG_START) {\n         len = self._unsafe_length - 1;\n         memPtr = start + 1;\n     } else {\n         uint bLen;\n         assembly {\n             bLen := sub(b0, 0xB7) // DATA_LONG_OFFSET\n         }\n         len = self._unsafe_length - 1 - bLen;\n         memPtr = start + bLen + 1;\n     }\n }\n\n // Assumes that enough memory has been allocated to store in target.\n function _copyToBytes(uint btsPtr, bytes memory tgt, uint btsLen) private {\n     // Exploiting the fact that 'tgt' was the last thing to be allocated,\n     // we can write entire words, and just overwrite any excess.\n     assembly {\n         {\n                 let words := div(add(btsLen, 31), 32)\n                 let rOffset := btsPtr\n                 let wOffset := add(tgt, 0x20)\n\n                 // Start at arr + 0x20\n                 for { let i := 0 } not(eq(i, words)) { i := add(i, 1) }\n                 {\n                     let offset := mul(i, 0x20)\n                     mstore(add(wOffset, offset), mload(add(rOffset, offset)))\n                 }\n                 mstore(add(tgt, add(0x20, mload(tgt))), 0)\n         }\n     }\n }\n\n // Check that an RLP item is valid.\n     function _validate(RLPItem memory self) private view returns (bool ret) {\n         // Check that RLP is well-formed.\n         uint b0;\n         uint b1;\n         uint memPtr = self._unsafe_memPtr;\n         assembly {\n             b0 := byte(0, mload(memPtr))\n             b1 := byte(1, mload(memPtr))\n         }\n         if(b0 == DATA_SHORT_START + 1 && b1 < DATA_SHORT_START)\n             return false;\n         return true;\n     }\n}\n"
  },
  {
    "path": "test/contracts/AuctionRegistrar.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Tests for a fixed fee registrar contract.\n */\n\n#include <test/libsolidity/SolidityExecutionFramework.h>\n#include <test/contracts/ContractInterface.h>\n#include <test/EVMHost.h>\n\n#include <libsolutil/LazyInit.h>\n\n#include <boost/test/unit_test.hpp>\n\n#include <string>\n#include <optional>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::test;\n\nnamespace solidity::frontend::test\n{\n\nnamespace\n{\nstatic char const* registrarCode = R\"DELIMITER(\npragma solidity >=0.7.0 <0.9.0;\n\nabstract contract NameRegister {\n\tfunction addr(string memory _name) public virtual view returns (address o_owner);\n\tfunction name(address _owner) public view virtual returns (string memory o_name);\n}\n\nabstract contract Registrar is NameRegister {\n\tevent Changed(string indexed name);\n\tevent PrimaryChanged(string indexed name, address indexed addr);\n\n\tfunction owner(string memory _name) public view virtual returns (address o_owner);\n\tfunction addr(string memory _name) public virtual override view returns (address o_address);\n\tfunction subRegistrar(string memory _name) public virtual view returns (address o_subRegistrar);\n\tfunction content(string memory _name) public virtual view returns (bytes32 o_content);\n\n\tfunction name(address _owner) public virtual override view returns (string memory o_name);\n}\n\nabstract contract AuctionSystem {\n\tevent AuctionEnded(string indexed _name, address _winner);\n\tevent NewBid(string indexed _name, address _bidder, uint _value);\n\n\t/// Function that is called once an auction ends.\n\tfunction onAuctionEnd(string memory _name) internal virtual;\n\n\tfunction bid(string memory _name, address payable _bidder, uint _value) internal {\n\t\tAuction storage auction = m_auctions[_name];\n\t\tif (auction.endDate > 0 && block.timestamp > auction.endDate)\n\t\t{\n\t\t\temit AuctionEnded(_name, auction.highestBidder);\n\t\t\tonAuctionEnd(_name);\n\t\t\tdelete m_auctions[_name];\n\t\t\treturn;\n\t\t}\n\t\tif (msg.value > auction.highestBid)\n\t\t{\n\t\t\t// new bid on auction\n\t\t\tauction.secondHighestBid = auction.highestBid;\n\t\t\tauction.sumOfBids += _value;\n\t\t\tauction.highestBid = _value;\n\t\t\tauction.highestBidder = _bidder;\n\t\t\tauction.endDate = block.timestamp + c_biddingTime;\n\n\t\t\temit NewBid(_name, _bidder, _value);\n\t\t}\n\t}\n\n\tuint constant c_biddingTime = 7 days;\n\n\tstruct Auction {\n\t\taddress payable highestBidder;\n\t\tuint highestBid;\n\t\tuint secondHighestBid;\n\t\tuint sumOfBids;\n\t\tuint endDate;\n\t}\n\tmapping(string => Auction) m_auctions;\n}\n\ncontract GlobalRegistrar is Registrar, AuctionSystem {\n\tstruct Record {\n\t\taddress payable owner;\n\t\taddress primary;\n\t\taddress subRegistrar;\n\t\tbytes32 content;\n\t\tuint renewalDate;\n\t}\n\n\tuint constant c_renewalInterval = 365 days;\n\tuint constant c_freeBytes = 12;\n\n\tconstructor() {\n\t\t// TODO: Populate with hall-of-fame.\n\t}\n\n\tfunction onAuctionEnd(string memory _name) internal override {\n\t\tAuction storage auction = m_auctions[_name];\n\t\tRecord storage record = m_toRecord[_name];\n\t\taddress previousOwner = record.owner;\n\t\trecord.renewalDate = block.timestamp + c_renewalInterval;\n\t\trecord.owner = auction.highestBidder;\n\t\temit Changed(_name);\n\t\tif (previousOwner != 0x0000000000000000000000000000000000000000) {\n\t\t\tif (!record.owner.send(auction.sumOfBids - auction.highestBid / 100))\n\t\t\t\trevert();\n\t\t} else {\n\t\t\tif (!auction.highestBidder.send(auction.highestBid - auction.secondHighestBid))\n\t\t\t\trevert();\n\t\t}\n\t}\n\n\tfunction reserve(string calldata _name) external payable {\n\t\tif (bytes(_name).length == 0)\n\t\t\trevert();\n\t\tbool needAuction = requiresAuction(_name);\n\t\tif (needAuction)\n\t\t{\n\t\t\tif (block.timestamp < m_toRecord[_name].renewalDate)\n\t\t\t\trevert();\n\t\t\tbid(_name, payable(msg.sender), msg.value);\n\t\t} else {\n\t\t\tRecord storage record = m_toRecord[_name];\n\t\t\tif (record.owner != 0x0000000000000000000000000000000000000000)\n\t\t\t\trevert();\n\t\t\tm_toRecord[_name].owner = payable(msg.sender);\n\t\t\temit Changed(_name);\n\t\t}\n\t}\n\n\tfunction requiresAuction(string memory _name) internal returns (bool) {\n\t\treturn bytes(_name).length < c_freeBytes;\n\t}\n\n\tmodifier onlyrecordowner(string memory _name) { if (m_toRecord[_name].owner == msg.sender) _; }\n\n\tfunction transfer(string memory _name, address payable _newOwner) onlyrecordowner(_name) public {\n\t\tm_toRecord[_name].owner = _newOwner;\n\t\temit Changed(_name);\n\t}\n\n\tfunction disown(string memory _name) onlyrecordowner(_name) public {\n\t\tif (stringsEqual(m_toName[m_toRecord[_name].primary], _name))\n\t\t{\n\t\t\temit PrimaryChanged(_name, m_toRecord[_name].primary);\n\t\t\tm_toName[m_toRecord[_name].primary] = \"\";\n\t\t}\n\t\tdelete m_toRecord[_name];\n\t\temit Changed(_name);\n\t}\n\n\tfunction setAddress(string memory _name, address _a, bool _primary) onlyrecordowner(_name) public {\n\t\tm_toRecord[_name].primary = _a;\n\t\tif (_primary)\n\t\t{\n\t\t\temit PrimaryChanged(_name, _a);\n\t\t\tm_toName[_a] = _name;\n\t\t}\n\t\temit Changed(_name);\n\t}\n\tfunction setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {\n\t\tm_toRecord[_name].subRegistrar = _registrar;\n\t\temit Changed(_name);\n\t}\n\tfunction setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {\n\t\tm_toRecord[_name].content = _content;\n\t\temit Changed(_name);\n\t}\n\n\tfunction stringsEqual(string storage _a, string memory _b) internal returns (bool) {\n\t\tbytes storage a = bytes(_a);\n\t\tbytes memory b = bytes(_b);\n\t\tif (a.length != b.length)\n\t\t\treturn false;\n\t\t// @todo unroll this loop\n\t\tfor (uint i = 0; i < a.length; i ++)\n\t\t\tif (a[i] != b[i])\n\t\t\t\treturn false;\n\t\treturn true;\n\t}\n\n\tfunction owner(string memory _name) public override view returns (address) { return m_toRecord[_name].owner; }\n\tfunction addr(string memory _name) public override view returns (address) { return m_toRecord[_name].primary; }\n\tfunction subRegistrar(string memory _name) public override view returns (address) { return m_toRecord[_name].subRegistrar; }\n\tfunction content(string memory _name) public override view returns (bytes32) { return m_toRecord[_name].content; }\n\tfunction name(address _addr) public override view returns (string memory o_name) { return m_toName[_addr]; }\n\n\tmapping (address => string) m_toName;\n\tmapping (string => Record) m_toRecord;\n}\n)DELIMITER\";\n\nstatic LazyInit<bytes> s_compiledRegistrar;\n\nclass AuctionRegistrarTestFramework: public SolidityExecutionFramework\n{\nprotected:\n\tvoid deployRegistrar()\n\t{\n\t\tbytes const& compiled = s_compiledRegistrar.init([&]{\n\t\t\treturn compileContract(registrarCode, \"GlobalRegistrar\");\n\t\t});\n\n\t\tsendMessage(compiled, bytes(), true);\n\t\tBOOST_REQUIRE(m_transactionSuccessful);\n\t\tBOOST_REQUIRE(!m_output.empty());\n\t}\n\n\tclass RegistrarInterface: public ContractInterface\n\t{\n\tpublic:\n\t\tRegistrarInterface(SolidityExecutionFramework& _framework): ContractInterface(_framework) {}\n\t\tvoid reserve(std::string const& _name)\n\t\t{\n\t\t\tcallString(\"reserve\", _name);\n\t\t}\n\t\th160 owner(std::string const& _name)\n\t\t{\n\t\t\treturn callStringReturnsAddress(\"owner\", _name);\n\t\t}\n\t\tvoid setAddress(std::string const& _name, h160 const& _address, bool _primary)\n\t\t{\n\t\t\tcallStringAddressBool(\"setAddress\", _name, _address, _primary);\n\t\t}\n\t\th160 addr(std::string const& _name)\n\t\t{\n\t\t\treturn callStringReturnsAddress(\"addr\", _name);\n\t\t}\n\t\tstd::string name(h160 const& _addr)\n\t\t{\n\t\t\treturn callAddressReturnsString(\"name\", _addr);\n\t\t}\n\t\tvoid setSubRegistrar(std::string const& _name, h160 const& _address)\n\t\t{\n\t\t\tcallStringAddress(\"setSubRegistrar\", _name, _address);\n\t\t}\n\t\th160 subRegistrar(std::string const& _name)\n\t\t{\n\t\t\treturn callStringReturnsAddress(\"subRegistrar\", _name);\n\t\t}\n\t\tvoid setContent(std::string const& _name, h256 const& _content)\n\t\t{\n\t\t\tcallStringBytes32(\"setContent\", _name, _content);\n\t\t}\n\t\th256 content(std::string const& _name)\n\t\t{\n\t\t\treturn callStringReturnsBytes32(\"content\", _name);\n\t\t}\n\t\tvoid transfer(std::string const& _name, h160 const& _target)\n\t\t{\n\t\t\treturn callStringAddress(\"transfer\", _name, _target);\n\t\t}\n\t\tvoid disown(std::string const& _name)\n\t\t{\n\t\t\treturn callString(\"disown\", _name);\n\t\t}\n\t};\n\n\tint64_t const m_biddingTime = 7 * 24 * 3600;\n};\n\n}\n\n/// This is a test suite that tests optimised code!\nBOOST_FIXTURE_TEST_SUITE(SolidityAuctionRegistrar, AuctionRegistrarTestFramework)\n\nBOOST_AUTO_TEST_CASE(creation)\n{\n\tdeployRegistrar();\n}\n\nBOOST_AUTO_TEST_CASE(reserve)\n{\n\t// Test that reserving works for long strings\n\tdeployRegistrar();\n\tstd::vector<std::string> names{\"abcabcabcabcabc\", \"defdefdefdefdef\", \"ghighighighighighighighighighighighighighighi\"};\n\n\tRegistrarInterface registrar(*this);\n\n\t// should not work\n\tregistrar.reserve(\"\");\n\tBOOST_CHECK_EQUAL(registrar.owner(\"\"), h160{});\n\n\tfor (auto const& name: names)\n\t{\n\t\tregistrar.reserve(name);\n\t\tBOOST_CHECK_EQUAL(registrar.owner(name), m_sender);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(double_reserve_long)\n{\n\t// Test that it is not possible to re-reserve from a different address.\n\tdeployRegistrar();\n\tstd::string name = \"abcabcabcabcabcabcabcabcabcabca\";\n\tRegistrarInterface registrar(*this);\n\tregistrar.reserve(name);\n\tBOOST_CHECK_EQUAL(registrar.owner(name), m_sender);\n\n\tsendEther(account(1), u256(10) * ether);\n\tm_sender = account(1);\n\tregistrar.reserve(name);\n\tBOOST_CHECK_EQUAL(registrar.owner(name), account(0));\n}\n\nBOOST_AUTO_TEST_CASE(properties)\n{\n\t// Test setting and retrieving  the various properties works.\n\tdeployRegistrar();\n\tRegistrarInterface registrar(*this);\n\tstd::string names[] = {\"abcaeouoeuaoeuaoeu\", \"defncboagufra,fui\", \"ghagpyajfbcuajouhaeoi\"};\n\tsize_t addr = 0x9872543;\n\tsize_t count = 1;\n\tfor (std::string const& name: names)\n\t{\n\t\tm_sender = account(0);\n\t\tsendEther(account(count), u256(20) * ether);\n\t\tm_sender = account(count);\n\t\tauto sender = m_sender;\n\t\taddr += count;\n\t\t// setting by sender works\n\t\tregistrar.reserve(name);\n\t\tBOOST_CHECK_EQUAL(registrar.owner(name), sender);\n\t\tregistrar.setAddress(name, h160(addr), true);\n\t\tBOOST_CHECK_EQUAL(registrar.addr(name), h160(addr));\n\t\tregistrar.setSubRegistrar(name, h160(addr + 20));\n\t\tBOOST_CHECK_EQUAL(registrar.subRegistrar(name), h160(addr + 20));\n\t\tregistrar.setContent(name, h256(u256(addr + 90)));\n\t\tBOOST_CHECK_EQUAL(registrar.content(name), h256(u256(addr + 90)));\n\n\t\t// but not by someone else\n\t\tm_sender = account(count - 1);\n\t\tBOOST_CHECK_EQUAL(registrar.owner(name), sender);\n\t\tregistrar.setAddress(name, h160(addr + 1), true);\n\t\tBOOST_CHECK_EQUAL(registrar.addr(name), h160(addr));\n\t\tregistrar.setSubRegistrar(name, h160(addr + 20 + 1));\n\t\tBOOST_CHECK_EQUAL(registrar.subRegistrar(name), h160(addr + 20));\n\t\tregistrar.setContent(name, h256(u256(addr + 90 + 1)));\n\t\tBOOST_CHECK_EQUAL(registrar.content(name), h256(u256(addr + 90)));\n\t\tcount++;\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(transfer)\n{\n\tdeployRegistrar();\n\tstd::string name = \"abcaoeguaoucaeoduceo\";\n\tRegistrarInterface registrar(*this);\n\tregistrar.reserve(name);\n\tregistrar.setContent(name, h256(u256(123)));\n\tregistrar.transfer(name, h160(555));\n\tBOOST_CHECK_EQUAL(registrar.owner(name), h160(555));\n\tBOOST_CHECK_EQUAL(registrar.content(name), h256(u256(123)));\n}\n\nBOOST_AUTO_TEST_CASE(disown)\n{\n\tdeployRegistrar();\n\tstd::string name = \"abcaoeguaoucaeoduceo\";\n\n\tRegistrarInterface registrar(*this);\n\tregistrar.reserve(name);\n\tregistrar.setContent(name, h256(u256(123)));\n\tregistrar.setAddress(name, h160(124), true);\n\tregistrar.setSubRegistrar(name, h160(125));\n\tBOOST_CHECK_EQUAL(registrar.name(h160(124)), name);\n\n\t// someone else tries disowning\n\tsendEther(account(1), u256(10) * ether);\n\tm_sender = account(1);\n\tregistrar.disown(name);\n\tBOOST_CHECK_EQUAL(registrar.owner(name), account(0));\n\n\tm_sender = account(0);\n\tregistrar.disown(name);\n\tBOOST_CHECK_EQUAL(registrar.owner(name), h160());\n\tBOOST_CHECK_EQUAL(registrar.addr(name), h160());\n\tBOOST_CHECK_EQUAL(registrar.subRegistrar(name), h160());\n\tBOOST_CHECK_EQUAL(registrar.content(name), h256());\n\tBOOST_CHECK_EQUAL(registrar.name(h160(124)), \"\");\n}\n\nBOOST_AUTO_TEST_CASE(auction_simple)\n{\n\tdeployRegistrar();\n\tstd::string name = \"x\";\n\n\tRegistrarInterface registrar(*this);\n\t// initiate auction\n\tregistrar.setNextValue(8);\n\tregistrar.reserve(name);\n\tBOOST_CHECK_EQUAL(registrar.owner(name), h160());\n\t// \"wait\" until auction end\n\n\tm_evmcHost->tx_context.block_timestamp += m_biddingTime + 10;\n\t// trigger auction again\n\tregistrar.reserve(name);\n\tBOOST_CHECK_EQUAL(registrar.owner(name), m_sender);\n}\n\nBOOST_AUTO_TEST_CASE(auction_bidding)\n{\n\tdeployRegistrar();\n\tstd::string name = \"x\";\n\n\tunsigned startTime = 0x776347e2;\n\tm_evmcHost->tx_context.block_timestamp = startTime;\n\n\tRegistrarInterface registrar(*this);\n\t// initiate auction\n\tregistrar.setNextValue(8);\n\tregistrar.reserve(name);\n\tBOOST_CHECK_EQUAL(registrar.owner(name), h160());\n\t// overbid self\n\tm_evmcHost->tx_context.block_timestamp = startTime + m_biddingTime - 10;\n\tregistrar.setNextValue(12);\n\tregistrar.reserve(name);\n\t// another bid by someone else\n\tsendEther(account(1), 10 * ether);\n\tm_sender = account(1);\n\tm_evmcHost->tx_context.block_timestamp = startTime + 2 * m_biddingTime - 50;\n\tregistrar.setNextValue(13);\n\tregistrar.reserve(name);\n\tBOOST_CHECK_EQUAL(registrar.owner(name), h160());\n\t// end auction by first bidder (which is not highest) trying to overbid again (too late)\n\tm_sender = account(0);\n\tm_evmcHost->tx_context.block_timestamp = startTime + 4 * m_biddingTime;\n\tregistrar.setNextValue(20);\n\tregistrar.reserve(name);\n\tBOOST_CHECK_EQUAL(registrar.owner(name), account(1));\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/contracts/ContractInterface.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <boost/test/unit_test.hpp>\n#include <test/ExecutionFramework.h>\n\n#include <functional>\n\nnamespace solidity::test\n{\n\nclass ContractInterface\n{\npublic:\n\tContractInterface(ExecutionFramework& _framework): m_framework(_framework) {}\n\n\tvoid setNextValue(u256 const& _value) { m_nextValue = _value; }\n\nprotected:\n\ttemplate <class... Args>\n\tbytes const& call(std::string const& _sig, Args const&... _arguments)\n\t{\n\t\tauto const& ret = m_framework.callContractFunctionWithValue(_sig, m_nextValue, _arguments...);\n\t\tm_nextValue = 0;\n\t\treturn ret;\n\t}\n\n\tvoid callString(std::string const& _name, std::string const& _arg)\n\t{\n\t\tBOOST_CHECK(call(_name + \"(string)\", u256(0x20), _arg.length(), _arg).empty());\n\t}\n\n\tvoid callStringAddress(std::string const& _name, std::string const& _arg1, util::h160 const& _arg2)\n\t{\n\t\tBOOST_CHECK(call(_name + \"(string,address)\", u256(0x40), _arg2, _arg1.length(), _arg1).empty());\n\t}\n\n\tvoid callStringAddressBool(std::string const& _name, std::string const& _arg1, util::h160 const& _arg2, bool _arg3)\n\t{\n\t\tBOOST_CHECK(call(_name + \"(string,address,bool)\", u256(0x60), _arg2, _arg3, _arg1.length(), _arg1).empty());\n\t}\n\n\tvoid callStringBytes32(std::string const& _name, std::string const& _arg1, util::h256 const& _arg2)\n\t{\n\t\tBOOST_CHECK(call(_name + \"(string,bytes32)\", u256(0x40), _arg2, _arg1.length(), _arg1).empty());\n\t}\n\n\tutil::h160 callStringReturnsAddress(std::string const& _name, std::string const& _arg)\n\t{\n\t\tbytes const& ret = call(_name + \"(string)\", u256(0x20), _arg.length(), _arg);\n\t\tBOOST_REQUIRE(ret.size() == 0x20);\n\t\tBOOST_CHECK(std::count(ret.begin(), ret.begin() + 12, 0) == 12);\n\t\tbytes const addr{ret.begin() + 12, ret.end()};\n\t\treturn util::h160(addr);\n\t}\n\n\tstd::string callAddressReturnsString(std::string const& _name, util::h160 const& _arg)\n\t{\n\t\tbytesConstRef const ret(&call(_name + \"(address)\", _arg));\n\t\tBOOST_REQUIRE(ret.size() >= 0x40);\n\t\tu256 offset(util::h256(ret.cropped(0, 0x20)));\n\t\tBOOST_REQUIRE_EQUAL(offset, 0x20);\n\t\tu256 len(util::h256(ret.cropped(0x20, 0x20)));\n\t\tBOOST_REQUIRE_EQUAL(ret.size(), 0x40 + ((len + 0x1f) / 0x20) * 0x20);\n\t\treturn ret.cropped(0x40, size_t(len)).toString();\n\t}\n\n\tutil::h256 callStringReturnsBytes32(std::string const& _name, std::string const& _arg)\n\t{\n\t\tbytes const& ret = call(_name + \"(string)\", u256(0x20), _arg.length(), _arg);\n\t\tBOOST_REQUIRE(ret.size() == 0x20);\n\t\treturn util::h256(ret);\n\t}\n\nprivate:\n\tu256 m_nextValue;\n\tExecutionFramework& m_framework;\n};\n\n} // end namespaces\n\n"
  },
  {
    "path": "test/contracts/Wallet.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Tests for a (comparatively) complex multisig wallet contract.\n */\n\n#include <libsolutil/LazyInit.h>\n\n#include <string>\n#include <tuple>\n#include <optional>\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4535) // calling _set_se_translator requires /EHa\n#endif\n#include <boost/test/unit_test.hpp>\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n#include <test/libsolidity/SolidityExecutionFramework.h>\n\nusing namespace solidity::test;\nusing namespace solidity::util;\n\nnamespace solidity::frontend::test\n{\nstatic char const* walletCode = R\"DELIMITER(\n//sol Wallet\n// Multi-sig, daily-limited account proxy/wallet.\n// @authors:\n// Gav Wood <g@ethdev.com>\n// inheritable \"property\" contract that enables methods to be protected by requiring the acquiescence of either a\n// single, or, crucially, each of a number of, designated owners.\n// usage:\n// use modifiers onlyowner (just own owned) or onlymanyowners(hash), whereby the same hash must be provided by\n// some number (specified in constructor) of the set of owners (specified in the constructor, modifiable) before the\n// interior is executed.\n\npragma solidity >=0.4.0 <0.9.0;\n\ncontract multiowned {\n\n\t// TYPES\n\n\t// struct for the status of a pending operation.\n\tstruct PendingState {\n\t\tuint yetNeeded;\n\t\tuint ownersDone;\n\t\tuint index;\n\t}\n\n\t// EVENTS\n\n\t// this contract only has five types of events: it can accept a confirmation, in which case\n\t// we record owner and operation (hash) alongside it.\n\tevent Confirmation(address owner, bytes32 operation);\n\tevent Revoke(address owner, bytes32 operation);\n\t// some others are in the case of an owner changing.\n\tevent OwnerChanged(address oldOwner, address newOwner);\n\tevent OwnerAdded(address newOwner);\n\tevent OwnerRemoved(address oldOwner);\n\t// the last one is emitted if the required signatures change\n\tevent RequirementChanged(uint newRequirement);\n\n\t// MODIFIERS\n\n\t// simple single-sig function modifier.\n\tmodifier onlyowner {\n\t\tif (isOwner(msg.sender))\n\t\t\t_;\n\t}\n\t// multi-sig function modifier: the operation must have an intrinsic hash in order\n\t// that later attempts can be realised as the same underlying operation and\n\t// thus count as confirmations.\n\tmodifier onlymanyowners(bytes32 _operation) {\n\t\tif (confirmAndCheck(_operation))\n\t\t\t_;\n\t}\n\n\t// METHODS\n\n\t// constructor is given number of sigs required to do protected \"onlymanyowners\" transactions\n\t// as well as the selection of addresses capable of confirming them.\n\tconstructor(address[] memory _owners, uint _required) {\n\t\tm_numOwners = _owners.length + 1;\n\t\tm_owners[1] = uint160(msg.sender);\n\t\tm_ownerIndex[uint160(msg.sender)] = 1;\n\t\tfor (uint i = 0; i < _owners.length; ++i)\n\t\t{\n\t\t\tm_owners[2 + i] = uint160(_owners[i]);\n\t\t\tm_ownerIndex[uint160(_owners[i])] = 2 + i;\n\t\t}\n\t\tm_required = _required;\n\t}\n\n\t// Revokes a prior confirmation of the given operation\n\tfunction revoke(bytes32 _operation) external {\n\t\tuint ownerIndex = m_ownerIndex[uint160(msg.sender)];\n\t\t// make sure they're an owner\n\t\tif (ownerIndex == 0) return;\n\t\tuint ownerIndexBit = 2**ownerIndex;\n\t\tPendingState storage pending = m_pending[_operation];\n\t\tif (pending.ownersDone & ownerIndexBit > 0) {\n\t\t\tpending.yetNeeded++;\n\t\t\tpending.ownersDone -= ownerIndexBit;\n\t\t\temit Revoke(msg.sender, _operation);\n\t\t}\n\t}\n\n\t// Replaces an owner `_from` with another `_to`.\n\tfunction changeOwner(address _from, address _to) onlymanyowners(keccak256(msg.data)) public virtual {\n\t\tif (isOwner(_to)) return;\n\t\tuint ownerIndex = m_ownerIndex[uint160(_from)];\n\t\tif (ownerIndex == 0) return;\n\n\t\tclearPending();\n\t\tm_owners[ownerIndex] = uint160(_to);\n\t\tm_ownerIndex[uint160(_from)] = 0;\n\t\tm_ownerIndex[uint160(_to)] = ownerIndex;\n\t\temit OwnerChanged(_from, _to);\n\t}\n\n\tfunction addOwner(address _owner) onlymanyowners(keccak256(msg.data)) external {\n\t\tif (isOwner(_owner)) return;\n\n\t\tclearPending();\n\t\tif (m_numOwners >= c_maxOwners)\n\t\t\treorganizeOwners();\n\t\tif (m_numOwners >= c_maxOwners)\n\t\t\treturn;\n\t\tm_numOwners++;\n\t\tm_owners[m_numOwners] = uint160(_owner);\n\t\tm_ownerIndex[uint160(_owner)] = m_numOwners;\n\t\temit OwnerAdded(_owner);\n\t}\n\n\tfunction removeOwner(address _owner) onlymanyowners(keccak256(msg.data)) external {\n\t\tuint ownerIndex = m_ownerIndex[uint160(_owner)];\n\t\tif (ownerIndex == 0) return;\n\t\tif (m_required > m_numOwners - 1) return;\n\n\t\tm_owners[ownerIndex] = 0;\n\t\tm_ownerIndex[uint160(_owner)] = 0;\n\t\tclearPending();\n\t\treorganizeOwners(); //make sure m_numOwner is equal to the number of owners and always points to the optimal free slot\n\t\temit OwnerRemoved(_owner);\n\t}\n\n\tfunction changeRequirement(uint _newRequired) onlymanyowners(keccak256(msg.data)) external {\n\t\tif (_newRequired > m_numOwners) return;\n\t\tm_required = _newRequired;\n\t\tclearPending();\n\t\temit RequirementChanged(_newRequired);\n\t}\n\n\tfunction isOwner(address _addr) public returns (bool) {\n\t\treturn m_ownerIndex[uint160(_addr)] > 0;\n\t}\n\n\tfunction hasConfirmed(bytes32 _operation, address _owner) public view returns (bool) {\n\t\tPendingState storage pending = m_pending[_operation];\n\t\tuint ownerIndex = m_ownerIndex[uint160(_owner)];\n\n\t\t// make sure they're an owner\n\t\tif (ownerIndex == 0) return false;\n\n\t\t// determine the bit to set for this owner.\n\t\tuint ownerIndexBit = 2**ownerIndex;\n\t\tif (pending.ownersDone & ownerIndexBit == 0) {\n\t\t\treturn false;\n\t\t} else {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// INTERNAL METHODS\n\n\tfunction confirmAndCheck(bytes32 _operation) internal returns (bool) {\n\t\t// determine what index the present sender is:\n\t\tuint ownerIndex = m_ownerIndex[uint160(msg.sender)];\n\t\t// make sure they're an owner\n\t\tif (ownerIndex == 0) return false;\n\n\t\tPendingState storage pending = m_pending[_operation];\n\t\t// if we're not yet working on this operation, switch over and reset the confirmation status.\n\t\tif (pending.yetNeeded == 0) {\n\t\t\t// reset count of confirmations needed.\n\t\t\tpending.yetNeeded = m_required;\n\t\t\t// reset which owners have confirmed (none) - set our bitmap to 0.\n\t\t\tpending.ownersDone = 0;\n\t\t\tm_pendingIndex.push(_operation);\n\t\t\tpending.index = m_pendingIndex.length - 1;\n\t\t}\n\t\t// determine the bit to set for this owner.\n\t\tuint ownerIndexBit = 2**ownerIndex;\n\t\t// make sure we (the message sender) haven't confirmed this operation previously.\n\t\tif (pending.ownersDone & ownerIndexBit == 0) {\n\t\t\temit Confirmation(msg.sender, _operation);\n\t\t\t// ok - check if count is enough to go ahead.\n\t\t\tif (pending.yetNeeded <= 1) {\n\t\t\t\t// enough confirmations: reset and run interior.\n\t\t\t\tdelete m_pendingIndex[m_pending[_operation].index];\n\t\t\t\tdelete m_pending[_operation];\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// not enough: record that this owner in particular confirmed.\n\t\t\t\tpending.yetNeeded--;\n\t\t\t\tpending.ownersDone |= ownerIndexBit;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction reorganizeOwners() private returns (bool) {\n\t\tuint free = 1;\n\t\twhile (free < m_numOwners)\n\t\t{\n\t\t\twhile (free < m_numOwners && m_owners[free] != 0) free++;\n\t\t\twhile (m_numOwners > 1 && m_owners[m_numOwners] == 0) m_numOwners--;\n\t\t\tif (free < m_numOwners && m_owners[m_numOwners] != 0 && m_owners[free] == 0)\n\t\t\t{\n\t\t\t\tm_owners[free] = m_owners[m_numOwners];\n\t\t\t\tm_ownerIndex[m_owners[free]] = free;\n\t\t\t\tm_owners[m_numOwners] = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction clearPending() internal virtual {\n\t\tuint length = m_pendingIndex.length;\n\t\tfor (uint i = 0; i < length; ++i)\n\t\t\tif (m_pendingIndex[i] != 0)\n\t\t\t\tdelete m_pending[m_pendingIndex[i]];\n\t\tdelete m_pendingIndex;\n\t}\n\n\t// FIELDS\n\n\t// the number of owners that must confirm the same operation before it is run.\n\tuint public m_required;\n\t// pointer used to find a free slot in m_owners\n\tuint public m_numOwners;\n\n\t// list of owners\n\tuint[256] m_owners;\n\tuint constant c_maxOwners = 250;\n\t// index on the list of owners to allow reverse lookup\n\tmapping(uint => uint) m_ownerIndex;\n\t// the ongoing operations.\n\tmapping(bytes32 => PendingState) m_pending;\n\tbytes32[] m_pendingIndex;\n}\n\n// inheritable \"property\" contract that enables methods to be protected by placing a linear limit (specifiable)\n// on a particular resource per calendar day. is multiowned to allow the limit to be altered. resource that method\n// uses is specified in the modifier.\nabstract contract daylimit is multiowned {\n\n\t// MODIFIERS\n\n\t// simple modifier for daily limit.\n\tmodifier limitedDaily(uint _value) {\n\t\tif (underLimit(_value))\n\t\t\t_;\n\t}\n\n\t// METHODS\n\n\t// constructor - stores initial daily limit and records the present day's index.\n\tconstructor(uint _limit) {\n\t\tm_dailyLimit = _limit;\n\t\tm_lastDay = today();\n\t}\n\t// (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today.\n\tfunction setDailyLimit(uint _newLimit) onlymanyowners(keccak256(msg.data)) external {\n\t\tm_dailyLimit = _newLimit;\n\t}\n\t// (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today.\n\tfunction resetSpentToday() onlymanyowners(keccak256(msg.data)) external {\n\t\tm_spentToday = 0;\n\t}\n\n\t// INTERNAL METHODS\n\n\t// checks to see if there is at least `_value` left from the daily limit today. if there is, subtracts it and\n\t// returns true. otherwise just returns false.\n\tfunction underLimit(uint _value) internal onlyowner returns (bool) {\n\t\t// reset the spend limit if we're on a different day to last time.\n\t\tif (today() > m_lastDay) {\n\t\t\tm_spentToday = 0;\n\t\t\tm_lastDay = today();\n\t\t}\n\t\t// check to see if there's enough left - if so, subtract and return true.\n\t\tif (m_spentToday + _value >= m_spentToday && m_spentToday + _value <= m_dailyLimit) {\n\t\t\tm_spentToday += _value;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\t// determines today's index.\n\tfunction today() private view returns (uint) { return block.timestamp / 1 days; }\n\n\t// FIELDS\n\n\tuint public m_dailyLimit;\n\tuint m_spentToday;\n\tuint m_lastDay;\n}\n\n// interface contract for multisig proxy contracts; see below for docs.\nabstract contract multisig {\n\n\t// EVENTS\n\n\t// logged events:\n\t// Funds has arrived into the wallet (record how much).\n\tevent Deposit(address from, uint value);\n\t// Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going).\n\tevent SingleTransact(address owner, uint value, address to, bytes data);\n\t// Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going).\n\tevent MultiTransact(address owner, bytes32 operation, uint value, address to, bytes data);\n\t// Confirmation still needed for a transaction.\n\tevent ConfirmationNeeded(bytes32 operation, address initiator, uint value, address to, bytes data);\n\n\t// FUNCTIONS\n\n\t// TODO: document\n\tfunction changeOwner(address _from, address _to) public virtual;\n\tfunction execute(address _to, uint _value, bytes calldata _data) external virtual returns (bytes32);\n\tfunction confirm(bytes32 _h) public virtual returns (bool);\n}\n\n// usage:\n// bytes32 h = Wallet(w).from(oneOwner).transact(to, value, data);\n// Wallet(w).from(anotherOwner).confirm(h);\ncontract Wallet is multisig, multiowned, daylimit {\n\n\t// TYPES\n\n\t// Transaction structure to remember details of transaction lest it need be saved for a later call.\n\tstruct Transaction {\n\t\taddress to;\n\t\tuint value;\n\t\tbytes data;\n\t}\n\n\t// METHODS\n\n\t// constructor - just pass on the owner array to the multiowned and\n\t// the limit to daylimit\n\tconstructor(address[] memory _owners, uint _required, uint _daylimit) payable\n\t\t\tmultiowned(_owners, _required) daylimit(_daylimit) {\n\t}\n\n\tfunction changeOwner(address _from, address _to) public override(multiowned, multisig) {\n\t\tmultiowned.changeOwner(_from, _to);\n\t}\n\t// destroys the contract sending everything to `_to`.\n\tfunction shutdown(address payable _to) onlymanyowners(keccak256(msg.data)) external {\n\t\tselfdestruct(_to);\n\t}\n\n\t// gets called for plain ether transfers\n\treceive() external payable {\n\t\t// did we actually receive value?\n\t\tif (msg.value > 0)\n\t\t\temit Deposit(msg.sender, msg.value);\n\t}\n\n\t// Outside-visible transact entry point. Executes transaction immediately if below daily spend limit.\n\t// If not, goes into multisig process. We provide a hash on return to allow the sender to provide\n\t// shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value\n\t// and _data arguments). They still get the option of using them if they want, anyways.\n\tfunction execute(address _to, uint _value, bytes calldata _data) external override onlyowner returns (bytes32 _r) {\n\t\t// first, take the opportunity to check that we're under the daily limit.\n\t\tif (underLimit(_value)) {\n\t\t\temit SingleTransact(msg.sender, _value, _to, _data);\n\t\t\t// yes - just execute the call.\n\t\t\t_to.call{value: _value}(_data);\n\t\t\treturn 0;\n\t\t}\n\t\t// determine our operation hash.\n\t\t_r = keccak256(abi.encodePacked(msg.data, block.number));\n\t\tif (!confirm(_r) && m_txs[_r].to == 0x0000000000000000000000000000000000000000) {\n\t\t\tm_txs[_r].to = _to;\n\t\t\tm_txs[_r].value = _value;\n\t\t\tm_txs[_r].data = _data;\n\t\t\temit ConfirmationNeeded(_r, msg.sender, _value, _to, _data);\n\t\t}\n\t}\n\n\t// confirm a transaction through just the hash. we use the previous transactions map, m_txs, in order\n\t// to determine the body of the transaction from the hash provided.\n\tfunction confirm(bytes32 _h) onlymanyowners(_h) public override returns (bool) {\n\t\tif (m_txs[_h].to != 0x0000000000000000000000000000000000000000) {\n\t\t\tm_txs[_h].to.call{value: m_txs[_h].value}(m_txs[_h].data);\n\t\t\temit MultiTransact(msg.sender, _h, m_txs[_h].value, m_txs[_h].to, m_txs[_h].data);\n\t\t\tdelete m_txs[_h];\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// INTERNAL METHODS\n\n\tfunction clearPending() internal override {\n\t\tuint length = m_pendingIndex.length;\n\t\tfor (uint i = 0; i < length; ++i)\n\t\t\tdelete m_txs[m_pendingIndex[i]];\n\t\tsuper.clearPending();\n\t}\n\n\t// FIELDS\n\n\t// pending transactions we have at present.\n\tmapping (bytes32 => Transaction) m_txs;\n}\n)DELIMITER\";\n\nstatic LazyInit<bytes> s_compiledWallet;\n\nclass WalletTestFramework: public SolidityExecutionFramework\n{\nprotected:\n\tvoid deployWallet(\n\t\tu256 const& _value = 0,\n\t\tstd::vector<h160> const& _owners = std::vector<h160>{},\n\t\tu256 _required = 1,\n\t\tu256 _dailyLimit = 0\n\t)\n\t{\n\t\tbytes const& compiled = s_compiledWallet.init([&]{\n\t\t\treturn compileContract(walletCode, \"Wallet\");\n\t\t});\n\n\t\tbytes args = encodeArgs(u256(0x60), _required, _dailyLimit, u256(_owners.size()), _owners);\n\t\tsendMessage(compiled, args, true, _value);\n\t\tBOOST_REQUIRE(m_transactionSuccessful);\n\t\tBOOST_REQUIRE(!m_output.empty());\n\t}\n};\n\n/// This is a test suite that tests optimised code!\nBOOST_FIXTURE_TEST_SUITE(SolidityWallet, WalletTestFramework)\n\nBOOST_AUTO_TEST_CASE(creation)\n{\n\tdeployWallet(200);\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", m_sender) == encodeArgs(true));\n\tbool v2 = !solidity::test::CommonOptions::get().useABIEncoderV1;\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h256(~0)) == (v2 ? encodeArgs() : encodeArgs(false)));\n}\n\nBOOST_AUTO_TEST_CASE(add_owners)\n{\n\tdeployWallet(200);\n\th160 originalOwner = m_sender;\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(1)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", account(1)) == encodeArgs(true));\n\t// now let the new owner add someone\n\tsendEther(account(1), 10 * ether);\n\tm_sender = account(1);\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", h160(0x13)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x13)) == encodeArgs(true));\n\t// and check that a non-owner cannot add a new owner\n\tm_sender = account(0);\n\tsendEther(account(2), 10 * ether);\n\tm_sender = account(2);\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", h160(0x20)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x20)) == encodeArgs(false));\n\t// finally check that all the owners are there\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", originalOwner) == encodeArgs(true));\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", account(1)) == encodeArgs(true));\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x13)) == encodeArgs(true));\n}\n\nBOOST_AUTO_TEST_CASE(change_owners)\n{\n\tdeployWallet(200);\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", h160(0x12)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x12)) == encodeArgs(true));\n\tBOOST_REQUIRE(callContractFunction(\"changeOwner(address,address)\", h160(0x12), h160(0x13)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x12)) == encodeArgs(false));\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x13)) == encodeArgs(true));\n}\n\nBOOST_AUTO_TEST_CASE(remove_owner)\n{\n\tdeployWallet(200);\n\t// add 10 owners\n\tfor (unsigned i = 0; i < 10; ++i)\n\t{\n\t\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", h160(0x12 + i)) == encodeArgs());\n\t\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x12 + i)) == encodeArgs(true));\n\t}\n\t// check they are there again\n\tfor (unsigned i = 0; i < 10; ++i)\n\t\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x12 + i)) == encodeArgs(true));\n\t// remove the odd owners\n\tfor (unsigned i = 0; i < 10; ++i)\n\t\tif (i % 2 == 1)\n\t\t\tBOOST_REQUIRE(callContractFunction(\"removeOwner(address)\", h160(0x12 + i)) == encodeArgs());\n\t// check the result\n\tfor (unsigned i = 0; i < 10; ++i)\n\t\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x12 + i)) == encodeArgs(i % 2 == 0));\n\t// add them again\n\tfor (unsigned i = 0; i < 10; ++i)\n\t\tif (i % 2 == 1)\n\t\t\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", h160(0x12 + i)) == encodeArgs());\n\t// check everyone is there\n\tfor (unsigned i = 0; i < 10; ++i)\n\t\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x12 + i)) == encodeArgs(true));\n}\n\nBOOST_AUTO_TEST_CASE(initial_owners)\n{\n\tstd::vector<h160> owners{\n\t\th160(\"0x42c56279432962a17176998a4747d1b4d6ed4367\"),\n\t\th160(\"0xd4d4669f5ba9f4c27d38ef02a358c339b5560c47\"),\n\t\th160(\"0xe6716f9544a56c530d868e4bfbacb172315bdead\"),\n\t\th160(\"0x775e18be7a50a0abb8a4e82b1bd697d79f31fe04\"),\n\t\th160(\"0xf4dd5c3794f1fd0cdc0327a83aa472609c806e99\"),\n\t\th160(\"0x4c9113886af165b2de069d6e99430647e94a9fff\"),\n\t\th160(\"0x3fb1cd2cd96c6d5c0b5eb3322d807b34482481d4\")\n\t};\n\tdeployWallet(0, owners, 4, 2);\n\tBOOST_CHECK(callContractFunction(\"m_numOwners()\") == encodeArgs(u256(8)));\n\tBOOST_CHECK(callContractFunction(\"isOwner(address)\", m_sender) == encodeArgs(true));\n\tfor (h160 const& owner: owners)\n\t{\n\t\tBOOST_CHECK(callContractFunction(\"isOwner(address)\", owner) == encodeArgs(true));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(multisig_value_transfer)\n{\n\tdeployWallet(200);\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(1)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(2)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(3)) == encodeArgs());\n\t// 4 owners, set required to 3\n\tBOOST_REQUIRE(callContractFunction(\"changeRequirement(uint256)\", u256(3)) == encodeArgs());\n\th160 destination = h160(\"0x5c6d6026d3fb35cd7175fd0054ae8df50d8f8b41\");\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 0);\n\tm_sender = account(0);\n\tsendEther(account(1), 10 * ether);\n\tm_sender = account(1);\n\tauto ophash = callContractFunction(\"execute(address,uint256,bytes)\", destination, 100, 0x60, 0x00);\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 0);\n\tm_sender = account(0);\n\tsendEther(account(2), 10 * ether);\n\tm_sender = account(2);\n\tcallContractFunction(\"confirm(bytes32)\", ophash);\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 0);\n\tm_sender = account(0);\n\tsendEther(account(3), 10 * ether);\n\tm_sender = account(3);\n\tcallContractFunction(\"confirm(bytes32)\", ophash);\n\t// now it should go through\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 100);\n}\n\nBOOST_AUTO_TEST_CASE(revoke_addOwner)\n{\n\tdeployWallet();\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(1)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(2)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(3)) == encodeArgs());\n\t// 4 owners, set required to 3\n\tBOOST_REQUIRE(callContractFunction(\"changeRequirement(uint256)\", u256(3)) == encodeArgs());\n\t// add a new owner\n\th160 deployer = m_sender;\n\th256 opHash = util::keccak256(util::selectorFromSignatureH32(\"addOwner(address)\").asBytes() + h256(0x33).asBytes());\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", h160(0x33)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x33)) == encodeArgs(false));\n\tm_sender = account(0);\n\tsendEther(account(1), 10 * ether);\n\tm_sender = account(1);\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", h160(0x33)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x33)) == encodeArgs(false));\n\t// revoke one confirmation\n\tm_sender = deployer;\n\tBOOST_REQUIRE(callContractFunction(\"revoke(bytes32)\", opHash) == encodeArgs());\n\tm_sender = account(0);\n\tsendEther(account(2), 10 * ether);\n\tm_sender = account(2);\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", h160(0x33)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x33)) == encodeArgs(false));\n\tm_sender = account(0);\n\tsendEther(account(3), 10 * ether);\n\tm_sender = account(3);\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", h160(0x33)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"isOwner(address)\", h160(0x33)) == encodeArgs(true));\n}\n\nBOOST_AUTO_TEST_CASE(revoke_transaction)\n{\n\tdeployWallet(200);\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(1)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(2)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(3)) == encodeArgs());\n\t// 4 owners, set required to 3\n\tBOOST_REQUIRE(callContractFunction(\"changeRequirement(uint256)\", u256(3)) == encodeArgs());\n\t// create a transaction\n\th160 deployer = m_sender;\n\th160 destination = h160(\"0x5c6d6026d3fb35cd7175fd0054ae8df50d8f8b41\");\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 0);\n\tm_sender = account(0);\n\tsendEther(account(1), 10 * ether);\n\tm_sender = account(1);\n\tauto opHash = callContractFunction(\"execute(address,uint256,bytes)\", destination, 100, 0x60, 0x00);\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 0);\n\tm_sender = account(0);\n\tsendEther(account(2), 10 * ether);\n\tm_sender = account(2);\n\tcallContractFunction(\"confirm(bytes32)\", opHash);\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 0);\n\tm_sender = account(0);\n\tsendEther(account(1), 10 * ether);\n\tm_sender = account(1);\n\tBOOST_REQUIRE(callContractFunction(\"revoke(bytes32)\", opHash) == encodeArgs());\n\tm_sender = deployer;\n\tcallContractFunction(\"confirm(bytes32)\", opHash);\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 0);\n\tm_sender = account(0);\n\tsendEther(account(3), 10 * ether);\n\tm_sender = account(3);\n\tcallContractFunction(\"confirm(bytes32)\", opHash);\n\t// now it should go through\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 100);\n}\n\nBOOST_AUTO_TEST_CASE(daylimit)\n{\n\tdeployWallet(200);\n\tBOOST_REQUIRE(callContractFunction(\"m_dailyLimit()\") == encodeArgs(u256(0)));\n\tBOOST_REQUIRE(callContractFunction(\"setDailyLimit(uint256)\", u256(100)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"m_dailyLimit()\") == encodeArgs(u256(100)));\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(1)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(2)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"addOwner(address)\", account(3)) == encodeArgs());\n\t// 4 owners, set required to 3\n\tBOOST_REQUIRE(callContractFunction(\"changeRequirement(uint256)\", u256(3)) == encodeArgs());\n\n\t// try to send tx over daylimit\n\th160 destination = h160(\"0x5c6d6026d3fb35cd7175fd0054ae8df50d8f8b41\");\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 0);\n\tsendEther(account(1), 10 * ether);\n\tm_sender = account(1);\n\tBOOST_REQUIRE(\n\t\tcallContractFunction(\"execute(address,uint256,bytes)\", destination, 150, 0x60, 0x00) !=\n\t\tencodeArgs(u256(0))\n\t);\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 0);\n\t// try to send tx under daylimit by stranger\n\tm_sender = account(0);\n\tsendEther(account(4), 10 * ether);\n\tm_sender = account(4);\n\tBOOST_REQUIRE(\n\t\tcallContractFunction(\"execute(address,uint256,bytes)\", destination, 90, 0x60, 0x00) ==\n\t\tencodeArgs(u256(0))\n\t);\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 0);\n\t// now send below limit by owner\n\tm_sender = account(0);\n\tsendEther(account(1), 10 * ether);\n\tBOOST_REQUIRE(\n\t\tcallContractFunction(\"execute(address,uint256,bytes)\", destination, 90, 0x60, 0x00) ==\n\t\tencodeArgs(u256(0))\n\t);\n\tBOOST_CHECK_EQUAL(balanceAt(destination), 90);\n}\n\nBOOST_AUTO_TEST_CASE(daylimit_constructor)\n{\n\tdeployWallet(200, {}, 1, 20);\n\tBOOST_REQUIRE(callContractFunction(\"m_dailyLimit()\") == encodeArgs(u256(20)));\n\tBOOST_REQUIRE(callContractFunction(\"setDailyLimit(uint256)\", u256(30)) == encodeArgs());\n\tBOOST_REQUIRE(callContractFunction(\"m_dailyLimit()\") == encodeArgs(u256(30)));\n}\n\n//@todo test data calls\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/docsCodeStyle.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\n## GLOBAL VARIABLES\n\nREPO_ROOT=$(cd \"$(dirname \"$0\")/..\" && pwd)\n\n## FUNCTIONS\n\nif [ \"$CIRCLECI\" ]\nthen\n    function printTask { echo \"$(tput bold)$(tput setaf 2)$1$(tput setaf 7)\"; }\n    function printError { echo \"$(tput setaf 1)$1$(tput setaf 7)\"; }\nelse\n    function printTask { echo \"$(tput bold)$(tput setaf 2)$1$(tput sgr0)\"; }\n    function printError { echo \"$(tput setaf 1)$1$(tput sgr0)\"; }\nfi\n\nprintTask \"Checking docs examples style\"\nSOLTMPDIR=$(mktemp -d)\n(\n    set -e\n    cd \"$SOLTMPDIR\"\n    \"$REPO_ROOT\"/scripts/isolate_tests.py \"$REPO_ROOT\"/docs/\n\n    if npm -v >/dev/null 2>&1; then\n        if npm list -g | grep solhint >/dev/null 2>&1; then\n            echo \"node is installed, setting up solhint\"\n            cp \"$REPO_ROOT\"/test/.solhint.json \"$SOLTMPDIR\"/.solhint.json\n            cp \"$REPO_ROOT\"/test/.solhintignore \"$SOLTMPDIR\"/.solhintignore\n\n            for f in *.sol\n            do\n                echo \"$f\"\n                # Only report errors\n                solhint -f unix \"$SOLTMPDIR/$f\"\n            done\n        else\n            echo \"node is installed, but not solhint\"\n            exit 1\n        fi\n    else\n        echo \"node not installed, skipping docs style checker\"\n        exit 1\n    fi\n)\nrm -rf \"$SOLTMPDIR\"\necho \"Done.\"\n"
  },
  {
    "path": "test/ethdebugSchemaTests/conftest.py",
    "content": "import shutil\nimport subprocess\nfrom pathlib import Path\n\nimport pytest\nimport referencing\nimport yaml\nfrom referencing.jsonschema import DRAFT202012\n\n\ndef pytest_addoption(parser):\n    parser.addoption(\"--solc-binary-path\", type=Path, required=True, help=\"Path to the solidity compiler binary.\")\n\n\n@pytest.fixture\ndef solc_path(request):\n    solc_path = request.config.getoption(\"--solc-binary-path\")\n    assert solc_path.is_file()\n    assert solc_path.exists()\n    return solc_path\n\n\n@pytest.fixture(scope=\"module\")\ndef ethdebug_clone_dir(tmpdir_factory):\n    temporary_dir = Path(tmpdir_factory.mktemp(\"data\"))\n    yield temporary_dir\n    shutil.rmtree(temporary_dir)\n\n\n@pytest.fixture(scope=\"module\")\ndef ethdebug_schema_repository(ethdebug_clone_dir):\n    process = subprocess.run(\n        [\"git\", \"clone\", \"https://github.com/ethdebug/format.git\", ethdebug_clone_dir],\n        encoding=\"utf8\",\n        capture_output=True,\n        check=True\n    )\n    assert process.returncode == 0\n\n    registry = referencing.Registry()\n    for path in (ethdebug_clone_dir / \"schemas\").rglob(\"*.yaml\"):\n        with open(path, \"r\", encoding=\"utf8\") as f:\n            schema = yaml.safe_load(f)\n            if \"$id\" in schema:\n                resource = referencing.Resource.from_contents(schema, DRAFT202012)\n                registry = resource @ registry\n            else:\n                raise ValueError(f\"Schema did not define an $id: {path}\")\n    return registry\n"
  },
  {
    "path": "test/ethdebugSchemaTests/input_file.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"viaIR\": true,\n    \"debug\": {\n      \"debugInfo\": [\n        \"ethdebug\"\n      ]\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"evm.deployedBytecode.ethdebug\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/ethdebugSchemaTests/input_file_eof.json",
    "content": "{\n  \"language\": \"Solidity\",\n  \"sources\": {\n    \"a.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }\"\n    },\n    \"b.sol\": {\n      \"content\": \"//SPDX-License-Identifier: GPL-3.0\\npragma solidity >=0.0;\\ncontract A1 { function b(uint x) public pure { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }\"\n    }\n  },\n  \"settings\": {\n    \"experimental\": true,\n    \"eofVersion\": 1,\n    \"evmVersion\": \"osaka\",\n    \"viaIR\": true,\n    \"debug\": {\n      \"debugInfo\": [\n        \"ethdebug\"\n      ]\n    },\n    \"outputSelection\": {\n      \"*\": {\n        \"*\": [\n          \"evm.bytecode.ethdebug\",\n          \"evm.deployedBytecode.ethdebug\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/ethdebugSchemaTests/test_ethdebug_schema_conformity.py",
    "content": "#!/usr/bin/env python3\n\nimport json\nimport subprocess\nfrom pathlib import Path\n\nimport jsonschema\nimport pytest\n\n\ndef get_nested_value(dictionary, *keys):\n    for key in keys:\n        dictionary = dictionary[key]\n    return dictionary\n\n\n@pytest.fixture(params=[\"input_file.json\", \"input_file_eof.json\"])\ndef solc_output(request, solc_path):\n    testfile_dir = Path(__file__).parent\n    with open(testfile_dir / request.param, \"r\", encoding=\"utf8\") as f:\n        source = json.load(f)\n\n    process = subprocess.run(\n        [solc_path, \"--standard-json\"],\n        input=json.dumps(source),\n        encoding=\"utf8\",\n        capture_output=True,\n        check=True,\n    )\n    assert process.returncode == 0\n    return json.loads(process.stdout)\n\n\n@pytest.mark.parametrize(\"output_selection\", [\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"], ids=str)\ndef test_program_schema(\n    output_selection,\n    ethdebug_schema_repository,\n    solc_output\n):\n    validator = jsonschema.Draft202012Validator(\n        schema={\"$ref\": \"schema:ethdebug/format/program\"},\n        registry=ethdebug_schema_repository\n    )\n    assert \"contracts\" in solc_output\n    for contract in solc_output[\"contracts\"].keys():\n        contract_output = solc_output[\"contracts\"][contract]\n        assert len(contract_output) > 0\n        for source in contract_output.keys():\n            source_output = contract_output[source]\n            ethdebug_data = get_nested_value(source_output, *(output_selection.split(\".\")))\n            validator.validate(ethdebug_data)\n"
  },
  {
    "path": "test/evmc/CMakeLists.txt",
    "content": "# EVMC: Ethereum Client-VM Connector API.\n# Copyright 2016-2019 The EVMC Authors.\n# Licensed under the Apache License, Version 2.0.\n\n\nadd_library(evmc_loader STATIC loader.h loader.c)\nset_target_properties(evmc_loader PROPERTIES LINKER_LANGUAGE C)\ntarget_link_libraries(evmc_loader INTERFACE ${CMAKE_DL_LIBS})\ntarget_include_directories(evmc_loader PUBLIC ${PROJECT_SOURCE_DIR}/test/)\nset_target_properties(evmc_loader PROPERTIES\n    POSITION_INDEPENDENT_CODE TRUE\n)\n\nadd_library(evmc INTERFACE)\ntarget_sources(evmc INTERFACE\n    ${PROJECT_SOURCE_DIR}/test/evmc/evmc.h\n    ${PROJECT_SOURCE_DIR}/test/evmc/evmc.hpp\n    ${PROJECT_SOURCE_DIR}/test/evmc/helpers.h\n    ${PROJECT_SOURCE_DIR}/test/evmc/utils.h\n)\ntarget_include_directories(evmc INTERFACE ${PROJECT_SOURCE_DIR}/test/)\ntarget_link_libraries(evmc INTERFACE evmc_loader)\n"
  },
  {
    "path": "test/evmc/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "test/evmc/README.md",
    "content": "# EVMC\n\nThis is an import of [EVMC](https://github.com/ipsilon/evmc) version [12.0.0](https://github.com/ipsilon/evmc/releases/tag/v12.0.0).\n\nSteps when upgrading:\n- Copy all from [include/evmc](https://github.com/ipsilon/evmc/tree/master/include/evmc) to [test/evmc](https://github.com/argotorg/solidity/tree/develop/test/evmc)\n    - Note that you should delete (or not copy in the first place) `tooling.hpp` and `instructions.h`.\n- Copy [`loader.c`](https://github.com/ipsilon/evmc/blob/master/lib/loader/loader.c) to [test/evmc](https://github.com/argotorg/solidity/tree/develop/test/evmc)\n- `MockedAccount.storage` in `mocked_host.hpp` should be changed to a `map` from `unordered_map` as ordering is important for fuzzing. You'll also need to include `<map>`.\n    See [PR #11094](https://github.com/argotorg/solidity/pull/11094) for more details.\n"
  },
  {
    "path": "test/evmc/bytes.hpp",
    "content": "// EVMC: Ethereum Client-VM Connector API.\n// Copyright 2024 The EVMC Authors.\n// Licensed under the Apache License, Version 2.0.\n#pragma once\n\n#include <algorithm>\n#include <cstring>\n#include <string>\n#include <string_view>\n\nnamespace evmc\n{\n/// The char traits for byte-like types.\n///\n/// See: https://en.cppreference.com/w/cpp/string/char_traits.\ntemplate <typename T>\nstruct byte_traits : std::char_traits<char>\n{\n    static_assert(sizeof(T) == 1, \"type must be a byte\");\n\n    using char_type = T;  ///< The byte type.\n\n    /// Assigns c2 to c1.\n    static constexpr void assign(char_type& c1, const char_type& c2) { c1 = c2; }\n\n    /// Assigns value to each byte in [ptr, ptr+count).\n    static constexpr char_type* assign(char_type* ptr, std::size_t count, char_type value)\n    {\n        std::fill_n(ptr, count, value);\n        return ptr;\n    }\n\n    /// Returns true if bytes are equal.\n    static constexpr bool eq(char_type a, char_type b) { return a == b; }\n\n    /// Returns true if byte a is less than byte b.\n    static constexpr bool lt(char_type a, char_type b) { return a < b; }\n\n    /// Copies count bytes from src to dest. Performs correctly even if ranges overlap.\n    static constexpr char_type* move(char_type* dest, const char_type* src, std::size_t count)\n    {\n        if (dest < src)\n            std::copy_n(src, count, dest);\n        else if (src < dest)\n            std::copy_backward(src, src + count, dest + count);\n        return dest;\n    }\n\n    /// Copies count bytes from src to dest. The ranges must not overlap.\n    static constexpr char_type* copy(char_type* dest, const char_type* src, std::size_t count)\n    {\n        std::copy_n(src, count, dest);\n        return dest;\n    }\n\n    /// Compares lexicographically the bytes in two ranges of equal length.\n    static constexpr int compare(const char_type* a, const char_type* b, std::size_t count)\n    {\n        for (; count != 0; --count, ++a, ++b)\n        {\n            if (lt(*a, *b))\n                return -1;\n            if (lt(*b, *a))\n                return 1;\n        }\n        return 0;\n    }\n\n    /// Returns the length of a null-terminated byte string.\n    // TODO: Not constexpr\n    static std::size_t length(const char_type* s)\n    {\n        return std::strlen(reinterpret_cast<const char*>(s));\n    }\n\n    /// Finds the value in the range of bytes and returns the pointer to the first occurrence\n    /// or nullptr if not found.\n    static constexpr const char_type* find(const char_type* s,\n                                           std::size_t count,\n                                           const char_type& value)\n    {\n        const auto end = s + count;\n        const auto p = std::find(s, end, value);\n        return p != end ? p : nullptr;\n    }\n};\n\n/// String of unsigned chars representing bytes.\nusing bytes = std::basic_string<unsigned char, byte_traits<unsigned char>>;\n\n/// String view of unsigned chars representing bytes.\nusing bytes_view = std::basic_string_view<unsigned char, byte_traits<unsigned char>>;\n}  // namespace evmc\n"
  },
  {
    "path": "test/evmc/evmc.h",
    "content": "/**\n * EVMC: Ethereum Client-VM Connector API\n *\n * @copyright\n * Copyright 2016 The EVMC Authors.\n * Licensed under the Apache License, Version 2.0.\n *\n * @defgroup EVMC EVMC\n * @{\n */\n#ifndef EVMC_H\n#define EVMC_H\n\n#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 6)\n/**\n * Portable declaration of \"deprecated\" attribute.\n *\n * Available for clang and GCC 6+ compilers. The older GCC compilers know\n * this attribute, but it cannot be applied to enum elements.\n */\n#define EVMC_DEPRECATED __attribute__((deprecated))\n#else\n#define EVMC_DEPRECATED\n#endif\n\n\n#include <stdbool.h> /* Definition of bool, true and false. */\n#include <stddef.h>  /* Definition of size_t. */\n#include <stdint.h>  /* Definition of int64_t, uint64_t. */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* BEGIN Python CFFI declarations */\n\nenum\n{\n    /**\n     * The EVMC ABI version number of the interface declared in this file.\n     *\n     * The EVMC ABI version always equals the major version number of the EVMC project.\n     * The Host SHOULD check if the ABI versions match when dynamically loading VMs.\n     *\n     * @see @ref versioning\n     */\n    EVMC_ABI_VERSION = 12\n};\n\n\n/**\n * The fixed size array of 32 bytes.\n *\n * 32 bytes of data capable of storing e.g. 256-bit hashes.\n */\ntypedef struct evmc_bytes32\n{\n    /** The 32 bytes. */\n    uint8_t bytes[32];\n} evmc_bytes32;\n\n/**\n * The alias for evmc_bytes32 to represent a big-endian 256-bit integer.\n */\ntypedef struct evmc_bytes32 evmc_uint256be;\n\n/** Big-endian 160-bit hash suitable for keeping an Ethereum address. */\ntypedef struct evmc_address\n{\n    /** The 20 bytes of the hash. */\n    uint8_t bytes[20];\n} evmc_address;\n\n/** The kind of call-like instruction. */\nenum evmc_call_kind\n{\n    EVMC_CALL = 0,         /**< Request CALL. */\n    EVMC_DELEGATECALL = 1, /**< Request DELEGATECALL. Valid since Homestead.\n                                The value param ignored. */\n    EVMC_CALLCODE = 2,     /**< Request CALLCODE. */\n    EVMC_CREATE = 3,       /**< Request CREATE. */\n    EVMC_CREATE2 = 4,      /**< Request CREATE2. Valid since Constantinople.*/\n    EVMC_EOFCREATE = 5     /**< Request EOFCREATE. Valid since Prague.*/\n};\n\n/** The flags for ::evmc_message. */\nenum evmc_flags\n{\n    EVMC_STATIC = 1 /**< Static call mode. */\n};\n\n/**\n * The message describing an EVM call, including a zero-depth calls from a transaction origin.\n *\n * Most of the fields are modelled by the section 8. Message Call of the Ethereum Yellow Paper.\n */\nstruct evmc_message\n{\n    /** The kind of the call. For zero-depth calls ::EVMC_CALL SHOULD be used. */\n    enum evmc_call_kind kind;\n\n    /**\n     * Additional flags modifying the call execution behavior.\n     * In the current version the only valid values are ::EVMC_STATIC or 0.\n     */\n    uint32_t flags;\n\n    /**\n     * The present depth of the message call stack.\n     *\n     * Defined as `e` in the Yellow Paper.\n     */\n    int32_t depth;\n\n    /**\n     * The amount of gas available to the message execution.\n     *\n     * Defined as `g` in the Yellow Paper.\n     */\n    int64_t gas;\n\n    /**\n     * The recipient of the message.\n     *\n     * This is the address of the account which storage/balance/nonce is going to be modified\n     * by the message execution. In case of ::EVMC_CALL, this is also the account where the\n     * message value evmc_message::value is going to be transferred.\n     * For ::EVMC_CALLCODE or ::EVMC_DELEGATECALL, this may be different from\n     * the evmc_message::code_address.\n     *\n     * Defined as `r` in the Yellow Paper.\n     */\n    evmc_address recipient;\n\n    /**\n     * The sender of the message.\n     *\n     * The address of the sender of a message call defined as `s` in the Yellow Paper.\n     * This must be the message recipient of the message at the previous (lower) depth,\n     * except for the ::EVMC_DELEGATECALL where recipient is the 2 levels above the present depth.\n     * At the depth 0 this must be the transaction origin.\n     */\n    evmc_address sender;\n\n    /**\n     * The message input data.\n     *\n     * The arbitrary length byte array of the input data of the call,\n     * defined as `d` in the Yellow Paper.\n     * This MAY be NULL.\n     */\n    const uint8_t* input_data;\n\n    /**\n     * The size of the message input data.\n     *\n     * If input_data is NULL this MUST be 0.\n     */\n    size_t input_size;\n\n    /**\n     * The amount of Ether transferred with the message.\n     *\n     * This is transferred value for ::EVMC_CALL or apparent value for ::EVMC_DELEGATECALL.\n     * Defined as `v` or `v~` in the Yellow Paper.\n     */\n    evmc_uint256be value;\n\n    /**\n     * The optional value used in new contract address construction.\n     *\n     * Needed only for a Host to calculate created address when kind is ::EVMC_CREATE2 or\n     * ::EVMC_EOFCREATE.\n     * Ignored in evmc_execute_fn().\n     */\n    evmc_bytes32 create2_salt;\n\n    /**\n     * The address of the code to be executed.\n     *\n     * For ::EVMC_CALLCODE or ::EVMC_DELEGATECALL this may be different from\n     * the evmc_message::recipient.\n     * Not required when invoking evmc_execute_fn(), only when invoking evmc_call_fn().\n     * Ignored if kind is ::EVMC_CREATE, ::EVMC_CREATE2 or ::EVMC_EOFCREATE.\n     *\n     * In case of ::EVMC_CAPABILITY_PRECOMPILES implementation, this fields should be inspected\n     * to identify the requested precompile.\n     *\n     * Defined as `c` in the Yellow Paper.\n     */\n    evmc_address code_address;\n\n    /**\n     * The code to be executed.\n     */\n    const uint8_t* code;\n\n    /**\n     * The length of the code to be executed.\n     */\n    size_t code_size;\n};\n\n/** The hashed initcode used for TXCREATE instruction. */\ntypedef struct evmc_tx_initcode\n{\n    evmc_bytes32 hash;   /**< The initcode hash. */\n    const uint8_t* code; /**< The code. */\n    size_t code_size;    /**< The length of the code. */\n} evmc_tx_initcode;\n\n/** The transaction and block data for execution. */\nstruct evmc_tx_context\n{\n    evmc_uint256be tx_gas_price;       /**< The transaction gas price. */\n    evmc_address tx_origin;            /**< The transaction origin account. */\n    evmc_address block_coinbase;       /**< The miner of the block. */\n    int64_t block_number;              /**< The block number. */\n    int64_t block_timestamp;           /**< The block timestamp. */\n    int64_t block_gas_limit;           /**< The block gas limit. */\n    evmc_uint256be block_prev_randao;  /**< The block previous RANDAO (EIP-4399). */\n    evmc_uint256be chain_id;           /**< The blockchain's ChainID. */\n    evmc_uint256be block_base_fee;     /**< The block base fee per gas (EIP-1559, EIP-3198). */\n    evmc_uint256be blob_base_fee;      /**< The blob base fee (EIP-7516). */\n    const evmc_bytes32* blob_hashes;   /**< The array of blob hashes (EIP-4844). */\n    size_t blob_hashes_count;          /**< The number of blob hashes (EIP-4844). */\n    const evmc_tx_initcode* initcodes; /**< The array of transaction initcodes (TXCREATE). */\n    size_t initcodes_count;            /**< The number of transaction initcodes (TXCREATE). */\n};\n\n/**\n * @struct evmc_host_context\n * The opaque data type representing the Host execution context.\n * @see evmc_execute_fn().\n */\nstruct evmc_host_context;\n\n/**\n * Get transaction context callback function.\n *\n *  This callback function is used by an EVM to retrieve the transaction and\n *  block context.\n *\n *  @param      context  The pointer to the Host execution context.\n *  @return              The transaction context.\n */\ntypedef struct evmc_tx_context (*evmc_get_tx_context_fn)(struct evmc_host_context* context);\n\n/**\n * Get block hash callback function.\n *\n * This callback function is used by a VM to query the hash of the header of the given block.\n * If the information about the requested block is not available, then this is signalled by\n * returning null bytes.\n *\n * @param context  The pointer to the Host execution context.\n * @param number   The block number.\n * @return         The block hash or null bytes\n *                 if the information about the block is not available.\n */\ntypedef evmc_bytes32 (*evmc_get_block_hash_fn)(struct evmc_host_context* context, int64_t number);\n\n/**\n * The execution status code.\n *\n * Successful execution is represented by ::EVMC_SUCCESS having value 0.\n *\n * Positive values represent failures defined by VM specifications with generic\n * ::EVMC_FAILURE code of value 1.\n *\n * Status codes with negative values represent VM internal errors\n * not provided by EVM specifications. These errors MUST not be passed back\n * to the caller. They MAY be handled by the Client in predefined manner\n * (see e.g. ::EVMC_REJECTED), otherwise internal errors are not recoverable.\n * The generic representant of errors is ::EVMC_INTERNAL_ERROR but\n * an EVM implementation MAY return negative status codes that are not defined\n * in the EVMC documentation.\n *\n * @note\n * In case new status codes are needed, please create an issue or pull request\n * in the EVMC repository (https://github.com/ipsilon/evmc).\n */\nenum evmc_status_code\n{\n    /** Execution finished with success. */\n    EVMC_SUCCESS = 0,\n\n    /** Generic execution failure. */\n    EVMC_FAILURE = 1,\n\n    /**\n     * Execution terminated with REVERT opcode.\n     *\n     * In this case the amount of gas left MAY be non-zero and additional output\n     * data MAY be provided in ::evmc_result.\n     */\n    EVMC_REVERT = 2,\n\n    /** The execution has run out of gas. */\n    EVMC_OUT_OF_GAS = 3,\n\n    /**\n     * The designated INVALID instruction has been hit during execution.\n     *\n     * The EIP-141 (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-141.md)\n     * defines the instruction 0xfe as INVALID instruction to indicate execution\n     * abortion coming from high-level languages. This status code is reported\n     * in case this INVALID instruction has been encountered.\n     */\n    EVMC_INVALID_INSTRUCTION = 4,\n\n    /** An undefined instruction has been encountered. */\n    EVMC_UNDEFINED_INSTRUCTION = 5,\n\n    /**\n     * The execution has attempted to put more items on the EVM stack\n     * than the specified limit.\n     */\n    EVMC_STACK_OVERFLOW = 6,\n\n    /** Execution of an opcode has required more items on the EVM stack. */\n    EVMC_STACK_UNDERFLOW = 7,\n\n    /** Execution has violated the jump destination restrictions. */\n    EVMC_BAD_JUMP_DESTINATION = 8,\n\n    /**\n     * Tried to read outside memory bounds.\n     *\n     * An example is RETURNDATACOPY reading past the available buffer.\n     */\n    EVMC_INVALID_MEMORY_ACCESS = 9,\n\n    /** Call depth has exceeded the limit (if any) */\n    EVMC_CALL_DEPTH_EXCEEDED = 10,\n\n    /** Tried to execute an operation which is restricted in static mode. */\n    EVMC_STATIC_MODE_VIOLATION = 11,\n\n    /**\n     * A call to a precompiled or system contract has ended with a failure.\n     *\n     * An example: elliptic curve functions handed invalid EC points.\n     */\n    EVMC_PRECOMPILE_FAILURE = 12,\n\n    /**\n     * Contract validation has failed (e.g. due to EVM 1.5 jump validity,\n     * Casper's purity checker or ewasm contract rules).\n     */\n    EVMC_CONTRACT_VALIDATION_FAILURE = 13,\n\n    /**\n     * An argument to a state accessing method has a value outside of the\n     * accepted range of values.\n     */\n    EVMC_ARGUMENT_OUT_OF_RANGE = 14,\n\n    /**\n     * A WebAssembly `unreachable` instruction has been hit during execution.\n     */\n    EVMC_WASM_UNREACHABLE_INSTRUCTION = 15,\n\n    /**\n     * A WebAssembly trap has been hit during execution. This can be for many\n     * reasons, including division by zero, validation errors, etc.\n     */\n    EVMC_WASM_TRAP = 16,\n\n    /** The caller does not have enough funds for value transfer. */\n    EVMC_INSUFFICIENT_BALANCE = 17,\n\n    /** EVM implementation generic internal error. */\n    EVMC_INTERNAL_ERROR = -1,\n\n    /**\n     * The execution of the given code and/or message has been rejected\n     * by the EVM implementation.\n     *\n     * This error SHOULD be used to signal that the EVM is not able to or\n     * willing to execute the given code type or message.\n     * If an EVM returns the ::EVMC_REJECTED status code,\n     * the Client MAY try to execute it in other EVM implementation.\n     * For example, the Client tries running a code in the EVM 1.5. If the\n     * code is not supported there, the execution falls back to the EVM 1.0.\n     */\n    EVMC_REJECTED = -2,\n\n    /** The VM failed to allocate the amount of memory needed for execution. */\n    EVMC_OUT_OF_MEMORY = -3\n};\n\n/* Forward declaration. */\nstruct evmc_result;\n\n/**\n * Releases resources assigned to an execution result.\n *\n * This function releases memory (and other resources, if any) assigned to the\n * specified execution result making the result object invalid.\n *\n * @param result  The execution result which resources are to be released. The\n *                result itself it not modified by this function, but becomes\n *                invalid and user MUST discard it as well.\n *                This MUST NOT be NULL.\n *\n * @note\n * The result is passed by pointer to avoid (shallow) copy of the ::evmc_result\n * struct. Think of this as the best possible C language approximation to\n * passing objects by reference.\n */\ntypedef void (*evmc_release_result_fn)(const struct evmc_result* result);\n\n/** The EVM code execution result. */\nstruct evmc_result\n{\n    /** The execution status code. */\n    enum evmc_status_code status_code;\n\n    /**\n     * The amount of gas left after the execution.\n     *\n     * If evmc_result::status_code is neither ::EVMC_SUCCESS nor ::EVMC_REVERT\n     * the value MUST be 0.\n     */\n    int64_t gas_left;\n\n    /**\n     * The refunded gas accumulated from this execution and its sub-calls.\n     *\n     * The transaction gas refund limit is not applied.\n     * If evmc_result::status_code is other than ::EVMC_SUCCESS the value MUST be 0.\n     */\n    int64_t gas_refund;\n\n    /**\n     * The reference to output data.\n     *\n     * The output contains data coming from RETURN opcode (iff evmc_result::code\n     * field is ::EVMC_SUCCESS) or from REVERT opcode.\n     *\n     * The memory containing the output data is owned by EVM and has to be\n     * freed with evmc_result::release().\n     *\n     * This pointer MAY be NULL.\n     * If evmc_result::output_size is 0 this pointer MUST NOT be dereferenced.\n     */\n    const uint8_t* output_data;\n\n    /**\n     * The size of the output data.\n     *\n     * If evmc_result::output_data is NULL this MUST be 0.\n     */\n    size_t output_size;\n\n    /**\n     * The method releasing all resources associated with the result object.\n     *\n     * This method (function pointer) is optional (MAY be NULL) and MAY be set\n     * by the VM implementation. If set it MUST be called by the user once to\n     * release memory and other resources associated with the result object.\n     * Once the resources are released the result object MUST NOT be used again.\n     *\n     * The suggested code pattern for releasing execution results:\n     * @code\n     * struct evmc_result result = ...;\n     * if (result.release)\n     *     result.release(&result);\n     * @endcode\n     *\n     * @note\n     * It works similarly to C++ virtual destructor. Attaching the release\n     * function to the result itself allows VM composition.\n     */\n    evmc_release_result_fn release;\n\n    /**\n     * The address of the possibly created contract.\n     *\n     * The create address may be provided even though the contract creation has failed\n     * (evmc_result::status_code is not ::EVMC_SUCCESS). This is useful in situations\n     * when the address is observable, e.g. access to it remains warm.\n     * In all other cases the address MUST be null bytes.\n     */\n    evmc_address create_address;\n\n    /**\n     * Reserved data that MAY be used by a evmc_result object creator.\n     *\n     * This reserved 4 bytes together with 20 bytes from create_address form\n     * 24 bytes of memory called \"optional data\" within evmc_result struct\n     * to be optionally used by the evmc_result object creator.\n     *\n     * @see evmc_result_optional_data, evmc_get_optional_data().\n     *\n     * Also extends the size of the evmc_result to 64 bytes (full cache line).\n     */\n    uint8_t padding[4];\n};\n\n\n/**\n * Check account existence callback function.\n *\n * This callback function is used by the VM to check if\n * there exists an account at given address.\n * @param context  The pointer to the Host execution context.\n * @param address  The address of the account the query is about.\n * @return         true if exists, false otherwise.\n */\ntypedef bool (*evmc_account_exists_fn)(struct evmc_host_context* context,\n                                       const evmc_address* address);\n\n/**\n * Get storage callback function.\n *\n * This callback function is used by a VM to query the given account storage entry.\n *\n * @param context  The Host execution context.\n * @param address  The address of the account.\n * @param key      The index of the account's storage entry.\n * @return         The storage value at the given storage key or null bytes\n *                 if the account does not exist.\n */\ntypedef evmc_bytes32 (*evmc_get_storage_fn)(struct evmc_host_context* context,\n                                            const evmc_address* address,\n                                            const evmc_bytes32* key);\n\n/**\n * Get transient storage callback function.\n *\n * This callback function is used by a VM to query\n * the given account transient storage (EIP-1153) entry.\n *\n * @param context  The Host execution context.\n * @param address  The address of the account.\n * @param key      The index of the account's transient storage entry.\n * @return         The transient storage value at the given storage key or null bytes\n *                 if the account does not exist.\n */\ntypedef evmc_bytes32 (*evmc_get_transient_storage_fn)(struct evmc_host_context* context,\n                                                      const evmc_address* address,\n                                                      const evmc_bytes32* key);\n\n\n/**\n * The effect of an attempt to modify a contract storage item.\n *\n * See @ref storagestatus for additional information about design of this enum\n * and analysis of the specification.\n *\n * For the purpose of explaining the meaning of each element, the following\n * notation is used:\n * - 0 is zero value,\n * - X != 0 (X is any value other than 0),\n * - Y != 0, Y != X,  (Y is any value other than X and 0),\n * - Z != 0, Z != X, Z != X (Z is any value other than Y and X and 0),\n * - the \"o -> c -> v\" triple describes the change status in the context of:\n *   - o: original value (cold value before a transaction started),\n *   - c: current storage value,\n *   - v: new storage value to be set.\n *\n * The order of elements follows EIPs introducing net storage gas costs:\n * - EIP-2200: https://eips.ethereum.org/EIPS/eip-2200,\n * - EIP-1283: https://eips.ethereum.org/EIPS/eip-1283.\n */\nenum evmc_storage_status\n{\n    /**\n     * The new/same value is assigned to the storage item without affecting the cost structure.\n     *\n     * The storage value item is either:\n     * - left unchanged (c == v) or\n     * - the dirty value (o != c) is modified again (c != v).\n     * This is the group of cases related to minimal gas cost of only accessing warm storage.\n     * 0|X   -> 0 -> 0 (current value unchanged)\n     * 0|X|Y -> Y -> Y (current value unchanged)\n     * 0|X   -> Y -> Z (modified previously added/modified value)\n     *\n     * This is \"catch all remaining\" status. I.e. if all other statuses are correctly matched\n     * this status should be assigned to all remaining cases.\n     */\n    EVMC_STORAGE_ASSIGNED = 0,\n\n    /**\n     * A new storage item is added by changing\n     * the current clean zero to a nonzero value.\n     * 0 -> 0 -> Z\n     */\n    EVMC_STORAGE_ADDED = 1,\n\n    /**\n     * A storage item is deleted by changing\n     * the current clean nonzero to the zero value.\n     * X -> X -> 0\n     */\n    EVMC_STORAGE_DELETED = 2,\n\n    /**\n     * A storage item is modified by changing\n     * the current clean nonzero to other nonzero value.\n     * X -> X -> Z\n     */\n    EVMC_STORAGE_MODIFIED = 3,\n\n    /**\n     * A storage item is added by changing\n     * the current dirty zero to a nonzero value other than the original value.\n     * X -> 0 -> Z\n     */\n    EVMC_STORAGE_DELETED_ADDED = 4,\n\n    /**\n     * A storage item is deleted by changing\n     * the current dirty nonzero to the zero value and the original value is not zero.\n     * X -> Y -> 0\n     */\n    EVMC_STORAGE_MODIFIED_DELETED = 5,\n\n    /**\n     * A storage item is added by changing\n     * the current dirty zero to the original value.\n     * X -> 0 -> X\n     */\n    EVMC_STORAGE_DELETED_RESTORED = 6,\n\n    /**\n     * A storage item is deleted by changing\n     * the current dirty nonzero to the original zero value.\n     * 0 -> Y -> 0\n     */\n    EVMC_STORAGE_ADDED_DELETED = 7,\n\n    /**\n     * A storage item is modified by changing\n     * the current dirty nonzero to the original nonzero value other than the current value.\n     * X -> Y -> X\n     */\n    EVMC_STORAGE_MODIFIED_RESTORED = 8\n};\n\n\n/**\n * Set storage callback function.\n *\n * This callback function is used by a VM to update the given account storage entry.\n * The VM MUST make sure that the account exists. This requirement is only a formality because\n * VM implementations only modify storage of the account of the current execution context\n * (i.e. referenced by evmc_message::recipient).\n *\n * @param context  The pointer to the Host execution context.\n * @param address  The address of the account.\n * @param key      The index of the storage entry.\n * @param value    The value to be stored.\n * @return         The effect on the storage item.\n */\ntypedef enum evmc_storage_status (*evmc_set_storage_fn)(struct evmc_host_context* context,\n                                                        const evmc_address* address,\n                                                        const evmc_bytes32* key,\n                                                        const evmc_bytes32* value);\n\n/**\n * Set transient storage callback function.\n *\n * This callback function is used by a VM to update\n * the given account's transient storage (EIP-1153) entry.\n * The VM MUST make sure that the account exists. This requirement is only a formality because\n * VM implementations only modify storage of the account of the current execution context\n * (i.e. referenced by evmc_message::recipient).\n *\n * @param context  The pointer to the Host execution context.\n * @param address  The address of the account.\n * @param key      The index of the transient storage entry.\n * @param value    The value to be stored.\n */\ntypedef void (*evmc_set_transient_storage_fn)(struct evmc_host_context* context,\n                                              const evmc_address* address,\n                                              const evmc_bytes32* key,\n                                              const evmc_bytes32* value);\n\n/**\n * Get balance callback function.\n *\n * This callback function is used by a VM to query the balance of the given account.\n *\n * @param context  The pointer to the Host execution context.\n * @param address  The address of the account.\n * @return         The balance of the given account or 0 if the account does not exist.\n */\ntypedef evmc_uint256be (*evmc_get_balance_fn)(struct evmc_host_context* context,\n                                              const evmc_address* address);\n\n/**\n * Get code size callback function.\n *\n * This callback function is used by a VM to get the size of the code stored\n * in the account at the given address.\n *\n * @param context  The pointer to the Host execution context.\n * @param address  The address of the account.\n * @return         The size of the code in the account or 0 if the account does not exist.\n */\ntypedef size_t (*evmc_get_code_size_fn)(struct evmc_host_context* context,\n                                        const evmc_address* address);\n\n/**\n * Get code hash callback function.\n *\n * This callback function is used by a VM to get the keccak256 hash of the code stored\n * in the account at the given address. For existing accounts not having a code, this\n * function returns keccak256 hash of empty data.\n *\n * @param context  The pointer to the Host execution context.\n * @param address  The address of the account.\n * @return         The hash of the code in the account or null bytes if the account does not exist.\n */\ntypedef evmc_bytes32 (*evmc_get_code_hash_fn)(struct evmc_host_context* context,\n                                              const evmc_address* address);\n\n/**\n * Copy code callback function.\n *\n * This callback function is used by an EVM to request a copy of the code\n * of the given account to the memory buffer provided by the EVM.\n * The Client MUST copy the requested code, starting with the given offset,\n * to the provided memory buffer up to the size of the buffer or the size of\n * the code, whichever is smaller.\n *\n * @param context      The pointer to the Host execution context. See ::evmc_host_context.\n * @param address      The address of the account.\n * @param code_offset  The offset of the code to copy.\n * @param buffer_data  The pointer to the memory buffer allocated by the EVM\n *                     to store a copy of the requested code.\n * @param buffer_size  The size of the memory buffer.\n * @return             The number of bytes copied to the buffer by the Client.\n */\ntypedef size_t (*evmc_copy_code_fn)(struct evmc_host_context* context,\n                                    const evmc_address* address,\n                                    size_t code_offset,\n                                    uint8_t* buffer_data,\n                                    size_t buffer_size);\n\n/**\n * Selfdestruct callback function.\n *\n * This callback function is used by an EVM to SELFDESTRUCT given contract.\n * The execution of the contract will not be stopped, that is up to the EVM.\n *\n * @param context      The pointer to the Host execution context. See ::evmc_host_context.\n * @param address      The address of the contract to be selfdestructed.\n * @param beneficiary  The address where the remaining ETH is going to be transferred.\n * @return             The information if the given address has not been registered as\n *                     selfdestructed yet. True if registered for the first time, false otherwise.\n */\ntypedef bool (*evmc_selfdestruct_fn)(struct evmc_host_context* context,\n                                     const evmc_address* address,\n                                     const evmc_address* beneficiary);\n\n/**\n * Log callback function.\n *\n * This callback function is used by an EVM to inform about a LOG that happened\n * during an EVM bytecode execution.\n *\n * @param context       The pointer to the Host execution context. See ::evmc_host_context.\n * @param address       The address of the contract that generated the log.\n * @param data          The pointer to unindexed data attached to the log.\n * @param data_size     The length of the data.\n * @param topics        The pointer to the array of topics attached to the log.\n * @param topics_count  The number of the topics. Valid values are between 0 and 4 inclusively.\n */\ntypedef void (*evmc_emit_log_fn)(struct evmc_host_context* context,\n                                 const evmc_address* address,\n                                 const uint8_t* data,\n                                 size_t data_size,\n                                 const evmc_bytes32 topics[],\n                                 size_t topics_count);\n\n/**\n * Access status per EIP-2929: Gas cost increases for state access opcodes.\n */\nenum evmc_access_status\n{\n    /**\n     * The entry hasn't been accessed before – it's the first access.\n     */\n    EVMC_ACCESS_COLD = 0,\n\n    /**\n     * The entry is already in accessed_addresses or accessed_storage_keys.\n     */\n    EVMC_ACCESS_WARM = 1\n};\n\n/**\n * Access account callback function.\n *\n * This callback function is used by a VM to add the given address\n * to accessed_addresses substate (EIP-2929).\n *\n * @param context  The Host execution context.\n * @param address  The address of the account.\n * @return         EVMC_ACCESS_WARM if accessed_addresses already contained the address\n *                 or EVMC_ACCESS_COLD otherwise.\n */\ntypedef enum evmc_access_status (*evmc_access_account_fn)(struct evmc_host_context* context,\n                                                          const evmc_address* address);\n\n/**\n * Access storage callback function.\n *\n * This callback function is used by a VM to add the given account storage entry\n * to accessed_storage_keys substate (EIP-2929).\n *\n * @param context  The Host execution context.\n * @param address  The address of the account.\n * @param key      The index of the account's storage entry.\n * @return         EVMC_ACCESS_WARM if accessed_storage_keys already contained the key\n *                 or EVMC_ACCESS_COLD otherwise.\n */\ntypedef enum evmc_access_status (*evmc_access_storage_fn)(struct evmc_host_context* context,\n                                                          const evmc_address* address,\n                                                          const evmc_bytes32* key);\n\n/**\n * Pointer to the callback function supporting EVM calls.\n *\n * @param context  The pointer to the Host execution context.\n * @param msg      The call parameters.\n * @return         The result of the call.\n */\ntypedef struct evmc_result (*evmc_call_fn)(struct evmc_host_context* context,\n                                           const struct evmc_message* msg);\n\n/**\n * The Host interface.\n *\n * The set of all callback functions expected by VM instances. This is C\n * realisation of vtable for OOP interface (only virtual methods, no data).\n * Host implementations SHOULD create constant singletons of this (similarly\n * to vtables) to lower the maintenance and memory management cost.\n */\nstruct evmc_host_interface\n{\n    /** Check account existence callback function. */\n    evmc_account_exists_fn account_exists;\n\n    /** Get storage callback function. */\n    evmc_get_storage_fn get_storage;\n\n    /** Set storage callback function. */\n    evmc_set_storage_fn set_storage;\n\n    /** Get balance callback function. */\n    evmc_get_balance_fn get_balance;\n\n    /** Get code size callback function. */\n    evmc_get_code_size_fn get_code_size;\n\n    /** Get code hash callback function. */\n    evmc_get_code_hash_fn get_code_hash;\n\n    /** Copy code callback function. */\n    evmc_copy_code_fn copy_code;\n\n    /** Selfdestruct callback function. */\n    evmc_selfdestruct_fn selfdestruct;\n\n    /** Call callback function. */\n    evmc_call_fn call;\n\n    /** Get transaction context callback function. */\n    evmc_get_tx_context_fn get_tx_context;\n\n    /** Get block hash callback function. */\n    evmc_get_block_hash_fn get_block_hash;\n\n    /** Emit log callback function. */\n    evmc_emit_log_fn emit_log;\n\n    /** Access account callback function. */\n    evmc_access_account_fn access_account;\n\n    /** Access storage callback function. */\n    evmc_access_storage_fn access_storage;\n\n    /** Get transient storage callback function. */\n    evmc_get_transient_storage_fn get_transient_storage;\n\n    /** Set transient storage callback function. */\n    evmc_set_transient_storage_fn set_transient_storage;\n};\n\n\n/* Forward declaration. */\nstruct evmc_vm;\n\n/**\n * Destroys the VM instance.\n *\n * @param vm  The VM instance to be destroyed.\n */\ntypedef void (*evmc_destroy_fn)(struct evmc_vm* vm);\n\n/**\n * Possible outcomes of evmc_set_option.\n */\nenum evmc_set_option_result\n{\n    EVMC_SET_OPTION_SUCCESS = 0,\n    EVMC_SET_OPTION_INVALID_NAME = 1,\n    EVMC_SET_OPTION_INVALID_VALUE = 2\n};\n\n/**\n * Configures the VM instance.\n *\n * Allows modifying options of the VM instance.\n * Options:\n * - code cache behavior: on, off, read-only, ...\n * - optimizations,\n *\n * @param vm     The VM instance to be configured.\n * @param name   The option name. NULL-terminated string. Cannot be NULL.\n * @param value  The new option value. NULL-terminated string. Cannot be NULL.\n * @return       The outcome of the operation.\n */\ntypedef enum evmc_set_option_result (*evmc_set_option_fn)(struct evmc_vm* vm,\n                                                          char const* name,\n                                                          char const* value);\n\n\n/**\n * EVM revision.\n *\n * The revision of the EVM specification based on the Ethereum\n * upgrade / hard fork codenames.\n */\nenum evmc_revision\n{\n    /**\n     * The Frontier revision.\n     *\n     * The one Ethereum launched with.\n     */\n    EVMC_FRONTIER = 0,\n\n    /**\n     * The Homestead revision.\n     *\n     * https://eips.ethereum.org/EIPS/eip-606\n     */\n    EVMC_HOMESTEAD = 1,\n\n    /**\n     * The Tangerine Whistle revision.\n     *\n     * https://eips.ethereum.org/EIPS/eip-608\n     */\n    EVMC_TANGERINE_WHISTLE = 2,\n\n    /**\n     * The Spurious Dragon revision.\n     *\n     * https://eips.ethereum.org/EIPS/eip-607\n     */\n    EVMC_SPURIOUS_DRAGON = 3,\n\n    /**\n     * The Byzantium revision.\n     *\n     * https://eips.ethereum.org/EIPS/eip-609\n     */\n    EVMC_BYZANTIUM = 4,\n\n    /**\n     * The Constantinople revision.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1013\n     */\n    EVMC_CONSTANTINOPLE = 5,\n\n    /**\n     * The Petersburg revision.\n     *\n     * Other names: Constantinople2, ConstantinopleFix.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1716\n     */\n    EVMC_PETERSBURG = 6,\n\n    /**\n     * The Istanbul revision.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1679\n     */\n    EVMC_ISTANBUL = 7,\n\n    /**\n     * The Berlin revision.\n     *\n     * https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md\n     */\n    EVMC_BERLIN = 8,\n\n    /**\n     * The London revision.\n     *\n     * https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md\n     */\n    EVMC_LONDON = 9,\n\n    /**\n     * The Paris revision (aka The Merge).\n     *\n     * https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md\n     */\n    EVMC_PARIS = 10,\n\n    /**\n     * The Shanghai revision.\n     *\n     * https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md\n     */\n    EVMC_SHANGHAI = 11,\n\n    /**\n     * The Cancun revision.\n     *\n     * https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md\n     */\n    EVMC_CANCUN = 12,\n\n    /**\n     * The Prague revision.\n     *\n     * The future next revision after Cancun.\n     */\n    EVMC_PRAGUE = 13,\n\n    /**\n     * The Osaka revision.\n     *\n     * The future next revision after Prague.\n     */\n    EVMC_OSAKA = 14,\n\n    /** The maximum EVM revision supported. */\n    EVMC_MAX_REVISION = EVMC_OSAKA,\n\n    /**\n     * The latest known EVM revision with finalized specification.\n     *\n     * This is handy for EVM tools to always use the latest revision available.\n     */\n    EVMC_LATEST_STABLE_REVISION = EVMC_CANCUN\n};\n\n\n/**\n * Executes the given code using the input from the message.\n *\n * This function MAY be invoked multiple times for a single VM instance.\n *\n * @param vm         The VM instance. This argument MUST NOT be NULL.\n * @param host       The Host interface. This argument MUST NOT be NULL unless\n *                   the @p vm has the ::EVMC_CAPABILITY_PRECOMPILES capability.\n * @param context    The opaque pointer to the Host execution context.\n *                   This argument MAY be NULL. The VM MUST pass the same\n *                   pointer to the methods of the @p host interface.\n *                   The VM MUST NOT dereference the pointer.\n * @param rev        The requested EVM specification revision.\n * @param msg        The call parameters. See ::evmc_message. This argument MUST NOT be NULL.\n * @param code       The reference to the code to be executed. This argument MAY be NULL.\n * @param code_size  The length of the code. If @p code is NULL this argument MUST be 0.\n * @return           The execution result.\n */\ntypedef struct evmc_result (*evmc_execute_fn)(struct evmc_vm* vm,\n                                              const struct evmc_host_interface* host,\n                                              struct evmc_host_context* context,\n                                              enum evmc_revision rev,\n                                              const struct evmc_message* msg,\n                                              uint8_t const* code,\n                                              size_t code_size);\n\n/**\n * Possible capabilities of a VM.\n */\nenum evmc_capabilities\n{\n    /**\n     * The VM is capable of executing EVM1 bytecode.\n     */\n    EVMC_CAPABILITY_EVM1 = (1u << 0),\n\n    /**\n     * The VM is capable of executing ewasm bytecode.\n     */\n    EVMC_CAPABILITY_EWASM = (1u << 1),\n\n    /**\n     * The VM is capable of executing the precompiled contracts\n     * defined for the range of code addresses.\n     *\n     * The EIP-1352 (https://eips.ethereum.org/EIPS/eip-1352) specifies\n     * the range 0x000...0000 - 0x000...ffff of addresses\n     * reserved for precompiled and system contracts.\n     *\n     * This capability is **experimental** and MAY be removed without notice.\n     */\n    EVMC_CAPABILITY_PRECOMPILES = (1u << 2)\n};\n\n/**\n * Alias for unsigned integer representing a set of bit flags of EVMC capabilities.\n *\n * @see evmc_capabilities\n */\ntypedef uint32_t evmc_capabilities_flagset;\n\n/**\n * Return the supported capabilities of the VM instance.\n *\n * This function MAY be invoked multiple times for a single VM instance,\n * and its value MAY be influenced by calls to evmc_vm::set_option.\n *\n * @param vm  The VM instance.\n * @return    The supported capabilities of the VM. @see evmc_capabilities.\n */\ntypedef evmc_capabilities_flagset (*evmc_get_capabilities_fn)(struct evmc_vm* vm);\n\n\n/**\n * The VM instance.\n *\n * Defines the base struct of the VM implementation.\n */\nstruct evmc_vm\n{\n    /**\n     * EVMC ABI version implemented by the VM instance.\n     *\n     * Can be used to detect ABI incompatibilities.\n     * The EVMC ABI version represented by this file is in ::EVMC_ABI_VERSION.\n     */\n    const int abi_version;\n\n    /**\n     * The name of the EVMC VM implementation.\n     *\n     * It MUST be a NULL-terminated not empty string.\n     * The content MUST be UTF-8 encoded (this implies ASCII encoding is also allowed).\n     */\n    const char* name;\n\n    /**\n     * The version of the EVMC VM implementation, e.g. \"1.2.3b4\".\n     *\n     * It MUST be a NULL-terminated not empty string.\n     * The content MUST be UTF-8 encoded (this implies ASCII encoding is also allowed).\n     */\n    const char* version;\n\n    /**\n     * Pointer to function destroying the VM instance.\n     *\n     * This is a mandatory method and MUST NOT be set to NULL.\n     */\n    evmc_destroy_fn destroy;\n\n    /**\n     * Pointer to function executing a code by the VM instance.\n     *\n     * This is a mandatory method and MUST NOT be set to NULL.\n     */\n    evmc_execute_fn execute;\n\n    /**\n     * A method returning capabilities supported by the VM instance.\n     *\n     * The value returned MAY change when different options are set via the set_option() method.\n     *\n     * A Client SHOULD only rely on the value returned if it has queried it after\n     * it has called the set_option().\n     *\n     * This is a mandatory method and MUST NOT be set to NULL.\n     */\n    evmc_get_capabilities_fn get_capabilities;\n\n    /**\n     * Optional pointer to function modifying VM's options.\n     *\n     * If the VM does not support this feature the pointer can be NULL.\n     */\n    evmc_set_option_fn set_option;\n};\n\n/* END Python CFFI declarations */\n\n#ifdef EVMC_DOCUMENTATION\n/**\n * Example of a function creating an instance of an example EVM implementation.\n *\n * Each EVM implementation MUST provide a function returning an EVM instance.\n * The function SHOULD be named `evmc_create_<vm-name>(void)`. If the VM name contains hyphens\n * replaces them with underscores in the function names.\n *\n * @par Binaries naming convention\n * For VMs distributed as shared libraries, the name of the library SHOULD match the VM name.\n * The conventional library filename prefixes and extensions SHOULD be ignored by the Client.\n * For example, the shared library with the \"beta-interpreter\" implementation may be named\n * `libbeta-interpreter.so`.\n *\n * @return  The VM instance or NULL indicating instance creation failure.\n */\nstruct evmc_vm* evmc_create_example_vm(void);\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n/** @} */\n"
  },
  {
    "path": "test/evmc/evmc.hpp",
    "content": "// EVMC: Ethereum Client-VM Connector API.\n// Copyright 2018 The EVMC Authors.\n// Licensed under the Apache License, Version 2.0.\n#pragma once\n\n#include <evmc/evmc.h>\n#include <evmc/helpers.h>\n#include <evmc/hex.hpp>\n\n#include <functional>\n#include <initializer_list>\n#include <ostream>\n#include <string_view>\n#include <utility>\n\nstatic_assert(EVMC_LATEST_STABLE_REVISION <= EVMC_MAX_REVISION,\n              \"latest stable revision ill-defined\");\n\n/// EVMC C++ API - wrappers and bindings for C++\n/// @ingroup cpp\nnamespace evmc\n{\n/// The big-endian 160-bit hash suitable for keeping an Ethereum address.\n///\n/// This type wraps C ::evmc_address to make sure objects of this type are always initialized.\nstruct address : evmc_address\n{\n    /// Default and converting constructor.\n    ///\n    /// Initializes bytes to zeros if not other @p init value provided.\n    constexpr address(evmc_address init = {}) noexcept : evmc_address{init} {}\n\n    /// Converting constructor from unsigned integer value.\n    ///\n    /// This constructor assigns the @p v value to the last 8 bytes [12:19]\n    /// in big-endian order.\n    constexpr explicit address(uint64_t v) noexcept\n      : evmc_address{{0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      static_cast<uint8_t>(v >> 56),\n                      static_cast<uint8_t>(v >> 48),\n                      static_cast<uint8_t>(v >> 40),\n                      static_cast<uint8_t>(v >> 32),\n                      static_cast<uint8_t>(v >> 24),\n                      static_cast<uint8_t>(v >> 16),\n                      static_cast<uint8_t>(v >> 8),\n                      static_cast<uint8_t>(v >> 0)}}\n    {}\n\n    /// Explicit operator converting to bool.\n    inline constexpr explicit operator bool() const noexcept;\n\n    /// Implicit operator converting to bytes_view.\n    inline constexpr operator bytes_view() const noexcept { return {bytes, sizeof(bytes)}; }\n};\n\n/// The fixed size array of 32 bytes for storing 256-bit EVM values.\n///\n/// This type wraps C ::evmc_bytes32 to make sure objects of this type are always initialized.\nstruct bytes32 : evmc_bytes32\n{\n    /// Default and converting constructor.\n    ///\n    /// Initializes bytes to zeros if not other @p init value provided.\n    constexpr bytes32(evmc_bytes32 init = {}) noexcept : evmc_bytes32{init} {}\n\n    /// Converting constructor from unsigned integer value.\n    ///\n    /// This constructor assigns the @p v value to the last 8 bytes [24:31]\n    /// in big-endian order.\n    constexpr explicit bytes32(uint64_t v) noexcept\n      : evmc_bytes32{{0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      0,\n                      static_cast<uint8_t>(v >> 56),\n                      static_cast<uint8_t>(v >> 48),\n                      static_cast<uint8_t>(v >> 40),\n                      static_cast<uint8_t>(v >> 32),\n                      static_cast<uint8_t>(v >> 24),\n                      static_cast<uint8_t>(v >> 16),\n                      static_cast<uint8_t>(v >> 8),\n                      static_cast<uint8_t>(v >> 0)}}\n    {}\n\n    /// Explicit operator converting to bool.\n    inline constexpr explicit operator bool() const noexcept;\n\n    /// Implicit operator converting to bytes_view.\n    inline constexpr operator bytes_view() const noexcept { return {bytes, sizeof(bytes)}; }\n};\n\n/// The alias for evmc::bytes32 to represent a big-endian 256-bit integer.\nusing uint256be = bytes32;\n\n\n/// Loads 64 bits / 8 bytes of data from the given @p data array in big-endian order.\ninline constexpr uint64_t load64be(const uint8_t* data) noexcept\n{\n    return (uint64_t{data[0]} << 56) | (uint64_t{data[1]} << 48) | (uint64_t{data[2]} << 40) |\n           (uint64_t{data[3]} << 32) | (uint64_t{data[4]} << 24) | (uint64_t{data[5]} << 16) |\n           (uint64_t{data[6]} << 8) | uint64_t{data[7]};\n}\n\n/// Loads 64 bits / 8 bytes of data from the given @p data array in little-endian order.\ninline constexpr uint64_t load64le(const uint8_t* data) noexcept\n{\n    return uint64_t{data[0]} | (uint64_t{data[1]} << 8) | (uint64_t{data[2]} << 16) |\n           (uint64_t{data[3]} << 24) | (uint64_t{data[4]} << 32) | (uint64_t{data[5]} << 40) |\n           (uint64_t{data[6]} << 48) | (uint64_t{data[7]} << 56);\n}\n\n/// Loads 32 bits / 4 bytes of data from the given @p data array in big-endian order.\ninline constexpr uint32_t load32be(const uint8_t* data) noexcept\n{\n    return (uint32_t{data[0]} << 24) | (uint32_t{data[1]} << 16) | (uint32_t{data[2]} << 8) |\n           uint32_t{data[3]};\n}\n\n/// Loads 32 bits / 4 bytes of data from the given @p data array in little-endian order.\ninline constexpr uint32_t load32le(const uint8_t* data) noexcept\n{\n    return uint32_t{data[0]} | (uint32_t{data[1]} << 8) | (uint32_t{data[2]} << 16) |\n           (uint32_t{data[3]} << 24);\n}\n\nnamespace fnv\n{\nconstexpr auto prime = 0x100000001b3;              ///< The 64-bit FNV prime number.\nconstexpr auto offset_basis = 0xcbf29ce484222325;  ///< The 64-bit FNV offset basis.\n\n/// The hashing transformation for 64-bit inputs based on the FNV-1a formula.\ninline constexpr uint64_t fnv1a_by64(uint64_t h, uint64_t x) noexcept\n{\n    return (h ^ x) * prime;\n}\n}  // namespace fnv\n\n\n/// The \"equal to\" comparison operator for the evmc::address type.\ninline constexpr bool operator==(const address& a, const address& b) noexcept\n{\n    return load64le(&a.bytes[0]) == load64le(&b.bytes[0]) &&\n           load64le(&a.bytes[8]) == load64le(&b.bytes[8]) &&\n           load32le(&a.bytes[16]) == load32le(&b.bytes[16]);\n}\n\n/// The \"not equal to\" comparison operator for the evmc::address type.\ninline constexpr bool operator!=(const address& a, const address& b) noexcept\n{\n    return !(a == b);\n}\n\n/// The \"less than\" comparison operator for the evmc::address type.\ninline constexpr bool operator<(const address& a, const address& b) noexcept\n{\n    return load64be(&a.bytes[0]) < load64be(&b.bytes[0]) ||\n           (load64be(&a.bytes[0]) == load64be(&b.bytes[0]) &&\n            (load64be(&a.bytes[8]) < load64be(&b.bytes[8]) ||\n             (load64be(&a.bytes[8]) == load64be(&b.bytes[8]) &&\n              load32be(&a.bytes[16]) < load32be(&b.bytes[16]))));\n}\n\n/// The \"greater than\" comparison operator for the evmc::address type.\ninline constexpr bool operator>(const address& a, const address& b) noexcept\n{\n    return b < a;\n}\n\n/// The \"less than or equal to\" comparison operator for the evmc::address type.\ninline constexpr bool operator<=(const address& a, const address& b) noexcept\n{\n    return !(b < a);\n}\n\n/// The \"greater than or equal to\" comparison operator for the evmc::address type.\ninline constexpr bool operator>=(const address& a, const address& b) noexcept\n{\n    return !(a < b);\n}\n\n/// The \"equal to\" comparison operator for the evmc::bytes32 type.\ninline constexpr bool operator==(const bytes32& a, const bytes32& b) noexcept\n{\n    return load64le(&a.bytes[0]) == load64le(&b.bytes[0]) &&\n           load64le(&a.bytes[8]) == load64le(&b.bytes[8]) &&\n           load64le(&a.bytes[16]) == load64le(&b.bytes[16]) &&\n           load64le(&a.bytes[24]) == load64le(&b.bytes[24]);\n}\n\n/// The \"not equal to\" comparison operator for the evmc::bytes32 type.\ninline constexpr bool operator!=(const bytes32& a, const bytes32& b) noexcept\n{\n    return !(a == b);\n}\n\n/// The \"less than\" comparison operator for the evmc::bytes32 type.\ninline constexpr bool operator<(const bytes32& a, const bytes32& b) noexcept\n{\n    return load64be(&a.bytes[0]) < load64be(&b.bytes[0]) ||\n           (load64be(&a.bytes[0]) == load64be(&b.bytes[0]) &&\n            (load64be(&a.bytes[8]) < load64be(&b.bytes[8]) ||\n             (load64be(&a.bytes[8]) == load64be(&b.bytes[8]) &&\n              (load64be(&a.bytes[16]) < load64be(&b.bytes[16]) ||\n               (load64be(&a.bytes[16]) == load64be(&b.bytes[16]) &&\n                load64be(&a.bytes[24]) < load64be(&b.bytes[24]))))));\n}\n\n/// The \"greater than\" comparison operator for the evmc::bytes32 type.\ninline constexpr bool operator>(const bytes32& a, const bytes32& b) noexcept\n{\n    return b < a;\n}\n\n/// The \"less than or equal to\" comparison operator for the evmc::bytes32 type.\ninline constexpr bool operator<=(const bytes32& a, const bytes32& b) noexcept\n{\n    return !(b < a);\n}\n\n/// The \"greater than or equal to\" comparison operator for the evmc::bytes32 type.\ninline constexpr bool operator>=(const bytes32& a, const bytes32& b) noexcept\n{\n    return !(a < b);\n}\n\n/// Checks if the given address is the zero address.\ninline constexpr bool is_zero(const address& a) noexcept\n{\n    return a == address{};\n}\n\ninline constexpr address::operator bool() const noexcept\n{\n    return !is_zero(*this);\n}\n\n/// Checks if the given bytes32 object has all zero bytes.\ninline constexpr bool is_zero(const bytes32& a) noexcept\n{\n    return a == bytes32{};\n}\n\ninline constexpr bytes32::operator bool() const noexcept\n{\n    return !is_zero(*this);\n}\n\nnamespace literals\n{\n/// Converts a raw literal into value of type T.\n///\n/// This function is expected to be used on literals in constexpr context only.\n/// In case the input is invalid the std::terminate() is called.\n/// TODO(c++20): Use consteval.\ntemplate <typename T>\nconstexpr T parse(std::string_view s) noexcept\n{\n    return from_hex<T>(s).value();\n}\n\n/// Literal for evmc::address.\nconstexpr address operator\"\"_address(const char* s) noexcept\n{\n    return parse<address>(s);\n}\n\n/// Literal for evmc::bytes32.\nconstexpr bytes32 operator\"\"_bytes32(const char* s) noexcept\n{\n    return parse<bytes32>(s);\n}\n}  // namespace literals\n\nusing namespace literals;\n\n\n/// @copydoc evmc_status_code_to_string\ninline const char* to_string(evmc_status_code status_code) noexcept\n{\n    return evmc_status_code_to_string(status_code);\n}\n\n/// @copydoc evmc_revision_to_string\ninline const char* to_string(evmc_revision rev) noexcept\n{\n    return evmc_revision_to_string(rev);\n}\n\n\n/// Alias for evmc_make_result().\nconstexpr auto make_result = evmc_make_result;\n\n/// @copydoc evmc_result\n///\n/// This is a RAII wrapper for evmc_result and objects of this type\n/// automatically release attached resources.\nclass Result : private evmc_result\n{\npublic:\n    using evmc_result::create_address;\n    using evmc_result::gas_left;\n    using evmc_result::gas_refund;\n    using evmc_result::output_data;\n    using evmc_result::output_size;\n    using evmc_result::status_code;\n\n    /// Creates the result from the provided arguments.\n    ///\n    /// The provided output is copied to memory allocated with malloc()\n    /// and the evmc_result::release function is set to one invoking free().\n    ///\n    /// @param _status_code  The status code.\n    /// @param _gas_left     The amount of gas left.\n    /// @param _gas_refund   The amount of refunded gas.\n    /// @param _output_data  The pointer to the output.\n    /// @param _output_size  The output size.\n    explicit Result(evmc_status_code _status_code,\n                    int64_t _gas_left,\n                    int64_t _gas_refund,\n                    const uint8_t* _output_data,\n                    size_t _output_size) noexcept\n      : evmc_result{make_result(_status_code, _gas_left, _gas_refund, _output_data, _output_size)}\n    {}\n\n    /// Creates the result without output.\n    ///\n    /// @param _status_code  The status code.\n    /// @param _gas_left     The amount of gas left.\n    /// @param _gas_refund   The amount of refunded gas.\n    explicit Result(evmc_status_code _status_code = EVMC_INTERNAL_ERROR,\n                    int64_t _gas_left = 0,\n                    int64_t _gas_refund = 0) noexcept\n      : evmc_result{make_result(_status_code, _gas_left, _gas_refund, nullptr, 0)}\n    {}\n\n    /// Creates the result of contract creation.\n    ///\n    /// @param _status_code     The status code.\n    /// @param _gas_left        The amount of gas left.\n    /// @param _gas_refund      The amount of refunded gas.\n    /// @param _create_address  The address of the possibly created account.\n    explicit Result(evmc_status_code _status_code,\n                    int64_t _gas_left,\n                    int64_t _gas_refund,\n                    const evmc_address& _create_address) noexcept\n      : evmc_result{make_result(_status_code, _gas_left, _gas_refund, nullptr, 0)}\n    {\n        create_address = _create_address;\n    }\n\n    /// Converting constructor from raw evmc_result.\n    ///\n    /// This object takes ownership of the resources of @p res.\n    explicit Result(const evmc_result& res) noexcept : evmc_result{res} {}\n\n    /// Destructor responsible for automatically releasing attached resources.\n    ~Result() noexcept\n    {\n        if (release != nullptr)\n            release(this);\n    }\n\n    /// Move constructor.\n    Result(Result&& other) noexcept : evmc_result{other}\n    {\n        other.release = nullptr;  // Disable releasing of the rvalue object.\n    }\n\n    /// Move assignment operator.\n    ///\n    /// The self-assignment MUST never happen.\n    ///\n    /// @param other The other result object.\n    /// @return      The reference to the left-hand side object.\n    Result& operator=(Result&& other) noexcept\n    {\n        this->~Result();                           // Release this object.\n        static_cast<evmc_result&>(*this) = other;  // Copy data.\n        other.release = nullptr;                   // Disable releasing of the rvalue object.\n        return *this;\n    }\n\n    /// Access the result object as a referenced to ::evmc_result.\n    evmc_result& raw() noexcept { return *this; }\n\n    /// Access the result object as a const referenced to ::evmc_result.\n    const evmc_result& raw() const noexcept { return *this; }\n\n    /// Releases the ownership and returns the raw copy of evmc_result.\n    ///\n    /// This method drops the ownership of the result\n    /// (result's resources are not going to be released when this object is destructed).\n    /// It is the caller's responsibility having the returned copy of the result to release it.\n    /// This object MUST NOT be used after this method is invoked.\n    ///\n    /// @return  The copy of this object converted to raw evmc_result.\n    evmc_result release_raw() noexcept\n    {\n        const auto out = evmc_result{*this};  // Copy data.\n        this->release = nullptr;              // Disable releasing of this object.\n        return out;\n    }\n};\n\n\n/// The EVMC Host interface\nclass HostInterface\n{\npublic:\n    virtual ~HostInterface() noexcept = default;\n\n    /// @copydoc evmc_host_interface::account_exists\n    virtual bool account_exists(const address& addr) const noexcept = 0;\n\n    /// @copydoc evmc_host_interface::get_storage\n    virtual bytes32 get_storage(const address& addr, const bytes32& key) const noexcept = 0;\n\n    /// @copydoc evmc_host_interface::set_storage\n    virtual evmc_storage_status set_storage(const address& addr,\n                                            const bytes32& key,\n                                            const bytes32& value) noexcept = 0;\n\n    /// @copydoc evmc_host_interface::get_balance\n    virtual uint256be get_balance(const address& addr) const noexcept = 0;\n\n    /// @copydoc evmc_host_interface::get_code_size\n    virtual size_t get_code_size(const address& addr) const noexcept = 0;\n\n    /// @copydoc evmc_host_interface::get_code_hash\n    virtual bytes32 get_code_hash(const address& addr) const noexcept = 0;\n\n    /// @copydoc evmc_host_interface::copy_code\n    virtual size_t copy_code(const address& addr,\n                             size_t code_offset,\n                             uint8_t* buffer_data,\n                             size_t buffer_size) const noexcept = 0;\n\n    /// @copydoc evmc_host_interface::selfdestruct\n    virtual bool selfdestruct(const address& addr, const address& beneficiary) noexcept = 0;\n\n    /// @copydoc evmc_host_interface::call\n    virtual Result call(const evmc_message& msg) noexcept = 0;\n\n    /// @copydoc evmc_host_interface::get_tx_context\n    virtual evmc_tx_context get_tx_context() const noexcept = 0;\n\n    /// @copydoc evmc_host_interface::get_block_hash\n    virtual bytes32 get_block_hash(int64_t block_number) const noexcept = 0;\n\n    /// @copydoc evmc_host_interface::emit_log\n    virtual void emit_log(const address& addr,\n                          const uint8_t* data,\n                          size_t data_size,\n                          const bytes32 topics[],\n                          size_t num_topics) noexcept = 0;\n\n    /// @copydoc evmc_host_interface::access_account\n    virtual evmc_access_status access_account(const address& addr) noexcept = 0;\n\n    /// @copydoc evmc_host_interface::access_storage\n    virtual evmc_access_status access_storage(const address& addr, const bytes32& key) noexcept = 0;\n\n    /// @copydoc evmc_host_interface::get_transient_storage\n    virtual bytes32 get_transient_storage(const address& addr,\n                                          const bytes32& key) const noexcept = 0;\n\n    /// @copydoc evmc_host_interface::set_transient_storage\n    virtual void set_transient_storage(const address& addr,\n                                       const bytes32& key,\n                                       const bytes32& value) noexcept = 0;\n};\n\n\n/// Wrapper around EVMC host context / host interface.\n///\n/// To be used by VM implementations as better alternative to using ::evmc_host_context directly.\nclass HostContext : public HostInterface\n{\n    const evmc_host_interface* host = nullptr;\n    evmc_host_context* context = nullptr;\n\npublic:\n    /// Default constructor for null Host context.\n    HostContext() = default;\n\n    /// Constructor from the EVMC Host primitives.\n    /// @param interface  The reference to the Host interface.\n    /// @param ctx        The pointer to the Host context object. This parameter MAY be null.\n    HostContext(const evmc_host_interface& interface, evmc_host_context* ctx) noexcept\n      : host{&interface}, context{ctx}\n    {}\n\n    bool account_exists(const address& address) const noexcept final\n    {\n        return host->account_exists(context, &address);\n    }\n\n    bytes32 get_storage(const address& address, const bytes32& key) const noexcept final\n    {\n        return host->get_storage(context, &address, &key);\n    }\n\n    evmc_storage_status set_storage(const address& address,\n                                    const bytes32& key,\n                                    const bytes32& value) noexcept final\n    {\n        return host->set_storage(context, &address, &key, &value);\n    }\n\n    uint256be get_balance(const address& address) const noexcept final\n    {\n        return host->get_balance(context, &address);\n    }\n\n    size_t get_code_size(const address& address) const noexcept final\n    {\n        return host->get_code_size(context, &address);\n    }\n\n    bytes32 get_code_hash(const address& address) const noexcept final\n    {\n        return host->get_code_hash(context, &address);\n    }\n\n    size_t copy_code(const address& address,\n                     size_t code_offset,\n                     uint8_t* buffer_data,\n                     size_t buffer_size) const noexcept final\n    {\n        return host->copy_code(context, &address, code_offset, buffer_data, buffer_size);\n    }\n\n    bool selfdestruct(const address& addr, const address& beneficiary) noexcept final\n    {\n        return host->selfdestruct(context, &addr, &beneficiary);\n    }\n\n    Result call(const evmc_message& message) noexcept final\n    {\n        return Result{host->call(context, &message)};\n    }\n\n    /// @copydoc HostInterface::get_tx_context()\n    evmc_tx_context get_tx_context() const noexcept final { return host->get_tx_context(context); }\n\n    bytes32 get_block_hash(int64_t number) const noexcept final\n    {\n        return host->get_block_hash(context, number);\n    }\n\n    void emit_log(const address& addr,\n                  const uint8_t* data,\n                  size_t data_size,\n                  const bytes32 topics[],\n                  size_t topics_count) noexcept final\n    {\n        host->emit_log(context, &addr, data, data_size, topics, topics_count);\n    }\n\n    evmc_access_status access_account(const address& address) noexcept final\n    {\n        return host->access_account(context, &address);\n    }\n\n    evmc_access_status access_storage(const address& address, const bytes32& key) noexcept final\n    {\n        return host->access_storage(context, &address, &key);\n    }\n\n    bytes32 get_transient_storage(const address& address, const bytes32& key) const noexcept final\n    {\n        return host->get_transient_storage(context, &address, &key);\n    }\n\n    void set_transient_storage(const address& address,\n                               const bytes32& key,\n                               const bytes32& value) noexcept final\n    {\n        host->set_transient_storage(context, &address, &key, &value);\n    }\n};\n\n\n/// Abstract class to be used by Host implementations.\n///\n/// When implementing EVMC Host, you can directly inherit from the evmc::Host class.\n/// This way your implementation will be simpler by avoiding manual handling\n/// of the ::evmc_host_context and the ::evmc_host_interface.\nclass Host : public HostInterface\n{\npublic:\n    /// Provides access to the global host interface.\n    /// @returns  Reference to the host interface object.\n    static const evmc_host_interface& get_interface() noexcept;\n\n    /// Converts the Host object to the opaque host context pointer.\n    /// @returns  Pointer to evmc_host_context.\n    evmc_host_context* to_context() noexcept { return reinterpret_cast<evmc_host_context*>(this); }\n\n    /// Converts the opaque host context pointer back to the original Host object.\n    /// @tparam DerivedClass  The class derived from the Host class.\n    /// @param context        The opaque host context pointer.\n    /// @returns              The pointer to DerivedClass.\n    template <typename DerivedClass = Host>\n    static DerivedClass* from_context(evmc_host_context* context) noexcept\n    {\n        // Get pointer of the Host base class.\n        auto* h = reinterpret_cast<Host*>(context);\n\n        // Additional downcast, only possible if DerivedClass inherits from Host.\n        return static_cast<DerivedClass*>(h);\n    }\n};\n\n\n/// @copybrief evmc_vm\n///\n/// This is a RAII wrapper for evmc_vm, and object of this type\n/// automatically destroys the VM instance.\nclass VM\n{\npublic:\n    VM() noexcept = default;\n\n    /// Converting constructor from evmc_vm.\n    explicit VM(evmc_vm* vm) noexcept : m_instance{vm} {}\n\n    /// Destructor responsible for automatically destroying the VM instance.\n    ~VM() noexcept\n    {\n        if (m_instance != nullptr)\n            m_instance->destroy(m_instance);\n    }\n\n    VM(const VM&) = delete;\n    VM& operator=(const VM&) = delete;\n\n    /// Move constructor.\n    VM(VM&& other) noexcept : m_instance{other.m_instance} { other.m_instance = nullptr; }\n\n    /// Move assignment operator.\n    VM& operator=(VM&& other) noexcept\n    {\n        this->~VM();\n        m_instance = other.m_instance;\n        other.m_instance = nullptr;\n        return *this;\n    }\n\n    /// The constructor that captures a VM instance and configures the instance\n    /// with the provided list of options.\n    inline VM(evmc_vm* vm,\n              std::initializer_list<std::pair<const char*, const char*>> options) noexcept;\n\n    /// Checks if contains a valid pointer to the VM instance.\n    explicit operator bool() const noexcept { return m_instance != nullptr; }\n\n    /// Checks whenever the VM instance is ABI compatible with the current EVMC API.\n    bool is_abi_compatible() const noexcept { return m_instance->abi_version == EVMC_ABI_VERSION; }\n\n    /// @copydoc evmc_vm::name\n    char const* name() const noexcept { return m_instance->name; }\n\n    /// @copydoc evmc_vm::version\n    char const* version() const noexcept { return m_instance->version; }\n\n    /// Checks if the VM has the given capability.\n    bool has_capability(evmc_capabilities capability) const noexcept\n    {\n        return (get_capabilities() & static_cast<evmc_capabilities_flagset>(capability)) != 0;\n    }\n\n    /// @copydoc evmc_vm::get_capabilities\n    evmc_capabilities_flagset get_capabilities() const noexcept\n    {\n        return m_instance->get_capabilities(m_instance);\n    }\n\n    /// @copydoc evmc_set_option()\n    evmc_set_option_result set_option(const char name[], const char value[]) noexcept\n    {\n        return evmc_set_option(m_instance, name, value);\n    }\n\n    /// @copydoc evmc_execute()\n    Result execute(const evmc_host_interface& host,\n                   evmc_host_context* ctx,\n                   evmc_revision rev,\n                   const evmc_message& msg,\n                   const uint8_t* code,\n                   size_t code_size) noexcept\n    {\n        return Result{m_instance->execute(m_instance, &host, ctx, rev, &msg, code, code_size)};\n    }\n\n    /// Convenient variant of the VM::execute() that takes reference to evmc::Host class.\n    Result execute(Host& host,\n                   evmc_revision rev,\n                   const evmc_message& msg,\n                   const uint8_t* code,\n                   size_t code_size) noexcept\n    {\n        return execute(Host::get_interface(), host.to_context(), rev, msg, code, code_size);\n    }\n\n    /// Executes code without the Host context.\n    ///\n    /// The same as\n    /// execute(const evmc_host_interface&, evmc_host_context*, evmc_revision,\n    ///         const evmc_message&, const uint8_t*, size_t),\n    /// but without providing the Host context and interface.\n    /// This method is for experimental precompiles support where execution is\n    /// guaranteed not to require any Host access.\n    Result execute(evmc_revision rev,\n                   const evmc_message& msg,\n                   const uint8_t* code,\n                   size_t code_size) noexcept\n    {\n        return Result{\n            m_instance->execute(m_instance, nullptr, nullptr, rev, &msg, code, code_size)};\n    }\n\n    /// Returns the pointer to C EVMC struct representing the VM.\n    ///\n    /// Gives access to the C EVMC VM struct to allow advanced interaction with the VM not supported\n    /// by the C++ interface. Use as the last resort.\n    /// This object still owns the VM after returning the pointer. The returned pointer MAY be null.\n    evmc_vm* get_raw_pointer() const noexcept { return m_instance; }\n\nprivate:\n    evmc_vm* m_instance = nullptr;\n};\n\ninline VM::VM(evmc_vm* vm,\n              std::initializer_list<std::pair<const char*, const char*>> options) noexcept\n  : m_instance{vm}\n{\n    // This constructor is implemented outside of the class definition to workaround a doxygen bug.\n    for (const auto& option : options)\n        set_option(option.first, option.second);\n}\n\n\nnamespace internal\n{\ninline bool account_exists(evmc_host_context* h, const evmc_address* addr) noexcept\n{\n    return Host::from_context(h)->account_exists(*addr);\n}\n\ninline evmc_bytes32 get_storage(evmc_host_context* h,\n                                const evmc_address* addr,\n                                const evmc_bytes32* key) noexcept\n{\n    return Host::from_context(h)->get_storage(*addr, *key);\n}\n\ninline evmc_storage_status set_storage(evmc_host_context* h,\n                                       const evmc_address* addr,\n                                       const evmc_bytes32* key,\n                                       const evmc_bytes32* value) noexcept\n{\n    return Host::from_context(h)->set_storage(*addr, *key, *value);\n}\n\ninline evmc_uint256be get_balance(evmc_host_context* h, const evmc_address* addr) noexcept\n{\n    return Host::from_context(h)->get_balance(*addr);\n}\n\ninline size_t get_code_size(evmc_host_context* h, const evmc_address* addr) noexcept\n{\n    return Host::from_context(h)->get_code_size(*addr);\n}\n\ninline evmc_bytes32 get_code_hash(evmc_host_context* h, const evmc_address* addr) noexcept\n{\n    return Host::from_context(h)->get_code_hash(*addr);\n}\n\ninline size_t copy_code(evmc_host_context* h,\n                        const evmc_address* addr,\n                        size_t code_offset,\n                        uint8_t* buffer_data,\n                        size_t buffer_size) noexcept\n{\n    return Host::from_context(h)->copy_code(*addr, code_offset, buffer_data, buffer_size);\n}\n\ninline bool selfdestruct(evmc_host_context* h,\n                         const evmc_address* addr,\n                         const evmc_address* beneficiary) noexcept\n{\n    return Host::from_context(h)->selfdestruct(*addr, *beneficiary);\n}\n\ninline evmc_result call(evmc_host_context* h, const evmc_message* msg) noexcept\n{\n    return Host::from_context(h)->call(*msg).release_raw();\n}\n\ninline evmc_tx_context get_tx_context(evmc_host_context* h) noexcept\n{\n    return Host::from_context(h)->get_tx_context();\n}\n\ninline evmc_bytes32 get_block_hash(evmc_host_context* h, int64_t block_number) noexcept\n{\n    return Host::from_context(h)->get_block_hash(block_number);\n}\n\ninline void emit_log(evmc_host_context* h,\n                     const evmc_address* addr,\n                     const uint8_t* data,\n                     size_t data_size,\n                     const evmc_bytes32 topics[],\n                     size_t num_topics) noexcept\n{\n    Host::from_context(h)->emit_log(*addr, data, data_size, static_cast<const bytes32*>(topics),\n                                    num_topics);\n}\n\ninline evmc_access_status access_account(evmc_host_context* h, const evmc_address* addr) noexcept\n{\n    return Host::from_context(h)->access_account(*addr);\n}\n\ninline evmc_access_status access_storage(evmc_host_context* h,\n                                         const evmc_address* addr,\n                                         const evmc_bytes32* key) noexcept\n{\n    return Host::from_context(h)->access_storage(*addr, *key);\n}\n\ninline evmc_bytes32 get_transient_storage(evmc_host_context* h,\n                                          const evmc_address* addr,\n                                          const evmc_bytes32* key) noexcept\n{\n    return Host::from_context(h)->get_transient_storage(*addr, *key);\n}\n\ninline void set_transient_storage(evmc_host_context* h,\n                                  const evmc_address* addr,\n                                  const evmc_bytes32* key,\n                                  const evmc_bytes32* value) noexcept\n{\n    Host::from_context(h)->set_transient_storage(*addr, *key, *value);\n}\n}  // namespace internal\n\ninline const evmc_host_interface& Host::get_interface() noexcept\n{\n    static constexpr evmc_host_interface interface = {\n        ::evmc::internal::account_exists,\n        ::evmc::internal::get_storage,\n        ::evmc::internal::set_storage,\n        ::evmc::internal::get_balance,\n        ::evmc::internal::get_code_size,\n        ::evmc::internal::get_code_hash,\n        ::evmc::internal::copy_code,\n        ::evmc::internal::selfdestruct,\n        ::evmc::internal::call,\n        ::evmc::internal::get_tx_context,\n        ::evmc::internal::get_block_hash,\n        ::evmc::internal::emit_log,\n        ::evmc::internal::access_account,\n        ::evmc::internal::access_storage,\n        ::evmc::internal::get_transient_storage,\n        ::evmc::internal::set_transient_storage,\n    };\n    return interface;\n}\n}  // namespace evmc\n\n\n/// \"Stream out\" operator implementation for ::evmc_status_code.\n///\n/// @note This is defined in global namespace to match ::evmc_status_code definition and allow\n///       convenient operator overloading usage.\ninline std::ostream& operator<<(std::ostream& os, evmc_status_code status_code)\n{\n    return os << evmc::to_string(status_code);\n}\n\n/// \"Stream out\" operator implementation for ::evmc_revision.\n///\n/// @note This is defined in global namespace to match ::evmc_revision definition and allow\n///       convenient operator overloading usage.\ninline std::ostream& operator<<(std::ostream& os, evmc_revision rev)\n{\n    return os << evmc::to_string(rev);\n}\n\nnamespace std\n{\n/// Hash operator template specialization for evmc::address. Needed for unordered containers.\ntemplate <>\nstruct hash<evmc::address>\n{\n    /// Hash operator using FNV1a-based folding.\n    constexpr size_t operator()(const evmc::address& s) const noexcept\n    {\n        using namespace evmc;\n        using namespace fnv;\n        return static_cast<size_t>(fnv1a_by64(\n            fnv1a_by64(fnv1a_by64(fnv::offset_basis, load64le(&s.bytes[0])), load64le(&s.bytes[8])),\n            load32le(&s.bytes[16])));\n    }\n};\n\n/// Hash operator template specialization for evmc::bytes32. Needed for unordered containers.\ntemplate <>\nstruct hash<evmc::bytes32>\n{\n    /// Hash operator using FNV1a-based folding.\n    constexpr size_t operator()(const evmc::bytes32& s) const noexcept\n    {\n        using namespace evmc;\n        using namespace fnv;\n        return static_cast<size_t>(\n            fnv1a_by64(fnv1a_by64(fnv1a_by64(fnv1a_by64(fnv::offset_basis, load64le(&s.bytes[0])),\n                                             load64le(&s.bytes[8])),\n                                  load64le(&s.bytes[16])),\n                       load64le(&s.bytes[24])));\n    }\n};\n}  // namespace std\n"
  },
  {
    "path": "test/evmc/filter_iterator.hpp",
    "content": "// EVMC: Ethereum Client-VM Connector API.\n// Copyright 2022 The EVMC Authors.\n// Licensed under the Apache License, Version 2.0.\n#pragma once\n\n#include <iterator>\n\nnamespace evmc\n{\n/// The constexpr variant of std::isspace().\ninline constexpr bool isspace(char ch) noexcept\n{\n    // Implementation taken from LLVM's libc.\n    return ch == ' ' || (static_cast<unsigned>(ch) - '\\t') < 5;\n}\n\n/// Checks if a character is not a white space.\ninline constexpr bool is_not_space(char ch) noexcept\n{\n    return !isspace(ch);\n}\n\n/// The filter iterator adaptor creates a view of an iterator range in which some elements of the\n/// range are skipped. A predicate function controls which elements are skipped. When the predicate\n/// is applied to an element, if it returns true then the element is retained and if it returns\n/// false then the element is skipped over. When skipping over elements, it is necessary for the\n/// filter adaptor to know when to stop so as to avoid going past the end of the underlying range.\n/// A filter iterator is therefore constructed with pair of iterators indicating the range of\n/// elements in the unfiltered sequence to be traversed.\n///\n/// Similar to boost::filter_iterator.\ntemplate <typename BaseIterator,\n          bool predicate(typename std::iterator_traits<BaseIterator>::value_type) noexcept>\nstruct filter_iterator\n{\n    /// The iterator difference type.\n    using difference_type = typename std::iterator_traits<BaseIterator>::difference_type;\n\n    /// The iterator value type.\n    using value_type = typename std::iterator_traits<BaseIterator>::value_type;\n\n    /// The iterator pointer type.\n    using pointer = typename std::iterator_traits<BaseIterator>::pointer;\n\n    /// The iterator reference type.\n    using reference = typename std::iterator_traits<BaseIterator>::reference;\n\n    /// The iterator category.\n    using iterator_category = std::input_iterator_tag;\n\nprivate:\n    BaseIterator base;\n    BaseIterator base_end;\n    value_type value;\n\n    constexpr void forward_to_next_value() noexcept\n    {\n        for (; base != base_end; ++base)\n        {\n            value = *base;\n            if (predicate(value))\n                break;\n        }\n    }\n\npublic:\n    /// The constructor of the base iterator pair.\n    constexpr filter_iterator(BaseIterator it, BaseIterator end) noexcept : base{it}, base_end{end}\n    {\n        forward_to_next_value();\n    }\n\n    /// The dereference operator.\n    constexpr auto operator*() noexcept\n    {\n        // We should not read from an input base iterator twice. So the only read is in\n        // forward_to_next_value() and here we return the cached value.\n        return value;\n    }\n\n    /// The increment operator.\n    constexpr void operator++() noexcept\n    {\n        ++base;\n        forward_to_next_value();\n    }\n\n    /// The equality operator.\n    constexpr bool operator==(const filter_iterator& o) const noexcept { return base == o.base; }\n\n    /// The inequality operator.\n    constexpr bool operator!=(const filter_iterator& o) const noexcept { return base != o.base; }\n};\n\n/// The input filter iterator which skips whitespace characters from the base input iterator.\ntemplate <typename BaseIterator>\nstruct skip_space_iterator : filter_iterator<BaseIterator, is_not_space>\n{\n    using filter_iterator<BaseIterator, is_not_space>::filter_iterator;\n};\n\n/// Class template argument deduction guide.\ntemplate <typename BaseIterator>\nskip_space_iterator(BaseIterator, BaseIterator) -> skip_space_iterator<BaseIterator>;\n}  // namespace evmc\n"
  },
  {
    "path": "test/evmc/helpers.h",
    "content": "// EVMC: Ethereum Client-VM Connector API.\n// Copyright 2018 The EVMC Authors.\n// Licensed under the Apache License, Version 2.0.\n\n/**\n * EVMC Helpers\n *\n * A collection of C helper functions for invoking a VM instance methods.\n * These are convenient for languages where invoking function pointers\n * is \"ugly\" or impossible (such as Go).\n *\n * @defgroup helpers EVMC Helpers\n * @{\n */\n#pragma once\n\n#include <evmc/evmc.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wold-style-cast\"\n#endif\n#endif\n\n/**\n * Returns true if the VM has a compatible ABI version.\n */\nstatic inline bool evmc_is_abi_compatible(struct evmc_vm* vm)\n{\n    return vm->abi_version == EVMC_ABI_VERSION;\n}\n\n/**\n * Returns the name of the VM.\n */\nstatic inline const char* evmc_vm_name(struct evmc_vm* vm)\n{\n    return vm->name;\n}\n\n/**\n * Returns the version of the VM.\n */\nstatic inline const char* evmc_vm_version(struct evmc_vm* vm)\n{\n    return vm->version;\n}\n\n/**\n * Checks if the VM has the given capability.\n *\n * @see evmc_get_capabilities_fn\n */\nstatic inline bool evmc_vm_has_capability(struct evmc_vm* vm, enum evmc_capabilities capability)\n{\n    return (vm->get_capabilities(vm) & (evmc_capabilities_flagset)capability) != 0;\n}\n\n/**\n * Destroys the VM instance.\n *\n * @see evmc_destroy_fn\n */\nstatic inline void evmc_destroy(struct evmc_vm* vm)\n{\n    vm->destroy(vm);\n}\n\n/**\n * Sets the option for the VM, if the feature is supported by the VM.\n *\n * @see evmc_set_option_fn\n */\nstatic inline enum evmc_set_option_result evmc_set_option(struct evmc_vm* vm,\n                                                          char const* name,\n                                                          char const* value)\n{\n    if (vm->set_option)\n        return vm->set_option(vm, name, value);\n    return EVMC_SET_OPTION_INVALID_NAME;\n}\n\n/**\n * Executes code in the VM instance.\n *\n * @see evmc_execute_fn.\n */\nstatic inline struct evmc_result evmc_execute(struct evmc_vm* vm,\n                                              const struct evmc_host_interface* host,\n                                              struct evmc_host_context* context,\n                                              enum evmc_revision rev,\n                                              const struct evmc_message* msg,\n                                              uint8_t const* code,\n                                              size_t code_size)\n{\n    return vm->execute(vm, host, context, rev, msg, code, code_size);\n}\n\n/// The evmc_result release function using free() for releasing the memory.\n///\n/// This function is used in the evmc_make_result(),\n/// but may be also used in other case if convenient.\n///\n/// @param result The result object.\nstatic void evmc_free_result_memory(const struct evmc_result* result)\n{\n    free((uint8_t*)result->output_data);\n}\n\n/// Creates the result from the provided arguments.\n///\n/// The provided output is copied to memory allocated with malloc()\n/// and the evmc_result::release function is set to one invoking free().\n///\n/// In case of memory allocation failure, the result has all fields zeroed\n/// and only evmc_result::status_code is set to ::EVMC_OUT_OF_MEMORY internal error.\n///\n/// @param status_code  The status code.\n/// @param gas_left     The amount of gas left.\n/// @param gas_refund   The amount of refunded gas.\n/// @param output_data  The pointer to the output.\n/// @param output_size  The output size.\nstatic inline struct evmc_result evmc_make_result(enum evmc_status_code status_code,\n                                                  int64_t gas_left,\n                                                  int64_t gas_refund,\n                                                  const uint8_t* output_data,\n                                                  size_t output_size)\n{\n    struct evmc_result result;\n    memset(&result, 0, sizeof(result));\n\n    if (output_size != 0)\n    {\n        uint8_t* buffer = (uint8_t*)malloc(output_size);\n\n        if (!buffer)\n        {\n            result.status_code = EVMC_OUT_OF_MEMORY;\n            return result;\n        }\n\n        memcpy(buffer, output_data, output_size);\n        result.output_data = buffer;\n        result.output_size = output_size;\n        result.release = evmc_free_result_memory;\n    }\n\n    result.status_code = status_code;\n    result.gas_left = gas_left;\n    result.gas_refund = gas_refund;\n    return result;\n}\n\n/**\n * Releases the resources allocated to the execution result.\n *\n * @param result  The result object to be released. MUST NOT be NULL.\n *\n * @see evmc_result::release() evmc_release_result_fn\n */\nstatic inline void evmc_release_result(struct evmc_result* result)\n{\n    if (result->release)\n        result->release(result);\n}\n\n\n/**\n * Helpers for optional storage of evmc_result.\n *\n * In some contexts (i.e. evmc_result::create_address is unused) objects of\n * type evmc_result contains a memory storage that MAY be used by the object\n * owner. This group defines helper types and functions for accessing\n * the optional storage.\n *\n * @defgroup result_optional_storage Result Optional Storage\n * @{\n */\n\n/**\n * The union representing evmc_result \"optional storage\".\n *\n * The evmc_result struct contains 24 bytes of optional storage that can be\n * reused by the object creator if the object does not contain\n * evmc_result::create_address.\n *\n * A VM implementation MAY use this memory to keep additional data\n * when returning result from evmc_execute_fn().\n * The host application MAY use this memory to keep additional data\n * when returning result of performed calls from evmc_call_fn().\n *\n * @see evmc_get_optional_storage(), evmc_get_const_optional_storage().\n */\nunion evmc_result_optional_storage\n{\n    uint8_t bytes[24]; /**< 24 bytes of optional storage. */\n    void* pointer;     /**< Optional pointer. */\n};\n\n/** Provides read-write access to evmc_result \"optional storage\". */\nstatic inline union evmc_result_optional_storage* evmc_get_optional_storage(\n    struct evmc_result* result)\n{\n    return (union evmc_result_optional_storage*)&result->create_address;\n}\n\n/** Provides read-only access to evmc_result \"optional storage\". */\nstatic inline const union evmc_result_optional_storage* evmc_get_const_optional_storage(\n    const struct evmc_result* result)\n{\n    return (const union evmc_result_optional_storage*)&result->create_address;\n}\n\n/** @} */\n\n/** Returns text representation of the ::evmc_status_code. */\nstatic inline const char* evmc_status_code_to_string(enum evmc_status_code status_code)\n{\n    switch (status_code)\n    {\n    case EVMC_SUCCESS:\n        return \"success\";\n    case EVMC_FAILURE:\n        return \"failure\";\n    case EVMC_REVERT:\n        return \"revert\";\n    case EVMC_OUT_OF_GAS:\n        return \"out of gas\";\n    case EVMC_INVALID_INSTRUCTION:\n        return \"invalid instruction\";\n    case EVMC_UNDEFINED_INSTRUCTION:\n        return \"undefined instruction\";\n    case EVMC_STACK_OVERFLOW:\n        return \"stack overflow\";\n    case EVMC_STACK_UNDERFLOW:\n        return \"stack underflow\";\n    case EVMC_BAD_JUMP_DESTINATION:\n        return \"bad jump destination\";\n    case EVMC_INVALID_MEMORY_ACCESS:\n        return \"invalid memory access\";\n    case EVMC_CALL_DEPTH_EXCEEDED:\n        return \"call depth exceeded\";\n    case EVMC_STATIC_MODE_VIOLATION:\n        return \"static mode violation\";\n    case EVMC_PRECOMPILE_FAILURE:\n        return \"precompile failure\";\n    case EVMC_CONTRACT_VALIDATION_FAILURE:\n        return \"contract validation failure\";\n    case EVMC_ARGUMENT_OUT_OF_RANGE:\n        return \"argument out of range\";\n    case EVMC_WASM_UNREACHABLE_INSTRUCTION:\n        return \"wasm unreachable instruction\";\n    case EVMC_WASM_TRAP:\n        return \"wasm trap\";\n    case EVMC_INSUFFICIENT_BALANCE:\n        return \"insufficient balance\";\n    case EVMC_INTERNAL_ERROR:\n        return \"internal error\";\n    case EVMC_REJECTED:\n        return \"rejected\";\n    case EVMC_OUT_OF_MEMORY:\n        return \"out of memory\";\n    }\n    return \"<unknown>\";\n}\n\n/** Returns the name of the ::evmc_revision. */\nstatic inline const char* evmc_revision_to_string(enum evmc_revision rev)\n{\n    switch (rev)\n    {\n    case EVMC_FRONTIER:\n        return \"Frontier\";\n    case EVMC_HOMESTEAD:\n        return \"Homestead\";\n    case EVMC_TANGERINE_WHISTLE:\n        return \"Tangerine Whistle\";\n    case EVMC_SPURIOUS_DRAGON:\n        return \"Spurious Dragon\";\n    case EVMC_BYZANTIUM:\n        return \"Byzantium\";\n    case EVMC_CONSTANTINOPLE:\n        return \"Constantinople\";\n    case EVMC_PETERSBURG:\n        return \"Petersburg\";\n    case EVMC_ISTANBUL:\n        return \"Istanbul\";\n    case EVMC_BERLIN:\n        return \"Berlin\";\n    case EVMC_LONDON:\n        return \"London\";\n    case EVMC_PARIS:\n        return \"Paris\";\n    case EVMC_SHANGHAI:\n        return \"Shanghai\";\n    case EVMC_CANCUN:\n        return \"Cancun\";\n    case EVMC_PRAGUE:\n        return \"Prague\";\n    case EVMC_OSAKA:\n        return \"Osaka\";\n    }\n    return \"<unknown>\";\n}\n\n/** @} */\n\n#ifdef __cplusplus\n#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif\n}  // extern \"C\"\n#endif\n"
  },
  {
    "path": "test/evmc/hex.hpp",
    "content": "// EVMC: Ethereum Client-VM Connector API.\n// Copyright 2021 The EVMC Authors.\n// Licensed under the Apache License, Version 2.0.\n#pragma once\n\n#include <evmc/bytes.hpp>\n#include <evmc/filter_iterator.hpp>\n#include <cstdint>\n#include <optional>\n#include <string>\n#include <string_view>\n\nnamespace evmc\n{\n/// Encode a byte to a hex string.\ninline std::string hex(uint8_t b) noexcept\n{\n    static constexpr auto hex_digits = \"0123456789abcdef\";\n    return {hex_digits[b >> 4], hex_digits[b & 0xf]};\n}\n\n/// Encodes bytes as hex string.\ninline std::string hex(bytes_view bs)\n{\n    std::string str;\n    str.reserve(bs.size() * 2);\n    for (const auto b : bs)\n        str += hex(b);\n    return str;\n}\n\nnamespace internal\n{\n/// Extracts the nibble value out of a hex digit.\n/// Returns -1 in case of invalid hex digit.\ninline constexpr int from_hex_digit(char h) noexcept\n{\n    if (h >= '0' && h <= '9')\n        return h - '0';\n    else if (h >= 'a' && h <= 'f')\n        return h - 'a' + 10;\n    else if (h >= 'A' && h <= 'F')\n        return h - 'A' + 10;\n    else\n        return -1;\n}\n}  // namespace internal\n\n/// Decodes hex-encoded sequence of characters.\n///\n/// It is guaranteed that the output will not be longer than half of the input length.\n///\n/// @param begin  The input begin iterator. It only must satisfy input iterator concept.\n/// @param end    The input end iterator. It only must satisfy input iterator concept.\n/// @param out    The output iterator. It must satisfy output iterator concept.\n/// @return       True if successful, false if input is invalid hex.\ntemplate <typename InputIt, typename OutputIt>\ninline constexpr bool from_hex(InputIt begin, InputIt end, OutputIt out) noexcept\n{\n    int hi_nibble = -1;  // Init with invalid value, should never be used.\n    size_t i = 0;\n    for (auto it = begin; it != end; ++it, ++i)\n    {\n        const auto h = *it;\n        const int v = evmc::internal::from_hex_digit(h);\n        if (v < 0)\n        {\n            if (i == 1 && hi_nibble == 0 && h == 'x')  // 0x prefix\n                continue;\n            return false;\n        }\n\n        if (i % 2 == 0)\n            hi_nibble = v << 4;\n        else\n            *out++ = static_cast<uint8_t>(hi_nibble | v);\n    }\n\n    return i % 2 == 0;\n}\n\n/// Validates hex encoded string.\n///\n/// @return  True if the input is valid hex.\ninline bool validate_hex(std::string_view hex) noexcept\n{\n    struct noop_output_iterator\n    {\n        uint8_t sink = {};\n        uint8_t& operator*() noexcept { return sink; }\n        noop_output_iterator operator++(int) noexcept { return *this; }  // NOLINT(cert-dcl21-cpp)\n    };\n\n    return from_hex(hex.begin(), hex.end(), noop_output_iterator{});\n}\n\n/// Decodes hex encoded string to bytes.\n///\n/// In case the input is invalid the returned value is std::nullopt.\n/// This can happen if a non-hex digit or odd number of digits is encountered.\ninline std::optional<bytes> from_hex(std::string_view hex)\n{\n    bytes bs;\n    bs.reserve(hex.size() / 2);\n    if (!from_hex(hex.begin(), hex.end(), std::back_inserter(bs)))\n        return {};\n    return bs;\n}\n\n/// Decodes hex-encoded string into custom type T with .bytes array of uint8_t.\n///\n/// When the input is smaller than the result type, the result is padded with zeros on the left\n/// (the result bytes of lowest indices are filled with zeros).\n/// TODO: Support optional left alignment.\ntemplate <typename T>\nconstexpr std::optional<T> from_hex(std::string_view s) noexcept\n{\n    // Omit the optional 0x prefix.\n    if (s.size() >= 2 && s[0] == '0' && s[1] == 'x')\n        s.remove_prefix(2);\n\n    T r{};  // The T must have .bytes array. This may be lifted if std::bit_cast is available.\n    constexpr auto num_out_bytes = std::size(r.bytes);\n    const auto num_in_bytes = s.length() / 2;\n    if (num_in_bytes > num_out_bytes)\n        return {};\n    if (!from_hex(s.begin(), s.end(), &r.bytes[num_out_bytes - num_in_bytes]))\n        return {};\n    return r;\n}\n\n/// Decodes hex encoded string to bytes. The whitespace in the input is ignored.\n///\n/// In case the input is invalid the returned value is std::nullopt.\n/// This can happen if a non-hex digit or odd number of digits is encountered.\n/// The whitespace (as defined by std::isspace) in the input is ignored.\ntemplate <typename InputIterator>\nstd::optional<bytes> from_spaced_hex(InputIterator begin, InputIterator end) noexcept\n{\n    bytes bs;\n    if (!from_hex(skip_space_iterator{begin, end}, skip_space_iterator{end, end},\n                  std::back_inserter(bs)))\n        return {};\n    return bs;\n}\n\n/// @copydoc from_spaced_hex\ninline std::optional<bytes> from_spaced_hex(std::string_view hex) noexcept\n{\n    return from_spaced_hex(hex.begin(), hex.end());\n}\n}  // namespace evmc\n"
  },
  {
    "path": "test/evmc/loader.c",
    "content": "// EVMC: Ethereum Client-VM Connector API.\n// Copyright 2018 The EVMC Authors.\n// Licensed under the Apache License, Version 2.0.\n\n#include <evmc/loader.h>\n\n#include <evmc/evmc.h>\n#include <evmc/helpers.h>\n\n#include <stdarg.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <string.h>\n\n#if defined(EVMC_LOADER_MOCK)\n#include \"../../test/unittests/loader_mock.h\"\n#elif defined(_WIN32)\n#include <Windows.h>\n#define DLL_HANDLE HMODULE\n#define DLL_OPEN(filename) LoadLibrary(filename)\n#define DLL_CLOSE(handle) FreeLibrary(handle)\n#define DLL_GET_CREATE_FN(handle, name) (evmc_create_fn)(uintptr_t) GetProcAddress(handle, name)\n#define DLL_GET_ERROR_MSG() NULL\n#else\n#include <dlfcn.h>\n#define DLL_HANDLE void*\n#define DLL_OPEN(filename) dlopen(filename, RTLD_LAZY)\n#define DLL_CLOSE(handle) dlclose(handle)\n// NOLINTNEXTLINE(performance-no-int-to-ptr)\n#define DLL_GET_CREATE_FN(handle, name) (evmc_create_fn)(uintptr_t) dlsym(handle, name)\n#define DLL_GET_ERROR_MSG() dlerror()\n#endif\n\n#ifdef __has_attribute\n#if __has_attribute(format)\n#define ATTR_FORMAT(archetype, string_index, first_to_check) \\\n    __attribute__((format(archetype, string_index, first_to_check)))\n#endif\n#endif\n\n#ifndef ATTR_FORMAT\n#define ATTR_FORMAT(...)\n#endif\n\n/*\n * Limited variant of strcpy_s().\n */\n#if !defined(EVMC_LOADER_MOCK)\nstatic\n#endif\n    int\n    strcpy_sx(char* dest, size_t destsz, const char* src)\n{\n    size_t len = strlen(src);\n    if (len >= destsz)\n    {\n        // The input src will not fit into the dest buffer.\n        // Set the first byte of the dest to null to make it effectively empty string\n        // and return error.\n        dest[0] = 0;\n        return 1;\n    }\n    // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)\n    memcpy(dest, src, len);\n    dest[len] = 0;\n    return 0;\n}\n\nenum\n{\n    PATH_MAX_LENGTH = 4096,\n    LAST_ERROR_MSG_BUFFER_SIZE = 511\n};\n\nstatic const char* last_error_msg = NULL;\n\n// Buffer for formatted error messages.\n// It has one null byte extra to avoid buffer read overflow during concurrent access.\nstatic char last_error_msg_buffer[LAST_ERROR_MSG_BUFFER_SIZE + 1];\n\nATTR_FORMAT(printf, 2, 3)\nstatic enum evmc_loader_error_code set_error(enum evmc_loader_error_code error_code,\n                                             const char* format,\n                                             ...)\n{\n    va_list args;\n    va_start(args, format);\n    // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)\n    if (vsnprintf(last_error_msg_buffer, LAST_ERROR_MSG_BUFFER_SIZE, format, args) <\n        LAST_ERROR_MSG_BUFFER_SIZE)\n        last_error_msg = last_error_msg_buffer;\n    va_end(args);\n    return error_code;\n}\n\n\nevmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* error_code)\n{\n    last_error_msg = NULL;  // Reset last error.\n    enum evmc_loader_error_code ec = EVMC_LOADER_SUCCESS;\n    evmc_create_fn create_fn = NULL;\n\n    if (!filename)\n    {\n        ec = set_error(EVMC_LOADER_INVALID_ARGUMENT, \"invalid argument: file name cannot be null\");\n        goto exit;\n    }\n\n    const size_t length = strlen(filename);\n    if (length == 0)\n    {\n        ec = set_error(EVMC_LOADER_INVALID_ARGUMENT, \"invalid argument: file name cannot be empty\");\n        goto exit;\n    }\n    else if (length > PATH_MAX_LENGTH)\n    {\n        ec = set_error(EVMC_LOADER_INVALID_ARGUMENT,\n                       \"invalid argument: file name is too long (%d, maximum allowed length is %d)\",\n                       (int)length, PATH_MAX_LENGTH);\n        goto exit;\n    }\n\n    DLL_HANDLE handle = DLL_OPEN(filename);\n    if (!handle)\n    {\n        // Get error message if available.\n        last_error_msg = DLL_GET_ERROR_MSG();\n        if (last_error_msg)\n            ec = EVMC_LOADER_CANNOT_OPEN;\n        else\n            ec = set_error(EVMC_LOADER_CANNOT_OPEN, \"cannot open %s\", filename);\n        goto exit;\n    }\n\n    // Create name buffer with the prefix.\n    const char prefix[] = \"evmc_create_\";\n    const size_t prefix_length = strlen(prefix);\n    char prefixed_name[sizeof(prefix) + PATH_MAX_LENGTH];\n    strcpy_sx(prefixed_name, sizeof(prefixed_name), prefix);\n\n    // Find filename in the path.\n    const char* sep_pos = strrchr(filename, '/');\n#ifdef _WIN32\n    // On Windows check also Windows classic path separator.\n    const char* sep_pos_windows = strrchr(filename, '\\\\');\n    sep_pos = sep_pos_windows > sep_pos ? sep_pos_windows : sep_pos;\n#endif\n    const char* name_pos = sep_pos ? sep_pos + 1 : filename;\n\n    // Skip \"lib\" prefix if present.\n    const char lib_prefix[] = \"lib\";\n    const size_t lib_prefix_length = strlen(lib_prefix);\n    if (strncmp(name_pos, lib_prefix, lib_prefix_length) == 0)\n        name_pos += lib_prefix_length;\n\n    char* base_name = prefixed_name + prefix_length;\n    strcpy_sx(base_name, PATH_MAX_LENGTH, name_pos);\n\n    // Trim all file extensions.\n    char* ext_pos = strchr(prefixed_name, '.');\n    if (ext_pos)\n        *ext_pos = 0;\n\n    // Replace all \"-\" with \"_\".\n    char* dash_pos = base_name;\n    while ((dash_pos = strchr(dash_pos, '-')) != NULL)\n        *dash_pos++ = '_';\n\n    // Search for the built function name.\n    create_fn = DLL_GET_CREATE_FN(handle, prefixed_name);\n\n    if (!create_fn)\n        create_fn = DLL_GET_CREATE_FN(handle, \"evmc_create\");\n\n    if (!create_fn)\n    {\n        DLL_CLOSE(handle);\n        ec = set_error(EVMC_LOADER_SYMBOL_NOT_FOUND, \"EVMC create function not found in %s\",\n                       filename);\n    }\n\nexit:\n    if (error_code)\n        *error_code = ec;\n    return create_fn;\n}\n\nconst char* evmc_last_error_msg(void)\n{\n    const char* m = last_error_msg;\n    last_error_msg = NULL;\n    return m;\n}\n\nstruct evmc_vm* evmc_load_and_create(const char* filename, enum evmc_loader_error_code* error_code)\n{\n    // First load the DLL. This also resets the last_error_msg;\n    evmc_create_fn create_fn = evmc_load(filename, error_code);\n\n    if (!create_fn)\n        return NULL;\n\n    enum evmc_loader_error_code ec = EVMC_LOADER_SUCCESS;\n\n    struct evmc_vm* vm = create_fn();\n    if (!vm)\n    {\n        ec = set_error(EVMC_LOADER_VM_CREATION_FAILURE, \"creating EVMC VM of %s has failed\",\n                       filename);\n        goto exit;\n    }\n\n    if (!evmc_is_abi_compatible(vm))\n    {\n        ec = set_error(EVMC_LOADER_ABI_VERSION_MISMATCH,\n                       \"EVMC ABI version %d of %s mismatches the expected version %d\",\n                       vm->abi_version, filename, EVMC_ABI_VERSION);\n        evmc_destroy(vm);\n        vm = NULL;\n        goto exit;\n    }\n\nexit:\n    if (error_code)\n        *error_code = ec;\n\n    return vm;\n}\n\n/// Gets the token delimited by @p delim character of the string pointed by the @p str_ptr.\n/// If the delimiter is not found, the whole string is returned.\n/// The @p str_ptr is also slided after the delimiter or to the string end\n/// if the delimiter is not found (in this case the @p str_ptr points to an empty string).\nstatic char* get_token(char** str_ptr, char delim)\n{\n    char* str = *str_ptr;\n    char* delim_pos = strchr(str, delim);\n    if (delim_pos)\n    {\n        // If the delimiter is found, null it to get null-terminated prefix\n        // and slide the str_ptr after the delimiter.\n        *delim_pos = '\\0';\n        *str_ptr = delim_pos + 1;\n    }\n    else\n    {\n        // Otherwise, slide the str_ptr to the end and return the whole string as the prefix.\n        *str_ptr += strlen(str);\n    }\n    return str;\n}\n\nstruct evmc_vm* evmc_load_and_configure(const char* config, enum evmc_loader_error_code* error_code)\n{\n    enum evmc_loader_error_code ec = EVMC_LOADER_SUCCESS;\n    struct evmc_vm* vm = NULL;\n\n    char config_copy_buffer[PATH_MAX_LENGTH];\n    if (strcpy_sx(config_copy_buffer, sizeof(config_copy_buffer), config) != 0)\n    {\n        ec = set_error(EVMC_LOADER_INVALID_ARGUMENT,\n                       \"invalid argument: configuration is too long (maximum allowed length is %d)\",\n                       (int)sizeof(config_copy_buffer));\n        goto exit;\n    }\n\n    char* options = config_copy_buffer;\n    const char* path = get_token(&options, ',');\n\n    vm = evmc_load_and_create(path, error_code);\n    if (!vm)\n        return NULL;\n\n    while (strlen(options) != 0)\n    {\n        if (vm->set_option == NULL)\n        {\n            ec = set_error(EVMC_LOADER_INVALID_OPTION_NAME, \"%s (%s) does not support any options\",\n                           vm->name, path);\n            goto exit;\n        }\n\n        char* option = get_token(&options, ',');\n\n        // Slit option into name and value by taking the name token.\n        // The option variable will have the value, can be empty.\n        const char* name = get_token(&option, '=');\n\n        enum evmc_set_option_result r = vm->set_option(vm, name, option);\n        switch (r)\n        {\n        case EVMC_SET_OPTION_SUCCESS:\n            break;\n        case EVMC_SET_OPTION_INVALID_NAME:\n            ec = set_error(EVMC_LOADER_INVALID_OPTION_NAME, \"%s (%s): unknown option '%s'\",\n                           vm->name, path, name);\n            goto exit;\n        case EVMC_SET_OPTION_INVALID_VALUE:\n            ec = set_error(EVMC_LOADER_INVALID_OPTION_VALUE,\n                           \"%s (%s): unsupported value '%s' for option '%s'\", vm->name, path,\n                           option, name);\n            goto exit;\n\n        default:\n            ec = set_error(EVMC_LOADER_INVALID_OPTION_VALUE,\n                           \"%s (%s): unknown error when setting value '%s' for option '%s'\",\n                           vm->name, path, option, name);\n            goto exit;\n        }\n    }\n\nexit:\n    if (error_code)\n        *error_code = ec;\n\n    if (ec == EVMC_LOADER_SUCCESS)\n        return vm;\n\n    if (vm)\n        evmc_destroy(vm);\n    return NULL;\n}\n"
  },
  {
    "path": "test/evmc/loader.h",
    "content": "// EVMC: Ethereum Client-VM Connector API.\n// Copyright 2018 The EVMC Authors.\n// Licensed under the Apache License, Version 2.0.\n\n/**\n * EVMC Loader Library\n *\n * The EVMC Loader Library supports loading VMs implemented as Dynamically Loaded Libraries\n * (DLLs, shared objects).\n *\n * @defgroup loader EVMC Loader\n * @{\n */\n#pragma once\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** The function pointer type for EVMC create functions. */\ntypedef struct evmc_vm* (*evmc_create_fn)(void);\n\n/// Error codes for the EVMC loader.\n///\n/// Objects of this type SHOULD be initialized with ::EVMC_LOADER_UNSPECIFIED_ERROR\n/// before passing to the EVMC loader.\nenum evmc_loader_error_code\n{\n    /** The loader succeeded. */\n    EVMC_LOADER_SUCCESS = 0,\n\n    /** The loader cannot open the given file name. */\n    EVMC_LOADER_CANNOT_OPEN = 1,\n\n    /** The VM create function not found. */\n    EVMC_LOADER_SYMBOL_NOT_FOUND = 2,\n\n    /** The invalid argument value provided. */\n    EVMC_LOADER_INVALID_ARGUMENT = 3,\n\n    /** The creation of a VM instance has failed. */\n    EVMC_LOADER_VM_CREATION_FAILURE = 4,\n\n    /** The ABI version of the VM instance has mismatched. */\n    EVMC_LOADER_ABI_VERSION_MISMATCH = 5,\n\n    /** The VM option is invalid. */\n    EVMC_LOADER_INVALID_OPTION_NAME = 6,\n\n    /** The VM option value is invalid. */\n    EVMC_LOADER_INVALID_OPTION_VALUE = 7,\n\n    /// This error value will be never returned by the EVMC loader,\n    /// but can be used by users to init evmc_loader_error_code objects.\n    EVMC_LOADER_UNSPECIFIED_ERROR = -1\n};\n\n/**\n * Dynamically loads the EVMC module with a VM implementation.\n *\n * This function tries to open a dynamically loaded library (DLL) at the given `filename`.\n * On UNIX-like systems dlopen() function is used. On Windows LoadLibrary() function is used.\n *\n * If the file does not exist or is not a valid shared library the ::EVMC_LOADER_CANNOT_OPEN error\n * code is signaled and NULL is returned.\n *\n * After the DLL is successfully loaded the function tries to find the EVM create function in the\n * library. The `filename` is used to guess the EVM name and the name of the create function.\n * The create function name is constructed by the following rules. Consider example path:\n * \"/ethereum/libexample-interpreter.so.1.0\".\n * - the filename is taken from the path:\n *   \"libexample-interpreter.so.1.0\",\n * - the \"lib\" prefix and all file extensions are stripped from the name:\n *   \"example-interpreter\"\n * - all \"-\" are replaced with \"_\" to construct _base name_:\n *   \"example_interpreter\",\n * - the function name \"evmc_create_\" + _base name_ is searched in the library:\n *   \"evmc_create_example_interpreter\",\n * - if the function is not found, the function name \"evmc_create\" is searched in the library.\n *\n * If the create function is found in the library, the pointer to the function is returned.\n * Otherwise, the ::EVMC_LOADER_SYMBOL_NOT_FOUND error code is signaled and NULL is returned.\n *\n * It is safe to call this function with the same filename argument multiple times\n * (the DLL is not going to be loaded multiple times).\n *\n * @param filename    The null terminated path (absolute or relative) to an EVMC module\n *                    (dynamically loaded library) containing the VM implementation.\n *                    If the value is NULL, an empty C-string or longer than the path maximum length\n *                    the ::EVMC_LOADER_INVALID_ARGUMENT is signaled.\n * @param error_code  The pointer to the error code. If not NULL the value is set to\n *                    ::EVMC_LOADER_SUCCESS on success or any other error code as described above.\n * @return            The pointer to the EVM create function or NULL in case of error.\n */\nevmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* error_code);\n\n/**\n * Dynamically loads the EVMC module and creates the VM instance.\n *\n * This is a macro for creating the VM instance with the function returned from evmc_load().\n * The function signals the same errors as evmc_load() and additionally:\n * - ::EVMC_LOADER_VM_CREATION_FAILURE when the create function returns NULL,\n * - ::EVMC_LOADER_ABI_VERSION_MISMATCH when the created VM instance has ABI version different\n *   from the ABI version of this library (::EVMC_ABI_VERSION).\n *\n * It is safe to call this function with the same filename argument multiple times:\n * the DLL is not going to be loaded multiple times, but the function will return new VM instance\n * each time.\n *\n * @param filename    The null terminated path (absolute or relative) to an EVMC module\n *                    (dynamically loaded library) containing the VM implementation.\n *                    If the value is NULL, an empty C-string or longer than the path maximum length\n *                    the ::EVMC_LOADER_INVALID_ARGUMENT is signaled.\n * @param error_code  The pointer to the error code. If not NULL the value is set to\n *                    ::EVMC_LOADER_SUCCESS on success or any other error code as described above.\n * @return            The pointer to the created VM or NULL in case of error.\n */\nstruct evmc_vm* evmc_load_and_create(const char* filename, enum evmc_loader_error_code* error_code);\n\n/**\n * Dynamically loads the EVMC module, then creates and configures the VM instance.\n *\n * This function performs the following actions atomically:\n * - loads the EVMC module (as evmc_load()),\n * - creates the VM instance,\n * - configures the VM instance with options provided in the @p config parameter.\n *\n * The configuration string (@p config) has the following syntax:\n *\n *     <path> (\",\" <option-name> [\"=\" <option-value>])*\n *\n * In this syntax, an option without a value can be specified (`,option,`)\n * as a shortcut for using empty value (`,option=,`).\n *\n * Options are passed to a VM in the order they are specified in the configuration string.\n * It is up to the VM implementation how to handle duplicated options and other conflicts.\n *\n * Example configuration string:\n *\n *     ./modules/vm.so,engine=compiler,trace,verbosity=2\n *\n * The function signals the same errors as evmc_load_and_create() and additionally:\n * - ::EVMC_LOADER_INVALID_OPTION_NAME\n *   when the provided options list contains an option unknown for the VM,\n * - ::EVMC_LOADER_INVALID_OPTION_VALUE\n *   when there exists unsupported value for a given VM option.\n\n *\n * @param config      The path to the EVMC module with additional configuration options.\n * @param error_code  The pointer to the error code. If not NULL the value is set to\n *                    ::EVMC_LOADER_SUCCESS on success or any other error code as described above.\n * @return            The pointer to the created VM or NULL in case of error.\n */\nstruct evmc_vm* evmc_load_and_configure(const char* config,\n                                        enum evmc_loader_error_code* error_code);\n\n/**\n * Returns the human-readable message describing the most recent error\n * that occurred in EVMC loading since the last call to this function.\n *\n * In case any loading function returned ::EVMC_LOADER_SUCCESS this function always returns NULL.\n * In case of error code other than success returned, this function MAY return the error message.\n * Calling this function \"consumes\" the error message and the function will return NULL\n * from subsequent invocations.\n * This function is not thread-safe.\n *\n * @return Error message or NULL if no additional information is available.\n *         The returned pointer MUST NOT be freed by the caller.\n */\nconst char* evmc_last_error_msg(void);\n\n#ifdef __cplusplus\n}\n#endif\n\n/** @} */\n"
  },
  {
    "path": "test/evmc/mocked_host.hpp",
    "content": "// EVMC: Ethereum Client-VM Connector API.\n// Copyright 2019 The EVMC Authors.\n// Licensed under the Apache License, Version 2.0.\n#pragma once\n\n#include <evmc/evmc.hpp>\n#include <algorithm>\n#include <cassert>\n#include <string>\n#include <map>\n#include <unordered_map>\n#include <vector>\n\nnamespace evmc\n{\n/// Extended value (with original value and access flag) for account storage.\nstruct StorageValue\n{\n    /// The current storage value.\n    bytes32 current;\n\n    /// The original storage value.\n    bytes32 original;\n\n    /// Is the storage key cold or warm.\n    evmc_access_status access_status = EVMC_ACCESS_COLD;\n\n    /// Default constructor.\n    StorageValue() noexcept = default;\n\n    /// Constructor sets the current and original to the same value. Optional access status.\n    StorageValue(const bytes32& _value,  // NOLINT(hicpp-explicit-conversions)\n                 evmc_access_status _access_status = EVMC_ACCESS_COLD) noexcept\n      : current{_value}, original{_value}, access_status{_access_status}\n    {}\n\n    /// Constructor with original value and optional access status\n    StorageValue(const bytes32& _value,\n                 const bytes32& _original,\n                 evmc_access_status _access_status = EVMC_ACCESS_COLD) noexcept\n      : current{_value}, original{_original}, access_status{_access_status}\n    {}\n};\n\n/// Mocked account.\nstruct MockedAccount\n{\n    /// The account nonce.\n    int nonce = 0;\n\n    /// The account code.\n    bytes code;\n\n    /// The code hash. Can be a value not related to the actual code.\n    bytes32 codehash;\n\n    /// The account balance.\n    uint256be balance;\n\n    /// The account storage map.\n    std::map<bytes32, StorageValue> storage;\n\n    /// The account transient storage.\n    std::unordered_map<bytes32, bytes32> transient_storage;\n\n    /// Helper method for setting balance by numeric type.\n    void set_balance(uint64_t x) noexcept\n    {\n        balance = uint256be{};\n        for (std::size_t i = 0; i < sizeof(x); ++i)\n            balance.bytes[sizeof(balance) - 1 - i] = static_cast<uint8_t>(x >> (8 * i));\n    }\n};\n\n/// Mocked EVMC Host implementation.\nclass MockedHost : public Host\n{\npublic:\n    /// LOG record.\n    struct log_record\n    {\n        /// The address of the account which created the log.\n        address creator;\n\n        /// The data attached to the log.\n        bytes data;\n\n        /// The log topics.\n        std::vector<bytes32> topics;\n\n        /// Equal operator.\n        bool operator==(const log_record& other) const noexcept\n        {\n            return creator == other.creator && data == other.data && topics == other.topics;\n        }\n    };\n\n    /// The set of all accounts in the Host, organized by their addresses.\n    std::unordered_map<address, MockedAccount> accounts;\n\n    /// The EVMC transaction context to be returned by get_tx_context().\n    evmc_tx_context tx_context = {};\n\n    /// The block header hash value to be returned by get_block_hash().\n    bytes32 block_hash = {};\n\n    /// The call result to be returned by the call() method.\n    evmc_result call_result = {};\n\n    /// The record of all block numbers for which get_block_hash() was called.\n    mutable std::vector<int64_t> recorded_blockhashes;\n\n    /// The record of all account accesses.\n    mutable std::vector<address> recorded_account_accesses;\n\n    /// The maximum number of entries in recorded_account_accesses record.\n    /// This is arbitrary value useful in fuzzing when we don't want the record to explode.\n    static constexpr auto max_recorded_account_accesses = 200;\n\n    /// The record of all call messages requested in the call() method.\n    std::vector<evmc_message> recorded_calls;\n\n    /// The maximum number of entries in recorded_calls record.\n    /// This is arbitrary value useful in fuzzing when we don't want the record to explode.\n    static constexpr auto max_recorded_calls = 100;\n\n    /// The record of all LOGs passed to the emit_log() method.\n    std::vector<log_record> recorded_logs;\n\n    /// The record of all SELFDESTRUCTs from the selfdestruct() method\n    /// as a map selfdestructed_address => [beneficiary1, beneficiary2, ...].\n    std::unordered_map<address, std::vector<address>> recorded_selfdestructs;\n\nprivate:\n    /// The copy of call inputs for the recorded_calls record.\n    std::vector<bytes> m_recorded_calls_inputs;\n\n    /// Record an account access.\n    /// @param addr  The address of the accessed account.\n    void record_account_access(const address& addr) const\n    {\n        if (recorded_account_accesses.empty())\n            recorded_account_accesses.reserve(max_recorded_account_accesses);\n\n        if (recorded_account_accesses.size() < max_recorded_account_accesses)\n            recorded_account_accesses.emplace_back(addr);\n    }\n\npublic:\n    /// Returns true if an account exists (EVMC Host method).\n    bool account_exists(const address& addr) const noexcept override\n    {\n        record_account_access(addr);\n        return accounts.count(addr) != 0;\n    }\n\n    /// Get the account's storage value at the given key (EVMC Host method).\n    bytes32 get_storage(const address& addr, const bytes32& key) const noexcept override\n    {\n        record_account_access(addr);\n\n        const auto account_iter = accounts.find(addr);\n        if (account_iter == accounts.end())\n            return {};\n\n        const auto storage_iter = account_iter->second.storage.find(key);\n        if (storage_iter != account_iter->second.storage.end())\n            return storage_iter->second.current;\n        return {};\n    }\n\n    /// Set the account's storage value (EVMC Host method).\n    evmc_storage_status set_storage(const address& addr,\n                                    const bytes32& key,\n                                    const bytes32& value) noexcept override\n    {\n        record_account_access(addr);\n\n        // Get the reference to the storage entry value.\n        // This will create the account in case it was not present.\n        // This is convenient for unit testing and standalone EVM execution to preserve the\n        // storage values after the execution terminates.\n        auto& s = accounts[addr].storage[key];\n\n        // Follow the EIP-2200 specification as closely as possible.\n        // https://eips.ethereum.org/EIPS/eip-2200\n        // Warning: this is not the most efficient implementation. The storage status can be\n        // figured out by combining only 4 checks:\n        // - original != current (dirty)\n        // - original == value (restored)\n        // - current != 0\n        // - value != 0\n        const auto status = [&original = s.original, &current = s.current, &value]() {\n            // Clause 1 is irrelevant:\n            // 1. \"If gasleft is less than or equal to gas stipend,\n            //    fail the current call frame with ‘out of gas’ exception\"\n\n            // 2. \"If current value equals new value (this is a no-op)\"\n            if (current == value)\n            {\n                // \"SLOAD_GAS is deducted\"\n                return EVMC_STORAGE_ASSIGNED;\n            }\n            // 3. \"If current value does not equal new value\"\n            else\n            {\n                // 3.1. \"If original value equals current value\n                //      (this storage slot has not been changed by the current execution context)\"\n                if (original == current)\n                {\n                    // 3.1.1 \"If original value is 0\"\n                    if (is_zero(original))\n                    {\n                        // \"SSTORE_SET_GAS is deducted\"\n                        return EVMC_STORAGE_ADDED;\n                    }\n                    // 3.1.2 \"Otherwise\"\n                    else\n                    {\n                        // \"SSTORE_RESET_GAS gas is deducted\"\n                        auto st = EVMC_STORAGE_MODIFIED;\n\n                        // \"If new value is 0\"\n                        if (is_zero(value))\n                        {\n                            // \"add SSTORE_CLEARS_SCHEDULE gas to refund counter\"\n                            st = EVMC_STORAGE_DELETED;\n                        }\n\n                        return st;\n                    }\n                }\n                // 3.2. \"If original value does not equal current value\n                //      (this storage slot is dirty),\n                //      SLOAD_GAS gas is deducted.\n                //      Apply both of the following clauses.\"\n                else\n                {\n                    // Because we need to apply \"both following clauses\"\n                    // we first collect information which clause is triggered\n                    // then assign status code to combination of these clauses.\n                    enum\n                    {\n                        None = 0,\n                        RemoveClearsSchedule = 1 << 0,\n                        AddClearsSchedule = 1 << 1,\n                        RestoredBySet = 1 << 2,\n                        RestoredByReset = 1 << 3,\n                    };\n                    int triggered_clauses = None;\n\n                    // 3.2.1. \"If original value is not 0\"\n                    if (!is_zero(original))\n                    {\n                        // 3.2.1.1. \"If current value is 0\"\n                        if (is_zero(current))\n                        {\n                            // \"(also means that new value is not 0)\"\n                            assert(!is_zero(value));\n                            // \"remove SSTORE_CLEARS_SCHEDULE gas from refund counter\"\n                            triggered_clauses |= RemoveClearsSchedule;\n                        }\n                        // 3.2.1.2. \"If new value is 0\"\n                        if (is_zero(value))\n                        {\n                            // \"(also means that current value is not 0)\"\n                            assert(!is_zero(current));\n                            // \"add SSTORE_CLEARS_SCHEDULE gas to refund counter\"\n                            triggered_clauses |= AddClearsSchedule;\n                        }\n                    }\n\n                    // 3.2.2. \"If original value equals new value (this storage slot is reset)\"\n                    // Except: we use term 'storage slot restored'.\n                    if (original == value)\n                    {\n                        // 3.2.2.1. \"If original value is 0\"\n                        if (is_zero(original))\n                        {\n                            // \"add SSTORE_SET_GAS - SLOAD_GAS to refund counter\"\n                            triggered_clauses |= RestoredBySet;\n                        }\n                        // 3.2.2.2. \"Otherwise\"\n                        else\n                        {\n                            // \"add SSTORE_RESET_GAS - SLOAD_GAS gas to refund counter\"\n                            triggered_clauses |= RestoredByReset;\n                        }\n                    }\n\n                    switch (triggered_clauses)\n                    {\n                    case RemoveClearsSchedule:\n                        return EVMC_STORAGE_DELETED_ADDED;\n                    case AddClearsSchedule:\n                        return EVMC_STORAGE_MODIFIED_DELETED;\n                    case RemoveClearsSchedule | RestoredByReset:\n                        return EVMC_STORAGE_DELETED_RESTORED;\n                    case RestoredBySet:\n                        return EVMC_STORAGE_ADDED_DELETED;\n                    case RestoredByReset:\n                        return EVMC_STORAGE_MODIFIED_RESTORED;\n                    case None:\n                        return EVMC_STORAGE_ASSIGNED;\n                    default:\n                        assert(false);  // Other combinations are impossible.\n                        return evmc_storage_status{};\n                    }\n                }\n            }\n        }();\n\n        s.current = value;  // Finally update the current storage value.\n        return status;\n    }\n\n    /// Get the account's balance (EVMC Host method).\n    uint256be get_balance(const address& addr) const noexcept override\n    {\n        record_account_access(addr);\n        const auto it = accounts.find(addr);\n        if (it == accounts.end())\n            return {};\n\n        return it->second.balance;\n    }\n\n    /// Get the account's code size (EVMC host method).\n    size_t get_code_size(const address& addr) const noexcept override\n    {\n        record_account_access(addr);\n        const auto it = accounts.find(addr);\n        if (it == accounts.end())\n            return 0;\n        return it->second.code.size();\n    }\n\n    /// Get the account's code hash (EVMC host method).\n    bytes32 get_code_hash(const address& addr) const noexcept override\n    {\n        record_account_access(addr);\n        const auto it = accounts.find(addr);\n        if (it == accounts.end())\n            return {};\n        return it->second.codehash;\n    }\n\n    /// Copy the account's code to the given buffer (EVMC host method).\n    size_t copy_code(const address& addr,\n                     size_t code_offset,\n                     uint8_t* buffer_data,\n                     size_t buffer_size) const noexcept override\n    {\n        record_account_access(addr);\n        const auto it = accounts.find(addr);\n        if (it == accounts.end())\n            return 0;\n\n        const auto& code = it->second.code;\n\n        if (code_offset >= code.size())\n            return 0;\n\n        const auto n = std::min(buffer_size, code.size() - code_offset);\n\n        if (n > 0)\n            std::copy_n(&code[code_offset], n, buffer_data);\n        return n;\n    }\n\n    /// Selfdestruct the account (EVMC host method).\n    bool selfdestruct(const address& addr, const address& beneficiary) noexcept override\n    {\n        record_account_access(addr);\n        auto& beneficiaries = recorded_selfdestructs[addr];\n        beneficiaries.emplace_back(beneficiary);\n        return beneficiaries.size() == 1;\n    }\n\n    /// Call/create other contract (EVMC host method).\n    Result call(const evmc_message& msg) noexcept override\n    {\n        record_account_access(msg.recipient);\n\n        if (recorded_calls.empty())\n        {\n            recorded_calls.reserve(max_recorded_calls);\n            m_recorded_calls_inputs.reserve(max_recorded_calls);  // Iterators will not invalidate.\n        }\n\n        if (recorded_calls.size() < max_recorded_calls)\n        {\n            recorded_calls.emplace_back(msg);\n            auto& call_msg = recorded_calls.back();\n            if (call_msg.input_size > 0)\n            {\n                m_recorded_calls_inputs.emplace_back(call_msg.input_data, call_msg.input_size);\n                const auto& input_copy = m_recorded_calls_inputs.back();\n                call_msg.input_data = input_copy.data();\n            }\n        }\n        return Result{call_result};\n    }\n\n    /// Get transaction context (EVMC host method).\n    evmc_tx_context get_tx_context() const noexcept override { return tx_context; }\n\n    /// Get the block header hash (EVMC host method).\n    bytes32 get_block_hash(int64_t block_number) const noexcept override\n    {\n        recorded_blockhashes.emplace_back(block_number);\n        return block_hash;\n    }\n\n    /// Emit LOG (EVMC host method).\n    void emit_log(const address& addr,\n                  const uint8_t* data,\n                  size_t data_size,\n                  const bytes32 topics[],\n                  size_t topics_count) noexcept override\n    {\n        recorded_logs.push_back({addr, {data, data_size}, {topics, topics + topics_count}});\n    }\n\n    /// Record an account access.\n    ///\n    /// This method is required by EIP-2929 introduced in ::EVMC_BERLIN. It will record the account\n    /// access in MockedHost::recorded_account_accesses and return previous access status.\n    /// This methods returns ::EVMC_ACCESS_WARM for known addresses of precompiles.\n    /// The EIP-2929 specifies that evmc_message::sender and evmc_message::recipient are always\n    /// ::EVMC_ACCESS_WARM. Therefore, you should init the MockedHost with:\n    ///\n    ///     mocked_host.access_account(msg.sender);\n    ///     mocked_host.access_account(msg.recipient);\n    ///\n    /// The same way you can mock transaction access list (EIP-2930) for account addresses.\n    ///\n    /// @param addr  The address of the accessed account.\n    /// @returns     The ::EVMC_ACCESS_WARM if the account has been accessed before,\n    ///              the ::EVMC_ACCESS_COLD otherwise.\n    evmc_access_status access_account(const address& addr) noexcept override\n    {\n        // Check if the address have been already accessed.\n        const auto already_accessed =\n            std::find(recorded_account_accesses.begin(), recorded_account_accesses.end(), addr) !=\n            recorded_account_accesses.end();\n\n        record_account_access(addr);\n\n        // Accessing precompiled contracts is always warm.\n        if (addr >= 0x0000000000000000000000000000000000000001_address &&\n            addr <= 0x0000000000000000000000000000000000000009_address)\n            return EVMC_ACCESS_WARM;\n\n        return already_accessed ? EVMC_ACCESS_WARM : EVMC_ACCESS_COLD;\n    }\n\n    /// Access the account's storage value at the given key.\n    ///\n    /// This method is required by EIP-2929 introduced in ::EVMC_BERLIN. In records\n    /// that the given account's storage key has been access and returns the\n    /// previous access status. To mock storage access list (EIP-2930), you can\n    /// pre-init account's storage values with the ::EVMC_ACCESS_WARM flag:\n    ///\n    ///     mocked_host.accounts[msg.recipient].storage[key] = {value,\n    ///     EVMC_ACCESS_WARM};\n    ///\n    /// @param addr  The account address.\n    /// @param key   The account's storage key.\n    /// @return      The ::EVMC_ACCESS_WARM if the storage key has been accessed before,\n    ///              the ::EVMC_ACCESS_COLD otherwise.\n    evmc_access_status access_storage(const address& addr, const bytes32& key) noexcept override\n    {\n        auto& value = accounts[addr].storage[key];\n        const auto access_status = value.access_status;\n        value.access_status = EVMC_ACCESS_WARM;\n        return access_status;\n    }\n\n    /// Get account's transient storage.\n    ///\n    /// @param addr  The account address.\n    /// @param key   The account's transient storage key.\n    /// @return      The transient storage value. Null value in case the account does not exist.\n    bytes32 get_transient_storage(const address& addr, const bytes32& key) const noexcept override\n    {\n        record_account_access(addr);\n\n        const auto account_iter = accounts.find(addr);\n        if (account_iter == accounts.end())\n            return {};\n\n        const auto storage_iter = account_iter->second.transient_storage.find(key);\n        if (storage_iter != account_iter->second.transient_storage.end())\n            return storage_iter->second;\n        return {};\n    }\n\n    /// Set account's transient storage.\n    ///\n    /// @param addr   The account address.\n    /// @param key    The account's transient storage key.\n    /// @param value  The value to be stored.\n    void set_transient_storage(const address& addr,\n                               const bytes32& key,\n                               const bytes32& value) noexcept override\n    {\n        record_account_access(addr);\n        accounts[addr].transient_storage[key] = value;\n    }\n};\n}  // namespace evmc\n"
  },
  {
    "path": "test/evmc/utils.h",
    "content": "// EVMC: Ethereum Client-VM Connector API.\n// Copyright 2018 The EVMC Authors.\n// Licensed under the Apache License, Version 2.0.\n\n#pragma once\n\n/**\n * @file\n * A collection of helper macros to handle some non-portable features of C/C++ compilers.\n *\n * @addtogroup helpers\n * @{\n */\n\n/**\n * @def EVMC_EXPORT\n * Marks a function to be exported from a shared library.\n */\n#if defined _MSC_VER || defined __MINGW32__\n#define EVMC_EXPORT __declspec(dllexport)\n#else\n#define EVMC_EXPORT __attribute__((visibility(\"default\")))\n#endif\n\n/**\n * @def EVMC_NOEXCEPT\n * Safe way of marking a function with `noexcept` C++ specifier.\n */\n#ifdef __cplusplus\n#define EVMC_NOEXCEPT noexcept\n#else\n#define EVMC_NOEXCEPT\n#endif\n\n/** @} */\n"
  },
  {
    "path": "test/externalTests/README.md",
    "content": "## Solidity external tests\nThis directory contains scripts for compiling some of the popular open-source projects using the\ncurrent version of the compiler and running their test suites.\n\nSince projects often do not use the latest compiler, we keep a fork of each of these projects\nat https://github.com/solidity-external-tests/. If changes are needed to make a project work with the\nlatest version of the compiler, they are maintained as a branch on top of the upstream master branch.\nThis is especially important for testing our `breaking` branch because we can not realistically expect\nexternal projects to be instantly compatible with a compiler version that has not been released yet.\nApplying necessary changes ourselves gives us confidence that breaking changes are sane and that\nthese projects *can* be upgraded at all.\n\n### Recommended workflow\n\n#### Adding a new external project\n1. If the upstream code cannot be compiled without modifications, create a fork of the repository\n   in https://github.com/solidity-external-tests/.\n2. In our fork, remove all the branches except for the main one (`master`, `develop`, `main`, etc).\n    This branch is going to be always kept up to date with the upstream repository and should not\n    contain any extra commits.\n    - If the project is not up to date with the latest compiler version but has a branch that is,\n        try to use that branch instead.\n3. In our fork, create a new branch named after the main branch and the compiler version from our\n `develop` branch.\n     E.g. if the latest Solidity version is 0.7.5 and the main branch of the external project\n     is called `master`, create `master_070`. This is where we will be adding our own commits.\n4. Create a script for compiling/testing the project and put it in `test/externalTests/` in the\n    Solidity repository.\n    - The script should apply workarounds necessary to make the project actually use the compiler\n        binary it receives as a parameter and possibly add generic workarounds that should\n        work across different versions of the upstream project.\n    - Very specific workarounds that may easily break with every upstream change are better done as\n        commits in the newly added branch in the fork instead.\n5. List the script in `test/externalTests.sh`.\n6. Add the script to CircleCI configuration. Make sure to add both a compilation-only run and one that\n    also executes the test suite. If the latter takes a significant amount of time (say, more than\n    15 minutes) make it run nightly rather than on every PR.\n7. Make sure that tests pass both on `develop` and on `breaking`. If the compiler from `breaking`\n    branch will not work without additional changes, add another branch, called after it in turn,\n    and add necessary workarounds there. Continuing the example above, the new branch would be\n    called `master_080` and should be rebased on top of `master_070`.\n    - The fewer commits in these branches, the better. Ideally, any changes needed to make the compiler\n        work should be submitted upstream and our scripts should be using the upstream repository\n        directly.\n\n#### Updating external projects for a PR that introduces breaking changes in the compiler\nIf a PR to our `breaking` branch introduces changes that will make an external project no longer\ncompile or pass its tests, the fork needs to be modified (or created if it does not yet exist):\n- If a branch specific to the compiler version from `breaking` does not exist yet:\n    1. Create the branch. It should be based on the version-specific branch used on `develop`.\n    2. Make your PR modify the project script in `test/externalScripts/` to use the new branch.\n    3. You are free to add any changes you need in the new branch since it will not interfere with\n        tests on `breaking`.\n    4. Work on your PR until it is approved and merged into `breaking`.\n- If the branch already exists and our CI depends on it:\n    1. If the external project after your changes can still work with `breaking` even without your PR or\n        if you know that the PR is straightforward and will be merged immediately without interfering\n        with tests on `breaking` for a significant amount of time, you can just push your modifications\n        to the branch directly and skip straight to steps 4. and 6.\n    2. Create a PR in the fork, targeting the existing version-specific branch.\n    3. In your PR to `breaking`, modify the corresponding script in `test/externalScripts/` to\n        use the branch from your PR in the fork.\n    4. Work on your PR until it is approved and ready to merge.\n    5. Merge the PR in the fork.\n    6. Discard your changes to the script and merge your PR into `breaking`.\n\n#### Pulling upstream changes into a fork\n1. Pull changes directly into the main branch in the fork. This should be straightforward thanks to\n    it not containing any of our customizations.\n2. If the project has been updated to a newer Solidity version, abandon the current version-specific\n    branch used on `develop` (but do not delete it) and create a new one corresponding to the newer\n    version. Then update project script in `test/externalTests/` to use the new branch. E.g. if `develop` uses\n    `master_050` and the project has been updated to use Solidity 0.7.3, create `master_070`.\n3. Otherwise, rebase the current version-specific branch on the main branch of the fork. This may require\n    tweaking some of the commits to apply our fixes in new places.\n4. If we have a separate branch for `breaking`, rebase it on top of the one used on `develop`.\n\nThe above is the workflow to use when the update is straightforward and looks safe. In that case it is\nfine to just modify the branches directly. If this is not the case, it is recommended to first perform the\noperation on copies of these version-specific branches and test them by creating PRs on `develop` and\n`breaking` to see if tests pass. The PRs should just modify project scripts in `test/externalScripts/`\nto use the updated copies of the branches and can be discarded afterwards without being merged.\n\n#### Changes needed after a breaking release of the compiler\nWhen a non-backwards-compatible version becomes the most recent release, `breaking` branch\ngets merged into `develop` which automatically results in a switch to the newer version-specific\nbranches if they exist. If no changes on our part were necessary, it is completely fine to keep using\ne.g. the `master_060` of an external project in Solidity 0.8.x.\n\nSince each project is handled separately, this approach may result in a mix of version-specific branches\nbetween different external projects. For example, in one project we could have `master_050` on\nboth `develop` and `breaking` and in another `breaking` could use `master_080` while `develop` still\nuses `master_060`.\n"
  },
  {
    "path": "test/externalTests/bleeps.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2022 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { npm run compile; }\n# NOTE: `npm run test` runs `mocha` which seems to disable the gas reporter.\nfunction test_fn { HARDHAT_DEPLOY_FIXTURE=true npx --no hardhat --no-compile test; }\n\nfunction bleeps_test\n{\n    local repo=\"https://github.com/wighawag/bleeps\"\n    local ref=main\n    local config_file=\"hardhat.config.ts\"\n    local config_var=config\n\n    local compile_only_presets=()\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        #ir-no-optimize            # Compilation fails with: \"YulException: Variable expr_15509_mpos is 4 too deep in the stack\". No memoryguard was present.\n        #ir-optimize-evm-only      # Compilation fails with: \"YulException: Variable expr_15260_mpos is 4 too deep in the stack\". No memoryguard was present.\n        #ir-optimize-evm+yul       # Compilation fails with: \"YulException: Variable expr_15208_mpos is 1 too deep in the stack\". No memoryguard was present.\n        #legacy-no-optimize        # Compilation fails with: \"CompilerError: Stack too deep, try removing local variables.\"\n        #legacy-optimize-evm-only  # Compilation fails with: \"CompilerError: Stack too deep, try removing local variables.\"\n        legacy-optimize-evm+yul\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n\n    pushd \"common-lib/\"\n    neutralize_package_json_hooks\n    npm install\n    npm run build\n    popd\n\n    pushd \"contracts/\"\n    sed -i 's|\"bleeps-common\": \"workspace:\\*\",|\"bleeps-common\": \"file:../common-lib/\",|g' package.json\n\n    sed -i 's/function() public/fallback() external/g' src/externals/WETH9.sol\n    sed -i 's/this\\.balance/address(this).balance/g' src/externals/WETH9.sol\n    sed -i 's/uint(-1)/type(uint).max/g' src/externals/WETH9.sol\n    sed -i 's/msg\\.sender\\.transfer(/payable(msg.sender).transfer(/g' src/externals/WETH9.sol\n    sed -i 's/^\\s*\\(Deposit\\|Withdrawal\\|Approval\\|Transfer\\)(/emit \\1(/g' src/externals/WETH9.sol\n\n    # This test does not currently pass due to an upstream problem.\n    # TODO: Remove this line when https://github.com/wighawag/bleeps/issues/2 is fixed\n    rm test/BleepsDAO.governor.test.ts\n\n    neutralize_package_lock\n    neutralize_package_json_hooks\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\" \"$config_var\"\n    npm install npm-run-all\n    npm install\n\n    # Causes a test failure with hardhat 2.11.0 (latest at the moment of writing this)\n    # TODO: Remove when https://github.com/wighawag/bleeps/issues/4 is resolved\n    npm install hardhat@2.10.2\n\n    # TODO: Bleeps depends on OpenZeppelin 4.3.2, which is affected by\n    # https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3293.\n    # Forcing OZ >= 4.6.0 fixes this but it also causes a lot of unrelated compilation errors.\n    # Remove this when Bleeps gets updated to support newer OpenZeppelin.\n    perl -i -0pe \\\n        \"s/(function hashProposal\\(\\n        address\\[\\] )calldata( targets,\\n        uint256\\[\\] )calldata( values,\\n        bytes\\[\\] )calldata( calldatas,)/\\1memory\\2memory\\3memory\\4/g\" \\\n        node_modules/@openzeppelin/contracts/governance/IGovernor.sol\n\n    replace_version_pragmas\n\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn \"$config_var\"\n        store_benchmark_report hardhat bleeps \"$repo\" \"$preset\"\n    done\n\n    popd\n}\n\nexternal_test Bleeps bleeps_test\n"
  },
  {
    "path": "test/externalTests/brink.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2022 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { yarn hardhat-compile; }\nfunction test_fn { SNAPSHOT_UPDATE=1 npx --no hardhat test; }\n\nfunction brink_test\n{\n    local repo=\"https://github.com/brinktrade/brink-core\"\n    local ref=\"<latest-release>\"\n    local config_file=\"hardhat.config.js\"\n    local config_var=\"\"\n    local extra_settings=\"metadata: {bytecodeHash: 'none'}\"\n    local extra_optimizer_settings=\"runs: 800\"\n\n    local compile_only_presets=(\n        ir-no-optimize             # Lots of test failures. Tests depend on constants.js, which seems to be calculated specifically for 0.8.10.\n        ir-optimize-evm-only       # Lots of test failures. Tests depend on constants.js, which seems to be calculated specifically for 0.8.10.\n        ir-optimize-evm+yul        # Lots of test failures. Tests depend on constants.js, which seems to be calculated specifically for 0.8.10.\n        legacy-optimize-evm+yul    # Lots of test failures. Tests depend on constants.js, which seems to be calculated specifically for 0.8.10.\n        legacy-no-optimize         # Lots of test failures. Tests depend on constants.js, which seems to be calculated specifically for 0.8.10.\n        legacy-optimize-evm-only   # Lots of test failures. Tests depend on constants.js, which seems to be calculated specifically for 0.8.10.\n    )\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n\n    # TODO: Remove this once Brink merges PR #52 (https://github.com/brinktrade/brink-core/pull/52).\n    sed -i \"s|\\(function isValidSignature(bytes \\)calldata\\( _data, bytes \\)calldata\\( _signature)\\)|\\1memory\\2memory\\3|g\" src/Test/MockEIP1271Validator.sol\n\n    neutralize_package_lock\n    neutralize_package_json_hooks\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\" \"$config_var\" \"$CURRENT_EVM_VERSION\" \"$extra_settings\" \"$extra_optimizer_settings\"\n    pnpm install\n    pnpm install hardhat-gas-reporter\n\n    replace_version_pragmas\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn \"$config_var\" \"$extra_settings\" \"$extra_optimizer_settings\"\n        store_benchmark_report hardhat brink \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test Brink brink_test\n"
  },
  {
    "path": "test/externalTests/chainlink.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2022 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { yarn compile; }\nfunction test_fn { yarn test; }\n\nfunction chainlink_test\n{\n    local repo=\"https://github.com/solidity-external-tests/chainlink\"\n    local ref=develop_080\n    local config_file=\"hardhat.config.ts\"\n    local config_var=config\n\n    local compile_only_presets=(\n        legacy-no-optimize        # Tests crash on a machine with 8 GB of RAM in CI \"FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory\"\n    )\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        #ir-no-optimize           # Compilation fails with \"YulException: Variable expr_10724_mpos is 2 too deep in the stack\". No memoryguard was present.\n        #ir-optimize-evm-only     # Compilation fails with \"YulException: Variable expr_1891_mpos is 2 too deep in the stack\". No memoryguard was present.\n        ir-optimize-evm+yul\n        legacy-optimize-evm-only  # NOTE: This requires >= 4 GB RAM in CI not to crash\n        legacy-optimize-evm+yul   # NOTE: This requires >= 4 GB RAM in CI not to crash\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n\n    cd \"contracts/\"\n\n    # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables\n    # them for other presets but that's fine - we want same code run for benchmarks to be comparable.\n    # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365).\n    sed -i \"s|\\(it\\)\\(('reverts'\\)|\\1.skip\\2|g\" test/v0.6/BasicConsumer.test.ts\n    sed -i \"s|\\(it\\)\\(('has a reasonable gas cost \\[ @skip-coverage \\]'\\)|\\1.skip\\2|g\" test/v0.6/BasicConsumer.test.ts\n    sed -i \"s|\\(describe\\)\\(('#add[^']*'\\)|\\1.skip\\2|g\" test/v0.6/Chainlink.test.ts\n    sed -i \"s|\\(it\\)\\(('throws'\\)|\\1.skip\\2|g\" test/v0.6/SignedSafeMath.test.ts\n    sed -i \"s|\\(it\\)\\(('reverts when not enough LINK in the contract'\\)|\\1.skip\\2|g\" test/v0.*/VRFD20.test.ts\n    sed -i \"s|\\(it\\)\\(('errors while parsing invalid cron strings'\\)|\\1.skip\\2|g\" test/v0.8/Cron.test.ts\n    sed -i \"s|\\(it\\)\\(('reverts if the amount passed in data mismatches actual amount sent'\\)|\\1.skip\\2|g\" test/v0.8/KeeperRegistrar.test.ts\n    sed -i \"s|\\(it\\)\\(('reverts if the sender passed in data mismatches actual sender'\\)|\\1.skip\\2|g\" test/v0.8/KeeperRegistrar.test.ts\n    sed -i \"s|\\(it\\)\\(('reverts if the admin address is 0x0000...'\\)|\\1.skip\\2|g\" test/v0.8/KeeperRegistrar.test.ts\n    sed -i \"s|\\(it\\)\\(('reverts if not called with more or less than 32 bytes'\\)|\\1.skip\\2|g\" test/v0.8/KeeperRegistry.test.ts\n    sed -i \"s|\\(context\\)\\(('when permissions are not set'\\)|\\1.skip\\2|g\" test/v0.8/KeeperRegistry.test.ts\n\n    # In some cases Hardhat does not detect revert reasons properly via IR.\n    # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed.\n    sed -i \"s|\\(it\\)\\(('does not allow the specified address to start new rounds'\\)|\\1.skip\\2|g\" test/v0.6/FluxAggregator.test.ts\n    sed -i \"s|\\(describe\\)\\(('when called by a stranger'\\)|\\1.skip\\2|g\" test/v0.6/FluxAggregator.test.ts\n    sed -i \"s|\\(describe\\)\\(('if the access control is turned on'\\)|\\1.skip\\2|g\" test/v0.*/Flags.test.ts\n    sed -i \"s|\\(it\\)\\(('respects the access controls of #getFlag'\\)|\\1.skip\\2|g\" test/v0.*/Flags.test.ts\n    sed -i \"s|\\(describe\\)\\(('setting 0 authorized senders'\\)|\\1.skip\\2|g\" test/v0.7/AuthorizedForwarder.test.ts\n    sed -i \"s|\\(it\\)\\(('cannot add an authorized node'\\)|\\1.skip\\2|g\" test/v0.7/AuthorizedForwarder.test.ts\n    sed -i \"s|\\(it\\)\\(('should disallow reads on AggregatorV2V3Interface functions when consuming contract is not whitelisted'\\)|\\1.skip\\2|g\" test/v0.8/dev/ArbitrumSequencerUptimeFeed.test.ts\n    sed -i \"s|\\(it\\)\\(('should not be callable by non-owners'\\)|\\1.skip\\2|g\" test/v0.8/dev/CrossDomainOwnable.test.ts\n    sed -i \"s|\\(it\\)\\(('should not be callable by non pending-owners'\\)|\\1.skip\\2|g\" test/v0.8/dev/CrossDomainOwnable.test.ts\n    sed -i \"s|\\(it\\)\\(('cannot add a consumer to a nonexistent subscription'\\)|\\1.skip\\2|g\" test/v0.8/dev/VRFCoordinatorV2Mock.test.ts\n    sed -i \"s|\\(it\\)\\(('cannot remove a consumer from a nonexistent subscription'\\)|\\1.skip\\2|g\" test/v0.8/dev/VRFCoordinatorV2Mock.test.ts\n    sed -i \"s|\\(it\\)\\(('cannot remove a consumer after it is already removed'\\)|\\1.skip\\2|g\" test/v0.8/dev/VRFCoordinatorV2Mock.test.ts\n    sed -i \"s|\\(it\\)\\(('fails to fulfill without being a valid consumer'\\)|\\1.skip\\2|g\" test/v0.8/dev/VRFCoordinatorV2Mock.test.ts\n    # TODO: check why these two are needed due to this PR.\n    sed -i \"s|\\(it\\)\\(('cannot fund a nonexistent subscription'\\)|\\1.skip\\2|g\" test/v0.8/dev/VRFCoordinatorV2Mock.test.ts\n    sed -i \"s|\\(it\\)\\(('can cancel a subscription'\\)|\\1.skip\\2|g\" test/v0.8/dev/VRFCoordinatorV2Mock.test.ts\n\n\n    # Disable tests with hard-coded gas expectations.\n    sed -i \"s|\\(it\\)\\(('not use too much gas \\[ @skip-coverage \\]'\\)|\\1.skip\\2|g\" test/v0.6/FluxAggregator.test.ts\n    sed -i \"s|\\(it\\)\\(('has a large enough gas overhead to cover upkeeps that use all their gas \\[ @skip-coverage \\]'\\)|\\1.skip\\2|g\" test/v0.*/KeeperRegistry*.test.ts\n    sed -i \"s|\\(it\\)\\(('only pays .\\+'\\)|\\1.skip\\2|g\" test/v0.*/KeeperRegistry*.test.ts\n    sed -i \"s|\\(it\\)\\(('uses a specific amount of gas \\[ @skip-coverage \\]'\\)|\\1.skip\\2|g\" test/v0.8/ValidatorProxy.test.ts\n    sed -i \"s|\\(describe\\)\\(('Gas costs'\\)|\\1.skip\\2|g\" test/v0.8/dev/ArbitrumSequencerUptimeFeed.test.ts\n\n    neutralize_package_lock\n    neutralize_package_json_hooks\n    name_hardhat_default_export \"$config_file\" \"$config_var\"\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\" \"$config_var\"\n    force_hardhat_unlimited_contract_size \"$config_file\" \"$config_var\"\n    yarn install\n    yarn add hardhat-gas-reporter\n\n    replace_version_pragmas\n\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn \"$config_var\"\n        store_benchmark_report hardhat chainlink \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test Chainlink chainlink_test\n"
  },
  {
    "path": "test/externalTests/colony.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2019 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { yarn run provision:token:contracts; }\nfunction test_fn { yarn run test:contracts; }\n\nfunction colony_test\n{\n    local repo=\"https://github.com/solidity-external-tests/colonyNetwork.git\"\n    local ref=\"develop_080\"\n    local config_file=\"truffle.js\"\n\n    local compile_only_presets=(\n        ir-no-optimize            # Compiles but tests run out of gas\n        ir-optimize-evm-only      # Compiles but tests run out of gas\n        legacy-no-optimize        # Compiles but tests run out of gas\n        legacy-optimize-evm-only  # Compiles but tests run out of gas\n    )\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        ir-optimize-evm+yul\n        legacy-optimize-evm+yul\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n    [[ $BINARY_TYPE == native ]] && replace_global_solc \"$BINARY_PATH\"\n\n    neutralize_package_json_hooks\n    force_truffle_compiler_settings \"$config_file\" \"$BINARY_TYPE\" \"${DIR}/solc/dist\" \"$(first_word \"$SELECTED_PRESETS\")\"\n    yarn install\n    git submodule update --init\n\n    cd lib\n    rm -Rf dappsys\n    git clone https://github.com/solidity-external-tests/dappsys-monolithic.git -b master_080 dappsys\n    cd ..\n\n    replace_version_pragmas\n    [[ $BINARY_TYPE == solcjs ]] && force_solc_modules \"${DIR}/solc/dist\"\n\n    for preset in $SELECTED_PRESETS; do\n        truffle_run_test \"$config_file\" \"$BINARY_TYPE\" \"${DIR}/solc/dist\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn\n        store_benchmark_report truffle colony \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test ColonyNetworks colony_test\n"
  },
  {
    "path": "test/externalTests/elementfi.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2022 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { npm run build; }\nfunction test_fn { npm run test; }\n\nfunction elementfi_test\n{\n    local repo=\"https://github.com/element-fi/elf-contracts\"\n    local ref=\"<latest-release>\"\n    local config_file=\"hardhat.config.ts\"\n    local config_var=config\n\n    local compile_only_presets=(\n        # ElementFi's test suite is hard-coded for Mainnet forked via alchemy.io.\n        # Locally we can only compile.\n        ir-no-optimize\n        ir-optimize-evm-only\n        ir-optimize-evm+yul\n        legacy-no-optimize\n        legacy-optimize-evm-only\n        legacy-optimize-evm+yul\n    )\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n\n    chmod +x scripts/load-balancer-contracts.sh\n    scripts/load-balancer-contracts.sh\n\n    # Balancer contracts require 0.7.x. Patch them for 0.8.x.\n    pushd contracts/balancer-core-v2\n    sed -i 's|uint256(address(this))|uint256(uint160(address(this)))|g' test/MockPoolFactory.sol\n    sed -i 's|uint256(address(this))|uint256(uint160(address(this)))|g' vault/ProtocolFeesCollector.sol\n    sed -i 's|uint256(address(this))|uint256(uint160(address(this)))|g' vault/VaultAuthorization.sol\n    sed -i 's|msg\\.sender\\.sendValue(excess)|payable(msg.sender).sendValue(excess)|g' vault/AssetTransfersHandler.sol\n    sed -i 's|msg\\.sender\\.transfer(wad)|payable(msg.sender).transfer(wad)|g' test/WETH.sol\n    sed -i 's|int256(-amountsOut\\[i\\])|-int256(amountsOut[i])|g' test/MockVault.sol\n    sed -i 's|int256(-amount)|-int256(amount)|g' vault/AssetManagers.sol\n    sed -i 's|uint256(-1)|type(uint256).max|g' pools/BalancerPoolToken.sol\n    sed -i 's|uint256(-1)|type(uint256).max|g' test/WETH.sol\n    sed -i 's|IERC20(0)|IERC20(address(0))|g' pools/BasePool.sol\n    sed -i 's|IERC20(0)|IERC20(address(0))|g' vault/balances/TwoTokenPoolsBalance.sol\n    sed -i 's|IERC20(0)|IERC20(address(0))|g' vault/FlashLoans.sol\n    sed -i 's|IERC20(0)|IERC20(address(0))|g' vault/PoolTokens.sol\n    sed -i 's|uint256(msg\\.sender)|uint256(uint160(msg.sender))|g' pools/BasePool.sol\n    sed -i 's|uint256(msg\\.sender)|uint256(uint160(msg.sender))|g' pools/weighted/WeightedPool2Tokens.sol\n    sed -i 's|address(uint256(_data))|address(uint160(uint256(_data)))|g' lib/openzeppelin/Create2.sol\n    sed -i 's|address(uint256(poolId) >> (12 \\* 8))|address(uint160(uint256(poolId) >> (12 * 8)))|g' vault/PoolRegistry.sol\n    sed -i 's|bytes32(uint256(pool))|bytes32(uint256(uint160(pool)))|g' vault/PoolRegistry.sol\n    popd\n\n    # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables\n    # them for other presets but that's fine - we want same code run for benchmarks to be comparable.\n    # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365).\n    sed -i 's|it(\\(\"fails to withdraw more shares than in balance\"\\)|it.skip(\\1|g' test/compoundAssetProxyTest.ts\n    sed -i 's|it(\\(\"should prevent withdrawal of Principal Tokens and Interest Tokens before the tranche expires \"\\)|it.skip(\\1|g' test/trancheTest.ts\n    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\n\n    # This test file is very flaky. There's one particular case that fails randomly (see\n    # https://github.com/element-fi/elf-contracts/issues/240) but some others also depend on an external\n    # service which makes tests time out when that service is down.\n    # \"ProviderError: Too Many Requests error received from eth-mainnet.alchemyapi.io\"\n    rm test/mockERC20YearnVaultTest.ts\n\n    neutralize_package_lock\n    neutralize_package_json_hooks\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\" \"$config_var\"\n    force_hardhat_unlimited_contract_size \"$config_file\" \"$config_var\"\n    npm install\n\n    replace_version_pragmas\n\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn \"$config_var\"\n        store_benchmark_report hardhat elementfi \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test ElementFi elementfi_test\n"
  },
  {
    "path": "test/externalTests/ens.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2019 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { yarn build; }\nfunction test_fn { yarn test; }\n\nfunction ens_test\n{\n    local repo=\"https://github.com/ensdomains/ens-contracts.git\"\n    local ref=\"083d29a2c50cd0a8307386abf8fadc217b256256\"\n    local config_file=\"hardhat.config.js\"\n\n    local compile_only_presets=(\n        ir-no-optimize            # FIXME: Tests fail with \"Error: cannot estimate gas; transaction may fail or may require manual gas limit\"\n        legacy-no-optimize        # Compiles but tests fail to deploy GovernorCompatibilityBravo (code too large).\n    )\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        ir-optimize-evm-only\n        ir-optimize-evm+yul       # Needs memory-safe inline assembly patch\n        legacy-optimize-evm-only\n        legacy-optimize-evm+yul\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n\n    neutralize_package_lock\n    neutralize_package_json_hooks\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\"\n    pnpm install\n\n    replace_version_pragmas\n    neutralize_packaged_contracts\n\n    # In some cases Hardhat does not detect revert reasons properly via IR.\n    # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed.\n    sed -i \"s|it\\(('Does not allow wrapping a name you do not own',\\)|it.skip\\1|g\" test/wrapper/NameWrapper.js\n    sed -i \"s|it\\(('can set fuses and then burn ability to burn fuses',\\)|it.skip\\1|g\" test/wrapper/NameWrapper.js\n    sed -i \"s|it\\(('can set fuses and burn canSetResolver and canSetTTL',\\)|it.skip\\1|g\" test/wrapper/NameWrapper.js\n    sed -i \"s|it\\(('Cannot be called if CANNOT_TRANSFER is burned\\.',\\)|it.skip\\1|g\" test/wrapper/NameWrapper.js\n    sed -i \"s|it\\(('Cannot be called if CANNOT_SET_RESOLVER is burned\\.\\?',\\)|it.skip\\1|g\" test/wrapper/NameWrapper.js\n    sed -i \"s|it\\(('Cannot be called if CANNOT_SET_TTL is burned\\.\\?',\\)|it.skip\\1|g\" test/wrapper/NameWrapper.js\n    sed -i \"s|it\\(('Cannot be called if CREATE_SUBDOMAIN is burned and is a new subdomain',\\)|it.skip\\1|g\" test/wrapper/NameWrapper.js\n    sed -i \"s|it\\(('Cannot be called if REPLACE_SUBDOMAIN is burned and is an existing subdomain',\\)|it.skip\\1|g\" test/wrapper/NameWrapper.js\n    sed -i \"s|it\\(('Cannot be called if CANNOT_CREATE_SUBDOMAIN is burned and is a new subdomain',\\)|it.skip\\1|g\" test/wrapper/NameWrapper.js\n    sed -i \"s|it\\(('Cannot be called if PARENT_CANNOT_CONTROL is burned and is an existing subdomain',\\)|it.skip\\1|g\" test/wrapper/NameWrapper.js\n\n    find . -name \"*.sol\" -type f -exec sed -i -e 's/^\\(\\s*\\)\\(assembly\\)/\\1\\/\\/\\/ @solidity memory-safe-assembly\\n\\1\\2/' '{}' \\;\n\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn\n        store_benchmark_report hardhat ens \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test ENS ens_test\n"
  },
  {
    "path": "test/externalTests/euler.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2022 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { npm run compile; }\nfunction test_fn {\n    # The default timeout of 20000 ms is too short for unoptimized code (https://github.com/argotorg/solidity/pull/12765).\n    TEST_TIMEOUT=100000 npx --no hardhat --no-compile test\n}\n\nfunction euler_test\n{\n    local repo=\"https://github.com/euler-xyz/euler-contracts\"\n    local ref=\"master\"\n    local config_file=\"hardhat.config.js\"\n\n    local compile_only_presets=()\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        #ir-no-optimize           # Compilation fails with \"YulException: Variable var_v_mpos is 4 too deep in the stack\". No memoryguard was present.\n        #ir-optimize-evm-only     # Compilation fails with \"YulException: Variable var_v_mpos is 4 too deep in the stack\". No memoryguard was present.\n        ir-optimize-evm+yul\n        legacy-optimize-evm-only\n        legacy-optimize-evm+yul\n        legacy-no-optimize\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n\n    # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables\n    # them for other presets but that's fine - we want same code run for benchmarks to be comparable.\n    # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed.\n    sed -i \"/expectError: 'JUNK_UPGRADE_TEST_FAILURE'/d\" test/moduleUpgrade.js\n    sed -i \"/et\\.expect(errMsg)\\.to\\.contain('e\\/collateral-violation');/d\" test/flashLoanNative.js\n\n    neutralize_package_lock\n    neutralize_package_json_hooks\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\"\n    force_hardhat_unlimited_contract_size \"$config_file\"\n    npm install @uniswap/v3-sdk@3.29.1 # TODO: Remove after https://github.com/Uniswap/sdks/issues/557 is resolved\n    npm install\n    replace_version_pragmas\n    neutralize_packaged_contracts\n\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn\n        store_benchmark_report hardhat euler \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test Euler euler_test\n"
  },
  {
    "path": "test/externalTests/gnosis.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2019 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { npm run build; }\nfunction test_fn { npm test; }\n\nfunction gnosis_safe_test\n{\n    local repo=\"https://github.com/safe-global/safe-contracts.git\"\n    local ref=\"v1.4.1\"\n    local config_file=\"hardhat.config.ts\"\n    local config_var=userConfig\n\n    local compile_only_presets=()\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        #ir-no-optimize            # Compilation fails with \"YulException: Variable var_txHash is 1 too deep in the stack\". No memoryguard was present.\n        #ir-optimize-evm-only      # Compilation fails with \"YulException: Variable var_txHash is 1 too deep in the stack\". No memoryguard was present.\n        # TODO: Uncomment the preset below when the issue: https://github.com/safe-global/safe-contracts/issues/544 is solved.\n        #ir-optimize-evm+yul       # Compilation fails with \"YulException: Cannot swap Variable var_operation with Variable _1: too deep in the stack by 4 slots.\"\n        legacy-no-optimize\n        legacy-optimize-evm-only\n        legacy-optimize-evm+yul\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n    [[ $BINARY_TYPE == native ]] && replace_global_solc \"$BINARY_PATH\"\n\n    # NOTE: The patterns below intentionally have hard-coded versions.\n    # When the upstream updates them, there's a chance we can just remove the regex.\n    sed -i 's|\"@gnosis\\.pm/mock-contract\": \"\\^4\\.0\\.0\"|\"@gnosis.pm/mock-contract\": \"github:solidity-external-tests/mock-contract#master_080\"|g' package.json\n    sed -i 's|\"@openzeppelin/contracts\": \"\\^3\\.4\\.0\"|\"@openzeppelin/contracts\": \"^4.0.0\"|g' package.json\n\n    # Disable two tests failing due to Hardhat's heuristics not yet updated to handle solc 0.8.10.\n    # TODO: Remove this when Hardhat implements them (https://github.com/nomiclabs/hardhat/issues/2451).\n    sed -i \"s|\\(it\\)\\((\\\"should revert if called directly\\\"\\)|\\1.skip\\2|g\" test/handlers/CompatibilityFallbackHandler.spec.ts\n\n    # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables\n    # them for other presets but that's fine - we want same code run for benchmarks to be comparable.\n    # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365).\n    sed -i \"s|\\(it\\)\\((\\\"should not allow to call setup on singleton\\\"\\)|\\1.skip\\2|g\" test/core/Safe.Setup.spec.ts\n    sed -i \"s|\\(it\\)\\((\\\"can be used only via DELEGATECALL opcode\\\"\\)|\\1.skip\\2|g\" test/libraries/SignMessageLib.spec.ts\n    sed -i \"s|it\\((\\\"can only be called from Safe itself\\\"\\)|it.skip\\1|g\" test/libraries/Migration.spec.ts\n\n    neutralize_package_lock\n    neutralize_package_json_hooks\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\" \"$config_var\"\n    npm install\n    npm install hardhat-gas-reporter\n\n    replace_version_pragmas\n    [[ $BINARY_TYPE == solcjs ]] && force_solc_modules \"${DIR}/solc/dist\"\n\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn \"$config_var\"\n        store_benchmark_report hardhat gnosis \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test Gnosis-Safe gnosis_safe_test\n"
  },
  {
    "path": "test/externalTests/gp2.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2019 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { yarn run build; }\nfunction test_fn { yarn test; }\n\nfunction gp2_test\n{\n    local repo=\"https://github.com/cowprotocol/contracts.git\"\n    local ref=\"<latest-release>\"\n    local config_file=\"hardhat.config.ts\"\n    local config_var=\"config\"\n\n    local compile_only_presets=(\n        ir-no-optimize            # Tests fail with \"Error: Transaction reverted: trying to deploy a contract whose code is too large\"\n        legacy-no-optimize        # Tests fail with \"Error: Transaction reverted: trying to deploy a contract whose code is too large\"\n    )\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        ir-optimize-evm-only\n        ir-optimize-evm+yul\n        legacy-optimize-evm-only\n        legacy-optimize-evm+yul\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n    [[ $BINARY_TYPE == native ]] && replace_global_solc \"$BINARY_PATH\"\n\n    neutralize_package_json_hooks\n    name_hardhat_default_export \"$config_file\" \"$config_var\"\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\" \"$config_var\"\n    force_hardhat_unlimited_contract_size \"$config_file\" \"$config_var\"\n    yarn\n    # Hardhat 3.0+ breaks the test suite\n    # v2.27.1 is the last v2 Hardhat (introduces Osaka support)\n    # hardhat-gas-reporter v2 is required for compatibility with our injected gas reporter settings\n    yarn add hardhat@2.27.1 hardhat-gas-reporter@^2\n\n    # Ignore bench directory which fails to compile with current hardhat and ethers versions.\n    # bench/trace/gas.ts:123:19 - error TS2339: Property 'equals' does not exist on type 'Uint8Array'.\n    jq '. + {\"exclude\": [\"bench\"]}' tsconfig.json > temp.json\n    mv temp.json tsconfig.json\n\n    # Remove the config section that requires an Etherscan key. We don't need it just to run tests.\n    sed -i '/^  etherscan: {$/,/^  },$/d' hardhat.config.ts\n\n    # Some dependencies come with pre-built artifacts. We want to build from scratch.\n    rm -r node_modules/@gnosis.pm/safe-contracts/build/\n\n    # FIXME: One of the E2E tests tries to import artifacts from Gnosis Safe. We should rebuild them\n    # but it's not that easy because @gnosis.pm/safe-contracts does not come with Hardhat config.\n    rm test/e2e/contractOrdersWithGnosisSafe.test.ts\n\n    # Patch contracts for 0.8.x compatibility.\n    # NOTE: I'm patching OpenZeppelin as well instead of installing OZ 4.0 because it requires less\n    # work. The project imports files that were moved to different locations in 4.0.\n    sed -i 's|uint256(-1)|type(uint256).max|g' src/contracts/GPv2Settlement.sol\n    sed -i 's|return msg\\.sender;|return payable(msg.sender);|g' node_modules/@openzeppelin/contracts/utils/Context.sol\n    perl -i -0pe \\\n        \"s/uint256 (executedBuyAmount = \\(-tokenDeltas\\[trade.buyTokenIndex\\]\\)\\n\\s+.toUint256\\(\\);)/uint256 executedBuyAmount; unchecked \\{\\1\\}/g\" \\\n        src/contracts/GPv2Settlement.sol\n\n    # This test is not supposed to work. The compiler is supposed to enforce zero padding since\n    # at least 0.5.8 (see https://github.com/argotorg/solidity/pull/5815). For some reason the\n    # test worked on 0.7.6 but no longer works on 0.8.x.\n    sed -i 's|it\\((\"invalid EVM transaction encoding does not change order hash\"\\)|it.skip\\1|g' test/GPv2Signing.test.ts\n\n    # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables\n    # them for other presets but that's fine - we want same code run for benchmarks to be comparable.\n    # TODO: Remove this when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3365).\n    sed -i 's|it\\((\"should revert when encoding invalid flags\"\\)|it.skip\\1|g' test/GPv2Trade.test.ts\n\n    replace_version_pragmas\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn \"$config_var\"\n        store_benchmark_report hardhat gp2 \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test Gnosis-Protocol-V2 gp2_test\n"
  },
  {
    "path": "test/externalTests/pool-together.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2022 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { yarn compile; }\nfunction test_fn { yarn test; }\n\nfunction pool_together_test\n{\n    local repo=\"https://github.com/pooltogether/v4-core.git\"\n    local ref=\"<latest-release>\"\n    local config_file=\"hardhat.config.ts\"\n    local config_var=\"config\"\n\n    local compile_only_presets=()\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        ir-no-optimize\n        ir-optimize-evm-only\n        ir-optimize-evm+yul\n        legacy-no-optimize\n        legacy-optimize-evm-only\n        legacy-optimize-evm+yul\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n\n    # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed.\n    sed -i \"s|it\\(('should fail to return value if value passed does not fit in [0-9]\\+ bits'\\)|it.skip\\1|g\" test/libraries/ExtendedSafeCast.test.ts\n    sed -i \"s|it\\(('should require an rng to be requested'\\)|it.skip\\1|g\" test/DrawBeacon.test.ts\n\n    neutralize_package_json_hooks\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\" \"$config_var\"\n    yarn install\n    # Hardhat 3.0+ breaks the test suite\n    # v2.27.1 is the last v2 Hardhat (introduces Osaka support)\n    yarn add hardhat@2.27.1\n\n    # These come with already compiled artifacts. We want them recompiled with latest compiler.\n    rm -r node_modules/@pooltogether/yield-source-interface/artifacts/\n    rm -r node_modules/@pooltogether/uniform-random-number/artifacts/\n    rm -r node_modules/@pooltogether/owner-manager-contracts/artifacts/\n\n    replace_version_pragmas\n    neutralize_packaged_contracts\n\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn \"$config_var\"\n        store_benchmark_report hardhat pool-together \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test Pool-Together-V4 pool_together_test\n"
  },
  {
    "path": "test/externalTests/prb-math.py",
    "content": "#!/usr/bin/env python3\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2023 solidity contributors.\n# ------------------------------------------------------------------------------\n\nimport sys\nimport subprocess\nfrom pathlib import Path\nfrom shutil import which\n\n# Our scripts/ is not a proper Python package so we need to modify PYTHONPATH to import from it\n# pragma pylint: disable=import-error,wrong-import-position\nPROJECT_ROOT = Path(__file__).parents[2]\nsys.path.insert(0, f\"{PROJECT_ROOT}/scripts/externalTests\")\n\nfrom runners.base import run_test\nfrom runners.base import TestConfig\nfrom runners.foundry import FoundryRunner\nfrom test_helpers import SettingsPreset\n\nclass PRBMathRunner(FoundryRunner):\n    def configure(self):\n        if which(\"pnpm\") is None:\n            raise RuntimeError(\"pnpm not found.\")\n\n        self.setup_presets_profiles()\n        # Starting from version v4.0.2, the default installation method for PRBMath dependencies\n        # has transitioned from Foundry to Node.js.\n        subprocess.run(\n            [\"pnpm\", \"install\", \"--no-frozen-lockfile\"],\n            env=self.env,\n            check=True\n        )\n\ntest_config = TestConfig(\n    name=\"PRBMath\",\n    repo_url=\"https://github.com/PaulRBerg/prb-math.git\",\n    ref=\"main\",\n    settings_presets=[\n        SettingsPreset.LEGACY_NO_OPTIMIZE,\n        SettingsPreset.LEGACY_OPTIMIZE_EVM_ONLY,\n        SettingsPreset.LEGACY_OPTIMIZE_EVM_YUL,\n        SettingsPreset.IR_NO_OPTIMIZE,\n        SettingsPreset.IR_OPTIMIZE_EVM_YUL,\n        SettingsPreset.IR_OPTIMIZE_EVM_ONLY,\n    ],\n)\n\nsys.exit(run_test(PRBMathRunner(argv=sys.argv[1:], config=test_config)))\n"
  },
  {
    "path": "test/externalTests/solc-js/DAO/DAO.sol",
    "content": "/*\nThis file is part of the DAO.\n\nThe DAO is free software: you can redistribute it and/or modify\nit under the terms of the GNU lesser General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThe DAO is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU lesser General Public License for more details.\n\nYou should have received a copy of the GNU lesser General Public License\nalong with the DAO.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n\n/*\nStandard smart contract for a Decentralized Autonomous Organization (DAO)\nto automate organizational governance and decision-making.\n*/\n\nimport \"./TokenCreation.sol\";\nimport \"./ManagedAccount.sol\";\n\nabstract contract DAOInterface {\n\n    // The amount of days for which people who try to participate in the\n    // creation by calling the fallback function will still get their ether back\n    uint constant creationGracePeriod = 40 days;\n    // The minimum debate period that a generic proposal can have\n    uint constant minProposalDebatePeriod = 2 weeks;\n    // The minimum debate period that a split proposal can have\n    uint constant minSplitDebatePeriod = 1 weeks;\n    // Period of days inside which it's possible to execute a DAO split\n    uint constant splitExecutionPeriod = 27 days;\n    // Period of time after which the minimum Quorum is halved\n    uint constant quorumHalvingPeriod = 25 weeks;\n    // Period after which a proposal is closed\n    // (used in the case `executeProposal` fails because it throws)\n    uint constant executeProposalPeriod = 10 days;\n    // Denotes the maximum proposal deposit that can be given. It is given as\n    // a fraction of total Ether spent plus balance of the DAO\n    uint constant maxDepositDivisor = 100;\n\n    // Proposals to spend the DAO's ether or to choose a new Curator\n    Proposal[] public proposals;\n    // The quorum needed for each proposal is partially calculated by\n    // totalSupply / minQuorumDivisor\n    uint public minQuorumDivisor;\n    // The unix time of the last time quorum was reached on a proposal\n    uint public lastTimeMinQuorumMet;\n\n    // Address of the curator\n    address payable public curator;\n    // The whitelist: List of addresses the DAO is allowed to send ether to\n    mapping (address => bool) public allowedRecipients;\n\n    // Tracks the addresses that own Reward Tokens. Those addresses can only be\n    // DAOs that have split from the original DAO. Conceptually, Reward Tokens\n    // represent the proportion of the rewards that the DAO has the right to\n    // receive. These Reward Tokens are generated when the DAO spends ether.\n    mapping (address => uint) public rewardToken;\n    // Total supply of rewardToken\n    uint public totalRewardToken;\n\n    // The account used to manage the rewards which are to be distributed to the\n    // DAO Token Holders of this DAO\n    ManagedAccount public rewardAccount;\n\n    // The account used to manage the rewards which are to be distributed to\n    // any DAO that holds Reward Tokens\n    ManagedAccount public DAOrewardAccount;\n\n    // Amount of rewards (in wei) already paid out to a certain DAO\n    mapping (address => uint) public DAOpaidOut;\n\n    // Amount of rewards (in wei) already paid out to a certain address\n    mapping (address => uint) public paidOut;\n    // Map of addresses blocked during a vote (not allowed to transfer DAO\n    // tokens). The address points to the proposal ID.\n    mapping (address => uint) public blocked;\n\n    // The minimum deposit (in wei) required to submit any proposal that is not\n    // requesting a new Curator (no deposit is required for splits)\n    uint public proposalDeposit;\n\n    // the accumulated sum of all current proposal deposits\n    uint sumOfProposalDeposits;\n\n    // Contract that is able to create a new DAO (with the same code as\n    // this one), used for splits\n    DAO_Creator public daoCreator;\n\n    // A proposal with `newCurator == false` represents a transaction\n    // to be issued by this DAO\n    // A proposal with `newCurator == true` represents a DAO split\n    struct Proposal {\n        // The address where the `amount` will go to if the proposal is accepted\n        // or if `newCurator` is true, the proposed Curator of\n        // the new DAO).\n        address payable recipient;\n        // The amount to transfer to `recipient` if the proposal is accepted.\n        uint amount;\n        // A plain text description of the proposal\n        string description;\n        // A unix timestamp, denoting the end of the voting period\n        uint votingDeadline;\n        // True if the proposal's votes have yet to be counted, otherwise False\n        bool open;\n        // True if quorum has been reached, the votes have been counted, and\n        // the majority said yes\n        bool proposalPassed;\n        // A hash to check validity of a proposal\n        bytes32 proposalHash;\n        // Deposit in wei the creator added when submitting their proposal. It\n        // is taken from the msg.value of a newProposal call.\n        uint proposalDeposit;\n        // True if this proposal is to assign a new Curator\n        bool newCurator;\n        // Data needed for splitting the DAO\n        SplitData[] splitData;\n        // Number of Tokens in favor of the proposal\n        uint yea;\n        // Number of Tokens opposed to the proposal\n        uint nay;\n        // Simple mapping to check if a shareholder has voted for it\n        mapping (address => bool) votedYes;\n        // Simple mapping to check if a shareholder has voted against it\n        mapping (address => bool) votedNo;\n        // Address of the shareholder who created the proposal\n        address payable creator;\n    }\n\n    // Used only in the case of a newCurator proposal.\n    struct SplitData {\n        // The balance of the current DAO minus the deposit at the time of split\n        uint splitBalance;\n        // The total amount of DAO Tokens in existence at the time of split.\n        uint totalSupply;\n        // Amount of Reward Tokens owned by the DAO at the time of split.\n        uint rewardToken;\n        // The new DAO contract created at the time of split.\n        DAO newDAO;\n    }\n\n    /// @dev Constructor setting the Curator and the address\n    /// for the contract able to create another DAO as well as the parameters\n    /// for the DAO Token Creation\n    /// @param _curator The Curator\n    /// @param _daoCreator The contract able to (re)create this DAO\n    /// @param _proposalDeposit The deposit to be paid for a regular proposal\n    /// @param _minTokensToCreate Minimum required wei-equivalent tokens\n    ///        to be created for a successful DAO Token Creation\n    /// @param _closingTime Date (in Unix time) of the end of the DAO Token Creation\n    /// @param _privateCreation If zero the DAO Token Creation is open to public, a\n    /// non-zero address means that the DAO Token Creation is only for the address\n    /// @param _tokenName The name that the DAO's token will have\n    /// @param _tokenSymbol The ticker symbol that this DAO token should have\n    /// @param _decimalPlaces The number of decimal places that the token is\n    ///        counted from.\n    // This is the constructor: it can not be overloaded so it is commented out\n    //  function DAO(\n        //  address payable _curator,\n        //  DAO_Creator _daoCreator,\n        //  uint _proposalDeposit,\n        //  uint _minTokensToCreate,\n        //  uint _closingTime,\n        //  address _privateCreation\n        //  string _tokenName,\n        //  string _tokenSymbol,\n        //  uint8 _decimalPlaces\n    //  );\n\n    /// @notice Create Token with `msg.sender` as the beneficiary\n    receive() virtual external payable;\n\n\n    /// @dev This function is used to send ether back\n    /// to the DAO, it can also be used to receive payments that should not be\n    /// counted as rewards (donations, grants, etc.)\n    /// @return Whether the DAO received the ether successfully\n    function receiveEther() public virtual returns (bool);\n\n    /// @notice `msg.sender` creates a proposal to send `_amount` Wei to\n    /// `_recipient` with the transaction data `_transactionData`. If\n    /// `_newCurator` is true, then this is a proposal that splits the\n    /// DAO and sets `_recipient` as the new DAO's Curator.\n    /// @param _recipient Address of the recipient of the proposed transaction\n    /// @param _amount Amount of wei to be sent with the proposed transaction\n    /// @param _description String describing the proposal\n    /// @param _transactionData Data of the proposed transaction\n    /// @param _debatingPeriod Time used for debating a proposal, at least 2\n    /// weeks for a regular proposal, 10 days for new Curator proposal\n    /// @param _newCurator Bool defining whether this proposal is about\n    /// a new Curator or not\n    /// @return _proposalID The proposal ID. Needed for voting on the proposal\n    function newProposal(\n        address payable _recipient,\n        uint _amount,\n        string memory _description,\n        bytes memory _transactionData,\n        uint _debatingPeriod,\n        bool _newCurator\n    ) public virtual payable returns (uint _proposalID);\n\n    /// @notice Check that the proposal with the ID `_proposalID` matches the\n    /// transaction which sends `_amount` with data `_transactionData`\n    /// to `_recipient`\n    /// @param _proposalID The proposal ID\n    /// @param _recipient The recipient of the proposed transaction\n    /// @param _amount The amount of wei to be sent in the proposed transaction\n    /// @param _transactionData The data of the proposed transaction\n    /// @return _codeChecksOut Whether the proposal ID matches the transaction data or not\n    function checkProposalCode(\n        uint _proposalID,\n        address payable _recipient,\n        uint _amount,\n        bytes memory _transactionData\n    ) public virtual view returns (bool _codeChecksOut);\n\n    /// @notice Vote on proposal `_proposalID` with `_supportsProposal`\n    /// @param _proposalID The proposal ID\n    /// @param _supportsProposal Yes/No - support of the proposal\n    /// @return _voteID The vote ID.\n    function vote(\n        uint _proposalID,\n        bool _supportsProposal\n    ) public virtual returns (uint _voteID);\n\n    /// @notice Checks whether proposal `_proposalID` with transaction data\n    /// `_transactionData` has been voted for or rejected, and executes the\n    /// transaction in the case it has been voted for.\n    /// @param _proposalID The proposal ID\n    /// @param _transactionData The data of the proposed transaction\n    /// @return _success Whether the proposed transaction has been executed or not\n    function executeProposal(\n        uint _proposalID,\n        bytes memory _transactionData\n    ) public virtual returns (bool _success);\n\n    /// @notice ATTENTION! I confirm to move my remaining ether to a new DAO\n    /// with `_newCurator` as the new Curator, as has been\n    /// proposed in proposal `_proposalID`. This will burn my tokens. This can\n    /// not be undone and will split the DAO into two DAO's, with two\n    /// different underlying tokens.\n    /// @param _proposalID The proposal ID\n    /// @param _newCurator The new Curator of the new DAO\n    /// @dev This function, when called for the first time for this proposal,\n    /// will create a new DAO and send the sender's portion of the remaining\n    /// ether and Reward Tokens to the new DAO. It will also burn the DAO Tokens\n    /// of the sender.\n    function splitDAO(\n        uint _proposalID,\n        address payable _newCurator\n    ) public virtual returns (bool _success);\n\n    /// @dev can only be called by the DAO itself through a proposal\n    /// updates the contract of the DAO by sending all ether and rewardTokens\n    /// to the new DAO. The new DAO needs to be approved by the Curator\n    /// @param _newContract the address of the new contract\n    function newContract(address payable _newContract) virtual public;\n\n\n    /// @notice Add a new possible recipient `_recipient` to the whitelist so\n    /// that the DAO can send transactions to them (using proposals)\n    /// @param _recipient New recipient address\n    /// @dev Can only be called by the current Curator\n    /// @return _success Whether successful or not\n    function changeAllowedRecipients(address _recipient, bool _allowed) virtual external returns (bool _success);\n\n\n    /// @notice Change the minimum deposit required to submit a proposal\n    /// @param _proposalDeposit The new proposal deposit\n    /// @dev Can only be called by this DAO (through proposals with the\n    /// recipient being this DAO itself)\n    function changeProposalDeposit(uint _proposalDeposit) virtual external;\n\n    /// @notice Move rewards from the DAORewards managed account\n    /// @param _toMembers If true rewards are moved to the actual reward account\n    ///                   for the DAO. If not then it's moved to the DAO itself\n    /// @return _success Whether the call was successful\n    function retrieveDAOReward(bool _toMembers) virtual external returns (bool _success);\n\n    /// @notice Get my portion of the reward that was sent to `rewardAccount`\n    /// @return _success Whether the call was successful\n    function getMyReward() public virtual returns (bool _success);\n\n    /// @notice Withdraw `_account`'s portion of the reward from `rewardAccount`\n    /// to `_account`'s balance\n    /// @return _success Whether the call was successful\n    function withdrawRewardFor(address payable _account) internal virtual returns (bool _success);\n\n    /// @notice Send `_amount` tokens to `_to` from `msg.sender`. Prior to this\n    /// getMyReward() is called.\n    /// @param _to The address of the recipient\n    /// @param _amount The amount of tokens to be transferred\n    /// @return success Whether the transfer was successful or not\n    function transferWithoutReward(address _to, uint256 _amount) public virtual returns (bool success);\n\n    /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it\n    /// is approved by `_from`. Prior to this getMyReward() is called.\n    /// @param _from The address of the sender\n    /// @param _to The address of the recipient\n    /// @param _amount The amount of tokens to be transferred\n    /// @return success Whether the transfer was successful or not\n    function transferFromWithoutReward(\n        address payable _from,\n        address _to,\n        uint256 _amount\n    ) public virtual returns (bool success);\n\n    /// @notice Doubles the 'minQuorumDivisor' in the case quorum has not been\n    /// achieved in 52 weeks\n    /// @return _success Whether the change was successful or not\n    function halveMinQuorum() public virtual returns (bool _success);\n\n    /// @return _numberOfProposals total number of proposals ever created\n    function numberOfProposals() public virtual view returns (uint _numberOfProposals);\n\n    /// @param _proposalID Id of the new curator proposal\n    /// @return _newDAO Address of the new DAO\n    function getNewDAOAddress(uint _proposalID) public virtual view returns (address _newDAO);\n\n    /// @param _account The address of the account which is checked.\n    /// @return Whether the account is blocked (not allowed to transfer tokens) or not.\n    function isBlocked(address _account) internal virtual returns (bool);\n\n    /// @notice If the caller is blocked by a proposal whose voting deadline\n    /// has exprired then unblock him.\n    /// @return Whether the account is blocked (not allowed to transfer tokens) or not.\n    function unblockMe() public virtual returns (bool);\n\n    event ProposalAdded(\n        uint indexed proposalID,\n        address recipient,\n        uint amount,\n        bool newCurator,\n        string description\n    );\n    event Voted(uint indexed proposalID, bool position, address indexed voter);\n    event ProposalTallied(uint indexed proposalID, bool result, uint quorum);\n    event NewCurator(address indexed _newCurator);\n    event AllowedRecipientChanged(address indexed _recipient, bool _allowed);\n}\n\n// The DAO contract itself\ncontract DAO is DAOInterface, Token, TokenCreation {\n\n    // Modifier that allows only shareholders to vote and create new proposals\n    modifier onlyTokenholders {\n        if (balanceOf(msg.sender) == 0) revert();\n            _;\n    }\n\n    constructor(\n        address payable _curator,\n        DAO_Creator _daoCreator,\n        uint _proposalDeposit,\n        uint _minTokensToCreate,\n        uint _closingTime,\n        address _privateCreation,\n        string memory _tokenName,\n        string memory _tokenSymbol,\n        uint8 _decimalPlaces\n    ) TokenCreation(\n        _minTokensToCreate,\n        _closingTime,\n        _privateCreation,\n        _tokenName,\n        _tokenSymbol,\n        _decimalPlaces) public {\n\n        curator = _curator;\n        daoCreator = _daoCreator;\n        proposalDeposit = _proposalDeposit;\n        rewardAccount = new ManagedAccount(address(this), false);\n        DAOrewardAccount = new ManagedAccount(address(this), false);\n        if (address(rewardAccount) == 0x0000000000000000000000000000000000000000)\n            revert();\n        if (address(DAOrewardAccount) == 0x0000000000000000000000000000000000000000)\n            revert();\n        lastTimeMinQuorumMet = block.timestamp;\n        minQuorumDivisor = 5; // sets the minimal quorum to 20%\n        proposals.push(); // avoids a proposal with ID 0 because it is used\n\n        allowedRecipients[address(this)] = true;\n        allowedRecipients[curator] = true;\n    }\n\n    receive() external payable override(DAOInterface, TokenCreation) {\n        if (block.timestamp < closingTime + creationGracePeriod && msg.sender != address(extraBalance))\n            createTokenProxy(payable(msg.sender));\n        else\n            receiveEther();\n    }\n\n\n    function receiveEther() public override returns (bool) {\n        return true;\n    }\n\n\n    function newProposal(\n        address payable _recipient,\n        uint _amount,\n        string memory _description,\n        bytes memory _transactionData,\n        uint _debatingPeriod,\n        bool _newCurator\n    ) onlyTokenholders public override payable returns (uint _proposalID) {\n\n        // Sanity check\n        if (_newCurator && (\n            _amount != 0\n            || _transactionData.length != 0\n            || _recipient == curator\n            || msg.value > 0\n            || _debatingPeriod < minSplitDebatePeriod)) {\n            revert();\n        } else if (\n            !_newCurator\n            && (!isRecipientAllowed(_recipient) || (_debatingPeriod <  minProposalDebatePeriod))\n        ) {\n            revert();\n        }\n\n        if (_debatingPeriod > 8 weeks)\n            revert();\n\n        if (!isFueled\n            || block.timestamp < closingTime\n            || (msg.value < proposalDeposit && !_newCurator)) {\n\n            revert();\n        }\n\n        if (block.timestamp + _debatingPeriod < block.timestamp) // prevents overflow\n            revert();\n\n        // to prevent a 51% attacker to convert the ether into deposit\n        if (msg.sender == address(this))\n            revert();\n\n        // to prevent curator from halving quorum before first proposal\n        if (proposals.length == 1) // initial length is 1 (see constructor)\n            lastTimeMinQuorumMet = block.timestamp;\n\n        Proposal storage p = proposals.push();\n         _proposalID = proposals.length - 1;\n        p.recipient = _recipient;\n        p.amount = _amount;\n        p.description = _description;\n        p.proposalHash = keccak256(abi.encodePacked(_recipient, _amount, _transactionData));\n        p.votingDeadline = block.timestamp + _debatingPeriod;\n        p.open = true;\n        //p.proposalPassed = False; // that's default\n        p.newCurator = _newCurator;\n        if (_newCurator)\n            p.splitData.push();\n        p.creator = payable(msg.sender);\n        p.proposalDeposit = msg.value;\n\n        sumOfProposalDeposits += msg.value;\n\n        emit ProposalAdded(\n            _proposalID,\n            _recipient,\n            _amount,\n            _newCurator,\n            _description\n        );\n    }\n\n\n    function checkProposalCode(\n        uint _proposalID,\n        address payable _recipient,\n        uint _amount,\n        bytes memory _transactionData\n    ) public override view returns (bool _codeChecksOut) {\n        Proposal storage p = proposals[_proposalID];\n        return p.proposalHash == keccak256(abi.encodePacked(_recipient, _amount, _transactionData));\n    }\n\n\n    function vote(\n        uint _proposalID,\n        bool _supportsProposal\n    ) onlyTokenholders public override returns (uint _voteID) {\n\n        Proposal storage p = proposals[_proposalID];\n        if (p.votedYes[msg.sender]\n            || p.votedNo[msg.sender]\n            || block.timestamp >= p.votingDeadline) {\n\n            revert();\n        }\n\n        if (_supportsProposal) {\n            p.yea += balances[msg.sender];\n            p.votedYes[msg.sender] = true;\n        } else {\n            p.nay += balances[msg.sender];\n            p.votedNo[msg.sender] = true;\n        }\n\n        if (blocked[msg.sender] == 0) {\n            blocked[msg.sender] = _proposalID;\n        } else if (p.votingDeadline > proposals[blocked[msg.sender]].votingDeadline) {\n            // this proposal's voting deadline is further into the future than\n            // the proposal that blocks the sender so make it the blocker\n            blocked[msg.sender] = _proposalID;\n        }\n\n        emit Voted(_proposalID, _supportsProposal, msg.sender);\n    }\n\n\n    function executeProposal(\n        uint _proposalID,\n        bytes memory _transactionData\n    ) public override returns (bool _success) {\n\n        Proposal storage p = proposals[_proposalID];\n\n        uint waitPeriod = p.newCurator\n            ? splitExecutionPeriod\n            : executeProposalPeriod;\n        // If we are over deadline and waiting period, assert proposal is closed\n        if (p.open && block.timestamp > p.votingDeadline + waitPeriod) {\n            closeProposal(_proposalID);\n            return false;\n        }\n\n        // Check if the proposal can be executed\n        if (block.timestamp < p.votingDeadline  // has the voting deadline arrived?\n            // Have the votes been counted?\n            || !p.open\n            || p.proposalPassed // anyone trying to call us recursively?\n            // Does the transaction code match the proposal?\n            || p.proposalHash != keccak256(abi.encodePacked(p.recipient, p.amount, _transactionData))) {\n\n            revert();\n        }\n\n        // If the curator removed the recipient from the whitelist, close the proposal\n        // in order to free the deposit and allow unblocking of voters\n        if (!isRecipientAllowed(p.recipient)) {\n            closeProposal(_proposalID);\n            p.creator.send(p.proposalDeposit);\n            return false;\n        }\n\n        bool proposalCheck = true;\n\n        if (p.amount > actualBalance())\n            proposalCheck = false;\n\n        uint quorum = p.yea + p.nay;\n\n        // require 53% for calling newContract()\n        if (_transactionData.length >= 4 && _transactionData[0] == 0x68\n            && _transactionData[1] == 0x37 && _transactionData[2] == 0xff\n            && _transactionData[3] == 0x1e\n            && quorum < minQuorum(actualBalance() + rewardToken[address(this)])) {\n\n                proposalCheck = false;\n        }\n\n        if (quorum >= minQuorum(p.amount)) {\n            if (!p.creator.send(p.proposalDeposit))\n                revert();\n\n            lastTimeMinQuorumMet = block.timestamp;\n            // set the minQuorum to 20% again, in the case it has been reached\n            if (quorum > totalSupply / 5)\n                minQuorumDivisor = 5;\n        }\n\n        // Execute result\n        if (quorum >= minQuorum(p.amount) && p.yea > p.nay && proposalCheck) {\n            // we are setting this here before the CALL() value transfer to\n            // assure that in the case of a malicious recipient contract trying\n            // to call executeProposal() recursively money can't be transferred\n            // multiple times out of the DAO\n            p.proposalPassed = true;\n\n            (bool success,) = p.recipient.call{value: p.amount}(_transactionData);\n            if (!success)\n                revert();\n\n            _success = true;\n\n            // only create reward tokens when ether is not sent to the DAO itself and\n            // related addresses. Proxy addresses should be forbidden by the curator.\n            if (p.recipient != address(this) && p.recipient != address(rewardAccount)\n                && p.recipient != address(DAOrewardAccount)\n                && p.recipient != address(extraBalance)\n                && p.recipient != address(curator)) {\n\n                rewardToken[address(this)] += p.amount;\n                totalRewardToken += p.amount;\n            }\n        }\n\n        closeProposal(_proposalID);\n\n        // Initiate event\n        emit ProposalTallied(_proposalID, _success, quorum);\n    }\n\n\n    function closeProposal(uint _proposalID) internal {\n        Proposal storage p = proposals[_proposalID];\n        if (p.open)\n            sumOfProposalDeposits -= p.proposalDeposit;\n        p.open = false;\n    }\n\n    function splitDAO(\n        uint _proposalID,\n        address payable _newCurator\n    ) onlyTokenholders public override returns (bool _success) {\n\n        Proposal storage p = proposals[_proposalID];\n\n        // Sanity check\n\n        if (block.timestamp < p.votingDeadline  // has the voting deadline arrived?\n            //The request for a split expires XX days after the voting deadline\n            || block.timestamp > p.votingDeadline + splitExecutionPeriod\n            // Does the new Curator address match?\n            || p.recipient != _newCurator\n            // Is it a new curator proposal?\n            || !p.newCurator\n            // Have you voted for this split?\n            || !p.votedYes[msg.sender]\n            // Did you already vote on another proposal?\n            || (blocked[msg.sender] != _proposalID && blocked[msg.sender] != 0) )  {\n\n            revert();\n        }\n\n        // If the new DAO doesn't exist yet, create the new DAO and store the\n        // current split data\n        if (address(p.splitData[0].newDAO) == 0x0000000000000000000000000000000000000000) {\n            p.splitData[0].newDAO = createNewDAO(_newCurator);\n            // Call depth limit reached, etc.\n            if (address(p.splitData[0].newDAO) == 0x0000000000000000000000000000000000000000)\n                revert();\n            // should never happen\n            if (address(this).balance < sumOfProposalDeposits)\n                revert();\n            p.splitData[0].splitBalance = actualBalance();\n            p.splitData[0].rewardToken = rewardToken[address(this)];\n            p.splitData[0].totalSupply = totalSupply;\n            p.proposalPassed = true;\n        }\n\n        // Move ether and assign new Tokens\n        uint fundsToBeMoved =\n            (balances[msg.sender] * p.splitData[0].splitBalance) /\n            p.splitData[0].totalSupply;\n        if (p.splitData[0].newDAO.createTokenProxy{value: fundsToBeMoved}(payable(msg.sender)) == false)\n            revert();\n\n\n        // Assign reward rights to new DAO\n        uint rewardTokenToBeMoved =\n            (balances[msg.sender] * p.splitData[0].rewardToken) /\n            p.splitData[0].totalSupply;\n\n        uint paidOutToBeMoved = DAOpaidOut[address(this)] * rewardTokenToBeMoved /\n            rewardToken[address(this)];\n\n        rewardToken[address(p.splitData[0].newDAO)] += rewardTokenToBeMoved;\n        if (rewardToken[address(this)] < rewardTokenToBeMoved)\n            revert();\n        rewardToken[address(this)] -= rewardTokenToBeMoved;\n\n        DAOpaidOut[address(p.splitData[0].newDAO)] += paidOutToBeMoved;\n        if (DAOpaidOut[address(this)] < paidOutToBeMoved)\n            revert();\n        DAOpaidOut[address(this)] -= paidOutToBeMoved;\n\n        // Burn DAO Tokens\n        emit Transfer(msg.sender, 0x0000000000000000000000000000000000000000, balances[msg.sender]);\n        withdrawRewardFor(payable(msg.sender)); // be nice, and get his rewards\n        totalSupply -= balances[msg.sender];\n        balances[msg.sender] = 0;\n        paidOut[msg.sender] = 0;\n        return true;\n    }\n\n    function newContract(address payable _newContract) public override {\n        if (msg.sender != address(this) || !allowedRecipients[_newContract]) return;\n        // move all ether\n        (bool success,) = _newContract.call{value: address(this).balance}(\"\");\n        if (!success) {\n            revert();\n        }\n\n        //move all reward tokens\n        rewardToken[_newContract] += rewardToken[address(this)];\n        rewardToken[address(this)] = 0;\n        DAOpaidOut[_newContract] += DAOpaidOut[address(this)];\n        DAOpaidOut[address(this)] = 0;\n    }\n\n\n    function retrieveDAOReward(bool _toMembers) external override returns (bool _success) {\n        DAO dao = DAO(payable(msg.sender));\n\n        if ((rewardToken[msg.sender] * DAOrewardAccount.accumulatedInput()) /\n            totalRewardToken < DAOpaidOut[msg.sender])\n            revert();\n\n        uint reward =\n            (rewardToken[msg.sender] * DAOrewardAccount.accumulatedInput()) /\n            totalRewardToken - DAOpaidOut[msg.sender];\n\n        reward = address(DAOrewardAccount).balance < reward ? address(DAOrewardAccount).balance : reward;\n\n        if(_toMembers) {\n            if (!DAOrewardAccount.payOut(payable(dao.rewardAccount()), reward))\n                revert();\n            }\n        else {\n            if (!DAOrewardAccount.payOut(payable(dao), reward))\n                revert();\n        }\n        DAOpaidOut[msg.sender] += reward;\n        return true;\n    }\n\n    function getMyReward() public override returns (bool _success) {\n        return withdrawRewardFor(payable(msg.sender));\n    }\n\n\n    function withdrawRewardFor(address payable _account) noEther internal\noverride returns (bool _success) {\n        if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply < paidOut[_account])\n            revert();\n\n        uint reward =\n            (balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply - paidOut[_account];\n\n        reward = address(rewardAccount).balance < reward ? address(rewardAccount).balance : reward;\n\n        if (!rewardAccount.payOut(_account, reward))\n            revert();\n        paidOut[_account] += reward;\n        return true;\n    }\n\n\n    function transfer(address _to, uint256 _value) public override returns (bool success) {\n        if (isFueled\n            && block.timestamp > closingTime\n            && !isBlocked(msg.sender)\n            && _to != address(this)\n            && transferPaidOut(msg.sender, _to, _value)\n            && super.transfer(_to, _value)) {\n\n            return true;\n        } else {\n            revert();\n        }\n    }\n\n\n    function transferWithoutReward(address _to, uint256 _value) public override returns (bool success) {\n        if (!getMyReward())\n            revert();\n        return transfer(_to, _value);\n    }\n\n\n    function transferFrom(address _from, address _to, uint256 _value) public\noverride returns (bool success) {\n        if (isFueled\n            && block.timestamp > closingTime\n            && !isBlocked(_from)\n            && _to != address(this)\n            && transferPaidOut(_from, _to, _value)\n            && super.transferFrom(_from, _to, _value)) {\n\n            return true;\n        } else {\n            revert();\n        }\n    }\n\n\n    function transferFromWithoutReward(\n        address payable _from,\n        address _to,\n        uint256 _value\n    ) public override returns (bool success) {\n\n        if (!withdrawRewardFor(_from))\n            revert();\n        return transferFrom(_from, _to, _value);\n    }\n\n\n    function transferPaidOut(\n        address _from,\n        address _to,\n        uint256 _value\n    ) internal returns (bool success) {\n\n        uint transferPaidOut = paidOut[_from] * _value / balanceOf(_from);\n        if (transferPaidOut > paidOut[_from])\n            revert();\n        paidOut[_from] -= transferPaidOut;\n        paidOut[_to] += transferPaidOut;\n        return true;\n    }\n\n\n    function changeProposalDeposit(uint _proposalDeposit) external override {\n        if (msg.sender != address(this) || _proposalDeposit > (actualBalance() + rewardToken[address(this)])\n            / maxDepositDivisor) {\n\n            revert();\n        }\n        proposalDeposit = _proposalDeposit;\n    }\n\n\n    function changeAllowedRecipients(address _recipient, bool _allowed) external\noverride returns (bool _success) {\n        if (msg.sender != curator)\n            revert();\n        allowedRecipients[_recipient] = _allowed;\n        emit AllowedRecipientChanged(_recipient, _allowed);\n        return true;\n    }\n\n\n    function isRecipientAllowed(address _recipient) internal returns (bool _isAllowed) {\n        if (allowedRecipients[_recipient]\n            || (_recipient == address(extraBalance)\n                // only allowed when at least the amount held in the\n                // extraBalance account has been spent from the DAO\n                && totalRewardToken > extraBalance.accumulatedInput()))\n            return true;\n        else\n            return false;\n    }\n\n    function actualBalance() public view returns (uint _actualBalance) {\n        return address(this).balance - sumOfProposalDeposits;\n    }\n\n\n    function minQuorum(uint _value) internal view returns (uint _minQuorum) {\n        // minimum of 20% and maximum of 53.33%\n        return totalSupply / minQuorumDivisor +\n            (_value * totalSupply) / (3 * (actualBalance() + rewardToken[address(this)]));\n    }\n\n\n    function halveMinQuorum() public override returns (bool _success) {\n        // this can only be called after `quorumHalvingPeriod` has passed or at anytime after\n        // fueling by the curator with a delay of at least `minProposalDebatePeriod`\n        // between the calls\n        if ((lastTimeMinQuorumMet < (block.timestamp - quorumHalvingPeriod) || msg.sender == curator)\n            && lastTimeMinQuorumMet < (block.timestamp - minProposalDebatePeriod)\n            && block.timestamp >= closingTime\n            && proposals.length > 1) {\n            lastTimeMinQuorumMet = block.timestamp;\n            minQuorumDivisor *= 2;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    function createNewDAO(address payable _newCurator) internal returns (DAO _newDAO) {\n        emit NewCurator(_newCurator);\n        return daoCreator.createDAO(\n            _newCurator,\n            0,\n            0,\n            block.timestamp + splitExecutionPeriod,\n            name,\n            symbol,\n            decimals\n        );\n    }\n\n    function numberOfProposals() public view override returns (uint _numberOfProposals) {\n        // Don't count index 0. It's used by isBlocked() and exists from start\n        return proposals.length - 1;\n    }\n\n    function getNewDAOAddress(uint _proposalID) public override view returns (address _newDAO) {\n        return address(proposals[_proposalID].splitData[0].newDAO);\n    }\n\n    function isBlocked(address _account) internal override returns (bool) {\n        if (blocked[_account] == 0)\n            return false;\n        Proposal storage p = proposals[blocked[_account]];\n        if (block.timestamp > p.votingDeadline) {\n            blocked[_account] = 0;\n            return false;\n        } else {\n            return true;\n        }\n    }\n\n    function unblockMe() public override returns (bool) {\n        return isBlocked(msg.sender);\n    }\n}\n\ncontract DAO_Creator {\n    function createDAO(\n        address payable _curator,\n        uint _proposalDeposit,\n        uint _minTokensToCreate,\n        uint _closingTime,\n        string memory _tokenName,\n        string memory _tokenSymbol,\n        uint8 _decimalPlaces\n    ) public returns (DAO _newDAO) {\n\n        return new DAO(\n            _curator,\n            DAO_Creator(this),\n            _proposalDeposit,\n            _minTokensToCreate,\n            _closingTime,\n            msg.sender,\n            _tokenName,\n            _tokenSymbol,\n            _decimalPlaces\n        );\n    }\n}\n"
  },
  {
    "path": "test/externalTests/solc-js/DAO/ManagedAccount.sol",
    "content": "/*\nThis file is part of the DAO.\n\nThe DAO is free software: you can redistribute it and/or modify\nit under the terms of the GNU lesser General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThe DAO is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU lesser General Public License for more details.\n\nYou should have received a copy of the GNU lesser General Public License\nalong with the DAO.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n\n/*\nBasic account, used by the DAO contract to separately manage both the rewards\nand the extraBalance accounts.\n*/\n\nabstract contract ManagedAccountInterface {\n    // The only address with permission to withdraw from this account\n    address public owner;\n    // If true, only the owner of the account can receive ether from it\n    bool public payOwnerOnly;\n    // The sum of ether (in wei) which has been sent to this contract\n    uint public accumulatedInput;\n\n    /// @notice Sends `_amount` of wei to _recipient\n    /// @param _amount The amount of wei to send to `_recipient`\n    /// @param _recipient The address to receive `_amount` of wei\n    /// @return True if the send completed\n    function payOut(address payable _recipient, uint _amount) public virtual returns (bool);\n\n    event PayOut(address indexed _recipient, uint _amount);\n}\n\n\ncontract ManagedAccount is ManagedAccountInterface{\n\n    // The constructor sets the owner of the account\n    constructor(address _owner, bool _payOwnerOnly) {\n        owner = _owner;\n        payOwnerOnly = _payOwnerOnly;\n    }\n\n    // When the contract receives a transaction without data this is called.\n    // It counts the amount of ether it receives and stores it in\n    // accumulatedInput.\n    receive() external payable {\n        accumulatedInput += msg.value;\n    }\n\n    function payOut(address payable _recipient, uint _amount) public override returns (bool) {\n        if (msg.sender != owner || (payOwnerOnly && _recipient != owner))\n            revert();\n        (bool success,) = _recipient.call{value: _amount}(\"\");\n        if (success) {\n            emit PayOut(_recipient, _amount);\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "test/externalTests/solc-js/DAO/Token.sol",
    "content": "/*\nThis file is part of the DAO.\n\nThe DAO is free software: you can redistribute it and/or modify\nit under the terms of the GNU lesser General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThe DAO is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU lesser General Public License for more details.\n\nYou should have received a copy of the GNU lesser General Public License\nalong with the DAO.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n\n/*\nBasic, standardized Token contract with no \"premine\". Defines the functions to\ncheck token balances, send tokens, send tokens on behalf of a 3rd party and the\ncorresponding approval process. Tokens need to be created by a derived\ncontract (e.g. TokenCreation.sol).\n\nThank you ConsenSys, this contract originated from:\nhttps://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/Standard_Token.sol\nWhich is itself based on the Ethereum standardized contract APIs:\nhttps://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs\n*/\n\n/// @title Standard Token Contract.\n\nabstract contract TokenInterface {\n    mapping (address => uint256) balances;\n    mapping (address => mapping (address => uint256)) allowed;\n\n    /// Public variables of the token, all used for display\n    string public name;\n    string public symbol;\n    uint8 public decimals;\n    string public standard = 'Token 0.1';\n\n    /// Total amount of tokens\n    uint256 public totalSupply;\n\n    /// @param _owner The address from which the balance will be retrieved\n    /// @return balance The balance\n    function balanceOf(address _owner) public virtual view returns (uint256 balance);\n\n    /// @notice Send `_amount` tokens to `_to` from `msg.sender`\n    /// @param _to The address of the recipient\n    /// @param _amount The amount of tokens to be transferred\n    /// @return success Whether the transfer was successful or not\n    function transfer(address _to, uint256 _amount) public virtual returns (bool success);\n\n    /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it\n    /// is approved by `_from`\n    /// @param _from The address of the origin of the transfer\n    /// @param _to The address of the recipient\n    /// @param _amount The amount of tokens to be transferred\n    /// @return success Whether the transfer was successful or not\n    function transferFrom(address _from, address _to, uint256 _amount) public\nvirtual returns (bool success);\n\n    /// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on\n    /// its behalf\n    /// @param _spender The address of the account able to transfer the tokens\n    /// @param _amount The amount of tokens to be approved for transfer\n    /// @return success Whether the approval was successful or not\n    function approve(address _spender, uint256 _amount) public virtual returns (bool success);\n\n    /// @param _owner The address of the account owning tokens\n    /// @param _spender The address of the account able to transfer the tokens\n    /// @return remaining Amount of remaining tokens of _owner that _spender is allowed\n    /// to spend\n    function allowance(\n        address _owner,\n        address _spender\n    ) public virtual view returns (uint256 remaining);\n\n    event Transfer(address indexed _from, address indexed _to, uint256 _amount);\n    event Approval(\n        address indexed _owner,\n        address indexed _spender,\n        uint256 _amount\n    );\n}\n\nabstract contract tokenRecipient {\n    function receiveApproval(address _from, uint256 _value, address _token, bytes memory _extraData) public virtual;\n}\n\ncontract Token is TokenInterface {\n    // Protects users by preventing the execution of method calls that\n    // inadvertently also transferred ether\n    modifier noEther() {if (msg.value > 0) revert(); _; }\n\n    function balanceOf(address _owner) public override view returns (uint256 balance) {\n        return balances[_owner];\n    }\n\n    function transfer(address _to, uint256 _amount) public virtual override returns (bool success) {\n        if (balances[msg.sender] >= _amount && _amount > 0) {\n            balances[msg.sender] -= _amount;\n            balances[_to] += _amount;\n            emit Transfer(msg.sender, _to, _amount);\n            return true;\n        } else {\n           return false;\n        }\n    }\n\n    function transferFrom(\n        address _from,\n        address _to,\n        uint256 _amount\n    ) public virtual override returns (bool success) {\n\n        if (balances[_from] >= _amount\n            && allowed[_from][msg.sender] >= _amount\n            && _amount > 0) {\n\n            balances[_to] += _amount;\n            balances[_from] -= _amount;\n            allowed[_from][msg.sender] -= _amount;\n            emit Transfer(_from, _to, _amount);\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    function approve(address _spender, uint256 _amount) public override returns (bool success) {\n        allowed[msg.sender][_spender] = _amount;\n        emit Approval(msg.sender, _spender, _amount);\n        return true;\n    }\n\n    /// Allow another contract to spend some tokens in your behalf\n    function approveAndCall(address _spender, uint256 _value, bytes memory _extraData)\n        public returns (bool success) {\n        allowed[msg.sender][_spender] = _value;\n        tokenRecipient spender = tokenRecipient(_spender);\n        spender.receiveApproval(msg.sender, _value, address(this), _extraData);\n        return true;\n    }\n\n    function allowance(address _owner, address _spender) public override view returns (uint256 remaining) {\n        return allowed[_owner][_spender];\n    }\n}\n"
  },
  {
    "path": "test/externalTests/solc-js/DAO/TokenCreation.sol",
    "content": "/*\nThis file is part of the DAO.\n\nThe DAO is free software: you can redistribute it and/or modify\nit under the terms of the GNU lesser General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThe DAO is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU lesser General Public License for more details.\n\nYou should have received a copy of the GNU lesser General Public License\nalong with the DAO.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n\n/*\n * Token Creation contract, used by the DAO to create its tokens and initialize\n * its ether. Feel free to modify the divisor method to implement different\n * Token Creation parameters\n*/\n\nimport \"./Token.sol\";\nimport \"./ManagedAccount.sol\";\n\nabstract contract TokenCreationInterface {\n\n    // End of token creation, in Unix time\n    uint public closingTime;\n    // Minimum fueling goal of the token creation, denominated in tokens to\n    // be created\n    uint public minTokensToCreate;\n    // True if the DAO reached its minimum fueling goal, false otherwise\n    bool public isFueled;\n    // For DAO splits - if privateCreation is 0, then it is a public token\n    // creation, otherwise only the address stored in privateCreation is\n    // allowed to create tokens\n    address public privateCreation;\n    // hold extra ether which has been sent after the DAO token\n    // creation rate has increased\n    ManagedAccount public extraBalance;\n    // tracks the amount of wei given from each contributor (used for refund)\n    mapping (address => uint256) weiGiven;\n\n    /// @dev Constructor setting the minimum fueling goal and the\n    /// end of the Token Creation\n    /// @param _minTokensToCreate Minimum fueling goal in number of\n    ///        Tokens to be created\n    /// @param _closingTime Date (in Unix time) of the end of the Token Creation\n    /// @param _privateCreation Zero means that the creation is public.  A\n    /// non-zero address represents the only address that can create Tokens\n    /// (the address can also create Tokens on behalf of other accounts)\n    // This is the constructor: it can not be overloaded so it is commented out\n    //  function TokenCreation(\n        //  uint _minTokensTocreate,\n        //  uint _closingTime,\n        //  address _privateCreation\n        //  string _tokenName,\n        //  string _tokenSymbol,\n        //  uint _decimalPlaces\n    //  );\n\n    /// @notice Create Token with `_tokenHolder` as the initial owner of the Token\n    /// @param _tokenHolder The address of the Tokens's recipient\n    /// @return success Whether the token creation was successful\n    function createTokenProxy(address payable _tokenHolder) payable virtual public returns (bool success);\n\n    /// @notice Refund `msg.sender` in the case the Token Creation did\n    /// not reach its minimum fueling goal\n    function refund() virtual public;\n\n    /// @return divisor The divisor used to calculate the token creation rate during\n    /// the creation phase\n    function divisor() public virtual view returns (uint divisor);\n\n    event FuelingToDate(uint value);\n    event CreatedToken(address indexed to, uint amount);\n    event Refund(address indexed to, uint value);\n}\n\n\ncontract TokenCreation is TokenCreationInterface, Token {\n    constructor(\n        uint _minTokensToCreate,\n        uint _closingTime,\n        address _privateCreation,\n        string memory _tokenName,\n        string memory _tokenSymbol,\n        uint8 _decimalPlaces) public {\n\n        closingTime = _closingTime;\n        minTokensToCreate = _minTokensToCreate;\n        privateCreation = _privateCreation;\n        extraBalance = new ManagedAccount(address(this), true);\n        name = _tokenName;\n        symbol = _tokenSymbol;\n        decimals = _decimalPlaces;\n\n    }\n\n    function createTokenProxy(address payable _tokenHolder) payable public\noverride returns (bool success) {\n        if (block.timestamp < closingTime && msg.value > 0\n            && (privateCreation == 0x0000000000000000000000000000000000000000 || privateCreation == msg.sender)) {\n\n            uint token = (msg.value * 20) / divisor();\n            address(extraBalance).call{value: msg.value - token}(\"\");\n            balances[_tokenHolder] += token;\n            totalSupply += token;\n            weiGiven[_tokenHolder] += msg.value;\n            emit CreatedToken(_tokenHolder, token);\n            if (totalSupply >= minTokensToCreate && !isFueled) {\n                isFueled = true;\n                emit FuelingToDate(totalSupply);\n            }\n            return true;\n        }\n        revert();\n    }\n\n    function refund() public override {\n        if (block.timestamp > closingTime && !isFueled) {\n            // Get extraBalance - will only succeed when called for the first time\n            if (address(extraBalance).balance >= extraBalance.accumulatedInput())\n                extraBalance.payOut(payable(this), extraBalance.accumulatedInput());\n\n            // Execute refund\n            (bool success,) = msg.sender.call{value: weiGiven[msg.sender]}(\"\");\n            if (success) {\n                emit Refund(msg.sender, weiGiven[msg.sender]);\n                totalSupply -= balances[msg.sender];\n                balances[msg.sender] = 0;\n                weiGiven[msg.sender] = 0;\n            }\n        }\n    }\n\n    function divisor() public override view returns (uint divisor) {\n        // The number of (base unit) tokens per wei is calculated\n        // as `msg.value` * 20 / `divisor`\n        // The fueling period starts with a 1:1 ratio\n        if (closingTime - 2 weeks > block.timestamp) {\n            return 20;\n        // Followed by 10 days with a daily creation rate increase of 5%\n        } else if (closingTime - 4 days > block.timestamp) {\n            return (20 + (block.timestamp - (closingTime - 2 weeks)) / (1 days));\n        // The last 4 days there is a constant creation rate ratio of 1:1.5\n        } else {\n            return 30;\n        }\n    }\n    receive() external virtual payable {\n    }\n}\n"
  },
  {
    "path": "test/externalTests/solc-js/asm-json.js",
    "content": "const tape = require('tape');\nconst fs = require('fs');\nconst solc = require('../index.js');\n\ntape('ASM Json output consistency', function (t) {\n    t.test('Nested structure', function(st) {\n        const testdir = 'test/';\n        const output = JSON.parse(solc.compile(JSON.stringify({\n            language: 'Solidity',\n            settings: {\n                viaIR: true,\n                outputSelection: {\n                    '*': {\n                        '*': ['evm.legacyAssembly']\n                    }\n                }\n            },\n            sources: {\n                C: {\n                    content: fs.readFileSync(testdir + 'code_access_runtime.sol', 'utf8')\n                }\n            }\n        })));\n        st.ok(output);\n\n        function containsAssemblyItem(assemblyJSON, assemblyItem) {\n            if (Array.isArray(assemblyJSON))\n                return assemblyJSON.some(item => containsAssemblyItem(item, assemblyItem));\n            else if (typeof assemblyJSON === 'object' && assemblyJSON !== null) {\n                if (assemblyJSON.name === assemblyItem.name && assemblyJSON.value === assemblyItem.value)\n                    return true;\n                return Object.values(assemblyJSON).some(value => containsAssemblyItem(value, assemblyItem));\n            }\n            return false;\n        }\n\n        // regression test that there is indeed a negative subassembly index in there\n        // and it is based on a 64 bit uint\n        const targetObject = {\n            \"name\": \"PUSH #[$]\",\n            \"value\": \"000000000000000000000000000000000000000000000000ffffffffffffffff\"\n        };\n        st.equal(containsAssemblyItem(output[\"contracts\"][\"C\"][\"C\"][\"evm\"][\"legacyAssembly\"], targetObject), true)\n    });\n});\n"
  },
  {
    "path": "test/externalTests/solc-js/determinism.js",
    "content": "const tape = require('tape');\nconst fs = require('fs');\nconst solc = require('../index.js');\n\ntape('Deterministic Compilation', function (t) {\n  t.test('DAO', function (st) {\n    const input = {};\n    let prevBytecode = null;\n    const testdir = 'test/DAO/';\n    const files = ['DAO.sol', 'Token.sol', 'TokenCreation.sol', 'ManagedAccount.sol'];\n    let i;\n    for (i in files) {\n      const file = files[i];\n      input[file] = { content: fs.readFileSync(testdir + file, 'utf8') };\n    }\n    for (i = 0; i < 10; i++) {\n      const output = JSON.parse(solc.compile(JSON.stringify({\n        language: 'Solidity',\n        settings: {\n          optimizer: {\n            enabled: true\n          },\n          outputSelection: {\n            '*': {\n              '*': ['evm.bytecode']\n            }\n          }\n        },\n        sources: input\n      })));\n      st.ok(output);\n      st.ok(output.contracts);\n      st.ok(output.contracts['DAO.sol']);\n      st.ok(output.contracts['DAO.sol'].DAO);\n      st.ok(output.contracts['DAO.sol'].DAO.evm.bytecode.object);\n      const bytecode = output.contracts['DAO.sol'].DAO.evm.bytecode.object;\n      st.ok(bytecode.length > 0);\n      if (prevBytecode !== null) {\n        st.equal(prevBytecode, bytecode);\n      }\n      prevBytecode = bytecode;\n    }\n    st.end();\n  });\n});\n"
  },
  {
    "path": "test/externalTests/solc-js/solc-js.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2019 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nSOLJSON=\"$1\"\nVERSION=\"$2\"\nSOLCJS_CHECKOUT=\"$3\" # optional\n\n[[ $SOLJSON != \"\" && -f \"$SOLJSON\" && $VERSION != \"\" ]] || fail \"Usage: $0 <path to soljson.js> <version> [<path to solc-js>]\"\n\nfunction solcjs_test\n{\n    TEST_DIR=$(pwd)\n    SOLCJS_INPUT_DIR=\"$TEST_DIR\"/test/externalTests/solc-js\n\n    # set up solc-js on the branch specified\n    setup_solc \"$DIR\" solcjs \"$SOLJSON\" master solc/ \"$SOLCJS_CHECKOUT\"\n    cd solc/\n\n    printLog \"Updating index.js file...\"\n    echo \"require('./determinism.js');\" >> test/index.js\n\n    printLog \"Copying determinism.js...\"\n    cp -f \"$SOLCJS_INPUT_DIR/determinism.js\" test/\n\n    printLog \"Copying contracts...\"\n    cp -Rf \"$SOLCJS_INPUT_DIR/DAO\" test/\n\n    printLog \"Copying test with non-zero subassembly access\"\n    cp -f \"$TEST_DIR\"/test/libsolidity/semanticTests/various/code_access_runtime.sol test/\n\n    printLog \"Copying SMTChecker tests...\"\n    # We do not copy all tests because that takes too long.\n    cp -Rf \"$TEST_DIR\"/test/libsolidity/smtCheckerTests/external_calls test/smtCheckerTests/\n    cp -Rf \"$TEST_DIR\"/test/libsolidity/smtCheckerTests/loops test/smtCheckerTests/\n    cp -Rf \"$TEST_DIR\"/test/libsolidity/smtCheckerTests/invariants test/smtCheckerTests/\n\n    # Update version (needed for some tests)\n    echo \"Updating package.json to version $VERSION\"\n    npm version --allow-same-version --no-git-tag-version \"$VERSION\"\n\n    replace_version_pragmas\n\n    printLog \"Running test function...\"\n    npm test\n}\n\nexternal_test solc-js solcjs_test\n"
  },
  {
    "path": "test/externalTests/trident.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2021 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { yarn build; }\n\nfunction test_fn {\n    # shellcheck disable=SC2046\n    TS_NODE_TRANSPILE_ONLY=1 npx hardhat test --no-compile $(\n        # TODO: We need to skip Migration.test.ts because it fails and makes other tests fail too.\n        # Replace this with `yarn test` once https://github.com/sushiswap/trident/issues/283 is fixed.\n        find test/ -name \"*.test.ts\" ! -path \"test/Migration.test.ts\" | LC_ALL=C sort\n    )\n}\n\nfunction trident_test\n{\n    local repo=\"https://github.com/sushiswap/trident\"\n    # FIXME: Switch back to master branch when https://github.com/sushiswap/trident/issues/303 gets fixed.\n    local ref=\"0cab5ae884cc9a41223d52791be775c3a053cb26\" # master as of 2021-12-16\n    local config_file=\"hardhat.config.ts\"\n    local config_var=config\n\n    local compile_only_presets=()\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        ir-no-optimize\n        ir-optimize-evm-only\n        ir-optimize-evm+yul        # Needs memory-safe inline assembly patch\n        legacy-no-optimize\n        legacy-optimize-evm-only\n        legacy-optimize-evm+yul\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n\n    # TODO: Currently tests work only with the exact versions from yarn.lock.\n    # Re-enable this when https://github.com/sushiswap/trident/issues/284 is fixed.\n    #neutralize_package_lock\n\n    neutralize_package_json_hooks\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\" \"$config_var\"\n    yarn install\n\n    replace_version_pragmas\n    force_solc_modules \"${DIR}/solc\"\n\n    # BentoBoxV1Flat.sol requires a few small tweaks to compile on 0.8.x.\n    # TODO: Remove once https://github.com/sushiswap/trident/pull/282 gets merged.\n    sed -i 's|uint128(-1)|type(uint128).max|g' contracts/flat/BentoBoxV1Flat.sol\n    sed -i 's|uint64(-1)|type(uint64).max|g' contracts/flat/BentoBoxV1Flat.sol\n    sed -i 's|uint32(-1)|type(uint32).max|g' contracts/flat/BentoBoxV1Flat.sol\n    sed -i 's|IERC20(0)|IERC20(address(0))|g' contracts/flat/BentoBoxV1Flat.sol\n    sed -i 's|IStrategy(0)|IStrategy(address(0))|g' contracts/flat/BentoBoxV1Flat.sol\n    find contracts -name \"*.sol\" -exec sed -i -e 's/^\\(\\s*\\)\\(assembly\\)/\\1\\/\\/\\/ @solidity memory-safe-assembly\\n\\1\\2/' '{}' \\;\n\n    # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed.\n    sed -i 's|it\\((\"Reverts on direct deployment via factory\"\\)|it.skip\\1|g' test/MasterDeployer.test.ts\n\n    # @sushiswap/core package contains contracts that get built with 0.6.12 and fail our compiler\n    # version check. It's not used by tests so we can remove it.\n    rm -r node_modules/@sushiswap/core/\n\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn \"$config_var\"\n        store_benchmark_report hardhat trident \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test Trident trident_test\n"
  },
  {
    "path": "test/externalTests/uniswap.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2022 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { yarn compile; }\nfunction test_fn { UPDATE_SNAPSHOT=1 npx hardhat test; }\n\nfunction uniswap_test\n{\n    local repo=\"https://github.com/solidity-external-tests/uniswap-v3-core.git\"\n    local ref=main_080\n    local config_file=\"hardhat.config.ts\"\n    local config_var=config\n\n    local compile_only_presets=()\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        ir-no-optimize\n        ir-optimize-evm-only\n        ir-optimize-evm+yul\n        legacy-no-optimize\n        legacy-optimize-evm-only\n        legacy-optimize-evm+yul\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n\n    # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables\n    # them for other presets but that's fine - we want same code run for benchmarks to be comparable.\n    # TODO: Remove this when https://github.com/NomicFoundation/hardhat/issues/3365 gets fixed.\n    sed -i \"s|it\\(('underpay zero for one and exact in',\\)|it.skip\\1|g\" test/UniswapV3Pool.spec.ts\n    sed -i \"s|it\\(('pay in the wrong token zero for one and exact in',\\)|it.skip\\1|g\" test/UniswapV3Pool.spec.ts\n    sed -i \"s|it\\(('underpay zero for one and exact out',\\)|it.skip\\1|g\" test/UniswapV3Pool.spec.ts\n    sed -i \"s|it\\(('pay in the wrong token zero for one and exact out',\\)|it.skip\\1|g\" test/UniswapV3Pool.spec.ts\n    sed -i \"s|it\\(('underpay one for zero and exact in',\\)|it.skip\\1|g\" test/UniswapV3Pool.spec.ts\n    sed -i \"s|it\\(('pay in the wrong token one for zero and exact in',\\)|it.skip\\1|g\" test/UniswapV3Pool.spec.ts\n    sed -i \"s|it\\(('underpay one for zero and exact out',\\)|it.skip\\1|g\" test/UniswapV3Pool.spec.ts\n    sed -i \"s|it\\(('pay in the wrong token one for zero and exact out',\\)|it.skip\\1|g\" test/UniswapV3Pool.spec.ts\n\n    neutralize_package_json_hooks\n    name_hardhat_default_export \"$config_file\" \"$config_var\"\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\" \"$config_var\"\n    force_hardhat_unlimited_contract_size \"$config_file\" \"$config_var\"\n\n    # Force latest versions of everything except Hardhat and some of its dependencies.\n    # - Hardhat 2.2.0 pulled in by yarn.lock is too old because it can't decode Panics caused by overflow/underflow.\n    # - Hardhat 2.5.0+ won't work because of error messages hard-coded in test expectations. E.g.\n    #   \"revert SPL\" is expected but the message is \"reverted with reason string 'SPL'\" in 2.5.0.\n    # - Newer versions of ethereumjs/tx have an issue with 'gteHardfork()' method.\n    neutralize_package_lock\n\n    pnpm install\n    pnpm install hardhat-gas-reporter\n\n    # With ethers.js 5.6.2 many tests for revert messages fail.\n    # TODO: Remove when https://github.com/ethers-io/ethers.js/discussions/2849 is resolved.\n    pnpm install ethers@5.6.1\n\n    pnpm install hardhat\n\n    replace_version_pragmas\n\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn \"$config_var\"\n        store_benchmark_report hardhat uniswap \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test Uniswap-V3 uniswap_test\n"
  },
  {
    "path": "test/externalTests/yield-liquidator.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2022 solidity contributors.\n#------------------------------------------------------------------------------\n\nset -e\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { npm run build; }\nfunction test_fn { npm run test; }\n\nfunction yield_liquidator_test\n{\n    local repo=\"https://github.com/yieldprotocol/yield-liquidator-v2\"\n    local ref=\"master\"\n    local config_file=\"hardhat.config.ts\"\n    local config_var=\"module.exports\"\n\n    local compile_only_presets=()\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        ir-no-optimize\n        ir-optimize-evm-only\n        ir-optimize-evm+yul\n        legacy-optimize-evm-only\n        legacy-optimize-evm+yul\n        legacy-no-optimize\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n\n    neutralize_package_lock\n    neutralize_package_json_hooks\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\" \"$config_var\"\n    force_hardhat_unlimited_contract_size \"$config_file\" \"$config_var\"\n    # TODO: Remove after https://github.com/Uniswap/sdks/issues/557 is resolved\n    # Pin broken @uniswap/* packages via overrides. The following versions were published with\n    # 'workspace:*' deps that npm cannot resolve (EUNSUPPORTEDPROTOCOL), causing a silent exit-1:\n    #   @uniswap/v3-sdk@3.29.2  (via smart-order-router -> ^3.7.0)\n    #   @uniswap/v4-sdk@1.29.2  (via smart-order-router -> router-sdk -> ^1.20.0)\n    #   @uniswap/v2-sdk@4.19.2  (via smart-order-router -> router-sdk -> ^4.14.0)\n    # Cannot just run npm install with unbroken version because these are indirect dependencies.\n    node -e \"\n        const fs = require('fs');\n        const p = JSON.parse(fs.readFileSync('package.json'));\n        p.overrides = Object.assign(p.overrides || {}, {\n            '@uniswap/v3-sdk': '3.29.1',\n            '@uniswap/v4-sdk': '1.29.1',\n            '@uniswap/v2-sdk': '4.19.1',\n        });\n        fs.writeFileSync('package.json', JSON.stringify(p, null, 2));\n    \"\n    npm install\n\n    # The contract below is not used in any test and it depends on ISwapRouter which does not exists\n    # in the main repository.\n    # See: https://github.com/yieldprotocol/yield-liquidator-v2/blob/9a49d9a0e9398f6a6c07bad531e77d1001a1166f/src/swap_router.rs#L94\n    rm --force contracts/.YvBasicFlashLiquidator.sol\n\n    replace_version_pragmas\n    neutralize_packaged_contracts\n\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn \"$config_var\"\n        store_benchmark_report hardhat yield_liquidator \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test Yield-Liquidator-V2 yield_liquidator_test\n"
  },
  {
    "path": "test/externalTests/zeppelin.sh",
    "content": "#!/usr/bin/env bash\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2019 solidity contributors.\n#------------------------------------------------------------------------------\n\n# Disable shellcheck errors on quoted special chars like backticks. Too many false-positives.\n# shellcheck disable=SC2016\n\nset -e\n# Temporary(?) fix to up the heap limit for node in order to prevent 'out of heap errors'\nexport NODE_OPTIONS=\"--max-old-space-size=4096\"\n\nsource scripts/common.sh\nsource scripts/externalTests/common.sh\n\nREPO_ROOT=$(realpath \"$(dirname \"$0\")/../..\")\n\nverify_input \"$@\"\nBINARY_TYPE=\"$1\"\nBINARY_PATH=\"$(realpath \"$2\")\"\nSELECTED_PRESETS=\"$3\"\n\nfunction compile_fn { npm run compile; }\nfunction test_fn { npm test; }\n\nfunction zeppelin_test\n{\n    local repo=\"https://github.com/OpenZeppelin/openzeppelin-contracts.git\"\n    local ref=\"<latest-release>\"\n    local config_file=\"hardhat.config.js\"\n\n    local compile_only_presets=(\n        #ir-no-optimize           # Compilation fails with \"Contract initcode size is 49410 bytes and exceeds 49152 bytes (a limit introduced in Shanghai).\"\n        ir-optimize-evm-only      # FIXME: A few tests fail with \"Transaction: ... exited with an error (status 0) after consuming all gas.\"\n)\n    local settings_presets=(\n        \"${compile_only_presets[@]}\"\n        ir-optimize-evm+yul\n        #legacy-no-optimize       # FIXME: Fails with stack too deep\n        #legacy-optimize-evm-only # FIXME: Fails with stack too deep\n        legacy-optimize-evm+yul\n    )\n\n    [[ $SELECTED_PRESETS != \"\" ]] || SELECTED_PRESETS=$(circleci_select_steps_multiarg \"${settings_presets[@]}\")\n    print_presets_or_exit \"$SELECTED_PRESETS\"\n\n    setup_solc \"$DIR\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    download_project \"$repo\" \"$ref\" \"$DIR\"\n\n    # Disable tests that won't pass on the ir presets due to Hardhat heuristics. Note that this also disables\n    # them for other presets but that's fine - we want same code run for benchmarks to be comparable.\n    # TODO: Remove the lines below when Hardhat adjusts heuristics for IR (https://github.com/nomiclabs/hardhat/issues/3750).\n    sed -i \"s|it(\\('proxy admin cannot call delegated functions',\\)|it.skip(\\1|g\" test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js\n    sed -i \"s|describe(\\('when the given implementation is the zero address'\\)|describe.skip(\\1|g\" test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js\n    sed -i \"s|describe(\\('when the new proposed admin is the zero address'\\)|describe.skip(\\1|g\" test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js\n    # In some cases Hardhat does not detect revert reasons properly via IR.\n    sed -i \"s|it(\\('prevent unauthorized maintenance'\\)|it.skip(\\1|g\" test/governance/TimelockController.test.js\n    sed -i \"s|it(\\('cannot cancel invalid operation'\\)|it.skip(\\1|g\" test/governance/TimelockController.test.js\n    sed -i \"s|it(\\('cannot call onlyInitializable function outside the scope of an initializable function'\\)|it.skip(\\1|g\" test/proxy/utils/Initializable.test.js\n    sed -i \"s|it(\\('reverts when sending non-zero amounts'\\)|it.skip(\\1|g\" test/utils/Address.test.js\n    sed -i \"s|it(\\('reverts when sending more than the balance'\\)|it.skip(\\1|g\" test/utils/Address.test.js\n    sed -i \"s|it(\\('fails deploying a contract if the bytecode length is zero'\\)|it.skip(\\1|g\" test/utils/Create2.test.js\n    sed -i \"s|it(\\('fails deploying a contract if factory contract does not have sufficient balance'\\)|it.skip(\\1|g\" test/utils/Create2.test.js\n    sed -i \"s|it(\\('reverts when casting -1'\\)|it.skip(\\1|g\" test/utils/math/SafeCast.test.js\n    sed -i 's|it(\\(`reverts when casting [^`]\\+`\\)|it.skip(\\1|g' test/utils/math/SafeCast.test.js\n    sed -i \"s|it(\\('reverts if index is greater than supply'\\)|it.skip(\\1|g\" test/token/ERC721/ERC721.behavior.js\n    sed -i \"s|it(\\('burns all tokens'\\)|it.skip(\\1|g\" test/token/ERC721/ERC721.behavior.js\n    sed -i \"s|it(\\('guards transfer against invalid user'\\)|it.skip(\\1|g\" test/access/Ownable2Step.test.js\n    sed -i \"s|it(\\('reverting initialization function'\\)|it.skip(\\1|g\" test/proxy/beacon/BeaconProxy.test.js\n    sed -i \"s|describe(\\('reverting initialization'\\)|describe.skip(\\1|g\" test/proxy/Proxy.behaviour.js\n    sed -i \"s|it(\\('does not allow remote callback'\\)|it.skip(\\1|g\" test/utils/ReentrancyGuard.test.js\n\n    # TODO: Remove when hardhat properly handle reverts of custom errors with via-ir enabled\n    # and/or open-zeppelin fix https://github.com/OpenZeppelin/openzeppelin-contracts/issues/4349\n    sed -i \"s|it(\\('cannot nest reinitializers'\\)|it.skip(\\1|g\" test/proxy/utils/Initializable.test.js\n    sed -i \"s|it(\\('prevents re-initialization'\\)|it.skip(\\1|g\" test/proxy/utils/Initializable.test.js\n    sed -i \"s|it(\\('can lock contract after initialization'\\)|it.skip(\\1|g\" test/proxy/utils/Initializable.test.js\n    sed -i \"s|it(\\('calling upgradeTo on the implementation reverts'\\)|it.skip(\\1|g\" test/proxy/utils/UUPSUpgradeable.test.js\n    sed -i \"s|it(\\('calling upgradeToAndCall on the implementation reverts'\\)|it.skip(\\1|g\" test/proxy/utils/UUPSUpgradeable.test.js\n    sed -i \"s|it(\\('calling upgradeTo from a contract that is not an ERC1967 proxy\\)|it.skip(\\1|g\" test/proxy/utils/UUPSUpgradeable.test.js\n    sed -i \"s|it(\\('calling upgradeToAndCall from a contract that is not an ERC1967 proxy\\)|it.skip(\\1|g\" test/proxy/utils/UUPSUpgradeable.test.js\n    sed -i \"s|it(\\('rejects overflow'\\)|it.skip(\\1|g\" test/token/ERC20/ERC20.test.js\n    sed -i \"s|it(\\('decimals overflow'\\)|it.skip(\\1|g\" test/token/ERC20/extensions/ERC4626.test.js\n\n    # Here only the testToInt(248) and testToInt(256) cases fail so change the loop range to skip them\n    sed -i \"s|range(8, 256, 8)\\(.forEach(bits => testToInt(bits));\\)|range(8, 240, 8)\\1|\" test/utils/math/SafeCast.test.js\n\n    # TODO: Remove when next hardhat version releases, the fix is already merged: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5663\n    # Fails with ProviderError: Invalid transaction: GasFloorMoreThanGasLimit\n    sed -i \"177s|+ 2_000n|+ 10_000n|\" test/metatx/ERC2771Forwarder.test.js\n\n    # Fails under evmVersion=osaka, likely due to transaction gas limits introduced by EIP-7825 or by the modexp upper bound EIP-7823.\n    sed -i \"s|describe(\\('RSA'\\)|describe.skip(\\1|g\" test/utils/cryptography/RSA.test.js\n\n    cat <<-EOF >> \"$config_file\"\n    const { TASK_COMPILE_SOLIDITY_COMPILE } = require(\"hardhat/builtin-tasks/task-names\");\n\n    task(TASK_COMPILE_SOLIDITY_COMPILE)\n        .setAction(async (args, hre, runSuper) => {\n            const result = await runSuper(args);\n\n            result.output.errors = (result.output.errors || []).filter(err => {\n                if (err.severity === \"warning\" && err.message.includes(\"deprecated\")) {\n                    return false; // suppress this warning\n                }\n                return true;\n            });\n\n            return result;\n        });\n\nEOF\n\n    neutralize_package_json_hooks\n    force_hardhat_compiler_binary \"$config_file\" \"$BINARY_TYPE\" \"$BINARY_PATH\"\n    force_hardhat_compiler_settings \"$config_file\" \"$(first_word \"$SELECTED_PRESETS\")\"\n    npm install\n    npm install hardhat\n\n    replace_version_pragmas\n    for preset in $SELECTED_PRESETS; do\n        hardhat_run_test \"$config_file\" \"$preset\" \"${compile_only_presets[*]}\" compile_fn test_fn\n        store_benchmark_report hardhat zeppelin \"$repo\" \"$preset\"\n    done\n}\n\nexternal_test Zeppelin zeppelin_test\n"
  },
  {
    "path": "test/external_tests.py",
    "content": "#!/usr/bin/env python3\n\n# ------------------------------------------------------------------------------\n# This file is part of solidity.\n#\n# solidity is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# solidity is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with solidity.  If not, see <http://www.gnu.org/licenses/>\n#\n# (c) 2023 solidity contributors.\n# ------------------------------------------------------------------------------\n\nfrom argparse import ArgumentParser, Namespace\nimport os\nfrom pathlib import Path\nimport sys\nimport subprocess\n\nEXTERNAL_TESTS_DIR = Path(__file__).parent / \"externalTests\"\n\n\nclass ExternalTestNotFound(Exception):\n    pass\n\n\ndef detect_external_tests() -> dict:\n    return {\n        file_path.stem: file_path\n        for file_path in Path(EXTERNAL_TESTS_DIR).iterdir()\n        if file_path.is_file() and file_path.suffix in (\".sh\", \".py\")\n    }\n\n\ndef display_available_external_tests(_):\n    print(\"Available external tests:\")\n    print(*detect_external_tests().keys())\n\n\ndef run_test_scripts(solc_binary_type: str, solc_binary_path: Path, tests: dict):\n    for test_name, test_script_path in tests.items():\n        print(f\"Running {test_name} external test...\")\n        subprocess.run(\n            [test_script_path, solc_binary_type, solc_binary_path],\n            check=True\n        )\n\n\ndef run_external_tests(args: dict):\n    solc_binary_type = args[\"solc_binary_type\"]\n    solc_binary_path = args[\"solc_binary_path\"]\n\n    all_test_scripts = detect_external_tests()\n    selected_tests = args[\"selected_tests\"]\n    if args[\"run_all\"]:\n        assert len(selected_tests) == 0\n        run_test_scripts(solc_binary_type, solc_binary_path, all_test_scripts)\n        return\n\n    if len(selected_tests) == 0:\n        raise ExternalTestNotFound(\n            \"External test was not selected. Please use --run or --run-all option\"\n        )\n\n    unrecognized_tests = set(selected_tests) - set(all_test_scripts.keys())\n    if unrecognized_tests != set():\n        raise ExternalTestNotFound(\n            f\"External test(s) not found: {', '.join(unrecognized_tests)}\"\n        )\n    run_test_scripts(\n        solc_binary_type,\n        solc_binary_path,\n        {k: all_test_scripts[k] for k in selected_tests},\n    )\n\n\ndef parse_commandline() -> Namespace:\n    script_description = \"Script to run external Solidity tests.\"\n\n    parser = ArgumentParser(description=script_description)\n    subparser = parser.add_subparsers()\n    list_command = subparser.add_parser(\n        \"list\",\n        help=\"List all available external tests.\",\n    )\n    list_command.set_defaults(cmd=display_available_external_tests)\n\n    run_command = subparser.add_parser(\n        \"test\",\n        help=\"Run external tests.\",\n    )\n    run_command.set_defaults(cmd=run_external_tests)\n\n    run_command.add_argument(\n        \"--solc-binary-type\",\n        dest=\"solc_binary_type\",\n        type=str,\n        required=True,\n        choices=[\"native\", \"solcjs\"],\n        help=\"Type of the solidity compiler binary to be used.\",\n    )\n    run_command.add_argument(\n        \"--solc-binary-path\",\n        dest=\"solc_binary_path\",\n        type=Path,\n        required=True,\n        help=\"Path to the solidity compiler binary.\",\n    )\n\n    running_mode = run_command.add_mutually_exclusive_group()\n    running_mode.add_argument(\n        \"--run\",\n        metavar=\"TEST_NAME\",\n        dest=\"selected_tests\",\n        nargs=\"+\",\n        default=[],\n        help=\"List of one or more external tests to run (separated by sapce).\",\n    )\n    running_mode.add_argument(\n        \"--run-all\",\n        dest=\"run_all\",\n        default=False,\n        action=\"store_true\",\n        help=\"Run all available external tests.\",\n    )\n\n    return parser.parse_args()\n\n\ndef main():\n    try:\n        args = parse_commandline()\n        args.cmd(vars(args))\n        return os.EX_OK\n    except ExternalTestNotFound as exception:\n        print(f\"Error: {exception}\", file=sys.stderr)\n        return os.EX_NOINPUT\n    except RuntimeError as exception:\n        print(f\"Error: {exception}\", file=sys.stderr)\n        return 1\n\n\nif __name__ == \"__main__\":\n    sys.exit(main())\n"
  },
  {
    "path": "test/formal/README.md",
    "content": "The Solidity compiler implements several [optimization rules](https://github.com/argotorg/solidity/blob/develop/libevmasm/RuleList.h).\n\nThis directory contains an effort to formally prove the correctness of those rules in:\n\n- HOL with [EthIsabelle](https://github.com/ekpyron/eth-isabelle)\n- FOL with SMT solvers using [Integers and BitVectors](http://smtlib.cs.uiowa.edu/theories.shtml)\n"
  },
  {
    "path": "test/formal/and_distributed_over_shl.py",
    "content": "from opcodes import AND, SHL\nfrom rule import Rule\nfrom z3 import BitVec\n\n\"\"\"\nRule:\nAND(SHL(Z,X), SHL(Z,Y)) -> SHL(Z, AND(X,Y))\n\"\"\"\n\nrule = Rule()\n\nn_bits = 128\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\nZ = BitVec('Z', n_bits)\n\n# Non optimized result\nnonopt = AND(SHL(Z,X), SHL(Z,Y))\n\n# Optimized result\nopt = SHL(Z, AND(X,Y))\n\nrule.check(nonopt, opt)\n"
  },
  {
    "path": "test/formal/byte_big.py",
    "content": "from opcodes import BYTE\nfrom rule import Rule\nfrom z3 import BitVec\n\n\"\"\"\nbyte(A, X) -> 0\ngiven A >= WordSize / 8\n\"\"\"\n\nrule = Rule()\n\nn_bits = 256\n\n# Input vars\nX = BitVec('X', n_bits)\nA = BitVec('A', n_bits)\n\nrule.require(A >= n_bits / 8)\nrule.check(BYTE(A, X), 0)\n"
  },
  {
    "path": "test/formal/byte_equivalence.py",
    "content": "from opcodes import BYTE\nfrom rule import Rule\nfrom z3 import BitVec, BitVecVal, Concat, Extract\n\n\"\"\"\nChecks that the byte opcode (implemented using shift) is equivalent to a\ncanonical definition of byte using extract.\n\"\"\"\n\nrule = Rule()\n\nn_bits = 256\nx = BitVec('X', n_bits)\n\nfor i in range(0, 32):\n    # For Byte, i = 0 corresponds to most significant bit\n    # But for extract i = 0 corresponds to the least significant bit\n    lsb = 31 - i\n    rule.check(\n        BYTE(BitVecVal(i, n_bits), x),\n        Concat(BitVecVal(0, n_bits - 8), Extract(8 * lsb + 7, 8 * lsb, x))\n    )\n"
  },
  {
    "path": "test/formal/checked_int_add.py",
    "content": "from opcodes import AND, ISZERO, SGT, SLT, ADD\nfrom rule import Rule\nfrom util import BVSignedMax, BVSignedMin, BVSignedUpCast\nfrom z3 import BitVec, BVAddNoOverflow, BVAddNoUnderflow, Not\n\n\"\"\"\nOverflow checked signed integer addition.\n\"\"\"\n\nn_bits = 256\ntype_bits = 8\n\nwhile type_bits <= n_bits:\n\n\trule = Rule()\n\n\t# Input vars\n\tX_short = BitVec('X', type_bits)\n\tY_short = BitVec('Y', type_bits)\n\n\t# Z3's overflow and underflow conditions\n\tactual_overflow = Not(BVAddNoOverflow(X_short, Y_short, True))\n\tactual_underflow = Not(BVAddNoUnderflow(X_short, Y_short))\n\n\t# cast to full n_bits values\n\tX = BVSignedUpCast(X_short, n_bits)\n\tY = BVSignedUpCast(Y_short, n_bits)\n\tsum_ = ADD(X, Y)\n\n\t# Constants\n\tmaxValue = BVSignedMax(type_bits, n_bits)\n\tminValue = BVSignedMin(type_bits, n_bits)\n\n\t# Overflow and underflow checks in YulUtilFunction::overflowCheckedIntAddFunction\n\tif type_bits == 256:\n\t\toverflow_check = AND(ISZERO(SLT(X, 0)), SLT(sum_, Y))\n\t\tunderflow_check = AND(SLT(X, 0), ISZERO(SLT(sum_, Y)))\n\telse:\n\t\toverflow_check = SGT(sum_, maxValue)\n\t\tunderflow_check = SLT(sum_, minValue)\n\n\ttype_bits += 8\n\n\trule.check(actual_overflow, overflow_check != 0)\n\trule.check(actual_underflow, underflow_check != 0)\n"
  },
  {
    "path": "test/formal/checked_int_div.py",
    "content": "from opcodes import AND, EQ, SUB\nfrom rule import Rule\nfrom util import BVSignedMin, BVSignedUpCast\nfrom z3 import BitVec, BVSDivNoOverflow, Not\n\n\"\"\"\nOverflow checked signed integer division.\n\"\"\"\n\nn_bits = 256\ntype_bits = 8\n\nwhile type_bits <= n_bits:\n\n\trule = Rule()\n\n\t# Input vars\n\tX_short = BitVec('X', type_bits)\n\tY_short = BitVec('Y', type_bits)\n\n\t# Z3's overflow conditions\n\tactual_overflow = Not(BVSDivNoOverflow(X_short, Y_short))\n\n\t# cast to full n_bits values\n\tX = BVSignedUpCast(X_short, n_bits)\n\tY = BVSignedUpCast(Y_short, n_bits)\n\n\t# Constants\n\tminValue = BVSignedMin(type_bits, n_bits)\n\n\t# Overflow check in YulUtilFunction::overflowCheckedIntDivFunction\n\toverflow_check = AND(EQ(X, minValue), EQ(Y, SUB(0, 1)))\n\n\trule.check(actual_overflow, overflow_check != 0)\n\n\ttype_bits *= 2\n"
  },
  {
    "path": "test/formal/checked_int_mul_12.py",
    "content": "from opcodes import AND, SDIV, MUL, EQ, ISZERO, OR, SLT\nfrom rule import Rule\nfrom util import BVSignedUpCast, BVSignedMin, BVSignedCleanupFunction\nfrom z3 import BVMulNoOverflow, BVMulNoUnderflow, BitVec, Not, Or\n\n\"\"\"\nOverflow checked signed integer multiplication.\n\"\"\"\n\n# Approximation with 16-bit base types.\nn_bits = 12\n\nfor type_bits in [4, 6, 8, 12]:\n\n\trule = Rule()\n\n\t# Input vars\n\tX_short = BitVec('X', type_bits)\n\tY_short = BitVec('Y', type_bits)\n\n\t# Z3's overflow and underflow conditions\n\tactual_overflow = Not(BVMulNoOverflow(X_short, Y_short, True))\n\tactual_underflow = Not(BVMulNoUnderflow(X_short, Y_short))\n\n\t# cast to full n_bits values\n\tX = BVSignedUpCast(X_short, n_bits)\n\tY = BVSignedUpCast(Y_short, n_bits)\n\tproduct_raw = MUL(X, Y)\n\t#remove any overflown bits\n\tproduct = BVSignedCleanupFunction(product_raw, type_bits)\n\n\t# Constants\n\tmin_value = BVSignedMin(type_bits, n_bits)\n\n\t# Overflow and underflow checks in YulUtilFunction::overflowCheckedIntMulFunction\n\tif type_bits > n_bits / 2:\n\t\tsol_overflow_check_1 = ISZERO(OR(ISZERO(X), EQ(Y, SDIV(product, X))))\n\t\tif type_bits == n_bits:\n\t\t\tsol_overflow_check_2 = AND(SLT(X, 0), EQ(Y, min_value))\n\t\t\tsol_overflow_check = Or(sol_overflow_check_1 != 0, sol_overflow_check_2 != 0)\n\t\telse:\n\t\t\tsol_overflow_check = (sol_overflow_check_1 != 0)\n\telse:\n\t\tsol_overflow_check = (ISZERO(EQ(product, product_raw)) != 0)\n\n\trule.check(Or(actual_overflow, actual_underflow), sol_overflow_check)\n"
  },
  {
    "path": "test/formal/checked_int_sub.py",
    "content": "from opcodes import AND, ISZERO, SLT, SGT, SUB\nfrom rule import Rule\nfrom util import BVSignedMax, BVSignedMin, BVSignedUpCast\nfrom z3 import BitVec, BVSubNoOverflow, BVSubNoUnderflow, Not\n\n\"\"\"\nOverflow checked signed integer subtraction.\n\"\"\"\n\nn_bits = 256\ntype_bits = 8\n\nwhile type_bits <= n_bits:\n\n\trule = Rule()\n\n\t# Input vars\n\tX_short = BitVec('X', type_bits)\n\tY_short = BitVec('Y', type_bits)\n\n\t# Z3's overflow and underflow conditions\n\tactual_overflow = Not(BVSubNoOverflow(X_short, Y_short))\n\tactual_underflow = Not(BVSubNoUnderflow(X_short, Y_short, True))\n\n\t# cast to full n_bits values\n\tX = BVSignedUpCast(X_short, n_bits)\n\tY = BVSignedUpCast(Y_short, n_bits)\n\tdiff = SUB(X, Y)\n\n\t# Constants\n\tmaxValue = BVSignedMax(type_bits, n_bits)\n\tminValue = BVSignedMin(type_bits, n_bits)\n\n\t# Overflow and underflow checks in YulUtilFunction::overflowCheckedIntSubFunction\n\tif type_bits == 256:\n\t\tunderflow_check = AND(ISZERO(SLT(Y, 0)), SGT(diff, X))\n\t\toverflow_check = AND(SLT(Y, 0), SLT(diff, X))\n\telse:\n\t\tunderflow_check = SLT(diff, minValue)\n\t\toverflow_check = SGT(diff, maxValue)\n\n\ttype_bits += 8\n\n\trule.check(actual_underflow, underflow_check != 0)\n\trule.check(actual_overflow, overflow_check != 0)\n"
  },
  {
    "path": "test/formal/checked_uint_add.py",
    "content": "from opcodes import GT, ADD\nfrom rule import Rule\nfrom util import BVUnsignedMax, BVUnsignedUpCast\nfrom z3 import BitVec, BVAddNoOverflow, Not\n\n\"\"\"\nOverflow checked unsigned integer addition.\n\"\"\"\n\nn_bits = 256\ntype_bits = 8\n\nwhile type_bits <= n_bits:\n\n\trule = Rule()\n\n\t# Input vars\n\tX_short = BitVec('X', type_bits)\n\tY_short = BitVec('Y', type_bits)\n\n\t# Z3's overflow condition\n\tactual_overflow = Not(BVAddNoOverflow(X_short, Y_short, False))\n\n\t# cast to full n_bits values\n\tX = BVUnsignedUpCast(X_short, n_bits)\n\tY = BVUnsignedUpCast(Y_short, n_bits)\n\tsum_ = ADD(X, Y)\n\n\t# Constants\n\tmaxValue = BVUnsignedMax(type_bits, n_bits)\n\n\t# Overflow check in YulUtilFunction::overflowCheckedIntAddFunction\n\tif type_bits == 256:\n\t\toverflow_check = GT(X, sum_)\n\telse:\n\t\toverflow_check = GT(sum_, maxValue)\n\n\ttype_bits += 8\n\n\trule.check(overflow_check != 0, actual_overflow)\n"
  },
  {
    "path": "test/formal/checked_uint_mul_12.py",
    "content": "from opcodes import ISZERO, DIV, MUL, EQ, OR\nfrom rule import Rule\nfrom util import BVUnsignedUpCast, BVUnsignedCleanupFunction\nfrom z3 import BitVec, Not, BVMulNoOverflow\n\n\"\"\"\nOverflow checked unsigned integer multiplication.\n\"\"\"\n\n# Approximation with 16-bit base types.\nn_bits = 12\n\nfor type_bits in [4, 6, 8, 12]:\n\n\trule = Rule()\n\n\t# Input vars\n\tX_short = BitVec('X', type_bits)\n\tY_short = BitVec('Y', type_bits)\n\n\t# Z3's overflow condition\n\tactual_overflow = Not(BVMulNoOverflow(X_short, Y_short, False))\n\n\t# cast to full n_bits values\n\tX = BVUnsignedUpCast(X_short, n_bits)\n\tY = BVUnsignedUpCast(Y_short, n_bits)\n\tproduct_raw = MUL(X, Y)\n\t#remove any overflown bits\n\tproduct = BVUnsignedCleanupFunction(product_raw, type_bits)\n\n\t# Overflow check in YulUtilFunction::overflowCheckedIntMulFunctions\n\tif type_bits > n_bits / 2:\n\t\toverflow_check = ISZERO(OR(ISZERO(X), EQ(Y, DIV(product, X))))\n\telse:\n\t\toverflow_check = ISZERO(EQ(product, product_raw))\n\n\trule.check(overflow_check != 0, actual_overflow)\n"
  },
  {
    "path": "test/formal/checked_uint_sub.py",
    "content": "from opcodes import SUB, GT\nfrom rule import Rule\nfrom util import BVUnsignedMax, BVUnsignedUpCast\nfrom z3 import BVSubNoUnderflow, BitVec, Not\n\n\"\"\"\nOverflow checked unsigned integer subtraction.\n\"\"\"\n\nn_bits = 256\ntype_bits = 8\n\nwhile type_bits <= n_bits:\n\n\trule = Rule()\n\n\t# Input vars\n\tX_short = BitVec('X', type_bits)\n\tY_short = BitVec('Y', type_bits)\n\n\t# Z3's overflow condition\n\tactual_overflow = Not(BVSubNoUnderflow(X_short, Y_short, False))\n\n\t# cast to full n_bits values\n\tX = BVUnsignedUpCast(X_short, n_bits)\n\tY = BVUnsignedUpCast(Y_short, n_bits)\n\tdiff = SUB(X, Y)\n\n\t# Constants\n\tmaxValue = BVUnsignedMax(type_bits, n_bits)\n\n\t# Overflow check in YulUtilFunction::overflowCheckedIntSubFunction\n\tif type_bits == 256:\n\t\toverflow_check = GT(diff, X)\n\telse:\n\t\toverflow_check = GT(diff, maxValue)\n\n\ttype_bits += 8\n\n\trule.check(overflow_check != 0, actual_overflow)\n"
  },
  {
    "path": "test/formal/combine_byte_shl.py",
    "content": "from opcodes import BYTE, SHL\nfrom rule import Rule\nfrom z3 import BitVec, ULE\n\n\"\"\"\nbyte(A, shl(B, X))\ngiven B % 8 == 0 && A <= 32 && B <= 256\n->\nbyte(A + B / 8, X)\n\"\"\"\n\nrule = Rule()\n\nn_bits = 256\n\n# Input vars\nX = BitVec('X', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\n# Non optimized result\nnonopt = BYTE(A, SHL(B, X))\n# Optimized result\nopt = BYTE(A + B / 8, X)\n\nrule.require(B % 8 == 0)\nrule.require(ULE(A, 32))\nrule.require(ULE(B, 256))\n\nrule.check(nonopt, opt)\n"
  },
  {
    "path": "test/formal/combine_byte_shr_1.py",
    "content": "from opcodes import BYTE, DIV, SHR\nfrom rule import Rule\nfrom z3 import BitVec, UGE, ULE, ULT\n\n\"\"\"\nbyte(A, shr(B, X))\ngiven B % 8 == 0 && A < n_bits/8 && B <= n_bits && A >= B / 8\n->\nbyte(A - B / 8, X)\n\"\"\"\n\nrule = Rule()\n\nn_bits = 256\n\n# Input vars\nX = BitVec('X', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\n# Non optimized result\nnonopt = BYTE(A, SHR(B, X))\n# Optimized result\nopt = BYTE(A - B / 8, X)\n\nrule.require(B % 8 == 0)\nrule.require(ULT(A, n_bits/8))\nrule.require(ULE(B, n_bits))\nrule.require(UGE(A, DIV(B,8)))\n\nrule.check(nonopt, opt)\n"
  },
  {
    "path": "test/formal/combine_byte_shr_2.py",
    "content": "from opcodes import BYTE, SHR, DIV\nfrom rule import Rule\nfrom z3 import BitVec, ULT\n\n\"\"\"\nbyte(A, shr(B, X))\ngiven A < B / 8\n->\n0\n\"\"\"\n\nrule = Rule()\n\nn_bits = 256\n\n# Input vars\nX = BitVec('X', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\n# Non optimized result\nnonopt = BYTE(A, SHR(B, X))\n# Optimized result\nopt = 0\n\nrule.require(ULT(A, DIV(B,8)))\n\nrule.check(nonopt, opt)\n"
  },
  {
    "path": "test/formal/combine_div_shl_one_32.py",
    "content": "from opcodes import DIV, SHL, SHR\nfrom rule import Rule\nfrom z3 import BitVec\n\n\"\"\"\nRule:\nDIV(X, SHL(Y, 1)) -> SHR(Y, X)\nRequirements:\n\"\"\"\n\nrule = Rule()\n\nn_bits = 32\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\n\n# Non optimized result\nnonopt = DIV(X, SHL(Y, 1))\n\n# Optimized result\nopt = SHR(Y, X)\n\nrule.check(nonopt, opt)\n"
  },
  {
    "path": "test/formal/combine_mul_shl_one_64.py",
    "content": "from opcodes import SHL, MUL\nfrom rule import Rule\nfrom z3 import BitVec\n\n\"\"\"\nRule:\nMUL(X, SHL(Y, 1)) -> SHL(Y, X)\nMUL(SHL(X, 1), Y) -> SHL(X, Y)\nRequirements:\n\"\"\"\n\nrule = Rule()\n\nn_bits = 64\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\n\n# Requirements\n\n# Non optimized result\nnonopt_1 = MUL(X, SHL(Y, 1))\nnonopt_2 = MUL(SHL(X, 1), Y)\n\n# Optimized result\nopt_1 = SHL(Y, X)\nopt_2 = SHL(X, Y)\n\nrule.check(nonopt_1, opt_1)\nrule.check(nonopt_2, opt_2)\n"
  },
  {
    "path": "test/formal/combine_shl_shr_by_constant_64.py",
    "content": "from opcodes import AND, SHL, SHR\nfrom rule import Rule\nfrom z3 import BitVec, BitVecVal, If, Int2BV, IntVal, UGT, ULT\n\n\"\"\"\nRule:\nmask = shlWorkaround(u256(-1), unsigned(A.d())) >> unsigned(B.d())\nSHR(B, SHL(A, X)) -> AND(SH[L/R]([B - A / A - B], X), Mask)\nRequirements:\nA < BitWidth\nB < BitWidth\n\"\"\"\n\nrule = Rule()\n\nn_bits = 64\n\n# Input vars\nX = BitVec('X', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\n# Constants\nBitWidth = BitVecVal(n_bits, n_bits)\n\n# Requirements\nrule.require(ULT(A, BitWidth))\nrule.require(ULT(B, BitWidth))\n\n# Non optimized result\nnonopt = SHR(B, SHL(A, X))\n\n# Optimized result\nMask = SHR(B, SHL(A, Int2BV(IntVal(-1), n_bits)))\nopt = If(\n\tUGT(A, B),\n\tAND(SHL(A - B, X), Mask),\n\t\tIf(\n\t\t\tUGT(B, A),\n\t\t\tAND(SHR(B - A, X), Mask),\n\t\t\tAND(X, Mask)\n\t\t)\n\t)\n\nrule.check(nonopt, opt)\n"
  },
  {
    "path": "test/formal/combine_shr_shl_by_constant_64.py",
    "content": "from opcodes import AND, SHL, SHR\nfrom rule import Rule\nfrom z3 import BitVec, BitVecVal, If, Int2BV, IntVal, UGT, ULT\n\n\"\"\"\nRule:\nmask = shlWorkaround(u256(-1) >> unsigned(A.d()), unsigned(B.d()))\nSHL(B, SHR(A, X)) -> AND(SH[L/R]([B - A / A - B], X), Mask)\nRequirements:\nA < BitWidth\nB < BitWidth\n\"\"\"\n\nrule = Rule()\n\nn_bits = 64\n\n# Input vars\nX = BitVec('X', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\n# Constants\nBitWidth = BitVecVal(n_bits, n_bits)\n\n# Requirements\nrule.require(ULT(A, BitWidth))\nrule.require(ULT(B, BitWidth))\n\n# Non optimized result\nnonopt = SHL(B, SHR(A, X))\n\n# Optimized result\nMask = SHL(B, SHR(A, Int2BV(IntVal(-1), n_bits)))\nopt = If(\n\tUGT(A, B),\n\tAND(SHR(A - B, X), Mask),\n\t\tIf(\n\t\t\tUGT(B, A),\n\t\t\tAND(SHL(B - A, X), Mask),\n\t\t\tAND(X, Mask)\n\t\t)\n\t)\n\nrule.check(nonopt, opt)\n"
  },
  {
    "path": "test/formal/eq_sub.py",
    "content": "from opcodes import EQ, ISZERO, SUB\nfrom rule import Rule\nfrom z3 import BitVec\n\n\"\"\"\nRule:\nISZERO(SUB(X, Y)) -> EQ(X, Y)\n\"\"\"\n\nrule = Rule()\n\nn_bits = 256\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\n\n# Non optimized result\nnonopt = ISZERO(SUB(X, Y))\n\n# Optimized result\nopt = EQ(X, Y)\n\nrule.check(nonopt, opt)\n"
  },
  {
    "path": "test/formal/exp_neg_one.py",
    "content": "from opcodes import AND, ISZERO, MOD, SUB\nfrom rule import Rule\nfrom util import BVUnsignedMax\nfrom z3 import BitVec, BitVecVal, If\n\n\"\"\"\nChecking conversion of exp(-1, X) to sub(isZero(and(X, 1)), and(X, 1))\n\"\"\"\n\nrule = Rule()\nn_bits = 256\n\nX = BitVec('X', n_bits)\n\nexp_neg_one = If(MOD(X, 2) == 0, BitVecVal(1, n_bits), BVUnsignedMax(n_bits, n_bits))\n\nrule.check(SUB(ISZERO(AND(X, 1)), AND(X, 1)), exp_neg_one)\n"
  },
  {
    "path": "test/formal/exp_to_shl.py",
    "content": "from opcodes import SHL\nfrom rule import Rule\nfrom z3 import BitVec, If\n\n\"\"\"\nChecking conversion of exp(2, X) to shl(X, 1)\n\"\"\"\n\nrule = Rule()\nn_bits = 256\n\n# Proof of exp(2, X) = shl(X, 1) by induction:\n#\n# Base case: X = 0, exp(2, 0) = 1 = 1 = shl(0, 1)\n# Inductive step: assuming exp(2, X) = shl(X, 1) for X <= N\n#                 to prove: exp(2, N + 1) = shl(N + 1, 1)\n#\n# Notice that exp(2, N + 1) = 2 * exp(2, N) mod 2**256\n# since exp(2, N) = shl(N, 1), it is enough to show that\n# 2 * shl(N, 1) mod 2**256 = shl(N + 1, 1)\n#\n# Also note that N + 1 < 2**256\n\nN = BitVec('N', n_bits)\ninductive_step = 2 * SHL(N, 1)\n\nrule.check(\n    inductive_step,\n    If(\n        N == 2**256 - 1,\n        0,\n        SHL(N + 1, 1)\n    )\n)\n"
  },
  {
    "path": "test/formal/mod_add_to_addmod.py",
    "content": "from opcodes import MOD, ADD, ADDMOD\nfrom rule import Rule\nfrom z3 import BitVec\n\n\"\"\"\nRule:\nMOD(ADD(X, Y), A) -> ADDMOD(X, Y, A)\ngiven\n    A > 0\n    A & (A - 1) == 0\n\"\"\"\n\nrule = Rule()\n\nn_bits = 32\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\nA = BitVec('A', n_bits)\n\n# Non optimized result\nnonopt = MOD(ADD(X, Y), A)\n\n# Optimized result\nopt = ADDMOD(X, Y, A)\n\nrule.require(A > 0)\nrule.require(((A & (A - 1)) == 0))\n\nrule.check(nonopt, opt)\n"
  },
  {
    "path": "test/formal/mod_mul_to_mulmod.py",
    "content": "from opcodes import MOD, MUL, MULMOD\nfrom rule import Rule\nfrom z3 import BitVec\n\n\"\"\"\nRule:\nMOD(MUL(X, Y), A) -> MULMOD(X, Y, A)\ngiven\n    A > 0\n    A & (A - 1) == 0\n\"\"\"\n\nrule = Rule()\n\nn_bits = 8\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\nA = BitVec('A', n_bits)\n\n# Non optimized result\nnonopt = MOD(MUL(X, Y), A)\n\n# Optimized result\nopt = MULMOD(X, Y, A)\n\nrule.require(A > 0)\nrule.require(((A & (A - 1)) == 0))\n\nrule.check(nonopt, opt)\n"
  },
  {
    "path": "test/formal/move_and_across_shl_128.py",
    "content": "from opcodes import AND, SHL\nfrom rule import Rule\nfrom z3 import BitVec, BitVecVal, ULT\n\n\"\"\"\nRule:\nSHL(B, AND(X, A)) -> AND(SHL(B, X), A << B)\nSHL(B, AND(A, X)) -> AND(SHL(B, X), A << B)\nRequirements:\nB < BitWidth\n\"\"\"\n\nrule = Rule()\n\nn_bits = 128\n\n# Input vars\nX = BitVec('X', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\n# Constants\nBitWidth = BitVecVal(n_bits, n_bits)\n\n# Requirements\nrule.require(ULT(B, BitWidth))\n\n# Non optimized result\nnonopt_1 = SHL(B, AND(X, A))\nnonopt_2 = SHL(B, AND(A, X))\n\n# Optimized result\nMask = SHL(B, A)\nopt = AND(SHL(B, X), Mask)\n\nrule.check(nonopt_1, opt)\nrule.check(nonopt_2, opt)\n"
  },
  {
    "path": "test/formal/move_and_across_shr_128.py",
    "content": "from opcodes import AND, SHR\nfrom rule import Rule\nfrom z3 import BitVec, BitVecVal, ULT\n\n\"\"\"\nRule:\nSHR(B, AND(X, A)) -> AND(SHR(B, X), A >> B)\nSHR(B, AND(A, X)) -> AND(SHR(B, X), A >> B)\nRequirements:\nB < BitWidth\n\"\"\"\n\nrule = Rule()\n\nn_bits = 128\n\n# Input vars\nX = BitVec('X', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\n# Constants\nBitWidth = BitVecVal(n_bits, n_bits)\n\n# Requirements\nrule.require(ULT(B, BitWidth))\n\n# Non optimized result\nnonopt_1 = SHR(B, AND(X, A))\nnonopt_2 = SHR(B, AND(A, X))\n\n# Optimized result\nMask = SHR(B, A)\nopt = AND(SHR(B, X), Mask)\n\nrule.check(nonopt_1, opt)\nrule.check(nonopt_2, opt)\n"
  },
  {
    "path": "test/formal/move_and_inside_or.py",
    "content": "from opcodes import AND, OR\nfrom rule import Rule\nfrom z3 import BitVec\n\n\n\"\"\"\nRule:\nAND(OR(AND(X, A), Y), B) -> OR(AND(X, A & B), AND(Y, B))\n\"\"\"\n\nrule = Rule()\n\n# bit width is irrelevant\nn_bits = 128\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\n# Non optimized result, explicit form\nnonopt = AND(OR(AND(X, A), Y), B)\n\n# Optimized result\nopt = OR(AND(X, A & B), AND(Y, B))\n\nrule.check(nonopt, opt)\n\n# Now the forms as they are constructod in the code.\nfor inner in [AND(X, A), AND(A, X)]:\n    for second in [OR(inner, Y), OR(Y, inner)]:\n        rule.check(AND(second, B), opt)\n        rule.check(AND(B, second), opt)\n"
  },
  {
    "path": "test/formal/opcodes.py",
    "content": "from z3 import BitVecVal, BV2Int, If, LShR, UDiv, ULT, UGT, URem, ZeroExt, Extract\n\ndef ADD(x, y):\n\treturn x + y\n\ndef MUL(x, y):\n\treturn x * y\n\ndef SUB(x, y):\n\treturn x - y\n\ndef DIV(x, y):\n\treturn If(y == 0, 0, UDiv(x, y))\n\ndef SDIV(x, y):\n\treturn If(y == 0, 0, x / y)\n\ndef MOD(x, y):\n\treturn If(y == 0, 0, URem(x, y))\n\ndef MULMOD(x, y, m):\n\treturn If(m == 0, 0, Extract(x.size() - 1, 0, URem(ZeroExt(x.size(), x) * ZeroExt(x.size(), y), ZeroExt(m.size(), m))))\n\ndef ADDMOD(x, y, m):\n\treturn If(m == 0, 0, Extract(x.size() - 1, 0, URem(ZeroExt(1, x) + ZeroExt(1, y), ZeroExt(1, m))))\n\ndef SMOD(x, y):\n\treturn If(\n\t\ty == 0,\n\t\t0,\n\t\tIf(\n\t\t\tx >= 0,\n\t\t\tIf(y >= 0, x % y, x % (-y)),\n\t\t\tIf(y >= 0, -((-x) % y), -((-x) % (-y)))\n\t\t)\n\t)\n\ndef LT(x, y):\n\treturn If(ULT(x, y), BitVecVal(1, x.size()), BitVecVal(0, x.size()))\n\ndef GT(x, y):\n\treturn If(UGT(x, y), BitVecVal(1, x.size()), BitVecVal(0, x.size()))\n\ndef SLT(x, y):\n\treturn If(x < y, BitVecVal(1, x.size()), BitVecVal(0, x.size()))\n\ndef SGT(x, y):\n\treturn If(x > y, BitVecVal(1, x.size()), BitVecVal(0, x.size()))\n\ndef EQ(x, y):\n\treturn If(x == y, BitVecVal(1, x.size()), BitVecVal(0, x.size()))\n\ndef ISZERO(x):\n\treturn If(x == 0, BitVecVal(1, x.size()), BitVecVal(0, x.size()))\n\ndef AND(x, y):\n\treturn x & y\n\ndef OR(x, y):\n\treturn x | y\n\ndef NOT(x):\n\treturn ~(x)\n\ndef SHL(x, y):\n\treturn y << x\n\ndef SHR(x, y):\n\treturn LShR(y, x)\n\ndef SAR(x, y):\n\treturn y >> x\n\ndef BYTE(i, x):\n\tbit = (i + 1) * 8\n\treturn If(\n\t\tUGT(i, x.size() / 8 - 1),\n\t\tBitVecVal(0, x.size()),\n\t\t(LShR(x, (x.size() - bit))) & 0xff\n\t)\n\ndef SIGNEXTEND(i, x):\n\tbitBV = i * 8 + 7\n\tbitInt = BV2Int(i) * 8 + 7\n\ttest = BitVecVal(1, x.size()) << bitBV\n\tmask = test - 1\n\treturn If(\n\t\tbitInt >= x.size(),\n\t\tx,\n\t\tIf(\n\t\t\t(x & test) == 0,\n\t\t\tx & mask,\n\t\t\tx | ~mask\n\t\t)\n\t)\n"
  },
  {
    "path": "test/formal/redundant_store_unrelated.py",
    "content": "import sys\nfrom z3 import Solver, Int, unsat\n\n\"\"\"\nTests that the conditions inside RedundantStoreEliminator::knownUnrelated\nonly return \"unrelated\" incorrectly if one of the operation reverts\ndue to large memory access.\n\"\"\"\n\nn_bits = 256\n\nsolver = Solver()\nsolver.set(\"timeout\", 60000)\n\ndef restrict(x):\n    solver.add(x >= 0)\n    solver.add(x < 2**n_bits)\n\ndef restrictedInt(x):\n    var = Int(x)\n    restrict(var)\n    return var\n\nstart1 = restrictedInt('start1')\nlength1 = restrictedInt('length1')\nstart2 = restrictedInt('start2')\nlength2 = restrictedInt('length2')\n\nk = Int('k')\ndiff = Int('diff')\nsolver.add(diff == start2 - start1 + k * 2**n_bits)\nrestrict(diff)\n# diff is the result of sub(start2, start1) in EVM\n\n# These are the conditions in the code.\nsolver.add(diff >= length1)\nsolver.add(diff <= 2**(n_bits-1))\n\n# We check that the two conditions are conflicting:\n# - overlap\n# - start1 is small\n\n# Overlap:\n# x is a potential point where the memory operations\n# overlap.\n# Note that we do not use wrapping arithmetic\n# here, because it is not done in the EVM either.\n# For example calldatacopy(2**256 - 2, 0, 10)\n# (copy 10 bytes from calldata position zero to memory\n# position 2**256 - 2) would not write to memory position\n# zero either.\nx = Int('x')\nsolver.add(start1 <= x)\nsolver.add(x < start1 + length1)\nsolver.add(start2 <= x)\nsolver.add(x < start2 + length2)\n\n# start1 is \"small\":\nsolver.add(start1 < 2**(n_bits-1))\n\nif solver.check() != unsat:\n  print(\"Expected unsat but got something else\")\n  sys.exit(1)\n"
  },
  {
    "path": "test/formal/repeated_and.py",
    "content": "from opcodes import AND\nfrom rule import Rule\nfrom z3 import BitVec, BitVecVal\n\n\"\"\"\nRule:\nAND(AND(X, Y), Y) -> AND(X, Y)\nAND(Y, AND(X, Y)) -> AND(X, Y)\nAND(AND(Y, X), Y) -> AND(Y, X)\nAND(Y, AND(Y, X)) -> AND(Y, X)\nRequirements:\n\"\"\"\n\nrule = Rule()\n\nn_bits = 256\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\n\n# Constants\nBitWidth = BitVecVal(n_bits, n_bits)\n\n# Requirements\n\n# Non optimized result\nnonopt_1 = AND(AND(X, Y), Y)\nnonopt_2 = AND(Y, AND(X, Y))\nnonopt_3 = AND(AND(Y, X), Y)\nnonopt_4 = AND(Y, AND(Y, X))\n\n# Optimized result\nopt_1 = AND(X, Y)\nopt_2 = AND(Y, X)\n\nrule.check(nonopt_1, opt_1)\nrule.check(nonopt_2, opt_1)\nrule.check(nonopt_3, opt_2)\nrule.check(nonopt_4, opt_2)\n"
  },
  {
    "path": "test/formal/repeated_or.py",
    "content": "from opcodes import OR\nfrom rule import Rule\nfrom z3 import BitVec, BitVecVal\n\n\"\"\"\nRule:\nOR(OR(X, Y), Y) -> OR(X, Y)\nOR(Y, OR(X, Y)) -> OR(X, Y)\nOR(OR(Y, X), Y) -> OR(Y, X)\nOR(Y, OR(Y, X)) -> OR(Y, X)\nRequirements:\n\"\"\"\n\nrule = Rule()\n\nn_bits = 256\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\n\n# Constants\nBitWidth = BitVecVal(n_bits, n_bits)\n\n# Requirements\n\n# Non optimized result\nnonopt_1 = OR(OR(X, Y), Y)\nnonopt_2 = OR(Y, OR(X, Y))\nnonopt_3 = OR(OR(Y, X), Y)\nnonopt_4 = OR(Y, OR(Y, X))\n\n# Optimized result\nopt_1 = OR(X, Y)\nopt_2 = OR(Y, X)\n\nrule.check(nonopt_1, opt_1)\nrule.check(nonopt_2, opt_1)\nrule.check(nonopt_3, opt_2)\nrule.check(nonopt_4, opt_2)\n"
  },
  {
    "path": "test/formal/replace_mul_by_shift.py",
    "content": "from opcodes import DIV, MUL, SHL, SHR\nfrom rule import Rule\nfrom z3 import BitVec\n\n\"\"\"\nRule:\nMUL(X, A) -> SHL(k, X)\nMUL(A, X) -> SHL(k, X)\nDIV(X, A) -> SHR(k, X)\nRequirements:\nA == 1 << K\n\"\"\"\n\nrule = Rule()\n\nn_bits = 32\n\n# Input vars\nX = BitVec('X', n_bits)\nA = BitVec('A', n_bits)\nK = BitVec('K', n_bits)\n\n# Requirements\nrule.require(A == SHL(K, 1))\n\n# Non optimized result\nnonopt_1 = MUL(X, A)\nnonopt_2 = MUL(A, X)\nnonopt_3 = DIV(X, A)\n\n# Optimized result\nopt_1 = SHL(K, X)\nopt_2 = SHL(K, X)\nopt_3 = SHR(K, X)\n\nrule.check(nonopt_1, opt_1)\nrule.check(nonopt_2, opt_2)\nrule.check(nonopt_3, opt_3)\n"
  },
  {
    "path": "test/formal/rule.py",
    "content": "import sys\n\nfrom z3 import sat, Solver, unknown, unsat\n\nclass Rule:\n\tdef __init__(self):\n\t\tself.requirements = []\n\t\tself.constraints = []\n\t\tself.solver = Solver()\n\t\tself.setTimeout(60000)\n\n\tdef setTimeout(self, _t):\n\t\tself.solver.set(\"timeout\", _t)\n\n\tdef __lshift__(self, _c):\n\t\tself.constraints.append(_c)\n\n\tdef require(self, _r):\n\t\tself.requirements.append(_r)\n\n\tdef check(self, _nonopt, _opt):\n\t\tself.solver.add(self.requirements)\n\t\tresult = self.solver.check()\n\n\t\tif result == unknown:\n\t\t\tself.error('Unable to satisfy requirements.')\n\t\telif result == unsat:\n\t\t\tself.error('Requirements are unsatisfiable.')\n\n\t\tself.solver.push()\n\t\tself.solver.add(self.constraints)\n\t\tself.solver.add(_nonopt != _opt)\n\n\t\tresult = self.solver.check()\n\t\tif result == unknown:\n\t\t\tself.error('Unable to prove rule.')\n\t\telif result == sat:\n\t\t\tm = self.solver.model()\n\t\t\tself.error('Rule is incorrect.\\nModel: ' + str(m))\n\t\tself.solver.pop()\n\n\t@classmethod\n\tdef error(cls, msg):\n\t\tprint(msg)\n\t\tsys.exit(1)\n"
  },
  {
    "path": "test/formal/shl_workaround_8.py",
    "content": "from opcodes import SHL\nfrom rule import Rule\nfrom z3 import BitVec, BV2Int, Int2BV, IntVal\n\n\"\"\"\nShift left workaround that Solidity implements\ndue to a bug in Boost.\n\"\"\"\n\nrule = Rule()\n\nn_bits = 8\nbigint_bits = 16\n\n# Input vars\nX = BitVec('X', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', bigint_bits)\n\n# Compute workaround\nworkaround = Int2BV(\n\tBV2Int(\n\t\t(Int2BV(BV2Int(X), bigint_bits) << Int2BV(BV2Int(A), bigint_bits)) &\n\t\tInt2BV(BV2Int(Int2BV(IntVal(-1), n_bits)), bigint_bits)\n\t), n_bits\n)\n\nrule.check(workaround, SHL(A, X))\n"
  },
  {
    "path": "test/formal/signed_integer_cleanup_function.py",
    "content": "from opcodes import SIGNEXTEND\nfrom rule import Rule\nfrom util import BVSignedCleanupFunction, BVSignedUpCast\nfrom z3 import BitVec, BitVecVal, Concat\n\n\"\"\"\nOverflow checked signed integer multiplication.\n\"\"\"\n\nn_bits = 256\n\n# Check that YulUtilFunction::cleanupFunction cleanup matches BVSignedCleanupFunction\nfor type_bits in range(8,256,8):\n\n\trule = Rule()\n\n\t# Input vars\n\tX = BitVec('X', n_bits)\n\targ = BitVecVal(type_bits / 8 - 1, n_bits)\n\n\tcleaned_reference = BVSignedCleanupFunction(X, type_bits)\n\tcleaned = SIGNEXTEND(arg, X)\n\n\trule.check(cleaned, cleaned_reference)\n\n\n# Check that BVSignedCleanupFunction properly cleans up values.\nfor type_bits in range(8,256,8):\n\n\trule = Rule()\n\n\t# Input vars\n\tX_short = BitVec('X', type_bits)\n\tdirt = BitVec('dirt', n_bits - type_bits)\n\n\tX = BVSignedUpCast(X_short, n_bits)\n\tX_dirty = Concat(dirt, X_short)\n\tX_cleaned = BVSignedCleanupFunction(X_dirty, type_bits)\n\n\n\trule.check(X, X_cleaned)\n"
  },
  {
    "path": "test/formal/signextend.py",
    "content": "from opcodes import SIGNEXTEND\nfrom rule import Rule\nfrom z3 import BitVec, BitVecVal, If, UGE, ULT\n\n\"\"\"\nRule:\n1) SIGNEXTEND(A, X) -> X if A >= Pattern::WordSize / 8 - 1;\n\n2) SIGNEXTEND(X, SIGNEXTEND(X, Y)) -> SIGNEXTEND(X, Y)\n\n3) SIGNEXTEND(A, SIGNEXTEND(B, X)) -> SIGNEXTEND(min(A, B), X)\n\"\"\"\n\nn_bits = 128\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\nrule1 = Rule()\n# Requirements\nrule1.require(UGE(A, BitVecVal(n_bits // 8 - 1, n_bits)))\nrule1.check(SIGNEXTEND(A, X), X)\n\nrule2 = Rule()\nrule2.check(\n    SIGNEXTEND(X, SIGNEXTEND(X, Y)),\n    SIGNEXTEND(X, Y)\n)\n\nrule3 = Rule()\nrule3.check(\n    SIGNEXTEND(A, SIGNEXTEND(B, X)),\n    SIGNEXTEND(If(ULT(A, B), A, B), X)\n)\n"
  },
  {
    "path": "test/formal/signextend_and.py",
    "content": "from opcodes import SIGNEXTEND, AND\nfrom rule import Rule\nfrom z3 import BitVec, BitVecVal, ULT\n\n\"\"\"\nRule:\nAND(A, SIGNEXTEND(B, X)) -> AND(A, X)\ngiven\n    B < WordSize / 8 - 1 AND\n    A & (1 << ((B + 1) * 8) - 1) == A\n\"\"\"\n\nn_bits = 128\n\n# Input vars\nX = BitVec('X', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\nrule = Rule()\n# Requirements\nrule.require(ULT(B, BitVecVal(n_bits // 8 - 1, n_bits)))\nrule.require((A & ((BitVecVal(1, n_bits) << ((B + 1) * 8)) - 1)) == A)\nrule.check(\n    AND(A, SIGNEXTEND(B, X)),\n    AND(A, X)\n)\n"
  },
  {
    "path": "test/formal/signextend_equivalence.py",
    "content": "from opcodes import SIGNEXTEND\nfrom rule import Rule\nfrom z3 import BitVec, BitVecVal, Extract, SignExt, UGT\n\n\"\"\"\nChecking the implementation of SIGNEXTEND using Z3's native SignExt and Extract\n\"\"\"\n\nrule = Rule()\nn_bits = 256\n\nx = BitVec('X', n_bits)\n\ndef SIGNEXTEND_native(i, x):\n    return SignExt(256 - 8 * i - 8, Extract(8 * i + 7, 0, x))\n\nfor i in range(0, 32):\n    rule.check(\n        SIGNEXTEND(BitVecVal(i, n_bits), x),\n        SIGNEXTEND_native(i, x)\n    )\n\ni = BitVec('I', n_bits)\nrule.require(UGT(i, BitVecVal(31, n_bits)))\nrule.check(SIGNEXTEND(i, x), x)\n"
  },
  {
    "path": "test/formal/signextend_shl.py",
    "content": "from opcodes import SHL, SIGNEXTEND\nfrom rule import Rule\nfrom z3 import BitVec, LShR, ULE\n\n\"\"\"\nRule:\nSHL(A, SIGNEXTEND(B, X)) -> SIGNEXTEND((A >> 3) + B, SHL(A, X))\ngiven return A & 7 == 0  AND  A <= WordSize  AND  B <= WordSize / 8\n\"\"\"\n\nn_bits = 256\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\nrule = Rule()\nrule.require(A & 7 == 0)\nrule.require(ULE(A, n_bits))\nrule.require(ULE(B, n_bits / 8))\nrule.check(\n    SHL(A, SIGNEXTEND(B, X)),\n    SIGNEXTEND(LShR(A, 3) + B, SHL(A, X))\n)\n"
  },
  {
    "path": "test/formal/signextend_shr.py",
    "content": "from opcodes import SIGNEXTEND, SAR, SHR\nfrom rule import Rule\nfrom z3 import BitVec,  BitVecVal, ULE\n\n\"\"\"\nRule:\nSIGNEXTEND(A, SHR(B, X)) -> SAR(B, X)\ngiven\n    B % 8 == 0 AND\n    A <= WordSize AND\n    B <= wordSize AND\n    (WordSize - B) / 8 == A + 1\n\"\"\"\n\nn_bits = 256\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\nA = BitVec('A', n_bits)\nB = BitVec('B', n_bits)\n\nrule = Rule()\nrule.require(B % 8 == 0)\nrule.require(ULE(A, n_bits))\nrule.require(ULE(B, n_bits))\nrule.require((BitVecVal(n_bits, n_bits) - B) / 8 == A + 1)\nrule.check(\n    SIGNEXTEND(A, SHR(B, X)),\n    SAR(B, X)\n)\n"
  },
  {
    "path": "test/formal/smod.py",
    "content": "from z3 import BitVec\nfrom rule import Rule\nfrom opcodes import SMOD\n\n\nn_bits = 256\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\n\n\ndef smod_test(a, b, r, op=SMOD):\n    r\"\"\"\n    Tests SMOD with predefined parameters a,b against an expected result r.\n    \"\"\"\n    to_check = Rule()\n    to_check.require(X == a)\n    to_check.require(Y == b)\n    to_check.check(op(X, Y), r)\n\n\n# tests from:\n# https://github.com/ethereum/tests/blob/2e37a9f41167534b07e0e8f247ea934a5fe3cac9/src/GeneralStateTestsFiller/VMTests/vmArithmeticTest/smodFiller.yml\nsmod_test(2, 3, 2)\nsmod_test(-1, 2, -1)\nsmod_test(0, -1, 0)\nsmod_test(3, 0, 0)\nsmod_test(-2, 3, -2)\nsmod_test(-2, 3, -2)\nsmod_test(16, 0, -1, op=lambda x, y: SMOD(x, y) - 1)\n\n# more tests\nrule = Rule()\nrule.require(X == 7)\nrule.require(Y == 5)\nrule.check(SMOD(X, Y), 2)\n\nrule = Rule()\nrule.require(X == 7)\nrule.require(Y == 5)\nrule.check(SMOD(X, Y), 2)\n\nrule = Rule()\nrule.require(X == -7)\nrule.require(Y == 5)\nrule.check(SMOD(X, Y), -2)\n\nrule = Rule()\nrule.require(X == 7)\nrule.require(Y == -5)\nrule.check(SMOD(X, Y), 2)\n\nrule = Rule()\nrule.require(X == -7)\nrule.require(Y == -5)\nrule.check(SMOD(X, Y), -2)\n\nfor k in [-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7]:\n    for i in [-13, -12, -11, 10, -7, -2, 1, 0, 1, 2, 7, 10, 11, 12, 13]:\n        rule = Rule()\n        rule.require(X == i)\n        rule.require(Y == k)\n        if k != 0:\n            rule.check(SMOD(X, Y) % Y, X % Y)\n        else:\n            rule.check(SMOD(X, Y), 0)\n"
  },
  {
    "path": "test/formal/sub_not_zero_x_to_not_x_256.py",
    "content": "from opcodes import NOT, SUB\nfrom rule import Rule\nfrom z3 import BitVec, BitVecVal\n\n\"\"\"\nRule:\nSUB(~0, X) -> NOT(X)\nRequirements:\n\"\"\"\n\nrule = Rule()\n\nn_bits = 256\n\n# Input vars\nX = BitVec('X', n_bits)\n\n# Constants\nZERO = BitVecVal(0, n_bits)\n\n# Non optimized result\nnonopt = SUB(~ZERO, X)\n\n# Optimized result\nopt = NOT(X)\n\nrule.check(nonopt, opt)\n"
  },
  {
    "path": "test/formal/sub_sub.py",
    "content": "from opcodes import ADD, SUB\nfrom rule import Rule\nfrom z3 import BitVec\n\n\"\"\"\nRules:\nSUB(SUB(X, A), Y) -> SUB(SUB(X, Y), A)\nSUB(SUB(A, X), Y) -> SUB(A, ADD(X, Y))\nSUB(X, SUB(Y, A)) -> ADD(SUB(X, Y), A)\nSUB(X, SUB(A, Y)) -> ADD(ADD(X, Y), -A)\n\"\"\"\n\nrule = Rule()\n\nn_bits = 256\n\n# Input vars\nX = BitVec('X', n_bits)\nY = BitVec('Y', n_bits)\nA = BitVec('A', n_bits)\n\nrule.check(\n    SUB(SUB(X, A), Y),\n    SUB(SUB(X, Y), A)\n)\nrule.check(\n    SUB(SUB(A, X), Y),\n    SUB(A, ADD(X, Y))\n)\nrule.check(\n    SUB(X, SUB(Y, A)),\n    ADD(SUB(X, Y), A)\n)\nrule.check(\n    SUB(X, SUB(A, Y)),\n    ADD(ADD(X, Y), SUB(0, A))\n)\n"
  },
  {
    "path": "test/formal/unsigned_integer_cleanup_function.py",
    "content": "from opcodes import AND\nfrom rule import Rule\nfrom util import BVUnsignedCleanupFunction, BVUnsignedUpCast\nfrom z3 import BitVec, BitVecVal, Concat\n\n\"\"\"\nOverflow checked unsigned integer multiplication.\n\"\"\"\n\nn_bits = 256\n\n# Check that YulUtilFunction::cleanupFunction cleanup matches BVUnsignedCleanupFunction\nfor type_bits in range(8,256,8):\n\n\trule = Rule()\n\n\t# Input vars\n\tX = BitVec('X', n_bits)\n\tmask = BitVecVal((1 << type_bits) - 1, n_bits)\n\n\tcleaned_reference = BVUnsignedCleanupFunction(X, type_bits)\n\tcleaned = AND(X, mask)\n\n\trule.check(cleaned, cleaned_reference)\n\n# Check that BVUnsignedCleanupFunction properly cleans up values.\nfor type_bits in range(8,256,8):\n\n\trule = Rule()\n\n\t# Input vars\n\tX_short = BitVec('X', type_bits)\n\tdirt = BitVec('dirt', n_bits - type_bits)\n\n\tX = BVUnsignedUpCast(X_short, n_bits)\n\tX_dirty = Concat(dirt, X_short)\n\tX_cleaned = BVUnsignedCleanupFunction(X_dirty, type_bits)\n\n\n\trule.check(X, X_cleaned)\n"
  },
  {
    "path": "test/formal/util.py",
    "content": "from z3 import BitVecVal, Concat, If\n\ndef BVUnsignedUpCast(x, n_bits):\n\tassert x.size() <= n_bits\n\tif x.size() < n_bits:\n\t\treturn Concat(BitVecVal(0, n_bits - x.size()), x)\n\telse:\n\t\treturn x\n\ndef BVUnsignedMax(type_bits, n_bits):\n\tassert type_bits <= n_bits\n\treturn BitVecVal((1 << type_bits) - 1, n_bits)\n\ndef BVSignedUpCast(x, n_bits):\n\tassert x.size() <= n_bits\n\tif x.size() < n_bits:\n\t\treturn Concat(If(x < 0, BitVecVal(-1, n_bits - x.size()), BitVecVal(0, n_bits - x.size())), x)\n\telse:\n\t\treturn x\n\ndef BVSignedMax(type_bits, n_bits):\n\tassert type_bits <= n_bits\n\treturn BitVecVal((1 << (type_bits - 1)) - 1, n_bits)\n\ndef BVSignedMin(type_bits, n_bits):\n\tassert type_bits <= n_bits\n\treturn BitVecVal(-(1 << (type_bits - 1)), n_bits)\n\ndef BVSignedCleanupFunction(x, type_bits):\n\tassert x.size() >= type_bits\n\tsign_mask = BitVecVal(1, x.size()) << (type_bits - 1)\n\tbit_mask = (BitVecVal(1, x.size()) << type_bits) - 1\n\treturn If(\n\t\tx & sign_mask == 0,\n\t\tx & bit_mask,\n\t\tx | ~bit_mask\n\t)\n\ndef BVUnsignedCleanupFunction(x, type_bits):\n\tassert x.size() >= type_bits\n\tbit_mask = (BitVecVal(1, x.size()) << type_bits) - 1\n\treturn x & bit_mask\n"
  },
  {
    "path": "test/libevmasm/Assembler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Alex Beregszaszi\n * @date 2018\n * Tests for the assembler.\n */\n#include <test/Common.h>\n\n#include <libevmasm/Assembly.h>\n#include <libsolutil/JSON.h>\n#include <libevmasm/Disassemble.h>\n#include <libevmasm/Ethdebug.h>\n#include <libyul/Exceptions.h>\n\n#include <test/Common.h>\n#include <boost/test/unit_test.hpp>\n\n#include <algorithm>\n#include <memory>\n#include <string>\n#include <tuple>\n\nusing namespace solidity::langutil;\nusing namespace solidity::evmasm;\nusing namespace solidity::test;\nusing namespace std::string_literals;\n\nnamespace solidity::frontend::test\n{\n\nnamespace\n{\n\tvoid checkCompilation(evmasm::Assembly const& _assembly)\n\t{\n\t\tLinkerObject output = _assembly.assemble();\n\t\tBOOST_CHECK(output.bytecode.size() > 0);\n\t\tBOOST_CHECK(output.toHex().length() > 0);\n\t}\n}\n\nBOOST_AUTO_TEST_SUITE(Assembler)\n\nBOOST_AUTO_TEST_CASE(all_assembly_items, *boost::unit_test::precondition(nonEOF()))\n{\n\tstd::map<std::string, unsigned> indices = {\n\t\t{ \"root.asm\", 0 },\n\t\t{ \"sub.asm\", 1 },\n\t\t{ \"verbatim.asm\", 2 }\n\t};\n\tEVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion();\n\tAssembly _assembly{evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), {}};\n\tauto root_asm = std::make_shared<std::string>(\"root.asm\");\n\t_assembly.setSourceLocation({1, 3, root_asm});\n\n\tAssembly _subAsm{evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), {}};\n\tauto sub_asm = std::make_shared<std::string>(\"sub.asm\");\n\t_subAsm.setSourceLocation({6, 8, sub_asm});\n\n\tAssembly _verbatimAsm(evmVersion, true, solidity::test::CommonOptions::get().eofVersion(), \"\");\n\tauto verbatim_asm = std::make_shared<std::string>(\"verbatim.asm\");\n\t_verbatimAsm.setSourceLocation({8, 18, verbatim_asm});\n\n\t// PushImmutable\n\t_subAsm.appendImmutable(\"someImmutable\");\n\t_subAsm.append(AssemblyItem(PushTag, 0));\n\t_subAsm.append(Instruction::INVALID);\n\tstd::shared_ptr<Assembly> _subAsmPtr = std::make_shared<Assembly>(_subAsm);\n\n\t_verbatimAsm.appendVerbatim({0xff,0xff}, 0, 0);\n\t_verbatimAsm.appendVerbatim({0x74, 0x65, 0x73, 0x74}, 0, 1);\n\t_verbatimAsm.append(Instruction::MSTORE);\n\tstd::shared_ptr<Assembly> _verbatimAsmPtr = std::make_shared<Assembly>(_verbatimAsm);\n\n\t// Tag\n\tauto tag = _assembly.newTag();\n\t_assembly.append(tag);\n\t// Operation\n\t_assembly.append(u256(1));\n\t_assembly.append(u256(2));\n\t// Push\n\tauto keccak256 = AssemblyItem(Instruction::KECCAK256);\n\t_assembly.m_currentModifierDepth = 1;\n\t_assembly.append(keccak256);\n\t_assembly.m_currentModifierDepth = 0;\n\t// PushProgramSize\n\t_assembly.appendProgramSize();\n\t// PushLibraryAddress\n\t_assembly.appendLibraryAddress(\"someLibrary\");\n\t// PushTag + Operation\n\t_assembly.appendJump(tag);\n\t// PushData\n\t_assembly.append(bytes{0x1, 0x2, 0x3, 0x4});\n\t// PushSubSize\n\tauto sub = _assembly.appendSubroutine(_subAsmPtr);\n\t// PushSub\n\t_assembly.pushSubroutineOffset(SubAssemblyID(sub.data()));\n\t// PushSubSize\n\tauto verbatim_sub = _assembly.appendSubroutine(_verbatimAsmPtr);\n\t// PushSub\n\t_assembly.pushSubroutineOffset(SubAssemblyID(verbatim_sub.data()));\n\t// PushDeployTimeAddress\n\t_assembly.append(PushDeployTimeAddress);\n\t// AssignImmutable.\n\t// Note that since there is no reference to \"someOtherImmutable\", this will just compile to two POPs in the hex output.\n\t_assembly.appendImmutableAssignment(\"someOtherImmutable\");\n\t_assembly.append(u256(2));\n\t_assembly.appendImmutableAssignment(\"someImmutable\");\n\t// Operation\n\t_assembly.append(Instruction::STOP);\n\t_assembly.appendToAuxiliaryData(bytes{0x42, 0x66});\n\t_assembly.appendToAuxiliaryData(bytes{0xee, 0xaa});\n\n\t_assembly.m_currentModifierDepth = 2;\n\t_assembly.appendJump(tag);\n\t_assembly.m_currentModifierDepth = 0;\n\n\tcheckCompilation(_assembly);\n\n\tBOOST_CHECK_EQUAL(\n\t\t_assembly.assemble().toHex(),\n\t\t\"5b6001600220607f73__$bf005014d9d0f534b8fcb268bd84c491a2$__\"\n\t\t\"60005660776024604c600760707300000000000000000000000000000000000000005050\"\n\t\t\"600260010152\"\n\t\t\"006000\"\n\t\t\"56fe\"\n\t\t\"7f0000000000000000000000000000000000000000000000000000000000000000\"\n\t\t\"6000feffff7465737452010203044266eeaa\"\n\t);\n\tBOOST_CHECK_EQUAL(\n\t\t_assembly.assemblyString(),\n\t\t\"    /* \\\"root.asm\\\":1:3   */\\n\"\n\t\t\"tag_1:\\n\"\n\t\t\"  keccak256(0x02, 0x01)\\n\"\n\t\t\"  bytecodeSize\\n\"\n\t\t\"  linkerSymbol(\\\"bf005014d9d0f534b8fcb268bd84c491a2380f4acd260d1ccfe9cd8201f7e994\\\")\\n\"\n\t\t\"  jump(tag_1)\\n\"\n\t\t\"  data_a6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b\\n\"\n\t\t\"  dataSize(sub_0)\\n\"\n\t\t\"  dataOffset(sub_0)\\n\"\n\t\t\"  dataSize(sub_1)\\n\"\n\t\t\"  dataOffset(sub_1)\\n\"\n\t\t\"  deployTimeAddress()\\n\"\n\t\t\"  assignImmutable(\\\"0xc3978657661c4d8e32e3d5f42597c009f0d3859e9f9d0d94325268f9799e2bfb\\\")\\n\"\n\t\t\"  0x02\\n\"\n\t\t\"  assignImmutable(\\\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\\\")\\n\"\n\t\t\"  stop\\n\"\n\t\t\"  jump(tag_1)\\n\"\n\t\t\"stop\\n\"\n\t\t\"data_a6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b 01020304\\n\"\n\t\t\"\\n\"\n\t\t\"sub_0: assembly {\\n\"\n\t\t\"        /* \\\"sub.asm\\\":6:8   */\\n\"\n\t\t\"      immutable(\\\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\\\")\\n\"\n\t\t\"      tag_0\\n\"\n\t\t\"      invalid\\n\"\n\t\t\"}\\n\"\n\t\t\"\\n\"\n\t\t\"sub_1: assembly {\\n\"\n\t\t\"        /* \\\"verbatim.asm\\\":8:18   */\\n\"\n\t\t\"      verbatimbytecode_ffff\\n\"\n\t\t\"      verbatimbytecode_74657374\\n\"\n\t\t\"      mstore\\n\"\n\t\t\"}\\n\"\n\t\t\"\\n\"\n\t\t\"auxdata: 0x4266eeaa\\n\"\n\t);\n\tstd::string json{\n\t\t\"{\\\".auxdata\\\":\\\"4266eeaa\\\",\\\".code\\\":[\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"tag\\\",\\\"source\\\":0,\\\"value\\\":\\\"1\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"JUMPDEST\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"1\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"2\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"modifierDepth\\\":1,\\\"name\\\":\\\"KECCAK256\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSHSIZE\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSHLIB\\\",\\\"source\\\":0,\\\"value\\\":\\\"someLibrary\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH [tag]\\\",\\\"source\\\":0,\\\"value\\\":\\\"1\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"JUMP\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH data\\\",\\\"source\\\":0,\\\"value\\\":\\\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH #[$]\\\",\\\"source\\\":0,\\\"value\\\":\\\"0000000000000000000000000000000000000000000000000000000000000000\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH [$]\\\",\\\"source\\\":0,\\\"value\\\":\\\"0000000000000000000000000000000000000000000000000000000000000000\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH #[$]\\\",\\\"source\\\":0,\\\"value\\\":\\\"0000000000000000000000000000000000000000000000000000000000000001\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH [$]\\\",\\\"source\\\":0,\\\"value\\\":\\\"0000000000000000000000000000000000000000000000000000000000000001\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSHDEPLOYADDRESS\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"ASSIGNIMMUTABLE\\\",\\\"source\\\":0,\\\"value\\\":\\\"someOtherImmutable\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"2\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"ASSIGNIMMUTABLE\\\",\\\"source\\\":0,\\\"value\\\":\\\"someImmutable\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"STOP\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"modifierDepth\\\":2,\\\"name\\\":\\\"PUSH [tag]\\\",\\\"source\\\":0,\\\"value\\\":\\\"1\\\"},{\\\"begin\\\":1,\\\"end\\\":3,\\\"modifierDepth\\\":2,\\\"name\\\":\\\"JUMP\\\",\\\"source\\\":0}\"\n\t\t\"],\\\".data\\\":{\\\"0\\\":{\\\".code\\\":[\"\n\t\t\"{\\\"begin\\\":6,\\\"end\\\":8,\\\"name\\\":\\\"PUSHIMMUTABLE\\\",\\\"source\\\":1,\\\"value\\\":\\\"someImmutable\\\"},\"\n\t\t\"{\\\"begin\\\":6,\\\"end\\\":8,\\\"name\\\":\\\"PUSH [ErrorTag]\\\",\\\"source\\\":1},\"\n\t\t\"{\\\"begin\\\":6,\\\"end\\\":8,\\\"name\\\":\\\"INVALID\\\",\\\"source\\\":1}\"\n\t\t\"]},\"\n\t\t\"\\\"1\\\":{\\\".code\\\":[\"\n\t\t\"{\\\"begin\\\":8,\\\"end\\\":18,\\\"name\\\":\\\"VERBATIM\\\",\\\"source\\\":2,\\\"value\\\":\\\"ffff\\\"},\"\n\t\t\"{\\\"begin\\\":8,\\\"end\\\":18,\\\"name\\\":\\\"VERBATIM\\\",\\\"source\\\":2,\\\"value\\\":\\\"74657374\\\"},\"\n\t\t\"{\\\"begin\\\":8,\\\"end\\\":18,\\\"name\\\":\\\"MSTORE\\\",\\\"source\\\":2}\"\n\t\t\"]},\\\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\\\":\\\"01020304\\\"},\\\"sourceList\\\":[\\\"root.asm\\\",\\\"sub.asm\\\",\\\"verbatim.asm\\\"]}\"\n\t};\n\tJson jsonValue;\n\tBOOST_CHECK(util::jsonParseStrict(json, jsonValue));\n\tBOOST_CHECK_EQUAL(util::jsonCompactPrint(_assembly.assemblyJSON(indices)), util::jsonCompactPrint(jsonValue));\n}\n\n// TODO: Implement EOF counterpart\nBOOST_AUTO_TEST_CASE(immutables_and_its_source_maps, *boost::unit_test::precondition(nonEOF()))\n{\n\tEVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion();\n\t// Tests for 1, 2, 3 number of immutables.\n\tfor (int numImmutables = 1; numImmutables <= 3; ++numImmutables)\n\t{\n\t\tBOOST_TEST_MESSAGE(\"NumImmutables: \"s + std::to_string(numImmutables));\n\t\t// Tests for the cases 1, 2, 3 occurrences of an immutable reference.\n\t\tfor (int numActualRefs = 1; numActualRefs <= 3; ++numActualRefs)\n\t\t{\n\t\t\tBOOST_TEST_MESSAGE(\"NumActualRefs: \"s + std::to_string(numActualRefs));\n\t\t\tauto const NumExpectedMappings =\n\t\t\t\t(\n\t\t\t\t\t2 +                        // PUSH <a> PUSH <b>\n\t\t\t\t\t(numActualRefs - 1) * 5 +  // DUP DUP PUSH <n> ADD MSTORE\n\t\t\t\t\t3                          // PUSH <n> ADD MSTORE\n\t\t\t\t) * numImmutables;\n\n\t\t\tauto constexpr NumSubs = 1;\n\t\t\tauto constexpr NumOpcodesWithoutMappings =\n\t\t\t\tNumSubs +                  // PUSH <addr> for every sub assembly\n\t\t\t\t1;                         // INVALID\n\n\t\t\tauto assemblyName = std::make_shared<std::string>(\"root.asm\");\n\t\t\tauto subName = std::make_shared<std::string>(\"sub.asm\");\n\n\t\t\tstd::map<std::string, unsigned> indices = {\n\t\t\t\t{ *assemblyName, 0 },\n\t\t\t\t{ *subName, 1 }\n\t\t\t};\n\n\t\t\tauto subAsm = std::make_shared<Assembly>(evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), std::string{});\n\t\t\tfor (char i = 0; i < numImmutables; ++i)\n\t\t\t{\n\t\t\t\tfor (int r = 0; r < numActualRefs; ++r)\n\t\t\t\t{\n\t\t\t\t\tsubAsm->setSourceLocation(SourceLocation{10*i, 10*i + 6 + r, subName});\n\t\t\t\t\tsubAsm->appendImmutable(std::string(1, char('a' + i))); // \"a\", \"b\", ...\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tAssembly assembly{evmVersion, true, solidity::test::CommonOptions::get().eofVersion(), {}};\n\t\t\tfor (char i = 1; i <= numImmutables; ++i)\n\t\t\t{\n\t\t\t\tassembly.setSourceLocation({10*i, 10*i + 3+i, assemblyName});\n\t\t\t\tassembly.append(u256(0x71));              // immutble value\n\t\t\t\tassembly.append(u256(0));                 // target... modules?\n\t\t\t\tassembly.appendImmutableAssignment(std::string(1, char('a' + i - 1)));\n\t\t\t}\n\n\t\t\tassembly.appendSubroutine(subAsm);\n\n\t\t\tcheckCompilation(assembly);\n\n\t\t\tBOOST_REQUIRE(assembly.codeSections().size() == 1);\n\t\t\tstd::string const sourceMappings = AssemblyItem::computeSourceMapping(assembly.codeSections().at(0).items, indices);\n\t\t\tauto const numberOfMappings = std::count(sourceMappings.begin(), sourceMappings.end(), ';');\n\n\t\t\tLinkerObject const& obj = assembly.assemble();\n\t\t\tstd::string const disassembly = disassemble(obj.bytecode, evmVersion, \"\\n\");\n\t\t\tauto const numberOfOpcodes = std::count(disassembly.begin(), disassembly.end(), '\\n');\n\n\t\t\t#if 0 // {{{ debug prints\n\t\t\t{\n\t\t\t\tLinkerObject const& subObj = assembly.sub(0).assemble();\n\t\t\t\tstd::string const subDisassembly = disassemble(subObj.bytecode, \"\\n\");\n\t\t\t\tstd::cout << '\\n';\n\t\t\t\tstd::cout << \"### immutables: \" << numImmutables << \", refs: \" << numActualRefs << '\\n';\n\t\t\t\tstd::cout << \" - srcmap: \\\"\" << sourceMappings << \"\\\"\\n\";\n\t\t\t\tstd::cout << \" - src mappings: \" << numberOfMappings << '\\n';\n\t\t\t\tstd::cout << \" - opcodes: \" << numberOfOpcodes << '\\n';\n\t\t\t\tstd::cout << \" - subs: \" << assembly.numSubs() << '\\n';\n\t\t\t\tstd::cout << \" - sub opcodes \" << std::count(subDisassembly.begin(), subDisassembly.end(), '\\n') << '\\n';\n\t\t\t\tstd::cout << \" - sub srcmaps \" << AssemblyItem::computeSourceMapping(subAsm->items(), indices) << '\\n';\n\t\t\t\tstd::cout << \" - main bytecode:\\n\\t\" << disassemble(obj.bytecode, \"\\n\\t\");\n\t\t\t\tstd::cout << \"\\r - sub bytecode:\\n\\t\" << disassemble(subObj.bytecode, \"\\n\\t\");\n\t\t\t}\n\t\t\t#endif // }}}\n\n\t\t\tBOOST_REQUIRE_EQUAL(NumExpectedMappings, numberOfMappings);\n\t\t\tBOOST_REQUIRE_EQUAL(NumExpectedMappings, numberOfOpcodes - NumOpcodesWithoutMappings);\n\t\t}\n\t}\n}\n\n// TODO: Implement EOF counterpart\nBOOST_AUTO_TEST_CASE(immutable, *boost::unit_test::precondition(nonEOF()))\n{\n\tstd::map<std::string, unsigned> indices = {\n\t\t{ \"root.asm\", 0 },\n\t\t{ \"sub.asm\", 1 }\n\t};\n\tEVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion();\n\tAssembly _assembly{evmVersion, true, solidity::test::CommonOptions::get().eofVersion(), {}};\n\tauto root_asm = std::make_shared<std::string>(\"root.asm\");\n\t_assembly.setSourceLocation({1, 3, root_asm});\n\n\tAssembly _subAsm{evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), {}};\n\tauto sub_asm = std::make_shared<std::string>(\"sub.asm\");\n\t_subAsm.setSourceLocation({6, 8, sub_asm});\n\t_subAsm.appendImmutable(\"someImmutable\");\n\t_subAsm.appendImmutable(\"someOtherImmutable\");\n\t_subAsm.appendImmutable(\"someImmutable\");\n\tstd::shared_ptr<Assembly> _subAsmPtr = std::make_shared<Assembly>(_subAsm);\n\n\t_assembly.append(u256(42));\n\t_assembly.append(u256(0));\n\t_assembly.appendImmutableAssignment(\"someImmutable\");\n\t_assembly.append(u256(23));\n\t_assembly.append(u256(0));\n\t_assembly.appendImmutableAssignment(\"someOtherImmutable\");\n\n\tauto sub = _assembly.appendSubroutine(_subAsmPtr);\n\t_assembly.pushSubroutineOffset(SubAssemblyID(sub.data()));\n\n\tcheckCompilation(_assembly);\n\n\tstd::string genericPush0 = evmVersion.hasPush0() ? \"5f\" : \"6000\";\n\t// PUSH1 0x1b v/s PUSH1 0x19\n\tstd::string dataOffset = evmVersion.hasPush0() ? \"6019\" : \"601b\" ;\n\n\tBOOST_CHECK_EQUAL(\n\t\t_assembly.assemble().toHex(),\n\t\t// root.asm\n\t\t// assign \"someImmutable\"\n\t\t\"602a\" + // PUSH1 42 - value for someImmutable\n\t\tgenericPush0 + // PUSH1 0 - offset of code into which to insert the immutable\n\t\t\"8181\" // DUP2 DUP2\n\t\t\"6001\" // PUSH1 1 - offset of first someImmutable in sub_0\n\t\t\"01\" // ADD - add offset of immutable to offset of code\n\t\t\"52\" // MSTORE\n\t\t\"6043\" // PUSH1 67 - offset of second someImmutable in sub_0\n\t\t\"01\" // ADD - add offset of immutable to offset of code\n\t\t\"52\" // MSTORE\n\t\t// assign \"someOtherImmutable\"\n\t\t\"6017\" + // PUSH1 23 - value for someOtherImmutable\n\t\tgenericPush0 + // PUSH1 0 - offset of code into which to insert the immutable\n\t\t\"6022\" // PUSH1 34 - offset of someOtherImmutable in sub_0\n\t\t\"01\" // ADD - add offset of immutable to offset of code\n\t\t\"52\" // MSTORE\n\t\t\"6063\" + // PUSH1 0x63 - dataSize(sub_0)\n\t\tdataOffset +  // PUSH1 0x23 - dataOffset(sub_0)\n\t\t\"fe\" // INVALID\n\t\t// end of root.asm\n\t\t// sub.asm\n\t\t\"7f0000000000000000000000000000000000000000000000000000000000000000\" // PUSHIMMUTABLE someImmutable - data at offset 1\n\t\t\"7f0000000000000000000000000000000000000000000000000000000000000000\" // PUSHIMMUTABLE someOtherImmutable - data at offset 34\n\t\t\"7f0000000000000000000000000000000000000000000000000000000000000000\" // PUSHIMMUTABLE someImmutable - data at offset 67\n\t);\n\tBOOST_CHECK_EQUAL(\n\t\t_assembly.assemblyString(),\n\t\t\"    /* \\\"root.asm\\\":1:3   */\\n\"\n\t\t\"  0x2a\\n\"\n\t\t\"  0x00\\n\"\n\t\t\"  assignImmutable(\\\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\\\")\\n\"\n\t\t\"  0x17\\n\"\n\t\t\"  0x00\\n\"\n\t\t\"  assignImmutable(\\\"0xc3978657661c4d8e32e3d5f42597c009f0d3859e9f9d0d94325268f9799e2bfb\\\")\\n\"\n\t\t\"  dataSize(sub_0)\\n\"\n\t\t\"  dataOffset(sub_0)\\n\"\n\t\t\"stop\\n\"\n\t\t\"\\n\"\n\t\t\"sub_0: assembly {\\n\"\n\t\t\"        /* \\\"sub.asm\\\":6:8   */\\n\"\n\t\t\"      immutable(\\\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\\\")\\n\"\n\t\t\"      immutable(\\\"0xc3978657661c4d8e32e3d5f42597c009f0d3859e9f9d0d94325268f9799e2bfb\\\")\\n\"\n\t\t\"      immutable(\\\"0x26f2c0195e9d408feff3abd77d83f2971f3c9a18d1e8a9437c7835ae4211fc9f\\\")\\n\"\n\t\t\"}\\n\"\n\t);\n\tBOOST_CHECK_EQUAL(\n\t\tutil::jsonCompactPrint(_assembly.assemblyJSON(indices)),\n\t\t\"{\\\".code\\\":[\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"2A\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"0\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"ASSIGNIMMUTABLE\\\",\\\"source\\\":0,\\\"value\\\":\\\"someImmutable\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"17\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"0\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"ASSIGNIMMUTABLE\\\",\\\"source\\\":0,\\\"value\\\":\\\"someOtherImmutable\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH #[$]\\\",\\\"source\\\":0,\\\"value\\\":\\\"0000000000000000000000000000000000000000000000000000000000000000\\\"},\"\n\t\t\"{\\\"begin\\\":1,\\\"end\\\":3,\\\"name\\\":\\\"PUSH [$]\\\",\\\"source\\\":0,\\\"value\\\":\\\"0000000000000000000000000000000000000000000000000000000000000000\\\"}\"\n\t\t\"],\\\".data\\\":{\\\"0\\\":{\\\".code\\\":[\"\n\t\t\"{\\\"begin\\\":6,\\\"end\\\":8,\\\"name\\\":\\\"PUSHIMMUTABLE\\\",\\\"source\\\":1,\\\"value\\\":\\\"someImmutable\\\"},\"\n\t\t\"{\\\"begin\\\":6,\\\"end\\\":8,\\\"name\\\":\\\"PUSHIMMUTABLE\\\",\\\"source\\\":1,\\\"value\\\":\\\"someOtherImmutable\\\"},\"\n\t\t\"{\\\"begin\\\":6,\\\"end\\\":8,\\\"name\\\":\\\"PUSHIMMUTABLE\\\",\\\"source\\\":1,\\\"value\\\":\\\"someImmutable\\\"}\"\n\t\t\"]}},\\\"sourceList\\\":[\\\"root.asm\\\",\\\"sub.asm\\\"]}\"\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(subobject_encode_decode)\n{\n\tEVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion();\n\tAssembly assembly{evmVersion, true, solidity::test::CommonOptions::get().eofVersion(), {}};\n\n\tstd::shared_ptr<Assembly> subAsmPtr = std::make_shared<Assembly>(evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), std::string{});\n\tstd::shared_ptr<Assembly> subSubAsmPtr = std::make_shared<Assembly>(evmVersion, false, solidity::test::CommonOptions::get().eofVersion(), std::string{});\n\n\tassembly.appendSubroutine(subAsmPtr);\n\tsubAsmPtr->appendSubroutine(subSubAsmPtr);\n\n\tBOOST_CHECK(assembly.encodeSubPath({SubAssemblyID{0}}).value == 0);\n\tBOOST_REQUIRE_THROW(assembly.encodeSubPath({SubAssemblyID{1}}), solidity::langutil::InternalCompilerError);\n\tBOOST_REQUIRE_THROW(assembly.decodeSubPath(SubAssemblyID{1}), solidity::evmasm::AssemblyException);\n\n\tstd::vector<SubAssemblyID> subPath{{0}, {0}};\n\tBOOST_CHECK(assembly.decodeSubPath(assembly.encodeSubPath(subPath)) == subPath);\n}\n\nBOOST_AUTO_TEST_CASE(ethdebug_program_last_instruction_with_immediate_arguments)\n{\n\tEVMVersion evmVersion = solidity::test::CommonOptions::get().evmVersion();\n\t{\n\t\tAssembly assembly{evmVersion, true, {}, {}};\n\t\tassembly.append(AssemblyItem{0x11223344});\n\t\tLinkerObject output = assembly.assemble();\n\n\t\tJson const program = ethdebug::program(\"\", 0, assembly, output);\n\t\tBOOST_REQUIRE(program[\"instructions\"].size() == 1);\n\t\tBOOST_REQUIRE(program[\"instructions\"][0][\"operation\"][\"mnemonic\"] == \"PUSH4\");\n\t\tBOOST_REQUIRE(program[\"instructions\"][0][\"operation\"][\"arguments\"][0] == \"0x11223344\");\n\t}\n\t{\n\t\tAssembly assembly{evmVersion, true, {}, {}};\n\t\tassembly.append(AssemblyItem{Instruction::PUSH0});\n\t\tassembly.append(AssemblyItem{0x1122334455});\n\t\tLinkerObject output = assembly.assemble();\n\n\t\tJson const program = ethdebug::program(\"\", 0, assembly, output);\n\t\tBOOST_REQUIRE(program[\"instructions\"].size() == 2);\n\t\tBOOST_REQUIRE(program[\"instructions\"][0][\"operation\"][\"mnemonic\"] == \"PUSH0\");\n\t\tBOOST_REQUIRE(!program[\"instructions\"][0][\"operation\"].contains(\"arguments\"));\n\t\tBOOST_REQUIRE(program[\"instructions\"][1][\"operation\"][\"mnemonic\"] == \"PUSH5\");\n\t\tBOOST_REQUIRE(program[\"instructions\"][1][\"operation\"][\"arguments\"][0] == \"0x1122334455\");\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(ethdebug_resources)\n{\n\tJson const resources = ethdebug::resources({\"sourceA\", \"sourceB\"}, \"version1\");\n\tBOOST_REQUIRE(resources[\"compilation\"][\"compiler\"][\"name\"] == \"solc\");\n\tBOOST_REQUIRE(resources[\"compilation\"][\"compiler\"][\"version\"] == \"version1\");\n\tBOOST_REQUIRE(resources[\"compilation\"][\"sources\"].size() == 2);\n\tBOOST_REQUIRE(resources[\"compilation\"][\"sources\"][0][\"id\"] == 0);\n\tBOOST_REQUIRE(resources[\"compilation\"][\"sources\"][0][\"path\"] == \"sourceA\");\n\tBOOST_REQUIRE(resources[\"compilation\"][\"sources\"][1][\"id\"] == 1);\n\tBOOST_REQUIRE(resources[\"compilation\"][\"sources\"][1][\"path\"] == \"sourceB\");\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libevmasm/EVMAssemblyTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <test/libevmasm/EVMAssemblyTest.h>\n\n#include <test/libevmasm/PlainAssemblyParser.h>\n\n#include <test/Common.h>\n\n#include <libevmasm/Disassemble.h>\n#include <libevmasm/EVMAssemblyStack.h>\n\n#include <boost/algorithm/string/predicate.hpp>\n#include <boost/algorithm/string/split.hpp>\n#include <boost/algorithm/string/trim.hpp>\n\n#include <range/v3/view/map.hpp>\n\nusing namespace std::string_literals;\nusing namespace solidity;\nusing namespace solidity::test;\nusing namespace solidity::evmasm;\nusing namespace solidity::evmasm::test;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\n\nstd::vector<std::string> const EVMAssemblyTest::c_outputLabels = {\n\t\"InputAssemblyJSON\",\n\t\"Assembly\",\n\t\"Bytecode\",\n\t\"Opcodes\",\n\t\"SourceMappings\",\n};\n\nstd::unique_ptr<TestCase> EVMAssemblyTest::create(Config const& _config)\n{\n\treturn std::make_unique<EVMAssemblyTest>(_config.filename);\n}\n\nEVMAssemblyTest::EVMAssemblyTest(std::string const& _filename):\n\tEVMVersionRestrictedTestCase(_filename)\n{\n\tm_source = m_reader.source();\n\tm_expectation = m_reader.simpleExpectations();\n\n\tif (_filename.ends_with(\".asmjson\"))\n\t\tm_assemblyFormat = AssemblyFormat::JSON;\n\telse if (_filename.ends_with(\".asm\"))\n\t\tm_assemblyFormat = AssemblyFormat::Plain;\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Not an assembly test: \\\"\" + _filename + \"\\\". Allowed extensions: .asm, .asmjson.\"));\n\n\tm_selectedOutputs = m_reader.stringSetting(\"outputs\", \"Assembly,Bytecode,Opcodes,SourceMappings\");\n\tOptimisationPreset optimizationPreset = m_reader.enumSetting<OptimisationPreset>(\n\t\t\"optimizationPreset\",\n\t\t{\n\t\t\t{\"none\", OptimisationPreset::None},\n\t\t\t{\"minimal\", OptimisationPreset::Minimal},\n\t\t\t{\"standard\", OptimisationPreset::Standard},\n\t\t\t{\"full\", OptimisationPreset::Full},\n\t\t},\n\t\t\"none\"\n\t);\n\tm_optimizerSettings = Assembly::OptimiserSettings::translateSettings(OptimiserSettings::preset(optimizationPreset));\n\tsize_t defaultExpectedExecutionsPerDeployment = m_optimizerSettings.expectedExecutionsPerDeployment;\n\tm_optimizerSettings.expectedExecutionsPerDeployment = m_reader.sizetSetting(\n\t\t\"optimizer.expectedExecutionsPerDeployment\",\n\t\tm_optimizerSettings.expectedExecutionsPerDeployment\n\t);\n\tm_usingDefaultExpectedExecutionsPerDeployment =\n\t\tm_optimizerSettings.expectedExecutionsPerDeployment == defaultExpectedExecutionsPerDeployment;\n\n\tauto const optimizerComponentSetting = [&](std::string const& _component, bool& _setting) {\n\t\t_setting = m_reader.boolSetting(\"optimizer.\" + _component, _setting);\n\t};\n\toptimizerComponentSetting(\"inliner\", m_optimizerSettings.runInliner);\n\toptimizerComponentSetting(\"jumpdestRemover\", m_optimizerSettings.runJumpdestRemover);\n\toptimizerComponentSetting(\"peephole\", m_optimizerSettings.runPeephole);\n\toptimizerComponentSetting(\"deduplicate\", m_optimizerSettings.runDeduplicate);\n\toptimizerComponentSetting(\"cse\", m_optimizerSettings.runCSE);\n\toptimizerComponentSetting(\"constantOptimizer\", m_optimizerSettings.runConstantOptimiser);\n\n\t// TODO: Enable when assembly import for EOF is implemented.\n\tif (CommonOptions::get().eofVersion().has_value())\n\t\tm_shouldRun = false;\n}\n\nTestCase::TestResult EVMAssemblyTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted)\n{\n\tEVMAssemblyStack evmAssemblyStack(\n\t\tCommonOptions::get().evmVersion(),\n\t\tCommonOptions::get().eofVersion(),\n\t\tm_optimizerSettings\n\t);\n\n\tevmAssemblyStack.selectDebugInfo(DebugInfoSelection::AllExceptExperimental());\n\n\tstd::string assemblyJSON;\n\tswitch (m_assemblyFormat)\n\t{\n\tcase AssemblyFormat::JSON:\n\t\tassemblyJSON = m_source;\n\t\tbreak;\n\tcase AssemblyFormat::Plain:\n\t\tassemblyJSON = jsonPrint(\n\t\t\tPlainAssemblyParser{}.parse(m_reader.fileName().filename().string(), m_source),\n\t\t\t{JsonFormat::Pretty, 4}\n\t\t);\n\t\tbreak;\n\t}\n\n\ttry\n\t{\n\t\tevmAssemblyStack.parseAndAnalyze(m_reader.fileName().filename().string(), assemblyJSON);\n\t}\n\tcatch (AssemblyImportException const& _exception)\n\t{\n\t\tm_obtainedResult = \"AssemblyImportException: \"s + _exception.what() + \"\\n\";\n\t\treturn checkResult(_stream, _linePrefix, _formatted);\n\t}\n\n\tsoltestAssert(evmAssemblyStack.evmAssembly());\n\tif (!m_usingDefaultExpectedExecutionsPerDeployment && evmAssemblyStack.evmAssembly()->numSubs() == 0)\n\t\t// This is a common mistake. We can't issue a warning here, so let's report it as an error.\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\n\t\t\t\"The custom value specified for optimizer.expectedExecutionsPerDeployment has no effect \"\n\t\t\t\"on the creation assembly, which is the only assembly in the test.\"\n\t\t));\n\n\ttry\n\t{\n\t\tevmAssemblyStack.assemble();\n\t}\n\tcatch (Error const& _error)\n\t{\n\t\t// TODO: EVMAssemblyStack should catch these on its own and provide an error reporter.\n\t\tsoltestAssert(_error.comment(), \"Errors must include a message for the user.\");\n\t\tm_obtainedResult = Error::formatErrorType(_error.type()) + \": \" + *_error.comment() + \"\\n\";\n\t\treturn checkResult(_stream, _linePrefix, _formatted);\n\t}\n\tsoltestAssert(evmAssemblyStack.compilationSuccessful());\n\n\tauto const produceOutput = [&](std::string const& _output) {\n\t\tif (_output == \"InputAssemblyJSON\")\n\t\t\treturn assemblyJSON;\n\t\tif (_output == \"Assembly\")\n\t\t\treturn evmAssemblyStack.assemblyString({{m_reader.fileName().filename().string(), m_source}});\n\t\tif (_output == \"Bytecode\")\n\t\t\treturn util::toHex(evmAssemblyStack.object().bytecode);\n\t\tif (_output == \"Opcodes\")\n\t\t\treturn disassemble(evmAssemblyStack.object().bytecode, CommonOptions::get().evmVersion());\n\t\tif (_output == \"SourceMappings\")\n\t\t\treturn evmAssemblyStack.sourceMapping();\n\t\tsoltestAssert(false);\n\t\tunreachable();\n\t};\n\n\tstd::set<std::string> selectedOutputSet;\n\tboost::split(selectedOutputSet, m_selectedOutputs, boost::is_any_of(\",\"));\n\tfor (std::string const& output: c_outputLabels)\n\t\tif (selectedOutputSet.contains(output))\n\t\t{\n\t\t\tif (!m_obtainedResult.empty() && m_obtainedResult.back() != '\\n')\n\t\t\t\tm_obtainedResult += \"\\n\";\n\n\t\t\t// Don't trim on the left to avoid stripping indentation.\n\t\t\tstd::string content = produceOutput(output);\n\t\t\tboost::trim_right(content);\n\t\t\tstd::string separator = (content.empty() ? \"\" : (output == \"Assembly\" ? \"\\n\" : \" \"));\n\t\t\tm_obtainedResult += output + \":\" + separator + content;\n\t\t}\n\tif (!m_obtainedResult.empty() && m_obtainedResult.back() != '\\n')\n\t\tm_obtainedResult += \"\\n\";\n\n\treturn checkResult(_stream, _linePrefix, _formatted);\n}\n"
  },
  {
    "path": "test/libevmasm/EVMAssemblyTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <test/TestCase.h>\n\n#include <libevmasm/Assembly.h>\n\n#include <memory>\n#include <ostream>\n#include <string>\n#include <vector>\n\nnamespace solidity::evmasm::test\n{\n\n/// Custom test case that runs the final part of the compiler pipeline (assembling into bytecode).\n/// Supports two kinds of input (depending on file extension):\n/// - .asmjson: assembly JSON format produced by --asm-json.\n/// - .asm: plain assembly, a more limited but human-readable format that is internally converted\n///     to assembly JSON.\n///\n/// Available settings:\n/// - EVMVersion: The range of EVM versions to run the test for. Inherited from EVMVersionRestrictedTestCase.\n/// - bytecodeFormat: The range of bytecode formats (EOF/legacy) to run the test for. Inherited from EVMVersionRestrictedTestCase.\n/// - outputs: List of outputs to include in the test. The order of values does NOT determine the order\n///     in which the outputs are printed. Supported outputs: InputAssemblyJSON, Assembly, Bytecode, Opcodes, SourceMappings.\n///     The default is to print all outputs except InputAssemblyJSON.\n/// - optimizationPreset: Preset to load as the base optimizer settings.\n///     One of: none, minimal, standard, full. The default is none.\n/// - optimizer.*: A set of detailed optimizer settings applied on top of the base preset.\n///     Each one corresponds to a field in Assembly::OptimiserSettings and uses the value from the\n///     preset as its default. Available settings:\n///     - optimizer.expectedExecutionsPerDeployment (integer)\n///     - optimizer.inliner (bool)\n///     - optimizer.jumpdestRemover (bool)\n///     - optimizer.peephole (bool)\n///     - optimizer.deduplicate (bool)\n///     - optimizer.cse (bool)\n///     - optimizer.constantOptimizer (bool)\nclass EVMAssemblyTest: public frontend::test::EVMVersionRestrictedTestCase\n{\npublic:\n\tstatic std::unique_ptr<TestCase> create(Config const& _config);\n\n\tEVMAssemblyTest(std::string const& _filename);\n\n\tTestResult run(std::ostream& _stream, std::string const& _linePrefix = \"\", bool const _formatted = false) override;\n\nprivate:\n\tenum class AssemblyFormat\n\t{\n\t\tJSON,\n\t\tPlain,\n\t};\n\n\tstatic std::vector<std::string> const c_outputLabels;\n\n\tAssemblyFormat m_assemblyFormat{};\n\tstd::string m_selectedOutputs;\n\tevmasm::Assembly::OptimiserSettings m_optimizerSettings;\n\tbool m_usingDefaultExpectedExecutionsPerDeployment{};\n};\n\n}\n"
  },
  {
    "path": "test/libevmasm/Optimiser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Tests for the Solidity optimizer.\n */\n\n#include <test/Common.h>\n\n#include <libevmasm/CommonSubexpressionEliminator.h>\n#include <libevmasm/PeepholeOptimiser.h>\n#include <libevmasm/Inliner.h>\n#include <libevmasm/JumpdestRemover.h>\n#include <libevmasm/ControlFlowGraph.h>\n#include <libevmasm/BlockDeduplicator.h>\n#include <libevmasm/Assembly.h>\n\n#include <boost/test/unit_test.hpp>\n\n#include <range/v3/algorithm/any_of.hpp>\n\n#include <string>\n#include <tuple>\n#include <memory>\n\nusing namespace solidity::langutil;\nusing namespace solidity::evmasm;\nusing namespace solidity::test;\n\nnamespace solidity::frontend::test\n{\n\nnamespace\n{\n\tAssemblyItems addDummyLocations(AssemblyItems const& _input)\n\t{\n\t\t// add dummy locations to each item so that we can check that they are not deleted\n\t\tAssemblyItems input = _input;\n\t\tfor (AssemblyItem& item: input)\n\t\t\titem.setLocation({1, 3, nullptr});\n\t\treturn input;\n\t}\n\n\tevmasm::KnownState createInitialState(AssemblyItems const& _input)\n\t{\n\t\tevmasm::KnownState state;\n\t\tfor (auto const& item: addDummyLocations(_input))\n\t\t\tstate.feedItem(item, true);\n\t\treturn state;\n\t}\n\n\tAssemblyItems CSE(AssemblyItems const& _input, evmasm::KnownState const& _state = evmasm::KnownState())\n\t{\n\t\tAssemblyItems input = addDummyLocations(_input);\n\n\t\tbool usesMsize = ranges::any_of(_input, [](AssemblyItem const& _i) {\n\t\t\treturn _i == AssemblyItem{Instruction::MSIZE} || _i.type() == VerbatimBytecode;\n\t\t});\n\t\tevmasm::CommonSubexpressionEliminator cse(_state, CommonOptions::get().evmVersion());\n\t\tBOOST_REQUIRE(cse.feedItems(input.begin(), input.end(), usesMsize) == input.end());\n\t\tAssemblyItems output = cse.getOptimizedItems();\n\n\t\tfor (AssemblyItem const& item: output)\n\t\t{\n\t\t\tBOOST_CHECK(item == Instruction::POP || item.location().isValid());\n\t\t}\n\t\treturn output;\n\t}\n\n\tvoid checkCSE(\n\t\tAssemblyItems const& _input,\n\t\tAssemblyItems const& _expectation,\n\t\tKnownState const& _state = evmasm::KnownState()\n\t)\n\t{\n\t\tAssemblyItems output = CSE(_input, _state);\n\t\tBOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end());\n\t}\n\n\t/// In contrast to the function `CSE`, this function doesn't finish the CSE optimization on an\n\t/// instruction that breaks CSE Analysis block. Copied from Assembly.cpp\n\tAssemblyItems fullCSE(AssemblyItems const& _input)\n\t{\n\t\tAssemblyItems optimisedItems;\n\n\t\tbool usesMSize = ranges::any_of(_input, [](AssemblyItem const& _i) {\n\t\t\treturn _i == AssemblyItem{Instruction::MSIZE} || _i.type() == VerbatimBytecode;\n\t\t});\n\n\t\tauto iter = _input.begin();\n\t\twhile (iter != _input.end())\n\t\t{\n\t\t\tKnownState emptyState;\n\t\t\tCommonSubexpressionEliminator eliminator{emptyState, CommonOptions::get().evmVersion()};\n\t\t\tauto orig = iter;\n\t\t\titer = eliminator.feedItems(iter, _input.end(), usesMSize);\n\t\t\tbool shouldReplace = false;\n\t\t\tAssemblyItems optimisedChunk;\n\t\t\toptimisedChunk = eliminator.getOptimizedItems();\n\t\t\tshouldReplace = (optimisedChunk.size() < static_cast<size_t>(iter - orig));\n\t\t\tif (shouldReplace)\n\t\t\t\toptimisedItems += optimisedChunk;\n\t\t\telse\n\t\t\t\tcopy(orig, iter, back_inserter(optimisedItems));\n\t\t}\n\n\t\treturn optimisedItems;\n\t}\n\n\tvoid checkFullCSE(\n\t\tAssemblyItems const& _input,\n\t\tAssemblyItems const& _expectation\n\t)\n\t{\n\t\tAssemblyItems output = fullCSE(_input);\n\t\tBOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end());\n\t}\n\n\tAssemblyItems CFG(AssemblyItems const& _input)\n\t{\n\t\tAssemblyItems output = _input;\n\t\t// Running it four times should be enough for these tests.\n\t\tfor (unsigned i = 0; i < 4; ++i)\n\t\t{\n\t\t\tControlFlowGraph cfg(output);\n\t\t\tAssemblyItems optItems;\n\t\t\tfor (BasicBlock const& block: cfg.optimisedBlocks())\n\t\t\t\tcopy(output.begin() + static_cast<int>(block.begin), output.begin() + static_cast<int>(block.end),\n\t\t\t\t\t back_inserter(optItems));\n\t\t\toutput = std::move(optItems);\n\t\t}\n\t\treturn output;\n\t}\n\n\tvoid checkCFG(AssemblyItems const& _input, AssemblyItems const& _expectation)\n\t{\n\t\tAssemblyItems output = CFG(_input);\n\t\tBOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end());\n\t}\n}\n\nBOOST_AUTO_TEST_SUITE(Optimiser)\n\nBOOST_AUTO_TEST_CASE(cse_push_immutable_same)\n{\n\tAssemblyItem pushImmutable{PushImmutable, 0x1234};\n\tcheckCSE({pushImmutable, pushImmutable}, {pushImmutable, Instruction::DUP1});\n}\n\nBOOST_AUTO_TEST_CASE(cse_push_immutable_different)\n{\n\tAssemblyItems input{{PushImmutable, 0x1234},{PushImmutable, 0xABCD}};\n\tcheckCSE(input, input);\n}\n\nBOOST_AUTO_TEST_CASE(cse_assign_immutable)\n{\n\t{\n\t\tAssemblyItems input{u256(0x42), {AssignImmutable, 0x1234}};\n\t\tcheckCSE(input, input);\n\t}\n\t{\n\t\tAssemblyItems input{{AssignImmutable, 0x1234}};\n\t\tcheckCSE(input, input);\n\t}\n}\n\n\nBOOST_AUTO_TEST_CASE(cse_assign_immutable_breaks)\n{\n\tAssemblyItems input = addDummyLocations(AssemblyItems{\n\t\tu256(0x42),\n\t\t{AssignImmutable, 0x1234},\n\t\tInstruction::ORIGIN\n\t});\n\n\tevmasm::CommonSubexpressionEliminator cse{evmasm::KnownState(), CommonOptions::get().evmVersion()};\n\t// Make sure CSE breaks after AssignImmutable.\n\tBOOST_REQUIRE(cse.feedItems(input.begin(), input.end(), false) == input.begin() + 2);\n}\n\nBOOST_AUTO_TEST_CASE(cse_intermediate_swap)\n{\n\tevmasm::KnownState state;\n\tevmasm::CommonSubexpressionEliminator cse(state, CommonOptions::get().evmVersion());\n\tAssemblyItems input{\n\t\tInstruction::SWAP1, Instruction::POP, Instruction::ADD, u256(0), Instruction::SWAP1,\n\t\tInstruction::SLOAD, Instruction::SWAP1, u256(100), Instruction::EXP, Instruction::SWAP1,\n\t\tInstruction::DIV, u256(0xff), Instruction::AND\n\t};\n\tBOOST_REQUIRE(cse.feedItems(input.begin(), input.end(), false) == input.end());\n\tAssemblyItems output = cse.getOptimizedItems();\n\tBOOST_CHECK(!output.empty());\n}\n\nBOOST_AUTO_TEST_CASE(cse_negative_stack_access)\n{\n\tAssemblyItems input{Instruction::DUP2, u256(0)};\n\tcheckCSE(input, input);\n}\n\nBOOST_AUTO_TEST_CASE(cse_negative_stack_end)\n{\n\tAssemblyItems input{Instruction::ADD};\n\tcheckCSE(input, input);\n}\n\nBOOST_AUTO_TEST_CASE(cse_intermediate_negative_stack)\n{\n\tAssemblyItems input{Instruction::ADD, u256(1), Instruction::DUP1};\n\tcheckCSE(input, input);\n}\n\nBOOST_AUTO_TEST_CASE(cse_pop)\n{\n\tcheckCSE({Instruction::POP}, {Instruction::POP});\n}\n\nBOOST_AUTO_TEST_CASE(cse_unneeded_items)\n{\n\tAssemblyItems input{\n\t\tInstruction::ADD,\n\t\tInstruction::SWAP1,\n\t\tInstruction::POP,\n\t\tu256(7),\n\t\tu256(8),\n\t};\n\tcheckCSE(input, input);\n}\n\nBOOST_AUTO_TEST_CASE(cse_constant_addition)\n{\n\tAssemblyItems input{u256(7), u256(8), Instruction::ADD};\n\tcheckCSE(input, {u256(7 + 8)});\n}\n\nBOOST_AUTO_TEST_CASE(cse_invariants)\n{\n\tAssemblyItems input{\n\t\tInstruction::DUP1,\n\t\tInstruction::DUP1,\n\t\tu256(0),\n\t\tInstruction::OR,\n\t\tInstruction::OR\n\t};\n\tcheckCSE(input, {Instruction::DUP1});\n}\n\nBOOST_AUTO_TEST_CASE(cse_subself)\n{\n\tcheckCSE({Instruction::DUP1, Instruction::SUB}, {Instruction::POP, u256(0)});\n}\n\nBOOST_AUTO_TEST_CASE(cse_subother)\n{\n\tcheckCSE({Instruction::SUB}, {Instruction::SUB});\n}\n\nBOOST_AUTO_TEST_CASE(cse_double_negation)\n{\n\tcheckCSE({Instruction::DUP5, Instruction::NOT, Instruction::NOT}, {Instruction::DUP5});\n}\n\nBOOST_AUTO_TEST_CASE(cse_double_iszero)\n{\n\tcheckCSE({Instruction::GT, Instruction::ISZERO, Instruction::ISZERO}, {Instruction::GT});\n\tcheckCSE({Instruction::GT, Instruction::ISZERO}, {Instruction::GT, Instruction::ISZERO});\n\tcheckCSE(\n\t\t{Instruction::ISZERO, Instruction::ISZERO, Instruction::ISZERO},\n\t\t{Instruction::ISZERO}\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(cse_associativity)\n{\n\tAssemblyItems input{\n\t\tInstruction::DUP1,\n\t\tInstruction::DUP1,\n\t\tu256(0),\n\t\tInstruction::OR,\n\t\tInstruction::OR\n\t};\n\tcheckCSE(input, {Instruction::DUP1});\n}\n\nBOOST_AUTO_TEST_CASE(cse_associativity2)\n{\n\tAssemblyItems input{\n\t\tu256(0),\n\t\tInstruction::DUP2,\n\t\tu256(2),\n\t\tu256(1),\n\t\tInstruction::DUP6,\n\t\tInstruction::ADD,\n\t\tu256(2),\n\t\tInstruction::ADD,\n\t\tInstruction::ADD,\n\t\tInstruction::ADD,\n\t\tInstruction::ADD\n\t};\n\tcheckCSE(input, {Instruction::DUP2, Instruction::DUP2, Instruction::ADD, u256(5), Instruction::ADD});\n}\n\nBOOST_AUTO_TEST_CASE(cse_double_shift_right_overflow)\n{\n\tif (solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())\n\t{\n\t\tAssemblyItems input{\n\t\t\tInstruction::CALLVALUE,\n\t\t\tu256(2),\n\t\t\tInstruction::SHR,\n\t\t\tu256(-1),\n\t\t\tInstruction::SHR\n\t\t};\n\t\tcheckCSE(input, {u256(0)});\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(cse_double_shift_left_overflow)\n{\n\tif (solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())\n\t{\n\t\tAssemblyItems input{\n\t\t\tInstruction::DUP1,\n\t\t\tu256(2),\n\t\t\tInstruction::SHL,\n\t\t\tu256(-1),\n\t\t\tInstruction::SHL\n\t\t};\n\t\tcheckCSE(input, {u256(0)});\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(cse_byte_ordering_bug)\n{\n\tAssemblyItems input{\n\t\tu256(31),\n\t\tInstruction::CALLVALUE,\n\t\tInstruction::BYTE\n\t};\n\tcheckCSE(input, {u256(31), Instruction::CALLVALUE, Instruction::BYTE});\n}\n\nBOOST_AUTO_TEST_CASE(cse_byte_ordering_fix)\n{\n\tAssemblyItems input{\n\t\tInstruction::CALLVALUE,\n\t\tu256(31),\n\t\tInstruction::BYTE\n\t};\n\tcheckCSE(input, {u256(0xff), Instruction::CALLVALUE, Instruction::AND});\n}\n\nBOOST_AUTO_TEST_CASE(cse_storage)\n{\n\tAssemblyItems input{\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tInstruction::ADD,\n\t\tu256(0),\n\t\tInstruction::SSTORE\n\t};\n\tcheckCSE(input, {\n\t\tu256(0),\n\t\tInstruction::DUP1,\n\t\tInstruction::SLOAD,\n\t\tInstruction::DUP1,\n\t\tInstruction::ADD,\n\t\tInstruction::SWAP1,\n\t\tInstruction::SSTORE\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_noninterleaved_storage)\n{\n\t// two stores to the same location should be replaced by only one store, even if we\n\t// read in the meantime\n\tAssemblyItems input{\n\t\tu256(7),\n\t\tInstruction::DUP2,\n\t\tInstruction::SSTORE,\n\t\tInstruction::DUP1,\n\t\tInstruction::SLOAD,\n\t\tu256(8),\n\t\tInstruction::DUP3,\n\t\tInstruction::SSTORE\n\t};\n\tcheckCSE(input, {\n\t\tu256(8),\n\t\tInstruction::DUP2,\n\t\tInstruction::SSTORE,\n\t\tu256(7)\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_interleaved_storage)\n{\n\t// stores and reads to/from two unknown locations, should not optimize away the first store\n\tAssemblyItems input{\n\t\tu256(7),\n\t\tInstruction::DUP2,\n\t\tInstruction::SSTORE, // store to \"DUP1\"\n\t\tInstruction::DUP2,\n\t\tInstruction::SLOAD, // read from \"DUP2\", might be equal to \"DUP1\"\n\t\tu256(0),\n\t\tInstruction::DUP3,\n\t\tInstruction::SSTORE // store different value to \"DUP1\"\n\t};\n\tcheckCSE(input, input);\n}\n\nBOOST_AUTO_TEST_CASE(cse_interleaved_storage_same_value)\n{\n\t// stores and reads to/from two unknown locations, should not optimize away the first store\n\t// but it should optimize away the second, since we already know the value will be the same\n\tAssemblyItems input{\n\t\tu256(7),\n\t\tInstruction::DUP2,\n\t\tInstruction::SSTORE, // store to \"DUP1\"\n\t\tInstruction::DUP2,\n\t\tInstruction::SLOAD, // read from \"DUP2\", might be equal to \"DUP1\"\n\t\tu256(6),\n\t\tu256(1),\n\t\tInstruction::ADD,\n\t\tInstruction::DUP3,\n\t\tInstruction::SSTORE // store same value to \"DUP1\"\n\t};\n\tcheckCSE(input, {\n\t\tu256(7),\n\t\tInstruction::DUP2,\n\t\tInstruction::SSTORE,\n\t\tInstruction::DUP2,\n\t\tInstruction::SLOAD\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_interleaved_storage_at_known_location)\n{\n\t// stores and reads to/from two known locations, should optimize away the first store,\n\t// because we know that the location is different\n\tAssemblyItems input{\n\t\tu256(0x70),\n\t\tu256(1),\n\t\tInstruction::SSTORE, // store to 1\n\t\tu256(2),\n\t\tInstruction::SLOAD, // read from 2, is different from 1\n\t\tu256(0x90),\n\t\tu256(1),\n\t\tInstruction::SSTORE // store different value at 1\n\t};\n\tcheckCSE(input, {\n\t\tu256(2),\n\t\tInstruction::SLOAD,\n\t\tu256(0x90),\n\t\tu256(1),\n\t\tInstruction::SSTORE\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_interleaved_storage_at_known_location_offset)\n{\n\t// stores and reads to/from two locations which are known to be different,\n\t// should optimize away the first store, because we know that the location is different\n\tAssemblyItems input{\n\t\tu256(0x70),\n\t\tInstruction::DUP2,\n\t\tu256(1),\n\t\tInstruction::ADD,\n\t\tInstruction::SSTORE, // store to \"DUP1\"+1\n\t\tInstruction::DUP1,\n\t\tu256(2),\n\t\tInstruction::ADD,\n\t\tInstruction::SLOAD, // read from \"DUP1\"+2, is different from \"DUP1\"+1\n\t\tu256(0x90),\n\t\tInstruction::DUP3,\n\t\tu256(1),\n\t\tInstruction::ADD,\n\t\tInstruction::SSTORE // store different value at \"DUP1\"+1\n\t};\n\tcheckCSE(input, {\n\t\tu256(2),\n\t\tInstruction::DUP2,\n\t\tInstruction::ADD,\n\t\tInstruction::SLOAD,\n\t\tu256(0x90),\n\t\tu256(1),\n\t\tInstruction::DUP4,\n\t\tInstruction::ADD,\n\t\tInstruction::SSTORE\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_deep_stack)\n{\n\tAssemblyItems input{\n\t\tInstruction::ADD,\n\t\tInstruction::SWAP1,\n\t\tInstruction::POP,\n\t\tInstruction::SWAP8,\n\t\tInstruction::POP,\n\t\tInstruction::SWAP8,\n\t\tInstruction::POP,\n\t\tInstruction::SWAP8,\n\t\tInstruction::SWAP5,\n\t\tInstruction::POP,\n\t\tInstruction::POP,\n\t\tInstruction::POP,\n\t\tInstruction::POP,\n\t\tInstruction::POP,\n\t};\n\tcheckCSE(input, {\n\t\tInstruction::SWAP4,\n\t\tInstruction::SWAP12,\n\t\tInstruction::SWAP3,\n\t\tInstruction::SWAP11,\n\t\tInstruction::POP,\n\t\tInstruction::SWAP1,\n\t\tInstruction::SWAP3,\n\t\tInstruction::ADD,\n\t\tInstruction::SWAP8,\n\t\tInstruction::POP,\n\t\tInstruction::SWAP6,\n\t\tInstruction::POP,\n\t\tInstruction::POP,\n\t\tInstruction::POP,\n\t\tInstruction::POP,\n\t\tInstruction::POP,\n\t\tInstruction::POP,\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_jumpi_no_jump)\n{\n\tAssemblyItems input{\n\t\tu256(0),\n\t\tu256(1),\n\t\tInstruction::DUP2,\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMPI\n\t};\n\tcheckCSE(input, {\n\t\tu256(0),\n\t\tu256(1)\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_jumpi_jump)\n{\n\tAssemblyItems input{\n\t\tu256(1),\n\t\tu256(1),\n\t\tInstruction::DUP2,\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMPI\n\t};\n\tcheckCSE(input, {\n\t\tu256(1),\n\t\tInstruction::DUP1,\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_empty_keccak256)\n{\n\tAssemblyItems input{\n\t\tu256(0),\n\t\tInstruction::DUP2,\n\t\tInstruction::KECCAK256\n\t};\n\tcheckCSE(input, {\n\t\tu256(util::keccak256(bytesConstRef()))\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_partial_keccak256)\n{\n\tAssemblyItems input{\n\t\tu256(0xabcd) << (256 - 16),\n\t\tu256(0),\n\t\tInstruction::MSTORE,\n\t\tu256(2),\n\t\tu256(0),\n\t\tInstruction::KECCAK256\n\t};\n\tcheckCSE(input, {\n\t\tu256(0xabcd) << (256 - 16),\n\t\tu256(0),\n\t\tInstruction::MSTORE,\n\t\tu256(util::keccak256(bytes{0xab, 0xcd}))\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_location)\n{\n\t// Keccak-256 twice from same dynamic location\n\tAssemblyItems input{\n\t\tInstruction::DUP2,\n\t\tInstruction::DUP1,\n\t\tInstruction::MSTORE,\n\t\tu256(64),\n\t\tInstruction::DUP2,\n\t\tInstruction::KECCAK256,\n\t\tu256(64),\n\t\tInstruction::DUP3,\n\t\tInstruction::KECCAK256\n\t};\n\tcheckCSE(input, {\n\t\tInstruction::DUP2,\n\t\tInstruction::DUP1,\n\t\tInstruction::MSTORE,\n\t\tu256(64),\n\t\tInstruction::DUP2,\n\t\tInstruction::KECCAK256,\n\t\tInstruction::DUP1\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_content)\n{\n\t// Keccak-256 twice from different dynamic location but with same content\n\tAssemblyItems input{\n\t\tInstruction::DUP1,\n\t\tu256(0x80),\n\t\tInstruction::MSTORE, // m[128] = DUP1\n\t\tu256(0x20),\n\t\tu256(0x80),\n\t\tInstruction::KECCAK256, // keccak256(m[128..(128+32)])\n\t\tInstruction::DUP2,\n\t\tu256(12),\n\t\tInstruction::MSTORE, // m[12] = DUP1\n\t\tu256(0x20),\n\t\tu256(12),\n\t\tInstruction::KECCAK256 // keccak256(m[12..(12+32)])\n\t};\n\tcheckCSE(input, {\n\t\tu256(0x80),\n\t\tInstruction::DUP2,\n\t\tInstruction::DUP2,\n\t\tInstruction::MSTORE,\n\t\tu256(0x20),\n\t\tInstruction::SWAP1,\n\t\tInstruction::KECCAK256,\n\t\tu256(12),\n\t\tInstruction::DUP3,\n\t\tInstruction::SWAP1,\n\t\tInstruction::MSTORE,\n\t\tInstruction::DUP1\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_content_dynamic_store_in_between)\n{\n\t// Keccak-256 twice from different dynamic location but with same content,\n\t// dynamic mstore in between, which forces us to re-calculate the hash\n\tAssemblyItems input{\n\t\tu256(0x80),\n\t\tInstruction::DUP2,\n\t\tInstruction::DUP2,\n\t\tInstruction::MSTORE, // m[128] = DUP1\n\t\tu256(0x20),\n\t\tInstruction::DUP1,\n\t\tInstruction::DUP3,\n\t\tInstruction::KECCAK256, // keccak256(m[128..(128+32)])\n\t\tu256(12),\n\t\tInstruction::DUP5,\n\t\tInstruction::DUP2,\n\t\tInstruction::MSTORE, // m[12] = DUP1\n\t\tInstruction::DUP12,\n\t\tInstruction::DUP14,\n\t\tInstruction::MSTORE, // destroys memory knowledge\n\t\tInstruction::SWAP2,\n\t\tInstruction::SWAP1,\n\t\tInstruction::SWAP2,\n\t\tInstruction::KECCAK256 // keccak256(m[12..(12+32)])\n\t};\n\tcheckCSE(input, input);\n}\n\nBOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_content_noninterfering_store_in_between)\n{\n\t// Keccak-256 twice from different dynamic location but with same content,\n\t// dynamic mstore in between, but does not force us to re-calculate the hash\n\tAssemblyItems input{\n\t\tu256(0x80),\n\t\tInstruction::DUP2,\n\t\tInstruction::DUP2,\n\t\tInstruction::MSTORE, // m[128] = DUP1\n\t\tu256(0x20),\n\t\tInstruction::DUP1,\n\t\tInstruction::DUP3,\n\t\tInstruction::KECCAK256, // keccak256(m[128..(128+32)])\n\t\tu256(12),\n\t\tInstruction::DUP5,\n\t\tInstruction::DUP2,\n\t\tInstruction::MSTORE, // m[12] = DUP1\n\t\tInstruction::DUP12,\n\t\tu256(12 + 32),\n\t\tInstruction::MSTORE, // does not destroy memory knowledge\n\t\tInstruction::DUP13,\n\t\tu256(128 - 32),\n\t\tInstruction::MSTORE, // does not destroy memory knowledge\n\t\tu256(0x20),\n\t\tu256(12),\n\t\tInstruction::KECCAK256 // keccak256(m[12..(12+32)])\n\t};\n\t// if this changes too often, only count the number of SHA3 and MSTORE instructions\n\tAssemblyItems output = CSE(input);\n\tBOOST_CHECK_EQUAL(4, count(output.begin(), output.end(), AssemblyItem(Instruction::MSTORE)));\n\tBOOST_CHECK_EQUAL(1, count(output.begin(), output.end(), AssemblyItem(Instruction::KECCAK256)));\n}\n\nBOOST_AUTO_TEST_CASE(cse_with_initially_known_stack)\n{\n\tevmasm::KnownState state = createInitialState(AssemblyItems{\n\t\tu256(0x12),\n\t\tu256(0x20),\n\t\tInstruction::ADD\n\t});\n\tAssemblyItems input{\n\t\tu256(0x12 + 0x20)\n\t};\n\tcheckCSE(input, AssemblyItems{Instruction::DUP1}, state);\n}\n\nBOOST_AUTO_TEST_CASE(cse_equality_on_initially_known_stack)\n{\n\tevmasm::KnownState state = createInitialState(AssemblyItems{Instruction::DUP1});\n\tAssemblyItems input{\n\t\tInstruction::EQ\n\t};\n\tAssemblyItems output = CSE(input, state);\n\t// check that it directly pushes 1 (true)\n\tBOOST_CHECK(find(output.begin(), output.end(), AssemblyItem(u256(1))) != output.end());\n}\n\nBOOST_AUTO_TEST_CASE(cse_access_previous_sequence)\n{\n\t// Tests that the code generator detects whether it tries to access SLOAD instructions\n\t// from a sequenced expression which is not in its scope.\n\tevmasm::KnownState state = createInitialState(AssemblyItems{\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tu256(1),\n\t\tInstruction::ADD,\n\t\tu256(0),\n\t\tInstruction::SSTORE\n\t});\n\t// now stored: val_1 + 1 (value at sequence 1)\n\t// if in the following instructions, the SLOAD cresolves to \"val_1 + 1\",\n\t// this cannot be generated because we cannot load from sequence 1 anymore.\n\tAssemblyItems input{\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t};\n\tBOOST_CHECK_THROW(CSE(input, state), StackTooDeepException);\n\t// @todo for now, this throws an exception, but it should recover to the following\n\t// (or an even better version) at some point:\n\t// 0, SLOAD, 1, ADD, SSTORE, 0 SLOAD\n}\n\nBOOST_AUTO_TEST_CASE(cse_optimise_return)\n{\n\tcheckCSE(\n\t\tAssemblyItems{u256(0), u256(7), Instruction::RETURN},\n\t\tAssemblyItems{Instruction::STOP}\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused)\n{\n\t// remove parts of the code that are unused\n\tAssemblyItems input{\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tu256(7),\n\t\tAssemblyItem(Tag, 1),\n\t};\n\tcheckCFG(input, {});\n}\n\nBOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused_loop)\n{\n\tAssemblyItems input{\n\t\tAssemblyItem(PushTag, 3),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(7),\n\t\tAssemblyItem(PushTag, 2),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(8),\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 3),\n\t\tu256(11)\n\t};\n\tcheckCFG(input, {u256(11)});\n}\n\nBOOST_AUTO_TEST_CASE(control_flow_graph_reconnect_single_jump_source)\n{\n\t// move code that has only one unconditional jump source\n\tAssemblyItems input{\n\t\tu256(1),\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(2),\n\t\tAssemblyItem(PushTag, 3),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(3),\n\t\tAssemblyItem(PushTag, 2),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 3),\n\t\tu256(4),\n\t};\n\tcheckCFG(input, {u256(1), u256(3), u256(2), u256(4)});\n}\n\nBOOST_AUTO_TEST_CASE(control_flow_graph_do_not_remove_returned_to)\n{\n\t// do not remove parts that are \"returned to\"\n\tAssemblyItems input{\n\t\tAssemblyItem(PushTag, 1),\n\t\tAssemblyItem(PushTag, 2),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(2)\n\t};\n\tcheckCFG(input, {u256(2)});\n}\n\nBOOST_AUTO_TEST_CASE(block_deduplicator)\n{\n\tAssemblyItems input{\n\t\tAssemblyItem(PushTag, 2),\n\t\tAssemblyItem(PushTag, 1),\n\t\tAssemblyItem(PushTag, 3),\n\t\tu256(6),\n\t\tInstruction::SWAP3,\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(6),\n\t\tInstruction::SWAP3,\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(6),\n\t\tInstruction::SWAP3,\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 3)\n\t};\n\tBlockDeduplicator deduplicator(input);\n\tdeduplicator.deduplicate();\n\n\tstd::set<u256> pushTags;\n\tfor (AssemblyItem const& item: input)\n\t\tif (item.type() == PushTag)\n\t\t\tpushTags.insert(item.data());\n\tBOOST_CHECK_EQUAL(pushTags.size(), 2);\n}\n\nBOOST_AUTO_TEST_CASE(block_deduplicator_assign_immutable_same)\n{\n\tAssemblyItems blocks{\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(42),\n\t\tAssemblyItem{AssignImmutable, 0x1234},\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(42),\n\t\tAssemblyItem{AssignImmutable, 0x1234},\n\t\tInstruction::JUMP\n\t};\n\n\tAssemblyItems input = AssemblyItems{\n\t\tAssemblyItem(PushTag, 2),\n\t\tAssemblyItem(PushTag, 1),\n\t} + blocks;\n\tAssemblyItems output = AssemblyItems{\n\t\tAssemblyItem(PushTag, 1),\n\t\tAssemblyItem(PushTag, 1),\n\t} + blocks;\n\tBlockDeduplicator deduplicator(input);\n\tdeduplicator.deduplicate();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(input.begin(), input.end(), output.begin(), output.end());\n}\n\nBOOST_AUTO_TEST_CASE(block_deduplicator_assign_immutable_different_value)\n{\n\tAssemblyItems input{\n\t\tAssemblyItem(PushTag, 2),\n\t\tAssemblyItem(PushTag, 1),\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(42),\n\t\tAssemblyItem{AssignImmutable, 0x1234},\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(23),\n\t\tAssemblyItem{AssignImmutable, 0x1234},\n\t\tInstruction::JUMP\n\t};\n\tBlockDeduplicator deduplicator(input);\n\tBOOST_CHECK(!deduplicator.deduplicate());\n}\n\nBOOST_AUTO_TEST_CASE(block_deduplicator_assign_immutable_different_hash)\n{\n\tAssemblyItems input{\n\t\tAssemblyItem(PushTag, 2),\n\t\tAssemblyItem(PushTag, 1),\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(42),\n\t\tAssemblyItem{AssignImmutable, 0x1234},\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(42),\n\t\tAssemblyItem{AssignImmutable, 0xABCD},\n\t\tInstruction::JUMP\n\t};\n\tBlockDeduplicator deduplicator(input);\n\tBOOST_CHECK(!deduplicator.deduplicate());\n}\n\nBOOST_AUTO_TEST_CASE(block_deduplicator_loops)\n{\n\tAssemblyItems input{\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tAssemblyItem(PushTag, 1),\n\t\tAssemblyItem(PushTag, 2),\n\t\tInstruction::JUMPI,\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(5),\n\t\tu256(6),\n\t\tInstruction::SSTORE,\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(5),\n\t\tu256(6),\n\t\tInstruction::SSTORE,\n\t\tAssemblyItem(PushTag, 2),\n\t\tInstruction::JUMP,\n\t};\n\tBlockDeduplicator deduplicator(input);\n\tdeduplicator.deduplicate();\n\n\tstd::set<u256> pushTags;\n\tfor (AssemblyItem const& item: input)\n\t\tif (item.type() == PushTag)\n\t\t\tpushTags.insert(item.data());\n\tBOOST_CHECK_EQUAL(pushTags.size(), 1);\n}\n\nBOOST_AUTO_TEST_CASE(clear_unreachable_code)\n{\n\tAssemblyItems items{\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(5),\n\t\tu256(6),\n\t\tInstruction::SSTORE,\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tu256(5),\n\t\tu256(6)\n\t};\n\tAssemblyItems expectation{\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(5),\n\t\tu256(6),\n\t\tInstruction::SSTORE,\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP\n\t};\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(clear_unreachable_code_eof, *boost::unit_test::precondition(onEOF()))\n{\n\tfor (auto const& blockTerminatingItem:\n\t\t {\n\t\t\tAssemblyItem::relativeJumpTo(AssemblyItem(Tag, 1)),\n\t\t\tAssemblyItem::jumpToFunction(1, 0, 0),\n\t\t\tAssemblyItem::functionReturn(),\n\t\t\tAssemblyItem::returnContract(0),\n\t\t}\n \t)\n\t{\n\t\tAssemblyItems items{\n\t\t\tblockTerminatingItem,\n\t\t\tu256(0),\n\t\t\tInstruction::SLOAD,\n\t\t\tAssemblyItem(Tag, 2),\n\t\t\tu256(5),\n\t\t\tu256(6),\n\t\t\tInstruction::SSTORE,\n\t\t\tblockTerminatingItem,\n\t\t\tu256(5),\n\t\t\tu256(6)\n\t\t};\n\t\tAssemblyItems expectation{\n\t\t\tblockTerminatingItem,\n\t\t\tAssemblyItem(Tag, 2),\n\t\t\tu256(5),\n\t\t\tu256(6),\n\t\t\tInstruction::SSTORE,\n\t\t\tblockTerminatingItem,\n\t\t};\n\t\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\t\tBOOST_REQUIRE(peepOpt.optimise());\n\t\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\t\titems.begin(), items.end(),\n\t\t\texpectation.begin(), expectation.end()\n\t\t);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(is_zero_is_zero_rjumpi, *boost::unit_test::precondition(onEOF()))\n{\n\tAssemblyItems items{\n\t\tu256(1),\n\t\tInstruction::ISZERO,\n\t\tInstruction::ISZERO,\n\t\tAssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)),\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tAssemblyItem(Tag, 1),\n\t};\n\n\tAssemblyItems expectation{\n\t\tu256(1),\n\t\tAssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)),\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tAssemblyItem(Tag, 1),\n\t};\n\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(equal_is_zero_rjumpi, *boost::unit_test::precondition(onEOF()))\n{\n\tAssemblyItems items{\n\t\tu256(1),\n\t\tu256(2),\n\t\tInstruction::EQ,\n\t\tInstruction::ISZERO,\n\t\tAssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)),\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tAssemblyItem(Tag, 1),\n\t};\n\n\tAssemblyItems expectation{\n\t\tu256(1),\n\t\tu256(2),\n\t\tInstruction::SUB,\n\t\tAssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)),\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tAssemblyItem(Tag, 1),\n\t};\n\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(double_rjump, *boost::unit_test::precondition(onEOF()))\n{\n\tAssemblyItems items{\n\t\tu256(1),\n\t\tAssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)),\n\t\tAssemblyItem::relativeJumpTo(AssemblyItem(Tag, 2)),\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tAssemblyItem(Tag, 2),\n\t};\n\n\tAssemblyItems expectation{\n\t\tu256(1),\n\t\tInstruction::ISZERO,\n\t\tAssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 2)),\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tAssemblyItem(Tag, 2),\n\t};\n\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(rjump_to_next, *boost::unit_test::precondition(onEOF()))\n{\n\tAssemblyItems items{\n\t\tAssemblyItem::relativeJumpTo(AssemblyItem(Tag, 1)),\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t};\n\n\tAssemblyItems expectation{\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t};\n\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(rjumpi_to_next, *boost::unit_test::precondition(onEOF()))\n{\n\tAssemblyItems items{\n\t\tAssemblyItem::conditionalRelativeJumpTo(AssemblyItem(Tag, 1)),\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t};\n\n\tAssemblyItems expectation{\n\t\tInstruction::POP,\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t};\n\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(deduplicateNextTagBlockSize3)\n{\n\tAssemblyItems items{\n\t\tInstruction::JUMP,\n\t\tu256(0),\n\t\tu256(1),\n\t\tInstruction::REVERT,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(0),\n\t\tu256(1),\n\t\tInstruction::REVERT\n\t};\n\n\tAssemblyItems expectation{\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(0),\n\t\tu256(1),\n\t\tInstruction::REVERT\n\t};\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(deduplicateNextTagBlockSize2)\n{\n\tAssemblyItems items{\n\t\tInstruction::JUMP,\n\t\tu256(0),\n\t\tInstruction::SELFDESTRUCT,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(0),\n\t\tInstruction::SELFDESTRUCT\n\t};\n\n\tAssemblyItems expectation{\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tu256(0),\n\t\tInstruction::SELFDESTRUCT\n\t};\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(deduplicateNextTagBlockSize1)\n{\n\tAssemblyItems items{\n\t\tInstruction::JUMP,\n\t\tInstruction::STOP,\n\t\tAssemblyItem(Tag, 2),\n\t\tInstruction::STOP\n\t};\n\n\tAssemblyItems expectation{\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 2),\n\t\tInstruction::STOP\n\t};\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(peephole_double_push)\n{\n\tAssemblyItems items{\n\t\tu256(0),\n\t\tu256(0),\n\t\tu256(5),\n\t\tu256(5),\n\t\tu256(4),\n\t\tu256(5)\n\t};\n\tAssemblyItems expectation{\n\t\tu256(0),\n\t\tInstruction::DUP1,\n\t\tu256(5),\n\t\tInstruction::DUP1,\n\t\tu256(4),\n\t\tu256(5)\n\t};\n\n\t// `PUSH0 PUSH0` is cheaper than `DUP1 PUSH0`\n\tif (solidity::test::CommonOptions::get().evmVersion() >= EVMVersion::shanghai())\n\t\texpectation = {\n\t\t\tu256(0),\n\t\t\tu256(0),\n\t\t\tu256(5),\n\t\t\tInstruction::DUP1,\n\t\t\tu256(4),\n\t\t\tu256(5)\n\t\t};\n\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(peephole_pop_calldatasize)\n{\n\tAssemblyItems items{\n\t\tu256(4),\n\t\tInstruction::CALLDATASIZE,\n\t\tInstruction::LT,\n\t\tInstruction::POP\n\t};\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tfor (size_t i = 0; i < 3; i++)\n\t\tBOOST_CHECK(peepOpt.optimise());\n\tBOOST_CHECK(items.empty());\n}\n\nBOOST_AUTO_TEST_CASE(peephole_commutative_swap1)\n{\n\tstd::vector<Instruction> ops{\n\t\tInstruction::ADD,\n\t\tInstruction::MUL,\n\t\tInstruction::EQ,\n\t\tInstruction::AND,\n\t\tInstruction::OR,\n\t\tInstruction::XOR\n\t};\n\tfor (Instruction const op: ops)\n\t{\n\t\tAssemblyItems items{\n\t\t\tu256(1),\n\t\t\tu256(2),\n\t\t\tInstruction::SWAP1,\n\t\t\top,\n\t\t\tu256(4),\n\t\t\tu256(5)\n\t\t};\n\t\tAssemblyItems expectation{\n\t\t\tu256(1),\n\t\t\tu256(2),\n\t\t\top,\n\t\t\tu256(4),\n\t\t\tu256(5)\n\t\t};\n\t\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\t\tBOOST_REQUIRE(peepOpt.optimise());\n\t\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\t\titems.begin(), items.end(),\n\t\t\texpectation.begin(), expectation.end()\n\t\t);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(peephole_noncommutative_swap1)\n{\n\t// NOTE: not comprehensive\n\tstd::vector<Instruction> ops{\n\t\tInstruction::SUB,\n\t\tInstruction::DIV,\n\t\tInstruction::SDIV,\n\t\tInstruction::MOD,\n\t\tInstruction::SMOD,\n\t\tInstruction::EXP\n\t};\n\tfor (Instruction const op: ops)\n\t{\n\t\tAssemblyItems items{\n\t\t\tu256(1),\n\t\t\tu256(2),\n\t\t\tInstruction::SWAP1,\n\t\t\top,\n\t\t\tu256(4),\n\t\t\tu256(5)\n\t\t};\n\t\tAssemblyItems expectation{\n\t\t\tu256(1),\n\t\t\tu256(2),\n\t\t\tInstruction::SWAP1,\n\t\t\top,\n\t\t\tu256(4),\n\t\t\tu256(5)\n\t\t};\n\t\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\t\tBOOST_REQUIRE(!peepOpt.optimise());\n\t\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\t\titems.begin(), items.end(),\n\t\t\texpectation.begin(), expectation.end()\n\t\t);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(peephole_swap_comparison)\n{\n\tstd::map<Instruction, Instruction> swappableOps{\n\t\t{ Instruction::LT, Instruction::GT },\n\t\t{ Instruction::GT, Instruction::LT },\n\t\t{ Instruction::SLT, Instruction::SGT },\n\t\t{ Instruction::SGT, Instruction::SLT }\n\t};\n\n\tfor (auto const& op: swappableOps)\n\t{\n\t\tAssemblyItems items{\n\t\t\tu256(1),\n\t\t\tu256(2),\n\t\t\tInstruction::SWAP1,\n\t\t\top.first,\n\t\t\tu256(4),\n\t\t\tu256(5)\n\t\t};\n\t\tAssemblyItems expectation{\n\t\t\tu256(1),\n\t\t\tu256(2),\n\t\t\top.second,\n\t\t\tu256(4),\n\t\t\tu256(5)\n\t\t};\n\t\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\t\tBOOST_REQUIRE(peepOpt.optimise());\n\t\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\t\titems.begin(), items.end(),\n\t\t\texpectation.begin(), expectation.end()\n\t\t);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(peephole_truthy_and)\n{\n\tAssemblyItems items{\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::BALANCE,\n\t\tu256(0),\n\t\tInstruction::NOT,\n\t\tInstruction::AND,\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMPI\n\t};\n\tAssemblyItems expectation{\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::BALANCE,\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMPI\n\t};\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\n\nBOOST_AUTO_TEST_CASE(peephole_iszero_iszero_jumpi)\n{\n\tAssemblyItems items{\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tInstruction::CALLDATALOAD,\n\t\tInstruction::ISZERO,\n\t\tInstruction::ISZERO,\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMPI,\n\t\tu256(0),\n\t\tu256(0x20),\n\t\tInstruction::RETURN\n\t};\n\tAssemblyItems expectation{\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tInstruction::CALLDATALOAD,\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMPI,\n\t\tu256(0),\n\t\tu256(0x20),\n\t\tInstruction::RETURN\n\t};\n\tPeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_REQUIRE(peepOpt.optimise());\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t  items.begin(), items.end(),\n\t  expectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(jumpdest_removal)\n{\n\tAssemblyItems items{\n\t\tAssemblyItem(Tag, 2),\n\t\tAssemblyItem(PushTag, 1),\n\t\tu256(5),\n\t\tAssemblyItem(Tag, 10),\n\t\tAssemblyItem(Tag, 3),\n\t\tu256(6),\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::JUMP,\n\t};\n\tAssemblyItems expectation{\n\t\tAssemblyItem(PushTag, 1),\n\t\tu256(5),\n\t\tu256(6),\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::JUMP\n\t};\n\tJumpdestRemover jdr(items);\n\tBOOST_REQUIRE(jdr.optimise({}));\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies, *boost::unit_test::precondition(nonEOF()))\n{\n\t// This tests that tags from subassemblies are not removed\n\t// if they are referenced by a super-assembly. Furthermore,\n\t// tag unifications (due to block deduplication) is also\n\t// visible at the super-assembly.\n\n\tsolAssert(!solidity::test::CommonOptions::get().eofVersion().has_value());\n\tAssembly::OptimiserSettings settings;\n\tsettings.runInliner = false;\n\tsettings.runJumpdestRemover = true;\n\tsettings.runPeephole = true;\n\tsettings.runDeduplicate = true;\n\tsettings.runCSE = true;\n\tsettings.runConstantOptimiser = true;\n\tsettings.expectedExecutionsPerDeployment = OptimiserSettings{}.expectedExecutionsPerDeployment;\n\n\tauto const evmVersion = CommonOptions::get().evmVersion();\n\tAssembly main{evmVersion, false, std::nullopt, {}};\n\tAssemblyPointer sub = std::make_shared<Assembly>(evmVersion, true, std::nullopt, std::string{});\n\n\tsub->append(u256(1));\n\tauto t1 = sub->newTag();\n\tsub->append(t1);\n\tsub->append(u256(2));\n\tsub->append(Instruction::JUMP);\n\tauto t2 = sub->newTag();\n\tsub->append(t2); // Identical to T1, will be unified\n\tsub->append(u256(2));\n\tsub->append(Instruction::JUMP);\n\tauto t3 = sub->newTag();\n\tsub->append(t3);\n\tauto t4 = sub->newTag();\n\tsub->append(t4);\n\tauto t5 = sub->newTag();\n\tsub->append(t5); // This will be removed\n\tsub->append(u256(7));\n\tsub->append(t4.pushTag());\n\tsub->append(Instruction::JUMP);\n\n\tSubAssemblyID subId{main.appendSubroutine(sub).data()};\n\tmain.append(t1.toSubAssemblyTag(subId));\n\tmain.append(t1.toSubAssemblyTag(subId));\n\tmain.append(u256(8));\n\n\tmain.optimise(settings);\n\n\tAssemblyItems expectationMain{\n\t\tAssemblyItem(PushSubSize, 0),\n\t\tt1.toSubAssemblyTag(subId).pushTag(),\n\t\tt1.toSubAssemblyTag(subId).pushTag(),\n\t\tu256(8)\n\t};\n\tBOOST_REQUIRE(main.codeSections().size() == 1);\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\tmain.codeSections().at(0).items.begin(),main.codeSections().at(0).items.end(),\n\t\texpectationMain.begin(), expectationMain.end()\n\t);\n\n\tAssemblyItems expectationSub{\n\t\tu256(1), t1.tag(), u256(2), Instruction::JUMP, t4.tag(), u256(7), t4.pushTag(), Instruction::JUMP\n\t};\n\tBOOST_REQUIRE(sub->codeSections().size() == 1);\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\tsub->codeSections().at(0).items.begin(), sub->codeSections().at(0).items.end(),\n\t\texpectationSub.begin(), expectationSub.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(cse_sub_zero)\n{\n\tcheckCSE({\n\t\tu256(0),\n\t\tInstruction::DUP2,\n\t\tInstruction::SUB\n\t}, {\n\t\tInstruction::DUP1\n\t});\n\n\tcheckCSE({\n\t\tInstruction::DUP1,\n\t\tu256(0),\n\t\tInstruction::SUB\n\t}, {\n\t\tu256(0),\n\t\tInstruction::DUP2,\n\t\tInstruction::SWAP1,\n\t\tInstruction::SUB\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_simple_verbatim)\n{\n\tauto verbatim = AssemblyItem{bytes{1, 2, 3, 4, 5}, 0, 0};\n\tAssemblyItems input{verbatim};\n\tcheckCSE(input, input);\n\tcheckFullCSE(input, input);\n}\n\nBOOST_AUTO_TEST_CASE(cse_mload_pop)\n{\n\tAssemblyItems input{\n\t\tu256(1000),\n\t\tInstruction::MLOAD,\n\t\tInstruction::POP,\n\t};\n\n\tAssemblyItems output{\n\t};\n\n\tcheckCSE(input, output);\n\tcheckFullCSE(input, output);\n}\n\nBOOST_AUTO_TEST_CASE(cse_verbatim_mload)\n{\n\tauto verbatim = AssemblyItem{bytes{1, 2, 3, 4, 5}, 0, 0};\n\tAssemblyItems input{\n\t\tu256(1000),\n\t\tInstruction::MLOAD, // Should not be removed\n\t\tInstruction::POP,\n\t\tverbatim,\n\t\tu256(1000),\n\t\tInstruction::MLOAD, // Should not be removed\n\t\tInstruction::POP,\n\t};\n\n\tcheckFullCSE(input, input);\n}\n\nBOOST_AUTO_TEST_CASE(cse_sload_verbatim_dup)\n{\n\tauto verbatim = AssemblyItem{bytes{1, 2, 3, 4, 5}, 0, 0};\n\tAssemblyItems input{\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tverbatim\n\t};\n\n\tAssemblyItems output{\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tInstruction::DUP1,\n\t\tverbatim\n\t};\n\n\tcheckCSE(input, output);\n\tcheckFullCSE(input, output);\n}\n\nBOOST_AUTO_TEST_CASE(cse_verbatim_sload_sideeffect)\n{\n\tauto verbatim = AssemblyItem{bytes{1, 2, 3, 4, 5}, 0, 0};\n\tAssemblyItems input{\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tverbatim,\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t};\n\n\tcheckFullCSE(input, input);\n}\n\nBOOST_AUTO_TEST_CASE(cse_verbatim_eq)\n{\n\tauto verbatim = AssemblyItem{bytes{1, 2, 3, 4, 5}, 0, 0};\n\tAssemblyItems input{\n\t\tu256(0),\n\t\tInstruction::SLOAD,\n\t\tverbatim,\n\t\tInstruction::DUP1,\n\t\tInstruction::EQ\n\t};\n\n\tcheckFullCSE(input, input);\n}\n\nBOOST_AUTO_TEST_CASE(verbatim_knownstate)\n{\n\tKnownState state = createInitialState(AssemblyItems{\n\t\t\tInstruction::DUP1,\n\t\t\tInstruction::DUP2,\n\t\t\tInstruction::DUP3,\n\t\t\tInstruction::DUP4\n\t\t});\n\tstd::map<int, unsigned> const& stackElements = state.stackElements();\n\n\tBOOST_CHECK(state.stackHeight() == 4);\n\t// One more than stack height because of the initial unknown element.\n\tBOOST_CHECK(stackElements.size() == 5);\n\tBOOST_CHECK(stackElements.count(0));\n\tunsigned initialElement = stackElements.at(0);\n\t// Check if all the DUPs were correctly matched to the same class.\n\tfor (auto const& height: {1, 2, 3, 4})\n\t\tBOOST_CHECK(stackElements.at(height) == initialElement);\n\n\tauto verbatim2i5o = AssemblyItem{bytes{1, 2, 3, 4, 5}, 2, 5};\n\tstate.feedItem(verbatim2i5o);\n\n\tBOOST_CHECK(state.stackHeight() == 7);\n\t// Stack elements\n\t// Before verbatim: {{0, x}, {1, x}, {2, x}, {3, x}, {4, x}}\n\t// After verbatim: {{0, x}, {1, x}, {2, x}, {3, a}, {4, b}, {5, c}, {6, d}, {7, e}}\n\tBOOST_CHECK(stackElements.size() == 8);\n\n\tfor (auto const& height: {1, 2})\n\t\tBOOST_CHECK(stackElements.at(height) == initialElement);\n\n\tfor (auto const& height: {3, 4, 5, 6, 7})\n\t\tBOOST_CHECK(stackElements.at(height) != initialElement);\n\n\tfor (auto const& height1: {3, 4, 5, 6, 7})\n\t\tfor (auto const& height2: {3, 4, 5, 6, 7})\n\t\t\tif (height1 < height2)\n\t\t\t\tBOOST_CHECK(stackElements.at(height1) != stackElements.at(height2));\n}\n\nBOOST_AUTO_TEST_CASE(cse_remove_redundant_shift_masking)\n{\n\tif (!solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())\n\t\treturn;\n\n\tfor (unsigned i = 1; i < 256; i++)\n\t{\n\t\tcheckCSE({\n\t\t\tu256(boost::multiprecision::pow(u256(2), i) - 1),\n\t\t\tInstruction::CALLVALUE,\n\t\t\tu256(256-i),\n\t\t\tInstruction::SHR,\n\t\t\tInstruction::AND\n\t\t}, {\n\t\t\tInstruction::CALLVALUE,\n\t\t\tu256(256-i),\n\t\t\tInstruction::SHR,\n\t\t});\n\n\t\tcheckCSE({\n\t\t\tInstruction::CALLVALUE,\n\t\t\tu256(256-i),\n\t\t\tInstruction::SHR,\n\t\t\tu256(boost::multiprecision::pow(u256(2), i)-1),\n\t\t\tInstruction::AND\n\t\t}, {\n\t\t\tInstruction::CALLVALUE,\n\t\t\tu256(256-i),\n\t\t\tInstruction::SHR,\n\t\t});\n\t}\n\n\t// Check that opt. does NOT trigger\n\tfor (unsigned i = 1; i < 255; i++)\n\t{\n\t\tcheckCSE({\n\t\t\tu256(boost::multiprecision::pow(u256(2), i) - 1),\n\t\t\tInstruction::CALLVALUE,\n\t\t\tu256(255-i),\n\t\t\tInstruction::SHR,\n\t\t\tInstruction::AND\n\t\t}, { // Opt. did some reordering\n\t\t\tInstruction::CALLVALUE,\n\t\t\tu256(255-i),\n\t\t\tInstruction::SHR,\n\t\t\tu256(boost::multiprecision::pow(u256(2), i)-1),\n\t\t\tInstruction::AND\n\t\t});\n\n\t\tcheckCSE({\n\t\t\tInstruction::CALLVALUE,\n\t\t\tu256(255-i),\n\t\t\tInstruction::SHR,\n\t\t\tu256(boost::multiprecision::pow(u256(2), i)-1),\n\t\t\tInstruction::AND\n\t\t}, { // Opt. did some reordering\n\t\t\tu256(boost::multiprecision::pow(u256(2), i)-1),\n\t\t\tInstruction::CALLVALUE,\n\t\t\tu256(255-i),\n\t\t\tInstruction::SHR,\n\t\t\tInstruction::AND\n\t\t});\n\t}\n\n\t//(x >> (31*8)) & 0xffffffff\n\tcheckCSE({\n\t\tInstruction::CALLVALUE,\n\t\tu256(31*8),\n\t\tInstruction::SHR,\n\t\tu256(0xffffffff),\n\t\tInstruction::AND\n\t}, {\n\t\tInstruction::CALLVALUE,\n\t\tu256(31*8),\n\t\tInstruction::SHR\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_remove_unwanted_masking_of_address)\n{\n\tstd::vector<Instruction> ops{\n\t\tInstruction::ADDRESS,\n\t\tInstruction::CALLER,\n\t\tInstruction::ORIGIN,\n\t\tInstruction::COINBASE\n\t};\n\tfor (auto const& op: ops)\n\t{\n\t\tcheckCSE({\n\t\t\tu256(\"0xffffffffffffffffffffffffffffffffffffffff\"),\n\t\t\top,\n\t\t\tInstruction::AND\n\t\t}, {\n\t\t\top\n\t\t});\n\n\t\tcheckCSE({\n\t\t\top,\n\t\t\tu256(\"0xffffffffffffffffffffffffffffffffffffffff\"),\n\t\t\tInstruction::AND\n\t\t}, {\n\t\t\top\n\t\t});\n\n\t\t// do not remove mask for other masking\n\t\tcheckCSE({\n\t\t\tu256(1234),\n\t\t\top,\n\t\t\tInstruction::AND\n\t\t}, {\n\t\t\top,\n\t\t\tu256(1234),\n\t\t\tInstruction::AND\n\t\t});\n\n\t\tcheckCSE({\n\t\t\top,\n\t\t\tu256(1234),\n\t\t\tInstruction::AND\n\t\t}, {\n\t\t\tu256(1234),\n\t\t\top,\n\t\t\tInstruction::AND\n\t\t});\n\t}\n\n\t// leave other opcodes untouched\n\tcheckCSE({\n\t\tu256(\"0xffffffffffffffffffffffffffffffffffffffff\"),\n\t\tInstruction::CALLVALUE,\n\t\tInstruction::AND\n\t}, {\n\t\tInstruction::CALLVALUE,\n\t\tu256(\"0xffffffffffffffffffffffffffffffffffffffff\"),\n\t\tInstruction::AND\n\t});\n\n\tcheckCSE({\n\t\tInstruction::CALLVALUE,\n\t\tu256(\"0xffffffffffffffffffffffffffffffffffffffff\"),\n\t\tInstruction::AND\n\t}, {\n\t\tu256(\"0xffffffffffffffffffffffffffffffffffffffff\"),\n\t\tInstruction::CALLVALUE,\n\t\tInstruction::AND\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_replace_too_large_shift)\n{\n\tif (!solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())\n\t\treturn;\n\n\tcheckCSE({\n\t\tInstruction::CALLVALUE,\n\t\tu256(299),\n\t\tInstruction::SHL\n\t}, {\n\t\tu256(0)\n\t});\n\n\tcheckCSE({\n\t\tInstruction::CALLVALUE,\n\t\tu256(299),\n\t\tInstruction::SHR\n\t}, {\n\t\tu256(0)\n\t});\n\n\tcheckCSE({\n\t\tInstruction::CALLVALUE,\n\t\tu256(255),\n\t\tInstruction::SHL\n\t}, {\n\t\tInstruction::CALLVALUE,\n\t\tu256(255),\n\t\tInstruction::SHL\n\t});\n\n\tcheckCSE({\n\t\tInstruction::CALLVALUE,\n\t\tu256(255),\n\t\tInstruction::SHR\n\t}, {\n\t\tInstruction::CALLVALUE,\n\t\tu256(255),\n\t\tInstruction::SHR\n\t});\n}\n\nBOOST_AUTO_TEST_CASE(cse_dup)\n{\n\tAssemblyItems input{\n\t\tu256(0),\n\t\tInstruction::DUP1,\n\t\tInstruction::REVERT\n\t};\n\tAssemblyItems output = input;\n\n\tcheckCSE(input, output);\n\tcheckFullCSE(input, output);\n}\n\nBOOST_AUTO_TEST_CASE(cse_push0)\n{\n\tAssemblyItems input{\n\t\tu256(0),\n\t\tu256(0),\n\t\tInstruction::REVERT\n\t};\n\tAssemblyItems output{\n\t\tu256(0),\n\t\tInstruction::DUP1,\n\t\tInstruction::REVERT\n\t};\n\t// The CSE has a rule to replace with DUP1 PUSH0\n\tcheckCSE(input, output);\n\n\t// The full handling by the compiler (Assembly::optimiseInternal)\n\t// will not choose to replace the pattern, because the new size is the same as the old one\n\toutput = input;\n\tcheckFullCSE(input, output);\n}\n\nBOOST_AUTO_TEST_CASE(inliner)\n{\n\tAssemblyItem jumpInto{Instruction::JUMP};\n\tjumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction);\n\tAssemblyItem jumpOutOf{Instruction::JUMP};\n\tjumpOutOf.setJumpType(AssemblyItem::JumpType::OutOfFunction);\n\tAssemblyItems items{\n\t\tAssemblyItem(PushTag, 1),\n\t\tAssemblyItem(PushTag, 2),\n\t\tjumpInto,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::STOP,\n\t\tAssemblyItem(Tag, 2),\n\t\tInstruction::CALLVALUE,\n\t\tInstruction::SWAP1,\n\t\tjumpOutOf,\n\t};\n\tAssemblyItems expectation{\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::CALLVALUE,\n\t\tInstruction::SWAP1,\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::STOP,\n\t\tAssemblyItem(Tag, 2),\n\t\tInstruction::CALLVALUE,\n\t\tInstruction::SWAP1,\n\t\tjumpOutOf,\n\t};\n\tInliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\n\nBOOST_AUTO_TEST_CASE(inliner_no_inline_type)\n{\n\t// Will not inline due to jump types.\n\tAssemblyItems items{\n\t\tAssemblyItem(PushTag, 1),\n\t\tAssemblyItem(PushTag, 2),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::STOP,\n\t\tAssemblyItem(Tag, 2),\n\t\tInstruction::CALLVALUE,\n\t\tInstruction::SWAP1,\n\t\tInstruction::JUMP,\n\t};\n\tInliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\titems.begin(), items.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(inliner_no_inline)\n{\n\tAssemblyItems items{\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::CALLVALUE,\n\t\tInstruction::JUMPI,\n\t\tInstruction::JUMP,\n\t};\n\tAssemblyItems expectation{\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::CALLVALUE,\n\t\tInstruction::JUMPI,\n\t\tInstruction::JUMP,\n\t};\n\tInliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\n\nBOOST_AUTO_TEST_CASE(inliner_single_jump)\n{\n\tAssemblyItem jumpInto{Instruction::JUMP};\n\tjumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction);\n\tAssemblyItem jumpOutOf{Instruction::JUMP};\n\tjumpOutOf.setJumpType(AssemblyItem::JumpType::OutOfFunction);\n\tAssemblyItems items{\n\t\tAssemblyItem(PushTag, 1),\n\t\tAssemblyItem(PushTag, 2),\n\t\tjumpInto,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::STOP,\n\t\tAssemblyItem(Tag, 2),\n\t\tjumpOutOf,\n\t};\n\tAssemblyItems expectation{\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::STOP,\n\t\tAssemblyItem(Tag, 2),\n\t\tjumpOutOf,\n\t};\n\tInliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(inliner_end_of_bytecode)\n{\n\tAssemblyItem jumpInto{Instruction::JUMP};\n\tjumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction);\n\t// Cannot inline, since the block at Tag_2 does not end in a jump.\n\tAssemblyItems items{\n\t\tAssemblyItem(PushTag, 1),\n\t\tAssemblyItem(PushTag, 2),\n\t\tjumpInto,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::STOP,\n\t\tAssemblyItem(Tag, 2),\n\t};\n\tInliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\titems.begin(), items.end()\n\t);\n}\n\n\nBOOST_AUTO_TEST_CASE(inliner_cse_break)\n{\n\tAssemblyItem jumpInto{Instruction::JUMP};\n\tjumpInto.setJumpType(AssemblyItem::JumpType::IntoFunction);\n\tAssemblyItem jumpOutOf{Instruction::JUMP};\n\tjumpOutOf.setJumpType(AssemblyItem::JumpType::OutOfFunction);\n\t// Could be inlined, but we only consider non-CSE-breaking blocks ending in JUMP so far.\n\tAssemblyItems items{\n\t\tAssemblyItem(PushTag, 1),\n\t\tAssemblyItem(PushTag, 2),\n\t\tjumpInto,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::STOP,\n\t\tAssemblyItem(Tag, 2),\n\t\tInstruction::STOP, // CSE breaking instruction\n\t\tjumpOutOf\n\t};\n\tInliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\titems.begin(), items.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(inliner_stop)\n{\n\tAssemblyItems items{\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::STOP\n\t};\n\tAssemblyItems expectation{\n\t\tInstruction::STOP,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::STOP\n\t};\n\tInliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(inliner_stop_jumpi)\n{\n\t// Because of `jumpi`, will not be inlined.\n\tAssemblyItems items{\n\t\tu256(1),\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMPI,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::STOP\n\t};\n\tAssemblyItems expectation = items;\n\tInliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(inliner_revert)\n{\n\tAssemblyItems items{\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tInstruction::DUP1,\n\t\tInstruction::REVERT\n\t};\n\tAssemblyItems expectation{\n\t\tu256(0),\n\t\tInstruction::DUP1,\n\t\tInstruction::REVERT,\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tInstruction::DUP1,\n\t\tInstruction::REVERT\n\t};\n\n\tInliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(inliner_revert_push0)\n{\n\t// Inlining this without PUSH0 would increase data gas (5 bytes v/s 4 bytes), therefore, it would be skipped.\n\t// However, with PUSH0 it is inlined (3 bytes vs 4 bytes).\n\tAssemblyItems items{\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tu256(0),\n\t\tInstruction::REVERT\n\t};\n\tAssemblyItems expectation{\n\t\tu256(0),\n\t\tu256(0),\n\t\tInstruction::REVERT,\n\t\tAssemblyItem(Tag, 1),\n\t\tu256(0),\n\t\tu256(0),\n\t\tInstruction::REVERT\n\t};\n\n\tInliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(inliner_invalid)\n{\n\tAssemblyItems items{\n\t\tAssemblyItem(PushTag, 1),\n\t\tInstruction::JUMP,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::INVALID\n\t};\n\n\tAssemblyItems expectation = {\n\t\tInstruction::INVALID,\n\t\tAssemblyItem(Tag, 1),\n\t\tInstruction::INVALID\n\t};\n\tInliner{items, {}, Assembly::OptimiserSettings{}.expectedExecutionsPerDeployment, false, {}}.optimise();\n\tBOOST_CHECK_EQUAL_COLLECTIONS(\n\t\titems.begin(), items.end(),\n\t\texpectation.begin(), expectation.end()\n\t);\n}\n\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libevmasm/PlainAssemblyParser.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <test/libevmasm/PlainAssemblyParser.h>\n\n#include <test/Common.h>\n#include <test/libsolidity/util/SoltestErrors.h>\n\n#include <libevmasm/Instruction.h>\n\n#include <liblangutil/Common.h>\n\n#include <boost/algorithm/string/find.hpp>\n\n#include <fmt/format.h>\n\nusing namespace std::string_literals;\nusing namespace solidity;\nusing namespace solidity::test;\nusing namespace solidity::evmasm;\nusing namespace solidity::evmasm::test;\nusing namespace solidity::langutil;\n\nJson PlainAssemblyParser::parse(std::string _sourceName, std::string const& _source)\n{\n\tm_sourceStream = std::istringstream(_source);\n\tm_sourceName = std::move(_sourceName);\n\tm_lineNumber = 0;\n\n\tadvanceLine();\n\treturn parseAssembly(0);\n}\n\nJson PlainAssemblyParser::parseAssembly(size_t _nestingLevel)\n{\n\tJson assemblyJSON = {{\".code\", Json::array()}};\n\tJson& codeJSON = assemblyJSON[\".code\"];\n\n\twhile (m_line.has_value())\n\t{\n\t\tif (m_lineTokens.empty())\n\t\t{\n\t\t\tadvanceLine();\n\t\t\tcontinue;\n\t\t}\n\n\t\tsize_t newLevel = parseNestingLevel();\n\t\tif (newLevel > _nestingLevel)\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(formatError(\"Indentation does not match the current subassembly nesting level.\")));\n\n\t\tif (newLevel < _nestingLevel)\n\t\t\treturn assemblyJSON;\n\n\t\tif (currentToken().value == \".sub\")\n\t\t{\n\t\t\tadvanceLine();\n\n\t\t\tstd::string nextDataIndex = std::to_string(assemblyJSON[\".data\"].size());\n\t\t\tassemblyJSON[\".data\"][nextDataIndex] = parseAssembly(_nestingLevel + 1);\n\t\t\tcontinue;\n\t\t}\n\t\telse if (assemblyJSON.contains(\".data\"))\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(formatError(\"The code of an assembly must be specified before its subassemblies.\")));\n\n\t\tif (c_instructions.contains(currentToken().value) || currentToken().value == \"PUSHSIZE\")\n\t\t{\n\t\t\texpectNoMoreArguments();\n\t\t\tcodeJSON.push_back({{\"name\", currentToken().value}});\n\t\t}\n\t\telse if (currentToken().value == \"PUSH\")\n\t\t{\n\t\t\tif (hasMoreTokens() && nextToken().value == \"[tag]\")\n\t\t\t{\n\t\t\t\tadvanceToken();\n\t\t\t\tstd::string_view tagID = expectArgument();\n\t\t\t\texpectNoMoreArguments();\n\t\t\t\tcodeJSON.push_back({{\"name\", \"PUSH [tag]\"}, {\"value\", tagID}});\n\t\t\t}\n\t\t\telse if (hasMoreTokens() && (nextToken().value == \"[$]\" || nextToken().value == \"#[$]\"))\n\t\t\t{\n\t\t\t\tstd::string pushType = std::string(nextToken().value);\n\t\t\t\tadvanceToken();\n\t\t\t\tstd::string_view subassemblyID = expectArgument();\n\t\t\t\texpectNoMoreArguments();\n\n\t\t\t\tif (!subassemblyID.starts_with(\"0x\"))\n\t\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(formatError(\"The subassembly ID must be a hex number prefixed with '0x'.\")));\n\n\t\t\t\tsubassemblyID.remove_prefix(\"0x\"s.size());\n\t\t\t\tcodeJSON.push_back({{\"name\", \"PUSH \" + pushType}, {\"value\", subassemblyID}});\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstd::string_view immediateArgument = expectArgument();\n\t\t\t\texpectNoMoreArguments();\n\n\t\t\t\tif (!immediateArgument.starts_with(\"0x\"))\n\t\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(formatError(\"The immediate argument to PUSH must be a hex number prefixed with '0x'.\")));\n\n\t\t\t\timmediateArgument.remove_prefix(\"0x\"s.size());\n\t\t\t\tcodeJSON.push_back({{\"name\", \"PUSH\"}, {\"value\", immediateArgument}});\n\t\t\t}\n\t\t}\n\t\telse if (currentToken().value == \"tag\")\n\t\t{\n\t\t\tstd::string_view tagID = expectArgument();\n\t\t\texpectNoMoreArguments();\n\n\t\t\tcodeJSON.push_back({{\"name\", \"tag\"}, {\"value\", tagID}});\n\t\t\tcodeJSON.push_back({{\"name\", \"JUMPDEST\"}});\n\t\t}\n\t\telse\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(formatError(\"Unknown instruction.\")));\n\n\t\tadvanceLine();\n\t}\n\n\treturn assemblyJSON;\n}\n\nsize_t PlainAssemblyParser::parseNestingLevel() const\n{\n\tstd::string_view indentationString = indentation();\n\n\tif (indentationString != std::string(indentationString.size(), ' '))\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(formatError(\"Non-space characters used for indentation.\")));\n\n\tif (indentationString.size() % 4 != 0)\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(formatError(\"Each indentation level must consist of 4 spaces.\")));\n\n\treturn indentationString.size() / 4;\n}\n\nPlainAssemblyParser::Token const& PlainAssemblyParser::currentToken() const\n{\n\tsoltestAssert(m_tokenIndex < m_lineTokens.size());\n\treturn m_lineTokens[m_tokenIndex];\n}\n\nPlainAssemblyParser::Token const& PlainAssemblyParser::nextToken() const\n{\n\tsoltestAssert(m_tokenIndex + 1 < m_lineTokens.size());\n\treturn m_lineTokens[m_tokenIndex + 1];\n}\n\nstd::string_view PlainAssemblyParser::indentation() const\n{\n\tsoltestAssert(m_line.has_value());\n\n\tif (m_lineTokens.empty())\n\t\treturn *m_line;\n\n\treturn std::string_view(*m_line).substr(0, m_lineTokens.at(0).position);\n}\n\nbool PlainAssemblyParser::advanceToken()\n{\n\tif (!hasMoreTokens())\n\t\treturn false;\n\n\t++m_tokenIndex;\n\treturn true;\n}\n\nstd::string_view PlainAssemblyParser::expectArgument()\n{\n\tbool hasArgument = advanceToken();\n\tif (!hasArgument)\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(formatError(\"Missing argument(s).\")));\n\n\treturn currentToken().value;\n}\n\nvoid PlainAssemblyParser::expectNoMoreArguments()\n{\n\tbool hasArgument = advanceToken();\n\tif (hasArgument)\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(formatError(\"Too many arguments.\")));\n}\n\nbool PlainAssemblyParser::advanceLine()\n{\n\tstd::string line;\n\tif (!getline(m_sourceStream, line))\n\t{\n\t\tm_line = std::nullopt;\n\t\treturn false;\n\t}\n\n\t++m_lineNumber;\n\tm_line = std::move(line);\n\tm_lineTokens = tokenizeLine(*m_line);\n\tm_tokenIndex = 0;\n\treturn true;\n}\n\nstd::vector<PlainAssemblyParser::Token> PlainAssemblyParser::tokenizeLine(std::string_view _line)\n{\n\tauto const notWhiteSpace = [](char _c) { return !isWhiteSpace(_c); };\n\n\tstd::vector<Token> tokens;\n\tauto tokenLocation = boost::find_token(_line, notWhiteSpace, boost::token_compress_on);\n\twhile (!tokenLocation.empty())\n\t{\n\t\tstd::string_view value{tokenLocation.begin(), tokenLocation.end()};\n\t\tif (value.starts_with(\"//\"))\n\t\t\tbreak;\n\n\t\ttokens.push_back({\n\t\t\t.value = value,\n\t\t\t.position = static_cast<size_t>(std::distance(_line.begin(), tokenLocation.begin())),\n\t\t});\n\t\tsoltestAssert(!value.empty());\n\t\tsoltestAssert(tokens.back().position < _line.size());\n\t\tsoltestAssert(tokens.back().position + value.size() <= _line.size());\n\n\t\tstd::string_view tail{tokenLocation.end(), _line.end()};\n\t\ttokenLocation = boost::find_token(tail, notWhiteSpace, boost::token_compress_on);\n\t}\n\n\treturn tokens;\n}\n\nstd::string PlainAssemblyParser::formatError(std::string_view _message) const\n{\n\tsoltestAssert(m_line.has_value());\n\tsoltestAssert(!m_lineTokens.empty());\n\n\tstd::string lineNumberString = std::to_string(m_lineNumber);\n\tstd::string padding(lineNumberString.size(), ' ');\n\tstd::string underline = std::string(currentToken().position, ' ') + std::string(currentToken().value.size(), '^');\n\treturn fmt::format(\n\t\t\"Error while parsing plain assembly: {}\\n\"\n\t\t\"{}--> {}\\n\"\n\t\t\"{} | \\n\"\n\t\t\"{} | {}\\n\"\n\t\t\"{} | {}\\n\",\n\t\t_message,\n\t\tpadding, m_sourceName,\n\t\tpadding,\n\t\tm_lineNumber, *m_line,\n\t\tpadding, underline\n\t);\n}\n"
  },
  {
    "path": "test/libevmasm/PlainAssemblyParser.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/JSON.h>\n\n#include <sstream>\n#include <string>\n#include <string_view>\n#include <vector>\n\nnamespace solidity::evmasm::test\n{\n\n/// Parser for the plain assembly format. The format is meant to be good enough for humans to read\n/// while being straightforward to map to the assembly JSON format that solc can import.\n///\n/// Syntax:\n/// - Every line consists of zero or more whitespace-separated tokens.\n/// - A token that begins with `//` starts a comment, which extends to the end of the line.\n/// - A non-empty line represents a single assembly item.\n/// - The name of the item is the first thing on the line and may consist of one or more tokens.\n/// - One or more arguments follow the name.\n/// - Indentation determines assembly nesting level (4 spaces per level).\n/// - A new subassembly starts with '.sub' and contains all subsequent lines at a higher nesting level.\n///     The first line at the same or lower nesting level ends the subassembly.\n/// - Subassemblies can be nested to arbitrary depth.\n/// - The code of an assembly must be specified before its subassemblies.\n///\n/// Supported items:\n/// - All instruction names.\n/// - PUSH <hex value>\n/// - PUSH [tag] <tagID>\n/// - tag <tagID>\n/// - PUSH [$] <subassemblyID>\n/// - PUSH #[$] <subassemblyID>\n/// - .sub\nclass PlainAssemblyParser\n{\npublic:\n\t/// Parses plain assembly format and returns the equivalent assembly JSON.\n\t/// Errors are reported by throwing runtime_error.\n\tJson parse(std::string _sourceName, std::string const& _source);\n\nprotected:\n\tstruct Token\n\t{\n\t\tstd::string_view value; ///< Substring of m_line that represents a complete token.\n\t\tsize_t position;        ///< Position of the first character of the token within m_line.\n\t};\n\n\tJson parseAssembly(size_t _nestingLevel);\n\tsize_t parseNestingLevel() const;\n\n\tToken const& currentToken() const;\n\tToken const& nextToken() const;\n\tbool hasMoreTokens() const { return m_tokenIndex + 1 < m_lineTokens.size(); }\n\n\tstd::string_view indentation() const;\n\n\tbool advanceToken();\n\tstd::string_view expectArgument();\n\tvoid expectNoMoreArguments();\n\tbool advanceLine();\n\n\tstatic std::vector<Token> tokenizeLine(std::string_view _line);\n\tstd::string formatError(std::string_view _message) const;\n\nprivate:\n\tstd::istringstream m_sourceStream; ///< The source code being parsed.\n\tstd::string m_sourceName;          ///< Name of the file the source comes from.\n\tsize_t m_lineNumber = 0;           ///< The number of the current line within the source, 1-based.\n\tstd::optional<std::string> m_line; ///< The current line, unparsed.\n\tstd::vector<Token> m_lineTokens;   ///< Decomposition of the current line into tokens (does not include comments).\n\tsize_t m_tokenIndex = 0;           ///< Points at a token within m_lineTokens.\n};\n\n}\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/code_generation_error.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"PUSH [$]\", \"value\": \"0\"}\n    ],\n    \".data\": {\n        \"0\": {\n            \".code\": [\n                {\"name\": \"PUSHIMMUTABLE\", \"value\": \"x\"}\n            ]\n        }\n    }\n}\n// ----\n// CodeGenerationError: Some immutables were read from but never assigned, possibly because of optimization.\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/comments.asm",
    "content": "//\n//// comment\n    // comment\nCALLVALUE // 0xff\nCALLVALUE //0xff\n\nPUSH 0xff // comment // //0xff\n//\n\n//\n// ====\n// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings\n// ----\n// InputAssemblyJSON: {\n//     \".code\": [\n//         {\n//             \"name\": \"CALLVALUE\"\n//         },\n//         {\n//             \"name\": \"CALLVALUE\"\n//         },\n//         {\n//             \"name\": \"PUSH\",\n//             \"value\": \"ff\"\n//         }\n//     ]\n// }\n// Assembly:\n//   callvalue\n//   callvalue\n//   0xff\n// Bytecode: 343460ff\n// Opcodes: CALLVALUE CALLVALUE PUSH1 0xFF\n// SourceMappings: :::-:0;;\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/empty.asm",
    "content": "// ====\n// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings\n// ----\n// InputAssemblyJSON: {\n//     \".code\": []\n// }\n// Assembly:\n// Bytecode:\n// Opcodes:\n// SourceMappings:\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/invalid_json.asmjson",
    "content": "{\n// ----\n// AssemblyImportException: Could not parse JSON file.\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/jumps.asm",
    "content": "PUSH [tag] 1\nJUMP\ntag 1\nPUSH 0x01\nJUMPI\nPUSH [tag] 0x012AB\ntag 0x012AB\n// ====\n// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings\n// ----\n// InputAssemblyJSON: {\n//     \".code\": [\n//         {\n//             \"name\": \"PUSH [tag]\",\n//             \"value\": \"1\"\n//         },\n//         {\n//             \"name\": \"JUMP\"\n//         },\n//         {\n//             \"name\": \"tag\",\n//             \"value\": \"1\"\n//         },\n//         {\n//             \"name\": \"JUMPDEST\"\n//         },\n//         {\n//             \"name\": \"PUSH\",\n//             \"value\": \"01\"\n//         },\n//         {\n//             \"name\": \"JUMPI\"\n//         },\n//         {\n//             \"name\": \"PUSH [tag]\",\n//             \"value\": \"0x012AB\"\n//         },\n//         {\n//             \"name\": \"tag\",\n//             \"value\": \"0x012AB\"\n//         },\n//         {\n//             \"name\": \"JUMPDEST\"\n//         }\n//     ]\n// }\n// Assembly:\n//   jump(tag_1)\n// tag_1:\n//   0x01\n//   jumpi\n//   tag_4779\n// tag_4779:\n// Bytecode: 6003565b60015760095b\n// Opcodes: PUSH1 0x3 JUMP JUMPDEST PUSH1 0x1 JUMPI PUSH1 0x9 JUMPDEST\n// SourceMappings: :::-:0;;;;;;\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/nontrivial_subassembly_ids.asm",
    "content": "// sub_0 and children\nPUSH #[$] 0x0000\n// negative indices for nested subobjects in DFS order\nPUSH #[$] 0x000000000000000000000000000000000000000000000000ffffffffffffffff\nPUSH #[$] 0x000000000000000000000000000000000000000000000000fffffffffffffffe\nPUSH #[$] 0x000000000000000000000000000000000000000000000000fffffffffffffffd\nPUSH #[$] 0x000000000000000000000000000000000000000000000000fffffffffffffffc\n// sub_1 and children\nPUSH #[$] 0x0001\nPUSH #[$] 0x000000000000000000000000000000000000000000000000fffffffffffffffb\n\n.sub\n    // referencing sub_0.sub_0 from inside sub_0\n    PUSH #[$] 0x0000\n    // referencing sub_0.sub_0.sub_0 from inside sub_0\n    PUSH #[$] 0x000000000000000000000000000000000000000000000000ffffffffffffffff\n    .sub\n        .sub\n    .sub\n    .sub\n.sub\n    .sub\n// ----\n// Assembly:\n//   dataSize(sub_0)\n//   dataSize(sub_0.sub_0)\n//   dataSize(sub_0.sub_0.sub_0)\n//   dataSize(sub_0.sub_1)\n//   dataSize(sub_0.sub_2)\n//   dataSize(sub_1)\n//   dataSize(sub_1.sub_0)\n// stop\n//\n// sub_0: assembly {\n//       dataSize(sub_0)\n//       dataSize(sub_0.sub_0)\n//     stop\n//\n//     sub_0: assembly {\n//         stop\n//\n//         sub_0: assembly {\n//         }\n//     }\n//\n//     sub_1: assembly {\n//     }\n//\n//     sub_2: assembly {\n//     }\n// }\n//\n// sub_1: assembly {\n//     stop\n//\n//     sub_0: assembly {\n//     }\n// }\n// Bytecode: 6005600160006000600060016000fe\n// Opcodes: PUSH1 0x5 PUSH1 0x1 PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 INVALID\n// SourceMappings: :::-:0;;;;;;\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/operations.asm",
    "content": "NUMBER\nSLOAD\nADDRESS\nORIGIN\nADD\nDUP1\nSWAP1\nMSTORE8\nSTOP\n// ====\n// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings\n// ----\n// InputAssemblyJSON: {\n//     \".code\": [\n//         {\n//             \"name\": \"NUMBER\"\n//         },\n//         {\n//             \"name\": \"SLOAD\"\n//         },\n//         {\n//             \"name\": \"ADDRESS\"\n//         },\n//         {\n//             \"name\": \"ORIGIN\"\n//         },\n//         {\n//             \"name\": \"ADD\"\n//         },\n//         {\n//             \"name\": \"DUP1\"\n//         },\n//         {\n//             \"name\": \"SWAP1\"\n//         },\n//         {\n//             \"name\": \"MSTORE8\"\n//         },\n//         {\n//             \"name\": \"STOP\"\n//         }\n//     ]\n// }\n// Assembly:\n//   sload(number)\n//   add(origin, address)\n//   dup1\n//   swap1\n//   mstore8\n//   stop\n// Bytecode: 435430320180905300\n// Opcodes: NUMBER SLOAD ADDRESS ORIGIN ADD DUP1 SWAP1 MSTORE8 STOP\n// SourceMappings: :::-:0;;;;;;;;\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/push.asm",
    "content": "PUSH 0x0\nPUSH 0x1\nPUSH 0x0123456789ABCDEF\nPUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// ====\n// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings\n// ----\n// InputAssemblyJSON: {\n//     \".code\": [\n//         {\n//             \"name\": \"PUSH\",\n//             \"value\": \"0\"\n//         },\n//         {\n//             \"name\": \"PUSH\",\n//             \"value\": \"1\"\n//         },\n//         {\n//             \"name\": \"PUSH\",\n//             \"value\": \"0123456789ABCDEF\"\n//         },\n//         {\n//             \"name\": \"PUSH\",\n//             \"value\": \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n//         }\n//     ]\n// }\n// Assembly:\n//   0x00\n//   0x01\n//   0x0123456789abcdef\n//   0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// Bytecode: 5f6001670123456789abcdef7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// Opcodes: PUSH0 PUSH1 0x1 PUSH8 0x123456789ABCDEF PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// SourceMappings: :::-:0;;;\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/pushsize.asm",
    "content": "PUSHSIZE\n\n.sub\n    PUSHSIZE\n// ====\n// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings\n// ----\n// InputAssemblyJSON: {\n//     \".code\": [\n//         {\n//             \"name\": \"PUSHSIZE\"\n//         }\n//     ],\n//     \".data\": {\n//         \"0\": {\n//             \".code\": [\n//                 {\n//                     \"name\": \"PUSHSIZE\"\n//                 }\n//             ]\n//         }\n//     }\n// }\n// Assembly:\n//   bytecodeSize\n// stop\n//\n// sub_0: assembly {\n//       bytecodeSize\n// }\n// Bytecode: 6003fe\n// Opcodes: PUSH1 0x3 INVALID\n// SourceMappings: :::-:0\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/pushsubsize.asm",
    "content": "PUSH [$] 0x0000\nPUSH #[$] 0x0000\n\n.sub\n    PUSH [$] 0x0\n    PUSH #[$] 0x2\n\n    .sub\n    .sub\n    .sub\n// ====\n// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings\n// ----\n// InputAssemblyJSON: {\n//     \".code\": [\n//         {\n//             \"name\": \"PUSH [$]\",\n//             \"value\": \"0000\"\n//         },\n//         {\n//             \"name\": \"PUSH #[$]\",\n//             \"value\": \"0000\"\n//         }\n//     ],\n//     \".data\": {\n//         \"0\": {\n//             \".code\": [\n//                 {\n//                     \"name\": \"PUSH [$]\",\n//                     \"value\": \"0\"\n//                 },\n//                 {\n//                     \"name\": \"PUSH #[$]\",\n//                     \"value\": \"2\"\n//                 }\n//             ],\n//             \".data\": {\n//                 \"0\": {\n//                     \".code\": []\n//                 },\n//                 \"1\": {\n//                     \".code\": []\n//                 },\n//                 \"2\": {\n//                     \".code\": []\n//                 }\n//             }\n//         }\n//     }\n// }\n// Assembly:\n//   dataOffset(sub_0)\n//   dataSize(sub_0)\n// stop\n//\n// sub_0: assembly {\n//       dataOffset(sub_0)\n//       dataSize(sub_2)\n//     stop\n//\n//     sub_0: assembly {\n//     }\n//\n//     sub_1: assembly {\n//     }\n//\n//     sub_2: assembly {\n//     }\n// }\n// Bytecode: 60056005fe60056000fe\n// Opcodes: PUSH1 0x5 PUSH1 0x5 INVALID PUSH1 0x5 PUSH1 0x0 INVALID\n// SourceMappings: :::-:0;\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/settings_eof_version.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"CODESIZE\"}\n    ]\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Assembly:\n//   codesize\n// Bytecode: 38\n// Opcodes: CODESIZE\n// SourceMappings: :::-:0\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/settings_evm_version.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"BLOBBASEFEE\"}\n    ]\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// Assembly:\n//   blobbasefee\n// Bytecode: 4a\n// Opcodes: BLOBBASEFEE\n// SourceMappings: :::-:0\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_constant_optimizer.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"PUSH\", \"value\": \"ffffffffffffffff\"}\n    ]\n}\n// ====\n// optimizationPreset: none\n// optimizer.constantOptimizer: true\n// ----\n// Assembly:\n//   sub(shl(0x40, 0x01), 0x01)\n// Bytecode: 6001600160401b03\n// Opcodes: PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB\n// SourceMappings: :::-:0;;;;\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_cse.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"PUSH\", \"value\": \"0\"},\n        {\"name\": \"DUP2\"},\n        {\"name\": \"SUB\"}\n    ]\n}\n// ====\n// optimizationPreset: none\n// optimizer.cse: true\n// ----\n// Assembly:\n//   dup1\n// Bytecode: 80\n// Opcodes: DUP1\n// SourceMappings: :::-:0\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_deduplicate.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"PUSH [tag]\", \"value\": \"1\"},\n        {\"name\": \"PUSH [tag]\", \"value\": \"2\"},\n        {\"name\": \"tag\", \"value\": \"1\"},\n        {\"name\": \"JUMPDEST\"},\n        {\"name\": \"JUMP\"},\n        {\"name\": \"tag\", \"value\": \"2\"},\n        {\"name\": \"JUMPDEST\"},\n        {\"name\": \"JUMP\"}\n    ]\n}\n// ====\n// optimizationPreset: none\n// optimizer.deduplicate: true\n// ----\n// Assembly:\n//   tag_1\n//   tag_1\n// tag_1:\n//   jump\n// tag_2:\n//   jump\n// Bytecode: 600460045b565b56\n// Opcodes: PUSH1 0x4 PUSH1 0x4 JUMPDEST JUMP JUMPDEST JUMP\n// SourceMappings: :::-:0;;;;;\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_expected_executions_per_deployment.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"PUSH [$]\", \"value\": \"0\"}\n    ],\n    \".data\": {\n        \"0\": {\n            \".code\": [\n                {\"name\": \"PUSH\", \"value\": \"ffffffffffffffff\"}\n            ]\n         }\n    }\n}\n// ====\n// optimizationPreset: standard\n// optimizer.expectedExecutionsPerDeployment: 0\n// ----\n// Assembly:\n//   dataOffset(sub_0)\n// stop\n//\n// sub_0: assembly {\n//       sub(shl(0x40, 0x01), 0x01)\n// }\n// Bytecode: 6003fe6001600160401b03\n// Opcodes: PUSH1 0x3 INVALID PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB\n// SourceMappings: :::-:0\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_inliner.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"PUSH [tag]\", \"value\": \"1\"},\n        {\"name\": \"PUSH [tag]\", \"value\": \"2\"},\n        {\"name\": \"JUMP\"},\n        {\"name\": \"tag\", \"value\": \"1\"},\n        {\"name\": \"JUMPDEST\"},\n        {\"name\": \"STOP\"},\n        {\"name\": \"tag\", \"value\": \"2\"},\n        {\"name\": \"JUMPDEST\"},\n        {\"name\": \"CALLVALUE\"},\n        {\"name\": \"SWAP1\"},\n        {\"name\": \"JUMP\"}\n    ]\n}\n// ====\n// optimizationPreset: none\n// optimizer.inliner: true\n// ----\n// Assembly:\n//   tag_1\n//   callvalue\n//   swap1\n//   jump\n// tag_1:\n//   stop\n// tag_2:\n//   callvalue\n//   swap1\n//   jump\n// Bytecode: 60053490565b005b349056\n// Opcodes: PUSH1 0x5 CALLVALUE SWAP1 JUMP JUMPDEST STOP JUMPDEST CALLVALUE SWAP1 JUMP\n// SourceMappings: :::-:0;;;;;;;;;\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_jumpdest_remover.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"tag\", \"value\": \"1\"},\n        {\"name\": \"JUMPDEST\"}\n    ]\n}\n// ====\n// optimizationPreset: none\n// optimizer.jumpdestRemover: true\n// ----\n// Assembly:\n// Bytecode:\n// Opcodes:\n// SourceMappings:\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_peephole.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"STOP\"},\n        {\"name\": \"STOP\"}\n    ]\n}\n// ====\n// optimizationPreset: none\n// optimizer.peephole: true\n// ----\n// Assembly:\n//   stop\n// Bytecode: 00\n// Opcodes: STOP\n// SourceMappings: :::-:0\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/settings_optimizer_preset.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"PUSH\", \"value\": \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"},\n        {\"name\": \"PUSH\", \"value\": \"42\"},\n        {\"name\": \"PUSH\", \"value\": \"24\"},\n        {\"name\": \"SWAP1\"},\n        {\"name\": \"ADD\"}\n    ]\n}\n// ====\n// optimizationPreset: full\n// ----\n// Assembly:\n//   not(0x00)\n//   0x66\n// Bytecode: 5f196066\n// Opcodes: PUSH0 NOT PUSH1 0x66\n// SourceMappings: :::-:0;;\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/settings_outputs.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"CALLVALUE\"}\n    ]\n}\n// ====\n// outputs: SourceMappings,Opcodes\n// ----\n// Opcodes: CALLVALUE\n// SourceMappings: :::-:0\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/smoke.asmjson",
    "content": "{\n    \".code\": [\n        {\"name\": \"CALLVALUE\"}\n    ]\n}\n// ----\n// Assembly:\n//   callvalue\n// Bytecode: 34\n// Opcodes: CALLVALUE\n// SourceMappings: :::-:0\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/smoke_plain.asm",
    "content": "CALLVALUE\n// ====\n// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings\n// ----\n// InputAssemblyJSON: {\n//     \".code\": [\n//         {\n//             \"name\": \"CALLVALUE\"\n//         }\n//     ]\n// }\n// Assembly:\n//   callvalue\n// Bytecode: 34\n// Opcodes: CALLVALUE\n// SourceMappings: :::-:0\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies.asm",
    "content": "PUSH 0x2\nDUP1\nADD\n\n.sub\n    PUSH 0x42\n    DUP1\n    MUL\n\n.sub\n    STOP\n// ====\n// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings\n// ----\n// InputAssemblyJSON: {\n//     \".code\": [\n//         {\n//             \"name\": \"PUSH\",\n//             \"value\": \"2\"\n//         },\n//         {\n//             \"name\": \"DUP1\"\n//         },\n//         {\n//             \"name\": \"ADD\"\n//         }\n//     ],\n//     \".data\": {\n//         \"0\": {\n//             \".code\": [\n//                 {\n//                     \"name\": \"PUSH\",\n//                     \"value\": \"42\"\n//                 },\n//                 {\n//                     \"name\": \"DUP1\"\n//                 },\n//                 {\n//                     \"name\": \"MUL\"\n//                 }\n//             ]\n//         },\n//         \"1\": {\n//             \".code\": [\n//                 {\n//                     \"name\": \"STOP\"\n//                 }\n//             ]\n//         }\n//     }\n// }\n// Assembly:\n//   0x02\n//   dup1\n//   add\n// stop\n//\n// sub_0: assembly {\n//       0x42\n//       dup1\n//       mul\n// }\n//\n// sub_1: assembly {\n//       stop\n// }\n// Bytecode: 60028001fe\n// Opcodes: PUSH1 0x2 DUP1 ADD INVALID\n// SourceMappings: :::-:0;;\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_empty.asm",
    "content": ".sub\n.sub\n.sub\n// ====\n// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings\n// ----\n// InputAssemblyJSON: {\n//     \".code\": [],\n//     \".data\": {\n//         \"0\": {\n//             \".code\": []\n//         },\n//         \"1\": {\n//             \".code\": []\n//         },\n//         \"2\": {\n//             \".code\": []\n//         }\n//     }\n// }\n// Assembly:\n// stop\n//\n// sub_0: assembly {\n// }\n//\n// sub_1: assembly {\n// }\n//\n// sub_2: assembly {\n// }\n// Bytecode: fe\n// Opcodes: INVALID\n// SourceMappings:\n"
  },
  {
    "path": "test/libevmasm/evmAssemblyTests/isoltestTesting/subassemblies_nested.asm",
    "content": "TIMESTAMP\nTIMESTAMP\n\n.sub\n    TIMESTAMP\n\n    .sub\n        TIMESTAMP\n    .sub\n        TIMESTAMP\n        .sub\n            TIMESTAMP\n            .sub\n                TIMESTAMP\n    .sub\n        TIMESTAMP\n.sub\n    NUMBER\n    SLOAD\n    .sub\n        NUMBER\n        MLOAD\n        .sub\n            NUMBER\n            TLOAD\n\n// ====\n// outputs: InputAssemblyJSON,Assembly,Bytecode,Opcodes,SourceMappings\n// ----\n// InputAssemblyJSON: {\n//     \".code\": [\n//         {\n//             \"name\": \"TIMESTAMP\"\n//         },\n//         {\n//             \"name\": \"TIMESTAMP\"\n//         }\n//     ],\n//     \".data\": {\n//         \"0\": {\n//             \".code\": [\n//                 {\n//                     \"name\": \"TIMESTAMP\"\n//                 }\n//             ],\n//             \".data\": {\n//                 \"0\": {\n//                     \".code\": [\n//                         {\n//                             \"name\": \"TIMESTAMP\"\n//                         }\n//                     ]\n//                 },\n//                 \"1\": {\n//                     \".code\": [\n//                         {\n//                             \"name\": \"TIMESTAMP\"\n//                         }\n//                     ],\n//                     \".data\": {\n//                         \"0\": {\n//                             \".code\": [\n//                                 {\n//                                     \"name\": \"TIMESTAMP\"\n//                                 }\n//                             ],\n//                             \".data\": {\n//                                 \"0\": {\n//                                     \".code\": [\n//                                         {\n//                                             \"name\": \"TIMESTAMP\"\n//                                         }\n//                                     ]\n//                                 }\n//                             }\n//                         }\n//                     }\n//                 },\n//                 \"2\": {\n//                     \".code\": [\n//                         {\n//                             \"name\": \"TIMESTAMP\"\n//                         }\n//                     ]\n//                 }\n//             }\n//         },\n//         \"1\": {\n//             \".code\": [\n//                 {\n//                     \"name\": \"NUMBER\"\n//                 },\n//                 {\n//                     \"name\": \"SLOAD\"\n//                 }\n//             ],\n//             \".data\": {\n//                 \"0\": {\n//                     \".code\": [\n//                         {\n//                             \"name\": \"NUMBER\"\n//                         },\n//                         {\n//                             \"name\": \"MLOAD\"\n//                         }\n//                     ],\n//                     \".data\": {\n//                         \"0\": {\n//                             \".code\": [\n//                                 {\n//                                     \"name\": \"NUMBER\"\n//                                 },\n//                                 {\n//                                     \"name\": \"TLOAD\"\n//                                 }\n//                             ]\n//                         }\n//                     }\n//                 }\n//             }\n//         }\n//     }\n// }\n// Assembly:\n//   timestamp\n//   timestamp\n// stop\n//\n// sub_0: assembly {\n//       timestamp\n//     stop\n//\n//     sub_0: assembly {\n//           timestamp\n//     }\n//\n//     sub_1: assembly {\n//           timestamp\n//         stop\n//\n//         sub_0: assembly {\n//               timestamp\n//             stop\n//\n//             sub_0: assembly {\n//                   timestamp\n//             }\n//         }\n//     }\n//\n//     sub_2: assembly {\n//           timestamp\n//     }\n// }\n//\n// sub_1: assembly {\n//       sload(number)\n//     stop\n//\n//     sub_0: assembly {\n//           mload(number)\n//         stop\n//\n//         sub_0: assembly {\n//               tload(number)\n//         }\n//     }\n// }\n// Bytecode: 4242fe\n// Opcodes: TIMESTAMP TIMESTAMP INVALID\n// SourceMappings: :::-:0;\n"
  },
  {
    "path": "test/liblangutil/CharStream.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Rocky Bernstein <rocky.bernstein@consensys.net>\n * @date 2019\n * Unit tests for the CharStream class.\n */\n\n#include <liblangutil/CharStream.h>\n#include <liblangutil/Exceptions.h>\n\n#include <test/Common.h>\n\n#include <boost/test/unit_test.hpp>\n\nusing namespace solidity::test;\n\nnamespace boost::test_tools::tt_detail\n{\n\ntemplate<>\nstruct print_log_value<std::optional<int>>\n{\n\tvoid operator()(std::ostream& _out, std::optional<int> const& _value) const\n\t{\n\t\t_out << (_value ? to_string(*_value) : \"[std::nullopt]\");\n\t}\n};\n\ntemplate<>\nstruct print_log_value<std::nullopt_t>\n{\n\tvoid operator()(std::ostream& _out, std::nullopt_t const&) const\n\t{\n\t\t_out << \"[std::nullopt]\";\n\t}\n};\n\n} // namespace boost::test_tools::tt_detail\n\n\nnamespace solidity::langutil::test\n{\n\nBOOST_AUTO_TEST_SUITE(CharStreamTest)\n\nBOOST_AUTO_TEST_CASE(test_fail)\n{\n\tauto const source = std::make_shared<CharStream>(\"now is the time for testing\", \"source\");\n\n\tBOOST_CHECK('n' == source->get());\n\tBOOST_CHECK('n' == source->get());\n\tBOOST_CHECK('o' == source->advanceAndGet());\n\tBOOST_CHECK('n' == source->rollback(1));\n\tBOOST_CHECK('w' == source->setPosition(2));\n\tBOOST_REQUIRE_THROW(\n\t\tsource->setPosition(200),\n\t\t::solidity::langutil::InternalCompilerError\n\t);\n}\n\nnamespace\n{\nstd::optional<int> toPosition(int _line, int _column, std::string const& _text)\n{\n\treturn CharStream{_text, \"source\"}.translateLineColumnToPosition(\n\t\tLineColumn{_line, _column}\n\t);\n}\n\n}\n\nBOOST_AUTO_TEST_CASE(translateLineColumnToPosition)\n{\n\tBOOST_CHECK_EQUAL(toPosition(-1, 0, \"ABC\"), std::nullopt);\n\tBOOST_CHECK_EQUAL(toPosition(0, -1, \"ABC\"), std::nullopt);\n\n\tBOOST_CHECK_EQUAL(toPosition(0, 0, \"\"), 0);\n\tBOOST_CHECK_EQUAL(toPosition(1, 0, \"\"), std::nullopt);\n\tBOOST_CHECK_EQUAL(toPosition(0, 1, \"\"), std::nullopt);\n\n\t// With last line containing no LF\n\tBOOST_CHECK_EQUAL(toPosition(0, 0, \"ABC\"), 0);\n\tBOOST_CHECK_EQUAL(toPosition(0, 1, \"ABC\"), 1);\n\tBOOST_CHECK_EQUAL(toPosition(0, 2, \"ABC\"), 2);\n\tBOOST_CHECK_EQUAL(toPosition(0, 3, \"ABC\"), 3);\n\tBOOST_CHECK_EQUAL(toPosition(0, 4, \"ABC\"), std::nullopt);\n\tBOOST_CHECK_EQUAL(toPosition(1, 0, \"ABC\"), std::nullopt);\n\n\tBOOST_CHECK_EQUAL(toPosition(0, 3, \"ABC\\nDEF\"), 3);\n\tBOOST_CHECK_EQUAL(toPosition(0, 4, \"ABC\\nDEF\"), std::nullopt);\n\tBOOST_CHECK_EQUAL(toPosition(1, 0, \"ABC\\nDEF\"), 4);\n\tBOOST_CHECK_EQUAL(toPosition(1, 1, \"ABC\\nDEF\"), 5);\n\tBOOST_CHECK_EQUAL(toPosition(1, 2, \"ABC\\nDEF\"), 6);\n\tBOOST_CHECK_EQUAL(toPosition(1, 3, \"ABC\\nDEF\"), 7);\n\tBOOST_CHECK_EQUAL(toPosition(1, 4, \"ABC\\nDEF\"), std::nullopt);\n\tBOOST_CHECK_EQUAL(toPosition(2, 0, \"ABC\\nDEF\"), std::nullopt);\n\tBOOST_CHECK_EQUAL(toPosition(2, 1, \"ABC\\nDEF\"), std::nullopt);\n\n\t// With last line containing LF\n\tBOOST_CHECK_EQUAL(toPosition(0, 0, \"ABC\\nDEF\\n\"), 0);\n\tBOOST_CHECK_EQUAL(toPosition(0, 1, \"ABC\\nDEF\\n\"), 1);\n\tBOOST_CHECK_EQUAL(toPosition(0, 2, \"ABC\\nDEF\\n\"), 2);\n\n\tBOOST_CHECK_EQUAL(toPosition(1, 0, \"ABC\\nDEF\\n\"), 4);\n\tBOOST_CHECK_EQUAL(toPosition(1, 1, \"ABC\\nDEF\\n\"), 5);\n\tBOOST_CHECK_EQUAL(toPosition(1, 2, \"ABC\\nDEF\\n\"), 6);\n\tBOOST_CHECK_EQUAL(toPosition(1, 3, \"ABC\\nDEF\\n\"), 7);\n\tBOOST_CHECK_EQUAL(toPosition(1, 4, \"ABC\\nDEF\\n\"), std::nullopt);\n\tBOOST_CHECK_EQUAL(toPosition(2, 0, \"ABC\\nDEF\\n\"), 8);\n\tBOOST_CHECK_EQUAL(toPosition(2, 1, \"ABC\\nDEF\\n\"), std::nullopt);\n\n\tBOOST_CHECK_EQUAL(toPosition(2, 0, \"ABC\\nDEF\\nGHI\\n\"), 8);\n\tBOOST_CHECK_EQUAL(toPosition(2, 1, \"ABC\\nDEF\\nGHI\\n\"), 9);\n\tBOOST_CHECK_EQUAL(toPosition(2, 2, \"ABC\\nDEF\\nGHI\\n\"), 10);\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n}\n"
  },
  {
    "path": "test/liblangutil/Scanner.cpp",
    "content": "/*\n    This file is part of solidity.\n\n    solidity is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    solidity is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Unit tests for the solidity scanner.\n */\n\n#include <liblangutil/Scanner.h>\n\n#include <boost/test/unit_test.hpp>\n\nusing namespace solidity::langutil;\nusing namespace std::string_literals;\n\nnamespace solidity::langutil::test\n{\n\nBOOST_AUTO_TEST_SUITE(ScannerTest)\n\nBOOST_AUTO_TEST_CASE(test_empty)\n{\n\tCharStream stream{};\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(smoke_test)\n{\n\tCharStream stream(\"function break;765  \\t  \\\"string1\\\",'string2'\\nidentifier1\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Break);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Semicolon);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"765\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"string1\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Comma);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"string2\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"identifier1\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(assembly_assign)\n{\n\tCharStream stream(\"let a := 1\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Let);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::AssemblyAssign);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"1\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(assembly_multiple_assign)\n{\n\tCharStream stream(\"let a, b, c := 1\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Let);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Comma);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Comma);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::AssemblyAssign);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"1\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(string_printable)\n{\n\tfor (unsigned v = 0x20; v < 0x7e; v++) {\n\t\tstd::string lit{static_cast<char>(v)};\n\t\t// Escape \\ and \" (since we are quoting with \")\n\t\tif (v == '\\\\' || v == '\"')\n\t\t\tlit = std::string{'\\\\'} + lit;\n\t\tCharStream stream(\"  { \\\"\" + lit + \"\\\"\", \"\");\n\t\tScanner scanner(stream);\n\t\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);\n\t\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), std::string{static_cast<char>(v)});\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\t}\n\t// Special case of unescaped \" for strings quoted with '\n\tCharStream stream(\"  { '\\\"'\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(string_nonprintable)\n{\n\tfor (unsigned v = 0; v < 0xff; v++) {\n\t\t// Skip the valid ones\n\t\tif (v >= 0x20 && v <= 0x7e)\n\t\t\tcontinue;\n\t\tstd::string lit{static_cast<char>(v)};\n\t\tCharStream stream(\"  { \\\"\" + lit + \"\\\"\", \"\");\n\t\tScanner scanner(stream);\n\t\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\t\tif (v == '\\n' || v == '\\v' || v == '\\f' || v == '\\r')\n\t\t\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalStringEndQuote);\n\t\telse\n\t\t\tBOOST_CHECK_EQUAL(scanner.currentError(),ScannerError::UnicodeCharacterInNonUnicodeString);\n\t\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"\");\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(string_escapes)\n{\n\tCharStream stream(\"  { \\\"a\\\\x61\\\"\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"aa\");\n}\n\nBOOST_AUTO_TEST_CASE(string_escapes_all)\n{\n\tCharStream stream(\"  { \\\"a\\\\x61\\\\n\\\\r\\\\t\\\"\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"aa\\n\\r\\t\");\n}\n\nstruct TestScanner\n{\n\tstd::unique_ptr<CharStream> stream;\n\tstd::unique_ptr<Scanner> scanner;\n\texplicit TestScanner(std::string _text) { reset(std::move(_text)); }\n\n\tvoid reset(std::string _text)\n\t{\n\t\tstream = std::make_unique<CharStream>(std::move(_text), \"\");\n\t\tscanner = std::make_unique<Scanner>(*stream);\n\t}\n\n\tdecltype(auto) currentToken() { return scanner->currentToken(); }\n\tdecltype(auto) next() { return scanner->next(); }\n\tdecltype(auto) currentError() { return scanner->currentError(); }\n\tdecltype(auto) currentLiteral() { return scanner->currentLiteral(); }\n\tdecltype(auto) currentCommentLiteral() { return scanner->currentCommentLiteral(); }\n\tdecltype(auto) currentLocation() { return scanner->currentLocation(); }\n};\n\nBOOST_AUTO_TEST_CASE(string_escapes_legal_before_080)\n{\n\tTestScanner scanner(\"  { \\\"a\\\\b\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalEscapeSequence);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"\");\n\tscanner.reset(\"  { \\\"a\\\\f\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalEscapeSequence);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"\");\n\tscanner.reset(\"  { \\\"a\\\\v\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalEscapeSequence);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"\");\n}\n\nBOOST_AUTO_TEST_CASE(string_escapes_with_zero)\n{\n\tTestScanner scanner(\"  { \\\"a\\\\x61\\\\x00abc\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), std::string(\"aa\\0abc\", 6));\n}\n\nBOOST_AUTO_TEST_CASE(string_escape_illegal)\n{\n\tCharStream stream(\" bla \\\"\\\\x6rf\\\" (illegalescape)\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalEscapeSequence);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"\");\n\t// TODO recovery from illegal tokens should be improved\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(hex_numbers)\n{\n\tTestScanner scanner(\"var x = 0x765432536763762734623472346;\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Var);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Assign);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"0x765432536763762734623472346\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Semicolon);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(\"0x1234\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"0x1234\");\n\tscanner.reset(\"0X1234\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal);\n}\n\nBOOST_AUTO_TEST_CASE(octal_numbers)\n{\n\tTestScanner scanner(\"07\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal);\n\tscanner.reset(\"007\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal);\n\tscanner.reset(\"-07\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Sub);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tscanner.reset(\"-.07\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Sub);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tscanner.reset(\"0\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tscanner.reset(\"0.1\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n}\n\nBOOST_AUTO_TEST_CASE(scientific_notation)\n{\n\tCharStream stream(\"var x = 2e10;\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Var);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Assign);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"2e10\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Semicolon);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(leading_dot_in_identifier)\n{\n\tTestScanner scanner(\"function .a(\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Period);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(\"function .a(\");\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Period);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(middle_dot_in_identifier)\n{\n\tTestScanner scanner(\"function a..a(\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Period);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Period);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(\"function a...a(\");\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(trailing_dot_in_identifier)\n{\n\tTestScanner scanner(\"function a.(\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Period);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(\"function a.(\");\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(trailing_dot_in_numbers)\n{\n\tTestScanner scanner(\"2.5\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(\"2.5e10\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(\".5\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(\".5e10\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(\"2.\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Period);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(leading_underscore_decimal_is_identifier)\n{\n\t// Actual error is caught by SyntaxChecker.\n\tCharStream stream(\"_1.2\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(leading_underscore_decimal_after_dot_illegal)\n{\n\t// Actual error is caught by SyntaxChecker.\n\tTestScanner scanner(\"1._2\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\n\tscanner.reset(\"1._\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(leading_underscore_exp_are_identifier)\n{\n\t// Actual error is caught by SyntaxChecker.\n\tCharStream stream(\"_1e2\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(leading_underscore_exp_after_e_illegal)\n{\n\t// Actual error is caught by SyntaxChecker.\n\tCharStream stream(\"1e_2\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"1e_2\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(leading_underscore_hex_illegal)\n{\n\tCharStream stream(\"0x_abc\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(fixed_number_invalid_underscore_front)\n{\n\t// Actual error is caught by SyntaxChecker.\n\tCharStream stream(\"12._1234_1234\", \"\");\n\tScanner scanner(stream);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(number_literals_with_trailing_underscore_at_eos)\n{\n\t// Actual error is caught by SyntaxChecker.\n\tTestScanner scanner(\"0x123_\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\n\tscanner.reset(\"123_\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\n\tscanner.reset(\"12.34_\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(negative_numbers)\n{\n\tTestScanner scanner(\"var x = -.2 + -0x78 + -7.3 + 8.9 + 2e-2;\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Var);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Assign);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Sub);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \".2\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Add);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Sub);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"0x78\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Add);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Sub);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"7.3\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Add);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"8.9\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Add);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"2e-2\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Semicolon);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(locations)\n{\n\tTestScanner scanner(\"function_identifier has ; -0x743/*comment*/\\n ident //comment\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.currentLocation().start, 0);\n\tBOOST_CHECK_EQUAL(scanner.currentLocation().end, 19);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.currentLocation().start, 20);\n\tBOOST_CHECK_EQUAL(scanner.currentLocation().end, 23);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Semicolon);\n\tBOOST_CHECK_EQUAL(scanner.currentLocation().start, 24);\n\tBOOST_CHECK_EQUAL(scanner.currentLocation().end, 25);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Sub);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.currentLocation().start, 27);\n\tBOOST_CHECK_EQUAL(scanner.currentLocation().end, 32);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.currentLocation().start, 45);\n\tBOOST_CHECK_EQUAL(scanner.currentLocation().end, 50);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(ambiguities)\n{\n\t// test scanning of some operators which need look-ahead\n\tTestScanner scanner(\"<=\" \"<\" \"+ +=a++ =>\" \"<<\" \">>\" \" >>=\" \">>>\" \">>>=\" \" >>>>>=><<=\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LessThanOrEqual);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LessThan);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Add);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::AssignAdd);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Inc);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::DoubleArrow);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SHL);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SAR);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::AssignSar);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SHR);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::AssignShr);\n\t// the last \"monster\" token combination\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SHR);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::AssignSar);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::GreaterThan);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::AssignShl);\n}\n\nBOOST_AUTO_TEST_CASE(documentation_comments_parsed_begin)\n{\n\tTestScanner scanner(\"/// Send $(value / 1000) chocolates to the user\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::EOS);\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"Send $(value / 1000) chocolates to the user\");\n}\n\nBOOST_AUTO_TEST_CASE(multiline_documentation_comments_parsed_begin)\n{\n\tTestScanner scanner(\"/** Send $(value / 1000) chocolates to the user*/\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::EOS);\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"Send $(value / 1000) chocolates to the user\");\n}\n\nBOOST_AUTO_TEST_CASE(documentation_comments_parsed)\n{\n\tTestScanner scanner(\"some other tokens /// Send $(value / 1000) chocolates to the user\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"Send $(value / 1000) chocolates to the user\");\n}\n\nBOOST_AUTO_TEST_CASE(multiline_documentation_comments_parsed)\n{\n\tTestScanner scanner(\"some other tokens /**\\n\"\n\t\t\t\t\t\t\"* Send $(value / 1000) chocolates to the user\\n\"\n\t\t\t\t\t\t\"*/\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \" Send $(value / 1000) chocolates to the user\");\n}\n\nBOOST_AUTO_TEST_CASE(multiline_documentation_no_stars)\n{\n\tTestScanner scanner(\"some other tokens /**\\n\"\n\t\t\t\t\t\t\" Send $(value / 1000) chocolates to the user\\n\"\n\t\t\t\t\t\t\"*/\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"Send $(value / 1000) chocolates to the user\");\n}\n\nBOOST_AUTO_TEST_CASE(multiline_documentation_whitespace_hell)\n{\n\tTestScanner scanner(\"some other tokens /** \\t \\r \\n\"\n\t\t\t\t\t\t\"\\t \\r  * Send $(value / 1000) chocolates to the user\\n\"\n\t\t\t\t\t\t\"*/\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \" Send $(value / 1000) chocolates to the user\");\n}\n\nBOOST_AUTO_TEST_CASE(comment_before_eos)\n{\n\tTestScanner scanner(\"//\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::EOS);\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"\");\n}\n\nBOOST_AUTO_TEST_CASE(documentation_comment_before_eos)\n{\n\tTestScanner scanner(\"///\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::EOS);\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"\");\n}\n\nBOOST_AUTO_TEST_CASE(empty_multiline_comment)\n{\n\tTestScanner scanner(\"/**/\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::EOS);\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"\");\n}\n\nBOOST_AUTO_TEST_CASE(empty_multiline_documentation_comment_before_eos)\n{\n\tTestScanner scanner(\"/***/\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::EOS);\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"\");\n}\n\nBOOST_AUTO_TEST_CASE(comments_mixed_in_sequence)\n{\n\tTestScanner scanner(\"hello_world ///documentation comment \\n\"\n\t\t\t\t\t\t\"//simple comment \\n\"\n\t\t\t\t\t\t\"<<\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SHL);\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"documentation comment \");\n}\n\nBOOST_AUTO_TEST_CASE(ether_subdenominations)\n{\n\tTestScanner scanner(\"wei gwei ether\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::SubWei);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SubGwei);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SubEther);\n}\n\nBOOST_AUTO_TEST_CASE(time_subdenominations)\n{\n\tTestScanner scanner(\"seconds minutes hours days weeks years\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::SubSecond);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SubMinute);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SubHour);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SubDay);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SubWeek);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::SubYear);\n}\n\nBOOST_AUTO_TEST_CASE(empty_comment)\n{\n\tTestScanner scanner(\"//\\ncontract{}\");\n\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Contract);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::RBrace);\n\n}\n\n// Unicode string escapes\n\nBOOST_AUTO_TEST_CASE(valid_unicode_string_escape)\n{\n\tTestScanner scanner(\"{ \\\"\\\\u00DAnicode\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), std::string(\"\\xC3\\x9Anicode\", 8));\n}\n\nBOOST_AUTO_TEST_CASE(valid_unicode_string_escape_7f)\n{\n\tTestScanner scanner(\"{ \\\"\\\\u007Fnicode\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), std::string(\"\\x7Fnicode\", 7));\n}\n\nBOOST_AUTO_TEST_CASE(valid_unicode_string_escape_7ff)\n{\n\tTestScanner scanner(\"{ \\\"\\\\u07FFnicode\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), std::string(\"\\xDF\\xBFnicode\", 8));\n}\n\nBOOST_AUTO_TEST_CASE(valid_unicode_string_escape_ffff)\n{\n\tTestScanner scanner(\"{ \\\"\\\\uFFFFnicode\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), std::string(\"\\xEF\\xBF\\xBFnicode\", 9));\n}\n\nBOOST_AUTO_TEST_CASE(invalid_short_unicode_string_escape)\n{\n\tTestScanner scanner(\"{ \\\"\\\\uFFnicode\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n}\n\n// Unicode string literal\n\nBOOST_AUTO_TEST_CASE(unicode_prefix_only)\n{\n\tTestScanner scanner(\"{ unicode\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalToken);\n\tscanner.reset(\"{ unicode\");\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"unicode\");\n}\n\nBOOST_AUTO_TEST_CASE(unicode_invalid_space)\n{\n\tTestScanner scanner(\"{ unicode \");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalToken);\n}\n\nBOOST_AUTO_TEST_CASE(unicode_invalid_token)\n{\n\tTestScanner scanner(\"{ unicode test\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalToken);\n\tscanner.reset(\"{ unicode test\");\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"unicode\");\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"test\");\n}\n\nBOOST_AUTO_TEST_CASE(valid_unicode_literal)\n{\n\tTestScanner scanner(\"{ unicode\\\"Hello 😃\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::UnicodeStringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), std::string(\"Hello \\xf0\\x9f\\x98\\x83\", 10));\n}\n\nBOOST_AUTO_TEST_CASE(valid_nonprintable_in_unicode_literal)\n{\n\t// Non-printable characters are allowed in unicode strings...\n\tTestScanner scanner(\"{ unicode\\\"Hello \\007😃\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::UnicodeStringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), std::string(\"Hello \\x07\\xf0\\x9f\\x98\\x83\", 11));\n}\n\n// Hex string literal\n\nBOOST_AUTO_TEST_CASE(hex_prefix_only)\n{\n\tTestScanner scanner(\"{ hex\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalToken);\n\tscanner.reset(\"{ hex\");\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalToken);\n}\n\nBOOST_AUTO_TEST_CASE(hex_invalid_space)\n{\n\tTestScanner scanner(\"{ hex \");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalToken);\n}\n\nBOOST_AUTO_TEST_CASE(hex_invalid_token)\n{\n\tTestScanner scanner(\"{ hex test\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalToken);\n\tscanner.reset(\"{ hex test\");\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalToken);\n}\n\nBOOST_AUTO_TEST_CASE(valid_hex_literal)\n{\n\tTestScanner scanner(\"{ hex\\\"00112233FF\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::HexStringLiteral);\n\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), std::string(\"\\x00\\x11\\x22\\x33\\xFF\", 5));\n}\n\nBOOST_AUTO_TEST_CASE(invalid_short_hex_literal)\n{\n\tTestScanner scanner(\"{ hex\\\"00112233F\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalHexString);\n}\n\nBOOST_AUTO_TEST_CASE(invalid_hex_literal_with_space)\n{\n\tTestScanner scanner(\"{ hex\\\"00112233FF \\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalHexString);\n}\n\nBOOST_AUTO_TEST_CASE(invalid_hex_literal_with_wrong_quotes)\n{\n\tTestScanner scanner(\"{ hex\\\"00112233FF'\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalHexString);\n}\n\nBOOST_AUTO_TEST_CASE(invalid_hex_literal_nonhex_string)\n{\n\tTestScanner scanner(\"{ hex\\\"hello\\\"\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalHexString);\n}\n\n// Comments\n\nBOOST_AUTO_TEST_CASE(invalid_multiline_comment_close)\n{\n\t// This used to parse as \"comment\", \"identifier\"\n\tTestScanner scanner(\"/** / x\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(multiline_doc_comment_at_eos)\n{\n\t// This used to parse as \"whitespace\"\n\tTestScanner scanner(\"/**\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(multiline_comment_at_eos)\n{\n\tTestScanner scanner(\"/*\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(regular_line_break_in_single_line_comment)\n{\n\tfor (auto const& nl: {\"\\r\", \"\\n\", \"\\r\\n\"})\n\t{\n\t\tTestScanner scanner(\"// abc \" + std::string(nl) + \" def \");\n\t\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"\");\n\t\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\t\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"def\");\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(irregular_line_breaks_in_single_line_comment)\n{\n\tfor (auto const& nl: {\"\\v\", \"\\f\", \"\\xE2\\x80\\xA8\", \"\\xE2\\x80\\xA9\"})\n\t{\n\t\tTestScanner scanner(\"// abc \" + std::string(nl) + \" def \");\n\t\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"\");\n\t\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal);\n\t\tfor (size_t i = 0; i < std::string(nl).size() - 1; i++)\n\t\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\t\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"def\");\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(regular_line_breaks_in_single_line_doc_comment)\n{\n\tfor (auto const& nl: {\"\\r\", \"\\n\", \"\\r\\n\"})\n\t{\n\t\tTestScanner scanner(\"/// abc \" + std::string(nl) + \" def \");\n\t\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"abc \");\n\t\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\t\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"def\");\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(regular_line_breaks_in_multiline_doc_comment)\n{\n\t// Test CR, LF, CRLF as line valid terminators for code comments.\n\t// Any accepted non-LF is being canonicalized to LF.\n\tfor (auto const& nl : {\"\\r\"s, \"\\n\"s, \"\\r\\n\"s})\n\t{\n\t\tTestScanner scanner{\"/// Hello\" + nl + \"/// World\" + nl + \"ident\"};\n\t\tauto const& lit = scanner.currentCommentLiteral();\n\t\tBOOST_CHECK_EQUAL(lit, \"Hello\\n World\");\n\t\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"Hello\\n World\");\n\t\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\t\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"ident\");\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(irregular_line_breaks_in_single_line_doc_comment)\n{\n\tfor (auto const& nl: {\"\\v\", \"\\f\", \"\\xE2\\x80\\xA8\", \"\\xE2\\x80\\xA9\"})\n\t{\n\t\tTestScanner scanner(\"/// abc \" + std::string(nl) + \" def \");\n\t\tBOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), \"abc \");\n\t\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal);\n\t\tfor (size_t i = 0; i < std::string(nl).size() - 1; i++)\n\t\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\t\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"def\");\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(regular_line_breaks_in_strings)\n{\n\tfor (auto const& nl: {\"\\r\"s, \"\\n\"s, \"\\r\\n\"s})\n\t{\n\t\tTestScanner scanner(\"\\\"abc \" + nl + \" def\\\"\");\n\t\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal);\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\t\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"def\");\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(irregular_line_breaks_in_strings)\n{\n\tfor (auto const& nl: {\"\\v\", \"\\f\", \"\\xE2\\x80\\xA8\", \"\\xE2\\x80\\xA9\"})\n\t{\n\t\tTestScanner scanner(\"\\\"abc \" + std::string(nl) + \" def\\\"\");\n\t\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Illegal);\n\t\tfor (size_t i = 0; i < std::string(nl).size(); i++)\n\t\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\t\tBOOST_CHECK_EQUAL(scanner.currentLiteral(), \"def\");\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);\n\t\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(solidity_keywords)\n{\n\t// These are tokens which have a different meaning in Yul.\n\tstd::string keywords = \"return byte bool address var in true false leave switch case default\";\n\tTestScanner scanner(keywords);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Return);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Byte);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Bool);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Address);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Var);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::In);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::TrueLiteral);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::FalseLiteral);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Switch);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Case);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Default);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(keywords);\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::TrueLiteral);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::FalseLiteral);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Leave);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Switch);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Case);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Default);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(yul_keyword_like)\n{\n\tTestScanner scanner(\"leave.function\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Period);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(\"leave.function\");\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(yul_identifier_with_dots)\n{\n\tTestScanner scanner(\"mystorage.slot := 1\");\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Period);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::AssemblyAssign);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(\"mystorage.slot := 1\");\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::AssemblyAssign);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Number);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(yul_function)\n{\n\tstd::string sig = \"function f(a, b) -> x, y\";\n\tTestScanner scanner(sig);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Comma);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::RParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::RightArrow);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Comma);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(sig);\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Comma);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::RParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::RightArrow);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Comma);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(yul_function_with_whitespace)\n{\n\tstd::string sig = \"function f (a, b) - > x, y\";\n\tTestScanner scanner(sig);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Comma);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::RParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Sub);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::GreaterThan);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Comma);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n\tscanner.reset(sig);\n\tscanner.scanner->setScannerMode(ScannerKind::Yul);\n\tBOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::LParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Comma);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::RParen);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Sub);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::GreaterThan);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Comma);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);\n\tBOOST_CHECK_EQUAL(scanner.next(), Token::EOS);\n}\n\nBOOST_AUTO_TEST_CASE(special_comment_with_invalid_escapes)\n{\n\tstd::string input(R\"(\"test\\x\\f\\g\\u\\g\\a\\u\\g\\a12\\uö\\xyoof\")\");\n\tstd::string expectedOutput(R\"(test12öyoof)\");\n\tCharStream stream(input, \"\");\n\tScanner scanner(stream, ScannerKind::SpecialComment);\n\tBOOST_REQUIRE(scanner.currentToken() == Token::StringLiteral);\n\tBOOST_REQUIRE(scanner.currentLiteral() == expectedOutput);\n}\n\nBOOST_AUTO_TEST_CASE(special_comment_with_valid_and_invalid_escapes)\n{\n\tstd::string input(R\"(\"test\\n\\x61\\t\\u01A9test\\f\")\");\n\tstd::string expectedOutput(R\"(test6101A9test)\");\n\tCharStream stream(input, \"\");\n\tScanner scanner(stream, ScannerKind::SpecialComment);\n\tBOOST_REQUIRE(scanner.currentToken() == Token::StringLiteral);\n\tBOOST_REQUIRE(scanner.currentLiteral() == expectedOutput);\n}\n\nBOOST_AUTO_TEST_CASE(special_comment_with_unterminated_escape_sequence_at_eos)\n{\n\tCharStream stream(R\"(\"test\\)\", \"\");\n\tstd::string expectedOutput(R\"(test6101A9test)\");\n\tScanner scanner(stream, ScannerKind::SpecialComment);\n\tBOOST_REQUIRE(scanner.currentToken() == Token::Illegal);\n\tBOOST_REQUIRE(scanner.currentError() == ScannerError::IllegalEscapeSequence);\n}\n\nBOOST_AUTO_TEST_CASE(special_comment_with_escaped_quotes)\n{\n\tCharStream stream(R\"(\"test\\\\\\\"\")\", \"\");\n\tstd::string expectedOutput(R\"(test)\");\n\tScanner scanner(stream, ScannerKind::SpecialComment);\n\tBOOST_REQUIRE(scanner.currentToken() == Token::StringLiteral);\n\tBOOST_REQUIRE(scanner.currentLiteral() == expectedOutput);\n}\n\nBOOST_AUTO_TEST_CASE(special_comment_with_unterminated_string)\n{\n\tCharStream stream(R\"(\"test)\", \"\");\n\tScanner scanner(stream, ScannerKind::SpecialComment);\n\tBOOST_REQUIRE(scanner.currentToken() == Token::Illegal);\n\tBOOST_REQUIRE(scanner.currentError() == ScannerError::IllegalStringEndQuote);\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/liblangutil/SourceLocation.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Yoichi Hirai <yoichi@ethereum.org>\n * @date 2016\n * Unit tests for the SourceLocation class.\n */\n\n#include <liblangutil/SourceLocation.h>\n\n#include <test/Common.h>\n\n#include <boost/test/unit_test.hpp>\n\nnamespace solidity::langutil::test\n{\n\nBOOST_AUTO_TEST_SUITE(SourceLocationTest)\n\nBOOST_AUTO_TEST_CASE(test_fail)\n{\n\tauto const source = std::make_shared<std::string>(\"source\");\n\tauto const sourceA = std::make_shared<std::string>(\"sourceA\");\n\tauto const sourceB = std::make_shared<std::string>(\"sourceB\");\n\n\tBOOST_CHECK(SourceLocation{} == SourceLocation{});\n\tBOOST_CHECK((SourceLocation{0, 3, sourceA} != SourceLocation{0, 3, sourceB}));\n\tBOOST_CHECK((SourceLocation{0, 3, source} == SourceLocation{0, 3, source}));\n\tBOOST_CHECK((SourceLocation{3, 7, source}.contains(SourceLocation{4, 6, source})));\n\tBOOST_CHECK((!SourceLocation{3, 7, sourceA}.contains(SourceLocation{4, 6, sourceB})));\n\tBOOST_CHECK((SourceLocation{3, 7, sourceA} < SourceLocation{4, 6, sourceB}));\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/ABIDecoderTests.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Unit tests for Solidity's ABI decoder.\n */\n\n#include <functional>\n#include <string>\n#include <tuple>\n#include <boost/test/unit_test.hpp>\n#include <liblangutil/Exceptions.h>\n#include <test/libsolidity/SolidityExecutionFramework.h>\n\n#include <test/libsolidity/ABITestsCommon.h>\n\nusing namespace std::placeholders;\nusing namespace solidity::test;\n\nnamespace solidity::frontend::test\n{\n\nBOOST_FIXTURE_TEST_SUITE(ABIDecoderTest, SolidityExecutionFramework)\n\nBOOST_AUTO_TEST_CASE(value_types)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f(uint a, uint16 b, uint24 c, int24 d, bytes3 x, bool e, C g) public returns (uint) {\n\t\t\t\tif (a != 1) return 1;\n\t\t\t\tif (b != 2) return 2;\n\t\t\t\tif (c != 3) return 3;\n\t\t\t\tif (d != 4) return 4;\n\t\t\t\tif (x != \"abc\") return 5;\n\t\t\t\tif (e != true) return 6;\n\t\t\t\tif (g != this) return 7;\n\t\t\t\treturn 20;\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tABI_CHECK(callContractFunction(\n\t\t\t\"f(uint256,uint16,uint24,int24,bytes3,bool,address)\",\n\t\t\t1, 2, 3, 4, std::string(\"abc\"), true, m_contractAddress\n\t\t), encodeArgs(u256(20)));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(decode_from_memory_simple)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tuint public _a;\n\t\t\tuint[] public _b;\n\t\t\tconstructor(uint a, uint[] memory b) {\n\t\t\t\t_a = a;\n\t\t\t\t_b = b;\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode, 0, \"C\", encodeArgs(\n\t\t\t7, 0x40,\n\t\t\t// b\n\t\t\t3, 0x21, 0x22, 0x23\n\t\t));\n\t\tABI_CHECK(callContractFunction(\"_a()\"), encodeArgs(7));\n\t\tABI_CHECK(callContractFunction(\"_b(uint256)\", 0), encodeArgs(0x21));\n\t\tABI_CHECK(callContractFunction(\"_b(uint256)\", 1), encodeArgs(0x22));\n\t\tABI_CHECK(callContractFunction(\"_b(uint256)\", 2), encodeArgs(0x23));\n\t\tABI_CHECK(callContractFunction(\"_b(uint256)\", 3), encodeArgs());\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(decode_function_type)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract D {\n\t\t\tfunction () external returns (uint) public _a;\n\t\t\tconstructor(function () external returns (uint) a) {\n\t\t\t\t_a = a;\n\t\t\t}\n\t\t}\n\t\tcontract C {\n\t\t\tfunction f() public returns (uint) {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\tfunction g(function () external returns (uint) _f) public returns (uint) {\n\t\t\t\treturn _f();\n\t\t\t}\n\t\t\t// uses \"decode from memory\"\n\t\t\tfunction test1() public returns (uint) {\n\t\t\t\tD d = new D(this.f);\n\t\t\t\treturn d._a()();\n\t\t\t}\n\t\t\t// uses \"decode from calldata\"\n\t\t\tfunction test2() public returns (uint) {\n\t\t\t\treturn this.g(this.f);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tABI_CHECK(callContractFunction(\"test1()\"), encodeArgs(3));\n\t\tABI_CHECK(callContractFunction(\"test2()\"), encodeArgs(3));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(decode_function_type_array)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract D {\n\t\t\tfunction () external returns (uint)[] public _a;\n\t\t\tconstructor(function () external returns (uint)[] memory a) {\n\t\t\t\t_a = a;\n\t\t\t}\n\t\t}\n\t\tcontract E {\n\t\t\tfunction () external returns (uint)[3] public _a;\n\t\t\tconstructor(function () external returns (uint)[3] memory a) {\n\t\t\t\t_a = a;\n\t\t\t}\n\t\t}\n\t\tcontract C {\n\t\t\tfunction f1() public returns (uint) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tfunction f2() public returns (uint) {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\tfunction f3() public returns (uint) {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\tfunction g(function () external returns (uint)[] memory _f, uint i) public returns (uint) {\n\t\t\t\treturn _f[i]();\n\t\t\t}\n\t\t\tfunction h(function () external returns (uint)[3] memory _f, uint i) public returns (uint) {\n\t\t\t\treturn _f[i]();\n\t\t\t}\n\t\t\t// uses \"decode from memory\"\n\t\t\tfunction test1_dynamic() public returns (uint) {\n\t\t\t\tfunction () external returns (uint)[] memory x = new function() external returns (uint)[](4);\n\t\t\t\tx[0] = this.f1;\n\t\t\t\tx[1] = this.f2;\n\t\t\t\tx[2] = this.f3;\n\t\t\t\tD d = new D(x);\n\t\t\t\treturn d._a(2)();\n\t\t\t}\n\t\t\tfunction test1_static() public returns (uint) {\n\t\t\t\tE e = new E([this.f1, this.f2, this.f3]);\n\t\t\t\treturn e._a(2)();\n\t\t\t}\n\t\t\t// uses \"decode from calldata\"\n\t\t\tfunction test2_dynamic() public returns (uint) {\n\t\t\t\tfunction () external returns (uint)[] memory x = new function() external returns (uint)[](3);\n\t\t\t\tx[0] = this.f1;\n\t\t\t\tx[1] = this.f2;\n\t\t\t\tx[2] = this.f3;\n\t\t\t\treturn this.g(x, 0);\n\t\t\t}\n\t\t\tfunction test2_static() public returns (uint) {\n\t\t\t\treturn this.h([this.f1, this.f2, this.f3], 0);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tABI_CHECK(callContractFunction(\"test1_static()\"), encodeArgs(3));\n\t\tABI_CHECK(callContractFunction(\"test1_dynamic()\"), encodeArgs(3));\n\t\tABI_CHECK(callContractFunction(\"test2_static()\"), encodeArgs(1));\n\t\tABI_CHECK(callContractFunction(\"test2_dynamic()\"), encodeArgs(1));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(decode_from_memory_complex)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tuint public _a;\n\t\t\tuint[] public _b;\n\t\t\tbytes[2] public _c;\n\t\t\tconstructor(uint a, uint[] memory b, bytes[2] memory c) {\n\t\t\t\t_a = a;\n\t\t\t\t_b = b;\n\t\t\t\t_c = c;\n\t\t\t}\n\t\t}\n\t)\";\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode, 0, \"C\", encodeArgs(\n\t\t\t7, 0x60, 7 * 0x20,\n\t\t\t// b\n\t\t\t3, 0x21, 0x22, 0x23,\n\t\t\t// c\n\t\t\t0x40, 0x80,\n\t\t\t8, std::string(\"abcdefgh\"),\n\t\t\t52, std::string(\"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ\")\n\t\t));\n\t\tABI_CHECK(callContractFunction(\"_a()\"), encodeArgs(7));\n\t\tABI_CHECK(callContractFunction(\"_b(uint256)\", 0), encodeArgs(0x21));\n\t\tABI_CHECK(callContractFunction(\"_b(uint256)\", 1), encodeArgs(0x22));\n\t\tABI_CHECK(callContractFunction(\"_b(uint256)\", 2), encodeArgs(0x23));\n\t\tABI_CHECK(callContractFunction(\"_b(uint256)\", 3), encodeArgs());\n\t\tABI_CHECK(callContractFunction(\"_c(uint256)\", 0), encodeArgs(0x20, 8, std::string(\"abcdefgh\")));\n\t\tABI_CHECK(callContractFunction(\"_c(uint256)\", 1), encodeArgs(0x20, 52, std::string(\"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ\")));\n\t\tABI_CHECK(callContractFunction(\"_c(uint256)\", 2), encodeArgs());\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(short_input_value_type)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f(uint a, uint b) public pure returns (uint) { return a; }\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tABI_CHECK(callContractFunction(\"f(uint256,uint256)\", 1, 2), encodeArgs(1));\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(uint256,uint256)\", bytes(64, 0)), encodeArgs(0));\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(uint256,uint256)\", bytes(63, 0)), encodeArgs());\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(short_input_array)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f(uint[] memory a) public pure returns (uint) { return 7; }\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(uint256[])\", encodeArgs(0x20, 0)), encodeArgs(7));\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(uint256[])\", encodeArgs(0x20, 1)), encodeArgs());\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(uint256[])\", encodeArgs(0x20, 1) + bytes(31, 0)), encodeArgs());\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(uint256[])\", encodeArgs(0x20, 1) + bytes(32, 0)), encodeArgs(7));\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(uint256[])\", encodeArgs(0x20, 2, 5, 6)), encodeArgs(7));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(short_dynamic_input_array)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f(bytes[1] memory a) public pure returns (uint) { return 7; }\n\t\t}\n\t)\";\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode);\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(bytes[1])\", encodeArgs(0x20)), encodeArgs());\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(short_input_bytes)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n\t\t\tfunction f(bytes[] memory a) public pure returns (uint) { return 7; }\n\t\t}\n\t)\";\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode);\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"e(bytes)\", encodeArgs(0x20, 7) + bytes(5, 0)), encodeArgs());\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"e(bytes)\", encodeArgs(0x20, 7) + bytes(6, 0)), encodeArgs());\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"e(bytes)\", encodeArgs(0x20, 7) + bytes(7, 0)), encodeArgs(7));\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"e(bytes)\", encodeArgs(0x20, 7) + bytes(8, 0)), encodeArgs(7));\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(bytes[])\", encodeArgs(0x20, 1, 0x20, 7) + bytes(5, 0)), encodeArgs());\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(bytes[])\", encodeArgs(0x20, 1, 0x20, 7) + bytes(6, 0)), encodeArgs());\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(bytes[])\", encodeArgs(0x20, 1, 0x20, 7) + bytes(7, 0)), encodeArgs(7));\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"f(bytes[])\", encodeArgs(0x20, 1, 0x20, 7) + bytes(8, 0)), encodeArgs(7));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(validation_int_inside_arrays)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tenum E { A, B }\n\t\t\tfunction f(uint16[] memory a) public pure returns (uint r) { assembly { r := mload(add(a, 0x20)) } }\n\t\t\tfunction g(int16[] memory a) public pure returns (uint r) { assembly { r := mload(add(a, 0x20)) } }\n\t\t\tfunction h(E[] memory a) public pure returns (uint r) { assembly { r := mload(add(a, 0x20)) } }\n\t\t}\n\t)\";\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode);\n\t\tABI_CHECK(callContractFunction(\"f(uint16[])\", 0x20, 1, 7), encodeArgs(7));\n\t\tABI_CHECK(callContractFunction(\"g(int16[])\", 0x20, 1, 7), encodeArgs(7));\n\t\tABI_CHECK(callContractFunction(\"f(uint16[])\", 0x20, 1, u256(\"0xffff\")), encodeArgs(u256(\"0xffff\")));\n\t\tABI_CHECK(callContractFunction(\"g(int16[])\", 0x20, 1, u256(\"0xffff\")), encodeArgs());\n\t\tABI_CHECK(callContractFunction(\"f(uint16[])\", 0x20, 1, u256(\"0x1ffff\")), encodeArgs());\n\t\tABI_CHECK(callContractFunction(\"g(int16[])\", 0x20, 1, u256(\"0x10fff\")), encodeArgs());\n\t\tABI_CHECK(callContractFunction(\"h(uint8[])\", 0x20, 1, 0), encodeArgs(u256(0)));\n\t\tABI_CHECK(callContractFunction(\"h(uint8[])\", 0x20, 1, 1), encodeArgs(u256(1)));\n\t\tABI_CHECK(callContractFunction(\"h(uint8[])\", 0x20, 1, 2), encodeArgs());\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(validation_function_type)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f(function () external) public pure returns (uint r) { r = 1; }\n\t\t\tfunction g(function () external[] memory) public pure returns (uint r) { r = 2; }\n\t\t\tfunction h(function () external[] calldata) external pure returns (uint r) { r = 3; }\n\t\t\tfunction i(function () external[] calldata a) external pure returns (uint r) { a[0]; r = 4; }\n\t\t}\n\t)\";\n\tbool newDecoder = false;\n\tstd::string validFun{\"01234567890123456789abcd\"};\n\tstd::string invalidFun{\"01234567890123456789abcdX\"};\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tABI_CHECK(callContractFunction(\"f(function)\", validFun), encodeArgs(1));\n\t\tABI_CHECK(callContractFunction(\"f(function)\", invalidFun), newDecoder ? bytes{} : encodeArgs(1));\n\t\tABI_CHECK(callContractFunction(\"g(function[])\", 0x20, 1, validFun), encodeArgs(2));\n\t\tABI_CHECK(callContractFunction(\"g(function[])\", 0x20, 1, invalidFun), newDecoder ? bytes{} : encodeArgs(2));\n\t\tABI_CHECK(callContractFunction(\"h(function[])\", 0x20, 1, validFun), encodeArgs(3));\n\t\t// No failure because the data is not accessed.\n\t\tABI_CHECK(callContractFunction(\"h(function[])\", 0x20, 1, invalidFun), encodeArgs(3));\n\t\tABI_CHECK(callContractFunction(\"i(function[])\", 0x20, 1, validFun), encodeArgs(4));\n\t\tABI_CHECK(callContractFunction(\"i(function[])\", 0x20, 1, invalidFun), newDecoder ? bytes{} : encodeArgs(4));\n\t\tnewDecoder = true;\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(struct_short)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tstruct S { int a; uint b; bytes16 c; }\n\t\t\tfunction f(S memory s) public pure returns (S memory q) {\n\t\t\t\tq = s;\n\t\t\t}\n\t\t}\n\t)\";\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tABI_CHECK(\n\t\t\tcallContractFunction(\"f((int256,uint256,bytes16))\", 0xff010, 0xff0002, \"abcd\"),\n\t\t\tencodeArgs(0xff010, 0xff0002, \"abcd\")\n\t\t);\n\t\tABI_CHECK(\n\t\t\tcallContractFunctionNoEncoding(\"f((int256,uint256,bytes16))\", encodeArgs(0xff010, 0xff0002) + bytes(32, 0)),\n\t\t\tencodeArgs(0xff010, 0xff0002, 0)\n\t\t);\n\t\tABI_CHECK(\n\t\t\tcallContractFunctionNoEncoding(\"f((int256,uint256,bytes16))\", encodeArgs(0xff010, 0xff0002) + bytes(31, 0)),\n\t\t\tencodeArgs()\n\t\t);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(complex_struct)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tenum E {A, B, C}\n\t\t\tstruct T { uint x; E e; uint8 y; }\n\t\t\tstruct S { C c; T[] t;}\n\t\t\tfunction f(uint a, S[2] memory s1, S[] memory s2, uint b) public returns\n\t\t\t\t\t(uint r1, C r2, uint r3, uint r4, C r5, uint r6, E r7, uint8 r8) {\n\t\t\t\tr1 = a;\n\t\t\t\tr2 = s1[0].c;\n\t\t\t\tr3 = b;\n\t\t\t\tr4 = s2.length;\n\t\t\t\tr5 = s2[1].c;\n\t\t\t\tr6 = s2[1].t.length;\n\t\t\t\tr7 = s2[1].t[1].e;\n\t\t\t\tr8 = s2[1].t[1].y;\n\t\t\t}\n\t\t}\n\t)\";\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tstd::string sig = \"f(uint256,(address,(uint256,uint8,uint8)[])[2],(address,(uint256,uint8,uint8)[])[],uint256)\";\n\t\tbytes args = encodeArgs(\n\t\t\t7, 0x80, 0x1e0, 8,\n\t\t\t// S[2] s1\n\t\t\t0x40,\n\t\t\t0x100,\n\t\t\t// S s1[0]\n\t\t\tm_contractAddress,\n\t\t\t0x40,\n\t\t\t// T s1[0].t\n\t\t\t1, // length\n\t\t\t// s1[0].t[0]\n\t\t\t0x11, 1, 0x12,\n\t\t\t// S s1[1]\n\t\t\t0, 0x40,\n\t\t\t// T s1[1].t\n\t\t\t0,\n\t\t\t// S[] s2 (0x1e0)\n\t\t\t2, // length\n\t\t\t0x40, 0xa0,\n\t\t\t// S s2[0]\n\t\t\t0, 0x40, 0,\n\t\t\t// S s2[1]\n\t\t\t0x1234, 0x40,\n\t\t\t// s2[1].t\n\t\t\t3, // length\n\t\t\t0, 0, 0,\n\t\t\t0x21, 2, 0x22,\n\t\t\t0, 0, 0\n\t\t);\n\t\tABI_CHECK(callContractFunction(sig, args), encodeArgs(7, m_contractAddress, 8, 2, 0x1234, 3, 2, 0x22));\n\t\t// invalid enum value\n\t\targs.data()[0x20 * 28] = 3;\n\t\tABI_CHECK(callContractFunction(sig, args), encodeArgs());\n\t)\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/ABIEncoderTests.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Unit tests for Solidity's ABI encoder.\n */\n\n#include <test/libsolidity/SolidityExecutionFramework.h>\n\n#include <test/libsolidity/ABITestsCommon.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <boost/algorithm/string/replace.hpp>\n#include <boost/test/unit_test.hpp>\n\n#include <functional>\n#include <string>\n#include <tuple>\n\nusing namespace std::placeholders;\nusing namespace solidity::util;\nusing namespace solidity::test;\n\nnamespace solidity::frontend::test\n{\n\n#define REQUIRE_LOG_DATA(DATA) do { \\\n\tBOOST_REQUIRE_EQUAL(numLogs(), 1); \\\n\tBOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); \\\n\tABI_CHECK(logData(0), DATA); \\\n} while (false)\n\nBOOST_FIXTURE_TEST_SUITE(ABIEncoderTest, SolidityExecutionFramework)\n\nBOOST_AUTO_TEST_CASE(value_types)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tevent E(uint a, uint16 b, uint24 c, int24 d, bytes3 x, bool, C);\n\t\t\tfunction f() public {\n\t\t\t\tbytes6 x = hex\"1bababababa2\";\n\t\t\t\tbool b;\n\t\t\t\tassembly { b := 7 }\n\t\t\t\tC c;\n\t\t\t\tassembly { c := sub(0, 5) }\n\t\t\t\temit E(10, uint16(type(uint).max - 1), uint24(uint(0x12121212)), int24(int256(-1)), bytes3(x), b, c);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f()\");\n\t\tREQUIRE_LOG_DATA(encodeArgs(\n\t\t\t10, u256(65534), u256(0x121212), u256(-1), std::string(\"\\x1b\\xab\\xab\"), true, h160(\"fffffffffffffffffffffffffffffffffffffffb\")\n\t\t));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(string_literal)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tevent E(string, bytes20, string);\n\t\t\tfunction f() public {\n\t\t\t\temit E(\"abcdef\", \"abcde\", \"abcdefabcdefgehabcabcasdfjklabcdefabcedefghabcabcasdfjklabcdefabcdefghabcabcasdfjklabcdeefabcdefghabcabcasdefjklabcdefabcdefghabcabcasdfjkl\");\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f()\");\n\t\tREQUIRE_LOG_DATA(encodeArgs(\n\t\t\t0x60, std::string(\"abcde\"), 0xa0,\n\t\t\t6, std::string(\"abcdef\"),\n\t\t\t0x8b, std::string(\"abcdefabcdefgehabcabcasdfjklabcdefabcedefghabcabcasdfjklabcdefabcdefghabcabcasdfjklabcdeefabcdefghabcabcasdefjklabcdefabcdefghabcabcasdfjkl\")\n\t\t));\n\t)\n}\n\n\nBOOST_AUTO_TEST_CASE(enum_type_cleanup)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tenum E { A, B }\n\t\t\tfunction f(uint x) public returns (E en) {\n\t\t\t\tassembly { en := x }\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tBOOST_CHECK(callContractFunction(\"f(uint256)\", 0) == encodeArgs(0));\n\t\tBOOST_CHECK(callContractFunction(\"f(uint256)\", 1) == encodeArgs(1));\n\t\tBOOST_CHECK(callContractFunction(\"f(uint256)\", 2) == panicData(PanicCode::EnumConversionError));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(conversion)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tevent E(bytes4, bytes4, uint16, uint8, int16, int8);\n\t\t\tfunction f() public {\n\t\t\t\tbytes2 x; assembly { x := 0xf1f2f3f400000000000000000000000000000000000000000000000000000000 }\n\t\t\t\tuint8 a;\n\t\t\t\tuint16 b = 0x1ff;\n\t\t\t\tint8 c;\n\t\t\t\tint16 d;\n\t\t\t\tassembly { a := sub(0, 1) c := 0x0101ff d := 0xff01 }\n\t\t\t\temit E(bytes4(uint32(10)), x, a, uint8(b), c, int8(d));\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f()\");\n\t\tREQUIRE_LOG_DATA(encodeArgs(\n\t\t\tstd::string(3, 0) + std::string(\"\\x0a\"), std::string(\"\\xf1\\xf2\"),\n\t\t\t0xff, 0xff, u256(-1), u256(1)\n\t\t));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(memory_array_one_dim)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tevent E(uint a, int16[] b, uint c);\n\t\t\tfunction f() public {\n\t\t\t\tint16[] memory x = new int16[](3);\n\t\t\t\tassembly {\n\t\t\t\t\tfor { let i := 0 } lt(i, 3) { i := add(i, 1) } {\n\t\t\t\t\t\tmstore(add(x, mul(add(i, 1), 0x20)), add(0xfffffffe, i))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\temit E(10, x, 11);\n\t\t\t}\n\t\t}\n\t)\";\n\n\tif (solidity::test::CommonOptions::get().useABIEncoderV1)\n\t{\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f()\");\n\t\t// The old encoder does not clean array elements.\n\t\tREQUIRE_LOG_DATA(encodeArgs(10, 0x60, 11, 3, u256(\"0xfffffffe\"), u256(\"0xffffffff\"), u256(\"0x100000000\")));\n\t}\n\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f()\");\n\t\tREQUIRE_LOG_DATA(encodeArgs(10, 0x60, 11, 3, u256(-2), u256(-1), u256(0)));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(memory_array_two_dim)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tevent E(uint a, int16[][2] b, uint c);\n\t\t\tfunction f() public {\n\t\t\t\tint16[][2] memory x;\n\t\t\t\tx[0] = new int16[](3);\n\t\t\t\tx[1] = new int16[](2);\n\t\t\t\tx[0][0] = 7;\n\t\t\t\tx[0][1] = int16(int(0x010203040506));\n\t\t\t\tx[0][2] = -1;\n\t\t\t\tx[1][0] = 4;\n\t\t\t\tx[1][1] = 5;\n\t\t\t\temit E(10, x, 11);\n\t\t\t}\n\t\t}\n\t)\";\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f()\");\n\t\tREQUIRE_LOG_DATA(encodeArgs(10, 0x60, 11, 0x40, 0xc0, 3, 7, 0x0506, u256(-1), 2, 4, 5));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(memory_byte_array)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tevent E(uint a, bytes[] b, uint c);\n\t\t\tfunction f() public {\n\t\t\t\tbytes[] memory x = new bytes[](2);\n\t\t\t\tx[0] = \"abcabcdefghjklmnopqrsuvwabcdefgijklmnopqrstuwabcdefgijklmnoprstuvw\";\n\t\t\t\tx[1] = \"abcdefghijklmnopqrtuvwabcfghijklmnopqstuvwabcdeghijklmopqrstuvw\";\n\t\t\t\temit E(10, x, 11);\n\t\t\t}\n\t\t}\n\t)\";\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f()\");\n\t\tREQUIRE_LOG_DATA(encodeArgs(\n\t\t\t10, 0x60, 11,\n\t\t\t2, 0x40, 0xc0,\n\t\t\t66, std::string(\"abcabcdefghjklmnopqrsuvwabcdefgijklmnopqrstuwabcdefgijklmnoprstuvw\"),\n\t\t\t63, std::string(\"abcdefghijklmnopqrtuvwabcfghijklmnopqstuvwabcdeghijklmopqrstuvw\")\n\t\t));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(storage_byte_array)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tbytes short;\n\t\t\tbytes long;\n\t\t\tevent E(bytes s, bytes l);\n\t\t\tfunction f() public {\n\t\t\t\tshort = \"123456789012345678901234567890a\";\n\t\t\t\tlong = \"ffff123456789012345678901234567890afffffffff123456789012345678901234567890a\";\n\t\t\t\temit E(short, long);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f()\");\n\t\tREQUIRE_LOG_DATA(encodeArgs(\n\t\t\t0x40, 0x80,\n\t\t\t31, std::string(\"123456789012345678901234567890a\"),\n\t\t\t75, std::string(\"ffff123456789012345678901234567890afffffffff123456789012345678901234567890a\")\n\t\t));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(storage_array)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\taddress[3] addr;\n\t\t\tevent E(address[3] a);\n\t\t\tfunction f() public {\n\t\t\t\tassembly {\n\t\t\t\t\tsstore(0, sub(0, 1))\n\t\t\t\t\tsstore(1, sub(0, 2))\n\t\t\t\t\tsstore(2, sub(0, 3))\n\t\t\t\t}\n\t\t\t\temit E(addr);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f()\");\n\t\tREQUIRE_LOG_DATA(encodeArgs(\n\t\t\th160(\"ffffffffffffffffffffffffffffffffffffffff\"),\n\t\t\th160(\"fffffffffffffffffffffffffffffffffffffffe\"),\n\t\t\th160(\"fffffffffffffffffffffffffffffffffffffffd\")\n\t\t));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(storage_array_dyn)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\taddress[] addr;\n\t\t\tevent E(address[] a);\n\t\t\tfunction f() public {\n\t\t\t\taddr.push(0x0000000000000000000000000000000000000001);\n\t\t\t\taddr.push(0x0000000000000000000000000000000000000002);\n\t\t\t\taddr.push(0x0000000000000000000000000000000000000003);\n\t\t\t\temit E(addr);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f()\");\n\t\tREQUIRE_LOG_DATA(encodeArgs(\n\t\t\t0x20,\n\t\t\t3,\n\t\t\th160(\"0000000000000000000000000000000000000001\"),\n\t\t\th160(\"0000000000000000000000000000000000000002\"),\n\t\t\th160(\"0000000000000000000000000000000000000003\")\n\t\t));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(storage_array_compact)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tint72[] x;\n\t\t\tevent E(int72[]);\n\t\t\tfunction f() public {\n\t\t\t\tx.push(-1);\n\t\t\t\tx.push(2);\n\t\t\t\tx.push(-3);\n\t\t\t\tx.push(4);\n\t\t\t\tx.push(-5);\n\t\t\t\tx.push(6);\n\t\t\t\tx.push(-7);\n\t\t\t\tx.push(8);\n\t\t\t\temit E(x);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f()\");\n\t\tREQUIRE_LOG_DATA(encodeArgs(\n\t\t\t0x20, 8, u256(-1), 2, u256(-3), 4, u256(-5), 6, u256(-7), 8\n\t\t));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(external_function)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tevent E(function(uint) external returns (uint), function(uint) external returns (uint));\n\t\t\tfunction(uint) external returns (uint) g;\n\t\t\tfunction f(uint) public returns (uint) {\n\t\t\t\tg = this.f;\n\t\t\t\temit E(this.f, g);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f(uint256)\", u256(0));\n\t\tstd::string functionIdF = asString(m_contractAddress.ref()) + asString(util::selectorFromSignatureH32(\"f(uint256)\").ref());\n\t\tREQUIRE_LOG_DATA(encodeArgs(functionIdF, functionIdF));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(external_function_cleanup)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tevent E(function(uint) external returns (uint), function(uint) external returns (uint));\n\t\t\t// This test relies on the fact that g is stored in slot zero.\n\t\t\tfunction(uint) external returns (uint) g;\n\t\t\tfunction f(uint) public returns (uint) {\n\t\t\t\tfunction(uint) external returns (uint)[1] memory h;\n\t\t\t\tassembly { sstore(0, sub(0, 1)) mstore(h, sub(0, 1)) }\n\t\t\t\temit E(h[0], g);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f(uint256)\", u256(0));\n\t\tREQUIRE_LOG_DATA(encodeArgs(std::string(24, char(-1)), std::string(24, char(-1))));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(calldata)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tevent E(bytes);\n\t\t\tfunction f(bytes calldata a) external {\n\t\t\t\temit E(a);\n\t\t\t}\n\t\t}\n\t)\";\n\tstd::string s(\"abcdef\");\n\tstd::string t(\"abcdefgggggggggggggggggggggggggggggggggggggggghhheeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeggg\");\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tcallContractFunction(\"f(bytes)\", 0x20, s.size(), s);\n\t\tREQUIRE_LOG_DATA(encodeArgs(0x20, s.size(), s));\n\t\tcallContractFunction(\"f(bytes)\", 0x20, t.size(), t);\n\t\tREQUIRE_LOG_DATA(encodeArgs(0x20, t.size(), t));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(function_name_collision)\n{\n\t// This tests a collision between a function name used by inline assembly\n\t// and by the ABI encoder\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f(uint x) public returns (uint) {\n\t\t\t\tassembly {\n\t\t\t\t\tfunction abi_encode_t_uint256_to_t_uint256() {\n\t\t\t\t\t\tmstore(0, 7)\n\t\t\t\t\t\treturn(0, 0x20)\n\t\t\t\t\t}\n\t\t\t\t\tswitch x\n\t\t\t\t\tcase 0 { abi_encode_t_uint256_to_t_uint256() }\n\t\t\t\t}\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t)\";\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode);\n\t\tBOOST_CHECK(callContractFunction(\"f(uint256)\", encodeArgs(0)) == encodeArgs(7));\n\t\tBOOST_CHECK(callContractFunction(\"f(uint256)\", encodeArgs(1)) == encodeArgs(1));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(structs)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tstruct S { uint16 a; uint16 b; T[] sub; uint16 c; }\n\t\t\tstruct T { uint64[2] x; }\n\t\t\tS s;\n\t\t\tevent e(uint16, S);\n\t\t\tfunction f() public returns (uint, S memory) {\n\t\t\t\tuint16 x = 7;\n\t\t\t\ts.a = 8;\n\t\t\t\ts.b = 9;\n\t\t\t\ts.c = 10;\n\t\t\t\ts.sub.push();\n\t\t\t\ts.sub.push();\n\t\t\t\ts.sub.push();\n\t\t\t\ts.sub[0].x[0] = 11;\n\t\t\t\ts.sub[1].x[0] = 12;\n\t\t\t\ts.sub[2].x[1] = 13;\n\t\t\t\temit e(x, s);\n\t\t\t\treturn (x, s);\n\t\t\t}\n\t\t}\n\t)\";\n\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tbytes encoded = encodeArgs(\n\t\t\tu256(7), 0x40,\n\t\t\t8, 9, 0x80, 10,\n\t\t\t3,\n\t\t\t11, 0,\n\t\t\t12, 0,\n\t\t\t0, 13\n\t\t);\n\t\tBOOST_CHECK(callContractFunction(\"f()\") == encoded);\n\t\tREQUIRE_LOG_DATA(encoded);\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 0), keccak256(std::string(\"e(uint16,(uint16,uint16,(uint64[2])[],uint16))\")));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(structs2)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tenum E {A, B, C}\n\t\t\tstruct T { uint x; E e; uint8 y; }\n\t\t\tstruct S { C c; T[] t;}\n\t\t\tfunction f() public returns (uint a, S[2] memory s1, S[] memory s2, uint b) {\n\t\t\t\ta = 7;\n\t\t\t\tb = 8;\n\t\t\t\ts1[0].c = this;\n\t\t\t\ts1[0].t = new T[](1);\n\t\t\t\ts1[0].t[0].x = 0x11;\n\t\t\t\ts1[0].t[0].e = E.B;\n\t\t\t\ts1[0].t[0].y = 0x12;\n\t\t\t\ts2 = new S[](2);\n\t\t\t\ts2[1].c = C(address(0x1234));\n\t\t\t\ts2[1].t = new T[](3);\n\t\t\t\ts2[1].t[1].x = 0x21;\n\t\t\t\ts2[1].t[1].e = E.C;\n\t\t\t\ts2[1].t[1].y = 0x22;\n\t\t\t}\n\t\t}\n\t)\";\n\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(\n\t\t\t7, 0x80, 0x1e0, 8,\n\t\t\t// S[2] s1\n\t\t\t0x40,\n\t\t\t0x100,\n\t\t\t// S s1[0]\n\t\t\tm_contractAddress,\n\t\t\t0x40,\n\t\t\t// T s1[0].t\n\t\t\t1, // length\n\t\t\t// s1[0].t[0]\n\t\t\t0x11, 1, 0x12,\n\t\t\t// S s1[1]\n\t\t\t0, 0x40,\n\t\t\t// T s1[1].t\n\t\t\t0,\n\t\t\t// S[] s2 (0x1e0)\n\t\t\t2, // length\n\t\t\t0x40, 0xa0,\n\t\t\t// S s2[0]\n\t\t\t0, 0x40, 0,\n\t\t\t// S s2[1]\n\t\t\t0x1234, 0x40,\n\t\t\t// s2[1].t\n\t\t\t3, // length\n\t\t\t0, 0, 0,\n\t\t\t0x21, 2, 0x22,\n\t\t\t0, 0, 0\n\t\t));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(bool_arrays)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tbool[] x;\n\t\t\tbool[4] y;\n\t\t\tevent E(bool[], bool[4]);\n\t\t\tfunction f() public returns (bool[] memory, bool[4] memory) {\n\t\t\t\tx.push(true);\n\t\t\t\tx.push(false);\n\t\t\t\tx.push(true);\n\t\t\t\tx.push(false);\n\t\t\t\ty[0] = true;\n\t\t\t\ty[1] = false;\n\t\t\t\ty[2] = true;\n\t\t\t\ty[3] = false;\n\t\t\t\temit E(x, y);\n\t\t\t\treturn (x, y); // this copies to memory first\n\t\t\t}\n\t\t}\n\t)\";\n\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tbytes encoded = encodeArgs(\n\t\t\t0xa0, 1, 0, 1, 0,\n\t\t\t4, 1, 0, 1, 0\n\t\t);\n\t\tABI_CHECK(callContractFunction(\"f()\"), encoded);\n\t\tREQUIRE_LOG_DATA(encoded);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(bool_arrays_split)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tbool[] x;\n\t\t\tbool[4] y;\n\t\t\tevent E(bool[], bool[4]);\n\t\t\tfunction store() public {\n\t\t\t\tx.push(true);\n\t\t\t\tx.push(false);\n\t\t\t\tx.push(true);\n\t\t\t\tx.push(false);\n\t\t\t\ty[0] = true;\n\t\t\t\ty[1] = false;\n\t\t\t\ty[2] = true;\n\t\t\t\ty[3] = false;\n\t\t\t}\n\t\t\tfunction f() public returns (bool[] memory, bool[4] memory) {\n\t\t\t\temit E(x, y);\n\t\t\t\treturn (x, y); // this copies to memory first\n\t\t\t}\n\t\t}\n\t)\";\n\n\tBOTH_ENCODERS(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tbytes encoded = encodeArgs(\n\t\t\t0xa0, 1, 0, 1, 0,\n\t\t\t4, 1, 0, 1, 0\n\t\t);\n\t\tABI_CHECK(callContractFunction(\"store()\"), bytes{});\n\t\tABI_CHECK(callContractFunction(\"f()\"), encoded);\n\t\tREQUIRE_LOG_DATA(encoded);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(bytesNN_arrays)\n{\n\t// This tests that encoding packed arrays from storage work correctly.\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tbytes8[] x;\n\t\t\tbytesWIDTH[SIZE] y;\n\t\t\tevent E(bytes8[], bytesWIDTH[SIZE]);\n\t\t\tfunction store() public {\n\t\t\t\tx.push(\"abc\");\n\t\t\t\tx.push(\"def\");\n\t\t\t\tfor (uint i = 0; i < y.length; i ++)\n\t\t\t\t\ty[i] = bytesWIDTH(uintUINTWIDTH(i + 1));\n\t\t\t}\n\t\t\tfunction f() public returns (bytes8[] memory, bytesWIDTH[SIZE] memory) {\n\t\t\t\temit E(x, y);\n\t\t\t\treturn (x, y); // this copies to memory first\n\t\t\t}\n\t\t}\n\t)\";\n\n\tBOTH_ENCODERS(\n\t\tfor (size_t size = 1; size < 15; size++)\n\t\t{\n\t\t\tfor (size_t width: {1u, 2u, 4u, 5u, 7u, 15u, 16u, 17u, 31u, 32u})\n\t\t\t{\n\t\t\t\tstd::string source = boost::algorithm::replace_all_copy(sourceCode, \"SIZE\", std::to_string(size));\n\t\t\t\tsource = boost::algorithm::replace_all_copy(source, \"UINTWIDTH\", std::to_string(width * 8));\n\t\t\t\tsource = boost::algorithm::replace_all_copy(source, \"WIDTH\", std::to_string(width));\n\t\t\t\tcompileAndRun(source, 0, \"C\");\n\t\t\t\tABI_CHECK(callContractFunction(\"store()\"), bytes{});\n\t\t\t\tstd::vector<u256> arr;\n\t\t\t\tfor (size_t i = 0; i < size; i ++)\n\t\t\t\t\tarr.emplace_back(u256(i + 1) << (8 * (32 - width)));\n\t\t\t\tbytes encoded = encodeArgs(\n\t\t\t\t\t0x20 * (1 + size), arr,\n\t\t\t\t\t2, \"abc\", \"def\"\n\t\t\t\t);\n\t\t\t\tABI_CHECK(callContractFunction(\"f()\"), encoded);\n\t\t\t\tREQUIRE_LOG_DATA(encoded);\n\t\t\t}\n\t\t}\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(bytesNN_arrays_dyn)\n{\n\t// This tests that encoding packed arrays from storage work correctly.\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tbytes8[] x;\n\t\t\tbytesWIDTH[] y;\n\t\t\tevent E(bytesWIDTH[], bytes8[]);\n\t\t\tfunction store() public {\n\t\t\t\tx.push(\"abc\");\n\t\t\t\tx.push(\"def\");\n\t\t\t\tfor (uint i = 0; i < SIZE; i ++)\n\t\t\t\t\ty.push(bytesWIDTH(uintUINTWIDTH(i + 1)));\n\t\t\t}\n\t\t\tfunction f() public returns (bytesWIDTH[] memory, bytes8[] memory) {\n\t\t\t\temit E(y, x);\n\t\t\t\treturn (y, x); // this copies to memory first\n\t\t\t}\n\t\t}\n\t)\";\n\n\tBOTH_ENCODERS(\n\t\tfor (size_t size = 0; size < 15; size++)\n\t\t{\n\t\t\tfor (size_t width: {1u, 2u, 4u, 5u, 7u, 15u, 16u, 17u, 31u, 32u})\n\t\t\t{\n\t\t\t\tstd::string source = boost::algorithm::replace_all_copy(sourceCode, \"SIZE\", std::to_string(size));\n\t\t\t\tsource = boost::algorithm::replace_all_copy(source, \"UINTWIDTH\", std::to_string(width * 8));\n\t\t\t\tsource = boost::algorithm::replace_all_copy(source, \"WIDTH\", std::to_string(width));\n\t\t\t\tcompileAndRun(source, 0, \"C\");\n\t\t\t\tABI_CHECK(callContractFunction(\"store()\"), bytes{});\n\t\t\t\tstd::vector<u256> arr;\n\t\t\t\tfor (size_t i = 0; i < size; i ++)\n\t\t\t\t\tarr.emplace_back(u256(i + 1) << (8 * (32 - width)));\n\t\t\t\tbytes encoded = encodeArgs(\n\t\t\t\t\t0x20 * 2, 0x20 * (3 + size),\n\t\t\t\t\tsize, arr,\n\t\t\t\t\t2, \"abc\", \"def\"\n\t\t\t\t);\n\t\t\t\tABI_CHECK(callContractFunction(\"f()\"), encoded);\n\t\t\t\tREQUIRE_LOG_DATA(encoded);\n\t\t\t}\n\t\t}\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(packed_structs)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tstruct S { bool a; int8 b; function() external g; bytes3 d; int8 e; }\n\t\t\tS s;\n\t\t\tevent E(S);\n\t\t\tfunction store() public {\n\t\t\t\ts.a = false;\n\t\t\t\ts.b = -5;\n\t\t\t\ts.g = this.g;\n\t\t\t\ts.d = 0x010203;\n\t\t\t\ts.e = -3;\n\t\t\t}\n\t\t\tfunction f() public returns (S memory) {\n\t\t\t\temit E(s);\n\t\t\t\treturn s; // this copies to memory first\n\t\t\t}\n\t\t\tfunction g() public pure {}\n\t\t}\n\t)\";\n\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tABI_CHECK(callContractFunction(\"store()\"), bytes{});\n\t\tbytes fun = m_contractAddress.asBytes() + fromHex(\"0xe2179b8e\");\n\t\tbytes encoded = encodeArgs(\n\t\t\t0, u256(-5), asString(fun), \"\\x01\\x02\\x03\", u256(-3)\n\t\t);\n\t\tABI_CHECK(callContractFunction(\"f()\"), encoded);\n\t\tREQUIRE_LOG_DATA(encoded);\n\t)\n}\n\n\nBOOST_AUTO_TEST_CASE(struct_in_constructor)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tstruct S {\n\t\t\t\tstring a;\n\t\t\t\tuint8 b;\n\t\t\t\tstring c;\n\t\t\t}\n\t\t\tS public x;\n\t\t\tconstructor(S memory s) { x = s; }\n\t\t}\n\t)\";\n\n\tNEW_ENCODER(\n\t\tcompileAndRun(sourceCode, 0, \"C\", encodeArgs(0x20, 0x60, 0x03, 0x80, 0x00, 0x00));\n\t\tABI_CHECK(callContractFunction(\"x()\"), encodeArgs(0x60, 0x03, 0x80, 0x00, 0x00));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(struct_in_constructor_indirect)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tstruct S {\n\t\t\t\tstring a;\n\t\t\t\tuint8 b;\n\t\t\t\tstring c;\n\t\t\t}\n\t\t\tS public x;\n\t\t\tconstructor(S memory s) { x = s; }\n\t\t}\n\n\t\tcontract D {\n\t\t\tfunction f() public returns (string memory, uint8, string memory) {\n\t\t\t\tC.S memory s;\n\t\t\t\ts.a = \"abc\";\n\t\t\t\ts.b = 7;\n\t\t\t\ts.c = \"def\";\n\t\t\t\tC c = new C(s);\n\t\t\t\treturn c.x();\n\t\t\t}\n\t\t}\n\t)\";\n\tif (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())\n\t{\n\t\tNEW_ENCODER(\n\t\t\tcompileAndRun(sourceCode, 0, \"D\");\n\t\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(0x60, 7, 0xa0, 3, \"abc\", 3, \"def\"));\n\t\t)\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(struct_in_constructor_data_short)\n{\n\tstd::string sourceCode = R\"(\n\t\tcontract C {\n\t\t\tstruct S {\n\t\t\t\tstring a;\n\t\t\t\tuint8 b;\n\t\t\t\tstring c;\n\t\t\t}\n\t\t\tS public x;\n\t\t\tconstructor(S memory s) { x = s; }\n\t\t}\n\t)\";\n\n\tNEW_ENCODER(\n\t\tBOOST_CHECK(\n\t\t\tcompileAndRunWithoutCheck({{\"\", sourceCode}}, 0, \"C\", encodeArgs(0x20, 0x60, 0x03, 0x80, 0x00)).empty()\n\t\t);\n\t)\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/ABIJson/basic_test.sol",
    "content": "contract test {\n\tfunction f(uint a) public returns (uint d) { return a * 7; }\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"a\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"f\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"d\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/constructor_abi.sol",
    "content": "contract test {\n    constructor(uint param1, test param2, bool param3) {}\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"param1\",\n//         \"type\": \"uint256\"\n//       },\n//       {\n//         \"internalType\": \"contract test\",\n//         \"name\": \"param2\",\n//         \"type\": \"address\"\n//       },\n//       {\n//         \"internalType\": \"bool\",\n//         \"name\": \"param3\",\n//         \"type\": \"bool\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"constructor\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/empty_contract.sol",
    "content": "contract test { }\n// ----\n//     :test\n// []\n"
  },
  {
    "path": "test/libsolidity/ABIJson/empty_name_input_parameter_with_named_one.sol",
    "content": "contract test {\n    function f(uint, uint k) public returns (uint ret_k, uint ret_g) {\n        uint g = 8;\n        ret_k = k;\n        ret_g = g;\n    }\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"\",\n//         \"type\": \"uint256\"\n//       },\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"k\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"f\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"ret_k\",\n//         \"type\": \"uint256\"\n//       },\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"ret_g\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/empty_name_return_parameters.sol",
    "content": "contract test {\n    function f(uint k) public returns (uint) {\n        return k;\n    }\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"k\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"f\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/errors.sol",
    "content": "error FreeError();\ncontract X {\n    error E(uint);\n    error E2(uint a, uint b);\n    error E4(uint a, bytes[][] c);\n    struct S { uint x; }\n    error E5(S t);\n    function f() public pure {\n        revert FreeError();\n    }\n}\n// ----\n//     :X\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"E\",\n//     \"type\": \"error\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"a\",\n//         \"type\": \"uint256\"\n//       },\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"b\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"E2\",\n//     \"type\": \"error\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"a\",\n//         \"type\": \"uint256\"\n//       },\n//       {\n//         \"internalType\": \"bytes[][]\",\n//         \"name\": \"c\",\n//         \"type\": \"bytes[][]\"\n//       }\n//     ],\n//     \"name\": \"E4\",\n//     \"type\": \"error\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"components\": [\n//           {\n//             \"internalType\": \"uint256\",\n//             \"name\": \"x\",\n//             \"type\": \"uint256\"\n//           }\n//         ],\n//         \"internalType\": \"struct X.S\",\n//         \"name\": \"t\",\n//         \"type\": \"tuple\"\n//       }\n//     ],\n//     \"name\": \"E5\",\n//     \"type\": \"error\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"FreeError\",\n//     \"type\": \"error\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"f\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"pure\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/errors_referenced.sol",
    "content": "error E1();\nfunction f() {\n    revert E1();\n}\ncontract C {\n    // unreferenced but inherited\n    error E2();\n}\ncontract D {\n    // referenced\n    error E3(uint);\n}\ncontract X is C {\n    // unreferenced but defined\n    error E3();\n    function g(uint x) public {\n        if (x == 0)\n            f();\n        else if (x == 2)\n            revert D.E3(1);\n    }\n}\n// ----\n//     :C\n// [\n//   {\n//     \"inputs\": [],\n//     \"name\": \"E2\",\n//     \"type\": \"error\"\n//   }\n// ]\n//\n//\n//     :D\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"E3\",\n//     \"type\": \"error\"\n//   }\n// ]\n//\n//\n//     :X\n// [\n//   {\n//     \"inputs\": [],\n//     \"name\": \"E1\",\n//     \"type\": \"error\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"E2\",\n//     \"type\": \"error\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"E3\",\n//     \"type\": \"error\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"E3\",\n//     \"type\": \"error\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"x\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"g\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/event_emitted_from_foreign_contract.sol",
    "content": "interface I {\n    event Event(uint256 value);\n}\ncontract C {\n    event Event(address indexed sender);\n}\ncontract D {\n    event Event(address indexed sender);\n    function test(address sender) public {\n        emit I.Event(1);\n        emit C.Event(msg.sender);\n        emit Event(msg.sender);\n    }\n}\n// ----\n//     :C\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": true,\n//         \"internalType\": \"address\",\n//         \"name\": \"sender\",\n//         \"type\": \"address\"\n//       }\n//     ],\n//     \"name\": \"Event\",\n//     \"type\": \"event\"\n//   }\n// ]\n//\n//\n//     :D\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint256\",\n//         \"name\": \"value\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"Event\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": true,\n//         \"internalType\": \"address\",\n//         \"name\": \"sender\",\n//         \"type\": \"address\"\n//       }\n//     ],\n//     \"name\": \"Event\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": true,\n//         \"internalType\": \"address\",\n//         \"name\": \"sender\",\n//         \"type\": \"address\"\n//       }\n//     ],\n//     \"name\": \"Event\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"address\",\n//         \"name\": \"sender\",\n//         \"type\": \"address\"\n//       }\n//     ],\n//     \"name\": \"test\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n//\n//\n//     :I\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint256\",\n//         \"name\": \"value\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"Event\",\n//     \"type\": \"event\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/event_emitted_in_base_contract.sol",
    "content": "library   L { event E(uint8); }\n\ncontract B {\n    constructor() {\n        emit L.E(0);\n    }\n}\n\ncontract C is B {}\n\n// ----\n//     :B\n// [\n//   {\n//     \"inputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"constructor\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint8\",\n//         \"name\": \"\",\n//         \"type\": \"uint8\"\n//       }\n//     ],\n//     \"name\": \"E\",\n//     \"type\": \"event\"\n//   }\n// ]\n//\n//\n//     :C\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint8\",\n//         \"name\": \"\",\n//         \"type\": \"uint8\"\n//       }\n//     ],\n//     \"name\": \"E\",\n//     \"type\": \"event\"\n//   }\n// ]\n//\n//\n//     :L\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint8\",\n//         \"name\": \"\",\n//         \"type\": \"uint8\"\n//       }\n//     ],\n//     \"name\": \"E\",\n//     \"type\": \"event\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/event_file_level.sol",
    "content": "event Event();\nevent Event(uint);\n\nevent UnusedEvent();\n\nfunction f() {\n    emit Event();\n}\n\ncontract C {\n    function c_main() public {\n        emit Event(42);\n        f();\n    }\n}\n\ncontract D is C {\n    event Event(string);\n\n    function d_main() public {\n        emit Event(\"abc\");\n    }\n}\n// ----\n//     :C\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"Event\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint256\",\n//         \"name\": \"\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"Event\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"c_main\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n//\n//\n//     :D\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"Event\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint256\",\n//         \"name\": \"\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"Event\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"string\",\n//         \"name\": \"\",\n//         \"type\": \"string\"\n//       }\n//     ],\n//     \"name\": \"Event\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"c_main\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"d_main\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/event_from_aggregated_contract_not_emitted.sol",
    "content": "contract C {\n    event e();\n    function f() public {\n        emit e();\n    }\n}\n\ncontract D {\n    C c;\n    constructor() {\n        c = new C();\n        c.f();\n    }\n}\n\n// ----\n//     :C\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"e\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"f\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n//\n//\n//     :D\n// [\n//   {\n//     \"inputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"constructor\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/event_inheritance.sol",
    "content": "interface B {\n    event EB();\n}\n\ncontract C is B {\n    event EC();\n}\n\ncontract D is C {\n    event ED();\n}\n\n// ----\n//     :B\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"EB\",\n//     \"type\": \"event\"\n//   }\n// ]\n//\n//\n//     :C\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"EB\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"EC\",\n//     \"type\": \"event\"\n//   }\n// ]\n//\n//\n//     :D\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"EB\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"EC\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"ED\",\n//     \"type\": \"event\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/event_structs.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    struct S { uint a; T[] sub; bytes b; }\n    struct T { uint[2] x; }\n    event E(T t, S s);\n}\n// ----\n//     :C\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"components\": [\n//           {\n//             \"internalType\": \"uint256[2]\",\n//             \"name\": \"x\",\n//             \"type\": \"uint256[2]\"\n//           }\n//         ],\n//         \"indexed\": false,\n//         \"internalType\": \"struct C.T\",\n//         \"name\": \"t\",\n//         \"type\": \"tuple\"\n//       },\n//       {\n//         \"components\": [\n//           {\n//             \"internalType\": \"uint256\",\n//             \"name\": \"a\",\n//             \"type\": \"uint256\"\n//           },\n//           {\n//             \"components\": [\n//               {\n//                 \"internalType\": \"uint256[2]\",\n//                 \"name\": \"x\",\n//                 \"type\": \"uint256[2]\"\n//               }\n//             ],\n//             \"internalType\": \"struct C.T[]\",\n//             \"name\": \"sub\",\n//             \"type\": \"tuple[]\"\n//           },\n//           {\n//             \"internalType\": \"bytes\",\n//             \"name\": \"b\",\n//             \"type\": \"bytes\"\n//           }\n//         ],\n//         \"indexed\": false,\n//         \"internalType\": \"struct C.S\",\n//         \"name\": \"s\",\n//         \"type\": \"tuple\"\n//       }\n//     ],\n//     \"name\": \"E\",\n//     \"type\": \"event\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/events.sol",
    "content": "contract test {\n    function f(uint a) public returns (uint d) { return a * 7; }\n    event e1(uint b, address indexed c);\n    event e2();\n    event e2(uint a);\n    event e3() anonymous;\n}\n// ----\n//     :test\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint256\",\n//         \"name\": \"b\",\n//         \"type\": \"uint256\"\n//       },\n//       {\n//         \"indexed\": true,\n//         \"internalType\": \"address\",\n//         \"name\": \"c\",\n//         \"type\": \"address\"\n//       }\n//     ],\n//     \"name\": \"e1\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"e2\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint256\",\n//         \"name\": \"a\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"e2\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": true,\n//     \"inputs\": [],\n//     \"name\": \"e3\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"a\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"f\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"d\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/events_anonymous.sol",
    "content": "contract test {\n    event e() anonymous;\n}\n// ----\n//     :test\n// [\n//   {\n//     \"anonymous\": true,\n//     \"inputs\": [],\n//     \"name\": \"e\",\n//     \"type\": \"event\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/events_indirect.sol",
    "content": "library L {\n    event e1(uint b);\n    event e2();\n    event e2(uint a);\n    event e3() anonymous;\n}\ncontract test {\n    function f() public {\n        emit L.e1(1);\n        emit L.e3();\n    }\n}\n// ----\n//     :L\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint256\",\n//         \"name\": \"b\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"e1\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"e2\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint256\",\n//         \"name\": \"a\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"e2\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": true,\n//     \"inputs\": [],\n//     \"name\": \"e3\",\n//     \"type\": \"event\"\n//   }\n// ]\n//\n//\n//     :test\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": false,\n//         \"internalType\": \"uint256\",\n//         \"name\": \"b\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"e1\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": true,\n//     \"inputs\": [],\n//     \"name\": \"e3\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"f\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/events_repetitions.sol",
    "content": "library L {\n\tevent e();\n}\ncontract C {\n\tconstructor() {\n\t\temit L.e();\n\t}\n\tfunction f() public {\n\t\temit L.e();\n\t}\n}\n\n// ----\n//     :C\n// [\n//   {\n//     \"inputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"constructor\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"e\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"f\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n//\n//\n//     :L\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"e\",\n//     \"type\": \"event\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/function_type.sol",
    "content": "contract test {\n    function g(function(uint) external returns (uint) x) public {}\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"function (uint256) external returns (uint256)\",\n//         \"name\": \"x\",\n//         \"type\": \"function\"\n//       }\n//     ],\n//     \"name\": \"g\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/function_type_extended.sol",
    "content": "contract test {\n    function g(function(test) external returns (test[] memory) x) public {}\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"function (contract test) external returns (contract test[])\",\n//         \"name\": \"x\",\n//         \"type\": \"function\"\n//       }\n//     ],\n//     \"name\": \"g\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/global_struct.sol",
    "content": "pragma abicoder               v2;\nstruct S { uint a; }\ncontract C {\n    function f(S calldata s) external view {}\n    function g(S memory s) public view {}\n}\n// ----\n//     :C\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"components\": [\n//           {\n//             \"internalType\": \"uint256\",\n//             \"name\": \"a\",\n//             \"type\": \"uint256\"\n//           }\n//         ],\n//         \"internalType\": \"struct S\",\n//         \"name\": \"s\",\n//         \"type\": \"tuple\"\n//       }\n//     ],\n//     \"name\": \"f\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"components\": [\n//           {\n//             \"internalType\": \"uint256\",\n//             \"name\": \"a\",\n//             \"type\": \"uint256\"\n//           }\n//         ],\n//         \"internalType\": \"struct S\",\n//         \"name\": \"s\",\n//         \"type\": \"tuple\"\n//       }\n//     ],\n//     \"name\": \"g\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/include_fallback_function.sol",
    "content": "contract test {\n    fallback() external {}\n}\n// ----\n//     :test\n// [\n//   {\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"fallback\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/inherited.sol",
    "content": "contract Base {\n    function baseFunction(uint p) public returns (uint i) { return p; }\n    event baseEvent(bytes32 indexed evtArgBase);\n}\ncontract Derived is Base {\n    function derivedFunction(bytes32 p) public returns (bytes32 i) { return p; }\n    event derivedEvent(uint indexed evtArgDerived);\n}\n// ----\n//     :Base\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": true,\n//         \"internalType\": \"bytes32\",\n//         \"name\": \"evtArgBase\",\n//         \"type\": \"bytes32\"\n//       }\n//     ],\n//     \"name\": \"baseEvent\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"p\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"baseFunction\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"i\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n//\n//\n//     :Derived\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": true,\n//         \"internalType\": \"bytes32\",\n//         \"name\": \"evtArgBase\",\n//         \"type\": \"bytes32\"\n//       }\n//     ],\n//     \"name\": \"baseEvent\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [\n//       {\n//         \"indexed\": true,\n//         \"internalType\": \"uint256\",\n//         \"name\": \"evtArgDerived\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"derivedEvent\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"p\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"baseFunction\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"i\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"bytes32\",\n//         \"name\": \"p\",\n//         \"type\": \"bytes32\"\n//       }\n//     ],\n//     \"name\": \"derivedFunction\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"bytes32\",\n//         \"name\": \"i\",\n//         \"type\": \"bytes32\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/internal_constructor.sol",
    "content": "// bug #8712\nabstract contract B {\n    uint immutable x;\n    constructor(function() internal returns(uint) fp) {\n        x = fp(); }\n}\n// ----\n//     :B\n// []\n"
  },
  {
    "path": "test/libsolidity/ABIJson/library_function.sol",
    "content": "contract X {}\nlibrary test {\n    struct StructType { uint a; }\n    function f(StructType storage b, uint[] storage c, X d) public returns (uint[] memory e, StructType storage f) { f = f; }\n    function f1(uint[] memory c, X d) public pure returns (uint[] memory e) {  }\n}\n// ----\n//     :X\n// []\n//\n//\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256[]\",\n//         \"name\": \"c\",\n//         \"type\": \"uint256[]\"\n//       },\n//       {\n//         \"internalType\": \"contract X\",\n//         \"name\": \"d\",\n//         \"type\": \"X\"\n//       }\n//     ],\n//     \"name\": \"f1\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256[]\",\n//         \"name\": \"e\",\n//         \"type\": \"uint256[]\"\n//       }\n//     ],\n//     \"stateMutability\": \"pure\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/mapping.sol",
    "content": "contract test {\n    mapping(address owner => mapping(address spender => uint value)) public allowance;\n    mapping(bytes32 => address sender) public commits;\n    mapping(bytes32 => bytes32) public something;\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"address\",\n//         \"name\": \"owner\",\n//         \"type\": \"address\"\n//       },\n//       {\n//         \"internalType\": \"address\",\n//         \"name\": \"spender\",\n//         \"type\": \"address\"\n//       }\n//     ],\n//     \"name\": \"allowance\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"value\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"bytes32\",\n//         \"name\": \"\",\n//         \"type\": \"bytes32\"\n//       }\n//     ],\n//     \"name\": \"commits\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"address\",\n//         \"name\": \"sender\",\n//         \"type\": \"address\"\n//       }\n//     ],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"bytes32\",\n//         \"name\": \"\",\n//         \"type\": \"bytes32\"\n//       }\n//     ],\n//     \"name\": \"something\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"bytes32\",\n//         \"name\": \"\",\n//         \"type\": \"bytes32\"\n//       }\n//     ],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/multiple_methods.sol",
    "content": "contract test {\n    function f(uint a) public returns (uint d) { return a * 7; }\n    function g(uint b) public returns (uint e) { return b * 8; }\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"a\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"f\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"d\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"b\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"g\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"e\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/multiple_methods_order.sol",
    "content": "// methods are expected to be in alphabetical order\ncontract test {\n    function f(uint a) public returns (uint d) { return a * 7; }\n    function c(uint b) public returns (uint e) { return b * 8; }\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"b\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"c\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"e\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"a\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"f\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"d\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/multiple_params.sol",
    "content": "contract test {\n    function f(uint a, uint b) public returns (uint d) { return a + b; }\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"a\",\n//         \"type\": \"uint256\"\n//       },\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"b\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"f\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"d\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/payable_constructor_abi.sol",
    "content": "contract test {\n    constructor(uint param1, test param2, bool param3) payable {}\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"param1\",\n//         \"type\": \"uint256\"\n//       },\n//       {\n//         \"internalType\": \"contract test\",\n//         \"name\": \"param2\",\n//         \"type\": \"address\"\n//       },\n//       {\n//         \"internalType\": \"bool\",\n//         \"name\": \"param3\",\n//         \"type\": \"bool\"\n//       }\n//     ],\n//     \"stateMutability\": \"payable\",\n//     \"type\": \"constructor\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/payable_fallback_function.sol",
    "content": "contract test {\n    fallback () external payable {}\n}\n// ----\n//     :test\n// [\n//   {\n//     \"stateMutability\": \"payable\",\n//     \"type\": \"fallback\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/payable_function.sol",
    "content": "contract test {\n    function f() public {}\n    function g() public payable {}\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [],\n//     \"name\": \"f\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"g\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"payable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/pure_function.sol",
    "content": "contract test {\n    function foo(uint a, uint b) public returns (uint d) { return a + b; }\n    function boo(uint32 a) public pure returns (uint b) { return a * 4; }\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint32\",\n//         \"name\": \"a\",\n//         \"type\": \"uint32\"\n//       }\n//     ],\n//     \"name\": \"boo\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"b\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"pure\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"a\",\n//         \"type\": \"uint256\"\n//       },\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"b\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"foo\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"d\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/receive_ether_and_fallback_function.sol",
    "content": "contract test {\n    receive() external payable {}\n    fallback() external {}\n}\n// ----\n//     :test\n// [\n//   {\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"fallback\"\n//   },\n//   {\n//     \"stateMutability\": \"payable\",\n//     \"type\": \"receive\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/receive_ether_function.sol",
    "content": "contract test {\n    receive() external payable {}\n}\n// ----\n//     :test\n// [\n//   {\n//     \"stateMutability\": \"payable\",\n//     \"type\": \"receive\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/return_param_in_abi.sol",
    "content": "// bug #1801\ncontract test {\n    enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }\n    constructor(ActionChoices param) {}\n    function ret() public returns (ActionChoices) {\n        ActionChoices action = ActionChoices.GoLeft;\n        return action;\n    }\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"enum test.ActionChoices\",\n//         \"name\": \"param\",\n//         \"type\": \"uint8\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"constructor\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"ret\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"enum test.ActionChoices\",\n//         \"name\": \"\",\n//         \"type\": \"uint8\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/return_structs.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    struct S { uint a; T[] sub; }\n    struct T { uint[2] x; }\n    function f() public returns (uint x, S memory s) {\n    }\n}\n// ----\n//     :C\n// [\n//   {\n//     \"inputs\": [],\n//     \"name\": \"f\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"x\",\n//         \"type\": \"uint256\"\n//       },\n//       {\n//         \"components\": [\n//           {\n//             \"internalType\": \"uint256\",\n//             \"name\": \"a\",\n//             \"type\": \"uint256\"\n//           },\n//           {\n//             \"components\": [\n//               {\n//                 \"internalType\": \"uint256[2]\",\n//                 \"name\": \"x\",\n//                 \"type\": \"uint256[2]\"\n//               }\n//             ],\n//             \"internalType\": \"struct C.T[]\",\n//             \"name\": \"sub\",\n//             \"type\": \"tuple[]\"\n//           }\n//         ],\n//         \"internalType\": \"struct C.S\",\n//         \"name\": \"s\",\n//         \"type\": \"tuple\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/return_structs_with_contracts.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    struct S { C[] x; C y; }\n    function f() public returns (S memory s, C c) {\n    }\n}\n// ----\n//     :C\n// [\n//   {\n//     \"inputs\": [],\n//     \"name\": \"f\",\n//     \"outputs\": [\n//       {\n//         \"components\": [\n//           {\n//             \"internalType\": \"contract C[]\",\n//             \"name\": \"x\",\n//             \"type\": \"address[]\"\n//           },\n//           {\n//             \"internalType\": \"contract C\",\n//             \"name\": \"y\",\n//             \"type\": \"address\"\n//           }\n//         ],\n//         \"internalType\": \"struct C.S\",\n//         \"name\": \"s\",\n//         \"type\": \"tuple\"\n//       },\n//       {\n//         \"internalType\": \"contract C\",\n//         \"name\": \"c\",\n//         \"type\": \"address\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/same_event_defined_twice.sol",
    "content": "library L1 { event e(); }\nlibrary L2 { event e(); }\ncontract C {\n\tconstructor() {\n\t\temit L1.e();\n\t}\n\tfunction f() public {\n\t\temit L2.e();\n\t}\n}\n\n// ----\n//     :C\n// [\n//   {\n//     \"inputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"constructor\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"e\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"e\",\n//     \"type\": \"event\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"f\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n//\n//\n//     :L1\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"e\",\n//     \"type\": \"event\"\n//   }\n// ]\n//\n//\n//     :L2\n// [\n//   {\n//     \"anonymous\": false,\n//     \"inputs\": [],\n//     \"name\": \"e\",\n//     \"type\": \"event\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/structs_and_arrays.sol",
    "content": "// bug #1801\ncontract test {\n    function f(string calldata a, bytes calldata b, uint[] calldata c) external {}\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"string\",\n//         \"name\": \"a\",\n//         \"type\": \"string\"\n//       },\n//       {\n//         \"internalType\": \"bytes\",\n//         \"name\": \"b\",\n//         \"type\": \"bytes\"\n//       },\n//       {\n//         \"internalType\": \"uint256[]\",\n//         \"name\": \"c\",\n//         \"type\": \"uint256[]\"\n//       }\n//     ],\n//     \"name\": \"f\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/structs_in_libraries.sol",
    "content": "pragma abicoder               v2;\nlibrary L {\n    struct S { uint a; T[] sub; bytes b; }\n    struct T { uint[2] x; }\n    function f(L.S storage s) public view {}\n    function g(L.S memory s) public view {}\n}\n// ----\n//     :L\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"components\": [\n//           {\n//             \"internalType\": \"uint256\",\n//             \"name\": \"a\",\n//             \"type\": \"uint256\"\n//           },\n//           {\n//             \"components\": [\n//               {\n//                 \"internalType\": \"uint256[2]\",\n//                 \"name\": \"x\",\n//                 \"type\": \"uint256[2]\"\n//               }\n//             ],\n//             \"internalType\": \"struct L.T[]\",\n//             \"name\": \"sub\",\n//             \"type\": \"tuple[]\"\n//           },\n//           {\n//             \"internalType\": \"bytes\",\n//             \"name\": \"b\",\n//             \"type\": \"bytes\"\n//           }\n//         ],\n//         \"internalType\": \"struct L.S\",\n//         \"name\": \"s\",\n//         \"type\": \"tuple\"\n//       }\n//     ],\n//     \"name\": \"g\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/user_defined_value_type.sol",
    "content": "type MyInt is int;\ntype MyByte1 is bytes1;\ncontract C {\n    type MyAddress is address;\n    type MyUInt8 is uint8;\n    type MyBytes32 is bytes32;\n\n    MyInt public myInt;\n    MyByte1 public myByte1;\n    MyAddress public myAddress;\n    MyUInt8 public myUInt8;\n    MyBytes32 public myBytes32;\n\n    function setMyInt(MyInt a) external {\n        myInt = a;\n    }\n    function setMyByte1(MyByte1 a) external {\n        myByte1 = a;\n    }\n    function setMyAddress(MyAddress a) external {\n        myAddress = a;\n    }\n    function setMyUInt8(MyUInt8 a) external {\n        myUInt8 = a;\n    }\n    function setMyBytes32(MyBytes32 a) external {\n        myBytes32 = a;\n    }\n}\n// ----\n//     :C\n// [\n//   {\n//     \"inputs\": [],\n//     \"name\": \"myAddress\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"C.MyAddress\",\n//         \"name\": \"\",\n//         \"type\": \"address\"\n//       }\n//     ],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"myByte1\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"MyByte1\",\n//         \"name\": \"\",\n//         \"type\": \"bytes1\"\n//       }\n//     ],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"myBytes32\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"C.MyBytes32\",\n//         \"name\": \"\",\n//         \"type\": \"bytes32\"\n//       }\n//     ],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"myInt\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"MyInt\",\n//         \"name\": \"\",\n//         \"type\": \"int256\"\n//       }\n//     ],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [],\n//     \"name\": \"myUInt8\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"C.MyUInt8\",\n//         \"name\": \"\",\n//         \"type\": \"uint8\"\n//       }\n//     ],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"C.MyAddress\",\n//         \"name\": \"a\",\n//         \"type\": \"address\"\n//       }\n//     ],\n//     \"name\": \"setMyAddress\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"MyByte1\",\n//         \"name\": \"a\",\n//         \"type\": \"bytes1\"\n//       }\n//     ],\n//     \"name\": \"setMyByte1\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"C.MyBytes32\",\n//         \"name\": \"a\",\n//         \"type\": \"bytes32\"\n//       }\n//     ],\n//     \"name\": \"setMyBytes32\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"MyInt\",\n//         \"name\": \"a\",\n//         \"type\": \"int256\"\n//       }\n//     ],\n//     \"name\": \"setMyInt\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"C.MyUInt8\",\n//         \"name\": \"a\",\n//         \"type\": \"uint8\"\n//       }\n//     ],\n//     \"name\": \"setMyUInt8\",\n//     \"outputs\": [],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJson/view_function.sol",
    "content": "contract test {\n    function foo(uint a, uint b) public returns (uint d) { return a + b; }\n    function boo(uint32 a) public view returns(uint b) { return a * 4; }\n}\n// ----\n//     :test\n// [\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint32\",\n//         \"name\": \"a\",\n//         \"type\": \"uint32\"\n//       }\n//     ],\n//     \"name\": \"boo\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"b\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"view\",\n//     \"type\": \"function\"\n//   },\n//   {\n//     \"inputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"a\",\n//         \"type\": \"uint256\"\n//       },\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"b\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"name\": \"foo\",\n//     \"outputs\": [\n//       {\n//         \"internalType\": \"uint256\",\n//         \"name\": \"d\",\n//         \"type\": \"uint256\"\n//       }\n//     ],\n//     \"stateMutability\": \"nonpayable\",\n//     \"type\": \"function\"\n//   }\n// ]\n"
  },
  {
    "path": "test/libsolidity/ABIJsonTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n */\n/**\n * Unit tests for the solidity compiler ABI JSON Interface output.\n */\n\n#include <test/libsolidity/ABIJsonTest.h>\n\n#include <test/Common.h>\n\n#include <libsolidity/interface/CompilerStack.h>\n#include <libsolutil/JSON.h>\n#include <libsolutil/AnsiColorized.h>\n\n#include <fstream>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\n\nABIJsonTest::ABIJsonTest(std::string const& _filename):\n\tTestCase(_filename)\n{\n\tm_source = m_reader.source();\n\tm_expectation = m_reader.simpleExpectations();\n}\n\nTestCase::TestResult ABIJsonTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted)\n{\n\tCompilerStack compiler;\n\n\tcompiler.setSources({{\n\t\t\"\",\n\t\t\"pragma solidity >=0.0;\\n// SPDX-License-Identifier: GPL-3.0\\n\" + m_source\n\t}});\n\tcompiler.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\tcompiler.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n\tif (!compiler.parseAndAnalyze())\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Parsing contract failed\"));\n\n\tm_obtainedResult.clear();\n\tbool first = true;\n\tfor (std::string const& contractName: compiler.contractNames())\n\t{\n\t\tif (!first)\n\t\t\tm_obtainedResult += \"\\n\\n\";\n\t\tm_obtainedResult += \"    \" + contractName + \"\\n\";\n\t\tm_obtainedResult += jsonPrettyPrint(compiler.contractABI(contractName)) + \"\\n\";\n\t\tfirst = false;\n\t}\n\n\treturn checkResult(_stream, _linePrefix, _formatted);\n}\n"
  },
  {
    "path": "test/libsolidity/ABIJsonTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Unit tests for the solidity compiler ABI JSON Interface output.\n */\n\n#pragma once\n\n#include <test/TestCase.h>\n\n#include <string>\n\nnamespace solidity::frontend::test\n{\n\n\nclass ABIJsonTest: public TestCase\n{\npublic:\n\tstatic std::unique_ptr<TestCase> create(Config const& _config)\n\t{ return std::make_unique<ABIJsonTest>(_config.filename); }\n\tABIJsonTest(std::string const& _filename);\n\n\tTestResult run(std::ostream& _stream, std::string const& _linePrefix = \"\", bool const _formatted = false) override;\n};\n\n}\n"
  },
  {
    "path": "test/libsolidity/ABITestsCommon.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <string>\n\nnamespace solidity::frontend::test\n{\n\n#define NEW_ENCODER(CODE) \\\n{ \\\n\tstd::string sourceCodeTmp = sourceCode; \\\n\tsourceCode = \"pragma abicoder v2;\\n\" + sourceCode; \\\n\t{ CODE } \\\n\tsourceCode = sourceCodeTmp; \\\n}\n\n#define OLD_ENCODER(CODE) \\\n{ \\\n\tstd::string sourceCodeTmp = sourceCode; \\\n\tsourceCode = \"pragma abicoder v1;\\n\" + sourceCode; \\\n\t{ CODE } \\\n\tsourceCode = sourceCodeTmp; \\\n}\n\n#define BOTH_ENCODERS(CODE) \\\n{ \\\n\tOLD_ENCODER(CODE) \\\n\tNEW_ENCODER(CODE) \\\n}\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/abstract_contract.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      5\n    ]\n  },\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": true,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"18:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"37:4:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"34:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"37:0:1\"\n          },\n          \"scope\": 5,\n          \"src\": \"23:18:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"scope\": 6,\n      \"src\": \"0:43:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:44:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/abstract_contract.sol",
    "content": "abstract contract C {\n\tconstructor() {\n\t}\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/abstract_contract_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": true,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 5,\n      \"name\": \"C\",\n      \"nameLocation\": \"18:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"37:4:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"34:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"37:0:1\"\n          },\n          \"src\": \"23:18:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false\n        }\n      ],\n      \"src\": \"0:43:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:44:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/address_payable.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      39\n    ]\n  },\n  \"id\": 40,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 39,\n      \"linearizedBaseContracts\": [\n        39\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"functionSelector\": \"97682884\",\n          \"id\": 4,\n          \"mutability\": \"mutable\",\n          \"name\": \"m\",\n          \"nameLocation\": \"60:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 39,\n          \"src\": \"17:44:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_mapping$_t_address_$_t_address_payable_$\",\n            \"typeString\": \"mapping(address => address payable)\"\n          },\n          \"typeName\": {\n            \"id\": 3,\n            \"keyName\": \"\",\n            \"keyNameLocation\": \"-1:-1:-1\",\n            \"keyType\": {\n              \"id\": 1,\n              \"name\": \"address\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"25:7:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_address\",\n                \"typeString\": \"address\"\n              }\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"17:35:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_mapping$_t_address_$_t_address_payable_$\",\n              \"typeString\": \"mapping(address => address payable)\"\n            },\n            \"valueName\": \"\",\n            \"valueNameLocation\": \"-1:-1:-1\",\n            \"valueType\": {\n              \"id\": 2,\n              \"name\": \"address\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"36:15:1\",\n              \"stateMutability\": \"payable\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_address_payable\",\n                \"typeString\": \"address payable\"\n              }\n            }\n          },\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 37,\n            \"nodeType\": \"Block\",\n            \"src\": \"134:122:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  12\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 12,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"a\",\n                    \"nameLocation\": \"160:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 37,\n                    \"src\": \"144:17:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_address_payable\",\n                      \"typeString\": \"address payable\"\n                    },\n                    \"typeName\": {\n                      \"id\": 11,\n                      \"name\": \"address\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"144:15:1\",\n                      \"stateMutability\": \"payable\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_address_payable\",\n                        \"typeString\": \"address payable\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 16,\n                \"initialValue\": {\n                  \"baseExpression\": {\n                    \"id\": 13,\n                    \"name\": \"m\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 4,\n                    \"src\": \"164:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_mapping$_t_address_$_t_address_payable_$\",\n                      \"typeString\": \"mapping(address => address payable)\"\n                    }\n                  },\n                  \"id\": 15,\n                  \"indexExpression\": {\n                    \"id\": 14,\n                    \"name\": \"arg\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 6,\n                    \"src\": \"166:3:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_address_payable\",\n                      \"typeString\": \"address payable\"\n                    }\n                  },\n                  \"isConstant\": false,\n                  \"isLValue\": true,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"nodeType\": \"IndexAccess\",\n                  \"src\": \"164:6:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address_payable\",\n                    \"typeString\": \"address payable\"\n                  }\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"144:26:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 19,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"leftHandSide\": {\n                    \"id\": 17,\n                    \"name\": \"r\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 9,\n                    \"src\": \"180:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_address_payable\",\n                      \"typeString\": \"address payable\"\n                    }\n                  },\n                  \"nodeType\": \"Assignment\",\n                  \"operator\": \"=\",\n                  \"rightHandSide\": {\n                    \"id\": 18,\n                    \"name\": \"arg\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 6,\n                    \"src\": \"184:3:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_address_payable\",\n                      \"typeString\": \"address payable\"\n                    }\n                  },\n                  \"src\": \"180:7:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address_payable\",\n                    \"typeString\": \"address payable\"\n                  }\n                },\n                \"id\": 20,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"180:7:1\"\n              },\n              {\n                \"assignments\": [\n                  22\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 22,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"c\",\n                    \"nameLocation\": \"205:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 37,\n                    \"src\": \"197:9:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_address\",\n                      \"typeString\": \"address\"\n                    },\n                    \"typeName\": {\n                      \"id\": 21,\n                      \"name\": \"address\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"197:7:1\",\n                      \"stateMutability\": \"nonpayable\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 27,\n                \"initialValue\": {\n                  \"arguments\": [\n                    {\n                      \"id\": 25,\n                      \"name\": \"this\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": -28,\n                      \"src\": \"217:4:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_contract$_C_$39\",\n                        \"typeString\": \"contract C\"\n                      }\n                    }\n                  ],\n                  \"expression\": {\n                    \"argumentTypes\": [\n                      {\n                        \"typeIdentifier\": \"t_contract$_C_$39\",\n                        \"typeString\": \"contract C\"\n                      }\n                    ],\n                    \"id\": 24,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"ElementaryTypeNameExpression\",\n                    \"src\": \"209:7:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_type$_t_address_$\",\n                      \"typeString\": \"type(address)\"\n                    },\n                    \"typeName\": {\n                      \"id\": 23,\n                      \"name\": \"address\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"209:7:1\",\n                      \"typeDescriptions\": {}\n                    }\n                  },\n                  \"id\": 26,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"typeConversion\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"209:13:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address\",\n                    \"typeString\": \"address\"\n                  }\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"197:25:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 35,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"leftHandSide\": {\n                    \"baseExpression\": {\n                      \"id\": 28,\n                      \"name\": \"m\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 4,\n                      \"src\": \"232:1:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_mapping$_t_address_$_t_address_payable_$\",\n                        \"typeString\": \"mapping(address => address payable)\"\n                      }\n                    },\n                    \"id\": 30,\n                    \"indexExpression\": {\n                      \"id\": 29,\n                      \"name\": \"c\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 22,\n                      \"src\": \"234:1:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      }\n                    },\n                    \"isConstant\": false,\n                    \"isLValue\": true,\n                    \"isPure\": false,\n                    \"lValueRequested\": true,\n                    \"nodeType\": \"IndexAccess\",\n                    \"src\": \"232:4:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_address_payable\",\n                      \"typeString\": \"address payable\"\n                    }\n                  },\n                  \"nodeType\": \"Assignment\",\n                  \"operator\": \"=\",\n                  \"rightHandSide\": {\n                    \"arguments\": [\n                      {\n                        \"hexValue\": \"30\",\n                        \"id\": 33,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": true,\n                        \"kind\": \"number\",\n                        \"lValueRequested\": false,\n                        \"nodeType\": \"Literal\",\n                        \"src\": \"247:1:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_rational_0_by_1\",\n                          \"typeString\": \"int_const 0\"\n                        },\n                        \"value\": \"0\"\n                      }\n                    ],\n                    \"expression\": {\n                      \"argumentTypes\": [\n                        {\n                          \"typeIdentifier\": \"t_rational_0_by_1\",\n                          \"typeString\": \"int_const 0\"\n                        }\n                      ],\n                      \"id\": 32,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"lValueRequested\": false,\n                      \"nodeType\": \"ElementaryTypeNameExpression\",\n                      \"src\": \"239:8:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_type$_t_address_payable_$\",\n                        \"typeString\": \"type(address payable)\"\n                      },\n                      \"typeName\": {\n                        \"id\": 31,\n                        \"name\": \"address\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"239:8:1\",\n                        \"stateMutability\": \"payable\",\n                        \"typeDescriptions\": {}\n                      }\n                    },\n                    \"id\": 34,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"kind\": \"typeConversion\",\n                    \"lValueRequested\": false,\n                    \"nameLocations\": [],\n                    \"names\": [],\n                    \"nodeType\": \"FunctionCall\",\n                    \"src\": \"239:10:1\",\n                    \"tryCall\": false,\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_address_payable\",\n                      \"typeString\": \"address payable\"\n                    }\n                  },\n                  \"src\": \"232:17:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address_payable\",\n                    \"typeString\": \"address payable\"\n                  }\n                },\n                \"id\": 36,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"232:17:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"fc68521a\",\n          \"id\": 38,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"76:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 6,\n                \"mutability\": \"mutable\",\n                \"name\": \"arg\",\n                \"nameLocation\": \"94:3:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 38,\n                \"src\": \"78:19:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_address_payable\",\n                  \"typeString\": \"address payable\"\n                },\n                \"typeName\": {\n                  \"id\": 5,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"78:15:1\",\n                  \"stateMutability\": \"payable\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address_payable\",\n                    \"typeString\": \"address payable\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"77:21:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 10,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 9,\n                \"mutability\": \"mutable\",\n                \"name\": \"r\",\n                \"nameLocation\": \"131:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 38,\n                \"src\": \"115:17:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_address_payable\",\n                  \"typeString\": \"address payable\"\n                },\n                \"typeName\": {\n                  \"id\": 8,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"115:15:1\",\n                  \"stateMutability\": \"payable\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address_payable\",\n                    \"typeString\": \"address payable\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"114:19:1\"\n          },\n          \"scope\": 39,\n          \"src\": \"67:189:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 40,\n      \"src\": \"0:258:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:259:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/address_payable.sol",
    "content": "contract C {\n    mapping(address => address payable) public m;\n    function f(address payable arg) public returns (address payable r) {\n        address payable a = m[arg];\n        r = arg;\n        address c = address(this);\n        m[c] = payable(0);\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/address_payable_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 40,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 39,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 4,\n          \"mutability\": \"mutable\",\n          \"name\": \"m\",\n          \"nameLocation\": \"60:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"17:44:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 3,\n            \"keyName\": \"\",\n            \"keyNameLocation\": \"-1:-1:-1\",\n            \"keyType\": {\n              \"id\": 1,\n              \"name\": \"address\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"25:7:1\",\n              \"typeDescriptions\": {}\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"17:35:1\",\n            \"typeDescriptions\": {},\n            \"valueName\": \"\",\n            \"valueNameLocation\": \"-1:-1:-1\",\n            \"valueType\": {\n              \"id\": 2,\n              \"name\": \"address\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"36:15:1\",\n              \"stateMutability\": \"payable\",\n              \"typeDescriptions\": {}\n            }\n          },\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 37,\n            \"nodeType\": \"Block\",\n            \"src\": \"134:122:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  12\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 12,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"a\",\n                    \"nameLocation\": \"160:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"144:17:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 11,\n                      \"name\": \"address\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"144:15:1\",\n                      \"stateMutability\": \"payable\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 16,\n                \"initialValue\": {\n                  \"baseExpression\": {\n                    \"id\": 13,\n                    \"name\": \"m\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"164:1:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"id\": 15,\n                  \"indexExpression\": {\n                    \"id\": 14,\n                    \"name\": \"arg\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"166:3:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"nodeType\": \"IndexAccess\",\n                  \"src\": \"164:6:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"144:26:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 19,\n                  \"leftHandSide\": {\n                    \"id\": 17,\n                    \"name\": \"r\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"180:1:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"nodeType\": \"Assignment\",\n                  \"operator\": \"=\",\n                  \"rightHandSide\": {\n                    \"id\": 18,\n                    \"name\": \"arg\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"184:3:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"src\": \"180:7:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 20,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"180:7:1\"\n              },\n              {\n                \"assignments\": [\n                  22\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 22,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"c\",\n                    \"nameLocation\": \"205:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"197:9:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 21,\n                      \"name\": \"address\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"197:7:1\",\n                      \"stateMutability\": \"nonpayable\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 27,\n                \"initialValue\": {\n                  \"arguments\": [\n                    {\n                      \"id\": 25,\n                      \"name\": \"this\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"src\": \"217:4:1\",\n                      \"typeDescriptions\": {}\n                    }\n                  ],\n                  \"expression\": {\n                    \"id\": 24,\n                    \"nodeType\": \"ElementaryTypeNameExpression\",\n                    \"src\": \"209:7:1\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 23,\n                      \"name\": \"address\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"209:7:1\",\n                      \"typeDescriptions\": {}\n                    }\n                  },\n                  \"id\": 26,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"209:13:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {}\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"197:25:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 35,\n                  \"leftHandSide\": {\n                    \"baseExpression\": {\n                      \"id\": 28,\n                      \"name\": \"m\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"src\": \"232:1:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"id\": 30,\n                    \"indexExpression\": {\n                      \"id\": 29,\n                      \"name\": \"c\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"src\": \"234:1:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"nodeType\": \"IndexAccess\",\n                    \"src\": \"232:4:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"nodeType\": \"Assignment\",\n                  \"operator\": \"=\",\n                  \"rightHandSide\": {\n                    \"arguments\": [\n                      {\n                        \"hexValue\": \"30\",\n                        \"id\": 33,\n                        \"kind\": \"number\",\n                        \"nodeType\": \"Literal\",\n                        \"src\": \"247:1:1\",\n                        \"typeDescriptions\": {},\n                        \"value\": \"0\"\n                      }\n                    ],\n                    \"expression\": {\n                      \"id\": 32,\n                      \"nodeType\": \"ElementaryTypeNameExpression\",\n                      \"src\": \"239:8:1\",\n                      \"typeDescriptions\": {},\n                      \"typeName\": {\n                        \"id\": 31,\n                        \"name\": \"address\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"239:8:1\",\n                        \"stateMutability\": \"payable\",\n                        \"typeDescriptions\": {}\n                      }\n                    },\n                    \"id\": 34,\n                    \"nameLocations\": [],\n                    \"names\": [],\n                    \"nodeType\": \"FunctionCall\",\n                    \"src\": \"239:10:1\",\n                    \"tryCall\": false,\n                    \"typeDescriptions\": {}\n                  },\n                  \"src\": \"232:17:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 36,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"232:17:1\"\n              }\n            ]\n          },\n          \"id\": 38,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"76:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 6,\n                \"mutability\": \"mutable\",\n                \"name\": \"arg\",\n                \"nameLocation\": \"94:3:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"78:19:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 5,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"78:15:1\",\n                  \"stateMutability\": \"payable\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"77:21:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 10,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 9,\n                \"mutability\": \"mutable\",\n                \"name\": \"r\",\n                \"nameLocation\": \"131:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"115:17:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 8,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"115:15:1\",\n                  \"stateMutability\": \"payable\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"114:19:1\"\n          },\n          \"src\": \"67:189:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:258:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:259:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/array_type_name.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      4\n    ]\n  },\n  \"id\": 5,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 4,\n      \"linearizedBaseContracts\": [\n        4\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 3,\n          \"mutability\": \"mutable\",\n          \"name\": \"i\",\n          \"nameLocation\": \"20:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 4,\n          \"src\": \"13:8:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_array$_t_uint256_$dyn_storage\",\n            \"typeString\": \"uint256[]\"\n          },\n          \"typeName\": {\n            \"baseType\": {\n              \"id\": 1,\n              \"name\": \"uint\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"13:4:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_uint256\",\n                \"typeString\": \"uint256\"\n              }\n            },\n            \"id\": 2,\n            \"nodeType\": \"ArrayTypeName\",\n            \"src\": \"13:6:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_array$_t_uint256_$dyn_storage_ptr\",\n              \"typeString\": \"uint256[]\"\n            }\n          },\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"scope\": 5,\n      \"src\": \"0:24:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:25:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/array_type_name.sol",
    "content": "contract C { uint[] i; }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/array_type_name_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 5,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 4,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 3,\n          \"mutability\": \"mutable\",\n          \"name\": \"i\",\n          \"nameLocation\": \"20:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"13:8:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"baseType\": {\n              \"id\": 1,\n              \"name\": \"uint\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"13:4:1\",\n              \"typeDescriptions\": {}\n            },\n            \"id\": 2,\n            \"nodeType\": \"ArrayTypeName\",\n            \"src\": \"13:6:1\",\n            \"typeDescriptions\": {}\n          },\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"src\": \"0:24:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:25:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/call.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      6\n    ]\n  },\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 6,\n      \"linearizedBaseContracts\": [\n        6\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"37:59:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"56:34:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"56:34:1\",\n                  \"statements\": [\n                    {\n                      \"expression\": {\n                        \"arguments\": [\n                          {\n                            \"arguments\": [\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"67:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"67:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"0\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"70:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"70:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"1\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"73:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"73:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"2\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"76:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"76:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"3\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"79:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"79:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"4\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"82:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"82:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"5\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"85:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"85:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"6\"\n                              }\n                            ],\n                            \"functionName\": {\n                              \"name\": \"call\",\n                              \"nativeSrc\": \"62:4:1\",\n                              \"nodeType\": \"YulIdentifier\",\n                              \"src\": \"62:4:1\"\n                            },\n                            \"nativeSrc\": \"62:25:1\",\n                            \"nodeType\": \"YulFunctionCall\",\n                            \"src\": \"62:25:1\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"pop\",\n                          \"nativeSrc\": \"58:3:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"58:3:1\"\n                        },\n                        \"nativeSrc\": \"58:30:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"58:30:1\"\n                      },\n                      \"nativeSrc\": \"58:30:1\",\n                      \"nodeType\": \"YulExpressionStatement\",\n                      \"src\": \"58:30:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"47:43:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"b582ec5f\",\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"j\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"37:0:1\"\n          },\n          \"scope\": 6,\n          \"src\": \"17:79:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 7,\n      \"src\": \"0:98:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:99:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/call.sol",
    "content": "contract C {\n    function j() public {\n        assembly { pop(call(0, 1, 2, 3, 4, 5, 6)) }\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/call_legacy.json",
    "content": "{\n  \"attributes\":\n  {\n    \"absolutePath\": \"a\",\n    \"exportedSymbols\":\n    {\n      \"C\":\n      [\n        6\n      ]\n    }\n  },\n  \"children\":\n  [\n    {\n      \"attributes\":\n      {\n        \"abstract\": false,\n        \"baseContracts\":\n        [\n          null\n        ],\n        \"contractDependencies\":\n        [\n          null\n        ],\n        \"contractKind\": \"contract\",\n        \"fullyImplemented\": true,\n        \"linearizedBaseContracts\":\n        [\n          6\n        ],\n        \"name\": \"C\",\n        \"scope\": 7\n      },\n      \"children\":\n      [\n        {\n          \"attributes\":\n          {\n            \"functionSelector\": \"b582ec5f\",\n            \"implemented\": true,\n            \"isConstructor\": false,\n            \"kind\": \"function\",\n            \"modifiers\":\n            [\n              null\n            ],\n            \"name\": \"j\",\n            \"scope\": 6,\n            \"stateMutability\": \"nonpayable\",\n            \"virtual\": false,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 1,\n              \"name\": \"ParameterList\",\n              \"src\": \"27:2:1\"\n            },\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 2,\n              \"name\": \"ParameterList\",\n              \"src\": \"37:0:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"evmVersion\": %EVMVERSION%,\n                    \"externalReferences\":\n                    [\n                      null\n                    ],\n                    \"operations\": \"{\\n    pop(call(0, 1, 2, 3, 4, 5, 6))\\n}\"\n                  },\n                  \"children\": [],\n                  \"id\": 3,\n                  \"name\": \"InlineAssembly\",\n                  \"src\": \"47:43:1\"\n                }\n              ],\n              \"id\": 4,\n              \"name\": \"Block\",\n              \"src\": \"37:59:1\"\n            }\n          ],\n          \"id\": 5,\n          \"name\": \"FunctionDefinition\",\n          \"src\": \"17:79:1\"\n        }\n      ],\n      \"id\": 6,\n      \"name\": \"ContractDefinition\",\n      \"src\": \"0:98:1\"\n    }\n  ],\n  \"id\": 7,\n  \"name\": \"SourceUnit\",\n  \"src\": \"0:99:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/call_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 6,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"37:59:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"56:34:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"56:34:1\",\n                  \"statements\": [\n                    {\n                      \"expression\": {\n                        \"arguments\": [\n                          {\n                            \"arguments\": [\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"67:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"67:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"0\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"70:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"70:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"1\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"73:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"73:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"2\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"76:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"76:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"3\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"79:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"79:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"4\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"82:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"82:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"5\"\n                              },\n                              {\n                                \"kind\": \"number\",\n                                \"nativeSrc\": \"85:1:1\",\n                                \"nodeType\": \"YulLiteral\",\n                                \"src\": \"85:1:1\",\n                                \"type\": \"\",\n                                \"value\": \"6\"\n                              }\n                            ],\n                            \"functionName\": {\n                              \"name\": \"call\",\n                              \"nativeSrc\": \"62:4:1\",\n                              \"nodeType\": \"YulIdentifier\",\n                              \"src\": \"62:4:1\"\n                            },\n                            \"nativeSrc\": \"62:25:1\",\n                            \"nodeType\": \"YulFunctionCall\",\n                            \"src\": \"62:25:1\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"pop\",\n                          \"nativeSrc\": \"58:3:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"58:3:1\"\n                        },\n                        \"nativeSrc\": \"58:30:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"58:30:1\"\n                      },\n                      \"nativeSrc\": \"58:30:1\",\n                      \"nodeType\": \"YulExpressionStatement\",\n                      \"src\": \"58:30:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"47:43:1\"\n              }\n            ]\n          },\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"j\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"37:0:1\"\n          },\n          \"src\": \"17:79:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:98:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:99:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/empty_block.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      6\n    ]\n  },\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 6,\n      \"linearizedBaseContracts\": [\n        6\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:31:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"61:6:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"61:6:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"63:2:1\",\n                      \"nodeType\": \"YulBlock\",\n                      \"src\": \"63:2:1\",\n                      \"statements\": []\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"52:15:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"e2179b8e\",\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"g\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"scope\": 6,\n          \"src\": \"17:56:1\",\n          \"stateMutability\": \"view\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 7,\n      \"src\": \"0:75:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:76:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/empty_block.sol",
    "content": "contract C {\n    function g() view public {\n        assembly { {} }\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/empty_block_legacy.json",
    "content": "{\n  \"attributes\":\n  {\n    \"absolutePath\": \"a\",\n    \"exportedSymbols\":\n    {\n      \"C\":\n      [\n        6\n      ]\n    }\n  },\n  \"children\":\n  [\n    {\n      \"attributes\":\n      {\n        \"abstract\": false,\n        \"baseContracts\":\n        [\n          null\n        ],\n        \"contractDependencies\":\n        [\n          null\n        ],\n        \"contractKind\": \"contract\",\n        \"fullyImplemented\": true,\n        \"linearizedBaseContracts\":\n        [\n          6\n        ],\n        \"name\": \"C\",\n        \"scope\": 7\n      },\n      \"children\":\n      [\n        {\n          \"attributes\":\n          {\n            \"functionSelector\": \"e2179b8e\",\n            \"implemented\": true,\n            \"isConstructor\": false,\n            \"kind\": \"function\",\n            \"modifiers\":\n            [\n              null\n            ],\n            \"name\": \"g\",\n            \"scope\": 6,\n            \"stateMutability\": \"view\",\n            \"virtual\": false,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 1,\n              \"name\": \"ParameterList\",\n              \"src\": \"27:2:1\"\n            },\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 2,\n              \"name\": \"ParameterList\",\n              \"src\": \"42:0:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"evmVersion\": %EVMVERSION%,\n                    \"externalReferences\":\n                    [\n                      null\n                    ],\n                    \"operations\": \"{ { } }\"\n                  },\n                  \"children\": [],\n                  \"id\": 3,\n                  \"name\": \"InlineAssembly\",\n                  \"src\": \"52:15:1\"\n                }\n              ],\n              \"id\": 4,\n              \"name\": \"Block\",\n              \"src\": \"42:31:1\"\n            }\n          ],\n          \"id\": 5,\n          \"name\": \"FunctionDefinition\",\n          \"src\": \"17:56:1\"\n        }\n      ],\n      \"id\": 6,\n      \"name\": \"ContractDefinition\",\n      \"src\": \"0:75:1\"\n    }\n  ],\n  \"id\": 7,\n  \"name\": \"SourceUnit\",\n  \"src\": \"0:76:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/empty_block_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 6,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:31:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"61:6:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"61:6:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"63:2:1\",\n                      \"nodeType\": \"YulBlock\",\n                      \"src\": \"63:2:1\",\n                      \"statements\": []\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"52:15:1\"\n              }\n            ]\n          },\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"g\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"src\": \"17:56:1\",\n          \"stateMutability\": \"view\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:75:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:76:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      6\n    ]\n  },\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 6,\n      \"linearizedBaseContracts\": [\n        6\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"39:30:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"52:14:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"52:14:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"57:5:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"57:5:1\",\n                      \"variables\": [\n                        {\n                          \"name\": \"x\",\n                          \"nativeSrc\": \"61:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"61:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"43:23:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"23:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"24:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"39:0:1\"\n          },\n          \"scope\": 6,\n          \"src\": \"14:55:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 7,\n      \"src\": \"0:71:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:72:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tassembly {\n\t\t\tlet x\n\t\t}\n\t}\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/empty_let_variable_declaration_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 6,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"39:30:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"52:14:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"52:14:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"57:5:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"57:5:1\",\n                      \"variables\": [\n                        {\n                          \"name\": \"x\",\n                          \"nativeSrc\": \"61:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"61:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"43:23:1\"\n              }\n            ]\n          },\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"23:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"24:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"39:0:1\"\n          },\n          \"src\": \"14:55:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:71:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:72:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/function.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      6\n    ]\n  },\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 6,\n      \"linearizedBaseContracts\": [\n        6\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:68:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"61:43:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"61:43:1\",\n                  \"statements\": [\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"76:22:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"76:22:1\",\n                        \"statements\": [\n                          {\n                            \"expression\": {\n                              \"arguments\": [\n                                {\n                                  \"arguments\": [\n                                    {\n                                      \"kind\": \"number\",\n                                      \"nativeSrc\": \"92:2:1\",\n                                      \"nodeType\": \"YulLiteral\",\n                                      \"src\": \"92:2:1\",\n                                      \"type\": \"\",\n                                      \"value\": \"20\"\n                                    }\n                                  ],\n                                  \"functionName\": {\n                                    \"name\": \"blockhash\",\n                                    \"nativeSrc\": \"82:9:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"82:9:1\"\n                                  },\n                                  \"nativeSrc\": \"82:13:1\",\n                                  \"nodeType\": \"YulFunctionCall\",\n                                  \"src\": \"82:13:1\"\n                                }\n                              ],\n                              \"functionName\": {\n                                \"name\": \"pop\",\n                                \"nativeSrc\": \"78:3:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"78:3:1\"\n                              },\n                              \"nativeSrc\": \"78:18:1\",\n                              \"nodeType\": \"YulFunctionCall\",\n                              \"src\": \"78:18:1\"\n                            },\n                            \"nativeSrc\": \"78:18:1\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"78:18:1\"\n                          }\n                        ]\n                      },\n                      \"name\": \"g\",\n                      \"nativeSrc\": \"63:35:1\",\n                      \"nodeType\": \"YulFunctionDefinition\",\n                      \"src\": \"63:35:1\"\n                    },\n                    {\n                      \"expression\": {\n                        \"arguments\": [],\n                        \"functionName\": {\n                          \"name\": \"g\",\n                          \"nativeSrc\": \"99:1:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"99:1:1\"\n                        },\n                        \"nativeSrc\": \"99:3:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"99:3:1\"\n                      },\n                      \"nativeSrc\": \"99:3:1\",\n                      \"nodeType\": \"YulExpressionStatement\",\n                      \"src\": \"99:3:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"52:52:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"b8c9d365\",\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"h\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"scope\": 6,\n          \"src\": \"17:93:1\",\n          \"stateMutability\": \"view\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 7,\n      \"src\": \"0:112:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:113:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/function.sol",
    "content": "contract C {\n    function h() view public {\n        assembly { function g() { pop(blockhash(20)) } g() }\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/function_legacy.json",
    "content": "{\n  \"attributes\":\n  {\n    \"absolutePath\": \"a\",\n    \"exportedSymbols\":\n    {\n      \"C\":\n      [\n        6\n      ]\n    }\n  },\n  \"children\":\n  [\n    {\n      \"attributes\":\n      {\n        \"abstract\": false,\n        \"baseContracts\":\n        [\n          null\n        ],\n        \"contractDependencies\":\n        [\n          null\n        ],\n        \"contractKind\": \"contract\",\n        \"fullyImplemented\": true,\n        \"linearizedBaseContracts\":\n        [\n          6\n        ],\n        \"name\": \"C\",\n        \"scope\": 7\n      },\n      \"children\":\n      [\n        {\n          \"attributes\":\n          {\n            \"functionSelector\": \"b8c9d365\",\n            \"implemented\": true,\n            \"isConstructor\": false,\n            \"kind\": \"function\",\n            \"modifiers\":\n            [\n              null\n            ],\n            \"name\": \"h\",\n            \"scope\": 6,\n            \"stateMutability\": \"view\",\n            \"virtual\": false,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 1,\n              \"name\": \"ParameterList\",\n              \"src\": \"27:2:1\"\n            },\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 2,\n              \"name\": \"ParameterList\",\n              \"src\": \"42:0:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"evmVersion\": %EVMVERSION%,\n                    \"externalReferences\":\n                    [\n                      null\n                    ],\n                    \"operations\": \"{\\n    function g()\\n    { pop(blockhash(20)) }\\n    g()\\n}\"\n                  },\n                  \"children\": [],\n                  \"id\": 3,\n                  \"name\": \"InlineAssembly\",\n                  \"src\": \"52:52:1\"\n                }\n              ],\n              \"id\": 4,\n              \"name\": \"Block\",\n              \"src\": \"42:68:1\"\n            }\n          ],\n          \"id\": 5,\n          \"name\": \"FunctionDefinition\",\n          \"src\": \"17:93:1\"\n        }\n      ],\n      \"id\": 6,\n      \"name\": \"ContractDefinition\",\n      \"src\": \"0:112:1\"\n    }\n  ],\n  \"id\": 7,\n  \"name\": \"SourceUnit\",\n  \"src\": \"0:113:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/function_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 6,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:68:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"61:43:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"61:43:1\",\n                  \"statements\": [\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"76:22:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"76:22:1\",\n                        \"statements\": [\n                          {\n                            \"expression\": {\n                              \"arguments\": [\n                                {\n                                  \"arguments\": [\n                                    {\n                                      \"kind\": \"number\",\n                                      \"nativeSrc\": \"92:2:1\",\n                                      \"nodeType\": \"YulLiteral\",\n                                      \"src\": \"92:2:1\",\n                                      \"type\": \"\",\n                                      \"value\": \"20\"\n                                    }\n                                  ],\n                                  \"functionName\": {\n                                    \"name\": \"blockhash\",\n                                    \"nativeSrc\": \"82:9:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"82:9:1\"\n                                  },\n                                  \"nativeSrc\": \"82:13:1\",\n                                  \"nodeType\": \"YulFunctionCall\",\n                                  \"src\": \"82:13:1\"\n                                }\n                              ],\n                              \"functionName\": {\n                                \"name\": \"pop\",\n                                \"nativeSrc\": \"78:3:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"78:3:1\"\n                              },\n                              \"nativeSrc\": \"78:18:1\",\n                              \"nodeType\": \"YulFunctionCall\",\n                              \"src\": \"78:18:1\"\n                            },\n                            \"nativeSrc\": \"78:18:1\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"78:18:1\"\n                          }\n                        ]\n                      },\n                      \"name\": \"g\",\n                      \"nativeSrc\": \"63:35:1\",\n                      \"nodeType\": \"YulFunctionDefinition\",\n                      \"src\": \"63:35:1\"\n                    },\n                    {\n                      \"expression\": {\n                        \"arguments\": [],\n                        \"functionName\": {\n                          \"name\": \"g\",\n                          \"nativeSrc\": \"99:1:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"99:1:1\"\n                        },\n                        \"nativeSrc\": \"99:3:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"99:3:1\"\n                      },\n                      \"nativeSrc\": \"99:3:1\",\n                      \"nodeType\": \"YulExpressionStatement\",\n                      \"src\": \"99:3:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"52:52:1\"\n              }\n            ]\n          },\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"h\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"src\": \"17:93:1\",\n          \"stateMutability\": \"view\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:112:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:113:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/leave.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      6\n    ]\n  },\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 6,\n      \"linearizedBaseContracts\": [\n        6\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"37:51:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"56:26:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"56:26:1\",\n                  \"statements\": [\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"71:9:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"71:9:1\",\n                        \"statements\": [\n                          {\n                            \"nativeSrc\": \"73:5:1\",\n                            \"nodeType\": \"YulLeave\",\n                            \"src\": \"73:5:1\"\n                          }\n                        ]\n                      },\n                      \"name\": \"f\",\n                      \"nativeSrc\": \"58:22:1\",\n                      \"nodeType\": \"YulFunctionDefinition\",\n                      \"src\": \"58:22:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"47:35:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"ece866b9\",\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"l\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"37:0:1\"\n          },\n          \"scope\": 6,\n          \"src\": \"17:71:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 7,\n      \"src\": \"0:90:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:91:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/leave.sol",
    "content": "contract C {\n    function l() public {\n        assembly { function f() { leave } }\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/leave_legacy.json",
    "content": "{\n  \"attributes\":\n  {\n    \"absolutePath\": \"a\",\n    \"exportedSymbols\":\n    {\n      \"C\":\n      [\n        6\n      ]\n    }\n  },\n  \"children\":\n  [\n    {\n      \"attributes\":\n      {\n        \"abstract\": false,\n        \"baseContracts\":\n        [\n          null\n        ],\n        \"contractDependencies\":\n        [\n          null\n        ],\n        \"contractKind\": \"contract\",\n        \"fullyImplemented\": true,\n        \"linearizedBaseContracts\":\n        [\n          6\n        ],\n        \"name\": \"C\",\n        \"scope\": 7\n      },\n      \"children\":\n      [\n        {\n          \"attributes\":\n          {\n            \"functionSelector\": \"ece866b9\",\n            \"implemented\": true,\n            \"isConstructor\": false,\n            \"kind\": \"function\",\n            \"modifiers\":\n            [\n              null\n            ],\n            \"name\": \"l\",\n            \"scope\": 6,\n            \"stateMutability\": \"nonpayable\",\n            \"virtual\": false,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 1,\n              \"name\": \"ParameterList\",\n              \"src\": \"27:2:1\"\n            },\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 2,\n              \"name\": \"ParameterList\",\n              \"src\": \"37:0:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"evmVersion\": %EVMVERSION%,\n                    \"externalReferences\":\n                    [\n                      null\n                    ],\n                    \"operations\": \"{\\n    function f()\\n    { leave }\\n}\"\n                  },\n                  \"children\": [],\n                  \"id\": 3,\n                  \"name\": \"InlineAssembly\",\n                  \"src\": \"47:35:1\"\n                }\n              ],\n              \"id\": 4,\n              \"name\": \"Block\",\n              \"src\": \"37:51:1\"\n            }\n          ],\n          \"id\": 5,\n          \"name\": \"FunctionDefinition\",\n          \"src\": \"17:71:1\"\n        }\n      ],\n      \"id\": 6,\n      \"name\": \"ContractDefinition\",\n      \"src\": \"0:90:1\"\n    }\n  ],\n  \"id\": 7,\n  \"name\": \"SourceUnit\",\n  \"src\": \"0:91:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/leave_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 6,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"37:51:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"56:26:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"56:26:1\",\n                  \"statements\": [\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"71:9:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"71:9:1\",\n                        \"statements\": [\n                          {\n                            \"nativeSrc\": \"73:5:1\",\n                            \"nodeType\": \"YulLeave\",\n                            \"src\": \"73:5:1\"\n                          }\n                        ]\n                      },\n                      \"name\": \"f\",\n                      \"nativeSrc\": \"58:22:1\",\n                      \"nodeType\": \"YulFunctionDefinition\",\n                      \"src\": \"58:22:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"47:35:1\"\n              }\n            ]\n          },\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"l\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"37:0:1\"\n          },\n          \"src\": \"17:71:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:90:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:91:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/loop.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      6\n    ]\n  },\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 6,\n      \"linearizedBaseContracts\": [\n        6\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:74:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"61:49:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"61:49:1\",\n                  \"statements\": [\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"90:18:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"90:18:1\",\n                        \"statements\": [\n                          {\n                            \"nativeSrc\": \"92:5:1\",\n                            \"nodeType\": \"YulBreak\",\n                            \"src\": \"92:5:1\"\n                          },\n                          {\n                            \"nativeSrc\": \"98:8:1\",\n                            \"nodeType\": \"YulContinue\",\n                            \"src\": \"98:8:1\"\n                          }\n                        ]\n                      },\n                      \"condition\": {\n                        \"kind\": \"number\",\n                        \"nativeSrc\": \"70:1:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"70:1:1\",\n                        \"type\": \"\",\n                        \"value\": \"1\"\n                      },\n                      \"nativeSrc\": \"63:45:1\",\n                      \"nodeType\": \"YulForLoop\",\n                      \"post\": {\n                        \"nativeSrc\": \"72:17:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"72:17:1\",\n                        \"statements\": [\n                          {\n                            \"expression\": {\n                              \"arguments\": [\n                                {\n                                  \"arguments\": [\n                                    {\n                                      \"kind\": \"number\",\n                                      \"nativeSrc\": \"84:1:1\",\n                                      \"nodeType\": \"YulLiteral\",\n                                      \"src\": \"84:1:1\",\n                                      \"type\": \"\",\n                                      \"value\": \"0\"\n                                    }\n                                  ],\n                                  \"functionName\": {\n                                    \"name\": \"sload\",\n                                    \"nativeSrc\": \"78:5:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"78:5:1\"\n                                  },\n                                  \"nativeSrc\": \"78:8:1\",\n                                  \"nodeType\": \"YulFunctionCall\",\n                                  \"src\": \"78:8:1\"\n                                }\n                              ],\n                              \"functionName\": {\n                                \"name\": \"pop\",\n                                \"nativeSrc\": \"74:3:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"74:3:1\"\n                              },\n                              \"nativeSrc\": \"74:13:1\",\n                              \"nodeType\": \"YulFunctionCall\",\n                              \"src\": \"74:13:1\"\n                            },\n                            \"nativeSrc\": \"74:13:1\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"74:13:1\"\n                          }\n                        ]\n                      },\n                      \"pre\": {\n                        \"nativeSrc\": \"67:2:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"67:2:1\",\n                        \"statements\": []\n                      },\n                      \"src\": \"63:45:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"52:58:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"e2179b8e\",\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"g\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"scope\": 6,\n          \"src\": \"17:99:1\",\n          \"stateMutability\": \"view\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 7,\n      \"src\": \"0:118:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:119:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/loop.sol",
    "content": "contract C {\n    function g() view public {\n        assembly { for {} 1 { pop(sload(0)) } { break continue } }\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/loop_legacy.json",
    "content": "{\n  \"attributes\":\n  {\n    \"absolutePath\": \"a\",\n    \"exportedSymbols\":\n    {\n      \"C\":\n      [\n        6\n      ]\n    }\n  },\n  \"children\":\n  [\n    {\n      \"attributes\":\n      {\n        \"abstract\": false,\n        \"baseContracts\":\n        [\n          null\n        ],\n        \"contractDependencies\":\n        [\n          null\n        ],\n        \"contractKind\": \"contract\",\n        \"fullyImplemented\": true,\n        \"linearizedBaseContracts\":\n        [\n          6\n        ],\n        \"name\": \"C\",\n        \"scope\": 7\n      },\n      \"children\":\n      [\n        {\n          \"attributes\":\n          {\n            \"functionSelector\": \"e2179b8e\",\n            \"implemented\": true,\n            \"isConstructor\": false,\n            \"kind\": \"function\",\n            \"modifiers\":\n            [\n              null\n            ],\n            \"name\": \"g\",\n            \"scope\": 6,\n            \"stateMutability\": \"view\",\n            \"virtual\": false,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 1,\n              \"name\": \"ParameterList\",\n              \"src\": \"27:2:1\"\n            },\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 2,\n              \"name\": \"ParameterList\",\n              \"src\": \"42:0:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"evmVersion\": %EVMVERSION%,\n                    \"externalReferences\":\n                    [\n                      null\n                    ],\n                    \"operations\": \"{\\n    for { } 1 { pop(sload(0)) }\\n    {\\n        break\\n        continue\\n    }\\n}\"\n                  },\n                  \"children\": [],\n                  \"id\": 3,\n                  \"name\": \"InlineAssembly\",\n                  \"src\": \"52:58:1\"\n                }\n              ],\n              \"id\": 4,\n              \"name\": \"Block\",\n              \"src\": \"42:74:1\"\n            }\n          ],\n          \"id\": 5,\n          \"name\": \"FunctionDefinition\",\n          \"src\": \"17:99:1\"\n        }\n      ],\n      \"id\": 6,\n      \"name\": \"ContractDefinition\",\n      \"src\": \"0:118:1\"\n    }\n  ],\n  \"id\": 7,\n  \"name\": \"SourceUnit\",\n  \"src\": \"0:119:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/loop_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 6,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:74:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"61:49:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"61:49:1\",\n                  \"statements\": [\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"90:18:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"90:18:1\",\n                        \"statements\": [\n                          {\n                            \"nativeSrc\": \"92:5:1\",\n                            \"nodeType\": \"YulBreak\",\n                            \"src\": \"92:5:1\"\n                          },\n                          {\n                            \"nativeSrc\": \"98:8:1\",\n                            \"nodeType\": \"YulContinue\",\n                            \"src\": \"98:8:1\"\n                          }\n                        ]\n                      },\n                      \"condition\": {\n                        \"kind\": \"number\",\n                        \"nativeSrc\": \"70:1:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"70:1:1\",\n                        \"type\": \"\",\n                        \"value\": \"1\"\n                      },\n                      \"nativeSrc\": \"63:45:1\",\n                      \"nodeType\": \"YulForLoop\",\n                      \"post\": {\n                        \"nativeSrc\": \"72:17:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"72:17:1\",\n                        \"statements\": [\n                          {\n                            \"expression\": {\n                              \"arguments\": [\n                                {\n                                  \"arguments\": [\n                                    {\n                                      \"kind\": \"number\",\n                                      \"nativeSrc\": \"84:1:1\",\n                                      \"nodeType\": \"YulLiteral\",\n                                      \"src\": \"84:1:1\",\n                                      \"type\": \"\",\n                                      \"value\": \"0\"\n                                    }\n                                  ],\n                                  \"functionName\": {\n                                    \"name\": \"sload\",\n                                    \"nativeSrc\": \"78:5:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"78:5:1\"\n                                  },\n                                  \"nativeSrc\": \"78:8:1\",\n                                  \"nodeType\": \"YulFunctionCall\",\n                                  \"src\": \"78:8:1\"\n                                }\n                              ],\n                              \"functionName\": {\n                                \"name\": \"pop\",\n                                \"nativeSrc\": \"74:3:1\",\n                                \"nodeType\": \"YulIdentifier\",\n                                \"src\": \"74:3:1\"\n                              },\n                              \"nativeSrc\": \"74:13:1\",\n                              \"nodeType\": \"YulFunctionCall\",\n                              \"src\": \"74:13:1\"\n                            },\n                            \"nativeSrc\": \"74:13:1\",\n                            \"nodeType\": \"YulExpressionStatement\",\n                            \"src\": \"74:13:1\"\n                          }\n                        ]\n                      },\n                      \"pre\": {\n                        \"nativeSrc\": \"67:2:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"67:2:1\",\n                        \"statements\": []\n                      },\n                      \"src\": \"63:45:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"52:58:1\"\n              }\n            ]\n          },\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"g\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"src\": \"17:99:1\",\n          \"stateMutability\": \"view\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:118:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:119:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/nested_functions.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      8\n    ]\n  },\n  \"id\": 9,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 8,\n      \"linearizedBaseContracts\": [\n        8\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 6,\n            \"nodeType\": \"Block\",\n            \"src\": \"57:95:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"72:76:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"72:76:1\",\n                  \"statements\": [\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"94:35:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"94:35:1\",\n                        \"statements\": [\n                          {\n                            \"body\": {\n                              \"nativeSrc\": \"118:3:1\",\n                              \"nodeType\": \"YulBlock\",\n                              \"src\": \"118:3:1\",\n                              \"statements\": []\n                            },\n                            \"name\": \"f2\",\n                            \"nativeSrc\": \"104:17:1\",\n                            \"nodeType\": \"YulFunctionDefinition\",\n                            \"src\": \"104:17:1\"\n                          }\n                        ]\n                      },\n                      \"name\": \"f1\",\n                      \"nativeSrc\": \"80:49:1\",\n                      \"nodeType\": \"YulFunctionDefinition\",\n                      \"src\": \"80:49:1\"\n                    },\n                    {\n                      \"nativeSrc\": \"136:6:1\",\n                      \"nodeType\": \"YulAssignment\",\n                      \"src\": \"136:6:1\",\n                      \"value\": {\n                        \"kind\": \"number\",\n                        \"nativeSrc\": \"141:1:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"141:1:1\",\n                        \"type\": \"\",\n                        \"value\": \"2\"\n                      },\n                      \"variableNames\": [\n                        {\n                          \"name\": \"x\",\n                          \"nativeSrc\": \"136:1:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"136:1:1\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [\n                  {\n                    \"declaration\": 3,\n                    \"isOffset\": false,\n                    \"isSlot\": false,\n                    \"src\": \"136:1:1\",\n                    \"valueSize\": 1\n                  }\n                ],\n                \"id\": 5,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"63:85:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 7,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"24:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"25:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 4,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 3,\n                \"mutability\": \"mutable\",\n                \"name\": \"x\",\n                \"nameLocation\": \"54:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 7,\n                \"src\": \"49:6:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                },\n                \"typeName\": {\n                  \"id\": 2,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"49:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"48:8:1\"\n          },\n          \"scope\": 8,\n          \"src\": \"15:137:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 9,\n      \"src\": \"0:154:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:155:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/nested_functions.sol",
    "content": "contract C {\n  function f() public pure returns (uint x) {\n    assembly {\n      function f1() {\n        function f2() { }\n      }\n      x := 2\n    }\n  }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/nested_functions_legacy.json",
    "content": "{\n  \"attributes\":\n  {\n    \"absolutePath\": \"a\",\n    \"exportedSymbols\":\n    {\n      \"C\":\n      [\n        8\n      ]\n    }\n  },\n  \"children\":\n  [\n    {\n      \"attributes\":\n      {\n        \"abstract\": false,\n        \"baseContracts\":\n        [\n          null\n        ],\n        \"contractDependencies\":\n        [\n          null\n        ],\n        \"contractKind\": \"contract\",\n        \"linearizedBaseContracts\":\n        [\n          8\n        ],\n        \"name\": \"C\",\n        \"scope\": 9\n      },\n      \"children\":\n      [\n        {\n          \"attributes\":\n          {\n            \"implemented\": true,\n            \"isConstructor\": false,\n            \"kind\": \"function\",\n            \"modifiers\":\n            [\n              null\n            ],\n            \"name\": \"f\",\n            \"scope\": 8,\n            \"stateMutability\": \"pure\",\n            \"virtual\": false,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 1,\n              \"name\": \"ParameterList\",\n              \"src\": \"25:2:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"constant\": false,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"scope\": 7,\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"visibility\": \"internal\"\n                  },\n                  \"children\":\n                  [\n                    {\n                      \"attributes\":\n                      {\n                        \"name\": \"uint\"\n                      },\n                      \"id\": 2,\n                      \"name\": \"ElementaryTypeName\",\n                      \"src\": \"49:4:1\"\n                    }\n                  ],\n                  \"id\": 3,\n                  \"name\": \"VariableDeclaration\",\n                  \"src\": \"49:6:1\"\n                }\n              ],\n              \"id\": 4,\n              \"name\": \"ParameterList\",\n              \"src\": \"48:8:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"evmVersion\": %EVMVERSION%,\n                    \"externalReferences\":\n                    [\n                      null\n                    ],\n                    \"operations\": \"{\\n    function f1()\\n    {\\n        function f2()\\n        { }\\n        x := 2\\n    }\\n}\"\n                  },\n                  \"children\": [],\n                  \"id\": 5,\n                  \"name\": \"InlineAssembly\",\n                  \"src\": \"63:87:1\"\n                }\n              ],\n              \"id\": 6,\n              \"name\": \"Block\",\n              \"src\": \"57:97:1\"\n            }\n          ],\n          \"id\": 7,\n          \"name\": \"FunctionDefinition\",\n          \"src\": \"15:139:1\"\n        }\n      ],\n      \"id\": 8,\n      \"name\": \"ContractDefinition\",\n      \"src\": \"0:156:1\"\n    }\n  ],\n  \"id\": 9,\n  \"name\": \"SourceUnit\",\n  \"src\": \"0:157:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/nested_functions_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 9,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 8,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 6,\n            \"nodeType\": \"Block\",\n            \"src\": \"57:95:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"72:76:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"72:76:1\",\n                  \"statements\": [\n                    {\n                      \"body\": {\n                        \"nativeSrc\": \"94:35:1\",\n                        \"nodeType\": \"YulBlock\",\n                        \"src\": \"94:35:1\",\n                        \"statements\": [\n                          {\n                            \"body\": {\n                              \"nativeSrc\": \"118:3:1\",\n                              \"nodeType\": \"YulBlock\",\n                              \"src\": \"118:3:1\",\n                              \"statements\": []\n                            },\n                            \"name\": \"f2\",\n                            \"nativeSrc\": \"104:17:1\",\n                            \"nodeType\": \"YulFunctionDefinition\",\n                            \"src\": \"104:17:1\"\n                          }\n                        ]\n                      },\n                      \"name\": \"f1\",\n                      \"nativeSrc\": \"80:49:1\",\n                      \"nodeType\": \"YulFunctionDefinition\",\n                      \"src\": \"80:49:1\"\n                    },\n                    {\n                      \"nativeSrc\": \"136:6:1\",\n                      \"nodeType\": \"YulAssignment\",\n                      \"src\": \"136:6:1\",\n                      \"value\": {\n                        \"kind\": \"number\",\n                        \"nativeSrc\": \"141:1:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"141:1:1\",\n                        \"type\": \"\",\n                        \"value\": \"2\"\n                      },\n                      \"variableNames\": [\n                        {\n                          \"name\": \"x\",\n                          \"nativeSrc\": \"136:1:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"136:1:1\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 5,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"63:85:1\"\n              }\n            ]\n          },\n          \"id\": 7,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"24:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"25:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 4,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 3,\n                \"mutability\": \"mutable\",\n                \"name\": \"x\",\n                \"nameLocation\": \"54:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"49:6:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 2,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"49:4:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"48:8:1\"\n          },\n          \"src\": \"15:137:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:154:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:155:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/slot_offset.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      12\n    ]\n  },\n  \"id\": 13,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 12,\n      \"linearizedBaseContracts\": [\n        12\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"canonicalName\": \"C.S\",\n          \"id\": 3,\n          \"members\": [\n            {\n              \"constant\": false,\n              \"id\": 2,\n              \"mutability\": \"mutable\",\n              \"name\": \"x\",\n              \"nameLocation\": \"33:1:1\",\n              \"nodeType\": \"VariableDeclaration\",\n              \"scope\": 3,\n              \"src\": \"28:6:1\",\n              \"stateVariable\": false,\n              \"storageLocation\": \"default\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_uint256\",\n                \"typeString\": \"uint256\"\n              },\n              \"typeName\": {\n                \"id\": 1,\n                \"name\": \"uint\",\n                \"nodeType\": \"ElementaryTypeName\",\n                \"src\": \"28:4:1\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                }\n              },\n              \"visibility\": \"internal\"\n            }\n          ],\n          \"name\": \"S\",\n          \"nameLocation\": \"24:1:1\",\n          \"nodeType\": \"StructDefinition\",\n          \"scope\": 12,\n          \"src\": \"17:20:1\",\n          \"visibility\": \"public\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 6,\n          \"mutability\": \"mutable\",\n          \"name\": \"s\",\n          \"nameLocation\": \"44:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 12,\n          \"src\": \"42:3:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_struct$_S_$3_storage\",\n            \"typeString\": \"struct C.S\"\n          },\n          \"typeName\": {\n            \"id\": 5,\n            \"nodeType\": \"UserDefinedTypeName\",\n            \"pathNode\": {\n              \"id\": 4,\n              \"name\": \"S\",\n              \"nameLocations\": [\n                \"42:1:1\"\n              ],\n              \"nodeType\": \"IdentifierPath\",\n              \"referencedDeclaration\": 3,\n              \"src\": \"42:1:1\"\n            },\n            \"referencedDeclaration\": 3,\n            \"src\": \"42:1:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_struct$_S_$3_storage_ptr\",\n              \"typeString\": \"struct C.S\"\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 10,\n            \"nodeType\": \"Block\",\n            \"src\": \"76:70:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"95:45:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"95:45:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"97:17:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"97:17:1\",\n                      \"value\": {\n                        \"name\": \"s.offset\",\n                        \"nativeSrc\": \"106:8:1\",\n                        \"nodeType\": \"YulIdentifier\",\n                        \"src\": \"106:8:1\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"x\",\n                          \"nativeSrc\": \"101:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"101:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    },\n                    {\n                      \"nativeSrc\": \"115:23:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"115:23:1\",\n                      \"value\": {\n                        \"arguments\": [\n                          {\n                            \"name\": \"s.slot\",\n                            \"nativeSrc\": \"128:6:1\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"128:6:1\"\n                          },\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"136:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"136:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"2\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"mul\",\n                          \"nativeSrc\": \"124:3:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"124:3:1\"\n                        },\n                        \"nativeSrc\": \"124:14:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"124:14:1\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"y\",\n                          \"nativeSrc\": \"119:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"119:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [\n                  {\n                    \"declaration\": 6,\n                    \"isOffset\": true,\n                    \"isSlot\": false,\n                    \"src\": \"106:8:1\",\n                    \"suffix\": \"offset\",\n                    \"valueSize\": 1\n                  },\n                  {\n                    \"declaration\": 6,\n                    \"isOffset\": false,\n                    \"isSlot\": true,\n                    \"src\": \"128:6:1\",\n                    \"suffix\": \"slot\",\n                    \"valueSize\": 1\n                  }\n                ],\n                \"id\": 9,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"86:54:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"ffae15ba\",\n          \"id\": 11,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"e\",\n          \"nameLocation\": \"60:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"61:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 8,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"76:0:1\"\n          },\n          \"scope\": 12,\n          \"src\": \"51:95:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 13,\n      \"src\": \"0:148:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:149:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/slot_offset.sol",
    "content": "contract C {\n    struct S { uint x; }\n    S s;\n    function e() pure public {\n        assembly { let x := s.offset let y := mul(s.slot, 2) }\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/slot_offset_legacy.json",
    "content": "{\n  \"attributes\":\n  {\n    \"absolutePath\": \"a\",\n    \"exportedSymbols\":\n    {\n      \"C\":\n      [\n        12\n      ]\n    }\n  },\n  \"children\":\n  [\n    {\n      \"attributes\":\n      {\n        \"abstract\": false,\n        \"baseContracts\":\n        [\n          null\n        ],\n        \"contractDependencies\":\n        [\n          null\n        ],\n        \"contractKind\": \"contract\",\n        \"fullyImplemented\": true,\n        \"linearizedBaseContracts\":\n        [\n          12\n        ],\n        \"name\": \"C\",\n        \"scope\": 13\n      },\n      \"children\":\n      [\n        {\n          \"attributes\":\n          {\n            \"canonicalName\": \"C.S\",\n            \"name\": \"S\",\n            \"scope\": 12,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"constant\": false,\n                \"mutability\": \"mutable\",\n                \"name\": \"x\",\n                \"scope\": 3,\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"type\": \"uint256\",\n                \"visibility\": \"internal\"\n              },\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"name\": \"uint\",\n                    \"type\": \"uint256\"\n                  },\n                  \"id\": 1,\n                  \"name\": \"ElementaryTypeName\",\n                  \"src\": \"28:4:1\"\n                }\n              ],\n              \"id\": 2,\n              \"name\": \"VariableDeclaration\",\n              \"src\": \"28:6:1\"\n            }\n          ],\n          \"id\": 3,\n          \"name\": \"StructDefinition\",\n          \"src\": \"17:20:1\"\n        },\n        {\n          \"attributes\":\n          {\n            \"constant\": false,\n            \"mutability\": \"mutable\",\n            \"name\": \"s\",\n            \"scope\": 12,\n            \"stateVariable\": true,\n            \"storageLocation\": \"default\",\n            \"type\": \"struct C.S\",\n            \"visibility\": \"internal\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"referencedDeclaration\": 3,\n                \"type\": \"struct C.S\"\n              },\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"name\": \"S\",\n                    \"referencedDeclaration\": 3\n                  },\n                  \"id\": 4,\n                  \"name\": \"IdentifierPath\",\n                  \"src\": \"42:1:1\"\n                }\n              ],\n              \"id\": 5,\n              \"name\": \"UserDefinedTypeName\",\n              \"src\": \"42:1:1\"\n            }\n          ],\n          \"id\": 6,\n          \"name\": \"VariableDeclaration\",\n          \"src\": \"42:3:1\"\n        },\n        {\n          \"attributes\":\n          {\n            \"functionSelector\": \"ffae15ba\",\n            \"implemented\": true,\n            \"isConstructor\": false,\n            \"kind\": \"function\",\n            \"modifiers\":\n            [\n              null\n            ],\n            \"name\": \"e\",\n            \"scope\": 12,\n            \"stateMutability\": \"pure\",\n            \"virtual\": false,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 7,\n              \"name\": \"ParameterList\",\n              \"src\": \"61:2:1\"\n            },\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 8,\n              \"name\": \"ParameterList\",\n              \"src\": \"76:0:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"evmVersion\": %EVMVERSION%,\n                    \"externalReferences\":\n                    [\n                      {\n                        \"declaration\": 6,\n                        \"isOffset\": true,\n                        \"isSlot\": false,\n                        \"src\": \"106:8:1\",\n                        \"suffix\": \"offset\",\n                        \"valueSize\": 1\n                      },\n                      {\n                        \"declaration\": 6,\n                        \"isOffset\": false,\n                        \"isSlot\": true,\n                        \"src\": \"128:6:1\",\n                        \"suffix\": \"slot\",\n                        \"valueSize\": 1\n                      }\n                    ],\n                    \"operations\": \"{\\n    let x := s.offset\\n    let y := mul(s.slot, 2)\\n}\"\n                  },\n                  \"children\": [],\n                  \"id\": 9,\n                  \"name\": \"InlineAssembly\",\n                  \"src\": \"86:54:1\"\n                }\n              ],\n              \"id\": 10,\n              \"name\": \"Block\",\n              \"src\": \"76:70:1\"\n            }\n          ],\n          \"id\": 11,\n          \"name\": \"FunctionDefinition\",\n          \"src\": \"51:95:1\"\n        }\n      ],\n      \"id\": 12,\n      \"name\": \"ContractDefinition\",\n      \"src\": \"0:148:1\"\n    }\n  ],\n  \"id\": 13,\n  \"name\": \"SourceUnit\",\n  \"src\": \"0:149:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/slot_offset_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 13,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 12,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"id\": 3,\n          \"members\": [\n            {\n              \"constant\": false,\n              \"id\": 2,\n              \"mutability\": \"mutable\",\n              \"name\": \"x\",\n              \"nameLocation\": \"33:1:1\",\n              \"nodeType\": \"VariableDeclaration\",\n              \"src\": \"28:6:1\",\n              \"stateVariable\": false,\n              \"storageLocation\": \"default\",\n              \"typeDescriptions\": {},\n              \"typeName\": {\n                \"id\": 1,\n                \"name\": \"uint\",\n                \"nodeType\": \"ElementaryTypeName\",\n                \"src\": \"28:4:1\",\n                \"typeDescriptions\": {}\n              },\n              \"visibility\": \"internal\"\n            }\n          ],\n          \"name\": \"S\",\n          \"nameLocation\": \"24:1:1\",\n          \"nodeType\": \"StructDefinition\",\n          \"src\": \"17:20:1\",\n          \"visibility\": \"public\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 6,\n          \"mutability\": \"mutable\",\n          \"name\": \"s\",\n          \"nameLocation\": \"44:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"42:3:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 5,\n            \"nodeType\": \"UserDefinedTypeName\",\n            \"pathNode\": {\n              \"id\": 4,\n              \"name\": \"S\",\n              \"nameLocations\": [\n                \"42:1:1\"\n              ],\n              \"nodeType\": \"IdentifierPath\",\n              \"src\": \"42:1:1\"\n            },\n            \"src\": \"42:1:1\",\n            \"typeDescriptions\": {}\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 10,\n            \"nodeType\": \"Block\",\n            \"src\": \"76:70:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"95:45:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"95:45:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"97:17:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"97:17:1\",\n                      \"value\": {\n                        \"name\": \"s.offset\",\n                        \"nativeSrc\": \"106:8:1\",\n                        \"nodeType\": \"YulIdentifier\",\n                        \"src\": \"106:8:1\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"x\",\n                          \"nativeSrc\": \"101:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"101:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    },\n                    {\n                      \"nativeSrc\": \"115:23:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"115:23:1\",\n                      \"value\": {\n                        \"arguments\": [\n                          {\n                            \"name\": \"s.slot\",\n                            \"nativeSrc\": \"128:6:1\",\n                            \"nodeType\": \"YulIdentifier\",\n                            \"src\": \"128:6:1\"\n                          },\n                          {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"136:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"136:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"2\"\n                          }\n                        ],\n                        \"functionName\": {\n                          \"name\": \"mul\",\n                          \"nativeSrc\": \"124:3:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"124:3:1\"\n                        },\n                        \"nativeSrc\": \"124:14:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"124:14:1\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"y\",\n                          \"nativeSrc\": \"119:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"119:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 9,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"86:54:1\"\n              }\n            ]\n          },\n          \"id\": 11,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"e\",\n          \"nameLocation\": \"60:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"61:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 8,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"76:0:1\"\n          },\n          \"src\": \"51:95:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:148:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:149:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/stringlit.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      6\n    ]\n  },\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 6,\n      \"linearizedBaseContracts\": [\n        6\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"37:43:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"56:18:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"56:18:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"58:14:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"58:14:1\",\n                      \"value\": {\n                        \"hexValue\": \"616263\",\n                        \"kind\": \"string\",\n                        \"nativeSrc\": \"67:5:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"67:5:1\",\n                        \"type\": \"\",\n                        \"value\": \"abc\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"x\",\n                          \"nativeSrc\": \"62:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"62:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"47:27:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"5a2ee019\",\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"m\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"37:0:1\"\n          },\n          \"scope\": 6,\n          \"src\": \"17:63:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 7,\n      \"src\": \"0:82:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:83:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/stringlit.sol",
    "content": "contract C {\n    function m() public {\n        assembly { let x := \"abc\" }\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/stringlit_legacy.json",
    "content": "{\n  \"attributes\":\n  {\n    \"absolutePath\": \"a\",\n    \"exportedSymbols\":\n    {\n      \"C\":\n      [\n        6\n      ]\n    }\n  },\n  \"children\":\n  [\n    {\n      \"attributes\":\n      {\n        \"abstract\": false,\n        \"baseContracts\":\n        [\n          null\n        ],\n        \"contractDependencies\":\n        [\n          null\n        ],\n        \"contractKind\": \"contract\",\n        \"fullyImplemented\": true,\n        \"linearizedBaseContracts\":\n        [\n          6\n        ],\n        \"name\": \"C\",\n        \"scope\": 7\n      },\n      \"children\":\n      [\n        {\n          \"attributes\":\n          {\n            \"functionSelector\": \"5a2ee019\",\n            \"implemented\": true,\n            \"isConstructor\": false,\n            \"kind\": \"function\",\n            \"modifiers\":\n            [\n              null\n            ],\n            \"name\": \"m\",\n            \"scope\": 6,\n            \"stateMutability\": \"nonpayable\",\n            \"virtual\": false,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 1,\n              \"name\": \"ParameterList\",\n              \"src\": \"27:2:1\"\n            },\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 2,\n              \"name\": \"ParameterList\",\n              \"src\": \"37:0:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"evmVersion\": %EVMVERSION%,\n                    \"externalReferences\":\n                    [\n                      null\n                    ],\n                    \"operations\": \"{ let x := \\\"abc\\\" }\"\n                  },\n                  \"children\": [],\n                  \"id\": 3,\n                  \"name\": \"InlineAssembly\",\n                  \"src\": \"47:27:1\"\n                }\n              ],\n              \"id\": 4,\n              \"name\": \"Block\",\n              \"src\": \"37:43:1\"\n            }\n          ],\n          \"id\": 5,\n          \"name\": \"FunctionDefinition\",\n          \"src\": \"17:63:1\"\n        }\n      ],\n      \"id\": 6,\n      \"name\": \"ContractDefinition\",\n      \"src\": \"0:82:1\"\n    }\n  ],\n  \"id\": 7,\n  \"name\": \"SourceUnit\",\n  \"src\": \"0:83:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/stringlit_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 6,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"37:43:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"56:18:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"56:18:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"58:14:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"58:14:1\",\n                      \"value\": {\n                        \"hexValue\": \"616263\",\n                        \"kind\": \"string\",\n                        \"nativeSrc\": \"67:5:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"67:5:1\",\n                        \"type\": \"\",\n                        \"value\": \"abc\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"x\",\n                          \"nativeSrc\": \"62:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"62:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"47:27:1\"\n              }\n            ]\n          },\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"m\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"37:0:1\"\n          },\n          \"src\": \"17:63:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:82:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:83:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/switch.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      6\n    ]\n  },\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 6,\n      \"linearizedBaseContracts\": [\n        6\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:154:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"61:129:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"61:129:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"75:10:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"75:10:1\",\n                      \"value\": {\n                        \"kind\": \"number\",\n                        \"nativeSrc\": \"84:1:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"84:1:1\",\n                        \"type\": \"\",\n                        \"value\": \"0\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"v\",\n                          \"nativeSrc\": \"79:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"79:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    },\n                    {\n                      \"cases\": [\n                        {\n                          \"body\": {\n                            \"nativeSrc\": \"139:10:1\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"139:10:1\",\n                            \"statements\": [\n                              {\n                                \"nativeSrc\": \"141:6:1\",\n                                \"nodeType\": \"YulAssignment\",\n                                \"src\": \"141:6:1\",\n                                \"value\": {\n                                  \"kind\": \"number\",\n                                  \"nativeSrc\": \"146:1:1\",\n                                  \"nodeType\": \"YulLiteral\",\n                                  \"src\": \"146:1:1\",\n                                  \"type\": \"\",\n                                  \"value\": \"1\"\n                                },\n                                \"variableNames\": [\n                                  {\n                                    \"name\": \"v\",\n                                    \"nativeSrc\": \"141:1:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"141:1:1\"\n                                  }\n                                ]\n                              }\n                            ]\n                          },\n                          \"nativeSrc\": \"132:17:1\",\n                          \"nodeType\": \"YulCase\",\n                          \"src\": \"132:17:1\",\n                          \"value\": {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"137:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"137:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          }\n                        },\n                        {\n                          \"body\": {\n                            \"nativeSrc\": \"170:10:1\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"170:10:1\",\n                            \"statements\": [\n                              {\n                                \"nativeSrc\": \"172:6:1\",\n                                \"nodeType\": \"YulAssignment\",\n                                \"src\": \"172:6:1\",\n                                \"value\": {\n                                  \"kind\": \"number\",\n                                  \"nativeSrc\": \"177:1:1\",\n                                  \"nodeType\": \"YulLiteral\",\n                                  \"src\": \"177:1:1\",\n                                  \"type\": \"\",\n                                  \"value\": \"2\"\n                                },\n                                \"variableNames\": [\n                                  {\n                                    \"name\": \"v\",\n                                    \"nativeSrc\": \"172:1:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"172:1:1\"\n                                  }\n                                ]\n                              }\n                            ]\n                          },\n                          \"nativeSrc\": \"162:18:1\",\n                          \"nodeType\": \"YulCase\",\n                          \"src\": \"162:18:1\",\n                          \"value\": \"default\"\n                        }\n                      ],\n                      \"expression\": {\n                        \"arguments\": [],\n                        \"functionName\": {\n                          \"name\": \"calldatasize\",\n                          \"nativeSrc\": \"105:12:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"105:12:1\"\n                        },\n                        \"nativeSrc\": \"105:14:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"105:14:1\"\n                      },\n                      \"nativeSrc\": \"98:82:1\",\n                      \"nodeType\": \"YulSwitch\",\n                      \"src\": \"98:82:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"52:138:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"scope\": 6,\n          \"src\": \"17:179:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 7,\n      \"src\": \"0:198:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:199:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/switch.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            let v := 0\n            switch calldatasize()\n            case 0 { v := 1 }\n            default { v := 2 }\n        }\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/switch_default.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      6\n    ]\n  },\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 6,\n      \"linearizedBaseContracts\": [\n        6\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:58:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"61:33:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"61:33:1\",\n                  \"statements\": [\n                    {\n                      \"cases\": [\n                        {\n                          \"body\": {\n                            \"nativeSrc\": \"79:2:1\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"79:2:1\",\n                            \"statements\": []\n                          },\n                          \"nativeSrc\": \"72:9:1\",\n                          \"nodeType\": \"YulCase\",\n                          \"src\": \"72:9:1\",\n                          \"value\": {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"77:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"77:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          }\n                        },\n                        {\n                          \"body\": {\n                            \"nativeSrc\": \"90:2:1\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"90:2:1\",\n                            \"statements\": []\n                          },\n                          \"nativeSrc\": \"82:10:1\",\n                          \"nodeType\": \"YulCase\",\n                          \"src\": \"82:10:1\",\n                          \"value\": \"default\"\n                        }\n                      ],\n                      \"expression\": {\n                        \"kind\": \"number\",\n                        \"nativeSrc\": \"70:1:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"70:1:1\",\n                        \"type\": \"\",\n                        \"value\": \"0\"\n                      },\n                      \"nativeSrc\": \"63:29:1\",\n                      \"nodeType\": \"YulSwitch\",\n                      \"src\": \"63:29:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"52:42:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"e2179b8e\",\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"g\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"scope\": 6,\n          \"src\": \"17:83:1\",\n          \"stateMutability\": \"view\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 7,\n      \"src\": \"0:102:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:103:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/switch_default.sol",
    "content": "contract C {\n    function g() view public {\n        assembly { switch 0 case 0 {} default {} }\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/switch_default_legacy.json",
    "content": "{\n  \"attributes\":\n  {\n    \"absolutePath\": \"a\",\n    \"exportedSymbols\":\n    {\n      \"C\":\n      [\n        6\n      ]\n    }\n  },\n  \"children\":\n  [\n    {\n      \"attributes\":\n      {\n        \"abstract\": false,\n        \"baseContracts\":\n        [\n          null\n        ],\n        \"contractDependencies\":\n        [\n          null\n        ],\n        \"contractKind\": \"contract\",\n        \"fullyImplemented\": true,\n        \"linearizedBaseContracts\":\n        [\n          6\n        ],\n        \"name\": \"C\",\n        \"scope\": 7\n      },\n      \"children\":\n      [\n        {\n          \"attributes\":\n          {\n            \"functionSelector\": \"e2179b8e\",\n            \"implemented\": true,\n            \"isConstructor\": false,\n            \"kind\": \"function\",\n            \"modifiers\":\n            [\n              null\n            ],\n            \"name\": \"g\",\n            \"scope\": 6,\n            \"stateMutability\": \"view\",\n            \"virtual\": false,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 1,\n              \"name\": \"ParameterList\",\n              \"src\": \"27:2:1\"\n            },\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 2,\n              \"name\": \"ParameterList\",\n              \"src\": \"42:0:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"evmVersion\": %EVMVERSION%,\n                    \"externalReferences\":\n                    [\n                      null\n                    ],\n                    \"operations\": \"{\\n    switch 0\\n    case 0 { }\\n    default { }\\n}\"\n                  },\n                  \"children\": [],\n                  \"id\": 3,\n                  \"name\": \"InlineAssembly\",\n                  \"src\": \"52:42:1\"\n                }\n              ],\n              \"id\": 4,\n              \"name\": \"Block\",\n              \"src\": \"42:58:1\"\n            }\n          ],\n          \"id\": 5,\n          \"name\": \"FunctionDefinition\",\n          \"src\": \"17:83:1\"\n        }\n      ],\n      \"id\": 6,\n      \"name\": \"ContractDefinition\",\n      \"src\": \"0:102:1\"\n    }\n  ],\n  \"id\": 7,\n  \"name\": \"SourceUnit\",\n  \"src\": \"0:103:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/switch_default_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 6,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:58:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"61:33:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"61:33:1\",\n                  \"statements\": [\n                    {\n                      \"cases\": [\n                        {\n                          \"body\": {\n                            \"nativeSrc\": \"79:2:1\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"79:2:1\",\n                            \"statements\": []\n                          },\n                          \"nativeSrc\": \"72:9:1\",\n                          \"nodeType\": \"YulCase\",\n                          \"src\": \"72:9:1\",\n                          \"value\": {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"77:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"77:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          }\n                        },\n                        {\n                          \"body\": {\n                            \"nativeSrc\": \"90:2:1\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"90:2:1\",\n                            \"statements\": []\n                          },\n                          \"nativeSrc\": \"82:10:1\",\n                          \"nodeType\": \"YulCase\",\n                          \"src\": \"82:10:1\",\n                          \"value\": \"default\"\n                        }\n                      ],\n                      \"expression\": {\n                        \"kind\": \"number\",\n                        \"nativeSrc\": \"70:1:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"70:1:1\",\n                        \"type\": \"\",\n                        \"value\": \"0\"\n                      },\n                      \"nativeSrc\": \"63:29:1\",\n                      \"nodeType\": \"YulSwitch\",\n                      \"src\": \"63:29:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"52:42:1\"\n              }\n            ]\n          },\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"g\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"src\": \"17:83:1\",\n          \"stateMutability\": \"view\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:102:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:103:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/switch_legacy.json",
    "content": "{\n  \"attributes\":\n  {\n    \"absolutePath\": \"a\",\n    \"exportedSymbols\":\n    {\n      \"C\":\n      [\n        6\n      ]\n    }\n  },\n  \"children\":\n  [\n    {\n      \"attributes\":\n      {\n        \"abstract\": false,\n        \"baseContracts\":\n        [\n          null\n        ],\n        \"contractDependencies\":\n        [\n          null\n        ],\n        \"contractKind\": \"contract\",\n        \"linearizedBaseContracts\":\n        [\n          6\n        ],\n        \"name\": \"C\",\n        \"scope\": 7\n      },\n      \"children\":\n      [\n        {\n          \"attributes\":\n          {\n            \"implemented\": true,\n            \"isConstructor\": false,\n            \"kind\": \"function\",\n            \"modifiers\":\n            [\n              null\n            ],\n            \"name\": \"f\",\n            \"scope\": 6,\n            \"stateMutability\": \"pure\",\n            \"virtual\": false,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 1,\n              \"name\": \"ParameterList\",\n              \"src\": \"27:2:1\"\n            },\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 2,\n              \"name\": \"ParameterList\",\n              \"src\": \"42:0:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"evmVersion\": %EVMVERSION%,\n                    \"externalReferences\":\n                    [\n                      {\n                        \"declaration\": 5,\n                        \"isOffset\": false,\n                        \"isSlot\": false,\n                        \"src\": \"141:1:1\",\n                        \"valueSize\": 18446744073709551615\n                      },\n                      {\n                        \"declaration\": 5,\n                        \"isOffset\": false,\n                        \"isSlot\": false,\n                        \"src\": \"172:1:1\",\n                        \"valueSize\": 18446744073709551615\n                      }\n                    ],\n                    \"operations\": \"{\\n    let f := 0\\n    switch calldatasize()\\n    case 0 { f := 1 }\\n    default { f := 2 }\\n}\"\n                  },\n                  \"children\": [],\n                  \"id\": 3,\n                  \"name\": \"InlineAssembly\",\n                  \"src\": \"52:138:1\"\n                }\n              ],\n              \"id\": 4,\n              \"name\": \"Block\",\n              \"src\": \"42:154:1\"\n            }\n          ],\n          \"id\": 5,\n          \"name\": \"FunctionDefinition\",\n          \"src\": \"17:179:1\"\n        }\n      ],\n      \"id\": 6,\n      \"name\": \"ContractDefinition\",\n      \"src\": \"0:198:1\"\n    }\n  ],\n  \"id\": 7,\n  \"name\": \"SourceUnit\",\n  \"src\": \"0:199:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/switch_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 6,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:154:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"61:129:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"61:129:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"75:10:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"75:10:1\",\n                      \"value\": {\n                        \"kind\": \"number\",\n                        \"nativeSrc\": \"84:1:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"84:1:1\",\n                        \"type\": \"\",\n                        \"value\": \"0\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"v\",\n                          \"nativeSrc\": \"79:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"79:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    },\n                    {\n                      \"cases\": [\n                        {\n                          \"body\": {\n                            \"nativeSrc\": \"139:10:1\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"139:10:1\",\n                            \"statements\": [\n                              {\n                                \"nativeSrc\": \"141:6:1\",\n                                \"nodeType\": \"YulAssignment\",\n                                \"src\": \"141:6:1\",\n                                \"value\": {\n                                  \"kind\": \"number\",\n                                  \"nativeSrc\": \"146:1:1\",\n                                  \"nodeType\": \"YulLiteral\",\n                                  \"src\": \"146:1:1\",\n                                  \"type\": \"\",\n                                  \"value\": \"1\"\n                                },\n                                \"variableNames\": [\n                                  {\n                                    \"name\": \"v\",\n                                    \"nativeSrc\": \"141:1:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"141:1:1\"\n                                  }\n                                ]\n                              }\n                            ]\n                          },\n                          \"nativeSrc\": \"132:17:1\",\n                          \"nodeType\": \"YulCase\",\n                          \"src\": \"132:17:1\",\n                          \"value\": {\n                            \"kind\": \"number\",\n                            \"nativeSrc\": \"137:1:1\",\n                            \"nodeType\": \"YulLiteral\",\n                            \"src\": \"137:1:1\",\n                            \"type\": \"\",\n                            \"value\": \"0\"\n                          }\n                        },\n                        {\n                          \"body\": {\n                            \"nativeSrc\": \"170:10:1\",\n                            \"nodeType\": \"YulBlock\",\n                            \"src\": \"170:10:1\",\n                            \"statements\": [\n                              {\n                                \"nativeSrc\": \"172:6:1\",\n                                \"nodeType\": \"YulAssignment\",\n                                \"src\": \"172:6:1\",\n                                \"value\": {\n                                  \"kind\": \"number\",\n                                  \"nativeSrc\": \"177:1:1\",\n                                  \"nodeType\": \"YulLiteral\",\n                                  \"src\": \"177:1:1\",\n                                  \"type\": \"\",\n                                  \"value\": \"2\"\n                                },\n                                \"variableNames\": [\n                                  {\n                                    \"name\": \"v\",\n                                    \"nativeSrc\": \"172:1:1\",\n                                    \"nodeType\": \"YulIdentifier\",\n                                    \"src\": \"172:1:1\"\n                                  }\n                                ]\n                              }\n                            ]\n                          },\n                          \"nativeSrc\": \"162:18:1\",\n                          \"nodeType\": \"YulCase\",\n                          \"src\": \"162:18:1\",\n                          \"value\": \"default\"\n                        }\n                      ],\n                      \"expression\": {\n                        \"arguments\": [],\n                        \"functionName\": {\n                          \"name\": \"calldatasize\",\n                          \"nativeSrc\": \"105:12:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"105:12:1\"\n                        },\n                        \"nativeSrc\": \"105:14:1\",\n                        \"nodeType\": \"YulFunctionCall\",\n                        \"src\": \"105:14:1\"\n                      },\n                      \"nativeSrc\": \"98:82:1\",\n                      \"nodeType\": \"YulSwitch\",\n                      \"src\": \"98:82:1\"\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"52:138:1\"\n              }\n            ]\n          },\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"src\": \"17:179:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:198:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:199:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/var_access.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      9\n    ]\n  },\n  \"id\": 10,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 9,\n      \"linearizedBaseContracts\": [\n        9\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 7,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:51:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"57:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 7,\n                    \"src\": \"52:6:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_uint256\",\n                      \"typeString\": \"uint256\"\n                    },\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"uint\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"52:4:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_uint256\",\n                        \"typeString\": \"uint256\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 5,\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"52:6:1\"\n              },\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"77:10:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"77:10:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"79:6:1\",\n                      \"nodeType\": \"YulAssignment\",\n                      \"src\": \"79:6:1\",\n                      \"value\": {\n                        \"kind\": \"number\",\n                        \"nativeSrc\": \"84:1:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"84:1:1\",\n                        \"type\": \"\",\n                        \"value\": \"7\"\n                      },\n                      \"variableNames\": [\n                        {\n                          \"name\": \"x\",\n                          \"nativeSrc\": \"79:1:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"79:1:1\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [\n                  {\n                    \"declaration\": 4,\n                    \"isOffset\": false,\n                    \"isSlot\": false,\n                    \"src\": \"79:1:1\",\n                    \"valueSize\": 1\n                  }\n                ],\n                \"id\": 6,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"68:19:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 8,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"scope\": 9,\n          \"src\": \"17:76:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 10,\n      \"src\": \"0:95:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:96:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/var_access.sol",
    "content": "contract C {\n    function f() pure public {\n        uint x;\n        assembly { x := 7 }\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/var_access_legacy.json",
    "content": "{\n  \"attributes\":\n  {\n    \"absolutePath\": \"a\",\n    \"exportedSymbols\":\n    {\n      \"C\":\n      [\n        9\n      ]\n    }\n  },\n  \"children\":\n  [\n    {\n      \"attributes\":\n      {\n        \"abstract\": false,\n        \"baseContracts\":\n        [\n          null\n        ],\n        \"contractDependencies\":\n        [\n          null\n        ],\n        \"contractKind\": \"contract\",\n        \"fullyImplemented\": true,\n        \"linearizedBaseContracts\":\n        [\n          9\n        ],\n        \"name\": \"C\",\n        \"scope\": 10\n      },\n      \"children\":\n      [\n        {\n          \"attributes\":\n          {\n            \"functionSelector\": \"26121ff0\",\n            \"implemented\": true,\n            \"isConstructor\": false,\n            \"kind\": \"function\",\n            \"modifiers\":\n            [\n              null\n            ],\n            \"name\": \"f\",\n            \"scope\": 9,\n            \"stateMutability\": \"pure\",\n            \"virtual\": false,\n            \"visibility\": \"public\"\n          },\n          \"children\":\n          [\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 1,\n              \"name\": \"ParameterList\",\n              \"src\": \"27:2:1\"\n            },\n            {\n              \"attributes\":\n              {\n                \"parameters\":\n                [\n                  null\n                ]\n              },\n              \"children\": [],\n              \"id\": 2,\n              \"name\": \"ParameterList\",\n              \"src\": \"42:0:1\"\n            },\n            {\n              \"children\":\n              [\n                {\n                  \"attributes\":\n                  {\n                    \"assignments\":\n                    [\n                      4\n                    ]\n                  },\n                  \"children\":\n                  [\n                    {\n                      \"attributes\":\n                      {\n                        \"constant\": false,\n                        \"mutability\": \"mutable\",\n                        \"name\": \"x\",\n                        \"scope\": 7,\n                        \"stateVariable\": false,\n                        \"storageLocation\": \"default\",\n                        \"type\": \"uint256\",\n                        \"visibility\": \"internal\"\n                      },\n                      \"children\":\n                      [\n                        {\n                          \"attributes\":\n                          {\n                            \"name\": \"uint\",\n                            \"type\": \"uint256\"\n                          },\n                          \"id\": 3,\n                          \"name\": \"ElementaryTypeName\",\n                          \"src\": \"52:4:1\"\n                        }\n                      ],\n                      \"id\": 4,\n                      \"name\": \"VariableDeclaration\",\n                      \"src\": \"52:6:1\"\n                    }\n                  ],\n                  \"id\": 5,\n                  \"name\": \"VariableDeclarationStatement\",\n                  \"src\": \"52:6:1\"\n                },\n                {\n                  \"attributes\":\n                  {\n                    \"evmVersion\": %EVMVERSION%,\n                    \"externalReferences\":\n                    [\n                      {\n                        \"declaration\": 4,\n                        \"isOffset\": false,\n                        \"isSlot\": false,\n                        \"src\": \"79:1:1\",\n                        \"valueSize\": 1\n                      }\n                    ],\n                    \"operations\": \"{ x := 7 }\"\n                  },\n                  \"children\": [],\n                  \"id\": 6,\n                  \"name\": \"InlineAssembly\",\n                  \"src\": \"68:19:1\"\n                }\n              ],\n              \"id\": 7,\n              \"name\": \"Block\",\n              \"src\": \"42:51:1\"\n            }\n          ],\n          \"id\": 8,\n          \"name\": \"FunctionDefinition\",\n          \"src\": \"17:76:1\"\n        }\n      ],\n      \"id\": 9,\n      \"name\": \"ContractDefinition\",\n      \"src\": \"0:95:1\"\n    }\n  ],\n  \"id\": 10,\n  \"name\": \"SourceUnit\",\n  \"src\": \"0:96:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/assembly/var_access_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 10,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 9,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 7,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:51:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"57:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"52:6:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"uint\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"52:4:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 5,\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"52:6:1\"\n              },\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"77:10:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"77:10:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"79:6:1\",\n                      \"nodeType\": \"YulAssignment\",\n                      \"src\": \"79:6:1\",\n                      \"value\": {\n                        \"kind\": \"number\",\n                        \"nativeSrc\": \"84:1:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"84:1:1\",\n                        \"type\": \"\",\n                        \"value\": \"7\"\n                      },\n                      \"variableNames\": [\n                        {\n                          \"name\": \"x\",\n                          \"nativeSrc\": \"79:1:1\",\n                          \"nodeType\": \"YulIdentifier\",\n                          \"src\": \"79:1:1\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 6,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"68:19:1\"\n              }\n            ]\n          },\n          \"id\": 8,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"src\": \"17:76:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:95:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:96:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.json",
    "content": "[\n{\n  \"absolutePath\": \"L\",\n  \"exportedSymbols\": {\n    \"L\": [\n      78\n    ],\n    \"free1\": [\n      65\n    ],\n    \"free2\": [\n      69\n    ]\n  },\n  \"id\": 79,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"body\": {\n        \"id\": 64,\n        \"nodeType\": \"Block\",\n        \"src\": \"17:2:1\",\n        \"statements\": []\n      },\n      \"id\": 65,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"free1\",\n      \"nameLocation\": \"9:5:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 62,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"14:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 63,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"17:0:1\"\n      },\n      \"scope\": 79,\n      \"src\": \"0:19:1\",\n      \"stateMutability\": \"nonpayable\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"body\": {\n        \"id\": 68,\n        \"nodeType\": \"Block\",\n        \"src\": \"37:2:1\",\n        \"statements\": []\n      },\n      \"id\": 69,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"free2\",\n      \"nameLocation\": \"29:5:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 66,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"34:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 67,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"37:0:1\"\n      },\n      \"scope\": 79,\n      \"src\": \"20:19:1\",\n      \"stateMutability\": \"nonpayable\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"L\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"library\",\n      \"fullyImplemented\": true,\n      \"id\": 78,\n      \"linearizedBaseContracts\": [\n        78\n      ],\n      \"name\": \"L\",\n      \"nameLocation\": \"48:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 72,\n            \"nodeType\": \"Block\",\n            \"src\": \"78:2:1\",\n            \"statements\": []\n          },\n          \"id\": 73,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"g\",\n          \"nameLocation\": \"65:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 70,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"66:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 71,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"78:0:1\"\n          },\n          \"scope\": 78,\n          \"src\": \"56:24:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 76,\n            \"nodeType\": \"Block\",\n            \"src\": \"107:2:1\",\n            \"statements\": []\n          },\n          \"id\": 77,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"h\",\n          \"nameLocation\": \"94:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 74,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"95:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 75,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"107:0:1\"\n          },\n          \"scope\": 78,\n          \"src\": \"85:24:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"scope\": 79,\n      \"src\": \"40:71:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:112:1\"\n},\n{\n  \"absolutePath\": \"A\",\n  \"exportedSymbols\": {\n    \"A\": [\n      22\n    ],\n    \"B\": [\n      37\n    ],\n    \"L\": [\n      78\n    ],\n    \"free1\": [\n      65\n    ],\n    \"free2\": [\n      69\n    ]\n  },\n  \"id\": 38,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"absolutePath\": \"L\",\n      \"file\": \"L\",\n      \"id\": 1,\n      \"nameLocation\": \"-1:-1:-1\",\n      \"nodeType\": \"ImportDirective\",\n      \"scope\": 38,\n      \"sourceUnit\": 79,\n      \"src\": \"0:11:2\",\n      \"symbolAliases\": [],\n      \"unitAlias\": \"\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"A\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 22,\n      \"internalFunctionIDs\": {\n        \"69\": 1,\n        \"73\": 2,\n        \"77\": 3\n      },\n      \"linearizedBaseContracts\": [\n        22\n      ],\n      \"name\": \"A\",\n      \"nameLocation\": \"21:1:2\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 20,\n            \"nodeType\": \"Block\",\n            \"src\": \"49:60:2\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"expression\": {\n                          \"id\": 4,\n                          \"name\": \"L\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"referencedDeclaration\": 78,\n                          \"src\": \"60:1:2\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_type$_t_contract$_L_$78_$\",\n                            \"typeString\": \"type(library L)\"\n                          }\n                        },\n                        \"id\": 6,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": false,\n                        \"lValueRequested\": false,\n                        \"memberLocation\": \"62:1:2\",\n                        \"memberName\": \"g\",\n                        \"nodeType\": \"MemberAccess\",\n                        \"referencedDeclaration\": 73,\n                        \"src\": \"60:3:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 7,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"59:5:2\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 8,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"59:7:2\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 9,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"59:7:2\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"id\": 10,\n                        \"name\": \"free2\",\n                        \"nodeType\": \"Identifier\",\n                        \"overloadedDeclarations\": [],\n                        \"referencedDeclaration\": 69,\n                        \"src\": \"77:5:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 11,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"76:7:2\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 12,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"76:9:2\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 13,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"76:9:2\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"expression\": {\n                          \"id\": 14,\n                          \"name\": \"L\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"referencedDeclaration\": 78,\n                          \"src\": \"96:1:2\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_type$_t_contract$_L_$78_$\",\n                            \"typeString\": \"type(library L)\"\n                          }\n                        },\n                        \"id\": 16,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": false,\n                        \"lValueRequested\": false,\n                        \"memberLocation\": \"98:1:2\",\n                        \"memberName\": \"h\",\n                        \"nodeType\": \"MemberAccess\",\n                        \"referencedDeclaration\": 77,\n                        \"src\": \"96:3:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 17,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"95:5:2\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 18,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"95:7:2\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 19,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"95:7:2\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 21,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"38:1:2\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"39:2:2\"\n          },\n          \"returnParameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"49:0:2\"\n          },\n          \"scope\": 22,\n          \"src\": \"29:80:2\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 38,\n      \"src\": \"12:99:2\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"B\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 37,\n      \"internalFunctionIDs\": {\n        \"69\": 1,\n        \"77\": 2\n      },\n      \"linearizedBaseContracts\": [\n        37\n      ],\n      \"name\": \"B\",\n      \"nameLocation\": \"121:1:2\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 35,\n            \"nodeType\": \"Block\",\n            \"src\": \"149:43:2\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"expression\": {\n                          \"id\": 25,\n                          \"name\": \"L\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"referencedDeclaration\": 78,\n                          \"src\": \"160:1:2\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_type$_t_contract$_L_$78_$\",\n                            \"typeString\": \"type(library L)\"\n                          }\n                        },\n                        \"id\": 27,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": false,\n                        \"lValueRequested\": false,\n                        \"memberLocation\": \"162:1:2\",\n                        \"memberName\": \"h\",\n                        \"nodeType\": \"MemberAccess\",\n                        \"referencedDeclaration\": 77,\n                        \"src\": \"160:3:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 28,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"159:5:2\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 29,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"159:7:2\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 30,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"159:7:2\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"id\": 31,\n                        \"name\": \"free2\",\n                        \"nodeType\": \"Identifier\",\n                        \"overloadedDeclarations\": [],\n                        \"referencedDeclaration\": 69,\n                        \"src\": \"177:5:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 32,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"176:7:2\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 33,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"176:9:2\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 34,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"176:9:2\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 36,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"138:1:2\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 23,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"139:2:2\"\n          },\n          \"returnParameters\": {\n            \"id\": 24,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"149:0:2\"\n          },\n          \"scope\": 37,\n          \"src\": \"129:63:2\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 38,\n      \"src\": \"112:82:2\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:195:2\"\n},\n{\n  \"absolutePath\": \"C\",\n  \"exportedSymbols\": {\n    \"C\": [\n      60\n    ],\n    \"L\": [\n      78\n    ],\n    \"free1\": [\n      65\n    ],\n    \"free2\": [\n      69\n    ]\n  },\n  \"id\": 61,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"absolutePath\": \"L\",\n      \"file\": \"L\",\n      \"id\": 39,\n      \"nameLocation\": \"-1:-1:-1\",\n      \"nodeType\": \"ImportDirective\",\n      \"scope\": 61,\n      \"sourceUnit\": 79,\n      \"src\": \"0:11:3\",\n      \"symbolAliases\": [],\n      \"unitAlias\": \"\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 60,\n      \"internalFunctionIDs\": {\n        \"69\": 1,\n        \"73\": 2,\n        \"77\": 3\n      },\n      \"linearizedBaseContracts\": [\n        60\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"21:1:3\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 58,\n            \"nodeType\": \"Block\",\n            \"src\": \"49:60:3\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"expression\": {\n                          \"id\": 42,\n                          \"name\": \"L\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"referencedDeclaration\": 78,\n                          \"src\": \"60:1:3\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_type$_t_contract$_L_$78_$\",\n                            \"typeString\": \"type(library L)\"\n                          }\n                        },\n                        \"id\": 44,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": false,\n                        \"lValueRequested\": false,\n                        \"memberLocation\": \"62:1:3\",\n                        \"memberName\": \"g\",\n                        \"nodeType\": \"MemberAccess\",\n                        \"referencedDeclaration\": 73,\n                        \"src\": \"60:3:3\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 45,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"59:5:3\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 46,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"59:7:3\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 47,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"59:7:3\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"id\": 48,\n                        \"name\": \"free2\",\n                        \"nodeType\": \"Identifier\",\n                        \"overloadedDeclarations\": [],\n                        \"referencedDeclaration\": 69,\n                        \"src\": \"77:5:3\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 49,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"76:7:3\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 50,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"76:9:3\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 51,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"76:9:3\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"expression\": {\n                          \"id\": 52,\n                          \"name\": \"L\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"referencedDeclaration\": 78,\n                          \"src\": \"96:1:3\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_type$_t_contract$_L_$78_$\",\n                            \"typeString\": \"type(library L)\"\n                          }\n                        },\n                        \"id\": 54,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": false,\n                        \"lValueRequested\": false,\n                        \"memberLocation\": \"98:1:3\",\n                        \"memberName\": \"h\",\n                        \"nodeType\": \"MemberAccess\",\n                        \"referencedDeclaration\": 77,\n                        \"src\": \"96:3:3\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 55,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"95:5:3\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 56,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"95:7:3\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 57,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"95:7:3\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 59,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"38:1:3\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 40,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"39:2:3\"\n          },\n          \"returnParameters\": {\n            \"id\": 41,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"49:0:3\"\n          },\n          \"scope\": 60,\n          \"src\": \"29:80:3\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 61,\n      \"src\": \"12:99:3\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:112:3\"\n}\n]\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/ast_internal_function_different_ids_export.sol",
    "content": "==== Source: L ====\nfunction free1() {}\nfunction free2() {}\nlibrary L {\n    function g() internal {}\n    function h() internal {}\n}\n\n==== Source: A ====\nimport \"L\";\ncontract A {\n    function f() public {\n        (L.g)();\n        (free2)();\n        (L.h)();\n    }\n}\ncontract B {\n    function f() public {\n        (L.h)();\n        (free2)();\n    }\n}\n\n==== Source: C ====\nimport \"L\";\ncontract C {\n    function f() public {\n        (L.g)();\n        (free2)();\n        (L.h)();\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/ast_internal_function_id_export.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      128\n    ],\n    \"D\": [\n      141\n    ],\n    \"L\": [\n      53\n    ],\n    \"free1\": [\n      4\n    ],\n    \"free2\": [\n      8\n    ],\n    \"free3\": [\n      12\n    ]\n  },\n  \"id\": 142,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"body\": {\n        \"id\": 3,\n        \"nodeType\": \"Block\",\n        \"src\": \"17:2:1\",\n        \"statements\": []\n      },\n      \"id\": 4,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"free1\",\n      \"nameLocation\": \"9:5:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 1,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"14:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 2,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"17:0:1\"\n      },\n      \"scope\": 142,\n      \"src\": \"0:19:1\",\n      \"stateMutability\": \"nonpayable\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"body\": {\n        \"id\": 7,\n        \"nodeType\": \"Block\",\n        \"src\": \"37:2:1\",\n        \"statements\": []\n      },\n      \"id\": 8,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"free2\",\n      \"nameLocation\": \"29:5:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 5,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"34:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 6,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"37:0:1\"\n      },\n      \"scope\": 142,\n      \"src\": \"20:19:1\",\n      \"stateMutability\": \"nonpayable\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"body\": {\n        \"id\": 11,\n        \"nodeType\": \"Block\",\n        \"src\": \"57:2:1\",\n        \"statements\": []\n      },\n      \"id\": 12,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"free3\",\n      \"nameLocation\": \"49:5:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 9,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"54:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 10,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"57:0:1\"\n      },\n      \"scope\": 142,\n      \"src\": \"40:19:1\",\n      \"stateMutability\": \"nonpayable\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"L\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"library\",\n      \"fullyImplemented\": true,\n      \"id\": 53,\n      \"internalFunctionIDs\": {\n        \"20\": 3,\n        \"24\": 4,\n        \"4\": 1,\n        \"8\": 2\n      },\n      \"linearizedBaseContracts\": [\n        53\n      ],\n      \"name\": \"L\",\n      \"nameLocation\": \"68:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 15,\n            \"nodeType\": \"Block\",\n            \"src\": \"100:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"cf9f23b5\",\n          \"id\": 16,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"ext\",\n          \"nameLocation\": \"85:3:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 13,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"88:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 14,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"100:0:1\"\n          },\n          \"scope\": 53,\n          \"src\": \"76:26:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        },\n        {\n          \"body\": {\n            \"id\": 19,\n            \"nodeType\": \"Block\",\n            \"src\": \"132:2:1\",\n            \"statements\": []\n          },\n          \"id\": 20,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"inr1\",\n          \"nameLocation\": \"116:4:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 17,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"120:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 18,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"132:0:1\"\n          },\n          \"scope\": 53,\n          \"src\": \"107:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 23,\n            \"nodeType\": \"Block\",\n            \"src\": \"164:2:1\",\n            \"statements\": []\n          },\n          \"id\": 24,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"inr2\",\n          \"nameLocation\": \"148:4:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 21,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"152:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 22,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"164:0:1\"\n          },\n          \"scope\": 53,\n          \"src\": \"139:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 27,\n            \"nodeType\": \"Block\",\n            \"src\": \"196:2:1\",\n            \"statements\": []\n          },\n          \"id\": 28,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"inr3\",\n          \"nameLocation\": \"180:4:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 25,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"184:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 26,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"196:0:1\"\n          },\n          \"scope\": 53,\n          \"src\": \"171:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 39,\n            \"nodeType\": \"Block\",\n            \"src\": \"228:51:1\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"id\": 31,\n                  \"name\": \"free1\",\n                  \"nodeType\": \"Identifier\",\n                  \"overloadedDeclarations\": [],\n                  \"referencedDeclaration\": 4,\n                  \"src\": \"238:5:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                    \"typeString\": \"function ()\"\n                  }\n                },\n                \"id\": 32,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"238:5:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 33,\n                  \"name\": \"inr1\",\n                  \"nodeType\": \"Identifier\",\n                  \"overloadedDeclarations\": [],\n                  \"referencedDeclaration\": 20,\n                  \"src\": \"253:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                    \"typeString\": \"function ()\"\n                  }\n                },\n                \"id\": 34,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"253:4:1\"\n              },\n              {\n                \"expression\": {\n                  \"expression\": {\n                    \"id\": 35,\n                    \"name\": \"L\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 53,\n                    \"src\": \"267:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_type$_t_contract$_L_$53_$\",\n                      \"typeString\": \"type(library L)\"\n                    }\n                  },\n                  \"id\": 37,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"memberLocation\": \"269:3:1\",\n                  \"memberName\": \"ext\",\n                  \"nodeType\": \"MemberAccess\",\n                  \"referencedDeclaration\": 16,\n                  \"src\": \"267:5:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_function_delegatecall_nonpayable$__$returns$__$\",\n                    \"typeString\": \"function ()\"\n                  }\n                },\n                \"id\": 38,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"267:5:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"71907f17\",\n          \"id\": 40,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"access\",\n          \"nameLocation\": \"212:6:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 29,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"218:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 30,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"228:0:1\"\n          },\n          \"scope\": 53,\n          \"src\": \"203:76:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 51,\n            \"nodeType\": \"Block\",\n            \"src\": \"313:44:1\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"id\": 43,\n                        \"name\": \"free2\",\n                        \"nodeType\": \"Identifier\",\n                        \"overloadedDeclarations\": [],\n                        \"referencedDeclaration\": 8,\n                        \"src\": \"324:5:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 44,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"323:7:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 45,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"323:9:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 46,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"323:9:1\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"id\": 47,\n                        \"name\": \"inr2\",\n                        \"nodeType\": \"Identifier\",\n                        \"overloadedDeclarations\": [],\n                        \"referencedDeclaration\": 24,\n                        \"src\": \"343:4:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 48,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"342:6:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 49,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"342:8:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 50,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"342:8:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"4228dae0\",\n          \"id\": 52,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"expression\",\n          \"nameLocation\": \"293:10:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 41,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"303:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 42,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"313:0:1\"\n          },\n          \"scope\": 53,\n          \"src\": \"284:73:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 142,\n      \"src\": \"60:299:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 128,\n      \"internalFunctionIDs\": {\n        \"20\": 3,\n        \"24\": 4,\n        \"4\": 1,\n        \"69\": 5,\n        \"73\": 6,\n        \"8\": 2\n      },\n      \"linearizedBaseContracts\": [\n        128\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"369:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 56,\n            \"nodeType\": \"Block\",\n            \"src\": \"402:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"05b07a6b\",\n          \"id\": 57,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"ext1\",\n          \"nameLocation\": \"386:4:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 54,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"390:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 55,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"402:0:1\"\n          },\n          \"scope\": 128,\n          \"src\": \"377:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        },\n        {\n          \"body\": {\n            \"id\": 60,\n            \"nodeType\": \"Block\",\n            \"src\": \"434:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"5aa6e183\",\n          \"id\": 61,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"ext2\",\n          \"nameLocation\": \"418:4:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 58,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"422:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 59,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"434:0:1\"\n          },\n          \"scope\": 128,\n          \"src\": \"409:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        },\n        {\n          \"body\": {\n            \"id\": 64,\n            \"nodeType\": \"Block\",\n            \"src\": \"466:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"0a77b8ef\",\n          \"id\": 65,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"ext3\",\n          \"nameLocation\": \"450:4:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 62,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"454:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 63,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"466:0:1\"\n          },\n          \"scope\": 128,\n          \"src\": \"441:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        },\n        {\n          \"body\": {\n            \"id\": 68,\n            \"nodeType\": \"Block\",\n            \"src\": \"498:2:1\",\n            \"statements\": []\n          },\n          \"id\": 69,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"inr1\",\n          \"nameLocation\": \"482:4:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 66,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"486:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 67,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"498:0:1\"\n          },\n          \"scope\": 128,\n          \"src\": \"473:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 72,\n            \"nodeType\": \"Block\",\n            \"src\": \"530:2:1\",\n            \"statements\": []\n          },\n          \"id\": 73,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"inr2\",\n          \"nameLocation\": \"514:4:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 70,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"518:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 71,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"530:0:1\"\n          },\n          \"scope\": 128,\n          \"src\": \"505:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 76,\n            \"nodeType\": \"Block\",\n            \"src\": \"562:2:1\",\n            \"statements\": []\n          },\n          \"id\": 77,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"inr3\",\n          \"nameLocation\": \"546:4:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 74,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"550:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 75,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"562:0:1\"\n          },\n          \"scope\": 128,\n          \"src\": \"537:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 96,\n            \"nodeType\": \"Block\",\n            \"src\": \"594:86:1\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"expression\": {\n                    \"id\": 80,\n                    \"name\": \"this\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": -28,\n                    \"src\": \"604:4:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_contract$_C_$128\",\n                      \"typeString\": \"contract C\"\n                    }\n                  },\n                  \"id\": 82,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"memberLocation\": \"609:4:1\",\n                  \"memberName\": \"ext1\",\n                  \"nodeType\": \"MemberAccess\",\n                  \"referencedDeclaration\": 57,\n                  \"src\": \"604:9:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_function_external_nonpayable$__$returns$__$\",\n                    \"typeString\": \"function () external\"\n                  }\n                },\n                \"id\": 83,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"604:9:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 84,\n                  \"name\": \"inr1\",\n                  \"nodeType\": \"Identifier\",\n                  \"overloadedDeclarations\": [],\n                  \"referencedDeclaration\": 69,\n                  \"src\": \"623:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                    \"typeString\": \"function ()\"\n                  }\n                },\n                \"id\": 85,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"623:4:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 86,\n                  \"name\": \"free1\",\n                  \"nodeType\": \"Identifier\",\n                  \"overloadedDeclarations\": [],\n                  \"referencedDeclaration\": 4,\n                  \"src\": \"637:5:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                    \"typeString\": \"function ()\"\n                  }\n                },\n                \"id\": 87,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"637:5:1\"\n              },\n              {\n                \"expression\": {\n                  \"expression\": {\n                    \"id\": 88,\n                    \"name\": \"L\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 53,\n                    \"src\": \"652:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_type$_t_contract$_L_$53_$\",\n                      \"typeString\": \"type(library L)\"\n                    }\n                  },\n                  \"id\": 90,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"memberLocation\": \"654:4:1\",\n                  \"memberName\": \"inr1\",\n                  \"nodeType\": \"MemberAccess\",\n                  \"referencedDeclaration\": 20,\n                  \"src\": \"652:6:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                    \"typeString\": \"function ()\"\n                  }\n                },\n                \"id\": 91,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"652:6:1\"\n              },\n              {\n                \"expression\": {\n                  \"expression\": {\n                    \"id\": 92,\n                    \"name\": \"L\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 53,\n                    \"src\": \"668:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_type$_t_contract$_L_$53_$\",\n                      \"typeString\": \"type(library L)\"\n                    }\n                  },\n                  \"id\": 94,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"memberLocation\": \"670:3:1\",\n                  \"memberName\": \"ext\",\n                  \"nodeType\": \"MemberAccess\",\n                  \"referencedDeclaration\": 16,\n                  \"src\": \"668:5:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_function_delegatecall_nonpayable$__$returns$__$\",\n                    \"typeString\": \"function ()\"\n                  }\n                },\n                \"id\": 95,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"668:5:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"71907f17\",\n          \"id\": 97,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"access\",\n          \"nameLocation\": \"578:6:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 78,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"584:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 79,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"594:0:1\"\n          },\n          \"scope\": 128,\n          \"src\": \"569:111:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 126,\n            \"nodeType\": \"Block\",\n            \"src\": \"714:106:1\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"expression\": {\n                          \"id\": 100,\n                          \"name\": \"this\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"referencedDeclaration\": -28,\n                          \"src\": \"725:4:1\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_contract$_C_$128\",\n                            \"typeString\": \"contract C\"\n                          }\n                        },\n                        \"id\": 102,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": false,\n                        \"lValueRequested\": false,\n                        \"memberLocation\": \"730:4:1\",\n                        \"memberName\": \"ext2\",\n                        \"nodeType\": \"MemberAccess\",\n                        \"referencedDeclaration\": 61,\n                        \"src\": \"725:9:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_external_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function () external\"\n                        }\n                      }\n                    ],\n                    \"id\": 103,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"724:11:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_external_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function () external\"\n                    }\n                  },\n                  \"id\": 104,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"724:13:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 105,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"724:13:1\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"id\": 106,\n                        \"name\": \"inr2\",\n                        \"nodeType\": \"Identifier\",\n                        \"overloadedDeclarations\": [],\n                        \"referencedDeclaration\": 73,\n                        \"src\": \"748:4:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 107,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"747:6:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 108,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"747:8:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 109,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"747:8:1\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"id\": 110,\n                        \"name\": \"free2\",\n                        \"nodeType\": \"Identifier\",\n                        \"overloadedDeclarations\": [],\n                        \"referencedDeclaration\": 8,\n                        \"src\": \"766:5:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 111,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"765:7:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 112,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"765:9:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 113,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"765:9:1\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"expression\": {\n                          \"id\": 114,\n                          \"name\": \"L\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"referencedDeclaration\": 53,\n                          \"src\": \"785:1:1\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_type$_t_contract$_L_$53_$\",\n                            \"typeString\": \"type(library L)\"\n                          }\n                        },\n                        \"id\": 116,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": false,\n                        \"lValueRequested\": false,\n                        \"memberLocation\": \"787:4:1\",\n                        \"memberName\": \"inr2\",\n                        \"nodeType\": \"MemberAccess\",\n                        \"referencedDeclaration\": 24,\n                        \"src\": \"785:6:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 117,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"784:8:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 118,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"784:10:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 119,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"784:10:1\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"components\": [\n                      {\n                        \"expression\": {\n                          \"id\": 120,\n                          \"name\": \"L\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"referencedDeclaration\": 53,\n                          \"src\": \"805:1:1\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_type$_t_contract$_L_$53_$\",\n                            \"typeString\": \"type(library L)\"\n                          }\n                        },\n                        \"id\": 122,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": false,\n                        \"lValueRequested\": false,\n                        \"memberLocation\": \"807:3:1\",\n                        \"memberName\": \"ext\",\n                        \"nodeType\": \"MemberAccess\",\n                        \"referencedDeclaration\": 16,\n                        \"src\": \"805:5:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_function_delegatecall_nonpayable$__$returns$__$\",\n                          \"typeString\": \"function ()\"\n                        }\n                      }\n                    ],\n                    \"id\": 123,\n                    \"isConstant\": false,\n                    \"isInlineArray\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"TupleExpression\",\n                    \"src\": \"804:7:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_delegatecall_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 124,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"804:9:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 125,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"804:9:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"4228dae0\",\n          \"id\": 127,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"expression\",\n          \"nameLocation\": \"694:10:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 98,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"704:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 99,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"714:0:1\"\n          },\n          \"scope\": 128,\n          \"src\": \"685:135:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 142,\n      \"src\": \"360:462:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 129,\n            \"name\": \"C\",\n            \"nameLocations\": [\n              \"837:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 128,\n            \"src\": \"837:1:1\"\n          },\n          \"id\": 130,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"837:1:1\"\n        }\n      ],\n      \"canonicalName\": \"D\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 141,\n      \"internalFunctionIDs\": {\n        \"20\": 3,\n        \"24\": 4,\n        \"4\": 1,\n        \"69\": 5,\n        \"73\": 6,\n        \"8\": 2\n      },\n      \"linearizedBaseContracts\": [\n        141,\n        128\n      ],\n      \"name\": \"D\",\n      \"nameLocation\": \"832:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 139,\n            \"nodeType\": \"Block\",\n            \"src\": \"859:47:1\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"id\": 133,\n                    \"name\": \"access\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 97,\n                    \"src\": \"869:6:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 134,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"869:8:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 135,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"869:8:1\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"id\": 136,\n                    \"name\": \"expression\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 127,\n                    \"src\": \"887:10:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 137,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"887:12:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 138,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"887:12:1\"\n              }\n            ]\n          },\n          \"id\": 140,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 131,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"856:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 132,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"859:0:1\"\n          },\n          \"scope\": 141,\n          \"src\": \"845:61:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 142,\n      \"src\": \"823:85:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:909:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/ast_internal_function_id_export.sol",
    "content": "function free1() {}\nfunction free2() {}\nfunction free3() {}\nlibrary L {\n    function ext() external {}\n    function inr1() internal {}\n    function inr2() internal {}\n    function inr3() internal {}\n    function access() public {\n        free1;\n        inr1;\n        L.ext;\n    }\n    function expression() public {\n        (free2)();\n        (inr2)();\n    }\n}\ncontract C {\n    function ext1() external {}\n    function ext2() external {}\n    function ext3() external {}\n    function inr1() internal {}\n    function inr2() internal {}\n    function inr3() internal {}\n    function access() public {\n        this.ext1;\n        inr1;\n        free1;\n        L.inr1;\n        L.ext;\n    }\n    function expression() public {\n        (this.ext2)();\n        (inr2)();\n        (free2)();\n        (L.inr2)();\n        (L.ext)();\n    }\n}\ncontract D is C {\n    constructor() {\n        access();\n        expression();\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/base_constructor_call.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"A\": [\n      7\n    ],\n    \"C\": [\n      17\n    ]\n  },\n  \"id\": 18,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"A\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 7,\n      \"linearizedBaseContracts\": [\n        7\n      ],\n      \"name\": \"A\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 5,\n            \"nodeType\": \"Block\",\n            \"src\": \"31:2:1\",\n            \"statements\": []\n          },\n          \"id\": 6,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 2,\n                \"mutability\": \"mutable\",\n                \"name\": \"\",\n                \"nameLocation\": \"-1:-1:-1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 6,\n                \"src\": \"25:4:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                },\n                \"typeName\": {\n                  \"id\": 1,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"25:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"24:6:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 4,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"31:0:1\"\n          },\n          \"scope\": 7,\n          \"src\": \"13:20:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 18,\n      \"src\": \"0:35:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 8,\n            \"name\": \"A\",\n            \"nameLocations\": [\n              \"50:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 7,\n            \"src\": \"50:1:1\"\n          },\n          \"id\": 9,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"50:1:1\"\n        }\n      ],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 17,\n      \"linearizedBaseContracts\": [\n        17,\n        7\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"45:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 15,\n            \"nodeType\": \"Block\",\n            \"src\": \"73:2:1\",\n            \"statements\": []\n          },\n          \"id\": 16,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [\n            {\n              \"arguments\": [\n                {\n                  \"hexValue\": \"32\",\n                  \"id\": 12,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": true,\n                  \"kind\": \"number\",\n                  \"lValueRequested\": false,\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"70:1:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_rational_2_by_1\",\n                    \"typeString\": \"int_const 2\"\n                  },\n                  \"value\": \"2\"\n                }\n              ],\n              \"id\": 13,\n              \"kind\": \"baseConstructorSpecifier\",\n              \"modifierName\": {\n                \"id\": 11,\n                \"name\": \"A\",\n                \"nameLocations\": [\n                  \"68:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 7,\n                \"src\": \"68:1:1\"\n              },\n              \"nodeType\": \"ModifierInvocation\",\n              \"src\": \"68:4:1\"\n            }\n          ],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 10,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"65:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 14,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"73:0:1\"\n          },\n          \"scope\": 17,\n          \"src\": \"54:21:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 18,\n      \"src\": \"36:41:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:78:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/base_constructor_call.sol",
    "content": "contract A { constructor(uint) {} }\ncontract C is A { constructor() A(2) {} }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/base_constructor_call_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 18,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 7,\n      \"name\": \"A\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 5,\n            \"nodeType\": \"Block\",\n            \"src\": \"31:2:1\",\n            \"statements\": []\n          },\n          \"id\": 6,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 2,\n                \"mutability\": \"mutable\",\n                \"name\": \"\",\n                \"nameLocation\": \"-1:-1:-1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"25:4:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 1,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"25:4:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"24:6:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 4,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"31:0:1\"\n          },\n          \"src\": \"13:20:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false\n        }\n      ],\n      \"src\": \"0:35:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 8,\n            \"name\": \"A\",\n            \"nameLocations\": [\n              \"50:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"50:1:1\"\n          },\n          \"id\": 9,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"50:1:1\"\n        }\n      ],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 17,\n      \"name\": \"C\",\n      \"nameLocation\": \"45:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 15,\n            \"nodeType\": \"Block\",\n            \"src\": \"73:2:1\",\n            \"statements\": []\n          },\n          \"id\": 16,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [\n            {\n              \"arguments\": [\n                {\n                  \"hexValue\": \"32\",\n                  \"id\": 12,\n                  \"kind\": \"number\",\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"70:1:1\",\n                  \"typeDescriptions\": {},\n                  \"value\": \"2\"\n                }\n              ],\n              \"id\": 13,\n              \"modifierName\": {\n                \"id\": 11,\n                \"name\": \"A\",\n                \"nameLocations\": [\n                  \"68:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"src\": \"68:1:1\"\n              },\n              \"nodeType\": \"ModifierInvocation\",\n              \"src\": \"68:4:1\"\n            }\n          ],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 10,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"65:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 14,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"73:0:1\"\n          },\n          \"src\": \"54:21:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false\n        }\n      ],\n      \"src\": \"36:41:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:78:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/constructor.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      5\n    ]\n  },\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"28:4:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"25:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"28:0:1\"\n          },\n          \"scope\": 5,\n          \"src\": \"14:18:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 6,\n      \"src\": \"0:34:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:35:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/constructor.sol",
    "content": "contract C {\n\tconstructor() {\n\t}\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/constructor_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 5,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"28:4:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"25:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"28:0:1\"\n          },\n          \"src\": \"14:18:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false\n        }\n      ],\n      \"src\": \"0:34:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:35:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/contract_dep_order.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"A\": [\n      1\n    ],\n    \"B\": [\n      4\n    ],\n    \"C\": [\n      7\n    ],\n    \"D\": [\n      10\n    ],\n    \"E\": [\n      13\n    ]\n  },\n  \"id\": 14,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"A\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 1,\n      \"linearizedBaseContracts\": [\n        1\n      ],\n      \"name\": \"A\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 14,\n      \"src\": \"0:14:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 2,\n            \"name\": \"A\",\n            \"nameLocations\": [\n              \"29:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 1,\n            \"src\": \"29:1:1\"\n          },\n          \"id\": 3,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"29:1:1\"\n        }\n      ],\n      \"canonicalName\": \"B\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 4,\n      \"linearizedBaseContracts\": [\n        4,\n        1\n      ],\n      \"name\": \"B\",\n      \"nameLocation\": \"24:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 14,\n      \"src\": \"15:19:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 5,\n            \"name\": \"B\",\n            \"nameLocations\": [\n              \"49:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 4,\n            \"src\": \"49:1:1\"\n          },\n          \"id\": 6,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"49:1:1\"\n        }\n      ],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 7,\n      \"linearizedBaseContracts\": [\n        7,\n        4,\n        1\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"44:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 14,\n      \"src\": \"35:19:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 8,\n            \"name\": \"C\",\n            \"nameLocations\": [\n              \"69:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 7,\n            \"src\": \"69:1:1\"\n          },\n          \"id\": 9,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"69:1:1\"\n        }\n      ],\n      \"canonicalName\": \"D\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 10,\n      \"linearizedBaseContracts\": [\n        10,\n        7,\n        4,\n        1\n      ],\n      \"name\": \"D\",\n      \"nameLocation\": \"64:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 14,\n      \"src\": \"55:19:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 11,\n            \"name\": \"D\",\n            \"nameLocations\": [\n              \"89:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 10,\n            \"src\": \"89:1:1\"\n          },\n          \"id\": 12,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"89:1:1\"\n        }\n      ],\n      \"canonicalName\": \"E\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 13,\n      \"linearizedBaseContracts\": [\n        13,\n        10,\n        7,\n        4,\n        1\n      ],\n      \"name\": \"E\",\n      \"nameLocation\": \"84:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 14,\n      \"src\": \"75:19:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:95:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/contract_dep_order.sol",
    "content": "contract A { }\ncontract B is A { }\ncontract C is B { }\ncontract D is C { }\ncontract E is D { }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/contract_dep_order_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 14,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 1,\n      \"name\": \"A\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"0:14:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 2,\n            \"name\": \"A\",\n            \"nameLocations\": [\n              \"29:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"29:1:1\"\n          },\n          \"id\": 3,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"29:1:1\"\n        }\n      ],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 4,\n      \"name\": \"B\",\n      \"nameLocation\": \"24:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"15:19:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 5,\n            \"name\": \"B\",\n            \"nameLocations\": [\n              \"49:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"49:1:1\"\n          },\n          \"id\": 6,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"49:1:1\"\n        }\n      ],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 7,\n      \"name\": \"C\",\n      \"nameLocation\": \"44:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"35:19:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 8,\n            \"name\": \"C\",\n            \"nameLocations\": [\n              \"69:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"69:1:1\"\n          },\n          \"id\": 9,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"69:1:1\"\n        }\n      ],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 10,\n      \"name\": \"D\",\n      \"nameLocation\": \"64:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"55:19:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 11,\n            \"name\": \"D\",\n            \"nameLocations\": [\n              \"89:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"89:1:1\"\n          },\n          \"id\": 12,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"89:1:1\"\n        }\n      ],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 13,\n      \"name\": \"E\",\n      \"nameLocation\": \"84:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"75:19:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:95:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation.json",
    "content": "[\n{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      2\n    ]\n  },\n  \"id\": 3,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"documentation\": {\n        \"id\": 1,\n        \"nodeType\": \"StructuredDocumentation\",\n        \"src\": \"0:27:1\",\n        \"text\": \"This contract is empty\"\n      },\n      \"fullyImplemented\": true,\n      \"id\": 2,\n      \"linearizedBaseContracts\": [\n        2\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"37:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 3,\n      \"src\": \"28:13:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"28:14:1\"\n},\n{\n  \"absolutePath\": \"b\",\n  \"exportedSymbols\": {\n    \"C\": [\n      5\n    ]\n  },\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"documentation\": {\n        \"id\": 4,\n        \"nodeType\": \"StructuredDocumentation\",\n        \"src\": \"0:61:2\",\n        \"text\": \"This contract is empty\\nand has a line-breaking comment.\"\n      },\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"71:1:2\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 6,\n      \"src\": \"62:13:2\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"62:14:2\"\n},\n{\n  \"absolutePath\": \"c\",\n  \"exportedSymbols\": {\n    \"C\": [\n      23\n    ]\n  },\n  \"id\": 24,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 23,\n      \"linearizedBaseContracts\": [\n        23\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:3\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"documentation\": {\n            \"id\": 7,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"15:32:3\",\n            \"text\": \"Some comment on state var.\"\n          },\n          \"functionSelector\": \"c19d93fb\",\n          \"id\": 9,\n          \"mutability\": \"mutable\",\n          \"name\": \"state\",\n          \"nameLocation\": \"60:5:3\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 23,\n          \"src\": \"48:17:3\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_uint256\",\n            \"typeString\": \"uint256\"\n          },\n          \"typeName\": {\n            \"id\": 8,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"48:4:3\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_uint256\",\n              \"typeString\": \"uint256\"\n            }\n          },\n          \"visibility\": \"public\"\n        },\n        {\n          \"anonymous\": false,\n          \"documentation\": {\n            \"id\": 10,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"69:26:3\",\n            \"text\": \"Some comment on Evt.\"\n          },\n          \"eventSelector\": \"a69007916fc1145953e5a7032d7c3eab4b8e2f33ec59b0f71e732904eeede3a4\",\n          \"id\": 12,\n          \"name\": \"Evt\",\n          \"nameLocation\": \"102:3:3\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"105:2:3\"\n          },\n          \"src\": \"96:12:3\"\n        },\n        {\n          \"body\": {\n            \"id\": 16,\n            \"nodeType\": \"Block\",\n            \"src\": \"153:6:3\",\n            \"statements\": [\n              {\n                \"id\": 15,\n                \"nodeType\": \"PlaceholderStatement\",\n                \"src\": \"155:1:3\"\n              }\n            ]\n          },\n          \"documentation\": {\n            \"id\": 13,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"111:26:3\",\n            \"text\": \"Some comment on mod.\"\n          },\n          \"id\": 17,\n          \"name\": \"mod\",\n          \"nameLocation\": \"147:3:3\",\n          \"nodeType\": \"ModifierDefinition\",\n          \"parameters\": {\n            \"id\": 14,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"150:2:3\"\n          },\n          \"src\": \"138:21:3\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 21,\n            \"nodeType\": \"Block\",\n            \"src\": \"209:2:3\",\n            \"statements\": []\n          },\n          \"documentation\": {\n            \"id\": 18,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"162:25:3\",\n            \"text\": \"Some comment on fn.\"\n          },\n          \"functionSelector\": \"a4a2c40b\",\n          \"id\": 22,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"fn\",\n          \"nameLocation\": \"197:2:3\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 19,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"199:2:3\"\n          },\n          \"returnParameters\": {\n            \"id\": 20,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"209:0:3\"\n          },\n          \"scope\": 23,\n          \"src\": \"188:23:3\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 24,\n      \"src\": \"0:213:3\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        12\n      ]\n    }\n  ],\n  \"src\": \"0:214:3\"\n}\n]\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation.sol",
    "content": "==== Source: a ====\n/**This contract is empty*/ contract C {}\n\n==== Source: b ====\n/**This contract is empty\n and has a line-breaking comment.*/\ncontract C {}\n\n==== Source: c ====\ncontract C {\n  /** Some comment on state var.*/ uint public state;\n  /** Some comment on Evt.*/ event Evt();\n  /** Some comment on mod.*/ modifier mod() { _; }\n  /** Some comment on fn.*/ function fn() public {}\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation_local_variable.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      41\n    ]\n  },\n  \"id\": 42,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 41,\n      \"linearizedBaseContracts\": [\n        41\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 26,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:330:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  5\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 5,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"114:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 26,\n                    \"src\": \"109:6:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_uint256\",\n                      \"typeString\": \"uint256\"\n                    },\n                    \"typeName\": {\n                      \"id\": 4,\n                      \"name\": \"uint\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"109:4:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_uint256\",\n                        \"typeString\": \"uint256\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"documentation\": \"Documentation for x; will appear in ast json\",\n                \"id\": 7,\n                \"initialValue\": {\n                  \"hexValue\": \"31\",\n                  \"id\": 6,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": true,\n                  \"kind\": \"number\",\n                  \"lValueRequested\": false,\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"118:1:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_rational_1_by_1\",\n                    \"typeString\": \"int_const 1\"\n                  },\n                  \"value\": \"1\"\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"109:10:1\"\n              },\n              {\n                \"body\": {\n                  \"id\": 24,\n                  \"nodeType\": \"Block\",\n                  \"src\": \"270:96:1\",\n                  \"statements\": [\n                    {\n                      \"assignments\": [\n                        21\n                      ],\n                      \"declarations\": [\n                        {\n                          \"constant\": false,\n                          \"id\": 21,\n                          \"mutability\": \"mutable\",\n                          \"name\": \"j\",\n                          \"nameLocation\": \"350:1:1\",\n                          \"nodeType\": \"VariableDeclaration\",\n                          \"scope\": 24,\n                          \"src\": \"345:6:1\",\n                          \"stateVariable\": false,\n                          \"storageLocation\": \"default\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_uint256\",\n                            \"typeString\": \"uint256\"\n                          },\n                          \"typeName\": {\n                            \"id\": 20,\n                            \"name\": \"uint\",\n                            \"nodeType\": \"ElementaryTypeName\",\n                            \"src\": \"345:4:1\",\n                            \"typeDescriptions\": {\n                              \"typeIdentifier\": \"t_uint256\",\n                              \"typeString\": \"uint256\"\n                            }\n                          },\n                          \"visibility\": \"internal\"\n                        }\n                      ],\n                      \"documentation\": \"documentation for j; will appear in ast json\",\n                      \"id\": 23,\n                      \"initialValue\": {\n                        \"hexValue\": \"30\",\n                        \"id\": 22,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": true,\n                        \"kind\": \"number\",\n                        \"lValueRequested\": false,\n                        \"nodeType\": \"Literal\",\n                        \"src\": \"354:1:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_rational_0_by_1\",\n                          \"typeString\": \"int_const 0\"\n                        },\n                        \"value\": \"0\"\n                      },\n                      \"nodeType\": \"VariableDeclarationStatement\",\n                      \"src\": \"345:10:1\"\n                    }\n                  ]\n                },\n                \"condition\": {\n                  \"commonType\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  },\n                  \"id\": 15,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"leftExpression\": {\n                    \"id\": 13,\n                    \"name\": \"i\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 10,\n                    \"src\": \"236:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_uint256\",\n                      \"typeString\": \"uint256\"\n                    }\n                  },\n                  \"nodeType\": \"BinaryOperation\",\n                  \"operator\": \"<\",\n                  \"rightExpression\": {\n                    \"hexValue\": \"3130\",\n                    \"id\": 14,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"kind\": \"number\",\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"240:2:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_rational_10_by_1\",\n                      \"typeString\": \"int_const 10\"\n                    },\n                    \"value\": \"10\"\n                  },\n                  \"src\": \"236:6:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_bool\",\n                    \"typeString\": \"bool\"\n                  }\n                },\n                \"id\": 25,\n                \"initializationExpression\": {\n                  \"assignments\": [\n                    10\n                  ],\n                  \"declarations\": [\n                    {\n                      \"constant\": false,\n                      \"id\": 10,\n                      \"mutability\": \"mutable\",\n                      \"name\": \"i\",\n                      \"nameLocation\": \"217:1:1\",\n                      \"nodeType\": \"VariableDeclaration\",\n                      \"scope\": 25,\n                      \"src\": \"212:6:1\",\n                      \"stateVariable\": false,\n                      \"storageLocation\": \"default\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_uint256\",\n                        \"typeString\": \"uint256\"\n                      },\n                      \"typeName\": {\n                        \"id\": 9,\n                        \"name\": \"uint\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"212:4:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_uint256\",\n                          \"typeString\": \"uint256\"\n                        }\n                      },\n                      \"visibility\": \"internal\"\n                    }\n                  ],\n                  \"id\": 12,\n                  \"initialValue\": {\n                    \"hexValue\": \"30\",\n                    \"id\": 11,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"kind\": \"number\",\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"221:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_rational_0_by_1\",\n                      \"typeString\": \"int_const 0\"\n                    },\n                    \"value\": \"0\"\n                  },\n                  \"nodeType\": \"VariableDeclarationStatement\",\n                  \"src\": \"212:10:1\"\n                },\n                \"isSimpleCounterLoop\": true,\n                \"loopExpression\": {\n                  \"expression\": {\n                    \"id\": 17,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"UnaryOperation\",\n                    \"operator\": \"++\",\n                    \"prefix\": true,\n                    \"src\": \"256:3:1\",\n                    \"subExpression\": {\n                      \"id\": 16,\n                      \"name\": \"i\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 10,\n                      \"src\": \"258:1:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_uint256\",\n                        \"typeString\": \"uint256\"\n                      }\n                    },\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_uint256\",\n                      \"typeString\": \"uint256\"\n                    }\n                  },\n                  \"id\": 18,\n                  \"nodeType\": \"ExpressionStatement\",\n                  \"src\": \"256:3:1\"\n                },\n                \"nodeType\": \"ForStatement\",\n                \"src\": \"129:237:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 27,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"scope\": 41,\n          \"src\": \"17:355:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 39,\n            \"nodeType\": \"Block\",\n            \"src\": \"662:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"191157d1\",\n          \"id\": 40,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"g\",\n          \"nameLocation\": \"386:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 37,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 30,\n                \"mutability\": \"mutable\",\n                \"name\": \"param1\",\n                \"nameLocation\": \"468:6:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 40,\n                \"src\": \"463:11:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                },\n                \"typeName\": {\n                  \"id\": 29,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"463:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              },\n              {\n                \"constant\": false,\n                \"id\": 33,\n                \"mutability\": \"mutable\",\n                \"name\": \"param2\",\n                \"nameLocation\": \"555:6:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 40,\n                \"src\": \"550:11:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                },\n                \"typeName\": {\n                  \"id\": 32,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"550:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              },\n              {\n                \"constant\": false,\n                \"id\": 36,\n                \"mutability\": \"mutable\",\n                \"name\": \"param3\",\n                \"nameLocation\": \"642:6:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 40,\n                \"src\": \"637:11:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                },\n                \"typeName\": {\n                  \"id\": 35,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"637:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"387:267:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 38,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"662:0:1\"\n          },\n          \"scope\": 41,\n          \"src\": \"377:287:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 42,\n      \"src\": \"0:666:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:667:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation_local_variable.sol",
    "content": "contract C {\n    function f() public pure {\n        /// Documentation for x; will appear in ast json\n        uint x = 1;\n        for (\n            /// documentation for i; will not appear in ast json\n            uint i = 0;\n            i < 10;\n            ++i\n        ) {\n            /// documentation for j; will appear in ast json\n            uint j = 0;\n        }\n    }\n    function g(\n        /// documentation for param1; will not appear in ast json\n        uint param1,\n        /// documentation for param2; will not appear in ast json\n        uint param2,\n        /// documentation for param3; will not appear in ast json\n        uint param3\n    ) public {}\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation_local_variable_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 42,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 41,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 26,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:330:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  5\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 5,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"114:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"109:6:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 4,\n                      \"name\": \"uint\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"109:4:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"documentation\": \"Documentation for x; will appear in ast json\",\n                \"id\": 7,\n                \"initialValue\": {\n                  \"hexValue\": \"31\",\n                  \"id\": 6,\n                  \"kind\": \"number\",\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"118:1:1\",\n                  \"typeDescriptions\": {},\n                  \"value\": \"1\"\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"109:10:1\"\n              },\n              {\n                \"body\": {\n                  \"id\": 24,\n                  \"nodeType\": \"Block\",\n                  \"src\": \"270:96:1\",\n                  \"statements\": [\n                    {\n                      \"assignments\": [\n                        21\n                      ],\n                      \"declarations\": [\n                        {\n                          \"constant\": false,\n                          \"id\": 21,\n                          \"mutability\": \"mutable\",\n                          \"name\": \"j\",\n                          \"nameLocation\": \"350:1:1\",\n                          \"nodeType\": \"VariableDeclaration\",\n                          \"src\": \"345:6:1\",\n                          \"stateVariable\": false,\n                          \"storageLocation\": \"default\",\n                          \"typeDescriptions\": {},\n                          \"typeName\": {\n                            \"id\": 20,\n                            \"name\": \"uint\",\n                            \"nodeType\": \"ElementaryTypeName\",\n                            \"src\": \"345:4:1\",\n                            \"typeDescriptions\": {}\n                          },\n                          \"visibility\": \"internal\"\n                        }\n                      ],\n                      \"documentation\": \"documentation for j; will appear in ast json\",\n                      \"id\": 23,\n                      \"initialValue\": {\n                        \"hexValue\": \"30\",\n                        \"id\": 22,\n                        \"kind\": \"number\",\n                        \"nodeType\": \"Literal\",\n                        \"src\": \"354:1:1\",\n                        \"typeDescriptions\": {},\n                        \"value\": \"0\"\n                      },\n                      \"nodeType\": \"VariableDeclarationStatement\",\n                      \"src\": \"345:10:1\"\n                    }\n                  ]\n                },\n                \"condition\": {\n                  \"commonType\": {},\n                  \"id\": 15,\n                  \"leftExpression\": {\n                    \"id\": 13,\n                    \"name\": \"i\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"236:1:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"nodeType\": \"BinaryOperation\",\n                  \"operator\": \"<\",\n                  \"rightExpression\": {\n                    \"hexValue\": \"3130\",\n                    \"id\": 14,\n                    \"kind\": \"number\",\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"240:2:1\",\n                    \"typeDescriptions\": {},\n                    \"value\": \"10\"\n                  },\n                  \"src\": \"236:6:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 25,\n                \"initializationExpression\": {\n                  \"assignments\": [\n                    10\n                  ],\n                  \"declarations\": [\n                    {\n                      \"constant\": false,\n                      \"id\": 10,\n                      \"mutability\": \"mutable\",\n                      \"name\": \"i\",\n                      \"nameLocation\": \"217:1:1\",\n                      \"nodeType\": \"VariableDeclaration\",\n                      \"src\": \"212:6:1\",\n                      \"stateVariable\": false,\n                      \"storageLocation\": \"default\",\n                      \"typeDescriptions\": {},\n                      \"typeName\": {\n                        \"id\": 9,\n                        \"name\": \"uint\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"212:4:1\",\n                        \"typeDescriptions\": {}\n                      },\n                      \"visibility\": \"internal\"\n                    }\n                  ],\n                  \"id\": 12,\n                  \"initialValue\": {\n                    \"hexValue\": \"30\",\n                    \"id\": 11,\n                    \"kind\": \"number\",\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"221:1:1\",\n                    \"typeDescriptions\": {},\n                    \"value\": \"0\"\n                  },\n                  \"nodeType\": \"VariableDeclarationStatement\",\n                  \"src\": \"212:10:1\"\n                },\n                \"loopExpression\": {\n                  \"expression\": {\n                    \"id\": 17,\n                    \"nodeType\": \"UnaryOperation\",\n                    \"operator\": \"++\",\n                    \"prefix\": true,\n                    \"src\": \"256:3:1\",\n                    \"subExpression\": {\n                      \"id\": 16,\n                      \"name\": \"i\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"src\": \"258:1:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"typeDescriptions\": {}\n                  },\n                  \"id\": 18,\n                  \"nodeType\": \"ExpressionStatement\",\n                  \"src\": \"256:3:1\"\n                },\n                \"nodeType\": \"ForStatement\",\n                \"src\": \"129:237:1\"\n              }\n            ]\n          },\n          \"id\": 27,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"src\": \"17:355:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 39,\n            \"nodeType\": \"Block\",\n            \"src\": \"662:2:1\",\n            \"statements\": []\n          },\n          \"id\": 40,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"g\",\n          \"nameLocation\": \"386:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 37,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 30,\n                \"mutability\": \"mutable\",\n                \"name\": \"param1\",\n                \"nameLocation\": \"468:6:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"463:11:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 29,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"463:4:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              },\n              {\n                \"constant\": false,\n                \"id\": 33,\n                \"mutability\": \"mutable\",\n                \"name\": \"param2\",\n                \"nameLocation\": \"555:6:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"550:11:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 32,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"550:4:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              },\n              {\n                \"constant\": false,\n                \"id\": 36,\n                \"mutability\": \"mutable\",\n                \"name\": \"param3\",\n                \"nameLocation\": \"642:6:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"637:11:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 35,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"637:4:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"387:267:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 38,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"662:0:1\"\n          },\n          \"src\": \"377:287:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:666:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:667:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation_on_statements.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      27\n    ]\n  },\n  \"id\": 28,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 27,\n      \"linearizedBaseContracts\": [\n        27\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 2,\n          \"mutability\": \"mutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"50:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 27,\n          \"src\": \"45:6:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_uint256\",\n            \"typeString\": \"uint256\"\n          },\n          \"typeName\": {\n            \"id\": 1,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"45:4:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_uint256\",\n              \"typeString\": \"uint256\"\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 25,\n            \"nodeType\": \"Block\",\n            \"src\": \"99:229:1\",\n            \"statements\": [\n              {\n                \"body\": {\n                  \"id\": 21,\n                  \"nodeType\": \"Block\",\n                  \"src\": \"156:66:1\",\n                  \"statements\": [\n                    {\n                      \"expression\": {\n                        \"id\": 19,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": false,\n                        \"lValueRequested\": false,\n                        \"leftHandSide\": {\n                          \"id\": 17,\n                          \"name\": \"x\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"referencedDeclaration\": 5,\n                          \"src\": \"205:1:1\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_uint256\",\n                            \"typeString\": \"uint256\"\n                          }\n                        },\n                        \"nodeType\": \"Assignment\",\n                        \"operator\": \"*=\",\n                        \"rightHandSide\": {\n                          \"hexValue\": \"32\",\n                          \"id\": 18,\n                          \"isConstant\": false,\n                          \"isLValue\": false,\n                          \"isPure\": true,\n                          \"kind\": \"number\",\n                          \"lValueRequested\": false,\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"210:1:1\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_rational_2_by_1\",\n                            \"typeString\": \"int_const 2\"\n                          },\n                          \"value\": \"2\"\n                        },\n                        \"src\": \"205:6:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_uint256\",\n                          \"typeString\": \"uint256\"\n                        }\n                      },\n                      \"id\": 20,\n                      \"nodeType\": \"ExpressionStatement\",\n                      \"src\": \"205:6:1\"\n                    }\n                  ]\n                },\n                \"condition\": {\n                  \"commonType\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  },\n                  \"id\": 13,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"leftExpression\": {\n                    \"id\": 11,\n                    \"name\": \"i\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 8,\n                    \"src\": \"143:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_uint256\",\n                      \"typeString\": \"uint256\"\n                    }\n                  },\n                  \"nodeType\": \"BinaryOperation\",\n                  \"operator\": \"<\",\n                  \"rightExpression\": {\n                    \"hexValue\": \"3230\",\n                    \"id\": 12,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"kind\": \"number\",\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"147:2:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_rational_20_by_1\",\n                      \"typeString\": \"int_const 20\"\n                    },\n                    \"value\": \"20\"\n                  },\n                  \"src\": \"143:6:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_bool\",\n                    \"typeString\": \"bool\"\n                  }\n                },\n                \"id\": 22,\n                \"initializationExpression\": {\n                  \"assignments\": [\n                    8\n                  ],\n                  \"declarations\": [\n                    {\n                      \"constant\": false,\n                      \"id\": 8,\n                      \"mutability\": \"mutable\",\n                      \"name\": \"i\",\n                      \"nameLocation\": \"136:1:1\",\n                      \"nodeType\": \"VariableDeclaration\",\n                      \"scope\": 22,\n                      \"src\": \"131:6:1\",\n                      \"stateVariable\": false,\n                      \"storageLocation\": \"default\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_uint256\",\n                        \"typeString\": \"uint256\"\n                      },\n                      \"typeName\": {\n                        \"id\": 7,\n                        \"name\": \"uint\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"131:4:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_uint256\",\n                          \"typeString\": \"uint256\"\n                        }\n                      },\n                      \"visibility\": \"internal\"\n                    }\n                  ],\n                  \"id\": 10,\n                  \"initialValue\": {\n                    \"hexValue\": \"30\",\n                    \"id\": 9,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"kind\": \"number\",\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"140:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_rational_0_by_1\",\n                      \"typeString\": \"int_const 0\"\n                    },\n                    \"value\": \"0\"\n                  },\n                  \"nodeType\": \"VariableDeclarationStatement\",\n                  \"src\": \"131:10:1\"\n                },\n                \"isSimpleCounterLoop\": true,\n                \"loopExpression\": {\n                  \"expression\": {\n                    \"id\": 15,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"UnaryOperation\",\n                    \"operator\": \"++\",\n                    \"prefix\": false,\n                    \"src\": \"151:3:1\",\n                    \"subExpression\": {\n                      \"id\": 14,\n                      \"name\": \"i\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 8,\n                      \"src\": \"151:1:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_uint256\",\n                        \"typeString\": \"uint256\"\n                      }\n                    },\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_uint256\",\n                      \"typeString\": \"uint256\"\n                    }\n                  },\n                  \"id\": 16,\n                  \"nodeType\": \"ExpressionStatement\",\n                  \"src\": \"151:3:1\"\n                },\n                \"nodeType\": \"ForStatement\",\n                \"src\": \"126:96:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 23,\n                  \"name\": \"x\",\n                  \"nodeType\": \"Identifier\",\n                  \"overloadedDeclarations\": [],\n                  \"referencedDeclaration\": 5,\n                  \"src\": \"320:1:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"functionReturnParameters\": 6,\n                \"id\": 24,\n                \"nodeType\": \"Return\",\n                \"src\": \"313:8:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 26,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"66:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"67:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 6,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 5,\n                \"mutability\": \"mutable\",\n                \"name\": \"x\",\n                \"nameLocation\": \"96:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 26,\n                \"src\": \"91:6:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                },\n                \"typeName\": {\n                  \"id\": 4,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"91:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"90:8:1\"\n          },\n          \"scope\": 27,\n          \"src\": \"57:271:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 28,\n      \"src\": \"0:330:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:331:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation_on_statements.sol",
    "content": "contract C {\n    // this is not exported\n    uint a;\n    function f() public pure returns (uint x) {\n        // test2\n        for (uint i = 0; i < 20; i++) {\n            // not exported either\n            x *= 2;\n        }\n        // nor is this because they are all\n        // not using the triple-slash\n        return x;\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation_on_statements_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 28,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 27,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 2,\n          \"mutability\": \"mutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"50:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"45:6:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 1,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"45:4:1\",\n            \"typeDescriptions\": {}\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 25,\n            \"nodeType\": \"Block\",\n            \"src\": \"99:229:1\",\n            \"statements\": [\n              {\n                \"body\": {\n                  \"id\": 21,\n                  \"nodeType\": \"Block\",\n                  \"src\": \"156:66:1\",\n                  \"statements\": [\n                    {\n                      \"expression\": {\n                        \"id\": 19,\n                        \"leftHandSide\": {\n                          \"id\": 17,\n                          \"name\": \"x\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"src\": \"205:1:1\",\n                          \"typeDescriptions\": {}\n                        },\n                        \"nodeType\": \"Assignment\",\n                        \"operator\": \"*=\",\n                        \"rightHandSide\": {\n                          \"hexValue\": \"32\",\n                          \"id\": 18,\n                          \"kind\": \"number\",\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"210:1:1\",\n                          \"typeDescriptions\": {},\n                          \"value\": \"2\"\n                        },\n                        \"src\": \"205:6:1\",\n                        \"typeDescriptions\": {}\n                      },\n                      \"id\": 20,\n                      \"nodeType\": \"ExpressionStatement\",\n                      \"src\": \"205:6:1\"\n                    }\n                  ]\n                },\n                \"condition\": {\n                  \"commonType\": {},\n                  \"id\": 13,\n                  \"leftExpression\": {\n                    \"id\": 11,\n                    \"name\": \"i\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"143:1:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"nodeType\": \"BinaryOperation\",\n                  \"operator\": \"<\",\n                  \"rightExpression\": {\n                    \"hexValue\": \"3230\",\n                    \"id\": 12,\n                    \"kind\": \"number\",\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"147:2:1\",\n                    \"typeDescriptions\": {},\n                    \"value\": \"20\"\n                  },\n                  \"src\": \"143:6:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 22,\n                \"initializationExpression\": {\n                  \"assignments\": [\n                    8\n                  ],\n                  \"declarations\": [\n                    {\n                      \"constant\": false,\n                      \"id\": 8,\n                      \"mutability\": \"mutable\",\n                      \"name\": \"i\",\n                      \"nameLocation\": \"136:1:1\",\n                      \"nodeType\": \"VariableDeclaration\",\n                      \"src\": \"131:6:1\",\n                      \"stateVariable\": false,\n                      \"storageLocation\": \"default\",\n                      \"typeDescriptions\": {},\n                      \"typeName\": {\n                        \"id\": 7,\n                        \"name\": \"uint\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"131:4:1\",\n                        \"typeDescriptions\": {}\n                      },\n                      \"visibility\": \"internal\"\n                    }\n                  ],\n                  \"id\": 10,\n                  \"initialValue\": {\n                    \"hexValue\": \"30\",\n                    \"id\": 9,\n                    \"kind\": \"number\",\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"140:1:1\",\n                    \"typeDescriptions\": {},\n                    \"value\": \"0\"\n                  },\n                  \"nodeType\": \"VariableDeclarationStatement\",\n                  \"src\": \"131:10:1\"\n                },\n                \"loopExpression\": {\n                  \"expression\": {\n                    \"id\": 15,\n                    \"nodeType\": \"UnaryOperation\",\n                    \"operator\": \"++\",\n                    \"prefix\": false,\n                    \"src\": \"151:3:1\",\n                    \"subExpression\": {\n                      \"id\": 14,\n                      \"name\": \"i\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"src\": \"151:1:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"typeDescriptions\": {}\n                  },\n                  \"id\": 16,\n                  \"nodeType\": \"ExpressionStatement\",\n                  \"src\": \"151:3:1\"\n                },\n                \"nodeType\": \"ForStatement\",\n                \"src\": \"126:96:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 23,\n                  \"name\": \"x\",\n                  \"nodeType\": \"Identifier\",\n                  \"overloadedDeclarations\": [],\n                  \"src\": \"320:1:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 24,\n                \"nodeType\": \"Return\",\n                \"src\": \"313:8:1\"\n              }\n            ]\n          },\n          \"id\": 26,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"66:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"67:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 6,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 5,\n                \"mutability\": \"mutable\",\n                \"name\": \"x\",\n                \"nameLocation\": \"96:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"91:6:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 4,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"91:4:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"90:8:1\"\n          },\n          \"src\": \"57:271:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:330:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:331:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation_parseOnly.json",
    "content": "[\n{\n  \"absolutePath\": \"a\",\n  \"id\": 3,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"documentation\": {\n        \"id\": 1,\n        \"nodeType\": \"StructuredDocumentation\",\n        \"src\": \"0:27:1\",\n        \"text\": \"This contract is empty\"\n      },\n      \"id\": 2,\n      \"name\": \"C\",\n      \"nameLocation\": \"37:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"28:13:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"28:14:1\"\n},\n{\n  \"absolutePath\": \"b\",\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"documentation\": {\n        \"id\": 4,\n        \"nodeType\": \"StructuredDocumentation\",\n        \"src\": \"0:61:2\",\n        \"text\": \"This contract is empty\\nand has a line-breaking comment.\"\n      },\n      \"id\": 5,\n      \"name\": \"C\",\n      \"nameLocation\": \"71:1:2\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"62:13:2\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"62:14:2\"\n},\n{\n  \"absolutePath\": \"c\",\n  \"id\": 24,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 23,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:3\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 9,\n          \"mutability\": \"mutable\",\n          \"name\": \"state\",\n          \"nameLocation\": \"60:5:3\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"48:17:3\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 8,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"48:4:3\",\n            \"typeDescriptions\": {}\n          },\n          \"visibility\": \"public\"\n        },\n        {\n          \"anonymous\": false,\n          \"documentation\": {\n            \"id\": 10,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"69:26:3\",\n            \"text\": \"Some comment on Evt.\"\n          },\n          \"id\": 12,\n          \"name\": \"Evt\",\n          \"nameLocation\": \"102:3:3\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"105:2:3\"\n          },\n          \"src\": \"96:12:3\"\n        },\n        {\n          \"body\": {\n            \"id\": 16,\n            \"nodeType\": \"Block\",\n            \"src\": \"153:6:3\",\n            \"statements\": [\n              {\n                \"id\": 15,\n                \"nodeType\": \"PlaceholderStatement\",\n                \"src\": \"155:1:3\"\n              }\n            ]\n          },\n          \"documentation\": {\n            \"id\": 13,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"111:26:3\",\n            \"text\": \"Some comment on mod.\"\n          },\n          \"id\": 17,\n          \"name\": \"mod\",\n          \"nameLocation\": \"147:3:3\",\n          \"nodeType\": \"ModifierDefinition\",\n          \"parameters\": {\n            \"id\": 14,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"150:2:3\"\n          },\n          \"src\": \"138:21:3\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 21,\n            \"nodeType\": \"Block\",\n            \"src\": \"209:2:3\",\n            \"statements\": []\n          },\n          \"documentation\": {\n            \"id\": 18,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"162:25:3\",\n            \"text\": \"Some comment on fn.\"\n          },\n          \"id\": 22,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"fn\",\n          \"nameLocation\": \"197:2:3\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 19,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"199:2:3\"\n          },\n          \"returnParameters\": {\n            \"id\": 20,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"209:0:3\"\n          },\n          \"src\": \"188:23:3\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:213:3\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:214:3\"\n}\n]\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation_triple.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      28\n    ]\n  },\n  \"id\": 29,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 28,\n      \"linearizedBaseContracts\": [\n        28\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"documentation\": {\n            \"id\": 1,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"17:8:1\",\n            \"text\": \"test\"\n          },\n          \"id\": 3,\n          \"mutability\": \"mutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"35:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 28,\n          \"src\": \"30:6:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_uint256\",\n            \"typeString\": \"uint256\"\n          },\n          \"typeName\": {\n            \"id\": 2,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"30:4:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_uint256\",\n              \"typeString\": \"uint256\"\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 26,\n            \"nodeType\": \"Block\",\n            \"src\": \"84:181:1\",\n            \"statements\": [\n              {\n                \"body\": {\n                  \"id\": 22,\n                  \"nodeType\": \"Block\",\n                  \"src\": \"142:75:1\",\n                  \"statements\": [\n                    {\n                      \"documentation\": \"tee\\n s \\\"t\\\" 3\",\n                      \"expression\": {\n                        \"id\": 20,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": false,\n                        \"lValueRequested\": false,\n                        \"leftHandSide\": {\n                          \"id\": 18,\n                          \"name\": \"x\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"referencedDeclaration\": 6,\n                          \"src\": \"200:1:1\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_uint256\",\n                            \"typeString\": \"uint256\"\n                          }\n                        },\n                        \"nodeType\": \"Assignment\",\n                        \"operator\": \"*=\",\n                        \"rightHandSide\": {\n                          \"hexValue\": \"32\",\n                          \"id\": 19,\n                          \"isConstant\": false,\n                          \"isLValue\": false,\n                          \"isPure\": true,\n                          \"kind\": \"number\",\n                          \"lValueRequested\": false,\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"205:1:1\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_rational_2_by_1\",\n                            \"typeString\": \"int_const 2\"\n                          },\n                          \"value\": \"2\"\n                        },\n                        \"src\": \"200:6:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_uint256\",\n                          \"typeString\": \"uint256\"\n                        }\n                      },\n                      \"id\": 21,\n                      \"nodeType\": \"ExpressionStatement\",\n                      \"src\": \"200:6:1\"\n                    }\n                  ]\n                },\n                \"condition\": {\n                  \"commonType\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  },\n                  \"id\": 14,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"leftExpression\": {\n                    \"id\": 12,\n                    \"name\": \"i\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 9,\n                    \"src\": \"129:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_uint256\",\n                      \"typeString\": \"uint256\"\n                    }\n                  },\n                  \"nodeType\": \"BinaryOperation\",\n                  \"operator\": \"<\",\n                  \"rightExpression\": {\n                    \"hexValue\": \"3230\",\n                    \"id\": 13,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"kind\": \"number\",\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"133:2:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_rational_20_by_1\",\n                      \"typeString\": \"int_const 20\"\n                    },\n                    \"value\": \"20\"\n                  },\n                  \"src\": \"129:6:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_bool\",\n                    \"typeString\": \"bool\"\n                  }\n                },\n                \"documentation\": \"test2\",\n                \"id\": 23,\n                \"initializationExpression\": {\n                  \"assignments\": [\n                    9\n                  ],\n                  \"declarations\": [\n                    {\n                      \"constant\": false,\n                      \"id\": 9,\n                      \"mutability\": \"mutable\",\n                      \"name\": \"i\",\n                      \"nameLocation\": \"122:1:1\",\n                      \"nodeType\": \"VariableDeclaration\",\n                      \"scope\": 23,\n                      \"src\": \"117:6:1\",\n                      \"stateVariable\": false,\n                      \"storageLocation\": \"default\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_uint256\",\n                        \"typeString\": \"uint256\"\n                      },\n                      \"typeName\": {\n                        \"id\": 8,\n                        \"name\": \"uint\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"117:4:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_uint256\",\n                          \"typeString\": \"uint256\"\n                        }\n                      },\n                      \"visibility\": \"internal\"\n                    }\n                  ],\n                  \"id\": 11,\n                  \"initialValue\": {\n                    \"hexValue\": \"30\",\n                    \"id\": 10,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"kind\": \"number\",\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"126:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_rational_0_by_1\",\n                      \"typeString\": \"int_const 0\"\n                    },\n                    \"value\": \"0\"\n                  },\n                  \"nodeType\": \"VariableDeclarationStatement\",\n                  \"src\": \"117:10:1\"\n                },\n                \"isSimpleCounterLoop\": true,\n                \"loopExpression\": {\n                  \"expression\": {\n                    \"id\": 16,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"UnaryOperation\",\n                    \"operator\": \"++\",\n                    \"prefix\": false,\n                    \"src\": \"137:3:1\",\n                    \"subExpression\": {\n                      \"id\": 15,\n                      \"name\": \"i\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 9,\n                      \"src\": \"137:1:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_uint256\",\n                        \"typeString\": \"uint256\"\n                      }\n                    },\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_uint256\",\n                      \"typeString\": \"uint256\"\n                    }\n                  },\n                  \"id\": 17,\n                  \"nodeType\": \"ExpressionStatement\",\n                  \"src\": \"137:3:1\"\n                },\n                \"nodeType\": \"ForStatement\",\n                \"src\": \"112:105:1\"\n              },\n              {\n                \"documentation\": \"tes \\\"t4\\\" \",\n                \"expression\": {\n                  \"id\": 24,\n                  \"name\": \"x\",\n                  \"nodeType\": \"Identifier\",\n                  \"overloadedDeclarations\": [],\n                  \"referencedDeclaration\": 6,\n                  \"src\": \"257:1:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"functionReturnParameters\": 7,\n                \"id\": 25,\n                \"nodeType\": \"Return\",\n                \"src\": \"250:8:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 27,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"51:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 4,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"52:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 6,\n                \"mutability\": \"mutable\",\n                \"name\": \"x\",\n                \"nameLocation\": \"81:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 27,\n                \"src\": \"76:6:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                },\n                \"typeName\": {\n                  \"id\": 5,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"76:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"75:8:1\"\n          },\n          \"scope\": 28,\n          \"src\": \"42:223:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 29,\n      \"src\": \"0:267:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:268:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation_triple.sol",
    "content": "contract C {\n    /// test\n    uint a;\n    function f() public pure returns (uint x) {\n        /// test2\n        for (uint i = 0; i < 20; i++) {\n            /// tee\n            /// s \"t\" 3\n            x *= 2;\n        }\n        /** tes \"t4\" */\n        return x;\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/documentation_triple_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 29,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 28,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 3,\n          \"mutability\": \"mutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"35:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"30:6:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 2,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"30:4:1\",\n            \"typeDescriptions\": {}\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 26,\n            \"nodeType\": \"Block\",\n            \"src\": \"84:181:1\",\n            \"statements\": [\n              {\n                \"body\": {\n                  \"id\": 22,\n                  \"nodeType\": \"Block\",\n                  \"src\": \"142:75:1\",\n                  \"statements\": [\n                    {\n                      \"documentation\": \"tee\\n s \\\"t\\\" 3\",\n                      \"expression\": {\n                        \"id\": 20,\n                        \"leftHandSide\": {\n                          \"id\": 18,\n                          \"name\": \"x\",\n                          \"nodeType\": \"Identifier\",\n                          \"overloadedDeclarations\": [],\n                          \"src\": \"200:1:1\",\n                          \"typeDescriptions\": {}\n                        },\n                        \"nodeType\": \"Assignment\",\n                        \"operator\": \"*=\",\n                        \"rightHandSide\": {\n                          \"hexValue\": \"32\",\n                          \"id\": 19,\n                          \"kind\": \"number\",\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"205:1:1\",\n                          \"typeDescriptions\": {},\n                          \"value\": \"2\"\n                        },\n                        \"src\": \"200:6:1\",\n                        \"typeDescriptions\": {}\n                      },\n                      \"id\": 21,\n                      \"nodeType\": \"ExpressionStatement\",\n                      \"src\": \"200:6:1\"\n                    }\n                  ]\n                },\n                \"condition\": {\n                  \"commonType\": {},\n                  \"id\": 14,\n                  \"leftExpression\": {\n                    \"id\": 12,\n                    \"name\": \"i\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"129:1:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"nodeType\": \"BinaryOperation\",\n                  \"operator\": \"<\",\n                  \"rightExpression\": {\n                    \"hexValue\": \"3230\",\n                    \"id\": 13,\n                    \"kind\": \"number\",\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"133:2:1\",\n                    \"typeDescriptions\": {},\n                    \"value\": \"20\"\n                  },\n                  \"src\": \"129:6:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"documentation\": \"test2\",\n                \"id\": 23,\n                \"initializationExpression\": {\n                  \"assignments\": [\n                    9\n                  ],\n                  \"declarations\": [\n                    {\n                      \"constant\": false,\n                      \"id\": 9,\n                      \"mutability\": \"mutable\",\n                      \"name\": \"i\",\n                      \"nameLocation\": \"122:1:1\",\n                      \"nodeType\": \"VariableDeclaration\",\n                      \"src\": \"117:6:1\",\n                      \"stateVariable\": false,\n                      \"storageLocation\": \"default\",\n                      \"typeDescriptions\": {},\n                      \"typeName\": {\n                        \"id\": 8,\n                        \"name\": \"uint\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"117:4:1\",\n                        \"typeDescriptions\": {}\n                      },\n                      \"visibility\": \"internal\"\n                    }\n                  ],\n                  \"id\": 11,\n                  \"initialValue\": {\n                    \"hexValue\": \"30\",\n                    \"id\": 10,\n                    \"kind\": \"number\",\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"126:1:1\",\n                    \"typeDescriptions\": {},\n                    \"value\": \"0\"\n                  },\n                  \"nodeType\": \"VariableDeclarationStatement\",\n                  \"src\": \"117:10:1\"\n                },\n                \"loopExpression\": {\n                  \"expression\": {\n                    \"id\": 16,\n                    \"nodeType\": \"UnaryOperation\",\n                    \"operator\": \"++\",\n                    \"prefix\": false,\n                    \"src\": \"137:3:1\",\n                    \"subExpression\": {\n                      \"id\": 15,\n                      \"name\": \"i\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"src\": \"137:1:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"typeDescriptions\": {}\n                  },\n                  \"id\": 17,\n                  \"nodeType\": \"ExpressionStatement\",\n                  \"src\": \"137:3:1\"\n                },\n                \"nodeType\": \"ForStatement\",\n                \"src\": \"112:105:1\"\n              },\n              {\n                \"documentation\": \"tes \\\"t4\\\" \",\n                \"expression\": {\n                  \"id\": 24,\n                  \"name\": \"x\",\n                  \"nodeType\": \"Identifier\",\n                  \"overloadedDeclarations\": [],\n                  \"src\": \"257:1:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 25,\n                \"nodeType\": \"Return\",\n                \"src\": \"250:8:1\"\n              }\n            ]\n          },\n          \"id\": 27,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"51:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 4,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"52:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 6,\n                \"mutability\": \"mutable\",\n                \"name\": \"x\",\n                \"nameLocation\": \"81:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"76:6:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 5,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"76:4:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"75:8:1\"\n          },\n          \"src\": \"42:223:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:267:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:268:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/emit_event_from_module_via_member_access.json",
    "content": "[\n{\n  \"absolutePath\": \"A.sol\",\n  \"exportedSymbols\": {\n    \"AContract\": [\n      17\n    ],\n    \"TransferA\": [\n      8\n    ]\n  },\n  \"id\": 18,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"anonymous\": false,\n      \"eventSelector\": \"ef0684aa87ada311bea2dad2b653ce28cd604aa1c10a123df8fb2f789c3178f0\",\n      \"id\": 8,\n      \"name\": \"TransferA\",\n      \"nameLocation\": \"6:9:1\",\n      \"nodeType\": \"EventDefinition\",\n      \"parameters\": {\n        \"id\": 7,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [\n          {\n            \"constant\": false,\n            \"id\": 2,\n            \"indexed\": true,\n            \"mutability\": \"mutable\",\n            \"name\": \"from\",\n            \"nameLocation\": \"32:4:1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"scope\": 8,\n            \"src\": \"16:20:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_address\",\n              \"typeString\": \"address\"\n            },\n            \"typeName\": {\n              \"id\": 1,\n              \"name\": \"address\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"16:7:1\",\n              \"stateMutability\": \"nonpayable\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_address\",\n                \"typeString\": \"address\"\n              }\n            },\n            \"visibility\": \"internal\"\n          },\n          {\n            \"constant\": false,\n            \"id\": 4,\n            \"indexed\": true,\n            \"mutability\": \"mutable\",\n            \"name\": \"to\",\n            \"nameLocation\": \"54:2:1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"scope\": 8,\n            \"src\": \"38:18:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_address\",\n              \"typeString\": \"address\"\n            },\n            \"typeName\": {\n              \"id\": 3,\n              \"name\": \"address\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"38:7:1\",\n              \"stateMutability\": \"nonpayable\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_address\",\n                \"typeString\": \"address\"\n              }\n            },\n            \"visibility\": \"internal\"\n          },\n          {\n            \"constant\": false,\n            \"id\": 6,\n            \"indexed\": false,\n            \"mutability\": \"mutable\",\n            \"name\": \"amount\",\n            \"nameLocation\": \"63:6:1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"scope\": 8,\n            \"src\": \"58:11:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_uint256\",\n              \"typeString\": \"uint256\"\n            },\n            \"typeName\": {\n              \"id\": 5,\n              \"name\": \"uint\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"58:4:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_uint256\",\n                \"typeString\": \"uint256\"\n              }\n            },\n            \"visibility\": \"internal\"\n          }\n        ],\n        \"src\": \"15:55:1\"\n      },\n      \"src\": \"0:71:1\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"AContract\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 17,\n      \"linearizedBaseContracts\": [\n        17\n      ],\n      \"name\": \"AContract\",\n      \"nameLocation\": \"81:9:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"eventSelector\": \"665f5beb8eab22c2d0fba9f14e33a83ad719ffbed2f484458c23490e8577adc9\",\n          \"id\": 16,\n          \"name\": \"TransferAContract\",\n          \"nameLocation\": \"103:17:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 15,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 10,\n                \"indexed\": true,\n                \"mutability\": \"mutable\",\n                \"name\": \"from\",\n                \"nameLocation\": \"137:4:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 16,\n                \"src\": \"121:20:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_address\",\n                  \"typeString\": \"address\"\n                },\n                \"typeName\": {\n                  \"id\": 9,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"121:7:1\",\n                  \"stateMutability\": \"nonpayable\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address\",\n                    \"typeString\": \"address\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              },\n              {\n                \"constant\": false,\n                \"id\": 12,\n                \"indexed\": true,\n                \"mutability\": \"mutable\",\n                \"name\": \"to\",\n                \"nameLocation\": \"159:2:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 16,\n                \"src\": \"143:18:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_address\",\n                  \"typeString\": \"address\"\n                },\n                \"typeName\": {\n                  \"id\": 11,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"143:7:1\",\n                  \"stateMutability\": \"nonpayable\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address\",\n                    \"typeString\": \"address\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              },\n              {\n                \"constant\": false,\n                \"id\": 14,\n                \"indexed\": false,\n                \"mutability\": \"mutable\",\n                \"name\": \"amount\",\n                \"nameLocation\": \"168:6:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 16,\n                \"src\": \"163:11:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                },\n                \"typeName\": {\n                  \"id\": 13,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"163:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"120:55:1\"\n          },\n          \"src\": \"97:79:1\"\n        }\n      ],\n      \"scope\": 18,\n      \"src\": \"72:106:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        16\n      ]\n    }\n  ],\n  \"src\": \"0:179:1\"\n},\n{\n  \"absolutePath\": \"ERC20.sol\",\n  \"exportedSymbols\": {\n    \"A\": [\n      19\n    ],\n    \"ERC20\": [\n      74\n    ]\n  },\n  \"id\": 75,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"absolutePath\": \"A.sol\",\n      \"file\": \"A.sol\",\n      \"id\": 19,\n      \"nameLocation\": \"12:1:2\",\n      \"nodeType\": \"ImportDirective\",\n      \"scope\": 75,\n      \"sourceUnit\": 18,\n      \"src\": \"0:27:2\",\n      \"symbolAliases\": [],\n      \"unitAlias\": \"A\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"ERC20\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 74,\n      \"linearizedBaseContracts\": [\n        74\n      ],\n      \"name\": \"ERC20\",\n      \"nameLocation\": \"37:5:2\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"eventSelector\": \"ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\n          \"id\": 27,\n          \"name\": \"Transfer\",\n          \"nameLocation\": \"55:8:2\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 26,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 21,\n                \"indexed\": true,\n                \"mutability\": \"mutable\",\n                \"name\": \"from\",\n                \"nameLocation\": \"80:4:2\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 27,\n                \"src\": \"64:20:2\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_address\",\n                  \"typeString\": \"address\"\n                },\n                \"typeName\": {\n                  \"id\": 20,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"64:7:2\",\n                  \"stateMutability\": \"nonpayable\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address\",\n                    \"typeString\": \"address\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              },\n              {\n                \"constant\": false,\n                \"id\": 23,\n                \"indexed\": true,\n                \"mutability\": \"mutable\",\n                \"name\": \"to\",\n                \"nameLocation\": \"102:2:2\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 27,\n                \"src\": \"86:18:2\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_address\",\n                  \"typeString\": \"address\"\n                },\n                \"typeName\": {\n                  \"id\": 22,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"86:7:2\",\n                  \"stateMutability\": \"nonpayable\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address\",\n                    \"typeString\": \"address\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              },\n              {\n                \"constant\": false,\n                \"id\": 25,\n                \"indexed\": false,\n                \"mutability\": \"mutable\",\n                \"name\": \"amount\",\n                \"nameLocation\": \"111:6:2\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 27,\n                \"src\": \"106:11:2\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                },\n                \"typeName\": {\n                  \"id\": 24,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"106:4:2\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"63:55:2\"\n          },\n          \"src\": \"49:70:2\"\n        },\n        {\n          \"body\": {\n            \"id\": 72,\n            \"nodeType\": \"Block\",\n            \"src\": \"145:181:2\",\n            \"statements\": [\n              {\n                \"eventCall\": {\n                  \"arguments\": [\n                    {\n                      \"arguments\": [\n                        {\n                          \"hexValue\": \"31\",\n                          \"id\": 33,\n                          \"isConstant\": false,\n                          \"isLValue\": false,\n                          \"isPure\": true,\n                          \"kind\": \"number\",\n                          \"lValueRequested\": false,\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"177:1:2\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_rational_1_by_1\",\n                            \"typeString\": \"int_const 1\"\n                          },\n                          \"value\": \"1\"\n                        }\n                      ],\n                      \"expression\": {\n                        \"argumentTypes\": [\n                          {\n                            \"typeIdentifier\": \"t_rational_1_by_1\",\n                            \"typeString\": \"int_const 1\"\n                          }\n                        ],\n                        \"id\": 32,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": true,\n                        \"lValueRequested\": false,\n                        \"nodeType\": \"ElementaryTypeNameExpression\",\n                        \"src\": \"169:7:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_type$_t_address_$\",\n                          \"typeString\": \"type(address)\"\n                        },\n                        \"typeName\": {\n                          \"id\": 31,\n                          \"name\": \"address\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"169:7:2\",\n                          \"typeDescriptions\": {}\n                        }\n                      },\n                      \"id\": 34,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"typeConversion\",\n                      \"lValueRequested\": false,\n                      \"nameLocations\": [],\n                      \"names\": [],\n                      \"nodeType\": \"FunctionCall\",\n                      \"src\": \"169:10:2\",\n                      \"tryCall\": false,\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      }\n                    },\n                    {\n                      \"arguments\": [\n                        {\n                          \"hexValue\": \"32\",\n                          \"id\": 37,\n                          \"isConstant\": false,\n                          \"isLValue\": false,\n                          \"isPure\": true,\n                          \"kind\": \"number\",\n                          \"lValueRequested\": false,\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"189:1:2\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_rational_2_by_1\",\n                            \"typeString\": \"int_const 2\"\n                          },\n                          \"value\": \"2\"\n                        }\n                      ],\n                      \"expression\": {\n                        \"argumentTypes\": [\n                          {\n                            \"typeIdentifier\": \"t_rational_2_by_1\",\n                            \"typeString\": \"int_const 2\"\n                          }\n                        ],\n                        \"id\": 36,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": true,\n                        \"lValueRequested\": false,\n                        \"nodeType\": \"ElementaryTypeNameExpression\",\n                        \"src\": \"181:7:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_type$_t_address_$\",\n                          \"typeString\": \"type(address)\"\n                        },\n                        \"typeName\": {\n                          \"id\": 35,\n                          \"name\": \"address\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"181:7:2\",\n                          \"typeDescriptions\": {}\n                        }\n                      },\n                      \"id\": 38,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"typeConversion\",\n                      \"lValueRequested\": false,\n                      \"nameLocations\": [],\n                      \"names\": [],\n                      \"nodeType\": \"FunctionCall\",\n                      \"src\": \"181:10:2\",\n                      \"tryCall\": false,\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      }\n                    },\n                    {\n                      \"hexValue\": \"33\",\n                      \"id\": 39,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"number\",\n                      \"lValueRequested\": false,\n                      \"nodeType\": \"Literal\",\n                      \"src\": \"193:1:2\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_rational_3_by_1\",\n                        \"typeString\": \"int_const 3\"\n                      },\n                      \"value\": \"3\"\n                    }\n                  ],\n                  \"expression\": {\n                    \"argumentTypes\": [\n                      {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      },\n                      {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      },\n                      {\n                        \"typeIdentifier\": \"t_rational_3_by_1\",\n                        \"typeString\": \"int_const 3\"\n                      }\n                    ],\n                    \"id\": 30,\n                    \"name\": \"Transfer\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 27,\n                    \"src\": \"160:8:2\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$\",\n                      \"typeString\": \"function (address,address,uint256)\"\n                    }\n                  },\n                  \"id\": 40,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"160:35:2\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 41,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"155:40:2\"\n              },\n              {\n                \"eventCall\": {\n                  \"arguments\": [\n                    {\n                      \"arguments\": [\n                        {\n                          \"hexValue\": \"31\",\n                          \"id\": 47,\n                          \"isConstant\": false,\n                          \"isLValue\": false,\n                          \"isPure\": true,\n                          \"kind\": \"number\",\n                          \"lValueRequested\": false,\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"230:1:2\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_rational_1_by_1\",\n                            \"typeString\": \"int_const 1\"\n                          },\n                          \"value\": \"1\"\n                        }\n                      ],\n                      \"expression\": {\n                        \"argumentTypes\": [\n                          {\n                            \"typeIdentifier\": \"t_rational_1_by_1\",\n                            \"typeString\": \"int_const 1\"\n                          }\n                        ],\n                        \"id\": 46,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": true,\n                        \"lValueRequested\": false,\n                        \"nodeType\": \"ElementaryTypeNameExpression\",\n                        \"src\": \"222:7:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_type$_t_address_$\",\n                          \"typeString\": \"type(address)\"\n                        },\n                        \"typeName\": {\n                          \"id\": 45,\n                          \"name\": \"address\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"222:7:2\",\n                          \"typeDescriptions\": {}\n                        }\n                      },\n                      \"id\": 48,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"typeConversion\",\n                      \"lValueRequested\": false,\n                      \"nameLocations\": [],\n                      \"names\": [],\n                      \"nodeType\": \"FunctionCall\",\n                      \"src\": \"222:10:2\",\n                      \"tryCall\": false,\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      }\n                    },\n                    {\n                      \"arguments\": [\n                        {\n                          \"hexValue\": \"32\",\n                          \"id\": 51,\n                          \"isConstant\": false,\n                          \"isLValue\": false,\n                          \"isPure\": true,\n                          \"kind\": \"number\",\n                          \"lValueRequested\": false,\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"242:1:2\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_rational_2_by_1\",\n                            \"typeString\": \"int_const 2\"\n                          },\n                          \"value\": \"2\"\n                        }\n                      ],\n                      \"expression\": {\n                        \"argumentTypes\": [\n                          {\n                            \"typeIdentifier\": \"t_rational_2_by_1\",\n                            \"typeString\": \"int_const 2\"\n                          }\n                        ],\n                        \"id\": 50,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": true,\n                        \"lValueRequested\": false,\n                        \"nodeType\": \"ElementaryTypeNameExpression\",\n                        \"src\": \"234:7:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_type$_t_address_$\",\n                          \"typeString\": \"type(address)\"\n                        },\n                        \"typeName\": {\n                          \"id\": 49,\n                          \"name\": \"address\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"234:7:2\",\n                          \"typeDescriptions\": {}\n                        }\n                      },\n                      \"id\": 52,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"typeConversion\",\n                      \"lValueRequested\": false,\n                      \"nameLocations\": [],\n                      \"names\": [],\n                      \"nodeType\": \"FunctionCall\",\n                      \"src\": \"234:10:2\",\n                      \"tryCall\": false,\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      }\n                    },\n                    {\n                      \"hexValue\": \"33\",\n                      \"id\": 53,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"number\",\n                      \"lValueRequested\": false,\n                      \"nodeType\": \"Literal\",\n                      \"src\": \"246:1:2\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_rational_3_by_1\",\n                        \"typeString\": \"int_const 3\"\n                      },\n                      \"value\": \"3\"\n                    }\n                  ],\n                  \"expression\": {\n                    \"argumentTypes\": [\n                      {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      },\n                      {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      },\n                      {\n                        \"typeIdentifier\": \"t_rational_3_by_1\",\n                        \"typeString\": \"int_const 3\"\n                      }\n                    ],\n                    \"expression\": {\n                      \"id\": 42,\n                      \"name\": \"A\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 19,\n                      \"src\": \"210:1:2\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_module_18\",\n                        \"typeString\": \"module \\\"A.sol\\\"\"\n                      }\n                    },\n                    \"id\": 44,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"lValueRequested\": false,\n                    \"memberLocation\": \"212:9:2\",\n                    \"memberName\": \"TransferA\",\n                    \"nodeType\": \"MemberAccess\",\n                    \"referencedDeclaration\": 8,\n                    \"src\": \"210:11:2\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$\",\n                      \"typeString\": \"function (address,address,uint256)\"\n                    }\n                  },\n                  \"id\": 54,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"210:38:2\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 55,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"205:43:2\"\n              },\n              {\n                \"eventCall\": {\n                  \"arguments\": [\n                    {\n                      \"arguments\": [\n                        {\n                          \"hexValue\": \"31\",\n                          \"id\": 63,\n                          \"isConstant\": false,\n                          \"isLValue\": false,\n                          \"isPure\": true,\n                          \"kind\": \"number\",\n                          \"lValueRequested\": false,\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"301:1:2\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_rational_1_by_1\",\n                            \"typeString\": \"int_const 1\"\n                          },\n                          \"value\": \"1\"\n                        }\n                      ],\n                      \"expression\": {\n                        \"argumentTypes\": [\n                          {\n                            \"typeIdentifier\": \"t_rational_1_by_1\",\n                            \"typeString\": \"int_const 1\"\n                          }\n                        ],\n                        \"id\": 62,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": true,\n                        \"lValueRequested\": false,\n                        \"nodeType\": \"ElementaryTypeNameExpression\",\n                        \"src\": \"293:7:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_type$_t_address_$\",\n                          \"typeString\": \"type(address)\"\n                        },\n                        \"typeName\": {\n                          \"id\": 61,\n                          \"name\": \"address\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"293:7:2\",\n                          \"typeDescriptions\": {}\n                        }\n                      },\n                      \"id\": 64,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"typeConversion\",\n                      \"lValueRequested\": false,\n                      \"nameLocations\": [],\n                      \"names\": [],\n                      \"nodeType\": \"FunctionCall\",\n                      \"src\": \"293:10:2\",\n                      \"tryCall\": false,\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      }\n                    },\n                    {\n                      \"arguments\": [\n                        {\n                          \"hexValue\": \"32\",\n                          \"id\": 67,\n                          \"isConstant\": false,\n                          \"isLValue\": false,\n                          \"isPure\": true,\n                          \"kind\": \"number\",\n                          \"lValueRequested\": false,\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"313:1:2\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_rational_2_by_1\",\n                            \"typeString\": \"int_const 2\"\n                          },\n                          \"value\": \"2\"\n                        }\n                      ],\n                      \"expression\": {\n                        \"argumentTypes\": [\n                          {\n                            \"typeIdentifier\": \"t_rational_2_by_1\",\n                            \"typeString\": \"int_const 2\"\n                          }\n                        ],\n                        \"id\": 66,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": true,\n                        \"lValueRequested\": false,\n                        \"nodeType\": \"ElementaryTypeNameExpression\",\n                        \"src\": \"305:7:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_type$_t_address_$\",\n                          \"typeString\": \"type(address)\"\n                        },\n                        \"typeName\": {\n                          \"id\": 65,\n                          \"name\": \"address\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"305:7:2\",\n                          \"typeDescriptions\": {}\n                        }\n                      },\n                      \"id\": 68,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"typeConversion\",\n                      \"lValueRequested\": false,\n                      \"nameLocations\": [],\n                      \"names\": [],\n                      \"nodeType\": \"FunctionCall\",\n                      \"src\": \"305:10:2\",\n                      \"tryCall\": false,\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      }\n                    },\n                    {\n                      \"hexValue\": \"33\",\n                      \"id\": 69,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"number\",\n                      \"lValueRequested\": false,\n                      \"nodeType\": \"Literal\",\n                      \"src\": \"317:1:2\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_rational_3_by_1\",\n                        \"typeString\": \"int_const 3\"\n                      },\n                      \"value\": \"3\"\n                    }\n                  ],\n                  \"expression\": {\n                    \"argumentTypes\": [\n                      {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      },\n                      {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      },\n                      {\n                        \"typeIdentifier\": \"t_rational_3_by_1\",\n                        \"typeString\": \"int_const 3\"\n                      }\n                    ],\n                    \"expression\": {\n                      \"expression\": {\n                        \"id\": 56,\n                        \"name\": \"A\",\n                        \"nodeType\": \"Identifier\",\n                        \"overloadedDeclarations\": [],\n                        \"referencedDeclaration\": 19,\n                        \"src\": \"263:1:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_module_18\",\n                          \"typeString\": \"module \\\"A.sol\\\"\"\n                        }\n                      },\n                      \"id\": 59,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"lValueRequested\": false,\n                      \"memberLocation\": \"265:9:2\",\n                      \"memberName\": \"AContract\",\n                      \"nodeType\": \"MemberAccess\",\n                      \"referencedDeclaration\": 17,\n                      \"src\": \"263:11:2\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_type$_t_contract$_AContract_$17_$\",\n                        \"typeString\": \"type(contract AContract)\"\n                      }\n                    },\n                    \"id\": 60,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"memberLocation\": \"275:17:2\",\n                    \"memberName\": \"TransferAContract\",\n                    \"nodeType\": \"MemberAccess\",\n                    \"referencedDeclaration\": 16,\n                    \"src\": \"263:29:2\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$\",\n                      \"typeString\": \"function (address,address,uint256)\"\n                    }\n                  },\n                  \"id\": 70,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"263:56:2\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 71,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"258:61:2\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 73,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"133:1:2\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 28,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"135:2:2\"\n          },\n          \"returnParameters\": {\n            \"id\": 29,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"145:0:2\"\n          },\n          \"scope\": 74,\n          \"src\": \"124:202:2\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 75,\n      \"src\": \"28:300:2\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        8,\n        16,\n        27\n      ]\n    }\n  ],\n  \"src\": \"0:329:2\"\n}\n]\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/emit_event_from_module_via_member_access.sol",
    "content": "==== Source: A.sol ====\nevent TransferA(address indexed from, address indexed to, uint amount);\ncontract AContract {\n    event TransferAContract(address indexed from, address indexed to, uint amount);\n}\n\n==== Source: ERC20.sol ====\nimport * as A from \"A.sol\";\ncontract ERC20 {\n    event Transfer(address indexed from, address indexed to, uint amount);\n    function f () public {\n        emit Transfer(address(1), address(2), 3);\n        emit A.TransferA(address(1), address(2), 3);\n        emit A.AContract.TransferAContract(address(1), address(2), 3);\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_natspec.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"Color\": [\n      4\n    ]\n  },\n  \"id\": 5,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"canonicalName\": \"Color\",\n      \"documentation\": {\n        \"id\": 1,\n        \"nodeType\": \"StructuredDocumentation\",\n        \"src\": \"0:112:1\",\n        \"text\": \"@title example of title\\n @author example of author\\n @notice example of notice\\n @dev example of dev\"\n      },\n      \"id\": 4,\n      \"members\": [\n        {\n          \"id\": 2,\n          \"name\": \"Red\",\n          \"nameLocation\": \"129:3:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"129:3:1\"\n        },\n        {\n          \"id\": 3,\n          \"name\": \"Green\",\n          \"nameLocation\": \"138:5:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"138:5:1\"\n        }\n      ],\n      \"name\": \"Color\",\n      \"nameLocation\": \"117:5:1\",\n      \"nodeType\": \"EnumDefinition\",\n      \"src\": \"112:33:1\"\n    }\n  ],\n  \"src\": \"112:34:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_natspec.sol",
    "content": "/// @title example of title\n/// @author example of author\n/// @notice example of notice\n/// @dev example of dev\nenum Color {\n    Red,\n    Green\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_natspec_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 5,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"documentation\": {\n        \"id\": 1,\n        \"nodeType\": \"StructuredDocumentation\",\n        \"src\": \"0:112:1\",\n        \"text\": \"@title example of title\\n @author example of author\\n @notice example of notice\\n @dev example of dev\"\n      },\n      \"id\": 4,\n      \"members\": [\n        {\n          \"id\": 2,\n          \"name\": \"Red\",\n          \"nameLocation\": \"129:3:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"129:3:1\"\n        },\n        {\n          \"id\": 3,\n          \"name\": \"Green\",\n          \"nameLocation\": \"138:5:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"138:5:1\"\n        }\n      ],\n      \"name\": \"Color\",\n      \"nameLocation\": \"117:5:1\",\n      \"nodeType\": \"EnumDefinition\",\n      \"src\": \"112:33:1\"\n    }\n  ],\n  \"src\": \"112:34:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_value.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      4\n    ]\n  },\n  \"id\": 5,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 4,\n      \"linearizedBaseContracts\": [\n        4\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"canonicalName\": \"C.E\",\n          \"id\": 3,\n          \"members\": [\n            {\n              \"id\": 1,\n              \"name\": \"A\",\n              \"nameLocation\": \"22:1:1\",\n              \"nodeType\": \"EnumValue\",\n              \"src\": \"22:1:1\"\n            },\n            {\n              \"id\": 2,\n              \"name\": \"B\",\n              \"nameLocation\": \"25:1:1\",\n              \"nodeType\": \"EnumValue\",\n              \"src\": \"25:1:1\"\n            }\n          ],\n          \"name\": \"E\",\n          \"nameLocation\": \"18:1:1\",\n          \"nodeType\": \"EnumDefinition\",\n          \"src\": \"13:15:1\"\n        }\n      ],\n      \"scope\": 5,\n      \"src\": \"0:30:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:31:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_value.sol",
    "content": "contract C { enum E { A, B } }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_value_declaration.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"A\": [\n      3\n    ],\n    \"f\": [\n      13\n    ]\n  },\n  \"id\": 14,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"canonicalName\": \"A\",\n      \"id\": 3,\n      \"members\": [\n        {\n          \"id\": 1,\n          \"name\": \"X\",\n          \"nameLocation\": \"9:1:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"9:1:1\"\n        },\n        {\n          \"id\": 2,\n          \"name\": \"Y\",\n          \"nameLocation\": \"12:1:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"12:1:1\"\n        }\n      ],\n      \"name\": \"A\",\n      \"nameLocation\": \"5:1:1\",\n      \"nodeType\": \"EnumDefinition\",\n      \"src\": \"0:15:1\"\n    },\n    {\n      \"body\": {\n        \"id\": 12,\n        \"nodeType\": \"Block\",\n        \"src\": \"46:15:1\",\n        \"statements\": [\n          {\n            \"expression\": {\n              \"expression\": {\n                \"id\": 9,\n                \"name\": \"A\",\n                \"nodeType\": \"Identifier\",\n                \"overloadedDeclarations\": [],\n                \"referencedDeclaration\": 3,\n                \"src\": \"55:1:1\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_type$_t_enum$_A_$3_$\",\n                  \"typeString\": \"type(enum A)\"\n                }\n              },\n              \"id\": 10,\n              \"isConstant\": false,\n              \"isLValue\": false,\n              \"isPure\": true,\n              \"lValueRequested\": false,\n              \"memberLocation\": \"57:1:1\",\n              \"memberName\": \"X\",\n              \"nodeType\": \"MemberAccess\",\n              \"referencedDeclaration\": 1,\n              \"src\": \"55:3:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_enum$_A_$3\",\n                \"typeString\": \"enum A\"\n              }\n            },\n            \"functionReturnParameters\": 8,\n            \"id\": 11,\n            \"nodeType\": \"Return\",\n            \"src\": \"48:10:1\"\n          }\n        ]\n      },\n      \"id\": 13,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"f\",\n      \"nameLocation\": \"25:1:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 4,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"26:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 8,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [\n          {\n            \"constant\": false,\n            \"id\": 7,\n            \"mutability\": \"mutable\",\n            \"name\": \"\",\n            \"nameLocation\": \"-1:-1:-1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"scope\": 13,\n            \"src\": \"43:1:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_enum$_A_$3\",\n              \"typeString\": \"enum A\"\n            },\n            \"typeName\": {\n              \"id\": 6,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 5,\n                \"name\": \"A\",\n                \"nameLocations\": [\n                  \"43:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 3,\n                \"src\": \"43:1:1\"\n              },\n              \"referencedDeclaration\": 3,\n              \"src\": \"43:1:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_enum$_A_$3\",\n                \"typeString\": \"enum A\"\n              }\n            },\n            \"visibility\": \"internal\"\n          }\n        ],\n        \"src\": \"42:3:1\"\n      },\n      \"scope\": 14,\n      \"src\": \"16:45:1\",\n      \"stateMutability\": \"pure\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    }\n  ],\n  \"src\": \"0:62:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_value_declaration.sol",
    "content": "enum A { X, Y }\nfunction f() pure returns (A) { return A.X; }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_value_declaration_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 14,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"id\": 3,\n      \"members\": [\n        {\n          \"id\": 1,\n          \"name\": \"X\",\n          \"nameLocation\": \"9:1:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"9:1:1\"\n        },\n        {\n          \"id\": 2,\n          \"name\": \"Y\",\n          \"nameLocation\": \"12:1:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"12:1:1\"\n        }\n      ],\n      \"name\": \"A\",\n      \"nameLocation\": \"5:1:1\",\n      \"nodeType\": \"EnumDefinition\",\n      \"src\": \"0:15:1\"\n    },\n    {\n      \"body\": {\n        \"id\": 12,\n        \"nodeType\": \"Block\",\n        \"src\": \"46:15:1\",\n        \"statements\": [\n          {\n            \"expression\": {\n              \"expression\": {\n                \"id\": 9,\n                \"name\": \"A\",\n                \"nodeType\": \"Identifier\",\n                \"overloadedDeclarations\": [],\n                \"src\": \"55:1:1\",\n                \"typeDescriptions\": {}\n              },\n              \"id\": 10,\n              \"memberLocation\": \"57:1:1\",\n              \"memberName\": \"X\",\n              \"nodeType\": \"MemberAccess\",\n              \"src\": \"55:3:1\",\n              \"typeDescriptions\": {}\n            },\n            \"id\": 11,\n            \"nodeType\": \"Return\",\n            \"src\": \"48:10:1\"\n          }\n        ]\n      },\n      \"id\": 13,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"f\",\n      \"nameLocation\": \"25:1:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 4,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"26:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 8,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [\n          {\n            \"constant\": false,\n            \"id\": 7,\n            \"mutability\": \"mutable\",\n            \"name\": \"\",\n            \"nameLocation\": \"-1:-1:-1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"src\": \"43:1:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {},\n            \"typeName\": {\n              \"id\": 6,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 5,\n                \"name\": \"A\",\n                \"nameLocations\": [\n                  \"43:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"src\": \"43:1:1\"\n              },\n              \"src\": \"43:1:1\",\n              \"typeDescriptions\": {}\n            },\n            \"visibility\": \"internal\"\n          }\n        ],\n        \"src\": \"42:3:1\"\n      },\n      \"src\": \"16:45:1\",\n      \"stateMutability\": \"pure\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    }\n  ],\n  \"src\": \"0:62:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_value_natspec.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"Color\": [\n      6\n    ]\n  },\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"canonicalName\": \"Color\",\n      \"id\": 6,\n      \"members\": [\n        {\n          \"id\": 1,\n          \"name\": \"Red\",\n          \"nameLocation\": \"17:3:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"17:3:1\"\n        },\n        {\n          \"documentation\": {\n            \"id\": 2,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"26:57:1\",\n            \"text\": \"@notice example of notice\\n @dev example of dev\"\n          },\n          \"id\": 3,\n          \"name\": \"Green\",\n          \"nameLocation\": \"88:5:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"88:5:1\"\n        },\n        {\n          \"documentation\": {\n            \"id\": 4,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"99:23:1\",\n            \"text\": \"@dev example of dev\"\n          },\n          \"id\": 5,\n          \"name\": \"Blue\",\n          \"nameLocation\": \"127:4:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"127:4:1\"\n        }\n      ],\n      \"name\": \"Color\",\n      \"nameLocation\": \"5:5:1\",\n      \"nodeType\": \"EnumDefinition\",\n      \"src\": \"0:164:1\"\n    }\n  ],\n  \"src\": \"0:165:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_value_natspec.sol",
    "content": "enum Color {\n    Red,\n    /// @notice example of notice\n    /// @dev example of dev\n    Green,\n    /// @dev example of dev\n    Blue\n    /// @dev beyond last value\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_value_natspec_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"id\": 6,\n      \"members\": [\n        {\n          \"id\": 1,\n          \"name\": \"Red\",\n          \"nameLocation\": \"17:3:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"17:3:1\"\n        },\n        {\n          \"documentation\": {\n            \"id\": 2,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"26:57:1\",\n            \"text\": \"@notice example of notice\\n @dev example of dev\"\n          },\n          \"id\": 3,\n          \"name\": \"Green\",\n          \"nameLocation\": \"88:5:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"88:5:1\"\n        },\n        {\n          \"documentation\": {\n            \"id\": 4,\n            \"nodeType\": \"StructuredDocumentation\",\n            \"src\": \"99:23:1\",\n            \"text\": \"@dev example of dev\"\n          },\n          \"id\": 5,\n          \"name\": \"Blue\",\n          \"nameLocation\": \"127:4:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"127:4:1\"\n        }\n      ],\n      \"name\": \"Color\",\n      \"nameLocation\": \"5:5:1\",\n      \"nodeType\": \"EnumDefinition\",\n      \"src\": \"0:164:1\"\n    }\n  ],\n  \"src\": \"0:165:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/enum_value_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 5,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 4,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"id\": 3,\n          \"members\": [\n            {\n              \"id\": 1,\n              \"name\": \"A\",\n              \"nameLocation\": \"22:1:1\",\n              \"nodeType\": \"EnumValue\",\n              \"src\": \"22:1:1\"\n            },\n            {\n              \"id\": 2,\n              \"name\": \"B\",\n              \"nameLocation\": \"25:1:1\",\n              \"nodeType\": \"EnumValue\",\n              \"src\": \"25:1:1\"\n            }\n          ],\n          \"name\": \"E\",\n          \"nameLocation\": \"18:1:1\",\n          \"nodeType\": \"EnumDefinition\",\n          \"src\": \"13:15:1\"\n        }\n      ],\n      \"src\": \"0:30:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:31:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/error_from_module_via_member_access.json",
    "content": "[\n{\n  \"absolutePath\": \"A.sol\",\n  \"exportedSymbols\": {\n    \"AContract\": [\n      9\n    ],\n    \"ErrorA\": [\n      4\n    ]\n  },\n  \"id\": 10,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"errorSelector\": \"23b0db14\",\n      \"id\": 4,\n      \"name\": \"ErrorA\",\n      \"nameLocation\": \"6:6:1\",\n      \"nodeType\": \"ErrorDefinition\",\n      \"parameters\": {\n        \"id\": 3,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [\n          {\n            \"constant\": false,\n            \"id\": 2,\n            \"mutability\": \"mutable\",\n            \"name\": \"msg\",\n            \"nameLocation\": \"20:3:1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"scope\": 4,\n            \"src\": \"13:10:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_string_memory_ptr\",\n              \"typeString\": \"string\"\n            },\n            \"typeName\": {\n              \"id\": 1,\n              \"name\": \"string\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"13:6:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_string_storage_ptr\",\n                \"typeString\": \"string\"\n              }\n            },\n            \"visibility\": \"internal\"\n          }\n        ],\n        \"src\": \"12:12:1\"\n      },\n      \"src\": \"0:25:1\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"AContract\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 9,\n      \"linearizedBaseContracts\": [\n        9\n      ],\n      \"name\": \"AContract\",\n      \"nameLocation\": \"35:9:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"errorSelector\": \"e00f4941\",\n          \"id\": 8,\n          \"name\": \"ErrorAContract\",\n          \"nameLocation\": \"57:14:1\",\n          \"nodeType\": \"ErrorDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 6,\n                \"mutability\": \"mutable\",\n                \"name\": \"msg\",\n                \"nameLocation\": \"79:3:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 8,\n                \"src\": \"72:10:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_string_memory_ptr\",\n                  \"typeString\": \"string\"\n                },\n                \"typeName\": {\n                  \"id\": 5,\n                  \"name\": \"string\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"72:6:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_string_storage_ptr\",\n                    \"typeString\": \"string\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"71:12:1\"\n          },\n          \"src\": \"51:33:1\"\n        }\n      ],\n      \"scope\": 10,\n      \"src\": \"26:60:1\",\n      \"usedErrors\": [\n        8\n      ],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:87:1\"\n},\n{\n  \"absolutePath\": \"B.sol\",\n  \"exportedSymbols\": {\n    \"A\": [\n      11\n    ],\n    \"BContract\": [\n      46\n    ]\n  },\n  \"id\": 47,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"absolutePath\": \"A.sol\",\n      \"file\": \"A.sol\",\n      \"id\": 11,\n      \"nameLocation\": \"12:1:2\",\n      \"nodeType\": \"ImportDirective\",\n      \"scope\": 47,\n      \"sourceUnit\": 10,\n      \"src\": \"0:27:2\",\n      \"symbolAliases\": [],\n      \"unitAlias\": \"A\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"BContract\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 46,\n      \"linearizedBaseContracts\": [\n        46\n      ],\n      \"name\": \"BContract\",\n      \"nameLocation\": \"37:9:2\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"errorSelector\": \"1e012d26\",\n          \"id\": 15,\n          \"name\": \"ErrorBContract\",\n          \"nameLocation\": \"59:14:2\",\n          \"nodeType\": \"ErrorDefinition\",\n          \"parameters\": {\n            \"id\": 14,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 13,\n                \"mutability\": \"mutable\",\n                \"name\": \"msg\",\n                \"nameLocation\": \"81:3:2\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 15,\n                \"src\": \"74:10:2\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_string_memory_ptr\",\n                  \"typeString\": \"string\"\n                },\n                \"typeName\": {\n                  \"id\": 12,\n                  \"name\": \"string\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"74:6:2\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_string_storage_ptr\",\n                    \"typeString\": \"string\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"73:12:2\"\n          },\n          \"src\": \"53:33:2\"\n        },\n        {\n          \"body\": {\n            \"id\": 22,\n            \"nodeType\": \"Block\",\n            \"src\": \"113:52:2\",\n            \"statements\": [\n              {\n                \"errorCall\": {\n                  \"arguments\": [\n                    {\n                      \"hexValue\": \"736f6d65206572726f72\",\n                      \"id\": 19,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"string\",\n                      \"lValueRequested\": false,\n                      \"nodeType\": \"Literal\",\n                      \"src\": \"145:12:2\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577\",\n                        \"typeString\": \"literal_string \\\"some error\\\"\"\n                      },\n                      \"value\": \"some error\"\n                    }\n                  ],\n                  \"expression\": {\n                    \"argumentTypes\": [\n                      {\n                        \"typeIdentifier\": \"t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577\",\n                        \"typeString\": \"literal_string \\\"some error\\\"\"\n                      }\n                    ],\n                    \"id\": 18,\n                    \"name\": \"ErrorBContract\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 15,\n                    \"src\": \"130:14:2\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_error_pure$_t_string_memory_ptr_$returns$_t_error_$\",\n                      \"typeString\": \"function (string memory) pure returns (error)\"\n                    }\n                  },\n                  \"id\": 20,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"130:28:2\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_error\",\n                    \"typeString\": \"error\"\n                  }\n                },\n                \"id\": 21,\n                \"nodeType\": \"RevertStatement\",\n                \"src\": \"123:35:2\"\n              }\n            ]\n          },\n          \"functionSelector\": \"c27fc305\",\n          \"id\": 23,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f1\",\n          \"nameLocation\": \"100:2:2\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 16,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"103:2:2\"\n          },\n          \"returnParameters\": {\n            \"id\": 17,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"113:0:2\"\n          },\n          \"scope\": 46,\n          \"src\": \"91:74:2\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 32,\n            \"nodeType\": \"Block\",\n            \"src\": \"192:46:2\",\n            \"statements\": [\n              {\n                \"errorCall\": {\n                  \"arguments\": [\n                    {\n                      \"hexValue\": \"736f6d65206572726f72\",\n                      \"id\": 29,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"string\",\n                      \"lValueRequested\": false,\n                      \"nodeType\": \"Literal\",\n                      \"src\": \"218:12:2\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577\",\n                        \"typeString\": \"literal_string \\\"some error\\\"\"\n                      },\n                      \"value\": \"some error\"\n                    }\n                  ],\n                  \"expression\": {\n                    \"argumentTypes\": [\n                      {\n                        \"typeIdentifier\": \"t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577\",\n                        \"typeString\": \"literal_string \\\"some error\\\"\"\n                      }\n                    ],\n                    \"expression\": {\n                      \"id\": 26,\n                      \"name\": \"A\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 11,\n                      \"src\": \"209:1:2\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_module_10\",\n                        \"typeString\": \"module \\\"A.sol\\\"\"\n                      }\n                    },\n                    \"id\": 28,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"lValueRequested\": false,\n                    \"memberLocation\": \"211:6:2\",\n                    \"memberName\": \"ErrorA\",\n                    \"nodeType\": \"MemberAccess\",\n                    \"referencedDeclaration\": 4,\n                    \"src\": \"209:8:2\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_error_pure$_t_string_memory_ptr_$returns$_t_error_$\",\n                      \"typeString\": \"function (string memory) pure returns (error)\"\n                    }\n                  },\n                  \"id\": 30,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"209:22:2\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_error\",\n                    \"typeString\": \"error\"\n                  }\n                },\n                \"id\": 31,\n                \"nodeType\": \"RevertStatement\",\n                \"src\": \"202:29:2\"\n              }\n            ]\n          },\n          \"functionSelector\": \"9942ec6f\",\n          \"id\": 33,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f2\",\n          \"nameLocation\": \"179:2:2\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 24,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"182:2:2\"\n          },\n          \"returnParameters\": {\n            \"id\": 25,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"192:0:2\"\n          },\n          \"scope\": 46,\n          \"src\": \"170:68:2\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 44,\n            \"nodeType\": \"Block\",\n            \"src\": \"265:64:2\",\n            \"statements\": [\n              {\n                \"errorCall\": {\n                  \"arguments\": [\n                    {\n                      \"hexValue\": \"736f6d65206572726f72\",\n                      \"id\": 41,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"string\",\n                      \"lValueRequested\": false,\n                      \"nodeType\": \"Literal\",\n                      \"src\": \"309:12:2\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577\",\n                        \"typeString\": \"literal_string \\\"some error\\\"\"\n                      },\n                      \"value\": \"some error\"\n                    }\n                  ],\n                  \"expression\": {\n                    \"argumentTypes\": [\n                      {\n                        \"typeIdentifier\": \"t_stringliteral_b4ae9cd779cde5df80ff601d28c3fa893d24133d1b4e6fdffbb3a05b40d7a577\",\n                        \"typeString\": \"literal_string \\\"some error\\\"\"\n                      }\n                    ],\n                    \"expression\": {\n                      \"expression\": {\n                        \"id\": 36,\n                        \"name\": \"A\",\n                        \"nodeType\": \"Identifier\",\n                        \"overloadedDeclarations\": [],\n                        \"referencedDeclaration\": 11,\n                        \"src\": \"282:1:2\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_module_10\",\n                          \"typeString\": \"module \\\"A.sol\\\"\"\n                        }\n                      },\n                      \"id\": 39,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"lValueRequested\": false,\n                      \"memberLocation\": \"284:9:2\",\n                      \"memberName\": \"AContract\",\n                      \"nodeType\": \"MemberAccess\",\n                      \"referencedDeclaration\": 9,\n                      \"src\": \"282:11:2\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_type$_t_contract$_AContract_$9_$\",\n                        \"typeString\": \"type(contract AContract)\"\n                      }\n                    },\n                    \"id\": 40,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"memberLocation\": \"294:14:2\",\n                    \"memberName\": \"ErrorAContract\",\n                    \"nodeType\": \"MemberAccess\",\n                    \"referencedDeclaration\": 8,\n                    \"src\": \"282:26:2\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_error_pure$_t_string_memory_ptr_$returns$_t_error_$\",\n                      \"typeString\": \"function (string memory) pure returns (error)\"\n                    }\n                  },\n                  \"id\": 42,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"282:40:2\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_error\",\n                    \"typeString\": \"error\"\n                  }\n                },\n                \"id\": 43,\n                \"nodeType\": \"RevertStatement\",\n                \"src\": \"275:47:2\"\n              }\n            ]\n          },\n          \"functionSelector\": \"aaf05f3d\",\n          \"id\": 45,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f3\",\n          \"nameLocation\": \"252:2:2\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 34,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"255:2:2\"\n          },\n          \"returnParameters\": {\n            \"id\": 35,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"265:0:2\"\n          },\n          \"scope\": 46,\n          \"src\": \"243:86:2\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 47,\n      \"src\": \"28:303:2\",\n      \"usedErrors\": [\n        4,\n        8,\n        15\n      ],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:332:2\"\n}\n]\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/error_from_module_via_member_access.sol",
    "content": "==== Source: A.sol ====\nerror ErrorA(string msg);\ncontract AContract {\n    error ErrorAContract(string msg);\n}\n\n==== Source: B.sol ====\nimport * as A from \"A.sol\";\ncontract BContract {\n    error ErrorBContract(string msg);\n    function f1 () public {\n        revert ErrorBContract(\"some error\");\n    }\n    function f2 () public {\n        revert A.ErrorA(\"some error\");\n    }\n    function f3 () public {\n        revert A.AContract.ErrorAContract(\"some error\");\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_aggregated_contract.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      10\n    ],\n    \"D\": [\n      30\n    ]\n  },\n  \"id\": 31,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 10,\n      \"linearizedBaseContracts\": [\n        10\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"eventSelector\": \"ffae15ba29768297c9b951e2e14bc33dc84599d1572acc234266fc70392babc8\",\n          \"id\": 2,\n          \"name\": \"e\",\n          \"nameLocation\": \"23:1:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"24:2:1\"\n          },\n          \"src\": \"17:10:1\"\n        },\n        {\n          \"body\": {\n            \"id\": 8,\n            \"nodeType\": \"Block\",\n            \"src\": \"52:25:1\",\n            \"statements\": [\n              {\n                \"eventCall\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"id\": 5,\n                    \"name\": \"e\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 2,\n                    \"src\": \"67:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_event_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 6,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"67:3:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 7,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"62:8:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 9,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"41:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 4,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"52:0:1\"\n          },\n          \"scope\": 10,\n          \"src\": \"32:45:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 31,\n      \"src\": \"0:79:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        2\n      ]\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"D\",\n      \"contractDependencies\": [\n        10\n      ],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 30,\n      \"linearizedBaseContracts\": [\n        30\n      ],\n      \"name\": \"D\",\n      \"nameLocation\": \"89:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 13,\n          \"mutability\": \"mutable\",\n          \"name\": \"c\",\n          \"nameLocation\": \"99:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 30,\n          \"src\": \"97:3:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_contract$_C_$10\",\n            \"typeString\": \"contract C\"\n          },\n          \"typeName\": {\n            \"id\": 12,\n            \"nodeType\": \"UserDefinedTypeName\",\n            \"pathNode\": {\n              \"id\": 11,\n              \"name\": \"C\",\n              \"nameLocations\": [\n                \"97:1:1\"\n              ],\n              \"nodeType\": \"IdentifierPath\",\n              \"referencedDeclaration\": 10,\n              \"src\": \"97:1:1\"\n            },\n            \"referencedDeclaration\": 10,\n            \"src\": \"97:1:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_contract$_C_$10\",\n              \"typeString\": \"contract C\"\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 28,\n            \"nodeType\": \"Block\",\n            \"src\": \"120:43:1\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"id\": 21,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"leftHandSide\": {\n                    \"id\": 16,\n                    \"name\": \"c\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 13,\n                    \"src\": \"130:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_contract$_C_$10\",\n                      \"typeString\": \"contract C\"\n                    }\n                  },\n                  \"nodeType\": \"Assignment\",\n                  \"operator\": \"=\",\n                  \"rightHandSide\": {\n                    \"arguments\": [],\n                    \"expression\": {\n                      \"argumentTypes\": [],\n                      \"id\": 19,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": false,\n                      \"lValueRequested\": false,\n                      \"nodeType\": \"NewExpression\",\n                      \"src\": \"134:5:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_function_creation_nonpayable$__$returns$_t_contract$_C_$10_$\",\n                        \"typeString\": \"function () returns (contract C)\"\n                      },\n                      \"typeName\": {\n                        \"id\": 18,\n                        \"nodeType\": \"UserDefinedTypeName\",\n                        \"pathNode\": {\n                          \"id\": 17,\n                          \"name\": \"C\",\n                          \"nameLocations\": [\n                            \"138:1:1\"\n                          ],\n                          \"nodeType\": \"IdentifierPath\",\n                          \"referencedDeclaration\": 10,\n                          \"src\": \"138:1:1\"\n                        },\n                        \"referencedDeclaration\": 10,\n                        \"src\": \"138:1:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_contract$_C_$10\",\n                          \"typeString\": \"contract C\"\n                        }\n                      }\n                    },\n                    \"id\": 20,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"kind\": \"functionCall\",\n                    \"lValueRequested\": false,\n                    \"nameLocations\": [],\n                    \"names\": [],\n                    \"nodeType\": \"FunctionCall\",\n                    \"src\": \"134:7:1\",\n                    \"tryCall\": false,\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_contract$_C_$10\",\n                      \"typeString\": \"contract C\"\n                    }\n                  },\n                  \"src\": \"130:11:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_contract$_C_$10\",\n                    \"typeString\": \"contract C\"\n                  }\n                },\n                \"id\": 22,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"130:11:1\"\n              },\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"expression\": {\n                      \"id\": 23,\n                      \"name\": \"c\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 13,\n                      \"src\": \"151:1:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_contract$_C_$10\",\n                        \"typeString\": \"contract C\"\n                      }\n                    },\n                    \"id\": 25,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"memberLocation\": \"153:1:1\",\n                    \"memberName\": \"f\",\n                    \"nodeType\": \"MemberAccess\",\n                    \"referencedDeclaration\": 9,\n                    \"src\": \"151:3:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_external_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function () external\"\n                    }\n                  },\n                  \"id\": 26,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"151:5:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 27,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"151:5:1\"\n              }\n            ]\n          },\n          \"id\": 29,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 14,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"117:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 15,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"120:0:1\"\n          },\n          \"scope\": 30,\n          \"src\": \"106:57:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 31,\n      \"src\": \"80:85:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:166:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_aggregated_contract.sol",
    "content": "contract C {\n    event e();\n    function f() public {\n        emit e();\n    }\n}\ncontract D {\n    C c;\n    constructor() {\n        c = new C();\n        c.f();\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_definition.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      3\n    ]\n  },\n  \"id\": 4,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 3,\n      \"linearizedBaseContracts\": [\n        3\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"eventSelector\": \"92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\",\n          \"id\": 2,\n          \"name\": \"E\",\n          \"nameLocation\": \"19:1:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"20:2:1\"\n          },\n          \"src\": \"13:10:1\"\n        }\n      ],\n      \"scope\": 4,\n      \"src\": \"0:25:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        2\n      ]\n    }\n  ],\n  \"src\": \"0:26:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_definition.sol",
    "content": "contract C { event E(); }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_definition_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 4,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 3,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"id\": 2,\n          \"name\": \"E\",\n          \"nameLocation\": \"19:1:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"20:2:1\"\n          },\n          \"src\": \"13:10:1\"\n        }\n      ],\n      \"src\": \"0:25:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:26:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_emited_in_base_contract.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"B\": [\n      16\n    ],\n    \"C\": [\n      19\n    ],\n    \"L\": [\n      5\n    ]\n  },\n  \"id\": 20,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"L\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"library\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"L\",\n      \"nameLocation\": \"10:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"eventSelector\": \"870e3024466c178150e2490c7cfb455e33c0db877113af040f89189d07946664\",\n          \"id\": 4,\n          \"name\": \"E\",\n          \"nameLocation\": \"20:1:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 2,\n                \"indexed\": false,\n                \"mutability\": \"mutable\",\n                \"name\": \"\",\n                \"nameLocation\": \"-1:-1:-1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 4,\n                \"src\": \"22:5:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint8\",\n                  \"typeString\": \"uint8\"\n                },\n                \"typeName\": {\n                  \"id\": 1,\n                  \"name\": \"uint8\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"22:5:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint8\",\n                    \"typeString\": \"uint8\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"21:7:1\"\n          },\n          \"src\": \"14:15:1\"\n        }\n      ],\n      \"scope\": 20,\n      \"src\": \"0:31:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        4\n      ]\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"B\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 16,\n      \"linearizedBaseContracts\": [\n        16\n      ],\n      \"name\": \"B\",\n      \"nameLocation\": \"41:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 14,\n            \"nodeType\": \"Block\",\n            \"src\": \"63:28:1\",\n            \"statements\": [\n              {\n                \"eventCall\": {\n                  \"arguments\": [\n                    {\n                      \"hexValue\": \"30\",\n                      \"id\": 11,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"number\",\n                      \"lValueRequested\": false,\n                      \"nodeType\": \"Literal\",\n                      \"src\": \"82:1:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_rational_0_by_1\",\n                        \"typeString\": \"int_const 0\"\n                      },\n                      \"value\": \"0\"\n                    }\n                  ],\n                  \"expression\": {\n                    \"argumentTypes\": [\n                      {\n                        \"typeIdentifier\": \"t_rational_0_by_1\",\n                        \"typeString\": \"int_const 0\"\n                      }\n                    ],\n                    \"expression\": {\n                      \"id\": 8,\n                      \"name\": \"L\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 5,\n                      \"src\": \"78:1:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_type$_t_contract$_L_$5_$\",\n                        \"typeString\": \"type(library L)\"\n                      }\n                    },\n                    \"id\": 10,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"memberLocation\": \"80:1:1\",\n                    \"memberName\": \"E\",\n                    \"nodeType\": \"MemberAccess\",\n                    \"referencedDeclaration\": 4,\n                    \"src\": \"78:3:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_event_nonpayable$_t_uint8_$returns$__$\",\n                      \"typeString\": \"function (uint8)\"\n                    }\n                  },\n                  \"id\": 12,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"78:6:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 13,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"73:11:1\"\n              }\n            ]\n          },\n          \"id\": 15,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 6,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"60:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"63:0:1\"\n          },\n          \"scope\": 16,\n          \"src\": \"49:42:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 20,\n      \"src\": \"32:61:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        4\n      ]\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 17,\n            \"name\": \"B\",\n            \"nameLocations\": [\n              \"108:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 16,\n            \"src\": \"108:1:1\"\n          },\n          \"id\": 18,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"108:1:1\"\n        }\n      ],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 19,\n      \"linearizedBaseContracts\": [\n        19,\n        16\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"103:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 20,\n      \"src\": \"94:18:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        4\n      ]\n    }\n  ],\n  \"src\": \"0:113:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_emited_in_base_contract.sol",
    "content": "library   L { event E(uint8); }\ncontract B {\n    constructor() {\n        emit L.E(0);\n    }\n}\ncontract C is B {}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_emitted_from_foreign_contract.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      5\n    ],\n    \"D\": [\n      19\n    ]\n  },\n  \"id\": 20,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"eventSelector\": \"bd1155618a34fd53d1a2de9f705f42f3582842cba0b985b25c59888d86e0c929\",\n          \"id\": 4,\n          \"name\": \"E\",\n          \"nameLocation\": \"23:1:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 2,\n                \"indexed\": true,\n                \"mutability\": \"mutable\",\n                \"name\": \"sender\",\n                \"nameLocation\": \"41:6:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 4,\n                \"src\": \"25:22:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_address\",\n                  \"typeString\": \"address\"\n                },\n                \"typeName\": {\n                  \"id\": 1,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"25:7:1\",\n                  \"stateMutability\": \"nonpayable\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address\",\n                    \"typeString\": \"address\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"24:24:1\"\n          },\n          \"src\": \"17:32:1\"\n        }\n      ],\n      \"scope\": 20,\n      \"src\": \"0:51:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        4\n      ]\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"D\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 19,\n      \"linearizedBaseContracts\": [\n        19\n      ],\n      \"name\": \"D\",\n      \"nameLocation\": \"61:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 17,\n            \"nodeType\": \"Block\",\n            \"src\": \"106:37:1\",\n            \"statements\": [\n              {\n                \"eventCall\": {\n                  \"arguments\": [\n                    {\n                      \"expression\": {\n                        \"id\": 13,\n                        \"name\": \"msg\",\n                        \"nodeType\": \"Identifier\",\n                        \"overloadedDeclarations\": [],\n                        \"referencedDeclaration\": -15,\n                        \"src\": \"125:3:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_magic_message\",\n                          \"typeString\": \"msg\"\n                        }\n                      },\n                      \"id\": 14,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": false,\n                      \"lValueRequested\": false,\n                      \"memberLocation\": \"129:6:1\",\n                      \"memberName\": \"sender\",\n                      \"nodeType\": \"MemberAccess\",\n                      \"src\": \"125:10:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      }\n                    }\n                  ],\n                  \"expression\": {\n                    \"argumentTypes\": [\n                      {\n                        \"typeIdentifier\": \"t_address\",\n                        \"typeString\": \"address\"\n                      }\n                    ],\n                    \"expression\": {\n                      \"id\": 10,\n                      \"name\": \"C\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 5,\n                      \"src\": \"121:1:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_type$_t_contract$_C_$5_$\",\n                        \"typeString\": \"type(contract C)\"\n                      }\n                    },\n                    \"id\": 12,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"memberLocation\": \"123:1:1\",\n                    \"memberName\": \"E\",\n                    \"nodeType\": \"MemberAccess\",\n                    \"referencedDeclaration\": 4,\n                    \"src\": \"121:3:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_event_nonpayable$_t_address_$returns$__$\",\n                      \"typeString\": \"function (address)\"\n                    }\n                  },\n                  \"id\": 15,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"121:15:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 16,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"116:20:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"bb29998e\",\n          \"id\": 18,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"test\",\n          \"nameLocation\": \"78:4:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 8,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 7,\n                \"mutability\": \"mutable\",\n                \"name\": \"sender\",\n                \"nameLocation\": \"91:6:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 18,\n                \"src\": \"83:14:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_address\",\n                  \"typeString\": \"address\"\n                },\n                \"typeName\": {\n                  \"id\": 6,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"83:7:1\",\n                  \"stateMutability\": \"nonpayable\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_address\",\n                    \"typeString\": \"address\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"82:16:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 9,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"106:0:1\"\n          },\n          \"scope\": 19,\n          \"src\": \"69:74:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 20,\n      \"src\": \"52:93:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        4\n      ]\n    }\n  ],\n  \"src\": \"0:146:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_emitted_from_foreign_contract.sol",
    "content": "contract C {\n    event E(address indexed sender);\n}\ncontract D {\n    function test(address sender) public {\n        emit C.E(msg.sender);\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_emitted_from_foreign_contract_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 20,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 5,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"id\": 4,\n          \"name\": \"E\",\n          \"nameLocation\": \"23:1:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 2,\n                \"indexed\": true,\n                \"mutability\": \"mutable\",\n                \"name\": \"sender\",\n                \"nameLocation\": \"41:6:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"25:22:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 1,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"25:7:1\",\n                  \"stateMutability\": \"nonpayable\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"24:24:1\"\n          },\n          \"src\": \"17:32:1\"\n        }\n      ],\n      \"src\": \"0:51:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 19,\n      \"name\": \"D\",\n      \"nameLocation\": \"61:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 17,\n            \"nodeType\": \"Block\",\n            \"src\": \"106:37:1\",\n            \"statements\": [\n              {\n                \"eventCall\": {\n                  \"arguments\": [\n                    {\n                      \"expression\": {\n                        \"id\": 13,\n                        \"name\": \"msg\",\n                        \"nodeType\": \"Identifier\",\n                        \"overloadedDeclarations\": [],\n                        \"src\": \"125:3:1\",\n                        \"typeDescriptions\": {}\n                      },\n                      \"id\": 14,\n                      \"memberLocation\": \"129:6:1\",\n                      \"memberName\": \"sender\",\n                      \"nodeType\": \"MemberAccess\",\n                      \"src\": \"125:10:1\",\n                      \"typeDescriptions\": {}\n                    }\n                  ],\n                  \"expression\": {\n                    \"expression\": {\n                      \"id\": 10,\n                      \"name\": \"C\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"src\": \"121:1:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"id\": 12,\n                    \"memberLocation\": \"123:1:1\",\n                    \"memberName\": \"E\",\n                    \"nodeType\": \"MemberAccess\",\n                    \"src\": \"121:3:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"id\": 15,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"121:15:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 16,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"116:20:1\"\n              }\n            ]\n          },\n          \"id\": 18,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"test\",\n          \"nameLocation\": \"78:4:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 8,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 7,\n                \"mutability\": \"mutable\",\n                \"name\": \"sender\",\n                \"nameLocation\": \"91:6:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"83:14:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 6,\n                  \"name\": \"address\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"83:7:1\",\n                  \"stateMutability\": \"nonpayable\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"82:16:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 9,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"106:0:1\"\n          },\n          \"src\": \"69:74:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"52:93:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:146:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_inheritance.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"B\": [\n      3\n    ],\n    \"C\": [\n      8\n    ],\n    \"D\": [\n      13\n    ]\n  },\n  \"id\": 14,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"B\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"interface\",\n      \"fullyImplemented\": true,\n      \"id\": 3,\n      \"linearizedBaseContracts\": [\n        3\n      ],\n      \"name\": \"B\",\n      \"nameLocation\": \"10:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"eventSelector\": \"dbec0351ad6bb0c1f07ea56e236e3e692fde2259f0165fd422f241da339b7e4f\",\n          \"id\": 2,\n          \"name\": \"EB\",\n          \"nameLocation\": \"24:2:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"26:2:1\"\n          },\n          \"src\": \"18:11:1\"\n        }\n      ],\n      \"scope\": 14,\n      \"src\": \"0:31:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        2\n      ]\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 4,\n            \"name\": \"B\",\n            \"nameLocations\": [\n              \"46:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 3,\n            \"src\": \"46:1:1\"\n          },\n          \"id\": 5,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"46:1:1\"\n        }\n      ],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 8,\n      \"linearizedBaseContracts\": [\n        8,\n        3\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"41:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"eventSelector\": \"a08b3367d3fa83ea27f8951ffb5d9d160cbfadbd80816b47f677e7699d76f5a0\",\n          \"id\": 7,\n          \"name\": \"EC\",\n          \"nameLocation\": \"60:2:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 6,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"62:2:1\"\n          },\n          \"src\": \"54:11:1\"\n        }\n      ],\n      \"scope\": 14,\n      \"src\": \"32:35:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        2,\n        7\n      ]\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 9,\n            \"name\": \"C\",\n            \"nameLocations\": [\n              \"82:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 8,\n            \"src\": \"82:1:1\"\n          },\n          \"id\": 10,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"82:1:1\"\n        }\n      ],\n      \"canonicalName\": \"D\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 13,\n      \"linearizedBaseContracts\": [\n        13,\n        8,\n        3\n      ],\n      \"name\": \"D\",\n      \"nameLocation\": \"77:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"eventSelector\": \"caa54b91a2314ab89b39714b1cd283762e53a2f59cfb997d6770e2824c39db0d\",\n          \"id\": 12,\n          \"name\": \"ED\",\n          \"nameLocation\": \"96:2:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"98:2:1\"\n          },\n          \"src\": \"90:11:1\"\n        }\n      ],\n      \"scope\": 14,\n      \"src\": \"68:35:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        2,\n        7,\n        12\n      ]\n    }\n  ],\n  \"src\": \"0:104:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_inheritance.sol",
    "content": "interface B {\n    event EB();\n}\ncontract C is B {\n    event EC();\n}\ncontract D is C {\n    event ED();\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_with_variables_of_internal_types.sol",
    "content": "contract C {\n    event E(function() internal);\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/event_with_variables_of_internal_types_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 8,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 7,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"id\": 6,\n          \"name\": \"E\",\n          \"nameLocation\": \"23:1:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 5,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 4,\n                \"indexed\": false,\n                \"mutability\": \"mutable\",\n                \"name\": \"\",\n                \"nameLocation\": \"-1:-1:-1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"25:20:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 3,\n                  \"nodeType\": \"FunctionTypeName\",\n                  \"parameterTypes\": {\n                    \"id\": 1,\n                    \"nodeType\": \"ParameterList\",\n                    \"parameters\": [],\n                    \"src\": \"33:2:1\"\n                  },\n                  \"returnParameterTypes\": {\n                    \"id\": 2,\n                    \"nodeType\": \"ParameterList\",\n                    \"parameters\": [],\n                    \"src\": \"44:0:1\"\n                  },\n                  \"src\": \"25:20:1\",\n                  \"stateMutability\": \"nonpayable\",\n                  \"typeDescriptions\": {},\n                  \"visibility\": \"internal\"\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"24:21:1\"\n          },\n          \"src\": \"17:29:1\"\n        }\n      ],\n      \"src\": \"0:48:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:49:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/fail_after_parsing.sol",
    "content": "function g() public;\ninterface I {\n    struct S { S s; }\n    function f(E storage e) {\n        error E;\n        emit E();\n        ++c;\n        uint calldata c = 123.4;\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/fail_after_parsing_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 30,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"id\": 3,\n      \"implemented\": false,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"g\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 1,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"10:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 2,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"19:0:1\"\n      },\n      \"src\": \"0:20:1\",\n      \"stateMutability\": \"nonpayable\",\n      \"virtual\": false,\n      \"visibility\": \"public\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"interface\",\n      \"id\": 29,\n      \"name\": \"I\",\n      \"nameLocation\": \"31:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"id\": 7,\n          \"members\": [\n            {\n              \"constant\": false,\n              \"id\": 6,\n              \"mutability\": \"mutable\",\n              \"name\": \"s\",\n              \"nameLocation\": \"52:1:1\",\n              \"nodeType\": \"VariableDeclaration\",\n              \"src\": \"50:3:1\",\n              \"stateVariable\": false,\n              \"storageLocation\": \"default\",\n              \"typeDescriptions\": {},\n              \"typeName\": {\n                \"id\": 5,\n                \"nodeType\": \"UserDefinedTypeName\",\n                \"pathNode\": {\n                  \"id\": 4,\n                  \"name\": \"S\",\n                  \"nameLocations\": [\n                    \"50:1:1\"\n                  ],\n                  \"nodeType\": \"IdentifierPath\",\n                  \"src\": \"50:1:1\"\n                },\n                \"src\": \"50:1:1\",\n                \"typeDescriptions\": {}\n              },\n              \"visibility\": \"internal\"\n            }\n          ],\n          \"name\": \"S\",\n          \"nameLocation\": \"46:1:1\",\n          \"nodeType\": \"StructDefinition\",\n          \"src\": \"39:17:1\",\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 27,\n            \"nodeType\": \"Block\",\n            \"src\": \"85:88:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  15\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 15,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"E\",\n                    \"nameLocation\": \"101:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"95:7:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 14,\n                      \"nodeType\": \"UserDefinedTypeName\",\n                      \"pathNode\": {\n                        \"id\": 13,\n                        \"name\": \"error\",\n                        \"nameLocations\": [\n                          \"95:5:1\"\n                        ],\n                        \"nodeType\": \"IdentifierPath\",\n                        \"src\": \"95:5:1\"\n                      },\n                      \"src\": \"95:5:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 16,\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"95:7:1\"\n              },\n              {\n                \"eventCall\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"id\": 17,\n                    \"name\": \"E\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"117:1:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"id\": 18,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"117:3:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 19,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"112:8:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 21,\n                  \"nodeType\": \"UnaryOperation\",\n                  \"operator\": \"++\",\n                  \"prefix\": true,\n                  \"src\": \"130:3:1\",\n                  \"subExpression\": {\n                    \"id\": 20,\n                    \"name\": \"c\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"132:1:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 22,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"130:3:1\"\n              },\n              {\n                \"assignments\": [\n                  24\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 24,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"c\",\n                    \"nameLocation\": \"157:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"143:15:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"calldata\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 23,\n                      \"name\": \"uint\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"143:4:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 26,\n                \"initialValue\": {\n                  \"hexValue\": \"3132332e34\",\n                  \"id\": 25,\n                  \"kind\": \"number\",\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"161:5:1\",\n                  \"typeDescriptions\": {},\n                  \"value\": \"123.4\"\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"143:23:1\"\n              }\n            ]\n          },\n          \"id\": 28,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"70:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 10,\n                \"mutability\": \"mutable\",\n                \"name\": \"e\",\n                \"nameLocation\": \"82:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"72:11:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"storage\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 9,\n                  \"nodeType\": \"UserDefinedTypeName\",\n                  \"pathNode\": {\n                    \"id\": 8,\n                    \"name\": \"E\",\n                    \"nameLocations\": [\n                      \"72:1:1\"\n                    ],\n                    \"nodeType\": \"IdentifierPath\",\n                    \"src\": \"72:1:1\"\n                  },\n                  \"src\": \"72:1:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"71:13:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 12,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"85:0:1\"\n          },\n          \"src\": \"61:112:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"21:154:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:176:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/fallback.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      5\n    ]\n  },\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"43:5:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"fallback\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"43:0:1\"\n          },\n          \"scope\": 5,\n          \"src\": \"15:33:1\",\n          \"stateMutability\": \"payable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        }\n      ],\n      \"scope\": 6,\n      \"src\": \"0:50:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:51:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/fallback.sol",
    "content": "contract C {\n  fallback() external payable {\n  }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/fallback_and_receive_ether.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      9\n    ]\n  },\n  \"id\": 10,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 9,\n      \"linearizedBaseContracts\": [\n        9\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:5:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"receive\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"22:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"scope\": 9,\n          \"src\": \"15:32:1\",\n          \"stateMutability\": \"payable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        },\n        {\n          \"body\": {\n            \"id\": 7,\n            \"nodeType\": \"Block\",\n            \"src\": \"78:5:1\",\n            \"statements\": []\n          },\n          \"id\": 8,\n          \"implemented\": true,\n          \"kind\": \"fallback\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 5,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"58:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 6,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"78:0:1\"\n          },\n          \"scope\": 9,\n          \"src\": \"50:33:1\",\n          \"stateMutability\": \"payable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        }\n      ],\n      \"scope\": 10,\n      \"src\": \"0:85:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:86:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/fallback_and_receive_ether.sol",
    "content": "contract C {\n  receive() external payable {\n  }\n  fallback() external payable {\n  }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/fallback_and_receive_ether_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 10,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 9,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:5:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"receive\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"22:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"src\": \"15:32:1\",\n          \"stateMutability\": \"payable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        },\n        {\n          \"body\": {\n            \"id\": 7,\n            \"nodeType\": \"Block\",\n            \"src\": \"78:5:1\",\n            \"statements\": []\n          },\n          \"id\": 8,\n          \"implemented\": true,\n          \"kind\": \"fallback\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 5,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"58:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 6,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"78:0:1\"\n          },\n          \"src\": \"50:33:1\",\n          \"stateMutability\": \"payable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        }\n      ],\n      \"src\": \"0:85:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:86:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/fallback_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 5,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"43:5:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"fallback\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"43:0:1\"\n          },\n          \"src\": \"15:33:1\",\n          \"stateMutability\": \"payable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        }\n      ],\n      \"src\": \"0:50:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:51:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/fallback_payable.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      5\n    ]\n  },\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"34:2:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"fallback\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"22:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"34:0:1\"\n          },\n          \"scope\": 5,\n          \"src\": \"14:22:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        }\n      ],\n      \"scope\": 6,\n      \"src\": \"0:38:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:39:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/fallback_payable.sol",
    "content": "contract C {\n\tfallback() external {}\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/fallback_payable_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 5,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"34:2:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"fallback\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"22:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"34:0:1\"\n          },\n          \"src\": \"14:22:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        }\n      ],\n      \"src\": \"0:38:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:39:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/function_type.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      17\n    ]\n  },\n  \"id\": 18,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 17,\n      \"linearizedBaseContracts\": [\n        17\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 15,\n            \"nodeType\": \"Block\",\n            \"src\": \"127:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"d6cd4974\",\n          \"id\": 16,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 6,\n                \"mutability\": \"mutable\",\n                \"name\": \"x\",\n                \"nameLocation\": \"67:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 16,\n                \"src\": \"24:44:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_function_external_payable$__$returns$_t_uint256_$\",\n                  \"typeString\": \"function () payable external returns (uint256)\"\n                },\n                \"typeName\": {\n                  \"id\": 5,\n                  \"nodeType\": \"FunctionTypeName\",\n                  \"parameterTypes\": {\n                    \"id\": 1,\n                    \"nodeType\": \"ParameterList\",\n                    \"parameters\": [],\n                    \"src\": \"32:2:1\"\n                  },\n                  \"returnParameterTypes\": {\n                    \"id\": 4,\n                    \"nodeType\": \"ParameterList\",\n                    \"parameters\": [\n                      {\n                        \"constant\": false,\n                        \"id\": 3,\n                        \"mutability\": \"mutable\",\n                        \"name\": \"\",\n                        \"nameLocation\": \"-1:-1:-1\",\n                        \"nodeType\": \"VariableDeclaration\",\n                        \"scope\": 5,\n                        \"src\": \"61:4:1\",\n                        \"stateVariable\": false,\n                        \"storageLocation\": \"default\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_uint256\",\n                          \"typeString\": \"uint256\"\n                        },\n                        \"typeName\": {\n                          \"id\": 2,\n                          \"name\": \"uint\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"61:4:1\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_uint256\",\n                            \"typeString\": \"uint256\"\n                          }\n                        },\n                        \"visibility\": \"internal\"\n                      }\n                    ],\n                    \"src\": \"60:6:1\"\n                  },\n                  \"src\": \"24:44:1\",\n                  \"stateMutability\": \"payable\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_function_external_payable$__$returns$_t_uint256_$\",\n                    \"typeString\": \"function () payable external returns (uint256)\"\n                  },\n                  \"visibility\": \"external\"\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"23:46:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 14,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 13,\n                \"mutability\": \"mutable\",\n                \"name\": \"\",\n                \"nameLocation\": \"-1:-1:-1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 16,\n                \"src\": \"86:40:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_function_external_view$__$returns$_t_uint256_$\",\n                  \"typeString\": \"function () view external returns (uint256)\"\n                },\n                \"typeName\": {\n                  \"id\": 12,\n                  \"nodeType\": \"FunctionTypeName\",\n                  \"parameterTypes\": {\n                    \"id\": 8,\n                    \"nodeType\": \"ParameterList\",\n                    \"parameters\": [],\n                    \"src\": \"94:2:1\"\n                  },\n                  \"returnParameterTypes\": {\n                    \"id\": 11,\n                    \"nodeType\": \"ParameterList\",\n                    \"parameters\": [\n                      {\n                        \"constant\": false,\n                        \"id\": 10,\n                        \"mutability\": \"mutable\",\n                        \"name\": \"\",\n                        \"nameLocation\": \"-1:-1:-1\",\n                        \"nodeType\": \"VariableDeclaration\",\n                        \"scope\": 12,\n                        \"src\": \"120:4:1\",\n                        \"stateVariable\": false,\n                        \"storageLocation\": \"default\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_uint256\",\n                          \"typeString\": \"uint256\"\n                        },\n                        \"typeName\": {\n                          \"id\": 9,\n                          \"name\": \"uint\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"120:4:1\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_uint256\",\n                            \"typeString\": \"uint256\"\n                          }\n                        },\n                        \"visibility\": \"internal\"\n                      }\n                    ],\n                    \"src\": \"119:6:1\"\n                  },\n                  \"src\": \"86:40:1\",\n                  \"stateMutability\": \"view\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_function_external_view$__$returns$_t_uint256_$\",\n                    \"typeString\": \"function () view external returns (uint256)\"\n                  },\n                  \"visibility\": \"external\"\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"85:41:1\"\n          },\n          \"scope\": 17,\n          \"src\": \"13:116:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 18,\n      \"src\": \"0:131:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:132:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/function_type.sol",
    "content": "contract C { function f(function() external payable returns (uint) x) public returns (function() external view returns (uint)) {} }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/function_type_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 18,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 17,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 15,\n            \"nodeType\": \"Block\",\n            \"src\": \"127:2:1\",\n            \"statements\": []\n          },\n          \"id\": 16,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 6,\n                \"mutability\": \"mutable\",\n                \"name\": \"x\",\n                \"nameLocation\": \"67:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"24:44:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 5,\n                  \"nodeType\": \"FunctionTypeName\",\n                  \"parameterTypes\": {\n                    \"id\": 1,\n                    \"nodeType\": \"ParameterList\",\n                    \"parameters\": [],\n                    \"src\": \"32:2:1\"\n                  },\n                  \"returnParameterTypes\": {\n                    \"id\": 4,\n                    \"nodeType\": \"ParameterList\",\n                    \"parameters\": [\n                      {\n                        \"constant\": false,\n                        \"id\": 3,\n                        \"mutability\": \"mutable\",\n                        \"name\": \"\",\n                        \"nameLocation\": \"-1:-1:-1\",\n                        \"nodeType\": \"VariableDeclaration\",\n                        \"src\": \"61:4:1\",\n                        \"stateVariable\": false,\n                        \"storageLocation\": \"default\",\n                        \"typeDescriptions\": {},\n                        \"typeName\": {\n                          \"id\": 2,\n                          \"name\": \"uint\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"61:4:1\",\n                          \"typeDescriptions\": {}\n                        },\n                        \"visibility\": \"internal\"\n                      }\n                    ],\n                    \"src\": \"60:6:1\"\n                  },\n                  \"src\": \"24:44:1\",\n                  \"stateMutability\": \"payable\",\n                  \"typeDescriptions\": {},\n                  \"visibility\": \"external\"\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"23:46:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 14,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 13,\n                \"mutability\": \"mutable\",\n                \"name\": \"\",\n                \"nameLocation\": \"-1:-1:-1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"86:40:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 12,\n                  \"nodeType\": \"FunctionTypeName\",\n                  \"parameterTypes\": {\n                    \"id\": 8,\n                    \"nodeType\": \"ParameterList\",\n                    \"parameters\": [],\n                    \"src\": \"94:2:1\"\n                  },\n                  \"returnParameterTypes\": {\n                    \"id\": 11,\n                    \"nodeType\": \"ParameterList\",\n                    \"parameters\": [\n                      {\n                        \"constant\": false,\n                        \"id\": 10,\n                        \"mutability\": \"mutable\",\n                        \"name\": \"\",\n                        \"nameLocation\": \"-1:-1:-1\",\n                        \"nodeType\": \"VariableDeclaration\",\n                        \"src\": \"120:4:1\",\n                        \"stateVariable\": false,\n                        \"storageLocation\": \"default\",\n                        \"typeDescriptions\": {},\n                        \"typeName\": {\n                          \"id\": 9,\n                          \"name\": \"uint\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"120:4:1\",\n                          \"typeDescriptions\": {}\n                        },\n                        \"visibility\": \"internal\"\n                      }\n                    ],\n                    \"src\": \"119:6:1\"\n                  },\n                  \"src\": \"86:40:1\",\n                  \"stateMutability\": \"view\",\n                  \"typeDescriptions\": {},\n                  \"visibility\": \"external\"\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"85:41:1\"\n          },\n          \"src\": \"13:116:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:131:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:132:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/global_enum.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"E\": [\n      2\n    ]\n  },\n  \"id\": 3,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"canonicalName\": \"E\",\n      \"id\": 2,\n      \"members\": [\n        {\n          \"id\": 1,\n          \"name\": \"A\",\n          \"nameLocation\": \"9:1:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"9:1:1\"\n        }\n      ],\n      \"name\": \"E\",\n      \"nameLocation\": \"5:1:1\",\n      \"nodeType\": \"EnumDefinition\",\n      \"src\": \"0:12:1\"\n    }\n  ],\n  \"src\": \"0:13:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/global_enum.sol",
    "content": "enum E { A }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/global_enum_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 3,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"id\": 2,\n      \"members\": [\n        {\n          \"id\": 1,\n          \"name\": \"A\",\n          \"nameLocation\": \"9:1:1\",\n          \"nodeType\": \"EnumValue\",\n          \"src\": \"9:1:1\"\n        }\n      ],\n      \"name\": \"E\",\n      \"nameLocation\": \"5:1:1\",\n      \"nodeType\": \"EnumDefinition\",\n      \"src\": \"0:12:1\"\n    }\n  ],\n  \"src\": \"0:13:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/global_struct.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"S\": [\n      3\n    ]\n  },\n  \"id\": 4,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"canonicalName\": \"S\",\n      \"id\": 3,\n      \"members\": [\n        {\n          \"constant\": false,\n          \"id\": 2,\n          \"mutability\": \"mutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"19:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 3,\n          \"src\": \"11:9:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_uint256\",\n            \"typeString\": \"uint256\"\n          },\n          \"typeName\": {\n            \"id\": 1,\n            \"name\": \"uint256\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"11:7:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_uint256\",\n              \"typeString\": \"uint256\"\n            }\n          },\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"name\": \"S\",\n      \"nameLocation\": \"7:1:1\",\n      \"nodeType\": \"StructDefinition\",\n      \"scope\": 4,\n      \"src\": \"0:23:1\",\n      \"visibility\": \"public\"\n    }\n  ],\n  \"src\": \"0:24:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/global_struct.sol",
    "content": "struct S { uint256 a; }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/global_struct_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 4,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"id\": 3,\n      \"members\": [\n        {\n          \"constant\": false,\n          \"id\": 2,\n          \"mutability\": \"mutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"19:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"11:9:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 1,\n            \"name\": \"uint256\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"11:7:1\",\n            \"typeDescriptions\": {}\n          },\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"name\": \"S\",\n      \"nameLocation\": \"7:1:1\",\n      \"nodeType\": \"StructDefinition\",\n      \"src\": \"0:23:1\",\n      \"visibility\": \"public\"\n    }\n  ],\n  \"src\": \"0:24:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/indirect_event.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      25\n    ],\n    \"L\": [\n      10\n    ]\n  },\n  \"id\": 26,\n  \"license\": \"GPL-3.0\",\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"L\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"library\",\n      \"fullyImplemented\": true,\n      \"id\": 10,\n      \"linearizedBaseContracts\": [\n        10\n      ],\n      \"name\": \"L\",\n      \"nameLocation\": \"44:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"eventSelector\": \"92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\",\n          \"id\": 2,\n          \"name\": \"E\",\n          \"nameLocation\": \"58:1:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"59:2:1\"\n          },\n          \"src\": \"52:10:1\"\n        },\n        {\n          \"body\": {\n            \"id\": 8,\n            \"nodeType\": \"Block\",\n            \"src\": \"89:13:1\",\n            \"statements\": [\n              {\n                \"eventCall\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"id\": 5,\n                    \"name\": \"E\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 2,\n                    \"src\": \"96:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_event_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 6,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"96:3:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 7,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"91:8:1\"\n              }\n            ]\n          },\n          \"id\": 9,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"76:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"77:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 4,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"89:0:1\"\n          },\n          \"scope\": 10,\n          \"src\": \"67:35:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"scope\": 26,\n      \"src\": \"36:68:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        2\n      ]\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 25,\n      \"linearizedBaseContracts\": [\n        25\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"114:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"eventSelector\": \"70a5d861ef9816388422765f41d618eb3abdf490acb37354b539729e37b09f0e\",\n          \"id\": 12,\n          \"name\": \"H\",\n          \"nameLocation\": \"128:1:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"129:2:1\"\n          },\n          \"src\": \"122:10:1\"\n        },\n        {\n          \"body\": {\n            \"id\": 23,\n            \"nodeType\": \"Block\",\n            \"src\": \"157:20:1\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"expression\": {\n                      \"id\": 15,\n                      \"name\": \"L\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 10,\n                      \"src\": \"159:1:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_type$_t_contract$_L_$10_$\",\n                        \"typeString\": \"type(library L)\"\n                      }\n                    },\n                    \"id\": 17,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"memberLocation\": \"161:1:1\",\n                    \"memberName\": \"f\",\n                    \"nodeType\": \"MemberAccess\",\n                    \"referencedDeclaration\": 9,\n                    \"src\": \"159:3:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 18,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"159:5:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 19,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"159:5:1\"\n              },\n              {\n                \"eventCall\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"id\": 20,\n                    \"name\": \"H\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 12,\n                    \"src\": \"171:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_event_nonpayable$__$returns$__$\",\n                      \"typeString\": \"function ()\"\n                    }\n                  },\n                  \"id\": 21,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"171:3:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 22,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"166:8:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"e2179b8e\",\n          \"id\": 24,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"g\",\n          \"nameLocation\": \"146:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 13,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"147:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 14,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"157:0:1\"\n          },\n          \"scope\": 25,\n          \"src\": \"137:40:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 26,\n      \"src\": \"105:74:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": [\n        2,\n        12\n      ]\n    }\n  ],\n  \"src\": \"36:144:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/indirect_event.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\nlibrary L {\n    event E();\n    function f() internal { emit E(); }\n}\ncontract C {\n    event H();\n    function g() public { L.f(); emit H(); }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/indirect_event_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 26,\n  \"license\": \"GPL-3.0\",\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"library\",\n      \"id\": 10,\n      \"name\": \"L\",\n      \"nameLocation\": \"44:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"id\": 2,\n          \"name\": \"E\",\n          \"nameLocation\": \"58:1:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"59:2:1\"\n          },\n          \"src\": \"52:10:1\"\n        },\n        {\n          \"body\": {\n            \"id\": 8,\n            \"nodeType\": \"Block\",\n            \"src\": \"89:13:1\",\n            \"statements\": [\n              {\n                \"eventCall\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"id\": 5,\n                    \"name\": \"E\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"96:1:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"id\": 6,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"96:3:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 7,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"91:8:1\"\n              }\n            ]\n          },\n          \"id\": 9,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"76:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"77:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 4,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"89:0:1\"\n          },\n          \"src\": \"67:35:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"src\": \"36:68:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 25,\n      \"name\": \"C\",\n      \"nameLocation\": \"114:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"anonymous\": false,\n          \"id\": 12,\n          \"name\": \"H\",\n          \"nameLocation\": \"128:1:1\",\n          \"nodeType\": \"EventDefinition\",\n          \"parameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"129:2:1\"\n          },\n          \"src\": \"122:10:1\"\n        },\n        {\n          \"body\": {\n            \"id\": 23,\n            \"nodeType\": \"Block\",\n            \"src\": \"157:20:1\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"expression\": {\n                      \"id\": 15,\n                      \"name\": \"L\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"src\": \"159:1:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"id\": 17,\n                    \"memberLocation\": \"161:1:1\",\n                    \"memberName\": \"f\",\n                    \"nodeType\": \"MemberAccess\",\n                    \"src\": \"159:3:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"id\": 18,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"159:5:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 19,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"159:5:1\"\n              },\n              {\n                \"eventCall\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"id\": 20,\n                    \"name\": \"H\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"171:1:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"id\": 21,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"171:3:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 22,\n                \"nodeType\": \"EmitStatement\",\n                \"src\": \"166:8:1\"\n              }\n            ]\n          },\n          \"id\": 24,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"g\",\n          \"nameLocation\": \"146:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 13,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"147:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 14,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"157:0:1\"\n          },\n          \"src\": \"137:40:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"105:74:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"36:144:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/inheritance_specifier.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C1\": [\n      1\n    ],\n    \"C2\": [\n      4\n    ]\n  },\n  \"id\": 5,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C1\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 1,\n      \"linearizedBaseContracts\": [\n        1\n      ],\n      \"name\": \"C1\",\n      \"nameLocation\": \"9:2:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 5,\n      \"src\": \"0:14:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 2,\n            \"name\": \"C1\",\n            \"nameLocations\": [\n              \"30:2:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 1,\n            \"src\": \"30:2:1\"\n          },\n          \"id\": 3,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"30:2:1\"\n        }\n      ],\n      \"canonicalName\": \"C2\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 4,\n      \"linearizedBaseContracts\": [\n        4,\n        1\n      ],\n      \"name\": \"C2\",\n      \"nameLocation\": \"24:2:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 5,\n      \"src\": \"15:20:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:36:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/inheritance_specifier.sol",
    "content": "contract C1 {} contract C2 is C1 {}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/inheritance_specifier_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 5,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 1,\n      \"name\": \"C1\",\n      \"nameLocation\": \"9:2:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"0:14:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 2,\n            \"name\": \"C1\",\n            \"nameLocations\": [\n              \"30:2:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"30:2:1\"\n          },\n          \"id\": 3,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"30:2:1\"\n        }\n      ],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 4,\n      \"name\": \"C2\",\n      \"nameLocation\": \"24:2:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"15:20:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:36:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/license.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      1\n    ]\n  },\n  \"id\": 2,\n  \"license\": \"GPL-3.0\",\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 1,\n      \"linearizedBaseContracts\": [\n        1\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"45:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 2,\n      \"src\": \"36:13:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"36:14:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/license.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/license_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 2,\n  \"license\": \"GPL-3.0\",\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 1,\n      \"name\": \"C\",\n      \"nameLocation\": \"45:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"36:13:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"36:14:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/long_type_name_binary_operation.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"c\": [\n      11\n    ]\n  },\n  \"id\": 12,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"c\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 11,\n      \"linearizedBaseContracts\": [\n        11\n      ],\n      \"name\": \"c\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 9,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:19:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"a\",\n                    \"nameLocation\": \"40:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 9,\n                    \"src\": \"35:6:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_uint256\",\n                      \"typeString\": \"uint256\"\n                    },\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"uint\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"35:4:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_uint256\",\n                        \"typeString\": \"uint256\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 8,\n                \"initialValue\": {\n                  \"commonType\": {\n                    \"typeIdentifier\": \"t_rational_5_by_1\",\n                    \"typeString\": \"int_const 5\"\n                  },\n                  \"id\": 7,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": true,\n                  \"lValueRequested\": false,\n                  \"leftExpression\": {\n                    \"hexValue\": \"32\",\n                    \"id\": 5,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"kind\": \"number\",\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"44:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_rational_2_by_1\",\n                      \"typeString\": \"int_const 2\"\n                    },\n                    \"value\": \"2\"\n                  },\n                  \"nodeType\": \"BinaryOperation\",\n                  \"operator\": \"+\",\n                  \"rightExpression\": {\n                    \"hexValue\": \"33\",\n                    \"id\": 6,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"kind\": \"number\",\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"48:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_rational_3_by_1\",\n                      \"typeString\": \"int_const 3\"\n                    },\n                    \"value\": \"3\"\n                  },\n                  \"src\": \"44:5:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_rational_5_by_1\",\n                    \"typeString\": \"int_const 5\"\n                  }\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:14:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 10,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"scope\": 11,\n          \"src\": \"13:39:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 12,\n      \"src\": \"0:54:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:55:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/long_type_name_binary_operation.sol",
    "content": "contract c { function f() public { uint a = 2 + 3; } }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/long_type_name_binary_operation_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 12,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 11,\n      \"name\": \"c\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 9,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:19:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"a\",\n                    \"nameLocation\": \"40:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"35:6:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"uint\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"35:4:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 8,\n                \"initialValue\": {\n                  \"commonType\": {},\n                  \"id\": 7,\n                  \"leftExpression\": {\n                    \"hexValue\": \"32\",\n                    \"id\": 5,\n                    \"kind\": \"number\",\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"44:1:1\",\n                    \"typeDescriptions\": {},\n                    \"value\": \"2\"\n                  },\n                  \"nodeType\": \"BinaryOperation\",\n                  \"operator\": \"+\",\n                  \"rightExpression\": {\n                    \"hexValue\": \"33\",\n                    \"id\": 6,\n                    \"kind\": \"number\",\n                    \"nodeType\": \"Literal\",\n                    \"src\": \"48:1:1\",\n                    \"typeDescriptions\": {},\n                    \"value\": \"3\"\n                  },\n                  \"src\": \"44:5:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:14:1\"\n              }\n            ]\n          },\n          \"id\": 10,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"src\": \"13:39:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:54:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:55:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/long_type_name_identifier.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"c\": [\n      15\n    ]\n  },\n  \"id\": 16,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"c\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 15,\n      \"linearizedBaseContracts\": [\n        15\n      ],\n      \"name\": \"c\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 3,\n          \"mutability\": \"mutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"20:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 15,\n          \"src\": \"13:8:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_array$_t_uint256_$dyn_storage\",\n            \"typeString\": \"uint256[]\"\n          },\n          \"typeName\": {\n            \"baseType\": {\n              \"id\": 1,\n              \"name\": \"uint\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"13:4:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_uint256\",\n                \"typeString\": \"uint256\"\n              }\n            },\n            \"id\": 2,\n            \"nodeType\": \"ArrayTypeName\",\n            \"src\": \"13:6:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_array$_t_uint256_$dyn_storage_ptr\",\n              \"typeString\": \"uint256[]\"\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 13,\n            \"nodeType\": \"Block\",\n            \"src\": \"43:25:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  10\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 10,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"b\",\n                    \"nameLocation\": \"60:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 13,\n                    \"src\": \"45:16:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"storage\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_array$_t_uint256_$dyn_storage_ptr\",\n                      \"typeString\": \"uint256[]\"\n                    },\n                    \"typeName\": {\n                      \"baseType\": {\n                        \"id\": 8,\n                        \"name\": \"uint\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"45:4:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_uint256\",\n                          \"typeString\": \"uint256\"\n                        }\n                      },\n                      \"id\": 9,\n                      \"nodeType\": \"ArrayTypeName\",\n                      \"src\": \"45:6:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_array$_t_uint256_$dyn_storage_ptr\",\n                        \"typeString\": \"uint256[]\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 12,\n                \"initialValue\": {\n                  \"id\": 11,\n                  \"name\": \"a\",\n                  \"nodeType\": \"Identifier\",\n                  \"overloadedDeclarations\": [],\n                  \"referencedDeclaration\": 3,\n                  \"src\": \"64:1:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_array$_t_uint256_$dyn_storage\",\n                    \"typeString\": \"uint256[] storage ref\"\n                  }\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"45:20:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 14,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"32:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 4,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 5,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"43:0:1\"\n          },\n          \"scope\": 15,\n          \"src\": \"23:45:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 16,\n      \"src\": \"0:70:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:71:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/long_type_name_identifier.sol",
    "content": "contract c { uint[] a; function f() public { uint[] storage b = a; } }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/long_type_name_identifier_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 16,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 15,\n      \"name\": \"c\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 3,\n          \"mutability\": \"mutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"20:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"13:8:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"baseType\": {\n              \"id\": 1,\n              \"name\": \"uint\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"13:4:1\",\n              \"typeDescriptions\": {}\n            },\n            \"id\": 2,\n            \"nodeType\": \"ArrayTypeName\",\n            \"src\": \"13:6:1\",\n            \"typeDescriptions\": {}\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 13,\n            \"nodeType\": \"Block\",\n            \"src\": \"43:25:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  10\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 10,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"b\",\n                    \"nameLocation\": \"60:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"45:16:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"storage\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"baseType\": {\n                        \"id\": 8,\n                        \"name\": \"uint\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"45:4:1\",\n                        \"typeDescriptions\": {}\n                      },\n                      \"id\": 9,\n                      \"nodeType\": \"ArrayTypeName\",\n                      \"src\": \"45:6:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 12,\n                \"initialValue\": {\n                  \"id\": 11,\n                  \"name\": \"a\",\n                  \"nodeType\": \"Identifier\",\n                  \"overloadedDeclarations\": [],\n                  \"src\": \"64:1:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"45:20:1\"\n              }\n            ]\n          },\n          \"id\": 14,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"32:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 4,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 5,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"43:0:1\"\n          },\n          \"src\": \"23:45:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:70:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:71:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/mappings.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      23\n    ]\n  },\n  \"id\": 24,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 23,\n      \"linearizedBaseContracts\": [\n        23\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"canonicalName\": \"C.E\",\n          \"id\": 4,\n          \"members\": [\n            {\n              \"id\": 1,\n              \"name\": \"A\",\n              \"nameLocation\": \"26:1:1\",\n              \"nodeType\": \"EnumValue\",\n              \"src\": \"26:1:1\"\n            },\n            {\n              \"id\": 2,\n              \"name\": \"B\",\n              \"nameLocation\": \"29:1:1\",\n              \"nodeType\": \"EnumValue\",\n              \"src\": \"29:1:1\"\n            },\n            {\n              \"id\": 3,\n              \"name\": \"C\",\n              \"nameLocation\": \"32:1:1\",\n              \"nodeType\": \"EnumValue\",\n              \"src\": \"32:1:1\"\n            }\n          ],\n          \"name\": \"E\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"EnumDefinition\",\n          \"src\": \"17:18:1\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 9,\n          \"mutability\": \"mutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"59:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 23,\n          \"src\": \"40:20:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_mapping$_t_contract$_C_$23_$_t_bool_$\",\n            \"typeString\": \"mapping(contract C => bool)\"\n          },\n          \"typeName\": {\n            \"id\": 8,\n            \"keyName\": \"\",\n            \"keyNameLocation\": \"-1:-1:-1\",\n            \"keyType\": {\n              \"id\": 6,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 5,\n                \"name\": \"C\",\n                \"nameLocations\": [\n                  \"48:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 23,\n                \"src\": \"48:1:1\"\n              },\n              \"referencedDeclaration\": 23,\n              \"src\": \"48:1:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_contract$_C_$23\",\n                \"typeString\": \"contract C\"\n              }\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"40:18:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_mapping$_t_contract$_C_$23_$_t_bool_$\",\n              \"typeString\": \"mapping(contract C => bool)\"\n            },\n            \"valueName\": \"\",\n            \"valueNameLocation\": \"-1:-1:-1\",\n            \"valueType\": {\n              \"id\": 7,\n              \"name\": \"bool\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"53:4:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_bool\",\n                \"typeString\": \"bool\"\n              }\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 13,\n          \"mutability\": \"mutable\",\n          \"name\": \"b\",\n          \"nameLocation\": \"91:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 23,\n          \"src\": \"66:26:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_mapping$_t_address_$_t_bool_$\",\n            \"typeString\": \"mapping(address => bool)\"\n          },\n          \"typeName\": {\n            \"id\": 12,\n            \"keyName\": \"\",\n            \"keyNameLocation\": \"-1:-1:-1\",\n            \"keyType\": {\n              \"id\": 10,\n              \"name\": \"address\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"74:7:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_address\",\n                \"typeString\": \"address\"\n              }\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"66:24:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_mapping$_t_address_$_t_bool_$\",\n              \"typeString\": \"mapping(address => bool)\"\n            },\n            \"valueName\": \"\",\n            \"valueNameLocation\": \"-1:-1:-1\",\n            \"valueType\": {\n              \"id\": 11,\n              \"name\": \"bool\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"85:4:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_bool\",\n                \"typeString\": \"bool\"\n              }\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 18,\n          \"mutability\": \"mutable\",\n          \"name\": \"c\",\n          \"nameLocation\": \"117:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 23,\n          \"src\": \"98:20:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_mapping$_t_enum$_E_$4_$_t_bool_$\",\n            \"typeString\": \"mapping(enum C.E => bool)\"\n          },\n          \"typeName\": {\n            \"id\": 17,\n            \"keyName\": \"\",\n            \"keyNameLocation\": \"-1:-1:-1\",\n            \"keyType\": {\n              \"id\": 15,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 14,\n                \"name\": \"E\",\n                \"nameLocations\": [\n                  \"106:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 4,\n                \"src\": \"106:1:1\"\n              },\n              \"referencedDeclaration\": 4,\n              \"src\": \"106:1:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_enum$_E_$4\",\n                \"typeString\": \"enum C.E\"\n              }\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"98:18:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_mapping$_t_enum$_E_$4_$_t_bool_$\",\n              \"typeString\": \"mapping(enum C.E => bool)\"\n            },\n            \"valueName\": \"\",\n            \"valueNameLocation\": \"-1:-1:-1\",\n            \"valueType\": {\n              \"id\": 16,\n              \"name\": \"bool\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"111:4:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_bool\",\n                \"typeString\": \"bool\"\n              }\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 22,\n          \"mutability\": \"mutable\",\n          \"name\": \"d\",\n          \"nameLocation\": \"169:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 23,\n          \"src\": \"124:46:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_mapping$_t_address_$_t_uint256_$\",\n            \"typeString\": \"mapping(address => uint256)\"\n          },\n          \"typeName\": {\n            \"id\": 21,\n            \"keyName\": \"keyAddress\",\n            \"keyNameLocation\": \"140:10:1\",\n            \"keyType\": {\n              \"id\": 19,\n              \"name\": \"address\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"132:7:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_address\",\n                \"typeString\": \"address\"\n              }\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"124:44:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_mapping$_t_address_$_t_uint256_$\",\n              \"typeString\": \"mapping(address => uint256)\"\n            },\n            \"valueName\": \"value\",\n            \"valueNameLocation\": \"162:5:1\",\n            \"valueType\": {\n              \"id\": 20,\n              \"name\": \"uint256\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"154:7:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_uint256\",\n                \"typeString\": \"uint256\"\n              }\n            }\n          },\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"scope\": 24,\n      \"src\": \"0:173:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:174:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/mappings.sol",
    "content": "contract C {\n    enum E { A, B, C }\n    mapping(C => bool) a;\n    mapping(address => bool) b;\n    mapping(E => bool) c;\n    mapping(address keyAddress => uint256 value) d;\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/mappings_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 24,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 23,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"id\": 4,\n          \"members\": [\n            {\n              \"id\": 1,\n              \"name\": \"A\",\n              \"nameLocation\": \"26:1:1\",\n              \"nodeType\": \"EnumValue\",\n              \"src\": \"26:1:1\"\n            },\n            {\n              \"id\": 2,\n              \"name\": \"B\",\n              \"nameLocation\": \"29:1:1\",\n              \"nodeType\": \"EnumValue\",\n              \"src\": \"29:1:1\"\n            },\n            {\n              \"id\": 3,\n              \"name\": \"C\",\n              \"nameLocation\": \"32:1:1\",\n              \"nodeType\": \"EnumValue\",\n              \"src\": \"32:1:1\"\n            }\n          ],\n          \"name\": \"E\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"EnumDefinition\",\n          \"src\": \"17:18:1\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 9,\n          \"mutability\": \"mutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"59:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"40:20:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 8,\n            \"keyName\": \"\",\n            \"keyNameLocation\": \"-1:-1:-1\",\n            \"keyType\": {\n              \"id\": 6,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 5,\n                \"name\": \"C\",\n                \"nameLocations\": [\n                  \"48:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"src\": \"48:1:1\"\n              },\n              \"src\": \"48:1:1\",\n              \"typeDescriptions\": {}\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"40:18:1\",\n            \"typeDescriptions\": {},\n            \"valueName\": \"\",\n            \"valueNameLocation\": \"-1:-1:-1\",\n            \"valueType\": {\n              \"id\": 7,\n              \"name\": \"bool\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"53:4:1\",\n              \"typeDescriptions\": {}\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 13,\n          \"mutability\": \"mutable\",\n          \"name\": \"b\",\n          \"nameLocation\": \"91:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"66:26:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 12,\n            \"keyName\": \"\",\n            \"keyNameLocation\": \"-1:-1:-1\",\n            \"keyType\": {\n              \"id\": 10,\n              \"name\": \"address\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"74:7:1\",\n              \"typeDescriptions\": {}\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"66:24:1\",\n            \"typeDescriptions\": {},\n            \"valueName\": \"\",\n            \"valueNameLocation\": \"-1:-1:-1\",\n            \"valueType\": {\n              \"id\": 11,\n              \"name\": \"bool\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"85:4:1\",\n              \"typeDescriptions\": {}\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 18,\n          \"mutability\": \"mutable\",\n          \"name\": \"c\",\n          \"nameLocation\": \"117:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"98:20:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 17,\n            \"keyName\": \"\",\n            \"keyNameLocation\": \"-1:-1:-1\",\n            \"keyType\": {\n              \"id\": 15,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 14,\n                \"name\": \"E\",\n                \"nameLocations\": [\n                  \"106:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"src\": \"106:1:1\"\n              },\n              \"src\": \"106:1:1\",\n              \"typeDescriptions\": {}\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"98:18:1\",\n            \"typeDescriptions\": {},\n            \"valueName\": \"\",\n            \"valueNameLocation\": \"-1:-1:-1\",\n            \"valueType\": {\n              \"id\": 16,\n              \"name\": \"bool\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"111:4:1\",\n              \"typeDescriptions\": {}\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 22,\n          \"mutability\": \"mutable\",\n          \"name\": \"d\",\n          \"nameLocation\": \"169:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"124:46:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 21,\n            \"keyName\": \"keyAddress\",\n            \"keyNameLocation\": \"140:10:1\",\n            \"keyType\": {\n              \"id\": 19,\n              \"name\": \"address\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"132:7:1\",\n              \"typeDescriptions\": {}\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"124:44:1\",\n            \"typeDescriptions\": {},\n            \"valueName\": \"value\",\n            \"valueNameLocation\": \"162:5:1\",\n            \"valueType\": {\n              \"id\": 20,\n              \"name\": \"uint256\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"154:7:1\",\n              \"typeDescriptions\": {}\n            }\n          },\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"src\": \"0:173:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:174:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/modifier_definition.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      14\n    ]\n  },\n  \"id\": 15,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 14,\n      \"linearizedBaseContracts\": [\n        14\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 5,\n            \"nodeType\": \"Block\",\n            \"src\": \"32:6:1\",\n            \"statements\": [\n              {\n                \"id\": 4,\n                \"nodeType\": \"PlaceholderStatement\",\n                \"src\": \"34:1:1\"\n              }\n            ]\n          },\n          \"id\": 6,\n          \"name\": \"M\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"ModifierDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 2,\n                \"mutability\": \"mutable\",\n                \"name\": \"i\",\n                \"nameLocation\": \"29:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 6,\n                \"src\": \"24:6:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                },\n                \"typeName\": {\n                  \"id\": 1,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"24:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"23:8:1\"\n          },\n          \"src\": \"13:25:1\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 12,\n            \"nodeType\": \"Block\",\n            \"src\": \"64:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"28811f59\",\n          \"id\": 13,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [\n            {\n              \"arguments\": [\n                {\n                  \"hexValue\": \"31\",\n                  \"id\": 9,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": true,\n                  \"kind\": \"number\",\n                  \"lValueRequested\": false,\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"54:1:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_rational_1_by_1\",\n                    \"typeString\": \"int_const 1\"\n                  },\n                  \"value\": \"1\"\n                }\n              ],\n              \"id\": 10,\n              \"kind\": \"modifierInvocation\",\n              \"modifierName\": {\n                \"id\": 8,\n                \"name\": \"M\",\n                \"nameLocations\": [\n                  \"52:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 6,\n                \"src\": \"52:1:1\"\n              },\n              \"nodeType\": \"ModifierInvocation\",\n              \"src\": \"52:4:1\"\n            }\n          ],\n          \"name\": \"F\",\n          \"nameLocation\": \"48:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"49:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"64:0:1\"\n          },\n          \"scope\": 14,\n          \"src\": \"39:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 15,\n      \"src\": \"0:68:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:69:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/modifier_definition.sol",
    "content": "contract C { modifier M(uint i) { _; } function F() M(1) public {} }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/modifier_definition_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 15,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 14,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 5,\n            \"nodeType\": \"Block\",\n            \"src\": \"32:6:1\",\n            \"statements\": [\n              {\n                \"id\": 4,\n                \"nodeType\": \"PlaceholderStatement\",\n                \"src\": \"34:1:1\"\n              }\n            ]\n          },\n          \"id\": 6,\n          \"name\": \"M\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"ModifierDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 2,\n                \"mutability\": \"mutable\",\n                \"name\": \"i\",\n                \"nameLocation\": \"29:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"24:6:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 1,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"24:4:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"23:8:1\"\n          },\n          \"src\": \"13:25:1\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 12,\n            \"nodeType\": \"Block\",\n            \"src\": \"64:2:1\",\n            \"statements\": []\n          },\n          \"id\": 13,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [\n            {\n              \"arguments\": [\n                {\n                  \"hexValue\": \"31\",\n                  \"id\": 9,\n                  \"kind\": \"number\",\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"54:1:1\",\n                  \"typeDescriptions\": {},\n                  \"value\": \"1\"\n                }\n              ],\n              \"id\": 10,\n              \"modifierName\": {\n                \"id\": 8,\n                \"name\": \"M\",\n                \"nameLocations\": [\n                  \"52:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"src\": \"52:1:1\"\n              },\n              \"nodeType\": \"ModifierInvocation\",\n              \"src\": \"52:4:1\"\n            }\n          ],\n          \"name\": \"F\",\n          \"nameLocation\": \"48:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"49:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"64:0:1\"\n          },\n          \"src\": \"39:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:68:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:69:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/modifier_invocation.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      14\n    ]\n  },\n  \"id\": 15,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 14,\n      \"linearizedBaseContracts\": [\n        14\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 5,\n            \"nodeType\": \"Block\",\n            \"src\": \"32:6:1\",\n            \"statements\": [\n              {\n                \"id\": 4,\n                \"nodeType\": \"PlaceholderStatement\",\n                \"src\": \"34:1:1\"\n              }\n            ]\n          },\n          \"id\": 6,\n          \"name\": \"M\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"ModifierDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 2,\n                \"mutability\": \"mutable\",\n                \"name\": \"i\",\n                \"nameLocation\": \"29:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 6,\n                \"src\": \"24:6:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_uint256\",\n                  \"typeString\": \"uint256\"\n                },\n                \"typeName\": {\n                  \"id\": 1,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"24:4:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"23:8:1\"\n          },\n          \"src\": \"13:25:1\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 12,\n            \"nodeType\": \"Block\",\n            \"src\": \"64:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"28811f59\",\n          \"id\": 13,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [\n            {\n              \"arguments\": [\n                {\n                  \"hexValue\": \"31\",\n                  \"id\": 9,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": true,\n                  \"kind\": \"number\",\n                  \"lValueRequested\": false,\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"54:1:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_rational_1_by_1\",\n                    \"typeString\": \"int_const 1\"\n                  },\n                  \"value\": \"1\"\n                }\n              ],\n              \"id\": 10,\n              \"kind\": \"modifierInvocation\",\n              \"modifierName\": {\n                \"id\": 8,\n                \"name\": \"M\",\n                \"nameLocations\": [\n                  \"52:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 6,\n                \"src\": \"52:1:1\"\n              },\n              \"nodeType\": \"ModifierInvocation\",\n              \"src\": \"52:4:1\"\n            }\n          ],\n          \"name\": \"F\",\n          \"nameLocation\": \"48:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"49:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"64:0:1\"\n          },\n          \"scope\": 14,\n          \"src\": \"39:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 15,\n      \"src\": \"0:68:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:69:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/modifier_invocation.sol",
    "content": "contract C { modifier M(uint i) { _; } function F() M(1) public {} }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/modifier_invocation_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 15,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 14,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 5,\n            \"nodeType\": \"Block\",\n            \"src\": \"32:6:1\",\n            \"statements\": [\n              {\n                \"id\": 4,\n                \"nodeType\": \"PlaceholderStatement\",\n                \"src\": \"34:1:1\"\n              }\n            ]\n          },\n          \"id\": 6,\n          \"name\": \"M\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"ModifierDefinition\",\n          \"parameters\": {\n            \"id\": 3,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 2,\n                \"mutability\": \"mutable\",\n                \"name\": \"i\",\n                \"nameLocation\": \"29:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"24:6:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 1,\n                  \"name\": \"uint\",\n                  \"nodeType\": \"ElementaryTypeName\",\n                  \"src\": \"24:4:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"23:8:1\"\n          },\n          \"src\": \"13:25:1\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        },\n        {\n          \"body\": {\n            \"id\": 12,\n            \"nodeType\": \"Block\",\n            \"src\": \"64:2:1\",\n            \"statements\": []\n          },\n          \"id\": 13,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [\n            {\n              \"arguments\": [\n                {\n                  \"hexValue\": \"31\",\n                  \"id\": 9,\n                  \"kind\": \"number\",\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"54:1:1\",\n                  \"typeDescriptions\": {},\n                  \"value\": \"1\"\n                }\n              ],\n              \"id\": 10,\n              \"modifierName\": {\n                \"id\": 8,\n                \"name\": \"M\",\n                \"nameLocations\": [\n                  \"52:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"src\": \"52:1:1\"\n              },\n              \"nodeType\": \"ModifierInvocation\",\n              \"src\": \"52:4:1\"\n            }\n          ],\n          \"name\": \"F\",\n          \"nameLocation\": \"48:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"49:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"64:0:1\"\n          },\n          \"src\": \"39:27:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:68:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:69:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/mutability.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      10\n    ]\n  },\n  \"id\": 11,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 10,\n      \"linearizedBaseContracts\": [\n        10\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"functionSelector\": \"0dbe671f\",\n          \"id\": 3,\n          \"mutability\": \"immutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"39:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 10,\n          \"src\": \"17:27:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_uint256\",\n            \"typeString\": \"uint256\"\n          },\n          \"typeName\": {\n            \"id\": 1,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"17:4:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_uint256\",\n              \"typeString\": \"uint256\"\n            }\n          },\n          \"value\": {\n            \"hexValue\": \"34\",\n            \"id\": 2,\n            \"isConstant\": false,\n            \"isLValue\": false,\n            \"isPure\": true,\n            \"kind\": \"number\",\n            \"lValueRequested\": false,\n            \"nodeType\": \"Literal\",\n            \"src\": \"43:1:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_rational_4_by_1\",\n              \"typeString\": \"int_const 4\"\n            },\n            \"value\": \"4\"\n          },\n          \"visibility\": \"public\"\n        },\n        {\n          \"constant\": true,\n          \"functionSelector\": \"4df7e3d0\",\n          \"id\": 6,\n          \"mutability\": \"constant\",\n          \"name\": \"b\",\n          \"nameLocation\": \"71:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 10,\n          \"src\": \"50:26:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_uint256\",\n            \"typeString\": \"uint256\"\n          },\n          \"typeName\": {\n            \"id\": 4,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"50:4:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_uint256\",\n              \"typeString\": \"uint256\"\n            }\n          },\n          \"value\": {\n            \"hexValue\": \"32\",\n            \"id\": 5,\n            \"isConstant\": false,\n            \"isLValue\": false,\n            \"isPure\": true,\n            \"kind\": \"number\",\n            \"lValueRequested\": false,\n            \"nodeType\": \"Literal\",\n            \"src\": \"75:1:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_rational_2_by_1\",\n              \"typeString\": \"int_const 2\"\n            },\n            \"value\": \"2\"\n          },\n          \"visibility\": \"public\"\n        },\n        {\n          \"constant\": false,\n          \"functionSelector\": \"c3da42b8\",\n          \"id\": 9,\n          \"mutability\": \"mutable\",\n          \"name\": \"c\",\n          \"nameLocation\": \"94:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 10,\n          \"src\": \"82:17:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_uint256\",\n            \"typeString\": \"uint256\"\n          },\n          \"typeName\": {\n            \"id\": 7,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"82:4:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_uint256\",\n              \"typeString\": \"uint256\"\n            }\n          },\n          \"value\": {\n            \"hexValue\": \"33\",\n            \"id\": 8,\n            \"isConstant\": false,\n            \"isLValue\": false,\n            \"isPure\": true,\n            \"kind\": \"number\",\n            \"lValueRequested\": false,\n            \"nodeType\": \"Literal\",\n            \"src\": \"98:1:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_rational_3_by_1\",\n              \"typeString\": \"int_const 3\"\n            },\n            \"value\": \"3\"\n          },\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 11,\n      \"src\": \"0:102:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:103:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/mutability.sol",
    "content": "contract C\n{\n    uint public immutable a = 4;\n    uint public constant b = 2;\n    uint public c = 3;\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/mutability_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 11,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 10,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 3,\n          \"mutability\": \"immutable\",\n          \"name\": \"a\",\n          \"nameLocation\": \"39:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"17:27:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 1,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"17:4:1\",\n            \"typeDescriptions\": {}\n          },\n          \"value\": {\n            \"hexValue\": \"34\",\n            \"id\": 2,\n            \"kind\": \"number\",\n            \"nodeType\": \"Literal\",\n            \"src\": \"43:1:1\",\n            \"typeDescriptions\": {},\n            \"value\": \"4\"\n          },\n          \"visibility\": \"public\"\n        },\n        {\n          \"constant\": true,\n          \"id\": 6,\n          \"mutability\": \"constant\",\n          \"name\": \"b\",\n          \"nameLocation\": \"71:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"50:26:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 4,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"50:4:1\",\n            \"typeDescriptions\": {}\n          },\n          \"value\": {\n            \"hexValue\": \"32\",\n            \"id\": 5,\n            \"kind\": \"number\",\n            \"nodeType\": \"Literal\",\n            \"src\": \"75:1:1\",\n            \"typeDescriptions\": {},\n            \"value\": \"2\"\n          },\n          \"visibility\": \"public\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 9,\n          \"mutability\": \"mutable\",\n          \"name\": \"c\",\n          \"nameLocation\": \"94:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"82:17:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 7,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"82:4:1\",\n            \"typeDescriptions\": {}\n          },\n          \"value\": {\n            \"hexValue\": \"33\",\n            \"id\": 8,\n            \"kind\": \"number\",\n            \"nodeType\": \"Literal\",\n            \"src\": \"98:1:1\",\n            \"typeDescriptions\": {},\n            \"value\": \"3\"\n          },\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:102:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:103:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/non_utf8.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      15\n    ]\n  },\n  \"id\": 16,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 15,\n      \"linearizedBaseContracts\": [\n        15\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 13,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:45:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"49:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 13,\n                    \"src\": \"35:15:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"memory\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_string_memory_ptr\",\n                      \"typeString\": \"string\"\n                    },\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"string\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"35:6:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_string_storage_ptr\",\n                        \"typeString\": \"string\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 12,\n                \"initialValue\": {\n                  \"arguments\": [\n                    {\n                      \"arguments\": [\n                        {\n                          \"hexValue\": \"ff\",\n                          \"id\": 9,\n                          \"isConstant\": false,\n                          \"isLValue\": false,\n                          \"isPure\": true,\n                          \"kind\": \"hexString\",\n                          \"lValueRequested\": false,\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"66:7:1\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_stringliteral_8b1a944cf13a9a1c08facb2c9e98623ef3254d2ddb48113885c3e8e97fec8db9\",\n                            \"typeString\": \"literal_string hex\\\"ff\\\"\"\n                          }\n                        }\n                      ],\n                      \"expression\": {\n                        \"argumentTypes\": [\n                          {\n                            \"typeIdentifier\": \"t_stringliteral_8b1a944cf13a9a1c08facb2c9e98623ef3254d2ddb48113885c3e8e97fec8db9\",\n                            \"typeString\": \"literal_string hex\\\"ff\\\"\"\n                          }\n                        ],\n                        \"id\": 8,\n                        \"isConstant\": false,\n                        \"isLValue\": false,\n                        \"isPure\": true,\n                        \"lValueRequested\": false,\n                        \"nodeType\": \"ElementaryTypeNameExpression\",\n                        \"src\": \"60:5:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_type$_t_bytes_storage_ptr_$\",\n                          \"typeString\": \"type(bytes storage pointer)\"\n                        },\n                        \"typeName\": {\n                          \"id\": 7,\n                          \"name\": \"bytes\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"60:5:1\",\n                          \"typeDescriptions\": {}\n                        }\n                      },\n                      \"id\": 10,\n                      \"isConstant\": false,\n                      \"isLValue\": false,\n                      \"isPure\": true,\n                      \"kind\": \"typeConversion\",\n                      \"lValueRequested\": false,\n                      \"nameLocations\": [],\n                      \"names\": [],\n                      \"nodeType\": \"FunctionCall\",\n                      \"src\": \"60:14:1\",\n                      \"tryCall\": false,\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_bytes_memory_ptr\",\n                        \"typeString\": \"bytes memory\"\n                      }\n                    }\n                  ],\n                  \"expression\": {\n                    \"argumentTypes\": [\n                      {\n                        \"typeIdentifier\": \"t_bytes_memory_ptr\",\n                        \"typeString\": \"bytes memory\"\n                      }\n                    ],\n                    \"id\": 6,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": true,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"ElementaryTypeNameExpression\",\n                    \"src\": \"53:6:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_type$_t_string_storage_ptr_$\",\n                      \"typeString\": \"type(string storage pointer)\"\n                    },\n                    \"typeName\": {\n                      \"id\": 5,\n                      \"name\": \"string\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"53:6:1\",\n                      \"typeDescriptions\": {}\n                    }\n                  },\n                  \"id\": 11,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": true,\n                  \"kind\": \"typeConversion\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"53:22:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_string_memory_ptr\",\n                    \"typeString\": \"string memory\"\n                  }\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:40:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 14,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"scope\": 15,\n          \"src\": \"13:65:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 16,\n      \"src\": \"0:80:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:81:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/non_utf8.sol",
    "content": "contract C { function f() public { string memory x = string(bytes(hex\"ff\")); } }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/non_utf8_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 16,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 15,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 13,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:45:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"49:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"35:15:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"memory\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"string\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"35:6:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 12,\n                \"initialValue\": {\n                  \"arguments\": [\n                    {\n                      \"arguments\": [\n                        {\n                          \"hexValue\": \"ff\",\n                          \"id\": 9,\n                          \"kind\": \"hexString\",\n                          \"nodeType\": \"Literal\",\n                          \"src\": \"66:7:1\",\n                          \"typeDescriptions\": {}\n                        }\n                      ],\n                      \"expression\": {\n                        \"id\": 8,\n                        \"nodeType\": \"ElementaryTypeNameExpression\",\n                        \"src\": \"60:5:1\",\n                        \"typeDescriptions\": {},\n                        \"typeName\": {\n                          \"id\": 7,\n                          \"name\": \"bytes\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"60:5:1\",\n                          \"typeDescriptions\": {}\n                        }\n                      },\n                      \"id\": 10,\n                      \"nameLocations\": [],\n                      \"names\": [],\n                      \"nodeType\": \"FunctionCall\",\n                      \"src\": \"60:14:1\",\n                      \"tryCall\": false,\n                      \"typeDescriptions\": {}\n                    }\n                  ],\n                  \"expression\": {\n                    \"id\": 6,\n                    \"nodeType\": \"ElementaryTypeNameExpression\",\n                    \"src\": \"53:6:1\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 5,\n                      \"name\": \"string\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"53:6:1\",\n                      \"typeDescriptions\": {}\n                    }\n                  },\n                  \"id\": 11,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"53:22:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {}\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:40:1\"\n              }\n            ]\n          },\n          \"id\": 14,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"src\": \"13:65:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:80:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:81:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/not_existing_import.sol",
    "content": "import \"notexisting.sol\" as NotExisting;\ncontract C is NotExisting.X\n{\n\tNotExisting.SomeStruct public myStruct;\n\tconstructor() {}\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/not_existing_import_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 12,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"absolutePath\": \"notexisting.sol\",\n      \"file\": \"notexisting.sol\",\n      \"id\": 1,\n      \"nameLocation\": \"28:11:1\",\n      \"nodeType\": \"ImportDirective\",\n      \"src\": \"0:40:1\",\n      \"symbolAliases\": [],\n      \"unitAlias\": \"NotExisting\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 2,\n            \"name\": \"NotExisting.X\",\n            \"nameLocations\": [\n              \"55:11:1\",\n              \"67:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"55:13:1\"\n          },\n          \"id\": 3,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"55:13:1\"\n        }\n      ],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 11,\n      \"name\": \"C\",\n      \"nameLocation\": \"50:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"constant\": false,\n          \"id\": 6,\n          \"mutability\": \"mutable\",\n          \"name\": \"myStruct\",\n          \"nameLocation\": \"102:8:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"72:38:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 5,\n            \"nodeType\": \"UserDefinedTypeName\",\n            \"pathNode\": {\n              \"id\": 4,\n              \"name\": \"NotExisting.SomeStruct\",\n              \"nameLocations\": [\n                \"72:11:1\",\n                \"84:10:1\"\n              ],\n              \"nodeType\": \"IdentifierPath\",\n              \"src\": \"72:22:1\"\n            },\n            \"src\": \"72:22:1\",\n            \"typeDescriptions\": {}\n          },\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 9,\n            \"nodeType\": \"Block\",\n            \"src\": \"127:2:1\",\n            \"statements\": []\n          },\n          \"id\": 10,\n          \"implemented\": true,\n          \"kind\": \"constructor\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"124:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 8,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"127:0:1\"\n          },\n          \"src\": \"113:16:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false\n        }\n      ],\n      \"src\": \"41:90:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:132:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/override.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"A\": [\n      5\n    ],\n    \"B\": [\n      16\n    ],\n    \"C\": [\n      29\n    ]\n  },\n  \"id\": 30,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"A\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"A\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"44:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"a399b6a2\",\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"faa\",\n          \"nameLocation\": \"23:3:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"26:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"44:0:1\"\n          },\n          \"scope\": 5,\n          \"src\": \"14:32:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": true,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 30,\n      \"src\": \"0:48:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": true,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 6,\n            \"name\": \"A\",\n            \"nameLocations\": [\n              \"72:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 5,\n            \"src\": \"72:1:1\"\n          },\n          \"id\": 7,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"72:1:1\"\n        }\n      ],\n      \"canonicalName\": \"B\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": false,\n      \"id\": 16,\n      \"linearizedBaseContracts\": [\n        16,\n        5\n      ],\n      \"name\": \"B\",\n      \"nameLocation\": \"67:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"functionSelector\": \"c2985578\",\n          \"id\": 10,\n          \"implemented\": false,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"foo\",\n          \"nameLocation\": \"86:3:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 8,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"89:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 9,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"106:0:1\"\n          },\n          \"scope\": 16,\n          \"src\": \"77:30:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": true,\n          \"visibility\": \"public\"\n        },\n        {\n          \"baseFunctions\": [\n            4\n          ],\n          \"body\": {\n            \"id\": 14,\n            \"nodeType\": \"Block\",\n            \"src\": \"148:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"a399b6a2\",\n          \"id\": 15,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"faa\",\n          \"nameLocation\": \"118:3:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"overrides\": {\n            \"id\": 12,\n            \"nodeType\": \"OverrideSpecifier\",\n            \"overrides\": [],\n            \"src\": \"139:8:1\"\n          },\n          \"parameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"121:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 13,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"148:0:1\"\n          },\n          \"scope\": 16,\n          \"src\": \"109:41:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": true,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 30,\n      \"src\": \"49:103:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 17,\n            \"name\": \"B\",\n            \"nameLocations\": [\n              \"167:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 16,\n            \"src\": \"167:1:1\"\n          },\n          \"id\": 18,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"167:1:1\"\n        }\n      ],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 29,\n      \"linearizedBaseContracts\": [\n        29,\n        16,\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"162:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"baseFunctions\": [\n            10\n          ],\n          \"body\": {\n            \"id\": 22,\n            \"nodeType\": \"Block\",\n            \"src\": \"203:3:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"c2985578\",\n          \"id\": 23,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"foo\",\n          \"nameLocation\": \"181:3:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"overrides\": {\n            \"id\": 20,\n            \"nodeType\": \"OverrideSpecifier\",\n            \"overrides\": [],\n            \"src\": \"194:8:1\"\n          },\n          \"parameters\": {\n            \"id\": 19,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"184:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 21,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"203:0:1\"\n          },\n          \"scope\": 29,\n          \"src\": \"172:34:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        },\n        {\n          \"baseFunctions\": [\n            15\n          ],\n          \"body\": {\n            \"id\": 27,\n            \"nodeType\": \"Block\",\n            \"src\": \"239:3:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"a399b6a2\",\n          \"id\": 28,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"faa\",\n          \"nameLocation\": \"217:3:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"overrides\": {\n            \"id\": 25,\n            \"nodeType\": \"OverrideSpecifier\",\n            \"overrides\": [],\n            \"src\": \"230:8:1\"\n          },\n          \"parameters\": {\n            \"id\": 24,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"220:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 26,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"239:0:1\"\n          },\n          \"scope\": 29,\n          \"src\": \"208:34:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 30,\n      \"src\": \"153:91:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:245:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/override.sol",
    "content": "contract A {\n\tfunction faa() public virtual {}\n}\nabstract contract B is A {\n\tfunction foo() public virtual;\n\tfunction faa() public virtual override {}\n}\ncontract C is B {\n\tfunction foo() public override { }\n\tfunction faa() public override { }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/override_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 30,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 5,\n      \"name\": \"A\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"44:2:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"faa\",\n          \"nameLocation\": \"23:3:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"26:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"44:0:1\"\n          },\n          \"src\": \"14:32:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": true,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:48:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": true,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 6,\n            \"name\": \"A\",\n            \"nameLocations\": [\n              \"72:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"72:1:1\"\n          },\n          \"id\": 7,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"72:1:1\"\n        }\n      ],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 16,\n      \"name\": \"B\",\n      \"nameLocation\": \"67:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"id\": 10,\n          \"implemented\": false,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"foo\",\n          \"nameLocation\": \"86:3:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 8,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"89:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 9,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"106:0:1\"\n          },\n          \"src\": \"77:30:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": true,\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 14,\n            \"nodeType\": \"Block\",\n            \"src\": \"148:2:1\",\n            \"statements\": []\n          },\n          \"id\": 15,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"faa\",\n          \"nameLocation\": \"118:3:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"overrides\": {\n            \"id\": 12,\n            \"nodeType\": \"OverrideSpecifier\",\n            \"overrides\": [],\n            \"src\": \"139:8:1\"\n          },\n          \"parameters\": {\n            \"id\": 11,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"121:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 13,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"148:0:1\"\n          },\n          \"src\": \"109:41:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": true,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"49:103:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 17,\n            \"name\": \"B\",\n            \"nameLocations\": [\n              \"167:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"167:1:1\"\n          },\n          \"id\": 18,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"167:1:1\"\n        }\n      ],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 29,\n      \"name\": \"C\",\n      \"nameLocation\": \"162:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 22,\n            \"nodeType\": \"Block\",\n            \"src\": \"203:3:1\",\n            \"statements\": []\n          },\n          \"id\": 23,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"foo\",\n          \"nameLocation\": \"181:3:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"overrides\": {\n            \"id\": 20,\n            \"nodeType\": \"OverrideSpecifier\",\n            \"overrides\": [],\n            \"src\": \"194:8:1\"\n          },\n          \"parameters\": {\n            \"id\": 19,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"184:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 21,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"203:0:1\"\n          },\n          \"src\": \"172:34:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        },\n        {\n          \"body\": {\n            \"id\": 27,\n            \"nodeType\": \"Block\",\n            \"src\": \"239:3:1\",\n            \"statements\": []\n          },\n          \"id\": 28,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"faa\",\n          \"nameLocation\": \"217:3:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"overrides\": {\n            \"id\": 25,\n            \"nodeType\": \"OverrideSpecifier\",\n            \"overrides\": [],\n            \"src\": \"230:8:1\"\n          },\n          \"parameters\": {\n            \"id\": 24,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"220:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 26,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"239:0:1\"\n          },\n          \"src\": \"208:34:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"153:91:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:245:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/placeholder_statement.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      5\n    ]\n  },\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"24:6:1\",\n            \"statements\": [\n              {\n                \"id\": 2,\n                \"nodeType\": \"PlaceholderStatement\",\n                \"src\": \"26:1:1\"\n              }\n            ]\n          },\n          \"id\": 4,\n          \"name\": \"M\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"ModifierDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"24:0:1\"\n          },\n          \"src\": \"13:17:1\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"scope\": 6,\n      \"src\": \"0:32:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:33:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/placeholder_statement.sol",
    "content": "contract C { modifier M { _; } }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/placeholder_statement_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 5,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"24:6:1\",\n            \"statements\": [\n              {\n                \"id\": 2,\n                \"nodeType\": \"PlaceholderStatement\",\n                \"src\": \"26:1:1\"\n              }\n            ]\n          },\n          \"id\": 4,\n          \"name\": \"M\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"ModifierDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"24:0:1\"\n          },\n          \"src\": \"13:17:1\",\n          \"virtual\": false,\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"src\": \"0:32:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:33:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/pragma_experimental_solidity.sol",
    "content": "pragma experimental solidity;\n// ====\n// EVMVersion: >=constantinople\n// ----\n// failAfter: Parsed\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/pragma_experimental_solidity_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"experimentalSolidity\": true,\n  \"id\": 2,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"id\": 1,\n      \"literals\": [\n        \"experimental\",\n        \"solidity\"\n      ],\n      \"nodeType\": \"PragmaDirective\",\n      \"src\": \"0:29:1\"\n    }\n  ],\n  \"src\": \"0:70:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/receive_ether.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      5\n    ]\n  },\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:5:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"receive\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"22:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"scope\": 5,\n          \"src\": \"15:32:1\",\n          \"stateMutability\": \"payable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        }\n      ],\n      \"scope\": 6,\n      \"src\": \"0:49:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:50:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/receive_ether.sol",
    "content": "contract C {\n  receive() external payable {\n  }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/receive_ether_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 5,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"42:5:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"receive\",\n          \"modifiers\": [],\n          \"name\": \"\",\n          \"nameLocation\": \"-1:-1:-1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"22:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"42:0:1\"\n          },\n          \"src\": \"15:32:1\",\n          \"stateMutability\": \"payable\",\n          \"virtual\": false,\n          \"visibility\": \"external\"\n        }\n      ],\n      \"src\": \"0:49:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:50:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/short_type_name.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"c\": [\n      11\n    ]\n  },\n  \"id\": 12,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"c\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 11,\n      \"linearizedBaseContracts\": [\n        11\n      ],\n      \"name\": \"c\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 9,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:20:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  7\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 7,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"49:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 9,\n                    \"src\": \"35:15:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"memory\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_array$_t_uint256_$dyn_memory_ptr\",\n                      \"typeString\": \"uint256[]\"\n                    },\n                    \"typeName\": {\n                      \"baseType\": {\n                        \"id\": 5,\n                        \"name\": \"uint\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"35:4:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_uint256\",\n                          \"typeString\": \"uint256\"\n                        }\n                      },\n                      \"id\": 6,\n                      \"nodeType\": \"ArrayTypeName\",\n                      \"src\": \"35:6:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_array$_t_uint256_$dyn_storage_ptr\",\n                        \"typeString\": \"uint256[]\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 8,\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:15:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 10,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"scope\": 11,\n          \"src\": \"13:40:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 12,\n      \"src\": \"0:55:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:56:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/short_type_name.sol",
    "content": "contract c { function f() public { uint[] memory x; } }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/short_type_name_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 12,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 11,\n      \"name\": \"c\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 9,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:20:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  7\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 7,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"49:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"35:15:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"memory\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"baseType\": {\n                        \"id\": 5,\n                        \"name\": \"uint\",\n                        \"nodeType\": \"ElementaryTypeName\",\n                        \"src\": \"35:4:1\",\n                        \"typeDescriptions\": {}\n                      },\n                      \"id\": 6,\n                      \"nodeType\": \"ArrayTypeName\",\n                      \"src\": \"35:6:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 8,\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:15:1\"\n              }\n            ]\n          },\n          \"id\": 10,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"src\": \"13:40:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:55:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:56:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/short_type_name_ref.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"c\": [\n      12\n    ]\n  },\n  \"id\": 13,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"c\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 12,\n      \"linearizedBaseContracts\": [\n        12\n      ],\n      \"name\": \"c\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 10,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:25:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  8\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 8,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"rows\",\n                    \"nameLocation\": \"51:4:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 10,\n                    \"src\": \"35:20:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"memory\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptr\",\n                      \"typeString\": \"uint256[][]\"\n                    },\n                    \"typeName\": {\n                      \"baseType\": {\n                        \"baseType\": {\n                          \"id\": 5,\n                          \"name\": \"uint\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"35:4:1\",\n                          \"typeDescriptions\": {\n                            \"typeIdentifier\": \"t_uint256\",\n                            \"typeString\": \"uint256\"\n                          }\n                        },\n                        \"id\": 6,\n                        \"nodeType\": \"ArrayTypeName\",\n                        \"src\": \"35:6:1\",\n                        \"typeDescriptions\": {\n                          \"typeIdentifier\": \"t_array$_t_uint256_$dyn_storage_ptr\",\n                          \"typeString\": \"uint256[]\"\n                        }\n                      },\n                      \"id\": 7,\n                      \"nodeType\": \"ArrayTypeName\",\n                      \"src\": \"35:8:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_array$_t_array$_t_uint256_$dyn_storage_$dyn_storage_ptr\",\n                        \"typeString\": \"uint256[][]\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 9,\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:20:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 11,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"scope\": 12,\n          \"src\": \"13:45:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 13,\n      \"src\": \"0:60:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:61:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/short_type_name_ref.sol",
    "content": "contract c { function f() public { uint[][] memory rows; } }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/short_type_name_ref_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 13,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 12,\n      \"name\": \"c\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 10,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:25:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  8\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 8,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"rows\",\n                    \"nameLocation\": \"51:4:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"35:20:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"memory\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"baseType\": {\n                        \"baseType\": {\n                          \"id\": 5,\n                          \"name\": \"uint\",\n                          \"nodeType\": \"ElementaryTypeName\",\n                          \"src\": \"35:4:1\",\n                          \"typeDescriptions\": {}\n                        },\n                        \"id\": 6,\n                        \"nodeType\": \"ArrayTypeName\",\n                        \"src\": \"35:6:1\",\n                        \"typeDescriptions\": {}\n                      },\n                      \"id\": 7,\n                      \"nodeType\": \"ArrayTypeName\",\n                      \"src\": \"35:8:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 9,\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:20:1\"\n              }\n            ]\n          },\n          \"id\": 11,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"src\": \"13:45:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:60:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:61:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/smoke.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      1\n    ]\n  },\n  \"id\": 2,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 1,\n      \"linearizedBaseContracts\": [\n        1\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 2,\n      \"src\": \"0:13:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:14:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/smoke.sol",
    "content": "contract C {}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/smoke_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 2,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 1,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"0:13:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:14:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/source_location.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      12\n    ]\n  },\n  \"id\": 13,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 12,\n      \"linearizedBaseContracts\": [\n        12\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 10,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:20:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"40:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 10,\n                    \"src\": \"35:6:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_uint256\",\n                      \"typeString\": \"uint256\"\n                    },\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"uint\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"35:4:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_uint256\",\n                        \"typeString\": \"uint256\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 6,\n                \"initialValue\": {\n                  \"hexValue\": \"32\",\n                  \"id\": 5,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": true,\n                  \"kind\": \"number\",\n                  \"lValueRequested\": false,\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"44:1:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_rational_2_by_1\",\n                    \"typeString\": \"int_const 2\"\n                  },\n                  \"value\": \"2\"\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:10:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 8,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"nodeType\": \"UnaryOperation\",\n                  \"operator\": \"++\",\n                  \"prefix\": false,\n                  \"src\": \"47:3:1\",\n                  \"subExpression\": {\n                    \"id\": 7,\n                    \"name\": \"x\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 4,\n                    \"src\": \"47:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_uint256\",\n                      \"typeString\": \"uint256\"\n                    }\n                  },\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_uint256\",\n                    \"typeString\": \"uint256\"\n                  }\n                },\n                \"id\": 9,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"47:3:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 11,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"scope\": 12,\n          \"src\": \"13:40:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 13,\n      \"src\": \"0:55:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:56:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/source_location.sol",
    "content": "contract C { function f() public { uint x = 2; x++; } }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/source_location_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 13,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 12,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 10,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:20:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"40:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"35:6:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"default\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"uint\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"35:4:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 6,\n                \"initialValue\": {\n                  \"hexValue\": \"32\",\n                  \"id\": 5,\n                  \"kind\": \"number\",\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"44:1:1\",\n                  \"typeDescriptions\": {},\n                  \"value\": \"2\"\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:10:1\"\n              },\n              {\n                \"expression\": {\n                  \"id\": 8,\n                  \"nodeType\": \"UnaryOperation\",\n                  \"operator\": \"++\",\n                  \"prefix\": false,\n                  \"src\": \"47:3:1\",\n                  \"subExpression\": {\n                    \"id\": 7,\n                    \"name\": \"x\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"47:1:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 9,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"47:3:1\"\n              }\n            ]\n          },\n          \"id\": 11,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"src\": \"13:40:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:55:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:56:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/storage_layout_specifier.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      5\n    ]\n  },\n  \"id\": 6,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 6,\n      \"src\": \"0:35:1\",\n      \"storageLayout\": {\n        \"baseSlotExpression\": {\n          \"commonType\": {\n            \"typeIdentifier\": \"t_rational_5801_by_1\",\n            \"typeString\": \"int_const 5801\"\n          },\n          \"id\": 3,\n          \"isConstant\": false,\n          \"isLValue\": false,\n          \"isPure\": true,\n          \"lValueRequested\": false,\n          \"leftExpression\": {\n            \"hexValue\": \"31323334\",\n            \"id\": 1,\n            \"isConstant\": false,\n            \"isLValue\": false,\n            \"isPure\": true,\n            \"kind\": \"number\",\n            \"lValueRequested\": false,\n            \"nodeType\": \"Literal\",\n            \"src\": \"21:4:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_rational_1234_by_1\",\n              \"typeString\": \"int_const 1234\"\n            },\n            \"value\": \"1234\"\n          },\n          \"nodeType\": \"BinaryOperation\",\n          \"operator\": \"+\",\n          \"rightExpression\": {\n            \"hexValue\": \"34353637\",\n            \"id\": 2,\n            \"isConstant\": false,\n            \"isLValue\": false,\n            \"isPure\": true,\n            \"kind\": \"number\",\n            \"lValueRequested\": false,\n            \"nodeType\": \"Literal\",\n            \"src\": \"28:4:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_rational_4567_by_1\",\n              \"typeString\": \"int_const 4567\"\n            },\n            \"value\": \"4567\"\n          },\n          \"src\": \"21:11:1\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_rational_5801_by_1\",\n            \"typeString\": \"int_const 5801\"\n          }\n        },\n        \"id\": 4,\n        \"nodeType\": \"StorageLayoutSpecifier\",\n        \"src\": \"11:21:1\"\n      },\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:36:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/storage_layout_specifier.sol",
    "content": "contract C layout at 1234 + 4567 {}\n\n// ----"
  },
  {
    "path": "test/libsolidity/ASTJSON/string.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      9\n    ]\n  },\n  \"id\": 10,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 9,\n      \"linearizedBaseContracts\": [\n        9\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 7,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:36:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"49:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 7,\n                    \"src\": \"35:15:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"memory\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_string_memory_ptr\",\n                      \"typeString\": \"string\"\n                    },\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"string\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"35:6:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_string_storage_ptr\",\n                        \"typeString\": \"string\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 6,\n                \"initialValue\": {\n                  \"hexValue\": \"48656c6c6f20576f726c64\",\n                  \"id\": 5,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": true,\n                  \"kind\": \"string\",\n                  \"lValueRequested\": false,\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"53:13:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_stringliteral_592fa743889fc7f92ac2a37bb1f5ba1daf2a5c84741ca0e0061d243a2e6707ba\",\n                    \"typeString\": \"literal_string \\\"Hello World\\\"\"\n                  },\n                  \"value\": \"Hello World\"\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:31:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 8,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"scope\": 9,\n          \"src\": \"13:56:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 10,\n      \"src\": \"0:71:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:72:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/string.sol",
    "content": "contract C { function f() public { string memory x = \"Hello World\"; } }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/string_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 10,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 9,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 7,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:36:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"49:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"35:15:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"memory\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"string\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"35:6:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 6,\n                \"initialValue\": {\n                  \"hexValue\": \"48656c6c6f20576f726c64\",\n                  \"id\": 5,\n                  \"kind\": \"string\",\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"53:13:1\",\n                  \"typeDescriptions\": {},\n                  \"value\": \"Hello World\"\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:31:1\"\n              }\n            ]\n          },\n          \"id\": 8,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"src\": \"13:56:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:71:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:72:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/struct_natspec.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"Example\": [\n      8\n    ]\n  },\n  \"id\": 9,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"canonicalName\": \"Example\",\n      \"documentation\": {\n        \"id\": 1,\n        \"nodeType\": \"StructuredDocumentation\",\n        \"src\": \"0:112:1\",\n        \"text\": \"@title example of title\\n @author example of author\\n @notice example of notice\\n @dev example of dev\"\n      },\n      \"id\": 8,\n      \"members\": [\n        {\n          \"constant\": false,\n          \"id\": 3,\n          \"mutability\": \"mutable\",\n          \"name\": \"text\",\n          \"nameLocation\": \"140:4:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 8,\n          \"src\": \"133:11:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_string_storage_ptr\",\n            \"typeString\": \"string\"\n          },\n          \"typeName\": {\n            \"id\": 2,\n            \"name\": \"string\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"133:6:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_string_storage_ptr\",\n              \"typeString\": \"string\"\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 5,\n          \"mutability\": \"mutable\",\n          \"name\": \"valid\",\n          \"nameLocation\": \"155:5:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 8,\n          \"src\": \"150:10:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_bool\",\n            \"typeString\": \"bool\"\n          },\n          \"typeName\": {\n            \"id\": 4,\n            \"name\": \"bool\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"150:4:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_bool\",\n              \"typeString\": \"bool\"\n            }\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 7,\n          \"mutability\": \"mutable\",\n          \"name\": \"value\",\n          \"nameLocation\": \"174:5:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 8,\n          \"src\": \"166:13:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_uint256\",\n            \"typeString\": \"uint256\"\n          },\n          \"typeName\": {\n            \"id\": 6,\n            \"name\": \"uint256\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"166:7:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_uint256\",\n              \"typeString\": \"uint256\"\n            }\n          },\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"name\": \"Example\",\n      \"nameLocation\": \"119:7:1\",\n      \"nodeType\": \"StructDefinition\",\n      \"scope\": 9,\n      \"src\": \"112:70:1\",\n      \"visibility\": \"public\"\n    }\n  ],\n  \"src\": \"112:71:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/struct_natspec.sol",
    "content": "/// @title example of title\n/// @author example of author\n/// @notice example of notice\n/// @dev example of dev\nstruct Example {\n    string text;\n    bool valid;\n    uint256 value;\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/struct_natspec_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 9,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"documentation\": {\n        \"id\": 1,\n        \"nodeType\": \"StructuredDocumentation\",\n        \"src\": \"0:112:1\",\n        \"text\": \"@title example of title\\n @author example of author\\n @notice example of notice\\n @dev example of dev\"\n      },\n      \"id\": 8,\n      \"members\": [\n        {\n          \"constant\": false,\n          \"id\": 3,\n          \"mutability\": \"mutable\",\n          \"name\": \"text\",\n          \"nameLocation\": \"140:4:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"133:11:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 2,\n            \"name\": \"string\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"133:6:1\",\n            \"typeDescriptions\": {}\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 5,\n          \"mutability\": \"mutable\",\n          \"name\": \"valid\",\n          \"nameLocation\": \"155:5:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"150:10:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 4,\n            \"name\": \"bool\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"150:4:1\",\n            \"typeDescriptions\": {}\n          },\n          \"visibility\": \"internal\"\n        },\n        {\n          \"constant\": false,\n          \"id\": 7,\n          \"mutability\": \"mutable\",\n          \"name\": \"value\",\n          \"nameLocation\": \"174:5:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"166:13:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 6,\n            \"name\": \"uint256\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"166:7:1\",\n            \"typeDescriptions\": {}\n          },\n          \"visibility\": \"internal\"\n        }\n      ],\n      \"name\": \"Example\",\n      \"nameLocation\": \"119:7:1\",\n      \"nodeType\": \"StructDefinition\",\n      \"src\": \"112:70:1\",\n      \"visibility\": \"public\"\n    }\n  ],\n  \"src\": \"112:71:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/two_base_functions.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"A\": [\n      5\n    ],\n    \"B\": [\n      10\n    ],\n    \"C\": [\n      22\n    ]\n  },\n  \"id\": 23,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"A\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 5,\n      \"linearizedBaseContracts\": [\n        5\n      ],\n      \"name\": \"A\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"45:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"45:0:1\"\n          },\n          \"scope\": 5,\n          \"src\": \"17:30:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": true,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 23,\n      \"src\": \"0:49:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"B\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 10,\n      \"linearizedBaseContracts\": [\n        10\n      ],\n      \"name\": \"B\",\n      \"nameLocation\": \"59:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 8,\n            \"nodeType\": \"Block\",\n            \"src\": \"95:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 9,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"76:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 6,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"77:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"95:0:1\"\n          },\n          \"scope\": 10,\n          \"src\": \"67:30:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": true,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 23,\n      \"src\": \"50:49:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 11,\n            \"name\": \"A\",\n            \"nameLocations\": [\n              \"114:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 5,\n            \"src\": \"114:1:1\"\n          },\n          \"id\": 12,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"114:1:1\"\n        },\n        {\n          \"baseName\": {\n            \"id\": 13,\n            \"name\": \"B\",\n            \"nameLocations\": [\n              \"117:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 10,\n            \"src\": \"117:1:1\"\n          },\n          \"id\": 14,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"117:1:1\"\n        }\n      ],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 22,\n      \"linearizedBaseContracts\": [\n        22,\n        10,\n        5\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"109:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"baseFunctions\": [\n            4,\n            9\n          ],\n          \"body\": {\n            \"id\": 20,\n            \"nodeType\": \"Block\",\n            \"src\": \"160:2:1\",\n            \"statements\": []\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 21,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"134:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"overrides\": {\n            \"id\": 18,\n            \"nodeType\": \"OverrideSpecifier\",\n            \"overrides\": [\n              {\n                \"id\": 16,\n                \"name\": \"A\",\n                \"nameLocations\": [\n                  \"154:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 5,\n                \"src\": \"154:1:1\"\n              },\n              {\n                \"id\": 17,\n                \"name\": \"B\",\n                \"nameLocations\": [\n                  \"157:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 10,\n                \"src\": \"157:1:1\"\n              }\n            ],\n            \"src\": \"145:14:1\"\n          },\n          \"parameters\": {\n            \"id\": 15,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"135:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 19,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"160:0:1\"\n          },\n          \"scope\": 22,\n          \"src\": \"125:37:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 23,\n      \"src\": \"100:64:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:165:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/two_base_functions.sol",
    "content": "contract A {\n    function f() public virtual {}\n}\ncontract B {\n    function f() public virtual {}\n}\ncontract C is A, B {\n    function f() public override(A, B) {}\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/two_base_functions_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 23,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 5,\n      \"name\": \"A\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 3,\n            \"nodeType\": \"Block\",\n            \"src\": \"45:2:1\",\n            \"statements\": []\n          },\n          \"id\": 4,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"26:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"27:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"45:0:1\"\n          },\n          \"src\": \"17:30:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": true,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:49:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 10,\n      \"name\": \"B\",\n      \"nameLocation\": \"59:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 8,\n            \"nodeType\": \"Block\",\n            \"src\": \"95:2:1\",\n            \"statements\": []\n          },\n          \"id\": 9,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"76:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 6,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"77:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 7,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"95:0:1\"\n          },\n          \"src\": \"67:30:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": true,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"50:49:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [\n        {\n          \"baseName\": {\n            \"id\": 11,\n            \"name\": \"A\",\n            \"nameLocations\": [\n              \"114:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"114:1:1\"\n          },\n          \"id\": 12,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"114:1:1\"\n        },\n        {\n          \"baseName\": {\n            \"id\": 13,\n            \"name\": \"B\",\n            \"nameLocations\": [\n              \"117:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"117:1:1\"\n          },\n          \"id\": 14,\n          \"nodeType\": \"InheritanceSpecifier\",\n          \"src\": \"117:1:1\"\n        }\n      ],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 22,\n      \"name\": \"C\",\n      \"nameLocation\": \"109:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 20,\n            \"nodeType\": \"Block\",\n            \"src\": \"160:2:1\",\n            \"statements\": []\n          },\n          \"id\": 21,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"134:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"overrides\": {\n            \"id\": 18,\n            \"nodeType\": \"OverrideSpecifier\",\n            \"overrides\": [\n              {\n                \"id\": 16,\n                \"name\": \"A\",\n                \"nameLocations\": [\n                  \"154:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"src\": \"154:1:1\"\n              },\n              {\n                \"id\": 17,\n                \"name\": \"B\",\n                \"nameLocations\": [\n                  \"157:1:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"src\": \"157:1:1\"\n              }\n            ],\n            \"src\": \"145:14:1\"\n          },\n          \"parameters\": {\n            \"id\": 15,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"135:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 19,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"160:0:1\"\n          },\n          \"src\": \"125:37:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"100:64:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:165:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/unicode.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      9\n    ]\n  },\n  \"id\": 10,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 9,\n      \"linearizedBaseContracts\": [\n        9\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 7,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:42:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"49:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"scope\": 7,\n                    \"src\": \"35:15:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"memory\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_string_memory_ptr\",\n                      \"typeString\": \"string\"\n                    },\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"string\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"35:6:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_string_storage_ptr\",\n                        \"typeString\": \"string\"\n                      }\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 6,\n                \"initialValue\": {\n                  \"hexValue\": \"48656c6c6f20f09f9883\",\n                  \"id\": 5,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": true,\n                  \"kind\": \"unicodeString\",\n                  \"lValueRequested\": false,\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"53:19:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_stringliteral_cd7a99177cebb3d14b8cc54e313dbf76867c71cd6fbb9a33ce3870dc80e9992b\",\n                    \"typeString\": \"literal_string hex\\\"48656c6c6f20f09f9883\\\"\"\n                  },\n                  \"value\": \"Hello \\ud83d\\ude03\"\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:37:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 8,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"scope\": 9,\n          \"src\": \"13:62:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 10,\n      \"src\": \"0:77:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:78:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/unicode.sol",
    "content": "contract C { function f() public { string memory x = unicode\"Hello 😃\"; } }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/unicode_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 10,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 9,\n      \"name\": \"C\",\n      \"nameLocation\": \"9:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 7,\n            \"nodeType\": \"Block\",\n            \"src\": \"33:42:1\",\n            \"statements\": [\n              {\n                \"assignments\": [\n                  4\n                ],\n                \"declarations\": [\n                  {\n                    \"constant\": false,\n                    \"id\": 4,\n                    \"mutability\": \"mutable\",\n                    \"name\": \"x\",\n                    \"nameLocation\": \"49:1:1\",\n                    \"nodeType\": \"VariableDeclaration\",\n                    \"src\": \"35:15:1\",\n                    \"stateVariable\": false,\n                    \"storageLocation\": \"memory\",\n                    \"typeDescriptions\": {},\n                    \"typeName\": {\n                      \"id\": 3,\n                      \"name\": \"string\",\n                      \"nodeType\": \"ElementaryTypeName\",\n                      \"src\": \"35:6:1\",\n                      \"typeDescriptions\": {}\n                    },\n                    \"visibility\": \"internal\"\n                  }\n                ],\n                \"id\": 6,\n                \"initialValue\": {\n                  \"hexValue\": \"48656c6c6f20f09f9883\",\n                  \"id\": 5,\n                  \"kind\": \"unicodeString\",\n                  \"nodeType\": \"Literal\",\n                  \"src\": \"53:19:1\",\n                  \"typeDescriptions\": {},\n                  \"value\": \"Hello \\ud83d\\ude03\"\n                },\n                \"nodeType\": \"VariableDeclarationStatement\",\n                \"src\": \"35:37:1\"\n              }\n            ]\n          },\n          \"id\": 8,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"22:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"23:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"33:0:1\"\n          },\n          \"src\": \"13:62:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:77:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:78:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/used_errors.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      19\n    ],\n    \"X\": [\n      2\n    ],\n    \"f\": [\n      9\n    ]\n  },\n  \"id\": 20,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"errorSelector\": \"c1599bd9\",\n      \"id\": 2,\n      \"name\": \"X\",\n      \"nameLocation\": \"6:1:1\",\n      \"nodeType\": \"ErrorDefinition\",\n      \"parameters\": {\n        \"id\": 1,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"7:2:1\"\n      },\n      \"src\": \"0:10:1\"\n    },\n    {\n      \"body\": {\n        \"id\": 8,\n        \"nodeType\": \"Block\",\n        \"src\": \"29:15:1\",\n        \"statements\": [\n          {\n            \"errorCall\": {\n              \"arguments\": [],\n              \"expression\": {\n                \"argumentTypes\": [],\n                \"id\": 5,\n                \"name\": \"X\",\n                \"nodeType\": \"Identifier\",\n                \"overloadedDeclarations\": [],\n                \"referencedDeclaration\": 2,\n                \"src\": \"38:1:1\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_function_error_pure$__$returns$_t_error_$\",\n                  \"typeString\": \"function () pure returns (error)\"\n                }\n              },\n              \"id\": 6,\n              \"isConstant\": false,\n              \"isLValue\": false,\n              \"isPure\": false,\n              \"kind\": \"functionCall\",\n              \"lValueRequested\": false,\n              \"nameLocations\": [],\n              \"names\": [],\n              \"nodeType\": \"FunctionCall\",\n              \"src\": \"38:3:1\",\n              \"tryCall\": false,\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_error\",\n                \"typeString\": \"error\"\n              }\n            },\n            \"id\": 7,\n            \"nodeType\": \"RevertStatement\",\n            \"src\": \"31:10:1\"\n          }\n        ]\n      },\n      \"id\": 9,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"f\",\n      \"nameLocation\": \"20:1:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 3,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"21:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 4,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"29:0:1\"\n      },\n      \"scope\": 20,\n      \"src\": \"11:33:1\",\n      \"stateMutability\": \"pure\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 19,\n      \"linearizedBaseContracts\": [\n        19\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"54:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"errorSelector\": \"2bc80f3a\",\n          \"id\": 11,\n          \"name\": \"T\",\n          \"nameLocation\": \"68:1:1\",\n          \"nodeType\": \"ErrorDefinition\",\n          \"parameters\": {\n            \"id\": 10,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"69:2:1\"\n          },\n          \"src\": \"62:10:1\"\n        },\n        {\n          \"body\": {\n            \"id\": 17,\n            \"nodeType\": \"Block\",\n            \"src\": \"97:8:1\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"argumentTypes\": [],\n                    \"id\": 14,\n                    \"name\": \"f\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 9,\n                    \"src\": \"99:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_function_internal_pure$__$returns$__$\",\n                      \"typeString\": \"function () pure\"\n                    }\n                  },\n                  \"id\": 15,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"kind\": \"functionCall\",\n                  \"lValueRequested\": false,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"99:3:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_tuple$__$\",\n                    \"typeString\": \"tuple()\"\n                  }\n                },\n                \"id\": 16,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"99:3:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"b8c9d365\",\n          \"id\": 18,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"h\",\n          \"nameLocation\": \"86:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 12,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"87:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 13,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"97:0:1\"\n          },\n          \"scope\": 19,\n          \"src\": \"77:28:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 20,\n      \"src\": \"45:62:1\",\n      \"usedErrors\": [\n        2,\n        11\n      ],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:108:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/used_errors.sol",
    "content": "error X();\nfunction f() pure { revert X(); }\ncontract C {\n    error T();\n    function h() public { f(); }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/used_errors_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 20,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"id\": 2,\n      \"name\": \"X\",\n      \"nameLocation\": \"6:1:1\",\n      \"nodeType\": \"ErrorDefinition\",\n      \"parameters\": {\n        \"id\": 1,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"7:2:1\"\n      },\n      \"src\": \"0:10:1\"\n    },\n    {\n      \"body\": {\n        \"id\": 8,\n        \"nodeType\": \"Block\",\n        \"src\": \"29:15:1\",\n        \"statements\": [\n          {\n            \"errorCall\": {\n              \"arguments\": [],\n              \"expression\": {\n                \"id\": 5,\n                \"name\": \"X\",\n                \"nodeType\": \"Identifier\",\n                \"overloadedDeclarations\": [],\n                \"src\": \"38:1:1\",\n                \"typeDescriptions\": {}\n              },\n              \"id\": 6,\n              \"nameLocations\": [],\n              \"names\": [],\n              \"nodeType\": \"FunctionCall\",\n              \"src\": \"38:3:1\",\n              \"tryCall\": false,\n              \"typeDescriptions\": {}\n            },\n            \"id\": 7,\n            \"nodeType\": \"RevertStatement\",\n            \"src\": \"31:10:1\"\n          }\n        ]\n      },\n      \"id\": 9,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"f\",\n      \"nameLocation\": \"20:1:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 3,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"21:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 4,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"29:0:1\"\n      },\n      \"src\": \"11:33:1\",\n      \"stateMutability\": \"pure\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 19,\n      \"name\": \"C\",\n      \"nameLocation\": \"54:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"id\": 11,\n          \"name\": \"T\",\n          \"nameLocation\": \"68:1:1\",\n          \"nodeType\": \"ErrorDefinition\",\n          \"parameters\": {\n            \"id\": 10,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"69:2:1\"\n          },\n          \"src\": \"62:10:1\"\n        },\n        {\n          \"body\": {\n            \"id\": 17,\n            \"nodeType\": \"Block\",\n            \"src\": \"97:8:1\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"arguments\": [],\n                  \"expression\": {\n                    \"id\": 14,\n                    \"name\": \"f\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"src\": \"99:1:1\",\n                    \"typeDescriptions\": {}\n                  },\n                  \"id\": 15,\n                  \"nameLocations\": [],\n                  \"names\": [],\n                  \"nodeType\": \"FunctionCall\",\n                  \"src\": \"99:3:1\",\n                  \"tryCall\": false,\n                  \"typeDescriptions\": {}\n                },\n                \"id\": 16,\n                \"nodeType\": \"ExpressionStatement\",\n                \"src\": \"99:3:1\"\n              }\n            ]\n          },\n          \"id\": 18,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"h\",\n          \"nameLocation\": \"86:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 12,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"87:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 13,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"97:0:1\"\n          },\n          \"src\": \"77:28:1\",\n          \"stateMutability\": \"nonpayable\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"45:62:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:108:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/userDefinedValueType.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      27\n    ],\n    \"MyAddress\": [\n      2\n    ],\n    \"MyUInt\": [\n      4\n    ],\n    \"f\": [\n      16\n    ]\n  },\n  \"id\": 28,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"canonicalName\": \"MyAddress\",\n      \"id\": 2,\n      \"name\": \"MyAddress\",\n      \"nameLocation\": \"5:9:1\",\n      \"nodeType\": \"UserDefinedValueTypeDefinition\",\n      \"src\": \"0:26:1\",\n      \"underlyingType\": {\n        \"id\": 1,\n        \"name\": \"address\",\n        \"nodeType\": \"ElementaryTypeName\",\n        \"src\": \"18:7:1\",\n        \"stateMutability\": \"nonpayable\",\n        \"typeDescriptions\": {\n          \"typeIdentifier\": \"t_address\",\n          \"typeString\": \"address\"\n        }\n      }\n    },\n    {\n      \"canonicalName\": \"MyUInt\",\n      \"id\": 4,\n      \"name\": \"MyUInt\",\n      \"nameLocation\": \"32:6:1\",\n      \"nodeType\": \"UserDefinedValueTypeDefinition\",\n      \"src\": \"27:20:1\",\n      \"underlyingType\": {\n        \"id\": 3,\n        \"name\": \"uint\",\n        \"nodeType\": \"ElementaryTypeName\",\n        \"src\": \"42:4:1\",\n        \"typeDescriptions\": {\n          \"typeIdentifier\": \"t_uint256\",\n          \"typeString\": \"uint256\"\n        }\n      }\n    },\n    {\n      \"body\": {\n        \"id\": 15,\n        \"nodeType\": \"Block\",\n        \"src\": \"61:34:1\",\n        \"statements\": [\n          {\n            \"assignments\": [\n              9\n            ],\n            \"declarations\": [\n              {\n                \"constant\": false,\n                \"id\": 9,\n                \"mutability\": \"mutable\",\n                \"name\": \"a\",\n                \"nameLocation\": \"77:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 15,\n                \"src\": \"67:11:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_userDefinedValueType$_MyAddress_$2\",\n                  \"typeString\": \"MyAddress\"\n                },\n                \"typeName\": {\n                  \"id\": 8,\n                  \"nodeType\": \"UserDefinedTypeName\",\n                  \"pathNode\": {\n                    \"id\": 7,\n                    \"name\": \"MyAddress\",\n                    \"nameLocations\": [\n                      \"67:9:1\"\n                    ],\n                    \"nodeType\": \"IdentifierPath\",\n                    \"referencedDeclaration\": 2,\n                    \"src\": \"67:9:1\"\n                  },\n                  \"referencedDeclaration\": 2,\n                  \"src\": \"67:9:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_userDefinedValueType$_MyAddress_$2\",\n                    \"typeString\": \"MyAddress\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"id\": 10,\n            \"nodeType\": \"VariableDeclarationStatement\",\n            \"src\": \"67:11:1\"\n          },\n          {\n            \"assignments\": [\n              13\n            ],\n            \"declarations\": [\n              {\n                \"constant\": false,\n                \"id\": 13,\n                \"mutability\": \"mutable\",\n                \"name\": \"b\",\n                \"nameLocation\": \"91:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 15,\n                \"src\": \"84:8:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_userDefinedValueType$_MyUInt_$4\",\n                  \"typeString\": \"MyUInt\"\n                },\n                \"typeName\": {\n                  \"id\": 12,\n                  \"nodeType\": \"UserDefinedTypeName\",\n                  \"pathNode\": {\n                    \"id\": 11,\n                    \"name\": \"MyUInt\",\n                    \"nameLocations\": [\n                      \"84:6:1\"\n                    ],\n                    \"nodeType\": \"IdentifierPath\",\n                    \"referencedDeclaration\": 4,\n                    \"src\": \"84:6:1\"\n                  },\n                  \"referencedDeclaration\": 4,\n                  \"src\": \"84:6:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_userDefinedValueType$_MyUInt_$4\",\n                    \"typeString\": \"MyUInt\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"id\": 14,\n            \"nodeType\": \"VariableDeclarationStatement\",\n            \"src\": \"84:8:1\"\n          }\n        ]\n      },\n      \"id\": 16,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"f\",\n      \"nameLocation\": \"57:1:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 5,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"58:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 6,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"61:0:1\"\n      },\n      \"scope\": 28,\n      \"src\": \"48:47:1\",\n      \"stateMutability\": \"nonpayable\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 27,\n      \"linearizedBaseContracts\": [\n        27\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"105:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"canonicalName\": \"C.MyAddress\",\n          \"id\": 18,\n          \"name\": \"MyAddress\",\n          \"nameLocation\": \"118:9:1\",\n          \"nodeType\": \"UserDefinedValueTypeDefinition\",\n          \"src\": \"113:26:1\",\n          \"underlyingType\": {\n            \"id\": 17,\n            \"name\": \"address\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"131:7:1\",\n            \"stateMutability\": \"nonpayable\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_address\",\n              \"typeString\": \"address\"\n            }\n          }\n        },\n        {\n          \"canonicalName\": \"C.MyUInt\",\n          \"id\": 20,\n          \"name\": \"MyUInt\",\n          \"nameLocation\": \"149:6:1\",\n          \"nodeType\": \"UserDefinedValueTypeDefinition\",\n          \"src\": \"144:20:1\",\n          \"underlyingType\": {\n            \"id\": 19,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"159:4:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_uint256\",\n              \"typeString\": \"uint256\"\n            }\n          }\n        },\n        {\n          \"constant\": false,\n          \"functionSelector\": \"97682884\",\n          \"id\": 26,\n          \"mutability\": \"mutable\",\n          \"name\": \"m\",\n          \"nameLocation\": \"205:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"scope\": 27,\n          \"src\": \"169:37:1\",\n          \"stateVariable\": true,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {\n            \"typeIdentifier\": \"t_mapping$_t_userDefinedValueType$_MyAddress_$18_$_t_userDefinedValueType$_MyUInt_$20_$\",\n            \"typeString\": \"mapping(C.MyAddress => C.MyUInt)\"\n          },\n          \"typeName\": {\n            \"id\": 25,\n            \"keyName\": \"\",\n            \"keyNameLocation\": \"-1:-1:-1\",\n            \"keyType\": {\n              \"id\": 22,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 21,\n                \"name\": \"MyAddress\",\n                \"nameLocations\": [\n                  \"177:9:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 18,\n                \"src\": \"177:9:1\"\n              },\n              \"referencedDeclaration\": 18,\n              \"src\": \"177:9:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_userDefinedValueType$_MyAddress_$18\",\n                \"typeString\": \"C.MyAddress\"\n              }\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"169:28:1\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_mapping$_t_userDefinedValueType$_MyAddress_$18_$_t_userDefinedValueType$_MyUInt_$20_$\",\n              \"typeString\": \"mapping(C.MyAddress => C.MyUInt)\"\n            },\n            \"valueName\": \"\",\n            \"valueNameLocation\": \"-1:-1:-1\",\n            \"valueType\": {\n              \"id\": 24,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 23,\n                \"name\": \"MyUInt\",\n                \"nameLocations\": [\n                  \"190:6:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 20,\n                \"src\": \"190:6:1\"\n              },\n              \"referencedDeclaration\": 20,\n              \"src\": \"190:6:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_userDefinedValueType$_MyUInt_$20\",\n                \"typeString\": \"C.MyUInt\"\n              }\n            }\n          },\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 28,\n      \"src\": \"96:113:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:210:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/userDefinedValueType.sol",
    "content": "type MyAddress is address;\ntype MyUInt is uint;\nfunction f() {\n    MyAddress a;\n    MyUInt b;\n}\ncontract C {\n    type MyAddress is address;\n    type MyUInt is uint;\n    mapping(MyAddress => MyUInt) public m;\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/userDefinedValueType_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 28,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"id\": 2,\n      \"name\": \"MyAddress\",\n      \"nameLocation\": \"5:9:1\",\n      \"nodeType\": \"UserDefinedValueTypeDefinition\",\n      \"src\": \"0:26:1\",\n      \"underlyingType\": {\n        \"id\": 1,\n        \"name\": \"address\",\n        \"nodeType\": \"ElementaryTypeName\",\n        \"src\": \"18:7:1\",\n        \"stateMutability\": \"nonpayable\",\n        \"typeDescriptions\": {}\n      }\n    },\n    {\n      \"id\": 4,\n      \"name\": \"MyUInt\",\n      \"nameLocation\": \"32:6:1\",\n      \"nodeType\": \"UserDefinedValueTypeDefinition\",\n      \"src\": \"27:20:1\",\n      \"underlyingType\": {\n        \"id\": 3,\n        \"name\": \"uint\",\n        \"nodeType\": \"ElementaryTypeName\",\n        \"src\": \"42:4:1\",\n        \"typeDescriptions\": {}\n      }\n    },\n    {\n      \"body\": {\n        \"id\": 15,\n        \"nodeType\": \"Block\",\n        \"src\": \"61:34:1\",\n        \"statements\": [\n          {\n            \"assignments\": [\n              9\n            ],\n            \"declarations\": [\n              {\n                \"constant\": false,\n                \"id\": 9,\n                \"mutability\": \"mutable\",\n                \"name\": \"a\",\n                \"nameLocation\": \"77:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"67:11:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 8,\n                  \"nodeType\": \"UserDefinedTypeName\",\n                  \"pathNode\": {\n                    \"id\": 7,\n                    \"name\": \"MyAddress\",\n                    \"nameLocations\": [\n                      \"67:9:1\"\n                    ],\n                    \"nodeType\": \"IdentifierPath\",\n                    \"src\": \"67:9:1\"\n                  },\n                  \"src\": \"67:9:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"id\": 10,\n            \"nodeType\": \"VariableDeclarationStatement\",\n            \"src\": \"67:11:1\"\n          },\n          {\n            \"assignments\": [\n              13\n            ],\n            \"declarations\": [\n              {\n                \"constant\": false,\n                \"id\": 13,\n                \"mutability\": \"mutable\",\n                \"name\": \"b\",\n                \"nameLocation\": \"91:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"src\": \"84:8:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {},\n                \"typeName\": {\n                  \"id\": 12,\n                  \"nodeType\": \"UserDefinedTypeName\",\n                  \"pathNode\": {\n                    \"id\": 11,\n                    \"name\": \"MyUInt\",\n                    \"nameLocations\": [\n                      \"84:6:1\"\n                    ],\n                    \"nodeType\": \"IdentifierPath\",\n                    \"src\": \"84:6:1\"\n                  },\n                  \"src\": \"84:6:1\",\n                  \"typeDescriptions\": {}\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"id\": 14,\n            \"nodeType\": \"VariableDeclarationStatement\",\n            \"src\": \"84:8:1\"\n          }\n        ]\n      },\n      \"id\": 16,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"f\",\n      \"nameLocation\": \"57:1:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 5,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"58:2:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 6,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"61:0:1\"\n      },\n      \"src\": \"48:47:1\",\n      \"stateMutability\": \"nonpayable\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 27,\n      \"name\": \"C\",\n      \"nameLocation\": \"105:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"id\": 18,\n          \"name\": \"MyAddress\",\n          \"nameLocation\": \"118:9:1\",\n          \"nodeType\": \"UserDefinedValueTypeDefinition\",\n          \"src\": \"113:26:1\",\n          \"underlyingType\": {\n            \"id\": 17,\n            \"name\": \"address\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"131:7:1\",\n            \"stateMutability\": \"nonpayable\",\n            \"typeDescriptions\": {}\n          }\n        },\n        {\n          \"id\": 20,\n          \"name\": \"MyUInt\",\n          \"nameLocation\": \"149:6:1\",\n          \"nodeType\": \"UserDefinedValueTypeDefinition\",\n          \"src\": \"144:20:1\",\n          \"underlyingType\": {\n            \"id\": 19,\n            \"name\": \"uint\",\n            \"nodeType\": \"ElementaryTypeName\",\n            \"src\": \"159:4:1\",\n            \"typeDescriptions\": {}\n          }\n        },\n        {\n          \"constant\": false,\n          \"id\": 26,\n          \"mutability\": \"mutable\",\n          \"name\": \"m\",\n          \"nameLocation\": \"205:1:1\",\n          \"nodeType\": \"VariableDeclaration\",\n          \"src\": \"169:37:1\",\n          \"stateVariable\": false,\n          \"storageLocation\": \"default\",\n          \"typeDescriptions\": {},\n          \"typeName\": {\n            \"id\": 25,\n            \"keyName\": \"\",\n            \"keyNameLocation\": \"-1:-1:-1\",\n            \"keyType\": {\n              \"id\": 22,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 21,\n                \"name\": \"MyAddress\",\n                \"nameLocations\": [\n                  \"177:9:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"src\": \"177:9:1\"\n              },\n              \"src\": \"177:9:1\",\n              \"typeDescriptions\": {}\n            },\n            \"nodeType\": \"Mapping\",\n            \"src\": \"169:28:1\",\n            \"typeDescriptions\": {},\n            \"valueName\": \"\",\n            \"valueNameLocation\": \"-1:-1:-1\",\n            \"valueType\": {\n              \"id\": 24,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 23,\n                \"name\": \"MyUInt\",\n                \"nameLocations\": [\n                  \"190:6:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"src\": \"190:6:1\"\n              },\n              \"src\": \"190:6:1\",\n              \"typeDescriptions\": {}\n            }\n          },\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"96:113:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:210:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/user_defined_operator.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      49\n    ],\n    \"I8\": [\n      2\n    ],\n    \"sub\": [\n      20\n    ],\n    \"unsub\": [\n      30\n    ]\n  },\n  \"id\": 50,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"canonicalName\": \"I8\",\n      \"id\": 2,\n      \"name\": \"I8\",\n      \"nameLocation\": \"5:2:1\",\n      \"nodeType\": \"UserDefinedValueTypeDefinition\",\n      \"src\": \"0:16:1\",\n      \"underlyingType\": {\n        \"id\": 1,\n        \"name\": \"int8\",\n        \"nodeType\": \"ElementaryTypeName\",\n        \"src\": \"11:4:1\",\n        \"typeDescriptions\": {\n          \"typeIdentifier\": \"t_int8\",\n          \"typeString\": \"int8\"\n        }\n      }\n    },\n    {\n      \"functionList\": [\n        {\n          \"definition\": {\n            \"id\": 3,\n            \"name\": \"sub\",\n            \"nameLocations\": [\n              \"24:3:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 20,\n            \"src\": \"24:3:1\"\n          },\n          \"operator\": \"-\"\n        },\n        {\n          \"definition\": {\n            \"id\": 4,\n            \"name\": \"unsub\",\n            \"nameLocations\": [\n              \"34:5:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 30,\n            \"src\": \"34:5:1\"\n          },\n          \"operator\": \"-\"\n        }\n      ],\n      \"global\": true,\n      \"id\": 7,\n      \"nodeType\": \"UsingForDirective\",\n      \"src\": \"17:43:1\",\n      \"typeName\": {\n        \"id\": 6,\n        \"nodeType\": \"UserDefinedTypeName\",\n        \"pathNode\": {\n          \"id\": 5,\n          \"name\": \"I8\",\n          \"nameLocations\": [\n            \"50:2:1\"\n          ],\n          \"nodeType\": \"IdentifierPath\",\n          \"referencedDeclaration\": 2,\n          \"src\": \"50:2:1\"\n        },\n        \"referencedDeclaration\": 2,\n        \"src\": \"50:2:1\",\n        \"typeDescriptions\": {\n          \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n          \"typeString\": \"I8\"\n        }\n      }\n    },\n    {\n      \"body\": {\n        \"id\": 19,\n        \"nodeType\": \"Block\",\n        \"src\": \"100:2:1\",\n        \"statements\": []\n      },\n      \"id\": 20,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"sub\",\n      \"nameLocation\": \"70:3:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 14,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [\n          {\n            \"constant\": false,\n            \"id\": 10,\n            \"mutability\": \"mutable\",\n            \"name\": \"\",\n            \"nameLocation\": \"-1:-1:-1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"scope\": 20,\n            \"src\": \"74:2:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n              \"typeString\": \"I8\"\n            },\n            \"typeName\": {\n              \"id\": 9,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 8,\n                \"name\": \"I8\",\n                \"nameLocations\": [\n                  \"74:2:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 2,\n                \"src\": \"74:2:1\"\n              },\n              \"referencedDeclaration\": 2,\n              \"src\": \"74:2:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                \"typeString\": \"I8\"\n              }\n            },\n            \"visibility\": \"internal\"\n          },\n          {\n            \"constant\": false,\n            \"id\": 13,\n            \"mutability\": \"mutable\",\n            \"name\": \"\",\n            \"nameLocation\": \"-1:-1:-1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"scope\": 20,\n            \"src\": \"78:2:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n              \"typeString\": \"I8\"\n            },\n            \"typeName\": {\n              \"id\": 12,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 11,\n                \"name\": \"I8\",\n                \"nameLocations\": [\n                  \"78:2:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 2,\n                \"src\": \"78:2:1\"\n              },\n              \"referencedDeclaration\": 2,\n              \"src\": \"78:2:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                \"typeString\": \"I8\"\n              }\n            },\n            \"visibility\": \"internal\"\n          }\n        ],\n        \"src\": \"73:8:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 18,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [\n          {\n            \"constant\": false,\n            \"id\": 17,\n            \"mutability\": \"mutable\",\n            \"name\": \"\",\n            \"nameLocation\": \"-1:-1:-1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"scope\": 20,\n            \"src\": \"96:2:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n              \"typeString\": \"I8\"\n            },\n            \"typeName\": {\n              \"id\": 16,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 15,\n                \"name\": \"I8\",\n                \"nameLocations\": [\n                  \"96:2:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 2,\n                \"src\": \"96:2:1\"\n              },\n              \"referencedDeclaration\": 2,\n              \"src\": \"96:2:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                \"typeString\": \"I8\"\n              }\n            },\n            \"visibility\": \"internal\"\n          }\n        ],\n        \"src\": \"95:4:1\"\n      },\n      \"scope\": 50,\n      \"src\": \"61:41:1\",\n      \"stateMutability\": \"pure\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"body\": {\n        \"id\": 29,\n        \"nodeType\": \"Block\",\n        \"src\": \"140:2:1\",\n        \"statements\": []\n      },\n      \"id\": 30,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"unsub\",\n      \"nameLocation\": \"112:5:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 24,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [\n          {\n            \"constant\": false,\n            \"id\": 23,\n            \"mutability\": \"mutable\",\n            \"name\": \"\",\n            \"nameLocation\": \"-1:-1:-1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"scope\": 30,\n            \"src\": \"118:2:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n              \"typeString\": \"I8\"\n            },\n            \"typeName\": {\n              \"id\": 22,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 21,\n                \"name\": \"I8\",\n                \"nameLocations\": [\n                  \"118:2:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 2,\n                \"src\": \"118:2:1\"\n              },\n              \"referencedDeclaration\": 2,\n              \"src\": \"118:2:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                \"typeString\": \"I8\"\n              }\n            },\n            \"visibility\": \"internal\"\n          }\n        ],\n        \"src\": \"117:4:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 28,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [\n          {\n            \"constant\": false,\n            \"id\": 27,\n            \"mutability\": \"mutable\",\n            \"name\": \"\",\n            \"nameLocation\": \"-1:-1:-1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"scope\": 30,\n            \"src\": \"136:2:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n              \"typeString\": \"I8\"\n            },\n            \"typeName\": {\n              \"id\": 26,\n              \"nodeType\": \"UserDefinedTypeName\",\n              \"pathNode\": {\n                \"id\": 25,\n                \"name\": \"I8\",\n                \"nameLocations\": [\n                  \"136:2:1\"\n                ],\n                \"nodeType\": \"IdentifierPath\",\n                \"referencedDeclaration\": 2,\n                \"src\": \"136:2:1\"\n              },\n              \"referencedDeclaration\": 2,\n              \"src\": \"136:2:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                \"typeString\": \"I8\"\n              }\n            },\n            \"visibility\": \"internal\"\n          }\n        ],\n        \"src\": \"135:4:1\"\n      },\n      \"scope\": 50,\n      \"src\": \"103:39:1\",\n      \"stateMutability\": \"pure\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 49,\n      \"linearizedBaseContracts\": [\n        49\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"152:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 47,\n            \"nodeType\": \"Block\",\n            \"src\": \"208:30:1\",\n            \"statements\": [\n              {\n                \"expression\": {\n                  \"commonType\": {\n                    \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                    \"typeString\": \"I8\"\n                  },\n                  \"function\": 20,\n                  \"id\": 45,\n                  \"isConstant\": false,\n                  \"isLValue\": false,\n                  \"isPure\": false,\n                  \"lValueRequested\": false,\n                  \"leftExpression\": {\n                    \"function\": 30,\n                    \"id\": 43,\n                    \"isConstant\": false,\n                    \"isLValue\": false,\n                    \"isPure\": false,\n                    \"lValueRequested\": false,\n                    \"nodeType\": \"UnaryOperation\",\n                    \"operator\": \"-\",\n                    \"prefix\": true,\n                    \"src\": \"225:2:1\",\n                    \"subExpression\": {\n                      \"id\": 42,\n                      \"name\": \"a\",\n                      \"nodeType\": \"Identifier\",\n                      \"overloadedDeclarations\": [],\n                      \"referencedDeclaration\": 33,\n                      \"src\": \"226:1:1\",\n                      \"typeDescriptions\": {\n                        \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                        \"typeString\": \"I8\"\n                      }\n                    },\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                      \"typeString\": \"I8\"\n                    }\n                  },\n                  \"nodeType\": \"BinaryOperation\",\n                  \"operator\": \"-\",\n                  \"rightExpression\": {\n                    \"id\": 44,\n                    \"name\": \"b\",\n                    \"nodeType\": \"Identifier\",\n                    \"overloadedDeclarations\": [],\n                    \"referencedDeclaration\": 36,\n                    \"src\": \"230:1:1\",\n                    \"typeDescriptions\": {\n                      \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                      \"typeString\": \"I8\"\n                    }\n                  },\n                  \"src\": \"225:6:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                    \"typeString\": \"I8\"\n                  }\n                },\n                \"functionReturnParameters\": 41,\n                \"id\": 46,\n                \"nodeType\": \"Return\",\n                \"src\": \"218:13:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"ac9fe858\",\n          \"id\": 48,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"169:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 37,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 33,\n                \"mutability\": \"mutable\",\n                \"name\": \"a\",\n                \"nameLocation\": \"174:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 48,\n                \"src\": \"171:4:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                  \"typeString\": \"I8\"\n                },\n                \"typeName\": {\n                  \"id\": 32,\n                  \"nodeType\": \"UserDefinedTypeName\",\n                  \"pathNode\": {\n                    \"id\": 31,\n                    \"name\": \"I8\",\n                    \"nameLocations\": [\n                      \"171:2:1\"\n                    ],\n                    \"nodeType\": \"IdentifierPath\",\n                    \"referencedDeclaration\": 2,\n                    \"src\": \"171:2:1\"\n                  },\n                  \"referencedDeclaration\": 2,\n                  \"src\": \"171:2:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                    \"typeString\": \"I8\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              },\n              {\n                \"constant\": false,\n                \"id\": 36,\n                \"mutability\": \"mutable\",\n                \"name\": \"b\",\n                \"nameLocation\": \"180:1:1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 48,\n                \"src\": \"177:4:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                  \"typeString\": \"I8\"\n                },\n                \"typeName\": {\n                  \"id\": 35,\n                  \"nodeType\": \"UserDefinedTypeName\",\n                  \"pathNode\": {\n                    \"id\": 34,\n                    \"name\": \"I8\",\n                    \"nameLocations\": [\n                      \"177:2:1\"\n                    ],\n                    \"nodeType\": \"IdentifierPath\",\n                    \"referencedDeclaration\": 2,\n                    \"src\": \"177:2:1\"\n                  },\n                  \"referencedDeclaration\": 2,\n                  \"src\": \"177:2:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                    \"typeString\": \"I8\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"170:12:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 41,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [\n              {\n                \"constant\": false,\n                \"id\": 40,\n                \"mutability\": \"mutable\",\n                \"name\": \"\",\n                \"nameLocation\": \"-1:-1:-1\",\n                \"nodeType\": \"VariableDeclaration\",\n                \"scope\": 48,\n                \"src\": \"204:2:1\",\n                \"stateVariable\": false,\n                \"storageLocation\": \"default\",\n                \"typeDescriptions\": {\n                  \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                  \"typeString\": \"I8\"\n                },\n                \"typeName\": {\n                  \"id\": 39,\n                  \"nodeType\": \"UserDefinedTypeName\",\n                  \"pathNode\": {\n                    \"id\": 38,\n                    \"name\": \"I8\",\n                    \"nameLocations\": [\n                      \"204:2:1\"\n                    ],\n                    \"nodeType\": \"IdentifierPath\",\n                    \"referencedDeclaration\": 2,\n                    \"src\": \"204:2:1\"\n                  },\n                  \"referencedDeclaration\": 2,\n                  \"src\": \"204:2:1\",\n                  \"typeDescriptions\": {\n                    \"typeIdentifier\": \"t_userDefinedValueType$_I8_$2\",\n                    \"typeString\": \"I8\"\n                  }\n                },\n                \"visibility\": \"internal\"\n              }\n            ],\n            \"src\": \"203:4:1\"\n          },\n          \"scope\": 49,\n          \"src\": \"160:78:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 50,\n      \"src\": \"143:97:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:241:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/user_defined_operator.sol",
    "content": "type I8 is int8;\nusing {sub as -, unsub as -} for I8 global;\nfunction sub(I8, I8) pure returns (I8) {}\nfunction unsub(I8) pure returns (I8) {}\ncontract C {\n    function f(I8 a, I8 b) public pure returns (I8) {\n        return -a - b;\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/using_for_directive.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"C\": [\n      13\n    ],\n    \"L\": [\n      4\n    ],\n    \"f\": [\n      10\n    ]\n  },\n  \"id\": 14,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"functionList\": [\n        {\n          \"function\": {\n            \"id\": 1,\n            \"name\": \"f\",\n            \"nameLocations\": [\n              \"7:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 10,\n            \"src\": \"7:1:1\"\n          }\n        }\n      ],\n      \"global\": false,\n      \"id\": 3,\n      \"nodeType\": \"UsingForDirective\",\n      \"src\": \"0:19:1\",\n      \"typeName\": {\n        \"id\": 2,\n        \"name\": \"uint\",\n        \"nodeType\": \"ElementaryTypeName\",\n        \"src\": \"14:4:1\",\n        \"typeDescriptions\": {\n          \"typeIdentifier\": \"t_uint256\",\n          \"typeString\": \"uint256\"\n        }\n      }\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"L\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"library\",\n      \"fullyImplemented\": true,\n      \"id\": 4,\n      \"linearizedBaseContracts\": [\n        4\n      ],\n      \"name\": \"L\",\n      \"nameLocation\": \"28:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"scope\": 14,\n      \"src\": \"20:12:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"body\": {\n        \"id\": 9,\n        \"nodeType\": \"Block\",\n        \"src\": \"50:2:1\",\n        \"statements\": []\n      },\n      \"id\": 10,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"f\",\n      \"nameLocation\": \"42:1:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 7,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [\n          {\n            \"constant\": false,\n            \"id\": 6,\n            \"mutability\": \"mutable\",\n            \"name\": \"\",\n            \"nameLocation\": \"-1:-1:-1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"scope\": 10,\n            \"src\": \"44:4:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {\n              \"typeIdentifier\": \"t_uint256\",\n              \"typeString\": \"uint256\"\n            },\n            \"typeName\": {\n              \"id\": 5,\n              \"name\": \"uint\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"44:4:1\",\n              \"typeDescriptions\": {\n                \"typeIdentifier\": \"t_uint256\",\n                \"typeString\": \"uint256\"\n              }\n            },\n            \"visibility\": \"internal\"\n          }\n        ],\n        \"src\": \"43:6:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 8,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"50:0:1\"\n      },\n      \"scope\": 14,\n      \"src\": \"33:19:1\",\n      \"stateMutability\": \"nonpayable\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"C\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 13,\n      \"linearizedBaseContracts\": [\n        13\n      ],\n      \"name\": \"C\",\n      \"nameLocation\": \"62:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"global\": false,\n          \"id\": 12,\n          \"libraryName\": {\n            \"id\": 11,\n            \"name\": \"L\",\n            \"nameLocations\": [\n              \"72:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"referencedDeclaration\": 4,\n            \"src\": \"72:1:1\"\n          },\n          \"nodeType\": \"UsingForDirective\",\n          \"src\": \"66:14:1\"\n        }\n      ],\n      \"scope\": 14,\n      \"src\": \"53:29:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:83:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/using_for_directive.sol",
    "content": "using {f} for uint;\nlibrary L {}\nfunction f(uint) {}\ncontract C { using L for *; }\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/using_for_directive_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 14,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"functionList\": [\n        {\n          \"function\": {\n            \"id\": 1,\n            \"name\": \"f\",\n            \"nameLocations\": [\n              \"7:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"7:1:1\"\n          }\n        }\n      ],\n      \"global\": false,\n      \"id\": 3,\n      \"nodeType\": \"UsingForDirective\",\n      \"src\": \"0:19:1\",\n      \"typeName\": {\n        \"id\": 2,\n        \"name\": \"uint\",\n        \"nodeType\": \"ElementaryTypeName\",\n        \"src\": \"14:4:1\",\n        \"typeDescriptions\": {}\n      }\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"library\",\n      \"id\": 4,\n      \"name\": \"L\",\n      \"nameLocation\": \"28:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [],\n      \"src\": \"20:12:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    },\n    {\n      \"body\": {\n        \"id\": 9,\n        \"nodeType\": \"Block\",\n        \"src\": \"50:2:1\",\n        \"statements\": []\n      },\n      \"id\": 10,\n      \"implemented\": true,\n      \"kind\": \"freeFunction\",\n      \"modifiers\": [],\n      \"name\": \"f\",\n      \"nameLocation\": \"42:1:1\",\n      \"nodeType\": \"FunctionDefinition\",\n      \"parameters\": {\n        \"id\": 7,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [\n          {\n            \"constant\": false,\n            \"id\": 6,\n            \"mutability\": \"mutable\",\n            \"name\": \"\",\n            \"nameLocation\": \"-1:-1:-1\",\n            \"nodeType\": \"VariableDeclaration\",\n            \"src\": \"44:4:1\",\n            \"stateVariable\": false,\n            \"storageLocation\": \"default\",\n            \"typeDescriptions\": {},\n            \"typeName\": {\n              \"id\": 5,\n              \"name\": \"uint\",\n              \"nodeType\": \"ElementaryTypeName\",\n              \"src\": \"44:4:1\",\n              \"typeDescriptions\": {}\n            },\n            \"visibility\": \"internal\"\n          }\n        ],\n        \"src\": \"43:6:1\"\n      },\n      \"returnParameters\": {\n        \"id\": 8,\n        \"nodeType\": \"ParameterList\",\n        \"parameters\": [],\n        \"src\": \"50:0:1\"\n      },\n      \"src\": \"33:19:1\",\n      \"stateMutability\": \"nonpayable\",\n      \"virtual\": false,\n      \"visibility\": \"internal\"\n    },\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 13,\n      \"name\": \"C\",\n      \"nameLocation\": \"62:1:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"global\": false,\n          \"id\": 12,\n          \"libraryName\": {\n            \"id\": 11,\n            \"name\": \"L\",\n            \"nameLocations\": [\n              \"72:1:1\"\n            ],\n            \"nodeType\": \"IdentifierPath\",\n            \"src\": \"72:1:1\"\n          },\n          \"nodeType\": \"UsingForDirective\",\n          \"src\": \"66:14:1\"\n        }\n      ],\n      \"src\": \"53:29:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:83:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/yul_hex_literal.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"exportedSymbols\": {\n    \"Sample\": [\n      6\n    ]\n  },\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"canonicalName\": \"Sample\",\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"fullyImplemented\": true,\n      \"id\": 6,\n      \"linearizedBaseContracts\": [\n        6\n      ],\n      \"name\": \"Sample\",\n      \"nameLocation\": \"9:6:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"47:167:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"66:142:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"66:142:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"80:15:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"80:15:1\",\n                      \"value\": {\n                        \"hexValue\": \"74657374\",\n                        \"kind\": \"string\",\n                        \"nativeSrc\": \"89:6:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"89:6:1\",\n                        \"type\": \"\",\n                        \"value\": \"test\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"a\",\n                          \"nativeSrc\": \"84:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"84:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    },\n                    {\n                      \"nativeSrc\": \"108:54:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"108:54:1\",\n                      \"value\": {\n                        \"hexValue\": \"112233445566778899aabbccddeeff6677889900\",\n                        \"kind\": \"string\",\n                        \"nativeSrc\": \"117:45:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"117:45:1\",\n                        \"type\": \"\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"b\",\n                          \"nativeSrc\": \"112:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"112:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    },\n                    {\n                      \"nativeSrc\": \"175:23:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"175:23:1\",\n                      \"value\": {\n                        \"hexValue\": \"1234abcd\",\n                        \"kind\": \"string\",\n                        \"nativeSrc\": \"184:14:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"184:14:1\",\n                        \"type\": \"\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"c\",\n                          \"nativeSrc\": \"179:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"179:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"57:151:1\"\n              }\n            ]\n          },\n          \"functionSelector\": \"26121ff0\",\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"31:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"32:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"47:0:1\"\n          },\n          \"scope\": 6,\n          \"src\": \"22:192:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"scope\": 7,\n      \"src\": \"0:216:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:217:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/yul_hex_literal.sol",
    "content": "contract Sample {\n    function f() public pure {\n        assembly {\n            let a := \"test\"\n            let b := hex\"112233445566778899aabbccddeeff6677889900\"\n            let c := hex\"1234_abcd\"\n        }\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/ASTJSON/yul_hex_literal_parseOnly.json",
    "content": "{\n  \"absolutePath\": \"a\",\n  \"id\": 7,\n  \"nodeType\": \"SourceUnit\",\n  \"nodes\": [\n    {\n      \"abstract\": false,\n      \"baseContracts\": [],\n      \"contractDependencies\": [],\n      \"contractKind\": \"contract\",\n      \"id\": 6,\n      \"name\": \"Sample\",\n      \"nameLocation\": \"9:6:1\",\n      \"nodeType\": \"ContractDefinition\",\n      \"nodes\": [\n        {\n          \"body\": {\n            \"id\": 4,\n            \"nodeType\": \"Block\",\n            \"src\": \"47:167:1\",\n            \"statements\": [\n              {\n                \"AST\": {\n                  \"nativeSrc\": \"66:142:1\",\n                  \"nodeType\": \"YulBlock\",\n                  \"src\": \"66:142:1\",\n                  \"statements\": [\n                    {\n                      \"nativeSrc\": \"80:15:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"80:15:1\",\n                      \"value\": {\n                        \"hexValue\": \"74657374\",\n                        \"kind\": \"string\",\n                        \"nativeSrc\": \"89:6:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"89:6:1\",\n                        \"type\": \"\",\n                        \"value\": \"test\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"a\",\n                          \"nativeSrc\": \"84:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"84:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    },\n                    {\n                      \"nativeSrc\": \"108:54:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"108:54:1\",\n                      \"value\": {\n                        \"hexValue\": \"112233445566778899aabbccddeeff6677889900\",\n                        \"kind\": \"string\",\n                        \"nativeSrc\": \"117:45:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"117:45:1\",\n                        \"type\": \"\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"b\",\n                          \"nativeSrc\": \"112:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"112:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    },\n                    {\n                      \"nativeSrc\": \"175:23:1\",\n                      \"nodeType\": \"YulVariableDeclaration\",\n                      \"src\": \"175:23:1\",\n                      \"value\": {\n                        \"hexValue\": \"1234abcd\",\n                        \"kind\": \"string\",\n                        \"nativeSrc\": \"184:14:1\",\n                        \"nodeType\": \"YulLiteral\",\n                        \"src\": \"184:14:1\",\n                        \"type\": \"\"\n                      },\n                      \"variables\": [\n                        {\n                          \"name\": \"c\",\n                          \"nativeSrc\": \"179:1:1\",\n                          \"nodeType\": \"YulTypedName\",\n                          \"src\": \"179:1:1\",\n                          \"type\": \"\"\n                        }\n                      ]\n                    }\n                  ]\n                },\n                \"evmVersion\": %EVMVERSION%,\n                \"externalReferences\": [],\n                \"id\": 3,\n                \"nodeType\": \"InlineAssembly\",\n                \"src\": \"57:151:1\"\n              }\n            ]\n          },\n          \"id\": 5,\n          \"implemented\": true,\n          \"kind\": \"function\",\n          \"modifiers\": [],\n          \"name\": \"f\",\n          \"nameLocation\": \"31:1:1\",\n          \"nodeType\": \"FunctionDefinition\",\n          \"parameters\": {\n            \"id\": 1,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"32:2:1\"\n          },\n          \"returnParameters\": {\n            \"id\": 2,\n            \"nodeType\": \"ParameterList\",\n            \"parameters\": [],\n            \"src\": \"47:0:1\"\n          },\n          \"src\": \"22:192:1\",\n          \"stateMutability\": \"pure\",\n          \"virtual\": false,\n          \"visibility\": \"public\"\n        }\n      ],\n      \"src\": \"0:216:1\",\n      \"usedErrors\": [],\n      \"usedEvents\": []\n    }\n  ],\n  \"src\": \"0:217:1\"\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSONTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <liblangutil/SourceReferenceFormatter.h>\n#include <libsolidity/ast/ASTJsonExporter.h>\n#include <libsolutil/AnsiColorized.h>\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/JSON.h>\n\n#include <test/Common.h>\n#include <test/libsolidity/ASTJSONTest.h>\n\n#include <boost/algorithm/string.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n#include <boost/algorithm/string/replace.hpp>\n#include <boost/algorithm/string/trim.hpp>\n#include <boost/test/unit_test.hpp>\n#include <boost/throw_exception.hpp>\n\n#include <fstream>\n#include <memory>\n#include <stdexcept>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\nusing namespace solidity::util::formatting;\nusing namespace solidity::util;\nnamespace fs = boost::filesystem;\nusing namespace boost::unit_test;\nusing namespace std::string_literals;\n\nnamespace\n{\n\nstd::string const sourceDelimiter(\"==== Source: \");\n\nstd::string compilerStateToString(CompilerStack::State _state)\n{\n\tswitch (_state)\n\t{\n\t\tcase CompilerStack::State::Empty: return \"Empty\";\n\t\tcase CompilerStack::State::SourcesSet: return \"SourcesSet\";\n\t\tcase CompilerStack::State::Parsed: return \"Parsed\";\n\t\tcase CompilerStack::State::ParsedAndImported: return \"ParsedAndImported\";\n\t\tcase CompilerStack::State::AnalysisSuccessful: return \"AnalysisSuccessful\";\n\t\tcase CompilerStack::State::CompilationSuccessful: return \"CompilationSuccessful\";\n\t}\n\tsoltestAssert(false, \"Unexpected value of state parameter\");\n}\n\nCompilerStack::State stringToCompilerState(const std::string& _state)\n{\n\tfor (unsigned int i = CompilerStack::State::Empty; i <= CompilerStack::State::CompilationSuccessful; ++i)\n\t{\n\t\tif (_state == compilerStateToString(CompilerStack::State(i)))\n\t\t\treturn CompilerStack::State(i);\n\t}\n\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Unsupported compiler state (\" + _state + \") in test contract file\"));\n}\n\nvoid replaceVersionWithTag(std::string& _input)\n{\n\tboost::algorithm::replace_all(\n\t\t_input,\n\t\t\"\\\"\" + solidity::test::CommonOptions::get().evmVersion().name() + \"\\\"\",\n\t\t\"%EVMVERSION%\"\n\t);\n}\n\nvoid replaceTagWithVersion(std::string& _input)\n{\n\tboost::algorithm::replace_all(\n\t\t_input,\n\t\t\"%EVMVERSION%\",\n\t\t\"\\\"\" + solidity::test::CommonOptions::get().evmVersion().name() + \"\\\"\"\n\t);\n}\n\n}\n\nvoid ASTJSONTest::generateTestVariants(std::string const& _filename)\n{\n\tstd::string_view baseName = _filename;\n\tbaseName.remove_suffix(4);\n\n\tconst std::vector<CompilerStack::State> variantCompileStates = {\n\t\tCompilerStack::State::Parsed,\n\t\tCompilerStack::State::AnalysisSuccessful,\n\t};\n\n\tfor (const auto state: variantCompileStates)\n\t{\n\t\tauto variant = TestVariant(baseName, state);\n\t\tif (boost::filesystem::exists(variant.astFilename()))\n\t\t{\n\t\t\tvariant.expectation = readFileAsString(variant.astFilename());\n\t\t\tboost::replace_all(variant.expectation, \"\\r\\n\", \"\\n\");\n\t\t\tm_variants.push_back(variant);\n\t\t}\n\t}\n}\n\nvoid ASTJSONTest::fillSources(std::string const& _filename)\n{\n\tstd::ifstream file(_filename);\n\tif (!file)\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Cannot open test contract: \\\"\" + _filename + \"\\\".\"));\n\tfile.exceptions(std::ios::badbit);\n\n\tstd::string sourceName;\n\tstd::string source;\n\tstd::string line;\n\tstd::string const delimiter(\"// ----\");\n\tstd::string const failMarker(\"// failAfter:\");\n\twhile (getline(file, line))\n\t{\n\t\tif (boost::algorithm::starts_with(line, sourceDelimiter))\n\t\t{\n\t\t\tif (!sourceName.empty())\n\t\t\t\tm_sources.emplace_back(sourceName, source);\n\n\t\t\tsourceName = line.substr(\n\t\t\t\tsourceDelimiter.size(),\n\t\t\t\tline.size() - \" ====\"s.size() - sourceDelimiter.size()\n\t\t\t);\n\t\t\tsource = std::string();\n\t\t}\n\t\telse if (boost::algorithm::starts_with(line, failMarker))\n\t\t{\n\t\t\tstd::string state = line.substr(failMarker.size());\n\t\t\tboost::algorithm::trim(state);\n\t\t\tif (m_expectedFailAfter.has_value())\n\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Duplicated \\\"failAfter\\\" directive\"));\n\t\t\tm_expectedFailAfter = stringToCompilerState(state);\n\n\t\t}\n\t\telse if (!line.empty() && !boost::algorithm::starts_with(line, delimiter))\n\t\t\tsource += line + \"\\n\";\n\t}\n\tm_sources.emplace_back(sourceName.empty() ? \"a\" : sourceName, source);\n\tfile.close();\n}\n\nvoid ASTJSONTest::validateTestConfiguration() const\n{\n\tif (m_variants.empty())\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"No file with expected result found.\"));\n\n\tif (m_expectedFailAfter.has_value())\n\t{\n\t\tauto unexpectedTestVariant = std::find_if(\n\t\t\tm_variants.begin(), m_variants.end(),\n\t\t\t[failAfter = m_expectedFailAfter](TestVariant v) { return v.stopAfter > failAfter; }\n\t\t);\n\n\t\tif (unexpectedTestVariant != m_variants.end())\n\t\t\tBOOST_THROW_EXCEPTION(\n\t\t\t\tstd::runtime_error(\n\t\t\t\t\tstd::string(\"Unexpected JSON file: \") + unexpectedTestVariant->astFilename() +\n\t\t\t\t\t\" in \\\"failAfter: \" +\n\t\t\t\t\tcompilerStateToString(m_expectedFailAfter.value()) + \"\\\" scenario.\"\n\t\t\t\t)\n\t\t\t);\n\t}\n}\n\nASTJSONTest::ASTJSONTest(std::string const& _filename):\n\tEVMVersionRestrictedTestCase(_filename)\n{\n\tif (!boost::algorithm::ends_with(_filename, \".sol\"))\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid test contract file name: \\\"\" + _filename + \"\\\".\"));\n\n\tgenerateTestVariants(_filename);\n\tfillSources(_filename);\n\tvalidateTestConfiguration();\n}\n\nTestCase::TestResult ASTJSONTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted)\n{\n\tCompilerStack c;\n\n\tStringMap sources;\n\tstd::map<std::string, unsigned> sourceIndices;\n\tfor (size_t i = 0; i < m_sources.size(); i++)\n\t{\n\t\tsources[m_sources[i].first] = m_sources[i].second;\n\t\tsourceIndices[m_sources[i].first] = static_cast<unsigned>(i + 1);\n\t}\n\n\tbool resultsMatch = true;\n\n\tfor (TestVariant& variant: m_variants)\n\t{\n\t\tc.reset();\n\t\tc.setSources(sources);\n\t\tc.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\n\t\tif (!c.parseAndAnalyze(variant.stopAfter))\n\t\t{\n\t\t\tif (!m_expectedFailAfter.has_value() || m_expectedFailAfter.value() + 1 != c.state())\n\t\t\t{\n\t\t\t\tSourceReferenceFormatter formatter(_stream, c, _formatted, false);\n\t\t\t\tformatter.printErrorInformation(c.errors());\n\t\t\t\treturn TestResult::FatalError;\n\t\t\t}\n\t\t}\n\n\t\tresultsMatch = resultsMatch && runTest(\n\t\t\tvariant,\n\t\t\tsourceIndices,\n\t\t\tc,\n\t\t\t_stream,\n\t\t\t_linePrefix,\n\t\t\t_formatted\n\t\t);\n\t}\n\n\treturn resultsMatch ? TestResult::Success : TestResult::Failure;\n}\n\nbool ASTJSONTest::runTest(\n\tTestVariant& _variant,\n\tstd::map<std::string, unsigned> const& _sourceIndices,\n\tCompilerStack& _compiler,\n\tstd::ostream& _stream,\n\tstd::string const& _linePrefix,\n\tbool const _formatted\n)\n{\n\tif (m_sources.size() > 1)\n\t\t_variant.result += \"[\\n\";\n\n\tfor (size_t i = 0; i < m_sources.size(); i++)\n\t{\n\t\tstd::ostringstream result;\n\t\tASTJsonExporter(_compiler.state(), _sourceIndices).print(result, _compiler.ast(m_sources[i].first), JsonFormat{ JsonFormat::Pretty });\n\t\t_variant.result += result.str();\n\t\tif (i != m_sources.size() - 1)\n\t\t\t_variant.result += \",\";\n\t\t_variant.result += \"\\n\";\n\t}\n\n\tif (m_sources.size() > 1)\n\t\t_variant.result += \"]\\n\";\n\n\treplaceTagWithVersion(_variant.expectation);\n\n\tif (_variant.expectation != _variant.result)\n\t{\n\t\tstd::string nextIndentLevel = _linePrefix + \"  \";\n\t\tAnsiColorized(_stream, _formatted, {BOLD, CYAN}) <<\n\t\t\t_linePrefix <<\n\t\t\t\"Expected result\" <<\n\t\t\t(!_variant.name().empty() ? \" (\" + _variant.name() + \"):\" : \":\") <<\n\t\t\tstd::endl;\n\t\tprintPrefixed(_stream, _variant.expectation, nextIndentLevel);\n\t\t_stream << std::endl;\n\n\t\tAnsiColorized(_stream, _formatted, {BOLD, CYAN}) <<\n\t\t\t_linePrefix <<\n\t\t\t\"Obtained result\" <<\n\t\t\t(!_variant.name().empty() ? \" (\" + _variant.name() + \"):\" : \":\") <<\n\t\t\tstd::endl;\n\t\tprintPrefixed(_stream, _variant.result, nextIndentLevel);\n\t\t_stream << std::endl;\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nvoid ASTJSONTest::printSource(std::ostream& _stream, std::string const& _linePrefix, bool const) const\n{\n\tfor (auto const& source: m_sources)\n\t{\n\t\tif (m_sources.size() > 1 || source.first != \"a\")\n\t\t\tprintPrefixed(_stream, sourceDelimiter + source.first + \" ====\\n\", _linePrefix);\n\t\tprintPrefixed(_stream, source.second, _linePrefix);\n\t\t_stream << std::endl;\n\t}\n}\n\nvoid ASTJSONTest::printUpdatedExpectations(std::ostream&, std::string const&) const\n{\n\tfor (TestVariant const& variant: m_variants)\n\t\tupdateExpectation(\n\t\t\tvariant.astFilename(),\n\t\t\tvariant.result,\n\t\t\tvariant.name().empty() ? \"\" : variant.name() + \" \"\n\t\t);\n}\n\nvoid ASTJSONTest::updateExpectation(std::string const& _filename, std::string const& _expectation, std::string const& _variant) const\n{\n\tstd::ofstream file(_filename.c_str());\n\tif (!file) BOOST_THROW_EXCEPTION(std::runtime_error(\"Cannot write \" + _variant + \"AST expectation to \\\"\" + _filename + \"\\\".\"));\n\tfile.exceptions(std::ios::badbit);\n\n\tstd::string replacedResult = _expectation;\n\treplaceVersionWithTag(replacedResult);\n\n\tfile << replacedResult;\n\tfile.flush();\n\tfile.close();\n}\n"
  },
  {
    "path": "test/libsolidity/ASTJSONTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <libsolutil/AnsiColorized.h>\n#include <libsolidity/interface/CompilerStack.h>\n#include <test/TestCase.h>\n\n#include <iosfwd>\n#include <string>\n#include <vector>\n#include <utility>\n\nnamespace solidity::frontend\n{\nclass CompilerStack;\n}\n\nnamespace solidity::frontend::test\n{\n\nclass ASTJSONTest: public EVMVersionRestrictedTestCase\n{\npublic:\n\tstruct TestVariant\n\t{\n\t\tTestVariant(std::string_view _baseName, CompilerStack::State _stopAfter):\n\t\t\tbaseName(_baseName),\n\t\t\tstopAfter(_stopAfter)\n\t\t{}\n\n\t\tstd::string name() const\n\t\t{\n\t\t\treturn stopAfter == CompilerStack::State::Parsed ? \"parseOnly\" : \"\";\n\t\t}\n\n\t\tstd::string astFilename() const\n\t\t{\n\t\t\treturn std::string(baseName) +\n\t\t\t\t(name().empty() ? \"\" : \"_\") +\n\t\t\t\tname() +\n\t\t\t\t\".json\";\n\t\t}\n\n\t\tstd::string baseName;\n\t\tCompilerStack::State stopAfter;\n\t\tstd::string result;\n\t\tstd::string expectation;\n\t};\n\n\tstatic std::unique_ptr<TestCase> create(Config const& _config)\n\t{\n\t\treturn std::make_unique<ASTJSONTest>(_config.filename);\n\t}\n\tASTJSONTest(std::string const& _filename);\n\n\tTestResult run(std::ostream& _stream, std::string const& _linePrefix = \"\", bool const _formatted = false) override;\n\n\tvoid printSource(std::ostream& _stream, std::string const& _linePrefix = \"\", bool const _formatted = false) const override;\n\tvoid printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;\nprivate:\n\tbool runTest(\n\t\tTestVariant& _testVariant,\n\t\tstd::map<std::string, unsigned> const& _sourceIndices,\n\t\tCompilerStack& _compiler,\n\t\tstd::ostream& _stream,\n\t\tstd::string const& _linePrefix = \"\",\n\t\tbool const _formatted = false\n\t);\n\tvoid updateExpectation(\n\t\tstd::string const& _filename,\n\t\tstd::string const& _expectation,\n\t\tstd::string const& _variant\n\t) const;\n\n\tvoid generateTestVariants(std::string const& _filename);\n\tvoid fillSources(std::string const& _filename);\n\tvoid validateTestConfiguration() const;\n\n\tstd::vector<TestVariant> m_variants;\n\tstd::optional<CompilerStack::State> m_expectedFailAfter;\n\n\tstd::vector<std::pair<std::string, std::string>> m_sources;\n};\n\n}\n"
  },
  {
    "path": "test/libsolidity/ASTPropertyTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/libsolidity/ASTPropertyTest.h>\n#include <test/Common.h>\n\n#include <libsolidity/ast/ASTJsonExporter.h>\n#include <libsolidity/interface/CompilerStack.h>\n\n#include <liblangutil/Common.h>\n#include <liblangutil/SourceReferenceFormatter.h>\n#include <libsolutil/JSON.h>\n\n#include <boost/algorithm/string.hpp>\n#include <boost/throw_exception.hpp>\n\n#include <range/v3/algorithm/find_if.hpp>\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/split.hpp>\n\n#include <queue>\n\nusing namespace solidity::util;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\nusing namespace solidity;\nusing namespace std::string_literals;\n\nASTPropertyTest::ASTPropertyTest(std::string const& _filename):\n\tEVMVersionRestrictedTestCase(_filename)\n{\n\tif (!boost::algorithm::ends_with(_filename, \".sol\"))\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Not a Solidity file: \\\"\" + _filename + \"\\\".\"));\n\n\tm_source = m_reader.source();\n\treadExpectations();\n\tsoltestAssert(m_tests.size() > 0, \"No tests specified in \" + _filename);\n}\n\nstd::string ASTPropertyTest::formatExpectations(bool _obtainedResult)\n{\n\tstd::string expectations;\n\tfor (std::string const& testId: m_testOrder)\n\t{\n\t\tsoltestAssert(m_tests.count(testId) > 0);\n\t\texpectations +=\n\t\t\ttestId +\n\t\t\t\": \" +\n\t\t\t(_obtainedResult ? m_tests[testId].obtainedValue : m_tests[testId].expectedValue)\n\t\t\t+ \"\\n\";\n\t}\n\treturn expectations;\n}\n\nstd::vector<StringPair> ASTPropertyTest::readKeyValuePairs(std::string const& _input)\n{\n\tstd::vector<StringPair> result;\n\tfor (std::string line: _input | ranges::views::split('\\n') | ranges::to<std::vector<std::string>>)\n\t{\n\t\tboost::trim(line);\n\t\tif (line.empty())\n\t\t\tcontinue;\n\n\t\tsoltestAssert(\n\t\t\tranges::all_of(line, [](char c) { return isprint(c); }),\n\t\t\t\"Non-printable character(s) found in property test: \" + line\n\t\t);\n\n\t\tauto colonPosition = line.find_first_of(':');\n\t\tsoltestAssert(colonPosition != std::string::npos, \"Property test is missing a colon: \" + line);\n\n\t\tStringPair pair{\n\t\t\tboost::trim_copy(line.substr(0, colonPosition)),\n\t\t\tboost::trim_copy(line.substr(colonPosition + 1))\n\t\t};\n\t\tsoltestAssert(!std::get<0>(pair).empty() != false, \"Empty key in property test: \" + line);\n\t\tsoltestAssert(!std::get<1>(pair).empty() != false, \"Empty value in property test: \" + line);\n\n\t\tresult.push_back(pair);\n\t}\n\treturn result;\n}\n\nvoid ASTPropertyTest::readExpectations()\n{\n\tfor (auto const& [testId, testExpectation]: readKeyValuePairs(m_reader.simpleExpectations()))\n\t{\n\t\tsoltestAssert(m_tests.count(testId) == 0, \"More than one expectation for test \\\"\" + testId + \"\\\"\");\n\t\tm_tests.emplace(testId, Test{\"\", testExpectation, \"\"});\n\t\tm_testOrder.push_back(testId);\n\t}\n\tm_expectation = formatExpectations(false /* _obtainedResult */);\n}\n\nvoid ASTPropertyTest::extractTestsFromAST(Json const& _astJson)\n{\n\tstd::queue<Json> nodesToVisit;\n\tnodesToVisit.push(_astJson);\n\n\twhile (!nodesToVisit.empty())\n\t{\n\t\tJson& node = nodesToVisit.front();\n\n\t\tif (node.is_array())\n\t\t\tfor (auto&& member: node)\n\t\t\t\tnodesToVisit.push(member);\n\t\telse if (node.is_object())\n\t\t\tfor (auto const& [memberName, value]: node.items())\n\t\t\t{\n\t\t\t\tif (memberName != \"documentation\")\n\t\t\t\t{\n\t\t\t\t\tnodesToVisit.push(node[memberName]);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tstd::string nodeDocstring = value.is_object() ?\n\t\t\t\t\tvalue[\"text\"].get<std::string>() : value.get<std::string>();\n\t\t\t\tsoltestAssert(!nodeDocstring.empty());\n\n\t\t\t\tstd::vector<StringPair> pairs = readKeyValuePairs(nodeDocstring);\n\t\t\t\tif (pairs.empty())\n\t\t\t\t\tcontinue;\n\n\t\t\t\tfor (auto const& [testId, testedProperty]: pairs)\n\t\t\t\t{\n\t\t\t\t\tsoltestAssert(\n\t\t\t\t\t\tm_tests.count(testId) > 0,\n\t\t\t\t\t\t\"Test \\\"\" + testId + \"\\\" does not have a corresponding expected value.\"\n\t\t\t\t\t);\n\t\t\t\t\tsoltestAssert(\n\t\t\t\t\t\tm_tests[testId].property.empty(),\n\t\t\t\t\t\t\"Test \\\"\" + testId + \"\\\" was already defined before.\"\n\t\t\t\t\t);\n\t\t\t\t\tm_tests[testId].property = testedProperty;\n\n\t\t\t\t\tsoltestAssert(node.contains(\"nodeType\"));\n\t\t\t\t\tstd::optional<Json> propertyNode = jsonValueByPath(node, testedProperty);\n\t\t\t\t\tsoltestAssert(\n\t\t\t\t\t\tpropertyNode.has_value(),\n\t\t\t\t\t\tnode[\"nodeType\"].get<std::string>() + \" node does not have a property named \\\"\"s + testedProperty + \"\\\"\"\n\t\t\t\t\t);\n\t\t\t\t\tsoltestAssert(\n\t\t\t\t\t\t!propertyNode->is_object() && !propertyNode->is_array(),\n\t\t\t\t\t\t\"Property \\\"\" + testedProperty + \"\\\" is an object or an array.\"\n\t\t\t\t\t);\n\t\t\t\t\tif (propertyNode->is_string())\n\t\t\t\t\t\tm_tests[testId].obtainedValue = propertyNode->get<std::string>();\n\t\t\t\t\telse if  (propertyNode->is_boolean())\n\t\t\t\t\t\tm_tests[testId].obtainedValue = fmt::format(\"{}\", propertyNode->get<bool>());\n\t\t\t\t\telse\n\t\t\t\t\t\tsoltestAssert(false);\n\t\t\t\t}\n\t\t\t}\n\n\t\tnodesToVisit.pop();\n\t}\n\n\tauto firstTestWithoutProperty = ranges::find_if(\n\t\tm_tests,\n\t\t[&](auto const& _testCase) { return _testCase.second.property.empty(); }\n\t);\n\tsoltestAssert(\n\t\tfirstTestWithoutProperty == ranges::end(m_tests),\n\t\t\"AST property not defined for test \\\"\" + firstTestWithoutProperty->first + \"\\\"\"\n\t);\n\n\tm_obtainedResult = formatExpectations(true /* _obtainedResult */);\n}\n\nTestCase::TestResult ASTPropertyTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted)\n{\n\tCompilerStack compiler;\n\n\tcompiler.setSources({{\n\t\t\"A\",\n\t\t\"pragma solidity >=0.0;\\n// SPDX-License-Identifier: GPL-3.0\\n\" + m_source\n\t}});\n\tcompiler.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\tcompiler.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n\tif (!compiler.parseAndAnalyze())\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\n\t\t\t\"Parsing contract failed\" +\n\t\t\tSourceReferenceFormatter::formatErrorInformation(compiler.errors(), compiler, _formatted)\n\t\t));\n\n\tJson astJson = ASTJsonExporter(compiler.state()).toJson(compiler.ast(\"A\"));\n\tsoltestAssert(!astJson.empty());\n\n\textractTestsFromAST(astJson);\n\n\treturn checkResult(_stream, _linePrefix, _formatted);\n}\n"
  },
  {
    "path": "test/libsolidity/ASTPropertyTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <test/TestCase.h>\n\n#include <libsolutil/JSON.h>\n\n#include <string>\n#include <vector>\n\nnamespace solidity::frontend\n{\nclass CompilerStack;\n}\n\nnamespace solidity::frontend::test\n{\n\nusing StringPair = std::pair<std::string, std::string>;\n\nclass ASTPropertyTest: public EVMVersionRestrictedTestCase\n{\npublic:\n\tstatic std::unique_ptr<TestCase> create(Config const& _config)\n\t{\n\t\treturn std::make_unique<ASTPropertyTest>(_config.filename);\n\t}\n\tASTPropertyTest(std::string const& _filename);\n\n\tTestResult run(std::ostream& _stream, std::string const& _linePrefix = \"\", bool const _formatted = false) override;\n\nprivate:\n\tstruct Test\n\t{\n\t\tstd::string property;\n\t\tstd::string expectedValue;\n\t\tstd::string obtainedValue;\n\t};\n\n\tvoid readExpectations();\n\tstd::vector<StringPair> readKeyValuePairs(std::string const& _input);\n\tvoid extractTestsFromAST(Json const& _astJson);\n\tstd::string formatExpectations(bool _obtainedResult = true);\n\n\tstd::vector<std::string> m_testOrder;\n\tstd::map<std::string, Test> m_tests;\n};\n\n}\n"
  },
  {
    "path": "test/libsolidity/AnalysisFramework.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Framework for testing features from the analysis phase of compiler.\n */\n\n#include <test/libsolidity/AnalysisFramework.h>\n\n#include <test/libsolidity/util/Common.h>\n#include <test/libsolidity/util/SoltestErrors.h>\n#include <test/Common.h>\n\n#include <libsolidity/interface/CompilerStack.h>\n#include <liblangutil/SourceReferenceFormatter.h>\n\n#include <libsolidity/ast/AST.h>\n\n#include <liblangutil/Scanner.h>\n\n#include <libsolutil/FunctionSelector.h>\n\n#include <boost/test/unit_test.hpp>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\n\nstd::pair<SourceUnit const*, ErrorList> AnalysisFramework::runAnalysisAndExpectNoParsingErrors(\n\tstd::string const& _source,\n\tbool _includeWarningsAndInfos,\n\tbool _addPreamble,\n\tbool _allowMultiple\n)\n{\n\trunFramework(_addPreamble ? withPreamble(_source) : _source, PipelineStage::Analysis);\n\n\tif (!stageSuccessful(PipelineStage::Parsing))\n\t\tBOOST_FAIL(\"Parsing contract failed in analysis test suite:\" + formatErrors(m_compiler->errors()));\n\n\tErrorList errors = filteredErrors(_includeWarningsAndInfos);\n\tif (errors.size() > 1 && !_allowMultiple)\n\t\tBOOST_FAIL(\"Multiple errors found: \" + formatErrors(errors));\n\n\treturn make_pair(&compiler().ast(\"\"), std::move(errors));\n}\n\nbool AnalysisFramework::runFramework(StringMap _sources, PipelineStage _targetStage)\n{\n\tresetFramework();\n\tm_targetStage = _targetStage;\n\tsoltestAssert(m_compiler);\n\n\tm_compiler->setSources(std::move(_sources));\n\tsetupCompiler(*m_compiler);\n\texecuteCompilationPipeline();\n\treturn pipelineSuccessful();\n}\n\nvoid AnalysisFramework::resetFramework()\n{\n\tcompiler().reset();\n\tm_targetStage = PipelineStage::Compilation;\n}\n\nstd::unique_ptr<CompilerStack> AnalysisFramework::createStack() const\n{\n\treturn std::make_unique<CompilerStack>();\n}\n\nvoid AnalysisFramework::setupCompiler(CompilerStack& _compiler)\n{\n\t// These are just defaults based on the (global) CLI options.\n\t// Technically, every TestCase should override these with values passed to it in TestCase::Config.\n\t// In practice TestCase::Config always matches global config so most test cases don't care.\n\t_compiler.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\t_compiler.setEOFVersion(solidity::test::CommonOptions::get().eofVersion());\n\t_compiler.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n}\n\nvoid AnalysisFramework::executeCompilationPipeline()\n{\n\tsoltestAssert(m_compiler);\n\n\t// If you add a new stage, remember to handle it below.\n\tsoltestAssert(\n\t\tm_targetStage == PipelineStage::Parsing ||\n\t\tm_targetStage == PipelineStage::Analysis ||\n\t\tm_targetStage == PipelineStage::Compilation\n\t);\n\n\tbool parsingSuccessful = m_compiler->parse();\n\tsoltestAssert(parsingSuccessful || !filteredErrors(false /* _includeWarningsAndInfos */).empty());\n\tif (!parsingSuccessful || stageSuccessful(m_targetStage))\n\t\treturn;\n\n\tbool analysisSuccessful = m_compiler->analyze();\n\tsoltestAssert(analysisSuccessful || !filteredErrors(false /* _includeWarningsAndInfos */).empty());\n\tif (!analysisSuccessful || stageSuccessful(m_targetStage))\n\t\treturn;\n\n\tbool compilationSuccessful = m_compiler->compile();\n\tsoltestAssert(compilationSuccessful || !filteredErrors(false /* _includeWarningsAndInfos */).empty());\n\tsoltestAssert(stageSuccessful(m_targetStage) == compilationSuccessful);\n}\n\nErrorList AnalysisFramework::filterErrors(ErrorList const& _errorList, bool _includeWarningsAndInfos) const\n{\n\tErrorList errors;\n\tfor (auto const& currentError: _errorList)\n\t{\n\t\tsolAssert(currentError->comment(), \"\");\n\t\tif (!Error::isError(currentError->type()))\n\t\t{\n\t\t\tif (!_includeWarningsAndInfos)\n\t\t\t\tcontinue;\n\t\t\tbool ignoreWarningsAndInfos = false;\n\t\t\tfor (auto const& filter: m_warningsToFilter)\n\t\t\t\tif (currentError->comment()->find(filter) == 0)\n\t\t\t\t{\n\t\t\t\t\tignoreWarningsAndInfos = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\tif (ignoreWarningsAndInfos)\n\t\t\t\tcontinue;\n\t\t}\n\n\t\tstd::shared_ptr<Error const> newError = currentError;\n\t\tfor (auto const& messagePrefix: m_messagesToCut)\n\t\t\tif (currentError->comment()->find(messagePrefix) == 0)\n\t\t\t{\n\t\t\t\tSourceLocation const* location = currentError->sourceLocation();\n\t\t\t\t// sufficient for now, but in future we might clone the error completely, including the secondary location\n\t\t\t\tnewError = std::make_shared<Error>(\n\t\t\t\t\tcurrentError->errorId(),\n\t\t\t\t\tcurrentError->type(),\n\t\t\t\t\tmessagePrefix + \" ....\",\n\t\t\t\t\tlocation ? *location : SourceLocation()\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\terrors.emplace_back(newError);\n\t}\n\n\treturn errors;\n}\n\nbool AnalysisFramework::stageSuccessful(PipelineStage _stage) const\n{\n\tswitch (_stage) {\n\t\tcase PipelineStage::Parsing: return compiler().state() >= CompilerStack::Parsed;\n\t\tcase PipelineStage::Analysis: return compiler().state() >= CompilerStack::AnalysisSuccessful;\n\t\tcase PipelineStage::Compilation: return compiler().state() >= CompilerStack::CompilationSuccessful;\n\t}\n\tunreachable();\n}\n\nErrorList AnalysisFramework::runAnalysisAndExpectError(\n\tstd::string const& _source,\n\tbool _includeWarningsAndInfos,\n\tbool _allowMultiple\n)\n{\n\tauto [ast, errors] = runAnalysisAndExpectNoParsingErrors(_source, _includeWarningsAndInfos, true, _allowMultiple);\n\tBOOST_REQUIRE(!errors.empty());\n\tBOOST_REQUIRE_MESSAGE(ast, \"Expected error, but no error happened.\");\n\treturn errors;\n}\n\nstd::string AnalysisFramework::formatErrors(\n\tlangutil::ErrorList const& _errors,\n\tbool _colored,\n\tbool _withErrorIds\n) const\n{\n\treturn SourceReferenceFormatter::formatErrorInformation(\n\t\t_errors,\n\t\t*m_compiler,\n\t\t_colored,\n\t\t_withErrorIds\n\t);\n}\n\nstd::string AnalysisFramework::formatError(\n\tError const& _error,\n\tbool _colored,\n\tbool _withErrorIds\n) const\n{\n\treturn SourceReferenceFormatter::formatErrorInformation(\n\t\t_error,\n\t\t*m_compiler,\n\t\t_colored,\n\t\t_withErrorIds\n\t);\n}\n\nContractDefinition const* AnalysisFramework::retrieveContractByName(SourceUnit const& _source, std::string const& _name)\n{\n\tContractDefinition* contract = nullptr;\n\n\tfor (std::shared_ptr<ASTNode> const& node: _source.nodes())\n\t\tif ((contract = dynamic_cast<ContractDefinition*>(node.get())) && contract->name() == _name)\n\t\t\treturn contract;\n\n\treturn nullptr;\n}\n\nFunctionTypePointer AnalysisFramework::retrieveFunctionBySignature(\n\tContractDefinition const& _contract,\n\tstd::string const& _signature\n)\n{\n\treturn _contract.interfaceFunctions()[util::selectorFromSignatureH32(_signature)];\n}\n"
  },
  {
    "path": "test/libsolidity/AnalysisFramework.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Framework for testing features from the analysis phase of compiler.\n */\n\n#pragma once\n\n#include <test/libsolidity/ErrorCheck.h>\n\n#include <libsolidity/interface/CompilerStack.h>\n\n#include <functional>\n#include <string>\n#include <memory>\n\nnamespace solidity::frontend\n{\nclass Type;\nclass FunctionType;\nusing FunctionTypePointer = FunctionType const*;\n}\n\nnamespace solidity::frontend::test\n{\n\nenum class PipelineStage {\n\tParsing,\n\tAnalysis,\n\tCompilation,\n};\n\nclass AnalysisFramework\n{\n\nprotected:\n\tvirtual ~AnalysisFramework() = default;\n\n\t/// Runs analysis via runFramework() and returns either an AST or a filtered list of errors.\n\t/// Uses Boost test macros to fail if errors do not occur specifically at the analysis stage.\n\t///\n\t/// @deprecated This is a legacy helper. Use runFramework() directly in new tests.\n\t///\n\t/// @param _includeWarningsAndInfos Do not remove warning and info messages from the error list.\n\t/// @param _addPreamble Apply withPreamble() to @p _source.\n\t/// @param _allowMultiple When false, use Boost test macros to fail when there's more\n\t///        than one item on the error list.\n\tstd::pair<SourceUnit const*, langutil::ErrorList> runAnalysisAndExpectNoParsingErrors(\n\t\tstd::string const& _source,\n\t\tbool _includeWarningsAndInfos = false,\n\t\tbool _addPreamble = true,\n\t\tbool _allowMultiple = false\n\t);\n\n\t/// Runs analysis via runAnalysisAndExpectNoParsingErrors() and returns the list of errors.\n\t/// Uses Boost test macros to fail if there are no errors.\n\t///\n\t/// @deprecated This is a legacy helper. Use runFramework() directly in new tests.\n\t///\n\t/// @param _includeWarningsAndInfos Do not remove warning and info messages from the error list.\n\t/// @param _allowMultiple When false, use Boost test macros to fail when there's more\n\t///        than one item on the error list.\n\tlangutil::ErrorList runAnalysisAndExpectError(\n\t\tstd::string const& _source,\n\t\tbool _includeWarningsAndInfos = false,\n\t\tbool _allowMultiple = false\n\t);\n\npublic:\n\t/// Runs the full compiler pipeline on specified sources. This is the main function of the\n\t/// framework. Resets the stack, configures it and runs either until the first failed stage or\n\t/// until the @p _targetStage is reached.\n\t/// Afterwards the caller can inspect the stack via @p compiler(). The framework provides a few\n\t/// convenience helpers to check the state and error list, in general the caller can freely\n\t/// access the stack, including generating outputs if the compilation succeeded.\n\tbool runFramework(StringMap _sources, PipelineStage _targetStage = PipelineStage::Compilation);\n\tbool runFramework(std::string _source, PipelineStage _targetStage = PipelineStage::Compilation)\n\t{\n\t\treturn runFramework({{\"\", std::move(_source)}}, _targetStage);\n\t}\n\n\tvoid resetFramework();\n\n\tPipelineStage targetStage() const { return m_targetStage; }\n\tbool pipelineSuccessful() const { return stageSuccessful(m_targetStage); }\n\tbool stageSuccessful(PipelineStage _stage) const;\n\n\tstd::string formatErrors(\n\t\tlangutil::ErrorList const& _errors,\n\t\tbool _colored = false,\n\t\tbool _withErrorIds = false\n\t) const;\n\tstd::string formatError(\n\t\tlangutil::Error const& _error,\n\t\tbool _colored = false,\n\t\tbool _withErrorIds = false\n\t) const;\n\n\tstatic ContractDefinition const* retrieveContractByName(SourceUnit const& _source, std::string const& _name);\n\tstatic FunctionTypePointer retrieveFunctionBySignature(\n\t\tContractDefinition const& _contract,\n\t\tstd::string const& _signature\n\t);\n\n\t/// filter out the warnings in m_warningsToFilter or all warnings and infos if _includeWarningsAndInfos is false\n\tlangutil::ErrorList filterErrors(langutil::ErrorList const& _errorList, bool _includeWarningsAndInfos = true) const;\n\tlangutil::ErrorList filteredErrors(bool _includeWarningsAndInfos = true) const\n\t{\n\t\treturn filterErrors(compiler().errors(), _includeWarningsAndInfos);\n\t}\n\n\t/// @returns reference to lazy-instantiated CompilerStack.\n\tsolidity::frontend::CompilerStack& compiler()\n\t{\n\t\tif (!m_compiler)\n\t\t\tm_compiler = createStack();\n\t\treturn *m_compiler;\n\t}\n\n\t/// @returns reference to lazy-instantiated CompilerStack.\n\tsolidity::frontend::CompilerStack const& compiler() const\n\t{\n\t\tif (!m_compiler)\n\t\t\tm_compiler = createStack();\n\t\treturn *m_compiler;\n\t}\n\nprotected:\n\t/// Creates a new instance of @p CompilerStack. Override if your test case needs to pass in\n\t/// custom constructor arguments.\n\tvirtual std::unique_ptr<CompilerStack> createStack() const;\n\n\t/// Configures @p CompilerStack. The default implementation sets basic parameters based on\n\t/// CLI options. Override if your test case needs extra configuration.\n\tvirtual void setupCompiler(CompilerStack& _compiler);\n\n\t/// Executes the requested pipeline stages until @p m_targetStage is reached.\n\t/// Stops at the first failed stage.\n\tvoid executeCompilationPipeline();\n\n\tstd::vector<std::string> m_warningsToFilter = {\"This is a pre-release compiler version\"};\n\tstd::vector<std::string> m_messagesToCut = {\"Source file requires different compiler version (current compiler is\"};\n\nprivate:\n\tmutable std::unique_ptr<solidity::frontend::CompilerStack> m_compiler;\n\tPipelineStage m_targetStage = PipelineStage::Compilation;\n};\n\n// Asserts that the compilation down to typechecking\n// emits multiple errors of different types and messages, provided in the second argument.\n#define CHECK_ALLOW_MULTI(text, expectations) \\\ndo \\\n{ \\\n\tErrorList errors = runAnalysisAndExpectError((text), true, true); \\\n\tauto message = searchErrors(errors, (expectations)); \\\n\tBOOST_CHECK_MESSAGE(message.empty(), message); \\\n} while(0)\n\n#define CHECK_ERROR_OR_WARNING(text, typ, substrings, includeWarningsAndInfos, allowMulti) \\\ndo \\\n{ \\\n\tErrorList errors = runAnalysisAndExpectError((text), (includeWarningsAndInfos), (allowMulti)); \\\n\tstd::vector<std::pair<Error::Type, std::string>> expectations; \\\n\tfor (auto const& str: substrings) \\\n\t\texpectations.emplace_back((Error::Type::typ), str); \\\n\tauto message = searchErrors(errors, expectations); \\\n\tBOOST_CHECK_MESSAGE(message.empty(), message); \\\n} while(0)\n\n// [checkError(text, type, substring)] asserts that the compilation down to typechecking\n// emits an error of type [type] and with a message containing [substring].\n#define CHECK_ERROR(text, type, substring) \\\nCHECK_ERROR_OR_WARNING(text, type, std::vector<std::string>{(substring)}, false, false)\n\n// [checkError(text, type, substring)] asserts that the compilation down to typechecking\n// emits multiple errors of the same type [type] and with a messages containing [substrings].\n// Because of the limitations of the preprocessor, you cannot use {{T1, \"abc\"}, {T2, \"def\"}} as arguments,\n// but have to replace them by (std::vector<std::pair<Error::Type, std::string>>{\"abc\", \"def\"})\n// (note the parentheses)\n#define CHECK_ERROR_ALLOW_MULTI(text, type, substrings) \\\nCHECK_ERROR_OR_WARNING(text, type, substrings, false, true)\n\n// [checkWarning(text, substring)] asserts that the compilation down to typechecking\n// emits a warning and with a message containing [substring].\n#define CHECK_WARNING(text, substring) \\\nCHECK_ERROR_OR_WARNING(text, Warning, std::vector<std::string>{(substring)}, true, false)\n\n// [checkWarningAllowMulti(text, substring)] asserts that the compilation down to typechecking\n// emits a warning and with a message containing [substring].\n// Because of the limitations of the preprocessor, you cannot use {\"abc\", \"def\"} as arguments,\n// but have to replace them by (std::vector<std::string>{\"abc\", \"def\"}) (note the parentheses)\n#define CHECK_WARNING_ALLOW_MULTI(text, substrings) \\\nCHECK_ERROR_OR_WARNING(text, Warning, substrings, true, true)\n\n// [checkSuccess(text)] asserts that the compilation down to typechecking succeeds.\n#define CHECK_SUCCESS(text) do { \\\n\tauto [ast, errors] = runAnalysisAndExpectNoParsingErrors((text)); \\\n\tBOOST_CHECK(errors.empty()); \\\n} while(0)\n\n#define CHECK_SUCCESS_NO_WARNINGS(text) \\\ndo \\\n{ \\\n\tauto [ast, errors] = runAnalysisAndExpectNoParsingErrors((text), true); \\\n\tstd::string message; \\\n\tif (!errors.empty()) \\\n\t\tmessage = formatErrors(errors);\\\n\tBOOST_CHECK_MESSAGE(errors.empty(), message); \\\n} \\\nwhile(0)\n\n}\n"
  },
  {
    "path": "test/libsolidity/Assembly.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Lefteris Karapetsas <lefteris@ethdev.com>\n * @date 2015\n * Unit tests for Assembly Items from evmasm/Assembly.h\n */\n\n#include <test/Common.h>\n\n#include <liblangutil/SourceLocation.h>\n#include <libevmasm/Assembly.h>\n\n#include <liblangutil/CharStream.h>\n\n#include <libsolidity/parsing/Parser.h>\n#include <libsolidity/analysis/DeclarationTypeChecker.h>\n#include <libsolidity/analysis/NameAndTypeResolver.h>\n#include <libsolidity/analysis/Scoper.h>\n#include <libsolidity/codegen/Compiler.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/analysis/TypeChecker.h>\n#include <libsolidity/analysis/SyntaxChecker.h>\n#include <liblangutil/ErrorReporter.h>\n\n#include <boost/test/unit_test.hpp>\n\n#include <string>\n#include <iostream>\n\nusing namespace solidity::langutil;\nusing namespace solidity::evmasm;\n\nnamespace solidity::frontend::test\n{\n\nnamespace\n{\n\nevmasm::AssemblyItems compileContract(std::shared_ptr<CharStream> _sourceCode)\n{\n\tErrorList errors;\n\tErrorReporter errorReporter(errors);\n\tParser parser(\n\t\terrorReporter,\n\t\tsolidity::test::CommonOptions::get().evmVersion(),\n\t\tsolidity::test::CommonOptions::get().eofVersion()\n\t);\n\tASTPointer<SourceUnit> sourceUnit;\n\tBOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(*_sourceCode));\n\tBOOST_CHECK(!!sourceUnit);\n\n\tScoper::assignScopes(*sourceUnit);\n\tBOOST_REQUIRE(SyntaxChecker(errorReporter, false /* _useYulOptimizer */, false /* _experimental */).checkSyntax(*sourceUnit));\n\tGlobalContext globalContext(solidity::test::CommonOptions::get().evmVersion());\n\tNameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), errorReporter, false);\n\tDeclarationTypeChecker declarationTypeChecker(errorReporter, solidity::test::CommonOptions::get().evmVersion());\n\tsolAssert(!Error::containsErrors(errorReporter.errors()), \"\");\n\tresolver.registerDeclarations(*sourceUnit);\n\tBOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*sourceUnit));\n\tif (Error::containsErrors(errorReporter.errors()))\n\t\treturn AssemblyItems();\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t{\n\t\tBOOST_REQUIRE_NO_THROW(declarationTypeChecker.check(*node));\n\t\tif (Error::containsErrors(errorReporter.errors()))\n\t\t\treturn AssemblyItems();\n\t}\n\tTypeChecker checker(\n\t\tsolidity::test::CommonOptions::get().evmVersion(),\n\t\tsolidity::test::CommonOptions::get().eofVersion(),\n\t\terrorReporter\n\t);\n\tBOOST_REQUIRE_NO_THROW(checker.checkTypeRequirements(*sourceUnit));\n\tif (Error::containsErrors(errorReporter.errors()))\n\t\treturn AssemblyItems();\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))\n\t\t{\n\t\t\tCompiler compiler(\n\t\t\t\tsolidity::test::CommonOptions::get().evmVersion(),\n\t\t\t\tsolidity::test::CommonOptions::get().eofVersion(),\n\t\t\t\tRevertStrings::Default,\n\t\t\t\tsolidity::test::CommonOptions::get().optimize ? OptimiserSettings::standard() : OptimiserSettings::minimal()\n\t\t\t);\n\t\t\tcompiler.compileContract(*contract, std::map<ContractDefinition const*, std::shared_ptr<Compiler const>>{}, bytes());\n\n\t\t\tBOOST_REQUIRE(compiler.runtimeAssembly().codeSections().size() == 1);\n\t\t\treturn compiler.runtimeAssembly().codeSections().at(0).items;\n\t\t}\n\tBOOST_FAIL(\"No contract found in source.\");\n\treturn AssemblyItems();\n}\n\nvoid printAssemblyLocations(AssemblyItems const& _items)\n{\n\tauto printRepeated = [](SourceLocation const& _loc, size_t _repetitions)\n\t{\n\t\tstd::cout <<\n\t\t\t\"\\t\\tvector<SourceLocation>(\" <<\n\t\t\t_repetitions <<\n\t\t\t\", SourceLocation{\" <<\n\t\t\t_loc.start <<\n\t\t\t\", \" <<\n\t\t\t_loc.end <<\n\t\t\t\", make_shared<string>(\\\"\" <<\n\t\t\t*_loc.sourceName <<\n\t\t\t\"\\\")}) +\" << std::endl;\n\t};\n\n\tstd::vector<SourceLocation> locations;\n\tfor (auto const& item: _items)\n\t\tlocations.push_back(item.location());\n\tsize_t repetitions = 0;\n\tSourceLocation const* previousLoc = nullptr;\n\tfor (size_t i = 0; i < locations.size(); ++i)\n\t{\n\t\tSourceLocation& loc = locations[i];\n\t\tif (previousLoc && *previousLoc == loc)\n\t\t\trepetitions++;\n\t\telse\n\t\t{\n\t\t\tif (previousLoc)\n\t\t\t\tprintRepeated(*previousLoc, repetitions);\n\t\t\tpreviousLoc = &loc;\n\t\t\trepetitions = 1;\n\t\t}\n\t}\n\tif (previousLoc)\n\t\tprintRepeated(*previousLoc, repetitions);\n}\n\nvoid checkAssemblyLocations(AssemblyItems const& _items, std::vector<SourceLocation> const& _locations)\n{\n\tBOOST_CHECK_EQUAL(_items.size(), _locations.size());\n\tfor (size_t i = 0; i < std::min(_items.size(), _locations.size()); ++i)\n\t{\n\t\tif (_items[i].location().start != _locations[i].start ||\n\t\t\t_items[i].location().end != _locations[i].end)\n\t\t{\n\t\t\tBOOST_CHECK_MESSAGE(false, \"Location mismatch for item \" + std::to_string(i) + \". Found the following locations:\");\n\t\t\tprintAssemblyLocations(_items);\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n\n} // end anonymous namespace\n\nBOOST_AUTO_TEST_SUITE(Assembly)\n\nBOOST_AUTO_TEST_CASE(location_test)\n{\n\tstd::string sourceCode = R\"(\n\tpragma abicoder v1;\n\tcontract test {\n\t\tfunction f() public returns (uint256 a) {\n\t\t\treturn 16;\n\t\t}\n\t}\n\t)\";\n\tAssemblyItems items = compileContract(std::make_shared<CharStream>(sourceCode, \"\"));\n\tstd::shared_ptr<std::string> sourceName = std::make_shared<std::string>();\n\tbool hasShifts = solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting();\n\n\tauto codegenCharStream = std::make_shared<CharStream>(\"\", \"--CODEGEN--\");\n\n\tstd::vector<SourceLocation> locations;\n\tif (solidity::test::CommonOptions::get().optimize)\n\t\tlocations =\n\t\t\tstd::vector<SourceLocation>(31, SourceLocation{23, 103, sourceName}) +\n\t\t\tstd::vector<SourceLocation>(1, SourceLocation{41, 100, sourceName}) +\n\t\t\tstd::vector<SourceLocation>(1, SourceLocation{93, 95, sourceName}) +\n\t\t\tstd::vector<SourceLocation>(15, SourceLocation{41, 100, sourceName});\n\telse\n\t\tlocations =\n\t\t\tstd::vector<SourceLocation>(hasShifts ? 31 : 32, SourceLocation{23, 103, sourceName}) +\n\t\t\tstd::vector<SourceLocation>(24, SourceLocation{41, 100, sourceName}) +\n\t\t\tstd::vector<SourceLocation>(1, SourceLocation{70, 79, sourceName}) +\n\t\t\tstd::vector<SourceLocation>(1, SourceLocation{93, 95, sourceName}) +\n\t\t\tstd::vector<SourceLocation>(2, SourceLocation{86, 95, sourceName}) +\n\t\t\tstd::vector<SourceLocation>(2, SourceLocation{41, 100, sourceName});\n\tcheckAssemblyLocations(items, locations);\n}\n\n\nBOOST_AUTO_TEST_CASE(jump_type)\n{\n\tauto sourceCode = std::make_shared<CharStream>(R\"(\n\tpragma abicoder v1;\n\tcontract C {\n\t\tfunction f(uint a) public pure returns (uint t) {\n\t\t\tassembly {\n\t\t\t\tfunction g(x) -> y { if x { leave } y := 8 }\n\t\t\t\tt := g(a)\n\t\t\t}\n\t\t}\n\t}\n\t)\", \"\");\n\tAssemblyItems items = compileContract(sourceCode);\n\n\tstd::string jumpTypes;\n\tfor (AssemblyItem const& item: items)\n\t\tif (item.getJumpType() != AssemblyItem::JumpType::Ordinary)\n\t\t\tjumpTypes += item.getJumpTypeAsString() + \"\\n\";\n\n\tif (solidity::test::CommonOptions::get().optimize)\n\t\tBOOST_CHECK_EQUAL(jumpTypes, \"[in]\\n[out]\\n[out]\\n[in]\\n[out]\\n\");\n\telse\n\t\tBOOST_CHECK_EQUAL(jumpTypes, \"[in]\\n[out]\\n[in]\\n[out]\\n\");\n}\n\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/ErrorCheck.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file ErrorCheck.cpp\n * @author Yoichi Hirai <i@yoichihirai.com>\n * @date 2016\n */\n\n#include <test/libsolidity/ErrorCheck.h>\n#include <libsolutil/Exceptions.h>\n\n#include <string>\n#include <set>\n#include <iostream>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\n\nnamespace\n{\nstd::string errorMessage(Error const& _e)\n{\n\treturn _e.comment() ? *_e.comment() : \"NONE\";\n}\n}\n\nbool solidity::frontend::test::searchErrorMessage(Error const& _err, std::string const& _substr)\n{\n\tif (std::string const* errorMessage = _err.comment())\n\t{\n\t\tif (errorMessage->find(_substr) == std::string::npos)\n\t\t{\n\t\t\tstd::cout << \"Expected message \\\"\" << _substr << \"\\\" but found \\\"\" << *errorMessage << \"\\\".\\n\";\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\telse\n\t\tstd::cout << \"Expected error message but found none.\" << std::endl;\n\treturn _substr.empty();\n}\n\nstd::string solidity::frontend::test::searchErrors(ErrorList const& _errors, std::vector<std::pair<Error::Type, std::string>> const& _expectations)\n{\n\tauto expectations = _expectations;\n\tfor (auto const& error: _errors)\n\t{\n\t\tstd::string msg = errorMessage(*error);\n\t\tbool found = false;\n\t\tfor (auto it = expectations.begin(); it != expectations.end(); ++it)\n\t\t\tif (msg.find(it->second) != std::string::npos && error->type() == it->first)\n\t\t\t{\n\t\t\t\tfound = true;\n\t\t\t\texpectations.erase(it);\n\t\t\t\tbreak;\n\t\t\t}\n\t\tif (!found)\n\t\t\treturn \"Unexpected error: \" + Error::formatErrorType(error->type()) + \": \" + msg;\n\t}\n\tif (!expectations.empty())\n\t{\n\t\tstd::string msg = \"Expected error(s) not present:\\n\";\n\t\tfor (auto const& expectation: expectations)\n\t\t\tmsg += expectation.second + \"\\n\";\n\t\treturn msg;\n\t}\n\n\treturn \"\";\n}\n"
  },
  {
    "path": "test/libsolidity/ErrorCheck.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/** @file ErrorCheck.h\n * @author Yoichi Hirai <i@yoichihirai.com>\n * @date 2016\n */\n\n#pragma once\n\n#include <liblangutil/Exceptions.h>\n\n#include <vector>\n#include <tuple>\n\nnamespace solidity::frontend::test\n{\n\nbool searchErrorMessage(langutil::Error const& _err, std::string const& _substr);\n\n/// Checks that all provided errors are of the given type and have a given substring in their\n/// description.\n/// If the expectations are not met, returns a nonempty description, otherwise an empty string.\nstd::string searchErrors(langutil::ErrorList const& _errors, std::vector<std::pair<langutil::Error::Type, std::string>> const& _expectations);\n\n}\n"
  },
  {
    "path": "test/libsolidity/FunctionDependencyGraphTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/libsolidity/FunctionDependencyGraphTest.h>\n\n#include <libsolidity/experimental/analysis/Analysis.h>\n#include <libsolidity/experimental/analysis/FunctionDependencyAnalysis.h>\n\n#include <libyul/backends/evm/EVMDialect.h>\n#include <libyul/optimiser/FunctionCallFinder.h>\n\n#include <libsolutil/StringUtils.h>\n\n#include <fstream>\n#include <stdexcept>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::util::formatting;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\n\nTestCase::TestResult FunctionDependencyGraphTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted)\n{\n\tcompiler().reset();\n\tcompiler().setSources(StringMap{{\"\", m_source}});\n\tcompiler().setViaIR(true);\n\tcompiler().setOptimiserSettings(OptimiserSettings::none());\n\t// Experimental on by default as function dependency analysis is a part of Generic Solidity implementation\n\tcompiler().setExperimental(true);\n\tif (!compiler().compile(CompilerStack::AnalysisSuccessful))\n\t{\n\t\tprintPrefixed(_stream, formatErrors(filteredErrors(), _formatted), _linePrefix);\n\t\treturn TestResult::FatalError;\n\t}\n\n\tm_obtainedResult.clear();\n\tfor (auto [top, subs]: compiler().experimentalAnalysis().annotation<experimental::FunctionDependencyAnalysis>().functionCallGraph.edges)\n\t{\n\t\tstd::string topName = top->name().empty() ? \"fallback\" : top->name();\n\t\tm_obtainedResult += \"(\" + topName + \") --> {\";\n\t\tfor (auto sub: subs)\n\t\t\tm_obtainedResult += sub->name() + \",\";\n\t\tm_obtainedResult += \"}\\n\";\n\t}\n\n\treturn checkResult(_stream, _linePrefix, _formatted);\n}\n"
  },
  {
    "path": "test/libsolidity/FunctionDependencyGraphTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <test/libsolidity/AnalysisFramework.h>\n#include <test/TestCase.h>\n#include <test/CommonSyntaxTest.h>\n\n#include <iosfwd>\n#include <string>\n\nnamespace solidity::frontend::test\n{\n\tusing solidity::test::SyntaxTestError;\n\n\tclass FunctionDependencyGraphTest: public AnalysisFramework, public TestCase\n\t{\n\tpublic:\n\t\tstatic std::unique_ptr<TestCase> create(Config const& _config)\n\t\t{\n\t\t\treturn std::make_unique<FunctionDependencyGraphTest>(_config.filename);\n\t\t}\n\n\t\tFunctionDependencyGraphTest(std::string const& _filename): TestCase(_filename)\n\t\t{\n\t\t\tm_source = m_reader.source();\n\t\t\tm_expectation = m_reader.simpleExpectations();\n\t\t}\n\n\t\tTestResult run(std::ostream& _stream, std::string const& _linePrefix = \"\", bool _formatted = false) override;\n\t};\n}\n"
  },
  {
    "path": "test/libsolidity/GasCosts.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Tests that check that the cost of certain operations stay within range.\n */\n\n#include <test/libsolidity/SolidityExecutionFramework.h>\n#include <liblangutil/EVMVersion.h>\n#include <libsolutil/IpfsHash.h>\n#include <libevmasm/GasMeter.h>\n\n#include <cmath>\n\nusing namespace solidity::langutil;\nusing namespace solidity::langutil;\nusing namespace solidity::evmasm;\nusing namespace solidity::frontend;\nusing namespace solidity::test;\n\nnamespace solidity::frontend::test\n{\n\n#define CHECK_DEPLOY_GAS(_gasNoOpt, _gasOpt, _evmVersion) \\\n\tdo \\\n\t{ \\\n\t\tu256 metaCost = GasMeter::dataGas(m_compiler.cborMetadata(m_compiler.lastContractName()), true, _evmVersion); \\\n\t\tu256 gasOpt{_gasOpt}; \\\n\t\tu256 gasNoOpt{_gasNoOpt}; \\\n\t\tu256 gas = m_optimiserSettings == OptimiserSettings::minimal() ? gasNoOpt : gasOpt; \\\n\t\tBOOST_CHECK_MESSAGE( \\\n\t\t\tm_gasUsed >= metaCost, \\\n\t\t\t\"Gas used: \" + \\\n\t\t\tm_gasUsed.str() + \\\n\t\t\t\" is less than the data cost for the cbor metadata: \" + \\\n\t\t\tu256(metaCost).str() \\\n\t\t); \\\n\t\tu256 gasUsed = m_gasUsed - metaCost; \\\n\t\tBOOST_CHECK_MESSAGE( \\\n\t\t\tgas == gasUsed, \\\n\t\t\t\"Gas used: \" + \\\n\t\t\tgasUsed.str() + \\\n\t\t\t\" - expected: \" + \\\n\t\t\tgas.str() \\\n\t\t); \\\n\t} while(0)\n\n#define CHECK_GAS(_gasNoOpt, _gasOpt, _tolerance) \\\n\tdo \\\n\t{ \\\n\t\tu256 gasOpt{_gasOpt}; \\\n\t\tu256 gasNoOpt{_gasNoOpt}; \\\n\t\tu256 tolerance{_tolerance}; \\\n\t\tu256 gas = m_optimiserSettings == OptimiserSettings::minimal() ? gasNoOpt : gasOpt; \\\n\t\tu256 diff = gas < m_gasUsed ? m_gasUsed - gas : gas - m_gasUsed; \\\n\t\tBOOST_CHECK_MESSAGE( \\\n\t\t\tdiff <= tolerance, \\\n\t\t\t\"Gas used: \" + \\\n\t\t\tm_gasUsed.str() + \\\n\t\t\t\" - expected: \" + \\\n\t\t\tgas.str() + \\\n\t\t\t\" (tolerance: \" + \\\n\t\t\ttolerance.str() + \\\n\t\t\t\")\" \\\n\t\t); \\\n\t} while(0)\n\nBOOST_FIXTURE_TEST_SUITE(GasCostTests, SolidityExecutionFramework)\n\nBOOST_AUTO_TEST_CASE(string_storage)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f() pure public {\n\t\t\t\trequire(false, \"Not Authorized. This function can only be called by the custodian or owner of this contract\");\n\t\t\t}\n\t\t}\n\t)\";\n\tm_compiler.setMetadataFormat(CompilerStack::MetadataFormat::NoMetadata);\n\tm_appendCBORMetadata = false;\n\tcompileAndRun(sourceCode);\n\n\tauto evmVersion = solidity::test::CommonOptions::get().evmVersion();\n\n\tif (evmVersion <= EVMVersion::byzantium())\n\t{\n\t\tif (CommonOptions::get().useABIEncoderV1)\n\t\t\tCHECK_DEPLOY_GAS(133045, 129731, evmVersion);\n\t\telse\n\t\t\tCHECK_DEPLOY_GAS(144995, 121229, evmVersion);\n\t}\n\t// This is only correct on >=Constantinople.\n\telse if (!CommonOptions::get().useABIEncoderV1)\n\t{\n\t\tif (CommonOptions::get().optimize)\n\t\t{\n\t\t\t// Costs with 0 are cases which cannot be triggered in tests.\n\t\t\tif (evmVersion < EVMVersion::istanbul())\n\t\t\t\tCHECK_DEPLOY_GAS(0, 109237, evmVersion);\n\t\t\telse if (evmVersion < EVMVersion::shanghai())\n\t\t\t\tCHECK_DEPLOY_GAS(0, 97693, evmVersion);\n\t\t\t// Shanghai is cheaper due to `push0`\n\t\t\telse\n\t\t\t\tCHECK_DEPLOY_GAS(0, 97067, evmVersion);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (evmVersion < EVMVersion::istanbul())\n\t\t\t\tCHECK_DEPLOY_GAS(139009, 123969, evmVersion);\n\t\t\telse if (evmVersion < EVMVersion::shanghai())\n\t\t\t\tCHECK_DEPLOY_GAS(123357, 110969, evmVersion);\n\t\t\t// Shanghai is cheaper due to `push0`\n\t\t\telse\n\t\t\t\tCHECK_DEPLOY_GAS(121489, 110969, evmVersion);\n\t\t}\n\t}\n\telse if (evmVersion < EVMVersion::istanbul())\n\t\tCHECK_DEPLOY_GAS(125829, 118559, evmVersion);\n\telse if (evmVersion < EVMVersion::shanghai())\n\t\tCHECK_DEPLOY_GAS(114077, 96461, evmVersion);\n\telse\n\t\tCHECK_DEPLOY_GAS(114077, 95831, evmVersion);\n\n\tif (evmVersion >= EVMVersion::byzantium())\n\t{\n\t\tcallContractFunction(\"f()\");\n\t\tif (evmVersion == EVMVersion::byzantium())\n\t\t\tCHECK_GAS(21741, 21522, 20);\n\t\t// This is only correct on >=Constantinople.\n\t\telse if (!CommonOptions::get().useABIEncoderV1)\n\t\t{\n\t\t\tif (CommonOptions::get().optimize)\n\t\t\t{\n\t\t\t\tif (evmVersion < EVMVersion::istanbul())\n\t\t\t\t\tCHECK_GAS(0, 21526, 20);\n\t\t\t\telse\n\t\t\t\t\tCHECK_GAS(0, 21318, 20);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (evmVersion < EVMVersion::istanbul())\n\t\t\t\t\tCHECK_GAS(21736, 21559, 20);\n\t\t\t\telse\n\t\t\t\t\tCHECK_GAS(21528, 21351, 20);\n\t\t\t}\n\t\t}\n\t\telse if (evmVersion < EVMVersion::istanbul())\n\t\t\tCHECK_GAS(21546, 21526, 20);\n\t\telse\n\t\t\tCHECK_GAS(21332, 21322, 20);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(single_callvaluecheck)\n{\n\tstd::string sourceCode = R\"(\n\t\t// All functions nonpayable, we can check callvalue at the beginning\n\t\tcontract Nonpayable {\n\t\t\taddress a;\n\t\t\tfunction f(address b) public {\n\t\t\t\ta = b;\n\t\t\t}\n\t\t\tfunction f1(address b) public pure returns (uint c) {\n\t\t\t\treturn uint160(b) + 2;\n\t\t\t}\n\t\t\tfunction f2(address b) public pure returns (uint) {\n\t\t\t\treturn uint160(b) + 8;\n\t\t\t}\n\t\t\tfunction f3(address, uint c) pure public returns (uint) {\n\t\t\t\treturn c - 5;\n\t\t\t}\n\t\t}\n\t\t// At least on payable function, we cannot do the optimization.\n\t\tcontract Payable {\n\t\t\taddress a;\n\t\t\tfunction f(address b) public {\n\t\t\t\ta = b;\n\t\t\t}\n\t\t\tfunction f1(address b) public pure returns (uint c) {\n\t\t\t\treturn uint160(b) + 2;\n\t\t\t}\n\t\t\tfunction f2(address b) public pure returns (uint) {\n\t\t\t\treturn uint160(b) + 8;\n\t\t\t}\n\t\t\tfunction f3(address, uint c) payable public returns (uint) {\n\t\t\t\treturn c - 5;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode);\n\tsize_t bytecodeSizeNonpayable = m_compiler.object(\"Nonpayable\").bytecode.size();\n\tsize_t bytecodeSizePayable = m_compiler.object(\"Payable\").bytecode.size();\n\n\tauto evmVersion = solidity::test::CommonOptions::get().evmVersion();\n\tif (evmVersion < EVMVersion::shanghai())\n\t\tBOOST_CHECK_EQUAL(bytecodeSizePayable - bytecodeSizeNonpayable, 26);\n\telse\n\t\tBOOST_CHECK_EQUAL(bytecodeSizePayable - bytecodeSizeNonpayable, 24);\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n}\n"
  },
  {
    "path": "test/libsolidity/GasMeter.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Unit tests for the gas estimator.\n */\n\n#include <test/libsolidity/SolidityExecutionFramework.h>\n#include <libevmasm/GasMeter.h>\n#include <libevmasm/KnownState.h>\n#include <libevmasm/PathGasMeter.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/interface/GasEstimator.h>\n\nusing namespace solidity::langutil;\nusing namespace solidity::evmasm;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\nusing namespace solidity::test;\n\nnamespace solidity::frontend::test\n{\n\nclass GasMeterTestFramework: public SolidityExecutionFramework\n{\npublic:\n\tvoid compile(std::string const& _sourceCode)\n\t{\n\t\tm_compiler.reset();\n\t\tm_compiler.setSources({{\"\", \"pragma solidity >=0.0;\\n\"\n\t\t\t\t\"// SPDX-License-Identifier: GPL-3.0\\n\" + _sourceCode}});\n\t\tm_compiler.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n\t\tm_compiler.setEVMVersion(m_evmVersion);\n\t\tBOOST_REQUIRE_MESSAGE(m_compiler.compile(), \"Compiling contract failed\");\n\t}\n\n\tvoid testCreationTimeGas(std::string const& _sourceCode, u256 const& _tolerance = u256(0))\n\t{\n\t\tcompileAndRun(_sourceCode);\n\t\tauto state = std::make_shared<KnownState>();\n\t\tPathGasMeter meter(*m_compiler.assemblyItems(m_compiler.lastContractName()), solidity::test::CommonOptions::get().evmVersion());\n\t\tGasMeter::GasConsumption gas = meter.estimateMax(0, state);\n\t\tu256 bytecodeSize(m_compiler.runtimeObject(m_compiler.lastContractName()).bytecode.size());\n\t\t// costs for deployment\n\t\tgas += bytecodeSize * GasCosts::createDataGas;\n\t\t// costs for transaction\n\t\tgas += gasForTransaction(m_compiler.object(m_compiler.lastContractName()).bytecode, true);\n\n\t\tBOOST_REQUIRE(!gas.isInfinite);\n\t\tBOOST_CHECK_LE(m_gasUsed, gas.value);\n\t\tBOOST_CHECK_LE(gas.value - _tolerance, m_gasUsed);\n\t}\n\n\t/// Compares the gas computed by PathGasMeter for the given signature (but unknown arguments)\n\t/// against the actual gas usage computed by the VM on the given set of argument variants.\n\tvoid testRunTimeGas(std::string const& _sig, std::vector<bytes> _argumentVariants, u256 const& _tolerance = u256(0))\n\t{\n\t\tu256 gasUsed = 0;\n\t\tGasMeter::GasConsumption gas;\n\t\tutil::FixedHash<4> hash = util::selectorFromSignatureH32(_sig);\n\t\tfor (bytes const& arguments: _argumentVariants)\n\t\t{\n\t\t\tsendMessage(hash.asBytes(), arguments, false, 0);\n\t\t\tBOOST_CHECK(m_transactionSuccessful);\n\t\t\tgasUsed = std::max(gasUsed, m_gasUsed);\n\t\t\tgas = std::max(gas, gasForTransaction(hash.asBytes() + arguments, false));\n\t\t}\n\n\t\tgas += GasEstimator(solidity::test::CommonOptions::get().evmVersion()).functionalEstimation(\n\t\t\t*m_compiler.runtimeAssemblyItems(m_compiler.lastContractName()),\n\t\t\t_sig\n\t\t);\n\t\tBOOST_REQUIRE(!gas.isInfinite);\n\t\tBOOST_CHECK_LE(m_gasUsed, gas.value);\n\t\tBOOST_CHECK_LE(gas.value - _tolerance, m_gasUsed);\n\t}\n\n\tstatic GasMeter::GasConsumption gasForTransaction(bytes const& _data, bool _isCreation)\n\t{\n\t\tauto evmVersion = solidity::test::CommonOptions::get().evmVersion();\n\t\tGasMeter::GasConsumption gas = _isCreation ? GasCosts::txCreateGas : GasCosts::txGas;\n\t\tfor (auto i: _data)\n\t\t\tgas += i != 0 ? GasCosts::txDataNonZeroGas(evmVersion) : GasCosts::txDataZeroGas;\n\t\treturn gas;\n\t}\n};\n\nBOOST_FIXTURE_TEST_SUITE(GasMeterTests, GasMeterTestFramework)\n\nBOOST_AUTO_TEST_CASE(simple_contract)\n{\n\t// Tests a simple \"deploy contract\" code without constructor. The actual contract is not relevant.\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tbytes32 public shaValue;\n\t\t\tfunction f(uint a) public {\n\t\t\t\tshaValue = keccak256(abi.encodePacked(a));\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode);\n}\n\nBOOST_AUTO_TEST_CASE(store_keccak256)\n{\n\tchar const* sourceCode = R\"(\n\t\t// TODO: We should enable v2 again once the yul optimizer is activated.\n\t\tpragma abicoder v1;\n\n\t\tcontract test {\n\t\t\tbytes32 public shaValue;\n\t\t\tconstructor() {\n\t\t\t\tshaValue = keccak256(abi.encodePacked(this));\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode);\n}\n\nBOOST_AUTO_TEST_CASE(updating_store)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tuint data;\n\t\t\tuint data2;\n\t\t\tconstructor() {\n\t\t\t\tdata = 1;\n\t\t\t\tdata = 2;\n\t\t\t\tdata2 = 0;\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode, m_evmVersion < langutil::EVMVersion::constantinople() ? u256(0) : u256(9600));\n}\n\nBOOST_AUTO_TEST_CASE(branches)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tuint data;\n\t\t\tuint data2;\n\t\t\tfunction f(uint x) public {\n\t\t\t\tif (x > 7)\n\t\t\t\t\tdata2 = 1;\n\t\t\t\telse\n\t\t\t\t\tdata = 1;\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode, 1);\n\ttestRunTimeGas(\"f(uint256)\", std::vector<bytes>{encodeArgs(2), encodeArgs(8)}, 1);\n}\n\nBOOST_AUTO_TEST_CASE(function_calls)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tuint data;\n\t\t\tuint data2;\n\t\t\tfunction f(uint x) public {\n\t\t\t\tif (x > 7)\n\t\t\t\t\t{ unchecked { data2 = g(x**8) + 1; } }\n\t\t\t\telse\n\t\t\t\t\tdata = 1;\n\t\t\t}\n\t\t\tfunction g(uint x) internal returns (uint) {\n\t\t\t\treturn data2;\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode);\n\t// In f, data2 is accessed twice, so there is a reduction of 2200 to 100 in actual costs.\n\t// However, GasMeter always assumes cold costs.\n\ttestRunTimeGas(\n\t\t\"f(uint256)\",\n\t\tstd::vector<bytes>{encodeArgs(2), encodeArgs(8)},\n\t\tm_evmVersion < EVMVersion::berlin() ?\n\t\tu256(0) :\n\t\tu256(2100)\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(multiple_external_functions)\n{\n\tchar const* sourceCode = R\"(\n\t\t// TODO: We should enable v2 again once the yul optimizer is activated.\n\t\tpragma abicoder v1;\n\n\t\tcontract test {\n\t\t\tuint data;\n\t\t\tuint data2;\n\t\t\tfunction f(uint x) public {\n\t\t\t\tif (x > 7)\n\t\t\t\t\t{ unchecked { data2 = g(x**8) + 1; } }\n\t\t\t\telse\n\t\t\t\t\tdata = 1;\n\t\t\t}\n\t\t\tfunction g(uint x) public returns (uint) {\n\t\t\t\treturn data2;\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode);\n\t// In f, data2 is accessed twice, so there is a reduction of 2200 to 100 in actual costs.\n\t// However, GasMeter always assumes cold costs.\n\ttestRunTimeGas(\n\t\t\"f(uint256)\",\n\t\tstd::vector<bytes>{encodeArgs(2), encodeArgs(8)},\n\t\tm_evmVersion < EVMVersion::berlin() ?\n\t\tu256(0) :\n\t\tu256(2100)\n\t);\n\n\ttestRunTimeGas(\"g(uint256)\", std::vector<bytes>{encodeArgs(2)});\n}\n\nBOOST_AUTO_TEST_CASE(exponent_size)\n{\n\tchar const* sourceCode = R\"(\n\t\t// TODO: We should enable v2 again once the yul optimizer is activated.\n\t\tpragma abicoder v1;\n\n\t\tcontract A {\n\t\t\tfunction f(uint x) public returns (uint) {\n\t\t\t\tunchecked { return x ** 0; }\n\t\t\t}\n\t\t\tfunction g(uint x) public returns (uint) {\n\t\t\t\tunchecked { return x ** 0x100; }\n\t\t\t}\n\t\t\tfunction h(uint x) public returns (uint) {\n\t\t\t\tunchecked { return x ** 0x10000; }\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode);\n\ttestRunTimeGas(\"f(uint256)\", std::vector<bytes>{encodeArgs(2)});\n\ttestRunTimeGas(\"g(uint256)\", std::vector<bytes>{encodeArgs(2)});\n\ttestRunTimeGas(\"h(uint256)\", std::vector<bytes>{encodeArgs(2)});\n}\n\nBOOST_AUTO_TEST_CASE(balance_gas)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract A {\n\t\t\tfunction lookup_balance(address a) public returns (uint) {\n\t\t\t\treturn a.balance;\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode);\n\ttestRunTimeGas(\"lookup_balance(address)\", std::vector<bytes>{encodeArgs(2), encodeArgs(100)});\n}\n\nBOOST_AUTO_TEST_CASE(extcodesize_gas)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract A {\n\t\t\tfunction f() public returns (uint _s) {\n\t\t\t\tassembly {\n\t\t\t\t\t_s := extcodesize(0x30)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode);\n\ttestRunTimeGas(\"f()\", std::vector<bytes>{encodeArgs()});\n}\n\nBOOST_AUTO_TEST_CASE(regular_functions_exclude_fallback)\n{\n\t// A bug in the estimator caused the costs for a specific function\n\t// to always include the costs for the fallback.\n\tchar const* sourceCode = R\"(\n\t\tcontract A {\n\t\t\tuint public x;\n\t\t\tfallback() external { x = 2; }\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode);\n\ttestRunTimeGas(\"x()\", std::vector<bytes>{encodeArgs()});\n}\n\nBOOST_AUTO_TEST_CASE(complex_control_flow)\n{\n\t// This crashed the gas estimator previously (or took a very long time).\n\t// Now we do not follow branches if they start out with lower gas costs than the ones\n\t// we previously considered. This of course reduces accuracy.\n\tchar const* sourceCode = R\"(\n\t\t// TODO: We should enable v2 again once the yul optimizer is activated.\n\t\tpragma abicoder v1;\n\n\t\tcontract log {\n\t\t\tfunction ln(int128 x) public pure returns (int128 result) {\n\t\t\t\tunchecked {\n\t\t\t\t\tint128 t = x / 256;\n\t\t\t\t\tint128 y = 5545177;\n\t\t\t\t\tx = t;\n\t\t\t\t\tt = x * 16; if (t <= 1000000) { x = t; y = y - 2772588; }\n\t\t\t\t\tt = x * 4; if (t <= 1000000) { x = t; y = y - 1386294; }\n\t\t\t\t\tt = x * 2; if (t <= 1000000) { x = t; y = y - 693147; }\n\t\t\t\t\tt = x + x / 2; if (t <= 1000000) { x = t; y = y - 405465; }\n\t\t\t\t\tt = x + x / 4; if (t <= 1000000) { x = t; y = y - 223144; }\n\t\t\t\t\tt = x + x / 8; if (t <= 1000000) { x = t; y = y - 117783; }\n\t\t\t\t\tt = x + x / 16; if (t <= 1000000) { x = t; y = y - 60624; }\n\t\t\t\t\tt = x + x / 32; if (t <= 1000000) { x = t; y = y - 30771; }\n\t\t\t\t\tt = x + x / 64; if (t <= 1000000) { x = t; y = y - 15504; }\n\t\t\t\t\tt = x + x / 128; if (t <= 1000000) { x = t; y = y - 7782; }\n\t\t\t\t\tt = x + x / 256; if (t <= 1000000) { x = t; y = y - 3898; }\n\t\t\t\t\tt = x + x / 512; if (t <= 1000000) { x = t; y = y - 1951; }\n\t\t\t\t\tt = x + x / 1024; if (t <= 1000000) { x = t; y = y - 976; }\n\t\t\t\t\tt = x + x / 2048; if (t <= 1000000) { x = t; y = y - 488; }\n\t\t\t\t\tt = x + x / 4096; if (t <= 1000000) { x = t; y = y - 244; }\n\t\t\t\t\tt = x + x / 8192; if (t <= 1000000) { x = t; y = y - 122; }\n\t\t\t\t\tt = x + x / 16384; if (t <= 1000000) { x = t; y = y - 61; }\n\t\t\t\t\tt = x + x / 32768; if (t <= 1000000) { x = t; y = y - 31; }\n\t\t\t\t\tt = x + x / 65536; if (t <= 1000000) { y = y - 15; }\n\t\t\t\t\treturn y;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode);\n\t// max gas is used for small x\n\ttestRunTimeGas(\"ln(int128)\", std::vector<bytes>{encodeArgs(0), encodeArgs(10), encodeArgs(105), encodeArgs(30000)});\n}\n\nBOOST_AUTO_TEST_CASE(\n\tmcopy_memory_expansion_gas,\n\t*boost::unit_test::precondition(minEVMVersionCheck(EVMVersion::cancun()))\n)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction no_expansion() public {\n\t\t\t\tassembly {\n\t\t\t\t\tmstore(0xffe0, 1) // expand memory before using mcopy\n\t\t\t\t\tmcopy(0, 0xffff, 1)\n\t\t\t\t\treturn(0, 1)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction expansion_on_write() public {\n\t\t\t\tassembly {\n\t\t\t\t\tmcopy(0xffff, 0, 1)\n\t\t\t\t\treturn(0xffff, 1)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction expansion_on_read() public {\n\t\t\t\tassembly {\n\t\t\t\t\tmcopy(0, 0xffff, 1)\n\t\t\t\t\treturn(0, 1)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction expansion_on_read_write() public {\n\t\t\t\tassembly {\n\t\t\t\t\tmcopy(0xffff, 0xffff, 1)\n\t\t\t\t\treturn(0, 1)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction expansion_on_zero_size() public {\n\t\t\t\tassembly {\n\t\t\t\t\tmcopy(0xffff, 0xffff, 0)\n\t\t\t\t\treturn(0, 1)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction expansion_on_0_0_0() public {\n\t\t\t\tassembly {\n\t\t\t\t\tmcopy(0, 0, 0)\n\t\t\t\t\treturn(0, 1)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode);\n\ttestRunTimeGas(\"no_expansion()\", {encodeArgs()});\n\ttestRunTimeGas(\"expansion_on_write()\", {encodeArgs()});\n\ttestRunTimeGas(\"expansion_on_read()\", {encodeArgs()});\n\ttestRunTimeGas(\"expansion_on_read_write()\", {encodeArgs()});\n\ttestRunTimeGas(\"expansion_on_zero_size()\", {encodeArgs()});\n\ttestRunTimeGas(\"expansion_on_0_0_0()\", {encodeArgs()});\n}\n\nBOOST_AUTO_TEST_CASE(\n\tmcopy_word_gas,\n\t*boost::unit_test::precondition(minEVMVersionCheck(EVMVersion::cancun()))\n)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction no_overlap() public {\n\t\t\t\tassembly {\n\t\t\t\t\tmstore(0xffe0, 1) // expand memory before using mcopy\n\t\t\t\t\tmcopy(0x4000, 0x2000, 0x2000)\n\t\t\t\t\treturn(0, 0x10000)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction overlap_right() public {\n\t\t\t\tassembly {\n\t\t\t\t\tmstore(0xffe0, 1) // expand memory before using mcopy\n\t\t\t\t\tmcopy(0x3000, 0x2000, 0x2000)\n\t\t\t\t\treturn(0, 0x10000)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction overlap_left() public {\n\t\t\t\tassembly {\n\t\t\t\t\tmstore(0xffe0, 1) // expand memory before using mcopy\n\t\t\t\t\tmcopy(0x1000, 0x2000, 0x2000)\n\t\t\t\t\treturn(0, 0x10000)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction overlap_full() public {\n\t\t\t\tassembly {\n\t\t\t\t\tmstore(0xffe0, 1) // expand memory before using mcopy\n\t\t\t\t\tmcopy(0x2000, 0x2000, 0x2000)\n\t\t\t\t\treturn(0, 0x10000)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t)\";\n\ttestCreationTimeGas(sourceCode);\n\ttestRunTimeGas(\"no_overlap()\", {encodeArgs()});\n\ttestRunTimeGas(\"overlap_right()\", {encodeArgs()});\n\ttestRunTimeGas(\"overlap_left()\", {encodeArgs()});\n\ttestRunTimeGas(\"overlap_full()\", {encodeArgs()});\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n}\n"
  },
  {
    "path": "test/libsolidity/GasTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/libsolidity/GasTest.h>\n#include <test/libsolidity/util/Common.h>\n#include <test/Common.h>\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/JSON.h>\n#include <libsolutil/StringUtils.h>\n#include <boost/algorithm/string.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n#include <boost/filesystem.hpp>\n#include <boost/test/unit_test.hpp>\n#include <boost/throw_exception.hpp>\n#include <fstream>\n#include <stdexcept>\n\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\nusing namespace solidity;\nusing namespace boost::unit_test;\n\nGasTest::GasTest(std::string const& _filename):\n\tEVMVersionRestrictedTestCase(_filename)\n{\n\tm_source = m_reader.source();\n\tm_optimise = m_reader.boolSetting(\"optimize\", false);\n\tm_optimiseYul = m_reader.boolSetting(\"optimize-yul\", false);\n\tm_optimiseRuns = m_reader.sizetSetting(\"optimize-runs\", OptimiserSettings{}.expectedExecutionsPerDeployment);\n\tparseExpectations(m_reader.stream());\n}\n\nvoid GasTest::parseExpectations(std::istream& _stream)\n{\n\tstd::map<std::string, std::string>* currentKind = nullptr;\n\tstd::string line;\n\n\twhile (getline(_stream, line))\n\t\tif (!boost::starts_with(line, \"// \"))\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid expectation: expected \\\"// \\\".\"));\n\t\telse if (boost::ends_with(line, \":\"))\n\t\t{\n\t\t\tstd::string kind = line.substr(3, line.length() - 4);\n\t\t\tboost::trim(kind);\n\t\t\tcurrentKind = &m_expectations[std::move(kind)];\n\t\t}\n\t\telse if (!currentKind)\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"No function kind specified. Expected \\\"creation:\\\", \\\"external:\\\" or \\\"internal:\\\".\"));\n\t\telse\n\t\t{\n\t\t\tauto it = line.begin() + 3;\n\t\t\tskipWhitespace(it, line.end());\n\t\t\tauto functionNameBegin = it;\n\t\t\twhile (it != line.end() && *it != ':')\n\t\t\t\t++it;\n\t\t\tstd::string functionName(functionNameBegin, it);\n\t\t\tif (functionName == \"fallback\")\n\t\t\t\tfunctionName.clear();\n\t\t\texpect(it, line.end(), ':');\n\t\t\tskipWhitespace(it, line.end());\n\t\t\tif (it == line.end())\n\t\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid expectation: expected gas cost.\"));\n\t\t\t(*currentKind)[functionName] = std::string(it, line.end());\n\t\t}\n}\n\nvoid GasTest::printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const\n{\n\tJson estimates = compiler().gasEstimates(compiler().lastContractName());\n\tfor (auto& [key, group] : estimates.items())\n\t{\n\t\t_stream << _linePrefix << key << \":\" << std::endl;\n\t\tfor (auto& [elementKey, value] : group.items())\n\t\t{\n\t\t\t_stream << _linePrefix << \"  \";\n\t\t\tif (elementKey.empty())\n\t\t\t\t_stream << \"fallback\";\n\t\t\telse\n\t\t\t\t_stream << elementKey;\n\t\t\t_stream << \": \" << value.get<std::string>() << std::endl;\n\t\t}\n\t}\n}\n\nvoid GasTest::setupCompiler(CompilerStack& _compiler)\n{\n\tAnalysisFramework::setupCompiler(_compiler);\n\n\t// Prerelease CBOR metadata varies in size due to changing version numbers and build dates.\n\t// This leads to volatile creation cost estimates. Therefore we force the compiler to\n\t// release mode for testing gas estimates.\n\t_compiler.setMetadataFormat(CompilerStack::MetadataFormat::NoMetadata);\n\tOptimiserSettings settings = m_optimise ? OptimiserSettings::standard() : OptimiserSettings::minimal();\n\tif (m_optimiseYul)\n\t{\n\t\tsettings.runYulOptimiser = m_optimise;\n\t\tsettings.optimizeStackAllocation = m_optimise;\n\t}\n\tsettings.expectedExecutionsPerDeployment = m_optimiseRuns;\n\t_compiler.setOptimiserSettings(settings);\n}\n\nTestCase::TestResult GasTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted)\n{\n\tif (!runFramework(withPreamble(m_source), PipelineStage::Compilation))\n\t{\n\t\tutil::printPrefixed(_stream, formatErrors(filteredErrors(), _formatted), _linePrefix);\n\t\treturn TestResult::FatalError;\n\t}\n\n\tJson estimateGroups = compiler().gasEstimates(compiler().lastContractName());\n\tif (\n\t\tm_expectations.size() == estimateGroups.size() &&\n\t\tboost::all(m_expectations, [&](auto const& expectations) {\n\t\tauto const& estimates = estimateGroups[expectations.first];\n\t\treturn estimates.size() == expectations.second.size() &&\n\t\t\tboost::all(expectations.second, [&](auto const& entry) {\n\t\t\t\treturn entry.second == estimates[entry.first].template get<std::string>();\n\t\t\t});\n\t\t})\n\t)\n\t\treturn TestResult::Success;\n\telse\n\t{\n\t\t_stream << _linePrefix << \"Expected:\" << std::endl;\n\t\tfor (auto const& expectations: m_expectations)\n\t\t{\n\t\t\t_stream << _linePrefix << \"  \" << expectations.first << \":\" << std::endl;\n\t\t\tfor (auto const& entry: expectations.second)\n\t\t\t\t_stream << _linePrefix\n\t\t\t\t\t<< \"    \"\n\t\t\t\t\t<< (entry.first.empty() ? \"fallback\" : entry.first)\n\t\t\t\t\t<< \": \"\n\t\t\t\t\t<< entry.second\n\t\t\t\t\t<< std::endl;\n\t\t}\n\t\t_stream << _linePrefix << \"Obtained:\" << std::endl;\n\t\tprintUpdatedExpectations(_stream, _linePrefix + \"  \");\n\t\treturn TestResult::Failure;\n\t}\n}\n"
  },
  {
    "path": "test/libsolidity/GasTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <test/libsolidity/AnalysisFramework.h>\n#include <test/TestCase.h>\n#include <liblangutil/Exceptions.h>\n\n#include <libsolidity/interface/OptimiserSettings.h>\n\n#include <iosfwd>\n#include <string>\n#include <vector>\n#include <utility>\n\nnamespace solidity::frontend::test\n{\n\nclass GasTest: AnalysisFramework, public EVMVersionRestrictedTestCase\n{\npublic:\n\tstatic std::unique_ptr<TestCase> create(Config const& _config)\n\t{ return std::make_unique<GasTest>(_config.filename); }\n\tGasTest(std::string const& _filename);\n\n\tTestResult run(std::ostream& _stream, std::string const& _linePrefix = \"\", bool _formatted = false) override;\n\n\tvoid printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;\n\nprotected:\n\tvoid setupCompiler(CompilerStack& _compiler) override;\n\nprivate:\n\tvoid parseExpectations(std::istream& _stream);\n\n\tbool m_optimise = false;\n\tbool m_optimiseYul = false;\n\tsize_t m_optimiseRuns = OptimiserSettings{}.expectedExecutionsPerDeployment;\n\tstd::map<std::string, std::map<std::string, std::string>> m_expectations;\n};\n\n}\n"
  },
  {
    "path": "test/libsolidity/Imports.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Tests for high level features like import.\n */\n\n#include <test/libsolidity/ErrorCheck.h>\n#include <test/Common.h>\n\n#include <liblangutil/Exceptions.h>\n#include <libsolidity/interface/CompilerStack.h>\n#include <libsolidity/interface/ImportRemapper.h>\n\n#include <boost/test/unit_test.hpp>\n\n#include <string>\n\n\nnamespace solidity::frontend::test\n{\n\nBOOST_AUTO_TEST_SUITE(SolidityImports)\n\nBOOST_AUTO_TEST_CASE(remappings)\n{\n\tCompilerStack c;\n\tc.setRemappings(std::vector<ImportRemapper::Remapping>{{\"\", \"s\", \"s_1.4.6\"},{\"\", \"t\", \"Tee\"}});\n\tc.setSources({\n\t\t{\"a\", \"import \\\"s/s.sol\\\"; contract A is S {} pragma solidity >=0.0;\"},\n\t\t{\"b\", \"import \\\"t/tee.sol\\\"; contract A is Tee {} pragma solidity >=0.0;\"},\n\t\t{\"s_1.4.6/s.sol\", \"contract S {} pragma solidity >=0.0;\"},\n\t\t{\"Tee/tee.sol\", \"contract Tee {} pragma solidity >=0.0;\"}\n\t});\n\tc.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_CHECK(c.compile());\n}\n\nBOOST_AUTO_TEST_CASE(context_dependent_remappings)\n{\n\tCompilerStack c;\n\tc.setRemappings(std::vector<ImportRemapper::Remapping>{{\"a\", \"s\", \"s_1.4.6\"}, {\"b\", \"s\", \"s_1.4.7\"}});\n\tc.setSources({\n\t\t{\"a/a.sol\", \"import \\\"s/s.sol\\\"; contract A is SSix {} pragma solidity >=0.0;\"},\n\t\t{\"b/b.sol\", \"import \\\"s/s.sol\\\"; contract B is SSeven {} pragma solidity >=0.0;\"},\n\t\t{\"s_1.4.6/s.sol\", \"contract SSix {} pragma solidity >=0.0;\"},\n\t\t{\"s_1.4.7/s.sol\", \"contract SSeven {} pragma solidity >=0.0;\"}\n\t});\n\tc.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_CHECK(c.compile());\n}\n\nBOOST_AUTO_TEST_CASE(context_dependent_remappings_ensure_default_and_module_preserved)\n{\n\tCompilerStack c;\n\tc.setRemappings(std::vector<ImportRemapper::Remapping>{\n\t\t{\"\", \"foo\", \"vendor/foo_2.0.0\"},\n\t\t{\"vendor/bar\", \"foo\", \"vendor/foo_1.0.0\"},\n\t\t{\"\", \"bar\", \"vendor/bar\"}\n\t});\n\tc.setSources({\n\t\t{\"main.sol\", \"import \\\"foo/foo.sol\\\"; import {Bar} from \\\"bar/bar.sol\\\"; contract Main is Foo2, Bar {} pragma solidity >=0.0;\"},\n\t\t{\"vendor/bar/bar.sol\", \"import \\\"foo/foo.sol\\\"; contract Bar {Foo1 foo;} pragma solidity >=0.0;\"},\n\t\t{\"vendor/foo_1.0.0/foo.sol\", \"contract Foo1 {} pragma solidity >=0.0;\"},\n\t\t{\"vendor/foo_2.0.0/foo.sol\", \"contract Foo2 {} pragma solidity >=0.0;\"}\n\t});\n\tc.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_CHECK(c.compile());\n}\n\nBOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent_1)\n{\n\tCompilerStack c;\n\tc.setRemappings(std::vector<ImportRemapper::Remapping>{{\"a\", \"x/y/z\", \"d\"}, {\"a/b\", \"x\", \"e\"}});\n\tc.setSources({\n\t\t{\"a/main.sol\", \"import \\\"x/y/z/z.sol\\\"; contract Main is D {} pragma solidity >=0.0;\"},\n\t\t{\"a/b/main.sol\", \"import \\\"x/y/z/z.sol\\\"; contract Main is E {} pragma solidity >=0.0;\"},\n\t\t{\"d/z.sol\", \"contract D {} pragma solidity >=0.0;\"},\n\t\t{\"e/y/z/z.sol\", \"contract E {} pragma solidity >=0.0;\"}\n\t});\n\tc.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_CHECK(c.compile());\n}\n\nBOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent_2)\n{\n\tCompilerStack c;\n\tc.setRemappings(std::vector<ImportRemapper::Remapping>{{\"a/b\", \"x\", \"e\"}, {\"a\", \"x/y/z\", \"d\"}});\n\tc.setSources({\n\t\t{\"a/main.sol\", \"import \\\"x/y/z/z.sol\\\"; contract Main is D {} pragma solidity >=0.0;\"},\n\t\t{\"a/b/main.sol\", \"import \\\"x/y/z/z.sol\\\"; contract Main is E {} pragma solidity >=0.0;\"},\n\t\t{\"d/z.sol\", \"contract D {} pragma solidity >=0.0;\"},\n\t\t{\"e/y/z/z.sol\", \"contract E {} pragma solidity >=0.0;\"}\n\t});\n\tc.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\tBOOST_CHECK(c.compile());\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/InlineAssembly.cpp",
    "content": "/*\n    This file is part of solidity.\n\n    solidity is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    solidity is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * @author Christian <c@ethdev.com>\n * @date 2016\n * Unit tests for inline assembly.\n */\n\n#include <test/Common.h>\n\n#include <test/libsolidity/ErrorCheck.h>\n\n#include <libsolidity/ast/AST.h>\n\n#include <libyul/YulStack.h>\n\n#include <liblangutil/DebugInfoSelection.h>\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/Scanner.h>\n#include <liblangutil/SourceReferenceFormatter.h>\n\n#include <libevmasm/Assembly.h>\n\n#include <boost/algorithm/string/replace.hpp>\n#include <boost/test/unit_test.hpp>\n\n#include <memory>\n#include <optional>\n#include <string>\n\nusing namespace solidity::langutil;\nusing namespace solidity::yul;\nusing namespace solidity::test;\n\nnamespace solidity::frontend::test\n{\n\nnamespace\n{\n\nstd::optional<Error> parseAndReturnFirstError(\n\tstd::string const& _source,\n\tbool _assemble = false,\n\tbool _allowWarnings = true,\n\tYulStack::Machine _machine = YulStack::Machine::EVM\n)\n{\n\tYulStack stack(\n\t\tsolidity::test::CommonOptions::get().evmVersion(),\n\t\tsolidity::test::CommonOptions::get().eofVersion(),\n\t\tsolidity::frontend::OptimiserSettings::none(),\n\t\tDebugInfoSelection::None()\n\t);\n\tbool success = stack.parseAndAnalyze(\"\", _source);\n\tif (success && _assemble)\n\t\tstack.assemble(_machine);\n\tstd::shared_ptr<Error const> error;\n\tfor (auto const& e: stack.errors())\n\t{\n\t\tif (_allowWarnings && e->type() == Error::Type::Warning)\n\t\t\tcontinue;\n\t\tif (error)\n\t\t\tBOOST_FAIL(\n\t\t\t\t\"Found more than one error:\\n\" +\n\t\t\t\tSourceReferenceFormatter::formatErrorInformation(stack.errors(), stack)\n\t\t\t);\n\t\terror = e;\n\t}\n\tif (!success)\n\t\tBOOST_REQUIRE(error);\n\tif (error)\n\t\treturn *error;\n\treturn {};\n}\n\nbool successParse(\n\tstd::string const& _source,\n\tbool _assemble = false,\n\tbool _allowWarnings = true,\n\tYulStack::Machine _machine = YulStack::Machine::EVM\n)\n{\n\treturn !parseAndReturnFirstError(_source, _assemble, _allowWarnings, _machine);\n}\n\nbool successAssemble(std::string const& _source, bool _allowWarnings = true)\n{\n\treturn\n\t\tsuccessParse(_source, true, _allowWarnings, YulStack::Machine::EVM);\n}\n\nError expectError(\n\tstd::string const& _source,\n\tbool _assemble,\n\tbool _allowWarnings = false\n)\n{\n\n\tauto error = parseAndReturnFirstError(_source, _assemble, _allowWarnings);\n\tBOOST_REQUIRE(error);\n\treturn *error;\n}\n\nvoid parsePrintCompare(std::string const& _source, bool _canWarn = false)\n{\n\tYulStack stack(\n\t\tsolidity::test::CommonOptions::get().evmVersion(),\n\t\tsolidity::test::CommonOptions::get().eofVersion(),\n\t\tOptimiserSettings::none(),\n\t\tDebugInfoSelection::None()\n\t);\n\tBOOST_REQUIRE(stack.parseAndAnalyze(\"\", _source));\n\tif (_canWarn)\n\t\tBOOST_REQUIRE(!Error::containsErrors(stack.errors()));\n\telse\n\t\tBOOST_REQUIRE(!Error::hasErrorsWarningsOrInfos(stack.errors()));\n\tstd::string expectation = \"object \\\"object\\\" {\\n    code \" + boost::replace_all_copy(_source, \"\\n\", \"\\n    \") + \"\\n}\\n\";\n\tBOOST_CHECK_EQUAL(stack.print(), expectation);\n}\n\n}\n\n#define CHECK_ERROR(text, assemble, typ, substring, warnings) \\\ndo \\\n{ \\\n\tError err = expectError((text), (assemble), warnings); \\\n\tBOOST_CHECK(err.type() == (Error::Type::typ)); \\\n\tBOOST_CHECK(searchErrorMessage(err, (substring))); \\\n} while(0)\n\n#define CHECK_PARSE_ERROR(text, type, substring) \\\nCHECK_ERROR(text, false, type, substring, false)\n\n#define CHECK_PARSE_WARNING(text, type, substring) \\\nCHECK_ERROR(text, false, type, substring, false)\n\n#define CHECK_ASSEMBLE_ERROR(text, type, substring) \\\nCHECK_ERROR(text, true, type, substring, false)\n\n#define CHECK_STRICT_ERROR(text, type, substring) \\\nCHECK_ERROR(text, false, type, substring, false)\n\n#define CHECK_STRICT_WARNING(text, type, substring) \\\nCHECK_ERROR(text, false, type, substring, false)\n\n#define SUCCESS_STRICT(text) \\\ndo { successParse((text), false, false); } while (false)\n\n\nBOOST_AUTO_TEST_SUITE(SolidityInlineAssembly)\n\nBOOST_AUTO_TEST_SUITE(Printing) // {{{\n\nBOOST_AUTO_TEST_CASE(print_smoke)\n{\n\tparsePrintCompare(\"{ }\");\n}\n\nBOOST_AUTO_TEST_CASE(print_instructions)\n{\n\tparsePrintCompare(\"{ pop(7) }\");\n}\n\nBOOST_AUTO_TEST_CASE(print_subblock)\n{\n\tparsePrintCompare(\"{ { pop(7) } }\");\n}\n\nBOOST_AUTO_TEST_CASE(print_functional)\n{\n\tparsePrintCompare(\"{ let x := mul(sload(0x12), 7) }\");\n}\n\nBOOST_AUTO_TEST_CASE(print_assignments)\n{\n\tparsePrintCompare(\"{\\n    let x := mul(2, 3)\\n    pop(7)\\n    x := add(1, 2)\\n}\");\n}\n\nBOOST_AUTO_TEST_CASE(print_multi_assignments)\n{\n\tparsePrintCompare(\"{\\n    function f() -> x, y\\n    { }\\n    let x, y := f()\\n}\");\n}\n\nBOOST_AUTO_TEST_CASE(print_string_literals)\n{\n\tparsePrintCompare(\"{ let x := \\\"\\\\n'\\\\xab\\\\x95\\\\\\\"\\\" }\");\n}\n\nBOOST_AUTO_TEST_CASE(print_string_literal_unicode)\n{\n\tstd::string source = \"{ let x := \\\"\\\\u1bac\\\" }\";\n\tstd::string parsed = \"object \\\"object\\\" {\\n    code { let x := \\\"\\\\xe1\\\\xae\\\\xac\\\" }\\n}\\n\";\n\tYulStack stack(\n\t\tsolidity::test::CommonOptions::get().evmVersion(),\n\t\tsolidity::test::CommonOptions::get().eofVersion(),\n\t\tOptimiserSettings::none(),\n\t\tDebugInfoSelection::None()\n\t);\n\tBOOST_REQUIRE(stack.parseAndAnalyze(\"\", source));\n\tBOOST_REQUIRE(!Error::hasErrorsWarningsOrInfos(stack.errors()));\n\tBOOST_CHECK_EQUAL(stack.print(), parsed);\n\n\tstd::string parsedInner = \"{ let x := \\\"\\\\xe1\\\\xae\\\\xac\\\" }\";\n\tparsePrintCompare(parsedInner);\n}\n\nBOOST_AUTO_TEST_CASE(print_if)\n{\n\tparsePrintCompare(\"{ if 2 { pop(mload(0)) } }\");\n}\n\nBOOST_AUTO_TEST_CASE(print_switch)\n{\n\tparsePrintCompare(\"{\\n    switch 42\\n    case 1 { }\\n    case 2 { }\\n    default { }\\n}\");\n}\n\nBOOST_AUTO_TEST_CASE(print_for)\n{\n\tparsePrintCompare(\"{\\n    let ret := 5\\n    for { let i := 1 } lt(i, 15) { i := add(i, 1) }\\n    { ret := mul(ret, i) }\\n}\");\n}\n\nBOOST_AUTO_TEST_CASE(function_definitions_multiple_args)\n{\n\tparsePrintCompare(\"{\\n    function f(a, d)\\n    { mstore(a, d) }\\n    function g(a, d) -> x, y\\n    { }\\n}\");\n}\n\nBOOST_AUTO_TEST_CASE(function_calls)\n{\n\tstd::string source = R\"({\n\tfunction y()\n\t{ }\n\tfunction f(a) -> b\n\t{ }\n\tfunction g(a, b, c)\n\t{ }\n\tg(1, mul(2, address()), f(mul(2, caller())))\n\ty()\n})\";\n\tboost::replace_all(source, \"\\t\", \"    \");\n\tparsePrintCompare(source);\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n// }}}\n\nBOOST_AUTO_TEST_SUITE(Analysis) // {{{\n\nBOOST_AUTO_TEST_CASE(string_literals)\n{\n\tBOOST_CHECK(successAssemble(\"{ let x := \\\"12345678901234567890123456789012\\\" }\"));\n}\n\nBOOST_AUTO_TEST_CASE(oversize_string_literals)\n{\n\tCHECK_ASSEMBLE_ERROR(\"{ let x := \\\"123456789012345678901234567890123\\\" }\", TypeError, \"String literal too long\");\n}\n\nBOOST_AUTO_TEST_CASE(magic_variables)\n{\n\tCHECK_ASSEMBLE_ERROR(\"{ pop(this) }\", DeclarationError, \"Identifier \\\"this\\\" not found\");\n\tCHECK_ASSEMBLE_ERROR(\"{ pop(ecrecover) }\", DeclarationError, \"Identifier \\\"ecrecover\\\" not found\");\n\tBOOST_CHECK(successAssemble(\"{ let ecrecover := 1 pop(ecrecover) }\"));\n}\n\nBOOST_AUTO_TEST_CASE(stack_variables)\n{\n\tBOOST_CHECK(successAssemble(\"{ let y := 3 { let z := 2 { let x := y } } }\"));\n}\n\nBOOST_AUTO_TEST_CASE(designated_invalid_instruction)\n{\n\tBOOST_CHECK(successAssemble(\"{ invalid() }\"));\n}\n\n// TODO: Implement EOF counterpart\nBOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_declaration, *boost::unit_test::precondition(nonEOF()))\n{\n\tCHECK_ASSEMBLE_ERROR(\"{ let gas := 1 }\", ParserError, \"Cannot use builtin\");\n}\n\nBOOST_AUTO_TEST_CASE(revert)\n{\n\tBOOST_CHECK(successAssemble(\"{ revert(0, 0) }\"));\n}\n\nBOOST_AUTO_TEST_CASE(large_constant)\n{\n\tauto source = R\"({\n\t\tswitch mul(1, 2)\n\t\tcase 0x0000000000000000000000000000000000000000000000000000000026121ff0 {\n\t\t}\n\t})\";\n\tBOOST_CHECK(successAssemble(source));\n}\n\nBOOST_AUTO_TEST_CASE(keccak256)\n{\n\tBOOST_CHECK(successAssemble(\"{ pop(keccak256(0, 0)) }\"));\n}\n\nBOOST_AUTO_TEST_CASE(returndatasize)\n{\n\tif (!solidity::test::CommonOptions::get().evmVersion().supportsReturndata())\n\t\treturn;\n\tBOOST_CHECK(successAssemble(\"{ let r := returndatasize() }\"));\n}\n\nBOOST_AUTO_TEST_CASE(returndatacopy)\n{\n\tif (!solidity::test::CommonOptions::get().evmVersion().supportsReturndata())\n\t\treturn;\n\tBOOST_CHECK(successAssemble(\"{ returndatacopy(0, 32, 64) }\"));\n}\n\nBOOST_AUTO_TEST_CASE(staticcall, *boost::unit_test::precondition(nonEOF()))\n{\n\tif (!solidity::test::CommonOptions::get().evmVersion().hasStaticCall())\n\t\treturn;\n\tBOOST_CHECK(successAssemble(\"{ pop(staticcall(10000, 0x123, 64, 0x10, 128, 0x10)) }\"));\n}\n\nBOOST_AUTO_TEST_CASE(create2, *boost::unit_test::precondition(nonEOF()))\n{\n\tif (!solidity::test::CommonOptions::get().evmVersion().hasCreate2())\n\t\treturn;\n\tBOOST_CHECK(successAssemble(\"{ pop(create2(10, 0x123, 32, 64)) }\"));\n}\n\nBOOST_AUTO_TEST_CASE(shift)\n{\n\tif (!solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())\n\t\treturn;\n\tBOOST_CHECK(successAssemble(\"{ pop(shl(10, 32)) }\"));\n\tBOOST_CHECK(successAssemble(\"{ pop(shr(10, 32)) }\"));\n\tBOOST_CHECK(successAssemble(\"{ pop(sar(10, 32)) }\"));\n}\n\nBOOST_AUTO_TEST_CASE(shift_constantinople_warning)\n{\n\tif (solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())\n\t\treturn;\n\tCHECK_PARSE_WARNING(\"{ shl(10, 32) }\", TypeError, \"The \\\"shl\\\" instruction is only available for Constantinople-compatible VMs\");\n\tCHECK_PARSE_WARNING(\"{ shr(10, 32) }\", TypeError, \"The \\\"shr\\\" instruction is only available for Constantinople-compatible VMs\");\n\tCHECK_PARSE_WARNING(\"{ sar(10, 32) }\", TypeError, \"The \\\"sar\\\" instruction is only available for Constantinople-compatible VMs\");\n}\n\nBOOST_AUTO_TEST_SUITE_END() // }}}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/LibSolc.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @date 2017\n * Unit tests for libsolc/libsolc.cpp.\n */\n\n#include <string>\n#include <boost/test/unit_test.hpp>\n#include <libsolutil/JSON.h>\n#include <libsolidity/interface/ReadFile.h>\n#include <libsolidity/interface/Version.h>\n#include <libsolc/libsolc.h>\n\n\nnamespace solidity::frontend::test\n{\n\nnamespace\n{\n\n/// TODO: share this between StandardCompiler.cpp\n/// Helper to match a specific error type and message\nbool containsError(Json const& _compilerResult, std::string const& _type, std::string const& _message)\n{\n\tif (!_compilerResult.contains(\"errors\"))\n\t\treturn false;\n\n\tfor (auto const& error: _compilerResult[\"errors\"])\n\t{\n\t\tBOOST_REQUIRE(error.is_object());\n\t\tBOOST_REQUIRE(error[\"type\"].is_string());\n\t\tBOOST_REQUIRE(error[\"message\"].is_string());\n\t\tif ((error[\"type\"].get<std::string>() == _type) && (error[\"message\"].get<std::string>() == _message))\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nJson compile(std::string const& _input, CStyleReadFileCallback _callback = nullptr)\n{\n\tchar* output_ptr = solidity_compile(_input.c_str(), _callback, nullptr);\n\tstd::string output(output_ptr);\n\tsolidity_free(output_ptr);\n\tsolidity_reset();\n\tJson ret;\n\tBOOST_REQUIRE(util::jsonParseStrict(output, ret));\n\treturn ret;\n}\n\nchar* stringToSolidity(std::string const& _input)\n{\n\tchar* ptr = solidity_alloc(_input.length());\n\tBOOST_REQUIRE(ptr != nullptr);\n\tstd::memcpy(ptr, _input.c_str(), _input.length());\n\treturn ptr;\n}\n\n} // end anonymous namespace\n\nBOOST_AUTO_TEST_SUITE(LibSolc)\n\nBOOST_AUTO_TEST_CASE(read_version)\n{\n\tstd::string output(solidity_version());\n\tBOOST_CHECK(output.find(VersionString) == 0);\n}\n\nBOOST_AUTO_TEST_CASE(read_license)\n{\n\tstd::string output(solidity_license());\n\tBOOST_CHECK(output.find(\"GNU GENERAL PUBLIC LICENSE\") != std::string::npos);\n}\n\nBOOST_AUTO_TEST_CASE(standard_compilation)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_REQUIRE(result.is_object());\n\n\t// Only tests some assumptions. The StandardCompiler is tested properly in another suite.\n\tBOOST_CHECK(result.contains(\"sources\"));\n\t// This used to test that it is a member, but we did not actually request any output,\n\t// so there should not be a contract member.\n\tBOOST_CHECK(!result.contains(\"contracts\"));\n}\n\nBOOST_AUTO_TEST_CASE(missing_callback)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"import \\\"missing.sol\\\"; contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_REQUIRE(result.is_object());\n\n\tBOOST_CHECK(containsError(result, \"ParserError\", \"Source \\\"missing.sol\\\" not found: File not supplied initially.\"));\n}\n\nBOOST_AUTO_TEST_CASE(with_callback)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"import \\\"found.sol\\\"; import \\\"notfound.sol\\\"; contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\n\tCStyleReadFileCallback callback{\n\t\t[](void* _context, char const* _kind, char const* _path, char** o_contents, char** o_error)\n\t\t{\n\t\t\t// Passed in a nullptr in the compile() helper above.\n\t\t\tBOOST_REQUIRE(_context == nullptr);\n\t\t\t// Caller frees the pointers.\n\t\t\tBOOST_REQUIRE(std::string(_kind) == ReadCallback::kindString(ReadCallback::Kind::ReadFile));\n\t\t\tif (std::string(_path) == \"found.sol\")\n\t\t\t{\n\t\t\t\tstatic std::string content{\"import \\\"missing.sol\\\"; contract B {}\"};\n\t\t\t\t*o_contents = stringToSolidity(content);\n\t\t\t\t*o_error = nullptr;\n\t\t\t}\n\t\t\telse if (std::string(_path) == \"missing.sol\")\n\t\t\t{\n\t\t\t\tstatic std::string errorMsg{\"Missing file.\"};\n\t\t\t\t*o_error = stringToSolidity(errorMsg);\n\t\t\t\t*o_contents = nullptr;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t*o_error = nullptr;\n\t\t\t\t*o_contents = nullptr;\n\t\t\t}\n\t\t}\n\t};\n\n\tJson result = compile(input, callback);\n\tBOOST_REQUIRE(result.is_object());\n\n\t// This ensures that \"found.sol\" was properly loaded which triggered the second import statement.\n\tBOOST_CHECK(containsError(result, \"ParserError\", \"Source \\\"missing.sol\\\" not found: Missing file.\"));\n\n\t// This should be placed due to the missing \"notfound.sol\" which sets both pointers to null.\n\tBOOST_CHECK(containsError(result, \"ParserError\", \"Source \\\"notfound.sol\\\" not found: Callback not supported.\"));\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/MemoryGuardTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/libsolidity/MemoryGuardTest.h>\n\n#include <test/Common.h>\n#include <test/libyul/Common.h>\n\n#include <libsolidity/codegen/ir/Common.h>\n\n#include <libsolutil/Algorithms.h>\n#include <libsolutil/StringUtils.h>\n\n#include <libyul/Object.h>\n#include <libyul/optimiser/FunctionCallFinder.h>\n#include <libyul/AST.h>\n#include <libyul/YulStack.h>\n\n#include <fstream>\n#include <memory>\n#include <stdexcept>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::util::formatting;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\nusing namespace solidity::test;\nusing namespace solidity::yul::test;\nusing namespace yul;\n\nvoid MemoryGuardTest::setupCompiler(CompilerStack& _compiler)\n{\n\tAnalysisFramework::setupCompiler(_compiler);\n\n\t_compiler.setViaIR(true);\n\t_compiler.setOptimiserSettings(OptimiserSettings::none());\n}\n\nTestCase::TestResult MemoryGuardTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted)\n{\n\tif (!runFramework(m_source, PipelineStage::Compilation))\n\t{\n\t\tprintPrefixed(_stream, formatErrors(filteredErrors(), _formatted), _linePrefix);\n\t\treturn TestResult::FatalError;\n\t}\n\n\tm_obtainedResult.clear();\n\tfor (std::string contractName: compiler().contractNames())\n\t{\n\t\tErrorList errors;\n\t\tstd::optional<std::string> const& ir = compiler().yulIR(contractName);\n\t\tsoltestAssert(ir);\n\n\t\tYulStack yulStack = parseYul(*ir);\n\t\tif (yulStack.hasErrors())\n\t\t{\n\t\t\tprintYulErrors(yulStack, _stream, _linePrefix, _formatted);\n\t\t\treturn TestResult::FatalError;\n\t\t}\n\n\t\tauto handleObject = [&](std::string const& _kind, Object const& _object) {\n\t\t\tauto const memoryGuardHandle = yulStack.dialect().findBuiltin(\"memoryguard\");\n\t\t\tm_obtainedResult += contractName + \"(\" + _kind + \") \";\n\t\t\tif (memoryGuardHandle && !findFunctionCalls(\n\t\t\t\t_object.code()->root(),\n\t\t\t\t*memoryGuardHandle\n\t\t\t).empty())\n\t\t\t\tm_obtainedResult += \"true\\n\";\n\t\t\telse\n\t\t\t\tm_obtainedResult += \"false\\n\";\n\t\t};\n\t\thandleObject(\"creation\", *yulStack.parserResult());\n\t\tsize_t deployedIndex = yulStack.parserResult()->subIndexByName.at(\n\t\t\tIRNames::deployedObject(compiler().contractDefinition(contractName))\n\t\t);\n\t\thandleObject(\"runtime\", dynamic_cast<Object const&>(*yulStack.parserResult()->subObjects[deployedIndex]));\n\t}\n\treturn checkResult(_stream, _linePrefix, _formatted);\n}\n"
  },
  {
    "path": "test/libsolidity/MemoryGuardTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <test/libsolidity/AnalysisFramework.h>\n#include <test/TestCase.h>\n#include <test/CommonSyntaxTest.h>\n#include <liblangutil/Exceptions.h>\n#include <libsolutil/AnsiColorized.h>\n\n#include <iosfwd>\n#include <string>\n#include <vector>\n#include <utility>\n\nnamespace solidity::frontend::test\n{\n\nusing solidity::test::SyntaxTestError;\n\nclass MemoryGuardTest: public AnalysisFramework, public EVMVersionRestrictedTestCase\n{\npublic:\n\tstatic std::unique_ptr<TestCase> create(Config const& _config)\n\t{\n\t\treturn std::make_unique<MemoryGuardTest>(_config.filename);\n\t}\n\tMemoryGuardTest(std::string const& _filename): EVMVersionRestrictedTestCase(_filename)\n\t{\n\t\tm_source = m_reader.source();\n\t\tm_expectation = m_reader.simpleExpectations();\n\t}\n\n\tTestResult run(std::ostream& _stream, std::string const& _linePrefix = \"\", bool _formatted = false) override;\n\nprotected:\n\tvoid setupCompiler(CompilerStack& _compiler) override;\n};\n\n}\n"
  },
  {
    "path": "test/libsolidity/Metadata.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n */\n/**\n * @date 2017\n * Unit tests for the metadata output.\n */\n\n#include <test/Metadata.h>\n#include <test/Common.h>\n#include <libsolidity/interface/CompilerStack.h>\n#include <libsolidity/interface/Version.h>\n#include <libsolutil/SwarmHash.h>\n#include <libsolutil/IpfsHash.h>\n#include <libsolutil/JSON.h>\n\n#include <boost/test/unit_test.hpp>\n\n\nnamespace solidity::frontend::test\n{\n\nnamespace\n{\n\nstd::map<std::string, std::string> requireParsedCBORMetadata(bytes const& _bytecode, CompilerStack::MetadataFormat _metadataFormat)\n{\n\tbytes cborMetadata = solidity::test::onlyMetadata(_bytecode);\n\tif (_metadataFormat != CompilerStack::MetadataFormat::NoMetadata)\n\t{\n\t\tBOOST_REQUIRE(!cborMetadata.empty());\n\t\tstd::optional<std::map<std::string, std::string>> tmp = solidity::test::parseCBORMetadata(cborMetadata);\n\t\tBOOST_REQUIRE(tmp);\n\t\treturn *tmp;\n\t}\n\tBOOST_REQUIRE(cborMetadata.empty());\n\treturn {};\n}\n\nstd::optional<std::string> compileAndCheckLicenseMetadata(std::string const& _contractName, char const* _sourceCode)\n{\n\tCompilerStack compilerStack;\n\tcompilerStack.setSources({{\"A.sol\", _sourceCode}});\n\tBOOST_REQUIRE_MESSAGE(compilerStack.compile(), \"Compiling contract failed\");\n\n\tstd::string const& serialisedMetadata = compilerStack.metadata(_contractName);\n\tJson metadata;\n\tBOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata));\n\tBOOST_CHECK(solidity::test::isValidMetadata(metadata));\n\n\tBOOST_CHECK_EQUAL(metadata[\"sources\"].size(), 1);\n\tBOOST_REQUIRE(metadata[\"sources\"].contains(\"A.sol\"));\n\n\tif (metadata[\"sources\"][\"A.sol\"].contains(\"license\"))\n\t{\n\t\tBOOST_REQUIRE(metadata[\"sources\"][\"A.sol\"][\"license\"].is_string());\n\t\treturn metadata[\"sources\"][\"A.sol\"][\"license\"].get<std::string>();\n\t}\n\telse\n\t\treturn std::nullopt;\n}\n\n}\n\nBOOST_AUTO_TEST_SUITE(Metadata)\n\nBOOST_AUTO_TEST_CASE(metadata_stamp)\n{\n\t// Check that the metadata stamp is at the end of the runtime bytecode.\n\tchar const* sourceCode = R\"(\n\t\tpragma solidity >=0.0;\n\t\tpragma experimental __testOnlyAnalysis;\n\t\tcontract test {\n\t\t\tfunction g(function(uint) external returns (uint) x) public {}\n\t\t}\n\t)\";\n\tfor (auto metadataFormat: std::set<CompilerStack::MetadataFormat>{\n\t\tCompilerStack::MetadataFormat::NoMetadata,\n\t\tCompilerStack::MetadataFormat::WithReleaseVersionTag,\n\t\tCompilerStack::MetadataFormat::WithPrereleaseVersionTag\n\t})\n\t\tfor (auto metadataHash: std::set<CompilerStack::MetadataHash>{\n\t\t\tCompilerStack::MetadataHash::IPFS,\n\t\t\tCompilerStack::MetadataHash::Bzzr1,\n\t\t\tCompilerStack::MetadataHash::None\n\t\t})\n\t\t{\n\t\t\tCompilerStack compilerStack;\n\t\t\tcompilerStack.setMetadataFormat(metadataFormat);\n\t\t\tcompilerStack.setSources({{\"\", sourceCode}});\n\t\t\tcompilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\t\t\tcompilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n\t\t\tcompilerStack.setMetadataHash(metadataHash);\n\t\t\tBOOST_REQUIRE_MESSAGE(compilerStack.compile(), \"Compiling contract failed\");\n\t\t\tbytes const& bytecode = compilerStack.runtimeObject(\"test\").bytecode;\n\t\t\tstd::string const& metadata = compilerStack.metadata(\"test\");\n\t\t\tBOOST_CHECK(solidity::test::isValidMetadata(metadata));\n\n\t\t\tauto const cborMetadata = requireParsedCBORMetadata(bytecode, metadataFormat);\n\t\t\tif (metadataHash == CompilerStack::MetadataHash::None)\n\t\t\t\tBOOST_CHECK(cborMetadata.size() == (metadataFormat == CompilerStack::MetadataFormat::NoMetadata ? 0 : 1));\n\t\t\telse\n\t\t\t{\n\t\t\t\tbytes hash;\n\t\t\t\tstd::string hashMethod;\n\t\t\t\tif (metadataHash == CompilerStack::MetadataHash::IPFS)\n\t\t\t\t{\n\t\t\t\t\thash = util::ipfsHash(metadata);\n\t\t\t\t\tBOOST_REQUIRE(hash.size() == 34);\n\t\t\t\t\thashMethod = \"ipfs\";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\thash = util::bzzr1Hash(metadata).asBytes();\n\t\t\t\t\tBOOST_REQUIRE(hash.size() == 32);\n\t\t\t\t\thashMethod = \"bzzr1\";\n\t\t\t\t}\n\n\t\t\t\tif (metadataFormat != CompilerStack::MetadataFormat::NoMetadata)\n\t\t\t\t{\n\t\t\t\t\tBOOST_CHECK(cborMetadata.size() == 2);\n\t\t\t\t\tBOOST_CHECK(cborMetadata.count(hashMethod) == 1);\n\t\t\t\t\tBOOST_CHECK(cborMetadata.at(hashMethod) == util::toHex(hash));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (metadataFormat == CompilerStack::MetadataFormat::NoMetadata)\n\t\t\t\tBOOST_CHECK(cborMetadata.empty());\n\t\t\telse\n\t\t\t{\n\t\t\t\tBOOST_CHECK(cborMetadata.count(\"solc\") == 1);\n\t\t\t\tif (metadataFormat == CompilerStack::MetadataFormat::WithReleaseVersionTag)\n\t\t\t\t\tBOOST_CHECK(cborMetadata.at(\"solc\") == util::toHex(VersionCompactBytes));\n\t\t\t\telse\n\t\t\t\t\tBOOST_CHECK(cborMetadata.at(\"solc\") == VersionStringStrict);\n\t\t\t\tBOOST_CHECK(!cborMetadata.contains(\"experimental\"));\n\t\t\t}\n\t\t}\n}\n\nBOOST_AUTO_TEST_CASE(metadata_stamp_experimental)\n{\n\t// Check that the metadata stamp is at the end of the runtime bytecode.\n\tchar const* sourceCode = R\"(\n\t\tpragma solidity >=0.0;\n\t\tpragma experimental __test;\n\t\tcontract test {\n\t\t\tfunction g(function(uint) external returns (uint) x) public {}\n\t\t}\n\t)\";\n\tfor (auto metadataFormat: std::set<CompilerStack::MetadataFormat>{\n\t\t\tCompilerStack::MetadataFormat::NoMetadata,\n\t\t\tCompilerStack::MetadataFormat::WithReleaseVersionTag,\n\t\t\tCompilerStack::MetadataFormat::WithPrereleaseVersionTag\n\t})\n\t\tfor (auto metadataHash: std::set<CompilerStack::MetadataHash>{\n\t\t\tCompilerStack::MetadataHash::IPFS,\n\t\t\tCompilerStack::MetadataHash::Bzzr1,\n\t\t\tCompilerStack::MetadataHash::None\n\t\t})\n\t\t{\n\t\t\tCompilerStack compilerStack;\n\t\t\tcompilerStack.setMetadataFormat(metadataFormat);\n\t\t\tcompilerStack.setSources({{\"\", sourceCode}});\n\t\t\tcompilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\t\t\tcompilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n\t\t\tcompilerStack.setMetadataHash(metadataHash);\n\t\t\tcompilerStack.setExperimental(true); // Experimental pragma requires it\n\t\t\tBOOST_REQUIRE_MESSAGE(compilerStack.compile(), \"Compiling contract failed\");\n\t\t\tbytes const& bytecode = compilerStack.runtimeObject(\"test\").bytecode;\n\t\t\tstd::string const& metadata = compilerStack.metadata(\"test\");\n\t\t\tBOOST_CHECK(solidity::test::isValidMetadata(metadata));\n\n\t\t\tauto const cborMetadata = requireParsedCBORMetadata(bytecode, metadataFormat);\n\t\t\tif (metadataHash == CompilerStack::MetadataHash::None)\n\t\t\t\tBOOST_CHECK(cborMetadata.size() == (metadataFormat == CompilerStack::MetadataFormat::NoMetadata ? 0 : 2));\n\t\t\telse\n\t\t\t{\n\t\t\t\tbytes hash;\n\t\t\t\tstd::string hashMethod;\n\t\t\t\tif (metadataHash == CompilerStack::MetadataHash::IPFS)\n\t\t\t\t{\n\t\t\t\t\thash = util::ipfsHash(metadata);\n\t\t\t\t\tBOOST_REQUIRE(hash.size() == 34);\n\t\t\t\t\thashMethod = \"ipfs\";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\thash = util::bzzr1Hash(metadata).asBytes();\n\t\t\t\t\tBOOST_REQUIRE(hash.size() == 32);\n\t\t\t\t\thashMethod = \"bzzr1\";\n\t\t\t\t}\n\n\t\t\t\tif (metadataFormat != CompilerStack::MetadataFormat::NoMetadata)\n\t\t\t\t{\n\t\t\t\t\tBOOST_CHECK(cborMetadata.size() == 3);\n\t\t\t\t\tBOOST_CHECK(cborMetadata.count(hashMethod) == 1);\n\t\t\t\t\tBOOST_CHECK(cborMetadata.at(hashMethod) == util::toHex(hash));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (metadataFormat == CompilerStack::MetadataFormat::NoMetadata)\n\t\t\t\tBOOST_CHECK(cborMetadata.empty());\n\t\t\telse\n\t\t\t{\n\t\t\t\tBOOST_CHECK(cborMetadata.count(\"solc\") == 1);\n\t\t\t\tif (metadataFormat == CompilerStack::MetadataFormat::WithReleaseVersionTag)\n\t\t\t\t\tBOOST_CHECK(cborMetadata.at(\"solc\") == util::toHex(VersionCompactBytes));\n\t\t\t\telse\n\t\t\t\t\tBOOST_CHECK(cborMetadata.at(\"solc\") == VersionStringStrict);\n\t\t\t\tBOOST_CHECK(cborMetadata.contains(\"experimental\"));\n\t\t\t\tBOOST_CHECK(cborMetadata.at(\"experimental\") == \"true\");\n\t\t\t}\n\t\t}\n}\n\nBOOST_AUTO_TEST_CASE(metadata_eof_experimental)\n{\n\t// Check that setting an EOF version results in the experimental flag being set.\n\tchar const* sourceCode = R\"(\n\t\tpragma solidity >=0.0;\n\t\tcontract test {\n\t\t\tfunction g(function(uint) external returns (uint) x) public {}\n\t\t}\n\t)\";\n\tfor (auto metadataFormat: std::set<CompilerStack::MetadataFormat>{\n\t\tCompilerStack::MetadataFormat::NoMetadata,\n\t\tCompilerStack::MetadataFormat::WithReleaseVersionTag,\n\t\tCompilerStack::MetadataFormat::WithPrereleaseVersionTag\n\t})\n\t{\n\t\tCompilerStack compilerStack;\n\t\tcompilerStack.setMetadataFormat(metadataFormat);\n\t\tcompilerStack.setSources({{\"\", sourceCode}});\n\t\tcompilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\t\tcompilerStack.setViaIR(true);\n\t\tcompilerStack.setEOFVersion(solidity::test::CommonOptions::get().eofVersion());\n\t\tcompilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n\t\tBOOST_REQUIRE_MESSAGE(compilerStack.compile(), \"Compiling contract failed\");\n\t\tbytes const& bytecode = compilerStack.runtimeObject(\"test\").bytecode;\n\t\tstd::string const& metadata = compilerStack.metadata(\"test\");\n\t\tBOOST_CHECK(solidity::test::isValidMetadata(metadata));\n\n\t\tauto const cborMetadata = requireParsedCBORMetadata(bytecode, metadataFormat);\n\n\t\tif (\n\t\t\tmetadataFormat == CompilerStack::MetadataFormat::NoMetadata ||\n\t\t\t!solidity::test::CommonOptions::get().eofVersion().has_value()\n\t\t)\n\t\t\tBOOST_CHECK(cborMetadata.count(\"experimental\") == 0);\n\t\telse\n\t\t{\n\t\t\tBOOST_CHECK(cborMetadata.count(\"experimental\") == 1);\n\t\t\tBOOST_CHECK(cborMetadata.at(\"experimental\") == \"true\");\n\t\t}\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(metadata_relevant_sources)\n{\n\tCompilerStack compilerStack;\n\tchar const* sourceCodeA = R\"(\n\t\tpragma solidity >=0.0;\n\t\tcontract A {\n\t\t\tfunction g(function(uint) external returns (uint) x) public {}\n\t\t}\n\t)\";\n\tchar const* sourceCodeB = R\"(\n\t\tpragma solidity >=0.0;\n\t\tcontract B {\n\t\t\tfunction g(function(uint) external returns (uint) x) public {}\n\t\t}\n\t)\";\n\tcompilerStack.setSources({\n\t\t{\"A\", sourceCodeA},\n\t\t{\"B\", sourceCodeB},\n\t});\n\tcompilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\tcompilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n\tBOOST_REQUIRE_MESSAGE(compilerStack.compile(), \"Compiling contract failed\");\n\n\tstd::string const& serialisedMetadata = compilerStack.metadata(\"A\");\n\tJson metadata;\n\tBOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata));\n\tBOOST_CHECK(solidity::test::isValidMetadata(metadata));\n\n\tBOOST_CHECK_EQUAL(metadata[\"sources\"].size(), 1);\n\tBOOST_CHECK(metadata[\"sources\"].contains(\"A\"));\n}\n\nBOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports)\n{\n\tCompilerStack compilerStack;\n\tchar const* sourceCodeA = R\"(\n\t\tpragma solidity >=0.0;\n\t\tcontract A {\n\t\t\tfunction g(function(uint) external returns (uint) x) public virtual {}\n\t\t}\n\t)\";\n\tchar const* sourceCodeB = R\"(\n\t\tpragma solidity >=0.0;\n\t\timport \"./A\";\n\t\tcontract B is A {\n\t\t\tfunction g(function(uint) external returns (uint) x) public virtual override {}\n\t\t}\n\t)\";\n\tchar const* sourceCodeC = R\"(\n\t\tpragma solidity >=0.0;\n\t\timport \"./B\";\n\t\tcontract C is B {\n\t\t\tfunction g(function(uint) external returns (uint) x) public override {}\n\t\t}\n\t)\";\n\tcompilerStack.setSources({\n\t\t{\"A\", sourceCodeA},\n\t\t{\"B\", sourceCodeB},\n\t\t{\"C\", sourceCodeC}\n\t});\n\tcompilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\tcompilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n\tBOOST_REQUIRE_MESSAGE(compilerStack.compile(), \"Compiling contract failed\");\n\n\tstd::string const& serialisedMetadata = compilerStack.metadata(\"C\");\n\tJson metadata;\n\tBOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata));\n\tBOOST_CHECK(solidity::test::isValidMetadata(metadata));\n\n\tBOOST_CHECK_EQUAL(metadata[\"sources\"].size(), 3);\n\tBOOST_CHECK(metadata[\"sources\"].contains(\"A\"));\n\tBOOST_CHECK(metadata[\"sources\"].contains(\"B\"));\n\tBOOST_CHECK(metadata[\"sources\"].contains(\"C\"));\n}\n\nBOOST_AUTO_TEST_CASE(metadata_useLiteralContent)\n{\n\t// Check that the metadata contains \"useLiteralContent\"\n\tchar const* sourceCode = R\"(\n\t\tpragma solidity >=0.0;\n\t\tcontract test {\n\t\t}\n\t)\";\n\n\tauto check = [](char const* _src, bool _literal)\n\t{\n\t\tCompilerStack compilerStack;\n\t\tcompilerStack.setSources({{\"\", _src}});\n\t\tcompilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\t\tcompilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n\t\tcompilerStack.useMetadataLiteralSources(_literal);\n\t\tBOOST_REQUIRE_MESSAGE(compilerStack.compile(), \"Compiling contract failed\");\n\t\tstd::string metadata_str = compilerStack.metadata(\"test\");\n\t\tJson metadata;\n\t\tBOOST_REQUIRE(util::jsonParseStrict(metadata_str, metadata));\n\t\tBOOST_CHECK(solidity::test::isValidMetadata(metadata));\n\t\tBOOST_CHECK(metadata.contains(\"settings\"));\n\t\tBOOST_CHECK(metadata[\"settings\"].contains(\"metadata\"));\n\t\tBOOST_CHECK(metadata[\"settings\"][\"metadata\"].contains(\"bytecodeHash\"));\n\t\tif (_literal)\n\t\t{\n\t\t\tBOOST_CHECK(metadata[\"settings\"][\"metadata\"].contains(\"useLiteralContent\"));\n\t\t\tBOOST_CHECK(metadata[\"settings\"][\"metadata\"][\"useLiteralContent\"].get<bool>());\n\t\t}\n\t};\n\n\tcheck(sourceCode, true);\n\tcheck(sourceCode, false);\n}\n\nBOOST_AUTO_TEST_CASE(metadata_viair)\n{\n\tchar const* sourceCode = R\"(\n\t\tpragma solidity >=0.0;\n\t\tcontract test {\n\t\t}\n\t)\";\n\n\tauto check = [](char const* _src, bool _viaIR)\n\t{\n\t\tCompilerStack compilerStack;\n\t\tcompilerStack.setSources({{\"\", _src}});\n\t\tcompilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\t\tcompilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n\t\tcompilerStack.setViaIR(_viaIR);\n\t\tBOOST_REQUIRE_MESSAGE(compilerStack.compile(), \"Compiling contract failed\");\n\n\t\tJson metadata;\n\t\tBOOST_REQUIRE(util::jsonParseStrict(compilerStack.metadata(\"test\"), metadata));\n\t\tBOOST_CHECK(solidity::test::isValidMetadata(metadata));\n\t\tBOOST_CHECK(metadata.contains(\"settings\"));\n\t\tif (_viaIR)\n\t\t{\n\t\t\tBOOST_CHECK(metadata[\"settings\"].contains(\"viaIR\"));\n\t\t\tBOOST_CHECK(metadata[\"settings\"][\"viaIR\"].get<bool>());\n\t\t}\n\t\telse\n\t\t\tBOOST_CHECK(!metadata[\"settings\"].contains(\"viaIR\"));\n\n\t\tBOOST_CHECK(compilerStack.cborMetadata(\"test\") == compilerStack.cborMetadata(\"test\", _viaIR));\n\t\tBOOST_CHECK(compilerStack.cborMetadata(\"test\") != compilerStack.cborMetadata(\"test\", !_viaIR));\n\n\t\tstd::map<std::string, std::string> const parsedCBORMetadata = requireParsedCBORMetadata(\n\t\t\tcompilerStack.runtimeObject(\"test\").bytecode,\n\t\t\tCompilerStack::MetadataFormat::WithReleaseVersionTag\n\t\t);\n\n\t\tBOOST_CHECK(parsedCBORMetadata.count(\"experimental\") == 0);\n\t};\n\n\tcheck(sourceCode, true);\n\tcheck(sourceCode, false);\n}\n\nBOOST_AUTO_TEST_CASE(metadata_viassacfg)\n{\n\tstatic auto constexpr sourceCode = R\"(\n\t\tpragma solidity >=0.0;\n\t\tcontract test {\n\t\t}\n\t)\";\n\n\tauto check = [](char const* _src, bool _viaSSACFG)\n\t{\n\t\tCompilerStack compilerStack;\n\t\tcompilerStack.setSources({{\"\", _src}});\n\t\tcompilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\t\tcompilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);\n\t\tcompilerStack.setViaIR(true);\n\t\tcompilerStack.setExperimental(true);\n\t\tcompilerStack.setViaSSACFG(_viaSSACFG);\n\t\tBOOST_REQUIRE_MESSAGE(compilerStack.compile(), \"Compiling contract failed\");\n\n\t\tJson metadata;\n\t\tBOOST_REQUIRE(util::jsonParseStrict(compilerStack.metadata(\"test\"), metadata));\n\t\tBOOST_CHECK(solidity::test::isValidMetadata(metadata));\n\t\tBOOST_CHECK(metadata.contains(\"settings\"));\n\t\tBOOST_CHECK(metadata[\"settings\"].contains(\"viaIR\"));\n\t\tBOOST_CHECK(metadata[\"settings\"][\"viaIR\"].get<bool>());\n\t\tif (_viaSSACFG)\n\t\t{\n\t\t\tBOOST_CHECK(metadata[\"settings\"].contains(\"viaSSACFG\"));\n\t\t\tBOOST_CHECK(metadata[\"settings\"][\"viaSSACFG\"].get<bool>());\n\t\t}\n\t\telse\n\t\t\tBOOST_CHECK(!metadata[\"settings\"].contains(\"viaSSACFG\"));\n\n\t\tstd::map<std::string, std::string> const parsedCBORMetadata = requireParsedCBORMetadata(\n\t\t\tcompilerStack.runtimeObject(\"test\").bytecode,\n\t\t\tCompilerStack::MetadataFormat::WithReleaseVersionTag\n\t\t);\n\n\t\tBOOST_CHECK(parsedCBORMetadata.contains(\"experimental\"));\n\t};\n\n\tcheck(sourceCode, true);\n\tcheck(sourceCode, false);\n}\n\nBOOST_AUTO_TEST_CASE(metadata_revert_strings)\n{\n\tCompilerStack compilerStack;\n\tchar const* sourceCodeA = R\"(\n\t\tpragma solidity >=0.0;\n\t\tcontract A {\n\t\t}\n\t)\";\n\tcompilerStack.setSources({{\"A\", sourceCodeA}});\n\tcompilerStack.setRevertStringBehaviour(RevertStrings::Strip);\n\tBOOST_REQUIRE_MESSAGE(compilerStack.compile(), \"Compiling contract failed\");\n\n\tstd::string const& serialisedMetadata = compilerStack.metadata(\"A\");\n\tJson metadata;\n\tBOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata));\n\tBOOST_CHECK(solidity::test::isValidMetadata(metadata));\n\n\tBOOST_CHECK_EQUAL(metadata[\"settings\"][\"debug\"][\"revertStrings\"], \"strip\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_optimiser_sequence)\n{\n\tstd::string const sourceCode = R\"(\n\t\tpragma solidity >=0.0;\n\t\tcontract C {\n\t\t}\n\t)\";\n\n\tstd::vector<std::tuple<std::string, std::string>> sequences =\n\t{\n\t\t// {\"<optimizer sequence>\", \"<optimizer cleanup sequence>\"}\n\t\t{\"\", \"\"},\n\t\t{\"\", \"fDn\"},\n\t\t{\"dhfoDgvulfnTUtnIf\", \"\" },\n\t\t{\"dhfoDgvulfnTUtnIf\", \"fDn\"},\n\t\t// test that a custom cleanup step sequence does not lead to default standard optimiser settings in metadata\n\t\t{OptimiserSettings::DefaultYulOptimiserSteps, \"D\"},\n\t\t// test that a custom optimizer sequence does not lead to default standard optimiser settings in metadata\n\t\t{\"dhfoDgvulfnTUtnIf\", OptimiserSettings::DefaultYulOptimiserCleanupSteps}\n\t};\n\n\tstd::vector<OptimiserSettings> settingsToTest;\n\tfor (auto const& [optimizerSequence, optimizerCleanupSequence]: sequences)\n\t{\n\t\tfor (auto const& preset: {\n\t\t\tOptimiserSettings::none(),\n\t\t\tOptimiserSettings::minimal(),\n\t\t\tOptimiserSettings::standard(),\n\t\t\tOptimiserSettings::full(),\n\t\t})\n\t\t{\n\t\t\tsettingsToTest.emplace_back(preset);\n\t\t\tsettingsToTest.back().runYulOptimiser = true;\n\t\t\tsettingsToTest.back().yulOptimiserSteps = optimizerSequence;\n\t\t\tsettingsToTest.back().yulOptimiserCleanupSteps = optimizerCleanupSequence;\n\t\t}\n\t}\n\n\tauto generateMetadataJson = [](std::string const& _source, OptimiserSettings const& _optimizerSettings) -> Json\n\t{\n\t\tCompilerStack compilerStack;\n\t\tcompilerStack.setSources({{\"\", _source}});\n\t\tcompilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());\n\t\tcompilerStack.setOptimiserSettings(_optimizerSettings);\n\n\t\tBOOST_REQUIRE_MESSAGE(compilerStack.compile(), \"Compiling contract failed\");\n\n\t\tstd::string const& serialisedMetadata = compilerStack.metadata(\"C\");\n\t\tJson metadata;\n\t\tBOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata));\n\t\tBOOST_CHECK(solidity::test::isValidMetadata(metadata));\n\t\treturn metadata;\n\t};\n\n\tauto checkCustomSettings = [generateMetadataJson, sourceCode](OptimiserSettings const& _optimizerSettings)\n\t{\n\t\tauto const metadataJson = generateMetadataJson(sourceCode, _optimizerSettings);\n\t\tBOOST_CHECK(metadataJson[\"settings\"][\"optimizer\"].contains(\"details\"));\n\t\tBOOST_CHECK(metadataJson[\"settings\"][\"optimizer\"][\"details\"].contains(\"yulDetails\"));\n\t\tBOOST_CHECK(metadataJson[\"settings\"][\"optimizer\"][\"details\"][\"yulDetails\"].contains(\"optimizerSteps\"));\n\n\t\tstd::string const metadataOptimizerSteps = metadataJson[\"settings\"][\"optimizer\"][\"details\"][\"yulDetails\"][\"optimizerSteps\"].get<std::string>();\n\t\tstd::string const expectedMetadataOptimiserSteps = _optimizerSettings.yulOptimiserSteps + \":\" + _optimizerSettings.yulOptimiserCleanupSteps;\n\t\tBOOST_CHECK_EQUAL(metadataOptimizerSteps, expectedMetadataOptimiserSteps);\n\t};\n\n\tfor (auto const& optimizerSettings: settingsToTest)\n\t\tcheckCustomSettings(optimizerSettings);\n\n\tfor (auto const& preset: {OptimiserSettings::minimal(), OptimiserSettings::standard(), OptimiserSettings::full()})\n\t{\n\t\tauto const metadataJson = generateMetadataJson(sourceCode, preset);\n\t\tJson expectedOptimizerMetadata = {\n\t\t\t{\"enabled\", preset != OptimiserSettings::minimal()},\n\t\t\t{\"runs\", preset.expectedExecutionsPerDeployment}\n\t\t};\n\t\tBOOST_CHECK(metadataJson[\"settings\"][\"optimizer\"] == expectedOptimizerMetadata);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_missing)\n{\n\tchar const* sourceCode = R\"(\n\t\tpragma solidity >=0.0;\n\t\tcontract C {\n\t\t}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == std::nullopt);\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_gpl3)\n{\n\t// Can't use a raw string here due to the stylechecker.\n\tchar const* sourceCode =\n\t\t\"// NOTE: we also add trailing whitespace after the license, to see it is trimmed.\\n\"\n\t\t\"// SPDX-License-Identifier: GPL-3.0    \\n\"\n\t\t\"pragma solidity >=0.0;\\n\"\n\t\t\"contract C {\\n\"\n\t\t\"}\\n\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_whitespace_before_spdx)\n{\n\tchar const* sourceCode = R\"(\n\t\t//     SPDX-License-Identifier: GPL-3.0\n\t\tcontract C {}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_whitespace_after_colon)\n{\n\tchar const* sourceCode = R\"(\n\t\t// SPDX-License-Identifier:    GPL-3.0\n\t\tcontract C {}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_gpl3_or_apache2)\n{\n\tchar const* sourceCode = R\"(\n\t\t// SPDX-License-Identifier: GPL-3.0 OR Apache-2.0\n\t\tpragma solidity >=0.0;\n\t\tcontract C {\n\t\t}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0 OR Apache-2.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_bidi_marks)\n{\n\tchar const* sourceCode =\n\t\t\"// \\xE2\\x80\\xAE\"\"0.3-LPG :reifitnedI-esneciL-XDPS\\xE2\\x80\\xAC\\n\"\n\t\t\"// NOTE: The text above is reversed using Unicode directional marks. In raw form it would look like this:\\n\"\n\t\t\"// <LRO>0.3-LPG :reifitnedI-esneciL-XDPS<PDF>\\n\"\n\t\t\"contract C {}\\n\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == std::nullopt);\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_bottom)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {}\n\t\t// SPDX-License-Identifier: GPL-3.0\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_cr_endings)\n{\n\tchar const* sourceCode =\n\t\t\"// SPDX-License-Identifier: GPL-3.0\\r\"\n\t\t\"contract C {}\\r\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_crlf_endings)\n{\n\tchar const* sourceCode =\n\t\t\"// SPDX-License-Identifier: GPL-3.0\\r\\n\"\n\t\t\"contract C {}\\r\\n\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_in_string)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tbytes license = \"// SPDX-License-Identifier: GPL-3.0\";\n\t\t}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == std::nullopt);\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_in_contract)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t// SPDX-License-Identifier: GPL-3.0\n\t\t}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == std::nullopt);\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_missing_colon)\n{\n\tchar const* sourceCode = R\"(\n\t\t// SPDX-License-Identifier GPL-3.0\n\t\tcontract C {}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == std::nullopt);\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_multiline)\n{\n\tchar const* sourceCode = R\"(\n\t\t/* SPDX-License-Identifier: GPL-3.0 */\n\t\tcontract C {}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_natspec)\n{\n\tchar const* sourceCode = R\"(\n\t\t/// SPDX-License-Identifier: GPL-3.0\n\t\tcontract C {}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_natspec_multiline)\n{\n\tchar const* sourceCode = R\"(\n\t\t/** SPDX-License-Identifier: GPL-3.0 */\n\t\tcontract C {}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_no_whitespace_multiline)\n{\n\tchar const* sourceCode = R\"(\n\t\t/*SPDX-License-Identifier:GPL-3.0*/\n\t\tcontract C {}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_nonempty_line)\n{\n\tchar const* sourceCode = R\"(\n\t\tpragma solidity >= 0.0; // SPDX-License-Identifier: GPL-3.0\n\t\tcontract C {}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_CASE(metadata_license_no_whitespace)\n{\n\tchar const* sourceCode = R\"(\n\t\t//SPDX-License-Identifier:GPL-3.0\n\t\tcontract C {}\n\t)\";\n\tBOOST_CHECK(compileAndCheckLicenseMetadata(\"C\", sourceCode) == \"GPL-3.0\");\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n}\n"
  },
  {
    "path": "test/libsolidity/NatspecJSONTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n */\n/**\n * Unit tests for the solidity compiler ABI JSON Interface output.\n */\n\n#include <test/libsolidity/NatspecJSONTest.h>\n\n#include <libsolutil/CommonIO.h>\n#include <libsolutil/StringUtils.h>\n\n#include <boost/algorithm/string/predicate.hpp>\n\n#include <fmt/format.h>\n\n#include <vector>\n\nusing namespace solidity::frontend::test;\nusing namespace solidity::util;\nusing namespace std::string_literals;\n\nstd::ostream& solidity::frontend::test::operator<<(std::ostream& _output, NatspecJSONKind _kind)\n{\n\tswitch (_kind) {\n\tcase NatspecJSONKind::Devdoc: _output << \"devdoc\"; break;\n\tcase NatspecJSONKind::Userdoc: _output << \"userdoc\"; break;\n\t}\n\treturn _output;\n}\n\nstd::unique_ptr<TestCase> NatspecJSONTest::create(Config const& _config)\n{\n\treturn std::make_unique<NatspecJSONTest>(_config.filename, _config.evmVersion);\n}\n\nvoid NatspecJSONTest::parseCustomExpectations(std::istream& _stream)\n{\n\tsoltestAssert(m_expectedNatspecJSON.empty());\n\n\t// We expect a series of expectations in the following format:\n\t//\n\t//     // <qualified contract name> <devdoc|userdoc>\n\t//     // <json>\n\n\tstd::string line;\n\twhile (getline(_stream, line))\n\t{\n\t\tstd::string_view strippedLine = expectLinePrefix(line);\n\t\tif (strippedLine.empty())\n\t\t\tcontinue;\n\n\t\tauto [contractName, kind] = parseExpectationHeader(strippedLine);\n\n\t\tstd::string rawJSON = extractExpectationJSON(_stream);\n\t\tstd::string jsonErrors;\n\t\tJson parsedJSON;\n\t\tbool jsonParsingSuccessful = jsonParseStrict(rawJSON, parsedJSON, &jsonErrors);\n\t\tif (!jsonParsingSuccessful)\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(fmt::format(\n\t\t\t\t\"Malformed JSON in {} expectation for contract {}.\\n\"\n\t\t\t\t\"Note that JSON expectations must be pretty-printed to be split correctly. \"\n\t\t\t\t\"The object is assumed to and at the first unindented closing brace.\\n\"\n\t\t\t\t\"{}\",\n\t\t\t\ttoString(kind),\n\t\t\t\tcontractName,\n\t\t\t\trawJSON\n\t\t\t)));\n\n\t\tm_expectedNatspecJSON[std::string(contractName)][kind] = parsedJSON;\n\t}\n}\n\nbool NatspecJSONTest::expectationsMatch()\n{\n\t// NOTE: Comparing pretty printed Jsons to avoid using its operator==, which fails to\n\t// compare equal numbers as equal. For example, for 'version' field the value is sometimes int,\n\t// sometimes uint and they compare as different even when both are 1.\n\treturn\n\t\tSyntaxTest::expectationsMatch() &&\n\t\tprettyPrinted(obtainedNatspec()) == prettyPrinted(m_expectedNatspecJSON);\n}\n\nvoid NatspecJSONTest::printExpectedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const\n{\n\tSyntaxTest::printExpectedResult(_stream, _linePrefix, _formatted);\n\tif (!m_expectedNatspecJSON.empty())\n\t{\n\t\t_stream << _linePrefix << \"----\" << std::endl;\n\t\tprintPrefixed(_stream, formatNatspecExpectations(m_expectedNatspecJSON), _linePrefix);\n\t}\n\n}\n\nvoid NatspecJSONTest::printObtainedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const\n{\n\tSyntaxTest::printObtainedResult(_stream, _linePrefix, _formatted);\n\n\tNatspecMap natspecJSON = obtainedNatspec();\n\tif (!natspecJSON.empty())\n\t{\n\t\t_stream << _linePrefix << \"----\" << std::endl;\n\t\t// TODO: Diff both versions and highlight differences.\n\t\t// We should have a helper for doing that in newly defined test cases without much effort.\n\t\tprintPrefixed(_stream, formatNatspecExpectations(natspecJSON), _linePrefix);\n\t}\n}\n\nstd::tuple<std::string_view, NatspecJSONKind> NatspecJSONTest::parseExpectationHeader(std::string_view _line)\n{\n\tfor (NatspecJSONKind kind: {NatspecJSONKind::Devdoc, NatspecJSONKind::Userdoc})\n\t{\n\t\tstd::string kindSuffix = \" \" + toString(kind);\n\t\tif (boost::algorithm::ends_with(_line, kindSuffix))\n\t\t\treturn {_line.substr(0, _line.size() - kindSuffix.size()), kind};\n\t}\n\n\tBOOST_THROW_EXCEPTION(std::runtime_error(\n\t\t\"Natspec kind (devdoc/userdoc) not present in the expectation: \"s.append(_line)\n\t));\n}\n\nstd::string NatspecJSONTest::extractExpectationJSON(std::istream& _stream)\n{\n\tstd::string rawJSON;\n\tstd::string line;\n\twhile (getline(_stream, line))\n\t{\n\t\tstd::string_view strippedLine = expectLinePrefix(line);\n\t\trawJSON += strippedLine;\n\t\trawJSON += \"\\n\";\n\n\t\tif (boost::algorithm::starts_with(strippedLine, \"}\"))\n\t\t\tbreak;\n\t}\n\n\treturn rawJSON;\n}\n\nstd::string_view NatspecJSONTest::expectLinePrefix(std::string_view _line)\n{\n\tsize_t startPosition = 0;\n\tif (!boost::algorithm::starts_with(_line, \"//\"))\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\n\t\t\t\"Expectation line is not a comment: \"s.append(_line)\n\t\t));\n\n\tstartPosition += 2;\n\tif (startPosition < _line.size() && _line[startPosition] == ' ')\n\t\t++startPosition;\n\n\treturn _line.substr(startPosition, _line.size() - startPosition);\n}\n\nstd::string NatspecJSONTest::formatNatspecExpectations(NatspecMap const& _expectations) const\n{\n\tstd::string output;\n\tbool first = true;\n\t// NOTE: Not sorting explicitly because CompilerStack seems to put contracts roughly in the\n\t// order in which they appear in the source, which is much better than alphabetical order.\n\tfor (auto const& [contractName, expectationsForAllKinds]: _expectations)\n\t\tfor (auto const& [jsonKind, natspecJSON]: expectationsForAllKinds)\n\t\t{\n\t\t\tif (!first)\n\t\t\t\toutput += \"\\n\\n\";\n\t\t\tfirst = false;\n\n\t\t\toutput += contractName + \" \" + toString(jsonKind) + \"\\n\";\n\t\t\toutput += jsonPrint(natspecJSON, {JsonFormat::Pretty, 4});\n\t\t}\n\n\treturn output;\n}\n\nNatspecMap NatspecJSONTest::obtainedNatspec() const\n{\n\tif (compiler().state() < CompilerStack::AnalysisSuccessful)\n\t\treturn {};\n\n\tNatspecMap result;\n\tfor (std::string contractName: compiler().contractNames())\n\t{\n\t\tresult[contractName][NatspecJSONKind::Devdoc]  = compiler().natspecDev(contractName);\n\t\tresult[contractName][NatspecJSONKind::Userdoc] = compiler().natspecUser(contractName);\n\t}\n\n\treturn result;\n}\n\nSerializedNatspecMap NatspecJSONTest::prettyPrinted(NatspecMap const& _expectations) const\n{\n\tSerializedNatspecMap result;\n\tfor (auto const& [contractName, expectationsForAllKinds]: _expectations)\n\t\tfor (auto const& [jsonKind, natspecJSON]: expectationsForAllKinds)\n\t\t\tresult[contractName][jsonKind] = jsonPrint(natspecJSON, {JsonFormat::Pretty, 4});\n\n\treturn result;\n}\n"
  },
  {
    "path": "test/libsolidity/NatspecJSONTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Unit tests for the Natspec userdoc and devdoc JSON output.\n */\n\n#pragma once\n\n#include <test/libsolidity/SyntaxTest.h>\n\n#include <libsolutil/JSON.h>\n\n#include <istream>\n#include <map>\n#include <memory>\n#include <ostream>\n#include <string>\n#include <string_view>\n#include <tuple>\n\nnamespace solidity::frontend::test\n{\n\nenum class NatspecJSONKind\n{\n\tDevdoc,\n\tUserdoc,\n};\n\nstd::ostream& operator<<(std::ostream& _output, NatspecJSONKind _kind);\n\nusing NatspecMap = std::map<std::string, std::map<NatspecJSONKind, Json>>;\nusing SerializedNatspecMap = std::map<std::string, std::map<NatspecJSONKind, std::string>>;\n\nclass NatspecJSONTest: public SyntaxTest\n{\npublic:\n\n\tstatic std::unique_ptr<TestCase> create(Config const& _config);\n\n\tNatspecJSONTest(std::string const& _filename, langutil::EVMVersion _evmVersion):\n\t\tSyntaxTest(\n\t\t\t_filename,\n\t\t\t_evmVersion,\n\t\t\tlangutil::Error::Severity::Error // _minSeverity\n\t\t)\n\t{}\n\nprotected:\n\tvoid parseCustomExpectations(std::istream& _stream) override;\n\tbool expectationsMatch() override;\n\tvoid printExpectedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const override;\n\tvoid printObtainedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const override;\n\n\tNatspecMap m_expectedNatspecJSON;\n\nprivate:\n\tstatic std::tuple<std::string_view, NatspecJSONKind> parseExpectationHeader(std::string_view _line);\n\tstatic std::string extractExpectationJSON(std::istream& _stream);\n\tstatic std::string_view expectLinePrefix(std::string_view _line);\n\n\tstd::string formatNatspecExpectations(NatspecMap const& _expectations) const;\n\tSerializedNatspecMap prettyPrinted(NatspecMap const& _expectations) const;\n\tNatspecMap obtainedNatspec() const;\n};\n\n}\n"
  },
  {
    "path": "test/libsolidity/OptimizedIRCachingTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/libsolidity/OptimizedIRCachingTest.h>\n#include <test/libsolidity/util/SoltestErrors.h>\n\n#include <liblangutil/Exceptions.h>\n\n#include <libsolutil/StringUtils.h>\n\nusing namespace solidity::util;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\n\nvoid OptimizedIRCachingTest::setupCompiler(CompilerStack& _compiler)\n{\n\tAnalysisFramework::setupCompiler(_compiler);\n\t_compiler.setOptimiserSettings(true);\n\t_compiler.setViaIR(true);\n}\n\nTestCase::TestResult OptimizedIRCachingTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted)\n{\n\tsoltestAssert(compiler().objectOptimizer().size() == 0);\n\n\tif (!runFramework(m_source, PipelineStage::Compilation))\n\t{\n\t\tprintPrefixed(_stream, formatErrors(filteredErrors(), _formatted), _linePrefix);\n\t\treturn TestResult::FatalError;\n\t}\n\n\tm_obtainedResult = \"cachedObjects: \" + toString(compiler().objectOptimizer().size()) + \"\\n\";\n\treturn checkResult(_stream, _linePrefix, _formatted);\n}\n"
  },
  {
    "path": "test/libsolidity/OptimizedIRCachingTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * Unit tests for the optimized IR caching in CompilerStack.\n */\n\n#pragma once\n\n#include <test/libsolidity/AnalysisFramework.h>\n#include <test/TestCase.h>\n\n#include <ostream>\n#include <string>\n\nnamespace solidity::frontend::test\n{\n\nclass OptimizedIRCachingTest: public AnalysisFramework, public EVMVersionRestrictedTestCase\n{\npublic:\n\tOptimizedIRCachingTest(std::string const& _filename):\n\t\tEVMVersionRestrictedTestCase(_filename)\n\t{\n\t\tm_source = m_reader.source();\n\t\tm_expectation = m_reader.simpleExpectations();\n\t}\n\n\tstatic std::unique_ptr<TestCase> create(Config const& _config)\n\t{\n\t\treturn std::make_unique<OptimizedIRCachingTest>(_config.filename);\n\t}\n\n\tTestResult run(std::ostream& _stream, std::string const& _linePrefix = \"\", bool _formatted = false) override;\n\nprotected:\n\tvoid setupCompiler(CompilerStack& _compiler) override;\n};\n\n}\n"
  },
  {
    "path": "test/libsolidity/SMTCheckerTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/libsolidity/SMTCheckerTest.h>\n#include <test/Common.h>\n\n#include <range/v3/action/remove_if.hpp>\n\nusing namespace solidity;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\nusing namespace solidity::test;\n\nSMTCheckerTest::SMTCheckerTest(std::string const& _filename):\n\tSyntaxTest(_filename, EVMVersion{}),\n\tuniversalCallback(nullptr, smtCommand)\n{\n\tauto contract = m_reader.stringSetting(\"SMTContract\", \"\");\n\tauto maybeContracts = ModelCheckerContracts::fromString(contract);\n\tauto isValidContractName = [](std::string const& _name)\n\t{\n\t\treturn !_name.empty() && _name.find_first_of(\" \\t\\n\\r:,\") == std::string::npos;\n\t};\n\tif (maybeContracts)\n\t\tm_modelCheckerSettings.contracts = *maybeContracts;\n\telse if (isValidContractName(contract))\n\t\tm_modelCheckerSettings.contracts.contracts[\"\"] = {contract};\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid contract specified in SMTContract setting.\"));\n\n\tauto extCallsMode = ModelCheckerExtCalls::fromString(m_reader.stringSetting(\"SMTExtCalls\", \"untrusted\"));\n\tif (extCallsMode)\n\t\tm_modelCheckerSettings.externalCalls = *extCallsMode;\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid SMT external calls mode.\"));\n\n\tauto const& showProvedSafe = m_reader.stringSetting(\"SMTShowProvedSafe\", \"no\");\n\tif (showProvedSafe == \"no\")\n\t\tm_modelCheckerSettings.showProvedSafe = false;\n\telse if (showProvedSafe == \"yes\")\n\t\tm_modelCheckerSettings.showProvedSafe = true;\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid SMT \\\"show proved safe\\\" choice.\"));\n\n\tauto const& showUnproved = m_reader.stringSetting(\"SMTShowUnproved\", \"yes\");\n\tif (showUnproved == \"no\")\n\t\tm_modelCheckerSettings.showUnproved = false;\n\telse if (showUnproved == \"yes\")\n\t\tm_modelCheckerSettings.showUnproved = true;\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid SMT \\\"show unproved\\\" choice.\"));\n\n\tauto const& showUnsupported = m_reader.stringSetting(\"SMTShowUnsupported\", \"yes\");\n\tif (showUnsupported == \"no\")\n\t\tm_modelCheckerSettings.showUnsupported = false;\n\telse if (showUnsupported == \"yes\")\n\t\tm_modelCheckerSettings.showUnsupported = true;\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid SMT \\\"show unsupported\\\" choice.\"));\n\n\tm_modelCheckerSettings.solvers = smtutil::SMTSolverChoice::None();\n\tauto const& choice = m_reader.stringSetting(\"SMTSolvers\", \"z3\");\n\tif (choice == \"none\")\n\t\tm_modelCheckerSettings.solvers = smtutil::SMTSolverChoice::None();\n\telse if (!m_modelCheckerSettings.solvers.setSolver(choice))\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid SMT solver choice.\"));\n\n\tm_modelCheckerSettings.solvers &= ModelChecker::availableSolvers();\n\n\t/// Underflow and Overflow are not enabled by default for Solidity >=0.8.7,\n\t/// so we explicitly enable all targets for the tests,\n\t/// if the targets were not explicitly set by the test.\n\tauto targets = ModelCheckerTargets::fromString(m_reader.stringSetting(\"SMTTargets\", \"all\"));\n\tif (targets)\n\t\tm_modelCheckerSettings.targets = *targets;\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid SMT targets.\"));\n\n\tauto engine = ModelCheckerEngine::fromString(m_reader.stringSetting(\"SMTEngine\", \"all\"));\n\tif (engine)\n\t\tm_modelCheckerSettings.engine = *engine;\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid SMT engine choice.\"));\n\n\tif (m_modelCheckerSettings.solvers.none() || m_modelCheckerSettings.engine.none())\n\t\tm_shouldRun = false;\n\n\tauto const& ignoreCex = m_reader.stringSetting(\"SMTIgnoreCex\", \"yes\");\n\tif (ignoreCex == \"no\")\n\t\tm_ignoreCex = false;\n\telse if (ignoreCex == \"yes\")\n\t\tm_ignoreCex = true;\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid SMT counterexample choice.\"));\n\n\tstatic auto removeInv = [](std::vector<SyntaxTestError>&& errors) {\n\t\tstd::vector<SyntaxTestError> filtered;\n\t\tfor (auto&& e: errors)\n\t\t\tif (e.errorId != 1180_error)\n\t\t\t\tfiltered.emplace_back(e);\n\t\treturn filtered;\n\t};\n\n\tauto const& ignoreInv = m_reader.stringSetting(\"SMTIgnoreInv\", \"yes\");\n\tif (ignoreInv == \"no\")\n\t\tm_modelCheckerSettings.invariants = ModelCheckerInvariants::All();\n\telse if (ignoreInv == \"yes\")\n\t\tm_modelCheckerSettings.invariants = ModelCheckerInvariants::None();\n\telse\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid SMT invariant choice.\"));\n\n\tif (m_modelCheckerSettings.invariants.invariants.empty())\n\t\tm_expectations = removeInv(std::move(m_expectations));\n\n\tauto const& ignoreOSSetting = m_reader.stringSetting(\"SMTIgnoreOS\", \"none\");\n\tfor (std::string const& os: ignoreOSSetting | ranges::views::split(',') | ranges::to<std::vector<std::string>>())\n\t{\n#ifdef __APPLE__\n\t\tif (os == \"macos\")\n\t\t\tm_shouldRun = false;\n#elif _WIN32\n\t\tif (os == \"windows\")\n\t\t\tm_shouldRun = false;\n#elif __linux__\n\t\tif (os == \"linux\")\n\t\t\tm_shouldRun = false;\n#else\n\t\t// On other operating systems this setting is ignored (as we don't test other operating systems in CI),\n\t\t// but we need to prevent an unused-variable warning.\n\t\t(void)os;\n#endif\n\t}\n\n\tauto const& bmcLoopIterations = m_reader.sizetSetting(\"BMCLoopIterations\", 1);\n\tm_modelCheckerSettings.bmcLoopIterations = std::optional<unsigned>{bmcLoopIterations};\n\n\t// TODO: Enable EOF testing when EOF gets stable and smtCheckerTest starts using IR.\n\tif (CommonOptions::get().eofVersion().has_value())\n\t\tm_shouldRun = false;\n}\n\nvoid SMTCheckerTest::setupCompiler(CompilerStack& _compiler)\n{\n\tSyntaxTest::setupCompiler(_compiler);\n\n\t_compiler.setModelCheckerSettings(m_modelCheckerSettings);\n}\n\nvoid SMTCheckerTest::filterObtainedErrors()\n{\n\tSyntaxTest::filterObtainedErrors();\n\tm_unfilteredErrorList = m_errorList;\n\n\tstatic auto removeCex = [](std::vector<SyntaxTestError>& errors) {\n\t\tfor (auto& e: errors)\n\t\t\tif (\n\t\t\t\tauto cexPos = e.message.find(\"\\\\nCounterexample\");\n\t\t\t\tcexPos != std::string::npos\n\t\t\t)\n\t\t\t\te.message = e.message.substr(0, cexPos);\n\t};\n\n\tif (m_ignoreCex)\n\t{\n\t\tremoveCex(m_expectations);\n\t\tremoveCex(m_errorList);\n\t}\n}\n\nvoid SMTCheckerTest::printUpdatedExpectations(std::ostream &_stream, const std::string &_linePrefix) const {\n\tif (!m_unfilteredErrorList.empty())\n\t\tprintErrorList(_stream, m_unfilteredErrorList, _linePrefix, false);\n\telse\n\t\tCommonSyntaxTest::printUpdatedExpectations(_stream, _linePrefix);\n}\n\nstd::unique_ptr<CompilerStack> SMTCheckerTest::createStack() const {\n\treturn std::make_unique<CompilerStack>(universalCallback.callback());\n}\n"
  },
  {
    "path": "test/libsolidity/SMTCheckerTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <test/libsolidity/SyntaxTest.h>\n\n#include <libsmtutil/SolverInterface.h>\n\n#include <libsolidity/formal/ModelChecker.h>\n\n#include <libsolidity/interface/SMTSolverCommand.h>\n#include <libsolidity/interface/UniversalCallback.h>\n\n#include <string>\n\nnamespace solidity::frontend::test\n{\n\nclass SMTCheckerTest: public SyntaxTest\n{\npublic:\n\tstatic std::unique_ptr<TestCase> create(Config const& _config)\n\t{\n\t\treturn std::make_unique<SMTCheckerTest>(_config.filename);\n\t}\n\texplicit SMTCheckerTest(std::string const& _filename);\n\n\tvoid setupCompiler(CompilerStack& _compiler) override;\n\tvoid filterObtainedErrors() override;\n\n\tvoid printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;\n\nprotected:\n\tstd::unique_ptr<CompilerStack> createStack() const override;\n\n\t/*\n\tOptions that can be set in the test:\n\tSMTEngine: `all`, `chc`, `bmc`, `none`, where the default is `all`.\n\t\tSet in m_modelCheckerSettings.\n\tSMTIgnoreCex: `yes`, `no`, where the default is `no`.\n\t\tSet in m_ignoreCex.\n\tSMTIgnoreInv: `yes`, `no`, where the default is `no`.\n\t\tSet in m_modelCheckerSettings.\n\tSMTShowProvedSafe: `yes`, `no`, where the default is `no`.\n\t\tSet in m_modelCheckerSettings.\n\tSMTShowUnproved: `yes`, `no`, where the default is `yes`.\n\t\tSet in m_modelCheckerSettings.\n\tSMTSolvers: `all`, `cvc5`, `z3`, `eld`, `none`, where the default is `z3`.\n\t\tSet in m_modelCheckerSettings.\n\tBMCLoopIterations: number of loop iterations for BMC engine, the default is 1.\n\t\tSet in m_modelCheckerSettings.\n\t*/\n\n\tModelCheckerSettings m_modelCheckerSettings;\n\n\tbool m_ignoreCex = false;\n\n\tstd::vector<SyntaxTestError> m_unfilteredErrorList;\n\n\tSMTSolverCommand smtCommand;\n\tUniversalCallback universalCallback;\n};\n\n}\n"
  },
  {
    "path": "test/libsolidity/SemVerMatcher.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <chris@ethereum.org>\n * @date 2016\n * Unit tests for the semantic versioning matcher.\n */\n\n#include <string>\n#include <vector>\n#include <tuple>\n#include <liblangutil/Scanner.h>\n#include <liblangutil/SemVerHandler.h>\n#include <test/Common.h>\n#include <test/libsolidity/util/SoltestErrors.h>\n\n#include <boost/test/unit_test.hpp>\n\nusing namespace solidity::langutil;\n\nnamespace solidity::frontend::test\n{\n\nBOOST_AUTO_TEST_SUITE(SemVerMatcher)\n\nnamespace\n{\n\nSemVerMatchExpression parseExpression(std::string const& _input)\n{\n\tCharStream stream(_input, \"\");\n\tScanner scanner{stream};\n\tstd::vector<std::string> literals;\n\tstd::vector<Token> tokens;\n\twhile (scanner.currentToken() != Token::EOS)\n\t{\n\t\tauto token = scanner.currentToken();\n\t\tstd::string literal = scanner.currentLiteral();\n\t\tif (literal.empty() && TokenTraits::toString(token))\n\t\t\tliteral = TokenTraits::toString(token);\n\t\tliterals.push_back(literal);\n\t\ttokens.push_back(token);\n\t\tscanner.next();\n\t}\n\n\ttry\n\t{\n\t\tauto matchExpression = SemVerMatchExpressionParser(tokens, literals).parse();\n\n\t\tBOOST_CHECK_MESSAGE(\n\t\t\tmatchExpression.isValid(),\n\t\t\t\"Expression \\\"\" + _input + \"\\\" did not parse properly.\"\n\t\t);\n\n\t\treturn matchExpression;\n\t}\n\tcatch (SemVerError const&)\n\t{\n\t\t// Ignored, since a test case should have a parsable version\n\t\tsoltestAssert(false);\n\t}\n\n\t// FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794)\n\tutil::unreachable();\n}\n\n}\n\nBOOST_AUTO_TEST_CASE(exception_on_invalid_version_in_semverversion_constructor)\n{\n\tBOOST_CHECK_EXCEPTION(\n\t\tSemVerVersion version(\"1.2\"),\n\t\tSemVerError,\n\t\t[&](auto const& _exception) { BOOST_TEST(_exception.what() == \"Invalid versionString: 1.2\"); return true; }\n\t);\n\n\tBOOST_CHECK_EXCEPTION(\n\t\tSemVerVersion version(\"-1.2.0\"),\n\t\tSemVerError,\n\t\t[&](auto const& _exception) { BOOST_TEST(_exception.what() == \"Invalid versionString: -1.2.0\"); return true; }\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(positive_range)\n{\n\t// Positive range tests\n\tstd::vector<std::pair<std::string, std::string>> tests = {\n\t\t{\"*\", \"1.2.3-foo\"},\n\t\t{\"1.0.0 - 2.0.0\", \"1.2.3\"},\n\t\t{\"1.0.0\", \"1.0.0\"},\n\t\t{\"1.0\", \"1.0.0\"},\n\t\t{\"1\", \"1.0.0\"},\n\t\t{\">=*\", \"0.2.4\"},\n\t\t{\"*\", \"1.2.3\"},\n\t\t{\">=1.0.0\", \"1.0.0\"},\n\t\t{\">=1.0.0\", \"1.0.1\"},\n\t\t{\">=1.0.0\", \"1.1.0\"},\n\t\t{\">1.0.0\", \"1.0.1\"},\n\t\t{\">1.0.0\", \"1.1.0\"},\n\t\t{\"<=2.0.0\", \"2.0.0\"},\n\t\t{\"<=2.0.0\", \"1.9999.9999\"},\n\t\t{\"<=2.0.0\", \"0.2.9\"},\n\t\t{\"<2.0.0\", \"1.9999.9999\"},\n\t\t{\"<2.0.0\", \"0.2.9\"},\n\t\t{\"<1.0\", \"1.0.0-pre\"},\n\t\t{\"<1\", \"1.0.0-pre\"},\n\t\t{\">= 1.0.0\", \"1.0.0\"},\n\t\t{\">=  1.0.0\", \"1.0.1\"},\n\t\t{\">=   1.0.0\", \"1.1.0\"},\n\t\t{\"> 1.0.0\", \"1.0.1\"},\n\t\t{\">  1.0.0\", \"1.1.0\"},\n\t\t{\"<=   2.0.0\", \"2.0.0\"},\n\t\t{\"<= 2.0.0\", \"1.9999.9999\"},\n\t\t{\"<=  2.0.0\", \"0.2.9\"},\n\t\t{\"<    2.0.0\", \"1.9999.9999\"},\n\t\t{\"<\\t2.0.0\", \"0.2.9\"},\n\t\t{\">=0.1.97\", \"0.1.97\"},\n\t\t{\"0.1.20 || 1.2.4\", \"1.2.4\"},\n\t\t{\">=0.2.3 || <0.0.1\", \"0.0.0\"},\n\t\t{\">=0.2.3 || <0.0.1\", \"0.2.3\"},\n\t\t{\">=0.2.3 || <0.0.1\", \"0.2.4\"},\n\t\t{\"\\\"2.x.x\\\"\", \"2.1.3\"},\n\t\t{\"1.2.x\", \"1.2.3\"},\n\t\t{\"\\\"1.2.x\\\" || \\\"2.x\\\"\", \"2.1.3\"},\n\t\t{\"\\\"1.2.x\\\" || \\\"2.x\\\"\", \"1.2.3\"},\n\t\t{\"x\", \"1.2.3\"},\n\t\t{\"2.*.*\", \"2.1.3\"},\n\t\t{\"1.2.*\", \"1.2.3\"},\n\t\t{\"1.2.* || 2.*\", \"2.1.3\"},\n\t\t{\"1.2.* || 2.*\", \"1.2.3\"},\n\t\t{\"*\", \"1.2.3\"},\n\t\t{\"2\", \"2.1.2\"},\n\t\t{\"2.3\", \"2.3.1\"},\n\t\t{\"~2.4\", \"2.4.0\"}, // >=2.4.0 <2.5.0\n\t\t{\"~2.4\", \"2.4.5\"},\n\t\t{\"~1\", \"1.2.3\"}, // >=1.0.0 <2.0.0\n\t\t{\"~1.0\", \"1.0.2\"}, // >=1.0.0 <1.1.0,\n\t\t{\"~ 1.0\", \"1.0.2\"},\n\t\t{\"~ 1.0.3\", \"1.0.12\"},\n\t\t{\">=1\", \"1.0.0\"},\n\t\t{\">= 1\", \"1.0.0\"},\n\t\t{\"<1.2\", \"1.1.1\"},\n\t\t{\"< 1.2\", \"1.1.1\"},\n\t\t{\"=0.7.x\", \"0.7.2\"},\n\t\t{\"<=0.7.x\", \"0.7.2\"},\n\t\t{\">=0.7.x\", \"0.7.2\"},\n\t\t{\"<=0.7.x\", \"0.6.2\"},\n\t\t{\"~1.2.1 >=1.2.3\", \"1.2.3\"},\n\t\t{\"~1.2.1 =1.2.3\", \"1.2.3\"},\n\t\t{\"~1.2.1 1.2.3\", \"1.2.3\"},\n\t\t{\"~1.2.1 >=1.2.3 1.2.3\", \"1.2.3\"},\n\t\t{\"~1.2.1 1.2.3 >=1.2.3\", \"1.2.3\"},\n\t\t{\">=\\\"1.2.1\\\" 1.2.3\", \"1.2.3\"},\n\t\t{\"1.2.3 >=1.2.1\", \"1.2.3\"},\n\t\t{\">=1.2.3 >=1.2.1\", \"1.2.3\"},\n\t\t{\">=1.2.1 >=1.2.3\", \"1.2.3\"},\n\t\t{\">=1.2\", \"1.2.8\"},\n\t\t{\"^1.2.3\", \"1.8.1\"},\n\t\t{\"^0.1.2\", \"0.1.2\"},\n\t\t{\"^0.1\", \"0.1.2\"},\n\t\t{\"^1.2\", \"1.4.2\"},\n\t\t{\"^1.2\", \"1.2.0\"},\n\t\t{\"^1\", \"1.2.0\"},\n\t\t{\"<=1.2.3\", \"1.2.3-beta\"},\n\t\t{\">1.2\", \"1.3.0-beta\"},\n\t\t{\"<1.2.3\", \"1.2.3-beta\"},\n\t\t{\"^1.2 ^1\", \"1.4.2\"},\n\t\t{\"^0\", \"0.5.1\"},\n\t\t{\"^0\", \"0.1.1\"},\n\t};\n\tfor (auto const& t: tests)\n\t{\n\t\tSemVerVersion version(t.second);\n\t\tSemVerMatchExpression matchExpression = parseExpression(t.first);\n\t\tBOOST_CHECK_MESSAGE(\n\t\t\tmatchExpression.matches(version),\n\t\t\t\"Version \\\"\" + t.second + \"\\\" did not satisfy expression \\\"\" + t.first + \"\\\"\"\n\t\t);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(negative_range)\n{\n\t// Negative range tests\n\tstd::vector<std::pair<std::string, std::string>> tests = {\n\t\t{\"^0^1\", \"0.0.0\"},\n\t\t{\"^0^1\", \"1.0.0\"},\n\t\t{\"1.0.0 - 2.0.0\", \"2.2.3\"},\n\t\t{\"1.0\", \"1.0.0-pre\"},\n\t\t{\"1\", \"1.0.0-pre\"},\n\t\t{\"^1.2.3\", \"1.2.3-pre\"},\n\t\t{\"^1.2\", \"1.2.0-pre\"},\n\t\t{\"^1.2\", \"1.2.1-pre\"},\n\t\t{\"^1.2.3\", \"1.2.3-beta\"},\n\t\t{\"=0.7.x\", \"0.7.0-asdf\"},\n\t\t{\">=0.7.x\", \"0.7.0-asdf\"},\n\t\t{\"1.0.0\", \"1.0.1\"},\n\t\t{\">=1.0.0\", \"0.0.0\"},\n\t\t{\">=1.0.0\", \"0.0.1\"},\n\t\t{\">=1.0.0\", \"0.1.0\"},\n\t\t{\">1.0.0\", \"0.0.1\"},\n\t\t{\">1.0.0\", \"0.1.0\"},\n\t\t{\"<=2.0.0\", \"3.0.0\"},\n\t\t{\"<=2.0.0\", \"2.9999.9999\"},\n\t\t{\"<=2.0.0\", \"2.2.9\"},\n\t\t{\"<2.0.0\", \"2.9999.9999\"},\n\t\t{\"<2.0.0\", \"2.2.9\"},\n\t\t{\">=0.1.97\", \"0.1.93\"},\n\t\t{\"0.1.20 || 1.2.4\", \"1.2.3\"},\n\t\t{\">=0.2.3 || <0.0.1\", \"0.0.3\"},\n\t\t{\">=0.2.3 || <0.0.1\", \"0.2.2\"},\n\t\t{\"\\\"2.x.x\\\"\", \"1.1.3\"},\n\t\t{\"\\\"2.x.x\\\"\", \"3.1.3\"},\n\t\t{\"1.2.x\", \"1.3.3\"},\n\t\t{\"\\\"1.2.x\\\" || \\\"2.x\\\"\", \"3.1.3\"},\n\t\t{\"\\\"1.2.x\\\" || \\\"2.x\\\"\", \"1.1.3\"},\n\t\t{\"2.*.*\", \"1.1.3\"},\n\t\t{\"2.*.*\", \"3.1.3\"},\n\t\t{\"1.2.*\", \"1.3.3\"},\n\t\t{\"1.2.* || 2.*\", \"3.1.3\"},\n\t\t{\"1.2.* || 2.*\", \"1.1.3\"},\n\t\t{\"2\", \"1.1.2\"},\n\t\t{\"2.3\", \"2.4.1\"},\n\t\t{\"~2.4\", \"2.5.0\"}, // >=2.4.0 <2.5.0\n\t\t{\"~2.4\", \"2.3.9\"},\n\t\t{\"~1\", \"0.2.3\"}, // >=1.0.0 <2.0.0\n\t\t{\"~1.0\", \"1.1.0\"}, // >=1.0.0 <1.1.0\n\t\t{\"<1\", \"1.0.0\"},\n\t\t{\">=1.2\", \"1.1.1\"},\n\t\t{\"=0.7.x\", \"0.8.2\"},\n\t\t{\">=0.7.x\", \"0.6.2\"},\n\t\t{\"<0.7.x\", \"0.7.2\"},\n\t\t{\"=1.2.3\", \"1.2.3-beta\"},\n\t\t{\">1.2\", \"1.2.8\"},\n\t\t{\"^1.2.3\", \"2.0.0-alpha\"},\n\t\t{\"^0.6\", \"0.6.2-alpha\"},\n\t\t{\"^0.6\", \"0.6.0-alpha\"},\n\t\t{\"^1.2\", \"1.2.1-pre\"},\n\t\t{\"^1.2.3\", \"1.2.2\"},\n\t\t{\"^1\", \"1.2.0-pre\"},\n\t\t{\"^1\", \"1.2.0-pre\"},\n\t\t{\"^1.2\", \"1.1.9\"},\n\t\t{\"^0\", \"0.5.1-pre\"},\n\t\t{\"^0\", \"0.0.0-pre\"},\n\t\t{\"^0\", \"1.0.0\"},\n\t};\n\tfor (auto const& t: tests)\n\t{\n\t\tSemVerVersion version(t.second);\n\t\tauto matchExpression = parseExpression(t.first);\n\t\tBOOST_CHECK_MESSAGE(\n\t\t\t!matchExpression.matches(version),\n\t\t\t\"Version \\\"\" + t.second + \"\\\" did satisfy expression \\\"\" + t.first + \"\\\" \" +\n\t\t\t\"(although it should not)\"\n\t\t);\n\t}\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/SemanticTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <test/libsolidity/SemanticTest.h>\n\n#include <libsolutil/Whiskers.h>\n#include <libyul/Exceptions.h>\n#include <test/Common.h>\n#include <test/libsolidity/util/BytesUtils.h>\n\n#include <boost/algorithm/string.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n#include <boost/algorithm/string/trim.hpp>\n#include <boost/throw_exception.hpp>\n\n#include <algorithm>\n#include <cctype>\n#include <fstream>\n#include <functional>\n#include <memory>\n#include <optional>\n#include <stdexcept>\n#include <string>\n#include <utility>\n\nusing namespace solidity;\nusing namespace solidity::yul;\nusing namespace solidity::langutil;\nusing namespace solidity::util;\nusing namespace solidity::util::formatting;\nusing namespace solidity::frontend::test;\nusing namespace boost::algorithm;\nusing namespace boost::unit_test;\nusing namespace std::string_literals;\nnamespace fs = boost::filesystem;\n\nstd::ostream& solidity::frontend::test::operator<<(std::ostream& _output, RequiresYulOptimizer _requiresYulOptimizer)\n{\n\tswitch (_requiresYulOptimizer)\n\t{\n\tcase RequiresYulOptimizer::False: _output << \"false\"; break;\n\tcase RequiresYulOptimizer::MinimalStack: _output << \"minimalStack\"; break;\n\tcase RequiresYulOptimizer::Full: _output << \"full\"; break;\n\t}\n\treturn _output;\n}\n\nSemanticTest::SemanticTest(\n\tstd::string const& _filename,\n\tlangutil::EVMVersion _evmVersion,\n\tstd::optional<uint8_t> _eofVersion,\n\tstd::vector<boost::filesystem::path> const& _vmPaths,\n\tbool _enforceGasCost,\n\tu256 _enforceGasCostMinValue\n):\n\tSolidityExecutionFramework(_evmVersion, _eofVersion, _vmPaths, false),\n\tEVMVersionRestrictedTestCase(_filename),\n\tm_sources(m_reader.sources()),\n\tm_lineOffset(m_reader.lineNumber()),\n\tm_builtins(makeBuiltins()),\n\tm_sideEffectHooks(makeSideEffectHooks()),\n\tm_enforceGasCost(_enforceGasCost),\n\tm_enforceGasCostMinValue(std::move(_enforceGasCostMinValue))\n{\n\tstatic std::set<std::string> const compileViaYulAllowedValues{\"also\", \"true\", \"false\"};\n\tstatic std::set<std::string> const yulRunTriggers{\"also\", \"true\"};\n\tstatic std::set<std::string> const legacyRunTriggers{\"also\", \"false\", \"default\"};\n\n\tm_requiresYulOptimizer = m_reader.enumSetting<RequiresYulOptimizer>(\n\t\t\"requiresYulOptimizer\",\n\t\t{\n\t\t\t{toString(RequiresYulOptimizer::False), RequiresYulOptimizer::False},\n\t\t\t{toString(RequiresYulOptimizer::MinimalStack), RequiresYulOptimizer::MinimalStack},\n\t\t\t{toString(RequiresYulOptimizer::Full), RequiresYulOptimizer::Full},\n\t\t},\n\t\ttoString(RequiresYulOptimizer::False)\n\t);\n\n\tm_runWithABIEncoderV1Only = m_reader.boolSetting(\"ABIEncoderV1Only\", false);\n\tif (m_runWithABIEncoderV1Only && !solidity::test::CommonOptions::get().useABIEncoderV1)\n\t\tm_shouldRun = false;\n\n\tauto const eofEnabled = solidity::test::CommonOptions::get().eofVersion().has_value();\n\tstd::string compileViaYul = m_reader.stringSetting(\"compileViaYul\", eofEnabled ? \"true\" : \"also\");\n\n\tif (compileViaYul == \"false\" && eofEnabled)\n\t\tm_shouldRun = false;\n\n\tif (m_runWithABIEncoderV1Only && compileViaYul != \"false\")\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\n\t\t\t\"ABIEncoderV1Only tests cannot be run via yul, \"\n\t\t\t\"so they need to also specify ``compileViaYul: false``\"\n\t\t));\n\tif (!util::contains(compileViaYulAllowedValues, compileViaYul))\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid compileViaYul value: \" + compileViaYul + \".\"));\n\tm_testCaseWantsYulRun = util::contains(yulRunTriggers, compileViaYul);\n\tm_testCaseWantsLegacyRun = util::contains(legacyRunTriggers, compileViaYul);\n\n\tauto revertStrings = revertStringsFromString(m_reader.stringSetting(\"revertStrings\", \"default\"));\n\tsoltestAssert(revertStrings, \"Invalid revertStrings setting.\");\n\tm_revertStrings = revertStrings.value();\n\n\tm_allowNonExistingFunctions = m_reader.boolSetting(\"allowNonExistingFunctions\", false);\n\tm_testCaseWantsSSACFGRun = m_reader.boolSetting(\"compileViaSSACFG\", false);\n\tm_compiler.setExperimental(m_reader.boolSetting(\"experimental\", false));\n\n\tparseExpectations(m_reader.stream());\n\tsoltestAssert(!m_tests.empty(), \"No tests specified in \" + _filename);\n\n\tif (m_enforceGasCost)\n\t{\n\t\tm_compiler.setMetadataFormat(CompilerStack::MetadataFormat::NoMetadata);\n\t\tm_compiler.setMetadataHash(CompilerStack::MetadataHash::None);\n\t}\n}\n\nstd::map<std::string, Builtin> SemanticTest::makeBuiltins()\n{\n\treturn {\n\t\t{\n\t\t\t\"isoltest_builtin_test\",\n\t\t\t[](FunctionCall const&) -> std::optional<bytes>\n\t\t\t{\n\t\t\t\treturn toBigEndian(u256(0x1234));\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"isoltest_side_effects_test\",\n\t\t\t[](FunctionCall const& _call) -> std::optional<bytes>\n\t\t\t{\n\t\t\t\tif (_call.arguments.parameters.empty())\n\t\t\t\t\treturn toBigEndian(0);\n\t\t\t\telse\n\t\t\t\t\treturn _call.arguments.rawBytes();\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"balance\",\n\t\t\t[this](FunctionCall const& _call) -> std::optional<bytes>\n\t\t\t{\n\t\t\t\tsoltestAssert(_call.arguments.parameters.size() <= 1, \"Account address expected.\");\n\t\t\t\th160 address;\n\t\t\t\tif (_call.arguments.parameters.size() == 1)\n\t\t\t\t\taddress = h160(_call.arguments.parameters.at(0).rawString);\n\t\t\t\telse\n\t\t\t\t\taddress = m_contractAddress;\n\t\t\t\treturn toBigEndian(balanceAt(address));\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"storageEmpty\",\n\t\t\t[this](FunctionCall const& _call) -> std::optional<bytes>\n\t\t\t{\n\t\t\t\tsoltestAssert(_call.arguments.parameters.empty(), \"No arguments expected.\");\n\t\t\t\treturn toBigEndian(u256(storageEmpty(m_contractAddress) ? 1 : 0));\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"account\",\n\t\t\t[this](FunctionCall const& _call) -> std::optional<bytes>\n\t\t\t{\n\t\t\t\tsoltestAssert(_call.arguments.parameters.size() == 1, \"Account number expected.\");\n\t\t\t\tsize_t accountNumber = static_cast<size_t>(stoi(_call.arguments.parameters.at(0).rawString));\n\t\t\t\t// Need to pad it to 32-bytes to workaround limitations in BytesUtils::formatHex.\n\t\t\t\treturn toBigEndian(h256(ExecutionFramework::setAccount(accountNumber).asBytes(), h256::AlignRight));\n\t\t\t}\n\t\t},\n\t};\n}\n\nstd::vector<SideEffectHook> SemanticTest::makeSideEffectHooks() const\n{\n\tusing namespace std::placeholders;\n\treturn {\n\t\t[](FunctionCall const& _call) -> std::vector<std::string>\n\t\t{\n\t\t\tif (_call.signature == \"isoltest_side_effects_test\")\n\t\t\t{\n\t\t\t\tstd::vector<std::string> result;\n\t\t\t\tfor (auto const& argument: _call.arguments.parameters)\n\t\t\t\t\tresult.emplace_back(util::toHex(argument.rawBytes));\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\treturn {};\n\t\t},\n\t\tbind(&SemanticTest::eventSideEffectHook, this, _1)\n\t};\n}\n\nstd::string SemanticTest::formatEventParameter(std::optional<AnnotatedEventSignature> _signature, bool _indexed, size_t _index, bytes const& _data)\n{\n\tauto isPrintableASCII = [](bytes const& s)\n\t{\n\t\tbool zeroes = true;\n\t\tfor (auto c: s)\n\t\t{\n\t\t\tif (static_cast<unsigned>(c) != 0x00)\n\t\t\t{\n\t\t\t\tzeroes = false;\n\t\t\t\tif (static_cast<unsigned>(c) <= 0x1f || static_cast<unsigned>(c) >= 0x7f)\n\t\t\t\t\treturn false;\n\t\t\t} else\n\t\t\t\tbreak;\n\t\t}\n\t\treturn !zeroes;\n\t};\n\n\tABIType abiType(ABIType::Type::Hex);\n\tif (isPrintableASCII(_data))\n\t\tabiType = ABIType(ABIType::Type::String);\n\tif (_signature.has_value())\n\t{\n\t\tstd::vector<std::string> const& types = _indexed ? _signature->indexedTypes : _signature->nonIndexedTypes;\n\t\tif (_index < types.size())\n\t\t{\n\t\t\tif (types.at(_index) == \"bool\")\n\t\t\t\tabiType = ABIType(ABIType::Type::Boolean);\n\t\t}\n\t}\n\treturn BytesUtils::formatBytes(_data, abiType);\n}\n\nstd::vector<std::string> SemanticTest::eventSideEffectHook(FunctionCall const&) const\n{\n\tstd::vector<std::string> sideEffects;\n\tstd::vector<LogRecord> recordedLogs = ExecutionFramework::recordedLogs();\n\tfor (LogRecord const& log: recordedLogs)\n\t{\n\t\tstd::optional<AnnotatedEventSignature> eventSignature;\n\t\tif (!log.topics.empty())\n\t\t\teventSignature = matchEvent(log.topics[0]);\n\t\tstd::stringstream sideEffect;\n\t\tsideEffect << \"emit \";\n\t\tif (eventSignature.has_value())\n\t\t\tsideEffect << eventSignature.value().signature;\n\t\telse\n\t\t\tsideEffect << \"<anonymous>\";\n\n\t\tif (m_contractAddress != log.creator)\n\t\t\tsideEffect << \" from 0x\" << log.creator;\n\n\t\tstd::vector<std::string> eventStrings;\n\t\tsize_t index{0};\n\t\tfor (h256 const& topic: log.topics)\n\t\t{\n\t\t\tif (!eventSignature.has_value() || index != 0)\n\t\t\t\teventStrings.push_back(\"#\" + formatEventParameter(eventSignature, true, index, topic.asBytes()));\n\t\t\t++index;\n\t\t}\n\n\t\tsoltestAssert(log.data.size() % 32 == 0, \"\");\n\t\tfor (size_t index = 0; index < log.data.size() / 32; ++index)\n\t\t{\n\t\t\tauto begin = log.data.begin() + static_cast<long>(index * 32);\n\t\t\tbytes const& data = bytes{begin, begin + 32};\n\t\t\teventStrings.emplace_back(formatEventParameter(eventSignature, false, index, data));\n\t\t}\n\n\t\tif (!eventStrings.empty())\n\t\t\tsideEffect << \": \";\n\t\tsideEffect << joinHumanReadable(eventStrings);\n\t\tsideEffects.emplace_back(sideEffect.str());\n\t}\n\treturn sideEffects;\n}\n\nstd::optional<AnnotatedEventSignature> SemanticTest::matchEvent(util::h256 const& hash) const\n{\n\tstd::optional<AnnotatedEventSignature> result;\n\tfor (std::string& contractName: m_compiler.contractNames())\n\t{\n\t\tContractDefinition const& contract = m_compiler.contractDefinition(contractName);\n\t\tfor (EventDefinition const* event: contract.events() + contract.usedInterfaceEvents())\n\t\t{\n\t\t\tFunctionTypePointer eventFunctionType = event->functionType(true);\n\t\t\tif (!event->isAnonymous() && keccak256(eventFunctionType->externalSignature()) == hash)\n\t\t\t{\n\t\t\t\tAnnotatedEventSignature eventInfo;\n\t\t\t\teventInfo.signature = eventFunctionType->externalSignature();\n\t\t\t\tfor (auto const& param: event->parameters())\n\t\t\t\t\tif (param->isIndexed())\n\t\t\t\t\t\teventInfo.indexedTypes.emplace_back(param->type()->toString(true));\n\t\t\t\t\telse\n\t\t\t\t\t\teventInfo.nonIndexedTypes.emplace_back(param->type()->toString(true));\n\t\t\t\tresult = eventInfo;\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n\nfrontend::OptimiserSettings SemanticTest::optimizerSettingsFor(RequiresYulOptimizer _requiresYulOptimizer)\n{\n\tswitch (_requiresYulOptimizer)\n\t{\n\tcase RequiresYulOptimizer::False:\n\t\treturn OptimiserSettings::minimal();\n\tcase RequiresYulOptimizer::MinimalStack:\n\t{\n\t\tOptimiserSettings settings = OptimiserSettings::minimal();\n\t\tsettings.runYulOptimiser = true;\n\t\tsettings.yulOptimiserSteps = \"uljmul jmul\";\n\t\treturn settings;\n\t}\n\tcase RequiresYulOptimizer::Full:\n\t\treturn OptimiserSettings::full();\n\t}\n\tunreachable();\n}\n\nTestCase::TestResult SemanticTest::run(std::ostream& _stream, std::string const& _linePrefix, bool _formatted)\n{\n\tTestResult result = TestResult::Success;\n\n\tif (m_testCaseWantsLegacyRun && !m_eofVersion.has_value())\n\t\tresult = runTest(_stream, _linePrefix, _formatted, false /* _isYulRun */);\n\n\tif (m_testCaseWantsYulRun && result == TestResult::Success)\n\t{\n\t\tif (solidity::test::CommonOptions::get().optimize)\n\t\t\tresult = runTest(_stream, _linePrefix, _formatted, true /* _isYulRun */);\n\t\telse\n\t\t\tresult = tryRunTestWithYulOptimizer(_stream, _linePrefix, _formatted);\n\t}\n\n\tif (m_testCaseWantsSSACFGRun && m_testCaseWantsYulRun && result == TestResult::Success)\n\t{\n\t\tif (solidity::test::CommonOptions::get().optimize)\n\t\t\tresult = runTest(_stream, _linePrefix, _formatted, true /* _isYulRun */, true /* _isSSACFGRun */);\n\t\telse\n\t\t\tresult = tryRunTestWithYulOptimizer(_stream, _linePrefix, _formatted, true /* _isSSACFGRun */);\n\t}\n\n\tif (result != TestResult::Success)\n\t\tsolidity::test::CommonOptions::get().printSelectedOptions(\n\t\t\t_stream,\n\t\t\t_linePrefix,\n\t\t\t{\"evmVersion\", \"optimize\", \"useABIEncoderV1\", \"batch\"}\n\t\t);\n\n\treturn result;\n}\n\nTestCase::TestResult SemanticTest::runTest(\n\tstd::ostream& _stream,\n\tstd::string const& _linePrefix,\n\tbool _formatted,\n\tbool _isYulRun,\n\tbool _isSSACFGRun\n)\n{\n\tbool success = true;\n\tm_gasCostFailure = false;\n\tm_isSSACFGRun = _isSSACFGRun;\n\n\tselectVM(evmc_capabilities::EVMC_CAPABILITY_EVM1);\n\n\treset();\n\n\tm_compileViaYul = _isYulRun;\n\tm_compileViaSSACFG = _isSSACFGRun;\n\n\tif (_isSSACFGRun)\n\t\tAnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << \"Running via SSA Yul: \" << std::endl;\n\telse if (_isYulRun)\n\t\tAnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << \"Running via Yul: \" << std::endl;\n\n\tfor (TestFunctionCall& test: m_tests)\n\t\ttest.reset();\n\n\tstd::map<std::string, solidity::test::Address> libraries;\n\n\tbool constructed = false;\n\n\tfor (TestFunctionCall& test: m_tests)\n\t{\n\t\tif (constructed)\n\t\t{\n\t\t\tsoltestAssert(\n\t\t\t\ttest.call().kind != FunctionCall::Kind::Library,\n\t\t\t\t\"Libraries have to be deployed before any other call.\"\n\t\t\t);\n\t\t\tsoltestAssert(\n\t\t\t\ttest.call().kind != FunctionCall::Kind::Constructor,\n\t\t\t\t\"Constructor has to be the first function call expect for library deployments.\"\n\t\t\t);\n\t\t}\n\t\telse if (test.call().kind == FunctionCall::Kind::Library)\n\t\t{\n\t\t\tsoltestAssert(\n\t\t\t\tdeploy(test.call().signature, 0, {}, libraries) && m_transactionSuccessful,\n\t\t\t\t\"Failed to deploy library \" + test.call().signature);\n\t\t\t// For convenience, in semantic tests we assume that an unqualified name like `L` is equivalent to one\n\t\t\t// with an empty source unit name (`:L`). This is fine because the compiler never uses unqualified\n\t\t\t// names in the Yul code it produces and does not allow `linkersymbol()` at all in inline assembly.\n\t\t\tlibraries[test.call().libraryFile + \":\" + test.call().signature] = m_contractAddress;\n\t\t\tcontinue;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (test.call().kind == FunctionCall::Kind::Constructor)\n\t\t\t\tdeploy(\"\", test.call().value.value, test.call().arguments.rawBytes(), libraries);\n\t\t\telse\n\t\t\t\tsoltestAssert(deploy(\"\", 0, bytes(), libraries), \"Failed to deploy contract.\");\n\t\t\tconstructed = true;\n\t\t}\n\n\t\tif (test.call().kind == FunctionCall::Kind::Constructor)\n\t\t{\n\t\t\tif (m_transactionSuccessful == test.call().expectations.failure)\n\t\t\t\tsuccess = false;\n\t\t\tif (success && !checkGasCostExpectation(test, _isYulRun))\n\t\t\t{\n\t\t\t\tsuccess = false;\n\t\t\t\tm_gasCostFailure = true;\n\t\t\t}\n\n\t\t\ttest.setFailure(!m_transactionSuccessful);\n\t\t\ttest.setRawBytes(bytes());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbytes output;\n\t\t\tif (test.call().kind == FunctionCall::Kind::LowLevel)\n\t\t\t\toutput = callLowLevel(test.call().arguments.rawBytes(), test.call().value.value);\n\t\t\telse if (test.call().kind == FunctionCall::Kind::Builtin)\n\t\t\t{\n\t\t\t\tstd::optional<bytes> builtinOutput = m_builtins.at(test.call().signature)(test.call());\n\t\t\t\tif (builtinOutput.has_value())\n\t\t\t\t{\n\t\t\t\t\tm_transactionSuccessful = true;\n\t\t\t\t\toutput = builtinOutput.value();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tm_transactionSuccessful = false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsoltestAssert(\n\t\t\t\t\tm_allowNonExistingFunctions ||\n\t\t\t\t\tm_compiler.interfaceSymbols(m_compiler.lastContractName(m_sources.mainSourceFile))[\"methods\"].contains(test.call().signature),\n\t\t\t\t\t\"The function \" + test.call().signature + \" is not known to the compiler\"\n\t\t\t\t);\n\n\t\t\t\toutput = callContractFunctionWithValueNoEncoding(\n\t\t\t\t\ttest.call().signature,\n\t\t\t\t\ttest.call().value.value,\n\t\t\t\t\ttest.call().arguments.rawBytes()\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tbool outputMismatch = (output != test.call().expectations.rawBytes());\n\t\t\tif (!outputMismatch && !checkGasCostExpectation(test, _isYulRun))\n\t\t\t{\n\t\t\t\tsuccess = false;\n\t\t\t\tm_gasCostFailure = true;\n\t\t\t}\n\n\t\t\t// Pre byzantium, it was not possible to return failure data, so we disregard\n\t\t\t// output mismatch for those EVM versions.\n\t\t\tif (test.call().expectations.failure && !m_transactionSuccessful && !m_evmVersion.supportsReturndata())\n\t\t\t\toutputMismatch = false;\n\t\t\tif (m_transactionSuccessful != !test.call().expectations.failure || outputMismatch)\n\t\t\t\tsuccess = false;\n\n\t\t\ttest.setFailure(!m_transactionSuccessful);\n\t\t\ttest.setRawBytes(std::move(output));\n\t\t\tif (test.call().kind != FunctionCall::Kind::LowLevel)\n\t\t\t\ttest.setContractABI(m_compiler.contractABI(m_compiler.lastContractName(m_sources.mainSourceFile)));\n\t\t}\n\n\t\tstd::vector<std::string> effects;\n\t\tfor (SideEffectHook const& hook: m_sideEffectHooks)\n\t\t\teffects += hook(test.call());\n\t\ttest.setSideEffects(std::move(effects));\n\n\t\tsuccess &= test.call().expectedSideEffects == test.call().actualSideEffects;\n\t}\n\n\tif (!success)\n\t{\n\t\tAnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << \"Expected result:\" << std::endl;\n\t\tfor (TestFunctionCall const& test: m_tests)\n\t\t{\n\t\t\tErrorReporter errorReporter;\n\t\t\t_stream << test.format(\n\t\t\t\terrorReporter,\n\t\t\t\t_linePrefix,\n\t\t\t\tTestFunctionCall::RenderMode::ExpectedValuesExpectedGas,\n\t\t\t\t_formatted,\n\t\t\t\t/* _interactivePrint */ true\n\t\t\t) << std::endl;\n\t\t\t_stream << errorReporter.format(_linePrefix, _formatted);\n\t\t}\n\t\t_stream << std::endl;\n\t\tAnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << \"Obtained result:\" << std::endl;\n\t\tfor (TestFunctionCall const& test: m_tests)\n\t\t{\n\t\t\tErrorReporter errorReporter;\n\t\t\t_stream << test.format(\n\t\t\t\terrorReporter,\n\t\t\t\t_linePrefix,\n\t\t\t\tm_gasCostFailure ? TestFunctionCall::RenderMode::ExpectedValuesActualGas : TestFunctionCall::RenderMode::ActualValuesExpectedGas,\n\t\t\t\t_formatted,\n\t\t\t\t/* _interactivePrint */ true\n\t\t\t) << std::endl;\n\t\t\t_stream << errorReporter.format(_linePrefix, _formatted);\n\t\t}\n\t\tAnsiColorized(_stream, _formatted, {BOLD, RED})\n\t\t\t<< _linePrefix << std::endl\n\t\t\t<< _linePrefix << \"Attention: Updates on the test will apply the detected format displayed.\" << std::endl;\n\t\tif (_isYulRun && m_testCaseWantsLegacyRun)\n\t\t{\n\t\t\t_stream << _linePrefix << std::endl << _linePrefix;\n\t\t\tAnsiColorized(_stream, _formatted, {RED_BACKGROUND}) << \"Note that the test passed without Yul.\";\n\t\t\t_stream << std::endl;\n\t\t}\n\t\telse if (!_isYulRun && m_testCaseWantsYulRun)\n\t\t\tAnsiColorized(_stream, _formatted, {BOLD, YELLOW})\n\t\t\t\t<< _linePrefix << std::endl\n\t\t\t\t<< _linePrefix << \"Note that the test also has to pass via Yul.\" << std::endl;\n\t\treturn TestResult::Failure;\n\t}\n\n\treturn TestResult::Success;\n}\n\nTestCase::TestResult SemanticTest::tryRunTestWithYulOptimizer(\n\tstd::ostream& _stream,\n\tstd::string const& _linePrefix,\n\tbool _formatted,\n\tbool _isSSACFGRun\n)\n{\n\tTestResult result{};\n\tfor (auto requiresYulOptimizer: {\n\t\tRequiresYulOptimizer::False,\n\t\tRequiresYulOptimizer::MinimalStack,\n\t\tRequiresYulOptimizer::Full,\n\t})\n\t{\n\t\tScopedSaveAndRestore optimizerSettings(\n\t\t\tm_optimiserSettings,\n\t\t\toptimizerSettingsFor(requiresYulOptimizer)\n\t\t);\n\n\t\ttry\n\t\t{\n\t\t\tresult = runTest(_stream, _linePrefix, _formatted, true /* _isYulRun */, _isSSACFGRun);\n\t\t}\n\t\tcatch (yul::StackTooDeepError const&)\n\t\t{\n\t\t\tif (requiresYulOptimizer == RequiresYulOptimizer::Full)\n\t\t\t\tthrow;\n\t\t\telse\n\t\t\t\tcontinue;\n\t\t}\n\n\t\tif (m_requiresYulOptimizer != requiresYulOptimizer && result != TestResult::FatalError)\n\t\t{\n\t\t\tsoltestAssert(result == TestResult::Success || result == TestResult::Failure);\n\n\t\t\tAnsiColorized(_stream, _formatted, {BOLD, YELLOW})\n\t\t\t\t<< _linePrefix << std::endl\n\t\t\t\t<< _linePrefix << \"requiresYulOptimizer is set to \" << m_requiresYulOptimizer\n\t\t\t\t<< \" but should be \" << requiresYulOptimizer << std::endl;\n\t\t\tm_requiresYulOptimizer = requiresYulOptimizer;\n\t\t\treturn TestResult::Failure;\n\t\t}\n\n\t\treturn result;\n\t}\n\tunreachable();\n}\n\nbool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _compileViaYul) const\n{\n\tstd::string setting = m_isSSACFGRun\n\t\t? (m_optimiserSettings == OptimiserSettings::full() ? \"ssaCFGOptimized\"s : \"ssaCFG\"s)\n\t\t: (_compileViaYul ? \"ir\"s : \"legacy\"s) +\n\t\t  (m_optimiserSettings == OptimiserSettings::full() ? \"Optimized\" : \"\");\n\n\tsoltestAssert(\n\t\tio_test.call().expectations.gasUsedExcludingCode.count(setting) ==\n\t\tio_test.call().expectations.gasUsedForCodeDeposit.count(setting)\n\t);\n\n\tbool uninteresting =\n\t\tm_gasUsed < m_enforceGasCostMinValue || // gas used less than threshold for enforcing feature\n\t\tm_gasUsed >= InitialGas || // test has used up all available gas (test will fail anyway)\n\t\tsetting == \"ir\" ||\n\t\tsetting == \"ssaCFG\" ||\n\t\tio_test.call().kind == FunctionCall::Kind::Builtin; // isoltest builtin e.g. `smokeTest` or `storageEmpty`\n\tbool gasValueMissing = !io_test.call().expectations.gasUsedExcludingCode.contains(setting);\n\tif (!m_enforceGasCost || (gasValueMissing && uninteresting))\n\t\treturn true;\n\n\tsolAssert(!m_runWithABIEncoderV1Only);\n\n\t// NOTE: Cost excluding code is unlikely to be negative but it may still be possible due to refunds.\n\t// We'll deal with it when we actually have a test case like that.\n\tsolUnimplementedAssert(m_gasUsed >= m_gasUsedForCodeDeposit);\n\tio_test.setGasCostExcludingCode(setting, m_gasUsed - m_gasUsedForCodeDeposit);\n\tio_test.setCodeDepositGasCost(setting, m_gasUsedForCodeDeposit);\n\n\treturn\n\t\tio_test.call().expectations.gasUsedExcludingCode.count(setting) > 0 &&\n\t\tm_gasUsed - m_gasUsedForCodeDeposit == io_test.call().expectations.gasUsedExcludingCode.at(setting) &&\n\t\tm_gasUsedForCodeDeposit == io_test.call().expectations.gasUsedForCodeDeposit.at(setting);\n}\n\nvoid SemanticTest::printSource(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const\n{\n\tif (m_sources.sources.empty())\n\t\treturn;\n\n\tbool outputNames = (m_sources.sources.size() - m_sources.externalSources.size() != 1 || !m_sources.sources.begin()->first.empty());\n\n\tstd::set<std::string> externals;\n\tfor (auto const& [name, path]: m_sources.externalSources)\n\t{\n\t\texternals.insert(name);\n\t\tstd::string externalSource;\n\t\tif (name == path)\n\t\t\texternalSource = name;\n\t\telse\n\t\t\texternalSource = name + \"=\" + path.generic_string();\n\n\t\tif (_formatted)\n\t\t\t_stream << _linePrefix  << formatting::CYAN << \"==== ExternalSource: \" << externalSource << \" ====\"s << formatting::RESET << std::endl;\n\t\telse\n\t\t\t_stream << _linePrefix << \"==== ExternalSource: \" << externalSource << \" ====\"s << std::endl;\n\t}\n\n\tfor (auto const& [name, source]: m_sources.sources)\n\t\tif (externals.find(name) == externals.end())\n\t\t{\n\t\t\tif (_formatted)\n\t\t\t{\n\t\t\t\tif (source.empty())\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (outputNames)\n\t\t\t\t\t_stream << _linePrefix << formatting::CYAN << \"==== Source: \" << name\n\t\t\t\t\t\t\t<< \" ====\" << formatting::RESET << std::endl;\n\n\t\t\t\tstd::vector<char const*> sourceFormatting(source.length(), formatting::RESET);\n\t\t\t\t_stream << _linePrefix << sourceFormatting.front() << source.front();\n\t\t\t\tfor (size_t i = 1; i < source.length(); i++)\n\t\t\t\t{\n\t\t\t\t\tif (sourceFormatting[i] != sourceFormatting[i - 1])\n\t\t\t\t\t\t_stream << sourceFormatting[i];\n\t\t\t\t\tif (source[i] != '\\n')\n\t\t\t\t\t\t_stream << source[i];\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t_stream << formatting::RESET << std::endl;\n\t\t\t\t\t\tif (i + 1 < source.length())\n\t\t\t\t\t\t\t_stream << _linePrefix << sourceFormatting[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t_stream << formatting::RESET;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (outputNames)\n\t\t\t\t\tprintPrefixed(_stream, \"==== Source: \" + name + \" ====\", _linePrefix);\n\t\t\t\tprintPrefixed(_stream, source, _linePrefix);\n\t\t\t}\n\t\t}\n}\n\nvoid SemanticTest::printUpdatedExpectations(std::ostream& _stream, std::string const&) const\n{\n\tfor (TestFunctionCall const& test: m_tests)\n\t\t_stream << test.format(\n\t\t\t\"\",\n\t\t\tm_gasCostFailure ? TestFunctionCall::RenderMode::ExpectedValuesActualGas : TestFunctionCall::RenderMode::ActualValuesExpectedGas,\n\t\t\t/* _highlight = */ false\n\t\t) << std::endl;\n}\n\nvoid SemanticTest::printUpdatedSettings(std::ostream& _stream, std::string const& _linePrefix)\n{\n\tauto& settings = m_reader.settings();\n\tif (settings.empty() && m_requiresYulOptimizer == RequiresYulOptimizer::False)\n\t\treturn;\n\n\t_stream << _linePrefix << \"// ====\" << std::endl;\n\tif (m_requiresYulOptimizer != RequiresYulOptimizer::False)\n\t\t_stream << _linePrefix << \"// requiresYulOptimizer: \" << m_requiresYulOptimizer << std::endl;\n\n\tfor (auto const& [settingName, settingValue]: settings)\n\t\tif (settingName != \"requiresYulOptimizer\")\n\t\t\t_stream << _linePrefix << \"// \" << settingName << \": \" << settingValue<< std::endl;\n}\n\nvoid SemanticTest::parseExpectations(std::istream& _stream)\n{\n\tm_tests += TestFileParser{_stream, m_builtins}.parseFunctionCalls(m_lineOffset);\n}\n\nbool SemanticTest::deploy(\n\tstd::string const& _contractName,\n\tu256 const& _value,\n\tbytes const& _arguments,\n\tstd::map<std::string, solidity::test::Address> const& _libraries\n)\n{\n\tauto output = compileAndRunWithoutCheck(m_sources.sources, _value, _contractName, _arguments, _libraries, m_sources.mainSourceFile);\n\treturn !output.empty() && m_transactionSuccessful;\n}\n"
  },
  {
    "path": "test/libsolidity/SemanticTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n\n#pragma once\n\n#include <test/libsolidity/util/TestFileParser.h>\n#include <test/libsolidity/util/TestFunctionCall.h>\n#include <test/libsolidity/SolidityExecutionFramework.h>\n#include <test/libsolidity/AnalysisFramework.h>\n#include <test/TestCase.h>\n#include <liblangutil/Exceptions.h>\n#include <libsolutil/AnsiColorized.h>\n\n#include <iosfwd>\n#include <string>\n#include <vector>\n#include <utility>\n\nnamespace solidity::frontend::test\n{\n\nstruct AnnotatedEventSignature\n{\n\tstd::string signature;\n\tstd::vector<std::string> indexedTypes;\n\tstd::vector<std::string> nonIndexedTypes;\n};\n\nenum class RequiresYulOptimizer\n{\n\tFalse,\n\tMinimalStack,\n\tFull,\n};\n\nstd::ostream& operator<<(std::ostream& _output, RequiresYulOptimizer _requiresYulOptimizer);\n\n/**\n * Class that represents a semantic test (or end-to-end test) and allows running it as part of the\n * boost unit test environment or isoltest. It reads the Solidity source and an additional comment\n * section from the given file. This comment section should define a set of functions to be called\n * and an expected result they return after being executed.\n */\nclass SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrictedTestCase\n{\npublic:\n\tstatic std::unique_ptr<TestCase> create(Config const& _options)\n\t{\n\t\treturn std::make_unique<SemanticTest>(\n\t\t\t_options.filename,\n\t\t\t_options.evmVersion,\n\t\t\t_options.eofVersion,\n\t\t\t_options.vmPaths,\n\t\t\t_options.enforceGasCost,\n\t\t\t_options.enforceGasCostMinValue\n\t\t);\n\t}\n\n\texplicit SemanticTest(\n\t\tstd::string const& _filename,\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tstd::vector<boost::filesystem::path> const& _vmPaths,\n\t\tbool _enforceGasCost = false,\n\t\tu256 _enforceGasCostMinValue = 100000\n\t);\n\n\tTestResult run(std::ostream& _stream, std::string const& _linePrefix = \"\", bool _formatted = false) override;\n\tvoid printSource(std::ostream &_stream, std::string const& _linePrefix = \"\", bool _formatted = false) const override;\n\tvoid printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix = \"\") const override;\n\tvoid printUpdatedSettings(std::ostream& _stream, std::string const& _linePrefix = \"\") override;\n\n\t/// Instantiates a test file parser that parses the additional comment section at the end of\n\t/// the input stream \\param _stream. Each function call is represented using a `FunctionCallTest`\n\t/// and added to the list of call to be executed when `run()` is called.\n\t/// Throws if parsing expectations failed.\n\tvoid parseExpectations(std::istream& _stream);\n\n\t/// Compiles and deploys currently held source.\n\t/// Returns true if deployment was successful, false otherwise.\n\tbool deploy(std::string const& _contractName, u256 const& _value, bytes const& _arguments, std::map<std::string, solidity::test::Address> const& _libraries = {});\n\nprivate:\n\tTestResult runTest(\n\t\tstd::ostream& _stream,\n\t\tstd::string const& _linePrefix,\n\t\tbool _formatted,\n\t\tbool _isYulRun,\n\t\tbool _isSSACFGRun = false\n\t);\n\tTestResult tryRunTestWithYulOptimizer(\n\t\tstd::ostream& _stream,\n\t\tstd::string const& _linePrefix,\n\t\tbool _formatted,\n\t\tbool _isSSACFGRun = false\n\t);\n\tbool checkGasCostExpectation(TestFunctionCall& io_test, bool _compileViaYul) const;\n\tstd::map<std::string, Builtin> makeBuiltins();\n\tstd::vector<SideEffectHook> makeSideEffectHooks() const;\n\tstd::vector<std::string> eventSideEffectHook(FunctionCall const&) const;\n\tstd::optional<AnnotatedEventSignature> matchEvent(util::h256 const& hash) const;\n\tstatic std::string formatEventParameter(std::optional<AnnotatedEventSignature> _signature, bool _indexed, size_t _index, bytes const& _data);\n\n\tOptimiserSettings optimizerSettingsFor(RequiresYulOptimizer _requiresYulOptimizer);\n\n\tSourceMap m_sources;\n\tstd::size_t m_lineOffset;\n\tstd::vector<TestFunctionCall> m_tests;\n\tstd::map<std::string, Builtin> const m_builtins;\n\tstd::vector<SideEffectHook> const m_sideEffectHooks;\n\tbool m_testCaseWantsYulRun = true;\n\tbool m_testCaseWantsLegacyRun = true;\n\tbool m_testCaseWantsSSACFGRun = false;\n\tbool m_isSSACFGRun = false;\n\tbool m_runWithABIEncoderV1Only = false;\n\tbool m_allowNonExistingFunctions = false;\n\tbool m_gasCostFailure = false;\n\tbool m_enforceGasCost = false;\n\tRequiresYulOptimizer m_requiresYulOptimizer{};\n\tu256 m_enforceGasCostMinValue;\n};\n\n}\n"
  },
  {
    "path": "test/libsolidity/SolidityCompiler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n */\n/**\n * Unit tests for the compiler itself.\n */\n\n#include <test/libsolidity/AnalysisFramework.h>\n#include <test/Metadata.h>\n#include <test/Common.h>\n\n#include <boost/test/unit_test.hpp>\n\nusing namespace solidity::test;\n\nnamespace solidity::frontend::test\n{\n\nclass SolidityCompilerFixture: protected AnalysisFramework\n{\n\tvoid setupCompiler(CompilerStack& _compiler) override\n\t{\n\t\tAnalysisFramework::setupCompiler(_compiler);\n\n\t\t// FIXME: This test was probably supposed to respect CommonOptions::get().optimize but\n\t\t// due to a bug it was always running with optimizer disabled and it does not pass with it.\n\t\t_compiler.setOptimiserSettings(false);\n\t}\n};\n\nBOOST_FIXTURE_TEST_SUITE(SolidityCompiler, SolidityCompilerFixture)\n\n// TODO: Implement EOF counterpart\nBOOST_AUTO_TEST_CASE(does_not_include_creation_time_only_internal_functions, *boost::unit_test::precondition(nonEOF()))\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tuint x;\n\t\t\tconstructor() { f(); }\n\t\t\tfunction f() internal { unchecked { for (uint i = 0; i < 10; ++i) x += 3 + i; } }\n\t\t}\n\t)\";\n\n\trunFramework(sourceCode, PipelineStage::Compilation);\n\tBOOST_REQUIRE_MESSAGE(\n\t\tpipelineSuccessful(),\n\t\t\"Contract compilation failed:\\n\" + formatErrors(filteredErrors(), true /* _colored */)\n\t);\n\n\tbytes const& creationBytecode = solidity::test::bytecodeSansMetadata(compiler().object(\"C\").bytecode);\n\tbytes const& runtimeBytecode = solidity::test::bytecodeSansMetadata(compiler().runtimeObject(\"C\").bytecode);\n\tBOOST_CHECK(creationBytecode.size() >= 90);\n\tBOOST_CHECK(creationBytecode.size() <= 120);\n\tauto evmVersion = solidity::test::CommonOptions::get().evmVersion();\n\tunsigned threshold = evmVersion.hasPush0() ? 9 : 10;\n\tBOOST_CHECK(runtimeBytecode.size() >= threshold);\n\tBOOST_CHECK(runtimeBytecode.size() <= 30);\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n}\n"
  },
  {
    "path": "test/libsolidity/SolidityEndToEndTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @author Gav Wood <g@ethdev.com>\n * @date 2014\n * Unit tests for the solidity expression compiler, testing the behaviour of the code.\n */\n\n#include <test/libsolidity/SolidityExecutionFramework.h>\n\n#include <test/Common.h>\n#include <test/EVMHost.h>\n\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/EVMVersion.h>\n\n#include <libevmasm/Assembly.h>\n\n#include <libsolutil/Keccak256.h>\n#include <libsolutil/ErrorCodes.h>\n\n#include <libyul/Exceptions.h>\n\n#include <boost/test/unit_test.hpp>\n\n#include <range/v3/view/transform.hpp>\n\n#include <functional>\n#include <numeric>\n#include <string>\n#include <tuple>\n\nusing namespace std::placeholders;\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::test;\nusing namespace solidity::langutil;\n\n#define ALSO_VIA_YUL(CODE)                                      \\\n{                                                               \\\n\tm_compileViaYul = false;                                    \\\n\tRUN_AND_RERUN_WITH_OPTIMIZER_ON_STACK_ERROR(CODE)           \\\n                                                                \\\n\tm_compileViaYul = true;                                     \\\n\treset();                                                    \\\n\tRUN_AND_RERUN_WITH_OPTIMIZER_ON_STACK_ERROR(CODE)           \\\n}\n\n#define RUN_AND_RERUN_WITH_OPTIMIZER_ON_STACK_ERROR(CODE)       \\\n{                                                               \\\n\ttry                                                         \\\n\t{ CODE }                                                    \\\n\tcatch (yul::StackTooDeepError const&)                       \\\n\t{                                                           \\\n\t\tif (m_optimiserSettings == OptimiserSettings::full())   \\\n\t\t\tthrow;                                              \\\n                                                                \\\n\t\treset();                                                \\\n\t\tm_optimiserSettings = OptimiserSettings::full();        \\\n\t\t{ CODE }                                                \\\n\t}                                                           \\\n}\n\n\nnamespace solidity::frontend::test\n{\n\nstruct SolidityEndToEndTestExecutionFramework: public SolidityExecutionFramework\n{\n};\n\nBOOST_FIXTURE_TEST_SUITE(SolidityEndToEndTest, SolidityEndToEndTestExecutionFramework)\n\nBOOST_AUTO_TEST_CASE(creation_code_optimizer)\n{\n\tstd::string codeC = R\"(\n\t\tcontract C {\n\t\t\tconstructor(uint x) {\n\t\t\tif (x == 0xFFFFFFFFFFFFFFFF42)\n\t\t\t\trevert();\n\t\t\t}\n\t\t}\n\t)\";\n\tstd::string codeD = R\"(\n\t\tcontract D {\n\t\t\tfunction f() public pure returns (bytes memory) {\n\t\t\t\treturn type(C).creationCode;\n\t\t\t}\n\t\t}\n\t)\";\n\n\tm_metadataHash = CompilerStack::MetadataHash::None;\n\tALSO_VIA_YUL({\n\t\tbytes bytecodeC = compileContract(codeC);\n\t\treset();\n\t\tcompileAndRun(codeC + codeD);\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(0x20, bytecodeC.size()) + encode(bytecodeC, false));\n\t})\n}\n\nunsigned constexpr roundTo32(unsigned _num)\n{\n\treturn (_num + 31) / 32 * 32;\n}\n\nBOOST_AUTO_TEST_CASE(exp_operator)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint a) public returns(uint d) { return 2 ** a; }\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode);\n\ttestContractAgainstCppOnRange(\"f(uint256)\", [](u256 const& a) -> u256 { return u256(1 << a.convert_to<int>()); }, 0, 16);\n}\n\nBOOST_AUTO_TEST_CASE(exp_zero)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint a) public returns(uint d) { return a ** 0; }\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode);\n\ttestContractAgainstCppOnRange(\"f(uint256)\", [](u256 const&) -> u256 { return u256(1); }, 0, 16);\n}\n\n/* TODO let's add this back when I figure out the correct type conversion.\nBOOST_AUTO_TEST_CASE(conditional_expression_string_literal)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(bool cond) public returns (bytes32) {\n\t\t\t\treturn cond ? \"true\" : \"false\";\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode);\n\tABI_CHECK(callContractFunction(\"f(bool)\", true), encodeArgs(string(\"true\", 4)));\n\tABI_CHECK(callContractFunction(\"f(bool)\", false), encodeArgs(string(\"false\", 5)));\n}\n*/\n\nBOOST_AUTO_TEST_CASE(recursive_calls)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint n) public returns(uint nfac) {\n\t\t\t\tif (n <= 1) return 1;\n\t\t\t\telse return n * f(n - 1);\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\t\tstd::function<u256(u256)> recursive_calls_cpp = [&recursive_calls_cpp](u256 const& n) -> u256\n\t\t{\n\t\t\tif (n <= 1)\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn n * recursive_calls_cpp(n - 1);\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", recursive_calls_cpp, 0, 5);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(while_loop)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint n) public returns(uint nfac) {\n\t\t\t\tnfac = 1;\n\t\t\t\tuint i = 2;\n\t\t\t\twhile (i <= n) nfac *= i++;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tauto while_loop_cpp = [](u256 const& n) -> u256\n\t\t{\n\t\t\tu256 nfac = 1;\n\t\t\tu256 i = 2;\n\t\t\twhile (i <= n)\n\t\t\t\tnfac *= i++;\n\n\t\t\treturn nfac;\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", while_loop_cpp, 0, 5);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(do_while_loop)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint n) public returns(uint nfac) {\n\t\t\t\tnfac = 1;\n\t\t\t\tuint i = 2;\n\t\t\t\tdo { nfac *= i++; } while (i <= n);\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tauto do_while_loop_cpp = [](u256 const& n) -> u256\n\t\t{\n\t\t\tu256 nfac = 1;\n\t\t\tu256 i = 2;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tnfac *= i++;\n\t\t\t}\n\t\t\twhile (i <= n);\n\n\t\t\treturn nfac;\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", do_while_loop_cpp, 0, 5);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(do_while_loop_multiple_local_vars)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint x) public pure returns(uint r) {\n\t\t\t\tuint i = 0;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tuint z = x * 2;\n\t\t\t\t\tif (z < 4) break;\n\t\t\t\t\telse {\n\t\t\t\t\t\tuint k = z + 1;\n\t\t\t\t\t\tif (k < 8) {\n\t\t\t\t\t\t\tx++;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (z > 12) return 0;\n\t\t\t\t\tx++;\n\t\t\t\t\ti++;\n\t\t\t\t} while (true);\n\t\t\t\treturn 42;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tauto do_while = [](u256 n) -> u256\n\t\t{\n\t\t\tu256 i = 0;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tu256 z = n * 2;\n\t\t\t\tif (z < 4) break;\n\t\t\t\telse {\n\t\t\t\t\tu256 k = z + 1;\n\t\t\t\t\tif (k < 8) {\n\t\t\t\t\t\tn++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (z > 12) return 0;\n\t\t\t\tn++;\n\t\t\t\ti++;\n\t\t\t} while (true);\n\t\t\treturn 42;\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", do_while, 0, 12);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(nested_loops)\n{\n\t// tests that break and continue statements in nested loops jump to the correct place\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint x) public returns(uint y) {\n\t\t\t\twhile (x > 1) {\n\t\t\t\t\tif (x == 10) break;\n\t\t\t\t\twhile (x > 5) {\n\t\t\t\t\t\tif (x == 8) break;\n\t\t\t\t\t\tx--;\n\t\t\t\t\t\tif (x == 6) continue;\n\t\t\t\t\t\treturn x;\n\t\t\t\t\t}\n\t\t\t\t\tx--;\n\t\t\t\t\tif (x == 3) continue;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn x;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tauto nested_loops_cpp = [](u256 n) -> u256\n\t\t{\n\t\t\twhile (n > 1)\n\t\t\t{\n\t\t\t\tif (n == 10)\n\t\t\t\t\tbreak;\n\t\t\t\twhile (n > 5)\n\t\t\t\t{\n\t\t\t\t\tif (n == 8)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tn--;\n\t\t\t\t\tif (n == 6)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\treturn n;\n\t\t\t\t}\n\t\t\t\tn--;\n\t\t\t\tif (n == 3)\n\t\t\t\t\tcontinue;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn n;\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", nested_loops_cpp, 0, 12);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(nested_loops_multiple_local_vars)\n{\n\t// tests that break and continue statements in nested loops jump to the correct place\n\t// and free local variables properly\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint x) public returns(uint y) {\n\t\t\t\twhile (x > 0) {\n\t\t\t\t\tuint z = x + 10;\n\t\t\t\t\tuint k = z + 1;\n\t\t\t\t\tif (k > 20) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tuint p = 100;\n\t\t\t\t\t\tk += p;\n\t\t\t\t\t}\n\t\t\t\t\tif (k > 15) {\n\t\t\t\t\t\tx--;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tuint t = 1000;\n\t\t\t\t\t\tx += t;\n\t\t\t\t\t}\n\t\t\t\t\twhile (k > 10) {\n\t\t\t\t\t\tuint m = k - 1;\n\t\t\t\t\t\tif (m == 10) return x;\n\t\t\t\t\t\treturn k;\n\t\t\t\t\t\tuint h = 10000;\n\t\t\t\t\t\tz += h;\n\t\t\t\t\t}\n\t\t\t\t\tx--;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn x;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tauto nested_loops_cpp = [](u256 n) -> u256\n\t\t{\n\t\t\twhile (n > 0)\n\t\t\t{\n\t\t\t\tu256 z = n + 10;\n\t\t\t\tu256 k = z + 1;\n\t\t\t\tif (k > 20) break;\n\t\t\t\tif (k > 15) {\n\t\t\t\t\tn--;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\twhile (k > 10)\n\t\t\t\t{\n\t\t\t\t\tu256 m = k - 1;\n\t\t\t\t\tif (m == 10) return n;\n\t\t\t\t\treturn k;\n\t\t\t\t}\n\t\t\t\tn--;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn n;\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", nested_loops_cpp, 0, 12);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(for_loop_multiple_local_vars)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint x) public pure returns(uint r) {\n\t\t\t\tfor (uint i = 0; i < 12; i++)\n\t\t\t\t{\n\t\t\t\t\tuint z = x + 1;\n\t\t\t\t\tif (z < 4) break;\n\t\t\t\t\telse {\n\t\t\t\t\t\tuint k = z * 2;\n\t\t\t\t\t\tif (i + k < 10) {\n\t\t\t\t\t\t\tx++;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (z > 8) return 0;\n\t\t\t\t\tx++;\n\t\t\t\t}\n\t\t\t\treturn 42;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tauto for_loop = [](u256 n) -> u256\n\t\t{\n\t\t\tfor (u256 i = 0; i < 12; i++)\n\t\t\t{\n\t\t\t\tu256 z = n + 1;\n\t\t\t\tif (z < 4) break;\n\t\t\t\telse {\n\t\t\t\t\tu256 k = z * 2;\n\t\t\t\t\tif (i + k < 10) {\n\t\t\t\t\t\tn++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (z > 8) return 0;\n\t\t\t\tn++;\n\t\t\t}\n\t\t\treturn 42;\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", for_loop, 0, 12);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(nested_for_loop_multiple_local_vars)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint x) public pure returns(uint r) {\n\t\t\t\tfor (uint i = 0; i < 5; i++)\n\t\t\t\t{\n\t\t\t\t\tuint z = x + 1;\n\t\t\t\t\tif (z < 3) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tuint p = z + 2;\n\t\t\t\t\t}\n\t\t\t\t\tfor (uint j = 0; j < 5; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tuint k = z * 2;\n\t\t\t\t\t\tif (j + k < 8) {\n\t\t\t\t\t\t\tx++;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\tuint t = z * 3;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tx++;\n\t\t\t\t\t\tif (x > 20) {\n\t\t\t\t\t\t\treturn 84;\n\t\t\t\t\t\t\tuint h = x + 42;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (x > 30) {\n\t\t\t\t\t\treturn 42;\n\t\t\t\t\t\tuint b = 0xcafe;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn 42;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tauto for_loop = [](u256 n) -> u256\n\t\t{\n\t\t\tfor (u256 i = 0; i < 5; i++)\n\t\t\t{\n\t\t\t\tu256 z = n + 1;\n\t\t\t\tif (z < 3) break;\n\t\t\t\tfor (u256 j = 0; j < 5; j++)\n\t\t\t\t{\n\t\t\t\t\tu256 k = z * 2;\n\t\t\t\t\tif (j + k < 8) {\n\t\t\t\t\t\tn++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tn++;\n\t\t\t\t\tif (n > 20) return 84;\n\t\t\t\t}\n\t\t\t\tif (n > 30) return 42;\n\t\t\t}\n\t\t\treturn 42;\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", for_loop, 0, 12);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(for_loop)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint n) public returns(uint nfac) {\n\t\t\t\tnfac = 1;\n\t\t\t\tuint i;\n\t\t\t\tfor (i = 2; i <= n; i++)\n\t\t\t\t\tnfac *= i;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tauto for_loop_cpp = [](u256 const& n) -> u256\n\t\t{\n\t\t\tu256 nfac = 1;\n\t\t\tfor (auto i = 2; i <= n; i++)\n\t\t\t\tnfac *= i;\n\t\t\treturn nfac;\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", for_loop_cpp, 0, 5);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(for_loop_simple_init_expr)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint n) public returns(uint nfac) {\n\t\t\t\tnfac = 1;\n\t\t\t\tuint256 i;\n\t\t\t\tfor (i = 2; i <= n; i++)\n\t\t\t\t\tnfac *= i;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tauto for_loop_simple_init_expr_cpp = [](u256 const& n) -> u256\n\t\t{\n\t\t\tu256 nfac = 1;\n\t\t\tu256 i;\n\t\t\tfor (i = 2; i <= n; i++)\n\t\t\t\tnfac *= i;\n\t\t\treturn nfac;\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", for_loop_simple_init_expr_cpp, 0, 5);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(for_loop_break_continue)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint n) public returns (uint r)\n\t\t\t{\n\t\t\t\tuint i = 1;\n\t\t\t\tuint k = 0;\n\t\t\t\tfor (i *= 5; k < n; i *= 7)\n\t\t\t\t{\n\t\t\t\t\tk++;\n\t\t\t\t\ti += 4;\n\t\t\t\t\tif (n % 3 == 0)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\ti += 9;\n\t\t\t\t\tif (n % 2 == 0)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\ti += 19;\n\t\t\t\t}\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tauto breakContinue = [](u256 const& n) -> u256\n\t\t{\n\t\t\tu256 i = 1;\n\t\t\tu256 k = 0;\n\t\t\tfor (i *= 5; k < n; i *= 7)\n\t\t\t{\n\t\t\t\tk++;\n\t\t\t\ti += 4;\n\t\t\t\tif (n % 3 == 0)\n\t\t\t\t\tbreak;\n\t\t\t\ti += 9;\n\t\t\t\tif (n % 2 == 0)\n\t\t\t\t\tcontinue;\n\t\t\t\ti += 19;\n\t\t\t}\n\t\t\treturn i;\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", breakContinue, 0, 10);\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(short_circuiting)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction run(uint x) public returns(uint y) {\n\t\t\t\tx == 0 || ((x = 8) > 0);\n\t\t\t\treturn x;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tauto short_circuiting_cpp = [](u256 n) -> u256\n\t\t{\n\t\t\t(void)(n == 0 || (n = 8) > 0);\n\t\t\treturn n;\n\t\t};\n\n\t\ttestContractAgainstCppOnRange(\"run(uint256)\", short_circuiting_cpp, 0, 2);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(high_bits_cleaning)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction run() public returns(uint256 y) {\n\t\t\t\tunchecked {\n\t\t\t\t\tuint32 t = uint32(0xffffffff);\n\t\t\t\t\tuint32 x = t + 10;\n\t\t\t\t\tif (x >= 0xffffffff) return 0;\n\t\t\t\t\treturn x;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode);\n\tauto high_bits_cleaning_cpp = []() -> u256\n\t{\n\t\tuint32_t t = uint32_t(0xffffffff);\n\t\tuint32_t x = t + 10;\n\t\tif (x >= 0xffffffff)\n\t\t\treturn 0;\n\t\treturn x;\n\t};\n\ttestContractAgainstCpp(\"run()\", high_bits_cleaning_cpp);\n}\n\nBOOST_AUTO_TEST_CASE(sign_extension)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction run() public returns(uint256 y) {\n\t\t\t\tunchecked {\n\t\t\t\t\tint64 x = -int32(int64(0xff));\n\t\t\t\t\tif (x >= 0xff) return 0;\n\t\t\t\t\treturn 0 - uint256(int256(x));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode);\n\tauto sign_extension_cpp = []() -> u256\n\t{\n\t\tint64_t x = -int32_t(0xff);\n\t\tif (x >= 0xff)\n\t\t\treturn 0;\n\t\treturn u256(x) * -1;\n\t};\n\ttestContractAgainstCpp(\"run()\", sign_extension_cpp);\n}\n\nBOOST_AUTO_TEST_CASE(small_unsigned_types)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction run() public returns(uint256 y) {\n\t\t\t\tunchecked {\n\t\t\t\t\tuint32 t = uint32(0xffffff);\n\t\t\t\t\tuint32 x = t * 0xffffff;\n\t\t\t\t\treturn x / 0x100;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode);\n\tauto small_unsigned_types_cpp = []() -> u256\n\t{\n\t\tuint32_t t = uint32_t(0xffffff);\n\t\tuint32_t x = t * 0xffffff;\n\t\treturn x / 0x100;\n\t};\n\ttestContractAgainstCpp(\"run()\", small_unsigned_types_cpp);\n}\n\nBOOST_AUTO_TEST_CASE(mapping_state_inc_dec)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tuint value;\n\t\t\tmapping(uint => uint) table;\n\t\t\tfunction f(uint x) public returns (uint y) {\n\t\t\t\tvalue = x;\n\t\t\t\tif (x > 0) table[++value] = 8;\n\t\t\t\tif (x > 1) value--;\n\t\t\t\tif (x > 2) table[value]++;\n\t\t\t\ttable[value] += 10;\n\t\t\t\treturn --table[value++];\n\t\t\t}\n\t\t}\n\t)\";\n\n\tu256 value;\n\tstd::map<u256, u256> table;\n\tauto f = [&](u256 const& _x) -> u256\n\t{\n\t\tvalue = _x;\n\t\tif (_x > 0)\n\t\t\ttable[++value] = 8;\n\t\tif (_x > 1)\n\t\t\tvalue --;\n\t\tif (_x > 2)\n\t\t\ttable[value]++;\n\t\ttable[value] += 10;\n\t\treturn --table[value++];\n\t};\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\t\tvalue = 0;\n\t\ttable.clear();\n\n\t\ttestContractAgainstCppOnRange(\"f(uint256)\", f, 0, 5);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(multi_level_mapping)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tmapping(uint => mapping(uint => uint)) table;\n\t\t\tfunction f(uint x, uint y, uint z) public returns (uint w) {\n\t\t\t\tif (z == 0) return table[x][y];\n\t\t\t\telse return table[x][y] = z;\n\t\t\t}\n\t\t}\n\t)\";\n\tstd::map<u256, std::map<u256, u256>> table;\n\tauto f = [&](u256 const& _x, u256 const& _y, u256 const& _z) -> u256\n\t{\n\t\tif (_z == 0) return table[_x][_y];\n\t\telse return table[_x][_y] = _z;\n\t};\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\t\ttable.clear();\n\n\t\ttestContractAgainstCpp(\"f(uint256,uint256,uint256)\", f, u256(4), u256(5), u256(0));\n\t\ttestContractAgainstCpp(\"f(uint256,uint256,uint256)\", f, u256(5), u256(4), u256(0));\n\t\ttestContractAgainstCpp(\"f(uint256,uint256,uint256)\", f, u256(4), u256(5), u256(9));\n\t\ttestContractAgainstCpp(\"f(uint256,uint256,uint256)\", f, u256(4), u256(5), u256(0));\n\t\ttestContractAgainstCpp(\"f(uint256,uint256,uint256)\", f, u256(5), u256(4), u256(0));\n\t\ttestContractAgainstCpp(\"f(uint256,uint256,uint256)\", f, u256(5), u256(4), u256(7));\n\t\ttestContractAgainstCpp(\"f(uint256,uint256,uint256)\", f, u256(4), u256(5), u256(0));\n\t\ttestContractAgainstCpp(\"f(uint256,uint256,uint256)\", f, u256(5), u256(4), u256(0));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(constructor)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tmapping(uint => uint) data;\n\t\t\tconstructor() {\n\t\t\t\tdata[7] = 8;\n\t\t\t}\n\t\t\tfunction get(uint key) public returns (uint value) {\n\t\t\t\treturn data[key];\n\t\t\t}\n\t\t}\n\t)\";\n\n\tstd::map<u256, uint8_t> data;\n\tdata[7] = 8;\n\tauto get = [&](u256 const& _x) -> u256\n\t{\n\t\treturn data[_x];\n\t};\n\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\t\ttestContractAgainstCpp(\"get(uint256)\", get, u256(6));\n\t\ttestContractAgainstCpp(\"get(uint256)\", get, u256(7));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(send_ether)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tconstructor() payable {}\n\t\t\tfunction a(address payable addr, uint amount) public returns (uint ret) {\n\t\t\t\taddr.send(amount);\n\t\t\t\treturn address(this).balance;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tu256 amount(250);\n\t\tcompileAndRun(sourceCode, amount + 1);\n\t\th160 address(23);\n\t\tABI_CHECK(callContractFunction(\"a(address,uint256)\", address, amount), encodeArgs(1));\n\t\tBOOST_CHECK_EQUAL(balanceAt(address), amount);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(transfer_ether)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract A {\n\t\t\tconstructor() payable {}\n\t\t\tfunction a(address payable addr, uint amount) public returns (uint) {\n\t\t\t\taddr.transfer(amount);\n\t\t\t\treturn address(this).balance;\n\t\t\t}\n\t\t\tfunction b(address payable addr, uint amount) public {\n\t\t\t\taddr.transfer(amount);\n\t\t\t}\n\t\t}\n\n\t\tcontract B {\n\t\t}\n\n\t\tcontract C {\n\t\t\treceive () external payable {\n\t\t\t\trevert();\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"B\");\n\t\th160 const nonPayableRecipient = m_contractAddress;\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\th160 const oogRecipient = m_contractAddress;\n\t\tcompileAndRun(sourceCode, 20, \"A\");\n\t\th160 payableRecipient(23);\n\t\tABI_CHECK(callContractFunction(\"a(address,uint256)\", payableRecipient, 10), encodeArgs(10));\n\t\tBOOST_CHECK_EQUAL(balanceAt(payableRecipient), 10);\n\t\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10);\n\t\tABI_CHECK(callContractFunction(\"b(address,uint256)\", nonPayableRecipient, 10), encodeArgs());\n\t\tABI_CHECK(callContractFunction(\"b(address,uint256)\", oogRecipient, 10), encodeArgs());\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(inter_contract_calls)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Helper {\n\t\t\tfunction multiply(uint a, uint b) public returns (uint c) {\n\t\t\t\treturn a * b;\n\t\t\t}\n\t\t}\n\t\tcontract Main {\n\t\t\tHelper h;\n\t\t\tfunction callHelper(uint a, uint b) public returns (uint c) {\n\t\t\t\treturn h.multiply(a, b);\n\t\t\t}\n\t\t\tfunction getHelper() public returns (address haddress) {\n\t\t\t\treturn address(h);\n\t\t\t}\n\t\t\tfunction setHelper(address haddress) public {\n\t\t\t\th = Helper(haddress);\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Helper\");\n\th160 const c_helperAddress = m_contractAddress;\n\tcompileAndRun(sourceCode, 0, \"Main\");\n\tBOOST_REQUIRE(callContractFunction(\"setHelper(address)\", c_helperAddress) == bytes());\n\tBOOST_REQUIRE(callContractFunction(\"getHelper()\", c_helperAddress) == encodeArgs(c_helperAddress));\n\tu256 a(3456789);\n\tu256 b(\"0x282837623374623234aa74\");\n\tBOOST_REQUIRE(callContractFunction(\"callHelper(uint256,uint256)\", a, b) == encodeArgs(a * b));\n}\n\nBOOST_AUTO_TEST_CASE(inter_contract_calls_with_complex_parameters)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Helper {\n\t\t\tfunction sel(uint a, bool select, uint b) public returns (uint c) {\n\t\t\t\tif (select) return a; else return b;\n\t\t\t}\n\t\t}\n\t\tcontract Main {\n\t\t\tHelper h;\n\t\t\tfunction callHelper(uint a, bool select, uint b) public returns (uint c) {\n\t\t\t\treturn h.sel(a, select, b) * 3;\n\t\t\t}\n\t\t\tfunction getHelper() public returns (address haddress) {\n\t\t\t\treturn address(h);\n\t\t\t}\n\t\t\tfunction setHelper(address haddress) public {\n\t\t\t\th = Helper(haddress);\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Helper\");\n\th160 const c_helperAddress = m_contractAddress;\n\tcompileAndRun(sourceCode, 0, \"Main\");\n\tBOOST_REQUIRE(callContractFunction(\"setHelper(address)\", c_helperAddress) == bytes());\n\tBOOST_REQUIRE(callContractFunction(\"getHelper()\", c_helperAddress) == encodeArgs(c_helperAddress));\n\tu256 a(3456789);\n\tu256 b(\"0x282837623374623234aa74\");\n\tBOOST_REQUIRE(callContractFunction(\"callHelper(uint256,bool,uint256)\", a, true, b) == encodeArgs(a * 3));\n\tBOOST_REQUIRE(callContractFunction(\"callHelper(uint256,bool,uint256)\", a, false, b) == encodeArgs(b * 3));\n}\n\nBOOST_AUTO_TEST_CASE(inter_contract_calls_accessing_this)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Helper {\n\t\t\tfunction getAddress() public returns (address addr) {\n\t\t\t\treturn address(this);\n\t\t\t}\n\t\t}\n\t\tcontract Main {\n\t\t\tHelper h;\n\t\t\tfunction callHelper() public returns (address addr) {\n\t\t\t\treturn h.getAddress();\n\t\t\t}\n\t\t\tfunction getHelper() public returns (address addr) {\n\t\t\t\treturn address(h);\n\t\t\t}\n\t\t\tfunction setHelper(address addr) public {\n\t\t\t\th = Helper(addr);\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Helper\");\n\th160 const c_helperAddress = m_contractAddress;\n\tcompileAndRun(sourceCode, 0, \"Main\");\n\tBOOST_REQUIRE(callContractFunction(\"setHelper(address)\", c_helperAddress) == bytes());\n\tBOOST_REQUIRE(callContractFunction(\"getHelper()\", c_helperAddress) == encodeArgs(c_helperAddress));\n\tBOOST_REQUIRE(callContractFunction(\"callHelper()\") == encodeArgs(c_helperAddress));\n}\n\nBOOST_AUTO_TEST_CASE(calls_to_this)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Helper {\n\t\t\tfunction invoke(uint a, uint b) public returns (uint c) {\n\t\t\t\treturn this.multiply(a, b, 10);\n\t\t\t}\n\t\t\tfunction multiply(uint a, uint b, uint8 c) public returns (uint ret) {\n\t\t\t\treturn a * b + c;\n\t\t\t}\n\t\t}\n\t\tcontract Main {\n\t\t\tHelper h;\n\t\t\tfunction callHelper(uint a, uint b) public returns (uint ret) {\n\t\t\t\treturn h.invoke(a, b);\n\t\t\t}\n\t\t\tfunction getHelper() public returns (address addr) {\n\t\t\t\treturn address(h);\n\t\t\t}\n\t\t\tfunction setHelper(address addr) public {\n\t\t\t\th = Helper(addr);\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Helper\");\n\th160 const c_helperAddress = m_contractAddress;\n\tcompileAndRun(sourceCode, 0, \"Main\");\n\tBOOST_REQUIRE(callContractFunction(\"setHelper(address)\", c_helperAddress) == bytes());\n\tBOOST_REQUIRE(callContractFunction(\"getHelper()\", c_helperAddress) == encodeArgs(c_helperAddress));\n\tu256 a(3456789);\n\tu256 b(\"0x282837623374623234aa74\");\n\tBOOST_REQUIRE(callContractFunction(\"callHelper(uint256,uint256)\", a, b) == encodeArgs(a * b + 10));\n}\n\nBOOST_AUTO_TEST_CASE(inter_contract_calls_with_local_vars)\n{\n\t// note that a reference to another contract's function occupies two stack slots,\n\t// so this tests correct stack slot allocation\n\tchar const* sourceCode = R\"(\n\t\tcontract Helper {\n\t\t\tfunction multiply(uint a, uint b) public returns (uint c) {\n\t\t\t\treturn a * b;\n\t\t\t}\n\t\t}\n\t\tcontract Main {\n\t\t\tHelper h;\n\t\t\tfunction callHelper(uint a, uint b) public returns (uint c) {\n\t\t\t\tuint8 y = 9;\n\t\t\t\tuint256 ret = h.multiply(a, b);\n\t\t\t\treturn ret + y;\n\t\t\t}\n\t\t\tfunction getHelper() public returns (address haddress) {\n\t\t\t\treturn address(h);\n\t\t\t}\n\t\t\tfunction setHelper(address haddress) public {\n\t\t\t\th = Helper(haddress);\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Helper\");\n\th160 const c_helperAddress = m_contractAddress;\n\tcompileAndRun(sourceCode, 0, \"Main\");\n\tBOOST_REQUIRE(callContractFunction(\"setHelper(address)\", c_helperAddress) == bytes());\n\tBOOST_REQUIRE(callContractFunction(\"getHelper()\", c_helperAddress) == encodeArgs(c_helperAddress));\n\tu256 a(3456789);\n\tu256 b(\"0x282837623374623234aa74\");\n\tBOOST_REQUIRE(callContractFunction(\"callHelper(uint256,uint256)\", a, b) == encodeArgs(a * b + 9));\n}\n\nBOOST_AUTO_TEST_CASE(fixed_bytes_in_calls)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Helper {\n\t\t\tfunction invoke(bytes3 x, bool stop) public returns (bytes4 ret) {\n\t\t\t\treturn x;\n\t\t\t}\n\t\t}\n\t\tcontract Main {\n\t\t\tHelper h;\n\t\t\tfunction callHelper(bytes2 x, bool stop) public returns (bytes5 ret) {\n\t\t\t\treturn h.invoke(x, stop);\n\t\t\t}\n\t\t\tfunction getHelper() public returns (address addr) {\n\t\t\t\treturn address(h);\n\t\t\t}\n\t\t\tfunction setHelper(address addr) public {\n\t\t\t\th = Helper(addr);\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Helper\");\n\th160 const c_helperAddress = m_contractAddress;\n\tcompileAndRun(sourceCode, 0, \"Main\");\n\tBOOST_REQUIRE(callContractFunction(\"setHelper(address)\", c_helperAddress) == bytes());\n\tBOOST_REQUIRE(callContractFunction(\"getHelper()\", c_helperAddress) == encodeArgs(c_helperAddress));\n\tABI_CHECK(callContractFunction(\"callHelper(bytes2,bool)\", std::string(\"\\0a\", 2), true), encodeArgs(std::string(\"\\0a\\0\\0\\0\", 5)));\n}\n\nBOOST_AUTO_TEST_CASE(constructor_with_long_arguments)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Main {\n\t\t\tstring public a;\n\t\t\tstring public b;\n\n\t\t\tconstructor(string memory _a, string memory _b) {\n\t\t\t\ta = _a;\n\t\t\t\tb = _b;\n\t\t\t}\n\t\t}\n\t)\";\n\tstd::string a = \"01234567890123gabddunaouhdaoneudapcgadi4567890789012oneudapcgadi4567890789012oneudapcgadi4567890789012oneudapcgadi4567890789012oneudapcgadi4567890789012oneudapcgadi4567890789012oneudapcgadi4567890789012oneudapcgadi45678907890123456789abcd123456787890123456789abcd90123456789012345678901234567890123456789aboneudapcgadi4567890789012oneudapcgadi4567890789012oneudapcgadi45678907890123456789abcd123456787890123456789abcd90123456789012345678901234567890123456789aboneudapcgadi4567890789012oneudapcgadi4567890789012oneudapcgadi45678907890123456789abcd123456787890123456789abcd90123456789012345678901234567890123456789aboneudapcgadi4567890789012cdef\";\n\tstd::string b = \"AUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PYAUTAHIACIANOTUHAOCUHAOEUNAOEHUNTHDYDHPYDRCPYDRSTITOEUBXHUDGO>PY\";\n\n\tcompileAndRun(sourceCode, 0, \"Main\", encodeArgs(\n\t\tu256(0x40),\n\t\tu256(0x40 + 0x20 + ((a.length() + 31) / 32) * 32),\n\t\tu256(a.length()),\n\t\ta,\n\t\tu256(b.length()),\n\t\tb\n\t));\n\tABI_CHECK(callContractFunction(\"a()\"), encodeDyn(a));\n\tABI_CHECK(callContractFunction(\"b()\"), encodeDyn(b));\n}\n\nBOOST_AUTO_TEST_CASE(contracts_as_addresses)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract helper {\n\t\t\treceive() external payable { } // can receive ether\n\t\t}\n\t\tcontract test {\n\t\t\thelper h;\n\t\t\tconstructor() payable { h = new helper(); payable(h).send(5); }\n\t\t\tfunction getBalance() public returns (uint256 myBalance, uint256 helperBalance) {\n\t\t\t\tmyBalance = address(this).balance;\n\t\t\t\thelperBalance = address(h).balance;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 20);\n\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 20 - 5);\n\tBOOST_REQUIRE(callContractFunction(\"getBalance()\") == encodeArgs(u256(20 - 5), u256(5)));\n}\n\nBOOST_AUTO_TEST_CASE(blockhash)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tuint256 counter;\n\t\t\tfunction g() public returns (bool) { counter++; return true; }\n\t\t\tfunction f() public returns (bytes32[] memory r) {\n\t\t\t\tr = new bytes32[](259);\n\t\t\t\tfor (uint i = 0; i < 259; i++) {\n\t\t\t\t\tunchecked {\n\t\t\t\t\t\tr[i] = blockhash(block.number - 257 + i);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode);\n\t// generate a sufficient amount of blocks\n\twhile (blockNumber() < u256(255))\n\t\tABI_CHECK(callContractFunction(\"g()\"), encodeArgs(true));\n\n\tstd::vector<u256> hashes;\n\t// ``blockhash()`` is only valid for the last 256 blocks, otherwise zero\n\thashes.emplace_back(0);\n\tfor (u256 i = blockNumber() - u256(255); i <= blockNumber(); i++)\n\t\thashes.emplace_back(blockHash(i));\n\t// the current block hash is not yet known at execution time and therefore zero\n\thashes.emplace_back(0);\n\t// future block hashes are zero\n\thashes.emplace_back(0);\n\n\tABI_CHECK(callContractFunction(\"f()\"), encodeDyn(hashes));\n}\n\nBOOST_AUTO_TEST_CASE(internal_constructor)\n{\n\tchar const* sourceCode = R\"(\n\t\tabstract contract C {\n\t\t\tconstructor() {}\n\t\t}\n\t)\";\n\t// via yul disabled because it will throw an error instead of\n\t// returning empty bytecode.\n\tBOOST_CHECK(compileAndRunWithoutCheck({{\"\", sourceCode}}, 0, \"C\").empty());\n}\n\nBOOST_AUTO_TEST_CASE(default_fallback_throws)\n{\n\tchar const* sourceCode = R\"YY(\n\t\tcontract A {\n\t\t\tfunction f() public returns (bool) {\n\t\t\t\t(bool success,) = address(this).call(\"\");\n\t\t\t\treturn success;\n\t\t\t}\n\t\t}\n\t)YY\";\n\tcompileAndRun(sourceCode);\n\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(0));\n\n\tif (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())\n\t{\n\t\tchar const* sourceCode = R\"YY(\n\t\t\tcontract A {\n\t\t\t\tfunction f() public returns (bool) {\n\t\t\t\t\t(bool success, bytes memory data) = address(this).staticcall(\"\");\n\t\t\t\t\tassert(data.length == 0);\n\t\t\t\t\treturn success;\n\t\t\t\t}\n\t\t\t}\n\t\t)YY\";\n\t\tcompileAndRun(sourceCode);\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(0));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint, uint k) public returns(uint ret_k, uint ret_g){\n\t\t\t\tuint g = 8;\n\t\t\t\tret_k = k;\n\t\t\t\tret_g = g;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\t\tBOOST_CHECK(callContractFunction(\"f(uint256,uint256)\", 5, 9) != encodeArgs(5, 8));\n\t\tABI_CHECK(callContractFunction(\"f(uint256,uint256)\", 5, 9), encodeArgs(9, 8));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(generic_call)\n{\n\tchar const* sourceCode = R\"**(\n\t\t\tcontract receiver {\n\t\t\t\tuint public received;\n\t\t\t\tfunction recv(uint256 x) public payable { received = x; }\n\t\t\t}\n\t\t\tcontract sender {\n\t\t\t\tconstructor() payable {}\n\t\t\t\tfunction doSend(address rec) public returns (uint d)\n\t\t\t\t{\n\t\t\t\t\tbytes4 signature = bytes4(bytes32(keccak256(\"recv(uint256)\")));\n\t\t\t\t\trec.call{value: 2}(abi.encodeWithSelector(signature, 23));\n\t\t\t\t\treturn receiver(rec).received();\n\t\t\t\t}\n\t\t\t}\n\t)**\";\n\tcompileAndRun(sourceCode, 0, \"receiver\");\n\th160 const c_receiverAddress = m_contractAddress;\n\tcompileAndRun(sourceCode, 50, \"sender\");\n\tBOOST_REQUIRE(callContractFunction(\"doSend(address)\", c_receiverAddress) == encodeArgs(23));\n\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 50 - 2);\n}\n\nBOOST_AUTO_TEST_CASE(generic_delegatecall)\n{\n\tchar const* sourceCode = R\"**(\n\t\t\tcontract Receiver {\n\t\t\t\tuint public received;\n\t\t\t\taddress public sender;\n\t\t\t\tuint public value;\n\t\t\t\tconstructor() payable {}\n\t\t\t\tfunction recv(uint256 x) public payable { received = x; sender = msg.sender; value = msg.value; }\n\t\t\t}\n\t\t\tcontract Sender {\n\t\t\t\tuint public received;\n\t\t\t\taddress public sender;\n\t\t\t\tuint public value;\n\t\t\t\tconstructor() payable {}\n\t\t\t\tfunction doSend(address rec) public payable\n\t\t\t\t{\n\t\t\t\t\tbytes4 signature = bytes4(bytes32(keccak256(\"recv(uint256)\")));\n\t\t\t\t\t(bool success,) = rec.delegatecall(abi.encodeWithSelector(signature, 23));\n\t\t\t\t\tsuccess;\n\t\t\t\t}\n\t\t\t}\n\t)**\";\n\n\tfor (auto v2: {false, true})\n\t{\n\t\tstd::string source = \"pragma abicoder \" + std::string(v2 ? \"v2\" : \"v1\") + \";\\n\" + std::string(sourceCode);\n\n\t\tcompileAndRun(source, 0, \"Receiver\");\n\t\th160 const c_receiverAddress = m_contractAddress;\n\t\tcompileAndRun(source, 50, \"Sender\");\n\t\th160 const c_senderAddress = m_contractAddress;\n\t\tBOOST_CHECK(m_sender != c_senderAddress); // just for sanity\n\t\tABI_CHECK(callContractFunctionWithValue(\"doSend(address)\", 11, c_receiverAddress), encodeArgs());\n\t\tABI_CHECK(callContractFunction(\"received()\"), encodeArgs(u256(23)));\n\t\tABI_CHECK(callContractFunction(\"sender()\"), encodeArgs(m_sender));\n\t\tABI_CHECK(callContractFunction(\"value()\"), encodeArgs(u256(11)));\n\t\tm_contractAddress = c_receiverAddress;\n\t\tABI_CHECK(callContractFunction(\"received()\"), encodeArgs(u256(0)));\n\t\tABI_CHECK(callContractFunction(\"sender()\"), encodeArgs(u256(0)));\n\t\tABI_CHECK(callContractFunction(\"value()\"), encodeArgs(u256(0)));\n\t\tBOOST_CHECK(storageEmpty(c_receiverAddress));\n\t\tBOOST_CHECK(!storageEmpty(c_senderAddress));\n\t\tBOOST_CHECK_EQUAL(balanceAt(c_receiverAddress), 0);\n\t\tBOOST_CHECK_EQUAL(balanceAt(c_senderAddress), 50 + 11);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(generic_staticcall)\n{\n\tif (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())\n\t{\n\t\tchar const* sourceCode = R\"**(\n\t\t\t\tcontract A {\n\t\t\t\t\tuint public x;\n\t\t\t\t\tconstructor() { x = 42; }\n\t\t\t\t\tfunction pureFunction(uint256 p) public pure returns (uint256) { return p; }\n\t\t\t\t\tfunction viewFunction(uint256 p) public view returns (uint256) { return p + x; }\n\t\t\t\t\tfunction nonpayableFunction(uint256 p) public returns (uint256) { x = p; return x; }\n\t\t\t\t\tfunction assertFunction(uint256 p) public view returns (uint256) { assert(x == p); return x; }\n\t\t\t\t}\n\t\t\t\tcontract C {\n\t\t\t\t\tfunction f(address a) public view returns (bool, bytes memory)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn a.staticcall(abi.encodeWithSignature(\"pureFunction(uint256)\", 23));\n\t\t\t\t\t}\n\t\t\t\t\tfunction g(address a) public view returns (bool, bytes memory)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn a.staticcall(abi.encodeWithSignature(\"viewFunction(uint256)\", 23));\n\t\t\t\t\t}\n\t\t\t\t\tfunction h(address a) public view returns (bool, bytes memory)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn a.staticcall(abi.encodeWithSignature(\"nonpayableFunction(uint256)\", 23));\n\t\t\t\t\t}\n\t\t\t\t\tfunction i(address a, uint256 v) public view returns (bool, bytes memory)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn a.staticcall(abi.encodeWithSignature(\"assertFunction(uint256)\", v));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t)**\";\n\t\tcompileAndRun(sourceCode, 0, \"A\");\n\t\th160 const c_addressA = m_contractAddress;\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tABI_CHECK(callContractFunction(\"f(address)\", c_addressA), encodeArgs(true, 0x40, 0x20, 23));\n\t\tABI_CHECK(callContractFunction(\"g(address)\", c_addressA), encodeArgs(true, 0x40, 0x20, 23 + 42));\n\t\tABI_CHECK(callContractFunction(\"h(address)\", c_addressA), encodeArgs(false, 0x40, 0x00));\n\t\tABI_CHECK(callContractFunction(\"i(address,uint256)\", c_addressA, 42), encodeArgs(true, 0x40, 0x20, 42));\n\t\tABI_CHECK(callContractFunction(\"i(address,uint256)\", c_addressA, 23), encodeArgs(false, 0x40, 0x24) + panicData(PanicCode::Assert) + bytes(32 - 4, 0));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(library_call_protection)\n{\n\t// This tests code that reverts a call if it is a direct call to a library\n\t// as opposed to a delegatecall.\n\tchar const* sourceCode = R\"(\n\t\tlibrary Lib {\n\t\t\tstruct S { uint x; }\n\t\t\t// a direct call to this should revert\n\t\t\tfunction np(S storage s) public returns (address) { s.x = 3; return msg.sender; }\n\t\t\t// a direct call to this is fine\n\t\t\tfunction v(S storage) public view returns (address) { return msg.sender; }\n\t\t\t// a direct call to this is fine\n\t\t\tfunction pu() public pure returns (uint) { return 2; }\n\t\t}\n\t\tcontract Test {\n\t\t\tLib.S public s;\n\t\t\tfunction np() public returns (address) { return Lib.np(s); }\n\t\t\tfunction v() public view returns (address) { return Lib.v(s); }\n\t\t\tfunction pu() public pure returns (uint) { return Lib.pu(); }\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"Lib\");\n\t\tABI_CHECK(callContractFunction(\"np(Lib.S storage)\", 0), encodeArgs());\n\t\tABI_CHECK(callContractFunction(\"v(Lib.S storage)\", 0), encodeArgs(m_sender));\n\t\tABI_CHECK(callContractFunction(\"pu()\"), encodeArgs(2));\n\t\tcompileAndRun(sourceCode, 0, \"Test\", bytes(), std::map<std::string, h160>{{\":Lib\", m_contractAddress}});\n\t\tABI_CHECK(callContractFunction(\"s()\"), encodeArgs(0));\n\t\tABI_CHECK(callContractFunction(\"np()\"), encodeArgs(m_sender));\n\t\tABI_CHECK(callContractFunction(\"s()\"), encodeArgs(3));\n\t\tABI_CHECK(callContractFunction(\"v()\"), encodeArgs(m_sender));\n\t\tABI_CHECK(callContractFunction(\"pu()\"), encodeArgs(2));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f() public returns (bytes32) {\n\t\t\t\treturn keccak256(abi.encodePacked(\"abc\", msg.data));\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\t\tbytes calldata1 = util::selectorFromSignatureH32(\"f()\").asBytes() + bytes(61, 0x22) + bytes(12, 0x12);\n\t\tsendMessage(calldata1, bytes(), false);\n\t\tBOOST_CHECK(m_transactionSuccessful);\n\t\tBOOST_CHECK(m_output == encodeArgs(util::keccak256(bytes{'a', 'b', 'c'} + calldata1)));\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(call_forward_bytes_length)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract receiver {\n\t\t\tuint public calledLength;\n\t\t\tfallback() external { calledLength = msg.data.length; }\n\t\t}\n\t\tcontract sender {\n\t\t\treceiver rec;\n\t\t\tconstructor() { rec = new receiver(); }\n\t\t\tfunction viaCalldata() public returns (uint) {\n\t\t\t\t(bool success,) = address(rec).call(msg.data);\n\t\t\t\trequire(success);\n\t\t\t\treturn rec.calledLength();\n\t\t\t}\n\t\t\tfunction viaMemory() public returns (uint) {\n\t\t\t\tbytes memory x = msg.data;\n\t\t\t\t(bool success,) = address(rec).call(x);\n\t\t\t\trequire(success);\n\t\t\t\treturn rec.calledLength();\n\t\t\t}\n\t\t\tbytes s;\n\t\t\tfunction viaStorage() public returns (uint) {\n\t\t\t\ts = msg.data;\n\t\t\t\t(bool success,) = address(rec).call(s);\n\t\t\t\trequire(success);\n\t\t\t\treturn rec.calledLength();\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"sender\");\n\n\t\t// No additional data, just function selector\n\t\tABI_CHECK(callContractFunction(\"viaCalldata()\"), encodeArgs(4));\n\t\tABI_CHECK(callContractFunction(\"viaMemory()\"), encodeArgs(4));\n\t\tABI_CHECK(callContractFunction(\"viaStorage()\"), encodeArgs(4));\n\n\t\t// Some additional unpadded data\n\t\tbytes unpadded = asBytes(std::string(\"abc\"));\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"viaCalldata()\", unpadded), encodeArgs(7));\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"viaMemory()\", unpadded), encodeArgs(7));\n\t\tABI_CHECK(callContractFunctionNoEncoding(\"viaStorage()\", unpadded), encodeArgs(7));\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(copying_bytes_multiassign)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract receiver {\n\t\t\tuint public received;\n\t\t\tfunction recv(uint x) public { received += x + 1; }\n\t\t\tfallback() external { received = 0x80; }\n\t\t}\n\t\tcontract sender {\n\t\t\tconstructor() { rec = new receiver(); }\n\t\t\tfallback() external { savedData1 = savedData2 = msg.data; }\n\t\t\tfunction forward(bool selector) public returns (bool) {\n\t\t\t\tif (selector) { address(rec).call(savedData1); delete savedData1; }\n\t\t\t\telse { address(rec).call(savedData2); delete savedData2; }\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tfunction val() public returns (uint) { return rec.received(); }\n\t\t\treceiver rec;\n\t\t\tbytes savedData1;\n\t\t\tbytes savedData2;\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"sender\");\n\t\tABI_CHECK(callContractFunction(\"recv(uint256)\", 7), bytes());\n\t\tABI_CHECK(callContractFunction(\"val()\"), encodeArgs(0));\n\t\tABI_CHECK(callContractFunction(\"forward(bool)\", true), encodeArgs(true));\n\t\tABI_CHECK(callContractFunction(\"val()\"), encodeArgs(8));\n\t\tABI_CHECK(callContractFunction(\"forward(bool)\", false), encodeArgs(true));\n\t\tABI_CHECK(callContractFunction(\"val()\"), encodeArgs(16));\n\t\tABI_CHECK(callContractFunction(\"forward(bool)\", true), encodeArgs(true));\n\t\tABI_CHECK(callContractFunction(\"val()\"), encodeArgs(0x80));\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(copy_from_calldata_removes_bytes_data)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract c {\n\t\t\tfunction set() public returns (bool) { data = msg.data; return true; }\n\t\t\tfallback() external { data = msg.data; }\n\t\t\tbytes data;\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\t\tABI_CHECK(callContractFunction(\"set()\", 1, 2, 3, 4, 5), encodeArgs(true));\n\t\tBOOST_CHECK(!storageEmpty(m_contractAddress));\n\t\tsendMessage(bytes(), bytes(), false);\n\t\tBOOST_CHECK(m_transactionSuccessful);\n\t\tBOOST_CHECK(m_output.empty());\n\t\tBOOST_CHECK(storageEmpty(m_contractAddress));\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(struct_referencing)\n{\n\tstatic char const* sourceCode = R\"(\n\t\tpragma abicoder v2;\n\t\tinterface I {\n\t\t\tstruct S { uint a; }\n\t\t}\n\t\tlibrary L {\n\t\t\tstruct S { uint b; uint a; }\n\t\t\tfunction f() public pure returns (S memory) {\n\t\t\t\tS memory s;\n\t\t\t\ts.a = 3;\n\t\t\t\treturn s;\n\t\t\t}\n\t\t\tfunction g() public pure returns (I.S memory) {\n\t\t\t\tI.S memory s;\n\t\t\t\ts.a = 4;\n\t\t\t\treturn s;\n\t\t\t}\n\t\t\t// argument-dependent lookup tests\n\t\t\tfunction a(I.S memory) public pure returns (uint) { return 1; }\n\t\t\tfunction a(S memory) public pure returns (uint) { return 2; }\n\t\t}\n\t\tcontract C is I {\n\t\t\tfunction f() public pure returns (S memory) {\n\t\t\t\tS memory s;\n\t\t\t\ts.a = 1;\n\t\t\t\treturn s;\n\t\t\t}\n\t\t\tfunction g() public pure returns (I.S memory) {\n\t\t\t\tI.S memory s;\n\t\t\t\ts.a = 2;\n\t\t\t\treturn s;\n\t\t\t}\n\t\t\tfunction h() public pure returns (L.S memory) {\n\t\t\t\tL.S memory s;\n\t\t\t\ts.a = 5;\n\t\t\t\treturn s;\n\t\t\t}\n\t\t\tfunction x() public pure returns (L.S memory) {\n\t\t\t\treturn L.f();\n\t\t\t}\n\t\t\tfunction y() public pure returns (I.S memory) {\n\t\t\t\treturn L.g();\n\t\t\t}\n\t\t\tfunction a1() public pure returns (uint) { S memory s; return L.a(s); }\n\t\t\tfunction a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"L\");\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(0, 3));\n\t\tABI_CHECK(callContractFunction(\"g()\"), encodeArgs(4));\n\t\tcompileAndRun(sourceCode, 0, \"C\", bytes(), std::map<std::string, h160>{ {\":L\", m_contractAddress}});\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(1));\n\t\tABI_CHECK(callContractFunction(\"g()\"), encodeArgs(2));\n\t\tABI_CHECK(callContractFunction(\"h()\"), encodeArgs(0, 5));\n\t\tABI_CHECK(callContractFunction(\"x()\"), encodeArgs(0, 3));\n\t\tABI_CHECK(callContractFunction(\"y()\"), encodeArgs(4));\n\t\tABI_CHECK(callContractFunction(\"a1()\"), encodeArgs(1));\n\t\tABI_CHECK(callContractFunction(\"a2()\"), encodeArgs(2));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(enum_referencing)\n{\n\tchar const* sourceCode = R\"(\n\t\tinterface I {\n\t\t\tenum Direction { A, B, Left, Right }\n\t\t}\n\t\tlibrary L {\n\t\t\tenum Direction { Left, Right }\n\t\t\tfunction f() public pure returns (Direction) {\n\t\t\t\treturn Direction.Right;\n\t\t\t}\n\t\t\tfunction g() public pure returns (I.Direction) {\n\t\t\t\treturn I.Direction.Right;\n\t\t\t}\n\t\t}\n\t\tcontract C is I {\n\t\t\tfunction f() public pure returns (Direction) {\n\t\t\t\treturn Direction.Right;\n\t\t\t}\n\t\t\tfunction g() public pure returns (I.Direction) {\n\t\t\t\treturn I.Direction.Right;\n\t\t\t}\n\t\t\tfunction h() public pure returns (L.Direction) {\n\t\t\t\treturn L.Direction.Right;\n\t\t\t}\n\t\t\tfunction x() public pure returns (L.Direction) {\n\t\t\t\treturn L.f();\n\t\t\t}\n\t\t\tfunction y() public pure returns (I.Direction) {\n\t\t\t\treturn L.g();\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"L\");\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(1));\n\t\tABI_CHECK(callContractFunction(\"g()\"), encodeArgs(3));\n\t\tcompileAndRun(sourceCode, 0, \"C\", bytes(), std::map<std::string, h160>{{\":L\", m_contractAddress}});\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(3));\n\t\tABI_CHECK(callContractFunction(\"g()\"), encodeArgs(3));\n\t\tABI_CHECK(callContractFunction(\"h()\"), encodeArgs(1));\n\t\tABI_CHECK(callContractFunction(\"x()\"), encodeArgs(1));\n\t\tABI_CHECK(callContractFunction(\"y()\"), encodeArgs(3));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(bytes_in_arguments)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract c {\n\t\t\tuint result;\n\t\t\tfunction f(uint a, uint b) public { result += a + b; }\n\t\t\tfunction g(uint a) public { result *= a; }\n\t\t\tfunction test(uint a, bytes calldata data1, bytes calldata data2, uint b) external returns (uint r_a, uint r, uint r_b, uint l) {\n\t\t\t\tr_a = a;\n\t\t\t\taddress(this).call(data1);\n\t\t\t\taddress(this).call(data2);\n\t\t\t\tr = result;\n\t\t\t\tr_b = b;\n\t\t\t\tl = data1.length;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\n\t\tstd::string innercalldata1 = asString(util::selectorFromSignatureH32(\"f(uint256,uint256)\").asBytes() + encodeArgs(8, 9));\n\t\tstd::string innercalldata2 = asString(util::selectorFromSignatureH32(\"g(uint256)\").asBytes() + encodeArgs(3));\n\t\tbytes calldata = encodeArgs(\n\t\t\t12, 32 * 4, u256(32 * 4 + 32 + (innercalldata1.length() + 31) / 32 * 32), 13,\n\t\t\tu256(innercalldata1.length()), innercalldata1,\n\t\t\tu256(innercalldata2.length()), innercalldata2);\n\t\tABI_CHECK(\n\t\t\tcallContractFunction(\"test(uint256,bytes,bytes,uint256)\", calldata),\n\t\t\tencodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length()))\n\t\t);\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(array_copy_storage_abi)\n{\n\t// NOTE: This does not really test copying from storage to ABI directly,\n\t// because it will always copy to memory first.\n\tchar const* sourceCode = R\"(\n\t\tpragma abicoder v2;\n\t\tcontract c {\n\t\t\tuint8[] x;\n\t\t\tuint16[] y;\n\t\t\tuint24[] z;\n\t\t\tuint24[][] w;\n\t\t\tfunction test1() public returns (uint8[] memory) {\n\t\t\t\tfor (uint i = 0; i < 101; ++i)\n\t\t\t\t\tx.push(uint8(i));\n\t\t\t\treturn x;\n\t\t\t}\n\t\t\tfunction test2() public returns (uint16[] memory) {\n\t\t\t\tfor (uint i = 0; i < 101; ++i)\n\t\t\t\t\ty.push(uint16(i));\n\t\t\t\treturn y;\n\t\t\t}\n\t\t\tfunction test3() public returns (uint24[] memory) {\n\t\t\t\tfor (uint i = 0; i < 101; ++i)\n\t\t\t\t\tz.push(uint24(i));\n\t\t\t\treturn z;\n\t\t\t}\n\t\t\tfunction test4() public returns (uint24[][] memory) {\n\t\t\t\tw = new uint24[][](5);\n\t\t\t\tfor (uint i = 0; i < 5; ++i)\n\t\t\t\t\tfor (uint j = 0; j < 101; ++j)\n\t\t\t\t\t\tw[i].push(uint24(j));\n\t\t\t\treturn w;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode);\n\t\tbytes valueSequence;\n\t\tfor (size_t i = 0; i < 101; ++i)\n\t\t\tvalueSequence += toBigEndian(u256(i));\n\t\tABI_CHECK(callContractFunction(\"test1()\"), encodeArgs(0x20, 101) + valueSequence);\n\t\tABI_CHECK(callContractFunction(\"test2()\"), encodeArgs(0x20, 101) + valueSequence);\n\t\tABI_CHECK(callContractFunction(\"test3()\"), encodeArgs(0x20, 101) + valueSequence);\n\t\tABI_CHECK(callContractFunction(\"test4()\"),\n\t\t\tencodeArgs(0x20, 5, 0xa0, 0xa0 + 102 * 32 * 1, 0xa0 + 102 * 32 * 2, 0xa0 + 102 * 32 * 3, 0xa0 + 102 * 32 * 4) +\n\t\t\tencodeArgs(101) + valueSequence +\n\t\t\tencodeArgs(101) + valueSequence +\n\t\t\tencodeArgs(101) + valueSequence +\n\t\t\tencodeArgs(101) + valueSequence +\n\t\t\tencodeArgs(101) + valueSequence\n\t\t);\n\t);\n}\n\n//BOOST_AUTO_TEST_CASE(assignment_to_const_array_vars)\n//{\n//    char const* sourceCode = R\"(\n//        contract C {\n//            uint[3] constant x = [uint(1), 2, 3];\n//            uint constant y = x[0] + x[1] + x[2];\n//            function f() public returns (uint) { return y; }\n//        }\n//    )\";\n//    compileAndRun(sourceCode);\n//    ABI_CHECK(callContractFunction(\"f()\"), encodeArgs(1 + 2 + 3));\n//}\n\n// Disabled until https://github.com/argotorg/solidity/issues/715 is implemented\n//BOOST_AUTO_TEST_CASE(constant_struct)\n//{\n//    char const* sourceCode = R\"(\n//        contract C {\n//            struct S { uint x; uint[] y; }\n//            S constant x = S(5, new uint[](4));\n//            function f() public returns (uint) { return x.x; }\n//        }\n//    )\";\n//    compileAndRun(sourceCode);\n//    ABI_CHECK(callContractFunction(\"f()\"), encodeArgs(5));\n//}\n\nBOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract A {\n\t\t\tuint public test = 1;\n\t\t\tuint[3] arr;\n\t\t\tconstructor()\n\t\t\t{\n\t\t\t\tuint index = 5;\n\t\t\t\ttest = arr[index];\n\t\t\t\t++test;\n\t\t\t}\n\t\t}\n\t)\";\n\tABI_CHECK(compileAndRunWithoutCheck({{\"\", sourceCode}}, 0, \"A\"), panicData(PanicCode::ArrayOutOfBounds));\n\tBOOST_CHECK(!m_transactionSuccessful);\n}\n\nBOOST_AUTO_TEST_CASE(failing_send)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Helper {\n\t\t\tuint[] data;\n\t\t\tfallback () external {\n\t\t\t\tdata[9]; // trigger exception\n\t\t\t}\n\t\t}\n\t\tcontract Main {\n\t\t\tconstructor() payable {}\n\t\t\tfunction callHelper(address payable _a) public returns (bool r, uint bal) {\n\t\t\t\tr = !_a.send(5);\n\t\t\t\tbal = address(this).balance;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Helper\");\n\th160 const c_helperAddress = m_contractAddress;\n\tcompileAndRun(sourceCode, 20, \"Main\");\n\tBOOST_REQUIRE(callContractFunction(\"callHelper(address)\", c_helperAddress) == encodeArgs(true, 20));\n}\n\nBOOST_AUTO_TEST_CASE(return_multiple_strings_of_various_sizes)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Main {\n\t\t\tstring public s1;\n\t\t\tstring public s2;\n\t\t\tfunction set(string calldata _s1, uint x, string calldata _s2) external returns (uint) {\n\t\t\t\ts1 = _s1;\n\t\t\t\ts2 = _s2;\n\t\t\t\treturn x;\n\t\t\t}\n\t\t\tfunction get() public returns (string memory r1, string memory r2) {\n\t\t\t\tr1 = s1;\n\t\t\t\tr2 = s2;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Main\");\n\tstd::string s1(\n\t\t\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"\n\t\t\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"\n\t\t\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"\n\t\t\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"\n\t);\n\tstd::string s2(\n\t\t\"ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ\"\n\t\t\"ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ\"\n\t\t\"ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ\"\n\t\t\"ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ\"\n\t\t\"ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ\"\n\t);\n\tstd::vector<size_t> lengths{0, 30, 32, 63, 64, 65, 210, 300};\n\tfor (auto l1: lengths)\n\t\tfor (auto l2: lengths)\n\t\t{\n\t\t\tbytes dyn1 = encodeArgs(u256(l1), s1.substr(0, l1));\n\t\t\tbytes dyn2 = encodeArgs(u256(l2), s2.substr(0, l2));\n\t\t\tbytes args = encodeArgs(u256(0x60), u256(l1), u256(0x60 + dyn1.size())) + dyn1 + dyn2;\n\t\t\tBOOST_REQUIRE(\n\t\t\t\tcallContractFunction(\"set(string,uint256,string)\", asString(args)) ==\n\t\t\t\tencodeArgs(u256(l1))\n\t\t\t);\n\t\t\tbytes result = encodeArgs(u256(0x40), u256(0x40 + dyn1.size())) + dyn1 + dyn2;\n\t\t\tABI_CHECK(callContractFunction(\"get()\"), result);\n\t\t\tABI_CHECK(callContractFunction(\"s1()\"), encodeArgs(0x20) + dyn1);\n\t\t\tABI_CHECK(callContractFunction(\"s2()\"), encodeArgs(0x20) + dyn2);\n\t\t}\n}\n\nBOOST_AUTO_TEST_CASE(accessor_involving_strings)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Main {\n\t\t\tstruct stringData { string a; uint b; string c; }\n\t\t\tmapping(uint => stringData[]) public data;\n\t\t\tfunction set(uint x, uint y, string calldata a, uint b, string calldata c) external returns (bool) {\n\t\t\t\twhile (data[x].length < y + 1)\n\t\t\t\t\tdata[x].push();\n\t\t\t\tdata[x][y].a = a;\n\t\t\t\tdata[x][y].b = b;\n\t\t\t\tdata[x][y].c = c;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Main\");\n\tstd::string s1(\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\");\n\tstd::string s2(\"ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ\");\n\tbytes s1Data = encodeArgs(u256(s1.length()), s1);\n\tbytes s2Data = encodeArgs(u256(s2.length()), s2);\n\tu256 b = 765;\n\tu256 x = 7;\n\tu256 y = 123;\n\tbytes args = encodeArgs(x, y, u256(0xa0), b, u256(0xa0 + s1Data.size()), s1Data, s2Data);\n\tbytes result = encodeArgs(u256(0x60), b, u256(0x60 + s1Data.size()), s1Data, s2Data);\n\tBOOST_REQUIRE(callContractFunction(\"set(uint256,uint256,string,uint256,string)\", asString(args)) == encodeArgs(true));\n\tBOOST_REQUIRE(callContractFunction(\"data(uint256,uint256)\", x, y) == result);\n}\n\nBOOST_AUTO_TEST_CASE(bytes_in_function_calls)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Main {\n\t\t\tstring public s1;\n\t\t\tstring public s2;\n\t\t\tfunction set(string memory _s1, uint x, string memory _s2) public returns (uint) {\n\t\t\t\ts1 = _s1;\n\t\t\t\ts2 = _s2;\n\t\t\t\treturn x;\n\t\t\t}\n\t\t\tfunction setIndirectFromMemory(string memory _s1, uint x, string memory _s2) public returns (uint) {\n\t\t\t\treturn this.set(_s1, x, _s2);\n\t\t\t}\n\t\t\tfunction setIndirectFromCalldata(string calldata _s1, uint x, string calldata _s2) external returns (uint) {\n\t\t\t\treturn this.set(_s1, x, _s2);\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Main\");\n\tstd::string s1(\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\");\n\tstd::string s2(\"ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ\");\n\tstd::vector<size_t> lengths{0, 31, 64, 65};\n\tfor (auto l1: lengths)\n\t\tfor (auto l2: lengths)\n\t\t{\n\t\t\tbytes dyn1 = encodeArgs(u256(l1), s1.substr(0, l1));\n\t\t\tbytes dyn2 = encodeArgs(u256(l2), s2.substr(0, l2));\n\t\t\tbytes args1 = encodeArgs(u256(0x60), u256(l1), u256(0x60 + dyn1.size())) + dyn1 + dyn2;\n\t\t\tBOOST_REQUIRE(\n\t\t\t\tcallContractFunction(\"setIndirectFromMemory(string,uint256,string)\", asString(args1)) ==\n\t\t\t\tencodeArgs(u256(l1))\n\t\t\t);\n\t\t\tABI_CHECK(callContractFunction(\"s1()\"), encodeArgs(0x20) + dyn1);\n\t\t\tABI_CHECK(callContractFunction(\"s2()\"), encodeArgs(0x20) + dyn2);\n\t\t\t// swapped\n\t\t\tbytes args2 = encodeArgs(u256(0x60), u256(l1), u256(0x60 + dyn2.size())) + dyn2 + dyn1;\n\t\t\tBOOST_REQUIRE(\n\t\t\t\tcallContractFunction(\"setIndirectFromCalldata(string,uint256,string)\", asString(args2)) ==\n\t\t\t\tencodeArgs(u256(l1))\n\t\t\t);\n\t\t\tABI_CHECK(callContractFunction(\"s1()\"), encodeArgs(0x20) + dyn2);\n\t\t\tABI_CHECK(callContractFunction(\"s2()\"), encodeArgs(0x20) + dyn1);\n\t\t}\n}\n\nBOOST_AUTO_TEST_CASE(return_bytes_internal)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Main {\n\t\t\tbytes s1;\n\t\t\tfunction doSet(bytes memory _s1) public returns (bytes memory _r1) {\n\t\t\t\ts1 = _s1;\n\t\t\t\t_r1 = s1;\n\t\t\t}\n\t\t\tfunction set(bytes calldata _s1) external returns (uint _r, bytes memory _r1) {\n\t\t\t\t_r1 = doSet(_s1);\n\t\t\t\t_r = _r1.length;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Main\");\n\tstd::string s1(\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\");\n\tstd::vector<size_t> lengths{0, 31, 64, 65};\n\tfor (auto l1: lengths)\n\t{\n\t\tbytes dyn1 = encodeArgs(u256(l1), s1.substr(0, l1));\n\t\tbytes args1 = encodeArgs(u256(0x20)) + dyn1;\n\t\tBOOST_REQUIRE(\n\t\t\tcallContractFunction(\"set(bytes)\", asString(args1)) ==\n\t\t\tencodeArgs(u256(l1), u256(0x40)) + dyn1\n\t\t);\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(calldata_struct_short)\n{\n\tchar const* sourceCode = R\"(\n\t\tpragma abicoder v2;\n\t\tcontract C {\n\t\t\tstruct S { uint256 a; uint256 b; }\n\t\t\tfunction f(S calldata) external pure returns (uint256) {\n\t\t\t\treturn msg.data.length;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"C\");\n\n\t// double check that the valid case goes through\n\tABI_CHECK(callContractFunction(\"f((uint256,uint256))\", u256(1), u256(2)), encodeArgs(0x44));\n\n\tABI_CHECK(callContractFunctionNoEncoding(\"f((uint256,uint256))\", bytes(63,0)), encodeArgs());\n\tABI_CHECK(callContractFunctionNoEncoding(\"f((uint256,uint256))\", bytes(33,0)), encodeArgs());\n\tABI_CHECK(callContractFunctionNoEncoding(\"f((uint256,uint256))\", bytes(32,0)), encodeArgs());\n\tABI_CHECK(callContractFunctionNoEncoding(\"f((uint256,uint256))\", bytes(31,0)), encodeArgs());\n\tABI_CHECK(callContractFunctionNoEncoding(\"f((uint256,uint256))\", bytes()), encodeArgs());\n}\n\nBOOST_AUTO_TEST_CASE(calldata_struct_function_type)\n{\n\tchar const* sourceCode = R\"(\n\t\tpragma abicoder v2;\n\t\tcontract C {\n\t\t\tstruct S { function (uint) external returns (uint) fn; }\n\t\t\tfunction f(S calldata s) external returns (uint256) {\n\t\t\t\treturn s.fn(42);\n\t\t\t}\n\t\t\tfunction g(uint256 a) external returns (uint256) {\n\t\t\t\treturn a * 3;\n\t\t\t}\n\t\t\tfunction h(uint256 a) external returns (uint256) {\n\t\t\t\treturn 23;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"C\");\n\n\tbytes fn_C_g = m_contractAddress.asBytes() + util::selectorFromSignatureH32(\"g(uint256)\").asBytes() + bytes(8,0);\n\tbytes fn_C_h = m_contractAddress.asBytes() + util::selectorFromSignatureH32(\"h(uint256)\").asBytes() + bytes(8,0);\n\tABI_CHECK(callContractFunctionNoEncoding(\"f((function))\", fn_C_g), encodeArgs(42 * 3));\n\tABI_CHECK(callContractFunctionNoEncoding(\"f((function))\", fn_C_h), encodeArgs(23));\n}\n\nBOOST_AUTO_TEST_CASE(calldata_array_dynamic_three_dimensional)\n{\n\tstd::vector<std::vector<std::vector<u256>>> data {\n\t\t{\n\t\t\t{ 0x010A01, 0x010A02, 0x010A03 },\n\t\t\t{ 0x010B01, 0x010B02, 0x010B03 }\n\t\t},\n\t\t{\n\t\t\t{ 0x020A01, 0x020A02, 0x020A03 },\n\t\t\t{ 0x020B01, 0x020B02, 0x020B03 }\n\t\t}\n\t};\n\n\tfor (bool outerDynamicallySized: { true, false })\n\tfor (bool middleDynamicallySized: { true, false })\n\tfor (bool innerDynamicallySized: { true, false })\n\t{\n\t\t// only test dynamically encoded arrays\n\t\tif (!outerDynamicallySized && !middleDynamicallySized && !innerDynamicallySized)\n\t\t\tcontinue;\n\n\t\tstd::string arrayType = \"uint256\";\n\t\tarrayType += innerDynamicallySized ? \"[]\" : \"[3]\";\n\t\tarrayType += middleDynamicallySized ? \"[]\" : \"[2]\";\n\t\tarrayType += outerDynamicallySized ? \"[]\" : \"[2]\";\n\n\t\tstd::string sourceCode = R\"(\n\t\t\tpragma abicoder v2;\n\t\t\tcontract C {\n\t\t\t\tfunction test()\" + arrayType + R\"( calldata a) external returns (uint256) {\n\t\t\t\t\treturn a.length;\n\t\t\t\t}\n\t\t\t\tfunction test()\" + arrayType + R\"( calldata a, uint256 i) external returns (uint256) {\n\t\t\t\t\treturn a[i].length;\n\t\t\t\t}\n\t\t\t\tfunction test()\" + arrayType + R\"( calldata a, uint256 i, uint256 j) external returns (uint256) {\n\t\t\t\t\treturn a[i][j].length;\n\t\t\t\t}\n\t\t\t\tfunction test()\" + arrayType + R\"( calldata a, uint256 i, uint256 j, uint256 k) external returns (uint256) {\n\t\t\t\t\treturn a[i][j][k];\n\t\t\t\t}\n\t\t\t\tfunction reenc()\" + arrayType + R\"( calldata a, uint256 i, uint256 j, uint256 k) external returns (uint256) {\n\t\t\t\t\treturn this.test(a, i, j, k);\n\t\t\t\t}\n\t\t\t}\n\t\t)\";\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\n\t\tbytes encoding = encodeArray(\n\t\t\touterDynamicallySized,\n\t\t\tmiddleDynamicallySized || innerDynamicallySized,\n\t\t\tdata | ranges::views::transform([&](auto const& _middleData) {\n\t\t\t\treturn encodeArray(\n\t\t\t\t\tmiddleDynamicallySized,\n\t\t\t\t\tinnerDynamicallySized,\n\t\t\t\t\t_middleData | ranges::views::transform([&](auto const& _values) {\n\t\t\t\t\t\treturn encodeArray(innerDynamicallySized, false, _values);\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t})\n\t\t);\n\n\t\tABI_CHECK(callContractFunction(\"test(\" + arrayType + \")\", 0x20, encoding), encodeArgs(data.size()));\n\t\tfor (size_t i = 0; i < data.size(); i++)\n\t\t{\n\t\t\tABI_CHECK(callContractFunction(\"test(\" + arrayType + \",uint256)\", 0x40, i, encoding), encodeArgs(data[i].size()));\n\t\t\tfor (size_t j = 0; j < data[i].size(); j++)\n\t\t\t{\n\t\t\t\tABI_CHECK(callContractFunction(\"test(\" + arrayType + \",uint256,uint256)\", 0x60, i, j, encoding), encodeArgs(data[i][j].size()));\n\t\t\t\tfor (size_t k = 0; k < data[i][j].size(); k++)\n\t\t\t\t{\n\t\t\t\t\tABI_CHECK(callContractFunction(\"test(\" + arrayType + \",uint256,uint256,uint256)\", 0x80, i, j, k, encoding), encodeArgs(data[i][j][k]));\n\t\t\t\t\tABI_CHECK(callContractFunction(\"reenc(\" + arrayType + \",uint256,uint256,uint256)\", 0x80, i, j, k, encoding), encodeArgs(data[i][j][k]));\n\t\t\t\t}\n\t\t\t\tABI_CHECK(callContractFunction(\"test(\" + arrayType + \",uint256,uint256,uint256)\", 0x80, i, j, data[i][j].size(), encoding), panicData(PanicCode::ArrayOutOfBounds));\n\t\t\t}\n\t\t\tABI_CHECK(callContractFunction(\"test(\" + arrayType + \",uint256,uint256)\", 0x60, i, data[i].size(), encoding), panicData(PanicCode::ArrayOutOfBounds));\n\t\t}\n\t\tABI_CHECK(callContractFunction(\"test(\" + arrayType + \",uint256)\", 0x40, data.size(), encoding), panicData(PanicCode::ArrayOutOfBounds));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(literal_strings)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Test {\n\t\t\tstring public long;\n\t\t\tstring public medium;\n\t\t\tstring public short;\n\t\t\tstring public empty;\n\t\t\tfunction f() public returns (string memory) {\n\t\t\t\tlong = \"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n\t\t\t\tmedium = \"01234567890123456789012345678901234567890123456789012345678901234567890123456789\";\n\t\t\t\tshort = \"123\";\n\t\t\t\tempty = \"\";\n\t\t\t\treturn \"Hello, World!\";\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Test\");\n\tstd::string longStr = \"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n\tstd::string medium = \"01234567890123456789012345678901234567890123456789012345678901234567890123456789\";\n\tstd::string shortStr = \"123\";\n\tstd::string hello = \"Hello, World!\";\n\n\tABI_CHECK(callContractFunction(\"f()\"), encodeDyn(hello));\n\tABI_CHECK(callContractFunction(\"long()\"), encodeDyn(longStr));\n\tABI_CHECK(callContractFunction(\"medium()\"), encodeDyn(medium));\n\tABI_CHECK(callContractFunction(\"short()\"), encodeDyn(shortStr));\n\tABI_CHECK(callContractFunction(\"empty()\"), encodeDyn(std::string()));\n}\n\nBOOST_AUTO_TEST_CASE(initialise_string_constant)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Test {\n\t\t\tstring public short = \"abcdef\";\n\t\t\tstring public long = \"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Test\");\n\tstd::string longStr = \"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n\tstd::string shortStr = \"abcdef\";\n\n\tABI_CHECK(callContractFunction(\"long()\"), encodeDyn(longStr));\n\tABI_CHECK(callContractFunction(\"short()\"), encodeDyn(shortStr));\n}\n\nBOOST_AUTO_TEST_CASE(string_as_mapping_key)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Test {\n\t\t\tmapping(string => uint) data;\n\t\t\tfunction set(string memory _s, uint _v) public { data[_s] = _v; }\n\t\t\tfunction get(string memory _s) public returns (uint) { return data[_s]; }\n\t\t}\n\t)\";\n\n\tstd::vector<std::string> strings{\n\t\t\"Hello, World!\",\n\t\t\"Hello,                            World!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1111\",\n\t\t\"\",\n\t\t\"1\"\n\t};\n\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"Test\");\n\t\tfor (unsigned i = 0; i < strings.size(); i++)\n\t\t\tABI_CHECK(callContractFunction(\n\t\t\t\t\"set(string,uint256)\",\n\t\t\t\tu256(0x40),\n\t\t\t\tu256(7 + i),\n\t\t\t\tu256(strings[i].size()),\n\t\t\t\tstrings[i]\n\t\t\t), encodeArgs());\n\t\tfor (unsigned i = 0; i < strings.size(); i++)\n\t\t\tABI_CHECK(callContractFunction(\n\t\t\t\t\"get(string)\",\n\t\t\t\tu256(0x20),\n\t\t\t\tu256(strings[i].size()),\n\t\t\t\tstrings[i]\n\t\t\t), encodeArgs(u256(7 + i)));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(string_as_public_mapping_key)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Test {\n\t\t\tmapping(string => uint) public data;\n\t\t\tfunction set(string memory _s, uint _v) public { data[_s] = _v; }\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Test\");\n\tstd::vector<std::string> strings{\n\t\t\"Hello, World!\",\n\t\t\"Hello,                            World!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1111\",\n\t\t\"\",\n\t\t\"1\"\n\t};\n\tfor (unsigned i = 0; i < strings.size(); i++)\n\t\tABI_CHECK(callContractFunction(\n\t\t\t\"set(string,uint256)\",\n\t\t\tu256(0x40),\n\t\t\tu256(7 + i),\n\t\t\tu256(strings[i].size()),\n\t\t\tstrings[i]\n\t\t), encodeArgs());\n\tfor (unsigned i = 0; i < strings.size(); i++)\n\t\tABI_CHECK(callContractFunction(\n\t\t\t\"data(string)\",\n\t\t\tu256(0x20),\n\t\t\tu256(strings[i].size()),\n\t\t\tstrings[i]\n\t\t), encodeArgs(u256(7 + i)));\n}\n\nBOOST_AUTO_TEST_CASE(nested_string_as_public_mapping_key)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Test {\n\t\t\tmapping(string => mapping(string => uint)) public data;\n\t\t\tfunction set(string memory _s, string memory _s2, uint _v) public {\n\t\t\t\tdata[_s][_s2] = _v; }\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Test\");\n\tstd::vector<std::string> strings{\n\t\t\"Hello, World!\",\n\t\t\"Hello,                            World!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1111\",\n\t\t\"\",\n\t\t\"1\",\n\t\t\"last one\"\n\t};\n\tfor (unsigned i = 0; i + 1 < strings.size(); i++)\n\t\tABI_CHECK(callContractFunction(\n\t\t\t\"set(string,string,uint256)\",\n\t\t\tu256(0x60),\n\t\t\tu256(roundTo32(static_cast<unsigned>(0x80 + strings[i].size()))),\n\t\t\tu256(7 + i),\n\t\t\tu256(strings[i].size()),\n\t\t\tstrings[i],\n\t\t\tu256(strings[i+1].size()),\n\t\t\tstrings[i+1]\n\t\t), encodeArgs());\n\tfor (unsigned i = 0; i + 1 < strings.size(); i++)\n\t\tABI_CHECK(callContractFunction(\n\t\t\t\"data(string,string)\",\n\t\t\tu256(0x40),\n\t\t\tu256(roundTo32(static_cast<unsigned>(0x60 + strings[i].size()))),\n\t\t\tu256(strings[i].size()),\n\t\t\tstrings[i],\n\t\t\tu256(strings[i+1].size()),\n\t\t\tstrings[i+1]\n\t\t), encodeArgs(u256(7 + i)));\n}\n\nBOOST_AUTO_TEST_CASE(nested_mixed_string_as_public_mapping_key)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Test {\n\t\t\tmapping(string =>\n\t\t\t\tmapping(int =>\n\t\t\t\t\tmapping(address =>\n\t\t\t\t\t\tmapping(bytes => int)))) public data;\n\n\t\t\tfunction set(\n\t\t\t\tstring memory _s1,\n\t\t\t\tint _s2,\n\t\t\t\taddress _s3,\n\t\t\t\tbytes memory _s4,\n\t\t\t\tint _value\n\t\t\t) public\n\t\t\t{\n\t\t\t\tdata[_s1][_s2][_s3][_s4] = _value;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"Test\");\n\n\tstruct Index\n\t{\n\t\tstd::string s1;\n\t\tint s2;\n\t\tint s3;\n\t\tstd::string s4;\n\t};\n\n\tstd::vector<Index> data{\n\t\t{ \"aabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcbc\", 4, 23, \"efg\" },\n\t\t{ \"tiaron\", 456, 63245, \"908apzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapzapz\" },\n\t\t{ \"\", 2345, 12934, \"665i65i65i65i65i65i65i65i65i65i65i65i65i65i65i65i65i65i5iart\" },\n\t\t{ \"¡¿…\", 9781, 8148, \"\" },\n\t\t{ \"ρν♀♀ω₂₃♀\", 929608, 303030, \"\" }\n\t};\n\n\tfor (size_t i = 0; i + 1 < data.size(); i++)\n\t\tABI_CHECK(callContractFunction(\n\t\t\t\"set(string,int256,address,bytes,int256)\",\n\t\t\tu256(0xA0),\n\t\t\tu256(data[i].s2),\n\t\t\tu256(data[i].s3),\n\t\t\tu256(roundTo32(static_cast<unsigned>(0xC0 + data[i].s1.size()))),\n\t\t\tu256(i - 3),\n\t\t\tu256(data[i].s1.size()),\n\t\t\tdata[i].s1,\n\t\t\tu256(data[i].s4.size()),\n\t\t\tdata[i].s4\n\t\t), encodeArgs());\n\tfor (size_t i = 0; i + 1 < data.size(); i++)\n\t\tABI_CHECK(callContractFunction(\n\t\t\t\"data(string,int256,address,bytes)\",\n\t\t\tu256(0x80),\n\t\t\tu256(data[i].s2),\n\t\t\tu256(data[i].s3),\n\t\t\tu256(roundTo32(static_cast<unsigned>(0xA0 + data[i].s1.size()))),\n\t\t\tu256(data[i].s1.size()),\n\t\t\tdata[i].s1,\n\t\t\tu256(data[i].s4.size()),\n\t\t\tdata[i].s4\n\t\t), encodeArgs(u256(i - 3)));\n}\n\nBOOST_AUTO_TEST_CASE(library_call)\n{\n\tchar const* sourceCode = R\"(\n\t\tlibrary Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\n\t\tcontract Test {\n\t\t\tfunction f(uint x) public returns (uint) {\n\t\t\t\treturn Lib.m(x, 9);\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"Lib\");\n\t\tcompileAndRun(sourceCode, 0, \"Test\", bytes(), std::map<std::string, h160>{{\":Lib\", m_contractAddress}});\n\t\tABI_CHECK(callContractFunction(\"f(uint256)\", u256(33)), encodeArgs(u256(33) * 9));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(library_function_external)\n{\n\tchar const* sourceCode = R\"(\n\t\tlibrary Lib { function m(bytes calldata b) external pure returns (bytes1) { return b[2]; } }\n\t\tcontract Test {\n\t\t\tfunction f(bytes memory b) public pure returns (bytes1) {\n\t\t\t\treturn Lib.m(b);\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"Lib\");\n\t\tcompileAndRun(sourceCode, 0, \"Test\", bytes(), std::map<std::string, h160>{{\":Lib\", m_contractAddress}});\n\t\tABI_CHECK(callContractFunction(\"f(bytes)\", u256(0x20), u256(5), \"abcde\"), encodeArgs(\"c\"));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(using_library_mappings_external)\n{\n\tchar const* libSourceCode = R\"(\n\t\t\tlibrary Lib {\n\t\t\t\tfunction set(mapping(uint => uint) storage m, uint key, uint value) external\n\t\t\t\t{\n\t\t\t\t\tm[key] = value * 2;\n\t\t\t\t}\n\t\t\t}\n\t\t)\";\n\tchar const* sourceCode = R\"(\n\t\t\tlibrary Lib {\n\t\t\t\tfunction set(mapping(uint => uint) storage m, uint key, uint value) external {}\n\t\t\t}\n\t\t\tcontract Test {\n\t\t\t\tmapping(uint => uint) m1;\n\t\t\t\tmapping(uint => uint) m2;\n\t\t\t\tfunction f() public returns (uint, uint, uint, uint, uint, uint)\n\t\t\t\t{\n\t\t\t\t\tLib.set(m1, 0, 1);\n\t\t\t\t\tLib.set(m1, 2, 42);\n\t\t\t\t\tLib.set(m2, 0, 23);\n\t\t\t\t\tLib.set(m2, 2, 99);\n\t\t\t\t\treturn (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n\t\t\t\t}\n\t\t\t}\n\t\t)\";\n\tfor (auto v2: {false, true})\n\t{\n\t\tstd::string prefix = \"pragma abicoder \" + std::string(v2 ? \"v2\" : \"v1\") + \";\\n\";\n\t\tcompileAndRun(prefix + libSourceCode, 0, \"Lib\");\n\t\tcompileAndRun(prefix + sourceCode, 0, \"Test\", bytes(), std::map<std::string, h160>{{\":Lib\", m_contractAddress}});\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(u256(2), u256(0), u256(84), u256(46), u256(0), u256(198)));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(short_strings)\n{\n\t// This test verifies that the byte array encoding that combines length and data works\n\t// correctly.\n\tchar const* sourceCode = R\"(\n\t\tcontract A {\n\t\t\tbytes public data1 = \"123\";\n\t\t\tbytes data2;\n\t\t\tfunction lengthChange() public returns (uint)\n\t\t\t{\n\t\t\t\t// store constant in short and long string\n\t\t\t\tdata1 = \"123\";\n\t\t\t\tif (!equal(data1, \"123\")) return 1;\n\t\t\t\tdata2 = \"12345678901234567890123456789012345678901234567890a\";\n\t\t\t\tif (data2[17] != \"8\") return 3;\n\t\t\t\tif (data2.length != 51) return 4;\n\t\t\t\tif (data2[data2.length - 1] != \"a\") return 5;\n\t\t\t\t// change length: short -> short\n\t\t\t\twhile (data1.length < 5)\n\t\t\t\t\tdata1.push();\n\t\t\t\tif (data1.length != 5) return 6;\n\t\t\t\tdata1[4] = \"4\";\n\t\t\t\tif (data1[0] != \"1\") return 7;\n\t\t\t\tif (data1[4] != \"4\") return 8;\n\t\t\t\t// change length: short -> long\n\t\t\t\twhile (data1.length < 80)\n\t\t\t\t\tdata1.push();\n\t\t\t\tif (data1.length != 80) return 9;\n\t\t\t\twhile (data1.length > 70)\n\t\t\t\t\tdata1.pop();\n\t\t\t\tif (data1.length != 70) return 9;\n\t\t\t\tif (data1[0] != \"1\") return 10;\n\t\t\t\tif (data1[4] != \"4\") return 11;\n\t\t\t\tfor (uint i = 0; i < data1.length; i ++)\n\t\t\t\t\tdata1[i] = bytes1(uint8(i * 3));\n\t\t\t\tif (uint8(data1[4]) != 4 * 3) return 12;\n\t\t\t\tif (uint8(data1[67]) != 67 * 3) return 13;\n\t\t\t\t// change length: long -> short\n\t\t\t\twhile (data1.length > 22)\n\t\t\t\t\tdata1.pop();\n\t\t\t\tif (data1.length != 22) return 14;\n\t\t\t\tif (uint8(data1[21]) != 21 * 3) return 15;\n\t\t\t\tif (uint8(data1[2]) != 2 * 3) return 16;\n\t\t\t\t// change length: short -> shorter\n\t\t\t\twhile (data1.length > 19)\n\t\t\t\t\tdata1.pop();\n\t\t\t\tif (data1.length != 19) return 17;\n\t\t\t\tif (uint8(data1[7]) != 7 * 3) return 18;\n\t\t\t\t// and now again to original size\n\t\t\t\twhile (data1.length < 22)\n\t\t\t\t\tdata1.push();\n\t\t\t\tif (data1.length != 22) return 19;\n\t\t\t\tif (data1[21] != 0) return 20;\n\t\t\t\twhile (data1.length > 0)\n\t\t\t\t\tdata1.pop();\n\t\t\t\twhile (data2.length > 0)\n\t\t\t\t\tdata2.pop();\n\t\t\t}\n\t\t\tfunction copy() public returns (uint) {\n\t\t\t\tbytes memory x = \"123\";\n\t\t\t\tbytes memory y = \"012345678901234567890123456789012345678901234567890123456789\";\n\t\t\t\tbytes memory z = \"1234567\";\n\t\t\t\tdata1 = x;\n\t\t\t\tdata2 = y;\n\t\t\t\tif (!equal(data1, x)) return 1;\n\t\t\t\tif (!equal(data2, y)) return 2;\n\t\t\t\t// lengthen\n\t\t\t\tdata1 = y;\n\t\t\t\tif (!equal(data1, y)) return 3;\n\t\t\t\t// shorten\n\t\t\t\tdata1 = x;\n\t\t\t\tif (!equal(data1, x)) return 4;\n\t\t\t\t// change while keeping short\n\t\t\t\tdata1 = z;\n\t\t\t\tif (!equal(data1, z)) return 5;\n\t\t\t\t// copy storage -> storage\n\t\t\t\tdata1 = x;\n\t\t\t\tdata2 = y;\n\t\t\t\t// lengthen\n\t\t\t\tdata1 = data2;\n\t\t\t\tif (!equal(data1, y)) return 6;\n\t\t\t\t// shorten\n\t\t\t\tdata1 = x;\n\t\t\t\tdata2 = data1;\n\t\t\t\tif (!equal(data2, x)) return 7;\n\t\t\t\tbytes memory c = data2;\n\t\t\t\tdata1 = c;\n\t\t\t\tif (!equal(data1, x)) return 8;\n\t\t\t\tdata1 = \"\";\n\t\t\t\tdata2 = \"\";\n\t\t\t}\n\t\t\tfunction deleteElements() public returns (uint) {\n\t\t\t\tdata1 = \"01234\";\n\t\t\t\tdelete data1[2];\n\t\t\t\tif (data1[2] != 0) return 1;\n\t\t\t\tif (data1[0] != \"0\") return 2;\n\t\t\t\tif (data1[3] != \"3\") return 3;\n\t\t\t\tdelete data1;\n\t\t\t\tif (data1.length != 0) return 4;\n\t\t\t}\n\n\t\t\tfunction equal(bytes storage a, bytes memory b) internal returns (bool) {\n\t\t\t\tif (a.length != b.length) return false;\n\t\t\t\tfor (uint i = 0; i < a.length; ++i) if (a[i] != b[i]) return false;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"A\");\n\t\tABI_CHECK(callContractFunction(\"data1()\"), encodeDyn(std::string(\"123\")));\n\t\tABI_CHECK(callContractFunction(\"lengthChange()\"), encodeArgs(u256(0)));\n\t\tBOOST_CHECK(storageEmpty(m_contractAddress));\n\t\tABI_CHECK(callContractFunction(\"deleteElements()\"), encodeArgs(u256(0)));\n\t\tBOOST_CHECK(storageEmpty(m_contractAddress));\n\t\tABI_CHECK(callContractFunction(\"copy()\"), encodeArgs(u256(0)));\n\t\tBOOST_CHECK(storageEmpty(m_contractAddress));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(calldata_offset)\n{\n\t// This tests a specific bug that was caused by not using the correct memory offset in the\n\t// calldata unpacker.\n\tchar const* sourceCode = R\"(\n\t\tcontract CB\n\t\t{\n\t\t\taddress[] _arr;\n\t\t\tstring public last = \"nd\";\n\t\t\tconstructor(address[] memory guardians)\n\t\t\t{\n\t\t\t\t_arr = guardians;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"CB\", encodeArgs(u256(0x20), u256(0x00)));\n\tABI_CHECK(callContractFunction(\"last()\", encodeArgs()), encodeDyn(std::string(\"nd\")));\n}\n\nBOOST_AUTO_TEST_CASE(reject_ether_sent_to_library)\n{\n\tchar const* sourceCode = R\"(\n\t\tlibrary lib {}\n\t\tcontract c {\n\t\t\tconstructor() payable {}\n\t\t\tfunction f(address payable x) public returns (bool) {\n\t\t\t\treturn x.send(1);\n\t\t\t}\n\t\t\treceive () external payable {}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"lib\");\n\t\tAddress libraryAddress = m_contractAddress;\n\t\tcompileAndRun(sourceCode, 10, \"c\");\n\t\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10);\n\t\tBOOST_CHECK_EQUAL(balanceAt(libraryAddress), 0);\n\t\tABI_CHECK(callContractFunction(\"f(address)\", encodeArgs(libraryAddress)), encodeArgs(false));\n\t\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10);\n\t\tBOOST_CHECK_EQUAL(balanceAt(libraryAddress), 0);\n\t\tABI_CHECK(callContractFunction(\"f(address)\", encodeArgs(m_contractAddress)), encodeArgs(true));\n\t\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10);\n\t\tBOOST_CHECK_EQUAL(balanceAt(libraryAddress), 0);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(create_memory_array_allocation_size)\n{\n\t// Check allocation size of byte array. Should be 32 plus length rounded up to next\n\t// multiple of 32\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f() public pure returns (uint d1, uint d2, uint d3, uint memsize) {\n\t\t\t\tbytes memory b1 = new bytes(31);\n\t\t\t\tbytes memory b2 = new bytes(32);\n\t\t\t\tbytes memory b3 = new bytes(256);\n\t\t\t\tbytes memory b4 = new bytes(31);\n\t\t\t\tassembly {\n\t\t\t\t\td1 := sub(b2, b1)\n\t\t\t\t\td2 := sub(b3, b2)\n\t\t\t\t\td3 := sub(b4, b3)\n\t\t\t\t\tmemsize := msize()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t)\";\n\tif (!m_optimiserSettings.runYulOptimiser)\n\t{\n\t\tcompileAndRun(sourceCode);\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(0x40, 0x40, 0x20 + 256, 0x260));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(inline_long_string_return)\n{\n\t\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f() public returns (string memory) {\n\t\t\t\treturn ([\"somethingShort\", \"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\"][1]);\n\t\t\t}\n\t\t}\n\t)\";\n\n\tstd::string strLong = \"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n\tcompileAndRun(sourceCode, 0, \"C\");\n\tABI_CHECK(callContractFunction(\"f()\"), encodeDyn(strLong));\n}\n\nBOOST_AUTO_TEST_CASE(index_access_with_type_conversion)\n{\n\t// Test for a bug where higher order bits cleanup was not done for array index access.\n\tchar const* sourceCode = R\"(\n\t\t\tcontract C {\n\t\t\t\tfunction f(uint x) public returns (uint[256] memory r){\n\t\t\t\t\tr[uint8(x)] = 2;\n\t\t\t\t}\n\t\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"C\");\n\t// neither of the two should throw due to out-of-bounds access\n\tBOOST_CHECK(callContractFunction(\"f(uint256)\", u256(0x01)).size() == 256 * 32);\n\tBOOST_CHECK(callContractFunction(\"f(uint256)\", u256(0x101)).size() == 256 * 32);\n}\n\nBOOST_AUTO_TEST_CASE(correctly_initialize_memory_array_in_constructor)\n{\n\t// Memory arrays are initialized using calldatacopy past the size of the calldata.\n\t// This test checks that it also works in the constructor context.\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tbool public success;\n\t\t\tconstructor() {\n\t\t\t\t// Make memory dirty.\n\t\t\t\tassembly {\n\t\t\t\t\tfor { let i := 0 } lt(i, 64) { i := add(i, 1) } {\n\t\t\t\t\t\tmstore(msize(), not(0))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tuint16[3] memory c;\n\t\t\t\trequire(c[0] == 0 && c[1] == 0 && c[2] == 0);\n\t\t\t\tuint16[] memory x = new uint16[](3);\n\t\t\t\trequire(x[0] == 0 && x[1] == 0 && x[2] == 0);\n\t\t\t\tsuccess = true;\n\t\t\t}\n\t\t}\n\t)\";\n\t// Cannot run against yul optimizer because of msize\n\tif (!m_optimiserSettings.runYulOptimiser)\n\t{\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tABI_CHECK(callContractFunction(\"success()\"), encodeArgs(u256(1)));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(mutex)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract mutexed {\n\t\t\tbool locked;\n\t\t\tmodifier protected {\n\t\t\t\tif (locked) revert();\n\t\t\t\tlocked = true;\n\t\t\t\t_;\n\t\t\t\tlocked = false;\n\t\t\t}\n\t\t}\n\t\tcontract Fund is mutexed {\n\t\t\tuint shares;\n\t\t\tconstructor() payable { shares = msg.value; }\n\t\t\tfunction withdraw(uint amount) public protected returns (uint) {\n\t\t\t\t// NOTE: It is very bad practice to write this function this way.\n\t\t\t\t// Please refer to the documentation of how to do this properly.\n\t\t\t\tif (amount > shares) revert();\n\t\t\t\t(bool success,) = msg.sender.call{value: amount}(\"\");\n\t\t\t\trequire(success);\n\t\t\t\tshares -= amount;\n\t\t\t\treturn shares;\n\t\t\t}\n\t\t\tfunction withdrawUnprotected(uint amount) public returns (uint) {\n\t\t\t\t// NOTE: It is very bad practice to write this function this way.\n\t\t\t\t// Please refer to the documentation of how to do this properly.\n\t\t\t\tif (amount > shares) revert();\n\t\t\t\t(bool success,) = msg.sender.call{value: amount}(\"\");\n\t\t\t\trequire(success);\n\t\t\t\tshares -= amount;\n\t\t\t\treturn shares;\n\t\t\t}\n\t\t}\n\t\tcontract Attacker {\n\t\t\tFund public fund;\n\t\t\tuint callDepth;\n\t\t\tbool protected;\n\t\t\tfunction setProtected(bool _protected) public { protected = _protected; }\n\t\t\tconstructor(Fund _fund) { fund = _fund; }\n\t\t\tfunction attack() public returns (uint) {\n\t\t\t\tcallDepth = 0;\n\t\t\t\treturn attackInternal();\n\t\t\t}\n\t\t\tfunction attackInternal() internal returns (uint) {\n\t\t\t\tif (protected)\n\t\t\t\t\treturn fund.withdraw(10);\n\t\t\t\telse\n\t\t\t\t\treturn fund.withdrawUnprotected(10);\n\t\t\t}\n\t\t\tfallback() external payable {\n\t\t\t\tcallDepth++;\n\t\t\t\tif (callDepth < 4)\n\t\t\t\t\tattackInternal();\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 500, \"Fund\");\n\th160 const fund = m_contractAddress;\n\tBOOST_CHECK_EQUAL(balanceAt(fund), 500);\n\tcompileAndRun(sourceCode, 0, \"Attacker\", encodeArgs(fund));\n\tABI_CHECK(callContractFunction(\"setProtected(bool)\", true), encodeArgs());\n\tABI_CHECK(callContractFunction(\"attack()\"), encodeArgs());\n\tBOOST_CHECK_EQUAL(balanceAt(fund), 500);\n\tABI_CHECK(callContractFunction(\"setProtected(bool)\", false), encodeArgs());\n\tABI_CHECK(callContractFunction(\"attack()\"), encodeArgs(u256(460)));\n\tBOOST_CHECK_EQUAL(balanceAt(fund), 460);\n}\n\nBOOST_AUTO_TEST_CASE(payable_function)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tuint public a;\n\t\t\tfunction f() payable public returns (uint) {\n\t\t\t\treturn msg.value;\n\t\t\t}\n\t\t\tfallback() external payable {\n\t\t\t\ta = msg.value + 1;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"C\");\n\tABI_CHECK(callContractFunctionWithValue(\"f()\", 27), encodeArgs(u256(27)));\n\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 27);\n\tABI_CHECK(callContractFunctionWithValue(\"\", 27), encodeArgs());\n\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 27 + 27);\n\tABI_CHECK(callContractFunction(\"a()\"), encodeArgs(u256(28)));\n\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 27 + 27);\n}\n\nBOOST_AUTO_TEST_CASE(non_payable_throw)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tuint public a;\n\t\t\tfunction f() public returns (uint) {\n\t\t\t\treturn msgvalue();\n\t\t\t}\n\t\t\tfunction msgvalue() internal returns (uint) {\n\t\t\t\treturn msg.value;\n\t\t\t}\n\t\t\tfallback() external {\n\t\t\t\tupdate();\n\t\t\t}\n\t\t\tfunction update() internal {\n\t\t\t\ta = msg.value + 1;\n\t\t\t}\n\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tABI_CHECK(callContractFunctionWithValue(\"f()\", 27), encodeArgs());\n\t\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);\n\t\tABI_CHECK(callContractFunction(\"\"), encodeArgs());\n\t\tABI_CHECK(callContractFunction(\"a()\"), encodeArgs(u256(1)));\n\t\tABI_CHECK(callContractFunctionWithValue(\"\", 27), encodeArgs());\n\t\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);\n\t\tABI_CHECK(callContractFunction(\"a()\"), encodeArgs(u256(1)));\n\t\tABI_CHECK(callContractFunctionWithValue(\"a()\", 27), encodeArgs());\n\t\tBOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call)\n{\n\t// This tests that memory resize for return values is not paid during the call, which would\n\t// make the gas calculation overly complex. We access the end of the output area before\n\t// the call is made.\n\t// Tests that this also survives the optimizer.\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f() public returns (uint[200] memory) {}\n\t\t}\n\t\tcontract D {\n\t\t\tfunction f(C c) public returns (uint) { c.f(); return 7; }\n\t\t}\n\t)\";\n\n\tcompileAndRun(sourceCode, 0, \"C\");\n\th160 const cAddr = m_contractAddress;\n\tcompileAndRun(sourceCode, 0, \"D\");\n\tABI_CHECK(callContractFunction(\"f(address)\", cAddr), encodeArgs(u256(7)));\n}\n\nBOOST_AUTO_TEST_CASE(receive_external_function_type)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction g() public returns (uint) { return 7; }\n\t\t\tfunction f(function() external returns (uint) g) public returns (uint) {\n\t\t\t\treturn g();\n\t\t\t}\n\t\t}\n\t)\";\n\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tABI_CHECK(callContractFunction(\n\t\t\t\"f(function)\",\n\t\t\tm_contractAddress.asBytes() + util::selectorFromSignatureH32(\"g()\").asBytes() + bytes(32 - 4 - 20, 0)\n\t\t), encodeArgs(u256(7)));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(return_external_function_type)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction g() public {}\n\t\t\tfunction f() public returns (function() external) {\n\t\t\t\treturn this.g;\n\t\t\t}\n\t\t}\n\t)\";\n\n\tcompileAndRun(sourceCode, 0, \"C\");\n\tABI_CHECK(\n\t\tcallContractFunction(\"f()\"),\n\t\tm_contractAddress.asBytes() + util::selectorFromSignatureH32(\"g()\").asBytes() + bytes(32 - 4 - 20, 0)\n\t);\n}\n\n// TODO: store attached internal library functions\n\nBOOST_AUTO_TEST_CASE(shift_bytes)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction left(bytes20 x, uint8 y) public returns (bytes20) {\n\t\t\t\treturn x << y;\n\t\t\t}\n\t\t\tfunction right(bytes20 x, uint8 y) public returns (bytes20) {\n\t\t\t\treturn x >> y;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"C\");\n\tABI_CHECK(callContractFunction(\"left(bytes20,uint8)\", \"12345678901234567890\", 8 * 8), encodeArgs(\"901234567890\" + std::string(8, 0)));\n\tABI_CHECK(callContractFunction(\"right(bytes20,uint8)\", \"12345678901234567890\", 8 * 8), encodeArgs(std::string(8, 0) + \"123456789012\"));\n}\n\nBOOST_AUTO_TEST_CASE(contracts_separated_with_comment)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C1 {}\n\t\t/**\n\t\t**/\n\t\tcontract C2 {}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"C1\");\n\t\tcompileAndRun(sourceCode, 0, \"C2\");\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(include_creation_bytecode_only_once)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract D {\n\t\t\tbytes a = hex\"1237651237125387136581271652831736512837126583171583712358126123765123712538713658127165283173651283712658317158371235812612376512371253871365812716528317365128371265831715837123581261237651237125387136581271652831736512837126583171583712358126\";\n\t\t\tbytes b = hex\"1237651237125327136581271252831736512837126583171383712358126123765125712538713658127165253173651283712658357158371235812612376512371a5387136581271652a317365128371265a317158371235812612a765123712538a13658127165a83173651283712a58317158371235a126\";\n\t\t\tconstructor(uint) {}\n\t\t}\n\t\tcontract Double {\n\t\t\tfunction f() public {\n\t\t\t\tnew D(2);\n\t\t\t}\n\t\t\tfunction g() public {\n\t\t\t\tnew D(3);\n\t\t\t}\n\t\t}\n\t\tcontract Single {\n\t\t\tfunction f() public {\n\t\t\t\tnew D(2);\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode);\n\tBOOST_CHECK_LE(\n\t\tdouble(m_compiler.object(\"Double\").bytecode.size()),\n\t\t1.2 * double(m_compiler.object(\"Single\").bytecode.size())\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(revert_with_cause)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract D {\n\t\t\tstring constant msg1 = \"test1234567890123456789012345678901234567890\";\n\t\t\tstring msg2 = \"test1234567890123456789012345678901234567890\";\n\t\t\tfunction f() public {\n\t\t\t\trevert(\"test123\");\n\t\t\t}\n\t\t\tfunction g() public {\n\t\t\t\trevert(\"test1234567890123456789012345678901234567890\");\n\t\t\t}\n\t\t\tfunction h() public {\n\t\t\t\trevert(msg1);\n\t\t\t}\n\t\t\tfunction i() public {\n\t\t\t\trevert(msg2);\n\t\t\t}\n\t\t\tfunction j() public {\n\t\t\t\tstring memory msg3 = \"test1234567890123456789012345678901234567890\";\n\t\t\t\trevert(msg3);\n\t\t\t}\n\t\t}\n\t\tcontract C {\n\t\t\tD d = new D();\n\t\t\tfunction forward(address target, bytes memory data) internal returns (bool success, bytes memory retval) {\n\t\t\t\tuint retsize;\n\t\t\t\tassembly {\n\t\t\t\t\tsuccess := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0)\n\t\t\t\t\tretsize := returndatasize()\n\t\t\t\t}\n\t\t\t\tretval = new bytes(retsize);\n\t\t\t\tassembly {\n\t\t\t\t\treturndatacopy(add(retval, 0x20), 0, returndatasize())\n\t\t\t\t}\n\t\t\t}\n\t\t\tfunction f() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t\tfunction g() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t\tfunction h() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t\tfunction i() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t\tfunction j() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t}\n\t)\";\n\tif (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())\n\t{\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tbytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, \"test123\") + bytes(28, 0));\n\t\tABI_CHECK(callContractFunction(\"g()\"), encodeArgs(0, 0x40, 0x84) + errorSignature + encodeArgs(0x20, 44, \"test1234567890123456789012345678901234567890\") + bytes(28, 0));\n\t\tABI_CHECK(callContractFunction(\"h()\"), encodeArgs(0, 0x40, 0x84) + errorSignature + encodeArgs(0x20, 44, \"test1234567890123456789012345678901234567890\") + bytes(28, 0));\n\t\tABI_CHECK(callContractFunction(\"i()\"), encodeArgs(0, 0x40, 0x84) + errorSignature + encodeArgs(0x20, 44, \"test1234567890123456789012345678901234567890\") + bytes(28, 0));\n\t\tABI_CHECK(callContractFunction(\"j()\"), encodeArgs(0, 0x40, 0x84) + errorSignature + encodeArgs(0x20, 44, \"test1234567890123456789012345678901234567890\") + bytes(28, 0));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(require_with_message)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract D {\n\t\t\tbool flag = false;\n\t\t\tstring storageError = \"abc\";\n\t\t\tstring constant constantError = \"abc\";\n\t\t\tfunction f(uint x) public {\n\t\t\t\trequire(x > 7, \"failed\");\n\t\t\t}\n\t\t\tfunction g() public {\n\t\t\t\t// As a side-effect of internalFun, the flag will be set to true\n\t\t\t\t// (even if the condition is true),\n\t\t\t\t// but it will only throw in the next evaluation.\n\t\t\t\tbool flagCopy = flag;\n\t\t\t\trequire(flagCopy == false, internalFun());\n\t\t\t}\n\t\t\tfunction internalFun() public returns (string memory) {\n\t\t\t\tflag = true;\n\t\t\t\treturn \"only on second run\";\n\t\t\t}\n\t\t\tfunction h() public {\n\t\t\t\trequire(false, storageError);\n\t\t\t}\n\t\t\tfunction i() public {\n\t\t\t\trequire(false, constantError);\n\t\t\t}\n\t\t\tfunction j() public {\n\t\t\t\tstring memory errMsg = \"msg\";\n\t\t\t\trequire(false, errMsg);\n\t\t\t}\n\t\t}\n\t\tcontract C {\n\t\t\tD d = new D();\n\t\t\tfunction forward(address target, bytes memory data) internal returns (bool success, bytes memory retval) {\n\t\t\t\tuint retsize;\n\t\t\t\tassembly {\n\t\t\t\t\tsuccess := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0)\n\t\t\t\t\tretsize := returndatasize()\n\t\t\t\t}\n\t\t\t\tretval = new bytes(retsize);\n\t\t\t\tassembly {\n\t\t\t\t\treturndatacopy(add(retval, 0x20), 0, returndatasize())\n\t\t\t\t}\n\t\t\t}\n\t\t\tfunction f(uint x) public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t\tfunction g() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t\tfunction h() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t\tfunction i() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t\tfunction j() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t}\n\t)\";\n\tif (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())\n\t{\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tbytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};\n\t\tABI_CHECK(callContractFunction(\"f(uint256)\", 8), encodeArgs(1, 0x40, 0));\n\t\tABI_CHECK(callContractFunction(\"f(uint256)\", 5), encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 6, \"failed\") + bytes(28, 0));\n\t\tABI_CHECK(callContractFunction(\"g()\"), encodeArgs(1, 0x40, 0));\n\t\tABI_CHECK(callContractFunction(\"g()\"), encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 18, \"only on second run\") + bytes(28, 0));\n\t\tABI_CHECK(callContractFunction(\"h()\"), encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 3, \"abc\") + bytes(28, 0));\n\t\tABI_CHECK(callContractFunction(\"i()\"), encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 3, \"abc\") + bytes(28, 0));\n\t\tABI_CHECK(callContractFunction(\"j()\"), encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 3, \"msg\") + bytes(28, 0));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(bubble_up_error_messages)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract D {\n\t\t\tfunction f() public {\n\t\t\t\trevert(\"message\");\n\t\t\t}\n\t\t\tfunction g() public {\n\t\t\t\tthis.f();\n\t\t\t}\n\t\t}\n\t\tcontract C {\n\t\t\tD d = new D();\n\t\t\tfunction forward(address target, bytes memory data) internal returns (bool success, bytes memory retval) {\n\t\t\t\tuint retsize;\n\t\t\t\tassembly {\n\t\t\t\t\tsuccess := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0)\n\t\t\t\t\tretsize := returndatasize()\n\t\t\t\t}\n\t\t\t\tretval = new bytes(retsize);\n\t\t\t\tassembly {\n\t\t\t\t\treturndatacopy(add(retval, 0x20), 0, returndatasize())\n\t\t\t\t}\n\t\t\t}\n\t\t\tfunction f() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t\tfunction g() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t}\n\t)\";\n\tif (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())\n\t{\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tbytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, \"message\") + bytes(28, 0));\n\t\tABI_CHECK(callContractFunction(\"g()\"), encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, \"message\") + bytes(28, 0));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(bubble_up_error_messages_through_transfer)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract D {\n\t\t\treceive() external payable {\n\t\t\t\trevert(\"message\");\n\t\t\t}\n\t\t\tfunction f() public {\n\t\t\t\tpayable(this).transfer(0);\n\t\t\t}\n\t\t}\n\t\tcontract C {\n\t\t\tD d = new D();\n\t\t\tfunction forward(address target, bytes memory data) internal returns (bool success, bytes memory retval) {\n\t\t\t\tuint retsize;\n\t\t\t\tassembly {\n\t\t\t\t\tsuccess := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0)\n\t\t\t\t\tretsize := returndatasize()\n\t\t\t\t}\n\t\t\t\tretval = new bytes(retsize);\n\t\t\t\tassembly {\n\t\t\t\t\treturndatacopy(add(retval, 0x20), 0, returndatasize())\n\t\t\t\t}\n\t\t\t}\n\t\t\tfunction f() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t}\n\t)\";\n\tif (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())\n\t{\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tbytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, \"message\") + bytes(28, 0));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(bubble_up_error_messages_through_create)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract E {\n\t\t\tconstructor() {\n\t\t\t\trevert(\"message\");\n\t\t\t}\n\t\t}\n\t\tcontract D {\n\t\t\tfunction f() public {\n\t\t\t\tE x = new E();\n\t\t\t}\n\t\t}\n\t\tcontract C {\n\t\t\tD d = new D();\n\t\t\tfunction forward(address target, bytes memory data) internal returns (bool success, bytes memory retval) {\n\t\t\t\tuint retsize;\n\t\t\t\tassembly {\n\t\t\t\t\tsuccess := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0)\n\t\t\t\t\tretsize := returndatasize()\n\t\t\t\t}\n\t\t\t\tretval = new bytes(retsize);\n\t\t\t\tassembly {\n\t\t\t\t\treturndatacopy(add(retval, 0x20), 0, returndatasize())\n\t\t\t\t}\n\t\t\t}\n\t\t\tfunction f() public returns (bool, bytes memory) {\n\t\t\t\treturn forward(address(d), msg.data);\n\t\t\t}\n\t\t}\n\t)\";\n\tif (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())\n\t{\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tbytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, \"message\") + bytes(28, 0));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(interface_contract)\n{\n\tchar const* sourceCode = R\"(\n\t\tinterface I {\n\t\t\tevent A();\n\t\t\tfunction f() external returns (bool);\n\t\t\tfallback() external payable;\n\t\t}\n\n\t\tcontract A is I {\n\t\t\tfunction f() public override returns (bool) {\n\t\t\t\treturn g();\n\t\t\t}\n\n\t\t\tfunction g() public returns (bool) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tfallback() override external payable {\n\t\t\t}\n\t\t}\n\n\t\tcontract C {\n\t\t\tfunction f(address payable _interfaceAddress) public returns (bool) {\n\t\t\t\tI i = I(_interfaceAddress);\n\t\t\t\treturn i.f();\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"A\");\n\th160 const recipient = m_contractAddress;\n\tcompileAndRun(sourceCode, 0, \"C\");\n\tABI_CHECK(callContractFunction(\"f(address)\", recipient), encodeArgs(true));\n}\n\nBOOST_AUTO_TEST_CASE(bare_call_invalid_address)\n{\n\tchar const* sourceCode = R\"YY(\n\t\tcontract C {\n\t\t\t/// Calling into non-existent account is successful (creates the account)\n\t\t\tfunction f() external returns (bool) {\n\t\t\t\t(bool success,) = address(0x4242).call(\"\");\n\t\t\t\treturn success;\n\t\t\t}\n\t\t\tfunction h() external returns (bool) {\n\t\t\t\t(bool success,) = address(0x4242).delegatecall(\"\");\n\t\t\t\treturn success;\n\t\t\t}\n\t\t}\n\t)YY\";\n\tcompileAndRun(sourceCode, 0, \"C\");\n\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(u256(1)));\n\tABI_CHECK(callContractFunction(\"h()\"), encodeArgs(u256(1)));\n\n\tif (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())\n\t{\n\t\tchar const* sourceCode = R\"YY(\n\t\t\tcontract C {\n\t\t\t\tfunction f() external returns (bool, bytes memory) {\n\t\t\t\t\treturn address(0x4242).staticcall(\"\");\n\t\t\t\t}\n\t\t\t}\n\t\t)YY\";\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tABI_CHECK(callContractFunction(\"f()\"), encodeArgs(u256(1), 0x40, 0x00));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(bare_call_return_data)\n{\n\tif (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())\n\t{\n\t\tstd::vector<std::string> calltypes = {\"call\", \"delegatecall\"};\n\t\tif (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())\n\t\t\tcalltypes.emplace_back(\"staticcall\");\n\t\tfor (std::string const& calltype: calltypes)\n\t\t{\n\t\t\tstd::string sourceCode = R\"DELIMITER(\n\t\t\t\tcontract A {\n\t\t\t\t\tconstructor() {\n\t\t\t\t\t}\n\t\t\t\t\tfunction return_bool() public pure returns(bool) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tfunction return_int32() public pure returns(int32) {\n\t\t\t\t\t\treturn -32;\n\t\t\t\t\t}\n\t\t\t\t\tfunction return_uint32() public pure returns(uint32) {\n\t\t\t\t\t\treturn 0x3232;\n\t\t\t\t\t}\n\t\t\t\t\tfunction return_int256() public pure returns(int256) {\n\t\t\t\t\t\treturn -256;\n\t\t\t\t\t}\n\t\t\t\t\tfunction return_uint256() public pure returns(uint256) {\n\t\t\t\t\t\treturn 0x256256;\n\t\t\t\t\t}\n\t\t\t\t\tfunction return_bytes4() public pure returns(bytes4) {\n\t\t\t\t\t\treturn 0xabcd0012;\n\t\t\t\t\t}\n\t\t\t\t\tfunction return_multi() public pure returns(bool, uint32, bytes4) {\n\t\t\t\t\t\treturn (false, 0x3232, 0xabcd0012);\n\t\t\t\t\t}\n\t\t\t\t\tfunction return_bytes() public pure returns(bytes memory b) {\n\t\t\t\t\t\tb = new bytes(2);\n\t\t\t\t\t\tb[0] = 0x42;\n\t\t\t\t\t\tb[1] = 0x21;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontract C {\n\t\t\t\t\tA addr;\n\t\t\t\t\tconstructor() {\n\t\t\t\t\t\taddr = new A();\n\t\t\t\t\t}\n\t\t\t\t\tfunction f(string memory signature) public returns (bool, bytes memory) {\n\t\t\t\t\t\treturn address(addr).)DELIMITER\" + calltype + R\"DELIMITER((abi.encodeWithSignature(signature));\n\t\t\t\t\t}\n\t\t\t\t\tfunction check_bool() external returns (bool) {\n\t\t\t\t\t\t(bool success, bytes memory data) = f(\"return_bool()\");\n\t\t\t\t\t\tassert(success);\n\t\t\t\t\t\tbool a = abi.decode(data, (bool));\n\t\t\t\t\t\tassert(a);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tfunction check_int32() external returns (bool) {\n\t\t\t\t\t\t(bool success, bytes memory data) = f(\"return_int32()\");\n\t\t\t\t\t\tassert(success);\n\t\t\t\t\t\tint32 a = abi.decode(data, (int32));\n\t\t\t\t\t\tassert(a == -32);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tfunction check_uint32() external returns (bool) {\n\t\t\t\t\t\t(bool success, bytes memory data) = f(\"return_uint32()\");\n\t\t\t\t\t\tassert(success);\n\t\t\t\t\t\tuint32 a = abi.decode(data, (uint32));\n\t\t\t\t\t\tassert(a == 0x3232);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tfunction check_int256() external returns (bool) {\n\t\t\t\t\t\t(bool success, bytes memory data) = f(\"return_int256()\");\n\t\t\t\t\t\tassert(success);\n\t\t\t\t\t\tint256 a = abi.decode(data, (int256));\n\t\t\t\t\t\tassert(a == -256);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tfunction check_uint256() external returns (bool) {\n\t\t\t\t\t\t(bool success, bytes memory data) = f(\"return_uint256()\");\n\t\t\t\t\t\tassert(success);\n\t\t\t\t\t\tuint256 a = abi.decode(data, (uint256));\n\t\t\t\t\t\tassert(a == 0x256256);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tfunction check_bytes4() external returns (bool) {\n\t\t\t\t\t\t(bool success, bytes memory data) = f(\"return_bytes4()\");\n\t\t\t\t\t\tassert(success);\n\t\t\t\t\t\tbytes4 a = abi.decode(data, (bytes4));\n\t\t\t\t\t\tassert(a == 0xabcd0012);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tfunction check_multi() external returns (bool) {\n\t\t\t\t\t\t(bool success, bytes memory data) = f(\"return_multi()\");\n\t\t\t\t\t\tassert(success);\n\t\t\t\t\t\t(bool a, uint32 b, bytes4 c) = abi.decode(data, (bool, uint32, bytes4));\n\t\t\t\t\t\tassert(a == false && b == 0x3232 && c == 0xabcd0012);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tfunction check_bytes() external returns (bool) {\n\t\t\t\t\t\t(bool success, bytes memory data) = f(\"return_bytes()\");\n\t\t\t\t\t\tassert(success);\n\t\t\t\t\t\t(bytes memory d) = abi.decode(data, (bytes));\n\t\t\t\t\t\tassert(d.length == 2 && d[0] == 0x42 && d[1] == 0x21);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)DELIMITER\";\n\t\t\tALSO_VIA_YUL(\n\t\t\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\t\t\tABI_CHECK(callContractFunction(\"f(string)\", encodeDyn(std::string(\"return_bool()\"))), encodeArgs(true, 0x40, 0x20, true));\n\t\t\t\tABI_CHECK(callContractFunction(\"f(string)\", encodeDyn(std::string(\"return_int32()\"))), encodeArgs(true, 0x40, 0x20, u256(-32)));\n\t\t\t\tABI_CHECK(callContractFunction(\"f(string)\", encodeDyn(std::string(\"return_uint32()\"))), encodeArgs(true, 0x40, 0x20, u256(0x3232)));\n\t\t\t\tABI_CHECK(callContractFunction(\"f(string)\", encodeDyn(std::string(\"return_int256()\"))), encodeArgs(true, 0x40, 0x20, u256(-256)));\n\t\t\t\tABI_CHECK(callContractFunction(\"f(string)\", encodeDyn(std::string(\"return_uint256()\"))), encodeArgs(true, 0x40, 0x20, u256(0x256256)));\n\t\t\t\tABI_CHECK(callContractFunction(\"f(string)\", encodeDyn(std::string(\"return_bytes4()\"))), encodeArgs(true, 0x40, 0x20, u256(0xabcd0012) << (28*8)));\n\t\t\t\tABI_CHECK(callContractFunction(\"f(string)\", encodeDyn(std::string(\"return_multi()\"))), encodeArgs(true, 0x40, 0x60, false, u256(0x3232), u256(0xabcd0012) << (28*8)));\n\t\t\t\tABI_CHECK(callContractFunction(\"f(string)\", encodeDyn(std::string(\"return_bytes()\"))), encodeArgs(true, 0x40, 0x60, 0x20, 0x02, encode(bytes{0x42,0x21}, false)));\n\t\t\t\tABI_CHECK(callContractFunction(\"check_bool()\"), encodeArgs(true));\n\t\t\t\tABI_CHECK(callContractFunction(\"check_int32()\"), encodeArgs(true));\n\t\t\t\tABI_CHECK(callContractFunction(\"check_uint32()\"), encodeArgs(true));\n\t\t\t\tABI_CHECK(callContractFunction(\"check_int256()\"), encodeArgs(true));\n\t\t\t\tABI_CHECK(callContractFunction(\"check_uint256()\"), encodeArgs(true));\n\t\t\t\tABI_CHECK(callContractFunction(\"check_bytes4()\"), encodeArgs(true));\n\t\t\t\tABI_CHECK(callContractFunction(\"check_multi()\"), encodeArgs(true));\n\t\t\t\tABI_CHECK(callContractFunction(\"check_bytes()\"), encodeArgs(true));\n\t\t\t)\n\t\t}\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(abi_encodePacked)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f0() public pure returns (bytes memory) {\n\t\t\t\treturn abi.encodePacked();\n\t\t\t}\n\t\t\tfunction f1() public pure returns (bytes memory) {\n\t\t\t\treturn abi.encodePacked(uint8(1), uint8(2));\n\t\t\t}\n\t\t\tfunction f2() public pure returns (bytes memory) {\n\t\t\t\tstring memory x = \"abc\";\n\t\t\t\treturn abi.encodePacked(uint8(1), x, uint8(2));\n\t\t\t}\n\t\t\tfunction f3() public pure returns (bytes memory r) {\n\t\t\t\t// test that memory is properly allocated\n\t\t\t\tstring memory x = \"abc\";\n\t\t\t\tr = abi.encodePacked(uint8(1), x, uint8(2));\n\t\t\t\tbytes memory y = \"def\";\n\t\t\t\trequire(y[0] == \"d\");\n\t\t\t\ty[0] = \"e\";\n\t\t\t\trequire(y[0] == \"e\");\n\t\t\t}\n\t\t\tfunction f4() public pure returns (bytes memory) {\n\t\t\t\tstring memory x = \"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\";\n\t\t\t\treturn abi.encodePacked(uint16(0x0701), x, uint16(0x1201));\n\t\t\t}\n\t\t\tfunction f_literal() public pure returns (bytes memory) {\n\t\t\t\treturn abi.encodePacked(uint8(0x01), \"abc\", uint8(0x02));\n\t\t\t}\n\t\t\tfunction f_calldata() public pure returns (bytes memory) {\n\t\t\t\treturn abi.encodePacked(uint8(0x01), msg.data, uint8(0x02));\n\t\t\t}\n\t\t}\n\t)\";\n\tfor (auto v2: {false, true})\n\t{\n\t\tALSO_VIA_YUL(\n\t\t\tstd::string prefix = \"pragma abicoder \" + std::string(v2 ? \"v2\" : \"v1\") + \";\\n\";\n\t\t\tcompileAndRun(prefix + sourceCode, 0, \"C\");\n\t\t\tABI_CHECK(callContractFunction(\"f0()\"), encodeArgs(0x20, 0));\n\t\t\tABI_CHECK(callContractFunction(\"f1()\"), encodeArgs(0x20, 2, \"\\x01\\x02\"));\n\t\t\tABI_CHECK(callContractFunction(\"f2()\"), encodeArgs(0x20, 5, \"\\x01\" \"abc\" \"\\x02\"));\n\t\t\tABI_CHECK(callContractFunction(\"f3()\"), encodeArgs(0x20, 5, \"\\x01\" \"abc\" \"\\x02\"));\n\t\t\tABI_CHECK(callContractFunction(\"f4()\"), encodeArgs(0x20, 2 + 26 + 26 + 2, \"\\x07\\x01\" \"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\" \"\\x12\\x01\"));\n\t\t\tABI_CHECK(callContractFunction(\"f_literal()\"), encodeArgs(0x20, 5, \"\\x01\" \"abc\" \"\\x02\"));\n\t\t\tABI_CHECK(callContractFunction(\"f_calldata()\"), encodeArgs(0x20, 6, \"\\x01\" \"\\xa5\\xbf\\xa1\\xee\" \"\\x02\"));\n\t\t)\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(abi_encodePacked_from_storage)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tuint24[9] small_fixed;\n\t\t\tint24[9] small_fixed_signed;\n\t\t\tuint24[] small_dyn;\n\t\t\tuint248[5] large_fixed;\n\t\t\tuint248[] large_dyn;\n\t\t\tbytes bytes_storage;\n\t\t\tfunction sf() public returns (bytes memory) {\n\t\t\t\tsmall_fixed[0] = 0xfffff1;\n\t\t\t\tsmall_fixed[2] = 0xfffff2;\n\t\t\t\tsmall_fixed[5] = 0xfffff3;\n\t\t\t\tsmall_fixed[8] = 0xfffff4;\n\t\t\t\treturn abi.encodePacked(uint8(0x01), small_fixed, uint8(0x02));\n\t\t\t}\n\t\t\tfunction sd() public returns (bytes memory) {\n\t\t\t\tsmall_dyn.push(0xfffff1);\n\t\t\t\tsmall_dyn.push(0x00);\n\t\t\t\tsmall_dyn.push(0xfffff2);\n\t\t\t\tsmall_dyn.push(0x00);\n\t\t\t\tsmall_dyn.push(0x00);\n\t\t\t\tsmall_dyn.push(0xfffff3);\n\t\t\t\tsmall_dyn.push(0x00);\n\t\t\t\tsmall_dyn.push(0x00);\n\t\t\t\tsmall_dyn.push(0xfffff4);\n\t\t\t\treturn abi.encodePacked(uint8(0x01), small_dyn, uint8(0x02));\n\t\t\t}\n\t\t\tfunction sfs() public returns (bytes memory) {\n\t\t\t\tsmall_fixed_signed[0] = -2;\n\t\t\t\tsmall_fixed_signed[2] = 0xffff2;\n\t\t\t\tsmall_fixed_signed[5] = -200;\n\t\t\t\tsmall_fixed_signed[8] = 0xffff4;\n\t\t\t\treturn abi.encodePacked(uint8(0x01), small_fixed_signed, uint8(0x02));\n\t\t\t}\n\t\t\tfunction lf() public returns (bytes memory) {\n\t\t\t\tlarge_fixed[0] = 2**248-1;\n\t\t\t\tlarge_fixed[1] = 0xfffff2;\n\t\t\t\tlarge_fixed[2] = 2**248-2;\n\t\t\t\tlarge_fixed[4] = 0xfffff4;\n\t\t\t\treturn abi.encodePacked(uint8(0x01), large_fixed, uint8(0x02));\n\t\t\t}\n\t\t\tfunction ld() public returns (bytes memory) {\n\t\t\t\tlarge_dyn.push(2**248-1);\n\t\t\t\tlarge_dyn.push(0xfffff2);\n\t\t\t\tlarge_dyn.push(2**248-2);\n\t\t\t\tlarge_dyn.push(0);\n\t\t\t\tlarge_dyn.push(0xfffff4);\n\t\t\t\treturn abi.encodePacked(uint8(0x01), large_dyn, uint8(0x02));\n\t\t\t}\n\t\t\tfunction bytes_short() public returns (bytes memory) {\n\t\t\t\tbytes_storage = \"abcd\";\n\t\t\t\treturn abi.encodePacked(uint8(0x01), bytes_storage, uint8(0x02));\n\t\t\t}\n\t\t\tfunction bytes_long() public returns (bytes memory) {\n\t\t\t\tbytes_storage = \"0123456789012345678901234567890123456789\";\n\t\t\t\treturn abi.encodePacked(uint8(0x01), bytes_storage, uint8(0x02));\n\t\t\t}\n\t\t}\n\t)\";\n\tfor (auto v2: {false, true})\n\t{\n\t\tALSO_VIA_YUL(\n\t\t\tstd::string prefix = \"pragma abicoder \" + std::string(v2 ? \"v2\" : \"v1\") + \";\\n\";\n\t\t\tcompileAndRun(prefix + sourceCode, 0, \"C\");\n\t\t\tbytes payload = encodeArgs(0xfffff1, 0, 0xfffff2, 0, 0, 0xfffff3, 0, 0, 0xfffff4);\n\t\t\tbytes encoded = encodeArgs(0x20, 0x122, \"\\x01\" + asString(payload) + \"\\x02\");\n\t\t\tABI_CHECK(callContractFunction(\"sf()\"), encoded);\n\t\t\tABI_CHECK(callContractFunction(\"sd()\"), encoded);\n\t\t\tABI_CHECK(callContractFunction(\"sfs()\"), encodeArgs(0x20, 0x122, \"\\x01\" + asString(encodeArgs(\n\t\t\t\tu256(-2), 0, 0xffff2, 0, 0, u256(-200), 0, 0, 0xffff4\n\t\t\t)) + \"\\x02\"));\n\t\t\tpayload = encodeArgs(\n\t\t\t\tu256(\"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"),\n\t\t\t\t0xfffff2,\n\t\t\t\tu256(\"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\"),\n\t\t\t\t0,\n\t\t\t\t0xfffff4\n\t\t\t);\n\t\t\tABI_CHECK(callContractFunction(\"lf()\"), encodeArgs(0x20, 5 * 32 + 2, \"\\x01\" + asString(encodeArgs(payload)) + \"\\x02\"));\n\t\t\tABI_CHECK(callContractFunction(\"ld()\"), encodeArgs(0x20, 5 * 32 + 2, \"\\x01\" + asString(encodeArgs(payload)) + \"\\x02\"));\n\t\t\tABI_CHECK(callContractFunction(\"bytes_short()\"), encodeArgs(0x20, 6, \"\\x01\" \"abcd\\x02\"));\n\t\t\tABI_CHECK(callContractFunction(\"bytes_long()\"), encodeArgs(0x20, 42, \"\\x01\" \"0123456789012345678901234567890123456789\\x02\"));\n\t\t)\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(abi_encodePacked_from_memory)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction sf() public pure returns (bytes memory) {\n\t\t\t\tuint24[9] memory small_fixed;\n\t\t\t\tsmall_fixed[0] = 0xfffff1;\n\t\t\t\tsmall_fixed[2] = 0xfffff2;\n\t\t\t\tsmall_fixed[5] = 0xfffff3;\n\t\t\t\tsmall_fixed[8] = 0xfffff4;\n\t\t\t\treturn abi.encodePacked(uint8(0x01), small_fixed, uint8(0x02));\n\t\t\t}\n\t\t\tfunction sd() public pure returns (bytes memory) {\n\t\t\t\tuint24[] memory small_dyn = new uint24[](9);\n\t\t\t\tsmall_dyn[0] = 0xfffff1;\n\t\t\t\tsmall_dyn[2] = 0xfffff2;\n\t\t\t\tsmall_dyn[5] = 0xfffff3;\n\t\t\t\tsmall_dyn[8] = 0xfffff4;\n\t\t\t\treturn abi.encodePacked(uint8(0x01), small_dyn, uint8(0x02));\n\t\t\t}\n\t\t\tfunction sfs() public pure returns (bytes memory) {\n\t\t\t\tint24[9] memory small_fixed_signed;\n\t\t\t\tsmall_fixed_signed[0] = -2;\n\t\t\t\tsmall_fixed_signed[2] = 0xffff2;\n\t\t\t\tsmall_fixed_signed[5] = -200;\n\t\t\t\tsmall_fixed_signed[8] = 0xffff4;\n\t\t\t\treturn abi.encodePacked(uint8(0x01), small_fixed_signed, uint8(0x02));\n\t\t\t}\n\t\t\tfunction lf() public pure returns (bytes memory) {\n\t\t\t\tuint248[5] memory large_fixed;\n\t\t\t\tlarge_fixed[0] = 2**248-1;\n\t\t\t\tlarge_fixed[1] = 0xfffff2;\n\t\t\t\tlarge_fixed[2] = 2**248-2;\n\t\t\t\tlarge_fixed[4] = 0xfffff4;\n\t\t\t\treturn abi.encodePacked(uint8(0x01), large_fixed, uint8(0x02));\n\t\t\t}\n\t\t\tfunction ld() public pure returns (bytes memory) {\n\t\t\t\tuint248[] memory large_dyn = new uint248[](5);\n\t\t\t\tlarge_dyn[0] = 2**248-1;\n\t\t\t\tlarge_dyn[1] = 0xfffff2;\n\t\t\t\tlarge_dyn[2] = 2**248-2;\n\t\t\t\tlarge_dyn[4] = 0xfffff4;\n\t\t\t\treturn abi.encodePacked(uint8(0x01), large_dyn, uint8(0x02));\n\t\t\t}\n\t\t}\n\t)\";\n\tfor (auto v2: {false, true})\n\t{\n\t\tALSO_VIA_YUL(\n\t\t\tstd::string prefix = \"pragma abicoder \" + std::string(v2 ? \"v2\" : \"v1\") + \";\\n\";\n\t\t\tcompileAndRun(prefix + sourceCode, 0, \"C\");\n\t\t\tbytes payload = encodeArgs(0xfffff1, 0, 0xfffff2, 0, 0, 0xfffff3, 0, 0, 0xfffff4);\n\t\t\tbytes encoded = encodeArgs(0x20, 0x122, \"\\x01\" + asString(payload) + \"\\x02\");\n\t\t\tABI_CHECK(callContractFunction(\"sf()\"), encoded);\n\t\t\tABI_CHECK(callContractFunction(\"sd()\"), encoded);\n\t\t\tABI_CHECK(callContractFunction(\"sfs()\"), encodeArgs(0x20, 0x122, \"\\x01\" + asString(encodeArgs(\n\t\t\t\tu256(-2), 0, 0xffff2, 0, 0, u256(-200), 0, 0, 0xffff4\n\t\t\t)) + \"\\x02\"));\n\t\t\tpayload = encodeArgs(\n\t\t\t\tu256(\"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"),\n\t\t\t\t0xfffff2,\n\t\t\t\tu256(\"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\"),\n\t\t\t\t0,\n\t\t\t\t0xfffff4\n\t\t\t);\n\t\t\tABI_CHECK(callContractFunction(\"lf()\"), encodeArgs(0x20, 5 * 32 + 2, \"\\x01\" + asString(encodeArgs(payload)) + \"\\x02\"));\n\t\t\tABI_CHECK(callContractFunction(\"ld()\"), encodeArgs(0x20, 5 * 32 + 2, \"\\x01\" + asString(encodeArgs(payload)) + \"\\x02\"));\n\t\t)\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(abi_encodePacked_functionPtr)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tC other = C(0x1112131400000000000011121314000000000087);\n\t\t\tfunction testDirect() public view returns (bytes memory) {\n\t\t\t\treturn abi.encodePacked(uint8(8), other.f, uint8(2));\n\t\t\t}\n\t\t\tfunction testFixedArray() public view returns (bytes memory) {\n\t\t\t\tfunction () external pure returns (bytes memory)[1] memory x;\n\t\t\t\tx[0] = other.f;\n\t\t\t\treturn abi.encodePacked(uint8(8), x, uint8(2));\n\t\t\t}\n\t\t\tfunction testDynamicArray() public view returns (bytes memory) {\n\t\t\t\tfunction () external pure returns (bytes memory)[] memory x = new function() external pure returns (bytes memory)[](1);\n\t\t\t\tx[0] = other.f;\n\t\t\t\treturn abi.encodePacked(uint8(8), x, uint8(2));\n\t\t\t}\n\t\t\tfunction f() public pure returns (bytes memory) {}\n\t\t}\n\t)\";\n\tfor (auto v2: {false, true})\n\t{\n\t\tALSO_VIA_YUL(\n\t\t\tstd::string prefix = \"pragma abicoder \" + std::string(v2 ? \"v2\" : \"v1\") + \";\\n\";\n\t\t\tcompileAndRun(prefix + sourceCode, 0, \"C\");\n\t\t\tstd::string directEncoding = asString(fromHex(\"08\" \"1112131400000000000011121314000000000087\" \"26121ff0\" \"02\"));\n\t\t\tABI_CHECK(callContractFunction(\"testDirect()\"), encodeArgs(0x20, directEncoding.size(), directEncoding));\n\t\t\tstd::string arrayEncoding = asString(fromHex(\"08\" \"1112131400000000000011121314000000000087\" \"26121ff0\" \"0000000000000000\" \"02\"));\n\t\t\tABI_CHECK(callContractFunction(\"testFixedArray()\"), encodeArgs(0x20, arrayEncoding.size(), arrayEncoding));\n\t\t\tABI_CHECK(callContractFunction(\"testDynamicArray()\"), encodeArgs(0x20, arrayEncoding.size(), arrayEncoding));\n\t\t)\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(abi_encodePackedV2_structs)\n{\n\tchar const* sourceCode = R\"(\n\t\tpragma abicoder v2;\n\t\tcontract C {\n\t\t\tstruct S {\n\t\t\t\tuint8 a;\n\t\t\t\tint16 b;\n\t\t\t\tuint8[2] c;\n\t\t\t\tint16[] d;\n\t\t\t}\n\t\t\tS s;\n\t\t\tevent E(S indexed);\n\t\t\tconstructor() {\n\t\t\t\ts.a = 0x12;\n\t\t\t\ts.b = -7;\n\t\t\t\ts.c[0] = 2;\n\t\t\t\ts.c[1] = 3;\n\t\t\t\ts.d.push(-7);\n\t\t\t\ts.d.push(-8);\n\t\t\t}\n\t\t\tfunction testStorage() public {\n\t\t\t\temit E(s);\n\t\t\t}\n\t\t\tfunction testMemory() public {\n\t\t\t\tS memory m = s;\n\t\t\t\temit E(m);\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tbytes structEnc = encodeArgs(int(0x12), u256(-7), int(2), int(3), u256(-7), u256(-8));\n\t\tABI_CHECK(callContractFunction(\"testStorage()\"), encodeArgs());\n\t\tBOOST_REQUIRE_EQUAL(numLogTopics(0), 2);\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(std::string(\"E((uint8,int16,uint8[2],int16[]))\")));\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 1), util::keccak256(asString(structEnc)));\n\t\tABI_CHECK(callContractFunction(\"testMemory()\"), encodeArgs());\n\t\tBOOST_REQUIRE_EQUAL(numLogTopics(0), 2);\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(std::string(\"E((uint8,int16,uint8[2],int16[]))\")));\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 1), util::keccak256(asString(structEnc)));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(abi_encodePackedV2_nestedArray)\n{\n\tchar const* sourceCode = R\"(\n\t\tpragma abicoder v2;\n\t\tcontract C {\n\t\t\tstruct S {\n\t\t\t\tuint8 a;\n\t\t\t\tint16 b;\n\t\t\t}\n\t\t\tevent E(S[2][][3] indexed);\n\t\t\tfunction testNestedArrays() public {\n\t\t\t\tS[2][][3] memory x;\n\t\t\t\tx[1] = new S[2][](2);\n\t\t\t\tx[1][0][0].a = 1;\n\t\t\t\tx[1][0][0].b = 2;\n\t\t\t\tx[1][0][1].a = 3;\n\t\t\t\tx[1][1][1].b = 4;\n\t\t\t\temit E(x);\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tbytes structEnc = encodeArgs(1, 2, 3, 0, 0, 0, 0, 4);\n\t\tABI_CHECK(callContractFunction(\"testNestedArrays()\"), encodeArgs());\n\t\tBOOST_REQUIRE_EQUAL(numLogTopics(0), 2);\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(std::string(\"E((uint8,int16)[2][][3])\")));\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 1), util::keccak256(asString(structEnc)));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(abi_encodePackedV2_arrayOfStrings)\n{\n\tchar const* sourceCode = R\"(\n\t\tpragma abicoder v2;\n\t\tcontract C {\n\t\t\tstring[] x;\n\t\t\tevent E(string[] indexed);\n\t\t\tconstructor() {\n\t\t\t\tx.push(\"abc\");\n\t\t\t\tx.push(\"0123456789012345678901234567890123456789\");\n\t\t\t}\n\t\t\tfunction testStorage() public {\n\t\t\t\temit E(x);\n\t\t\t}\n\t\t\tfunction testMemory() public {\n\t\t\t\tstring[] memory y = x;\n\t\t\t\temit E(y);\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\tbytes arrayEncoding = encodeArgs(\"abc\", \"0123456789012345678901234567890123456789\");\n\t\tABI_CHECK(callContractFunction(\"testStorage()\"), encodeArgs());\n\t\tBOOST_REQUIRE_EQUAL(numLogTopics(0), 2);\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(std::string(\"E(string[])\")));\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 1), util::keccak256(asString(arrayEncoding)));\n\t\tABI_CHECK(callContractFunction(\"testMemory()\"), encodeArgs());\n\t\tBOOST_REQUIRE_EQUAL(numLogTopics(0), 2);\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(std::string(\"E(string[])\")));\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 1), util::keccak256(asString(arrayEncoding)));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(code_access)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction lengths() public pure returns (bool) {\n\t\t\t\tuint crLen = type(D).creationCode.length;\n\t\t\t\tuint runLen = type(D).runtimeCode.length;\n\t\t\t\trequire(runLen < crLen);\n\t\t\t\trequire(crLen >= 0x20);\n\t\t\t\trequire(runLen >= 0x20);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tfunction creation() public pure returns (bytes memory) {\n\t\t\t\treturn type(D).creationCode;\n\t\t\t}\n\t\t\tfunction runtime() public pure returns (bytes memory) {\n\t\t\t\treturn type(D).runtimeCode;\n\t\t\t}\n\t\t\tfunction runtimeAllocCheck() public pure returns (bytes memory) {\n\t\t\t\tuint[] memory a = new uint[](2);\n\t\t\t\tbytes memory c = type(D).runtimeCode;\n\t\t\t\tuint[] memory b = new uint[](2);\n\t\t\t\ta[0] = 0x1111;\n\t\t\t\ta[1] = 0x2222;\n\t\t\t\tb[0] = 0x3333;\n\t\t\t\tb[1] = 0x4444;\n\t\t\t\treturn c;\n\t\t\t}\n\t\t}\n\t\tcontract D {\n\t\t\tfunction f() public pure returns (uint) { return 7; }\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"C\");\n\tABI_CHECK(callContractFunction(\"lengths()\"), encodeArgs(true));\n\tbytes codeCreation = callContractFunction(\"creation()\");\n\tbytes codeRuntime1 = callContractFunction(\"runtime()\");\n\tbytes codeRuntime2 = callContractFunction(\"runtimeAllocCheck()\");\n\tABI_CHECK(codeRuntime1, codeRuntime2);\n}\n\nBOOST_AUTO_TEST_CASE(contract_name)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tstring public nameAccessor = type(C).name;\n\t\t\tstring public constant constantNameAccessor = type(C).name;\n\n\t\t\tfunction name() public virtual pure returns (string memory) {\n\t\t\t\treturn type(C).name;\n\t\t\t}\n\t\t}\n\t\tcontract D is C {\n\t\t\tfunction name() public override pure returns (string memory) {\n\t\t\t\treturn type(D).name;\n\t\t\t}\n\t\t\tfunction name2() public pure returns (string memory) {\n\t\t\t\treturn type(C).name;\n\t\t\t}\n\t\t}\n\t\tcontract ThisIsAVeryLongContractNameExceeding256bits {\n\t\t\tstring public nameAccessor = type(ThisIsAVeryLongContractNameExceeding256bits).name;\n\t\t\tstring public constant constantNameAccessor = type(ThisIsAVeryLongContractNameExceeding256bits).name;\n\n\t\t\tfunction name() public pure returns (string memory) {\n\t\t\t\treturn type(ThisIsAVeryLongContractNameExceeding256bits).name;\n\t\t\t}\n\t\t}\n\t)\";\n\n\tcompileAndRun(sourceCode, 0, \"C\");\n\tbytes argsC = encodeArgs(u256(0x20), u256(1), \"C\");\n\tABI_CHECK(callContractFunction(\"name()\"), argsC);\n\tABI_CHECK(callContractFunction(\"nameAccessor()\"), argsC);\n\tABI_CHECK(callContractFunction(\"constantNameAccessor()\"), argsC);\n\n\tcompileAndRun(sourceCode, 0, \"D\");\n\tbytes argsD = encodeArgs(u256(0x20), u256(1), \"D\");\n\tABI_CHECK(callContractFunction(\"name()\"), argsD);\n\tABI_CHECK(callContractFunction(\"name2()\"), argsC);\n\n\tstd::string longName = \"ThisIsAVeryLongContractNameExceeding256bits\";\n\tcompileAndRun(sourceCode, 0, longName);\n\tbytes argsLong = encodeArgs(u256(0x20), u256(longName.length()), longName);\n\tABI_CHECK(callContractFunction(\"name()\"), argsLong);\n\tABI_CHECK(callContractFunction(\"nameAccessor()\"), argsLong);\n\tABI_CHECK(callContractFunction(\"constantNameAccessor()\"), argsLong);\n}\n\nBOOST_AUTO_TEST_CASE(event_wrong_abi_name)\n{\n\tchar const* sourceCode = R\"(\n\t\tlibrary ClientReceipt {\n\t\t\tevent Deposit(Test indexed _from, bytes32 indexed _id, uint _value);\n\t\t\tfunction deposit(bytes32 _id) public {\n\t\t\t\tTest a;\n\t\t\t\temit Deposit(a, _id, msg.value);\n\t\t\t}\n\t\t}\n\t\tcontract Test {\n\t\t\tfunction f() public {\n\t\t\t\tClientReceipt.deposit(\"123\");\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tcompileAndRun(sourceCode, 0, \"ClientReceipt\", bytes());\n\t\tcompileAndRun(sourceCode, 0, \"Test\", bytes(), std::map<std::string, h160>{{\":ClientReceipt\", m_contractAddress}});\n\n\t\tcallContractFunction(\"f()\");\n\t\tBOOST_REQUIRE_EQUAL(numLogs(), 1);\n\t\tBOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);\n\t\tBOOST_REQUIRE_EQUAL(numLogTopics(0), 3);\n\t\tBOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(std::string(\"Deposit(address,bytes32,uint256)\")));\n\t)\n}\n\nBOOST_AUTO_TEST_CASE(dirty_scratch_space_prior_to_constant_optimiser)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tevent X(uint);\n\t\t\tconstructor() {\n\t\t\t\tassembly {\n\t\t\t\t\t// make scratch space dirty\n\t\t\t\t\tmstore(0, 0x4242424242424242424242424242424242424242424242424242424242424242)\n\t\t\t\t}\n\t\t\t\tuint x = 0x0000000000001234123412431234123412412342112341234124312341234124;\n\t\t\t\t// This is just to create many instances of x\n\t\t\t\tunchecked { emit X(x + f() * g(tx.origin) ^ h(block.number)); }\n\t\t\t\tassembly {\n\t\t\t\t\t// make scratch space dirty\n\t\t\t\t\tmstore(0, 0x4242424242424242424242424242424242424242424242424242424242424242)\n\t\t\t\t}\n\t\t\t\temit X(x);\n\t\t\t}\n\t\t\tfunction f() internal pure returns (uint) {\n\t\t\t\treturn 0x0000000000001234123412431234123412412342112341234124312341234124;\n\t\t\t}\n\t\t\tfunction g(address a) internal pure returns (uint) {\n\t\t\t\tunchecked { return uint(uint160(a)) * 0x0000000000001234123412431234123412412342112341234124312341234124; }\n\t\t\t}\n\t\t\tfunction h(uint a) internal pure returns (uint) {\n\t\t\t\tunchecked { return a * 0x0000000000001234123412431234123412412342112341234124312341234124; }\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileAndRun(sourceCode, 0, \"C\");\n\tBOOST_REQUIRE_EQUAL(numLogs(), 2);\n\tBOOST_CHECK_EQUAL(logAddress(1), m_contractAddress);\n\tABI_CHECK(\n\t\tlogData(1),\n\t\tencodeArgs(u256(\"0x0000000000001234123412431234123412412342112341234124312341234124\"))\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(strip_reason_strings)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f(bool _x) public pure returns (uint) {\n\t\t\t\trequire(_x, \"some reason\");\n\t\t\t\treturn 7;\n\t\t\t}\n\t\t\tfunction g(bool _x) public pure returns (uint) {\n\t\t\t\tstring memory x = \"some indirect reason\";\n\t\t\t\trequire(_x, x);\n\t\t\t\treturn 8;\n\t\t\t}\n\t\t\tfunction f1(bool _x) public pure returns (uint) {\n\t\t\t\tif (!_x) revert( /* */ \"some reason\" /* */ );\n\t\t\t\treturn 9;\n\t\t\t}\n\t\t\tfunction g1(bool _x) public pure returns (uint) {\n\t\t\t\tstring memory x = \"some indirect reason\";\n\t\t\t\tif (!_x) revert(x);\n\t\t\t\treturn 10;\n\t\t\t}\n\t\t}\n\t)\";\n\tALSO_VIA_YUL(\n\t\tm_revertStrings = RevertStrings::Default;\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\n\t\tif (\n\t\t\tm_optimiserSettings == OptimiserSettings::minimal() ||\n\t\t\tm_optimiserSettings == OptimiserSettings::none()\n\t\t)\n\t\t\t// check that the reason string IS part of the binary.\n\t\t\tBOOST_CHECK(util::toHex(m_output).find(\"736f6d6520726561736f6e\") != std::string::npos);\n\n\t\tm_revertStrings = RevertStrings::Strip;\n\t\tcompileAndRun(sourceCode, 0, \"C\");\n\t\t// check that the reason string is NOT part of the binary.\n\t\tBOOST_CHECK(util::toHex(m_output).find(\"736f6d6520726561736f6e\") == std::string::npos);\n\n\t\tABI_CHECK(callContractFunction(\"f(bool)\", true), encodeArgs(7));\n\t\tABI_CHECK(callContractFunction(\"f(bool)\", false), encodeArgs());\n\t\tABI_CHECK(callContractFunction(\"g(bool)\", true), encodeArgs(8));\n\t\tABI_CHECK(callContractFunction(\"g(bool)\", false), encodeArgs());\n\t\tABI_CHECK(callContractFunction(\"f1(bool)\", true), encodeArgs(9));\n\t\tABI_CHECK(callContractFunction(\"f1(bool)\", false), encodeArgs());\n\t\tABI_CHECK(callContractFunction(\"g1(bool)\", true), encodeArgs(10));\n\t\tABI_CHECK(callContractFunction(\"g1(bool)\", false), encodeArgs());\n\t)\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/SolidityExecutionFramework.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2016\n * Framework for executing Solidity contracts and testing them against C++ implementation.\n */\n\n#include <test/libsolidity/SolidityExecutionFramework.h>\n#include <test/libsolidity/util/Common.h>\n\n#include <liblangutil/DebugInfoSelection.h>\n#include <libyul/Exceptions.h>\n#include <liblangutil/Exceptions.h>\n#include <liblangutil/SourceReferenceFormatter.h>\n\n#include <boost/test/framework.hpp>\n\n#include <cstdlib>\n#include <iostream>\n\nusing namespace solidity;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\nusing namespace solidity::langutil;\nusing namespace solidity::test;\n\nbytes SolidityExecutionFramework::multiSourceCompileContract(\n\tstd::map<std::string, std::string> const& _sourceCode,\n\tstd::optional<std::string> const& _mainSourceName,\n\tstd::string const& _contractName,\n\tstd::map<std::string, Address> const& _libraryAddresses\n)\n{\n\tif (_mainSourceName.has_value())\n\t\tsolAssert(_sourceCode.find(_mainSourceName.value()) != _sourceCode.end(), \"\");\n\n\tm_compiler.reset();\n\tm_compiler.setSources(withPreamble(\n\t\t_sourceCode,\n\t\tsolidity::test::CommonOptions::get().useABIEncoderV1 // _addAbicoderV1Pragma\n\t));\n\tm_compiler.setLibraries(_libraryAddresses);\n\tm_compiler.setRevertStringBehaviour(m_revertStrings);\n\tm_compiler.setEVMVersion(m_evmVersion);\n\tm_compiler.setEOFVersion(m_eofVersion);\n\tm_compiler.setOptimiserSettings(m_optimiserSettings);\n\tm_compiler.setViaIR(m_compileViaYul);\n\tm_compiler.setViaSSACFG(m_compileViaSSACFG);\n\tm_compiler.setRevertStringBehaviour(m_revertStrings);\n\tif (!m_appendCBORMetadata) {\n\t\tm_compiler.setMetadataFormat(CompilerStack::MetadataFormat::NoMetadata);\n\t}\n\tm_compiler.setMetadataHash(m_metadataHash);\n\n\tif (!m_compiler.compile())\n\t{\n\t\t// The testing framework expects an exception for\n\t\t// \"unimplemented\" yul IR generation.\n\t\tif (m_compileViaYul)\n\t\t\tfor (auto const& error: m_compiler.errors())\n\t\t\t\tif (error->type() == langutil::Error::Type::CodeGenerationError)\n\t\t\t\t\tBOOST_THROW_EXCEPTION(*error);\n\t\tlangutil::SourceReferenceFormatter{std::cerr, m_compiler, true, false}\n\t\t\t.printErrorInformation(m_compiler.errors());\n\t\tBOOST_ERROR(\"Compiling contract failed\");\n\t}\n\tstd::string contractName(_contractName.empty() ? m_compiler.lastContractName(_mainSourceName) : _contractName);\n\tevmasm::LinkerObject obj = m_compiler.object(contractName);\n\tBOOST_REQUIRE(obj.linkReferences.empty());\n\tif (m_showMetadata)\n\t\tstd::cout << \"metadata: \" << m_compiler.metadata(contractName) << std::endl;\n\treturn obj.bytecode;\n}\n\nbytes SolidityExecutionFramework::compileContract(\n\tstd::string const& _sourceCode,\n\tstd::string const& _contractName,\n\tstd::map<std::string, Address> const& _libraryAddresses\n)\n{\n\treturn multiSourceCompileContract(\n\t\t{{\"\", _sourceCode}},\n\t\tstd::nullopt,\n\t\t_contractName,\n\t\t_libraryAddresses\n\t);\n}\n"
  },
  {
    "path": "test/libsolidity/SolidityExecutionFramework.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Framework for executing Solidity contracts and testing them against C++ implementation.\n */\n\n#pragma once\n\n#include <functional>\n\n#include <test/ExecutionFramework.h>\n\n#include <libsolidity/interface/CompilerStack.h>\n#include <libsolidity/interface/DebugSettings.h>\n\n#include <libyul/YulStack.h>\n\nnamespace solidity::frontend::test\n{\n\nclass SolidityExecutionFramework: public solidity::test::ExecutionFramework\n{\n\npublic:\n\tSolidityExecutionFramework(): m_showMetadata(solidity::test::CommonOptions::get().showMetadata) {}\n\texplicit SolidityExecutionFramework(\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tstd::optional<uint8_t> _eofVersion,\n\t\tstd::vector<boost::filesystem::path> const& _vmPaths,\n\t\tbool _appendCBORMetadata = true\n\t):\n\t\tExecutionFramework(_evmVersion, _vmPaths),\n\t\tm_eofVersion(_eofVersion),\n\t\tm_showMetadata(solidity::test::CommonOptions::get().showMetadata),\n\t\tm_appendCBORMetadata(_appendCBORMetadata)\n\t{}\n\n\tbytes const& compileAndRunWithoutCheck(\n\t\tstd::map<std::string, std::string> const& _sourceCode,\n\t\tu256 const& _value = 0,\n\t\tstd::string const& _contractName = \"\",\n\t\tbytes const& _arguments = {},\n\t\tstd::map<std::string, solidity::test::Address> const& _libraryAddresses = {},\n\t\tstd::optional<std::string> const& _sourceName = std::nullopt\n\t) override\n\t{\n\t\tbytes bytecode = multiSourceCompileContract(_sourceCode, _sourceName, _contractName, _libraryAddresses);\n\t\tsendMessage(bytecode, _arguments, true, _value);\n\t\treturn m_output;\n\t}\n\n\tbytes compileContract(\n\t\tstd::string const& _sourceCode,\n\t\tstd::string const& _contractName = \"\",\n\t\tstd::map<std::string, solidity::test::Address> const& _libraryAddresses = {}\n\t);\n\n\tbytes multiSourceCompileContract(\n\t\tstd::map<std::string, std::string> const& _sources,\n\t\tstd::optional<std::string> const& _mainSourceName = std::nullopt,\n\t\tstd::string const& _contractName = \"\",\n\t\tstd::map<std::string, solidity::test::Address> const& _libraryAddresses = {}\n\t);\n\nprotected:\n\tusing CompilerStack = solidity::frontend::CompilerStack;\n\tstd::optional<uint8_t> m_eofVersion;\n\tCompilerStack m_compiler;\n\tbool m_compileViaYul = false;\n\tbool m_compileViaSSACFG = false;\n\tbool m_showMetadata = false;\n\tbool m_appendCBORMetadata = true;\n\tCompilerStack::MetadataHash m_metadataHash = CompilerStack::MetadataHash::IPFS;\n\tRevertStrings m_revertStrings = RevertStrings::Default;\n};\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/SolidityExpressionCompiler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Unit tests for the solidity expression compiler.\n */\n\n#include <string>\n\n#include <liblangutil/Scanner.h>\n#include <libsolidity/parsing/Parser.h>\n#include <libsolidity/analysis/NameAndTypeResolver.h>\n#include <libsolidity/analysis/Scoper.h>\n#include <libsolidity/analysis/SyntaxChecker.h>\n#include <libsolidity/analysis/DeclarationTypeChecker.h>\n#include <libsolidity/codegen/CompilerContext.h>\n#include <libsolidity/codegen/ExpressionCompiler.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/analysis/TypeChecker.h>\n#include <liblangutil/ErrorReporter.h>\n#include <libevmasm/LinkerObject.h>\n#include <test/Common.h>\n\n#include <boost/test/unit_test.hpp>\n\nusing namespace solidity::evmasm;\nusing namespace solidity::langutil;\nusing namespace solidity::test;\n\nnamespace solidity::frontend::test\n{\n\nnamespace\n{\n\n/// Helper class that extracts the first expression in an AST.\nclass FirstExpressionExtractor: private ASTVisitor\n{\npublic:\n\tFirstExpressionExtractor(ASTNode& _node): m_expression(nullptr) { _node.accept(*this); }\n\tExpression* expression() const { return m_expression; }\nprivate:\n\tbool visit(Assignment& _expression) override { return checkExpression(_expression); }\n\tbool visit(UnaryOperation& _expression) override { return checkExpression(_expression); }\n\tbool visit(BinaryOperation& _expression) override { return checkExpression(_expression); }\n\tbool visit(FunctionCall& _expression) override { return checkExpression(_expression); }\n\tbool visit(MemberAccess& _expression) override { return checkExpression(_expression); }\n\tbool visit(IndexAccess& _expression) override { return checkExpression(_expression); }\n\tbool visit(Identifier& _expression) override { return checkExpression(_expression); }\n\tbool visit(ElementaryTypeNameExpression& _expression) override { return checkExpression(_expression); }\n\tbool visit(Literal& _expression) override { return checkExpression(_expression); }\n\tbool checkExpression(Expression& _expression)\n\t{\n\t\tif (m_expression == nullptr)\n\t\t\tm_expression = &_expression;\n\t\treturn false;\n\t}\nprivate:\n\tExpression* m_expression;\n};\n\nDeclaration const& resolveDeclaration(\n\tSourceUnit const& _sourceUnit,\n\tstd::vector<std::string> const& _namespacedName,\n\tNameAndTypeResolver const& _resolver\n)\n{\n\tASTNode const* scope = &_sourceUnit;\n\t// bracers are required, cause msvc couldn't handle this macro in for statement\n\tfor (std::string const& namePart: _namespacedName)\n\t{\n\t\tauto declarations = _resolver.resolveName(namePart, scope);\n\t\tBOOST_REQUIRE(!declarations.empty());\n\t\tBOOST_REQUIRE(scope = *declarations.begin());\n\t}\n\tBOOST_REQUIRE(scope);\n\treturn dynamic_cast<Declaration const&>(*scope);\n}\n\nbytes compileFirstExpression(\n\tstd::string const& _sourceCode,\n\tstd::vector<std::vector<std::string>> _functions = {},\n\tstd::vector<std::vector<std::string>> _localVariables = {}\n)\n{\n\tstd::string sourceCode = \"pragma solidity >=0.0; // SPDX-License-Identifier: GPL-3\\n\" + _sourceCode;\n\tCharStream stream(sourceCode, \"\");\n\n\tASTPointer<SourceUnit> sourceUnit;\n\ttry\n\t{\n\t\tErrorList errors;\n\t\tErrorReporter errorReporter(errors);\n\t\tsourceUnit = Parser(\n\t\t\terrorReporter,\n\t\t\tsolidity::test::CommonOptions::get().evmVersion(),\n\t\t\tsolidity::test::CommonOptions::get().eofVersion()\n\t\t).parse(stream);\n\t\tif (!sourceUnit)\n\t\t\treturn bytes();\n\t}\n\tcatch (...)\n\t{\n\t\tstd::string msg = \"Parsing source code failed with:\\n\" + boost::current_exception_diagnostic_information();\n\t\tBOOST_FAIL(msg);\n\t}\n\n\tErrorList errors;\n\tErrorReporter errorReporter(errors);\n\tGlobalContext globalContext(solidity::test::CommonOptions::get().evmVersion());\n\tScoper::assignScopes(*sourceUnit);\n\tBOOST_REQUIRE(SyntaxChecker(errorReporter, false /* _useYulOptimizer */, false /* _experimental */).checkSyntax(*sourceUnit));\n\tNameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), errorReporter, false);\n\tresolver.registerDeclarations(*sourceUnit);\n\tBOOST_REQUIRE_MESSAGE(resolver.resolveNamesAndTypes(*sourceUnit), \"Resolving names failed\");\n\tDeclarationTypeChecker declarationTypeChecker(errorReporter, solidity::test::CommonOptions::get().evmVersion());\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t\tBOOST_REQUIRE(declarationTypeChecker.check(*node));\n\tTypeChecker typeChecker(\n\t\tsolidity::test::CommonOptions::get().evmVersion(),\n\t\tsolidity::test::CommonOptions::get().eofVersion(),\n\t\terrorReporter\n\t);\n\tBOOST_REQUIRE(typeChecker.checkTypeRequirements(*sourceUnit));\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))\n\t\t{\n\t\t\tFirstExpressionExtractor extractor(*contract);\n\t\t\tBOOST_REQUIRE(extractor.expression() != nullptr);\n\n\t\t\tCompilerContext context(\n\t\t\t\tsolidity::test::CommonOptions::get().evmVersion(),\n\t\t\t\tsolidity::test::CommonOptions::get().eofVersion(),\n\t\t\t\tRevertStrings::Default\n\t\t\t);\n\t\t\tcontext.resetVisitedNodes(contract);\n\t\t\tcontext.setMostDerivedContract(*contract);\n\t\t\tcontext.setArithmetic(Arithmetic::Wrapping);\n\t\t\tsize_t parametersSize = _localVariables.size(); // assume they are all one slot on the stack\n\t\t\tcontext.adjustStackOffset(static_cast<int>(parametersSize));\n\t\t\tfor (std::vector<std::string> const& variable: _localVariables)\n\t\t\t\tcontext.addVariable(\n\t\t\t\t\tdynamic_cast<VariableDeclaration const&>(resolveDeclaration(*sourceUnit, variable, resolver)),\n\t\t\t\t\tstatic_cast<unsigned>(parametersSize--)\n\t\t\t\t);\n\n\t\t\tExpressionCompiler(\n\t\t\t\tcontext,\n\t\t\t\tsolidity::test::CommonOptions::get().optimize\n\t\t\t).compile(*extractor.expression());\n\n\t\t\tfor (std::vector<std::string> const& function: _functions)\n\t\t\t\tcontext << context.functionEntryLabel(dynamic_cast<FunctionDefinition const&>(\n\t\t\t\t\tresolveDeclaration(*sourceUnit, function, resolver)\n\t\t\t\t));\n\n\t\t\tcontext.appendMissingLowLevelFunctions();\n\t\t\t// NOTE: We intentionally disable optimisations for utility functions to simplify the tests\n\t\t\tcontext.appendYulUtilityFunctions({});\n\t\t\tBOOST_REQUIRE(context.appendYulUtilityFunctionsRan());\n\n\t\t\tBOOST_REQUIRE(context.assemblyPtr());\n\t\t\tLinkerObject const& object = context.assemblyPtr()->assemble();\n\t\t\tBOOST_REQUIRE(object.immutableReferences.empty());\n\t\t\tbytes instructions = object.bytecode;\n\t\t\t// debug\n\t\t\t// cout << evmasm::disassemble(instructions) << endl;\n\t\t\treturn instructions;\n\t\t}\n\tBOOST_FAIL(\"No contract found in source.\");\n\treturn bytes();\n}\n\n} // end anonymous namespace\n\nBOOST_AUTO_TEST_SUITE(SolidityExpressionCompiler)\n\nBOOST_AUTO_TEST_CASE(literal_true)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public { bool x = true; }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode);\n\n\tbytes expectation({uint8_t(Instruction::PUSH1), 0x1});\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(literal_false)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public { bool x = false; }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode);\n\n\tbytes expectation = solidity::test::CommonOptions::get().evmVersion().hasPush0() ?\n\t\tbytes{uint8_t(Instruction::PUSH0)} :\n\t\tbytes{uint8_t(Instruction::PUSH1), 0x0};\n\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(int_literal)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t  function f() public { uint x = 0x12345678901234567890; }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode);\n\n\tbytes expectation({uint8_t(Instruction::PUSH10), 0x12, 0x34, 0x56, 0x78, 0x90,\n\t\t\t\t\t\t\t\t\t\t\t\t\t   0x12, 0x34, 0x56, 0x78, 0x90});\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(int_with_wei_ether_subdenomination)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tconstructor() {\n\t\t\t\t uint x = 1 wei;\n\t\t\t}\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode);\n\n\tbytes expectation({uint8_t(Instruction::PUSH1), 0x1});\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(int_with_gwei_ether_subdenomination)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public {\n\t\t\t\tuint x = 1 gwei;\n\t\t\t}\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode);\n\n\tbytes expectation({uint8_t(Instruction::PUSH4), 0x3b, 0x9a, 0xca, 0x00});\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tconstructor() {\n\t\t\t\t uint x = 1 ether;\n\t\t\t}\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode);\n\n\tbytes expectation({uint8_t(Instruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00});\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(comparison)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public { bool x = (0x10aa < 0x11aa) != true; }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode);\n\n\tbytes expectation;\n\tif (solidity::test::CommonOptions::get().optimize)\n\t\texpectation = {\n\t\t\tuint8_t(Instruction::PUSH2), 0x11, 0xaa,\n\t\t\tuint8_t(Instruction::PUSH2), 0x10, 0xaa,\n\t\t\tuint8_t(Instruction::LT), uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::PUSH1), 0x1,\n\t\t\tuint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::EQ),\n\t\t\tuint8_t(Instruction::ISZERO)\n\t\t};\n\telse\n\t\texpectation = {\n\t\t\tuint8_t(Instruction::PUSH1), 0x1, uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::PUSH2), 0x11, 0xaa,\n\t\t\tuint8_t(Instruction::PUSH2), 0x10, 0xaa,\n\t\t\tuint8_t(Instruction::LT), uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::EQ),\n\t\t\tuint8_t(Instruction::ISZERO)\n\t\t};\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(short_circuiting)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public { bool x = true != (4 <= 8 + 10 || 9 != 2); }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode);\n\n\tbytes expectation{\n\t\tuint8_t(Instruction::PUSH1), 0x12, // 8 + 10\n\t\tuint8_t(Instruction::PUSH1), 0x4,\n\t\tuint8_t(Instruction::GT),\n\t\tuint8_t(Instruction::ISZERO), // after this we have 4 <= 8 + 10\n\t\tuint8_t(Instruction::DUP1),\n\t\tuint8_t(Instruction::PUSH1), 0x11,\n\t\tuint8_t(Instruction::JUMPI), // short-circuit if it is true\n\t\tuint8_t(Instruction::POP),\n\t\tuint8_t(Instruction::PUSH1), 0x2,\n\t\tuint8_t(Instruction::PUSH1), 0x9,\n\t\tuint8_t(Instruction::EQ),\n\t\tuint8_t(Instruction::ISZERO), // after this we have 9 != 2\n\t\tuint8_t(Instruction::JUMPDEST),\n\t\tuint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),\n\t\tuint8_t(Instruction::PUSH1), 0x1, uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),\n\t\tuint8_t(Instruction::EQ),\n\t\tuint8_t(Instruction::ISZERO)\n\t};\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(arithmetic)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint y) public { unchecked { ((((((((y ^ 8) & 7) | 6) - 5) + 4) % 3) / 2) * 1); } }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode, {}, {{\"test\", \"f\", \"y\"}});\n\tbool hasPush0 = solidity::test::CommonOptions::get().evmVersion().hasPush0();\n\tbytes push0Bytes = hasPush0 ?\n\t\tbytes{uint8_t(Instruction::PUSH0)} :\n\t\tbytes{uint8_t(Instruction::PUSH1), 0x0};\n\tuint8_t size = hasPush0 ? 0x65: 0x67;\n\tbytes panic =\n\t\tbytes{\n\t\t\tuint8_t(Instruction::JUMPDEST),\n\t\t\tuint8_t(Instruction::PUSH32)\n\t\t} +\n\t\tutil::fromHex(\"4E487B7100000000000000000000000000000000000000000000000000000000\") +\n\t\t  push0Bytes +\n\t\tbytes{\n\t\t\tuint8_t(Instruction::MSTORE),\n\t\t\tuint8_t(Instruction::PUSH1), 0x12,\n\t\t\tuint8_t(Instruction::PUSH1), 0x4,\n\t\t\tuint8_t(Instruction::MSTORE),\n\t\t\tuint8_t(Instruction::PUSH1), 0x24\n\t\t} +\n\t\tpush0Bytes +\n\t\tbytes{\n\t\t\tuint8_t(Instruction::REVERT),\n\t\t\tuint8_t(Instruction::JUMPDEST),\n\t\t\tuint8_t(Instruction::JUMP),\n\t\t\tuint8_t(Instruction::JUMPDEST)\n\t\t};\n\n\tbytes expectation;\n\tif (solidity::test::CommonOptions::get().optimize)\n\t\texpectation = bytes{\n\t\t\tuint8_t(Instruction::PUSH1), 0x2,\n\t\t\tuint8_t(Instruction::PUSH1), 0x3,\n\t\t\tuint8_t(Instruction::PUSH1), 0x5,\n\t\t\tuint8_t(Instruction::DUP4),\n\t\t\tuint8_t(Instruction::PUSH1), 0x8,\n\t\t\tuint8_t(Instruction::XOR),\n\t\t\tuint8_t(Instruction::PUSH1), 0x7,\n\t\t\tuint8_t(Instruction::AND),\n\t\t\tuint8_t(Instruction::PUSH1), 0x6,\n\t\t\tuint8_t(Instruction::OR),\n\t\t\tuint8_t(Instruction::SUB),\n\t\t\tuint8_t(Instruction::PUSH1), 0x4,\n\t\t\tuint8_t(Instruction::ADD),\n\t\t\tuint8_t(Instruction::DUP2),\n\t\t\tuint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::PUSH1), 0x20,\n\t\t\tuint8_t(Instruction::JUMPI),\n\t\t\tuint8_t(Instruction::PUSH1), 0x1f,\n\t\t\tuint8_t(Instruction::PUSH1), 0x36,\n\t\t\tuint8_t(Instruction::JUMP),\n\t\t\tuint8_t(Instruction::JUMPDEST),\n\t\t\tuint8_t(Instruction::JUMPDEST),\n\t\t\tuint8_t(Instruction::MOD),\n\t\t\tuint8_t(Instruction::DUP2),\n\t\t\tuint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::PUSH1), 0x2e,\n\t\t\tuint8_t(Instruction::JUMPI),\n\t\t\tuint8_t(Instruction::PUSH1), 0x2d,\n\t\t\tuint8_t(Instruction::PUSH1), 0x36,\n\t\t\tuint8_t(Instruction::JUMP),\n\t\t\tuint8_t(Instruction::JUMPDEST),\n\t\t\tuint8_t(Instruction::JUMPDEST),\n\t\t\tuint8_t(Instruction::DIV),\n\t\t\tuint8_t(Instruction::PUSH1), 0x1,\n\t\t\tuint8_t(Instruction::MUL),\n\t\t\tuint8_t(Instruction::PUSH1), size,\n\t\t\tuint8_t(Instruction::JUMP)\n\t\t} + panic;\n\telse\n\t\texpectation = bytes{\n\t\t\tuint8_t(Instruction::PUSH1), 0x1,\n\t\t\tuint8_t(Instruction::PUSH1), 0x2,\n\t\t\tuint8_t(Instruction::PUSH1), 0x3,\n\t\t\tuint8_t(Instruction::PUSH1), 0x4,\n\t\t\tuint8_t(Instruction::PUSH1), 0x5,\n\t\t\tuint8_t(Instruction::PUSH1), 0x6,\n\t\t\tuint8_t(Instruction::PUSH1), 0x7,\n\t\t\tuint8_t(Instruction::PUSH1), 0x8,\n\t\t\tuint8_t(Instruction::DUP9),\n\t\t\tuint8_t(Instruction::XOR),\n\t\t\tuint8_t(Instruction::AND),\n\t\t\tuint8_t(Instruction::OR),\n\t\t\tuint8_t(Instruction::SUB),\n\t\t\tuint8_t(Instruction::ADD),\n\t\t\tuint8_t(Instruction::DUP2),\n\t\t\tuint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::PUSH1), 0x22,\n\t\t\tuint8_t(Instruction::JUMPI),\n\t\t\tuint8_t(Instruction::PUSH1), 0x21,\n\t\t\tuint8_t(Instruction::PUSH1), 0x36,\n\t\t\tuint8_t(Instruction::JUMP),\n\t\t\tuint8_t(Instruction::JUMPDEST),\n\t\t\tuint8_t(Instruction::JUMPDEST),\n\t\t\tuint8_t(Instruction::MOD),\n\t\t\tuint8_t(Instruction::DUP2),\n\t\t\tuint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::ISZERO),\n\t\t\tuint8_t(Instruction::PUSH1), 0x30,\n\t\t\tuint8_t(Instruction::JUMPI),\n\t\t\tuint8_t(Instruction::PUSH1), 0x2f,\n\t\t\tuint8_t(Instruction::PUSH1), 0x36,\n\t\t\tuint8_t(Instruction::JUMP),\n\t\t\tuint8_t(Instruction::JUMPDEST),\n\t\t\tuint8_t(Instruction::JUMPDEST),\n\t\t\tuint8_t(Instruction::DIV),\n\t\t\tuint8_t(Instruction::MUL),\n\t\t\tuint8_t(Instruction::PUSH1), size,\n\t\t\tuint8_t(Instruction::JUMP)\n\t\t} + panic;\n\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(unary_operators)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(int y) public { unchecked { !(~- y == 2); } }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode, {}, {{\"test\", \"f\", \"y\"}});\n\n\tbytes push0Bytes = solidity::test::CommonOptions::get().evmVersion().hasPush0() ?\n\t\tbytes{uint8_t(Instruction::PUSH0)} :\n\t\tbytes{uint8_t(Instruction::PUSH1), 0x0};\n\n\tbytes expectation;\n\tif (solidity::test::CommonOptions::get().optimize)\n\t\texpectation = bytes{\n\t\t\tuint8_t(Instruction::DUP1),\n\t\t} +\n\t\tpush0Bytes +\n\t\tbytes{\n\t\t\tuint8_t(Instruction::SUB),\n\t\t\tuint8_t(Instruction::NOT),\n\t\t\tuint8_t(Instruction::PUSH1), 0x2,\n\t\t\tuint8_t(Instruction::EQ),\n\t\t\tuint8_t(Instruction::ISZERO)\n\t\t};\n\telse\n\t\texpectation = bytes{\n\t\t\tuint8_t(Instruction::PUSH1), 0x2,\n\t\t\tuint8_t(Instruction::DUP2),\n\t\t} +\n\t\tpush0Bytes +\n\t\tbytes{\n\t\t\tuint8_t(Instruction::SUB),\n\t\t\tuint8_t(Instruction::NOT),\n\t\t\tuint8_t(Instruction::EQ),\n\t\t\tuint8_t(Instruction::ISZERO)\n\t\t};\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(unary_inc_dec)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint a) public returns (uint x) { unchecked { x = --a ^ (a-- ^ (++a ^ a++)); } }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode, {}, {{\"test\", \"f\", \"a\"}, {\"test\", \"f\", \"x\"}});\n\n\t// Stack: a, x\n\tbytes expectation{\n\t\tuint8_t(Instruction::DUP2),\n\t\tuint8_t(Instruction::DUP1),\n\t\tuint8_t(Instruction::PUSH1), 0x1,\n\t\tuint8_t(Instruction::ADD),\n\t\t// Stack here: a x a (a+1)\n\t\tuint8_t(Instruction::SWAP3),\n\t\tuint8_t(Instruction::POP), // first ++\n\t\t// Stack here: (a+1) x a\n\t\tuint8_t(Instruction::DUP3),\n\t\tuint8_t(Instruction::PUSH1), 0x1,\n\t\tuint8_t(Instruction::ADD),\n\t\t// Stack here: (a+1) x a (a+2)\n\t\tuint8_t(Instruction::SWAP3),\n\t\tuint8_t(Instruction::POP),\n\t\t// Stack here: (a+2) x a\n\t\tuint8_t(Instruction::DUP3), // second ++\n\t\tuint8_t(Instruction::XOR),\n\t\t// Stack here: (a+2) x a^(a+2)\n\t\tuint8_t(Instruction::DUP3),\n\t\tuint8_t(Instruction::DUP1),\n\t\tuint8_t(Instruction::PUSH1), 0x1,\n\t\tuint8_t(Instruction::SWAP1),\n\t\tuint8_t(Instruction::SUB),\n\t\t// Stack here: (a+2) x a^(a+2) (a+2) (a+1)\n\t\tuint8_t(Instruction::SWAP4),\n\t\tuint8_t(Instruction::POP), // first --\n\t\tuint8_t(Instruction::XOR),\n\t\t// Stack here: (a+1) x a^(a+2)^(a+2)\n\t\tuint8_t(Instruction::DUP3),\n\t\tuint8_t(Instruction::PUSH1), 0x1,\n\t\tuint8_t(Instruction::SWAP1),\n\t\tuint8_t(Instruction::SUB),\n\t\t// Stack here: (a+1) x a^(a+2)^(a+2) a\n\t\tuint8_t(Instruction::SWAP3),\n\t\tuint8_t(Instruction::POP), // second ++\n\t\t// Stack here: a x a^(a+2)^(a+2)\n\t\tuint8_t(Instruction::DUP3), // will change\n\t\tuint8_t(Instruction::XOR),\n\t\tuint8_t(Instruction::SWAP1),\n\t\tuint8_t(Instruction::POP),\n\t\tuint8_t(Instruction::DUP1)\n\t};\n\t// Stack here: a x a^(a+2)^(a+2)^a\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(assignment)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint a, uint b) public { unchecked { (a += b) * 2; } }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode, {}, {{\"test\", \"f\", \"a\"}, {\"test\", \"f\", \"b\"}});\n\n\t// Stack: a, b\n\tbytes expectation;\n\tif (solidity::test::CommonOptions::get().optimize)\n\t\texpectation = {\n\t\t\tuint8_t(Instruction::DUP1),\n\t\t\tuint8_t(Instruction::DUP3),\n\t\t\tuint8_t(Instruction::ADD),\n\t\t\tuint8_t(Instruction::SWAP2),\n\t\t\tuint8_t(Instruction::POP),\n\t\t\tuint8_t(Instruction::DUP2),\n\t\t\tuint8_t(Instruction::PUSH1), 0x2,\n\t\t\tuint8_t(Instruction::MUL)\n\t\t};\n\telse\n\t\texpectation = {\n\t\t\tuint8_t(Instruction::PUSH1), 0x2,\n\t\t\tuint8_t(Instruction::DUP2),\n\t\t\tuint8_t(Instruction::DUP4),\n\t\t\tuint8_t(Instruction::ADD),\n\t\t\t// Stack here: a b 2 a+b\n\t\t\tuint8_t(Instruction::SWAP3),\n\t\t\tuint8_t(Instruction::POP),\n\t\t\tuint8_t(Instruction::DUP3),\n\t\t\t// Stack here: a+b b 2 a+b\n\t\t\tuint8_t(Instruction::MUL)\n\t\t};\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(negative_literals_8bits)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public { int8 x = -0x80; }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode);\n\n\tbytes expectation(bytes({uint8_t(Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80));\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(negative_literals_16bits)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public { int64 x = ~0xabc; }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode);\n\n\tbytes expectation(bytes({uint8_t(Instruction::PUSH32)}) + bytes(30, 0xff) + bytes{0xf5, 0x43});\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(intermediately_overflowing_literals)\n{\n\t// first literal itself is too large for 256 bits but it fits after all constant operations\n\t// have been applied\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public { uint8 x = (0x00ffffffffffffffffffffffffffffffffffffffff * 0xffffffffffffffffffffffffff01) & 0xbf; }\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode);\n\n\tbytes expectation(bytes({uint8_t(Instruction::PUSH1), 0xbf}));\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(blockhash)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public {\n\t\t\t\tblockhash(3);\n\t\t\t}\n\t\t}\n\t)\";\n\n\tbytes code = compileFirstExpression(sourceCode, {}, {});\n\n\tbytes expectation({uint8_t(Instruction::PUSH1), 0x03,\n\t\t\t\t\t   uint8_t(Instruction::BLOCKHASH)});\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(\n\tblobhash,\n\t*boost::unit_test::precondition(minEVMVersionCheck(EVMVersion::cancun()))\n)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public {\n\t\t\t\tblobhash(3);\n\t\t\t}\n\t\t}\n\t)\";\n\n\tbytes code = compileFirstExpression(sourceCode, {}, {});\n\n\tbytes expectation({\n\t\tuint8_t(Instruction::PUSH1), 0x03,\n\t\tuint8_t(Instruction::BLOBHASH)\n\t});\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(gas_left)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public returns (uint256 val) {\n\t\t\t\treturn gasleft();\n\t\t\t}\n\t\t}\n\t)\";\n\tbytes code = compileFirstExpression(sourceCode, {}, {});\n\n\tbytes expectation = bytes({uint8_t(Instruction::GAS)});\n\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n}\n\nBOOST_AUTO_TEST_CASE(selfbalance)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f() public returns (uint) {\n\t\t\t\treturn address(this).balance;\n\t\t\t}\n\t\t}\n\t)\";\n\n\tbytes code = compileFirstExpression(sourceCode, {}, {});\n\n\tif (solidity::test::CommonOptions::get().evmVersion().hasSelfBalance())\n\t{\n\t\tbytes expectation({uint8_t(Instruction::SELFBALANCE)});\n\t\tBOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());\n\t}\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/SolidityNameAndTypeResolution.cpp",
    "content": "/*\n    This file is part of solidity.\n\n    solidity is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    solidity is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Unit tests for the name and type resolution of the solidity parser.\n */\n\n#include <test/libsolidity/AnalysisFramework.h>\n#include <test/libsolidity/util/SoltestErrors.h>\n\n#include <test/Common.h>\n\n#include <libsolidity/ast/AST.h>\n\n#include <libsolutil/Keccak256.h>\n\n#include <boost/test/unit_test.hpp>\n\n#include <string>\n\nusing namespace solidity::langutil;\n\nnamespace solidity::frontend::test\n{\n\nBOOST_FIXTURE_TEST_SUITE(SolidityNameAndTypeResolution, AnalysisFramework)\n\nBOOST_AUTO_TEST_CASE(function_no_implementation)\n{\n\tchar const* text = R\"(\n\t\tabstract contract test {\n\t\t\tfunction functionName(bytes32 input) public virtual returns (bytes32 out);\n\t\t}\n\t)\";\n\tauto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);\n\tsoltestAssert(sourceUnit);\n\tsoltestAssert(errors.empty(), \"Unexpected error: \" + formatErrors(errors));\n\n\tstd::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();\n\tContractDefinition* contract = dynamic_cast<ContractDefinition*>(nodes[1].get());\n\tBOOST_REQUIRE(contract);\n\tBOOST_CHECK(!contract->annotation().unimplementedDeclarations->empty());\n\tBOOST_CHECK(!contract->definedFunctions()[0]->isImplemented());\n}\n\nBOOST_AUTO_TEST_CASE(abstract_contract)\n{\n\tchar const* text = R\"(\n\t\tabstract contract base { function foo() public virtual; }\n\t\tcontract derived is base { function foo() public override {} }\n\t)\";\n\tauto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);\n\tsoltestAssert(sourceUnit);\n\tsoltestAssert(errors.empty(), \"Unexpected error: \" + formatErrors(errors));\n\n\tstd::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();\n\tContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get());\n\tContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());\n\tBOOST_REQUIRE(base);\n\tBOOST_CHECK(!base->annotation().unimplementedDeclarations->empty());\n\tBOOST_CHECK(!base->definedFunctions()[0]->isImplemented());\n\tBOOST_REQUIRE(derived);\n\tBOOST_CHECK(derived->annotation().unimplementedDeclarations->empty());\n\tBOOST_CHECK(derived->definedFunctions()[0]->isImplemented());\n}\n\nBOOST_AUTO_TEST_CASE(abstract_contract_with_overload)\n{\n\tchar const* text = R\"(\n\t\tabstract contract base { function foo(bool) public virtual; }\n\t\tabstract contract derived is base { function foo(uint) public {} }\n\t)\";\n\tauto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);\n\tsoltestAssert(sourceUnit);\n\tsoltestAssert(errors.empty(), \"Unexpected error: \" + formatErrors(errors));\n\n\tstd::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();\n\tContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get());\n\tContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());\n\tBOOST_REQUIRE(base);\n\tBOOST_CHECK(!base->annotation().unimplementedDeclarations->empty());\n\tBOOST_REQUIRE(derived);\n\tBOOST_CHECK(!derived->annotation().unimplementedDeclarations->empty());\n}\n\nBOOST_AUTO_TEST_CASE(implement_abstract_via_constructor)\n{\n\tchar const* text = R\"(\n\t\tabstract contract base { function foo() public virtual; }\n\t\tabstract contract foo is base { constructor() {} }\n\t)\";\n\tauto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);\n\tsoltestAssert(sourceUnit);\n\tsoltestAssert(errors.empty(), \"Unexpected error: \" + formatErrors(errors));\n\n\tstd::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();\n\tBOOST_CHECK_EQUAL(nodes.size(), 3);\n\tContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());\n\tBOOST_REQUIRE(derived);\n\tBOOST_CHECK(!derived->annotation().unimplementedDeclarations->empty());\n}\n\nBOOST_AUTO_TEST_CASE(function_canonical_signature)\n{\n\tchar const* text = R\"(\n\t\tcontract Test {\n\t\t\tfunction foo(uint256 arg1, uint64 arg2, bool arg3) public returns (uint256 ret) {\n\t\t\t\tret = arg1 + arg2;\n\t\t\t}\n\t\t}\n\t)\";\n\tauto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);\n\tsoltestAssert(sourceUnit);\n\tsoltestAssert(errors.empty(), \"Unexpected error: \" + formatErrors(errors));\n\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))\n\t\t{\n\t\t\tauto functions = contract->definedFunctions();\n\t\t\tBOOST_CHECK_EQUAL(\"foo(uint256,uint64,bool)\", functions[0]->externalSignature());\n\t\t}\n}\n\nBOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases)\n{\n\tchar const* text = R\"(\n\t\tcontract Test {\n\t\t\tfunction boo(uint, bytes32, address) public returns (uint ret) {\n\t\t\t\tret = 5;\n\t\t\t}\n\t\t}\n\t)\";\n\tauto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);\n\tsoltestAssert(sourceUnit);\n\tsoltestAssert(errors.empty(), \"Unexpected error: \" + formatErrors(errors));\n\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))\n\t\t{\n\t\t\tauto functions = contract->definedFunctions();\n\t\t\tif (functions.empty())\n\t\t\t\tcontinue;\n\t\t\tBOOST_CHECK_EQUAL(\"boo(uint256,bytes32,address)\", functions[0]->externalSignature());\n\t\t}\n}\n\nBOOST_AUTO_TEST_CASE(function_external_types)\n{\n\tchar const* text = R\"(\n\t\tcontract C {\n\t\t\tuint a;\n\t\t}\n\t\tcontract Test {\n\t\t\tfunction boo(uint, bool, bytes8, bool[2] calldata, uint[] calldata, C, address[] calldata) external returns (uint ret) {\n\t\t\t\tret = 5;\n\t\t\t}\n\t\t}\n\t)\";\n\tauto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);\n\tsoltestAssert(sourceUnit);\n\tsoltestAssert(errors.empty(), \"Unexpected error: \" + formatErrors(errors));\n\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))\n\t\t{\n\t\t\tauto functions = contract->definedFunctions();\n\t\t\tif (functions.empty())\n\t\t\t\tcontinue;\n\t\t\tBOOST_CHECK_EQUAL(\"boo(uint256,bool,bytes8,bool[2],uint256[],address,address[])\", functions[0]->externalSignature());\n\t\t}\n}\n\nBOOST_AUTO_TEST_CASE(enum_external_type)\n{\n\tchar const* text = R\"(\n\t\t// test for bug #1801\n\t\tcontract Test {\n\t\t\tenum ActionChoices { GoLeft, GoRight, GoStraight, Sit }\n\t\t\tfunction boo(ActionChoices enumArg) external returns (uint ret) {\n\t\t\t\tret = 5;\n\t\t\t}\n\t\t}\n\t)\";\n\tauto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);\n\tsoltestAssert(sourceUnit);\n\tsoltestAssert(errors.empty(), \"Unexpected error: \" + formatErrors(errors));\n\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))\n\t\t{\n\t\t\tauto functions = contract->definedFunctions();\n\t\t\tif (functions.empty())\n\t\t\t\tcontinue;\n\t\t\tBOOST_CHECK_EQUAL(\"boo(uint8)\", functions[0]->externalSignature());\n\t\t}\n}\n\nBOOST_AUTO_TEST_CASE(external_struct_signatures)\n{\n\tchar const* text = R\"(\n\t\tpragma abicoder v2;\n\t\tcontract Test {\n\t\t\tenum ActionChoices { GoLeft, GoRight, GoStraight, Sit }\n\t\t\tstruct Simple { uint i; }\n\t\t\tstruct Nested { X[2][] a; uint y; }\n\t\t\tstruct X { bytes32 x; Test t; Simple[] s; }\n\t\t\tfunction f(ActionChoices, uint, Simple calldata) external {}\n\t\t\tfunction g(Test, Nested calldata) external {}\n\t\t\tfunction h(function(Nested memory) external returns (uint)[] calldata) external {}\n\t\t\tfunction i(Nested[] calldata) external {}\n\t\t}\n\t)\";\n\t// Ignore analysis errors. This test only checks that correct signatures\n\t// are generated for external structs, but they are not yet supported\n\t// in code generation and therefore cause an error in the TypeChecker.\n\tSourceUnit const* sourceUnit = runAnalysisAndExpectNoParsingErrors(text, false, true, true).first;\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))\n\t\t{\n\t\t\tauto functions = contract->definedFunctions();\n\t\t\tBOOST_REQUIRE(!functions.empty());\n\t\t\tBOOST_CHECK_EQUAL(\"f(uint8,uint256,(uint256))\", functions[0]->externalSignature());\n\t\t\tBOOST_CHECK_EQUAL(\"g(address,((bytes32,address,(uint256)[])[2][],uint256))\", functions[1]->externalSignature());\n\t\t\tBOOST_CHECK_EQUAL(\"h(function[])\", functions[2]->externalSignature());\n\t\t\tBOOST_CHECK_EQUAL(\"i(((bytes32,address,(uint256)[])[2][],uint256)[])\", functions[3]->externalSignature());\n\t\t}\n}\n\nBOOST_AUTO_TEST_CASE(external_struct_signatures_in_libraries)\n{\n\tchar const* text = R\"(\n\t\tpragma abicoder v2;\n\t\tlibrary Test {\n\t\t\tenum ActionChoices { GoLeft, GoRight, GoStraight, Sit }\n\t\t\tstruct Simple { uint i; }\n\t\t\tstruct Nested { X[2][] a; uint y; }\n\t\t\tstruct X { bytes32 x; Test t; Simple[] s; }\n\t\t\tfunction f(ActionChoices, uint, Simple calldata) external {}\n\t\t\tfunction g(Test, Nested calldata) external {}\n\t\t\tfunction h(function(Nested memory) external returns (uint)[] calldata) external {}\n\t\t\tfunction i(Nested[] calldata) external {}\n\t\t}\n\t)\";\n\t// Ignore analysis errors. This test only checks that correct signatures\n\t// are generated for external structs, but calldata structs are not yet supported\n\t// in code generation and therefore cause an error in the TypeChecker.\n\tSourceUnit const* sourceUnit = runAnalysisAndExpectNoParsingErrors(text, false, true, true).first;\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))\n\t\t{\n\t\t\tauto functions = contract->definedFunctions();\n\t\t\tBOOST_REQUIRE(!functions.empty());\n\t\t\tBOOST_CHECK_EQUAL(\"f(Test.ActionChoices,uint256,Test.Simple)\", functions[0]->externalSignature());\n\t\t\tBOOST_CHECK_EQUAL(\"g(Test,Test.Nested)\", functions[1]->externalSignature());\n\t\t\tBOOST_CHECK_EQUAL(\"h(function[])\", functions[2]->externalSignature());\n\t\t\tBOOST_CHECK_EQUAL(\"i(Test.Nested[])\", functions[3]->externalSignature());\n\t\t}\n}\n\nBOOST_AUTO_TEST_CASE(struct_with_mapping_in_library)\n{\n\tchar const* text = R\"(\n\t\tlibrary Test {\n\t\t\tstruct Nested { mapping(uint => uint)[2][] a; uint y; }\n\t\t\tstruct X { Nested n; }\n\t\t\tfunction f(X storage x) external {}\n\t\t}\n\t)\";\n\tauto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);\n\tsoltestAssert(sourceUnit);\n\tsoltestAssert(errors.empty(), \"Unexpected error: \" + formatErrors(errors));\n\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t\tif (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))\n\t\t{\n\t\t\tauto functions = contract->definedFunctions();\n\t\t\tBOOST_REQUIRE(!functions.empty());\n\t\t\tBOOST_CHECK_EQUAL(\"f(Test.X storage)\", functions[0]->externalSignature());\n\t\t}\n}\n\nBOOST_AUTO_TEST_CASE(state_variable_accessors)\n{\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tfunction fun() public {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t\tuint256 public foo;\n\t\t\tmapping(uint=>bytes4) public map;\n\t\t\tmapping(uint=>mapping(uint=>bytes4)) public multiple_map;\n\t\t}\n\t)\";\n\n\tauto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);\n\tsoltestAssert(sourceUnit);\n\tsoltestAssert(errors.empty(), \"Unexpected error: \" + formatErrors(errors));\n\n\tContractDefinition const* contract;\n\tBOOST_REQUIRE((contract = retrieveContractByName(*sourceUnit, \"test\")) != nullptr);\n\tFunctionTypePointer function = retrieveFunctionBySignature(*contract, \"foo()\");\n\tBOOST_REQUIRE(function && function->hasDeclaration());\n\tauto returnParams = function->returnParameterTypes();\n\tBOOST_CHECK_EQUAL(returnParams.at(0)->canonicalName(), \"uint256\");\n\tBOOST_CHECK(function->stateMutability() == StateMutability::View);\n\n\tfunction = retrieveFunctionBySignature(*contract, \"map(uint256)\");\n\tBOOST_REQUIRE(function && function->hasDeclaration());\n\tauto params = function->parameterTypes();\n\tBOOST_CHECK_EQUAL(params.at(0)->canonicalName(), \"uint256\");\n\treturnParams = function->returnParameterTypes();\n\tBOOST_CHECK_EQUAL(returnParams.at(0)->canonicalName(), \"bytes4\");\n\tBOOST_CHECK(function->stateMutability() == StateMutability::View);\n\n\tfunction = retrieveFunctionBySignature(*contract, \"multiple_map(uint256,uint256)\");\n\tBOOST_REQUIRE(function && function->hasDeclaration());\n\tparams = function->parameterTypes();\n\tBOOST_CHECK_EQUAL(params.at(0)->canonicalName(), \"uint256\");\n\tBOOST_CHECK_EQUAL(params.at(1)->canonicalName(), \"uint256\");\n\treturnParams = function->returnParameterTypes();\n\tBOOST_CHECK_EQUAL(returnParams.at(0)->canonicalName(), \"bytes4\");\n\tBOOST_CHECK(function->stateMutability() == StateMutability::View);\n}\n\nBOOST_AUTO_TEST_CASE(private_state_variable)\n{\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tfunction fun() public {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t\tuint256 private foo;\n\t\t\tuint256 internal bar;\n\t\t}\n\t)\";\n\n\tauto [sourceUnit, errors] = runAnalysisAndExpectNoParsingErrors(text);\n\tsoltestAssert(sourceUnit);\n\tsoltestAssert(errors.empty(), \"Unexpected error: \" + formatErrors(errors));\n\n\tContractDefinition const* contract;\n\tBOOST_CHECK((contract = retrieveContractByName(*sourceUnit, \"test\")) != nullptr);\n\tFunctionTypePointer function;\n\tfunction = retrieveFunctionBySignature(*contract, \"foo()\");\n\tBOOST_CHECK_MESSAGE(function == nullptr, \"Accessor function of a private variable should not exist\");\n\tfunction = retrieveFunctionBySignature(*contract, \"bar()\");\n\tBOOST_CHECK_MESSAGE(function == nullptr, \"Accessor function of an internal variable should not exist\");\n}\n\nBOOST_AUTO_TEST_CASE(string)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tstring s;\n\t\t\tfunction f(string calldata x) external { s = x; }\n\t\t}\n\t)\";\n\tCHECK_SUCCESS(sourceCode);\n}\n\nBOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)\n{\n\tchar const* sourceCode = R\"(\n\t\tabstract contract C {\n\t\t\tfunction f(uint) public virtual returns (string memory);\n\t\t\tfunction g() public {\n\t\t\t\tstring memory x = this.f(2);\n\t\t\t\t// we can assign to x but it is not usable.\n\t\t\t\tbytes(x).length;\n\t\t\t}\n\t\t}\n\t)\";\n\tif (solidity::test::CommonOptions::get().evmVersion() == EVMVersion::homestead())\n\t\tCHECK_ERROR(sourceCode, TypeError, \"Type inaccessible dynamic type is not implicitly convertible to expected type string memory.\");\n\telse\n\t\tCHECK_SUCCESS_NO_WARNINGS(sourceCode);\n}\n\nBOOST_AUTO_TEST_CASE(warn_nonpresent_pragma)\n{\n\tchar const* text = R\"(\n\t\t// SPDX-License-Identifier: GPL-3.0\n\t\tcontract C {}\n\t)\";\n\tauto sourceAndError = runAnalysisAndExpectNoParsingErrors(text, true, false);\n\tBOOST_REQUIRE(!sourceAndError.second.empty());\n\tBOOST_REQUIRE(!!sourceAndError.first);\n\tBOOST_CHECK(searchErrorMessage(*sourceAndError.second.front(), \"Source file does not specify required compiler version!\"));\n}\n\nBOOST_AUTO_TEST_CASE(getter_is_memory_type)\n{\n\tchar const* text = R\"(\n\t\tcontract C {\n\t\t\tstruct S { string m; }\n\t\t\tstring[] public x;\n\t\t\tS[] public y;\n\t\t}\n\t)\";\n\tCHECK_SUCCESS_NO_WARNINGS(text);\n\t// Check that the getters return a memory strings, not a storage strings.\n\tContractDefinition const& c = dynamic_cast<ContractDefinition const&>(*compiler().ast(\"\").nodes().at(1));\n\tBOOST_CHECK(c.interfaceFunctions().size() == 2);\n\tfor (auto const& f: c.interfaceFunctions())\n\t{\n\t\tauto const& retType = f.second->returnParameterTypes().at(0);\n\t\tBOOST_CHECK(retType->dataStoredIn(DataLocation::Memory));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(address_staticcall)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f() public view returns(bool) {\n\t\t\t\t(bool success,) = address(0x4242).staticcall(\"\");\n\t\t\t\treturn success;\n\t\t\t}\n\t\t}\n\t)\";\n\n\tif (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())\n\t\tCHECK_SUCCESS_NO_WARNINGS(sourceCode);\n\telse\n\t\tCHECK_ERROR(sourceCode, TypeError, \"\\\"staticcall\\\" is not supported by the VM version.\");\n}\n\nBOOST_AUTO_TEST_CASE(address_staticcall_value)\n{\n\tif (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())\n\t{\n\t\tchar const* sourceCode = R\"(\n\t\t\tcontract C {\n\t\t\t\tfunction f() public view {\n\t\t\t\t\taddress(0x4242).staticcall.value;\n\t\t\t\t}\n\t\t\t}\n\t\t)\";\n\t\tCHECK_ERROR(sourceCode, TypeError, \"Member \\\"value\\\" is only available for payable functions.\");\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(address_call_full_return_type)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f() public {\n\t\t\t\t(bool success, bytes memory m) = address(0x4242).call(\"\");\n\t\t\t\tsuccess; m;\n\t\t\t}\n\t\t}\n\t)\";\n\n\tif (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())\n\t\tCHECK_SUCCESS_NO_WARNINGS(sourceCode);\n\telse\n\t\tCHECK_ERROR(sourceCode, TypeError, \"Type inaccessible dynamic type is not implicitly convertible to expected type bytes memory.\");\n}\n\nBOOST_AUTO_TEST_CASE(address_delegatecall_full_return_type)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tfunction f() public {\n\t\t\t\t(bool success, bytes memory m) = address(0x4242).delegatecall(\"\");\n\t\t\t\tsuccess; m;\n\t\t\t}\n\t\t}\n\t)\";\n\n\tif (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())\n\t\tCHECK_SUCCESS_NO_WARNINGS(sourceCode);\n\telse\n\t\tCHECK_ERROR(sourceCode, TypeError, \"Type inaccessible dynamic type is not implicitly convertible to expected type bytes memory.\");\n}\n\n\nBOOST_AUTO_TEST_CASE(address_staticcall_full_return_type)\n{\n\tif (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())\n\t{\n\t\tchar const* sourceCode = R\"(\n\t\t\tcontract C {\n\t\t\t\tfunction f() public view {\n\t\t\t\t\t(bool success, bytes memory m) = address(0x4242).staticcall(\"\");\n\t\t\t\t\tsuccess; m;\n\t\t\t\t}\n\t\t\t}\n\t\t)\";\n\n\t\tCHECK_SUCCESS_NO_WARNINGS(sourceCode);\n\t}\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/SolidityOptimizer.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Tests for the Solidity optimizer.\n */\n\n#include <test/Metadata.h>\n#include <test/libsolidity/SolidityExecutionFramework.h>\n\n#include <libevmasm/Instruction.h>\n#include <libevmasm/Disassemble.h>\n\n#include <boost/test/unit_test.hpp>\n\n#include <chrono>\n#include <string>\n#include <tuple>\n#include <memory>\n#include <limits>\n\nusing namespace solidity::util;\nusing namespace solidity::evmasm;\nusing namespace solidity::test;\n\nnamespace solidity::frontend::test\n{\n\nclass OptimizerTestFramework: public SolidityExecutionFramework\n{\npublic:\n\tbytes const& compileAndRunWithOptimizer(\n\t\tstd::string const& _sourceCode,\n\t\tu256 const& _value = 0,\n\t\tstd::string const& _contractName = \"\",\n\t\tbool const _optimize = true,\n\t\tunsigned const _optimizeRuns = 200\n\t)\n\t{\n\t\tOptimiserSettings previousSettings = std::move(m_optimiserSettings);\n\t\t// This uses \"none\" / \"full\" while most other test frameworks use\n\t\t// \"minimal\" / \"standard\".\n\t\tm_optimiserSettings = _optimize ? OptimiserSettings::full() : OptimiserSettings::none();\n\t\tm_optimiserSettings.expectedExecutionsPerDeployment = _optimizeRuns;\n\t\tbytes const& ret = compileAndRun(_sourceCode, _value, _contractName);\n\t\tm_optimiserSettings = std::move(previousSettings);\n\t\treturn ret;\n\t}\n\n\t/// Compiles the source code with and without optimizing.\n\tvoid compileBothVersions(\n\t\tstd::string const& _sourceCode,\n\t\tu256 const& _value = 0,\n\t\tstd::string const& _contractName = \"\",\n\t\tunsigned const _optimizeRuns = 200\n\t)\n\t{\n\t\tm_nonOptimizedBytecode = compileAndRunWithOptimizer(\"pragma solidity >=0.0;\\n\" + _sourceCode, _value, _contractName, false, _optimizeRuns);\n\t\tm_nonOptimizedContract = m_contractAddress;\n\t\tm_optimizedBytecode = compileAndRunWithOptimizer(\"pragma solidity >=0.0;\\n\" + _sourceCode, _value, _contractName, true, _optimizeRuns);\n\t\tsize_t nonOptimizedSize = numInstructions(m_nonOptimizedBytecode);\n\t\tsize_t optimizedSize = numInstructions(m_optimizedBytecode);\n\t\tBOOST_CHECK_MESSAGE(\n\t\t\t_optimizeRuns < 50 || optimizedSize < nonOptimizedSize,\n\t\t\tstd::string(\"Optimizer did not reduce bytecode size. Non-optimized size: \") +\n\t\t\tstd::to_string(nonOptimizedSize) + \" - optimized size: \" +\n\t\t\tstd::to_string(optimizedSize)\n\t\t);\n\t\tm_optimizedContract = m_contractAddress;\n\t}\n\n\ttemplate <class... Args>\n\tvoid compareVersions(std::string _sig, Args const&... _arguments)\n\t{\n\t\tm_contractAddress = m_nonOptimizedContract;\n\t\tbytes nonOptimizedOutput = callContractFunction(_sig, _arguments...);\n\t\tm_gasUsedNonOptimized = m_gasUsed;\n\t\tm_contractAddress = m_optimizedContract;\n\t\tbytes optimizedOutput = callContractFunction(_sig, _arguments...);\n\t\tm_gasUsedOptimized = m_gasUsed;\n\t\tBOOST_CHECK_MESSAGE(!optimizedOutput.empty(), \"No optimized output for \" + _sig);\n\t\tBOOST_CHECK_MESSAGE(!nonOptimizedOutput.empty(), \"No un-optimized output for \" + _sig);\n\t\tBOOST_CHECK_MESSAGE(nonOptimizedOutput == optimizedOutput, \"Computed values do not match.\"\n\t\t\t\t\t\t\t\"\\nNon-Optimized: \" + util::toHex(nonOptimizedOutput) +\n\t\t\t\t\t\t\t\"\\nOptimized:     \" + util::toHex(optimizedOutput));\n\t}\n\n\t/// @returns the number of instructions in the given bytecode, not taking the metadata hash\n\t/// into account.\n\tsize_t numInstructions(bytes const& _bytecode, std::optional<Instruction> _which = std::optional<Instruction>{})\n\t{\n\t\tbytes realCode = bytecodeSansMetadata(_bytecode);\n\t\tBOOST_REQUIRE_MESSAGE(!realCode.empty(), \"Invalid or missing metadata in bytecode.\");\n\t\tsize_t instructions = 0;\n\t\tevmasm::eachInstruction(realCode, m_evmVersion, [&](Instruction _instr, u256 const&) {\n\t\t\tif (!_which || *_which == _instr)\n\t\t\t\tinstructions++;\n\t\t});\n\t\treturn instructions;\n\t}\n\nprotected:\n\tu256 m_gasUsedOptimized;\n\tu256 m_gasUsedNonOptimized;\n\tbytes m_nonOptimizedBytecode;\n\tbytes m_optimizedBytecode;\n\th160 m_optimizedContract;\n\th160 m_nonOptimizedContract;\n};\n\nBOOST_FIXTURE_TEST_SUITE(SolidityOptimizer, OptimizerTestFramework)\n\nBOOST_AUTO_TEST_CASE(smoke_test)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint a) public returns (uint b) {\n\t\t\t\treturn a;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(uint256)\", u256(7));\n}\n\nBOOST_AUTO_TEST_CASE(identities)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(int a) public returns (int b) {\n\t\t\t\treturn int(0) | (int(1) * (int(0) ^ (0 + a)));\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(int256)\", u256(0x12334664));\n}\n\nBOOST_AUTO_TEST_CASE(unused_expressions)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tuint data;\n\t\t\tfunction f() public returns (uint a, uint b) {\n\t\t\t\t10 + 20;\n\t\t\t\tdata;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f()\");\n}\n\nBOOST_AUTO_TEST_CASE(constant_folding_both_sides)\n{\n\t// if constants involving the same associative and commutative operator are applied from both\n\t// sides, the operator should be applied only once, because the expression compiler pushes\n\t// literals as late as possible\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(uint x) public returns (uint y) {\n\t\t\t\treturn 98 ^ (7 * ((1 | (x | 1000)) * 40) ^ 102);\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(uint256)\", 7);\n}\n\nBOOST_AUTO_TEST_CASE(storage_access)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tuint8[40] data;\n\t\t\tfunction f(uint x) public returns (uint y) {\n\t\t\t\tdata[2] = data[7] = uint8(x);\n\t\t\t\tdata[4] = data[2] * 10 + data[3];\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(uint256)\", 7);\n}\n\nBOOST_AUTO_TEST_CASE(array_copy)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tbytes2[] data1;\n\t\t\tbytes5[] data2;\n\t\t\tfunction f(uint x) public returns (uint l, uint y) {\n\t\t\t\tfor (uint i = 0; i < msg.data.length; i++)\n\t\t\t\t\tdata1.push();\n\t\t\t\tfor (uint i = 0; i < msg.data.length; ++i)\n\t\t\t\t\tdata1[i] = msg.data[i];\n\t\t\t\tdata2 = data1;\n\t\t\t\tl = data2.length;\n\t\t\t\ty = uint(uint40(data2[x]));\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(uint256)\", 0);\n\tcompareVersions(\"f(uint256)\", 10);\n\tcompareVersions(\"f(uint256)\", 35);\n}\n\nBOOST_AUTO_TEST_CASE(function_calls)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f1(uint x) public returns (uint) { unchecked { return x*x; } }\n\t\t\tfunction f(uint x) public returns (uint) { unchecked { return f1(7+x) - this.f1(x**9); } }\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(uint256)\", 0);\n\tcompareVersions(\"f(uint256)\", 10);\n\tcompareVersions(\"f(uint256)\", 36);\n}\n\nBOOST_AUTO_TEST_CASE(storage_write_in_loops)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tuint d;\n\t\t\tfunction f(uint a) public returns (uint r) {\n\t\t\t\tuint x = d;\n\t\t\t\tfor (uint i = 1; i < a * a; i++) {\n\t\t\t\t\tr = d;\n\t\t\t\t\td = i;\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(uint256)\", 0);\n\tcompareVersions(\"f(uint256)\", 10);\n\tcompareVersions(\"f(uint256)\", 36);\n}\n\n// Test disabled with https://github.com/argotorg/solidity/pull/762\n// Information in joining branches is not retained anymore.\nBOOST_AUTO_TEST_CASE(retain_information_in_branches)\n{\n\t// This tests that the optimizer knows that we already have \"z == keccak256(abi.encodePacked(y))\" inside both branches.\n\tchar const* sourceCode = R\"(\n\t\tcontract c {\n\t\t\tbytes32 d;\n\t\t\tuint a;\n\t\t\tfunction f(uint x, bytes32 y) public returns (uint r_a, bytes32 r_d) {\n\t\t\t\tbytes32 z = keccak256(abi.encodePacked(y));\n\t\t\t\tif (x > 8) {\n\t\t\t\t\tz = keccak256(abi.encodePacked(y));\n\t\t\t\t\ta = x;\n\t\t\t\t} else {\n\t\t\t\t\tz = keccak256(abi.encodePacked(y));\n\t\t\t\t\ta = x;\n\t\t\t\t}\n\t\t\t\tr_a = a;\n\t\t\t\tr_d = d;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(uint256,bytes32)\", 0, \"abc\");\n\tcompareVersions(\"f(uint256,bytes32)\", 8, \"def\");\n\tcompareVersions(\"f(uint256,bytes32)\", 10, \"ghi\");\n\n\tbytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, \"c\", true);\n\tsize_t numSHA3s = 0;\n\teachInstruction(optimizedBytecode, m_evmVersion, [&](Instruction _instr, u256 const&) {\n\t\tif (_instr == Instruction::KECCAK256)\n\t\t\tnumSHA3s++;\n\t});\n// TEST DISABLED - OPTIMIZER IS NOT EFFECTIVE ON THIS ONE ANYMORE\n// BOOST_CHECK_EQUAL(1, numSHA3s);\n}\n\nBOOST_AUTO_TEST_CASE(store_tags_as_unions)\n{\n\t// This calls the same function from two sources and both calls have a certain Keccak-256 on\n\t// the stack at the same position.\n\t// Without storing tags as unions, the return from the shared function would not know where to\n\t// jump and thus all jumpdests are forced to clear their state and we do not know about the\n\t// sha3 anymore.\n\t// Note that, for now, this only works if the functions have the same number of return\n\t// parameters since otherwise, the return jump addresses are at different stack positions\n\t// which triggers the \"unknown jump target\" situation.\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tbytes32 data;\n\t\t\tfunction f(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) {\n\t\t\t\tr_d = keccak256(abi.encodePacked(y));\n\t\t\t\tshared(y);\n\t\t\t\tr_d = keccak256(abi.encodePacked(y));\n\t\t\t\tr_a = 5;\n\t\t\t}\n\t\t\tfunction g(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) {\n\t\t\t\tr_d = keccak256(abi.encodePacked(y));\n\t\t\t\tshared(y);\n\t\t\t\tr_d = bytes32(uint(keccak256(abi.encodePacked(y))) + 2);\n\t\t\t\tr_a = 7;\n\t\t\t}\n\t\t\tfunction shared(bytes32 y) internal {\n\t\t\t\tdata = keccak256(abi.encodePacked(y));\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(uint256,bytes32)\", 7, \"abc\");\n\n\tbytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, \"test\", true);\n\tsize_t numSHA3s = 0;\n\teachInstruction(optimizedBytecode, m_evmVersion, [&](Instruction _instr, u256 const&) {\n\t\tif (_instr == Instruction::KECCAK256)\n\t\t\tnumSHA3s++;\n\t});\n// TEST DISABLED UNTIL 93693404 IS IMPLEMENTED\n// BOOST_CHECK_EQUAL(2, numSHA3s);\n}\n\nBOOST_AUTO_TEST_CASE(incorrect_storage_access_bug)\n{\n\t// This bug appeared because a Keccak-256 operation with too low sequence number was used,\n\t// resulting in memory not being rewritten before the Keccak-256. The fix was to\n\t// take the max of the min sequence numbers when merging the states.\n\tchar const* sourceCode = R\"(\n\t\tcontract C\n\t\t{\n\t\t\tmapping(uint => uint) data;\n\t\t\tfunction f() public returns (uint)\n\t\t\t{\n\t\t\t\tif (data[block.timestamp] == 0)\n\t\t\t\t\tdata[type(uint).max - 6] = 5;\n\t\t\t\treturn data[block.timestamp];\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f()\");\n}\n\nBOOST_AUTO_TEST_CASE(sequence_number_for_calls)\n{\n\t// This is a test for a bug that was present because we did not increment the sequence\n\t// number for CALLs - CALLs can read and write from memory (and DELEGATECALLs can do the same\n\t// to storage), so the sequence number should be incremented.\n\tchar const* sourceCode = R\"(\n\t\tcontract test {\n\t\t\tfunction f(string memory a, string memory b) public returns (bool) { return sha256(bytes(a)) == sha256(bytes(b)); }\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(string,string)\", 0x40, 0x80, 3, \"abc\", 3, \"def\");\n}\n\nBOOST_AUTO_TEST_CASE(computing_constants)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\tuint m_a;\n\t\t\tuint m_b;\n\t\t\tuint m_c;\n\t\t\tuint m_d;\n\t\t\tconstructor() {\n\t\t\t\tset();\n\t\t\t}\n\t\t\tfunction set() public returns (uint) {\n\t\t\t\tm_a = 0x77abc0000000000000000000000000000000000000000000000000000000001;\n\t\t\t\tm_b = 0x817416927846239487123469187231298734162934871263941234127518276;\n\t\t\t\tg();\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tfunction g() public {\n\t\t\t\tm_b = 0x817416927846239487123469187231298734162934871263941234127518276;\n\t\t\t\tm_c = 0x817416927846239487123469187231298734162934871263941234127518276;\n\t\t\t\th();\n\t\t\t}\n\t\t\tfunction h() public {\n\t\t\t\tm_d = 0xff05694900000000000000000000000000000000000000000000000000000000;\n\t\t\t}\n\t\t\tfunction get() public returns (uint ra, uint rb, uint rc, uint rd) {\n\t\t\t\tra = m_a;\n\t\t\t\trb = m_b;\n\t\t\t\trc = m_c;\n\t\t\t\trd = m_d;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode, 0, \"C\", 1);\n\tcompareVersions(\"get()\");\n\tcompareVersions(\"set()\");\n\tcompareVersions(\"get()\");\n\n\tbytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, \"C\", true, 1);\n\tbytes complicatedConstant = toBigEndian(u256(\"0x817416927846239487123469187231298734162934871263941234127518276\"));\n\tunsigned occurrences = 0;\n\tfor (auto iter = optimizedBytecode.cbegin(); iter < optimizedBytecode.cend(); ++occurrences)\n\t{\n\t\titer = search(iter, optimizedBytecode.cend(), complicatedConstant.cbegin(), complicatedConstant.cend());\n\t\tif (iter < optimizedBytecode.cend())\n\t\t\t++iter;\n\t}\n\tBOOST_CHECK_EQUAL(2, occurrences);\n\n\tbytes constantWithZeros = toBigEndian(u256(\"0x77abc0000000000000000000000000000000000000000000000000000000001\"));\n\tBOOST_CHECK(search(\n\t\toptimizedBytecode.cbegin(),\n\t\toptimizedBytecode.cend(),\n\t\tconstantWithZeros.cbegin(),\n\t\tconstantWithZeros.cend()\n\t) == optimizedBytecode.cend());\n}\n\n\nBOOST_AUTO_TEST_CASE(constant_optimization_early_exit)\n{\n\t// This tests that the constant optimizer does not try to find the best representation\n\t// indefinitely but instead stops after some number of iterations.\n\tchar const* sourceCode = R\"(\n\tcontract HexEncoding {\n\t\tfunction hexEncodeTest(address addr) public returns (bytes32 ret) {\n\t\t\tuint x = uint(uint160(addr)) / 2**32;\n\n\t\t\t// Nibble interleave\n\t\t\tx = x & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff;\n\t\t\tx = (x | (x * 2**64)) & 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff;\n\t\t\tx = (x | (x * 2**32)) & 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff;\n\t\t\tx = (x | (x * 2**16)) & 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff;\n\t\t\tx = (x | (x * 2** 8)) & 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff;\n\t\t\tx = (x | (x * 2** 4)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f;\n\n\t\t\t// Hex encode\n\t\t\tuint h = (x & 0x0808080808080808080808080808080808080808080808080808080808080808) / 8;\n\t\t\tuint i = (x & 0x0404040404040404040404040404040404040404040404040404040404040404) / 4;\n\t\t\tuint j = (x & 0x0202020202020202020202020202020202020202020202020202020202020202) / 2;\n\t\t\tx = x + (h & (i | j)) * 0x27 + 0x3030303030303030303030303030303030303030303030303030303030303030;\n\n\t\t\t// Store and load next batch\n\t\t\tassembly {\n\t\t\t\tmstore(0, x)\n\t\t\t}\n\t\t\tx = uint160(addr) * 2**96;\n\n\t\t\t// Nibble interleave\n\t\t\tx = x & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff;\n\t\t\tx = (x | (x * 2**64)) & 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff;\n\t\t\tx = (x | (x * 2**32)) & 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff;\n\t\t\tx = (x | (x * 2**16)) & 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff;\n\t\t\tx = (x | (x * 2** 8)) & 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff;\n\t\t\tx = (x | (x * 2** 4)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f;\n\n\t\t\t// Hex encode\n\t\t\th = (x & 0x0808080808080808080808080808080808080808080808080808080808080808) / 8;\n\t\t\ti = (x & 0x0404040404040404040404040404040404040404040404040404040404040404) / 4;\n\t\t\tj = (x & 0x0202020202020202020202020202020202020202020202020202020202020202) / 2;\n\t\t\tx = x + (h & (i | j)) * 0x27 + 0x3030303030303030303030303030303030303030303030303030303030303030;\n\n\t\t\t// Store and hash\n\t\t\tassembly {\n\t\t\t\tmstore(32, x)\n\t\t\t\tret := keccak256(0, 40)\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tauto start = std::chrono::steady_clock::now();\n\tcompileBothVersions(sourceCode);\n\tdouble duration = std::chrono::duration<double>(std::chrono::steady_clock::now() - start).count();\n\t// Since run time on an ASan build is not really realistic, we disable this test for those builds.\n\tsize_t maxDuration = 20;\n#if !defined(__SANITIZE_ADDRESS__) && defined(__has_feature)\n#if __has_feature(address_sanitizer)\n#define __SANITIZE_ADDRESS__ 1\n#endif\n#endif\n#if __SANITIZE_ADDRESS__\n\tmaxDuration = std::numeric_limits<size_t>::max();\n\tBOOST_TEST_MESSAGE(\"Disabled constant optimizer run time check for address sanitizer build.\");\n#endif\n\tBOOST_CHECK_MESSAGE(duration <= double(maxDuration), \"Compilation of constants took longer than 20 seconds.\");\n\tcompareVersions(\"hexEncodeTest(address)\", u256(0x123456789));\n}\n\nBOOST_AUTO_TEST_CASE(inconsistency)\n{\n\t// This is a test of a bug in the optimizer.\n\tchar const* sourceCode = R\"(\n\t\tcontract Inconsistency {\n\t\t\tstruct Value {\n\t\t\t\tuint badnum;\n\t\t\t\tuint number;\n\t\t\t}\n\n\t\t\tstruct Container {\n\t\t\t\tuint[] valueIndices;\n\t\t\t\tValue[] values;\n\t\t\t}\n\n\t\t\tContainer[] containers;\n\t\t\tuint[] valueIndices;\n\t\t\tuint INDEX_ZERO = 0;\n\t\t\tuint  debug;\n\n\t\t\t// Called with params: containerIndex=0, valueIndex=0\n\t\t\tfunction levelIII(uint containerIndex, uint valueIndex) private {\n\t\t\t\tContainer storage container = containers[containerIndex];\n\t\t\t\tValue storage value = container.values[valueIndex];\n\t\t\t\tdebug = container.valueIndices[value.number];\n\t\t\t}\n\t\t\tfunction levelII() private {\n\t\t\t\tfor (uint i = 0; i < valueIndices.length; i++) {\n\t\t\t\t\tlevelIII(INDEX_ZERO, valueIndices[i]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction trigger() public returns (uint) {\n\t\t\t\tContainer storage container = containers.push();\n\n\t\t\t\tcontainer.values.push(Value({\n\t\t\t\t\tbadnum: 9000,\n\t\t\t\t\tnumber: 0\n\t\t\t\t}));\n\n\t\t\t\tcontainer.valueIndices.push();\n\t\t\t\tvalueIndices.push();\n\n\t\t\t\tlevelII();\n\t\t\t\treturn debug;\n\t\t\t}\n\n\t\t\tfunction DoNotCallButDoNotDelete() public {\n\t\t\t\tlevelII();\n\t\t\t\tlevelIII(1, 2);\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"trigger()\");\n}\n\nBOOST_AUTO_TEST_CASE(dead_code_elimination_across_assemblies)\n{\n\t// This tests that a runtime-function that is stored in storage in the constructor\n\t// is not removed as part of dead code elimination.\n\tchar const* sourceCode = R\"(\n\t\tcontract DCE {\n\t\t\tfunction () internal returns (uint) stored;\n\t\t\tconstructor() {\n\t\t\t\tstored = f;\n\t\t\t}\n\t\t\tfunction f() internal returns (uint) { return 7; }\n\t\t\tfunction test() public returns (uint) { return stored(); }\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"test()\");\n}\n\nBOOST_AUTO_TEST_CASE(invalid_state_at_control_flow_join)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Test {\n\t\t\tuint256 public totalSupply = 100;\n\t\t\tfunction f() public returns (uint r) {\n\t\t\t\tif (false)\n\t\t\t\t\tr = totalSupply;\n\t\t\t\ttotalSupply -= 10;\n\t\t\t}\n\t\t\tfunction test() public returns (uint) {\n\t\t\t\tf();\n\t\t\t\treturn this.totalSupply();\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"test()\");\n}\n\nBOOST_AUTO_TEST_CASE(init_empty_dynamic_arrays)\n{\n\t// This is not so much an optimizer test, but rather a test\n\t// that allocating empty arrays is implemented efficiently.\n\t// In particular, initializing a dynamic memory array does\n\t// not use any memory.\n\tchar const* sourceCode = R\"(\n\t\tcontract Test {\n\t\t\tfunction f() public pure returns (uint r) {\n\t\t\t\tuint[][] memory x = new uint[][](20000);\n\t\t\t\treturn x.length;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f()\");\n\tBOOST_CHECK_LE(m_gasUsedNonOptimized, 1900000);\n\tBOOST_CHECK_LE(1600000, m_gasUsedNonOptimized);\n}\n\nBOOST_AUTO_TEST_CASE(optimise_multi_stores)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract Test {\n\t\t\tstruct S { uint16 a; uint16 b; uint16[3] c; uint[] dyn; }\n\t\t\tuint padding;\n\t\t\tS[] s;\n\t\t\tfunction f() public returns (uint16, uint16, uint16[3] memory, uint) {\n\t\t\t\tuint16[3] memory c;\n\t\t\t\tc[0] = 7;\n\t\t\t\tc[1] = 8;\n\t\t\t\tc[2] = 9;\n\t\t\t\ts.push(S(1, 2, c, new uint[](4)));\n\t\t\t\treturn (s[0].a, s[0].b, s[0].c, s[0].dyn[2]);\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f()\");\n\tBOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::SSTORE), 9);\n\tBOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, Instruction::SSTORE), 6);\n}\n\nBOOST_AUTO_TEST_CASE(optimise_constant_to_codecopy)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\t// We use the state variable so that the functions won't be deemed identical\n\t\t\t// and be optimised out to the same implementation.\n\t\t\tuint a;\n\t\t\tfunction f() public returns (uint) {\n\t\t\t\ta = 1;\n\t\t\t\t// This cannot be represented well with the `CalculateMethod`,\n\t\t\t\t// hence the decision will be between `LiteralMethod` and `CopyMethod`.\n\t\t\t\treturn 0x1234123412431234123412412342112341234124312341234124;\n\t\t\t}\n\t\t\tfunction g() public returns (uint) {\n\t\t\t\ta = 2;\n\t\t\t\treturn 0x1234123412431234123412412342112341234124312341234124;\n\t\t\t}\n\t\t\tfunction h() public returns (uint) {\n\t\t\t\ta = 3;\n\t\t\t\treturn 0x1234123412431234123412412342112341234124312341234124;\n\t\t\t}\n\t\t\tfunction i() public returns (uint) {\n\t\t\t\ta = 4;\n\t\t\t\treturn 0x1234123412431234123412412342112341234124312341234124;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode, 0, \"C\", 50);\n\tcompareVersions(\"f()\");\n\tcompareVersions(\"g()\");\n\tcompareVersions(\"h()\");\n\tcompareVersions(\"i()\");\n\t// This is counting in the deployed code.\n\tBOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::CODECOPY), 0);\n\tBOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, Instruction::CODECOPY), 4);\n}\n\nBOOST_AUTO_TEST_CASE(byte_access)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C\n\t\t{\n\t\t\tfunction f(bytes32 x) public returns (bytes1 r)\n\t\t\t{\n\t\t\t\tassembly { r := and(byte(x, 31), 0xff) }\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(bytes32)\", u256(\"0x1223344556677889900112233445566778899001122334455667788990011223\"));\n}\n\nBOOST_AUTO_TEST_CASE(shift_optimizer_bug)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C\n\t\t{\n\t\t\tfunction f(uint x) public returns (uint)\n\t\t\t{\n\t\t\t\treturn (x << 1) << type(uint).max;\n\t\t\t}\n\t\t\tfunction g(uint x) public returns (uint)\n\t\t\t{\n\t\t\t\treturn (x >> 1) >> type(uint).max;\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode);\n\tcompareVersions(\"f(uint256)\", 7);\n\tcompareVersions(\"g(uint256)\", u256(-1));\n}\n\nBOOST_AUTO_TEST_CASE(avoid_double_cleanup)\n{\n\tchar const* sourceCode = R\"(\n\t\tcontract C {\n\t\t\treceive() external payable {\n\t\t\t\tabi.encodePacked(uint200(0));\n\t\t\t}\n\t\t}\n\t)\";\n\tcompileBothVersions(sourceCode, 0, \"C\", 50);\n\t// Check that there is no double AND instruction in the resulting code\n\tBOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::AND), 1);\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/SolidityParser.cpp",
    "content": "/*\n    This file is part of solidity.\n\n    solidity is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    solidity is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * @author Christian <c@ethdev.com>\n * @date 2014\n * Unit tests for the solidity parser.\n */\n\n#include <string>\n#include <memory>\n#include <liblangutil/Scanner.h>\n#include <libsolidity/parsing/Parser.h>\n#include <liblangutil/ErrorReporter.h>\n#include <test/Common.h>\n#include <test/libsolidity/ErrorCheck.h>\n#include <libsolidity/ast/ASTVisitor.h>\n\n#include <boost/test/unit_test.hpp>\n\nusing namespace solidity::langutil;\n\nnamespace solidity::frontend::test\n{\n\nnamespace\n{\nASTPointer<ContractDefinition> parseText(std::string const& _source, ErrorList& _errors)\n{\n\tErrorReporter errorReporter(_errors);\n\tauto charStream = CharStream(_source, \"\");\n\tASTPointer<SourceUnit> sourceUnit = Parser(\n\t\terrorReporter,\n\t\tsolidity::test::CommonOptions::get().evmVersion(),\n\t\tsolidity::test::CommonOptions::get().eofVersion()\n\t).parse(charStream);\n\tif (!sourceUnit)\n\t\treturn ASTPointer<ContractDefinition>();\n\tfor (ASTPointer<ASTNode> const& node: sourceUnit->nodes())\n\t\tif (ASTPointer<ContractDefinition> contract = std::dynamic_pointer_cast<ContractDefinition>(node))\n\t\t\treturn contract;\n\tBOOST_FAIL(\"No contract found in source.\");\n\treturn ASTPointer<ContractDefinition>();\n}\n\nbool successParse(std::string const& _source)\n{\n\tErrorList errors;\n\ttry\n\t{\n\t\tauto sourceUnit = parseText(_source, errors);\n\t\tif (!sourceUnit)\n\t\t\treturn false;\n\t}\n\tcatch (FatalError const& /*_exception*/)\n\t{\n\t\tif (Error::containsErrorOfType(errors, Error::Type::ParserError))\n\t\t\treturn false;\n\t}\n\tif (Error::containsErrorOfType(errors, Error::Type::ParserError))\n\t\treturn false;\n\n\tBOOST_CHECK(!Error::containsErrors(errors));\n\treturn true;\n}\n\nError getError(std::string const& _source)\n{\n\tErrorList errors;\n\ttry\n\t{\n\t\tparseText(_source, errors);\n\t}\n\tcatch (FatalError const& /*_exception*/)\n\t{\n\t\t// no-op\n\t}\n\tError const* error = Error::containsErrorOfType(errors, Error::Type::ParserError);\n\tBOOST_REQUIRE(error);\n\treturn *error;\n}\n\nvoid checkFunctionNatspec(\n\tFunctionDefinition const* _function,\n\tstd::string const& _expectedDoc\n)\n{\n\tauto doc = _function->documentation()->text();\n\tBOOST_CHECK_MESSAGE(doc != nullptr, \"Function does not have Natspec Doc as expected\");\n\tBOOST_CHECK_EQUAL(*doc, _expectedDoc);\n}\n\n}\n\n#define CHECK_PARSE_ERROR(source, substring) \\\ndo \\\n{\\\n\tError err = getError((source)); \\\n\tBOOST_CHECK(searchErrorMessage(err, (substring))); \\\n}\\\nwhile(0)\n\n\nBOOST_AUTO_TEST_SUITE(SolidityParser)\n\nBOOST_AUTO_TEST_CASE(reserved_keywords)\n{\n\tBOOST_CHECK(!TokenTraits::isReservedKeyword(Token::Identifier));\n\tBOOST_CHECK(TokenTraits::isReservedKeyword(Token::After));\n\tBOOST_CHECK(!TokenTraits::isReservedKeyword(Token::Unchecked));\n\tBOOST_CHECK(TokenTraits::isReservedKeyword(Token::Var));\n\tBOOST_CHECK(TokenTraits::isReservedKeyword(Token::Reference));\n\tBOOST_CHECK(!TokenTraits::isReservedKeyword(Token::Illegal));\n}\n\nBOOST_AUTO_TEST_CASE(function_natspec_documentation)\n{\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tuint256 stateVar;\n\t\t\t/// This is a test function\n\t\t\tfunction functionName(bytes32 input) public returns (bytes32 out) {}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n\tErrorList errors;\n\tASTPointer<ContractDefinition> contract = parseText(text, errors);\n\tFunctionDefinition const* function = nullptr;\n\tauto functions = contract->definedFunctions();\n\n\tBOOST_REQUIRE_MESSAGE(function = functions.at(0), \"Failed to retrieve function\");\n\tcheckFunctionNatspec(function, \"This is a test function\");\n}\n\nBOOST_AUTO_TEST_CASE(function_normal_comments)\n{\n\tFunctionDefinition const* function = nullptr;\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tuint256 stateVar;\n\t\t\t// We won't see this comment\n\t\t\tfunction functionName(bytes32 input) public returns (bytes32 out) {}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n\tErrorList errors;\n\tASTPointer<ContractDefinition> contract = parseText(text, errors);\n\tauto functions = contract->definedFunctions();\n\tBOOST_REQUIRE_MESSAGE(function = functions.at(0), \"Failed to retrieve function\");\n\tBOOST_CHECK_MESSAGE(function->documentation() == nullptr,\n\t\t\t\t\t\t\"Should not have gotten a Natspecc comment for this function\");\n}\n\nBOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation)\n{\n\tFunctionDefinition const* function = nullptr;\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tuint256 stateVar;\n\t\t\t/// This is test function 1\n\t\t\tfunction functionName1(bytes32 input) public returns (bytes32 out) {}\n\t\t\t/// This is test function 2\n\t\t\tfunction functionName2(bytes32 input) public returns (bytes32 out) {}\n\t\t\t// nothing to see here\n\t\t\tfunction functionName3(bytes32 input) public returns (bytes32 out) {}\n\t\t\t/// This is test function 4\n\t\t\tfunction functionName4(bytes32 input) public returns (bytes32 out) {}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n\tErrorList errors;\n\tASTPointer<ContractDefinition> contract = parseText(text, errors);\n\tauto functions = contract->definedFunctions();\n\n\tBOOST_REQUIRE_MESSAGE(function = functions.at(0), \"Failed to retrieve function\");\n\tcheckFunctionNatspec(function, \"This is test function 1\");\n\n\tBOOST_REQUIRE_MESSAGE(function = functions.at(1), \"Failed to retrieve function\");\n\tcheckFunctionNatspec(function, \"This is test function 2\");\n\n\tBOOST_REQUIRE_MESSAGE(function = functions.at(2), \"Failed to retrieve function\");\n\tBOOST_CHECK_MESSAGE(function->documentation() == nullptr,\n\t\t\t\t\t\t\"Should not have gotten natspec comment for functionName3()\");\n\n\tBOOST_REQUIRE_MESSAGE(function = functions.at(3), \"Failed to retrieve function\");\n\tcheckFunctionNatspec(function, \"This is test function 4\");\n}\n\nBOOST_AUTO_TEST_CASE(multiline_function_documentation)\n{\n\tFunctionDefinition const* function = nullptr;\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tuint256 stateVar;\n\t\t\t/// This is a test function\n\t\t\t/// and it has 2 lines\n\t\t\tfunction functionName1(bytes32 input) public returns (bytes32 out) {}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n\tErrorList errors;\n\tASTPointer<ContractDefinition> contract = parseText(text, errors);\n\tauto functions = contract->definedFunctions();\n\tBOOST_REQUIRE_MESSAGE(function = functions.at(0), \"Failed to retrieve function\");\n\tcheckFunctionNatspec(function, \"This is a test function\\n\"\n\t\t\t\t\t\t \" and it has 2 lines\");\n}\n\nBOOST_AUTO_TEST_CASE(natspec_comment_in_function_body)\n{\n\tFunctionDefinition const* function = nullptr;\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\t/// fun1 description\n\t\t\tfunction fun1(uint256 a) {\n\t\t\t\tuint b;\n\t\t\t\t// I should not interfere with actual natspec comments (natspec comments on local variables not allowed anymore)\n\t\t\t\tuint256 c;\n\t\t\t\tmapping(address=>bytes32) d;\n\t\t\t\tbytes7 name = \"Solidity\";\n\t\t\t}\n\t\t\t/// This is a test function\n\t\t\t/// and it has 2 lines\n\t\t\tfunction fun(bytes32 input) public returns (bytes32 out) {}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n\tErrorList errors;\n\tASTPointer<ContractDefinition> contract = parseText(text, errors);\n\tauto functions = contract->definedFunctions();\n\n\tBOOST_REQUIRE_MESSAGE(function = functions.at(0), \"Failed to retrieve function\");\n\tcheckFunctionNatspec(function, \"fun1 description\");\n\n\tBOOST_REQUIRE_MESSAGE(function = functions.at(1), \"Failed to retrieve function\");\n\tcheckFunctionNatspec(function, \"This is a test function\\n\"\n\t\t\t\t\t\t \" and it has 2 lines\");\n}\n\nBOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature)\n{\n\tFunctionDefinition const* function = nullptr;\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tuint256 stateVar;\n\t\t\tfunction ///I am in the wrong place\n\t\t\tfun1(uint256 a) {\n\t\t\t\tuint b;\n\t\t\t\t// I should not interfere with actual natspec comments (natspec comments on local variables not allowed anymore)\n\t\t\t\tuint256 c;\n\t\t\t\tmapping(address=>bytes32) d;\n\t\t\t\tbytes7 name = \"Solidity\";\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n\tErrorList errors;\n\tASTPointer<ContractDefinition> contract = parseText(text, errors);\n\tauto functions = contract->definedFunctions();\n\n\tBOOST_REQUIRE_MESSAGE(function = functions.at(0), \"Failed to retrieve function\");\n\tBOOST_CHECK_MESSAGE(!function->documentation(),\n\t\t\t\t\t\t\"Shouldn't get natspec docstring for this function\");\n}\n\nBOOST_AUTO_TEST_CASE(natspec_docstring_after_signature)\n{\n\tFunctionDefinition const* function = nullptr;\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tuint256 stateVar;\n\t\t\tfunction fun1(uint256 a) {\n\t\t\t\t// I should have been above the function signature (natspec comments on local variables not allowed anymore)\n\t\t\t\tuint b;\n\t\t\t\t// I should not interfere with actual natspec comments (natspec comments on local variables not allowed anymore)\n\t\t\t\tuint256 c;\n\t\t\t\tmapping(address=>bytes32) d;\n\t\t\t\tbytes7 name = \"Solidity\";\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n\tErrorList errors;\n\tASTPointer<ContractDefinition> contract = parseText(text, errors);\n\tauto functions = contract->definedFunctions();\n\n\tBOOST_REQUIRE_MESSAGE(function = functions.at(0), \"Failed to retrieve function\");\n\tBOOST_CHECK_MESSAGE(!function->documentation(),\n\t\t\t\t\t\t\"Shouldn't get natspec docstring for this function\");\n}\n\nBOOST_AUTO_TEST_CASE(variable_definition)\n{\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tfunction fun(uint256 a) {\n\t\t\t\tuint b;\n\t\t\t\tuint256 c;\n\t\t\t\tmapping(address=>bytes32) d;\n\t\t\t\tcustomtype varname;\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(variable_definition_with_initialization)\n{\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tfunction fun(uint256 a) {\n\t\t\t\tuint b = 2;\n\t\t\t\tuint256 c = 0x87;\n\t\t\t\tmapping(address=>bytes32) d;\n\t\t\t\tbytes7 name = \"Solidity\";\n\t\t\t\tcustomtype varname;\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(operator_expression)\n{\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tfunction fun(uint256 a) {\n\t\t\t\tuint256 x = (1 + 4) || false && (1 - 12) + -9;\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(complex_expression)\n{\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tfunction fun(uint256 a) {\n\t\t\t\tuint256 x = (1 + 4).member(++67)[a/=9] || true;\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(statement_starting_with_type_conversion)\n{\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t\tuint64[7](3);\n\t\t\t\tuint64[](3);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(type_conversion_to_dynamic_array)\n{\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tfunction fun() {\n\t\t\t\tuint x = uint64[](3);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(import_directive)\n{\n\tchar const* text = R\"(\n\t\timport \"abc\";\n\t\tcontract test {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(multiple_contracts)\n{\n\tchar const* text = R\"(\n\t\tcontract test {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t}\n\t\tcontract test2 {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(multiple_contracts_and_imports)\n{\n\tchar const* text = R\"(\n\t\timport \"abc\";\n\t\tcontract test {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t}\n\t\timport \"def\";\n\t\tcontract test2 {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t}\n\t\timport \"ghi\";\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(contract_inheritance)\n{\n\tchar const* text = R\"(\n\t\tcontract base {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t}\n\t\tcontract derived is base {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(contract_multiple_inheritance)\n{\n\tchar const* text = R\"(\n\t\tcontract base {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t}\n\t\tcontract derived is base, nonExisting {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(contract_multiple_inheritance_with_arguments)\n{\n\tchar const* text = R\"(\n\t\tcontract base {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t}\n\t\tcontract derived is base(2), nonExisting(\"abc\", \"def\", base.fun()) {\n\t\t\tfunction fun() {\n\t\t\t\tuint64(2);\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(keyword_is_reserved)\n{\n\tauto keywords = {\n\t\t\"after\",\n\t\t\"alias\",\n\t\t\"apply\",\n\t\t\"auto\",\n\t\t\"byte\",\n\t\t\"case\",\n\t\t\"copyof\",\n\t\t\"default\",\n\t\t\"define\",\n\t\t\"final\",\n\t\t\"implements\",\n\t\t\"in\",\n\t\t\"inline\",\n\t\t\"let\",\n\t\t\"macro\",\n\t\t\"match\",\n\t\t\"mutable\",\n\t\t\"null\",\n\t\t\"of\",\n\t\t\"partial\",\n\t\t\"promise\",\n\t\t\"reference\",\n\t\t\"relocatable\",\n\t\t\"sealed\",\n\t\t\"sizeof\",\n\t\t\"static\",\n\t\t\"supports\",\n\t\t\"switch\",\n\t\t\"typedef\",\n\t\t\"typeof\",\n\t\t\"var\"\n\t};\n\n\tBOOST_CHECK_EQUAL(std::size(keywords), static_cast<int>(Token::Var) - static_cast<int>(Token::After) + 1);\n\n\tfor (auto const& keyword: keywords)\n\t{\n\t\tauto text = std::string(\"contract \") + keyword + \" {}\";\n\t\tCHECK_PARSE_ERROR(text.c_str(), std::string(\"Expected identifier but got reserved keyword '\") + keyword + \"'\");\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(member_access_parser_ambiguity)\n{\n\tchar const* text = R\"(\n\t\tcontract C {\n\t\t\tstruct S { uint a; uint b; uint[][][] c; }\n\t\t\tfunction f() {\n\t\t\t\tC.S x;\n\t\t\t\tC.S memory y;\n\t\t\t\tC.S[10] memory z;\n\t\t\t\tC.S[10](x);\n\t\t\t\tx.a = 2;\n\t\t\t\tx.c[1][2][3] = 9;\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(using_for)\n{\n\tchar const* text = R\"(\n\t\tcontract C {\n\t\t\tstruct s { uint a; }\n\t\t\tusing LibraryName for uint;\n\t\t\tusing Library2 for *;\n\t\t\tusing Lib for s;\n\t\t\tfunction f() {\n\t\t\t}\n\t\t}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(complex_import)\n{\n\tchar const* text = R\"(\n\t\timport \"abc\" as x;\n\t\timport * as x from \"abc\";\n\t\timport {a as b, c as d, f} from \"def\";\n\t\tcontract x {}\n\t)\";\n\tBOOST_CHECK(successParse(text));\n}\n\nBOOST_AUTO_TEST_CASE(inline_asm_end_location)\n{\n\tauto sourceCode = std::string(R\"(\n\tcontract C {\n\t\tfunction f() public pure returns (uint y) {\n\t\t\tuint a;\n\t\t\tassembly { a := 0x12345678 }\n\t\t\tuint z = a;\n\t\t\ty = z;\n\t\t}\n\t}\n\t)\");\n\tErrorList errors;\n\tauto contract = parseText(sourceCode, errors);\n\n\tclass CheckInlineAsmLocation: public ASTConstVisitor\n\t{\n\tpublic:\n\t\texplicit CheckInlineAsmLocation(std::string _sourceCode): m_sourceCode(_sourceCode) {}\n\t\tbool visited = false;\n\t\tbool visit(InlineAssembly const& _inlineAsm) override\n\t\t{\n\t\t\tauto loc = _inlineAsm.location();\n\t\t\tauto asmStr = m_sourceCode.substr(static_cast<size_t>(loc.start), static_cast<size_t>(loc.end - loc.start));\n\t\t\tBOOST_CHECK_EQUAL(asmStr, \"assembly { a := 0x12345678 }\");\n\t\t\tvisited = true;\n\n\t\t\treturn false;\n\t\t}\n\t\tstd::string m_sourceCode;\n\t};\n\n\tCheckInlineAsmLocation visitor{sourceCode};\n\tcontract->accept(visitor);\n\n\tBOOST_CHECK_MESSAGE(visitor.visited, \"No inline asm block found?!\");\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/SolidityTypes.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @author Christian <c@ethdev.com>\n * @date 2015\n * Unit tests for the type system of Solidity.\n */\n\n#include <libsolidity/ast/Types.h>\n#include <libsolidity/ast/TypeProvider.h>\n#include <libsolidity/ast/AST.h>\n#include <libsolutil/Keccak256.h>\n#include <boost/test/unit_test.hpp>\n\nusing namespace solidity::langutil;\n\nnamespace solidity::frontend::test\n{\n\nBOOST_AUTO_TEST_SUITE(SolidityTypes)\n\nBOOST_AUTO_TEST_CASE(int_types)\n{\n\tBOOST_CHECK(*TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken(Token::Int, 0, 0)) == *TypeProvider::integer(256, IntegerType::Modifier::Signed));\n\tfor (unsigned i = 8; i <= 256; i += 8)\n\t\tBOOST_CHECK(*TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken(Token::IntM, i, 0)) == *TypeProvider::integer(i, IntegerType::Modifier::Signed));\n}\n\nBOOST_AUTO_TEST_CASE(uint_types)\n{\n\tBOOST_CHECK(*TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken(Token::UInt, 0, 0)) == *TypeProvider::integer(256, IntegerType::Modifier::Unsigned));\n\tfor (unsigned i = 8; i <= 256; i += 8)\n\t\tBOOST_CHECK(*TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken(Token::UIntM, i, 0)) == *TypeProvider::integer(i, IntegerType::Modifier::Unsigned));\n}\n\nBOOST_AUTO_TEST_CASE(byte_types)\n{\n\tfor (unsigned i = 1; i <= 32; i++)\n\t\tBOOST_CHECK(*TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, i, 0)) == *TypeProvider::fixedBytes(i));\n}\n\nBOOST_AUTO_TEST_CASE(fixed_types)\n{\n\tBOOST_CHECK(*TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken(Token::Fixed, 0, 0)) == *TypeProvider::fixedPoint(128, 18, FixedPointType::Modifier::Signed));\n\tfor (unsigned i = 8; i <= 256; i += 8)\n\t{\n\t\tBOOST_CHECK(*TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken(Token::FixedMxN, i, 0)) == *TypeProvider::fixedPoint(i, 0, FixedPointType::Modifier::Signed));\n\t\tBOOST_CHECK(*TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken(Token::FixedMxN, i, 2)) == *TypeProvider::fixedPoint(i, 2, FixedPointType::Modifier::Signed));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(ufixed_types)\n{\n\tBOOST_CHECK(*TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken(Token::UFixed, 0, 0)) == *TypeProvider::fixedPoint(128, 18, FixedPointType::Modifier::Unsigned));\n\tfor (unsigned i = 8; i <= 256; i += 8)\n\t{\n\t\tBOOST_CHECK(*TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken(Token::UFixedMxN, i, 0)) == *TypeProvider::fixedPoint(i, 0, FixedPointType::Modifier::Unsigned));\n\t\tBOOST_CHECK(*TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken(Token::UFixedMxN, i, 2)) == *TypeProvider::fixedPoint(i, 2, FixedPointType::Modifier::Unsigned));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(storage_layout_simple)\n{\n\tMemberList members(MemberList::MemberMap({\n\t\t{\"first\", TypeProvider::fromElementaryTypeName(\"uint128\")},\n\t\t{\"second\", TypeProvider::fromElementaryTypeName(\"uint120\")},\n\t\t{\"wraps\", TypeProvider::fromElementaryTypeName(\"uint16\")}\n\t}));\n\tBOOST_REQUIRE_EQUAL(u256(2), members.storageSize());\n\tBOOST_REQUIRE(members.memberStorageOffset(\"first\") != nullptr);\n\tBOOST_REQUIRE(members.memberStorageOffset(\"second\") != nullptr);\n\tBOOST_REQUIRE(members.memberStorageOffset(\"wraps\") != nullptr);\n\tBOOST_CHECK(*members.memberStorageOffset(\"first\") == std::make_pair(u256(0), unsigned(0)));\n\tBOOST_CHECK(*members.memberStorageOffset(\"second\") == std::make_pair(u256(0), unsigned(16)));\n\tBOOST_CHECK(*members.memberStorageOffset(\"wraps\") == std::make_pair(u256(1), unsigned(0)));\n}\n\nBOOST_AUTO_TEST_CASE(storage_layout_mapping)\n{\n\tMemberList members(MemberList::MemberMap({\n\t\t{\"first\", TypeProvider::fromElementaryTypeName(\"uint128\")},\n\t\t{\"second\", TypeProvider::mapping(\n\t\t\tTypeProvider::fromElementaryTypeName(\"uint8\"),\n\t\t\t\"\",\n\t\t\tTypeProvider::fromElementaryTypeName(\"uint8\"),\n\t\t\t\"\"\n\t\t)},\n\t\t{\"third\", TypeProvider::fromElementaryTypeName(\"uint16\")},\n\t\t{\"final\", TypeProvider::mapping(\n\t\t\tTypeProvider::fromElementaryTypeName(\"uint8\"),\n\t\t\t\"\",\n\t\t\tTypeProvider::fromElementaryTypeName(\"uint8\"),\n\t\t\t\"\"\n\t\t)},\n\t}));\n\tBOOST_REQUIRE_EQUAL(u256(4), members.storageSize());\n\tBOOST_REQUIRE(members.memberStorageOffset(\"first\") != nullptr);\n\tBOOST_REQUIRE(members.memberStorageOffset(\"second\") != nullptr);\n\tBOOST_REQUIRE(members.memberStorageOffset(\"third\") != nullptr);\n\tBOOST_REQUIRE(members.memberStorageOffset(\"final\") != nullptr);\n\tBOOST_CHECK(*members.memberStorageOffset(\"first\") == std::make_pair(u256(0), unsigned(0)));\n\tBOOST_CHECK(*members.memberStorageOffset(\"second\") == std::make_pair(u256(1), unsigned(0)));\n\tBOOST_CHECK(*members.memberStorageOffset(\"third\") == std::make_pair(u256(2), unsigned(0)));\n\tBOOST_CHECK(*members.memberStorageOffset(\"final\") == std::make_pair(u256(3), unsigned(0)));\n}\n\nBOOST_AUTO_TEST_CASE(storage_layout_arrays)\n{\n\tBOOST_CHECK(ArrayType(DataLocation::Storage, TypeProvider::fixedBytes(1), 32).storageSize() == 1);\n\tBOOST_CHECK(ArrayType(DataLocation::Storage, TypeProvider::fixedBytes(1), 33).storageSize() == 2);\n\tBOOST_CHECK(ArrayType(DataLocation::Storage, TypeProvider::fixedBytes(2), 31).storageSize() == 2);\n\tBOOST_CHECK(ArrayType(DataLocation::Storage, TypeProvider::fixedBytes(7), 8).storageSize() == 2);\n\tBOOST_CHECK(ArrayType(DataLocation::Storage, TypeProvider::fixedBytes(7), 9).storageSize() == 3);\n\tBOOST_CHECK(ArrayType(DataLocation::Storage, TypeProvider::fixedBytes(31), 9).storageSize() == 9);\n\tBOOST_CHECK(ArrayType(DataLocation::Storage, TypeProvider::fixedBytes(32), 9).storageSize() == 9);\n}\n\nBOOST_AUTO_TEST_CASE(type_identifier_escaping)\n{\n\tBOOST_CHECK_EQUAL(Type::escapeIdentifier(\"(\"), \"$_\");\n\tBOOST_CHECK_EQUAL(Type::escapeIdentifier(\")\"), \"_$\");\n\tBOOST_CHECK_EQUAL(Type::escapeIdentifier(\",\"), \"_$_\");\n\tBOOST_CHECK_EQUAL(Type::escapeIdentifier(\"$\"), \"$$$\");\n\tBOOST_CHECK_EQUAL(Type::escapeIdentifier(\")$(\"), \"_$$$$$_\");\n\tBOOST_CHECK_EQUAL(Type::escapeIdentifier(\"()\"), \"$__$\");\n\tBOOST_CHECK_EQUAL(Type::escapeIdentifier(\"(,)\"), \"$__$__$\");\n\tBOOST_CHECK_EQUAL(Type::escapeIdentifier(\"(,$,)\"), \"$__$_$$$_$__$\");\n\tBOOST_CHECK_EQUAL(\n\t\tType::escapeIdentifier(\"((__(_$_$$,__($$,,,$$),$,,,)))$$,$$\"),\n\t\t\"$_$___$__$$$_$$$$$$_$___$_$$$$$$_$__$__$_$$$$$$_$_$_$$$_$__$__$__$_$_$$$$$$$_$_$$$$$$\"\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(type_identifiers)\n{\n\tint64_t id = 0;\n\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"uint128\")->identifier(), \"t_uint128\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"int128\")->identifier(), \"t_int128\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"address\")->identifier(), \"t_address\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"uint8\")->identifier(), \"t_uint8\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"ufixed64x2\")->identifier(), \"t_ufixed64x2\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"fixed128x8\")->identifier(), \"t_fixed128x8\");\n\tBOOST_CHECK_EQUAL(RationalNumberType(rational(7, 1)).identifier(), \"t_rational_7_by_1\");\n\tBOOST_CHECK_EQUAL(RationalNumberType(rational(200, 77)).identifier(), \"t_rational_200_by_77\");\n\tBOOST_CHECK_EQUAL(RationalNumberType(rational(2 * 200, 2 * 77)).identifier(), \"t_rational_200_by_77\");\n\tBOOST_CHECK_EQUAL(RationalNumberType(rational(-2 * 200, 2 * 77)).identifier(), \"t_rational_minus_200_by_77\");\n\tBOOST_CHECK_EQUAL(\n\t\tStringLiteralType(Literal(++id, SourceLocation{}, Token::StringLiteral, std::make_shared<std::string>(\"abc - def\"))).identifier(),\n\t\t \"t_stringliteral_196a9142ee0d40e274a6482393c762b16dd8315713207365e1e13d8d85b74fc4\"\n\t);\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"bytes1\")->identifier(), \"t_bytes1\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"bytes8\")->identifier(), \"t_bytes8\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"bytes32\")->identifier(), \"t_bytes32\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"bool\")->identifier(), \"t_bool\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"bytes\")->identifier(), \"t_bytes_storage_ptr\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"bytes memory\")->identifier(), \"t_bytes_memory_ptr\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"bytes storage\")->identifier(), \"t_bytes_storage_ptr\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"bytes calldata\")->identifier(), \"t_bytes_calldata_ptr\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"string\")->identifier(), \"t_string_storage_ptr\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"string memory\")->identifier(), \"t_string_memory_ptr\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"string storage\")->identifier(), \"t_string_storage_ptr\");\n\tBOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName(\"string calldata\")->identifier(), \"t_string_calldata_ptr\");\n\tArrayType largeintArray(DataLocation::Memory, TypeProvider::fromElementaryTypeName(\"int128\"), u256(\"2535301200456458802993406410752\"));\n\tBOOST_CHECK_EQUAL(largeintArray.identifier(), \"t_array$_t_int128_$2535301200456458802993406410752_memory_ptr\");\n\tType const* stringArray = TypeProvider::array(DataLocation::Storage, TypeProvider::fromElementaryTypeName(\"string\"), u256(\"20\"));\n\tType const* multiArray = TypeProvider::array(DataLocation::Storage, stringArray);\n\tBOOST_CHECK_EQUAL(multiArray->identifier(), \"t_array$_t_array$_t_string_storage_$20_storage_$dyn_storage_ptr\");\n\n\tContractDefinition c(++id, SourceLocation{}, std::make_shared<std::string>(\"MyContract$\"), SourceLocation{}, {}, {}, {}, ContractKind::Contract);\n\tBOOST_CHECK_EQUAL(c.type()->identifier(), \"t_type$_t_contract$_MyContract$$$_$2_$\");\n\tBOOST_CHECK_EQUAL(ContractType(c, true).identifier(), \"t_super$_MyContract$$$_$2\");\n\n\tStructDefinition s(++id, {}, std::make_shared<std::string>(\"Struct\"), {}, {}, {});\n\ts.annotation().recursive = false;\n\tBOOST_CHECK_EQUAL(s.type()->identifier(), \"t_type$_t_struct$_Struct_$3_storage_ptr_$\");\n\n\tEnumDefinition e(++id, {}, std::make_shared<std::string>(\"Enum\"), {}, {}, {});\n\tBOOST_CHECK_EQUAL(e.type()->identifier(), \"t_type$_t_enum$_Enum_$4_$\");\n\n\tTupleType t({e.type(), s.type(), stringArray, nullptr});\n\tBOOST_CHECK_EQUAL(t.identifier(), \"t_tuple$_t_type$_t_enum$_Enum_$4_$_$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$_t_array$_t_string_storage_$20_storage_ptr_$__$\");\n\n\tType const* keccak256fun = TypeProvider::function(strings{}, strings{}, FunctionType::Kind::KECCAK256);\n\tBOOST_CHECK_EQUAL(keccak256fun->identifier(), \"t_function_keccak256_nonpayable$__$returns$__$\");\n\n\tFunctionType metaFun(TypePointers{keccak256fun}, TypePointers{s.type()}, strings{\"\"}, strings{\"\"});\n\tBOOST_CHECK_EQUAL(metaFun.identifier(), \"t_function_internal_nonpayable$_t_function_keccak256_nonpayable$__$returns$__$_$returns$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$\");\n\n\tType const* m = TypeProvider::mapping(TypeProvider::fromElementaryTypeName(\"bytes32\"), \"\", s.type(), \"\");\n\tMappingType m2(TypeProvider::fromElementaryTypeName(\"uint64\"), \"\", m, \"\");\n\tBOOST_CHECK_EQUAL(m2.identifier(), \"t_mapping$_t_uint64_$_t_mapping$_t_bytes32_$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$_$\");\n\n\t// TypeType is tested with contract\n\n\tauto emptyParams = std::make_shared<ParameterList>(++id, SourceLocation(), std::vector<ASTPointer<VariableDeclaration>>());\n\tModifierDefinition mod(++id, SourceLocation{}, std::make_shared<std::string>(\"modif\"), SourceLocation{}, {}, emptyParams, {}, {}, {});\n\tBOOST_CHECK_EQUAL(ModifierType(mod).identifier(), \"t_modifier$__$\");\n\n\tSourceUnit su(++id, {}, {}, {}, {});\n\tBOOST_CHECK_EQUAL(ModuleType(su).identifier(), \"t_module_7\");\n\tBOOST_CHECK_EQUAL(MagicType(MagicType::Kind::Block).identifier(), \"t_magic_block\");\n\tBOOST_CHECK_EQUAL(MagicType(MagicType::Kind::Message).identifier(), \"t_magic_message\");\n\tBOOST_CHECK_EQUAL(MagicType(MagicType::Kind::Transaction).identifier(), \"t_magic_transaction\");\n\n\tBOOST_CHECK_EQUAL(InaccessibleDynamicType().identifier(), \"t_inaccessible\");\n}\n\nBOOST_AUTO_TEST_CASE(encoded_sizes)\n{\n\tBOOST_CHECK_EQUAL(IntegerType(16).calldataEncodedSize(true), 32);\n\tBOOST_CHECK_EQUAL(IntegerType(16).calldataEncodedSize(false), 2);\n\n\tBOOST_CHECK_EQUAL(FixedBytesType(16).calldataEncodedSize(true), 32);\n\tBOOST_CHECK_EQUAL(FixedBytesType(16).calldataEncodedSize(false), 16);\n\n\tBOOST_CHECK_EQUAL(BoolType().calldataEncodedSize(true), 32);\n\tBOOST_CHECK_EQUAL(BoolType().calldataEncodedSize(false), 1);\n\n\tArrayType const* uint24Array = TypeProvider::array(\n\t\tDataLocation::Memory,\n\t\tTypeProvider::uint(24),\n\t\t9\n\t);\n\tBOOST_CHECK_EQUAL(uint24Array->calldataEncodedSize(true), 9 * 32);\n\tBOOST_CHECK_EQUAL(uint24Array->calldataEncodedSize(false), 9 * 32);\n\n\tArrayType twoDimArray(DataLocation::Memory, uint24Array, 3);\n\tBOOST_CHECK_EQUAL(twoDimArray.calldataEncodedSize(true),  9 * 3 * 32);\n\tBOOST_CHECK_EQUAL(twoDimArray.calldataEncodedSize(false), 9 * 3 * 32);\n}\n\nBOOST_AUTO_TEST_CASE(helper_bool_result)\n{\n\tBoolResult r1{true};\n\tBoolResult r2 = BoolResult::err(\"Failure.\");\n\tr1.merge(r2, std::logical_and<bool>());\n\tBOOST_REQUIRE_EQUAL(r1.get(), false);\n\tBOOST_REQUIRE_EQUAL(r1.message(), \"Failure.\");\n\n\tBoolResult r3{false};\n\tBoolResult r4{true};\n\tr3.merge(r4, std::logical_and<bool>());\n\tBOOST_REQUIRE_EQUAL(r3.get(), false);\n\tBOOST_REQUIRE_EQUAL(r3.message(), \"\");\n\n\tBoolResult r5{true};\n\tBoolResult r6{true};\n\tr5.merge(r6, std::logical_and<bool>());\n\tBOOST_REQUIRE_EQUAL(r5.get(), true);\n\tBOOST_REQUIRE_EQUAL(r5.message(), \"\");\n}\n\nBOOST_AUTO_TEST_CASE(helper_string_result)\n{\n\tusing StringResult = util::Result<std::string>;\n\n\tStringResult r1{std::string{\"Success\"}};\n\tStringResult r2 = StringResult::err(\"Failure\");\n\n\tBOOST_REQUIRE_EQUAL(r1.get(), \"Success\");\n\tBOOST_REQUIRE_EQUAL(r2.get(), \"\");\n\n\tr1.merge(r2, [](std::string const&, std::string const& _rhs) { return _rhs; });\n\n\tBOOST_REQUIRE_EQUAL(r1.get(), \"\");\n\tBOOST_REQUIRE_EQUAL(r1.message(), \"Failure\");\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n}\n"
  },
  {
    "path": "test/libsolidity/StandardCompiler.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n/**\n * @date 2017\n * Unit tests for interface/StandardCompiler.h.\n */\n\n#include <string>\n#include <boost/test/unit_test.hpp>\n#include <boost/test/data/test_case.hpp>\n#include <boost/algorithm/string/replace.hpp>\n#include <liblangutil/EVMVersion.h>\n#include <libsolidity/interface/OptimiserSettings.h>\n#include <libsolidity/interface/StandardCompiler.h>\n#include <libsolidity/interface/Version.h>\n#include <libsolutil/JSON.h>\n#include <libsolutil/CommonData.h>\n#include <test/Metadata.h>\n#include <test/Common.h>\n\n#include <algorithm>\n#include <set>\n#include <utility>\n\nusing namespace solidity::evmasm;\nusing namespace solidity::langutil;\nusing namespace std::string_literals;\n\nnamespace solidity::frontend::test\n{\n\nnamespace\n{\n\nError::Severity str2Severity(std::string const& _cat)\n{\n\tstd::map<std::string, Error::Severity> cats{\n\t\t{\"info\", Error::Severity::Info},\n\t\t{\"Info\", Error::Severity::Info},\n\t\t{\"warning\", Error::Severity::Warning},\n\t\t{\"Warning\", Error::Severity::Warning},\n\t\t{\"error\", Error::Severity::Error},\n\t\t{\"Error\", Error::Severity::Error}\n\t};\n\treturn cats.at(_cat);\n}\n\n/// Helper to match a specific error type and message\nbool containsError(Json const& _compilerResult, std::string const& _type, std::string const& _message)\n{\n\tif (!_compilerResult.contains(\"errors\"))\n\t\treturn false;\n\n\tfor (auto const& error: _compilerResult[\"errors\"])\n\t{\n\t\tBOOST_REQUIRE(error.is_object());\n\t\tBOOST_REQUIRE(error[\"type\"].is_string());\n\t\tBOOST_REQUIRE(error[\"message\"].is_string());\n\t\tif ((error[\"type\"].get<std::string>() == _type) && (error[\"message\"].get<std::string>() == _message))\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nbool containsAtMostWarnings(Json const& _compilerResult)\n{\n\tif (!_compilerResult.contains(\"errors\"))\n\t\treturn true;\n\n\tfor (auto const& error: _compilerResult[\"errors\"])\n\t{\n\t\tBOOST_REQUIRE(error.is_object());\n\t\tBOOST_REQUIRE(error[\"severity\"].is_string());\n\t\tif (Error::isError(str2Severity(error[\"severity\"].get<std::string>())))\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nJson getContractResult(Json const& _compilerResult, std::string const& _file, std::string const& _name)\n{\n\tif (!_compilerResult.contains(\"contracts\") ||\n\t\t!_compilerResult[\"contracts\"].is_object() ||\n\t\t!_compilerResult[\"contracts\"][_file].is_object() ||\n\t\t!_compilerResult[\"contracts\"][_file][_name].is_object()\n\t)\n\t\treturn Json();\n\treturn _compilerResult[\"contracts\"][_file][_name];\n}\n\nvoid checkLinkReferencesSchema(Json const& _contractResult)\n{\n\tBOOST_TEST_REQUIRE(_contractResult.is_object());\n\tBOOST_TEST_REQUIRE(_contractResult[\"evm\"][\"bytecode\"].is_object());\n\n\tJson const& linkReferenceResult = _contractResult[\"evm\"][\"bytecode\"][\"linkReferences\"];\n\tBOOST_TEST_REQUIRE(linkReferenceResult.is_object());\n\n\tfor (auto const& [fileName, references]: linkReferenceResult.items())\n\t{\n\t\tBOOST_TEST_REQUIRE(references.is_object());\n\t\tfor (auto const& [libraryName, libraryValue]: references.items())\n\t\t{\n\t\t\tBOOST_TEST_REQUIRE(libraryValue.is_array());\n\t\t\tBOOST_TEST_REQUIRE(!libraryValue.empty());\n\t\t\tfor (size_t i = 0; i < static_cast<size_t>(linkReferenceResult.size()); ++i)\n\t\t\t{\n\t\t\t\tBOOST_TEST_REQUIRE(libraryValue[i].is_object());\n\t\t\t\tBOOST_TEST_REQUIRE(libraryValue[i].size() == 2);\n\t\t\t\tBOOST_TEST_REQUIRE(libraryValue[i][\"length\"].is_number_unsigned());\n\t\t\t\tBOOST_TEST_REQUIRE(libraryValue[i][\"start\"].is_number_unsigned());\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid expectLinkReferences(Json const& _contractResult, std::map<std::string, std::set<std::string>> const& _expectedLinkReferences)\n{\n\tcheckLinkReferencesSchema(_contractResult);\n\n\tJson const& linkReferenceResult = _contractResult[\"evm\"][\"bytecode\"][\"linkReferences\"];\n\tBOOST_TEST(linkReferenceResult.size() == _expectedLinkReferences.size());\n\n\tfor (auto const& [fileName, libraries]: _expectedLinkReferences)\n\t{\n\t\tBOOST_TEST(linkReferenceResult.contains(fileName));\n\t\tBOOST_TEST(linkReferenceResult[fileName].size() == libraries.size());\n\t\tfor (std::string const& libraryName: libraries)\n\t\t\tBOOST_TEST(linkReferenceResult[fileName].contains(libraryName));\n\t}\n}\n\nJson compile(std::string _input)\n{\n\tStandardCompiler compiler;\n\tstd::string output = compiler.compile(std::move(_input));\n\tJson ret;\n\tBOOST_REQUIRE(util::jsonParseStrict(output, ret));\n\treturn ret;\n}\n\nJson createLanguageAndSourcesSection(std::string const& _language, std::map<std::string, Json> const& _sources, bool _contentNode = true)\n{\n\tJson result = Json::object();\n\tresult[\"language\"] = _language;\n\tresult[\"sources\"] = Json::object();\n\tfor (auto const& source: _sources)\n\t{\n\t\tresult[\"sources\"][source.first] = Json::object();\n\t\tif (_contentNode)\n\t\t\tresult[\"sources\"][source.first][\"content\"] = source.second;\n\t\telse\n\t\t\tresult[\"sources\"][source.first] = source.second;\n\t}\n\treturn result;\n}\n\nclass Code\n{\npublic:\n\tvirtual ~Code() = default;\n\texplicit Code(std::map<std::string, Json> _code = {}) : m_code(std::move(_code)) {}\n\t[[nodiscard]] virtual Json json() const = 0;\nprotected:\n\tstd::map<std::string, Json> m_code;\n};\n\nclass SolidityCode: public Code\n{\npublic:\n\texplicit SolidityCode(std::map<std::string, Json> _code = {\n\t\t{\"fileA\", \"pragma solidity >=0.0; contract C { function f() public pure {} }\"}\n\t}) : Code(std::move(_code)) {}\n\t[[nodiscard]] Json json() const override\n\t{\n\t\treturn createLanguageAndSourcesSection(\"Solidity\", m_code);\n\t}\n};\n\nclass YulCode: public Code\n{\npublic:\n\texplicit YulCode(std::map<std::string, Json> _code = {\n\t\t{\"fileA\", \"{}\"}\n\t}) : Code(std::move(_code)) {}\n\t[[nodiscard]] Json json() const override\n\t{\n\t\treturn createLanguageAndSourcesSection(\"Yul\", m_code);\n\t}\n};\n\nclass EvmAssemblyCode: public Code\n{\npublic:\n\texplicit EvmAssemblyCode(std::map<std::string, Json> _code = {\n\t\t{\"fileA\", Json::parse(R\"(\n\t\t\t{\n\t\t\t\t\"assemblyJson\": {\n\t\t\t\t\t\".code\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"begin\": 36,\n\t\t\t\t\t\t\t\"end\": 51,\n\t\t\t\t\t\t\t\"name\": \"PUSH\",\n\t\t\t\t\t\t\t\"source\": 0,\n\t\t\t\t\t\t\t\"value\": \"0\"\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"sourceList\": [\n\t\t\t\t\t\t\"<stdin>\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t\t)\")}\n\t}) : Code(std::move(_code)) {}\n\t[[nodiscard]] Json json() const override\n\t{\n\t\treturn createLanguageAndSourcesSection(\"EVMAssembly\", m_code, false);\n\t}\n};\n\nclass SolidityAstCode: public Code\n{\npublic:\n\texplicit SolidityAstCode(std::map<std::string, Json> _code = {\n\t\t{\"fileA\", Json::parse(R\"(\n\t\t{\n\t\t\t\"ast\": {\n\t\t\t\t\"absolutePath\": \"empty_contract.sol\",\n\t\t\t\t\"exportedSymbols\": {\n\t\t\t\t\t\"test\": [\n\t\t\t\t\t\t1\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t\"id\": 2,\n\t\t\t\t\"nodeType\": \"SourceUnit\",\n\t\t\t\t\"nodes\": [\n\t\t\t\t{\n\t\t\t\t\t\"abstract\": false,\n\t\t\t\t\t\"baseContracts\": [],\n\t\t\t\t\t\"canonicalName\": \"test\",\n\t\t\t\t\t\"contractDependencies\": [],\n\t\t\t\t\t\"contractKind\": \"contract\",\n\t\t\t\t\t\"fullyImplemented\": true,\n\t\t\t\t\t\"id\": 1,\n\t\t\t\t\t\"linearizedBaseContracts\": [\n\t\t\t\t\t\t1\n\t\t\t\t\t],\n\t\t\t\t\t\"name\": \"test\",\n\t\t\t\t\t\"nameLocation\": \"9:4:0\",\n\t\t\t\t\t\"nodeType\": \"ContractDefinition\",\n\t\t\t\t\t\"nodes\": [],\n\t\t\t\t\t\"scope\": 2,\n\t\t\t\t\t\"src\": \"0:17:0\",\n\t\t\t\t\t\"usedErrors\": []\n\t\t\t\t}\n\t\t\t\t],\n\t\t\t\"src\": \"0:124:0\"\n\t\t\t},\n\t\t\t\"id\": 0\n\t\t}\n\t\t)\")}\n\t}) : Code(std::move(_code)) {}\n\t[[nodiscard]] Json json() const override\n\t{\n\t\treturn createLanguageAndSourcesSection(\"SolidityAST\", m_code);\n\t}\n};\n\nJson generateStandardJson(bool _viaIr, Json const& _debugInfoSelection, Json const& _outputSelection, Code const& _code = SolidityCode(), bool _advancedOutputSelection = false)\n{\n\tJson result = _code.json();\n\tresult[\"settings\"] = Json::object();\n\tresult[\"settings\"][\"viaIR\"] = _viaIr;\n\tif (!_debugInfoSelection.empty())\n\t\tresult[\"settings\"][\"debug\"][\"debugInfo\"] = _debugInfoSelection;\n\tif (_advancedOutputSelection)\n\t\tresult[\"settings\"][\"outputSelection\"] = _outputSelection;\n\telse\n\t\tresult[\"settings\"][\"outputSelection\"][\"*\"][\"*\"] = _outputSelection;\n\treturn result;\n}\n\nJson generateExperimentalStandardJson(bool _viaIR, Json const& _debugInfoSelection, Json const& _outputSelection, Code const& _code = SolidityCode(), bool _advancedOutputSelection = false)\n{\n\tJson result = generateStandardJson(_viaIR, _debugInfoSelection, _outputSelection, _code, _advancedOutputSelection);\n\tresult[\"settings\"][\"experimental\"] = true;\n\treturn result;\n}\n\n} // end anonymous namespace\n\nBOOST_AUTO_TEST_SUITE(StandardCompiler)\n\nBOOST_AUTO_TEST_CASE(assume_object_input)\n{\n\tJson result;\n\n\t/// Use the native JSON interface of StandardCompiler to trigger these\n\tfrontend::StandardCompiler compiler;\n\tresult = compiler.compile(Json());\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"Input is not a JSON object.\"));\n\tresult = compiler.compile(Json(\"INVALID\"));\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"Input is not a JSON object.\"));\n\n\t/// Use the string interface of StandardCompiler to trigger these\n\tresult = compile(\"\");\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON\"));\n\tresult = compile(\"invalid\");\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'i'\"));\n\tresult = compile(\"\\\"invalid\\\"\");\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"Input is not a JSON object.\"));\n\tresult = compile(\"{}\");\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"No input sources specified.\"));\n\tBOOST_CHECK(!containsAtMostWarnings(result));\n}\n\nBOOST_AUTO_TEST_CASE(invalid_language)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"INVALID\",\n\t\t\"sources\": { \"name\": { \"content\": \"abc\" } }\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"Only \\\"Solidity\\\", \\\"Yul\\\", \\\"SolidityAST\\\" or \\\"EVMAssembly\\\" is supported as a language.\"));\n}\n\nBOOST_AUTO_TEST_CASE(valid_language)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\"\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(!containsError(result, \"JSONError\", \"Only \\\"Solidity\\\" or \\\"Yul\\\" is supported as a language.\"));\n}\n\nBOOST_AUTO_TEST_CASE(no_sources)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\"\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"No input sources specified.\"));\n}\n\nBOOST_AUTO_TEST_CASE(no_sources_empty_object)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"No input sources specified.\"));\n}\n\nBOOST_AUTO_TEST_CASE(no_sources_empty_array)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": []\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"\\\"sources\\\" is not a JSON object.\"));\n}\n\nBOOST_AUTO_TEST_CASE(sources_is_array)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": [\"aa\", \"bb\"]\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"\\\"sources\\\" is not a JSON object.\"));\n}\n\nBOOST_AUTO_TEST_CASE(unexpected_trailing_test)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"A\": {\n\t\t\t\t\"content\": \"contract A { function f() {} }\"\n\t\t\t}\n\t\t}\n\t}\n\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"parse error at line 10, column 2: syntax error while parsing value - unexpected '}'; expected end of input\"));\n}\n\nBOOST_AUTO_TEST_CASE(smoke_test)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"empty\": {\n\t\t\t\t\"content\": \"\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n}\n\nBOOST_AUTO_TEST_CASE(optimizer_enabled_not_boolean)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"optimizer\": {\n\t\t\t\t\"enabled\": \"wrong\"\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"empty\": {\n\t\t\t\t\"content\": \"\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"The \\\"enabled\\\" setting must be a Boolean.\"));\n}\n\nBOOST_AUTO_TEST_CASE(optimizer_runs_not_a_number)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"optimizer\": {\n\t\t\t\t\"enabled\": true,\n\t\t\t\t\"runs\": \"not a number\"\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"empty\": {\n\t\t\t\t\"content\": \"\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"The \\\"runs\\\" setting must be an unsigned number.\"));\n}\n\nBOOST_AUTO_TEST_CASE(optimizer_runs_not_an_unsigned_number)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"optimizer\": {\n\t\t\t\t\"enabled\": true,\n\t\t\t\t\"runs\": -1\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"empty\": {\n\t\t\t\t\"content\": \"\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"The \\\"runs\\\" setting must be an unsigned number.\"));\n}\n\nBOOST_AUTO_TEST_CASE(basic_compilation)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { }\"\n\t\t\t}\n\t\t},\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": {\n\t\t\t\t\t\"A\": [ \"abi\", \"devdoc\", \"userdoc\", \"evm.bytecode\", \"evm.assembly\", \"evm.gasEstimates\", \"evm.legacyAssembly\", \"metadata\" ],\n\t\t\t\t\t\"\": [ \"ast\" ]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"abi\"].is_array());\n\tBOOST_CHECK_EQUAL(util::jsonCompactPrint(contract[\"abi\"]), \"[]\");\n\tBOOST_CHECK(contract[\"devdoc\"].is_object());\n\tBOOST_CHECK_EQUAL(util::jsonCompactPrint(contract[\"devdoc\"]), R\"({\"kind\":\"dev\",\"methods\":{},\"version\":1})\");\n\tBOOST_CHECK(contract[\"userdoc\"].is_object());\n\tBOOST_CHECK_EQUAL(util::jsonCompactPrint(contract[\"userdoc\"]), R\"({\"kind\":\"user\",\"methods\":{},\"version\":1})\");\n\tBOOST_CHECK(contract[\"evm\"].is_object());\n\t/// @TODO check evm.methodIdentifiers, legacyAssembly, bytecode, deployedBytecode\n\tBOOST_CHECK(contract[\"evm\"][\"bytecode\"].is_object());\n\tBOOST_CHECK(contract[\"evm\"][\"bytecode\"][\"object\"].is_string());\n\tBOOST_CHECK_EQUAL(\n\t\tsolidity::test::bytecodeSansMetadata(contract[\"evm\"][\"bytecode\"][\"object\"].get<std::string>()),\n\t\tstd::string(\"6080604052348015600e575f5ffd5b5060\") +\n\t\t(VersionIsRelease ? \"3e\" : util::toHex(bytes{uint8_t(60 + VersionStringStrict.size())})) +\n\t\t\"80601a5f395ff3fe60806040525f5ffdfe\"\n\t);\n\tBOOST_CHECK(contract[\"evm\"][\"assembly\"].is_string());\n\tBOOST_CHECK(contract[\"evm\"][\"assembly\"].get<std::string>().find(\n\t\t\"    /* \\\"fileA\\\":0:14  contract A { } */\\n  mstore(0x40, 0x80)\\n  \"\n\t\t\"callvalue\\n  dup1\\n  \"\n\t\t\"iszero\\n  tag_1\\n  jumpi\\n  \"\n\t\t\"revert(0x00, 0x00)\\n\"\n\t\t\"tag_1:\\n  pop\\n  dataSize(sub_0)\\n  dup1\\n  \"\n\t\t\"dataOffset(sub_0)\\n  0x00\\n  codecopy\\n  0x00\\n  return\\nstop\\n\\nsub_0: assembly {\\n        \"\n\t\t\"/* \\\"fileA\\\":0:14  contract A { } */\\n      mstore(0x40, 0x80)\\n      \"\n\t\t\"revert(0x00, 0x00)\\n\\n    auxdata: 0xa26469706673582212\"\n\t) == 0);\n\tBOOST_CHECK(contract[\"evm\"][\"gasEstimates\"].is_object());\n\tBOOST_CHECK_EQUAL(contract[\"evm\"][\"gasEstimates\"].size(), 1);\n\tBOOST_CHECK(contract[\"evm\"][\"gasEstimates\"][\"creation\"].is_object());\n\tBOOST_CHECK_EQUAL(contract[\"evm\"][\"gasEstimates\"][\"creation\"].size(), 3);\n\tBOOST_CHECK(contract[\"evm\"][\"gasEstimates\"][\"creation\"][\"codeDepositCost\"].is_string());\n\tBOOST_CHECK(contract[\"evm\"][\"gasEstimates\"][\"creation\"][\"executionCost\"].is_string());\n\tBOOST_CHECK(contract[\"evm\"][\"gasEstimates\"][\"creation\"][\"totalCost\"].is_string());\n\tBOOST_CHECK_EQUAL(\n\t\tu256(contract[\"evm\"][\"gasEstimates\"][\"creation\"][\"codeDepositCost\"].get<std::string>()) +\n\t\tu256(contract[\"evm\"][\"gasEstimates\"][\"creation\"][\"executionCost\"].get<std::string>()),\n\t\tu256(contract[\"evm\"][\"gasEstimates\"][\"creation\"][\"totalCost\"].get<std::string>())\n\t);\n\t// Lets take the top level `.code` section (the \"deployer code\"), that should expose most of the features of\n\t// the assembly JSON. What we want to check here is Operation, Push, PushTag, PushSub, PushSubSize and Tag.\n\tBOOST_CHECK(contract[\"evm\"][\"legacyAssembly\"].is_object());\n\tBOOST_CHECK(contract[\"evm\"][\"legacyAssembly\"][\".code\"].is_array());\n\tBOOST_CHECK_EQUAL(\n\t\tutil::jsonCompactPrint(contract[\"evm\"][\"legacyAssembly\"][\".code\"]),\n\t\t\"[{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"80\\\"},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"40\\\"},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"MSTORE\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"CALLVALUE\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"DUP1\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"ISZERO\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"PUSH [tag]\\\",\\\"source\\\":0,\\\"value\\\":\\\"1\\\"},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"JUMPI\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"0\\\"},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"0\\\"},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"REVERT\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"tag\\\",\\\"source\\\":0,\\\"value\\\":\\\"1\\\"},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"JUMPDEST\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"POP\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"PUSH #[$]\\\",\\\"source\\\":0,\\\"value\\\":\\\"0000000000000000000000000000000000000000000000000000000000000000\\\"},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"DUP1\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"PUSH [$]\\\",\\\"source\\\":0,\\\"value\\\":\\\"0000000000000000000000000000000000000000000000000000000000000000\\\"},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"0\\\"},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"CODECOPY\\\",\\\"source\\\":0},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"PUSH\\\",\\\"source\\\":0,\\\"value\\\":\\\"0\\\"},\"\n\t\t\"{\\\"begin\\\":0,\\\"end\\\":14,\\\"name\\\":\\\"RETURN\\\",\\\"source\\\":0}]\"\n\t);\n\tBOOST_CHECK(contract[\"metadata\"].is_string());\n\tBOOST_CHECK(solidity::test::isValidMetadata(contract[\"metadata\"].get<std::string>()));\n\tBOOST_CHECK(result[\"sources\"].is_object());\n\tBOOST_CHECK(result[\"sources\"][\"fileA\"].is_object());\n\tBOOST_CHECK(result[\"sources\"][\"fileA\"][\"ast\"].is_object());\n\tBOOST_CHECK_EQUAL(\n\t\tutil::jsonCompactPrint(result[\"sources\"][\"fileA\"][\"ast\"]),\n\t\t\"{\\\"absolutePath\\\":\\\"fileA\\\",\\\"exportedSymbols\\\":{\\\"A\\\":[1]},\\\"id\\\":2,\\\"nodeType\\\":\\\"SourceUnit\\\",\\\"nodes\\\":[{\\\"abstract\\\":false,\"\n\t\t\"\\\"baseContracts\\\":[],\\\"canonicalName\\\":\\\"A\\\",\\\"contractDependencies\\\":[],\"\n\t\t\"\\\"contractKind\\\":\\\"contract\\\",\\\"fullyImplemented\\\":true,\\\"id\\\":1,\"\n\t\t\"\\\"linearizedBaseContracts\\\":[1],\\\"name\\\":\\\"A\\\",\\\"nameLocation\\\":\\\"9:1:0\\\",\\\"nodeType\\\":\\\"ContractDefinition\\\",\\\"nodes\\\":[],\\\"scope\\\":2,\"\n\t\t\"\\\"src\\\":\\\"0:14:0\\\",\\\"usedErrors\\\":[],\\\"usedEvents\\\":[]}],\\\"src\\\":\\\"0:14:0\\\"}\"\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(compilation_error)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": {\n\t\t\t\t\t\"A\": [\n\t\t\t\t\t\t\"abi\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { function }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(result.contains(\"errors\"));\n\tBOOST_CHECK(result[\"errors\"].size() >= 1);\n\tfor (auto const& error: result[\"errors\"])\n\t{\n\t\tBOOST_REQUIRE(error.is_object());\n\t\tBOOST_REQUIRE(error[\"message\"].is_string());\n\t\tif (error[\"message\"].get<std::string>().find(\"pre-release compiler\") == std::string::npos)\n\t\t{\n\t\t\tBOOST_CHECK_EQUAL(\n\t\t\t\tutil::jsonCompactPrint(error),\n\t\t\t\t\"{\\\"component\\\":\\\"general\\\",\\\"errorCode\\\":\\\"2314\\\",\\\"formattedMessage\\\":\\\"ParserError: Expected identifier but got '}'\\\\n\"\n\t\t\t\t\" --> fileA:1:23:\\\\n  |\\\\n1 | contract A { function }\\\\n  |                       ^\\\\n\\\\n\\\",\\\"message\\\":\\\"Expected identifier but got '}'\\\",\"\n\t\t\t\t\"\\\"severity\\\":\\\"error\\\",\\\"sourceLocation\\\":{\\\"end\\\":23,\\\"file\\\":\\\"fileA\\\",\\\"start\\\":22},\\\"type\\\":\\\"ParserError\\\"}\"\n\t\t\t);\n\t\t}\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(output_selection_explicit)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": {\n\t\t\t\t\t\"A\": [\n\t\t\t\t\t\t\"abi\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"abi\"].is_array());\n\tBOOST_CHECK_EQUAL(util::jsonCompactPrint(contract[\"abi\"]), \"[]\");\n}\n\nBOOST_AUTO_TEST_CASE(output_selection_all_contracts)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": {\n\t\t\t\t\t\"*\": [\n\t\t\t\t\t\t\"abi\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"abi\"].is_array());\n\tBOOST_CHECK_EQUAL(util::jsonCompactPrint(contract[\"abi\"]), \"[]\");\n}\n\nBOOST_AUTO_TEST_CASE(output_selection_all_files_single_contract)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"*\": {\n\t\t\t\t\t\"A\": [\n\t\t\t\t\t\t\"abi\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"abi\"].is_array());\n\tBOOST_CHECK_EQUAL(util::jsonCompactPrint(contract[\"abi\"]), \"[]\");\n}\n\nBOOST_AUTO_TEST_CASE(output_selection_all_files_all_contracts)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"*\": {\n\t\t\t\t\t\"*\": [\n\t\t\t\t\t\t\"abi\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"abi\"].is_array());\n\tBOOST_CHECK_EQUAL(util::jsonCompactPrint(contract[\"abi\"]), \"[]\");\n}\n\nBOOST_AUTO_TEST_CASE(output_selection_dependent_contract)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"*\": {\n\t\t\t\t\t\"A\": [\n\t\t\t\t\t\t\"abi\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract B { } contract A { function f() public { new B(); } }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"abi\"].is_array());\n\tBOOST_CHECK_EQUAL(util::jsonCompactPrint(contract[\"abi\"]), \"[{\\\"inputs\\\":[],\\\"name\\\":\\\"f\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"}]\");\n}\n\nBOOST_AUTO_TEST_CASE(output_selection_dependent_contract_with_import)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"*\": {\n\t\t\t\t\t\"A\": [\n\t\t\t\t\t\t\"abi\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"import \\\"fileB\\\"; contract A { function f() public { new B(); } }\"\n\t\t\t},\n\t\t\t\"fileB\": {\n\t\t\t\t\"content\": \"contract B { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"abi\"].is_array());\n\tBOOST_CHECK_EQUAL(util::jsonCompactPrint(contract[\"abi\"]), \"[{\\\"inputs\\\":[],\\\"name\\\":\\\"f\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"}]\");\n}\n\nBOOST_AUTO_TEST_CASE(filename_with_colon)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"https://github.com/argotorg/solidity/blob/develop/test/compilationTests/gnosis/Tokens/StandardToken.sol\": {\n\t\t\t\t\t\"A\": [\n\t\t\t\t\t\t\"abi\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"https://github.com/argotorg/solidity/blob/develop/test/compilationTests/gnosis/Tokens/StandardToken.sol\": {\n\t\t\t\t\"content\": \"contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"https://github.com/argotorg/solidity/blob/develop/test/compilationTests/gnosis/Tokens/StandardToken.sol\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"abi\"].is_array());\n\tBOOST_CHECK_EQUAL(util::jsonCompactPrint(contract[\"abi\"]), \"[]\");\n}\n\nBOOST_AUTO_TEST_CASE(library_filename_with_colon)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": {\n\t\t\t\t\t\"A\": [\n\t\t\t\t\t\t\"evm.bytecode\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"import \\\"git:library.sol\\\"; contract A { function f() public returns (uint) { return L.g(); } }\"\n\t\t\t},\n\t\t\t\"git:library.sol\": {\n\t\t\t\t\"content\": \"library L { function g() public returns (uint) { return 1; } }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\texpectLinkReferences(contract, {{\"git:library.sol\", {\"L\"}}});\n}\n\nBOOST_AUTO_TEST_CASE(libraries_invalid_top_level)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"libraries\": \"42\"\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"empty\": {\n\t\t\t\t\"content\": \"\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"\\\"libraries\\\" is not a JSON object.\"));\n}\n\nBOOST_AUTO_TEST_CASE(libraries_invalid_entry)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"libraries\": {\n\t\t\t\t\"L\": \"42\"\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"empty\": {\n\t\t\t\t\"content\": \"\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"Library entry is not a JSON object.\"));\n}\n\nBOOST_AUTO_TEST_CASE(libraries_invalid_hex)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"libraries\": {\n\t\t\t\t\"library.sol\": {\n\t\t\t\t\t\"L\": \"0x4200000000000000000000000000000000000xx1\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"empty\": {\n\t\t\t\t\"content\": \"\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"Invalid library address (\\\"0x4200000000000000000000000000000000000xx1\\\") supplied.\"));\n}\n\nBOOST_AUTO_TEST_CASE(libraries_invalid_length)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"libraries\": {\n\t\t\t\t\"library.sol\": {\n\t\t\t\t\t\"L1\": \"0x42\",\n\t\t\t\t\t\"L2\": \"0x4200000000000000000000000000000000000001ff\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"empty\": {\n\t\t\t\t\"content\": \"\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"Library address is of invalid length.\"));\n}\n\nBOOST_AUTO_TEST_CASE(libraries_missing_hex_prefix)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"libraries\": {\n\t\t\t\t\"library.sol\": {\n\t\t\t\t\t\"L\": \"4200000000000000000000000000000000000001\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"empty\": {\n\t\t\t\t\"content\": \"\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"Library address is not prefixed with \\\"0x\\\".\"));\n}\n\nBOOST_AUTO_TEST_CASE(library_linking)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"libraries\": {\n\t\t\t\t\"library.sol\": {\n\t\t\t\t\t\"L\": \"0x4200000000000000000000000000000000000001\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": {\n\t\t\t\t\t\"A\": [\n\t\t\t\t\t\t\"evm.bytecode\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"import \\\"library.sol\\\"; import \\\"library2.sol\\\"; contract A { function f() public returns (uint) { L2.g(); return L.g(); } }\"\n\t\t\t},\n\t\t\t\"library.sol\": {\n\t\t\t\t\"content\": \"library L { function g() public returns (uint) { return 1; } }\"\n\t\t\t},\n\t\t\t\"library2.sol\": {\n\t\t\t\t\"content\": \"library L2 { function g() public { } }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_TEST(containsAtMostWarnings(result));\n\tJson contractResult = getContractResult(result, \"fileA\", \"A\");\n\texpectLinkReferences(contractResult, {{\"library2.sol\", {\"L2\"}}});\n}\n\nBOOST_AUTO_TEST_CASE(linking_yul)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Yul\",\n\t\t\"settings\": {\n\t\t\t\"libraries\": {\n\t\t\t\t\"fileB\": {\n\t\t\t\t\t\"L\": \"0x4200000000000000000000000000000000000001\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": {\n\t\t\t\t\t\"*\": [\n\t\t\t\t\t\t\"evm.bytecode.linkReferences\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"object \\\"a\\\" { code { let addr := linkersymbol(\\\"fileB:L\\\") sstore(0, addr) } }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_TEST(containsAtMostWarnings(result));\n\tJson contractResult = getContractResult(result, \"fileA\", \"a\");\n\texpectLinkReferences(contractResult, {});\n}\n\nBOOST_AUTO_TEST_CASE(linking_yul_empty_link_reference)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Yul\",\n\t\t\"settings\": {\n\t\t\t\"libraries\": {\n\t\t\t\t\"\": {\n\t\t\t\t\t\"\": \"0x4200000000000000000000000000000000000001\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": {\n\t\t\t\t\t\"*\": [\n\t\t\t\t\t\t\"evm.bytecode.linkReferences\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"object \\\"a\\\" { code { let addr := linkersymbol(\\\"\\\") sstore(0, addr) } }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_TEST(containsAtMostWarnings(result));\n\tJson contractResult = getContractResult(result, \"fileA\", \"a\");\n\texpectLinkReferences(contractResult, {{\"\", {\"\"}}});\n}\n\nBOOST_AUTO_TEST_CASE(linking_yul_no_filename_in_link_reference)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Yul\",\n\t\t\"settings\": {\n\t\t\t\"libraries\": {\n\t\t\t\t\"\": {\n\t\t\t\t\t\"L\": \"0x4200000000000000000000000000000000000001\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": {\n\t\t\t\t\t\"*\": [\n\t\t\t\t\t\t\"evm.bytecode.linkReferences\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"object \\\"a\\\" { code { let addr := linkersymbol(\\\"L\\\") sstore(0, addr) } }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_TEST(containsAtMostWarnings(result));\n\tJson contractResult = getContractResult(result, \"fileA\", \"a\");\n\texpectLinkReferences(contractResult, {{\"\", {\"L\"}}});\n}\n\nBOOST_AUTO_TEST_CASE(linking_yul_same_library_name_different_files)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Yul\",\n\t\t\"settings\": {\n\t\t\t\"libraries\": {\n\t\t\t\t\"fileB\": {\n\t\t\t\t\t\"L\": \"0x4200000000000000000000000000000000000001\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": {\n\t\t\t\t\t\"*\": [\n\t\t\t\t\t\t\"evm.bytecode.linkReferences\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"object \\\"a\\\" { code { let addr := linkersymbol(\\\"fileC:L\\\") sstore(0, addr) } }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_TEST(containsAtMostWarnings(result));\n\tJson contractResult = getContractResult(result, \"fileA\", \"a\");\n\texpectLinkReferences(contractResult, {{\"fileC\", {\"L\"}}});\n}\n\nBOOST_AUTO_TEST_CASE(evm_version)\n{\n\tauto inputForVersion = [](std::string const& _version)\n\t{\n\t\treturn R\"(\n\t\t\t{\n\t\t\t\t\"language\": \"Solidity\",\n\t\t\t\t\"sources\": { \"fileA\": { \"content\": \"contract A { }\" } },\n\t\t\t\t\"settings\": {\n\t\t\t\t\t)\" + _version + R\"(\n\t\t\t\t\t\"outputSelection\": {\n\t\t\t\t\t\t\"fileA\": {\n\t\t\t\t\t\t\t\"A\": [ \"metadata\" ]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t)\";\n\t};\n\tJson result;\n\tfor (auto const& version: EVMVersion::allVersions())\n\t{\n\t\tresult = compile(inputForVersion(fmt::format(\"\\\"evmVersion\\\": \\\"{}\\\",\", version.name())));\n\t\tBOOST_CHECK(result[\"contracts\"][\"fileA\"][\"A\"][\"metadata\"].get<std::string>().find(fmt::format(\"\\\"evmVersion\\\":\\\"{}\\\"\", version.name())) != std::string::npos);\n\t}\n\t// test default\n\tresult = compile(inputForVersion(\"\"));\n\tBOOST_CHECK(result[\"contracts\"][\"fileA\"][\"A\"][\"metadata\"].get<std::string>().find(fmt::format(\"\\\"evmVersion\\\":\\\"{}\\\"\", EVMVersion::current().name())) != std::string::npos);\n\t// test invalid\n\tresult = compile(inputForVersion(\"\\\"evmVersion\\\": \\\"invalid\\\",\"));\n\tBOOST_CHECK(result[\"errors\"][0][\"message\"].get<std::string>() == \"Invalid EVM version requested.\");\n}\n\nBOOST_AUTO_TEST_CASE(optimizer_settings_default_disabled)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": { \"A\": [ \"metadata\" ] }\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"metadata\"].is_string());\n\tJson metadata;\n\tBOOST_CHECK(util::jsonParseStrict(contract[\"metadata\"].get<std::string>(), metadata));\n\n\tJson const& optimizer = metadata[\"settings\"][\"optimizer\"];\n\tBOOST_CHECK(optimizer.contains(\"enabled\"));\n\tBOOST_CHECK(optimizer[\"enabled\"].get<bool>() == false);\n\tBOOST_CHECK(!optimizer.contains(\"details\"));\n\tBOOST_CHECK(optimizer[\"runs\"].get<unsigned>() == 200);\n}\n\nBOOST_AUTO_TEST_CASE(optimizer_settings_default_enabled)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": { \"A\": [ \"metadata\" ] }\n\t\t\t},\n\t\t\t\"optimizer\": { \"enabled\": true }\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"metadata\"].is_string());\n\tJson metadata;\n\tBOOST_CHECK(util::jsonParseStrict(contract[\"metadata\"].get<std::string>(), metadata));\n\n\tJson const& optimizer = metadata[\"settings\"][\"optimizer\"];\n\tBOOST_CHECK(optimizer.contains(\"enabled\"));\n\tBOOST_CHECK(optimizer[\"enabled\"].get<bool>() == true);\n\tBOOST_CHECK(!optimizer.contains(\"details\"));\n\tBOOST_CHECK(optimizer[\"runs\"].get<unsigned>() == 200);\n}\n\nBOOST_AUTO_TEST_CASE(optimizer_settings_details_exactly_as_default_disabled)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": { \"A\": [ \"metadata\" ] }\n\t\t\t},\n\t\t\t\"optimizer\": { \"details\": {\n\t\t\t\t\"constantOptimizer\" : false,\n\t\t\t\t\"cse\" : false,\n\t\t\t\t\"deduplicate\" : false,\n\t\t\t\t\"jumpdestRemover\" : true,\n\t\t\t\t\"orderLiterals\" : false,\n\t\t\t\t\"peephole\" : true\n\t\t\t} }\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"metadata\"].is_string());\n\tJson metadata;\n\tBOOST_CHECK(util::jsonParseStrict(contract[\"metadata\"].get<std::string>(), metadata));\n\n\tJson const& optimizer = metadata[\"settings\"][\"optimizer\"];\n\tBOOST_CHECK(optimizer.contains(\"enabled\"));\n\t// enabled is switched to false instead!\n\tBOOST_CHECK(optimizer[\"enabled\"].get<bool>() == false);\n\tBOOST_CHECK(!optimizer.contains(\"details\"));\n\tBOOST_CHECK(optimizer[\"runs\"].get<unsigned>() == 200);\n}\n\nBOOST_AUTO_TEST_CASE(optimizer_settings_details_different)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": { \"A\": [ \"metadata\" ] }\n\t\t\t},\n\t\t\t\"optimizer\": { \"runs\": 600, \"details\": {\n\t\t\t\t\"constantOptimizer\" : true,\n\t\t\t\t\"cse\" : false,\n\t\t\t\t\"deduplicate\" : true,\n\t\t\t\t\"jumpdestRemover\" : true,\n\t\t\t\t\"orderLiterals\" : false,\n\t\t\t\t\"peephole\" : true,\n\t\t\t\t\"yul\": true,\n\t\t\t\t\"inliner\": true\n\t\t\t} }\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"metadata\"].is_string());\n\tJson metadata;\n\tBOOST_CHECK(util::jsonParseStrict(contract[\"metadata\"].get<std::string>(), metadata));\n\n\tJson const& optimizer = metadata[\"settings\"][\"optimizer\"];\n\tBOOST_CHECK(!optimizer.contains(\"enabled\"));\n\tBOOST_CHECK(optimizer.contains(\"details\"));\n\tBOOST_CHECK(optimizer[\"details\"][\"constantOptimizer\"].get<bool>() == true);\n\tBOOST_CHECK(optimizer[\"details\"][\"cse\"].get<bool>() == false);\n\tBOOST_CHECK(optimizer[\"details\"][\"deduplicate\"].get<bool>() == true);\n\tBOOST_CHECK(optimizer[\"details\"][\"jumpdestRemover\"].get<bool>() == true);\n\tBOOST_CHECK(optimizer[\"details\"][\"orderLiterals\"].get<bool>() == false);\n\tBOOST_CHECK(optimizer[\"details\"][\"peephole\"].get<bool>() == true);\n\tBOOST_CHECK(optimizer[\"details\"][\"yul\"].get<bool>() == true);\n\tBOOST_CHECK(optimizer[\"details\"][\"yulDetails\"].is_object());\n//\tBOOST_CHECK(\n//\t\tutil::convertContainer<std::set<std::string>>(optimizer[\"details\"][\"yulDetails\"].getMemberNames()) ==\n//\t\t(std::set<std::string>{\"stackAllocation\", \"optimizerSteps\"})\n//\t);\n\tBOOST_CHECK(optimizer[\"details\"][\"yulDetails\"][\"stackAllocation\"].get<bool>() == true);\n\tBOOST_CHECK(\n\t\toptimizer[\"details\"][\"yulDetails\"][\"optimizerSteps\"].get<std::string>() ==\n\t\tOptimiserSettings::DefaultYulOptimiserSteps + \":\"s + OptimiserSettings::DefaultYulOptimiserCleanupSteps\n \t);\n\tBOOST_CHECK_EQUAL(optimizer[\"details\"].size(), 10);\n\tBOOST_CHECK(optimizer[\"runs\"].get<unsigned>() == 600);\n}\n\nBOOST_AUTO_TEST_CASE(metadata_without_compilation)\n{\n\t// NOTE: the contract code here should fail to compile due to \"out of stack\"\n\t// If the metadata is successfully returned, that means no compilation was attempted.\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": { \"A\": [ \"metadata\" ] }\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A {\n  function x(uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h, uint i, uint j, uint k, uint l, uint m, uint n, uint o, uint p) pure public {}\n  function y() pure public {\n    uint a; uint b; uint c; uint d; uint e; uint f; uint g; uint h; uint i; uint j; uint k; uint l; uint m; uint n; uint o; uint p;\n    x(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);\n  }\n}\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"metadata\"].is_string());\n\tBOOST_CHECK(solidity::test::isValidMetadata(contract[\"metadata\"].get<std::string>()));\n}\n\n\nBOOST_AUTO_TEST_CASE(license_in_metadata)\n{\n\tstd::string const input = R\"(\n\t\t\t{\n\t\t\t\t\"language\": \"Solidity\",\n\t\t\t\t\"sources\": {\n\t\t\t\t\t\"fileA\": { \"content\": \"import \\\"fileB\\\"; contract A { } // SPDX-License-Identifier: GPL-3.0 \\n\" },\n\t\t\t\t\t\"fileB\": { \"content\": \"import \\\"fileC\\\"; /* SPDX-License-Identifier: MIT */ contract B { }\" },\n\t\t\t\t\t\"fileC\": { \"content\": \"import \\\"fileD\\\"; /* SPDX-License-Identifier: MIT AND GPL-3.0 */ contract C { }\" },\n\t\t\t\t\t\"fileD\": { \"content\": \"// SPDX-License-Identifier: (GPL-3.0+ OR MIT) AND MIT \\n import \\\"fileE\\\"; contract D { }\" },\n\t\t\t\t\t\"fileE\": { \"content\": \"import \\\"fileF\\\"; /// SPDX-License-Identifier: MIT   \\n contract E { }\" },\n\t\t\t\t\t\"fileF\": { \"content\": \"/*\\n * SPDX-License-Identifier: MIT\\n */ contract F { }\" }\n\t\t\t\t},\n\t\t\t\t\"settings\": {\n\t\t\t\t\t\"outputSelection\": {\n\t\t\t\t\t\t\"fileA\": {\n\t\t\t\t\t\t\t\"*\": [ \"metadata\" ]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"metadata\"].is_string());\n\tJson metadata;\n\tBOOST_REQUIRE(util::jsonParseStrict(contract[\"metadata\"].get<std::string>(), metadata));\n\tBOOST_CHECK_EQUAL(metadata[\"sources\"][\"fileA\"][\"license\"], \"GPL-3.0\");\n\tBOOST_CHECK_EQUAL(metadata[\"sources\"][\"fileB\"][\"license\"], \"MIT\");\n\tBOOST_CHECK_EQUAL(metadata[\"sources\"][\"fileC\"][\"license\"], \"MIT AND GPL-3.0\");\n\tBOOST_CHECK_EQUAL(metadata[\"sources\"][\"fileD\"][\"license\"], \"(GPL-3.0+ OR MIT) AND MIT\");\n\t// This is actually part of the docstring, but still picked up\n\t// because the source location of the contract does not cover the docstring.\n\tBOOST_CHECK_EQUAL(metadata[\"sources\"][\"fileE\"][\"license\"], \"MIT\");\n\tBOOST_CHECK_EQUAL(metadata[\"sources\"][\"fileF\"][\"license\"], \"MIT\");\n}\n\nBOOST_AUTO_TEST_CASE(common_pattern)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"*\": {\n\t\t\t\t\t\"*\": [ \"evm.bytecode.object\", \"metadata\" ]\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A { function f() pure public {} }\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_CHECK(contract.is_object());\n\tBOOST_CHECK(contract[\"metadata\"].is_string());\n\tBOOST_CHECK(solidity::test::isValidMetadata(contract[\"metadata\"].get<std::string>()));\n\tBOOST_CHECK(contract[\"evm\"][\"bytecode\"].is_object());\n\tBOOST_CHECK(contract[\"evm\"][\"bytecode\"][\"object\"].is_string());\n}\n\nBOOST_AUTO_TEST_CASE(use_stack_optimization)\n{\n\t// NOTE: the contract code here should fail to compile due to \"out of stack\"\n\t// If we enable stack optimization, though, it will compile.\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"settings\": {\n\t\t\t\"optimizer\": { \"enabled\": true, \"details\": { \"yul\": true } },\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"fileA\": { \"A\": [ \"evm.bytecode.object\" ] }\n\t\t\t}\n\t\t},\n\t\t\"sources\": {\n\t\t\t\"fileA\": {\n\t\t\t\t\"content\": \"contract A {\n\t\t\t\t\tfunction y() public {\n\t\t\t\t\t\tassembly {\n\t\t\t\t\t\t\tfunction fun() -> a3, b3, c3, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, n3, o3, p3\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlet a := 1\n\t\t\t\t\t\t\t\tlet b := 1\n\t\t\t\t\t\t\t\tlet z3 := 1\n\t\t\t\t\t\t\t\tsstore(a, b)\n\t\t\t\t\t\t\t\tsstore(add(a, 1), b)\n\t\t\t\t\t\t\t\tsstore(add(a, 2), b)\n\t\t\t\t\t\t\t\tsstore(add(a, 3), b)\n\t\t\t\t\t\t\t\tsstore(add(a, 4), b)\n\t\t\t\t\t\t\t\tsstore(add(a, 5), b)\n\t\t\t\t\t\t\t\tsstore(add(a, 6), b)\n\t\t\t\t\t\t\t\tsstore(add(a, 7), b)\n\t\t\t\t\t\t\t\tsstore(add(a, 8), b)\n\t\t\t\t\t\t\t\tsstore(add(a, 9), b)\n\t\t\t\t\t\t\t\tsstore(add(a, 10), b)\n\t\t\t\t\t\t\t\tsstore(add(a, 11), b)\n\t\t\t\t\t\t\t\tsstore(add(a, 12), b)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlet a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1 := fun()\n\t\t\t\t\t\t\tlet a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2 := fun()\n\t\t\t\t\t\t\tsstore(a1, a2)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\"\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\n\tJson parsedInput;\n\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\n\tsolidity::frontend::StandardCompiler compiler;\n\tJson result = compiler.compile(parsedInput);\n\n\tBOOST_CHECK(containsAtMostWarnings(result));\n\tJson contract = getContractResult(result, \"fileA\", \"A\");\n\tBOOST_REQUIRE(contract.is_object());\n\tBOOST_REQUIRE(contract[\"evm\"][\"bytecode\"][\"object\"].is_string());\n\tBOOST_CHECK(contract[\"evm\"][\"bytecode\"][\"object\"].get<std::string>().length() > 20);\n\n\t// Now disable stack optimizations and UnusedFunctionParameterPruner (p)\n\t// results in \"stack too deep\"\n\tstd::string optimiserSteps = OptimiserSettings::DefaultYulOptimiserSteps;\n\toptimiserSteps.erase(\n\t\tremove_if(optimiserSteps.begin(), optimiserSteps.end(), [](char ch) { return ch == 'p'; }),\n\t\toptimiserSteps.end()\n\t);\n\tparsedInput[\"settings\"][\"optimizer\"][\"details\"][\"yulDetails\"][\"stackAllocation\"] = false;\n\tparsedInput[\"settings\"][\"optimizer\"][\"details\"][\"yulDetails\"][\"optimizerSteps\"] = optimiserSteps;\n\n\tresult = compiler.compile(parsedInput);\n\tBOOST_REQUIRE(result[\"errors\"].is_array());\n\tBOOST_CHECK(result[\"errors\"][0][\"severity\"] == \"error\");\n\tBOOST_REQUIRE(result[\"errors\"][0][\"message\"].is_string());\n\tBOOST_CHECK(result[\"errors\"][0][\"message\"].get<std::string>().find(\"When compiling inline assembly\") != std::string::npos);\n\tBOOST_CHECK(result[\"errors\"][0][\"type\"] == \"CompilerError\");\n}\n\nBOOST_AUTO_TEST_CASE(standard_output_selection_wildcard)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\t\"sources\":\n\t\t{\n\t\t\t\"A\":\n\t\t\t{\n\t\t\t\t\"content\": \"pragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t\t}\n\t\t},\n\t\t\"settings\":\n\t\t{\n\t\t\t\"outputSelection\":\n\t\t\t{\n\t\t\t\t\"*\": { \"C\": [\"evm.bytecode\"] }\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\n\tJson parsedInput;\n\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\n\tsolidity::frontend::StandardCompiler compiler;\n\tJson result = compiler.compile(parsedInput);\n\n\tBOOST_REQUIRE(result[\"contracts\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\"A\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"A\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\"A\"][\"C\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"A\"][\"C\"][\"evm\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"A\"][\"C\"][\"evm\"][\"bytecode\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"].size() == 1);\n\tBOOST_REQUIRE(result[\"sources\"][\"A\"].is_object());\n\n}\n\nBOOST_AUTO_TEST_CASE(standard_output_selection_wildcard_colon_source)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\":\n\t\t{\n\t\t\t\":A\":\n\t\t\t{\n\t\t\t\t\"content\": \"pragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t\t}\n\t\t},\n\t\t\"settings\":\n\t\t{\n\t\t\t\"outputSelection\":\n\t\t\t{\n\t\t\t\t\"*\": { \"C\": [\"evm.bytecode\"] }\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\n\tJson parsedInput;\n\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\n\tsolidity::frontend::StandardCompiler compiler;\n\tJson result = compiler.compile(parsedInput);\n\n\tBOOST_REQUIRE(result[\"contracts\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\":A\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\":A\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\":A\"][\"C\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\":A\"][\"C\"][\"evm\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\":A\"][\"C\"][\"evm\"][\"bytecode\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"].size() == 1);\n\tBOOST_REQUIRE(result[\"sources\"][\":A\"].is_object());\n}\n\nBOOST_AUTO_TEST_CASE(standard_output_selection_wildcard_empty_source)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\":\n\t\t{\n\t\t\t\"\":\n\t\t\t{\n\t\t\t\t\"content\": \"pragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t\t}\n\t\t},\n\t\t\"settings\":\n\t\t{\n\t\t\t\"outputSelection\":\n\t\t\t{\n\t\t\t\t\"*\": { \"C\": [\"evm.bytecode\"] }\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\n\tJson parsedInput;\n\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\n\tsolidity::frontend::StandardCompiler compiler;\n\tJson result = compiler.compile(parsedInput);\n\n\tBOOST_REQUIRE(result[\"contracts\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\"\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\"\"][\"C\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"\"][\"C\"][\"evm\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"\"][\"C\"][\"evm\"][\"bytecode\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"].size() == 1);\n\tBOOST_REQUIRE(result[\"sources\"][\"\"].is_object());\n}\n\nBOOST_AUTO_TEST_CASE(standard_output_selection_wildcard_multiple_sources)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\":\n\t\t{\n\t\t\t\"A\":\n\t\t\t{\n\t\t\t\t\"content\": \"pragma solidity >=0.0; contract C { function f() public pure {} }\"\n\t\t\t},\n\t\t\t\"B\":\n\t\t\t{\n\t\t\t\t\"content\": \"pragma solidity >=0.0; contract D { function f() public pure {} }\"\n\t\t\t}\n\t\t},\n\t\t\"settings\":\n\t\t{\n\t\t\t\"outputSelection\":\n\t\t\t{\n\t\t\t\t\"*\": { \"D\": [\"evm.bytecode\"] }\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\n\tJson parsedInput;\n\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\n\tsolidity::frontend::StandardCompiler compiler;\n\tJson result = compiler.compile(parsedInput);\n\n\tBOOST_REQUIRE(result[\"contracts\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\"B\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"B\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\"B\"][\"D\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"B\"][\"D\"][\"evm\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"B\"][\"D\"][\"evm\"][\"bytecode\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"].size() == 2);\n\tBOOST_REQUIRE(result[\"sources\"][\"A\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"][\"B\"].is_object());\n}\n\nBOOST_AUTO_TEST_CASE(stopAfter_invalid_value)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\":\n\t\t{ \"\": { \"content\": \"pragma solidity >=0.0; contract C { function f() public pure {} }\" } },\n\t\t\"settings\":\n\t\t{\n\t\t\t\"stopAfter\": \"rrr\",\n\t\t\t\"outputSelection\":\n\t\t\t{\n\t\t\t\t\"*\": { \"C\": [\"evm.bytecode\"] }\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"Invalid value for \\\"settings.stopAfter\\\". Only valid value is \\\"parsing\\\".\"));\n}\n\nBOOST_AUTO_TEST_CASE(stopAfter_invalid_type)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\":\n\t\t{ \"\": { \"content\": \"pragma solidity >=0.0; contract C { function f() public pure {} }\" } },\n\t\t\"settings\":\n\t\t{\n\t\t\t\"stopAfter\": 3,\n\t\t\t\"outputSelection\":\n\t\t\t{\n\t\t\t\t\"*\": { \"C\": [\"evm.bytecode\"] }\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"\\\"settings.stopAfter\\\" must be a string.\"));\n}\n\nBOOST_AUTO_TEST_CASE(stopAfter_bin_conflict)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\":\n\t\t{ \"\": { \"content\": \"pragma solidity >=0.0; contract C { function f() public pure {} }\" } },\n\t\t\"settings\":\n\t\t{\n\t\t\t\"stopAfter\": \"parsing\",\n\t\t\t\"outputSelection\":\n\t\t\t{\n\t\t\t\t\"*\": { \"C\": [\"evm.bytecode\"] }\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"Requested output selection conflicts with \\\"settings.stopAfter\\\".\"));\n}\n\nBOOST_AUTO_TEST_CASE(stopAfter_ast_output)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"a.sol\": {\n\t\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-3.0\\nimport \\\"tes32.sol\\\";\\n contract C is X { constructor() {} }\"\n\t\t\t}\n\t\t},\n\t\t\"settings\": {\n\t\t\t\"stopAfter\": \"parsing\",\n\t\t\t\"outputSelection\": { \"*\": { \"\": [ \"ast\" ] } }\n\t\t}\n\t}\n\t)\";\n\tJson result = compile(input);\n\tBOOST_CHECK(result[\"sources\"].is_object());\n\tBOOST_CHECK(result[\"sources\"][\"a.sol\"].is_object());\n\tBOOST_CHECK(result[\"sources\"][\"a.sol\"][\"ast\"].is_object());\n}\n\nBOOST_AUTO_TEST_CASE(dependency_tracking_of_abstract_contract)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"BlockRewardAuRaBase.sol\": {\n\t\t\t\t\"content\": \" contract Sacrifice { constructor() payable {} } abstract contract BlockRewardAuRaBase { function _transferNativeReward() internal { new Sacrifice(); } function _distributeTokenRewards() internal virtual; } \"\n\t\t\t},\n\t\t\t\"BlockRewardAuRaCoins.sol\": {\n\t\t\t\t\"content\": \" import \\\"./BlockRewardAuRaBase.sol\\\"; contract BlockRewardAuRaCoins is BlockRewardAuRaBase { function transferReward() public { _transferNativeReward(); } function _distributeTokenRewards() internal override {} } \"\n\t\t\t}\n\t\t},\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"BlockRewardAuRaCoins.sol\": {\n\t\t\t\t\t\"BlockRewardAuRaCoins\": [\"ir\", \"evm.bytecode.sourceMap\"]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\n\tJson parsedInput;\n\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\n\tsolidity::frontend::StandardCompiler compiler;\n\tJson result = compiler.compile(parsedInput);\n\n\tBOOST_REQUIRE(result[\"contracts\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\"BlockRewardAuRaCoins.sol\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"BlockRewardAuRaCoins.sol\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\"BlockRewardAuRaCoins.sol\"][\"BlockRewardAuRaCoins\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"BlockRewardAuRaCoins.sol\"][\"BlockRewardAuRaCoins\"][\"evm\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"BlockRewardAuRaCoins.sol\"][\"BlockRewardAuRaCoins\"][\"ir\"].is_string());\n\tBOOST_REQUIRE(result[\"contracts\"][\"BlockRewardAuRaCoins.sol\"][\"BlockRewardAuRaCoins\"][\"evm\"][\"bytecode\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"].size() == 2);\n}\n\nBOOST_AUTO_TEST_CASE(dependency_tracking_of_abstract_contract_yul)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"A.sol\": {\n\t\t\t\t\"content\": \"contract A {} contract B {} contract C { constructor() { new B(); } } contract D {}\"\n\t\t\t}\n\t\t},\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"A.sol\": {\n\t\t\t\t\t\"C\": [\"ir\"]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\n\tJson parsedInput;\n\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\n\tsolidity::frontend::StandardCompiler compiler;\n\tJson result = compiler.compile(parsedInput);\n\n\tBOOST_REQUIRE(result[\"contracts\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\"A.sol\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"A.sol\"].size() == 1);\n\tBOOST_REQUIRE(result[\"contracts\"][\"A.sol\"][\"C\"].is_object());\n\tBOOST_REQUIRE(result[\"contracts\"][\"A.sol\"][\"C\"][\"ir\"].is_string());\n\n\tconst std::string& irCode = result[\"contracts\"][\"A.sol\"][\"C\"][\"ir\"].get<std::string>();\n\n\t// Make sure C and B contracts are deployed\n\tBOOST_REQUIRE(irCode.find(\"object \\\"C\") != std::string::npos);\n\tBOOST_REQUIRE(irCode.find(\"object \\\"B\") != std::string::npos);\n\n\t// Make sure A and D are NOT deployed as they were not requested and are not\n\t// in any dependency\n\tBOOST_REQUIRE(irCode.find(\"object \\\"A\") == std::string::npos);\n\tBOOST_REQUIRE(irCode.find(\"object \\\"D\") == std::string::npos);\n\n\n\tBOOST_REQUIRE(result[\"sources\"].is_object());\n\tBOOST_REQUIRE(result[\"sources\"].size() == 1);\n}\n\nBOOST_AUTO_TEST_CASE(source_location_of_bare_block)\n{\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"A.sol\": {\n\t\t\t\t\"content\": \"contract A { constructor() { uint x = 2; { uint y = 3; } } }\"\n\t\t\t}\n\t\t},\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"A.sol\": {\n\t\t\t\t\t\"A\": [\"evm.bytecode.sourceMap\"]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\n\tJson parsedInput;\n\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\n\tsolidity::frontend::StandardCompiler compiler;\n\tJson result = compiler.compile(parsedInput);\n\n\tstd::string sourceMap = result[\"contracts\"][\"A.sol\"][\"A\"][\"evm\"][\"bytecode\"][\"sourceMap\"].get<std::string>();\n\n\t// Check that the bare block's source location is referenced.\n\tstd::string sourceRef =\n\t\t\";\" +\n\t\tstd::to_string(std::string{\"contract A { constructor() { uint x = 2; \"}.size()) +\n\t\t\":\" +\n\t\tstd::to_string(std::string{\"{ uint y = 3; }\"}.size());\n\tBOOST_REQUIRE(sourceMap.find(sourceRef) != std::string::npos);\n}\n\nBOOST_AUTO_TEST_CASE(ethdebug_excluded_from_wildcards)\n{\n\tfrontend::StandardCompiler compiler;\n\t// excluded from output selection wildcard\n\tJson result = compiler.compile(generateStandardJson(true, {}, Json::array({\"*\"})));\n\tBOOST_REQUIRE(result.dump().find(\"ethdebug\") == std::string::npos);\n\t// excluded from debug info selection wildcard\n\tresult = compiler.compile(generateStandardJson(true, {\"*\"}, Json::array({\"ir\"})));\n\tBOOST_REQUIRE(result.dump().find(\"ethdebug\") == std::string::npos);\n\t// excluded from both - just in case ;)\n\tresult = compiler.compile(generateStandardJson(true, {\"*\"}, Json::array({\"*\"})));\n\tBOOST_REQUIRE(result.dump().find(\"ethdebug\") == std::string::npos);\n}\n\nBOOST_AUTO_TEST_CASE(ethdebug_debug_info_ethdebug)\n{\n\tstatic std::vector<std::tuple<Json, std::optional<std::function<bool(Json)>>>> tests{\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, Json::array({\"ethdebug\"}), Json::array({\"*\"})),\n\t\t\tstd::nullopt,\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"ethdebug\"}), Json::array({\"*\"})),\n\t\t\tstd::nullopt,\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, Json::array({\"ethdebug\"}), Json::array({\"evm.bytecode.ethdebug\"})),\n\t\t\tstd::nullopt,\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, Json::array({\"ethdebug\"}), Json::array({\"evm.deployedBytecode.ethdebug\"})),\n\t\t\tstd::nullopt,\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, Json::array({\"ethdebug\"}), Json::array({\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"})),\n\t\t\tstd::nullopt,\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, Json::array({\"ethdebug\"}), Json::array({\"irOptimized\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, Json::array({\"ethdebug\"}), Json::array({\"irOptimized\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"irOptimized\", \"evm.bytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"irOptimized\", \"evm.deployedBytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"irOptimized\", \"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"irOptimized\", \"evm.bytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"irOptimized\", \"evm.deployedBytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"irOptimized\", \"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"ethdebug\"}), Json::array({\"irOptimized\"}), YulCode()),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"ethdebug\"}), Json::array({\"irOptimized\"}), YulCode()),\n\t\t\t{}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"ethdebugs\"}), Json::array({\"irOptimized\"}), YulCode()), {}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(\n\t\t\t\ttrue, Json::array({\"ethdebug\"}), {\n\t\t\t\t\t{\"fileA\", {{\"contractA\", Json::array({\"evm.deployedBytecode.bin\"})}}},\n\t\t\t\t\t{\"fileB\", {{\"contractB\", Json::array({\"evm.bytecode.bin\"})}}}\n\t\t\t\t},\n\t\t\t\tSolidityCode({\n\t\t\t\t\t{\"fileA\", \"pragma solidity >=0.0; contract contractA { function f() public pure {} }\"},\n\t\t\t\t\t{\"fileB\", \"pragma solidity >=0.0; contract contractB { function f() public pure {} }\"}\n\t\t\t\t}), true\n\t\t\t),\n\t\t\tstd::nullopt,\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"ethdebug\"}), Json::array({\"*\"}), EvmAssemblyCode()),\n\t\t\tstd::nullopt,\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"ethdebug\"}), Json::array({\"*\"}), SolidityAstCode()),\n\t\t\tstd::nullopt,\n\t\t},\n\t};\n\tfrontend::StandardCompiler compiler;\n\tfor (auto const& test: tests)\n\t{\n\t\tJson result = compiler.compile(std::get<0>(test));\n\t\tif (std::get<1>(test).has_value())\n\t\t\tBOOST_REQUIRE((*std::get<1>(test))(result));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(ethdebug_ethdebug_output)\n{\n\tstatic std::vector<std::tuple<Json, std::optional<std::function<bool(Json)>>>> tests{\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, Json::array({\"ethdebug\"}), Json::array({\"evm.bytecode.ethdebug\"})),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, {}, Json::array({\"evm.bytecode.ethdebug\"})),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, Json::array({\"ethdebug\"}), Json::array({\"evm.deployedBytecode.ethdebug\"})),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, {}, Json::array({\"evm.deployedBytecode.ethdebug\"})),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, Json::array({\"ethdebug\"}), Json::array({\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"})),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(false, {}, Json::array({\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"})),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"location\"}), Json::array({\"evm.bytecode.ethdebug\"})),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"location\"}), Json::array({\"evm.deployedBytecode.ethdebug\"})),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"location\"}), Json::array({\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"})),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"ethdebug\"}), Json::array({\"evm.bytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.contains(\"ethdebug\") && result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"bytecode\"].contains(\"ethdebug\");\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"ethdebug\"}), Json::array({\"evm.deployedBytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.contains(\"ethdebug\") && result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"deployedBytecode\"].contains(\"ethdebug\");\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, Json::array({\"ethdebug\"}), Json::array({\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.contains(\"ethdebug\") && result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"deployedBytecode\"].contains(\"ethdebug\") &&\n\t\t\t\t\t result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"bytecode\"].contains(\"ethdebug\");\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.bytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.contains(\"ethdebug\") && result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"bytecode\"].contains(\"ethdebug\");\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.deployedBytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.contains(\"ethdebug\") && result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"deployedBytecode\"].contains(\"ethdebug\");\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.contains(\"ethdebug\") && result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"deployedBytecode\"].contains(\"ethdebug\") &&\n\t\t\t\t\t result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"bytecode\"].contains(\"ethdebug\");\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.bytecode.ethdebug\", \"ir\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos && result.contains(\"ethdebug\") && result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"bytecode\"].contains(\"ethdebug\");\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.deployedBytecode.ethdebug\", \"ir\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos && result.contains(\"ethdebug\") && result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"deployedBytecode\"].contains(\"ethdebug\");\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.bytecode.ethdebugs\"})),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.deployedBytecode.ethdebugs\"})),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\", \"ir\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos && result.contains(\"ethdebug\") && result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"deployedBytecode\"].contains(\"ethdebug\") &&\n\t\t\t\t\t result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][\"bytecode\"].contains(\"ethdebug\");\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.bytecode.ethdebug\", \"ir\"}), YulCode()),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"/// ethdebug: enabled\") != std::string::npos && result[\"contracts\"][\"fileA\"][\"object\"][\"evm\"][\"bytecode\"].contains(\"ethdebug\");\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.deployedBytecode.ethdebug\", \"ir\"}), YulCode()),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.bytecode.ethdebug\", \"evm.deployedBytecode.ethdebug\", \"ir\"}), YulCode()),\n\t\t\tstd::nullopt\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.bytecode\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"ethdebug\") == std::string::npos;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(true, {}, Json::array({\"evm.deployedBytecode\"})),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result.dump().find(\"ethdebug\") == std::string::npos;\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tgenerateExperimentalStandardJson(\n\t\t\t\ttrue, {}, {\n\t\t\t\t\t{\"fileA\", {{\"contractA\", Json::array({\"evm.deployedBytecode.ethdebug\"})}}},\n\t\t\t\t\t{\"fileB\", {{\"contractB\", Json::array({\"evm.bytecode.ethdebug\"})}}}\n\t\t\t\t},\n\t\t\t\tSolidityCode({\n\t\t\t\t\t{\"fileA\", \"pragma solidity >=0.0; contract contractA { function f() public pure {} }\"},\n\t\t\t\t\t{\"fileB\", \"pragma solidity >=0.0; contract contractB { function f() public pure {} }\"}\n\t\t\t\t}), true\n\t\t\t),\n\t\t\t[](const Json& result)\n\t\t\t{\n\t\t\t\treturn result[\"contracts\"][\"fileA\"][\"contractA\"][\"evm\"][\"deployedBytecode\"].contains(\"ethdebug\") &&\n\t\t\t\t\tresult[\"contracts\"][\"fileB\"][\"contractB\"][\"evm\"][\"bytecode\"].contains(\"ethdebug\") && result.contains(\"ethdebug\");\n\t\t\t}\n\t\t}\n\t};\n\tfrontend::StandardCompiler compiler;\n\tfor (auto const& [standardJsonToCompile, optionalCheck]: tests)\n\t{\n\t\tJson result = compiler.compile(standardJsonToCompile);\n\t\tBOOST_REQUIRE(!optionalCheck.has_value() ? result.contains(\"errors\") : result.contains(\"contracts\"));\n\t\tif (optionalCheck.has_value())\n\t\t\tBOOST_REQUIRE((*optionalCheck)(result));\n\t}\n}\n\nBOOST_DATA_TEST_CASE(ethdebug_output_instructions_smoketest, boost::unit_test::data::make({\"deployedBytecode\", \"bytecode\"}), bytecodeType)\n{\n\tfrontend::StandardCompiler compiler;\n\tJson result = compiler.compile(generateExperimentalStandardJson(true, {}, Json::array({std::string(\"evm.\") + bytecodeType + \".ethdebug\"})));\n\tBOOST_REQUIRE(result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][bytecodeType].contains(\"ethdebug\"));\n\tbool creation = std::string(bytecodeType) == \"bytecode\";\n\tJson ethdebugInstructionsToCheck = result[\"contracts\"][\"fileA\"][\"C\"][\"evm\"][bytecodeType][\"ethdebug\"];\n\tBOOST_REQUIRE(ethdebugInstructionsToCheck[\"contract\"][\"definition\"][\"source\"][\"id\"] == 0);\n\tBOOST_REQUIRE(ethdebugInstructionsToCheck[\"contract\"][\"name\"] == \"C\");\n\tBOOST_REQUIRE(ethdebugInstructionsToCheck[\"environment\"] == (creation ? \"create\" : \"call\"));\n\tBOOST_REQUIRE(ethdebugInstructionsToCheck[\"instructions\"].is_array());\n\tfor (auto const& instruction: ethdebugInstructionsToCheck[\"instructions\"])\n\t{\n\t\tBOOST_REQUIRE(instruction.contains(\"offset\"));\n\t\tBOOST_REQUIRE(instruction.contains(\"operation\"));\n\t\tBOOST_REQUIRE(instruction[\"operation\"].contains(\"mnemonic\"));\n\t\tif (instruction.contains(\"context\"))\n\t\t{\n\t\t\tBOOST_REQUIRE(instruction[\"context\"][\"code\"][\"range\"].contains(\"length\"));\n\t\t\tBOOST_REQUIRE(instruction[\"context\"][\"code\"][\"range\"].contains(\"offset\"));\n\t\t\tBOOST_REQUIRE(instruction[\"context\"][\"code\"][\"source\"].contains(\"id\"));\n\t\t}\n\t\tstd::string mnemonic = instruction[\"operation\"][\"mnemonic\"];\n\t\tif (mnemonic.find(\"PUSH\") != std::string::npos)\n\t\t{\n\t\t\tsize_t bytesToPush = boost::lexical_cast<size_t>(mnemonic.substr(4));\n\t\t\tif (bytesToPush > 0)\n\t\t\t{\n\t\t\t\tBOOST_REQUIRE(instruction[\"operation\"].contains(\"arguments\"));\n\t\t\t\tBOOST_REQUIRE(instruction[\"operation\"][\"arguments\"].is_array());\n\t\t\t\tBOOST_REQUIRE(instruction[\"operation\"][\"arguments\"].size() == 1);\n\t\t\t\tstd::string argument = instruction[\"operation\"][\"arguments\"][0];\n\t\t\t\tBOOST_REQUIRE(argument.length() % 2 == 0);\n\t\t\t\tBOOST_REQUIRE(bytesToPush == (argument.length() - 2) / 2); // remove \"0x\" and calculate actual byte size from hex.\n\t\t\t}\n\t\t\telse\n\t\t\t\tBOOST_REQUIRE(!instruction[\"operation\"].contains(\"arguments\"));\n\t\t}\n\t\telse\n\t\t\tBOOST_REQUIRE(!instruction[\"operation\"].contains(\"arguments\"));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(no_experimental_import_ast_solidity_evmasm)\n{\n\tfrontend::StandardCompiler compiler;\n\t{\n\t\tchar const* input = R\"(\n\t\t{\n\t\t\t\"language\": \"SolidityAST\",\n\t\t\t\"sources\": {\n\t\t\t\t\"A\": {\n\t\t            \"assemblyJson\": {\n\t\t                \".code\": [\n\t\t                    { \"name\": \"PUSH\", \"value\": \"0\" }\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t)\";\n\n\t\tJson parsedInput;\n\t\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\t\tJson result = compiler.compile(parsedInput);\n\t\tBOOST_CHECK(containsError(result, \"FatalError\", \"'SolidityAST' and 'EVMAssembly' inputs are experimental and can only be used with the 'settings.experimental' option enabled.\"));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(no_experimental_invalid_output_selection)\n{\n\tfrontend::StandardCompiler compiler;\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"A.sol\": {\n\t\t\t\t\"content\": \"contract A { constructor() { uint x = 2; { uint y = 3; } } }\"\n\t\t\t}\n\t\t},\n\t\t\"settings\": {\n\t\t\t\"outputSelection\": {\n\t\t\t\t\"A.sol\": {\n\t\t\t\t\t\"A\": [\"irOptimizedAst\"]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t)\";\n\n\tJson parsedInput;\n\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\tJson result = compiler.compile(parsedInput);\n\tBOOST_CHECK(\n\t\tcontainsError(\n\t\t\tresult,\n\t\t\t\"FatalError\", \"'irAst', 'irOptimizedAst', 'yulCFGJson', and 'ethdebug' outputs are experimental and can only be used with the 'settings.experimental' option enabled.\"\n\t\t)\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(experimental_non_boolean)\n{\n\tfrontend::StandardCompiler compiler;\n\tchar const* input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"A.sol\": {\n\t\t\t\t\"content\": \"contract A { constructor() { uint x = 2; { uint y = 3; } } }\"\n\t\t\t}\n\t\t},\n\t\t\"settings\": {\n\t\t\t\"experimental\": 1\n\t\t}\n\t}\n\t)\";\n\n\tJson parsedInput;\n\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\tJson result = compiler.compile(parsedInput);\n\tBOOST_CHECK(containsError(result, \"JSONError\", \"'settings.experimental' must be a Boolean.\"));\n}\n\nBOOST_AUTO_TEST_CASE(via_ssa_cfg_with_experimental)\n{\n\tfrontend::StandardCompiler compiler;\n\tstatic auto constexpr input = R\"(\n\t{\n\t\t\"language\": \"Solidity\",\n\t\t\"sources\": {\n\t\t\t\"A.sol\": {\n\t\t\t\t\"content\": \"// SPDX-License-Identifier: GPL-2.0\\npragma solidity >=0.0;\\ncontract A { function f() public pure returns (uint) { return 1; } }\"\n\t\t\t}\n\t\t},\n\t\t\"settings\": {\n\t\t\t\"experimental\": true,\n\t\t\t\"viaSSACFG\": true,\n\t\t\t\"outputSelection\": {\"*\": {\"*\": [\"evm.bytecode\"]}}\n\t\t}\n\t}\n\t)\";\n\n\tJson parsedInput;\n\tBOOST_REQUIRE(util::jsonParseStrict(input, parsedInput));\n\tJson result = compiler.compile(parsedInput);\n\t// Should compile without fatal errors (warnings are acceptable)\n\tBOOST_CHECK(!containsError(result, \"FatalError\", \"\"));\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // end namespaces\n"
  },
  {
    "path": "test/libsolidity/SyntaxTest.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#include <test/libsolidity/SyntaxTest.h>\n\n#include <test/libsolidity/util/Common.h>\n#include <test/Common.h>\n#include <boost/algorithm/string.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n#include <boost/test/unit_test.hpp>\n#include <boost/throw_exception.hpp>\n#include <range/v3/algorithm/find_if.hpp>\n#include <fstream>\n#include <memory>\n#include <stdexcept>\n\nusing namespace solidity;\nusing namespace solidity::util;\nusing namespace solidity::util::formatting;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace solidity::frontend::test;\nusing namespace boost::unit_test;\nnamespace fs = boost::filesystem;\n\nSyntaxTest::SyntaxTest(\n\tstd::string const& _filename,\n\tlangutil::EVMVersion _evmVersion,\n\tError::Severity _minSeverity\n):\n\tCommonSyntaxTest(_filename, _evmVersion),\n\tm_minSeverity(_minSeverity)\n{\n\tstatic std::set<std::string> const compileViaYulAllowedValues{\"true\", \"false\"};\n\n\tauto const eofEnabled = solidity::test::CommonOptions::get().eofVersion().has_value();\n\n\tm_compileViaYul = m_reader.stringSetting(\"compileViaYul\", eofEnabled ? \"true\" : \"false\");\n\tif (!compileViaYulAllowedValues.contains(m_compileViaYul))\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid compileViaYul value: \" + m_compileViaYul + \".\"));\n\n\tif (m_compileViaYul == \"false\" && eofEnabled)\n\t\tm_shouldRun = false;\n\n\tm_optimiseYul = m_reader.boolSetting(\"optimize-yul\", true);\n\tm_experimental = m_reader.boolSetting(\"experimental\", false);\n\n\tstatic std::map<std::string, PipelineStage> const pipelineStages = {\n\t\t{\"parsing\", PipelineStage::Parsing},\n\t\t{\"analysis\", PipelineStage::Analysis},\n\t\t{\"compilation\", PipelineStage::Compilation}\n\t};\n\tstd::string stopAfter = m_reader.stringSetting(\"stopAfter\", \"compilation\");\n\tif (!pipelineStages.count(stopAfter))\n\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\"Invalid stopAfter value: \" + stopAfter + \".\"));\n\tm_stopAfter = pipelineStages.at(stopAfter);\n}\n\nvoid SyntaxTest::setupCompiler(CompilerStack& _compiler)\n{\n\tAnalysisFramework::setupCompiler(_compiler);\n\n\t_compiler.setEVMVersion(m_evmVersion);\n\t_compiler.setOptimiserSettings(\n\t\tm_optimiseYul ?\n\t\tOptimiserSettings::full() :\n\t\tOptimiserSettings::minimal()\n\t);\n\t_compiler.setViaIR(m_compileViaYul == \"true\");\n\t_compiler.setExperimental(m_experimental);\n\t_compiler.setMetadataFormat(CompilerStack::MetadataFormat::NoMetadata);\n\t_compiler.setMetadataHash(CompilerStack::MetadataHash::None);\n}\n\nvoid SyntaxTest::parseAndAnalyze()\n{\n\trunFramework(withPreamble(m_sources.sources), m_stopAfter);\n\tif (!pipelineSuccessful() && stageSuccessful(PipelineStage::Analysis) && !compiler().isExperimentalAnalysis())\n\t{\n\t\tErrorList const& errors = compiler().errors();\n\t\tstatic auto isInternalError = [](std::shared_ptr<Error const> const& _error) {\n\t\t\treturn\n\t\t\t\tError::isError(_error->type()) &&\n\t\t\t\t_error->type() != Error::Type::CodeGenerationError &&\n\t\t\t\t_error->type() != Error::Type::UnimplementedFeatureError\n\t\t\t;\n\t\t};\n\t\t// Most errors are detected during analysis, and should not happen during code generation.\n\t\t// There are some exceptions, e.g. unimplemented features or stack too deep, but anything else at this stage\n\t\t// is an internal error that signals a bug in the compiler (rather than in user's code).\n\t\tif (\n\t\t\tauto error = ranges::find_if(errors, isInternalError);\n\t\t\terror != ranges::end(errors)\n\t\t)\n\t\t\tBOOST_THROW_EXCEPTION(std::runtime_error(\n\t\t\t\t\"Unexpected \" + Error::formatErrorType((*error)->type()) + \" at compilation stage.\"\n\t\t\t\t\" This error should NOT be encoded as expectation and should be fixed instead.\"\n\t\t\t));\n\t}\n\n\tfilterObtainedErrors();\n}\n\nvoid SyntaxTest::filterObtainedErrors()\n{\n\tfor (auto const& currentError: filteredErrors())\n\t{\n\t\tif (currentError->severity() < m_minSeverity)\n\t\t\tcontinue;\n\n\t\tint locationStart = -1;\n\t\tint locationEnd = -1;\n\t\tstd::string sourceName;\n\t\tif (SourceLocation const* location = currentError->sourceLocation())\n\t\t{\n\t\t\tlocationStart = location->start;\n\t\t\tlocationEnd = location->end;\n\t\t\tsolAssert(location->sourceName, \"\");\n\t\t\tsourceName = *location->sourceName;\n\t\t\tif(m_sources.sources.count(sourceName) == 1)\n\t\t\t{\n\t\t\t\tint preambleSize =\n\t\t\t\t\t\tstatic_cast<int>(compiler().charStream(sourceName).size()) -\n\t\t\t\t\t\tstatic_cast<int>(m_sources.sources[sourceName].size());\n\t\t\t\tsolAssert(preambleSize >= 0, \"\");\n\n\t\t\t\t// ignore the version & license pragma inserted by the testing tool when calculating locations.\n\t\t\t\tif (location->start != -1)\n\t\t\t\t{\n\t\t\t\t\tsolAssert(location->start >= preambleSize, \"\");\n\t\t\t\t\tlocationStart = location->start - preambleSize;\n\t\t\t\t}\n\t\t\t\tif (location->end != -1)\n\t\t\t\t{\n\t\t\t\t\tsolAssert(location->end >= preambleSize, \"\");\n\t\t\t\t\tlocationEnd = location->end - preambleSize;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tm_errorList.emplace_back(SyntaxTestError{\n\t\t\tcurrentError->type(),\n\t\t\tcurrentError->errorId(),\n\t\t\terrorMessage(*currentError),\n\t\t\tsourceName,\n\t\t\tlocationStart,\n\t\t\tlocationEnd\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "test/libsolidity/SyntaxTest.h",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n#pragma once\n\n#include <test/libsolidity/AnalysisFramework.h>\n#include <test/TestCase.h>\n#include <test/CommonSyntaxTest.h>\n#include <liblangutil/Exceptions.h>\n#include <libsolutil/AnsiColorized.h>\n\n#include <iosfwd>\n#include <string>\n#include <vector>\n#include <utility>\n\nnamespace solidity::frontend::test\n{\n\nusing solidity::test::SyntaxTestError;\n\nclass SyntaxTest: public AnalysisFramework, public solidity::test::CommonSyntaxTest\n{\npublic:\n\tstatic std::unique_ptr<TestCase> create(Config const& _config)\n\t{\n\t\treturn std::make_unique<SyntaxTest>(_config.filename, _config.evmVersion);\n\t}\n\tSyntaxTest(\n\t\tstd::string const& _filename,\n\t\tlangutil::EVMVersion _evmVersion,\n\t\tlangutil::Error::Severity _minSeverity = langutil::Error::Severity::Info\n\t);\n\nprotected:\n\tvoid setupCompiler(CompilerStack& _compiler) override;\n\tvoid parseAndAnalyze() override;\n\tvirtual void filterObtainedErrors();\n\n\tbool m_optimiseYul{};\n\tbool m_experimental{};\n\tstd::string m_compileViaYul{};\n\tlangutil::Error::Severity m_minSeverity{};\n\tPipelineStage m_stopAfter;\n};\n\n}\n"
  },
  {
    "path": "test/libsolidity/ViewPureChecker.cpp",
    "content": "/*\n    This file is part of solidity.\n\n    solidity is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    solidity is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/**\n * Unit tests for the view and pure checker.\n */\n\n#include <test/libsolidity/AnalysisFramework.h>\n\n#include <test/Common.h>\n\n#include <boost/test/unit_test.hpp>\n\n#include <string>\n#include <tuple>\n\nusing namespace solidity::langutil;\nusing namespace solidity::test;\n\nnamespace solidity::frontend::test\n{\n\nBOOST_FIXTURE_TEST_SUITE(ViewPureChecker, AnalysisFramework)\n\nBOOST_AUTO_TEST_CASE(environment_access)\n{\n\tstd::vector<std::string> view{\n\t\t\"block.coinbase\",\n\t\t\"block.timestamp\",\n\t\t\"block.difficulty\",\n\t\t\"block.number\",\n\t\t\"block.gaslimit\",\n\t\t\"blockhash(7)\",\n\t\t\"gasleft()\",\n\t\t\"msg.value\",\n\t\t\"msg.sender\",\n\t\t\"tx.origin\",\n\t\t\"tx.gasprice\",\n\t\t\"this\",\n\t\t\"address(1).balance\",\n\t};\n\tif (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())\n\t\tview.emplace_back(\"address(0x4242).staticcall(\\\"\\\")\");\n\tif (solidity::test::CommonOptions::get().evmVersion().hasBlobHash())\n\t\tview.emplace_back(\"blobhash(7)\");\n\n\t// ``block.blockhash`` and ``blockhash`` are tested separately below because their usage will\n\t// produce warnings that can't be handled in a generic way.\n\tstd::vector<std::string> pure{\n\t\t\"msg.data\",\n\t\t\"msg.data[0]\",\n\t\t\"msg.sig\",\n\t\t\"msg\",\n\t\t\"block\",\n\t\t\"tx\"\n\t};\n\tfor (std::string const& x: view)\n\t{\n\t\tCHECK_ERROR(\n\t\t\t\"contract C { function f() pure public { \" + x + \"; } }\",\n\t\t\tTypeError,\n\t\t\t\"Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires \\\"view\\\"\"\n\t\t);\n\t}\n\tfor (std::string const& x: pure)\n\t{\n\t\tCHECK_WARNING(\n\t\t\t\"contract C { function f() view public { \" + x + \"; } }\",\n\t\t\t\"Function state mutability can be restricted to pure\"\n\t\t);\n\t}\n\n\tCHECK_WARNING_ALLOW_MULTI(\n\t\t\"contract C { function f() view public { blockhash; } }\",\n\t\t(std::vector<std::string>{\n\t\t\t\"Function state mutability can be restricted to pure\",\n\t\t\t\"Statement has no effect.\"\n\t}));\n\n\tCHECK_ERROR(\n\t\t\"contract C { function f() view public { block.blockhash; } }\",\n\t\tTypeError,\n\t\t\"\\\"block.blockhash()\\\" has been deprecated in favor of \\\"blockhash()\\\"\"\n\t);\n\n\tstd::string baseFeeContract = \"contract C { function f() view public { block.basefee; } }\";\n\tif (!solidity::test::CommonOptions::get().evmVersion().hasBaseFee())\n\t\tCHECK_ERROR(\n\t\t\tbaseFeeContract,\n\t\t\tTypeError,\n\t\t\t\"\\\"basefee\\\" is not supported by the VM version.\"\n\t\t);\n\telse\n\t\tCHECK_SUCCESS_NO_WARNINGS(baseFeeContract);\n\n\tstd::string blobBaseFeeContract = \"contract C { function f() view public { block.blobbasefee; } }\";\n\tif (!solidity::test::CommonOptions::get().evmVersion().hasBlobBaseFee())\n\t\tCHECK_ERROR(\n\t\t\tblobBaseFeeContract,\n\t\t\tTypeError,\n\t\t\t\"\\\"blobbasefee\\\" is not supported by the VM version.\"\n\t\t);\n\telse\n\t\tCHECK_SUCCESS_NO_WARNINGS(blobBaseFeeContract);\n}\n\nBOOST_AUTO_TEST_CASE(address_staticcall)\n{\n\tstd::string text = R\"(\n\t\tcontract C {\n\t\t\tfunction i() view public returns (bool) {\n\t\t\t\t(bool success,) = address(0x4242).staticcall(\"\");\n\t\t\t\treturn success;\n\t\t\t}\n\t\t}\n\t)\";\n\tif (!solidity::test::CommonOptions::get().evmVersion().hasStaticCall())\n\t\tCHECK_ERROR(text, TypeError, \"\\\"staticcall\\\" is not supported by the VM version.\");\n\telse\n\t\tCHECK_SUCCESS_NO_WARNINGS(text);\n}\n\n\nBOOST_AUTO_TEST_CASE(assembly_staticcall, *boost::unit_test::precondition(nonEOF()))\n{\n\tstd::string text = R\"(\n\t\tcontract C {\n\t\t\tfunction i() view public {\n\t\t\t\tassembly { pop(staticcall(gas(), 1, 2, 3, 4, 5)) }\n\t\t\t}\n\t\t}\n\t)\";\n\tif (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())\n\t\tCHECK_SUCCESS_NO_WARNINGS(text);\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n}\n"
  },
  {
    "path": "test/libsolidity/analysis/FunctionCallGraph.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n/// Unit tests for libsolidity/analysis/FunctionCallGraph.h\n\n#include <libsolidity/analysis/FunctionCallGraph.h>\n\n#include <test/Common.h>\n#include <test/libsolidity/util/SoltestErrors.h>\n\n#include <libsolutil/CommonData.h>\n\n#include <libsolidity/ast/AST.h>\n#include <libsolidity/interface/CompilerStack.h>\n\n#include <boost/test/unit_test.hpp>\n\n#include <range/v3/action/sort.hpp>\n#include <range/v3/algorithm/all_of.hpp>\n#include <range/v3/range/conversion.hpp>\n#include <range/v3/view/join.hpp>\n#include <range/v3/view/map.hpp>\n#include <range/v3/view/remove_if.hpp>\n#include <range/v3/view/set_algorithm.hpp>\n#include <range/v3/view/transform.hpp>\n\n#include <memory>\n#include <ostream>\n#include <set>\n#include <string>\n#include <tuple>\n#include <vector>\n\nusing namespace solidity::util;\nusing namespace solidity::langutil;\nusing namespace solidity::frontend;\nusing namespace std::string_literals;\n\nusing EdgeMap = std::map<\n\tCallGraph::Node,\n\tstd::set<CallGraph::Node, CallGraph::CompareByID>,\n\tCallGraph::CompareByID\n>;\nusing EdgeNames = std::set<std::tuple<std::string, std::string>>;\nusing CallGraphMap = std::map<std::string, CallGraph const*>;\n\nnamespace\n{\n\nstd::unique_ptr<CompilerStack> parseAndAnalyzeContracts(std::string _sourceCode)\n{\n\tReadCallback::Callback fileReader = [](std::string const&, std::string const&)\n\t{\n\t\tsoltestAssert(false, \"For simplicity this test suite supports only files without imports.\");\n\t\treturn ReadCallback::Result{true, \"\"};\n\t};\n\n\tauto compilerStack = std::make_unique<CompilerStack>(fileReader);\n\tcompilerStack->setSources({{\"\", _sourceCode}});\n\n\t// NOTE: The code in test cases is expected to be correct so we can keep error handling simple\n\t// here and just assert that there are no errors.\n\tbool success = compilerStack->parseAndAnalyze();\n\tsoltestAssert(success, \"\");\n\n\tsoltestAssert(\n\t\tranges::all_of(\n\t\t\tcompilerStack->ast(\"\").nodes(),\n\t\t\t[](auto const& _node){ return !dynamic_cast<ImportDirective const*>(_node.get()); }\n\t\t),\n\t\t\"For simplicity this test suite supports only files without imports.\"\n\t);\n\n\treturn compilerStack;\n}\n\nEdgeNames edgeNames(EdgeMap const& _edgeMap)\n{\n\tEdgeNames names;\n\n\tfor (auto const& [edgeStart, allEnds]: _edgeMap)\n\t\tfor (auto const& edgeEnd: allEnds)\n\t\t\tnames.emplace(toString(edgeStart), toString(edgeEnd));\n\n\treturn names;\n}\n\nstd::tuple<CallGraphMap, CallGraphMap> collectGraphs(CompilerStack const& _compilerStack)\n{\n\tsoltestAssert(_compilerStack.state() >= CompilerStack::State::AnalysisSuccessful);\n\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs;\n\n\tfor (std::string const& fullyQualifiedContractName: _compilerStack.contractNames())\n\t{\n\t\tsoltestAssert(std::get<0>(graphs).count(fullyQualifiedContractName) == 0 && std::get<1>(graphs).count(fullyQualifiedContractName) == 0, \"\");\n\n\t\t// This relies on two assumptions: (1) CompilerStack received an empty string as a path for\n\t\t// the contract and (2) contracts used in test cases have no imports.\n\t\tsoltestAssert(fullyQualifiedContractName.size() > 0 && fullyQualifiedContractName[0] == ':', \"\");\n\t\tstd::string contractName = fullyQualifiedContractName.substr(1);\n\n\t\tstd::get<0>(graphs).emplace(contractName, _compilerStack.contractDefinition(fullyQualifiedContractName).annotation().creationCallGraph->get());\n\t\tstd::get<1>(graphs).emplace(contractName, _compilerStack.contractDefinition(fullyQualifiedContractName).annotation().deployedCallGraph->get());\n\t}\n\n\treturn graphs;\n}\n\nvoid checkCallGraphExpectations(\n\tCallGraphMap const& _callGraphs,\n\tstd::map<std::string, EdgeNames> const& _expectedEdges,\n\tstd::map<std::string, std::set<std::string>> const& _expectedCreatedContractSets = {},\n\tstd::map<std::string, std::set<std::string>> const& _expectedEmittedEventSets = {}\n)\n{\n\tauto getContractName = [](ContractDefinition const* _contract){ return _contract->name(); };\n\tauto eventToString = [](EventDefinition const* _event){ return toString(CallGraph::Node(_event)); };\n\tauto notEmpty = [](std::set<std::string> const& _set){ return !_set.empty(); };\n\n\tsoltestAssert(\n\t\t(_expectedCreatedContractSets | ranges::views::values | ranges::views::remove_if(notEmpty)).empty(),\n\t\t\"Contracts that are not expected to create other contracts should not be included in _expectedCreatedContractSets.\"\n\t);\n\tsoltestAssert(\n\t\t(_expectedEdges | ranges::views::keys | ranges::to<std::set>()) == (_callGraphs | ranges::views::keys | ranges::to<std::set>()) &&\n\t\t(ranges::views::set_difference(_expectedCreatedContractSets | ranges::views::keys, _expectedEdges | ranges::views::keys)).empty(),\n\t\t\"Contracts listed in expectations do not match contracts actually found in the source file or in other expectations.\"\n\t);\n\tfor (std::string const& contractName: _expectedEdges | ranges::views::keys)\n\t{\n\t\tsoltestAssert(\n\t\t\t(ranges::views::set_difference(valueOrDefault(_expectedCreatedContractSets, contractName, {}), _expectedEdges | ranges::views::keys)).empty(),\n\t\t\t\"Inconsistent expectations: contract expected to be created but not to be present in the source file.\"\n\t\t);\n\t}\n\n\tstd::map<std::string, EdgeNames> edges;\n\tstd::map<std::string, std::set<std::string>> createdContractSets;\n\tstd::map<std::string, std::set<std::string>> emittedEventSets;\n\tfor (std::string const& contractName: _expectedEdges | ranges::views::keys)\n\t{\n\t\tsoltestAssert(_callGraphs.at(contractName) != nullptr, \"\");\n\t\tCallGraph const& callGraph = *_callGraphs.at(contractName);\n\n\t\tedges[contractName] = edgeNames(callGraph.edges);\n\t\tif (!callGraph.bytecodeDependency.empty())\n\t\t\tcreatedContractSets[contractName] = callGraph.bytecodeDependency |\n\t\t\t\tranges::views::keys |\n\t\t\t\tranges::views::transform(getContractName) |\n\t\t\t\tranges::to<std::set<std::string>>();\n\t\tif (!callGraph.emittedEvents.empty())\n\t\t\temittedEventSets[contractName] = callGraph.emittedEvents |\n\t\t\t\t ranges::views::transform(eventToString) |\n\t\t\t\t ranges::to<std::set<std::string>>();\n\t}\n\n\tBOOST_CHECK_EQUAL(edges, _expectedEdges);\n\tBOOST_CHECK_EQUAL(createdContractSets, _expectedCreatedContractSets);\n\tBOOST_CHECK_EQUAL(emittedEventSets, _expectedEmittedEventSets);\n}\n\nstd::ostream& operator<<(std::ostream& _out, EdgeNames const& _edgeNames)\n{\n\tfor (auto const& [from, to]: _edgeNames)\n\t\t_out << \"    \" << from << \" -> \" << to << std::endl;\n\treturn _out;\n}\n\nstd::ostream& operator<<(std::ostream& _out, std::set<std::string> const& _set)\n{\n\t_out << \"{\" << (_set | ranges::views::join(\", \") | ranges::to<std::string>()) << \"}\";\n\treturn _out;\n}\n\nstd::ostream& operator<<(std::ostream& _out, std::map<std::string, EdgeNames> const& _edgeSets)\n{\n\t// Extra newline for error report readability. Otherwise the first line does not start at the first column.\n\t_out << std::endl;\n\n\tfor (auto const &[contractName, edges]: _edgeSets)\n\t{\n\t\t_out << contractName << \":\" << std::endl;\n\t\t_out << edges;\n\t}\n\treturn _out;\n}\n\nstd::ostream& operator<<(std::ostream& _out, std::map<std::string, std::set<std::string>> const& _map)\n{\n\t// Extra newline for error report readability. Otherwise the first line does not start at the first column.\n\t_out << std::endl;\n\n\tfor (auto const &[key, value]: _map)\n\t\t_out << key << \": \" << value << std::endl;\n\treturn _out;\n}\n\n} // namespace\n\nnamespace boost::test_tools::tt_detail\n{\n\n// Boost won't find the << operator unless we put it in the std namespace which is illegal.\n// The recommended solution is to overload print_log_value<> struct and make it use our operator.\n\ntemplate<>\nstruct print_log_value<EdgeNames>\n{\n\tvoid operator()(std::ostream& _output, EdgeNames const& _edgeNames) { ::operator<<(_output, _edgeNames); }\n};\n\ntemplate<>\nstruct print_log_value<std::set<std::string>>\n{\n\tvoid operator()(std::ostream& _output, std::set<std::string> const& _set) { ::operator<<(_output, _set); }\n};\n\ntemplate<>\nstruct print_log_value<std::map<std::string, EdgeNames>>\n{\n\tvoid operator()(std::ostream& _output, std::map<std::string, EdgeNames> const& _edgeSets) { ::operator<<(_output, _edgeSets); }\n};\n\ntemplate<>\nstruct print_log_value<std::map<std::string, std::set<std::string>>>\n{\n\tvoid operator()(std::ostream& _output, std::map<std::string, std::set<std::string>> const& _map) { ::operator<<(_output, _map); }\n};\n\n} // namespace boost::test_tools::tt_detail\n\nnamespace solidity::frontend::test\n{\n\nBOOST_AUTO_TEST_SUITE(FunctionCallGraphTest)\n\nBOOST_AUTO_TEST_CASE(only_definitions)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction free() {}\n\n\t\tlibrary L {\n\t\t\tfunction ext() external {}\n\t\t\tfunction pub() public {}\n\t\t\tfunction inr() internal {}\n\t\t\tfunction prv() private {}\n\t\t}\n\n\t\tcontract C {\n\t\t\tfunction ext() external {}\n\t\t\tfunction pub() public {}\n\t\t\tfunction inr() internal {}\n\t\t\tfunction prv() private {}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t\t{\"L\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.ext()\"},\n\t\t\t{\"Entry\", \"function C.pub()\"},\n\t\t}},\n\t\t{\"L\", {\n\t\t\t{\"Entry\", \"function L.ext()\"},\n\t\t\t{\"Entry\", \"function L.pub()\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(ordinary_calls)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction free() {}\n\n\t\tlibrary L {\n\t\t\tfunction ext() external { pub(); inr(); }\n\t\t\tfunction pub() public { inr(); }\n\t\t\tfunction inr() internal { prv(); }\n\t\t\tfunction prv() private { free(); free(); }\n\t\t}\n\n\t\tcontract C {\n\t\t\tfunction ext() external { pub(); }\n\t\t\tfunction pub() public { inr(); prv(); free(); }\n\t\t\tfunction inr() internal { prv(); L.inr(); }\n\t\t\tfunction prv() private { free(); free(); }\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t\t{\"L\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.ext()\"},\n\t\t\t{\"Entry\", \"function C.pub()\"},\n\t\t\t{\"function C.ext()\", \"function C.pub()\"},\n\t\t\t{\"function C.pub()\", \"function C.inr()\"},\n\t\t\t{\"function C.pub()\", \"function C.prv()\"},\n\t\t\t{\"function C.pub()\", \"function free()\"},\n\t\t\t{\"function C.inr()\", \"function C.prv()\"},\n\t\t\t{\"function C.inr()\", \"function L.inr()\"},\n\t\t\t{\"function C.prv()\", \"function free()\"},\n\t\t\t{\"function L.inr()\", \"function L.prv()\"},\n\t\t\t{\"function L.prv()\", \"function free()\"},\n\t\t}},\n\t\t{\"L\", {\n\t\t\t{\"Entry\", \"function L.ext()\"},\n\t\t\t{\"Entry\", \"function L.pub()\"},\n\t\t\t{\"function L.ext()\", \"function L.pub()\"},\n\t\t\t{\"function L.ext()\", \"function L.inr()\"},\n\t\t\t{\"function L.pub()\", \"function L.inr()\"},\n\t\t\t{\"function L.inr()\", \"function L.prv()\"},\n\t\t\t{\"function L.prv()\", \"function free()\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(call_chains_through_externals)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tlibrary L {\n\t\t\tfunction ext() external { C(address(0x0)).ext(); }\n\t\t\tfunction pub() public {}\n\t\t\tfunction inr() internal {}\n\t\t\tfunction prv() private {}\n\t\t}\n\n\t\tcontract C {\n\t\t\tfunction ext() external {}\n\t\t\tfunction pub() public {}\n\t\t\tfunction inr() internal {}\n\t\t\tfunction prv() private {}\n\n\t\t\tfunction ext2() external { this.ext(); this.pub(); L.ext(); L.pub(); }\n\t\t\tfunction pub2() public { this.ext(); this.pub(); L.ext(); L.pub(); }\n\t\t\tfunction pub3() public { C(address(0x0)).ext(); }\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t\t{\"L\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.ext()\"},\n\t\t\t{\"Entry\", \"function C.ext2()\"},\n\t\t\t{\"Entry\", \"function C.pub()\"},\n\t\t\t{\"Entry\", \"function C.pub2()\"},\n\t\t\t{\"Entry\", \"function C.pub3()\"},\n\t\t}},\n\t\t{\"L\", {\n\t\t\t{\"Entry\", \"function L.ext()\"},\n\t\t\t{\"Entry\", \"function L.pub()\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(calls_from_constructors)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction free() returns (uint) {}\n\n\t\tlibrary L {\n\t\t\tfunction ext() external {}\n\t\t}\n\n\t\tcontract C {\n\t\t\tconstructor() { this.ext(); inr(); L.ext(); free(); }\n\n\t\t\tfunction ext() external {}\n\t\t\tfunction inr() internal {}\n\t\t}\n\n\t\tcontract D {\n\t\t\tuint a = this.ext();\n\t\t\tuint b = inr();\n\t\t\tuint c = free();\n\n\t\t\tfunction ext() external returns (uint) {}\n\t\t\tfunction inr() internal returns (uint) {}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"constructor of C\"},\n\t\t\t{\"constructor of C\", \"function C.inr()\"},\n\t\t\t{\"constructor of C\", \"function free()\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"function D.inr()\"},\n\t\t\t{\"Entry\", \"function free()\"},\n\t\t}},\n\t\t{\"L\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.ext()\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"function D.ext()\"},\n\t\t}},\n\t\t{\"L\", {\n\t\t\t{\"Entry\", \"function L.ext()\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(calls_to_constructors)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction free() { new D(); }\n\n\t\tlibrary L {\n\t\t\tfunction ext() external { new C(); new D(); inr(); }\n\t\t\tfunction inr() internal { new C(); new D(); free(); }\n\t\t}\n\n\t\tcontract C {\n\t\t\tconstructor() { new D(); }\n\n\t\t\tfunction ext() external { new D(); inr(); }\n\t\t\tfunction inr() internal { new D(); free(); }\n\t\t}\n\n\t\tcontract D {}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"constructor of C\"},\n\t\t}},\n\t\t{\"D\", {}},\n\t\t{\"L\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.ext()\"},\n\t\t\t{\"function C.ext()\", \"function C.inr()\"},\n\t\t\t{\"function C.inr()\", \"function free()\"},\n\t\t}},\n\t\t{\"D\", {}},\n\t\t{\"L\", {\n\t\t\t{\"Entry\", \"function L.ext()\"},\n\t\t\t{\"function L.ext()\", \"function L.inr()\"},\n\t\t\t{\"function L.inr()\", \"function free()\"},\n\t\t}},\n\t};\n\n\tstd::map<std::string, std::set<std::string>> expectedCreatedContractsAtCreation = {\n\t\t{\"C\", {\"D\"}},\n\t};\n\tstd::map<std::string, std::set<std::string>> expectedCreatedContractsAfterDeployment = {\n\t\t{\"C\", {\"D\"}},\n\t\t{\"L\", {\"C\", \"D\"}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges, expectedCreatedContractsAtCreation);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges, expectedCreatedContractsAfterDeployment);\n}\n\nBOOST_AUTO_TEST_CASE(inherited_constructors)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction free() {}\n\n\t\tlibrary L {\n\t\t\tfunction ext() external { inr(); }\n\t\t\tfunction inr() internal { free(); }\n\t\t}\n\n\t\tcontract C {\n\t\t\tconstructor() { inrC(); free(); }\n\n\t\t\tfunction extC() external returns (uint) { inrC(); }\n\t\t\tfunction inrC() internal returns (uint) { free(); }\n\t\t}\n\n\t\tcontract D {\n\t\t\tconstructor() { L.ext(); }\n\t\t}\n\n\t\tcontract E is C {\n\t\t\tuint e2 = this.extE();\n\t\t\tuint i2 = inrE();\n\n\t\t\tfunction extE() external returns (uint) { inrE(); }\n\t\t\tfunction inrE() internal returns (uint) { free(); }\n\t\t}\n\n\t\tcontract F is C, D(), E {\n\t\t\tuint e3 = this.extF();\n\t\t\tuint i3 = inrF();\n\n\t\t\tconstructor() E() C() {}\n\n\t\t\tfunction extF() external returns (uint) { inrF(); }\n\t\t\tfunction inrF() internal returns (uint) { free(); }\n\t\t}\n\n\t\tcontract G is E() {\n\t\t\tfunction extG() external returns (uint) { new F(); }\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"constructor of C\"},\n\t\t\t{\"constructor of C\", \"function C.inrC()\"},\n\t\t\t{\"constructor of C\", \"function free()\"},\n\t\t\t{\"function C.inrC()\", \"function free()\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"constructor of D\"},\n\t\t}},\n\t\t{\"E\", {\n\t\t\t{\"Entry\", \"constructor of C\"},\n\t\t\t{\"Entry\", \"function E.inrE()\"},\n\t\t\t{\"constructor of C\", \"function C.inrC()\"},\n\t\t\t{\"constructor of C\", \"function free()\"},\n\t\t\t{\"function C.inrC()\", \"function free()\"},\n\t\t\t{\"function E.inrE()\", \"function free()\"},\n\t\t}},\n\t\t{\"F\", {\n\t\t\t{\"Entry\", \"constructor of C\"},\n\t\t\t{\"Entry\", \"constructor of D\"},\n\t\t\t{\"Entry\", \"constructor of F\"},\n\t\t\t{\"Entry\", \"function E.inrE()\"},\n\t\t\t{\"Entry\", \"function F.inrF()\"},\n\t\t\t{\"constructor of C\", \"function C.inrC()\"},\n\t\t\t{\"constructor of C\", \"function free()\"},\n\t\t\t{\"function C.inrC()\", \"function free()\"},\n\t\t\t{\"function E.inrE()\", \"function free()\"},\n\t\t\t{\"function F.inrF()\", \"function free()\"},\n\t\t}},\n\t\t{\"G\", {\n\t\t\t{\"Entry\", \"constructor of C\"},\n\t\t\t{\"Entry\", \"function E.inrE()\"},\n\t\t\t{\"constructor of C\", \"function C.inrC()\"},\n\t\t\t{\"constructor of C\", \"function free()\"},\n\t\t\t{\"function C.inrC()\", \"function free()\"},\n\t\t\t{\"function E.inrE()\", \"function free()\"},\n\t\t}},\n\t\t{\"L\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.extC()\"},\n\t\t\t{\"function C.extC()\", \"function C.inrC()\"},\n\t\t\t{\"function C.inrC()\", \"function free()\"},\n\t\t}},\n\t\t{\"D\", {}},\n\t\t{\"E\", {\n\t\t\t{\"Entry\", \"function C.extC()\"},\n\t\t\t{\"Entry\", \"function E.extE()\"},\n\t\t\t{\"function C.extC()\", \"function C.inrC()\"},\n\t\t\t{\"function E.extE()\", \"function E.inrE()\"},\n\t\t\t{\"function C.inrC()\", \"function free()\"},\n\t\t\t{\"function E.inrE()\", \"function free()\"},\n\t\t}},\n\t\t{\"F\", {\n\t\t\t{\"Entry\", \"function C.extC()\"},\n\t\t\t{\"Entry\", \"function E.extE()\"},\n\t\t\t{\"Entry\", \"function F.extF()\"},\n\t\t\t{\"function C.extC()\", \"function C.inrC()\"},\n\t\t\t{\"function E.extE()\", \"function E.inrE()\"},\n\t\t\t{\"function F.extF()\", \"function F.inrF()\"},\n\t\t\t{\"function C.inrC()\", \"function free()\"},\n\t\t\t{\"function E.inrE()\", \"function free()\"},\n\t\t\t{\"function F.inrF()\", \"function free()\"},\n\t\t}},\n\t\t{\"G\", {\n\t\t\t{\"Entry\", \"function C.extC()\"},\n\t\t\t{\"Entry\", \"function E.extE()\"},\n\t\t\t{\"Entry\", \"function G.extG()\"},\n\t\t\t{\"function C.extC()\", \"function C.inrC()\"},\n\t\t\t{\"function E.extE()\", \"function E.inrE()\"},\n\t\t\t{\"function C.inrC()\", \"function free()\"},\n\t\t\t{\"function E.inrE()\", \"function free()\"},\n\t\t}},\n\t\t{\"L\", {\n\t\t\t{\"Entry\", \"function L.ext()\"},\n\t\t\t{\"function L.ext()\", \"function L.inr()\"},\n\t\t\t{\"function L.inr()\", \"function free()\"},\n\t\t}},\n\t};\n\n\tstd::map<std::string, std::set<std::string>> expectedCreatedContractsAtCreation = {};\n\tstd::map<std::string, std::set<std::string>> expectedCreatedContractsAfterDeployment = {\n\t\t{\"G\", {\"F\"}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges, expectedCreatedContractsAtCreation);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges, expectedCreatedContractsAfterDeployment);\n}\n\nBOOST_AUTO_TEST_CASE(inheritance_specifiers)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction fD() returns (uint) {}\n\t\tfunction fE() returns (uint) {}\n\t\tfunction fFD() returns (uint) {}\n\t\tfunction fFE() returns (uint) {}\n\t\tfunction fG() returns (uint) {}\n\n\t\tfunction fVarC() returns (uint) {}\n\t\tfunction fVarD() returns (uint) {}\n\t\tfunction fVarE() returns (uint) {}\n\t\tfunction fVarF() returns (uint) {}\n\n\t\tcontract C {\n\t\t\tuint c = fVarC();\n\n\t\t\tconstructor (uint) {}\n\t\t}\n\n\t\tcontract D is C(fD()) {\n\t\t\tuint d = fVarD();\n\n\t\t\tconstructor (uint) {}\n\t\t}\n\n\t\tabstract contract E is C {\n\t\t\tuint e = fVarE();\n\n\t\t\tconstructor (uint) {}\n\t\t}\n\n\t\tcontract F is D(fFD()), E {\n\t\t\tuint f = fVarF();\n\n\t\t\tconstructor (uint) E(fFE()) {}\n\t\t}\n\n\t\tcontract G is D(fG()), E(fG()) {}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"constructor of C\"},\n\t\t\t{\"Entry\", \"function fVarC()\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"constructor of C\"},\n\t\t\t{\"Entry\", \"constructor of D\"},\n\t\t\t{\"Entry\", \"function fVarC()\"},\n\t\t\t{\"Entry\", \"function fVarD()\"},\n\t\t\t{\"constructor of D\", \"function fD()\"},\n\t\t}},\n\t\t{\"E\", {\n\t\t\t{\"Entry\", \"constructor of C\"},\n\t\t\t{\"Entry\", \"constructor of E\"},\n\t\t\t{\"Entry\", \"function fVarC()\"},\n\t\t\t{\"Entry\", \"function fVarE()\"},\n\t\t}},\n\t\t{\"F\", {\n\t\t\t{\"Entry\", \"constructor of C\"},\n\t\t\t{\"Entry\", \"constructor of D\"},\n\t\t\t{\"Entry\", \"constructor of E\"},\n\t\t\t{\"Entry\", \"constructor of F\"},\n\t\t\t{\"Entry\", \"function fVarC()\"},\n\t\t\t{\"Entry\", \"function fVarD()\"},\n\t\t\t{\"Entry\", \"function fVarE()\"},\n\t\t\t{\"Entry\", \"function fVarF()\"},\n\t\t\t{\"constructor of D\", \"function fD()\"},\n\t\t\t{\"constructor of F\", \"function fFD()\"},\n\t\t\t{\"constructor of F\", \"function fFE()\"},\n\t\t}},\n\t\t{\"G\", {\n\t\t\t{\"Entry\", \"constructor of C\"},\n\t\t\t{\"Entry\", \"constructor of D\"},\n\t\t\t{\"Entry\", \"constructor of E\"},\n\t\t\t// G, unlike F, has no constructor so fG() gets an edge from Entry.\n\t\t\t{\"Entry\", \"function fG()\"},\n\t\t\t{\"Entry\", \"function fVarC()\"},\n\t\t\t{\"Entry\", \"function fVarD()\"},\n\t\t\t{\"Entry\", \"function fVarE()\"},\n\t\t\t{\"constructor of D\", \"function fD()\"},\n\t\t}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t\t{\"E\", {}},\n\t\t{\"F\", {}},\n\t\t{\"G\", {}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(inherited_functions_virtual_and_super)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tcontract C {\n\t\t\tfunction f() internal {}\n\t\t\tfunction g() internal virtual {}\n\t\t\tfunction h() internal virtual {}\n\n\t\t\tfunction ext() external virtual {}\n\t\t}\n\n\t\tcontract D {\n\t\t\tfunction h() internal virtual {}\n\n\t\t\tfunction ext() external virtual {}\n\t\t}\n\n\t\tcontract E is C, D {\n\t\t\tfunction g() internal override {}\n\t\t\tfunction h() internal override(C, D) {}\n\t\t\tfunction i() internal {}\n\n\t\t\tfunction ext() external override(C, D) {}\n\n\t\t\tfunction callF() external { f(); }\n\t\t\tfunction callG() external { g(); }\n\t\t\tfunction callH() external { h(); }\n\t\t\tfunction callI() external { i(); }\n\t\t\tfunction callCF() external { C.f(); }\n\t\t\tfunction callCG() external { C.g(); }\n\t\t\tfunction callCH() external { C.h(); }\n\t\t\tfunction callDH() external { D.h(); }\n\t\t\tfunction callEI() external { E.i(); }\n\t\t\tfunction callSuperF() external { super.f(); }\n\t\t\tfunction callSuperG() external { super.g(); }\n\t\t\tfunction callSuperH() external { super.h(); }\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t\t{\"E\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.ext()\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"function D.ext()\"},\n\t\t}},\n\t\t{\"E\", {\n\t\t\t{\"Entry\", \"function E.callF()\"},\n\t\t\t{\"Entry\", \"function E.callG()\"},\n\t\t\t{\"Entry\", \"function E.callH()\"},\n\t\t\t{\"Entry\", \"function E.callI()\"},\n\t\t\t{\"Entry\", \"function E.callCF()\"},\n\t\t\t{\"Entry\", \"function E.callCG()\"},\n\t\t\t{\"Entry\", \"function E.callCH()\"},\n\t\t\t{\"Entry\", \"function E.callDH()\"},\n\t\t\t{\"Entry\", \"function E.callEI()\"},\n\t\t\t{\"Entry\", \"function E.callSuperF()\"},\n\t\t\t{\"Entry\", \"function E.callSuperG()\"},\n\t\t\t{\"Entry\", \"function E.callSuperH()\"},\n\t\t\t{\"Entry\", \"function E.ext()\"},\n\t\t\t{\"function E.callF()\", \"function C.f()\"},\n\t\t\t{\"function E.callG()\", \"function E.g()\"},\n\t\t\t{\"function E.callH()\", \"function E.h()\"},\n\t\t\t{\"function E.callI()\", \"function E.i()\"},\n\t\t\t{\"function E.callCF()\", \"function C.f()\"},\n\t\t\t{\"function E.callCG()\", \"function C.g()\"},\n\t\t\t{\"function E.callCH()\", \"function C.h()\"},\n\t\t\t{\"function E.callDH()\", \"function D.h()\"},\n\t\t\t{\"function E.callEI()\", \"function E.i()\"},\n\t\t\t{\"function E.callSuperF()\", \"function C.f()\"},\n\t\t\t{\"function E.callSuperG()\", \"function C.g()\"},\n\t\t\t{\"function E.callSuperH()\", \"function D.h()\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(overloaded_functions)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tenum E {E1, E2, E3}\n\n\t\tfunction free() {}\n\t\tfunction free(uint) {}\n\t\tfunction free(bytes memory) {}\n\t\tfunction free(E) {}\n\n\t\tcontract C {\n\t\t\tfunction f(E) internal {}\n\t\t\tfunction f(bool) external {}\n\t\t}\n\n\t\tcontract D is C {\n\t\t\tfunction ext1() external { free(); free(123); free(\"123\"); }\n\t\t\tfunction ext2() external { f(); f(123); f(\"123\"); }\n\t\t\tfunction ext3() external { free(E.E2); f(E.E2); }\n\t\t\tfunction ext4() external { this.f(false); }\n\n\t\t\tfunction f() internal {}\n\t\t\tfunction f(uint) internal {}\n\t\t\tfunction f(bytes memory) internal {}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.f(bool)\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"function C.f(bool)\"},\n\t\t\t{\"Entry\", \"function D.ext1()\"},\n\t\t\t{\"Entry\", \"function D.ext2()\"},\n\t\t\t{\"Entry\", \"function D.ext3()\"},\n\t\t\t{\"Entry\", \"function D.ext4()\"},\n\t\t\t{\"function D.ext1()\", \"function free()\"},\n\t\t\t{\"function D.ext1()\", \"function free(uint256)\"},\n\t\t\t{\"function D.ext1()\", \"function free(bytes)\"},\n\t\t\t{\"function D.ext2()\", \"function D.f()\"},\n\t\t\t{\"function D.ext2()\", \"function D.f(uint256)\"},\n\t\t\t{\"function D.ext2()\", \"function D.f(bytes)\"},\n\t\t\t{\"function D.ext3()\", \"function free(enum E)\"},\n\t\t\t{\"function D.ext3()\", \"function C.f(enum E)\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(modifiers)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tlibrary L {\n\t\t\tmodifier m() { g(); _; }\n\n\t\t\tfunction f() m internal {}\n\t\t\tfunction g() internal {}\n\t\t}\n\n\t\tcontract C {\n\t\t\tmodifier m1() virtual { _; }\n\n\t\t\tfunction q() m1 internal virtual { L.f(); }\n\t\t}\n\n\t\tcontract D is C {\n\t\t\tmodifier m2() { q(); _; new C(); }\n\n\t\t\tfunction p() m2 internal { C.q(); }\n\t\t\tfunction q() m2 internal override virtual {}\n\t\t}\n\n\t\tcontract E is D {\n\t\t\tmodifier m1() override { _; }\n\t\t\tmodifier m3() { p(); _; }\n\n\t\t\tconstructor() D() m1 E.m3 {}\n\t\t\tfunction ext() external m1 E.m3 { inr(); }\n\t\t\tfunction inr() internal m1 E.m3 { L.f(); }\n\n\t\t\tfunction q() internal override {}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t\t{\"L\", {}},\n\t\t{\"E\", {\n\t\t\t{\"Entry\", \"constructor of E\"},\n\t\t\t{\"constructor of E\", \"modifier E.m1\"},\n\t\t\t{\"constructor of E\", \"modifier E.m3\"},\n\t\t\t{\"function C.q()\", \"modifier E.m1\"},\n\t\t\t{\"function C.q()\", \"function L.f()\"},\n\t\t\t{\"function D.p()\", \"modifier D.m2\"},\n\t\t\t{\"function D.p()\", \"function C.q()\"},\n\t\t\t{\"function L.f()\", \"modifier L.m\"},\n\t\t\t{\"modifier L.m\", \"function L.g()\"},\n\t\t\t{\"modifier D.m2\", \"function E.q()\"},\n\t\t\t{\"modifier E.m3\", \"function D.p()\"},\n\t\t}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t\t{\"L\", {}},\n\t\t{\"E\", {\n\t\t\t{\"Entry\", \"function E.ext()\"},\n\t\t\t{\"function C.q()\", \"modifier E.m1\"},\n\t\t\t{\"function C.q()\", \"function L.f()\"},\n\t\t\t{\"function D.p()\", \"modifier D.m2\"},\n\t\t\t{\"function D.p()\", \"function C.q()\"},\n\t\t\t{\"function L.f()\", \"modifier L.m\"},\n\t\t\t{\"function E.ext()\", \"function E.inr()\"},\n\t\t\t{\"function E.ext()\", \"modifier E.m1\"},\n\t\t\t{\"function E.ext()\", \"modifier E.m3\"},\n\t\t\t{\"function E.inr()\", \"modifier E.m1\"},\n\t\t\t{\"function E.inr()\", \"modifier E.m3\"},\n\t\t\t{\"function E.inr()\", \"function L.f()\"},\n\t\t\t{\"modifier L.m\", \"function L.g()\"},\n\t\t\t{\"modifier D.m2\", \"function E.q()\"},\n\t\t\t{\"modifier E.m3\", \"function D.p()\"},\n\t\t}},\n\t};\n\n\tstd::map<std::string, std::set<std::string>> expectedCreatedContractsAtCreation = {{\"E\", {\"C\"}}};\n\tstd::map<std::string, std::set<std::string>> expectedCreatedContractsAfterDeployment = {{\"E\", {\"C\"}}};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges, expectedCreatedContractsAtCreation);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges, expectedCreatedContractsAfterDeployment);\n}\n\nBOOST_AUTO_TEST_CASE(events)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction free() { emit L.Ev(); }\n\n\t\tlibrary L {\n\t\t\tevent Ev();\n\t\t\tevent Ev(bytes4, string indexed);\n\n\t\t\tfunction ext() external { emit Ev(); }\n\t\t\tfunction inr() internal { emit Ev(0x12345678, \"a\"); emit L.Ev(); }\n\t\t}\n\n\t\tcontract C {\n\t\t\tevent EvC(uint) anonymous;\n\n\t\t\tmodifier m() { emit EvC(1); _; }\n\t\t}\n\n\t\tcontract D is C {\n\t\t\tevent EvD1(uint);\n\t\t\tevent EvD2(uint);\n\n\t\t\tfunction ext() m external { emit D.EvD1(1); emit EvC(f()); inr(); }\n\t\t\tfunction inr() m internal { emit EvD1(1); emit C.EvC(f()); L.inr(); free(); EvD2; }\n\n\t\t\tfunction f() internal returns (uint) {}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t\t{\"L\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"function D.ext()\"},\n\t\t\t{\"function D.ext()\", \"function D.inr()\"},\n\t\t\t{\"function D.ext()\", \"modifier C.m\"},\n\t\t\t{\"function D.ext()\", \"function D.f()\"},\n\t\t\t{\"function D.inr()\", \"function L.inr()\"},\n\t\t\t{\"function D.inr()\", \"function free()\"},\n\t\t\t{\"function D.inr()\", \"modifier C.m\"},\n\t\t\t{\"function D.inr()\", \"function D.f()\"},\n\t\t}},\n\t\t{\"L\", {\n\t\t\t{\"Entry\", \"function L.ext()\"},\n\t\t}},\n\t};\n\n\tstd::map<std::string, std::set<std::string>> expectedCreationEvents = {};\n\tstd::map<std::string, std::set<std::string>> expectedDeployedEvents = {\n\t\t{\"D\", {\n\t\t\t\"event D.EvD1(uint256)\",\n\t\t\t\"event C.EvC(uint256)\",\n\t\t\t\"event L.Ev(bytes4,string)\",\n\t\t\t\"event L.Ev()\",\n\t\t}},\n\t\t{\"L\", {\n\t\t\t\"event L.Ev()\",\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges, {}, expectedCreationEvents);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges, {}, expectedDeployedEvents);\n}\n\nBOOST_AUTO_TEST_CASE(cycles)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction free1() { free1(); }\n\t\tfunction free2() { free3(); }\n\t\tfunction free3() { free2(); }\n\n\t\tlibrary L {\n\t\t\tfunction inr1() internal { inr1(); }\n\t\t\tfunction inr2() internal { inr3(); }\n\t\t\tfunction inr3() internal { inr2(); }\n\t\t}\n\n\t\tcontract C {\n\t\t\tfunction virt() internal virtual { virt(); }\n\t\t}\n\n\t\tcontract D is C {\n\t\t\tfunction init() external { this.ext1(); inr1(); inr2(); L.inr1(); L.inr2(); free1(); free2(); virt(); }\n\n\t\t\tfunction ext1() external { this.ext1(); }\n\t\t\tfunction ext2() external { this.ext3(); }\n\t\t\tfunction ext3() external { this.ext2(); }\n\t\t\tfunction inr1() internal { inr1(); }\n\t\t\tfunction inr2() internal { inr3(); }\n\t\t\tfunction inr3() internal { inr2(); }\n\t\t\tfunction inr3(uint) internal {}\n\n\t\t\tfunction virt() internal override { C.virt(); }\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"L\", {}},\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"L\", {}},\n\t\t{\"C\", {}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"function D.init()\"},\n\t\t\t{\"Entry\", \"function D.ext1()\"},\n\t\t\t{\"Entry\", \"function D.ext2()\"},\n\t\t\t{\"Entry\", \"function D.ext3()\"},\n\t\t\t{\"function D.init()\", \"function D.inr1()\"},\n\t\t\t{\"function D.init()\", \"function D.inr2()\"},\n\t\t\t{\"function D.init()\", \"function D.virt()\"},\n\t\t\t{\"function D.init()\", \"function L.inr1()\"},\n\t\t\t{\"function D.init()\", \"function L.inr2()\"},\n\t\t\t{\"function D.init()\", \"function free1()\"},\n\t\t\t{\"function D.init()\", \"function free2()\"},\n\t\t\t{\"function D.inr1()\", \"function D.inr1()\"},\n\t\t\t{\"function D.inr2()\", \"function D.inr3()\"},\n\t\t\t{\"function D.inr3()\", \"function D.inr2()\"},\n\t\t\t{\"function D.virt()\", \"function C.virt()\"},\n\t\t\t{\"function C.virt()\", \"function D.virt()\"},\n\t\t\t{\"function L.inr1()\", \"function L.inr1()\"},\n\t\t\t{\"function L.inr2()\", \"function L.inr3()\"},\n\t\t\t{\"function L.inr3()\", \"function L.inr2()\"},\n\t\t\t{\"function free1()\", \"function free1()\"},\n\t\t\t{\"function free2()\", \"function free3()\"},\n\t\t\t{\"function free3()\", \"function free2()\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(interfaces_and_abstract_contracts)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tinterface I {\n\t\t\tevent Ev(uint);\n\n\t\t\tfunction ext1() external;\n\t\t\tfunction ext2() external;\n\t\t}\n\n\t\tinterface J is I {\n\t\t\tfunction ext2() external override;\n\t\t\tfunction ext3() external;\n\t\t}\n\n\t\tabstract contract C is J {\n\t\t\tmodifier m() virtual;\n\n\t\t\tfunction ext3() external override virtual;\n\t\t\tfunction ext4() external { inr2();}\n\t\t\tfunction inr1() internal virtual;\n\t\t\tfunction inr2() m internal { inr1(); this.ext1(); this.ext2(); this.ext3(); }\n\t\t}\n\n\t\tcontract D is C {\n\t\t\tfunction ext1() public override { emit I.Ev(1); inr1(); inr2(); }\n\t\t\tfunction ext2() external override { I(this).ext1(); }\n\t\t\tfunction ext3() external override {}\n\t\t\tfunction inr1() internal override {}\n\n\t\t\tmodifier m() override { _; }\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"I\", {}},\n\t\t{\"J\", {}},\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"I\", {\n\t\t\t{\"Entry\", \"function I.ext1()\"},\n\t\t\t{\"Entry\", \"function I.ext2()\"},\n\t\t}},\n\t\t{\"J\", {\n\t\t\t{\"Entry\", \"function I.ext1()\"},\n\t\t\t{\"Entry\", \"function J.ext2()\"},\n\t\t\t{\"Entry\", \"function J.ext3()\"},\n\t\t}},\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function I.ext1()\"},\n\t\t\t{\"Entry\", \"function J.ext2()\"},\n\t\t\t{\"Entry\", \"function C.ext3()\"},\n\t\t\t{\"Entry\", \"function C.ext4()\"},\n\t\t\t{\"function C.ext4()\", \"function C.inr2()\"},\n\t\t\t{\"function C.inr2()\", \"function C.inr1()\"},\n\t\t\t{\"function C.inr2()\", \"modifier C.m\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"function D.ext1()\"},\n\t\t\t{\"Entry\", \"function D.ext2()\"},\n\t\t\t{\"Entry\", \"function D.ext3()\"},\n\t\t\t{\"Entry\", \"function C.ext4()\"},\n\t\t\t{\"function C.ext4()\", \"function C.inr2()\"},\n\t\t\t{\"function C.inr2()\", \"function D.inr1()\"},\n\t\t\t{\"function C.inr2()\", \"modifier D.m\"},\n\t\t\t{\"function D.ext1()\", \"function D.inr1()\"},\n\t\t\t{\"function D.ext1()\", \"function C.inr2()\"},\n\t\t}},\n\t};\n\n\tstd::map<std::string, std::set<std::string>> expectedCreationEvents = {};\n\tstd::map<std::string, std::set<std::string>> expectedDeployedEvents = {\n\t\t{\"D\", {\n\t\t\t\"event I.Ev(uint256)\",\n\t\t}},\n\t};\n\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges, {}, expectedCreationEvents);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges, {}, expectedDeployedEvents);\n}\n\nBOOST_AUTO_TEST_CASE(indirect_calls)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction free1() {}\n\t\tfunction free2() {}\n\t\tfunction free3() {}\n\n\t\tlibrary L {\n\t\t\tfunction ext() external {}\n\t\t\tfunction inr1() internal {}\n\t\t\tfunction inr2() internal {}\n\t\t\tfunction inr3() internal {}\n\n\t\t\tfunction access() public {\n\t\t\t\tfree1;\n\t\t\t\tinr1;\n\t\t\t\tL.ext;\n\t\t\t}\n\n\t\t\tfunction expression() public {\n\t\t\t\t(free2)();\n\t\t\t\t(inr2)();\n\t\t\t}\n\t\t}\n\n\t\tcontract C {\n\t\t\tfunction ext1() external {}\n\t\t\tfunction ext2() external {}\n\t\t\tfunction ext3() external {}\n\t\t\tfunction inr1() internal {}\n\t\t\tfunction inr2() internal {}\n\t\t\tfunction inr3() internal {}\n\n\t\t\tfunction access() public {\n\t\t\t\tthis.ext1;\n\t\t\t\tinr1;\n\t\t\t\tfree1;\n\t\t\t\tL.inr1;\n\t\t\t\tL.ext;\n\t\t\t}\n\n\t\t\tfunction expression() public {\n\t\t\t\t(this.ext2)();\n\t\t\t\t(inr2)();\n\t\t\t\t(free2)();\n\t\t\t\t(L.inr2)();\n\t\t\t\t(L.ext)();\n\t\t\t}\n\t\t}\n\n\t\tcontract D is C {\n\t\t\tconstructor() {\n\t\t\t\taccess();\n\t\t\t\texpression();\n\t\t\t}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"L\", {}},\n\t\t{\"C\", {}},\n\t\t{\"D\", {\n\t\t\t{\"InternalDispatch\", \"function L.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function C.inr1()\"},\n\t\t\t{\"InternalDispatch\", \"function C.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function free1()\"},\n\t\t\t{\"InternalDispatch\", \"function free2()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr1()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr2()\"},\n\t\t\t{\"Entry\", \"constructor of D\"},\n\t\t\t{\"constructor of D\", \"function C.access()\"},\n\t\t\t{\"constructor of D\", \"function C.expression()\"},\n\t\t\t{\"function C.expression()\", \"InternalDispatch\"},\n\t\t}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"L\", {\n\t\t\t{\"InternalDispatch\", \"function L.inr1()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function free1()\"},\n\t\t\t{\"InternalDispatch\", \"function free2()\"},\n\t\t\t{\"Entry\", \"function L.ext()\"},\n\t\t\t{\"Entry\", \"function L.access()\"},\n\t\t\t{\"Entry\", \"function L.expression()\"},\n\t\t\t{\"function L.expression()\", \"InternalDispatch\"},\n\t\t}},\n\t\t{\"C\", {\n\t\t\t{\"InternalDispatch\", \"function C.inr1()\"},\n\t\t\t{\"InternalDispatch\", \"function C.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function free1()\"},\n\t\t\t{\"InternalDispatch\", \"function free2()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr1()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr2()\"},\n\t\t\t{\"Entry\", \"function C.ext1()\"},\n\t\t\t{\"Entry\", \"function C.ext2()\"},\n\t\t\t{\"Entry\", \"function C.ext3()\"},\n\t\t\t{\"Entry\", \"function C.access()\"},\n\t\t\t{\"Entry\", \"function C.expression()\"},\n\t\t\t{\"function C.expression()\", \"InternalDispatch\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"InternalDispatch\", \"function L.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function C.inr1()\"},\n\t\t\t{\"InternalDispatch\", \"function C.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function free1()\"},\n\t\t\t{\"InternalDispatch\", \"function free2()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr1()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr2()\"},\n\t\t\t{\"Entry\", \"function C.ext1()\"},\n\t\t\t{\"Entry\", \"function C.ext2()\"},\n\t\t\t{\"Entry\", \"function C.ext3()\"},\n\t\t\t{\"Entry\", \"function C.access()\"},\n\t\t\t{\"Entry\", \"function C.expression()\"},\n\t\t\t{\"function C.expression()\", \"InternalDispatch\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(calls_via_pointers)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction free1() {}\n\t\tfunction free2() {}\n\t\tfunction free3() {}\n\n\t\tlibrary L {\n\t\t\tfunction inr1() internal {}\n\t\t\tfunction inr2() internal {}\n\t\t\tfunction inr3() internal {}\n\n\t\t\tfunction callPtrs(\n\t\t\t\tfunction () external e,\n\t\t\t\tfunction () internal i,\n\t\t\t\tfunction () internal f,\n\t\t\t\tfunction () internal l\n\t\t\t) internal\n\t\t\t{\n\t\t\t\te();\n\t\t\t\ti();\n\t\t\t\tf();\n\t\t\t\tl();\n\t\t\t}\n\t\t}\n\n\t\tcontract C {\n\t\t\tfunction ext1() external {}\n\t\t\tfunction ext2() external {}\n\t\t\tfunction ext3() external {}\n\t\t\tfunction inr1() internal {}\n\t\t\tfunction inr2() internal {}\n\t\t\tfunction inr3() internal {}\n\n\t\t\tfunction getPtrs2() internal returns (\n\t\t\t\tfunction () external,\n\t\t\t\tfunction () internal,\n\t\t\t\tfunction () internal,\n\t\t\t\tfunction () internal\n\t\t\t)\n\t\t\t{\n\t\t\t\treturn (this.ext2, inr2, free2, L.inr2);\n\t\t\t}\n\n\t\t\tfunction testLocalVars() public {\n\t\t\t\t(function () external e, function () i, function () f, function () l) = getPtrs2();\n\t\t\t\tL.callPtrs(e, i, f, l);\n\t\t\t}\n\t\t}\n\n\t\tcontract D is C {\n\t\t\tfunction () external m_e = this.ext1;\n\t\t\tfunction () internal m_i = inr1;\n\t\t\tfunction () internal m_f = free1;\n\t\t\tfunction () internal m_l = L.inr1;\n\t\t\tfunction () internal immutable m_imm = inr1;\n\n\t\t\tfunction callStatePtrs() internal {\n\t\t\t\tm_e();\n\t\t\t\tm_i();\n\t\t\t\tm_f();\n\t\t\t\tm_l();\n\t\t\t}\n\n\t\t\tfunction updateStatePtrs(\n\t\t\t\tfunction () external e,\n\t\t\t\tfunction () internal i,\n\t\t\t\tfunction () internal f,\n\t\t\t\tfunction () internal l\n\t\t\t) internal\n\t\t\t{\n\t\t\t\tm_e = e;\n\t\t\t\tm_i = i;\n\t\t\t\tm_f = f;\n\t\t\t\tm_l = l;\n\t\t\t}\n\n\t\t\tfunction testStateVars() public {\n\t\t\t\t(function () external e, function () i, function () f, function () l) = getPtrs2();\n\t\t\t\tupdateStatePtrs(e, i, f, l);\n\t\t\t\tcallStatePtrs();\n\t\t\t}\n\n\t\t\tfunction testImmutablePtr() public {\n\t\t\t\tm_imm();\n\t\t\t}\n\n\t\t\tconstructor() {\n\t\t\t\ttestStateVars();\n\t\t\t\ttestLocalVars();\n\t\t\t}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"L\", {}},\n\t\t{\"C\", {}},\n\t\t{\"D\", {\n\t\t\t{\"InternalDispatch\", \"function C.inr1()\"},\n\t\t\t{\"InternalDispatch\", \"function C.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr1()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function free1()\"},\n\t\t\t{\"InternalDispatch\", \"function free2()\"},\n\t\t\t{\"Entry\", \"constructor of D\"},\n\t\t\t{\"constructor of D\", \"function C.testLocalVars()\"},\n\t\t\t{\"constructor of D\", \"function D.testStateVars()\"},\n\t\t\t{\"function C.testLocalVars()\", \"function C.getPtrs2()\"},\n\t\t\t{\"function C.testLocalVars()\", \"function L.callPtrs(function () external,function (),function (),function ())\"},\n\t\t\t{\"function D.testStateVars()\", \"function C.getPtrs2()\"},\n\t\t\t{\"function D.testStateVars()\", \"function D.updateStatePtrs(function () external,function (),function (),function ())\"},\n\t\t\t{\"function D.testStateVars()\", \"function D.callStatePtrs()\"},\n\t\t\t{\"function D.callStatePtrs()\", \"InternalDispatch\"},\n\t\t\t{\"function L.callPtrs(function () external,function (),function (),function ())\", \"InternalDispatch\"},\n\t\t}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"L\", {}},\n\t\t{\"C\", {\n\t\t\t{\"InternalDispatch\", \"function C.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function free2()\"},\n\t\t\t{\"Entry\", \"function C.ext1()\"},\n\t\t\t{\"Entry\", \"function C.ext2()\"},\n\t\t\t{\"Entry\", \"function C.ext3()\"},\n\t\t\t{\"Entry\", \"function C.testLocalVars()\"},\n\t\t\t{\"function C.testLocalVars()\", \"function C.getPtrs2()\"},\n\t\t\t{\"function C.testLocalVars()\", \"function L.callPtrs(function () external,function (),function (),function ())\"},\n\t\t\t{\"function L.callPtrs(function () external,function (),function (),function ())\", \"InternalDispatch\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"InternalDispatch\", \"function C.inr1()\"},\n\t\t\t{\"InternalDispatch\", \"function C.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr1()\"},\n\t\t\t{\"InternalDispatch\", \"function L.inr2()\"},\n\t\t\t{\"InternalDispatch\", \"function free1()\"},\n\t\t\t{\"InternalDispatch\", \"function free2()\"},\n\t\t\t{\"Entry\", \"function C.ext1()\"},\n\t\t\t{\"Entry\", \"function C.ext2()\"},\n\t\t\t{\"Entry\", \"function C.ext3()\"},\n\t\t\t{\"Entry\", \"function C.testLocalVars()\"},\n\t\t\t{\"Entry\", \"function D.testStateVars()\"},\n\t\t\t{\"Entry\", \"function D.testImmutablePtr()\"},\n\t\t\t{\"function C.testLocalVars()\", \"function C.getPtrs2()\"},\n\t\t\t{\"function C.testLocalVars()\", \"function L.callPtrs(function () external,function (),function (),function ())\"},\n\t\t\t{\"function D.testStateVars()\", \"function C.getPtrs2()\"},\n\t\t\t{\"function D.testStateVars()\", \"function D.updateStatePtrs(function () external,function (),function (),function ())\"},\n\t\t\t{\"function D.testStateVars()\", \"function D.callStatePtrs()\"},\n\t\t\t{\"function D.testImmutablePtr()\", \"InternalDispatch\"},\n\t\t\t{\"function D.callStatePtrs()\", \"InternalDispatch\"},\n\t\t\t{\"function L.callPtrs(function () external,function (),function (),function ())\", \"InternalDispatch\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(pointer_to_overridden_function)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tcontract C {\n\t\t\tfunction f() internal virtual {}\n\t\t}\n\n\t\tcontract D is C {\n\t\t\tfunction f() internal override {}\n\n\t\t\tfunction getF() internal returns (function ()) {\n\t\t\t\treturn C.f;\n\t\t\t}\n\n\t\t\tfunction getSuperF() internal returns (function ()) {\n\t\t\t\treturn super.f;\n\t\t\t}\n\n\t\t\tfunction test1() public {\n\t\t\t\tgetF()();\n\t\t\t}\n\n\t\t\tfunction test2() public {\n\t\t\t\tgetSuperF()();\n\t\t\t}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {}},\n\t\t{\"D\", {\n\t\t\t{\"InternalDispatch\", \"function C.f()\"},\n\t\t\t{\"Entry\", \"function D.test1()\"},\n\t\t\t{\"Entry\", \"function D.test2()\"},\n\t\t\t{\"function D.test1()\", \"function D.getF()\"},\n\t\t\t{\"function D.test1()\", \"InternalDispatch\"},\n\t\t\t{\"function D.test2()\", \"function D.getSuperF()\"},\n\t\t\t{\"function D.test2()\", \"InternalDispatch\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(pointer_to_nonexistent_function)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tinterface I {\n\t\t\tfunction f() external;\n\t\t}\n\n\t\tabstract contract C is I {\n\t\t\tfunction g() internal virtual;\n\n\t\t\tfunction getF() internal returns (function () external) { return this.f; }\n\t\t\tfunction getG() internal returns (function () internal) { return g; }\n\n\t\t\tfunction testInterface() public {\n\t\t\t\tgetF()();\n\t\t\t\tgetG()();\n\t\t\t}\n\n\t\t\tfunction testBadPtr() public {\n\t\t\t\tfunction () ptr;\n\t\t\t\tptr();\n\t\t\t}\n\t\t}\n\n\t\tcontract D is C {\n\t\t\tfunction f() public override {}\n\t\t\tfunction g() internal override {}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"I\", {}},\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"I\", {\n\t\t\t{\"Entry\", \"function I.f()\"},\n\t\t\t  }},\n\t\t{\"C\", {\n\t\t\t{\"InternalDispatch\", \"function C.g()\"},\n\t\t\t{\"Entry\", \"function C.testInterface()\"},\n\t\t\t{\"Entry\", \"function C.testBadPtr()\"},\n\t\t\t{\"Entry\", \"function I.f()\"},\n\t\t\t{\"function C.testInterface()\", \"function C.getF()\"},\n\t\t\t{\"function C.testInterface()\", \"function C.getG()\"},\n\t\t\t{\"function C.testInterface()\", \"InternalDispatch\"},\n\t\t\t{\"function C.testBadPtr()\", \"InternalDispatch\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"InternalDispatch\", \"function D.g()\"},\n\t\t\t{\"Entry\", \"function C.testInterface()\"},\n\t\t\t{\"Entry\", \"function C.testBadPtr()\"},\n\t\t\t{\"Entry\", \"function D.f()\"},\n\t\t\t{\"function C.testInterface()\", \"function C.getF()\"},\n\t\t\t{\"function C.testInterface()\", \"function C.getG()\"},\n\t\t\t{\"function C.testInterface()\", \"InternalDispatch\"},\n\t\t\t{\"function C.testBadPtr()\", \"InternalDispatch\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(function_self_reference)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tcontract C {\n\t\t\tfunction f() public returns (bool ret) {\n\t\t\t\treturn f == f;\n\t\t\t}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.f()\"},\n\t\t\t{\"InternalDispatch\", \"function C.f()\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(pointer_cycle)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tcontract C {\n\t\t\tfunction () ptr = f;\n\n\t\t\tfunction f() internal { ptr(); }\n\n\t\t\tfunction test() public {\n\t\t\t\tptr();\n\t\t\t}\n\t\t}\n\t)\"s);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {\n\t\t\t{\"InternalDispatch\", \"function C.f()\"},\n\t\t\t{\"function C.f()\", \"InternalDispatch\"},\n\t\t}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"InternalDispatch\", \"function C.f()\"},\n\t\t\t{\"Entry\", \"function C.test()\"},\n\t\t\t{\"function C.test()\", \"InternalDispatch\"},\n\t\t\t{\"function C.f()\", \"InternalDispatch\"},\n\t\t}},\n\t};\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(using_for)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tstruct S {\n\t\t\tuint x;\n\t\t}\n\n\t\tlibrary L {\n\t\t\tfunction ext(S memory _s) external {}\n\t\t\tfunction inr(S memory _s) internal {}\n\t\t}\n\n\t\tcontract C {\n\t\t\tusing L for S;\n\n\t\t\tfunction pub() public {\n\t\t\t\tS memory s = S(42);\n\n\t\t\t\ts.ext();\n\t\t\t\ts.inr();\n\t\t\t}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"L\", {}},\n\t\t{\"C\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"L\", {\n\t\t\t{\"Entry\", \"function L.ext(struct S)\"},\n\t\t}},\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.pub()\"},\n\t\t\t{\"function C.pub()\", \"function L.inr(struct S)\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(user_defined_binary_operator)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\ttype Int is int128;\n\t\tusing {add as +} for Int global;\n\n\t\tfunction add(Int, Int) pure returns (Int) {\n\t\t\treturn Int.wrap(0);\n\t\t}\n\n\t\tcontract C {\n\t\t\tfunction pub() public {\n\t\t\t\tInt.wrap(0) + Int.wrap(1);\n\t\t\t}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.pub()\"},\n\t\t\t{\"function C.pub()\", \"function add(Int,Int)\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(user_defined_unary_operator)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\ttype Int is int128;\n\t\tusing {sub as -} for Int global;\n\n\t\tfunction sub(Int) pure returns (Int) {\n\t\t\treturn Int.wrap(0);\n\t\t}\n\n\t\tcontract C {\n\t\t\tfunction pub() public {\n\t\t\t\t-Int.wrap(1);\n\t\t\t}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.pub()\"},\n\t\t\t{\"function C.pub()\", \"function sub(Int)\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(getters)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tcontract C {\n\t\t\tuint public variable;\n\t\t\tuint[][] public array;\n\t\t\tmapping(bytes => bytes) public map;\n\n\t\t\tfunction test() public {\n\t\t\t\tthis.variable();\n\t\t\t\tthis.array(1, 2);\n\t\t\t\tthis.map(\"value\");\n\t\t\t}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {{\"Entry\", \"function C.test()\"}}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(fallback_and_receive)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tcontract C {\n\t\t\tfunction ext() external {}\n\t\t\tfunction inr() internal {}\n\n\t\t\tfallback() external {\n\t\t\t\tthis.ext();\n\t\t\t\tinr();\n\t\t\t}\n\n\t\t\treceive() external payable {\n\t\t\t\tthis.ext();\n\t\t\t\tinr();\n\t\t\t}\n\t\t}\n\n\t\tcontract D {\n\t\t\tfallback(bytes calldata) external returns (bytes memory) {}\n\n\t\t\tfunction test() public {\n\t\t\t\t(bool success, bytes memory result) = address(this).call(\"abc\");\n\t\t\t}\n\t\t}\n\n\t\tcontract E is C {}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t\t{\"E\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.ext()\"},\n\t\t\t{\"Entry\", \"receive of C\"},\n\t\t\t{\"Entry\", \"fallback of C\"},\n\t\t\t{\"fallback of C\", \"function C.inr()\"},\n\t\t\t{\"receive of C\", \"function C.inr()\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"function D.test()\"},\n\t\t\t{\"Entry\", \"fallback of D\"},\n\t\t}},\n\t\t{\"E\", {\n\t\t\t{\"Entry\", \"function C.ext()\"},\n\t\t\t{\"Entry\", \"fallback of C\"},\n\t\t\t{\"Entry\", \"receive of C\"},\n\t\t\t{\"fallback of C\", \"function C.inr()\"},\n\t\t\t{\"receive of C\", \"function C.inr()\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(virtual_fallback_and_receive)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tcontract C {\n\t\t\tfallback() external virtual {}\n\t\t\treceive() external payable virtual {}\n\t\t}\n\n\t\tcontract D is C {}\n\n\t\tcontract E is D {\n\t\t\tfallback() external virtual override {}\n\t\t\treceive() external payable virtual override {}\n\t\t}\n\n\t\tcontract F is E {\n\t\t\tfallback() external override {}\n\t\t\treceive() external payable override {}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"C\", {}},\n\t\t{\"D\", {}},\n\t\t{\"E\", {}},\n\t\t{\"F\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"receive of C\"},\n\t\t\t{\"Entry\", \"fallback of C\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"receive of C\"},\n\t\t\t{\"Entry\", \"fallback of C\"},\n\t\t}},\n\t\t{\"E\", {\n\t\t\t{\"Entry\", \"receive of E\"},\n\t\t\t{\"Entry\", \"fallback of E\"},\n\t\t}},\n\t\t{\"F\", {\n\t\t\t{\"Entry\", \"receive of F\"},\n\t\t\t{\"Entry\", \"fallback of F\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(builtins)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tinterface I {}\n\n\t\tcontract C {\n\t\t\tfunction accessBuiltin() public payable {\n\t\t\t\tabi.decode;\n\t\t\t\tabi.encode;\n\t\t\t\tabi.encodePacked;\n\t\t\t\tabi.encodeWithSelector;\n\t\t\t\tabi.encodeWithSignature;\n\t\t\t\tblock.basefee;\n\t\t\t\tblock.chainid;\n\t\t\t\tblock.coinbase;\n\t\t\t\tblock.difficulty;\n\t\t\t\tblock.prevrandao;\n\t\t\t\tblock.gaslimit;\n\t\t\t\tblock.number;\n\t\t\t\tblock.timestamp;\n\t\t\t\tgasleft;\n\t\t\t\tmsg.data;\n\t\t\t\tmsg.sender;\n\t\t\t\tmsg.value;\n\t\t\t\ttx.gasprice;\n\t\t\t\ttx.origin;\n\t\t\t\tblockhash;\n\t\t\t\tkeccak256;\n\t\t\t\tsha256;\n\t\t\t\tripemd160;\n\t\t\t\tecrecover;\n\t\t\t\taddmod;\n\t\t\t\tmulmod;\n\t\t\t\tthis;\n\t\t\t\tsuper;\n\t\t\t\tselfdestruct;\n\t\t\t\taddress(0).balance;\n\t\t\t\taddress(0).code;\n\t\t\t\taddress(0).codehash;\n\t\t\t\tpayable(0).send;\n\t\t\t\tpayable(0).transfer;\n\t\t\t\taddress(0).call;\n\t\t\t\taddress(0).delegatecall;\n\t\t\t\taddress(0).staticcall;\n\t\t\t\ttype(C).name;\n\t\t\t\ttype(I).interfaceId;\n\t\t\t\ttype(uint).min;\n\t\t\t\ttype(uint).max;\n\t\t\t\tassert;\n\t\t\t}\n\n\t\t\tfunction callBuiltin() public payable {\n\t\t\t\tbytes memory data;\n\n\t\t\t\tabi.decode(data, (uint));\n\t\t\t\tabi.encode(0);\n\t\t\t\tabi.encodePacked(data);\n\t\t\t\tabi.encodeWithSelector(0x12345678);\n\t\t\t\tabi.encodeWithSignature(\"abc\");\n\t\t\t\tgasleft();\n\t\t\t\tblockhash(0);\n\t\t\t\tkeccak256(data);\n\t\t\t\tsha256(data);\n\t\t\t\tripemd160(data);\n\t\t\t\tecrecover(0x0, 0, 0, 0);\n\t\t\t\taddmod(1, 2, 3);\n\t\t\t\tmulmod(1, 2, 3);\n\t\t\t\tselfdestruct(payable(0));\n\t\t\t\tpayable(0).send(0);\n\t\t\t\tpayable(0).transfer(0);\n\t\t\t\taddress(0).call(data);\n\t\t\t\taddress(0).delegatecall(data);\n\t\t\t\taddress(0).staticcall(data);\n\t\t\t\tassert(true);\n\t\t\t\trequire(true);\n\t\t\t\trevert();\n\t\t\t}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"I\", {}},\n\t\t{\"C\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"I\", {}},\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.accessBuiltin()\"},\n\t\t\t{\"Entry\", \"function C.callBuiltin()\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(conversions_and_struct_array_constructors)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tinterface I {}\n\n\t\tenum E {A, B, C}\n\n\t\tstruct S {\n\t\t\tuint a;\n\t\t\tE b;\n\t\t}\n\n\t\tcontract C is I {\n\t\t\tuint[] u;\n\n\t\t\tfunction convert() public payable {\n\t\t\t\tuint(0);\n\t\t\t\tint(0);\n\t\t\t\tbool(true);\n\t\t\t\tbytes16(0);\n\t\t\t\tpayable(address(0));\n\t\t\t\tE(0);\n\t\t\t\tC(address(C(address(0))));\n\t\t\t\tI(C(address(0)));\n\n\t\t\t\tbytes memory b;\n\t\t\t\tstring(b);\n\t\t\t\tbytes(b);\n\t\t\t}\n\n\t\t\tfunction create() public payable {\n\t\t\t\tS(1, E.A);\n\n\t\t\t\tuint[3] memory u3;\n\t\t\t\tuint[3](u3);\n\t\t\t\tuint[](new uint[](3));\n\t\t\t}\n\n\t\t\tfunction pushPop() public payable {\n\t\t\t\tu.push();\n\t\t\t\tu.push(1);\n\t\t\t\tu.pop();\n\t\t\t}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"I\", {}},\n\t\t{\"C\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"I\", {}},\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function C.convert()\"},\n\t\t\t{\"Entry\", \"function C.create()\"},\n\t\t\t{\"Entry\", \"function C.pushPop()\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(immutable_initialization)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction free() pure returns (uint) { return 42; }\n\n\t\tcontract Base {\n\t\t\tfunction ext() external pure returns (uint) { free(); }\n\t\t\tfunction inr() internal pure returns (uint) { free(); }\n\t\t}\n\n\t\tcontract C is Base {\n\t\t\tuint immutable extImmutable = this.ext();\n\t\t\tuint immutable inrImmutable = inr();\n\t\t}\n\n\t\tcontract D is Base {\n\t\t\tuint immutable extImmutable;\n\t\t\tuint immutable inrImmutable;\n\n\t\t\tconstructor () {\n\t\t\t\textImmutable = this.ext();\n\t\t\t\tinrImmutable = inr();\n\t\t\t}\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"Base\", {}},\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function Base.inr()\"},\n\t\t\t{\"function Base.inr()\", \"function free()\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"constructor of D\"},\n\t\t\t{\"constructor of D\", \"function Base.inr()\"},\n\t\t\t{\"function Base.inr()\", \"function free()\"},\n\t\t}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"Base\", {\n\t\t\t{\"Entry\", \"function Base.ext()\"},\n\t\t\t{\"function Base.ext()\", \"function free()\"},\n\t\t}},\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function Base.ext()\"},\n\t\t\t{\"function Base.ext()\", \"function free()\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"Entry\", \"function Base.ext()\"},\n\t\t\t{\"function Base.ext()\", \"function free()\"},\n\t\t}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_CASE(function_selector_access)\n{\n\tstd::unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R\"(\n\t\tfunction free() pure {}\n\n\t\tbytes4 constant extFreeConst = Base.ext.selector;\n\t\tbytes4 constant pubFreeConst = Base.pub.selector;\n\n\t\tcontract Base {\n\t\t\tfunction ext() external pure { free(); extFreeConst; }\n\t\t\tfunction pub() public pure { free(); pubFreeConst; }\n\t\t}\n\n\t\tcontract C is Base {\n\t\t\tbytes4 constant extConst = Base.ext.selector;\n\t\t\tbytes4 constant pubConst = Base.pub.selector;\n\t\t}\n\n\t\tcontract D is Base {\n\t\t\tbytes4 immutable extImmutable = Base.ext.selector;\n\t\t\tbytes4 immutable pubImmutable = Base.pub.selector;\n\t\t}\n\n\t\tcontract E is Base {\n\t\t\tbytes4 extVar = Base.ext.selector;\n\t\t\tbytes4 pubVar = Base.pub.selector;\n\t\t}\n\n\t\tcontract F is Base {\n\t\t\tfunction f() public pure returns (bytes4, bytes4) {\n\t\t\t\treturn (Base.ext.selector, Base.pub.selector);\n\t\t\t}\n\t\t}\n\n\t\tlibrary L {\n\t\t\tbytes4 constant extConst = Base.ext.selector;\n\t\t\tbytes4 constant pubConst = Base.pub.selector;\n\t\t}\n\t)\"s);\n\tstd::tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);\n\n\tstd::map<std::string, EdgeNames> expectedCreationEdges = {\n\t\t{\"Base\", {}},\n\t\t{\"C\", {}},\n\t\t{\"D\", {\n\t\t\t{\"InternalDispatch\", \"function Base.pub()\"},\n\t\t\t{\"function Base.pub()\", \"function free()\"},\n\t\t}},\n\t\t{\"E\", {\n\t\t\t{\"InternalDispatch\", \"function Base.pub()\"},\n\t\t\t{\"function Base.pub()\", \"function free()\"},\n\t\t}},\n\t\t{\"F\", {}},\n\t\t{\"L\", {}},\n\t};\n\n\tstd::map<std::string, EdgeNames> expectedDeployedEdges = {\n\t\t{\"Base\", {\n\t\t\t{\"Entry\", \"function Base.ext()\"},\n\t\t\t{\"Entry\", \"function Base.pub()\"},\n\t\t\t{\"function Base.ext()\", \"function free()\"},\n\t\t\t{\"function Base.pub()\", \"function free()\"},\n\t\t}},\n\t\t{\"C\", {\n\t\t\t{\"Entry\", \"function Base.ext()\"},\n\t\t\t{\"Entry\", \"function Base.pub()\"},\n\t\t\t{\"function Base.ext()\", \"function free()\"},\n\t\t\t{\"function Base.pub()\", \"function free()\"},\n\t\t}},\n\t\t{\"D\", {\n\t\t\t{\"InternalDispatch\", \"function Base.pub()\"},\n\t\t\t{\"Entry\", \"function Base.ext()\"},\n\t\t\t{\"Entry\", \"function Base.pub()\"},\n\t\t\t{\"function Base.ext()\", \"function free()\"},\n\t\t\t{\"function Base.pub()\", \"function free()\"},\n\t\t}},\n\t\t{\"E\", {\n\t\t\t{\"InternalDispatch\", \"function Base.pub()\"},\n\t\t\t{\"Entry\", \"function Base.ext()\"},\n\t\t\t{\"Entry\", \"function Base.pub()\"},\n\t\t\t{\"function Base.ext()\", \"function free()\"},\n\t\t\t{\"function Base.pub()\", \"function free()\"},\n\t\t}},\n\t\t{\"F\", {\n\t\t\t{\"InternalDispatch\", \"function Base.pub()\"},\n\t\t\t{\"Entry\", \"function Base.ext()\"},\n\t\t\t{\"Entry\", \"function Base.pub()\"},\n\t\t\t{\"Entry\", \"function F.f()\"},\n\t\t\t{\"function Base.ext()\", \"function free()\"},\n\t\t\t{\"function Base.pub()\", \"function free()\"},\n\t\t}},\n\t\t{\"L\", {}},\n\t};\n\n\tcheckCallGraphExpectations(std::get<0>(graphs), expectedCreationEdges);\n\tcheckCallGraphExpectations(std::get<1>(graphs), expectedDeployedEdges);\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // namespace solidity::frontend::test\n"
  },
  {
    "path": "test/libsolidity/astPropertyTests/blank_test_case.sol",
    "content": "/// TestCase1: name\ncontract C {\n    ///\n    ///\n    function f() public pure { }\n}\n// ----\n// TestCase1: C\n//\n"
  },
  {
    "path": "test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop_negative_cases.sol",
    "content": "type UINT is uint;\n\nfunction add(UINT x, UINT y) pure returns (UINT) {\n    return UINT.wrap(UINT.unwrap(x) + UINT.unwrap(y));\n}\n\nfunction lt(UINT x, UINT y) pure returns (bool) {\n    return UINT.unwrap(x) < UINT.unwrap(y);\n}\n\nusing {lt as <, add as +} for UINT global;\n\nfunction g() pure returns (bool) {\n    return false;\n}\n\nfunction h() pure returns (uint) {\n    return 13;\n}\n\ncontract C {\n    uint z = 0;\n    uint transient t;\n\n    function modifyStateVarZ() public returns (uint) {\n        z = type(uint).max;\n        return z;\n    }\n\n    struct S {\n        uint x;\n    }\n\n    function f() public {\n        /// AdditionLoopExpression: isSimpleCounterLoop\n        for(uint i = 0; i < 42; i = i + 1) {\n        }\n        /// ShortHandAdditionLoopExpression: isSimpleCounterLoop\n        for(uint i = 0; i < 42; i += 1) {\n        }\n        /// SimplePreDecrement: isSimpleCounterLoop\n        for(uint i = 42; i > 0; --i) {\n        }\n        /// SimplePosDecrement: isSimpleCounterLoop\n        for(uint i = 42; i > 0; i--) {\n        }\n        /// MultiplicationLoopExpression: isSimpleCounterLoop\n        for(uint i = 1; i < 42; i = i * 2) {\n        }\n        /// CounterIncrementLoopBody: isSimpleCounterLoop\n        for(uint i = 0; i < 42; ++i) {\n            i++;\n        }\n        /// CounterAssignmentLoopBody: isSimpleCounterLoop\n        for(uint i = 0; i < 42; ++i) {\n            i = 43;\n        }\n        /// CounterAssignmentInlineAssemblyLoopBody: isSimpleCounterLoop\n        for(uint i = 0; i < 42; ++i) {\n            assembly {\n                i := add(i, 1)\n            }\n        }\n        uint j = type(uint).max;\n        /// ExternalCounterLoopExpression: isSimpleCounterLoop\n        for (uint i = 0; i < 10; ++j) {\n        }\n        uint x;\n        /// CounterIncrementRHSAssignment: isSimpleCounterLoop\n        for(uint i = 0; i < 10; ++i) {\n            x = i++;\n        }\n        /// NoEffectLoopExpression: isSimpleCounterLoop\n        for(uint i = 0; i < 42; i) {\n        }\n        /// EmptyLoopExpression: isSimpleCounterLoop\n        for(uint i = 0; i < 10; ) {\n        }\n        j = 0;\n        /// EmptyConditionExpression: isSimpleCounterLoop\n        for(uint i = 0; ; ++i) {\n        }\n        uint y = type(uint8).max + 1;\n        /// DifferentCommonTypeCondition: isSimpleCounterLoop\n        for(uint8 i = 0; i < y; ++i) {\n        }\n        /// LessThanOrEqualCondition: isSimpleCounterLoop\n        for(uint i = 0; i <= 10; ++i) {\n        }\n        /// ComplexExpressionCondition: isSimpleCounterLoop\n        for(uint i = 0; (i < 10 || g()); ++i) {\n        }\n        /// FreeFunctionConditionLHS: isSimpleCounterLoop\n        for(uint i = 0; h() < 100; ++i) {\n        }\n        /// FreeFunctionConditionDifferentCommonTypeLHS: isSimpleCounterLoop\n        for(uint8 i = 0; i < h(); ++i) {\n        }\n        /// NonIntegerTypeCondition: isSimpleCounterLoop\n        for(uint i = 0; address(this) < msg.sender; ++i) {\n        }\n        UINT ZERO = UINT.wrap(0);\n        UINT ONE = UINT.wrap(1);\n        UINT TEN = UINT.wrap(10);\n        /// UDVTOperators: isSimpleCounterLoop\n        for(UINT i = ZERO; i < TEN; i = i + ONE) {\n        }\n        /// CounterAssignmentConditionRHS: isSimpleCounterLoop\n        for(uint i = 0; i < (i = i + 1); ++i) {\n        }\n        /// LiteralDifferentCommonTypeConditionRHS: isSimpleCounterLoop\n        for(uint8 i = 0; i < 257 ; ++i) {\n        }\n        /// StateVarCounterModifiedFunctionConditionRHS: isSimpleCounterLoop\n        for (z = 1; z < modifyStateVarZ(); ++z) {\n        }\n        /// StateVarCounterModifiedFunctionLoopBody: isSimpleCounterLoop\n        for (z = 1; z < 2048; ++z) {\n            modifyStateVarZ();\n        }\n        /// StorageStateVarCounter: isSimpleCounterLoop\n        for (z = 1; z < 2048; ++z) {\n        }\n        /// TransientStateVarCounter: isSimpleCounterLoop\n        for (t = 1; t < 2048; ++t) {\n        }\n        /// NonIntegerCounter: isSimpleCounterLoop\n        for (address i = address(0x123); i < address(this); i = address(0x123 + 1)) {\n        }\n        /// AssemblyAfterAssignmentToCounter: isSimpleCounterLoop\n        for (uint i = 0; i < 42; ++i) {\n            i = type(uint).max;\n            assembly {}\n        }\n        uint k = type(uint).max;\n        /// ExpressionIncrement: isSimpleCounterLoop\n        for (uint i = 0; i < 10; ++(k)) {\n        }\n        S memory s = S(type(uint).max);\n        /// StructMemberAccessIncrement: isSimpleCounterLoop\n        for (uint i = 0; i < 10; ++s.x) {\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// AdditionLoopExpression: false\n// ShortHandAdditionLoopExpression: false\n// SimplePreDecrement: false\n// SimplePosDecrement: false\n// MultiplicationLoopExpression: false\n// CounterIncrementLoopBody: false\n// CounterAssignmentLoopBody: false\n// CounterAssignmentInlineAssemblyLoopBody: false\n// ExternalCounterLoopExpression: false\n// CounterIncrementRHSAssignment: false\n// NoEffectLoopExpression: false\n// DifferentCommonTypeCondition: false\n// EmptyLoopExpression: false\n// EmptyConditionExpression: false\n// LessThanOrEqualCondition: false\n// ComplexExpressionCondition: false\n// FreeFunctionConditionLHS: false\n// FreeFunctionConditionDifferentCommonTypeLHS: false\n// NonIntegerTypeCondition: false\n// UDVTOperators: false\n// CounterAssignmentConditionRHS: false\n// LiteralDifferentCommonTypeConditionRHS: false\n// StateVarCounterModifiedFunctionConditionRHS: false\n// StateVarCounterModifiedFunctionLoopBody: false\n// StorageStateVarCounter: false\n// TransientStateVarCounter: false\n// NonIntegerCounter: false\n// AssemblyAfterAssignmentToCounter: false\n// ExpressionIncrement: false\n// StructMemberAccessIncrement: false\n"
  },
  {
    "path": "test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop_positive_cases.sol",
    "content": "function h() pure returns (uint) {\n    return 13;\n}\n\ncontract C {\n    uint[] dynArray;\n\n    function f() public {\n        /// SimplePreIncrement: isSimpleCounterLoop\n        for(uint i = 0; i < 42; ++i) {\n        }\n        /// SimplePosIncrement: isSimpleCounterLoop\n        for(int i = 0; i < 42; i++) {\n        }\n        uint x;\n        /// CounterReadLoopBody: isSimpleCounterLoop\n        for(uint i = 0; i < 42; i++) {\n            x = i;\n        }\n        /// LocalVarConditionRHS: isSimpleCounterLoop\n        for(uint i = 0; i < x; i++) {\n        }\n        x = 0;\n        /// EmptyInitExpression: isSimpleCounterLoop\n        for(; x < 10; ++x) {\n        }\n        uint[8] memory array;\n        /// StaticArrayLengthConditionRHS: isSimpleCounterLoop\n        for(uint i = 0; i < array.length; i++) {\n        }\n        dynArray.push();\n        /// DynamicArrayLengthConditionRHS: isSimpleCounterLoop\n        for(uint i = 0; i < dynArray.length; i++) {\n            dynArray.push(i);\n        }\n        /// CounterReadInlineAssembly: isSimpleCounterLoop\n        for(uint i = 0; i < 42; ++i) {\n            assembly {\n                x := i\n            }\n        }\n        /// BinaryOperationConditionRHS: isSimpleCounterLoop\n        for(uint i = 0; i < i + 1; i++) {\n        }\n        /// FreeFunctionConditionRHS: isSimpleCounterLoop\n        for(uint i = 0; i < h(); ++i) {\n        }\n    }\n    function functionParamLoopCounter(uint i) public pure {\n        /// FunctionParameterLoopCounter: isSimpleCounterLoop\n        for (i = 0; i < 42; ++i){\n        }\n    }\n    function functionReturnLoopCounter() public pure returns (uint i) {\n        /// FunctionReturnLoopCounter: isSimpleCounterLoop\n        for (i = 0; i < 42; ++i){\n        }\n    }\n}\n// ----\n// SimplePreIncrement: true\n// SimplePosIncrement: true\n// CounterReadLoopBody: true\n// LocalVarConditionRHS: true\n// EmptyInitExpression: true\n// StaticArrayLengthConditionRHS: true\n// DynamicArrayLengthConditionRHS: true\n// CounterReadInlineAssembly: true\n// BinaryOperationConditionRHS: true\n// FreeFunctionConditionRHS: true\n// FunctionParameterLoopCounter: true\n// FunctionReturnLoopCounter: true\n"
  },
  {
    "path": "test/libsolidity/astPropertyTests/multiple_nested_properties_per_node.sol",
    "content": "contract C {\n    function f() public pure {\n        /// TestCase1: condition.operator\n        /// TestCase2: initializationExpression.initialValue.value\n        /// TestCase3: loopExpression.expression.subExpression.name\n        for(uint i = 1; i < 42; i++) {\n        }\n    }\n}\n// ----\n// TestCase1: <\n// TestCase2: 1\n// TestCase3: i\n"
  },
  {
    "path": "test/libsolidity/astPropertyTests/multiple_properties_per_node.sol",
    "content": "contract C {\n    /// TestCase1: name\n    /// TestCase2: functionSelector\n    /// TestCase3: visibility\n    function singleFunction() public pure {\n    }\n}\n// ----\n// TestCase1: singleFunction\n// TestCase2: 3d33252c\n// TestCase3: public\n"
  },
  {
    "path": "test/libsolidity/astPropertyTests/nested_properties.sol",
    "content": "contract C {\n    function f() public pure {\n        /// TestCase1: condition.operator\n        for(uint i = 0; i < 42; ++i) {\n        }\n        /// TestCase2: initializationExpression.initialValue.value\n        for(uint i = 1; i < 42; i = i * 2) {\n        }\n        /// TestCase3: loopExpression.expression.subExpression.name\n        for(uint i = 0; i < 42; i++) {\n        }\n    }\n}\n// ----\n// TestCase1: <\n// TestCase2: 1\n// TestCase3: i\n"
  },
  {
    "path": "test/libsolidity/astPropertyTests/property_expectation_with_colon.sol",
    "content": "/// TestCase1: nameLocation\n/// TestCase2: src\ncontract C {\n    function f() public pure {\n    }\n}\n// ----\n// TestCase1: 115:1:-1\n// TestCase2: 106:51:-1\n"
  },
  {
    "path": "test/libsolidity/astPropertyTests/simple_properties.sol",
    "content": "/// TestContractC: name\ncontract C {\n    /// TestStateVarX: stateVariable\n    uint x;\n    /// TestFunctionF: visibility\n    function f() public pure {\n    }\n}\n// ----\n// TestContractC: C\n// TestStateVarX: true\n// TestFunctionF: public\n"
  },
  {
    "path": "test/libsolidity/astPropertyTests/transient_data_location.sol",
    "content": "contract C {\n    /// TransientDataLocation: storageLocation\n    /// TransientVarName: name\n    uint transient x;\n    /// StorageDataLocation: storageLocation\n    /// StorageVarName: name\n    uint y;\n\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// TransientDataLocation: transient\n// TransientVarName: x\n// StorageDataLocation: default\n// StorageVarName: y\n"
  },
  {
    "path": "test/libsolidity/functionDependencyGraphTests/callgraph.sol",
    "content": "// fallback---------->f----------+\n//                    |          |\n//                    |          |\n//                    |          |\n//                    |          |\n//                    v          v\n//                    g          h\n//\n//\n// add\n//\n// unreferenced\n\npragma experimental solidity;\n\ntype uint256 = __builtin(\"word\");\n\ninstantiation uint256: + {\n    function add(x, y) -> uint256 {\n        let a = uint256.rep(x);\n        let b = uint256.rep(y);\n        assembly {\n            a := add(a,b)\n        }\n        return uint256.abs(a);\n    }\n}\n\nfunction unreferenced(x:uint256) -> uint256\n{\n    return x;\n}\n\nfunction f(x:uint256) -> uint256\n{\n    return g(h(x));\n}\n\nfunction g(x:uint256) -> uint256\n{\n    return x;\n}\n\nfunction h(x:uint256) -> uint256\n{\n    return x;\n}\n\ncontract C {\n    fallback() external {\n        let a: uint256->uint256 = f;\n    }\n}\n// ----\n// (add) --> {}\n// (unreferenced) --> {}\n// (f) --> {g,h,}\n// (g) --> {}\n// (h) --> {}\n// (fallback) --> {f,}\n"
  },
  {
    "path": "test/libsolidity/functionDependencyGraphTests/callgraph_no_leaves.sol",
    "content": "// a<------b\n// |       ^\n// |       |\n// |       |\n// |       |\n// |       |\n// +------>c------->d-------->e------->f\n//                            ^        |\n//                            |        |\n//                            |        |\n//                            |        |\n//                            |        v\n//                            h<-------g\n\npragma experimental solidity;\n\nfunction a()\n{\n    c();\n}\n\nfunction b()\n{\n    a();\n}\n\nfunction c()\n{\n    b();\n    d();\n}\n\nfunction d()\n{\n    e();\n}\n\nfunction e()\n{\n    f();\n}\n\nfunction f()\n{\n    g();\n}\n\nfunction g()\n{\n    h();\n}\n\nfunction h()\n{\n    e();\n}\n\n// ----\n// (a) --> {c,}\n// (b) --> {a,}\n// (c) --> {b,d,}\n// (d) --> {e,}\n// (e) --> {f,}\n// (f) --> {g,}\n// (g) --> {h,}\n// (h) --> {e,}\n"
  },
  {
    "path": "test/libsolidity/gasTests/abiv2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    uint public a;\n    uint[] public b;\n    function f1(uint) public pure returns (uint) { }\n    function f2(uint[] memory, string[] memory, uint16, address) public returns (uint[] memory, uint16[] memory) {}\n    function f3(uint16[] memory, string[] memory, uint16, address) public returns (uint[] memory, uint16[] memory) {}\n    function f4(uint32[] memory, string[12] memory, bytes[2][] memory, address) public returns (uint[] memory, uint16[] memory) {}\n    function f5(address[] memory, string[] memory, bytes memory, address) public returns (uint[] memory, uint16[] memory) {}\n    function f6(uint[30] memory, string[] memory, uint16, address) public returns (uint16[200] memory, uint16[] memory) {}\n    function f7(uint[31] memory, string[20] memory, C, address) public returns (bytes[] memory, uint16[] memory) {}\n    function f8(uint[32] memory, string[] memory, uint32, address) public returns (uint[] memory, uint16[] memory) {}\n}\n// ====\n// EVMVersion: =current\n// bytecodeFormat: legacy\n// ----\n// creation:\n//   codeDepositCost: 1208000\n//   executionCost: 1252\n//   totalCost: 1209252\n// external:\n//   a(): 2425\n//   b(uint256): infinite\n//   f1(uint256): infinite\n//   f2(uint256[],string[],uint16,address): infinite\n//   f3(uint16[],string[],uint16,address): infinite\n//   f4(uint32[],string[12],bytes[2][],address): infinite\n//   f5(address[],string[],bytes,address): infinite\n//   f6(uint256[30],string[],uint16,address): infinite\n//   f7(uint256[31],string[20],address,address): infinite\n//   f8(uint256[32],string[],uint32,address): infinite\n"
  },
  {
    "path": "test/libsolidity/gasTests/abiv2_optimised.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    uint public a;\n    uint[] public b;\n    function f1(uint) public pure returns (uint) { }\n    function f2(uint[] memory, string[] memory, uint16, address) public returns (uint[] memory, uint16[] memory) {}\n    function f3(uint16[] memory, string[] memory, uint16, address) public returns (uint[] memory, uint16[] memory) {}\n    function f4(uint32[] memory, string[12] memory, bytes[2][] memory, address) public returns (uint[] memory, uint16[] memory) {}\n    function f5(address[] memory, string[] memory, bytes memory, address) public returns (uint[] memory, uint16[] memory) {}\n    function f6(uint[30] memory, string[] memory, uint16, address) public returns (uint16[200] memory, uint16[] memory) {}\n    function f7(uint[31] memory, string[20] memory, C, address) public returns (bytes[] memory, uint16[] memory) {}\n    function f8(uint[32] memory, string[] memory, uint32, address) public returns (uint[] memory, uint16[] memory) {}\n}\n// ====\n// EVMVersion: =current\n// bytecodeFormat: legacy\n// optimize: true\n// optimize-yul: true\n// ----\n// creation:\n//   codeDepositCost: 618200\n//   executionCost: 649\n//   totalCost: 618849\n// external:\n//   a(): 2283\n//   b(uint256): 4649\n//   f1(uint256): 304\n//   f2(uint256[],string[],uint16,address): infinite\n//   f3(uint16[],string[],uint16,address): infinite\n//   f4(uint32[],string[12],bytes[2][],address): infinite\n//   f5(address[],string[],bytes,address): infinite\n//   f6(uint256[30],string[],uint16,address): infinite\n//   f7(uint256[31],string[20],address,address): infinite\n//   f8(uint256[32],string[],uint32,address): infinite\n"
  },
  {
    "path": "test/libsolidity/gasTests/data_storage.sol",
    "content": "contract C {\n    function f() pure public {\n        require(false, \"1234567890123456789012345678901\");\n        require(false, \"12345678901234567890123456789012\");\n        require(false, \"123456789012345678901234567890123\");\n        require(false, \"1234567890123456789012345678901234\");\n        require(false, \"12345678901234567890123456789012345\");\n        require(false, \"123456789012345678901234567890123456\");\n        require(false, \"123456789012345678901234567890121234567890123456789012345678901\");\n        require(false, \"1234567890123456789012345678901212345678901234567890123456789012\");\n        require(false, \"12345678901234567890123456789012123456789012345678901234567890123\");\n    }\n}\n// ====\n// EVMVersion: =current\n// bytecodeFormat: legacy\n// ----\n// creation:\n//   codeDepositCost: 377800\n//   executionCost: 416\n//   totalCost: 378216\n// external:\n//   f(): 421\n"
  },
  {
    "path": "test/libsolidity/gasTests/dispatch_large.sol",
    "content": "contract Large {\n    uint public a;\n    uint[] public b;\n    function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }\n    function f2(uint x) public returns (uint) { b[uint8(msg.data[1])] = x; }\n    function f3(uint x) public returns (uint) { b[uint8(msg.data[2])] = x; }\n    function f4(uint x) public returns (uint) { b[uint8(msg.data[3])] = x; }\n    function f5(uint x) public returns (uint) { b[uint8(msg.data[4])] = x; }\n    function f6(uint x) public returns (uint) { b[uint8(msg.data[5])] = x; }\n    function f7(uint x) public returns (uint) { b[uint8(msg.data[6])] = x; }\n    function f8(uint x) public returns (uint) { b[uint8(msg.data[7])] = x; }\n    function f9(uint x) public returns (uint) { b[uint8(msg.data[8])] = x; }\n    function f0(uint x) public pure returns (uint) { require(x > 10); }\n    function g1(uint x) public payable returns (uint) { a = x; b[uint8(msg.data[0])] = x; }\n    function g2(uint x) public payable returns (uint) { b[uint8(msg.data[1])] = x; }\n    function g3(uint x) public payable returns (uint) { b[uint8(msg.data[2])] = x; }\n    function g4(uint x) public payable returns (uint) { b[uint8(msg.data[3])] = x; }\n    function g5(uint x) public payable returns (uint) { b[uint8(msg.data[4])] = x; }\n    function g6(uint x) public payable returns (uint) { b[uint8(msg.data[5])] = x; }\n    function g7(uint x) public payable returns (uint) { b[uint8(msg.data[6])] = x; }\n    function g8(uint x) public payable returns (uint) { b[uint8(msg.data[7])] = x; }\n    function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }\n    function g0(uint x) public payable returns (uint) { require(x > 10); }\n}\n// ====\n// EVMVersion: =current\n// bytecodeFormat: legacy\n// ----\n// creation:\n//   codeDepositCost: 618400\n//   executionCost: 649\n//   totalCost: 619049\n// external:\n//   a(): 2470\n//   b(uint256): infinite\n//   f0(uint256): infinite\n//   f1(uint256): infinite\n//   f2(uint256): infinite\n//   f3(uint256): infinite\n//   f4(uint256): infinite\n//   f5(uint256): infinite\n//   f6(uint256): infinite\n//   f7(uint256): infinite\n//   f8(uint256): infinite\n//   f9(uint256): infinite\n//   g0(uint256): infinite\n//   g1(uint256): infinite\n//   g2(uint256): infinite\n//   g3(uint256): infinite\n//   g4(uint256): infinite\n//   g5(uint256): infinite\n//   g6(uint256): infinite\n//   g7(uint256): infinite\n//   g8(uint256): infinite\n//   g9(uint256): infinite\n"
  },
  {
    "path": "test/libsolidity/gasTests/dispatch_large_optimised.sol",
    "content": "contract Large {\n    uint public a;\n    uint[] public b;\n    function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }\n    function f2(uint x) public returns (uint) { b[uint8(msg.data[1])] = x; }\n    function f3(uint x) public returns (uint) { b[uint8(msg.data[2])] = x; }\n    function f4(uint x) public returns (uint) { b[uint8(msg.data[3])] = x; }\n    function f5(uint x) public returns (uint) { b[uint8(msg.data[4])] = x; }\n    function f6(uint x) public returns (uint) { b[uint8(msg.data[5])] = x; }\n    function f7(uint x) public returns (uint) { b[uint8(msg.data[6])] = x; }\n    function f8(uint x) public returns (uint) { b[uint8(msg.data[7])] = x; }\n    function f9(uint x) public returns (uint) { b[uint8(msg.data[8])] = x; }\n    function f0(uint x) public pure returns (uint) { require(x > 10); }\n    function g1(uint x) public payable returns (uint) { a = x; b[uint8(msg.data[0])] = x; }\n    function g2(uint x) public payable returns (uint) { b[uint8(msg.data[1])] = x; }\n    function g3(uint x) public payable returns (uint) { b[uint8(msg.data[2])] = x; }\n    function g4(uint x) public payable returns (uint) { b[uint8(msg.data[3])] = x; }\n    function g5(uint x) public payable returns (uint) { b[uint8(msg.data[4])] = x; }\n    function g6(uint x) public payable returns (uint) { b[uint8(msg.data[5])] = x; }\n    function g7(uint x) public payable returns (uint) { b[uint8(msg.data[6])] = x; }\n    function g8(uint x) public payable returns (uint) { b[uint8(msg.data[7])] = x; }\n    function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }\n    function g0(uint x) public payable returns (uint) { require(x > 10); }\n}\n// ====\n// EVMVersion: =current\n// bytecodeFormat: legacy\n// optimize: true\n// optimize-runs: 2\n// ----\n// creation:\n//   codeDepositCost: 224600\n//   executionCost: 267\n//   totalCost: 224867\n// external:\n//   a(): 2281\n//   b(uint256): 4934\n//   f0(uint256): 363\n//   f1(uint256): 47002\n//   f2(uint256): 24967\n//   f3(uint256): 25055\n//   f4(uint256): 25033\n//   f5(uint256): 25011\n//   f6(uint256): 24923\n//   f7(uint256): 24703\n//   f8(uint256): 24835\n//   f9(uint256): 24857\n//   g0(uint256): 603\n//   g1(uint256): 46714\n//   g2(uint256): 24701\n//   g3(uint256): 24789\n//   g4(uint256): 24767\n//   g5(uint256): 24855\n//   g6(uint256): 24635\n//   g7(uint256): 24745\n//   g8(uint256): 24723\n//   g9(uint256): 24569\n"
  },
  {
    "path": "test/libsolidity/gasTests/dispatch_medium.sol",
    "content": "contract Medium {\n    uint public a;\n    uint[] public b;\n    function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }\n    function f2(uint x) public returns (uint) { b[uint8(msg.data[1])] = x; }\n    function f3(uint x) public returns (uint) { b[uint8(msg.data[2])] = x; }\n    function g7(uint x) public payable returns (uint) { b[uint8(msg.data[6])] = x; }\n    function g8(uint x) public payable returns (uint) { b[uint8(msg.data[7])] = x; }\n    function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }\n    function g0(uint x) public payable returns (uint) { require(x > 10); }\n}\n// ====\n// EVMVersion: =current\n// bytecodeFormat: legacy\n// ----\n// creation:\n//   codeDepositCost: 259600\n//   executionCost: 298\n//   totalCost: 259898\n// external:\n//   a(): 2447\n//   b(uint256): infinite\n//   f1(uint256): infinite\n//   f2(uint256): infinite\n//   f3(uint256): infinite\n//   g0(uint256): infinite\n//   g7(uint256): infinite\n//   g8(uint256): infinite\n//   g9(uint256): infinite\n"
  },
  {
    "path": "test/libsolidity/gasTests/dispatch_medium_optimised.sol",
    "content": "contract Medium {\n    uint public a;\n    uint[] public b;\n    function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }\n    function f2(uint x) public returns (uint) { b[uint8(msg.data[1])] = x; }\n    function f3(uint x) public returns (uint) { b[uint8(msg.data[2])] = x; }\n    function g7(uint x) public payable returns (uint) { b[uint8(msg.data[6])] = x; }\n    function g8(uint x) public payable returns (uint) { b[uint8(msg.data[7])] = x; }\n    function g9(uint x) public payable returns (uint) { b[uint8(msg.data[8])] = x; }\n    function g0(uint x) public payable returns (uint) { require(x > 10); }\n}\n// ====\n// EVMVersion: =current\n// bytecodeFormat: legacy\n// ====\n// optimize: true\n// optimize-runs: 2\n// ----\n// creation:\n//   codeDepositCost: 126000\n//   executionCost: 169\n//   totalCost: 126169\n// external:\n//   a(): 2281\n//   b(uint256): 4692\n//   f1(uint256): 46782\n//   f2(uint256): 24725\n//   f3(uint256): 24769\n//   g0(uint256): 361\n//   g7(uint256): 24635\n//   g8(uint256): 24613\n//   g9(uint256): 24569\n"
  },
  {
    "path": "test/libsolidity/gasTests/dispatch_small.sol",
    "content": "contract Small {\n    uint public a;\n    uint[] public b;\n    function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }\n    fallback () external payable {}\n}\n// ====\n// EVMVersion: =current\n// bytecodeFormat: legacy\n// ----\n// creation:\n//   codeDepositCost: 103800\n//   executionCost: 151\n//   totalCost: 103951\n// external:\n//   fallback: 128\n//   a(): 2402\n//   b(uint256): infinite\n//   f1(uint256): infinite\n"
  },
  {
    "path": "test/libsolidity/gasTests/dispatch_small_optimised.sol",
    "content": "contract Small {\n    uint public a;\n    uint[] public b;\n    function f1(uint x) public returns (uint) { a = x; b[uint8(msg.data[0])] = x; }\n    fallback () external payable {}\n}\n// ====\n// EVMVersion: =current\n// optimize: true\n// optimize-runs: 2\n// bytecodeFormat: legacy\n// ----\n// creation:\n//   codeDepositCost: 58200\n//   executionCost: 109\n//   totalCost: 58309\n// external:\n//   fallback: 117\n//   a(): 2259\n//   b(uint256): 4582\n//   f1(uint256): 46716\n"
  },
  {
    "path": "test/libsolidity/gasTests/exp.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tfunction exp_neg_one(uint exponent) public returns(int) {\n\t\tunchecked { return (-1)**exponent; }\n\t}\n\tfunction exp_two(uint exponent) public returns(uint) {\n\t\tunchecked { return 2**exponent; }\n\t}\n\tfunction exp_zero(uint exponent) public returns(uint) {\n\t\tunchecked { return 0**exponent; }\n\t}\n\tfunction exp_one(uint exponent) public returns(uint) {\n\t\tunchecked { return 1**exponent; }\n\t}\n}\n// ====\n// EVMVersion: =current\n// bytecodeFormat: legacy\n// optimize: false\n// optimize-yul: false\n// ----\n// creation:\n//   codeDepositCost: 107000\n//   executionCost: 151\n//   totalCost: 107151\n// external:\n//   exp_neg_one(uint256): 2250\n//   exp_one(uint256): infinite\n//   exp_two(uint256): infinite\n//   exp_zero(uint256): infinite\n"
  },
  {
    "path": "test/libsolidity/gasTests/exp_optimized.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tfunction exp_neg_one(uint exponent) public returns(int) {\n\t\tunchecked { return (-1)**exponent; }\n\t}\n\tfunction exp_two(uint exponent) public returns(uint) {\n\t\tunchecked { return 2**exponent; }\n\t}\n\tfunction exp_zero(uint exponent) public returns(uint) {\n\t\tunchecked { return 0**exponent; }\n\t}\n\tfunction exp_one(uint exponent) public returns(uint) {\n\t\tunchecked { return 1**exponent; }\n\t}\n}\n// ====\n// EVMVersion: =current\n// bytecodeFormat: legacy\n// optimize: true\n// optimize-yul: true\n// ----\n// creation:\n//   codeDepositCost: 35800\n//   executionCost: 85\n//   totalCost: 35885\n// external:\n//   exp_neg_one(uint256): 1914\n//   exp_one(uint256): 1868\n//   exp_two(uint256): 1846\n//   exp_zero(uint256): 1889\n"
  },
  {
    "path": "test/libsolidity/gasTests/storage_costs.sol",
    "content": "contract C {\n    uint x;\n    function setX(uint y) public {\n        x = y;\n    }\n    function resetX() public {\n        x = 0;\n    }\n    function readX() public view returns(uint) {\n        return x;\n    }\n}\n// ====\n// EVMVersion: =current\n// optimize: true\n// optimize-yul: true\n// bytecodeFormat: legacy\n// ----\n// creation:\n//   codeDepositCost: 25600\n//   executionCost: 73\n//   totalCost: 25673\n// external:\n//   readX(): 2288\n//   resetX(): 5114\n//   setX(uint256): 22309\n"
  },
  {
    "path": "test/libsolidity/interface/FileReader.cpp",
    "content": "/*\n\tThis file is part of solidity.\n\n\tsolidity is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tsolidity is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with solidity.  If not, see <http://www.gnu.org/licenses/>.\n*/\n// SPDX-License-Identifier: GPL-3.0\n\n/// Unit tests for libsolidity/interface/FileReader.h\n\n#include <libsolidity/interface/FileReader.h>\n\n#include <test/Common.h>\n#include <test/FilesystemUtils.h>\n#include <test/libsolidity/util/SoltestErrors.h>\n\n#include <libsolutil/TemporaryDirectory.h>\n\n#include <boost/algorithm/string.hpp>\n#include <boost/filesystem.hpp>\n#include <boost/test/unit_test.hpp>\n\nusing namespace solidity::util;\nusing namespace solidity::test;\n\n#define TEST_CASE_NAME (boost::unit_test::framework::current_test_case().p_name)\n\nnamespace solidity::frontend::test\n{\n\nusing SymlinkResolution = FileReader::SymlinkResolution;\n\nBOOST_AUTO_TEST_SUITE(FileReaderTest)\n\nBOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_absolute_path)\n{\n\tfor (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})\n\t{\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/.\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/./\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/./.\", resolveSymlinks), \"/\");\n\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a\", resolveSymlinks), \"/a\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/\", resolveSymlinks), \"/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/.\", resolveSymlinks), \"/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/./a\", resolveSymlinks), \"/a\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/./a/\", resolveSymlinks), \"/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/./a/.\", resolveSymlinks), \"/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/b\", resolveSymlinks), \"/a/b\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/b/\", resolveSymlinks), \"/a/b/\");\n\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/./b/\", resolveSymlinks), \"/a/b/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/../a/b/\", resolveSymlinks), \"/a/b/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/b/c/..\", resolveSymlinks), \"/a/b\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/b/c/../\", resolveSymlinks), \"/a/b/\");\n\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/b/c/../../..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/b/c/../../../\", resolveSymlinks), \"/\");\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_relative_path)\n{\n\tTemporaryDirectory tempDir({\"x/y/z\"}, TEST_CASE_NAME);\n\tTemporaryWorkingDirectory tempWorkDir(tempDir.path() / \"x/y/z\");\n\n\t// NOTE: If path to work dir contains symlinks (often the case on macOS), boost might resolve\n\t// them, making the path different from tempDirPath.\n\tboost::filesystem::path expectedPrefix = boost::filesystem::current_path().parent_path().parent_path().parent_path();\n\t// On Windows tempDir.path() normally contains the drive letter while the normalized path should not.\n\texpectedPrefix = \"/\" / expectedPrefix.relative_path();\n\tsoltestAssert(expectedPrefix.is_absolute() || expectedPrefix.root_path() == \"/\", \"\");\n\n\tfor (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})\n\t{\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\".\", resolveSymlinks), expectedPrefix / \"x/y/z/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"./\", resolveSymlinks), expectedPrefix / \"x/y/z/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\".//\", resolveSymlinks), expectedPrefix / \"x/y/z/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"..\", resolveSymlinks), expectedPrefix / \"x/y\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../\", resolveSymlinks), expectedPrefix / \"x/y/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"..//\", resolveSymlinks), expectedPrefix / \"x/y/\");\n\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a\", resolveSymlinks), expectedPrefix / \"x/y/z/a\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/\", resolveSymlinks), expectedPrefix / \"x/y/z/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/.\", resolveSymlinks), expectedPrefix / \"x/y/z/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"./a\", resolveSymlinks), expectedPrefix / \"x/y/z/a\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"./a/\", resolveSymlinks), expectedPrefix / \"x/y/z/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"./a/.\", resolveSymlinks), expectedPrefix / \"x/y/z/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"./a/./\", resolveSymlinks), expectedPrefix / \"x/y/z/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"./a/.//\", resolveSymlinks), expectedPrefix / \"x/y/z/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"./a/./.\", resolveSymlinks), expectedPrefix / \"x/y/z/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"./a/././\", resolveSymlinks), expectedPrefix / \"x/y/z/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"./a/././/\", resolveSymlinks), expectedPrefix / \"x/y/z/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/b\", resolveSymlinks), expectedPrefix / \"x/y/z/a/b\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/b/\", resolveSymlinks), expectedPrefix / \"x/y/z/a/b/\");\n\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../a/b\", resolveSymlinks), expectedPrefix / \"x/y/a/b\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../../a/b\", resolveSymlinks), expectedPrefix / \"x/a/b\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"./a/b\", resolveSymlinks), expectedPrefix / \"x/y/z/a/b\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"././a/b\", resolveSymlinks), expectedPrefix / \"x/y/z/a/b\");\n\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/./b/\", resolveSymlinks), expectedPrefix / \"x/y/z/a/b/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/../a/b/\", resolveSymlinks), expectedPrefix / \"x/y/z/a/b/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/b/c/..\", resolveSymlinks), expectedPrefix / \"x/y/z/a/b\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/b/c/../\", resolveSymlinks), expectedPrefix / \"x/y/z/a/b/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/b/c/..//\", resolveSymlinks), expectedPrefix / \"x/y/z/a/b/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/b/c/../..\", resolveSymlinks), expectedPrefix / \"x/y/z/a\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/b/c/../../\", resolveSymlinks), expectedPrefix / \"x/y/z/a/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/b/c/../..//\", resolveSymlinks), expectedPrefix / \"x/y/z/a/\");\n\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../../a/.././../p/../q/../a/b\", resolveSymlinks), expectedPrefix / \"a/b\");\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_redundant_slashes)\n{\n\tfor (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})\n\t{\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"///\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"////\", resolveSymlinks), \"/\");\n\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"////a/b/\", resolveSymlinks), \"/a/b/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a//b/\", resolveSymlinks), \"/a/b/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a////b/\", resolveSymlinks), \"/a/b/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/b//\", resolveSymlinks), \"/a/b/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/b////\", resolveSymlinks), \"/a/b/\");\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_unc_path)\n{\n\tTemporaryDirectory tempDir(TEST_CASE_NAME);\n\tTemporaryWorkingDirectory tempWorkDir(tempDir);\n\n\t// On Windows tempDir.path() normally contains the drive letter while the normalized path should not.\n\tboost::filesystem::path expectedWorkDir = \"/\" / boost::filesystem::current_path().relative_path();\n\tsoltestAssert(expectedWorkDir.is_absolute() || expectedWorkDir.root_path() == \"/\", \"\");\n\n\tfor (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})\n\t{\n\t\t// UNC paths start with // or \\\\ followed by a name. They are used for network shares on Windows.\n\t\t// On UNIX systems they are not supported but still treated in a special way.\n\n\t\t// TODO: Re-enable these once the boost 1.86 change has been addressed\n\t\t//BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"//host/\", resolveSymlinks), \"//host/\");\n\t\t//BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"//host/a/b\", resolveSymlinks), \"//host/a/b\");\n\t\t//BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"//host/a/b/\", resolveSymlinks), \"//host/a/b/\");\n\n#if defined(_WIN32)\n\t\t// On Windows an UNC path can also start with \\\\ instead of //\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"\\\\\\\\host/\", resolveSymlinks), \"//host/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"\\\\\\\\host/a/b\", resolveSymlinks), \"//host/a/b\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"\\\\\\\\host/a/b/\", resolveSymlinks), \"//host/a/b/\");\n#else\n\t\t// On UNIX systems it's just a fancy relative path instead\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"\\\\\\\\host/\", resolveSymlinks), expectedWorkDir / \"\\\\\\\\host/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"\\\\\\\\host/a/b\", resolveSymlinks), expectedWorkDir / \"\\\\\\\\host/a/b\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"\\\\\\\\host/a/b/\", resolveSymlinks), expectedWorkDir / \"\\\\\\\\host/a/b/\");\n#endif\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_root_name_only)\n{\n\tTemporaryDirectory tempDir(TEST_CASE_NAME);\n\tTemporaryWorkingDirectory tempWorkDir(tempDir);\n\n\tboost::filesystem::path expectedWorkDir = \"/\" / boost::filesystem::current_path().relative_path();\n\tsoltestAssert(expectedWorkDir.is_absolute() || expectedWorkDir.root_path() == \"/\", \"\");\n\n\t// A root **path** consists of a directory name (typically / or \\) and the root name (drive\n\t// letter (C:), UNC host name (//host), etc.). Either can be empty. Root path as a whole may be\n\t// an absolute path but root name on its own is considered relative. For example on Windows\n\t// C:\\ represents the root directory of drive C: but C: on its own refers to the current working\n\t// directory.\n\n\tfor (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})\n\t{\n\t\t// UNC paths\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"//\", resolveSymlinks), \"//\" / expectedWorkDir);\n\t\t// TODO: Re-enable these once the boost 1.86 change has been addressed\n\t\t//BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"//host\", resolveSymlinks), \"//host\" / expectedWorkDir);\n\n\t\t// On UNIX systems root name is empty.\n\t\t// TODO: Re-enable these once the boost 1.86 change has been addressed\n\t\t//BOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"\", resolveSymlinks), expectedWorkDir);\n\n#if defined(_WIN32)\n\t\tboost::filesystem::path driveLetter = boost::filesystem::current_path().root_name();\n\t\tsoltestAssert(!driveLetter.empty(), \"\");\n\t\tsoltestAssert(driveLetter.is_relative(), \"\");\n\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(driveLetter, resolveSymlinks), expectedWorkDir);\n#endif\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_stripping_root_name)\n{\n\tTemporaryDirectory tempDir(TEST_CASE_NAME);\n\tTemporaryWorkingDirectory tempWorkDir(tempDir);\n\n\tsoltestAssert(boost::filesystem::current_path().is_absolute(), \"\");\n#if defined(_WIN32)\n\tsoltestAssert(!boost::filesystem::current_path().root_name().empty(), \"\");\n#endif\n\n\tfor (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})\n\t{\n\t\tboost::filesystem::path workDir = boost::filesystem::current_path();\n\n\t\tboost::filesystem::path normalizedPath = FileReader::normalizeCLIPathForVFS(\n\t\t\tworkDir,\n\t\t\tresolveSymlinks\n\t\t);\n\t\tBOOST_CHECK_EQUAL(normalizedPath, \"/\" / workDir.relative_path());\n\t\tBOOST_TEST(normalizedPath.root_name().empty());\n\t\tBOOST_CHECK_EQUAL(normalizedPath.root_directory(), \"/\");\n\n#if defined(_WIN32)\n\t\tstd::string root = workDir.root_path().string();\n\t\tsoltestAssert(root.length() == 3 && root[1] == ':' && root[2] == '\\\\', \"\");\n\n\t\tfor (auto convert: {boost::to_lower_copy<std::string>, boost::to_upper_copy<std::string>})\n\t\t{\n\t\t\tboost::filesystem::path workDirWin = convert(root, std::locale()) / workDir.relative_path();\n\t\t\tnormalizedPath = FileReader::normalizeCLIPathForVFS(\n\t\t\t\tworkDirWin,\n\t\t\t\tresolveSymlinks\n\t\t\t);\n\t\t\tBOOST_CHECK_EQUAL(normalizedPath, \"/\" / workDir.relative_path());\n\t\t\tBOOST_TEST(normalizedPath.root_name().empty());\n\t\t\tBOOST_CHECK_EQUAL(normalizedPath.root_directory(), \"/\");\n\t\t}\n#endif\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_path_beyond_root)\n{\n\tTemporaryWorkingDirectory tempWorkDir(\"/\");\n\n\tfor (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})\n\t{\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/../\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/../.\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/../..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/../a\", resolveSymlinks), \"/a\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/../a/..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/../a/../..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/../../a\", resolveSymlinks), \"/a\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/../../a/..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/../../a/../..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/../..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"/a/../../b/../..\", resolveSymlinks), \"/\");\n\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../.\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../a\", resolveSymlinks), \"/a\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../a/..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../a/../..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../../a\", resolveSymlinks), \"/a\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../../a/..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"../../a/../..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/../..\", resolveSymlinks), \"/\");\n\t\tBOOST_CHECK_EQUAL(FileReader::normalizeCLIPathForVFS(\"a/../../b/../..\", resolveSymlinks), \"/\");\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_case_sensitivity)\n{\n\tTemporaryDirectory tempDir(TEST_CASE_NAME);\n\tTemporaryWorkingDirectory tempWorkDir(tempDir);\n\n\tboost::filesystem::path workDirNoSymlinks = boost::filesystem::weakly_canonical(tempDir);\n\tboost::filesystem::path expectedPrefix = \"/\" / workDirNoSymlinks.relative_path();\n\n\tfor (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})\n\t{\n\t\tBOOST_TEST(FileReader::normalizeCLIPathForVFS(workDirNoSymlinks / \"abc\", resolveSymlinks) == expectedPrefix / \"abc\");\n\t\tBOOST_TEST(FileReader::normalizeCLIPathForVFS(workDirNoSymlinks / \"abc\", resolveSymlinks) != expectedPrefix / \"ABC\");\n\t\tBOOST_TEST(FileReader::normalizeCLIPathForVFS(workDirNoSymlinks / \"ABC\", resolveSymlinks) != expectedPrefix / \"abc\");\n\t\tBOOST_TEST(FileReader::normalizeCLIPathForVFS(workDirNoSymlinks / \"ABC\", resolveSymlinks) == expectedPrefix / \"ABC\");\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_path_separators)\n{\n\tfor (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})\n\t{\n\t\t// Even on Windows we want / as a separator.\n\t\tBOOST_TEST((\n\t\t\tFileReader::normalizeCLIPathForVFS(\"/a/b/c\", resolveSymlinks).native() ==\n\t\t\tboost::filesystem::path(\"/a/b/c\").native()\n\t\t));\n\t}\n}\n\nBOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_should_not_resolve_symlinks_unless_requested)\n{\n\tTemporaryDirectory tempDir({\"abc/\"}, TEST_CASE_NAME);\n\tsoltestAssert(tempDir.path().is_absolute(), \"\");\n\n\tif (!createSymlinkIfSupportedByFilesystem(tempDir.path() / \"abc\", tempDir.path() / \"sym\", true))\n\t\treturn;\n\n\tboost::filesystem::path expectedRootPath = FileReader::normalizeCLIRootPathForVFS(tempDir);\n\tboost::filesystem::path expectedPrefixWithSymlinks = expectedRootPath / tempDir.path().relative_path();\n\tboost::filesystem::path expectedPrefixWithoutSymlinks = expectedRootPath / boost::filesystem::weakly_canonical(tempDir).relative_path();\n\n\tBOOST_CHECK_EQUAL(\n\t\tFileReader::normalizeCLIPathForVFS(tempDir.path() / \"sym/contract.sol\", SymlinkResolution::Disabled),\n\t\texpectedPrefixWithSymlinks / \"sym/contract.sol\"\n\t);\n\tBOOST_CHECK_EQUAL(\n\t\tFileReader::normalizeCLIPathForVFS(tempDir.path() / \"abc/contract.sol\", SymlinkResolution::Disabled),\n\t\texpectedPrefixWithSymlinks / \"abc/contract.sol\"\n\t);\n\n\tBOOST_CHECK_EQUAL(\n\t\tFileReader::normalizeCLIPathForVFS(tempDir.path() / \"sym/contract.sol\", SymlinkResolution::Enabled),\n\t\texpectedPrefixWithoutSymlinks / \"abc/contract.sol\"\n\t);\n\tBOOST_CHECK_EQUAL(\n\t\tFileReader::normalizeCLIPathForVFS(tempDir.path() / \"abc/contract.sol\", SymlinkResolution::Enabled),\n\t\texpectedPrefixWithoutSymlinks / \"abc/contract.sol\"\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_should_resolve_symlinks_in_workdir_when_path_is_relative)\n{\n\tTemporaryDirectory tempDir({\"abc/\"}, TEST_CASE_NAME);\n\tsoltestAssert(tempDir.path().is_absolute(), \"\");\n\n\tif (!createSymlinkIfSupportedByFilesystem(tempDir.path() / \"abc\", tempDir.path() / \"sym\", true))\n\t\treturn;\n\n\tTemporaryWorkingDirectory tempWorkDir(tempDir.path() / \"sym\");\n\tboost::filesystem::path expectedWorkDir = \"/\" / boost::filesystem::weakly_canonical(boost::filesystem::current_path()).relative_path();\n\tsoltestAssert(expectedWorkDir.is_absolute() || expectedWorkDir.root_path() == \"/\", \"\");\n\n\tboost::filesystem::path expectedPrefix = \"/\" / tempDir.path().relative_path();\n\tsoltestAssert(expectedPrefix.is_absolute() || expectedPrefix.root_path() == \"/\", \"\");\n\n\tfor (SymlinkResolution resolveSymlinks: {SymlinkResolution::Enabled, SymlinkResolution::Disabled})\n\t{\n\t\tBOOST_CHECK_EQUAL(\n\t\t\tFileReader::normalizeCLIPathForVFS(\"contract.sol\", resolveSymlinks),\n\t\t\texpectedWorkDir / \"contract.sol\"\n\t\t);\n\t}\n\n\tBOOST_CHECK_EQUAL(\n\t\tFileReader::normalizeCLIPathForVFS(tempDir.path() / \"sym/contract.sol\", SymlinkResolution::Disabled),\n\t\texpectedPrefix / \"sym/contract.sol\"\n\t);\n\tBOOST_CHECK_EQUAL(\n\t\tFileReader::normalizeCLIPathForVFS(tempDir.path() / \"abc/contract.sol\", SymlinkResolution::Disabled),\n\t\texpectedPrefix / \"abc/contract.sol\"\n\t);\n\n\tBOOST_CHECK_EQUAL(\n\t\tFileReader::normalizeCLIPathForVFS(tempDir.path() / \"sym/contract.sol\", SymlinkResolution::Enabled),\n\t\texpectedWorkDir / \"contract.sol\"\n\t);\n\tBOOST_CHECK_EQUAL(\n\t\tFileReader::normalizeCLIPathForVFS(tempDir.path() / \"abc/contract.sol\", SymlinkResolution::Enabled),\n\t\texpectedWorkDir / \"contract.sol\"\n\t);\n}\n\nBOOST_AUTO_TEST_CASE(isPathPrefix_file_prefix)\n{\n\tBOOST_TEST(FileReader::isPathPrefix(\"/\", \"/contract.sol\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/contract.sol\", \"/contract.sol\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/contract.sol/\", \"/contract.sol\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/contract.sol/.\", \"/contract.sol\"));\n\n\tBOOST_TEST(FileReader::isPathPrefix(\"/\", \"/a/bc/def/contract.sol\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a\", \"/a/bc/def/contract.sol\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a/\", \"/a/bc/def/contract.sol\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a/bc\", \"/a/bc/def/contract.sol\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a/bc/def/contract.sol\", \"/a/bc/def/contract.sol\"));\n\n\tBOOST_TEST(FileReader::isPathPrefix(\"/\", \"/a/bc/def/contract.sol\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a\", \"/a/bc/def/contract.sol\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a/\", \"/a/bc/def/contract.sol\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a/bc\", \"/a/bc/def/contract.sol\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a/bc/def/contract.sol\", \"/a/bc/def/contract.sol\"));\n\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/contract.sol\", \"/token.sol\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/contract\", \"/contract.sol\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/contract.sol\", \"/contract\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/contract.so\", \"/contract.sol\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/contract.sol\", \"/contract.so\"));\n\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/b/c/contract.sol\", \"/a/b/contract.sol\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/b/contract.sol\", \"/a/b/c/contract.sol\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/b/c/contract.sol\", \"/a/b/c/d/contract.sol\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/b/c/d/contract.sol\", \"/a/b/c/contract.sol\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/b/c/contract.sol\", \"/contract.sol\"));\n}\n\nBOOST_AUTO_TEST_CASE(isPathPrefix_directory_prefix)\n{\n\tBOOST_TEST(FileReader::isPathPrefix(\"/\", \"/\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/b/c/\", \"/\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/b/c\", \"/\"));\n\n\tBOOST_TEST(FileReader::isPathPrefix(\"/\", \"/a/bc/\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a\", \"/a/bc/\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a/\", \"/a/bc/\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a/bc\", \"/a/bc/\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"/a/bc/\", \"/a/bc/\"));\n\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a\", \"/b/\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/\", \"/b/\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/contract.sol\", \"/a/b/\"));\n\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/b/c/\", \"/a/b/\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/b/c\", \"/a/b/\"));\n}\n\nBOOST_AUTO_TEST_CASE(isPathPrefix_unc_path)\n{\n\tBOOST_TEST(FileReader::isPathPrefix(\"//host/a/b/\", \"//host/a/b/\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"//host/a/b\", \"//host/a/b/\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"//host/a/\", \"//host/a/b/\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"//host/a\", \"//host/a/b/\"));\n\tBOOST_TEST(FileReader::isPathPrefix(\"//host/\", \"//host/a/b/\"));\n\n\t// NOTE: //host and // cannot be passed to isPathPrefix() because they are considered relative.\n\n\tBOOST_TEST(!FileReader::isPathPrefix(\"//host1/\", \"//host2/\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"//host1/a/b/\", \"//host2/a/b/\"));\n\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/b/c/\", \"//a/b/c/\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"//a/b/c/\", \"/a/b/c/\"));\n}\n\nBOOST_AUTO_TEST_CASE(isPathPrefix_case_sensitivity)\n{\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a.sol\", \"/A.sol\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/A.sol\", \"/a.sol\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/A/\", \"/a/\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/\", \"/A/\"));\n\tBOOST_TEST(!FileReader::isPathPrefix(\"/a/BC/def/\", \"/a/bc/def/contract.sol\"));\n}\n\nBOOST_AUTO_TEST_CASE(stripPrefixIfPresent_file_prefix)\n{\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/\", \"/contract.sol\"), \"contract.sol\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/contract.sol\", \"/contract.sol\"), \".\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/contract.sol/\", \"/contract.sol\"), \".\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/contract.sol/.\", \"/contract.sol\"), \".\");\n\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/\", \"/a/bc/def/contract.sol\"), \"a/bc/def/contract.sol\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a\", \"/a/bc/def/contract.sol\"), \"bc/def/contract.sol\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/\", \"/a/bc/def/contract.sol\"), \"bc/def/contract.sol\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/bc\", \"/a/bc/def/contract.sol\"), \"def/contract.sol\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/bc/def/\", \"/a/bc/def/contract.sol\"), \"contract.sol\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/bc/def/contract.sol\", \"/a/bc/def/contract.sol\"), \".\");\n\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/contract.sol\", \"/token.sol\"), \"/token.sol\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/contract\", \"/contract.sol\"), \"/contract.sol\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/contract.sol\", \"/contract\"), \"/contract\");\n\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/b/c/contract.sol\", \"/a/b/contract.sol\"), \"/a/b/contract.sol\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/b/contract.sol\", \"/a/b/c/contract.sol\"), \"/a/b/c/contract.sol\");\n}\n\nBOOST_AUTO_TEST_CASE(stripPrefixIfPresent_directory_prefix)\n{\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/\", \"/\"), \".\");\n\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/\", \"/a/bc/def/\"), \"a/bc/def/\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a\", \"/a/bc/def/\"), \"bc/def/\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/\", \"/a/bc/def/\"), \"bc/def/\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/bc\", \"/a/bc/def/\"), \"def/\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/bc/def/\", \"/a/bc/def/\"), \".\");\n\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a\", \"/b/\"), \"/b/\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/\", \"/b/\"), \"/b/\");\n\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/b/c/\", \"/a/b/\"), \"/a/b/\");\n\tBOOST_CHECK_EQUAL(FileReader::stripPrefixIfPresent(\"/a/b/c\", \"/a/b/\"), \"/a/b/\");\n}\n\nBOOST_AUTO_TEST_CASE(isUNCPath)\n{\n\tBOOST_TEST(FileReader::isUNCPath(\"//\"));\n\tBOOST_TEST(FileReader::isUNCPath(\"//root\"));\n\tBOOST_TEST(FileReader::isUNCPath(\"//root/\"));\n\n#if defined(_WIN32)\n\t// On Windows boost sees these as ///, which is equivalent to /\n\tBOOST_TEST(!FileReader::isUNCPath(\"//\\\\\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\"\\\\\\\\/\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\"\\\\/\\\\\"));\n\n\tBOOST_TEST(FileReader::isUNCPath(\"\\\\\\\\\"));\n\tBOOST_TEST(FileReader::isUNCPath(\"\\\\\\\\root\"));\n\tBOOST_TEST(FileReader::isUNCPath(\"\\\\\\\\root/\"));\n#else\n\t// On UNIX it's actually an UNC path\n\tBOOST_TEST(FileReader::isUNCPath(\"//\\\\\"));\n\n\t// On UNIX these are just weird relative directory names consisting only of backslashes.\n\tBOOST_TEST(!FileReader::isUNCPath(\"\\\\\\\\/\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\"\\\\/\\\\\"));\n\n\tBOOST_TEST(!FileReader::isUNCPath(\"\\\\\\\\\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\"\\\\\\\\root\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\"\\\\\\\\root/\"));\n#endif\n\n\tBOOST_TEST(!FileReader::isUNCPath(\"\\\\/\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\"/\\\\\"));\n\n\tBOOST_TEST(!FileReader::isUNCPath(\"\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\".\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\"..\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\"/\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\"a\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\"a/b/c\"));\n\tBOOST_TEST(!FileReader::isUNCPath(\"contract.sol\"));\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n\n} // namespace solidity::frontend::test\n"
  },
  {
    "path": "test/libsolidity/lsp/analyze-full-project/C.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract C\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/analyze-full-project/D.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract D\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/analyze-full-project/E.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract E\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/didChange_template.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract C\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/didOpen_with_import.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nimport './goto/lib.sol';\n\ncontract C\n{\n    function f(uint a, uint b) public pure returns (uint)\n    {\n        return Lib.add(2 * a, b);\n        //     ^^^^^^^ @diagnostics\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/goto/goto_definition.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nimport \"./lib.sol\";\n//      ^ @importDirective\n\ninterface I\n{\n    function f(uint x) external returns (uint);\n    //       ^ @functionF\n}\n\ncontract IA is I\n    //   ^^ @IASymbol\n{\n    function f(uint x) public pure override returns (uint) { return x + 1; }\n}\n\ncontract IB is I\n{\n    function f(uint x) public pure override returns (uint) { return x + 2; }\n}\n\nlibrary IntLib\n{\n    function add(int self, int b) public pure returns (int) { return self + b; }\n    //       ^^^ @IntLibAdd\n}\n\ncontract C\n{\n    I obj;\n    function virtual_inheritance() public payable\n    {\n        obj = new IA();\n        //        ^ @usingIASymbol\n        obj.f(1); // goto-definition should jump to definition of interface.\n    //      ^ @virtualFunctionLookup\n    }\n\n    using IntLib for *;\n    function using_for(int i) pure public\n    {\n        i.add(5);\n //       ^ @usingIntAdd\n        14.add(4);\n    }\n\n    function useLib(uint n) public payable returns (uint)\n    {\n        return Lib.add(n, 1);\n        //     ^ @LibSymbol\n        //         ^ @LibAddSymbol\n    }\n\n    function enums(Color c) public pure returns (Color d)\n    //             ^ @ColorSymbolInParameter\n    {\n        Color e = Color.Red;\n        //    ^ @eVariableDeclaration\n        //              ^ @RedEnumMemberAccess\n        if (c == e)\n        //       ^ @eVariableAccess\n            d = Color.Green;\n        else\n            d = c;\n    }\n\n    type Price is uint128;\n    //   ^^^^^ @PriceDeclaration\n    function udlTest() public pure returns (uint128)\n    {\n        Price p = Price.wrap(128);\n    //  ^ @PriceSymbol\n    //            ^ @PriceInWrap\n        return Price.unwrap(p);\n    }\n\n    function structCtorTest(uint8 v) public pure returns (uint8 result)\n    {\n        RGBColor memory c = RGBColor(v, 2 * v, 3 * v);\n        //                       ^ @RGBColorCursor\n        result = c.red;\n        int a;\n//      ^^^^^ @unusedLocalVar\n    }\n}\n// ----\n// goto_definition: @unusedLocalVar 2072\n// lib: @diagnostics 2072\n// -> textDocument/definition {\n//     \"position\": @importDirective\n// }\n// <- [\n//     {\n//         \"range\": {\n//             \"end\": {\n//                 \"character\": 0,\n//                 \"line\": 0\n//             },\n//             \"start\": {\n//                 \"character\": 0,\n//                 \"line\": 0\n//             }\n//         },\n//         \"uri\": \"lib.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @usingIASymbol\n// }\n// <- [\n//     {\n//         \"range\": @IASymbol,\n//         \"uri\": \"goto_definition.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @virtualFunctionLookup\n// }\n// <- [\n//     {\n//         \"range\": @functionF,\n//         \"uri\": \"goto_definition.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @usingIntAdd\n// }\n// <- [\n//     {\n//         \"range\": @IntLibAdd,\n//         \"uri\": \"goto_definition.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @LibSymbol\n// }\n// <- [\n//     {\n//         \"range\": @LibLibrary,\n//         \"uri\": \"lib.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @LibAddSymbol\n// }\n// <- [\n//     {\n//         \"range\": @addSymbol,\n//         \"uri\": \"lib.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @ColorSymbolInParameter\n// }\n// <- [\n//     {\n//         \"range\": @ColorEnum,\n//         \"uri\": \"lib.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @RedEnumMemberAccess\n// }\n// <- [\n//     {\n//         \"range\": @EnumMemberRed,\n//         \"uri\": \"lib.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @eVariableAccess\n// }\n// <- [\n//     {\n//         \"range\": @eVariableDeclaration,\n//         \"uri\": \"goto_definition.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @PriceSymbol\n// }\n// <- [\n//     {\n//         \"range\": @PriceDeclaration,\n//         \"uri\": \"goto_definition.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @PriceInWrap\n// }\n// <- [\n//     {\n//         \"range\": @PriceDeclaration,\n//         \"uri\": \"goto_definition.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @RGBColorCursor\n// }\n// <- [\n//     {\n//         \"range\": @RGBColorStruct,\n//         \"uri\": \"lib.sol\"\n//     }\n// ]\n"
  },
  {
    "path": "test/libsolidity/lsp/goto/goto_definition_imports.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nimport {Weather as Wetter} from \"./lib.sol\";\n//       ^ @weatherImportCursor\nimport \"./lib.sol\" as That;\n//                    ^^^^ @ThatImport\n\ncontract C\n{\n    function test_symbol_alias() public pure returns (Wetter result)\n                                             //        ^ @WetterCursor\n    {\n        result = Wetter.Sunny;\n    }\n\n    function test_library_alias() public pure returns (That.Color result)\n                                                //     ^ @ThatCursor\n    {\n        That.Color color = That.Color.Red;\n//      ^ @ThatVarCursor   ^ @ThatExpressionCursor\n        result = color;\n    }\n}\n// ----\n// lib: @diagnostics 2072\n// -> textDocument/definition {\n//     \"position\": @weatherImportCursor\n// }\n// <- [\n//     {\n//         \"range\": @whetherEnum,\n//         \"uri\": \"lib.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @WetterCursor\n// }\n// <- [\n//     {\n//         \"range\": @whetherEnum,\n//         \"uri\": \"lib.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @ThatCursor\n// }\n// <- [\n//     {\n//         \"range\": @ColorEnum,\n//         \"uri\": \"lib.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @ThatVarCursor\n// }\n// <- [\n//     {\n//         \"range\": @ColorEnum,\n//         \"uri\": \"lib.sol\"\n//     }\n// ]\n// -> textDocument/definition {\n//     \"position\": @ThatExpressionCursor\n// }\n// <- [\n//     {\n//         \"range\": @ThatImport,\n//         \"uri\": \"goto_definition_imports.sol\"\n//     }\n// ]\n"
  },
  {
    "path": "test/libsolidity/lsp/goto/lib.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\n/// Some Error type E.\nerror E(uint, uint);\n\nenum Weather {\n//   ^^^^^^^ @whetherEnum\n    Sunny,\n    Cloudy,\n    Rainy\n}\n\n/// Some custom Color enum type holding 3 colors.\nenum Color {\n//   ^^^^^ @ColorEnum\n    /// Red color.\n    Red,\n//  ^^^ @EnumMemberRed\n    /// Green color.\n    Green,\n    /// Blue color.\n    Blue\n}\n\nlibrary Lib\n//   @  ^^^ @LibLibrary\n{\n    function add(uint a, uint b) public pure returns (uint result)\n// ^( @addFunction\n//           ^^^ @addSymbol\n    {\n        result = a + b;\n    }\n\n// ^) @addFunction\n    function warningWithUnused() public pure\n    {\n        uint unused;\n    //  ^^^^^^^^^^^ @diagnostics\n    }\n}\n\nstruct RGBColor\n//     ^^^^^^^^ @RGBColorStruct\n{\n    uint8 red;\n    uint8 green;\n    uint8 blue;\n}\n// ----\n// lib: @diagnostics 2072\n"
  },
  {
    "path": "test/libsolidity/lsp/goto/publish_diagnostics_1.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract MyContract\n{\n    constructor()\n    {\n        uint unused; // [Warning 2072] Unused local variable.\n   //   ^^^^^^^^^^^ @unusedVariable\n    }\n}\n\ncontract D\n{\n    function main() public payable returns (uint)\n                                       //   ^^^^ @unusedReturnVariable\n    {\n        MyContract c = new MyContract();\n   //   ^^^^^^^^^^^^ @unusedContractVariable\n    }\n}\n// ----\n// publish_diagnostics_1: @unusedReturnVariable 6321 @unusedVariable 2072 @unusedContractVariable 2072\n"
  },
  {
    "path": "test/libsolidity/lsp/goto/publish_diagnostics_2.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract C\n{\n    function makeSomeError() public pure returns (uint res)\n    {\n        uint x = \"hi\";\n    //  ^^^^^^^^^^^^^ @conversionError\n        return;\n     // ^^^^^^^ @argumentsRequired\n        res = 2;\n    }\n}\n\ncontract D\n{\n    function main() public payable returns (uint)\n    {\n        C c = new C();\n        return c.makeSomeError(2, 3);\n          //   ^^^^^^^^^^^^^^^^^^^^^ @wrongArgumentsCount\n    }\n}\n// ----\n// publish_diagnostics_2: @conversionError 9574 @argumentsRequired 6777 @wrongArgumentsCount 6160\n"
  },
  {
    "path": "test/libsolidity/lsp/hover/hover.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\n/// Documenting another contract here.\ncontract AnotherContract {}\n\n/// User being documented.\ncontract User\n{\n    /// Some enum value.\n    enum SomeEnum\n    {\n        Red,\n        Blue\n    }\n\n    /// publicVariable being documented.\n    SomeEnum public publicVariable;\n//  ^ @Cursor1\n//  ^^^^^^^^ @Cursor1Range\n\n    // not documented\n    mapping(int => User.SomeEnum) someRemapping;\n//                      ^ @Cursor2\n//                      ^^^^^^^^ @Cursor2Range\n\n    /// Documenting the setContract().\n    function setValue(User.SomeEnum _value) public\n//                    ^ @Cursor3\n//                    ^^^^ @Cursor3Range\n    {\n        publicVariable = _value;\n//      ^ @Cursor4\n//      ^^^^^^^^^^^^^^ @Cursor4Range\n    }\n\n    function createAnotherContract() public returns (AnotherContract)\n    {\n        return new AnotherContract();\n//                 ^ @Cursor5\n//                 ^^^^^^^^^^^^^^^ @Cursor5Range\n    }\n}\n// ----\n// -> textDocument/hover {\n//     \"position\": @Cursor1\n// }\n// <- {\n//     \"contents\": {\n//         \"kind\": \"markdown\",\n//         \"value\": \"```solidity\\ntype(enum User.SomeEnum)\\n```\\n\\nSome enum value.\\n\\n\"\n//     },\n//     \"range\": {\n//         \"end\": {\n//             \"character\": 12,\n//             \"line\": 17\n//         },\n//         \"start\": {\n//             \"character\": 4,\n//             \"line\": 17\n//         }\n//     }\n// }\n// -> textDocument/hover {\n//     \"position\": @Cursor2\n// }\n// <- {\n//     \"contents\": {\n//         \"kind\": \"markdown\",\n//         \"value\": \"```solidity\\ntype(enum User.SomeEnum)\\n```\\n\\nSome enum value.\\n\\n\"\n//     },\n//     \"range\": {\n//         \"end\": {\n//             \"character\": 32,\n//             \"line\": 22\n//         },\n//         \"start\": {\n//             \"character\": 24,\n//             \"line\": 22\n//         }\n//     }\n// }\n// -> textDocument/hover {\n//     \"position\": @Cursor3\n// }\n// <- {\n//     \"contents\": {\n//         \"kind\": \"markdown\",\n//         \"value\": \"```solidity\\ntype(contract User)\\n```\\n\\nUser being documented.\\n\\n\"\n//     },\n//     \"range\": @Cursor3Range\n// }\n// -> textDocument/hover {\n//     \"position\": @Cursor4\n// }\n// <- {\n//     \"contents\": {\n//         \"kind\": \"markdown\",\n//         \"value\": \"```solidity\\nenum User.SomeEnum\\n```\\n\\n\"\n//     },\n//     \"range\": @Cursor4Range\n// }\n// -> textDocument/hover {\n//     \"position\": @Cursor5\n// }\n// <- {\n//     \"contents\": {\n//         \"kind\": \"markdown\",\n//         \"value\": \"```solidity\\ntype(contract AnotherContract)\\n```\\n\\nDocumenting another contract here.\\n\\n\"\n//     },\n//     \"range\": @Cursor5Range\n// }\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths/default_include.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nimport \"my-module/test.sol\";\n\ncontract MyContract\n{\n    function f(uint a, uint b) public pure returns (uint)\n    {\n        return MyModule.add(a, b);\n    }\n}\n// ----\n// test:\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths/file_at_include_path.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nimport \"rootlib.sol\";\n\ncontract MyContract\n{\n}\n// ----\n// rootlib:\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths/file_not_found_in_searchpath.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\n   import \"test.sol\";\n// ^^^^^^^^^^^^^^^^^^ @IncludeLocation\n\ncontract SomeContract\n{\n}\n// ----\n// file_not_found_in_searchpath: @IncludeLocation 6275\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths/using-custom-includes.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\n   import \"otherlib/otherlib.sol\";\n// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @NotFound\n\ncontract MyContract\n{\n}\n// ----\n// using-custom-includes: @NotFound 6275\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths-nested/A/B/C/foo.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract C\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths-nested/A/B/foo.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract B\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths-nested/A/foo.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract A\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths-nested/foo.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract RootContract\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths-nested-2/A/B/C/foo.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nimport \"otherlib/second.sol\";\n\ncontract C\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths-nested-2/A/B/foo.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract B\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths-nested-2/A/foo.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract A\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/include-paths-nested-2/foo.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract RootContract\n{\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/other-include-dir/otherlib/otherlib.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nlibrary OtherLib\n{\n    function f(uint n) public returns (uint) { return n + 1; }\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/other-include-dir/otherlib/second.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nlibrary Second\n{\n    function f(uint n) public pure returns (uint) { return n + 1; }\n}\n"
  },
  {
    "path": "test/libsolidity/lsp/publish_diagnostics_3.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nabstract contract A {\n    function a() public virtual;\n}\n\ncontract B is A\n// ^( @notAbstract\n{\n}\n// ^) @notAbstract\n"
  },
  {
    "path": "test/libsolidity/lsp/rename/contract.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract ToRename\n//       ^ @CursorOnContractDefinition\n//       ^^^^^^^^ @ContractInDefinition\n{\n}\n\ncontract User\n//       ^^^^ @UserContractInContractTest\n{\n    ToRename public publicVariable;\n//  ^^^^^^^^ @ContractInPublicVariable\n//         ^ @CursorOnPublicVariableType\n\n    ToRename[10] previousContracts;\n//  ^^^^^^^^ @ContractInArrayType\n//   ^ @CursorOnArrayType\n\n    mapping(int => ToRename) contractMapping;\n    //             ^^^^^^^^ @ContractInMapping\n    //              ^ @CursorOnMapping\n\n    function getContract() public returns (ToRename)\n                                  //       ^^^^^^^^ @ContractInReturnParameter\n//                                            ^ @CursorOnReturnParameter\n    {\n        return new ToRename();\n        //         ^^^^^^^^ @ContractInReturnExpression\n//                    ^ @CursorOnReturnExpression\n    }\n\n    function setContract(ToRename _contract) public\n    //                   ^^^^^^^^ @ContractInParameter\n    //                        ^ @CursorOnParameter\n    {\n        publicVariable = _contract;\n    }\n}\n// ----\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnContractDefinition\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/contract.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnExpression\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInMapping\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInArrayType\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnReturnParameter\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/contract.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnExpression\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInMapping\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInArrayType\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnReturnExpression\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/contract.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnExpression\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInMapping\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInArrayType\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnPublicVariableType\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/contract.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnExpression\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInMapping\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInArrayType\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnArrayType\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/contract.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnExpression\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInMapping\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInArrayType\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnMapping\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/contract.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnExpression\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInMapping\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInArrayType\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnParameter\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/contract.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnExpression\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInMapping\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInArrayType\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInDefinition\n//             }\n//         ]\n//     }\n// }\n"
  },
  {
    "path": "test/libsolidity/lsp/rename/function.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract C\n{\n    function renameMe() public pure returns (int)\n    //       ^^^^^^^^ @FunctionInDefinition\n    //            ^ @CursorInDefinition\n    {\n        return 1;\n    }\n\n    function other() public view\n    {\n        renameMe();\n//      ^^^^^^^^ @FunctionInFunctionSameContract\n//         ^ @CursorInFunctionSameContract\n        this.renameMe();\n     //      ^^^^^^^^ @FunctionInFunctionSameContractExternal\n         //         ^ @CursorInFunctionSameContractExternal\n    }\n}\n\ncontract Other\n{\n    C m_contract;\n\n    function other() public view\n    {\n        m_contract.renameMe();\n           //      ^^^^^^^^ @FunctionInFunctionOtherContract\n        //         ^ @CursorInFunctionOtherContract\n    }\n}\n\nfunction free() pure\n{\n    C local_contract;\n    local_contract.renameMe();\n           //      ^^^^^^^^ @FunctionInFreeFunction\n        //         ^ @CursorInFreeFunction\n}\n// ----\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorInDefinition\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/function.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFreeFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionOtherContract\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionSameContractExternal\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionSameContract\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorInFunctionOtherContract\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/function.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFreeFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionOtherContract\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionSameContractExternal\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionSameContract\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorInFunctionSameContractExternal\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/function.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFreeFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionOtherContract\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionSameContractExternal\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionSameContract\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorInFunctionSameContract\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/function.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFreeFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionOtherContract\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionSameContractExternal\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionSameContract\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorInFreeFunction\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/function.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFreeFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionOtherContract\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionSameContractExternal\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInFunctionSameContract\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FunctionInDefinition\n//             }\n//         ]\n//     }\n// }\n"
  },
  {
    "path": "test/libsolidity/lsp/rename/functionCall.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract C\n{\n    function foo(int a, int b, int c) pure public returns(int)\n    //                      ^ @ParameterB\n    //               ^ @ParameterA\n    //                             ^ @ParameterC\n    {\n        return a + b + c;\n        //         ^ @ParameterBInFoo\n        //     ^ @ParameterAInFoo\n        //             ^ @ParameterCInFoo\n\n    }\n\n    function bar() public view\n    {\n        this.foo({c:1, b:2, a:3});\n        //             ^ @ParameterBInCall\n        //        ^ @ParameterCInCall\n        //                  ^ @ParameterAInCall\n    }\n}\n// ----\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @ParameterA\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/functionCall.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterAInCall\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterAInFoo\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterA\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @ParameterAInCall\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/functionCall.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterAInCall\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterAInFoo\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterA\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @ParameterAInFoo\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/functionCall.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterAInCall\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterAInFoo\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterA\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @ParameterC\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/functionCall.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterCInCall\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterCInFoo\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterC\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @ParameterCInCall\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/functionCall.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterCInCall\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterCInFoo\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterC\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @ParameterCInFoo\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/functionCall.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterCInCall\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterCInFoo\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterC\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @ParameterBInCall\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/functionCall.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterBInCall\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterBInFoo\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterB\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @ParameterBInFoo\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/functionCall.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterBInCall\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterBInFoo\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ParameterB\n//             }\n//         ]\n//     }\n// }\n"
  },
  {
    "path": "test/libsolidity/lsp/rename/import_directive.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nimport \"./contract.sol\" as externalFile;\n//                         ^^^^^^^^^^^^ @FileAliasInImportDirective\n//                             ^ @CursorOnFileAliasInImportDirective\nimport {ToRename as ExternalContract, User} from \"./contract.sol\";\n//                  ^^^^^^^^^^^^^^^^ @RenamedContractInImportDirective\n//                         ^ @CursorOnRenamedContractInImportDirective\n//      ^^^^^^^^ @OriginalNameInImportDirective\n//      ^ @CursorOnOriginalNameInImportDirective\n//                                    ^^^^ @UserInImportDirective\n//                                    ^ @CursorOnUserInImportDirective\n\ncontract C\n{\n    ExternalContract public externalContract;\n//  ^^^^^^^^^^^^^^^^ @RenamedContractInPublicVariable\n//        ^ @CursorOnRenamedContractInPublicVariable\n    externalFile.ToRename public externalFileContract;\n//  ^^^^^^^^^^^^ @FileAliasInPublicVariable\n//  ^ @CursorOnFileAliasInPublicVariable\n//               ^^^^^^^^ @OriginalNameInPublicVariable\n//                      ^ @CursorOnOriginalNameInPublicVariable\n    User public externalUserContract;\n//  ^^^^ @UserInPublicVariable\n//     ^ @CursorOnUserInPublicVariable\n}\n// ----\n// contract:\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnFileAliasInImportDirective\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/import_directive.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FileAliasInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FileAliasInImportDirective\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnRenamedContractInImportDirective\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/import_directive.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @RenamedContractInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @RenamedContractInImportDirective\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnOriginalNameInImportDirective\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/contract.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnExpression\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInMapping\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInArrayType\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInDefinition\n//             }\n//         ],\n//         \"rename/import_directive.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @OriginalNameInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @OriginalNameInImportDirective\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnRenamedContractInPublicVariable\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/import_directive.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @RenamedContractInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @RenamedContractInImportDirective\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnFileAliasInPublicVariable\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/import_directive.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FileAliasInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @FileAliasInImportDirective\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnOriginalNameInPublicVariable\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/contract.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnExpression\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInReturnParameter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInMapping\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInArrayType\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @ContractInDefinition\n//             }\n//         ],\n//         \"rename/import_directive.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @OriginalNameInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @OriginalNameInImportDirective\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnUserInPublicVariable\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/contract.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @UserContractInContractTest\n//             }\n//         ],\n//         \"rename/import_directive.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @UserInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @UserInImportDirective\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnUserInImportDirective\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/contract.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @UserContractInContractTest\n//             }\n//         ],\n//         \"rename/import_directive.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @UserInPublicVariable\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @UserInImportDirective\n//             }\n//         ]\n//     }\n// }\n"
  },
  {
    "path": "test/libsolidity/lsp/rename/variable.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract C\n{\n    int public renameMe;\n    //         ^^^^^^^^ @VariableInDefinition\n    //         ^ @CursorOnVariableDefinition\n\n    function foo() public returns(int)\n    {\n        renameMe = 1;\n//      ^^^^^^^^ @VariableInFunction\n//             ^ @CursorOnVariableInFunction\n        return this.renameMe();\n//                  ^^^^^^^^ @VariableInGetter\n//                     ^ @CursorOnVariableInGetter\n    }\n}\n\nfunction freeFunction(C _contract) view returns(int)\n{\n    return _contract.renameMe();\n    //               ^^^^^^^^ @VariableInFreeFunction\n    //                 ^ @CursorOnVariableInFreeFunction\n}\n// ----\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnVariableInFunction\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/variable.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInFreeFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInGetter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnVariableDefinition\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/variable.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInFreeFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInGetter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnVariableInGetter\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/variable.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInFreeFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInGetter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInDefinition\n//             }\n//         ]\n//     }\n// }\n// -> textDocument/rename {\n//     \"newName\": \"Renamed\",\n//     \"position\": @CursorOnVariableInFreeFunction\n// }\n// <- {\n//     \"changes\": {\n//         \"rename/variable.sol\": [\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInFreeFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInGetter\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInFunction\n//             },\n//             {\n//                 \"newText\": \"Renamed\",\n//                 \"range\": @VariableInDefinition\n//             }\n//         ]\n//     }\n// }\n"
  },
  {
    "path": "test/libsolidity/lsp/semanticTokens/enums.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nenum Weather {\n    Sunny,\n    Cloudy,\n    Rainy\n}\n\nenum Color {\n    Red,\n    Green,\n    Blue\n}\n\nfunction getColorEnum() pure returns (Color result)\n{\n    result = Color.Red;\n}\n// ----\n// -> textDocument/semanticTokens/full {\n// }\n// <- {\n//     \"data\": [\n//         1, 0, 24, 8, 0,\n//         2, 5, 7, 2, 0,\n//         1, 4, 5, 3, 0,\n//         1, 4, 6, 3, 0,\n//         1, 4, 5, 3, 0,\n//         3, 5, 5, 2, 0,\n//         1, 4, 3, 3, 0,\n//         1, 4, 5, 3, 0,\n//         1, 4, 4, 3, 0,\n//         3, 9, 12, 5, 0,\n//         0, 29, 5, 2, 0,\n//         0, 6, 6, 19, 0,\n//         2, 4, 6, 2, 0,\n//         0, 9, 5, 2, 0,\n//         0, 6, 3, 3, 0\n//     ]\n// }\n"
  },
  {
    "path": "test/libsolidity/lsp/semanticTokens/functions.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nlibrary Lib\n{\n    function add(uint a, uint b) public pure returns (uint result)\n    {\n        result = a + b;\n    }\n\n    function warningWithUnused() public pure\n    {\n        uint unused;\n//      ^^^^^^^^^^^ @unusedVariable\n    }\n}\n\ncontract Contract\n{\n    function doNothing() pure public returns (bool)\n    {\n        return true;\n    }\n}\n// ----\n// functions: @unusedVariable 2072\n// -> textDocument/semanticTokens/full {\n// }\n// <- {\n//     \"data\": [\n//         1, 0, 24, 8, 0,\n//         2, 8, 3, 0, 0,\n//         2, 13, 3, 5, 0,\n//         0, 4, 4, 11, 0,\n//         0, 5, 1, 19, 0,\n//         0, 3, 4, 11, 0,\n//         0, 5, 1, 19, 0,\n//         0, 24, 4, 11, 0,\n//         0, 5, 6, 19, 0,\n//         2, 8, 6, 19, 0,\n//         0, 9, 1, 19, 0,\n//         0, 4, 1, 19, 0,\n//         3, 13, 17, 5, 0,\n//         2, 8, 4, 11, 0,\n//         0, 5, 6, 19, 0,\n//         5, 9, 8, 0, 0,\n//         2, 13, 9, 5, 0,\n//         0, 33, 4, 11, 0,\n//         2, 15, 4, 11, 0\n//     ]\n// }\n"
  },
  {
    "path": "test/libsolidity/lsp/semanticTokens/modifiers.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\ncontract C\n{\n    bool public locked = false;\n    int public calls = 0;\n    int public totalSum = 0;\n\n    function add(uint a, uint b) lock() monitor(a, b) public returns (uint result)\n    {\n        result = a + b;\n    }\n\n    modifier lock()\n    {\n        require(!locked);\n        locked = true;\n        _;\n        locked = false;\n    }\n\n    modifier monitor(uint a, uint b)\n    {\n        calls++;\n        totalSum = totalSum + a + b;\n        //         ^^^^^^^^^^^^^^^^ @totalSumWarning\n        //         ^^^^^^^^^^^^ @totalSumWarningSub\n        _;\n    }\n}\n// ----\n// modifiers: @totalSumWarningSub 2271 @totalSumWarning 2271\n// -> textDocument/semanticTokens/full {\n// }\n// <- {\n//     \"data\": [\n//         1, 0, 24, 8, 0,\n//         2, 9, 1, 0, 0,\n//         2, 4, 4, 11, 0,\n//         0, 12, 6, 19, 0,\n//         0, 9, 5, 11, 0,\n//         1, 4, 3, 11, 0,\n//         0, 11, 5, 19, 0,\n//         0, 8, 1, 11, 0,\n//         1, 4, 3, 11, 0,\n//         0, 11, 8, 19, 0,\n//         0, 11, 1, 11, 0,\n//         2, 13, 3, 5, 0,\n//         0, 4, 4, 11, 0,\n//         0, 5, 1, 19, 0,\n//         0, 3, 4, 11, 0,\n//         0, 5, 1, 19, 0,\n//         0, 40, 4, 11, 0,\n//         0, 5, 6, 19, 0,\n//         0, -42, 4, 19, 0,\n//         0, 7, 7, 19, 0,\n//         0, 8, 1, 19, 0,\n//         0, 3, 1, 19, 0,\n//         2, 8, 6, 19, 0,\n//         0, 9, 1, 19, 0,\n//         0, 4, 1, 19, 0,\n//         3, 13, 4, 10, 0,\n//         2, 8, 7, 19, 0,\n//         0, 9, 6, 19, 0,\n//         1, 8, 6, 19, 0,\n//         0, 9, 4, 11, 0,\n//         2, 8, 6, 19, 0,\n//         0, 9, 5, 11, 0,\n//         3, 13, 7, 10, 0,\n//         0, 8, 4, 11, 0,\n//         0, 5, 1, 19, 0,\n//         0, 3, 4, 11, 0,\n//         0, 5, 1, 19, 0,\n//         2, 8, 5, 19, 0,\n//         1, 8, 8, 19, 0,\n//         0, 11, 8, 19, 0,\n//         0, 11, 1, 19, 0,\n//         0, 4, 1, 19, 0\n//     ]\n// }\n"
  },
  {
    "path": "test/libsolidity/lsp/semanticTokens/structs.sol",
    "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\nstruct Tag\n{\n    uint id;\n    string name;\n}\n\nstruct RGBColor\n{\n    uint8 red;\n    uint8 green;\n    uint8 blue;\n    Tag tag;\n}\n\nfunction memberAccess(RGBColor memory color) pure returns(uint)\n{\n    return color.red + color.green + color.blue;\n}\n// ----\n// -> textDocument/semanticTokens/full {\n// }\n// <- {\n//     \"data\": [\n//         1, 0, 24, 8, 0,\n//         4, 4, 4, 11, 0,\n//         0, 5, 2, 19, 0,\n//         1, 4, 6, 17, 0,\n//         0, 7, 4, 19, 0,\n//         5, 4, 5, 11, 0,\n//         0, 6, 3, 19, 0,\n//         1, 4, 5, 11, 0,\n//         0, 6, 5, 19, 0,\n//         1, 4, 5, 11, 0,\n//         0, 6, 4, 19, 0,\n//         1, 4, 3, 16, 0,\n//         0, 4, 3, 19, 0,\n//         3, 9, 12, 5, 0,\n//         0, 13, 8, 16, 0,\n//         0, 16, 5, 19, 0,\n//         0, 20, 4, 11, 0,\n//         2, 17, 3, 19, 0,\n//         0, 12, 5, 19, 0,\n//         0, 14, 4, 19, 0\n//     ]\n// }\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/comment/constructor_safe_deploy_unsafe.sol",
    "content": "contract C {\n    constructor() {\n        uint256 x;\n        assembly { x := 0 }\n        f();\n    }\n    function f() internal pure {\n        /// @solidity memory-safe-assembly\n        assembly { mstore(0, 0) }\n    }\n    function g() public pure {\n        assembly { mstore(0, 0) }\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) false\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/comment/constructor_unsafe_deploy_safe.sol",
    "content": "contract C {\n    constructor() {\n        uint256 x;\n        assembly { x := 0 }\n        f();\n    }\n    function f() internal pure {\n        assembly { mstore(0, 0) }\n    }\n    function g() public pure {\n        /// @solidity memory-safe-assembly\n        assembly { mstore(0, 0) }\n    }\n}\n// ----\n// :C(creation) false\n// :C(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/comment/free_function.sol",
    "content": "function safe() pure returns (uint256 x) {\n    assembly { x := 42 }\n    /// @solidity memory-safe-assembly\n    assembly { mstore(0, 0) }\n}\nfunction unsafe() pure returns (uint256 x) {\n    assembly { pop(mload(0)) }\n}\ncontract C {\n    constructor() {\n        unsafe();\n    }\n    function f() public pure {\n        safe();\n    }\n}\ncontract D {\n    constructor() {\n        safe();\n    }\n    function f() public pure {\n        unsafe();\n    }\n}\n// ----\n// :C(creation) false\n// :C(runtime) true\n// :D(creation) true\n// :D(runtime) false\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/comment/multi_annotation.sol",
    "content": "contract C {\n    constructor() {\n        /// @solidity memory-safe-assembly    a memory-safe-assembly\n        assembly { mstore(0, 0) }\n    }\n    function f() internal pure {\n        /// @solidity a memory-safe-assembly\n        assembly { mstore(0, 0) }\n        /// @solidity a\n        ///           memory-safe-assembly\n        ///           b\n        assembly { mstore(0, 0) }\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/comment/multiple_contracts.sol",
    "content": "contract C {\n    constructor(uint256 x) {\n        assembly { x := 4 }\n        /// @solidity memory-safe-assembly\n        assembly { mstore(0, 0) }\n    }\n    function f() public pure {\n        assembly { mstore(0,0) }\n    }\n}\ncontract D {\n    constructor() {\n        assembly { mstore(0,0) }\n    }\n    function f(uint256 x) public pure {\n        assembly { x := 4 }\n        /// @solidity memory-safe-assembly\n        assembly { mstore(0, 0) }\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) false\n// :D(creation) false\n// :D(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/comment/safe_and_unmarked_empty.sol",
    "content": "contract C {\n    function f() external pure {\n        /// @solidity memory-safe-assembly\n        assembly {}\n        assembly {}\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/comment/safe_and_unmarked_unsafe.sol",
    "content": "contract C {\n    function f() external pure {\n        /// @solidity memory-safe-assembly\n        assembly {}\n        assembly { mstore(0,0) }\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) false\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/dialectString/constructor_safe_deploy_unsafe.sol",
    "content": "contract C {\n    constructor() {\n        uint256 x;\n        assembly { x := 0 }\n        f();\n    }\n    function f() internal pure {\n        assembly \"evmasm\" (\"memory-safe\") { mstore(0, 0) }\n        assembly (\"memory-safe\") { mstore(0, 0) }\n    }\n    function g() public pure {\n        assembly { mstore(0, 0) }\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) false\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/dialectString/constructor_unsafe_deploy_safe.sol",
    "content": "contract C {\n    constructor() {\n        uint256 x;\n        assembly { x := 0 }\n        f();\n    }\n    function f() internal pure {\n        assembly { mstore(0, 0) }\n    }\n    function g() public pure {\n        assembly \"evmasm\" (\"memory-safe\") { mstore(0, 0) }\n    }\n}\n// ----\n// :C(creation) false\n// :C(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/dialectString/free_function.sol",
    "content": "function safe() pure returns (uint256 x) {\n    assembly { x := 42 }\n    assembly \"evmasm\" (\"memory-safe\") { mstore(0, 0) }\n}\nfunction unsafe() pure returns (uint256 x) {\n    assembly { pop(mload(0)) }\n}\ncontract C {\n    constructor() {\n        unsafe();\n    }\n    function f() public pure {\n        safe();\n    }\n}\ncontract D {\n    constructor() {\n        safe();\n    }\n    function f() public pure {\n        unsafe();\n    }\n}\n// ----\n// :C(creation) false\n// :C(runtime) true\n// :D(creation) true\n// :D(runtime) false\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/dialectString/multiple_contracts.sol",
    "content": "contract C {\n    constructor(uint256 x) {\n        assembly { x := 4 }\n        assembly \"evmasm\" (\"memory-safe\") { mstore(0, 0) }\n    }\n    function f() public pure {\n        assembly { mstore(0,0) }\n    }\n}\ncontract D {\n    constructor() {\n        assembly { mstore(0,0) }\n    }\n    function f(uint256 x) public pure {\n        assembly { x := 4 }\n        assembly (\"memory-safe\") { mstore(0, 0) }\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) false\n// :D(creation) false\n// :D(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/dialectString/safe_and_unmarked_empty.sol",
    "content": "contract C {\n    function f() external pure {\n        assembly \"evmasm\" (\"memory-safe\") {}\n        assembly {}\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/dialectString/safe_and_unmarked_unsafe.sol",
    "content": "contract C {\n    function f() external pure {\n        assembly \"evmasm\" (\"memory-safe\") {}\n        assembly { mstore(0,0) }\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) false\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/dialectString/stub.sol",
    "content": "contract C {}\n// ----\n// :C(creation) true\n// :C(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/marked_empty.sol",
    "content": "contract C {\n    constructor() {\n        assembly (\"memory-safe\") {}\n    }\n\n    function f() public {\n        assembly (\"memory-safe\") {}\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/marked_with_memory_access.sol",
    "content": "contract C {\n    constructor() {\n        assembly (\"memory-safe\") {\n            mstore(0, 1)\n        }\n    }\n\n    function store() public {\n        assembly (\"memory-safe\") {\n            mstore(0, 1)\n        }\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/shadowing_memoryguard_with_inline_assembly_identifiers.sol",
    "content": "// NOTE: memoryguard is a builtin but only in pure Yul, not inline assembly.\n// NOTE: memoryguard is not a reserved identifier.\n\ncontract C {\n    constructor() {\n        // The expectation of this test is to see a 'true' outcome, indicating the memoryguard builtin being used\n        // due to explicitly marking the inline assembly as memory-safe\n\n        assembly (\"memory-safe\") { mstore(42, 42) function memoryguard() {} }\n        assembly (\"memory-safe\") { mstore(42, 42) function f(memoryguard) {} }\n        assembly (\"memory-safe\") { mstore(42, 42) function f() -> memoryguard {} }\n        assembly (\"memory-safe\") { mstore(42, 42) let memoryguard }\n    }\n\n    function f() public pure {\n        // The expectation of this test is to see a 'false' outcome, indicating the memoryguard builtin not being used\n\n        assembly { mstore(42, 42) function memoryguard() {} }\n        assembly { mstore(42, 42) function f(memoryguard) {} }\n        assembly { mstore(42, 42) function f() -> memoryguard {} }\n        assembly { mstore(42, 42) let memoryguard }\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) false\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/stub.sol",
    "content": "contract C {}\n// ----\n// :C(creation) true\n// :C(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/unmarked_but_no_memory_access.sol",
    "content": "contract C {\n    function f(uint256 x, uint256 y) public pure returns (uint256 z){\n        assembly { z := add(x, y) }\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/unmarked_empty.sol",
    "content": "contract C {\n    constructor() {\n        assembly {}\n    }\n\n    function f() public {\n        assembly {}\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) true\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/unmarked_with_memory_access_mcopy.sol",
    "content": "contract C {\n    constructor() {\n        assembly {\n            mcopy(1000, 2000, 1000)\n        }\n    }\n\n    function copy() public {\n        assembly {\n            mcopy(1000, 2000, 1000)\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// :C(creation) false\n// :C(runtime) false\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/unmarked_with_memory_access_mcopy_zero_size.sol",
    "content": "contract C {\n    constructor() {\n        assembly {\n            mcopy(1000, 2000, 0)\n        }\n    }\n\n    function copy() public {\n        assembly {\n            mcopy(1000, 2000, 0)\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// :C(creation) false\n// :C(runtime) false\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/unmarked_with_memory_access_mstore.sol",
    "content": "contract C {\n    constructor() {\n        assembly {\n            mstore(0, 1)\n        }\n    }\n\n    function store() public {\n        assembly {\n            mstore(0, 1)\n        }\n    }\n}\n// ----\n// :C(creation) false\n// :C(runtime) false\n"
  },
  {
    "path": "test/libsolidity/memoryGuardTests/unmarked_with_memory_assignment.sol",
    "content": "contract C {\n    function f() public pure {\n        bytes memory x;\n        assembly {\n            x := 0\n        }\n    }\n}\n// ----\n// :C(creation) true\n// :C(runtime) false\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/custom.sol",
    "content": "/// @custom:x one two three\n/// @custom:y line\n/// break\n/// @custom:t one\n/// @custom:t two\ncontract A {\n    /// @custom:note statevar\n    uint x;\n    /// @custom:since 2014\n    function g(int x) public pure virtual returns (int, int) { return (1, 2); }\n}\n\n// ----\n// ----\n// :A devdoc\n// {\n//     \"custom:t\": \"onetwo\",\n//     \"custom:x\": \"one two three\",\n//     \"custom:y\": \"line break\",\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(int256)\":\n//         {\n//             \"custom:since\": \"2014\"\n//         }\n//     },\n//     \"stateVariables\":\n//     {\n//         \"x\":\n//         {\n//             \"custom:note\": \"statevar\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :A userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/custom_inheritance.sol",
    "content": "contract A {\n    /// @custom:since 2014\n    function g(uint x) public pure virtual {}\n}\ncontract B is A {\n    function g(uint x) public pure override {}\n}\n\n// ----\n// ----\n// :A devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(uint256)\":\n//         {\n//             \"custom:since\": \"2014\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :A userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_and_user_basic_test.sol",
    "content": "contract test {\n    /// @notice Multiplies `a` by 7\n    /// @dev Multiplies a number by 7\n    function mul(uint a) public returns (uint d) { return a * 7; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"mul(uint256)\":\n//         {\n//             \"notice\": \"Multiplies `a` by 7\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_and_user_no_doc.sol",
    "content": "contract test {\n    function mul(uint a) public returns (uint d) {\n        return a * 7;\n    }\n    function sub(int input) public returns (int d) {\n        return input - 3;\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_author_at_function.sol",
    "content": "/// @author Lefteris\n/// @title Just a test contract\ncontract test {\n    /// @dev Mul function\n    /// @author John Doe\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// DocstringParsingError 6546: (73-119): Documentation tag @author not valid for functions.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_constructor.sol",
    "content": "contract test {\n    /// @param a the parameter a is really nice and very useful\n    /// @param second the second parameter is not very useful, it just provides additional confusion\n    constructor(uint a, uint second) { }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"constructor\":\n//         {\n//             \"params\":\n//             {\n//                 \"a\": \"the parameter a is really nice and very useful\",\n//                 \"second\": \"the second parameter is not very useful, it just provides additional confusion\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_constructor_and_function.sol",
    "content": "contract test {\n    /// @param a the parameter a is really nice and very useful\n    /// @param second the second parameter is not very useful, it just provides additional confusion\n    constructor(uint a, uint second) { }\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter starts here.\n    /// Since it's a really complicated parameter we need 2 lines\n    /// @param second Documentation for the second parameter\n    /// @return d The result of the multiplication\n    /// and cookies with nutella\n    function mul(uint a, uint second) public returns(uint d) {\n        return a * 7 + second;\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"constructor\":\n//         {\n//             \"params\":\n//             {\n//                 \"a\": \"the parameter a is really nice and very useful\",\n//                 \"second\": \"the second parameter is not very useful, it just provides additional confusion\"\n//             }\n//         },\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             },\n//             \"returns\":\n//             {\n//                 \"d\": \"The result of the multiplication and cookies with nutella\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_constructor_return.sol",
    "content": "contract test {\n    /// @param a the parameter a is really nice and very useful\n    /// @param second the second parameter is not very useful, it just provides additional confusion\n    /// @return return should not work within constructors\n    constructor(uint a, uint second) { }\n}\n\n// ----\n// DocstringParsingError 6546: (20-239): Documentation tag @return not valid for constructor.\n// DocstringParsingError 2604: (20-239): Documentation tag \"@return return should not work within constructors\" exceeds the number of return parameters.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_contract_doc.sol",
    "content": "/// @author Lefteris\n/// @title Just a test contract\ncontract test {\n    /// @dev Mul function\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"author\": \"Lefteris\",\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Mul function\"\n//         }\n//     },\n//     \"title\": \"Just a test contract\",\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_contract_no_doc.sol",
    "content": "contract test {\n    /// @dev Mul function\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Mul function\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_default_inherit.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// Second line.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract Middle is ERC20 {\n    function transfer(address to, uint amount) virtual override external returns (bool)\n    {\n    return false;\n    }\n}\n\ncontract Token is Middle {\n    function transfer(address to, uint amount) override external returns (bool)\n    {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``. Second line.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Middle devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Middle userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``. Second line.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``. Second line.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_default_inherit_variable.sol",
    "content": "contract C {\n    /// @notice Hello world\n    /// @dev test\n    function x() virtual external returns (uint) {\n        return 1;\n    }\n}\n\ncontract D is C {\n    uint public override x;\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"details\": \"test\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"notice\": \"Hello world\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :D devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"x\":\n//         {\n//             \"details\": \"test\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :D userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"notice\": \"Hello world\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_desc_after_nl.sol",
    "content": "contract test {\n    /// @dev\n    /// Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter\n    /// @param second Documentation for the second parameter\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_different_return_name.sol",
    "content": "contract A {\n    /// @return y value\n    function g(int x) public pure virtual returns (int y) { return x; }\n}\n\ncontract B is A {\n    function g(int x) public pure override returns (int z) { return x; }\n}\n\n// ----\n// ----\n// :A devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(int256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"y\": \"value\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :A userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(int256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"z\": \"value\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :B userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_different_return_name_multiple.sol",
    "content": "contract A {\n    /// @return a value A\n    /// @return b value B\n    function g(int x) public pure virtual returns (int a, int b) { return (1, 2); }\n}\n\ncontract B is A {\n    function g(int x) public pure override returns (int z, int y) { return (1, 2); }\n}\n\n// ----\n// ----\n// :A devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(int256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"a\": \"value A\",\n//                 \"b\": \"value B\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :A userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(int256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"y\": \"value B\",\n//                 \"z\": \"value A\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :B userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_different_return_name_multiple_partly_unnamed.sol",
    "content": "contract A {\n    /// @return value A\n    /// @return b value B\n    function g(int x) public pure virtual returns (int, int b) { return (1, 2); }\n}\n\ncontract B is A {\n    function g(int x) public pure override returns (int z, int) { return (1, 2); }\n}\n\n// ----\n// ----\n// :A devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(int256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"_0\": \"value A\",\n//                 \"b\": \"value B\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :A userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(int256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"_1\": \"value B\",\n//                 \"z\": \"value A\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :B userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_different_return_name_multiple_unnamed.sol",
    "content": "contract A {\n    /// @return value A\n    /// @return value B\n    function g(int x) public pure virtual returns (int, int) { return (1, 2); }\n}\n\ncontract B is A {\n    function g(int x) public pure override returns (int z, int y) { return (1, 2); }\n}\n\n// ----\n// ----\n// :A devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(int256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"_0\": \"value A\",\n//                 \"_1\": \"value B\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :A userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(int256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"y\": \"value B\",\n//                 \"z\": \"value A\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :B userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_documenting_no_param_description.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter\n    /// @param second\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// DocstringParsingError 9942: (20-156): No description given for param second\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_documenting_no_param_name.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter\n    /// @param\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// DocstringParsingError 3335: (20-149): No param name given\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_documenting_no_param_name_end.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter\n    /// @param se\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// DocstringParsingError 9942: (20-152): No description given for param se\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_documenting_no_return_param_name.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter\n    /// @param second Documentation for the second parameter\n    /// @return\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// DocstringParsingError 5856: (20-211): Documentation tag \"@return \" does not contain the name of its return parameter.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_documenting_nonexistent_param.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter\n    /// @param not_existing Documentation for the second parameter\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// DocstringParsingError 3881: (20-201): Documented parameter \"not_existing\" not found in the parameter list of the function.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_explicit_inherit.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract ERC21 {\n    function transfer(address to, uint amount) virtual external returns (bool) {\n        return false;\n    }\n}\n\ncontract Token is ERC21, ERC20 {\n    /// @inheritdoc ERC20\n    function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :ERC21 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_explicit_inherit2.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract ERC21 is ERC20 {\n    function transfer(address to, uint amount) virtual override external returns (bool) {\n        return false;\n    }\n}\n\ncontract Token is ERC20 {\n    /// @inheritdoc ERC20\n    function transfer(address to, uint amount) override external returns (bool) {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_explicit_inherit_complex.sol",
    "content": "==== Source: Interfaces.sol ====\ninterface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ninterface ERC21 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test2\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\n==== Source: Testfile.sol ====\nimport \"Interfaces.sol\" as myInterfaces;\n\ncontract Token is myInterfaces.ERC20, myInterfaces.ERC21 {\n    /// @inheritdoc myInterfaces.ERC20\n    function transfer(address too, uint amount)\n        override(myInterfaces.ERC20, myInterfaces.ERC21) external returns (bool) {\n        return false;\n    }\n}\n\n// ----\n// ----\n// Interfaces.sol:ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// Interfaces.sol:ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// Interfaces.sol:ERC21 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test2\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// Interfaces.sol:ERC21 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// Testfile.sol:Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// Testfile.sol:Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_explicit_inherit_partial.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract ERC21 {\n    function transfer(address to, uint amount) virtual external returns (bool) {\n        return false;\n    }\n}\n\ncontract Token is ERC21, ERC20 {\n    /// @inheritdoc ERC20\n    /// @dev override dev comment\n    /// @notice override notice\n    function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :ERC21 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"override dev comment\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"override notice\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_explicit_inherit_partial2.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract ERC21 is ERC20 {\n    /// @inheritdoc ERC20\n    /// @dev override dev comment\n    /// @notice override notice\n    function transfer(address to, uint amount) virtual override external returns (bool) {\n        return false;\n    }\n}\n\ncontract Token is ERC21 {\n    function transfer(address to, uint amount) override external returns (bool) {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"override dev comment\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"override notice\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"override dev comment\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"override notice\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_explicit_inherit_variable.sol",
    "content": "contract B {\n    function x() virtual external returns (uint) {\n        return 1;\n    }\n}\n\ncontract C {\n    /// @notice Hello world\n    /// @dev test\n    function x() virtual external returns (uint) {\n        return 1;\n    }\n}\n\ncontract D is C, B {\n    /// @inheritdoc C\n    uint public override(C, B) x;\n}\n\n// ----\n// ----\n// :B devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"details\": \"test\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"notice\": \"Hello world\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :D devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"x\":\n//         {\n//             \"details\": \"test\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :D userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"notice\": \"Hello world\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_inherit_parameter_mismatch.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract Middle is ERC20 {\n    function transfer(address to, uint amount) override virtual external returns (bool) {\n        return false;\n    }\n}\n\ncontract Token is Middle {\n    function transfer(address too, uint amount) override external returns (bool) {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Middle devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Middle userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_multiline_comment.sol",
    "content": "contract test {\n    /**\n     * @dev Multiplies a number by 7 and adds second parameter\n     * @param a Documentation for the first parameter starts here.\n     * Since it's a really complicated parameter we need 2 lines\n     * @param second Documentation for the second parameter\n     * @return d The result of the multiplication\n     * and cookies with nutella\n     */\n    function mul(uint a, uint second) public returns (uint d) {\n        return a * 7 + second;\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             },\n//             \"returns\":\n//             {\n//                 \"d\": \"The result of the multiplication and cookies with nutella\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_multiline_param_description.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter starts here.\n    /// Since it's a really complicated parameter we need 2 lines\n    /// @param second Documentation for the second parameter\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_multiline_return.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter starts here.\n    /// Since it's a really complicated parameter we need 2 lines\n    /// @param second Documentation for the second parameter\n    /// @return d The result of the multiplication\n    /// and cookies with nutella\n    function mul(uint a, uint second) public returns (uint d) {\n        return a * 7 + second;\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             },\n//             \"returns\":\n//             {\n//                 \"d\": \"The result of the multiplication and cookies with nutella\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_multiple_functions.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter\n    /// @param second Documentation for the second parameter\n    function mul(uint a, uint second) public returns (uint d) {\n        return a * 7 + second;\n    }\n    /// @dev Divides 2 numbers\n    /// @param input Documentation for the input parameter\n    /// @param div Documentation for the div parameter\n    function divide(uint input, uint div) public returns (uint d) {\n        return input / div;\n    }\n    /// @dev Subtracts 3 from `input`\n    /// @param input Documentation for the input parameter\n    function sub(int input) public returns (int d) {\n        return input - 3;\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"divide(uint256,uint256)\":\n//         {\n//             \"details\": \"Divides 2 numbers\",\n//             \"params\":\n//             {\n//                 \"div\": \"Documentation for the div parameter\",\n//                 \"input\": \"Documentation for the input parameter\"\n//             }\n//         },\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             }\n//         },\n//         \"sub(int256)\":\n//         {\n//             \"details\": \"Subtracts 3 from `input`\",\n//             \"params\":\n//             {\n//                 \"input\": \"Documentation for the input parameter\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_multiple_params.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter\n    /// @param second Documentation for the second parameter\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_multiple_params_mixed_whitespace.sol",
    "content": "contract test {\n  /// @dev Multiplies a number by 7 and adds second parameter\n  /// @param a Documentation for the first parameter\n  /// @param second Documentation for the second parameter\n  function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_return.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter starts here.\n    /// Since it's a really complicated parameter we need 2 lines\n    /// @param second Documentation for the second parameter\n    /// @return d The result of the multiplication\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             },\n//             \"returns\":\n//             {\n//                 \"d\": \"The result of the multiplication\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_return_desc_after_nl.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter starts here.\n    /// Since it's a really complicated parameter we need 2 lines\n    /// @param second Documentation for the second parameter\n    /// @return\n    /// d The result of the multiplication\n    function mul(uint a, uint second) public returns (uint d) {\n        return a * 7 + second;\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             },\n//             \"returns\":\n//             {\n//                 \"d\": \"The result of the multiplication\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_return_desc_multiple.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter starts here.\n    /// Since it's a really complicated parameter we need 2 lines\n    /// @param second Documentation for the second parameter\n    /// @return d The result of the multiplication\n    /// @return f And cookies with nutella\n    function mul(uint a, uint second) public returns (uint d, uint f) {\n        uint mul = a * 7;\n        return (mul, second);\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             },\n//             \"returns\":\n//             {\n//                 \"d\": \"The result of the multiplication\",\n//                 \"f\": \"And cookies with nutella\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_return_desc_multiple_unnamed.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter starts here.\n    /// Since it's a really complicated parameter we need 2 lines\n    /// @param second Documentation for the second parameter\n    /// @return The result of the multiplication\n    /// @return And cookies with nutella\n    function mul(uint a, uint second) public returns (uint, uint) {\n        uint mul = a * 7;\n        return (mul, second);\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             },\n//             \"returns\":\n//             {\n//                 \"_0\": \"The result of the multiplication\",\n//                 \"_1\": \"And cookies with nutella\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_return_desc_multiple_unnamed_mixed.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter starts here.\n    /// Since it's a really complicated parameter we need 2 lines\n    /// @param second Documentation for the second parameter\n    /// @return The result of the multiplication\n    /// @return _cookies And cookies with nutella\n    function mul(uint a, uint second) public returns (uint, uint _cookies) {\n        uint mul = a * 7;\n        return (mul, second);\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             },\n//             \"returns\":\n//             {\n//                 \"_0\": \"The result of the multiplication\",\n//                 \"_cookies\": \"And cookies with nutella\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_return_desc_multiple_unnamed_mixed_2.sol",
    "content": "contract test {\n    /// @dev Multiplies a number by 7 and adds second parameter\n    /// @param a Documentation for the first parameter starts here.\n    /// Since it's a really complicated parameter we need 2 lines\n    /// @param second Documentation for the second parameter\n    /// @return _cookies And cookies with nutella\n    /// @return The result of the multiplication\n    /// @return _milk And milk with nutella\n    function mul(uint a, uint second) public returns (uint _cookies, uint, uint _milk) {\n        uint mul = a * 7;\n        uint milk = 4;\n        return (mul, second, milk);\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"details\": \"Multiplies a number by 7 and adds second parameter\",\n//             \"params\":\n//             {\n//                 \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n//                 \"second\": \"Documentation for the second parameter\"\n//             },\n//             \"returns\":\n//             {\n//                 \"_1\": \"The result of the multiplication\",\n//                 \"_cookies\": \"And cookies with nutella\",\n//                 \"_milk\": \"And milk with nutella\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_return_name_no_description.sol",
    "content": "contract A {\n    /// @return a\n    function g(int x) public pure virtual returns (int a) { return 2; }\n}\n\ncontract B is A {\n    function g(int x) public pure override returns (int b) { return 2; }\n}\n\n// ----\n// ----\n// :A devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(int256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"a\": \"a\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :A userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"g(int256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"b\": \"a\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :B userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_return_no_params.sol",
    "content": "contract test {\n    /// @return d The result of the multiplication\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"d\": \"The result of the multiplication\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_struct_getter_override.sol",
    "content": "interface IThing {\n    /// @return x a number\n    /// @return y another number\n    function value() external view returns (uint128 x, uint128 y);\n}\n\ncontract Thing is IThing {\n    struct Value {\n        uint128 x;\n        uint128 y;\n    }\n\n    Value public override value;\n}\n\n// ----\n// ----\n// :IThing devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"value()\":\n//         {\n//             \"returns\":\n//             {\n//                 \"x\": \"a number\",\n//                 \"y\": \"another number\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :IThing userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :Thing devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"value\":\n//         {\n//             \"returns\":\n//             {\n//                 \"x\": \"a number\",\n//                 \"y\": \"another number\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Thing userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_struct_getter_override_different_return_parameter_names.sol",
    "content": "interface IThing {\n    /// @return x a number\n    /// @return y another number\n    function value() external view returns (uint128 x, uint128 y);\n}\n\ncontract Thing is IThing {\n    struct Value {\n        uint128 a;\n        uint128 b;\n    }\n\n    Value public override value;\n}\n\n// ----\n// ----\n// :IThing devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"value()\":\n//         {\n//             \"returns\":\n//             {\n//                 \"x\": \"a number\",\n//                 \"y\": \"another number\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :IThing userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :Thing devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"value\":\n//         {\n//             \"returns\":\n//             {\n//                 \"a\": \"a number\",\n//                 \"b\": \"another number\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Thing userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_struct_getter_override_no_return_name.sol",
    "content": "interface IThing {\n    ///@return\n    function value(uint) external returns (uint128,uint128);\n}\n\ncontract Thing is IThing {\n    struct Value {\n        uint128 x;\n        uint128 A;\n    }\n    mapping(uint=>Value) public override value;\n}\n\n// ----\n// ----\n// :IThing devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"value(uint256)\":\n//         {\n//             \"returns\":\n//             {\n//                 \"_0\": \"\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :IThing userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :Thing devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"value\":\n//         {\n//             \"return\": \"x \",\n//             \"returns\":\n//             {\n//                 \"x\": \"\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Thing userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/dev_title_at_function_error.sol",
    "content": "/// @author Lefteris\n/// @title Just a test contract\ncontract test {\n    /// @dev Mul function\n    /// @title I really should not be here\n    function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n}\n\n// ----\n// DocstringParsingError 6546: (73-137): Documentation tag @title not valid for functions.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/docstring_double_empty.sol",
    "content": "contract C {\n  ///\n  ///\n  function vote(uint id) public {\n  }\n}\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/docstring_named_return_parameter.sol",
    "content": "abstract contract C {\n    /// @return value The value returned by this function.\n    function vote() public virtual returns (uint value);\n}\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"vote()\":\n//         {\n//             \"returns\":\n//             {\n//                 \"value\": \"The value returned by this function.\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/docstring_parameter.sol",
    "content": "contract C {\n    /**\n     * @dev a function\n     * @param _from 5 from address\n     * @param _5to   : to address\n     * @param value: token transfer amount\n     * @param value? token transfer amount\n     */\n    function f(address _from, address _5to, uint256 value) internal {\n    }\n}\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/docstring_private_state_variable.sol",
    "content": "contract C {\n    /// @notice example of notice\n    /// @dev example of dev\n    uint private state;\n}\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"state\":\n//         {\n//             \"details\": \"example of dev\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/docstring_state_variable.sol",
    "content": "contract C {\n    /// @notice example of notice\n    /// @dev example of dev\n    uint public state;\n}\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"state\":\n//         {\n//             \"details\": \"example of dev\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"state()\":\n//         {\n//             \"notice\": \"example of notice\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/docstring_struct.sol",
    "content": "contract C {\n    /// @title example of title\n    /// @author example of author\n    /// @notice example of notice\n    /// @dev example of dev\n    struct Example {\n        string text;\n        bool valid;\n        uint256 value;\n    }\n}\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/docstring_variable.sol",
    "content": "contract C {\n    function f() public pure returns (uint) {\n        /// @title example of title\n        /// @author example of author\n        /// @notice example of notice\n        /// @dev example of dev\n        /// @param example of param\n        /// @return example of return\n        uint state = 42;\n        return state;\n    }\n}\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_event_from_foreign_contract.sol",
    "content": "contract X {\n    /// @notice Userdoc for event E.\n    /// @dev Devdoc for event E.\n    event E();\n}\n\ncontract C {\n    function g() public {\n        emit X.E();\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"details\": \"Devdoc for event E.\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"notice\": \"Userdoc for event E.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :X devdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"details\": \"Devdoc for event E.\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :X userdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"notice\": \"Userdoc for event E.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_event_from_foreign_contract_no_inheritance.sol",
    "content": "// Tests that emitting an event from contract C in contract D does not inherit natspec from C.E\n\ncontract C {\n    /// @notice C.E event\n    /// @dev C.E event\n    event E();\n}\n\ncontract D {\n    event E();\n\n    function test() public {\n        emit C.E();\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"details\": \"C.E event\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"notice\": \"C.E event\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :D devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :D userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_event_from_foreign_contract_with_same_signature.sol",
    "content": "contract C {\n    /// @notice C.E event\n    /// @dev C.E event\n    event E(uint256 value);\n}\n\ncontract D {\n    /// @notice D.E event\n    /// @dev D.E event\n    event E(uint256 value);\n\n    function test() public {\n        emit C.E(1);\n        emit E(2);\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"events\":\n//     {\n//         \"E(uint256)\":\n//         {\n//             \"details\": \"C.E event\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"events\":\n//     {\n//         \"E(uint256)\":\n//         {\n//             \"notice\": \"C.E event\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :D devdoc\n// {\n//     \"events\":\n//     {\n//         \"E(uint256)\":\n//         {\n//             \"details\": \"D.E event\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :D userdoc\n// {\n//     \"events\":\n//     {\n//         \"E(uint256)\":\n//         {\n//             \"notice\": \"D.E event\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_event_from_module_via_member_access.sol",
    "content": "==== Source: A.sol ====\n/// @notice This event is emitted when a transfer from A occurs.\n/// @param from The source account.\n/// @param to The destination account.\n/// @param amount The amount.\n/// @dev A test case!\nevent TransferA(address indexed from, address indexed to, uint amount);\n\ncontract AContract {\n    /// @notice This event is emitted when a transfer from AContract occurs.\n    /// @param from The source account.\n    /// @param to The destination account.\n    /// @param amount The amount.\n    /// @dev A test case!\n    event TransferAContract(address indexed from, address indexed to, uint amount);\n}\n\n==== Source: ERC20.sol ====\nimport * as A from \"A.sol\";\ncontract ERC20 {\n    /// @notice This event is emitted when a transfer from ERC20 occurs.\n    /// @param from The source account.\n    /// @param to The destination account.\n    /// @param amount The amount.\n    /// @dev A test case!\n    event Transfer(address indexed from, address indexed to, uint amount);\n\n    function test() public {\n        emit Transfer(address(1), address(5), 1);\n        emit A.AContract.TransferAContract(address(1), address(5), 1);\n        emit A.TransferA(address(1), address(5), 1);\n    }\n}\n\n// ----\n// ----\n// A.sol:AContract devdoc\n// {\n//     \"events\": {\n//         \"TransferAContract(address,address,uint256)\": {\n//             \"details\": \"A test case!\",\n//             \"params\": {\n//                 \"amount\": \"The amount.\",\n//                 \"from\": \"The source account.\",\n//                 \"to\": \"The destination account.\"\n//             }\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// A.sol:AContract userdoc\n// {\n//     \"events\": {\n//         \"TransferAContract(address,address,uint256)\": {\n//             \"notice\": \"This event is emitted when a transfer from AContract occurs.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// ERC20.sol:ERC20 devdoc\n// {\n//     \"events\": {\n//         \"Transfer(address,address,uint256)\": {\n//             \"details\": \"A test case!\",\n//             \"params\": {\n//                 \"amount\": \"The amount.\",\n//                 \"from\": \"The source account.\",\n//                 \"to\": \"The destination account.\"\n//             }\n//         },\n//         \"TransferA(address,address,uint256)\": {\n//             \"details\": \"A test case!\",\n//             \"params\": {\n//                 \"amount\": \"The amount.\",\n//                 \"from\": \"The source account.\",\n//                 \"to\": \"The destination account.\"\n//             }\n//         },\n//         \"TransferAContract(address,address,uint256)\": {\n//             \"details\": \"A test case!\",\n//             \"params\": {\n//                 \"amount\": \"The amount.\",\n//                 \"from\": \"The source account.\",\n//                 \"to\": \"The destination account.\"\n//             }\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// ERC20.sol:ERC20 userdoc\n// {\n//     \"events\": {\n//         \"Transfer(address,address,uint256)\": {\n//             \"notice\": \"This event is emitted when a transfer from ERC20 occurs.\"\n//         },\n//         \"TransferA(address,address,uint256)\": {\n//             \"notice\": \"This event is emitted when a transfer from A occurs.\"\n//         },\n//         \"TransferAContract(address,address,uint256)\": {\n//             \"notice\": \"This event is emitted when a transfer from AContract occurs.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_file_level_event.sol",
    "content": "/// @notice Userdoc for file-level event E.\n/// @dev Devdoc for file-level E.\nevent E();\n\ncontract C {\n    function f() public {\n        emit E();\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"details\": \"Devdoc for file-level E.\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"notice\": \"Userdoc for file-level event E.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_file_level_event_inheritance.sol",
    "content": "/// @notice Userdoc for file-level event E.\n/// @dev Devdoc for file-level E.\nevent E();\n\ncontract C {\n    function f() public {\n        emit E();\n    }\n}\n\ncontract D is C {}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"details\": \"Devdoc for file-level E.\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"notice\": \"Userdoc for file-level event E.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :D devdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"details\": \"Devdoc for file-level E.\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :D userdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"notice\": \"Userdoc for file-level event E.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_file_level_event_with_same_signature_as_foreign_event.sol",
    "content": "/// @notice Userdoc for file-level event E.\n/// @dev Devdoc for file-level E.\nevent E();\n\ncontract F {\n    /// @notice Userdoc for event F.E.\n    /// @dev Devdoc for event F.E.\n    event E();\n}\n\ncontract C {\n    function f() public {\n        emit E();\n        emit F.E();\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :F devdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"details\": \"Devdoc for event F.E.\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :F userdoc\n// {\n//     \"events\":\n//     {\n//         \"E()\":\n//         {\n//             \"notice\": \"Userdoc for event F.E.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_same_signature_event_different_libraries.sol",
    "content": "library L1 {\n    /// @notice This event is defined in Library L1\n    /// @dev This should not appear in Contract C dev doc\n    event SameSignatureEvent(uint16);\n}\nlibrary L2 {\n    /// @notice This event is defined in Library L2\n    /// @dev This should not appear in Contract C dev doc\n    event SameSignatureEvent(uint16);\n}\nlibrary L3 {\n    /// @notice This event is defined in Library L3\n    /// @dev This should not appear in Contract C dev doc\n    event SameSignatureEvent(uint16);\n}\ncontract C {\n    function f() public {\n        emit L1.SameSignatureEvent(0);\n        emit L2.SameSignatureEvent(1);\n        emit L3.SameSignatureEvent(2);\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L1 devdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"details\": \"This should not appear in Contract C dev doc\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L1 userdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"notice\": \"This event is defined in Library L1\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L2 devdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"details\": \"This should not appear in Contract C dev doc\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L2 userdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"notice\": \"This event is defined in Library L2\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L3 devdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"details\": \"This should not appear in Contract C dev doc\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L3 userdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"notice\": \"This event is defined in Library L3\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_same_signature_event_different_libraries_missing_natspec.sol",
    "content": "library L1 {\n    event SameSignatureEvent(uint16);\n}\nlibrary L2 {\n    /// @notice This event is defined in library L2\n    /// @dev This should not appear in Contract C devdoc\n    event SameSignatureEvent(uint16);\n}\nlibrary L3 {\n    event SameSignatureEvent(uint16);\n}\ncontract C {\n    function f() public {\n        emit L1.SameSignatureEvent(0);\n        emit L2.SameSignatureEvent(1);\n        emit L3.SameSignatureEvent(2);\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L1 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L1 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L2 devdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"details\": \"This should not appear in Contract C devdoc\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L2 userdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"notice\": \"This event is defined in library L2\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L3 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L3 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_same_signature_event_library_contract.sol",
    "content": "library L {\n    /// @notice This event is defined in Library L\n    /// @dev This should not appear in Contract C dev doc\n    event SameSignatureEvent(uint16);\n    /// @notice This event is defined in Library L\n    /// @dev This should appear in Contract C dev doc\n    event LibraryEvent(uint32);\n}\ncontract C {\n    /// @notice This event is defined in Contract C\n    /// @dev This should appear in Contract C dev doc\n    event SameSignatureEvent(uint16);\n    /// @notice This event is defined in Contract C\n    /// @dev This should appear in contract C dev doc\n    event ContractEvent(uint32);\n    function f() public {\n    emit L.SameSignatureEvent(0);\n    emit SameSignatureEvent(1);\n    emit L.LibraryEvent(2);\n    emit ContractEvent(3);\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"events\":\n//     {\n//         \"ContractEvent(uint32)\":\n//         {\n//             \"details\": \"This should appear in contract C dev doc\"\n//         },\n//         \"LibraryEvent(uint32)\":\n//         {\n//             \"details\": \"This should appear in Contract C dev doc\"\n//         },\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"details\": \"This should appear in Contract C dev doc\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"events\":\n//     {\n//         \"ContractEvent(uint32)\":\n//         {\n//             \"notice\": \"This event is defined in Contract C\"\n//         },\n//         \"LibraryEvent(uint32)\":\n//         {\n//             \"notice\": \"This event is defined in Library L\"\n//         },\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"notice\": \"This event is defined in Contract C\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L devdoc\n// {\n//     \"events\":\n//     {\n//         \"LibraryEvent(uint32)\":\n//         {\n//             \"details\": \"This should appear in Contract C dev doc\"\n//         },\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"details\": \"This should not appear in Contract C dev doc\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L userdoc\n// {\n//     \"events\":\n//     {\n//         \"LibraryEvent(uint32)\":\n//         {\n//             \"notice\": \"This event is defined in Library L\"\n//         },\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"notice\": \"This event is defined in Library L\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_same_signature_event_library_contract_missing_natspec.sol",
    "content": "library L {\n    /// @notice This event is defined in library L\n    /// @dev This should not appear in contract C devdoc\n    event SameSignatureEvent(uint16);\n    /// @notice This event is defined in library L\n    /// @dev This should appear in contract C devdoc\n    event LibraryEvent(uint32);\n}\ncontract C {\n    event SameSignatureEvent(uint16);\n    /// @notice This event is defined in contract C\n    event ContractEvent(uint32);\n    function f() public {\n        emit L.SameSignatureEvent(0);\n        emit SameSignatureEvent(1);\n        emit L.LibraryEvent(2);\n        emit ContractEvent(3);\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"events\":\n//     {\n//         \"LibraryEvent(uint32)\":\n//         {\n//             \"details\": \"This should appear in contract C devdoc\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"events\":\n//     {\n//         \"ContractEvent(uint32)\":\n//         {\n//             \"notice\": \"This event is defined in contract C\"\n//         },\n//         \"LibraryEvent(uint32)\":\n//         {\n//             \"notice\": \"This event is defined in library L\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L devdoc\n// {\n//     \"events\":\n//     {\n//         \"LibraryEvent(uint32)\":\n//         {\n//             \"details\": \"This should appear in contract C devdoc\"\n//         },\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"details\": \"This should not appear in contract C devdoc\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L userdoc\n// {\n//     \"events\":\n//     {\n//         \"LibraryEvent(uint32)\":\n//         {\n//             \"notice\": \"This event is defined in library L\"\n//         },\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"notice\": \"This event is defined in library L\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_same_signature_event_library_inherited.sol",
    "content": "contract D {\n    /// @notice This event is defined in contract D\n    /// @dev This should appear in Contract C dev doc\n    event SameSignatureEvent(uint16);\n}\nlibrary L {\n    /// @notice This event is defined in Library L\n    /// @dev This should not appear in Contract C\n    event SameSignatureEvent(uint16);\n}\ncontract C is D {\n    function f() public {\n        emit L.SameSignatureEvent(0);\n        emit D.SameSignatureEvent(1);\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"details\": \"This should appear in Contract C dev doc\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"notice\": \"This event is defined in contract D\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :D devdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"details\": \"This should appear in Contract C dev doc\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :D userdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"notice\": \"This event is defined in contract D\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L devdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"details\": \"This should not appear in Contract C\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L userdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"notice\": \"This event is defined in Library L\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/emit_same_signature_event_library_inherited_missing_natspec.sol",
    "content": "contract D {\n    event SameSignatureEvent(uint16);\n}\nlibrary L {\n    /// @notice This event is defined in library L\n    /// @dev This should not appear in contract C devdoc\n    event SameSignatureEvent(uint16);\n}\ncontract C is D {\n    function f() public {\n        emit L.SameSignatureEvent(0);\n        emit D.SameSignatureEvent(1);\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :D devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :D userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L devdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"details\": \"This should not appear in contract C devdoc\"\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :L userdoc\n// {\n//     \"events\":\n//     {\n//         \"SameSignatureEvent(uint16)\":\n//         {\n//             \"notice\": \"This event is defined in library L\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/empty_comment.sol",
    "content": "//\ncontract test\n{}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/enum.sol",
    "content": "contract C {\n    /// @title example of title\n    /// @author example of author\n    /// @notice example of notice\n    /// @dev example of dev\n    enum Color {\n        Red,\n        Green\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/enum_value.sol",
    "content": "contract C {\n    enum Color {\n        /// @custom red color\n        Red,\n        /// @title example of title\n        /// @author example of author\n        /// @notice example of notice\n        /// @dev example of dev\n        Green\n        /// @notice beyond last value\n    }\n}\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/error.sol",
    "content": "contract test {\n    /// Something failed.\n    /// @dev an error.\n    /// @param a first parameter\n    /// @param b second parameter\n    error E(uint a, uint b);\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"errors\":\n//     {\n//         \"E(uint256,uint256)\":\n//         [\n//             {\n//                 \"details\": \"an error.\",\n//                 \"params\":\n//                 {\n//                     \"a\": \"first parameter\",\n//                     \"b\": \"second parameter\"\n//                 }\n//             }\n//         ]\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"errors\":\n//     {\n//         \"E(uint256,uint256)\":\n//         [\n//             {\n//                 \"notice\": \"Something failed.\"\n//             }\n//         ]\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/error_from_module_via_member_access.sol",
    "content": "==== Source: A.sol ====\n/// Something failed.\n/// @dev an error.\n/// @param a first parameter\n/// @param b second parameter\nerror E(uint a, uint b);\n\ncontract AContract {\n    /// Something failed.\n    /// @dev an error.\n    /// @param a first parameter\n    /// @param b second parameter\n    error EAContract(uint a, uint b);\n}\n\n==== Source: ERC20.sol ====\nimport * as A from \"A.sol\";\ncontract ERC20 {\n    /// Something failed.\n    /// @dev an error.\n    /// @param a first parameter\n    /// @param b second parameter\n    error EERC20(uint a, uint b);\n\n    function f(uint a) public pure {\n        if (a > 0)\n            revert EERC20(1, 2);\n        else if (a < 0)\n            revert A.AContract.EAContract(5, 6);\n        else\n            revert A.E(5, 6);\n    }\n}\n\n// ----\n// ----\n// A.sol:AContract devdoc\n// {\n//     \"errors\": {\n//         \"EAContract(uint256,uint256)\": [\n//             {\n//                 \"details\": \"an error.\",\n//                 \"params\": {\n//                     \"a\": \"first parameter\",\n//                     \"b\": \"second parameter\"\n//                 }\n//             }\n//         ]\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// A.sol:AContract userdoc\n// {\n//     \"errors\": {\n//         \"EAContract(uint256,uint256)\": [\n//             {\n//                 \"notice\": \"Something failed.\"\n//             }\n//         ]\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// ERC20.sol:ERC20 devdoc\n// {\n//     \"errors\": {\n//         \"E(uint256,uint256)\": [\n//             {\n//                 \"details\": \"an error.\",\n//                 \"params\": {\n//                     \"a\": \"first parameter\",\n//                     \"b\": \"second parameter\"\n//                 }\n//             }\n//         ],\n//         \"EAContract(uint256,uint256)\": [\n//             {\n//                 \"details\": \"an error.\",\n//                 \"params\": {\n//                     \"a\": \"first parameter\",\n//                     \"b\": \"second parameter\"\n//                 }\n//             }\n//         ],\n//         \"EERC20(uint256,uint256)\": [\n//             {\n//                 \"details\": \"an error.\",\n//                 \"params\": {\n//                     \"a\": \"first parameter\",\n//                     \"b\": \"second parameter\"\n//                 }\n//             }\n//         ]\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// ERC20.sol:ERC20 userdoc\n// {\n//     \"errors\": {\n//         \"E(uint256,uint256)\": [\n//             {\n//                 \"notice\": \"Something failed.\"\n//             }\n//         ],\n//         \"EAContract(uint256,uint256)\": [\n//             {\n//                 \"notice\": \"Something failed.\"\n//             }\n//         ],\n//         \"EERC20(uint256,uint256)\": [\n//             {\n//                 \"notice\": \"Something failed.\"\n//             }\n//         ]\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/error_multiple.sol",
    "content": "contract A {\n    /// Something failed.\n    /// @dev an error.\n    /// @param x first parameter\n    /// @param y second parameter\n    error E(uint x, uint y);\n}\ncontract test {\n    /// X Something failed.\n    /// @dev X an error.\n    /// @param a X first parameter\n    /// @param b X second parameter\n    error E(uint a, uint b);\n    function f(bool a) public pure {\n        if (a)\n            revert E(1, 2);\n        else\n            revert A.E(5, 6);\n    }\n}\n\n// ----\n// ----\n// :A devdoc\n// {\n//     \"errors\":\n//     {\n//         \"E(uint256,uint256)\":\n//         [\n//             {\n//                 \"details\": \"an error.\",\n//                 \"params\":\n//                 {\n//                     \"x\": \"first parameter\",\n//                     \"y\": \"second parameter\"\n//                 }\n//             }\n//         ]\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :A userdoc\n// {\n//     \"errors\":\n//     {\n//         \"E(uint256,uint256)\":\n//         [\n//             {\n//                 \"notice\": \"Something failed.\"\n//             }\n//         ]\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test devdoc\n// {\n//     \"errors\":\n//     {\n//         \"E(uint256,uint256)\":\n//         [\n//             {\n//                 \"details\": \"an error.\",\n//                 \"params\":\n//                 {\n//                     \"x\": \"first parameter\",\n//                     \"y\": \"second parameter\"\n//                 }\n//             },\n//             {\n//                 \"details\": \"X an error.\",\n//                 \"params\":\n//                 {\n//                     \"a\": \"X first parameter\",\n//                     \"b\": \"X second parameter\"\n//                 }\n//             }\n//         ]\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"errors\":\n//     {\n//         \"E(uint256,uint256)\":\n//         [\n//             {\n//                 \"notice\": \"Something failed.\"\n//             },\n//             {\n//                 \"notice\": \"X Something failed.\"\n//             }\n//         ]\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/event.sol",
    "content": "contract ERC20 {\n    /// @notice This event is emitted when a transfer occurs.\n    /// @param from The source account.\n    /// @param to The destination account.\n    /// @param amount The amount.\n    /// @dev A test case!\n    event Transfer(address indexed from, address indexed to, uint amount);\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"details\": \"A test case!\",\n//             \"params\":\n//             {\n//                 \"amount\": \"The amount.\",\n//                 \"from\": \"The source account.\",\n//                 \"to\": \"The destination account.\"\n//             }\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"notice\": \"This event is emitted when a transfer occurs.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/event_inheritance.sol",
    "content": "contract ERC20 {\n    /// @notice This event is emitted when a transfer occurs.\n    /// @param from The source account.\n    /// @param to The destination account.\n    /// @param amount The amount.\n    /// @dev A test case!\n    event Transfer(address indexed from, address indexed to, uint amount);\n}\ncontract A is ERC20 {\n}\ncontract B is A {\n}\n\n// ----\n// ----\n// :A devdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"details\": \"A test case!\",\n//             \"params\":\n//             {\n//                 \"amount\": \"The amount.\",\n//                 \"from\": \"The source account.\",\n//                 \"to\": \"The destination account.\"\n//             }\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :A userdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"notice\": \"This event is emitted when a transfer occurs.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B devdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"details\": \"A test case!\",\n//             \"params\":\n//             {\n//                 \"amount\": \"The amount.\",\n//                 \"from\": \"The source account.\",\n//                 \"to\": \"The destination account.\"\n//             }\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B userdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"notice\": \"This event is emitted when a transfer occurs.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :ERC20 devdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"details\": \"A test case!\",\n//             \"params\":\n//             {\n//                 \"amount\": \"The amount.\",\n//                 \"from\": \"The source account.\",\n//                 \"to\": \"The destination account.\"\n//             }\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"notice\": \"This event is emitted when a transfer occurs.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/event_inheritance_interface.sol",
    "content": "interface ERC20 {\n    /// @notice This event is emitted when a transfer occurs.\n    /// @param from The source account.\n    /// @param to The destination account.\n    /// @param amount The amount.\n    /// @dev A test case!\n    event Transfer(address indexed from, address indexed to, uint amount);\n}\ncontract A is ERC20 {\n}\ncontract B is A {\n}\n\n// ----\n// ----\n// :A devdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"details\": \"A test case!\",\n//             \"params\":\n//             {\n//                 \"amount\": \"The amount.\",\n//                 \"from\": \"The source account.\",\n//                 \"to\": \"The destination account.\"\n//             }\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :A userdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"notice\": \"This event is emitted when a transfer occurs.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B devdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"details\": \"A test case!\",\n//             \"params\":\n//             {\n//                 \"amount\": \"The amount.\",\n//                 \"from\": \"The source account.\",\n//                 \"to\": \"The destination account.\"\n//             }\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B userdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"notice\": \"This event is emitted when a transfer occurs.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :ERC20 devdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"details\": \"A test case!\",\n//             \"params\":\n//             {\n//                 \"amount\": \"The amount.\",\n//                 \"from\": \"The source account.\",\n//                 \"to\": \"The destination account.\"\n//             }\n//         }\n//     },\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"events\":\n//     {\n//         \"Transfer(address,address,uint256)\":\n//         {\n//             \"notice\": \"This event is emitted when a transfer occurs.\"\n//         }\n//     },\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_author_function.sol",
    "content": "contract C {\n    /// @author author\n    function iHaveAuthor() public pure {}\n}\n// ----\n// DocstringParsingError 6546: (17-35): Documentation tag @author not valid for functions.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_author_title_state_variable.sol",
    "content": "contract C {\n    /// @title title\n    /// @author author\n    uint private state;\n}\n// ----\n// DocstringParsingError 6546: (17-56): Documentation tag @author not valid for non-public state variables.\n// DocstringParsingError 6546: (17-56): Documentation tag @title not valid for non-public state variables.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_empty_description.sol",
    "content": "contract C {\n    /// @param id\n    function vote(uint id) public {}\n}\n// ----\n// DocstringParsingError 9942: (17-30): No description given for param id\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_empty_tag.sol",
    "content": "abstract contract C {\n    /// @param\n    function vote(uint id) public {}\n}\n// ----\n// DocstringParsingError 3335: (26-36): No param name given\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_inherit_modifier_no_return.sol",
    "content": "contract C {\n\t///@return\n\tmodifier m22 virtual { _; }\n}\n\ncontract D is C {\n\tmodifier m22 override { _; }\n}\n// ----\n// DocstringParsingError 6546: (14-24): Documentation tag @return not valid for modifiers.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_inherit_modifier_no_return2.sol",
    "content": "contract A {\n\t/// @return a\n\tfunction g(int x) public virtual { return 2; }\n}\n\ncontract B is A {\n\tfunction g(int x) public pure override returns (int b) { return 2; }\n}\n// ----\n// DocstringParsingError 2604: (14-27): Documentation tag \"@return a\" exceeds the number of return parameters.\n// TypeError 4822: (98-166): Overriding function return types differ.\n// TypeError 8863: (64-72): Different number of arguments in return statement than in returns declaration.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_inheritdoc.sol",
    "content": "contract C {\n    /// @inheritdoc X\n    function f() internal {\n    }\n}\n// ----\n// DocstringParsingError 9397: (17-34): Documentation tag @inheritdoc references inexistent contract \"X\".\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_inheritdoc2.sol",
    "content": "contract D {\n}\n\ncontract C is D {\n    /// @inheritdoc D\n    function f() internal {\n    }\n}\n// ----\n// DocstringParsingError 4682: (38-55): Documentation tag @inheritdoc references contract \"D\", but the contract does not contain a function that is overridden by this function.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_inheritdoc3.sol",
    "content": "contract D {\n    struct S { uint a; }\n}\n\ncontract C is D {\n    /// @inheritdoc D.S\n    function f() internal {\n    }\n}\n// ----\n// DocstringParsingError 1430: (63-82): Documentation tag @inheritdoc reference \"D.S\" is not a contract.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_inheritdoc_emptys.sol",
    "content": "contract C {\n    /// @inheritdoc\n    function f() internal {\n    }\n    /// @inheritdoc .\n    function f() internal {\n    }\n    /// @inheritdoc C..f\n    function f() internal {\n    }\n    /// @inheritdoc C.\n    function f() internal {\n    }\n}\n// ----\n// DocstringParsingError 1933: (17-32): Expected contract name following documentation tag @inheritdoc.\n// DocstringParsingError 5967: (71-88): Documentation tag @inheritdoc reference \".\" is malformed.\n// DocstringParsingError 5967: (127-147): Documentation tag @inheritdoc reference \"C..f\" is malformed.\n// DocstringParsingError 5967: (186-204): Documentation tag @inheritdoc reference \"C.\" is malformed.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_inheritdoc_twice.sol",
    "content": "contract B {}\n\ncontract C {\n    /// @inheritdoc B\n    /// @inheritdoc B\n    function f() internal {}\n}\n// ----\n// DocstringParsingError 5142: (32-71): Documentation tag @inheritdoc can only be given once.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_inheritdoc_wrong_type.sol",
    "content": "contract C {\n    struct S { uint a; }\n    /// @inheritdoc S\n    function f() internal {\n    }\n}\n// ----\n// DocstringParsingError 1430: (42-59): Documentation tag @inheritdoc reference \"S\" is not a contract.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_named_return_param_mismatch.sol",
    "content": "abstract contract C {\n    /// @param id Some identifier\n    /// @return No value returned\n    function vote(uint id) public virtual returns (uint value);\n}\n// ----\n// DocstringParsingError 5856: (26-89): Documentation tag \"@return No value returned\" does not contain the name of its return parameter.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_non_public_state_variable_with_return.sol",
    "content": "contract test {\n  /// @return returns something\n  uint private state;\n}\n// ----\n// DocstringParsingError 6546: (18-47): Documentation tag @return not valid for non-public state variables.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_parameter.sol",
    "content": "contract C {\n    /**\n     * @param 5value a value parameter\n     * @param _ a value parameter\n     */\n    function f(uint256 _5value, uint256 _value, uint256 value) internal {\n    }\n}\n// ----\n// DocstringParsingError 3881: (17-101): Documented parameter \"\" not found in the parameter list of the function.\n// DocstringParsingError 3881: (17-101): Documented parameter \"_\" not found in the parameter list of the function.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_return_size_mismatch.sol",
    "content": "abstract contract C {\n    /// @param id Some identifier\n    /// @return No value returned\n    function vote(uint id) public virtual returns (uint value);\n\n    /// @return No value returned\n    function unvote(uint id) public virtual returns (uint value);\n}\n// ----\n// DocstringParsingError 5856: (26-89): Documentation tag \"@return No value returned\" does not contain the name of its return parameter.\n// DocstringParsingError 5856: (159-188): Documentation tag \"@return No value returned\" does not contain the name of its return parameter.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_state_variable_too_many_return_tags.sol",
    "content": "contract test {\n  /// @notice example of notice\n  /// @dev example of dev\n  /// @return returns something\n  /// @return returns something\n  uint public state;\n}\n// ----\n// DocstringParsingError 2604: (18-137): Documentation tag \"@return returns something\" exceeds the number of return parameters.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/docstring_too_many_return_tags.sol",
    "content": "abstract contract C {\n    /// @param id Some identifier\n    /// @return value Some value\n\t/// @return value2 Some value 2\n    function vote(uint id) public virtual returns (uint value);\n}\n// ----\n// DocstringParsingError 2604: (26-121): Documentation tag \"@return value2 Some value 2\" exceeds the number of return parameters.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/inherit_doc_events.sol",
    "content": "contract ERC20 {\n\t/// @notice This event is emitted when a transfer occurs.\n\t/// @param from The source account.\n\t/// @param to The destination account.\n\t/// @param amount The amount.\n\t/// @dev A test case!\n\tevent Transfer(address indexed from, address indexed to, uint amount);\n}\n\ncontract A is ERC20 {\n\t/// @inheritdoc ERC20\n\tevent Transfer();\n}\n\n\n// ----\n// DocstringParsingError 6546: (305-326): Documentation tag @inheritdoc not valid for events.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/invalid/invalid_tag.sol",
    "content": "/// @a&b test\ncontract C {\n\t/// @custom:x^y test2\n\tfunction f() public pure {}\n\t/// @custom:\n\tfunction g() public pure {}\n\t/// @custom:abcDEF\n\tfunction h() public pure {}\n\t/// @custom:abc-def\n\tfunction i() public pure {}\n\t/// @custom\n\tfunction j() public pure {}\n}\n// ----\n// DocstringParsingError 6546: (0-14): Documentation tag @a&b not valid for contracts.\n// DocstringParsingError 2968: (28-49): Invalid character in custom tag @custom:x^y. Only lowercase letters and \"-\" are permitted.\n// DocstringParsingError 6564: (80-92): Custom documentation tag must contain a chosen name, i.e. @custom:mytag.\n// DocstringParsingError 2968: (123-141): Invalid character in custom tag @custom:abcDEF. Only lowercase letters and \"-\" are permitted.\n// DocstringParsingError 6564: (222-233): Custom documentation tag must contain a chosen name, i.e. @custom:mytag.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/multiline_notice_without_tag.sol",
    "content": "contract test {\n    /// I do something awesome\n    /// which requires two lines to explain\n    function mul(uint a) public returns (uint d) { return a * 7; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"mul(uint256)\":\n//         {\n//             \"notice\": \"I do something awesome which requires two lines to explain\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/notice_without_tag.sol",
    "content": "contract test {\n    /// I do something awesome\n    function mul(uint a) public returns (uint d) { return a * 7; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"mul(uint256)\":\n//         {\n//             \"notice\": \"I do something awesome\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/private_state_variable.sol",
    "content": "contract test {\n    /// @dev example of dev\n    uint private state;\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"state\":\n//         {\n//             \"details\": \"example of dev\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/public_state_variable.sol",
    "content": "contract test {\n    /// @notice example of notice\n    /// @dev example of dev\n    /// @return returns state\n    uint public state;\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"state\":\n//         {\n//             \"details\": \"example of dev\",\n//             \"return\": \"returns state\",\n//             \"returns\":\n//             {\n//                 \"_0\": \"returns state\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"state()\":\n//         {\n//             \"notice\": \"example of notice\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/public_state_variable_struct.sol",
    "content": "contract Bank {\n    struct Coin {\n        string observeGraphicURL;\n        string reverseGraphicURL;\n    }\n\n    /// @notice Get the n-th coin I own\n    /// @return observeGraphicURL Front pic\n    /// @return reverseGraphicURL Back pic\n    Coin[] public coinStack;\n}\n\n// ----\n// ----\n// :Bank devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"coinStack\":\n//         {\n//             \"returns\":\n//             {\n//                 \"observeGraphicURL\": \"Front pic\",\n//                 \"reverseGraphicURL\": \"Back pic\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Bank userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"coinStack(uint256)\":\n//         {\n//             \"notice\": \"Get the n-th coin I own\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/public_state_variable_struct_repeated.sol",
    "content": "contract Bank {\n    struct Coin {\n        string obverseGraphicURL;\n        string reverseGraphicURL;\n    }\n\n    /// @notice Get the n-th coin I own\n    /// @return obverseGraphicURL Front pic\n    /// @return obverseGraphicURL Front pic\n    Coin[] public coinStack;\n}\n\n// ----\n// DocstringParsingError 5856: (113-236): Documentation tag \"@return obverseGraphicURL Front pic\" does not contain the name of its return parameter.\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/return_param_amount_differs.sol",
    "content": "interface IThing {\n    /// @return x a number\n    /// @return y another number\n    function value() external view returns (uint128 x, uint128 y);\n}\n\ncontract Thing is IThing {\n    struct Value {\n        uint128 x;\n        uint128 y;\n    }\n\n    Value public override value;\n}\n// ----\n// ----\n// :IThing devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"value()\":\n//         {\n//             \"returns\":\n//             {\n//                 \"x\": \"a number\",\n//                 \"y\": \"another number\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :IThing userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :Thing devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"value\":\n//         {\n//             \"returns\":\n//             {\n//                 \"x\": \"a number\",\n//                 \"y\": \"another number\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Thing userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/return_param_amount_differs2.sol",
    "content": "interface IThing {\n    /// @param v value to search for\n    /// @return x a number\n    /// @return y another number\n    function value(uint256 v) external view returns (uint128 x, uint128 y);\n}\n\ncontract Thing is IThing {\n    struct Value {\n        uint128 x;\n        uint128 y;\n    }\n\n    mapping(uint256=>Value) public override value;\n}\n// ----\n// ----\n// :IThing devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"value(uint256)\":\n//         {\n//             \"params\":\n//             {\n//                 \"v\": \"value to search for\"\n//             },\n//             \"returns\":\n//             {\n//                 \"x\": \"a number\",\n//                 \"y\": \"another number\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :IThing userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :Thing devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"value\":\n//         {\n//             \"params\":\n//             {\n//                 \"v\": \"value to search for\"\n//             },\n//             \"returns\":\n//             {\n//                 \"x\": \"a number\",\n//                 \"y\": \"another number\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Thing userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/slash3_slash3.sol",
    "content": "contract test {\n    /// @notice lorem\n    /// ipsum\n    function f() public { }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"f()\":\n//         {\n//             \"notice\": \"lorem ipsum\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/slash3_slash4.sol",
    "content": "contract test {\n    /// @notice lorem\n    //// ipsum\n    function f() public { }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"f()\":\n//         {\n//             \"notice\": \"lorem\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/slash4.sol",
    "content": "contract test {\n    //// @notice lorem ipsum\n    function f() public { }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/star3.sol",
    "content": "contract test {\n    /***\n     * @notice lorem ipsum\n     */\n    function f() public { }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/storage_layout_specifier_no_doc.sol",
    "content": "contract C\n    /// @notice this changes the base slot of the contract storage\n    layout at\n    /// @dev the expression must be in range of uint256\n    0x1234\n{ }\n// ====\n// stopAfter: analysis\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/struct_no_docs.sol",
    "content": "contract C {\n    /// @title example of title\n    /// @author example of author\n    /// @notice example of notice\n    /// @dev example of dev\n    struct Example {\n        string text;\n        bool valid;\n        uint256 value;\n    }\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/unused_file_level_event.sol",
    "content": "/// @notice Userdoc for file-level event E.\n/// @dev Devdoc for file-level E.\nevent E();\n\ncontract C {}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_basic_test.sol",
    "content": "contract test {\n    /// @notice Multiplies `a` by 7\n    function mul(uint a) public returns(uint d) { return a * 7; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"mul(uint256)\":\n//         {\n//             \"notice\": \"Multiplies `a` by 7\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_constructor.sol",
    "content": "contract test {\n    /// @notice this is a really nice constructor\n    constructor(uint a, uint second) { }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"constructor\":\n//         {\n//             \"notice\": \"this is a really nice constructor\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_constructor_and_function.sol",
    "content": "contract test {\n    /// @notice this is a really nice constructor\n    constructor(uint a, uint second) { }\n    /// another multiplier\n    function mul(uint a, uint second) public returns(uint d) { return a * 7 + second; }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"constructor\":\n//         {\n//             \"notice\": \"this is a really nice constructor\"\n//         },\n//         \"mul(uint256,uint256)\":\n//         {\n//             \"notice\": \"another multiplier\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_default_inherit.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// Second line.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract Middle is ERC20 {\n    function transfer(address to, uint amount) virtual override external returns (bool)\n    {\n        return false;\n    }\n}\n\ncontract Token is Middle {\n    function transfer(address to, uint amount) override external returns (bool)\n    {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``. Second line.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Middle devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Middle userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``. Second line.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``. Second line.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_default_inherit_variable.sol",
    "content": "contract C {\n    /// @notice Hello world\n    /// @dev test\n    function x() virtual external returns (uint) {\n        return 1;\n    }\n}\n\ncontract D is C {\n    uint public override x;\n}\n\n// ----\n// ----\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"details\": \"test\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"notice\": \"Hello world\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :D devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"x\":\n//         {\n//             \"details\": \"test\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :D userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"notice\": \"Hello world\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_empty_contract.sol",
    "content": "contract test { }\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_empty_natspec_test.sol",
    "content": "contract test {\n    ///\n    ///\n    function f() public {\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_explicit_inherit.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract ERC21 {\n    function transfer(address to, uint amount) virtual external returns (bool) {\n        return false;\n    }\n}\n\ncontract Token is ERC21, ERC20 {\n    /// @inheritdoc ERC20\n    function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :ERC21 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_explicit_inherit2.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract ERC21 is ERC20 {\n    function transfer(address to, uint amount) virtual override external returns (bool) {\n        return false;\n    }\n}\n\ncontract Token is ERC20 {\n    /// @inheritdoc ERC20\n    function transfer(address to, uint amount) override external returns (bool) {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_explicit_inherit_partial.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract ERC21 {\n    function transfer(address to, uint amount) virtual external returns (bool) {\n        return false;\n    }\n}\n\ncontract Token is ERC21, ERC20 {\n    /// @inheritdoc ERC20\n    /// @dev override dev comment\n    /// @notice override notice\n    function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :ERC21 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"override dev comment\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"override notice\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_explicit_inherit_partial2.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract ERC21 is ERC20 {\n    /// @inheritdoc ERC20\n    /// @dev override dev comment\n    /// @notice override notice\n    function transfer(address to, uint amount) virtual override external returns (bool) {\n        return false;\n    }\n}\n\ncontract Token is ERC21 {\n    function transfer(address to, uint amount) override external returns (bool) {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"override dev comment\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC21 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"override notice\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"override dev comment\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"override notice\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_explicit_inherit_variable.sol",
    "content": "contract B {\n    function x() virtual external returns (uint) {\n        return 1;\n    }\n}\n\ncontract C {\n    /// @notice Hello world\n    /// @dev test\n    function x() virtual external returns (uint) {\n        return 1;\n    }\n}\n\ncontract D is C, B {\n    /// @inheritdoc C\n    uint public override(C, B) x;\n}\n\n// ----\n// ----\n// :B devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :B userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :C devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"details\": \"test\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :C userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"notice\": \"Hello world\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :D devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"stateVariables\":\n//     {\n//         \"x\":\n//         {\n//             \"details\": \"test\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :D userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"x()\":\n//         {\n//             \"notice\": \"Hello world\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_inherit_parameter_mismatch.sol",
    "content": "interface ERC20 {\n    /// Transfer ``amount`` from ``msg.sender`` to ``to``.\n    /// @dev test\n    /// @param to address to transfer to\n    /// @param amount amount to transfer\n    function transfer(address to, uint amount) external returns (bool);\n}\n\ncontract Middle is ERC20 {\n    function transfer(address to, uint amount) override virtual external returns (bool) {\n        return false;\n    }\n}\n\ncontract Token is Middle {\n    function transfer(address too, uint amount) override external returns (bool) {\n        return false;\n    }\n}\n\n// ----\n// ----\n// :ERC20 devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :ERC20 userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Middle devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"details\": \"test\",\n//             \"params\":\n//             {\n//                 \"amount\": \"amount to transfer\",\n//                 \"to\": \"address to transfer to\"\n//             }\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Middle userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"transfer(address,uint256)\":\n//         {\n//             \"notice\": \"Transfer ``amount`` from ``msg.sender`` to ``to``.\"\n//         }\n//     },\n//     \"version\": 1\n// }\n//\n// :Token devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :Token userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_multiline_comment.sol",
    "content": "contract test {\n    /// @notice Multiplies `a` by 7\n    /// and then adds `b`\n    function mul_and_add(uint a, uint256 b) public returns (uint256 d) {\n        return (a * 7) + b;\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"mul_and_add(uint256,uint256)\":\n//         {\n//             \"notice\": \"Multiplies `a` by 7 and then adds `b`\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_multiline_empty_lines.sol",
    "content": "contract test {\n    /**\n     *\n     *\n     * @notice hello world\n     */\n    function f() public {\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"f()\":\n//         {\n//             \"notice\": \"hello world\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_multiple_functions.sol",
    "content": "contract test {\n    /// @notice Multiplies `a` by 7 and then adds `b`\n    function mul_and_add(uint a, uint256 b) public returns (uint256 d) {\n        return (a * 7) + b;\n    }\n\n    /// @notice Divides `input` by `div`\n    function divide(uint input, uint div) public returns (uint d) {\n        return input / div;\n    }\n\n    /// @notice Subtracts 3 from `input`\n    function sub(int input) public returns (int d) {\n        return input - 3;\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"divide(uint256,uint256)\":\n//         {\n//             \"notice\": \"Divides `input` by `div`\"\n//         },\n//         \"mul_and_add(uint256,uint256)\":\n//         {\n//             \"notice\": \"Multiplies `a` by 7 and then adds `b`\"\n//         },\n//         \"sub(int256)\":\n//         {\n//             \"notice\": \"Subtracts 3 from `input`\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/natspecJSON/user_newline_break.sol",
    "content": "contract test {\n    ///\n    /// @notice hello\n\n    /// @notice world\n    function f() public {\n    }\n}\n\n// ----\n// ----\n// :test devdoc\n// {\n//     \"kind\": \"dev\",\n//     \"methods\": {},\n//     \"version\": 1\n// }\n//\n// :test userdoc\n// {\n//     \"kind\": \"user\",\n//     \"methods\":\n//     {\n//         \"f()\":\n//         {\n//             \"notice\": \"world\"\n//         }\n//     },\n//     \"version\": 1\n// }\n"
  },
  {
    "path": "test/libsolidity/optimizedIRCaching/bytecode_dependency_creation.sol",
    "content": "contract A {}\n\ncontract C {\n    A a = new A();\n}\n// ----\n// cachedObjects: 4\n"
  },
  {
    "path": "test/libsolidity/optimizedIRCaching/bytecode_dependency_creation_and_runtime.sol",
    "content": "contract A {}\ncontract B {}\n\ncontract C {\n    A a = new A();\n\n    function f() public returns (B) {\n        return new B();\n    }\n}\n// ----\n// cachedObjects: 6\n"
  },
  {
    "path": "test/libsolidity/optimizedIRCaching/bytecode_dependency_creation_and_runtime_shared.sol",
    "content": "contract A {}\n\ncontract C {\n    A a = new A();\n\n    function f() public returns (A) {\n        return new A();\n    }\n}\n// ----\n// cachedObjects: 4\n"
  },
  {
    "path": "test/libsolidity/optimizedIRCaching/bytecode_dependency_runtime.sol",
    "content": "contract A {}\n\ncontract C {\n    function f() public returns (A) {\n        return new A();\n    }\n}\n// ----\n// cachedObjects: 4\n"
  },
  {
    "path": "test/libsolidity/optimizedIRCaching/bytecode_dependency_shared_by_multiple_contracts.sol",
    "content": "contract A {}\n\ncontract C {\n    A a = new A();\n\n    function f() public returns (A) {\n        return new A();\n    }\n}\n\ncontract D {\n    A a = new A();\n\n    function f() public returns (A) {\n        return new A();\n    }\n}\n// ----\n// cachedObjects: 6\n"
  },
  {
    "path": "test/libsolidity/optimizedIRCaching/multiple_contracts.sol",
    "content": "contract C {}\ncontract D {}\ncontract E {}\n// ----\n// cachedObjects: 6\n"
  },
  {
    "path": "test/libsolidity/optimizedIRCaching/no_contracts.sol",
    "content": "// ----\n// cachedObjects: 0\n"
  },
  {
    "path": "test/libsolidity/optimizedIRCaching/single_contract.sol",
    "content": "contract C {}\n// ----\n// cachedObjects: 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_calldata.sol",
    "content": "contract C {\n    function f(bytes calldata data)\n        external\n        pure\n        returns (uint256, bytes memory r)\n    {\n        return abi.decode(data, (uint256, bytes));\n    }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_simple.sol",
    "content": "contract C {\n    function f(bytes memory data) public pure returns (uint256, bytes memory) {\n        return abi.decode(data, (uint256, bytes));\n    }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_decode_simple_storage.sol",
    "content": "contract C {\n    bytes data;\n\n    function f(bytes memory _data) public returns (uint256, bytes memory) {\n        data = _data;\n        return abi.decode(data, (uint256, bytes));\n    }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n// gas irOptimized: 135441\n// gas legacy: 137095\n// gas legacyOptimized: 135828\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call.sol",
    "content": "pragma abicoder v2;\ncontract C {\n\ttype UnsignedNumber is uint256;\n\tenum Enum { First, Second, Third }\n\n\tstruct Struct {\n\t\tUnsignedNumber[] dynamicArray;\n\t\tuint256 justAnInt;\n\t\tstring name;\n\t\tbytes someBytes;\n\t\tEnum theEnum;\n\t}\n\n\tfunction callMeMaybe(Struct calldata _data, int256 _intVal, string memory _nameVal) external pure {\n\t\tassert(_data.dynamicArray.length == 3);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[0]) == 0);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[1]) == 1);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[2]) == 2);\n\t\tassert(_data.justAnInt == 6);\n\t\tassert(keccak256(bytes(_data.name)) == keccak256(\"StructName\"));\n\t\tassert(keccak256(_data.someBytes) == keccak256(bytes(\"1234\")));\n\t\tassert(_data.theEnum == Enum.Second);\n\t\tassert(_intVal == 5);\n\t\tassert(keccak256(bytes(_nameVal)) == keccak256(\"TestName\"));\n\t}\n\n\tfunction callExternal() public returns (bool) {\n\t\tStruct memory structToSend;\n\t\tstructToSend.dynamicArray = new UnsignedNumber[](3);\n\t\tstructToSend.dynamicArray[0] = UnsignedNumber.wrap(0);\n\t\tstructToSend.dynamicArray[1] = UnsignedNumber.wrap(1);\n\t\tstructToSend.dynamicArray[2] = UnsignedNumber.wrap(2);\n\t\tstructToSend.justAnInt = 6;\n\t\tstructToSend.name = \"StructName\";\n\t\tstructToSend.someBytes = bytes(\"1234\");\n\t\tstructToSend.theEnum = Enum.Second;\n\n\t\t(bool success,) = address(this).call(abi.encodeCall(this.callMeMaybe, (\n\t\t\tstructToSend,\n\t\t\t5,\n\t\t\t\"TestName\"\n\t\t)));\n\n\t\treturn success;\n\t}\n}\n// ----\n// callExternal() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_declaration.sol",
    "content": "pragma abicoder v2;\n\ncontract X {\n    // no \"returns\" on purpose\n    function a(uint) public pure {}\n    function b(uint) external pure {}\n}\n\ncontract Base {\n    function a(uint x) external pure returns (uint) { return x + 1; }\n}\n\ncontract C is Base {\n\tfunction test() public view returns (uint r) {\n        bool success;\n        bytes memory result;\n        (success, result) = address(this).staticcall(abi.encodeCall(X.a, 1));\n        require(success && result.length == 32);\n        r += abi.decode(result, (uint));\n        require(r == 2);\n\n        (success, result) = address(this).staticcall(abi.encodeCall(X.b, 10));\n        require(success && result.length == 32);\n        r += abi.decode(result, (uint));\n        require(r == 13);\n\n        (success, result) = address(this).staticcall(abi.encodeCall(Base.a, 100));\n        require(success && result.length == 32);\n        r += abi.decode(result, (uint));\n        require(r == 114);\n\n        (success, result) = address(this).staticcall(abi.encodeCall(this.a, 1000));\n        require(success && result.length == 32);\n        r += abi.decode(result, (uint));\n        require(r == 1115);\n\n        (success, result) = address(this).staticcall(abi.encodeCall(C.b, 10000));\n        require(success && result.length == 32);\n        r += abi.decode(result, (uint));\n        require(r == 11116);\n\n        return r;\n\t}\n    function b(uint x) external view returns (uint) {\n        return this.a(x);\n    }\n\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test() -> 11116\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_is_consistent.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction(uint256, string memory) external fPointer;\n\tfunction fExternal(uint256 p, string memory t) external {}\n\tstring xstor;\n\tfunction getExternalFunctionPointer() public returns (function(uint256, string memory) external) {\n\t\tsideEffectRan = true;\n\t\treturn this.fExternal;\n\t}\n\n\tfunction fSignatureFromLiteral() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fExternal(uint256,string)\", 1, \"123\");\n\t}\n\tfunction fSignatureFromLiteralCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1, \"123\"));\n\t}\n\tfunction fSignatureFromMemory() public pure returns (bytes memory) {\n\t\tstring memory x = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(x, 1, \"123\");\n\t}\n\tfunction fSignatureFromMemoryCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1,\"123\"));\n\t}\n\tfunction fSignatureFromMemorys() public returns (bytes memory) {\n\t\txstor = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(xstor, 1, \"123\");\n\t}\n\tfunction fPointerCall() public returns(bytes memory) {\n\t\tfPointer = this.fExternal;\n\t\treturn abi.encodeCall(fPointer, (1, \"123\"));\n\t}\n\tfunction fLocalPointerCall() public returns(bytes memory) {\n\t\tfunction(uint256, string memory) external localFunctionPointer = this.fExternal;\n\t\treturn abi.encodeCall(localFunctionPointer, (1, \"123\"));\n\t}\n\tfunction fReturnedFunctionPointer() public returns (bytes memory) {\n\t\treturn abi.encodeCall(getExternalFunctionPointer(), (1, \"123\"));\n\t}\n\n\tfunction assertConsistentSelectors() public {\n\t\tassert(keccak256(fSignatureFromLiteral()) == keccak256(fSignatureFromLiteralCall()));\n\t\tassert(keccak256(fSignatureFromMemory()) == keccak256(fSignatureFromMemoryCall()));\n\t\tassert(keccak256(fSignatureFromMemoryCall()) == keccak256(fSignatureFromMemorys()));\n\t\tassert(keccak256(fPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fLocalPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fReturnedFunctionPointer()) == keccak256(fSignatureFromLiteral()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteral() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromLiteralCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemory() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemoryCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemorys() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fLocalPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fReturnedFunctionPointer() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract D {\n\tfunction something() external pure {}\n}\n\ncontract C {\n\tfunction something() external pure {}\n\tfunction test() external returns (bytes4) {\n\t\tfunction() external[2] memory x;\n\t\tx[0] = this.something;\n\t\tx[1] = (new D()).something;\n\t\tfunction() external f = x[1];\n\t\tbytes memory a = abi.encodeCall(x[0], ());\n\t\tbytes memory b = abi.encodeCall(x[1], ());\n\t\tbytes memory c = abi.encodeCall(f, ());\n\t\tassert(a.length == 4 && b.length == 4 && c.length == 4);\n\t\tassert(bytes4(a) == bytes4(b));\n\t\tassert(bytes4(a) == bytes4(c));\n\t\tassert(bytes4(a) == f.selector);\n\t\treturn bytes4(a);\n\t}\n}\n// ----\n// test() -> 0xa7a0d53700000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_special_args.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_call_uint_bytes.sol",
    "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_empty_string_v1.sol",
    "content": "pragma abicoder v1;\n// Tests that this will not end up using a \"bytes0\" type\n// (which would assert)\ncontract C {\n    function f() public pure returns (bytes memory, bytes memory) {\n        return (abi.encode(\"\"), abi.encodePacked(\"\"));\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f() -> 0x40, 0xa0, 0x40, 0x20, 0x0, 0x0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_selector.sol",
    "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_selectorv2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n\tstruct S { uint a; string b; uint16 c; }\n\tfunction f4() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\tS memory s;\n\t\ts.a = 0x1234567;\n\t\ts.b = \"Lorem ipsum dolor sit ethereum........\";\n\t\ts.c = 0x1234;\n\t\treturn abi.encodeWithSelector(x, type(uint).max, s, uint(3));\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n// f4() -> 0x20, 292, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_signature.sol",
    "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"f(uint256)\");\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\tstring memory x = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(x, \"abc\");\n\t}\n\tstring xstor;\n\tfunction f1s() public returns (bytes memory) {\n\t\txstor = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(xstor, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory r, uint[] memory ar) {\n\t\tstring memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n\t\tuint[] memory y = new uint[](4);\n\t\ty[0] = type(uint).max;\n\t\ty[1] = type(uint).max - 1;\n\t\ty[2] = type(uint).max - 2;\n\t\ty[3] = type(uint).max - 3;\n\t\tr = abi.encodeWithSignature(x, y);\n\t\t// The hash uses temporary memory. This allocation reuses the memory\n\t\t// and should initialize it properly.\n\t\tar = new uint[](2);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/abi_encode_with_signaturev2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n    function f0() public pure returns (bytes memory) {\n        return abi.encodeWithSignature(\"f(uint256)\");\n    }\n    function f1() public pure returns (bytes memory) {\n        string memory x = \"f(uint256)\";\n        return abi.encodeWithSignature(x, \"abc\");\n    }\n    string xstor;\n    function f1s() public returns (bytes memory) {\n        xstor = \"f(uint256)\";\n        return abi.encodeWithSignature(xstor, \"abc\");\n    }\n    function f2() public pure returns (bytes memory r, uint[] memory ar) {\n        string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n        uint[] memory y = new uint[](4);\n        y[0] = type(uint).max;\n        y[1] = type(uint).max - 1;\n        y[2] = type(uint).max - 2;\n        y[3] = type(uint).max - 3;\n        r = abi.encodeWithSignature(x, y);\n        // The hash uses temporary memory. This allocation reuses the memory\n        // and should initialize it properly.\n        ar = new uint[](2);\n    }\n    struct S { uint a; string b; uint16 c; }\n    function f4() public pure returns (bytes memory) {\n        S memory s;\n        s.a = 0x1234567;\n        s.b = \"Lorem ipsum dolor sit ethereum........\";\n        s.c = 0x1234;\n        return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n    }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/contract_array.sol",
    "content": "contract C {\n  function f(bytes calldata x) public returns (C[] memory) {\n    return abi.decode(x, (C[]));\n  }\n  function g() public returns (bytes memory) {\n    C[] memory c = new C[](3);\n    c[0] = C(address(0x42));\n    c[1] = C(address(0x21));\n    c[2] = C(address(0x23));\n    return abi.encode(c);\n  }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/contract_array_v2.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n  function f(bytes calldata x) public returns (C[] memory) {\n    return abi.decode(x, (C[]));\n  }\n  function g() public returns (bytes memory) {\n    C[] memory c = new C[](3);\n    c[0] = C(address(0x42));\n    c[1] = C(address(0x21));\n    c[2] = C(address(0x23));\n    return abi.encode(c);\n  }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/offset_overflow_in_array_decoding.sol",
    "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t  uint(0)); // bogus first element\n\t\t/*\n\t\t  At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t  Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t  The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t  x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t  that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/offset_overflow_in_array_decoding_2.sol",
    "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t  uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t  As above, but in this case we are adding to:\n\t\t  0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t  giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t  Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncodeDecode/offset_overflow_in_array_decoding_3.sol",
    "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n            uint(32),\n            uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n            uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n        );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_decode_dynamic_array.sol",
    "content": "contract C {\n    function f(bytes calldata data) external pure returns (uint256[] memory) {\n        return abi.decode(data, (uint256[]));\n    }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_decode_fixed_arrays.sol",
    "content": "contract C {\n    function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k)\n            public pure returns (uint, uint) {\n        return (a[i], b[j][k]);\n    }\n}\n// ----\n// f(uint16[3],uint16[2][3],uint256,uint256,uint256): 1, 2, 3, 11, 12, 21, 22, 31, 32, 1, 2, 1 -> 2, 32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_decode_static_array.sol",
    "content": "contract C {\n    function f(bytes calldata data)\n        external\n        pure\n        returns (uint256[2][3] memory)\n    {\n        return abi.decode(data, (uint256[2][3]));\n    }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_decode_static_array_v2.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(bytes calldata data)\n        external\n        pure\n        returns (uint256[2][3] memory)\n    {\n        return abi.decode(data, (uint256[2][3]));\n    }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_decode_trivial.sol",
    "content": "contract C {\n    function f(bytes memory data) public pure returns (uint256) {\n        return abi.decode(data, (uint256));\n    }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint256[] b;\n    }\n\n    function f() public pure returns (S memory) {\n        S memory s;\n        s.a = 8;\n        s.b = new uint256[](3);\n        s.b[0] = 9;\n        s.b[1] = 10;\n        s.b[2] = 11;\n        return abi.decode(abi.encode(s), (S));\n    }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_calldata.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint256[] b;\n    }\n\n    function f(bytes calldata data) external pure returns (S memory) {\n        return abi.decode(data, (S));\n    }\n}\n// ----\n// f(bytes): 0x20, 0xe0, 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc -> 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    bytes data;\n    struct S {\n        uint256 a;\n        uint256[] b;\n    }\n\n    function f() public returns (S memory) {\n        S memory s;\n        s.a = 8;\n        s.b = new uint256[](3);\n        s.b[0] = 9;\n        s.b[1] = 10;\n        s.b[2] = 11;\n        data = abi.encode(s);\n        return abi.decode(data, (S));\n    }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203109\n// gas legacy: 206263\n// gas legacyOptimized: 203177\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_encode.sol",
    "content": "contract C {\n    function f0() public returns (bytes memory) {\n        return abi.encode();\n    }\n\n    function f1() public returns (bytes memory) {\n        return abi.encode(1, 2);\n    }\n\n    function f2() public returns (bytes memory) {\n        string memory x = \"abc\";\n        return abi.encode(1, x, 2);\n    }\n\n    function f3() public returns (bytes memory r) {\n        // test that memory is properly allocated\n        string memory x = \"abc\";\n        r = abi.encode(1, x, 2);\n        bytes memory y = \"def\";\n        require(y[0] == \"d\");\n        y[0] = \"e\";\n        require(y[0] == \"e\");\n    }\n\n    function f4() public returns (bytes memory) {\n        bytes4 x = \"abcd\";\n        return abi.encode(bytes2(x));\n    }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x20, \"ab\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_encode_call.sol",
    "content": "contract C {\n    bool x;\n\n    function c(uint256 a, uint256[] memory b) public {\n        require(a == 5);\n        require(b.length == 2);\n        require(b[0] == 6);\n        require(b[1] == 7);\n        x = true;\n    }\n\n    function f() public returns (bool) {\n        uint256 a = 5;\n        uint256[] memory b = new uint256[](2);\n        b[0] = 6;\n        b[1] = 7;\n        (bool success, ) = address(this).call(\n            abi.encodeWithSignature(\"c(uint256,uint256[])\", a, b)\n        );\n        require(success);\n        return x;\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol",
    "content": "contract C {\n\tfunction enc_packed_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(data[start:end]);\n\t}\n\tfunction enc_packed_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(bytes(data[start:end]));\n\t}\n\n\tfunction enc_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(data[start:end]);\n\t}\n\tfunction enc_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(bytes(data[start:end]));\n\t}\n\n\tfunction enc_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\tfunction enc_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\n\tfunction enc_packed_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\tfunction enc_packed_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\n\tfunction compare(bytes memory x, bytes memory y) internal {\n\t\tassert(x.length == y.length);\n\t\tfor (uint i = 0; i < x.length; ++i)\n\t\t\tassert(x[i] == y[i]);\n\t}\n\n\tfunction test_bytes() public {\n\t\tbytes memory test = new bytes(3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_bytes(test, i, j), this.enc_packed_bytes_reference(test, i, j));\n\t\t\t\tcompare(this.enc_bytes(test, i, j), this.enc_bytes_reference(test, i, j));\n\t\t\t}\n\t}\n\n\tfunction test_uint256() public {\n\t\tuint256[] memory test = new uint256[](3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_uint256(test, i, j), this.enc_packed_uint256_reference(test, i, j));\n\t\t\t\tcompare(this.enc_uint256(test, i, j), this.enc_uint256_reference(test, i, j));\n\t\t\t}\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test_bytes() ->\n// gas irOptimized: 314884\n// gas legacy: 305816\n// gas legacyOptimized: 253573\n// test_uint256() ->\n// gas irOptimized: 448346\n// gas legacy: 421304\n// gas legacyOptimized: 351544\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_encode_decode_simple.sol",
    "content": "contract C {\n    function f() public pure returns (uint256, bytes memory) {\n        bytes memory arg = \"abcdefg\";\n        return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n    }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_encode_empty_string.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f1() public returns (bytes memory) {\n        return abi.encode(\"\");\n    }\n    function f2(string calldata msg) public returns (bytes memory) {\n        return abi.encode(msg);\n    }\n    function g1() public returns (bytes memory) {\n        return abi.encodePacked(\"\");\n    }\n    function g2(string calldata msg) public returns (bytes memory) {\n        return abi.encodePacked(msg);\n    }\n    function h1() public returns (bytes memory) {\n        return abi.encodeWithSelector(0x00000001, \"\");\n    }\n    function h2(string calldata msg) public returns (bytes memory) {\n        return abi.encodeWithSelector(0x00000001, msg);\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/abi_encode_rational.sol",
    "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n    function f() public pure returns (bytes memory) {\n        return abi.encode(1, -2);\n    }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/bool_out_of_bounds.sol",
    "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/byte_arrays.sol",
    "content": "contract C {\n    function f(uint a, bytes memory b, uint c)\n            public pure returns (uint, uint, bytes1, uint) {\n        return (a, b.length, b[3], c);\n    }\n\n    function f_external(uint a, bytes calldata b, uint c)\n            external pure returns (uint, uint, bytes1, uint) {\n        return (a, b.length, b[3], c);\n    }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/calldata_arrays_too_large.sol",
    "content": "contract C {\n    function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n        return 7;\n    }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/calldata_bytes_bytes32_arrays.sol",
    "content": "pragma abicoder v1;\n\ncontract C {\n    function f(bool a, bytes calldata b, bytes32[2] calldata c)\n        public\n        returns (bool, bytes calldata, bytes32[2] calldata)\n    {\n        return (a, b, c);\n    }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bool,bytes,bytes32[2]): true, 0x80, \"a\", \"b\", 4, \"abcd\" -> true, 0x80, \"a\", \"b\", 4, \"abcd\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/cleanup/cleanup.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f(uint16 a, int16 b, address c, bytes3 d, bool e)\n            public pure returns (uint v, uint w, uint x, uint y, uint z) {\n        assembly { v := a  w := b x := c y := d z := e}\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint16,int16,address,bytes3,bool): 1, 2, 3, \"a\", true -> 1, 2, 3, \"a\", true\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"abcd\", 1 -> 0xffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffff, \"abc\", true\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, \"bcd\", 1 -> 0xffff, 0, 0, \"bcd\", true\n// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, \"ab\", 1 -> 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0, \"ab\", true\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"ad\", 1 -> 0, 0, 0xffffffffffffffffffffffffffffffffffffffff, \"ad\", true\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abcd\", 1 -> 0, 0, 0, \"abc\", true\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abc\", 2 -> 0, 0, 0, \"abc\", true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/decode_slice.sol",
    "content": "contract C {\n    function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n        (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n        e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n        f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n    }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/dynamic_arrays.sol",
    "content": "contract C {\n    function f(uint a, uint16[] memory b, uint c)\n            public pure returns (uint, uint, uint) {\n        return (b.length, b[a], c);\n    }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/dynamic_memory_copy.sol",
    "content": "contract C {\n    function test(bytes memory buf) public view returns (bool same, bool inplaceDecoded) {\n        (uint256[] memory arr1, uint256[] memory arr2) = abi.decode(buf, (uint256[],uint256[]));\n        assembly {\n            // Check whether arr1 and arr2 end up at the same memory location.\n            // This used to be the case, if both tail pointers in buf pointed to the\n            // same memory region, i.e. this used to be false in the first two, but true\n            // in the last three calls below. The desired behaviour is to always get distinct\n            // memory regions, i.e. this should be false.\n            same := eq(arr1, arr2)\n            // Check whether (given the particular tail pointer of 0x40 for arr1 in the calls below)\n            // arr1 points to the part of buf containing the encoding of arr1.\n            // The position of the encoding of arr1 in buf is at offset 0x20 (length) + 0x40 (tail pointer)\n            // of buf.\n            // This used to be the case for all the test calls below, whereas now arr1 is always copied\n            // from buf to a new memory area. Should always be false.\n            inplaceDecoded := eq(arr1, add(buf, 0x60))\n        }\n    }\n}\n// ----\n// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false\n// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x60, 0x40, 0x40, 0 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/enums.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    enum E { A, B }\n    function f(E e) public pure returns (uint x) {\n        assembly { x := e }\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/memory_dynamic_array_and_calldata_bytes.sol",
    "content": "pragma abicoder v1;\n\ncontract C {\n    function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n        return abi.encode(a, b);\n    }\n\n    function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n        return f(a, b);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/memory_params_in_external_function.sol",
    "content": "contract C {\n    function f(bytes memory a, bytes calldata b, uint[] memory c)\n        external\n        pure\n        returns (uint, bytes1, uint, bytes1, uint, uint)\n    {\n        return (a.length, a[1], b.length, b[2], c.length, c[3]);\n    }\n    function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n        uint[] memory x = new uint[](4);\n        x[3] = 7;\n        return this.f(\"abc\", \"def\", x);\n    }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_advanced.sol",
    "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_out_of_range_1.sol",
    "content": "contract C {\n    function dyn(uint x) public returns (bytes memory a) {\n        assembly {\n            mstore(0, 0x20)\n            mstore(0x20, 0x21)\n            return(0, x)\n        }\n    }\n    function f(uint x) public returns (bool) {\n        this.dyn(x);\n        return true;\n    }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_out_of_range_2.sol",
    "content": "contract C {\n    function dyn(uint x) public returns (bytes memory a) {\n        assembly {\n            mstore(0, 0x20)\n            mstore(0x20, 0x21)\n            return(0, x)\n        }\n    }\n    function f(uint x) public returns (bool) {\n        this.dyn(x);\n        return true;\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/return_dynamic_types_cross_call_simple.sol",
    "content": "contract C {\n    function dyn() public returns (bytes memory) {\n        return \"1234567890123456789012345678901234567890\";\n    }\n    function f() public returns (bytes memory) {\n        return this.dyn();\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol",
    "content": "library L {\n\tstruct S { uint x; uint y; }\n\tfunction f(uint[] storage r, S storage s) public returns (uint, uint, uint, uint) {\n\t\tr[2] = 8;\n\t\ts.x = 7;\n\t\treturn (r[0], r[1], s.x, s.y);\n\t}\n}\ncontract C {\n\tuint8 x = 3;\n\tL.S s;\n\tuint[] r;\n\tfunction f() public returns (uint, uint, uint, uint, uint, uint) {\n\t\tr = new uint[](6);\n\t\tr[0] = 1;\n\t\tr[1] = 2;\n\t\tr[2] = 3;\n\t\ts.x = 11;\n\t\ts.y = 12;\n\t\t(uint a, uint b, uint c, uint d) = L.f(r, s);\n\t\treturn (r[2], s.x, a, b, c, d);\n\t}\n}\n// ----\n// library: L\n// f() -> 8, 7, 1, 2, 7, 12\n// gas irOptimized: 166766\n// gas legacy: 170486\n// gas legacyOptimized: 167252\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n\tfunction enc_packed_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(data[start:end]);\n\t}\n\tfunction enc_packed_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(bytes(data[start:end]));\n\t}\n\n\tfunction enc_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(data[start:end]);\n\t}\n\tfunction enc_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(bytes(data[start:end]));\n\t}\n\n\tfunction enc_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\tfunction enc_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\n\tfunction enc_packed_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\tfunction enc_packed_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\n\tfunction compare(bytes memory x, bytes memory y) internal {\n\t\tassert(x.length == y.length);\n\t\tfor (uint i = 0; i < x.length; ++i)\n\t\t\tassert(x[i] == y[i]);\n\t}\n\n\tfunction test_bytes() public {\n\t\tbytes memory test = new bytes(3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_bytes(test, i, j), this.enc_packed_bytes_reference(test, i, j));\n\t\t\t\tcompare(this.enc_bytes(test, i, j), this.enc_bytes_reference(test, i, j));\n\t\t\t}\n\t}\n\n\tfunction test_uint256() public {\n\t\tuint256[] memory test = new uint256[](3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_uint256(test, i, j), this.enc_packed_uint256_reference(test, i, j));\n\t\t\t\tcompare(this.enc_uint256(test, i, j), this.enc_uint256_reference(test, i, j));\n\t\t\t}\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test_bytes() ->\n// gas irOptimized: 314884\n// gas legacy: 305816\n// gas legacyOptimized: 253573\n// test_uint256() ->\n// gas irOptimized: 448346\n// gas legacy: 421304\n// gas legacyOptimized: 351544\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/abi_encode_empty_string_v2.sol",
    "content": "// Tests that this will not end up using a \"bytes0\" type\n// (which would assert)\npragma abicoder               v2;\n\n\ncontract C {\n    function f() public pure returns (bytes memory, bytes memory) {\n        return (abi.encode(\"\"), abi.encodePacked(\"\"));\n    }\n}\n// ----\n// f() -> 0x40, 0xa0, 0x40, 0x20, 0x0, 0x0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/abi_encode_rational_v2.sol",
    "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder               v2;\n\n\ncontract C {\n    function f() public pure returns (bytes memory) {\n        return abi.encode(1, -2);\n    }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint256[] b;\n    }\n\n    function f0() public pure returns (bytes memory) {\n        return abi.encode();\n    }\n\n    function f1() public pure returns (bytes memory) {\n        return abi.encode(1, 2);\n    }\n\n    function f2() public pure returns (bytes memory) {\n        string memory x = \"abc\";\n        return abi.encode(1, x, 2);\n    }\n\n    function f3() public pure returns (bytes memory r) {\n        // test that memory is properly allocated\n        string memory x = \"abc\";\n        r = abi.encode(1, x, 2);\n        bytes memory y = \"def\";\n        require(y[0] == \"d\");\n        y[0] = \"e\";\n        require(y[0] == \"e\");\n    }\n\n    S s;\n\n    function f4() public returns (bytes memory r) {\n        string memory x = \"abc\";\n        s.a = 7;\n        s.b.push(2);\n        s.b.push(3);\n        r = abi.encode(1, x, s, 2);\n        bytes memory y = \"def\";\n        require(y[0] == \"d\");\n        y[0] = \"e\";\n        require(y[0] == \"e\");\n    }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol",
    "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n    uint a;\n    uint[2] b;\n    uint c;\n}\n\ncontract A {\n    function get() public view returns (Data memory) {\n        return Data(5, [uint(66), 77], 8);\n    }\n}\n\ncontract B {\n    function foo(A _a) public returns (uint) {\n        return _a.get().b[1];\n    }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n    function test() public returns (uint) {\n        return foo(new A());\n    }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol",
    "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n    uint value;\n}\n\ncontract A {\n    function get() public view returns (Data memory) {\n        return Data(5);\n    }\n}\n\ncontract B {\n    uint x = 10;\n    uint y = 10;\n\n    modifier updateStorage() {\n        A a = new A();\n        x = a.get().value;\n        _;\n        y = a.get().value;\n    }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n    function test()\n        public\n        updateStorage\n        returns (uint, uint)\n    {\n        return (x, y);\n    }\n}\n// ----\n// test() -> 5, 10\n// gas irOptimized: 65040\n// gas irOptimized code: 26200\n// gas legacy: 66250\n// gas legacy code: 36400\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/abi_encoder_v2_head_overflow_with_static_array_cleanup_bug.sol",
    "content": "pragma abicoder v2;\n\nstruct T {\n    bytes x;\n    uint[3] y;\n}\n\ncontract E {\n    function f(bool a, T calldata b, bytes32[2] calldata c)\n        public\n        returns (bool, T calldata, bytes32[2] calldata)\n    {\n        return (a, b, c);\n    }\n}\n// ----\n// f(bool,(bytes,uint256[3]),bytes32[2]): 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\" -> 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/bool_out_of_bounds.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/byte_arrays.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    function f(uint a, bytes memory b, uint c)\n            public pure returns (uint, uint, bytes1, uint) {\n        return (a, b.length, b[3], c);\n    }\n\n    function f_external(uint a, bytes calldata b, uint c)\n            external pure returns (uint, uint, bytes1, uint) {\n        return (a, b.length, b[3], c);\n    }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function g(uint256[] calldata) external pure returns (bytes memory) {\n        return msg.data;\n    }\n    function f(uint256[][1] calldata s) external view returns (bool) {\n        bytes memory a = this.g(s[0]);\n        uint256[] memory m = s[0];\n        bytes memory b = this.g(m);\n        assert(a.length == b.length);\n        for (uint i = 0; i < a.length; i++)\n            assert(a[i] == b[i]);\n        return true;\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 98324\n// gas legacyOptimized: 94348\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_dynamic.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(uint256[] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function g(uint256[] calldata s) external view returns (bytes memory) {\n        return this.f(s);\n    }\n    function h(uint8[] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function i(uint8[] calldata s) external view returns (bytes memory) {\n        return this.h(s);\n    }\n    function j(bytes calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function k(bytes calldata s) external view returns (bytes memory) {\n        return this.j(s);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_dynamic_index_access.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(uint256[] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n        return this.f(s[which]);\n    }\n    function h(uint8[] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n        return this.h(s[which]);\n    }\n    function j(bytes calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n        return this.j(s[which]);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_dynamic_static_dynamic.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n        return msg.data;\n    }\n    function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n        return msg.data;\n    }\n    function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n        return this.f(s);\n    }\n    function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n        return this.f2(s);\n    }\n    function g() external returns (bytes memory) {\n        uint8[][1][] memory m = new uint8[][1][](1);\n        m[0][0] = new uint8[](1);\n        m[0][0][0] = 42;\n        return this.f(m);\n    }\n    function h() external returns (bytes memory) {\n        uint8[][1][] memory m = new uint8[][1][](1);\n        m[0][0] = new uint8[](1);\n        m[0][0][0] = 42;\n        return this.reenc_f(m);\n    }\n    function i() external returns (bytes memory) {\n        uint256[][2][] memory m = new uint256[][2][](1);\n        m[0][0] = new uint256[](1);\n        m[0][1] = new uint256[](1);\n        m[0][0][0] = 42;\n        m[0][1][0] = 42;\n        return this.f2(m);\n    }\n    function j() external returns (bytes memory) {\n        uint256[][2][] memory m = new uint256[][2][](1);\n        m[0][0] = new uint256[](1);\n        m[0][1] = new uint256[](1);\n        m[0][0][0] = 42;\n        m[0][1][0] = 42;\n        return this.reenc_f2(m);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_dynamic_static_in_library.sol",
    "content": "library L {\n    // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n    function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n        return (a, b);\n    }\n}\n\ncontract C {\n    function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n        return L.g(a, b);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_dynamic_static_short_decode.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(uint256[][2][] calldata x) external returns (uint256) {\n        x[0]; // trigger bounds checks\n        return 23;\n    }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_dynamic_static_short_reencode.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(uint256[][2][] calldata x) external returns (uint256) {\n        return 42;\n    }\n    function g(uint256[][2][] calldata x) external returns (uint256) {\n        return this.f(x);\n    }\n}\n// ----\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 42\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 42\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_function_types.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n        assert(s.length == 3);\n        return (s[0](), s[1](), s[2]());\n    }\n    function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n        return this.f(s);\n    }\n    function getter1() external returns (uint) {\n        return 23;\n    }\n    function getter2() external returns (uint) {\n        return 37;\n    }\n    function getter3() external returns (uint) {\n        return 71;\n    }\n    function g(bool reenc) external returns (uint, uint, uint) {\n        function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n        a[0] = this.getter1;\n        a[1] = this.getter2;\n        a[2] = this.getter3;\n        return reenc ? this.f_reenc(a) : this.f(a);\n    }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_multi_dynamic.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(uint256[][] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function g(uint256[][] calldata s) external view returns (bytes memory) {\n        return this.f(s);\n    }\n    function h(uint8[][] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function i(uint8[][] calldata s) external view returns (bytes memory) {\n        return this.h(s);\n    }\n    function j(bytes[] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function k(bytes[] calldata s) external view returns (bytes memory) {\n        return this.j(s);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// g(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// h(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// i(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// j(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n// k(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_short.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_short_no_revert_string.sol",
    "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_static.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(uint256[3] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function g(uint256[3] calldata s) external view returns (bytes memory) {\n        return this.f(s);\n    }\n    function h(uint8[3] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function i(uint8[3] calldata s) external view returns (bytes memory) {\n        return this.h(s);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[3]): 0xAB23, 0x1242, 0xFF87 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_static_dynamic_static.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n        return msg.data;\n    }\n    function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n        return msg.data;\n    }\n    function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n        return this.f(s);\n    }\n    function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n        return this.f2(s);\n    }\n    function g() external returns (bytes memory) {\n        uint8[1][][1] memory m = [new uint8[1][](1)];\n        m[0][0][0] = 42;\n        return this.f(m);\n    }\n    function h() external returns (bytes memory) {\n        uint8[1][][1] memory m = [new uint8[1][](1)];\n        m[0][0][0] = 42;\n        return this.reenc_f(m);\n    }\n    function i() external returns (bytes memory) {\n        uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n        m[0][0][0] = 0x00042;\n        m[0][0][1] = 0x00142;\n        m[1][0][0] = 0x10042;\n        m[1][0][1] = 0x10142;\n        return this.f2(m);\n    }\n    function j() external returns (bytes memory) {\n        uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n        m[0][0][0] = 0x00042;\n        m[0][0][1] = 0x00142;\n        m[1][0][0] = 0x10042;\n        m[1][0][1] = 0x10142;\n        return this.reenc_f2(m);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_static_index_access.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(uint256[3] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n        return this.f(s[which]);\n    }\n    function h(uint8[3] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n        return this.h(s[which]);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_struct_dynamic.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { uint256[] a; }\n    function f(S[] calldata s) external pure returns (bytes memory) {\n        return abi.encode(s);\n    }\n    function g(S[] calldata s) external view returns (bytes memory) {\n        return this.f(s);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_two_dynamic.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n        if (which)\n            return abi.encode(s1);\n        else\n            return abi.encode(s2);\n    }\n    function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n        return this.f(s1, s2, which);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_array_two_static.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n        if (which)\n            return abi.encode(s1);\n        else\n            return abi.encode(s2);\n    }\n    function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n        return this.f(s1, s2, which);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_dynamic_array_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    function f(uint[][] calldata a) public returns (uint[][] memory) {\n        return a;\n    }\n\n    function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n        return a;\n    }\n\n    function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n        return a;\n    }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_nested_array_reencode.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    function f(uint[][] calldata a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n    function g(uint8[][][] calldata a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n    function h(uint16[][2][] calldata a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n    function i(uint16[][][1] calldata a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n    function j(uint16[2][][] calldata a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 0x20, 0x80, 0x20, 1, 0x20, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 -> 0x20, 0x01a0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access offset\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0, 1 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 -> 0x20, 0x0200, 0x20, 2, 0x40, 288, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> 0x20, 0x0140, 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14, 15 -> 0x20, 0x0180, 0x20, 2, 0x40, 0xa0, 1, 10, 11, 2, 12, 13, 14, 15\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_nested_array_static_reencode.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_dynamic_arrays.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    uint[] s;\n    uint[2] n;\n\n    function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n        return (a, b);\n    }\n\n    function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n        return abi.encode(a, b);\n    }\n\n    function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n        return abi.encode(a[which], b[1]);\n    }\n\n    function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n        s = a;\n        n = b;\n        return abi.encode(s);\n    }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111356\n// gas legacy: 113826\n// gas legacyOptimized: 111724\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_overlapped_nested_dynamic_arrays.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    uint[] s;\n    uint[2] n;\n\n    function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n        return a;\n    }\n\n    function f_encode(uint[][] calldata a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n\n    function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n        return a[which];\n    }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_struct_array_reencode.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct D { uint[] x; }\n    struct S { uint x; }\n\n    function f(D calldata a) public returns (bytes memory){\n        return abi.encode(a);\n    }\n\n    function g(D[2] calldata a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n\n    function h(D[][] calldata a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n\n    function i(D[2][] calldata a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n\n    function j(S[] memory a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n\n    function k(S[2] memory a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n\n    function l(S[][] memory a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_struct_dynamic.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { uint256[] a; }\n\n    function f(S calldata s) external returns (bytes memory) {\n        return abi.encode(s);\n    }\n\n    function g(S calldata s) external returns (bytes memory) {\n        return this.f(s);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_struct_member_offset.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct A {\n        uint256 a;\n        uint256[] b;\n    }\n    struct B {\n        A a;\n        uint256 b;\n    }\n    function g(B calldata b) external pure returns(uint256) {\n        return b.b;\n    }\n    function f() public view returns(uint256, uint256) {\n        uint256[] memory arr = new uint256[](20);\n        arr[0] = 31; arr[2] = 84;\n        B memory b = B(A(420, arr), 11);\n        return (b.b, this.g(b));\n    }\n}\n// ----\n// f() -> 11, 11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_struct_simple.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { uint256 a; }\n\n    function f(S calldata s) external returns (bytes memory) {\n        return abi.encode(s);\n    }\n\n    function g(S calldata s) external returns (bytes memory) {\n        return this.f(s);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_three_dimensional_dynamic_array_index_access.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S { uint[] a; }\n\n    function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n        return abi.encode(s[i][j]);\n    }\n\n    function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n        return abi.encode(s[i][j][k]);\n    }\n\n    function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n        return abi.encode(s[0][i]);\n    }\n\n    function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n        return abi.encode(s[i][j].a);\n    }\n\n    function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n        return abi.encode(s[i][j].a);\n    }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/calldata_with_garbage.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    uint[] aTmp;\n    uint[2] bTmp;\n\n    function f_memory(uint[] calldata a) public returns (uint[] memory) {\n        return a;\n    }\n\n    function f_encode(uint[] calldata a) public returns (bytes memory) {\n        return abi.encode(a);\n    }\n\n    function f_storage(uint[] calldata a) public returns (bytes memory) {\n        aTmp = a;\n        return abi.encode(aTmp);\n    }\n\n    function f_index(uint[] calldata a, uint which) public returns (uint) {\n        return a[which];\n    }\n\n    function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n        return (a, b);\n    }\n\n    function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n        return abi.encode(a, b);\n    }\n\n    function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n        aTmp = a;\n        bTmp = b;\n        return abi.encode(aTmp, bTmp);\n    }\n\n    function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n        return (a[which], b[0]);\n    }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/cleanup/address.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function g(address x) external pure returns (uint256 r) {\n        assembly { r := x }\n    }\n    function f(uint256 a) external view returns (uint256) {\n        address x;\n        assembly { x := a }\n        return this.g(x);\n    }\n}\n// ----\n// f(uint256): 0 -> 0\n// g(address): 0 -> 0 # test validation as well as sanity check #\n// f(uint256): 1 -> 1\n// g(address): 1 -> 1\n// f(uint256): 2 -> 2\n// g(address): 2 -> 2\n// f(uint256): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// f(uint256): 0x010000000000000000000000000000000000000000 -> 0\n// g(address): 0x010000000000000000000000000000000000000000 -> FAILURE\n// f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0x01abcdef0123456789abcdef0123456789abcdefff -> FAILURE\n// f(uint256): 0x01ffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0x01ffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// f(uint256): -1 -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): -1 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/cleanup/bool.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function gggg(bool x) external pure returns (bool) {\n        return x;\n    }\n    function f(uint256 a) external view returns (bool) {\n        bool x = false;\n        assembly { x := a }\n        return this.gggg(x);\n    }\n}\n// ----\n// f(uint256): 0 -> false\n// gggg(bool): 0 -> false # test validation as well as sanity check #\n// f(uint256): 1 -> true\n// gggg(bool): 1 -> true\n// f(uint256): 2 -> true\n// gggg(bool): 2 -> FAILURE\n// f(uint256): 0x1000 -> true\n// gggg(bool): 0x1000 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/cleanup/bytesx.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function gg1(bytes1 x) external pure returns (bytes32) {\n        return x;\n    }\n    function f1(bytes32 a) external view returns (bytes32) {\n        bytes1 x;\n        assembly { x := a }\n        return this.gg1(x);\n    }\n    function gg2(bytes2 x) external pure returns (bytes32) {\n        return x;\n    }\n    function f2(bytes32 a) external view returns (bytes32) {\n        bytes2 x;\n        assembly { x := a }\n        return this.gg2(x);\n    }\n    function gg4(bytes4 x) external pure returns (bytes32) {\n        return x;\n    }\n    function f4(bytes32 a) external view returns (bytes32) {\n        bytes4 x;\n        assembly { x := a }\n        return this.gg4(x);\n    }\n    function gg8(bytes8 x) external pure returns (bytes32) {\n        return x;\n    }\n    function f8(bytes32 a) external view returns (bytes32) {\n        bytes8 x;\n        assembly { x := a }\n        return this.gg8(x);\n    }\n    function g16(bytes16 x) external pure returns (bytes32) {\n        return x;\n    }\n    function f16(bytes32 a) external view returns (bytes32) {\n        bytes16 x;\n        assembly { x := a }\n        return this.g16(x);\n    }\n}\n// ----\n// f1(bytes32): left(0) -> left(0)\n// gg1(bytes1): left(0) -> left(0) # test validation as well as sanity check #\n// f1(bytes32): left(1) -> left(1)\n// gg1(bytes1): left(1) -> left(1)\n// f1(bytes32): left(0xFE) -> left(0xFE)\n// gg1(bytes1): left(0xFE) -> left(0xFE)\n// f1(bytes32): left(0xFF) -> left(0xFF)\n// gg1(bytes1): left(0xFF) -> left(0xFF)\n// f1(bytes32): left(0x0001) -> left(0x00)\n// gg1(bytes1): left(0x0001) -> FAILURE\n// f1(bytes32): left(0x0101) -> left(0x01)\n// gg1(bytes1): left(0x0101) -> FAILURE\n// f1(bytes32): -1 -> left(0xFF)\n// gg1(bytes1): -1 -> FAILURE\n// f2(bytes32): left(0) -> left(0)\n// gg2(bytes2): left(0) -> left(0)\n// f2(bytes32): left(1) -> left(1)\n// gg2(bytes2): left(1) -> left(1)\n// f2(bytes32): left(0xFFFE) -> left(0xFFFE)\n// gg2(bytes2): left(0xFFFE) -> left(0xFFFE)\n// f2(bytes32): left(0xFFFF) -> left(0xFFFF)\n// gg2(bytes2): left(0xFFFF) -> left(0xFFFF)\n// f2(bytes32): left(0x000001) -> left(0x00)\n// gg2(bytes2): left(0x000001) -> FAILURE\n// f2(bytes32): left(0x010001) -> left(0x01)\n// gg2(bytes2): left(0x010001) -> FAILURE\n// f2(bytes32): -1 -> left(0xFFFF)\n// gg2(bytes2): -1 -> FAILURE\n// f4(bytes32): left(0) -> left(0)\n// gg4(bytes4): left(0) -> left(0)\n// f4(bytes32): left(1) -> left(1)\n// gg4(bytes4): left(1) -> left(1)\n// f4(bytes32): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// gg4(bytes4): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// f4(bytes32): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// gg4(bytes4): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// f4(bytes32): left(0x0000000001) -> left(0x00)\n// gg4(bytes4): left(0x0000000001) -> FAILURE\n// f4(bytes32): left(0x0100000001) -> left(0x01)\n// gg4(bytes4): left(0x0100000001) -> FAILURE\n// f4(bytes32): -1 -> left(0xFFFFFFFF)\n// gg4(bytes4): -1 -> FAILURE\n// f8(bytes32): left(0) -> left(0)\n// gg8(bytes8): left(0) -> left(0)\n// f8(bytes32): left(1) -> left(1)\n// gg8(bytes8): left(1) -> left(1)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// f8(bytes32): left(0x000000000000000001) -> left(0x00)\n// gg8(bytes8): left(0x000000000000000001) -> FAILURE\n// f8(bytes32): left(0x010000000000000001) -> left(0x01)\n// gg8(bytes8): left(0x010000000000000001) -> FAILURE\n// f8(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): -1 -> FAILURE\n// f16(bytes32): left(0) -> left(0)\n// g16(bytes16): left(0) -> left(0)\n// f16(bytes32): left(1) -> left(1)\n// g16(bytes16): left(1) -> left(1)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// f16(bytes32): left(0x0000000000000000000000000000000001) -> left(0x00)\n// g16(bytes16): left(0x0000000000000000000000000000000001) -> FAILURE\n// f16(bytes32): left(0x0100000000000000000000000000000001) -> left(0x01)\n// g16(bytes16): left(0x0100000000000000000000000000000001) -> FAILURE\n// f16(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): -1 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/cleanup/cleanup.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(uint16 a, int16 b, address c, bytes3 d, bool e)\n            public pure returns (uint v, uint w, uint x, uint y, uint z) {\n        assembly { v := a  w := b x := c y := d z := e}\n    }\n}\n// ----\n// f(uint16,int16,address,bytes3,bool): 1, 2, 3, \"a\", true -> 1, 2, 3, \"a\", true\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, \"bcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, \"ab\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"ad\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abc\", 2 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/cleanup/dynamic_array.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function ggg(uint8[] calldata s) external pure returns (bytes memory) {\n        s[0]; // only this will validate.\n        return msg.data;\n    }\n    function f(uint256[] calldata a) external returns (bytes memory) {\n        uint8[] memory m = new uint8[](a.length);\n        assembly {\n            calldatacopy(add(m, 0x20), 0x44, mul(calldataload(4), 0x20))\n        }\n        return this.ggg(m);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 0x20, 2, 1, 1 -> 0x20, 0x84, hex\"304a4c23\", 0x20, 2, 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// ggg(uint8[]): 0x20, 2, 1, 1 -> 0x20, 0x84, hex\"304a4c23\", 0x20, 2, 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256[]): 0x20, 2, 0x0101, 0x0101 -> 0x20, 0x84, hex\"304a4c23\", 0x20, 2, 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// ggg(uint8[]): 0x20, 2, 0x0101, 0x0101 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/cleanup/function.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { function() external f; }\n    function ggg(function() external x) external pure returns (uint256 r) {\n        assembly { r := calldataload(4) }\n    }\n    function h(S calldata x) external pure returns (uint256 r) {\n        x.f; // validation only happens here\n        assembly { r := calldataload(4) }\n    }\n    function dummy() external {}\n    function ffff(uint256 a) external view returns (uint256, uint256) {\n        S memory s = S(this.dummy);\n        assembly { mstore(s, a) }\n        return (this.ggg(s.f), this.h(s));\n    }\n}\n// ----\n// ffff(uint256): 0 -> 0, 0\n// ggg(function): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcdX\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcdX\" -> FAILURE\n// h((function)): \"01234567890123456789abcdX\" -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/cleanup/intx.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function ggg8(int8 x) external pure returns (int256) {\n        return x;\n    }\n    function gg16(int16 x) external pure returns (int256) {\n        return x;\n    }\n    function gg32(int32 x) external pure returns (int256) {\n        return x;\n    }\n    function gg64(int64 x) external pure returns (int256) {\n        return x;\n    }\n    function g128(int128 x) external pure returns (int256) {\n        return x;\n    }\n    function f8(int256 a) external view returns (int256) {\n        int8 x = 0;\n        assembly { x := a }\n        return this.ggg8(x);\n    }\n    function f16(int256 a) external view returns (int256) {\n        int16 x = 0;\n        assembly { x := a }\n        return this.gg16(x);\n    }\n    function f32(int256 a) external view returns (int256) {\n        int32 x = 0;\n        assembly { x := a }\n        return this.gg32(x);\n    }\n    function f64(int256 a) external view returns (int256) {\n        int64 x = 0;\n        assembly { x := a }\n        return this.gg64(x);\n    }\n    function f128(int256 a) external view returns (int256) {\n        int128 x = 0;\n        assembly { x := a }\n        return this.g128(x);\n    }\n}\n// ----\n// f8(int256): 0 -> 0\n// ggg8(int8): 0 -> 0 # test validation as well as sanity check #\n// f8(int256): 1 -> 1\n// ggg8(int8): 1 -> 1\n// f8(int256): -1 -> -1\n// ggg8(int8): -1 -> -1\n// f8(int256): 0x7F -> 0x7F\n// ggg8(int8): 0x7F -> 0x7F\n// f8(int256): 0x80 -> -128\n// ggg8(int8): 0x80 -> FAILURE\n// f8(int256): 0xFE -> -2\n// ggg8(int8): 0xFE -> FAILURE\n// f8(int256): 0xFF -> -1\n// ggg8(int8): 0xFF -> FAILURE\n// f8(int256): 0x0100 -> 0x00\n// ggg8(int8): 0x0100 -> FAILURE\n// f8(int256): 0x0101 -> 0x01\n// ggg8(int8): 0x0101 -> FAILURE\n// f8(int256): 0x01FF -> -1\n// ggg8(int8): 0x01FF -> FAILURE\n// f8(int256): 0x01FE -> -2\n// ggg8(int8): 0x01FE -> FAILURE\n// f16(int256): 0 -> 0\n// gg16(int16): 0 -> 0\n// f16(int256): 1 -> 1\n// gg16(int16): 1 -> 1\n// f16(int256): -1 -> -1\n// gg16(int16): -1 -> -1\n// f16(int256): 0x7FFF -> 0x7FFF\n// gg16(int16): 0x7FFF -> 0x7FFF\n// f16(int256): 0x8000 -> -32768\n// gg16(int16): 0x8000 -> FAILURE\n// f16(int256): 0xFFFE -> -2\n// gg16(int16): 0xFFFE -> FAILURE\n// f16(int256): 0xFFFF -> -1\n// gg16(int16): 0xFFFF -> FAILURE\n// f16(int256): 0x010000 -> 0x00\n// gg16(int16): 0x010000 -> FAILURE\n// f16(int256): 0x010001 -> 0x01\n// gg16(int16): 0x010001 -> FAILURE\n// f16(int256): 0x01FFFF -> -1\n// gg16(int16): 0x01FFFF -> FAILURE\n// f16(int256): 0x01FFFE -> -2\n// gg16(int16): 0x01FFFE -> FAILURE\n// f32(int256): 0 -> 0\n// gg32(int32): 0 -> 0\n// f32(int256): 1 -> 1\n// gg32(int32): 1 -> 1\n// f32(int256): -1 -> -1\n// gg32(int32): -1 -> -1\n// f32(int256): 0x7FFFFFFF -> 0x7FFFFFFF\n// gg32(int32): 0x7FFFFFFF -> 0x7FFFFFFF\n// f32(int256): 0x80000000 -> -2147483648\n// gg32(int32): 0x80000000 -> FAILURE\n// f32(int256): 0xFFFFFFFE -> -2\n// gg32(int32): 0xFFFFFFFE -> FAILURE\n// f32(int256): 0xFFFFFFFF -> -1\n// gg32(int32): 0xFFFFFFFF -> FAILURE\n// f32(int256): 0x0100000000 -> 0x00\n// gg32(int32): 0x0100000000 -> FAILURE\n// f32(int256): 0x0100000001 -> 0x01\n// gg32(int32): 0x0100000001 -> FAILURE\n// f32(int256): 0x01FFFFFFFF -> -1\n// gg32(int32): 0x01FFFFFFFF -> FAILURE\n// f32(int256): 0x01FFFFFFFE -> -2\n// gg32(int32): 0x01FFFFFFFE -> FAILURE\n// f64(int256): 0 -> 0\n// gg64(int64): 0 -> 0\n// f64(int256): 1 -> 1\n// gg64(int64): 1 -> 1\n// f64(int256): -1 -> -1\n// gg64(int64): -1 -> -1\n// f64(int256): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// gg64(int64): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// f64(int256): 0x8000000000000000 -> -9223372036854775808\n// gg64(int64): 0x8000000000000000 -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0xFFFFFFFFFFFFFFFE -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0xFFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x010000000000000000 -> 0x00\n// gg64(int64): 0x010000000000000000 -> FAILURE\n// f64(int256): 0x010000000000000001 -> 0x01\n// gg64(int64): 0x010000000000000001 -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0x01FFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0x01FFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0 -> 0\n// g128(int128): 0 -> 0\n// f128(int256): 1 -> 1\n// g128(int128): 1 -> 1\n// f128(int256): -1 -> -1\n// g128(int128): -1 -> -1\n// f128(int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(int128): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(int256): 0x80000000000000000000000000000000 -> -170141183460469231731687303715884105728\n// g128(int128): 0x80000000000000000000000000000000 -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000000 -> 0x00\n// g128(int128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000001 -> 0x01\n// g128(int128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/cleanup/reencoded_calldata_string.sol",
    "content": "contract C {\n    function f(string calldata x) external returns (bytes memory r) {\n        uint mptr;\n        assembly {\n            // dirty memory\n            mptr := mload(0x40)\n            for { let i := mptr } lt(i, add(mptr, 0x0100)) { i := add(i, 32) }\n            {\n                mstore(i, sub(0, 1))\n            }\n        }\n        r = abi.encode(x);\n        assembly {\n            // assert that we dirtied the memory that was encoded to\n            if iszero(eq(mptr, r)) {\n                revert(0, 0)\n            }\n        }\n    }\n    function test() external returns (bytes memory) {\n        return this.f(\"abc\");\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> 0x20, 0x60, 0x20, 3, \"abc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/cleanup/simple_struct.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { uint8 a; bytes1 b; }\n    function gg(S calldata s) external pure returns (bytes memory) {\n        s.a; s.b; // only this will validate.\n        return msg.data;\n    }\n    function f(uint256 a, bytes32 b) public returns (bytes memory) {\n        S memory s = S(2,0x02);\n        assembly {\n            mstore(s, a)\n            mstore(add(s, 0x20), b)\n        }\n        return this.gg(s);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/cleanup/static_array.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function gggggggg(uint8[2] calldata s) external pure returns (bytes memory) {\n        s[0]; // only this will validate.\n        return msg.data;\n    }\n    function f(uint256 a, uint256 b) public returns (bytes memory) {\n        uint8[2] memory m = [0,0];\n        assembly {\n            mstore(m, a)\n            mstore(add(m, 0x20), b)\n        }\n        return this.gggggggg(m);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,uint256): 1, 1 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// gggggggg(uint8[2]): 1, 1 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,uint256): 0x0101, 0x0101 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// gggggggg(uint8[2]): 0x0101, 0x0101 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/cleanup/uintx.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function ggg8(uint8 x) external pure returns (uint256) {\n        return x;\n    }\n    function gg16(uint16 x) external pure returns (uint256) {\n        return x;\n    }\n    function gg32(uint32 x) external pure returns (uint256) {\n        return x;\n    }\n    function gg64(uint64 x) external pure returns (uint256) {\n        return x;\n    }\n    function g128(uint128 x) external pure returns (uint256) {\n        return x;\n    }\n    function f8(uint256 a) external view returns (uint256) {\n        uint8 x = 0;\n        assembly { x := a }\n        return this.ggg8(x);\n    }\n    function f16(uint256 a) external view returns (uint256) {\n        uint16 x = 0;\n        assembly { x := a }\n        return this.gg16(x);\n    }\n    function f32(uint256 a) external view returns (uint256) {\n        uint32 x = 0;\n        assembly { x := a }\n        return this.gg32(x);\n    }\n    function f64(uint256 a) external view returns (uint256) {\n        uint64 x = 0;\n        assembly { x := a }\n        return this.gg64(x);\n    }\n    function f128(uint256 a) external view returns (uint256) {\n        uint128 x = 0;\n        assembly { x := a }\n        return this.g128(x);\n    }\n}\n// ----\n// f8(uint256): 0 -> 0\n// ggg8(uint8): 0 -> 0 # test validation as well as sanity check #\n// f8(uint256): 1 -> 1\n// ggg8(uint8): 1 -> 1\n// f8(uint256): 0xFE -> 0xFE\n// ggg8(uint8): 0xFE -> 0xFE\n// f8(uint256): 0xFF -> 0xFF\n// ggg8(uint8): 0xFF -> 0xFF\n// f8(uint256): 0x0100 -> 0x00\n// ggg8(uint8): 0x0100 -> FAILURE\n// f8(uint256): 0x0101 -> 0x01\n// ggg8(uint8): 0x0101 -> FAILURE\n// f8(uint256): -1 -> 0xFF\n// ggg8(uint8): -1 -> FAILURE\n// f16(uint256): 0 -> 0\n// gg16(uint16): 0 -> 0\n// f16(uint256): 1 -> 1\n// gg16(uint16): 1 -> 1\n// f16(uint256): 0xFFFE -> 0xFFFE\n// gg16(uint16): 0xFFFE -> 0xFFFE\n// f16(uint256): 0xFFFF -> 0xFFFF\n// gg16(uint16): 0xFFFF -> 0xFFFF\n// f16(uint256): 0x010000 -> 0x0000\n// gg16(uint16): 0x010000 -> FAILURE\n// f16(uint256): 0x010001 -> 0x0001\n// gg16(uint16): 0x010001 -> FAILURE\n// f16(uint256): -1 -> 0xFFFF\n// gg16(uint16): -1 -> FAILURE\n// f32(uint256): 0 -> 0\n// gg32(uint32): 0 -> 0\n// f32(uint256): 1 -> 1\n// gg32(uint32): 1 -> 1\n// f32(uint256): 0xFFFFFFFE -> 0xFFFFFFFE\n// gg32(uint32): 0xFFFFFFFE -> 0xFFFFFFFE\n// f32(uint256): 0xFFFFFFFF -> 0xFFFFFFFF\n// gg32(uint32): 0xFFFFFFFF -> 0xFFFFFFFF\n// f32(uint256): 0x0100000000 -> 0x00000000\n// gg32(uint32): 0x0100000000 -> FAILURE\n// f32(uint256): 0x0100000001 -> 0x00000001\n// gg32(uint32): 0x0100000001 -> FAILURE\n// f32(uint256): -1 -> 0xFFFFFFFF\n// gg32(uint32): -1 -> FAILURE\n// f64(uint256): 0 -> 0\n// gg64(uint64): 0 -> 0\n// f64(uint256): 1 -> 1\n// gg64(uint64): 1 -> 1\n// f64(uint256): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE\n// gg64(uint64): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE\n// f64(uint256): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF\n// gg64(uint64): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF\n// f64(uint256): 0x010000000000000000 -> 0x0000000000000000\n// gg64(uint64): 0x010000000000000000 -> FAILURE\n// f64(uint256): 0x010000000000000001 -> 0x0000000000000001\n// gg64(uint64): 0x010000000000000001 -> FAILURE\n// f64(uint256): -1 -> 0xFFFFFFFFFFFFFFFF\n// gg64(uint64): -1 -> FAILURE\n// f128(uint256): 0 -> 0\n// g128(uint128): 0 -> 0\n// f128(uint256): 1 -> 1\n// g128(uint128): 1 -> 1\n// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(uint256): 0x0100000000000000000000000000000000 -> 0x00000000000000000000000000000000\n// g128(uint128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(uint256): 0x0100000000000000000000000000000001 -> 0x00000000000000000000000000000001\n// g128(uint128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(uint256): -1 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(uint128): -1 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/dynamic_arrays.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(uint a, uint16[] memory b, uint c)\n            public pure returns (uint, uint, uint) {\n        return (b.length, b[a], c);\n    }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/dynamic_nested_arrays.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tfunction f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)\n\t\t\tpublic pure returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\treturn (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);\n\t}\n\tfunction test() public view returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\tuint16[][] memory b = new uint16[][](3);\n\t\tb[0] = new uint16[](2);\n\t\tb[0][0] = 0x55;\n\t\tb[0][1] = 0x56;\n\t\tb[1] = new uint16[](4);\n\t\tb[1][0] = 0x65;\n\t\tb[1][1] = 0x66;\n\t\tb[1][2] = 0x67;\n\t\tb[1][3] = 0x68;\n\n\t\tuint[2][][3] memory c;\n\t\tc[0] = new uint[2][](1);\n\t\tc[0][0][1] = 0x75;\n\t\tc[1] = new uint[2][](5);\n\t\tc[1][1][1] = 0x85;\n\n\t\treturn this.f(12, b, c, 13);\n\t}\n}\n// ----\n// test() -> 12, 3, 4, 0x66, 5, 0x85, 13\n// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/enums.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    enum E { A, B }\n    function f(E e) public pure returns (uint x) {\n        assembly { x := e }\n    }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/memory_dynamic_array_and_calldata_bytes.sol",
    "content": "contract C {\n    function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n        return abi.encode(a, b);\n    }\n\n    function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n        return f(a, b);\n    }\n}\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/memory_dynamic_array_and_calldata_static_array.sol",
    "content": "contract C {\n    function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n        return abi.encode(a, b);\n    }\n\n    function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n        return f(a, b);\n    }\n\n    function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n        return (a, b);\n    }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/memory_params_in_external_function.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    function f(bytes memory a, bytes calldata b, uint[] memory c)\n        external\n        pure\n        returns (uint, bytes1, uint, bytes1, uint, uint)\n    {\n        return (a.length, a[1], b.length, b[2], c.length, c[3]);\n    }\n    function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n        uint[] memory x = new uint[](4);\n        x[3] = 7;\n        return this.f(\"abc\", \"def\", x);\n    }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol",
    "content": "pragma abicoder               v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n    uint256[2][] tmp_h;\n    function h(uint256[2][] calldata s) external returns (bytes memory) {\n        tmp_h = s;\n        return abi.encode(tmp_h);\n    }\n    uint256[2][2] tmp_i;\n    function i(uint256[2][2] calldata s) external returns (bytes memory) {\n        tmp_i = s;\n        return abi.encode(tmp_i);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180022\n// gas legacy: 186541\n// gas legacyOptimized: 180429\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 116683\n// gas legacyOptimized: 112303\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre2_struct.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { C c; uint[] x; }\n    function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) {\n        r1 = a;\n        r2 = s1[0].c;\n        r3 = b;\n    }\n}\n// ----\n// f(uint256,(address,uint256[])[2],uint256): 7, 0x60, 8, 0x40, 0xE0, 0x0, 0x40, 2, 0x11, 0x12, 0x99, 0x40, 4, 0x31, 0x32, 0x34, 0x35 -> 7, 0x0, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre_struct.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { C c; }\n    function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) {\n        r1 = a;\n        r2 = s1[0].c;\n        r3 = b;\n    }\n}\n// ----\n// f(uint256,(address)[2],uint256): 7, 0, 0, 8 -> 7, 0, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/struct/struct_function.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { function () external returns (uint) f; uint b; }\n    function f(S memory s) public returns (uint, uint) {\n        return (s.f(), s.b);\n    }\n    function test() public returns (uint, uint) {\n        return this.f(S(this.g, 3));\n    }\n    function g() public returns (uint) { return 7; }\n}\n// ----\n// test() -> 7, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/struct/struct_short.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { int a; uint b; bytes16 c; }\n    function f(S memory s) public pure returns (S memory q) {\n        q = s;\n    }\n}\n// ----\n// f((int256,uint256,bytes16)): 0xff010, 0xff0002, \"abcd\" -> 0xff010, 0xff0002, \"abcd\"\n// f((int256,uint256,bytes16)): 0xff010, 0xff0002, 0x1111222233334444555566667777888800000000000000000000000000000000 -> 0xff010, 0xff0002, left(0x11112222333344445555666677778888)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/struct/struct_simple.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { uint a; uint8 b; uint8 c; bytes2 d; }\n    function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) {\n        a = s.a;\n        b = s.b;\n        c = s.c;\n        d = uint16(s.d);\n    }\n}\n// ----\n// f((uint256,uint8,uint8,bytes2)): 1, 2, 3, \"ab\" -> 1, 2, 3, 0x6162\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/struct/struct_validation.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct S { int16 a; uint8 b; bytes2 c; }\n\tfunction f(S memory s) public pure returns (uint a, uint b, uint c) {\n\t\tassembly {\n\t\t\ta := mload(s)\n\t\t\tb := mload(add(s, 0x20))\n\t\t\tc := mload(add(s, 0x40))\n\t\t}\n\t}\n}\n// ----\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\" -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\"\n// f((int16,uint8,bytes2)): 0xff010, 0xff, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff0002, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"abcd\" -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/abiEncoderV2/struct/validation_function_type_inside_struct.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { function () external x; }\n    function f(S memory) public pure returns (uint r) { r = 1; }\n    function g(S calldata) external pure returns (uint r) { r = 2; }\n    function h(S calldata s) external pure returns (uint r) { s.x; r = 3; }\n}\n// ----\n// f((function)): \"01234567890123456789abcd\" -> 1\n// f((function)): \"01234567890123456789abcdX\" -> FAILURE\n// g((function)): \"01234567890123456789abcd\" -> 2\n// g((function)): \"01234567890123456789abcdX\" -> 2\n// h((function)): \"01234567890123456789abcd\" -> 3\n// h((function)): \"01234567890123456789abcdX\" -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/accessor/accessor_for_const_state_variable.sol",
    "content": "contract Lotto {\n    uint256 public constant ticketPrice = 555;\n}\n// ----\n// ticketPrice() -> 555\n"
  },
  {
    "path": "test/libsolidity/semanticTests/accessor/accessor_for_state_variable.sol",
    "content": "contract Lotto {\n    uint256 public ticketPrice = 500;\n}\n// ----\n// ticketPrice() -> 500\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/addmod_mulmod.sol",
    "content": "contract C {\n    function test() public returns (uint256) {\n        // Note that this only works because computation on literals is done using\n        // unbounded integers.\n        if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n        if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n        return 0;\n    }\n}\n// ----\n// test() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/addmod_mulmod_zero.sol",
    "content": "contract C {\n    function f(uint256 d) public pure returns (uint256) {\n        addmod(1, 2, d);\n        return 2;\n    }\n\n    function g(uint256 d) public pure returns (uint256) {\n        mulmod(1, 2, d);\n        return 2;\n    }\n\n    function h() public pure returns (uint256) {\n        mulmod(0, 1, 2);\n        mulmod(1, 0, 2);\n        addmod(0, 1, 2);\n        addmod(1, 0, 2);\n        return 2;\n    }\n}\n// ----\n// f(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// h() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/block_inside_unchecked.sol",
    "content": "contract C {\n  function f() public returns (uint y) {\n    unchecked{{\n        uint max = type(uint).max;\n        uint x = max + 1;\n        y = x;\n    }}\n  }\n}\n// ----\n// f() -> 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/check_var_init.sol",
    "content": "contract C {\n    uint public x = msg.value - 10;\n    constructor() payable {}\n}\n\ncontract D {\n    function f() public {\n        unchecked {\n            new C();\n        }\n    }\n    function g() public payable returns (uint) {\n        return (new C{value: 11}()).x();\n    }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x11\n// g(), 100 wei -> 1\n// gas legacy: 76780\n// gas legacy code: 23600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/checked_add_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    // Input is still not checked - this needs ABIEncoderV2!\n    function f(uint16 a, uint16 b) public returns (uint16) {\n        return a + b;\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> 0x00\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/checked_add_v2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n    function f(uint16 a, uint16 b) public returns (uint16) {\n        return a + b;\n    }\n}\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> FAILURE\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/checked_called_by_unchecked.sol",
    "content": "contract C {\n    function add(uint16 a, uint16 b) public returns (uint16) {\n        return a + b;\n    }\n\n    function f(uint16 a, uint16 b, uint16 c) public returns (uint16) {\n        unchecked { return add(a, b) + c; }\n    }\n}\n// ----\n// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint16,uint16,uint16): 0xe000, 0x1000, 0x1000 -> 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/checked_modifier_called_by_unchecked.sol",
    "content": "contract C {\n    modifier add(uint16 a, uint16 b) {\n        unchecked { a + b; }\n        _;\n    }\n\n    function f(uint16 a, uint16 b, uint16 c) public add(a, b) returns (uint16) {\n        return b + c;\n    }\n}\n// ----\n// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> 58626\n// f(uint16,uint16,uint16): 0x1000, 0xe500, 0xe000 -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/divisiod_by_zero.sol",
    "content": "contract C {\n    function div(uint256 a, uint256 b) public returns (uint256) {\n        return a / b;\n    }\n\n    function mod(uint256 a, uint256 b) public returns (uint256) {\n        return a % b;\n    }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/exp_associativity.sol",
    "content": "contract C {\n    // (2**3)**4 = 4096\n    // 2**(3**4) = 2417851639229258349412352\n    function test_hardcode1(uint a, uint b, uint c) public returns (uint256) {\n        return a**b**c;\n    }\n\n    // (3**2)**2)**2 = 6561\n    // 3**(2**(2**2) = 43046721\n    function test_hardcode2(uint a, uint b, uint c, uint d) public returns (uint256) {\n        return a**b**c**d;\n    }\n\n    function test_invariant(uint a, uint b, uint c) public returns (bool) {\n        return a**b**c == a**(b**c);\n    }\n\n    function test_literal_mix(uint a, uint b) public returns (bool) {\n        return\n            (a**2**b == a**(2**b)) &&\n            (2**a**b == 2**(a**b)) &&\n            (a**b**2 == a**(b**2));\n    }\n\n    function test_other_operators(uint a, uint b) public returns (bool) {\n        return\n            (a**b/25 == (a**b)/25) &&\n            (a**b*3**b == (a**b)*(3**b)) &&\n            (b**a**a/b**a**b == (b**(a**a))/(b**(a**b)));\n     }\n}\n// ----\n// test_hardcode1(uint256,uint256,uint256): 2, 3, 4 -> 2417851639229258349412352\n// test_hardcode2(uint256,uint256,uint256,uint256): 3, 2, 2, 2 -> 43046721\n// test_invariant(uint256,uint256,uint256): 2, 3, 4 -> true\n// test_invariant(uint256,uint256,uint256): 3, 4, 2 -> true\n// test_literal_mix(uint256,uint256): 2, 3 -> true\n// test_other_operators(uint256,uint256): 2, 4 -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/signed_mod.sol",
    "content": "contract C {\n    function f(int a, int b) public pure returns (int) {\n        return a % b;\n    }\n    function g(bool _check) public pure returns (int) {\n        int x = type(int).min;\n        if (_check) {\n            return x / -1;\n        } else {\n            unchecked { return x / -1; }\n        }\n    }\n}\n// ----\n// f(int256,int256): 7, 5 -> 2\n// f(int256,int256): 7, -5 -> 2\n// f(int256,int256): -7, 5 -> -2\n// f(int256,int256): -7, 5 -> -2\n// f(int256,int256): -5, -5 -> 0\n// g(bool): true -> FAILURE, hex\"4e487b71\", 0x11\n// g(bool): false -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/unchecked_called_by_checked.sol",
    "content": "contract C {\n    function add(uint16 a, uint16 b) public returns (uint16) {\n        unchecked {\n            return a + b;\n        }\n    }\n\n    function f(uint16 a) public returns (uint16) {\n        return add(a, 0x100) + 0x100;\n    }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/arithmetics/unchecked_div_by_zero.sol",
    "content": "contract C {\n    function div(uint256 a, uint256 b) public returns (uint256) {\n        // Does not disable div by zero check\n        unchecked {\n            return a / b;\n        }\n    }\n\n    function mod(uint256 a, uint256 b) public returns (uint256) {\n        // Does not disable div by zero check\n        unchecked {\n            return a % b;\n        }\n    }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_2d_zeroed_memory_index_access.sol",
    "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint m, uint a, uint b) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[][] memory x = new uint[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tx[i] = new uint[](m);\n\t\treturn x[a][b];\n\t}\n}\n// ----\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 0, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 3, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 3, 3, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 5, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_array_static.sol",
    "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint m) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[4][] memory x = new uint[4][](n);\n\t\treturn x[m][0];\n\t}\n}\n// ----\n// set(string,uint256,uint256): 0x60, 2, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 2, 1, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 2, 2, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n// set(string,uint256,uint256): 0x60, 200, 199, 32, \"01234567890123456789012345678901\" -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_static_return_param_zeroed_memory_index_access.sol",
    "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public returns (uint[3] memory x, uint[2] memory y, uint[] memory z, uint t) {\n\t\tmap[s] = 0;\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" -> 0, 0, 0, 0, 0, 0xe0, 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_static_zeroed_memory_index_access.sol",
    "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[3] memory x;\n\t\treturn x[2];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/arrayMemoryAllocation/array_zeroed_memory_index_access.sol",
    "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint a) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[] memory x = new uint[](n);\n\t\treturn x[a];\n\t}\n}\n// ----\n// set(string,uint256,uint256): 0x60, 5, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 1, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 4, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 5, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_2d_assignment.sol",
    "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_2d_new.sol",
    "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_3d_assignment.sol",
    "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_3d_new.sol",
    "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_function_pointers.sol",
    "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_memory_as_parameter.sol",
    "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_memory_create.sol",
    "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_memory_index_access.sol",
    "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_push_return_reference.sol",
    "content": "contract C {\n    uint[] storageArray;\n    function test(uint256 v) public {\n        storageArray.push() = v;\n    }\n    function getLength() public view returns (uint256) {\n        return storageArray.length;\n    }\n    function fetch(uint256 a) public view returns (uint256) {\n        return storageArray[a];\n    }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_push_with_arg.sol",
    "content": "contract C {\n    uint[] storageArray;\n    function test(uint256 v) public {\n        storageArray.push(v);\n    }\n    function getLength() public view returns (uint256) {\n        return storageArray.length;\n    }\n    function fetch(uint256 a) public view returns (uint256) {\n        return storageArray[a];\n    }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_storage_index_access.sol",
    "content": "contract C {\n    uint[] storageArray;\n    function test_indices(uint256 len) public\n    {\n        while (storageArray.length < len)\n            storageArray.push();\n        while (storageArray.length > len)\n            storageArray.pop();\n        for (uint i = 0; i < len; i++)\n            storageArray[i] = i + 1;\n\n        for (uint i = 0; i < len; i++)\n            require(storageArray[i] == i + 1);\n    }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_storage_index_boundary_test.sol",
    "content": "contract C {\n    uint[] storageArray;\n    function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n    {\n        while(storageArray.length < len)\n            storageArray.push();\n        while(storageArray.length > len)\n            storageArray.pop();\n        return storageArray[access];\n    }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol",
    "content": "contract C {\n    uint[] storageArray;\n    function test_zeroed_indices(uint256 len) public\n    {\n        while(storageArray.length < len)\n            storageArray.push();\n        while(storageArray.length > len)\n            storageArray.pop();\n\n        for (uint i = 0; i < len; i++)\n            storageArray[i] = i + 1;\n\n        if (len > 3)\n        {\n            while(storageArray.length > 0)\n                storageArray.pop();\n            while(storageArray.length < 3)\n                storageArray.push();\n\n            for (uint i = 3; i < len; i++)\n            {\n                assembly {\n                    mstore(0, storageArray.slot)\n                    let pos := add(keccak256(0, 0x20), i)\n\n                    if iszero(eq(sload(pos), 0)) {\n                        revert(0, 0)\n                    }\n                }\n            }\n\n        }\n\n        while(storageArray.length > 0)\n            storageArray.pop();\n        while(storageArray.length < len)\n            storageArray.push();\n\n        for (uint i = 0; i < len; i++)\n        {\n            require(storageArray[i] == 0);\n\n            uint256 val = storageArray[i];\n            uint256 check;\n\n            assembly { check := iszero(val) }\n\n            require(check == 1);\n        }\n    }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_storage_length_access.sol",
    "content": "contract C {\n    uint[] storageArray;\n    function set_get_length(uint256 len) public returns (uint256) {\n        while(storageArray.length < len)\n            storageArray.push();\n        return storageArray.length;\n    }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 98764\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_storage_pop_zero_length.sol",
    "content": "contract C {\n    uint[] storageArray;\n    function popEmpty() public {\n        storageArray.pop();\n    }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_storage_push_empty.sol",
    "content": "contract C {\n    uint256[] storageArray;\n    function pushEmpty(uint256 len) public {\n        while(storageArray.length < len)\n            storageArray.push();\n\n        for (uint i = 0; i < len; i++)\n            require(storageArray[i] == 0);\n    }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_storage_push_empty_length_address.sol",
    "content": "contract C {\n    address[] addressArray;\n    function set_get_length(uint256 len) public returns (uint256)\n    {\n        while(addressArray.length < len)\n            addressArray.push();\n        while(addressArray.length > len)\n            addressArray.pop();\n        return addressArray.length;\n    }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 76123\n// gas legacy: 75618\n// gas legacyOptimized: 75076\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/array_storage_push_pop.sol",
    "content": "contract C {\n    uint[] storageArray;\n    function set_get_length(uint256 len) public returns (uint256) {\n        while(storageArray.length < len)\n            storageArray.push();\n        while(storageArray.length > 0)\n            storageArray.pop();\n        return storageArray.length;\n    }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 0\n// set_get_length(uint256): 10 -> 0\n// set_get_length(uint256): 20 -> 0\n// gas irOptimized: 87226\n// gas legacy: 85609\n// gas legacyOptimized: 83462\n// set_get_length(uint256): 0xFF -> 0\n// gas irOptimized: 833586\n// gas legacy: 807764\n// gas legacyOptimized: 784467\n// set_get_length(uint256): 0xFFF -> 0\n// gas irOptimized: 13029438\n// gas legacy: 12608096\n// gas legacyOptimized: 12239199\n// set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol",
    "content": "contract Test {\n    uint24[3][] public data;\n\n    function set(uint24[3][] memory _data) public returns (uint256) {\n        data = _data;\n        return data.length;\n    }\n\n    function get() public returns (uint24[3][] memory) {\n        return data;\n    }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185221\n// gas legacy: 199970\n// gas legacyOptimized: 186342\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/byte_array_storage_layout.sol",
    "content": "contract c {\n    bytes data;\n    function test_short() public returns (uint256 r) {\n        assembly {\n            sstore(data.slot, 0)\n        }\n        for (uint8 i = 0; i < 15; i++) {\n            data.push(bytes1(i));\n        }\n        assembly {\n            r := sload(data.slot)\n        }\n    }\n\n    function test_long() public returns (uint256 r) {\n        assembly {\n            sstore(data.slot, 0)\n        }\n        for (uint8 i = 0; i < 33; i++) {\n            data.push(bytes1(i));\n        }\n        assembly {\n            r := sload(data.slot)\n        }\n    }\n\n    function test_pop() public returns (uint256 r) {\n        assembly {\n            sstore(data.slot, 0)\n        }\n        for (uint8 i = 0; i < 32; i++) {\n            data.push(bytes1(i));\n        }\n        data.pop();\n        data.pop();\n        assembly {\n            r := sload(data.slot)\n        }\n    }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 57661\n// gas legacyOptimized: 57073\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89482\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 58079\n// gas legacyOptimized: 56932\n// storageEmpty -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/byte_array_transitional_2.sol",
    "content": "// Tests transition between short and long encoding both ways\ncontract c {\n    bytes data;\n\n    function test() public returns (uint256) {\n        for (uint8 i = 0; i < 33; i++) {\n            data.push(bytes1(i));\n        }\n        for (uint8 i = 0; i < data.length; i++)\n            if (data[i] != bytes1(i)) return i;\n        data.pop();\n        data.pop();\n        for (uint8 i = 0; i < data.length; i++)\n            if (data[i] != bytes1(i)) return i;\n        return 0;\n    }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/bytes_length_member.sol",
    "content": "contract c {\n    function set() public returns (bool) {\n        data = msg.data;\n        return true;\n    }\n\n    function getLength() public returns (uint256) {\n        return data.length;\n    }\n\n    bytes data;\n}\n// ----\n// getLength() -> 0\n// set(): 1, 2 -> true\n// gas irOptimized: 110393\n// gas legacy: 110951\n// gas legacyOptimized: 110577\n// getLength() -> 68\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/bytes_to_fixed_bytes_cleanup.sol",
    "content": "contract C {\n    bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n    function fromMemory(bytes memory m) public returns (bytes16) {\n        assembly { mstore(m, 14) }\n        return bytes16(m);\n    }\n    function fromCalldata(bytes calldata c) external returns (bytes16) {\n        return bytes16(c);\n    }\n    function fromStorage() external returns (bytes32) {\n        return bytes32(s);\n    }\n    function fromSlice(bytes calldata c) external returns (bytes8) {\n        return bytes8(c[0:6]);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/bytes_to_fixed_bytes_simple.sol",
    "content": "contract C {\n    bytes s = \"abcdefghabcdefgh\";\n    bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n    function fromMemory(bytes memory m) public returns (bytes16) {\n        return bytes16(m);\n    }\n    function fromCalldata(bytes calldata c) external returns (bytes16) {\n        return bytes16(c);\n    }\n    function fromStorage() external returns (bytes16) {\n        return bytes16(s);\n    }\n    function fromStorageLong() external returns (bytes32) {\n        return bytes32(sLong);\n    }\n    function fromSlice(bytes calldata c) external returns (bytes8) {\n        return bytes8(c[1:9]);\n    }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/bytes_to_fixed_bytes_too_long.sol",
    "content": "contract C {\n    bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n    function fromMemory(bytes memory m) public returns (bytes32) {\n        return bytes32(m);\n    }\n    function fromCalldata(bytes calldata c) external returns (bytes32) {\n        return bytes32(c);\n    }\n    function fromStorage() external returns (bytes32) {\n        return bytes32(s);\n    }\n    function fromSlice(bytes calldata c) external returns (bytes32) {\n        return bytes32(c[0:33]);\n    }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/calldata_array.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(uint256[2] calldata s)\n        external\n        pure\n        returns (uint256 a, uint256 b)\n    {\n        a = s[0];\n        b = s[1];\n    }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/calldata_array_as_argument_internal_function.sol",
    "content": "pragma abicoder v2;\ncontract Test {\n    function f(uint256[] calldata c) internal returns (uint a, uint b) {\n        return (c.length, c[0]);\n    }\n\n    function g(uint256[] calldata c) external returns (uint a, uint b) {\n        return f(c);\n    }\n\n    function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n        return f(c[start: end]);\n    }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/calldata_array_dynamic_invalid.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(uint256[][] calldata a) external returns (uint256) {\n        return 42;\n    }\n\n    function g(uint256[][] calldata a) external returns (uint256) {\n        a[0];\n        return 42;\n    }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/calldata_array_dynamic_invalid_static_middle.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(uint256[][1][] calldata a) external returns (uint256) {\n        return 42;\n    }\n\n    function g(uint256[][1][] calldata a) external returns (uint256) {\n        a[0];\n        return 42;\n    }\n\n    function h(uint256[][1][] calldata a) external returns (uint256) {\n        a[0][0];\n        return 42;\n    }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/calldata_array_of_struct.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint256 b;\n    }\n\n    function f(S[] calldata s)\n        external\n        pure\n        returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n    {\n        l = s.length;\n        a = s[0].a;\n        b = s[0].b;\n        c = s[1].a;\n        d = s[1].b;\n    }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/calldata_array_two_dimensional.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function test(uint256[][2] calldata a) external returns (uint256) {\n        return a.length;\n    }\n    function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n        return a[i].length;\n    }\n    function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n        return a[i][j];\n    }\n    function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n        return this.test(a, i, j);\n    }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/calldata_array_two_dimensional_1.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function test(uint256[][] calldata a) external returns (uint256) {\n        return a.length;\n    }\n    function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n        return a[i].length;\n    }\n    function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n        return a[i][j];\n    }\n    function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n        return this.test(a, i, j);\n    }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/calldata_bytes_array_bounds.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(bytes[] calldata a, uint256 i) external returns (uint) {\n        return uint8(a[0][i]);\n    }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/calldata_slice_access.sol",
    "content": "contract C {\n    function f(uint256[] calldata x, uint256 start, uint256 end) external pure {\n        x[start:end];\n    }\n    function g(uint256[] calldata x, uint256 start, uint256 end, uint256 index) external pure returns (uint256, uint256, uint256) {\n        return (x[start:end][index], x[start:][0:end-start][index], x[:end][start:][index]);\n    }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x80, 0, 0, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 1, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 1, 0, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 2, 42, 23 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 3, 0, 2, 42, 23 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, -1, 0, 1, 42 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> 42, 42, 42\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 5, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 3, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 5, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/concat/bytes_concat_2_args.sol",
    "content": "contract C {\n    function f(bytes memory a, bytes memory b) public returns (bytes memory) {\n        return bytes.concat(a, b);\n    }\n}\n// ----\n// f(bytes,bytes): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n//\n// f(bytes,bytes):\n//   0x40, 0xa0, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\"\n//   ->\n//   0x20, 69, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// f(bytes,bytes): 0x40, 0x80, 3, \"abc\", 3, \"def\" -> 0x20, 6, \"abcdef\"\n//\n// f(bytes,bytes):\n//  0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 30, \"cdabcdabcdabcdabcdabcdabcdabcd\"\n//  ->\n//  0x20, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\"\n//\n// f(bytes,bytes):\n//  0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 34, \"cdabcdabcdabcdabcdabcdabcdabcdab\", \"cd\"\n//  ->\n//  0x20, 68, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcd\"\n//\n// f(bytes,bytes):\n//   0x40, 0x80, 3, \"abc\", 30, \"dabcdabcdabcdabcdabcdabcdabcda\"\n//   ->\n//   0x20, 33, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"a\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/concat/bytes_concat_3_args.sol",
    "content": "contract C {\n    function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) {\n        return bytes.concat(a, b, c);\n    }\n}\n// ----\n// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\", 3, \"abc\" -> 0x20, 40, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefabc\"\n// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 3, \"abc\", 2, \"de\", 3, \"fgh\" -> 0x20, 8, \"abcdefgh\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/concat/bytes_concat_as_argument.sol",
    "content": "contract C {\n    function f(bytes memory a, bytes memory b) public returns (bytes32) {\n        return keccak256(bytes.concat(a, b));\n    }\n\n    function h(bytes memory a) internal returns (uint256) {\n        return a.length;\n    }\n\n    function g(bytes memory a, bytes memory b) public returns (uint256) {\n        return h(bytes.concat(a, b));\n    }\n}\n// ----\n// f(bytes,bytes): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x1106e19b6f06d1cce71c2d816754f83dfa5b95df958c5cbf12b7c472320c427c\n// g(bytes,bytes): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 37\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/concat/bytes_concat_different_types.sol",
    "content": "contract C {\n    bytes s = \"bcdef\";\n\n    function f(bytes memory a) public returns (bytes memory) {\n        return bytes.concat(a, \"bcdef\");\n    }\n    function g(bytes calldata a) public returns (bytes memory) {\n        return bytes.concat(a, \"abcdefghabcdefghabcdefghabcdefghab\");\n    }\n    function h(bytes calldata a) public returns (bytes memory) {\n        return bytes.concat(a, s);\n    }\n    function j(bytes calldata a) public returns (bytes memory) {\n        bytes storage ref = s;\n        return bytes.concat(a, ref, s);\n    }\n    function k(bytes calldata a, string memory b) public returns (bytes memory) {\n        return bytes.concat(a, bytes(b));\n    }\n    function slice(bytes calldata a) public returns (bytes memory) {\n        require(a.length > 2, \"\");\n        return bytes.concat(a[:2], a[2:]);\n    }\n    function strParam(string calldata a) public returns (bytes memory) {\n        return bytes.concat(bytes(a), \"bcdef\");\n    }\n    function fixedBytesParam(bytes16 b1, bytes15 b2, bytes31 b3) public returns (\n        bytes memory,\n        bytes memory,\n        bytes memory,\n        bytes memory\n    ) {\n        return (\n            bytes.concat(b1, b2),\n            bytes.concat(b1, b3),\n            bytes.concat(b1, \"bcdef\"),\n            bytes.concat(b1, s)\n        );\n    }\n    function fixedBytesParam2(bytes calldata c, bytes6 b1, bytes6 b2) public returns (bytes memory, bytes memory) {\n        return (\n            bytes.concat(s, b1, c),\n            bytes.concat(b1, c, b2)\n        );\n    }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// g(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 66, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdefghabcdefghabcdefghabcdefgh\", \"ab\"\n// h(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// j(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 42, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefbcdef\"\n// k(bytes,string): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// slice(bytes): 0x20, 4, \"abcd\" -> 0x20, 4, \"abcd\"\n// strParam(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// fixedBytesParam(bytes16,bytes15,bytes31):\n//  \"aabbccddeeffgghh\",\n//  \"abcdefghabcdefg\",\n//  \"0123456789012345678901234567890\" ->\n//  0x80, 0xc0, 0x120, 0x160,\n//  31, \"aabbccddeeffgghhabcdefghabcdefg\",\n//  47, \"aabbccddeeffgghh0123456789012345\", \"678901234567890\",\n//  21, \"aabbccddeeffgghhbcdef\",\n//  21, \"aabbccddeeffgghhbcdef\"\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x010203040506), left(0x0708090A0B0C), 20, left(0x1011121314151617181920212223242526272829) ->\n//   0x40, 0x80,\n//   31, left(0x62636465660102030405061011121314151617181920212223242526272829),\n//   32, 0x01020304050610111213141516171819202122232425262728290708090A0B0C\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x01), left(0x02), 5, left(0x03) ->\n//   0x40, 0x80,\n//   16, left(0x6263646566010000000000030000000000),\n//   17, left(0x010000000000030000000002000000000000)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/concat/bytes_concat_empty_argument_list.sol",
    "content": "contract C {\n    function f() public returns (bytes memory) {\n        return bytes.concat();\n    }\n}\n// ----\n// f() -> 0x20, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/concat/bytes_concat_empty_strings.sol",
    "content": "contract C {\n    function f() public returns (bytes memory) {\n        bytes memory b = \"\";\n        return bytes.concat(\n            bytes.concat(b),\n            bytes.concat(b, b),\n            bytes.concat(\"\", b),\n            bytes.concat(b, \"\")\n        );\n    }\n\n    function g() public returns (bytes memory) {\n        return bytes.concat(\"\", \"abc\", hex\"\", \"abc\", unicode\"\");\n    }\n\n    function h() public returns (bytes memory) {\n        bytes memory b = \"\";\n        return bytes.concat(b, \"abc\", b, \"abc\", b);\n    }\n}\n// ----\n// f() -> 0x20, 0\n// g() -> 0x20, 6, \"abcabc\"\n// h() -> 0x20, 6, \"abcabc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/concat/bytes_concat_nested.sol",
    "content": "contract C {\n    function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) {\n        return bytes.concat(bytes.concat(a, b), c);\n    }\n}\n// ----\n// f(bytes,bytes,bytes): 0x60, 0x60, 0x60, 2, \"ab\" -> 0x20, 6, \"ababab\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/constant_var_as_array_length.sol",
    "content": "contract C {\n    uint256 constant LEN = 3;\n    uint256[LEN] public a;\n\n    constructor(uint256[LEN] memory _a) {\n        a = _a;\n    }\n}\n// ----\n// constructor(): 1, 2, 3 ->\n// gas irOptimized: 124991\n// gas irOptimized code: 14800\n// gas legacy: 142553\n// gas legacy code: 46200\n// gas legacyOptimized: 126306\n// gas legacyOptimized code: 23400\n// a(uint256): 0 -> 1\n// a(uint256): 1 -> 2\n// a(uint256): 2 -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol",
    "content": "contract c {\n    uint[9] m_data;\n    uint[] m_data_dyn;\n    uint8[][] m_byte_data;\n    function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n        m_data = a;\n        m_data_dyn = a;\n        m_byte_data = b;\n        return b[3][1]; // note that access and declaration are reversed to each other\n    }\n    function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n        a = m_data.length;\n        b = m_data[7];\n        c = m_data_dyn.length;\n        d = m_data_dyn[7];\n        e = m_byte_data.length;\n        f = m_byte_data[3].length;\n        g = m_byte_data[3][1];\n    }\n}\n// ----\n// 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\n// gas irOptimized: 647730\n// gas legacy: 659420\n// gas legacyOptimized: 648899\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol",
    "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n    uint128[] x;\n    function f() public returns(bool) {\n        x.push(42); x.push(42); x.push(42); x.push(42);\n        uint128[] memory y = new uint128[](1);\n        y[0] = 23;\n        x = y;\n        assembly { sstore(x.slot, 4) }\n\n        assert(x[0] == 23);\n        assert(x[1] == 0);\n\n        assert(x[2] == 0);\n        // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n        // the slot dirty.\n        assert(x[3] == 0);\n\n        return true;\n    }\n}\n// ----\n// f() -> true\n// gas irOptimized: 73981\n// gas legacy: 75550\n// gas legacyOptimized: 73812\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol",
    "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n    uint40[] x;\n    function f() public returns(bool) {\n\n        x.push(42); x.push(42); x.push(42); x.push(42);\n        x.push(42); x.push(42); x.push(42); x.push(42);\n        x.push(42); x.push(42); x.push(42); x.push(42);\n        x.push(42); x.push(42); x.push(42); x.push(42);\n        x.push(42); x.push(42); x.push(42); x.push(42);\n\n        uint40[] memory y = new uint40[](1);\n        y[0] = 23;\n        x = y;\n\n        assembly { sstore(x.slot, 20) }\n\n        assert(x[0] == 23);\n        assert(x[1] == 0);\n        assert(x[2] == 0);\n        assert(x[3] == 0);\n\n        assert(x[4] == 0);\n        assert(x[5] == 0);\n        assert(x[6] == 0);\n        assert(x[7] == 0);\n\n        assert(x[8] == 0);\n        assert(x[9] == 0);\n        assert(x[10] == 0);\n        assert(x[11] == 0);\n\n        assert(x[12] == 0);\n        assert(x[13] == 0);\n        assert(x[14] == 0);\n        assert(x[15] == 0);\n\n        assert(x[16] == 0);\n        assert(x[17] == 0);\n        assert(x[18] == 0);\n        assert(x[19] == 0);\n\n        return true;\n\n    }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122596\n// gas legacy: 125651\n// gas legacyOptimized: 121668\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol",
    "content": "contract C {\n    uint256[] x;\n    function f() public returns(uint256) {\n        x.push(42); x.push(42); x.push(42); x.push(42);\n        uint256[] memory y = new uint256[](1);\n        y[0] = 23;\n        x = y;\n        assembly { sstore(x.slot, 4) }\n        assert(x[1] == 0);\n        assert(x[2] == 0);\n        return x[3];\n    }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108096\n// gas legacy: 110351\n// gas legacyOptimized: 107708\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol",
    "content": "contract C {\n    uint128[] x;\n    uint64[] x1;\n    uint120[] x2;\n    function f() public returns(uint128) {\n        x.push(42); x.push(42); x.push(42); x.push(42);\n        uint128[] memory y = new uint128[](1);\n        y[0] = 23;\n        x = y;\n        assembly { sstore(x.slot, 4) }\n        assert(x[0] == 23);\n        assert(x[2] == 0);\n        assert(x[3] == 0);\n        return x[1];\n    }\n\n    function g() public returns(uint64) {\n        x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n        uint64[] memory y = new uint64[](1);\n        y[0] = 23;\n        x1 = y;\n        assembly { sstore(x1.slot, 4) }\n        assert(x1[0] == 23);\n        assert(x1[2] == 0);\n        assert(x1[3] == 0);\n        return x1[1];\n    }\n\n    function h() public returns(uint120) {\n        x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n        uint120[] memory y = new uint120[](1);\n        y[0] = 23;\n        x2 = y;\n        assembly { sstore(x2.slot, 4) }\n        assert(x2[0] == 23);\n        assert(x2[2] == 0);\n        assert(x2[3] == 0);\n        return x2[1];\n    }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 74044\n// gas legacy: 75528\n// gas legacyOptimized: 73861\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 74114\n// gas legacy: 75553\n// gas legacyOptimized: 73904\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol",
    "content": "contract c {\n    bytes8[] data1; // 4 per slot\n    bytes10[] data2; // 3 per slot\n\n    function test()\n        public\n        returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n    {\n        data1 = new bytes8[](9);\n        for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n        data2 = data1;\n        a = data2[1];\n        b = data2[2];\n        c = data2[3];\n        d = data2[4];\n        e = data2[5];\n    }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220059\n// gas legacyOptimized: 211458\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol",
    "content": "contract c {\n    uint[3][90][] large;\n    uint[3][3][] small;\n    function test() public returns (uint r) {\n        for (uint i = 0; i < 7; i++) {\n            large.push();\n            small.push();\n        }\n        large[3][2][0] = 2;\n        large[1] = large[3];\n        small[3][2][0] = 2;\n        small[1] = small[2];\n        r = ((\n            small[3][2][0] * 0x100 |\n            small[1][2][0]) * 0x100 |\n            large[3][2][0]) * 0x100 |\n            large[1][2][0];\n        delete small;\n        delete large;\n\n    }\n    function clear() public returns (uint, uint) {\n        for (uint i = 0; i < 7; i++) {\n            large.push();\n            small.push();\n        }\n        small[3][2][0] = 0;\n        large[3][2][0] = 0;\n        while (small.length > 0)\n            small.pop();\n        while (large.length > 0)\n            large.pop();\n        return (small.length, large.length);\n    }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4560468\n// gas legacy: 4536539\n// gas legacyOptimized: 4456732\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4488719\n// gas legacy: 4407759\n// gas legacyOptimized: 4385068\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_memory_to_storage.sol",
    "content": "contract C {\n    uint128[13] unused;\n    uint32[] a;\n    uint32[3] b;\n    function f() public returns (uint32, uint256) {\n        uint32[] memory m = new uint32[](3);\n        m[0] = 1;\n        m[1] = 2;\n        m[2] = 3;\n        a = m;\n        assert(a[0] == m[0]);\n        assert(a[1] == m[1]);\n        assert(a[2] == m[2]);\n        return (a[0], a.length);\n    }\n    function g() public returns (uint32, uint32, uint32) {\n        uint32[3] memory m;\n        m[0] = 1; m[1] = 2; m[2] = 3;\n        a = m;\n        b = m;\n        assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n        assert(a.length == b.length);\n        return (a[0], b[1], a[2]);\n    }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol",
    "content": "contract c {\n    uint256[4][] a;\n    uint256[10][] b;\n    uint256[][] c;\n\n    function test(uint256[2][] calldata d) external returns (uint256) {\n        a = d;\n        b = a;\n        c = b;\n        return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n    }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689539\n// gas legacy: 713478\n// gas legacyOptimized: 690424\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_storage_abi_signed.sol",
    "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n    int16[] x;\n\n    function test() public returns (int16[] memory) {\n        x.push(int16(-1));\n        x.push(int16(-1));\n        x.push(int16(8));\n        x.push(int16(-16));\n        x.push(int16(-2));\n        x.push(int16(6));\n        x.push(int16(8));\n        x.push(int16(-1));\n        return x;\n    }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol",
    "content": "contract c {\n    uint64[] data1;\n    uint256[] data2;\n\n    function test() public returns (uint256 x, uint256 y) {\n        data2.push(11);\n        data1.push(0);\n        data1.push(1);\n        data1.push(2);\n        data1.push(3);\n        data1.push(4);\n        data2 = data1;\n        assert(data1[0] == data2[0]);\n        x = data2.length;\n        y = data2[4];\n    }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 207971\n// gas legacyOptimized: 204828\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol",
    "content": "contract c {\n    uint48[5][2] data1;\n    uint120[6][3] data2;\n\n    function test() public returns (uint256 x, uint120 y) {\n        data2[0][0] = 11;\n        data2[1][0] = 22;\n        data2[2][0] = 33;\n\n        data1[0][0] = 0;\n        data1[0][1] = 1;\n        data1[0][2] = 2;\n        data1[0][3] = 3;\n        data1[0][4] = 4;\n        data1[1][0] = 3;\n        data2 = data1;\n        assert(data1[0][1] == data2[0][1]);\n        x = data2.length;\n        y = data2[0][4];\n    }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169553\n// gas legacy: 182361\n// gas legacyOptimized: 169554\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol",
    "content": "\ncontract c {\n    uint[] data1;\n    uint[] data2;\n    function setData1(uint length, uint index, uint value) public {\n        data1 = new uint[](length);\n        if (index < length)\n            data1[index] = value;\n    }\n    function copyStorageStorage() public { data2 = data1; }\n    function getData2(uint index) public returns (uint len, uint val) {\n        len = data2.length; if (index < len) val = data2[index];\n    }\n}\n// ----\n// setData1(uint256,uint256,uint256): 10, 5, 4 ->\n// copyStorageStorage() ->\n// gas irOptimized: 111321\n// gas legacy: 112434\n// gas legacyOptimized: 111494\n// getData2(uint256): 5 -> 10, 4\n// setData1(uint256,uint256,uint256): 0, 0, 0 ->\n// copyStorageStorage() ->\n// getData2(uint256): 0 -> 0, 0\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol",
    "content": "contract c {\n    uint256[] data1;\n    uint256[] data2;\n\n    function test() public returns (uint256 x, uint256 y) {\n        data2.push(11);\n        data1.push(0);\n        data1.push(1);\n        data1.push(2);\n        data1.push(3);\n        data1.push(4);\n        data2 = data1;\n        assert(data1[0] == data2[0]);\n        x = data2.length;\n        y = data2[4];\n    }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 253591\n// gas legacy: 253664\n// gas legacyOptimized: 252200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol",
    "content": "contract c {\n    uint256[9] data1;\n    uint256[] data2;\n\n    function test() public returns (uint256 x, uint256 y) {\n        data1[8] = 4;\n        data2 = data1;\n        x = data2.length;\n        y = data2[8];\n    }\n}\n// ----\n// test() -> 9, 4\n// gas irOptimized: 123180\n// gas legacy: 124642\n// gas legacyOptimized: 123345\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_simple.sol",
    "content": "contract C {\n    bytes1[2] data1;\n    bytes2[2] data2;\n    function test() public returns (bytes2, bytes2) {\n        uint i;\n        for (i = 0; i < data1.length; ++i)\n            data1[i] = bytes1(uint8(1 + i));\n        data2 = data1;\n        return (data2[0], data2[1]);\n    }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 69235\n// gas legacyOptimized: 66974\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol",
    "content": "contract c {\n    uint256[40] data1;\n    uint256[20] data2;\n\n    function test() public returns (uint256 x, uint256 y) {\n        data1[30] = 4;\n        data1[2] = 7;\n        data1[3] = 9;\n        data2[3] = 8;\n        data1 = data2;\n        x = data1[3];\n        y = data1[30]; // should be cleared\n    }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196370\n// gas legacy: 210073\n// gas legacyOptimized: 196759\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol",
    "content": "contract c {\n    struct Data { uint x; uint y; }\n    Data[] data1;\n    Data[] data2;\n    function test() public returns (uint x, uint y) {\n        while (data1.length < 9)\n            data1.push();\n        data1[8].x = 4;\n        data1[8].y = 5;\n        data2 = data1;\n        x = data2[8].x;\n        y = data2[8].y;\n        while (data1.length > 0)\n            data1.pop();\n        data2 = data1;\n    }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190676\n// gas legacy: 210706\n// gas legacyOptimized: 190472\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory.sol",
    "content": "contract C {\n    uint[] a;\n    function f() public returns (uint, uint) {\n        a.push(1); a.push(0); a.push(0);\n        uint[] memory b = a;\n        return (b[0], b.length);\n    }\n}\n// ----\n// f() -> 1, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol",
    "content": "pragma abicoder v2;\ncontract C {\n    uint[][] a;\n\n    function f() public returns (uint[][] memory) {\n        a.push();\n        a.push();\n        a[0].push(0);\n        a[0].push(1);\n        a[1].push(2);\n        a[1].push(3);\n        uint[][] memory m = a;\n        return m;\n    }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol",
    "content": "contract c {\n    bytes1[10] data1;\n    bytes2[32] data2;\n    function test() public returns (uint check, uint res1, uint res2) {\n        uint i;\n        for (i = 0; i < data2.length; ++i)\n            data2[i] = 0xffff;\n        check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n        for (i = 0; i < data1.length; ++i)\n            data1[i] = bytes1(uint8(1 + i));\n        data2 = data1;\n        for (i = 0; i < 16; ++i)\n            res1 |= uint(uint16(data2[i])) * 0x10000**i;\n        for (i = 0; i < 16; ++i)\n            res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n    }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100506\n// gas legacy: 146700\n// gas legacyOptimized: 122680\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol",
    "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n    bytes8[4] data1; // fits into one slot\n    bytes10[6] data2; // 4 elements need two slots\n\n    function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n        data1[0] = bytes8(uint64(1));\n        data1[1] = bytes8(uint64(2));\n        data1[2] = bytes8(uint64(3));\n        data1[3] = bytes8(uint64(4));\n        for (uint256 i = 0; i < data2.length; ++i)\n            data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n        data2 = data1;\n        r1 = data2[3];\n        r2 = data2[4];\n        r3 = data2[5];\n    }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 91320\n// gas legacy: 97777\n// gas legacyOptimized: 91993\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol",
    "content": "contract c {\n    bytes8[9] data1; // 4 per slot\n    bytes17[10] data2; // 1 per slot, no offset counter\n\n    function test()\n        public\n        returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n    {\n        for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n        data2[8] = data2[9] = bytes8(uint64(2));\n        data2 = data1;\n        a = data2[1];\n        b = data2[2];\n        c = data2[3];\n        d = data2[4];\n        e = data2[9];\n    }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273548\n// gas legacy: 280148\n// gas legacyOptimized: 274502\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol",
    "content": "contract c {\n    bytes9[7] data1; // 3 per slot\n    bytes32[10] data2; // 1 per slot\n\n    function test()\n        public\n        returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n    {\n        for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n        data2[8] = data2[9] = bytes8(uint64(2));\n        data2 = data1;\n        a = data2[1];\n        b = data2[2];\n        c = data2[3];\n        d = data2[4];\n        e = data2[9];\n    }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 233012\n// gas legacy: 239400\n// gas legacyOptimized: 233948\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    mapping (uint => uint8[][]) m;\n\n    uint8[][] s;\n\n    constructor() {\n        s = new uint8[][](2);\n\n        s[0] = new uint8[](2);\n        s[0][0] = 10;\n        s[0][1] = 11;\n\n        s[1] = new uint8[](3);\n        s[1][0] = 12;\n        s[1][1] = 13;\n        s[1][2] = 14;\n    }\n\n    function from_storage() public returns (uint8[][] memory) {\n        m[0] = new uint8[][](2);\n        m[0][0] = s[0];\n        m[0][1] = s[1];\n        return m[0];\n    }\n\n\n    function from_storage_ptr() public returns (uint8[][] memory) {\n        uint8[][] storage sPtr = s;\n        m[0] = new uint8[][](2);\n        m[0][0] = sPtr[0];\n        m[0][1] = sPtr[1];\n        return m[0];\n    }\n\n\n    function from_memory() public returns (uint8[][] memory) {\n        uint8[][] memory a = s;\n        m[0] = new uint8[][](2);\n        m[0][0] = a[0];\n        m[0][1] = a[1];\n        return m[0];\n    }\n\n    function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n        m[0] = new uint8[][](2);\n        m[0][0] = _a[0];\n        m[0][1] = _a[1];\n        return m[0];\n    }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149856\n// gas legacy: 156721\n// gas legacyOptimized: 149000\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// 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\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract c {\n    function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n        uint256[][] memory a1 = c;\n        assert(a1[0][0] == c[0][0]);\n        assert(a1[0][1] == c[0][1]);\n        return (a1.length, a1[0][0] + a1[1][1]);\n    }\n\n    function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n        uint256[][2] memory a2 = c;\n        assert(a2[0][0] == c[0][0]);\n        assert(a2[0][1] == c[0][1]);\n        return (a2[0].length, a2[0][0] + a2[1][1]);\n    }\n\n    function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n        uint256[2][] memory a3 = c;\n        assert(a3[0][0] == c[0][0]);\n        assert(a3[0][1] == c[0][1]);\n        return (a3.length, a3[0][0] + a3[1][1]);\n    }\n\n    function test4(uint256[2][2] calldata c) external returns (uint256) {\n        uint256[2][2] memory a4 = c;\n        assert(a4[0][0] == c[0][0]);\n        assert(a4[0][1] == c[0][1]);\n        return (a4[0][0] + a4[1][1]);\n    }\n}\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract c {\n    uint256[][] a1;\n    uint256[][2] a2;\n    uint256[2][] a3;\n    uint256[2][2] a4;\n\n    function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n        a1 = c;\n        assert(a1[0][0] == c[0][0]);\n        assert(a1[0][1] == c[0][1]);\n        return (a1.length, a1[0][0] + a1[1][1]);\n    }\n\n    function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n        a2 = c;\n        assert(a2[0][0] == c[0][0]);\n        assert(a2[0][1] == c[0][1]);\n        return (a2[0].length, a2[0][0] + a2[1][1]);\n    }\n\n    function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n        a3 = c;\n        assert(a3[0][0] == c[0][0]);\n        assert(a3[0][1] == c[0][1]);\n        return (a3.length, a3[0][0] + a3[1][1]);\n    }\n\n    function test4(uint256[2][2] calldata c) external returns (uint256) {\n        a4 = c;\n        assert(a4[0][0] == c[0][0]);\n        assert(a4[0][1] == c[0][1]);\n        return (a4[0][0] + a4[1][1]);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 180918\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134685\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol",
    "content": "contract Test {\n    uint128[13] unused;\n    uint256[][] a;\n    uint256[4][] b;\n    uint256[2][3] c;\n\n    function test() external returns (uint256) {\n        uint256[][] memory m = new uint256[][](2);\n        m[0] = new uint256[](3);\n        m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n        m[1] = new uint256[](4);\n        m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n        a = m;\n        return a[0][0] + a[0][1] + a[1][3];\n    }\n\n    function test1() external returns (uint256) {\n        uint256[2][] memory m = new uint256[2][](1);\n        m[0][0] = 1; m[0][1] = 2;\n        b = m;\n        return b[0][0] + b[0][1];\n    }\n\n    function test2() external returns (uint256) {\n        uint256[2][2] memory m;\n        m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n        c = m;\n        return c[0][0] + c[1][1] + c[0][1];\n    }\n\n    function test3() external returns (uint256) {\n        uint256[2][3] memory m;\n        m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n        m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n        a = m;\n        return a[0][0] + a[1][0] + a[2][1];\n    }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226647\n// gas legacy: 229060\n// gas legacyOptimized: 226495\n// test1() -> 3\n// test2() -> 6\n// gas irOptimized: 95905\n// gas legacy: 100519\n// test3() -> 24\n// gas irOptimized: 141297\n// gas legacy: 146668\n// gas legacyOptimized: 141331\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_nested_storage_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    uint256[][] a1;\n    uint256[][2] a2;\n    uint256[2][] a3;\n    uint256[2][2] a4;\n\n    constructor() {\n        a1 = new uint256[][](2);\n        a1[0] = [1, 2];\n        a1[1] = [3, 4, 5];\n\n        a2[0] = [6, 7, 8];\n        a2[1] = [9];\n\n        a3.push([1, 2]);\n        a3.push([3, 4]);\n        a3.push([5, 6]);\n\n        a4 = [[10, 11], [12, 13]];\n    }\n\n    function test1() external returns (uint256[][] memory) {\n        return a1;\n    }\n\n    function test2() external returns (uint256[][2] memory) {\n        return a2;\n    }\n\n    function test3() external returns (uint256[2][] memory) {\n        return a3;\n    }\n\n    function test4() external returns (uint256[2][2] memory) {\n        return a4;\n    }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic.sol",
    "content": "contract C {\n    function testFunction1() public {}\n    function testFunction2() public {}\n    function testFunction3() public {}\n\n\n    function() external [] externalArray0;\n    function() external [] externalArray1;\n\n    function() internal [] internalArray0;\n    function() internal [] internalArray1;\n\n    constructor() {\n        externalArray0 = new function() external[] (3);\n        externalArray1 = [\n            this.testFunction1,\n            this.testFunction2,\n            this.testFunction3\n        ];\n\n        internalArray0 = new function() internal[] (3);\n        internalArray1 = [\n            testFunction1,\n            testFunction2,\n            testFunction3\n        ];\n    }\n\n    function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n        assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n        externalArray0 = externalArray1;\n        return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n    }\n\n    function copyInternalArrayOfFunctionType() external returns (bool) {\n        internalArray0 = internalArray1;\n        assert(internalArray0.length == 3);\n\n        return\n            internalArray0.length == internalArray1.length &&\n            internalArray0[0] == internalArray1[0] &&\n            internalArray0[1] == internalArray1[1] &&\n            internalArray0[2] == internalArray1[2];\n    }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104629\n// gas legacy: 111170\n// gas legacyOptimized: 104620\n// copyInternalArrayOfFunctionType() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol",
    "content": "contract C {\n    function testFunction1() public {}\n    function testFunction2() public view {}\n    function testFunction3() public pure {}\n\n\n    function() external [] externalArray0;\n    function() external [] externalArray1;\n\n    function() internal [] internalArray0;\n    function() internal [] internalArray1;\n\n    constructor() {\n        externalArray0 = new function() external[] (3);\n        externalArray1 = [\n            this.testFunction1,\n            this.testFunction2,\n            this.testFunction3\n        ];\n\n        internalArray0 = new function() internal[] (3);\n        internalArray1 = [\n            testFunction1,\n            testFunction2,\n            testFunction3\n        ];\n    }\n\n\n    function copyExternalStorageArraysOfFunctionType() external returns (bool)\n    {\n        assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n        externalArray0 = externalArray1;\n        return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n    }\n\n    function copyInternalArrayOfFunctionType() external returns (bool)\n    {\n        internalArray0 = internalArray1;\n        assert(internalArray0.length == 3);\n\n        return\n            internalArray0.length == internalArray1.length &&\n            internalArray0[0] == internalArray1[0] &&\n            internalArray0[1] == internalArray1[1] &&\n            internalArray0[2] == internalArray1[2];\n    }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 110911\n// gas legacyOptimized: 104377\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 38695\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint128 a;\n        uint64 b;\n        uint128 c;\n    }\n    function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n        S[3] memory m = c;\n        return (m[2].a, m[1].b, m[0].c);\n    }\n    function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n        S[] memory m = c;\n        return (m[2].a, m[1].b, m[0].c);\n    }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint128 a;\n        uint64 b;\n        uint128 c;\n    }\n    uint128[137] unused;\n    S[] s;\n    function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n        s = c;\n        return (s[2].a, s[1].b, s[0].c);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120751\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol",
    "content": "contract C {\n    struct S {\n        uint128 a;\n        uint64 b;\n        uint128 c;\n    }\n    uint128[137] unused;\n    S[] s;\n    function f() public returns (uint128, uint64, uint128) {\n        S[] memory m = new S[](3);\n        m[2].a = 10;\n        m[1].b = 11;\n        m[0].c = 12;\n        s = m;\n        return (s[2].a, s[1].b, s[0].c);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint256[] a;\n    }\n\n    function f(S[] calldata c) external returns (uint256, uint256) {\n        S[] memory s = c;\n        assert(s.length == c.length);\n        for (uint i = 0; i < s.length; i++) {\n            assert(s[i].a.length == c[i].a.length);\n            for (uint j = 0; j < s[i].a.length; j++) {\n                assert(s[i].a[j] == c[i].a[j]);\n            }\n        }\n        return (s[1].a.length, s[1].a[0]);\n    }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint256[] a;\n    }\n\n    S[] s;\n\n    function f(S[] calldata c) external returns (uint256, uint256) {\n        s = c;\n        assert(s.length == c.length);\n        for (uint i = 0; i < s.length; i++) {\n            assert(s[i].a.length == c[i].a.length);\n            for (uint j = 0; j < s[i].a.length; j++) {\n                assert(s[i].a[j] == c[i].a[j]);\n            }\n        }\n        return (s[1].a.length, s[1].a[0]);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327461\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint136 p;\n        uint128[3] b;\n        uint128[] c;\n    }\n\n    S[] s;\n\n    function f() external returns (uint256, uint256, uint128, uint128) {\n        S[] memory m = new S[](3);\n        m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n        m[1].c[0] = 1;\n        m[1].c[1] = 2;\n        m[1].c[2] = 3;\n        s = m;\n        assert(s.length == m.length);\n        assert(s[1].b[1] == m[1].b[1]);\n        assert(s[1].c[0] == m[1].c[0]);\n        return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol",
    "content": "contract C {\n    uint8[33] a;\n    uint32[9] b;\n    uint120[3] c;\n\n    function f() public returns (uint8, uint32, uint120) {\n        a[32] = 1; a[31] = 2; a[30] = 3;\n        b[0] = 1; b[1] = 2; b[2] = 3;\n        c[2] = 3; c[1] = 1;\n        return (a[32], b[1], c[2]);\n    }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/array_to_mapping.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    mapping (uint => uint8[][]) m;\n\n    uint8[][] s;\n\n    constructor() {\n        s = new uint8[][](2);\n\n        s[0] = new uint8[](2);\n        s[0][0] = 10;\n        s[0][1] = 11;\n\n        s[1] = new uint8[](3);\n        s[1][0] = 12;\n        s[1][1] = 13;\n        s[1][2] = 14;\n    }\n\n    function from_storage() public returns (uint8[][] memory) {\n        m[0] = s;\n        return m[0];\n    }\n\n    function from_storage_ptr() public returns (uint8[][] memory) {\n        uint8[][] storage sPtr = s;\n        m[0] = sPtr;\n        return m[0];\n    }\n\n    function from_memory() public returns (uint8[][] memory) {\n        uint8[][] memory a = s;\n        m[0] = a;\n        return m[0];\n    }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147749\n// gas legacy: 154218\n// gas legacyOptimized: 147020\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol",
    "content": "contract Test {\n    uint24[] public data;\n    function set(uint24[] memory _data) public returns (uint) {\n        data = _data;\n        return data.length;\n    }\n    function get() public returns (uint24[] memory) {\n        return data;\n    }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 95505\n// gas legacy: 104176\n// gas legacyOptimized: 96785\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/bytes_calldata_to_string_calldata.sol",
    "content": "contract C {\n    function f(bytes calldata c) public returns (string calldata s) {\n        return string(c);\n    }\n}\n// ----\n// f(bytes): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol",
    "content": "contract c {\n    function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n    function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n    mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110560\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177511\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// gas irOptimized: 48421\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// gas irOptimized: 35641\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// gas irOptimized: 35641\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/bytes_memory_to_storage.sol",
    "content": "contract C {\n  bytes s;\n  function f() external returns (bytes1) {\n    bytes memory data = \"abcd\";\n    s = data;\n    return s[0];\n  }\n}\n// ----\n// f() -> \"a\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/bytes_storage_to_memory.sol",
    "content": "contract C {\n  bytes s = \"abcd\";\n  function f() external returns (bytes1) {\n    bytes memory data = s;\n    return data[0];\n  }\n}\n// ----\n// f() -> \"a\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol",
    "content": "contract c {\n    bytes a;\n    bytes b;\n    function f(uint len) public returns (bytes memory) {\n        bytes memory x = new bytes(len);\n        for (uint i = 0; i < len; i++)\n            x[i] = bytes1(uint8(i));\n        a = x;\n        for (uint i = 0; i < len; i++)\n            assert(a[i] == x[i]);\n        b = a;\n        for (uint i = 0; i < len; i++)\n            assert(b[i] == x[i]);\n        return b;\n    }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112645\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128859\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 123888\n// gas legacy: 135510\n// gas legacyOptimized: 135218\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 126948\n// gas legacy: 148110\n// gas legacyOptimized: 148448\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas irOptimized: 54204\n// gas legacy: 59832\n// gas legacyOptimized: 57268\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460669\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_1d_array_into_2d_memory_array_element.sol",
    "content": "// Example from https://github.com/argotorg/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n    function f(uint[] calldata a) external returns (uint[][] memory) {\n        uint[][] memory m = new uint[][](2);\n        m[0] = a;\n\n        return m;\n    }\n}\ncontract Test {\n    C immutable c = new C();\n\n    function test() external returns (bool) {\n        uint[] memory arr = new uint[](4);\n\n        arr[0] = 13;\n        arr[1] = 14;\n        arr[2] = 15;\n        arr[3] = 16;\n\n        uint[][] memory ret = c.f(arr);\n        assert(ret.length == 2);\n        assert(ret[0].length == 4);\n        assert(ret[0][0] == 13);\n        assert(ret[0][1] == 14);\n        assert(ret[0][2] == 15);\n        assert(ret[0][3] == 16);\n        assert(ret[1].length == 0);\n\n        return true;\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_2d_bytes_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    function g(bytes[2] memory m) internal returns (bytes memory) {\n        return m[0];\n    }\n    function f(bytes[2] calldata c) external returns (bytes memory) {\n        return g(c);\n    }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_2d_bytes_to_memory_2.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    function g(bytes[2] memory m) internal {\n        assert(m[0].length > 1);\n        assert(m[1].length > 1);\n        assert(m[0][0] == m[1][0]);\n        assert(m[0][1] == m[1][1]);\n    }\n    function f(bytes[2] calldata c) external {\n        g(c);\n    }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n  uint256[] s;\n  function f(uint256[] calldata data) external returns (uint) {\n    s = data;\n    return s[0];\n  }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 110973\n// gas legacy: 112436\n// gas legacyOptimized: 111313\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_array_of_struct_to_memory.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint256 b;\n    }\n\n    function f(S[] calldata s)\n        external\n        pure\n        returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n    {\n        S[] memory m = s;\n        l = m.length;\n        a = m[0].a;\n        b = m[0].b;\n        c = m[1].a;\n        d = m[1].b;\n    }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_array_static_to_memory.sol",
    "content": "contract C {\n    function f(uint256[2] calldata c) public returns (uint256, uint256) {\n        uint256[2] memory m1 = c;\n        return (m1[0], m1[1]);\n    }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    mapping (uint => uint8[][]) m;\n\n    uint8[][] s;\n\n    function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n        m[0] = _a;\n        return m[0];\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// 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\n// gas irOptimized: 139587\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_bytes_array_to_memory.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(bytes[] calldata a)\n        external\n        returns (uint256, uint256, bytes memory)\n    {\n        bytes memory m = a[0];\n        return (a.length, m.length, m);\n    }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_bytes_to_storage.sol",
    "content": "contract C {\n  bytes s;\n  function f(bytes calldata data) external returns (bytes1) {\n    s = data;\n    return s[0];\n  }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_dyn_2d_bytes_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    function f(bytes[] calldata c) external returns (bytes[] memory) {\n        return c;\n    }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_dynamic_array_to_memory.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(uint256[][] calldata a)\n        external\n        returns (uint256, uint256[] memory)\n    {\n        uint256[] memory m = a[0];\n        return (a.length, m);\n    }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_nested_array_copy_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract Test {\n    struct shouldBug {\n        uint256[][2] deadly;\n    }\n    function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n        return shouldBug(weapon);\n    }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/calldata_to_storage_different_base.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    bytes10[] s;\n    function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n        s = c;\n        return (s.length, s[0], s[1], s[2]);\n    }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/cleanup_during_multi_element_per_slot_copy.sol",
    "content": "contract C {\n    uint32[] s;\n    constructor()\n    {\n        s.push();\n        s.push();\n    }\n    function f() external returns (uint)\n    {\n        (s[1], s) = (4, [0]);\n        s = [0];\n        s.push();\n        return s[1];\n        // used to return 4 via IR.\n    }\n}\n// ----\n// constructor()\n// gas irOptimized: 89349\n// gas irOptimized code: 140200\n// gas legacy: 100902\n// gas legacy code: 271400\n// gas legacyOptimized: 83062\n// gas legacyOptimized code: 91800\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol",
    "content": "pragma abicoder               v2;\nstruct S {\n    uint16 x;\n    bytes a;\n    uint16 y;\n    bytes b;\n}\ncontract C {\n    uint padding;\n    S data;\n\n    function f() public returns (bytes memory, bytes memory) {\n        S memory x;\n        x.x = 7;\n        x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n        x.a = \"abcdef\";\n        x.y = 9;\n        data = x;\n        return (data.a, data.b);\n    }\n    function g() public returns (bytes memory, bytes memory) {\n        S memory x;\n        x.x = 7;\n        x.b = \"12345678923456789\";\n        x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n        x.y = 9;\n        data = x;\n        return (data.a, data.b);\n    }\n    function h() public returns (bytes memory, bytes memory) {\n        S memory x;\n        data = x;\n        return (data.a, data.b);\n    }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179690\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106381\n// gas legacy: 109472\n// gas legacyOptimized: 106648\n// h() -> 0x40, 0x60, 0x00, 0x00\n// gas irOptimized: 46948\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol",
    "content": "function dataslot() pure returns (bytes32) {\n    return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n    bytes32 s = dataslot();\n    assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n    return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n    assembly { r := sload(1) }\n}\n\ncontract C {\n    uint padding;\n    bytes data;\n\n    function f() public returns (uint) {\n        bytes32 zero;\n        if (!(readDataSlot() == zero)) return 1;\n        data = \"abc\";\n        if (!(readDataSlot() == zero)) return 2;\n        data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n        if (!(readDataSlot() != zero)) return 3;\n        if (!(readDataSlot(1) != zero)) return 4;\n        if (!(readDataSlot(2) != zero)) return 5;\n        if (!(readDataSlot(3) == zero)) return 6;\n        if (!(readDataSlot(4) == zero)) return 7;\n        data = \"abc\";\n        if (!(readDataSlot() == zero)) return 8;\n        if (!(readDataSlot(1) == zero)) return 9;\n        if (!(readDataSlot(2) == zero)) return 10;\n        if (!(readDataSlot(3) == zero)) return 11;\n        data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n        data = \"123456789012345678901234567890123456\";\n        if (!(readDataSlot() != zero)) return 12;\n        if (!(readDataSlot(1) != zero)) return 13;\n        if (!(readDataSlot(2) == zero)) return 14;\n        if (!(readDataSlot(3) == zero)) return 15;\n        return 0xff;\n    }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143935\n// gas legacy: 153487\n// gas legacyOptimized: 146748\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/copy_function_internal_storage_array.sol",
    "content": "contract C {\n    function() internal returns (uint)[] x;\n    function() internal returns (uint)[] y;\n\n    function test() public returns (uint256) {\n        x = new function() internal returns (uint)[](10);\n        x[9] = a;\n        y = x;\n        return y[9]();\n    }\n\n    function a() public returns (uint256) {\n        return 7;\n    }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122575\n// gas legacy: 208558\n// gas legacyOptimized: 202409\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/copy_internal_function_array_to_storage.sol",
    "content": "contract C {\n    function() internal returns (uint)[20] x;\n    int256 mutex;\n\n    function one() public returns (uint256) {\n        function() internal returns (uint)[20] memory xmem;\n        x = xmem;\n        return 3;\n    }\n\n    function two() public returns (uint256) {\n        if (mutex > 0) return 7;\n        mutex = 1;\n        // If this test fails, it might re-execute this function.\n        x[0]();\n        return 2;\n    }\n}\n// ----\n// one() -> 3\n// gas legacy: 142687\n// gas legacyOptimized: 135991\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol",
    "content": "\ncontract c {\n    function set() public returns (bool) { data1 = msg.data; return true; }\n    function reset() public returns (bool) { data1 = data2; return true; }\n    bytes data1;\n    bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177551\n// storageEmpty -> 0\n// reset() -> true\n// gas irOptimized: 47341\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/copying_bytes_multiassign.sol",
    "content": "contract receiver {\n    uint public received;\n    function recv(uint x) public { received += x + 1; }\n    fallback() external { received = 0x80; }\n}\ncontract sender {\n    constructor() { rec = new receiver(); }\n    fallback() external { savedData1 = savedData2 = msg.data; }\n    function forward(bool selector) public returns (bool) {\n        if (selector) { address(rec).call(savedData1); delete savedData1; }\n        else { address(rec).call(savedData2); delete savedData2; }\n        return true;\n    }\n    function val() public returns (uint) { return rec.received(); }\n    receiver rec;\n    bytes savedData1;\n    bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110735\n// gas legacy: 111388\n// gas legacyOptimized: 111066\n// val() -> 0\n// forward(bool): true -> true\n// gas irOptimized: 49573\n// val() -> 0x80\n// forward(bool): false -> true\n// gas irOptimized: 31410\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/dirty_memory_bytes_to_storage_copy.sol",
    "content": "contract C {\n    bytes x;\n    function f() public returns (uint r) {\n        bytes memory m = \"tmp\";\n        assembly {\n            mstore(m, 8)\n            mstore(add(m, 32), \"deadbeef15dead\")\n        }\n        // via yul disabled because this truncates the string.\n        x = m;\n        assembly {\n            r := sload(x.slot)\n        }\n    }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/dirty_memory_bytes_to_storage_copy_ir.sol",
    "content": "contract C {\n    bytes x;\n    function f() public returns (uint r) {\n        bytes memory m = \"tmp\";\n        assembly {\n            mstore(m, 8)\n            mstore(add(m, 32), \"deadbeef15dead\")\n        }\n        x = m;\n        assembly {\n            r := sload(x.slot)\n        }\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8[] a;\n        uint8[2] b;\n    }\n\n    S[][][] s1;\n    S[][1][] s2;\n    S[1][][1] s3;\n\n    function test1(S[][][] calldata _a) public returns (S[][] memory){\n        s1.push();\n        s1[0] = _a[0];\n        return s1[0];\n    }\n\n    function test2(S[][1][] calldata _a) public returns (S[][1] memory) {\n        s2.push();\n        s2[0] = _a[0];\n        return s2[0];\n    }\n\n    function test3(S[1][][2] calldata _a) public returns (S[1][] memory) {\n        s3[0] = _a[1];\n        return s3[0];\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// 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\n// gas irOptimized: 327936\n// 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\n// gas irOptimized: 141168\n// 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\n// gas irOptimized: 188448\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8[] a;\n        uint8[2] b;\n    }\n\n    S[][][] s1;\n    S[][1][] s2;\n    S[1][][1] s3;\n\n    function test1(S[][][] memory _a) public returns (S[][] memory){\n        s1.push();\n        s1[0] = _a[0];\n        return s1[0];\n    }\n\n    function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n        s2.push();\n        s2[0] = _a[0];\n        return s2[0];\n    }\n\n    function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n        s3[0] = _a[1];\n        return s3[0];\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// 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\n// gas irOptimized: 332582\n// 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\n// gas irOptimized: 145415\n// 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\n// gas irOptimized: 192254\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/empty_bytes_copy.sol",
    "content": "contract C {\n    bytes data;\n    bytes otherData;\n    function fromMemory() public returns (bytes1) {\n        bytes memory t;\n        uint[2] memory x;\n        x[0] = type(uint).max;\n        data = t;\n        data.push();\n        return data[0];\n    }\n    function fromCalldata(bytes calldata x) public returns (bytes1) {\n        data = x;\n        data.push();\n        return data[0];\n    }\n    function fromStorage() public returns (bytes1) {\n        // zero-length but dirty higher order bits\n        assembly  { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n        data = otherData;\n        data.push();\n        return data[0];\n    }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/function_type_array_to_storage.sol",
    "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116512\n// gas legacy: 120226\n// gas legacyOptimized: 116941\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103138\n// gas legacy: 105192\n// gas legacyOptimized: 103752\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    bytes[] s;\n    function f() external returns (uint256) {\n        bytes[] memory m = new bytes[](3);\n        m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n        s = m;\n        assert(s.length == m.length);\n        for (uint i = 0; i < s.length; ++i) {\n            assert(s[i].length == m[i].length);\n            for (uint j = 0; j < s[i].length; ++j) {\n                 assert(s[i][j] == m[i][j]);\n            }\n        }\n        return s.length;\n    }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128301\n// gas legacy: 129528\n// gas legacyOptimized: 128171\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/memory_to_storage_different_base.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    bytes10[] s;\n    function f() external returns (uint256, bytes10, bytes10, bytes10) {\n        bytes4[] memory m = new bytes4[](3);\n        m[0] = \"abcd\";\n        m[1] = \"bcde\";\n        m[2] = \"cdef\";\n        s = m;\n        return (s.length, s[0], s[1], s[2]);\n    }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n        return _a[1];\n    }\n\n    function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n        return _a[0];\n    }\n\n    function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n        return _a[0];\n    }\n\n    function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n        uint16[][][] memory tmp = new uint16[][][](2);\n        tmp[1] = _a;\n        return tmp[1];\n    }\n\n    function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n        uint32[][2][] memory tmp = new uint32[][2][](1);\n        tmp[0] = _a;\n        return tmp[0];\n    }\n\n    function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n        uint32[2][][] memory tmp = new uint32[2][][](1);\n        tmp[0] = _a;\n        return tmp[0];\n    }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol",
    "content": "contract C {\n    uint8[2][2] a;\n    uint8[2][2][2] a2;\n\n    function test(uint8[2][2][2] calldata _a) public {\n        a = _a[0];\n        require(a[0][0] == 1);\n        require(a[0][1] == 2);\n        require(a[1][0] == 3);\n        require(a[1][1] == 4);\n    }\n\n    function test2(uint8[2][2] calldata _a) public {\n        a2[0] = _a;\n        require(a2[0][0][0] == 1);\n        require(a2[0][0][1] == 2);\n        require(a2[0][1][0] == 3);\n        require(a2[0][1][1] == 4);\n        require(a2[1][0][0] == 0);\n        require(a2[1][0][1] == 0);\n        require(a2[1][1][0] == 0);\n        require(a2[1][1][1] == 0);\n    }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 72076\n// gas legacyOptimized: 72086\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n        return _a[1];\n    }\n\n    function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n        return _a[0];\n    }\n\n    function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n        return _a[0];\n    }\n\n    function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n        uint16[][][] memory tmp = new uint16[][][](2);\n        tmp[1] = _a;\n        return tmp[1];\n    }\n\n    function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n        uint32[][2][] memory tmp = new uint32[][2][](1);\n        tmp[0] = _a;\n        return tmp[0];\n    }\n\n    function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n        uint32[2][][] memory tmp = new uint32[2][][](1);\n        tmp[0] = _a;\n        return tmp[0];\n    }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol",
    "content": "contract C {\n    uint8[2][2] a1;\n    uint8[2][2][2] a2;\n\n    function test(uint8[2][2][2] memory _a) public {\n        a1 = _a[0];\n        require(a1[0][0] == 1);\n        require(a1[0][1] == 2);\n        require(a1[1][0] == 3);\n        require(a1[1][1] == 4);\n    }\n\n    function test2(uint8[2][2] memory _a) public {\n        a2[0] = _a;\n        require(a2[0][0][0] == 1);\n        require(a2[0][0][1] == 2);\n        require(a2[0][1][0] == 3);\n        require(a2[0][1][1] == 4);\n        require(a2[1][0][0] == 0);\n        require(a2[1][0][1] == 0);\n        require(a2[1][1][0] == 0);\n        require(a2[1][1][1] == 0);\n    }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 73031\n// gas legacyOptimized: 73155\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    uint8[][][] a1 = new uint8[][][](2);\n    uint8[][][2] a2;\n    uint8[][2][] a3 = new uint8[][2][](1);\n    uint8[2][][] a4 = new uint8[2][][](2);\n\n    constructor() {\n        a1[1] = new uint8[][](2);\n        a1[1][0] = [3, 4];\n        a1[1][1] = [5, 6];\n\n        a2[0] = new uint8[][](2);\n        a2[0][0] = [6, 7];\n        a2[0][1] = [8, 9];\n        a2[1] = new uint8[][](2);\n        a2[1][0] = [10, 11];\n\n        a3[0][0] = [3, 4];\n        a3[0][1] = [5, 6];\n\n        a4[0] = new uint8[2][](1);\n        a4[0][0] = [17, 23];\n        a4[1] = new uint8[2][](1);\n        a4[1][0] = [19, 31];\n    }\n\n    function test1() public returns (uint8[][] memory) {\n        return a1[1];\n    }\n\n    function test2() public returns (uint8[][] memory) {\n        return a2[0];\n    }\n\n    function test3() public returns (uint8[][2] memory) {\n        return a3[0];\n    }\n\n    function test4() public returns (uint8[2][] memory) {\n        return a4[1];\n    }\n\n    function test5() public returns (uint8[][][] memory) {\n        uint8[][][] memory tmp = new uint8[][][](3);\n        tmp[1] = a1[1];\n        return tmp;\n    }\n\n    function test6() public returns (uint8[][2][] memory) {\n        uint8[][2][] memory tmp = new uint8[][2][](2);\n        tmp[0] = a3[0];\n        return tmp;\n    }\n\n    function test7() public returns (uint8[2][][] memory) {\n        uint8[2][][] memory tmp = new uint8[2][][](1);\n        tmp[0] = a4[0];\n        return tmp;\n    }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    uint8[][][] src1 = new uint8[][][](2);\n    uint8[][][2] src2;\n    uint8[][2][] src3 = new uint8[][2][](1);\n    uint8[2][][] src4 = new uint8[2][][](2);\n\n    uint8[][] dst1;\n    uint8[][] dst2;\n    uint8[][2] dst3;\n    uint8[2][] dst4;\n\n    constructor() {\n        src1[1] = new uint8[][](2);\n        src1[1][0] = [3, 4];\n        src1[1][1] = [5, 6];\n\n        src2[0] = new uint8[][](2);\n        src2[0][0] = [6, 7];\n        src2[0][1] = [8, 9];\n        src2[1] = new uint8[][](2);\n        src2[1][0] = [10, 11];\n\n        src3[0][0] = [3, 4];\n        src3[0][1] = [5, 6];\n\n        src4[0] = new uint8[2][](1);\n        src4[0][0] = [17, 23];\n        src4[1] = new uint8[2][](1);\n        src4[1][0] = [19, 31];\n    }\n\n    function test1() public {\n        dst1 = src1[1];\n\n        require(dst1.length == 2);\n        require(dst1[0][0] == src1[1][0][0]);\n        require(dst1[0][1] == src1[1][0][1]);\n        require(dst1[1][0] == src1[1][1][0]);\n        require(dst1[1][1] == src1[1][1][1]);\n    }\n\n    function test2() public {\n        dst2 = src2[0];\n\n        require(dst2.length == 2);\n        require(dst2[0][0] == src2[0][0][0]);\n        require(dst2[0][1] == src2[0][0][1]);\n        require(dst2[1][0] == src2[0][1][0]);\n        require(dst2[1][1] == src2[0][1][1]);\n    }\n\n    function test3() public {\n        dst3 = src3[0];\n        require(dst3[0][0] == src3[0][0][0]);\n        require(dst3[0][1] == src3[0][0][1]);\n        require(dst3[1][0] == src3[0][1][0]);\n        require(dst3[1][1] == src3[0][1][1]);\n    }\n\n    function test4() public {\n        dst4 = src4[1];\n        require(dst4.length == 1);\n        require(dst4[0][0] == src4[1][0][0]);\n        require(dst4[0][1] == src4[1][0][1]);\n    }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150449\n// gas legacy: 156275\n// gas legacyOptimized: 150983\n// test2() ->\n// gas irOptimized: 147342\n// gas legacy: 153508\n// gas legacyOptimized: 148067\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 130649\n// gas legacyOptimized: 125142\n// test4() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8 x;\n        uint8 y;\n    }\n\n    function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n        return a;\n    }\n\n    function test2(S[1][] calldata a) public returns (S[1][] memory) {\n        return a;\n    }\n\n    function test3(S[][2] calldata a) public returns (S[][2] memory) {\n        return a;\n    }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8[] a;\n        uint8[2] b;\n    }\n\n    S[][] s1;\n    S[][1] s2;\n    S[1][] s3;\n\n    function test1(S[][] calldata _a) public returns (S[][] memory){\n        s1 = _a;\n        return s1;\n    }\n\n    function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n        s2 = _a;\n        return s2;\n    }\n\n    function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n        s3 = _a;\n        return s3;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// 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\n// gas irOptimized: 304750\n// 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\n// gas irOptimized: 116659\n// 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\n// gas irOptimized: 187942\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8 x;\n        uint8 y;\n    }\n\n    function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n        r = a;\n    }\n\n    function test2(S[1][] memory a) public returns (S[1][] memory r) {\n        r = a;\n    }\n\n    function test3(S[][2] memory a) public returns (S[][2] memory r) {\n        r = a;\n    }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8[] a;\n        uint8[2] b;\n    }\n\n    S[][] s1;\n    S[][1] s2;\n    S[1][] s3;\n\n    function test1(S[][] memory _a) public returns (S[][] memory){\n        s1 = _a;\n        return s1;\n    }\n\n    function test2(S[][1] memory _a) public returns (S[][1] memory) {\n        s2 = _a;\n        return s2;\n    }\n\n    function test3(S[1][] memory _a) public returns (S[1][] memory) {\n        s3 = _a;\n        return s3;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// 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\n// gas irOptimized: 309034\n// 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\n// gas irOptimized: 118320\n// 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\n// gas irOptimized: 190993\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_of_structs_storage_to_storage.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8 x;\n        uint8 y;\n    }\n\n    S[][] src1;\n    S[][1] src2;\n    S[1][] src3;\n\n    S[][] dst1;\n    S[][1] dst2;\n    S[1][] dst3;\n\n    constructor() {\n        src1 = new S[][](1);\n        src1[0].push(S({x: 3, y: 7}));\n        src1[0].push(S({x: 11, y: 13}));\n\n        src2[0].push(S({x: 3, y: 7}));\n        src2[0].push(S({x: 11, y: 13}));\n        src2[0].push(S({x: 17, y: 19}));\n\n        src3.push([S({x: 3, y: 7})]);\n        src3.push([S({x: 11, y: 13})]);\n    }\n\n    function test1() public {\n        dst1 = src1;\n\n        require(dst1.length == 1);\n        require(dst1[0][0].x == src1[0][0].x);\n        require(dst1[0][0].y == src1[0][0].y);\n        require(dst1[0][1].x == src1[0][1].x);\n        require(dst1[0][1].y == src1[0][1].y);\n    }\n\n    function test2() public {\n        dst2 = src2;\n\n        require(dst2[0].length == 3);\n        require(dst2[0][0].x == src2[0][0].x);\n        require(dst2[0][0].y == src2[0][0].y);\n        require(dst2[0][1].x == src2[0][1].x);\n        require(dst2[0][1].y == src2[0][1].y);\n        require(dst2[0][2].x == src2[0][2].x);\n        require(dst2[0][2].y == src2[0][2].y);\n    }\n\n    function test3() public {\n        dst3 = src3;\n\n        require(dst3.length == 2);\n        require(dst3[0][0].x == src3[0][0].x);\n        require(dst3[0][0].y == src3[0][0].y);\n        require(dst3[1][0].x == src3[1][0].x);\n        require(dst3[1][0].y == src3[1][0].y);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_array_of_structs_with_nested_array_from_storage_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8[] a;\n        uint8[2] b;\n    }\n\n    uint8[] a1;\n    uint8[] a2;\n    uint8[] a3;\n\n    S[][] s1;\n    S[1][1] s2;\n\n    constructor() {\n        a1.push(23);\n        a1.push(29);\n        a2.push(31);\n\n        s1 = new S[][](2);\n        s1[0] = new S[](2);\n        s1[0][0] = S({a: a1, b: [7, 11]});\n        s1[0][1] = S({a: a2, b: [17, 19]});\n\n        s1[1] = new S[](1);\n        s1[1][0] = S({a: a3, b: [37, 41]});\n\n        s2[0][0] = S({a: a3, b: [43, 47]});\n    }\n\n    function test1() public returns (S[] memory) {\n        return s1[0];\n    }\n\n    function test2() public returns (S[1] memory) {\n        return s2[0];\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    uint8[][] a;\n    uint8[][][] a2;\n\n    function test(uint8[][][] calldata _a) public {\n        a = _a[1];\n        require(a.length == 2);\n        require(a[0].length == 1);\n        require(a[0][0] == 7);\n        require(a[1].length == 2);\n        require(a[1][0] == 8);\n        require(a[1][1] == 9);\n    }\n\n    function test2(uint8[][] calldata _a) public {\n        a2 = new uint8[][][](2);\n        a2[0] = _a;\n        require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137891\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164249\n// gas legacyOptimized: 120228\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol",
    "content": "contract C {\n    uint72[5][] a;\n\n    function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n        for (uint i = 0; i < 4; i++)\n            a.push();\n        a[0][0] = 1;\n        a[0][3] = 2;\n        a[1][1] = 3;\n        a[1][4] = 4;\n        a[2][0] = 5;\n        a[3][2] = 6;\n        a[3][3] = 7;\n        uint72[5][] memory m = a;\n        return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n    }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211758\n// gas legacyOptimized: 211179\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    bytes[] a;\n\n    function f() public returns (bytes[] memory) {\n        a.push(\"abc\");\n        a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n        bytes[] memory m = a;\n        return m;\n    }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202903\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol",
    "content": "contract C {\n    uint72[5][] a;\n\n    function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n        for (uint i = 0; i < 4; i++)\n            a.push();\n        a[0][0] = 1;\n        a[0][3] = 2;\n        a[1][1] = 3;\n        a[1][4] = 4;\n        a[2][0] = 5;\n        a[3][2] = 6;\n        a[3][3] = 7;\n        uint72[5][] storage a_ = a;\n        uint72[5][] memory m = a_;\n        return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n    }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol",
    "content": "contract C {\n    struct T { uint8 x; uint8 y; uint[] z; }\n    T[3][] a;\n\n    function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n        a.push();\n        a.push();\n        a[0][1].x = 11;\n        a[0][1].y = 12;\n        a[0][1].z.push(1);\n        a[0][1].z.push(2);\n        a[0][1].z.push(3);\n        a[1][2].x = 21;\n        a[1][2].y = 22;\n        a[1][2].z.push(4);\n        a[1][2].z.push(5);\n        a[1][2].z.push(6);\n        T[3][] memory m = a;\n        return (\n            m[0][1].x, m[0][1].y, m[0][1].z[0],\n            m[1][2].x, m[1][2].y, m[1][2].z[0]\n        );\n    }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/storage_memory_packed.sol",
    "content": "contract C {\n    uint8[33] a;\n\n    function f() public returns (uint8, uint8, uint8) {\n        a[0] = 2;\n        a[16] = 3;\n        a[32] = 4;\n        uint8[33] memory m = a;\n        return (m[0], m[16], m[32]);\n    }\n}\n// ----\n// f() -> 2, 3, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol",
    "content": "contract C {\n    uint8[] a;\n\n    function f() public returns (uint8, uint8, uint8) {\n        for (uint i = 0; i < 33; i++)\n            a.push(7);\n        a[0] = 2;\n        a[16] = 3;\n        a[32] = 4;\n        uint8[] memory m = a;\n        return (m[0], m[16], m[32]);\n    }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/copying/string_calldata_to_bytes_calldata.sol",
    "content": "contract C {\n    function f(string calldata s) public returns (bytes calldata m) {\n        return bytes(s);\n    }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/create_dynamic_array_with_zero_length.sol",
    "content": "contract C {\n    function f() public returns (uint256) {\n        uint256[][] memory a = new uint256[][](0);\n        return 7;\n    }\n}\n// ----\n// f() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/create_memory_array.sol",
    "content": "contract C {\n    struct S {\n        uint256[2] a;\n        bytes b;\n    }\n\n    function f() public returns (bytes1, uint256, uint256, bytes1) {\n        bytes memory x = new bytes(200);\n        x[199] = \"A\";\n        uint256[2][] memory y = new uint256[2][](300);\n        y[203][1] = 8;\n        S[] memory z = new S[](180);\n        z[170].a[1] = 4;\n        z[170].b = new bytes(102);\n        z[170].b[99] = \"B\";\n        return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n    }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/create_memory_array_too_large.sol",
    "content": "contract C {\n    function f() public returns (uint256) {\n        uint256 l = 2**256 / 32;\n        // This used to work without causing an error.\n        uint256[] memory x = new uint256[](l);\n        uint256[] memory y = new uint256[](1);\n        x[1] = 42;\n        // This used to overwrite the value written above.\n        y[0] = 23;\n        return x[1];\n    }\n    function g() public returns (uint256) {\n        uint256 l = 2**256 / 2 + 1;\n        // This used to work without causing an error.\n        uint16[] memory x = new uint16[](l);\n        uint16[] memory y = new uint16[](1);\n        x[2] = 42;\n        // This used to overwrite the value written above.\n        y[0] = 23;\n        return x[2];\n    }}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x41\n// g() -> FAILURE, hex\"4e487b71\", 0x41\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/create_memory_byte_array.sol",
    "content": "contract C {\n    function f() public returns (bytes1) {\n        bytes memory x = new bytes(35);\n        assert(x.length == 35);\n        x[34] = \"A\";\n        return (x[34]);\n    }\n}\n// ----\n// f() -> \"A\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/create_multiple_dynamic_arrays.sol",
    "content": "contract C {\n    function f() public returns (uint256) {\n        uint256[][] memory x = new uint256[][](42);\n        assert(x[0].length == 0);\n        x[0] = new uint256[](1);\n        x[0][0] = 1;\n        assert(x[4].length == 0);\n        x[4] = new uint256[](1);\n        x[4][0] = 2;\n        assert(x[10].length == 0);\n        x[10] = new uint256[](1);\n        x[10][0] = 44;\n        uint256[][] memory y = new uint256[][](24);\n        assert(y[0].length == 0);\n        y[0] = new uint256[](1);\n        y[0][0] = 1;\n        assert(y[4].length == 0);\n        y[4] = new uint256[](1);\n        y[4][0] = 2;\n        assert(y[10].length == 0);\n        y[10] = new uint256[](1);\n        y[10][0] = 88;\n        if (\n            (x[0][0] == y[0][0]) &&\n            (x[4][0] == y[4][0]) &&\n            (x[10][0] == 44) &&\n            (y[10][0] == 88)\n        ) return 7;\n        return 0;\n    }\n}\n// ----\n// f() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol",
    "content": "contract c {\n    bytes data;\n\n    function test1() external returns (bool) {\n        data = new bytes(100);\n        for (uint256 i = 0; i < data.length; i++) data[i] = bytes1(uint8(i));\n        delete data[94];\n        delete data[96];\n        delete data[98];\n        return\n            data[94] == 0 &&\n            uint8(data[95]) == 95 &&\n            data[96] == 0 &&\n            uint8(data[97]) == 97;\n    }\n}\n// ----\n// test1() -> true\n// gas irOptimized: 218420\n// gas legacy: 242263\n// gas legacyOptimized: 241187\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/delete/delete_bytes_array.sol",
    "content": "contract C {\n    bytes data;\n\n    function f() public returns (uint ret) {\n        data.push(\"a\");\n        data.push(\"b\");\n        delete data;\n        assembly {\n            ret := sload(data.slot)\n        }\n    }\n\n    function g() public returns (uint ret) {\n        assembly {\n            sstore(data.slot, 67)\n        }\n        data.push(\"a\");\n        data.push(\"b\");\n        assert(data.length == 35);\n        delete data;\n        assert(data.length == 0);\n\n        uint size = 999;\n        assembly {\n            size := sload(data.slot)\n            mstore(0, data.slot)\n            ret := sload(keccak256(0, 32))\n        }\n        assert(size == 0);\n    }\n}\n// ----\n// f() -> 0\n// g() -> 0\n// gas irOptimized: 56617\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/delete/delete_memory_array.sol",
    "content": "contract C {\n\n    function len() public returns (uint ret) {\n        uint[] memory data = new uint[](2);\n        data[0] = 234;\n        data[1] = 123;\n        delete data;\n        assembly {\n            ret := mload(data)\n        }\n    }\n}\n// ----\n// len() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/delete/delete_on_array_of_structs.sol",
    "content": "// Test for a bug where we did not increment the counter properly while deleting a dynamic array.\ncontract C {\n    struct S {\n        uint256 x;\n        uint256[] y;\n    }\n    S[] data;\n\n    function f() public returns (bool) {\n        S storage s1 = data.push();\n        s1.x = 2**200;\n        S storage s2 = data.push();\n        s2.x = 2**200;\n        delete data;\n        return true;\n    }\n}\n// ----\n// f() -> true # This code interprets x as an array length and thus will go out of gas. neither of the two should throw due to out-of-bounds access #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/delete/delete_removes_bytes_data.sol",
    "content": "contract c {\n    fallback() external { data = msg.data; }\n    function del() public returns (bool) { delete data; return true; }\n    bytes data;\n}\n// ----\n// (): 7 ->\n// storageEmpty -> 0\n// del(): 7 -> true\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/delete/delete_storage_array.sol",
    "content": "contract C {\n    uint[] data;\n\n    function len() public returns (uint ret) {\n        data.push(234);\n        data.push(123);\n        delete data;\n        assembly {\n            ret := sload(data.slot)\n        }\n    }\n\n    function val() public returns (uint ret) {\n        assembly {\n            sstore(0, 2)\n            mstore(0, 0)\n            sstore(keccak256(0, 32), 234)\n            sstore(add(keccak256(0, 32), 1), 123)\n        }\n\n        assert(data[0] == 234);\n        assert(data[1] == 123);\n\n        delete data;\n\n        uint size = 999;\n\n        assembly {\n            size := sload(0)\n            mstore(0, 0)\n            ret := sload(keccak256(0, 32))\n        }\n    }\n}\n// ----\n// len() -> 0\n// val() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol",
    "content": "contract C {\n    uint120[] data;\n\n    function f() public returns (uint120, uint120, uint120) {\n        data.push(123);\n        data.push(234);\n        data.push(345);\n        delete data;\n        assembly {\n            sstore(data.slot, 3)\n        }\n        return (data[0], data[1], data[2]);\n    }\n}\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 88028\n// gas legacy: 88796\n// gas legacyOptimized: 87704\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/delete/memory_arrays_delete.sol",
    "content": "contract Test {\n    function del() public returns (uint24[3][4] memory) {\n        uint24[3][4] memory x;\n        for (uint24 i = 0; i < x.length; i ++)\n            for (uint24 j = 0; j < x[i].length; j ++)\n                x[i][j] = i * 0x10 + j;\n        delete x[1];\n        delete x[3][2];\n        return x;\n    }\n}\n// ----\n// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol",
    "content": "contract c {\n    uint[20] spacer;\n    uint[] dynamic;\n    function fill() public {\n        for (uint i = 0; i < 21; ++i)\n            dynamic.push(i + 1);\n    }\n    function halfClear() public {\n        while (dynamic.length > 5)\n            dynamic.pop();\n    }\n    function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 91472\n// gas legacy: 90567\n// gas legacyOptimized: 90457\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol",
    "content": "contract c {\n    struct Data {\n        uint256 x;\n        uint256 y;\n    }\n    Data[] data;\n    uint256[] ids;\n\n    function setIDStatic(uint256 id) public {\n        ids[2] = id;\n    }\n\n    function setID(uint256 index, uint256 id) public {\n        ids[index] = id;\n    }\n\n    function setData(uint256 index, uint256 x, uint256 y) public {\n        data[index].x = x;\n        data[index].y = y;\n    }\n\n    function getID(uint256 index) public returns (uint256) {\n        return ids[index];\n    }\n\n    function getData(uint256 index) public returns (uint256 x, uint256 y) {\n        x = data[index].x;\n        y = data[index].y;\n    }\n\n    function getLengths() public returns (uint256 l1, uint256 l2) {\n        l1 = data.length;\n        l2 = ids.length;\n    }\n\n    function setLengths(uint256 l1, uint256 l2) public {\n        while (data.length < l1) data.push();\n        while (ids.length < l2) ids.push();\n    }\n}\n// ----\n// getLengths() -> 0, 0\n// setLengths(uint256,uint256): 48, 49 ->\n// gas irOptimized: 112674\n// gas legacy: 108272\n// gas legacyOptimized: 100268\n// getLengths() -> 48, 49\n// setIDStatic(uint256): 11 ->\n// getID(uint256): 2 -> 11\n// setID(uint256,uint256): 7, 8 ->\n// getID(uint256): 7 -> 8\n// setData(uint256,uint256,uint256): 7, 8, 9 ->\n// setData(uint256,uint256,uint256): 8, 10, 11 ->\n// getData(uint256): 7 -> 8, 9\n// getData(uint256): 8 -> 10, 11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol",
    "content": "contract c {\n    struct s { uint[][] d; }\n    s[] data;\n    function fill() public returns (uint) {\n        while (data.length < 3)\n            data.push();\n        while (data[2].d.length < 4)\n            data[2].d.push();\n        while (data[2].d[3].length < 5)\n            data[2].d[3].push();\n        data[2].d[3][4] = 8;\n        return data[2].d[3][4];\n    }\n    function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/dynamic_out_of_bounds_array_access.sol",
    "content": "contract c {\n    uint256[] data;\n\n    function enlarge(uint256 amount) public returns (uint256) {\n        while (data.length < amount) data.push();\n        return data.length;\n    }\n\n    function set(uint256 index, uint256 value) public returns (bool) {\n        data[index] = value;\n        return true;\n    }\n\n    function get(uint256 index) public returns (uint256) {\n        return data[index];\n    }\n\n    function length() public returns (uint256) {\n        return data.length;\n    }\n}\n// ----\n// length() -> 0\n// get(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x32\n// enlarge(uint256): 4 -> 4\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// get(uint256): 3 -> 4\n// length() -> 4\n// set(uint256,uint256): 4, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/evm_exceptions_out_of_band_access.sol",
    "content": "contract A {\n    uint256[3] arr;\n    bool public test = false;\n\n    function getElement(uint256 i) public returns (uint256) {\n        return arr[i];\n    }\n\n    function testIt() public returns (bool) {\n        uint256 i = this.getElement(5);\n        test = true;\n        return true;\n    }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/external_array_args.sol",
    "content": "contract c {\n    function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n            external returns (uint av, uint bv, uint cv) {\n        av = a[a_index];\n        bv = b[b_index];\n        cv = c[c_index];\n    }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/fixed_array_cleanup.sol",
    "content": "contract c {\n    uint spacer1;\n    uint spacer2;\n    uint[20] data;\n    function fill() public {\n        for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n    }\n    function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 97800\n// gas legacy: 97944\n// gas legacyOptimized: 97880\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol",
    "content": "contract A {\n    function f(uint16 input) public pure returns (uint16[5] memory arr) {\n        arr[0] = input;\n        arr[1] = ++input;\n        arr[2] = ++input;\n        arr[3] = ++input;\n        arr[4] = ++input;\n    }\n}\n\n\ncontract B {\n    function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n        A a = new A();\n        res = a.f(2);\n        res2 = a.f(1000);\n    }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/fixed_arrays_in_constructors.sol",
    "content": "contract Creator {\n    uint256 public r;\n    address public ch;\n\n    constructor(address[3] memory s, uint256 x) {\n        r = x;\n        ch = s[2];\n    }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/fixed_arrays_in_storage.sol",
    "content": "contract c {\n    struct Data {\n        uint256 x;\n        uint256 y;\n    }\n    Data[2**10] data;\n    uint256[2**10 + 3] ids;\n\n    function setIDStatic(uint256 id) public {\n        ids[2] = id;\n    }\n\n    function setID(uint256 index, uint256 id) public {\n        ids[index] = id;\n    }\n\n    function setData(uint256 index, uint256 x, uint256 y) public {\n        data[index].x = x;\n        data[index].y = y;\n    }\n\n    function getID(uint256 index) public returns (uint256) {\n        return ids[index];\n    }\n\n    function getData(uint256 index) public returns (uint256 x, uint256 y) {\n        x = data[index].x;\n        y = data[index].y;\n    }\n\n    function getLengths() public returns (uint256 l1, uint256 l2) {\n        l1 = data.length;\n        l2 = ids.length;\n    }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/fixed_bytes_length_access.sol",
    "content": "contract C {\n    bytes1 a;\n\n    function f(bytes32 x) public returns (uint256, uint256, uint256) {\n        return (x.length, bytes16(uint128(2)).length, a.length + 7);\n    }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/fixed_out_of_bounds_array_access.sol",
    "content": "contract c {\n    uint256[4] data;\n\n    function set(uint256 index, uint256 value) public returns (bool) {\n        data[index] = value;\n        return true;\n    }\n\n    function get(uint256 index) public returns (uint256) {\n        return data[index];\n    }\n\n    function length() public returns (uint256) {\n        return data.length;\n    }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/function_array_cross_calls.sol",
    "content": "contract D {\n    function f(function() external returns (function() external returns (uint))[] memory x)\n        public returns (function() external returns (uint)[3] memory r) {\n        r[0] = x[0]();\n        r[1] = x[1]();\n        r[2] = x[2]();\n    }\n}\n\n\ncontract C {\n    function test() public returns (uint256, uint256, uint256) {\n        function() external returns (function() external returns (uint))[] memory x =\n            new function() external returns (function() external returns (uint))[](10);\n        for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n        x[0] = this.htwo;\n        function() external returns (uint)[3] memory y = (new D()).f(x);\n        return (y[0](), y[1](), y[2]());\n    }\n\n    function e() public returns (uint256) {\n        return 5;\n    }\n\n    function f() public returns (uint256) {\n        return 6;\n    }\n\n    function g() public returns (uint256) {\n        return 7;\n    }\n\n    uint256 counter;\n\n    function h() public returns (function() external returns (uint)) {\n        return counter++ == 0 ? this.f : this.g;\n    }\n\n    function htwo() public returns (function() external returns (uint)) {\n        return this.e;\n    }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/function_memory_array.sol",
    "content": "contract C {\n    function a(uint256 x) public returns (uint256) {\n        return x + 1;\n    }\n\n    function b(uint256 x) public returns (uint256) {\n        return x + 2;\n    }\n\n    function c(uint256 x) public returns (uint256) {\n        return x + 3;\n    }\n\n    function d(uint256 x) public returns (uint256) {\n        return x + 5;\n    }\n\n    function e(uint256 x) public returns (uint256) {\n        return x + 8;\n    }\n\n    function test(uint256 x, uint256 i) public returns (uint256) {\n        function(uint) internal returns (uint)[] memory arr =\n            new function(uint) internal returns (uint)[](10);\n        arr[0] = a;\n        arr[1] = b;\n        arr[2] = c;\n        arr[3] = d;\n        arr[4] = e;\n        return arr[i](x);\n    }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/indexAccess/arrays_complex_memory_index_access.sol",
    "content": "contract Test {\n    function set(uint24[3][] memory _data, uint256 a, uint256 b)\n        public\n        returns (uint256 l, uint256 e)\n    {\n        l = _data.length;\n        e = _data[a][b];\n    }\n}\n// ----\n// set(uint24[3][],uint256,uint256): 0x60, 0x03, 0x02, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06, 0x0c\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/indexAccess/bytes_index_access.sol",
    "content": "contract c {\n    bytes data;\n    function direct(bytes calldata arg, uint index) external returns (uint) {\n        return uint(uint8(arg[index]));\n    }\n    function storageCopyRead(bytes calldata arg, uint index) external returns (uint) {\n        data = arg;\n        return uint(uint8(data[index]));\n    }\n    function storageWrite() external returns (uint) {\n        data = new bytes(35);\n        data[31] = 0x77;\n        data[32] = 0x14;\n\n        data[31] = 0x01;\n        data[31] |= 0x08;\n        data[30] = 0x01;\n        data[32] = 0x03;\n        return uint(uint8(data[30])) * 0x100 | uint(uint8(data[31])) * 0x10 | uint(uint8(data[32]));\n    }\n}\n// ----\n// direct(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21\n// storageCopyRead(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21\n// storageWrite() -> 0x193\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/indexAccess/bytes_index_access_memory.sol",
    "content": "contract Main {\n    function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (bytes1 c1, bytes1 c2, bytes1 c3) {\n        c1 = _s1[i1];\n        c2 = intern(_s1, i2);\n        c3 = internIndirect(_s1)[i3];\n    }\n    function intern(bytes memory _s1, uint i) public returns (bytes1 c) {\n        return _s1[i];\n    }\n    function internIndirect(bytes memory _s1) public returns (bytes memory) {\n        return _s1;\n    }\n}\n// ----\n// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> \"d\", \"e\", \"f\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/indexAccess/bytes_memory_index_access.sol",
    "content": "contract Test {\n    function set(bytes memory _data, uint256 i)\n        public\n        returns (uint256 l, bytes1 c)\n    {\n        l = _data.length;\n        c = _data[i];\n    }\n}\n// ----\n// set(bytes,uint256): 0x40, 0x03, 0x08, \"abcdefgh\" -> 0x08, \"d\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/indexAccess/fixed_bytes_index_access.sol",
    "content": "contract C {\n    bytes16[] public data;\n\n    function f(bytes32 x) public returns (bytes1) {\n        return x[2];\n    }\n\n    function g(bytes32 x) public returns (uint256) {\n        data = [x[0], x[1], x[2]];\n        data[0] = \"12345\";\n        return uint256(uint8(data[0][4]));\n    }\n}\n// ----\n// f(bytes32): \"789\" -> \"9\"\n// g(bytes32): \"789\" -> 0x35\n// data(uint256): 0x01 -> \"8\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/indexAccess/index_access.sol",
    "content": "contract C {\n    function to_little_endian_64(uint64 value) public pure returns (bytes memory ret) {\n        ret = new bytes(8);\n        bytes8 bytesValue = bytes8(value);\n        // Byteswapping during copying to bytes.\n        ret[0] = bytesValue[7];\n        ret[1] = bytesValue[6];\n        ret[2] = bytesValue[5];\n        ret[3] = bytesValue[4];\n        ret[4] = bytesValue[3];\n        ret[5] = bytesValue[2];\n        ret[6] = bytesValue[1];\n        ret[7] = bytesValue[0];\n    }\n}\n// ----\n// to_little_endian_64(uint64): 0 -> 0x20, 8, 0x00\n// to_little_endian_64(uint64): 0x0102030405060708 -> 0x20, 8, 0x0807060504030201000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/indexAccess/inline_array_index_access_ints.sol",
    "content": "contract C {\n    function f() public returns (uint256) {\n        return ([1, 2, 3, 4][2]);\n    }\n}\n// ----\n// f() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/indexAccess/inline_array_index_access_strings.sol",
    "content": "contract C {\n    string public tester;\n\n    function f() public returns (string memory) {\n        return ([\"abc\", \"def\", \"g\"][0]);\n    }\n\n    function test() public {\n        tester = f();\n    }\n}\n// ----\n// test() ->\n// tester() -> 0x20, 0x3, \"abc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/indexAccess/memory_arrays_dynamic_index_access_write.sol",
    "content": "contract Test {\n    uint24[3][][4] data;\n\n    function set(uint24[3][][4] memory x)\n        internal\n        returns (uint24[3][][4] memory)\n    {\n        x[1][2][2] = 1;\n        x[1][3][2] = 7;\n        return x;\n    }\n\n    function f() public returns (uint24[3][] memory) {\n        while (data[1].length < 4) data[1].push();\n        return set(data)[1];\n    }\n}\n// ----\n// f() -> 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/indexAccess/memory_arrays_index_access_write.sol",
    "content": "contract Test {\n    function set(uint24[3][4] memory x) public {\n        x[2][2] = 1;\n        x[3][2] = 7;\n    }\n\n    function f() public returns (uint24[3][4] memory) {\n        uint24[3][4] memory data;\n        set(data);\n        return data;\n    }\n}\n// ----\n// f() -> 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/inline_array_return.sol",
    "content": "contract C {\n    uint8[] tester;\n\n    function f() public returns (uint8[5] memory) {\n        return ([1, 2, 3, 4, 5]);\n    }\n\n    function test() public returns (uint8, uint8, uint8, uint8, uint8) {\n        tester = f();\n        return (tester[0], tester[1], tester[2], tester[3], tester[4]);\n    }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/inline_array_singleton.sol",
    "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n    function f() public returns (uint256) {\n        return [4][0];\n    }\n}\n// ----\n// f() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/inline_array_storage_to_memory_conversion_ints.sol",
    "content": "contract C {\n    function f() public returns (uint256 x, uint256 y) {\n        x = 3;\n        y = 6;\n        uint256[2] memory z = [x, y];\n        return (z[0], z[1]);\n    }\n}\n// ----\n// f() -> 3, 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/inline_array_storage_to_memory_conversion_strings.sol",
    "content": "contract C {\n    string s = \"doh\";\n\n    function f() public returns (string memory, string memory) {\n        string memory t = \"ray\";\n        string[3] memory x = [s, t, \"mi\"];\n        return (x[1], x[2]);\n    }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/inline_array_strings_from_document.sol",
    "content": "contract C {\n    function f(uint256 i) public returns (string memory) {\n        string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n        return (x[i]);\n    }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/invalid_encoding_for_storage_byte_array.sol",
    "content": "contract C {\n    bytes public x = \"abc\";\n    bytes public y;\n    function invalidateXShort() public {\n        assembly { sstore(x.slot, 64) }\n        delete y;\n    }\n    function invalidateXLong() public {\n        assembly { sstore(x.slot, 5) }\n        delete y;\n    }\n    function abiEncode() public view returns (bytes memory) { return x; }\n    function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n    function copyToMemory() public view returns (bytes memory m) { m = x; }\n    function indexAccess() public view returns (bytes1) { return x[0]; }\n    function assignTo() public { x = \"def\"; }\n    function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n    function copyToStorage() public { y = x; }\n    function copyFromStorageShort() public { y = \"abc\"; x = y; }\n    function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n    function arrayPop() public { x.pop(); }\n    function arrayPush() public { x.push(\"t\"); }\n    function arrayPushEmpty() public { x.push(); }\n    function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121092\n// gas legacy: 121904\n// gas legacyOptimized: 121393\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// gas irOptimized: 29404\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// gas irOptimized: 47028\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/long_byte_array_cleanup_after_delete.sol",
    "content": "contract C {\n    bytes testArray;\n\n    struct Canary {\n        uint256 value;\n    }\n\n    function getCanary() internal pure returns (Canary storage canary) {\n        assembly {\n            mstore(0, testArray.slot)\n            let testArrayDataArea := keccak256(0, 0x20)\n            // testArray's data area occupies 3 slots when filled. Canary goes right after\n            canary.slot := add(testArrayDataArea, 3)\n        }\n    }\n\n    constructor() {\n        Canary storage canary = getCanary();\n        canary.value = type(uint256).max;\n    }\n\n    function getArrayDataAreaSlot() public pure returns (uint256 slot) {\n        assembly {\n            mstore(0, testArray.slot)\n            slot := keccak256(0, 0x20)\n        }\n        assert(slot == 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563);\n        return slot;\n    }\n\n    function getCanarySlot() public pure returns (uint256) {\n        return getArrayDataAreaSlot() + 3;\n    }\n\n    function checkSlots() public view returns (uint256, uint256, uint256, uint256, uint256) {\n        uint256 dataSlot = getArrayDataAreaSlot();\n        uint256 slot0;\n        uint256 slot1;\n        uint256 slot2;\n        uint256 slot3;\n        assembly {\n            slot0 := sload(dataSlot)\n            slot1 := sload(add(dataSlot, 1))\n            slot2 := sload(add(dataSlot, 2))\n            slot3 := sload(add(dataSlot, 3))\n        }\n        return (slot0, slot1, slot2, slot3, testArray.length);\n    }\n\n    function fillArray() public {\n        // Fill testArray to exactly 96 bytes (3 slots in its data area)\n        for (uint i = 0; i < 96; i++) {\n            testArray.push(bytes1(uint8(i + 1)));\n        }\n    }\n\n    function deleteArray() public {\n        // Should clear 3 slots without touching canary\n        delete testArray;\n    }\n\n    function canaryValue() public view returns (uint256) {\n        return getCanary().value;\n    }\n}\n// ----\n// getArrayDataAreaSlot() -> 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563\n// getCanarySlot() -> 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566\n// checkSlots() -> 0, 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// fillArray()\n// gas irOptimized: 197289\n// gas legacy: 220574\n// gas legacyOptimized: 206839\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// deleteArray()\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/long_byte_array_cleanup_after_overwrite_with_long.sol",
    "content": "contract C {\n    bytes testArray;\n\n    struct Canary {\n        uint256 value;\n    }\n\n    function getCanary() internal pure returns (Canary storage canary) {\n        assembly {\n            mstore(0, testArray.slot)\n            let testArrayDataArea := keccak256(0, 0x20)\n            // testArray's data area occupies 3 slots when filled. Canary goes right after\n            canary.slot := add(testArrayDataArea, 3)\n        }\n    }\n\n    constructor() {\n        Canary storage canary = getCanary();\n        canary.value = type(uint256).max; // Should not be overwritten\n    }\n\n    function fillArray() public {\n        // Fill testArray to exactly 96 bytes (3 slots in its data area)\n        for (uint i = 0; i < 96; i++) {\n            testArray.push(bytes1(uint8(i + 1)));\n        }\n    }\n\n    function shrinkArray() public returns (uint256) {\n        // Shrink from 96 to 50 bytes. Should clear slot 2 without touching canary\n        bytes memory newData = new bytes(50);\n        for (uint i = 0; i < 50; i++) {\n            newData[i] = bytes1(uint8(i + 2));\n        }\n        testArray = newData;\n        return testArray.length;\n    }\n\n    function canaryValue() public view returns (uint256) {\n        return getCanary().value;\n    }\n\n    function arrayLength() public view returns (uint256) {\n        return testArray.length;\n    }\n\n    function getDataSlotContent(uint256 index) public view returns (bytes32 value) {\n        assembly {\n            mstore(0, testArray.slot)\n            let testArrayDataArea := keccak256(0, 0x20)\n            let slot := add(testArrayDataArea, index)\n            value := sload(slot)\n        }\n        return value;\n    }\n\n    function checkSlots() public view returns (bytes32, bytes32, bytes32, uint256, uint256) {\n        return (\n            getDataSlotContent(0),  // First data slot\n            getDataSlotContent(1),  // Second data slot (partial cleanup expected)\n            getDataSlotContent(2),  // Third data slot (should be cleared after shrink)\n            canaryValue(),          // Canary value (should never change)\n            arrayLength()           // Current array length\n        );\n    }\n\n    function getSlot1LastBytes() public view returns (bytes14 lastBytes) {\n        // Get the last 14 bytes of slot 1, which should be zero after partial cleanup\n        bytes32 slot1 = getDataSlotContent(1);\n        assembly {\n            // Shift left by 18 bytes (144 bits) to move the last 14 bytes to the front\n            lastBytes := shl(144, slot1)\n        }\n        return lastBytes;\n    }\n\n    function getArrayBytes(uint256 start, uint256 count) public view returns (bytes memory) {\n        bytes memory result = new bytes(count);\n        for (uint i = 0; i < count && start + i < testArray.length; i++) {\n            result[i] = testArray[start + i];\n        }\n        return result;\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// arrayLength() ->0\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// fillArray()\n// gas irOptimized: 197352\n// gas legacy: 220574\n// gas legacyOptimized: 206839\n// arrayLength() ->96\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// getArrayBytes(uint256,uint256): 0, 5 -> 0x20, 5, 0x0102030405000000000000000000000000000000000000000000000000000000\n// getArrayBytes(uint256,uint256): 32, 5 -> 0x20, 5, 0x2122232425000000000000000000000000000000000000000000000000000000\n// getArrayBytes(uint256,uint256): 64, 5 -> 0x20, 5, 0x4142434445000000000000000000000000000000000000000000000000000000\n// shrinkArray() -> 50\n// arrayLength() ->50\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// getArrayBytes(uint256,uint256): 0, 5 -> 0x20, 5, 0x0203040506000000000000000000000000000000000000000000000000000000\n// getArrayBytes(uint256,uint256): 32, 5 -> 0x20, 5, 0x2223242526000000000000000000000000000000000000000000000000000000\n// getArrayBytes(uint256,uint256): 45, 5 -> 0x20, 5, 0x2f30313233000000000000000000000000000000000000000000000000000000\n// getSlot1LastBytes() -> 0\n// getDataSlotContent(uint256): 2 -> 0\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/memory.sol",
    "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n    function h(uint[4] memory n) public pure returns (uint) {\n        return n[0] + n[1] + n[2] + n[3];\n    }\n\n    function i(uint[4] memory n) public view returns (uint) {\n        return this.h(n) * 2;\n    }\n}\n// ----\n// h(uint256[4]): 1, 2, 3, 4 -> 10\n// i(uint256[4]): 1, 2, 3, 4 -> 20\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/memory_arrays_of_various_sizes.sol",
    "content": "// Computes binomial coefficients the chinese way\ncontract C {\n    function f(uint256 n, uint256 k) public returns (uint256) {\n        uint256[][] memory rows = new uint256[][](n + 1);\n        for (uint256 i = 1; i <= n; i++) {\n            rows[i] = new uint256[](i);\n            rows[i][0] = rows[i][rows[i].length - 1] = 1;\n            for (uint256 j = 1; j < i - 1; j++)\n                rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n        }\n        return rows[n][k - 1];\n    }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/nested_calldata_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    uint[][2] public tmp_i;\n    function i(uint[][2] calldata s) external { tmp_i = s; }\n}\n// ====\n// compileViaYul: true\n// ----\n// i(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04\n// gas irOptimized: 223100\n// tmp_i(uint256,uint256): 0, 0 -> 0x0A01\n// tmp_i(uint256,uint256): 1, 0 -> 0x0B01\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/nested_calldata_storage2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    uint[][] public tmp_i;\n    function i(uint[][] calldata s) external { tmp_i = s; }\n}\n// ====\n// compileViaYul: true\n// ----\n// i(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04\n// gas irOptimized: 245511\n// tmp_i(uint256,uint256): 0, 0 -> 0x0A01\n// tmp_i(uint256,uint256): 1, 0 -> 0x0B01\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/array_pop.sol",
    "content": "contract c {\n    uint256[] data;\n\n    function test() public returns (uint256 x, uint256 l) {\n        data.push(7);\n        data.push(3);\n        x = data.length;\n        data.pop();\n        x = data.length;\n        data.pop();\n        l = data.length;\n    }\n}\n// ----\n// test() -> 1, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol",
    "content": "contract c {\n    uint256 a;\n    uint256 b;\n    uint256 c;\n    uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n    uint16[][] data;\n    function test() public returns (uint x, uint y, uint z) {\n        for (uint i = 1; i <= 48; i++)\n            data.push(inner);\n        for (uint j = 1; j <= 10; j++)\n            data.pop();\n        x = data[data.length - 1][0];\n        for (uint k = 1; k <= 10; k++)\n            data.pop();\n        y = data[data.length - 1][1];\n        for (uint l = 1; l <= 10; l++)\n            data.pop();\n        z = data[data.length - 1][2];\n        for (uint m = 1; m <= 18; m++)\n            data.pop();\n        delete inner;\n    }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828383\n// gas legacy: 1841877\n// gas legacyOptimized: 1821569\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/array_pop_empty_exception.sol",
    "content": "contract c {\n    uint256[] data;\n\n    function test() public returns (bool) {\n        data.pop();\n        return true;\n    }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x31\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/array_pop_isolated.sol",
    "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n    uint256[] data;\n\n    function test() public returns (uint256 x) {\n        x = 2;\n        data.pop;\n        x = 3;\n    }\n}\n// ----\n// test() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/array_pop_storage_empty.sol",
    "content": "contract c {\n    uint[] data;\n    function test() public {\n        data.push(7);\n        data.pop();\n    }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol",
    "content": "contract c {\n    uint16[] data;\n    function test() public returns (uint16 x, uint16 y, uint16 z) {\n        for (uint i = 1; i <= 48; i++)\n            data.push(uint16(i));\n        for (uint j = 1; j <= 10; j++)\n            data.pop();\n        x = data[data.length - 1];\n        for (uint k = 1; k <= 10; k++)\n            data.pop();\n        y = data[data.length - 1];\n        for (uint l = 1; l <= 10; l++)\n            data.pop();\n        z = data[data.length - 1];\n        for (uint m = 1; m <= 18; m++)\n            data.pop();\n    }\n}\n// ----\n// test() -> 38, 28, 18\n// gas irOptimized: 148380\n// gas legacy: 151182\n// gas legacyOptimized: 142418\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol",
    "content": "contract c {\n    uint256 a;\n    uint256 b;\n    uint256 c;\n    uint24[] data;\n    function test() public returns (uint24 x, uint24 y) {\n        for (uint i = 1; i <= 30; i++)\n            data.push(uint24(i));\n        for (uint j = 1; j <= 10; j++)\n            data.pop();\n        x = data[data.length - 1];\n        for (uint k = 1; k <= 10; k++)\n            data.pop();\n        y = data[data.length - 1];\n        for (uint l = 1; l <= 10; l++)\n            data.pop();\n    }\n}\n// ----\n// test() -> 20, 10\n// gas irOptimized: 125889\n// gas legacy: 127215\n// gas legacyOptimized: 122224\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/byte_array_pop.sol",
    "content": "contract c {\n    bytes data;\n\n    function test() public returns (uint256 x, uint256 y, uint256 l) {\n        data.push(0x07);\n        data.push(0x03);\n        x = data.length;\n        data.pop();\n        data.pop();\n        data.push(0x02);\n        y = data.length;\n        l = data.length;\n    }\n}\n// ----\n// test() -> 2, 1, 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol",
    "content": "contract c {\n    bytes data;\n\n    function test() public returns (bytes memory) {\n        for (uint256 i = 0; i < 33; i++) data.push(0x03);\n        for (uint256 j = 0; j < 4; j++) data.pop();\n        return data;\n    }\n}\n// ----\n// test() -> 0x20, 29, 0x0303030303030303030303030303030303030303030303030303030303000000\n// gas irOptimized: 85778\n// gas legacy: 97666\n// gas legacyOptimized: 96874\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/byte_array_pop_empty_exception.sol",
    "content": "contract c {\n    uint256 a;\n    uint256 b;\n    uint256 c;\n    bytes data;\n\n    function test() public returns (bool) {\n        data.pop();\n        return true;\n    }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x31\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/byte_array_pop_isolated.sol",
    "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n    bytes data;\n\n    function test() public returns (uint256 x) {\n        x = 2;\n        data.pop;\n        x = 3;\n    }\n}\n// ----\n// test() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol",
    "content": "contract c {\n    uint256 a;\n    uint256 b;\n    uint256 c;\n    bytes data;\n    function test() public returns (bool) {\n        for (uint8 i = 0; i <= 40; i++)\n            data.push(bytes1(i+1));\n        for (int8 j = 40; j >= 0; j--) {\n            require(data[uint8(j)] == bytes1(uint8(j+1)));\n            require(data.length == uint8(j+1));\n            data.pop();\n        }\n        return true;\n    }\n}\n// ----\n// test() -> true\n// gas irOptimized: 138795\n// gas legacy: 178396\n// gas legacyOptimized: 163832\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol",
    "content": "contract c {\n    uint256 a;\n    uint256 b;\n    bytes data;\n    function test() public {\n        for (uint8 i = 0; i <= 40; i++)\n            data.push(0x03);\n        for (uint8 j = 0; j <= 40; j++) {\n            assembly {\n                mstore(0, \"garbage\")\n            }\n            data.pop();\n        }\n    }\n}\n// ----\n// test() ->\n// gas irOptimized: 113631\n// gas legacy: 131256\n// gas legacyOptimized: 126668\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol",
    "content": "contract c {\n    bytes data;\n\n    function test() public returns (bytes memory) {\n        for (uint256 i = 0; i < 34; i++) data.push(0x03);\n        data.pop();\n        return data;\n    }\n}\n// ----\n// test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 106762\n// gas legacy: 121252\n// gas legacyOptimized: 120370\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/byte_array_pop_storage_empty.sol",
    "content": "contract c {\n    bytes data;\n    function test() public {\n        data.push(0x07);\n        data.push(0x05);\n        data.push(0x03);\n        data.pop();\n        data.pop();\n        data.pop();\n    }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/pop/parenthesized.sol",
    "content": "contract C {\n  int[] data;\n  function f() public returns (uint) {\n    data.push(1);\n    (data.pop)();\n    return data.length;\n  }\n}\n// ----\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/array_push.sol",
    "content": "contract c {\n    uint256[] data;\n\n    function test()\n        public\n        returns (uint256 x, uint256 y, uint256 z, uint256 l)\n    {\n        data.push(5);\n        x = data[0];\n        data.push(4);\n        y = data[1];\n        data.push(3);\n        l = data.length;\n        z = data[2];\n    }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/array_push_nested.sol",
    "content": "contract C {\n    uint8 b = 23;\n    uint120[][] s;\n    uint8 a = 17;\n    function f() public {\n        s.push();\n        assert(s.length == 1);\n        assert(s[0].length == 0);\n        s[0].push();\n        assert(s[0].length == 1);\n        assert(s[0][0] == 0);\n    }\n}\n// ----\n// f() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol",
    "content": "contract C {\n    uint8 b = 23;\n    uint120[][] s;\n    uint8 a = 17;\n    function f(uint120[] calldata c) public returns(uint120) {\n        s.push(c);\n        assert(s.length == 1);\n        assert(s[0].length == c.length);\n        assert(s[0].length > 0);\n        return s[0][0];\n    }\n}\n// ----\n// f(uint120[]): 0x20, 3, 1, 2, 3 -> 1\n// gas irOptimized: 112852\n// gas legacy: 114404\n// gas legacyOptimized: 113087\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/array_push_nested_from_memory.sol",
    "content": "contract C {\n    uint8 b = 23;\n    uint120[][] s;\n    uint8 a = 17;\n    function f() public returns(uint120) {\n        delete s;\n        uint120[] memory m = new uint120[](3);\n        m[0] = 1;\n        s.push(m);\n        assert(s.length == 1);\n        assert(s[0].length == m.length);\n        assert(s[0].length > 0);\n        return s[0][0];\n    }\n}\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/array_push_packed_array.sol",
    "content": "contract c {\n    uint80[] x;\n\n    function test() public returns (uint80, uint80, uint80, uint80) {\n        x.push(1);\n        x.push(2);\n        x.push(3);\n        x.push(4);\n        x.push(5);\n        x.pop();\n        return (x[0], x[1], x[2], x[3]);\n    }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 92545\n// gas legacy: 92756\n// gas legacyOptimized: 92045\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/array_push_struct.sol",
    "content": "contract c {\n    struct S {\n        uint16 a;\n        uint16 b;\n        uint16[3] c;\n        uint16[] d;\n    }\n    S[] data;\n\n    function test() public returns (uint16, uint16, uint16, uint16) {\n        S memory s;\n        s.a = 2;\n        s.b = 3;\n        s.c[2] = 4;\n        s.d = new uint16[](4);\n        s.d[2] = 5;\n        data.push(s);\n        return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]);\n    }\n}\n// ----\n// test() -> 2, 3, 4, 5\n// gas irOptimized: 135329\n// gas legacy: 139481\n// gas legacyOptimized: 135795\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol",
    "content": "pragma abicoder v2;\n\ncontract c {\n    struct S {\n        uint16 a;\n        uint16 b;\n        uint16[3] c;\n        uint16[] d;\n    }\n    S[] data;\n\n    function test(S calldata c) public returns (uint16, uint16, uint16, uint16) {\n        data.push(c);\n        return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]);\n    }\n}\n// ----\n// test((uint16,uint16,uint16[3],uint16[])): 0x20, 2, 3, 0, 0, 4, 0xC0, 4, 0, 0, 5, 0, 0 -> 2, 3, 4, 5\n// gas irOptimized: 137153\n// gas legacy: 142414\n// gas legacyOptimized: 137975\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/byte_array_push.sol",
    "content": "contract c {\n    bytes data;\n\n    function test() public returns (bool x) {\n        data.push(0x05);\n        if (data.length != 1) return true;\n        if (data[0] != 0x05) return true;\n        data.push(0x04);\n        if (data[1] != 0x04) return true;\n        data.push(0x03);\n        uint256 l = data.length;\n        if (data[2] != 0x03) return true;\n        if (l != 0x03) return true;\n    }\n}\n// ----\n// test() -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol",
    "content": "// Tests transition between short and long encoding\ncontract c {\n    bytes data;\n\n    function test() public returns (uint256) {\n        for (uint8 i = 1; i < 40; i++) {\n            data.push(bytes1(i));\n            if (data.length != i) return 0x1000 + i;\n            if (data[data.length - 1] != bytes1(i)) return i;\n        }\n        for (uint8 i = 1; i < 40; i++)\n            if (data[i - 1] != bytes1(i)) return 0x1000000 + i;\n        return 0;\n    }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 167569\n// gas legacy: 206218\n// gas legacyOptimized: 197297\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/nested_bytes_push.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    bytes[] a;\n\n    function f() public {\n        a.push(\"abc\");\n        a.push(\"abcdefghabcdefghabcdefghabcdefgh\");\n        a.push(\"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh\");\n        assert(a[0][0] == \"a\");\n        assert(a[1][31] == \"h\");\n        assert(a[2][32] == \"a\");\n    }\n}\n// ----\n// f() ->\n// gas irOptimized: 179534\n// gas legacy: 181013\n// gas legacyOptimized: 180406\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/push_no_args_1d.sol",
    "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/push_no_args_2d.sol",
    "content": "contract C {\n\tuint[][] array2d;\n\n\tfunction l() public returns (uint) {\n\t\treturn array2d.length;\n\t}\n\n\tfunction ll(uint index) public returns (uint) {\n\t\treturn array2d[index].length;\n\t}\n\n\tfunction a(uint i, uint j) public returns (uint) {\n\t\treturn array2d[i][j];\n\t}\n\n\tfunction f(uint index, uint value) public {\n\t\tuint[] storage pointer = array2d.push();\n\t\tfor (uint i = 0; i <= index; ++i)\n\t\t\tpointer.push();\n\t\tpointer[index] = value;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray2d.push().push() = value;\n\t}\n}\n// ----\n// l() -> 0\n// f(uint256,uint256): 42, 64 ->\n// gas irOptimized: 112288\n// gas legacy: 107925\n// gas legacyOptimized: 101896\n// l() -> 1\n// ll(uint256): 0 -> 43\n// a(uint256,uint256): 0, 42 -> 64\n// f(uint256,uint256): 84, 128 ->\n// gas irOptimized: 118708\n// gas legacy: 109977\n// gas legacyOptimized: 98446\n// l() -> 2\n// ll(uint256): 1 -> 85\n// a(uint256,uint256): 0, 42 -> 64\n// a(uint256,uint256): 1, 84 -> 128\n// lv(uint256): 512 ->\n// a(uint256,uint256): 2, 0 -> 512\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol",
    "content": "contract C {\n\tbytes array;\n\n\tfunction f() public {\n\t\tarray.push();\n\t}\n\n\tfunction g(uint x) public {\n\t\tfor (uint i = 0; i < x; ++i)\n\t\t\tarray.push() = bytes1(uint8(i));\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n\tfunction a(uint index) public view returns (bytes1) {\n\t\treturn array[index];\n\t}\n}\n// ----\n// l() -> 0\n// g(uint256): 70 ->\n// gas irOptimized: 181778\n// gas legacy: 175192\n// gas legacyOptimized: 175005\n// l() -> 70\n// a(uint256): 69 -> left(69)\n// f() ->\n// l() -> 71\n// a(uint256): 70 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/push/push_no_args_struct.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS[] array;\n\n\tfunction f(uint y) public {\n\t\tS storage s = array.push();\n\t\tg(s, y);\n\t}\n\n\tfunction g(S storage s, uint y) internal {\n\t\ts.x = y;\n\t}\n\n\tfunction h(uint y) public {\n\t\tg(array.push(), y);\n\t}\n\n\tfunction lv(uint y) public {\n\t\tarray.push().x = y;\n\t}\n\n\tfunction a(uint i) public returns (uint) {\n\t\treturn array[i].x;\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// f(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// h(uint256): 84 ->\n// l() -> 2\n// a(uint256): 1 -> 84\n// lv(uint256): 4096 ->\n// l() -> 3\n// a(uint256): 2 -> 4096\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/reusing_memory.sol",
    "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n    uint256 public flag;\n\n    constructor(uint256 x) {\n        flag = x;\n    }\n}\n\n\ncontract Main {\n    mapping(uint256 => uint256) map;\n\n    function f(uint256 x) public returns (uint256) {\n        map[x] = x;\n        return\n            (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n                .flag();\n    }\n\n    function g(uint256 a) public returns (uint256) {\n        return map[a];\n    }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/short_fixed_array_cleanup.sol",
    "content": "contract c {\n    uint spacer1;\n    uint spacer2;\n    uint[3] data;\n    function fill() public {\n        for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n    }\n    function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/slices/array_calldata_assignment.sol",
    "content": "contract C {\n    function f(uint256[] calldata x, uint256[] calldata y, uint256 i) external returns (uint256) {\n        x = y;\n        return x[i];\n    }\n}\n// ----\n// f(uint256[],uint256[],uint256): 0x60, 0xA0, 1, 1, 0, 2, 1, 2 -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/slices/array_slice_calldata_as_argument_of_external_calls.sol",
    "content": "contract C {\n    function f1(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) {\n        return keccak256(c1[s:e]) == keccak256(c2);\n    }\n\n    function f2(bytes calldata c, uint256 s) public returns (uint256, bytes memory) {\n        return abi.decode(c[s:], (uint256, bytes));\n    }\n\n    function f3(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) {\n        bytes memory a = abi.encode(c1[s:e]);\n        bytes memory b = abi.encode(c2);\n        if (a.length != b.length) { return false; }\n        for (uint256 i = 0; i < a.length; i++) {\n            if (a[i] != b[i]) { return false; }\n        }\n        return true;\n    }\n\n    function f4(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) {\n        bytes memory a = abi.encodePacked(c1[s:e]);\n        bytes memory b = abi.encodePacked(c2);\n        if (a.length != b.length) { return false; }\n        for (uint256 i = 0; i < a.length; i++) {\n            if (a[i] != b[i]) { return false; }\n        }\n        return true;\n    }\n}\n// ----\n// f1(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcde\" -> true\n// f1(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcdf\" -> false\n// f2(bytes,uint256): 0x40, 0, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n// f3(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcde\" -> true\n// f3(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcdf\" -> false\n// f4(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcde\" -> true\n// f4(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcdf\" -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/slices/array_slice_calldata_to_calldata.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint128 p1;\n        uint256[3] a;\n        uint32 p2;\n    }\n    function f(S[] calldata c) internal returns (S[] memory) {\n        return c;\n    }\n    function g(S[] calldata c, uint256 s, uint256 e) public returns (S[] memory) {\n        return f(c[s:e]);\n    }\n\n    function f1(uint256[3][] calldata c) internal returns (uint256[3][] memory) {\n        return c;\n    }\n    function g1(uint256[3][] calldata c, uint256 s, uint256 e) public returns (uint256[3][] memory) {\n        return f1(c[s:e]);\n    }\n}\n// ----\n// g((uint128,uint256[3],uint32)[],uint256,uint256): 0x60, 1, 3, 4, 55, 1, 2, 3, 66, 66, 2, 3, 4, 77, 77, 3, 4, 5, 88, 88, 4, 5, 6, 99 -> 0x20, 2, 66, 2, 3, 4, 77, 77, 3, 4, 5, 88\n// g1(uint256[3][],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 -> 0x20, 2, 4, 5, 6, 7, 8, 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/slices/array_slice_calldata_to_memory.sol",
    "content": "contract C {\n    function f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n        int[] memory m = b[start:end];\n        uint len = end - start;\n        assert(len == m.length);\n        for (uint i = 0; i < len; i++) {\n            assert(b[start:end][i] == m[i]);\n        }\n        return [b[start:end]][0][0];\n    }\n\n    function g(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n        return b[start:end];\n    }\n\n    function h1(int[] memory b) internal returns (int[] memory) {\n        return b;\n    }\n\n    function h(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n        return h1(b[start:end]);\n    }\n}\n// ----\n// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2\n// g(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n// h(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/slices/array_slice_calldata_to_storage.sol",
    "content": "contract C {\n    int[] s;\n    function f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n        s = b[start:end];\n        uint len = end - start;\n        assert(len == s.length);\n        for (uint i = 0; i < len; i++) {\n            assert(b[start:end][i] == s[i]);\n        }\n        return s[0];\n    }\n}\n// ----\n// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/storage_array_ref.sol",
    "content": "contract BinarySearch {\n    /// Finds the position of _value in the sorted list _data.\n    /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n    function find(uint256[] storage _data, uint256 _value)\n        internal\n        returns (uint256 o_position)\n    {\n        return find(_data, 0, _data.length, _value);\n    }\n\n    function find(\n        uint256[] storage _data,\n        uint256 _begin,\n        uint256 _len,\n        uint256 _value\n    ) private returns (uint256 o_position) {\n        if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n            return type(uint256).max; // failure\n        uint256 halfLen = _len / 2;\n        uint256 v = _data[_begin + halfLen];\n        if (_value < v) return find(_data, _begin, halfLen, _value);\n        else if (_value > v)\n            return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n        else return _begin + halfLen;\n    }\n}\n\n\ncontract Store is BinarySearch {\n    uint256[] data;\n\n    function add(uint256 v) public {\n        data.push(0);\n        data[data.length - 1] = v;\n    }\n\n    function find(uint256 v) public returns (uint256) {\n        return find(data, v);\n    }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/string_allocation_bug.sol",
    "content": "contract Sample {\n    struct s {\n        uint16 x;\n        uint16 y;\n        string a;\n        string b;\n    }\n    s[2] public p;\n\n    constructor() {\n        s memory m;\n        m.x = 0xbbbb;\n        m.y = 0xcccc;\n        m.a = \"hello\";\n        m.b = \"world\";\n        p[0] = m;\n    }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/string_bytes_conversion.sol",
    "content": "contract Test {\n    string s;\n    bytes b;\n\n    function f(string memory _s, uint256 n) public returns (bytes1) {\n        b = bytes(_s);\n        s = string(b);\n        return bytes(s)[n];\n    }\n\n    function l() public returns (uint256) {\n        return bytes(s).length;\n    }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/string_literal_assign_to_storage_bytes.sol",
    "content": "contract C {\n    bytes public s = \"abc\";\n    bytes public s1 = \"abcd\";\n    function f() public {\n        s = \"abcd\";\n        s1 = \"abc\";\n    }\n    function g() public {\n        (s, s1) = (\"abc\", \"abcd\");\n    }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/array/strings_in_struct.sol",
    "content": "contract buggystruct {\n    Buggy public bug;\n\n    struct Buggy {\n        uint256 first;\n        uint256 second;\n        uint256 third;\n        string last;\n    }\n\n    constructor() {\n        bug = Buggy(10, 20, 30, \"asdfghjkl\");\n    }\n\n    function getFirst() public returns (uint256) {\n        return bug.first;\n    }\n\n    function getSecond() public returns (uint256) {\n        return bug.second;\n    }\n\n    function getThird() public returns (uint256) {\n        return bug.third;\n    }\n\n    function getLast() public returns (string memory) {\n        return bug.last;\n    }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/assignment_to_const_var_involving_keccak.sol",
    "content": "contract C {\n    bytes32 constant x = keccak256(\"abc\");\n\n    function f() public returns (bytes32) {\n        return x;\n    }\n}\n// ----\n// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/blobhash.sol",
    "content": "contract C {\n    function f() public view returns(bytes32) {\n        return blobhash(0);\n    }\n    function g() public view returns(bytes32) {\n        return blobhash(1);\n    }\n    function h() public view returns(bytes32) {\n        // NOTE: blobhash(2) should return 0 since EVMHost has only two blob hashes injected in the block the transaction is being executed.\n        return blobhash(2);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// g() -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// h() -> 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/blobhash_shadow_resolution.sol",
    "content": "contract C {\n    function blobhash(uint256 index) public pure returns(bytes32) {\n        return bytes32(index);\n    }\n    function f() public pure returns(bytes32) {\n        return blobhash(3);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x03\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/blockhash.sol",
    "content": "contract C {\n    function f() public returns(bytes32) {\n        return blockhash(1);\n    }\n    function g() public returns(bytes32) {\n        return blockhash(2);\n    }\n    function h() public returns(bytes32) {\n        return blockhash(3);\n    }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// g() -> 0x3737373737373737373737373737373737373737373737373737373737373739\n// h() -> 0x373737373737373737373737373737373737373737373737373737373737373a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/blockhash_shadow_resolution.sol",
    "content": "contract C {\n    function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n    function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_equivalent_solidity_spec.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    // value from EIP-7201 (https://eips.ethereum.org/EIPS/eip-7201)\n    uint expectedSlot = 0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500;\n    string namespace = \"example.main\";\n\n    function builtinMatchesSolidityImplementation() public view returns (bool) {\n        assert(expectedSlot == erc7201Mock(namespace));\n\n        return\n            erc7201(namespace) == erc7201Mock(\"example.main\") &&\n            erc7201(\"example.main\") == erc7201Mock(\"example.main\");\n    }\n    function builtinOutput() public view returns (uint) {\n        return erc7201(namespace);\n    }\n}\n// ----\n// builtinMatchesSolidityImplementation() -> true\n// builtinOutput() -> 0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_equivalent_solidity_spec_comptime.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    uint8[erc7201(\"example.main\")] array;\n\n    function builtinMatchesSolidityImplementation() public view returns (bool) {\n        return array.length == erc7201Mock(\"example.main\");\n    }\n}\n// ----\n// builtinMatchesSolidityImplementation() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_layout_specifier_slot_match_comptime.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C layout at erc7201(\"example.main\") {\n    uint x;\n    function builtinMatchesSolidityImplementation() public pure returns (bool) {\n        uint firstSlot;\n        assembly {\n            firstSlot := x.slot\n        }\n        return firstSlot == erc7201Mock(\"example.main\");\n    }\n}\n// ----\n// builtinMatchesSolidityImplementation() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_overflow_expression.sol",
    "content": "contract C {\n    function f() public pure returns (uint) {\n        return erc7201(\"main:example\") + erc7201(\"main:example\");\n    }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_param_abi_encode.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    function builtinMatchesSolidityImplementation() public pure returns (bool) {\n        return\n            erc7201(string(abi.encode(\"example.main\"))) ==\n            erc7201Mock(string(abi.encode(\"example.main\")));\n    }\n    function builtinOutput() public pure returns (uint) {\n        return erc7201(string(abi.encode(\"example.main\")));\n    }\n}\n// ----\n// builtinMatchesSolidityImplementation() -> true\n// builtinOutput() -> -14651554186193368082021334953908208762193027200365752719897746810709432803072\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_param_array_string_literal.sol",
    "content": "contract C {\n    function test() public pure returns (bool) {\n        return erc7201([\"x\"][0]) == erc7201([\"y\", \"x\"][1]);\n    }\n}\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_param_locations.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    string storageVarStr = \"example.contract\";\n    string constant constStorageVarStr = \"example.contract\";\n    function storageVar() public view returns (bool) {\n        return erc7201(storageVarStr) == erc7201Mock(\"example.contract\");\n    }\n    function constStorageVar() public pure returns (bool) {\n        return erc7201(constStorageVarStr) == erc7201Mock(\"example.contract\");\n    }\n    function memoryVar() public pure returns (bool) {\n        string memory memoryVarStr = \"example.main\";\n        return erc7201(memoryVarStr) == erc7201Mock(\"example.main\");\n    }\n    function calldataParam(string calldata calldataVarStr) public pure returns (bool) {\n        return erc7201(calldataVarStr) == erc7201Mock(\"example.main\");\n    }\n    function calldataSlice(bytes calldata namespaceID) public pure returns (bool) {\n        return erc7201(string(namespaceID[2:5])) == erc7201Mock(\"amp\");\n    }\n    function literalParam() public pure returns (bool) {\n        return erc7201(\"example.main\") == erc7201Mock(\"example.main\");\n    }\n}\n// ----\n// storageVar() -> true\n// constStorageVar() -> true\n// memoryVar() -> true\n// calldataParam(string): 0x20, 12, \"example.main\" -> true\n// calldataSlice(bytes): 0x20, 12, \"example.main\" -> true\n// literalParam() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_param_pure_function.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    function f() public pure returns (string memory) {\n        return \"example.main\";\n    }\n    function builtinMatchesSolidityImplementation() public pure returns (bool) {\n        return erc7201(f()) == erc7201Mock(\"example.main\");\n    }\n}\n// ----\n// builtinMatchesSolidityImplementation() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_param_string_concat.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    function builtinMatchesSolidityImplementation() public view returns (bool) {\n        string memory first = \"example.\";\n        return erc7201(string.concat(first, \"main\")) == erc7201Mock(\"example.main\");\n    }\n}\n// ----\n// builtinMatchesSolidityImplementation() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_param_string_literal_with_escaped_chars.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    string constant CONST = \"\\n\\\"\\'\\\\abc\\\ndef\";\n    function builtinMatchesSolidityImplementation() public pure returns (bool) {\n        return erc7201(\"\\n\\\"\\'\\\\abc\\\ndef\") == erc7201Mock(\"\\n\\\"\\'\\\\abc\\\ndef\");\n    }\n}\n// ----\n// builtinMatchesSolidityImplementation() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_param_ternary_operator.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    function simple() public pure returns (bool) {\n        return erc7201(true ? \"x\" : \"y\") == erc7201Mock(\"x\");\n    }\n    function compounded(bool c1, bool c2) public pure returns (bool) {\n        return erc7201(c1 ? \"a\" : (c2 ? \"x\" : \"c\")) == erc7201Mock(\"x\");\n    }\n}\n// ----\n// simple() -> true\n// compounded(bool,bool): false, true -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_param_unicode_string_literal.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    function builtinMatchesSolidityImplementation() public pure returns (bool) {\n        return erc7201(unicode\"Hello 😃\") == erc7201Mock(unicode\"Hello 😃\");\n    }\n}\n// ----\n// builtinMatchesSolidityImplementation() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_param_unicode_string_variable.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    string unicodeStr = unicode\"Hello 😃\";\n    function builtinMatchesSolidityImplementation() public view returns (bool) {\n        return erc7201(unicodeStr) == erc7201Mock(unicode\"Hello 😃\");\n    }\n}\n// ----\n// builtinMatchesSolidityImplementation() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_param_with_zero_last_byte_of_inner_hash.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    // The purpose of this test is to guarantee that the\n    // erc7201 implementation does not subtract 1 only from the\n    // last byte rather than the whole number during its intermediary operations.\n    function builtinMatchesSolidityImplementation() public pure returns (bool) {\n        string memory s = \"85\";\n        bytes32 h = keccak256(bytes(s));\n\n        // \"85\" is intentionally chosen because it produces\n        // a keccak256 hash with the last byte zero\n        assert(uint8(h[31]) == 0);\n\n        return\n            erc7201(s) == erc7201Mock(s) &&\n            erc7201(\"85\") == erc7201Mock(\"85\");\n    }\n}\n// ----\n// builtinMatchesSolidityImplementation() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/erc7201_param_with_zero_last_byte_of_inner_hash_comptime.sol",
    "content": "function erc7201Mock(string memory id) pure returns (uint256) {\n    return uint256(\n        keccak256(bytes.concat(bytes32(uint256(keccak256(bytes(id))) - 1))) &\n        ~bytes32(uint256(0xff))\n    );\n}\n\ncontract C {\n    uint8[erc7201(\"85\")] array;\n    // The purpose of this test is to guarantee that the\n    // erc7201 implementation does not subtract 1 only from the\n    // last byte rather than the whole number during its intermediary operations.\n    function builtinMatchesSolidityImplementation() public view returns (bool) {\n        bytes32 h = keccak256(bytes(\"85\"));\n\n        // \"85\" is intentionally chosen because it produces\n        // a keccak256 hash with the last byte zero\n        assert(uint8(h[31]) == 0);\n\n        return array.length == erc7201Mock(\"85\");\n    }\n}\n// ----\n// builtinMatchesSolidityImplementation() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/function_types_sig.sol",
    "content": "contract C {\n    uint256 public x;\n\n    function f() public pure returns (bytes4) {\n        return this.f.selector;\n    }\n\n    function g() public returns (bytes4) {\n        function () pure external returns (bytes4) fun = this.f;\n        return fun.selector;\n    }\n\n    function h() public returns (bytes4) {\n        function () pure external returns (bytes4) fun = this.f;\n        return fun.selector;\n    }\n\n    function i() public pure returns (bytes4) {\n        return this.x.selector;\n    }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// i() -> 0x0c55699c00000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/iterated_keccak256_with_bytes.sol",
    "content": "contract c {\n    bytes data;\n\n    function foo() public returns (bytes32) {\n        data.push(\"x\");\n        data.push(\"y\");\n        data.push(\"z\");\n        return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n    }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/keccak256.sol",
    "content": "contract C {\n    function f(int256 input) public returns (bytes32 sha256hash) {\n        return keccak256(abi.encodePacked(bytes32(uint256(input))));\n    }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/keccak256_empty.sol",
    "content": "contract C {\n    function f() public returns (bytes32) {\n        return keccak256(\"\");\n    }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/keccak256_multiple_arguments.sol",
    "content": "contract c {\n    function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n        d = keccak256(abi.encodePacked(a, b, c));\n    }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/keccak256_multiple_arguments_with_numeric_literals.sol",
    "content": "contract c {\n    function foo(uint256 a, uint16 b) public returns (bytes32 d) {\n        d = keccak256(abi.encodePacked(a, b, uint8(145)));\n    }\n}\n// ----\n// foo(uint256,uint16): 0xa, 0xc -> 0x88acd45f75907e7c560318bc1a5249850a0999c4896717b1167d05d116e6dbad\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/keccak256_multiple_arguments_with_string_literals.sol",
    "content": "contract c {\n    function foo() public returns (bytes32 d) {\n        d = keccak256(\"foo\");\n    }\n\n    function bar(uint256 a, uint16 b) public returns (bytes32 d) {\n        d = keccak256(abi.encodePacked(a, b, uint8(145), \"foo\"));\n    }\n}\n// ----\n// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d\n// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/keccak256_packed.sol",
    "content": "contract C {\n    function f(int256 _input) public returns (bytes32 hash) {\n        uint24 b = 65536;\n        uint c = 256;\n        bytes32 input = bytes32(uint256(_input));\n        return keccak256(abi.encodePacked(uint8(8), input, b, input, c));\n    }\n}\n// ----\n// f(int256): 4 -> 0xd270285b9966fefc715561efcd09d5b6a8deb15596f7c53cb4a1bb73aa55ac3a\n// f(int256): 5 -> 0xf2f92566c5653600c1e527a7073e5d881576d12bb51887c0b8f3e1f81865b03d\n// f(int256): -1 -> 0xbc78b45e0db67af5af72e4ab62757c67aefa7388cdf0c4e74f8b5fe9dd5d9d13\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/keccak256_packed_complex_types.sol",
    "content": "contract C {\n    uint120[3] x;\n    function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n        uint120[] memory y = new uint120[](3);\n        x[0] = y[0] = uint120(type(uint).max - 1);\n        x[1] = y[1] = uint120(type(uint).max - 2);\n        x[2] = y[2] = uint120(type(uint).max - 3);\n        hash1 = keccak256(abi.encodePacked(x));\n        hash2 = keccak256(abi.encodePacked(y));\n        hash3 = keccak256(abi.encodePacked(C(address(0x1234))));\n    }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xe7490fade3a8e31113ecb6c0d2635e28a6f5ca8359a57afe914827f41ddf0848\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/keccak256_with_bytes.sol",
    "content": "contract c {\n    bytes data;\n\n    function foo() public returns (bool) {\n        data.push(\"f\");\n        data.push(\"o\");\n        data.push(\"o\");\n        return keccak256(data) == keccak256(\"foo\");\n    }\n}\n// ----\n// foo() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/msg_sig.sol",
    "content": "contract test {\n    function foo(uint256 a) public returns (bytes4 value) {\n        return msg.sig;\n    }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/msg_sig_after_internal_call_is_same.sol",
    "content": "contract test {\n    function boo() public returns (bytes4 value) {\n        return msg.sig;\n    }\n\n    function foo(uint256 a) public returns (bytes4 value) {\n        return boo();\n    }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/ripemd160.sol",
    "content": "contract C {\n    function f(int256 input) public returns (bytes32 sha256hash) {\n        return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n    }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/ripemd160_empty.sol",
    "content": "contract C {\n    function f() public returns (bytes20) {\n        return ripemd160(\"\");\n    }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/ripemd160_packed.sol",
    "content": "contract C {\n    function f(int256 _input) public returns (bytes32 hash) {\n        uint24 b = 65536;\n        uint c = 256;\n        bytes32 input = bytes32(uint256(_input));\n        return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n    }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/sha256.sol",
    "content": "contract C {\n    function f(int256 input) public returns (bytes32 sha256hash) {\n        return sha256(abi.encodePacked(bytes32(uint256(input))));\n    }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/sha256_empty.sol",
    "content": "contract C {\n    function f() public returns (bytes32) {\n        return sha256(\"\");\n    }\n}\n// ----\n// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n"
  },
  {
    "path": "test/libsolidity/semanticTests/builtinFunctions/sha256_packed.sol",
    "content": "contract C {\n    function f(int256 _input) public returns (bytes32 hash) {\n        uint24 b = 65536;\n        uint c = 256;\n        bytes32 input = bytes32(uint256(_input));\n        return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n    }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_array_access.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(uint256[] calldata x, uint256 i) external returns (uint256) {\n        return x[i];\n    }\n    function f(uint256[][] calldata x, uint256 i, uint256 j) external returns (uint256) {\n        return x[i][j];\n    }\n}\n// ----\n// f(uint256[],uint256): 0x40, 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[],uint256): 0x40, 0, 1, 23 -> 23\n// f(uint256[],uint256): 0x40, 1, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[],uint256): 0x40, 0, 2, 23, 42 -> 23\n// f(uint256[],uint256): 0x40, 1, 2, 23, 42 -> 42\n// f(uint256[],uint256): 0x40, 2, 2, 23, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][],uint256,uint256): 0x60, 0, 0 -> FAILURE\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 1, 0x20, 1, 23 -> 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_array_dynamic_bytes.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f1(bytes[1] calldata a)\n        external\n        returns (uint256, uint256, uint256, uint256)\n    {\n        return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n    }\n\n    function f2(bytes[1] calldata a, bytes[1] calldata b)\n        external\n        returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n    {\n        return (\n            a[0].length,\n            uint8(a[0][0]),\n            uint8(a[0][1]),\n            uint8(a[0][2]),\n            b[0].length,\n            uint8(b[0][0]),\n            uint8(b[0][1])\n        );\n    }\n\n    function g1(bytes[2] calldata a)\n        external\n        returns (\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256,\n            uint256\n        )\n    {\n        return (\n            a[0].length,\n            uint8(a[0][0]),\n            uint8(a[0][1]),\n            uint8(a[0][2]),\n            a[1].length,\n            uint8(a[1][0]),\n            uint8(a[1][1]),\n            uint8(a[1][2])\n        );\n    }\n\n    function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n        return [\n            a.length,\n            a[0].length,\n            uint8(a[0][0]),\n            uint8(a[0][1]),\n            a[1].length,\n            uint8(a[1][0]),\n            uint8(a[1][1]),\n            uint8(a[1][2])\n        ];\n    }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_array_index_range_access.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n        return uint256[](x[s:e]).length;\n    }\n    function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n        return uint256[](x[s:e][ss:ee]).length;\n    }\n    function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n        return uint256[](x[s:]).length;\n    }\n    function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n        return uint256[](x[:e]).length;\n    }\n    function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n        return uint256[](x[s:e])[idx];\n    }\n    function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n        return x[s:e][idx];\n    }\n    function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n        return x[s:][idx];\n    }\n    function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n        return x[:e][idx];\n    }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_array_length.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(uint256[] calldata x) external returns (uint256) {\n        return x.length;\n    }\n    function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n        l1 = x.length;\n        if (l1 > 0) l2 = x[0].length;\n        if (l1 > 1) l3 = x[1].length;\n    }\n    function f(uint256[2] calldata x) external returns (uint256) {\n        return x.length;\n    }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_array_three_dimensional.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n    }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_attached_to_bytes.sol",
    "content": "pragma abicoder v2;\n\nlibrary L {\n    function reverse(bytes calldata _b) internal pure returns (bytes1, bytes1) {\n        return (_b[1], _b[0]);\n    }\n}\n\ncontract C {\n    using L for bytes;\n\n    function test(uint, bytes calldata _b, uint) external pure returns (bytes1, bytes1) {\n        return _b.reverse();\n    }\n}\n// ----\n// test(uint256,bytes,uint256): 7, 0x60, 4, 2, \"ab\" -> \"b\", \"a\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_attached_to_dynamic_array_or_slice.sol",
    "content": "pragma abicoder v2;\n\nlibrary L {\n    function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n        return (_a[1], _a[0]);\n    }\n}\n\ncontract C {\n    using L for *;\n\n    function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n        return _a.reverse();\n    }\n\n    function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n        return _a[:].reverse();\n    }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_attached_to_static_array.sol",
    "content": "pragma abicoder v2;\n\nlibrary L {\n    function reverse(uint[2] calldata _a) internal pure returns (uint, uint) {\n        return (_a[1], _a[0]);\n    }\n}\n\ncontract C {\n    using L for uint[2];\n\n    function test(uint, uint[2] calldata _a, uint) external pure returns (uint, uint) {\n        return _a.reverse();\n    }\n}\n// ----\n// test(uint256,uint256[2],uint256): 7, 66, 77, 4 -> 77, 66\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_attached_to_struct.sol",
    "content": "pragma abicoder v2;\n\nstruct S {\n    uint x;\n    uint y;\n}\n\nlibrary L {\n    function reverse(S calldata _s) internal pure returns (uint, uint) {\n        return (_s.y, _s.x);\n    }\n}\n\ncontract C {\n    using L for S;\n\n    function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n        return _s.reverse();\n    }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_bytes_array_bounds.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(bytes[] calldata a, uint256 i) external returns (uint) {\n        return uint8(a[0][i]);\n    }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_bytes_external.sol",
    "content": "contract CalldataTest {\n    function test(bytes calldata x) public returns (bytes calldata) {\n        return x;\n    }\n    function tester(bytes calldata x) public returns (bytes1) {\n        return this.test(x)[2];\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// tester(bytes): 0x20, 0x08, \"abcdefgh\" -> \"c\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_bytes_internal.sol",
    "content": "contract C {\n    function f(bytes calldata b, uint i) internal pure returns (bytes1) {\n        return b[i];\n    }\n    function f(uint, bytes calldata b, uint) external pure returns (bytes1) {\n        return f(b, 2);\n    }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 7, 4, \"abcd\" -> \"c\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_bytes_to_memory.sol",
    "content": "contract C {\n  function f(bytes calldata data) external returns (bytes32) {\n    return keccak256(bytes(data));\n  }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_bytes_to_memory_encode.sol",
    "content": "contract C {\n  function f(bytes calldata data) external returns (bytes memory) {\n    return abi.encode(bytes(data));\n  }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_internal_function_pointer.sol",
    "content": "contract C {\n    function(bytes calldata) returns (bytes1) x;\n    constructor() { x = f; }\n    function f(bytes calldata b) internal pure returns (bytes1) {\n        return b[2];\n    }\n    function h(bytes calldata b) external returns (bytes1) {\n        return x(b);\n    }\n    function g() external returns (bytes1) {\n        bytes memory a = new bytes(34);\n        a[2] = bytes1(uint8(7));\n        return this.h(a);\n    }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_internal_library.sol",
    "content": "library L {\n    function f(uint, bytes calldata _x, uint) internal returns (bytes1) {\n        return _x[2];\n    }\n}\ncontract C {\n    function f(bytes calldata a)\n        external\n        returns (bytes1)\n    {\n        return L.f(3, a, 9);\n    }\n    function g() public returns (bytes1) {\n        bytes memory x = new bytes(4);\n        x[2] = 0x08;\n        return this.f(x);\n    }\n}\n// ----\n// g() -> 0x0800000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_internal_multi_array.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) {\n        return (s[0][1], s[1]);\n    }\n    function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) {\n        (uint x, uint[] calldata y) = g(s);\n        return (x, y[0]);\n    }\n    function g() public returns (uint, uint) {\n        uint[][2] memory x;\n        x[0] = new uint[](2);\n        x[1] = new uint[](2);\n        x[0][1] = 7;\n        x[1][0] = 8;\n        return this.f(4, x, 5);\n    }\n}\n// ----\n// g() -> 7, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_internal_multi_fixed_array.sol",
    "content": "contract C {\n    function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n        return (s[0][1], s[1]);\n    }\n    function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n        (uint x, uint[3] calldata y) = g(s);\n        return (x, y[0]);\n    }\n    function g() public returns (uint, uint) {\n        uint[3][2] memory x;\n        x[0][1] = 7;\n        x[1][0] = 8;\n        return this.f(4, x, 5);\n    }\n}\n// ----\n// g() -> 7, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_memory_mixed.sol",
    "content": "contract C {\n    function f(bytes memory _a, bytes calldata _b, bytes memory _c)\n        public\n        returns (uint, bytes1, bytes1, bytes1)\n    {\n        return (_a.length + _b.length + _c.length, _a[1], _b[1], _c[1]);\n    }\n    function g() public returns (uint, bytes1, bytes1, bytes1) {\n        bytes memory x = new bytes(3);\n        bytes memory y = new bytes(4);\n        bytes memory z = new bytes(7);\n        x[1] = 0x08;\n        y[1] = 0x09;\n        z[1] = 0x0a;\n        return this.f(x, y, z);\n    }\n}\n// ----\n// g() -> 0x0e, 0x0800000000000000000000000000000000000000000000000000000000000000, 0x0900000000000000000000000000000000000000000000000000000000000000, 0x0a00000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_string_array.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(string[] calldata a)\n        external\n        returns (uint256, uint256, uint256, string memory)\n    {\n        string memory s1 = a[0];\n        bytes memory m1 = bytes(s1);\n        return (a.length, m1.length, uint8(m1[0]), s1);\n    }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_struct.sol",
    "content": "pragma abicoder v2;\n\nstruct S {\n    uint x;\n    uint y;\n}\n\nlibrary L {\n    function reverse(S calldata _s) internal pure returns (uint, uint) {\n        return (_s.y, _s.x);\n    }\n}\n\ncontract C {\n    function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n        return L.reverse(_s);\n    }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_struct_cleaning.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    struct S {\n        uint8 a;\n        bytes1 b;\n    }\n\n    function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n        uint8 tmp1 = s.a;\n        bytes1 tmp2 = s.b;\n        assembly {\n            a := tmp1\n            b := tmp2\n        }\n    }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/calldata_struct_internal.sol",
    "content": "pragma abicoder               v2;\n\nstruct S {\n    uint x;\n    uint y;\n}\n\ncontract C {\n    function f(S calldata s) internal pure returns (uint, uint) {\n        return (s.x, s.y);\n    }\n    function f(uint, S calldata s, uint) external pure returns (uint, uint) {\n        return f(s);\n    }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/calldata/copy_from_calldata_removes_bytes_data.sol",
    "content": "contract c {\n    function set() public returns (bool) { data = msg.data; return true; }\n    function checkIfDataIsEmpty() public returns (bool) { return data.length == 0; }\n    function sendMessage() public returns (bool, bytes memory) { bytes memory emptyData; return address(this).call(emptyData);}\n    fallback() external { data = msg.data; }\n    bytes data;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// (): 1, 2, 3, 4, 5 ->\n// gas irOptimized: 155122\n// gas legacy: 155473\n// gas legacyOptimized: 155296\n// checkIfDataIsEmpty() -> false\n// sendMessage() -> true, 0x40, 0\n// gas irOptimized: 41925\n// checkIfDataIsEmpty() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/bool_conversion_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f(bool _b) public returns (uint256) {\n        if (_b) return 1;\n        else return 0;\n    }\n\n    function g(bool _in) public returns (bool _out) {\n        _out = _in;\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/bool_conversion_v2.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(bool _b) public returns (uint256) {\n        if (_b) return 1;\n        else return 0;\n    }\n\n    function g(bool _in) public returns (bool _out) {\n        _out = _in;\n    }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/byte_array_to_storage_cleanup.sol",
    "content": "contract C {\n    event ev(uint[], uint);\n    bytes public s;\n    function h() external returns (bytes memory) {\n        uint[] memory x = new uint[](2);\n        emit ev(x, 0x21);\n        bytes memory m = new bytes(63);\n        s = m;\n        s.push();\n        return s;\n    }\n    function g() external returns (bytes memory) {\n        bytes memory m = new bytes(63);\n        assembly {\n            mstore8(add(m, add(32, 63)), 0x42)\n        }\n        s = m;\n        s.push();\n        return s;\n    }\n    function f(bytes calldata c) external returns (bytes memory) {\n        s = c;\n        s.push();\n        return s;\n    }\n}\n// ====\n// compileViaYul: also\n// ----\n// constructor() ->\n// gas irOptimized: 82586\n// gas irOptimized code: 363600\n// gas legacy: 101811\n// gas legacy code: 608200\n// gas legacyOptimized: 85196\n// gas legacyOptimized code: 394800\n// h() -> 0x20, 0x40, 0x00, 0\n// ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00\n// g() -> 0x20, 0x40, 0, 0x00\n// f(bytes): 0x20, 33, 0, -1 -> 0x20, 0x22, 0, 0xff00000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 54117\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/cleanup_address_types_shortening.sol",
    "content": "contract C {\n    function f() public pure returns (address r) {\n        bytes21 x = 0x1122334455667788990011223344556677889900ff;\n        bytes20 y;\n        assembly {\n            y := x\n        }\n        address z = address(y);\n        assembly {\n            r := z\n        }\n        require(z == 0x1122334455667788990011223344556677889900);\n    }\n\n    function g() public pure returns (address payable r) {\n        bytes21 x = 0x1122334455667788990011223344556677889900ff;\n        bytes20 y;\n        assembly {\n            y := x\n        }\n        address payable z = payable(address(y));\n        assembly {\n            r := z\n        }\n        require(z == 0x1122334455667788990011223344556677889900);\n    }\n}\n// ----\n// f() -> 0x1122334455667788990011223344556677889900\n// g() -> 0x1122334455667788990011223344556677889900\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/cleanup_address_types_v1.sol",
    "content": "pragma abicoder v1;\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n    function f(address a) public returns (uint256) {\n        if (a != 0x1234567890123456789012345678901234567890) return 1;\n        return 0;\n    }\n\n    function g(address payable a) public returns (uint256) {\n        if (a != 0x1234567890123456789012345678901234567890) return 1;\n        return 0;\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/cleanup_address_types_v2.sol",
    "content": "pragma abicoder               v2;\n\n\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n    function f(address a) public returns (uint256) {\n        if (a != 0x1234567890123456789012345678901234567890) return 1;\n        return 0;\n    }\n\n    function g(address payable a) public returns (uint256) {\n        if (a != 0x1234567890123456789012345678901234567890) return 1;\n        return 0;\n    }\n}\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening_OldCodeGen.sol",
    "content": "contract C {\n    function f() public pure returns (bytes32 r) {\n        bytes4 x = 0xffffffff;\n        bytes2 y = bytes2(x);\n        assembly {\n            r := y\n        }\n        // At this point, r and y both store four bytes, but\n        // y is properly cleaned before the equality check\n        require(y == bytes2(0xffff));\n    }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0xffffffff00000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening_newCodeGen.sol",
    "content": "contract C {\n    function f() public pure returns (bytes32 r) {\n        bytes4 x = 0xffffffff;\n        bytes2 y = bytes2(x);\n        assembly {\n            r := y\n        }\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0xffff000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_v1.sol",
    "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n    function f(bytes2 a, uint16 x) public returns (uint256) {\n        if (a != \"ab\") return 1;\n        if (x != 0x0102) return 2;\n        if (bytes3(uint24(x)) != 0x000102) return 3;\n        return 0;\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_v2.sol",
    "content": "pragma abicoder               v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n    function f(bytes2 a, uint16 x) public returns (uint256) {\n        if (a != \"ab\") return 1;\n        if (x != 0x0102) return 2;\n        if (bytes3(uint24(x)) != 0x000102) return 3;\n        return 0;\n    }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/cleanup_in_compound_assign.sol",
    "content": "contract C {\n    function test() public returns (uint256, uint256) {\n        uint32 a = 0xffffffff;\n        uint16 x = uint16(a);\n        uint16 y = x;\n        x /= 0x100;\n        y = y / 0x100;\n        return (x, y);\n    }\n}\n// ----\n// test() -> 0xff, 0xff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/dirty_calldata_bytes.sol",
    "content": "contract C {\n    function f(bytes calldata b) public returns (bool correct) {\n        bytes1 a = b[3];\n        uint r;\n        assembly {\n            r := a\n        }\n        correct = r == (0x64 << 248);\n    }\n}\n// ----\n// f(bytes): 0x20, 0x04, \"dead\" -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/dirty_calldata_dynamic_array.sol",
    "content": "contract C {\n    function f(int16[] calldata a) external returns (bool correct) {\n        uint32 x = uint32(uint16(a[1]));\n        uint r;\n        assembly {\n            r := x\n        }\n        correct = r == 0x7fff;\n    }\n}\n// ----\n// f(int16[]): 0x20, 0x02, 0x7fff, 0x7fff -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/exp_cleanup.sol",
    "content": "contract C {\n    function f() public pure returns (uint x) {\n        unchecked {\n            uint8 y = uint8(2)**uint8(8);\n            return 0**y;\n        }\n    }\n}\n// ----\n// f() -> 0x1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/exp_cleanup_direct.sol",
    "content": "contract C {\n    function f() public pure returns (uint8 x) {\n        unchecked {\n            return uint8(0)**uint8(uint8(2)**uint8(8));\n        }\n    }\n}\n// ----\n// f() -> 0x1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/exp_cleanup_nonzero_base.sol",
    "content": "contract C {\n    function f() public pure returns (uint8 x) {\n        unchecked {\n\t\t\tuint16 x = 0x166;\n            return uint8(x)**uint8(uint8(2)**uint8(8));\n        }\n    }\n}\n// ----\n// f() -> 0x1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/exp_cleanup_smaller_base.sol",
    "content": "contract C {\n    function f() public pure returns (uint16 x) {\n        // tests that ``e`` is not converted to uint8\n        // right before the exp\n        uint16 e = 0x100;\n        uint8 b = 0x2;\n        unchecked {\n            return b**e;\n        }\n    }\n}\n// ----\n// f() -> 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast.sol",
    "content": "contract C {\n    function f() public pure returns (uint32 y) {\n        uint8 x = uint8(uint256(0x31313131313131313131313131313131));\n        assembly { y := x }\n    }\n\n    function g() public pure returns (bytes32 y) {\n        bytes1 x = bytes1(bytes16(0x31313131313131313131313131313131));\n        assembly { y := x }\n    }\n\n    function h() external returns (bytes32 y) {\n        bytes1 x;\n        assembly { x := sub(0,1) }\n        y = x;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x31\n// g() -> 0x3100000000000000000000000000000000000000000000000000000000000000\n// h() -> 0xff00000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/cleanup/indexed_log_topic_during_explicit_downcast_during_emissions.sol",
    "content": "contract C {\n    event ev0(bytes1 indexed);\n    constructor() {\n        emit ev0(bytes1(bytes16(0x31313131313131313131313131313131)));\n    }\n    function j() external {\n        bytes1 x;\n        assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 }\n        emit ev0(x);\n    }\n}\n// ----\n// constructor() ->\n// ~ emit ev0(bytes1): #\"1\"\n// gas legacy: 58919\n// gas legacy code: 33600\n// j() ->\n// ~ emit ev0(bytes1): #\"1\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constantEvaluator/negative_fractional_mod.sol",
    "content": "contract C {\n    function f() public pure returns (int, int) {\n        int x = int((-(-5.2 % 3)) * 5);\n        int t = 5;\n        return (x, (-(-t % 3)) * 5);\n    }\n}\n// ----\n// f() -> 11, 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constantEvaluator/rounding.sol",
    "content": "contract C {\n    int constant a = 7;\n    int constant b = 3;\n    int constant c = a / b;\n    int constant d = (-a) / b;\n    function f() public pure returns (uint, int, uint, int) {\n        uint[c] memory x;\n        uint[-d] memory y;\n        return (x.length, c, y.length, -d);\n    }\n}\n// ----\n// f() -> 2, 2, 2, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constants/asm_address_constant_regression.sol",
    "content": "// Test for regression of https://github.com/argotorg/solidity/issues/8406\n\ncontract C {\n  address constant e = 0x1212121212121212121212121000002134593163;\n\n  function f() public returns (bytes1 z) {\n    assembly { z := e }\n  }\n}\n// ----\n// f() -> 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constants/asm_constant_file_level.sol",
    "content": "address constant e = 0x1212121212121212121212121000002134593163;\n\ncontract C {\n  function f() public returns (address z) {\n    assembly { z := e }\n  }\n}\n// ----\n// f() -> 0x1212121212121212121212121000002134593163\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constants/assign_type_info.sol",
    "content": "contract A {\n}\n\ncontract B {\n    bytes constant creationCode = type(A).creationCode;\n    bytes constant runtimeCode = type(A).runtimeCode;\n\n    function nonEmptyCode() public pure returns (bool) {\n        return creationCode.length > 0 && runtimeCode.length > 0;\n    }\n}\n// ----\n// nonEmptyCode() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constants/constant_string.sol",
    "content": "contract C {\n    bytes constant a = \"\\x03\\x01\\x02\";\n    bytes constant b = hex\"030102\";\n    string constant c = \"hello\";\n\n    function f() public returns (bytes memory) {\n        return a;\n    }\n\n    function g() public returns (bytes memory) {\n        return b;\n    }\n\n    function h() public returns (bytes memory) {\n        return bytes(c);\n    }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constants/constant_string_at_file_level.sol",
    "content": "bytes constant a = \"\\x03\\x01\\x02\";\nbytes constant b = hex\"030102\";\nstring constant c = \"hello\";\nuint256 constant x = 56;\nenum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\nActionChoices constant choices = ActionChoices.GoRight;\nbytes32 constant st = \"abc\\x00\\xff__\";\n\ncontract C {\n    function f() public returns (bytes memory) {\n        return a;\n    }\n\n    function g() public returns (bytes memory) {\n        return b;\n    }\n\n    function h() public returns (bytes memory) {\n        return bytes(c);\n    }\n\n    function i() public returns (uint, ActionChoices, bytes32) {\n        return (x, choices, st);\n    }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n// i() -> 0x38, 1, 0x61626300ff5f5f00000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constants/constant_variables.sol",
    "content": "contract Foo {\n    uint256 constant x = 56;\n    enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n    ActionChoices constant choices = ActionChoices.GoLeft;\n    bytes32 constant st = \"abc\\x00\\xff__\";\n}\n// ----\n// constructor() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constants/constants_at_file_level_referencing.sol",
    "content": "==== Source: s1.sol ====\n\n\nbytes constant a = b;\nbytes constant b = hex\"030102\";\n\nfunction fre() pure returns (bytes memory) {\n    return a;\n}\n\n==== Source: s2.sol ====\n\nimport \"s1.sol\";\n\nuint256 constant c = uint8(a[0]) + 2;\n\ncontract C {\n    function f() public returns (bytes memory) {\n        return a;\n    }\n\n    function g() public returns (bytes memory) {\n        return b;\n    }\n\n    function h() public returns (uint) {\n        return c;\n    }\n\n    function i() public returns (bytes memory) {\n        return fre();\n    }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 5\n// i() -> 0x20, 3, \"\\x03\\x01\\x02\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constants/consteval_array_length.sol",
    "content": "contract C {\n    uint constant a = 12;\n    uint constant b = 10;\n\n    function f() public pure returns (uint, uint) {\n        uint[(a / b) * b] memory x;\n        return (x.length, (a / b) * b);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// f() -> 0x0a, 0x0a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constants/function_unreferenced.sol",
    "content": "contract B {\n    function g() public {}\n}\ncontract C is B {\n    bytes4 constant s2 = B.g.selector;\n    function f() external pure returns (bytes4) { return s2; }\n}\n// ----\n// f() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constants/same_constants_different_files.sol",
    "content": "==== Source: s1.sol ====\n\n\nuint constant a = 89;\n\nfunction fre() pure returns (uint) {\n    return a;\n}\n\n==== Source: s2.sol ====\n\nimport {a as b, fre} from \"s1.sol\";\nimport \"s1.sol\" as M;\n\nuint256 constant a = 13;\n\ncontract C {\n    function f() public returns (uint, uint, uint, uint) {\n        return (a, fre(), M.a, b);\n    }\n}\n// ----\n// f() -> 0x0d, 0x59, 0x59, 0x59\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constants/simple_constant_variables_test.sol",
    "content": "contract Foo {\n    function getX() public returns (uint256 r) {\n        return x;\n    }\n\n    uint256 constant x = 56;\n}\n// ----\n// getX() -> 56\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol",
    "content": "contract Base {\n    uint public m_x;\n    address[] m_s;\n    constructor(uint x, address[] memory s) {\n        m_x = x;\n        m_s = s;\n    }\n    function part(uint i) public returns (address) {\n        return m_s[i];\n    }\n}\ncontract Main is Base {\n    constructor(address[] memory s, uint x) Base(x, f(s)) {}\n    function f(address[] memory s) public returns (address[] memory) {\n        return s;\n    }\n}\ncontract Creator {\n    function f(uint x, address[] memory s) public returns (uint r, address ch) {\n        Main c = new Main(s, x);\n        r = c.m_x();\n        ch = c.part(x);\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 338477\n// gas legacy code: 244800\n// gas legacyOptimized: 329166\n// gas legacyOptimized code: 117000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/base_constructor_arguments.sol",
    "content": "contract BaseBase {\n    uint256 m_a;\n\n    constructor(uint256 a) {\n        m_a = a;\n    }\n}\n\n\ncontract Base is BaseBase(7) {\n    constructor() {\n        m_a *= m_a;\n    }\n}\n\n\ncontract Derived is Base {\n    function getA() public returns (uint256 r) {\n        return m_a;\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// getA() -> 49\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol",
    "content": "contract Base {\n    uint public m_x;\n    bytes m_s;\n    constructor(uint x, bytes memory s) {\n        m_x = x;\n        m_s = s;\n    }\n    function part(uint i) public returns (bytes1) {\n        return m_s[i];\n    }\n}\ncontract Main is Base {\n    constructor(bytes memory s, uint x) Base(x, f(s)) {}\n    function f(bytes memory s) public returns (bytes memory) {\n        return s;\n    }\n}\ncontract Creator {\n    function f(uint x, bytes memory s) public returns (uint r, bytes1 ch) {\n        Main c = new Main(s, x);\n        r = c.m_x();\n        ch = c.part(x);\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// f(uint256,bytes): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> 7, \"h\"\n// gas irOptimized: 169297\n// gas irOptimized code: 99600\n// gas legacy: 172946\n// gas legacy code: 239800\n// gas legacyOptimized: 169823\n// gas legacyOptimized code: 118600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/bytes_in_constructors_unpacker.sol",
    "content": "contract Test {\n    uint public m_x;\n    bytes public m_s;\n    constructor(uint x, bytes memory s) {\n        m_x = x;\n        m_s = s;\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// constructor(): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" ->\n// gas irOptimized: 181629\n// gas irOptimized code: 78400\n// gas legacy: 195484\n// gas legacy code: 109400\n// gas legacyOptimized: 181853\n// gas legacyOptimized code: 71400\n// m_x() -> 7\n// m_s() -> 0x20, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/callvalue_check.sol",
    "content": "contract A1 { constructor() {} }\ncontract B1 is A1 {}\n\ncontract A2 { constructor() payable {} }\ncontract B2 is A2 {}\n\ncontract B3 {}\n\ncontract B4 { constructor() {} }\n\ncontract C {\n\tfunction createWithValue(bytes memory c, uint256 value) public payable returns (bool) {\n\t\tuint256 y = 0;\n\t\t// TODO: This test is hard to recreate for EOF as for now eofcreate is disallowed in inline assembly.\n\t\tassembly { y := create(value, add(c, 0x20), mload(c)) }\n\t\treturn y != 0;\n\t}\n\tfunction f(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B1).creationCode, value);\n\t}\n\tfunction g(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B2).creationCode, value);\n\t}\n\tfunction h(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B3).creationCode, value);\n\t}\n\tfunction i(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B4).creationCode, value);\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// bytecodeFormat: legacy\n// ----\n// f(uint256), 2000 ether: 0 -> true\n// f(uint256), 2000 ether: 100 -> false\n// g(uint256), 2000 ether: 0 -> true\n// g(uint256), 2000 ether: 100 -> false\n// h(uint256), 2000 ether: 0 -> true\n// h(uint256), 2000 ether: 100 -> false\n// i(uint256), 2000 ether: 0 -> true\n// i(uint256), 2000 ether: 100 -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/constructor_arguments_external.sol",
    "content": "contract Main {\n    bytes3 name;\n    bool flag;\n\n    constructor(bytes3 x, bool f) {\n        name = x;\n        flag = f;\n    }\n\n    function getName() public returns (bytes3 ret) {\n        return name;\n    }\n\n    function getFlag() public returns (bool ret) {\n        return flag;\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/constructor_arguments_internal.sol",
    "content": "contract Helper {\n    bytes3 name;\n    bool flag;\n\n    constructor(bytes3 x, bool f) {\n        name = x;\n        flag = f;\n    }\n\n    function getName() public returns (bytes3 ret) {\n        return name;\n    }\n\n    function getFlag() public returns (bool ret) {\n        return flag;\n    }\n}\n\n\ncontract Main {\n    Helper h;\n\n    constructor() {\n        h = new Helper(\"abc\", true);\n    }\n\n    function getFlag() public returns (bool ret) {\n        return h.getFlag();\n    }\n\n    function getName() public returns (bytes3 ret) {\n        return h.getName();\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/constructor_function_argument.sol",
    "content": "// The IR of this test used to throw\ncontract D {\n    constructor(function() external returns (uint)) {\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// constructor(): 0xfdd67305928fcac8d213d1e47bfa6165cd0b87b946644cd0000000000000000 ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/constructor_function_complex.sol",
    "content": "contract D {\n    uint public x;\n    constructor(function() external pure returns (uint) g) {\n        x = g();\n    }\n}\n\ncontract C {\n    function f() public returns (uint r) {\n        D d = new D(this.sixteen);\n        r = d.x();\n    }\n\n    function sixteen() public pure returns (uint) {\n        return 16;\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/constructor_static_array_argument.sol",
    "content": "contract C {\n    uint256 public a;\n    uint256[3] public b;\n\n    constructor(uint256 _a, uint256[3] memory _b) {\n        a = _a;\n        b = _b;\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 166201\n// gas legacy code: 60400\n// gas legacyOptimized: 149177\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/evm_exceptions_in_constructor_call_fail.sol",
    "content": "contract A {\n    constructor() {\n        address(this).call(\"123\");\n    }\n}\n\n\ncontract B {\n    uint256 public test = 1;\n\n    function testIt() public {\n        A a = new A();\n        ++test;\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// testIt() ->\n// test() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/function_usage_in_constructor_arguments.sol",
    "content": "contract BaseBase {\n    uint256 m_a;\n\n    constructor(uint256 a) {\n        m_a = a;\n    }\n\n    function g() public returns (uint256 r) {\n        return 2;\n    }\n}\n\n\ncontract Base is BaseBase(BaseBase.g()) {}\n\n\ncontract Derived is Base {\n    function getA() public returns (uint256 r) {\n        return m_a;\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// getA() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/functions_called_by_constructor.sol",
    "content": "contract Test {\n    bytes3 name;\n    bool flag;\n\n    constructor() {\n        setName(\"abc\");\n    }\n\n    function getName() public returns (bytes3 ret) {\n        return name;\n    }\n\n    function setName(bytes3 _name) private {\n        name = _name;\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// getName() -> \"abc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/functions_called_by_constructor_through_dispatch.sol",
    "content": "contract Test {\n    bytes6 name;\n\n    constructor() {\n        function (bytes6 _name) internal setter = setName;\n        setter(\"abcdef\");\n\n        applyShift(leftByteShift, 3);\n    }\n\n    function getName() public returns (bytes6 ret) {\n        return name;\n    }\n\n    function setName(bytes6 _name) private {\n        name = _name;\n    }\n\n    function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n        return _value << _shift * 8;\n    }\n\n    function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n        name = _shiftOperator(name, _bytes);\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/inline_member_init_inheritence_without_constructor.sol",
    "content": "contract Base {\n    uint256 m_base = 5;\n\n    function getBMember() public returns (uint256 i) {\n        return m_base;\n    }\n}\n\n\ncontract Derived is Base {\n    uint256 m_derived = 6;\n\n    function getDMember() public returns (uint256 i) {\n        return m_derived;\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/no_callvalue_check.sol",
    "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10, salt: hex\"00\"}();\n\t\tnew B2{value: 10, salt: hex\"01\"}();\n\t\tnew B3{value: 10, salt: hex\"02\"}();\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117688\n// gas irOptimized code: 1800\n// gas legacy: 117889\n// gas legacy code: 4800\n// gas legacyOptimized: 117761\n// gas legacyOptimized code: 4800\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/order_of_evaluation.sol",
    "content": "contract A {\n    constructor(uint) {}\n}\ncontract B {\n    constructor(uint) {}\n}\ncontract C {\n    constructor(uint) {}\n}\ncontract D {\n    constructor(uint) {}\n}\ncontract X is D, C, B, A {\n    uint[] x;\n    function f(uint _x) internal returns (uint) {\n        x.push(_x);\n    }\n    function g() public view returns (uint[] memory) { return x; }\n    constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/payable_constructor.sol",
    "content": "contract C {\n    constructor() payable {}\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// constructor(), 27 wei ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/state_variable_initialization.sol",
    "content": "contract C {\n    uint public i = 1;\n    uint public k = 2;\n\n    constructor() {\n        i = i + i;\n        k = k - i;\n    }\n}\n// ----\n// i() -> 2\n// k() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/store_function_in_constructor.sol",
    "content": "contract C {\n    uint256 public result_in_constructor;\n    function(uint256) returns (uint256) internal x;\n\n    constructor() {\n        x = double;\n        result_in_constructor = use(2);\n    }\n\n    function double(uint256 _arg) public returns (uint256 _ret) {\n        _ret = _arg * 2;\n    }\n\n    function use(uint256 _arg) public returns (uint256) {\n        return x(_arg);\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/store_function_in_constructor_packed.sol",
    "content": "contract C {\n    uint16 public result_in_constructor;\n    function(uint16) returns (uint16) internal x;\n    uint16 public other = 0x1fff;\n\n    constructor() {\n        x = doubleInv;\n        result_in_constructor = use(2);\n    }\n\n    function doubleInv(uint16 _arg) public returns (uint16 _ret) {\n        _ret = ~(_arg * 2);\n    }\n\n    function use(uint16 _arg) public returns (uint16) {\n        return x(_arg);\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// use(uint16): 3 -> 0xfff9\n// result_in_constructor() -> 0xfffb\n// other() -> 0x1fff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/store_internal_unused_function_in_constructor.sol",
    "content": "contract C {\n    function() returns (uint256) internal x;\n\n    constructor() {\n        x = unused;\n    }\n\n    function unused() internal returns (uint256) {\n        return 7;\n    }\n\n    function t() public returns (uint256) {\n        return x();\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// t() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/store_internal_unused_library_function_in_constructor.sol",
    "content": "library L {\n    function x() internal returns (uint256) {\n        return 7;\n    }\n}\n\n\ncontract C {\n    function() returns (uint256) internal x;\n\n    constructor() {\n        x = L.x;\n    }\n\n    function t() public returns (uint256) {\n        return x();\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// t() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/constructor/transient_state_variable_initialization.sol",
    "content": "contract C {\n    uint128 transient x;\n    uint128 y;\n\n    constructor() {\n        x = 100;\n        y = x;\n    }\n\n    function f() external view returns (uint128) {\n        return y;\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// f() -> 100\n"
  },
  {
    "path": "test/libsolidity/semanticTests/conversions/function_type_array_to_storage.sol",
    "content": "contract C {\n    function () external returns(uint)[1] externalDefaultArray;\n    function () external view returns(uint)[1] externalViewArray;\n    function () external pure returns(uint)[1] externalPureArray;\n\n    function () internal returns(uint)[1] internalDefaultArray;\n    function () internal view returns(uint)[1] internalViewArray;\n    function () internal pure returns(uint)[1] internalPureArray;\n\n    function externalDefault() external returns(uint) { return 11; }\n    function externalView() external view returns(uint) { return 12; }\n    function externalPure() external pure returns(uint) { return 13; }\n\n    function internalDefault() internal returns(uint) { return 21; }\n    function internalView() internal view returns(uint) { return 22; }\n    function internalPure() internal pure returns(uint) { return 23; }\n\n    function testViewToDefault() public returns (uint, uint) {\n        externalDefaultArray = [this.externalView];\n        internalDefaultArray = [internalView];\n\n        return (externalDefaultArray[0](), internalDefaultArray[0]());\n    }\n\n    function testPureToDefault() public returns (uint, uint) {\n        externalDefaultArray = [this.externalPure];\n        internalDefaultArray = [internalPure];\n\n        return (externalDefaultArray[0](), internalDefaultArray[0]());\n    }\n\n    function testPureToView() public returns (uint, uint) {\n        externalViewArray = [this.externalPure];\n        internalViewArray = [internalPure];\n\n        return (externalViewArray[0](), internalViewArray[0]());\n    }\n}\n// ----\n// testViewToDefault() -> 12, 22\n// testPureToDefault() -> 13, 23\n// testPureToView() -> 13, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/conversions/string_to_bytes.sol",
    "content": "contract C {\n\tfunction f(string memory s) public pure returns (bytes memory t) {\n\t\tt = bytes(s);\n\t}\n}\n// ----\n// f(string): 32, 5, \"Hello\" -> 32, 5, \"Hello\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/bound_function.sol",
    "content": "// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too.\nfunction longdata(S memory) pure returns (bytes memory) {\n    return\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n        \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n}\n\nstruct S {\n    uint x;\n}\n\nusing { longdata } for S;\n\ncontract C {\n    bytes data;\n    constructor() {\n        S memory x;\n        data = x.longdata();\n    }\n    function test() public view returns (bool) {\n        // Tests that the function longdata is not\n        // included in the runtime code.\n        uint x;\n        assembly {\n            x := codesize()\n        }\n        return x < data.length;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/library_function.sol",
    "content": "// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too.\nlibrary L {\n    function longdata() pure internal returns (bytes memory) {\n        return\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n            \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n    }\n}\ncontract C {\n    bytes data;\n    constructor() {\n        data = L.longdata();\n    }\n    function test() public view returns (bool) {\n        // Tests that the function L.longdata is not\n        // included in the runtime code.\n        uint x;\n        assembly {\n            x := codesize()\n        }\n        return x < data.length;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/library_function_deployed.sol",
    "content": "library L {\n    function longdata() pure internal returns (bytes memory) {\n        return\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n            \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n    }\n}\n\ncontract C {\n    bytes data;\n    function () pure returns (bytes memory) f;\n    constructor() {\n        data = L.longdata();\n        f = L.longdata;\n    }\n    function test() public view returns (bool) {\n        return keccak256(data) == keccak256(f());\n    }\n}\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/module_function.sol",
    "content": "// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too.\n==== Source: mod.sol ====\nfunction longdata() pure returns (bytes memory) {\n    return\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n        \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n}\n==== Source: main.sol ====\nimport \"mod.sol\" as M;\n\ncontract C {\n    bytes data;\n    constructor() {\n        data = M.longdata();\n    }\n    function test() public view returns (bool) {\n        // Tests that the function longdata is not\n        // included in the runtime code.\n        uint x;\n        assembly {\n            x := codesize()\n        }\n        return x < data.length;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/module_function_deployed.sol",
    "content": "==== Source: mod.sol ====\nfunction longdata() pure returns (bytes memory) {\n    return\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n        \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n}\n==== Source: main.sol ====\nimport \"mod.sol\" as M;\n\ncontract C {\n    bytes data;\n    function () pure returns (bytes memory) f;\n    constructor() {\n        data = M.longdata();\n        f = M.longdata;\n    }\n    function test() public view returns (bool) {\n        return keccak256(data) == keccak256(f());\n    }\n}\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/static_base_function.sol",
    "content": "// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too.\nabstract contract S {\n    function longdata() internal pure returns (bytes memory) {\n        return\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n            \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n    }\n}\n\ncontract C is S {\n    bytes data;\n    constructor() {\n        data = S.longdata();\n    }\n    function test() public view returns (bool) {\n        // Tests that the function longdata is not\n        // included in the runtime code.\n        uint x;\n        assembly {\n            x := codesize()\n        }\n        return x < data.length;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/static_base_function_deployed.sol",
    "content": "abstract contract S {\n    function longdata() internal pure returns (bytes memory) {\n        return\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n            \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n    }\n}\n\ncontract C is S {\n    bytes data;\n    function () pure returns (bytes memory) f;\n    constructor() {\n        data = S.longdata();\n        f = S.longdata;\n    }\n    function test() public view returns (bool) {\n        return keccak256(data) == keccak256(f());\n    }\n}\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/subassembly_deduplication.sol",
    "content": "// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too.\ncontract A {\n    function longdata() pure external returns (bytes memory) {\n        return\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n        \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n        \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n        \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n        \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n        \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n    }\n}\n\ncontract C {\n    constructor() {\n    }\n\n    function a() external returns (bytes memory) {\n        return type(A).creationCode;\n    }\n\n    function b() external returns (A) {\n        return new A();\n    }\n\n    function test() public view returns (bool) {\n        uint x;\n        assembly {\n            x := codesize()\n        }\n        return type(A).creationCode.length < x &&\n            x < 2 * type(A).creationCode.length;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/super_function.sol",
    "content": "// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too.\nabstract contract S {\n    function longdata() internal pure returns (bytes memory) {\n        return\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n            \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n    }\n}\n\ncontract C is S {\n    bytes data;\n    constructor() {\n        data = super.longdata();\n    }\n    function test() public view returns (bool) {\n        // Tests that the function longdata is not\n        // included in the runtime code.\n        uint x;\n        assembly {\n            x := codesize()\n        }\n        return x < data.length;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/super_function_deployed.sol",
    "content": "abstract contract S {\n    function longdata() internal pure returns (bytes memory) {\n        return\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n            \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n    }\n}\n\ncontract C is S {\n    bytes data;\n    function () pure returns (bytes memory) f;\n    constructor() {\n        data = super.longdata();\n        f = super.longdata;\n    }\n    function test() public view returns (bool) {\n        return keccak256(data) == keccak256(f());\n    }\n}\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/virtual_function.sol",
    "content": "// TODO: Recreate this test for EOF when subassembly deduplication will be supported for EOF too.\nabstract contract S {\n    function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n    function longdata() internal override pure returns (bytes memory) {\n        return\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n            \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n        }\n}\n\ncontract C is X {\n    bytes data;\n    constructor() {\n        data = longdata();\n    }\n    function test() public view returns (bool) {\n        // Tests that the function longdata is not\n        // included in the runtime code.\n        uint x;\n        assembly {\n            x := codesize()\n        }\n        return x < data.length;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/deployedCodeExclusion/virtual_function_deployed.sol",
    "content": "abstract contract S {\n    function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n    function longdata() internal override pure returns (bytes memory) {\n        return\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \" .RPOKIDAS,.CKUMT.,ORKAD ,NOKIDHA .CGKIAD OVHAMS CUAOGT DAKN OIT\"\n            \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n            \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n            \"AJMO<KXBANJCPGUD ABKCJIDHA NKIMAJU,EKAMHSO;PYCAKUM,L.UCA MR;KITA\"\n            \"apibakrpidbacnidkacjadtnpdkylca.,jda,r.kuadc,jdlkjd',c'dj, ncg d\"\n            \"anosumantkudkc,djntudkantuadnc,ui,c.ud,.nujdncud,j.rsch'pkl.'pih\";\n        }\n}\n\ncontract C is X {\n    bytes data;\n    function () pure returns (bytes memory) f;\n    constructor() {\n        data = super.longdata();\n        f = super.longdata;\n    }\n    function test() public view returns (bool) {\n        return keccak256(data) == keccak256(f());\n    }\n}\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/ecrecover/ecrecover.sol",
    "content": "contract test {\n    function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) {\n        return ecrecover(h, v, r, s);\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// a(bytes32,uint8,bytes32,bytes32):\n// 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c,\n// 28,\n// 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f,\n// 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549\n// -> 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\n"
  },
  {
    "path": "test/libsolidity/semanticTests/ecrecover/ecrecover_abiV2.sol",
    "content": "pragma abicoder               v2;\ncontract test {\n    function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) {\n        return ecrecover(h, v, r, s);\n    }\n}\n// ----\n// a(bytes32,uint8,bytes32,bytes32):\n// 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c,\n// 28,\n// 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f,\n// 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549\n// -> 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\n"
  },
  {
    "path": "test/libsolidity/semanticTests/ecrecover/failing_ecrecover_invalid_input.sol",
    "content": "contract C {\n    // ecrecover should return zero for malformed input\n    // (v should be 27 or 28, not 1)\n    // Note that the precompile does not return zero but returns nothing.\n    function f() public returns (address) {\n        return ecrecover(bytes32(type(uint256).max), 1, bytes32(uint(2)), bytes32(uint(3)));\n    }\n}\n// ----\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/ecrecover/failing_ecrecover_invalid_input_asm.sol",
    "content": "contract C {\n    function f() public returns (address) {\n        assembly {\n            mstore(mload(0x40), 0xca35b7d915458ef540ade6068dfe2f44e8fa733c)\n        }\n        return ecrecover(\n            0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca,\n            0, // invalid v value\n            0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4,\n            0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d\n        );\n    }\n}\n// ----\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/ecrecover/failing_ecrecover_invalid_input_proper.sol",
    "content": "contract C {\n    function f() public returns (address) {\n        return recover(\n            0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca,\n            0, // invalid v value\n            0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4,\n            0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d,\n            0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c,\n            0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c\n        );\n    }\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s, uint blockExpired, bytes32 salt)\n        public returns (address)\n    {\n        require(hash == keccak256(abi.encodePacked(blockExpired, salt)));\n        return ecrecover(hash, v, r, s);\n    }\n}\n// ----\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/enums/constructing_enums_from_ints.sol",
    "content": "contract c {\n    enum Truth {False, True}\n\n    function test() public returns (uint256) {\n        return uint256(Truth(uint8(0x1)));\n    }\n}\n// ----\n// test() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/enums/enum_explicit_overflow.sol",
    "content": "contract test {\n    enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n    constructor() {}\n\n    function getChoiceExp(uint256 x) public returns (uint256 d) {\n        choice = ActionChoices(x);\n        d = uint256(choice);\n    }\n\n    function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n        choice = ActionChoices(x);\n        d = uint256(choice);\n    }\n\n    function getChoiceFromMax() public returns (uint256 d) {\n        choice = ActionChoices(type(uint).max);\n        d = uint256(choice);\n    }\n\n    ActionChoices choice;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// getChoiceExp(uint256): 2 -> 2\n// getChoiceExp(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x21 # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceFromMax() -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/enums/enum_explicit_overflow_homestead.sol",
    "content": "contract test {\n    enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n    constructor() {}\n\n    function getChoiceExp(uint256 x) public returns (uint256 d) {\n        choice = ActionChoices(x);\n        d = uint256(choice);\n    }\n\n    function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n        choice = ActionChoices(x);\n        d = uint256(choice);\n    }\n\n    function getChoiceFromMax() public returns (uint256 d) {\n        choice = ActionChoices(type(uint256).max);\n        d = uint256(choice);\n    }\n\n    ActionChoices choice;\n}\n// ====\n// EVMVersion: <byzantium\n// ----\n// getChoiceExp(uint256): 3 -> FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/enums/enum_referencing.sol",
    "content": "interface I {\n    enum Direction { A, B, Left, Right }\n}\nlibrary L {\n    enum Direction { Left, Right }\n    function f() public pure returns (Direction) {\n        return Direction.Right;\n    }\n    function g() public pure returns (I.Direction) {\n        return I.Direction.Right;\n    }\n}\ncontract C is I {\n    function f() public pure returns (Direction) {\n        return Direction.Right;\n    }\n    function g() public pure returns (I.Direction) {\n        return I.Direction.Right;\n    }\n    function h() public pure returns (L.Direction) {\n        return L.Direction.Right;\n    }\n    function x() public pure returns (L.Direction) {\n        return L.f();\n    }\n    function y() public pure returns (I.Direction) {\n        return L.g();\n    }\n}\n// ----\n// library: L\n// f() -> 3\n// g() -> 3\n// f() -> 3\n// g() -> 3\n// h() -> 1\n// x() -> 1\n// y() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/enums/enum_with_256_members.sol",
    "content": "pragma abicoder v2;\nenum E {\n    E000, E001, E002, E003, E004, E005, E006, E007, E008, E009,\n    E010, E011, E012, E013, E014, E015, E016, E017, E018, E019,\n    E020, E021, E022, E023, E024, E025, E026, E027, E028, E029,\n    E030, E031, E032, E033, E034, E035, E036, E037, E038, E039,\n    E040, E041, E042, E043, E044, E045, E046, E047, E048, E049,\n    E050, E051, E052, E053, E054, E055, E056, E057, E058, E059,\n    E060, E061, E062, E063, E064, E065, E066, E067, E068, E069,\n    E070, E071, E072, E073, E074, E075, E076, E077, E078, E079,\n    E080, E081, E082, E083, E084, E085, E086, E087, E088, E089,\n    E090, E091, E092, E093, E094, E095, E096, E097, E098, E099,\n    E100, E101, E102, E103, E104, E105, E106, E107, E108, E109,\n    E110, E111, E112, E113, E114, E115, E116, E117, E118, E119,\n    E120, E121, E122, E123, E124, E125, E126, E127, E128, E129,\n    E130, E131, E132, E133, E134, E135, E136, E137, E138, E139,\n    E140, E141, E142, E143, E144, E145, E146, E147, E148, E149,\n    E150, E151, E152, E153, E154, E155, E156, E157, E158, E159,\n    E160, E161, E162, E163, E164, E165, E166, E167, E168, E169,\n    E170, E171, E172, E173, E174, E175, E176, E177, E178, E179,\n    E180, E181, E182, E183, E184, E185, E186, E187, E188, E189,\n    E190, E191, E192, E193, E194, E195, E196, E197, E198, E199,\n    E200, E201, E202, E203, E204, E205, E206, E207, E208, E209,\n    E210, E211, E212, E213, E214, E215, E216, E217, E218, E219,\n    E220, E221, E222, E223, E224, E225, E226, E227, E228, E229,\n    E230, E231, E232, E233, E234, E235, E236, E237, E238, E239,\n    E240, E241, E242, E243, E244, E245, E246, E247, E248, E249,\n    E250, E251, E252, E253, E254, E255\n}\n\ncontract C {\n    function getMinMax() public returns (E, E) {\n        return (E.E000, E.E255);\n    }\n\n    function intToEnum(uint8 _i) public returns (E) {\n        return E(_i);\n    }\n\n    function enumToInt(E _e) public returns (uint8) {\n        return uint8(_e);\n    }\n\n    function decodeEnum(bytes memory data) public returns (E) {\n        (E e) = abi.decode(data, (E));\n        return e;\n    }\n}\n// ----\n// getMinMax() -> 0, 255\n// intToEnum(uint8): 0 -> 0\n// intToEnum(uint8): 255 -> 255\n// enumToInt(uint8): 0 -> 0\n// enumToInt(uint8): 255 -> 255\n// enumToInt(uint8): 256 -> FAILURE\n// decodeEnum(bytes): 0x20, 32, 0 -> 0\n// decodeEnum(bytes): 0x20, 32, 255 -> 255\n// decodeEnum(bytes): 0x20, 32, 256 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/enums/invalid_enum_logged.sol",
    "content": "contract C {\n    enum X { A, B }\n    event Log(X);\n\n    function test_log() public returns (uint) {\n        X garbled = X.A;\n        assembly {\n            garbled := 5\n        }\n        emit Log(garbled);\n        return 1;\n    }\n    function test_log_ok() public returns (uint) {\n        X x = X.A;\n        emit Log(x);\n        return 1;\n    }\n}\n// ----\n// test_log_ok() -> 1\n// ~ emit Log(uint8): 0x00\n// test_log() -> FAILURE, hex\"4e487b71\", 0x21\n"
  },
  {
    "path": "test/libsolidity/semanticTests/enums/minmax.sol",
    "content": "contract test {\n\tenum MinMax { A, B, C, D }\n\n\tfunction min() public returns(uint) { return uint(type(MinMax).min); }\n\tfunction max() public returns(uint) { return uint(type(MinMax).max); }\n}\n// ----\n// min() -> 0\n// max() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/enums/using_contract_enums_with_explicit_contract_name.sol",
    "content": "contract test {\n    enum Choice {A, B, C}\n\n    function answer() public returns (test.Choice _ret) {\n        _ret = test.Choice.B;\n    }\n}\n// ----\n// answer() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/enums/using_enums.sol",
    "content": "contract test {\n    enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n\n    constructor() {\n        choices = ActionChoices.GoStraight;\n    }\n\n    function getChoice() public returns (uint256 d) {\n        d = uint256(choices);\n    }\n\n    ActionChoices choices;\n}\n// ----\n// getChoice() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/enums/using_inherited_enum.sol",
    "content": "contract base {\n    enum Choice {A, B, C}\n}\n\n\ncontract test is base {\n    function answer() public returns (Choice _ret) {\n        _ret = Choice.B;\n    }\n}\n// ----\n// answer() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/enums/using_inherited_enum_excplicitly.sol",
    "content": "contract base {\n    enum Choice {A, B, C}\n}\n\n\ncontract test is base {\n    function answer() public returns (base.Choice _ret) {\n        _ret = base.Choice.B;\n    }\n}\n// ----\n// answer() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/error_in_library_and_interface.sol",
    "content": "error E(uint a);\nlibrary L {\n    error E(uint a, uint b);\n}\ninterface I {\n    error E(uint a, uint b, uint c);\n}\ncontract C {\n    function f() public pure {\n        revert E(1);\n    }\n    function g() public pure {\n        revert L.E(1, 2);\n    }\n    function h() public pure {\n        revert I.E(1, 2, 3);\n    }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/error_selector.sol",
    "content": "library L {\n    error E();\n}\nlibrary S {\n    error E(uint);\n}\nlibrary T {\n    error E();\n}\n\nerror E();\n\ninterface I {\n    error E();\n    function f() external pure;\n}\n\ncontract D {\n    error F();\n}\n\ncontract C is D {\n    function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) {\n        assert(L.E.selector == T.E.selector);\n        assert(L.E.selector != S.E.selector);\n        assert(E.selector == L.E.selector);\n        assert(I.E.selector == L.E.selector);\n        return (L.E.selector, S.E.selector, E.selector, I.E.selector);\n    }\n\n    bytes4 s1 = L.E.selector;\n    bytes4 s2 = S.E.selector;\n    bytes4 s3 = T.E.selector;\n    bytes4 s4 = I.E.selector;\n    function test2() external returns (bytes4, bytes4, bytes4, bytes4) {\n        return (s1, s2, s3, s4);\n    }\n\n    function test3() external returns (bytes4) {\n        return (F.selector);\n    }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/error_static_calldata_uint_array_and_dynamic_array.sol",
    "content": "contract C {\n    error E(uint[], uint[1]);\n\n    // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n    function f(uint[] memory a, uint[1] calldata b) public {\n        revert E(a, b);\n    }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/error_throw_from_module_via_member_access.sol",
    "content": "==== Source: A.sol ====\nerror ErrorA(string msg);\n==== Source: B.sol ====\nimport * as A from \"A.sol\";\n\nerror ErrorB(string msg);\n\ncontract BContract {\n    error ErrorB(string msg);\n}\n==== Source: C.sol ====\nimport * as B from \"B.sol\";\n\ncontract CContract {\n    function error1() external {\n        revert B.ErrorB(\"B error\");\n    }\n\n    function error2() external {\n        revert B.BContract.ErrorB(\"B.BContract error\");\n    }\n\n    function error3() external {\n        revert B.A.ErrorA(\"B.A error\");\n    }\n}\n\n// ----\n// error1() -> FAILURE, hex\"a5f9ec67\", 0x20, 7, \"B error\"\n// error2() -> FAILURE, hex\"a5f9ec67\", 0x20, 17, \"B.BContract error\"\n// error3() -> FAILURE, hex\"23b0db14\", 0x20, 9, \"B.A error\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/errors_by_parameter_type.sol",
    "content": "pragma abicoder v2;\n\nstruct S {\n    uint256 a;\n    bool b;\n    string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n    function a() external pure {\n        require(false, E());\n    }\n    function b() external pure {\n        require(false, E1(1));\n    }\n    function c() external pure {\n        require(false, E2(\"string literal\"));\n    }\n    function d() external pure {\n        require(false, E3(S(1, true, \"string literal\")));\n    }\n    function e() external view {\n        require(false, E4(address(0x1234)));\n    }\n    function f() external view {\n        require(false, E5(C(address(0x1234)).a));\n    }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"0000000000000000000000000000000000000000000000000000000000001234\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"00000000000000000000000000000000000012340dbe671f0000000000000000\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/named_error_args.sol",
    "content": "error E(uint a, uint b);\ncontract C {\n    function f() public pure {\n        revert E({b: 7, a: 2});\n    }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000007\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/named_parameters_shadowing_types.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    enum EnumType {A, B, C}\n\n    struct StructType {\n        uint x;\n    }\n\n    error E1(StructType StructType);\n    error E2(EnumType StructType, StructType EnumType);\n\n    function f() public {\n        revert E1({StructType: StructType(42)});\n    }\n\n    function g() public {\n        revert E2({EnumType: StructType(42), StructType: EnumType.B});\n    }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/panic_via_import.sol",
    "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport { E as Panic } from \"s1.sol\";\ncontract C {\n    error E(uint);\n    function a() public pure {\n        revert Panic(1);\n    }\n    function b() public pure {\n        revert E(1);\n    }\n}\n// ----\n// a() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// b() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_different_errors_same_parameters.sol",
    "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n    function f() external pure\n    {\n        require(false, AnError(1, \"two\", 3));\n    }\n\n    function g() external pure\n    {\n        require(false, AnotherError(4, \"five\", 6));\n    }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_error_condition_evaluated_only_once.sol",
    "content": "contract C {\n    uint256 counter = 0;\n\n    error CustomError(uint256);\n\n    function getCounter() public view returns (uint256) {\n        return counter;\n    }\n\n    function g(bool condition) internal returns (bool) {\n        counter++;\n        return condition;\n    }\n\n    function f(bool condition) external {\n        require(g(condition), CustomError(counter));\n    }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_error_evaluation_order_1.sol",
    "content": "contract C\n{\n    error E(uint);\n\n    function r() internal returns (uint)\n    {\n        assembly { mstore(0, 7) return (0, 32) }\n        return 42;\n    }\n\n    function f() public returns (uint)\n    {\n        require(false, E(r()));\n        return 42;\n    }\n\n    function g() public returns (uint)\n    {\n        require(true, E(r()));\n        return 42;\n    }\n}\n\n// ----\n// f() -> 7\n// g() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_error_evaluation_order_2.sol",
    "content": "contract C {\n    uint y;\n    function g(bool x) internal returns (bool) {\n        y = 42;\n        return x;\n    }\n    error E(uint256);\n    function h() internal returns (uint256) { return y; }\n    function f(bool c) public {\n        require(g(c), E(h()));\n    }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"002ff067\", 42\n// f(bool): true ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_error_evaluation_order_3.sol",
    "content": "contract C {\n    string failureMessage = \"Failure Message\";\n    function g(bool x) internal returns (bool) {\n        failureMessage = \"Intercepted failure message\";\n        return x;\n    }\n    function h() internal returns (string memory) { return failureMessage; }\n    function f(bool c) public {\n        require(g(c), h());\n    }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x1b, \"Intercepted failure message\"\n// f(bool): true ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_error_function_join_control_flow.sol",
    "content": "contract C {\n    uint x = 0;\n    uint y = 42;\n    error E(uint);\n    function f(bool c) public returns (uint256, uint256, uint256) {\n        uint z = x;\n        if (y == 42) {\n            x = 21;\n        } else {\n            require(c, E(y));\n        }\n        y /= 2;\n        return (x,y,z);\n    }\n}\n// ----\n// f(bool): true -> 0x15, 0x15, 0\n// f(bool): false -> FAILURE, hex\"002ff067\", 21\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_error_function_pointer_parameter.sol",
    "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n    function e(uint256 x) external pure returns (uint256)\n    {\n        return x;\n    }\n\n    function f() external view\n    {\n        // more than one stack slot\n        require(false, CustomError(C(address(0x1234)).e));\n    }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"0000000000000000000000000000000000001234f37cdc8e0000000000000000\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_error_multiple_arguments.sol",
    "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n    function f() external pure\n    {\n        require(false, CustomError(1, \"two\", 3));\n    }\n\n    function g() external pure\n    {\n        require(false, CustomError(4, \"five\", 6));\n    }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_error_stack_check.sol",
    "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n    error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n    uint public x;\n\n    function e(uint256 y) external pure returns (uint256) {\n        return y;\n    }\n\n    function f(bool condition, uint a, uint b, uint c) public {\n        require(condition, E(a, b, c, this.e));\n        x = b;\n    }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_error_string_literal.sol",
    "content": "error CustomError(string);\n\ncontract C\n{\n    function f() external pure\n    {\n        require(false, CustomError(\"errorReason\"));\n    }\n\n    function g() external pure\n    {\n        require(false, CustomError(\"anotherReason\"));\n    }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_error_string_memory.sol",
    "content": "error CustomError(string);\n\ncontract C\n{\n    function f() external pure\n    {\n        string memory reason = \"errorReason\";\n        require(false, CustomError(reason));\n    }\n\n    function g() external pure\n    {\n        string memory reason = \"anotherReason\";\n        require(false, CustomError(reason));\n    }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_error_uint256.sol",
    "content": "error CustomError(uint256);\n\ncontract C\n{\n    function f() external pure\n    {\n        require(false, CustomError(1));\n    }\n\n    function g() external pure\n    {\n        require(false, CustomError(2));\n    }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/require_inherited_error.sol",
    "content": "contract Base\n{\n    error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n    function f() external pure\n    {\n        require(false, CustomError(1, \"two\", 3));\n    }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/revert_conversion.sol",
    "content": "error E(string a, uint[] b);\ncontract C {\n    uint[] x;\n    function f() public {\n        x.push(7);\n        revert E(\"abc\", x);\n    }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/simple.sol",
    "content": "error E(uint a, uint b);\ncontract C {\n    function f() public pure {\n        revert E(2, 7);\n    }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", 2, 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/small_error_optimization.sol",
    "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/using_structs.sol",
    "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n    S s;\n    function f(bool c) public {\n        if (c) {\n            s.a = 9;\n            s.b = \"abc\";\n            revert E(2, s, 7);\n        } else {\n            revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n        }\n    }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/via_contract_type.sol",
    "content": "contract A {\n  error E(uint);\n}\ncontract X {\n  error E(string);\n}\ncontract B is A {\n  function f() public pure { revert E(1); }\n  function g() public pure  { revert A.E(1); }\n  function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/via_import.sol",
    "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport \"s1.sol\" as S;\n==== Source: s3.sol ====\nimport \"s1.sol\" as S;\nimport \"s2.sol\" as T;\nimport \"s1.sol\";\ncontract C {\n  function x() public pure {\n    revert E(1);\n  }\n  function y() public pure {\n    revert S.E(2);\n  }\n  function z() public pure {\n    revert T.S.E(3);\n  }\n}\n// ----\n// x() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// y() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// z() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/errors/weird_name.sol",
    "content": "error error(uint a);\ncontract C {\n    function f() public pure {\n        revert error(2);\n    }\n}\n// ----\n// f() -> FAILURE, hex\"b48fb6cf\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/emit_three_identical_events.sol",
    "content": "contract C {\n    event Terminated();\n\n    function terminate() external {\n        emit Terminated();\n        emit Terminated();\n        emit Terminated();\n    }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()"
  },
  {
    "path": "test/libsolidity/semanticTests/events/emit_two_identical_events.sol",
    "content": "contract C {\n    event Terminated();\n\n    function terminate() external {\n        emit Terminated();\n        emit Terminated();\n    }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event.sol",
    "content": "contract ClientReceipt {\n    event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n    function deposit(bytes32 _id, bool _manually) public payable {\n        if (_manually) {\n            bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n            uint value = msg.value;\n            address sender = msg.sender;\n            assembly {\n                mstore(0, value)\n                log3(0, 0x20, s, sender, _id)\n            }\n        } else {\n            emit Deposit(msg.sender, _id, msg.value);\n        }\n    }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_access_through_base_name_emit.sol",
    "content": "contract A {\n    event x();\n}\ncontract B is A {\n    function f() public returns (uint) {\n        emit A.x();\n        return 1;\n    }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_anonymous.sol",
    "content": "contract ClientReceipt {\n    event Deposit() anonymous;\n    function deposit() public {\n        emit Deposit();\n    }\n}\n// ----\n// deposit() ->\n// ~ emit <anonymous>\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_anonymous_with_signature_collision.sol",
    "content": "contract ClientReceipt {\n    event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n    function deposit(bytes32 _id) public payable {\n        emit Deposit(0x2012159ca6b6372f102c535a4814d13a00bfc5568ddfd72151364061b00355d1, _id, msg.value); // 0x2012159c -> 'Deposit(uint256,bytes32,uint256)'\n    }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit <anonymous>: #0x2012159ca6b6372f102c535a4814d13a00bfc5568ddfd72151364061b00355d1, #0x1234, 0x12\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_anonymous_with_signature_collision2.sol",
    "content": "contract ClientReceipt {\n    event Withdraw(uint _value, string owner);\n    event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n    function deposit(bytes32 _id) public payable {\n        emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n    }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_anonymous_with_topics.sol",
    "content": "contract ClientReceipt {\n    event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n    function deposit(bytes32 _id) public payable {\n        emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n    }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit <anonymous>: #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_constructor.sol",
    "content": "contract ClientReceipt {\n    event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n    constructor() {\n        emit Deposit(msg.sender, bytes32(\"abc\"), 7);\n    }\n}\n// ----\n// constructor()\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #\"abc\", 0x07\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_dynamic_array_memory.sol",
    "content": "contract C {\n    event E(uint[]);\n    function createEvent(uint x) public {\n        uint[] memory arr = new uint[](3);\n        arr[0] = x;\n        arr[1] = x + 1;\n        arr[2] = x + 2;\n        emit E(arr);\n    }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_dynamic_array_memory_v2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n    event E(uint[]);\n    function createEvent(uint x) public {\n        uint[] memory arr = new uint[](3);\n        arr[0] = x;\n        arr[1] = x + 1;\n        arr[2] = x + 2;\n        emit E(arr);\n    }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol",
    "content": "contract C {\n    event E(uint[]);\n    uint[] arr;\n    function createEvent(uint x) public {\n        while (arr.length < 3)\n            arr.push();\n        arr[0] = x;\n        arr[1] = x + 1;\n        arr[2] = x + 2;\n        emit E(arr);\n    }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n    event E(uint[]);\n    uint[] arr;\n    function createEvent(uint x) public {\n        while (arr.length < 3)\n            arr.push();\n        arr[0] = x;\n        arr[1] = x + 1;\n        arr[2] = x + 2;\n        emit E(arr);\n    }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_dynamic_nested_array_memory_v2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n    event E(uint[][]);\n    function createEvent(uint x) public {\n        uint[][] memory arr = new uint[][](2);\n        arr[0] = new uint[](2);\n        arr[1] = new uint[](2);\n        arr[0][0] = x;\n        arr[0][1] = x + 1;\n        arr[1][0] = x + 2;\n        arr[1][1] = x + 3;\n        emit E(arr);\n    }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n    event E(uint[][]);\n    uint[][] arr;\n    function createEvent(uint x) public {\n        arr.push(new uint[](2));\n        arr.push(new uint[](2));\n        arr[0][0] = x;\n        arr[0][1] = x + 1;\n        arr[1][0] = x + 2;\n        arr[1][1] = x + 3;\n        emit E(arr);\n    }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 188615\n// gas legacyOptimized: 184548\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_emit.sol",
    "content": "contract ClientReceipt {\n    event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n    function deposit(bytes32 _id) public payable {\n        emit Deposit(msg.sender, _id, msg.value);\n    }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_emit_file_level.sol",
    "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n    function deposit(bytes32 _id) public payable {\n        emit Deposit(msg.sender, _id, msg.value);\n    }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_emit_from_a_foreign_contract.sol",
    "content": "contract C {\n    event E();\n}\n\ncontract D {\n    function test() public {\n        emit C.E();\n    }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_emit_from_a_foreign_contract_same_name.sol",
    "content": "contract C {\n    event E(uint256 value);\n}\n\ncontract D {\n    event E(uint256 value);\n\n    function test() public {\n        emit C.E(1);\n        emit E(2);\n    }\n}\n\n// ----\n// test() ->\n// ~ emit E(uint256): 0x01\n// ~ emit E(uint256): 0x02\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_emit_from_module_via_member_access.sol",
    "content": "==== Source: A.sol ====\nevent Transfer(address indexed _from, address indexed _to, uint256 _value);\n==== Source: B.sol ====\nimport * as A from \"A.sol\";\n\nevent Transfer(address indexed _from, address indexed _to, uint256 _value);\n\ncontract BContract {\n    event Transfer(address indexed _from, address indexed _to, uint256 _value);\n}\n==== Source: C.sol ====\nimport * as B from \"B.sol\";\n\ncontract CContract {\n    function returnAddress() external {\n        emit B.Transfer(address(0x0b), address(0x0c), 0x0d);\n        emit B.BContract.Transfer(address(0x0e), address(0x0f), 0x10);\n        emit B.A.Transfer(address(0x11), address(0x12), 0x13);\n    }\n}\n\n// ----\n// returnAddress() ->\n// ~ emit Transfer(address,address,uint256): #0x0b, #0x0c, 0x0d\n// ~ emit Transfer(address,address,uint256): #0x0e, #0x0f, 0x10\n// ~ emit Transfer(address,address,uint256): #0x11, #0x12, 0x13\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_emit_from_other_contract.sol",
    "content": "// TODO: Implement this test for EOF. Now it's not possible because deployed contract address depends on contract bytecode.\n// This means that the address changes when optimisations are applied.\ncontract D {\n    event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n    function deposit(bytes32 _id) public payable {\n        emit Deposit(msg.sender, _id, msg.value);\n    }\n}\ncontract C {\n    D d;\n    constructor() {\n        d = new D();\n    }\n    function deposit(bytes32 _id) public payable {\n        d.deposit(_id);\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_emit_interface_event_via_library.sol",
    "content": "interface I {\n    event E();\n}\n\nlibrary L {\n    function f() internal {\n        emit I.E();\n    }\n}\n\ncontract C {\n    function g() public {\n        L.f();\n    }\n}\n\n// ----\n// g() ->\n// ~ emit E()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_emit_via_interface.sol",
    "content": "interface I {\n    event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n    function emitEvent(uint256 _value) public {\n        emit I.Event(msg.sender, _value);\n    }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_indexed_function.sol",
    "content": "contract C {\n    event Test(function() external indexed);\n    function f() public {\n        emit Test(C(address(0x1234)).f);\n    }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0x123426121ff00000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_indexed_function2.sol",
    "content": "contract C {\n    event TestA(function() external indexed);\n    event TestB(function(uint256) external indexed);\n    function f1() public {\n        emit TestA(C(address(0x1234)).f1);\n    }\n    function f2(uint256 a) public {\n        emit TestB(C(address(0x1234)).f2);\n    }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0x1234c27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0x1234bf3724af0000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_indexed_mixed.sol",
    "content": "contract C {\n    // Indexed parameters are always listed first in the output.\n    // The data is the ABI encoding of just the non-indexed parameters,\n    // so putting the indexed parameters \"in between\" would mess\n    // up the offsets for the reader.\n    event E(uint a, uint indexed r, uint b, bytes c);\n    function deposit() public {\n        emit E(1, 2, 3, \"def\");\n    }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23695\n// gas legacy: 24328\n// gas legacyOptimized: 23752\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_indexed_string.sol",
    "content": "contract C {\n    string x;\n    uint[4] y;\n    event E(string indexed r, uint[4] indexed t);\n    function deposit() public {\n        for (uint i = 0; i < 90; i++)\n            bytes(x).push(0);\n        for (uint8 i = 0; i < 90; i++)\n            bytes(x)[i] = bytes1(i);\n        y[0] = 4;\n        y[1] = 5;\n        y[2] = 6;\n        y[3] = 7;\n        emit E(x, y);\n    }\n}\n// ----\n// deposit() ->\n// ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81\n// gas irOptimized: 332788\n// gas legacy: 366022\n// gas legacyOptimized: 362429\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_lots_of_data.sol",
    "content": "contract ClientReceipt {\n    event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n    function deposit(bytes32 _id) public payable {\n        emit Deposit(msg.sender, _id, msg.value, true);\n    }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_no_arguments.sol",
    "content": "contract ClientReceipt {\n    event Deposit();\n    function deposit() public {\n        emit Deposit();\n    }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_really_lots_of_data.sol",
    "content": "contract ClientReceipt {\n    event Deposit(uint fixeda, bytes dynx, uint fixedb);\n    function deposit() public {\n        emit Deposit(10, msg.data, 15);\n    }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_really_lots_of_data_from_storage.sol",
    "content": "contract ClientReceipt {\n    bytes x;\n    event Deposit(uint fixeda, bytes dynx, uint fixedb);\n    function deposit() public {\n        x.push(\"A\");\n        x.push(\"B\");\n        x.push(\"C\");\n        emit Deposit(10, x, 15);\n    }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_really_really_lots_of_data_from_storage.sol",
    "content": "contract ClientReceipt {\n    bytes x;\n    event Deposit(uint fixeda, bytes dynx, uint fixedb);\n    function deposit() public {\n        x = new bytes(31);\n        x[0] = \"A\";\n        x[1] = \"B\";\n        x[2] = \"C\";\n        x[30] = \"Z\";\n        emit Deposit(10, x, 15);\n    }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_selector.sol",
    "content": "library L {\n    event E();\n}\n\nlibrary S {\n    event E(uint);\n}\n\nlibrary T {\n    event E();\n}\n\ninterface I {\n    event E();\n}\n\ncontract B {\n    event E();\n}\n\ncontract D {\n    event F();\n}\n\ncontract C is D {\n    function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n        assert(L.E.selector == T.E.selector);\n        assert(I.E.selector == L.E.selector);\n        assert(T.E.selector == I.E.selector);\n        assert(B.E.selector == T.E.selector);\n\n        assert(L.E.selector != S.E.selector);\n        assert(T.E.selector != S.E.selector);\n        assert(I.E.selector != S.E.selector);\n        assert(B.E.selector != S.E.selector);\n\n        return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n    }\n\n    bytes32 s1 = L.E.selector;\n    bytes32 s2 = S.E.selector;\n    bytes32 s3 = T.E.selector;\n    bytes32 s4 = I.E.selector;\n    bytes32 s5 = B.E.selector;\n    function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n        return (s1, s2, s3, s4, s5);\n    }\n\n    function test3() external returns (bytes32) {\n        return (F.selector);\n    }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_selector_file_level.sol",
    "content": "event E();\n\nlibrary L {\n    event E();\n}\n\ncontract C {\n    function main() external pure returns (bytes32, bytes32) {\n        assert(E.selector == L.E.selector);\n\n        return (E.selector, L.E.selector);\n    }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_shadowing_file_level.sol",
    "content": "event E();\n\nlibrary L1 {\n    event E(string);\n}\n\nlibrary L2 {\n    event E();\n}\n\nlibrary K {\n    function main() internal pure returns (bytes32, bytes32, bytes32) {\n        // Here E is the global event.\n        assert(E.selector != L1.E.selector);\n        assert(E.selector == L2.E.selector);\n\n        return (E.selector, L1.E.selector, L2.E.selector);\n    }\n}\n\ncontract C {\n    event E(string);\n\n    function main() external pure returns (bytes32, bytes32, bytes32) {\n        // Here E is the local event.\n        assert(E.selector == L1.E.selector);\n        assert(E.selector != L2.E.selector);\n\n        return (E.selector, L1.E.selector, L2.E.selector);\n    }\n\n    function k_main() external pure returns (bytes32, bytes32, bytes32) {\n        return K.main();\n    }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_signature_in_library.sol",
    "content": "pragma abicoder v2;\nlibrary L {\n    struct S {\n        uint8 a;\n        int16 b;\n    }\n    event E(S indexed, S);\n    function f() internal {\n        S memory s;\n        emit E(s, s);\n    }\n}\ncontract C {\n    constructor() {\n        L.f();\n    }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 62552\n// gas legacy code: 1600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_static_calldata_uint_array_and_dynamic_array.sol",
    "content": "contract C {\n    event E(uint[], uint[1]);\n\n    // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n    function f(uint[] memory a, uint[1] calldata b) public {\n        emit E(a, b);\n    }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_string.sol",
    "content": "contract C {\n    event E(string r);\n    function deposit() public {\n        emit E(\"HELLO WORLD\");\n    }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_struct_memory_v2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n    struct S { uint a; }\n    event E(S);\n    function createEvent(uint x) public {\n        emit E(S(x));\n    }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/event_struct_storage_v2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n    struct S { uint a; }\n    event E(S);\n    S s;\n    function createEvent(uint x) public {\n        s.a = x;\n        emit E(s);\n    }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/events_with_same_name.sol",
    "content": "contract ClientReceipt {\n    event Deposit();\n    event Deposit(address _addr);\n    event Deposit(address _addr, uint _amount);\n    event Deposit(address _addr, bool _flag);\n    function deposit() public returns (uint) {\n        emit Deposit();\n        return 1;\n    }\n    function deposit(address _addr) public returns (uint) {\n        emit Deposit(_addr);\n        return 2;\n    }\n    function deposit(address _addr, uint _amount) public returns (uint) {\n        emit Deposit(_addr, _amount);\n        return 3;\n    }\n    function deposit(address _addr, bool _flag) public returns (uint) {\n        emit Deposit(_addr, _flag);\n        return 4;\n    }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/events_with_same_name_file_level.sol",
    "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n    function deposit() public returns (uint) {\n        emit Deposit();\n        return 1;\n    }\n    function deposit(address _addr) public returns (uint) {\n        emit Deposit(_addr);\n        return 2;\n    }\n    function deposit(address _addr, uint _amount) public returns (uint) {\n        emit Deposit(_addr, _amount);\n        return 3;\n    }\n    function deposit(address _addr, bool _flag) public returns (uint) {\n        emit Deposit(_addr, _flag);\n        return 4;\n    }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/events_with_same_name_inherited_emit.sol",
    "content": "contract A {\n    event Deposit();\n}\n\ncontract B {\n    event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n    event Deposit(address _addr, uint _amount);\n    function deposit() public returns (uint) {\n        emit Deposit();\n        return 1;\n    }\n    function deposit(address _addr) public returns (uint) {\n        emit Deposit(_addr);\n        return 1;\n    }\n    function deposit(address _addr, uint _amount) public returns (uint) {\n        emit Deposit(_addr, _amount);\n        return 1;\n    }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n"
  },
  {
    "path": "test/libsolidity/semanticTests/events/simple.sol",
    "content": "contract C {\n    event E();\n}\n\ncontract Test is C {\n    event E(uint256, uint256);\n    function f() public {\n        emit C.E();\n        emit E(1,2);\n    }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() ->\n// ~ emit E()\n// ~ emit E(uint256,uint256): 0x01, 0x02\n"
  },
  {
    "path": "test/libsolidity/semanticTests/experimental/stub.sol",
    "content": "pragma experimental solidity;\n\ntype word = __builtin(\"word\");\ntype bool = __builtin(\"bool\");\ntype integer = __builtin(\"integer\");\n\ntype uint256 = word;\n\ninstantiation uint256: + {\n    function add(x, y) -> uint256 {\n        let a = uint256.rep(x);\n        let b = uint256.rep(y);\n        assembly {\n            a := add(a,b)\n        }\n        return uint256.abs(a);\n    }\n}\n\n\ninstantiation uint256: * {\n    function mul(x, y) -> uint256 {\n        let a = uint256.rep(x);\n        let b = uint256.rep(y);\n        assembly {\n            a := mul(a,b)\n        }\n        return uint256.abs(a);\n    }\n}\ninstantiation word: * {\n    function mul(x, y) -> word {\n        let z: word;\n        assembly {\n            z := mul(x,y)\n        }\n        return z;\n    }\n}\n\ninstantiation word: Integer {\n    function fromInteger(x:integer) -> word {\n        //x + x;\n    }\n}\n\ninstantiation word: == {\n    function eq(x, y) -> bool {\n        assembly {\n            x := eq(x, y)\n        }\n    }\n}\n\n\nfunction f(x:uint256->uint256,y:uint256) -> uint256\n{\n    return x(y);\n}\n\nfunction g(x:uint256) -> uint256\n{\n    return x;\n}\n\ncontract C {\n    fallback() external {\n        let arg;\n        assembly {\n            arg := calldataload(0)\n        }\n        let x : word;\n        if (bool.abs(arg)) {\n            assembly {\n                x := 0x10\n            }\n        }\n        let w = uint256.abs(x);\n//        w = f(g, w);\n        w = w * w + w;\n        let y : word;\n        let z : (uint256,uint256);\n        assembly { y := 2 }\n        y = uint256.rep(w) * y;\n        assembly {\n            mstore(0, y)\n            return(0, 32)\n        }\n    }\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ====\n// compileViaYul: true\n// bytecodeFormat: legacy\n// ----\n// (): 0 -> 0\n// (): 1 -> 544\n"
  },
  {
    "path": "test/libsolidity/semanticTests/experimental/type_class.sol",
    "content": "pragma experimental solidity;\n\ntype word = __builtin(\"word\");\ntype bool = __builtin(\"bool\");\n\ntype Cat = word;\ntype Dog = word;\n\nclass Self: Animal {\n    function new() -> Self;\n    function alive(self: Self) -> bool;\n}\n\ninstantiation Cat: Animal {\n    function new() -> Cat {\n        let c;\n        return c;\n    }\n\n    function alive(self: Cat) -> bool {\n        // TODO: Boolean literals or operators not implemented.\n        let w;\n        assembly {\n            w := 1\n        }\n        return bool.abs(w);\n    }\n}\n\ninstantiation Dog: Animal {\n    function new() -> Dog {\n        let d: Dog;\n        return d;\n    }\n\n    function alive(self: Dog) -> bool {\n        let b: bool;\n        return b;\n    }\n}\n\ncontract C {\n    fallback() external {\n        let boolResult1: bool;\n        let boolResult2: bool;\n\n        let c: Cat = Animal.new();\n        boolResult1 = Animal.alive(c);\n\n        let d: Dog = Animal.new();\n        boolResult2 = Animal.alive(d);\n\n        let wordResult1 = bool.rep(boolResult1);\n        let wordResult2 = bool.rep(boolResult2);\n        assembly {\n            mstore(0, wordResult1)\n            mstore(32, wordResult2)\n            return(0, 64)\n        }\n    }\n}\n\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// bytecodeFormat: legacy\n// ----\n// () -> 1, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/exponentiation/literal_base.sol",
    "content": "contract test {\n    function f(uint x) public pure returns (uint, int) {\n        unchecked {\n            uint a = 2 ** x;\n            int b = -2 ** x;\n            return (a, b);\n        }\n    }\n}\n// ----\n// f(uint256): 0 -> 1, 1\n// f(uint256): 1 -> 2, -2\n// f(uint256): 2 -> 4, 4\n// f(uint256): 13 -> 0x2000, -8192\n// f(uint256): 113 -> 0x020000000000000000000000000000, -10384593717069655257060992658440192\n// f(uint256): 114 -> 0x040000000000000000000000000000, 20769187434139310514121985316880384\n// f(uint256): 1113 -> 0x00, 0\n// f(uint256): 1114 -> 0x00, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/exponentiation/signed_base.sol",
    "content": "contract test {\n    function f() public pure returns (int, int) {\n        int32 x = -3;\n        uint8 y1;\n        uint8 y2;\n        assembly {\n            y1 := 0x102\n            y2 := 0x103\n        }\n        return (x**y1, x**y2);\n    }\n}\n// ----\n// f() -> 9, -27\n"
  },
  {
    "path": "test/libsolidity/semanticTests/exponentiation/small_exp.sol",
    "content": "contract test {\n    function f() public pure returns (uint r) {\n        uint32 x;\n        uint8 y;\n        assembly {\n            x := 0xfffffffffe\n            y := 0x102\n        }\n        unchecked { r = x**y; }\n        return r;\n    }\n}\n// ----\n// f() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/bit_operators.sol",
    "content": "contract test {\n    uint8 x;\n    uint v;\n    function f() public returns (uint x, uint y, uint z) {\n        uint16 a;\n        uint32 b;\n        assembly {\n            a := 0x0f0f0f0f0f\n            b := 0xff0fff0fff\n        }\n        x = a & b;\n        y = a | b;\n        z = a ^ b;\n    }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/bytes_comparison.sol",
    "content": "contract test {\n    function f() public returns (bool) {\n        bytes2 a = \"a\";\n        bytes2 x = \"aa\";\n        bytes2 b = \"b\";\n        return a < x && x < b;\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/conditional_expression_different_types.sol",
    "content": "contract test {\n    function f(bool cond) public returns (uint) {\n        uint8 x = 0xcd;\n        uint16 y = 0xabab;\n        return cond ? x : y;\n    }\n}\n// ----\n// f(bool): true -> 0xcd\n// f(bool): false -> 0xabab\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/conditional_expression_false_literal.sol",
    "content": "contract test {\n    function f() public returns(uint d) {\n        return false ? 5 : 10;\n    }\n}\n// ----\n// f() -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/conditional_expression_functions.sol",
    "content": "contract test {\n    function x() public returns (uint) { return 1; }\n    function y() public returns (uint) { return 2; }\n\n    function f(bool cond) public returns (uint) {\n        function () returns (uint) z = cond ? x : y;\n        return z();\n    }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/conditional_expression_multiple.sol",
    "content": "contract test {\n    function f(uint x) public returns(uint d) {\n        return x > 100 ?\n                    x > 1000 ? 1000 : 100\n                    :\n                    x > 50 ? 50 : 10;\n    }\n}\n// ----\n// f(uint256): 1001 -> 1000\n// f(uint256): 500 -> 100\n// f(uint256): 80 -> 50\n// f(uint256): 40 -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/conditional_expression_storage_memory_1.sol",
    "content": "contract test {\n    bytes2[2] data1;\n    function f(bool cond) public returns (uint) {\n        bytes2[2] memory x;\n        x[0] = \"aa\";\n        bytes2[2] memory y;\n        y[0] = \"bb\";\n\n        data1 = cond ? x : y;\n\n        uint ret = 0;\n        if (data1[0] == \"aa\")\n        {\n            ret = 1;\n        }\n\n        if (data1[0] == \"bb\")\n        {\n            ret = 2;\n        }\n\n        return ret;\n    }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/conditional_expression_storage_memory_2.sol",
    "content": "contract test {\n    bytes2[2] data1;\n    function f(bool cond) public returns (uint) {\n        data1[0] = \"cc\";\n\n        bytes2[2] memory x;\n        bytes2[2] memory y;\n        y[0] = \"bb\";\n\n        x = cond ? y : data1;\n\n        uint ret = 0;\n        if (x[0] == \"bb\")\n        {\n            ret = 1;\n        }\n\n        if (x[0] == \"cc\")\n        {\n            ret = 2;\n        }\n\n        return ret;\n    }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/conditional_expression_true_literal.sol",
    "content": "contract test {\n    function f() public returns(uint d) {\n        return true ? 5 : 10;\n    }\n}\n// ----\n// f() -> 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/conditional_expression_tuples.sol",
    "content": "contract test {\n    function f(bool cond) public returns (uint, uint) {\n        return cond ? (1, 2) : (3, 4);\n    }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/conditional_expression_with_return_values.sol",
    "content": "contract test {\n    function f(bool cond, uint v) public returns (uint a, uint b) {\n        cond ? a = v : b = v;\n    }\n}\n// ----\n// f(bool,uint256): true, 20 -> 20, 0\n// f(bool,uint256): false, 20 -> 0, 20\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/exp_operator_const.sol",
    "content": "contract test {\n    function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/exp_operator_const_signed.sol",
    "content": "contract test {\n    function f() public returns(int d) { return (-2) ** 3; }\n}\n// ----\n// f() -> -8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/exp_zero_literal.sol",
    "content": "contract test {\n    function f() public returns(uint d) { return 0 ** 0; }\n}\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/inc_dec_operators.sol",
    "content": "contract test {\n    uint8 x;\n    uint v;\n    function f() public returns (uint r) {\n        uint a = 6;\n        r = a;\n        r += (a++) * 0x10;\n        r += (++a) * 0x100;\n        v = 3;\n        r += (v++) * 0x1000;\n        r += (++v) * 0x10000;\n    }\n}\n// ----\n// f() -> 0x053866\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/module_from_ternary_expression.sol",
    "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n    function f() public pure returns (bool) {\n        bool flag;\n        ((flag = true) ? M : M).D;\n        return flag;\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/tuple_from_ternary_expression.sol",
    "content": "contract C {\n    function f() public pure returns (bool){\n        bool flag;\n        ((flag = true) ? (1, 2, 3) : (3, 2, 1));\n        return flag;\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/unary_too_long_literal.sol",
    "content": "contract C {\n\tfunction f() public returns (bool) {\n\t\treturn\n\t\t\t0 <\n\t\t\t~~84926290883049832306107864558384249403874903260938453235235091622489261765859;\n\t}\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/expressions/uncalled_address_transfer_send.sol",
    "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/FixedFeeRegistrar.sol",
    "content": "//sol FixedFeeRegistrar\n// Simple global registrar with fixed-fee reservations.\n// @authors:\n//   Gav Wood <g@ethdev.com>\n\npragma solidity >=0.4.0 <0.9.0;\n\nabstract contract Registrar {\n\tevent Changed(string indexed name);\n\n\tfunction owner(string memory _name) public virtual view returns (address o_owner);\n\tfunction addr(string memory _name) public virtual view returns (address o_address);\n\tfunction subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);\n\tfunction content(string memory _name) public virtual view returns (bytes32 o_content);\n}\n\ncontract FixedFeeRegistrar is Registrar {\n\tstruct Record {\n\t\taddress addr;\n\t\taddress subRegistrar;\n\t\tbytes32 content;\n\t\taddress owner;\n\t}\n\n\tmodifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }\n\n\tfunction reserve(string memory _name) public payable {\n\t\tRecord storage rec = m_record(_name);\n\t\tif (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {\n\t\t\trec.owner = msg.sender;\n\t\t\temit Changed(_name);\n\t\t}\n\t}\n\tfunction disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {\n\t\tdelete m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t\tif (!_refund.send(c_fee))\n\t\t\trevert();\n\t\temit Changed(_name);\n\t}\n\tfunction transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {\n\t\tm_record(_name).owner = _newOwner;\n\t\temit Changed(_name);\n\t}\n\tfunction setAddr(string memory _name, address _a) onlyrecordowner(_name) public {\n\t\tm_record(_name).addr = _a;\n\t\temit Changed(_name);\n\t}\n\tfunction setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {\n\t\tm_record(_name).subRegistrar = _registrar;\n\t\temit Changed(_name);\n\t}\n\tfunction setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {\n\t\tm_record(_name).content = _content;\n\t\temit Changed(_name);\n\t}\n\n\tfunction record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {\n\t\tRecord storage rec = m_record(_name);\n\t\to_addr = rec.addr;\n\t\to_subRegistrar = rec.subRegistrar;\n\t\to_content = rec.content;\n\t\to_owner = rec.owner;\n\t}\n\tfunction addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }\n\tfunction subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }\n\tfunction content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }\n\tfunction owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }\n\n\tRecord[2**253] m_recordData;\n\tfunction m_record(string memory _name) view internal returns (Record storage o_record) {\n\t\treturn m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t}\n\tuint constant c_fee = 69 ether;\n}\n// ----\n// constructor()\n// gas irOptimized: 78076\n// gas irOptimized code: 307400\n// gas legacy: 115395\n// gas legacy code: 792400\n// gas legacyOptimized: 84598\n// gas legacyOptimized code: 388000\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// gas irOptimized: 45741\n// gas legacy: 46698\n// gas legacyOptimized: 45948\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 70 ether: 0x20, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 68 ether: 0x20, 3, \"ghi\" ->\n// owner(string): 0x20, 3, \"ghi\" -> 0\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// setContent(string,bytes32): 0x40, 0, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// transfer(string,address): 0x40, 555, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// owner(string): 0x20, 3, \"abc\" -> 555\n// content(string): 0x20, 3, \"abc\" -> 0x00\n// setContent(string,bytes32): 0x40, 333, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setAddr(string,address): 0x40, 124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setSubRegistrar(string,address): 0x40, 125, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// content(string): 0x20, 3, \"def\" -> 333\n// addr(string): 0x20, 3, \"def\" -> 124\n// subRegistrar(string): 0x20, 3, \"def\" -> 125\n// balance: 0x124 -> 0\n// disown(string,address): 0x40, 0x124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// balance: 0x124 -> 0\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0\n// content(string): 0x20, 3, \"def\" -> 0\n// addr(string): 0x20, 3, \"def\" -> 0\n// subRegistrar(string): 0x20, 3, \"def\" -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/_base64/base64_inline_asm.sol",
    "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n */\nlibrary InlineAsmBase64 {\n    /**\n     * @dev Base64 Encoding/Decoding Table\n     */\n    string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n    /**\n     * @dev Converts a `bytes` to its Bytes64 `string` representation.\n     */\n    function encode(bytes memory data) internal pure returns (string memory) {\n        /**\n         * Inspired by OpenZepplin Base64 implementation\n         * https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2884/commits/157c32b65a15cb0b58257543643cafa1cebf883a\n         */\n        if (data.length == 0) return \"\";\n\n        // Loads the table into memory\n        string memory table = _TABLE;\n\n        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n        // and split into 4 numbers of 6 bits.\n        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n        // - `data.length + 2`  -> Round up\n        // - `/ 3`              -> Number of 3-bytes chunks\n        // - `4 *`              -> 4 characters for each chunk\n        uint256 encodedLen = 4 * ((data.length + 2) / 3);\n\n        // Add some extra buffer at the end required for the writing\n        string memory result = new string(encodedLen);\n\n        assembly {\n            // Store the actual result length in memory\n            mstore(result, encodedLen)\n\n            // Prepare the lookup table\n            let tablePtr := add(table, 1)\n\n            // Prepare input pointer\n            let dataPtr := data\n            let endPtr := add(dataPtr, mload(data))\n\n            // Prepare result pointer, jump over length\n            let resultPtr := add(result, 32)\n\n            // Run over the input, 3 bytes at a time\n            for {\n\n            } lt(dataPtr, endPtr) {\n\n            } {\n                // Advance 3 bytes\n                dataPtr := add(dataPtr, 3)\n                let input := mload(dataPtr)\n\n                // To write each character, shift the 3 bytes (24 bits) chunk 4\n                // times in blocks of 6 bits for each character (18, 12, 6, 0)\n                // and apply logical AND with 0x3F to extract the 6-bit group.\n                // Add the 6-bit group with the table ptr to index into the\n                // table and acquire the character to write.  Finally, write\n                // the character to the result pointer.\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n            }\n\n            // When data `bytes` is not exactly 3 bytes long\n            // it is padded with `=` characters at the end\n            switch mod(mload(data), 3)\n            case 1 {\n                mstore8(sub(resultPtr, 1), 0x3d)\n                mstore8(sub(resultPtr, 2), 0x3d)\n            }\n            case 2 {\n                mstore8(sub(resultPtr, 1), 0x3d)\n            }\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/_base64/base64_no_inline_asm.sol",
    "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n */\nlibrary NoAsmBase64 {\n    bytes private constant TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n        function encode(bytes memory data) internal pure returns (string memory) {\n        if (data.length == 0) return \"\";\n\n        bytes memory table     = TABLE;\n        bytes memory result    = new bytes(4 * ((data.length + 2) / 3));\n        uint256      resultPtr = 0;\n\n        for (uint256 dataPtr = 0; dataPtr < data.length; dataPtr += 3) {\n            uint24 chunk = (                            (uint24(uint8(data[dataPtr + 0])) << 16))\n                         + (dataPtr + 1 < data.length ? (uint24(uint8(data[dataPtr + 1])) <<  8) : 0)\n                         + (dataPtr + 2 < data.length ? (uint24(uint8(data[dataPtr + 2]))      ) : 0);\n\n            result[resultPtr++] = table[uint8(chunk >> 18) & 0x3f];\n            result[resultPtr++] = table[uint8(chunk >> 12) & 0x3f];\n            result[resultPtr++] = table[uint8(chunk >>  6) & 0x3f];\n            result[resultPtr++] = table[uint8(chunk      ) & 0x3f];\n        }\n\n        if (data.length % 3 == 1) {\n            result[--resultPtr] = 0x3d;\n            result[--resultPtr] = 0x3d;\n        }\n        else if (data.length % 3 == 2) {\n            result[--resultPtr] = 0x3d;\n        }\n\n        return (string(result));\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/_prbmath/LICENSE.md",
    "content": "# WTFPL\n\nby Paul Razvan Berg (@PaulRBerg)\n\nTERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n0. You just DO WHAT THE FUCK YOU WANT TO.\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/_prbmath/PRBMathCommon.sol",
    "content": "// SPDX-License-Identifier: WTFPL\npragma solidity >=0.8.0;\n\n/// @dev Common mathematical functions used in both PRBMathSD59x18 and PRBMathUD60x18. Note that this shared library\n/// does not always assume the signed 59.18-decimal fixed-point or the unsigned 60.18-decimal fixed-point\n// representation. When it does not, it is annotated in the function's NatSpec documentation.\nlibrary PRBMathCommon {\n    /// @dev How many trailing decimals can be represented.\n    uint256 internal constant SCALE = 1e18;\n\n    /// @dev Largest power of two divisor of SCALE.\n    uint256 internal constant SCALE_LPOTD = 262144;\n\n    /// @dev SCALE inverted mod 2^256.\n    uint256 internal constant SCALE_INVERSE = 78156646155174841979727994598816262306175212592076161876661508869554232690281;\n\n    /// @notice Calculates the binary exponent of x using the binary fraction method.\n    /// @dev Uses 128.128-bit fixed-point numbers, which is the most efficient way.\n    /// See https://ethereum.stackexchange.com/a/96594/24693.\n    /// @param x The exponent as an unsigned 128.128-bit fixed-point number.\n    /// @return result The result as an unsigned 60x18 decimal fixed-point number.\n    function exp2(uint256 x) internal pure returns (uint256 result) {\n        unchecked {\n            // Start from 0.5 in the 128.128-bit fixed-point format.\n            result = 0x80000000000000000000000000000000;\n\n            // Multiply the result by root(2, 2^-i) when the bit at position i is 1. None of the intermediary results overflows\n            // because the initial result is 2^127 and all magic factors are less than 2^129.\n            if (x & 0x80000000000000000000000000000000 > 0) result = (result * 0x16A09E667F3BCC908B2FB1366EA957D3E) >> 128;\n            if (x & 0x40000000000000000000000000000000 > 0) result = (result * 0x1306FE0A31B7152DE8D5A46305C85EDED) >> 128;\n            if (x & 0x20000000000000000000000000000000 > 0) result = (result * 0x1172B83C7D517ADCDF7C8C50EB14A7920) >> 128;\n            if (x & 0x10000000000000000000000000000000 > 0) result = (result * 0x10B5586CF9890F6298B92B71842A98364) >> 128;\n            if (x & 0x8000000000000000000000000000000 > 0) result = (result * 0x1059B0D31585743AE7C548EB68CA417FE) >> 128;\n            if (x & 0x4000000000000000000000000000000 > 0) result = (result * 0x102C9A3E778060EE6F7CACA4F7A29BDE9) >> 128;\n            if (x & 0x2000000000000000000000000000000 > 0) result = (result * 0x10163DA9FB33356D84A66AE336DCDFA40) >> 128;\n            if (x & 0x1000000000000000000000000000000 > 0) result = (result * 0x100B1AFA5ABCBED6129AB13EC11DC9544) >> 128;\n            if (x & 0x800000000000000000000000000000 > 0) result = (result * 0x10058C86DA1C09EA1FF19D294CF2F679C) >> 128;\n            if (x & 0x400000000000000000000000000000 > 0) result = (result * 0x1002C605E2E8CEC506D21BFC89A23A011) >> 128;\n            if (x & 0x200000000000000000000000000000 > 0) result = (result * 0x100162F3904051FA128BCA9C55C31E5E0) >> 128;\n            if (x & 0x100000000000000000000000000000 > 0) result = (result * 0x1000B175EFFDC76BA38E31671CA939726) >> 128;\n            if (x & 0x80000000000000000000000000000 > 0) result = (result * 0x100058BA01FB9F96D6CACD4B180917C3E) >> 128;\n            if (x & 0x40000000000000000000000000000 > 0) result = (result * 0x10002C5CC37DA9491D0985C348C68E7B4) >> 128;\n            if (x & 0x20000000000000000000000000000 > 0) result = (result * 0x1000162E525EE054754457D5995292027) >> 128;\n            if (x & 0x10000000000000000000000000000 > 0) result = (result * 0x10000B17255775C040618BF4A4ADE83FD) >> 128;\n            if (x & 0x8000000000000000000000000000 > 0) result = (result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAC) >> 128;\n            if (x & 0x4000000000000000000000000000 > 0) result = (result * 0x100002C5C89D5EC6CA4D7C8ACC017B7CA) >> 128;\n            if (x & 0x2000000000000000000000000000 > 0) result = (result * 0x10000162E43F4F831060E02D839A9D16D) >> 128;\n            if (x & 0x1000000000000000000000000000 > 0) result = (result * 0x100000B1721BCFC99D9F890EA06911763) >> 128;\n            if (x & 0x800000000000000000000000000 > 0) result = (result * 0x10000058B90CF1E6D97F9CA14DBCC1629) >> 128;\n            if (x & 0x400000000000000000000000000 > 0) result = (result * 0x1000002C5C863B73F016468F6BAC5CA2C) >> 128;\n            if (x & 0x200000000000000000000000000 > 0) result = (result * 0x100000162E430E5A18F6119E3C02282A6) >> 128;\n            if (x & 0x100000000000000000000000000 > 0) result = (result * 0x1000000B1721835514B86E6D96EFD1BFF) >> 128;\n            if (x & 0x80000000000000000000000000 > 0) result = (result * 0x100000058B90C0B48C6BE5DF846C5B2F0) >> 128;\n            if (x & 0x40000000000000000000000000 > 0) result = (result * 0x10000002C5C8601CC6B9E94213C72737B) >> 128;\n            if (x & 0x20000000000000000000000000 > 0) result = (result * 0x1000000162E42FFF037DF38AA2B219F07) >> 128;\n            if (x & 0x10000000000000000000000000 > 0) result = (result * 0x10000000B17217FBA9C739AA5819F44FA) >> 128;\n            if (x & 0x8000000000000000000000000 > 0) result = (result * 0x1000000058B90BFCDEE5ACD3C1CEDC824) >> 128;\n            if (x & 0x4000000000000000000000000 > 0) result = (result * 0x100000002C5C85FE31F35A6A30DA1BE51) >> 128;\n            if (x & 0x2000000000000000000000000 > 0) result = (result * 0x10000000162E42FF0999CE3541B9FFFD0) >> 128;\n            if (x & 0x1000000000000000000000000 > 0) result = (result * 0x100000000B17217F80F4EF5AADDA45554) >> 128;\n            if (x & 0x800000000000000000000000 > 0) result = (result * 0x10000000058B90BFBF8479BD5A81B51AE) >> 128;\n            if (x & 0x400000000000000000000000 > 0) result = (result * 0x1000000002C5C85FDF84BD62AE30A74CD) >> 128;\n            if (x & 0x200000000000000000000000 > 0) result = (result * 0x100000000162E42FEFB2FED257559BDAA) >> 128;\n            if (x & 0x100000000000000000000000 > 0) result = (result * 0x1000000000B17217F7D5A7716BBA4A9AF) >> 128;\n            if (x & 0x80000000000000000000000 > 0) result = (result * 0x100000000058B90BFBE9DDBAC5E109CCF) >> 128;\n            if (x & 0x40000000000000000000000 > 0) result = (result * 0x10000000002C5C85FDF4B15DE6F17EB0E) >> 128;\n            if (x & 0x20000000000000000000000 > 0) result = (result * 0x1000000000162E42FEFA494F1478FDE05) >> 128;\n            if (x & 0x10000000000000000000000 > 0) result = (result * 0x10000000000B17217F7D20CF927C8E94D) >> 128;\n            if (x & 0x8000000000000000000000 > 0) result = (result * 0x1000000000058B90BFBE8F71CB4E4B33E) >> 128;\n            if (x & 0x4000000000000000000000 > 0) result = (result * 0x100000000002C5C85FDF477B662B26946) >> 128;\n            if (x & 0x2000000000000000000000 > 0) result = (result * 0x10000000000162E42FEFA3AE53369388D) >> 128;\n            if (x & 0x1000000000000000000000 > 0) result = (result * 0x100000000000B17217F7D1D351A389D41) >> 128;\n            if (x & 0x800000000000000000000 > 0) result = (result * 0x10000000000058B90BFBE8E8B2D3D4EDF) >> 128;\n            if (x & 0x400000000000000000000 > 0) result = (result * 0x1000000000002C5C85FDF4741BEA6E77F) >> 128;\n            if (x & 0x200000000000000000000 > 0) result = (result * 0x100000000000162E42FEFA39FE95583C3) >> 128;\n            if (x & 0x100000000000000000000 > 0) result = (result * 0x1000000000000B17217F7D1CFB72B45E3) >> 128;\n            if (x & 0x80000000000000000000 > 0) result = (result * 0x100000000000058B90BFBE8E7CC35C3F2) >> 128;\n            if (x & 0x40000000000000000000 > 0) result = (result * 0x10000000000002C5C85FDF473E242EA39) >> 128;\n            if (x & 0x20000000000000000000 > 0) result = (result * 0x1000000000000162E42FEFA39F02B772C) >> 128;\n            if (x & 0x10000000000000000000 > 0) result = (result * 0x10000000000000B17217F7D1CF7D83C1A) >> 128;\n            if (x & 0x8000000000000000000 > 0) result = (result * 0x1000000000000058B90BFBE8E7BDCBE2E) >> 128;\n            if (x & 0x4000000000000000000 > 0) result = (result * 0x100000000000002C5C85FDF473DEA871F) >> 128;\n            if (x & 0x2000000000000000000 > 0) result = (result * 0x10000000000000162E42FEFA39EF44D92) >> 128;\n            if (x & 0x1000000000000000000 > 0) result = (result * 0x100000000000000B17217F7D1CF79E949) >> 128;\n            if (x & 0x800000000000000000 > 0) result = (result * 0x10000000000000058B90BFBE8E7BCE545) >> 128;\n            if (x & 0x400000000000000000 > 0) result = (result * 0x1000000000000002C5C85FDF473DE6ECA) >> 128;\n            if (x & 0x200000000000000000 > 0) result = (result * 0x100000000000000162E42FEFA39EF366F) >> 128;\n            if (x & 0x100000000000000000 > 0) result = (result * 0x1000000000000000B17217F7D1CF79AFA) >> 128;\n            if (x & 0x80000000000000000 > 0) result = (result * 0x100000000000000058B90BFBE8E7BCD6E) >> 128;\n            if (x & 0x40000000000000000 > 0) result = (result * 0x10000000000000002C5C85FDF473DE6B3) >> 128;\n            if (x & 0x20000000000000000 > 0) result = (result * 0x1000000000000000162E42FEFA39EF359) >> 128;\n            if (x & 0x10000000000000000 > 0) result = (result * 0x10000000000000000B17217F7D1CF79AC) >> 128;\n\n            // We do two things at the same time below:\n            //\n            //     1. Multiply the result by 2^n + 1, where 2^n is the integer part and 1 is an extra bit to account\n            //        for the fact that we initially set the result to 0.5 We implement this by subtracting from 127\n            //        instead of 128.\n            //     2. Convert the result to the unsigned 60.18-decimal fixed-point format.\n            //\n            // This works because result * SCALE * 2^ip / 2^127 = result * SCALE / 2^(127 - ip), where ip is the integer\n            // part and SCALE / 2^128 is what converts the result to our unsigned fixed-point format.\n            result *= SCALE;\n            result >>= (127 - (x >> 128));\n        }\n    }\n\n    /// @notice Finds the zero-based index of the first one in the binary representation of x.\n    /// @dev See the note on msb in the \"Find First Set\" Wikipedia article https://en.wikipedia.org/wiki/Find_first_set\n    /// @param x The uint256 number for which to find the index of the most significant bit.\n    /// @return msb The index of the most significant bit as an uint256.\n    function mostSignificantBit(uint256 x) internal pure returns (uint256 msb) {\n        if (x >= 2**128) {\n            x >>= 128;\n            msb += 128;\n        }\n        if (x >= 2**64) {\n            x >>= 64;\n            msb += 64;\n        }\n        if (x >= 2**32) {\n            x >>= 32;\n            msb += 32;\n        }\n        if (x >= 2**16) {\n            x >>= 16;\n            msb += 16;\n        }\n        if (x >= 2**8) {\n            x >>= 8;\n            msb += 8;\n        }\n        if (x >= 2**4) {\n            x >>= 4;\n            msb += 4;\n        }\n        if (x >= 2**2) {\n            x >>= 2;\n            msb += 2;\n        }\n        if (x >= 2**1) {\n            // No need to shift x any more.\n            msb += 1;\n        }\n    }\n\n    /// @notice Calculates floor(x*y÷denominator) with full precision.\n    ///\n    /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n    ///\n    /// Requirements:\n    /// - The denominator cannot be zero.\n    /// - The result must fit within uint256.\n    ///\n    /// Caveats:\n    /// - This function does not work with fixed-point numbers.\n    ///\n    /// @param x The multiplicand as an uint256.\n    /// @param y The multiplier as an uint256.\n    /// @param denominator The divisor as an uint256.\n    /// @return result The result as an uint256.\n    function mulDiv(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 result) {\n        // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2**256 and mod 2**256 - 1, then use\n        // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n        // variables such that product = prod1 * 2**256 + prod0.\n        uint256 prod0; // Least significant 256 bits of the product\n        uint256 prod1; // Most significant 256 bits of the product\n        assembly {\n            let mm := mulmod(x, y, not(0))\n            prod0 := mul(x, y)\n            prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n        }\n\n        // Handle non-overflow cases, 256 by 256 division\n        if (prod1 == 0) {\n            require(denominator > 0);\n            assembly {\n                result := div(prod0, denominator)\n            }\n            return result;\n        }\n\n        // Make sure the result is less than 2**256. Also prevents denominator == 0.\n        require(denominator > prod1);\n\n        ///////////////////////////////////////////////\n        // 512 by 256 division.\n        ///////////////////////////////////////////////\n\n        // Make division exact by subtracting the remainder from [prod1 prod0].\n        uint256 remainder;\n        assembly {\n            // Compute remainder using mulmod.\n            remainder := mulmod(x, y, denominator)\n\n            // Subtract 256 bit number from 512 bit number\n            prod1 := sub(prod1, gt(remainder, prod0))\n            prod0 := sub(prod0, remainder)\n        }\n\n        // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n        // See https://cs.stackexchange.com/q/138556/92363.\n        unchecked {\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 lpotdod = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by lpotdod.\n                denominator := div(denominator, lpotdod)\n\n                // Divide [prod1 prod0] by lpotdod.\n                prod0 := div(prod0, lpotdod)\n\n                // Flip lpotdod such that it is 2**256 / lpotdod. If lpotdod is zero, then it becomes one.\n                lpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * lpotdod;\n\n            // Invert denominator mod 2**256. Now that denominator is an odd number, it has an inverse modulo 2**256 such\n            // that denominator * inv = 1 mod 2**256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2**4\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Now use Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2**8\n            inverse *= 2 - denominator * inverse; // inverse mod 2**16\n            inverse *= 2 - denominator * inverse; // inverse mod 2**32\n            inverse *= 2 - denominator * inverse; // inverse mod 2**64\n            inverse *= 2 - denominator * inverse; // inverse mod 2**128\n            inverse *= 2 - denominator * inverse; // inverse mod 2**256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2**256. Since the precoditions guarantee that the outcome is\n            // less than 2**256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /// @notice Calculates floor(x*y÷1e18) with full precision.\n    ///\n    /// @dev Variant of \"mulDiv\" with constant folding, i.e. in which the denominator is always 1e18. Before returning the\n    /// final result, we add 1 if (x * y) % SCALE >= HALF_SCALE. Without this, 6.6e-19 would be truncated to 0 instead of\n    /// being rounded to 1e-18.  See \"Listing 6\" and text above it at https://accu.org/index.php/journals/1717.\n    ///\n    /// Requirements:\n    /// - The result must fit within uint256.\n    ///\n    /// Caveats:\n    /// - The body is purposely left uncommented; see the NatSpec comments in \"PRBMathCommon.mulDiv\" to understand how this works.\n    /// - It is assumed that the result can never be type(uint256).max when x and y solve the following two equations:\n    ///     1. x * y = type(uint256).max * SCALE\n    ///     2. (x * y) % SCALE >= SCALE / 2\n    ///\n    /// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n    /// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n    /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n    function mulDivFixedPoint(uint256 x, uint256 y) internal pure returns (uint256 result) {\n        uint256 prod0;\n        uint256 prod1;\n        assembly {\n            let mm := mulmod(x, y, not(0))\n            prod0 := mul(x, y)\n            prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n        }\n\n        uint256 remainder;\n        uint256 roundUpUnit;\n        assembly {\n            remainder := mulmod(x, y, SCALE)\n            roundUpUnit := gt(remainder, 499999999999999999)\n        }\n\n        if (prod1 == 0) {\n            unchecked {\n                result = (prod0 / SCALE) + roundUpUnit;\n                return result;\n            }\n        }\n\n        require(SCALE > prod1);\n\n        assembly {\n            result := add(\n                mul(\n                    or(\n                        div(sub(prod0, remainder), SCALE_LPOTD),\n                        mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, SCALE_LPOTD), SCALE_LPOTD), 1))\n                    ),\n                    SCALE_INVERSE\n                ),\n                roundUpUnit\n            )\n        }\n    }\n\n    /// @notice Calculates the square root of x, rounding down.\n    /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n    ///\n    /// Caveats:\n    /// - This function does not work with fixed-point numbers.\n    ///\n    /// @param x The uint256 number for which to calculate the square root.\n    /// @return result The result as an uint256.\n    function sqrt(uint256 x) internal pure returns (uint256 result) {\n        if (x == 0) {\n            return 0;\n        }\n\n        // Calculate the square root of the perfect square of a power of two that is the closest to x.\n        uint256 xAux = uint256(x);\n        result = 1;\n        if (xAux >= 0x100000000000000000000000000000000) {\n            xAux >>= 128;\n            result <<= 64;\n        }\n        if (xAux >= 0x10000000000000000) {\n            xAux >>= 64;\n            result <<= 32;\n        }\n        if (xAux >= 0x100000000) {\n            xAux >>= 32;\n            result <<= 16;\n        }\n        if (xAux >= 0x10000) {\n            xAux >>= 16;\n            result <<= 8;\n        }\n        if (xAux >= 0x100) {\n            xAux >>= 8;\n            result <<= 4;\n        }\n        if (xAux >= 0x10) {\n            xAux >>= 4;\n            result <<= 2;\n        }\n        if (xAux >= 0x8) {\n            result <<= 1;\n        }\n\n        // The operations can never overflow because the result is max 2^127 when it enters this block.\n        unchecked {\n            result = (result + x / result) >> 1;\n            result = (result + x / result) >> 1;\n            result = (result + x / result) >> 1;\n            result = (result + x / result) >> 1;\n            result = (result + x / result) >> 1;\n            result = (result + x / result) >> 1;\n            result = (result + x / result) >> 1; // Seven iterations should be enough\n            uint256 roundedDownResult = x / result;\n            return result >= roundedDownResult ? roundedDownResult : result;\n        }\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/_prbmath/PRBMathSD59x18.sol",
    "content": "// SPDX-License-Identifier: WTFPL\npragma solidity >=0.8.0;\n\nimport \"./PRBMathCommon.sol\";\n\n/// @title PRBMathSD59x18\n/// @author Paul Razvan Berg\n/// @notice Smart contract library for advanced fixed-point math. It works with int256 numbers considered to have 18\n/// trailing decimals. We call this number representation signed 59.18-decimal fixed-point, since the numbers can have\n/// a sign and there can be up to 59 digits in the integer part and up to 18 decimals in the fractional part. The numbers\n/// are bound by the minimum and the maximum values permitted by the Solidity type int256.\nlibrary PRBMathSD59x18 {\n    /// @dev log2(e) as a signed 59.18-decimal fixed-point number.\n    int256 internal constant LOG2_E = 1442695040888963407;\n\n    /// @dev Half the SCALE number.\n    int256 internal constant HALF_SCALE = 5e17;\n\n    /// @dev The maximum value a signed 59.18-decimal fixed-point number can have.\n    int256 internal constant MAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728792003956564819967;\n\n    /// @dev The maximum whole value a signed 59.18-decimal fixed-point number can have.\n    int256 internal constant MAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728000000000000000000;\n\n    /// @dev The minimum value a signed 59.18-decimal fixed-point number can have.\n    int256 internal constant MIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n    /// @dev The minimum whole value a signed 59.18-decimal fixed-point number can have.\n    int256 internal constant MIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728000000000000000000;\n\n    /// @dev How many trailing decimals can be represented.\n    int256 internal constant SCALE = 1e18;\n\n    /// INTERNAL FUNCTIONS ///\n\n    /// @notice Calculate the absolute value of x.\n    ///\n    /// @dev Requirements:\n    /// - x must be greater than MIN_SD59x18.\n    ///\n    /// @param x The number to calculate the absolute value for.\n    /// @param result The absolute value of x.\n    function abs(int256 x) internal pure returns (int256 result) {\n        unchecked {\n            require(x > MIN_SD59x18);\n            result = x < 0 ? -x : x;\n        }\n    }\n\n    /// @notice Calculates arithmetic average of x and y, rounding down.\n    /// @param x The first operand as a signed 59.18-decimal fixed-point number.\n    /// @param y The second operand as a signed 59.18-decimal fixed-point number.\n    /// @return result The arithmetic average as a signed 59.18-decimal fixed-point number.\n    function avg(int256 x, int256 y) internal pure returns (int256 result) {\n        // The operations can never overflow.\n        unchecked {\n            // The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need\n            // to do this because if both numbers are odd, the 0.5 remainder gets truncated twice.\n            result = (x >> 1) + (y >> 1) + (x & y & 1);\n        }\n    }\n\n    /// @notice Yields the least greatest signed 59.18 decimal fixed-point number greater than or equal to x.\n    ///\n    /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n    /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n    ///\n    /// Requirements:\n    /// - x must be less than or equal to MAX_WHOLE_SD59x18.\n    ///\n    /// @param x The signed 59.18-decimal fixed-point number to ceil.\n    /// @param result The least integer greater than or equal to x, as a signed 58.18-decimal fixed-point number.\n    function ceil(int256 x) internal pure returns (int256 result) {\n        require(x <= MAX_WHOLE_SD59x18);\n        unchecked {\n            int256 remainder = x % SCALE;\n            if (remainder == 0) {\n                result = x;\n            } else {\n                // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n                result = x - remainder;\n                if (x > 0) {\n                    result += SCALE;\n                }\n            }\n        }\n    }\n\n    /// @notice Divides two signed 59.18-decimal fixed-point numbers, returning a new signed 59.18-decimal fixed-point number.\n    ///\n    /// @dev Variant of \"mulDiv\" that works with signed numbers. Works by computing the signs and the absolute values separately.\n    ///\n    /// Requirements:\n    /// - All from \"PRBMathCommon.mulDiv\".\n    /// - None of the inputs can be type(int256).min.\n    /// - y cannot be zero.\n    /// - The result must fit within int256.\n    ///\n    /// Caveats:\n    /// - All from \"PRBMathCommon.mulDiv\".\n    ///\n    /// @param x The numerator as a signed 59.18-decimal fixed-point number.\n    /// @param y The denominator as a signed 59.18-decimal fixed-point number.\n    /// @param result The quotient as a signed 59.18-decimal fixed-point number.\n    function div(int256 x, int256 y) internal pure returns (int256 result) {\n        require(x > type(int256).min);\n        require(y > type(int256).min);\n\n        // Get hold of the absolute values of x and y.\n        uint256 ax;\n        uint256 ay;\n        unchecked {\n            ax = x < 0 ? uint256(-x) : uint256(x);\n            ay = y < 0 ? uint256(-y) : uint256(y);\n        }\n\n        // Compute the absolute value of (x*SCALE)÷y. The result must fit within int256.\n        uint256 resultUnsigned = PRBMathCommon.mulDiv(ax, uint256(SCALE), ay);\n        require(resultUnsigned <= uint256(type(int256).max));\n\n        // Get the signs of x and y.\n        uint256 sx;\n        uint256 sy;\n        assembly {\n            sx := sgt(x, sub(0, 1))\n            sy := sgt(y, sub(0, 1))\n        }\n\n        // XOR over sx and sy. This is basically checking whether the inputs have the same sign. If yes, the result\n        // should be positive. Otherwise, it should be negative.\n        result = sx ^ sy == 1 ? -int256(resultUnsigned) : int256(resultUnsigned);\n    }\n\n    /// @notice Returns Euler's number as a signed 59.18-decimal fixed-point number.\n    /// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant).\n    function e() internal pure returns (int256 result) {\n        result = 2718281828459045235;\n    }\n\n    /// @notice Calculates the natural exponent of x.\n    ///\n    /// @dev Based on the insight that e^x = 2^(x * log2(e)).\n    ///\n    /// Requirements:\n    /// - All from \"log2\".\n    /// - x must be less than 88722839111672999628.\n    ///\n    /// @param x The exponent as a signed 59.18-decimal fixed-point number.\n    /// @return result The result as a signed 59.18-decimal fixed-point number.\n    function exp(int256 x) internal pure returns (int256 result) {\n        // Without this check, the value passed to \"exp2\" would be less than -59794705707972522261.\n        if (x < -41446531673892822322) {\n            return 0;\n        }\n\n        // Without this check, the value passed to \"exp2\" would be greater than 128e18.\n        require(x < 88722839111672999628);\n\n        // Do the fixed-point multiplication inline to save gas.\n        unchecked {\n            int256 doubleScaleProduct = x * LOG2_E;\n            result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE);\n        }\n    }\n\n    /// @notice Calculates the binary exponent of x using the binary fraction method.\n    ///\n    /// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n    ///\n    /// Requirements:\n    /// - x must be 128e18 or less.\n    /// - The result must fit within MAX_SD59x18.\n    ///\n    /// Caveats:\n    /// - For any x less than -59794705707972522261, the result is zero.\n    ///\n    /// @param x The exponent as a signed 59.18-decimal fixed-point number.\n    /// @return result The result as a signed 59.18-decimal fixed-point number.\n    function exp2(int256 x) internal pure returns (int256 result) {\n        // This works because 2^(-x) = 1/2^x.\n        if (x < 0) {\n            // 2**59.794705707972522262 is the maximum number whose inverse does not turn into zero.\n            if (x < -59794705707972522261) {\n                return 0;\n            }\n\n            // Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE.\n            unchecked { result = 1e36 / exp2(-x); }\n        } else {\n            // 2**128 doesn't fit within the 128.128-bit fixed-point representation.\n            require(x < 128e18);\n\n            unchecked {\n                // Convert x to the 128.128-bit fixed-point format.\n                uint256 x128x128 = (uint256(x) << 128) / uint256(SCALE);\n\n                // Safe to convert the result to int256 directly because the maximum input allowed is 128e18.\n                result = int256(PRBMathCommon.exp2(x128x128));\n            }\n        }\n    }\n\n    /// @notice Yields the greatest signed 59.18 decimal fixed-point number less than or equal to x.\n    ///\n    /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n    /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n    ///\n    /// Requirements:\n    /// - x must be greater than or equal to MIN_WHOLE_SD59x18.\n    ///\n    /// @param x The signed 59.18-decimal fixed-point number to floor.\n    /// @param result The greatest integer less than or equal to x, as a signed 58.18-decimal fixed-point number.\n    function floor(int256 x) internal pure returns (int256 result) {\n        require(x >= MIN_WHOLE_SD59x18);\n        unchecked {\n            int256 remainder = x % SCALE;\n            if (remainder == 0) {\n                result = x;\n            } else {\n                // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n                result = x - remainder;\n                if (x < 0) {\n                    result -= SCALE;\n                }\n            }\n        }\n    }\n\n    /// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right\n    /// of the radix point for negative numbers.\n    /// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n    /// @param x The signed 59.18-decimal fixed-point number to get the fractional part of.\n    /// @param result The fractional part of x as a signed 59.18-decimal fixed-point number.\n    function frac(int256 x) internal pure returns (int256 result) {\n        unchecked { result = x % SCALE; }\n    }\n\n    /// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down.\n    ///\n    /// @dev Requirements:\n    /// - x * y must fit within MAX_SD59x18, lest it overflows.\n    /// - x * y cannot be negative.\n    ///\n    /// @param x The first operand as a signed 59.18-decimal fixed-point number.\n    /// @param y The second operand as a signed 59.18-decimal fixed-point number.\n    /// @return result The result as a signed 59.18-decimal fixed-point number.\n    function gm(int256 x, int256 y) internal pure returns (int256 result) {\n        if (x == 0) {\n            return 0;\n        }\n\n        unchecked {\n            // Checking for overflow this way is faster than letting Solidity do it.\n            int256 xy = x * y;\n            require(xy / x == y);\n\n            // The product cannot be negative.\n            require(xy >= 0);\n\n            // We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE\n            // during multiplication. See the comments within the \"sqrt\" function.\n            result = int256(PRBMathCommon.sqrt(uint256(xy)));\n        }\n    }\n\n    /// @notice Calculates 1 / x, rounding towards zero.\n    ///\n    /// @dev Requirements:\n    /// - x cannot be zero.\n    ///\n    /// @param x The signed 59.18-decimal fixed-point number for which to calculate the inverse.\n    /// @return result The inverse as a signed 59.18-decimal fixed-point number.\n    function inv(int256 x) internal pure returns (int256 result) {\n        unchecked {\n            // 1e36 is SCALE * SCALE.\n            result = 1e36 / x;\n        }\n    }\n\n    /// @notice Calculates the natural logarithm of x.\n    ///\n    /// @dev Based on the insight that ln(x) = log2(x) / log2(e).\n    ///\n    /// Requirements:\n    /// - All from \"log2\".\n    ///\n    /// Caveats:\n    /// - All from \"log2\".\n    /// - This doesn't return exactly 1 for 2718281828459045235, for that we would need more fine-grained precision.\n    ///\n    /// @param x The signed 59.18-decimal fixed-point number for which to calculate the natural logarithm.\n    /// @return result The natural logarithm as a signed 59.18-decimal fixed-point number.\n    function ln(int256 x) internal pure returns (int256 result) {\n        // Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x)\n        // can return is 195205294292027477728.\n        unchecked { result = (log2(x) * SCALE) / LOG2_E; }\n    }\n\n    /// @notice Calculates the common logarithm of x.\n    ///\n    /// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common\n    /// logarithm based on the insight that log10(x) = log2(x) / log2(10).\n    ///\n    /// Requirements:\n    /// - All from \"log2\".\n    ///\n    /// Caveats:\n    /// - All from \"log2\".\n    ///\n    /// @param x The signed 59.18-decimal fixed-point number for which to calculate the common logarithm.\n    /// @return result The common logarithm as a signed 59.18-decimal fixed-point number.\n    function log10(int256 x) internal pure returns (int256 result) {\n        require(x > 0);\n\n        // Note that the \"mul\" in this block is the assembly mul operation, not the \"mul\" function defined in this contract.\n        // prettier-ignore\n        assembly {\n            switch x\n            case 1 { result := mul(SCALE, sub(0, 18)) }\n            case 10 { result := mul(SCALE, sub(1, 18)) }\n            case 100 { result := mul(SCALE, sub(2, 18)) }\n            case 1000 { result := mul(SCALE, sub(3, 18)) }\n            case 10000 { result := mul(SCALE, sub(4, 18)) }\n            case 100000 { result := mul(SCALE, sub(5, 18)) }\n            case 1000000 { result := mul(SCALE, sub(6, 18)) }\n            case 10000000 { result := mul(SCALE, sub(7, 18)) }\n            case 100000000 { result := mul(SCALE, sub(8, 18)) }\n            case 1000000000 { result := mul(SCALE, sub(9, 18)) }\n            case 10000000000 { result := mul(SCALE, sub(10, 18)) }\n            case 100000000000 { result := mul(SCALE, sub(11, 18)) }\n            case 1000000000000 { result := mul(SCALE, sub(12, 18)) }\n            case 10000000000000 { result := mul(SCALE, sub(13, 18)) }\n            case 100000000000000 { result := mul(SCALE, sub(14, 18)) }\n            case 1000000000000000 { result := mul(SCALE, sub(15, 18)) }\n            case 10000000000000000 { result := mul(SCALE, sub(16, 18)) }\n            case 100000000000000000 { result := mul(SCALE, sub(17, 18)) }\n            case 1000000000000000000 { result := 0 }\n            case 10000000000000000000 { result := SCALE }\n            case 100000000000000000000 { result := mul(SCALE, 2) }\n            case 1000000000000000000000 { result := mul(SCALE, 3) }\n            case 10000000000000000000000 { result := mul(SCALE, 4) }\n            case 100000000000000000000000 { result := mul(SCALE, 5) }\n            case 1000000000000000000000000 { result := mul(SCALE, 6) }\n            case 10000000000000000000000000 { result := mul(SCALE, 7) }\n            case 100000000000000000000000000 { result := mul(SCALE, 8) }\n            case 1000000000000000000000000000 { result := mul(SCALE, 9) }\n            case 10000000000000000000000000000 { result := mul(SCALE, 10) }\n            case 100000000000000000000000000000 { result := mul(SCALE, 11) }\n            case 1000000000000000000000000000000 { result := mul(SCALE, 12) }\n            case 10000000000000000000000000000000 { result := mul(SCALE, 13) }\n            case 100000000000000000000000000000000 { result := mul(SCALE, 14) }\n            case 1000000000000000000000000000000000 { result := mul(SCALE, 15) }\n            case 10000000000000000000000000000000000 { result := mul(SCALE, 16) }\n            case 100000000000000000000000000000000000 { result := mul(SCALE, 17) }\n            case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) }\n            case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) }\n            case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) }\n            case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) }\n            case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) }\n            case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) }\n            case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) }\n            case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) }\n            case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) }\n            case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) }\n            case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) }\n            case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) }\n            case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) }\n            case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) }\n            case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) }\n            case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) }\n            case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) }\n            case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) }\n            case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) }\n            case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) }\n            case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) }\n            case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) }\n            case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) }\n            case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) }\n            case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) }\n            case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) }\n            case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) }\n            case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) }\n            case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) }\n            case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) }\n            case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) }\n            case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) }\n            case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) }\n            case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) }\n            case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) }\n            case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) }\n            case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) }\n            case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) }\n            case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) }\n            case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) }\n            case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) }\n            default {\n                result := MAX_SD59x18\n            }\n        }\n\n        if (result == MAX_SD59x18) {\n            // Do the fixed-point division inline to save gas. The denominator is log2(10).\n            unchecked { result = (log2(x) * SCALE) / 332192809488736234; }\n        }\n    }\n\n    /// @notice Calculates the binary logarithm of x.\n    ///\n    /// @dev Based on the iterative approximation algorithm.\n    /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n    ///\n    /// Requirements:\n    /// - x must be greater than zero.\n    ///\n    /// Caveats:\n    /// - The results are nor perfectly accurate to the last digit, due to the lossy precision of the iterative approximation.\n    ///\n    /// @param x The signed 59.18-decimal fixed-point number for which to calculate the binary logarithm.\n    /// @return result The binary logarithm as a signed 59.18-decimal fixed-point number.\n    function log2(int256 x) internal pure returns (int256 result) {\n        require(x > 0);\n        unchecked {\n            // This works because log2(x) = -log2(1/x).\n            int256 sign;\n            if (x >= SCALE) {\n                sign = 1;\n            } else {\n                sign = -1;\n                // Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE.\n                assembly {\n                    x := div(1000000000000000000000000000000000000, x)\n                }\n            }\n\n            // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n).\n            uint256 n = PRBMathCommon.mostSignificantBit(uint256(x / SCALE));\n\n            // The integer part of the logarithm as a signed 59.18-decimal fixed-point number. The operation can't overflow\n            // because n is maximum 255, SCALE is 1e18 and sign is either 1 or -1.\n            result = int256(n) * SCALE;\n\n            // This is y = x * 2^(-n).\n            int256 y = x >> n;\n\n            // If y = 1, the fractional part is zero.\n            if (y == SCALE) {\n                return result * sign;\n            }\n\n            // Calculate the fractional part via the iterative approximation.\n            // The \"delta >>= 1\" part is equivalent to \"delta /= 2\", but shifting bits is faster.\n            for (int256 delta = int256(HALF_SCALE); delta > 0; delta >>= 1) {\n                y = (y * y) / SCALE;\n\n                // Is y^2 > 2 and so in the range [2,4)?\n                if (y >= 2 * SCALE) {\n                    // Add the 2^(-m) factor to the logarithm.\n                    result += delta;\n\n                    // Corresponds to z/2 on Wikipedia.\n                    y >>= 1;\n                }\n            }\n            result *= sign;\n        }\n    }\n\n    /// @notice Multiplies two signed 59.18-decimal fixed-point numbers together, returning a new signed 59.18-decimal\n    /// fixed-point number.\n    ///\n    /// @dev Variant of \"mulDiv\" that works with signed numbers and employs constant folding, i.e. the denominator is\n    /// alawys 1e18.\n    ///\n    /// Requirements:\n    /// - All from \"PRBMathCommon.mulDivFixedPoint\".\n    /// - The result must fit within MAX_SD59x18.\n    ///\n    /// Caveats:\n    /// - The body is purposely left uncommented; see the NatSpec comments in \"PRBMathCommon.mulDiv\" to understand how this works.\n    ///\n    /// @param x The multiplicand as a signed 59.18-decimal fixed-point number.\n    /// @param y The multiplier as a signed 59.18-decimal fixed-point number.\n    /// @return result The result as a signed 59.18-decimal fixed-point number.\n    function mul(int256 x, int256 y) internal pure returns (int256 result) {\n        require(x > MIN_SD59x18);\n        require(y > MIN_SD59x18);\n\n        unchecked {\n            uint256 ax;\n            uint256 ay;\n            ax = x < 0 ? uint256(-x) : uint256(x);\n            ay = y < 0 ? uint256(-y) : uint256(y);\n\n            uint256 resultUnsigned = PRBMathCommon.mulDivFixedPoint(ax, ay);\n            require(resultUnsigned <= uint256(MAX_SD59x18));\n\n            uint256 sx;\n            uint256 sy;\n            assembly {\n                sx := sgt(x, sub(0, 1))\n                sy := sgt(y, sub(0, 1))\n            }\n            result = sx ^ sy == 1 ? -int256(resultUnsigned) : int256(resultUnsigned);\n        }\n    }\n\n    /// @notice Retrieves PI as a signed 59.18-decimal fixed-point number.\n    function pi() internal pure returns (int256 result) {\n        result = 3141592653589793238;\n    }\n\n    /// @notice Raises x (signed 59.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the\n    /// famous algorithm \"exponentiation by squaring\".\n    ///\n    /// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring\n    ///\n    /// Requirements:\n    /// - All from \"abs\" and \"PRBMathCommon.mulDivFixedPoint\".\n    /// - The result must fit within MAX_SD59x18.\n    ///\n    /// Caveats:\n    /// - All from \"PRBMathCommon.mulDivFixedPoint\".\n    /// - Assumes 0^0 is 1.\n    ///\n    /// @param x The base as a signed 59.18-decimal fixed-point number.\n    /// @param y The exponent as an uint256.\n    /// @return result The result as a signed 59.18-decimal fixed-point number.\n    function pow(int256 x, uint256 y) internal pure returns (int256 result) {\n        uint256 absX = uint256(abs(x));\n\n        // Calculate the first iteration of the loop in advance.\n        uint256 absResult = y & 1 > 0 ? absX : uint256(SCALE);\n\n        // Equivalent to \"for(y /= 2; y > 0; y /= 2)\" but faster.\n        for (y >>= 1; y > 0; y >>= 1) {\n            absX = PRBMathCommon.mulDivFixedPoint(absX, absX);\n\n            // Equivalent to \"y % 2 == 1\" but faster.\n            if (y & 1 > 0) {\n                absResult = PRBMathCommon.mulDivFixedPoint(absResult, absX);\n            }\n        }\n\n        // The result must fit within the 59.18-decimal fixed-point representation.\n        require(absResult <= uint256(MAX_SD59x18));\n\n        // Is the base negative and the exponent an odd number?\n        bool isNegative = x < 0 && y & 1 == 1;\n        result = isNegative ? -int256(absResult) : int256(absResult);\n    }\n\n    /// @notice Returns 1 as a signed 59.18-decimal fixed-point number.\n    function scale() internal pure returns (int256 result) {\n        result = SCALE;\n    }\n\n    /// @notice Calculates the square root of x, rounding down.\n    /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n    ///\n    /// Requirements:\n    /// - x cannot be negative.\n    /// - x must be less than MAX_SD59x18 / SCALE.\n    ///\n    /// Caveats:\n    /// - The maximum fixed-point number permitted is 57896044618658097711785492504343953926634.992332820282019729.\n    ///\n    /// @param x The signed 59.18-decimal fixed-point number for which to calculate the square root.\n    /// @return result The result as a signed 59.18-decimal fixed-point .\n    function sqrt(int256 x) internal pure returns (int256 result) {\n        require(x >= 0);\n        require(x < 57896044618658097711785492504343953926634992332820282019729);\n        unchecked {\n            // Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two signed\n            // 59.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root).\n            result = int256(PRBMathCommon.sqrt(uint256(x * SCALE)));\n        }\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/_prbmath/PRBMathUD60x18.sol",
    "content": "// SPDX-License-Identifier: WTFPL\npragma solidity >=0.8.0;\n\nimport \"./PRBMathCommon.sol\";\n\n/// @title PRBMathUD60x18\n/// @author Paul Razvan Berg\n/// @notice Smart contract library for advanced fixed-point math. It works with uint256 numbers considered to have 18\n/// trailing decimals. We call this number representation unsigned 60.18-decimal fixed-point, since there can be up to 60\n/// digits in the integer part and up to 18 decimals in the fractional part. The numbers are bound by the minimum and the\n/// maximum values permitted by the Solidity type uint256.\nlibrary PRBMathUD60x18 {\n    /// @dev Half the SCALE number.\n    uint256 internal constant HALF_SCALE = 5e17;\n\n    /// @dev log2(e) as an unsigned 60.18-decimal fixed-point number.\n    uint256 internal constant LOG2_E = 1442695040888963407;\n\n    /// @dev The maximum value an unsigned 60.18-decimal fixed-point number can have.\n    uint256 internal constant MAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n    /// @dev The maximum whole value an unsigned 60.18-decimal fixed-point number can have.\n    uint256 internal constant MAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457000000000000000000;\n\n    /// @dev How many trailing decimals can be represented.\n    uint256 internal constant SCALE = 1e18;\n\n    /// @notice Calculates arithmetic average of x and y, rounding down.\n    /// @param x The first operand as an unsigned 60.18-decimal fixed-point number.\n    /// @param y The second operand as an unsigned 60.18-decimal fixed-point number.\n    /// @return result The arithmetic average as an unsigned 60.18-decimal fixed-point number.\n    function avg(uint256 x, uint256 y) internal pure returns (uint256 result) {\n        // The operations can never overflow.\n        unchecked {\n            // The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need\n            // to do this because if both numbers are odd, the 0.5 remainder gets truncated twice.\n            result = (x >> 1) + (y >> 1) + (x & y & 1);\n        }\n    }\n\n    /// @notice Yields the least unsigned 60.18 decimal fixed-point number greater than or equal to x.\n    ///\n    /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n    /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n    ///\n    /// Requirements:\n    /// - x must be less than or equal to MAX_WHOLE_UD60x18.\n    ///\n    /// @param x The unsigned 60.18-decimal fixed-point number to ceil.\n    /// @param result The least integer greater than or equal to x, as an unsigned 60.18-decimal fixed-point number.\n    function ceil(uint256 x) internal pure returns (uint256 result) {\n        require(x <= MAX_WHOLE_UD60x18);\n        assembly {\n            // Equivalent to \"x % SCALE\" but faster.\n            let remainder := mod(x, SCALE)\n\n            // Equivalent to \"SCALE - remainder\" but faster.\n            let delta := sub(SCALE, remainder)\n\n            // Equivalent to \"x + delta * (remainder > 0 ? 1 : 0)\" but faster.\n            result := add(x, mul(delta, gt(remainder, 0)))\n        }\n    }\n\n    /// @notice Divides two unsigned 60.18-decimal fixed-point numbers, returning a new unsigned 60.18-decimal fixed-point number.\n    ///\n    /// @dev Uses mulDiv to enable overflow-safe multiplication and division.\n    ///\n    /// Requirements:\n    /// - y cannot be zero.\n    ///\n    /// @param x The numerator as an unsigned 60.18-decimal fixed-point number.\n    /// @param y The denominator as an unsigned 60.18-decimal fixed-point number.\n    /// @param result The quotient as an unsigned 60.18-decimal fixed-point number.\n    function div(uint256 x, uint256 y) internal pure returns (uint256 result) {\n        result = PRBMathCommon.mulDiv(x, SCALE, y);\n    }\n\n    /// @notice Returns Euler's number as an unsigned 60.18-decimal fixed-point number.\n    /// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant).\n    function e() internal pure returns (uint256 result) {\n        result = 2718281828459045235;\n    }\n\n    /// @notice Calculates the natural exponent of x.\n    ///\n    /// @dev Based on the insight that e^x = 2^(x * log2(e)).\n    ///\n    /// Requirements:\n    /// - All from \"log2\".\n    /// - x must be less than 88722839111672999628.\n    ///\n    /// @param x The exponent as an unsigned 60.18-decimal fixed-point number.\n    /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n    function exp(uint256 x) internal pure returns (uint256 result) {\n        // Without this check, the value passed to \"exp2\" would be greater than 128e18.\n        require(x < 88722839111672999628);\n\n        // Do the fixed-point multiplication inline to save gas.\n        unchecked {\n            uint256 doubleScaleProduct = x * LOG2_E;\n            result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE);\n        }\n    }\n\n    /// @notice Calculates the binary exponent of x using the binary fraction method.\n    ///\n    /// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n    ///\n    /// Requirements:\n    /// - x must be 128e18 or less.\n    /// - The result must fit within MAX_UD60x18.\n    ///\n    /// @param x The exponent as an unsigned 60.18-decimal fixed-point number.\n    /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n    function exp2(uint256 x) internal pure returns (uint256 result) {\n        // 2**128 doesn't fit within the 128.128-bit format used internally in this function.\n        require(x < 128e18);\n\n        unchecked {\n            // Convert x to the 128.128-bit fixed-point format.\n            uint256 x128x128 = (x << 128) / SCALE;\n\n            // Pass x to the PRBMathCommon.exp2 function, which uses the 128.128-bit fixed-point number representation.\n            result = PRBMathCommon.exp2(x128x128);\n        }\n    }\n\n    /// @notice Yields the greatest unsigned 60.18 decimal fixed-point number less than or equal to x.\n    /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n    /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n    /// @param x The unsigned 60.18-decimal fixed-point number to floor.\n    /// @param result The greatest integer less than or equal to x, as an unsigned 60.18-decimal fixed-point number.\n    function floor(uint256 x) internal pure returns (uint256 result) {\n        assembly {\n            // Equivalent to \"x % SCALE\" but faster.\n            let remainder := mod(x, SCALE)\n\n            // Equivalent to \"x - remainder * (remainder > 0 ? 1 : 0)\" but faster.\n            result := sub(x, mul(remainder, gt(remainder, 0)))\n        }\n    }\n\n    /// @notice Yields the excess beyond the floor of x.\n    /// @dev Based on the odd function definition https://en.wikipedia.org/wiki/Fractional_part.\n    /// @param x The unsigned 60.18-decimal fixed-point number to get the fractional part of.\n    /// @param result The fractional part of x as an unsigned 60.18-decimal fixed-point number.\n    function frac(uint256 x) internal pure returns (uint256 result) {\n        assembly {\n            result := mod(x, SCALE)\n        }\n    }\n\n    /// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down.\n    ///\n    /// @dev Requirements:\n    /// - x * y must fit within MAX_UD60x18, lest it overflows.\n    ///\n    /// @param x The first operand as an unsigned 60.18-decimal fixed-point number.\n    /// @param y The second operand as an unsigned 60.18-decimal fixed-point number.\n    /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n    function gm(uint256 x, uint256 y) internal pure returns (uint256 result) {\n        if (x == 0) {\n            return 0;\n        }\n\n        unchecked {\n            // Checking for overflow this way is faster than letting Solidity do it.\n            uint256 xy = x * y;\n            require(xy / x == y);\n\n            // We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE\n            // during multiplication. See the comments within the \"sqrt\" function.\n            result = PRBMathCommon.sqrt(xy);\n        }\n    }\n\n    /// @notice Calculates 1 / x, rounding towards zero.\n    ///\n    /// @dev Requirements:\n    /// - x cannot be zero.\n    ///\n    /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the inverse.\n    /// @return result The inverse as an unsigned 60.18-decimal fixed-point number.\n    function inv(uint256 x) internal pure returns (uint256 result) {\n        unchecked {\n            // 1e36 is SCALE * SCALE.\n            result = 1e36 / x;\n        }\n    }\n\n    /// @notice Calculates the natural logarithm of x.\n    ///\n    /// @dev Based on the insight that ln(x) = log2(x) / log2(e).\n    ///\n    /// Requirements:\n    /// - All from \"log2\".\n    ///\n    /// Caveats:\n    /// - All from \"log2\".\n    /// - This doesn't return exactly 1 for 2718281828459045235, for that we would need more fine-grained precision.\n    ///\n    /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the natural logarithm.\n    /// @return result The natural logarithm as an unsigned 60.18-decimal fixed-point number.\n    function ln(uint256 x) internal pure returns (uint256 result) {\n        // Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x)\n        // can return is 196205294292027477728.\n        unchecked { result = (log2(x) * SCALE) / LOG2_E; }\n    }\n\n    /// @notice Calculates the common logarithm of x.\n    ///\n    /// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common\n    /// logarithm based on the insight that log10(x) = log2(x) / log2(10).\n    ///\n    /// Requirements:\n    /// - All from \"log2\".\n    ///\n    /// Caveats:\n    /// - All from \"log2\".\n    ///\n    /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the common logarithm.\n    /// @return result The common logarithm as an unsigned 60.18-decimal fixed-point number.\n    function log10(uint256 x) internal pure returns (uint256 result) {\n        require(x >= SCALE);\n\n        // Note that the \"mul\" in this block is the assembly mul operation, not the \"mul\" function defined in this contract.\n        // prettier-ignore\n        assembly {\n            switch x\n            case 1 { result := mul(SCALE, sub(0, 18)) }\n            case 10 { result := mul(SCALE, sub(1, 18)) }\n            case 100 { result := mul(SCALE, sub(2, 18)) }\n            case 1000 { result := mul(SCALE, sub(3, 18)) }\n            case 10000 { result := mul(SCALE, sub(4, 18)) }\n            case 100000 { result := mul(SCALE, sub(5, 18)) }\n            case 1000000 { result := mul(SCALE, sub(6, 18)) }\n            case 10000000 { result := mul(SCALE, sub(7, 18)) }\n            case 100000000 { result := mul(SCALE, sub(8, 18)) }\n            case 1000000000 { result := mul(SCALE, sub(9, 18)) }\n            case 10000000000 { result := mul(SCALE, sub(10, 18)) }\n            case 100000000000 { result := mul(SCALE, sub(11, 18)) }\n            case 1000000000000 { result := mul(SCALE, sub(12, 18)) }\n            case 10000000000000 { result := mul(SCALE, sub(13, 18)) }\n            case 100000000000000 { result := mul(SCALE, sub(14, 18)) }\n            case 1000000000000000 { result := mul(SCALE, sub(15, 18)) }\n            case 10000000000000000 { result := mul(SCALE, sub(16, 18)) }\n            case 100000000000000000 { result := mul(SCALE, sub(17, 18)) }\n            case 1000000000000000000 { result := 0 }\n            case 10000000000000000000 { result := SCALE }\n            case 100000000000000000000 { result := mul(SCALE, 2) }\n            case 1000000000000000000000 { result := mul(SCALE, 3) }\n            case 10000000000000000000000 { result := mul(SCALE, 4) }\n            case 100000000000000000000000 { result := mul(SCALE, 5) }\n            case 1000000000000000000000000 { result := mul(SCALE, 6) }\n            case 10000000000000000000000000 { result := mul(SCALE, 7) }\n            case 100000000000000000000000000 { result := mul(SCALE, 8) }\n            case 1000000000000000000000000000 { result := mul(SCALE, 9) }\n            case 10000000000000000000000000000 { result := mul(SCALE, 10) }\n            case 100000000000000000000000000000 { result := mul(SCALE, 11) }\n            case 1000000000000000000000000000000 { result := mul(SCALE, 12) }\n            case 10000000000000000000000000000000 { result := mul(SCALE, 13) }\n            case 100000000000000000000000000000000 { result := mul(SCALE, 14) }\n            case 1000000000000000000000000000000000 { result := mul(SCALE, 15) }\n            case 10000000000000000000000000000000000 { result := mul(SCALE, 16) }\n            case 100000000000000000000000000000000000 { result := mul(SCALE, 17) }\n            case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) }\n            case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) }\n            case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) }\n            case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) }\n            case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) }\n            case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) }\n            case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) }\n            case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) }\n            case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) }\n            case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) }\n            case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) }\n            case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) }\n            case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) }\n            case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) }\n            case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) }\n            case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) }\n            case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) }\n            case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) }\n            case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) }\n            case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) }\n            case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) }\n            case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) }\n            case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) }\n            case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) }\n            case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) }\n            case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) }\n            case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) }\n            case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) }\n            case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) }\n            case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) }\n            case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) }\n            case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) }\n            case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) }\n            case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) }\n            case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) }\n            case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) }\n            case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) }\n            case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) }\n            case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) }\n            case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) }\n            case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) }\n            case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 59) }\n            default {\n                result := MAX_UD60x18\n            }\n        }\n\n        if (result == MAX_UD60x18) {\n            // Do the fixed-point division inline to save gas. The denominator is log2(10).\n            unchecked { result = (log2(x) * SCALE) / 332192809488736234; }\n        }\n    }\n\n    /// @notice Calculates the binary logarithm of x.\n    ///\n    /// @dev Based on the iterative approximation algorithm.\n    /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n    ///\n    /// Requirements:\n    /// - x must be greater than or equal to SCALE, otherwise the result would be negative.\n    ///\n    /// Caveats:\n    /// - The results are nor perfectly accurate to the last digit, due to the lossy precision of the iterative approximation.\n    ///\n    /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the binary logarithm.\n    /// @return result The binary logarithm as an unsigned 60.18-decimal fixed-point number.\n    function log2(uint256 x) internal pure returns (uint256 result) {\n        require(x >= SCALE);\n        unchecked {\n            // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n).\n            uint256 n = PRBMathCommon.mostSignificantBit(x / SCALE);\n\n            // The integer part of the logarithm as an unsigned 60.18-decimal fixed-point number. The operation can't overflow\n            // because n is maximum 255 and SCALE is 1e18.\n            result = n * SCALE;\n\n            // This is y = x * 2^(-n).\n            uint256 y = x >> n;\n\n            // If y = 1, the fractional part is zero.\n            if (y == SCALE) {\n                return result;\n            }\n\n            // Calculate the fractional part via the iterative approximation.\n            // The \"delta >>= 1\" part is equivalent to \"delta /= 2\", but shifting bits is faster.\n            for (uint256 delta = HALF_SCALE; delta > 0; delta >>= 1) {\n                y = (y * y) / SCALE;\n\n                // Is y^2 > 2 and so in the range [2,4)?\n                if (y >= 2 * SCALE) {\n                    // Add the 2^(-m) factor to the logarithm.\n                    result += delta;\n\n                    // Corresponds to z/2 on Wikipedia.\n                    y >>= 1;\n                }\n            }\n        }\n    }\n\n    /// @notice Multiplies two unsigned 60.18-decimal fixed-point numbers together, returning a new unsigned 60.18-decimal\n    /// fixed-point number.\n    /// @dev See the documentation for the \"PRBMathCommon.mulDivFixedPoint\" function.\n    /// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n    /// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n    /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n    function mul(uint256 x, uint256 y) internal pure returns (uint256 result) {\n        result = PRBMathCommon.mulDivFixedPoint(x, y);\n    }\n\n    /// @notice Retrieves PI as an unsigned 60.18-decimal fixed-point number.\n    function pi() internal pure returns (uint256 result) {\n        result = 3141592653589793238;\n    }\n\n    /// @notice Raises x (unsigned 60.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the\n    /// famous algorithm \"exponentiation by squaring\".\n    ///\n    /// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring\n    ///\n    /// Requirements:\n    /// - The result must fit within MAX_UD60x18.\n    ///\n    /// Caveats:\n    /// - All from \"mul\".\n    /// - Assumes 0^0 is 1.\n    ///\n    /// @param x The base as an unsigned 60.18-decimal fixed-point number.\n    /// @param y The exponent as an uint256.\n    /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n    function pow(uint256 x, uint256 y) internal pure returns (uint256 result) {\n        // Calculate the first iteration of the loop in advance.\n        result = y & 1 > 0 ? x : SCALE;\n\n        // Equivalent to \"for(y /= 2; y > 0; y /= 2)\" but faster.\n        for (y >>= 1; y > 0; y >>= 1) {\n            x = PRBMathCommon.mulDivFixedPoint(x, x);\n\n            // Equivalent to \"y % 2 == 1\" but faster.\n            if (y & 1 > 0) {\n                result = PRBMathCommon.mulDivFixedPoint(result, x);\n            }\n        }\n    }\n\n    /// @notice Returns 1 as an unsigned 60.18-decimal fixed-point number.\n    function scale() internal pure returns (uint256 result) {\n        result = SCALE;\n    }\n\n    /// @notice Calculates the square root of x, rounding down.\n    /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n    ///\n    /// Requirements:\n    /// - x must be less than MAX_UD60x18 / SCALE.\n    ///\n    /// Caveats:\n    /// - The maximum fixed-point number permitted is 115792089237316195423570985008687907853269.984665640564039458.\n    ///\n    /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the square root.\n    /// @return result The result as an unsigned 60.18-decimal fixed-point .\n    function sqrt(uint256 x) internal pure returns (uint256 result) {\n        require(x < 115792089237316195423570985008687907853269984665640564039458);\n        unchecked {\n            // Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two unsigned\n            // 60.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root).\n            result = PRBMathCommon.sqrt(x * SCALE);\n        }\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/_prbmath/README.md",
    "content": "Imported from https://github.com/hifi-finance/prb-math/commit/62021c1abc3413f20d0bdc8f941cf9f21d5a7d2d\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/_stringutils/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2016 Nick Johnson\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/_stringutils/README.md",
    "content": "String utilities, originally from\n\nhttps://github.com/Arachnid/solidity-stringutils\n\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/_stringutils/stringutils.sol",
    "content": "/*\n * @title String & slice utility library for Solidity contracts.\n * @author Nick Johnson <arachnid@notdot.net>\n *\n * @dev Functionality in this library is largely implemented using an\n *      abstraction called a 'slice'. A slice represents a part of a string -\n *      anything from the entire string to a single character, or even no\n *      characters at all (a 0-length slice). Since a slice only has to specify\n *      an offset and a length, copying and manipulating slices is a lot less\n *      expensive than copying and manipulating the strings they reference.\n *\n *      To further reduce gas costs, most functions on slice that need to return\n *      a slice modify the original one instead of allocating a new one; for\n *      instance, `s.split(\".\")` will return the text up to the first '.',\n *      modifying s to only contain the remainder of the string after the '.'.\n *      In situations where you do not want to modify the original slice, you\n *      can make a copy first with `.copy()`, for example:\n *      `s.copy().split(\".\")`. Try and avoid using this idiom in loops; since\n *      Solidity has no memory management, it will result in allocating many\n *      short-lived slices that are later discarded.\n *\n *      Functions that return two slices come in two versions: a non-allocating\n *      version that takes the second slice as an argument, modifying it in\n *      place, and an allocating version that allocates and returns the second\n *      slice; see `nextRune` for example.\n *\n *      Functions that have to copy string data will return strings rather than\n *      slices; these can be cast back to slices for further processing if\n *      required.\n *\n *      For convenience, some functions are provided with non-modifying\n *      variants that create a new slice and return both; for instance,\n *      `s.splitNew('.')` leaves s unmodified, and returns two values\n *      corresponding to the left and right parts of the string.\n */\n\npragma solidity >=0.0;\n\nlibrary strings {\n    struct slice {\n        uint _len;\n        uint _ptr;\n    }\n\n    function memcpy(uint dest, uint src, uint len) private pure {\n        // Copy word-length chunks while possible\n        for(; len >= 32; len -= 32) {\n            assembly {\n                mstore(dest, mload(src))\n            }\n            dest += 32;\n            src += 32;\n        }\n\n        // The following masking would overflow in the case of len=0\n        // and the code path in that case is useless, albeit correct.\n        // This shortcut avoids it and saves gas.\n        if (len == 0)\n            return;\n\n        // Copy remaining bytes\n        uint mask;\n        unchecked { mask = 256 ** (32 - len) - 1; }\n        assembly {\n            let srcpart := and(mload(src), not(mask))\n            let destpart := and(mload(dest), mask)\n            mstore(dest, or(destpart, srcpart))\n        }\n    }\n\n    /*\n     * @dev Returns a slice containing the entire string.\n     * @param self The string to make a slice from.\n     * @return A newly allocated slice containing the entire string.\n     */\n    function toSlice(string memory self) internal pure returns (slice memory) {\n        uint ptr;\n        assembly {\n            ptr := add(self, 0x20)\n        }\n        return slice(bytes(self).length, ptr);\n    }\n\n    /*\n     * @dev Returns the length of a null-terminated bytes32 string.\n     * @param self The value to find the length of.\n     * @return The length of the string, from 0 to 32.\n     */\n    function len(bytes32 self) internal pure returns (uint) {\n        uint ret;\n        if (self == 0)\n            return 0;\n        if (uint256(self) & 0xffffffffffffffffffffffffffffffff == 0) {\n            ret += 16;\n            self = bytes32(uint(self) / 0x100000000000000000000000000000000);\n        }\n        if (uint256(self) & 0xffffffffffffffff == 0) {\n            ret += 8;\n            self = bytes32(uint(self) / 0x10000000000000000);\n        }\n        if (uint256(self) & 0xffffffff == 0) {\n            ret += 4;\n            self = bytes32(uint(self) / 0x100000000);\n        }\n        if (uint256(self) & 0xffff == 0) {\n            ret += 2;\n            self = bytes32(uint(self) / 0x10000);\n        }\n        if (uint256(self) & 0xff == 0) {\n            ret += 1;\n        }\n        return 32 - ret;\n    }\n\n    /*\n     * @dev Returns a slice containing the entire bytes32, interpreted as a\n     *      null-terminated utf-8 string.\n     * @param self The bytes32 value to convert to a slice.\n     * @return A new slice containing the value of the input argument up to the\n     *         first null.\n     */\n    function toSliceB32(bytes32 self) internal pure returns (slice memory ret) {\n        // Allocate space for `self` in memory, copy it there, and point ret at it\n        assembly {\n            let ptr := mload(0x40)\n            mstore(0x40, add(ptr, 0x20))\n            mstore(ptr, self)\n            mstore(add(ret, 0x20), ptr)\n        }\n        ret._len = len(self);\n    }\n\n    /*\n     * @dev Returns a new slice containing the same data as the current slice.\n     * @param self The slice to copy.\n     * @return A new slice containing the same data as `self`.\n     */\n    function copy(slice memory self) internal pure returns (slice memory) {\n        return slice(self._len, self._ptr);\n    }\n\n    /*\n     * @dev Copies a slice to a new string.\n     * @param self The slice to copy.\n     * @return A newly allocated string containing the slice's text.\n     */\n    function toString(slice memory self) internal pure returns (string memory) {\n        string memory ret = new string(self._len);\n        uint retptr;\n        assembly { retptr := add(ret, 32) }\n\n        memcpy(retptr, self._ptr, self._len);\n        return ret;\n    }\n\n    /*\n     * @dev Returns the length in runes of the slice. Note that this operation\n     *      takes time proportional to the length of the slice; avoid using it\n     *      in loops, and call `slice.empty()` if you only need to know whether\n     *      the slice is empty or not.\n     * @param self The slice to operate on.\n     * @return The length of the slice in runes.\n     */\n    function len(slice memory self) internal pure returns (uint l) {\n        // Starting at ptr-31 means the LSB will be the byte we care about\n        uint ptr = self._ptr - 31;\n        uint end = ptr + self._len;\n        for (l = 0; ptr < end; l++) {\n            uint8 b;\n            assembly { b := and(mload(ptr), 0xFF) }\n            if (b < 0x80) {\n                ptr += 1;\n            } else if(b < 0xE0) {\n                ptr += 2;\n            } else if(b < 0xF0) {\n                ptr += 3;\n            } else if(b < 0xF8) {\n                ptr += 4;\n            } else if(b < 0xFC) {\n                ptr += 5;\n            } else {\n                ptr += 6;\n            }\n        }\n    }\n\n    /*\n     * @dev Returns true if the slice is empty (has a length of 0).\n     * @param self The slice to operate on.\n     * @return True if the slice is empty, False otherwise.\n     */\n    function empty(slice memory self) internal pure returns (bool) {\n        return self._len == 0;\n    }\n\n    /*\n     * @dev Returns a positive number if `other` comes lexicographically after\n     *      `self`, a negative number if it comes before, or zero if the\n     *      contents of the two slices are equal. Comparison is done per-rune,\n     *      on unicode codepoints.\n     * @param self The first slice to compare.\n     * @param other The second slice to compare.\n     * @return The result of the comparison.\n     */\n    function compare(slice memory self, slice memory other) internal pure returns (int) {\n        uint shortest = self._len;\n        if (other._len < self._len)\n            shortest = other._len;\n\n        uint selfptr = self._ptr;\n        uint otherptr = other._ptr;\n        for (uint idx = 0; idx < shortest; idx += 32) {\n            uint a;\n            uint b;\n            assembly {\n                a := mload(selfptr)\n                b := mload(otherptr)\n            }\n            if (a != b) {\n                // Mask out irrelevant bytes and check again\n                uint256 mask = type(uint256).max; // 0xffff...\n                if(shortest < 32) {\n                  mask = ~(2 ** (8 * (32 - shortest + idx)) - 1);\n                }\n                uint256 diff;\n                // This depends on potential underflow.\n                unchecked { diff = (a & mask) - (b & mask); }\n                if (diff != 0)\n                    return int(diff);\n            }\n            selfptr += 32;\n            otherptr += 32;\n        }\n        return int(self._len) - int(other._len);\n    }\n\n    /*\n     * @dev Returns true if the two slices contain the same text.\n     * @param self The first slice to compare.\n     * @param self The second slice to compare.\n     * @return True if the slices are equal, false otherwise.\n     */\n    function equals(slice memory self, slice memory other) internal pure returns (bool) {\n        return compare(self, other) == 0;\n    }\n\n    /*\n     * @dev Extracts the first rune in the slice into `rune`, advancing the\n     *      slice to point to the next rune and returning `self`.\n     * @param self The slice to operate on.\n     * @param rune The slice that will contain the first rune.\n     * @return `rune`.\n     */\n    function nextRune(slice memory self, slice memory rune) internal pure returns (slice memory) {\n        rune._ptr = self._ptr;\n\n        if (self._len == 0) {\n            rune._len = 0;\n            return rune;\n        }\n\n        uint l;\n        uint b;\n        // Load the first byte of the rune into the LSBs of b\n        assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) }\n        if (b < 0x80) {\n            l = 1;\n        } else if(b < 0xE0) {\n            l = 2;\n        } else if(b < 0xF0) {\n            l = 3;\n        } else {\n            l = 4;\n        }\n\n        // Check for truncated codepoints\n        if (l > self._len) {\n            rune._len = self._len;\n            self._ptr += self._len;\n            self._len = 0;\n            return rune;\n        }\n\n        self._ptr += l;\n        self._len -= l;\n        rune._len = l;\n        return rune;\n    }\n\n    /*\n     * @dev Returns the first rune in the slice, advancing the slice to point\n     *      to the next rune.\n     * @param self The slice to operate on.\n     * @return A slice containing only the first rune from `self`.\n     */\n    function nextRune(slice memory self) internal pure returns (slice memory ret) {\n        nextRune(self, ret);\n    }\n\n    /*\n     * @dev Returns the number of the first codepoint in the slice.\n     * @param self The slice to operate on.\n     * @return The number of the first codepoint in the slice.\n     */\n    function ord(slice memory self) internal pure returns (uint ret) {\n        if (self._len == 0) {\n            return 0;\n        }\n\n        uint word;\n        uint length;\n        uint divisor = 2 ** 248;\n\n        // Load the rune into the MSBs of b\n        assembly { word:= mload(mload(add(self, 32))) }\n        uint b = word / divisor;\n        if (b < 0x80) {\n            ret = b;\n            length = 1;\n        } else if(b < 0xE0) {\n            ret = b & 0x1F;\n            length = 2;\n        } else if(b < 0xF0) {\n            ret = b & 0x0F;\n            length = 3;\n        } else {\n            ret = b & 0x07;\n            length = 4;\n        }\n\n        // Check for truncated codepoints\n        if (length > self._len) {\n            return 0;\n        }\n\n        for (uint i = 1; i < length; i++) {\n            divisor = divisor / 256;\n            b = (word / divisor) & 0xFF;\n            if (b & 0xC0 != 0x80) {\n                // Invalid UTF-8 sequence\n                return 0;\n            }\n            ret = (ret * 64) | (b & 0x3F);\n        }\n\n        return ret;\n    }\n\n    /*\n     * @dev Returns the keccak-256 hash of the slice.\n     * @param self The slice to hash.\n     * @return The hash of the slice.\n     */\n    function keccak(slice memory self) internal pure returns (bytes32 ret) {\n        assembly {\n            ret := keccak256(mload(add(self, 32)), mload(self))\n        }\n    }\n\n    /*\n     * @dev Returns true if `self` starts with `needle`.\n     * @param self The slice to operate on.\n     * @param needle The slice to search for.\n     * @return True if the slice starts with the provided text, false otherwise.\n     */\n    function startsWith(slice memory self, slice memory needle) internal pure returns (bool) {\n        if (self._len < needle._len) {\n            return false;\n        }\n\n        if (self._ptr == needle._ptr) {\n            return true;\n        }\n\n        bool equal;\n        assembly {\n            let length := mload(needle)\n            let selfptr := mload(add(self, 0x20))\n            let needleptr := mload(add(needle, 0x20))\n            equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n        }\n        return equal;\n    }\n\n    /*\n     * @dev If `self` starts with `needle`, `needle` is removed from the\n     *      beginning of `self`. Otherwise, `self` is unmodified.\n     * @param self The slice to operate on.\n     * @param needle The slice to search for.\n     * @return `self`\n     */\n    function beyond(slice memory self, slice memory needle) internal pure returns (slice memory) {\n        if (self._len < needle._len) {\n            return self;\n        }\n\n        bool equal = true;\n        if (self._ptr != needle._ptr) {\n            assembly {\n                let length := mload(needle)\n                let selfptr := mload(add(self, 0x20))\n                let needleptr := mload(add(needle, 0x20))\n                equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n            }\n        }\n\n        if (equal) {\n            self._len -= needle._len;\n            self._ptr += needle._len;\n        }\n\n        return self;\n    }\n\n    /*\n     * @dev Returns true if the slice ends with `needle`.\n     * @param self The slice to operate on.\n     * @param needle The slice to search for.\n     * @return True if the slice starts with the provided text, false otherwise.\n     */\n    function endsWith(slice memory self, slice memory needle) internal pure returns (bool) {\n        if (self._len < needle._len) {\n            return false;\n        }\n\n        uint selfptr = self._ptr + self._len - needle._len;\n\n        if (selfptr == needle._ptr) {\n            return true;\n        }\n\n        bool equal;\n        assembly {\n            let length := mload(needle)\n            let needleptr := mload(add(needle, 0x20))\n            equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n        }\n\n        return equal;\n    }\n\n    /*\n     * @dev If `self` ends with `needle`, `needle` is removed from the\n     *      end of `self`. Otherwise, `self` is unmodified.\n     * @param self The slice to operate on.\n     * @param needle The slice to search for.\n     * @return `self`\n     */\n    function until(slice memory self, slice memory needle) internal pure returns (slice memory) {\n        if (self._len < needle._len) {\n            return self;\n        }\n\n        uint selfptr = self._ptr + self._len - needle._len;\n        bool equal = true;\n        if (selfptr != needle._ptr) {\n            assembly {\n                let length := mload(needle)\n                let needleptr := mload(add(needle, 0x20))\n                equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n            }\n        }\n\n        if (equal) {\n            self._len -= needle._len;\n        }\n\n        return self;\n    }\n\n    // Returns the memory address of the first byte of the first occurrence of\n    // `needle` in `self`, or the first byte after `self` if not found.\n    function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {\n        uint ptr = selfptr;\n        uint idx;\n\n        if (needlelen <= selflen) {\n            if (needlelen <= 32) {\n                bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));\n\n                bytes32 needledata;\n                assembly { needledata := and(mload(needleptr), mask) }\n\n                uint end = selfptr + selflen - needlelen;\n                bytes32 ptrdata;\n                assembly { ptrdata := and(mload(ptr), mask) }\n\n                while (ptrdata != needledata) {\n                    if (ptr >= end)\n                        return selfptr + selflen;\n                    ptr++;\n                    assembly { ptrdata := and(mload(ptr), mask) }\n                }\n                return ptr;\n            } else {\n                // For long needles, use hashing\n                bytes32 hash;\n                assembly { hash := keccak256(needleptr, needlelen) }\n\n                for (idx = 0; idx <= selflen - needlelen; idx++) {\n                    bytes32 testHash;\n                    assembly { testHash := keccak256(ptr, needlelen) }\n                    if (hash == testHash)\n                        return ptr;\n                    ptr += 1;\n                }\n            }\n        }\n        return selfptr + selflen;\n    }\n\n    // Returns the memory address of the first byte after the last occurrence of\n    // `needle` in `self`, or the address of `self` if not found.\n    function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {\n        uint ptr;\n\n        if (needlelen <= selflen) {\n            if (needlelen <= 32) {\n                bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));\n\n                bytes32 needledata;\n                assembly { needledata := and(mload(needleptr), mask) }\n\n                ptr = selfptr + selflen - needlelen;\n                bytes32 ptrdata;\n                assembly { ptrdata := and(mload(ptr), mask) }\n\n                while (ptrdata != needledata) {\n                    if (ptr <= selfptr)\n                        return selfptr;\n                    ptr--;\n                    assembly { ptrdata := and(mload(ptr), mask) }\n                }\n                return ptr + needlelen;\n            } else {\n                // For long needles, use hashing\n                bytes32 hash;\n                assembly { hash := keccak256(needleptr, needlelen) }\n                ptr = selfptr + (selflen - needlelen);\n                while (ptr >= selfptr) {\n                    bytes32 testHash;\n                    assembly { testHash := keccak256(ptr, needlelen) }\n                    if (hash == testHash)\n                        return ptr + needlelen;\n                    ptr -= 1;\n                }\n            }\n        }\n        return selfptr;\n    }\n\n    /*\n     * @dev Modifies `self` to contain everything from the first occurrence of\n     *      `needle` to the end of the slice. `self` is set to the empty slice\n     *      if `needle` is not found.\n     * @param self The slice to search and modify.\n     * @param needle The text to search for.\n     * @return `self`.\n     */\n    function find(slice memory self, slice memory needle) internal pure returns (slice memory) {\n        uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);\n        self._len -= ptr - self._ptr;\n        self._ptr = ptr;\n        return self;\n    }\n\n    /*\n     * @dev Modifies `self` to contain the part of the string from the start of\n     *      `self` to the end of the first occurrence of `needle`. If `needle`\n     *      is not found, `self` is set to the empty slice.\n     * @param self The slice to search and modify.\n     * @param needle The text to search for.\n     * @return `self`.\n     */\n    function rfind(slice memory self, slice memory needle) internal pure returns (slice memory) {\n        uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);\n        self._len = ptr - self._ptr;\n        return self;\n    }\n\n    /*\n     * @dev Splits the slice, setting `self` to everything after the first\n     *      occurrence of `needle`, and `token` to everything before it. If\n     *      `needle` does not occur in `self`, `self` is set to the empty slice,\n     *      and `token` is set to the entirety of `self`.\n     * @param self The slice to split.\n     * @param needle The text to search for in `self`.\n     * @param token An output parameter to which the first token is written.\n     * @return `token`.\n     */\n    function split(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) {\n        uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);\n        token._ptr = self._ptr;\n        token._len = ptr - self._ptr;\n        if (ptr == self._ptr + self._len) {\n            // Not found\n            self._len = 0;\n        } else {\n            self._len -= token._len + needle._len;\n            self._ptr = ptr + needle._len;\n        }\n        return token;\n    }\n\n    /*\n     * @dev Splits the slice, setting `self` to everything after the first\n     *      occurrence of `needle`, and returning everything before it. If\n     *      `needle` does not occur in `self`, `self` is set to the empty slice,\n     *      and the entirety of `self` is returned.\n     * @param self The slice to split.\n     * @param needle The text to search for in `self`.\n     * @return The part of `self` up to the first occurrence of `delim`.\n     */\n    function split(slice memory self, slice memory needle) internal pure returns (slice memory token) {\n        split(self, needle, token);\n    }\n\n    /*\n     * @dev Splits the slice, setting `self` to everything before the last\n     *      occurrence of `needle`, and `token` to everything after it. If\n     *      `needle` does not occur in `self`, `self` is set to the empty slice,\n     *      and `token` is set to the entirety of `self`.\n     * @param self The slice to split.\n     * @param needle The text to search for in `self`.\n     * @param token An output parameter to which the first token is written.\n     * @return `token`.\n     */\n    function rsplit(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) {\n        uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);\n        token._ptr = ptr;\n        token._len = self._len - (ptr - self._ptr);\n        if (ptr == self._ptr) {\n            // Not found\n            self._len = 0;\n        } else {\n            self._len -= token._len + needle._len;\n        }\n        return token;\n    }\n\n    /*\n     * @dev Splits the slice, setting `self` to everything before the last\n     *      occurrence of `needle`, and returning everything after it. If\n     *      `needle` does not occur in `self`, `self` is set to the empty slice,\n     *      and the entirety of `self` is returned.\n     * @param self The slice to split.\n     * @param needle The text to search for in `self`.\n     * @return The part of `self` after the last occurrence of `delim`.\n     */\n    function rsplit(slice memory self, slice memory needle) internal pure returns (slice memory token) {\n        rsplit(self, needle, token);\n    }\n\n    /*\n     * @dev Counts the number of nonoverlapping occurrences of `needle` in `self`.\n     * @param self The slice to search.\n     * @param needle The text to search for in `self`.\n     * @return The number of occurrences of `needle` found in `self`.\n     */\n    function count(slice memory self, slice memory needle) internal pure returns (uint cnt) {\n        uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len;\n        while (ptr <= self._ptr + self._len) {\n            cnt++;\n            ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len;\n        }\n    }\n\n    /*\n     * @dev Returns True if `self` contains `needle`.\n     * @param self The slice to search.\n     * @param needle The text to search for in `self`.\n     * @return True if `needle` is found in `self`, false otherwise.\n     */\n    function contains(slice memory self, slice memory needle) internal pure returns (bool) {\n        return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr;\n    }\n\n    /*\n     * @dev Returns a newly allocated string containing the concatenation of\n     *      `self` and `other`.\n     * @param self The first slice to concatenate.\n     * @param other The second slice to concatenate.\n     * @return The concatenation of the two strings.\n     */\n    function concat(slice memory self, slice memory other) internal pure returns (string memory) {\n        string memory ret = new string(self._len + other._len);\n        uint retptr;\n        assembly { retptr := add(ret, 32) }\n        memcpy(retptr, self._ptr, self._len);\n        memcpy(retptr + self._len, other._ptr, other._len);\n        return ret;\n    }\n\n    /*\n     * @dev Joins an array of slices, using `self` as a delimiter, returning a\n     *      newly allocated string.\n     * @param self The delimiter to use.\n     * @param parts A list of slices to join.\n     * @return A newly allocated string containing all the slices in `parts`,\n     *         joined with `self`.\n     */\n    function join(slice memory self, slice[] memory parts) internal pure returns (string memory) {\n        if (parts.length == 0)\n            return \"\";\n\n        uint length = self._len * (parts.length - 1);\n        for(uint i = 0; i < parts.length; i++)\n            length += parts[i]._len;\n\n        string memory ret = new string(length);\n        uint retptr;\n        assembly { retptr := add(ret, 32) }\n\n        for(uint i = 0; i < parts.length; i++) {\n            memcpy(retptr, parts[i]._ptr, parts[i]._len);\n            retptr += parts[i]._len;\n            if (i < parts.length - 1) {\n                memcpy(retptr, self._ptr, self._len);\n                retptr += self._len;\n            }\n        }\n\n        return ret;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/base64.sol",
    "content": "==== ExternalSource: _base64/base64_inline_asm.sol ====\n==== ExternalSource: _base64/base64_no_inline_asm.sol ====\n==== Source: base64.sol ====\n\nimport \"_base64/base64_inline_asm.sol\";\nimport \"_base64/base64_no_inline_asm.sol\";\n\ncontract test {\n    function encode_inline_asm(bytes memory data) external pure returns (string memory) {\n      return InlineAsmBase64.encode(data);\n    }\n\n    function encode_no_asm(bytes memory data) external pure returns (string memory) {\n      return NoAsmBase64.encode(data);\n    }\n\n    function encode_inline_asm_large() external {\n      for (uint i = 0; i < 1000; i++) {\n        InlineAsmBase64.encode(\"foo\");\n      }\n    }\n\n    function encode_no_asm_large() external {\n      for (uint i = 0; i < 1000; i++) {\n        NoAsmBase64.encode(\"foo\");\n      }\n    }\n}\n// Test cases derived from Base64 specification: RFC4648\n// https://datatracker.ietf.org/doc/html/rfc4648#section-10\n//\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor()\n// gas irOptimized: 79076\n// gas irOptimized code: 322000\n// gas legacy: 102214\n// gas legacy code: 629800\n// gas legacyOptimized: 87926\n// gas legacyOptimized code: 429800\n// encode_inline_asm(bytes): 0x20, 0 -> 0x20, 0\n// encode_inline_asm(bytes): 0x20, 1, \"f\" -> 0x20, 4, \"Zg==\"\n// encode_inline_asm(bytes): 0x20, 2, \"fo\" -> 0x20, 4, \"Zm8=\"\n// encode_inline_asm(bytes): 0x20, 3, \"foo\" -> 0x20, 4, \"Zm9v\"\n// encode_inline_asm(bytes): 0x20, 4, \"foob\" -> 0x20, 8, \"Zm9vYg==\"\n// encode_inline_asm(bytes): 0x20, 5, \"fooba\" -> 0x20, 8, \"Zm9vYmE=\"\n// encode_inline_asm(bytes): 0x20, 6, \"foobar\" -> 0x20, 8, \"Zm9vYmFy\"\n// encode_no_asm(bytes): 0x20, 0 -> 0x20, 0\n// encode_no_asm(bytes): 0x20, 1, \"f\" -> 0x20, 4, \"Zg==\"\n// encode_no_asm(bytes): 0x20, 2, \"fo\" -> 0x20, 4, \"Zm8=\"\n// encode_no_asm(bytes): 0x20, 3, \"foo\" -> 0x20, 4, \"Zm9v\"\n// encode_no_asm(bytes): 0x20, 4, \"foob\" -> 0x20, 8, \"Zm9vYg==\"\n// encode_no_asm(bytes): 0x20, 5, \"fooba\" -> 0x20, 8, \"Zm9vYmE=\"\n// encode_no_asm(bytes): 0x20, 6, \"foobar\" -> 0x20, 8, \"Zm9vYmFy\"\n// encode_inline_asm_large()\n// gas irOptimized: 1406025\n// gas legacy: 1554038\n// gas legacyOptimized: 1132031\n// encode_no_asm_large()\n// gas irOptimized: 3512081\n// gas legacy: 4600082\n// gas legacyOptimized: 2813075\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/deposit_contract.sol",
    "content": "// ┏━━━┓━┏┓━┏┓━━┏━━━┓━━┏━━━┓━━━━┏━━━┓━━━━━━━━━━━━━━━━━━━┏┓━━━━━┏━━━┓━━━━━━━━━┏┓━━━━━━━━━━━━━━┏┓━\n// ┃┏━━┛┏┛┗┓┃┃━━┃┏━┓┃━━┃┏━┓┃━━━━┗┓┏┓┃━━━━━━━━━━━━━━━━━━┏┛┗┓━━━━┃┏━┓┃━━━━━━━━┏┛┗┓━━━━━━━━━━━━┏┛┗┓\n// ┃┗━━┓┗┓┏┛┃┗━┓┗┛┏┛┃━━┃┃━┃┃━━━━━┃┃┃┃┏━━┓┏━━┓┏━━┓┏━━┓┏┓┗┓┏┛━━━━┃┃━┗┛┏━━┓┏━┓━┗┓┏┛┏━┓┏━━┓━┏━━┓┗┓┏┛\n// ┃┏━━┛━┃┃━┃┏┓┃┏━┛┏┛━━┃┃━┃┃━━━━━┃┃┃┃┃┏┓┃┃┏┓┃┃┏┓┃┃━━┫┣┫━┃┃━━━━━┃┃━┏┓┃┏┓┃┃┏┓┓━┃┃━┃┏┛┗━┓┃━┃┏━┛━┃┃━\n// ┃┗━━┓━┃┗┓┃┃┃┃┃┃┗━┓┏┓┃┗━┛┃━━━━┏┛┗┛┃┃┃━┫┃┗┛┃┃┗┛┃┣━━┃┃┃━┃┗┓━━━━┃┗━┛┃┃┗┛┃┃┃┃┃━┃┗┓┃┃━┃┗┛┗┓┃┗━┓━┃┗┓\n// ┗━━━┛━┗━┛┗┛┗┛┗━━━┛┗┛┗━━━┛━━━━┗━━━┛┗━━┛┃┏━┛┗━━┛┗━━┛┗┛━┗━┛━━━━┗━━━┛┗━━┛┗┛┗┛━┗━┛┗┛━┗━━━┛┗━━┛━┗━┛\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┃┃━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┗┛━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n// SPDX-License-Identifier: CC0-1.0\n\n// This interface is designed to be compatible with the Vyper version.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ninterface IDepositContract {\n    /// @notice A processed deposit event.\n    event DepositEvent(\n        bytes pubkey,\n        bytes withdrawal_credentials,\n        bytes amount,\n        bytes signature,\n        bytes index\n    );\n\n    /// @notice Submit a Phase 0 DepositData object.\n    /// @param pubkey A BLS12-381 public key.\n    /// @param withdrawal_credentials Commitment to a public key for withdrawals.\n    /// @param signature A BLS12-381 signature.\n    /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object.\n    /// Used as a protection against malformed input.\n    function deposit(\n        bytes calldata pubkey,\n        bytes calldata withdrawal_credentials,\n        bytes calldata signature,\n        bytes32 deposit_data_root\n    ) external payable;\n\n    /// @notice Query the current deposit root hash.\n    /// @return The deposit root hash.\n    function get_deposit_root() external view returns (bytes32);\n\n    /// @notice Query the current deposit count.\n    /// @return The deposit count encoded as a little endian 64-bit number.\n    function get_deposit_count() external view returns (bytes memory);\n}\n\n// Based on official specification in https://eips.ethereum.org/EIPS/eip-165\ninterface ERC165 {\n    /// @notice Query if a contract implements an interface\n    /// @param interfaceId The interface identifier, as specified in ERC-165\n    /// @dev Interface identification is specified in ERC-165. This function\n    ///  uses less than 30,000 gas.\n    /// @return `true` if the contract implements `interfaceId` and\n    ///  `interfaceId` is not 0xffffffff, `false` otherwise\n    function supportsInterface(bytes4 interfaceId) external pure returns (bool);\n}\n\n// This is a rewrite of the Vyper Eth2.0 deposit contract in Solidity.\n// It tries to stay as close as possible to the original source code.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ncontract DepositContract is IDepositContract, ERC165 {\n    uint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32;\n    // NOTE: this also ensures `deposit_count` will fit into 64-bits\n    uint constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1;\n\n    bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] branch;\n    uint256 deposit_count;\n\n    bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] zero_hashes;\n\n    constructor() public {\n        // Compute hashes in empty sparse Merkle tree\n        for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++)\n            zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));\n    }\n\n    function get_deposit_root() override external view returns (bytes32) {\n        bytes32 node;\n        uint size = deposit_count;\n        for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n            if ((size & 1) == 1)\n                node = sha256(abi.encodePacked(branch[height], node));\n            else\n                node = sha256(abi.encodePacked(node, zero_hashes[height]));\n            size /= 2;\n        }\n        return sha256(abi.encodePacked(\n            node,\n            to_little_endian_64(uint64(deposit_count)),\n            bytes24(0)\n        ));\n    }\n\n    function get_deposit_count() override external view returns (bytes memory) {\n        return to_little_endian_64(uint64(deposit_count));\n    }\n\n    function deposit(\n        bytes calldata pubkey,\n        bytes calldata withdrawal_credentials,\n        bytes calldata signature,\n        bytes32 deposit_data_root\n    ) override external payable {\n        // Extended ABI length checks since dynamic types are used.\n        require(pubkey.length == 48, \"DepositContract: invalid pubkey length\");\n        require(withdrawal_credentials.length == 32, \"DepositContract: invalid withdrawal_credentials length\");\n        require(signature.length == 96, \"DepositContract: invalid signature length\");\n\n        // Check deposit amount\n        require(msg.value >= 1 ether, \"DepositContract: deposit value too low\");\n        require(msg.value % 1 gwei == 0, \"DepositContract: deposit value not multiple of gwei\");\n        uint deposit_amount = msg.value / 1 gwei;\n        require(deposit_amount <= type(uint64).max, \"DepositContract: deposit value too high\");\n\n        // Emit `DepositEvent` log\n        bytes memory amount = to_little_endian_64(uint64(deposit_amount));\n        emit DepositEvent(\n            pubkey,\n            withdrawal_credentials,\n            amount,\n            signature,\n            to_little_endian_64(uint64(deposit_count))\n        );\n\n        // Compute deposit data root (`DepositData` hash tree root)\n        bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0)));\n        bytes32 signature_root = sha256(abi.encodePacked(\n            sha256(abi.encodePacked(signature[:64])),\n            sha256(abi.encodePacked(signature[64:], bytes32(0)))\n        ));\n        bytes32 node = sha256(abi.encodePacked(\n            sha256(abi.encodePacked(pubkey_root, withdrawal_credentials)),\n            sha256(abi.encodePacked(amount, bytes24(0), signature_root))\n        ));\n\n        // Verify computed and expected deposit data roots match\n        require(node == deposit_data_root, \"DepositContract: reconstructed DepositData does not match supplied deposit_data_root\");\n\n        // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`)\n        require(deposit_count < MAX_DEPOSIT_COUNT, \"DepositContract: merkle tree full\");\n\n        // Add deposit data root to Merkle tree (update a single `branch` node)\n        deposit_count += 1;\n        uint size = deposit_count;\n        for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n            if ((size & 1) == 1) {\n                branch[height] = node;\n                return;\n            }\n            node = sha256(abi.encodePacked(branch[height], node));\n            size /= 2;\n        }\n        // As the loop should always end prematurely with the `return` statement,\n        // this code should be unreachable. We assert `false` just to be safe.\n        assert(false);\n    }\n\n    function supportsInterface(bytes4 interfaceId) override external pure returns (bool) {\n        return interfaceId == type(ERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId;\n    }\n\n    function to_little_endian_64(uint64 value) internal pure returns (bytes memory ret) {\n        ret = new bytes(8);\n        bytes8 bytesValue = bytes8(value);\n        // Byteswapping during copying to bytes.\n        ret[0] = bytesValue[7];\n        ret[1] = bytesValue[6];\n        ret[2] = bytesValue[5];\n        ret[3] = bytesValue[4];\n        ret[4] = bytesValue[3];\n        ret[5] = bytesValue[2];\n        ret[6] = bytesValue[1];\n        ret[7] = bytesValue[0];\n    }\n}\n// ====\n// compileViaSSACFG: true\n// experimental: true\n// ----\n// constructor()\n// gas irOptimized: 809570\n// gas irOptimized code: 558000\n// gas legacy: 920228\n// gas legacy code: 1438800\n// gas legacyOptimized: 848699\n// gas legacyOptimized code: 878200\n// gas ssaCFGOptimized: 810764\n// gas ssaCFGOptimized code: 582000\n// supportsInterface(bytes4): 0x0 -> 0\n// supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 #\n// supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id #\n// supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// gas ssaCFGOptimized: 110211\n// get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit #\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// gas ssaCFGOptimized: 110211\n// get_deposit_count() -> 0x20, 8, 0\n// deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00\n// get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// gas ssaCFGOptimized: 110201\n// get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// gas ssaCFGOptimized: 110201\n// get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol",
    "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: prbmath.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\ncontract test {\n    using PRBMathSD59x18 for int256;\n\n    function div(int256 x, int256 y) external pure returns (int256 ret) {\n        ret = x.div(y);\n    }\n    function exp(int256 x) external pure returns (int256 ret) {\n        ret = x.exp();\n    }\n    function exp2(int256 x) external pure returns (int256 ret) {\n        ret = x.exp2();\n    }\n    function gm(int256 x, int256 y) external pure returns (int256 ret) {\n        ret = x.gm(y);\n    }\n    function log10(int256 x) external pure returns (int256 ret) {\n        ret = x.log10();\n    }\n    function log2(int256 x) external pure returns (int256 ret) {\n        ret = x.log2();\n    }\n    function mul(int256 x, int256 y) external pure returns (int256 ret) {\n        ret = x.mul(y);\n    }\n    function pow(int256 x, uint256 y) external pure returns (int256 ret) {\n        ret = x.pow(y);\n    }\n    function sqrt(int256 x) external pure returns (int256 ret) {\n        ret = x.sqrt();\n    }\n    function benchmark(int256 x) external pure returns (int256 ret, int256 z1, int256 z2) {\n        int256 y = x.mul(3).ceil();\n        int256 z = y.div(x);\n        for (uint i = 0; i < 10; i++)\n            z = z.sqrt();\n        ret = z;\n\n        // Check precision\n        z1 = z.ceil();\n        z2 = z.sqrt().pow(2).ceil();\n        assert(z1 == z2);\n    }\n}\n// ----\n// constructor()\n// gas irOptimized: 177903\n// gas irOptimized code: 1674400\n// gas legacy: 209723\n// gas legacy code: 2205000\n// gas legacyOptimized: 178012\n// gas legacyOptimized code: 1669600\n// div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328\n// gas irOptimized: 22045\n// gas legacy: 22736\n// gas legacyOptimized: 22264\n// exp(int256): 3141592653589793238 -> 23140692632779268978\n// gas irOptimized: 24452\n// gas legacy: 25124\n// gas legacyOptimized: 24351\n// exp2(int256): 3141592653589793238 -> 8824977827076287620\n// gas irOptimized: 24162\n// gas legacy: 24787\n// gas legacyOptimized: 24105\n// gm(int256,int256): 3141592653589793238, 88714123 -> 16694419339601\n// gas irOptimized: 22805\n// gas legacy: 23202\n// gas legacyOptimized: 22685\n// log10(int256): 3141592653589793238 -> 4971498726941338506\n// gas irOptimized: 30300\n// gas legacy: 32841\n// gas legacyOptimized: 30249\n// log2(int256): 3141592653589793238 -> 1651496129472318782\n// gas irOptimized: 28566\n// gas legacy: 30979\n// gas legacyOptimized: 28357\n// mul(int256,int256): 3141592653589793238, 88714123 -> 278703637\n// gas irOptimized: 22147\n// gas legacy: 22775\n// gas legacyOptimized: 22288\n// pow(int256,uint256): 3141592653589793238, 5 -> 306019684785281453040\n// gas irOptimized: 22488\n// gas legacy: 23453\n// gas legacyOptimized: 22921\n// sqrt(int256): 3141592653589793238 -> 1772453850905516027\n// gas irOptimized: 22458\n// gas legacy: 22784\n// gas legacyOptimized: 22420\n// benchmark(int256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000\n// gas irOptimized: 34893\n// gas legacy: 35244\n// gas legacyOptimized: 33996\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol",
    "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathUD60x18.sol ====\n==== Source: prbmath.sol ====\nimport \"_prbmath/PRBMathUD60x18.sol\";\n\ncontract test {\n    using PRBMathUD60x18 for uint256;\n\n    function div(uint256 x, uint256 y) external pure returns (uint256 ret) {\n        ret = x.div(y);\n    }\n    function exp(uint256 x) external pure returns (uint256 ret) {\n        ret = x.exp();\n    }\n    function exp2(uint256 x) external pure returns (uint256 ret) {\n        ret = x.exp2();\n    }\n    function gm(uint256 x, uint256 y) external pure returns (uint256 ret) {\n        ret = x.gm(y);\n    }\n    function log10(uint256 x) external pure returns (uint256 ret) {\n        ret = x.log10();\n    }\n    function log2(uint256 x) external pure returns (uint256 ret) {\n        ret = x.log2();\n    }\n    function mul(uint256 x, uint256 y) external pure returns (uint256 ret) {\n        ret = x.mul(y);\n    }\n    function pow(uint256 x, uint256 y) external pure returns (uint256 ret) {\n        ret = x.pow(y);\n    }\n    function sqrt(uint256 x) external pure returns (uint256 ret) {\n        ret = x.sqrt();\n    }\n    function benchmark(uint256 x) external pure returns (uint256 ret, uint256 z1, uint256 z2) {\n        uint256 y = x.mul(3).ceil();\n        uint256 z = y.div(x);\n        for (uint i = 0; i < 10; i++)\n            z = z.sqrt();\n        ret = z;\n\n        // Check precision\n        z1 = z.ceil();\n        z2 = z.sqrt().pow(2).ceil();\n        assert(z1 == z2);\n    }\n}\n// ----\n// constructor()\n// gas irOptimized: 170626\n// gas irOptimized code: 1577400\n// gas legacy: 195206\n// gas legacy code: 1999000\n// gas legacyOptimized: 168857\n// gas legacyOptimized code: 1556200\n// div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328\n// gas irOptimized: 21912\n// gas legacy: 22475\n// gas legacyOptimized: 21998\n// exp(uint256): 3141592653589793238 -> 23140692632779268978\n// gas irOptimized: 24334\n// gas legacy: 25026\n// gas legacyOptimized: 24253\n// exp2(uint256): 3141592653589793238 -> 8824977827076287620\n// gas irOptimized: 24115\n// gas legacy: 24738\n// gas legacyOptimized: 24058\n// gm(uint256,uint256): 3141592653589793238, 88714123 -> 16694419339601\n// gas irOptimized: 22786\n// gas legacy: 23244\n// gas legacyOptimized: 22727\n// log10(uint256): 3141592653589793238 -> 0x44fe4fc084a52b8a\n// gas irOptimized: 30079\n// gas legacy: 32808\n// gas legacyOptimized: 29912\n// log2(uint256): 3141592653589793238 -> 1651496129472318782\n// gas irOptimized: 28107\n// gas legacy: 30900\n// gas legacyOptimized: 27994\n// mul(uint256,uint256): 3141592653589793238, 88714123 -> 278703637\n// gas irOptimized: 21988\n// gas legacy: 22581\n// gas legacyOptimized: 22089\n// pow(uint256,uint256): 3141592653589793238, 5 -> 306019684785281453040\n// gas irOptimized: 22316\n// gas legacy: 23196\n// gas legacyOptimized: 22652\n// sqrt(uint256): 3141592653589793238 -> 1772453850905516027\n// gas irOptimized: 22481\n// gas legacy: 22803\n// gas legacyOptimized: 22439\n// benchmark(uint256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000\n// gas irOptimized: 33961\n// gas legacy: 34006\n// gas legacyOptimized: 32724\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol",
    "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: ramanujan_pi.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\n// The goal of this test file is to implement Ramanujan's pi approximation using various libraries.\n\nfunction factorial(uint n) pure returns (uint ret) {\n    ret = 1;\n    for (; n > 1; --n)\n        ret *= n;\n}\n\ncontract test {\n    using PRBMathSD59x18 for int256;\n\n    function prb_scale(uint n) internal pure returns (int256 ret) {\n        // Scale to SD59x18\n        ret = int256(n * 10e17);\n    }\n\n    // This dumb implementation of Ramanujan series calculates 1/pi\n    function prb_pi() external pure returns (int256 ret) {\n        uint n = 6; // More than 6 iterations results in failure\n        for (uint k = 0; k < n; k++) {\n            int256 a = prb_scale(factorial(4 * k)).div(prb_scale(factorial(k)).pow(4));\n            int256 b = (prb_scale(25390).mul(prb_scale(k)) + prb_scale(1103)).div(prb_scale(396).pow(4 * k));\n            ret += a.mul(b);\n        }\n        ret = ret.mul(prb_scale(2).sqrt().mul(prb_scale(2)).div(prb_scale(99).pow(2)));\n        ret = prb_scale(1).div(ret);\n    }\n}\n// ----\n// constructor()\n// gas irOptimized: 77816\n// gas irOptimized code: 307600\n// gas legacy: 92110\n// gas legacy code: 523600\n// gas legacyOptimized: 82667\n// gas legacyOptimized code: 369200\n// prb_pi() -> 3141592656369545286\n// gas irOptimized: 55036\n// gas legacy: 100657\n// gas legacyOptimized: 74311\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/snark.sol",
    "content": "pragma abicoder v2;\n\nlibrary Pairing {\n\tstruct G1Point {\n\t\tuint X;\n\t\tuint Y;\n\t}\n\t// Encoding of field elements is: X[0] * z + X[1]\n\tstruct G2Point {\n\t\tuint[2] X;\n\t\tuint[2] Y;\n\t}\n\n\t/// @return the generator of G1\n\tfunction P1() internal returns (G1Point memory) {\n\t\treturn G1Point(1, 2);\n\t}\n\n\t/// @return the generator of G2\n\tfunction P2() internal returns (G2Point memory) {\n\t\treturn G2Point(\n\t\t\t[11559732032986387107991004021392285783925812861821192530917403151452391805634,\n\t\t\t 10857046999023057135944570762232829481370756359578518086990519993285655852781],\n\t\t\t[4082367875863433681332203403145435568316851327593401208105741076214120093531,\n\t\t\t 8495653923123431417604973247489272438418190587263600148770280649306958101930]\n\t\t);\n\t}\n\n\t/// @return the negation of p, i.e. p.add(p.negate()) should be zero.\n\tfunction negate(G1Point memory p) internal returns (G1Point memory) {\n\t\t// The prime q in the base field F_q for G1\n\t\tuint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tif (p.X == 0 && p.Y == 0)\n\t\t\treturn G1Point(0, 0);\n\t\treturn G1Point(p.X, q - (p.Y % q));\n\t}\n\n\t/// @return r the sum of two points of G1\n\tfunction add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) {\n\t\tuint[4] memory input;\n\t\tinput[0] = p1.X;\n\t\tinput[1] = p1.Y;\n\t\tinput[2] = p2.X;\n\t\tinput[3] = p2.Y;\n\t\t(bool success, bytes memory encodedResult) = address(6).call(abi.encode(input));\n\t\trequire(success);\n\t\tr = abi.decode(encodedResult, (G1Point));\n\t}\n\n\t/// @return r the product of a point on G1 and a scalar, i.e.\n\t/// p == p.mul(1) and p.add(p) == p.mul(2) for all points p.\n\tfunction mul(G1Point memory p, uint s) internal returns (G1Point memory r) {\n\t\tuint[3] memory input;\n\t\tinput[0] = p.X;\n\t\tinput[1] = p.Y;\n\t\tinput[2] = s;\n\t\t(bool success, bytes memory encodedResult) = address(7).call(abi.encode(input));\n\t\trequire(success);\n\t\tr = abi.decode(encodedResult, (G1Point));\n\t}\n\n\t/// @return the result of computing the pairing check\n\t/// e(p1[0], p2[0]) *  .... * e(p1[n], p2[n]) == 1\n\t/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should\n\t/// return true.\n\tfunction pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) {\n\t\trequire(p1.length == p2.length);\n\t\tuint elements = p1.length;\n\t\tuint inputSize = p1.length * 6;\n\t\tuint[] memory input = new uint[](inputSize);\n\t\tfor (uint i = 0; i < elements; i++)\n\t\t{\n\t\t\tinput[i * 6 + 0] = p1[i].X;\n\t\t\tinput[i * 6 + 1] = p1[i].Y;\n\t\t\tinput[i * 6 + 2] = p2[i].X[0];\n\t\t\tinput[i * 6 + 3] = p2[i].X[1];\n\t\t\tinput[i * 6 + 4] = p2[i].Y[0];\n\t\t\tinput[i * 6 + 5] = p2[i].Y[1];\n\t\t}\n\n\t\tbytes memory encodedInput = new bytes(inputSize * 32);\n\t\tfor (uint i = 0; i < inputSize; i++)\n\t\t{\n\t\t\tuint offset = (i + 1) * 32;\n\t\t\tuint item = input[i];\n\t\t\tassembly (\"memory-safe\") {\n\t\t\t\tmstore(add(encodedInput, offset), item)\n\t\t\t}\n\t\t}\n\t\t(bool success, bytes memory encodedResult) = address(8).call(encodedInput);\n\t\trequire(success);\n\t\treturn abi.decode(encodedResult, (bool));\n\t}\n\tfunction pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](2);\n\t\tG2Point[] memory p2 = new G2Point[](2);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd3(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](3);\n\t\tG2Point[] memory p2 = new G2Point[](3);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd4(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2,\n\t\t\tG1Point memory d1, G2Point memory d2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](4);\n\t\tG2Point[] memory p2 = new G2Point[](4);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp1[3] = d1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\tp2[3] = d2;\n\t\treturn pairing(p1, p2);\n\t}\n}\n\ncontract Test {\n\tusing Pairing for *;\n\tstruct VerifyingKey {\n\t\tPairing.G2Point A;\n\t\tPairing.G1Point B;\n\t\tPairing.G2Point C;\n\t\tPairing.G2Point gamma;\n\t\tPairing.G1Point gammaBeta1;\n\t\tPairing.G2Point gammaBeta2;\n\t\tPairing.G2Point Z;\n\t\tPairing.G1Point[] IC;\n\t}\n\tstruct Proof {\n\t\tPairing.G1Point A;\n\t\tPairing.G1Point A_p;\n\t\tPairing.G2Point B;\n\t\tPairing.G1Point B_p;\n\t\tPairing.G1Point C;\n\t\tPairing.G1Point C_p;\n\t\tPairing.G1Point K;\n\t\tPairing.G1Point H;\n\t}\n\tfunction f() public returns (bool) {\n\t\tPairing.G1Point memory p1;\n\t\tPairing.G1Point memory p2;\n\t\tp1.X = 1; p1.Y = 2;\n\t\tp2.X = 1; p2.Y = 2;\n\t\tPairing.G1Point memory explicit_sum = Pairing.add(p1, p2);\n\t\tPairing.G1Point memory scalar_prod = Pairing.mul(p1, 2);\n\t\treturn (explicit_sum.X == scalar_prod.X &&\n\t\t\texplicit_sum.Y == scalar_prod.Y);\n\t}\n\tfunction g() public returns (bool) {\n\t\tPairing.G1Point memory x = Pairing.add(Pairing.P1(), Pairing.negate(Pairing.P1()));\n\t\t// should be zero\n\t\treturn (x.X == 0 && x.Y == 0);\n\t}\n\tfunction testMul() public returns (bool) {\n\t\tPairing.G1Point memory p;\n\t\t// @TODO The points here are reported to be not well-formed\n\t\tp.X = 14125296762497065001182820090155008161146766663259912659363835465243039841726;\n\t\tp.Y = 16229134936871442251132173501211935676986397196799085184804749187146857848057;\n\t\tp = Pairing.mul(p, 13986731495506593864492662381614386532349950841221768152838255933892789078521);\n\t\treturn\n\t\t\tp.X == 18256332256630856740336504687838346961237861778318632856900758565550522381207 &&\n\t\t\tp.Y == 6976682127058094634733239494758371323697222088503263230319702770853579280803;\n\t}\n\tfunction pair() public returns (bool) {\n\t\tPairing.G2Point memory fiveTimesP2 = Pairing.G2Point(\n\t\t\t[4540444681147253467785307942530223364530218361853237193970751657229138047649, 20954117799226682825035885491234530437475518021362091509513177301640194298072],\n\t\t\t[11631839690097995216017572651900167465857396346217730511548857041925508482915, 21508930868448350162258892668132814424284302804699005394342512102884055673846]\n\t\t);\n\t\t// The prime p in the base field F_p for G1\n\t\tuint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tPairing.G1Point[] memory g1points = new Pairing.G1Point[](2);\n\t\tPairing.G2Point[] memory g2points = new Pairing.G2Point[](2);\n\t\t// check e(5 P1, P2)e(-P1, 5 P2) == 1\n\t\tg1points[0] = Pairing.P1().mul(5);\n\t\tg1points[1] = Pairing.P1().negate();\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = fiveTimesP2;\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\t// check e(P1, P2)e(-P1, P2) == 1\n\t\tg1points[0] = Pairing.P1();\n\t\tg1points[1] = Pairing.P1();\n\t\tg1points[1].Y = p - g1points[1].Y;\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = Pairing.P2();\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\tfunction verifyingKey() internal returns (VerifyingKey memory vk) {\n\t\tvk.A = Pairing.G2Point([0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678], [0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550]);\n\t\tvk.B = Pairing.G1Point(0x2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02, 0x03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84);\n\t\tvk.C = Pairing.G2Point([0x2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb, 0x01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3], [0x14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713, 0x178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590]);\n\t\tvk.gamma = Pairing.G2Point([0x25f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb1, 0x22acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d], [0x065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf68, 0x06d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb]);\n\t\tvk.gammaBeta1 = Pairing.G1Point(0x15794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f21, 0x14db745c6780e9df549864cec19c2daf4531f6ec0c89cc1c7436cc4d8d300c6d);\n\t\tvk.gammaBeta2 = Pairing.G2Point([0x1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e, 0x283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39], [0x140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e, 0x0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd4]);\n\t\tvk.Z = Pairing.G2Point([0x217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac29, 0x0a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c], [0x26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a9855, 0x2fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d7]);\n\t\tvk.IC = new Pairing.G1Point[](10);\n\t\tvk.IC[0] = Pairing.G1Point(0x0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a, 0x044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf);\n\t\tvk.IC[1] = Pairing.G1Point(0x1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc, 0x2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb);\n\t\tvk.IC[2] = Pairing.G1Point(0x1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f, 0x042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db);\n\t\tvk.IC[3] = Pairing.G1Point(0x17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5, 0x02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1);\n\t\tvk.IC[4] = Pairing.G1Point(0x0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d, 0x0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b);\n\t\tvk.IC[5] = Pairing.G1Point(0x232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8, 0x2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7);\n\t\tvk.IC[6] = Pairing.G1Point(0x09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe, 0x18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4);\n\t\tvk.IC[7] = Pairing.G1Point(0x0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a, 0x18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e);\n\t\tvk.IC[8] = Pairing.G1Point(0x0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a, 0x04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e);\n\t\tvk.IC[9] = Pairing.G1Point(0x111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f, 0x1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30);\n\t}\n\tfunction verify(uint[] memory input, Proof memory proof) internal returns (uint) {\n\t\tVerifyingKey memory vk = verifyingKey();\n\t\trequire(input.length + 1 == vk.IC.length);\n\t\t// Compute the linear combination vk_x\n\t\tPairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\n\t\tfor (uint i = 0; i < input.length; i++)\n\t\t\tvk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], input[i]));\n\t\tvk_x = Pairing.add(vk_x, vk.IC[0]);\n\t\tif (!Pairing.pairingProd2(proof.A, vk.A, Pairing.negate(proof.A_p), Pairing.P2())) return 1;\n\t\tif (!Pairing.pairingProd2(vk.B, proof.B, Pairing.negate(proof.B_p), Pairing.P2())) return 2;\n\t\tif (!Pairing.pairingProd2(proof.C, vk.C, Pairing.negate(proof.C_p), Pairing.P2())) return 3;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tproof.K, vk.gamma,\n\t\t\tPairing.negate(Pairing.add(vk_x, Pairing.add(proof.A, proof.C))), vk.gammaBeta2,\n\t\t\tPairing.negate(vk.gammaBeta1), proof.B\n\t\t)) return 4;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tPairing.add(vk_x, proof.A), proof.B,\n\t\t\tPairing.negate(proof.H), vk.Z,\n\t\t\tPairing.negate(proof.C), Pairing.P2()\n\t\t)) return 5;\n\t\treturn 0;\n\t}\n\tevent Verified(string);\n\tfunction verifyTx() public returns (bool) {\n\t\tuint[] memory input = new uint[](9);\n\t\tProof memory proof;\n\t\tproof.A = Pairing.G1Point(12873740738727497448187997291915224677121726020054032516825496230827252793177, 21804419174137094775122804775419507726154084057848719988004616848382402162497);\n\t\tproof.A_p = Pairing.G1Point(7742452358972543465462254569134860944739929848367563713587808717088650354556, 7324522103398787664095385319014038380128814213034709026832529060148225837366);\n\t\tproof.B = Pairing.G2Point(\n\t\t\t[8176651290984905087450403379100573157708110416512446269839297438960217797614, 15588556568726919713003060429893850972163943674590384915350025440408631945055],\n\t\t\t[15347511022514187557142999444367533883366476794364262773195059233657571533367, 4265071979090628150845437155927259896060451682253086069461962693761322642015]);\n\t\tproof.B_p = Pairing.G1Point(2979746655438963305714517285593753729335852012083057917022078236006592638393, 6470627481646078059765266161088786576504622012540639992486470834383274712950);\n\t\tproof.C = Pairing.G1Point(6851077925310461602867742977619883934042581405263014789956638244065803308498, 10336382210592135525880811046708757754106524561907815205241508542912494488506);\n\t\tproof.C_p = Pairing.G1Point(12491625890066296859584468664467427202390981822868257437245835716136010795448, 13818492518017455361318553880921248537817650587494176379915981090396574171686);\n\t\tproof.H = Pairing.G1Point(12091046215835229523641173286701717671667447745509192321596954139357866668225, 14446807589950902476683545679847436767890904443411534435294953056557941441758);\n\t\tproof.K = Pairing.G1Point(21341087976609916409401737322664290631992568431163400450267978471171152600502, 2942165230690572858696920423896381470344658299915828986338281196715687693170);\n\t\tinput[0] = 13986731495506593864492662381614386532349950841221768152838255933892789078521;\n\t\tinput[1] = 622860516154313070522697309645122400675542217310916019527100517240519630053;\n\t\tinput[2] = 11094488463398718754251685950409355128550342438297986977413505294941943071569;\n\t\tinput[3] = 6627643779954497813586310325594578844876646808666478625705401786271515864467;\n\t\tinput[4] = 2957286918163151606545409668133310005545945782087581890025685458369200827463;\n\t\tinput[5] = 1384290496819542862903939282897996566903332587607290986044945365745128311081;\n\t\tinput[6] = 5613571677741714971687805233468747950848449704454346829971683826953541367271;\n\t\tinput[7] = 9643208548031422463313148630985736896287522941726746581856185889848792022807;\n\t\tinput[8] = 18066496933330839731877828156604;\n\t\tif (verify(input, proof) == 0) {\n\t\t\temit Verified(\"Successfully verified.\");\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n/// Disabled because the point seems to be not well-formed, we need to find another example.\n/// testMul() -> true\n//\n// ====\n// EVMVersion: >=constantinople\n// compileViaSSACFG: true\n// experimental: true\n// ----\n// library: Pairing\n// f() -> true\n// g() -> true\n// pair() -> true\n// gas irOptimized: 275229\n// gas legacy: 293579\n// gas legacyOptimized: 276313\n// gas ssaCFGOptimized: 275439\n// verifyTx() -> true\n// ~ emit Verified(string): 0x20, 0x16, \"Successfully verified.\"\n// gas irOptimized: 818076\n// gas legacy: 904397\n// gas legacyOptimized: 816770\n// gas ssaCFGOptimized: 819542\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalContracts/strings.sol",
    "content": "==== ExternalSource: _stringutils/stringutils.sol ====\n==== Source: strings.sol ====\npragma abicoder v2;\nimport \"_stringutils/stringutils.sol\";\n\ncontract test {\n    using strings for bytes32;\n    using strings for string;\n    using strings for strings.slice;\n\n    function toSlice(string memory a) external pure returns (strings.slice memory) {\n        return a.toSlice();\n    }\n\n    function roundtrip(string memory a) external pure returns (string memory) {\n        return a.toSlice().toString();\n    }\n\n    function utf8len(string memory a) external pure returns (uint) {\n        return a.toSlice().len();\n    }\n\n    function multiconcat(string memory a, uint count) public pure returns (string memory) {\n        strings.slice memory s = a.toSlice();\n        for (uint i = 0; i < count; i++) {\n            s = s.concat(s).toSlice();\n        }\n        return s.toString();\n    }\n\n    function benchmark(string memory text, bytes32 seed) external pure returns (uint) {\n        // Grow text.\n        text = multiconcat(text, 10);\n\n        strings.slice memory a = text.toSlice();\n        strings.slice memory b = seed.toSliceB32();\n\n        // Some heavy computation.\n        bool c = b.equals(a) || b.startsWith(a);\n\n        // Join as a list.\n        strings.slice memory delim = c ? string(\",\").toSlice() : string(\";\").toSlice();\n        strings.slice[] memory parts = new strings.slice[](2);\n        parts[0] = a;\n        parts[1] = b;\n        string memory d = delim.join(parts);\n        return d.toSlice().len();\n    }\n}\n// ----\n// constructor()\n// gas irOptimized: 95303\n// gas irOptimized code: 520000\n// gas legacy: 126346\n// gas legacy code: 932600\n// gas legacyOptimized: 102639\n// gas legacyOptimized code: 612400\n// toSlice(string): 0x20, 11, \"hello world\" -> 11, 0xa0\n// gas irOptimized: 22646\n// gas legacy: 23168\n// gas legacyOptimized: 22488\n// roundtrip(string): 0x20, 11, \"hello world\" -> 0x20, 11, \"hello world\"\n// gas irOptimized: 23225\n// gas legacy: 23674\n// gas legacyOptimized: 22991\n// utf8len(string): 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" -> 4 # Input: \"😃😃😃😃\" #\n// gas irOptimized: 23956\n// gas legacy: 25621\n// gas legacyOptimized: 24096\n// multiconcat(string,uint256): 0x40, 3, 11, \"hello world\" -> 0x20, 0x58, 0x68656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f726c, 0x6468656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f72, 49027192869463622675296414541903001712009715982962058146354235762728281047040 # concatenating 3 times #\n// gas irOptimized: 27630\n// gas legacy: 30778\n// gas legacyOptimized: 27519\n// benchmark(string,bytes32): 0x40, 0x0842021, 8, \"solidity\" -> 0x2020\n// gas irOptimized: 1976778\n// gas legacy: 4234020\n// gas legacyOptimized: 2318668\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_external/external.sol",
    "content": "contract External {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_external/external.sol=sol",
    "content": "contract External {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_external/import.sol",
    "content": "import \"external.sol\";\nimport \"other_external.sol\";\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_external/import_with_subdir.sol",
    "content": "import \"subdir/import.sol\";\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_external/other_external.sol",
    "content": "contract OtherExternal {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_external/subdir/import.sol",
    "content": "import \"sub_external.sol\";\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_external/subdir/sub_external.sol",
    "content": "contract SubExternal {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_nonNormalizedPaths/a.sol",
    "content": "contract A {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_nonNormalizedPaths/c.sol",
    "content": "contract C {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_nonNormalizedPaths/d.sol",
    "content": "contract D {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_relativeImports/D/d.sol",
    "content": "contract D {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_relativeImports/c.sol",
    "content": "contract C {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_relativeImports/dir/B/b.sol",
    "content": "import {C} from \"../../c.sol\";\ncontract B {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_relativeImports/dir/G/g.sol",
    "content": "import {B} from \"../B/b.sol\";\ncontract G {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_relativeImports/dir/a.sol",
    "content": "contract A {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_relativeImports/dir/contract.sol",
    "content": "import {A} from \"./a.sol\";\nimport {B} from \"./B/b.sol\";\nimport {C} from \"../c.sol\";\nimport {D} from \"../D/d.sol\";\nimport {G} from \"./E/../F/../G/./g.sol\";\nimport {H} from \"../../../../_relativeImports/h.sol\";\ncontract Contract {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_relativeImports/h.sol",
    "content": "contract H {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/b.sol",
    "content": "contract B {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dir/a.sol",
    "content": "contract A {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dir/contract.sol",
    "content": "import {A} from \"./a.sol\";\nimport {B} from \"../b.sol\";\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dot_a.sol",
    "content": "contract Dot_A {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/_sourceNameStartingWithDots/dot_dot_b.sol",
    "content": "contract Dot_Dot_B {\n}\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/multiple_equals_signs.sol",
    "content": "==== ExternalSource: a=_external/external.sol=sol ====\nimport {External} from \"a\";\ncontract C {\n}\n// ----\n// constructor()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/multiple_external_source.sol",
    "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/multisource.sol",
    "content": "==== ExternalSource: _external/external.sol ====\n==== Source: s1.sol ====\nimport {External} from \"_external/external.sol\";\ncontract S1 {\n}\n==== Source: s2.sol ====\nimport {S1} from \"s1.sol\";\ncontract C {\n}\n// ----\n// constructor()\n\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/non_normalized_paths.sol",
    "content": "==== ExternalSource: _nonNormalizedPaths//a.sol ====\n==== ExternalSource: C/////c.sol=_nonNormalizedPaths/c.sol ====\n==== ExternalSource: C/../////D/d.sol=_nonNormalizedPaths///d.sol ====\nimport {A} from \"_nonNormalizedPaths//a.sol\";\nimport {C} from \"C/////c.sol\";\nimport {D} from \"C/../////D/d.sol\";\ncontract Contract {\n}\n// ----\n// constructor()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/relative_imports.sol",
    "content": "==== ExternalSource: _relativeImports/dir/contract.sol ====\n==== ExternalSource: _relativeImports/dir/a.sol ====\n==== ExternalSource: _relativeImports/dir/B/b.sol ====\n==== ExternalSource: _relativeImports/c.sol ====\n==== ExternalSource: _relativeImports/D/d.sol ====\n==== ExternalSource: _relativeImports/dir/G/g.sol ====\n==== ExternalSource: _relativeImports/h.sol ====\nimport {A, B, C, D, G, H, Contract} from \"_relativeImports/dir/contract.sol\";\ncontract CC {\n}\n// ----\n// constructor()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/source.sol",
    "content": "==== ExternalSource: _external/external.sol ====\nimport {External} from \"_external/external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/source_import.sol",
    "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/source_import_subdir.sol",
    "content": "==== ExternalSource: _external/import_with_subdir.sol ====\n==== ExternalSource: subdir/import.sol=_external/subdir/import.sol ====\n==== ExternalSource: sub_external.sol=_external/subdir/sub_external.sol ====\nimport {SubExternal} from \"sub_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/source_name_starting_with_dots.sol",
    "content": "==== ExternalSource: ./a.sol=_sourceNameStartingWithDots/dot_a.sol ====\n==== ExternalSource: ../b.sol=_sourceNameStartingWithDots/dot_dot_b.sol ====\n==== ExternalSource: _sourceNameStartingWithDots/dir/a.sol ====\n==== ExternalSource: _sourceNameStartingWithDots/b.sol ====\n==== ExternalSource: _sourceNameStartingWithDots/dir/contract.sol ====\nimport {A, B} from \"_sourceNameStartingWithDots/dir/contract.sol\";\ncontract Contract {\n}\n// ----\n// constructor()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/externalSource/source_remapping.sol",
    "content": "==== ExternalSource: ExtSource.sol=_external/external.sol ====\n==== ExternalSource: /ExtSource.sol=_external/other_external.sol ====\nimport \"ExtSource.sol\";\nimport \"/ExtSource.sol\";\ncontract C {\n    External _external;\n    OtherExternal _otherExternal;\n}\n// ----\n// constructor()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/fallback/call_forward_bytes.sol",
    "content": "contract receiver {\n    uint256 public received;\n    function recv(uint256 x) public { received += x + 1; }\n    fallback() external { received = 0x80; }\n}\ncontract sender {\n    constructor() { rec = new receiver();}\n    fallback() external { savedData = msg.data; }\n    function forward() public returns (bool) { address(rec).call(savedData); return true; }\n    function clear() public returns (bool) { delete savedData; return true; }\n    function val() public returns (uint) { return rec.received(); }\n    receiver rec;\n    bytes savedData;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// recv(uint256): 7 ->\n// val() -> 0\n// forward() -> true\n// val() -> 8\n// clear() -> true\n// gas irOptimized: 29243\n// val() -> 8\n// forward() -> true\n// val() -> 0x80\n"
  },
  {
    "path": "test/libsolidity/semanticTests/fallback/falback_return.sol",
    "content": "contract A {\n    uint public x;\n    fallback () external {\n        if (x == 2) return;\n        x++;\n    }\n}\n// ----\n// ()\n// x() -> 1\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/fallback/fallback_argument.sol",
    "content": "contract A {\n    uint public x;\n    fallback (bytes calldata _input) external returns (bytes memory) {\n        x = _input.length;\n        return \"\";\n    }\n    function f() public returns (bool, bytes memory) {\n        (bool success, bytes memory retval) = address(this).call(\"abc\");\n        return (success, retval);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/fallback/fallback_argument_to_storage.sol",
    "content": "contract A {\n    bytes public x;\n    fallback (bytes calldata _input) external returns (bytes memory) {\n        x = _input;\n        return \"\";\n    }\n    function f() public returns (bool, bytes memory) {\n        (bool success, bytes memory retval) = address(this).call(\"abc\");\n        return (success, retval);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 0x20, 3, \"abc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/fallback/fallback_or_receive.sol",
    "content": "contract C {\n    uint x;\n    uint y;\n    fallback () payable external { ++x; }\n    receive () payable external { ++y; }\n    function f() external returns (uint, uint) { return (x, y); }\n}\n// ----\n// f() -> 0, 0\n// () ->\n// f() -> 0, 1\n// (), 1 ether ->\n// f() -> 0, 2\n// (): 1 ->\n// f() -> 1, 2\n// (), 1 ether: 1 ->\n// f() -> 2, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/fallback/fallback_override.sol",
    "content": "contract A {\n    fallback (bytes calldata _input) virtual external returns (bytes memory) {\n        return _input;\n    }\n}\ncontract B is A {\n    fallback (bytes calldata _input) override external returns (bytes memory) {\n        return \"xyz\";\n    }\n    function f() public returns (bool, bytes memory) {\n        (bool success, bytes memory retval) = address(this).call(\"abc\");\n        return (success, retval);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/fallback/fallback_override2.sol",
    "content": "contract A {\n    fallback (bytes calldata _input) virtual external returns (bytes memory) {\n        return _input;\n    }\n}\ncontract B is A {\n    fallback () override external {\n    }\n    function f() public returns (bool, bytes memory) {\n        (bool success, bytes memory retval) = address(this).call(\"abc\");\n        return (success, retval);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 1, 0x40, 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/fallback/fallback_override_multi.sol",
    "content": "contract A {\n    fallback (bytes calldata _input) virtual external returns (bytes memory) {\n        return _input;\n    }\n}\ncontract B {\n    fallback (bytes calldata _input) virtual external returns (bytes memory) {\n        return \"xyz\";\n    }\n}\ncontract C is B, A {\n    fallback () external override (B, A) {}\n    function f() public returns (bool, bytes memory) {\n        (bool success, bytes memory retval) = address(this).call(\"abc\");\n        return (success, retval);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/fallback/fallback_return_data.sol",
    "content": "contract A {\n    fallback (bytes calldata _input) external returns (bytes memory) {\n        return _input;\n    }\n    function f() public returns (bool, bytes memory) {\n        (bool success, bytes memory retval) = address(this).call(\"abc\");\n        return (success, retval);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/fallback/inherited.sol",
    "content": "contract A {\n    uint data;\n    fallback() external { data = 1; }\n    function getData() public returns (uint r) { return data; }\n}\ncontract B is A {}\n// ----\n// getData() -> 0\n// (): 42 ->\n// getData() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/fallback/short_data_calls_fallback.sol",
    "content": "contract A {\n    uint public x;\n    // Signature is d88e0b00\n    function fow() public { x = 3; }\n    fallback () external { x = 2; }\n}\n// ----\n// (): hex\"d88e0b\"\n// x() -> 2\n// (): hex\"d88e0b00\"\n// x() -> 3\n// (): hex\"d88e\"\n// x() -> 2\n// (): hex\"d88e0b00\"\n// x() -> 3\n// (): hex\"d8\"\n// x() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/freeFunctions/easy.sol",
    "content": "function add(uint a, uint b) pure returns (uint) {\n  return a + b;\n}\n\ncontract C {\n  function f(uint x) public pure returns (uint) {\n    return add(x, 2);\n  }\n}\n// ----\n// f(uint256): 7 -> 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/freeFunctions/free_namesake_contract_function.sol",
    "content": "function f() pure returns (uint) { return 1337; }\ncontract C {\n  function f() public pure returns (uint) {\n    return f();\n  }\n}\n// ----\n// f() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/freeFunctions/free_runtimecode.sol",
    "content": "contract C {\n  uint public x = 2;\n}\n\nfunction test() returns (bool) {\n  return type(C).runtimeCode.length > 20;\n}\n\ncontract D {\n  function f() public returns (bool) {\n    return test();\n  }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/freeFunctions/import.sol",
    "content": "==== Source: A ====\nstruct S { uint x; }\nfunction set(S storage a, uint v) { a.x = v; }\n\n==== Source: B ====\nimport \"A\";\nimport \"A\" as A;\ncontract C {\n  A.S data;\n  function f(uint v) public returns (uint one, uint two) {\n    A.set(data, v);\n    one = data.x;\n    set(data, v + 1);\n    two = data.x;\n  }\n}\n// ----\n// f(uint256): 7 -> 7, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/freeFunctions/libraries_from_free.sol",
    "content": "library L {\n  function pub() public pure returns (uint) {\n    return 7;\n  }\n  function inter() internal pure returns (uint) {\n    return 8;\n  }\n}\n\nfunction fu() pure returns (uint, uint) {\n  return (L.pub(), L.inter());\n}\n\ncontract C {\n  function f() public pure returns (uint, uint) {\n    return fu();\n  }\n}\n// ----\n// library: L\n// f() -> 7, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/freeFunctions/new_operator.sol",
    "content": "contract C {\n  uint public x = 2;\n}\n\nfunction test() returns (uint) {\n  return (new C()).x();\n}\n\ncontract D {\n  function f() public returns (uint) {\n    return test();\n  }\n}\n// ----\n// f() -> 2\n// gas legacy: 76611\n// gas legacy code: 23600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/freeFunctions/overloads.sol",
    "content": "function f(uint) returns (uint) {\n    return 2;\n}\nfunction f(string memory) returns (uint) {\n    return 3;\n}\n\ncontract C {\n  function g() public returns (uint, uint) {\n      return (f(2), f(\"abc\"));\n  }\n}\n// ----\n// g() -> 2, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/freeFunctions/recursion.sol",
    "content": "function exp(uint base, uint exponent) pure returns (uint power) {\n    if (exponent == 0)\n        return 1;\n    power = exp(base, exponent / 2);\n    power *= power;\n    if (exponent & 1 == 1)\n        power *= base;\n}\n\ncontract C {\n  function g(uint base, uint exponent) public pure returns (uint) {\n      return exp(base, exponent);\n  }\n}\n// ----\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 10 -> 59049\n// g(uint256,uint256): 2, 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n"
  },
  {
    "path": "test/libsolidity/semanticTests/freeFunctions/storage_calldata_refs.sol",
    "content": "contract C {\n    uint[] data;\n    function f(uint x, uint[] calldata input) public returns (uint, uint) {\n        data.push(x);\n        (uint a, uint[] calldata b) = fun(input, data);\n        return (a, b[1]);\n\n    }\n}\n\nfunction fun(uint[] calldata _x, uint[] storage _y) view  returns (uint, uint[] calldata) {\n\treturn (_y[0], _x);\n}\n// ----\n// f(uint256,uint256[]): 7, 0x40, 3, 8, 9, 10 -> 7, 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/array_multiple_local_vars.sol",
    "content": "contract test {\n    function f(uint256[] calldata seq) external pure returns (uint256) {\n        uint i = 0;\n        uint sum = 0;\n        while (i < seq.length)\n        {\n            uint idx = i;\n            if (idx >= 10) break;\n            uint x = seq[idx];\n            if (x >= 1000) {\n                uint n = i + 1;\n                i = n;\n                continue;\n            }\n            else {\n                uint y = sum + x;\n                sum = y;\n            }\n            if (sum >= 500) return sum;\n            i++;\n        }\n        return sum;\n    }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/bare_call_no_returndatacopy.sol",
    "content": "contract C {\n    function f() public returns (bool) {\n        // Random address, no contract deployed to it.\n        (bool success, ) = address(0xffff).call(\"\");\n        return success;\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/call_attached_library_function_on_function.sol",
    "content": "library L {\n    function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n    using L for *;\n    function f() public returns (uint) {\n        return t.g();\n    }\n    function t() public pure returns (uint)  { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/call_attached_library_function_on_storage_variable.sol",
    "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n    using D for D.s;\n    D.s public x;\n    function f(uint a) public returns (uint) {\n        x.a = 6;\n        return (x.mul)({x: a});\n    }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/call_attached_library_function_on_string.sol",
    "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n    using D for string;\n    string x;\n    function f() public returns (uint) {\n        x = \"abc\";\n        return x.length();\n    }\n    function g() public returns (uint) {\n        string memory s = \"abc\";\n        return s.length();\n    }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/call_function_returning_function.sol",
    "content": "contract test {\n    function f0() public returns (uint) {\n        return 2;\n    }\n\n    function f1() internal returns (function() internal returns (uint)) {\n        return f0;\n    }\n\n    function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n        return f1;\n    }\n\n    function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n        return f2;\n    }\n\n    function f() public returns (uint) {\n        function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n        x = f3;\n        return x()()()();\n    }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/call_function_returning_nothing_via_pointer.sol",
    "content": "contract test {\n    bool public flag = false;\n\n    function f0() public {\n        flag = true;\n    }\n\n    function f() public returns (bool) {\n        function() internal x = f0;\n        x();\n        return flag;\n    }\n}\n// ----\n// f() -> true\n// flag() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/call_internal_function_via_expression.sol",
    "content": "contract C {\n    function foo() internal returns (uint) {\n        return 42;\n    }\n\n    function get_ptr(function() internal returns (uint) ptr) internal returns(function() internal returns (uint)) {\n        return ptr;\n    }\n\n    function associated() public returns (uint) {\n        // This expression directly references function definition\n        return (foo)();\n    }\n\n    function unassociated() public returns (uint) {\n        // This expression is not associated with a specific function definition\n        return (get_ptr(foo))();\n    }\n}\n// ----\n// associated() -> 42\n// unassociated() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/call_internal_function_with_multislot_arguments_via_pointer.sol",
    "content": "contract C {\n    function m(\n        function() external returns (uint) a,\n        function() external returns (uint) b\n    ) internal returns (function() external returns (uint)) {\n        return a;\n    }\n\n    function s(uint a, uint b) internal returns (uint) {\n        return a + b;\n    }\n\n    function foo() external returns (uint) {\n        return 6;\n    }\n\n    function test() public returns (uint) {\n        function(uint, uint) internal returns (uint) single_slot_function = s;\n\n        function(\n            function() external returns (uint),\n            function() external returns (uint)\n        ) internal returns (function() external returns (uint)) multi_slot_function = m;\n\n        return multi_slot_function(this.foo, this.foo)() + single_slot_function(5, 1);\n    }\n}\n// ----\n// test() -> 12\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/call_options_overload.sol",
    "content": "contract C {\n    function f(uint x) external payable returns (uint) { return 1; }\n    function f(uint x, uint y) external payable returns (uint) { return 2; }\n    function call() public payable returns (uint v, uint x, uint y, uint z) {\n        v = this.f{value: 10}(2);\n        x = this.f{gas: 10000}(2, 3);\n        y = this.f{gas: 10000, value: 10}(2, 3);\n        z = this.f{value: 10, gas: 10000}(2, 3);\n    }\n    function bal() external returns (uint) { return address(this).balance; }\n    receive() external payable {}\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/calling_nonexisting_contract_throws.sol",
    "content": "abstract contract D {\n    function g() public virtual;\n}\n\n\ncontract C {\n    D d = D(address(0x1212));\n\n    function f() public returns (uint256) {\n        d.g();\n        return 7;\n    }\n\n    function g() public returns (uint256) {\n        d.g{gas: 200}();\n        return 7;\n    }\n\n    function h() public returns (uint256) {\n        address(d).call(\"\"); // this does not throw (low-level)\n        return 7;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/calling_other_functions.sol",
    "content": "contract collatz {\n    function run(uint x) public returns(uint y) {\n        while ((y = x) > 1) {\n            if (x % 2 == 0) x = evenStep(x);\n            else x = oddStep(x);\n        }\n    }\n    function evenStep(uint x) public returns(uint y) {\n        return x / 2;\n    }\n    function oddStep(uint x) public returns(uint y) {\n        return 3 * x + 1;\n    }\n}\n// ----\n// run(uint256): 0 -> 0\n// run(uint256): 1 -> 1\n// run(uint256): 2 -> 1\n// run(uint256): 8 -> 1\n// run(uint256): 127 -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/calling_uninitialized_function.sol",
    "content": "contract C {\n    function intern() public returns (uint256) {\n        function (uint) internal returns (uint) x;\n        x(2);\n        return 7;\n    }\n\n    function extern() public returns (uint256) {\n        function (uint) external returns (uint) x;\n        x(2);\n        return 7;\n    }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/calling_uninitialized_function_in_detail.sol",
    "content": "contract C {\n    function() returns (uint256) internal x;\n    int256 mutex;\n\n    function t() public returns (uint256) {\n        if (mutex > 0) {\n            assembly {\n                mstore(0, 7)\n                return(0, 0x20)\n            }\n        }\n        mutex = 1;\n        // Avoid re-executing this function if we jump somewhere.\n        x();\n        return 2;\n    }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/calling_uninitialized_function_through_array.sol",
    "content": "contract C {\n    int256 mutex;\n\n    function t() public returns (uint256) {\n        if (mutex > 0) {\n            assembly {\n                mstore(0, 7)\n                return(0, 0x20)\n            }\n        }\n        mutex = 1;\n        // Avoid re-executing this function if we jump somewhere.\n        function() internal returns (uint)[200] memory x;\n        x[0]();\n        return 2;\n    }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/conditional_with_arguments.sol",
    "content": "contract C {\n    function g(int x, int y) public pure returns (int) { return x - y; }\n    function h(int y, int x) public pure returns (int) { return y - x; }\n\n    function f() public pure returns (int) {\n        return (false ? g : h)(2, 1);\n    }\n}\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/creation_function_call_no_args.sol",
    "content": "contract C {\n    uint public i;\n    constructor() {\n        i = 2;\n    }\n}\ncontract D {\n    function f() public returns (uint r) {\n        return new C().i();\n    }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/creation_function_call_with_args.sol",
    "content": "contract C {\n    uint public i;\n    constructor(uint newI) {\n        i = newI;\n    }\n}\ncontract D {\n    C c;\n    constructor(uint v) {\n        c = new C(v);\n    }\n    function f() public returns (uint r) {\n        return c.i();\n    }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/creation_function_call_with_salt.sol",
    "content": "contract C {\n    uint public i;\n    constructor(uint newI) {\n        i = newI;\n    }\n}\ncontract D {\n    C c;\n    constructor(uint v) {\n        c = new C{salt: \"abc\"}(v);\n    }\n    function f() public returns (uint r) {\n        return c.i();\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 139112\n// gas irOptimized code: 53800\n// gas legacy: 145935\n// gas legacy code: 95600\n// gas legacyOptimized: 138529\n// gas legacyOptimized code: 54600\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/delegatecall_return_value.sol",
    "content": "contract C {\n    uint256 value;\n\n    function set(uint256 _value) external {\n        value = _value;\n    }\n\n    function get() external view returns (uint256) {\n        return value;\n    }\n\n    function get_delegated() external returns (bool, bytes memory) {\n        return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n    }\n\n    function assert0() external view {\n        assert(value == 0);\n    }\n\n    function assert0_delegated() external returns (bool, bytes memory) {\n        return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/delegatecall_return_value_pre_byzantium.sol",
    "content": "contract C {\n    uint256 value;\n\n    function set(uint256 _value) external {\n        value = _value;\n    }\n\n    function get() external view returns (uint256) {\n        return value;\n    }\n\n    function get_delegated() external returns (bool) {\n        (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n        return success;\n    }\n\n    function assert0() external view {\n        assert(value == 0);\n    }\n\n    function assert0_delegated() external returns (bool) {\n        (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n        return success;\n    }\n}\n// ====\n// EVMVersion: <byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/disordered_named_args.sol",
    "content": "contract test {\n    function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n    function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/eof/call_options_overload.sol",
    "content": "contract C {\n    function f(uint x) external payable returns (uint) { return 1; }\n    function f(uint x, uint y) external payable returns (uint) { return 2; }\n    function call() public payable returns (uint x, uint y) {\n        x = this.f{value: 10}(2);\n        y = this.f{value: 10}(2, 3);\n    }\n    function bal() external returns (uint) { return address(this).balance; }\n    receive() external payable {}\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// (), 1 ether\n// call() -> 1, 2\n// bal() -> 1000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/eof/calling_nonexisting_contract.sol",
    "content": "abstract contract D {\n    function g() public virtual;\n}\n\n\ncontract C {\n    D d = D(address(0x1212));\n\n    function f() public returns (uint256) {\n        // This call throws on legacy bytecode because of calling nonexisting contract. Legacy checks that there is\n        // a non-empty code under an address. EOF doesn't do it because non-observability assumption\n        d.g();\n        return 7;\n    }\n\n    function h() public returns (uint256) {\n        address(d).call(\"\"); // this does not throw (low-level)\n        return 7;\n    }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// f() -> 7\n// h() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/eof/external_call_at_construction_time.sol",
    "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n    constructor() { this.f(); }\n    function f() external {}\n}\ncontract U {\n    constructor() { this.f(); }\n    function f() external returns (uint) {}\n}\n\ncontract C {\n    function f(uint c) external returns (uint) {\n        if (c == 0) new T();\n        else if (c == 1) new U();\n        return 1 + c;\n    }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/eof/external_call_to_nonexisting.sol",
    "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n    function a() external pure;\n    function b() external;\n    function c() external payable;\n    function x() external returns (uint);\n    function y() external returns (string memory);\n}\ncontract C {\n    I i = I(address(0xcafecafe));\n    constructor() payable {}\n    function f(uint c) external returns (uint) {\n        if (c == 0) i.a();\n        else if (c == 1) i.b();\n        else if (c == 2) i.c();\n        else if (c == 3) i.c{value: 1}();\n        else if (c == 4) i.x();\n        else if (c == 5) i.y();\n        return 1 + c;\n    }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 2\n// f(uint256): 2 -> 3\n// f(uint256): 3 -> 4\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/external_call.sol",
    "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n    function g(uint n) external pure returns (uint) {\n        return n + 1;\n    }\n\n    function f(uint n) public view returns (uint) {\n        return this.g(2 * n);\n    }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/external_call_at_construction_time.sol",
    "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n    constructor() { this.f(); }\n    function f() external {}\n}\ncontract U {\n    constructor() { this.f(); }\n    function f() external returns (uint) {}\n}\n\ncontract C {\n    function f(uint c) external returns (uint) {\n        if (c == 0) new T();\n        else if (c == 1) new U();\n        return 1 + c;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// bytecodeFormat: legacy\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/external_call_dynamic_returndata.sol",
    "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n    function d(uint n) external pure returns (uint[] memory) {\n        uint[] memory data = new uint[](n);\n        for (uint i = 0; i < data.length; ++i)\n            data[i] = i;\n        return data;\n    }\n\n    function dt(uint n) public view returns (uint) {\n        uint[] memory data = this.d(n);\n        uint sum = 0;\n        for (uint i = 0; i < data.length; ++i)\n            sum += data[i];\n        return sum;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting.sol",
    "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n    function a() external pure;\n    function b() external;\n    function c() external payable;\n    function x() external returns (uint);\n    function y() external returns (string memory);\n}\ncontract C {\n    I i = I(address(0xcafecafe));\n    constructor() payable {}\n    function f(uint c) external returns (uint) {\n        if (c == 0) i.a();\n        else if (c == 1) i.b();\n        else if (c == 2) i.c();\n        else if (c == 3) i.c{value: 1}();\n        else if (c == 4) i.x();\n        else if (c == 5) i.y();\n        return 1 + c;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/external_call_to_nonexisting_debugstrings.sol",
    "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n    function a() external pure;\n    function b() external;\n    function c() external payable;\n    function x() external returns (uint);\n    function y() external returns (string memory);\n}\ncontract C {\n    I i = I(address(0xcafecafe));\n    constructor() payable {}\n    function f(uint c) external returns (uint) {\n        if (c == 0) i.a();\n        else if (c == 1) i.b();\n        else if (c == 2) i.c();\n        else if (c == 3) i.c{value: 1}();\n        else if (c == 4) i.x();\n        else if (c == 5) i.y();\n        return 1 + c;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// bytecodeFormat: legacy\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/external_call_value.sol",
    "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n    function g(uint n) external payable returns (uint, uint) {\n        return (msg.value * 1000, n);\n    }\n\n    function f(uint n) public payable returns (uint, uint) {\n        return this.g{value: 10}(n);\n    }\n}\n// ----\n// g(uint256), 1 ether: 4 -> 1000000000000000000000, 4\n// f(uint256), 11 ether: 2 -> 10000, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/external_function.sol",
    "content": "contract c {\n    function f(uint256 a) public returns (uint256) {\n        return a;\n    }\n\n    function test(uint256 a, uint256 b)\n        external\n        returns (uint256 r_a, uint256 r_b)\n    {\n        r_a = f(a + 7);\n        r_b = b;\n    }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/external_public_override.sol",
    "content": "contract A {\n    function f() external virtual returns (uint256) {\n        return 1;\n    }\n}\n\n\ncontract B is A {\n    function f() public override returns (uint256) {\n        return 2;\n    }\n\n    function g() public returns (uint256) {\n        return f();\n    }\n}\n// ----\n// f() -> 2\n// g() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/failed_create.sol",
    "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public {\n\t\tx++;\n\t\t(new D){value: amount, salt: bytes32(x)}();\n\t}\n\tfunction stack(uint depth) public payable {\n\t\tif (depth > 0)\n\t\t\tthis.stack(depth - 1);\n\t\telse\n\t\t\tf(0);\n\t}\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 59688\n// gas irOptimized code: 81800\n// gas legacy: 64468\n// gas legacy code: 145400\n// gas legacyOptimized: 60443\n// gas legacyOptimized code: 91200\n// f(uint256): 20 ->\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 298110\n// gas legacy: 527207\n// gas legacyOptimized: 353607\n// x() -> 1\n// stack(uint256): 10 ->\n// x() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/file_level_call_via_module.sol",
    "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n    function f() public pure returns (uint, uint) {\n        return (M.f(2), M.f(\"abc\"));\n\n    }\n}\n// ----\n// f() -> 7, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/gas_and_value_basic.sol",
    "content": "contract helper {\n    bool flag;\n\n    function getBalance() public payable returns (uint256 myBalance) {\n        return address(this).balance;\n    }\n\n    function setFlag() public {\n        flag = true;\n    }\n\n    function getFlag() public returns (bool fl) {\n        return flag;\n    }\n}\ncontract test {\n    helper h;\n\n    constructor() payable {\n        h = new helper();\n    }\n\n    function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n        return h.getBalance{value: amount}();\n    }\n\n    function outOfGas() public returns (bool ret) {\n        h.setFlag{gas: 2}(); // should fail due to OOG\n        return true;\n    }\n\n    function checkState() public returns (bool flagAfter, uint256 myBal) {\n        flagAfter = h.getFlag();\n        myBal = address(this).balance;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/inheritance/base_base_overload.sol",
    "content": "contract BaseBase {\n\tuint public x;\n\tuint public y;\n\tfunction init(uint a, uint b) public virtual {\n\t\tx = b;\n\t\ty = a;\n\t}\n\tfunction init(uint a) public virtual {\n\t\tx = a + 1;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction init(uint a, uint b) public override {\n\t\tx = a;\n\t\ty = b;\n\t}\n\tfunction init(uint a) public override {\n\t\tx = a;\n\t}\n}\n\ncontract Child is Base {\n\tfunction cInit(uint c) public {\n\t\tBase.init(c);\n\t}\n\tfunction cInit(uint c, uint d) public {\n\t\tBase.init(c, d);\n\t}\n\tfunction bInit(uint c) public {\n\t\tBaseBase.init(c);\n\t}\n\tfunction bInit(uint c, uint d) public {\n\t\tBaseBase.init(c, d);\n\t}\n}\n// ----\n// x() -> 0\n// y() -> 0\n// cInit(uint256): 2 ->\n// x() -> 2\n// y() -> 0\n// cInit(uint256,uint256): 3, 3 ->\n// x() -> 3\n// y() -> 3\n// bInit(uint256): 4 ->\n// x() -> 5\n// bInit(uint256,uint256): 9, 10 ->\n// x() -> 10\n// y() -> 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/inheritance/base_overload.sol",
    "content": "contract Base {\n\tuint public x;\n\tuint public y;\n\tfunction init(uint a, uint b) public {\n\t\tx = a;\n\t\ty = b;\n\t}\n\tfunction init(uint a) public {\n\t\tx = a;\n\t}\n}\n\ncontract Child is Base {\n\tfunction cInit(uint c) public {\n\t\tBase.init(c);\n\t}\n\tfunction cInit(uint c, uint d) public {\n\t\tBase.init(c, d);\n\t}\n}\n// ----\n// x() -> 0\n// y() -> 0\n// cInit(uint256): 2 ->\n// x() -> 2\n// y() -> 0\n// cInit(uint256,uint256): 3, 3 ->\n// x() -> 3\n// y() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/inheritance/call_base.sol",
    "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/inheritance/call_base_base.sol",
    "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n\n\tfunction h(uint n) public returns (uint) {\n\t\treturn s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 12\n// h(uint256): 4 -> 16\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/inheritance/call_base_base_explicit.sol",
    "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\t// calling base-bse function of a virtual overridden function.\n\t\treturn BaseBase.f(n);\n\t}\n\n\tfunction k(uint n) public returns (uint) {\n\t\t// Calling base-base function of a non-virtual function.\n\t\treturn BaseBase.s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n// k(uint256): 4 -> 16\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/inheritance/call_base_explicit.sol",
    "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn Base.f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/inheritance/call_unimplemented_base.sol",
    "content": "abstract contract I\n{\n    function a() internal view virtual returns(uint256);\n}\nabstract contract J is I\n{\n    function a() internal view virtual override returns(uint256);\n}\nabstract contract V is J\n{\n    function b() public view returns(uint256) { return a(); }\n}\ncontract C is V\n{\n    function a() internal view override returns (uint256) { return 42; }\n}\n// ----\n// b() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/inheritance/super_skip_unimplemented_in_abstract_contract.sol",
    "content": "contract A {\n    function f() public virtual returns (uint) {\n        return 42;\n    }\n}\n\nabstract contract I {\n    function f() external virtual returns (uint);\n}\n\ncontract B is A, I {\n    function f() override(A, I) public returns (uint) {\n        // I.f() is before A.f() in the C3 linearized order\n        // but it has no implementation.\n        return super.f();\n    }\n}\n// ----\n// f() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/inheritance/super_skip_unimplemented_in_interface.sol",
    "content": "contract A {\n    function f() public virtual returns (uint) {\n        return 42;\n    }\n}\n\ninterface I {\n    function f() external returns (uint);\n}\n\ncontract B is A, I {\n    function f() override(A, I) public returns (uint) {\n        // I.f() is before A.f() in the C3 linearized order\n        // but it has no implementation.\n        return super.f();\n    }\n}\n// ----\n// f() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol",
    "content": "contract test {\n    mapping(uint8 => uint8)[2] a;\n    mapping(uint8 => uint8)[2] b;\n    function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n        uint8 oldValue1 = m[0][key];\n        uint8 oldValue2 = m[1][key];\n        m[0][key] = value1;\n        m[1][key] = value2;\n        return (oldValue1, oldValue2);\n    }\n    function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n        (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n        (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n    }\n    function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n        return (a[0][key], a[1][key], b[0][key], b[1][key]);\n    }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/mapping_internal_argument.sol",
    "content": "contract test {\n    mapping(uint8 => uint8) a;\n    mapping(uint8 => uint8) b;\n    function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n        uint8 oldValue = m[key];\n        m[key] = value;\n        return oldValue;\n    }\n    function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n        old_a = set_internal(a, key, value_a);\n        old_b = set_internal(b, key, value_b);\n    }\n    function get(uint8 key) public returns (uint8, uint8) {\n        return (a[key], b[key]);\n    }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/mapping_internal_return.sol",
    "content": "contract test {\n    mapping(uint8 => uint8) a;\n    mapping(uint8 => uint8) b;\n    function f() internal returns (mapping(uint8 => uint8) storage r) {\n        r = a;\n        r[1] = 42;\n        r = b;\n        r[1] = 84;\n    }\n    function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n        f()[2] = 21;\n        return (a[0], a[1], a[2], b[0], b[1], b[2]);\n    }\n    function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n        mapping(uint8 => uint8) storage m = f();\n        m[2] = 17;\n        return (a[0], a[1], a[2], b[0], b[1], b[2]);\n    }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/member_accessors.sol",
    "content": "contract test {\n    uint256 public data;\n    bytes6 public name;\n    bytes32 public a_hash;\n    address public an_address;\n    constructor() {\n        data = 8;\n        name = \"Celina\";\n        a_hash = keccak256(\"\\x7b\");\n        an_address = address(0x1337);\n        super_secret_data = 42;\n    }\n    uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/multiple_functions.sol",
    "content": "contract test {\n    function a() public returns(uint n) { return 0; }\n    function b() public returns(uint n) { return 1; }\n    function c() public returns(uint n) { return 2; }\n    function f() public returns(uint n) { return 3; }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// a() -> 0\n// b() -> 1\n// c() -> 2\n// f() -> 3\n// i_am_not_there() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/multiple_return_values.sol",
    "content": "contract test {\n    function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n        y1 = x2; y2 = x1;\n    }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/named_args.sol",
    "content": "contract test {\n    function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n    function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n    function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/named_args_overload.sol",
    "content": "contract C {\n    function f() public returns (uint) {\n        return 0;\n    }\n    function f(uint a) public returns (uint) {\n        return a;\n    }\n    function f(uint a, uint b) public returns (uint) {\n        return a+b;\n    }\n    function f(uint a, uint b, uint c) public returns (uint) {\n        return a+b+c;\n    }\n    function call(uint num) public returns (uint256) {\n        if (num == 0)\n            return f();\n        if (num == 1)\n            return f({a: 1});\n        if (num == 2)\n            return f({b: 1, a: 2});\n        if (num == 3)\n            return f({c: 1, a: 2, b: 3});\n        if (num == 4)\n            return f({b: 5, c: 1, a: 2});\n\n        return 500;\n    }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/precompile_extcodesize_check.sol",
    "content": "interface Identity {\n    function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n    function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n    Identity constant i = Identity(address(0x0004));\n    function testHighLevel() external pure returns (bool) {\n        // Works because the extcodesize check is skipped\n        // and the precompiled contract returns actual data.\n        i.selectorAndAppendValue(5);\n        return true;\n    }\n    function testHighLevel2() external pure returns (uint, uint, uint) {\n        // Fails because the identity contract does not return enough data.\n        return ReturnMoreData(address(4)).f(2);\n    }\n    function testLowLevel() external view returns (uint value) {\n        (bool success, bytes memory ret) =\n            address(4).staticcall(\n                abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n            );\n        value = abi.decode(ret, (uint));\n    }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/return_size_bigger_than_expected.sol",
    "content": "interface ShortReturn {\n    function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n    function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n    function test() public returns (uint) {\n        LongReturn longReturn = new LongReturn();\n        uint freeMemoryBefore;\n        assembly {\n            freeMemoryBefore := mload(0x40)\n        }\n\n        ShortReturn(address(longReturn)).f();\n\n        uint freeMemoryAfter;\n\n        assembly {\n            freeMemoryAfter := mload(0x40)\n        }\n\n        return freeMemoryAfter - freeMemoryBefore;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/return_size_shorter_than_expected.sol",
    "content": "interface LongReturn {\n    function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n    function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n    function test() public returns (uint) {\n        ShortReturn shortReturn = new ShortReturn();\n        uint freeMemoryBefore;\n        assembly {\n            freeMemoryBefore := mload(0x40)\n        }\n\n        LongReturn(address(shortReturn)).f();\n\n        uint freeMemoryAfter;\n\n        assembly {\n            freeMemoryAfter := mload(0x40)\n        }\n\n        return freeMemoryAfter - freeMemoryBefore;\n    }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/return_size_shorter_than_expected_evm_version_after_homestead.sol",
    "content": "interface LongReturn {\n    function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n    function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n    function test() public returns (uint) {\n        ShortReturn shortReturn = new ShortReturn();\n        uint freeMemoryBefore;\n        assembly {\n            freeMemoryBefore := mload(0x40)\n        }\n\n        // This reverts. The external call succeeds but ABI decoding fails due to the returned\n        // `bytes32` being much shorter than the expected `uint[20]`.\n        LongReturn(address(shortReturn)).f();\n\n        uint freeMemoryAfter;\n\n        assembly {\n            freeMemoryAfter := mload(0x40)\n        }\n\n        return freeMemoryAfter - freeMemoryBefore;\n    }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/send_zero_ether.sol",
    "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n    receive() external payable {}\n}\n\n\ncontract Main {\n    constructor() payable {}\n\n    function s() public returns (bool) {\n        Receiver r = new Receiver();\n        return payable(r).send(0);\n    }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 56314\n// gas irOptimized code: 37400\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 56463\n// gas legacyOptimized code: 39600\n// s() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/transaction_status.sol",
    "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionCall/value_test.sol",
    "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionSelector/function_selector_via_contract_name.sol",
    "content": "contract A {\n    function f() external {}\n    function g(uint256) external {}\n}\ncontract B {\n    function f() external returns (uint256) {}\n    function g(uint256) external returns (uint256) {}\n}\ncontract C {\n    function test1() external returns(bytes4, bytes4, bytes4, bytes4) {\n        return (A.f.selector, A.g.selector, B.f.selector, B.g.selector);\n    }\n    function test2() external returns(bytes4, bytes4, bytes4, bytes4) {\n        A a; B b;\n        return (a.f.selector, a.g.selector, b.f.selector, b.g.selector);\n    }\n}\n// ----\n// test1() -> left(0x26121ff0), left(0xe420264a), left(0x26121ff0), left(0xe420264a)\n// test2() -> left(0x26121ff0), left(0xe420264a), left(0x26121ff0), left(0xe420264a)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/address_member.sol",
    "content": "contract C {\n    function f() public view returns (address a1, address a2) {\n        a1 = C(address(0x1234)).f.address;\n        C(address(0x1234)).f.address;\n        [C(address(0x1234)).f.address][0];\n        a2 = [C(address(0x1234)).f.address][0];\n    }\n}\n// ----\n// f() -> 0x1234, 0x1234\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/call_to_zero_initialized_function_type_ir.sol",
    "content": "contract Other {\n    function addTwo(uint256 x) public returns (uint256) {\n        return x + 2;\n    }\n}\ncontract C {\n    function (function (uint) external returns (uint)) internal returns (uint) ev;\n    function (uint) external returns (uint) x;\n\n    function store(function(uint) external returns (uint) y) public {\n         x = y;\n    }\n\n    function eval(function(uint) external returns (uint) y) public returns (uint) {\n        return y(7);\n    }\n\n    function t() public returns (uint256) {\n        this.store((new Other()).addTwo);\n        // This call panics\n        return ev(x);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/call_to_zero_initialized_function_type_legacy.sol",
    "content": "contract Other {\n    function addTwo(uint256 x) public returns (uint256) {\n        return x + 2;\n    }\n}\ncontract C {\n    function (function (uint) external returns (uint)) internal returns (uint) ev;\n    function (uint) external returns (uint) x;\n\n    function store(function(uint) external returns (uint) y) public {\n         x = y;\n    }\n\n    function eval(function(uint) external returns (uint) y) public returns (uint) {\n        return y(7);\n    }\n\n    function t() public returns (uint256) {\n        this.store((new Other()).addTwo);\n        // This call panics\n        return ev(x);\n    }\n}\n// ====\n// compileViaYul: false\n// ----\n// t() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/comparison_operator_for_external_function_cleans_dirty_bits.sol",
    "content": "contract C {\n  function g() external {}\n  function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n        function() external g_ptr_dirty = this.g;\n        assembly {\n                g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n                g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n        }\n        function() external g_ptr = this.g;\n        return g_ptr == g_ptr_dirty;\n  }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/comparison_operators_for_external_functions.sol",
    "content": "contract C {\n    function f() external {}\n    function g() external {}\n    function h() pure external {}\n    function i() view external {}\n\n    function comparison_operators_for_external_functions() public returns (bool) {\n        assert(\n            this.f != this.g &&\n            this.f != this.h &&\n            this.f != this.i &&\n\n            this.g != this.h &&\n            this.g != this.i &&\n\n            this.h != this.i &&\n\n            this.f == this.f &&\n            this.g == this.g &&\n            this.h == this.h &&\n            this.i == this.i\n        );\n        return true;\n    }\n\n    function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n        function () external f_local = this.f;\n        function () external g_local = this.g;\n        function () external pure h_local = this.h;\n        function () external view i_local = this.i;\n\n        assert(\n            f_local == this.f &&\n            g_local == this.g &&\n            h_local == this.h &&\n            i_local == this.i &&\n\n            f_local != this.g &&\n            f_local != this.h &&\n            f_local != this.i &&\n\n            g_local != this.f &&\n            g_local != this.h &&\n            g_local != this.i &&\n\n            h_local != this.f &&\n            h_local != this.g &&\n            h_local != this.i &&\n\n            i_local != this.f &&\n            i_local != this.g &&\n            i_local != this.h\n        );\n\n        assert(\n            f_local == f_local &&\n            f_local != g_local &&\n            f_local != h_local &&\n            f_local != i_local\n        );\n\n        assert(\n            g_local == g_local &&\n            g_local != h_local &&\n            g_local != i_local\n        );\n\n        assert(\n            h_local == h_local &&\n            i_local == i_local &&\n            h_local != i_local\n        );\n\n        return true;\n    }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/duplicated_function_definition_with_same_id_in_internal_dispatcher.sol",
    "content": "contract C {\n    function a() internal {}\n    function f() public {\n        function() ptr1 = a;\n        function() ptr2 = a;\n    }\n}\n// ----\n// f()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type.sol",
    "content": "contract C {\n    function g(string calldata) external returns (bool) { return true; }\n\n    function main() external returns (bool) {\n        function (string memory) external returns (bool) ptr = this.g;\n        return ptr(\"testString\");\n    }\n}\n// ----\n// main() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/function_delete_stack.sol",
    "content": "contract C {\n    function a() public returns (uint256) {\n        return 7;\n    }\n\n    function test() public returns (uint256) {\n        function() returns (uint256) y = a;\n        delete y;\n        y();\n    }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/function_delete_storage.sol",
    "content": "contract C {\n    function a() public returns (uint256) {\n        return 7;\n    }\n\n    function() returns (uint256) internal y;\n\n    function set() public returns (uint256) {\n        y = a;\n        return y();\n    }\n\n    function d() public returns (uint256) {\n        delete y;\n        return 1;\n    }\n\n    function ca() public returns (uint256) {\n        return y();\n    }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/function_external_delete_storage.sol",
    "content": "contract C {\n    function() external public x;\n\n    function f() public {}\n\n    function set() external {\n        x = this.f;\n    }\n\n    function isF() external returns (bool) {\n        return x == this.f;\n    }\n\n    function isZero() external returns (bool) {\n        function() external zero;\n        return x == zero;\n    }\n\n    function deleteFunction() public {\n        // used to lead to an ICE during IR\n        delete x;\n    }\n}\n// ----\n// isF() -> false\n// isZero() -> true\n// deleteFunction() ->\n// isF() -> false\n// isZero() -> true\n// set() ->\n// isF() -> true\n// isZero() -> false\n// deleteFunction() ->\n// isF() -> false\n// isZero() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/function_type_library_internal.sol",
    "content": "library Utils {\n    function reduce(\n        uint256[] memory array,\n        function(uint, uint) internal returns (uint) f,\n        uint256 init\n    ) internal returns (uint256) {\n        for (uint256 i = 0; i < array.length; i++) {\n            init = f(array[i], init);\n        }\n        return init;\n    }\n\n    function sum(uint256 a, uint256 b) internal returns (uint256) {\n        return a + b;\n    }\n}\n\n\ncontract C {\n    function f(uint256[] memory x) public returns (uint256) {\n        return Utils.reduce(x, Utils.sum, 0);\n    }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/inline_array_with_value_call_option.sol",
    "content": "contract C {\n    function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n    function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n    function h() public payable returns (uint) {\n        return [this.f, this.g][0]{value: 1}();\n    }\n}\n// ----\n// h(), 1 ether -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/mapping_of_functions.sol",
    "content": "contract Flow {\n    bool public success;\n\n    mapping(address => function() internal) stages;\n\n    function stage0() internal {\n        stages[msg.sender] = stage1;\n    }\n\n    function stage1() internal {\n        stages[msg.sender] = stage2;\n    }\n\n    function stage2() internal {\n        success = true;\n    }\n\n    constructor() {\n        stages[msg.sender] = stage0;\n    }\n\n    function f() public returns (uint256) {\n        stages[msg.sender]();\n        return 7;\n    }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/pass_function_types_externally.sol",
    "content": "contract C {\n    function f(uint256 x) public returns (uint256) {\n        return this.eval(this.g, x);\n    }\n\n    function f2(uint256 x) public returns (uint256) {\n        return eval(this.g, x);\n    }\n\n    function eval(function(uint) external returns (uint) x, uint a) public returns (uint) {\n        return x(a);\n    }\n\n    function g(uint256 x) public returns (uint256) {\n        return x + 1;\n    }\n}\n// ----\n// f(uint256): 7 -> 8\n// f2(uint256): 7 -> 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/pass_function_types_internally.sol",
    "content": "contract C {\n    function f(uint256 x) public returns (uint256) {\n        return eval(g, x);\n    }\n\n    function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n        return x(a);\n    }\n\n    function g(uint256 x) public pure returns (uint256) {\n        return x + 1;\n    }\n}\n// ----\n// f(uint256): 7 -> 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/same_function_in_construction_and_runtime.sol",
    "content": "contract C {\n    uint256 public initial;\n\n    constructor() {\n        initial = double(2);\n    }\n\n    function double(uint256 _arg) public returns (uint256 _ret) {\n        _ret = _arg * 2;\n    }\n\n    function runtime(uint256 _arg) public returns (uint256) {\n        return double(_arg);\n    }\n}\n// ----\n// runtime(uint256): 3 -> 6\n// initial() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/same_function_in_construction_and_runtime_equality_check.sol",
    "content": "contract C {\n    function(uint256) returns (uint256) internal x;\n\n    constructor() {\n        x = double;\n    }\n\n    function test() public returns (bool) {\n        return x == double;\n    }\n\n    function double(uint256 _arg) public returns (uint256 _ret) {\n        _ret = _arg * 2;\n    }\n}\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/selector_1.sol",
    "content": "contract B {\n    function ext() external {}\n    function pub() public {}\n}\n\ncontract C is B {\n    function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n        return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/selector_2.sol",
    "content": "contract B {\n    function ext() external {}\n    function pub() public {}\n}\n\ncontract D {\n    function test() public returns (bytes4, bytes4) {\n        return (B.ext.selector, B.pub.selector);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/selector_assignment_expression.sol",
    "content": "contract C {\n    bool public z;\n    function f() public {\n        ((z = true) ? this.f : this.f).selector;\n    }\n}\n\n// ----\n// f()\n// z() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/selector_expression_side_effect.sol",
    "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/selector_ternary.sol",
    "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/selector_ternary_function_pointer_from_function_call.sol",
    "content": "contract A {\n    function f() public {}\n\tfunction g() public {}\n}\n\ncontract C {\n    A a = new A();\n\n    function getContract() public view returns (A) {\n        return a;\n    }\n\n    function test(bool b) public view returns (bytes4) {\n        return (b ? getContract().f : getContract().g).selector;\n    }\n}\n// ----\n// test(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// test(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/stack_height_check_on_adding_gas_variable_to_function.sol",
    "content": "contract C {\n    function g() external {}\n    function h() external payable {}\n    function test_function() external returns (bool){\n        assert (\n            this.g.address == this.g.address &&\n            this.g{gas: 42}.address == this.g.address &&\n            this.g{gas: 42}.selector == this.g.selector\n        );\n        assert (\n            this.h.address == this.h.address &&\n            this.h{gas: 42}.address == this.h.address &&\n            this.h{gas: 42}.selector == this.h.selector\n        );\n        assert (\n            this.h{gas: 42, value: 5}.address == this.h.address &&\n            this.h{gas: 42, value: 5}.selector == this.h.selector\n        );\n        return true;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// test_function() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/store_function.sol",
    "content": "contract Other {\n    function addTwo(uint256 x) public returns (uint256) {\n        return x + 2;\n    }\n}\n\n\ncontract C {\n    function (function (uint) external returns (uint)) internal returns (uint) ev;\n    function (uint) external returns (uint) x;\n\n    function store(function(uint) external returns (uint) y) public {\n        x = y;\n    }\n\n    function eval(function(uint) external returns (uint) y) public returns (uint) {\n        return y(7);\n    }\n\n    function t() public returns (uint256) {\n        ev = eval;\n        this.store((new Other()).addTwo);\n        return ev(x);\n    }\n}\n// ----\n// t() -> 9\n// gas irOptimized: 77300\n// gas irOptimized code: 19000\n// gas legacy: 79492\n// gas legacy code: 69600\n// gas legacyOptimized: 77587\n// gas legacyOptimized code: 28600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/struct_with_external_function.sol",
    "content": "struct S {\n    uint16 a;\n    function() external returns (uint) x;\n    uint16 b;\n}\ncontract Flow {\n    S[2] t;\n\n    function X() public pure returns (uint) {\n        return 1;\n    }\n\n    function Y() public pure returns (uint) {\n        return 2;\n    }\n\n    constructor() {\n        t[0].a = 0xff07;\n        t[0].b = 0xff07;\n        t[1].x = this.Y;\n        t[1].a = 0xff07;\n        t[1].b = 0xff07;\n        t[0].x = this.X;\n    }\n\n    function f() public returns (uint, uint) {\n        return (t[0].x(), t[1].x());\n    }\n}\n// ----\n// f() -> 1, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/struct_with_functions.sol",
    "content": "struct S {\n    uint16 a;\n    function() returns (uint) x;\n    uint16 b;\n}\ncontract Flow {\n    S[2] t;\n\n    function X() internal pure returns (uint) {\n        return 1;\n    }\n\n    function Y() internal pure returns (uint) {\n        return 2;\n    }\n\n    constructor() {\n        t[0].a = 0xff07;\n        t[0].b = 0xff07;\n        t[1].x = Y;\n        t[1].a = 0xff07;\n        t[1].b = 0xff07;\n        t[0].x = X;\n    }\n\n    function f() public returns (uint, uint) {\n        return (t[0].x(), t[1].x());\n    }\n}\n// ----\n// f() -> 1, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/ternary_contract_internal_function.sol",
    "content": "contract C {\n    function f() internal pure returns(uint256) { return 1;}\n    function g() internal pure returns(uint256) { return 2; }\n    function test(bool b) public returns(uint256) {\n        return (b ? C.f : C.g)();\n    }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/ternary_contract_library_internal_function.sol",
    "content": "library L {\n    function f() internal pure returns(uint256){ return 1; }\n}\n\ncontract C {\n    function g() internal pure returns(uint256) { return 2; }\n    function test(bool b) public returns(uint256) {\n        return (b ? L.f : C.g)();\n    }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/ternary_contract_public_function.sol",
    "content": "contract C {\n    function f() public pure returns(uint256) { return 1; }\n    function g() public pure returns(uint256) { return 2; }\n    function test(bool b) public returns(uint256) {\n        return (b ? C.f : C.g)();\n    }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/functionTypes/uninitialized_internal_storage_function_call.sol",
    "content": "contract Test {\n    function() internal x;\n\n    function f() public returns (uint256 r) {\n        x();\n        return 2;\n    }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/array_mapping_struct.sol",
    "content": "contract C {\n    struct Y {\n        uint a;\n        uint b;\n    }\n    mapping(uint256 => Y)[] public m;\n    mapping(uint256 => Y)[3] public n;\n    constructor() {\n        m.push();\n        m.push();\n        m[1][0].a = 1;\n        m[1][0].b = 2;\n        m[1][1].a = 3;\n        m[1][1].b = 4;\n        n[1][0].a = 7;\n        n[1][0].b = 8;\n        n[1][1].a = 9;\n        n[1][1].b = 10;\n    }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/arrays.sol",
    "content": "contract C {\n    uint8[][2] public a;\n    constructor() {\n        a[1].push(3);\n        a[1].push(4);\n    }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/bytes.sol",
    "content": "contract C {\n    bytes public b;\n    constructor() {\n        b = \"abc\";\n    }\n}\n// ----\n// b() -> 0x20, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/mapping.sol",
    "content": "contract C {\n    mapping(uint => mapping(uint => uint)) public x;\n    constructor() {\n        x[1][2] = 3;\n    }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/mapping_array_struct.sol",
    "content": "contract C {\n    struct Y {\n        uint a;\n        uint b;\n    }\n    mapping(uint256 => Y[]) public m;\n    mapping(uint256 => Y[3]) public n;\n    constructor() {\n        m[1].push().a = 1;\n        m[1][0].b = 2;\n        m[1].push().a = 3;\n        m[1][1].b = 4;\n        n[1][0].a = 7;\n        n[1][0].b = 8;\n        n[1][1].a = 9;\n        n[1][1].b = 10;\n    }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/mapping_of_string.sol",
    "content": "contract C {\n    mapping(string => uint8[3]) public x;\n    constructor() {\n        x[\"abc\"][0] = 1;\n        x[\"abc\"][2] = 3;\n        x[\"abc\"][1] = 2;\n        x[\"def\"][1] = 9;\n    }\n}\n// ----\n// x(string,uint256): 0x40, 0, 3, \"abc\" -> 1\n// x(string,uint256): 0x40, 1, 3, \"abc\" -> 2\n// x(string,uint256): 0x40, 2, 3, \"abc\" -> 3\n// x(string,uint256): 0x40, 0, 3, \"def\" -> 0x00\n// x(string,uint256): 0x40, 1, 3, \"def\" -> 9\n// x(string,uint256): 0x40, 2, 3, \"def\" -> 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/mapping_to_struct.sol",
    "content": "contract C {\n    struct S {\n        uint8 a;\n        uint16 b;\n        uint128 c;\n        uint d;\n    }\n    mapping(uint => mapping(uint => S)) public x;\n    constructor() {\n        x[1][2].a = 3;\n        x[1][2].b = 4;\n        x[1][2].c = 5;\n        x[1][2].d = 6;\n    }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6\n// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/mapping_with_names.sol",
    "content": "contract C {\n    mapping(uint a => mapping(uint b => uint c)) public x;\n    constructor() {\n        x[1][2] = 3;\n    }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/string_and_bytes.sol",
    "content": "contract C {\n    string public a;\n    string public b;\n    bytes public c;\n    string public d = \"abcd\";\n    constructor() {\n        a = \"hello world\";\n        b = hex\"41424344\";\n        c = hex\"ff077fff\";\n    }\n}\n// ----\n// a() -> 0x20, 11, \"hello world\"\n// b() -> 0x20, 4, \"ABCD\"\n// c() -> 0x20, 4, -439061522557375173052089223601630338202760422010735733633791622124826263552\n// d() -> 0x20, 4, \"abcd\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/struct_with_bytes.sol",
    "content": "contract C {\n    struct S {\n        uint a;\n        bytes b;\n        mapping(uint => uint) c;\n        uint[] d;\n    }\n    uint shifter;\n    S public s;\n    constructor() {\n        s.a = 7;\n        s.b = \"abc\";\n        s.c[0] = 9;\n        s.d.push(10);\n    }\n}\n// ----\n// s() -> 7, 0x40, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/struct_with_bytes_simple.sol",
    "content": "contract C {\n    struct S {\n        uint a;\n        bytes b;\n        mapping(uint => uint) c;\n        uint[] d;\n    }\n    uint shifter;\n    S public s;\n    constructor() {\n        s.a = 7;\n        s.b = \"abc\";\n        s.c[0] = 9;\n    }\n}\n// ----\n// s() -> 0x07, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/transient_value_types.sol",
    "content": "contract C {\n    int8 public transient x;\n\n    function f() public returns(int8) {\n        x = -1;\n        return this.x();\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/transient_value_types_multi_frame_call.sol",
    "content": "contract C {\n    int8 public transient x;\n\n    function f() public returns(int8) {\n        x = -1;\n        return this.h();\n    }\n    function g() public {\n        x = x - 1;\n    }\n    function h() public returns(int8) {\n        this.g();\n        return this.x();\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -2\n// h() -> -1\n// x() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/getters/value_types.sol",
    "content": "contract C {\n    uint8 public a;\n    uint16 public b;\n    uint128 public c;\n    uint public d;\n    bytes1 public e;\n    bytes20 public f;\n    bytes32 public g;\n    bool public h;\n    address public i;\n    constructor() {\n        a = 3;\n        b = 4;\n        c = 5;\n        d = 6;\n        e = bytes1(uint8(0x7f));\n        f = bytes20(uint160(0x6465616462656566313564656164000000000010));\n        g = bytes32(uint256(0x6465616462656566313564656164000000000000000000000000000000000010));\n        h = true;\n        i = address(type(uint160).max / 3);\n    }\n}\n// ----\n// a() -> 3\n// b() -> 4\n// c() -> 5\n// d() -> 6\n// e() -> 0x7f00000000000000000000000000000000000000000000000000000000000000\n// f() -> 0x6465616462656566313564656164000000000010000000000000000000000000\n// g() -> 0x6465616462656566313564656164000000000000000000000000000000000010\n// h() -> true\n// i() -> 0x5555555555555555555555555555555555555555\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/assign_at_declaration.sol",
    "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/assign_from_immutables.sol",
    "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/delete.sol",
    "content": "contract C {\n    uint8 immutable public a;\n    uint8 immutable public b = 0x42;\n    uint public c;\n\n    constructor() {\n        delete a;\n        delete b;\n        c = b * 2 + a;\n    }\n}\n// ----\n// a() -> 0\n// b() -> 0\n// c() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/fun_read_in_ctor.sol",
    "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = readA();\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n\n\tfunction readA() public view returns (uint8) {\n\t\treturn a;\n\t}\n}\n// ----\n// readX() -> 3\n// readA() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/getter.sol",
    "content": "contract C {\n    uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/getter_call_in_constructor.sol",
    "content": "contract A {\n    uint immutable public x = 1;\n    uint public y;\n    constructor() {\n        y = this.x();\n    }\n}\ncontract C {\n    function f() public returns (bool) {\n        try new A() { return false; }\n        catch { return true; }\n    }\n}\n// ====\n// EVMVersion: >=tangerineWhistle\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/immutable_signed.sol",
    "content": "contract C {\n    int8 immutable a = -2;\n    bytes2 immutable b = \"ab\";\n    function() internal returns (uint) immutable f = g;\n    function viaasm() view external returns (bytes32 x, bytes32 y) {\n        int8 _a = a;\n        bytes2 _b = b;\n        assembly { x := _a y := _b }\n    }\n    function g() internal pure returns (uint) { return 2; }\n}\n// ----\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/immutable_tag_too_large_bug.sol",
    "content": "contract C {\n  int immutable x = 1;\n  int immutable y = 3;\n\n  function f() public payable returns(int, int) {\n    uint a = uint(y / 1e8);\n    int256 b = x * y;\n    int24 c = int24(b * b >> 128);\n    int24 d = int24((100 * y + 1) >> 128);\n    int24 e = int24(x >> 128);\n    int256 f = x * 2;\n    if (c < 0) {\n      int256 g = (x * x * y) / x;\n      require((y >= 0 && g <= x) || (y < 0 && (x - y) > x));\n      if (b >= f) {\n        require(x <= int256(uint256(type(uint168).max)) && x >= 0, \"\");\n        b = (b * b) / f;\n        for (a = 0; a < a; a++) {\n          uint8 b;\n          assembly  {\n            b := and(mload(a), 0xFF)\n          }\n        }\n        b += f;\n      }\n      require(d % e != 0);\n      c = -c;\n    }\n    return (x, ((x * (x - y)) / (x + y)));\n  }\n\n  constructor () {\n    x--;\n    --x;\n    y++;\n    ++y;\n    --y;\n  }\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 73171\n// gas irOptimized code: 291200\n// gas legacy: 83499\n// gas legacy code: 408800\n// f() -> -1, 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/increment_decrement.sol",
    "content": "contract C {\n    int immutable x = 1;\n    int immutable y = 3;\n\n    constructor() {\n        x--;\n        --x;\n        y++;\n        ++y;\n        --y;\n    }\n\n    function f() public view returns (int, int) {\n        return (x, y);\n    }\n}\n// ----\n// f() -> -1, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/inheritance.sol",
    "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/internal_function_pointer.sol",
    "content": "contract C {\n\tfunction() internal view returns(uint256) immutable z;\n\tconstructor() {\n\t\tz = f;\n\t}\n\tfunction f() public view returns (uint256) {\n\t\treturn 7;\n\t}\n\tfunction callZ() public view returns (uint) {\n\t\treturn z();\n\t}\n}\n// ----\n// f() -> 7\n// callZ() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/multi_creation.sol",
    "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A{salt: hex\"00\"}()).f();\n\t\ty = (new B{salt: hex\"00\"}()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A{salt: hex\"01\"}()).f(), (new B{salt: hex\"01\"}()).f());\n\t}\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86892\n// gas irOptimized code: 37200\n// gas legacy: 87839\n// gas legacy code: 60800\n// gas legacyOptimized: 86870\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/multiple_initializations.sol",
    "content": "contract A {\n    uint immutable x = x + 1;\n    uint immutable y = x += 2;\n\n    constructor(uint) m(x += 16) m(x += 32) {\n        x += 64;\n        x += 128;\n    }\n\n    modifier m(uint) {\n        _;\n    }\n\n    function get() public returns (uint) {\n        return x;\n    }\n}\n\ncontract B is A(A.x += 8) {\n    constructor(uint) {}\n}\n\ncontract C is B {\n    constructor() B(x += 4) {}\n}\n// ----\n// get() -> 0xff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/read_in_ctor.sol",
    "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/small_types_in_reverse.sol",
    "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/stub.sol",
    "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tconstructor() {\n\t\tx = 42;\n\t\ty = 23;\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// f() -> 84, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/uninitialized.sol",
    "content": "contract C {\n    uint immutable u;\n    bool immutable b;\n    address immutable a;\n\n    function get() public returns (uint, bool, address) {\n        return (u, b, a);\n    }\n}\n// ----\n// get() -> 0, false, 0x0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/immutable/use_scratch.sol",
    "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tmapping(uint => uint) public m;\n\tconstructor(uint _a) {\n\t\tx = 42;\n\t\ty = 23;\n\t\tm[_a] = 7;\n\t\tnew uint[](4);\n\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// constructor(): 3 ->\n// gas irOptimized: 81194\n// gas irOptimized code: 42400\n// gas legacy: 88244\n// gas legacy code: 109400\n// gas legacyOptimized: 81858\n// gas legacyOptimized code: 55800\n// f() -> 84, 23\n// m(uint256): 3 -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/access_base_storage.sol",
    "content": "contract Base {\n    uint256 dataBase;\n\n    function getViaBase() public returns (uint256 i) {\n        return dataBase;\n    }\n}\n\n\ncontract Derived is Base {\n    uint256 dataDerived;\n\n    function setData(uint256 base, uint256 derived) public returns (bool r) {\n        dataBase = base;\n        dataDerived = derived;\n        return true;\n    }\n\n    function getViaDerived() public returns (uint256 base, uint256 derived) {\n        base = dataBase;\n        derived = dataDerived;\n    }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol",
    "content": "contract C {\n    function balance() public returns (uint256) {\n        return 1;\n    }\n\n    function transfer(uint256 amount) public returns (uint256) {\n        return amount;\n    }\n}\n\n\ncontract D {\n    function f() public returns (uint256) {\n        return (new C{salt: hex\"00\"}()).balance();\n    }\n\n    function g() public returns (uint256) {\n        return (new C{salt: hex\"01\"}()).transfer(5);\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 1\n// gas irOptimized: 54014\n// gas irOptimized code: 20200\n// gas legacy: 54553\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 54042\n// gas irOptimized code: 20200\n// gas legacy: 55090\n// gas legacy code: 57800\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/base_access_to_function_type_variables.sol",
    "content": "contract C {\n    function() returns (uint256) internal x;\n\n    function set() public {\n        C.x = g;\n    }\n\n    function g() public pure returns (uint256) {\n        return 2;\n    }\n\n    function h() public returns (uint256) {\n        return C.x();\n    }\n}\n// ----\n// g() -> 2\n// h() -> FAILURE, hex\"4e487b71\", 0x51\n// set() ->\n// h() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order.sol",
    "content": "contract A {\n    uint x;\n    constructor() {\n        x = 42;\n    }\n    function f() public returns(uint256) {\n        return x;\n    }\n}\ncontract B is A {\n    uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order_2.sol",
    "content": "contract A {\n    uint x = 42;\n    function f() public returns(uint256) {\n        return x;\n    }\n}\ncontract B is A {\n    uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order_3_legacy.sol",
    "content": "contract A {\n    uint public x = 2;\n    constructor(uint) {}\n    function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n    constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/constructor_inheritance_init_order_3_viaIR.sol",
    "content": "contract A {\n    uint public x = 2;\n    constructor(uint) {}\n    function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n    constructor() A(f()) {}\n}\n// ====\n// compileViaYul: true\n// ----\n// x() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/constructor_with_params.sol",
    "content": "contract C {\n    uint public i;\n    uint public k;\n\n    constructor(uint newI, uint newK) {\n        i = newI;\n        k = newK;\n    }\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 81170\n// gas irOptimized code: 20200\n// gas legacy: 83613\n// gas legacy code: 32000\n// i() -> 2\n// k() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/constructor_with_params_diamond_inheritance.sol",
    "content": "contract A {\n    uint public i;\n    uint public k;\n\n    constructor(uint newI, uint newK) {\n        i = newI;\n        k = newK;\n    }\n}\nabstract contract B is A {\n    uint public j;\n    constructor(uint newJ) {\n        j = newJ;\n    }\n}\ncontract C is A {\n    constructor(uint newI, uint newK) A(newI, newK) {}\n}\ncontract D is B, C {\n    constructor(uint newI, uint newK) B(newI) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 124350\n// gas irOptimized code: 27600\n// gas legacy: 128222\n// gas legacy code: 40400\n// gas legacyOptimized: 123920\n// gas legacyOptimized code: 20600\n// i() -> 2\n// j() -> 2\n// k() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/constructor_with_params_inheritance.sol",
    "content": "contract C {\n    uint public i;\n    uint public k;\n\n    constructor(uint newI, uint newK) {\n        i = newI;\n        k = newK;\n    }\n}\ncontract D is C {\n    constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/constructor_with_params_inheritance_2.sol",
    "content": "contract C {\n    uint public i;\n    uint public k;\n\n    constructor(uint newI, uint newK) {\n        i = newI;\n        k = newK;\n    }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/dataLocation/external_public_calldata.sol",
    "content": "abstract contract A {\n    function f(uint256[] calldata a) external virtual returns (uint256[] calldata);\n}\n\ncontract B is A {\n    function f(uint256[] memory a) public override returns (uint256[] memory) {\n        return a;\n    }\n\n    function g(uint[] calldata x) public returns (uint256[] memory) {\n        return f(x);\n    }\n}\n// ====\n// compileViaYul: also\n// ----\n// f(uint256[]): 0x20, 2, 9, 8 -> 0x20, 2, 9, 8\n// g(uint256[]): 0x20, 2, 9, 8 -> 0x20, 2, 9, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/derived_overload_base_function_direct.sol",
    "content": "contract B {\n    function f() public returns (uint256) {\n        return 10;\n    }\n}\n\n\ncontract C is B {\n    function f(uint256 i) public returns (uint256) {\n        return 2 * i;\n    }\n\n    function g() public returns (uint256) {\n        return f(1);\n    }\n}\n// ----\n// g() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/derived_overload_base_function_indirect.sol",
    "content": "contract A {\n    function f(uint256 a) public returns (uint256) {\n        return 2 * a;\n    }\n}\n\n\ncontract B {\n    function f() public returns (uint256) {\n        return 10;\n    }\n}\n\n\ncontract C is A, B {\n    function g() public returns (uint256) {\n        return f();\n    }\n\n    function h() public returns (uint256) {\n        return f(1);\n    }\n}\n// ----\n// g() -> 10\n// h() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/explicit_base_class.sol",
    "content": "contract BaseBase {\n    function g() public virtual returns (uint256 r) {\n        return 1;\n    }\n}\n\n\ncontract Base is BaseBase {\n    function g() public virtual override returns (uint256 r) {\n        return 2;\n    }\n}\n\n\ncontract Derived is Base {\n    function f() public returns (uint256 r) {\n        return BaseBase.g();\n    }\n\n    function g() public override returns (uint256 r) {\n        return 3;\n    }\n}\n// ----\n// g() -> 3\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/inherited_constant_state_var.sol",
    "content": "contract A {\n    uint256 constant x = 7;\n}\n\n\ncontract B is A {\n    function f() public returns (uint256) {\n        return A.x;\n    }\n}\n// ----\n// f() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/inherited_function.sol",
    "content": "contract A {\n    function f() internal virtual returns (uint256) {\n        return 1;\n    }\n}\n\n\ncontract B is A {\n    function f() internal override returns (uint256) {\n        return 2;\n    }\n\n    function g() public returns (uint256) {\n        return A.f();\n    }\n}\n// ----\n// g() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol",
    "content": "interface I {\n    function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n    function f(uint256[] calldata a) external override returns (uint256) {\n        return 42;\n    }\n}\n\n\ncontract B {\n    function f(uint256[] memory a) public returns (uint256) {\n        return a[1];\n    }\n\n    function g() public returns (uint256) {\n        I i = I(new A());\n        return i.f(new uint256[](2));\n    }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 54536\n// gas irOptimized code: 24800\n// gas legacy: 55868\n// gas legacy code: 66600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory.sol",
    "content": "contract A {\n    function f(uint256[] calldata a) external virtual returns (uint256) {\n        return a[0];\n    }\n}\n\n\ncontract B is A {\n    function f(uint256[] memory a) public override returns (uint256) {\n        return a[1];\n    }\n\n    function g() public returns (uint256) {\n        uint256[] memory m = new uint256[](2);\n        m[0] = 42;\n        m[1] = 23;\n        return A(this).f(m);\n    }\n}\n// ----\n// g() -> 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol",
    "content": "interface I {\n    function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n    function f(uint256[] memory a) public override returns (uint256) {\n        return 42;\n    }\n}\n\n\ncontract B {\n    function f(uint256[] memory a) public returns (uint256) {\n        return a[1];\n    }\n\n    function g() public returns (uint256) {\n        I i = I(new A());\n        return i.f(new uint256[](2));\n    }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 54828\n// gas irOptimized code: 42000\n// gas legacy: 56839\n// gas legacy code: 123600\n// gas legacyOptimized: 55001\n// gas legacyOptimized code: 60600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/inherited_function_from_a_library.sol",
    "content": "library A {\n    function f() internal returns (uint256) {\n        return 1;\n    }\n}\n\n\ncontract B {\n    function f() internal returns (uint256) {\n        return 2;\n    }\n\n    function g() public returns (uint256) {\n        return A.f();\n    }\n}\n// ----\n// g() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/inherited_function_through_dispatch.sol",
    "content": "contract A {\n    function f() internal virtual returns (uint256) {\n        return 1;\n    }\n}\n\n\ncontract B is A {\n    function f() internal override returns (uint256) {\n        return 2;\n    }\n\n    function g() public returns (uint256) {\n        function() internal returns (uint256) ptr = A.f;\n        return ptr();\n    }\n}\n// ----\n// g() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/interface_inheritance_conversions.sol",
    "content": "interface Parent {\n    function parentFun() external returns (uint256);\n}\n\ninterface SubA is Parent {\n    function subAFun() external returns (uint256);\n}\n\ninterface SubB is Parent {\n    function subBFun() external returns (uint256);\n}\n\ncontract C is SubA, SubB {\n    function parentFun() override external returns (uint256) { return 1; }\n    function subAFun() override external returns (uint256) { return 2; }\n    function subBFun() override external returns (uint256) { return 3; }\n\n    function convertParent() public returns (uint256) {\n        return this.parentFun();\n    }\n\n    function convertSubA() public returns (uint256, uint256) {\n        return (this.parentFun(), this.subAFun());\n    }\n\n    function convertSubB() public returns (uint256, uint256) {\n        return (this.parentFun(), this.subBFun());\n    }\n}\n// ----\n// convertParent() -> 1\n// gas irOptimized: 21793\n// convertSubA() -> 1, 2\n// gas irOptimized: 22459\n// gas legacy: 23286\n// convertSubB() -> 1, 3\n// gas irOptimized: 22330\n// gas legacy: 23154\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/member_notation_ctor.sol",
    "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D{salt: bytes32(uint256(p))}(p);\n\t\treturn d.getX();\n\t}\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77955\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77583\n// gas legacy code: 24200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/overloaded_function_call_resolve_to_first.sol",
    "content": "contract test {\n    function f(uint256 k) public returns (uint256 d) {\n        return k;\n    }\n\n    function f(uint256 a, uint256 b) public returns (uint256 d) {\n        return a + b;\n    }\n\n    function g() public returns (uint256 d) {\n        return f(3);\n    }\n}\n// ----\n// g() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/overloaded_function_call_resolve_to_second.sol",
    "content": "contract test {\n    function f(uint256 a, uint256 b) public returns (uint256 d) {\n        return a + b;\n    }\n\n    function f(uint256 k) public returns (uint256 d) {\n        return k;\n    }\n\n    function g() public returns (uint256 d) {\n        return f(3, 7);\n    }\n}\n// ----\n// g() -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/overloaded_function_call_with_if_else.sol",
    "content": "contract test {\n    function f(uint256 a, uint256 b) public returns (uint256 d) {\n        return a + b;\n    }\n\n    function f(uint256 k) public returns (uint256 d) {\n        return k;\n    }\n\n    function g(bool flag) public returns (uint256 d) {\n        if (flag) return f(3);\n        else return f(3, 7);\n    }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/pass_dynamic_arguments_to_the_base.sol",
    "content": "contract Base {\n    constructor(uint256 i) {\n        m_i = i;\n    }\n\n    uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n    constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/pass_dynamic_arguments_to_the_base_base.sol",
    "content": "contract Base {\n    constructor(uint256 j) {\n        m_i = j;\n    }\n\n    uint256 public m_i;\n}\n\n\ncontract Base1 is Base {\n    constructor(uint256 k) Base(k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n    constructor(uint256 i) Base1(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/pass_dynamic_arguments_to_the_base_base_with_gap.sol",
    "content": "contract Base {\n    constructor(uint256 i) {\n        m_i = i;\n    }\n\n    uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n    constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n    constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/state_variables_init_order.sol",
    "content": "contract A {\n    uint public x = 0;\n    uint y = f();\n    function f() public returns (uint256) {\n        ++x;\n        return 42;\n    }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/state_variables_init_order_2.sol",
    "content": "contract A {\n    uint public x = 0;\n    uint y = f();\n    function f() public returns (uint256) {\n        ++x;\n        return 42;\n    }\n}\ncontract B is A {\n    uint public z;\n    constructor() {\n        z = x;\n    }\n}\n// ----\n// z() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/state_variables_init_order_3.sol",
    "content": "contract A {\n    uint public a = 42;\n    uint public b;\n    uint public c;\n    constructor(uint x) {\n        b = a;\n        a = x;\n    }\n    function f(uint x) public returns (uint256) { c = x * 3;  return 23; }\n}\ncontract B is A {\n    uint public d = f(a);\n    uint public e = b;\n    uint public b_a;\n    uint public b_b;\n    uint public b_c;\n    constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/super_in_constructor.sol",
    "content": "contract A {\n    function f() public virtual returns (uint256 r) {\n        return 1;\n    }\n}\n\n\ncontract B is A {\n    function f() public virtual override returns (uint256 r) {\n        return super.f() | 2;\n    }\n}\n\n\ncontract C is A {\n    function f() public virtual override returns (uint256 r) {\n        return super.f() | 4;\n    }\n}\n\n\ncontract D is B, C {\n    uint256 data;\n\n    constructor() {\n        data = super.f() | 8;\n    }\n\n    function f() public override (B, C) returns (uint256 r) {\n        return data;\n    }\n}\n// ----\n// f() -> 15\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/super_in_constructor_assignment.sol",
    "content": "contract A {\n    function f() public virtual returns (uint256 r) {\n        return 1;\n    }\n}\n\n\ncontract B is A {\n    function f() public virtual override returns (uint256 r) {\n        function() internal returns (uint) x = super.f;\n        return x() | 2;\n    }\n}\n\n\ncontract C is A {\n    function f() public virtual override returns (uint256 r) {\n        function() internal returns (uint) x = super.f;\n        return x() | 4;\n    }\n}\n\n\ncontract D is B, C {\n    uint256 data;\n\n    constructor() {\n        function() internal returns (uint) x = super.f;\n        data = x() | 8;\n    }\n\n    function f() public override (B, C) returns (uint256 r) {\n        return data;\n    }\n}\n// ----\n// f() -> 15\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/super_overload.sol",
    "content": "contract A {\n    function f(uint256 a) public returns (uint256) {\n        return 2 * a;\n    }\n}\n\n\ncontract B {\n    function f(bool b) public returns (uint256) {\n        return 10;\n    }\n}\n\n\ncontract C is A, B {\n    function g() public returns (uint256) {\n        return super.f(true);\n    }\n\n    function h() public returns (uint256) {\n        return super.f(1);\n    }\n}\n// ----\n// g() -> 10\n// h() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/transient_storage_state_variable.sol",
    "content": "contract A {\n    uint24 transient x;\n    int24 y;\n}\n\ncontract C is A {\n    uint24 w;\n    int24 transient z;\n\n    function f() public returns (uint24, int24, uint24, int24) {\n        x += 1;\n        y += 2;\n        w += 3;\n        z += 4;\n\n        return (x, y, w, z);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 2, 3, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/transient_storage_state_variable_abstract_contract.sol",
    "content": "abstract contract A {\n    uint transient x;\n    int y;\n    function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n    uint w;\n    int transient z;\n\n    function g() public {\n        w += 2;\n        z += 2;\n    }\n\n    function f() public override returns (uint, int, uint, int) {\n        x += 1;\n        y += 1;\n        g();\n        return (x, y, w, z);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inheritance/value_for_constructor.sol",
    "content": "contract Helper {\n    bytes3 name;\n    bool flag;\n\n    constructor(bytes3 x, bool f) payable {\n        name = x;\n        flag = f;\n    }\n\n    function getName() public returns (bytes3 ret) {\n        return name;\n    }\n\n    function getFlag() public returns (bool ret) {\n        return flag;\n    }\n}\n\n\ncontract Main {\n    Helper h;\n\n    constructor() payable {\n        h = (new Helper){value: 10}(\"abc\", true);\n    }\n\n    function getFlag() public returns (bool ret) {\n        return h.getFlag();\n    }\n\n    function getName() public returns (bytes3 ret) {\n        return h.getName();\n    }\n\n    function getBalances() public returns (uint256 me, uint256 them) {\n        me = address(this).balance;\n        them = address(h).balance;\n    }\n}\n// ----\n// constructor(), 22 wei ->\n// gas irOptimized: 143864\n// gas irOptimized code: 118000\n// gas legacy: 156599\n// gas legacy code: 236400\n// gas legacyOptimized: 143592\n// gas legacyOptimized code: 118000\n// getFlag() -> true\n// getName() -> \"abc\"\n// getBalances() -> 12, 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/basefee_berlin_function.sol",
    "content": "contract C {\n    function f() public view returns (uint ret) {\n        assembly {\n            let basefee := sload(0)\n            ret := basefee\n        }\n    }\n    function g() public pure returns (uint ret) {\n        assembly {\n            function basefee() -> r {\n                r := 1000\n            }\n            ret := basefee()\n        }\n    }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/blobbasefee_shanghai_function.sol",
    "content": "contract C {\n    function f() public view returns (uint ret) {\n        assembly {\n            let blobbasefee := 999\n            ret := blobbasefee\n        }\n    }\n    function g() public pure returns (uint ret) {\n        assembly {\n            function blobbasefee() -> r {\n                r := 1000\n            }\n            ret := blobbasefee()\n        }\n    }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/blobhash.sol",
    "content": "contract C {\n    function f() public view returns (bytes32 ret) {\n        assembly {\n            ret := blobhash(0)\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/blobhash_index_exceeding_blob_count.sol",
    "content": "contract C {\n    function f() public view returns (bytes32 ret) {\n        assembly {\n            // EIP-4844 specifies that if `index >= len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n            // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n            // the return value of the function below MUST be zero.\n            ret := blobhash(2)\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/blobhash_pre_cancun.sol",
    "content": "contract C {\n    function f() public pure returns (uint ret) {\n        assembly {\n            let blobhash := 1\n            ret := blobhash\n        }\n    }\n    function g() public pure returns (uint ret) {\n        assembly {\n            function blobhash() -> r {\n                r := 1000\n            }\n            ret := blobhash()\n        }\n    }\n}\n// ====\n// EVMVersion: <cancun\n// ----\n// f() -> 1\n// g() -> 1000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/calldata_array_assign_dynamic.sol",
    "content": "contract C {\n    function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n        assembly { x.offset := 0x44 x.length := 2 }\n        r = x;\n    }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/calldata_array_assign_static.sol",
    "content": "contract C {\n    function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n        assembly { x := 0x24 }\n        r = x;\n    }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/calldata_array_read.sol",
    "content": "contract C {\n    function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n        assembly { l := x.length o := x.offset }\n        uint[2] calldata t = x[1];\n        // statically-sized arrays only use one slot, so we read directly.\n        assembly { s := t }\n    }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/calldata_assign.sol",
    "content": "contract C {\n    function f(bytes calldata x) public returns (bytes memory) {\n        assembly { x.offset := 1 x.length := 3 }\n        return x;\n    }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/calldata_assign_from_nowhere.sol",
    "content": "contract C {\n    function f() public pure returns (bytes calldata x) {\n        assembly { x.offset := 0 x.length := 4 }\n    }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/calldata_length_read.sol",
    "content": "contract C {\n    function lenBytesRead(bytes calldata x) public returns (uint l) {\n        assembly { l := x.length }\n    }\n\n    function lenStringRead(string calldata x) public returns (uint l) {\n        assembly { l := x.length }\n    }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/calldata_offset_read.sol",
    "content": "contract C {\n    function f(bytes calldata x) public returns (uint r) {\n        assembly { r := x.offset }\n    }\n\n    function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n        assembly {\n            r := x.offset\n            v := x.length\n        }\n    }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/calldata_offset_read_write.sol",
    "content": "contract C {\n    function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n        assembly {\n            x.offset := 8\n            x.length := 20\n        }\n        assembly {\n            r := x.offset\n            v := x.length\n        }\n    }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/calldata_struct_assign.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/calldata_struct_assign_and_return.sol",
    "content": "pragma abicoder v2;\ncontract C {\n  struct S { int8 x; int8 y; }\n  function f() internal pure returns(S calldata s) {\n    assembly {\n      s := 0x24\n    }\n  }\n  function g() public pure returns(int8, int8) {\n    S calldata s = f();\n    return (s.x, s.y);\n  }\n  function h() public pure returns(uint256) { f(); return 0x42; }\n  function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/chainid.sol",
    "content": "contract C {\n    function f() public returns (uint id) {\n        assembly {\n            id := chainid()\n        }\n    }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/clz.sol",
    "content": "contract C {\n    function f() public view returns (bytes32 ret) {\n        assembly {\n            ret := clz(0)\n        }\n    }\n\n    function g() public view returns (bytes32 ret) {\n        assembly {\n            ret := clz(1)\n        }\n    }\n\n    function h() public view returns (bytes32 ret) {\n        assembly {\n            ret := clz(0x4000000000000000000000000000000000000000000000000000000000000000)\n        }\n    }\n}\n// ====\n// EVMVersion: >=osaka\n// ----\n// f() -> 256\n// g() -> 255\n// h() -> 1"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/clz_pre_osaka.sol",
    "content": "contract C {\n    function f() public pure returns (uint ret) {\n        assembly {\n            let clz := 1\n            ret := clz\n        }\n    }\n    function g() public pure returns (uint ret) {\n        assembly {\n            function clz() -> r {\n                r := 1000\n            }\n            ret := clz()\n        }\n    }\n}\n// ====\n// EVMVersion: <osaka\n// ----\n// f() -> 1\n// g() -> 1000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/constant_access.sol",
    "content": "contract C {\n    uint constant a = 2;\n    bytes2 constant b = 0xabcd;\n    bytes3 constant c = \"abc\";\n    bool constant d = true;\n    address constant e = 0x1212121212121212121212121212121212121212;\n    function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n        assembly {\n            w := a\n            x := b\n            y := c\n            z := d\n            t := e\n        }\n    }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/constant_access_referencing.sol",
    "content": "contract C {\n    uint constant a = 2;\n    uint constant aa = a;\n    uint constant aaa = aa;\n    bytes2 constant b = 0xabcd;\n    bytes2 constant bb = b;\n    bytes3 constant c = \"abc\";\n    bytes3 constant cc = c;\n    bytes3 constant ccc = cc;\n    bytes3 constant cccc = ccc;\n    bool constant d = true;\n    bool constant dd = d;\n    address constant e = 0x1212121212121212121212121212121212121212;\n    address constant ee = e;\n    function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n        assembly {\n            w := aaa\n            x := bb\n            y := cccc\n            z := dd\n            t := ee\n        }\n    }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/difficulty.sol",
    "content": "contract C {\n    function f() public view returns (uint ret) {\n        assembly {\n            ret := difficulty()\n        }\n    }\n}\n// ====\n// EVMVersion: <paris\n// ----\n// f() -> 200000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_address.sol",
    "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = C(address(0x1234)).testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn C(address(0x1234)).testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0x1234\n// testSol() -> 0x1234\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_address_assignment.sol",
    "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_selector.sol",
    "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/external_function_pointer_selector_assignment.sol",
    "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/external_identifier_access_shadowing.sol",
    "content": "contract C {\n    function f() public returns (uint x) {\n        assembly {\n            function g() -> f { f := 2 }\n            x := g()\n        }\n    }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/for_loop_break.sol",
    "content": "contract C {\n    function f() public returns (uint i) {\n        assembly {\n            for {} lt(i, 10) { i := add(i, 1) }\n            {\n                if eq(i, 6) { break }\n                i := add(i, 1)\n            }\n        }\n    }\n}\n// ----\n// f() -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/for_loop_continue.sol",
    "content": "contract C {\n    function f() public returns (uint k) {\n        assembly {\n            for {let i := 0} lt(i, 10) { i := add(i, 1) }\n            {\n                if eq(mod(i, 2), 0) { continue }\n                k := add(k, 1)\n            }\n        }\n    }\n}\n// ----\n// f() -> 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/for_loop_nested.sol",
    "content": "contract C {\n    function f(uint x) public returns (uint i) {\n        assembly {\n            for {} lt(i, 10) { i := add(i, 1) }\n            {\n                if eq(x, 0) { i := 2 break }\n                for {} lt(x, 3) { i := 17 x := 9 } {\n                    if eq(x, 1) { continue }\n                    if eq(x, 2) { break }\n                }\n                if eq(x, 4) { i := 90 }\n            }\n        }\n    }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 18\n// f(uint256): 2 -> 10\n// f(uint256): 4 -> 91\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/function_name_clash.sol",
    "content": "contract C {\n  function f() public pure returns (uint r) {\n    assembly { function f() -> x { x := 1 } r := f() }\n  }\n  function g() public pure returns (uint r) {\n    assembly { function f() -> x { x := 2 } r := f() }\n  }\n}\n// ----\n// f() -> 1\n// g() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_embedded_function_call.sol",
    "content": "contract C {\n    function f() public {\n        assembly {\n            let d:= 0x10\n\n            function asmfun(a, b, c) -> x, y, z {\n                x := g(a)\n                function g(r) -> s {\n                    s := mul(r, r)\n                }\n                y := g(b)\n                z := 7\n            }\n            let a1, b1, c1 := asmfun(1, 2, 3)\n            mstore(0x00, a1)\n            mstore(0x20, b1)\n            mstore(0x40, c1)\n            mstore(0x60, d)\n            return (0, 0x80)\n        }\n    }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_for.sol",
    "content": "contract C {\n    function f(uint256 a) public returns (uint256 b) {\n        assembly {\n            function fac(n) -> nf {\n                nf := 1\n                for {\n                    let i := n\n                } gt(i, 0) {\n                    i := sub(i, 1)\n                } {\n                    nf := mul(nf, i)\n                }\n            }\n            b := fac(a)\n        }\n    }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_for2.sol",
    "content": "contract C {\n    uint256 st;\n\n    function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n        st = 0;\n        assembly {\n            function sideeffect(r) -> x {\n                sstore(0, add(sload(0), r))\n                x := 1\n            }\n            for {\n                let i := a\n            } eq(i, sideeffect(2)) {\n                d := add(d, 3)\n            } {\n                b := i\n                i := 0\n            }\n        }\n        c = st;\n    }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_function_call.sol",
    "content": "contract C {\n    function f() public {\n        assembly {\n            function asmfun(a, b, c) -> x, y, z {\n                x := a\n                y := b\n                z := 7\n            }\n            let a1, b1, c1 := asmfun(1, 2, 3)\n            mstore(0x00, a1)\n            mstore(0x20, b1)\n            mstore(0x40, c1)\n            return (0, 0x60)\n        }\n    }\n}\n// ----\n// f() -> 1, 2, 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_function_call2.sol",
    "content": "contract C {\n    function f() public {\n        assembly {\n            let d := 0x10\n\n            function asmfun(a, b, c) -> x, y, z {\n                x := a\n                y := b\n                z := 7\n            }\n            let a1, b1, c1 := asmfun(1, 2, 3)\n            mstore(0x00, a1)\n            mstore(0x20, b1)\n            mstore(0x40, c1)\n            mstore(0x60, d)\n            return (0, 0x80)\n        }\n    }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_function_call_assignment.sol",
    "content": "contract C {\n    function f() public {\n        assembly {\n            let a1, b1, c1\n\n            function asmfun(a, b, c) -> x, y, z {\n                x := a\n                y := b\n                z := 7\n            }\n            a1, b1, c1 := asmfun(1, 2, 3)\n            mstore(0x00, a1)\n            mstore(0x20, b1)\n            mstore(0x40, c1)\n            return (0, 0x60)\n        }\n    }\n}\n// ----\n// f() -> 1, 2, 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_if.sol",
    "content": "contract C {\n    function f(uint256 a) public returns (uint256 b) {\n        assembly {\n            if gt(a, 1) {\n                b := 2\n            }\n        }\n    }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_in_modifiers.sol",
    "content": "contract C {\n    modifier m {\n        uint256 a = 1;\n        assembly {\n            a := 2\n        }\n        if (a != 2) revert();\n        _;\n    }\n\n    function f() public m returns (bool) {\n        return true;\n    }\n\n    modifier n {\n        uint256 a = 1;\n        assembly {\n            a := 2\n        }\n        if (a != 2)\n            _;\n        revert();\n    }\n\n    function g() public n returns (bool) {\n        // This statement should never execute.\n        return true;\n    }\n}\n// ====\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// f() -> true\n// g() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_memory_access.sol",
    "content": "contract C {\n    function test() public returns (bytes memory) {\n        bytes memory x = new bytes(5);\n        for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n        assembly {\n            mstore(add(x, 32), \"12345678901234567890123456789012\")\n        }\n        return x;\n    }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_read_and_write_stack.sol",
    "content": "contract C {\n    function f() public returns (uint256 r) {\n        for (uint256 x = 0; x < 10; ++x)\n            assembly {\n                r := add(r, x)\n            }\n    }\n}\n// ----\n// f() -> 45\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_recursion.sol",
    "content": "contract C {\n    function f(uint256 a) public returns (uint256 b) {\n        assembly {\n            function fac(n) -> nf {\n                switch n\n                    case 0 {\n                        nf := 1\n                    }\n                    case 1 {\n                        nf := 1\n                    }\n                    default {\n                        nf := mul(n, fac(sub(n, 1)))\n                    }\n            }\n            b := fac(a)\n        }\n    }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_storage_access.sol",
    "content": "contract C {\n    uint16 x;\n    uint16 public y;\n    uint256 public z;\n\n    function f() public returns (bool) {\n        uint256 off1;\n        uint256 off2;\n        assembly {\n            sstore(z.slot, 7)\n            off1 := z.offset\n            off2 := y.offset\n        }\n        assert(off1 == 0);\n        assert(off2 == 2);\n        return true;\n    }\n}\n// ----\n// f() -> true\n// z() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_storage_access_inside_function.sol",
    "content": "contract C {\n    uint16 x;\n    uint16 public y;\n    uint256 public z;\n\n    function f() public returns (bool) {\n        uint256 off1;\n        uint256 off2;\n        assembly {\n            function f() -> o1 {\n                sstore(z.slot, 7)\n                o1 := y.offset\n            }\n            off2 := f()\n        }\n        assert(off2 == 2);\n        return true;\n    }\n}\n// ----\n// f() -> true\n// z() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_storage_access_local_var.sol",
    "content": "contract C {\n    uint256[] public a;\n\n    function f() public returns (uint256) {\n        uint256[] storage x = a;\n        uint256 off;\n        assembly {\n            sstore(x.slot, 7)\n            off := x.offset\n        }\n        assert(off == 0);\n        return a.length;\n    }\n}\n// ----\n// f() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_storage_access_via_pointer.sol",
    "content": "contract C {\n    struct Data {\n        uint256 contents;\n    }\n    uint256 public separator;\n    Data public a;\n    uint256 public separator2;\n\n    function f() public returns (bool) {\n        Data storage x = a;\n        uint256 off;\n        assembly {\n            sstore(x.slot, 7)\n            off := x.offset\n        }\n        assert(off == 0);\n        return true;\n    }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_switch.sol",
    "content": "contract C {\n    function f(uint256 a) public returns (uint256 b) {\n        assembly {\n            switch a\n                case 1 {\n                    b := 8\n                }\n                case 2 {\n                    b := 9\n                }\n                default {\n                    b := 2\n                }\n        }\n    }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_transient_storage_access_inside_function.sol",
    "content": "contract C {\n    uint16 transient x;\n    uint16 public transient y;\n    uint256 public transient z;\n\n    function f() public returns (uint256) {\n        uint256 offset;\n        assembly {\n            function f() -> o1 {\n                tstore(z.slot, 7)\n                o1 := y.offset\n            }\n            offset := f()\n        }\n        assert(offset == 2);\n        return z;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inline_assembly_write_to_stack.sol",
    "content": "contract C {\n    function f() public returns (uint256 r, bytes32 r2) {\n        assembly {\n            r := 7\n            r2 := \"abcdef\"\n        }\n    }\n}\n// ----\n// f() -> 7, \"abcdef\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/inlineasm_empty_let.sol",
    "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/keccak256_assembly.sol",
    "content": "contract C {\n    function f() public pure returns (bytes32 ret) {\n        assembly {\n            ret := keccak256(0, 0)\n        }\n    }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/keccak256_optimization.sol",
    "content": "contract C {\n    function f() public view returns (bool ret) {\n        assembly {\n            let x := calldataload(0)\n            mstore(0, x)\n            mstore(0x20, x)\n            let a := keccak256(0, 4)\n            let b := keccak256(0x20, 4)\n            ret := eq(a, b)\n        }\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/keccak256_optimizer_bug_different_memory_location.sol",
    "content": "contract C {\n    function f() public view returns (bool ret) {\n        assembly {\n            let x := calldataload(0)\n            mstore(0, x)\n            mstore(0x20, x)\n            let a := keccak256(0, 4)\n            let b := keccak256(0x20, 8)\n            ret := eq(a, b)\n        }\n    }\n}\n// ----\n// f() -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/keccak256_optimizer_cache_bug.sol",
    "content": "contract C {\n  uint[] data;\n\n  function val() public returns (bool) {\n    assembly {\n        sstore(0, 2)\n        mstore(0, 0)\n        sstore(keccak256(0, 32), 234)\n        // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n        // keccak256(0, 32), leading to `data[1] == 123` being true.\n        sstore(add(keccak256(0, 23), 1), 123)\n    }\n    assert(data[1] != 123);\n    assert(data[1] == 0);\n    return true;\n  }\n}\n// ----\n// val() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/keccak_optimization_bug_string.sol",
    "content": "contract C {\n    function f(string memory s) public returns (bool ret) {\n        assembly {\n            let a := keccak256(s, 32)\n            let b := keccak256(s, 8)\n            ret := eq(a, b)\n        }\n    }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol",
    "content": "contract C {\n    function g() public returns (uint ret) {\n        uint x = type(uint).max;\n        assembly {\n            mstore(0x20, x)\n            // both old and new optimizer should be able to evaluate this\n            ret := keccak256(0x20, 16)\n        }\n    }\n\n    function f() public returns (uint ret) {\n        uint x = type(uint).max;\n        assembly {\n            mstore(0x20, x)\n            // For Yul optimizer, load resolver and loop invariant code motion\n            // would take the Keccak-256 outside the loop. For the old-optimizer,\n            // this is not possible.\n            // Net savings approximately: 20 * cost of Keccak-256 = 572\n            for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n                ret := keccak256(0x20, 16)\n            }\n        }\n    }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22212\n// gas legacy: 23378\n// gas legacyOptimized: 23089\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21251\n// gas legacy: 21456\n// gas legacyOptimized: 21254\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/leave.sol",
    "content": "contract C {\n    function f() public pure returns (uint w) {\n        assembly {\n            function f() -> t {\n                t := 2\n                leave\n                t := 9\n            }\n            w := f()\n        }\n    }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/mcopy.sol",
    "content": "contract C {\n    function f(bytes memory src) public pure returns (bytes memory dst) {\n        assembly {\n            mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n            mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n            mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n            mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/mcopy_as_identifier_pre_cancun.sol",
    "content": "contract C {\n    function f() public pure returns (uint result) {\n        assembly {\n            let mcopy := 1\n            result := mcopy\n        }\n    }\n\n    function g() public pure returns (uint result) {\n        assembly {\n            function mcopy() -> r {\n                r := 1000\n            }\n            result := mcopy()\n        }\n    }\n}\n// ====\n// EVMVersion: <cancun\n// ----\n// f() -> 1\n// g() -> 1000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/mcopy_empty.sol",
    "content": "contract C {\n    function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n        out = pattern;\n\n        // This should have no effect on output\n        assembly {\n            mcopy(add(out, 0x20), add(out, 0x30), 0)\n            mcopy(add(out, 0x30), add(out, 0x30), 0)\n            mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n            mcopy(add(out, 0x21), 0, 0)\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/mcopy_overlap.sol",
    "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n    out =\n        hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n        hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n        hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n    assembly {\n        mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n    }\n}\n\ncontract C {\n    function mcopy_to_right_overlap() public pure returns (bytes memory) {\n        return copy(0x20, 0x10, 0x30);\n    }\n\n    function mcopy_to_left_overlap() public pure returns (bytes memory) {\n        return copy(0x10, 0x20, 0x30);\n    }\n\n    function mcopy_in_place() public pure returns (bytes memory) {\n        return copy(0x10, 0x10, 0x40);\n    }\n\n    function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n        return copy(0x30, 0x10, 0x20);\n    }\n\n    function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n        return copy(0x10, 0x30, 0x20);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap()    -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap()     -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place()            -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap()  -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/optimize_memory_store_multi_block.sol",
    "content": "contract C {\n\tfunction f() external returns (uint256 x) {\n\t\tassembly {\n\t\t\tmstore(0, 0x42)\n\t\t}\n\t\tassembly {\n\t\t\tx := mload(0)\n\t\t}\n\t}\n\tfunction g() external returns (bool) {\n\t\tuint initialFreeMemoryPointer;\n\t\tassembly {\n\t\t\tinitialFreeMemoryPointer := mload(0x40)\n\t\t}\n\t\tassembly {\n\t\t\tlet ptr := mload(0x40)\n\t\t\tmstore(0x40, add(ptr, 0x20))\n\t\t}\n\t\tuint finalFreeMemoryPointer;\n\t\tassembly {\n\t\t\tfinalFreeMemoryPointer := mload(0x40)\n\t\t}\n\t\tassert(initialFreeMemoryPointer != finalFreeMemoryPointer);\n\t\treturn true;\n\t}\n}\n// ----\n// f() -> 0x42\n// g() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/optimize_memory_store_multi_block_bugreport.sol",
    "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit <anonymous>: 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/prevrandao.sol",
    "content": "contract C {\n    function f() public view returns (uint ret) {\n        assembly {\n            ret := prevrandao()\n        }\n    }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/selfbalance.sol",
    "content": "contract C {\n    function f() public payable returns (uint ret) {\n        assembly {\n            ret := selfbalance()\n        }\n    }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/shadowing_local_function_opcode.sol",
    "content": "contract C {\n    function add(uint, uint) public pure returns (uint) { return 7; }\n    function g() public pure returns (uint x, uint y) {\n        x = add(1, 2);\n        assembly {\n            y := add(1, 2)\n        }\n    }\n}\n// ----\n// g() -> 7, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/slot_access.sol",
    "content": "contract C {\n    struct S {\n        uint a;\n        uint b;\n    }\n\n    mapping(uint => S) public mappingAccess;\n\n    function data() internal view returns (S storage _data) {\n        // We need to assign it from somewhere, otherwise we would\n        // get an \"uninitialized access\" error.\n        _data = mappingAccess[20];\n\n        bytes32 slot = keccak256(abi.encode(uint(1), uint(0)));\n        assembly {\n            _data.slot := slot\n        }\n    }\n\n    function set(uint x) public {\n        data().a = x;\n    }\n\n    function get() public view returns (uint) {\n        return data().a;\n    }\n}\n// ----\n// get() -> 0\n// mappingAccess(uint256): 1 -> 0, 0\n// set(uint256): 4\n// get() -> 4\n// mappingAccess(uint256): 1 -> 4, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/slot_access_via_mapping_pointer.sol",
    "content": "contract C {\n    mapping(uint => uint) private m0;\n    mapping(uint => uint) private m1;\n    mapping(uint => uint) private m2;\n\n    function f(uint i) public returns (uint slot, uint offset) {\n        mapping(uint => uint) storage m0Ptr = m0;\n        mapping(uint => uint) storage m1Ptr = m1;\n        mapping(uint => uint) storage m2Ptr = m2;\n\n        assembly {\n            switch i\n            case 1 {\n                slot := m1Ptr.slot\n                offset := m1Ptr.offset\n            }\n            case 2 {\n                slot := m2Ptr.slot\n                offset := m2Ptr.offset\n            }\n            default {\n                slot := m0Ptr.slot\n                offset := m0Ptr.offset\n            }\n        }\n    }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/tload_tstore_not_reserved_before_cancun.sol",
    "content": "contract C {\n    function f() public view returns (uint ret) {\n        assembly {\n            let tload := sload(0)\n            let tstore := add(tload, 1)\n            ret := tstore\n        }\n    }\n    function g() public view returns (uint ret) {\n        assembly {\n            function tstore() -> a {\n                a := 2\n            }\n            function tload() -> b {\n                b := 3\n            }\n            ret := add(tstore(), tload())\n        }\n    }\n}\n// ====\n// EVMVersion: <cancun\n// ----\n// f() -> 1\n// g() -> 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/transient_storage_creation.sol",
    "content": "contract C {\n    constructor() {\n        uint x;\n        assembly {\n            tstore(0, 42)\n            x := tload(0)\n        }\n        assert(x == 42);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/transient_storage_low_level_calls.sol",
    "content": "contract D {\n    function addOne() external {\n        assembly {\n            let x := tload(0)\n            tstore(0, add(x, 1))\n        }\n    }\n    function get() external returns (uint x) {\n        assembly {\n            x := tload(0)\n        }\n    }\n}\n\ncontract C {\n    function set(uint x) external {\n        assembly {\n            tstore(0, x)\n        }\n    }\n\n    function get() external view returns (uint x) {\n        assembly {\n            x := tload(0)\n        }\n    }\n\n    function testDelegateCall() external returns (bool) {\n        this.set(5);\n        D d = new D{salt: hex\"00\"}();\n        // Caller contract is the owner of the transient storage\n        (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n        require(success);\n        require(this.get() == 6);\n        return true;\n    }\n\n    function testCall() external returns (bool) {\n        this.set(5);\n        D d = new D{salt: hex\"01\"}();\n        // Callee/Target contract is the owner of the transient storage\n        (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n        require(success);\n        require(d.get() == 1);\n        return true;\n    }\n\n    function tloadAllowedStaticCall() external returns (bool) {\n        this.set(5);\n        D d = new D{salt: hex\"02\"}();\n        (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n        require(success);\n        require(abi.decode(result, (uint)) == 0);\n        return true;\n    }\n\n    function tstoreNotAllowedStaticCall() external returns (bool) {\n        D d = new D{salt: hex\"03\"}();\n        (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n        require(!success);\n        return true;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419721\n// gas irOptimized code: 19000\n// gas legacy: 98409087\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/transient_storage_multiple_calls_different_transactions.sol",
    "content": "contract C {\n    function get(uint256 addr) external view returns (uint256 x) {\n        assembly {\n            x := tload(addr)\n        }\n    }\n    function set(uint256 addr, uint256 x) external {\n        assembly {\n            tstore(addr, x)\n        }\n    }\n    function test() public {\n        assert(this.get(0) == 0 && this.get(42) == 0);\n        this.set(0, 21);\n        assert(this.get(0) == 21 && this.get(42) == 0);\n        this.set(42, 131);\n        assert(this.get(0) == 21 && this.get(42) == 131);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/transient_storage_multiple_transactions.sol",
    "content": "contract C {\n    function set(uint value) private {\n        assembly {\n            tstore(0, value)\n        }\n    }\n\n    function get() private view returns (uint value) {\n        assembly {\n            value := tload(0)\n        }\n    }\n\n    function f() external {\n        assembly {\n            tstore(0, 42)\n        }\n    }\n\n    function g() external view returns(uint r) {\n        assembly {\n            r := tload(0)\n        }\n    }\n\n    function h() external returns (uint x) {\n        set(99);\n        x = get();\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/transient_storage_reset_between_creation_runtime.sol",
    "content": "contract C {\n    constructor() {\n        uint x;\n        assembly {\n            tstore(0, 42)\n            x := tload(0)\n        }\n        assert(x == 42);\n    }\n\n    function f() public returns (uint x) {\n        assembly {\n            x := tload(0)\n            if eq(x, 42) {\n                revert(0, 0)\n            }\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/transient_storage_sanity_checks.sol",
    "content": "contract C {\n    function f() external {\n        assembly {\n            tstore(0, 21)\n            mstore(0, 42)\n            sstore(0, 42)\n            if iszero(eq(tload(0), 21)) {\n                revert(0, 0)\n            }\n        }\n    }\n    function g() external view returns (uint s, uint m, uint t) {\n        assembly {\n            s := sload(0)\n            m := mload(0)\n            t := tload(0)\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/transient_storage_selfdestruct.sol",
    "content": "contract C {\n    function set(uint value) external {\n        assembly {\n            tstore(0, value)\n        }\n    }\n\n    function get() external view returns (uint value) {\n        assembly {\n            value := tload(0)\n        }\n    }\n\n    function terminate(address payable a) external {\n        selfdestruct(a);\n    }\n}\n\ncontract D {\n    C public c;\n\n    constructor() {\n        c = new C();\n    }\n\n    function destroy() external {\n        c.set(42);\n        c.terminate(payable(address(this)));\n        assert(c.get() == 42);\n    }\n\n    function createAndDestroy() external {\n        c = new C();\n        c.set(42);\n        c.terminate(payable(address(this)));\n        assert(c.get() == 42);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// bytecodeFormat: legacy\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/transient_storage_simple_reentrancy_lock.sol",
    "content": "contract C {\n    modifier nonreentrant {\n        assembly {\n            if tload(0) { revert(0, 0) }\n            tstore(0, 1)\n        }\n        _;\n        assembly {\n            tstore(0, 0)\n        }\n    }\n    function f(bool simulateReentrancy) nonreentrant public {\n        if (simulateReentrancy) {\n            f(false);\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/truefalse.sol",
    "content": "contract C {\n    function f() public returns (uint x, uint y) {\n        assembly {\n            x := true\n            y := false\n        }\n    }\n}\n// ----\n// f() -> 1, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/inlineAssembly/tstore_hidden_staticcall.sol",
    "content": "contract C {\n    function f() internal {\n        assembly {\n            tstore(0, 0)\n        }\n    }\n    function g() public view {\n        function() internal ptr = f;\n        function() internal view ptr2;\n        assembly { ptr2 := ptr }\n        ptr2(); // we force calling the non-view function, which should result in a revert during the staticcall\n    }\n    function test() public {\n        this.g(); // an external call to a view function should use static call\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> FAILURE\n// gas irOptimized: 98437877\n// gas legacy: 98437871\n// gas legacyOptimized: 98437872\n"
  },
  {
    "path": "test/libsolidity/semanticTests/integer/basic.sol",
    "content": "contract C {\n\tfunction basic() public pure returns(bool) {\n\t\tuint uint_min = type(uint).min;\n\t\trequire(uint_min == 0);\n\n\t\tuint uint_max = type(uint).max;\n\t\trequire(uint_max == 2**256 - 1);\n\t\trequire(uint_max == 115792089237316195423570985008687907853269984665640564039457584007913129639935);\n\n\t\tint int_min = type(int).min;\n\t\trequire(int_min == -2**255);\n\t\trequire(int_min == -57896044618658097711785492504343953926634992332820282019728792003956564819968);\n\n\t\tint int_max = type(int).max;\n\t\trequire(int_max == 2**255 -1);\n\t\trequire(int_max == 57896044618658097711785492504343953926634992332820282019728792003956564819967);\n\n\t\treturn true;\n\t}\n}\n// ----\n// basic() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/integer/int.sol",
    "content": "contract test {\n\n\tfunction intMinA() public pure returns (bool) {\n\n\t\tint8 int8_min = type(int8).min;\n\t\trequire(int8_min == -2**7);\n\n\t\tint16 int16_min = type(int16).min;\n\t\trequire(int16_min == -2**15);\n\n\t\tint24 int24_min = type(int24).min;\n\t\trequire(int24_min == -2**23);\n\n\t\tint32 int32_min = type(int32).min;\n\t\trequire(int32_min == -2**31);\n\n\t\tint40 int40_min = type(int40).min;\n\t\trequire(int40_min == -2**39);\n\n\t\tint48 int48_min = type(int48).min;\n\t\trequire(int48_min == -2**47);\n\n\t\tint56 int56_min = type(int56).min;\n\t\trequire(int56_min == -2**55);\n\n\t\tint64 int64_min = type(int64).min;\n\t\trequire(int64_min == -2**63);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinB() public pure returns(bool) {\n\n\t\tint72 int72_min = type(int72).min;\n\t\trequire(int72_min == -2**71);\n\n\t\tint80 int80_min = type(int80).min;\n\t\trequire(int80_min == -2**79);\n\n\t\tint88 int88_min = type(int88).min;\n\t\trequire(int88_min == -2**87);\n\n\t\tint96 int96_min = type(int96).min;\n\t\trequire(int96_min == -2**95);\n\n\t\tint104 int104_min = type(int104).min;\n\t\trequire(int104_min == -2**103);\n\n\t\tint112 int112_min = type(int112).min;\n\t\trequire(int112_min == -2**111);\n\n\t\tint120 int120_min = type(int120).min;\n\t\trequire(int120_min == -2**119);\n\n\t\tint128 int128_min = type(int128).min;\n\t\trequire(int128_min == -2**127);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinC() public pure returns (bool) {\n\n\t\tint136 int136_min = type(int136).min;\n\t\trequire(int136_min == -2**135);\n\n\t\tint144 int144_min = type(int144).min;\n\t\trequire(int144_min == -2**143);\n\n\t\tint152 int152_min = type(int152).min;\n\t\trequire(int152_min == -2**151);\n\n\t\tint160 int160_min = type(int160).min;\n\t\trequire(int160_min == -2**159);\n\n\t\tint168 int168_min = type(int168).min;\n\t\trequire(int168_min == -2**167);\n\n\t\tint176 int176_min = type(int176).min;\n\t\trequire(int176_min == -2**175);\n\n\t\tint184 int184_min = type(int184).min;\n\t\trequire(int184_min == -2**183);\n\n\t\tint192 int192_min = type(int192).min;\n\t\trequire(int192_min == -2**191);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinD() public pure returns(bool) {\n\n\t\tint200 int200_min = type(int200).min;\n\t\trequire(int200_min == -2**199);\n\n\t\tint208 int208_min = type(int208).min;\n\t\trequire(int208_min == -2**207);\n\n\t\tint216 int216_min = type(int216).min;\n\t\trequire(int216_min == -2**215);\n\n\t\tint224 int224_min = type(int224).min;\n\t\trequire(int224_min == -2**223);\n\n\t\tint232 int232_min = type(int232).min;\n\t\trequire(int232_min == -2**231);\n\n\t\tint240 int240_min = type(int240).min;\n\t\trequire(int240_min == -2**239);\n\n\t\tint248 int248_min = type(int248).min;\n\t\trequire(int248_min == -2**247);\n\n\t\tint256 int256_min = type(int256).min;\n\t\trequire(int256_min == -2**255);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxA() public pure returns (bool) {\n\n\t\tint8 int8_max = type(int8).max;\n\t\trequire(int8_max == 2**7-1);\n\n\t\tint16 int16_max = type(int16).max;\n\t\trequire(int16_max == 2**15-1);\n\n\t\tint24 int24_max = type(int24).max;\n\t\trequire(int24_max == 2**23-1);\n\n\t\tint32 int32_max = type(int32).max;\n\t\trequire(int32_max == 2**31-1);\n\n\t\tint40 int40_max = type(int40).max;\n\t\trequire(int40_max == 2**39-1);\n\n\t\tint48 int48_max = type(int48).max;\n\t\trequire(int48_max == 2**47-1);\n\n\t\tint56 int56_max = type(int56).max;\n\t\trequire(int56_max == 2**55-1);\n\n\t\tint64 int64_max = type(int64).max;\n\t\trequire(int64_max == 2**63-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxB() public pure returns(bool) {\n\n\t\tint72 int72_max = type(int72).max;\n\t\trequire(int72_max == 2**71-1);\n\n\t\tint80 int80_max = type(int80).max;\n\t\trequire(int80_max == 2**79-1);\n\n\t\tint88 int88_max = type(int88).max;\n\t\trequire(int88_max == 2**87-1);\n\n\t\tint96 int96_max = type(int96).max;\n\t\trequire(int96_max == 2**95-1);\n\n\t\tint104 int104_max = type(int104).max;\n\t\trequire(int104_max == 2**103-1);\n\n\t\tint112 int112_max = type(int112).max;\n\t\trequire(int112_max == 2**111-1);\n\n\t\tint120 int120_max = type(int120).max;\n\t\trequire(int120_max == 2**119-1);\n\n\t\tint128 int128_max = type(int128).max;\n\t\trequire(int128_max == 2**127-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxC() public pure returns (bool) {\n\n\t\tint136 int136_max = type(int136).max;\n\t\trequire(int136_max == 2**135-1);\n\n\t\tint144 int144_max = type(int144).max;\n\t\trequire(int144_max == 2**143-1);\n\n\t\tint152 int152_max = type(int152).max;\n\t\trequire(int152_max == 2**151-1);\n\n\t\tint160 int160_max = type(int160).max;\n\t\trequire(int160_max == 2**159-1);\n\n\t\tint168 int168_max = type(int168).max;\n\t\trequire(int168_max == 2**167-1);\n\n\t\tint176 int176_max = type(int176).max;\n\t\trequire(int176_max == 2**175-1);\n\n\t\tint184 int184_max = type(int184).max;\n\t\trequire(int184_max == 2**183-1);\n\n\t\tint192 int192_max = type(int192).max;\n\t\trequire(int192_max == 2**191-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxD() public pure returns(bool) {\n\n\t\tint200 int200_max = type(int200).max;\n\t\trequire(int200_max == 2**199-1);\n\n\t\tint208 int208_max = type(int208).max;\n\t\trequire(int208_max == 2**207-1);\n\n\t\tint216 int216_max = type(int216).max;\n\t\trequire(int216_max == 2**215-1);\n\n\t\tint224 int224_max = type(int224).max;\n\t\trequire(int224_max == 2**223-1);\n\n\t\tint232 int232_max = type(int232).max;\n\t\trequire(int232_max == 2**231-1);\n\n\t\tint240 int240_max = type(int240).max;\n\t\trequire(int240_max == 2**239-1);\n\n\t\tint248 int248_max = type(int248).max;\n\t\trequire(int248_max == 2**247-1);\n\n\t\tint256 int256_max = type(int256).max;\n\t\trequire(int256_max == 2**255-1);\n\n\t\treturn true;\n\t}\n}\n// ----\n// intMinA() -> true\n// intMinB() -> true\n// intMinC() -> true\n// intMinD() -> true\n// intMaxA() -> true\n// intMaxB() -> true\n// intMaxC() -> true\n// intMaxD() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/integer/many_local_variables.sol",
    "content": "contract test {\n    function run(uint x1, uint x2, uint x3) public returns(uint y) {\n        uint8 a = 0x1; uint8 b = 0x10; uint16 c = 0x100;\n        y = a + b + c + x1 + x2 + x3;\n        y += b + x2;\n    }\n}\n// ----\n// run(uint256,uint256,uint256): 0x1000, 0x10000, 0x100000 -> 0x121121\n"
  },
  {
    "path": "test/libsolidity/semanticTests/integer/small_signed_types.sol",
    "content": "contract test {\n    function run() public returns(int256 y) {\n        return -int32(10) * -int64(20);\n    }\n}\n// ----\n// run() -> 200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/integer/uint.sol",
    "content": "contract test {\n\n\tfunction uintMinA() public pure returns(bool) {\n\n\t\tuint8 uint8_min = type(uint8).min;\n\t\trequire(uint8_min == 0);\n\n\t\tuint16 uint16_min = type(uint16).min;\n\t\trequire(uint16_min == 0);\n\n\t\tuint24 uint24_min = type(uint24).min;\n\t\trequire(uint24_min == 0);\n\n\t\tuint32 uint32_min = type(uint32).min;\n\t\trequire(uint32_min == 0);\n\n\t\tuint40 uint40_min = type(uint40).min;\n\t\trequire(uint40_min == 0);\n\n\t\tuint48 uint48_min = type(uint48).min;\n\t\trequire(uint48_min == 0);\n\n\t\tuint56 uint56_min = type(uint56).min;\n\t\trequire(uint56_min == 0);\n\n\t\tuint64 uint64_min = type(uint64).min;\n\t\trequire(uint64_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinB() public pure returns(bool) {\n\n\t\tuint72 uint72_min = type(uint72).min;\n\t\trequire(uint72_min == 0);\n\n\t\tuint80 uint80_min = type(uint80).min;\n\t\trequire(uint80_min == 0);\n\n\t\tuint88 uint88_min = type(uint88).min;\n\t\trequire(uint88_min == 0);\n\n\t\tuint96 uint96_min = type(uint96).min;\n\t\trequire(uint96_min == 0);\n\n\t\tuint104 uint104_min = type(uint104).min;\n\t\trequire(uint104_min == 0);\n\n\t\tuint112 uint112_min = type(uint112).min;\n\t\trequire(uint112_min == 0);\n\n\t\tuint120 uint120_min = type(uint120).min;\n\t\trequire(uint120_min == 0);\n\n\t\tuint128 uint128_min = type(uint128).min;\n\t\trequire(uint128_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinC() public pure returns(bool) {\n\n\t\tuint136 uint136_min = type(uint136).min;\n\t\trequire(uint136_min == 0);\n\n\t\tuint144 uint144_min = type(uint144).min;\n\t\trequire(uint144_min == 0);\n\n\t\tuint152 uint152_min = type(uint152).min;\n\t\trequire(uint152_min == 0);\n\n\t\tuint160 uint160_min = type(uint160).min;\n\t\trequire(uint160_min == 0);\n\n\t\tuint168 uint168_min = type(uint168).min;\n\t\trequire(uint168_min == 0);\n\n\t\tuint176 uint176_min = type(uint176).min;\n\t\trequire(uint176_min == 0);\n\n\t\tuint184 uint184_min = type(uint184).min;\n\t\trequire(uint184_min == 0);\n\n\t\tuint192 uint192_min = type(uint192).min;\n\t\trequire(uint192_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinD() public pure returns(bool) {\n\n\t\tuint200 uint200_min = type(uint200).min;\n\t\trequire(uint200_min == 0);\n\n\t\tuint208 uint208_min = type(uint208).min;\n\t\trequire(uint208_min == 0);\n\n\t\tuint216 uint216_min = type(uint216).min;\n\t\trequire(uint216_min == 0);\n\n\t\tuint224 uint224_min = type(uint224).min;\n\t\trequire(uint224_min == 0);\n\n\t\tuint232 uint232_min = type(uint232).min;\n\t\trequire(uint232_min == 0);\n\n\t\tuint240 uint240_min = type(uint240).min;\n\t\trequire(uint240_min == 0);\n\n\t\tuint248 uint248_min = type(uint248).min;\n\t\trequire(uint248_min == 0);\n\n\t\tuint256 uint256_min = type(uint256).min;\n\t\trequire(uint256_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxA() public pure returns (bool) {\n\n\t\tuint8 uint8_max = type(uint8).max;\n\t\trequire(uint8_max == 2**8-1);\n\n\t\tuint16 uint16_max = type(uint16).max;\n\t\trequire(uint16_max == 2**16-1);\n\n\t\tuint24 uint24_max = type(uint24).max;\n\t\trequire(uint24_max == 2**24-1);\n\n\t\tuint32 uint32_max = type(uint32).max;\n\t\trequire(uint32_max == 2**32-1);\n\n\t\tuint40 uint40_max = type(uint40).max;\n\t\trequire(uint40_max == 2**40-1);\n\n\t\tuint48 uint48_max = type(uint48).max;\n\t\trequire(uint48_max == 2**48-1);\n\n\t\tuint56 uint56_max = type(uint56).max;\n\t\trequire(uint56_max == 2**56-1);\n\n\t\tuint64 uint64_max = type(uint64).max;\n\t\trequire(uint64_max == 2**64-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxB() public pure returns (bool) {\n\n\t\tuint72 uint72_max = type(uint72).max;\n\t\trequire(uint72_max == 2**72-1);\n\n\t\tuint80 uint80_max = type(uint80).max;\n\t\trequire(uint80_max == 2**80-1);\n\n\t\tuint88 uint88_max = type(uint88).max;\n\t\trequire(uint88_max == 2**88-1);\n\n\t\tuint96 uint96_max = type(uint96).max;\n\t\trequire(uint96_max == 2**96-1);\n\n\t\tuint104 uint104_max = type(uint104).max;\n\t\trequire(uint104_max == 2**104-1);\n\n\t\tuint112 uint112_max = type(uint112).max;\n\t\trequire(uint112_max == 2**112-1);\n\n\t\tuint120 uint120_max = type(uint120).max;\n\t\trequire(uint120_max == 2**120-1);\n\n\t\tuint128 uint128_max = type(uint128).max;\n\t\trequire(uint128_max == 2**128-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxC() public pure returns (bool) {\n\n\t\tuint136 uint136_max = type(uint136).max;\n\t\trequire(uint136_max == 2**136-1);\n\n\t\tuint144 uint144_max = type(uint144).max;\n\t\trequire(uint144_max == 2**144-1);\n\n\t\tuint152 uint152_max = type(uint152).max;\n\t\trequire(uint152_max == 2**152-1);\n\n\t\tuint160 uint160_max = type(uint160).max;\n\t\trequire(uint160_max == 2**160-1);\n\n\t\tuint168 uint168_max = type(uint168).max;\n\t\trequire(uint168_max == 2**168-1);\n\n\t\tuint176 uint176_max = type(uint176).max;\n\t\trequire(uint176_max == 2**176-1);\n\n\t\tuint184 uint184_max = type(uint184).max;\n\t\trequire(uint184_max == 2**184-1);\n\n\t\tuint192 uint192_max = type(uint192).max;\n\t\trequire(uint192_max == 2**192-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxD() public pure returns(bool) {\n\t\tuint200 uint200_max = type(uint200).max;\n\t\trequire(uint200_max == 2**200-1);\n\n\t\tuint208 uint208_max = type(uint208).max;\n\t\trequire(uint208_max == 2**208-1);\n\n\t\tuint216 uint216_max = type(uint216).max;\n\t\trequire(uint216_max == 2**216-1);\n\n\t\tuint224 uint224_max = type(uint224).max;\n\t\trequire(uint224_max == 2**224-1);\n\n\t\tuint232 uint232_max = type(uint232).max;\n\t\trequire(uint232_max == 2**232-1);\n\n\t\tuint240 uint240_max = type(uint240).max;\n\t\trequire(uint240_max == 2**240-1);\n\n\t\tuint248 uint248_max = type(uint248).max;\n\t\trequire(uint248_max == 2**248-1);\n\n\t\tuint256 uint256_max = type(uint256).max;\n\t\trequire(uint256_max == 2**256-1);\n\n\t\treturn true;\n\t}\n}\n// ----\n// uintMinA() -> true\n// uintMinB() -> true\n// uintMinC() -> true\n// uintMinD() -> true\n// uintMaxA() -> true\n// uintMaxB() -> true\n// uintMaxC() -> true\n// uintMaxD() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/interfaceID/homer.sol",
    "content": "interface ERC165 {\n    /// @notice Query if a contract implements an interface\n    /// @param interfaceID The interface identifier, as specified in ERC-165\n    /// @dev Interface identification is specified in ERC-165. This function\n    ///  uses less than 30,000 gas.\n    /// @return `true` if the contract implements `interfaceID` and\n    ///  `interfaceID` is not 0xffffffff, `false` otherwise\n    function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\ninterface Simpson {\n    function is2D() external returns (bool);\n    function skinColor() external returns (string memory);\n}\n\ncontract Homer is ERC165, Simpson {\n    function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n        return\n            interfaceID == this.supportsInterface.selector || // ERC165\n            interfaceID == this.is2D.selector ^ this.skinColor.selector; // Simpson\n    }\n\n    function is2D() external override returns (bool) {\n        return true;\n    }\n\n    function skinColor() external override returns (string memory) {\n        return \"yellow\";\n    }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/interfaceID/homer_interfaceId.sol",
    "content": "interface ERC165 {\n    /// @notice Query if a contract implements an interface\n    /// @param interfaceID The interface identifier, as specified in ERC-165\n    /// @dev Interface identification is specified in ERC-165. This function\n    ///  uses less than 30,000 gas.\n    /// @return `true` if the contract implements `interfaceID` and\n    ///  `interfaceID` is not 0xffffffff, `false` otherwise\n    function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\ninterface Simpson {\n    function is2D() external returns (bool);\n    function skinColor() external returns (string memory);\n}\n\ncontract Homer is ERC165, Simpson {\n    function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n        return\n            interfaceID == type(ERC165).interfaceId ||\n            interfaceID == type(Simpson).interfaceId;\n    }\n\n    function is2D() external override returns (bool) {\n        return true;\n    }\n\n    function skinColor() external override returns (string memory) {\n        return \"yellow\";\n    }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/interfaceID/interfaceId_events.sol",
    "content": "interface HelloWorld {\n    function hello() external pure;\n    function world(int) external pure;\n}\n\ninterface HelloWorldWithEvent {\n    event Event();\n    function hello() external pure;\n    function world(int) external pure;\n}\n\ncontract Test {\n    bytes4 public hello_world = type(HelloWorld).interfaceId;\n    bytes4 public hello_world_with_event = type(HelloWorldWithEvent).interfaceId;\n}\n// ----\n// hello_world() -> left(0xc6be8b58)\n// hello_world_with_event() -> left(0xc6be8b58)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/interfaceID/interfaces.sol",
    "content": "interface HelloWorld {\n    function hello() external pure;\n    function world(int) external pure;\n}\n\ninterface HelloWorldDerived is HelloWorld {\n    function other() external pure;\n}\n\ninterface ERC165 {\n    /// @notice Query if a contract implements an interface\n    /// @param interfaceID The interface identifier, as specified in ERC-165\n    /// @dev Interface identification is specified in ERC-165. This function\n    ///  uses less than 30,000 gas.\n    /// @return `true` if the contract implements `interfaceID` and\n    ///  `interfaceID` is not 0xffffffff, `false` otherwise\n    function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\ncontract Test {\n    bytes4 public ghello_world_interfaceId = type(HelloWorld).interfaceId;\n    bytes4 public ERC165_interfaceId = type(ERC165).interfaceId;\n\n    function hello() public pure returns (bytes4 data){\n        HelloWorld i;\n        return i.hello.selector;\n    }\n\n    function world() public pure returns (bytes4 data){\n        HelloWorld i;\n        return i.world.selector;\n    }\n\n    function hello_world() public pure returns (bytes4 data){\n        // HelloWorld i;\n        // return i.hello.selector ^ i.world.selector; // = 0xc6be8b58\n        return 0xc6be8b58;\n    }\n\n    function hello_world_interfaceId() public pure returns (bytes4 data){\n        return type(HelloWorld).interfaceId;\n    }\n\n    function other() public pure returns (bytes4 data){\n        HelloWorldDerived i;\n        return i.other.selector;\n    }\n\n    function hello_world_derived_interfaceId() public pure returns (bytes4 data){\n        return type(HelloWorldDerived).interfaceId;\n    }\n}\n// ----\n// hello() -> left(0x19ff1d21)\n// world() -> left(0xdf419679)\n// ERC165_interfaceId() -> left(0x01ffc9a7)\n// hello_world() -> left(0xc6be8b58)\n// hello_world_interfaceId() -> left(0xc6be8b58)\n// ghello_world_interfaceId() -> left(0xc6be8b58)\n// other() -> left(0x85295877)\n// hello_world_derived_interfaceId() -> left(0x85295877)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/interfaceID/lisa.sol",
    "content": "interface ERC165 {\n    /// @notice Query if a contract implements an interface\n    /// @param interfaceID The interface identifier, as specified in ERC-165\n    /// @dev Interface identification is specified in ERC-165. This function\n    ///  uses less than 30,000 gas.\n    /// @return `true` if the contract implements `interfaceID` and\n    ///  `interfaceID` is not 0xffffffff, `false` otherwise\n    function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract ERC165MappingImplementation is ERC165 {\n    /// @dev You must not set element 0xffffffff to true\n    mapping(bytes4 => bool) internal supportedInterfaces;\n\n    constructor() {\n        supportedInterfaces[this.supportsInterface.selector] = true;\n    }\n\n    function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n        return supportedInterfaces[interfaceID];\n    }\n}\n\ninterface Simpson {\n    function is2D() external returns (bool);\n    function skinColor() external returns (string memory);\n}\n\ncontract Lisa is ERC165MappingImplementation, Simpson {\n    constructor() {\n        supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true;\n    }\n\n    function is2D() external override returns (bool) {\n        return true;\n    }\n\n    function skinColor() external override returns (string memory) {\n        return \"yellow\";\n    }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/interfaceID/lisa_interfaceId.sol",
    "content": "interface ERC165 {\n    /// @notice Query if a contract implements an interface\n    /// @param interfaceID The interface identifier, as specified in ERC-165\n    /// @dev Interface identification is specified in ERC-165. This function\n    ///  uses less than 30,000 gas.\n    /// @return `true` if the contract implements `interfaceID` and\n    ///  `interfaceID` is not 0xffffffff, `false` otherwise\n    function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract ERC165MappingImplementation is ERC165 {\n    /// @dev You must not set element 0xffffffff to true\n    mapping(bytes4 => bool) internal supportedInterfaces;\n\n    constructor() {\n        supportedInterfaces[this.supportsInterface.selector] = true;\n    }\n\n    function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n        return supportedInterfaces[interfaceID];\n    }\n}\n\ninterface Simpson {\n    function is2D() external returns (bool);\n    function skinColor() external returns (string memory);\n}\n\ncontract Lisa is ERC165MappingImplementation, Simpson {\n    constructor() {\n        supportedInterfaces[type(Simpson).interfaceId] = true;\n    }\n\n    function is2D() external override returns (bool) {\n        return true;\n    }\n\n    function skinColor() external override returns (string memory) {\n        return \"yellow\";\n    }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/account.sol",
    "content": "contract AccountBuiltinTest {\n    function who_am_i() public returns (address result) {\n        result = msg.sender;\n    }\n}\n// ----\n// constructor()\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// who_am_i() -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// who_am_i() -> 0x1212121212121212121212121212120000001012\n// balance: 0x1212121212121212121212121212120000001012 -> 1267650600228229401496703205376\n// account: 2 -> 0x1212121212121212121212121212120000002012\n// who_am_i() -> 0x1212121212121212121212121212120000002012\n// balance: 0x1212121212121212121212121212120000002012 -> 1267650600228229401496703205376\n// account: 3 -> 0x1212121212121212121212121212120000003012\n// who_am_i() -> 0x1212121212121212121212121212120000003012\n// balance: 0x1212121212121212121212121212120000003012 -> 1267650600228229401496703205376\n// account: 4 -> 0x1212121212121212121212121212120000004012\n// who_am_i() -> 0x1212121212121212121212121212120000004012\n// balance: 0x1212121212121212121212121212120000004012 -> 1267650600228229401496703205376\n// account: 5 -> 0x1212121212121212121212121212120000005012\n// who_am_i() -> 0x1212121212121212121212121212120000005012\n// balance: 0x1212121212121212121212121212120000005012 -> 1267650600228229401496703205376\n// account: 6 -> 0x1212121212121212121212121212120000006012\n// who_am_i() -> 0x1212121212121212121212121212120000006012\n// balance: 0x1212121212121212121212121212120000006012 -> 1267650600228229401496703205376\n// account: 7 -> 0x1212121212121212121212121212120000007012\n// who_am_i() -> 0x1212121212121212121212121212120000007012\n// balance: 0x1212121212121212121212121212120000007012 -> 1267650600228229401496703205376\n// account: 8 -> 0x1212121212121212121212121212120000008012\n// who_am_i() -> 0x1212121212121212121212121212120000008012\n// balance: 0x1212121212121212121212121212120000008012 -> 1267650600228229401496703205376\n// account: 9 -> 0x1212121212121212121212121212120000009012\n// who_am_i() -> 0x1212121212121212121212121212120000009012\n// balance: 0x1212121212121212121212121212120000009012 -> 1267650600228229401496703205376\n// account: 10 -> 0x121212121212121212121212121212000000a012\n// who_am_i() -> 0x121212121212121212121212121212000000a012\n// balance: 0x121212121212121212121212121212000000a012 -> 0\n// account: 11 -> 0x121212121212121212121212121212000000b012\n// who_am_i() -> 0x121212121212121212121212121212000000b012\n// balance: 0x121212121212121212121212121212000000b012 -> 0\n// account: 12 -> 0x121212121212121212121212121212000000c012\n// who_am_i() -> 0x121212121212121212121212121212000000c012\n// balance: 0x121212121212121212121212121212000000c012 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/balance_other_contract.sol",
    "content": "contract C {\n    constructor() payable {\n        payable(address(0x1234)).transfer(500);\n    }\n}\n// ----\n// constructor(), 2000 wei ->\n// balance -> 1500\n// balance: 0x0000000000000000000000000000000000001234 -> 500\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/balance_with_balance.sol",
    "content": "contract ClientReceipt {\n    constructor() payable {}\n}\n// ----\n// constructor(), 1000 wei ->\n// balance -> 1000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/balance_with_balance2.sol",
    "content": "contract ClientReceipt {\n    constructor() payable {}\n}\n// ----\n// constructor(), 1 ether ->\n// balance -> 1000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/balance_without_balance.sol",
    "content": "contract ClientReceipt {\n}\n// ----\n// balance -> 0\n// balance: 0x0000000000000000000000000000000000000000 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/builtins.sol",
    "content": "contract SmokeTest {\n}\n// ----\n// isoltest_builtin_test -> 0x1234\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/effects.sol",
    "content": "contract SmokeTest {\n}\n// ----\n// isoltest_side_effects_test -> 0\n// isoltest_side_effects_test: 0x1234 -> 0x1234\n// ~ 0000000000000000000000000000000000000000000000000000000000001234\n// isoltest_side_effects_test: 0x1234, 0x2345 # comment # -> 0x1234, 0x2345\n// ~ 0000000000000000000000000000000000000000000000000000000000001234\n// ~ 0000000000000000000000000000000000000000000000000000000000002345\n// isoltest_side_effects_test: 0x1234, 0x2345, 0x3456 -> 0x1234, 0x2345, 0x3456 # comment #\n// ~ 0000000000000000000000000000000000000000000000000000000000001234\n// ~ 0000000000000000000000000000000000000000000000000000000000002345\n// ~ 0000000000000000000000000000000000000000000000000000000000003456\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/empty_contract.sol",
    "content": "contract test {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// i_am_not_there() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/format_raw_string_with_control_chars.sol",
    "content": "contract C {\n    function f(string memory s) external pure returns (string memory) {\n        return s;\n    }\n}\n// NOTE: The test is here to illustrate the problem with formatting control chars in strings in\n// test expectations but unfortunately it can only be triggered manually. It does not test anything\n// unless you introduce a difference in expectations to force isoltest to reformat them.\n// ----\n// f(string): 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" -> 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" # Input/Output: \"😃😃😃😃\" #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/isoltestFormatting.sol",
    "content": "contract C {\n    function f() public returns (uint[5] memory) {\n        uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n        return a;\n    }\n    function g() public returns (uint[5] memory) {\n        uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n        return a;\n    }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/precompiles_ignoring_trailing_input.sol",
    "content": "contract C {\n    function ecRecover(uint[4] memory input) public returns (bytes memory) {\n        (bool success, bytes memory encodedOutput) = address(1).call(abi.encode(input));\n        require(success);\n        return encodedOutput;\n    }\n\n    function ecAdd(uint[4] memory input) public returns (bytes memory) {\n        (bool success, bytes memory encodedOutput) = address(6).call(abi.encode(input));\n        require(success);\n        return encodedOutput;\n    }\n\n    function ecMul(uint[3] memory input) public returns (bytes memory) {\n        (bool success, bytes memory encodedOutput) = address(7).call(abi.encode(input));\n        require(success);\n        return encodedOutput;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// ecRecover(uint256[4]): 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c, 0x000000000000000000000000000000000000000000000000000000000000001c, 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f, 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549                   -> 0x20, 0x20, 966588469268559010541288244128342317224451555083\n// ecRecover(uint256[4]): 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c, 0x000000000000000000000000000000000000000000000000000000000000001c, 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f, 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549, 0x01, 0x02, 0x03 -> 0x20, 0x20, 966588469268559010541288244128342317224451555083\n\n// ecAdd(uint256[4]): 0x01, 0x02, 0x01, 0x02                   -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764\n// ecAdd(uint256[4]): 0x01, 0x02, 0x01, 0x02, 0x01             -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764\n// ecAdd(uint256[4]): 0x01, 0x02, 0x01, 0x02, 0x01, 0x02       -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764\n// ecAdd(uint256[4]): 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03 -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764\n\n// ecMul(uint256[3]): 0x01, 0x02, 0x02                   -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764\n// ecMul(uint256[3]): 0x01, 0x02, 0x02, 0x01             -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764\n// ecMul(uint256[3]): 0x01, 0x02, 0x02, 0x01, 0x02       -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764\n// ecMul(uint256[3]): 0x01, 0x02, 0x02, 0x01, 0x02, 0x03 -> 0x20, 0x40, 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/storage/storage_empty.sol",
    "content": "contract StorageEmpty {\n}\n// ----\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/isoltestTesting/storage/storage_nonempty.sol",
    "content": "contract StorageNotEmpty {\n    uint256 x;\n    function set(uint256 _a) public { x = _a; }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256): 1 ->\n// storageEmpty -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/attached_internal_library_function_accepting_calldata.sol",
    "content": "library D {\n    function f(bytes calldata _x) internal pure returns (bytes1) {\n        return _x[0];\n    }\n    function g(bytes memory _x) internal pure returns (bytes1) {\n        return _x[0];\n    }\n}\n\ncontract C {\n    using D for bytes;\n    function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n        return (_x.f(), _x.g());\n    }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/attached_internal_library_function_returning_calldata.sol",
    "content": "library D {\n    function f(bytes calldata _x) internal pure returns (bytes calldata) {\n        return _x;\n    }\n    function g(bytes calldata _x) internal pure returns (bytes memory) {\n        return _x;\n    }\n}\n\ncontract C {\n    using D for bytes;\n    function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n        return (_x.f()[0], _x.g()[0]);\n    }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/attached_public_library_function_accepting_calldata.sol.sol",
    "content": "library D {\n    function f(bytes calldata _x) public pure returns (bytes1) {\n        return _x[0];\n    }\n    function g(bytes memory _x) public pure returns (bytes1) {\n        return _x[0];\n    }\n}\n\ncontract C {\n    using D for bytes;\n    function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n        return (_x.f(), _x.g());\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/attached_public_library_function_returning_calldata.sol",
    "content": "library D {\n    function f(bytes calldata _x) public pure returns (bytes calldata) {\n        return _x;\n    }\n    function g(bytes calldata _x) public pure returns (bytes memory) {\n        return _x;\n    }\n}\n\ncontract C {\n    using D for bytes;\n    function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n        return (_x.f()[0], _x.g()[0]);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/external_call_with_function_pointer_parameter.sol",
    "content": "library L {\n    function run(\n        function(uint256) external returns (uint256) _operation,\n        uint256 _a\n    )\n        external\n        returns (uint256)\n    {\n        return _operation(_a);\n    }\n}\n\ncontract C {\n    function double(uint256 _a) external returns (uint256) {\n        return _a * _a;\n    }\n\n    function g(uint256 _value) external returns (uint256) {\n        return L.run(this.double, _value);\n    }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/external_call_with_storage_array_parameter.sol",
    "content": "library L {\n    function f(uint256[2] storage _a) external returns (uint256) {\n        return _a[0] * _a[1];\n    }\n}\n\ncontract C {\n    uint256[2] x;\n\n    function g(uint256 _value) external returns (uint256) {\n        x[0] = x[1] = _value;\n        return L.f(x);\n    }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/external_call_with_storage_mapping_parameter.sol",
    "content": "library L {\n    function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n        return _a[0] * _a[1];\n    }\n}\n\ncontract C {\n    mapping(uint256 => uint256) x;\n\n    function g(uint256 _value) external returns (uint256) {\n        x[0] = x[1] = _value;\n        return L.f(x);\n    }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_call_attached_with_parentheses.sol",
    "content": "library L {\n    struct S {\n        uint256[] data;\n    }\n\n    function f(S memory _s) internal {\n        _s.data[3] += 2;\n    }\n}\n\n\ncontract C {\n    using L for L.S;\n\n    function f() public returns (uint256) {\n        L.S memory x;\n        x.data = new uint256[](7);\n        x.data[3] = 8;\n        (x.f)();\n        return x.data[3];\n    }\n}\n// ----\n// f() -> 0x0a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_call_unattached_with_parentheses.sol",
    "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function.sol",
    "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n    function f(uint256[] memory _data) internal {\n        _data[3] = 2;\n    }\n}\n\n\ncontract C {\n    function f() public returns (uint256) {\n        uint256[] memory x = new uint256[](7);\n        x[3] = 8;\n        L.f(x);\n        return x[3];\n    }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_address.sol",
    "content": "library L {\n    function equals(address a, address b) internal pure returns (bool) {\n        return a == b;\n    }\n}\n\ncontract C {\n    using L for address;\n\n    function foo(address a, address b) public returns (bool) {\n        return a.equals(b);\n    }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_address_named_send_transfer.sol",
    "content": "library L {\n    function transfer(address a) internal {}\n    function send(address a) internal {}\n}\n\ncontract C {\n    using L for address;\n\n    function useTransfer(address a) public {\n        a.transfer();\n    }\n\n    function useSend(address a) public {\n        a.send();\n    }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_array_named_pop_push.sol",
    "content": "library L {\n    function pop(uint[2] memory a) internal {}\n    function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n    using L for uint[2];\n\n    function test() public {\n        uint[2] memory input;\n\n        input.push();\n        input.pop();\n    }\n}\n// ----\n// test() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_bool.sol",
    "content": "library L {\n    function xor(bool a, bool b) internal pure returns (bool) {\n        return a != b;\n    }\n}\n\ncontract C {\n    using L for bool;\n\n    function foo(bool a, bool b) public returns (bool) {\n        return a.xor(b);\n    }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_contract.sol",
    "content": "contract E {}\n\nlibrary L {\n    function foo(E e) internal pure returns (uint) {\n        return 42;\n    }\n}\n\ncontract C {\n    using L for E;\n\n    function test() public returns (uint) {\n        E e = new E();\n        return e.foo();\n    }\n}\n// ----\n// test() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_dynamic_array.sol",
    "content": "library L {\n    function at(uint[] memory a, uint i) internal pure returns (uint) {\n        return a[i];\n    }\n}\n\ncontract C {\n    using L for uint[];\n\n    function secondItem() public returns (uint) {\n        uint[] memory input = new uint[](2);\n        input[0] = 0x11;\n        input[1] = 0x22;\n\n        return input.at(1);\n    }\n}\n// ----\n// secondItem() -> 0x22\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_enum.sol",
    "content": "library L {\n    enum E { A, B }\n\n    function equals(E a, E b) internal pure returns (bool) {\n        return a == b;\n    }\n}\n\ncontract C {\n    using L for L.E;\n\n    function equalsA(uint choice) public returns (bool) {\n        L.E x = L.E.A;\n        return x.equals(L.E(choice));\n    }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_external_function_type.sol",
    "content": "library L {\n    // NOTE: External function takes up two stack slots\n    function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n        return f(x) * 2;\n    }\n}\n\ncontract C {\n    using L for function(uint) external pure returns (uint);\n\n    function identity(uint x) external pure returns (uint) {\n        return x;\n    }\n\n    function test(uint value) public returns (uint) {\n        return this.identity.double(value);\n    }\n}\n// ----\n// test(uint256): 5 -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_fixed_array.sol",
    "content": "library L {\n    function at(uint[2] memory a, uint i) internal pure returns (uint) {\n        return a[i];\n    }\n}\n\ncontract C {\n    using L for uint[2];\n\n    function secondItem() public returns (uint) {\n        uint[2] memory input;\n        input[0] = 0x11;\n        input[1] = 0x22;\n\n        return input.at(1);\n    }\n}\n// ----\n// secondItem() -> 0x22\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_fixed_bytes.sol",
    "content": "library L {\n    function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n        return bytes2(uint16(a) + uint16(b));\n    }\n}\n\ncontract C {\n    using L for bytes2;\n\n    function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n        return a.add(b);\n    }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_integer.sol",
    "content": "library L {\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a + b;\n    }\n}\n\ncontract C {\n    using L for uint256;\n\n    function foo(uint256 a, uint256 b) public returns (uint256) {\n        return a.add(b);\n    }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_interface.sol",
    "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n    function foo(I i) internal pure returns (uint) {\n        return 42;\n    }\n}\n\ncontract C {\n    using L for I;\n\n    function test() public returns (uint) {\n        E e = new E();\n        return I(e).foo();\n    }\n}\n// ----\n// test() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_internal_function_type.sol",
    "content": "library L {\n    function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n        return f(x) * 2;\n    }\n}\n\ncontract C {\n    using L for function(uint) internal pure returns (uint);\n\n    function identity(uint x) internal pure returns (uint) {\n        return x;\n    }\n\n    function test(uint value) public returns (uint) {\n        return identity.double(value);\n    }\n}\n// ----\n// test(uint256): 5 -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_internal_function_type_named_selector.sol",
    "content": "library L {\n    function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n        return f(x) * 2;\n    }\n}\n\ncontract C {\n    using L for function(uint) internal pure returns (uint);\n\n    function identity(uint x) internal pure returns (uint) {\n        return x;\n    }\n\n    function test(uint value) public returns (uint) {\n        return identity.selector(value);\n    }\n}\n// ----\n// test(uint256): 5 -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_literal.sol",
    "content": "library L {\n    function double(uint a) internal pure returns (uint) {\n        return a * 2;\n    }\n\n    function double(bytes memory a) internal pure returns (bytes memory) {\n        return bytes.concat(a, a);\n    }\n}\n\ncontract C {\n    using L for *;\n\n    function double42() public returns (uint) {\n        return 42.double();\n    }\n\n    function doubleABC() public returns (bytes memory) {\n        return \"abc\".double();\n    }\n}\n// ----\n// double42() -> 84\n// doubleABC() -> 0x20, 6, \"abcabc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_mapping.sol",
    "content": "library L {\n    function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n        return a[i];\n    }\n}\n\ncontract C {\n    using L for mapping(uint => uint);\n\n    mapping(uint => uint) map;\n\n    function mapValue(uint a) public returns (uint) {\n        map[42] = 0x24;\n        map[66] = 0x66;\n\n        return map.at(a);\n    }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_string_accepting_memory.sol",
    "content": "library L {\n    function at(string memory a, uint i) internal pure returns (uint8) {\n        return uint8(bytes(a)[i]);\n    }\n}\n\ncontract C {\n    using L for string;\n\n    function secondChar() public returns (uint8) {\n        string memory input = \"abc\";\n        return input.at(1);\n    }\n}\n// ----\n// secondChar() -> 98\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_string_accepting_storage.sol",
    "content": "library L {\n    function f(string memory a) internal pure returns (string memory) {\n        return a;\n    }\n    function g(string storage a) internal pure returns (string memory) {\n        return a;\n    }\n}\n\ncontract C {\n    using L for string;\n    string s;\n\n    function test(string calldata x) public returns (string memory, string memory) {\n        s = x;\n        return (s.f(), s.g());\n    }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_attached_to_struct.sol",
    "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n    struct S {\n        uint256[] data;\n    }\n\n    function f(S memory _s) internal {\n        _s.data[3] = 2;\n    }\n}\n\n\ncontract C {\n    using L for L.S;\n\n    function f() public returns (uint256) {\n        L.S memory x;\n        x.data = new uint256[](7);\n        x.data[3] = 8;\n        x.f();\n        return x.data[3];\n    }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_calling_private.sol",
    "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n    function g(uint256[] memory _data) private {\n        _data[3] = 2;\n    }\n\n    function f(uint256[] memory _data) internal {\n        g(_data);\n    }\n}\n\n\ncontract C {\n    function f() public returns (uint256) {\n        uint256[] memory x = new uint256[](7);\n        x[3] = 8;\n        L.f(x);\n        return x[3];\n    }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_pointer.sol",
    "content": "library L {\n    function f() internal returns (uint) {\n        return 66;\n    }\n}\n\ncontract C {\n    function g() public returns (uint) {\n        function() internal returns(uint) ptr;\n        ptr = L.f;\n        return ptr();\n    }\n}\n// ----\n// g() -> 66\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_library_function_return_var_size.sol",
    "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n    struct S {\n        uint256[] data;\n    }\n\n    function f(S memory _s) internal returns (uint256[] memory) {\n        _s.data[3] = 2;\n        return _s.data;\n    }\n}\n\n\ncontract C {\n    using L for L.S;\n\n    function f() public returns (uint256) {\n        L.S memory x;\n        x.data = new uint256[](7);\n        x.data[3] = 8;\n        return x.f()[3];\n    }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/internal_types_in_library.sol",
    "content": "library Lib {\n    function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n    {\n        for (uint i = 0; i < _haystack.length; ++i)\n            if (_haystack[i] == _needle)\n                return i;\n        return type(uint).max;\n    }\n}\ncontract Test {\n    mapping(string => uint16[]) data;\n    function f() public returns (uint a, uint b)\n    {\n        while (data[\"abc\"].length < 20)\n            data[\"abc\"].push();\n        data[\"abc\"][4] = 9;\n        data[\"abc\"][17] = 3;\n        a = Lib.find(data[\"abc\"], 9);\n        b = Lib.find(data[\"abc\"], 3);\n    }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_address.sol",
    "content": "library L {\n    function f(uint256 v) external pure returns (uint) {\n        return v * v;\n    }\n    function g(uint256 v) external returns (uint) {\n        return v * v;\n    }\n}\ncontract C {\n    function addr() public view returns (bool) {\n        return address(L) == address(0);\n    }\n    function g(uint256 v) public view returns (uint256) {\n        return L.f(v);\n    }\n    function h(uint256 v) public returns (uint256) {\n        (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n        assert(success);\n        return abi.decode(result, (uint256));\n    }\n    function i(uint256 v) public returns (uint256) {\n        (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n        assert(success);\n        return abi.decode(result, (uint256));\n    }\n    function j(uint256 v) public returns (uint256) {\n        (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n        assert(success);\n        return abi.decode(result, (uint256));\n    }\n    function k(uint256 v) public returns (uint256) {\n        (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n        assert(success);\n        return abi.decode(result, (uint256));\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// bytecodeFormat: legacy,>=EOFv1\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_address_homestead.sol",
    "content": "library L {\n    function f(uint256 a, uint256 b) external {\n        assert(a * a == b);\n    }\n}\ncontract C {\n    function addr() public view returns (bool) {\n        return address(L) == address(0);\n    }\n    function g(uint256 a, uint256 b) public returns (bool) {\n        (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n        return success;\n    }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_address_via_module.sol",
    "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n    function f(uint256 v) external pure returns (uint) {\n        return v * v;\n    }\n    function g(uint256 v) external returns (uint) {\n        return v * v;\n    }\n}\ncontract C {\n    function addr() public view returns (bool) {\n        return address(M.L) == address(0);\n    }\n    function g(uint256 v) public view returns (uint256) {\n        return M.L.f(v);\n    }\n    function h(uint256 v) public returns (uint256) {\n        (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n        assert(success);\n        return abi.decode(result, (uint256));\n    }\n    function i(uint256 v) public returns (uint256) {\n        (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n        assert(success);\n        return abi.decode(result, (uint256));\n    }\n    function j(uint256 v) public returns (uint256) {\n        (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n        assert(success);\n        return abi.decode(result, (uint256));\n    }\n    function k(uint256 v) public returns (uint256) {\n        (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n        assert(success);\n        return abi.decode(result, (uint256));\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_call_in_homestead.sol",
    "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n    address public sender;\n    function f() public {\n        sender = Lib.m();\n    }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_delegatecall_guard_pure.sol",
    "content": "library L {\n    function f(uint256[] storage x) public pure returns (uint256) {\n        return 23;\n    }\n}\ncontract C {\n    uint256[] y;\n    string x;\n    constructor() { y.push(42); }\n    function f() public view returns (uint256) {\n        return L.f(y);\n    }\n    function g() public returns (bool, uint256) {\n        uint256 ys;\n        assembly { ys := y.slot }\n        (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n        return (success, success ? abi.decode(data,(uint256)) : 0);\n    }\n    function h() public returns (bool, uint256) {\n        uint256 ys;\n        assembly { ys := y.slot }\n        (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n        return (success, success ? abi.decode(data,(uint256)) : 0);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_delegatecall_guard_view_needed.sol",
    "content": "library L {\n    function f(uint256[] storage x) public view returns (uint256) {\n        return x.length;\n    }\n}\ncontract C {\n    uint256[] y;\n    string x;\n    constructor() { y.push(42); }\n    function f() public view returns (uint256) {\n        return L.f(y);\n    }\n    function g() public returns (bool, uint256) {\n        uint256 ys;\n        assembly { ys := y.slot }\n        (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n        return (success, success ? abi.decode(data,(uint256)) : 0);\n    }\n    function h() public returns (bool, uint256) {\n        uint256 ys;\n        assembly { ys := y.slot }\n        (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n        return (success, success ? abi.decode(data,(uint256)) : 0);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_delegatecall_guard_view_not_needed.sol",
    "content": "library L {\n    function f(uint256[] storage x) public view returns (uint256) {\n        return 84;\n    }\n}\ncontract C {\n    uint256[] y;\n    constructor() { y.push(42); }\n    function f() public view returns (uint256) {\n        return L.f(y);\n    }\n    function g() public returns (bool, uint256) {\n        uint256 ys;\n        assembly { ys := y.slot }\n        (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n        return (success, success ? abi.decode(data,(uint256)) : 0);\n    }\n    function h() public returns (bool, uint256) {\n        uint256 ys;\n        assembly { ys := y.slot }\n        (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n        return (success, success ? abi.decode(data,(uint256)) : 0);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_delegatecall_guard_view_staticcall.sol",
    "content": "contract D {\n    uint public x;\n    constructor() { x = 42; }\n}\nlibrary L {\n    function f(D d) public view returns (uint256) {\n        return d.x();\n    }\n}\ncontract C {\n    D d;\n    constructor() { d = new D(); }\n    function f() public view returns (uint256) {\n        return L.f(d);\n    }\n    function g() public returns (bool, uint256) {\n        (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n        return (success, success ? abi.decode(data,(uint256)) : 0);\n    }\n    function h() public returns (bool, uint256) {\n        (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n        return (success, success ? abi.decode(data,(uint256)) : 0);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_enum_as_an_expression.sol",
    "content": "library Arst {\n    enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n    function f() public returns (uint256) {\n        Arst.Foo;\n        return 1;\n    }\n}\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_function_selectors.sol",
    "content": "library L {\n    function f(uint256 x) external returns (uint) { return x; }\n    function g(uint256[] storage s) external returns (uint) { return s.length; }\n    function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n    uint256[] s;\n    constructor() { while (s.length < 42) s.push(0); }\n    function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n    }\n    function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n    }\n    function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_function_selectors_struct.sol",
    "content": "pragma abicoder               v2;\nlibrary L {\n    struct S { uint256 a; }\n    function f(S storage s) external returns (uint) { return s.a; }\n    function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n    L.S s;\n    constructor() { s.a = 42; }\n\n    function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n    }\n    function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_references_preserve.sol",
    "content": "library L1 {\n    function add(uint256 a, uint256 b) external pure returns (uint256) {\n        return a + b + 1;\n    }\n}\n\nlibrary L2 {\n    function add(uint256 a, uint256 b) external pure returns (uint256) {\n        return a + b + 2;\n    }\n}\n\ncontract A {\n    uint256 sum;\n    constructor() {\n        sum = L1.add(1, 2);\n    }\n    function getSum() external view returns(uint256) {\n        return sum;\n    }\n}\n\ncontract B {\n    uint256 sum;\n    constructor() {\n        sum = L2.add(1, 2);\n    }\n    function getSum() external view returns(uint256) {\n        return sum;\n    }\n}\n\ncontract C {\n    A a = new A();\n    B b = new B();\n    function aSum() external view returns(uint256) {\n        return a.getSum();\n    }\n    function bSum() external view returns(uint256) {\n        return b.getSum();\n    }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_return_struct_with_mapping.sol",
    "content": "pragma abicoder               v2;\n\nlibrary Lib {\n    struct Items {\n        mapping (uint => uint) a;\n    }\n\n    function get() public returns (Items storage x) {\n        assembly { x.slot := 123 }\n    }\n}\n\ncontract C {\n    function f() public returns(uint256 slot) {\n        Lib.Items storage ptr = Lib.get();\n        assembly { slot := ptr.slot }\n    }\n}\n// ----\n// library: Lib\n// f() -> 123\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_staticcall_delegatecall.sol",
    "content": "library Lib {\n    function x() public view returns (uint) {\n        return 1;\n    }\n}\ncontract Test {\n    uint t;\n    function f() public returns (uint) {\n        t = 2;\n        return this.g();\n    }\n    function g() public view returns (uint) {\n        return Lib.x();\n    }\n}\n// ----\n// library: Lib\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_stray_values.sol",
    "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n    function f(uint x) public returns (uint) {\n        Lib;\n        Lib.m;\n        return x + 9;\n    }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/library_struct_as_an_expression.sol",
    "content": "library Arst {\n    struct Foo {\n        int256 Things;\n        int256 Stuff;\n    }\n}\n\n\ncontract Tsra {\n    function f() public returns (uint256) {\n        Arst.Foo;\n        return 1;\n    }\n}\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/mapping_arguments_in_library.sol",
    "content": "library Lib {\n    function set(mapping(uint => uint) storage m, uint key, uint value) internal\n    {\n        m[key] = value;\n    }\n    function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n    {\n        return m[key];\n    }\n}\ncontract Test {\n    mapping(uint => uint) m;\n    function set(uint256 key, uint256 value) public returns (uint)\n    {\n        uint oldValue = Lib.get(m, key);\n        Lib.set(m, key, value);\n        return oldValue;\n    }\n    function get(uint256 key) public view returns (uint) {\n        return Lib.get(m, key);\n    }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/mapping_returns_in_library.sol",
    "content": "library Lib {\n    function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n    {\n        return c ? a : b;\n    }\n}\ncontract Test {\n    mapping(uint => uint) a;\n    mapping(uint => uint) b;\n    function set(bool choice, uint256 key, uint256 value) public returns (uint)\n    {\n        mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n        uint oldValue = m[key];\n        m[key] = value;\n        return oldValue;\n    }\n    function get(bool choice, uint256 key) public view returns (uint) {\n        return Lib.choose_mapping(a, b, choice)[key];\n    }\n    function get_a(uint256 key) public view returns (uint) {\n        return a[key];\n    }\n    function get_b(uint256 key) public view returns (uint) {\n        return b[key];\n    }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/mapping_returns_in_library_named.sol",
    "content": "library Lib {\n    function f(mapping(uint => uint) storage a, mapping(uint => uint) storage b) internal returns(mapping(uint=>uint) storage r)\n    {\n        r = a;\n        r[1] = 42;\n        r = b;\n        r[1] = 21;\n    }\n}\ncontract Test {\n    mapping(uint => uint) a;\n    mapping(uint => uint) b;\n    function f() public returns (uint, uint, uint, uint, uint, uint)\n    {\n        Lib.f(a, b)[2] = 84;\n        return (a[0], a[1], a[2], b[0], b[1], b[2]);\n    }\n    function g() public returns (uint, uint, uint, uint, uint, uint)\n    {\n        mapping(uint => uint) storage m = Lib.f(a, b);\n        m[2] = 17;\n        return (a[0], a[1], a[2], b[0], b[1], b[2]);\n    }\n}\n// ----\n// library: Lib\n// f() -> 0, 0x2a, 0, 0, 0x15, 0x54\n// g() -> 0, 0x2a, 0, 0, 0x15, 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/payable_function_calls_library.sol",
    "content": "library L {\n    function f() public returns (uint) { return 7; }\n}\ncontract C {\n    function f() public payable returns (uint) {\n        return L.f();\n    }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/stub.sol",
    "content": "library L {\n    function f(uint256 v) external returns (uint256) { return v*v; }\n}\ncontract C {\n    function g(uint256 v) external returns (uint256) {\n        return L.f(v);\n    }\n}\n// ----\n// library: L\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/stub_internal.sol",
    "content": "library L {\n    function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n    function g(uint256 v) external returns (uint256) {\n        return L.f(v);\n    }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/using_for_by_name.sol",
    "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n    using D for D.s;\n    D.s public x;\n    function f(uint a) public returns (uint) {\n        x.a = 6;\n        return x.mul({x: a});\n    }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/using_for_function_on_int.sol",
    "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/using_for_overload.sol",
    "content": "library D {\n    struct s { uint a; }\n    function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n    function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n    using D for D.s;\n    D.s public x;\n    function f(uint a) public returns (uint) {\n        x.a = 6;\n        return x.mul(a);\n    }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/using_for_storage_structs.sol",
    "content": "struct Struct { uint x; }\n\nlibrary L {\n    function f(Struct storage _x) internal view returns (uint256) {\n      return _x.x;\n    }\n}\n\ncontract C {\n  using L for Struct;\n\n  Struct s;\n\n  function h(Struct storage _s) internal view returns (uint) {\n    // _s is pointer\n    return _s.f();\n  }\n  function g() public returns (uint, uint) {\n    s.x = 7;\n    // s is reference\n    return (s.f(), h(s));\n  }\n}\n// ----\n// g() -> 7, 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/using_library_mappings_public.sol",
    "content": "library Lib {\n    function set(mapping(uint => uint) storage m, uint key, uint value) public\n    {\n        m[key] = value;\n    }\n}\ncontract Test {\n    mapping(uint => uint) m1;\n    mapping(uint => uint) m2;\n    function f() public returns (uint, uint, uint, uint, uint, uint)\n    {\n        Lib.set(m1, 0, 1);\n        Lib.set(m1, 2, 42);\n        Lib.set(m2, 0, 23);\n        Lib.set(m2, 2, 99);\n        return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n    }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/using_library_mappings_return.sol",
    "content": "library Lib {\n    function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n        return m[key];\n    }\n}\ncontract Test {\n    mapping(uint => mapping(uint => uint)) m;\n    function f() public returns (uint, uint, uint, uint, uint, uint)\n    {\n        Lib.choose(m, 0)[0] = 1;\n        Lib.choose(m, 0)[2] = 42;\n        Lib.choose(m, 1)[0] = 23;\n        Lib.choose(m, 1)[2] = 99;\n        return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n    }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n"
  },
  {
    "path": "test/libsolidity/semanticTests/libraries/using_library_structs.sol",
    "content": "library Lib {\n    struct Data { uint a; uint[] b; }\n    function set(Data storage _s) public\n    {\n        _s.a = 7;\n        while (_s.b.length < 20)\n            _s.b.push();\n        _s.b[19] = 8;\n    }\n}\ncontract Test {\n    mapping(string => Lib.Data) data;\n    function f() public returns (uint a, uint b)\n    {\n        Lib.set(data[\"abc\"]);\n        a = data[\"abc\"].a;\n        b = data[\"abc\"].b[19];\n    }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 97577\n// gas legacy: 101428\n"
  },
  {
    "path": "test/libsolidity/semanticTests/literals/denominations.sol",
    "content": "contract C {\n\tuint constant x = 1 ether + 1 gwei + 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000001000000001\n"
  },
  {
    "path": "test/libsolidity/semanticTests/literals/denominations_in_array_sizes.sol",
    "content": "contract C {\n    uint[2 wei] a;\n    uint[2 gwei] b;\n    uint[2 ether] c;\n    uint[2 seconds] d;\n    uint[2 minutes] e;\n    uint[2 hours] f;\n    uint[2 days] g;\n    uint[2 weeks] h;\n\n    function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) {\n        return (\n            a.length,\n            b.length,\n            c.length,\n            d.length,\n            e.length,\n            f.length,\n            g.length,\n            h.length\n        );\n    }\n}\n// ----\n// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/literals/escape.sol",
    "content": "pragma abicoder v2;\n\ncontract C\n{\n\tfunction f() public pure returns (uint, bytes1, bytes1) {\n\t\tbytes memory encoded = abi.encodePacked(\"\\\\\\\\\");\n\t\treturn (encoded.length, encoded[0], encoded[1]);\n\t}\n}\n// ----\n// f() -> 2, 0x5c00000000000000000000000000000000000000000000000000000000000000, 0x5c00000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/literals/ether.sol",
    "content": "contract C {\n\tuint constant x = 1 ether;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/literals/fractional_denominations.sol",
    "content": "contract C {\n    uint public g = 1.5 gwei;\n    uint public e = 1.5 ether;\n    uint public m = 1.5 minutes;\n    uint public h = 1.5 hours;\n    uint public d = 1.5 days;\n    uint public w = 1.5 weeks;\n}\n// ----\n// g() -> 1500000000\n// e() -> 1500000000000000000\n// m() -> 90\n// h() -> 5400\n// d() -> 129600\n// w() -> 907200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/literals/gwei.sol",
    "content": "contract C {\n\tuint constant x = 1 gwei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/literals/hex_string_with_non_printable_characters.sol",
    "content": "contract C {\n    function f() public pure returns (bytes32 result) {\n        assembly {\n            result := hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"\n        }\n    }\n}\n// ----\n// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n"
  },
  {
    "path": "test/libsolidity/semanticTests/literals/hex_string_with_underscore.sol",
    "content": "contract C {\n    function f() public pure returns(bytes memory) {\n        return hex\"12_34_5678_9A\";\n    }\n}\n// ----\n// f() -> 32, 5, left(0x123456789A)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/literals/scientific_notation.sol",
    "content": "contract C {\n    function f() public returns(uint) {\n        return 2e10 wei;\n    }\n\n    function g() public returns(uint) {\n        return 200e-2 wei;\n    }\n\n    function h() public returns(uint) {\n        return 2.5e1;\n    }\n\n    function i() public returns(int) {\n        return -2e10;\n    }\n\n    function j() public returns(int) {\n        return -200e-2;\n    }\n\n    function k() public returns(int) {\n        return -2.5e1;\n    }\n}\n// ----\n// f() -> 20000000000\n// g() -> 2\n// h() -> 25\n// i() -> -20000000000\n// j() -> -2\n// k() -> -25\n"
  },
  {
    "path": "test/libsolidity/semanticTests/literals/ternary_operator_with_literal_types_overflow.sol",
    "content": "contract TestTernary\n{\n    function h() pure public returns (uint16 b)\n    {\n        b = (true ? 63 : 255) + (false ? 63 : 255);\n    }\n\n    function g() pure public returns (uint16 a)\n    {\n        bool t = true;\n        bool f = false;\n        a = (t ? 63 : 255) + (f ? 63 : 255);\n    }\n}\n// ----\n// g() -> FAILURE, hex\"4e487b71\", 0x11\n// h() -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/literals/wei.sol",
    "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/memoryManagement/assembly_access.sol",
    "content": "contract C {\n    function f() public pure {\n        uint[] memory x;\n        uint y;\n        assembly {\n            y := x\n        }\n        // The value of an uninitialized dynamic array is not zero but rather\n        // an address of a location in memory that has the value of zero.\n        assert(y != 0);\n    }\n}\n// ----\n// f() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/memoryManagement/memory_types_initialisation.sol",
    "content": "contract Test {\n    mapping(uint=>uint) data;\n    function stat() public returns (uint[5] memory)\n    {\n        data[2] = 3; // make sure to use some memory\n    }\n    function dyn() public returns (uint[] memory) { stat(); }\n    function nested() public returns (uint[3][] memory) { stat(); }\n    function nestedStat() public returns (uint[3][7] memory) { stat(); }\n}\n// ----\n// stat() -> 0, 0, 0, 0, 0\n// dyn() -> 0x20, 0\n// nested() -> 0x20, 0\n// nestedStat() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/memoryManagement/return_variable.sol",
    "content": "contract C {\n    function memorySize() internal pure returns (uint s) {\n        assembly { s := mload(0x40) }\n    }\n    function f() public returns (uint, uint, uint) {\n        uint a = memorySize();\n        g();\n        uint b = memorySize();\n        h();\n        uint c = memorySize();\n        i();\n        uint d = memorySize();\n        return (b - a, c - b, d - c);\n    }\n    // In these functions, we do allocate memory in both cases.\n    // In `i()`, this could be avoided but we would have to check\n    // that all code paths return explicitly and provide a value.\n    function g() internal returns (uint[40] memory) {\n    }\n    function h() internal returns (uint[40] memory t) {\n    }\n    function i() internal returns (uint[40] memory) {\n        uint[40] memory x;\n        return x;\n    }\n}\n// ----\n// f() -> 0x0500, 0x0500, 0x0a00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/memoryManagement/static_memory_array_allocation.sol",
    "content": "contract C {\n    function memorySize() internal pure returns (uint s) {\n        assembly { s := mload(0x40) }\n    }\n    function withValue() public pure returns (uint) {\n        uint[20] memory x;\n        uint memorySizeBefore = memorySize();\n        uint[20] memory t = x;\n        uint memorySizeAfter = memorySize();\n        return memorySizeAfter - memorySizeBefore;\n    }\n    function withoutValue() public pure returns (uint) {\n        uint[20] memory x;\n        uint memorySizeBefore = memorySize();\n        uint[20] memory t;\n        uint memorySizeAfter = memorySize();\n        return memorySizeAfter - memorySizeBefore;\n    }\n}\n// ----\n// withValue() -> 0x00\n// withoutValue() -> 0x0280\n"
  },
  {
    "path": "test/libsolidity/semanticTests/memoryManagement/struct_allocation.sol",
    "content": "contract C {\n    struct S { uint x; uint y; uint z; }\n    function memorySize() internal pure returns (uint s) {\n        assembly { s := mload(0x40) }\n    }\n    function withValue() public pure returns (uint) {\n        S memory x = S(1, 2, 3);\n        uint memorySizeBefore = memorySize();\n        S memory t = x;\n        uint memorySizeAfter = memorySize();\n        return memorySizeAfter - memorySizeBefore;\n    }\n    function withoutValue() public pure returns (uint) {\n        uint memorySizeBefore = memorySize();\n        S memory t;\n        uint memorySizeAfter = memorySize();\n        return memorySizeAfter - memorySizeBefore;\n    }\n}\n// ----\n// withValue() -> 0x00\n// withoutValue() -> 0x60\n"
  },
  {
    "path": "test/libsolidity/semanticTests/metaTypes/name_other_contract.sol",
    "content": "abstract contract A {\n    function f() virtual public pure;\n}\n\ninterface I {\n    function f() external pure;\n}\n\ncontract C {\n    function f() pure public {\n    }\n}\n\ncontract Test is C {\n    function c() public pure returns (string memory) {\n        return type(C).name;\n    }\n    function a() public pure returns (string memory) {\n        return type(A).name;\n    }\n    function i() public pure returns (string memory) {\n        return type(I).name;\n    }\n}\n// ----\n// c() -> 0x20, 1, \"C\"\n// a() -> 0x20, 1, \"A\"\n// i() -> 0x20, 1, \"I\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/access_through_contract_name.sol",
    "content": "contract A {\n    uint public x = 7;\n    modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n    modifier m override { x = 1; _; }\n\n    function f() public A.m returns (uint) {\n        return 9;\n    }\n    function g() public m returns (uint) {\n        return 10;\n    }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/access_through_module_name.sol",
    "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n    uint public x;\n    modifier m { x = 1; _; }\n\n    function f() public M.M.C.m returns (uint t, uint r) {\n        t = x;\n        x = 3;\n        r = 9;\n    }\n    function g() public m returns (uint t, uint r) {\n        t = x;\n        x = 4;\n        r = 10;\n    }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/break_in_modifier.sol",
    "content": "contract C {\n    uint256 public x;\n    modifier run() {\n        for (uint256 i = 0; i < 10; i++) {\n            _;\n            if (i == 1)\n                break;\n        }\n    }\n\n    function f() public run {\n        uint256 k = x;\n        uint256 t = k + 1;\n        x = t;\n    }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/continue_in_modifier.sol",
    "content": "contract C {\n    uint256 public x;\n    modifier run() {\n        for (uint256 i = 0; i < 10; i++) {\n            if (i % 2 == 1) continue;\n            _;\n        }\n    }\n\n    function f() public run {\n        uint256 k = x;\n        uint256 t = k + 1;\n        x = t;\n    }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/evaluation_order.sol",
    "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n    uint[] x;\n    constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n        f(7);\n    }\n\n    function query() public view returns (uint[] memory) { return x; }\n\n    modifier m1(uint) { _; }\n    modifier m2(uint) { _; }\n    modifier m3(uint) { _; }\n\n    function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier.sol",
    "content": "contract C {\n    function getOne() public payable nonFree returns (uint256 r) {\n        return 1;\n    }\n\n    modifier nonFree {\n        if (msg.value > 0) _;\n    }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_calling_functions_in_creation_context.sol",
    "content": "contract A {\n    uint256 data;\n\n    constructor() mod1 {\n        f1();\n    }\n\n    function f1() public mod2 {\n        data |= 0x1;\n    }\n\n    function f2() public {\n        data |= 0x20;\n    }\n\n    function f3() public virtual {}\n\n    modifier mod1 virtual {\n        f2();\n        _;\n    }\n    modifier mod2 {\n        f3();\n        if (false) _;\n    }\n\n    function getData() public returns (uint256 r) {\n        return data;\n    }\n}\n\n\ncontract C is A {\n    modifier mod1 override {\n        f4();\n        _;\n    }\n\n    function f3() public override {\n        data |= 0x300;\n    }\n\n    function f4() public {\n        data |= 0x4000;\n    }\n}\n// ----\n// getData() -> 0x4300\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_empty.sol",
    "content": "abstract contract A {\n    function f() public mod returns (bool r) {\n        return true;\n    }\n\n    modifier mod virtual;\n}\n\n\ncontract C is A {\n    modifier mod override {\n        if (false) _;\n    }\n}\n// ----\n// f() -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_for_constructor.sol",
    "content": "contract A {\n    uint256 data;\n\n    constructor() mod1 {\n        data |= 2;\n    }\n\n    modifier mod1 virtual {\n        data |= 1;\n        _;\n    }\n\n    function getData() public returns (uint256 r) {\n        return data;\n    }\n}\n\n\ncontract C is A {\n    modifier mod1 override {\n        data |= 4;\n        _;\n    }\n}\n// ----\n// getData() -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_library.sol",
    "content": "library L {\n    struct S {\n        uint256 v;\n    }\n    modifier mod(S storage s) {\n        s.v++;\n        _;\n    }\n\n    function libFun(S storage s) internal mod(s) {\n        s.v += 0x100;\n    }\n}\n\n\ncontract Test {\n    using L for *;\n    L.S s;\n\n    function f() public returns (uint256) {\n        s.libFun();\n        L.libFun(s);\n        return s.v;\n    }\n}\n// ----\n// f() -> 0x202\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_library_inheritance.sol",
    "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n    struct S {\n        uint256 v;\n    }\n    modifier mod(S storage s) {\n        s.v++;\n        _;\n    }\n\n    function libFun(S storage s) internal mod(s) {\n        s.v += 0x100;\n    }\n}\n\n\ncontract Test {\n    using L for *;\n    L.S s;\n    modifier mod(L.S storage) {\n        revert();\n        _;\n    }\n\n    function f() public returns (uint256) {\n        s.libFun();\n        L.libFun(s);\n        return s.v;\n    }\n}\n// ----\n// f() -> 0x202\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_local_variables.sol",
    "content": "contract C {\n    modifier mod1 {\n        uint8 a = 1;\n        uint8 b = 2;\n        _;\n    }\n    modifier mod2(bool a) {\n        if (a) return;\n        else _;\n    }\n\n    function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n        return 3;\n    }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_loop.sol",
    "content": "contract C {\n    modifier repeat(uint256 count) {\n        uint256 i;\n        for (i = 0; i < count; ++i) _;\n    }\n\n    function f() public repeat(10) returns (uint256 r) {\n        r += 1;\n    }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f() -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_loop_viair.sol",
    "content": "contract C {\n    modifier repeat(uint256 count) {\n        uint256 i;\n        for (i = 0; i < count; ++i) _;\n    }\n\n    function f() public repeat(10) returns (uint256 r) {\n        r += 1;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_multi_invocation.sol",
    "content": "contract C {\n    modifier repeat(bool twice) {\n        if (twice) _;\n        _;\n    }\n\n    function f(bool twice) public repeat(twice) returns (uint256 r) {\n        r += 1;\n    }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_multi_invocation_viair.sol",
    "content": "contract C {\n    modifier repeat(bool twice) {\n        if (twice) _;\n        _;\n    }\n\n    function f(bool twice) public repeat(twice) returns (uint256 r) {\n        r += 1;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_multi_with_return.sol",
    "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n    modifier repeat(bool twice) {\n        if (twice) _;\n        _;\n    }\n\n    function f(bool twice) public repeat(twice) returns (uint256 r) {\n        r += 1;\n        return r;\n    }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_multiple_times.sol",
    "content": "contract C {\n    uint256 public a;\n    modifier mod(uint256 x) {\n        a += x;\n        _;\n    }\n\n    function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n        return a;\n    }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_multiple_times_local_vars.sol",
    "content": "contract C {\n    uint256 public a;\n    modifier mod(uint256 x) {\n        uint256 b = x;\n        a += b;\n        _;\n        a -= b;\n        assert(b == x);\n    }\n\n    function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n        return a;\n    }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_overriding.sol",
    "content": "contract A {\n    function f() public mod returns (bool r) {\n        return true;\n    }\n\n    modifier mod virtual {\n        _;\n    }\n}\n\n\ncontract C is A {\n    modifier mod override {\n        if (false) _;\n    }\n}\n// ----\n// f() -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_modifier_return_reference.sol",
    "content": "contract C {\n    modifier m1(uint value) {\n        _;\n    }\n    modifier m2(uint value) {\n        _;\n    }\n\n    function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n    }\n}\n// ----\n// f() -> 2, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_return_parameter.sol",
    "content": "// The IR of this contract used to throw\ncontract B {\n    function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n    modifier mod1(uint a, bool b) { if (b) _; }\n    modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/function_return_parameter_complex.sol",
    "content": "// Test to see if the function return parameter, when forwarded to the modifier actually has value\n// zero.\ncontract A {\n    uint public x = 0;\n\n    modifier alwaysZeros(uint256 a, uint256 b) {\n        x++;\n        _;\n        require(a == 0, \"a is not zero\");\n        require(b == 0, \"b is not zero\");\n    }\n\n    function f() public alwaysZeros(r1, r3) returns(uint r1, uint r2, uint r3) {\n        r1 = 16;\n        r2 = 32;\n        r3 = 64;\n    }\n\n    function shouldFail(uint i1) public alwaysZeros(i1, r + 20) returns (uint r) {\n        r = 0;\n    }\n\n    // The value of x would be 1 before calling this. It gets incremented four times in total during\n    // the modifier calls\n    function g() alwaysZeros(r, r) alwaysZeros(r, r) alwaysZeros(r + r, r - r) alwaysZeros(r * r, r & r) public returns (uint r) {\n        r = x;\n    }\n}\n// ----\n// f() -> 0x10, 0x20, 0x40\n// x() -> 1\n// shouldFail(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"a is not zero\"\n// shouldFail(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"b is not zero\"\n// x() -> 1\n// g() -> 5\n// x() -> 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/modifer_recursive.sol",
    "content": "contract C {\n    uint public called;\n    modifier mod1 {\n        called++;\n        _;\n    }\n    function f(uint x) public mod1 returns (uint256 r) {\n        return x == 0 ? 2 : f(x - 1)**2;\n    }\n}\n// ----\n// called() -> 0x00\n// f(uint256): 5 -> 0x0100000000\n// called() -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/modifier_in_constructor_ice.sol",
    "content": "// The IR of this contract used to throw\ncontract A { modifier m1{_;} }\ncontract B is A { constructor() A() m1{} }\n// ----\n// constructor() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/modifier_init_return.sol",
    "content": "contract C {\n    modifier m(bool condition) {\n        if (condition) _;\n    }\n\n    function f(uint x) public m(x >= 10) returns (uint[5] memory r) {\n        r[2] = 3;\n    }\n}\n// ----\n// f(uint256): 9 -> 0x00, 0x00, 0x00, 0x00, 0x00\n// f(uint256): 10 -> 0x00, 0x00, 3, 0x00, 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/modifiers_in_construction_context.sol",
    "content": "// The IR of this contract used to throw\ncontract A {\n  constructor() m1 { }\n  modifier m1 { _; }\n}\ncontract B is A {\n  modifier m2 { _; }\n  constructor() A() m1 m2 {  }\n}\n// ----\n// constructor() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/return_does_not_skip_modifier.sol",
    "content": "contract C {\n    uint256 public x;\n    modifier setsx {\n        _;\n        x = 9;\n    }\n\n    function f() public setsx returns (uint256) {\n        return 2;\n    }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/return_in_modifier.sol",
    "content": "contract C {\n    uint256 public x;\n    modifier run() {\n        for (uint256 i = 1; i < 10; i++) {\n            if (i == 5) return;\n            _;\n        }\n    }\n\n    function f() public run {\n        uint256 k = x;\n        uint256 t = k + 1;\n        x = t;\n    }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/stacked_return_with_modifiers.sol",
    "content": "contract C {\n    uint256 public x;\n    modifier m() {\n        for (uint256 i = 0; i < 10; i++) {\n            _;\n            ++x;\n            return;\n        }\n    }\n\n    function f() public m m m returns (uint) {\n        for (uint256 i = 0; i < 10; i++) {\n            ++x;\n            return 42;\n        }\n    }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/modifiers/transient_state_variable_value_type.sol",
    "content": "contract C {\n    uint16 transient x;\n\n    modifier m(uint16) {\n        x += 10;\n        _;\n    }\n\n    function f() public m(x) returns (uint16) {\n        x *= 10;\n        return x;\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/circular_import.sol",
    "content": "==== Source: s1.sol ====\nimport {f as g} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\ncontract C {\n  function foo() public pure returns (uint) {\n    return f() - g();\n  }\n}\n// ----\n// foo() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/circular_import_2.sol",
    "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n  function foo() public pure returns (uint) {\n    return h() - f() - g();\n  }\n}\n// ----\n// foo() -> 992\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/circular_reimport.sol",
    "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n  function foo() public pure returns (uint) {\n    return f() - g() - h();\n  }\n}\n// ----\n// foo() -> 0x60\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/circular_reimport_2.sol",
    "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract C {\n  function foo() public pure returns (uint) {\n    return 10000 + f() - g() - h();\n  }\n}\n// ----\n// foo() -> 0x2324\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/free_different_interger_types.sol",
    "content": "==== Source: s1.sol ====\nfunction f(uint24) pure returns (uint) { return 24; }\nfunction g(bool) pure returns (bool) { return true; }\n==== Source: s2.sol ====\nimport {f as g, g as g} from \"s1.sol\";\ncontract C {\n  function foo() public pure returns (uint, bool) {\n    return (g(2), g(false));\n  }\n}\n// ----\n// foo() -> 24, true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/free_function_resolution_base_contract.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n  function g() public pure returns (uint) {\n    return f();\n  }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n  function h() public pure returns (uint) {\n    return g();\n  }\n}\n// ----\n// h() -> 1337\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/free_function_resolution_override_virtual.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n  function g() public pure virtual returns (uint) {\n    return f() + 1;\n  }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n  function g() public pure override returns (uint) {\n    return f();\n  }\n}\n// ----\n// g() -> 1337\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/free_function_resolution_override_virtual_super.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n  function g() public pure virtual returns (uint) {\n    return f();\n  }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n  function g() public pure override returns (uint) {\n    return super.g();\n  }\n}\n// ----\n// g() -> 1337\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/free_function_resolution_override_virtual_transitive.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n  function g() public pure virtual returns (uint) {\n    return f();\n  }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n  function g() public pure virtual override returns (uint) {\n    return super.g() + 1;\n  }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract E is D {\n  function g() public pure override returns (uint) {\n    return super.g() + 1;\n  }\n}\n// ----\n// g() -> 1339\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/free_function_transitive_import.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n  function g() public pure returns (uint) {\n    return f();\n  }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n  function h() public pure returns (uint) {\n    return g();\n  }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n  function i() public pure returns (uint) {\n    return f();\n  }\n}\n// ----\n// i() -> 1337\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/import.sol",
    "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/import_overloaded_function.sol",
    "content": "==== Source: A ====\nfunction sub(uint256 x, uint256 y) pure returns (uint) { return 1; }\nfunction sub(uint256 x) pure returns (uint) { return 2; }\n==== Source: B ====\nimport {sub} from \"A\";\ncontract C\n{\n    function f() public pure returns (uint, uint) {\n        return (sub(1, 2), sub(2));\n    }\n}\n// ----\n// f() -> 1, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/imported_free_function_via_alias.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n  function g() public pure virtual returns (uint) {\n    return f();\n  }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\" as M;\nfunction f() pure returns (uint) { return 6; }\ncontract D is M.C {\n  function g() public pure override returns (uint) {\n    return super.g() + f() * 10000;\n  }\n}\n// ----\n// g() -> 61337\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/imported_free_function_via_alias_direct_call.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\nfunction f() pure returns (uint) { return 6; }\ncontract D {\n  function h() public pure returns (uint) {\n    return g() + f() * 10000;\n  }\n}\n// ----\n// h() -> 61337\n"
  },
  {
    "path": "test/libsolidity/semanticTests/multiSource/reimport_imported_function.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\n==== Source: s3.sol ====\nimport {g as h} from \"s2.sol\";\ncontract C {\n  function foo() public pure returns (uint) {\n    return h();\n  }\n}\n// ----\n// foo() -> 1337\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/compound_assign.sol",
    "content": "contract test {\n\tuint value1;\n\tuint value2;\n\tfunction f(uint x, uint y) public returns (uint w) {\n\t\tuint value3 = y;\n\t\tvalue1 += x;\n\t\tvalue3 *= x;\n\t\tvalue2 *= value3 + value1;\n\t\treturn value2 += 7;\n\t}\n}\n// ----\n// f(uint256,uint256): 0, 6 -> 7\n// f(uint256,uint256): 1, 3 -> 0x23\n// f(uint256,uint256): 2, 25 -> 0x0746\n// f(uint256,uint256): 3, 69 -> 396613\n// f(uint256,uint256): 4, 84 -> 137228105\n// f(uint256,uint256): 5, 2 -> 0xcc7c5e28\n// f(uint256,uint256): 6, 51 -> 1121839760671\n// f(uint256,uint256): 7, 48 -> 408349672884251\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/compound_assign_transient_storage.sol",
    "content": "contract test {\n\tuint value1;\n\tuint transient value2;\n\tfunction f(uint x, uint y) public returns (uint w) {\n\t\tuint value3 = y;\n\t\tvalue1 += x;\n\t\tvalue3 *= x;\n\t\tvalue2 += value3 + value1;\n\t\treturn value2 += 7;\n\t}\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(uint256,uint256): 0, 6 -> 7\n// f(uint256,uint256): 1, 3 -> 11\n// f(uint256,uint256): 2, 25 -> 0x3c\n// f(uint256,uint256): 3, 69 -> 0xdc\n// f(uint256,uint256): 4, 84 -> 353\n// f(uint256,uint256): 5, 2 -> 0x20\n// f(uint256,uint256): 6, 51 -> 334\n// f(uint256,uint256): 7, 48 -> 371\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/bitwise_shifting_constantinople.sol",
    "content": "contract C {\n    function shl(uint256 a, uint256 b) public returns (uint256 c) {\n        assembly {\n            c := shl(b, a)\n        }\n    }\n\n    function shr(uint256 a, uint256 b) public returns (uint256 c) {\n        assembly {\n            c := shr(b, a)\n        }\n    }\n\n    function sar(uint256 a, uint256 b) public returns (uint256 c) {\n        assembly {\n            c := sar(b, a)\n        }\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/bitwise_shifting_constantinople_combined.sol",
    "content": "contract C {\n    function shl_zero(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := shl(0, a)\n        }\n    }\n\n    function shr_zero(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := shr(0, a)\n        }\n    }\n\n    function sar_zero(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := sar(0, a)\n        }\n    }\n\n    function shl_large(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := shl(0x110, a)\n        }\n    }\n\n    function shr_large(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := shr(0x110, a)\n        }\n    }\n\n    function sar_large(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := sar(0x110, a)\n        }\n    }\n\n    function shl_combined(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := shl(4, shl(12, a))\n        }\n    }\n\n    function shr_combined(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := shr(4, shr(12, a))\n        }\n    }\n\n    function sar_combined(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := sar(4, sar(12, a))\n        }\n    }\n\n    function shl_combined_large(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := shl(0xd0, shl(0x40, a))\n        }\n    }\n\n    function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := shl(0x01, shl(not(0x00), a))\n        }\n    }\n\n    function shr_combined_large(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := shr(0xd0, shr(0x40, a))\n        }\n    }\n\n    function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := shr(0x01, shr(not(0x00), a))\n        }\n    }\n\n    function sar_combined_large(uint256 a) public returns (uint256 c) {\n        assembly {\n            c := sar(0xd0, sar(0x40, a))\n        }\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/bitwise_shifting_constants_constantinople.sol",
    "content": "contract C {\n    function shl_1() public returns (bool) {\n        uint256 c;\n        assembly {\n            c := shl(2, 1)\n        }\n        assert(c == 4);\n        return true;\n    }\n\n    function shl_2() public returns (bool) {\n        uint256 c;\n        assembly {\n            c := shl(\n                1,\n                0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n            )\n        }\n        assert(\n            c ==\n                0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n        );\n        return true;\n    }\n\n    function shl_3() public returns (bool) {\n        uint256 c;\n        assembly {\n            c := shl(\n                256,\n                0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n            )\n        }\n        assert(c == 0);\n        return true;\n    }\n\n    function shr_1() public returns (bool) {\n        uint256 c;\n        assembly {\n            c := shr(1, 3)\n        }\n        assert(c == 1);\n        return true;\n    }\n\n    function shr_2() public returns (bool) {\n        uint256 c;\n        assembly {\n            c := shr(\n                1,\n                0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n            )\n        }\n        assert(\n            c ==\n                0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n        );\n        return true;\n    }\n\n    function shr_3() public returns (bool) {\n        uint256 c;\n        assembly {\n            c := shr(\n                256,\n                0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n            )\n        }\n        assert(c == 0);\n        return true;\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_bytes_cleanup.sol",
    "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_bytes_cleanup_viaYul.sol",
    "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_cleanup.sol",
    "content": "contract C {\n    function f() public returns (uint16 x) {\n        unchecked {\n            x = 0xffff;\n            x += 32;\n            x <<= 8;\n            x >>= 16;\n        }\n    }\n}\n// ----\n// f() -> 0x0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_cleanup_garbled.sol",
    "content": "contract C {\n    function f() public returns (uint8 x) {\n        assembly {\n            x := 0xffff\n        }\n        x >>= 8;\n    }\n}\n// ----\n// f() -> 0x0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_constant_left.sol",
    "content": "contract C {\n    uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_constant_left_assignment.sol",
    "content": "contract C {\n    function f() public returns (uint256 a) {\n        a = 0x42;\n        a <<= 8;\n    }\n}\n// ----\n// f() -> 0x4200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_constant_right.sol",
    "content": "contract C {\n    uint256 public a = 0x4200 >> 8;\n}\n// ----\n// a() -> 0x42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_constant_right_assignment.sol",
    "content": "contract C {\n    function f() public returns (uint256 a) {\n        a = 0x4200;\n        a >>= 8;\n    }\n}\n// ----\n// f() -> 0x42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_left.sol",
    "content": "contract C {\n    function f(uint256 a, uint256 b) public returns (uint256) {\n        return a << b;\n    }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_left_assignment.sol",
    "content": "contract C {\n    function f(uint256 a, uint256 b) public returns (uint256) {\n        a <<= b;\n        return a;\n    }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_left_assignment_different_type.sol",
    "content": "contract C {\n    function f(uint256 a, uint8 b) public returns (uint256) {\n        a <<= b;\n        return a;\n    }\n}\n// ----\n// f(uint256,uint8): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint8): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint8): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint8): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint8): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_left_larger_type.sol",
    "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n    function f() public returns (int8) {\n        uint8 x = 254;\n        int8 y = 1;\n        return y << x;\n    }\n}\n// ----\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_left_uint32.sol",
    "content": "contract C {\n    function f(uint32 a, uint32 b) public returns (uint256) {\n        return a << b;\n    }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_left_uint8.sol",
    "content": "contract C {\n    function f(uint8 a, uint8 b) public returns (uint256) {\n        return a << b;\n    }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_negative_constant_left.sol",
    "content": "contract C {\n    int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_negative_constant_right.sol",
    "content": "contract C {\n    int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_overflow.sol",
    "content": "contract C {\n    function leftU(uint8 x, uint8 y) public returns (uint8) {\n        return x << y;\n    }\n\n    function leftS(int8 x, uint8 y) public returns (int8) {\n        return x << y;\n    }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right.sol",
    "content": "contract C {\n    function f(uint256 a, uint256 b) public returns (uint256) {\n        return a >> b;\n    }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_assignment.sol",
    "content": "contract C {\n    function f(uint256 a, uint256 b) public returns (uint256) {\n        a >>= b;\n        return a;\n    }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_garbled_signed_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f(int8 a, uint8 b) public returns (int256) {\n        assembly {\n            a := 0xfffffff0\n        }\n        // Higher bits should be signextended before the shift\n        return a >> b;\n    }\n\n    function g(int8 a, uint8 b) public returns (int256) {\n        assembly {\n            a := 0xf0\n        }\n        // Higher bits should be signextended before the shift\n        return a >> b;\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// f(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0x1003 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// f(int8,uint8): 0x00, 0x1004 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// g(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0x1003 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// g(int8,uint8): 0x00, 0x1004 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_garbled_signed_v2.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(int8 a, uint8 b) public returns (int256) {\n        assembly {\n            a := 0xfffffff0\n        }\n        // Higher bits should be signextended before the shift\n        return a >> b;\n    }\n\n    function g(int8 a, uint8 b) public returns (int256) {\n        assembly {\n            a := 0xf0\n        }\n        // Higher bits should be signextended before the shift\n        return a >> b;\n    }\n}\n// ----\n// f(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// f(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0x1003 -> FAILURE\n// f(int8,uint8): 0x00, 0x1004 -> FAILURE\n// g(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// g(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0x1003 -> FAILURE\n// g(int8,uint8): 0x00, 0x1004 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_garbled_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f(uint8 a, uint8 b) public returns (uint256) {\n        assembly {\n            a := 0xffffffff\n        }\n        // Higher bits should be cleared before the shift\n        return a >> b;\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_garbled_v2.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(uint8 a, uint8 b) public returns (uint256) {\n        assembly {\n            a := 0xffffffff\n        }\n        // Higher bits should be cleared before the shift\n        return a >> b;\n    }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_literal.sol",
    "content": "contract C {\n    function f1() public pure returns (bool) {\n        return (-4266 >> 0) == -4266;\n    }\n\n    function f2() public pure returns (bool) {\n        return (-4266 >> 1) == -2133;\n    }\n\n    function f3() public pure returns (bool) {\n        return (-4266 >> 4) == -267;\n    }\n\n    function f4() public pure returns (bool) {\n        return (-4266 >> 8) == -17;\n    }\n\n    function f5() public pure returns (bool) {\n        return (-4266 >> 16) == -1;\n    }\n\n    function f6() public pure returns (bool) {\n        return (-4266 >> 17) == -1;\n    }\n\n    function g1() public pure returns (bool) {\n        return (-4267 >> 0) == -4267;\n    }\n\n    function g2() public pure returns (bool) {\n        return (-4267 >> 1) == -2134;\n    }\n\n    function g3() public pure returns (bool) {\n        return (-4267 >> 4) == -267;\n    }\n\n    function g4() public pure returns (bool) {\n        return (-4267 >> 8) == -17;\n    }\n\n    function g5() public pure returns (bool) {\n        return (-4267 >> 16) == -1;\n    }\n\n    function g6() public pure returns (bool) {\n        return (-4267 >> 17) == -1;\n    }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_lvalue.sol",
    "content": "contract C {\n    function f(int256 a, uint256 b) public returns (int256) {\n        return a >> b;\n    }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_lvalue_assignment.sol",
    "content": "contract C {\n    function f(int256 a, uint256 b) public returns (int256) {\n        a >>= b;\n        return a;\n    }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_lvalue_int16.sol",
    "content": "contract C {\n    function f(int16 a, uint16 b) public returns (int256) {\n        return a >> b;\n    }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_lvalue_int32.sol",
    "content": "contract C {\n    function f(int32 a, uint32 b) public returns (int256) {\n        return a >> b;\n    }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_lvalue_int8.sol",
    "content": "contract C {\n    function f(int8 a, uint8 b) public returns (int256) {\n        return a >> b;\n    }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_lvalue_signextend_int16_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f(int16 a, uint16 b) public returns (int16) {\n        return a >> b;\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_lvalue_signextend_int16_v2.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(int16 a, uint16 b) public returns (int16) {\n        return a >> b;\n    }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_lvalue_signextend_int32_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f(int32 a, uint32 b) public returns (int32) {\n        return a >> b;\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_lvalue_signextend_int32_v2.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(int32 a, uint32 b) public returns (int32) {\n        return a >> b;\n    }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_lvalue_signextend_int8_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f(int8 a, uint8 b) public returns (int8) {\n        return a >> b;\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int8,uint8): 0x99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int8,uint8): 0x99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int8,uint8): 0x99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int8,uint8): 0x99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int8,uint8): 0x99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_negative_lvalue_signextend_int8_v2.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    function f(int8 a, uint8 b) public returns (int8) {\n        return a >> b;\n    }\n}\n// ----\n// f(int8,uint8): 0x99, 0x00 -> FAILURE\n// f(int8,uint8): 0x99, 0x01 -> FAILURE\n// f(int8,uint8): 0x99, 0x02 -> FAILURE\n// f(int8,uint8): 0x99, 0x04 -> FAILURE\n// f(int8,uint8): 0x99, 0x08 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_uint32.sol",
    "content": "contract C {\n    function f(uint32 a, uint32 b) public returns (uint256) {\n        return a >> b;\n    }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_right_uint8.sol",
    "content": "contract C {\n    function f(uint8 a, uint8 b) public returns (uint256) {\n        return a >> b;\n    }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shift_underflow_negative_rvalue.sol",
    "content": "contract C {\n    function f(int256 a, uint256 b) public returns (int256) {\n        return a << b;\n    }\n\n    function g(int256 a, uint256 b) public returns (int256) {\n        return a >> b;\n    }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/shifts/shifts.sol",
    "content": "contract C {\n    function f(uint x) public returns (uint y) {\n        assembly { y := shl(2, x) }\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/transient_storage_variable_increment_decrement.sol",
    "content": "contract C {\n    int transient x;\n    function f() public returns (int) {\n        ++x;\n        ++x;\n        --x;\n        x++;\n        x--;\n        return x;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/all_possible_operators.sol",
    "content": "type Int is int8;\nusing {\n    bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n    add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n    eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n    Int constant ZERO = Int.wrap(0);\n    Int constant ONE = Int.wrap(1);\n    Int constant TWO = Int.wrap(2);\n    Int constant THREE = Int.wrap(3);\n    Int constant SIX = Int.wrap(6);\n\n    function testBitwise() public pure {\n        assert(Int.unwrap(ONE | TWO) == 3);\n        assert(Int.unwrap(ONE | ZERO) == 1);\n\n        assert(Int.unwrap(ONE & THREE) == 1);\n        assert(Int.unwrap(ONE & ONE) == 1);\n\n        assert(Int.unwrap(TWO ^ TWO) == 0);\n        assert(Int.unwrap(TWO ^ ONE) == 3);\n\n        assert(Int.unwrap(~ZERO) == -1);\n        assert(Int.unwrap(~ONE) == -2);\n        assert(Int.unwrap(~TWO) == -3);\n    }\n\n    function testArithmetic() public pure {\n        assert(Int.unwrap(ONE + TWO) == 3);\n        assert(Int.unwrap(ONE + ZERO) == 1);\n\n        assert(Int.unwrap(TWO - ONE) == 1);\n        assert(Int.unwrap(THREE - THREE) == 0);\n\n        assert(Int.unwrap(-TWO) == -2);\n        assert(Int.unwrap(-ZERO) == 0);\n\n        assert(Int.unwrap(ONE * ONE) == 1);\n        assert(Int.unwrap(THREE * TWO) == 6);\n\n        assert(Int.unwrap(SIX / TWO) == 3);\n        assert(Int.unwrap(THREE / TWO) == 1);\n\n        assert(Int.unwrap(SIX % TWO) == 0);\n        assert(Int.unwrap(THREE % TWO) == 1);\n    }\n\n    function testComparison() public pure {\n        assert((ONE == ONE) == true);\n        assert((ONE == TWO) == false);\n\n        assert((ONE != ONE) == false);\n        assert((ONE != TWO) == true);\n\n        assert((ONE < TWO) == true);\n        assert((TWO < ONE) == false);\n\n        assert((ONE <= TWO) == true);\n        assert((TWO <= ONE) == false);\n\n        assert((ONE > TWO) == false);\n        assert((TWO > ONE) == true);\n\n        assert((ONE >= TWO) == false);\n        assert((TWO >= ONE) == true);\n    }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/all_possible_user_defined_value_types_with_operators.sol",
    "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n    return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n    return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n    return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n    return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n    return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n    return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n    function testIntBinary() public pure {\n        assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n        assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n        assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n        assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n        assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n        assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n        assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n        assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n        assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n        assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n        assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n        assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n        assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n        assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n        assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n        assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n        assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n        assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n        assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n        assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n        assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n        assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n        assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n        assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n        assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n        assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n        assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n        assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n        assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n        assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n        assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n        assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n        assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n    }\n\n    function testIntUnary() public pure {\n        assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n        assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n        assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n        assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n        assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n        assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n        assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n        assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n        assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n        assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n        assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n        assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n        assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n        assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n        assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n        assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n        assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n        assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n        assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n        assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n        assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n        assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n        assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n        assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n        assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n        assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n        assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n        assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n        assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n        assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n        assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n        assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n        assert(Int.unwrap(-Int.wrap(1)) == -1);\n    }\n\n    function testUintBinary() public pure {\n        assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n        assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n        assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n        assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n        assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n        assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n        assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n        assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n        assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n        assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n        assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n        assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n        assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n        assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n        assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n        assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n        assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n        assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n        assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n        assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n        assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n        assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n        assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n        assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n        assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n        assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n        assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n        assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n        assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n        assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n        assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n        assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n        assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n    }\n\n    function testUintUnary() public pure {\n        assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n        assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n        assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n        assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n        assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n        assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n        assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n        assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n        assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n        assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n        assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n        assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n        assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n        assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n        assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n        assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n        assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n        assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n        assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n        assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n        assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n        assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n        assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n        assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n        assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n        assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n        assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n        assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n        assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n        assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n        assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n        assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n        assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n    }\n\n    function testBytesBinary() public pure {\n        assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n        assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n        assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n        assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n        assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n        assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n        assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n        assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n        assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n        assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n        assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n        assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n        assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n        assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n        assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n        assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n        assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n        assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n        assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n        assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n        assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n        assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n        assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n        assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n        assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n        assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n        assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n        assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n        assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n        assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n        assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n        assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n    }\n\n    function testBytesUnary() public pure {\n        assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n        assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n        assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n        assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n        assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n        assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n        assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n        assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n        assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n        assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n        assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n        assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n        assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n        assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n        assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n        assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n        assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n        assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n        assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n        assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n        assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n        assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n        assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n        assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n        assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n        assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n        assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n        assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n        assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n        assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n        assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n        assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n    }\n\n    function testOtherBinary() public pure {\n        assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n        assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n        assert(Bool.unwrap(~Bool.wrap(true)) == false);\n    }\n\n    function testOtherUnary() public pure {\n        assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n        assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n        assert(Bool.unwrap(~Bool.wrap(true)) == false);\n    }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/attaching_and_defining_operator_with_same_function.sol",
    "content": "type Int is int16;\n\nusing {add as +, add} for Int global;\n\nfunction add(Int _a, Int _b) pure returns (Int) {\n    return Int.wrap(Int.unwrap(_a) + Int.unwrap(_b));\n}\n\ncontract C {\n    function f() pure public returns (Int) {\n        return Int.wrap(5) + Int.wrap(5);\n    }\n\n    function g() pure public returns (Int) {\n        return Int.wrap(7).add(Int.wrap(6));\n    }\n}\n// ----\n// f() -> 10\n// g() -> 13\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/checked_operators.sol",
    "content": "type U8 is uint8;\n\nfunction checkedAdd(U8 x, U8 y) pure returns (U8) {\n    return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n}\n\nusing {checkedAdd as +} for U8 global;\n\ncontract C {\n    function testCheckedOperator() public pure returns (U8) {\n        return U8.wrap(250) + U8.wrap(10);\n    }\n\n    function testCheckedOperatorInUncheckedBlock() public pure returns (U8) {\n        unchecked {\n            return U8.wrap(250) + U8.wrap(10);\n        }\n    }\n}\n// ----\n// testCheckedOperator() -> FAILURE, hex\"4e487b71\", 0x11\n// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/consecutive_operator_invocations.sol",
    "content": "type A is address;\n\nusing {add as +} for A global;\n\nfunction add(A a, A b) pure returns (A) {\n    return A.wrap(address(uint160(A.unwrap(a)) + uint160(A.unwrap(b))));\n}\n\ncontract C {\n    function g() public pure returns (A) {\n        A a = A.wrap(0x3333333333333333333333333333333333333333);\n        A b = A.wrap(0x1111111111111111111111111111111111111111);\n        A c = A.wrap(0x5555555555555555555555555555555555555555);\n        return a + b + c;\n    }\n}\n// ----\n// g() -> 0x9999999999999999999999999999999999999999\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/fixed_point_udvt_with_operators.sol",
    "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n    return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n    int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n    if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n    return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n    function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n        return value + value * percentage;\n    }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/multiple_operator_definitions_different_types_different_functions_separate_directives.sol",
    "content": "type SmallInt is int;\ntype BigInt is int;\n\nusing {addSmall as +} for SmallInt global;\nusing {addBig as +} for BigInt global;\n\nfunction addSmall(SmallInt a, SmallInt b) pure returns (SmallInt) {\n    return SmallInt.wrap(SmallInt.unwrap(a) + SmallInt.unwrap(b));\n}\n\nfunction addBig(BigInt a, BigInt b) pure returns (BigInt) {\n    return BigInt.wrap(10 * (BigInt.unwrap(a) + BigInt.unwrap(b)));\n}\n\ncontract C {\n    function small() public pure returns (SmallInt) {\n        return SmallInt.wrap(1) + SmallInt.wrap(2);\n    }\n\n    function big() public pure returns (BigInt) {\n        return BigInt.wrap(3) + BigInt.wrap(4);\n    }\n}\n// ----\n// small() -> 3\n// big() -> 70\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/multiple_operator_definitions_same_type_same_function_same_directive.sol",
    "content": "type Int is int32;\n\nusing {foo as +, foo as -} for Int global;\n\nfunction foo(Int a, Int b) pure returns(Int) {\n    return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n    function f() pure public returns (Int) {\n        return Int.wrap(2) + Int.wrap(3);\n    }\n\n    function g() pure public returns (Int) {\n        return Int.wrap(6) - Int.wrap(1);\n    }\n}\n// ----\n// f() -> 5\n// g() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/operator_definition_shadowing_builtin_keccak256.sol",
    "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n    return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n    function test() public returns (Int) {\n        return Int.wrap(3) + Int.wrap(4);\n    }\n}\n// ----\n// test() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/operator_evaluation_order.sol",
    "content": "type Bool is bool;\nusing {add as +, mul as *, unsub as -} for Bool global;\n\nfunction add(Bool x, Bool y) pure returns (Bool) {\n    return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\n\nfunction mul(Bool x, Bool y) pure returns (Bool) {\n    return Bool.wrap(Bool.unwrap(x) && Bool.unwrap(y));\n}\n\nfunction unsub(Bool x) pure returns (Bool) {\n    return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n    event Wrapped(uint);\n    event Probe(Bool);\n\n    function toBool(uint x) public returns (Bool) {\n        emit Wrapped(x);\n        return Bool.wrap(x > 0);\n    }\n\n    function probe(Bool x) public returns (Bool) {\n        emit Probe(x);\n        return x;\n    }\n\n    function testSingleOperator() public {\n        toBool(0) +\n        (toBool(1) + toBool(2)) +\n        toBool(3);\n    }\n\n    function testTwoBinaryOperators() public {\n        toBool(0) * toBool(1) +\n        (toBool(2) * toBool(3)) +\n        toBool(4) * toBool(5);\n    }\n\n    function testBinaryAndUnaryOperators() public {\n        -toBool(0) * -toBool(1) +\n        (-toBool(2) * -toBool(3)) +\n        -toBool(4) * -toBool(5);\n    }\n\n    function testOperatorsNestedInCalls() public {\n        -probe(toBool(0) * -toBool(1)) +\n        (-probe(toBool(2) * -toBool(3))) +\n        -probe(toBool(4) * -toBool(5));\n    }\n}\n// ----\n// testSingleOperator() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// testTwoBinaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testBinaryAndUnaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testOperatorsNestedInCalls() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// ~ emit Probe(bool): 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol",
    "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n    return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n    return loadAdder().inc(x);\n}\n\ninterface IAdder {\n    function mul(Int32, Int32) external pure returns (Int32);\n    function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n    function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n        return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n    }\n\n    function inc(Int32 x) external pure override returns (Int32) {\n        return Int32.wrap(Int32.unwrap(x) + 1);\n    }\n}\n\nfunction storeAdder(IAdder adder) pure {\n    assembly {\n        // This test would also work without assembly if we could hard-code an address here.\n        mstore(0, adder)\n    }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n    assembly {\n        adder := mload(0)\n    }\n}\n\ncontract C {\n    function testMul(Int32 x, Int32 y) public returns (Int32) {\n        storeAdder(new Adder{salt: hex\"00\"}());\n\n        return x + y;\n    }\n\n    function testInc(Int32 x) public returns (Int32) {\n        storeAdder(new Adder{salt: hex\"01\"}());\n\n        return -x;\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 54784\n// gas irOptimized code: 40600\n// gas legacy: 57117\n// gas legacy code: 127000\n// gas legacyOptimized: 55246\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 54621\n// gas irOptimized code: 40600\n// gas legacy: 56378\n// gas legacy code: 127000\n// gas legacyOptimized: 54943\n// gas legacyOptimized code: 68400\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol",
    "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n    return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n    return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n    function mul(Int32, Int32) external pure returns (Int32);\n    function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n    function mul(Int32, Int32) external view returns (Int32);\n    function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n    function mul(Int32 x, Int32 y) external view override returns (Int32) {\n        return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n    }\n\n    function inc(Int32 x) external view override returns (Int32) {\n        return Int32.wrap(Int32.unwrap(x) + 1);\n    }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n    assembly {\n        // This test would also work without assembly if we could hard-code an address here.\n        mstore(0, adder)\n    }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n    assembly {\n        // The adder we stored is view but we cheat by using a modified version with pure functions\n        adder := mload(0)\n    }\n}\n\ncontract C {\n    function testMul(Int32 x, Int32 y) public returns (Int32) {\n        storeAdder(new Adder{salt: hex\"00\"}());\n\n        return x + y;\n    }\n\n    function testInc(Int32 x) public returns (Int32) {\n        storeAdder(new Adder{salt: hex\"01\"}());\n\n        return -x;\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 54784\n// gas irOptimized code: 40600\n// gas legacy: 57117\n// gas legacy code: 127000\n// gas legacyOptimized: 55246\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 54621\n// gas irOptimized code: 40600\n// gas legacy: 56378\n// gas legacy code: 127000\n// gas legacyOptimized: 54943\n// gas legacyOptimized code: 68400\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/operator_parameter_and_return_cleanup_between_calls.sol",
    "content": "type U8 is uint8;\nusing {yoloAdd as +, yoloDiv as /} for U8 global;\n\nfunction yoloAdd(U8 x, U8 y) pure returns (U8 z) {\n    assembly {\n        z := add(x, y) // Wrong! No cleanup.\n    }\n}\n\nfunction yoloDiv(U8 x, U8 y) pure returns (U8 z) {\n    assembly {\n        z := div(x, y) // Wrong! No cleanup.\n    }\n}\n\ncontract C {\n    function divAddNoOverflow(U8 a, U8 b, U8 c) external pure returns (U8) {\n        return a / (b + c);\n    }\n}\n// ----\n// divAddNoOverflow(uint8,uint8,uint8): 4, 0xff, 3 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/operator_parameter_cleanup.sol",
    "content": "type U8 is uint8;\nusing {f as ~, add as +} for U8 global;\n\nfunction f(U8 x) pure returns (U8 z) {\n    assembly {\n        // NOTE: Not using shr so that the test works pre-constantinople too\n        z := div(x, 256)\n    }\n}\n\nfunction add(U8 x, U8 y) pure returns (U8 z) {\n    assembly {\n        z := add(div(x, 256), div(x, 256))\n    }\n}\n\ncontract C {\n    function testUnary() external pure returns (U8, U8) {\n        U8 a;\n        assembly {\n            a := 0x4200\n        }\n        // If the result is not 0, no cleanup was performed.\n        return (~a, f(a));\n    }\n\n    function testBinary() external pure returns (U8, U8) {\n        U8 a;\n        U8 b;\n        assembly {\n            a := 0x4200\n            b := 0x4200\n        }\n        // If the result is not 0, no cleanup was performed.\n        return (a + b, add(a, b));\n    }\n}\n// ----\n// testUnary() -> 0x42, 0x42\n// testBinary() -> 0x84, 0x84\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/operator_precendence.sol",
    "content": "type Int is int64;\nusing {\n    bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n    add as +, sub as -, unsub as -, mul as *, div as /, mod as %\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\ncontract C {\n    Int constant I0 = Int.wrap(0);\n    Int constant I1 = Int.wrap(1);\n    Int constant I2 = Int.wrap(2);\n    Int constant I3 = Int.wrap(3);\n    Int constant I4 = Int.wrap(4);\n    Int constant I5 = Int.wrap(5);\n    Int constant I6 = Int.wrap(6);\n    Int constant I7 = Int.wrap(7);\n    Int constant I8 = Int.wrap(8);\n    Int constant I10 = Int.wrap(10);\n    Int constant I13 = Int.wrap(13);\n    Int constant I15 = Int.wrap(15);\n    Int constant I20 = Int.wrap(20);\n    Int constant I128 = Int.wrap(128);\n\n    function testBitwise() public pure {\n        assert(Int.unwrap(I0 & I0 | I1) == (0 & 0 | 1));\n        assert(Int.unwrap(I0 & I0 | I1) == ((0 & 0) | 1));\n    }\n\n    function testBitwise_arithmetic() public pure {\n        assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (2 + 2 & ~1 | 6 * 6 - 4 & ~3));\n        assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (((2 + 2) & (~1)) | (((6 * 6) - 4) & (~3))));\n    }\n\n    function testArithmetic() public pure {\n        assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == (1 + 8 / 4 - 5 % 6 * 7));\n        assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == ((1 + (8 / 4)) - ((5 % 6) * 7)));\n    }\n\n    function testAll() public pure {\n        assert(\n            Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) ==\n            (128 + 1 - 10 + 4 & ~1 ^ ~1 * 2 | -15 % -10 * 20 / 2 + 13 & ~3)\n        );\n        assert(\n            Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) ==\n            (\n                (\n                    ((((128 + 1) - 10) + 4) & (~1)) ^\n                    ((~1) * 2)\n                ) |\n                ((((((-15) % (-10)) * 20) / 2) + 13) & (~3))\n            )\n        );\n    }\n}\n// ----\n// testBitwise() ->\n// testBitwise_arithmetic() ->\n// testArithmetic() ->\n// testAll() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/operator_return_parameter_cleanup.sol",
    "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n    assembly {\n        // Return a value with dirty bytes outside of uint8\n        z := 0xffff\n    }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n    assembly {\n        // Return a value with dirty bytes outside of uint8\n        z := 0xffff\n    }\n}\n\ncontract C {\n    function testUnary() external pure returns (uint, uint) {\n        U8 a; // Value does not matter\n\n        U8 opResult = ~a;\n        U8 fResult = f(a);\n\n        // Get the slot, including bytes outside of uint8\n        uint opResultFull;\n        uint fResultFull;\n        assembly {\n            opResultFull := opResult\n            fResultFull := fResult\n        }\n\n        // If the result is not 0xff, no cleanup was performed.\n        return (opResultFull, fResultFull);\n    }\n\n    function testBinary() external pure returns (uint, uint) {\n        U8 a; // Value does not matter\n        U8 b; // Value does not matter\n\n        U8 opResult = a + b;\n        U8 fResult = g(a, b);\n\n        // Get the slot, including bytes outside of uint8\n        uint opResultFull;\n        uint fResultFull;\n        assembly {\n            opResultFull := opResult\n            fResultFull := fResult\n        }\n\n        // If the result is not 0xff, no cleanup was performed.\n        return (opResultFull, fResultFull);\n    }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/recursive_operator.sol",
    "content": "type Uint is uint;\nusing {unaryCountdown as ~, binaryCountdown as ^, eq as ==} for Uint global;\n\nfunction unaryCountdown(Uint x) pure returns (Uint) {\n    if (x == Uint.wrap(0))\n        return Uint.wrap(0);\n\n    return ~Uint.wrap(Uint.unwrap(x) - 1);\n}\n\nfunction binaryCountdown(Uint x, Uint y) pure returns (Uint) {\n    if (x == Uint.wrap(0) && y == Uint.wrap(0))\n        return Uint.wrap(0);\n    if (x == Uint.wrap(0))\n        return y ^ x;\n\n    return Uint.wrap(Uint.unwrap(x) - 1) ^ y;\n}\n\nfunction eq(Uint x, Uint y) pure returns (bool) {\n    return Uint.unwrap(x) == Uint.unwrap(y);\n}\n\ncontract C {\n    function testUnary(Uint x) public pure returns (Uint) {\n        return ~x;\n    }\n\n    function testBinary(Uint x, Uint y) public pure returns (Uint) {\n        return x ^ y;\n    }\n}\n// ----\n// testUnary(uint256): 0 -> 0\n// testUnary(uint256): 1 -> 0\n// testUnary(uint256): 99999999999 -> FAILURE\n// testBinary(uint256,uint256): 0, 0 -> 0\n// testBinary(uint256,uint256): 1, 0 -> 0\n// testBinary(uint256,uint256): 0, 1 -> 0\n// testBinary(uint256,uint256): 1, 1 -> 0\n// testBinary(uint256,uint256): 99999999999, 99999999999 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/operators/userDefined/unchecked_operators.sol",
    "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n    unchecked {\n        return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n    }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n    function testUncheckedOperator() public pure returns (U8) {\n        return U8.wrap(250) + U8.wrap(10);\n    }\n\n    function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n        unchecked {\n            return U8.wrap(250) + U8.wrap(10);\n        }\n    }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/optimizer/shift_bytes.sol",
    "content": "// This tests the optimizer rule\n// byte(A, shl(B, X))\n// ->\n// byte(A + B / 8, X)\n// given A <= 32 && B % 8 == 0 && B <= 256\n//\n// and the respective rule about shr\ncontract C {\n  function f(uint a) public returns (uint, uint, uint) {\n    uint x = a << (256 - 8);\n    assembly {\n      x := byte(0, x)\n    }\n    uint y = a << 8;\n    assembly {\n      y := byte(30, y)\n    }\n    uint z = a << 16;\n    assembly {\n      z := byte(1, z)\n    }\n    return (x, y, z);\n  }\n  function g(uint a) public returns (uint, uint, uint) {\n    uint x = a >> (256 - 16);\n    assembly {\n      x := byte(31, x)\n    }\n    uint y = a >> 8;\n    assembly {\n      y := byte(4, y)\n    }\n    uint z = a >> 16;\n    assembly {\n      z := byte(7, z)\n    }\n    return (x, y, z);\n  }\n}\n// ----\n// f(uint256): 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f -> 0x1f, 0x1f, 3\n// g(uint256): 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f -> 1, 3, 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/optimizer/unused_store_storage_removal_bug.sol",
    "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/payable/no_nonpayable_circumvention_by_modifier.sol",
    "content": "contract C {\n    modifier tryCircumvent {\n        if (false) _; // avoid the function, we should still not accept ether\n    }\n    function f() tryCircumvent public returns (uint) {\n        return msgvalue();\n    }\n    function msgvalue() internal returns (uint) {\n        return msg.value;\n    }\n}\n// ----\n// f(), 27 wei -> FAILURE\n// balance -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/receive/empty_calldata_calls_receive.sol",
    "content": "contract A {\n    uint public x;\n    receive () external payable { ++x; }\n}\n// ----\n// x() -> 0\n// ()\n// x() -> 1\n// (), 1 wei\n// x() -> 2\n// x(), 1 wei -> FAILURE\n// (): hex\"00\" -> FAILURE\n// (), 1 ether: hex\"00\" -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/receive/ether_and_data.sol",
    "content": "contract C {\n    receive () payable external { }\n}\n// ----\n// (), 1 ether\n// (), 1 ether: 1 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/receive/inherited.sol",
    "content": "contract A {\n    uint data;\n    receive() external payable { ++data; }\n    function getData() public returns (uint r) { return data; }\n}\ncontract B is A {}\n// ----\n// getData() -> 0\n// () ->\n// getData() -> 1\n// (), 1 ether ->\n// getData() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/array_slices.sol",
    "content": "contract C {\n\tfunction f(uint256 start, uint256 end, uint256[] calldata arr) external pure {\n\t\tarr[start:end];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256,uint256[]): 2, 1, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 22, \"Slice starts after end\"\n// f(uint256,uint256,uint256[]): 1, 5, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Slice is greater than length\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/bubble.sol",
    "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/calldata_array_dynamic_invalid.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/calldata_array_dynamic_static_short_decode.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(uint256[][2][] calldata x) external returns (uint256) {\n        x[0];\n        return 23;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/calldata_array_dynamic_static_short_reencode.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(uint256[][2][] calldata x) external returns (uint256) {\n        return 42;\n    }\n    function g(uint256[][2][] calldata x) external returns (uint256) {\n        return this.f(x);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 30, \"Invalid calldata access offset\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/calldata_array_invalid_length.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n\tfunction f(uint256[][] calldata x) external returns (uint256) {\n\t\treturn x[0].length;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0x0100000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail length\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/calldata_arrays_too_large.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n\tfunction f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n\t\treturn 7;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray length\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/calldata_tail_short.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(uint256[][] calldata x) external { x[0]; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 2, 0x42 -> FAILURE, hex\"08c379a0\", 0x20, 23, \"Calldata tail too short\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/calldata_too_short_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/called_contract_has_code.sol",
    "content": "contract C {\n\tfunction f() external {}\n\tfunction g() external {\n\t\tC c = C(address(0x0000000000000000000000000000000000000000000000000000000000000000));\n\t\tc.f();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// bytecodeFormat: legacy\n// ----\n// g() -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/empty_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/empty_v2.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/enum_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/enum_v2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/ether_non_payable_function.sol",
    "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/function_entry_checks_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function t(uint) public pure {}\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// t(uint256) -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Calldata too short\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/function_entry_checks_v2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n    function t(uint) public pure {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// t(uint256) -> FAILURE, hex\"08c379a0\", 0x20, 34, \"ABI decoding: tuple data too sho\", \"rt\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/invalid_abi_decoding_calldata_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/invalid_abi_decoding_memory_v1.sol",
    "content": "pragma abicoder v1;\ncontract C {\n\tfunction dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {\n\t\tassembly {\n\t\t\tmstore(0, start)\n\t\t\tmstore(start, add(start, 1))\n\t\t\treturn(ptr, x)\n\t\t}\n\t}\n\tfunction f(uint ptr, uint start, uint x) public returns (bool) {\n\t\tthis.dyn(ptr, start, x);\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI memory decoding: invalid dat\", \"a start\"\n// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 40, \"ABI memory decoding: invalid dat\", \"a length\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/library_non_view_call.sol",
    "content": "library L {\n    function g() external {}\n}\ncontract C {\n    function f() public returns (bytes memory) {\n        (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/short_input_array.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n\tfunction f(uint[] memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/short_input_bytes.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/transfer.sol",
    "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/revertStrings/unknown_sig_no_fallback.sol",
    "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/reverts/assert_require.sol",
    "content": "contract C {\n    function f() public {\n        assert(false);\n    }\n\n    function g(bool val) public returns (bool) {\n        assert(val == true);\n        return true;\n    }\n\n    function h(bool val) public returns (bool) {\n        require(val);\n        return true;\n    }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x01\n// g(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// g(bool): true -> true\n// h(bool): false -> FAILURE\n// h(bool): true -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/reverts/eof/revert_return_area.sol",
    "content": "contract C {\n    fallback() external {\n        revert(\"abc\");\n    }\n\n    function f() public returns (uint s, uint r) {\n        address x = address(this);\n        assembly {\n            mstore(0, 7)\n            s := extcall(x, 0, 0, 0)\n            returndatacopy(0, 0, 32)\n            r := mload(0)\n        }\n    }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// f() -> 0x01, 0x08c379a000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/reverts/error_struct.sol",
    "content": "struct error { uint error; }\ncontract C {\n\terror test();\n\terror _struct;\n\tfunction f() public {\n\t\trevert test();\n\t}\n\tfunction g(uint x) public returns (uint) {\n\t\t_struct.error = x;\n\t\treturn _struct.error;\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"f8a8fd6d\"\n// g(uint256): 7 -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/reverts/invalid_enum_as_external_arg.sol",
    "content": "contract C {\n    enum X {A, B}\n\n    function tested(X x) public returns (uint256) {\n        return 1;\n    }\n\n    function test() public returns (uint256) {\n        X garbled;\n\n        assembly {\n            garbled := 5\n        }\n\n        return this.tested(garbled);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x21 # should throw #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/reverts/invalid_enum_as_external_ret.sol",
    "content": "contract C {\n    enum X {A, B}\n\n    function test_return() public returns (X) {\n        X garbled;\n        assembly {\n            garbled := 5\n        }\n        return garbled;\n    }\n\n    function test_inline_assignment() public returns (X _ret) {\n        assembly {\n            _ret := 5\n        }\n    }\n\n    function test_assignment() public returns (X _ret) {\n        X tmp;\n        assembly {\n            tmp := 5\n        }\n        _ret = tmp;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_return() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_inline_assignment() -> FAILURE, hex\"4e487b71\", 33\n// test_assignment() -> FAILURE, hex\"4e487b71\", 33\n"
  },
  {
    "path": "test/libsolidity/semanticTests/reverts/invalid_enum_compared.sol",
    "content": "contract C {\n    enum X {A, B}\n\n    function test_eq() public returns (bool) {\n        X garbled;\n        assembly {\n            garbled := 5\n        }\n        return garbled == garbled;\n    }\n\n    function test_eq_ok() public returns (bool) {\n        X garbled = X.A;\n        return garbled == garbled;\n    }\n\n    function test_neq() public returns (bool) {\n        X garbled;\n        assembly {\n            garbled := 5\n        }\n        return garbled != garbled;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_eq_ok() -> 1\n// test_eq() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_neq() -> FAILURE, hex\"4e487b71\", 33\n"
  },
  {
    "path": "test/libsolidity/semanticTests/reverts/invalid_enum_stored.sol",
    "content": "contract C {\n    enum X {A, B}\n    X public x;\n\n    function test_store() public returns (uint256) {\n        X garbled = X.A;\n        assembly {\n            garbled := 5\n        }\n        x = garbled;\n        return 1;\n    }\n\n    function test_store_ok() public returns (uint256) {\n        x = X.A;\n        return 1;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_store_ok() -> 1\n// x() -> 0\n// test_store() -> FAILURE, hex\"4e487b71\", 33 # should throw #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/reverts/invalid_instruction.sol",
    "content": "contract C {\n    function f() public {\n        assembly {\n            invalid()\n        }\n    }\n}\n// ----\n// f() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/reverts/revert.sol",
    "content": "contract C {\n    uint256 public a = 42;\n\n    function f() public {\n        a = 1;\n        revert();\n    }\n\n    function g() public {\n        a = 1;\n        assembly {\n            revert(0, 0)\n        }\n    }\n}\n// ----\n// f() -> FAILURE\n// a() -> 42\n// g() -> FAILURE\n// a() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/reverts/revert_return_area.sol",
    "content": "contract C {\n    fallback() external {\n        revert(\"abc\");\n    }\n\n    function f() public returns (uint s, uint r) {\n        address x = address(this);\n        assembly {\n            mstore(0, 7)\n            s := call(sub(0, 1), x, 0, 0, 0, 0, 32)\n            r := mload(0)\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// bytecodeFormat: legacy\n// ----\n// f() -> 0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/reverts/simple_throw.sol",
    "content": "contract Test {\n    function f(uint256 x) public returns (uint256) {\n        if (x > 10) return x + 10;\n        else revert();\n        return 2;\n    }\n}\n// ----\n// f(uint256): 11 -> 21\n// f(uint256): 1 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/saltedCreate/eof/salted_create_with_value.sol",
    "content": "contract B\n{\n    uint x;\n    function getBalance() public view returns (uint) {\n        return address(this).balance * 1000 + x;\n    }\n    constructor(uint _x) payable {\n        x = _x;\n    }\n}\n\ncontract A {\n    function f() public payable returns (uint, uint, uint) {\n        B x = new B{salt: \"abc1\", value: 3}(7);\n        B y = new B{value: 3, salt: \"abc2\"}(8);\n        B z = new B{salt: \"abc3\", value: 3}(9);\n        return (x.getBalance(), y.getBalance(), z.getBalance());\n    }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// f(), 10 ether -> 3007, 3008, 3009\n"
  },
  {
    "path": "test/libsolidity/semanticTests/saltedCreate/prediction_example.sol",
    "content": "contract D {\n    uint public x;\n    constructor(uint a) {\n        x = a;\n    }\n}\n\ncontract C {\n    function createDSalted(bytes32 salt, uint arg) public {\n        address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(\n            bytes1(0xff),\n            address(this),\n            salt,\n            keccak256(abi.encodePacked(\n                type(D).creationCode,\n                arg\n            ))\n        )))));\n\n        D d = new D{salt: salt}(arg);\n        require(address(d) == predictedAddress, \"Address mismatch.\");\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// compileViaYul: also\n// bytecodeFormat: legacy\n// ----\n// createDSalted(bytes32,uint256): 42, 64 ->\n// gas legacy: 78573\n// gas legacy code: 23600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/saltedCreate/salted_create.sol",
    "content": "contract B\n{\n}\n\ncontract A {\n    function different_salt() public returns (bool) {\n        B x = new B{salt: \"abc\"}();\n        B y = new B{salt: \"abcef\"}();\n        return x != y;\n    }\n    function same_salt() public returns (bool) {\n        B x = new B{salt: \"xyz\"}();\n        try new B{salt: \"xyz\"}() {} catch {\n            return true;\n        }\n        return false;\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// different_salt() -> true\n// same_salt() -> true\n// gas irOptimized: 98438295\n// gas irOptimized code: 600\n// gas legacy: 98437509\n// gas legacy code: 1600\n// gas legacyOptimized: 98437367\n// gas legacyOptimized code: 1600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/saltedCreate/salted_create_with_value.sol",
    "content": "contract B\n{\n    uint x;\n    function getBalance() public view returns (uint) {\n        return address(this).balance * 1000 + x;\n    }\n    constructor(uint _x) payable {\n        x = _x;\n    }\n}\n\ncontract A {\n    function f() public payable returns (uint, uint, uint) {\n        B x = new B{salt: \"abc\", value: 3}(7);\n        B y = new B{value: 3, salt: \"abc\"}(8);\n        B z = new B{salt: \"abc\", value: 3}(9);\n        return (x.getBalance(), y.getBalance(), z.getBalance());\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// bytecodeFormat: legacy\n// ----\n// f(), 10 ether -> 3007, 3008, 3009\n// gas irOptimized: 187022\n// gas irOptimized code: 67200\n// gas legacy: 190858\n// gas legacy code: 190200\n// gas legacyOptimized: 187256\n// gas legacyOptimized code: 92400\n"
  },
  {
    "path": "test/libsolidity/semanticTests/scoping/c99_scoping_activation.sol",
    "content": "contract test {\n    function f() pure public returns (uint) {\n        uint x = 7;\n        {\n            x = 3; // This should still assign to the outer variable\n            uint x;\n            x = 4; // This should assign to the new one\n        }\n        return x;\n    }\n    function g() pure public returns (uint x) {\n        x = 7;\n        {\n            x = 3;\n            uint x;\n            return x; // This returns the new variable, i.e. 0\n        }\n    }\n    function h() pure public returns (uint x, uint a, uint b) {\n        x = 7;\n        {\n            x = 3;\n            a = x; // This should read from the outer\n            uint x = 4;\n            b = x;\n        }\n    }\n    function i() pure public returns (uint x, uint a) {\n        x = 7;\n        {\n            x = 3;\n            uint x = x; // This should read from the outer and assign to the inner\n            a = x;\n        }\n    }\n}\n// ----\n// f() -> 3\n// g() -> 0\n// h() -> 3, 3, 4\n// i() -> 3, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/shanghai/evmone_support.sol",
    "content": "contract ShortReturn {\n    constructor() {\n        assembly {\n            // return(0, 32)\n            // PUSH1 0x20 PUSH0 RETURN\n            mstore(0, hex\"60205ff3\")\n            return(0, 4)\n        }\n    }\n}\n\ninterface DoesItReturnZero {\n    function foo() external pure returns (uint256);\n}\n\ncontract Test {\n    ShortReturn immutable shortReturn = new ShortReturn();\n    function bytecode() external view returns(bytes memory) {\n        return address(shortReturn).code;\n    }\n    function isPush0Supported() external view returns (bool) {\n        assert(DoesItReturnZero(address(shortReturn)).foo() == 0);\n        return true;\n    }\n}\n// ====\n// compileViaYul: also\n// EVMVersion: >=shanghai\n// bytecodeFormat: legacy\n// ----\n// bytecode() -> 0x20, 4, 0x60205ff300000000000000000000000000000000000000000000000000000000\n// isPush0Supported() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/shanghai/push0.sol",
    "content": "contract C {\n    function zero() external returns (uint) {\n        return 0;\n    }\n\n}\n// ====\n// compileViaYul: also\n// EVMVersion: >=shanghai\n// ----\n// zero() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/smoke/alignment.sol",
    "content": "contract C {\n    uint256 public stateDecimal = 0x20;\n}\n\ncontract D {\n    bool public stateBool = true;\n    uint256 public stateDecimal = 42;\n    bytes32 public stateBytes = \"\\x42\\x00\\xef\";\n\n    function internalStateDecimal() public returns (uint256) {\n        return (new C()).stateDecimal();\n    }\n\n    function update(bool _bool, uint256 _decimal, bytes32 _bytes) public returns (bool, uint256, bytes32) {\n        stateBool = _bool;\n        stateDecimal = _decimal;\n        stateBytes = _bytes;\n        return (stateBool, stateDecimal, stateBytes);\n    }\n}\n// ----\n// stateBool() -> true\n// stateBool() -> right(true)\n// stateDecimal() -> 42\n// stateDecimal() -> right(42)\n// stateBytes() -> left(0x4200ef)\n// internalStateDecimal() -> 0x20\n// gas legacy: 76665\n// gas legacy code: 23600\n// update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/smoke/arrays.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct T {\n        uint a;\n        uint b;\n        string s;\n    }\n    bool[2][] flags;\n    function r() public returns (bool[3] memory) {\n        return [true, false, true];\n    }\n    function s() public returns (uint[2] memory, uint) {\n        return ([uint(123), 456], 789);\n    }\n    function u() public returns (T[2] memory) {\n        return [T(23, 42, \"any\"), T(555, 666, \"any\")];\n    }\n    function v() public returns (bool[2][] memory) {\n        return flags;\n    }\n    function w1() public returns (string[1] memory) {\n        return [\"any\"];\n    }\n    function w2() public returns (string[2] memory) {\n        return [\"any\", \"any\"];\n    }\n    function w3() public returns (string[3] memory) {\n        return [\"any\", \"any\", \"any\"];\n    }\n    function x() public returns (string[2] memory, string[3] memory) {\n        return ([\"any\", \"any\"], [\"any\", \"any\", \"any\"]);\n    }\n}\n// ----\n// r() -> true, false, true\n// s() -> 123, 456, 789\n// u() -> 0x20, 0x40, 0xE0, 23, 42, 0x60, 3, \"any\", 555, 666, 0x60, 3, \"any\"\n// v() -> 0x20, 0\n// w1() -> 0x20, 0x20, 3, \"any\"\n// w2() -> 0x20, 0x40, 0x80, 3, \"any\", 3, \"any\"\n// w3() -> 0x20, 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n// x() -> 0x40, 0x0100, 0x40, 0x80, 3, \"any\", 3, \"any\", 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/smoke/basic.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function d() public {\n    }\n    function e() public payable returns (uint) {\n        return msg.value;\n    }\n    function f(uint a) public pure returns (uint, uint) {\n        return (a, a);\n    }\n    function g() public  pure returns (uint, uint) {\n        return (2, 3);\n    }\n    function h(uint x, uint y) public  pure returns (uint) {\n        unchecked { return x - y; }\n    }\n    function i(bool b) public  pure returns (bool) {\n        return !b;\n    }\n    function j(bytes32 b) public pure returns (bytes32, bytes32) {\n        return (b, b);\n    }\n    function k() public pure returns (uint) {\n        return msg.data.length;\n    }\n    function l(uint a) public pure returns (uint d) {\n        return a * 7;\n    }\n}\n// ----\n// d() ->\n// e(), 1 wei -> 1\n// e(), 1 ether -> 1000000000000000000\n// f(uint256): 3 -> 3, 3\n// g() -> 2, 3\n// h(uint256,uint256): 1, -2 -> 3\n// i(bool): true -> false\n// j(bytes32): 0x10001 -> 0x10001, 0x10001\n// k(): hex\"4200efef\" -> 8\n// l(uint256): 99 -> 693\n"
  },
  {
    "path": "test/libsolidity/semanticTests/smoke/bytes_and_strings.sol",
    "content": "contract C {\n    function e(bytes memory b) public pure returns (bytes memory) {\n        return b;\n    }\n    function f() public pure returns (string memory, string memory) {\n        return (\"any\", \"any\");\n    }\n    function g() public pure returns (string memory, uint, string memory) {\n        return (\"any\", 42, \"any\");\n    }\n    function h() public pure returns (string memory) {\n        return \"any\";\n    }\n}\n// ----\n// e(bytes): 32, 3, hex\"AB33BB\" -> 32, 3, left(0xAB33BB)\n// e(bytes): 32, 32, 0x20 -> 32, 32, 0x20\n// e(bytes): 32, 3, hex\"AB33FF\" -> 32, 3, hex\"ab33ff0000000000000000000000000000000000000000000000000000000000\"\n// f() -> 0x40, 0x80, 3, \"any\", 3, \"any\"\n// g() -> 0x60, 0x2a, 0xa0, 3, \"any\", 3, \"any\"\n// h() -> 0x20, 3, \"any\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/smoke/constructor.sol",
    "content": "contract C {\n    uint public state = 0;\n    constructor(uint _state) payable {\n        state = _state;\n    }\n    function balance() public payable returns (uint256) {\n        return address(this).balance;\n    }\n    function update(uint _state) public {\n        state = _state;\n    }\n}\n// ----\n// constructor(), 2 wei: 3 ->\n// gas irOptimized: 78996\n// gas irOptimized code: 25400\n// gas legacy: 83055\n// gas legacy code: 65200\n// gas legacyOptimized: 78898\n// gas legacyOptimized code: 27800\n// state() -> 3\n// balance() -> 2\n// balance -> 2\n// update(uint256): 4\n// state() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/smoke/failure.sol",
    "content": "contract C {\n    function e() public pure {\n        revert(\"Transaction failed.\");\n    }\n    function f(bool _value) public pure {\n        string memory message;\n        require(_value, message);\n    }\n    function g(bool _value) public pure {\n        require(_value, \"Value is false.\");\n    }\n    function h() public pure returns (uint) {\n        assert(false);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// allowNonExistingFunctions: true\n// ----\n// _() -> FAILURE\n// e() -> FAILURE, hex\"08c379a0\", 0x20, 0x13, \"Transaction failed.\"\n// f(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x00\n// g(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x0f, \"Value is false.\"\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n"
  },
  {
    "path": "test/libsolidity/semanticTests/smoke/fallback.sol",
    "content": "contract A {\n    uint public data;\n    uint public balance;\n    bytes public externalData;\n    fallback() external payable {\n        data += 1;\n        balance = msg.value;\n        externalData = msg.data;\n    }\n}\n// ----\n// data() -> 0\n// ()\n// data() -> 1\n// (): hex\"42ef\"\n// data() -> 2\n// externalData() -> 0x20, 2, left(0x42ef)\n// balance() -> 0\n// (), 1 wei\n// balance() -> 1\n// (), 2 wei: hex\"fefe\"\n// balance() -> 2\n// externalData() -> 0x20, 2, left(0xfefe)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/smoke/multiline.sol",
    "content": "contract C {\n    function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n        return a + b + c + d + e;\n    }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// -> 5\n// g()\n// # g() does not exist #\n// -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/smoke/multiline_comments.sol",
    "content": "contract C {\n    function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n        return a + b + c + d + e;\n    }\n}\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// # A comment on the function parameters. #\n// -> 5\n// f(uint256,uint256,uint256,uint256,uint256):\n// 1,\n// 1,\n// 1,\n// 1,\n// 1\n// -> 5\n// # Should return sum of all parameters. #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/smoke/structs.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint a;\n        uint b;\n    }\n    struct T {\n        uint a;\n        uint b;\n        string s;\n    }\n    function s() public returns (S memory) {\n        return S(23, 42);\n    }\n    function t() public returns (T memory) {\n        return T(23, 42, \"any\");\n    }\n}\n// ----\n// s() -> 23, 42\n// t() -> 0x20, 23, 42, 0x60, 3, \"any\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/specialFunctions/abi_encode_with_signature_from_string.sol",
    "content": "contract C {\n    function f() public pure returns (bytes memory r1, bytes memory r2) {\n        string memory x = \"my_signature\";\n        r1 = abi.encodeWithSignature(\"my_signature\", 1);\n        r2 = abi.encodeWithSignature(x, 1);\n        assert(r1.length == r2.length);\n        for (uint i = 0; i < r1.length; i++)\n            assert(r1[i] == r2[i]);\n    }\n}\n// ----\n// f() -> 0x40, 0xa0, 0x24, -813742827273327954027712588510533233455028711326166692885570228492575965184, 26959946667150639794667015087019630673637144422540572481103610249216, 0x24, -813742827273327954027712588510533233455028711326166692885570228492575965184, 26959946667150639794667015087019630673637144422540572481103610249216\n"
  },
  {
    "path": "test/libsolidity/semanticTests/specialFunctions/abi_functions_member_access.sol",
    "content": "contract C {\n    function f() public pure {\n        abi.encode;\n        abi.encodePacked;\n        abi.encodeWithSelector;\n        abi.encodeWithSignature;\n        abi.decode;\n    }\n}\n// ----\n// f() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/specialFunctions/keccak256_optimized.sol",
    "content": "// tests compile-time evaluation of keccak256 on literal strings\ncontract C {\n    function short() public pure returns (bool) {\n        bytes32 a = keccak256(\"abcdefghijklmn\");\n        bytes memory s = \"abcdefghijklmn\";\n        return a == keccak256(s);\n    }\n    bytes32 constant sc = keccak256(\"abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn\");\n    function long() public pure returns (bool, bool) {\n        bytes32 a = keccak256(\"abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn\");\n        bytes memory s = \"abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn\";\n        return (a == keccak256(s), sc == keccak256(s));\n    }\n}\n// ----\n// short() -> true\n// long() -> true, true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/blobhash.sol",
    "content": "contract C {\n    function f(uint _index) public returns (bytes32) {\n        return blobhash(_index);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(uint256): 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// f(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// f(uint256): 2 -> 0x00\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/block_basefee.sol",
    "content": "contract C {\n    function f() public view returns (uint) {\n        return block.basefee;\n    }\n    function g() public view returns (uint ret) {\n        assembly {\n            ret := basefee()\n        }\n    }\n}\n// ====\n// EVMVersion: >=london\n// ----\n// f() -> 7\n// g() -> 7\n// f() -> 7\n// g() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/block_blobbasefee.sol",
    "content": "contract C {\n    function f() public view returns (uint) {\n        return block.blobbasefee;\n    }\n    function g() public view returns (uint ret) {\n        assembly {\n            ret := blobbasefee()\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/block_chainid.sol",
    "content": "contract C {\n    function f() public returns (uint) {\n        return block.chainid;\n    }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/block_coinbase.sol",
    "content": "contract C {\n    function f() public returns (address payable) {\n        return block.coinbase;\n    }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/block_difficulty.sol",
    "content": "contract C {\n    function f() public returns (uint) {\n        return block.difficulty;\n    }\n}\n// ====\n// EVMVersion: <paris\n// ----\n// f() -> 200000000\n// f() -> 200000000\n// f() -> 200000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/block_difficulty_post_paris.sol",
    "content": "contract C {\n    function f() public returns (uint) {\n        return block.difficulty;\n    }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/block_gaslimit.sol",
    "content": "contract C {\n    function f() public returns (uint) {\n        return block.gaslimit;\n    }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/block_number.sol",
    "content": "contract C {\n    constructor() {}\n    function f() public returns (uint) {\n        return block.number;\n    }\n}\n// ----\n// constructor()\n// f() -> 2\n// f() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/block_prevrandao.sol",
    "content": "contract C {\n    function f() public view returns (uint) {\n        return block.prevrandao;\n    }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/block_prevrandao_pre_paris.sol",
    "content": "contract C {\n    function f() public view returns (uint) {\n        return block.prevrandao;\n    }\n}\n// ====\n// EVMVersion: <paris\n// ----\n// f() -> 200000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/block_timestamp.sol",
    "content": "contract C {\n    constructor() {}\n    function f() public returns (uint) {\n        return block.timestamp;\n    }\n}\n// ----\n// constructor() # This is the 1st block #\n// f() -> 0x1e # This is the 2nd block (each block is \"15 seconds\") #\n// f() -> 0x2d # This is the 3rd block #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/blockhash_basic.sol",
    "content": "contract C {\n    bytes32 public genesisHash;\n    bytes32 public currentHash;\n    constructor() {\n        require(block.number == 1);\n        genesisHash = blockhash(0);\n        currentHash = blockhash(1);\n    }\n    function f(uint blockNumber) public returns (bytes32) {\n        return blockhash(blockNumber);\n    }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/gasleft.sol",
    "content": "contract C {\n    function f() public returns (bool) {\n        return gasleft() > 0;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// f() -> true\n// f() -> true\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/msg_data.sol",
    "content": "contract C {\n    function f() public returns (bytes calldata) {\n        return msg.data;\n    }\n    function g(uint,bool) public returns (bytes calldata) {\n        return msg.data;\n    }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/msg_sender.sol",
    "content": "contract C {\n    function f() public returns (address) {\n        return msg.sender;\n    }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/msg_sig.sol",
    "content": "contract C {\n    function f() public returns (bytes4) {\n        return msg.sig;\n    }\n    function g() public returns (bytes4) {\n        return msg.sig;\n    }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/msg_value.sol",
    "content": "contract C {\n    function f() public payable returns (uint) {\n        return msg.value;\n    }\n}\n// ----\n// f() -> 0\n// f(), 12 ether -> 12000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/tx_gasprice.sol",
    "content": "contract C {\n    function f() public returns (uint) {\n        return tx.gasprice;\n    }\n}\n// ----\n// f() -> 3000000000\n// f() -> 3000000000\n// f() -> 3000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/tx_origin.sol",
    "content": "contract C {\n    function f() public returns (address) {\n        return tx.origin;\n    }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/uncalled_blobhash.sol",
    "content": "contract C {\n    function f() public returns (bytes32) {\n        // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n        // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n        // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n        return (blobhash)(0);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n"
  },
  {
    "path": "test/libsolidity/semanticTests/state/uncalled_blockhash.sol",
    "content": "contract C {\n    function f() public returns (bytes32) {\n        return (blockhash)(block.number - 1);\n    }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n"
  },
  {
    "path": "test/libsolidity/semanticTests/statements/do_while_loop_continue.sol",
    "content": "contract test {\n    function f() public pure returns(uint r) {\n        uint i = 0;\n        do\n        {\n            if (i > 0) return 0;\n            i++;\n            continue;\n        } while (false);\n        return 42;\n    }\n}\n// ----\n// f() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/statements/empty_for_loop.sol",
    "content": "contract test {\n    function f() public returns(uint ret) {\n        ret = 1;\n        for (;;) {\n            ret += 1;\n            if (ret >= 10) break;\n        }\n    }\n}\n// ----\n// f() -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/accessors_mapping_for_array.sol",
    "content": "contract test {\n    mapping(uint => uint[8]) public data;\n    mapping(uint => uint[]) public dynamicData;\n    constructor() {\n        data[2][2] = 8;\n        for (uint i = 0; i < 3; i++)\n            dynamicData[2].push();\n        dynamicData[2][2] = 8;\n    }\n}\n// ----\n// data(uint256,uint256): 2, 2 -> 8\n// data(uint256,uint256): 2, 8 -> FAILURE # NB: the original code contained a bug here #\n// dynamicData(uint256,uint256): 2, 2 -> 8\n// dynamicData(uint256,uint256): 2, 8 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/array_accessor.sol",
    "content": "contract test {\n    uint[8] public data;\n    uint[] public dynamicData;\n    uint24[] public smallTypeData;\n    struct st { uint a; uint[] finalArray; }\n    mapping(uint256 => mapping(uint256 => st[5])) public multiple_map;\n\n    constructor() {\n        data[0] = 8;\n\n        dynamicData.push();\n        dynamicData.push();\n        dynamicData.push(8);\n\n        smallTypeData = new uint24[](128);\n        smallTypeData[1] = 22;\n        smallTypeData[127] = 2;\n\n        multiple_map[2][1][2].a = 3;\n        for (uint i = 0; i < 4; i++)\n            multiple_map[2][1][2].finalArray.push();\n        multiple_map[2][1][2].finalArray[3] = 5;\n    }\n}\n// ----\n// data(uint256): 0 -> 8\n// data(uint256): 8 -> FAILURE\n// dynamicData(uint256): 2 -> 8\n// dynamicData(uint256): 8 -> FAILURE\n// smallTypeData(uint256): 1 -> 22\n// smallTypeData(uint256): 127 -> 2\n// smallTypeData(uint256): 128 -> FAILURE\n// multiple_map(uint256,uint256,uint256): 2, 1, 2 -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/chop_sign_bits.sol",
    "content": "contract Test {\n    int16[] public x = [-1, -2];\n    int16[2] public y = [-5, -6];\n    int16 z;\n    function f() public returns (int16[] memory) {\n        int8[] memory t = new int8[](2);\n        t[0] = -3;\n        t[1] = -4;\n        x = t;\n        return x;\n    }\n    function g() public returns (int16[2] memory) {\n        int8[2] memory t = [-3, -4];\n        y = t;\n        return y;\n    }\n    function h(int8 t) public returns (int16) {\n        z = t;\n        return z;\n    }\n}\n// ----\n// x(uint256): 0 -> -1\n// x(uint256): 1 -> -2\n// y(uint256): 0 -> -5\n// y(uint256): 1 -> -6\n// f() -> 0x20, 2, -3, -4\n// g() -> -3, -4\n// h(int8): -10 -> -10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/complex_accessors.sol",
    "content": "contract test {\n    mapping(uint256 => bytes4) public to_string_map;\n    mapping(uint256 => bool) public to_bool_map;\n    mapping(uint256 => uint256) public to_uint_map;\n    mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;\n    constructor() {\n        to_string_map[42] = \"24\";\n        to_bool_map[42] = false;\n        to_uint_map[42] = 12;\n        to_multiple_map[42][23] = 31;\n    }\n}\n// ----\n// to_string_map(uint256): 42 -> \"24\"\n// to_bool_map(uint256): 42 -> false\n// to_uint_map(uint256): 42 -> 12\n// to_multiple_map(uint256,uint256): 42, 23 -> 31\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_inherited_storage_same_value_type.sol",
    "content": "contract Base {\n    uint256 public x;\n\n    function deleteX() internal {\n        delete x;\n    }\n}\n\ncontract C is Base {\n    uint256 transient t;\n\n    function setAndClear() external {\n        x = 1;\n        t = 2;\n        deleteX();\n        delete t;\n        assert(t == 0);\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// setAndClear() ->\n// x() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_array_delete_different_base_type.sol",
    "content": "contract C {\n    bool[3] flags = [true, true, true];\n    uint256 transient temp;\n\n    function setAndClear() external {\n        temp = 0xffffffff;\n        delete flags;\n        delete temp;\n        assert(temp == 0);\n    }\n\n    function getFlags() external returns(bool[3] memory)\n    {\n        return flags;\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// getFlags() -> true, true, true\n// setAndClear() ->\n// getFlags() -> false, false, false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_array_pop_same_base_type.sol",
    "content": "contract C {\n    uint256[] arr;\n    uint256 transient t;\n\n    function pushArr() external {\n        arr.push(1);\n    }\n\n    function setAndClear() external {\n        t = 2;\n        delete t;\n        assert(t == 0);\n        arr.pop();\n    }\n\n    // Get value at index 0, which should have been cleared after arr.pop()\n    function getArr() external returns (uint256 value) {\n        assembly {\n            mstore(0, arr.slot)\n            value := sload(keccak256(0x00, 0x20))\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// pushArr() ->\n// getArr() -> 1\n// setAndClear() ->\n// getArr() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_delete_same_value_type.sol",
    "content": "contract C {\n    uint256 transient varTransient;\n    uint256 public varStorage = 0xeeeeeeeeee;\n\n    function setAndClear() external {\n        varTransient = 0xffffffff;\n        delete varStorage;\n        delete varTransient;\n        assert(varTransient == 0);\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// varStorage() -> 0xeeeeeeeeee\n// setAndClear() ->\n// varStorage() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_mapping_delete_same_value_type.sol",
    "content": "contract C {\n    mapping(uint256 => uint256) m;\n    uint256 transient t;\n\n    function setAndClear() external {\n        m[0] = 1;\n        t = 2;\n        delete m[0];\n        delete t;\n        assert(t == 0);\n    }\n\n    function getM() external view returns (uint256) {\n        return m[0];\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// setAndClear() ->\n// getM() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_after_storage_struct_delete_same_value_type.sol",
    "content": "contract C {\n    struct S {\n        uint256 a;\n        address b;\n    }\n\n    S s = S(1, address(0x1234));\n    uint256 transient t;\n\n    function setAndDelete() external {\n        t = 2;\n        delete s;\n        delete t;\n        assert(t == 0);\n    }\n\n    function getS() external view returns (uint256, address) {\n        return (s.a, s.b);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// getS() -> 1, 0x1234\n// setAndDelete() ->\n// getS() -> 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_inherited_storage_same_value_type.sol",
    "content": "contract Base {\n    uint256 public x;\n\n    function deleteX() internal {\n        delete x;\n    }\n}\n\ncontract C is Base {\n    uint256 transient t;\n\n    function setAndClear() external {\n        x = 1;\n        t = 2;\n        delete t;\n        assert(t == 0);\n        deleteX();\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// setAndClear() ->\n// x() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_array_delete_different_base_type.sol",
    "content": "contract C {\n    bool[3] flags = [true, true, true];\n    uint256 transient temp;\n\n    function setAndClear() external {\n        temp = 0xffffffff;\n        delete temp;\n        assert(temp == 0);\n        delete flags;\n    }\n\n    function getFlags() external returns(bool[3] memory)\n    {\n        return flags;\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// getFlags() -> true, true, true\n// setAndClear() ->\n// getFlags() -> false, false, false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_array_partial_assignment_same_base_type.sol",
    "content": "contract C {\n    uint256[2] small;\n    uint256[4] large;\n    uint256 transient t;\n\n    function setAndClear() external {\n        large = [1,2,3,4];\n        small = [10, 20];\n        t = 99;\n\n        delete t;\n        assert(t == 0);\n        large = small;\n    }\n\n    function getLarge() external view returns (uint256[4] memory) {\n        return large;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// setAndClear() ->\n// gas irOptimized: 124683\n// gas legacy: 127807\n// gas legacyOptimized: 124828\n// getLarge() -> 10, 20, 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_delete_same_value_type.sol",
    "content": "contract C {\n    uint256 transient varTransient;\n    uint256 public varStorage = 0xeeeeeeeeee;\n\n    function setAndClear() external {\n        varTransient = 0xffffffff;\n        delete varTransient;\n        assert(varTransient == 0);\n        delete varStorage;\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// varStorage() -> 0xeeeeeeeeee\n// setAndClear() ->\n// varStorage() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_mapping_delete_same_value_type.sol",
    "content": "contract C {\n    mapping(uint256 => uint256) m;\n    uint256 transient t;\n\n    function setAndClear() external {\n        m[0] = 1;\n        t = 2;\n        delete t;\n        assert(t == 0);\n        delete m[0];\n    }\n\n    function getM() external view returns (uint256) {\n        return m[0];\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// setAndClear() ->\n// getM() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/delete_overlapping_transient_before_storage_struct_delete_same_value_type.sol",
    "content": "contract C {\n    struct S {\n        uint256 a;\n        address b;\n    }\n\n    S s = S(1, address(0x1234));\n    uint256 transient t;\n\n    function setAndDelete() external {\n        t = 2;\n        delete t;\n        assert(t == 0);\n        delete s;\n    }\n\n    function getS() external view returns (uint256, address) {\n        return (s.a, s.b);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// getS() -> 1, 0x1234\n// setAndDelete() ->\n// getS() -> 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/empty_nonempty_empty.sol",
    "content": "contract Test {\n    bytes x;\n    function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111820\n// gas legacy: 112734\n// gas legacyOptimized: 112089\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// gas irOptimized: 33989\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/mapping_state.sol",
    "content": "contract Ballot {\n\tmapping(address => bool) canVote;\n\tmapping(address => uint) voteCount;\n\tmapping(address => bool) voted;\n\tfunction getVoteCount(address addr) public returns (uint retVoteCount) {\n\t\treturn voteCount[addr];\n\t}\n\tfunction grantVoteRight(address addr) public {\n\t\tcanVote[addr] = true;\n\t}\n\tfunction vote(address voter, address vote) public returns (bool success) {\n\t\tif (!canVote[voter] || voted[voter]) return false;\n\t\tvoted[voter] = true;\n\t\tvoteCount[vote] = voteCount[vote] + 1;\n\t\treturn true;\n\t}\n}\n// ----\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 0\n// vote(address,address): 0, 2 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 0\n// grantVoteRight(address): 0 ->\n// grantVoteRight(address): 1 ->\n// vote(address,address): 0, 2 -> true\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// vote(address,address): 0, 1 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// vote(address,address): 2, 1 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// grantVoteRight(address): 2 ->\n// vote(address,address): 2, 1 -> true\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 1\n// getVoteCount(address): 2 -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/mapping_string_key.sol",
    "content": "contract C {\n    mapping (string => uint) m_nameToRecord;\n    function set(string calldata key, uint value) external {\n        m_nameToRecord[key] = value;\n    }\n    function get(string calldata key) external view returns (uint) {\n        return m_nameToRecord[key];\n    }\n    function setFixed(uint value) external {\n        m_nameToRecord[\"fixed\"] = value;\n    }\n    function getFixed() external view returns (uint) {\n        return m_nameToRecord[\"fixed\"];\n    }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/mappings_array2d_pop_delete.sol",
    "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/mappings_array_pop_delete.sol",
    "content": "contract C {\n\tmapping (uint => uint)[] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\ta[a.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\treturn a[a.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/packed_functions.sol",
    "content": "contract C {\n    // these should take the same slot\n    function() internal returns (uint) a;\n    function() external returns (uint) b;\n    function() external returns (uint) c;\n    function() internal returns (uint) d;\n    uint8 public x;\n\n    function set() public {\n        x = 2;\n        d = g;\n        c = this.h;\n        b = this.h;\n        a = g;\n    }\n\n    function t1() public returns (uint256) {\n        return a();\n    }\n\n    function t2() public returns (uint256) {\n        return b();\n    }\n\n    function t3() public returns (uint256) {\n        return a();\n    }\n\n    function t4() public returns (uint256) {\n        return b();\n    }\n\n    function g() public returns (uint256) {\n        return 7;\n    }\n\n    function h() public returns (uint256) {\n        return 8;\n    }\n}\n// ----\n// set() ->\n// t1() -> 7\n// t2() -> 8\n// t3() -> 7\n// t4() -> 8\n// x() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/packed_storage_overflow.sol",
    "content": "contract C {\n    uint16 x = 0x1234;\n    uint16 a = 0xffff;\n    uint16 b;\n\n    function f() public returns (uint256, uint256, uint256, uint256) {\n        unchecked { a++; }\n        uint256 c = b;\n        delete b;\n        unchecked { a -= 2; }\n        return (x, c, b, a);\n    }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/packed_storage_signed.sol",
    "content": "contract C {\n    int8 a;\n    uint8 b;\n    int8 c;\n    uint8 d;\n\n    function test()\n        public\n        returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n    {\n        a = -2;\n        unchecked {\n            b = (0 - uint8(a)) * 2;\n            c = a * int8(120) * int8(121);\n        }\n        x1 = uint256(int256(a));\n        x2 = b;\n        x3 = uint256(int256(c));\n        x4 = d;\n    }\n}\n// ----\n// test() -> -2, 4, -112, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol",
    "content": "contract C {\n    struct s1 {\n        bytes1 a;\n        bytes1 b;\n        bytes10 c;\n        bytes9 d;\n        bytes10 e;\n    }\n    struct s2 {\n        bytes1 a;\n        s1 inner;\n        bytes1 b;\n        bytes1 c;\n    }\n    bytes1 x;\n    s2 data;\n    bytes1 y;\n\n    function test() public returns (bool) {\n        x = 0x01;\n        data.a = 0x02;\n        data.inner.a = 0x03;\n        data.inner.b = 0x04;\n        data.inner.c = \"1234567890\";\n        data.inner.d = \"123456789\";\n        data.inner.e = \"abcdefghij\";\n        data.b = 0x05;\n        data.c = bytes1(0x06);\n        y = 0x07;\n        return\n            x == 0x01 &&\n            data.a == 0x02 &&\n            data.inner.a == 0x03 &&\n            data.inner.b == 0x04 &&\n            data.inner.c == \"1234567890\" &&\n            data.inner.d == \"123456789\" &&\n            data.inner.e == \"abcdefghij\" &&\n            data.b == 0x05 &&\n            data.c == bytes1(0x06) &&\n            y == 0x07;\n    }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/packed_storage_structs_enum.sol",
    "content": "contract C {\n    enum small {A, B, C, D}\n    enum larger {A, B, C, D, E}\n    struct str {\n        small a;\n        small b;\n        larger c;\n        larger d;\n    }\n    str data;\n\n    function test() public returns (uint256) {\n        data.a = small.B;\n        if (data.a != small.B) return 2;\n        data.b = small.C;\n        if (data.b != small.C) return 3;\n        data.c = larger.D;\n        if (data.c != larger.D) return 4;\n        if (data.a != small.B) return 5;\n        data.a = small.C;\n        if (data.a != small.C) return 6;\n        if (data.b != small.C) return 7;\n        data.b = small.D;\n        if (data.b != small.D) return 8;\n        if (data.c != larger.D) return 9;\n        data.c = larger.B;\n        if (data.c != larger.B) return 10;\n        return 1;\n    }\n}\n// ----\n// test() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/packed_storage_structs_uint.sol",
    "content": "contract C {\n    struct str {\n        uint8 a;\n        uint16 b;\n        uint248 c;\n    }\n    str data;\n\n    function test() public returns (uint256) {\n        data.a = 2;\n        if (data.a != 2) return 2;\n        data.b = 0xabcd;\n        if (data.b != 0xabcd) return 3;\n        data.c = 0x1234567890;\n        if (data.c != 0x1234567890) return 4;\n        if (data.a != 2) return 5;\n        data.a = 8;\n        if (data.a != 8) return 6;\n        if (data.b != 0xabcd) return 7;\n        data.b = 0xdcab;\n        if (data.b != 0xdcab) return 8;\n        if (data.c != 0x1234567890) return 9;\n        data.c = 0x9876543210;\n        if (data.c != 0x9876543210) return 10;\n        return 1;\n    }\n}\n// ----\n// test() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/simple_accessor.sol",
    "content": "contract test {\n    uint256 public data;\n    constructor() {\n        data = 8;\n    }\n}\n// ----\n// data() -> 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/state_smoke_test.sol",
    "content": "contract test {\n    uint256 value1;\n    uint256 value2;\n    function get(uint8 which) public returns (uint256 value) {\n        if (which == 0) return value1;\n        else return value2;\n    }\n    function set(uint8 which, uint256 value) public {\n        if (which == 0) value1 = value;\n        else value2 = value;\n    }\n}\n// ----\n// get(uint8): 0x00 -> 0\n// get(uint8): 0x01 -> 0\n// set(uint8,uint256): 0x00, 0x1234 ->\n// set(uint8,uint256): 0x01, 0x8765 ->\n// get(uint8): 0x00 -> 0x1234\n// get(uint8): 0x01 -> 0x8765\n// set(uint8,uint256): 0x00, 0x03 ->\n// get(uint8): 0x00 -> 0x03\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/static_array_copy_cleanup.sol",
    "content": "contract C {\n    struct S {\n        uint64 a;\n        uint64 b;\n        uint64 c;\n        uint64 d;\n        // All fit in one slot (4 * 64 = 256 bits)\n    }\n\n    S[5] source;\n    S[10] dest;\n    uint256 public canary = type(uint256).max;\n\n    function fillSource() public {\n        for (uint i = 0; i < 5; i++) {\n            source[i] = S({\n                a: uint64(1 + i * 4),\n                b: uint64(2 + i * 4),\n                c: uint64(3 + i * 4),\n                d: uint64(4 + i * 4)\n            });\n        }\n    }\n\n    function fillDest() public {\n        for (uint i = 0; i < 10; i++) {\n            dest[i] = S({\n                a: uint64(100 + i * 4),\n                b: uint64(101 + i * 4),\n                c: uint64(102 + i * 4),\n                d: uint64(103 + i * 4)\n            });\n        }\n    }\n\n    function copySourceToDest() public {\n        dest = source;\n    }\n\n    function deleteSource() public {\n        delete source;\n    }\n\n    function deleteDest() public {\n        delete dest;\n    }\n\n    function getSourceAsUint() public view returns (uint64[20] memory result) {\n        for (uint i = 0; i < 5; i++) {\n            result[i * 4] = source[i].a;\n            result[i * 4 + 1] = source[i].b;\n            result[i * 4 + 2] = source[i].c;\n            result[i * 4 + 3] = source[i].d;\n        }\n    }\n\n    function getDestAsUint() public view returns (uint64[40] memory result) {\n        for (uint i = 0; i < 10; i++) {\n            result[i * 4] = dest[i].a;\n            result[i * 4 + 1] = dest[i].b;\n            result[i * 4 + 2] = dest[i].c;\n            result[i * 4 + 3] = dest[i].d;\n        }\n    }\n}\n// ----\n// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// getSourceAsUint() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// 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\n// fillSource()\n// gas irOptimized: 135018\n// gas legacy: 146851\n// gas legacyOptimized: 137549\n// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// getSourceAsUint() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20\n// fillDest()\n// gas irOptimized: 248706\n// gas legacy: 272468\n// gas legacyOptimized: 253871\n// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// getSourceAsUint() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20\n// 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\n// copySourceToDest()\n// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// getSourceAsUint() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20\n// 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\n// deleteSource()\n// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// getSourceAsUint() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// 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\n// deleteDest()\n// canary() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// getSourceAsUint() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// 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\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_array_and_partial_assignment_with_layout.sol",
    "content": "contract C layout at 2**256 - 5 {\n    uint256 a;\n\n    function getArray() internal pure returns (uint256[10][1] storage _x) {\n        assembly {\n            _x.slot := a.slot\n        }\n    }\n\n    function fillArray() public {\n        uint256[10][1] storage _x = getArray();\n        for (uint i = 1; i < 10; i++)\n            _x[0][i] = i;\n    }\n\n    function partialAssignArrayBeforeStorageBoundary() public {\n        uint256[10][1] storage _x = getArray();\n        _x[0] = [11, 12, 13];\n    }\n\n    function partialAssignArrayCrossStorageBoundary() public {\n        uint256[10][1] storage _x = getArray();\n        _x[0] = [14, 15, 16, 17, 18, 19, 20];\n    }\n\n    function clearArray() public {\n        uint256[10][1] storage _x = getArray();\n        delete _x[0];\n    }\n\n    function x() public view returns (uint256[10] memory) {\n        return getArray()[0];\n    }\n}\n// ----\n// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// fillArray()\n// gas irOptimized: 220749\n// gas legacy: 221473\n// gas legacyOptimized: 220915\n// partialAssignArrayBeforeStorageBoundary()\n// x() -> 11, 12, 13, 0, 0, 0, 0, 0, 0, 0\n// fillArray()\n// gas irOptimized: 186549\n// gas legacy: 187273\n// gas legacyOptimized: 186715\n// x() -> 11, 1, 2, 3, 4, 5, 6, 7, 8, 9\n// partialAssignArrayCrossStorageBoundary()\n// x() -> 14, 15, 16, 17, 18, 19, 20, 0, 0, 0\n// clearArray()\n// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// gas irOptimized: 44183\n// gas legacy: 46007\n// gas legacyOptimized: 43907\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_array_assignment.sol",
    "content": "contract C {\n    function getArray() internal pure returns (uint256[10][1] storage _x) {\n        assembly {\n            _x.slot := sub(0, 5)\n        }\n    }\n\n    function assignArray(uint256[10] memory y) public {\n        uint256[10][1] storage _x = getArray();\n        _x[0] = y;\n    }\n\n    function x() public view returns (uint256[10] memory) {\n        return getArray()[0];\n    }\n}\n// ----\n// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// assignArray(uint256[10]): 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ->\n// gas irOptimized: 245236\n// gas legacy: 249351\n// gas legacyOptimized: 245365\n// x() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\n// assignArray(uint256[10]): 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ->\n// x() -> 10, 20, 30, 40, 50, 60, 70, 80, 90, 100\n// gas irOptimized: 44183\n// gas legacy: 46012\n// gas legacyOptimized: 43907\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_array_copy.sol",
    "content": "contract C {\n    constructor() {\n        uint256[10][1] storage _x = getX();\n        _x[0] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    }\n\n    function getX() internal pure returns (uint256[10][1] storage _x) {\n        assembly {\n            _x.slot := sub(0, 5)\n        }\n    }\n\n    function getY() internal pure returns (uint256[10][1] storage _y) {\n        assembly {\n            _y.slot := 5\n        }\n    }\n\n    function copyXToY() public {\n        uint256[10][1] storage _x = getX();\n        uint256[10][1] storage _y = getY();\n        _y[0] = _x[0];\n    }\n\n    function clearX() public {\n        uint256[10][1] storage _x = getX();\n        delete _x[0];\n    }\n\n    function copyYToX() public {\n        uint256[10][1] storage _x = getX();\n        uint256[10][1] storage _y = getY();\n        _x[0] = _y[0];\n    }\n\n    function x() public view returns (uint256[10] memory) {\n        return getX()[0];\n    }\n\n    function y() public view returns (uint256[10] memory) {\n        return getY()[0];\n    }\n}\n// ----\n// x() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\n// y() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// copyXToY()\n// gas irOptimized: 264224\n// gas legacy: 265434\n// gas legacyOptimized: 264247\n// x() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\n// y() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\n// clearX()\n// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// y() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\n// copyYToX()\n// gas irOptimized: 266243\n// gas legacy: 267456\n// gas legacyOptimized: 266280\n// x() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\n// y() -> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_array_delete.sol",
    "content": "contract C {\n    function getArray() internal pure returns (uint256[10][1] storage _x) {\n        assembly {\n            _x.slot := sub(0, 5)\n        }\n    }\n\n    function fillArray() public {\n        uint256[10][1] storage _x = getArray();\n        for (uint i = 1; i < 10; i++)\n            _x[0][i] = i;\n    }\n\n    function clearArray() public {\n        uint256[10][1] storage _x = getArray();\n        delete _x[0];\n    }\n\n    function x() public view returns (uint256[10] memory) {\n        return getArray()[0];\n    }\n}\n// ----\n// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// fillArray()\n// gas irOptimized: 220705\n// gas legacy: 221434\n// gas legacyOptimized: 220871\n// x() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n// clearArray()\n// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// gas irOptimized: 44183\n// gas legacy: 46012\n// gas legacyOptimized: 43907\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_array_delete_overlapping_variable.sol",
    "content": "contract C {\n    uint256 public y = 42;\n\n    function getArray() internal pure returns (uint256[10][1] storage _x) {\n        assembly {\n            _x.slot := sub(0, 5)\n        }\n    }\n\n    function fillArray() public {\n        uint256[10][1] storage _x = getArray();\n        for (uint i = 1; i < 10; i++)\n            _x[0][i] = i;\n    }\n\n    function clearArray() public {\n        uint256[10][1] storage _x = getArray();\n        delete _x[0];\n    }\n\n    function x() public view returns (uint256[10] memory) {\n        return getArray()[0];\n    }\n}\n\n// ----\n// y() -> 42\n// x() -> 0, 0, 0, 0, 0, 42, 0, 0, 0, 0\n// fillArray()\n// gas irOptimized: 203627\n// gas legacy: 204356\n// gas legacyOptimized: 203793\n// y() -> 5\n// x() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n// clearArray()\n// y() -> 0\n// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// gas irOptimized: 44183\n// gas legacy: 46012\n// gas legacyOptimized: 43907\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_array_packing_not_overlapping_variable.sol",
    "content": "contract C {\n    struct Canary {\n        uint256 value;\n    }\n\n    constructor() {\n        Canary storage canary = getCanary();\n        canary.value = type(uint256).max; // Should not be overwritten\n    }\n\n    function getArray() internal pure returns (uint64[10][1] storage _x) {\n        // Array of 10 * uint64 values (8 bytes each)\n        // Packs 4 uint64 per slot -> 3 slots total (slots -1, 0, 1)\n        assembly {\n            _x.slot := sub(0, 1)\n        }\n    }\n\n    function getCanary() internal pure returns (Canary storage canary) {\n        // Canary at slot 2, right after the array ends at slot 1\n        assembly {\n            canary.slot := 2\n        }\n    }\n\n    function fillArray() public {\n        uint64[10][1] storage _x = getArray();\n        for (uint64 i = 0; i < 10; i++)\n            _x[0][i] = i;\n    }\n\n    function shrinkTo5() public {\n        uint64[10][1] storage _x = getArray();\n        // Resize by assigning a smaller array\n        // This should clear items [5..9] without touching y\n        _x[0] = [uint64(11), 12, 13, 14, 15];\n    }\n\n    function clearArray() public {\n        uint64[10][1] storage _x = getArray();\n        delete _x[0];\n    }\n\n    function x() public view returns (uint64[10] memory) {\n        return getArray()[0];\n    }\n\n    function canaryValue() public view returns (uint256) {\n        return getCanary().value;\n    }\n}\n// ----\n// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// fillArray()\n// x() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shrinkTo5()\n// x() -> 11, 12, 13, 14, 15, 0, 0, 0, 0, 0\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// clearArray()\n// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_array_partial_assignment.sol",
    "content": "contract C {\n    function getArray() internal pure returns (uint256[10][1] storage _x) {\n        assembly {\n            _x.slot := sub(0, 5)\n        }\n    }\n\n    function fillArray() public {\n        uint256[10][1] storage _x = getArray();\n        for (uint i = 1; i < 10; i++)\n            _x[0][i] = i;\n    }\n\n    function x() public view returns (uint256[10] memory) {\n        return getArray()[0];\n    }\n\n    function partialAssignArrayBeforeStorageBoundary() public {\n        uint256[10][1] storage _x = getArray();\n        _x[0] = [21, 22, 23];\n    }\n\n    function partialAssignArrayCrossStorageBoundary() public {\n        uint256[10][1] storage _x = getArray();\n        _x[0] = [11, 12, 13, 14, 15, 16, 17];\n    }\n}\n// ----\n// x() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n// fillArray()\n// gas irOptimized: 220727\n// gas legacy: 221456\n// gas legacyOptimized: 220893\n// x() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n// partialAssignArrayCrossStorageBoundary()\n// x() -> 11, 12, 13, 14, 15, 16, 17, 0, 0, 0\n// partialAssignArrayBeforeStorageBoundary()\n// x() -> 21, 22, 23, 0, 0, 0, 0, 0, 0, 0\n// gas irOptimized: 44183\n// gas legacy: 46012\n// gas legacyOptimized: 43907\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_delete_overflow_bug.sol",
    "content": "contract C {\n    mapping(string => uint256[256][2**240]) m;\n\n    function getSlot() internal view returns (uint256) {\n        uint256[256][2**240] storage _x = m[\"v 2.2.3\"];\n        uint256 slot;\n        assembly {\n            slot := _x.slot\n        }\n        assert(slot == 0xffdb3f1d9f54eb0b5012935c286c508459d381405d269e01c15f4ec2826edbbf);\n        return slot;\n    }\n\n    function getIndex() internal view returns (uint256) {\n        uint256 slot = getSlot();\n        // Pick the largest index such that `slot + 256 * index` <= `2**256 - 1`\n        uint256 index = (type(uint256).max - slot) / 256;\n        assert(index <= type(uint240).max);\n        assert((type(uint256).max - slot + 1) % 256 != 0);\n\n        return index;\n    }\n\n    function getArray() internal view returns (uint256[256][2**240] storage _x) {\n        uint256 s = getSlot();\n        assembly {\n            _x.slot := s\n        }\n    }\n\n    function fillArray() public {\n        uint256[256][2**240] storage _x = getArray();\n        for (uint i = 1; i < 256; i++)\n            _x[getIndex()][i] = i;\n    }\n\n    function partialAssignArray() public {\n        uint256[256][2**240] storage _x = getArray();\n        _x[getIndex()] = [11, 22, 33, 44, 55, 66, 77, 88, 99];\n    }\n\n    function clearArray() public {\n        uint256[256][2**240] storage _x = getArray();\n        delete _x[getIndex()];\n    }\n\n    function x() public view returns (uint256[256] memory) {\n        return getArray()[getIndex()];\n    }\n}\n\n// ----\n// 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\n// gas irOptimized: 604108\n// gas legacy: 644983\n// gas legacyOptimized: 598016\n// fillArray()\n// gas irOptimized: 5782148\n// gas legacy: 6044562\n// gas legacyOptimized: 5853893\n// 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\n// gas irOptimized: 604108\n// gas legacy: 644983\n// gas legacyOptimized: 598016\n// partialAssignArray()\n// gas irOptimized: 1067376\n// gas legacy: 1177356\n// gas legacyOptimized: 1068067\n// 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\n// gas irOptimized: 604108\n// gas legacy: 644983\n// gas legacyOptimized: 598016\n// clearArray()\n// gas irOptimized: 580378\n// gas legacy: 582973\n// gas legacyOptimized: 581299\n// 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\n// gas irOptimized: 604108\n// gas legacy: 644983\n// gas legacyOptimized: 598016\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_packed_array.sol",
    "content": "contract C {\n    function getArray() internal pure returns (uint64[40][1] storage _x) {\n        assembly {\n            _x.slot := sub(0, 5)\n        }\n    }\n\n    function fillArray() public {\n        uint64[40][1] storage _x = getArray();\n        for (uint64 i = 1; i < 40; i++)\n            _x[0][i] = i;\n    }\n\n    function clearArray() public {\n        uint64[40][1] storage _x = getArray();\n        delete _x[0];\n    }\n\n    function x() public view returns (uint64[40] memory) {\n        return getArray()[0];\n    }\n}\n// ----\n// 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\n// fillArray()\n// gas irOptimized: 254227\n// gas legacy: 258712\n// gas legacyOptimized: 257258\n// 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\n// clearArray()\n// gas irOptimized: 57426\n// 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\n// gas irOptimized: 48087\n// gas legacy: 64080\n// gas legacyOptimized: 56602\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_struct_array_mixed_types.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint256 a;      // slot 0 (bytes 0-31)\n        uint128 b;      // slot 1 (bytes 0-15)\n        uint64 c;       // slot 1 (bytes 16-23)\n        bytes32 d;      // slot 2 (bytes 0-31)\n        bool e;         // slot 3 (byte 0)\n        // Total: 4 slots per struct\n    }\n\n    struct Canary {\n        uint256 value;\n    }\n\n    function getBoundaryArray() internal pure returns (S[10][1] storage arr) {\n        // 10 structs * 4 slots = 40 slots total\n        // Starts at -20, ends at slot 19\n        assembly {\n            arr.slot := sub(0, 20)\n        }\n    }\n\n    function getDest() internal pure returns (S[10][1] storage arr) {\n        assembly {\n            arr.slot := 21\n        }\n    }\n\n    function getCanary() internal pure returns (Canary storage canary) {\n        // Array ends at slot 19, canary at slot 20\n        assembly {\n            canary.slot := 20\n        }\n    }\n\n    constructor() {\n        Canary storage canary = getCanary();\n        canary.value = type(uint256).max;\n    }\n\n    function fillBoundaryArray() public {\n        S[10][1] storage arr = getBoundaryArray();\n        for (uint i = 0; i < 10; i++) {\n            arr[0][i] = S({\n                a: 1 + i * 5,\n                b: uint128(2 + i * 5),\n                c: uint64(3 + i * 5),\n                d: bytes32(uint256(4 + i * 5)),\n                e: true\n            });\n        }\n    }\n\n    function deleteBoundaryArray() public {\n        S[10][1] storage arr = getBoundaryArray();\n        delete arr[0];\n    }\n\n    function copyFromBoundary() public {\n        S[10][1] storage source = getBoundaryArray();\n        S[10][1] storage dest = getDest();\n        dest[0] = source[0];\n    }\n\n    function copyToBoundary() public {\n        S[10][1] storage source = getDest();\n        S[10][1] storage dest = getBoundaryArray();\n        dest[0] = source[0];\n    }\n\n    function fillDestArray() public {\n        S[10][1] storage dest = getDest();\n        for (uint i = 0; i < 10; i++) {\n            dest[0][i] = S({\n                a: 51 + i * 5,\n                b: uint128(52 + i * 5),\n                c: uint64(53 + i * 5),\n                d: bytes32(uint256(54 + i * 5)),\n                e: true\n            });\n        }\n    }\n\n    function boundaryArray() public view returns (S[10] memory) {\n        return getBoundaryArray()[0];\n    }\n\n    function destArray() public view returns (S[10] memory) {\n        return getDest()[0];\n    }\n\n    function canaryValue() public view returns (uint256) {\n        return getCanary().value;\n    }\n}\n// ----\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// gas irOptimized: 113169\n// gas legacy: 120742\n// gas legacyOptimized: 112518\n// 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\n// gas irOptimized: 113078\n// gas legacy: 120738\n// gas legacyOptimized: 112505\n// fillBoundaryArray()\n// gas irOptimized: 912522\n// gas legacy: 930728\n// gas legacyOptimized: 916628\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// gas irOptimized: 113169\n// gas legacy: 120742\n// gas legacyOptimized: 112518\n// 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\n// gas irOptimized: 113078\n// gas legacy: 120738\n// gas legacyOptimized: 112505\n// copyFromBoundary()\n// gas irOptimized: 994579\n// gas legacy: 1023407\n// gas legacyOptimized: 994746\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// gas irOptimized: 113169\n// gas legacy: 120742\n// gas legacyOptimized: 112518\n// 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\n// gas irOptimized: 113078\n// gas legacy: 120738\n// gas legacyOptimized: 112505\n// fillDestArray()\n// gas irOptimized: 200426\n// gas legacy: 218746\n// gas legacyOptimized: 204648\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// gas irOptimized: 113169\n// gas legacy: 120742\n// gas legacyOptimized: 112518\n// 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\n// gas irOptimized: 113078\n// gas legacy: 120738\n// gas legacyOptimized: 112505\n// copyToBoundary()\n// gas irOptimized: 282623\n// gas legacy: 311362\n// gas legacyOptimized: 282712\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// gas irOptimized: 113169\n// gas legacy: 120742\n// gas legacyOptimized: 112518\n// 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\n// gas irOptimized: 113078\n// gas legacy: 120738\n// gas legacyOptimized: 112505\n// deleteBoundaryArray()\n// gas irOptimized: 177968\n// gas legacy: 180995\n// gas legacyOptimized: 178182\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// gas irOptimized: 113169\n// gas legacy: 120742\n// gas legacyOptimized: 112518\n// 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\n// gas irOptimized: 113078\n// gas legacy: 120738\n// gas legacyOptimized: 112505\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_struct_array_multislot.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint256 b;\n        uint256 c;\n        // 3 slots per struct\n    }\n\n    struct Canary {\n        uint256 value;\n    }\n\n    function getBoundaryArray() internal pure returns (S[10][1] storage arr) {\n        // 10 structs, each 3 slots = 30 slots total\n        assembly {\n            arr.slot := sub(0, 15)\n        }\n    }\n\n    function getDest() internal pure returns (S[10][1] storage arr) {\n        assembly {\n            arr.slot := 16\n        }\n    }\n\n    function getCanary() internal pure returns (Canary storage canary) {\n        assembly {\n            canary.slot := 15\n        }\n    }\n\n    constructor() {\n        Canary storage canary = getCanary();\n        canary.value = type(uint256).max;\n    }\n\n    function fillBoundaryArray() public {\n        S[10][1] storage arr = getBoundaryArray();\n        for (uint i = 0; i < 10; i++) {\n            arr[0][i] = S({\n                a: 1 + i * 3,\n                b: 2 + i * 3,\n                c: 3 + i * 3\n            });\n        }\n    }\n\n    function deleteBoundaryArray() public {\n        S[10][1] storage arr = getBoundaryArray();\n        delete arr[0];\n    }\n\n    function copyFromBoundary() public {\n        S[10][1] storage source = getBoundaryArray();\n        S[10][1] storage dest = getDest();\n        dest[0] = source[0];\n    }\n\n    function copyToBoundary() public {\n        S[10][1] storage source = getDest();\n        S[10][1] storage dest = getBoundaryArray();\n        dest[0] = source[0];\n    }\n\n    function fillDestArray() public {\n        S[10][1] storage dest = getDest();\n        for (uint i = 0; i < 10; i++) {\n            dest[0][i] = S({\n                a: 31 + i * 3,\n                b: 32 + i * 3,\n                c: 33 + i * 3\n            });\n        }\n    }\n\n    function boundaryArray() public view returns (S[10] memory) {\n        return getBoundaryArray()[0];\n    }\n\n    function destArray() public view returns (S[10] memory) {\n        return getDest()[0];\n    }\n\n    function canaryValue() public view returns (uint256) {\n        return getCanary().value;\n    }\n}\n// ----\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n// fillBoundaryArray()\n// gas irOptimized: 688719\n// gas legacy: 700075\n// gas legacyOptimized: 691605\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n// copyFromBoundary()\n// gas irOptimized: 748779\n// gas legacy: 767297\n// gas legacyOptimized: 748756\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n// fillDestArray()\n// gas irOptimized: 175623\n// gas legacy: 187093\n// gas legacyOptimized: 178625\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n// copyToBoundary()\n// gas irOptimized: 235823\n// gas legacy: 254252\n// gas legacyOptimized: 235722\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n// deleteBoundaryArray()\n// gas irOptimized: 137824\n// gas legacy: 137971\n// gas legacyOptimized: 137750\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_boundary_struct_array_packed.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint64 a;\n        uint64 b;\n        uint64 c;\n        uint64 d;\n        // All fit in one slot (4 * 64 = 256 bits)\n    }\n\n    struct Canary {\n        uint256 value;\n    }\n\n    function getBoundaryArray() internal pure returns (S[10][1] storage arr) {\n        // 10 structs, each 1 slot = 10 slots total\n        assembly {\n            arr.slot := sub(0, 5)\n        }\n    }\n\n    function getDest() internal pure returns (S[10][1] storage arr) {\n        assembly {\n            arr.slot := 6\n        }\n    }\n\n    function getCanary() internal pure returns (Canary storage canary) {\n        // Array ends at slot 4, canary at slot 5\n        assembly {\n            canary.slot := 5\n        }\n    }\n\n    constructor() {\n        Canary storage canary = getCanary();\n        canary.value = type(uint256).max;\n    }\n\n    function fillBoundaryArray() public {\n        S[10][1] storage arr = getBoundaryArray();\n        for (uint i = 0; i < 10; i++) {\n            arr[0][i] = S({\n                a: uint64(1 + i * 4),\n                b: uint64(2 + i * 4),\n                c: uint64(3 + i * 4),\n                d: uint64(4 + i * 4)\n            });\n        }\n    }\n\n    function deleteBoundaryArray() public {\n        S[10][1] storage arr = getBoundaryArray();\n        delete arr[0];\n    }\n\n    function copyFromBoundary() public {\n        S[10][1] storage source = getBoundaryArray();\n        S[10][1] storage dest = getDest();\n        dest[0] = source[0];\n    }\n\n    function copyToBoundary() public {\n        S[10][1] storage source = getDest();\n        S[10][1] storage dest = getBoundaryArray();\n        dest[0] = source[0];\n    }\n\n    function fillDestArray() public {\n        S[10][1] storage dest = getDest();\n        for (uint i = 0; i < 10; i++) {\n            dest[0][i] = S({\n                a: uint64(41 + i * 4),\n                b: uint64(42 + i * 4),\n                c: uint64(43 + i * 4),\n                d: uint64(44 + i * 4)\n            });\n        }\n    }\n\n    function boundaryArray() public view returns (S[10] memory) {\n        return getBoundaryArray()[0];\n    }\n\n    function destArray() public view returns (S[10] memory) {\n        return getDest()[0];\n    }\n\n    function canaryValue() public view returns (uint256) {\n        return getCanary().value;\n    }\n}\n// ----\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n// fillBoundaryArray()\n// gas irOptimized: 248990\n// gas legacy: 272856\n// gas legacyOptimized: 253856\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n// copyFromBoundary()\n// gas irOptimized: 274279\n// gas legacy: 298927\n// gas legacyOptimized: 272256\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n// fillDestArray()\n// gas legacy: 101874\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n// gas legacy: 59729\n// copyToBoundary()\n// gas irOptimized: 103323\n// gas legacy: 127882\n// gas legacyOptimized: 101222\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n// deleteBoundaryArray()\n// canaryValue() -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// 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\n// 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\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/storage_packed_array_copy.sol",
    "content": "contract C {\n    bytes8[9] _x; // 4 per slot\n    bytes17[10] _y; // 1 per slot, no offset counter\n\n\tconstructor() {\n        for (uint256 i = 0; i < _x.length; ++i) _x[i] = bytes8(uint64(i));\n        _y[8] = _y[9] = bytes8(uint64(2));\n\t}\n\n    function getXAsUint() public view returns (uint64[9] memory result) {\n        for (uint i = 0; i < 9; i++) {\n            result[i] = uint64(_x[i]);\n        }\n    }\n\n    function getYAsUint() public view returns (uint64[10] memory result) {\n        for (uint i = 0; i < 10; i++) {\n            result[i] = uint64(bytes8(_y[i]));\n        }\n    }\n\n    function copy() public {\n        _y = _x;\n    }\n}\n\n// ----\n// getXAsUint() -> 0, 1, 2, 3, 4, 5, 6, 7, 8\n// getYAsUint() -> 0, 0, 0, 0, 0, 0, 0, 0, 2, 2\n// copy()\n// gas irOptimized: 190810\n// gas legacy: 195580\n// gas legacyOptimized: 190906\n// getXAsUint() -> 0, 1, 2, 3, 4, 5, 6, 7, 8\n// getYAsUint() -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storage/struct_accessor.sol",
    "content": "contract test {\n    struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n    mapping(uint => Data) public data;\n    constructor() {\n        data[7].a = 1;\n        data[7].b = 2;\n        data[7].c[0] = 3;\n        data[7].d = true;\n    }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/base_slot_max_value.sol",
    "content": "contract C layout at 2**256 - 1 {\n    function f(uint a) public pure returns (uint) {\n        return a * 2;\n    }\n}\n// ----\n// f(uint256): 4 -> 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/constructor.sol",
    "content": "contract A {\n    uint public x;\n}\n\ncontract B is A {\n    int8 public y;\n}\n\ncontract C is B layout at 7 {\n    uint32 public z;\n\n    constructor(uint _x, int8 _y, uint32 _z) {\n        x = _x + 1;\n        y = _y + 2;\n        z = _z + 3;\n    }\n\n}\n// ----\n// constructor(): 1, 2, 3\n// gas irOptimized: 104178\n// gas irOptimized code: 30000\n// gas legacy: 114749\n// gas legacy code: 71400\n// gas legacyOptimized: 106296\n// gas legacyOptimized code: 31400\n// x() -> 2\n// y() -> 4\n// z() -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/delete.sol",
    "content": "contract C layout at 42 {\n    uint[] public array;\n\n    function fillArray() public returns (uint) {\n        array.push(1);\n        array.push(2);\n        array.push(3);\n        return array.length;\n    }\n    function deleteLast() public {\n        delete array[array.length - 1];\n    }\n    function deleteArray() public {\n        delete array;\n    }\n    function arrayLength() public returns (uint) {\n        return array.length;\n    }\n}\n// ----\n// fillArray() -> 3\n// gas irOptimized: 111121\n// gas legacy: 110730\n// gas legacyOptimized: 110307\n// arrayLength() -> 3\n// array(uint256): 2 -> 3\n// deleteLast() ->\n// array(uint256): 2 -> 0\n// deleteArray() ->\n// arrayLength() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/delete_transient_storage.sol",
    "content": "contract C layout at 42 {\n    uint transient x;\n    address transient a;\n\n    function f() public {\n        g();\n        delete x;\n        delete a;\n        assert(x == 0);\n        assert(a == address(0));\n    }\n    function g() public {\n        x = 99;\n        a = address(0x1234);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/dynamic_array_storage_end.sol",
    "content": "contract C layout at 2**256 - 2 {\n    uint[] array;\n\n    function init() public {\n        for (uint i = 0; i < 1000; ++i)\n            array.push(i + 1);\n    }\n    function validate() public {\n        for (uint i = 0; i < 1000; ++i)\n            require(array[i] == i + 1);\n    }\n    function clear() public {\n        for (uint i = 0; i < 1000; ++i)\n            array.pop();\n    }\n}\n// ----\n// init() ->\n// gas irOptimized: 22738151\n// gas legacy: 22699167\n// gas legacyOptimized: 22541160\n// validate() ->\n// gas irOptimized: 2444232\n// gas legacy: 2560245\n// gas legacyOptimized: 2442238\n// clear() ->\n// gas irOptimized: 4449608\n// gas legacy: 4300019\n// gas legacyOptimized: 4302413\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/function_from_base_contract.sol",
    "content": "contract A {\n    uint public x;\n    function f() public returns (uint) {\n        x = x + 1;\n        return x;\n    }\n}\n\ncontract B is A {\n    uint public y;\n    function g() public virtual returns (uint) {\n        y = y + 2;\n        return y;\n    }\n}\n\ncontract C is B layout at 42 {\n    uint public z;\n    function test() public returns (uint){\n        z = super.g() + A.f();\n        return z;\n    }\n}\n// ----\n// f() -> 1\n// g() -> 2\n// test() -> 6\n// x() -> 2\n// y() -> 4\n// z() -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/getters.sol",
    "content": "contract C layout at 7 {\n    uint public x = 1;\n    int8 public y = 2;\n    uint32 public z = 3;\n}\n// ----\n// x() -> 1\n// y() -> 2\n// z() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_abstract_contract.sol",
    "content": "abstract contract A {\n    uint public x;\n}\n\ncontract C is A layout at 42 {\n    uint public y;\n    function f() public returns (uint) {\n        x = 12;\n        x = x - 4;\n        y = x + 2;\n        return y;\n    }\n}\n// ----\n// f() -> 10\n// x() -> 8\n// y() -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_interface.sol",
    "content": "interface I {\n    function f(uint x) external returns (uint);\n}\n\ncontract C is I layout at 42 {\n    uint public y;\n    function f(uint x) public returns (uint) {\n        x = x - 4;\n        y = x + 2;\n        return y;\n    }\n}\n// ----\n// f(uint256): 8 -> 6\n// y() -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_from_same_base_state_var_slots.sol",
    "content": "contract A {\n    uint public x;\n    function xSlot() public view returns (uint xs) {\n        assembly {\n            xs := x.slot\n        }\n    }\n}\n\ncontract B is A layout at 5 {\n    uint public y;\n    function xAndYSlots() public view returns (uint xs, uint ys) {\n        assembly {\n            xs := x.slot\n            ys := y.slot\n        }\n    }\n}\n\ncontract C is A layout at 9 {\n    uint public z;\n    function xAndZSlots() public view returns (uint xs, uint zs) {\n        assembly {\n            xs := x.slot\n            zs := z.slot\n        }\n    }\n}\n\ncontract Test {\n    A a = new A();\n    B b = new B();\n    C c = new C();\n    function contractASlots() public view returns (uint) {\n        return a.xSlot();\n    }\n    function contractBSlots() public view returns (uint, uint) {\n        return b.xAndYSlots();\n    }\n    function contractCSlots() public view returns (uint, uint) {\n        return c.xAndZSlots();\n    }\n}\n// ----\n// contractASlots() -> 0\n// contractBSlots() -> 5, 6\n// contractCSlots() -> 9, 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_simple.sol",
    "content": "contract A {\n    uint public x = 10;\n}\n\ncontract C is A layout at 42 {\n    uint public y;\n    function f() public returns (uint) {\n        x = x - 4;\n        y = x + 2;\n        return y;\n    }\n}\n// ----\n// f() -> 8\n// x() -> 6\n// y() -> 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/inheritance_state_variable_slot_offset.sol",
    "content": "contract A {\n    uint x;\n    uint128 y;\n}\n\ncontract C is A layout at 7 {\n    uint32 w;\n    uint z;\n\n    function xSlotOffset() public returns(uint s, uint o) { assembly { s := x.slot o := x.offset } }\n    function ySlotOffset() public returns(uint s, uint o) { assembly { s := y.slot o := y.offset } }\n    function wSlotOffset() public returns(uint s, uint o) { assembly { s := w.slot o := w.offset } }\n    function zSlotOffset() public returns(uint s, uint o) { assembly { s := z.slot o := z.offset } }\n}\n// ----\n// xSlotOffset() -> 7, 0\n// ySlotOffset() -> 8, 0\n// wSlotOffset() -> 8, 16\n// zSlotOffset() -> 9, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/inline_assembly_direct_load.sol",
    "content": "contract C layout at 42 {\n    uint public x;\n    function f() public returns (uint r) {\n        x = 16;\n        assembly {\n            r := sload(42)\n        }\n    }\n}\n// ----\n// f() -> 16\n// x() -> 16\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/inline_assembly_direct_store.sol",
    "content": "contract C layout at 42 {\n    uint public x;\n    function f() public returns (uint) {\n        assembly {\n            sstore(42, 16)\n        }\n        return x;\n    }\n}\n// ----\n// f() -> 16\n// x() -> 16\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/last_allowed_storage_slot.sol",
    "content": "contract C layout at 2**256 - 2 {\n    uint public x;\n    function f(uint a) public returns (uint) {\n        x = a * 2;\n        return x;\n    }\n}\n// ----\n// f(uint256): 4 -> 8\n// x() -> 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/mapping_storage_end.sol",
    "content": "contract C layout at 2**256 - 2 {\n    mapping(uint => uint) m;\n\n    function init() public {\n        for (uint i = 0; i < 1000; ++i)\n            m[i] = i + 1;\n    }\n\n    function validate() public {\n        for (uint i = 0; i < 1000; ++i)\n            require(m[i] == i + 1);\n    }\n}\n// ----\n// init() ->\n// gas irOptimized: 22266229\n// gas legacy: 22447245\n// gas legacyOptimized: 22310238\n// validate() ->\n// gas irOptimized: 2279210\n// gas legacy: 2456223\n// gas legacyOptimized: 2327216\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/multiple_inheritance.sol",
    "content": "contract A {\n    uint public x;\n    function f(uint a) public {\n        x = a;\n    }\n}\n\ncontract B is A {\n    uint public y;\n    function g(uint a) public {\n        f(x + a);\n        y = x + 1;\n    }\n}\n\ncontract C is B {\n    uint public w;\n    function h(uint a) public {\n        g(a);\n        w = x + y;\n    }\n}\n\ncontract D is A, B, C layout at 42 {\n    uint public z;\n    function test() public returns (uint, uint, uint, uint) {\n        h(1);\n        z = w + 2;\n        return (x, y, w, z);\n    }\n}\n// ----\n// test() -> 1, 2, 3, 5\n// gas irOptimized: 110112\n// gas legacy: 111881\n// gas legacyOptimized: 110945\n// x() -> 1\n// y() -> 2\n// w() -> 3\n// z() -> 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/multiple_inheritance_state_var_slots.sol",
    "content": "contract A {\n    uint x;\n}\n\ncontract B is A {\n    uint32 y;\n}\n\ncontract C is B {\n    uint160 w;\n}\n\ncontract D is A, B, C layout at 2 {\n    uint z;\n    function xSlotOffset() public view returns (uint s, uint o) { assembly { s := x.slot o := x.offset } }\n    function ySlotOffset() public view returns (uint s, uint o) { assembly { s := y.slot o := y.offset } }\n    function wSlotOffset() public view returns (uint s, uint o) { assembly { s := w.slot o := w.offset } }\n    function zSlotOffset() public view returns (uint s, uint o) { assembly { s := z.slot o := z.offset } }\n}\n// ----\n// xSlotOffset() -> 2, 0\n// ySlotOffset() -> 3, 0\n// wSlotOffset() -> 3, 4\n// zSlotOffset() -> 4, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_arithmetic_expression.sol",
    "content": "contract C layout at 7 {\n    uint public x;\n    uint public y;\n    uint public z;\n\n    function f(uint a) public returns (uint) {\n        x = x + a;\n        y = y + x;\n        z = y - 2;\n\n        return z;\n    }\n}\n// ----\n// f(uint256): 2 -> 0\n// f(uint256): 3 -> 5\n// f(uint256): 5 -> 15\n// x() -> 10\n// y() -> 17\n// z() -> 15\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_constant_and_immutable.sol",
    "content": "contract C layout at 42 {\n    uint constant x = 10;\n    uint immutable y = 100;\n\n    function f() public view returns (uint) {\n        require(x > 9);\n        return x + 1;\n    }\n    function g() public view returns (uint) {\n        require(y > 99);\n        return y * 2;\n    }\n}\n// ----\n// f() -> 11\n// g() -> 200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_dynamic_array.sol",
    "content": "contract A {\n    uint[] public arrayA;\n}\n\ncontract C is A layout at 42 {\n    uint[] public arrayC;\n\n    function initA() public returns (uint, uint, uint) {\n        arrayA.push(1);\n        arrayA.push(2);\n        arrayA.push(3);\n\n        return (arrayA[0], arrayA[1], arrayA[2]);\n    }\n    function initCFromAInReverse() public returns (uint, uint, uint) {\n        arrayC = new uint[](3);\n        arrayC[0] = arrayA[2];\n        arrayC[1] = arrayA[1];\n        arrayC[2] = arrayA[0];\n\n        return (arrayC[0], arrayC[1], arrayC[2]);\n    }\n    function clearA () public {\n        arrayA.pop();\n        arrayA.pop();\n        arrayA.pop();\n    }\n    function arrayALength() public returns (uint) {\n        return arrayA.length;\n    }\n    function arrayCLength() public returns (uint) {\n        return arrayC.length;\n    }\n}\n// ----\n// initA() -> 1, 2, 3\n// gas irOptimized: 111986\n// gas legacy: 111679\n// gas legacyOptimized: 111150\n// arrayA(uint256): 0 -> 1\n// arrayALength() -> 3\n// arrayCLength() -> 0\n// initCFromAInReverse() -> 3, 2, 1\n// gas irOptimized: 121281\n// gas legacy: 121937\n// gas legacyOptimized: 120853\n// clearA() ->\n// arrayC(uint256): 0 -> 3\n// arrayALength() -> 0\n// arrayCLength() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_enum.sol",
    "content": "enum Color {Red, Blue, Green }\ncontract C layout at 42 {\n    Color c;\n    function cSlotOffset() public returns(uint s, uint o) {\n        assembly { s := c.slot o := c.offset }\n    }\n    function setBlue() public {\n        c = Color.Blue;\n    }\n    function checkBlue() public view returns (bool) {\n        return c == Color.Blue;\n    }\n}\n// ----\n// cSlotOffset() -> 42, 0\n// checkBlue() -> false\n// setBlue() ->\n// checkBlue() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_mapping.sol",
    "content": "contract A {\n    mapping(uint => bool) locked;\n}\ncontract C layout at 42 is A {\n    mapping(uint => string) rooms;\n\n    function setup() public {\n        locked[0] = true;\n        locked[1] = false;\n        locked[2] = true;\n        locked[3] = false;\n\n        rooms[0] = \"Empty\";\n        rooms[1] = \"Monster\";\n        rooms[2] = \"Treasure\";\n        rooms[3] = \"Empty\";\n    }\n    function open(uint x) public view returns (string memory) {\n        if (locked[x])\n            return \"Locked\";\n\n        require(!locked[x]);\n        return rooms[x];\n    }\n}\n// ----\n// setup() ->\n// gas irOptimized: 159082\n// gas legacy: 161738\n// gas legacyOptimized: 160218\n// open(uint256): 3 -> 0x20, 5, \"Empty\"\n// open(uint256): 2 -> 0x20, 6, \"Locked\"\n// open(uint256): 1 -> 0x20, 7, \"Monster\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_reference_types_slot_offset.sol",
    "content": "struct S {\n    uint x;\n    address a;\n    bool b;\n}\n\ncontract A {\n    S public s1;\n    uint transient t1;\n}\n\ncontract C is A layout at 42 {\n    uint transient t2;\n    S[][5] dArray;\n    uint[10][2] sArray;\n    bytes bArray;\n    string str;\n\n\n    function s1SlotOffset() public returns (uint s, uint o)     { assembly { s:= s1.slot     o:= s1.offset } }\n    function dArraySlotOffset() public returns (uint s, uint o) { assembly { s:= dArray.slot o:= dArray.offset } }\n    function sArraySlotOffset() public returns (uint s, uint o) { assembly { s:= sArray.slot o:= sArray.offset } }\n    function bArraySlotOffset() public returns (uint s, uint o) { assembly { s:= bArray.slot o:= bArray.offset } }\n    function strSlotOffset() public returns (uint s, uint o)    { assembly { s:= str.slot    o:= str.offset } }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// s1SlotOffset() -> 42, 0\n// dArraySlotOffset() -> 44, 0\n// sArraySlotOffset() -> 49, 0\n// bArraySlotOffset() -> 69, 0\n// strSlotOffset() -> 70, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_slot_offset.sol",
    "content": "contract C layout at 7 {\n    int8 public x;\n    int32 public y;\n    uint256 public z;\n\n    function xSlotOffset() public returns(uint s, uint o) { assembly { s := x.slot o := x.offset } }\n    function ySlotOffset() public returns(uint s, uint o) { assembly { s := y.slot o := y.offset } }\n    function zSlotOffset() public returns(uint s, uint o) { assembly { s := z.slot o := z.offset } }\n}\n// ----\n// xSlotOffset() -> 7, 0\n// ySlotOffset() -> 7, 1\n// zSlotOffset() -> 8, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/state_variable_struct.sol",
    "content": "struct S {\n    uint x;\n    address a;\n    bool b;\n}\n\ncontract A {\n    S public s1;\n    uint transient t1;\n}\n\ncontract C is A layout at 42 {\n    uint y;\n    uint8 z;\n    uint transient t2;\n    S public s2;\n\n    function initS1() public returns (uint, address, bool) {\n        s1.x = 7;\n        s1.a = address(0xABC);\n        s1.b = true;\n\n        return (s1.x, s1.a, s1.b);\n    }\n    function initS2() public returns (uint, address, bool) {\n        s2.x = 8;\n        s2.a = address(0xDEF);\n        s2.b = false;\n\n        return (s2.x, s2.a, s2.b);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// initS1() -> 7, 0x0abc, 1\n// initS2() -> 8, 0x0def, 0\n// s1() -> 7, 0x0abc, 1\n// s2() -> 8, 0x0def, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/state_variables_transient.sol",
    "content": "contract C layout at 42 {\n    int x;\n    bool transient lock;\n\n    function test() public returns(int) {\n        x = -1;\n        lock = true;\n        f();\n        return x;\n    }\n    function f() private {\n        lock = false;\n        setX();\n    }\n    function setX() private {\n        require(!lock);\n        x = 2;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> 2"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_array.sol",
    "content": "contract C layout at 42 {\n    uint[] public array;\n    function initUsingReference() public {\n        uint[] storage ptr = array;\n        for(uint i = 0; i < 10; ++i)\n            ptr.push(i + 1);\n\n        validate(array);\n    }\n    function validate(uint[] memory ptr) public pure {\n        for(uint i = 0; i < 10; ++i)\n            require(ptr[i] == i + 1);\n    }\n}\n// ----\n// initUsingReference() ->\n// gas irOptimized: 273556\n// gas legacy: 274795\n// gas legacyOptimized: 271954\n// array(uint256): 0 -> 1\n// array(uint256): 9 -> 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_inheritance.sol",
    "content": "pragma abicoder v2;\ncontract A {\n    struct S {\n        uint x;\n        bool b;\n    }\n    S public s;\n}\n\ncontract C is A layout at 42 {\n    function InitUsingReference() public {\n        S storage ptr = s;\n        ptr.x = 2;\n        ptr.b = true;\n\n        validate(s);\n    }\n    function validate(S memory ptr) public pure {\n        require(ptr.x == 2);\n        require(ptr.b);\n    }\n}\n// ----\n// InitUsingReference() ->\n// s() -> 2, true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/storage_reference_library_function.sol",
    "content": "pragma abicoder v2;\n\nstruct S {\n    uint x;\n    bool b;\n}\n\nlibrary L {\n    function validate(S memory ptr) public {\n        require(ptr.x == 2);\n        require(ptr.b);\n    }\n}\n\ncontract A {\n    S public s;\n}\n\ncontract C is A layout at 42 {\n    function initUsingReference() public {\n        S storage ptr = s;\n        ptr.x = 2;\n        ptr.b = true;\n\n        L.validate(s);\n    }\n}\n// ----\n// library: L\n// initUsingReference() ->\n// s() -> 2, true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/transient_state_variable_slot_offset.sol",
    "content": "contract C layout at 7 {\n    int transient x;\n    int y;\n    uint transient w;\n    uint256 z;\n\n    function xSlotOffset() public returns(uint s, uint o) { assembly { s := x.slot o := x.offset } }\n    function ySlotOffset() public returns(uint s, uint o) { assembly { s := y.slot o := y.offset } }\n    function wSlotOffset() public returns(uint s, uint o) { assembly { s := w.slot o := w.offset } }\n    function zSlotOffset() public returns(uint s, uint o) { assembly { s := z.slot o := z.offset } }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// xSlotOffset() -> 0, 0\n// ySlotOffset() -> 7, 0\n// wSlotOffset() -> 1, 0\n// zSlotOffset() -> 8, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/variable_cleanup.sol",
    "content": "contract C layout at 42 {\n    uint8 x;\n    int8 y;\n    bytes2 b;\n    // Note the return types are larger than the state variable ones\n    function f(uint _x, int _y, bytes3 _b) public returns (uint16, int32, bytes32) {\n        x = uint8(_x);\n        y = int8(_y);\n        b = bytes2(_b);\n        require(b == \"ab\");\n        return (x, y, b);\n    }\n}\n// ----\n// f(uint256,int256,bytes3): 0x0100, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f, \"abc\" -> 0x00, 0x7f, \"ab\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/variable_cleanup_sstore.sol",
    "content": "contract C layout at 42 {\n    uint8 x;\n    int8 y;\n    bytes2 b;\n    // Note the return types are larger than the state variable ones\n    function f() public returns (uint16, int32, bytes16) {\n        uint32 z = 0;\n        z = z | 0x10;\n        z = z | 0x7f00;\n        z = z | 0x61620000;\n\n        assembly {\n            sstore(x.slot, z)\n        }\n        require(b == \"ab\");\n        return (x, y, b);\n    }\n}\n// ----\n// f() -> 0x10, 127, \"ab\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/storageLayoutSpecifier/virtual_functions.sol",
    "content": "abstract contract A {\n    uint public x;\n    function f() public virtual returns (uint);\n}\n\ncontract B is A {\n    uint public y;\n    function f() public override returns (uint) {\n        x = 1;\n        return x;\n    }\n    function g() public virtual returns (uint) {\n        return y;\n    }\n}\n\ncontract C is B layout at 42 {\n    uint public z;\n    function g() public override returns (uint) {\n        y = x + 2;\n        return y;\n    }\n    function h() public returns (uint) {\n        z = g() + 3;\n        return z;\n    }\n}\n// ----\n// f() -> 1\n// g() -> 3\n// h() -> 6\n// x() -> 1\n// y() -> 3\n// z() -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/concat/string_concat_2_args.sol",
    "content": "contract C {\n    function f(string memory a, string memory b) public returns (string memory) {\n        return string.concat(a, b);\n    }\n}\n// ----\n// f(string,string): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// f(string,string): 0x40, 0xa0, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 0x45, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// f(string,string): 0x40, 0x80, 3, \"abc\", 3, \"def\" -> 0x20, 6, \"abcdef\"\n// f(string,string): 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 30, \"cdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x40, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364\n// f(string,string): 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 34, \"cdabcdabcdabcdabcdabcdabcdabcdab\", \"cd\" -> 0x20, 0x44, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364, 44048183293808120317390542201052832727062033572611867748297851798484192067584\n// f(string,string): 0x40, 0x80, 3, \"abc\", 30, \"dabcdabcdabcdabcdabcdabcdabcda\" -> 0x20, 0x21, 0x6162636461626364616263646162636461626364616263646162636461626364, 43874346312576839672212443538448152585028080127215369968075725190498334277632\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/concat/string_concat_different_types.sol",
    "content": "contract C{\n    string s = \"bcdef\";\n\n    function f(string memory a) public returns (string memory) {\n        return string.concat(a, \"bcdef\");\n    }\n    function g(string calldata a) public returns (string memory) {\n        return string.concat(a, \"abcdefghabcdefghabcdefghabcdefghab\");\n    }\n    function h(string calldata a) public returns (string memory) {\n        return string.concat(a, s);\n    }\n    function j(string calldata a) public returns (string memory) {\n        string storage ref = s;\n        return string.concat(a, ref, s);\n    }\n    function k(string calldata a, bytes memory b) public returns (string memory) {\n        return string.concat(a, string(b));\n    }\n    function slice(string calldata a) public returns (string memory) {\n        require(bytes(a).length > 2, \"\");\n        return string.concat(a[:2], a[2:]);\n    }\n    function strParam(bytes calldata a) public returns (string memory) {\n        return string.concat(string(a), \"bcdef\");\n    }\n}\n// ----\n// f(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// g(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x42, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636465666768616263646566676861626364656667686162636465666768, 44047497324925121336511606693520958599579173549109180625971642598225011015680\n// h(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// j(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x2a, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928944786876717917111204727192787026596791669343131645116682757734400\n// k(string,bytes): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// slice(string): 0x20, 4, \"abcd\" -> 0x20, 4, \"abcd\"\n// strParam(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/concat/string_concat_empty_argument_list.sol",
    "content": "contract C {\n    function f() public returns (string memory) {\n        return string.concat();\n    }\n}\n// ----\n// f() -> 0x20, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/concat/string_concat_empty_strings.sol",
    "content": "contract C {\n    function f() public returns (string memory) {\n        string memory b = \"\";\n        return string.concat(\n            string.concat(b),\n            string.concat(b, b),\n            string.concat(\"\", b),\n            string.concat(b, \"\")\n        );\n    }\n\n    function g() public returns (string memory) {\n        return string.concat(\"\", \"abc\", hex\"\", \"abc\", unicode\"\");\n    }\n\n    function h() public returns (string memory) {\n        string memory b = \"\";\n        return string.concat(b, \"abc\", b, \"abc\", b);\n    }\n}\n// ----\n// f() -> 0x20, 0\n// g() -> 0x20, 6, \"abcabc\"\n// h() -> 0x20, 6, \"abcabc\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/concat/string_concat_nested.sol",
    "content": "contract C {\n    function f(string memory a, string memory b, string memory c) public returns (string memory) {\n        return string.concat(string.concat(a, b), c);\n    }\n}\n// ----\n// f(string,string,string): 0x60, 0x60, 0x60, 2, \"ab\" -> 0x20, 6, \"ababab\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/constant_string_literal.sol",
    "content": "contract Test {\n    bytes32 constant public b = \"abcdefghijklmnopq\";\n    string constant public x = \"abefghijklmnopqabcdefghijklmnopqabcdefghijklmnopqabca\";\n\n    constructor() {\n        string memory xx = x;\n        bytes32 bb = b;\n    }\n    function getB() public returns (bytes32) { return b; }\n    function getX() public returns (string memory) { return x; }\n    function getX2() public returns (string memory r) { r = x; }\n    function unused() public returns (uint) {\n        \"unusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunused\";\n        return 2;\n    }\n}\n// ----\n// b() -> 0x6162636465666768696a6b6c6d6e6f7071000000000000000000000000000000\n// x() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096\n// getB() -> 0x6162636465666768696a6b6c6d6e6f7071000000000000000000000000000000\n// getX() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096\n// getX2() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096\n// unused() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/empty_storage_string.sol",
    "content": "contract C {\n\n    string uninitializedString;\n    string emptyString = \"\";\n    string nonEmptyString = \"This is a non empty string\";\n    string nonEmptyString2 = \"Another string\";\n    bytes uninitializedBytes;\n    bytes emptyBytes = \"\";\n    error EmptyError(string);\n    event EmptyEvent(string);\n\n    function f() public returns (string memory) {\n        return uninitializedString;\n    }\n\n    function g() public returns (string memory, string memory) {\n        return (uninitializedString, emptyString);\n    }\n\n    function h() public returns (string memory, string memory) {\n        return (uninitializedString, nonEmptyString);\n    }\n\n    function i() public returns (string memory, string memory) {\n        return (nonEmptyString, emptyString);\n    }\n\n    function j(string calldata _s) public returns (string memory) {\n        return _s;\n    }\n\n    function k() public returns (string memory) {\n        nonEmptyString2 = \"\";\n        return nonEmptyString2;\n    }\n\n    function l(string calldata _s) public returns (bytes memory) {\n        return abi.encode(_s);\n    }\n\n    function m() public returns (string memory) {\n        bytes memory b = abi.encode(emptyString);\n        return string(b);\n    }\n\n    function n() public {\n        revert EmptyError(uninitializedString);\n    }\n\n    function o() public {\n        emit EmptyEvent(emptyString);\n    }\n\n    function p() public {\n        emit EmptyEvent(\"\");\n    }\n\n    function q() public returns (bytes memory) {\n        return uninitializedBytes;\n    }\n\n    function r() public returns (bytes memory) {\n        emptyBytes = abi.encode(\"\");\n        return emptyBytes;\n    }\n\n    function s() public returns (bytes memory) {\n        emptyBytes = abi.encode(uninitializedString);\n        return emptyBytes;\n    }\n\n    function set(string calldata _s) public {\n        nonEmptyString = _s;\n    }\n\n    function get() public returns (string memory) {\n        return nonEmptyString;\n    }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() -> 0x20, 0\n// g() -> 0x40, 0x60, 0, 0\n// h() -> 0x40, 0x60, 0, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328\n// i() -> 0x40, 0x80, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328, 0\n// j(string): 0x20, 0, \"\" -> 0x20, 0\n// k() -> 0x20, 0\n// l(string): 0x20, 0, \"\" -> 0x20, 0x40, 0x20, 0\n// m() -> 0x20, 0x40, 0x20, 0\n// n() -> FAILURE, hex\"d3f13430\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000000\"\n// o() ->\n// ~ emit EmptyEvent(string): 0x20, 0x00\n// p() ->\n// ~ emit EmptyEvent(string): 0x20, 0x00\n// q() -> 0x20, 0\n// r() -> 0x20, 0x40, 0x20, 0\n// s() -> 0x20, 0x40, 0x20, 0\n// set(string): 0x20, 0, \"\" ->\n// get() -> 0x20, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/empty_string.sol",
    "content": "contract C {\n    function f() public pure returns (string memory) {\n        return \"\";\n    }\n}\n// ----\n// f() -> 0x20, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/empty_string_input.sol",
    "content": "contract C {\n    function f() public pure returns (string memory) {\n        return \"\";\n    }\n    function g(string calldata msg) public pure returns (string memory) {\n        return msg;\n    }\n    function h(string calldata msg, uint256 v) public pure returns (string memory, uint256) {\n        return (msg, v);\n    }\n    // Adjusting order of input/output intentionally.\n    function i(string calldata msg1, uint256 v, string calldata msg2) public pure returns (string memory, string memory, uint256) {\n        return (msg1, msg2, v);\n    }\n    function j(string calldata msg1, uint256 v) public pure returns (string memory, string memory, uint256) {\n        return (msg1, \"\", v);\n    }\n}\n// ----\n// f() -> 0x20, 0\n// g(string): 0x20, 0, \"\" -> 0x20, 0\n// g(string): 0x20, 0 -> 0x20, 0\n// h(string,uint256): 0x40, 0x888, 0, \"\" -> 0x40, 0x0888, 0\n// h(string,uint256): 0x40, 0x888, 0 -> 0x40, 0x0888, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0 -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0 -> 0x60, 0x80, 0x0888, 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/return_string.sol",
    "content": "contract Main {\n    string public s;\n    function set(string calldata _s) external {\n        s = _s;\n    }\n    function get1() public returns (string memory r) {\n        return s;\n    }\n    function get2() public returns (string memory r) {\n        r = s;\n    }\n}\n// ----\n// set(string): 0x20, 5, \"Julia\" ->\n// get1() -> 0x20, 5, \"Julia\"\n// get2() -> 0x20, 5, \"Julia\"\n// s() -> 0x20, 5, \"Julia\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/string_escapes.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = \"\\t\\n\\r\\'\\\"\\\\\";\n        return escapeCharacters;\n    }\n}\n// ----\n// f() -> 0x090a0d27225c0000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/unicode_escapes.sol",
    "content": "contract C {\n    function oneByteUTF8() public pure returns (string memory) {\n        return \"aaa\\u0024aaa\"; // usdollar\n    }\n\n    function twoBytesUTF8() public pure returns (string memory) {\n        return \"aaa\\u00A2aaa\"; // cent\n    }\n\n    function threeBytesUTF8() public pure returns (string memory) {\n        return \"aaa\\u20ACaaa\"; // euro\n    }\n\n    function combined() public pure returns (string memory) {\n        return \"\\u0024\\u00A2\\u20AC\";\n    }\n}\n// ----\n// oneByteUTF8() -> 0x20, 7, \"aaa$aaa\"\n// twoBytesUTF8() -> 0x20, 8, \"aaa\\xc2\\xa2aaa\"\n// threeBytesUTF8() -> 0x20, 9, \"aaa\\xe2\\x82\\xacaaa\"\n// combined() -> 0x20, 6, \"$\\xc2\\xa2\\xe2\\x82\\xac\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/strings/unicode_string.sol",
    "content": "contract C {\n    function f() public pure returns (string memory) {\n        return unicode\"😃, 😭, and 😈\";\n    }\n    function g() public pure returns (string memory) {\n        return unicode\"😃, 😭,\\\n and 😈\";\n    }\n}\n// ----\n// f() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n// g() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/array_of_recursive_struct.sol",
    "content": "contract Test {\n    struct RecursiveStruct {\n        RecursiveStruct[] vals;\n    }\n\n    function func() public pure {\n        RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n        assert(val[0].vals.length == 42);\n    }\n}\n// ----\n// func() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_nested_structs.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint128 p1;\n        uint256[][2] a;\n        uint32 p2;\n    }\n\n    struct S1 {\n        uint128 u;\n        S s;\n    }\n\n    struct S2 {\n        S[2] array;\n    }\n\n    function f1(S1 calldata c) internal returns(S1 calldata) {\n        return c;\n    }\n\n    function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n        S1 memory m = f1(c);\n        assert(m.s.a[0][0] == c.s.a[0][0]);\n        assert(m.s.a[1][1] == c.s.a[1][1]);\n        return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n    }\n\n    function g(S2 calldata c) external returns(uint128, uint256, uint256, uint32) {\n        S2 memory m = c;\n        assert(m.array[0].a[0][0] == c.array[0].a[0][0]);\n        assert(m.array[0].a[1][1] == c.array[0].a[1][1]);\n        return (m.array[1].p1, m.array[1].a[0][0], m.array[1].a[1][1], m.array[1].p2);\n    }\n\n    function h(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n        S memory m = c.s;\n        assert(m.a[0][0] == c.s.a[0][0]);\n        assert(m.a[1][1] == c.s.a[1][1]);\n        return (p, m.p1, m.a[0][0], m.a[1][1], m.p2);\n    }\n}\n// ----\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n// g(((uint128,uint256[][2],uint32)[2])): 0x20, 0x20, 0x40, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 22, 1, 2, 33\n// h((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint256 b;\n    }\n\n    function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n        a = s.a;\n        b = s.b;\n    }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_and_ints.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint256 b;\n    }\n\n    function f(uint256 a, S calldata s, uint256 b)\n        external\n        pure\n        returns (uint256, uint256, uint256, uint256)\n    {\n        return (a, s.a, s.b, b);\n    }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_array_member.sol",
    "content": "pragma abicoder v2;\n\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint256[2] b;\n        uint256 c;\n    }\n\n    function f(S calldata s)\n        external\n        pure\n        returns (uint256 a, uint256 b0, uint256 b1, uint256 c)\n    {\n        a = s.a;\n        b0 = s.b[0];\n        b1 = s.b[1];\n        c = s.c;\n    }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_array_member_dynamic.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint32 a;\n        uint256[] b;\n        uint64 c;\n    }\n\n    function f(S calldata s)\n        external\n        pure\n        returns (uint32 a, uint256 b0, uint256 b1, uint64 c)\n    {\n        a = s.a;\n        b0 = s.b[0];\n        b1 = s.b[1];\n        c = s.c;\n    }\n}\n// ----\n// f((uint32,uint256[],uint64)): 0x20, 42, 0x60, 23, 2, 1, 2 -> 42, 1, 2, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_as_argument_of_lib_function.sol",
    "content": "pragma abicoder v2;\n\nstruct S {\n    uint128 p1;\n    uint256[][2] a;\n    uint32 p2;\n}\nstruct S1 {\n    uint128 u;\n    S s;\n}\n\nlibrary L {\n    function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n        return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n    }\n}\n\ncontract C {\n\n    function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n        return L.f(c, p);\n    }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_as_memory_argument.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint128 p1;\n        uint256[][2] a;\n        uint32 p2;\n    }\n\n    function g(uint32 p1, S memory s) internal returns(uint32, uint128, uint256, uint256, uint32) {\n        s.p1++;\n        s.a[0][1]++;\n        return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n    }\n\n    function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n        return g(p1, c);\n    }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_struct_member.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint64 a;\n        uint64 b;\n    }\n    struct S1 {\n        uint256 a;\n        S s;\n        uint256 c;\n    }\n\n    function f(S1 calldata s1)\n        external\n        pure\n        returns (uint256 a, uint64 b0, uint64 b1, uint256 c)\n    {\n        a = s1.a;\n        b0 = s1.s.a;\n        b1 = s1.s.b;\n        c = s1.c;\n    }\n}\n// ----\n// f((uint256,(uint64,uint64),uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_struct_member_dynamic.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint64 a;\n        bytes b;\n    }\n    struct S1 {\n        uint256 a;\n        S s;\n        uint256 c;\n    }\n\n    function f(S1 calldata s1)\n        external\n        pure\n        returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n    {\n        a = s1.a;\n        b0 = s1.s.a;\n        b1 = s1.s.b[0];\n        c = s1.c;\n    }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint256 b;\n        bytes2 c;\n    }\n\n    function f(S calldata s) external pure returns (uint256, uint256, bytes1) {\n        S memory m = s;\n        return (m.a, m.b, m.c[1]);\n    }\n}\n// ----\n// f((uint256,uint256,bytes2)): 42, 23, \"ab\" -> 42, 23, \"b\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_to_memory_tuple_assignment.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint128 p1;\n        uint256[][2] a;\n        uint32 p2;\n    }\n\n    function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n        S memory m;\n        uint32 p2;\n        (p2, m) = (p1, c);\n        m.p1++;\n        m.a[0][1]++;\n        return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n    }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_to_storage.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint64 b;\n        bytes2 c;\n    }\n\n    uint[153] r;\n    S s;\n\n    function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n        s = c;\n        return (s.a, s.b, s.c[1]);\n    }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_array_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint256 a;\n        uint256[2] b;\n        uint256 c;\n    }\n\n    function f(S calldata c)\n        external\n        pure\n        returns (uint256, uint256, uint256, uint256)\n    {\n        S memory m = c;\n        return (m.a, m.b[0], m.b[1], m.c);\n    }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_bytes_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint256 a;\n        bytes b;\n        uint256 c;\n    }\n\n    function f(S calldata c)\n        external\n        pure\n        returns (uint256, bytes1, bytes1, uint256)\n    {\n        S memory m = c;\n        return (m.a, m.b[0], m.b[1], m.c);\n    }\n}\n// ----\n// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, \"ab\" -> 42, \"a\", \"b\", 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint128 p1;\n        uint256[][2] a;\n        uint32 p2;\n    }\n    function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n        S memory s = c;\n        assert(s.a[0][0] == c.a[0][0]);\n        assert(s.a[1][1] == c.a[1][1]);\n        s.p1++;\n        assert(s.p1 != c.p1);\n        s.a[0][1]++;\n        assert(s.a[0][1] != c.a[0][1]);\n        return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n    }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint128 p1;\n        uint256[][2] a;\n        uint32 p2;\n    }\n    S s;\n    function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n        s = c;\n        assert(s.a[0][0] == c.a[0][0]);\n        assert(s.a[1][1] == c.a[1][1]);\n        return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n    }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/calldata_structs.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    struct S1 {\n        uint256 a;\n        uint256 b;\n    }\n    struct S2 {\n        uint256 a;\n    }\n\n    function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n        external\n        pure\n        returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n    {\n        a = s1.a;\n        b = s1.b;\n        c = s2.a;\n        d = s3.a;\n        e = s3.b;\n    }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/dynamic_nested.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/calldata/dynamically_encoded.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct S { uint256[] a; }\n\tfunction f(S calldata s) external pure returns (uint256 a, uint256 b, uint256 c) {\n\t    return (s.a.length, s.a[0], s.a[1]);\n\t}\n}\n// ----\n// f((uint256[])): 32, 32, 2, 42, 23 -> 2, 42, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol",
    "content": "contract CopyTest {\n    struct Tree {\n        Tree[] children;\n    }\n\n    Tree storageTree;\n    Tree[] children;\n\n    constructor() {\n        for (uint i = 0; i < 2; i++)\n            storageTree.children.push();\n        for (uint i = 0; i < 23; i++)\n            storageTree.children[0].children.push();\n        for (uint i = 0; i < 42; i++)\n            storageTree.children[1].children.push();\n    }\n\n    function run() public returns (uint256, uint256, uint256) {\n        Tree memory memoryTree;\n        memoryTree = storageTree;\n        return (memoryTree.children.length, memoryTree.children[0].children.length, memoryTree.children[1].children.length);\n    }\n}\n// ----\n// run() -> 2, 23, 42\n// gas irOptimized: 192828\n// gas legacy: 185730\n// gas legacyOptimized: 184457\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory_complex.sol",
    "content": "contract CopyTest {\n    struct Tree {\n        uint256 data;\n        Tree[] children;\n    }\n    Tree storageTree;\n    Tree childStorageTree;\n\n    constructor() {\n        storageTree.data = 0x42;\n        for (uint i = 0; i < 2; i++)\n            storageTree.children.push(childStorageTree);\n        storageTree.children[0].data = 0x4200;\n        storageTree.children[1].data = 0x4201;\n        for (uint i = 0; i < 3; i++)\n            storageTree.children[0].children.push(childStorageTree);\n        for (uint i = 0; i < 3; i++)\n            storageTree.children[0].children[i].data = 0x420000 + i;\n        for (uint i = 0; i < 4; i++)\n            storageTree.children[1].children.push(childStorageTree);\n        for (uint i = 0; i < 4; i++)\n            storageTree.children[1].children[i].data = 0x420100 + i;\n    }\n\n    function countData(Tree memory tree) internal returns (uint256 c) {\n        c = 1;\n        for (uint i = 0; i < tree.children.length; i++) {\n            c += countData(tree.children[i]);\n        }\n    }\n\n    function copyFromTree(Tree memory tree, uint256[] memory data, uint256 offset) internal returns (uint256) {\n        data[offset++] = tree.data;\n        for (uint i = 0; i < tree.children.length; i++) {\n            offset = copyFromTree(tree.children[i], data, offset);\n        }\n        return offset;\n    }\n\n    function run() public returns (uint256[] memory) {\n        Tree memory memoryTree;\n        memoryTree = storageTree;\n        uint256 length = countData(memoryTree);\n        uint256[] memory result = new uint256[](length);\n        copyFromTree(memoryTree, result, 0);\n        return result;\n    }\n}\n// ----\n// run() -> 0x20, 10, 0x42, 0x4200, 0x420000, 0x420001, 0x420002, 0x4201, 0x420100, 0x420101, 0x420102, 0x420103\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/copy_from_mapping.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        bytes b;\n        uint16[] a;\n        uint16 u;\n    }\n\n    constructor() {\n        uint16[] memory a = new uint16[](2);\n        a[0] = 13;\n        a[1] = 14;\n\n        m[7] = S({b: \"foo\", a: a, u: 7});\n    }\n\n    mapping (uint => S) m;\n    S s;\n\n    function to_state() public returns (S memory) {\n\ts = m[7];\n        return s;\n    }\n\n    function to_storage() public returns (S memory) {\n        S storage sLocal = s;\n\tsLocal = m[7];\n        return sLocal;\n    }\n\n    function to_memory() public returns (S memory) {\n\treturn m[7];\n    }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 125480\n// gas legacyOptimized: 121695\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/copy_from_storage.sol",
    "content": "pragma abicoder v2;\n// Example from https://github.com/argotorg/solidity/issues/12558\nstruct S {\n    uint x;\n}\n\ncontract C {\n    S sStorage;\n    constructor() {\n        sStorage.x = 13;\n    }\n\n    function f() external returns (S[] memory) {\n        S[] memory sMemory = new S[](1);\n\n        sMemory[0] = sStorage;\n\n        return sMemory;\n    }\n}\n// ----\n// f() -> 0x20, 1, 13\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/copy_struct_array_from_storage.sol",
    "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n    S[][] a;\n    S[] b;\n\n    constructor() {\n        a.push();\n        a[0].push(S(1));\n        a[0].push(S(2));\n        a[0].push(S(3));\n\n        b.push(S(4));\n        b.push(S(5));\n        b.push(S(6));\n        b.push(S(7));\n    }\n\n    function test1() external returns (bool) {\n        a.push();\n        a[1] = b;\n\n        assert(a.length == 2);\n        assert(a[0].length == 3);\n        assert(a[1].length == 4);\n        assert(a[1][0].value == 4);\n        assert(a[1][1].value == 5);\n        assert(a[1][2].value == 6);\n        assert(a[1][3].value == 7);\n\n        return true;\n    }\n\n    function test2() external returns (bool) {\n        S[][] memory temp = new S[][](2);\n\n        temp = a;\n\n        assert(temp.length == 2);\n        assert(temp[0].length == 3);\n        assert(temp[1].length == 4);\n        assert(temp[1][0].value == 4);\n        assert(temp[1][1].value == 5);\n        assert(temp[1][2].value == 6);\n        assert(temp[1][3].value == 7);\n\n        return true;\n    }\n\n    function test3() external returns (bool) {\n        S[][] memory temp = new S[][](2);\n\n        temp[0] = a[0];\n        temp[1] = a[1];\n\n        assert(temp.length == 2);\n        assert(temp[0].length == 3);\n        assert(temp[1].length == 4);\n        assert(temp[1][0].value == 4);\n        assert(temp[1][1].value == 5);\n        assert(temp[1][2].value == 6);\n        assert(temp[1][3].value == 7);\n\n        return true;\n    }\n\n    function test4() external returns (bool) {\n        S[][] memory temp = new S[][](2);\n\n        temp[0] = a[0];\n        temp[1] = b;\n\n        assert(temp.length == 2);\n        assert(temp[0].length == 3);\n        assert(temp[1].length == 4);\n        assert(temp[1][0].value == 4);\n        assert(temp[1][1].value == 5);\n        assert(temp[1][2].value == 6);\n        assert(temp[1][3].value == 7);\n\n        return true;\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 155952\n// gas legacyOptimized: 152864\n// test2() -> true\n// test3() -> true\n// test4() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_calldata_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8[1] x;\n        uint8[] y;\n    }\n\n    function test(S calldata s) public returns (S memory) {\n        return s;\n    }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_calldata_to_storage.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8[1] x;\n        uint8[] y;\n    }\n\n    S s;\n\n    function test(S calldata src) public {\n        s = src;\n\n        require(s.x[0] == 3);\n        require(s.y.length == 2);\n        require(s.y[0] == 7);\n        require(s.y[1] == 11);\n    }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_memory_to_memory.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8[1] x;\n        uint8[] y;\n    }\n\n    function test(S memory s) public returns (S memory r) {\n        return r;\n    }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 0, 0x40, 0\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 0, 0x40, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_storage_to_storage.sol",
    "content": "contract C {\n    struct S {\n        uint8[1] x;\n        uint8[] y;\n    }\n\n    S src;\n    S dst;\n\n    constructor() {\n        src.x = [3];\n        src.y.push(7);\n        src.y.push(11);\n    }\n\n    function test() public {\n        dst = src;\n\n        require(dst.x[0] == 3);\n        require(dst.y.length == 2);\n        require(dst.y[0] == 7);\n        require(dst.y[1] == 11);\n    }\n}\n// ----\n// test()\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        bytes b;\n        uint16[] a;\n        uint16 u;\n    }\n\n    constructor() {\n        uint16[] memory a = new uint16[](2);\n        a[0] = 13;\n        a[1] = 14;\n\n        m[7] = S({b: \"foo\", a: a, u: 7});\n    }\n\n    mapping (uint => S) m;\n    S s;\n\n    function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n        return s;\n    }\n\n    function to_storage() public returns (S memory) {\n        S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n        return sLocal;\n    }\n\n    function to_memory() public returns (S memory) {\n        S memory sLocal;\n        sLocal.b = m[7].b;\n        sLocal.a = m[7].a;\n        sLocal.u = m[7].u;\n\treturn sLocal;\n    }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 125617\n// gas legacyOptimized: 121699\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        bytes b;\n        uint16[] a;\n        uint16 u;\n    }\n\n    S s;\n    constructor() {\n        uint16[] memory a = new uint16[](2);\n        a[0] = 13;\n        a[1] = 14;\n\n        s.b = \"foo\";\n        s.a = a;\n        s.u = 21;\n    }\n\n    mapping (uint => S) m;\n\n    function from_memory() public returns (S memory) {\n        S memory sMemory = s;\n        m[0].b = sMemory.b;\n        m[0].a = sMemory.a;\n        m[0].u = sMemory.u;\n        return m[0];\n    }\n\n    function from_state() public returns (S memory) {\n        m[1].b = s.b;\n        m[1].a = s.a;\n        m[1].u = s.u;\n        return m[1];\n    }\n\n    function from_storage() public returns (S memory) {\n        S storage sLocal = s;\n        m[1].b = sLocal.b;\n        m[1].a = sLocal.a;\n        m[1].u = sLocal.u;\n        return m[1];\n    }\n\n    function from_calldata(S calldata sCalldata) public returns (S memory) {\n        m[2].b = sCalldata.b;\n        m[2].a = sCalldata.a;\n        m[2].u = sCalldata.u;\n        return m[2];\n    }\n}\n// ----\n// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122720\n// gas legacy: 125558\n// gas legacyOptimized: 123322\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121424\n// gas legacy: 125693\n// gas legacyOptimized: 121804\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114852\n// gas legacy: 117950\n// gas legacyOptimized: 115526\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/copy_to_mapping.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        bytes b;\n        uint16[] a;\n        uint16 u;\n    }\n\n    S s;\n    constructor() {\n        uint16[] memory a = new uint16[](2);\n        a[0] = 13;\n        a[1] = 14;\n\n        s.b = \"foo\";\n        s.a = a;\n        s.u = 21;\n    }\n\n    mapping (uint => S) m;\n\n    function from_state() public returns (S memory) {\n        m[0] = s;\n        return m[0];\n    }\n\n    function from_storage() public returns (S memory) {\n        S storage sLocal = s;\n        m[1] = sLocal;\n        return m[1];\n    }\n\n    function from_memory() public returns (S memory) {\n        S memory sMemory = s;\n        m[2] = sMemory;\n        return m[2];\n    }\n\n\n    function from_calldata(S calldata sCalldata) public returns (S memory) {\n        m[3] = sCalldata;\n        return m[3];\n    }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 125554\n// gas legacyOptimized: 121747\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 125612\n// gas legacyOptimized: 121799\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 125423\n// gas legacyOptimized: 123323\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/delete_struct.sol",
    "content": "contract test {\n    struct topStruct {\n        nestedStruct nstr;\n        uint topValue;\n        mapping (uint => uint) topMapping;\n    }\n    uint toDelete;\n    topStruct str;\n    struct nestedStruct {\n        uint nestedValue;\n        mapping (uint => bool) nestedMapping;\n    }\n    constructor() {\n        toDelete = 5;\n        str.topValue = 1;\n        str.topMapping[0] = 1;\n        str.topMapping[1] = 2;\n\n        str.nstr.nestedValue = 2;\n        str.nstr.nestedMapping[0] = true;\n        str.nstr.nestedMapping[1] = false;\n        delete str;\n        delete toDelete;\n    }\n    function getToDelete() public returns (uint res){\n        res = toDelete;\n    }\n    function getTopValue() public returns(uint topValue){\n        topValue = str.topValue;\n    }\n    function getNestedValue() public returns(uint nestedValue){\n        nestedValue = str.nstr.nestedValue;\n    }\n    function getTopMapping(uint index) public returns(uint ret) {\n        ret = str.topMapping[index];\n    }\n    function getNestedMapping(uint index) public returns(bool ret) {\n        return str.nstr.nestedMapping[index];\n    }\n}\n// ----\n// getToDelete() -> 0\n// getTopValue() -> 0\n// getNestedValue() -> 0 #mapping values should be the same#\n// getTopMapping(uint256): 0 -> 1\n// getTopMapping(uint256): 1 -> 2\n// getNestedMapping(uint256): 0 -> true\n// getNestedMapping(uint256): 1 -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/event.sol",
    "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n    event Ev(Item);\n    function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n    function f() public {\n        L.o();\n    }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/function_type_copy.sol",
    "content": "pragma abicoder v2;\nstruct S {\n    function () external[] functions;\n}\n\ncontract C {\n    function f(function () external[] calldata functions) external returns (S memory) {\n        S memory s;\n        s.functions = functions;\n        return s;\n    }\n}\n\ncontract Test {\n    C immutable c = new C();\n\n    function test() external returns (bool) {\n        function() external[] memory functions = new function() external[](3);\n\n        functions[0] = this.random1;\n        functions[1] = this.random2;\n        functions[2] = this.random3;\n\n        S memory ret = c.f(functions);\n\n        assert(ret.functions.length == 3);\n        assert(ret.functions[0] == this.random1);\n        assert(ret.functions[1] == this.random2);\n        assert(ret.functions[2] == this.random3);\n\n        return true;\n    }\n    function random1() external {\n    }\n    function random2() external {\n    }\n    function random3() external {\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/global.sol",
    "content": "pragma abicoder               v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n    function f(S calldata s) external pure returns (uint256, uint256) {\n        return (s.a, s.b);\n    }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/lone_struct_array_type.sol",
    "content": "contract C {\n    struct s {\n        uint256 a;\n        uint256 b;\n    }\n\n    function f() public returns (uint256) {\n        s[7][]; // This is only the type, should not have any effect\n        return 3;\n    }\n}\n// ----\n// f() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/memory_struct_named_constructor.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint256 a;\n        bool x;\n    }\n\n    function s() public returns(S memory)\n    {\n        return S({x: true, a: 8});\n    }\n}\n// ----\n// s() -> 8, true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/memory_structs_as_function_args.sol",
    "content": "contract Test {\n    struct S {\n        uint8 x;\n        uint16 y;\n        uint256 z;\n    }\n\n    function test() public returns (uint256 x, uint256 y, uint256 z) {\n        S memory data = combine(1, 2, 3);\n        x = extract(data, 0);\n        y = extract(data, 1);\n        z = extract(data, 2);\n    }\n\n    function extract(S memory s, uint256 which) internal returns (uint256 x) {\n        if (which == 0) return s.x;\n        else if (which == 1) return s.y;\n        else return s.z;\n    }\n\n    function combine(uint8 x, uint16 y, uint256 z)\n        internal\n        returns (S memory s)\n    {\n        s.x = x;\n        s.y = y;\n        s.z = z;\n    }\n}\n// ----\n// test() -> 1, 2, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/memory_structs_nested.sol",
    "content": "contract Test {\n    struct S {\n        uint8 x;\n        uint16 y;\n        uint256 z;\n    }\n    struct X {\n        uint8 x;\n        S s;\n    }\n\n    function test()\n        public\n        returns (uint256 a, uint256 x, uint256 y, uint256 z)\n    {\n        X memory d = combine(1, 2, 3, 4);\n        a = extract(d, 0);\n        x = extract(d, 1);\n        y = extract(d, 2);\n        z = extract(d, 3);\n    }\n\n    function extract(X memory s, uint256 which) internal returns (uint256 x) {\n        if (which == 0) return s.x;\n        else if (which == 1) return s.s.x;\n        else if (which == 2) return s.s.y;\n        else return s.s.z;\n    }\n\n    function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n        internal\n        returns (X memory s)\n    {\n        s.x = a;\n        s.s.x = x;\n        s.s.y = y;\n        s.s.z = z;\n    }\n}\n// ----\n// test() -> 1, 2, 3, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol",
    "content": "contract Test {\n    struct S {\n        uint8 x;\n        uint16 y;\n        uint256 z;\n    }\n    struct X {\n        uint8 x;\n        S s;\n        uint8[2] a;\n    }\n    X m_x;\n\n    function load()\n        public\n        returns (\n            uint256 a,\n            uint256 x,\n            uint256 y,\n            uint256 z,\n            uint256 a1,\n            uint256 a2\n        )\n    {\n        m_x.x = 1;\n        m_x.s.x = 2;\n        m_x.s.y = 3;\n        m_x.s.z = 4;\n        m_x.a[0] = 5;\n        m_x.a[1] = 6;\n        X memory d = m_x;\n        a = d.x;\n        x = d.s.x;\n        y = d.s.y;\n        z = d.s.z;\n        a1 = d.a[0];\n        a2 = d.a[1];\n    }\n\n    function store()\n        public\n        returns (\n            uint256 a,\n            uint256 x,\n            uint256 y,\n            uint256 z,\n            uint256 a1,\n            uint256 a2\n        )\n    {\n        X memory d;\n        d.x = 1;\n        d.s.x = 2;\n        d.s.y = 3;\n        d.s.z = 4;\n        d.a[0] = 5;\n        d.a[1] = 6;\n        m_x = d;\n        a = m_x.x;\n        x = m_x.s.x;\n        y = m_x.s.y;\n        z = m_x.s.z;\n        a1 = m_x.a[0];\n        a2 = m_x.a[1];\n    }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/memory_structs_read_write.sol",
    "content": "contract Test {\n    struct S {\n        uint8 x;\n        uint16 y;\n        uint256 z;\n        uint8[2] a;\n    }\n    S[5] data;\n\n    function testInit()\n        public\n        returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n    {\n        S[2] memory d;\n        x = d[0].x;\n        y = d[0].y;\n        z = d[0].z;\n        a = d[0].a[1];\n        flag = true;\n    }\n\n    function testCopyRead()\n        public\n        returns (uint8 x, uint16 y, uint256 z, uint8 a)\n    {\n        data[2].x = 1;\n        data[2].y = 2;\n        data[2].z = 3;\n        data[2].a[1] = 4;\n        S memory s = data[2];\n        x = s.x;\n        y = s.y;\n        z = s.z;\n        a = s.a[1];\n    }\n\n    function testAssign()\n        public\n        returns (uint8 x, uint16 y, uint256 z, uint8 a)\n    {\n        S memory s;\n        s.x = 1;\n        s.y = 2;\n        s.z = 3;\n        s.a[1] = 4;\n        x = s.x;\n        y = s.y;\n        z = s.z;\n        a = s.a[1];\n    }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/msg_data_to_struct_member_copy.sol",
    "content": "pragma abicoder v2;\n\nstruct St0 {\n    bytes el0;\n}\ncontract C {\n    function f() external returns (St0 memory) {\n        St0 memory x;\n        x.el0 = msg.data;\n        return x;\n    }\n\n    function g() external returns (St0 memory) {\n        bytes memory temp = msg.data;\n        St0 memory x;\n        x.el0 = temp;\n        return x;\n    }\n\n    function hashes() external returns (bytes4, bytes4) {\n        return (this.f.selector, this.g.selector);\n    }\n\n    function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n        St0 memory x;\n        x.el0 = msg.data;\n        return x;\n    }\n\n    function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n        bytes memory temp = msg.data;\n        St0 memory x;\n        x.el0 = temp;\n        return x;\n    }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/multislot_struct_allocation.sol",
    "content": "contract C {\n  struct I {\n    uint b;\n    uint c;\n    function(uint) external returns (uint) x;\n  }\n  struct S {\n    I a;\n  }\n\n  function o(uint a) external returns(uint) { return a+1; }\n\n  function f() external returns (uint) {\n    S memory s = S(I(1,2, this.o));\n    return s.a.x(1);\n  }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/nested_struct_allocation.sol",
    "content": "contract C {\n  struct I {\n    uint b;\n    uint c;\n  }\n  struct S {\n    I a;\n  }\n\n  function f() external returns (uint) {\n    S memory s = S(I(1,2));\n    return s.a.b;\n  }\n}\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/packed_storage_structs_delete.sol",
    "content": "contract C {\n    struct str { uint8 a; uint16 b; uint8 c; }\n    uint8 x;\n    uint16 y;\n    str data;\n    function test() public returns (uint) {\n        x = 1;\n        y = 2;\n        data.a = 2;\n        data.b = 0xabcd;\n        data.c = 0xfa;\n        if (x != 1 || y != 2 || data.a != 2 || data.b != 0xabcd || data.c != 0xfa)\n            return 2;\n        delete y;\n        delete data.b;\n        if (x != 1 || y != 0 || data.a != 2 || data.b != 0 || data.c != 0xfa)\n            return 3;\n        delete x;\n        delete data;\n        return 1;\n    }\n}\n// ----\n// test() -> 1\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/recursive_struct_2.sol",
    "content": "contract C {\n    struct S {\n        uint16 v;\n        S[] x;\n    }\n    uint8[77] padding;\n    S s;\n    constructor() {\n         s.v = 21;\n         s.x.push(); s.x.push(); s.x.push();\n         s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n    }\n    function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n       S storage sptr1 = s.x[0];\n       S storage sptr2 = s.x[1];\n       S storage sptr3 = s.x[2];\n       uint256 slot1; uint256 slot2; uint256 slot3;\n       assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n       delete s;\n       assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n    }\n}\n// ----\n// f() -> 0, 0, 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/recursive_structs.sol",
    "content": "contract C {\n    struct S {\n        S[] x;\n    }\n    S sstorage;\n\n    function f() public returns (uint256) {\n        S memory s;\n        s.x = new S[](10);\n        delete s;\n        // TODO Uncomment after implemented.\n        // sstorage.x.push();\n        delete sstorage;\n        return 1;\n    }\n}\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/simple_struct_allocation.sol",
    "content": "contract C {\n  struct S {\n    uint a;\n  }\n\n  function f() external returns (uint) {\n    S memory s = S(1);\n    return s.a;\n  }\n}\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_assign_reference_to_struct.sol",
    "content": "contract test {\n    struct testStruct {\n        uint256 m_value;\n    }\n    testStruct data1;\n    testStruct data2;\n    testStruct data3;\n\n    constructor() {\n        data1.m_value = 2;\n    }\n\n    function assign()\n        public\n        returns (\n            uint256 ret_local,\n            uint256 ret_global,\n            uint256 ret_global3,\n            uint256 ret_global1\n        )\n    {\n        testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n        data2 = data1; // should copy data. data2.m_value == 2\n\n        ret_local = x.m_value; // = 2\n        ret_global = data2.m_value; // = 2\n\n        x.m_value = 3;\n        data3 = x; //should copy the data. data3.m_value == 3\n        ret_global3 = data3.m_value; // = 3\n        ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n    }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_constructor_nested.sol",
    "content": "contract C {\n    struct X {\n        uint256 x1;\n        uint256 x2;\n    }\n    struct S {\n        uint256 s1;\n        uint256[3] s2;\n        X s3;\n    }\n    S s;\n\n    constructor() {\n        uint256[3] memory s2;\n        s2[1] = 9;\n        s = S(1, s2, X(4, 5));\n    }\n\n    function get()\n        public\n        returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2)\n    {\n        s1 = s.s1;\n        s2 = s.s2;\n        x1 = s.s3.x1;\n        x2 = s.s3.x2;\n    }\n}\n// ----\n// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol",
    "content": "contract c {\n    struct Struct { uint a; bytes data; uint b; }\n    Struct data1;\n    Struct data2;\n    function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n        data1.a = _a;\n        data1.b = _b;\n        data1.data = _data;\n        return true;\n    }\n    function copy() public returns (bool) {\n        data1 = data2;\n        return true;\n    }\n    function del() public returns (bool) {\n        delete data1;\n        return true;\n    }\n    function test(uint256 i) public returns (bytes1) {\n        return data1.data[i];\n    }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133857\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133857\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_copy.sol",
    "content": "contract c {\n    struct Nested {\n        uint256 x;\n        uint256 y;\n    }\n    struct Struct {\n        uint256 a;\n        Nested nested;\n        uint256 c;\n    }\n    mapping(uint256 => Struct) data;\n\n    function set(uint256 k) public returns (bool) {\n        data[k].a = 1;\n        data[k].nested.x = 3;\n        data[k].nested.y = 4;\n        data[k].c = 2;\n        return true;\n    }\n\n    function copy(uint256 from, uint256 to) public returns (bool) {\n        data[to] = data[from];\n        return true;\n    }\n\n    function retrieve(uint256 k)\n        public\n        returns (uint256 a, uint256 x, uint256 y, uint256 c)\n    {\n        a = data[k].a;\n        x = data[k].nested.x;\n        y = data[k].nested.y;\n        c = data[k].c;\n    }\n}\n// ----\n// set(uint256): 7 -> true\n// gas irOptimized: 109932\n// gas legacy: 110593\n// gas legacyOptimized: 110003\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// gas irOptimized: 118581\n// gas legacy: 119144\n// gas legacyOptimized: 118618\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 0, 7 -> true\n// retrieve(uint256): 7 -> 0, 0, 0, 0\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// retrieve(uint256): 8 -> 0, 0, 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_copy_via_local.sol",
    "content": "contract c {\n    struct Struct {\n        uint256 a;\n        uint256 b;\n    }\n    uint[75] r;\n    Struct data1;\n    Struct data2;\n\n    function test() public returns (bool) {\n        data1.a = 1;\n        data1.b = 2;\n        Struct memory x = data1;\n        data2 = x;\n        return data2.a == data1.a && data2.b == data1.b;\n    }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_delete_member.sol",
    "content": "contract test {\n    struct testStruct {\n        uint256 m_value;\n    }\n    testStruct data1;\n\n    constructor() {\n        data1.m_value = 2;\n    }\n\n    function deleteMember() public returns (uint256 ret_value) {\n        testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n        x.m_value = 4;\n        delete x.m_value;\n        ret_value = data1.m_value;\n    }\n}\n// ----\n// deleteMember() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_delete_storage.sol",
    "content": "contract C {\n    struct S {\n        uint256 x;\n        uint128 y;\n        uint32 z;\n    }\n    uint8 b = 23;\n    S s;\n    uint8 a = 17;\n    function f() public {\n        s.x = 42; s.y = 42; s.y = 42;\n        delete s;\n        assert(s.x == 0);\n        assert(s.y == 0);\n        assert(s.z == 0);\n        assert(b == 23);\n        assert(a == 17);\n    }\n}\n// ----\n// f() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol",
    "content": "contract C {\n    struct S {\n        uint32 a;\n        S[] x;\n    }\n    S s;\n    function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n        assembly {\n            // 2 ** 150 - 1\n            sstore(s.slot, 1427247692705959881058285969449495136382746623)\n        }\n        s.a = 1;\n        s.x.push(); s.x.push();\n        S storage ptr1 = s.x[0];\n        S storage ptr2 = s.x[1];\n        assembly {\n            // 2 ** 150 - 1\n            sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n            sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n        }\n        s.x[0].a = 2; s.x[1].a = 3;\n        delete s;\n        assert(s.a == 0);\n        assert(s.x.length == 0);\n        assembly {\n            r1 := sload(s.slot)\n            r2 := sload(ptr1.slot)\n            r3 := sload(ptr2.slot)\n        }\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 93835\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_delete_storage_small.sol",
    "content": "contract C {\n    struct S {\n        uint64 y;\n        uint64 z;\n    }\n    S s;\n    function f() public returns (uint256 ret) {\n        assembly {\n            // 2 ** 150 - 1\n            sstore(s.slot, 1427247692705959881058285969449495136382746623)\n        }\n        s.y = 1; s.z = 2;\n        delete s;\n        assert(s.y == 0);\n        assert(s.z == 0);\n        assembly {\n            ret := sload(s.slot)\n        }\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint128 a;\n        uint256[] x;\n        uint240 b;\n    }\n    uint8 b = 23;\n    S s;\n    uint8 a = 17;\n    function f() public {\n        delete s;\n        s.x.push(42); s.x.push(42); s.x.push(42);\n        delete s;\n        assert(s.x.length == 0);\n        uint256[] storage x = s.x;\n        assembly { sstore(x.slot, 3) }\n        assert(s.x[0] == 0);\n        assert(s.x[1] == 0);\n        assert(s.x[2] == 0);\n        assert(b == 23);\n        assert(a == 17);\n    }\n\n    function g() public {\n        delete s;\n        s.x.push(42); s.x.push(42); s.x.push(42);\n        s.a = 1; s.b = 2;\n        delete s.x;\n        assert(s.x.length == 0);\n        uint256[] storage x = s.x;\n        assembly { sstore(x.slot, 3) }\n        assert(s.x[0] == 0);\n        assert(s.x[1] == 0);\n        assert(s.x[2] == 0);\n        assert(b == 23);\n        assert(a == 17);\n        assert(s.a == 1);\n        assert(s.b == 2);\n    }\n}\n// ----\n// f() ->\n// gas irOptimized: 113388\n// gas legacy: 113583\n// gas legacyOptimized: 113119\n// g() ->\n// gas irOptimized: 118768\n// gas legacy: 118761\n// gas legacyOptimized: 118203\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol",
    "content": "contract C {\n    struct S {\n        uint32 a;\n        uint32[3] b;\n        uint32[] x;\n    }\n    S s;\n    function f() public returns (uint256 ret) {\n        assembly {\n            // 2 ** 150 - 1\n            sstore(s.slot, 1427247692705959881058285969449495136382746623)\n        }\n        s.a = 1;\n        s.b[0] = 2; s.b[1] = 3;\n        s.x.push(4); s.x.push(5);\n        delete s;\n        assert(s.a == 0);\n        assert(s.b[0] == 0);\n        assert(s.b[1] == 0);\n        assert(s.x.length == 0);\n        assembly {\n            ret := sload(s.slot)\n        }\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0\n// gas irOptimized: 89468\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_delete_struct_in_mapping.sol",
    "content": "contract test {\n    struct testStruct {\n        uint256 m_value;\n    }\n    mapping(uint256 => testStruct) campaigns;\n\n    constructor() {\n        campaigns[0].m_value = 2;\n    }\n\n    function deleteIt() public returns (uint256) {\n        delete campaigns[0];\n        return campaigns[0].m_value;\n    }\n}\n// ----\n// deleteIt() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_memory_to_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint32 a;\n        uint128 b;\n        uint256 c;\n    }\n\n    struct X {\n        uint256 a;\n        S s;\n    }\n\n    uint[79] r;\n    X x;\n\n    function f() external returns (uint32, uint128, uint256) {\n        X memory m = X(12, S(42, 23, 34));\n        x = m;\n        return (x.s.a, x.s.b, x.s.c);\n    }\n}\n// ----\n// f() -> 42, 23, 34\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint32 a;\n        uint128 b;\n        uint256 c;\n        function() internal returns (uint32) f;\n    }\n\n    struct X {\n        uint256 a;\n        S s;\n    }\n\n    uint[79] r;\n    X x;\n\n    function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n        X memory m = X(12, S(42, 23, 34, g));\n        x = m;\n        return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n    }\n\n    function g() internal returns (uint32) {\n        return x.s.a;\n    }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_named_constructor.sol",
    "content": "contract C {\n    struct S {\n        uint256 a;\n        bool x;\n    }\n    S public s;\n\n    constructor() {\n        s = S({x: true, a: 1});\n    }\n}\n// ----\n// s() -> 1, true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_reference.sol",
    "content": "contract test {\n    struct s2 {\n        uint32 z;\n        mapping(uint8 => s2) recursive;\n    }\n    s2 data;\n    function check() public returns (bool ok) {\n        return data.z == 2 &&\n            data.recursive[0].z == 3 &&\n            data.recursive[0].recursive[1].z == 0 &&\n            data.recursive[0].recursive[0].z == 1;\n    }\n    function set() public {\n        data.z = 2;\n        mapping(uint8 => s2) storage map = data.recursive;\n        s2 storage inner = map[0];\n        inner.z = 3;\n        inner.recursive[0].z = inner.recursive[1].z + 1;\n    }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_referencing.sol",
    "content": "pragma abicoder v2;\ninterface I {\n    struct S { uint a; }\n}\n\nlibrary L {\n    struct S { uint b; uint a; }\n    function f() public pure returns (S memory) {\n        S memory s;\n        s.a = 3;\n        return s;\n    }\n    function g() public pure returns (I.S memory) {\n        I.S memory s;\n        s.a = 4;\n        return s;\n    }\n    // argument-dependent lookup tests\n    function a(I.S memory) public pure returns (uint) { return 1; }\n    function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n    function f() public pure returns (S memory) {\n        S memory s;\n        s.a = 1;\n        return s;\n    }\n    function g() public pure returns (I.S memory) {\n        I.S memory s;\n        s.a = 2;\n        return s;\n    }\n    function h() public pure returns (L.S memory) {\n        L.S memory s;\n        s.a = 5;\n        return s;\n    }\n    function x() public pure returns (L.S memory) {\n        return L.f();\n    }\n    function y() public pure returns (I.S memory) {\n        return L.g();\n    }\n    function a1() public pure returns (uint) { S memory s; return L.a(s); }\n    function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_storage_push_zero_value.sol",
    "content": "contract C {\n    struct S {\n        uint256 x;\n        uint128 y;\n        uint32 z;\n        uint128[3] a1;\n        uint128[] a2;\n    }\n    uint8 b = 23;\n    S[] s;\n    uint8 a = 17;\n    function f() public {\n        s.push();\n        assert(s[0].x == 0);\n        assert(s[0].y == 0);\n        assert(s[0].z == 0);\n        assert(s[0].a1[0] == 0);\n        assert(s[0].a1[1] == 0);\n        assert(s[0].a1[2] == 0);\n        assert(s[0].a2.length == 0);\n        assert(b == 23);\n        assert(a == 17);\n    }\n}\n// ----\n// f() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_storage_to_mapping.sol",
    "content": "contract C {\n    struct S {\n        uint a;\n    }\n    S s;\n    mapping (uint => S) m;\n\n    function f() external returns (bool) {\n        s.a = 12;\n        m[1] = s;\n        return m[1].a == 12;\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_storage_to_memory.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint32 a;\n        uint128 b;\n        uint256 c;\n    }\n    struct X {\n        uint32 a;\n        S s;\n    }\n\n    uint[79] arr;\n    X x = X(12, S(42, 23, 34));\n\n    function f() external returns (uint32, uint128, uint256) {\n        X memory m = x;\n        return (m.s.a, m.s.b, m.s.c);\n    }\n}\n// ----\n// f() -> 42, 23, 34\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/struct_storage_to_memory_function_ptr.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint32 a;\n        uint128 b;\n        uint256 c;\n        function() internal returns (uint32) f;\n    }\n\n    struct X {\n        uint256 a;\n        S s;\n    }\n\n    uint[79] arr;\n    X x = X(12, S(42, 23, 34, g));\n\n    function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n        X memory m = x;\n        return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n    }\n\n    function g() internal returns (uint32) {\n        return x.s.a;\n    }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/structs.sol",
    "content": "contract test {\n    struct s1 {\n        uint8 x;\n        bool y;\n    }\n    struct s2 {\n        uint32 z;\n        s1 s1data;\n        mapping(uint8 => s2) recursive;\n    }\n    s2 data;\n    function check() public returns (bool ok) {\n        return data.z == 1 && data.s1data.x == 2 &&\n            data.s1data.y == true &&\n            data.recursive[3].recursive[4].z == 5 &&\n            data.recursive[4].recursive[3].z == 6 &&\n            data.recursive[0].s1data.y == false &&\n            data.recursive[4].z == 9;\n    }\n    function set() public {\n        data.z = 1;\n        data.s1data.x = 2;\n        data.s1data.y = true;\n        data.recursive[3].recursive[4].z = 5;\n        data.recursive[4].recursive[3].z = 6;\n        data.recursive[0].s1data.y = false;\n        data.recursive[4].z = 9;\n    }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/structs/using_for_function_on_struct.sol",
    "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n    using D for D.s;\n    D.s public x;\n    function f(uint a) public returns (uint) {\n        x.a = 3;\n        return x.mul(a);\n    }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/assert.sol",
    "content": "contract C {\n    function g(bool x) public pure {\n        assert(x);\n    }\n    function f(bool x) public returns (uint) {\n        try this.g(x) {\n            return 1;\n        } catch {\n            return 2;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/assert_pre_byzantium.sol",
    "content": "contract C {\n    function g(bool x) public pure {\n        assert(x);\n    }\n    function f(bool x) public returns (uint) {\n        // Set the gas to make this work on pre-byzantium VMs\n        try this.g{gas: 8000}(x) {\n            return 1;\n        } catch {\n            return 2;\n        }\n    }\n}\n// ====\n// EVMVersion: <byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/create.sol",
    "content": "contract Reverts {\n    constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n    constructor(uint) { }\n}\n\ncontract C {\n    function f() public returns (bool created, string memory txt) {\n        uint i = 3;\n        try new Reverts(i) returns (Reverts r) {\n            created = (address(r) != address(0));\n            txt = \"success\";\n        } catch Error(string memory s) {\n            txt = s;\n        }\n    }\n    function g() public returns (bool created, string memory txt) {\n        uint i = 8;\n        try new Succeeds(i) returns (Succeeds r) {\n            created = (address(r) != address(0));\n            txt = \"success\";\n        } catch Error(string memory s) {\n            txt = s;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> false, 0x40, 13, \"test message.\"\n// g() -> true, 0x40, 7, \"success\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/invalid_error_encoding.sol",
    "content": "contract C {\n    function g(bytes memory revertMsg) public pure returns (uint, uint) {\n        assembly { revert(add(revertMsg, 0x20), mload(revertMsg)) }\n    }\n    function f1() public returns (uint x) {\n        // Invalid signature\n        try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        } catch (bytes memory) {\n            return 2;\n        }\n    }\n    function f1a() public returns (uint x) {\n        // Invalid signature\n        try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        } catch {\n            return 2;\n        }\n    }\n    function f1b() public returns (uint x) {\n        // Invalid signature\n        try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        }\n    }\n    function f1c() public returns (uint x) {\n        // Invalid signature\n        try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch {\n            return 2;\n        }\n    }\n    function f2() public returns (uint x) {\n        // Valid signature but illegal offset\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        } catch (bytes memory) {\n            return 2;\n        }\n    }\n    function f2a() public returns (uint x) {\n        // Valid signature but illegal offset\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        } catch {\n            return 2;\n        }\n    }\n    function f2b() public returns (uint x) {\n        // Valid signature but illegal offset\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        }\n    }\n    function f2c() public returns (uint x) {\n        // Valid signature but illegal offset\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch {\n            return 1;\n        }\n    }\n    function f3() public returns (uint x) {\n        // Valid up to length\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        } catch (bytes memory) {\n            return 2;\n        }\n    }\n    function f3a() public returns (uint x) {\n        // Valid up to length\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        } catch (bytes memory) {\n            return 2;\n        }\n    }\n    function f3b() public returns (uint x) {\n        // Valid up to length\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        }\n    }\n    function f3c() public returns (uint x) {\n        // Valid up to length\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n            return 0;\n        } catch {\n            return 1;\n        }\n    }\n    function f4() public returns (uint x) {\n        // Fully valid\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        } catch (bytes memory) {\n            return 2;\n        }\n    }\n    function f4a() public returns (uint x) {\n        // Fully valid\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        } catch {\n            return 2;\n        }\n    }\n    function f4b() public returns (uint x) {\n        // Fully valid\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n            return 0;\n        } catch Error(string memory) {\n            return 1;\n        }\n    }\n    function f4c() public returns (uint x) {\n        // Fully valid\n        try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n            return 0;\n        } catch {\n            return 1;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f1() -> 2\n// f1a() -> 2\n// f1b() -> FAILURE, hex\"12345678\", 0x0, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f1c() -> 2\n// f2() -> 2\n// f2a() -> 2\n// f2b() -> FAILURE, hex\"08c379a0\", 0x100, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f2c() -> 1\n// f3() -> 2\n// f3a() -> 2\n// f3b() -> FAILURE, hex\"08c379a0\", 0x20, 48, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f3c() -> 1\n// f4() -> 1\n// f4a() -> 1\n// f4b() -> 1\n// f4c() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/lowLevel.sol",
    "content": "contract C {\n    function g(bool b) public pure returns (uint, uint) {\n        require(b, \"message\");\n        return (1, 2);\n    }\n    function f(bool b) public returns (uint x, uint y, bytes memory txt) {\n        try this.g(b) returns (uint a, uint b) {\n            (x, y) = (a, b);\n        } catch (bytes memory s) {\n            txt = s;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 0\n// f(bool): false -> 0, 0, 96, 100, 0x8c379a000000000000000000000000000000000000000000000000000000000, 0x2000000000000000000000000000000000000000000000000000000000, 0x76d657373616765000000000000000000000000000000000000000000, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/malformed_error.sol",
    "content": "contract C {\n    function f(uint size) public pure {\n        assembly {\n            mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n            mstore(4, 0x20)\n            mstore(0x24, 7)\n            mstore(0x44, \"abcdefg\")\n            revert(0, size)\n        }\n    }\n    function a() public returns (uint) {\n        try this.f(3) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch Error(string memory) {\n            assert(false);\n        } catch {\n            assert(true);\n        }\n    }\n    function b() public returns (uint) {\n        try this.f(6) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch Error(string memory) {\n            assert(false);\n        } catch {\n            assert(true);\n        }\n    }\n    function b2() public returns (uint) {\n        try this.f(0x43) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch Error(string memory) {\n            assert(false);\n        } catch {\n            assert(true);\n        }\n    }\n    function b3() public returns (string memory) {\n        try this.f(0x4a) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch Error(string memory) {\n            assert(false);\n        } catch {\n            assert(true);\n        }\n    }\n    function c() public returns (string memory) {\n        try this.f(0x4b) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch Error(string memory er) {\n            assert(true);\n            return er;\n        } catch {\n            assert(false);\n        }\n    }\n    function d() public returns (string memory) {\n        try this.f(0x100) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch Error(string memory er) {\n            assert(true);\n            return er;\n        } catch {\n            assert(false);\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/malformed_panic.sol",
    "content": "contract C {\n    function f(uint size) public pure {\n        assembly {\n            mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n            mstore(4, 0x43)\n            revert(0, size)\n        }\n    }\n    function a() public returns (uint) {\n        try this.f(3) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch {\n            assert(true);\n        }\n    }\n    function b() public returns (uint) {\n        try this.f(6) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch {\n            assert(true);\n        }\n    }\n    function c() public returns (uint) {\n        try this.f(0x24) {\n            assert(false);\n        } catch Panic(uint c) {\n            assert(true);\n            return c;\n        } catch {\n            assert(false);\n        }\n    }\n    function d() public returns (uint) {\n        try this.f(0x100) {\n            assert(false);\n        } catch Panic(uint c) {\n            assert(true);\n            return c;\n        } catch {\n            assert(false);\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n// d() -> 0x43\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/malformed_panic_2.sol",
    "content": "contract C {\n    function f(uint size) public pure {\n        assembly {\n            mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n            mstore(4, 0x43)\n            revert(0, size)\n        }\n    }\n    function a() public returns (uint) {\n        try this.f(3) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        }\n        // Error will be re-thrown, since there is no low-level catch clause\n        assert(false);\n    }\n    function b() public returns (uint) {\n        try this.f(6) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        }\n        // Error will be re-thrown, since there is no low-level catch clause\n        assert(false);\n    }\n    function c() public returns (uint) {\n        try this.f(0x24) {\n            assert(false);\n        } catch Panic(uint c) {\n            assert(true);\n            return c;\n        }\n        assert(false);\n    }\n    function d() public returns (uint) {\n        try this.f(0x100) {\n            assert(false);\n        } catch Panic(uint c) {\n            assert(true);\n            return c;\n        }\n        assert(false);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> FAILURE, hex\"4e487b\"\n// b() -> FAILURE, hex\"4e487b710000\"\n// c() -> 0x43\n// d() -> 0x43\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/malformed_panic_3.sol",
    "content": "contract C {\n    function f(uint size) public pure {\n        assembly {\n            mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n            mstore(4, 0x43)\n            revert(0, size)\n        }\n    }\n    function a() public returns (uint) {\n        try this.f(3) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch Error(string memory) {\n            assert(false);\n        }\n        // Error will be re-thrown, since there is no low-level catch clause\n        assert(false);\n    }\n    function b() public returns (uint) {\n        try this.f(6) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch Error(string memory) {\n            assert(false);\n        }\n        // Error will be re-thrown, since there is no low-level catch clause\n        assert(false);\n    }\n    function c() public returns (uint) {\n        try this.f(0x24) {\n            assert(false);\n        } catch Panic(uint c) {\n            assert(true);\n            return c;\n        } catch Error(string memory) {\n            assert(false);\n        }\n    }\n    function d() public returns (uint) {\n        try this.f(0x100) {\n            assert(false);\n        } catch Panic(uint c) {\n            assert(true);\n            return c;\n        } catch Error(string memory) {\n            assert(false);\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> FAILURE, hex\"4e487b\"\n// b() -> FAILURE, hex\"4e487b710000\"\n// c() -> 0x43\n// d() -> 0x43\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/malformed_panic_4.sol",
    "content": "contract C {\n    function f(uint size) public pure {\n        assembly {\n            mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n            mstore(4, 0x43)\n            revert(0, size)\n        }\n    }\n    function a() public returns (uint) {\n        try this.f(3) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch Error(string memory) {\n            assert(false);\n        } catch {\n            assert(true);\n        }\n    }\n    function b() public returns (uint) {\n        try this.f(6) {\n            assert(false);\n        } catch Panic(uint) {\n            assert(false);\n        } catch Error(string memory) {\n            assert(false);\n        } catch {\n            assert(true);\n        }\n    }\n    function c() public returns (uint) {\n        try this.f(0x24) {\n            assert(false);\n        } catch Panic(uint c) {\n            assert(true);\n            return c;\n        } catch Error(string memory) {\n            assert(false);\n        } catch {\n            assert(false);\n        }\n    }\n    function d() public returns (uint) {\n        try this.f(0x100) {\n            assert(false);\n        } catch Panic(uint c) {\n            assert(true);\n            return c;\n        } catch Error(string memory) {\n            assert(false);\n        } catch {\n            assert(false);\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/nested.sol",
    "content": "contract C {\n    function g(bool b) public pure returns (uint, uint) {\n        require(b, \"failure\");\n        return (1, 2);\n    }\n    function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n        try this.g(cond1) returns (uint a, uint b) {\n            try this.g(cond2) returns (uint a2, uint b2) {\n                (x, y) = (a, b);\n                txt = \"success\";\n            } catch Error(string memory s) {\n                x = 12;\n                txt = bytes(s);\n            } catch (bytes memory s) {\n                x = 13;\n                txt = s;\n            }\n        } catch Error(string memory s) {\n            x = 99;\n            txt = bytes(s);\n        } catch (bytes memory s) {\n            x = 98;\n            txt = s;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/panic.sol",
    "content": "contract C {\n    function uf(bool b, uint x, uint y) public pure returns (uint) {\n        require(b, \"failure\");\n        return x - y;\n    }\n    function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n        try this.uf(b, x, y) returns (uint b) {\n            r = b;\n        } catch Panic(uint c) {\n            code = c;\n        }\n    }\n    function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n        try this.uf(b, x, y) returns (uint b) {\n            r = b;\n        } catch Panic(uint c) {\n            code = c;\n        } catch Error(string memory _errmsg) {\n            msg_ = _errmsg;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/require.sol",
    "content": "contract C {\n    function g(bool x) public pure {\n        require(x);\n    }\n    function f(bool x) public returns (uint) {\n        try this.g(x) {\n            return 1;\n        } catch {\n            return 2;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/require_pre_byzantium.sol",
    "content": "contract C {\n    function g(bool x) public pure {\n        require(x);\n    }\n    function f(bool x) public returns (uint) {\n        // Set the gas to make this work on pre-byzantium VMs\n        try this.g{gas: 8000}(x) {\n            return 1;\n        } catch {\n            return 2;\n        }\n    }\n}\n// ====\n// EVMVersion: <byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/return_function.sol",
    "content": "contract C {\n    function g() public returns (uint a, function() external h, uint b) {\n        a = 1;\n        h = C(address(0x1234)).fun;\n        b = 9;\n    }\n    function f() public returns (uint, function() external, uint) {\n        // Note that the function type uses two stack slots.\n        try this.g() returns (uint a, function() external h, uint b) {\n            return (a, h, b);\n        } catch {\n        }\n    }\n    function fun() public pure {}\n}\n// ----\n// f() -> 0x1, 0x1234946644cd0000000000000000, 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/simple.sol",
    "content": "contract C {\n    function g(bool b) public pure returns (uint x, uint y) {\n        require(b);\n        return (1, 2);\n    }\n    function f(bool flag) public view returns (uint x, uint y) {\n        try this.g(flag) returns (uint a, uint b) {\n            (x, y) = (a, b);\n        } catch {\n            (x, y) = (9, 10);\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 9, 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/simple_notuple.sol",
    "content": "contract C {\n    function g(bool b) public pure returns (uint x) {\n        require(b);\n        return 13;\n    }\n    function f(bool flag) public view returns (uint x) {\n        try this.g(flag) returns (uint a) {\n            x = a;\n        } catch {\n            x = 9;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/structured.sol",
    "content": "contract C {\n    function g(bool b) public pure returns (uint, uint) {\n        require(b, \"message\");\n        return (1, 2);\n    }\n    function f(bool b) public returns (uint x, uint y, string memory txt) {\n        try this.g(b) returns (uint a, uint b) {\n            (x, y) = (a, b);\n            txt = \"success\";\n        } catch Error(string memory s) {\n            txt = s;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 0x60, 7, \"success\"\n// f(bool): false -> 0, 0, 0x60, 7, \"message\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/structuredAndLowLevel.sol",
    "content": "contract C {\n    function g(bool b) public pure returns (uint, uint) {\n        require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n        return (1, 2);\n    }\n    function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n        try this.g(cond) returns (uint a, uint b) {\n            (x, y) = (a, b);\n            txt = \"success\";\n        } catch Error(string memory s) {\n            x = 99;\n            txt = bytes(s);\n        } catch (bytes memory s) {\n            x = 98;\n            txt = s;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/tryCatch/try_catch_library_call.sol",
    "content": "library L {\n    struct S { uint x; }\n    function integer(uint t, bool b) public view returns (uint) {\n        if (b) {\n            return t;\n        } else {\n            revert(\"failure\");\n        }\n    }\n    function stru(S storage t, bool b) public view returns (uint) {\n        if (b) {\n            return t.x;\n        } else {\n            revert(\"failure\");\n        }\n    }\n}\ncontract C {\n    using L for L.S;\n    L.S t;\n    function f(bool b) public returns (uint, string memory) {\n        uint x = 8;\n        try L.integer(x, b) returns (uint _x) {\n            return (_x, \"\");\n        } catch Error(string memory message) {\n            return (18, message);\n        }\n    }\n    function g(bool b) public returns (uint, string memory) {\n        t.x = 9;\n        try t.stru(b) returns (uint x) {\n            return (x, \"\");\n        } catch Error(string memory message) {\n            return (19, message);\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// f(bool): true -> 8, 0x40, 0\n// f(bool): false -> 18, 0x40, 7, \"failure\"\n// g(bool): true -> 9, 0x40, 0\n// g(bool): false -> 19, 0x40, 7, \"failure\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/array_mapping_abstract_constructor_param.sol",
    "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/assign_calldata_value_type.sol",
    "content": "contract C {\n    function f(uint256 x) public pure returns (uint256, uint256) {\n        uint256 b = x;\n        x = 42;\n        return (x, b);\n    }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/convert_fixed_bytes_to_fixed_bytes_greater_size.sol",
    "content": "contract Test {\n    function bytesToBytes(bytes2 input) public returns (bytes4 ret) {\n        return bytes4(input);\n    }\n}\n// ----\n// bytesToBytes(bytes2): \"ab\" -> \"ab\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/convert_fixed_bytes_to_fixed_bytes_same_size.sol",
    "content": "contract Test {\n    function bytesToBytes(bytes4 input) public returns (bytes4 ret) {\n        return bytes4(input);\n    }\n}\n// ----\n// bytesToBytes(bytes4): \"abcd\" -> \"abcd\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/convert_fixed_bytes_to_fixed_bytes_smaller_size.sol",
    "content": "contract Test {\n    function bytesToBytes(bytes4 input) public returns (bytes2 ret) {\n        return bytes2(input);\n    }\n}\n// ----\n// bytesToBytes(bytes4): \"abcd\" -> \"ab\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/convert_fixed_bytes_to_uint_greater_size.sol",
    "content": "contract Test {\n    function bytesToUint(bytes4 s) public returns (uint64 h) {\n        return uint64(uint32(s));\n    }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/convert_fixed_bytes_to_uint_same_min_size.sol",
    "content": "contract Test {\n    function bytesToUint(bytes1 s) public returns (uint8 h) {\n        return uint8(s);\n    }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/convert_fixed_bytes_to_uint_same_type.sol",
    "content": "contract Test {\n    function bytesToUint(bytes32 s) public returns (uint256 h) {\n        return uint(s);\n    }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/convert_fixed_bytes_to_uint_smaller_size.sol",
    "content": "contract Test {\n    function bytesToUint(bytes4 s) public returns (uint16 h) {\n        return uint16(uint32(s));\n    }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/convert_uint_to_fixed_bytes_greater_size.sol",
    "content": "contract Test {\n    function UintToBytes(uint16 h) public returns (bytes8 s) {\n        return bytes8(uint64(h));\n    }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/convert_uint_to_fixed_bytes_same_min_size.sol",
    "content": "contract Test {\n    function UintToBytes(uint8 h) public returns (bytes1 s) {\n        return bytes1(h);\n    }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/convert_uint_to_fixed_bytes_same_size.sol",
    "content": "contract Test {\n    function uintToBytes(uint256 h) public returns (bytes32 s) {\n        return bytes32(h);\n    }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/convert_uint_to_fixed_bytes_smaller_size.sol",
    "content": "contract Test {\n    function uintToBytes(uint32 h) public returns (bytes2 s) {\n        return bytes2(uint16(h));\n    }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/external_function_to_address.sol",
    "content": "contract C {\n    function f() public returns (bool) {\n        return this.f.address == address(this);\n    }\n    function g(function() external cb) public returns (address) {\n        return cb.address;\n    }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8[3] x;\n        uint8[][] y;\n        uint16 z;\n    }\n\n    mapping (uint8 => S) src;\n    mapping (uint8 => S) dst;\n\n    constructor() {\n        uint8[] memory d = new uint8[](2);\n        d[0] = 3;\n        d[1] = 4;\n\n        uint8[][] memory y = new uint8[][](2);\n        y[0] = d;\n        y[1] = d;\n\n        src[0] = S({x: [7, 8, 9], y: y, z: 13});\n    }\n\n    function f() public returns (S memory) {\n        dst[0] = src[0];\n        return dst[0];\n    }\n}\n// ----\n// f() -> 0x20, 7, 8, 9, 0xa0, 13, 2, 0x40, 0xa0, 2, 3, 4, 2, 3, 4\n// gas irOptimized: 197102\n// gas legacy: 205706\n// gas legacyOptimized: 196739\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping/copy_struct_to_array_stored_in_mapping.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S {\n        uint8 x;\n    }\n\n    constructor() {\n        s = S({x: 7});\n        m2[0].push();\n    }\n\n    S s;\n\n    mapping (uint8 => S[2]) m1;\n    mapping (uint8 => S[]) m2;\n\n    function from_storage_to_static_array() public returns (S[2] memory) {\n        m1[0][1] = s;\n        return m1[0];\n    }\n\n    function from_storage_to_dynamic_array() public returns (S[] memory) {\n        m2[0][0] = s;\n        return m2[0];\n    }\n\n    function from_memory_to_static_array() public returns (S[2] memory) {\n        S memory sLocal = s;\n        m1[0][1] = sLocal;\n        return m1[0];\n    }\n\n    function from_memory_to_dynamic_array() public returns (S[] memory) {\n        S memory sLocal = s;\n        m2[0][0] = sLocal;\n        return m2[0];\n    }\n\n    function from_calldata_to_static_array(S calldata sCalldata) public returns (S[2] memory) {\n        m1[0][1] = sCalldata;\n        return m1[0];\n    }\n\n    function from_calldata_to_dynamic_array(S calldata sCalldata) public returns (S[] memory) {\n        m2[0][0] = sCalldata;\n        return m2[0];\n    }\n}\n// ----\n// from_storage_to_static_array() -> 0, 7\n// from_storage_to_dynamic_array() -> 0x20, 1, 7\n// from_memory_to_static_array() -> 0, 7\n// from_memory_to_dynamic_array() -> 0x20, 1, 7\n// from_calldata_to_static_array((uint8)): 8 -> 0, 8\n// from_calldata_to_dynamic_array((uint8)): 8 -> 0x20, 1, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping/user_defined_types_mapping_storage.sol",
    "content": "type A is uint;\ntype B is uint;\n\nlibrary L {\n  function f(mapping(A=>B) storage _m, B _v) public { _m[A.wrap(uint(2))] = _v; }\n  function f(mapping(uint=>uint) storage _m, uint _v) public { _m[uint(3)] = _v; }\n}\n\ncontract C {\n\tmapping(uint=>uint) uintMap;\n\tmapping(A=>B) abMap;\n\n\tfunction testAB() public returns (bool) {\n\t\tL.f(abMap, B.wrap(3));\n\t\treturn B.unwrap(abMap[A.wrap(uint(2))]) == 3;\n\t}\n\tfunction testUint() public returns (bool) {\n\t\tL.f(uintMap, 4);\n\t\treturn uintMap[3] == 4;\n\t}\n}\n// ----\n// library: L\n// testAB() -> true\n// testUint() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping_abstract_constructor_param.sol",
    "content": "abstract contract A {\n    constructor (mapping (uint => uint) storage m) {\n        m[5] = 20;\n    }\n}\n\ncontract C is A {\n    mapping (uint => uint) public m;\n\n    constructor() A(m) {\n    }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping_contract_key.sol",
    "content": "interface A {}\ncontract test {\n    mapping(A => uint8) table;\n    function get(A k) public returns (uint8 v) {\n        return table[k];\n    }\n    function set(A k, uint8 v) public {\n        table[k] = v;\n    }\n}\n// ----\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping_contract_key_getter.sol",
    "content": "interface A {}\ncontract test {\n    mapping(A => uint8) public table;\n    function set(A k, uint8 v) public {\n        table[k] = v;\n    }\n    function get(A k) public returns (uint8) {\n        return this.table(k);\n    }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping_contract_key_library.sol",
    "content": "interface A {}\nlibrary L {\n    function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n        return table[k];\n    }\n    function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n        table[k] = v;\n    }\n}\ncontract test {\n    mapping(A => uint8) table;\n    function get(A k) public returns (uint8 v) {\n        return L.get(table, k);\n    }\n    function set(A k, uint8 v) public {\n        L.set(table, k, v);\n    }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping_enum_key_getter_v1.sol",
    "content": "pragma abicoder v1;\ncontract test {\n    enum E { A, B, C }\n    mapping(E => uint8) public table;\n    function set(E k, uint8 v) public {\n        table[k] = v;\n    }\n    function get(E k) public returns (uint8) {\n        return this.table(k);\n    }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping_enum_key_getter_v2.sol",
    "content": "pragma abicoder               v2;\ncontract test {\n    enum E { A, B, C }\n    mapping(E => uint8) public table;\n    function set(E k, uint8 v) public {\n        table[k] = v;\n    }\n    function get(E k) public returns (uint8) {\n        return this.table(k);\n    }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping_enum_key_library_v1.sol",
    "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n    function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n        return table[k];\n    }\n    function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n        table[k] = v;\n    }\n}\ncontract test {\n    mapping(E => uint8) table;\n    function get(E k) public returns (uint8 v) {\n        return L.get(table, k);\n    }\n    function set(E k, uint8 v) public {\n        L.set(table, k, v);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping_enum_key_library_v2.sol",
    "content": "pragma abicoder v2;\n\nenum E { A, B, C }\nlibrary L {\n    function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n        return table[k];\n    }\n    function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n        table[k] = v;\n    }\n}\ncontract test {\n    mapping(E => uint8) table;\n    function get(E k) public returns (uint8 v) {\n        return L.get(table, k);\n    }\n    function set(E k, uint8 v) public {\n        L.set(table, k, v);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping_enum_key_v1.sol",
    "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n    mapping(E => uint8) table;\n    function get(E k) public returns (uint8 v) {\n        return table[k];\n    }\n    function set(E k, uint8 v) public {\n        table[k] = v;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping_enum_key_v2.sol",
    "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n    mapping(E => uint8) table;\n    function get(E k) public returns (uint8 v) {\n        return table[k];\n    }\n    function set(E k, uint8 v) public {\n        table[k] = v;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/mapping_simple.sol",
    "content": "contract test {\n    mapping(uint8 => uint8) table;\n    function get(uint8 k) public returns (uint8 v) {\n        return table[k];\n    }\n    function set(uint8 k, uint8 v) public {\n        table[k] = v;\n    }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/nested_tuples.sol",
    "content": "contract test {\n    function f0() public returns(int, bool) {\n        int a;\n        bool b;\n        ((a, b)) = (2, true);\n        return (a, b);\n    }\n    function f1() public returns(int) {\n        int a;\n        (((a, ), )) = ((1, 2) ,3);\n        return a;\n    }\n    function f2() public returns(int) {\n        int a;\n        (((, a),)) = ((1, 2), 3);\n        return a;\n    }\n    function f3() public returns(int) {\n        int a = 3;\n        ((, ), ) = ((7, 8), 9);\n        return a;\n    }\n    function f4() public returns(int) {\n        int a;\n        (a, ) = (4, (8, 16, 32));\n        return a;\n    }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/packing_signed_types.sol",
    "content": "contract test {\n    function run() public returns(int8 y) {\n        uint8 x = 0xfa;\n        return int8(x);\n    }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/packing_unpacking_types.sol",
    "content": "contract test {\n    function run(bool a, uint32 b, uint64 c) public returns(uint256 y) {\n        if (a) y = 1;\n        y = y * 0x100000000 | ~b;\n        y = y * 0x10000000000000000 | ~c;\n    }\n}\n// ----\n// run(bool,uint32,uint64): true, 0x0f0f0f0f, 0xf0f0f0f0f0f0f0f0\n// -> 0x0000000000000000000000000000000000000001f0f0f0f00f0f0f0f0f0f0f0f\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/strings.sol",
    "content": "contract test {\n    function fixedBytesHex() public returns(bytes32 ret) {\n        return hex\"aabb00ff\";\n    }\n    function fixedBytes() public returns(bytes32 ret) {\n        return \"abc\\x00\\xff__\";\n    }\n    function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {\n        oneRet = one;\n        large = small;\n    }\n}\n// ----\n// fixedBytesHex() -> \"\\xaa\\xbb\\x00\\xff\"\n// fixedBytes() -> \"abc\\x00\\xff__\"\n// pipeThrough(bytes2,bool): \"\\x00\\x02\", true -> \"\\x00\\x02\", true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/struct_mapping_abstract_constructor_param.sol",
    "content": "struct S {\n\tmapping (uint => uint) m;\n}\n\nabstract contract A {\n\tconstructor (S storage s) {\n\t\ts.m[5] = 16;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => S) m;\n\n\tconstructor() A(m[1]) {\n\t}\n\n\tfunction getM(uint a, uint b) external returns (uint) {\n\t\treturn m[a].m[b];\n\t}\n}\n// ----\n// getM(uint256,uint256): 0, 0 -> 0\n// getM(uint256,uint256): 1, 5 -> 0x10\n// getM(uint256,uint256): 1, 0 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/tuple_assign_multi_slot_grow.sol",
    "content": "contract C {\n\n\tfunction f() public pure returns (uint, uint, uint) {\n\t\tbytes memory a; bytes memory b; bytes memory c;\n\t\t(a, (b, c)) = (\"0\", (\"1\", \"2\"));\n\t\treturn (uint8(a[0]), uint8(b[0]), uint8(c[0]));\n\t}\n\n}\n// ----\n// f() -> 0x30, 0x31, 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/types/type_conversion_cleanup.sol",
    "content": "contract Test {\n    function test() public returns (uint ret) { return uint(uint160(address(uint160(uint128(type(uint200).max))))); }\n}\n// ----\n// test() -> 0xffffffffffffffffffffffffffffffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/underscore/as_function.sol",
    "content": "contract C {\n    function _() public pure returns (uint) {\n        return 88;\n    }\n\n    function g() public pure returns (uint){\n        return _();\n    }\n\n    function h() public pure returns (uint) {\n        _;\n        return 33;\n    }\n}\n// ----\n// _() -> 88\n// g() -> 88\n// h() -> 33\n"
  },
  {
    "path": "test/libsolidity/semanticTests/uninitializedFunctionPointer/invalidInConstructor.sol",
    "content": "contract C {\n\n  function() internal storedFn;\n\n  bool flag;\n\n  constructor() {\n    if (!flag) {\n      flag = true;\n      function() internal invalid;\n      storedFn = invalid;\n      invalid();\n    }\n  }\n  function f() public pure {}\n}\ncontract Test {\n  function f() public {\n    new C();\n  }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/uninitializedFunctionPointer/invalidStoredInConstructor.sol",
    "content": "contract C {\n\n  function() internal storedFn;\n\n  bool flag;\n\n  constructor() {\n    if (!flag) {\n      flag = true;\n      function() internal invalid;\n      storedFn = invalid;\n      storedFn();\n    }\n  }\n  function f() public pure {}\n}\ncontract Test {\n  function f() public {\n    new C();\n  }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/uninitializedFunctionPointer/store2.sol",
    "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract InvalidTest {\n\n  function() internal storedFn;\n  uint public x;\n\n  constructor() {\n    uint _y1;\n    uint _y2;\n    uint _y3;\n    uint _y4;\n    uint _y5;\n    uint _y6;\n    uint _y7;\n    uint _y8;\n    uint _y9;\n    uint _y10;\n    uint _y11;\n    uint _y12;\n    uint _y13;\n    uint _y14;\n\n\n    function() internal invalid;\n    storedFn = invalid;\n  }\n\n  function run() public {\n    // this did not always cause revert in the past\n    storedFn();\n  }\n\n  function z() public {\n      x++;\n  }\n}\n// ----\n// run() -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/uninitializedFunctionPointer/storeInConstructor.sol",
    "content": "contract InvalidTest {\n\n  function() internal storedFn;\n\n  bool flag;\n\n  constructor() {\n    function() internal invalid;\n    storedFn = invalid;\n  }\n  function f() public returns (uint) {\n    if (flag) return 2;\n    flag = true;\n    storedFn();\n  }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n"
  },
  {
    "path": "test/libsolidity/semanticTests/uninitializedFunctionPointer/uninitialized_internal_storage_function_legacy.sol",
    "content": "contract Test {\n\tfunction() internal x;\n\tfunction f() public returns (bool) {\n\t\tfunction() internal t = x;\n\t\t// The legacy codegen  would use a specific function\n\t\t// entry tag that always panics.\n\t\t// Via Yul, the internal dispatch will panic instead.\n\t\tuint z;\n\t\tassembly { z := t }\n\t\tassert(z != 0);\n\t\treturn true;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/uninitializedFunctionPointer/uninitialized_internal_storage_function_via_yul.sol",
    "content": "contract Test {\n\tfunction() internal x;\n\tfunction f() public returns (bool) {\n\t\tfunction() internal t = x;\n\t\t// The legacy codegen  would use a specific function\n\t\t// entry tag that always panics.\n\t\t// Via Yul, the internal dispatch will panic instead.\n\t\tuint z;\n\t\tassembly { z := t }\n\t\tassert(z == 0);\n\t\treturn true;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/abicodec.sol",
    "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n    type MyInt is int;\n    function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n        a = MyInt.wrap(-1);\n        b = MyInt.wrap(0);\n        c = MyInt.wrap(1);\n        d = x;\n    }\n    function g() external returns(bool) {\n        (bool success1, bytes memory ret1) =  address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n        assert(success1);\n\n        (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n        assert(MyInt.unwrap(a1) == -1);\n        assert(MyInt.unwrap(b1) == 0);\n        assert(MyInt.unwrap(c1) == 1);\n        assert(MyInt.unwrap(d1) == 5);\n\n        (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n        assert(success2);\n\n        (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n        assert(a2 == -1);\n        assert(b2 == 0);\n        assert(c2 == 1);\n        assert(d2 == -5);\n\n        return true;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/assembly_access_bytes2_abicoder_v1.sol",
    "content": "pragma abicoder v1;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n    function f(MyBytes2 val) external returns (bytes2 ret) {\n        assembly {\n            ret := val\n        }\n    }\n\n    function g(bytes2 val) external returns (bytes2 ret) {\n        assembly {\n            ret := val\n        }\n    }\n\n    function h(uint256 val) external returns (MyBytes2) {\n        MyBytes2 ret;\n        assembly {\n            ret := val\n        }\n        return ret;\n    }\n\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/assembly_access_bytes2_abicoder_v2.sol",
    "content": "pragma abicoder v2;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n    function f(MyBytes2 val) external returns (bytes2 ret) {\n        assembly {\n            ret := val\n        }\n    }\n\n    function g(bytes2 val) external returns (bytes2 ret) {\n        assembly {\n            ret := val\n        }\n    }\n\n    function h(uint256 val) external returns (MyBytes2) {\n        MyBytes2 ret;\n        assembly {\n            ret := val\n        }\n        return ret;\n    }\n\n}\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> FAILURE\n// g(bytes2): \"abcdef\" -> FAILURE\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/calldata.sol",
    "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n    MyAddress[] public addresses;\n    function f(MyAddress[] calldata _addresses) external {\n        for (uint i = 0; i < _addresses.length; i++) {\n            MyAddress.unwrap(_addresses[i]).call(\"\");\n        }\n        addresses = _addresses;\n    }\n    function g(MyAddress[] memory _addresses) external {\n        for (uint i = 0; i < _addresses.length; i++) {\n            MyAddress.unwrap(_addresses[i]).call(\"\");\n        }\n        addresses = _addresses;\n    }\n    function test_f() external returns (bool) {\n        clean();\n        MyAddress[] memory test = new MyAddress[](3);\n        test[0] = MyAddress.wrap(address(21));\n        test[1] = MyAddress.wrap(address(22));\n        test[2] = MyAddress.wrap(address(23));\n        this.f(test);\n        test_equality(test);\n        return true;\n    }\n    function test_g() external returns (bool) {\n        clean();\n        MyAddress[] memory test = new MyAddress[](5);\n        test[0] = MyAddress.wrap(address(24));\n        test[1] = MyAddress.wrap(address(25));\n        test[2] = MyAddress.wrap(address(26));\n        test[3] = MyAddress.wrap(address(27));\n        test[4] = MyAddress.wrap(address(28));\n        this.g(test);\n        test_equality(test);\n        return true;\n    }\n    function clean() internal {\n        delete addresses;\n    }\n    function test_equality(MyAddress[] memory _addresses) internal view {\n        require (_addresses.length == addresses.length);\n        for (uint i = 0; i < _addresses.length; i++) {\n            require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n        }\n    }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122114\n// gas legacy: 126159\n// gas legacyOptimized: 122742\n// test_g() -> true\n// gas irOptimized: 106248\n// gas legacy: 111821\n// gas legacyOptimized: 106591\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/calldata_to_storage.sol",
    "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n    S public s;\n    Small[] public small;\n    Left[] public l;\n    function f(S calldata _s) external {\n        s = _s;\n    }\n    function g(Small[] calldata _small) external returns (Small[] memory) {\n        small = _small;\n        return small;\n    }\n    function h(Left[] calldata _left) external returns (Left[] memory) {\n        l = _left;\n        return l;\n    }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44237\n// gas legacy: 47154\n// gas legacyOptimized: 44982\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 68578\n// gas legacy: 71400\n// gas legacyOptimized: 69139\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 68635\n// gas legacy: 71231\n// gas legacyOptimized: 69289\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/cleanup.sol",
    "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n    uint8 a;\n    MyUInt8 b;\n    uint8 c;\n    function ret() external returns(MyUInt8) {\n        return wrap(0x1ff);\n    }\n    function f(MyUInt8 x) external returns(MyUInt8) {\n        return x;\n    }\n    function mem() external returns (MyUInt8[] memory) {\n        MyUInt8[] memory x = new MyUInt8[](2);\n        x[0] = wrap(0x1ff);\n        x[1] = wrap(0xff);\n        require(unwrap(x[0]) == unwrap(x[1]));\n        assembly {\n            mstore(add(x, 0x20), 0x1ff)\n        }\n        require(unwrap(x[0]) == unwrap(x[1]));\n        return x;\n    }\n    function stor() external returns (uint8, MyUInt8, uint8) {\n        a = 1;\n        c = 2;\n        b = wrap(0x1ff);\n        return (a, b, c);\n    }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/cleanup_abicoderv1.sol",
    "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n    uint8 a;\n    MyUInt8 b;\n    uint8 c;\n    function ret() external returns(MyUInt8) {\n        return wrap(0x1ff);\n    }\n    function f(MyUInt8 x) external returns(MyUInt8) {\n        return x;\n    }\n    function mem() external returns (MyUInt8[] memory) {\n        MyUInt8[] memory x = new MyUInt8[](2);\n        x[0] = wrap(0x1ff);\n        x[1] = wrap(0xff);\n        require(unwrap(x[0]) == unwrap(x[1]));\n        assembly {\n            mstore(add(x, 0x20), 0x1ff)\n        }\n        require(unwrap(x[0]) == unwrap(x[1]));\n        return x;\n    }\n    function stor() external returns (uint8, MyUInt8, uint8) {\n        a = 1;\n        c = 2;\n        b = wrap(0x1ff);\n        return (a, b, c);\n    }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/constant.sol",
    "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n  T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n  T constant public t = s;\n  int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/conversion.sol",
    "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n    function f(uint a) external returns(MyUInt8) {\n        return MyUInt8.wrap(uint8(a));\n    }\n    function g(uint a) external returns(MyInt8) {\n        return MyInt8.wrap(int8(int(a)));\n    }\n    function h(MyUInt8 a) external returns (MyInt8) {\n        return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n    }\n    function i(MyUInt8 a) external returns(MyUInt16) {\n        return MyUInt16.wrap(MyUInt8.unwrap(a));\n    }\n    function j(MyUInt8 a) external returns (uint) {\n        return MyUInt8.unwrap(a);\n    }\n    function k(MyUInt8 a) external returns (MyUInt16) {\n        return MyUInt16.wrap(MyUInt8.unwrap(a));\n    }\n    function m(MyUInt16 a) external returns (MyUInt8) {\n        return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n    }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/conversion_abicoderv1.sol",
    "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n    function f(uint a) external returns(MyUInt8) {\n        return MyUInt8.wrap(uint8(a));\n    }\n    function g(uint a) external returns(MyInt8) {\n        return MyInt8.wrap(int8(int(a)));\n    }\n    function h(MyUInt8 a) external returns (MyInt8) {\n        return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n    }\n    function i(MyUInt8 a) external returns(MyUInt16) {\n        return MyUInt16.wrap(MyUInt8.unwrap(a));\n    }\n    function j(MyUInt8 a) external returns (uint) {\n        return MyUInt8.unwrap(a);\n    }\n    function k(MyUInt8 a) external returns (MyUInt16) {\n        return MyUInt16.wrap(MyUInt8.unwrap(a));\n    }\n    function m(MyUInt16 a) external returns (MyUInt8) {\n        return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n    }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/dirty_slot.sol",
    "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n    MyUInt16 public a = MyUInt16.wrap(13);\n    MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n    bytes2 public x;\n    function write_a() external {\n        uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n        assembly {\n            sstore(a.slot, max)\n        }\n    }\n    function write_b() external {\n        uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n        assembly {\n            sstore(b.slot, max)\n        }\n    }\n    function get_b(uint index) public returns (bytes1) {\n        return MyBytes2.unwrap(b)[index];\n    }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/dirty_uint8_read.sol",
    "content": "type MyInt8 is int8;\ncontract C {\n    MyInt8 public x = MyInt8.wrap(-5);\n\n    /// The most significant bit is flipped to 0\n    function create_dirty_slot() external {\n        uint mask  = 2**255 -1;\n        assembly {\n            let value := sload(x.slot)\n            sstore(x.slot, and(mask, value))\n        }\n    }\n\n    function read_unclean_value() external returns (bytes32 ret) {\n        MyInt8 value = x;\n        assembly {\n            ret := value\n        }\n    }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/erc20.sol",
    "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n    function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n        return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n    }\n    function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n        return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n    }\n}\n\ncontract ERC20 {\n    using FixedMath for UFixed18;\n\n    event Transfer(address indexed from, address indexed to, UFixed18 value);\n    event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n    mapping (address => UFixed18) private _balances;\n    mapping (address => mapping (address => UFixed18)) private _allowances;\n    UFixed18 private _totalSupply;\n\n    constructor() {\n        _mint(msg.sender, UFixed18.wrap(20));\n    }\n\n    function totalSupply() public view returns (UFixed18) {\n        return _totalSupply;\n    }\n\n    function balanceOf(address owner) public view returns (UFixed18) {\n        return _balances[owner];\n    }\n\n    function allowance(address owner, address spender) public view returns (UFixed18) {\n        return _allowances[owner][spender];\n    }\n\n    function transfer(address to, UFixed18 value) public returns (bool) {\n        _transfer(msg.sender, to, value);\n        return true;\n    }\n\n    function approve(address spender, UFixed18 value) public returns (bool) {\n        _approve(msg.sender, spender, value);\n        return true;\n    }\n\n    function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n        _transfer(from, to, value);\n        // The subtraction here will revert on overflow.\n        _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n        return true;\n    }\n\n    function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n        // The addition here will revert on overflow.\n        _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n        return true;\n    }\n\n    function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n        // The subtraction here will revert on overflow.\n        _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n        return true;\n    }\n\n    function _transfer(address from, address to, UFixed18 value) internal {\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        // The subtraction and addition here will revert on overflow.\n        _balances[from] = _balances[from].sub(value);\n        _balances[to] = _balances[to].add(value);\n        emit Transfer(from, to, value);\n    }\n\n    function _mint(address account, UFixed18 value) internal {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        // The additions here will revert on overflow.\n        _totalSupply = _totalSupply.add(value);\n        _balances[account] = _balances[account].add(value);\n        emit Transfer(address(0), account, value);\n    }\n\n    function _burn(address account, UFixed18 value) internal {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        // The subtractions here will revert on overflow.\n        _totalSupply = _totalSupply.sub(value);\n        _balances[account] = _balances[account].sub(value);\n        emit Transfer(account, address(0), value);\n    }\n\n    function _approve(address owner, address spender, UFixed18 value) internal {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = value;\n        emit Approval(owner, spender, value);\n    }\n\n    function _burnFrom(address account, UFixed18 value) internal {\n        _burn(account, value);\n        _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n    }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23334\n// gas legacy: 23645\n// gas legacyOptimized: 23367\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 50997\n// gas legacy: 52323\n// gas legacyOptimized: 51380\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26054\n// gas legacy: 27165\n// gas legacyOptimized: 26320\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 23954\n// gas legacy: 24500\n// gas legacyOptimized: 24076\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 33897\n// gas legacy: 35223\n// gas legacyOptimized: 34280\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 23990\n// gas legacy: 24483\n// gas legacyOptimized: 24072\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/fixedpoint.sol",
    "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n    uint constant multiplier = 10**18;\n    /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n    /// uint256.\n    function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n        return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n    }\n    /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n    /// uint256.\n    function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n        return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n    }\n    /// Take the floor of a UFixed256x18 number.\n    /// @return the largest integer that does not exceed `a`.\n    function floor(UFixed256x18 a) internal returns (uint256) {\n        return UFixed256x18.unwrap(a) / multiplier;\n    }\n    /// Turns a uint256 into a UFixed256x18 of the same value.\n    /// Reverts if the integer is too large.\n    function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n        return UFixed256x18.wrap(a * multiplier);\n    }\n}\n\ncontract TestFixedMath {\n    function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n        return FixedMath.add(a, b);\n    }\n    function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n        return FixedMath.mul(a, b);\n    }\n    function floor(UFixed256x18 a) external returns (uint256) {\n        return FixedMath.floor(a);\n    }\n    function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n        return FixedMath.toUFixed256x18(a);\n    }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/immutable_signed.sol",
    "content": "type MyInt is int16;\ntype MyBytes is bytes2;\ncontract C {\n    MyInt immutable a = MyInt.wrap(-2);\n    MyBytes immutable b = MyBytes.wrap(\"ab\");\n    function() internal returns (uint) immutable f = g;\n    function direct() view external returns (MyInt, MyBytes) {\n        return (a, b);\n    }\n    function viaasm() view external returns (bytes32 x, bytes32 y) {\n        MyInt _a = a;\n        MyBytes _b = b;\n        assembly { x := _a y := _b }\n    }\n    function g() internal pure returns (uint) { return 2; }\n}\n// ----\n// direct() -> -2, 0x6162000000000000000000000000000000000000000000000000000000000000\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/in_parenthesis.sol",
    "content": "type MyInt is int;\ncontract C {\n    function f() public returns (MyInt a, int b) {\n        (MyInt).wrap;\n        a = (MyInt).wrap(5);\n        (MyInt).unwrap;\n        b = (MyInt).unwrap((MyInt).wrap(10));\n    }\n}\n// ----\n// f() -> 5, 10\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/mapping_key.sol",
    "content": "type MyInt is int;\ncontract C {\n    mapping(MyInt => int) public m;\n    function set(MyInt key, int value) external {\n        m[key] = value;\n    }\n    function set_unwrapped(int key, int value) external {\n        m[MyInt.wrap(key)] = value;\n    }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/memory_to_storage.sol",
    "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n    S public s;\n    Small[] public small;\n    Left[] public l;\n    function f(S memory _s) public {\n        s = _s;\n    }\n    function g(Small[] memory _small) public returns (Small[] memory) {\n        small = _small;\n        return small;\n    }\n    function h(Left[] memory _left) public returns (Left[] memory) {\n        l = _left;\n        return l;\n    }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44360\n// gas legacy: 46189\n// gas legacyOptimized: 44673\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 68898\n// gas legacy: 72336\n// gas legacyOptimized: 69607\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 68937\n// gas legacy: 72167\n// gas legacyOptimized: 69802\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/multisource.sol",
    "content": "==== Source: A ====\ntype MyInt is int;\ntype MyAddress is address;\n==== Source: B ====\nimport {MyInt, MyAddress as OurAddress} from \"A\";\ncontract A {\n    function f(int x) external view returns(MyInt) { return MyInt.wrap(x); }\n    function f(address x) external view returns(OurAddress) { return OurAddress.wrap(x); }\n}\n// ----\n// f(int256): 5 -> 5\n// f(address): 1 -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/multisource_module.sol",
    "content": "==== Source: s1.sol ====\ntype MyInt is int;\n==== Source: s2.sol ====\nimport \"s1.sol\" as M;\ncontract C {\n  function f(int x) public pure returns (M.MyInt) { return M.MyInt.wrap(x); }\n  function g(M.MyInt x) public pure returns (int) { return M.MyInt.unwrap(x); }\n}\n// ----\n// f(int256): 5 -> 5\n// g(int256): 1 -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/ownable.sol",
    "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n    type Owner is address;\n    Owner public owner = Owner.wrap(msg.sender);\n    error OnlyOwner();\n    modifier onlyOwner() {\n        if (Owner.unwrap(owner) != msg.sender)\n            revert OnlyOwner();\n\n        _;\n    }\n    event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n    function setOwner(Owner newOwner) onlyOwner external {\n        emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n        owner = newOwner;\n    }\n    function renounceOwnership() onlyOwner external {\n        owner = Owner.wrap(address(0));\n    }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/parameter.sol",
    "content": "pragma abicoder v2;\n\ntype MyAddress is address;\ncontract C {\n    function id(MyAddress a) external returns (MyAddress b) {\n        b = a;\n    }\n\n    function unwrap_assembly(MyAddress a) external returns (address b) {\n        assembly { b := a }\n    }\n\n    function wrap_assembly(address a) external returns (MyAddress b) {\n        assembly { b := a }\n    }\n\n    function unwrap(MyAddress a) external returns (address b) {\n        b = MyAddress.unwrap(a);\n    }\n    function wrap(address a) external returns (MyAddress b) {\n        b = MyAddress.wrap(a);\n    }\n\n}\n// ----\n// id(address): 5 -> 5\n// id(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// id(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap(address): 5 -> 5\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap(address): 5 -> 5\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap_assembly(address): 5 -> 5\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap_assembly(address): 5 -> 5\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/simple.sol",
    "content": "type MyInt is int;\ncontract C {\n    function f() external pure returns (MyInt a) {\n    }\n    function g() external pure returns (MyInt b, MyInt c) {\n        b = MyInt.wrap(int(1));\n        c = MyInt.wrap(1);\n    }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/storage_layout.sol",
    "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n    MyInt8 a;\n    MyInt8 b;\n    MyInt8 c;\n    MyAddress d;\n\n    MyAddress e;\n\n    MyAddress f;\n    MyInt96 g;\n\n    function storage_a() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := a.slot\n            offset := a.offset\n        }\n    }\n\n    function storage_b() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := b.slot\n            offset := b.offset\n        }\n    }\n\n    function storage_c() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := d.slot\n            offset := c.offset\n        }\n    }\n    function storage_d() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := d.slot\n            offset := d.offset\n        }\n    }\n\n    function storage_e() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := e.slot\n            offset := e.offset\n        }\n    }\n\n    function storage_f() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := f.slot\n            offset := f.offset\n        }\n    }\n\n    function storage_g() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := g.slot\n            offset := g.offset\n        }\n    }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/storage_layout_struct.sol",
    "content": "type MyInt64 is int64;\nstruct HalfSlot {\n    MyInt64 a;\n    MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n    int64 a;\n    int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n    MyInt96 a;\n    MyAddress b;\n}\nstruct RegularFullSlot {\n    int96 a;\n    address b;\n}\n\ncontract C {\n    HalfSlot public a;\n    RegularHalfSlot public ra;\n\n    HalfSlot public b;\n    RegularHalfSlot public rb;\n\n    HalfSlot public c;\n    RegularHalfSlot public rc;\n\n    FullSlot public d;\n    RegularFullSlot public rd;\n\n    function storage_a() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := a.slot\n            offset := a.offset\n        }\n    }\n\n    function storage_ra() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := ra.slot\n            offset := ra.offset\n        }\n    }\n\n    function storage_b() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := b.slot\n            offset := b.offset\n        }\n    }\n\n    function storage_rb() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := rb.slot\n            offset := rb.offset\n        }\n    }\n\n   function storage_c() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := c.slot\n            offset := c.offset\n        }\n    }\n\n   function storage_rc() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := rc.slot\n            offset := rc.offset\n        }\n    }\n\n   function storage_d() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := d.slot\n            offset := d.offset\n        }\n    }\n\n   function storage_rd() pure external returns(uint slot, uint offset) {\n        assembly {\n            slot := rd.slot\n            offset := rd.offset\n        }\n    }\n\n\n   function set_a(MyInt64 _a, MyInt64 _b) external {\n       a.a = _a;\n       a.b = _b;\n   }\n\n   function set_ra(int64 _a, int64 _b) external {\n       ra.a = _a;\n       ra.b = _b;\n   }\n\n   function set_b(MyInt64 _a, MyInt64 _b) external {\n       b.a = _a;\n       b.b = _b;\n   }\n\n   function set_rb(int64 _a, int64 _b) external {\n       rb.a = _a;\n       rb.b = _b;\n   }\n\n   function set_c(MyInt64 _a, MyInt64 _b) external {\n       c.a = _a;\n       c.b = _b;\n   }\n\n   function set_rc(int64 _a, int64 _b) external {\n       rc.a = _a;\n       rc.b = _b;\n   }\n\n   function set_d(MyInt96 _a, MyAddress _b) external {\n       d.a = _a;\n       d.b = _b;\n   }\n\n   function set_rd(int96 _a, address _b) external {\n       rd.a = _a;\n       rd.b = _b;\n   }\n\n   function read_slot(uint slot) view external returns (uint value) {\n       assembly {\n           value := sload(slot)\n       }\n   }\n\n   function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n       b.a = MyInt64.wrap(-2);\n       b.b = MyInt64.wrap(-3);\n       HalfSlot memory x = b;\n       MyInt64 y = b.a;\n       MyInt64 z = b.b;\n       assembly {\n           rxa := mload(x)\n           rya := y\n           rxb := mload(add(x, 0x20))\n           ryb := z\n       }\n   }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/storage_signed.sol",
    "content": "type MyInt is int16;\ncontract C {\n    bytes2 first = \"ab\";\n    MyInt public a = MyInt.wrap(-2);\n    bytes2 third = \"ef\";\n    function direct() external returns (MyInt) {\n        return a;\n    }\n    function indirect() external returns (int16) {\n        return MyInt.unwrap(a);\n    }\n    function toMemDirect() external returns (MyInt[1] memory) {\n        return [a];\n    }\n    function toMemIndirect() external returns (int16[1] memory) {\n        return [MyInt.unwrap(a)];\n    }\n    function div() external returns (int16) {\n        return MyInt.unwrap(a) / 2;\n    }\n    function viaasm() external returns (bytes32 x) {\n        MyInt st = a;\n        assembly { x := st }\n    }\n}\n// ----\n// a() -> -2\n// direct() -> -2\n// indirect() -> -2\n// toMemDirect() -> -2\n// toMemIndirect() -> -2\n// div() -> -1\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/wrap_unwrap.sol",
    "content": "type MyAddress is address;\ncontract C {\n    function f() pure public {\n        MyAddress.wrap;\n        MyAddress.unwrap;\n    }\n}\n// ----\n// f() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/wrap_unwrap_via_contract_name.sol",
    "content": "contract C {\n    type T is uint;\n}\ncontract D {\n    function f(C.T x) public pure returns(uint) {\n        return C.T.unwrap(x);\n    }\n    function g(uint x) public pure returns(C.T) {\n        return C.T.wrap(x);\n    }\n    function h(uint x) public pure returns(uint) {\n        return f(g(x));\n    }\n    function i(C.T x) public pure returns(C.T) {\n        return g(f(x));\n    }\n}\n// ----\n// f(uint256): 0x42 -> 0x42\n// g(uint256): 0x42 -> 0x42\n// h(uint256): 0x42 -> 0x42\n// i(uint256): 0x42 -> 0x42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_elementary.sol",
    "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n    int x;\n    function setX(int _x) external {\n        x = _x;\n    }\n    function getX() view external returns (int) {\n        return x;\n    }\n    function add(int a, int b) view external returns (int) {\n        return a + b;\n    }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23311\n// gas legacy: 23473\n// gas legacyOptimized: 23309\n// setX(int256): 5 ->\n// gas irOptimized: 43464\n// gas legacy: 43718\n// gas legacyOptimized: 43513\n// getX() -> 5\n// gas irOptimized: 23311\n// gas legacy: 23473\n// gas legacyOptimized: 23309\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21623\n// gas legacy: 22354\n// gas legacyOptimized: 21768\n"
  },
  {
    "path": "test/libsolidity/semanticTests/userDefinedValueType/zero_cost_abstraction_comparison_userdefined.sol",
    "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n    int x;\n    function setX(MyInt _x) external {\n        x = MyInt.unwrap(_x);\n    }\n    function getX() view external returns (MyInt) {\n        return MyInt.wrap(x);\n    }\n    function add(MyInt a, MyInt b) pure external returns(MyInt) {\n        return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n    }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23311\n// gas legacy: 23599\n// gas legacyOptimized: 23309\n// setX(int256): 5 ->\n// gas irOptimized: 43464\n// gas legacy: 43718\n// gas legacyOptimized: 43513\n// getX() -> 5\n// gas irOptimized: 23311\n// gas legacy: 23599\n// gas legacyOptimized: 23309\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21623\n// gas legacy: 22480\n// gas legacyOptimized: 21768\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/calldata_memory_copy.sol",
    "content": "\ncontract C {\n    function f(uint[] calldata arr) external returns (uint) {\n        return arr.sum();\n    }\n}\n\nfunction sum(uint[] memory arr) returns (uint result) {\n    for(uint i = 0; i < arr.length; i++) {\n        result += arr[i];\n    }\n}\n\nusing {sum} for uint[];\n\n// ----\n// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/free_function_braces.sol",
    "content": "function id(uint x) pure returns (uint) {\n    return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n    return 0;\n}\n\ncontract C {\n    function f(uint z) pure external returns(uint) {\n        return z.id();\n    }\n\n    function g(uint z) pure external returns (uint) {\n        return z.zero();\n    }\n\n    using {id, zero} for uint;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/free_function_multi.sol",
    "content": "contract C {\n    function f(uint z) pure external returns(uint) {\n        return z.id();\n    }\n\n    using {id, zero, zero, id} for uint;\n\n    function g(uint z) pure external returns (uint) {\n        return z.zero();\n    }\n}\n\nfunction id(uint x) pure returns (uint) {\n    return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n    return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/free_functions_individual.sol",
    "content": "using {zero} for uint;\n\ncontract C {\n    using {id} for uint;\n\n    function f(uint z) pure external returns(uint) {\n        return z.id();\n    }\n\n    function g(uint z) pure external returns (uint) {\n        return z.zero();\n    }\n}\n\nfunction id(uint x) pure returns (uint) {\n    return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n    return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/imported_functions.sol",
    "content": "==== Source: A ====\nfunction inc(uint x) pure returns (uint) {\n    return x + 1;\n}\n\n==== Source: B ====\ncontract C {\n\tfunction f(uint x) public returns (uint) {\n        return x.f() + x.inc();\n    }\n}\nusing {A.inc, f} for uint;\nimport {inc as f} from \"A\";\nimport \"A\" as A;\n// ----\n// f(uint256): 5 -> 12\n// f(uint256): 10 -> 0x16\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/library_functions_inside_contract.sol",
    "content": "library L {\n    function externalFunction(uint a) external pure returns (uint) { return a * 1; }\n    function publicFunction(uint b) public pure returns (uint) { return b * 2; }\n    function internalFunction(uint c) internal pure returns (uint) { return c * 3; }\n}\n\ncontract C {\n    using {L.externalFunction} for uint;\n    using {L.publicFunction} for uint;\n    using {L.internalFunction} for uint;\n\n    function f() public pure returns (uint) {\n        uint x = 1;\n        return x.externalFunction();\n    }\n\n    function g() public pure returns (uint) {\n        uint x = 1;\n        return x.publicFunction();\n    }\n\n    function h() public pure returns (uint) {\n        uint x = 1;\n        return x.internalFunction();\n    }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// h() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/library_on_interface.sol",
    "content": "using L for I;\ninterface I { function f() external pure returns (uint); }\nlibrary L {\n    function execute(I i) internal pure returns (uint) {\n        return i.f();\n    }\n}\ncontract C is I {\n    function x() public view returns (uint) {\n        I i = this;\n        return i.execute();\n    }\n    function f() public pure returns (uint) { return 7; }\n}\n// ----\n// x() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/library_through_module.sol",
    "content": "==== Source: A ====\nlibrary L {\n    function id(uint x) internal pure returns (uint) {\n        return x;\n    }\n    function one_ext(uint) pure external returns(uint) {\n        return 1;\n    }\n    function empty() pure internal {\n    }\n\n}\n\n==== Source: B ====\ncontract C {\n    using M.L for uint;\n    function f(uint x) public pure returns (uint) {\n        return x.id();\n    }\n    function g(uint x) public pure returns (uint) {\n        return x.one_ext();\n    }\n}\n\nimport \"A\" as M;\n\n// ----\n// library: \"A\":L\n// f(uint256): 5 -> 5\n// f(uint256): 10 -> 10\n// g(uint256): 5 -> 1\n// g(uint256): 10 -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/module_renamed.sol",
    "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n    return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n    return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n        return (x.f(), y.g());\n    }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/private_library_function.sol",
    "content": "library L {\n    using {L.privateFunction} for uint;\n    function privateFunction(uint x) private pure returns (uint) { return x + 1; }\n    function f() public pure returns (uint) {\n        uint x = 1;\n        return x.privateFunction();\n    }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/recursive_import.sol",
    "content": "==== Source: A ====\nimport {T as U} from \"A\";\nimport \"A\" as X;\n\ntype T is uint;\nfunction f(T x) pure returns (T) { return T.wrap(T.unwrap(x) + 1); }\nfunction g(T x) pure returns (uint) { return T.unwrap(x) + 10; }\n\nusing { f } for X.X.U global;\nusing { g } for T global;\n\nfunction cr() pure returns (T) {}\n\n==== Source: B ====\nimport { cr } from \"A\";\n\ncontract C {\n    function f() public returns (uint) {\n        return cr().f().g();\n    }\n}\n// ----\n// f() -> 11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/using_global_all_the_types.sol",
    "content": "==== Source: A ====\nenum E {A, B}\nstruct S { uint x; }\ntype T is uint;\nusing L for E global;\nusing L for S global;\nusing L for T global;\nlibrary L {\n    function f(E e) internal pure returns (uint) {\n        return uint(e);\n    }\n    function f(S memory s) internal pure returns (uint) {\n        return s.x;\n    }\n    function f(T t) internal pure returns (uint) {\n        return T.unwrap(t);\n    }\n}\n\n==== Source: B ====\ncontract C {\n    function f() public pure returns (uint a, uint b, uint c) {\n        E e = E.B;\n        a = e.f();\n        S memory s;\n        s.x = 7;\n        b = s.f();\n        T t = T.wrap(9);\n        c = t.f();\n    }\n}\n\nimport {E, S, T} from \"A\";\n\n// ----\n// f() -> 1, 7, 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/using_global_for_global.sol",
    "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n    using { g } for global;\n    function f(global r) public pure returns (global) {\n        return r.f().g();\n    }\n}\n// ----\n// f(uint256): 100 -> 111"
  },
  {
    "path": "test/libsolidity/semanticTests/using/using_global_invisible.sol",
    "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n    function inc(T x) internal pure returns (T) {\n        return T.wrap(T.unwrap(x) + 1);\n    }\n    function dec(T x) external pure returns (T) {\n        return T.wrap(T.unwrap(x) - 1);\n    }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n    return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n    function f() public pure returns (T r1) {\n        r1 = r1.inc().inc();\n    }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n    function test() public returns (uint) {\n        C c = new C();\n        // This tests that attached functions are available\n        // even if the type is not available by name.\n        // This is a regular function call, a\n        // public and an internal library call\n        // and a free function call.\n        return c.f().inc().inc().dec().unwrap();\n    }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/using/using_global_library.sol",
    "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n    function inc(T x) internal pure returns (T) {\n        return T.wrap(T.unwrap(x) + 1);\n    }\n    function dec(T x) external pure returns (T) {\n        return T.wrap(T.unwrap(x) - 1);\n    }\n}\n\n==== Source: B ====\ncontract C {\n    function f() public pure returns (T r1, T r2) {\n        r1 = r1.inc().inc();\n        r2 = r1.dec();\n    }\n}\n\nimport {T} from \"A\";\n\n// ----\n// library: \"A\":L\n// f() -> 2, 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/delete_local.sol",
    "content": "contract test {\n    function delLocal() public returns (uint res){\n        uint v = 5;\n        delete v;\n        res = v;\n    }\n}\n// ----\n// delLocal() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/delete_locals.sol",
    "content": "contract test {\n    function delLocal() public returns (uint res1, uint res2){\n        uint v = 5;\n        uint w = 6;\n        uint x = 7;\n        delete v;\n        res1 = w;\n        res2 = x;\n    }\n}\n// ----\n// delLocal() -> 6, 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/delete_transient_state_variable.sol",
    "content": "contract C {\n    uint transient x;\n    function f() public returns (uint) {\n        x = 10;\n        delete x;\n        return x;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/delete_transient_state_variable_non_zero_offset.sol",
    "content": "contract C {\n    bytes14 transient x;\n    uint32  transient y;\n    uint112 transient z;\n\n    function f() public returns (bytes14, uint32, uint112) {\n        x = 0xffffffffffffffffffffffffffff;\n        y = 0xffffffff;\n        z = 0xffffffffffffffffffffffffffff;\n        delete y;\n        return (x, y, z);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/mapping_local_assignment.sol",
    "content": "contract test {\n    mapping(uint8 => uint8) m1;\n    mapping(uint8 => uint8) m2;\n    function f() public returns (uint8, uint8, uint8, uint8) {\n        mapping(uint8 => uint8) storage m = m1;\n        m[1] = 42;\n\n        m = m2;\n        m[2] = 21;\n\n        return (m1[1], m1[2], m2[1], m2[2]);\n    }\n}\n// ----\n// f() -> 42, 0, 0, 21\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/mapping_local_compound_assignment.sol",
    "content": "contract test {\n    mapping(uint8 => uint8) m1;\n    mapping(uint8 => uint8) m2;\n    function f() public returns (uint8, uint8, uint8, uint8) {\n        mapping(uint8 => uint8) storage m = m1;\n        m[1] = 42;\n\n        (m = m2)[2] = 21;\n\n        return (m1[1], m1[2], m2[1], m2[2]);\n    }\n}\n// ----\n// f() -> 42, 0, 0, 21\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/mapping_local_tuple_assignment.sol",
    "content": "contract test {\n    mapping(uint8 => uint8) m1;\n    mapping(uint8 => uint8) m2;\n    function f() public returns (uint8, uint8, uint8, uint8) {\n        mapping(uint8 => uint8) storage m = m1;\n        m[1] = 42;\n\n        uint8 v;\n        (m, v) = (m2, 21);\n        m[2] = v;\n\n        return (m1[1], m1[2], m2[1], m2[2]);\n    }\n}\n// ----\n// f() -> 42, 0, 0, 21\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/public_state_overridding.sol",
    "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/public_state_overridding_dynamic_struct.sol",
    "content": "pragma abicoder               v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test() external virtual returns (uint256 v, string memory s)\n\t{\n\t    v = 42;\n\t    s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tS public override test;\n\n\tfunction set() public { test.v = 2; test.s = \"statevar\"; }\n}\n// ----\n// test() -> 0, 64, 0\n// set() ->\n// test() -> 2, 0x40, 8, \"statevar\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/public_state_overridding_mapping_to_dynamic_struct.sol",
    "content": "pragma abicoder               v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test(uint256 x) external virtual returns (uint256 v, string memory s)\n\t{\n\t    v = x;\n\t    s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tmapping(uint256 => S) public override test;\n\n\tfunction set() public { test[42].v = 2; test[42].s = \"statevar\"; }\n}\n// ----\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 0, 64, 0\n// set() ->\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 2, 0x40, 8, \"statevar\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/storing_invalid_boolean.sol",
    "content": "contract C {\n    event Ev(bool);\n    bool public perm;\n    function set() public returns(uint) {\n        bool tmp;\n        assembly {\n            tmp := 5\n        }\n        perm = tmp;\n        return 1;\n    }\n    function ret() public returns(bool) {\n        bool tmp;\n        assembly {\n            tmp := 5\n        }\n        return tmp;\n    }\n    function ev() public returns(uint) {\n        bool tmp;\n        assembly {\n            tmp := 5\n        }\n        emit Ev(tmp);\n        return 1;\n    }\n}\n// ----\n// set() -> 1\n// perm() -> true\n// ret() -> true\n// ev() -> 1\n// ~ emit Ev(bool): true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/transient_function_type_state_variable.sol",
    "content": "contract C {\n    function () external transient f;\n    function g() external {\n    }\n\n    function test() public returns (bool) {\n        assert(f != this.g);\n        f = this.g;\n\n        return f == this.g;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/transient_state_address_variable_members.sol",
    "content": "contract C {\n    address transient a;\n    function f() public returns (uint) {\n        a = msg.sender;\n        return a.balance;\n    }\n    function g() public returns (uint) {\n        return a.balance;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas legacy: 59027\n// gas legacy code: 70400\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// f() -> 1267650600228229401496703205376\n// g() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/transient_state_enum_variable.sol",
    "content": "contract C {\n    enum Pets { Dog, Cat, Bird, Fish }\n    Pets transient myPet;\n\n    function f() public {\n        myPet = Pets.Bird;\n        this.g();\n        assert(myPet == Pets.Cat);\n    }\n    function g() public {\n        myPet = Pets.Cat;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/transient_state_variable.sol",
    "content": "contract C {\n    uint transient public x;\n\n    function f() public {\n        x = 8;\n    }\n    function g() public returns (uint) {\n        x = 0;\n        this.f();\n        return x;\n    }\n    function h() public returns (uint) {\n        return x;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_assignment.sol",
    "content": "contract C {\n    uint8 transient x;\n    function f() public returns(uint256 r) {\n        uint8 y;\n        assembly { y := 0xFFFF }\n        x = y;\n        assembly {\n            r := tload(x.slot)\n        }\n\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/transient_state_variable_cleanup_tstore.sol",
    "content": "contract C {\n    uint8 transient x;\n    function f() public returns(uint256 r) {\n        assembly {\n            tstore(x.slot, 0xFFFF)\n        }\n       return x;\n\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/transient_state_variable_slot_inline_assembly.sol",
    "content": "contract C {\n    uint256 y;\n    uint256 transient x;\n    int8 transient w;\n    int z;\n    address transient a;\n    function f() public returns(uint256 s, uint256 o) {\n        assembly {\n            s := x.slot\n            o := x.offset\n        }\n    }\n    function g() public returns(uint256 s, uint256 o) {\n        assembly {\n            s := w.slot\n            o := w.offset\n        }\n    }\n    function h() public returns(uint256 s, uint256 o) {\n        assembly {\n            s := a.slot\n            o := a.offset\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0, 0\n// g() -> 1, 0\n// h() -> 1, 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/transient_state_variable_slots_and_offsets.sol",
    "content": "contract C {\n    uint128 transient x;\n    uint64 transient y;\n    uint64 transient w;\n    uint256 transient z;\n\n    function f() external returns (uint128, uint64, uint64, uint256) {\n        x = 1;\n        y = 2;\n        w = 3;\n        z = 4;\n\n        return (x, y, w, z);\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 2, 3, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/transient_state_variable_tuple_assignment.sol",
    "content": "contract C {\n    uint transient x;\n    uint y;\n    uint transient w;\n    uint z;\n\n    function f() public returns (uint, uint, uint) {\n        x = 1;\n        y = 2;\n        w = 3;\n        z = 4;\n\n        (x, y, w) = (y, w, z);\n        return (x, y, w);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/variables/transient_state_variable_udvt.sol",
    "content": "type MyInt is int256;\ncontract C {\n    MyInt transient public x;\n\n    function f() public {\n        x = MyInt.wrap(2);\n    }\n    function g() public returns (MyInt) {\n        x = MyInt.wrap(0);\n        this.f();\n        return x;\n    }\n    function h() public returns (MyInt) {\n        return x;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 2\n// h() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/address_code.sol",
    "content": "contract C {\n    bytes public initCode;\n\n    constructor() {\n        // This should catch problems, but lets also test the case the optimiser is buggy.\n        assert(address(this).code.length == 0);\n        initCode = address(this).code;\n    }\n\n    // To avoid dependency on exact length.\n    function f() public view returns (bool) { return address(this).code.length > 380; }\n    function g() public view returns (uint) { return address(0).code.length; }\n    function h() public view returns (uint) { return address(1).code.length; }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// constructor() ->\n// gas irOptimized: 70924\n// gas irOptimized code: 94600\n// gas legacy: 82688\n// gas legacy code: 153800\n// gas legacyOptimized: 69675\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/address_code_complex.sol",
    "content": "contract A {\n    constructor() {\n        assembly {\n            // This is only 7 bytes here.\n            mstore(0, 0x48aa5566000000)\n            return(0, 32)\n        }\n    }\n}\n\ncontract C {\n    function f() public returns (bytes memory) { return address(new A()).code; }\n    function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/assignment_to_const_var_involving_expression.sol",
    "content": "contract C {\n    uint256 constant x = 0x123 + 0x456;\n\n    function f() public returns (uint256) {\n        return x + 1;\n    }\n}\n// ----\n// f() -> 0x57a\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/balance.sol",
    "content": "contract test {\n    constructor() payable {}\n\n    function getBalance() public returns (uint256 balance) {\n        return address(this).balance;\n    }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/byte_optimization_bug.sol",
    "content": "contract C {\n    function f(uint256 x) public returns (uint256 a) {\n        assembly {\n            a := byte(x, 31)\n        }\n    }\n\n    function g(uint256 x) public returns (uint256 a) {\n        assembly {\n            a := byte(31, x)\n        }\n    }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/code_access_content.sol",
    "content": "contract D {\n    bytes32 public x;\n\n    constructor() {\n        bytes32 codeHash;\n        assembly {\n            let size := codesize()\n            codecopy(mload(0x40), 0, size)\n            codeHash := keccak256(mload(0x40), size)\n        }\n        x = codeHash;\n    }\n}\n\n\ncontract C {\n    function testRuntime() public returns (bool) {\n        D d = new D();\n        bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n        bytes32 otherHash;\n        uint256 size;\n        assembly {\n            size := extcodesize(d)\n            extcodecopy(d, mload(0x40), 0, size)\n            otherHash := keccak256(mload(0x40), size)\n        }\n        require(size == type(D).runtimeCode.length);\n        require(runtimeHash == otherHash);\n        return true;\n    }\n\n    function testCreation() public returns (bool) {\n        D d = new D();\n        bytes32 creationHash = keccak256(type(D).creationCode);\n        require(creationHash == d.x());\n        return true;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/code_access_create.sol",
    "content": "// TODO: Recreate this test when eofcreate will be allowed in inline assembly.\ncontract D {\n    uint256 x;\n\n    constructor() {\n        x = 7;\n    }\n\n    function f() public view returns (uint256) {\n        return x;\n    }\n}\n\n\ncontract C {\n    function test() public returns (uint256) {\n        bytes memory c = type(D).creationCode;\n        D d;\n        assembly {\n            d := create(0, add(c, 0x20), mload(c))\n        }\n        return d.f();\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/code_access_padding.sol",
    "content": "contract D {\n    function f() public pure returns (uint256) {\n        return 7;\n    }\n}\n\n\ncontract C {\n    function diff() public pure returns (uint256 remainder) {\n        bytes memory a = type(D).creationCode;\n        bytes memory b = type(D).runtimeCode;\n        assembly {\n            remainder := mod(sub(b, a), 0x20)\n        }\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/code_access_runtime.sol",
    "content": "contract D {\n    uint256 x;\n\n    constructor() {\n        x = 7;\n    }\n\n    function f() public view returns (uint256) {\n        return x;\n    }\n}\n\ncontract C {\n    function test() public returns (uint256) {\n        D d = new D();\n        bytes32 hash;\n        assembly { hash := extcodehash(d) }\n        assert(hash == keccak256(type(D).runtimeCode));\n        return 42;\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// bytecodeFormat: legacy\n// ----\n// test() -> 42\n// gas legacy: 76034\n// gas legacy code: 24200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/code_length.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n    uint len1;\n    uint len2;\n    constructor() {\n        uint mem_ptr_before;\n        uint mem_ptr_after;\n\n        assembly {\n            mem_ptr_before := mload(64)\n        }\n\n        len1 = address(0).code.length;\n\n        assembly {\n            mem_ptr_after := mload(64)\n        }\n\n        // To check that no memory was allocated and written.\n        assert(mem_ptr_before == mem_ptr_after);\n\n        len2 = address(this).code.length;\n\n        // To check that no memory was allocated and written.\n        assembly {\n            mem_ptr_after := mload(64)\n        }\n\n        assert(mem_ptr_before == mem_ptr_after);\n\n    }\n\n    function f() public view returns (bool r1, bool r2) {\n        uint mem_ptr_before;\n        uint mem_ptr_after;\n\n        assembly {\n            mem_ptr_before := mload(64)\n        }\n\n        r1 = address(this).code.length > 50;\n\n        assembly {\n            mem_ptr_after := mload(64)\n        }\n\n        // To check that no memory was allocated and written.\n        assert(mem_ptr_before == mem_ptr_after);\n\n        address a = address(0);\n        r2 = a.code.length == 0;\n\n        // To check that no memory was allocated and written.\n        assembly {\n            mem_ptr_after := mload(64)\n        }\n\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/code_length_contract_member.sol",
    "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n    bytes32 code;\n    bytes32 another;\n}\n\ncontract C {\n    S s;\n\n    function f() public returns (uint, uint, bool) {\n        return (s.code.length, s.another.length, address(this).code.length > 50);\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// f() -> 0x20, 0x20, true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/codebalance_assembly.sol",
    "content": "contract C {\n    constructor() payable {}\n\n    function f() public returns (uint256 ret) {\n        assembly {\n            ret := balance(0)\n        }\n    }\n    function g() public returns (uint256 ret) {\n        assembly {\n            ret := balance(1)\n        }\n    }\n    function h() public returns (uint256 ret) {\n        assembly {\n            ret := balance(address())\n        }\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 56667\n// gas legacy code: 42000\n// f() -> 0\n// g() -> 1\n// h() -> 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/codehash.sol",
    "content": "contract C {\n    function f() public returns (bytes32) {\n        // non-existent in tests\n        return address(0).codehash;\n    }\n    function g() public returns (bytes32) {\n        // precompile\n        return address(0x1).codehash;\n    }\n    function h() public returns (bool) {\n        return address(this).codehash != 0;\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// bytecodeFormat: legacy\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/codehash_assembly.sol",
    "content": "contract C {\n    function f() public returns (bytes32 ret) {\n        assembly {\n            ret := extcodehash(0)\n        }\n    }\n    function g() public returns (bytes32 ret) {\n        assembly {\n            ret := extcodehash(1)\n        }\n    }\n    function h() public returns (bool ret) {\n        assembly {\n            ret := iszero(iszero(extcodehash(address())))\n        }\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// bytecodeFormat: legacy\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/contract_binary_dependencies.sol",
    "content": "contract A {\n    function f() public {\n        new B();\n    }\n}\n\n\ncontract B {\n    function f() public {}\n}\n\n\ncontract C {\n    function f() public {\n        new B();\n    }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 56611\n// gas irOptimized code: 39400\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/crazy_elementary_typenames_on_stack.sol",
    "content": "contract C {\n    function f() public returns (uint256 r) {\n        uint256;\n        uint256;\n        uint256;\n        uint256;\n        int256 x = -7;\n        return uint256(x);\n    }\n}\n// ----\n// f() -> -7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/create_calldata.sol",
    "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68387\n// gas irOptimized code: 69000\n// gas legacy: 78348\n// gas legacy code: 90200\n// gas legacyOptimized: 68548\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/create_random.sol",
    "content": "contract C {\n    function addr() external returns (address) {\n        return address(this);\n    }\n\n    function testRunner() external returns (address a1, address a2) {\n        assembly {\n            // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n            // instability due to metadata changes.\n            let initcode := hex\"60016000f3\"\n            mstore(0, initcode)\n\n            a1 := create(0, 0, 5)\n            a2 := create2(0, 0, 5, address())\n        }\n    }\n\n    function testCalc() external returns (address a1, address a2) {\n        a1 = calculateCreate(address(this), 1);\n        a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n    }\n\n    function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n        assert(nonce <= 127);\n        bytes memory data =\n            bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n        return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n    }\n\n    function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n        return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// bytecodeFormat: legacy\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/cross_contract_types.sol",
    "content": "contract Lib {\n    struct S {\n        uint256 a;\n        uint256 b;\n    }\n}\n\n\ncontract Test {\n    function f() public returns (uint256 r) {\n        Lib.S memory x = Lib.S({a: 2, b: 3});\n        r = x.b;\n    }\n}\n// ----\n// f() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/decayed_tuple.sol",
    "content": "contract C {\n    function f() public returns (uint256) {\n        uint256 x = 1;\n        (x) = 2;\n        return x;\n    }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/destructuring_assignment.sol",
    "content": "contract C {\n    uint256 x = 7;\n    bytes data;\n    uint256[] y;\n    uint256[] arrayData;\n\n    function returnsArray() public returns (uint256[] memory) {\n        arrayData = new uint256[](9);\n        arrayData[2] = 5;\n        arrayData[7] = 4;\n        return arrayData;\n    }\n\n    function f(bytes memory s) public returns (uint256) {\n        uint256 loc;\n        uint256[] memory memArray;\n        (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n        if (loc != 8) return 1;\n        if (x != 4) return 2;\n        if (y.length != 9) return 3;\n        if (y[2] != 5) return 4;\n        if (y[7] != 4) return 5;\n        if (data.length != s.length) return 6;\n        if (data[3] != s[3]) return 7;\n        if (arrayData[3] != 2) return 8;\n        (memArray, loc) = (arrayData, 3);\n        if (loc != 3) return 9;\n        if (memArray.length != arrayData.length) return 10;\n        bytes memory memBytes;\n        (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n        if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n    }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242037\n// gas legacy: 246685\n// gas legacyOptimized: 242396\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/different_call_type_transient.sol",
    "content": "contract B {\n    uint256 transient public value;\n\n    function setValue(uint256 v) public {\n        value += v;\n    }\n}\n\ncontract A {\n    uint256 transient public value;\n\n    function delegateSetValue(address otherContract, uint256 v) public {\n        (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n        require(success);\n    }\n    function callSetValue(address otherContract, uint256 v) public {\n        (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n        require(success);\n    }\n    function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n        (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n        return success;\n    }\n}\n\ncontract Test {\n    A a = new A();\n    B b = new B();\n\n    function testDelegate() public returns (uint256, uint256) {\n        a.delegateSetValue(address(b), 7);\n        return (a.value(), b.value());\n    }\n    function testCall() public returns (uint256, uint256) {\n        a.callSetValue(address(b), 8);\n        return (a.value(), b.value());\n    }\n    function testStatic() view public returns (bool) {\n        return a.staticSetValue(address(b), 0);\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/empty_name_return_parameter.sol",
    "content": "contract test {\n    function f(uint256 k) public returns (uint256) {\n        return k;\n    }\n}\n// ----\n// f(uint256): 9 -> 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/eof/create_calldata.sol",
    "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x, bytes memory b) {\n\t\t// On EOF msg.data contains constructor arguments, while on legacy it's empty\n\t\t// (arguments are appended to the code).\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 288);\n\t\tuint y;\n\t\tbytes memory d;\n\t\t(y, d) = abi.decode(msg.data, (uint256, bytes));\n\t\tassert(x == y);\n\t\tassert(b.length == d.length);\n\t\tfor (uint i = 0; i < b.length; ++i)\n\t\t\tassert(b[i] == d[i]);\n\t}\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// constructor(): 42, 0x20, 0xc0, 1, 2, 3, 4, 5, 6 ->\n// s() -> 0x20, 0x0120, 42, 0x20, 0xc0, 1, 2, 3, 4, 5, 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/erc20.sol",
    "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n    event Transfer(address indexed from, address indexed to, uint256 value);\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    mapping (address => uint256) private _balances;\n    mapping (address => mapping (address => uint256)) private _allowances;\n    uint256 private _totalSupply;\n\n    constructor() {\n        _mint(msg.sender, 20);\n    }\n\n    function totalSupply() public view returns (uint256) {\n        return _totalSupply;\n    }\n\n    function balanceOf(address owner) public view returns (uint256) {\n        return _balances[owner];\n    }\n\n    function allowance(address owner, address spender) public view returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    function transfer(address to, uint256 value) public returns (bool) {\n        _transfer(msg.sender, to, value);\n        return true;\n    }\n\n    function approve(address spender, uint256 value) public returns (bool) {\n        _approve(msg.sender, spender, value);\n        return true;\n    }\n\n    function transferFrom(address from, address to, uint256 value) public returns (bool) {\n        _transfer(from, to, value);\n        // The subtraction here will revert on overflow.\n        _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n        return true;\n    }\n\n    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n        // The addition here will revert on overflow.\n        _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n        return true;\n    }\n\n    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n        // The subtraction here will revert on overflow.\n        _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n        return true;\n    }\n\n    function _transfer(address from, address to, uint256 value) internal {\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        // The subtraction and addition here will revert on overflow.\n        _balances[from] = _balances[from] - value;\n        _balances[to] = _balances[to] + value;\n        emit Transfer(from, to, value);\n    }\n\n    function _mint(address account, uint256 value) internal {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        // The additions here will revert on overflow.\n        _totalSupply = _totalSupply + value;\n        _balances[account] = _balances[account] + value;\n        emit Transfer(address(0), account, value);\n    }\n\n    function _burn(address account, uint256 value) internal {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        // The subtractions here will revert on overflow.\n        _totalSupply = _totalSupply - value;\n        _balances[account] = _balances[account] - value;\n        emit Transfer(account, address(0), value);\n    }\n\n    function _approve(address owner, address spender, uint256 value) internal {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = value;\n        emit Approval(owner, spender, value);\n    }\n\n    function _burnFrom(address account, uint256 value) internal {\n        _burn(account, value);\n        _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n    }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23334\n// gas legacy: 23519\n// gas legacyOptimized: 23367\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 51054\n// gas legacy: 52073\n// gas legacyOptimized: 51298\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26087\n// gas legacy: 26977\n// gas legacyOptimized: 26279\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 23981\n// gas legacy: 24462\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 33954\n// gas legacy: 34973\n// gas legacyOptimized: 34198\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24020\n// gas legacy: 24445\n// gas legacyOptimized: 24052\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/external_types_in_calls.sol",
    "content": "contract C1 {\n    C1 public bla;\n\n    constructor(C1 x) {\n        bla = x;\n    }\n}\n\n\ncontract C {\n    function test() public returns (C1 x, C1 y) {\n        C1 c = new C1(C1(address(9)));\n        x = c.bla();\n        y = this.t1(C1(address(7)));\n    }\n\n    function t1(C1 a) public returns (C1) {\n        return a;\n    }\n\n    function t2() public returns (C1) {\n        return C1(address(9));\n    }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/flipping_sign_tests.sol",
    "content": "contract test {\n    function f() public returns (bool) {\n        int256 x = -2**255;\n        unchecked { assert(-x == x); }\n        return true;\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/gasleft_decrease.sol",
    "content": "contract C {\n    uint256 v;\n\n    function f() public returns (bool) {\n        uint256 startGas = gasleft();\n        v++;\n        assert(startGas > gasleft());\n        return true;\n    }\n\n    function g() public returns (bool) {\n        uint256 startGas = gasleft();\n        assert(startGas > gasleft());\n        return true;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// f() -> true\n// g() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/gasleft_shadow_resolution.sol",
    "content": "contract C {\n    function gasleft() public returns (uint256) {\n        return 0;\n    }\n\n    function f() public returns (uint256) {\n        return gasleft();\n    }\n}\n// ----\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/inline_member_init.sol",
    "content": "contract test {\n    constructor() {\n        m_b = 6;\n        m_c = 8;\n    }\n\n    uint256 m_a = 5;\n    uint256 m_b;\n    uint256 m_c = 7;\n\n    function get() public returns (uint256 a, uint256 b, uint256 c) {\n        a = m_a;\n        b = m_b;\n        c = m_c;\n    }\n}\n// ----\n// get() -> 5, 6, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/inline_member_init_inheritence.sol",
    "content": "contract Base {\n    constructor() {}\n\n    uint256 m_base = 5;\n\n    function getBMember() public returns (uint256 i) {\n        return m_base;\n    }\n}\n\n\ncontract Derived is Base {\n    constructor() {}\n\n    uint256 m_derived = 6;\n\n    function getDMember() public returns (uint256 i) {\n        return m_derived;\n    }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/inline_tuple_with_rational_numbers.sol",
    "content": "contract c {\n    function f() public returns (int8) {\n        int8[5] memory foo3 = [int8(1), -1, 0, 0, 0];\n        return foo3[0];\n    }\n}\n// ----\n// f() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/iszero_bnot_correct.sol",
    "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n    function f() public returns (bool) {\n        bytes32 x = bytes32(uint256(1));\n        assembly {\n            x := not(x)\n        }\n        if (x != ~bytes32(uint256(1))) return false;\n        assembly {\n            x := iszero(x)\n        }\n        if (x != bytes32(0)) return false;\n        return true;\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/literal_empty_string.sol",
    "content": "contract C {\n    bytes32 public x;\n    uint256 public a;\n\n    function f(bytes32 _x, uint256 _a) public {\n        x = _x;\n        a = _a;\n    }\n\n    function g() public {\n        this.f(\"\", 2);\n    }\n}\n// ----\n// x() -> 0\n// a() -> 0\n// g() ->\n// x() -> 0\n// a() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/many_subassemblies.sol",
    "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n    function run() public {\n        // This is primarily meant to test assembly import via --import-asm-json.\n        // The exported JSON will fail the reimport unless the subassembly indices are parsed\n        // correctly - as hex numbers.\n        new C0{salt: hex\"00\"}();\n        new C1{salt: hex\"01\"}();\n        new C2{salt: hex\"02\"}();\n        new C3{salt: hex\"03\"}();\n        new C4{salt: hex\"04\"}();\n        new C5{salt: hex\"05\"}();\n        new C6{salt: hex\"06\"}();\n        new C7{salt: hex\"07\"}();\n        new C8{salt: hex\"08\"}();\n        new C9{salt: hex\"09\"}();\n        new C10{salt: hex\"0a\"}();\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// run() ->\n// gas irOptimized: 375192\n// gas irOptimized code: 6600\n// gas legacy: 375404\n// gas legacy code: 17600\n// gas legacyOptimized: 375464\n// gas legacyOptimized code: 17600\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/memory_overwrite.sol",
    "content": "contract C {\n    function f() public returns (bytes memory x) {\n        x = \"12345\";\n        x[3] = 0x61;\n        x[0] = 0x62;\n    }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/multi_modifiers.sol",
    "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n    uint256 public x;\n    modifier m1 {\n        address a1 = msg.sender;\n        x++;\n        _;\n    }\n\n    function f1() public m1() {\n        x += 7;\n    }\n\n    function f2() public m1() {\n        x += 3;\n    }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/multi_variable_declaration.sol",
    "content": "contract C {\n    function g() public returns (uint256 a, uint256 b, uint256 c) {\n        a = 1;\n        b = 2;\n        c = 3;\n    }\n\n    function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n        a = 1;\n        b = 2;\n        c = 3;\n        d = 4;\n    }\n\n    function f1() public returns (bool) {\n        (uint256 x, uint256 y, uint256 z) = g();\n        if (x != 1 || y != 2 || z != 3) return false;\n        (, uint256 a, ) = g();\n        if (a != 2) return false;\n        (uint256 b, , ) = g();\n        if (b != 1) return false;\n        (, , uint256 c) = g();\n        if (c != 3) return false;\n        return true;\n    }\n\n    function f2() public returns (bool) {\n        (uint256 a1, , uint256 a3, ) = h();\n        if (a1 != 1 || a3 != 3) return false;\n        (uint256 b1, uint256 b2, , ) = h();\n        if (b1 != 1 || b2 != 2) return false;\n        (, uint256 c2, uint256 c3, ) = h();\n        if (c2 != 2 || c3 != 3) return false;\n        (, , uint256 d3, uint256 d4) = h();\n        if (d3 != 3 || d4 != 4) return false;\n        (uint256 e1, , uint256 e3, uint256 e4) = h();\n        if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n        return true;\n    }\n\n    function f() public returns (bool) {\n        return f1() && f2();\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/negative_stack_height.sol",
    "content": "contract C {\n    mapping(uint256 => Invoice) public invoices;\n    struct Invoice {\n        uint256 AID;\n        bool Aboola;\n        bool Aboolc;\n        bool exists;\n    }\n\n    function nredit(uint256 startindex)\n        public\n        pure\n        returns (\n            uint256[500] memory CIDs,\n            uint256[500] memory dates,\n            uint256[500] memory RIDs,\n            bool[500] memory Cboolas,\n            uint256[500] memory amounts\n        )\n    {}\n\n    function return500InvoicesByDates(\n        uint256 begindate,\n        uint256 enddate,\n        uint256 startindex\n    )\n        public\n        view\n        returns (\n            uint256[500] memory AIDs,\n            bool[500] memory Aboolas,\n            uint256[500] memory dates,\n            bytes32[3][500] memory Abytesas,\n            bytes32[3][500] memory bytesbs,\n            bytes32[2][500] memory bytescs,\n            uint256[500] memory amounts,\n            bool[500] memory Aboolbs,\n            bool[500] memory Aboolcs\n        )\n    {}\n\n    function return500PaymentsByDates(\n        uint256 begindate,\n        uint256 enddate,\n        uint256 startindex\n    )\n        public\n        view\n        returns (\n            uint256[500] memory BIDs,\n            uint256[500] memory dates,\n            uint256[500] memory RIDs,\n            bool[500] memory Bboolas,\n            bytes32[3][500] memory bytesbs,\n            bytes32[2][500] memory bytescs,\n            uint256[500] memory amounts,\n            bool[500] memory Bboolbs\n        )\n    {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/nested_calldata_struct.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    struct S1 {\n        uint256 a;\n        uint256 b;\n    }\n    struct S2 {\n        uint256 a;\n        uint256 b;\n        S1 s;\n        uint256 c;\n    }\n\n    function f(S2 calldata s)\n        external\n        pure\n        returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n    {\n        return (s.a, s.b, s.s.a, s.s.b, s.c);\n    }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/nested_calldata_struct_to_memory.sol",
    "content": "pragma abicoder               v2;\n\n\ncontract C {\n    struct S1 {\n        uint256 a;\n        uint256 b;\n    }\n    struct S2 {\n        uint256 a;\n        uint256 b;\n        S1 s;\n        uint256 c;\n    }\n\n    function f(S2 calldata s)\n        external\n        pure\n        returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n    {\n        S2 memory m = s;\n        return (m.a, m.b, m.s.a, m.s.b, m.c);\n    }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/positive_integers_to_signed.sol",
    "content": "contract test {\n    int8 public x = 2;\n    int8 public y = 127;\n    int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/selfdestruct_post_cancun.sol",
    "content": "contract C {\n    constructor() payable {}\n\n    function terminate() external {\n        // NOTE: The contract `c` should still exist in the test below\n        // when the call to selfdestruct is executed in a transaction\n        // different from the one in which the contract was created.\n        // However, it should still send all Ether in `c` to the beneficiary.\n        selfdestruct(payable(msg.sender));\n        assert(false);\n    }\n}\n\ncontract D {\n    C public c;\n\n    constructor() payable {}\n\n    function deploy_create() public payable {\n        c = new C{value: 1 ether}();\n    }\n\n    function deploy_create2() public payable {\n        c = new C{value: 1 ether, salt: hex\"1234\"}();\n    }\n\n    function terminate() public {\n        // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n        // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n        c.terminate();\n    }\n\n    function test_create_and_terminate() public {\n        deploy_create();\n        assert(exists());\n        test_balance_after_create();\n        terminate();\n        test_balance_after_selfdestruct();\n    }\n\n    function test_create2_and_terminate() public {\n        deploy_create2();\n        assert(exists());\n        test_balance_after_create();\n        terminate();\n        test_balance_after_selfdestruct();\n    }\n\n    function test_balance_after_create() public view {\n        assert(address(this).balance == 0);\n        assert(address(c).balance == 1 ether);\n    }\n\n    function test_balance_after_selfdestruct() public view {\n        assert(address(this).balance == 1 ether);\n        assert(address(c).balance == 0);\n    }\n\n    function exists() public view returns (bool) {\n        return address(c).code.length != 0;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// bytecodeFormat: legacy\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/selfdestruct_post_cancun_multiple_beneficiaries.sol",
    "content": "contract C {\n    constructor() payable {}\n    function terminate(address _beneficiary) public {\n        selfdestruct(payable(_beneficiary));\n        assert(false);\n    }\n}\n\ncontract D {\n    address account1 = payable(0x1111111111111111111111111111111111111111);\n    address account2 = payable(0x2222222222222222222222222222222222222222);\n    C public c;\n\n    constructor() payable {}\n\n    function deploy() public payable {\n        c = new C{value: 1 ether}();\n    }\n\n    function terminate(address _beneficiary) public {\n        c.terminate(_beneficiary);\n    }\n\n    function test_deploy_and_terminate_twice() public {\n        deploy();\n        terminate(account1);\n        terminate(account2);\n    }\n\n    function exists() public view returns (bool) {\n        return address(c).code.length != 0;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// bytecodeFormat: legacy\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/selfdestruct_post_cancun_redeploy.sol",
    "content": "contract Factory {\n    event Deployed(address, bytes32);\n\n    function deploy(bytes32 _salt) external payable returns (address implAddr) {\n        // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n        // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n        //contract C {\n        //    constructor() payable {}\n        //    function terminate() external {\n        //        selfdestruct(payable(msg.sender));\n        //    }\n        //}\n        bytes memory initCode =\n            hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n            hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n            hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n            hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n        address target = address(uint160(uint256(keccak256(abi.encodePacked(\n            bytes1(0xff),\n            address(this),\n            _salt,\n            keccak256(abi.encodePacked(initCode))\n        )))));\n\n        assembly {\n            implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n            if iszero(extcodesize(implAddr)) {\n                revert(0, 0)\n            }\n        }\n        assert(address(implAddr) == target);\n        emit Deployed(implAddr, _salt);\n    }\n}\n\ninterface IC {\n    function terminate() external;\n}\n\ncontract D {\n    Factory public factory = new Factory();\n    IC public c;\n\n    constructor() payable {}\n\n    function deploy_create2() public payable {\n        // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n        // if not performed in the same transaction.\n        // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n        c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n    }\n\n    function terminate() public {\n        c.terminate();\n    }\n\n    function test_deploy_and_terminate() public {\n        deploy_create2();\n        assert(exists());\n        test_balance_after_create();\n        terminate();\n        test_balance_after_selfdestruct();\n    }\n\n    function test_balance_after_create() public view {\n        assert(address(this).balance == 0);\n        assert(address(c).balance == 1 ether);\n    }\n\n    function test_balance_after_selfdestruct() public view {\n        assert(address(this).balance == 1 ether);\n        assert(address(c).balance == 0);\n    }\n\n    function exists() public view returns (bool) {\n        return address(c).code.length != 0;\n    }\n}\n\n// ====\n// EVMVersion: >=cancun\n// bytecodeFormat: legacy\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/selfdestruct_pre_cancun.sol",
    "content": "contract C {\n    constructor() payable {}\n\n    function terminate() external {\n        // NOTE: The contract `c` should still exists in the test below,\n        // since the call to the selfdestruct method was done in a tx that is\n        // not the same tx that the contract was created.\n        // However, it should send all Ether in `c` to the beneficiary.\n        selfdestruct(payable(msg.sender));\n        assert(false);\n    }\n}\n\ncontract D {\n    C public c;\n\n    constructor() payable {}\n\n    function deploy_create() public payable {\n        c = new C{value: 1 ether}();\n    }\n\n    function deploy_create2() public payable {\n        c = new C{value: 1 ether, salt: hex\"1234\"}();\n    }\n\n    function terminate() public {\n        c.terminate();\n    }\n\n    function test_create_and_terminate() public {\n        deploy_create();\n        assert(exists());\n        test_balance_after_create();\n        terminate();\n        test_balance_after_selfdestruct();\n    }\n\n    function test_create2_and_terminate() public {\n        deploy_create2();\n        assert(exists());\n        test_balance_after_create();\n        terminate();\n        test_balance_after_selfdestruct();\n    }\n\n    function test_balance_after_create() public view {\n        assert(address(this).balance == 0);\n        assert(address(c).balance == 1 ether);\n    }\n\n    function test_balance_after_selfdestruct() public view {\n        assert(address(this).balance == 1 ether);\n        assert(address(c).balance == 0);\n    }\n\n    function exists() public view returns (bool) {\n        return address(c).code.length != 0;\n    }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_multiple_beneficiaries.sol",
    "content": "contract C {\n    constructor() payable {}\n    function terminate(address _beneficiary) public {\n        selfdestruct(payable(_beneficiary));\n        assert(false);\n    }\n}\n\ncontract D {\n    address account1 = payable(0x1111111111111111111111111111111111111111);\n    address account2 = payable(0x2222222222222222222222222222222222222222);\n    C public c;\n\n    constructor() payable {}\n\n    function deploy() public payable {\n        c = new C{value: 1 ether}();\n    }\n\n    function terminate(address _beneficiary) public {\n        c.terminate(_beneficiary);\n    }\n\n    function test_deploy_and_terminate_twice() public {\n        deploy();\n        terminate(account1);\n        terminate(account2);\n    }\n\n    function exists() public view returns (bool) {\n        return address(c).code.length != 0;\n    }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/selfdestruct_pre_cancun_redeploy.sol",
    "content": "contract Factory {\n    event Deployed(address, bytes32);\n\n    function deploy(bytes32 _salt) external payable returns (address implAddr) {\n        // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n        // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n        //contract C {\n        //    constructor() payable {}\n        //    function terminate() external {\n        //        selfdestruct(payable(msg.sender));\n        //    }\n        //}\n        bytes memory initCode =\n            hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n            hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n            hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n            hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n        address target = address(uint160(uint256(keccak256(abi.encodePacked(\n            bytes1(0xff),\n            address(this),\n            _salt,\n            keccak256(abi.encodePacked(initCode))\n        )))));\n\n        assembly {\n            implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n            if iszero(extcodesize(implAddr)) {\n                revert(0, 0)\n            }\n        }\n        assert(address(implAddr) == target);\n        emit Deployed(implAddr, _salt);\n    }\n}\n\ninterface IC {\n    function terminate() external;\n}\n\ncontract D {\n    Factory public factory = new Factory();\n    IC public c;\n\n    constructor() payable {}\n\n    function deploy_create2() public payable {\n        c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n    }\n\n    function terminate() public {\n        c.terminate();\n    }\n\n    function test_deploy_and_terminate() public {\n        deploy_create2();\n        assert(exists());\n        test_balance_after_create();\n        terminate();\n        test_balance_after_selfdestruct();\n    }\n\n    function test_balance_after_create() public view {\n        assert(address(this).balance == 0);\n        assert(address(c).balance == 1 ether);\n    }\n\n    function test_balance_after_selfdestruct() public view {\n        assert(address(this).balance == 1 ether);\n        assert(address(c).balance == 0);\n    }\n\n    function exists() public view returns (bool) {\n        return address(c).code.length != 0;\n    }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/senders_balance.sol",
    "content": "contract C {\n    function f() public view returns (uint256) {\n        return msg.sender.balance;\n    }\n}\n\n\ncontract D {\n    C c = new C();\n\n    constructor() payable {}\n\n    function f() public view returns (uint256) {\n        return c.f();\n    }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/single_copy_with_multiple_inheritance.sol",
    "content": "contract Base {\n    uint256 data;\n\n    function setData(uint256 i) public {\n        data = i;\n    }\n\n    function getViaBase() public returns (uint256 i) {\n        return data;\n    }\n}\n\n\ncontract A is Base {\n    function setViaA(uint256 i) public {\n        setData(i);\n    }\n}\n\n\ncontract B is Base {\n    function getViaB() public returns (uint256 i) {\n        return getViaBase();\n    }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/skip_dynamic_types.sol",
    "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n    function f() public returns (uint256, uint256[] memory, uint256) {\n        return (7, new uint256[](2), 8);\n    }\n\n    function g() public returns (uint256, uint256) {\n        // Previous implementation \"moved\" b to the second place and did not skip.\n        (uint256 a, , uint256 b) = this.f();\n        return (a, b);\n    }\n}\n// ----\n// g() -> 7, 8\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/skip_dynamic_types_for_static_arrays_with_dynamic_elements.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        bool[] b;\n    }\n\n    function f() public returns (uint256, bool[][2] memory, S[2] memory, uint256) {\n        return (\n            5,\n            [new bool[](1), new bool[](2)],\n            [S(new bool[](2)), S(new bool[](5))],\n            6\n        );\n    }\n\n    function g() public returns (uint256, uint256) {\n        (uint256 a, , , uint256 b) = this.f();\n        return (a, b);\n    }\n}\n// ----\n// g() -> 5, 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol",
    "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n    struct S {\n        uint256 x;\n        string a; // this is present in the accessor\n        uint256[] b; // this is not present\n        uint256 y;\n    }\n    S public s;\n\n    function g() public returns (uint256, uint256) {\n        s.x = 2;\n        s.a = \"abc\";\n        s.b = [7, 8, 9];\n        s.y = 6;\n        (uint256 x, , uint256 y) = this.s();\n        return (x, y);\n    }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 181357\n// gas legacyOptimized: 179055\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/state_variable_local_variable_mixture.sol",
    "content": "contract A {\n    uint256 x = 1;\n    uint256 y = 2;\n\n    function a() public returns (uint256 x) {\n        x = A.y;\n    }\n}\n// ----\n// a() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/state_variable_under_contract_name.sol",
    "content": "contract Scope {\n    uint256 stateVar = 42;\n\n    function getStateVar() public view returns (uint256 stateVar) {\n        stateVar = Scope.stateVar;\n    }\n}\n// ----\n// getStateVar() -> 42\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol",
    "content": "contract C {\n    uint256 x;\n\n    function f() public returns (uint256) {\n        x = 3;\n        return 1;\n    }\n}\n\n\ninterface CView {\n    function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n    function f() external pure returns (uint256);\n}\n\n\ncontract D {\n    function f() public returns (uint256) {\n        return (new C()).f();\n    }\n\n    function fview() public returns (uint256) {\n        return (CView(address(new C()))).f();\n    }\n\n    function fpure() public returns (uint256) {\n        return (CPure(address(new C()))).f();\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/staticcall_for_view_and_pure_pre_byzantium.sol",
    "content": "contract C {\n    uint256 x;\n\n    function f() public returns (uint256) {\n        x = 3;\n        return 1;\n    }\n}\n\n\ninterface CView {\n    function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n    function f() external pure returns (uint256);\n}\n\n\ncontract D {\n    function f() public returns (uint256) {\n        return (new C()).f();\n    }\n\n    function fview() public returns (uint256) {\n        return (CView(address(new C()))).f();\n    }\n\n    function fpure() public returns (uint256) {\n        return (CPure(address(new C()))).f();\n    }\n}\n// ====\n// EVMVersion: <byzantium\n// ----\n// f() -> 0x1\n// fview() -> 1\n// fpure() -> 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/storage_string_as_mapping_key_without_variable.sol",
    "content": "contract Test {\n    mapping(string => uint256) data;\n\n    function f() public returns (uint256) {\n        data[\"abc\"] = 2;\n        return data[\"abc\"];\n    }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/store_bytes.sol",
    "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n    function save() public returns (uint256 r) {\n        r = 23;\n        savedData = msg.data;\n        r = 24;\n    }\n\n    bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/string_tuples.sol",
    "content": "contract C {\n    function f() public returns (string memory, uint256) {\n        return (\"abc\", 8);\n    }\n\n    function g() public returns (string memory, string memory) {\n        return (h(), \"def\");\n    }\n\n    function h() public returns (string memory) {\n        return (\"abc\");\n    }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/super.sol",
    "content": "contract A {\n    function f() public virtual returns (uint256 r) {\n        return 1;\n    }\n}\n\n\ncontract B is A {\n    function f() public virtual override returns (uint256 r) {\n        return super.f() | 2;\n    }\n}\n\n\ncontract C is A {\n    function f() public virtual override returns (uint256 r) {\n        return super.f() | 4;\n    }\n}\n\n\ncontract D is B, C {\n    function f() public override(B, C) returns (uint256 r) {\n        return super.f() | 8;\n    }\n}\n// ----\n// f() -> 15\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/super_alone.sol",
    "content": "contract A {\n    function f() public {\n        super;\n    }\n}\n// ----\n// f() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/super_parentheses.sol",
    "content": "contract A {\n    function f() public virtual returns (uint256 r) {\n        return 1;\n    }\n}\n\n\ncontract B is A {\n    function f() public virtual override returns (uint256 r) {\n        return ((super).f)() | 2;\n    }\n}\n\n\ncontract C is A {\n    function f() public virtual override returns (uint256 r) {\n        return ((super).f)() | 4;\n    }\n}\n\n\ncontract D is B, C {\n    function f() public override(B, C) returns (uint256 r) {\n        return ((super).f)() | 8;\n    }\n}\n// ----\n// f() -> 15\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol",
    "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n    struct S {\n        uint256 a;\n        uint256 b;\n    }\n    S public x;\n    S public y;\n\n    function set() public {\n        x.a = 1;\n        x.b = 2;\n        y.a = 3;\n        y.b = 4;\n    }\n\n    function swap() public {\n        (x, y) = (y, x);\n    }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/test_underscore_in_hex.sol",
    "content": "contract test {\n    function f(bool cond) public pure returns (uint256) {\n        uint32 x = 0x1234_ab;\n        uint256 y = 0x1234_abcd_1234;\n        return cond ? x : y;\n    }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/transient_storage_reentrancy_lock.sol",
    "content": "contract C {\n    bool transient locked;\n    modifier nonReentrant {\n        require(!locked, \"Reentrancy attempt\");\n        locked = true;\n        _;\n        locked = false;\n    }\n\n    function test(address newAddress, bool reentrancy) nonReentrant public {\n        if (reentrancy)\n            reentrantCall(newAddress);\n    }\n\n    function reentrantCall(address a) public {\n        this.test(a, false);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/tuples.sol",
    "content": "contract C {\n    uint256[] data;\n    uint256[] m_c;\n\n    function g() internal returns (uint256 a, uint256 b, uint256[] storage c) {\n        return (1, 2, data);\n    }\n\n    function h() external returns (uint256 a, uint256 b) {\n        return (5, 6);\n    }\n\n    function f() public returns (uint256) {\n        data.push(3);\n        uint256 a;\n        uint256 b;\n        (a, b) = this.h();\n        if (a != 5 || b != 6) return 1;\n        uint256[] storage c = m_c;\n        (a, b, c) = g();\n        if (a != 1 || b != 2 || c[0] != 3) return 2;\n        (a, b) = (b, a);\n        if (a != 2 || b != 1) return 3;\n        (a, , b, , ) = (8, 9, 10, 11, 12);\n        if (a != 8 || b != 10) return 4;\n    }\n}\n// ----\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/typed_multi_variable_declaration.sol",
    "content": "contract C {\n    struct S {\n        uint256 x;\n    }\n    S s;\n\n    function g() internal returns (uint256, S storage, uint256) {\n        s.x = 7;\n        return (1, s, 2);\n    }\n\n    function f() public returns (bool) {\n        (uint256 x1, S storage y1, uint256 z1) = g();\n        if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n        (, S storage y2, ) = g();\n        if (y2.x != 7) return false;\n        (uint256 x2, , ) = g();\n        if (x2 != 1) return false;\n        (, , uint256 z2) = g();\n        if (z2 != 2) return false;\n        return true;\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/various/write_storage_external.sol",
    "content": "contract C {\n    uint256 public x;\n\n    function f(uint256 y) public payable {\n        x = y;\n    }\n\n    function g(uint256 y) external {\n        x = y;\n    }\n\n    function h() public {\n        this.g(12);\n    }\n}\n\n\ncontract D {\n    C c = new C();\n\n    function f() public payable returns (uint256) {\n        c.g(3);\n        return c.x();\n    }\n\n    function g() public returns (uint256) {\n        c.g(8);\n        return c.x();\n    }\n\n    function h() public returns (uint256) {\n        c.h();\n        return c.x();\n    }\n}\n// ----\n// f() -> 3\n// g() -> 8\n// h() -> 12\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/assert.sol",
    "content": "contract C {\n    function f(bool a) public pure returns (bool x) {\n        bool b = a;\n        x = b;\n        assert(b);\n    }\n    function fail() public pure returns (bool x) {\n        x = true;\n        assert(false);\n    }\n    function succeed() public pure returns (bool x) {\n        x = true;\n        assert(true);\n    }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/assert_and_require.sol",
    "content": "contract C {\n    function f(bool a) public pure returns (bool x) {\n        bool b = a;\n        x = b;\n        assert(b);\n    }\n    function f2(bool a) public pure returns (bool x) {\n        bool b = a;\n        x = b;\n        require(b);\n    }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/assign_tuple_from_function_call.sol",
    "content": "contract C {\n    function f() public pure returns (uint, uint, uint) {\n        return (1, 2, 3);\n    }\n    function g() public pure returns (uint a, uint b, uint c) {\n        (c, b, a) = f();\n    }\n    function h() public pure returns (uint a) {\n        (,,a) = f();\n    }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/cleanup/checked_arithmetic.sol",
    "content": "contract C {\n\tfunction add() public pure returns (uint8, uint8) {\n\t\tuint8 x; uint8 y = 0;\n\t\tassembly { x := 0x0101 }\n\t\treturn (x + y, y + x);\n\t}\n\tfunction sub() public pure returns (uint8, uint8) {\n\t\tuint8 x; uint8 y = 1;\n\t\tassembly { x := 0x0101 }\n\t\treturn (x - y, y - x);\n\t}\n\tfunction mul() public pure returns (uint8, uint8) {\n\t\tuint8 x; uint8 y = 1;\n\t\tassembly { x := 0x0101 }\n\t\treturn (x * y, y * x);\n\t}\n\tfunction div() public pure returns (uint8, uint8) {\n\t\tuint8 x; uint8 y = 1;\n\t\tassembly { x := 0x0101 }\n\t\treturn (x / y, y / x);\n\t}\n\tfunction mod() public pure returns (uint8, uint8) {\n\t\tuint8 x; uint8 y = 2;\n\t\tassembly { x := 0x0101 }\n\t\treturn (x % y, y % x);\n\t}\n\tfunction inc_pre() public pure returns (uint8) {\n\t\tuint8 x;\n\t\tassembly { x := 0x0100 }\n\t\treturn ++x;\n\t}\n\tfunction inc_post() public pure returns (uint8) {\n\t\tuint8 x;\n\t\tassembly { x := 0x0100 }\n\t\treturn x++;\n\t}\n\tfunction dec_pre() public pure returns (uint8) {\n\t\tuint8 x;\n\t\tassembly { x := not(0xFF) }\n\t\treturn --x;\n\t}\n\tfunction dec_post() public pure returns (uint8) {\n\t\tuint8 x;\n\t\tassembly { x := not(0xFF) }\n\t\treturn x--;\n\t}\n\tfunction neg() public pure returns (int8) {\n\t\tint8 x;\n\t\tassembly { x := 0x80 }\n\t\treturn -x;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// add() -> 1, 1\n// sub() -> 0, 0\n// mul() -> 1, 1\n// div() -> 1, 1\n// mod() -> 1, 0\n// inc_pre() -> 1\n// inc_post() -> 0\n// dec_pre() -> FAILURE, hex\"4e487b71\", 0x11\n// dec_post() -> FAILURE, hex\"4e487b71\", 0x11\n// neg() -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/cleanup/comparison.sol",
    "content": "contract C {\n\tfunction eq() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x == y);\n\t}\n\tfunction neq() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x != y);\n\t}\n\tfunction geq() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x >= y);\n\t}\n\tfunction leq() public pure returns (bool) {\n\t\tuint8 x = 2; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x <= y);\n\t}\n\tfunction gt() public pure returns (bool) {\n\t\tuint8 x = 2; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x > y);\n\t}\n\tfunction lt() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x < y);\n\t}\n}\n// ----\n// eq() -> true\n// neq() -> false\n// geq() -> true\n// leq() -> false\n// gt() -> true\n// lt() -> false\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/comparison.sol",
    "content": "contract C {\n    function f(address a) public pure returns (bool) {\n        return a == address(0);\n    }\n    function g() public pure returns (bool) {\n        return bytes3(\"abc\") == bytes4(\"abc\");\n    }\n    function lt(uint a, uint b) public pure returns (bool) {\n        return a < b;\n    }\n    function slt(int a, int b) public pure returns (bool) {\n        return a < b;\n    }\n    function lte(uint a, uint b) public pure returns (bool) {\n        return a <= b;\n    }\n    function slte(int a, int b) public pure returns (bool) {\n        return a <= b;\n    }\n    function gt(uint a, uint b) public pure returns (bool) {\n        return a > b;\n    }\n    function sgt(int a, int b) public pure returns (bool) {\n        return a > b;\n    }\n    function gte(uint a, uint b) public pure returns (bool) {\n        return a >= b;\n    }\n    function sgte(int a, int b) public pure returns (bool) {\n        return a >= b;\n    }\n    function eq(uint a, uint b) public pure returns (bool) {\n        return a == b;\n    }\n    function neq(uint a, uint b) public pure returns (bool) {\n        return a != b;\n    }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/comparison_functions.sol",
    "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv  = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv  = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conditional/conditional_multiple.sol",
    "content": "contract A {\n\tfunction f() public pure returns (uint) {\n\t\tuint x = 3 < 0 ? 2 > 1 ? 2 : 1 : 7 > 2 ? 7 : 6;\n\t\treturn x;\n\t}\n}\n// ----\n// f() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conditional/conditional_true_false_literal.sol",
    "content": "contract A {\n\tfunction f() public pure returns (uint) {\n\t\tuint x = true ? 1 : 0;\n\t\tuint y = false ? 0 : 1;\n\t\treturn x + y;\n\t}\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conditional/conditional_tuple.sol",
    "content": "contract A {\n\tfunction f(bool cond) public pure returns (uint, uint) {\n\t\t(uint a, uint b) = cond ? (1, 2) : (3, 4);\n\t\treturn (a, b);\n\t}\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conditional/conditional_with_assignment.sol",
    "content": "contract A {\n    function f() public pure returns (uint, uint, uint, uint) {\n\t\tuint y1 = 1;\n\t\tuint y2 = 1;\n\t\tuint x = 3 < 0 ? y1 = 3 : 6;\n\t\tuint z = 3 < 10 ? y2 = 5 : 6;\n\t\treturn (x, y1, y2, z);\n\t}\n}\n// ----\n// f() -> 6, 1, 5, 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conditional/conditional_with_variables.sol",
    "content": "contract A {\n\tfunction f() public pure returns (uint, uint, uint, uint) {\n\t\tuint x = 3;\n\t\tuint y = 1;\n\t\tuint z = (x > y) ? x : y;\n\t\tuint w = x < y ? x : y;\n\t\treturn (x, y, z, w);\n\t}\n}\n// ----\n// f() -> 3, 1, 3, 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conversion/explicit_cast_assignment.sol",
    "content": "contract C {\n    function f() public pure returns (uint16 x) {\n        uint8 y = uint8(0x78);\n        x = y;\n    }\n}\n// ----\n// f() -> 0x78\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conversion/explicit_cast_function_call.sol",
    "content": "contract C {\n    function f(bytes32 b) public pure returns (bytes32 x) {\n        x = b;\n    }\n    function g() public pure returns (bytes32 x) {\n        x = f(bytes4(uint32(0x12345678)));\n    }\n}\n// ----\n// g() -> 0x1234567800000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conversion/explicit_cast_local_assignment.sol",
    "content": "contract C {\n    function f(uint a) public pure returns (uint8 x) {\n        uint8 b = uint8(a);\n        x = b;\n    }\n}\n// ----\n// f(uint256): 0x12345678 -> 0x78\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conversion/explicit_string_bytes_calldata_cast.sol",
    "content": "// Triggered ICE before\ncontract C {\n\tfunction f(string calldata data) external pure returns(string memory) {\n\t\tbytes calldata test = bytes(data[:3]);\n\t\treturn string(test);\n\t}\n}\n// ----\n// f(string): 0x20, 3, \"123\" -> 0x20, 3, \"123\"\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conversion/function_cast.sol",
    "content": "contract C {\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn 2 * x;\n\t}\n\tfunction g() public view returns (function (uint) external returns (uint)) {\n\t\treturn this.f;\n\t}\n\tfunction h(uint x) public returns (uint) {\n\t\treturn this.g()(x) + 1;\n\t}\n\tfunction t() external view returns (\n\t\tfunction(uint) external returns (uint) a,\n\t\tfunction(uint) external view returns (uint) b\n\t) {\n\t\ta = C(address(0x1234)).f;\n\t\tb = C(address(0x1234)).f;\n\t}\n}\n// ----\n// f(uint256): 2 -> 4\n// h(uint256): 2 -> 5\n// t() -> 0x1234b3de648b0000000000000000, 0x1234b3de648b0000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conversion/implicit_cast_assignment.sol",
    "content": "// Tests IRGeneratorForStatements::visit(Assignment const& _assignment)\ncontract C {\n    function f() public pure returns (uint16 x) {\n        uint8 y;\n        assembly {\n            y := 0x12345678\n        }\n        x = y;\n    }\n}\n// ----\n// f() -> 0x78\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conversion/implicit_cast_function_call.sol",
    "content": "// IRGeneratorForStatements::visit(FunctionCall const& _functionCall)\ncontract C {\n    function f(uint b) public pure returns (uint x) {\n        x = b;\n    }\n    function g() public pure returns (uint x) {\n        uint8 a;\n        assembly {\n            a := 0x12345678\n        }\n        x = f(a);\n    }\n}\n// ----\n// g() -> 0x78\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/conversion/implicit_cast_local_assignment.sol",
    "content": "// IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDeclStatement)\ncontract C {\n    function f() public pure returns (uint y) {\n        uint8 a;\n        assembly { a := 0x12345678 }\n        uint z = a;\n        y = z;\n    }\n}\n// ----\n// f() -> 0x78\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/copy_struct_invalid_ir_bug.sol",
    "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/define_tuple_from_function_call.sol",
    "content": "contract C {\n    function f() public pure returns (uint, uint, uint) {\n        return (1, 2, 3);\n    }\n    function g() public pure returns (uint x, uint y, uint z) {\n        (uint c, uint b, uint a) = f();\n        (x, y, z) = (a, b, c);\n    }\n    function h() public pure returns (uint) {\n        (,,uint a) = f();\n        return a;\n    }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/delete.sol",
    "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/detect_add_overflow.sol",
    "content": "contract C {\n    function f(uint a, uint b) public pure returns (uint x) {\n        x = a + b;\n    }\n    function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n        x = a + b;\n    }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/detect_add_overflow_signed.sol",
    "content": "contract C {\n    function f(int a, int b) public pure returns (int x) {\n        x = a + b;\n    }\n    function g(int8 a, int8 b) public pure returns (int8 x) {\n        x = a + b;\n    }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/detect_div_overflow.sol",
    "content": "contract C {\n    function f(uint a, uint b) public pure returns (uint x) {\n        x = a / b;\n    }\n    function g(int8 a, int8 b) public pure returns (int8 x) {\n        x = a / b;\n    }\n    function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n        x = a / b;\n    }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/detect_mod_zero.sol",
    "content": "contract C {\n    function f(uint a, uint b) public pure returns (uint x) {\n        x = a % b;\n    }\n    function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n        x = a % b;\n    }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/detect_mod_zero_signed.sol",
    "content": "contract C {\n    function f(int a, int b) public pure returns (int x) {\n        x = a % b;\n    }\n    function g(int8 a, int8 b) public pure returns (int8 x) {\n        x = a % b;\n    }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/detect_mul_overflow.sol",
    "content": "contract C {\n    function f(uint a, uint b) public pure returns (uint x) {\n        x = a * b;\n    }\n    function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n        x = a * b;\n    }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/detect_mul_overflow_signed.sol",
    "content": "contract C {\n    function f(int a, int b) public pure returns (int x) {\n        x = a * b;\n    }\n    function g(int8 a, int8 b) public pure returns (int8 x) {\n        x = a * b;\n    }\n    function h(int160 a, int160 b) public pure returns (int160 x) {\n        x = a * b;\n    }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/detect_sub_overflow.sol",
    "content": "contract C {\n    function f(uint a, uint b) public pure returns (uint x) {\n        x = a - b;\n    }\n    function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n        x = a - b;\n    }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/detect_sub_overflow_signed.sol",
    "content": "contract C {\n    function f(int a, int b) public pure returns (int x) {\n        x = a - b;\n    }\n    function g(int8 a, int8 b) public pure returns (int8 x) {\n        x = a - b;\n    }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/dirty_calldata_struct.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    struct S {\n        uint16[] m;\n    }\n    function f(S calldata s) public pure returns (bool correct) {\n        int8 x = int8(int16(s.m[0]));\n        uint r;\n        assembly {\n            r := x\n        }\n        correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/dirty_memory_dynamic_array.sol",
    "content": "contract C {\n    function f() public pure returns (bool correct) {\n        uint8[] memory m = new uint8[](1);\n        assembly {\n            mstore(add(m, 32), 258)\n        }\n        uint8 x = m[0];\n        uint r;\n        assembly {\n            r := x\n        }\n        correct = (m[0] == 0x02) && (r == 0x02);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/dirty_memory_int32.sol",
    "content": "contract C {\n    function f() public pure returns (bool correct) {\n        uint256[1] memory m;\n        assembly {\n            mstore(m, 0xdeadbeef15dead)\n        }\n        int32 x = int32(uint32(m[0]));\n        uint r;\n        assembly {\n            r := x\n        }\n        correct = (m[0] == 0xdeadbeef15dead) && (r == (((2 ** 224 - 1) << 32) | 0xef15dead));\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/dirty_memory_static_array.sol",
    "content": "contract C {\n    function f() public pure returns (bool correct) {\n        uint8[1] memory m;\n        assembly {\n            mstore(m, 257)\n        }\n        uint8 x = m[0];\n        uint r;\n        assembly {\n            r := x\n        }\n        correct = (m[0] == 0x01) && (r == 0x01);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/dirty_memory_struct.sol",
    "content": "contract C {\n    struct S {\n        uint8[] m;\n    }\n    function f() public pure returns (bool correct) {\n        S memory s;\n        s.m = new uint8[](1);\n        assembly {\n            mstore(add(s, 64), 257)\n        }\n        uint8 x = s.m[0];\n        uint r;\n        assembly {\n            r := x\n        }\n        correct = r == 0x01;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/dirty_memory_uint32.sol",
    "content": "contract C {\n    function f() public pure returns (bool correct) {\n        uint256[1] memory m;\n        assembly {\n            mstore(m, 0xdeadbeef15dead)\n        }\n        uint32 x = uint32(m[0]);\n        uint r;\n        assembly {\n            r := x\n        }\n        correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/empty_return_corrupted_free_memory_pointer.sol",
    "content": "contract C {\n    function f() public {\n        assembly{ mstore(0x40, sub(0, 1)) }\n    }\n}\n// ----\n// f() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/exp.sol",
    "content": "contract C {\n    function f(uint x, uint y) public returns (uint) {\n        return x**y;\n    }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/exp_literals.sol",
    "content": "contract C {\n    function exp_2(uint y) public returns (uint) {\n        return 2**y;\n    }\n    function exp_minus_2(uint y) public returns (int) {\n        return (-2)**y;\n    }\n\n    function exp_uint_max(uint y) public returns (uint) {\n        return (2**256 - 1)**y;\n    }\n    function exp_int_max(uint y) public returns (int) {\n        return ((-2)**255)**y;\n    }\n\n    function exp_5(uint y) public returns (uint) {\n        return 5**y;\n    }\n    function exp_minus_5(uint y) public returns (int) {\n        return (-5)**y;\n    }\n\n    function exp_256(uint y) public returns (uint) {\n        return 256**y;\n    }\n    function exp_minus_256(uint y) public returns (int) {\n        return (-256)**y;\n    }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/exp_literals_success.sol",
    "content": "contract C {\n    function exp_2(uint y) public returns (uint) {\n        return 2**y;\n    }\n    function exp_minus_2(uint y) public returns (int) {\n        return (-2)**y;\n    }\n\n    function exp_uint_max(uint y) public returns (uint) {\n        return (2**256 - 1)**y;\n    }\n    function exp_int_max(uint y) public returns (int) {\n        return ((-2)**255)**y;\n    }\n\n    function exp_5(uint y) public returns (uint) {\n        return 5**y;\n    }\n    function exp_minus_5(uint y) public returns (int) {\n        return (-5)**y;\n    }\n\n    function exp_256(uint y) public returns (uint) {\n        return 256**y;\n    }\n    function exp_minus_256(uint y) public returns (int) {\n        return (-256)**y;\n    }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/exp_neg.sol",
    "content": "contract C {\n    function f(int x, uint y) public returns (int) {\n        return x**y;\n    }\n}\n// ----\n// f(int256,uint256): 0, 0 -> 1\n// f(int256,uint256): 0, 1 -> 0x00\n// f(int256,uint256): 0, 2 -> 0x00\n// f(int256,uint256): 1, 0 -> 1\n// f(int256,uint256): 1, 1 -> 1\n// f(int256,uint256): 1, 2 -> 1\n// f(int256,uint256): 2, 0 -> 1\n// f(int256,uint256): 2, 1 -> 2\n// f(int256,uint256): 2, 2 -> 4\n// f(int256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(int256,uint256): 128, 2 -> 0x4000\n// f(int256,uint256): -1, 0 -> 1\n// f(int256,uint256): -1, 1 -> -1\n// f(int256,uint256): -1, 2 -> 1\n// f(int256,uint256): -2, 0 -> 1\n// f(int256,uint256): -2, 1 -> -2\n// f(int256,uint256): -2, 2 -> 4\n// f(int256,uint256): -7, 63 -> -174251498233690814305510551794710260107945042018748343\n// f(int256,uint256): -128, 2 -> 0x4000\n// f(int256,uint256): -1, 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> -1\n// f(int256,uint256): -2, 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// f(int256,uint256): -8, 85 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// f(int256,uint256): -131072, 15 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// f(int256,uint256): -32, 51 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// f(int256,uint256): -57896044618658097711785492504343953926634992332820282019728792003956564819968, 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/exp_neg_overflow.sol",
    "content": "contract C {\n    function f(int8 x, uint y) public returns (int) {\n        return x**y;\n    }\n    function g(int256 x, uint y) public returns (int) {\n        return x**y;\n    }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/exp_overflow.sol",
    "content": "contract C {\n    function f(uint8 x, uint8 y) public returns (uint) {\n        return x**y;\n    }\n    function g(uint x, uint y) public returns (uint) {\n        return x**y;\n    }\n}\n// ----\n// f(uint8,uint8): 2, 7 -> 0x80\n// f(uint8,uint8): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 15, 2 -> 225\n// f(uint8,uint8): 6, 3 -> 0xd8\n// f(uint8,uint8): 7, 2 -> 0x31\n// f(uint8,uint8): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 1 -> 0x0200000000000000000000000000000000\n// g(uint256,uint256): 0x100000000000000000000000000000010, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 31 -> 400631961586894742455537928461950192806830589109049416147172451019287109375\n// g(uint256,uint256): 255, 32 -> -13630939032658036097408813250890608687528184442832962921928608997994916749311\n// g(uint256,uint256): 255, 33 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 31 -> 575719427506838823084316385994930914701079543089399988096291424922125729792\n// g(uint256,uint256): 258, 37 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 131 -> FAILURE, hex\"4e487b71\", 0x11\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/exp_various.sol",
    "content": "contract C {\n    function f(uint8 x, uint8 y) public returns (uint) {\n        return x**y;\n    }\n    function g(uint x, uint y) public returns (uint) {\n        return x**y;\n    }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/function_address.sol",
    "content": "contract C {\n    function f() external returns (address) {\n        return C(address(0x1234)).f.address;\n    }\n    function g() external returns (bool, bool) {\n        return (\n            this.f.address == address(this),\n            C(address(0x1234)).f.address == address(0x1234)\n        );\n    }\n    function h(function() external a) public returns (address) {\n        return a.address;\n    }\n}\n// ----\n// f() -> 0x1234\n// g() -> true, true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/function_entry_checks.sol",
    "content": "contract C {\n    function f() public returns (uint) {\n    }\n    function g(uint x, uint y) public returns (uint) {\n    }\n    function h() public payable returns (uint) {\n    }\n    function i(bytes32 b) public returns (bytes32) {\n    }\n    function j(bool b) public returns (bool) {\n    }\n    function k(bytes32 b) public returns (bytes32) {\n    }\n    function s() public returns (uint256[] memory) {\n    }\n    function t(uint) public pure {\n    }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/function_pointers.sol",
    "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/function_selector.sol",
    "content": "contract C {\n    function f() external returns (bytes4) {\n        return this.f.selector;\n    }\n    function h(function() external a) public returns (bytes4) {\n        return a.selector;\n    }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/if.sol",
    "content": "contract C {\n    function f(bool condition) public returns (uint x) {\n        x = 23;\n        if (condition)\n            x = 42;\n    }\n    function g(bool condition) public returns (uint x) {\n        x = 0;\n        if (condition)\n            x = 42;\n        else\n            x = 23;\n    }\n    function h(bool condition) public returns (uint x) {\n        if (condition)\n            return 42;\n        x = 23;\n    }\n    function i(bool condition) public returns (uint x) {\n        if (condition)\n            x = 10;\n        else\n            return 23;\n        x = 42;\n    }\n    function j(uint a, uint b) public returns (uint x, uint y) {\n        x = 42;\n        if (a + b < 10)\n            x = a;\n        else\n            x = b;\n        y = 100;\n    }\n    function k(uint a, uint b) public returns (uint x, uint y) {\n        x = 42;\n        do {\n            if (a + b < 10)\n            {\n                if (a == b)\n                {\n                    x = 99; y = 99;\n                    break;\n                }\n                else\n                {\n                    x = a;\n                }\n            }\n            else\n            {\n                x = b;\n                if (a != b)\n                    y = 17;\n                else\n                    y = 13;\n                break;\n            }\n            y = 100;\n        } while(false);\n    }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/keccak.sol",
    "content": "contract C {\n    function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n    }\n    function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n    }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/local_address_assignment.sol",
    "content": "contract C {\n    function f(address a) public pure returns (address x) {\n        address b = a;\n        x = b;\n    }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/local_assignment.sol",
    "content": "contract C {\n    function f(uint a) public pure returns (uint x) {\n        uint b = a;\n        x = b;\n    }\n}\n// ----\n// f(uint256): 6 -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/local_bool_assignment.sol",
    "content": "contract C {\n    function f(bool a) public pure returns (bool x) {\n        bool b = a;\n        x = b;\n    }\n}\n// ----\n// f(bool): true -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/local_tuple_assignment.sol",
    "content": "contract C {\n    uint public x = 17;\n    function f(uint a1, uint a2) public returns (uint r1, uint r2) {\n        (uint b1, uint b2) = (a1, a2);\n        (r1, x, r2) = (b1, b2, b2);\n    }\n    function g() public returns (uint a, uint b, uint c) {\n        uint256[3] memory m;\n        (m[0], m[1], m[2]) = (1, x, 3);\n        return (m[2], m[1], m[0]);\n    }\n    function h() public returns (uint a, uint b, uint c) {\n        uint256[3] memory m;\n        (m[0], m[1], , m[2], m[0]) = (1, x, 3, 4, 42);\n        return (m[2], m[1], m[0]);\n    }\n    function i() public returns (uint a, uint b, uint c, uint d) {\n        (a) = 42;\n        (((((b))))) = 23;\n        c = (((17)));\n        (((d))) = (13);\n    }\n}\n// ----\n// x() -> 17\n// f(uint256,uint256): 23, 42 -> 23, 42\n// x() -> 42\n// g() -> 3, 42, 1\n// h() -> 4, 42, 1\n// i() -> 42, 23, 17, 13\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/local_variable_without_init.sol",
    "content": "contract C {\n    function f() public pure returns (uint) {\n        uint x;\n        return x;\n    }\n}\n// ----\n// f() -> 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/loops/break.sol",
    "content": "contract C {\n    function f() public returns (uint x) {\n        x = 1;\n        for (uint a = 0; a < 10; a = a + 1) {\n            x = x + x;\n            break;\n        }\n    }\n    function g() public returns (uint x) {\n        x = 1;\n        uint a = 0;\n        while (a < 10) {\n            x = x + x;\n            break;\n            a = a + 1;\n        }\n    }\n    function h() public returns (uint x) {\n        x = 1;\n        do {\n            x = x + 1;\n            break;\n        } while (x < 3);\n    }\n}\n// ----\n// f() -> 2\n// g() -> 2\n// h() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/loops/continue.sol",
    "content": "contract C {\n    function f() public returns (uint x) {\n        x = 1;\n        uint a = 0;\n        for (; a < 10; a = a + 1) {\n            continue;\n            x = x + x;\n        }\n        x = x + a;\n    }\n    function g() public returns (uint x) {\n        x = 1;\n        uint a = 0;\n        while (a < 10) {\n            a = a + 1;\n            continue;\n            x = x + x;\n        }\n        x = x + a;\n    }\n    function h() public returns (uint x) {\n        x = 1;\n        uint a = 0;\n        do {\n            a = a + 1;\n            continue;\n            x = x + x;\n        } while (a < 4);\n        x = x + a;\n    }\n}\n// ----\n// f() -> 11\n// g() -> 11\n// h() -> 5\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/loops/return.sol",
    "content": "contract C {\n    function f() public returns (uint x) {\n        x = 1;\n        uint a;\n        for (; a < 10; a = a + 1) {\n            return x;\n            x = x + x;\n        }\n        x = x + a;\n    }\n    function g() public returns (uint x) {\n        x = 1;\n        uint a;\n        while (a < 10) {\n            return x;\n            x = x + x;\n            a = a + 1;\n        }\n        x = x + a;\n    }\n    function h() public returns (uint x) {\n        x = 1;\n        do {\n            x = x + 1;\n            return x;\n        } while (x < 3);\n    }\n}\n// ----\n// f() -> 1\n// g() -> 1\n// h() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/loops/simple.sol",
    "content": "contract C {\n    function f() public returns (uint x) {\n        x = 1;\n        for (uint a = 0; a < 10; a = a + 1) {\n            x = x + x;\n        }\n    }\n    function g() public returns (uint x) {\n        x = 1;\n        uint a = 0;\n        while (a < 10) {\n            x = x + x;\n            a = a + 1;\n        }\n    }\n    function h() public returns (uint x) {\n        x = 1;\n        do {\n            x = x + 1;\n        } while (false);\n    }\n    function i() public returns (uint x) {\n        x = 1;\n        do {\n            x = x + 1;\n        } while (x < 3);\n    }\n    function j() public {\n        for (;;) {break;}\n    }\n}\n// ----\n// f() -> 1024\n// g() -> 1024\n// h() -> 2\n// i() -> 3\n// j() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/mapping_enum_key_getter.sol",
    "content": "pragma abicoder               v2;\ncontract test {\n    enum E { A, B, C }\n    mapping(E => uint8) public table;\n    function set(E k, uint8 v) public {\n        table[k] = v;\n    }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/mapping_getters.sol",
    "content": "contract test {\n    mapping(uint256 => uint256) public m1;\n    mapping(uint256 => mapping(uint256 => uint256)) public m2;\n    function set(uint256 k, uint256 v) public {\n        m1[k] = v;\n    }\n    function set(uint256 k1, uint256 k2, uint256 v) public {\n        m2[k1][k2] = v;\n    }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/mapping_string_key.sol",
    "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/memory_struct_allow.sol",
    "content": "contract C {\n    struct S {\n        uint256 a;\n        uint256 b;\n    }\n\n    function f() public pure returns (uint256 a, uint256 b){\n        assembly {\n            // Make free memory dirty to check that the struct allocation cleans it up again.\n            let freeMem := mload(0x40)\n            mstore(freeMem, 42)\n            mstore(add(freeMem, 32), 42)\n        }\n        S memory s;\n        return (s.a, s.b);\n    }\n}\n// ----\n// f() -> 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/msg_sender.sol",
    "content": "contract C {\n    function test() public view returns (bool) {\n        address x;\n        assembly { x := caller() }\n        return x == msg.sender;\n    }\n}\n// ----\n// test() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/negation_bug.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/require.sol",
    "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/return.sol",
    "content": "contract C {\n    function f() public pure returns (uint x) {\n        return 7;\n        x = 3;\n    }\n}\n// ----\n// f() -> 7\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/return_and_convert.sol",
    "content": "contract C {\n    function f() public pure returns (uint) {\n        uint8 b;\n        assembly { b := 0xffff }\n        return b;\n    }\n}\n// ----\n// f() -> 255\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/return_storage_pointers.sol",
    "content": "contract C {\n\tuint[] arr1;\n\tuint[][] arr2;\n\tfunction f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {\n\t\tptr1 = arr1;\n\t\tptr2 = arr2;\n\t}\n\tfunction g() public returns (uint, uint) {\n\t\treturn (arr1.length, arr2.length);\n\t}\n\n}\n// ----\n// g() -> 0, 0\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/short_circuit.sol",
    "content": "contract C {\n    function or(uint x) public returns (bool t, uint y) {\n        t = (x == 0 || ((x = 8) > 0));\n        y = x;\n    }\n    function and(uint x) public returns (bool t, uint y) {\n        t = (x == 0 && ((x = 8) > 0));\n        y = x;\n    }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/simple_assignment.sol",
    "content": "contract C {\n    function f(uint a, uint b) public pure returns (uint x, uint y) {\n        x = a;\n        y = b;\n    }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/simple_inline_asm.sol",
    "content": "contract C {\n    function f() public pure returns (uint32 x) {\n        uint32 a;\n        uint32 b;\n        uint32 c;\n        assembly {\n            a := 1\n            b := 2\n            c := 3\n        }\n        x = a + b + c;\n    }\n}\n// ----\n// f() -> 6\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/smoke_test.sol",
    "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/storage/dirty_storage_bytes.sol",
    "content": "contract C {\n    bytes b;\n    function f() public returns (bool correct) {\n        assembly {\n            sstore(b.slot, or(\"deadbeef\", 0x08))\n        }\n        bytes1 s = b[3];\n        uint r;\n        assembly {\n            r := s\n        }\n        correct = r == (0x64 << 248);\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/storage/dirty_storage_bytes_long.sol",
    "content": "contract C {\n    bytes b;\n    function f() public returns (bool correct) {\n        assembly {\n            sstore(b.slot, 0x41)\n            mstore(0, b.slot)\n            sstore(keccak256(0, 0x20), \"deadbeefdeadbeefdeadbeefdeadbeef\")\n        }\n        bytes1 s = b[31];\n        uint r;\n        assembly {\n            r := s\n        }\n        correct = r == (0x66 << 248);\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/storage/dirty_storage_dynamic_array.sol",
    "content": "contract C {\n    uint8[] s;\n    function f() public returns (bool correct) {\n        s.push();\n        assembly {\n            mstore(0, s.slot)\n            sstore(keccak256(0, 0x20), 257)\n        }\n        uint8 x = s[0];\n        uint r;\n        assembly {\n            r := x\n        }\n        correct = (s[0] == 0x01) && (r == 0x01);\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/storage/dirty_storage_static_array.sol",
    "content": "contract C {\n    uint8[1] s;\n    function f() public returns (bool correct) {\n        assembly {\n            sstore(s.slot, 257)\n        }\n        uint8 x = s[0];\n        uint r;\n        assembly {\n            r := x\n        }\n        correct = (s[0] == 0x01) && (r == 0x01);\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/storage/dirty_storage_struct.sol",
    "content": "contract C {\n    struct S {\n        uint8[] m;\n    }\n    S s;\n    function f() public returns (bool correct) {\n        s.m.push();\n        assembly {\n            mstore(0, s.slot)\n            sstore(keccak256(0, 0x20), 257)\n        }\n        uint8 x = s.m[0];\n        uint r;\n        assembly {\n            r := x\n        }\n        correct = r == 0x01;\n    }\n}\n// ----\n// f() -> true\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/storage/mappings.sol",
    "content": "contract C {\n    mapping(uint => uint) simple;\n    mapping(uint16 => uint) cleanup;\n    mapping(string => uint) str;\n    mapping(uint => mapping(uint => uint)) twodim;\n    function test_simple(uint _off) public returns (uint _a, uint _b, uint _c) {\n        simple[_off + 2] = 3;\n        simple[_off + 3] = 4;\n        simple[type(uint256).max] = 5;\n        _c = simple[type(uint256).max];\n        _b = simple[3 + _off];\n        _a = simple[2 + _off];\n    }\n    function test_cleanup() public returns (bool) {\n        uint16 x;\n        assembly { x := 0xffff0001 }\n        cleanup[x] = 3;\n        return cleanup[1] == 3;\n    }\n    function test_str() public returns (bool) {\n        str[\"abc\"] = 3;\n        string memory s = \"abc\";\n        return str[s] == 3;\n    }\n    function test_twodim() public returns (uint a, uint b) {\n        twodim[2][3] = 3;\n        a = twodim[3][2];\n        b = twodim[2][3];\n    }\n}\n// ----\n// test_simple(uint256): 0 -> 3, 4, 5\n// test_simple(uint256): 1 -> 3, 4, 5\n// test_simple(uint256): 2 -> 3, 4, 5\n// test_cleanup() -> true\n// test_str() -> true\n// test_twodim() -> 0, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/storage/packed_storage.sol",
    "content": "contract C {\n    uint16 x;\n    bytes1 y;\n    uint16 z;\n    function f(uint8 a) public returns (uint _x) {\n        x = a;\n        y = bytes1(uint8(x) + 1);\n        z = uint8(y) + 1;\n        x = z + 1;\n        _x = x;\n    }\n}\n// ----\n// f(uint8): 6 -> 9\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/storage/simple_storage.sol",
    "content": "contract C {\n    uint x;\n    uint y;\n    function setX(uint a) public returns (uint _x) {\n        x = a;\n        _x = x;\n    }\n    function setY(uint a) public returns (uint _y) {\n        y = a;\n        _y = y;\n    }\n}\n// ----\n// setX(uint256): 6 -> 6\n// setY(uint256): 2 -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/string_format.sol",
    "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/string_literals.sol",
    "content": "contract C {\n    function short_dyn() public pure returns (string memory x) {\n        x = \"abc\";\n    }\n    function long_dyn() public pure returns (string memory x) {\n        x = \"12345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n    }\n    function short_bytes_dyn() public pure returns (bytes memory x) {\n        x = \"abc\";\n    }\n    function long_bytes_dyn() public pure returns (bytes memory x) {\n        x = \"12345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n    }\n    function bytesNN() public pure returns (bytes3 x) {\n        x = \"abc\";\n    }\n    function bytesNN_padded() public pure returns (bytes4 x) {\n        x = \"abc\";\n    }\n}\n// ----\n// short_dyn() -> 0x20, 3, \"abc\"\n// long_dyn() -> 0x20, 80, \"12345678901234567890123456789012\", \"34567890123456789012345678901234\", \"5678901234567890\"\n// short_bytes_dyn() -> 0x20, 3, \"abc\"\n// long_bytes_dyn() -> 0x20, 80, \"12345678901234567890123456789012\", \"34567890123456789012345678901234\", \"5678901234567890\"\n// bytesNN() -> 0x6162630000000000000000000000000000000000000000000000000000000000\n// bytesNN_padded() -> 0x6162630000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/struct_member_access.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S {\n        uint a;\n        uint[] b;\n        uint c;\n    }\n\n    S s;\n    constructor() {\n        s.a = 42;\n        s.b.push(1);\n        s.b.push(2);\n        s.b.push(3);\n        s.c = 21;\n    }\n\n    function f(S memory m) public pure returns (uint, uint[] memory, uint) {\n        return (m.a, m.b, m.c);\n    }\n    function g(S calldata c) external pure returns (uint, uint, uint, uint, uint, uint) {\n        return (c.a, c.b.length, c.c, c.b[0], c.b[1], c.b[2]);\n    }\n    function g2(S calldata c1, S calldata c2) external pure returns (uint, uint, uint, uint, uint, uint) {\n        return (c1.a, c1.c, c2.a, c2.b.length, c2.c, c2.b[0]);\n    }\n    function h() external view returns (uint, uint, uint, uint, uint, uint) {\n        return (s.a, s.b.length, s.c, s.b[0], s.b[1], s.b[2]);\n    }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 0x60, 21, 3, 1, 2, 3\n// g((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 3, 21, 1, 2, 3\n// g2((uint256,uint256[],uint256),(uint256,uint256[],uint256)): 0x40, 0x0120, 42, 0x60, 21, 2, 1, 2, 3, 7, 0x80, 9, 0, 1, 17 -> 42, 21, 7, 1, 9, 17\n// h() -> 42, 3, 21, 1, 2, 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/tuple_evaluation_order.sol",
    "content": "contract C {\n    uint256 x;\n    uint256 y;\n    function set(uint256 v) public returns (uint256) { x = v; return v; }\n    function f() public returns (uint256, uint256) {\n       (y, y, y) = (set(1), set(2), set(3));\n       assert(y == 1 && x == 3);\n       return (x, y);\n    }\n}\n// ----\n// f() -> 3, 1\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/unary_fixedbytes.sol",
    "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r =  ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r =  ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r =  ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r =  ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/unary_operations.sol",
    "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/various_inline_asm.sol",
    "content": "contract C {\n    function f() public pure returns (uint32 x) {\n        uint32 a;\n        uint32 b;\n        uint32 c;\n        assembly {\n            function myAwesomeFunction(param) -> returnMe {\n                let localVar := 10\n                returnMe := add(localVar, param)\n            }\n            let abc := sub(10, a)\n            let xyz := 20\n            a := abc\n            b := myAwesomeFunction(30)\n            c := xyz\n        }\n        x = a + b + c;\n    }\n}\n// ----\n// f() -> 70\n"
  },
  {
    "path": "test/libsolidity/semanticTests/viaYul/virtual_functions.sol",
    "content": "contract X {\n    function f() public returns (uint x) {\n        x = g();\n    }\n    function g() public virtual returns (uint x) {\n        x = 2;\n    }\n}\ncontract C is X {\n    function f1() public returns (uint x) {\n        // direct call\n        x = g();\n    }\n    function f2() public returns (uint x) {\n        // call via base\n        x = f();\n    }\n    function f3() public returns (uint x) {\n        // explicit call via base\n        //x = super.g();\n    }\n    function g() public override returns (uint x) {\n        x = 3;\n    }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n"
  },
  {
    "path": "test/libsolidity/semanticTests/virtualFunctions/internal_virtual_function_calls.sol",
    "content": "contract Base {\n    function f() public returns (uint256 i) {\n        return g();\n    }\n\n    function g() internal virtual returns (uint256 i) {\n        return 1;\n    }\n}\n\n\ncontract Derived is Base {\n    function g() internal override returns (uint256 i) {\n        return 2;\n    }\n}\n// ----\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/virtualFunctions/internal_virtual_function_calls_through_dispatch.sol",
    "content": "contract Base {\n    function f() internal returns (uint256 i) {\n        function() internal returns (uint256) ptr = g;\n        return ptr();\n    }\n\n    function g() internal virtual returns (uint256 i) {\n        return 1;\n    }\n}\n\n\ncontract Derived is Base {\n    function g() internal override returns (uint256 i) {\n        return 2;\n    }\n\n    function h() public returns (uint256 i) {\n        return f();\n    }\n}\n// ----\n// h() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/virtualFunctions/virtual_function_calls.sol",
    "content": "contract Base {\n    function f() public returns (uint256 i) {\n        return g();\n    }\n\n    function g() public virtual returns (uint256 i) {\n        return 1;\n    }\n}\n\n\ncontract Derived is Base {\n    function g() public override returns (uint256 i) {\n        return 2;\n    }\n}\n// ----\n// g() -> 2\n// f() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/virtualFunctions/virtual_function_usage_in_constructor_arguments.sol",
    "content": "contract BaseBase {\n    uint256 m_a;\n\n    constructor(uint256 a) {\n        m_a = a;\n    }\n\n    function overridden() public virtual returns (uint256 r) {\n        return 1;\n    }\n\n    function g() public returns (uint256 r) {\n        return overridden();\n    }\n}\n\n\ncontract Base is BaseBase(BaseBase.g()) {}\n\n\ncontract Derived is Base {\n    function getA() public returns (uint256 r) {\n        return m_a;\n    }\n\n    function overridden() public override returns (uint256 r) {\n        return 2;\n    }\n}\n// ----\n// getA() -> 2\n"
  },
  {
    "path": "test/libsolidity/semanticTests/virtualFunctions/virtual_override_changing_mutability_internal.sol",
    "content": "contract A {\n    function f() internal virtual {\n        mutableWithViewOverride();\n        mutableWithPureOverride();\n        viewWithPureOverride();\n    }\n\n    function mutableWithViewOverride() internal virtual {}\n    function mutableWithPureOverride() internal virtual {}\n    function viewWithPureOverride() internal view virtual {}\n}\n\ncontract C is A {\n    function run() public {\n        f();\n    }\n\n    function mutableWithViewOverride() internal view override {}\n    function mutableWithPureOverride() internal pure override {}\n    function viewWithPureOverride() internal pure override {}\n}\n// ----\n// run() ->\n"
  },
  {
    "path": "test/libsolidity/semanticTests/virtualFunctions/virtual_override_changing_mutability_public.sol",
    "content": "contract A {\n    function f() internal virtual {\n        mutableWithViewOverride();\n        mutableWithPureOverride();\n        viewWithPureOverride();\n    }\n\n    function mutableWithViewOverride() public virtual {}\n    function mutableWithPureOverride() public virtual {}\n    function viewWithPureOverride() public view virtual {}\n}\n\ncontract C is A {\n    function run() public {\n        f();\n    }\n\n    function mutableWithViewOverride() public view override {}\n    function mutableWithPureOverride() public pure override {}\n    function viewWithPureOverride() public pure override {}\n}\n// ----\n// run() ->\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_decode_1_tuple.sol",
    "content": "contract C {\n\tfunction f(bytes calldata data) external pure returns (uint256[] memory) {\n\t\treturn abi.decode(data, (uint256[]));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_decode_array.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction abiDecodeArray(bytes memory b1, bytes memory b2) public pure {\n\t\t(uint[] memory a, uint[] memory b) = abi.decode(b1, (uint[], uint[]));\n\t\tassert(a.length == b.length); // should fail\n\n\t\t(uint[] memory c, uint[] memory d) = abi.decode(b1, (uint[], uint[]));\n\t\tassert(a.length == c.length);\n\t\tassert(b.length == d.length);\n\n\t\t(uint[] memory e, uint[] memory f, uint[] memory g) = abi.decode(b1, (uint[], uint[], uint[]));\n\t\tassert(e.length == a.length); // should fail\n\t\tassert(f.length == b.length); // should fail\n\t\tassert(e.length == g.length); // should fail\n\n\t\t(uint[][] memory h, uint[][][] memory i, uint j) = abi.decode(b1, (uint[][], uint[][][], uint));\n\t\trequire(j < h.length);\n\t\trequire(j < i.length);\n\t\trequire(j < i[j].length);\n\t\tassert(h[j].length == i[j][j].length); // should fail\n\n\t\t(uint[] memory k, uint[] memory l) = abi.decode(b2, (uint[], uint[]));\n\t\tassert(k.length == a.length); // should fail\n\t\tassert(l.length == b.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (182-210): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nc = []\\nd = []\\ne = []\\nf = []\\ng = []\\nh = []\\ni = []\\nj = 0\\nk = []\\nl = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value\n// Warning 6328: (466-494): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nf = [83, 83, 83, 83, 83, 83, 67, 83, 83, 83, 83, 83, 70, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 72, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 71, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83]\\ng = [65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 55, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 60, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65]\\nh = []\\ni = []\\nj = 0\\nk = []\\nl = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value\n// Warning 6328: (513-541): CHC: Assertion violation happens here.\\nCounterexample:\\n\\ng = [65, 65, 65, 65, 65, 65, 65, 64, 65, 47, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 48, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65]\\nh = []\\ni = []\\nj = 0\\nk = []\\nl = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value\n// Warning 6328: (560-588): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb = []\\nd = []\\nh = []\\ni = []\\nj = 0\\nk = []\\nl = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value\n// Warning 6328: (785-822): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nf = [144]\\nj = 8365\\nk = []\\nl = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value\n// Warning 6328: (915-943): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nj = 8365\\nl = [35, 35, 35, 35, 35]\\n\\nTransaction trace:\\nC.constructor()\\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value\n// Warning 6328: (962-990): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nj = 32285\\n\\nTransaction trace:\\nC.constructor()\\nC.abiDecodeArray(b1, b2) -- counterexample incomplete; parameter name used instead of value\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_decode_simple.sol",
    "content": "contract C {\n\tfunction abiDecodeSimple(bytes memory b1, bytes memory b2) public pure {\n\t\t(uint x, uint y) = abi.decode(b1, (uint, uint));\n\t\t(uint z, uint w) = abi.decode(b1, (uint, uint));\n\t\tassert(x == z);\n\t\tassert(x == y); // should fail\n\t\tassert(y == w);\n\t\tassert(z == w); // should fail\n\n\t\t(uint a, uint b, bool c) = abi.decode(b1, (uint, uint, bool));\n\t\tassert(a == x); // should fail\n\t\tassert(b == y); // should fail\n\t\tassert(c); // should fail\n\n\t\t(uint k, uint l) = abi.decode(b2, (uint, uint));\n\t\tassert(k == x); // should fail\n\t\tassert(l == y); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (209-223): CHC: Assertion violation happens here.\n// Warning 6328: (260-274): CHC: Assertion violation happens here.\n// Warning 6328: (359-373): CHC: Assertion violation happens here.\n// Warning 6328: (392-406): CHC: Assertion violation happens here.\n// Warning 6328: (425-434): CHC: Assertion violation happens here.\n// Warning 6328: (505-519): CHC: Assertion violation happens here.\n// Warning 6328: (538-552): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_array_slice.sol",
    "content": "contract C {\n\tfunction abiEncodeSlice(bytes calldata data) external pure {\n\t\tbytes memory b1 = abi.encode(data);\n\t\tbytes memory b2 = abi.encode(data[0:]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[0:] because each index is assigned separately\n\t\tassert(b1.length == b2.length); // fails for now\n\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//bytes memory b3 = abi.encode(data[:data.length]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[:data.length] because each index is assigned separately\n\t\t//assert(b1.length == b3.length); // fails for now\n\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//bytes memory b4 = abi.encode(data[5:10]);\n\t\t//assert(b1.length == b4.length); // should fail\n\n\t\t// Disabled because of Spacer nondeterminism in Z3 4.8.9\n\t\t//uint x = 5;\n\t\t//uint y = 10;\n\t\t//bytes memory b5 = abi.encode(data[x:y]);\n\t\t// should hold but the engine cannot infer that data[5:10] is fully equals data[x:y] because each index is assigned separately\n\t\t//assert(b1.length == b5.length); // fails for now\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (279-309): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_array_slice_2.sol",
    "content": "contract C {\n\tfunction abiEncodeSlice(uint[] calldata data) external pure {\n\t\tbytes memory b1 = abi.encode(data);\n\t\tbytes memory b2 = abi.encode(data[0:]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[0:] because each index is assigned separately\n\t\tassert(b1.length == b2.length); // fails for now\n\n\t\tbytes memory b3 = abi.encode(data[:data.length]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[:data.length] because each index is assigned separately\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//assert(b1.length == b3.length); // fails for now\n\n\t\tbytes memory b4 = abi.encode(data[5:10]);\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//assert(b1.length == b4.length); // should fail\n\n\t\tuint x = 5;\n\t\tuint y = 10;\n\t\tbytes memory b5 = abi.encode(data[x:y]);\n\t\t// should hold but the engine cannot infer that data[5:10] is fully equals data[x:y] because each index is assigned separately\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//assert(b1.length == b5.length); // fails for now\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (332-347): Unused local variable.\n// Warning 2072: (618-633): Unused local variable.\n// Warning 2072: (791-806): Unused local variable.\n// Warning 6328: (280-310): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_call_simple_1.sol",
    "content": "contract C {\n\tfunction callMeMaybe(uint a, uint b) external {}\n\n\tfunction abiEncodeSimple(uint x, uint y, uint z) public view {\n\t\trequire(x == y);\n\t\tfunction (uint, uint) external f = this.callMeMaybe;\n\t\tbytes memory b1 = abi.encodeCall(f, (x, z));\n\t\tbytes memory b2 = abi.encodeCall(f, (y, z));\n\t\tassert(b1.length == b2.length); // should hold\n\t\tassert(b1[0] == b2[0]); // should hold\n\n\t\tbytes memory b3 = abi.encodeCall(this.callMeMaybe, (3, z));\n\t\tassert(b1.length == b3.length); // should hold, but we don't encode the length computation precisely\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6368: (354-359): CHC: Out of bounds access happens here.\n// Warning 6368: (363-368): CHC: Out of bounds access happens here.\n// Warning 6328: (451-481): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_call_simple_2.sol",
    "content": "contract C {\n\tfunction callMeMaybe(uint a, uint b) external {}\n\n\tfunction abiEncodeSimple(uint x, uint y, uint z) public view {\n\t\trequire(x == y);\n\t\tbytes memory b1 = abi.encodeCall(this.callMeMaybe, (x, z));\n\t\tbytes memory b2 = abi.encodeCall(this.callMeMaybe, (y, z));\n\t\tassert(b1.length == b2.length); // should hold\n\t\tassert(b1[0] == b2[0]); // should hold\n\n\t\tbytes memory b3 = abi.encodeCall(this.callMeMaybe, (3, z));\n\t\tassert(b1.length == b3.length); // should hold but we don't compute the length precisely\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6368: (329-334): CHC: Out of bounds access happens here.\n// Warning 6368: (338-343): CHC: Out of bounds access happens here.\n// Warning 6328: (426-456): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_call_simple_3.sol",
    "content": "contract C {\n\tfunction callMeMaybe(uint a, uint b) external {}\n\n\tfunction abiEncodeSimple(uint x, uint y, uint z) public pure {\n\t\trequire(x == y);\n\t\tbytes memory b1 = abi.encodeCall(C.callMeMaybe, (x, z));\n\t\tbytes memory b2 = abi.encodeCall(C.callMeMaybe, (y, z));\n\t\tassert(b1.length == b2.length); // should hold\n\t\tassert(b1[0] == b2[0]); // should hold\n\n\t\tbytes memory b3 = abi.encodeCall(C.callMeMaybe, (3, z));\n\t\tassert(b1.length == b3.length); // should hold but we don't compute the length precisely\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6368: (323-328): CHC: Out of bounds access happens here.\n// Warning 6368: (332-337): CHC: Out of bounds access happens here.\n// Warning 6328: (417-447): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_call_simple_4.sol",
    "content": "abstract contract D {\n\tfunction no(uint a, uint b) external virtual;\n}\n\ncontract C {\n\tfunction callMeMaybe(uint a, uint b) external {}\n\n\tfunction abiEncodeSimple(uint x, uint y, uint z) public pure {\n\t\trequire(x == y);\n\t\tbytes memory b1 = abi.encodeCall(D.no, (x, z));\n\t\tbytes memory b2 = abi.encodeCall(D.no, (y, z));\n\t\tassert(b1.length == b2.length); // should hold\n\t\tassert(b1[0] == b2[0]); // should hold\n\n\t\tbytes memory b3 = abi.encodeCall(D.no, (3, z));\n\t\tassert(b1.length == b3.length); // should hold but we don't compute the length precisely\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6368: (377-382): CHC: Out of bounds access happens here.\n// Warning 6368: (386-391): CHC: Out of bounds access happens here.\n// Warning 6328: (462-492): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_call_simple_5.sol",
    "content": "abstract contract D {\n\tfunction no(uint a, uint b) external virtual;\n}\n\ncontract C {\n\tfunction callMeMaybe(uint a, uint b) external {}\n\n\tfunction abiEncodeSimple(D d, uint x, uint y, uint z) public pure {\n\t\trequire(x == y);\n\t\tbytes memory b1 = abi.encodeCall(d.no, (x, z));\n\t\tbytes memory b2 = abi.encodeCall(d.no, (y, z));\n\t\tassert(b1.length == b2.length); // should hold\n\t\tassert(b1[0] == b2[0]); // should hold\n\n\t\tbytes memory b3 = abi.encodeCall(d.no, (3, z));\n\t\tassert(b1.length == b3.length); // should hold but we don't compute the length precisely\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6368: (382-387): CHC: Out of bounds access happens here.\n// Warning 6368: (391-396): CHC: Out of bounds access happens here.\n// Warning 6328: (467-497): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_function.sol",
    "content": "contract C {\n\tfunction f() public view {\n\t\tabi.encode(this.f);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_hash.sol",
    "content": "contract C {\n\tfunction abiEncodeHash(uint a, uint b) public pure {\n\t\trequire(a == b);\n\t\tbytes memory b1 = abi.encode(a, a, a, a);\n\t\tbytes memory b2 = abi.encode(b, a, b, a);\n\t\tassert(keccak256(b1) == keccak256(b2));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_no_arguments.sol",
    "content": "contract C {\n\tfunction f() pure public {\n\t\tbytes memory res = abi.encode();\n\t\tassert(res.length == 0); // should hold\n\t\tassert(res.length > 0); // should fail\n\t\tres = abi.encodePacked();\n\t\tassert(res.length == 0); // should hold\n\t\tassert(res.length > 0); // should fail\n\t\tres = abi.encodeWithSelector(0);\n\t\tassert(res.length == 4); // should hold, but SMTChecker cannot know this yet\n\t\tres = abi.encodeWithSignature(\"\");\n\t\tassert(res.length == 4); // should hold, but SMTChecker cannot know this yet\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (120-142): CHC: Assertion violation happens here.\n// Warning 6328: (231-253): CHC: Assertion violation happens here.\n// Warning 6328: (307-330): CHC: Assertion violation happens here.\n// Warning 6328: (423-446): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_packed_array_slice.sol",
    "content": "contract C {\n\tfunction abiencodePackedSlice(bytes calldata data) external pure {\n\t\tbytes memory b1 = abi.encodePacked(data);\n\t\tbytes memory b2 = abi.encodePacked(data[0:]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[0:] because each index is assigned separately\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//assert(b1.length == b2.length); // fails for now\n\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//bytes memory b3 = abi.encodePacked(data[:data.length]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[:data.length] because each index is assigned separately\n\t\t//assert(b1.length == b3.length); // fails for now\n\n\t\tbytes memory b4 = abi.encodePacked(data[5:10]);\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//assert(b1.length == b4.length); // should fail\n\n\t\tuint x = 5;\n\t\tuint y = 10;\n\t\tbytes memory b5 = abi.encodePacked(data[x:y]);\n\t\t// should hold but the engine cannot infer that data[5:10] is fully equals data[x:y] because each index is assigned separately\n\t\tassert(b1.length == b5.length); // fails for now\n\n\t\tbytes memory b6 = abi.encode(data[5:10]);\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//assert(b4.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (127-142): Unused local variable.\n// Warning 2072: (691-706): Unused local variable.\n// Warning 2072: (1099-1114): Unused local variable.\n// Warning 6328: (1047-1077): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_packed_array_slice_2.sol",
    "content": "contract C {\n\tfunction abiencodePackedSlice(uint[] calldata data) external pure {\n\t\tbytes memory b1 = abi.encodePacked(data);\n\t\tbytes memory b2 = abi.encodePacked(data[0:]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[0:] because each index is assigned separately\n\t\tassert(b1.length == b2.length); // fails for now\n\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//bytes memory b3 = abi.encodePacked(data[:data.length]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[:data.length] because each index is assigned separately\n\t\t//assert(b1.length == b3.length); // fails for now\n\n\t\tbytes memory b4 = abi.encodePacked(data[5:10]);\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//assert(b1.length == b4.length); // should fail\n\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//uint x = 5;\n\t\t//uint y = 10;\n\t\t//bytes memory b5 = abi.encodePacked(data[x:y]);\n\t\t// should hold but the engine cannot infer that data[5:10] is fully equals data[x:y] because each index is assigned separately\n\t\t//assert(b1.length == b5.length); // fails for now\n\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//bytes memory b6 = abi.encode(data[5:10]);\n\t\t//assert(b4.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (643-658): Unused local variable.\n// Warning 6328: (298-328): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_packed_hash.sol",
    "content": "contract C {\n\tfunction abiencodePackedHash(uint a, uint b) public pure {\n\t\trequire(a == b);\n\t\tbytes memory b1 = abi.encodePacked(a, a, a, a);\n\t\tbytes memory b2 = abi.encodePacked(b, a, b, a);\n\t\tassert(keccak256(b1) == keccak256(b2));\n\n\t\tbytes memory b3 = abi.encode(a, a, a, a);\n\t\tassert(keccak256(b1) == keccak256(b3)); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (281-319): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_packed_simple.sol",
    "content": "contract C {\n\tfunction abiencodePackedSimple(bool t, uint x, uint y, uint z, uint[] memory a, uint[] memory b) public pure {\n\t\trequire(x == y);\n\t\tbytes memory b1 = abi.encodePacked(x, z, a);\n\t\tbytes memory b2 = abi.encodePacked(y, z, a);\n\t\tassert(b1.length == b2.length);\n\n\t\tbytes memory b3 = abi.encodePacked(y, z, b);\n\t\tassert(b1.length == b3.length); // should fail\n\n\t\tbytes memory b4 = abi.encodePacked(t, z, a);\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tbytes memory b5 = abi.encodePacked(y, y, y, y, a, a, a);\n\t\tassert(b1.length != b5.length); // should fail\n\t\tassert(b1.length == b5.length); // should fail\n\n\t\t// Commented out because of nondeterminism in Spacer in Z3 4.8.9\n\t\t//bytes memory b6 = abi.encode(x, z, a);\n\t\t//assert(b1.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (322-352): CHC: Assertion violation happens here.\n// Warning 6328: (419-449): CHC: Assertion violation happens here.\n// Warning 6328: (528-558): CHC: Assertion violation happens here.\n// Warning 6328: (577-607): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_packed_string_literal.sol",
    "content": "contract C {\n\tfunction abiencodePackedStringLiteral() public pure {\n\t\tbytes memory b1 = abi.encodePacked(\"\");\n\t\tbytes memory b2 = abi.encodePacked(\"\");\n\t\tassert(b1.length == b2.length); // should hold\n\n\t\tbytes memory b3 = abi.encodePacked(bytes(\"\"));\n\t\tassert(b1.length == b3.length); // should hold\n\n\t\tbytes memory b4 = abi.encodePacked(bytes24(\"\"));\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tbytes memory b5 = abi.encodePacked(string(\"\"));\n\t\tassert(b1.length == b5.length); // should hold, but currently fails due to abstraction\n\n\t\tbytes memory b6 = abi.encode(\"\");\n\t\tassert(b1.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (354-384): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb5 = []\\nb6 = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiencodePackedStringLiteral()\n// Warning 6328: (454-484): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb6 = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiencodePackedStringLiteral()\n// Warning 6328: (580-610): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.abiencodePackedStringLiteral()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_packed_string_literal_no_unproved.sol",
    "content": "contract C {\n\tfunction abiencodePackedStringLiteral() public pure {\n\t\tbytes memory b1 = abi.encodePacked(\"\");\n\t\tbytes memory b2 = abi.encodePacked(\"\");\n\t\tassert(b1.length == b2.length); // should hold\n\n\t\tbytes memory b3 = abi.encodePacked(bytes(\"\"));\n\t\tassert(b1.length == b3.length); // should hold\n\n\t\tbytes memory b4 = abi.encodePacked(bytes24(\"\"));\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tbytes memory b5 = abi.encodePacked(string(\"\"));\n\t\tassert(b1.length == b5.length); // should hold, but fails due to abstraction\n\n\t\tbytes memory b6 = abi.encode(\"\");\n\t\tassert(b1.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTShowUnproved: no\n// ----\n// Warning 6328: (354-384): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb5 = []\\nb6 = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiencodePackedStringLiteral()\n// Warning 6328: (454-484): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb6 = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiencodePackedStringLiteral()\n// Warning 6328: (570-600): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.abiencodePackedStringLiteral()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_simple.sol",
    "content": "contract C {\n\tfunction abiEncodeSimple(bool t, uint x, uint y, uint z, uint[] memory a, uint[] memory b) public pure {\n\t\trequire(x == y);\n\t\tbytes memory b1 = abi.encode(x, z, a);\n\t\tbytes memory b2 = abi.encode(y, z, a);\n\t\tassert(b1.length == b2.length);\n\n\t\tbytes memory b3 = abi.encode(y, z, b);\n\t\tassert(b1.length == b3.length); // should fail\n\n\t\tbytes memory b4 = abi.encode(t, z, a);\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tbytes memory b5 = abi.encode(y, y, y, y, a, a, a);\n\t\tassert(b1.length != b5.length); // should fail\n\t\t// Disabled because of nondeterminism in Spacer Z3 4.8.9\n\t\t//assert(b1.length == b5.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (298-328): CHC: Assertion violation happens here.\n// Warning 6328: (389-419): CHC: Assertion violation happens here.\n// Warning 6328: (492-522): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_string_literal.sol",
    "content": "contract C {\n\tfunction abiEncodeStringLiteral() public pure {\n\t\tbytes memory b1 = abi.encode(\"\");\n\t\tbytes memory b2 = abi.encode(\"\");\n\t\t// should hold\n\t\tassert(b1.length == b2.length);\n\n\t\tbytes memory b3 = abi.encode(bytes(\"\"));\n\t\tassert(b1.length == b3.length); // should hold\n\n\t\tbytes memory b4 = abi.encode(bytes24(\"\"));\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tbytes memory b5 = abi.encode(string(\"\"));\n\t\tassert(b1.length == b5.length); // should hold, but currently fails due to abstraction\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (326-356): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb5 = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiEncodeStringLiteral()\n// Warning 6328: (420-450): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.abiEncodeStringLiteral()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice.sol",
    "content": "contract C {\n\tfunction abiEncodeSlice(bytes4 sel, bytes calldata data) external pure {\n\t\tbytes memory b1 = abi.encodeWithSelector(sel, data);\n\t\tbytes memory b2 = abi.encodeWithSelector(sel, data[0:]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[0:] because each index is assigned separately\n\t\tassert(b1.length == b2.length); // fails for now\n\n\t\tbytes memory b3 = abi.encodeWithSelector(sel, data[:data.length]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[:data.length] because each index is assigned separately\n\t\tassert(b1.length == b3.length); // fails for now\n\n\t\tbytes memory b4 = abi.encodeWithSelector(sel, data[5:10]);\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tuint x = 5;\n\t\tuint y = 10;\n\t\tbytes memory b5 = abi.encodeWithSelector(sel, data[x:y]);\n\t\t// should hold but the engine cannot infer that data[5:10] is fully equals data[x:y] because each index is assigned separately\n\t\tassert(b1.length == b5.length); // fails for now\n\n\t\tbytes memory b6 = abi.encodeWithSelector(0xcafecafe, data[5:10]);\n\t\tassert(b4.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (325-355): CHC: Assertion violation happens here.\n// Warning 6328: (578-608): CHC: Assertion violation happens here.\n// Warning 6328: (691-721): CHC: Assertion violation happens here.\n// Warning 6328: (959-989): CHC: Assertion violation happens here.\n// Warning 6328: (1079-1109): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_array_slice_2.sol",
    "content": "contract C {\n\tfunction abiEncodeSlice(bytes4 sel, uint[] calldata data) external pure {\n\t\tbytes memory b1 = abi.encodeWithSelector(sel, data);\n\t\tbytes memory b2 = abi.encodeWithSelector(sel, data[0:]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[0:] because each index is assigned separately\n\t\tassert(b1.length == b2.length); // fails for now\n\n\t\tbytes memory b3 = abi.encodeWithSelector(sel, data[:data.length]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[:data.length] because each index is assigned separately\n\t\tassert(b1.length == b3.length); // fails for now\n\n\t\tbytes memory b4 = abi.encodeWithSelector(sel, data[5:10]);\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tuint x = 5;\n\t\tuint y = 10;\n\t\tbytes memory b5 = abi.encodeWithSelector(sel, data[x:y]);\n\t\t// should hold but the engine cannot infer that data[5:10] is fully equals data[x:y] because each index is assigned separately\n\t\tassert(b1.length == b5.length); // fails for now\n\n\t\tbytes memory b6 = abi.encodeWithSelector(0xcafecafe, data[5:10]);\n\t\tassert(b4.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreCex: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (326-356): CHC: Assertion violation happens here.\n// Warning 6328: (579-609): CHC: Assertion violation happens here.\n// Warning 6328: (692-722): CHC: Assertion violation happens here.\n// Warning 6328: (960-990): CHC: Assertion violation happens here.\n// Warning 6328: (1080-1110): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_hash.sol",
    "content": "contract C {\n\tfunction abiEncodeHash(bytes4 sel, uint a, uint b) public pure {\n\t\trequire(a == b);\n\t\tbytes memory b1 = abi.encodeWithSelector(sel, a, a, a, a);\n\t\tbytes memory b2 = abi.encodeWithSelector(sel, b, a, b, a);\n\t\t// Disabled because of OSX nondeterminism\n\t\t//assert(keccak256(b1) == keccak256(b2));\n\n\t\tbytes memory b3 = abi.encodeWithSelector(0xcafecafe, a, a, a, a);\n\t\tassert(keccak256(b1) == keccak256(b3)); // should fail\n\t\tassert(keccak256(b1) != keccak256(b3)); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (161-176): Unused local variable.\n// Warning 6328: (379-417): CHC: Assertion violation happens here.\n// Warning 6328: (436-474): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_simple.sol",
    "content": "contract C {\n\tfunction abiEncodeSimple(bytes4 sel, bool t, uint x, uint y, uint z, uint[] memory a, uint[] memory b) public pure {\n\t\trequire(x == y);\n\t\t// Disabled because of Spacer nondeterminism\n\t\tbytes memory b1 = abi.encodeWithSelector(sel, x, z, a);\n\t\t//bytes memory b2 = abi.encodeWithSelector(sel, y, z, a);\n\t\t//assert(b1.length == b2.length);\n\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//bytes memory b3 = abi.encodeWithSelector(sel, y, z, b);\n\t\t//assert(b1.length == b3.length); // should fail\n\n\t\tbytes memory b4 = abi.encodeWithSelector(sel, t, z, a);\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tbytes memory b5 = abi.encodeWithSelector(sel, y, y, y, y, a, a, a);\n\t\tassert(b1.length != b5.length); // should fail\n\t\tassert(b1.length == b5.length); // should fail\n\n\t\tbytes memory b6 = abi.encodeWithSelector(0xcafecafe, x, z, a);\n\t\tassert(b1.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 5667: (100-115): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (571-601): CHC: Assertion violation happens here.\n// Warning 6328: (691-721): CHC: Assertion violation happens here.\n// Warning 6328: (740-770): CHC: Assertion violation happens here.\n// Warning 6328: (855-885): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_string_literal.sol",
    "content": "contract C {\n\tfunction abiEncodeStringLiteral(bytes4 sel) public pure {\n\t\tbytes memory b1 = abi.encodeWithSelector(sel, \"\");\n\t\tbytes memory b2 = abi.encodeWithSelector(sel, \"\");\n\n\t\tassert(b1.length == b2.length); // should hold\n\n\t\tbytes memory b3 = abi.encodeWithSelector(sel, bytes(\"\"));\n\t\tassert(b1.length == b3.length); // should hold\n\n\t\tbytes memory b4 = abi.encodeWithSelector(sel, bytes24(\"\"));\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tbytes memory b5 = abi.encodeWithSelector(sel, string(\"\"));\n\t\tassert(b1.length == b5.length); // should hold, but currently fails due to abstraction\n\n\t\tbytes memory b6 = abi.encodeWithSelector(0xcafecafe, bytes24(\"\"));\n\t\tassert(b4.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (403-433): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nsel = 0x0\\nb5 = []\\nb6 = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiEncodeStringLiteral(0x0)\n// Warning 6328: (514-544): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nsel = 0x0\\nb6 = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiEncodeStringLiteral(0x0)\n// Warning 6328: (673-703): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nsel = 0x0\\nb6 = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiEncodeStringLiteral(0x0)\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_string_literal_2.sol",
    "content": "contract C {\n\tfunction abiEncodeStringLiteral(bytes4 sel) public pure {\n\t\tbytes memory b1 = abi.encodeWithSelector(\"\");\n\t\trequire(sel == \"\");\n\t\tbytes memory b2 = abi.encodeWithSelector(sel);\n\t\tassert(b1.length == b2.length); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_selector_vs_sig.sol",
    "content": "contract C {\n\tfunction f(string memory sig, uint x, uint[] memory a) public pure {\n\t\tbytes memory b1 = abi.encodeWithSignature(sig, x, a);\n\t\tbytes memory b2 = abi.encodeWithSelector(bytes4(keccak256(bytes(sig))), x, a);\n\t\t// should hold but we do not evaluate keccak256 in an interpreted way\n\t\t//assert(b1.length == b2.length);\n\t\tassert(b1.length != b2.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (330-360): CHC: Assertion violation might happen here.\n// Warning 4661: (330-360): BMC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice.sol",
    "content": "contract C {\n\tfunction abiEncodeSlice(string memory sig, bytes calldata data) external pure {\n\t\tbytes memory b1 = abi.encodeWithSignature(sig, data);\n\t\tbytes memory b2 = abi.encodeWithSignature(sig, data[0:]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[0:] because each index is assigned separately\n\t\tassert(b1.length == b2.length); // fails for now\n\n\t\tbytes memory b3 = abi.encodeWithSignature(sig, data[:data.length]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[:data.length] because each index is assigned separately\n\t\tassert(b1.length == b3.length); // fails for now\n\n\t\tbytes memory b4 = abi.encodeWithSignature(sig, data[5:10]);\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tuint x = 5;\n\t\tuint y = 10;\n\t\tbytes memory b5 = abi.encodeWithSignature(sig, data[x:y]);\n\t\t// should hold but the engine cannot infer that data[5:10] is fully equals data[x:y] because each index is assigned separately\n\t\tassert(b1.length == b5.length); // fails for now\n\n\t\tbytes memory b6 = abi.encodeWithSelector(\"f()\", data[5:10]);\n\t\tassert(b4.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreOS: macos\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (334-364): CHC: Assertion violation happens here.\n// Warning 6328: (588-618): CHC: Assertion violation happens here.\n// Warning 6328: (702-732): CHC: Assertion violation happens here.\n// Warning 6328: (971-1001): CHC: Assertion violation happens here.\n// Warning 6328: (1086-1116): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_array_slice_2.sol",
    "content": "contract C {\n\tfunction abiEncodeSlice(string memory sig, uint[] calldata data) external pure {\n\t\tbytes memory b1 = abi.encodeWithSignature(sig, data);\n\t\tbytes memory b2 = abi.encodeWithSignature(sig, data[0:]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[0:] because each index is assigned separately\n\t\tassert(b1.length == b2.length); // fails for now\n\n\t\tbytes memory b3 = abi.encodeWithSignature(sig, data[:data.length]);\n\t\t// should hold but the engine cannot infer that data is fully equals data[:data.length] because each index is assigned separately\n\t\tassert(b1.length == b3.length); // fails for now\n\n\t\tbytes memory b4 = abi.encodeWithSignature(sig, data[5:10]);\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tuint x = 5;\n\t\tuint y = 10;\n\t\tbytes memory b5 = abi.encodeWithSignature(sig, data[x:y]);\n\t\t// should hold but the engine cannot infer that data[5:10] is fully equals data[x:y] because each index is assigned separately\n\t\tassert(b1.length == b5.length); // fails for now\n\n\t\tbytes memory b6 = abi.encodeWithSelector(\"f()\", data[5:10]);\n\t\tassert(b4.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreOS: macos\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (335-365): CHC: Assertion violation happens here.\n// Warning 6328: (589-619): CHC: Assertion violation happens here.\n// Warning 6328: (703-733): CHC: Assertion violation happens here.\n// Warning 6328: (972-1002): CHC: Assertion violation happens here.\n// Warning 6328: (1087-1117): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_hash.sol",
    "content": "contract C {\n\tfunction abiEncodeHash(string memory sig, uint a, uint b) public pure {\n\t\trequire(a == b);\n\t\tbytes memory b1 = abi.encodeWithSignature(sig, a, a, a, a);\n\t\tbytes memory b2 = abi.encodeWithSignature(sig, b, a, b, a);\n\t\tassert(keccak256(b1) == keccak256(b2));\n\n\t\tbytes memory b3 = abi.encodeWithSelector(\"f()\", a, a, a, a);\n\t\tassert(keccak256(b1) == keccak256(b3)); // should fail\n\t\tassert(keccak256(b1) != keccak256(b3)); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (337-375): CHC: Assertion violation happens here.\n// Warning 6328: (394-432): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_simple.sol",
    "content": "contract C {\n\tfunction abiEncodeSimple(string memory sig, bool t, uint x, uint y, uint z, uint[] memory a, uint[] memory b) public pure {\n\t\trequire(x == y);\n\t\tbytes memory b1 = abi.encodeWithSignature(sig, x, z, a);\n\t\tbytes memory b2 = abi.encodeWithSignature(sig, y, z, a);\n\t\tassert(b1.length == b2.length);\n\n\t\t// Disabled because of nondeterminism in Spacer Z3 4.8.9\n\t\t//bytes memory b3 = abi.encodeWithSignature(sig, y, z, b);\n\t\t//assert(b1.length == b3.length); // should fail\n\n\t\tbytes memory b4 = abi.encodeWithSignature(sig, t, z, a);\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tbytes memory b5 = abi.encodeWithSignature(sig, y, y, y, y, a, a, a);\n\t\tassert(b1.length != b5.length); // should fail\n\t\tassert(b1.length == b5.length); // should fail\n\n\t\tbytes memory b6 = abi.encodeWithSignature(\"f()\", x, z, a);\n\t\tassert(b1.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 5667: (107-122): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (543-573): CHC: Assertion violation happens here.\n// Warning 6328: (664-694): CHC: Assertion violation happens here.\n// Warning 6328: (713-743): CHC: Assertion violation happens here.\n// Warning 6328: (824-854): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/abi/abi_encode_with_sig_string_literal.sol",
    "content": "contract C {\n\tfunction abiEncodeStringLiteral(string memory sig) public pure {\n\t\tbytes memory b1 = abi.encodeWithSignature(sig, \"\");\n\t\tbytes memory b2 = abi.encodeWithSignature(sig, \"\");\n\t\tassert(b1.length == b2.length); // should hold\n\n\t\tbytes memory b3 = abi.encodeWithSignature(sig, bytes(\"\"));\n\t\tassert(b1.length == b3.length); // should hold\n\n\t\tbytes memory b4 = abi.encodeWithSignature(sig, bytes24(\"\"));\n\t\tassert(b1.length == b4.length); // should fail\n\n\t\tbytes memory b5 = abi.encodeWithSignature(sig, string(\"\"));\n\t\tassert(b1.length == b5.length); // should hold, but currently fails due to abstraction\n\n\t\tbytes memory b6 = abi.encodeWithSelector(\"f()\", bytes24(\"\"));\n\t\tassert(b4.length == b6.length); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (413-443): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb5 = []\\nb6 = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiEncodeStringLiteral(sig) -- counterexample incomplete; parameter name used instead of value\n// Warning 6328: (525-555): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb6 = []\\n\\nTransaction trace:\\nC.constructor()\\nC.abiEncodeStringLiteral(sig) -- counterexample incomplete; parameter name used instead of value\n// Warning 6328: (679-709): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.abiEncodeStringLiteral(sig) -- counterexample incomplete; parameter name used instead of value\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/array_pop_length_1.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f() public {\n\t\ta.pop();\n\t\ta.push();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (49-56): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\na = []\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/array_pop_length_2.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f() public {\n\t\ta.pop();\n\t\ta.length;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (49-56): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\na = []\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/array_pop_length_3.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f() public {\n\t\ta.pop();\n\t\ta.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (49-56): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\na = []\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f()\n// Warning 2529: (60-67): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\na = []\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/array_pop_length_4.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f() public {\n\t\ta.length;\n\t\ta.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (61-68): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\na = []\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/array_pop_length_5.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction g() internal {\n\t\ta.push();\n\t}\n\tfunction f() public {\n\t\ta.pop();\n\t\tg();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (89-96): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\na = []\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/array_pop_length_6.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction g() internal view {\n\t\ta.length;\n\t}\n\tfunction f() public {\n\t\ta.pop();\n\t\tg();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (94-101): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\na = []\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/array_pop_length_7.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f() public {\n\t\ta.push();\n\t\ta.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/array_pop_length_8.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f() public {\n\t\ta.pop();\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t\ta.pop();\n\t\ta.pop();\n\t\ta.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (49-56): CHC: Empty array \"pop\" happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/array_push_string_literal.sol",
    "content": "contract C {\n\tbytes data;\n\tfunction g() public {\n\t\trequire(data.length == 0);\n\t\tdata.push(\"b\");\n\t\tassert(data[0] == \"b\"); // should hold\n\t\tassert(data[0] == \"c\"); // should fail\n\t\tdelete data;\n\t\tdata.push(hex\"01\");\n\t\tassert(uint8(data[0]) == 1); // should hold\n\t\tassert(uint8(data[0]) == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (139-161): CHC: Assertion violation happens here.\n// Warning 6328: (263-290): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_1d_assignment_2d_memory_to_memory.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tfunction f(uint[][] memory arr) public pure {\n\t\trequire(arr.length > 0);\n\t\tuint[][] memory arr2 = arr;\n\t\tassert(arr2[0].length == arr[0].length);\n\t\tassert(arr.length == arr2.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_1d_assignment_2d_storage_to_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tuint[][] arr;\n\tuint[][] arr2;\n\tconstructor() {\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr2.push();\n\t\tarr2.push();\n\t}\n\tfunction f() public view {\n\t\tassert(arr2[0].length == arr[0].length);\n\t\tassert(arr2.length == arr.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_1d_copy_2d_memory_to_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tuint[][] arr;\n\tfunction f(uint[][] memory arr2) public {\n\t\trequire(arr2.length > 0);\n\t\tarr = arr2;\n\t\tassert(arr2[0].length == arr[0].length);\n\t\tassert(arr2.length == arr.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_1d_copy_2d_storage_to_memory.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tuint[][] arr;\n\tconstructor() {\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t}\n\tfunction f() public view {\n\t\tuint[][] memory arr2 = arr;\n\t\tassert(arr2[0].length == arr[0].length);\n\t\tassert(arr2.length == arr.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_1d_mapping_array_1.sol",
    "content": "contract C {\n\tmapping (uint => uint[]) map;\n\tfunction f() public view {\n\t\tassert(map[0].length == map[1].length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_1d_mapping_array_2.sol",
    "content": "contract C {\n\tmapping (uint => uint[]) map;\n\tfunction f(uint x, uint y) public view {\n\t\trequire(x == y);\n\t\tassert(map[x].length == map[y].length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_1d_mapping_array_2d_1.sol",
    "content": "contract C {\n\tmapping (uint => uint[][]) map;\n\tfunction f(uint x, uint y) public {\n\t\trequire(x == y);\n\t\tmap[x].push();\n\t\tassert(map[x][0].length == map[y][0].length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_1.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint[] arr;\n\t}\n\tS s1;\n\tS s2;\n\tfunction f() public view {\n\t\tassert(s1.arr.length == s2.arr.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_1d_struct_array_2d_1.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint[][] arr;\n\t}\n\tS s1;\n\tS s2;\n\tconstructor() {\n\t\ts1.arr.push();\n\t\ts2.arr.push();\n\t\ts1.arr[0].push();\n\t\ts1.arr[0].push();\n\t\ts1.arr[0].push();\n\t\ts2.arr[0].push();\n\t\ts2.arr[0].push();\n\t\ts2.arr[0].push();\n\t}\n\tfunction f() public view {\n\t\tassert(s1.arr[0].length == s2.arr[0].length);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_assignment_2d_memory_to_memory.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tfunction f(uint[][] memory arr) public pure {\n\t\tuint[][] memory arr2 = arr;\n\t\tassert(arr2.length == arr.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_assignment_memory_to_memory.sol",
    "content": "contract C {\n\tfunction f(uint[] memory arr) public pure {\n\t\tuint[] memory arr2 = arr;\n\t\tassert(arr2.length == arr.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_assignment_storage_to_storage.sol",
    "content": "contract C {\n\tuint[] arr;\n\tuint[] arr2;\n\tfunction f() public {\n\t\tarr2 = arr;\n\t\tassert(arr2.length == arr.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_basic.sol",
    "content": "contract C {\n\tuint[] arr;\n\tfunction f() public view {\n\t\tuint x = arr.length;\n\t\tuint y = x;\n\t\tassert(arr.length == y);\n\t\tassert(arr.length != y);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (120-143): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_copy_memory_to_storage.sol",
    "content": "contract C {\n\tuint[] arr;\n\tfunction f(uint[] memory marr) public {\n\t\tarr = marr;\n\t\tassert(marr.length == arr.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_copy_storage_to_memory.sol",
    "content": "contract C {\n\tuint[] arr;\n\tfunction f() public view {\n\t\tuint[] memory marr = arr;\n\t\tassert(marr.length == arr.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_function_call.sol",
    "content": "contract C {\n\tuint[] arr;\n\tfunction f() public view {\n\t\tassert(arr.length == g().length);\n\t}\n\tfunction g() internal pure returns (uint[] memory) {\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment.sol",
    "content": "contract C {\n\tuint[] arr;\n\tconstructor() {\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t}\n\tfunction f() public view {\n\t\tuint[] memory arr2 = arr;\n\t\tarr2[2] = 3;\n\t\tassert(arr.length == arr2.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_2.sol",
    "content": "contract C {\n\tuint[][] arr;\n\tconstructor() {\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr[2].push();\n\t\tarr[2].push();\n\t\tarr[2].push();\n\t\tarr[2].push();\n\t}\n\tfunction f() public {\n\t\tuint x = arr[2].length;\n\t\tuint y = arr[3].length;\n\t\tuint z = arr.length;\n\t\tarr[2][3] = 444;\n\t\tassert(arr[2].length == x);\n\t\tassert(arr[3].length == y);\n\t\tassert(arr.length == z);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 13 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_2_fail.sol",
    "content": "contract C {\n\tuint[][] arr;\n\tconstructor() {\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr[2].push();\n\t\tarr[2].push();\n\t\tarr[2].push();\n\t\tarr[2].push();\n\t}\n\tfunction f() public {\n\t\tuint x = arr[2].length;\n\t\tuint y = arr[3].length;\n\t\tuint z = arr.length;\n\t\tarr[2][3] = 444;\n\t\tassert(arr[2].length != x);\n\t\tassert(arr[3].length != y);\n\t\tassert(arr.length != z);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (291-317): CHC: Assertion violation happens here.\n// Warning 6328: (321-347): CHC: Assertion violation happens here.\n// Warning 6328: (351-374): CHC: Assertion violation happens here.\n// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3.sol",
    "content": "contract C {\n\tuint[][] arr;\n\n\tconstructor() {\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t}\n\n\tfunction f() public {\n\t\tuint x = arr[2].length;\n\t\tuint y = arr[3].length;\n\t\tuint z = arr.length;\n\t\tuint t = arr[5].length;\n\t\tarr[5] = arr[8];\n\t\tassert(arr[2].length == x);\n\t\tassert(arr[3].length == y);\n\t\tassert(arr.length == z);\n\t\tassert(arr[5].length == t);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 12 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/length_same_after_assignment_3_fail.sol",
    "content": "contract C {\n\tuint[][] arr;\n\tconstructor() {\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t\tarr.push();\n\t}\n\tfunction f() public {\n\t\tuint x = arr[2].length;\n\t\tuint y = arr[3].length;\n\t\tuint z = arr.length;\n\t\tuint t = arr[5].length;\n\t\tarr[5] = arr[8];\n\t\tassert(arr[2].length != x);\n\t\tassert(arr[3].length != y);\n\t\tassert(arr.length != z);\n\t\tassert(arr[5].length != t);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (319-345): CHC: Assertion violation happens here.\n// Warning 6328: (349-375): CHC: Assertion violation happens here.\n// Warning 6328: (379-402): CHC: Assertion violation happens here.\n// Warning 6328: (406-432): CHC: Assertion violation happens here.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/pop_1_safe.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f() public {\n\t\ta.push();\n\t\ta.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/pop_1_unsafe.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f() public {\n\t\ta.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 2529: (49-56): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\na = []\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/pop_2d_safe.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction f() public {\n\t\ta.push();\n\t\ta[0].push();\n\t\ta[0].pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/pop_2d_unsafe.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction f() public {\n\t\ta.push();\n\t\ta.push();\n\t\ta[0].push();\n\t\ta[1].pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (90-100): CHC: Empty array \"pop\" happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/pop_constructor_safe.sol",
    "content": "contract C {\n\tuint[] a;\n\tconstructor() {\n\t\ta.push();\n\t\ta.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/pop_constructor_unsafe.sol",
    "content": "contract C {\n\tuint[] a;\n\tconstructor() {\n\t\ta.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 2529: (43-50): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\na = []\\n\\nTransaction trace:\\nC.constructor()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/pop_loop_safe.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f(uint l) public {\n\t\tfor (uint i = 0; i < l; ++i) {\n\t\t\ta.push();\n\t\t\ta.pop();\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/pop_loop_unsafe.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f(uint l) public {\n\t\tfor (uint i = 0; i < l; ++i) {\n\t\t\ta.push();\n\t\t\ta.pop();\n\t\t}\n\t\ta.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (117-124): CHC: Empty array \"pop\" happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_2d_arg_1_safe.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction f(uint[] memory x, uint y) public {\n\t\ta.push(x);\n\t\ta[0].push(y);\n\t\tassert(a[0][a[0].length - 1] == y);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_2d_arg_1_unsafe.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction f(uint[] memory x, uint y) public {\n\t\ta.push(x);\n\t\ta[0].push(y);\n\t\ta[0].pop();\n\t\tassert(a[0][a[0].length - 1] == y);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 3944: (129-144): CHC: Underflow (resulting value less than 0) happens here.\n// Warning 6328: (117-151): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_arg_1.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f(uint x) public {\n\t\ta.push(x);\n\t\tassert(a[a.length - 1] == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_1d.sol",
    "content": "contract C {\n\tuint[] b;\n\n\tfunction f() public {\n\t\trequire(b.length == 0);\n\t\tb.push() = 1;\n\t\tassert(b[0] == 1);\n\t}\n\n\tfunction g() public {\n\t\tb.push() = 1;\n\t\tassert(b[b.length - 1] == 1);\n\t\t// Fails\n\t\tassert(b[b.length - 1] == 100);\n\t}\n\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (199-229): CHC: Assertion violation happens here.\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_2d.sol",
    "content": "contract C {\n\tuint[][] c;\n\n\tfunction f() public {\n\t\trequire(c.length == 0);\n\t\tc.push().push() = 2;\n\t\tassert(c.length == 1);\n\t\tassert(c[0].length == 1);\n\t\tassert(c[0][0] == 2);\n\t}\n\n\tfunction g() public {\n\t\tc.push().push() = 2;\n\t\tassert(c.length > 0);\n\t\tassert(c[c.length - 1].length == 1);\n\t\tassert(c[c.length - 1][c[c.length - 1].length - 1] == 2);\n\t\t// Fails\n\t\tassert(c[c.length - 1][c[c.length - 1].length - 1] == 200);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (362-420): CHC: Assertion violation happens here.\n// Info 1391: CHC: 23 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_2d_2.sol",
    "content": "contract C {\n\tint[][] array2d;\n\tfunction s() public returns (int[] memory) {\n\t\tarray2d.push() = array2d.push();\n\t\tassert(array2d[array2d.length - 1].length == array2d[array2d.length - 2].length);\n\t\treturn array2d[1];\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_3d.sol",
    "content": "contract C {\n\tuint[][][] c;\n\n\tfunction f() public {\n\t\trequire(c.length == 0);\n\t\tc.push().push().push() = 2;\n\t\tassert(c.length == 1);\n\t\tassert(c[0].length == 1);\n\t\tassert(c[0][0].length == 1);\n\t\tassert(c[0][0][0] == 2);\n\t}\n\n\tfunction g() public {\n\t\tc.push().push().push() = 2;\n\t\tuint length1 = c.length;\n\t\tuint length2 = c[length1 - 1].length;\n\t\tuint length3 = c[length1 - 1][length2 - 1].length;\n\t\tassert(length1 > 0);\n\t\tassert(length2 == 1);\n\t\tassert(length3 == 1);\n\t\tassert(c[length1 - 1][length2 - 1][length3 - 1] == 2);\n\t\t// Fails\n\t\tassert(c[length1 - 1][length2 - 1][length3 - 1] == 200);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (537-592): CHC: Assertion violation happens here.\n// Info 1391: CHC: 32 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_1d.sol",
    "content": "contract C {\n\tuint[] b;\n\tfunction f() public {\n\t\tb.push() = b.push();\n\t\tuint length = b.length;\n\t\tassert(length >= 2);\n\t\tassert(b[length - 1] == 0);\n\t\tassert(b[length - 1] == b[length - 2]);\n\t\t// Fails\n\t\tassert(b[length - 1] == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (204-230): CHC: Assertion violation happens here.\n// Info 1391: CHC: 11 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_2d_1.sol",
    "content": "contract C {\n\tuint[][] b;\n\tfunction f() public {\n\t\trequire(b.length == 0);\n\t\tb.push().push() = b.push().push();\n\t\tassert(b.length == 2);\n\t\tassert(b[0].length == 1);\n\t\tassert(b[0].length == 1);\n\t\tassert(b[0][0] == 0);\n\t\tassert(b[1][0] == 0);\n\t\tassert(b[0][0] == b[1][0]);\n\t\t// Fails\n\t\tassert(b[0][0] != b[1][0]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (284-310): CHC: Assertion violation happens here.\n// Info 1391: CHC: 20 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_2d_2.sol",
    "content": "contract C {\n\tuint[][] b;\n\tfunction f() public {\n\t\tb.push().push() = b.push().push();\n\t\tuint length = b.length;\n\t\tassert(length >= 2);\n\t\tuint length1 = b[length - 1].length;\n\t\tuint length2 = b[length - 2].length;\n\t\tassert(length1 == 1);\n\t\tassert(length2 == 1);\n\t\tassert(b[length - 1][length1 - 1] == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 12 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_and_rhs_bytes.sol",
    "content": "contract C {\n\tbytes b;\n\tfunction f() public {\n\t\tb.push() = b.push();\n\t\tuint length = b.length;\n\t\tassert(length >= 2);\n\t\tassert(b[length - 1] == 0);\n\t\tassert(b[length - 1] == b[length - 2]);\n\t\t// Fails\n\t\tassert(b[length - 1] == bytes1(uint8(1)));\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (203-244): CHC: Assertion violation happens here.\n// Info 1391: CHC: 11 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_bytes.sol",
    "content": "contract C {\n\tbytes b;\n\n\tfunction f() public {\n\t\trequire(b.length == 0);\n\t\tb.push() = bytes1(uint8(1));\n\t\tassert(b[0] == bytes1(uint8(1)));\n\t}\n\n\tfunction g() public {\n\t\tbytes1 one = bytes1(uint8(1));\n\t\tb.push() = one;\n\t\tassert(b[b.length - 1] == one);\n\t\t// Fails\n\t\tassert(b[b.length - 1] == bytes1(uint8(100)));\n\t}\n\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (265-310): CHC: Assertion violation happens here.\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_bytes_2d.sol",
    "content": "contract C {\n\tbytes[] c;\n\n\tfunction f() public {\n\t\tbytes1 val = bytes1(uint8(2));\n\t\trequire(c.length == 0);\n\t\tc.push().push() = val;\n\t\tassert(c.length == 1);\n\t\tassert(c[0].length == 1);\n\t\tassert(c[0][0] == val);\n\t}\n\n\tfunction g() public {\n\t\tbytes1 val = bytes1(uint8(2));\n\t\tc.push().push() = val;\n\t\tassert(c.length > 0);\n\t\tassert(c[c.length - 1].length == 1);\n\t\tassert(c[c.length - 1][c[c.length - 1].length - 1] == val);\n\t\t// Fails\n\t\tassert(c[c.length - 1][c[c.length - 1].length - 1] == bytes1(uint8(100)));\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (435-508): CHC: Assertion violation happens here.\n// Info 1391: CHC: 23 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_compound_assignment.sol",
    "content": "contract C {\n\n\tint[] u;\n\n\tfunction t() public {\n\t\trequire(u.length == 0);\n\t\tu.push() -= 1;\n\t\tassert(u[0] < 0); // should hold\n\t\tassert(u[0] >= 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (128-145): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_as_lhs_struct.sol",
    "content": "contract C {\n\tstruct S {\n\t\tint[] b;\n\t}\n\tS s;\n\tstruct T {\n\t\tS s;\n\t}\n\tT t;\n\tfunction f() public {\n\t\ts.b.push() = t.s.b.push();\n\t\tassert(s.b[s.b.length -1] == t.s.b[t.s.b.length - 1]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_function_return_value.sol",
    "content": "contract C {\n\tbytes x;\n\n\tfunction getX() internal view returns (bytes storage) {\n\t\treturn x;\n\t}\n\n\tfunction s() public {\n\t\trequire(x.length == 0);\n\t\tgetX().push(\"a\");\n\t\tassert(x.length == 1); // should hold but knowledge is erased due to pushing a reference\n\t\tassert(x.length == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (168-189): CHC: Assertion violation happens here.\n// Warning 6328: (259-280): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_overflow_1_safe.sol",
    "content": "contract C {\n\tuint256[] x;\n\tconstructor() { x.push(42); }\n\tfunction f() public {\n\t\tx.push(23);\n\t\tassert(x[0] == 42 || x[0] == 23);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreInv: yes\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_overflow_1_safe_no_overflow_assumption.sol",
    "content": "contract C {\n\tuint256[] x;\n\tconstructor() { x.push(42); }\n\tfunction f() public {\n\t\tx.push(23);\n\t\tassert(x[0] == 42);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_overflow_2_safe.sol",
    "content": "contract C {\n\tuint256[] x;\n\tfunction f(uint256 l) public {\n\t\trequire(x.length == 0);\n\t\tx.push(42);\n\t\tx.push(84);\n\t\tfor(uint256 i = 0; i < l; ++i)\n\t\t\tx.push(23);\n\t\tassert(x[0] == 42 || x[0] == 23);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_overflow_2_safe_no_overflow_assumption.sol",
    "content": "contract C {\n\tuint256[] x;\n\tfunction f(uint256 l) public {\n\t\trequire(x.length == 0);\n\t\tx.push(42);\n\t\tx.push(84);\n\t\tfor(uint256 i = 0; i < l; ++i)\n\t\t\tx.push(23);\n\t\tassert(x[0] == 42);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_push_no_args_1.sol",
    "content": "contract C {\n\tint[][] array2d;\n\tfunction l() public {\n\t\tarray2d.push().push();\n\t\tassert(array2d.length > 0);\n\t\tassert(array2d[array2d.length - 1].length > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_push_no_args_1_fail.sol",
    "content": "contract C {\n\tint[][] array2d;\n\tfunction l() public {\n\t\tarray2d.push().push();\n\t\tassert(array2d.length > 2);\n\t\tassert(array2d[array2d.length - 1].length > 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (81-107): CHC: Assertion violation happens here.\n// Warning 6328: (111-157): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_push_no_args_2.sol",
    "content": "contract C {\n\tint[][][] array2d;\n\tfunction l() public {\n\t\tarray2d.push().push().push();\n\t\tassert(array2d.length > 0);\n\t\tuint last = array2d[array2d.length - 1].length;\n\t\tassert(last > 0);\n\t\tassert(array2d[array2d.length - 1][last - 1].length > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_push_no_args_2_fail.sol",
    "content": "contract C {\n\tint[][][] array2d;\n\tfunction l() public {\n\t\tarray2d.push().push().push();\n\t\tassert(array2d.length > 2);\n\t\tuint last = array2d[array2d.length - 1].length;\n\t\tassert(last > 3);\n\t\tassert(array2d[array2d.length - 1][last - 1].length > 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (90-116): CHC: Assertion violation happens here.\n// Warning 6328: (170-186): CHC: Assertion violation happens here.\n// Warning 6328: (190-246): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_storage_ref_safe_aliasing.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction f() public {\n\t\ta.push();\n\t\tuint[] storage b = a[0];\n\t\tb.push(8);\n\t\tassert(b[b.length - 1] == 8);\n\t\t// Safe but fails due to aliasing.\n\t\tassert(a[0][a[0].length - 1] == 8);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6368: (179-183): CHC: Out of bounds access happens here.\n// Warning 6368: (184-188): CHC: Out of bounds access happens here.\n// Warning 3944: (184-199): CHC: Underflow (resulting value less than 0) happens here.\n// Warning 6328: (172-206): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_storage_ref_unsafe_aliasing.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction f() public {\n\t\ta.push();\n\t\ta[0].push();\n\t\ta[0][0] = 16;\n\t\tuint[] storage b = a[0];\n\t\tb[0] = 32;\n\t\t// Access is safe but fails due to aliasing.\n\t\tassert(a[0][0] == 16);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 6368: (188-192): CHC: Out of bounds access happens here.\n// Warning 6368: (188-195): CHC: Out of bounds access happens here.\n// Warning 6328: (181-202): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_storage_ref_unsafe_length.sol",
    "content": "contract C {\n\tuint[][] a;\n\tuint[][][] c;\n\tuint[] d;\n\tconstructor() {\n\t\tc.push().push().push();\n\t\td.push(); d.push();\n\t}\n\tfunction f() public {\n\t\ta.push();\n\t\tuint[] storage b = a[0];\n\t\t// Access is safe but oob reported due to aliasing.\n\t\tc[0][0][0] = 12;\n\t\t// Access is safe but oob reported due to aliasing.\n\t\td[1] = 7;\n\t\tb.push(8);\n\t\tassert(a[0].length == 0);\n\t\t// Safe but knowledge about `c` is erased because `b` could be pointing to `c[x][y]`.\n\t\t// Access is safe but oob reported due to aliasing.\n\t\tassert(c[0][0][0] == 12);\n\t\t// Safe but knowledge about `d` is erased because `b` could be pointing to `d`.\n\t\t// Removed assertion because current Spacer seg faults in cex generation.\n\t\t//assert(d[1] == 7);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6368: (238-242): CHC: Out of bounds access happens here.\n// Warning 6368: (238-245): CHC: Out of bounds access happens here.\n// Warning 6368: (238-248): CHC: Out of bounds access happens here.\n// Warning 6368: (311-315): CHC: Out of bounds access happens here.\n// Warning 6368: (343-347): CHC: Out of bounds access happens here.\n// Warning 6328: (336-360): CHC: Assertion violation happens here.\n// Warning 6368: (513-517): CHC: Out of bounds access happens here.\n// Warning 6368: (513-520): CHC: Out of bounds access happens here.\n// Warning 6368: (513-523): CHC: Out of bounds access happens here.\n// Warning 6328: (506-530): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_struct_member_1.sol",
    "content": "contract C {\n\tstruct S {\n\t\tint[] b;\n\t}\n\tS s;\n\tstruct T {\n\t\tS s;\n\t}\n\tT t;\n\tfunction f() public {\n\t\ts.b.push();\n\t\tt.s.b.push();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_struct_member_2.sol",
    "content": "contract C {\n\tstruct S {\n\t\tint[] b;\n\t}\n\tS s;\n\tstruct T {\n\t\tS[] s;\n\t}\n\tT t;\n\tfunction f() public {\n\t\ts.b.push();\n\t\tt.s.push();\n\t\tt.s[0].b.push();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_zero_2d_safe.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction f() public {\n\t\ta.push();\n\t\ta[a.length - 1].push();\n\t\tassert(a[a.length - 1][0] == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_zero_2d_unsafe.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction f() public {\n\t\ta.push();\n\t\ta[a.length - 1].push();\n\t\tassert(a[a.length - 1][0] == 100);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (89-122): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_zero_safe.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f() public {\n\t\ta.push();\n\t\tassert(a[a.length - 1] == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/push_zero_unsafe.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction f() public {\n\t\ta.push();\n\t\tassert(a[a.length - 1] == 100);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (61-91): CHC: Assertion violation happens here.\\nCounterexample:\\na = [0]\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/storage_pointer_push_1.sol",
    "content": "contract C {\n\tint[][] array2d;\n\tfunction l() public {\n\t\ts().push();\n\t\t// False positive.\n\t\t// Knowledge is erased because `s()` is a storage pointer.\n\t\tassert(array2d[2].length > 0);\n\t}\n\tfunction s() internal returns (int[] storage) {\n\t\tarray2d.push();\n\t\tarray2d.push();\n\t\tarray2d.push();\n\t\treturn array2d[2];\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6368: (159-169): CHC: Out of bounds access happens here.\n// Warning 6328: (152-181): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/array_members/storage_pointer_push_1_safe.sol",
    "content": "contract C {\n\tint[][] array2d;\n\tfunction l() public {\n\t\ts();\n\t\tarray2d[2].push();\n\t\tassert(array2d[2].length > 0);\n\t}\n\tfunction s() internal returns (int[] storage) {\n\t\tarray2d.push();\n\t\tarray2d.push();\n\t\tarray2d.push();\n\t\treturn array2d[2];\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_non_zero.sol",
    "content": "contract C {\n\tconstructor() payable {\n\t\tassert(address(this).balance == 0); // should fail\n\t\tassert(address(this).balance > 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (40-74): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor(){ msg.value: 0 }\n// Warning 6328: (93-126): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor(){ msg.value: 0 }\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_non_zero_2.sol",
    "content": "contract C {\n\tconstructor() payable {\n\t\trequire(msg.value > 100);\n\t}\n\tfunction f() public view {\n\t\tassert(address(this).balance > 100); // should hold\n\t\tassert(address(this).balance > 200); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (153-188): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_receive.sol",
    "content": "contract C {\n\tuint prevBalance;\n\tconstructor() payable {\n\t\tprevBalance = address(this).balance;\n\t}\n\tfunction f() public payable {\n\t\tassert(address(this).balance == prevBalance + msg.value); // should fail because there might be funds from selfdestruct/block.coinbase\n\t\tassert(address(this).balance < prevBalance + msg.value); // should fail\n\t\tassert(address(this).balance >= prevBalance + msg.value); // should hold\n\t\tprevBalance = address(this).balance;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (132-188): CHC: Assertion violation happens here.\n// Warning 6328: (269-324): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_2.sol",
    "content": "contract C {\n\tuint x;\n\tbool once;\n\tconstructor() payable {\n\t\tx = address(this).balance;\n\t}\n\tfunction f() public payable {\n\t\trequire(!once);\n\t\tonce = true;\n\t\trequire(msg.value > 0);\n\t\tassert(address(this).balance > x); // should hold\n\t\tassert(address(this).balance > x + 10); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (266-272): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (235-273): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_3.sol",
    "content": "contract C {\n\tconstructor() payable {\n\t\tassert(address(this).balance == msg.value); // should fail because there might be funds from before deployment\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (40-82): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor(){ msg.value: 0 }\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_4.sol",
    "content": "contract C {\n\tuint c;\n\tfunction f() public payable {\n\t\trequire(msg.value > 10);\n\t\t++c;\n\t}\n\tfunction inv() public view {\n\t\tassert(address(this).balance >= c * 11); // should hold\n\t\tassert(address(this).balance >= c * 12); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 4984: (82-85): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here.\n// Warning 4984: (154-160): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here.\n// Warning 4984: (212-218): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here.\n// Warning 6328: (180-219): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 2661: (82-85): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 2661: (154-160): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 2661: (212-218): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_5.sol",
    "content": "contract C {\n\tuint sum = msg.value;\n\tfunction f() public payable {\n\t\tsum += msg.value;\n\t}\n\tfunction inv() public view {\n\t\tassert(address(this).balance == sum); // should fail\n\t\tassert(address(this).balance >= sum); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (122-158): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_calls.sol",
    "content": "contract C {\n\tbool once;\n\tfunction f() public payable {\n\t\trequire(!once);\n\t\tonce = true;\n\t\trequire(msg.value == 10);\n\t\tassert(address(this).balance >= 10); // should hold\n\t\tassert(address(this).balance >= 20); // should fail\n\t\tg();\n\t}\n\tfunction g() internal view {\n\t\tassert(address(this).balance >= 10); // should hold\n\t\tassert(address(this).balance >= 20); // should fail\n\t\th();\n\t}\n\tfunction h() internal view {\n\t\tassert(address(this).balance >= 10); // should hold\n\t\tassert(address(this).balance >= 20); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (173-208): CHC: Assertion violation happens here.\n// Warning 6328: (321-356): CHC: Assertion violation happens here.\n// Warning 6328: (469-504): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls.sol",
    "content": "interface I {\n\tfunction ext() external;\n}\n\ncontract C {\n\tfunction f(I _i) public {\n\t\tuint x = address(this).balance;\n\t\t_i.ext();\n\t\tassert(address(this).balance == x); // should fail\n\t\tassert(address(this).balance >= x); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (131-165): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_2.sol",
    "content": "contract C {\n\tfunction f(address _a) public {\n\t\tuint x = address(this).balance;\n\t\t_a.call(\"\");\n\t\tassert(address(this).balance == x); // should fail\n\t\tassert(address(this).balance >= x); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreInv: yes\n// ----\n// Warning 9302: (82-93): Return value of low-level calls not used.\n// Warning 6328: (97-131): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_receive_ext_calls_mutex.sol",
    "content": "interface I {\n\tfunction ext() external;\n}\n\ncontract C {\n\tbool lock;\n\tmodifier mutex {\n\t\trequire(!lock);\n\t\tlock = true;\n\t\t_;\n\t\tlock = false;\n\t}\n\tfunction f(I _i) public mutex {\n\t\tuint x = address(this).balance;\n\t\t_i.ext();\n\t\tassert(address(this).balance == x); // should hold\n\t\tassert(address(this).balance < x); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (277-310): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_spend.sol",
    "content": "contract C {\n\tconstructor() payable {\n\t\trequire(msg.value > 100);\n\t}\n\tuint c;\n\tfunction f(address payable _a, uint _v) public {\n\t\trequire(_v < 10);\n\t\trequire(c < 2);\n\t\t++c;\n\t\t_a.transfer(_v);\n\t}\n\tfunction inv() public view {\n\t\tassert(address(this).balance > 80); // should hold\n\t\tassert(address(this).balance > 90); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 9207: (175-186): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 6328: (280-314): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_spend_2.sol",
    "content": "contract C {\n\tconstructor() payable {\n\t\trequire(msg.value > 100);\n\t}\n\tfunction f(address payable _a, uint _v) public {\n\t\trequire(_v < 10);\n\t\t_a.transfer(_v);\n\t}\n\tfunction inv() public view {\n\t\tassert(address(this).balance > 0); // should fail\n\t\tassert(address(this).balance > 80); // should fail\n\t\tassert(address(this).balance > 90); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 9207: (141-152): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 8656: (141-156): CHC: Insufficient funds happens here.\n// Warning 6328: (193-226): CHC: Assertion violation happens here.\n// Warning 6328: (245-279): CHC: Assertion violation happens here.\n// Warning 6328: (298-332): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_zero.sol",
    "content": "contract C {\n\tconstructor() {\n\t\tassert(address(this).balance == 0); // should fail because there might be funds from before deployment\n\t\tassert(address(this).balance > 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (32-66): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\n// Warning 6328: (137-170): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_zero_2.sol",
    "content": "contract C {\n\tfunction f() public view {\n\t\tassert(address(this).balance == 0); // should fail because there might be funds from before deployment\n\t\tassert(address(this).balance > 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (43-77): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (148-181): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_zero_3.sol",
    "content": "contract C {\n\tuint x = address(this).balance;\n\tconstructor() {\n\t\tassert(x == 0); // should fail because there might be funds from before deployment\n\t\tassert(x > 0); // should fail\n\t}\n\tfunction f() public view {\n\t\tassert(x == 0); // should fail because there might be funds from before deployment\n\t\tassert(x > 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (65-79): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1\\n\\nTransaction trace:\\nC.constructor()\n// Warning 6328: (150-163): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\n// Warning 6328: (213-227): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 1\\nC.f()\n// Warning 6328: (298-311): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/balance_zero_4.sol",
    "content": "contract C {\n\tuint x = g();\n\tfunction g() internal view returns (uint) {\n\t\treturn address(this).balance;\n\t}\n\tconstructor() {\n\t\tassert(x == 0); // should fail because there might be funds from before deployment\n\t\tassert(x > 0); // should fail\n\t}\n\tfunction f() public view {\n\t\tassert(x == 0); // should fail because there might be funds from before deployment\n\t\tassert(x > 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (127-141): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1\\n\\nTransaction trace:\\nC.constructor()\n// Warning 6328: (212-225): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\n// Warning 6328: (275-289): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 1\\nC.f()\n// Warning 6328: (360-373): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/decreasing_balance.sol",
    "content": "contract C {\n\tuint t;\n\tconstructor() {\n\t\tt = address(this).balance;\n\t}\n\tfunction f(address payable a, uint x) public {\n\t\trequire(address(this).balance >= x);\n\t\ta.transfer(x);\n\t}\n\tfunction inv() public view {\n\t\t// If only looking at `f`, it looks like this.balance always decreases.\n\t\t// However, the edge case of a contract `selfdestruct` sending its remaining balance\n\t\t// to this contract should make the claim false (since there's no fallback/receive here).\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(address(this).balance == t);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9207: (160-170): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/free_function_1.sol",
    "content": "function l(address payable a) {}\n\ncontract C {\n\tuint x;\n\tfunction f(address payable a) public payable {\n\t\trequire(msg.value > 1);\n\t\tuint b1 = address(this).balance;\n\t\tl(a);\n\t\tuint b2 = address(this).balance;\n\t\tassert(b1 == b2); // should hold\n\t\tassert(x == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/free_function_2.sol",
    "content": "function l(address payable a) {\n\ta.transfer(1);\n}\n\ncontract C {\n\tuint x;\n\tfunction f(address payable a) public payable {\n\t\trequire(msg.value > 1);\n\t\tuint b1 = address(this).balance;\n\t\trequire(a != address(this));\n\t\tl(a);\n\t\tuint b2 = address(this).balance;\n\t\tassert(b1 == b2); // should fail\n\t\tassert(b1 == b2 + 1); // should hold\n\t\tassert(x == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 9207: (33-43): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 6328: (258-274): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\na = 0x7e1e\\nb1 = 38\\nb2 = 37\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.f(0x7e1e){ msg.value: 17 }\\n    l(0x7e1e) -- internal call\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/library_internal_1.sol",
    "content": "library L {\n\tfunction l(address payable a) internal {}\n}\n\ncontract C {\n\tusing L for address payable;\n\tuint x;\n\tfunction f(address payable a) public payable {\n\t\trequire(msg.value > 1);\n\t\tuint b1 = address(this).balance;\n\t\ta.l();\n\t\tuint b2 = address(this).balance;\n\t\tassert(b1 == b2); // should hold\n\t\tassert(x == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/library_internal_2.sol",
    "content": "library L {\n\tfunction l(address payable a) internal {\n\t\trequire(a != address(this));\n\t\ta.transfer(1);\n\t}\n}\n\ncontract C {\n\tusing L for address payable;\n\tuint x;\n\tfunction f(address payable a) public payable {\n\t\trequire(msg.value > 1);\n\t\tuint b1 = address(this).balance;\n\t\ta.l();\n\t\tuint b2 = address(this).balance;\n\t\tassert(b1 == b2); // should fail\n\t\tassert(b1 == b2 + 1); // should hold\n\t\tassert(x == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 9207: (87-97): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 6328: (315-331): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\na = 0x7e1e\\nb1 = 38\\nb2 = 37\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.f(0x7e1e){ msg.value: 17 }\\n    L.l(0x7e1e) -- internal call\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/library_public_1.sol",
    "content": "library L {\n\tfunction l(address payable a) public {}\n}\n\ncontract C {\n\tusing L for address payable;\n\tuint x;\n\tfunction f(address payable a) public payable {\n\t\trequire(msg.value > 1);\n\t\tuint b1 = address(this).balance;\n\t\ta.l();\n\t\tuint b2 = address(this).balance;\n\t\tassert(b1 == b2); // should fail because the called library can transfer with `this`s balance\n\t\tassert(x == 0); // should fail because of `delegatecall`\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4588: (219-224): Assertion checker does not yet implement this type of function call.\n// Warning 6328: (263-279): CHC: Assertion violation happens here.\n// Warning 6328: (359-373): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/library_public_2.sol",
    "content": "library L {\n\tfunction l(address payable a) public {\n\t\ta.transfer(1);\n\t}\n}\n\ncontract C {\n\tusing L for address payable;\n\tuint x;\n\tfunction f(address payable a) public payable {\n\t\trequire(msg.value > 1);\n\t\tuint b1 = address(this).balance;\n\t\ta.l();\n\t\tuint b2 = address(this).balance;\n\t\tassert(b1 == b2); // should fail\n\t\tassert(x == 0); // should fail because of `delegatecall`\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 9207: (54-64): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 4588: (238-243): Assertion checker does not yet implement this type of function call.\n// Warning 8656: (54-67): CHC: Insufficient funds happens here.\\nCounterexample:\\n\\na = 0x0\\n\\nTransaction trace:\\nL.constructor()\\nL.l(0x0)\n// Warning 6328: (282-298): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\na = 0x0\\nb1 = 15923\\nb2 = 15924\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.f(0x0){ msg.value: 15923 }\n// Warning 6328: (317-331): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1\\na = 0x0\\nb1 = 15923\\nb2 = 15924\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.f(0x0){ msg.value: 15923 }\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/library_public_3.sol",
    "content": "library L {\n\tfunction l(address payable a) public returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n\ncontract C {\n\tusing L for address payable;\n\tuint x;\n\tfunction f(address payable a) public payable {\n\t\trequire(msg.value > 1);\n\t\tuint b1 = address(this).balance;\n\t\tuint v = a.l();\n\t\tuint b2 = address(this).balance;\n\t\tassert(b1 == b2); // should fail because the called library can transfer with `this`s balance\n\t\tassert(x == 0); // should fail because of `delegatecall`\n\t\tassert(v == msg.value); // should hold but we don't support `delegatecall` properly yet.\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 5667: (24-41): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 4588: (265-270): Assertion checker does not yet implement this type of function call.\n// Warning 6328: (309-325): CHC: Assertion violation happens here.\n// Warning 6328: (405-419): CHC: Assertion violation happens here.\n// Warning 6328: (464-486): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/library_public_4.sol",
    "content": "library L {\n\tfunction l(address payable a) public returns (address) {\n\t\treturn msg.sender;\n\t}\n}\n\ncontract C {\n\tusing L for address payable;\n\tuint x;\n\tfunction f(address payable a) public payable {\n\t\trequire(msg.value > 1);\n\t\tuint b1 = address(this).balance;\n\t\taddress v = a.l();\n\t\tuint b2 = address(this).balance;\n\t\tassert(b1 == b2); // should fail because the called library can transfer with `this`s balance\n\t\tassert(x == 0); // should fail because of `delegatecall`\n\t\tassert(v == msg.sender); // should hold but we don't support `delegatecall` properly yet.\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 5667: (24-41): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 2018: (13-93): Function state mutability can be restricted to view\n// Warning 4588: (272-277): Assertion checker does not yet implement this type of function call.\n// Warning 6328: (316-332): CHC: Assertion violation happens here.\n// Warning 6328: (412-426): CHC: Assertion violation happens here.\n// Warning 6328: (471-494): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change.sol",
    "content": "contract C {\n\taddress t;\n\tconstructor() {\n\t\tt = address(this);\n\t}\n\tfunction inv() public view {\n\t\tassert(address(this) == t);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_external_call.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual;\n}\n\ncontract C {\n\taddress t;\n\tconstructor() {\n\t\tt = address(this);\n\t}\n\tfunction f(D d) public {\n\t\taddress a = address(this);\n\t\td.d();\n\t\tassert(address(this) == t);\n\t\tassert(a == t);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreInv: yes\n// SMTIgnoreOS: macos\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/this_does_not_change_internal_call.sol",
    "content": "contract C {\n\taddress t;\n\tconstructor() {\n\t\tt = address(this);\n\t}\n\tfunction f() public view {\n\t\tg(address(this));\n\t}\n\tfunction g(address a) internal view {\n\t\tassert(a == t);\n\t\tassert(a == address(this));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/transfer_1.sol",
    "content": "contract C {\n\tfunction f(address payable a) public {\n\t\trequire(address(this).balance > 1000);\n\t\ta.transfer(666);\n\t\tassert(address(this).balance > 100);\n\t\t// Fails.\n\t\tassert(address(this).balance > 500);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 9207: (96-106): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 6328: (166-201): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0x0)\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/transfer_2.sol",
    "content": "contract C {\n\taddress payable recipient;\n\tuint amount;\n\n\tfunction shouldHold() public {\n\t\tuint tempAmount = address(this).balance;\n\t\trecipient.transfer(tempAmount);\n\t\trecipient.transfer(amount);\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 9207: (133-151): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 9207: (167-185): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/transfer_3.sol",
    "content": "contract C {\n\taddress payable recipient;\n\n\tfunction shouldFail() public {\n\t\trecipient.transfer(1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9207: (76-94): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 8656: (76-97): CHC: Insufficient funds happens here.\\nCounterexample:\\nrecipient = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: recipient = 0x0\\nC.shouldFail()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/blockchain_state/transfer_4.sol",
    "content": "contract C {\n\taddress payable recipient;\n\n\tfunction f() public payable {\n\t\trequire(msg.value > 1);\n\t\trecipient.transfer(1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9207: (101-119): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/assert.sol",
    "content": "contract C {\n\tfunction f(uint x) public pure {\n\t\tassert(x > 0);\n\t}\n\tfunction g(uint x) public pure {\n\t\trequire(x >= 0);\n\t}\n\tfunction h(uint x) public pure {\n\t\trequire(x == 2);\n\t\trequire(x != 2);\n\t}\n\tfunction i(uint x) public pure {\n\t\tif (false) {\n\t\t\tif (x != 2) {\n\t\t\t}\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (49-62): BMC: Assertion violation happens here.\n// Warning 6838: (111-117): BMC: Condition is always true.\n// Warning 6838: (186-192): BMC: Condition is always false.\n// Warning 2512: (254-260): BMC: Condition unreachable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/assert_in_constructor.sol",
    "content": "contract C {\n\tuint x = initX();\n\n\tfunction initX() internal pure returns (uint) {\n\t\treturn 42;\n\t}\n}\n\ncontract D is C {\n\tuint y;\n\n\tconstructor() {\n\t\tassert(x == 42);\n\t\ty = x;\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/branches_in_modifiers.sol",
    "content": "contract C {\n\n\tuint x;\n\n\tmodifier check() {\n\t\trequire(x == 0);\n\t\t_;\n\t\tassert(x == 1); // should fail;\n\t\tassert(x == 0); // should hold;\n\t}\n\n\tmodifier inc() {\n\t\tif (x == 0) {\n\t\t\treturn;\n\t\t}\n\t\tx = x + 1;\n\t\t_;\n\t}\n\n\tfunction test() check inc public {\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (70-84): BMC: Assertion violation happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/branches_in_modifiers_2.sol",
    "content": "contract C {\n\n    uint x;\n\n    function reset_if_overflow() internal postinc {\n        if (x < 10)\n            return;\n        x = 0;\n    }\n\n    modifier postinc() {\n        if (x == 0) {\n            return;\n        }\n        _;\n        x = x + 1;\n    }\n\n    function test() public {\n        if (x == 0) {\n            reset_if_overflow();\n            assert(x == 1); // should fail;\n            assert(x == 0); // should hold;\n            return;\n        }\n        if (x < 10) {\n            uint oldx = x;\n            reset_if_overflow();\n            assert(oldx + 1 == x); // should hold;\n            assert(oldx == x);     // should fail;\n            return;\n        }\n        reset_if_overflow();\n        assert(x == 1); // should hold;\n        assert(x == 0); // should fail;\n    }\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (351-365): BMC: Assertion violation happens here.\n// Warning 4661: (602-619): BMC: Assertion violation happens here.\n// Warning 4661: (748-762): BMC: Assertion violation happens here.\n// Info 6002: BMC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructor_state_variable_init.sol",
    "content": "contract A {\n\tint x;\n\tconstructor (int a) { x = a;}\n}\n\ncontract B is A {\n\tint y;\n\tconstructor(int a) A(-a) {\n\t\tif (a > 0) {\n\t\t\ty = 2;\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\ty = 3;\n\t\t}\n\t\ty = 4; // overwrites the else branch\n\t}\n}\n\ncontract C is B {\n\tconstructor(int a) B(a) {\n\t\tassert(y != 3); // should hold\n\t\tassert(y == 4); // should fail\n\t\tif (a > 0) {\n\t\t\tassert(x < 0 && y == 2); // should hold\n\t\t\tassert(x < 0 && y == 4); // should fail\n\t\t}\n\t\telse {\n\t\t\tassert(x >= 0 && y == 4); // should hold\n\t\t\tassert(x >= 0 && y == 2); // should fail\n\t\t\tassert(x > 0); // should fail\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (297-311): BMC: Assertion violation happens here.\n// Warning 4661: (389-412): BMC: Assertion violation happens here.\n// Warning 4661: (489-513): BMC: Assertion violation happens here.\n// Warning 4661: (533-546): BMC: Assertion violation happens here.\n// Info 6002: BMC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructor_state_variable_init_chain_alternate.sol",
    "content": "contract A {\n\tuint x = 1;\n}\n\ncontract B is A {\n\tconstructor(int a) {\n\t\tif (a > 0) {\n\t\t\tx = 2;\n\t\t\treturn;\n\t\t}\n\t\tx = 3;\n\t}\n}\n\nabstract contract C is B {\n}\n\ncontract D is C {\n\tconstructor(int a) B(a) {\n\t\tassert(a > 0 || x == 3); // should hold\n\t\tassert(a <= 0 || x == 2); // should hold\n\t\tassert(x == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (286-300): BMC: Assertion violation happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructor_state_variable_init_diamond.sol",
    "content": "contract A {\n\tint x;\n}\n\ncontract B is A {\n\tint y;\n\tconstructor (int a) {\n\t\tif (a >= 0) {\n\t\t\ty = 1;\n\t\t\treturn;\n\t\t}\n\t\tx = 1;\n\t\ty = 2;\n\t}\n}\n\ncontract C is A {\n\tint z;\n\tconstructor (int a) {\n\t\tif (a >= 0) {\n\t\t\tz = 1;\n\t\t\treturn;\n\t\t}\n\t\tx = -1;\n\t\tz = 2;\n\t}\n}\n\ncontract D1 is B, C {\n\tconstructor() B(1) C(1) {\n\t\tassert(x == 0); // should hold\n\t\tassert(x == 1); // should fail\n\t\tassert(x == -1); // should fail\n\t}\n}\n\ncontract D2 is B, C {\n\tconstructor() B(1) C(-1) {\n\t\tassert(x == 0); // should fail\n\t\tassert(x == 1); // should fail\n\t\tassert(x == -1); // should hold (constructor of C is executed AFTER constructor of B)\n\t}\n}\n\ncontract D3 is B, C {\n\tconstructor() B(-1) C(1) {\n\t\tassert(x == 0); // should fail\n\t\tassert(x == 1); // should hold\n\t\tassert(x == -1); // should fail\n\t}\n}\n\ncontract D4 is B, C {\n\tconstructor() B(-1) C(-1) {\n\t\tassert(x == 0); // should fail\n\t\tassert(x == 1); // should fail\n\t\tassert(x == -1); // should hold (constructor of C is executed AFTER constructor of B)\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (337-351): BMC: Assertion violation happens here.\n// Warning 4661: (370-385): BMC: Assertion violation happens here.\n// Warning 4661: (460-474): BMC: Assertion violation happens here.\n// Warning 4661: (493-507): BMC: Assertion violation happens here.\n// Warning 4661: (670-684): BMC: Assertion violation happens here.\n// Warning 4661: (736-751): BMC: Assertion violation happens here.\n// Warning 4661: (827-841): BMC: Assertion violation happens here.\n// Warning 4661: (860-874): BMC: Assertion violation happens here.\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/constructors.sol",
    "content": "contract B {\n\tint x;\n\tconstructor(int b) {\n\t\tif (b > 0) {\n\t\t\tx = 1;\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\tx = 2;\n\t\t\treturn;\n\t\t}\n\t\tx = 3; // dead code\n\t}\n}\n\ncontract C is B {\n\tconstructor(int a) B(a) {\n\t\tassert(a > 0 || x == 2); // should hold\n\t\tassert(a <= 0 || x == 1); // should hold\n\t\tassert(x == 3); // should fail\n\t\tassert(x == 2); // should fail\n\t\tassert(x == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 5740: (119-124): Unreachable code.\n// Warning 4661: (277-291): BMC: Assertion violation happens here.\n// Warning 4661: (310-324): BMC: Assertion violation happens here.\n// Warning 4661: (343-357): BMC: Assertion violation happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/nested_if.sol",
    "content": "contract C {\n\n\tfunction test(uint256 a, uint256 b) public pure {\n\t\tassert(nested_if(a,b) != 42); // should hold\n\t\tassert(nested_if(a,b) == 1);  // should fail\n\t}\n\n\tfunction nested_if(uint256 a, uint256 b) internal pure returns (uint256) {\n\t\tif (a < 5) {\n\t\t\tif (b > 1) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t\tif (a == 2 && b == 2) {\n\t\t\treturn 42; // unreachable\n\t\t}\n\t\telse {\n\t\t\treturn 1;\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (114-141): BMC: Assertion violation happens here.\n// Warning 6838: (299-315): BMC: Condition is always false.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/return_in_both_branches.sol",
    "content": "contract C {\n\n\tfunction test() public pure {\n\t\tassert(branches(0) == 0);\n\t\tassert(branches(1) == 42);\n\t}\n\n\tfunction branches(uint256 a) internal pure returns (uint256) {\n\t\tif (a == 0) {\n\t\t\treturn 0;\n\t\t}\n\t\telse {\n\t\t\treturn 42;\n\t\t}\n\t\treturn 1; // dead code\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 5740: (232-240): Unreachable code.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/simple_if.sol",
    "content": "contract C {\n\tfunction test(uint256 a, uint256 b) public pure returns (uint256) {\n\t\tif (a == 0) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn b / a; // This division is safe because of the early return in if-block.\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/simple_if2.sol",
    "content": "contract C {\n\n\tfunction test(uint256 a) public pure {\n\t\tassert(simple_if(a) == 1); // should fail for a == 0\n\t}\n\n\tfunction simple_if(uint256 a) internal pure returns (uint256) {\n\t\tif (a == 0) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn 1;\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (56-81): BMC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/simple_if_array.sol",
    "content": "contract C {\n\n\tuint[] a;\n\n\tconstructor () {\n\t\ta.push();\n\t\ta.push();\n\t}\n\n\tfunction check() public {\n\t\trequire(a.length >= 2);\n\t\trequire(a[1] == 0);\n\t\tconditional_store();\n\t\tassert(a[1] == 1); // should fail;\n\t\tassert(a[1] == 0); // should hold;\n\t}\n\n\tfunction conditional_store() internal {\n\t\tif (a[1] == 0) {\n\t\t\treturn;\n\t\t}\n\t\ta[1] = 1;\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (172-189): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/simple_if_state_var.sol",
    "content": "contract C {\n\n\tuint x;\n\n\tfunction check() public {\n\t\trequire(x == 0);\n\t\tconditional_increment();\n\t\tassert(x == 1); // should fail;\n\t\tassert(x == 0); // should hold;\n\t}\n\n\tfunction conditional_increment() internal {\n\t\tif (x == 0) {\n\t\t\treturn;\n\t\t}\n\t\tx = 1;\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (99-113): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/simple_if_struct.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t}\n\tS s;\n\n\tfunction check() public {\n\t\trequire(s.x == 0);\n\t\tconditional_increment();\n\t\tassert(s.x == 1); // should fail;\n\t\tassert(s.x == 0); // should hold;\n\t}\n\n\tfunction conditional_increment() internal {\n\t\tif (s.x == 0) {\n\t\t\treturn;\n\t\t}\n\t\ts.x = 1;\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (123-139): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/simple_if_struct_2.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t}\n\tS s;\n\n\tfunction check() public {\n\t\trequire(s.x == 0);\n\t\tconditional_increment();\n\t\tassert(s.x == 1); // should fail;\n\t\tassert(s.x == 0); // should hold;\n\t}\n\n\tfunction conditional_increment() internal {\n\t\tif (s.x == 0) {\n\t\t\treturn;\n\t\t}\n\t\ts = S(1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (123-139): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/simple_if_tuple.sol",
    "content": "contract C {\n\n\tuint x;\n\tuint y;\n\n\tfunction check() public {\n\t\trequire(x == 0);\n\t\trequire(y == 0);\n\t\tconditional_increment();\n\t\tassert(x == 0); // should fail;\n\t\tassert(x == 1); // should fail;\n\t\tassert(x == 2); // should hold;\n\t}\n\n\tfunction conditional_increment() internal {\n\t\tif (x == 0) {\n\t\t\t(x,y) = (2,2);\n\t\t\treturn;\n\t\t}\n\t\t(x,y) = (1,1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (127-141): BMC: Assertion violation happens here.\n// Warning 4661: (161-175): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/branches_with_return/triple_nested_if.sol",
    "content": "contract C {\n\n    uint a;\n    uint b;\n    uint c;\n\n\tfunction test() public view {\n\t\tif (a == 0) {\n\t\t\tif (b == 0) {\n\t\t\t\tif (c == 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tassert(a != 0 || b != 0 || c != 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/call_balance.sol",
    "content": "contract C {\n\tfunction f(address _a) public {\n\t\tuint b1 = address(this).balance;\n\t\t_a.call(\"\");\n\t\tuint b2 = address(this).balance;\n\t\tassert(b1 == b2); // should fail\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 9302: (83-94): Return value of low-level calls not used.\n// Warning 4661: (133-149): BMC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/call_state_var.sol",
    "content": "contract C {\n\tuint x;\n\tfunction f(address _a) public {\n\t\tx = 2;\n\t\t_a.call(\"\");\n\t\tassert(x == 2); // should fail\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 9302: (66-77): Return value of low-level calls not used.\n// Warning 4661: (81-95): BMC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/compound_bitwise_or_uint_3.sol",
    "content": "contract C {\n    struct S {\n        uint x;\n    }\n    S s;\n    function f(bool b) public {\n        s.x |= b ? 1 : 2;\n        assert(s.x > 0);\n    }\n}\n// ====\n// SMTEngine: bmc\n// SMTShowUnproved: no\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/cross_contract_getter_call.sol",
    "content": "contract C {\n\tD internal d;\n\tconstructor() {\n\t\td = new D();\n\t}\n\tfunction invokeAndCheck() public {\n\t\td.set();\n\t\tassert(d.n() <= 1);\n\t}\n}\n\ncontract D {\n\tuint public n;\n\tfunction set() external {\n\t\tn = 1;\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 8729: (51-58): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n// Warning 4661: (112-130): BMC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/funds.sol",
    "content": "contract C {\n\tfunction f(address payable a) public {\n\t\ta.transfer(200);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 9207: (55-65): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 1236: (55-70): BMC: Insufficient funds happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/implicit_constructor_with_function_calls.sol",
    "content": "contract C {\n\tuint x = initX();\n\tuint y = initY();\n\n    function initX() internal pure returns (uint) {\n\t\treturn 42;\n\t}\n\n\tfunction initY() internal view returns (uint) {\n\t\tassert(x == 42);\n\t\treturn x;\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (172-187): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/math.sol",
    "content": "contract C {\n\tfunction a(uint x, uint y) public pure returns (uint) {\n\t\treturn x + y;\n\t}\n\tfunction s(uint x, uint y) public pure returns (uint) {\n\t\treturn x - y;\n\t}\n\tfunction m(uint x, uint y) public pure returns (uint) {\n\t\treturn x * y;\n\t}\n\tfunction d(uint x, uint y) public pure returns (uint) {\n\t\treturn x / y;\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 2661: (79-84): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4144: (155-160): BMC: Underflow (resulting value less than 0) happens here.\n// Warning 2661: (231-236): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 3046: (307-312): BMC: Division by zero happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/math_constructor.sol",
    "content": "contract C {\n\tuint z = 1;\n\tuint w = z - 3;\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4144: (36-41): BMC: Underflow (resulting value less than 0) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/msg_value_4.sol",
    "content": "contract A {\n    uint x = msg.value;\n    constructor() {\n        assert(x == 0); // should hold\n    }\n}\n\ncontract B {\n    constructor() payable {\n        assert(msg.value == 0); // should fail\n    }\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (154-176): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/range_check.sol",
    "content": "contract C {\n\tconstructor() payable {\n\t\tassert(tx.origin >= address(0));\n\t\tassert(tx.origin <= address(2**160 - 1));\n\t\tassert(tx.gasprice >= 0);\n\t\tassert(tx.gasprice <= 2**256 - 1);\n\t\tassert(msg.sender >= address(0));\n\t\tassert(msg.sender <= address(2**160 - 1));\n\t\tassert(msg.value >= 0);\n\t\tassert(msg.value <= 2**256 - 1);\n\n\t\tassert(block.coinbase >= address(0));\n\t\tassert(block.coinbase <= address(2**160 - 1));\n\t\tassert(block.timestamp >= 0);\n\t\tassert(block.timestamp <= 2**256 - 1);\n\t\tassert(block.chainid >= 0);\n\t\tassert(block.chainid <= 2**256 - 1);\n\t\tassert(block.difficulty >= 0);\n\t\tassert(block.difficulty <= 2**256 - 1);\n\t\tassert(block.prevrandao > 2**64);\n\t\tassert(block.prevrandao <= 2**256 - 1);\n\t\tassert(block.gaslimit >= 0);\n\t\tassert(block.gaslimit <= 2**256 - 1);\n\t\tassert(block.number >= 0);\n\t\tassert(block.number <= 2**256 - 1);\n\t}\n}\n\ncontract D {\n\tconstructor() payable {\n\t\tunchecked {\n\t\t\tassert(tx.origin >= address(0));\n\t\t\tassert(tx.origin <= address(2**160 - 1));\n\t\t\tassert(tx.gasprice >= 0);\n\t\t\tassert(tx.gasprice <= 2**256 - 1);\n\t\t\tassert(msg.sender >= address(0));\n\t\t\tassert(msg.sender <= address(2**160 - 1));\n\t\t\tassert(msg.value >= 0);\n\t\t\tassert(msg.value <= 2**256 - 1);\n\n\t\t\tassert(block.coinbase >= address(0));\n\t\t\tassert(block.coinbase <= address(2**160 - 1));\n\t\t\tassert(block.timestamp >= 0);\n\t\t\tassert(block.timestamp <= 2**256 - 1);\n\t\t\tassert(block.chainid >= 0);\n\t\t\tassert(block.chainid <= 2**256 - 1);\n\t\t\tassert(block.difficulty >= 0);\n\t\t\tassert(block.difficulty <= 2**256 - 1);\n\t\t\tassert(block.prevrandao > 2**64);\n\t\t\tassert(block.prevrandao <= 2**256 - 1);\n\t\t\tassert(block.gaslimit >= 0);\n\t\t\tassert(block.gaslimit <= 2**256 - 1);\n\t\t\tassert(block.number >= 0);\n\t\t\tassert(block.number <= 2**256 - 1);\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 8417: (565-581): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (598-614): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (1447-1463): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (1481-1497): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Info 6002: BMC: 44 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/staticcall_balance.sol",
    "content": "contract C {\n\tfunction f(address _a) public view {\n\t\tuint b1 = address(this).balance;\n\t\t_a.staticcall(\"\");\n\t\tuint b2 = address(this).balance;\n\t\tassert(b1 == b2); // should hold\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 9302: (88-105): Return value of low-level calls not used.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/staticcall_state_var.sol",
    "content": "contract C {\n\tuint x;\n\tfunction f(address _a) public {\n\t\tx = 2;\n\t\t_a.staticcall(\"\");\n\t\tassert(x == 2); // should hold\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 9302: (66-83): Return value of low-level calls not used.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/timestamp.sol",
    "content": "contract C {\n    function f() public view returns (uint) {\n        uint b = block.timestamp;\n        uint a = b + 0; // Overflow not possible!\n        return a;\n    }\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/try_multiple_catch_clauses_2.sol",
    "content": "contract C {\n\n\tfunction g() public pure {}\n\n\tfunction f() public view {\n\t\tuint x = 0;\n\t\tbool success = false;\n\t\ttry this.g() {\n\t\t\tsuccess = true;\n\t\t\tx = 1;\n\t\t} catch Error (string memory /*reason*/) {\n\t\t\tx = 2;\n\t\t} catch (bytes memory /*reason*/) {\n\t\t\tx = 3;\n\t\t}\n\t\tassert(x > 0 && x < 4); // should hold\n\t\tassert(x == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (306-320): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/try_multiple_returned_values_with_tuple.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t\tint y;\n\t}\n\n\tfunction g() public pure returns (bool b, S memory s) {\n\t\tb = true;\n\t\ts.x = 42;\n\t\ts.y = -1;\n\t}\n\n\tfunction f() public view {\n\t\tbool success = false;\n\t\ttry this.g() returns (bool b, S memory s) {\n\t\t\tsuccess = true;\n\t\t\tassert(b && s.x == 42 && s.y == -1); // should hold\n\t\t} catch {\n\t\t}\n\t\tassert(success); // fails, not guaranteed that there will be no error\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (336-351): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/unary_add_minus_overflow_detected.sol",
    "content": "contract C {\n\tuint8 x;\n\n\tfunction inc_pre() public {\n\t\t++x;\n\t}\n\n\tfunction dec_pre() public {\n\t\t--x;\n\t}\n\n\t/* Commented out because Spacer segfaults in Z3 4.8.9\n    function inc_post() public {\n\t\tx++;\n\t}\n\n\tfunction dec_post() public {\n\t\tx--;\n\t}\n    */\n\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 2661: (55-58): BMC: Overflow (resulting value larger than 255) happens here.\n// Warning 4144: (95-98): BMC: Underflow (resulting value less than 0) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bmc_coverage/unchecked_function_call_with_unchecked_block.sol",
    "content": "contract C {\n\tfunction f(uint x) internal pure {\n\t\tunchecked {\n\t\t\tuint y = x - 1;\n\t\t\tassert(y < x); // should fail, underflow can happen, we are inside unchecked block\n\t\t}\n\t}\n\tfunction g(uint x) public pure {\n\t\tunchecked { f(x); }\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (85-98): BMC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bytes_concat/equals.sol",
    "content": "contract C {\n\n\tfunction concatCall(bytes8 a) public pure returns (bytes memory) {\n\t\treturn bytes.concat(a, a);\n\t}\n\n\tfunction equalArguments1(bytes8 a, bytes8 b, bytes8 c, bytes8 d) public pure {\n\t\trequire(a == c);\n\t\trequire(b == d);\n\t\tbytes memory concat1 = bytes.concat(a, b);\n\t\tbytes memory concat2 = bytes.concat(c, d);\n\t\tassert(keccak256(concat1) == keccak256(concat2));\n\t}\n\n\tfunction equalArguments2(bytes8 a, bytes8 c) public pure {\n\t\trequire(a == c);\n\t\tbytes memory concat1 = bytes.concat(a, concatCall(a));\n\t\tbytes memory concat2 = bytes.concat(c, concatCall(c));\n\t\tassert(keccak256(concat1) == keccak256(concat2));\n\t}\n\n\tfunction equalLengthFixedBytes(bytes8 a, bytes8 b) public pure {\n\t\tbytes memory concat1 = bytes.concat(a, b);\n\t\tbytes memory concat2 = bytes.concat(a, b);\n\t\tassert(concat1.length == concat2.length);\n\t}\n\n\tfunction equalLengthMemoryBytes(bytes memory a, bytes memory b) public pure {\n\t\tbytes memory concat1 = bytes.concat(a, b);\n\t\tbytes memory concat2 = bytes.concat(a, b);\n\t\tassert(concat1.length == concat2.length);\n\t}\n\n\tfunction equalLengthMixed(bytes memory a, bytes2 b) public pure {\n\t\tbytes memory concat1 = bytes.concat(a, b);\n\t\tbytes memory concat2 = bytes.concat(a, b);\n\t\tassert(concat1.length == concat2.length);\n\t}\n\n\tfunction equalLengthLiterals() public pure {\n\t\tbytes memory a = hex\"aa\";\n\t\tbytes1 b = bytes1(0xbb);\n\t\tbytes memory c = \"c\";\n\t\tbytes memory concat1 = bytes.concat(a, b, c);\n\t\tbytes memory concat2 = bytes.concat(a, b, c);\n\t\tassert(concat1.length == concat2.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bytes_concat/one_arg_call.sol",
    "content": "contract C {\n\tfunction oneArg(bytes memory a) public pure {\n\t\tbytes memory concat = bytes.concat(a);\n\t\tassert(keccak256(a) == keccak256(concat));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/bytes_concat/simple.sol",
    "content": "contract C {\n\tfunction zeroArgs() public pure returns(bytes memory) {\n\t\tbytes memory a = bytes.concat();\n\t\tassert(a.length == 0); // zero args call is an empty bytes array\n\t\treturn bytes.concat();\n\t}\n\n\tfunction oneArg(bytes memory a) public pure returns(bytes memory) {\n\t\treturn bytes.concat(a);\n\t}\n\n\tfunction oneArgFixedBytes(bytes8 a) public pure returns(bytes memory) {\n\t\treturn bytes.concat(a);\n\t}\n\n\tfunction fixedBytes(bytes8 a, bytes8 b) public pure returns(bytes memory) {\n\t\treturn bytes.concat(a, b);\n\t}\n\n\tfunction memoryBytes(bytes memory a, bytes memory b) public pure returns(bytes memory) {\n\t\treturn bytes.concat(a, b);\n\t}\n\n\tfunction mixed(bytes memory a, bytes2 b) public pure returns(bytes memory) {\n\t\treturn bytes.concat(a, b, \"StringLiteral\");\n\t}\n\n\tfunction functionCallAsArg(bytes memory a) public pure returns(bytes memory) {\n\t\treturn bytes.concat(oneArg(a), zeroArgs());\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/complex/MerkleProof.sol",
    "content": "/**\n * @title MerkleProof\n * @dev Merkle proof verification based on\n * https://github.com/ameensol/merkle-tree-solidity/blob/master/src/MerkleProof.sol\n */\nlibrary MerkleProof {\n    /**\n     * @dev Verifies a Merkle proof proving the existence of a leaf in a Merkle tree. Assumes that each pair of leaves\n     * and each pair of pre-images are sorted.\n     * @param proof Merkle proof containing sibling hashes on the branch from the leaf to the root of the Merkle tree\n     * @param root Merkle root\n     * @param leaf Leaf of Merkle tree\n     */\n    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n        bytes32 computedHash = leaf;\n\n        for (uint256 i = 0; i < proof.length; i++) {\n            bytes32 proofElement = proof[i];\n\n            if (computedHash < proofElement) {\n                // Hash(current computed hash + current element of the proof)\n                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));\n            } else {\n                // Hash(current element of the proof + current computed hash)\n                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));\n            }\n        }\n\n        // Check if the computed hash (root) is equal to the provided root\n        return computedHash == root;\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/complex/slither/const_state_variables.sol",
    "content": "\ncontract A {\n\n    address constant public MY_ADDRESS = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9;\n    address public myFriendsAddress = 0xc0ffee254729296a45a3885639AC7E10F9d54979;\n\n    uint public used;\n    uint public test = 5;\n\n    uint constant X = 32**22 + 8;\n    string constant TEXT1 = \"abc\";\n    string text2 = \"xyz\";\n\n    function setUsed() public {\n        if (msg.sender == MY_ADDRESS) {\n            used = test;\n        }\n    }\n}\n\n\ncontract B is A {\n\n    address public mySistersAddress = 0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E;\n\n    fallback () external {\n        used = 0;\n    }\n\n    function setUsed(uint a) public {\n        if (msg.sender == MY_ADDRESS) {\n            used = a;\n        }\n    }\n}\n\ncontract MyConc{\n\n    uint constant A = 1;\n    bytes32 should_be_constant = sha256('abc');\n    uint should_be_constant_2 = A + 1;\n    address not_constant = msg.sender;\n    uint not_constant_2 = getNumber();\n    uint not_constant_3 = 10 + block.number;\n\n    function getNumber() public returns(uint){\n        return block.number;\n    }\n\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2519: (740-759): This declaration shadows an existing declaration.\n// Warning 2018: (976-1053): Function state mutability can be restricted to view\n// Warning 4984: (952-969): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/complex/slither/data_dependency.sol",
    "content": "contract Simple{\n\n    address destination;\n    address source;\n\n    function set(address source_taint) public{\n        destination = source_taint;\n    }\n\n    function set2() public{\n        destination = source;\n    }\n}\n\ncontract Reference{\n\n    struct St{\n        uint val;\n    }\n\n    St destination;\n    St source;\n    St destination_indirect_1;\n    St destination_indirect_2;\n\n    function set(uint source_taint) public{\n        destination.val = source_taint;\n    }\n\n    function set2() public{\n        destination.val = source.val;\n    }\n\n    function set3(uint source_taint) public{\n        St storage ref = destination_indirect_1;\n        if(true){\n            ref = destination_indirect_2;\n        }\n        ref.val = source_taint;\n    }\n}\n\ncontract SolidityVar{\n\n    address addr_1;\n    address addr_2;\n\n    constructor(){\n        addr_1 = msg.sender;\n    }\n\n}\n\ncontract Intermediate{\n\n    uint destination;\n    uint source_intermediate;\n    uint source;\n\n    function f() public{\n        destination = source_intermediate;\n    }\n    function f2() public{\n        source_intermediate = source;\n    }\n\n}\n\n\ncontract Base{\n\n    uint destination;\n    uint source_intermediate;\n    uint source;\n\n    function f() public{\n        destination = source_intermediate;\n    }\n}\ncontract Derived is Base{\n\n    function f2() public{\n        source_intermediate = source;\n    }\n\n\n}\n\n\ncontract PropagateThroughArguments {\n    uint var_tainted;\n    uint var_not_tainted;\n    uint var_dependant;\n\n    function f(uint user_input) public {\n        f2(user_input, 4);\n        var_dependant = var_tainted;\n    }\n\n    function f2(uint x, uint y) internal {\n        var_tainted = x;\n        var_not_tainted = y;\n    }\n}\n\ncontract PropagateThroughReturnValue {\n  uint var_dependant;\n  uint var_state;\n\n  function foo() public {\n    var_dependant = bar();\n  }\n\n  function bar() internal returns (uint) {\n    return (var_state);\n  }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2018: (1847-1915): Function state mutability can be restricted to view\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/complex/slither/external_function.sol",
    "content": "contract ContractWithFunctionCalled {\n    function funcCalled() external  {\n        uint256 i = 0;\n    }\n}\n\ncontract ContractWithFunctionCalledSuper is ContractWithFunctionCalled {\n    function callWithSuper() public {\n        uint256 i = 0;\n    }\n}\n\ncontract ContractWithFunctionNotCalled {\n\n    function funcNotCalled3() public {\n\n    }\n\n    function funcNotCalled2() public {\n\n    }\n\n    function funcNotCalled() public {\n\n    }\n\n    function my_func() internal returns(bool){\n        return true;\n    }\n\n}\n\ncontract ContractWithFunctionNotCalled2 is ContractWithFunctionCalledSuper {\n    function funcNotCalled() public {\n        uint256 i = 0;\n        address three = address(new ContractWithFunctionNotCalled());\n        three.call(abi.encode(bytes4(keccak256(\"helloTwo()\"))));\n        super.callWithSuper();\n        ContractWithFunctionCalled c = new ContractWithFunctionCalled();\n        c.funcCalled();\n    }\n}\n\ncontract InternalCall {\n\n    function() returns(uint) ptr;\n\n    function set_test1() external{\n        ptr = test1;\n    }\n\n    function set_test2() external{\n        ptr = test2;\n    }\n\n    function test1() public returns(uint){\n        return 1;\n    }\n\n    function test2() public returns(uint){\n        return 2;\n    }\n\n    function test3() public returns(uint){\n        return 3;\n    }\n\n    function exec() external returns(uint){\n        return ptr();\n    }\n\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9302: (727-782): Return value of low-level calls not used.\n// Warning 2072: (84-93): Unused local variable.\n// Warning 2072: (227-236): Unused local variable.\n// Warning 2072: (634-643): Unused local variable.\n// Warning 2018: (42-104): Function state mutability can be restricted to pure\n// Warning 2018: (185-247): Function state mutability can be restricted to pure\n// Warning 2018: (437-506): Function state mutability can be restricted to pure\n// Warning 2018: (1111-1173): Function state mutability can be restricted to pure\n// Warning 2018: (1179-1241): Function state mutability can be restricted to pure\n// Warning 2018: (1247-1309): Function state mutability can be restricted to pure\n// Warning 8729: (681-716): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n// Warning 8729: (854-886): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n// Warning 5729: (1370-1375): BMC does not yet implement this type of function call.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/complex/warn_on_typecast.sol",
    "content": "contract C {\n    function f() public pure returns (uint) {\n        return uint8(1);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/assignment_in_declaration.sol",
    "content": "contract C {\n    function f() public pure { uint a = 2; assert(a == 2); }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_assert_condition_1.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        if (x > 10) {\n            assert(x > 9);\n        }\n        else\n        {\n            assert(x < 11);\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_assert_condition_2.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        if (x > 10) {\n            assert(x > 9);\n        }\n        else if (x > 2)\n        {\n            assert(x <= 10 && x > 2);\n        }\n        else\n        {\n           assert(0 <= x && x <= 2);\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_1.sol",
    "content": "contract C {\n    uint x;\n    modifier m(uint z) {\n\t\tuint y = 3;\n        if (z == 10)\n            x = 2 + y;\n        _;\n        if (z == 10)\n            x = 4 + y;\n    }\n    function f() m(10) internal {\n        x = 3;\n    }\n    function g() public {\n        x = 0;\n        f();\n        assert(x == 7);\n        // Fails\n        assert(x == 6);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (327-341): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_2.sol",
    "content": "contract C {\n    uint x;\n    modifier m(uint z) {\n\t\tuint y = 3;\n        if (z == 10)\n            x = 2 + y;\n        _;\n        if (z == 10)\n            x = 4 + y;\n    }\n    function f() m(10) m(12) internal {\n        x = 3;\n    }\n    function g() public {\n        x = 0;\n        f();\n        assert(x == 3);\n        // Fails\n        assert(x == 6);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (333-347): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_3.sol",
    "content": "contract C {\n    uint x;\n    modifier m(uint z) {\n\t\tuint y = 3;\n        if (z == 10)\n            x = 2 + y;\n        _;\n        if (z == 10)\n            x = 4 + y;\n    }\n    function f() m(8) internal {\n        x = 3;\n    }\n    function g() public {\n        x = 0;\n        f();\n        assert(x == 3);\n        // Fails\n        assert(x == 6);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (326-340): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_inside_modifiers_4.sol",
    "content": "contract C {\n    uint x;\n    modifier m(uint z) {\n\t\tuint y = 3;\n        if (z >= 10)\n            x = 2 + y;\n        _;\n        if (z >= 10)\n            x = 4 + y;\n    }\n    function f() m(10) m(12) internal {\n        x = 3;\n    }\n    function g() public {\n        x = 0;\n        f();\n        assert(x == 7);\n        // Fails\n        assert(x == 6);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (333-347): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_1.sol",
    "content": "// Branch does not touch variable a\ncontract C {\n    function f(uint x) public pure {\n        uint a = 3;\n        if (x > 10) {\n        }\n        assert(a == 3);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_2.sol",
    "content": "// Positive branch touches variable a, but assertion should still hold.\ncontract C {\n    function f(uint x) public pure {\n        uint a = 3;\n        if (x > 10) {\n            a = 3;\n        }\n        assert(a == 3);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_3.sol",
    "content": "// Negative branch touches variable a, but assertion should still hold.\ncontract C {\n    function f(uint x) public pure {\n        uint a = 3;\n        if (x > 10) {\n        } else {\n            a = 3;\n        }\n        assert(a == 3);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_4.sol",
    "content": "// Variable is not merged, if it is only read.\ncontract C {\n    function f(uint x) public pure {\n        uint a = 3;\n        if (x > 10) {\n            assert(a == 3);\n        } else {\n            assert(a == 3);\n        }\n        assert(a == 3);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_5.sol",
    "content": "// Variable is reset in both branches\ncontract C {\n    function f(uint x) public pure {\n        uint a = 2;\n        if (x > 10) {\n            a = 3;\n        } else {\n            a = 3;\n        }\n        assert(a == 3);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_6.sol",
    "content": "// Variable is reset in both branches\ncontract C {\n    function f(uint x) public pure {\n        uint a = 2;\n        if (x > 10) {\n            a = 3;\n        } else {\n            a = 4;\n        }\n        assert(a >= 3);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers.sol",
    "content": "contract C {\n\n\tuint x;\n\n\tmodifier check() {\n\t\trequire(x == 0);\n\t\t_;\n\t\tassert(x == 1); // should fail;\n\t\tassert(x == 0); // should hold;\n\t}\n\n\tmodifier inc() {\n\t\tif (x == 0) {\n\t\t\treturn;\n\t\t}\n\t\tx = x + 1;\n\t\t_;\n\t}\n\n\tfunction test() check inc public {\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (70-84): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/branches_in_modifiers_2.sol",
    "content": "contract C {\n\n\tuint x;\n\n\tfunction reset_if_overflow() internal postinc {\n\t\tif (x < 10)\n\t\t\treturn;\n\t\tx = 0;\n\t}\n\n\tmodifier postinc() {\n\t\tif (x == 0) {\n\t\t\treturn;\n\t\t}\n\t\t_;\n\t\tx = x + 1;\n\t}\n\n\tfunction test() public {\n\t\tif (x == 0) {\n\t\t\treset_if_overflow();\n\t\t\tassert(x == 1); // should fail;\n\t\t\tassert(x == 0); // should hold;\n\t\t\treturn;\n\t\t}\n\t\tif (x < 10) {\n\t\t\tuint oldx = x;\n\t\t\treset_if_overflow();\n\t\t\t// Disabled because of nondeterminism in Spacer Z3 4.8.9\n\t\t\t//assert(oldx + 1 == x); // should hold;\n\t\t\tassert(oldx == x);     // should fail;\n\t\t\treturn;\n\t\t}\n\t\treset_if_overflow();\n\t\tassert(x == 1); // should hold;\n\t\tassert(x == 0); // should fail;\n\t}\n\n\tfunction set(uint _x) public {\n\t\tx = _x;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (255-269): CHC: Assertion violation happens here.\n// Warning 6328: (502-519): CHC: Assertion violation happens here.\n// Warning 6328: (615-629): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init.sol",
    "content": "contract A {\n\tint x;\n\tconstructor (int a) { x = a;}\n}\n\ncontract B is A {\n\tint y;\n\tconstructor(int a) A(-a) {\n\t\tif (a > 0) {\n\t\t\ty = 2;\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\ty = 3;\n\t\t}\n\t\ty = 4; // overwrites the else branch\n\t}\n}\n\ncontract C is B {\n\tconstructor(int a) B(a) {\n\t\tassert(y != 3); // should hold\n\t\tassert(y == 4); // should fail\n\t\tif (a > 0) {\n\t\t\tassert(x < 0 && y == 2); // should hold\n\t\t\tassert(x < 0 && y == 4); // should fail\n\t\t}\n\t\telse {\n\t\t\tassert(x >= 0 && y == 4); // should hold\n\t\t\tassert(x >= 0 && y == 2); // should fail\n\t\t\tassert(x > 0); // should fail\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (297-311): CHC: Assertion violation happens here.\n// Warning 6328: (389-412): CHC: Assertion violation happens here.\n// Warning 6328: (489-513): CHC: Assertion violation happens here.\n// Warning 6328: (533-546): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init_chain_alternate.sol",
    "content": "contract A {\n\tuint x = 1;\n}\n\ncontract B is A {\n\tconstructor(int a) {\n\t\tif (a > 0) {\n\t\t\tx = 2;\n\t\t\treturn;\n\t\t}\n\t\tx = 3;\n\t}\n}\n\nabstract contract C is B {\n}\n\ncontract D is C {\n\tconstructor(int a) B(a) {\n\t\tassert(a > 0 || x == 3); // should hold\n\t\tassert(a <= 0 || x == 2); // should hold\n\t\tassert(x == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (286-300): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructor_state_variable_init_diamond.sol",
    "content": "contract A {\n\tint x;\n}\n\ncontract B is A {\n\tint y;\n\tconstructor (int a) {\n\t\tif (a >= 0) {\n\t\t\ty = 1;\n\t\t\treturn;\n\t\t}\n\t\tx = 1;\n\t\ty = 2;\n\t}\n}\n\ncontract C is A {\n\tint z;\n\tconstructor (int a) {\n\t\tif (a >= 0) {\n\t\t\tz = 1;\n\t\t\treturn;\n\t\t}\n\t\tx = -1;\n\t\tz = 2;\n\t}\n}\n\ncontract D1 is B, C {\n\tconstructor() B(1) C(1) {\n\t\tassert(x == 0); // should hold\n\t\tassert(x == 1); // should fail\n\t\tassert(x == -1); // should fail\n\t}\n}\n\ncontract D2 is B, C {\n\tconstructor() B(1) C(-1) {\n\t\tassert(x == 0); // should fail\n\t\tassert(x == 1); // should fail\n\t\tassert(x == -1); // should hold (constructor of C is executed AFTER constructor of B)\n\t}\n}\n\ncontract D3 is B, C {\n\tconstructor() B(-1) C(1) {\n\t\tassert(x == 0); // should fail\n\t\tassert(x == 1); // should hold\n\t\tassert(x == -1); // should fail\n\t}\n}\n\ncontract D4 is B, C {\n\tconstructor() B(-1) C(-1) {\n\t\tassert(x == 0); // should fail\n\t\tassert(x == 1); // should fail\n\t\tassert(x == -1); // should hold (constructor of C is executed AFTER constructor of B)\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (337-351): CHC: Assertion violation happens here.\n// Warning 6328: (370-385): CHC: Assertion violation happens here.\n// Warning 6328: (460-474): CHC: Assertion violation happens here.\n// Warning 6328: (493-507): CHC: Assertion violation happens here.\n// Warning 6328: (670-684): CHC: Assertion violation happens here.\n// Warning 6328: (736-751): CHC: Assertion violation happens here.\n// Warning 6328: (827-841): CHC: Assertion violation happens here.\n// Warning 6328: (860-874): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/constructors.sol",
    "content": "contract B {\n\tint x;\n\tconstructor(int b) {\n\t\tif (b > 0) {\n\t\t\tx = 1;\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\tx = 2;\n\t\t\treturn;\n\t\t}\n\t\tx = 3; // dead code\n\t}\n}\n\ncontract C is B {\n\tconstructor(int a) B(a) {\n\t\tassert(a > 0 || x == 2); // should hold\n\t\tassert(a <= 0 || x == 1); // should hold\n\t\tassert(x == 3); // should fail\n\t\tassert(x == 2); // should fail\n\t\tassert(x == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5740: (119-124): Unreachable code.\n// Warning 6328: (277-291): CHC: Assertion violation happens here.\n// Warning 6328: (310-324): CHC: Assertion violation happens here.\n// Warning 6328: (343-357): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/nested_if.sol",
    "content": "contract C {\n\n\tfunction test(uint256 a, uint256 b) public pure {\n\t\tassert(nested_if(a,b) != 42); // should hold\n\t\tassert(nested_if(a,b) == 1);  // should fail\n\t}\n\n\tfunction nested_if(uint256 a, uint256 b) internal pure returns (uint256) {\n\t\tif (a < 5) {\n\t\t\tif (b > 1) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t\tif (a == 2 && b == 2) {\n\t\t\treturn 42; // unreachable\n\t\t}\n\t\telse {\n\t\t\treturn 1;\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (114-141): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (299-315): BMC: Condition is always false.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/return_in_both_branches.sol",
    "content": "contract C {\n\n\tfunction test() public pure {\n\t\tassert(branches(0) == 0);\n\t\tassert(branches(1) == 42);\n\t}\n\n\tfunction branches(uint256 a) internal pure returns (uint256) {\n\t\tif (a == 0) {\n\t\t\treturn 0;\n\t\t}\n\t\telse {\n\t\t\treturn 42;\n\t\t}\n\t\treturn 1; // dead code\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5740: (232-240): Unreachable code.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/simple_if.sol",
    "content": "contract C {\n\tfunction test(uint256 a, uint256 b) public pure returns (uint256) {\n\t\tif (a == 0) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn b / a; // This division is safe because of the early return in if-block.\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/simple_if2.sol",
    "content": "contract C {\n\n\tfunction test(uint256 a) public pure {\n\t\tassert(simple_if(a) == 1); // should fail for a == 0\n\t}\n\n\tfunction simple_if(uint256 a) internal pure returns (uint256) {\n\t\tif (a == 0) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn 1;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (56-81): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.test(0)\\n    C.simple_if(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/simple_if_array.sol",
    "content": "contract C {\n\n\tuint[] a;\n\n\tconstructor () {\n\t\ta.push();\n\t\ta.push();\n\t}\n\n\tfunction check() public {\n\t\trequire(a.length >= 2);\n\t\trequire(a[1] == 0);\n\t\tconditional_store();\n\t\tassert(a[1] == 1); // should fail;\n\t\tassert(a[1] == 0); // should hold;\n\t}\n\n\tfunction conditional_store() internal {\n\t\tif (a[1] == 0) {\n\t\t\treturn;\n\t\t}\n\t\ta[1] = 1;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (172-189): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/simple_if_state_var.sol",
    "content": "contract C {\n\n\tuint x;\n\n\tfunction check() public {\n\t\trequire(x == 0);\n\t\tconditional_increment();\n\t\tassert(x == 1); // should fail;\n\t\tassert(x == 0); // should hold;\n\t}\n\n\tfunction conditional_increment() internal {\n\t\tif (x == 0) {\n\t\t\treturn;\n\t\t}\n\t\tx = 1;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (99-113): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/simple_if_struct.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t}\n\tS s;\n\n\tfunction check() public {\n\t\trequire(s.x == 0);\n\t\tconditional_increment();\n\t\tassert(s.x == 1); // should fail;\n\t\tassert(s.x == 0); // should hold;\n\t}\n\n\tfunction conditional_increment() internal {\n\t\tif (s.x == 0) {\n\t\t\treturn;\n\t\t}\n\t\ts.x = 1;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (123-139): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/simple_if_struct_2.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t}\n\tS s;\n\n\tfunction check() public {\n\t\trequire(s.x == 0);\n\t\tconditional_increment();\n\t\tassert(s.x == 1); // should fail;\n\t\tassert(s.x == 0); // should hold;\n\t}\n\n\tfunction conditional_increment() internal {\n\t\tif (s.x == 0) {\n\t\t\treturn;\n\t\t}\n\t\ts = S(1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (123-139): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/simple_if_tuple.sol",
    "content": "contract C {\n\n\tuint x;\n\tuint y;\n\n\tfunction check() public {\n\t\trequire(x == 0);\n\t\trequire(y == 0);\n\t\tconditional_increment();\n\t\tassert(x == 0); // should fail;\n\t\tassert(x == 1); // should fail;\n\t\tassert(x == 2); // should hold;\n\t}\n\n\tfunction conditional_increment() internal {\n\t\tif (x == 0) {\n\t\t\t(x,y) = (2,2);\n\t\t\treturn;\n\t\t}\n\t\t(x,y) = (1,1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (127-141): CHC: Assertion violation happens here.\n// Warning 6328: (161-175): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/branches_with_return/triple_nested_if.sol",
    "content": "contract C {\n\n    uint a;\n    uint b;\n    uint c;\n\n\tfunction test() public view {\n\t\tif (a == 0) {\n\t\t\tif (b == 0) {\n\t\t\t\tif (c == 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tassert(a != 0 || b != 0 || c != 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/function_call_inside_branch.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tif (true) {\n\t\t\taddress a = g();\n\t\t\tassert(a == address(0));\n\t\t}\n\t}\n\tfunction g() public pure returns (address) {\n\t\taddress a;\n\t\ta = address(0);\n\t\treturn a;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/function_call_inside_branch_2.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tif (true) {\n\t\t\taddress a = g();\n\t\t\tassert(a == address(0));\n\t\t}\n\t\telse\n\t\t{\n\t\t\taddress b = g();\n\t\t\tassert(b == address(0));\n\t\t}\n\t}\n\tfunction g() public pure returns (address) {\n\t\taddress a;\n\t\ta = address(0);\n\t\treturn a;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/function_call_inside_branch_3.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tif (true) {\n\t\t\taddress a = g();\n\t\t\tassert(a == address(0));\n\t\t}\n\t\tif (true) {\n\t\t\taddress a = g();\n\t\t\tassert(a == address(0));\n\t\t}\n\n\t}\n\tfunction g() public pure returns (address) {\n\t\taddress a;\n\t\ta = address(0);\n\t\treturn a;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/function_call_inside_branch_4.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tif (true) {\n\t\t\taddress a = g();\n\t\t\tassert(a == address(0));\n\t\t}\n\t\tif (true) {\n\t\t\taddress a = h();\n\t\t\tassert(a == address(0));\n\t\t}\n\n\t}\n\tfunction g() public pure returns (address) {\n\t\taddress a;\n\t\ta = address(0);\n\t\treturn a;\n\t}\n\tfunction h() public pure returns (address) {\n\t\taddress a;\n\t\treturn a;\n\t}\n\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/function_call_inside_else_branch.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tif (true) {\n\t\t} else {\n\t\t\taddress a = g();\n\t\t\tassert(a == address(0));\n\t\t}\n\t}\n\tfunction g() public pure returns (address) {\n\t\taddress x;\n\t\tx = address(0);\n\t\treturn x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/function_call_inside_modifier_branch.sol",
    "content": "contract C\n{\n\tmodifier m(address a) {\n\t\tif (true) {\n\t\t\ta = g();\n\t\t\t_;\n\t\t\tassert(a == address(0));\n\t\t}\n\t}\n\n\tfunction f(address a) m(a) public pure {\n\t}\n\tfunction g() public pure returns (address) {\n\t\taddress a;\n\t\ta = address(0);\n\t\treturn a;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/function_call_inside_placeholder_inside_modifier_branch.sol",
    "content": "contract C\n{\n\tmodifier m {\n\t\tif (true)\n\t\t\t_;\n\t}\n\n\tfunction f(address a) m public pure {\n\t\tif (true) {\n\t\t\ta = g();\n\t\t\tassert(a == address(0));\n\t\t}\n\t}\n\tfunction g() public pure returns (address) {\n\t\taddress a;\n\t\ta = address(0);\n\t\treturn a;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/require.sol",
    "content": "contract C {\n\tfunction f() pure public {\n\t\trequire(false);\n\t\t// This is not reachable.\n\t\tassert(false);\n\t}\n\n\tfunction g() pure public {\n\t\trequire(false, \"require message\");\n\t\t// This is not reachable.\n\t\tassert(false);\n\t}\n\n\tfunction h(bool b) pure public {\n\t\tif (b)\n\t\t\trequire(false);\n\t\tassert(!b);\n\t}\n\n\t// Check that arguments are evaluated.\n\tbool x = false;\n\tfunction m() view internal returns (string memory) {\n\t\tassert(x != true);\n\t}\n\tfunction i() public {\n\t\tx = true;\n\t\trequire(false, m());\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (396-409): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6328: (415-432): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/return_1.sol",
    "content": "contract C {\n\tfunction add(uint x, uint y) internal pure returns (uint) {\n\t\tif (y == 0)\n\t\t\treturn x;\n\t\tif (y == 1)\n\t\t\treturn ++x;\n\t\tif (y == 2)\n\t\t\treturn x + 2;\n\t\treturn x + y;\n\t}\n\n\tfunction f() public pure {\n\t\tassert(add(100, 0) == 100);\n\t\tassert(add(100, 1) == 101);\n\t\tassert(add(100, 2) == 102);\n\t\tassert(add(100, 100) == 200);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/return_1_fail.sol",
    "content": "contract C {\n\tfunction add(uint x, uint y) internal pure returns (uint) {\n\t\tif (y == 0)\n\t\t\treturn x;\n\t\tif (y == 1)\n\t\t\treturn ++x;\n\t\tif (y == 2)\n\t\t\treturn x + 2;\n\t\treturn x + y;\n\t}\n\n\tfunction f() public pure {\n\t\tassert(add(100, 0) != 100);\n\t\tassert(add(100, 1) != 101);\n\t\tassert(add(100, 2) != 102);\n\t\tassert(add(100, 100) != 200);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (211-237): CHC: Assertion violation happens here.\n// Warning 6328: (241-267): CHC: Assertion violation happens here.\n// Warning 6328: (271-297): CHC: Assertion violation happens here.\n// Warning 6328: (301-329): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/return_2.sol",
    "content": "contract C {\n\tuint c;\n\tfunction add(uint x, uint y) internal returns (uint) {\n\t\tc = 0xff;\n\t\tif (y == 0)\n\t\t\treturn x;\n\t\tc = 0xffff;\n\t\tif (y == 1)\n\t\t\treturn ++x;\n\t\tc = 0xffffff;\n\t\tif (y == 2)\n\t\t\treturn x + 2;\n\t\tc = 0xffffffff;\n\t\treturn x + y;\n\t}\n\n\tfunction f() public {\n\t\tassert(add(100, 0) == 100);\n\t\tassert(c == 0xff);\n\t\tassert(add(100, 1) == 101);\n\t\tassert(c == 0xffff);\n\t\tassert(add(100, 2) == 102);\n\t\tassert(c == 0xffffff);\n\t\tassert(add(100, 100) == 200);\n\t\tassert(c == 0xffffffff);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 11 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/return_2_fail.sol",
    "content": "contract C {\n\tuint c;\n\tfunction add(uint x, uint y) internal returns (uint) {\n\t\tc = 0xff;\n\t\tif (y == 0)\n\t\t\treturn x;\n\t\tc = 0xffff;\n\t\tif (y == 1)\n\t\t\treturn ++x;\n\t\tc = 0xffffff;\n\t\tif (y == 2)\n\t\t\treturn x + 2;\n\t\tc = 0xffffffff;\n\t\treturn x + y;\n\t}\n\n\tfunction f() public {\n\t\tassert(add(100, 0) != 100);\n\t\tassert(c != 0xff);\n\t\tassert(add(100, 1) != 101);\n\t\tassert(c != 0xffff);\n\t\tassert(add(100, 2) != 102);\n\t\tassert(c != 0xffffff);\n\t\tassert(add(100, 100) != 200);\n\t\tassert(c != 0xffffffff);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (270-296): CHC: Assertion violation happens here.\n// Warning 6328: (300-317): CHC: Assertion violation happens here.\n// Warning 6328: (321-347): CHC: Assertion violation happens here.\n// Warning 6328: (351-370): CHC: Assertion violation happens here.\n// Warning 6328: (374-400): CHC: Assertion violation happens here.\n// Warning 6328: (404-425): CHC: Assertion violation happens here.\n// Warning 6328: (429-457): CHC: Assertion violation happens here.\n// Warning 6328: (461-484): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/revert.sol",
    "content": "contract C {\n\tfunction f() pure public {\n\t\trevert();\n\t\t// This is not reachable.\n\t\tassert(false);\n\t}\n\n\tfunction g() pure public {\n\t\trevert(\"revert message\");\n\t\t// This is not reachable.\n\t\tassert(false);\n\t}\n\n\tfunction h(bool b) pure public {\n\t\tif (b)\n\t\t\trevert();\n\t\tassert(!b);\n\t}\n\n\t// Check that arguments are evaluated.\n\tbool x = false;\n\tfunction m() view internal returns (string memory) {\n\t\tassert(x != true);\n\t}\n\tfunction i() public {\n\t\tx = true;\n\t\trevert(m());\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5740: (83-96): Unreachable code.\n// Warning 5740: (188-201): Unreachable code.\n// Warning 6321: (375-388): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6328: (394-411): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/revert_complex_flow.sol",
    "content": "contract C {\n\tfunction f(bool b, uint a) pure public {\n\t\trequire(a <= 256);\n\t\tif (b)\n\t\t\trevert();\n\t\tuint c = a + 1;\n\t\tif (b)\n\t\t\tc--;\n\t\telse\n\t\t\tc++;\n\t\tassert(c == a);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (150-164): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (122-123): BMC: Condition is always false.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_and.sol",
    "content": "contract c {\n\tuint x;\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\tfunction g() public returns (bool) {\n\t\tx = 0;\n\t\tbool b = (f() == 0) && (f() == 0);\n\t\tassert(x == 1);\n\t\tassert(!b);\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_and_fail.sol",
    "content": "contract c {\n\tuint x;\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\tfunction g() public returns (bool) {\n\t\tx = 0;\n\t\tbool b = (f() == 0) && (f() == 0);\n\t\tassert(x == 1);\n\t\tassert(b);\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (194-203): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1\\n = false\\nb = false\\n\\nTransaction trace:\\nc.constructor()\\nState: x = 0\\nc.g()\\n    c.f() -- internal call\\n    c.f() -- internal call\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_and_inside_branch.sol",
    "content": "contract c {\n\tuint x;\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\tfunction g() public returns (bool) {\n\t\tbool b;\n\t\t\tx = 100;\n\t\t\tb = f() > 0;\n\t\t\tassert(x == 102);\n\t\t\t// Should fail.\n\t\t\tassert(!b);\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (169-185): CHC: Assertion violation happens here.\n// Warning 6328: (209-219): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_and_need_both.sol",
    "content": "contract c {\n\tuint x;\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\tfunction g() public returns (bool) {\n\t\tx = 0;\n\t\tbool b = (f() > 0) && (f() > 0);\n\t\tassert(x == 2);\n\t\tassert(b);\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_and_need_both_fail.sol",
    "content": "contract c {\n\tuint x;\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\tfunction g() public returns (bool) {\n\t\tx = 0;\n\t\tbool b = (f() > 0) && (f() > 0);\n\t\tassert(x == 2);\n\t\tassert(!b);\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (192-202): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n = false\\nb = true\\n\\nTransaction trace:\\nc.constructor()\\nState: x = 0\\nc.g()\\n    c.f() -- internal call\\n    c.f() -- internal call\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_and_touched.sol",
    "content": "contract C\n{\n\tbool b;\n\tfunction f() public {\n\t\tif ((b = false) && (b == true)) {}\n\t\tif ((b == false) && (b = true)) {}\n\t\tif ((b = false) && (b = true)) {}\n\t\tif ((b == false) && (b == true)) {}\n\t\tif ((b = true) && b) {}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (51-77): BMC: Condition is always false.\n// Warning 6838: (88-114): BMC: Condition is always true.\n// Warning 6838: (125-150): BMC: Condition is always false.\n// Warning 6838: (161-188): BMC: Condition is always false.\n// Warning 6838: (199-214): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_and_touched_function.sol",
    "content": "contract C\n{\n\tbool b;\n\tfunction g(bool _b) internal returns (bool) {\n\t\tb = _b;\n\t\treturn b;\n\t}\n\tfunction f() public {\n\t\tif (g(false) && (b == true)) {}\n\t\tif ((b == false) && g(true)) {}\n\t\tif (g(false) && g(true)) {}\n\t\tif (g(false) && (b == true)) {}\n\t\tif (g(true) && b) {}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (123-146): BMC: Condition is always false.\n// Warning 6838: (157-180): BMC: Condition is always true.\n// Warning 6838: (191-210): BMC: Condition is always false.\n// Warning 6838: (221-244): BMC: Condition is always false.\n// Warning 6838: (255-267): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_or.sol",
    "content": "contract c {\n\tuint x;\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\tfunction g() public returns (bool) {\n\t\tx = 0;\n\t\tbool b = (f() > 0) || (f() > 0);\n\t\tassert(x == 1);\n\t\tassert(b);\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_or_fail.sol",
    "content": "contract c {\n\tuint x;\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\tfunction g() public returns (bool) {\n\t\tx = 0;\n\t\tbool b = (f() > 0) || (f() > 0);\n\t\tassert(x == 1);\n\t\tassert(!b);\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (192-202): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1\\n = false\\nb = true\\n\\nTransaction trace:\\nc.constructor()\\nState: x = 0\\nc.g()\\n    c.f() -- internal call\\n    c.f() -- internal call\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_or_inside_branch.sol",
    "content": "contract c {\n\tuint x;\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\tfunction g(bool a) public returns (bool) {\n\t\tbool b;\n\t\tif (a) {\n\t\t\tx = 0;\n\t\t\tb = (f() > 0) || (f() > 0);\n\t\t\tassert(x == 1);\n\t\t\tassert(b);\n\t\t} else {\n\t\t\tx = 100;\n\t\t\tb = (f() == 0) || (f() > 0);\n\t\t\tassert(x == 102);\n\t\t\t// Should fail.\n\t\t\tassert(!b);\n\t\t}\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (327-337): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_or_need_both.sol",
    "content": "contract c {\n\tuint x;\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\tfunction g() public returns (bool) {\n\t\tx = 0;\n\t\tbool b = (f() > 1) || (f() > 1);\n\t\tassert(x == 2);\n\t\tassert(b);\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_or_need_both_fail.sol",
    "content": "contract c {\n\tuint x;\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\tfunction g() public returns (bool) {\n\t\tx = 0;\n\t\tbool b = (f() > 1) || (f() > 1);\n\t\tassert(x == 2);\n\t\tassert(!b);\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (192-202): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n = false\\nb = true\\n\\nTransaction trace:\\nc.constructor()\\nState: x = 0\\nc.g()\\n    c.f() -- internal call\\n    c.f() -- internal call\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_or_touched.sol",
    "content": "contract C\n{\n\tbool b;\n\tfunction f() public {\n\t\tif ((b = true) || (b == false)) {}\n\t\tif ((b == true) || (b = false)) {}\n\t\tif ((b = true) || (b = false)) {}\n\t\tif ((b == true) || (b == false)) {}\n\t\tif ((b = false) || b) {}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (51-77): BMC: Condition is always true.\n// Warning 6838: (88-114): BMC: Condition is always true.\n// Warning 6838: (125-150): BMC: Condition is always true.\n// Warning 6838: (161-188): BMC: Condition is always true.\n// Warning 6838: (199-215): BMC: Condition is always false.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/short_circuit_or_touched_function.sol",
    "content": "contract C\n{\n\tbool b;\n\tfunction g(bool _b) internal returns (bool) {\n\t\tb = _b;\n\t\treturn b;\n\t}\n\tfunction f() public {\n\t\tif (g(true) || (b == false)) {}\n\t\tif ((b == true) || g(false)) {}\n\t\tif (g(true) || g(false)) {}\n\t\tif (g(true) || (b == false)) {}\n\t\tif (g(false) || b) {}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (123-146): BMC: Condition is always true.\n// Warning 6838: (157-180): BMC: Condition is always true.\n// Warning 6838: (191-210): BMC: Condition is always true.\n// Warning 6838: (221-244): BMC: Condition is always true.\n// Warning 6838: (255-268): BMC: Condition is always false.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/side_effects_inside_if_1.sol",
    "content": "contract C {\n    function f() public pure {\n        uint x;\n        if (++x < 3) {}\n\n        assert(x == 1); // should hold\n        assert(x != 1); // should fail\n    }\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 6838: (72-79): BMC: Condition is always true.\n// Warning 4661: (132-146): BMC: Assertion violation happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/side_effects_inside_if_2.sol",
    "content": "contract C {\n    uint x;\n\n    function inc() internal returns (uint) {\n        // BMC inlines function calls and also looks at functions in isolation,\n        // therefore it says once that this is safe, when called by `f`,\n        // but also that it is unsafe just looking at this function (false positive).\n        ++x;\n        return x;\n    }\n\n    function f() public {\n        require(x < 1000);\n        uint y = x;\n        if (inc() < 3) {}\n\n        assert(x == y + 1); // should hold\n        assert(x != y + 1); // should fail\n    }\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 2661: (318-321): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4661: (499-517): BMC: Assertion violation happens here.\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/side_effects_inside_if_3.sol",
    "content": "contract C {\n    uint x;\n\n    function inc() internal returns (uint) {\n        // BMC inlines function calls and also looks at functions in isolation,\n        // therefore it says once that this is safe, when called by `f`,\n        // but also that it is unsafe just looking at this function (false positive).\n        ++x;\n        return x;\n    }\n\n    function inc2() internal returns (uint) {\n        return inc();\n    }\n\n    function f() public {\n        require(x < 1000);\n        uint y = x;\n        if (inc2() < 3) {}\n\n        assert(x == y + 1); // should hold\n        assert(x != y + 1); // should fail\n    }\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 2661: (318-321): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4661: (575-593): BMC: Assertion violation happens here.\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/side_effects_inside_if_4.sol",
    "content": "contract C {\n    function f() public pure {\n        uint x = 2;\n        if (--x < 3) {}\n\n        assert(x == 1); // should hold\n        assert(x != 1); // should fail\n    }\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 6838: (76-83): BMC: Condition is always true.\n// Warning 4661: (136-150): BMC: Assertion violation happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/side_effects_inside_ternary_1.sol",
    "content": "contract C {\n    function f() public pure {\n        uint x;\n        uint y = (++x < 3) ? ++x : --x;\n\n        assert(y == x); // should hold;\n        assert(x == 2); // should hold\n        assert(x != 2); // should fail\n    }\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 6838: (77-86): BMC: Condition is always true.\n// Warning 4661: (188-202): BMC: Assertion violation happens here.\n// Info 6002: BMC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/side_effects_inside_ternary_2.sol",
    "content": "contract C {\n    uint x;\n\n    function inc() internal returns (uint) {\n        // BMC inlines function calls and also looks at functions in isolation,\n        // therefore it says once that this is safe, when called by `f`,\n        // but also that it is unsafe just looking at this function (false positive).\n        ++x;\n        return x;\n    }\n\n    function f() public {\n        require(x < 1000);\n        uint z = x;\n        uint y = (inc() < 3) ? inc() : inc();\n\n        assert(y == x);\n        assert(x == z + 2); // should hold\n        assert(x != z + 2); // should fail\n    }\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 2661: (318-321): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4661: (543-561): BMC: Assertion violation happens here.\n// Info 6002: BMC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/side_effects_inside_ternary_3.sol",
    "content": "contract C {\n    uint x;\n\n    function inc() internal returns (uint) {\n        // BMC inlines function calls and also looks at functions in isolation,\n        // therefore it says once that this is safe, when called by `f`,\n        // but also that it is unsafe just looking at this function (false positive).\n        ++x;\n        return x;\n    }\n\n    function inc2() internal returns (uint) {\n        return inc();\n    }\n\n    function f() public {\n        require(x < 1000);\n        uint z = x;\n        uint y = (inc2() < 3) ? inc2() : inc2();\n\n        assert(y == x); // should hold\n        assert(x == z + 2); // should hold\n        assert(x != z + 2); // should fail\n    }\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 2661: (318-321): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4661: (636-654): BMC: Assertion violation happens here.\n// Info 6002: BMC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/side_effects_inside_ternary_4.sol",
    "content": "contract C {\n    function f() public pure {\n        uint x = 2;\n        uint y = (--x < 3) ? --x : 0;\n\n        assert(y == x); // should hold\n        assert(x == 0); // should hold\n        assert(x != 0); // should fail\n    }\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 6838: (81-90): BMC: Condition is always true.\n// Warning 4661: (189-203): BMC: Assertion violation happens here.\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/try_catch_1.sol",
    "content": "contract C {\n\tfunction g() public returns (uint) {\n\t\ttry this.g() returns (uint x) { x; }\n\t\tcatch Error(string memory s) { s; }\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// SMTEngine: all\n// ----\n// Warning 6321: (43-47): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/try_catch_2.sol",
    "content": "contract C {\n\tfunction f() public {\n\t\ttry this.f() {}\n\t\tcatch (bytes memory x) {\n\t\t\tx;\n\t\t}\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/virtual_function_call_inside_branch_1.sol",
    "content": "contract Context {}\n\ncontract ERC20 is Context {\n    function approve() public virtual { _approve(); }\n    function _approve() internal virtual {}\n}\n\ncontract __unstable__ERC20Owned is ERC20 {\n    function _approve() internal override {\n        if (true) {\n            super._approve();\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/virtual_function_call_inside_branch_2.sol",
    "content": "contract A {\n    function f() internal virtual {\n        v();\n    }\n    function v() internal virtual {\n    }\n}\n\ncontract B is A {\n    function f() internal virtual override {\n        super.f();\n    }\n}\n\ncontract C is B {\n    function v() internal override {\n        if (0==1)\n            f();\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (271-275): BMC: Condition is always false.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_1.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        uint a = 3;\n        if (x > 10) {\n            a++;\n        }\n        assert(a == 3);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (127-141): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_2.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        uint a = 3;\n        if (x > 10) {\n            ++a;\n        }\n        assert(a == 3);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (127-141): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_3.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        uint a = 3;\n        if (x > 10) {\n            a = 5;\n        }\n        assert(a == 3);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (129-143): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 11\\na = 5\\n\\nTransaction trace:\\nC.constructor()\\nC.f(11)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/crypto/crypto_functions_compare_hashes.sol",
    "content": "contract C {\n\tfunction f(bytes memory data) public pure {\n\t\tbytes32 k = keccak256(data);\n\t\tbytes32 s = sha256(data);\n\t\tbytes32 r = ripemd160(data);\n\t\tassert(k == s);\n\t\tassert(s == r);\n\t\tassert(r == k);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (150-164): CHC: Assertion violation happens here.\n// Warning 6328: (168-182): CHC: Assertion violation happens here.\n// Warning 6328: (186-200): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/crypto/crypto_functions_fail.sol",
    "content": "contract C {\n\tfunction k(bytes memory b0, bytes memory b1) public pure {\n\t\tbytes32 k0 = keccak256(b0);\n\t\tbytes32 k1 = keccak256(b1);\n\t\tassert(k0 == k1);\n\t}\n\tfunction s(bytes memory b0, bytes memory b1) public pure {\n\t\tbytes32 s0 = sha256(b0);\n\t\tbytes32 s1 = sha256(b1);\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//assert(s0 == s1);\n\t}\n\tfunction r(bytes memory b0, bytes memory b1) public pure {\n\t\tbytes32 r0 = ripemd160(b0);\n\t\tbytes32 r1 = ripemd160(b1);\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//assert(r0 == r1);\n\t}\n\tfunction e(bytes32 h0, uint8 v0, bytes32 r0, bytes32 s0, bytes32 h1, uint8 v1, bytes32 r1, bytes32 s1) public pure {\n\t\taddress a0 = ecrecover(h0, v0, r0, s0);\n\t\taddress a1 = ecrecover(h1, v1, r1, s1);\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//assert(a0 == a1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (218-228): Unused local variable.\n// Warning 2072: (245-255): Unused local variable.\n// Warning 2072: (405-415): Unused local variable.\n// Warning 2072: (435-445): Unused local variable.\n// Warning 2072: (656-666): Unused local variable.\n// Warning 2072: (698-708): Unused local variable.\n// Warning 6328: (135-151): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/crypto/crypto_functions_not_same.sol",
    "content": "contract C {\n\tfunction f(bytes memory data) public pure {\n\t\tbytes32 k = keccak256(data);\n\t\tfi(data, k);\n\t}\n\tfunction fi(bytes memory data, bytes32 k) internal pure {\n\t\tbytes32 h = sha256(data);\n\t\tassert(h == k);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (196-210): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/crypto/crypto_functions_over_blocks.sol",
    "content": "contract C {\n\tfunction f(bytes memory data) public pure {\n\t\tbytes32 k = keccak256(data);\n\t\tfi(data, k);\n\t}\n\tfunction fi(bytes memory data, bytes32 k) internal pure {\n\t\tbytes32 h = keccak256(data);\n\t\tassert(h == k);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_array.sol",
    "content": "contract C {\n\tfunction c1() public pure {\n\t\tbytes32 k1 = keccak256(abi.encode([1]));\n\t\tbytes32 k2 = keccak256(abi.encode([1]));\n\t\tassert(k1 == k2);\n\t}\n\n        function c2() public pure {\n\t\tbytes32 s1 = sha256(abi.encode([1,2]));\n\t\tbytes32 s2 = sha256(abi.encode([1,2]));\n\t\tassert(s1 == s2);\n\t}\n\n        function c3() public pure {\n\t\tbytes32 r1 = ripemd160(abi.encode([1,2,3]));\n\t\tbytes32 r2 = ripemd160(abi.encode([1,2,3]));\n\t\tassert(r1 == r2);\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_input_over_state_same_output.sol",
    "content": "contract C {\n\tbytes data;\n\tbytes32 h;\n\tuint8 v;\n\tbytes32 r;\n\tbytes32 s;\n\n\tbytes32 kec;\n\tbytes32 sha;\n\tbytes32 rip;\n\taddress erc;\n\n\tconstructor(bytes memory _data, bytes32 _h, uint8 _v, bytes32 _r, bytes32 _s) {\n\t\tdata = _data;\n\t\th = _h;\n\t\tv = _v;\n\t\tr = _r;\n\t\ts = _s;\n\n\t\tkec = keccak256(data);\n\t\tsha = sha256(data);\n\t\trip = ripemd160(data);\n\t\terc = ecrecover(h, v, r, s);\n\t}\n\n\tfunction f() public view {\n\t\tbytes32 _kec = keccak256(data);\n\t\tbytes32 _sha = sha256(data);\n\t\tbytes32 _rip = ripemd160(data);\n\t\taddress _erc = ecrecover(h, v, r, s);\n\t\tassert(_kec == kec);\n\t\tassert(_sha == sha);\n\t\tassert(_rip == rip);\n\t\tassert(_erc == erc);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_input_over_state_same_output_fail.sol",
    "content": "contract C {\n\tbytes data;\n\tbytes32 h;\n\tuint8 v;\n\tbytes32 r;\n\tbytes32 s;\n\n\tbytes32 kec;\n\tbytes32 sha;\n\tbytes32 rip;\n\taddress erc;\n\n\tconstructor(bytes memory _data, bytes32 _h, uint8 _v, bytes32 _r, bytes32 _s) {\n\t\tdata = _data;\n\t\th = _h;\n\t\tv = _v;\n\t\tr = _r;\n\t\ts = _s;\n\n\t\tkec = keccak256(data);\n\t\tsha = sha256(data);\n\t\trip = ripemd160(data);\n\t\terc = ecrecover(h, v, r, s);\n\t}\n\n\tfunction set(bytes memory _data, bytes32 _h, uint8 _v, bytes32 _r, bytes32 _s) public {\n\t\tdata = _data;\n\t\th = _h;\n\t\tv = _v;\n\t\tr = _r;\n\t\ts = _s;\n\t}\n\n\tfunction f() public view {\n\t\tbytes32 _kec = keccak256(data);\n\t\tbytes32 _sha = sha256(data);\n\t\tbytes32 _rip = ripemd160(data);\n\t\taddress _erc = ecrecover(h, v, r, s);\n\t\tassert(_kec == kec);\n\t\tassert(_sha == sha);\n\t\tassert(_rip == rip);\n\t\tassert(_erc == erc);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (693-712): CHC: Assertion violation happens here.\\nCounterexample:\\nh = 0x0, v = 0, r = 0x0, s = 0x0, kec = 0x52f7, sha = 0x0, rip = 0x0, erc = 0x0\\n_kec = 0x52f6\\n_sha = 0x2e15\\n_rip = 0x2297\\n_erc = 0x0985\\n\\nTransaction trace:\\nC.constructor(_data, 0x23c6, 198, 0x1599, 0x1980)\\nState: h = 0x23c6, v = 198, r = 0x1599, s = 0x1980, kec = 0x52f7, sha = 0x0, rip = 0x0, erc = 0x0\\nC.set(_data, 0x0, 0, 0x0, 0x0)\\nState: h = 0x0, v = 0, r = 0x0, s = 0x0, kec = 0x52f7, sha = 0x0, rip = 0x0, erc = 0x0\\nC.f()\n// Warning 6328: (716-735): CHC: Assertion violation happens here.\\nCounterexample:\\nh = 0x0, v = 0, r = 0x0, s = 0x0, kec = 0x0986, sha = 0x0, rip = 0x0, erc = 0x0\\n_kec = 0x0985\\n_sha = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd68\\n_rip = 0x20ad\\n_erc = 0x2e15\\n\\nTransaction trace:\\nC.constructor([0x19, 0x19, 0x19, 0x19, 0x19, 0x38, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x2b, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x36, 0x19, 0x19, 0x39, 0x19, 0x3b, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19], 0x1169, 88, 0x0a12, 0x1599)\\nState: data = [0x19, 0x19, 0x19, 0x19, 0x19, 0x38, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x2b, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x36, 0x19, 0x19, 0x39, 0x19, 0x3b, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19], h = 0x1169, v = 88, r = 0x0a12, s = 0x1599, kec = 0x0986, sha = 0x0, rip = 0x0, erc = 0x0\\nC.set(_data, 0x0, 0, 0x0, 0x0)\\nState: h = 0x0, v = 0, r = 0x0, s = 0x0, kec = 0x0986, sha = 0x0, rip = 0x0, erc = 0x0\\nC.f()\n// Warning 6328: (739-758): CHC: Assertion violation happens here.\n// Warning 6328: (762-781): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_input_same_output.sol",
    "content": "contract C {\n\tfunction k(bytes memory b0) public pure {\n\t\tbytes memory b1 = b0;\n\t\tbytes32 k0 = keccak256(b0);\n\t\tbytes32 k1 = keccak256(b1);\n\t\tassert(k0 == k1);\n\t}\n\tfunction s(bytes memory b0) public pure {\n\t\tbytes memory b1 = b0;\n\t\tbytes32 s0 = sha256(b0);\n\t\tbytes32 s1 = sha256(b1);\n\t\tassert(s0 == s1);\n\t}\n\tfunction r(bytes memory b0) public pure {\n\t\tbytes memory b1 = b0;\n\t\tbytes32 r0 = ripemd160(b0);\n\t\tbytes32 r1 = ripemd160(b1);\n\t\tassert(r0 == r1);\n\t}\n\tfunction e(bytes32 h0, uint8 v0, bytes32 r0, bytes32 s0) public pure {\n\t\t(bytes32 h1, uint8 v1, bytes32 r1, bytes32 s1) = (h0, v0, r0, s0);\n\t\taddress a0 = ecrecover(h0, v0, r0, s0);\n\t\taddress a1 = ecrecover(h1, v1, r1, s1);\n\t\tassert(a0 == a1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/crypto/crypto_functions_same_string_literal.sol",
    "content": "contract C {\n\tfunction c1() public pure {\n\t\tbytes32 k1 = keccak256(\"1\");\n\t\tbytes32 k2 = keccak256(\"1\");\n\t\tassert(k1 == k2);\n\t}\n\n\tfunction c2() public pure {\n\t\tbytes32 s1 = sha256(\"10\");\n\t\tbytes32 s2 = sha256(\"10\");\n\t\tassert(s1 == s2);\n\t}\n\n\tfunction c3() public pure {\n\t\tbytes32 r1 = ripemd160(\"100\");\n\t\tbytes32 r2 = ripemd160(\"100\");\n\t\tassert(r1 == r2);\n\t}\n\n\tfunction c4() public pure {\n\t\taddress e1 = ecrecover(\"a\", 1, hex\"bb\", unicode\"c\");\n\t\taddress e2 = ecrecover(\"a\", 1, hex\"bb\", unicode\"c\");\n\t\tassert(e1 == e2);\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_bmc_trusted.sol",
    "content": "contract D {\n\tuint x;\n\tfunction f() public view returns (uint) { return x; }\n}\n\ncontract C {\n\tfunction g() public {\n\t\tD d = new D();\n\t\tuint y = d.f();\n\t\tassert(y == 0); // should fail in BMC\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTExtCalls: trusted\n// ----\n// Warning 8729: (124-131): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n// Warning 4661: (153-167): BMC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_bmc_untrusted.sol",
    "content": "contract D {\n\tuint x;\n\tfunction f() public view returns (uint) { return x; }\n}\n\ncontract C {\n\tfunction g() public {\n\t\tD d = new D();\n\t\tuint y = d.f();\n\t\tassert(y == 0); // should fail in ext calls untrusted mode\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 8729: (124-131): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n// Warning 4661: (153-167): BMC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_trusted.sol",
    "content": "contract D {\n\tuint x;\n\tfunction f() public view returns (uint) { return x; }\n}\n\ncontract C {\n\tfunction g() public {\n\t\tD d = new D();\n\t\tuint y = d.f();\n\t\tassert(y == 0); // should hold in ext calls trusted mode\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTExtCalls: trusted\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_trusted_addresses.sol",
    "content": "contract D {\n\tuint x;\n}\n\ncontract C {\n\tfunction f() public {\n\t\tD d1 = new D();\n\t\tD d2 = new D();\n\n\t\tassert(d1 != d2); // should hold in ext calls trusted mode\n\t\tassert(address(this) != address(d1)); // should hold in ext calls trusted mode\n\t\tassert(address(this) != address(d2)); // should hold in ext calls trusted mode\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTExtCalls: trusted\n// ----\n// Warning 9170: (107-115): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_trusted_flow.sol",
    "content": "contract D {\n\tuint x;\n\tfunction inc() public { require(x < 5); ++x; }\n\tfunction f() public view returns (uint) { return x; }\n}\n\ncontract C {\n\tfunction f() public {\n\t\tD d = new D();\n\t\tassert(d.f() == 0); // should hold\n\t\td.inc();\n\t\tassert(d.f() == 1); // should hold\n\t\td = new D();\n\t\tassert(d.f() == 0); // should hold\n\t\tassert(d.f() == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (320-338): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_trusted_keep_storage_constraints.sol",
    "content": "contract D {\n\tuint x;\n}\n\ncontract C {\n\tuint y;\n\tfunction g() public {\n\t\tD d = new D();\n\t\tassert(y == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTExtCalls: trusted\n// ----\n// Warning 2072: (72-75): Unused local variable.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_trusted_state_flow.sol",
    "content": "contract D {\n\tuint x;\n\tfunction inc() public { ++x; }\n\tfunction f() public view returns (uint) { return x; }\n}\n\ncontract C {\n\tD d;\n\tconstructor() {\n\t\td = new D();\n\t\tassert(d.f() == 0); // should hold\n\t}\n\tfunction g() public view {\n\t\tassert(d.f() == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTExtCalls: trusted\n// SMTIgnoreOS: macos\n// ----\n// Warning 4984: (47-50): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here.\n// Warning 6328: (233-251): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 2661: (47-50): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_trusted_state_flow_2.sol",
    "content": "contract D {\n\tuint x;\n\tfunction f() public view returns (uint) { return x; }\n}\n\ncontract C {\n\tD d;\n\tconstructor() {\n\t\td = new D();\n\t\tassert(d.f() == 0); // should hold\n\t}\n\tfunction g() public view {\n\t\tassert(d.f() == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTExtCalls: trusted\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_trusted_state_flow_3.sol",
    "content": "contract D {\n\tuint x;\n\tfunction s(uint _x) public { x = _x; }\n\tfunction f() public view returns (uint) { return x; }\n}\n\ncontract C {\n\tD d;\n\tconstructor() {\n\t\td = new D();\n\t}\n\tfunction g() public view {\n\t\tassert(d.f() == 0); // should fail\n\t}\n}\n// ====\n// SMTContract: C\n// SMTEngine: all\n// SMTExtCalls: trusted\n// ----\n// Warning 6328: (204-222): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_trusted_state_flow_4.sol",
    "content": "contract D {\n\tbool b;\n\tfunction s() public { b = true; }\n\tfunction f() public view returns (bool) { return b; }\n}\n\ncontract C {\n\tD d;\n\tconstructor() {\n\t\td = new D();\n\t}\n\tfunction g() public view {\n\t\tassert(d.f()); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTExtCalls: trusted\n// ----\n// Warning 6328: (199-212): CHC: Assertion violation happens here.\\nCounterexample:\\nd = (- 1)\\n\\nTransaction trace:\\nC.constructor()\\nState: d = (- 1)\\nC.g()\\n    D.f() -- trusted external call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_untrusted.sol",
    "content": "contract D {\n\tuint x;\n\tfunction f() public view returns (uint) { return x; }\n}\n\ncontract C {\n\tfunction g() public {\n\t\tD d = new D();\n\t\tuint y = d.f();\n\t\tassert(y == 0); // should fail in ext calls untrusted mode\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8729: (124-131): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n// Warning 6328: (153-167): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nd = 0\\ny = 1\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    d.f() -- untrusted external call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_untrusted_addresses.sol",
    "content": "contract D {\n\tuint x;\n}\n\ncontract C {\n\tfunction f() public {\n\t\tD d1 = new D();\n\t\tD d2 = new D();\n\n\t\tassert(d1 != d2); // should fail in ext calls untrusted mode\n\t\tassert(address(this) != address(d1)); // should fail in ext calls untrusted mode\n\t\tassert(address(this) != address(d2)); // should fail in ext calls untrusted mode\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9170: (107-115): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// Warning 8729: (70-77): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n// Warning 8729: (88-95): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n// Warning 6328: (100-116): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nd1 = 0\\nd2 = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (163-199): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nd1 = 11797\\nd2 = 11797\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (246-282): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nd1 = 8855\\nd2 = 8855\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deploy_untrusted_erase_storage_constraints.sol",
    "content": "contract D {\n\tuint x;\n}\n\ncontract C {\n\tuint y;\n\tfunction g() public {\n\t\tD d = new D();\n\t\tassert(y == 0); // should fail in ext calls untrusted mode\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2072: (72-75): Unused local variable.\n// Warning 8729: (78-85): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n// Warning 6328: (89-103): CHC: Assertion violation happens here.\\nCounterexample:\\ny = 1\\nd = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: y = 0\\nC.g()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/deployment/deployment_trusted_with_value_1.sol",
    "content": "contract A {\n\tconstructor() payable {}\n}\n\ncontract B {\n\tfunction f() public payable {\n\t\trequire(address(this).balance == 100);\n\t\tA a = new A{value: 50}();\n\t\tassert(address(this).balance == 50); // should hold\n\t\tassert(address(this).balance == 60); // should fail\n\t\tassert(address(a).balance >= 50); // should hold\n\t\tassert(address(a).balance == 50); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// ----\n// Warning 6328: (211-246): CHC: Assertion violation happens here.\n// Warning 6328: (316-348): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_abstract_constructor_trusted_1.sol",
    "content": "contract D {\n\tconstructor(uint _x) { x = _x; }\n\tuint public x;\n}\n\ncontract E {\n\tconstructor() { x = 2; }\n\tuint public x;\n}\n\ncontract C {\n\tconstructor() {\n\t\taddress d = address(new D(42));\n\t\tassert(D(d).x() == 42); // should hold\n\t\tassert(D(d).x() == 43); // should fail\n\t\tuint y = E(d).x();\n\t\tassert(y == 2); // should fail, it would still call D.x() == 42\n\t\tassert(y == 42); // should hold, but fails due to false positive\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (231-253): CHC: Assertion violation happens here.\n// Warning 6328: (293-307): CHC: Assertion violation happens here.\n// Warning 6328: (359-374): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_abstract_constructor_trusted_2.sol",
    "content": "contract D {\n\tconstructor(uint _x) { x = _x; }\n\tfunction setD(uint _x) public { x = _x; }\n\tuint public x;\n}\n\ncontract C {\n\tconstructor() {\n\t\taddress d = address(new D(42));\n\t\tassert(D(d).x() == 42); // should hold\n\t\tassert(D(d).x() == 21); // should fail\n\t\td.call(abi.encodeCall(D.setD, (21)));\n\t\tassert(D(d).x() == 21); // should hold, but false positive cus low level calls are not handled precisely\n\t\tassert(D(d).x() == 42); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreCex: yes\n// ----\n// Warning 9302: (257-293): Return value of low-level calls not used.\n// Warning 6328: (216-238): CHC: Assertion violation happens here.\n// Warning 6328: (297-319): CHC: Assertion violation happens here.\n// Warning 6328: (404-426): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_abstract_trusted_1.sol",
    "content": "contract D {\n\tconstructor(uint _x) { x = _x; }\n\tuint public x;\n}\n\ncontract E {\n\tconstructor() { x = 2; }\n\tuint public x;\n}\n\ncontract C {\n\tfunction f() public {\n\t\taddress d = address(new D(42));\n\t\tassert(D(d).x() == 42); // should hold\n\t\tassert(D(d).x() == 43); // should fail\n\t\tuint y = E(d).x();\n\t\tassert(y == 2); // should fail, it would still call D.x() == 42\n\t\tassert(y == 42); // should hold, but fails due to false positive\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (237-259): CHC: Assertion violation happens here.\n// Warning 6328: (299-313): CHC: Assertion violation happens here.\n// Warning 6328: (365-380): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_abstract_trusted_2.sol",
    "content": "contract D {\n\tconstructor(uint _x) { x = _x; }\n\tfunction setD(uint _x) public { x = _x; }\n\tuint public x;\n}\n\ncontract C {\n\tfunction f() public {\n\t\taddress d = address(new D(42));\n\t\tassert(D(d).x() == 42); // should hold\n\t\tassert(D(d).x() == 21); // should fail\n\t\td.call(abi.encodeCall(D.setD, (21)));\n\t\tassert(D(d).x() == 21); // should hold, but false positive cus low level calls are not handled precisely\n\t\tassert(D(d).x() == 42); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreCex: yes\n// ----\n// Warning 9302: (263-299): Return value of low-level calls not used.\n// Warning 6328: (222-244): CHC: Assertion violation happens here.\n// Warning 6328: (303-325): CHC: Assertion violation happens here.\n// Warning 6328: (410-432): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_abstract_trusted_3.sol",
    "content": "contract D {\n\tconstructor(uint _x) { x = _x; }\n\tfunction setD(uint _x) public { x = _x; }\n\tuint public x;\n}\n\ncontract C {\n\tuint x;\n\n\tfunction f() public {\n\t\tx = 666;\n\t\taddress d = address(new D(42));\n\t\tassert(D(d).x() == 42); // should hold\n\t\tassert(D(d).x() == 21); // should fail\n\t\td.call(abi.encodeCall(D.setD, (21)));\n\t\tassert(D(d).x() == 21); // should hold, but false positive cus low level calls are not handled precisely\n\t\tassert(D(d).x() == 42); // should fail\n\t\tassert(x == 666); // should hold, C's storage should not have been havoced\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreCex: yes\n// ----\n// Warning 9302: (284-320): Return value of low-level calls not used.\n// Warning 6328: (243-265): CHC: Assertion violation happens here.\n// Warning 6328: (324-346): CHC: Assertion violation happens here.\n// Warning 6328: (431-453): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_constructor_1.sol",
    "content": "contract C {\n\tuint x;\n\tconstructor(address _a) {\n\t\t_a.call(\"aaaa\");\n\t\tassert(x == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9302: (51-66): Return value of low-level calls not used.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_constructor_2.sol",
    "content": "contract C {\n\tuint x;\n\tfunction f(uint _x) public {\n\t\tx = _x;\n\t}\n\tconstructor(address _a) {\n\t\t_a.call(\"aaaa\");\n\t\tassert(x == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9302: (94-109): Return value of low-level calls not used.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_mutex.sol",
    "content": "contract C {\n\tuint x;\n\n\tbool lock;\n\tmodifier mutex {\n\t\trequire(!lock);\n\t\tlock = true;\n\t\t_;\n\t\tlock = false;\n\t}\n\n\tfunction set(uint _x) mutex public {\n\t\tx = _x;\n\t}\n\n\tfunction f(address _a) mutex public {\n\t\tuint y = x;\n\t\t_a.call(\"aaaaa\");\n\t\tassert(y == x); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9302: (218-234): Return value of low-level calls not used.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_mutex_unsafe.sol",
    "content": "contract C {\n\tuint x;\n\n\tbool lock;\n\tmodifier mutex {\n\t\trequire(!lock);\n\t\tlock = true;\n\t\t_;\n\t\tlock = false;\n\t}\n\n\tfunction set(uint _x) mutex public {\n\t\tx = _x;\n\t}\n\n\tfunction f(address _a) public {\n\t\tuint y = x;\n\t\t_a.call(\"aaaaa\");\n\t\tassert(y == x); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 9302: (212-228): Return value of low-level calls not used.\n// Warning 6328: (232-246): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1, lock = false\\n_a = 0x0\\ny = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0, lock = false\\nC.f(0x0)\\n    _a.call(\"aaaaa\") -- untrusted external call, synthesized as:\\n        C.set(1) -- reentrant call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_reentrancy_1.sol",
    "content": "contract C {\n\tuint x;\n\tfunction s(uint _x) public {\n\t\tx = _x;\n\t}\n\tfunction f(address a) public {\n\t\t(bool s, bytes memory data) = a.call(\"\");\n\t\tassert(x == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2519: (100-106): This declaration shadows an existing declaration.\n// Warning 2072: (100-106): Unused local variable.\n// Warning 2072: (108-125): Unused local variable.\n// Warning 6328: (143-157): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_reentrancy_view.sol",
    "content": "contract C {\n\tuint x;\n\tfunction s(uint _x) public view {\n\t\tx == _x;\n\t}\n\tfunction f(address a) public {\n\t\t(bool s, bytes memory data) = a.call(\"\");\n\t\tassert(x == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 2519: (106-112): This declaration shadows an existing declaration.\n// Warning 2072: (106-112): Unused local variable.\n// Warning 2072: (114-131): Unused local variable.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_return_1.sol",
    "content": "contract C {\n\tuint x;\n\tfunction f(address a) public {\n\t\t(bool s, bytes memory data) = a.call(\"\");\n\t\tassert(s); // should fail\n\t\tassert(!s); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (65-82): Unused local variable.\n// Warning 6328: (100-109): CHC: Assertion violation happens here.\n// Warning 6328: (128-138): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_return_2.sol",
    "content": "contract C {\n\tuint x;\n\tfunction f(address a) public {\n\t\t(bool s, bytes memory data) = a.call(\"\");\n\t\tassert(data.length > 10); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (57-63): Unused local variable.\n// Warning 6328: (100-124): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_safe.sol",
    "content": "contract C {\n\tuint x;\n\tfunction f(address a) public {\n\t\t(bool s, bytes memory data) = a.call(\"\");\n\t\tassert(x == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreInv: yes\n// ----\n// Warning 2072: (57-63): Unused local variable.\n// Warning 2072: (65-82): Unused local variable.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_with_value_1.sol",
    "content": "contract C {\n\tfunction g(address payable i) public {\n\t\trequire(address(this).balance == 100);\n\t\ti.call{value: 10}(\"\");\n\t\tassert(address(this).balance == 90); // should hold\n\t\tassert(address(this).balance == 100); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTSolvers: eld\n// ----\n// Warning 9302: (96-117): Return value of low-level calls not used.\n// Warning 6328: (175-211): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_with_value_2.sol",
    "content": "contract C {\n\tfunction g(address payable i) public {\n\t\trequire(address(this).balance == 100);\n\t\ti.call{value: 0}(\"\");\n\t\tassert(address(this).balance == 100); // should hold\n\t\tassert(address(this).balance == 20); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTSolvers: eld\n// ----\n// Warning 9302: (96-116): Return value of low-level calls not used.\n// Warning 6328: (175-210): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/call_with_value_3.sol",
    "content": "contract C {\n\tfunction g(address payable i) public {\n\t\trequire(address(this).balance > 100);\n\t\ti.call{value: 20}(\"\");\n\t\tassert(address(this).balance > 0); // should hold\n\t\tassert(address(this).balance == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreCex: yes\n// SMTSolvers: eld\n// ----\n// Warning 9302: (95-116): Return value of low-level calls not used.\n// Warning 6328: (172-206): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual;\n}\n\ncontract C {\n\tuint x;\n\tD d;\n\tfunction f() public {\n\t\tif (x < 10)\n\t\t\t++x;\n\t}\n\tfunction g() public {\n\t\td.d();\n\t\tassert(x < 10);\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTTargets: assert\n// SMTIgnoreCex: yes\n// SMTIgnoreOS: linux\n// ----\n// Warning 6328: (167-181): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 10, d = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0, d = 0\\nC.f()\\nState: x = 1, d = 0\\nC.f()\\nState: x = 2, d = 0\\nC.f()\\nState: x = 3, d = 0\\nC.f()\\nState: x = 4, d = 0\\nC.f()\\nState: x = 5, d = 0\\nC.f()\\nState: x = 6, d = 0\\nC.g()\\n    d.d() -- untrusted external call, synthesized as:\\n        C.f() -- reentrant call\\n        C.f() -- reentrant call\\nState: x = 8, d = 0\\nC.g()\\n    d.d() -- untrusted external call, synthesized as:\\n        C.f() -- reentrant call\\n        C.f() -- reentrant call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_extra_parentheses_1.sol",
    "content": "contract C {\n\tfunction f() external {}\n\tfunction g() public {\n\t\t(this.f)();\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_extra_parentheses_2.sol",
    "content": "contract D {\n\tfunction f() external {}\n}\n\ncontract C {\n\tfunction g(D d) public {\n\t\t((d.f))();\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_1.sol",
    "content": "contract State {\n\tfunction f(uint _x) public pure returns (uint) {\n\t\tassert(_x < 100);\n\t\treturn _x;\n\t}\n}\ncontract C {\n\tState s;\n\tuint z = s.f(2);\n\n\tfunction f() public view {\n\t\tassert(z == 2); // should fail since we don't trust s.f's code\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (69-85): CHC: Assertion violation happens here.\n// Warning 6328: (177-191): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_1_trusted.sol",
    "content": "contract State {\n\tfunction f(uint _x) public pure returns (uint) {\n\t\tassert(_x < 100); // should hold when analyzing only contract C (can fail only when analyzing State as standalone contract)\n\t\treturn _x;\n\t}\n}\ncontract C {\n\tState s;\n\tuint z = s.f(2);\n\n\tfunction f() public view {\n\t\tassert(z == 2); // should hold in trusted mode\n\t}\n}\n// ====\n// SMTContract: C\n// SMTEngine: all\n// SMTExtCalls: trusted\n// SMTIgnoreInv: yes\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_2.sol",
    "content": "contract C {\n\tuint z = this.g(2);\n\n\tfunction g(uint _x) public pure returns (uint) {\n\t\tassert(_x > 0);\n\t\treturn _x;\n\t}\n\n\tfunction f() public view {\n\t\tassert(z == 2); // should fail since we don't trust s.f's code\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (87-101): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_2_trusted.sol",
    "content": "contract C {\n\tuint z = this.g(2);\n\n\tfunction g(uint _x) public pure returns (uint) {\n\t\tassert(_x > 0); // should fail\n\t\treturn _x;\n\t}\n\n\tfunction f() public view {\n\t\tassert(z == 2); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (87-101): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_3.sol",
    "content": "contract State {\n\tfunction f(uint _x) public pure returns (uint) {\n\t\tassert(_x < 100);\n\t\treturn _x;\n\t}\n}\ncontract C {\n\tState s;\n\tuint z;\n\n\tconstructor() {\n\t\tz = s.f(2);\n\t}\n\n\tfunction f() public view {\n\t\tassert(z == 2); // should fail since we don't trust s.f's code\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (69-85): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n_x = 100\\n = 0\\n\\nTransaction trace:\\nState.constructor()\\nState.f(100)\n// Warning 6328: (203-217): CHC: Assertion violation happens here.\\nCounterexample:\\ns = 0, z = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: s = 0, z = 0\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_3_trusted.sol",
    "content": "contract State {\n\tfunction f(uint _x) public pure returns (uint) {\n\t\tassert(_x < 100); // should hold when analyzing only contract C (can fail only when analyzing State as standalone contract)\n\t\treturn _x;\n\t}\n}\ncontract C {\n\tState s;\n\tuint z;\n\n\tconstructor() {\n\t\tz = s.f(2);\n\t}\n\n\tfunction f() public view {\n\t\tassert(z == 2); // should hold in trusted mode\n\t}\n}\n// ====\n// SMTContract: C\n// SMTEngine: all\n// SMTExtCalls: trusted\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_reentrancy_1.sol",
    "content": "interface D {\n\tfunction ext(C c) external returns (uint);\n}\n\ncontract C {\n\tuint x;\n\tfunction s(uint _x) public { x = _x; }\n\tconstructor(D d) {\n\t\tuint a = d.ext(this);\n\t\tassert(x == 0); // should hold because there's no reentrancy from the constructor\n\t\tassert(a == 2); // should fail\n\t}\n}\n// ====\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (253-267): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_1.sol",
    "content": "contract A {\n\tuint x;\n\tfunction setX(uint _x) public {\n\t\tx = _x;\n\t}\n\tfunction getX() public view returns (uint) {\n\t\treturn x;\n\t}\n}\n\ncontract B {\n\tA a;\n\tconstructor() {\n\t\ta = new A();\n\t\tassert(a.getX() == 0); // should hold\n\t}\n\tfunction g() public view {\n\t\tassert(a.getX() == 0); // should fail because A.setX() can be called without B\n\t}\n\tfunction getX() public view returns (uint) {\n\t\treturn a.getX();\n\t}\n}\n\ncontract C {\n\tB b;\n\tconstructor() {\n\t\tb = new B();\n\t\tassert(b.getX() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(b.getX() == 0); // should fail because A.setX() can be called without A\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// ----\n// Warning 6328: (256-277): CHC: Assertion violation happens here.\n// Warning 6328: (533-554): CHC: Assertion violation might happen here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_2.sol",
    "content": "contract A {\n    uint x;\n    address immutable owner;\n    constructor() {\n        owner = msg.sender;\n    }\n    function setX(uint _x) public {\n        require(msg.sender == owner);\n        x = _x;\n    }\n    function getX() public view returns (uint) {\n        return x;\n    }\n}\n\ncontract B {\n    A a;\n    constructor() {\n        a = new A();\n        assert(a.getX() == 0); // should hold\n    }\n    function g() public view {\n        assert(a.getX() == 0); // should hold, but fails because\n        // the nondet_interface constraint added for `A a` in between\n        // txs of `B` does not have the constraint that `msg.sender != address(this)`\n        // so `A.setX` is allowed with `msg.sender = address(this)` inside\n        // the current rules defining nondet_interface.\n        // If we want to support that, we likely need a new type of nondet_interface\n        // `nondet_interface_with_tx` that contains tx data as well as restricts\n        // every further `nondet_interface_with_tx` to not have that `msg.sender`.\n    }\n    function getX() public view returns (uint) {\n        return a.getX();\n    }\n}\n\ncontract C {\n    B b;\n    constructor() {\n        b = new B();\n        assert(b.getX() == 0); // should hold\n    }\n    function f() public view {\n        assert(b.getX() == 0); // should hold\n    }\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTSolvers: eld\n// ----\n// Warning 6328: (434-455): CHC: Assertion violation happens here.\n// Warning 6328: (1270-1291): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_3.sol",
    "content": "contract A {\n\tuint x;\n\taddress immutable owner;\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\tfunction setX(uint _x) public {\n\t\trequire(msg.sender == owner);\n\t\tx = _x;\n\t}\n\tfunction getX() public view returns (uint) {\n\t\treturn x;\n\t}\n}\n\ncontract B {\n\tA a;\n\tconstructor() {\n\t\ta = new A();\n\t\tassert(a.getX() == 0); // should hold\n\t}\n\tfunction g() public {\n\t\ta.setX(42);\n\t}\n\tfunction getX() public view returns (uint) {\n\t\treturn a.getX();\n\t}\n}\n\ncontract C {\n\tB b;\n\tconstructor() {\n\t\tb = new B();\n\t\tassert(b.getX() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(b.getX() == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (561-582): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_4.sol",
    "content": "contract A {\n\tuint x;\n\taddress immutable owner;\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\tfunction setX(uint _x) public {\n\t\trequire(msg.sender == owner);\n\t\tx = _x;\n\t}\n\tfunction getX() public view returns (uint) {\n\t\treturn x;\n\t}\n}\n\ncontract B {\n\tA a;\n\taddress immutable owner;\n\tconstructor() {\n\t\towner = msg.sender;\n\t\ta = new A();\n\t\tassert(a.getX() == 0); // should hold\n\t}\n\tfunction g() public {\n\t\trequire(msg.sender == owner);\n\t\ta.setX(42);\n\t}\n\tfunction getX() public view returns (uint) {\n\t\treturn a.getX();\n\t}\n}\n\ncontract C {\n\tB b;\n\tconstructor() {\n\t\tb = new B();\n\t\tassert(b.getX() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(b.getX() == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// ----\n// Warning 6328: (641-662): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_indirect_5.sol",
    "content": "contract A {\n\tuint x;\n\taddress immutable owner;\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\tfunction setX(uint _x) public {\n\t\trequire(msg.sender == owner);\n\t\tx = _x;\n\t}\n\tfunction getX() public view returns (uint) {\n\t\treturn x;\n\t}\n}\n\ncontract B {\n\tA a;\n\taddress immutable owner;\n\tconstructor() {\n\t\towner = msg.sender;\n\t\ta = new A();\n\t}\n\tfunction g() public {\n\t\trequire(msg.sender == owner);\n\t\ta.setX(42);\n\t}\n\tfunction getX() public view returns (uint) {\n\t\treturn a.getX();\n\t}\n}\n\ncontract C {\n\tB b;\n\tconstructor() {\n\t\tb = new B();\n\t\tassert(b.getX() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(b.getX() == 0); // should fail\n\t}\n\tfunction h() public {\n\t\tb.g();\n\t}\n}\n// ====\n// SMTContract: C\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTSolvers: eld\n// ----\n// Warning 6328: (601-622): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_semantic_this_1.sol",
    "content": "contract C {\n\tuint x;\n\tfunction i() public { ++x; }\n\tfunction f() public {\n\t\tx = 0;\n\t\tthis.i();\n\t\tassert(x == 1); // should hold in trusted mode\n\t\tassert(x != 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreCex: yes\n// SMTTargets: assert\n// ----\n// Warning 6328: (147-161): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_semantic_this_2.sol",
    "content": "contract C {\n\tuint x;\n\tfunction i() public { ++x; }\n\tfunction f() public {\n\t\tx = 0;\n\t\t((this)).i();\n\t\tassert(x == 1); // should hold in trusted mode\n\t\tassert(x != 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (151-165): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_semantic_this_3.sol",
    "content": "contract C {\n\tuint x;\n\tfunction i() public { ++x; }\n\tfunction f() public {\n\t\tx = 0;\n\t\tC c = this;\n\t\tc.i();\n\t\tassert(x == 1); // should hold in trusted mode\n\t\tassert(x != 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (158-172): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_address_inside_array_struct_trusted_1.sol",
    "content": "contract D {\n\tuint public x;\n}\n\ncontract C {\n\tstruct S {\n\t\taddress d;\n\t}\n\tS[] ss;\n\tconstructor() {\n\t\tss.push(S(address(new D())));\n\t\tassert(D(ss[0].d).x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(D(ss[0].d).x() == 0); // should hold, but fails because we havoc the state\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (210-237): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_address_inside_array_struct_trusted_2.sol",
    "content": "contract D {\n\tuint public x;\n\tfunction setD(uint _x) public { x = _x; }\n}\n\ncontract C {\n\tstruct S {\n\t\taddress d;\n\t}\n\tS[] ss;\n\tconstructor() {\n\t\tss.push(S(address(new D())));\n\t\tassert(D(ss[0].d).x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(D(ss[0].d).x() == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (253-280): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_address_inside_array_trusted_1.sol",
    "content": "contract D {\n\tuint public x;\n\tfunction setD(uint _x) public { x = _x; }\n}\n\ncontract C {\n\taddress[] ds;\n\tconstructor() {\n\t\tds.push(address(new D()));\n\t\tassert(D(ds[0]).x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(D(ds[0]).x() == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (226-251): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_address_inside_array_trusted_2.sol",
    "content": "contract D {\n\tuint public x;\n}\n\ncontract C {\n\taddress[] ds;\n\tconstructor() {\n\t\tds.push(address(new D()));\n\t\tassert(D(ds[0]).x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(D(ds[0]).x() == 0); // should hold, but fails because we havoc the state\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (183-208): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_address_inside_struct_trusted_1.sol",
    "content": "contract D {\n\tuint public x;\n\tfunction setD(uint _x) public { x = _x; }\n}\n\ncontract C {\n\tstruct S {\n\t\taddress d;\n\t}\n\tS s;\n\tconstructor() {\n\t\ts.d = address(new D());\n\t\tassert(D(s.d).x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(D(s.d).x() == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (240-263): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_address_inside_struct_trusted_2.sol",
    "content": "contract D {\n\tuint public x;\n}\n\ncontract C {\n\tstruct S {\n\t\taddress d;\n\t}\n\tS s;\n\tconstructor() {\n\t\ts.d = address(new D());\n\t\tassert(D(s.d).x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(D(s.d).x() == 0); // should hold, but fails because we havoc the state\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (197-220): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_address_inside_struct_trusted_3.sol",
    "content": "contract D {\n\tuint public x;\n}\n\ncontract C {\n\tstruct S {\n\t\taddress d;\n\t}\n\tstruct T {\n\t\tS s;\n\t}\n\tT t;\n\tconstructor() {\n\t\tt.s.d = address(new D());\n\t\tassert(D(t.s.d).x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(D(t.s.d).x() == 0); // should hold, but fails because we havoc the state\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (223-248): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_address_inside_struct_trusted_4.sol",
    "content": "contract D {\n\tuint public x;\n\tfunction setD(uint _x) public { x = _x; }\n}\n\ncontract C {\n\tstruct S {\n\t\taddress d;\n\t}\n\tstruct T {\n\t\tS s;\n\t}\n\tT t;\n\tconstructor() {\n\t\tt.s.d = address(new D());\n\t\tassert(D(t.s.d).x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(D(t.s.d).x() == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (266-291): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_contract_inside_array_struct_trusted_1.sol",
    "content": "contract D {\n\tuint public x;\n}\n\ncontract C {\n\tstruct S {\n\t\tD d;\n\t}\n\tS[] ss;\n\tconstructor() {\n\t\tss.push(S(new D()));\n\t\tassert(ss[0].d.x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(ss[0].d.x() == 0); // should hold, but fails because we havoc the state\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (192-216): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_contract_inside_array_struct_trusted_2.sol",
    "content": "contract D {\n\tuint public x;\n\tfunction setD(uint _x) public { x = _x; }\n}\n\ncontract C {\n\tstruct S {\n\t\tD d;\n\t}\n\tS[] ss;\n\tconstructor() {\n\t\tss.push(S(new D()));\n\t\tassert(ss[0].d.x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(ss[0].d.x() == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (235-259): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_contract_inside_array_trusted_1.sol",
    "content": "contract D {\n\tuint public x;\n\tfunction setD(uint _x) public { x = _x; }\n}\n\ncontract C {\n\tD[] ds;\n\tconstructor() {\n\t\tds.push(new D());\n\t\tassert(ds[0].x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(ds[0].x() == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (208-230): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_contract_inside_array_trusted_2.sol",
    "content": "contract D {\n\tuint public x;\n}\n\ncontract C {\n\tD[] ds;\n\tconstructor() {\n\t\tds.push(new D());\n\t\tassert(ds[0].x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(ds[0].x() == 0); // should hold, but fails because we havoc the state\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreCex: yes\n// SMTTargets: assert\n// ----\n// Warning 6328: (165-187): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_contract_inside_struct_trusted_1.sol",
    "content": "contract D {\n\tuint public x;\n\tfunction setD(uint _x) public { x = _x; }\n}\n\ncontract C {\n\tstruct S {\n\t\tD d;\n\t}\n\tS s;\n\tconstructor() {\n\t\ts.d = new D();\n\t\tassert(s.d.x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(s.d.x() == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (222-242): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_contract_inside_struct_trusted_2.sol",
    "content": "contract D {\n\tuint public x;\n}\n\ncontract C {\n\tstruct S {\n\t\tD d;\n\t}\n\tS s;\n\tconstructor() {\n\t\ts.d = new D();\n\t\tassert(s.d.x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(s.d.x() == 0); // should hold, but fails because we havoc the state\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreCex: yes\n// SMTTargets: assert\n// ----\n// Warning 6328: (179-199): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_contract_inside_struct_trusted_3.sol",
    "content": "contract D {\n\tuint public x;\n}\n\ncontract C {\n\tstruct S {\n\t\tD d;\n\t}\n\tstruct T {\n\t\tS s;\n\t}\n\tT t;\n\tconstructor() {\n\t\tt.s.d = new D();\n\t\tassert(t.s.d.x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(t.s.d.x() == 0); // should hold, but fails because we havoc the state\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreCex: yes\n// SMTTargets: assert\n// ----\n// Warning 6328: (205-227): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_state_var_contract_inside_struct_trusted_4.sol",
    "content": "contract D {\n\tuint public x;\n\tfunction setD(uint _x) public { x = _x; }\n}\n\ncontract C {\n\tstruct S {\n\t\tD d;\n\t}\n\tstruct T {\n\t\tS s;\n\t}\n\tT t;\n\tconstructor() {\n\t\tt.s.d = new D();\n\t\tassert(t.s.d.x() == 0); // should hold\n\t}\n\tfunction f() public view {\n\t\tassert(t.s.d.x() == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (248-270): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_this_with_value_1.sol",
    "content": "contract C {\n\tfunction g() public {\n\t\trequire(address(this).balance == 100);\n\t\tthis.h{value: 10}();\n\t\tassert(address(this).balance == 100); // should hold\n\t\tassert(address(this).balance == 90); // should fail\n\t}\n\n\tfunction h() external payable {}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (157-192): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_this_with_value_2.sol",
    "content": "contract C {\n\tfunction g(uint i) public {\n\t\trequire(address(this).balance == 100);\n\t\t// if called address is same as this, don't do anything with the value stuff\n\t\t// or fix the receiving end\n\t\tthis.h{value: i}();\n\t\tuint x = address(this).balance;\n\t\tassert(x == 100); // should hold\n\t\tassert(address(this).balance == 100); // should hold\n\t\tassert(address(this).balance == 90); // should fail\n\t}\n\n\tfunction h() external payable {}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (340-375): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_with_gas_1.sol",
    "content": "library L {\n\tfunction f() public view {\n\t\t(bool success, ) = address(10).staticcall{gas: 3}(\"\");\n\t\trequire(success);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_1.sol",
    "content": "interface I {\n\tfunction f() external payable;\n}\n\ncontract C {\n\tfunction g(I i) public {\n\t\trequire(address(this).balance == 100);\n\t\ti.f{value: 10}();\n\t\tassert(address(this).balance == 90); // should hold\n\t\tassert(address(this).balance == 100); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTSolvers: eld\n// ----\n// Warning 6328: (205-241): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_2.sol",
    "content": "interface I {\n\tfunction f() external payable;\n}\n\ncontract C {\n\tfunction g(I i) public {\n\t\trequire(address(this).balance == 100);\n\t\ti.f{value: 0}();\n\t\tassert(address(this).balance == 100); // should hold\n\t\tassert(address(this).balance == 90); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreCex: yes\n// SMTSolvers: eld\n// ----\n// Warning 6328: (205-240): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_call_with_value_3.sol",
    "content": "interface I {\n\tfunction f() external payable;\n}\n\ncontract C {\n\tfunction g(I i) public {\n\t\trequire(address(this).balance > 100);\n\t\ti.f{value: 20}();\n\t\tassert(address(this).balance > 0); // should hold\n\t\tassert(address(this).balance == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTSolvers: eld\n// ----\n// Warning 6328: (202-236): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash.sol",
    "content": "abstract contract Crypto {\n\tfunction hash(bytes32) external pure virtual returns (bytes32);\n}\n\ncontract C {\n\taddress owner;\n\tbytes32 sig_1;\n\tbytes32 sig_2;\n\tCrypto d;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\n\tfunction f1(bytes32 _msg) public {\n\t\taddress prevOwner = owner;\n\t\tsig_1 = d.hash(_msg);\n\t\tsig_2 = d.hash(_msg);\n\t\tassert(prevOwner == owner);\n\t}\n\n\tfunction inv() public view {\n\t\tassert(sig_1 == sig_2);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (390-412): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_pure.sol",
    "content": "contract Crypto {\n\tfunction hash(bytes32) external pure returns (bytes32) {\n\t\treturn bytes32(0);\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tbytes32 sig_1;\n\tbytes32 sig_2;\n\tCrypto d;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\n\tfunction f1(bytes32 _msg) public {\n\t\taddress prevOwner = owner;\n\t\tsig_1 = d.hash(_msg);\n\t\tsig_2 = d.hash(_msg);\n\t\tassert(prevOwner == owner);\n\t}\n\n\tfunction inv() public view {\n\t\tassert(sig_1 == sig_2);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (398-420): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_pure_trusted.sol",
    "content": "contract Crypto {\n\tfunction hash(bytes32) external pure returns (bytes32) {\n\t\treturn bytes32(0);\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tbytes32 sig_1;\n\tbytes32 sig_2;\n\tCrypto d;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\n\tfunction f1(bytes32 _msg) public {\n\t\taddress prevOwner = owner;\n\t\tsig_1 = d.hash(_msg);\n\t\tsig_2 = d.hash(_msg);\n\t\tassert(prevOwner == owner);\n\t}\n\n\tfunction inv() public view {\n\t\tassert(sig_1 == sig_2);\n\t}\n}\n// ====\n// SMTContract: C\n// SMTEngine: all\n// SMTExtCalls: trusted\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state.sol",
    "content": "contract State {\n\tuint x;\n\tfunction f() public returns (uint) {\n\t\tif (x == 0) x = 1;\n\t\telse if (x == 1) x = 2;\n\t\telse if (x == 2) x = 0;\n\t\treturn x;\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tuint z;\n\tState s;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\n\tfunction f() public {\n\t\taddress prevOwner = owner;\n\t\ty = s.f();\n\t\tz = s.f();\n\t\tassert(prevOwner == owner);\n\t}\n\n\tfunction inv() public view {\n\t\t// This is safe but external calls do not yet support the state\n\t\t// of the called contract.\n\t\tassert(owner == address(0) || y != z);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (495-532): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy.sol",
    "content": "contract State {\n\tuint x;\n\tC c;\n\tfunction f() public view returns (uint) {\n\t\treturn c.g();\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tState s;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\n\tfunction f() public view {\n\t\taddress prevOwner = owner;\n\t\tuint z = s.f();\n\t\tassert(z == y);\n\t\tassert(prevOwner == owner);\n\t}\n\n\tfunction g() public view returns (uint) {\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (266-280): CHC: Assertion violation happens here.\\nCounterexample:\\nowner = 0x0, y = 0, s = 0\\nprevOwner = 0x0\\nz = 1\\n\\nTransaction trace:\\nC.constructor(){ msg.sender: 0x0 }\\nState: owner = 0x0, y = 0, s = 0\\nC.f()\\n    s.f() -- untrusted external call\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_2.sol",
    "content": "contract State {\n\tuint x;\n\tC c;\n\tfunction f() public returns (uint) {\n\t\treturn c.g();\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tuint z;\n\tState s;\n\tbool insidef;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\n\tfunction zz() public {\n\t\trequire(insidef);\n\t\tz = 3;\n\t}\n\n\tfunction f() public {\n\t\trequire(!insidef);\n\t\taddress prevOwner = owner;\n\t\tinsidef = true;\n\t\ts.f();\n\t\tassert(z == y);\n\t\tassert(prevOwner == owner);\n\t\tinsidef = false;\n\t}\n\n\tfunction g() public view returns (uint) {\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreInv: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 2018: (33-88): Function state mutability can be restricted to view\n// Warning 6328: (367-381): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_2_trusted.sol",
    "content": "contract State {\n\tC c;\n\tconstructor(C _c) {\n\t\tc = _c;\n\t}\n\tfunction f() public view returns (uint) {\n\t\treturn c.g();\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tuint z;\n\tState s;\n\tbool insidef;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t\ts = new State(this);\n\t}\n\n\tfunction zz() public {\n\t\trequire(insidef);\n\t\tz = 3;\n\t}\n\n\tfunction f() public {\n\t\trequire(!insidef);\n\t\taddress prevOwner = owner;\n\t\tinsidef = true;\n\t\ts.f();\n\t\tassert(z == y);\n\t\tassert(prevOwner == owner);\n\t\tinsidef = false;\n\t}\n\n\tfunction g() public view returns (uint) {\n\t\treturn y;\n\t}\n}\n// ====\n// SMTContract: C\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_3.sol",
    "content": "contract State {\n\tuint x;\n\tC c;\n\tfunction f() public view returns (uint) {\n\t\treturn c.g();\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tuint z;\n\tState s;\n\tbool insidef;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\n\tfunction zz() public {\n\t\trequire(insidef);\n\t\tz = 3;\n\t}\n\n\tfunction f() public {\n\t\trequire(!insidef);\n\t\taddress prevOwner = owner;\n\t\tinsidef = true;\n\t\t// s.f() cannot call zz() because it is `view`\n\t\t// and zz modifies the state.\n\t\ts.f();\n\t\tassert(z == y);\n\t\tassert(prevOwner == owner);\n\t\tinsidef = false;\n\t}\n\n\tfunction g() public view returns (uint) {\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTSolvers: eld\n// SMTIgnoreInv: yes\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_indirect.sol",
    "content": "contract Other {\n\tC c;\n\tfunction h() public {\n\t\tc.setOwner(address(0));\n\t}\n}\n\ncontract State {\n\tuint x;\n\tOther o;\n\tC c;\n\tfunction f() public returns (uint) {\n\t\to.h();\n\t\treturn c.g();\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tState s;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\n\tfunction setOwner(address _owner) public {\n\t\towner = _owner;\n\t}\n\n\tfunction f() public {\n\t\taddress prevOwner = owner;\n\t\tuint z = s.f();\n\t\tassert(z == y);\n\t\tassert(prevOwner == owner);\n\t}\n\n\tfunction g() public view returns (uint) {\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (419-433): CHC: Assertion violation happens here.\n// Warning 6328: (437-463): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_indirect_trusted.sol",
    "content": "contract Other {\n\tfunction h(C c) public {\n\t\tc.setOwner(address(0));\n\t}\n}\n\ncontract State {\n\tuint x;\n\tOther o;\n\tconstructor() {\n\t\to = new Other();\n\t}\n\tfunction f(C c) public returns (uint) {\n\t\to.h(c);\n\t\treturn c.g();\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tState s;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t\ts = new State();\n\t}\n\n\tfunction setOwner(address _owner) public {\n\t\towner = _owner;\n\t}\n\n\tfunction f() public {\n\t\taddress prevOwner = owner;\n\t\tuint z = s.f(this);\n\t\tassert(z == y); // should hold\n\t\tassert(prevOwner == owner); // should not hold because of reentrancy\n\t}\n\n\tfunction g() public view returns (uint) {\n\t\treturn y;\n\t}\n}\n// ====\n// SMTContract: C\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// ----\n// Warning 6328: (509-535): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_trusted.sol",
    "content": "contract State {\n\tC c;\n\tconstructor(C _c) {\n\t\tc = _c;\n\t}\n\tfunction f() public view returns (uint) {\n\t\treturn c.g();\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tState s;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t\ts = new State(this);\n\t}\n\n\tfunction f() public view {\n\t\taddress prevOwner = owner;\n\t\tuint z = s.f();\n\t\tassert(z == y);\n\t\tassert(prevOwner == owner);\n\t}\n\n\tfunction g() public view returns (uint) {\n\t\treturn y;\n\t}\n}\n// ====\n// SMTContract: C\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTSolvers: eld\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe.sol",
    "content": "contract State {\n\tuint x;\n\tC c;\n\tfunction f() public returns (uint) {\n\t\tc.setOwner(address(0));\n\t\treturn c.g();\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tState s;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\n\tfunction setOwner(address _owner) public {\n\t\towner = _owner;\n\t}\n\n\tfunction f() public {\n\t\taddress prevOwner = owner;\n\t\tuint z = s.f();\n\t\tassert(z == y);\n\t\tassert(prevOwner == owner);\n\t}\n\n\tfunction g() public view returns (uint) {\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (348-362): CHC: Assertion violation happens here.\n// Warning 6328: (366-392): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_reentrancy_unsafe_trusted.sol",
    "content": "contract State {\n\tC c;\n\tconstructor(C _c) {\n\t\tc = _c;\n\t}\n\tfunction f() public returns (uint) {\n\t\tc.setOwner(address(0));\n\t\treturn c.g();\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tState s;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t\ts = new State(this);\n\t}\n\n\tfunction setOwner(address _owner) public {\n\t\towner = _owner;\n\t}\n\n\tfunction f() public {\n\t\taddress prevOwner = owner;\n\t\tuint z = s.f();\n\t\tassert(z == y); // should hold\n\t\tassert(prevOwner == owner); // should not hold because of reentrancy\n\t}\n\n\tfunction g() public view returns (uint) {\n\t\treturn y;\n\t}\n}\n// ====\n// SMTContract: C\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (429-455): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_trusted.sol",
    "content": "contract State {\n\tuint x;\n\tfunction f() public returns (uint) {\n\t\tif (x == 0) x = 1;\n\t\telse if (x == 1) x = 2;\n\t\telse if (x == 2) x = 0;\n\t\treturn x;\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tuint z;\n\tState s;\n\n\tconstructor() {\n\t\ts = new State();\n\t\towner = msg.sender;\n\t}\n\n\tfunction f() public {\n\t\taddress prevOwner = owner;\n\t\ty = s.f();\n\t\tz = s.f();\n\t\tassert(prevOwner == owner);\n\t\tassert(y != z);\n\t}\n}\n// ====\n// SMTContract: C\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// ----\n// Warning 6328: (355-381): CHC: Assertion violation might happen here.\n// Warning 6328: (385-399): CHC: Assertion violation might happen here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_unsafe.sol",
    "content": "contract State {\n\tuint x;\n\tfunction f() public returns (uint) {\n\t\tif (x == 0) x = 1;\n\t\telse if (x == 1) x = 2;\n\t\telse if (x == 2) x = 0;\n\t\treturn x;\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tuint z;\n\tState s;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t}\n\n\tfunction setOwner(address _owner) public {\n\t\towner = _owner;\n\t}\n\n\tfunction f() public {\n\t\taddress prevOwner = owner;\n\t\ty = s.f();\n\t\tz = s.f();\n\t\tassert(prevOwner == owner);\n\t}\n\n\tfunction inv() public view {\n\t\t// This is safe but external calls do not yet support the state\n\t\t// of the called contract.\n\t\tassert(owner == address(0) || y != z);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (402-428): CHC: Assertion violation happens here.\n// Warning 6328: (561-598): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_hash_known_code_state_unsafe_trusted.sol",
    "content": "contract State {\n\tuint x;\n\tfunction f() public returns (uint) {\n\t\tif (x == 0) x = 1;\n\t\telse if (x == 1) x = 2;\n\t\telse if (x == 2) x = 0;\n\t\treturn x;\n\t}\n}\n\ncontract C {\n\taddress owner;\n\tuint y;\n\tuint z;\n\tState s;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t\ts = new State();\n\t}\n\n\tfunction setOwner(address _owner) public {\n\t\towner = _owner;\n\t}\n\n\tfunction f() public {\n\t\taddress prevOwner = owner;\n\t\ty = s.f();\n\t\tz = s.f();\n\t\tassert(prevOwner == owner);\n\t\tassert(y != z);\n\t}\n}\n// ====\n// SMTContract: C\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// ----\n// Warning 6328: (421-447): CHC: Assertion violation might happen here.\n// Warning 6328: (451-465): CHC: Assertion violation might happen here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_inc.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual;\n}\n\ncontract C {\n\tuint x;\n\tD d;\n\n\tfunction inc() public {\n\t\trequire(x < 10);\n\t\t++x;\n\t}\n\n\tfunction f() public {\n\t\td.d();\n\t\tassert(x < 5);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (175-188): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 5, d = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0, d = 0\\nC.inc()\\nState: x = 1, d = 0\\nC.inc()\\nState: x = 2, d = 0\\nC.inc()\\nState: x = 3, d = 0\\nC.inc()\\nState: x = 4, d = 0\\nC.f()\\n    d.d() -- untrusted external call, synthesized as:\\n        C.inc() -- reentrant call\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_inc1_inc2.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual;\n}\n\ncontract C {\n\tuint x;\n\tuint y;\n\tD d;\n\n\tfunction inc2() public {\n\t\tif (y == 1)\n\t\t\tx = 1;\n\t}\n\tfunction inc1() public {\n\t\tif (x == 0)\n\t\t\ty = 1;\n\t}\n\n\tfunction f() public {\n\t\tuint oldX = x;\n\t\t// Removed because Spacer 4.8.9 seg faults.\n\t\t//d.d();\n\t\tassert(oldX == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2018: (203-322): Function state mutability can be restricted to view\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_1.sol",
    "content": "interface D { function e() external; }\n\ncontract C {\n\tbool locked = true;\n\n\tfunction call(address target) public {\n\t\tlocked = false;\n\t\tD(target).e();\n\t\tlocked = true;\n\t}\n\n\tfunction broken() public view {\n\t\tassert(locked);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (206-220): CHC: Assertion violation happens here.\\nCounterexample:\\nlocked = false\\ntarget = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: locked = true\\nC.call(0x0)\\n    D(target).e() -- untrusted external call, synthesized as:\\n        C.broken() -- reentrant call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_2.sol",
    "content": "interface D { function e() external; }\n\ncontract C {\n\tbool locked = true;\n\n\tfunction call(address target) public {\n\t\tassert(locked);\n\t\tlocked = false;\n\t\tD(target).e();\n\t\tlocked = true;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (117-131): CHC: Assertion violation happens here.\\nCounterexample:\\nlocked = false\\ntarget = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: locked = true\\nC.call(0x0)\\n    D(target).e() -- untrusted external call, synthesized as:\\n        C.call(0x0) -- reentrant call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_3.sol",
    "content": "abstract contract D {\n\tfunction d() virtual public {}\n}\n\ncontract A {\n\tint x = 0;\n\n\tfunction f() virtual public view {\n\t\tassert(x == 0); // should hold\n\t\tassert(x == 1); // should fail\n\t}\n}\ncontract C is A {\n\tconstructor() {\n\t\tx = 1;\n\t}\n\n\tfunction call(D d) public {\n\t\td.d();\n\t}\n\n\tfunction f() public view override {\n\t\tassert(x == 1); // should hold\n\t\tassert(x == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreCex: yes\n// SMTIgnoreInv: yes\n// SMTSolvers: eld\n// ----\n// Warning 6328: (154-168): CHC: Assertion violation happens here.\n// Warning 6328: (352-366): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_reentrancy_crypto.sol",
    "content": "abstract contract D {\n\tfunction d() virtual public;\n}\n\ncontract C {\n\tbytes data;\n\n\tbytes32 kec;\n\n\tconstructor(bytes memory _data) {\n\t\tdata = _data;\n\n\t\tkec = keccak256(data);\n\t}\n\n\tfunction check(bytes memory _data) public view {\n\t\tbytes32 _kec = keccak256(data);\n\t\tassert(_kec == kec); // should hold\n\t\tassert(kec == keccak256(_data)); // should fail\n\t}\n\n\tfunction ext(D d) public {\n\t\td.d();\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreInv: yes\n// ----\n// Warning 6328: (302-333): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_safe.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual;\n}\n\ncontract C {\n\tuint x;\n\tD d;\n\tfunction f() public {\n\t\tif (x < 4)\n\t\t\t++x;\n\t}\n\tfunction g() public {\n\t\td.d();\n\t\tassert(x < 5);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTTargets: assert\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/external_single_inc.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual;\n}\n\ncontract C {\n\tuint x;\n\tuint y;\n\tD d;\n\n\tfunction inc() public {\n\t\tif (y == 1)\n\t\t\tx = 1;\n\t\tif (x == 0)\n\t\t\ty = 1;\n\t}\n\n\tfunction f() public {\n\t\tuint oldX = x;\n\t\td.d();\n\t\tassert(oldX == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (223-240): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/internal_library_external_call_1.sol",
    "content": "interface I {\n    function i() external;\n}\n\nlibrary L {\n    function f(I _i) internal {\n        _i.i();\n    }\n}\n\ncontract C {\n    uint x;\n    bool inG;\n    function s() public {\n        require(inG);\n        x = 2;\n    }\n    function g(I _i) public {\n        inG = true;\n        L.f(_i);\n        assert(x == 0);\n        inG = false;\n    }\n}\n// ----\n// Warning 6328: (296-310): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2, inG = true\\n_i = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0, inG = false\\nC.g(0)\\n    L.f(0) -- internal call\\n        _i.i() -- untrusted external call, synthesized as:\\n            C.s() -- reentrant call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/internal_library_external_call_2.sol",
    "content": "interface I {\n    function i() external;\n}\n\nlibrary L {\n    function f(I _i) internal {\n        _i.i();\n    }\n\tfunction g(I _i) internal {\n\t\tf(_i);\n\t}\n}\n\ncontract C {\n    uint x;\n    bool inG;\n    function s() public {\n        require(inG);\n        x = 2;\n    }\n    function g(I _i) public {\n        inG = true;\n        L.g(_i);\n        assert(x == 0);\n        inG = false;\n    }\n}\n// ----\n// Warning 6328: (337-351): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/internal_library_external_call_3.sol",
    "content": "interface I {\n    function i() external;\n}\n\nlibrary M {\n    function f(I _i) internal {\n        _i.i();\n    }\n}\n\nlibrary L {\n\tfunction g(I _i) internal {\n\t\tM.f(_i);\n\t}\n}\n\ncontract C {\n    uint x;\n    bool inG;\n    function s() public {\n        require(inG);\n        x = 2;\n    }\n    function g(I _i) public {\n        inG = true;\n        L.g(_i);\n        assert(x == 0);\n        inG = false;\n    }\n}\n// ----\n// Warning 6328: (354-368): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/mutex.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual;\n}\n\ncontract C {\n\tuint x;\n\tD d;\n\n\tbool lock;\n\tmodifier mutex {\n\t\trequire(!lock);\n\t\tlock = true;\n\t\t_;\n\t\tlock = false;\n\t}\n\n\tfunction set(uint _x) mutex public {\n\t\tx = _x;\n\t}\n\n\tfunction f() mutex public {\n\t\tuint y = x;\n\t\td.d();\n\t\tassert(y == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreInv: yes\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/mutex_f_no_guard.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual;\n}\n\ncontract C {\n\tuint x;\n\tD d;\n\n\tbool lock;\n\tmodifier mutex {\n\t\trequire(!lock);\n\t\tlock = true;\n\t\t_;\n\t\tlock = false;\n\t}\n\n\tfunction set(uint _x) mutex public {\n\t\tx = _x;\n\t}\n\n\tfunction f() public {\n\t\tuint y = x;\n\t\td.d();\n\t\tassert(y == x);\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (274-288): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0, d = 0, lock = false\\ny = 1\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0, d = 0, lock = false\\nC.set(1)\\nState: x = 1, d = 0, lock = false\\nC.f()\\n    d.d() -- untrusted external call, synthesized as:\\n        C.set(0) -- reentrant call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/staticcall_mutex.sol",
    "content": "contract C {\n\tuint x;\n\n\tbool lock;\n\tmodifier mutex {\n\t\trequire(!lock);\n\t\tlock = true;\n\t\t_;\n\t\tlock = false;\n\t}\n\n\tfunction set(uint _x) mutex public {\n\t\tx = _x;\n\t}\n\n\tfunction f(address _a) mutex public {\n\t\tuint y = x;\n\t\t_a.staticcall(\"aaaaa\");\n\t\tassert(y == x); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9302: (218-240): Return value of low-level calls not used.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/staticcall_mutex_2.sol",
    "content": "contract C {\n\tuint x;\n\n\tbool lock;\n\tmodifier mutex {\n\t\trequire(!lock);\n\t\tlock = true;\n\t\t_;\n\t\tlock = false;\n\t}\n\n\tfunction set(uint _x) mutex public {\n\t\tx = _x;\n\t}\n\n\tfunction f(address _a) public {\n\t\tuint y = x;\n\t\t_a.staticcall(\"aaaaa\");\n\t\tassert(y == x); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9302: (212-234): Return value of low-level calls not used.\n// Warning 2018: (164-271): Function state mutability can be restricted to view\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/staticcall_reentrancy_view.sol",
    "content": "contract C {\n\tuint x;\n\tfunction s(uint _x) public view {\n\t\tx == _x;\n\t}\n\tfunction f(address a) public {\n\t\t(bool s, bytes memory data) = a.staticcall(\"\");\n\t\tassert(x == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2519: (106-112): This declaration shadows an existing declaration.\n// Warning 2072: (106-112): Unused local variable.\n// Warning 2072: (114-131): Unused local variable.\n// Warning 2018: (72-188): Function state mutability can be restricted to view\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/token_trusted_transfer_correct.sol",
    "content": "interface Token {\n\tfunction balanceOf(address _a) external view returns (uint);\n\tfunction transfer(address _to, uint _amt) external;\n}\n\ncontract TokenCorrect is Token {\n\tmapping (address => uint) balance;\n\tconstructor(address _a, uint _b) {\n\t\tbalance[_a] = _b;\n\t}\n\tfunction balanceOf(address _a) public view override returns (uint) {\n\t\treturn balance[_a];\n\t}\n\tfunction transfer(address _to, uint _amt) public override {\n\t\trequire(balance[msg.sender] >= _amt);\n\t\tbalance[msg.sender] -= _amt;\n\t\tbalance[_to] += _amt;\n\t}\n}\n\ncontract Test {\n\tfunction property_transfer(address _token, address _to, uint _amt) public {\n\t\trequire(_to != address(this));\n\n\t\tTokenCorrect t = TokenCorrect(_token);\n\n\t\tuint xPre = t.balanceOf(address(this));\n\t\trequire(xPre >= _amt);\n\t\tuint yPre = t.balanceOf(_to);\n\n\t\tt.transfer(_to, _amt);\n\t\tuint xPost = t.balanceOf(address(this));\n\t\tuint yPost = t.balanceOf(_to);\n\n\t\tassert(xPost == xPre - _amt);\n\t\tassert(yPost == yPre + _amt);\n\t}\n\n\tfunction test_concrete() public {\n\t\tTokenCorrect t = new TokenCorrect(address(this), 1000);\n\n\t\tuint b = t.balanceOf(address(this));\n\t\tassert(b == 1000);\n\n\t\taddress other = address(0x333);\n\t\trequire(address(this) != other);\n\n\t\tuint c = t.balanceOf(other);\n\t\tassert(c == 0);\n\n\t\tt.transfer(other, 100);\n\n\t\tuint d = t.balanceOf(address(this));\n\t\tassert(d == 900);\n\n\t\tuint e = t.balanceOf(other);\n\t\tassert(e == 100);\n\t}\n}\n// ====\n// SMTContract: Test\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/token_trusted_transfer_wrong.sol",
    "content": "interface Token {\n\tfunction balanceOf(address _a) external view returns (uint);\n\tfunction transfer(address _to, uint _amt) external;\n}\n\ncontract TokenWrong is Token {\n\tmapping (address => uint) balance;\n\tconstructor(address _a, uint _b) {\n\t\tbalance[_a] = _b;\n\t}\n\tfunction balanceOf(address _a) public view override returns (uint) {\n\t\treturn balance[_a];\n\t}\n\tfunction transfer(address _to, uint _amt) public override {\n\t\trequire(balance[msg.sender] >= _amt);\n\t\t// Commented out to make this token implementation wrong.\n\t\t//balance[msg.sender] -= _amt;\n\t\tbalance[_to] += _amt;\n\t}\n}\n\ncontract Test {\n\tfunction property_transfer(address _token, address _to, uint _amt) public {\n\t\trequire(_to != address(this));\n\n\t\tTokenWrong t = TokenWrong(_token);\n\n\t\tuint xPre = t.balanceOf(address(this));\n\t\trequire(xPre >= _amt);\n\t\tuint yPre = t.balanceOf(_to);\n\n\t\tt.transfer(_to, _amt);\n\t\tuint xPost = t.balanceOf(address(this));\n\t\tuint yPost = t.balanceOf(_to);\n\n\t\tassert(xPost == xPre - _amt); // should fail\n\t\tassert(yPost == yPre + _amt);\n\t}\n\n\tfunction test_concrete() public {\n\t\tTokenWrong t = new TokenWrong(address(this), 1000);\n\n\t\tuint b = t.balanceOf(address(this));\n\t\tassert(b == 1000);\n\n\t\taddress other = address(0x333);\n\t\trequire(address(this) != other);\n\n\t\tuint c = t.balanceOf(other);\n\t\tassert(c == 0);\n\n\t\tt.transfer(other, 100);\n\n\t\tuint d = t.balanceOf(address(this));\n\t\tassert(d == 900); // should fail\n\n\t\tuint e = t.balanceOf(other);\n\t\tassert(e == 100);\n\t}\n}\n// ====\n// SMTContract: Test\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (950-978): CHC: Assertion violation happens here.\n// Warning 6328: (1370-1386): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/external_calls/underflow_only_in_external_call.sol",
    "content": "contract C {\n\n\tuint v;\n\tbool guard = true;\n\n\tfunction dec() public returns (uint) {\n\t\trequire(!guard);\n\t\t--v;\n\t\treturn v;\n\t}\n\n\tfunction f() public returns (uint) {\n\t\tguard = false;\n\t\tuint ret = this.dec();\n\t\tguard = true;\n\t\treturn ret;\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreCex: no\n// SMTTargets: underflow\n// ----\n// Warning 3944: (105-108): CHC: Underflow (resulting value less than 0) happens here.\\nCounterexample:\\nv = 0, guard = false\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: v = 0, guard = true\\nC.f()\\n    C.dec() -- trusted external call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/abi_function_different_source.sol",
    "content": "==== Source: s1.sol ====\nfunction f() {\n\tecrecover(\"1234\", 1, \"0\", abi.decode(\"\", (bytes2)));\n}\n==== Source: s2.sol ====\ncontract C {}\n// ----\n// Warning 6133: (s1.sol:16-67): Statement has no effect.\n// Warning 2018: (s1.sol:0-70): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/abi_function_different_source_2.sol",
    "content": "==== Source: s1.sol ====\nfunction f() {\n\tecrecover(\"\", 1, \"\", \"\");\n}\n==== Source: s2.sol ====\ncontract C {}\n// ----\n// Warning 6133: (s1.sol:16-40): Statement has no effect.\n// Warning 2018: (s1.sol:0-43): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/constant_different_source.sol",
    "content": "==== Source: l.sol ====\nlibrary L {\n\tint constant one = 1;\n\tfunction f() internal {\n\t\tone;\n\t}\n}\n==== Source: s1.sol ====\nlibrary L {}\n// ----\n// Warning 6133: (l.sol:62-65): Statement has no effect.\n// Warning 2018: (l.sol:36-69): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/constant_easy.sol",
    "content": "uint constant x = 42;\n\ncontract C {\n\tfunction f() public pure {\n\t\tuint z = x;\n\t\tassert(z == 41);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (80-95): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nz = 42\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/constant_string_at_file_level.sol",
    "content": "bytes constant a = \"\\x03\\x01\\x02\";\nbytes constant b = hex\"030102\";\nstring constant c = \"hello\";\nuint256 constant x = 56;\nenum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\nActionChoices constant choices = ActionChoices.GoRight;\nbytes32 constant st = \"abc\\x00\\xff__\";\n\ncontract C {\n\tfunction f() internal pure returns (bytes memory) {\n\t\treturn a;\n\t}\n\n\tfunction g() internal pure returns (bytes memory) {\n\t\treturn b;\n\t}\n\n\tfunction h() internal pure returns (bytes memory) {\n\t\treturn bytes(c);\n\t}\n\n\tfunction i() internal pure returns (uint, ActionChoices, bytes32) {\n\t\treturn (x, choices, st);\n\t}\n\n\tfunction p() public pure {\n\t\tassert(f().length == 3); // should hold\n\t\tassert(g().length == 3); // should hold\n\t\tassert(h().length == 5); // should hold\n\t\t(uint w, ActionChoices z, bytes32 t) = i();\n\t\tassert(x == 56); // should hold\n\t\tassert(w == 56); // should hold\n\t\tassert(z == ActionChoices.GoRight); // should hold\n\t\tassert(t == \"abc\\x00\\xff__\"); // should hold\n\t\tassert(w == 59); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (968-983): CHC: Assertion violation happens here.\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/constants_at_file_level_referencing.sol",
    "content": "==== Source: s1.sol ====\n\n\nbytes constant a = b;\nbytes constant b = hex\"030102\";\n\nfunction fre() pure returns (bytes memory) {\n\treturn a;\n}\n\n==== Source: s2.sol ====\n\nimport \"s1.sol\";\n\nuint256 constant c = uint8(a[0]) + 2;\n\ncontract C {\n\tfunction f() internal pure returns (bytes memory) {\n\t\treturn a;\n\t}\n\n\tfunction g() internal pure returns (bytes memory) {\n\t\treturn b;\n\t}\n\n\tfunction h() internal pure returns (uint) {\n\t\treturn c;\n\t}\n\n\tfunction i() internal pure returns (bytes memory) {\n\t\treturn fre();\n\t}\n\n\tfunction p() public pure {\n\t\tbytes memory r1 = f();\n\t\tassert(r1[0] == 0x03); // should hold\n\t\tassert(r1[1] == 0x01); // should hold\n\t\tassert(r1[2] == 0x02); // should hold\n\t\tassert(r1[2] == 0x04); // should fail\n\n\t\tbytes memory r2 = g();\n\t\tassert(r2[0] == 0x03); // should hold\n\t\tassert(r2[1] == 0x01); // should hold\n\t\tassert(r2[2] == 0x02); // should hold\n\t\tassert(r2[2] == 0x04); // should fail\n\n\t\tbytes memory r3 = i();\n\t\tassert(r3[0] == 0x03); // should hold\n\t\tassert(r3[1] == 0x01); // should hold\n\t\tassert(r3[2] == 0x02); // should hold\n\t\tassert(r3[2] == 0x04); // should fail\n\n\t\tuint z = h();\n\t\tassert(z == 5); // should hold\n\t\tassert(z == 7); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (s2.sol:518-539): CHC: Assertion violation happens here.\n// Warning 6328: (s2.sol:704-725): CHC: Assertion violation happens here.\n// Warning 6328: (s2.sol:890-911): CHC: Assertion violation happens here.\n// Warning 6328: (s2.sol:980-994): CHC: Assertion violation happens here.\n// Info 1391: CHC: 24 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/easy.sol",
    "content": "function add(uint a, uint b) pure returns (uint) {\n\treturn a + b;\n}\n\ncontract C {\n\tfunction f(uint x) internal pure returns (uint) {\n\t\treturn add(x, 2);\n\t}\n\tfunction g() public pure {\n\t\tassert(f(7) == 9); // should hold\n\t\tassert(f(8) == 9); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (222-239): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.f(7) -- internal call\\n        add(7, 2) -- internal call\\n    C.f(8) -- internal call\\n        add(8, 2) -- internal call\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/enum.sol",
    "content": "enum E {\n\tREAD,\n\tWRITE\n}\n\nfunction allocate(bool b) pure returns (E) {\n\tif (b) return E.READ;\n\treturn E.WRITE;\n}\n\ncontract C {\n\tfunction f() public pure {\n\t\tE e1 = allocate(true);\n\t\tassert(e1 == E.READ); // should hold\n\t\tE e2 = allocate(false);\n\t\tassert(e2 == E.READ); // should fail\n\t\tassert(allocate(false) == E.WRITE); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (247-267): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/file_level_call_via_module.sol",
    "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n\tfunction f() internal pure returns (uint, uint) {\n\t\treturn (M.f(2), M.f(\"abc\"));\n\t}\n\tfunction p() public pure {\n\t\t(uint a, uint b) = f();\n\t\tassert(a == 7); // should hold\n\t\tassert(a == 9); // should fail\n\t\tassert(b == 3); // should hold\n\t\tassert(b == 5); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (b.sol:208-222): CHC: Assertion violation happens here.\n// Warning 6328: (b.sol:274-288): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/free_constant_1.sol",
    "content": "uint constant A = 42;\ncontract C {\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn x + A;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (93-98): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\\nCounterexample:\\n\\nx = 115792089237316195423570985008687907853269984665640564039457584007913129639894\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(115792089237316195423570985008687907853269984665640564039457584007913129639894)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/free_constant_2.sol",
    "content": "uint256 constant x = 56;\nenum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\nActionChoices constant choices = ActionChoices.GoRight;\nbytes32 constant st = \"abc\\x00\\xff__\";\ncontract C {\n\tfunction i() public returns (uint, ActionChoices, bytes32) {\n\t\treturn (x, choices, st);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2018: (188-278): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/free_function_1.sol",
    "content": "contract C {\n\tuint[] data;\n\tfunction f(uint x, uint[] calldata input) public view returns (uint, uint) {\n\t\t(uint a, uint[] calldata b) = fun(input, data);\n\t\treturn (a, b.length + x);\n\t}\n}\nfunction fun(uint[] calldata _x, uint[] storage _y) view  returns (uint, uint[] calldata) {\n\treturn (_y[0], _x);\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (168-180): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6368: (289-294): CHC: Out of bounds access happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/free_function_2.sol",
    "content": "contract C {\n\tfunction g() external {\n\t\tf();\n\t}\n}\nfunction f() {}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/free_function_3.sol",
    "content": "function f() view {}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/free_function_4.sol",
    "content": "function f()pure {\n\tufixed a = uint64(1) + ufixed(2);\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2072: (20-28): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/free_function_5.sol",
    "content": "contract K {}\nfunction f() pure {\n\t(abi.encode, \"\");\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (35-51): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/free_function_and_constant_1.sol",
    "content": "uint constant A = 42;\ncontract C {\n\tuint[] data;\n\tfunction f(uint x, uint[] calldata input) public view returns (uint, uint) {\n\t\t(uint a, uint[] calldata b) = fun(input, data);\n\t\treturn (a, b.length + x + A);\n\t}\n}\nfunction fun(uint[] calldata _x, uint[] storage _y) view  returns (uint, uint[] calldata) {\n\treturn (_y[0], _x);\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (190-202): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4984: (190-206): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6368: (315-320): CHC: Out of bounds access happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/free_namesake_contract_function.sol",
    "content": "function f() pure returns (uint) { return 1337; }\n\ncontract C {\n\tfunction g() public pure {\n\t\tassert(f() == 42); // should hold\n\t\tassert(f() == 1337); // should fail\n\t}\n\tfunction f() internal pure returns (uint) { return 42; }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2519: (170-226): This declaration shadows an existing declaration.\n// Warning 6328: (130-149): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/free_runtimecode.sol",
    "content": "contract C {\n\tuint public x = 2;\n}\n\nfunction test() pure returns (bool) {\n\treturn type(C).runtimeCode.length > 20;\n}\n\ncontract D {\n\tfunction f() public pure {\n\t\tassert(test()); // should hold but SMTChecker doesn't know that\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7507: (82-101): Assertion checker does not yet support this expression.\n// Warning 6328: (161-175): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nD.constructor()\\nD.f()\\n    test() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/import.sol",
    "content": "==== Source: A ====\nstruct S { uint x; }\nfunction set(S storage a, uint v) { a.x = v; }\n\n==== Source: B ====\nimport \"A\";\nimport \"A\" as A;\ncontract C {\n\tA.S data;\n\tfunction f(uint v) internal returns (uint one, uint two) {\n\t\tA.set(data, v);\n\t\tone = data.x;\n\t\tset(data, v + 1);\n\t\ttwo = data.x;\n\t}\n\tfunction g() public {\n\t\t(uint x, uint y) = f(7);\n\t\tassert(x == 7); // should hold but the SMTChecker doesn't know that\n\t\tassert(y == 8); // should hold but the SMTChecker doesn't know that\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (B:238-252): CHC: Assertion violation happens here.\n// Warning 6328: (B:308-322): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/libraries_from_free.sol",
    "content": "library L {\n\tfunction pub() public pure returns (uint) {\n\t\treturn 7;\n\t}\n\tfunction inter() internal pure returns (uint) {\n\t\treturn 8;\n\t}\n}\n\nfunction fu() pure returns (uint, uint) {\n\treturn (L.pub(), L.inter());\n}\n\ncontract C {\n\tfunction f() public pure {\n\t\t(uint x, uint y) = fu();\n\t\tassert(x == 7); // should hold but SMTChecker doesn't implement delegatecall\n\t\tassert(y == 9); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4588: (190-197): Assertion checker does not yet implement this type of function call.\n// Warning 6328: (284-298): CHC: Assertion violation happens here.\n// Warning 6328: (363-377): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/module_constants_1.sol",
    "content": "==== Source: s1.sol ====\nuint constant a = 89;\n==== Source: s2.sol ====\nuint constant a = 88;\n\n==== Source: s3.sol ====\nimport \"s1.sol\" as M;\nimport \"s2.sol\" as N;\n\ncontract C {\n\tfunction f() internal pure returns (uint, uint) {\n\t\treturn (M.a, N.a);\n\t}\n\tfunction p() public pure {\n\t\t(uint x, uint y) = f();\n\t\tassert(x == 89); // should hold\n\t\tassert(x == 88); // should fail\n\t\tassert(y == 88); // should hold\n\t\tassert(y == 89); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 6328: (s3.sol:223-238): CHC: Assertion violation happens here.\n// Warning 6328: (s3.sol:291-306): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/module_constants_functions_1.sol",
    "content": "==== Source: s1.sol ====\nuint constant a = 89;\n\nfunction fre() pure returns (uint) {\n\treturn a;\n}\n\n==== Source: s2.sol ====\nfunction foo() pure returns (uint) {\n\treturn 42;\n}\n\n==== Source: s3.sol ====\nimport {fre as foo} from \"s1.sol\";\nimport \"s1.sol\" as M;\nimport \"s2.sol\" as N;\n\nuint256 constant a = 13;\n\ncontract C {\n\tfunction f() internal pure returns (uint, uint, uint, uint) {\n\t\treturn (a, foo(), N.foo(), M.a);\n\t}\n\tfunction p() public pure {\n\t\t(uint x, uint y, uint z, uint t) = f();\n\n\t\tassert(x == 13); // should hold\n\t\tassert(x == 89); // should fail\n\n\t\tassert(y == 89); // should hold\n\t\tassert(y == 42); // should fail\n\n\t\tassert(z == 42); // should hold\n\t\tassert(z == 89); // should fail\n\n\t\tassert(t == 89); // should hold\n\t\tassert(t == 13); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (s3.sol:327-342): CHC: Assertion violation happens here.\n// Warning 6328: (s3.sol:396-411): CHC: Assertion violation happens here.\n// Warning 6328: (s3.sol:465-480): CHC: Assertion violation happens here.\n// Warning 6328: (s3.sol:534-549): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/new_operator.sol",
    "content": "contract C {\n\tuint public x = 2;\n}\n\nfunction test() returns (uint) {\n\treturn (new C()).x();\n}\n\ncontract D {\n\tfunction f() public {\n\t\tassert(test() == 2); // should hold but the SMTChecker doesn't support `new`\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8729: (78-85): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n// Warning 6328: (133-152): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nD.constructor()\\nD.f()\\n    test() -- internal call\\n        (new C()).x() -- untrusted external call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/overloads.sol",
    "content": "function f(uint) pure returns (uint) {\n\treturn 2;\n}\nfunction f(string memory) pure returns (uint) {\n\treturn 3;\n}\n\ncontract C {\n\tfunction g() public pure {\n\t\t(uint x, uint y) = (f(2), f(\"abc\"));\n\t\tassert(x == 2); // should hold\n\t\tassert(y == 4); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (229-243): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/recursion.sol",
    "content": "function exp(uint base, uint exponent) pure returns (uint power) {\n\tif (exponent == 0)\n\t\treturn 1;\n\tpower = exp(base, exponent / 2);\n\tpower *= power;\n\tif (exponent & 1 == 1)\n\t\tpower *= base;\n}\n\ncontract C {\n\tfunction g(uint base, uint exponent) internal pure returns (uint) {\n\t\treturn exp(base, exponent);\n\t}\n\tfunction f() public pure {\n\t\t// All of these should hold but the SMTChecker can't prove them.\n\t\t// Disabled because of Spacer nondet\n\t\t/*\n\t\tassert(g(0, 0) == 1);\n\t\tassert(g(0, 1) == 0);\n\t\tassert(g(1, 0) == 1);\n\t\tassert(g(2, 3) == 8);\n\t\tassert(g(3, 10) == 59049);\n\t\t*/\n\t}\n}\n// ====\n// SMTEngine: all\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/same_constants_different_files.sol",
    "content": "==== Source: s1.sol ====\n\n\nuint constant a = 89;\n\nfunction fre() pure returns (uint) {\n\treturn a;\n}\n\n==== Source: s2.sol ====\n\nimport {a as b, fre} from \"s1.sol\";\nimport \"s1.sol\" as M;\n\nuint256 constant a = 13;\n\ncontract C {\n\tfunction f() internal pure returns (uint, uint, uint, uint) {\n\t\treturn (a, fre(), M.a, b);\n\t}\n\tfunction p() public pure {\n\t\t(uint x, uint y, uint z, uint t) = f();\n\t\tassert(x == 13); // should hold\n\t\tassert(y == 89); // should hold\n\t\tassert(z == 89); // should hold\n\t\tassert(t == 89); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/file_level/struct.sol",
    "content": "struct S {\n\tuint x;\n\tuint[] a;\n}\n\nfunction allocate(uint _x, uint _f) pure returns (S memory) {\n\tS memory s;\n\ts.x = _x;\n\ts.a = new uint[](1);\n\ts.a[0] = _f;\n\treturn s;\n}\n\ncontract C {\n\tfunction f() public pure {\n\t\tS memory s = allocate(2, 1);\n\t\tassert(s.x == 2); // should hold\n\t\tassert(s.a[0] == 1); // should hold\n\t\tassert(s.x == 3); // should fail\n\t\tassert(s.a[0] == 4); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (317-333): CHC: Assertion violation happens here.\\nCounterexample:\\n\\ns = {x: 2, a: [1]}\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\\n    allocate(2, 1) -- internal call\n// Warning 6328: (352-371): CHC: Assertion violation happens here.\\nCounterexample:\\n\\ns = {x: 2, a: [1]}\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\\n    allocate(2, 1) -- internal call\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/function_selector/function_selector_via_contract_name.sol",
    "content": "contract A {\n    function f() external {}\n    function g(uint256) external {}\n}\ncontract B {\n    function f() external returns (uint256) {}\n    function g(uint256) external returns (uint256) {}\n}\ncontract C {\n    function test1() external pure returns(bytes4, bytes4, bytes4, bytes4) {\n        return (A.f.selector, A.g.selector, B.f.selector, B.g.selector);\n    }\n    function test2() external pure returns(bytes4, bytes4, bytes4, bytes4) {\n        A a; B b;\n        return (a.f.selector, a.g.selector, b.f.selector, b.g.selector);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/function_selector/function_types_sig.sol",
    "content": "contract C {\n    uint256 public x;\n\n    function f() public pure returns (bytes4) {\n        return this.f.selector;\n    }\n\n    function g() public view returns (bytes4) {\n        function () pure external returns (bytes4) fun = this.f;\n        return fun.selector;\n    }\n\n    function i() public pure returns (bytes4) {\n        return this.x.selector;\n    }\n\n    function check() public view {\n        assert(f() == 0x26121ff0);\n        assert(g() == 0x26121ff0);\n        assert(i() == 0x0c55699c);\n        assert(i() == 0x26121ff0);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7650: (251-263): Assertion checker does not yet support this expression.\n// Warning 6328: (437-462): CHC: Assertion violation happens here.\n// Warning 6328: (507-532): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/function_selector/homer.sol",
    "content": "interface ERC165 {\n    /// @notice Query if a contract implements an interface\n    /// @param interfaceID The interface identifier, as specified in ERC-165\n    /// @dev Interface identification is specified in ERC-165. This function\n    ///  uses less than 30,000 gas.\n    /// @return `true` if the contract implements `interfaceID` and\n    ///  `interfaceID` is not 0xffffffff, `false` otherwise\n    function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\ninterface Simpson {\n    function is2D() external returns (bool);\n    function skinColor() external returns (string memory);\n}\n\ninterface PeaceMaker {\n    function achieveWorldPeace() external;\n}\n\ncontract Homer is ERC165, Simpson {\n    function supportsInterface(bytes4 interfaceID) public pure override returns (bool) {\n        return\n            interfaceID == this.supportsInterface.selector || // ERC165\n            interfaceID == this.is2D.selector ^ this.skinColor.selector; // Simpson\n    }\n\n    function is2D() external pure override returns (bool) {\n        return true;\n    }\n\n    function skinColor() external pure override returns (string memory) {\n        return \"yellow\";\n    }\n\n    function check() public pure {\n        assert(supportsInterface(type(Simpson).interfaceId));\n        assert(supportsInterface(type(ERC165).interfaceId));\n        assert(supportsInterface(type(PeaceMaker).interfaceId));\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (1340-1395): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/function_selector/selector.sol",
    "content": "contract C {\n    function f() public pure {\n        assert(msg.sig == this.f.selector);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/function_selector/selector_2.sol",
    "content": "contract C {\n    function g() external pure {\n    }\n\n    function f() public pure {\n        assert(msg.sig == this.g.selector);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (92-126): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f(){ msg.sig: 0x26121ff0 }\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/function_selector/selector_3.sol",
    "content": "\ncontract C {\n    int public x;\n    int public y;\n\n    function f() public pure {\n        assert(this.x.selector != this.y.selector);\n        assert(this.x.selector == this.y.selector);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (142-184): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/abi_encode_functions.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f() public pure returns (bytes memory, bytes memory) {\n        return (abi.encode(\"\"), abi.encodePacked( \"7?8r\"));\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_base_basic.sol",
    "content": "contract A {\n\tuint x;\n\tconstructor() {\n\t\tx = 2;\n\t}\n}\n\ncontract B is A {\n\tconstructor() A() {\n\t\tx = 3;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\ncontract A is C {\n\tconstructor() C(2) {\n\t\tassert(a == 2);\n\t\tassert(a == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (120-134): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_2.sol",
    "content": "contract C { uint a; constructor(uint x) { a = x; } }\ncontract A is C { constructor() C(2) { assert(a == 2); } }\ncontract B is C { constructor() C(3) { assert(a == 3); } }\ncontract J is C { constructor() C(3) { assert(a == 4); } }\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (211-225): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_3.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\nabstract contract B is C {\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\ncontract A is B {\n\tconstructor(uint x) B(x) C(x + 2) {\n\t\tassert(a == x);\n\t\tassert(a == x + 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (171-176): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (200-218): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_4.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\nabstract contract B is C {\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\ncontract A is B {\n\tconstructor(uint x) C(x + 2) B(x + 1) {\n\t\tassert(a == x + 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (166-171): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4984: (175-180): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_diamond.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\nabstract contract B1 is C {\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\ncontract B2 is C {\n\tconstructor(uint x) C(x + 2) {\n\t\ta = x;\n\t}\n}\n\ncontract A is B2, B1 {\n\tconstructor(uint x) B2(x) B1(x) {\n\t\tassert(a == x);\n\t\tassert(a == x + 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (168-173): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (270-288): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_diamond_2.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\nabstract contract B1 is C {\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\ncontract B2 is C {\n\tconstructor(uint x) C(x + 2) {\n\t\ta = x;\n\t}\n}\n\ncontract A is B2, B1 {\n\tconstructor(uint x) B1(x) B2(x) {\n\t\tassert(a == x);\n\t\tassert(a == x + 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (168-173): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (270-288): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_diamond_3.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\nabstract contract B1 is C {\n\tuint b1;\n\tconstructor(uint x) {\n\t\tb1 = x + a;\n\t}\n}\n\ncontract B2 is C {\n\tuint b2;\n\tconstructor(uint x) C(x + 2) {\n\t\tb2 = x + a;\n\t}\n}\n\ncontract A is B2, B1 {\n\tconstructor(uint x) B2(x) B1(x) {\n\t\tassert(b1 == b2);\n\t\tassert(b1 != b2);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (193-198): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4984: (209-214): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (302-318): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_diamond_empty_middle.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor() {\n\t\ta = 2;\n\t}\n}\n\ncontract B is C {\n}\n\ncontract B2 is C {\n}\n\ncontract A is B, B2 {\n\tconstructor(uint x) {\n\t\tassert(a == 2);\n\t\tassert(a == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (132-138): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (162-176): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_diamond_empty_middle_empty_base.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor() {\n\t\ta = 2;\n\t}\n}\n\ncontract B is C {\n}\n\ncontract B2 is C {\n\tconstructor() {\n\t\tassert(a == 2);\n\t}\n}\n\ncontract A is B, B2 {\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_empty_chain.sol",
    "content": "contract F {\n\tuint a;\n\tconstructor() {\n\t\ta = 2;\n\t}\n}\n\ncontract E is F {}\ncontract D is E {}\ncontract C is D {}\ncontract B is C {}\n\ncontract A is B {\n\tconstructor(uint x) {\n\t\tassert(a == 2);\n\t\tassert(a == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (162-168): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (192-206): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_empty_middle.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor() {\n\t\ta = 2;\n\t}\n}\n\ncontract B is C {\n}\n\ncontract A is B {\n\tconstructor(uint x) B() {\n\t\tassert(a == 2);\n\t\tassert(a == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (106-112): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (140-154): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_empty_middle_no_invocation.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor() {\n\t\ta = 2;\n\t}\n}\n\ncontract B is C {\n}\n\ncontract A is B {\n\tconstructor(uint x) {\n\t\tassert(a == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (106-112): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (118-132): CHC: Assertion violation happens here.\\nCounterexample:\\na = 2\\nx = 0\\n\\nTransaction trace:\\nA.constructor(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_mixed_chain.sol",
    "content": "contract F {\n\tuint a;\n\tconstructor() {\n\t\ta = 2;\n\t}\n}\n\ncontract E is F {}\ncontract D is E {\n\tconstructor() {\n\t\ta = 3;\n\t}\n}\ncontract C is D {}\ncontract B is C {\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\n\ncontract A is B {\n\tconstructor(uint x) {\n\t\tassert(a == 4);\n\t\tassert(a == 5);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (222-228): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (252-266): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_mixed_chain_empty_base.sol",
    "content": "contract F {\n\tuint a;\n\tconstructor() {\n\t\ta = 2;\n\t}\n}\n\ncontract E is F {}\ncontract D is E {\n\tconstructor() {\n\t\ta = 3;\n\t}\n}\ncontract C is D {}\ncontract B is C {\n\tconstructor() {\n\t\tassert(a == 3);\n\t\ta = 4;\n\t}\n}\n\ncontract A is B {\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_mixed_chain_local_vars.sol",
    "content": "contract F {\n\tuint a;\n\tconstructor() {\n\t\tuint f = 2;\n\t\ta = f;\n\t}\n}\n\ncontract E is F {}\ncontract D is E {\n\tconstructor() {\n\t\tuint d = 3;\n\t\ta = d;\n\t}\n}\ncontract C is D {}\ncontract B is C {\n\tconstructor() {\n\t\tuint b = 4;\n\t\ta = b;\n\t}\n}\n\ncontract A is B {\n\tconstructor(uint x) {\n\t\tuint a1 = 4;\n\t\tuint a2 = 5;\n\t\tassert(a == a1);\n\t\tassert(a == a2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (264-270): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (325-340): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_mixed_chain_with_params.sol",
    "content": "contract F {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\nabstract contract E is F {}\nabstract contract D is E {\n\tconstructor() {\n\t\ta = 3;\n\t}\n}\nabstract contract C is D {}\ncontract B is C {\n\tconstructor(uint x) F(x + 1) {\n\t}\n}\n\ncontract A is B {\n\tconstructor(uint x) B(x) {\n\t\tassert(a == 3);\n\t\tassert(a == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (215-220): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (296-310): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_mixed_chain_with_params_2.sol",
    "content": "contract F {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\nabstract contract E is F {}\nabstract contract D is E {\n\tconstructor() {\n\t\ta = 3;\n\t}\n}\nabstract contract C is D {}\ncontract B is C {\n\tconstructor() F(1) {\n\t\tassert(a == 3);\n\t\tassert(a == 2);\n\t}\n}\n\ncontract A is B {\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (234-248): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_modifier.sol",
    "content": "contract C {\n\tuint a;\n\tmodifier n { _; a = 7; }\n\tconstructor(uint x) n {\n\t\ta = x;\n\t}\n}\n\ncontract A is C {\n\tmodifier m { a = 5; _; }\n\tconstructor() C(2) {\n\t\tassert(a == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (156-170): CHC: Assertion violation happens here.\\nCounterexample:\\na = 7\\n\\nTransaction trace:\\nA.constructor()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_hierarchy_same_var.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\ncontract A is C {\n\tconstructor() C(2) {\n\t\tassert(a == 0);\n\t\tassert(C.a == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (102-116): CHC: Assertion violation happens here.\\nCounterexample:\\na = 2\\n\\nTransaction trace:\\nA.constructor()\n// Warning 6328: (120-136): CHC: Assertion violation happens here.\\nCounterexample:\\na = 2\\n\\nTransaction trace:\\nA.constructor()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_simple.sol",
    "content": "contract C {\n\tuint x;\n\n\tconstructor() {\n\t\tassert(x == 0);\n\t\tx = 10;\n\t}\n\n\tfunction f(uint y) public view {\n\t\tassert(y == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (108-122): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_state_value.sol",
    "content": "contract C {\n\tuint x = 5;\n\n\tconstructor() {\n\t\tassert(x == 5);\n\t\tx = 10;\n\t}\n\n\tfunction f(uint y) public view {\n\t\tassert(y == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (112-126): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_state_value_inherited.sol",
    "content": "contract B {\n\tuint x = 5;\n}\n\ncontract C is B {\n\tconstructor() {\n\t\tassert(x == 5);\n\t\tx = 10;\n\t}\n\n\tfunction f(uint y) public view {\n\t\tassert(y == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (132-146): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_state_value_parameter.sol",
    "content": "contract C {\n\tuint x = 5;\n\n\tconstructor(uint a, uint b) {\n\t\tassert(x == 5);\n\t\tx = a + b;\n\t}\n\n\tfunction f(uint y) view public {\n\t\tassert(y == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (82-87): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (129-143): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/constructor_this.sol",
    "content": "contract C {\n    function f() public pure {}\n    constructor() {\n        C c = this;\n        c.f(); // this does not warn now, but should warn in the future\n        this.f();\n        (this).f();\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5805: (165-169): \"this\" used in constructor. Note that external functions of a contract cannot be called while it is being constructed.\n// Warning 5805: (184-188): \"this\" used in constructor. Note that external functions of a contract cannot be called while it is being constructed.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/free_function_multiple_contracts.sol",
    "content": "function check(uint x) pure {\n\tassert(x > 0);\n}\n\ncontract C {\n\tfunction a() public pure {\n\t\tcheck(1);\n\t}\n}\n\ncontract D {\n\tfunction b(uint x) public pure {\n\t\tcheck(x);\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (31-44): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nD.constructor()\\nD.b(0)\\n    check(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/function_call_does_not_clear_local_vars.sol",
    "content": "contract C {\n    function f() public {\n        uint a = 3;\n        this.f();\n        assert(a == 3);\n        f();\n        assert(a == 3);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5740: (122-136): Unreachable code.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/function_call_state_var_init.sol",
    "content": "contract C {\n\tuint x = f(2);\n\n\tfunction f(uint y) internal pure returns (uint) {\n\t\tassert(y > 1000);\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (83-99): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/function_external_call_should_not_inline_1.sol",
    "content": "contract State {\n\tC c;\n\tfunction f() public returns (uint) {\n\t\twhile(true)\n\t\t\tc.setOwner();\n\t}\n}\ncontract C {\n\taddress owner;\n\tfunction setOwner() public {\n\t\towner = address(0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (53-57): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/function_external_call_should_not_inline_2.sol",
    "content": "contract Other {\n\tC c;\n\tfunction h(bool b) public {\n\t\tif (b)\n\t\t\tc.setOwner(address(0));\n\t}\n}\ncontract C {\n\taddress owner;\n\tfunction setOwner(address _owner) public {\n\t\towner = _owner;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/function_inline_chain.sol",
    "content": "contract C\n{\n\tuint y;\n\n\tfunction f() public {\n\t\tif (y != 1)\n\t\t\tg();\n\t\tassert(y == 1);\n\t}\n\n\tfunction g() internal {\n\t\ty = 1;\n\t\th();\n\t}\n\n\tfunction h() internal {\n\t\tf();\n\t\tassert(y == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/function_inside_branch_modify_state_var.sol",
    "content": "contract C\n{\n\tuint x;\n\tfunction f() internal {\n\t\trequire(x < 10000);\n\t\tx = x + 1;\n\t}\n\tfunction g(bool b) public {\n\t\tx = 0;\n\t\tif (b)\n\t\t\tf();\n\t\t// Should fail for `b == true`.\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (176-190): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/function_inside_branch_modify_state_var_2.sol",
    "content": "contract C\n{\n\tuint x;\n\tfunction f() internal {\n\t\trequire(x < 10000);\n\t\tx = x + 1;\n\t}\n\tfunction g(bool b) public {\n\t\tx = 0;\n\t\tif (b)\n\t\t\tf();\n\t\telse\n\t\t\tf();\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/function_inside_branch_modify_state_var_3.sol",
    "content": "contract C\n{\n\tuint x;\n\tfunction f() internal {\n\t\trequire(x < 10000);\n\t\tx = x + 1;\n\t}\n\tfunction g(bool b) public {\n\t\tx = 0;\n\t\tif (b)\n\t\t\tf();\n\t\t// Should fail for `b == true`.\n\t\tassert(x == 0);\n\t}\n\tfunction h(bool b) public {\n\t\tx = 0;\n\t\tif (!b)\n\t\t\tf();\n\t\t// Should fail for `b == false`.\n\t\tassert(x == 0);\n\t}\n\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (176-190): CHC: Assertion violation happens here.\n// Warning 6328: (288-302): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_attached_1.sol",
    "content": "library L\n{\n\tfunction add(uint x, uint y) internal pure returns (uint) {\n\t\trequire(x < 1000);\n\t\trequire(y < 1000);\n\t\treturn x + y;\n\t}\n}\n\ncontract C\n{\n\tusing L for uint;\n\tfunction f(uint x) public pure {\n\t\tuint y = x.add(999);\n\t\tassert(y < 10000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_attached_1_fail.sol",
    "content": "library L\n{\n\tfunction add(uint x, uint y) internal pure returns (uint) {\n\t\trequire(x < 1000);\n\t\trequire(y < 1000);\n\t\treturn x + y;\n\t}\n}\n\ncontract C\n{\n\tusing L for uint;\n\tfunction f(uint x) public pure {\n\t\tuint y = x.add(999);\n\t\tassert(y < 1000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (228-244): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_external_1.sol",
    "content": "abstract contract D\n{\n\tfunction g(uint x) public virtual;\n}\n\ncontract C\n{\n\tuint x;\n\tfunction f(uint y, D d) public {\n\t\trequire(x == y);\n\t\tassert(x == y);\n\t\td.g(y);\n\t\t// Storage knowledge is cleared after an external call.\n\t\tassert(x == y);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreInv: yes\n// SMTIgnoreOS: macos\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_external_2.sol",
    "content": "abstract contract D\n{\n\tfunction g(uint x) public virtual;\n}\n\ncontract C\n{\n\tmapping (uint => uint) map;\n\tfunction f(uint y, D d) public {\n\t\trequire(map[0] == map[1]);\n\t\tassert(map[0] == map[1]);\n\t\td.g(y);\n\t\tassert(map[0] == map[1]);\n\t\tassert(map[0] == 0); // should fail\n\t}\n\n\tfunction set(uint x) public {\n\t\tmap[0] = x;\n\t\tmap[1] = x;\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreCex: yes\n// SMTSolvers: eld\n// ----\n// Warning 6328: (234-253): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_external_3.sol",
    "content": "abstract contract D\n{\n\tfunction g(uint x) public virtual;\n}\n\ncontract C\n{\n\tmapping (uint => uint) storageMap;\n\tfunction f(uint y, D d) public {\n\t\tmapping (uint => uint) storage map = storageMap;\n\t\trequire(map[0] == map[1]);\n\t\tassert(map[0] == map[1]);\n\t\td.g(y);\n\t\t// Storage knowledge is cleared after an external call.\n\t\tassert(map[0] == map[1]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_external_4.sol",
    "content": "contract C\n{\n\tfunction f(uint _x) public pure returns (uint) {\n\t\treturn _x;\n\t}\n}\n\ncontract D\n{\n\tC c;\n\tfunction g(uint _y) public view {\n\t\tuint z = c.f(_y);\n\t\tassert(z == _y);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (158-173): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_identifier_nested_tuple_1.sol",
    "content": "contract C {\n\tuint x;\n\tfunction f() public {\n\t\tx = 0;\n\t\t((inc))();\n\t\tassert(x == 1); // should hold\n\t}\n\n\tfunction inc() internal returns (uint) {\n\t\trequire(x < 100);\n\t\treturn ++x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_identifier_nested_tuple_2.sol",
    "content": "library L {\n\tstruct S {\n\t\tuint256[] data;\n\t}\n\tfunction f(S memory _s) internal pure returns (uint256) {\n\t\trequire(_s.data.length > 0);\n\t\treturn 42;\n\t}\n}\n\ncontract C {\n\tusing L for L.S;\n\tfunction f() public pure returns (uint256 y) {\n\t\tL.S memory x;\n\t\ty = (x.f)();\n\t\tassert(y == 42); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_identifier_nested_tuple_3.sol",
    "content": "contract C {\n    int[]data;\n\n    function f() public {\n        (data.pop)();\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (63-75): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\ndata = []\\n\\nTransaction trace:\\nC.constructor()\\nState: data = []\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_identity_1.sol",
    "content": "contract C\n{\n\tfunction h(uint x) public pure returns (uint) {\n\t\treturn x;\n\t}\n\tfunction g() public pure {\n\t\tuint x;\n\t\tx = h(42);\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_identity_1_fail.sol",
    "content": "contract C\n{\n\tfunction h(uint x) public pure returns (uint) {\n\t\treturn x;\n\t}\n\tfunction g() public pure {\n\t\tuint x;\n\t\tx = h(0);\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (129-142): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.h(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_identity_2.sol",
    "content": "contract C\n{\n\tfunction h(uint x) public pure returns (uint) {\n\t\treturn k(x);\n\t}\n\n\tfunction k(uint x) public pure returns (uint) {\n\t\treturn x;\n\t}\n\tfunction g() public pure {\n\t\tuint x;\n\t\tx = h(2);\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_identity_2_fail.sol",
    "content": "contract C\n{\n\tfunction h(uint x) public pure returns (uint) {\n\t\treturn k(x);\n\t}\n\n\tfunction k(uint x) public pure returns (uint) {\n\t\treturn x;\n\t}\n\tfunction g() public pure {\n\t\tuint x;\n\t\tx = h(0);\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (197-210): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.h(0) -- internal call\\n        C.k(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_identity_as_tuple.sol",
    "content": "contract C\n{\n\tfunction h(uint x) public pure returns (uint) {\n\t\treturn x;\n\t}\n\tfunction g() public pure {\n\t\tuint x;\n\t\tx = (h)(42);\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_identity_as_tuple_fail.sol",
    "content": "contract C\n{\n\tfunction h(uint x) public pure returns (uint) {\n\t\treturn x;\n\t}\n\tfunction g() public pure {\n\t\tuint x;\n\t\tx = (h)(0);\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (131-144): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.h(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_library_1.sol",
    "content": "library L\n{\n\tfunction add(uint x, uint y) internal pure returns (uint) {\n\t\trequire(x < 1000);\n\t\trequire(y < 1000);\n\t\treturn x + y;\n\t}\n}\n\ncontract C\n{\n\tfunction f(uint x) public pure {\n\t\tuint y = L.add(x, 999);\n\t\tassert(y < 10000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_library_1_fail.sol",
    "content": "library L\n{\n\tfunction add(uint x, uint y) internal pure returns (uint) {\n\t\trequire(x < 1000);\n\t\trequire(y < 1000);\n\t\treturn x + y;\n\t}\n}\n\ncontract C\n{\n\tfunction f(uint x) public pure {\n\t\tuint y = L.add(x, 999);\n\t\tassert(y < 1000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (212-228): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_library_internal.sol",
    "content": "library L {\n\tfunction value(function()internal a, uint256 b) internal {}\n}\ncontract C {\n\tusing L for function()internal;\n\n\tfunction f() public {\n\t\tfunction()internal x;\n\t\tx.value(42);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_recursive.sol",
    "content": "contract C\n{\n\tuint a;\n\tfunction g() public {\n\t\tif (a > 0)\n\t\t{\n\t\t\ta = a - 1;\n\t\t\tg();\n\t\t}\n\t\telse\n\t\t\tassert(a == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_recursive_indirect.sol",
    "content": "contract C\n{\n\tuint a;\n\tfunction f() public {\n\t\tif (a > 0)\n\t\t{\n\t\t\ta = a - 1;\n\t\t\tg();\n\t\t}\n\t\telse\n\t\t\tassert(a == 0);\n\t}\n\tfunction g() public {\n\t\tif (a > 0)\n\t\t{\n\t\t\ta = a - 1;\n\t\t\tf();\n\t\t}\n\t\telse\n\t\t\tassert(a == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_storage_var_1.sol",
    "content": "contract C\n{\n\tuint a;\n\tfunction f(uint x) public {\n\t\tuint y;\n\t\ta = (y = x);\n\t}\n\tfunction g() public {\n\t\tf(1);\n\t\tassert(a > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_storage_var_1_fail.sol",
    "content": "contract C\n{\n\tuint a;\n\tfunction f(uint x) public {\n\t\tuint y;\n\t\ta = (y = x);\n\t}\n\tfunction g() public {\n\t\tf(0);\n\t\tassert(a > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (112-125): CHC: Assertion violation happens here.\\nCounterexample:\\na = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: a = 0\\nC.g()\\n    C.f(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_storage_var_2.sol",
    "content": "contract C\n{\n\tuint a;\n\tfunction f(uint x) public {\n\t\tuint y;\n\t\ta = (y = x);\n\t}\n\tfunction g() public {\n\t\tf(1);\n\t\tf(42);\n\t\tassert(a > 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_storage_var_2_fail.sol",
    "content": "contract C\n{\n\tuint a;\n\tfunction f(uint x) public {\n\t\tuint y;\n\t\ta = (y = x);\n\t}\n\tfunction g() public {\n\t\tf(1);\n\t\tf(0);\n\t\tassert(a > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (120-133): CHC: Assertion violation happens here.\\nCounterexample:\\na = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: a = 0\\nC.g()\\n    C.f(1) -- internal call\\n    C.f(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_trivial_condition_for_only_call.sol",
    "content": "contract C\n{\n\tfunction f(bool x) public pure { for (;x;) {} }\n\tfunction g() public pure { f(true); }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_trivial_condition_if.sol",
    "content": "contract C\n{\n\tfunction f(bool x) public pure { require(x); if (x) {} }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (63-64): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_trivial_condition_require.sol",
    "content": "contract C\n{\n\tfunction f(bool x) public pure { x = true; require(x); }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (65-66): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_trivial_condition_require_only_call.sol",
    "content": "contract C\n{\n\tfunction f(bool x) public pure { require(x); }\n\tfunction g() public pure { f(true); }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/functions_trivial_condition_while_only_call.sol",
    "content": "contract C\n{\n\tfunction f(bool x) public pure { while (x) {} }\n\tfunction g() public pure { f(true); }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/address.sol",
    "content": "contract C {\n\taddress public x;\n\taddress payable public y;\n\n\tfunction f() public view {\n\t\taddress a = this.x();\n\t\taddress b = this.y();\n\t\tassert(a == x); // should hold\n\t\tassert(a == address(this)); // should fail\n\t\tassert(b == y); // should hold\n\t\tassert(y == address(this)); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (171-197): CHC: Assertion violation happens here.\n// Warning 6328: (249-275): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/array_1.sol",
    "content": "contract C {\n\tuint[] public a;\n\tconstructor() {\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t}\n\tfunction f() public view {\n\t\tuint y = this.a(2);\n\t\tassert(y == a[2]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (187-201): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/array_2.sol",
    "content": "contract C {\n\tuint[][] public a;\n\tconstructor() {\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t\ta[2].push();\n\t\ta[2].push();\n\t\ta[2].push();\n\t\ta[2].push();\n\t}\n\tfunction f() public view {\n\t\tuint y = this.a(2,3);\n\t\tassert(y == a[2][3]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (242-256): CHC: Assertion violation happens here.\\nCounterexample:\\na = [[], [], [0, 0, 0, 0]]\\ny = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: a = [[], [], [0, 0, 0, 0]]\\nC.f()\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/array_of_structs_1.sol",
    "content": "pragma abicoder v1;\nstruct Item {\n\tuint x;\n\tuint y;\n}\n\ncontract D {\n\tItem[][][] public items;\n\n\tfunction test() public view returns (uint) {\n\t\t(uint a, uint b) = this.items(1, 2, 3);\n\t\treturn a + b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/array_of_structs_2.sol",
    "content": "pragma abicoder v1;\nstruct Item {\n\tuint x;\n\tuint y;\n}\n\ncontract D {\n\tItem[] public items;\n\n\tfunction test() public {\n\t\tdelete items;\n\t\titems.push(Item(42, 43));\n\t\t(uint a, uint b) = this.items(0);\n\t\tassert(a == 42); // should hold\n\t\tassert(b == 43); // should hold\n\t\tassert(b == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// Warning 6328: (267-281): CHC: Assertion violation happens here.\\nCounterexample:\\nitems = [{x: 42, y: 43}]\\na = 42\\nb = 43\\n\\nTransaction trace:\\nD.constructor()\\nState: items = []\\nD.test()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/array_of_structs_3.sol",
    "content": "pragma abicoder v1;\nstruct Item {\n\tuint x;\n\tuint y;\n\tuint[] arr;\n}\n\ncontract D {\n\tItem[] public items;\n\n\tfunction test() public {\n\t\tdelete items;\n\t\tuint[] memory tmp = new uint[](1);\n\t\titems.push(Item(42, 43, tmp));\n\t\t(uint a, uint b) = this.items(0);\n\t\tassert(a == 42); // should hold\n\t\tassert(b == 43); // should hold\n\t\tassert(b == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// Warning 6328: (322-336): CHC: Assertion violation happens here.\\nCounterexample:\\nitems = [{x: 42, y: 43, arr: [0]}]\\ntmp = [0]\\na = 42\\nb = 43\\n\\nTransaction trace:\\nD.constructor()\\nState: items = []\\nD.test()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/bytes.sol",
    "content": "contract C {\n\tbytes public str2 = 'c';\n\n\tfunction f() public view {\n\t\tbytes memory a2 = this.str2();\n\t\tassert(keccak256(a2) == keccak256(str2)); // should hold\n\t\tassert(keccak256(a2) == keccak256('a')); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (162-201): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/contract.sol",
    "content": "contract D {}\n\ncontract C {\n\tD public d;\n\n\tfunction f() public view {\n\t\tD e = this.d();\n\t\tassert(e == d); // should hold\n\t\tassert(address(e) == address(this)); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9170: (97-103): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// Warning 6328: (123-158): CHC: Assertion violation happens here.\\nCounterexample:\\nd = 0\\ne = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: d = 0\\nC.f()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/double_access.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint u;\n\t}\n\n\tS public s;\n\n\tfunction f() public view {\n\t\tuint u = this.s();\n\t\tuint v = this.s();\n\t\tassert(u == s.u); // should hold\n\t\tassert(u == v); // should hold\n\t\tassert(u == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (193-207): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/enum.sol",
    "content": "\ncontract C {\n\tenum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }\n\tActionChoices public choice;\n\n\tfunction f() public view {\n\t\tActionChoices e = this.choice();\n\t\tassert(e == choice); // should hold\n\t\tassert(e == ActionChoices.SitStill); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (210-245): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/external_getter_1.sol",
    "content": "contract D {\n\tuint public d;\n\tfunction g() public {\n\t\t++d;\n\t}\n}\n\ncontract C {\n\tfunction f() public {\n\t\tD a = new D();\n\t\tassert(a.d() == 0); // should hold\n\t\ta.g();\n\t\tassert(a.d() == 1); // should hold\n\t\tassert(a.d() == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (203-221): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/external_getter_2.sol",
    "content": "contract E {\n\tuint public e;\n\tfunction setE(uint _e) public {\n\t\te = _e;\n\t}\n}\n\ncontract D {\n\tE e;\n\tconstructor(E _e) {\n\t\te = _e;\n\t}\n\tfunction setE(uint x) public {\n\t\te.setE(x);\n\t}\n}\n\ncontract C {\n\tfunction f() public {\n\t\tE e = new E();\n\t\tD d = new D(e);\n\t\tassert(e.e() == 0); // should hold\n\t\td.setE(42);\n\t\tassert(e.e() == 42); // should hold\n\t\tassert(e.e() == 2); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTTargets: assert\n// ----\n// Warning 6328: (344-362): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/external_getter_this_1.sol",
    "content": "contract C {\n\tuint public x;\n\n\tfunction f() public {\n\t\tx = 2;\n\t\tx = 3;\n\t\tuint y = this.x();\n\t\tassert(y == 3); // should hold\n\t\tassert(y == 2); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreCex: yes\n// SMTTargets: assert\n// ----\n// Warning 6328: (127-141): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/external_getter_this_2.sol",
    "content": "contract C {\n\tuint public x;\n\n\tfunction f() public {\n\t\tx = 2;\n\t\tx = 3;\n\t\tC c = this;\n\t\tuint y = c.x();\n\t\tassert(y == 3); // should hold\n\t\tassert(y == 2); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// SMTIgnoreCex: yes\n// SMTTargets: assert\n// ----\n// Warning 6328: (138-152): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/fixed_bytes.sol",
    "content": "contract C {\n\tbytes1 public x;\n\tbytes3 public y;\n\n\tfunction f() public view {\n\t\tbytes1 a = this.x();\n\t\tbytes3 b = this.y();\n\t\tassert(a == x); // should hold\n\t\tassert(a == 'a'); // should fail\n\t\tassert(b == y); // should hold\n\t\tassert(y == \"abc\"); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (159-175): CHC: Assertion violation happens here.\n// Warning 6328: (227-245): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/function.sol",
    "content": "contract C {\n\tfunction () external returns (uint) public g;\n\n\tfunction f() public {\n\t\tg = this.X;\n\t\tfunction () external returns (uint) e = this.g();\n\t\tassert(e() == g()); // should hold, but fails because of the lack of support for tracking function pointers\n\t\tassert(e() == 1); // should fail\n\t}\n\n\tfunction X() public pure returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8364: (140-146): Assertion checker does not yet implement type function () view external returns (function () external returns (uint256))\n// Warning 6328: (152-170): CHC: Assertion violation happens here.\n// Warning 6328: (262-278): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/inaccessible_dynamic_type_1.sol",
    "content": "contract C {\n\tstruct S {\n\t\tstring a;\n\t\tuint256 y;\n\t}\n\tS public s;\n\tfunction g() public view returns (uint256) {\n\t\tthis.s();\n\t}\n}\n// ====\n// SMTEngine: all\n// EVMVersion: <=spuriousDragon\n// ----\n// Warning 6321: (101-108): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/inaccessible_dynamic_type_2.sol",
    "content": "contract C {\n\tfunction f() public returns(bool[]memory) {\n\t\tthis.f();\n\t}\n}\n// ====\n// SMTEngine: all\n// EVMVersion: <=spuriousDragon\n// ----\n// Warning 6321: (42-54): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/inaccessible_dynamic_type_3.sol",
    "content": "contract C {\n\tstruct S {\n\t\tstring a;\n\t}\n\tS public s;\n\tfunction g() public view returns (uint256) {\n\t\tthis.s();\n\t}\n}\n// ====\n// SMTEngine: all\n// EVMVersion: <=spuriousDragon\n// ----\n// Warning 6321: (88-95): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/inaccessible_dynamic_type_4.sol",
    "content": "contract C {\n\tstring public s;\n\tfunction g() public view returns (uint256) {\n\t\tthis.s();\n\t}\n}\n// ====\n// SMTEngine: all\n// EVMVersion: <=spuriousDragon\n// ----\n// Warning 6321: (66-73): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/mapping_1.sol",
    "content": "contract C {\n\tmapping (uint => uint) public map;\n\n\tfunction f() public view {\n\t\tuint y = this.map(2);\n\t\tassert(y == map[2]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (142-156): CHC: Assertion violation happens here.\\nCounterexample:\\n\\ny = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/mapping_2.sol",
    "content": "contract C {\n\tmapping (uint => mapping (uint => uint)) public map;\n\n\tfunction f() public view {\n\t\tuint y = this.map(2, 3);\n\t\tassert(y == map[2][3]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (166-180): CHC: Assertion violation happens here.\\nCounterexample:\\n\\ny = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/mapping_with_cast.sol",
    "content": "contract C {\n\tmapping (bytes16 => uint) public m;\n\n\tfunction f() public view {\n\t\tuint y = this.m(\"foo\");\n\t\tassert(y == m[\"foo\"]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (147-161): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_1.sol",
    "content": "contract C {\n\tmapping (uint => uint[]) public m;\n\n\tconstructor() {\n\t\tm[0].push();\n\t\tm[0].push();\n\t\tm[0][1] = 42;\n\t}\n\n\tfunction f() public view {\n\t\tuint y = this.m(0,1);\n\t\tassert(y == m[0][1]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (210-224): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_10.sol",
    "content": "contract C {\n\tmapping (uint => uint[])[] public m;\n\n\tconstructor() {\n\t\tm.push();\n\t\tm[0][1].push();\n\t\tm[0][1].push();\n\t\tm[0][1].push();\n\t\tm[0][1][2] = 42;\n\t}\n\n\tfunction f() public view {\n\t\tuint y = this.m(0,1,2);\n\t\tassert(y == m[0][1][2]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (256-270): CHC: Assertion violation happens here.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_2.sol",
    "content": "contract C {\n\tmapping (uint => uint[][]) public m;\n\n\tconstructor() {\n\t\tm[0].push();\n\t\tm[0].push();\n\t\tm[0][1].push();\n\t\tm[0][1].push();\n\t\tm[0][1].push();\n\t\tm[0][1][2] = 42;\n\t}\n\n\tfunction f() public view {\n\t\tuint y = this.m(0,1,2);\n\t\tassert(y == m[0][1][2]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (274-288): CHC: Assertion violation happens here.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_3.sol",
    "content": "contract C {\n\tmapping (uint => uint[][][]) public m;\n\n\tconstructor() {\n\t\tm[0].push();\n\t\tm[0].push();\n\t\tm[0][1].push();\n\t\tm[0][1].push();\n\t\tm[0][1].push();\n\t\tm[0][1][2].push();\n\t\tm[0][1][2].push();\n\t\tm[0][1][2].push();\n\t\tm[0][1][2].push();\n\t\tm[0][1][2][3] = 42;\n\t}\n\n\tfunction f() public view {\n\t\tuint y = this.m(0,1,2,3);\n\t\tassert(y == m[0][1][2][3]); // should hold\n\t\t// Disabled because of Spacer seg fault\n\t\t//assert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 18 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_4.sol",
    "content": "contract C {\n\tmapping (uint => mapping (uint => uint[])) public m;\n\n\tconstructor() {\n\t\tm[0][1].push();\n\t\tm[0][1].push();\n\t\tm[0][1].push();\n\t\tm[0][1][2] = 42;\n\t}\n\n\tfunction f() public view {\n\t\tuint y = this.m(0,1,2);\n\t\tassert(y == m[0][1][2]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (260-274): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_5.sol",
    "content": "contract C {\n\tmapping (uint => mapping (uint => uint[][])) public m;\n\n\tconstructor() {\n\t\tm[0][1].push();\n\t\tm[0][1].push();\n\t\tm[0][1].push();\n\t\tm[0][1][2].push();\n\t\tm[0][1][2].push();\n\t\tm[0][1][2].push();\n\t\tm[0][1][2].push();\n\t\tm[0][1][2][3] = 42;\n\t}\n\n\tfunction f() public view {\n\t\tuint y = this.m(0,1,2,3);\n\t\tassert(y == m[0][1][2][3]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (354-368): CHC: Assertion violation happens here.\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_6.sol",
    "content": "contract C {\n\tmapping (uint => mapping (uint => mapping (uint => uint[]))) public m;\n\n\tconstructor() {\n\t\tm[0][1][2].push();\n\t\tm[0][1][2].push();\n\t\tm[0][1][2].push();\n\t\tm[0][1][2].push();\n\t\tm[0][1][2][3] = 42;\n\t}\n\n\tfunction f() public view {\n\t\tuint y = this.m(0,1,2,3);\n\t\tassert(y == m[0][1][2][3]); // should hold\n\t\t// Disabled because Spacer seg faults\n\t\t//assert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_7.sol",
    "content": "contract C {\n\tmapping (uint => uint)[] public m;\n\n\tconstructor() {\n\t\tm.push();\n\t\tm[0][1] = 42;\n\t}\n\n\tfunction f() public view {\n\t\tuint y = this.m(0,1);\n\t\tassert(y == m[0][1]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (192-206): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_8.sol",
    "content": "contract C {\n\tmapping (uint => uint)[][] public m;\n\n\tconstructor() {\n\t\tm.push();\n\t\tm[0].push();\n\t\tm[0].push();\n\t\tm[0][1][2] = 42;\n\t}\n\n\tfunction f() public view {\n\t\tuint y = this.m(0,1,2);\n\t\tassert(y == m[0][1][2]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (232-246): CHC: Assertion violation happens here.\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/nested_arrays_mappings_9.sol",
    "content": "contract C {\n\tmapping (uint => mapping (uint => uint))[] public m;\n\n\tconstructor() {\n\t\tm.push();\n\t\tm[0][1][2] = 42;\n\t}\n\n\tfunction f() public view {\n\t\tuint y = this.m(0,1,2);\n\t\tassert(y == m[0][1][2]); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (218-232): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/static_array.sol",
    "content": "\ncontract C {\n\n\tuint[2] public x = [42,1];\n\n\tfunction f() public view {\n\t\tassert(this.x(0) == x[0]); // should hold\n\t\tassert(this.x(1) == x[1]); // should hold\n\t\tassert(this.x(0) == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (162-184): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/string.sol",
    "content": "contract C {\n\tstring public str1 = 'b';\n\n\tfunction f() public view {\n\t\tstring memory a1 = this.str1();\n\t\tassert(keccak256(bytes(a1)) == keccak256(bytes(str1))); // should hold\n\t\tassert(keccak256(bytes(a1)) == keccak256('a')); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (178-224): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/struct_1.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct T {\n\t\tuint t;\n\t}\n\tstruct S {\n\t\tuint x;\n\t\tT t;\n\t\tbool b;\n\t\tuint[] a;\n\t}\n\n\tS public s;\n\n\tfunction f() public view {\n\t\tuint y;\n\t\tbool c;\n\t\tT memory t;\n\t\t(y,t,c) = this.s();\n\t\tassert(y == s.x); // this should hold\n\t\tassert(c == s.b); // this should hold\n\t\tassert(t.t == s.t.t); // this should hold\n\t\tassert(c == true); // this should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (338-355): CHC: Assertion violation happens here.\\nCounterexample:\\ns = {x: 0, t: {t: 0}, b: false, a: []}\\ny = 0\\nc = false\\nt = {t: 0}\\n\\nTransaction trace:\\nC.constructor()\\nState: s = {x: 0, t: {t: 0}, b: false, a: []}\\nC.f()\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/struct_2.sol",
    "content": "//pragma abicoder v2;\n\ncontract C {\n\tstruct S {\n\t\tuint[2] a;\n\t\tuint u;\n\t}\n\n\tS public s;\n\n\tfunction f() public view {\n\t\tuint u = this.s();\n\t\tassert(u == s.u); // should hold\n\t\tassert(u == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (175-189): CHC: Assertion violation happens here.\\nCounterexample:\\ns = {a: [0, 0], u: 0}\\nu = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: s = {a: [0, 0], u: 0}\\nC.f()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/struct_3.sol",
    "content": "contract C {\n\tstruct S {\n\t\tstring s;\n\t\tbytes b;\n\t}\n\n\tS public m;\n\n\tconstructor() {\n\t\tm.s = \"foo\";\n\t\tm.b = \"bar\";\n\t}\n\n\tfunction f() public view {\n\t\t(string memory s, bytes memory b) = this.m();\n\t\tassert(keccak256(bytes(s)) == keccak256(bytes(m.s))); // should hold\n\t\tassert(b[0] == m.b[0]); // should hold\n\t\tassert(b[0] == \"t\"); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (307-326): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/struct_4.sol",
    "content": "contract D {\n}\n\ncontract C {\n\tstruct S {\n\t\tD d;\n\t\tfunction () external returns (uint) f;\n\t}\n\n\tS public s;\n\n\tfunction test() public view {\n\t\t(D d, function () external returns (uint) f) = this.s();\n\t\tassert(d == s.d); // should hold\n\t\tassert(address(d) == address(this)); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9170: (206-214): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// Warning 2072: (146-183): Unused local variable.\n// Warning 8364: (187-193): Assertion checker does not yet implement type function () view external returns (contract D,function () external returns (uint256))\n// Warning 6328: (234-269): CHC: Assertion violation happens here.\\nCounterexample:\\ns = {d: 0, f: 0}\\nd = 0\\nf = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: s = {d: 0, f: 0}\\nC.test()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/struct_with_reassignment.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tbool b;\n\t}\n\n\tS public s;\n\n\tconstructor() {\n\t\ts.x = 1;\n\t\ts.b = false;\n\t}\n\n\tfunction f() public {\n\t\tuint x;\n\t\tbool b;\n\t\t(x,b) = this.s();\n\t\tassert(x == s.x); // this should hold\n\t\tassert(b == s.b); // this should hold\n\t\tassert(b == true); // this should fail\n\t\ts.x = 42;\n\t\t(uint y, bool c) = this.s();\n\t\tassert(c == b); // this should hold\n\t\tassert(y == x); // this should fail\n\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (255-272): CHC: Assertion violation happens here.\\nCounterexample:\\ns = {x: 1, b: false}\\nx = 1\\nb = false\\ny = 0\\nc = false\\n\\nTransaction trace:\\nC.constructor()\\nState: s = {x: 1, b: false}\\nC.f()\n// Warning 6328: (377-391): CHC: Assertion violation happens here.\\nCounterexample:\\ns = {x: 42, b: false}\\nx = 1\\nb = false\\ny = 42\\nc = false\\n\\nTransaction trace:\\nC.constructor()\\nState: s = {x: 1, b: false}\\nC.f()\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/getters/uint.sol",
    "content": "contract C {\n\tuint public x;\n\n\tfunction f() public view {\n\t\tuint y = this.x();\n\t\tassert(y == x); // should hold\n\t\tassert(y == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (114-128): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\ny = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.f()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/internal_call_inheritance.sol",
    "content": "contract C {\n\tfunction c() public pure returns (uint) { return 42; }\n}\n\ncontract B is C {\n\tfunction b() public pure returns (uint) { return c(); }\n}\n\ncontract A is B {\n\tuint public x;\n\n\tfunction a() public {\n\t\tx = b();\n\t\tassert(x < 40);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (221-235): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 42\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.a()\\n    B.b() -- internal call\\n        C.c() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/internal_call_state_var_init.sol",
    "content": "contract c {\n\tbool b = (f() == 0) && (f() == 0);\n\tfunction f() internal returns (uint) {}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/internal_call_state_var_init_2.sol",
    "content": "contract c {\n\tuint x;\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t}\n\tbool b = (f() > 0) || (f() > 0);\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (54-58): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_1.sol",
    "content": "contract C{\n    uint x;\n\tconstructor(uint y) {\n\t\tassert(x == 0);\n\t\tx = 1;\n\t}\n    function f() public {\n\t\tassert(x == 1);\n\t\t++x;\n\t\tg();\n\t\tassert(x == 1);\n    }\n\n\tfunction g() internal {\n\t\tassert(x == 2);\n\t\t--x;\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 5667: (37-43): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_1_fail.sol",
    "content": "contract C{\n    uint x;\n\tconstructor(uint y) {\n\t\tassert(x == 1);\n\t\tx = 1;\n\t}\n    function f() public {\n\t\tassert(x == 2);\n\t\t++x;\n\t\tg();\n\t\tassert(x == 2);\n    }\n\n\tfunction g() internal {\n\t\tassert(x == 3);\n\t\t--x;\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (37-43): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (49-63): CHC: Assertion violation happens here.\n// Warning 6328: (105-119): CHC: Assertion violation happens here.\n// Warning 6328: (137-151): CHC: Assertion violation happens here.\n// Warning 6328: (187-201): CHC: Assertion violation happens here.\n// Warning 6328: (212-226): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_inheritance_1.sol",
    "content": "contract A {\n\tuint x;\n\tfunction f() internal {\n\t\tassert(x == 1);\n\t\t--x;\n\t}\n}\n\ncontract C is A {\n\tconstructor() {\n\t\tassert(x == 0);\n\t\t++x;\n\t\tf();\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/internal_call_with_assertion_inheritance_1_fail.sol",
    "content": "contract A {\n\tuint x;\n\tfunction f() internal {\n\t\tassert(x == 2);\n\t\t--x;\n\t}\n}\n\ncontract C is A {\n\tconstructor() {\n\t\tassert(x == 1);\n\t\t++x;\n\t\tf();\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (49-63): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1\\n\\nTransaction trace:\\nC.constructor()\n// Warning 6328: (115-129): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\n// Warning 6328: (147-161): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/internal_multiple_calls_with_assertion_1.sol",
    "content": "contract C{\n    uint x;\n\tconstructor(uint y) {\n\t\tassert(x == 0);\n\t\tx = 1;\n\t}\n    function f() public {\n\t\tassert(x == 1);\n\t\t++x;\n\t\t++x;\n\t\tg();\n\t\tg();\n\t\tassert(x == 1);\n    }\n\n\tfunction g() internal {\n\t\t--x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (37-43): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/internal_multiple_calls_with_assertion_1_fail.sol",
    "content": "contract C{\n    uint x;\n\tconstructor(uint y) {\n\t\tassert(x == 1);\n\t\tx = 1;\n\t}\n    function f() public {\n\t\tassert(x == 2);\n\t\t++x;\n\t\t++x;\n\t\tg();\n\t\tg();\n\t\tassert(x == 3);\n    }\n\n\tfunction g() internal {\n\t\t--x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (37-43): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (49-63): CHC: Assertion violation happens here.\n// Warning 6328: (105-119): CHC: Assertion violation happens here.\n// Warning 6328: (151-165): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/library_after_contract.sol",
    "content": "contract C {\n\tfunction g(uint y) public {\n\t\tuint z = L.f(y);\n\t\tassert(z == y);\n\t}\n}\n\nlibrary L {\n\tfunction f(uint x) internal returns (uint) {\n\t\treturn x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2018: (98-157): Function state mutability can be restricted to pure\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/library_constant.sol",
    "content": "library l1 {\n\n\tuint private constant TON = 1000;\n\tfunction f1() public pure {\n\t\tassert(TON == 1000);\n\t\tassert(TON == 2000);\n\t}\n\tfunction f2(uint x, uint y) internal pure returns (uint) {\n\t\treturn x + y;\n\t}\n}\n\ncontract C {\n\tfunction f(uint x) public pure {\n\t\tuint z = l1.f2(x, 1);\n\t\tassert(z == x + 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (103-122): CHC: Assertion violation happens here.\\nCounterexample:\\nTON = 1000\\n\\nTransaction trace:\\nl1.constructor()\\nState: TON = 1000\\nl1.f1()\n// Warning 4984: (196-201): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\\nCounterexample:\\n\\nx = 115792089237316195423570985008687907853269984665640564039457584007913129639935\\n\\nTransaction trace:\\nC.constructor()\\nC.f(115792089237316195423570985008687907853269984665640564039457584007913129639935)\\n    l1.f2(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1) -- internal call\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/library_constant_2.sol",
    "content": "library l1 {\n\n\tuint private constant TON = 1000;\n\tfunction f1() public pure {\n\t\tassert(TON == 1000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/library_public_called_as_internal_1.sol",
    "content": "library L {\n    function f1(uint x) public pure {\n        assert(x > 0); // should fail\n    }\n    function f(uint x) internal pure { f1(x); }\n}\n\ncontract C {\n    function g(uint x) external pure {\n        // This should trigger the assertion failure\n        // since it calls `f` internally, which calls\n        // `f1` internally.\n        return L.f(x);\n    }\n\n    function h(uint x) external pure {\n        // This should not trigger the assertion failure\n        // since it delegatecalls and that's not supported.\n        return L.f1(x);\n    }\n}\n// ====\n// SMTContract: C\n// ----\n// Warning 4588: (533-540): Assertion checker does not yet implement this type of function call.\n// Warning 6328: (58-71): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.g(0)\\n    L.f(0) -- internal call\\n        L.f1(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/library_public_called_as_internal_2.sol",
    "content": "library L {\n    function f1(uint x) public pure {\n        assert(x > 0); // should fail\n    }\n    function f() internal pure {\n        f1(0); // should cause the assertion in `f1` to fail\n    }\n    function g() internal pure {\n        f1(1); // should not cause the assertion in `f1` to fail\n    }\n}\n\ncontract C {\n    function f() external pure {\n        return L.f(); // should cause the assertion to fail\n    }\n    function g() external pure {\n        return L.g(); // should not cause the assertion to fail\n    }\n}\n// ====\n// SMTContract: C\n// ----\n// Warning 6328: (58-71): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\\n    L.f() -- internal call\\n        L.f1(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/payable_1.sol",
    "content": "contract C {\n\tfunction g() external {\n\t\tf();\n\t}\n\n\tfunction h() external payable {\n\t\tf();\n\t}\n\n\tfunction f() internal {\n\t\trequire(msg.value == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/payable_2.sol",
    "content": "contract C {\n\tfunction g() external {\n\t\tf();\n\t\th();\n\t\ti();\n\t}\n\n\tfunction g2() external payable {\n\t\ti();\n\t}\n\n\tfunction f() internal {\n\t\trequire(msg.value == 0);\n\t}\n\n\tfunction h() internal {\n\t\tassert(msg.value == 0); // should hold\n\t}\n\n\tfunction i() internal {\n\t\tassert(msg.value == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (261-283): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/recursive_multi_return.sol",
    "content": "contract C {\n\tfunction g() public pure returns (uint, uint) {\n\t\tuint a;\n\t\tuint b;\n\t\t(a, b) = g();\n\t}\n}\n//\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/recursive_multi_return_2.sol",
    "content": "contract c { function f() public pure {22237625-86535-0+1;\n    555565-3*51;\n}\n}contract C {\n\tfunction g() public pure returns (\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\nint, uint, bytes14) {\n\t\tuint\na;\n\t\tuint b;\n\t\t(,,,,,,,a,b,,,,) = g();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (39-57): Statement has no effect.\n// Warning 6133: (63-74): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/super_function_assert.sol",
    "content": "contract A {\n\tint x = 0;\n\n\tfunction f() virtual internal {\n\t\tx = 2;\n\t}\n\n\tfunction proxy() public {\n\t\tf();\n\t}\n}\n\ncontract C is A {\n\tfunction f() internal virtual override {\n\t\tsuper.f();\n\t\tassert(x == 2);\n\t\tassert(x == 3); // should fail\n\t}\n}\n\ncontract D is C {\n\n\tfunction f() internal override {\n\t\tsuper.f();\n\t\tassert(x == 2);\n\t\tassert(x == 3); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (205-219): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nA.proxy()\\n    C.f() -- internal call\\n        A.f() -- internal call\n// Warning 6328: (328-342): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n\\nTransaction trace:\\nD.constructor()\\nState: x = 0\\nA.proxy()\\n    D.f() -- internal call\\n        C.f() -- internal call\\n            A.f() -- internal call\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/this_external_call.sol",
    "content": "contract C\n{\n\tuint x;\n\tfunction f(uint y) public {\n\t\tx = y;\n\t}\n\tfunction g(uint y) public {\n\t\trequire(y < 1000);\n\t\tthis.f(y);\n\t\tassert(x < 1000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/this_external_call_2.sol",
    "content": "contract C {\n    uint a;\n    function f(uint x) public {\n        this.g(x);\n        assert(a == x);\n        assert(a != 42);\n    }\n\n    function g(uint x) public {\n        a = x;\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (108-123): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/this_external_call_return.sol",
    "content": "contract C\n{\n\tuint x;\n\tfunction f(uint y) public returns (uint) {\n\t\tx = y;\n\t\treturn x;\n\t}\n\tfunction g(uint y) public {\n\t\trequire(y < 1000);\n\t\tuint z = this.f(y);\n\t\tassert(z < 1000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/this_external_call_sender.sol",
    "content": "contract C {\n    address lastCaller;\n\n    constructor() {\n        lastCaller = msg.sender;\n    }\n\n    modifier log {\n        lastCaller = msg.sender;\n        _;\n    }\n\n    function test() log public {\n        assert(lastCaller == msg.sender);\n        this.g();\n        assert(lastCaller == address(this));\n        assert(lastCaller == msg.sender);\n        assert(lastCaller == address(0));\n    }\n\n    function g() log public {\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (314-346): CHC: Assertion violation happens here.\n// Warning 6328: (356-388): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/this_external_call_tx_origin.sol",
    "content": "contract C {\n\n\tfunction test() view public {\n\t\trequire(address(this) != tx.origin);\n\t\tassert(!this.g());\n\t}\n\n\tfunction g() view public returns (bool) {\n\t\treturn msg.sender == tx.origin;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/this_state.sol",
    "content": "contract C\n{\n\tuint public x;\n\tfunction g() public {\n\t\tx = 0;\n\t\tthis.h();\n\t\tassert(x == 2);\n\t}\n\tfunction h() public {\n\t\tx = 2;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/virtual_function_assert.sol",
    "content": "contract A {\n    int x = 0;\n\n    function f() virtual internal view {\n        assert(x == 0);\n    }\n\n    function proxy() public view {\n        f();\n    }\n}\n\ncontract C is A {\n\n    function f() internal view override {\n        assert(x == 1);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (227-241): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/functions/virtual_function_called_by_constructor.sol",
    "content": "contract A {\n    uint public x;\n    function v() internal virtual {\n        x = 2;\n    }\n    constructor() {\n        v();\n    }\n\tfunction i() public view virtual {\n\t\tassert(x == 2); // should hold\n\t\tassert(x == 10); // should fail\n\t}\n}\n\ncontract C is A {\n    function v() internal override {\n        x = 10;\n    }\n\tfunction i() public view override {\n\t\tassert(x == 10); // should hold\n\t\tassert(x == 2); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (199-214): CHC: Assertion violation happens here.\n// Warning 6328: (387-401): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/ExtCall.sol",
    "content": "==== Source: ExtCall.sol ====\ninterface Unknown {\n    function callme() external;\n}\n\ncontract ExtCall {\n    uint x;\n\n    bool lock;\n    modifier mutex {\n        require(!lock);\n        lock = true;\n        _;\n        lock = false;\n    }\n\n    function setX(uint y) mutex public {\n        x = y;\n    }\n\n    function xMut(Unknown u) public {\n        uint x_prev = x;\n        u.callme();\n        assert(x_prev == x);\n    }\n}\n==== Source: ExtCall.t.sol ====\nimport \"ExtCall.sol\";\n\ncontract ExtCallTest {\n    ExtCall call;\n\n    function setUp() public {\n        call = new ExtCall();\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (ExtCall.sol:362-381): CHC: Assertion violation happens here.\n// Warning 8729: (ExtCall.t.sol:110-123): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/duplicated_errors_1.sol",
    "content": "==== Source: a.sol ====\ncontract A {\n\tuint x;\n}\n==== Source: b.sol ====\nimport \"a.sol\";\ncontract B is A {\n\tfunction g() public view { assert(x > x); }\n}\n==== Source: c.sol ====\nimport \"b.sol\";\ncontract C is B {\n\tfunction h(uint x) public pure { assert(x < x); }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: smtlib2\n// ----\n// Warning 6328: (b.sol:62-75): CHC: Assertion violation might happen here.\n// Warning 3996: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled.\n// Warning 7812: (b.sol:62-75): BMC: Assertion violation might happen here.\n// Warning 8084: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.\n// Warning 6328: (c.sol:68-81): CHC: Assertion violation might happen here.\n// Warning 3996: CHC analysis was not possible. No Horn solver was available. None of the installed solvers was enabled.\n// Warning 7812: (c.sol:68-81): BMC: Assertion violation might happen here.\n// Warning 8084: BMC analysis was not possible. No SMT solver (Z3 or cvc5) was available. None of the installed solvers was enabled.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/import_as_module_1.sol",
    "content": "==== Source: A ====\nimport \"s1.sol\" as M;\ncontract D is M.C {\n\tfunction f(uint _y) public {\n\t\tg(_y);\n\t\tassert(x == _y); // should hold\n\t\tassert(x > 100); // should fail\n\t}\n}\n==== Source: s1.sol ====\ncontract C {\n\tuint x;\n\tfunction g(uint _x) public {\n\t\tx = _x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (A:117-132): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/import_as_module_2.sol",
    "content": "==== Source: A ====\nimport \"s1.sol\" as M;\nfunction f(uint _x) pure {\n\tassert(_x > 0);\n}\ncontract D {\n\tfunction g(uint _y) public pure {\n\t\tM.f(200); // should hold\n\t\tM.f(_y); // should fail\n\t\tf(10); // should hold\n\t\tf(_y); // should fail\n\t}\n}\n==== Source: s1.sol ====\nfunction f(uint _x) pure {\n\tassert(_x > 100);\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (A:50-64): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n_y = 0\\n\\nTransaction trace:\\nD.constructor()\\nD.g(0)\\n    s1.sol:f(200) -- internal call\\n    s1.sol:f(0) -- internal call\\n    A:f(10) -- internal call\\n    A:f(0) -- internal call\n// Warning 6328: (s1.sol:28-44): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n_y = 0\\n\\nTransaction trace:\\nD.constructor()\\nD.g(0)\\n    s1.sol:f(200) -- internal call\\n    s1.sol:f(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/import_base.sol",
    "content": "==== Source: base ====\ncontract Base {\n\tuint x;\n\taddress a;\n\tfunction f() internal returns (uint) {\n\t\ta = address(this);\n\t\t++x;\n\t\treturn 2;\n\t}\n}\n==== Source: der ====\nimport \"base\";\ncontract Der is Base {\n\tfunction g(uint y) public {\n\t\trequire(x < 10); // added to restrict the search space and avoid non-determinism in Spacer\n\t\tx += f();\n\t\tassert(y > x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (der:174-187): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/import_free_functions.sol",
    "content": "==== Source: Address.sol ====\npragma solidity ^0.8.0;\nfunction s() pure {}\n==== Source: ERC20.sol ====\npragma solidity ^0.8.0;\n\nimport \"./Address.sol\";\n\nfunction sub(uint256 a, uint256 b) pure returns (uint256) {\n    return a - b;\n}\n\ncontract ERC20 {\n    mapping (address => uint256) private _balances;\n\n    function transferFrom(uint256 amount) public view {\n        sub(_balances[msg.sender], amount);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 3944: (ERC20.sol:121-126): CHC: Underflow (resulting value less than 0) happens here.\\nCounterexample:\\n\\namount = 1\\n\\nTransaction trace:\\nERC20.constructor()\\nERC20.transferFrom(1){ msg.sender: 0x52f6 }\\n    ERC20.sol:sub(0, 1) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/import_library.sol",
    "content": "==== Source: c ====\nimport \"lib\";\ncontract C {\n\tfunction g(uint x) public pure {\n\t\tuint y = L.f();\n\t\tassert(x > y);\n\t}\n}\n==== Source: lib ====\nlibrary L {\n\tuint constant one = 1;\n\tfunction f() internal pure returns (uint) {\n\t\treturn one;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (c:81-94): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\ny = 1\\n\\nTransaction trace:\\nC.constructor()\\nC.g(0)\\n    L.f() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/import_library_2.sol",
    "content": "==== Source: Address.sol ====\npragma solidity ^0.8.0;\nlibrary Address { function s() internal pure {} }\n==== Source: ERC20.sol ====\npragma solidity ^0.8.0;\n\nimport \"./Address.sol\";\n\nlibrary SafeMath {\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a - b;\n    }\n}\n\ncontract ERC20 {\n    using SafeMath for uint256;\n    using Address for address;\n\n    mapping (address => uint256) private _balances;\n\n    function transferFrom(uint256 amount) public view {\n        _balances[msg.sender].sub(amount);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 3944: (ERC20.sol:157-162): CHC: Underflow (resulting value less than 0) happens here.\\nCounterexample:\\n\\namount = 1\\n\\nTransaction trace:\\nERC20.constructor()\\nERC20.transferFrom(1){ msg.sender: 0x2e15 }\\n    SafeMath.sub(0, 1) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/imported_fail_1.sol",
    "content": "==== Source: A.sol ====\ncontract A {\n\tuint x;\n\tfunction f(uint _x) public {\n\t\tx = _x;\n\t}\n}\n==== Source: B.sol ====\nimport \"A.sol\";\ncontract B is A {\n\tfunction g(uint _x) public view {\n\t\tassert(_x > x);\n\t}\n}\n==== Source: C.sol ====\nimport \"B.sol\";\ncontract C is B {\n\tfunction h(uint _x) public view {\n\t\tassert(_x < x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (B.sol:71-85): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n_x = 0\\n\\nTransaction trace:\\nB.constructor()\\nState: x = 0\\nB.g(0)\n// Warning 6328: (C.sol:71-85): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n_x = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.h(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/imported_fail_2.sol",
    "content": "==== Source: A.sol ====\ncontract A {\n\tuint x;\n\tfunction f(uint _x) public {\n\t\tx = _x;\n\t}\n}\n==== Source: B.sol ====\nimport \"A.sol\";\ncontract B is A {\n\tfunction g(uint _x) public view {\n\t\tassert(_x > x);\n\t}\n}\n==== Source: C.sol ====\nimport \"B.sol\";\ncontract C is B {\n\tfunction h(uint _x) public view {\n\t\tassert(_x < x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (B.sol:71-85): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n_x = 0\\n\\nTransaction trace:\\nB.constructor()\\nState: x = 0\\nB.g(0)\n// Warning 6328: (C.sol:71-85): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n_x = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.h(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/imported_fail_3.sol",
    "content": "==== Source: A.sol ====\ncontract A {\n\tuint x;\n\tfunction f(uint _x) public {\n\t\tx = _x;\n\t}\n}\n==== Source: B.sol ====\nimport \"A.sol\";\ncontract B is A {\n\tfunction g(uint _x) public view {\n\t\tassert(_x > x);\n\t}\n}\n==== Source: C.sol ====\nimport \"A.sol\";\ncontract C is A {\n\tfunction h(uint _x) public view {\n\t\tassert(_x < x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (B.sol:71-85): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n_x = 0\\n\\nTransaction trace:\\nB.constructor()\\nState: x = 0\\nB.g(0)\n// Warning 6328: (C.sol:71-85): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n_x = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.h(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/private_vars.sol",
    "content": "==== Source: ERC20.sol ====\ncontract ERC20 {\n    uint256 private a;\n    function f() internal virtual {\n        a = 2;\n    }\n}\n==== Source: Token.sol ====\nimport \"ERC20.sol\";\ncontract Token is ERC20 {\n    constructor() {\n      f();\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/simple.sol",
    "content": "==== Source: A.sol ====\ncontract A { function f() public {} }\n==== Source: B.sol ====\nimport \"A.sol\";\ncontract C is A {}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_analyzed_when_called_from_selection_with_trusted_calls.sol",
    "content": "==== Source: A.sol ====\ncontract A { function a() pure public { assert(false); } }\n==== Source: B.sol ====\nimport \"A.sol\";\ncontract B { function b(A a) pure public { a.a(); } }\n// ====\n// SMTContract: B.sol:B\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// ----\n// 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\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/imports/target_in_imported_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol",
    "content": "==== Source: A.sol ====\ncontract A { function a() pure public { assert(false); } }\n==== Source: B.sol ====\nimport \"A.sol\";\ncontract B { function b() pure public { } }\n// ====\n// SMTContract: B.sol:B\n// SMTEngine: chc\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_1.sol",
    "content": "contract B {\n\tuint x;\n\tfunction f() public view {\n\t\tassert(x == 0);\n\t}\n}\n\ncontract C is B {\n\tuint y;\n\tfunction g() public {\n\t\tx = 1;\n\t\tf();\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (52-66): CHC: Assertion violation happens here.\\nCounterexample:\\ny = 0, x = 1\\n\\nTransaction trace:\\nC.constructor()\\nState: y = 0, x = 0\\nC.g()\\n    B.f() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_2.sol",
    "content": "contract A {\n\tuint x;\n\tfunction f() internal view {\n\t\tassert(x == 0);\n\t}\n}\n\ncontract B is A {\n\tuint a;\n\tuint b;\n}\n\ncontract C is B {\n\tuint y;\n\tuint z;\n\tuint w;\n\tfunction g() public {\n\t\tx = 1;\n\t\tf();\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (54-68): CHC: Assertion violation happens here.\\nCounterexample:\\ny = 0, z = 0, w = 0, a = 0, b = 0, x = 1\\n\\nTransaction trace:\\nC.constructor()\\nState: y = 0, z = 0, w = 0, a = 0, b = 0, x = 0\\nC.g()\\n    A.f() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_3.sol",
    "content": "contract A {\n\tuint x;\n\tfunction f() internal virtual {\n\t\tv();\n\t\tassert(x == 0); // should fail\n\t\tassert(x == 2); // should hold\n\t}\n\tfunction v() internal virtual {\n\t\tx = 0;\n\t}\n}\n\ncontract B is A {\n\tfunction f() internal virtual override {\n\t\tsuper.f();\n\t}\n}\n\ncontract C is B {\n\tfunction g() public {\n\t\tx = 1;\n\t\tf();\n\t}\n\tfunction v() internal override {\n\t\tx = 2;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (64-78): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.g()\\n    B.f() -- internal call\\n        A.f() -- internal call\\n            C.v() -- internal call\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_4.sol",
    "content": "contract A {\n\tuint x;\n\tfunction f() internal virtual {\n\t\tv();\n\t\tassert(x == 0); // should fail\n\t\tassert(x == 2); // should hold\n\t}\n\tfunction v() internal virtual {\n\t\tx = 0;\n\t}\n}\ncontract A1 is A {\n\tfunction f() internal virtual override {\n\t\tsuper.f();\n\t}\n}\ncontract B is A {\n\tfunction f() internal virtual override {\n\t\tsuper.f();\n\t}\n}\n\ncontract C is B, A1 {\n\tfunction g() public {\n\t\tx = 1;\n\t\tf();\n\t}\n\tfunction f() internal override(B, A1) {\n\t\tsuper.f();\n\t}\n\tfunction v() internal override {\n\t\tx = 2;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (64-78): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.g()\\n    C.f() -- internal call\\n        A1.f() -- internal call\\n            B.f() -- internal call\\n                A.f() -- internal call\\n                    C.v() -- internal call\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_5.sol",
    "content": "contract A {\n\tuint x;\n\tfunction f() internal virtual {\n\t\tv();\n\t\tassert(x == 0); // should hold\n\t\tassert(x == 2); // should fail\n\t}\n\tfunction v() internal virtual {\n\t\tx = 0;\n\t}\n}\n\ncontract B is A {\n\tfunction f() internal virtual override {\n\t\tsuper.f();\n\t}\n}\n\ncontract C is B {\n\tfunction g() public {\n\t\tx = 1;\n\t\tf();\n\t}\n\tfunction v() internal override {\n\t\tx = 2;\n\t\tsuper.v();\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (97-111): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.g()\\n    B.f() -- internal call\\n        A.f() -- internal call\\n            C.v() -- internal call\\n                A.v() -- internal call\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_6.sol",
    "content": "contract A {\n\tuint x;\n\tfunction f() internal virtual {\n\t\tv();\n\t\tassert(x == 2); // should hold\n\t}\n\tfunction v() internal virtual {\n\t\tx = 0;\n\t}\n\tfunction g() public virtual {\n\t\tv();\n\t\tassert(x == 2); // should fail\n\t}\n}\n\ncontract B is A {\n\tfunction f() internal virtual override {\n\t\tsuper.f();\n\t}\n}\n\ncontract C is B {\n\tfunction g() public override {\n\t\tx = 1;\n\t\tf();\n\t}\n\tfunction v() internal override {\n\t\tx = 2;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (183-197): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.g()\\n    A.v() -- internal call\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_7.sol",
    "content": "contract A {\n\tuint x;\n\tfunction f() internal {\n\t\tv();\n\t\tassert(x == 0); // should fail\n\t\tassert(x == 2); // should hold\n\t}\n\tfunction v() internal virtual {\n\t\tx = 0;\n\t}\n}\n\ncontract C is A {\n\tfunction g() public {\n\t\tx = 1;\n\t\tf();\n\t}\n\tfunction v() internal override {\n\t\tx = 2;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (56-70): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.g()\\n    A.f() -- internal call\\n        C.v() -- internal call\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_8.sol",
    "content": "abstract contract A {\n\tuint x;\n\tfunction f() public view {\n\t\tassert(x == 2);\n\t}\n}\n\ncontract C is  A {\n\tfunction g() public {\n\t\tx = 2;\n\t\tf();\n\t\tx = 0;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (61-75): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nA.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/base_contract_assertion_fail_9.sol",
    "content": "contract A {\n\tuint x;\n\tfunction f() public virtual {\n\t\tv();\n\t\tassert(x == 0); // should fail when C is the most derived contract\n\t\tassert(x == 2); // should fail when A is the most derived contract\n\t}\n\tfunction v() internal virtual {\n\t\tx = 0;\n\t}\n}\n\ncontract B is A {\n\tfunction f() public virtual override {\n\t\tsuper.f();\n\t}\n}\n\ncontract C is B {\n\tfunction g() public {\n\t\tx = 1;\n\t\tf();\n\t}\n\tfunction v() internal override {\n\t\tx = 2;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (62-76): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nB.f()\\n    A.f() -- internal call\\n        C.v() -- internal call\n// Warning 6328: (131-145): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.f()\\n    A.v() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_base_calls_inheritance_specifier_1.sol",
    "content": "contract A {\n\tuint public x;\n\tconstructor(uint a) { x = a; }\n}\n\ncontract B is A {\n\tconstructor(uint b) A(b) {\n\t}\n\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\n\tfunction g() internal returns (uint) {\n\t\tx = 42;\n\t\treturn x;\n\t}\n}\n\ncontract Z is B {\n\tconstructor(uint z) B(z + f()) {\n\t}\n}\n\ncontract C is Z(5) {\n\tconstructor() {\n\t\tassert(x == 6);\n\t\tassert(x > 9); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (292-299): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (367-380): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_base_calls_inheritance_specifier_2.sol",
    "content": "contract A {\n\tuint public x;\n\tconstructor(uint a) { x = a; }\n}\n\ncontract B is A(9) {\n\tconstructor(uint b) {\n\t\tx += b;\n\t}\n\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\n\tfunction g() internal returns (uint) {\n\t\tx = 42;\n\t\treturn x;\n\t}\n}\n\ncontract Z is B {\n\tconstructor(uint z) B(z + f()) {\n\t}\n}\n\ncontract C is Z(5) {\n\tconstructor() {\n\t\tassert(x == 15);\n\t\tassert(x > 90); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (110-116): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4984: (300-307): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (376-390): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_base_calls_with_side_effects_1.sol",
    "content": "contract A {\n\tuint public x;\n\tconstructor(uint a) { x = a; }\n}\n\ncontract B is A {\n\tconstructor(uint b) A(b + f()) {\n\t}\n\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n}\n\nabstract contract Z is A {\n\tuint k;\n\tconstructor(uint z) {\n\t\tk = z;\n\t}\n}\n\ncontract C is Z, B {\n\tconstructor() B(x) Z(x) {\n\t\tassert(x == 1);\n\t\tassert(k == 0);\n\t\tassert(x == k); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (105-112): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (351-365): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_base_calls_with_side_effects_2.sol",
    "content": "contract A {\n\tuint public x;\n\tconstructor(uint a) { x = a; }\n}\n\ncontract B is A {\n\tconstructor(uint b) A(b) {\n\t}\n\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n}\n\nabstract contract Z is A {\n\tuint k;\n\tconstructor(uint z) {\n\t\tk = z;\n\t}\n}\n\ncontract C is Z, B {\n\tconstructor() B(f()) Z(f()) {\n\t\tassert(x == 1);\n\t\tassert(k == 2);\n\t\tassert(x == k); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (349-363): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_base_calls_with_side_effects_3.sol",
    "content": "contract A {\n\tuint public x;\n\tconstructor(uint a) { x = a; }\n}\n\ncontract B is A {\n\tconstructor(uint b) A(b + f()) {\n\t}\n\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n}\n\nabstract contract Z is A {\n\tuint k;\n\tconstructor(uint z) {\n\t\tk = z;\n\t}\n}\n\ncontract C is Z, B {\n\tconstructor(uint c) B(c) Z(x) {\n\t\tassert(x == c + 1);\n\t\tassert(k == 0);\n\t\tassert(x == k); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (105-112): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (361-375): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_base_calls_with_side_effects_4.sol",
    "content": "contract A {\n\tuint public x;\n\tconstructor(uint a) { x = a; }\n}\n\ncontract B is A {\n\tconstructor(uint b) A(b + f()) {\n\t}\n\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n}\n\nabstract contract Z is A {\n\tuint k;\n\tconstructor(uint z) {\n\t\tk = z;\n\t}\n}\n\ncontract C is Z, B {\n\tconstructor(uint c) Z(x) B(c) {\n\t\tassert(x == c + 1);\n\t\tassert(k == 0);\n\t\tassert(x == k); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (105-112): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (361-375): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_base_calls_with_side_effects_5.sol",
    "content": "contract A {\n\tuint public x;\n\tconstructor(uint a) { x = a; }\n}\n\ncontract B is A {\n\tconstructor(uint b) A(b + f()) {\n\t}\n\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\n\tfunction g() internal returns (uint) {\n\t\tx = 42;\n\t\treturn x;\n\t}\n}\n\nabstract contract Z is A {\n\tuint k;\n\tconstructor(uint z) {\n\t\tk = z;\n\t}\n}\n\ncontract C is Z, B {\n\tconstructor() Z(g()) B(f()) {\n\t\tassert(x == 44);\n\t\tassert(k == 42);\n\t\tassert(x == k); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (105-112): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (423-437): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_base_calls_with_side_effects_6.sol",
    "content": "contract A {\n\tuint public x;\n\tconstructor(uint a) { x = a; }\n}\n\ncontract B is A {\n\tconstructor(uint b) A(b) {\n\t}\n\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\n\tfunction g() internal returns (uint) {\n\t\tx = 42;\n\t\treturn x;\n\t}\n}\n\nabstract contract Z is A {\n\tuint k;\n\tconstructor(uint z) {\n\t\tk = z;\n\t}\n}\n\ncontract C is Z, B {\n\tconstructor() Z(g()) B(f()) {\n\t\tassert(x == 1);\n\t\tassert(k == 42);\n\t\tassert(x == k); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (416-430): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_base_calls_with_side_effects_7.sol",
    "content": "contract A {\n\tuint public x;\n\tconstructor(uint a) { x = a; }\n}\n\ncontract B is A {\n\tconstructor(uint b) A(b) {\n\t}\n\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n\n\tfunction g() internal returns (uint) {\n\t\tx = 42;\n\t\treturn x;\n\t}\n}\n\ncontract Z is B {\n\tconstructor() B(f()) {\n\t}\n}\n\ncontract C is Z {\n\tconstructor() {\n\t\tassert(x == 1);\n\t\tassert(x > 2); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (354-367): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_base_calls_with_side_effects_8.sol",
    "content": "contract A {\n\tuint public x;\n\tconstructor(uint) {}\n\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n}\n\ncontract C is A {\n\tconstructor() A(f()) {\n\t\tassert(x == 1);\n\t\tassert(x == 0); // should fail\n\t\tassert(x > 2000); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (185-199): CHC: Assertion violation happens here.\n// Warning 6328: (218-234): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_base_calls_with_side_effects_9.sol",
    "content": "contract A {\n\tuint public x = 42;\n\tconstructor(uint) {}\n\n\tfunction f() internal returns (uint) {\n\t\tx = x + 1;\n\t\treturn x;\n\t}\n}\n\ncontract C is A {\n\tconstructor() A(f()) {\n\t\tassert(x == 42);\n\t\tassert(x == 0); // should fail\n\t\tassert(x == 1); // should fail\n\t\tassert(x > 2000); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (191-205): CHC: Assertion violation happens here.\n// Warning 6328: (224-238): CHC: Assertion violation happens here.\n// Warning 6328: (257-273): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_hierarchy_mixed_chain_with_params.sol",
    "content": "contract F {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\nabstract contract E is F {}\nabstract contract D is E {\n\tconstructor() {\n\t\ta = 3;\n\t}\n}\nabstract contract C is D {}\ncontract B is C {\n\tconstructor(uint x) F(x + 1) {\n\t}\n}\n\ncontract A is B {\n\tconstructor(uint x) B(x) {\n\t\tassert(a == 3);\n\t\tassert(a == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (215-220): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (296-310): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init.sol",
    "content": "contract C {\n\tuint x = 2;\n\tconstructor () {\n\t\tassert(x == 2);\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (64-78): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_asserts.sol",
    "content": "contract A {\n\tint x;\n\tconstructor (int a) { x = a;}\n}\n\ncontract B is A {\n\tint y;\n\tconstructor(int a) A(-a) {\n\t\tif (a > 0) {\n\t\t\ty = 2;\n\t\t}\n\t\telse {\n\t\t\ty = 4;\n\t\t}\n\t}\n}\n\ncontract C is B {\n\tconstructor(int a) B(a) {\n\t\tassert(y != 3); // should hold\n\t\tassert(y == 4); // should fail\n\t\tif (a > 0) {\n\t\t\tassert(x < 0 && y == 2); // should hold\n\t\t\tassert(x < 0 && y == 4); // should fail\n\t\t}\n\t\telse {\n\t\t\tassert(x >= 0 && y == 4); // should hold\n\t\t\tassert(x >= 0 && y == 2); // should fail\n\t\t\tassert(x > 0); // should fail\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (247-261): CHC: Assertion violation happens here.\n// Warning 6328: (339-362): CHC: Assertion violation happens here.\n// Warning 6328: (439-463): CHC: Assertion violation happens here.\n// Warning 6328: (483-496): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_base.sol",
    "content": "contract C {\n\tuint x = 2;\n}\n\ncontract D is C {\n\tconstructor() {\n\t\tassert(x == 2);\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (84-98): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain.sol",
    "content": "contract A {\n\tuint x = 1;\n}\n\ncontract B is A {\n\tconstructor() { x = 2; }\n}\n\ncontract C is B {\n\tconstructor() { x = 3; }\n}\n\ncontract D is C {\n\tconstructor() {\n\t\tassert(x == 3);\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (178-192): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_alternate.sol",
    "content": "contract A {\n\tuint x = 1;\n}\n\ncontract B is A {\n\tconstructor() { x = 2; }\n}\n\ncontract C is B {\n}\n\ncontract D is C {\n\tconstructor() {\n\t\tassert(x == 2);\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (152-166): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_run_all.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\nabstract contract B is C {\n\tuint b;\n\tconstructor(uint x) {\n\t\tb = a + x;\n\t}\n}\n\ncontract A is B {\n\tconstructor(uint x) B(x) C(x + 2) {\n\t\tassert(a == x + 2);\n\t\tassert(b == x + x + 2);\n\t\tassert(a == x + 5);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (125-130): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4984: (184-189): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (243-261): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_run_all_2.sol",
    "content": "contract C {\n\tuint a;\n\tconstructor(uint x) {\n\t\ta = x;\n\t}\n}\n\nabstract contract B is C {\n\tuint b;\n\tconstructor(uint x) {\n\t\tb = x + 10;\n\t}\n}\n\ncontract A is B {\n\tconstructor(uint x) B(x) C(x + 2) {\n\t\tassert(a == x + 2);\n\t\tassert(b == x + 10);\n\t\tassert(b == x + 5);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (125-131): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4984: (185-190): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (241-259): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_chain_tree.sol",
    "content": "contract A {\n\tint x;\n\tconstructor (int a) { x = a; }\n}\n\ncontract Z {\n\tint z;\n\tconstructor(int _z) {\n\t\tz = _z;\n\t}\n}\n\ncontract B is A, Z {\n\tconstructor(int b) A(b) Z(x) {\n\t\tassert(x == b);\n\t\tassert(z == 0);\n\t}\n}\n\ncontract F is Z, A {\n\tconstructor(int b) Z(x) A(b) {\n\t\tassert(x == b);\n\t\tassert(z == 0);\n\t}\n}\n\ncontract C is B {\n\tconstructor(int c) B(-c) {\n\t\tif (x > 0) {\n\t\t\tassert(c < 0); // should hold\n\t\t\tassert(c >= 0); // should fail\n\t\t}\n\t\telse {\n\t\t\tassert(c < 0); // should fail\n\t\t\tassert(c >= 0); // should hold\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (403-417): CHC: Assertion violation happens here.\n// Warning 6328: (450-463): CHC: Assertion violation happens here.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_diamond.sol",
    "content": "contract A {\n\tuint x = 2;\n}\n\ncontract B is A {\n}\n\ncontract C is A {\n}\n\ncontract D is B, C {\n\tconstructor() {\n\t\tassert(x == 2);\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (129-143): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_diamond_middle.sol",
    "content": "contract A {\n\tuint x = 1;\n}\n\ncontract B is A {\n\tconstructor() {\n\t\tassert(x == 1);\n\t\tx = 2;\n\t}\n}\n\ncontract C is A {\n\tconstructor() {\n\t\tassert(x == 1);\n\t\tx = 3;\n\t}\n}\n\ncontract D is B, C {\n\tconstructor() {\n\t\tassert(x == 3);\n\t\tassert(x == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (134-148): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n\\nTransaction trace:\\nD.constructor()\n// Warning 6328: (223-237): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 3\\n\\nTransaction trace:\\nD.constructor()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_state_variable_init_function_call.sol",
    "content": "contract C {\n\tuint x = f(2);\n\tconstructor () {\n\t\tassert(x == 2);\n\t}\n\n\tfunction f(uint y) internal view returns (uint) {\n\t\tassert(y > 0);\n\t\tassert(x == 0);\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/constructor_uses_function_base.sol",
    "content": "contract A {\n\tuint x;\n\tconstructor() {\n\t\tx = 42;\n\t}\n\tfunction f() public view returns(uint256) {\n\t\treturn x;\n\t}\n}\ncontract B is A {\n\tuint y = f();\n}\ncontract C is B {\n\tfunction g() public view {\n\t\tassert(y == 42);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/diamond_super_1.sol",
    "content": "contract A {\n\tfunction f() public virtual returns (uint256 r) {\n\t\treturn 1;\n\t}\n}\n\n\ncontract B is A {\n\tfunction f() public virtual override returns (uint256 r) {\n\t\treturn super.f() + 2;\n\t}\n}\n\n\ncontract C is A {\n\tfunction f() public virtual override returns (uint256 r) {\n\t\treturn super.f() + 4;\n\t}\n}\n\n\ncontract D is B, C {\n\tfunction f() public override(B, C) returns (uint256 r) {\n\t\tr = super.f() + 8;\n\t\tassert(r == 15); // should hold\n\t\tassert(r == 13); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (437-452): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nr = 15\\n\\nTransaction trace:\\nD.constructor()\\nD.f()\\n    C.f() -- internal call\\n        B.f() -- internal call\\n            A.f() -- internal call\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/diamond_super_2.sol",
    "content": "contract A {\n\tfunction f() public virtual returns (uint256 r) {\n\t\treturn 1;\n\t}\n}\n\n\ncontract B is A {\n\tfunction f() public virtual override returns (uint256 r) {\n\t\treturn super.f() + 2;\n\t}\n}\n\n\ncontract C is A {\n\tfunction f() public virtual override returns (uint256 r) {\n\t\treturn 2 * (super.f() + 4);\n\t}\n}\n\n\ncontract D is B, C {\n\tfunction f() public override(B, C) returns (uint256 r) {\n\t\tr = super.f() + 8;\n\t\tassert(r == 22); // should hold\n\t\tassert(r == 20); // should fail\n\t\tassert(r == 18); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (443-458): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nr = 22\\n\\nTransaction trace:\\nD.constructor()\\nD.f()\\n    C.f() -- internal call\\n        B.f() -- internal call\\n            A.f() -- internal call\n// Warning 6328: (477-492): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nr = 22\\n\\nTransaction trace:\\nD.constructor()\\nD.f()\\n    C.f() -- internal call\\n        B.f() -- internal call\\n            A.f() -- internal call\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/diamond_super_3.sol",
    "content": "contract A {\n\tint public x;\n\tfunction f() public virtual {\n\t\tx = 1;\n\t}\n}\n\ncontract B is A {\n\tfunction f() public virtual override {\n\t\tsuper.f();\n\t\tx += 100;\n\t}\n}\n\ncontract C is B {\n\tfunction f() public virtual override {\n\t\tsuper.f();\n\t\tx += 10;\n\t}\n}\n\ncontract D is B {\n}\n\ncontract E is C,D {\n\tfunction f() public override(C,B) {\n\t\tsuper.f();\n\t\tassert(x == 111); // should hold\n\t\tassert(x == 13); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (379-394): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 111\\n\\nTransaction trace:\\nE.constructor()\\nState: x = 0\\nE.f()\\n    C.f() -- internal call\\n        B.f() -- internal call\\n            A.f() -- internal call\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/fallback.sol",
    "content": "// 2 warnings, fallback and A.g\ncontract A {\n\tuint x;\n\n\tfallback () external virtual {\n\t\tassert(x == 1);\n\t}\n\tfunction g() public view {\n\t\tassert(x == 1);\n\t}\n}\n\n// 2 warnings, fallback and A.g\ncontract B is A {\n\tuint y;\n\n\tfallback () external override {\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (89-103): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.fallback()\n// Warning 6328: (138-152): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.g()\n// Warning 6328: (255-269): CHC: Assertion violation happens here.\\nCounterexample:\\ny = 0, x = 0\\n\\nTransaction trace:\\nB.constructor()\\nState: y = 0, x = 0\\nB.fallback()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/fallback_receive.sol",
    "content": "// 2 warnings, fallback and A.g\ncontract A {\n\tuint x;\n\n\tfallback () external {\n\t\tassert(x == 1);\n\t}\n\tfunction g() public view {\n\t\tassert(x == 1);\n\t}\n}\n\n// 3 warnings, receive, A.fallback and A.g\ncontract B is A {\n\tuint y;\n\n\treceive () external payable {\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (81-95): CHC: Assertion violation happens here.\n// Warning 6328: (130-144): CHC: Assertion violation happens here.\n// Warning 6328: (256-270): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/functions_1.sol",
    "content": "// 2 warnings, A.f and A.g\ncontract A {\n\tuint x;\n\n\tfunction f() public virtual view {\n\t\tassert(x == 1);\n\t}\n\tfunction g() public view {\n\t\tassert(x == 1);\n\t}\n}\n\n// 2 warnings, B.f and A.g\ncontract B is A {\n\tfunction f() public view override {\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (88-102): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.f()\n// Warning 6328: (137-151): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.g()\n// Warning 6328: (243-257): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nB.constructor()\\nState: x = 0\\nB.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/functions_2.sol",
    "content": "// 2 warnings, A.f and A.g\ncontract A {\n\tuint x;\n\n\tfunction f() public virtual view {\n\t\tassert(x == 1);\n\t}\n\tfunction g() public view {\n\t\tassert(x == 1);\n\t}\n}\n\n// 2 warnings, B.f and A.g\ncontract B is A {\n\tuint y;\n\n\tfunction f() public view override {\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (88-102): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.f()\n// Warning 6328: (137-151): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.g()\n// Warning 6328: (253-267): CHC: Assertion violation happens here.\\nCounterexample:\\ny = 0, x = 0\\n\\nTransaction trace:\\nB.constructor()\\nState: y = 0, x = 0\\nB.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/functions_3.sol",
    "content": "// 2 warnings, A.f and A.g\ncontract A {\n\tuint x;\n\n\tfunction f() public virtual view {\n\t\tassert(x == 1);\n\t}\n\tfunction g() public view {\n\t\tassert(x == 1);\n\t}\n}\n\n// 3 warnings, B.f, B.h, A.g\ncontract B is A {\n\tuint y;\n\n\tfunction f() public view virtual override {\n\t\tassert(x == 1);\n\t}\n\tfunction h() public view {\n\t\tassert(x == 1);\n\t}\n}\n\n// 4 warnings, C.f, C.i, B.h, A.g\ncontract C is B {\n\tuint z;\n\n\tfunction f() public view override {\n\t\tassert(x == 1);\n\t}\n\tfunction i() public view {\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (88-102): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.f()\n// Warning 6328: (137-151): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.g()\n// Warning 6328: (263-277): CHC: Assertion violation happens here.\\nCounterexample:\\ny = 0, x = 0\\n\\nTransaction trace:\\nB.constructor()\\nState: y = 0, x = 0\\nB.f()\n// Warning 6328: (312-326): CHC: Assertion violation happens here.\\nCounterexample:\\ny = 0, x = 0\\n\\nTransaction trace:\\nB.constructor()\\nState: y = 0, x = 0\\nB.h()\n// Warning 6328: (435-449): CHC: Assertion violation happens here.\\nCounterexample:\\nz = 0, y = 0, x = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: z = 0, y = 0, x = 0\\nC.f()\n// Warning 6328: (484-498): CHC: Assertion violation happens here.\\nCounterexample:\\nz = 0, y = 0, x = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: z = 0, y = 0, x = 0\\nC.i()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/implicit_constructor_hierarchy.sol",
    "content": "contract A {\n\tuint x;\n\tconstructor (uint y) { assert(x == 0); x = y; }\n}\n\ncontract B is A {\n\tconstructor () A(2) { assert(x == 2); }\n}\n\ncontract C is B {\n\tfunction f() public view {\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreInv: yes\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/implicit_only_constructor_hierarchy.sol",
    "content": "contract A {\n\tuint x;\n\tfunction h() public view {\n\t\tassert(x == 0);\n\t}\n}\n\ncontract B is A {\n\tfunction g() public view {\n\t\tassert(x == 0);\n\t}\n}\n\ncontract C is B {\n\tfunction f() public view {\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/overridden_function_static_call_parent.sol",
    "content": "contract BaseBase {\n\tuint x;\n\tfunction init(uint a, uint b) public virtual {\n\t\tx = a;\n\t}\n}\ncontract Base is BaseBase {\n\tfunction init(uint a, uint b) public override {\n\t}\n}\ncontract Child is Base {\n\tfunction bInit(uint c, uint d) public {\n\t\tBaseBase.init(c, d);\n\t\tassert(x == c);\n\t\tassert(x == d); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 5667: (52-58): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (282-296): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/receive.sol",
    "content": "// 2 warnings, receive and A.g\ncontract A {\n\tuint x;\n\n\treceive () external virtual payable {\n\t\tassert(x == 1);\n\t}\n\tfunction g() public view {\n\t\tassert(x == 1);\n\t}\n}\n\n// 2 warnings, receive and A.g\ncontract B is A {\n\tuint y;\n\n\treceive () external payable override {\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (95-109): CHC: Assertion violation happens here.\n// Warning 6328: (144-158): CHC: Assertion violation happens here.\n// Warning 6328: (267-281): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/receive_fallback.sol",
    "content": "// 2 warnings, receive and A.g\ncontract A {\n\tuint x;\n\n\treceive () external payable {\n\t\tassert(x == 1);\n\t}\n\tfunction g() public view {\n\t\tassert(x == 1);\n\t}\n}\n\n// 3 warnings, fallback, A.receive and A.g\ncontract B is A {\n\tuint y;\n\n\tfallback () external {\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (87-101): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.receive(){ msg.value: 1 }\n// Warning 6328: (136-150): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nA.constructor()\\nState: x = 0\\nA.g()\n// Warning 6328: (255-269): CHC: Assertion violation happens here.\\nCounterexample:\\ny = 0, x = 0\\n\\nTransaction trace:\\nB.constructor()\\nState: y = 0, x = 0\\nB.fallback()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/state_variables.sol",
    "content": "contract Base {\n\tuint x;\n\tuint z;\n\tuint private t;\n}\n\ncontract C is Base {\n\tfunction f(uint y) public {\n\t\trequire(x < 10);\n\t\trequire(y < 100);\n\t\tz = x + y;\n\t\tassert(z < 150);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/state_variables_2.sol",
    "content": "contract Base1 {\n\tuint x;\n}\n\ncontract Base2 is Base1 {\n\tuint z;\n}\n\ncontract C is Base2 {\n\tfunction f(uint y) public {\n\t\trequire(x < 10);\n\t\trequire(y < 100);\n\t\tz = x + y;\n\t\tassert(z < 150);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inheritance/state_variables_3.sol",
    "content": "contract Base {\n\tuint x;\n\tuint private t;\n}\n\ncontract C is Base {\n\n\tuint private z;\n\tfunction f(uint y) public {\n\t\trequire(x < 10);\n\t\trequire(y < 100);\n\t\tz = x + y;\n\t\tassert(z < 150);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inline_assembly/assembly_1.sol",
    "content": "contract C {\n\tfunction f() internal pure returns (bool) {\n\t\tbool b;\n\t\tassembly { b := 1 } // This assignment is overapproximated at the moment, we don't know value of b after the assembly block\n\t\treturn b;\n\t}\n\tfunction g() public pure {\n\t\tassert(f()); // False positive currently\n\t\tassert(!f()); // should fail, now because of overapproximation in the analysis\n\t\trequire(f()); // BMC constant value not detected at the moment\n\t\trequire(!f()); // BMC constant value not ddetected at the moment\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7737: (70-89): Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n// Warning 6328: (239-250): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.f() -- internal call\n// Warning 6328: (282-294): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.f() -- internal call\\n    C.f() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inline_assembly/assembly_2.sol",
    "content": "contract C {\n\tfunction f() public pure returns (bool) {\n\t\tbool b;\n\t\tint x = 42;\n\t\tassembly { b := 1 }\n\t\tassert(x == 42); // should hold\n\t\tassert(b); // should hold, but fails due to overapproximation\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7737: (82-101): Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n// Warning 6328: (138-147): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inline_assembly/assembly_3.sol",
    "content": "contract C {\n    function f() public pure returns (bool) {\n        bool b;\n        bool c = true;\n        assembly { b := c }\n        assert(c); // should hold, c is not assigned in the assembly\n        assert(b); // should hold, but fails currently because of overapproximation\n        return b;\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7737: (106-125): Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n// Warning 6328: (203-212): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inline_assembly/assembly_4.sol",
    "content": "contract C {\n\tfunction f() public pure returns (bool) {\n\t\tbool b;\n\t\tint x = 42;\n\t\tassembly { b := 1 }\n\t\tb = true;\n\t\tassert(x == 42); // should hold\n\t\tassert(b); // should hold\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7737: (82-101): Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inline_assembly/assembly_5.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS s;\n\n\tfunction f() public {\n\t\ts.x = 42;\n\t\tS memory sm = s;\n\t\tassert(sm.x == 42); // should hold\n\t\tuint256 i = 7;\n\t\tassembly {\n\t\t\tmstore(sm, i)\n\t\t}\n\t\tsm.x = 10;\n\t\tassert(sm.x == 10); // should hold\n\t\tassert(s.x == 42); // should hold, storage not changed by the assembly\n\t\tassert(i == 7); // should hold, not changed by the assembly\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7737: (156-187): Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inline_assembly/assembly_6.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS s;\n\n\tfunction f() public {\n\t\ts.x = 42;\n\t\tS storage sm = s;\n\t\tassert(sm.x == 42); // should hold\n\t\tuint256 i = 7;\n\t\tassembly {\n\t\t\tsstore(sm.slot, i)\n\t\t}\n\t\tsm.x = 10;\n\t\tassert(sm.x == 10); // should hold\n\t\tassert(i == 7); // should hold, not changed by the assembly\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7737: (157-193): Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inline_assembly/assembly_local_storage_access_inside_function.sol",
    "content": "contract C {\n\tuint256 public z;\n\n\tfunction f() public {\n\t\tz = 42;\n\t\tuint i = 32;\n\t\tassembly {\n\t\t\tfunction f() {\n\t\t\t\tsstore(z.slot, 7)\n\t\t\t}\n\t\t\tf()\n\t\t}\n\t\tassert(z == 42); // should fail\n\t\tassert(z == 7); // should hold, but the analysis cannot know this yet\n\t\tassert(i == 32); // should hold, not changed by the assembly\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 7737: (83-149): Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n// Warning 6328: (152-167): CHC: Assertion violation happens here.\n// Warning 6328: (186-200): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inline_assembly/assembly_local_storage_pointer.sol",
    "content": "contract C {\n\tuint256[] public a;\n\n\tfunction f() public {\n\t\trequire(a.length == 0);\n\t\tuint256[] storage x = a;\n\t\tassert(x.length == 0); // should hold\n\t\tuint256 i = 7;\n\t\tassembly {\n\t\t\tsstore(x.slot, 7)\n\t\t}\n\t\tassert(x.length == 0); // should fail\n\t\tassert(x.length == 7); // should hold, but the analysis cannot know this yet\n\t\tassert(i == 7); // should hold, not changed by the assembly\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 7737: (170-205): Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n// Warning 6328: (208-229): CHC: Assertion violation happens here.\n// Warning 6328: (248-269): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inline_assembly/assembly_memory_write.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS s;\n\n\tfunction f() public {\n\t\ts.x = 42;\n\t\tS memory sm = s;\n\t\tassert(sm.x == 42); // should hold\n\t\tuint256 i = 7;\n\t\tassembly {\n\t\t\tmstore(sm, i)\n\t\t}\n\t\tassert(sm.x == 42); // should fail\n\t\tassert(sm.x == 7); // should hold, but the analysis cannot know this yet\n\t\tassert(s.x == 42); // should hold, storage not changed by the assembly\n\t\tassert(i == 7); // should hold, not changed by the assembly\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 7737: (156-187): Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n// Warning 6328: (190-208): CHC: Assertion violation happens here.\n// Warning 6328: (227-244): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inline_assembly/empty.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tassembly {\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7737: (43-57): Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/inline_assembly/local_var.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure returns (uint) {\n\t\tassembly {\n\t\t\tx := 2\n\t\t}\n\t\treturn x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7737: (64-88): Inline assembly may cause SMTChecker to produce spurious warnings (false positives).\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/aon_blog_post.sol",
    "content": "contract C {\n\tbool a;\n\tbool b;\n\tbool c;\n\tbool d;\n\tbool e;\n\tbool f;\n\tfunction press_A() public {\n\t\tif(e) { a = true; } else { reset(); }\n\t}\n\tfunction press_B() public {\n\t\tif(c) { b = true; } else { reset(); }\n\t}\n\tfunction press_C() public {\n\t\tif(a) { c = true; } else { reset(); }\n\t}\n\tfunction press_D() public {\n\t\td = true;\n\t}\n\tfunction press_E() public {\n\t\tif(d) { e = true; } else { reset(); }\n\t}\n\tfunction press_F() public {\n\t\tif(b) { f = true; } else { reset(); }\n\t}\n\tfunction is_not_solved() view public {\n\t\t// f = true can be reached by calling the functions\n\t\t// press_D()\n\t\t// press_E()\n\t\t// press_A()\n\t\t// press_C()\n\t\t// press_B()\n\t\t// press_F()\n\t\tassert(!f);\n\t}\n\tfunction reset() internal {\n\t\ta = false;\n\t\tb = false;\n\t\tc = false;\n\t\td = false;\n\t\te = false;\n\t\tf = false;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (657-667): CHC: Assertion violation might happen here.\n// Warning 4661: (657-667): BMC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/array_access.sol",
    "content": "contract C {\n    int[2] a;\n\n    constructor() {\n        a[0] = 1;\n        a[1] = 2;\n    }\n\n    function i() public view {\n            assert(a[1] > a[0]);\n    }\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreInv: no\n// SMTSolvers: eld\n// SMTTargets: assert\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Info 1180: Contract invariant(s) for :C:\\n((a.length = 2) && ((a[1] - a[0]) >= 1))\\n\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/array_access_2.sol",
    "content": "contract C {\n  constructor() {\n    int8 v;\n    (v *= v);\n  }\n}\n\ncontract D {\n  bool[2] internal a;\n\n  function f() internal view {\n    do {} while(!(a[1]));\n  }\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreInv: no\n// SMTSolvers: z3\n// SMTTargets: overflow\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Info 1180: Contract invariant(s) for :D:\\n(true || true)\\nReentrancy property(ies) for :C:\\n((<errorCode> = 0) && (x!5 = x!4))\\nReentrancy property(ies) for :D:\\n((<errorCode> = 0) && (x!6 = x!4) && (a' = a))\\n<errorCode> = 0 -> no errors\\n<errorCode> = 1 -> Overflow at v *= v\\n\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/loop_basic.sol",
    "content": "contract Simple {\n\tfunction f(uint x) public pure {\n\t\tuint y;\n\t\trequire(x > 0);\n\t\twhile (y < x)\n\t\t\t++y;\n\t\tassert(y == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/loop_basic_for.sol",
    "content": "contract Simple {\n\tfunction f(uint x) public pure {\n\t\tuint y;\n\t\tfor (y = 0; y < x; ++y) {}\n\t\tassert(y == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/loop_nested.sol",
    "content": "contract Simple {\n\tfunction f() public pure {\n\t\tuint x = 10;\n\t\tuint y;\n\t\twhile (y < x)\n\t\t{\n\t\t\t++y;\n\t\t\tx = 0;\n\t\t\twhile (x < 10)\n\t\t\t\t++x;\n\t\t\tassert(x == 10);\n\t\t}\n\t\t// Removed because of Spacer nondeterminism.\n\t\t//assert(y == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/loop_nested_for.sol",
    "content": "contract Simple {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tuint y;\n\t\tfor (x = 10; y < x; ++y)\n\t\t{\n\t\t\tfor (x = 0; x < 10; ++x) {}\n\t\t\tassert(x == 10);\n\t\t}\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//assert(y == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/solver_response_involves_bv2int.sol",
    "content": "// Taken from issue #15770\ncontract c {\n    function f(uint len) public pure returns (bytes memory) {\n        bytes memory x = new bytes(len);\n        for (uint i = 0; i < len; i++) {\n            x[i] = bytes1(uint8(i));\n        }\n        return x;\n    }\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreInv: no\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/state_machine_1.sol",
    "content": "contract C {\n\tuint x;\n\n\tfunction f() public {\n\t\tif (x == 0)\n\t\t\tx = 1;\n\t}\n\n\tfunction g() public {\n\t\tif (x == 1)\n\t\t\tx = 2;\n\t}\n\n\tfunction h() public {\n\t\tif (x == 2)\n\t\t\tx = 0;\n\t}\n\n\t// This function shows that (x < 9) is not inductive and\n\t// a stronger invariant is needed to be found.\n\t// (x < 3) is the one found in the end.\n\tfunction j() public {\n\t\tif (x == 7)\n\t\t\tx = 100;\n\t}\n\n\tfunction i() public view {\n\t\tassert(x < 9);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/state_machine_1_fail.sol",
    "content": "contract C {\n\tuint x;\n\n\tfunction f() public {\n\t\tif (x == 0)\n\t\t\tx = 1;\n\t}\n\n\tfunction g() public {\n\t\tif (x == 1)\n\t\t\tx = 2;\n\t}\n\n\tfunction h() public {\n\t\tif (x == 2)\n\t\t\tx = 0;\n\t}\n\n\tfunction j() public {\n\t\tif (x < 2)\n\t\t\tx = 100;\n\t}\n\n\t// Fails due to j.\n\tfunction i() public view {\n\t\t// Disabled because Spacer 4.8.9 seg faults.\n\t\t//assert(x < 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/struct_access.sol",
    "content": "contract C {\n    struct S { int x; }\n    S s = S(1);\n\n    function i() public view {\n            assert(s.x > 0);\n    }\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreInv: no\n// SMTSolvers: eld\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Info 1180: Contract invariant(s) for :C:\\n(s.x = 1)\\n\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/invariants/unary_minus_formatting.sol",
    "content": "contract C {\n        int x = -1;\n\tfunction i() public view {\n\t\tassert(x == -1);\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreInv: no\n// SMTSolvers: eld\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Info 1180: Contract invariant(s) for :C:\\n(x = -1)\\n\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_1.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x < 100);\n\t\tdo {\n\t\t\tx = x + 1;\n\t\t} while (x < 1000);\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_1_fail.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x < 100);\n\t\tdo {\n\t\t\tx = x + 1;\n\t\t} while (x < 10);\n\t\tassert(x < 14);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 6328: (110-124): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_1.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\tdo {\n\t\t\t++x;\n\t\t} while (x < 2);\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_2.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\t++x;\n\t\t\t{\n\t\t\t\t++x;\n\t\t\t\t++x;\n\t\t\t}\n\t\t} while (x < 3);\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_3.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\tif (x >= 2)\n\t\t\t\t++x;\n\t\t\t++x;\n\t\t} while (x < 3);\n\t\tassert(x == 4);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 5\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_4.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\t++x;\n\t\t} while (true);\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 1\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_5.sol",
    "content": "contract C {\n    uint x;\n\n    function condition() private returns(bool) {\n\t\t++x;\n\t\treturn x < 3;\n\t}\n\n\tfunction f() public {\n\t\trequire(x == 0);\n\t\tdo {\n\t\t} while (condition());\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 5\n// ----\n// Warning 2661: (77-80): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_6.sol",
    "content": "contract C\n{\n\tuint x;\n\tuint y;\n\n\tfunction condition() private returns(bool) {\n\t\tx = (x + 1) % 2;\n\t\treturn (x == 1);\n\t}\n\n\tfunction f() public {\n\t\trequire(x == 0);\n\t\trequire(y == 0);\n\t\tdo {\n\t\t\t++y;\n\t\t} while (condition());\n\t\tassert(y == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 5\n// ----\n// Warning 2661: (85-90): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_7.sol",
    "content": "contract C\n{\n\tuint256[] y;\n\n\tfunction f() public view {\n\t\tuint256 x = 0;\n\t\tdo {\n\t\t\t++x;\n\t\t} while (x < y.length);\n\t\trequire(x != 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 1\n// ----\n// Warning 6838: (124-130): BMC: Condition is always true.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_assertion_fails_1.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\tdo {\n\t\t\t++x;\n\t\t} while (x < 2);\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Warning 4661: (102-116): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_assertion_fails_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\t++x;\n\t\t\tbreak;\n\t\t} while (x < 3);\n\t\tassert(x == 0);\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 2\n// ----\n// Warning 5740: (87-92): Unreachable code.\n// Warning 4661: (97-111): BMC: Assertion violation happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_assertion_fails_3.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\t++x;\n\t\t\tcontinue;\n\t\t} while (x < 2);\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 2\n// ----\n// Warning 4661: (100-114): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\t++x;\n\t\t\tbreak;\n\t\t} while (x < 3);\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Warning 5740: (87-92): Unreachable code.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tdo {\n\t\t\tif (x > 0)\n\t\t\t\tbreak;\n\t\t\t++x;\n\t\t} while (x < 3);\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_3.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tdo {\n\t\t\tif (x >= 0) {\n\t\t\t\t++x;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t++x;\n\t\t} while (x < 3);\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_4.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tdo {\n\t\t\tif (x > 0) {\n\t\t\t\t++x;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t++x;\n\t\t} while (x < 3);\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_5.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tdo {\n\t\t\t++x;\n\t\t\tif (x > 1) {\n\t\t\t\t++x;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (x < 3);\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_6.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\t++x;\n\t\t\tif (x > 0) {\n\t\t\t\tx = 2;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (x > 1) {\n\t\t\t\tx = 3;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (x < 3);\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_7.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\t++x;\n\t\t\tif (x > 1) {\n\t\t\t\tx = 3;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (x > 0) {\n\t\t\t\tx = 2;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (x < 3);\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_8.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\tbreak;\n\t\t} while (++x < 2);\n        // loop condition is not executed after break\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Warning 5740: (79-86): Unreachable code.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_continue_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\tif (x > 1) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (x >= 0) {\n\t\t\t\tx = 10;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} while (x < 3);\n\t\tassert(x == 10);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_break_continue_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\tif (x > 1) {\n\t\t\t\tx = 3;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (x >= 0) {\n\t\t\t\tx = 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} while (x < 4);\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_continue_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tdo {\n\t\t\t++x;\n\t\t\tif (x == 3) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t++x;\n\t\t} while (x < 3);\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_continue_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tuint y = 0;\n\t\tdo {\n\t\t\t++x;\n\t\t\tif (x == 2) {\n\t\t\t\t++x;\n\t\t\t\ty = 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (x == 3) {\n\t\t\t\ty = 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} while (x < 3);\n\t\tassert(y == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_continue_3.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tuint y = 0;\n\t\tdo {\n\t\t\t++x;\n\t\t\tif (x > 0) {\n\t\t\t\ty = 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (x > 0) {\n\t\t\t\ty = 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} while (x < 3);\n\t\tassert(y == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_continue_4.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\tuint i;\n\t\tdo {\n\t\t\t++i;\n\t\t\tif (i == 2) {\n\t\t\t\tx = 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (i == 1) {\n\t\t\t\tx = 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} while (i < 3);\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_nested.sol",
    "content": "contract C\n{\n\tfunction f(uint z) public pure {\n\t\tuint x = 0;\n\t\trequire(z == 0);\n\t\tdo {\n\t\t\tuint y = 0;\n\t\t\tdo {\n\t\t\t\t++z;\n\t\t\t\t++y;\n\t\t\t} while (y < 2);\n\t\t\t++x;\n\t\t} while (x < 2);\n\t\tassert(z == 4);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_nested_break.sol",
    "content": "contract C\n{\n\tfunction f(uint z) public pure {\n\t\tuint x = 0;\n\t\trequire(z == 0);\n\t\tdo {\n\t\t\tuint y = 0;\n\t\t\tdo {\n\t\t\t\tif (y > 0)\n\t\t\t\t\tbreak;\n\t\t\t\t++z;\n\t\t\t\t++y;\n\t\t\t} while (y < 2);\n\t\t\t++x;\n\t\t} while (x < 2);\n\t\tassert(z == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_nested_continue.sol",
    "content": "contract C\n{\n\tfunction f(uint z) public pure {\n\t\tuint x = 0;\n\t\trequire(z == 0);\n\t\tdo {\n\t\t\tuint y = 0;\n\t\t\tdo {\n\t\t\t\t++y;\n\t\t\t\tif (y > 0)\n\t\t\t\t\tcontinue;\n\t\t\t\t++z;\n\t\t\t} while (y < 2);\n\t\t\t++x;\n\t\t} while (x < 2);\n\t\tassert(z == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_semantics_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tint y = 0;\n\t\tdo {\n\t\t\tif (x >= 3)\n\t\t\t\ty = 1;\n\t\t\t++x;\n\t\t} while (x < 3 || y == 1);\n\t\t// BMC loop iteration setting is not enough to leave the loop\n\t\tassert(x == 0); // should hold - no assumptions on value if didn't complete loop\n\t\tassert(y == 0); // should hold - no assumptions on value if didn't complete loop\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 1\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_semantics_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tint y = 0;\n\t\tdo {\n\t\t\tif (x >= 3)\n\t\t\t\ty = 1;\n\t\t\t++x;\n\t\t} while (x < 3 || y == 1);\n\t\t// BMC loop iteration setting is just enough to leave the loop\n\t\tassert(x == 3);\n\t\tassert(y == 1); // should fail, when x == 3 loop is completed\n\t\tassert(y == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Warning 4661: (223-237): BMC: Assertion violation happens here.\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_semantics_3.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tint y = 0;\n\t\tdo {\n\t\t\tif (x >= 3)\n\t\t\t\ty = 1;\n\t\t\t++x;\n\t\t} while (x < 3 || y == 1);\n\t\t// BMC loop iteration setting is more than enough to leave the loop\n\t\tassert(x == 3);\n\t\tassert(y == 1); // should fail\n\t\tassert(y == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 5\n// ----\n// Warning 4661: (228-242): BMC: Assertion violation happens here.\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_semantics_4.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tint y = 0;\n\t\tdo {\n\t\t\t++x;\n\t\t\tif (x >= 3)\n\t\t\t\ty = 1;\n\t\t} while (x < 3 || y == 1);\n\t\t// BMC loop iteration setting is more than enough to leave the loop\n\t\tassert(x == 3); // should hold\n\t\tassert(y == 1); // should hold\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 5\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_bmc_iterations_shallow_unroll.sol",
    "content": "contract C {\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\tuint y;\n\t\tdo {\n\t\t\t++y;\n\t\t\tif (y == 2)\n\t\t\t    x = 3;\n\t\t} while (y < 3);\n\t\t// nothing is reported because loop condition is true after unrolling the loop one time\n\t\tassert(x == 4);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 1\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_break.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\tbreak;\n\t\t\tx = 1;\n\t\t} while (x == 0);\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 5740: (71-76): Unreachable code.\n// Warning 5740: (89-95): Unreachable code.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_break_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint a = 0;\n\t\twhile (true) {\n\t\t\tdo {\n\t\t\t\tbreak;\n\t\t\t\ta = 2;\n\t\t\t} while (true);\n\t\t\ta = 1;\n\t\t\tbreak;\n\t\t}\n\t\tassert(a == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 5740: (95-100): Unreachable code.\n// Warning 5740: (114-118): Unreachable code.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_break_2_fail.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint a = 0;\n\t\twhile (true) {\n\t\t\tdo {\n\t\t\t\tbreak;\n\t\t\t\ta = 2;\n\t\t\t} while (true);\n\t\t\ta = 1;\n\t\t\tbreak;\n\t\t}\n\t\tassert(a == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 5740: (95-100): Unreachable code.\n// Warning 5740: (114-118): Unreachable code.\n// Warning 6328: (147-161): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = 1\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_break_fail.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\tbreak;\n\t\t\tx = 1;\n\t\t} while (x == 0);\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 5740: (71-76): Unreachable code.\n// Warning 5740: (89-95): Unreachable code.\n// Warning 6328: (100-114): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/do_while_continue.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tdo {\n\t\t\tcontinue;\n\t\t\tx = 1;\n\t\t} while (x == 0);\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 5740: (74-79): Unreachable code.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_1_break.sol",
    "content": "contract C\n{\n\tfunction f(uint x, bool b) public pure {\n\t\trequire(x < 10);\n\t\tfor (; x < 10; ) {\n\t\t\tif (b)\n\t\t\t\t++x;\n\t\t\telse {\n\t\t\t\tx = 20;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tassert(x >= 10);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_1_break_fail.sol",
    "content": "contract C\n{\n\tfunction f(uint x, bool b) public pure {\n\t\tfor (; x < 10; ) {\n\t\t\tif (b)\n\t\t\t\t++x;\n\t\t\telse {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// Fails because the loop might break.\n\t\tassert(x >= 10);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 6328: (168-183): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_1_continue.sol",
    "content": "contract C\n{\n\tfunction f(uint x, bool b) public pure {\n\t\trequire(x < 10);\n\t\tfor (; x < 10; ++x) {\n\t\t\tif (b) {\n\t\t\t\tx = 20;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_1_continue_fail.sol",
    "content": "contract C\n{\n\tfunction f(uint x, bool b) public pure {\n\t\trequire(x < 10);\n\t\tfor (; x < 10; ) {\n\t\t\t++x;\n\t\t}\n\t\tassert(x > 15);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 5667: (33-39): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (109-123): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_1_false_positive.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x < 100);\n\t\tfor(uint i = 0; i < 5; ++i) {\n\t\t\tx = x + 1;\n\t\t}\n\t\t// Disabled because of non-determinism in Spacer in Z3 4.8.9, check with next solver release.\n\t\t//assert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (106-111): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_break_direct.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\tfor (x = 0; x < 10; ++x)\n\t\t\tbreak;\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 5740: (69-72): Unreachable code.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_1.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        require(x == 2);\n        for (;;) {}\n        assert(x == 2);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_2.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        for (; x == 2; ) {\n            assert(x == 2);\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_3.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        for (uint y = 2; x < 10; ) {\n            assert(y == 2);\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_4.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        for (uint y = 2; x < 10; y = 3) {\n            assert(y == 2);\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 6328: (104-118): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\ny = 3\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_5.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        uint y;\n        for (y = 2; x < 10; ) {\n            y = 3;\n        }\n        assert(y == 3);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 6328: (135-149): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 10\\ny = 2\\n\\nTransaction trace:\\nC.constructor()\\nC.f(10)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_6.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        uint y;\n        for (y = 2; x < 10; ) {\n            y = 3;\n        }\n        // False positive due to resetting y.\n        assert(y < 4);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_array_assignment_memory_memory.sol",
    "content": "contract LoopFor2 {\n\tfunction testUnboundedForLoop(uint n, uint[] memory b, uint[] memory c) public pure {\n\t\trequire(n < b.length);\n\t\trequire(n < c.length);\n\t\trequire(n > 0 && n < 100);\n\t\tb[0] = 900;\n\t\tuint[] memory a = b;\n\t\tfor (uint i = 0; i < n; i += 1) {\n\t\t\t// Accesses are safe but oob is reported due to potential aliasing after c's assignment.\n\t\t\t// Disabled because of Spacer nondeterminism.\n\t\t\t//b[i] = i + 1;\n\t\t\t//c[i] = b[i];\n\t\t}\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(b[0] == c[0]);\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(a[0] == 900);\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(b[0] == 900);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (202-217): Unused local variable.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_array_assignment_memory_storage.sol",
    "content": "contract LoopFor2 {\n\tuint[] a;\n\tfunction p() public {\n\t\ta.push();\n\t}\n\tfunction testUnboundedForLoop(uint n, uint[] memory b, uint[] memory c) public {\n\t\trequire(n < a.length);\n\t\trequire(n < b.length);\n\t\trequire(n < c.length);\n\t\trequire(n > 0 && n < 100);\n\t\tb[0] = 900;\n\t\ta = b;\n\t\tfor (uint i = 0; i < n; i += 1) {\n\t\t\t// Accesses are safe but oob is reported due to potential aliasing after c's assignment.\n\t\t\tb[i] = i + 1;\n\t\t\t// Disabled because of Spacer's nondeterminism.\n\t\t\t//c[i] = b[i];\n\t\t}\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(b[0] == c[0]);\n\t\t//assert(a[0] == 900);\n\t\t//assert(b[0] == 900);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_array_assignment_storage_memory.sol",
    "content": "// Most of the code has been commented out because of nondeterminism in Spacer in Z3 4.8.9\ncontract LoopFor2 {\n\tuint[] b;\n\t//uint[] c;\n\tfunction p() public {\n\t\tb.push();\n\t}\n\tfunction testUnboundedForLoop(uint n) public {\n\t\trequire(b.length > 0);\n\t\tb[0] = 900;\n\t\t//uint[] memory a = b;\n\t\trequire(n > 0 && n < 100);\n\t\tfor (uint i = 0; i < n; i += 1) {\n\t\t\t//b[i] = i + 1;\n\t\t\t//c[i] = b[i];\n\t\t}\n\t\t// This is safe but too hard to solve currently.\n\t\t//assert(b[0] == c[0]);\n\t\t//assert(a[0] == 900);\n\t\t//assert(b[0] == 900);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_array_assignment_storage_storage.sol",
    "content": "contract LoopFor2 {\n\tuint[] b;\n\tuint[] c;\n\n\t// Disabled because of Spancer nondeterminism in the overflow queries\n\t// which can't be disabled separately.\n\t/*\n\tfunction testUnboundedForLoop(uint n) public {\n\t\tb[0] = 900;\n\t\tuint[] storage a = b;\n\t\trequire(n > 0 && n < 100);\n\t\tfor (uint i = 0; i < n; i += 1) {\n\t\t\tb[i] = i + 1;\n\t\t\tc[i] = b[i];\n\t\t}\n\t\t// This is safe but too hard to prove currently.\n\t\tassert(b[0] == c[0]);\n\t\tassert(a[0] == 900);\n\t\tassert(b[0] == 900);\n\t}\n\t*/\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_1.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\t++x;\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_10.sol",
    "content": "contract C\n{\n\tuint256[] y;\n\n\tfunction f() public view {\n\t\tuint256 x = 0;\n\t\tfor (uint i = 0; i < y.length; i++) {\n\t\t\tx = 1;\n\t\t}\n\t\t// tests that constant condition warning is not reported\n\t\trequire(x != 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 1\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_2.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 3; ++i)\n\t\t\tx = i;\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_3.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 3; ++i)\n\t\t\tif (i > 1)\n\t\t\t\tx = 10;\n\t\tassert(x == 10);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n//  Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_4.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 0; ++i)\n\t\t\t++x;\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_5.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (; x < 0; ++x) {}\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 1\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_6.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tfor (uint i = 1; i < 3;) {\n\t\t\tx = i;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_7.sol",
    "content": "contract C\n{\n\tuint x;\n\n\tfunction condition() private returns(bool) {\n\t\t++x;\n\t\treturn x < 3;\n\t}\n\n\tfunction f() public {\n\t\trequire(x == 0);\n\t\tfor (; condition();) {\n\t\t}\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 5\n// ----\n// Warning 2661: (71-74): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_8.sol",
    "content": "contract C\n{\n\tuint x;\n\tuint y;\n\n\tfunction condition() private returns(bool) {\n\t\t++x;\n\t\treturn x < 3;\n\t}\n\n\tfunction expression() private {\n\t\t++y;\n\t}\n\n\tfunction f() public {\n\t\trequire(x == 0);\n\t\trequire(y == 0);\n\t\tfor (; condition(); expression()) {\n\t\t}\n\t\tassert(x == 3);\n\t\tassert(y == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 5\n// ----\n// Warning 2661: (80-83): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 2661: (140-143): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_9.sol",
    "content": "contract C\n{\n\tuint x;\n\tuint y;\n\n\tfunction condition() private returns(bool) {\n\t\tx = (x + 1) % 2;\n\t\treturn (x == 1);\n\t}\n\n\tfunction f() public {\n\t\trequire(x == 0);\n\t\trequire(y == 0);\n\t\tfor (; condition();) {\n\t\t\t++y;\n\t\t}\n\t\tassert(y == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 5\n// ----\n// Warning 2661: (85-90): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_assertion_fails_1.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\t++x;\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Warning 4661: (92-106): BMC: Assertion violation happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_assertion_fails_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 2; ++i) {\n\t\t\t++x;\n\t\t\tbreak;\n\t\t}\n\t\tassert(x == 0);\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Warning 5740: (77-80): Unreachable code.\n// Warning 4661: (108-122): BMC: Assertion violation happens here.\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_assertion_fails_3.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 2; ++i) {\n\t\t\t++x;\n\t\t\tcontinue;\n\t\t}\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Warning 4661: (111-125): BMC: Assertion violation happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_1.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 3; ++i) {\n\t\t\tbreak;\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Warning 5740: (77-80): Unreachable code.\n// Warning 5740: (97-100): Unreachable code.\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_2.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 3; ++i) {\n\t\t\t++x;\n\t\t\tbreak;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Warning 5740: (77-80): Unreachable code.\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_3.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 3; ++i) {\n\t\t\tif (i > 0)\n\t\t\t\tbreak;\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_4.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 3; ++i) {\n\t\t\t++x;\n\t\t\tif (i > 0)\n\t\t\t\tbreak;\n\t\t}\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_5.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 3; ++i) {\n\t\t\tif (i > 1) {\n\t\t\t\tx = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (i > 1) {\n\t\t\t\tx = 2;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_6.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 3; ++i) {\n\t\t\tif (i > 1) {\n\t\t\t\tx = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (i >= 1) {\n\t\t\t\tx = 2;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_7.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (;;) {\n\t\t\t++x;\n\t\t\tbreak;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_8.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (;;) {\n\t\t\tbreak;\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Warning 5740: (77-80): Unreachable code.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_9.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (;x < 2;) {\n\t\t\t++x;\n\t\t\tbreak;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_1.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 3; ++i) {\n\t\t\tif (i > 1) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (i >= 0) {\n\t\t\t\tx = 10;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tassert(x == 10);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_2.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 2; ++i) {\n\t\t\tif (i > 0) {\n\t\t\t\tx = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (i >= 0) {\n\t\t\t\tx = 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 2\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_break_continue_3.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 3; ++i) {\n\t\t\tif (i > 0) {\n\t\t\t\tx = 1;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tx = 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_continue_1.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\tfor (uint i = 0; i < 3; ++i) {\n\t\t\tif (i > 1)\n\t\t\t\tcontinue;\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_continue_2.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 2; ++i) {\n\t\t\tif (i == 1) {\n\t\t\t\tx = 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (i == 0) {\n\t\t\t\tx = 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_continue_3.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\tfor (uint i = 0; i < 3; ++i) {\n\t\t\tif (x > 1) {\n\t\t\t\tx = 10;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (x > 0) {\n\t\t\t\tx = 11;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 10);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_continue_4.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (; x < 2; ++x) {\n\t\t\tif (x > 1) {\n\t\t\t\tx = 10;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (x > 0) {\n\t\t\t\tx = 11;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\t// x > 0 branch triggers x = 11 and continue triggers ++x loop expression\n\t\tassert(x == 12);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_continue_5.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (; x < 2; ++x) {\n\t\t\tcontinue;\n\t\t}\n\t\t// loop expression is executed after continue\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_false_positive.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tfor (;;) {\n\t\t\tx = 1;\n\t\t}\n\t\tassert(x == 1000);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_nested.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x;\n\t\tfor (uint i = 0; i < 2; ++i) {\n\t\t\tfor (uint j = 0; j < 2; ++j)\n\t\t\t\t++x;\n\t\t}\n\t\tassert(x == 4);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_nested_break.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\tfor (uint i = 0; i < 2; ++i) {\n\t\t\tfor (uint j = 0; j < 2; ++j) {\n\t\t\t\tx = x + 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Warning 5740: (92-95): Unreachable code.\n// Warning 5740: (126-129): Unreachable code.\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_nested_continue.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tfor (uint i = 0; i < 2; ++i) {\n\t\t\tfor (uint j = 0; j < 2; ++j) {\n\t\t\t    if (i > 0)\n\t\t\t\t\tcontinue;\n\t\t\t\t++x;\n\t\t\t}\n\t\t}\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_semantics_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tint y = 0;\n\t\tfor (; x < 3 || y == 1; ++x) {\n\t\t\tif (x >= 3)\n\t\t\t\ty = 1;\n\t\t}\n        // BMC loop iteration setting is not enough to leave the loop\n\t\tassert(x == 0); // should hold - no assumptions on value if didn't complete the loop\n\t\tassert(y == 0); // should hold - no assumptions on value if didn't complete the loop\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 2\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_semantics_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tint y = 0;\n\t\tfor (; x < 3 || y == 1; ++x) {\n\t\t\tif (x >= 3)\n\t\t\t\ty = 1;\n\t\t}\n\t\t// BMC loop iteration setting is just enough to leave the loop\n\t\tassert(x == 3);\n\t\tassert(y == 1); // should fail\n\t\tassert(y == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Warning 4661: (216-230): BMC: Assertion violation happens here.\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_semantics_3.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tint y = 0;\n\t\tfor (; x < 3 || y == 1; ++x) {\n\t\t\tif (x >= 3)\n\t\t\t\ty = 1;\n\t\t}\n\t\t// BMC loop iteration setting is more than enough to leave the loop\n\t\tassert(x == 3);\n\t\tassert(y == 1); // should fail\n\t\tassert(y == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Warning 4661: (221-235): BMC: Assertion violation happens here.\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_bmc_iterations_shallow_unroll.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tfor (uint i = 0; i < 2; ++i) {\n\t\t\t++x;\n\t\t}\n\t\t// nothing is reported because loop condition is still true after BMCLoopIterations\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 1\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol",
    "content": "contract Test {\n    function loop() public pure {\n        for (uint k = 0; (k == 0 ? true : false); k++) {\n        }\n    }\n}\n// ====\n// SMTEngine: bmc\n// SMTTargets: constantCondition\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_trivial_condition_1.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        require(x == 2);\n        for (; x == 2;) {}\n        assert(x == 2);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_trivial_condition_2.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        require(x == 2);\n        uint y;\n        for (; x == 2;) {\n            y = 7;\n        }\n        assert(x == 2);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/for_loop_trivial_condition_3.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        require(x == 2);\n        uint y;\n        // The loop condition is always true,\n        // but since x is touched in the body\n        // we can't infer that.\n        for (; x == 2;) {\n            x = 2;\n        }\n        // False positive due to resetting x.\n        assert(x == 2);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 2072: (83-89): Unused local variable.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_1.sol",
    "content": "contract C\n{\n\tfunction f(uint x, bool b) public pure {\n\t\trequire(x < 100);\n\t\twhile (x < 10) {\n\t\t\tif (b)\n\t\t\t\tx = x + 1;\n\t\t\telse\n\t\t\t\tx = 0;\n\t\t}\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_1_break.sol",
    "content": "contract C\n{\n\tfunction f(uint x, bool b) public pure {\n\t\trequire(x < 10);\n\t\twhile (x < 10) {\n\t\t\tif (b)\n\t\t\t\t++x;\n\t\t\telse {\n\t\t\t\tx = 20;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tassert(x >= 10);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_1_break_fail.sol",
    "content": "contract C\n{\n\tfunction f(uint x, bool b) public pure {\n\t\trequire(x < 10);\n\t\twhile (x < 10) {\n\t\t\tif (b)\n\t\t\t\t++x;\n\t\t\telse {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// Fails because the loop might break.\n\t\tassert(x >= 10);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 6328: (185-200): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_1_continue.sol",
    "content": "contract C\n{\n\tfunction f(uint x, bool b) public pure {\n\t\trequire(x < 10);\n\t\twhile (x < 10) {\n\t\t\tif (b) {\n\t\t\t\tx = 20;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t++x;\n\t\t}\n\t\tassert(x >= 10);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_1_continue_fail.sol",
    "content": "contract C\n{\n\tfunction f(uint x, bool b) public pure {\n\t\trequire(x < 100);\n\t\twhile (x < 10) {\n\t\t\tif (b) {\n\t\t\t\tx = 15;\n\t\t\t\tcontinue;\n\t\t\t\tx = 200;\n\t\t\t}\n\t\t\tx = 20;\n\n\t\t}\n\t\t// Fails due to the if.\n\t\tassert(x >= 17);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 5740: (136-143): Unreachable code.\n// Warning 6328: (194-209): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 10\\nb = false\\n\\nTransaction trace:\\nC.constructor()\\nC.f(10, false)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_1_fail.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x < 100);\n\t\twhile (x < 10) {\n\t\t\tx = x + 1;\n\t\t}\n\t\tassert(x < 14);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 6328: (106-120): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_1_infinite.sol",
    "content": "contract C\n{\n\tfunction f(uint x, bool b) public pure {\n\t\trequire(x < 100);\n\t\twhile (x < 10) {\n\t\t\tif (b)\n\t\t\t\tx = x + 1;\n\t\t\telse\n\t\t\t\tx = 0;\n\t\t}\n\t\t// CHC proves it safe because\n\t\t// 1- if it doesn't go in the loop in the first place, x >= 10\n\t\t// 2- if it goes in the loop and b == true, x increases until >= 10\n\t\t// 3- if it goes in the loop and b == false, it's an infinite loop, therefore\n\t\t//    the assertion and the error are unreachable.\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_2.sol",
    "content": "contract C {\n\tfunction f(uint x) public pure {\n\t\tx = 2;\n\t\twhile (x > 1) {\n\t\t\tif (x > 10)\n\t\t\t\tx = 2;\n\t\t\telse\n\t\t\t\t--x;\n\t\t}\n\t\tassert(x < 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_2_break.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\twhile (x == 0) {\n\t\t\t++x;\n\t\t\tbreak;\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 5740: (95-98): Unreachable code.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_2_break_fail.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\twhile (x == 0) {\n\t\t\t++x;\n\t\t\tbreak;\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTSolvers: z3\n// ----\n// Warning 5740: (87-90): Unreachable code.\n// Warning 6328: (98-112): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_2_fail.sol",
    "content": "contract C {\n\tfunction f(uint x) public pure {\n\t\tx = 2;\n\t\twhile (x > 1) {\n\t\t\tif (x > 10)\n\t\t\t\tx = 2;\n\t\t\telse\n\t\t\t\tx = 10;\n\t\t}\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_1.sol",
    "content": "contract C {\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\tuint y;\n\t\twhile (y < 3) {\n\t\t\t++y;\n\t\t\tif (y == 2)\n\t\t\t    x = 3;\n\t\t}\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 2\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 3) {\n\t\t\t++x;\n\t\t\t{\n\t\t\t\t++x;\n\t\t\t\t++x;\n\t\t\t}\n\t\t}\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_3.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 3) {\n\t\t\tif (x >= 2)\n\t\t\t\t++x;\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 4);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 5\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_4.sol",
    "content": "contract C {\n\tfunction f(uint x) public pure {\n\t\tx = 0;\n\t\twhile (x < 1) {\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_5.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (true) {\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 1000);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 1\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_6.sol",
    "content": "contract C\n{\n\tuint x;\n\tuint y;\n\n\tfunction condition() private returns(bool) {\n\t\tx = (x + 1) % 2;\n\t\treturn (x == 1);\n\t}\n\n\tfunction f() public {\n\t\trequire(x == 0);\n\t\trequire(y == 0);\n\t\twhile (condition()) {\n\t\t\t++y;\n\t\t}\n\t\tassert(y == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 5\n// ----\n// Warning 2661: (85-90): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_7.sol",
    "content": "contract C {\n    uint x;\n\n    function condition() private returns(bool) {\n\t\t++x;\n\t\treturn x < 3;\n\t}\n\n\tfunction f() public {\n\t\trequire(x == 0);\n\t\twhile (condition()) {\n\t\t}\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 5\n// ----\n// Warning 2661: (77-80): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_8.sol",
    "content": "contract C\n{\n\tuint256[] y;\n\n\tfunction f() public view {\n\t\tuint256 x = 0;\n\t\twhile (x < y.length) {\n\t\t\tx = 1;\n\t\t}\n\t\t// tests that constant condition warning is not reported\n\t\trequire(x != 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 1\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_assertion_fails_1.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\twhile (x < 2) {\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Warning 4661: (98-112): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_assertion_fails_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 2) {\n\t\t\t++x;\n\t\t\tbreak;\n\t\t}\n\t\tassert(x == 0);\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 2\n// ----\n// Warning 4661: (93-107): BMC: Assertion violation happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_assertion_fails_3.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 2) {\n\t\t\t++x;\n\t\t\tcontinue;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Warning 4661: (96-110): BMC: Assertion violation happens here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 3) {\n\t\t\t++x;\n\t\t\tbreak;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 3) {\n\t\t\tif (x > 0)\n\t\t\t\tbreak;\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_3.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 3) {\n\t\t\tif (x > 0) {\n\t\t\t\t++x;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_4.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 3) {\n\t\t\t++x;\n\t\t\tif (x > 0) {\n\t\t\t\t++x;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_5.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 3) {\n\t\t\t++x;\n\t\t\tif (x > 1) {\n\t\t\t\t++x;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_6.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 3) {\n\t\t\t++x;\n\t\t\tif (x > 0) {\n\t\t\t\tx = 2;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (x > 1) {\n\t\t\t\tx = 3;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_7.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 3) {\n\t\t\t++x;\n\t\t\tif (x > 1) {\n\t\t\t\tx = 3;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (x > 0) {\n\t\t\t\tx = 2;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_8.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\twhile (x < 3) {\n\t\t\tif (x >= 0) {\n\t\t\t\t++x;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_9.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\twhile (x < 3) {\n\t\t\t++x;\n\t\t\tbreak;\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Warning 5740: (94-97): Unreachable code.\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_continue_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 3) {\n\t\t\tif (x > 1) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (x >= 0) {\n\t\t\t\tx = 10;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tassert(x == 10);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_break_continue_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\twhile (x < 3) {\n\t\t\tif (x > 1) {\n\t\t\t\tx = 3;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (x >= 0) {\n\t\t\t\tx = 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_continue_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tuint i;\n\t\twhile (i < 3) {\n\t\t\t++i;\n\t\t\tif (i > 1)\n\t\t\t\tcontinue;\n\t\t\t++x;\n\t\t}\n\t\tassert(x == 1);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_continue_2.sol",
    "content": "contract C {\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\tuint i;\n\t\twhile (i < 3) {\n\t\t\t ++i;\n\t\t\tif (i == 2) {\n\t\t\t\tx = 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (i == 1) {\n\t\t\t\tx = 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_nested.sol",
    "content": "contract C {\n\tfunction f(uint z) public pure {\n\t\tuint x = 0;\n\t\trequire(z == 0);\n\t\twhile (x < 2) {\n\t\t\tuint y = 0;\n\t\t\twhile (y < 2) {\n\t\t\t\t++z;\n\t\t\t\t++y;\n\t\t\t}\n\t\t\t++x;\n\t\t}\n\t\tassert(z == 4);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_nested_break.sol",
    "content": "contract C {\n\tfunction f(uint z) public pure {\n\t\tuint x = 0;\n\t\trequire(z == 0);\n\t\twhile (x < 2) {\n\t\t\tuint y = 0;\n\t\t\twhile (y < 2) {\n\t\t\t\tif (y > 0)\n\t\t\t\t\tbreak;\n\t\t\t\t++z;\n\t\t\t\t++y;\n\t\t\t}\n\t\t\t++x;\n\t\t}\n\t\tassert(z == 2);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_nested_continue.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x;\n\t\tuint i;\n\t\twhile (i < 3) {\n\t\t\t++i;\n\t\t\tuint j;\n\t\t\twhile (j < 3) {\n\t\t\t\t++j;\n\t\t\t\tif (i > 1)\n\t\t\t\t\tcontinue;\n\t\t\t\t++x;\n\t\t\t}\n\t\t}\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_semantics_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tint y = 0;\n\t\twhile (x < 3 || y == 1) {\n\t\t\tif (x >= 3)\n\t\t\t\ty = 1;\n\t\t\t++x;\n\t\t}\n\t\t// BMC loop iteration setting is not enough to leave the loop\n\t\tassert(x == 0); // should hold - no assumptions on value if didn't complete the loop\n\t\tassert(y == 0); // should hold - no assumptions on value if didn't complete the loop\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 2\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_semantics_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tint y = 0;\n\t\twhile (x < 3 || y == 1) {\n\t\t\tif (x >= 3)\n\t\t\t\ty = 1;\n\t\t\t++x;\n\t\t}\n\t\t// BMC loop iteration setting is just enough to leave the loop\n\t\tassert(x == 3);\n\t\tassert(y == 1); // should fail\n\t\tassert(y == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 3\n// ----\n// Warning 4661: (219-233): BMC: Assertion violation happens here.\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_semantics_3.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\tint y = 0;\n\t\twhile (x < 3 || y == 1) {\n\t\t\tif (x >= 3)\n\t\t\t\ty = 1;\n\t\t\t++x;\n\t\t}\n\t\t// BMC loop iteration setting is more than enough to leave the loop\n\t\tassert(x == 3);\n\t\tassert(y == 1); // should fail\n\t\tassert(y == 0);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 4\n// ----\n// Warning 4661: (224-238): BMC: Assertion violation happens here.\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_bmc_iterations_shallow_unroll.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = 0;\n\t\twhile (x < 5) {\n\t\t\tx = x + 1;\n\t\t}\n\t\t// nothing is reported because loop condition is true after unrolling the loop one time\n\t\tassert(x == 5);\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTSolvers: z3\n// BMCLoopIterations: 1\n// ----\n// Info 6002: BMC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_break_direct.sol",
    "content": "contract C {\n\tfunction f(uint x) public pure {\n\t\tx = 0;\n\t\twhile (x < 10)\n\t\t\tbreak;\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_loop_array_assignment_memory_memory.sol",
    "content": "contract LoopFor2 {\n\tfunction testUnboundedForLoop(uint n, uint[] memory b, uint[] memory c) public pure {\n\t\trequire(n < b.length);\n\t\trequire(n < c.length);\n\t\trequire(n > 0 && n < 100);\n\t\tb[0] = 900;\n\t\tuint[] memory a = b;\n\t\tuint i;\n\t\t// Disabled because of Spacer's nondeterminism.\n\t\t/*\n\t\twhile (i < n) {\n\t\t\t// Accesses are safe but oob is reported due to potential aliasing after c's assignment.\n\t\t\tb[i] = i + 1;\n\t\t\tc[i] = b[i];\n\t\t\t++i;\n\t\t}\n\t\t*/\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(b[0] == c[0]);\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(a[0] == 900);\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(b[0] == 900);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTSolvers: z3\n// ----\n// Warning 2072: (202-217): Unused local variable.\n// Warning 2072: (225-231): Unused local variable.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_loop_array_assignment_memory_storage.sol",
    "content": "contract LoopFor2 {\n\tuint[] a;\n\tfunction p() public {\n\t\ta.push();\n\t}\n\tfunction testUnboundedForLoop(uint n, uint[] memory b, uint[] memory c) public {\n\t\trequire(n < a.length);\n\t\trequire(n < b.length);\n\t\trequire(n < c.length);\n\t\tb[0] = 900;\n\t\ta = b;\n\t\trequire(n > 0 && n < 100);\n\t\tuint i;\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t/*\n\t\twhile (i < n) {\n\t\t\t// Accesses are safe but oob is reported due to potential aliasing after c's assignment.\n\t\t\tb[i] = i + 1;\n\t\t\tc[i] = b[i];\n\t\t\t++i;\n\t\t}\n\t\t*/\n\t\t// Fails due to aliasing, since both b and c are\n\t\t// memory references of same type.\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(b[0] == c[0]);\n\t\tassert(a[0] == 900);\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(b[0] == 900);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 2072: (280-286): Unused local variable.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_loop_array_assignment_storage_storage.sol",
    "content": "contract LoopFor2 {\n\tuint[] b;\n\tuint[] c;\n\tfunction p() public {\n\t\tb.push();\n\t\tc.push();\n\t}\n\tfunction testUnboundedForLoop(uint n) public {\n\t\trequire(n < b.length);\n\t\trequire(n < c.length);\n\t\trequire(n > 0 && n < 100);\n\t\tb[0] = 900;\n\t\tuint[] storage a = b;\n\t\tuint i;\n\t\twhile (i < n) {\n\t\t\tb[i] = i + 1;\n\t\t\t//c[i] = b[i]; // Removed because of Spacer's nondeterminism\n\t\t\t++i;\n\t\t}\n\t\t//assert(b[0] == c[0]); // Removed because of Spacer's nondeterminism\n\t\tassert(a[0] == 900);\n\t\tassert(b[0] == 900);\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTTargets: assert\n// ----\n// Warning 6328: (452-471): CHC: Assertion violation happens here.\\nCounterexample:\\nb = [1, 0], c = [0, 0]\\nn = 1\\ni = 1\\n\\nTransaction trace:\\nLoopFor2.constructor()\\nState: b = [], c = []\\nLoopFor2.p()\\nState: b = [0], c = [0]\\nLoopFor2.p()\\nState: b = [0, 0], c = [0, 0]\\nLoopFor2.testUnboundedForLoop(1)\n// Warning 6328: (475-494): CHC: Assertion violation happens here.\\nCounterexample:\\nb = [1, 0], c = [0, 0]\\nn = 1\\ni = 1\\n\\nTransaction trace:\\nLoopFor2.constructor()\\nState: b = [], c = []\\nLoopFor2.p()\\nState: b = [0], c = [0]\\nLoopFor2.p()\\nState: b = [0, 0], c = [0, 0]\\nLoopFor2.testUnboundedForLoop(1)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_loop_condition_constant_true_in_first_iteration_and_constant_false_in_second.sol",
    "content": "contract Test {\n    function loop() public pure {\n        uint k = 0;\n        while (k == 0 ? true : false) {\n            ++k;\n        }\n    }\n}\n// ====\n// SMTEngine: bmc\n// SMTTargets: constantCondition\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_loop_simple_1.sol",
    "content": "// Check that variables are cleared\ncontract C {\n    function f(uint x) public pure {\n        x = 2;\n        while (x > 1) {\n            x = 1;\n        }\n        assert(x == 2);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (162-176): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 1\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_loop_simple_2.sol",
    "content": "// Check that condition is assumed.\ncontract C {\n    function f(uint x) public pure {\n        while (x == 2) {\n            assert(x == 2);\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_loop_simple_3.sol",
    "content": "// Check that condition is not assumed after the body anymore\ncontract C {\n    function f(uint x) public pure {\n        while (x == 2) {\n        }\n        assert(x == 2);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTSolvers: z3\n// ----\n// Warning 6328: (155-169): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_loop_simple_4.sol",
    "content": "// Check that negation of condition is not assumed after the body anymore\ncontract C {\n    function f(uint x) public pure {\n        while (x == 2) {\n        }\n        assert(x != 2);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_loop_simple_5.sol",
    "content": "// Check that side-effects of condition are taken into account\ncontract C {\n    function f(uint x, uint y) public pure {\n        x = 7;\n        while ((x = y) > 0) {\n\t\t\t--y;\n        }\n        assert(x == 7);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Warning 6328: (192-206): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_nested_break.sol",
    "content": "contract C\n{\n\tfunction f(uint x, uint y, bool b, bool c) public pure {\n\t\trequire(x < 10);\n\t\twhile (x < 10) {\n\t\t\tif (b) {\n\t\t\t\t++x;\n\t\t\t\tif (x == 10)\n\t\t\t\t\tx = 15;\n\t\t\t}\n\t\t\telse {\n\t\t\t\trequire(y < 10);\n\t\t\t\twhile (y < 10) {\n\t\t\t\t\tif (c)\n\t\t\t\t\t\t++y;\n\t\t\t\t\telse {\n\t\t\t\t\t\ty = 20;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tassert(y >= 10);\n\t\t\t\tx = 15;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tassert(x >= 15);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_nested_break_fail.sol",
    "content": "contract C\n{\n\tfunction f(uint x, uint y, bool b, bool c) public pure {\n\t\trequire(x < 10);\n\t\twhile (x < 10) {\n\t\t\tif (b) {\n\t\t\t\t++x;\n\t\t\t\tif (x == 10)\n\t\t\t\t\tx = 15;\n\t\t\t}\n\t\t\telse {\n\t\t\t\trequire(y < 10);\n\t\t\t\twhile (y < 10) {\n\t\t\t\t\tif (c)\n\t\t\t\t\t\t++y;\n\t\t\t\t\telse {\n\t\t\t\t\t\ty = 20;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tassert(y >= 15);\n\t\t\t\tx = 15;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tassert(x >= 20);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (296-311): CHC: Assertion violation happens here.\n// Warning 6328: (347-362): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_nested_continue.sol",
    "content": "contract C\n{\n\tfunction f(uint x, uint y, bool b, bool c) public pure {\n\t\trequire(x < 10);\n\t\twhile (x < 10) {\n\t\t\tif (b) {\n\t\t\t\tx = 20;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse {\n\t\t\t\trequire(y < 10);\n\t\t\t\twhile (y < 10) {\n\t\t\t\t\tif (c) {\n\t\t\t\t\t\ty = 20;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\ty = 15;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tassert(y >= 15);\n\t\t\t\tx = y;\n\t\t\t}\n\t\t}\n\t\tassert(x >= 15);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/loops/while_nested_continue_fail.sol",
    "content": "contract C\n{\n\tfunction f(uint x, uint y, bool b, bool c) public pure {\n\t\trequire(x < 10);\n\t\twhile (x < 10) {\n\t\t\tif (b) {\n\t\t\t\tx = 15;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse {\n\t\t\t\trequire(y < 10);\n\t\t\t\twhile (y < 10) {\n\t\t\t\t\tif (c) {\n\t\t\t\t\t\ty = 20;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\ty = 15;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tassert(y >= 20);\n\t\t\t\tx = y;\n\t\t\t}\n\t\t}\n\t\tassert(x >= 20);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (290-305): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\ny = 15\\nb = false\\nc = false\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0, 0, false, false)\n// Warning 6328: (329-344): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 15\\ny = 0\\nb = true\\nc = false\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0, 0, true, false)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/math/addmod_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tassert(addmod(2**256 - 1, 10, 9) == 7);\n\t\tuint y = 0;\n\t\tuint x = addmod(2**256 - 1, 10, y);\n\t\tassert(x == 1);\n\t}\n\tfunction g(uint x, uint y, uint k) public pure returns (uint) {\n\t\treturn addmod(x, y, k);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4281: (108-133): CHC: Division by zero happens here.\n// Warning 6328: (137-151): CHC: Assertion violation happens here.\n// Warning 4281: (230-245): CHC: Division by zero happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/math/addmod_mulmod.sol",
    "content": "contract C {\n\tfunction test() public pure {\n\t\tuint x;\n\t\tif ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) x = 1;\n\t\tif ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) x = 2;\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (60-110): BMC: Condition is always false.\n// Warning 6838: (125-175): BMC: Condition is always false.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/math/addmod_mulmod_zero.sol",
    "content": "contract C {\n\tfunction f(uint256 d) public pure {\n\t\tuint x = addmod(1, 2, d);\n\t\tassert(x < d);\n\t}\n\n\tfunction g(uint256 d) public pure {\n\t\tuint x = mulmod(1, 2, d);\n\t\tassert(x < d);\n\t}\n\n\tfunction h() public pure returns (uint256) {\n\t\tuint x = mulmod(0, 1, 2);\n\t\tuint y = mulmod(1, 0, 2);\n\t\tassert(x == y);\n\t\tuint z = addmod(0, 1, 2);\n\t\tuint t = addmod(1, 0, 2);\n\t\tassert(z == t);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (220-227): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 4281: (61-76): CHC: Division by zero happens here.\n// Warning 6328: (80-93): CHC: Assertion violation happens here.\n// Warning 4281: (147-162): CHC: Division by zero happens here.\n// Warning 6328: (166-179): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/math/addmulmod.sol",
    "content": "contract C {\n\tfunction test_addmod(uint x, uint y) public pure {\n\t\trequire(x % 13 == 0);\n\t\trequire(y % 13 == 0);\n\n\t\tuint z = addmod(x, y, 13);\n\t\tassert(z == 0);\n\t}\n\tfunction test_mulmod(uint x, uint y) public pure {\n\t\trequire(x % 13 == 0);\n\t\trequire(y % 13 == 0);\n\n\t\tuint z = mulmod(x, y, 13);\n\t\tassert(z == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/math/mulmod_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tassert(mulmod(2**256 - 1, 2, 14) == 2);\n\t\tuint y = 0;\n\t\tuint x = mulmod(2**256 - 1, 10, y);\n\t\tassert(x == 1);\n\t}\n\tfunction g(uint x, uint y, uint k) public pure returns (uint) {\n\t\treturn mulmod(x, y, k);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4281: (108-133): CHC: Division by zero happens here.\n// Warning 6328: (137-151): CHC: Assertion violation happens here.\n// Warning 4281: (230-245): CHC: Division by zero happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_abstract.sol",
    "content": "abstract contract A {\n\tfunction f() public mod {}\n\tmodifier mod virtual;\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8429: (51-72): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_assignment_outside_branch.sol",
    "content": "contract C\n{\n    uint x;\n    address owner;\n\n\tmodifier onlyOwner {\n        if (msg.sender == owner) _;\n    }\n\n    function f() public onlyOwner {\n    }\n\n    function g(uint y) public {\n        y = 1;\n        if (y > x) f();\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_code_after_placeholder.sol",
    "content": "contract C\n{\n\tuint x;\n\n\tmodifier m {\n\t\trequire(x > 0);\n\t\t_;\n\t\t// Fails because of overflow behavior.\n\t\tassert(x > 1);\n\t}\n\n\tfunction f() m public {\n\t\tassert(x > 0);\n\t\tunchecked { x = x + 1; }\n\t}\n\n\tfunction g(uint _x) public {\n\t\tx = _x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (103-116): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_control_flow.sol",
    "content": "contract C\n{\n\tuint x;\n\n\tmodifier m {\n\t\tif (x == 0)\n\t\t\t_;\n\t}\n\n\tfunction f() m public view {\n\t\tassert(x == 0);\n\t\tassert(x > 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (111-124): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_inline_function_inside_branch.sol",
    "content": "contract C\n{\n\taddress owner;\n\tmodifier m {\n\t\tif (true)\n\t\t\towner = g();\n\t\t_;\n\t}\n\tfunction f() m public {\n\t}\n\tfunction g() public pure returns (address) {\n\t\taddress a;\n\t\ta = address(0);\n\t\treturn a;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_inside_branch.sol",
    "content": "contract C {\n    address owner;\n    modifier onlyOwner {\n        if (msg.sender == owner) _;\n    }\n    function g() public onlyOwner {\n    }\n    function f(uint x) public {\n        if (x > 0) g();\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_inside_branch_assignment.sol",
    "content": "contract C {\n\tuint x;\n\taddress owner;\n\n\tmodifier onlyOwner {\n\t\tif (msg.sender == owner) _;\n\t}\n\n\tfunction f() public onlyOwner {\n\t\tx = 0;\n\t}\n\tfunction g(uint y) public {\n\t\tx = 1;\n\t\tif (y > 0)\n\t\t\tf();\n\t\t// Fails for {y = >0, msg.sender == owner, x = 0}.\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (254-267): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0, owner = 0x0\\ny = 1\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0, owner = 0x0\\nC.f()\\nState: x = 0, owner = 0x0\\nC.g(1)\\n    C.f() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_inside_branch_assignment_branch.sol",
    "content": "contract C {\n\tuint x;\n\taddress owner;\n\n\tmodifier onlyOwner {\n\t\tif (msg.sender == owner) {\n\t\t\trequire(x > 0);\n\t\t\t_;\n\t\t}\n\t}\n\n\tfunction f() public onlyOwner {\n\t\t// Condition is always true due to `require(x > 0)` in the modifier.\n\t\tif (x > 0)\n\t\t\tx -= 1;\n\t}\n\tfunction g(uint y) public {\n\t\tx = 2;\n\t\tif (y > 0)\n\t\t\tf();\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (233-238): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_inside_branch_assignment_multi_branches.sol",
    "content": "contract C {\n\tuint x;\n\taddress owner;\n\n\tmodifier onlyOwner {\n\t\tif (msg.sender == owner) {\n\t\t\trequire(x > 0);\n\t\t\t_;\n\t\t}\n\t}\n\n\tfunction f() public onlyOwner {\n\t\tx -= 1;\n\t\th();\n\t}\n\tfunction h() public onlyOwner {\n\t\trequire(x < 10000);\n\t\tx += 2;\n\t}\n\tfunction g(uint y) public {\n\t\trequire(y > 0 && y < 10000);\n\t\trequire(msg.sender == owner);\n\t\tx = y;\n\t\tif (y > 1) {\n\t\t\tf();\n\t\t\t// This now fails as a false positive because\n\t\t\t// CHC does not propagate msg.sender throughout predicates.\n\t\t\tassert(x == y + 1);\n\t\t}\n\t\t// Fails for {y = 0, x = 0}.\n\t\tassert(x == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (540-554): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_multi.sol",
    "content": "contract C\n{\n\tuint x;\n\n\tmodifier m {\n\t\trequire(x > 0);\n\t\trequire(x < 10000);\n\t\t_;\n\t}\n\n\tmodifier n {\n\t\tx = x + 1;\n\t\t_;\n\t\tassert(x > 2);\n\t\tassert(x > 8);\n\t}\n\n\tfunction f() m n public {\n\t\tx = x + 1;\n\t}\n\n\tfunction g(uint _x) public {\n\t\tx = _x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (137-150): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_multi_functions.sol",
    "content": "contract C\n{\n\tmodifier m(uint a, uint b) {\n\t\trequire(g(a, b));\n\t\t_;\n\t}\n\n\tmodifier notZero(uint x) {\n\t\trequire(x > 0);\n\t\t_;\n\t}\n\n\tfunction g(uint a, uint b) notZero(a) internal pure returns (bool) {\n\t\treturn a > b;\n\t}\n\n\tfunction f(uint x) m(x, 0) public pure {\n\t\tassert(x > 0);\n\t\tassert(x > 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (278-291): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_multi_functions_recursive.sol",
    "content": "contract C\n{\n\tmodifier m(uint a, uint b) {\n\t\trequire(g(a, b));\n\t\t_;\n\t}\n\n\tfunction g(uint a, uint b) m(a, b) internal pure returns (bool) {\n\t\treturn a > b;\n\t}\n\n\tfunction f(uint x) m(x, 0) public pure {\n\t\tassert(x > 0);\n\t\tassert(x > 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5740: (137-157): Unreachable code.\n// Warning 5740: (199-237): Unreachable code.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_multi_parameters.sol",
    "content": "contract C\n{\n\tmodifier m(uint a, uint b) {\n\t\trequire(a > b);\n\t\t_;\n\t}\n\n\tfunction f(uint x) m(x, 0) public pure {\n\t\tassert(x > 0);\n\t\tassert(x > 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (131-144): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_overflow.sol",
    "content": "contract C\n{\n\tuint x;\n\n\tmodifier m {\n\t\trequire(x > 0);\n\t\t_;\n\t}\n\n\tfunction f() m public {\n\t\tassert(x > 0);\n\t\tx = x + 1;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_1.sol",
    "content": "abstract contract A {\n\tuint s;\n\n\tfunction f() public mod(s) {}\n\tmodifier mod(uint x) virtual;\n}\n\ncontract B is A {\n\tmodifier mod(uint x) override {\n\t\trequire(x == 42);\n\t\t_;\n\t\tassert(x == 42); // should hold\n\t\tassert(x == 0); // should fail\n\t}\n\n\tfunction set(uint x) public {\n\t\ts = x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8429: (64-93): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 6328: (209-223): CHC: Assertion violation happens here.\\nCounterexample:\\ns = 42\\nx = 42\\n\\nTransaction trace:\\nB.constructor()\\nState: s = 0\\nB.set(42)\\nState: s = 42\\nA.f()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_2.sol",
    "content": "abstract contract A {\n\tbool s;\n\n\tfunction f() public view mod {\n\t\tassert(s); // holds for C, but fails for B\n\t}\n\tmodifier mod() virtual;\n}\n\ncontract B is A {\n\tmodifier mod() virtual override {\n\t\ts = false;\n\t\t_;\n\t}\n}\n\ncontract C is B {\n\tmodifier mod() override {\n\t\ts = true;\n\t\t_;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8429: (113-136): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (159-213): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 6328: (66-75): CHC: Assertion violation happens here.\\nCounterexample:\\ns = false\\n\\nTransaction trace:\\nB.constructor()\\nState: s = false\\nA.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_3.sol",
    "content": "abstract contract A {\n\tbool s;\n\n\tfunction f() public view mod {\n\t\tassert(s); // holds for B\n\t\tassert(!s); // fails for B\n\t}\n\tmodifier mod() virtual;\n}\n\ncontract B is A {\n\tmodifier mod() virtual override {\n\t\tbool x = true;\n\t\ts = x;\n\t\t_;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8429: (125-148): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (171-238): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 6328: (94-104): CHC: Assertion violation happens here.\\nCounterexample:\\ns = true\\nx = true\\n\\nTransaction trace:\\nB.constructor()\\nState: s = false\\nA.f()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_overriding_4.sol",
    "content": "abstract contract A {\n\tint x = 0;\n\n\tfunction f() public view mod() {\n\t\tassert(x != 0); // does not hold for A, but A is abstract so it should not be reported\n\t\tassert(x != 1); // fails for B\n\t\tassert(x != 2); // fails for C\n\t\tassert(x != 3); // fails for D\n\t}\n\n\tmodifier mod() virtual {\n\t\t_;\n\t}\n}\n\ncontract B is A {\n\tmodifier mod() virtual override {\n\t\tx = 1;\n\t\t_;\n\t}\n}\n\ncontract C is A {\n\tmodifier mod() virtual override {\n\t\tx = 2;\n\t\t_;\n\t}\n}\n\ncontract D is B,C {\n\tmodifier mod() virtual override (B,C){\n\t\tx = 3;\n\t\t_;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8429: (262-294): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (317-367): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (390-440): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (465-520): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 6328: (160-174): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1\\n\\nTransaction trace:\\nB.constructor()\\nState: x = 0\\nA.f()\n// Warning 6328: (193-207): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nA.f()\n// Warning 6328: (226-240): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 3\\n\\nTransaction trace:\\nD.constructor()\\nState: x = 0\\nA.f()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_parameter_copy.sol",
    "content": "contract C\n{\n\tmodifier m(uint x) {\n\t\tx == 2;\n\t\t_;\n\t}\n\n\tfunction f(uint x) m(x) public pure {\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (95-109): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_parameters.sol",
    "content": "contract C\n{\n\tuint s;\n\tmodifier m(uint a) {\n\t\t// Condition is always true for m(2).\n\t\trequire(a > 0);\n\t\t_;\n\t}\n\n\tfunction f(uint x) m(x) m(2) m(s) public view {\n\t\tassert(x > 0);\n\t\tassert(s > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_return.sol",
    "content": "contract C\n{\n\tmodifier m(uint x) {\n\t\trequire(x == 2);\n\t\t_;\n\t\treturn;\n\t}\n\n\tmodifier n(uint x) {\n\t\trequire(x == 3);\n\t\t_;\n\t}\n\n\tfunction f(uint x) m(x) n(x) public pure {\n\t\tassert(x == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_same_local_variables.sol",
    "content": "contract C\n{\n\tmodifier m {\n\t\tuint x = 2;\n\t\t_;\n\t}\n\n\tfunction f(uint x) m public pure {\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (88-102): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\nx = 2\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_simple.sol",
    "content": "contract C\n{\n\tuint x;\n\n\tmodifier m {\n\t\trequire(x > 0);\n\t\t_;\n\t}\n\n\tfunction f() m public view {\n\t\tassert(x > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_two_invocations.sol",
    "content": "contract C\n{\n\tuint x;\n\n\tmodifier m {\n\t\t// Condition is always true for the second invocation.\n\t\trequire(x > 0);\n\t\trequire(x < 10000);\n\t\t_;\n\t\tassert(x > 1);\n\t}\n\n\tfunction f() m m public {\n\t\tx = x + 1;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_two_invocations_2.sol",
    "content": "contract C\n{\n\tuint x;\n\n\tmodifier m {\n\t\trequire(x == 0);\n\t\t_;\n\t\tx = x + 1;\n\t\tassert(x <= 2);\n\t}\n\n\tfunction f() m m public {\n\t\tx = x + 1;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (76-90): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 3\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.f()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_two_placeholders.sol",
    "content": "contract C\n{\n\tuint x;\n\n\tmodifier m {\n\t\trequire(x > 0);\n\t\trequire(x < 10000);\n\t\t_;\n\t\tassert(x > 1);\n\t\t_;\n\t\tassert(x > 2);\n\t\tassert(x > 10);\n\t}\n\n\tfunction f() m public {\n\t\tx = x + 1;\n\t}\n\n\tfunction g(uint _x) public {\n\t\tx = _x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (123-137): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_virtual_static_call_1.sol",
    "content": "contract A {\n    modifier m virtual {\n      _;\n    }\n}\ncontract C is A {\n    function f() public A.m returns (uint) {\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8429: (17-52): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/modifiers/modifier_virtual_static_call_2.sol",
    "content": "contract A {\n\tint x = 0;\n\n\tmodifier m virtual {\n\t\tassert(x == 0); // should hold\n\t\tassert(x == 42); // should fail\n\t\t_;\n\t}\n}\ncontract C is A {\n\n\tmodifier m override {\n\t\tassert(x == 1); // This assert is not reachable, should NOT be reported\n\t\t_;\n\t}\n\n\tfunction f() public A.m returns (uint) {\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8429: (27-122): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 6328: (83-98): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.f()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/natspec/abstract_free_function_1.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\ncontract C {\n    function f(uint x) external pure {\n        uint t = msb(x);\n        assert(t == 0); // should fail\n    }\n}\n\n/// @custom:smtchecker abstract-function-nondet\nfunction msb(uint256 x) pure returns (uint256 result) {}\n\n// ====\n// SMTEngine: chc\n// ----\n// Warning 6328: (144-158): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/natspec/abstract_function_nondet_1.sol",
    "content": "contract C {\n\t/// @custom:smtchecker abstract-function-nondet\n\tfunction f(uint x) internal pure returns (uint) {\n\t\treturn x;\n\t}\n\tfunction g(uint y) public pure {\n\t\tuint z = f(y);\n\t\t// Generally holds, but here it doesn't because function\n\t\t// `f` has been abstracted by nondeterministic values.\n\t\tassert(z == y);\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (297-311): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/natspec/abstract_function_nondet_pow_no_abstraction.sol",
    "content": "contract C {\n\tfunction e(uint _e) public pure {\n\t\t// Without abstracting function `pow` the solver\n\t\t// fails to prove that `++i` does not overflow.\n\t\tfor (uint i = 0; i < _e; ++i)\n\t\t\tpow(_e, _e);\n\t}\n\n\tfunction pow(uint base, uint exponent) internal pure returns (uint) {\n\t\t// Disabled because of Spacer nondet\n\t\t/*\n\t\tif (base == 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (exponent == 0) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (exponent == 1) {\n\t\t\treturn base;\n\t\t}\n\t\tuint y = 1;\n\t\twhile(exponent > 1) {\n\t\t\tif(exponent % 2 == 0) {\n\t\t\t\tbase = base * base;\n\t\t\t\texponent = exponent / 2;\n\t\t\t} else {\n\t\t\t\ty = base * y;\n\t\t\t\tbase = base * base;\n\t\t\t\texponent = (exponent - 1) / 2;\n\t\t\t}\n\t\t}\n\t\treturn base * y;\n\t\t*/\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/natspec/abstract_function_nondet_pow_with_abstraction.sol",
    "content": "contract C {\n\tfunction e(uint _e) public pure {\n\t\t// Without abstracting function `pow` the solver\n\t\t// fails to prove that `++i` does not overflow.\n\t\tfor (uint i = 0; i < _e; ++i)\n\t\t\tpow(_e, _e);\n\t}\n\n\t/// @custom:smtchecker abstract-function-nondet\n\tfunction pow(uint base, uint exponent) internal pure returns (uint) {\n\t\tif (base == 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (exponent == 0) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (exponent == 1) {\n\t\t\treturn base;\n\t\t}\n\t\tuint y = 1;\n\t\twhile(exponent > 1) {\n\t\t\tif(exponent % 2 == 0) {\n\t\t\t\tbase = base * base;\n\t\t\t\texponent = exponent / 2;\n\t\t\t} else {\n\t\t\t\ty = base * y;\n\t\t\t\tbase = base * base;\n\t\t\t\texponent = (exponent - 1) / 2;\n\t\t\t}\n\t\t}\n\t\treturn base * y;\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/natspec/natspec_smtchecker_empty.sol",
    "content": "contract C {\n\t/// @custom:smtchecker\n\tfunction f(uint x) internal pure returns (uint) {\n\t\treturn x;\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 3130: (38-102): Unknown option for \"custom:smtchecker\": \"\"\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/natspec/natspec_smtchecker_error_1.sol",
    "content": "contract C {\n\t/// @custom:smtchecker abstract-function\n\tfunction f(uint x) internal pure returns (uint) {\n\t\treturn x;\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 3130: (56-120): Unknown option for \"custom:smtchecker\": \"abstract-function\"\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/natspec/natspec_smtchecker_multi_errors_1.sol",
    "content": "contract C {\n    /// @custom:smtchecker b\n    /// @custom:smtchecker\n    /// @custom:smtchecker a b c\n    function f() internal {}\n}\n\ncontract D is C {}\n// ----\n// Warning 3130: (106-130): Unknown option for \"custom:smtchecker\": \"b\"\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/natspec/safe_assert_false_positive.sol",
    "content": "contract C {\n\tuint x;\n\tuint y;\n\n\tfunction g(uint _x) public {\n\t\tf1(_x);\n\t\t// If the body of function `f` is ignored while keeping the state,\n\t\t// the assertion is true and not reporting it would be a false negative.\n\t\t// However, since `f` can change the state, the state variables are also\n\t\t// assigned nondeterministic values after a call to `f`.\n\t\t// Therefore the assertion below should fail.\n\t\tassert(x == 0);\n\n\t\tf2(_x);\n\t\tassert(y == 0); // should fail\n\t}\n\n\t/// @custom:smtchecker abstract-function-nondet\n\tfunction f1(uint _x) internal {\n\t\tx = _x;\n\t}\n\n\tfunction f2(uint _y) internal {\n\t\ty = _y;\n\t}\n\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 6328: (400-414): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1, y = 0\\n_x = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0, y = 0\\nC.g(0)\\n    C.f1(0) -- internal call\n// Warning 6328: (429-443): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1, y = 1\\n_x = 1\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0, y = 0\\nC.g(1)\\n    C.f1(1) -- internal call\\n    C.f2(1) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/natspec/safe_assert_false_positive_pure.sol",
    "content": "contract C {\n\tuint x;\n\tuint y;\n\n\tfunction g(uint _x) public {\n\t\tuint z = f1(_x);\n\t\tassert(x == 0); // should hold because f1 is pure\n\t\tassert(z == _x); // should hold but f1 was abstracted as nondet, so it fails\n\n\t\tuint t = f2(_x);\n\t\tassert(y == 0); // should hold because f1 is pure and f2 is view\n\t\tassert(t == _x); // should hold\n\t}\n\n\t/// @custom:smtchecker abstract-function-nondet\n\tfunction f1(uint _x) internal pure returns (uint) {\n\t\treturn _x;\n\t}\n\n\tfunction f2(uint _y) internal view returns (uint) {\n\t\treturn _y;\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreCex: yes\n// ----\n// Warning 2018: (33-335): Function state mutability can be restricted to view\n// Warning 2018: (457-524): Function state mutability can be restricted to pure\n// Warning 6328: (135-150): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/natspec/unsafe_assert_remains_unsafe.sol",
    "content": "contract C {\n\tuint x;\n\tuint y;\n\n\tfunction g(uint _x) public {\n\t\tf1(_x);\n\t\tassert(x > 0); // should fail\n\n\t\tf2(_x);\n\t\tassert(y > 0); // should fail\n\t}\n\n\t/// @custom:smtchecker abstract-function-nondet\n\tfunction f1(uint _x) internal {\n\t\tx = _x;\n\t}\n\n\tfunction f2(uint _y) internal {\n\t\ty = _y;\n\t}\n\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 6328: (74-87): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0, y = 0\\n_x = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0, y = 0\\nC.g(0)\\n    C.f1(0) -- internal call\n// Warning 6328: (117-130): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 0, y = 0\\n_x = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0, y = 0\\nC.g(0)\\n    C.f1(0) -- internal call\\n    C.f2(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/assignment_chain_tuple_contract_1.sol",
    "content": "contract C {\n    string public name = (C).name = type(C).name;\n\n    function f() external view {\n        assert(keccak256(bytes(name)) == keccak256(bytes(\"C\"))); // should fail because SMTChecker doesn't support type(C).name\n    }\n}\n// ----\n// Warning 7507: (49-61): Assertion checker does not yet support this expression.\n// Warning 6328: (105-160): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/assignment_chain_tuple_contract_2.sol",
    "content": "contract C {\n    uint x = ((((C)))).x = ((C)).x = 2;\n\n    function f() external view {\n        assert(x == 2); // should hold\n    }\n\n    function g() external view {\n        assert(x != 2); // should fail\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (174-188): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 2\\nC.g()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/assignment_chain_tuple_contract_3.sol",
    "content": "contract C {\n    uint x = ((((C)))).x = ((C)).x = 2;\n\n    function f() external view {\n        assert(x == 2); // should fail for D\n    }\n\n    function g() external view {\n        assert(x != 2); // should fail for C\n    }\n}\n\ncontract D is C {\n    uint y = ((C)).x = 3;\n\n    function h() external view {\n        assert(y == 3); // should hold\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (95-109): CHC: Assertion violation happens here.\\nCounterexample:\\ny = 3, x = 3\\n\\nTransaction trace:\\nD.constructor()\\nState: y = 3, x = 3\\nC.f()\n// Warning 6328: (180-194): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 2\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 2\\nC.g()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable.sol",
    "content": "contract A {\n\tint x;\n\tint y;\n\tfunction a() public {\n\t\trequire(A.x < 100);\n\t\tA.y = A.x++;\n\t\tassert(A.y == A.x - 1);\n\t\t// Fails\n\t\t// assert(A.y == 0); // Disabled because of nondeterminism in Spacer\n\t\tA.y = ++A.x;\n\t\tassert(A.y == A.x);\n\t\tdelete A.x;\n\t\tassert(A.x == 0);\n\t\tA.y = A.x--;\n\t\tassert(A.y == A.x + 1);\n\t\tassert(A.y == 0);\n\t\tA.y = --A.x;\n\t\tassert(A.y == A.x);\n\t\tA.x += 10;\n\t\t// Fails\n\t\tassert(A.y == 0);\n\t\tassert(A.y + 10 == A.x);\n\t\tA.x -= 10;\n\t\tassert(A.y == A.x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreInv: yes\n// ----\n// Warning 6328: (392-408): CHC: Assertion violation happens here.\n// Info 1391: CHC: 26 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable_array.sol",
    "content": "contract A {\n\tuint[] a;\n\tfunction f() public {\n\t\tA.a.push(2);\n\t\tassert(A.a[A.a.length - 1] == 2);\n\t\tA.a.pop();\n\t\t// Fails\n\t\tassert(A.a.length > 0);\n\t\tassert(A.a.length == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (124-146): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable_array_2.sol",
    "content": "contract A {\n    int[] a;\n    function f() public {\n\t\tA.a.push();\n        A.a[0] = 2;\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/assignment_contract_member_variable_array_3.sol",
    "content": "contract A {\n\tint[] a;\n\tconstructor() {\n\t\tp();\n\t}\n\tfunction p() public {\n\t\ta.push(1);\n\t}\n\tfunction f() public {\n\t\trequire(a.length == 1 && a[0] == 1);\n\t\tint[] storage u = a;\n\t\tassert(u[0] == 1); // should hold\n\t\tint[] memory b = new int[](2);\n\t\ta = b;\n\t\t// Access is safe but oob is reported due to aliasing.\n\t\tassert(u[0] == 1); // should fail\n\t\tA.a = b;\n\t\t// Access is safe but oob is reported due to aliasing.\n\t\tassert(u[0] == 1); // should fail\n\t}\n\n\tfunction push_v(int x) public {\n\t\ta.push(x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6368: (318-322): CHC: Out of bounds access happens here.\n// Warning 6328: (311-328): CHC: Assertion violation happens here.\n// Warning 6368: (422-426): CHC: Out of bounds access happens here.\n// Warning 6328: (415-432): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/assignment_module_contract_member_variable.sol",
    "content": "==== Source: AASource ====\nimport \"AASource\" as AA;\ncontract A {\n\tint x;\n\tint y;\n\tfunction a() public {\n\t\trequire(A.x < 100);\n\t\tAA.A.y = A.x++;\n\t\tassert(A.y == AA.A.x - 1);\n\t\t// Fails\n\t\tassert(AA.A.y == 0);\n\t\tA.y = ++AA.A.x;\n\t\tassert(A.y == A.x);\n\t\tdelete AA.A.x;\n\t\tassert(A.x == 0);\n\t\tA.y = A.x--;\n\t\tassert(AA.A.y == AA.A.x + 1);\n\t\tA.y = --A.x;\n\t\tassert(A.y == A.x);\n\t\tAA.A.x += 10;\n\t\t// Fails\n\t\tassert(A.y == 0);\n\t\tassert(A.y + 10 == A.x);\n\t\tA.x -= 10;\n\t\tassert(AA.A.y == A.x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (AASource:159-178): CHC: Assertion violation happens here.\n// Warning 6328: (AASource:370-386): CHC: Assertion violation happens here.\n// Info 1391: CHC: 25 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_and_array.sol",
    "content": "contract C {\n\tfunction bitwiseXor(int[10] memory p) public pure {\n        1 ^ p[0];\n\t}\n\n\tfunction bitwiseAnd(int[10] memory p) public pure {\n\t\t1 & p[0];\n\t}\n\n\tfunction bitwiseOr(int[10] memory p) public pure {\n\t\t1 | p[0];\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_and_fixed_bytes.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tassert(bytes1(\"\") & (\"\") == bytes1(0)); // should hold\n\t\tassert(bytes1(0xAA) & bytes1(0x55) == bytes1(0)); // should hold\n\t\tassert(bytes1(0xFF) & bytes1(0xAA) == bytes1(0xAA)); // should hold\n\t\tassert(bytes1(0xFF) & bytes1(0xAA) == bytes1(0)); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (237-285): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_and_int.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tint8 x = 1;\n\t\tint8 y = 0;\n\t\tassert(x & y != 0); // should fail\n\t\tx = -1; y = 3;\n\t\tassert(x & y == 3); // should hold\n\t\ty = -1;\n\t\tint8 z = x & y;\n\t\tassert(z == -1); // should hold\n\t\ty = 127;\n\t\tassert(x & y == 127); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (71-89): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 1\\ny = 0\\nz = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_and_rational.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tassert(1 & 0 != 0);\n\t\tassert(-1 & 3 == 3);\n\t\tassert(-1 & -1 == -1);\n\t\tassert(-1 & 127 == 127);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (43-61): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_and_uint.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint8 x = 1;\n\t\tuint16 y = 0;\n\t\tassert(x & y != 0);\n\t\tx = 0xff;\n\t\ty = 0xffff;\n\t\tassert(x & y == 0xff);\n\t\tassert(x & y == 0xffff);\n\t\tassert(x & y == 0x0000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (74-92): CHC: Assertion violation happens here.\n// Warning 6328: (147-170): CHC: Assertion violation happens here.\n// Warning 6328: (174-197): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_combo.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint8 x = 0xff;\n\t\tuint8 y = ~x;\n\t\tassert(x & y == 0);\n\t\tassert(x | y == 0xff);\n\t\tassert(x ^ y == 0xff);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_not_fixed_bytes.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\t// ffff0000 in bytes4\n\t\tbytes4 x = ~bytes4(hex\"ffff\");\n\t\tassert(x == 0xffff0000); // should fail\n\t\tassert(x == 0x0000ffff); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (100-123): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_not_int.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tint16 x = 1;\n\t\tassert(~x == 0);\n\t\tx = 0xff;\n\t\tassert(~x == 0);\n\t\tx = 0x0f;\n\t\tassert(~x == 0xf0);\n\t\tx = -1;\n\t\tassert(~x != 0);\n\t\tx = -2;\n\t\tassert(~x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (58-73): CHC: Assertion violation happens here.\n// Warning 6328: (89-104): CHC: Assertion violation happens here.\n// Warning 6328: (120-138): CHC: Assertion violation happens here.\n// Warning 6328: (152-167): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_not_uint.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint8 x = 0xff;\n\t\tassert(~x == 0x00);\n\t\tuint16 y = 0xff00;\n\t\tassert(~y == 0xff);\n\t\tassert(~y == 0xffff);\n\t\tassert(~y == 0x0000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (126-146): CHC: Assertion violation happens here.\n// Warning 6328: (150-170): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_operators_do_not_throw_exceptions.sol",
    "content": "contract C {\n    // tests that bitwise operators are parsed from z3 answer\n    function test(uint x, uint y) public pure {\n        x | y;\n        x & y;\n        x ^ y;\n        assert(true);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_or_fixed_bytes.sol",
    "content": "contract C {\n\tfunction f() public pure returns (bytes1) {\n\t\tbytes1 b = (bytes1(0x0F) | (bytes1(0xF0)));\n\t\tassert(b == bytes1(0xFF)); // should hold\n\t\tassert(b == bytes1(0x00)); // should fail\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (150-175): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_or_int.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tint16 x = 1;\n\t\tint16 y = 0;\n\t\tassert(x | y == 1);\n\t\tx = 0; y = 0;\n\t\tassert(x | y != 0);\n\t\ty = 240;\n\t\tx = 15;\n\t\tint16 z = x | y;\n\t\tassert(z == 255);\n\t\tx = -1; y = 200;\n\t\tassert(x | y == x);\n\t\tassert(x | z != -1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (111-129): CHC: Assertion violation happens here.\n// Warning 6328: (234-253): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_or_uint.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint8 x = 1;\n\t\tuint16 y = 0;\n\t\tassert(x | y != 0);\n\t\tx = 0xff;\n\t\ty = 0xff00;\n\t\tassert(x | y == 0xff);\n\t\tassert(x | y == 0xffff);\n\t\tassert(x | y == 0x0000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (122-143): CHC: Assertion violation happens here.\n// Warning 6328: (174-197): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_rational_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint x = type(uint256).max - 1;\n\t\tassert(x == 2**256 - 2);\n\t\tassert(~1 == -2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_rational_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tassert(~1 | (~0xff & 0) == -2);\n\t\tint x = ~1 | (~0xff ^ 0);\n\t\t/// Result is negative, assertion fails.\n\t\tassert(x > 0);\n\t\tint y = ~x | (0xff & 1);\n\t\tassert(y > 0);\n\t\tassert(y & (0xffffffffffffffffff & 1) == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (148-161): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_xor_fixed_bytes.sol",
    "content": "contract Simp {\n\tfunction f3() public pure returns (bytes1) {\n\t\tbytes memory y = \"def\";\n\t\tassert(y[0] ^ \"e\" != bytes1(0)); // should hold\n\t\tassert(y[1] ^ \"e\" != bytes1(0)); // should fail\n\t\treturn y[0];\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (140-171): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_xor_int.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tint8 x = 1;\n\t\tint16 y = 0;\n\t\tassert(x ^ y == 1);\n\t\tint16 z = -1;\n\t\tassert(x ^ z == -2);\n\t\tassert(y ^ z == -1);\n\t\tassert(y ^ z > 0);\n\t\tx = 7; y = 3;\n\t\tassert(x ^ y < 5);\n\t\tassert(x ^ y > 5);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (156-173): CHC: Assertion violation happens here.\n// Warning 6328: (214-231): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bitwise_xor_uint.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint8 x = 1;\n\t\tuint16 y = 0;\n\t\tassert(x ^ y != 0);\n\t\tx = 0xff;\n\t\ty = 0xff00;\n\t\tassert(x ^ y == 0xff);\n\t\tassert(x ^ y == 0xffff);\n\t\tassert(x ^ y == 0x0000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (122-143): CHC: Assertion violation happens here.\n// Warning 6328: (174-197): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/bytes_new.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tbytes memory x = new bytes(0);\n\t\tassert(x.length == 0);\n\t}\n\tfunction g() public pure {\n\t\tbytes memory x = new bytes(3);\n\t\tassert(x.length == 3);\n\t\tassert(x[0] == 0);\n\t\tassert(x[1] == 0);\n\t\tassert(x[2] == 0);\n\t}\n\tfunction h() public pure {\n\t\tbytes memory x = new bytes(3);\n\t\tassert(x.length == 3);\n\t\tx[0] = 0x12;\n\t\tx[1] = 0x34;\n\t\tassert(x[0] == 0x12);\n\t\tassert(x[1] == 0x34);\n\t\t// This should be an out-of-bounds assertion.\n\t\tx[5] = 0xff;\n\t\tassert(x[5] == 0xff);\n\t}\n\tfunction h(uint size) public pure {\n\t\tbytes memory x = new bytes(size);\n\t\tassert(x.length == size);\n\t\trequire(size >= 2);\n\t\tx[0] = 0x12;\n\t\tx[1] = 0x34;\n\t\tassert(x[0] == 0x12);\n\t\tassert(x[1] == 0x34);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6368: (468-472): CHC: Out of bounds access happens here.\n// Warning 6368: (490-494): CHC: Out of bounds access happens here.\n// Info 1391: CHC: 23 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_add.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x < 100);\n\t\tuint y = 100;\n\t\ty += y + x;\n\t\tassert(y < 300);\n\t\tassert(y < 110);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTShowProvedSafe: yes\n// ----\n// Warning 6328: (118-133): CHC: Assertion violation happens here.\n// Info 9576: (90-95): CHC: Overflow (resulting value larger than 2**256 - 1) check is safe!\n// Info 9576: (85-95): CHC: Overflow (resulting value larger than 2**256 - 1) check is safe!\n// Info 9576: (99-114): CHC: Assertion violation check is safe!\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_add_array_index.sol",
    "content": "contract C\n{\n\tuint[] array;\n\tconstructor() {\n\t\tq(); q();\n\t}\n\tfunction q() public {\n\t\tarray.push();\n\t}\n\tfunction f(uint x, uint p) public {\n\t\trequire(p < array.length);\n\t\trequire(x < 100);\n\t\tarray[p] = 100;\n\t\tarray[p] += array[p] + x;\n\t\tassert(array[p] < 300);\n\t\tassert(array[p] < 110);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (262-284): CHC: Assertion violation happens here.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_add_chain.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint a = 1;\n\t\tuint b = 3;\n\t\tuint c = 7;\n\t\ta += b += c;\n\t\tassert(b ==  10 && a == 11);\n\t\ta += (b += c);\n\t\tassert(b ==  17 && a == 28);\n\t\ta += a += a;\n\t\tassert(a == 112);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_add_mapping.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) map;\n\tfunction f(uint x, uint p) public {\n\t\trequire(x < 100);\n\t\tmap[p] = 100;\n\t\tmap[p] += map[p] + x;\n\t\tassert(map[p] < 300);\n\t\tassert(map[p] < 110);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (165-185): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_assignment_division_1.sol",
    "content": "contract C {\n\tfunction f(uint x) public pure {\n\t\trequire(x == 2);\n\t\tuint y = 10;\n\t\ty /= y / x;\n\t\tassert(y == x);\n\t\tassert(y == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (115-129): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_assignment_division_2.sol",
    "content": "contract C {\n\tuint[] array;\n\tconstructor() {\n\t\tq(); q();\n\t}\n\tfunction q() public {\n\t\tarray.push();\n\t}\n\tfunction f(uint x, uint p) public {\n\t\trequire(p < array.length);\n\t\trequire(x == 2);\n\t\tarray[p] = 10;\n\t\tarray[p] /= array[p] / x;\n\t\tassert(array[p] == x);\n\t\tassert(array[p] == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (259-280): CHC: Assertion violation happens here.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_assignment_division_3.sol",
    "content": "contract C {\n\tmapping (uint => uint) map;\n\tfunction f(uint x, uint p) public {\n\t\trequire(x == 2);\n\t\tmap[p] = 10;\n\t\tmap[p] /= map[p] / x;\n\t\tassert(map[p] == x);\n\t\tassert(map[p] == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (162-181): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_assignment_right_shift.sol",
    "content": "contract C {\n\tfunction f(int a, uint b) public view {\n\t\ta >>= tx.gasprice;\n\t\trequire(a == 16 && b == 2);\n\t\ta >>= b;\n\t\tassert(a == 4); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_and_fixed_bytes.sol",
    "content": "contract C {\n    function f() public pure returns (bytes1) {\n        bytes1 a = 0xff;\n        bytes1 b = 0xf0;\n        a &= b;\n        assert(a == b);\n\n        a &= ~b;\n        assert(a != 0); // fails\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (51-57): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6328: (177-191): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_and_int.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tint8 x = 1;\n\t\tint8 y = 0;\n\t\tx &= y;\n\t\tassert(x != 0); // fails\n\t\tx = -1; y = 3;\n\t\ty &= x;\n\t\tassert(y == 3);\n\t\ty = -1;\n\t\ty &= x;\n\t\tassert(y == -1);\n\t\ty = 127;\n\t\tx &= y;\n\t\tassert(x == 127);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (81-95): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_and_uint.sol",
    "content": "contract C {\n    function f() public pure {\n        uint v = 1;\n        v &= 1;\n        assert(v == 1);\n\n        v = 7;\n        v &= 3;\n        assert(v != 3); // fails, as 7 & 3 = 3\n\n        uint c = 0;\n        c &= v;\n        assert(c == 0);\n\n        uint8 x = 0xff;\n        uint16 y = 0xffff;\n        y &= x;\n        assert(y == 0xff);\n        assert(y == 0xffff); // fails\n\n        y = 0xffff;\n        x = 0xff;\n        y &= y | x;\n        assert(y == 0xffff);\n        assert(y == 0xff); // fails\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (144-158): CHC: Assertion violation happens here.\n// Warning 6328: (347-366): CHC: Assertion violation happens here.\n// Warning 6328: (473-490): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_fixed_bytes.sol",
    "content": "contract C {\n    function f() public pure returns (bytes1) {\n        bytes1 a = 0xff;\n        bytes1 b = 0xf0;\n        b |= a;\n        assert(a == b);\n\n        a |= ~b;\n        assert(a == 0); // fails\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (51-57): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6328: (177-191): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_int.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tint8 x = 1;\n\t\tint8 y = 0;\n\t\tx |= y;\n\t\tassert(x == 0); // fails\n\t\tx = -1; y = 3;\n\t\tx |= y;\n\t\tassert(x == -1);\n\t\tx = 4;\n\t\ty |= x;\n\t\tassert(y == 7);\n\t\ty = 127;\n\t\tx |= y;\n\t\tassert(x == 127);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (81-95): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_int_1.sol",
    "content": "contract C {\n    int[1][20] c;\n    function f(bool b) public {\n\t    require(c[10][0] == 0);\n        if (b)\n            c[10][0] |= 1;\n        assert(c[10][0] == 0 || c[10][0] == 1);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6368: (76-81): CHC: Out of bounds access might happen here.\n// Warning 6368: (76-84): CHC: Out of bounds access might happen here.\n// Warning 6368: (119-124): CHC: Out of bounds access might happen here.\n// Warning 6368: (119-127): CHC: Out of bounds access might happen here.\n// Warning 6368: (149-154): CHC: Out of bounds access might happen here.\n// Warning 6368: (149-157): CHC: Out of bounds access might happen here.\n// Warning 6368: (166-171): CHC: Out of bounds access might happen here.\n// Warning 6368: (166-174): CHC: Out of bounds access might happen here.\n// Warning 6328: (142-180): CHC: Assertion violation might happen here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint.sol",
    "content": "contract C {\n    function f() public pure {\n        uint v = 7;\n        v |= 3;\n        assert(v != 7); // fails, as 7 | 3 = 7\n\n        uint c = 0;\n        c |= v;\n        assert(c == 7);\n\n        uint16 x = 0xff;\n        uint16 y = 0xffff;\n        y |= x;\n        assert(y == 0xff); // fails\n        assert(y == 0xffff);\n\n        y = 0xf1ff;\n        x = 0xff00;\n        x |= y & x;\n        assert(y == 0xffff); // fails\n        assert(x == 0xff00);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (88-102): CHC: Assertion violation happens here.\n// Warning 6328: (265-282): CHC: Assertion violation happens here.\n// Warning 6328: (391-410): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint_1.sol",
    "content": "contract C {\n    uint[1] c;\n    function f(bool b) public {\n        require(c[0] == 0);\n        if (b)\n            c[0] |= 1;\n        assert(c[0] <= 1);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6368: (76-80): CHC: Out of bounds access might happen here.\n// Warning 6368: (115-119): CHC: Out of bounds access might happen here.\n// Warning 6368: (141-145): CHC: Out of bounds access might happen here.\n// Warning 6328: (134-151): CHC: Assertion violation might happen here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint_2.sol",
    "content": "contract C {\n    struct S {\n        uint[] x;\n    }\n    S s;\n\tconstructor() {\n\t\ts.x.push();\n\t\ts.x.push();\n\t\ts.x.push();\n\t\ts.x.push();\n\t}\n    function f(bool b) public {\n        if (b)\n            s.x[2] |= 1;\n\t\t// Removed because of Spacer nondeterminism.\n        //assert(s.x[2] != 1);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6368: (196-202): CHC: Out of bounds access might happen here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_or_uint_3.sol",
    "content": "contract C {\n    struct S {\n        uint x;\n    }\n    S s;\n    function f(bool b) public {\n        s.x |= b ? 1 : 2;\n        assert(s.x > 0);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (125-140): CHC: Assertion violation might happen here.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_string_literal.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tbytes memory y = \"def\";\n\t\ty[0] &= \"d\";\n\t\tassert(y[0] == \"d\");\n\n\t\ty[0] |= \"e\";\n\t\tassert(y[0] == \"d\"); // fails\n\n\t\ty[0] ^= \"f\";\n\t\t// Disabled because of nondeterminism in Spacer in Z3 4.8.9\n\t\t//assert(y[0] == (bytes1(\"d\") | bytes1(\"e\")) ^ bytes1(\"f\"));\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (123-142): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_string_literal_2.sol",
    "content": "contract C {\n    function f() public pure {\n        bytes3 y = \"def\";\n        y &= \"def\";\n        assert(y == \"def\");\n\n        y |= \"dee\";\n        assert(y == \"def\"); // fails\n\n        y ^= \"fed\";\n        assert(y == (bytes3(\"def\") | bytes3(\"dee\")) ^ bytes3(\"fed\"));\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (147-165): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_string_literal_3.sol",
    "content": "contract C {\n    function f() public pure {\n        bytes32 y = \"abcdefghabcdefghabcdefghabcdefgh\";\n        bytes32 z = y;\n        y &= \"bcdefghabcdefghabcdefghabcdefgha\";\n        z &= \"bcdefghabcdefghabcdefghabcdefgha\";\n        assert(y == \"abcdefghabcdefghabcdefghabcdefgh\"); // fails\n\n        y |= \"cdefghabcdefghabcdefghabcdefghab\";\n        z |= \"cdefghabcdefghabcdefghabcdefghab\";\n        assert(y == \"abcdefghabcdefghabcdefghabcd\"); // fails\n\n        y ^= \"abcdefghabcdefghabcdefghabcdefgh\";\n        assert(y == z ^ \"abcdefghabcdefghabcdefghabcdefgh\");\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (229-276): CHC: Assertion violation happens here.\n// Warning 6328: (394-437): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_xor_fixed_bytes.sol",
    "content": "contract C {\n    function f() public pure returns (bytes1) {\n        bytes1 a = 0xff;\n        bytes1 b = 0xf0;\n        a ^= ~b;\n        assert(a == b);\n\n        a ^= ~b;\n        assert(a != 0xff); // fails\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (51-57): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6328: (178-195): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_xor_int.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tint8 x = 1;\n\t\tint8 y = 0;\n\t\tx ^= y;\n\t\tassert(x != 1); // fails\n\t\tx = -1; y = 1;\n\t\tx ^= y;\n\t\tassert(x == -2);\n\t\tx = 4;\n\t\ty ^= x;\n\t\tassert(y == 5);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (81-95): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_bitwise_xor_uint.sol",
    "content": "contract C {\n    function f() public pure {\n        uint v = 7;\n        v ^= 3;\n        assert(v != 4); // fails, as 7 ^ 3 = 4\n\n        uint c = 0;\n        c ^= v;\n        assert(c == 4);\n\n        uint16 x = 0xff;\n        uint16 y = 0xffff;\n        y ^= x;\n        assert(y == 0xff); // fails\n        assert(y == 0xff00);\n\n        y = 0xf1;\n        x = 0xff00;\n        y ^= x | y;\n        assert(y == 0xffff); // fails\n        assert(x == 0xff00);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (88-102): CHC: Assertion violation happens here.\n// Warning 6328: (265-282): CHC: Assertion violation happens here.\n// Warning 6328: (389-408): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_mul.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x < 10);\n\t\tuint y = 10;\n\t\ty *= y + x;\n\t\tassert(y <= 190);\n\t\tassert(y < 50);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (117-131): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_mul_array_index.sol",
    "content": "contract C\n{\n\tuint[] array;\n\tfunction q() public { array.push(); }\n\tfunction f(uint x, uint p) public {\n\t\trequire(p < array.length);\n\t\trequire(x < 10);\n\t\tarray[p] = 10;\n\t\tarray[p] *= array[p] + x;\n\t\tassert(array[p] <= 190);\n\t\tassert(array[p] < 50);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (226-247): CHC: Assertion violation happens here.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_mul_mapping.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) map;\n\tfunction f(uint x, uint p) public {\n\t\trequire(x < 10);\n\t\tmap[p] = 10;\n\t\tmap[p] *= map[p] + x;\n\t\tassert(map[p] <= 190);\n\t\tassert(map[p] < 50);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (164-183): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_shl_1.sol",
    "content": "contract C {\n\tfunction f(bool b) public pure {\n\t\tuint v = 1000000;\n\t\tif (b)\n\t\t\tv <<= 2;\n\t\tassert(v > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_shr_1.sol",
    "content": "contract C {\n\tfunction f(bool b) public pure {\n\t\tuint v = 1;\n\t\tif (b)\n\t\t\tv >>= 2;\n\t\tassert(v > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (84-97): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_sub.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x < 100);\n\t\tuint y = 200;\n\t\ty -= y - x;\n\t\tassert(y >= 0);\n\t\tassert(y < 90);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (117-131): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_sub_array_index.sol",
    "content": "contract C\n{\n\tuint[] array;\n\tfunction q() public { array.push(); }\n\tfunction f(uint x, uint p) public {\n\t\trequire(p < array.length);\n\t\trequire(x < 100);\n\t\tarray[p] = 200;\n\t\tarray[p] -= array[p] - x;\n\t\tassert(array[p] >= 0);\n\t\tassert(array[p] < 90);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (226-247): CHC: Assertion violation happens here.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/compound_sub_mapping.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) map;\n\tfunction f(uint x, uint p) public {\n\t\trequire(x < 100);\n\t\tmap[p] = 200;\n\t\tmap[p] -= map[p] - x;\n\t\tassert(map[p] >= 0);\n\t\tassert(map[p] < 90);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (164-183): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_1.sol",
    "content": "contract C {\n\tfunction f(bool b) public pure {\n\t\tuint a = b ? 2 : 3;\n\t\tassert(a > 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (71-84): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb = true\\na = 2\\n\\nTransaction trace:\\nC.constructor()\\nC.f(true)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_2.sol",
    "content": "contract C {\n\tfunction f(uint b) public pure {\n\t\trequire(b < 3);\n\t\tuint c = (b > 0) ? b++ : ++b;\n\t\tassert(c == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (99-113): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_3.sol",
    "content": "contract C {\n\tfunction f(uint a, uint b) public pure {\n\t\trequire(a < 10);\n\t\trequire(b <= a);\n\n\t\tuint c = (b > 4) ? a++ : b++;\n\t\tassert(c > a);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (128-141): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_4.sol",
    "content": "abstract contract D {\n    function d() public virtual ;\n}\n\ncontract C {\n    bool a;\n    uint x;\n    D d;\n    function g() public returns (uint) {\n        x = 2;\n        return x;\n    }\n    function f(bool b) public {\n        x = 1;\n        uint y = b ? g() : 3;\n        assert(x == 2 || x == 1);\n    }\n    function h() public {\n        x = 3;\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2072: (240-246): Unused local variable.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_5.sol",
    "content": "abstract contract D {\n    function d() public virtual ;\n}\n\ncontract C {\n    bool a;\n    uint x;\n    D d;\n    function g() public returns (uint) {\n        x = 2;\n        d.d();\n        return x;\n    }\n    function f() public {\n        x = 1;\n        uint y = g();\n        assert(x == 2 || x == 1);\n    }\n    function h() public {\n        x = 3;\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (249-255): Unused local variable.\n// Warning 6328: (271-295): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_6.sol",
    "content": "abstract contract D {\n    function d() public virtual ;\n}\n\ncontract C {\n    bool a;\n    uint x;\n    D d;\n    function g() public returns (uint) {\n        x = 2;\n        d.d();\n        return x;\n    }\n    function f(bool b) public {\n        x = 1;\n        uint y = b ? g() : 3;\n        assert(x == 2 || x == 1);\n    }\n    function h() internal {\n        x = 3;\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 2072: (255-261): Unused local variable.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_always_false.sol",
    "content": "contract C {\n\tfunction f(uint b) public pure returns (uint d) {\n\t\trequire(b < 10);\n\t\tuint c = b < 5 ? 5 : 1;\n\t\td = c > 5 ? 3 : 2;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (115-120): BMC: Condition is always false.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_always_true.sol",
    "content": "contract C {\n\tfunction f(bool b) public pure {\n\t\trequire(b);\n\t\tuint c = b ? 5 : 1;\n\t\tassert(c < 5);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (85-98): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb = true\\nc = 5\\n\\nTransaction trace:\\nC.constructor()\\nC.f(true)\n// Warning 6838: (72-73): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_function_1.sol",
    "content": "contract C {\n    function f(uint a) internal pure returns (bool b) {\n        b = a > 5;\n    }\n    function g(uint a) public pure {\n        uint c = f(a) ? 3 : 4;\n        assert(c > 5);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (170-183): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = 6\\nc = 3\\n\\nTransaction trace:\\nC.constructor()\\nC.g(6)\\n    C.f(6) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_function_2.sol",
    "content": "contract C {\n    function f(uint a) internal pure returns (uint b) {\n        require(a < 1000);\n        return a * a;\n    }\n    function g(uint a) internal pure returns (uint b) {\n        require(a < 1000);\n        return a + 100;\n    }\n    function h(uint a) public pure {\n        uint c = a < 5 ? g(a) : f(a);\n        assert(c >= 25);\n        assert(c < 20); // should fail\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (345-359): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_nested_always_true.sol",
    "content": "contract C {\n    function f(bool b1, bool b2) public pure {\n        require(b1 || b2);\n        uint c = b1 ? 3 : (b2 ? 2 : 1);\n        assert(c > 1);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (114-116): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_nested_unsafe.sol",
    "content": "contract C {\n    function f(bool b1, bool b2) public pure {\n        uint c = b1 ? 3 : (b2 ? 2 : 1);\n        assert(c > 1);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (108-121): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb1 = false\\nb2 = false\\nc = 1\\n\\nTransaction trace:\\nC.constructor()\\nC.f(false, false)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/conditional_assignment_statevar_1.sol",
    "content": "contract C {\n    uint a;\n    bool b;\n\n\tconstructor(bool _b) {\n\t\tb = _b;\n\t}\n\n    function f() public returns(uint c) {\n        c = b ? a + 10 : ++a;\n        assert(c >= a);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (143-146): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 2661: (143-146): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/const_exp_1.sol",
    "content": "contract C {\n\tuint constant x = 2;\n\tuint constant y = x ** 10;\n\n\tfunction f() public view {\n\t\tassert(y == 2 ** 10);\n\t\tassert(y == 1024);\n\t\tassert(y == 14); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2018: (65-173): Function state mutability can be restricted to pure\n// Warning 6328: (139-154): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/constant_evaluation_add.sol",
    "content": "contract C {\n    uint8 constant N = 255;\n\n    function f() public pure returns (uint8) {\n        return N + 1;\n    }\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 4984: (104-109): CHC: Overflow (resulting value larger than 255) happens here.\\nCounterexample:\\nN = 255\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: N = 255\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/constant_evaluation_bitwise_not.sol",
    "content": "contract C {\n    uint256 constant largeConstant = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n    function test() public pure returns (uint256) {\n        return ~largeConstant;\n    }\n}\n// ====\n// SMTEngine: chc\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/constant_evaluation_sub.sol",
    "content": "contract C {\n    uint256 public constant B = 1;\n\n    function f() public pure returns (uint256) {\n        return B - 112;\n    }\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 3944: (113-120): CHC: Underflow (resulting value less than 0) happens here.\\nCounterexample:\\nB = 1\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: B = 1\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/constant_propagation_1.sol",
    "content": "contract C {\n\tuint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32;\n\tuint constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1;\n\tfunction f() public pure {\n\t\tassert(DEPOSIT_CONTRACT_TREE_DEPTH == 32);\n\t\tassert(MAX_DEPOSIT_COUNT == 4294967295);\n\t\tassert(MAX_DEPOSIT_COUNT == 2); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (251-281): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/constant_propagation_2.sol",
    "content": "contract C {\n\tuint constant x = 7;\n\tuint constant y = 3;\n\tuint constant z = x / y;\n\n\tfunction f() public pure {\n\t\tassert(z == 2);\n\t\tassert(z == x / 3);\n\t\tassert(z == 7 / y);\n\t\tassert(z * 3 != 7);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_array.sol",
    "content": "contract C\n{\n\tuint[] a;\n\tfunction f(bool b) public {\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t\ta[2] = 3;\n\t\trequire(b);\n\t\tif (b)\n\t\t\tdelete a;\n\t\telse\n\t\t\tdelete a[2];\n\t\tassert(a.length == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (121-122): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_array_2d.sol",
    "content": "contract C\n{\n\tuint[][] a;\n\tconstructor() {\n\t\ta.push(); a.push(); a.push();\n\t\ta[2].push();\n\t\ta[2].push();\n\t\ta[2].push();\n\t\ta[2].push();\n\t}\n\tfunction f() public {\n\t\trequire(a[2][3] == 4);\n\t\tdelete a;\n\t\tassert(a[2][3] == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_array_index.sol",
    "content": "contract C\n{\n\tuint[] a;\n\tconstructor() {\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t}\n\tfunction f(bool b) public {\n\t\ta[2] = 3;\n\t\trequire(!b);\n\t\tif (b)\n\t\t\tdelete a;\n\t\telse\n\t\t\tdelete a[2];\n\t\tassert(a[2] == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (154-155): BMC: Condition is always false.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_array_index_2d.sol",
    "content": "contract C\n{\n\tuint[][] a;\n\tconstructor() {\n\t\tinit();\n\t}\n\tfunction init() internal {\n\t\ta.push();\n\t\ta.push();\n\t\ta[0].push();\n\t\ta[1].push();\n\t}\n\tfunction f(bool b) public {\n\t\t// Removed due to Spacer's nondeterminism.\n\t\t//a[1][1] = 512;\n\t\tif (b)\n\t\t\tdelete a;\n\t\telse\n\t\t\tdelete a[1];\n\t\tinit();\n\t\tassert(a[1][0] == 0);\n\t\tassert(a[0][0] == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (315-335): CHC: Assertion violation might happen here.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 4661: (315-335): BMC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_array_push.sol",
    "content": "contract C {\n\tint[][] array2d;\n\tfunction s() public {\n\t\tdelete array2d.push();\n\t\tassert(array2d[array2d.length - 1].length == 0);\n\t\t// Fails\n\t\tassert(array2d[array2d.length - 1].length != 0);\n\t\tdelete array2d.push().push();\n\t\tuint length = array2d.length;\n\t\tuint length2 = array2d[length - 1].length;\n\t\tassert(array2d[length - 1][length2 - 1] == 0);\n\t\t// Fails\n\t\tassert(array2d[length - 1][length2 - 1] != 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (143-190): CHC: Assertion violation happens here.\n// Warning 6328: (363-408): CHC: Assertion violation happens here.\n// Info 1391: CHC: 16 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_function.sol",
    "content": "contract C\n{\n\tuint[] a;\n\tconstructor() { init(); }\n\tfunction init() internal {\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t}\n\tfunction g() internal {\n\t\tdelete a;\n\t}\n\tfunction h() internal {\n\t\tdelete a[2];\n\t}\n\tfunction f(bool b) public {\n\t\ta[2] = 3;\n\t\trequire(b);\n\t\tif (b)\n\t\t\tg();\n\t\telse\n\t\t\th();\n\t\tinit();\n\t\tassert(a[2] == 0);\n\t\tassert(a[1] == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (262-263): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_function_type_1.sol",
    "content": "struct S {\n    function() external e;\n}\n\ncontract C {\n    S s;\n    function() external f;\n\n    constructor() {\n        delete s.e;\n        assert(s.e == f); // should fail for now because function pointer comparisons are not supported\n    }\n}\n// ----\n// Warning 7229: (146-154): Assertion checker does not yet implement the type function () external for comparisons\n// Warning 6328: (139-155): CHC: Assertion violation happens here.\\nCounterexample:\\ns = {e: 0}, f = 0\\n\\nTransaction trace:\\nC.constructor()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_function_type_2.sol",
    "content": "contract C {\n    mapping (uint => function() external) m;\n    function() external f;\n\n    constructor() {\n        m[2] = f;\n        delete m[2];\n        assert(m[2] == f); // should fail for now because function pointer comparisons are not supported\n    }\n}\n// ----\n// Warning 7229: (160-169): Assertion checker does not yet implement the type function () external for comparisons\n// Warning 6328: (153-170): CHC: Assertion violation happens here.\\nCounterexample:\\nf = 0\\n\\nTransaction trace:\\nC.constructor()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_function_type_3.sol",
    "content": "contract C {\n    function() external[] arr;\n    function() external f;\n\n    constructor() {\n        arr.push();\n        arr.push();\n        arr[1] = f;\n        delete arr[1];\n        assert(arr[1] == f); // should fail for now because function pointer comparisons are not supported\n    }\n}\n// ----\n// Warning 8364: (100-108): Assertion checker does not yet implement type function (function () external[] storage pointer) returns (function () external)\n// Warning 8364: (120-128): Assertion checker does not yet implement type function (function () external[] storage pointer) returns (function () external)\n// Warning 7229: (190-201): Assertion checker does not yet implement the type function () external for comparisons\n// Warning 6368: (167-173): CHC: Out of bounds access happens here.\\nCounterexample:\\nf = 0\\n\\nTransaction trace:\\nC.constructor()\n// Warning 6368: (190-196): CHC: Out of bounds access happens here.\\nCounterexample:\\nf = 0\\n\\nTransaction trace:\\nC.constructor()\n// Warning 6328: (183-202): CHC: Assertion violation happens here.\\nCounterexample:\\narr = [14, 0], f = 0\\n\\nTransaction trace:\\nC.constructor()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_multid_array.sol",
    "content": "contract C {\n\tuint[] a;\n\tuint[][] b;\n\tfunction p() public { a.push(); }\n\tfunction q() public { b.push().push(); }\n\tfunction f(uint x, uint v) public {\n\t\trequire(x < a.length);\n\t\ta[x] = v;\n\t\tdelete a;\n\t\tassert(a.length == 0);\n\t}\n\tfunction g(uint x, uint y, uint v) public {\n\t\trequire(x < b.length);\n\t\trequire(y < b[x].length);\n\t\tb[x][y] = v;\n\t\tdelete b;\n\t\tassert(b.length == 0);\n\t}\n\tfunction h(uint x, uint y, uint v) public {\n\t\trequire(x < b.length);\n\t\trequire(y < b[x].length);\n\t\tb[x][y] = v;\n\t\tdelete b[x];\n\t\tassert(b[x].length == 0);\n\t}\n\tfunction i(uint x, uint y, uint v) public {\n\t\trequire(x < b.length);\n\t\trequire(y < b[x].length);\n\t\tb[x][y] = v;\n\t\trequire(y < b.length);\n\t\tdelete b[y];\n\t\tassert(b[y].length == 0);\n\t}\n\tfunction j(uint x, uint y, uint z, uint v) public {\n\t\trequire(x < b.length);\n\t\trequire(y < b[x].length);\n\t\tb[x][y] = v;\n\t\trequire(z < b.length);\n\t\tdelete b[z];\n\t\t// Not necessarily the case.\n\t\trequire(y < b.length);\n\t\trequire(x < b[x].length);\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//assert(b[y][x] == 0);\n\t}\n\tfunction setA(uint x, uint y) public {\n\t\trequire(x < a.length);\n\t\ta[x] = y;\n\t}\n\tfunction setB(uint x, uint y, uint z) public {\n\t\trequire(x < b.length);\n\t\trequire(y < b[x].length);\n\t\tb[x][y] = z;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Info 1391: CHC: 27 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_struct.sol",
    "content": "contract C\n{\n\tstruct S\n\t{\n\t\tuint x;\n\t}\n\tfunction f(bool b) public pure {\n\t\tS memory s;\n\t\ts.x = 2;\n\t\tif (b)\n\t\t\tdelete s;\n\t\telse\n\t\t\tdelete s.x;\n\t\tassert(s.x == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/delete_tuple.sol",
    "content": "contract A{\n\tfunction f() public pure {\n\t\tdelete ([\"\"][0]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/div_zero.sol",
    "content": "contract C {\n\tuint z = 0;\n\tuint x = 2 / z;\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4281: (36-41): CHC: Division by zero happens here.\\nCounterexample:\\nz = 0, x = 0\\n\\nTransaction trace:\\nC.constructor()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_1.sol",
    "content": "contract C {\n\tfunction f(uint x, uint y) public pure returns (uint) {\n\t\treturn x / y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4281: (79-84): CHC: Division by zero happens here.\\nCounterexample:\\n\\nx = 0\\ny = 0\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0, 0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_2.sol",
    "content": "contract C {\n\tfunction f(uint x, uint y) public pure returns (uint) {\n\t\trequire(y != 0);\n\t\treturn x / y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_3.sol",
    "content": "contract C {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\trequire(y != 0);\n\t\treturn x / y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (95-100): CHC: Overflow (resulting value larger than 2**255 - 1) happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_4.sol",
    "content": "contract C {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\trequire(y != 0);\n\t\trequire(y != -1);\n\t\treturn x / y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_5.sol",
    "content": "contract C {\n\tfunction mul(uint8 a, uint8 b) internal pure returns (uint8) {\n\t\tuint8 c;\n\t\tif (a != 0) {\n\t\t\tc = a * b;\n\t\t\trequire(c / a == b);\n\t\t}\n\t\treturn c;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (129-139): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_6.sol",
    "content": "contract C {\n\tfunction mul(uint8 a, uint8 b) public pure returns (uint8) {\n\t\tif (a == 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tuint8 c = a * b;\n\t\trequire(c / a == b);\n\t\treturn c;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (120-125): CHC: Overflow (resulting value larger than 255) happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (137-147): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_7.sol",
    "content": "contract C {\n\tfunction div(uint256 a, uint256 b) internal pure returns (uint256) {\n\t\trequire(b > 0);\n\t\tuint256 c = a / b;\n\t\treturn c;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_1.sol",
    "content": "contract C {\n\tfunction f(uint x, uint y) public pure {\n\t\tx = 7;\n\t\ty = 2;\n\t\tassert(x / y == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_2.sol",
    "content": "contract C {\n\tfunction f(int x, int y) public pure {\n\t\tx = 7;\n\t\ty = 2;\n\t\tassert(x / y == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_3.sol",
    "content": "contract C {\n\tfunction f(int x, int y) public pure {\n\t\tx = -7;\n\t\ty = 2;\n\t\tassert(x / y == -3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_4.sol",
    "content": "contract C {\n\tfunction f(int x, int y) public pure {\n\t\tx = 7;\n\t\ty = -2;\n\t\tassert(x / y == -3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/division_truncates_correctly_5.sol",
    "content": "contract C {\n\tfunction f(int x, int y) public pure {\n\t\tx = -7;\n\t\ty = -2;\n\t\tassert(x / y == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/exp.sol",
    "content": "contract D {\n\tfunction f(uint x) public pure {\n\t\tassert(x**2 == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5188: (56-60): Assertion checker does not yet implement this operator.\n// Warning 6328: (49-66): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nD.constructor()\\nD.f(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/fixed_point_add.sol",
    "content": "contract test {\n\tfunction f() internal pure {\n\t\tufixed a = uint64(1) + ufixed(2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2072: (48-56): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/fixed_point_compound_add.sol",
    "content": "contract C {\n  fixed[] b;\n  function f() internal { b[0] += 1; }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/function_call_named_arguments.sol",
    "content": "library L {\n\tfunction l(uint x, uint y) internal pure returns (uint) {\n\t\treturn x + y;\n\t}\n}\n\ncontract C {\n\tfunction f(uint u, uint s, bool b) internal pure returns (uint z) {\n\t\tif (b)\n\t\t\tz = u;\n\t\telse\n\t\t\tz = s;\n\t}\n\n\tusing L for uint;\n\n\tfunction call() public pure {\n\t\tuint a = 2;\n\t\tuint b = a.l({y: 3});\n\t\tassert(b == 5);\n\t\tb = L.l({x: 3, y: 3});\n\t\tassert(b == 6);\n\t\tb = f({b: true, u: 1, s: 2});\n\t\tassert(b == 1);\n\t\tb = f({b: false, u: 1, s: 2});\n\t\t// Fails, should be 2.\n\t\tassert(b == 6);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (475-489): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/index_access_for_bytes.sol",
    "content": "contract C {\n    function f() public pure {\n        bytes memory x = hex\"00112233\";\n        assert(x[0] == 0x00);\n        assert(x[1] == 0x11);\n        assert(x.length == 3);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (152-173): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/index_access_for_bytesNN.sol",
    "content": "contract C {\n    bytes20 x;\n    function f(bytes16 b) public view {\n        b[uint8(x[2])];\n    }\n}\n// ====\n// SMTEngine: chc\n// SMTSolvers: eld\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/index_access_for_string.sol",
    "content": "contract C {\n    function f() public pure {\n        string memory x = \"\\x12\\x34\";\n        bytes memory y = bytes(x);\n        assert(y[0] == 0x12);\n        assert(y[1] == 0x34);\n        assert(y.length == 2);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/index_access_side_effect.sol",
    "content": "contract C {\n\tuint[] a;\n\tconstructor() {\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t}\n\t// Accesses are safe but oob is reported due to aliasing.\n\tfunction h() internal returns (uint[] storage) {\n\t\tif (a[2] == 0)\n\t\t\ta[2] = 3;\n\t\treturn a;\n\t}\n\tfunction g() public {\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//h()[2] = 4;\n\t\tassert(h()[2] == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTTargets: assert\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/integer_new.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint[] memory x = new uint[](0);\n\t\tassert(x.length == 0);\n\t}\n\tfunction g() public pure {\n\t\tuint[] memory x = new uint[](3);\n\t\tassert(x.length == 3);\n\t\tassert(x[0] == 0);\n\t\tassert(x[1] == 0);\n\t\tassert(x[2] == 0);\n\t}\n\tfunction h() public pure {\n\t\tuint[] memory x = new uint[](3);\n\t\tassert(x.length == 3);\n\t\tx[0] = 0x12;\n\t\tx[1] = 0x34;\n\t\tassert(x[0] == 0x12);\n\t\tassert(x[1] == 0x34);\n\t\t// This should be an out-of-bounds assertion.\n\t\tx[5] = 0xff;\n\t\tassert(x[5] == 0xff);\n\t}\n\tfunction h(uint size) public pure {\n\t\tuint[] memory x = new uint[](size);\n\t\tassert(x.length == size);\n\t\trequire(size >= 2);\n\t\tx[0] = 0x12;\n\t\tx[1] = 0x34;\n\t\tassert(x[0] == 0x12);\n\t\tassert(x[1] == 0x34);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6368: (474-478): CHC: Out of bounds access happens here.\n// Warning 6368: (496-500): CHC: Out of bounds access happens here.\n// Info 1391: CHC: 23 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/mod.sol",
    "content": "contract C {\n\tfunction f(int x, int y) public pure {\n\t\trequire(y == -10);\n\t\trequire(x == 100);\n\t\tint z1 = x % y;\n\t\tint z2 = x % -y;\n\t\tassert(z1 == z2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/mod_even.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure {\n\t\trequire(x < 10000);\n\t\tuint y = x * 2;\n\t\tassert((y % 2) == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/mod_n.sol",
    "content": "contract C\n{\n\tfunction f(uint x, uint y) public pure {\n\t\trequire(y > 0);\n\t\tuint z = x % y;\n\t\tassert(z < y);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/mod_n_uint16.sol",
    "content": "contract C\n{\n\tfunction f(uint16 x, uint16 y) public pure {\n\t\trequire(y > 0);\n\t\tuint z = x % y;\n\t\tassert(z < 100_000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/mod_signed.sol",
    "content": "contract C {\n\tfunction f(int x, int y) public pure {\n\t\trequire(y != 0);\n\t\trequire(x == 42);\n\t\tint z1 = x % y;\n\t\tint z2 = -x % y;\n\t\tassert(z1 == -z2);\n\t\tassert((x >= 0 && z1 >=0) || (x <= 0 && z1 <= 0));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (131-148): CHC: Assertion violation might happen here.\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Info 6002: BMC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/named_arguments_in_any_order.sol",
    "content": "contract C {\n\tfunction f(uint u, string memory s, bool b) internal {}\n\n\tfunction call() public {\n\t\tf({s: \"abc\", u: 1,     b: true});\n\t\tf({s: \"abc\", b: true,  u: 1});\n\t\tf({u: 1,     s: \"abc\", b: true});\n\t\tf({b: true,  s: \"abc\", u: 1});\n\t\tf({u: 1,     b: true,  s: \"abc\"});\n\t\tf({b: true,  u: 1,     s: \"abc\"});\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/named_arguments_overload_in_any_order.sol",
    "content": "contract C {\n\tfunction f(uint u, string memory s, bool b) internal {}\n\tfunction f(uint u, uint s, uint b) internal {}\n\n\tfunction call() public {\n\t\tf({s: \"abc\", u: 1,     b: true});\n\t\tf({s: \"abc\", b: true,  u: 1});\n\t\tf({u: 1,     s: \"abc\", b: true});\n\t\tf({b: true,  s: \"abc\", u: 1});\n\t\tf({u: 1,     b: true,  s: \"abc\"});\n\t\tf({b: true,  u: 1,     s: \"abc\"});\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/compound_shift_left.sol",
    "content": "contract C {\n    function f(uint256 a, uint256 b) internal pure returns (uint256) {\n        a <<= b;\n        return a;\n    }\n    function t() public pure {\n        assert(f(0x4266, 0x0) == 0x4266);\n        assert(f(0x4266, 0x8) == 0x426600);\n        assert(f(0x4266, 0xf0) == 0x4266000000000000000000000000000000000000000000000000000000000000);\n        assert(f(0x4266, 0x4266) == 0);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/compound_shift_right.sol",
    "content": "contract C {\n    function f(uint256 a, uint256 b) internal pure returns (uint256) {\n        a >>= b;\n        return a;\n    }\n    function t() public pure {\n        assert(f(0x4266, 0) == 0x4266);\n        assert(f(0x4266, 0x8) == 0x42);\n        assert(f(0x4266, 0x11) == 0);\n        assert(f(57896044618658097711785492504343953926634992332820282019728792003956564819968, 5) == 1809251394333065553493296640760748560207343510400633813116524750123642650624);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_cex.sol",
    "content": "contract C {\n\tfunction left() public pure {\n\t\tuint x = 0x4266;\n\t\tassert(x << 0x0 == 0x4266);\n\t\t// Fails because the above is true.\n\t\tassert(x << 0x0 == 0x4268);\n\t}\n\n\tfunction right() public pure {\n\t\tuint x = 0x4266;\n\t\tassert(x >> 0x0 == 0x4266);\n\t\t// Fails because the above is true.\n\t\tassert(x >> 0x0 == 0x4268);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (133-159): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 16998\\n\\nTransaction trace:\\nC.constructor()\\nC.left()\n// Warning 6328: (286-312): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 16998\\n\\nTransaction trace:\\nC.constructor()\\nC.right()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_cleanup.sol",
    "content": "contract C {\n\tfunction f() public pure returns (uint16 x) {\n\t\tunchecked {\n\t\t\tx = 0xffff;\n\t\t\tx += 32;\n\t\t\tx = x << 8;\n\t\t\tx = x >> 16;\n\t\t}\n\t\tassert(x == 0);\n\t\t// Fails because x = 0.\n\t\tassert(x == 10);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (182-197): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_left.sol",
    "content": "contract C {\n    function f(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a << b;\n    }\n\tfunction t() public pure {\n\t\tassert(f(0x4266, 0x0) == 0x4266);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0x0) == 0x4268);\n\n\t\tassert(f(0x4266, 0x8) == 0x426600);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0x8) == 0x120939);\n\n\t\tassert(f(0x4266, 0xf0) == 0x4266000000000000000000000000000000000000000000000000000000000000);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0xf0) == 0x4266000000000000000000000000000000000000000000000000000000000001);\n\n\t\tassert(f(0x4266, 0x4266) == 0);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0x4266) == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (217-249): CHC: Assertion violation happens here.\n// Warning 6328: (330-364): CHC: Assertion violation happens here.\n// Warning 6328: (504-597): CHC: Assertion violation happens here.\n// Warning 6328: (674-704): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_left_larger_type.sol",
    "content": "contract C {\n\tfunction f() public pure returns (int8) {\n\t\tuint8 x = 254;\n\t\tint8 y = 1;\n\t\tassert(y << x == 0);\n\t\t// Fails because z = 0.\n\t\tassert(y << x == 10);\n\t\treturn y << x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (138-158): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_left_uint32.sol",
    "content": "contract C {\n    function f(uint32 a, uint32 b) internal pure returns (uint256) {\n        return a << b;\n    }\n\tfunction t() public pure {\n\t\tassert(f(0x4266, 0) == 0x4266);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0) == 0x4267);\n\n\t\tassert(f(0x4266, 0x10) == 0x42660000);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0x10) == 0x426600000);\n\n\t\tassert(f(0x4266, 0x11) == 0x84cc0000);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0x11) == 0x84cc000);\n\n\t\tassert(f(0x4266, 0x20) == 0);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0x20) == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (213-243): CHC: Assertion violation happens here.\n// Warning 6328: (327-365): CHC: Assertion violation happens here.\n// Warning 6328: (449-485): CHC: Assertion violation happens here.\n// Warning 6328: (560-588): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_left_uint8.sol",
    "content": "contract C {\n    function f(uint8 a, uint8 b) internal pure returns (uint256) {\n        return a << b;\n    }\n\tfunction t() public pure {\n\t\tassert(f(0x66, 0x0) == 0x66);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x66, 0x0) == 0x660);\n\n\t\tassert(f(0x66, 0x8) == 0);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x66, 0x8) == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (209-238): CHC: Assertion violation happens here.\n// Warning 6328: (310-335): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_overflow.sol",
    "content": "contract C {\n    function leftU(uint8 x, uint8 y) internal pure returns (uint8) {\n        return x << y;\n    }\n\n    function leftS(int8 x, uint8 y) internal pure returns (int8) {\n        return x << y;\n    }\n\n\tfunction t() public pure {\n\t\tassert(leftU(255, 8) == 0);\n\t\t// Fails because the above is true.\n\t\tassert(leftU(255, 8) == 1);\n\n\t\tassert(leftU(255, 1) == 254);\n\t\t// Fails because the above is true.\n\t\tassert(leftU(255, 1) == 255);\n\n\t\tassert(leftU(255, 0) == 255);\n\t\t// Fails because the above is true.\n\t\tassert(leftU(255, 0) == 0);\n\n\t\tassert(leftS(1, 7) == -128);\n\t\t// Fails because the above is true.\n\t\tassert(leftS(1, 7) == 127);\n\n\t\tassert(leftS(1, 6) == 64);\n\t\t// Fails because the above is true.\n\t\tassert(leftS(1, 6) == -64);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (307-333): CHC: Assertion violation happens here.\n// Warning 6328: (408-436): CHC: Assertion violation happens here.\n// Warning 6328: (511-537): CHC: Assertion violation happens here.\n// Warning 6328: (611-637): CHC: Assertion violation happens here.\n// Warning 6328: (709-735): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_right.sol",
    "content": "contract C {\n    function f(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a >> b;\n    }\n\tfunction t() public pure {\n\t\tassert(f(0x4266, 0) == 0x4266);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0) == 0x426);\n\n\t\tassert(f(0x4266, 0x8) == 0x42);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0x8) == 0x420);\n\n\t\tassert(f(0x4266, 0x11) == 0);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0x11) == 1);\n\n\t\tassert(f(57896044618658097711785492504343953926634992332820282019728792003956564819968, 5) == 1809251394333065553493296640760748560207343510400633813116524750123642650624);\n\t\t// Fails because the above is true.\n\t\tassert(f(57896044618658097711785492504343953926634992332820282019728792003956564819968, 5) == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (215-244): CHC: Assertion violation happens here.\n// Warning 6328: (321-352): CHC: Assertion violation happens here.\n// Warning 6328: (427-455): CHC: Assertion violation happens here.\n// Warning 6328: (673-769): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_right_negative_literal.sol",
    "content": "contract C {\n\tfunction f(int16 x, uint16 y, int16 z) internal pure returns (bool) {\n\t\treturn x >> y == z;\n\t}\n\n\tfunction t() public pure {\n\t\tassert(f(-4266, 0, -4266));\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 0, -426));\n\n\t\tassert(f(-4266, 1, -2133));\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 1, -2134));\n\n\t\tassert(f(-4266, 4, -267));\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 4, -2670));\n\n\t\tassert(f(-4266, 8, -17));\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 8, -1));\n\n\t\tassert(f(-4266, 16, -1));\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 16, -0));\n\n\t\tassert(f(-4266, 17, -1));\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 17, -0));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (208-233): CHC: Assertion violation happens here.\n// Warning 6328: (306-332): CHC: Assertion violation happens here.\n// Warning 6328: (404-430): CHC: Assertion violation happens here.\n// Warning 6328: (501-524): CHC: Assertion violation happens here.\n// Warning 6328: (595-619): CHC: Assertion violation happens here.\n// Warning 6328: (690-714): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_right_negative_lvalue.sol",
    "content": "contract C {\n    function f(int256 a, uint256 b) internal pure returns (int256) {\n        return a >> b;\n    }\n\tfunction t() public pure {\n\t\tassert(f(-4266, 0) == -4266);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 0) == -426);\n\n\t\tassert(f(-4266, 1) == -2133);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 1) == -21330);\n\n\t\tassert(f(-4266, 4) == -267);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 4) == -255);\n\n\t\tassert(f(-4266, 8) == -17);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 8) == -1);\n\n\t\tassert(f(-4266, 16) == -1);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 16) == 0);\n\n\t\tassert(f(-4266, 17) == -1);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 17) == 0);\n\t}\n\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (211-238): CHC: Assertion violation happens here.\n// Warning 6328: (313-342): CHC: Assertion violation happens here.\n// Warning 6328: (416-443): CHC: Assertion violation happens here.\n// Warning 6328: (516-541): CHC: Assertion violation happens here.\n// Warning 6328: (614-639): CHC: Assertion violation happens here.\n// Warning 6328: (712-737): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_right_negative_lvalue_int16.sol",
    "content": "contract C {\n    function f(int16 a, uint16 b) internal pure returns (int256) {\n        return a >> b;\n    }\n\tfunction t() public pure {\n\t\tassert(f(-4266, 0) == -4266);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 0) == -426);\n\n\t\tassert(f(-4266, 1) == -2133);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 1) == -21330);\n\n\t\tassert(f(-4266, 4) == -267);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 4) == -255);\n\n\t\tassert(f(-4266, 8) == -17);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 8) == -1);\n\n\t\tassert(f(-4266, 16) == -1);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 16) == 0);\n\n\t\tassert(f(-4266, 17) == -1);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 17) == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (209-236): CHC: Assertion violation happens here.\n// Warning 6328: (311-340): CHC: Assertion violation happens here.\n// Warning 6328: (414-441): CHC: Assertion violation happens here.\n// Warning 6328: (514-539): CHC: Assertion violation happens here.\n// Warning 6328: (612-637): CHC: Assertion violation happens here.\n// Warning 6328: (710-735): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_right_negative_lvalue_int32.sol",
    "content": "contract C {\n    function f(int32 a, uint32 b) internal pure returns (int256) {\n        return a >> b;\n    }\n\tfunction t() public pure {\n\t\tassert(f(-4266, 0) == -4266);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 0) == -426);\n\n\t\tassert(f(-4266, 1) == -2133);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 1) == -21330);\n\n\t\tassert(f(-4266, 4) == -267);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 4) == -255);\n\n\t\tassert(f(-4266, 8) == -17);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 8) == -1);\n\n\t\tassert(f(-4266, 16) == -1);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 16) == 0);\n\n\t\tassert(f(-4266, 17) == -1);\n\t\t// Fails because the above is true.\n\t\tassert(f(-4266, 17) == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (209-236): CHC: Assertion violation happens here.\n// Warning 6328: (311-340): CHC: Assertion violation happens here.\n// Warning 6328: (414-441): CHC: Assertion violation happens here.\n// Warning 6328: (514-539): CHC: Assertion violation happens here.\n// Warning 6328: (612-637): CHC: Assertion violation happens here.\n// Warning 6328: (710-735): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_right_negative_lvalue_int8.sol",
    "content": "contract C {\n    function f(int8 a, uint8 b) internal pure returns (int256) {\n        return a >> b;\n    }\n\tfunction t() public pure {\n\t\tassert(f(-66, 0) == -66);\n\t\t// Fails because the above is true.\n\t\tassert(f(-66, 0) == -6);\n\n\t\tassert(f(-66, 1) == -33);\n\t\t// Fails because the above is true.\n\t\tassert(f(-66, 1) == -3);\n\n\t\tassert(f(-66, 4) == -5);\n\t\t// Fails because the above is true.\n\t\tassert(f(-66, 4) == -2);\n\n\t\tassert(f(-66, 8) == -1);\n\t\t// Fails because the above is true.\n\t\tassert(f(-66, 8) == -2);\n\n\t\tassert(f(-66, 16) == -1);\n\t\t// Fails because the above is true.\n\t\tassert(f(-66, 16) == 0);\n\n\t\tassert(f(-66, 17) == -1);\n\t\t// Fails because the above is true.\n\t\tassert(f(-66, 17) == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (203-226): CHC: Assertion violation happens here.\n// Warning 6328: (297-320): CHC: Assertion violation happens here.\n// Warning 6328: (390-413): CHC: Assertion violation happens here.\n// Warning 6328: (483-506): CHC: Assertion violation happens here.\n// Warning 6328: (577-600): CHC: Assertion violation happens here.\n// Warning 6328: (671-694): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_right_uint32.sol",
    "content": "contract C {\n    function f(uint32 a, uint32 b) internal pure returns (uint256) {\n        return a >> b;\n    }\n\tfunction t() public pure {\n\t\tassert(f(0x4266, 0) == 0x4266);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0) == 0x426);\n\n\t\tassert(f(0x4266, 8) == 0x42);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 8) == 0x420);\n\n\t\tassert(f(0x4266, 0x10) == 0);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0x10) == 255);\n\n\t\tassert(f(0x4266, 0x11) == 0);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x4266, 0x11) == 255);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (213-242): CHC: Assertion violation happens here.\n// Warning 6328: (317-346): CHC: Assertion violation happens here.\n// Warning 6328: (421-451): CHC: Assertion violation happens here.\n// Warning 6328: (526-556): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_right_uint8.sol",
    "content": "contract C {\n    function f(uint8 a, uint8 b) internal pure returns (uint256) {\n        return a >> b;\n    }\n\tfunction t() public pure {\n\t\tassert(f(0x66, 0) == 0x66);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x66, 0) == 0x6);\n\n\t\tassert(f(0x66, 8) == 0);\n\t\t// Fails because the above is true.\n\t\tassert(f(0x66, 8) == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (207-232): CHC: Assertion violation happens here.\n// Warning 6328: (302-325): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shift_underflow_negative_rvalue.sol",
    "content": "contract C {\n    function f(int256 a, uint256 b) internal pure returns (int256) {\n        return a << b;\n    }\n\n    function g(int256 a, uint256 b) internal pure returns (int256) {\n        return a >> b;\n    }\n\n\tfunction t() public pure {\n\t\tassert(f(1, 2**256 - 1) == 0);\n\t\t// Fails because the above is true.\n\t\tassert(f(1, 2**256 - 1) == 1);\n\n\t\tassert(g(1, 2**256 - 1) == 0);\n\t\t// Fails because the above is true.\n\t\tassert(g(1, 2**256 - 1) == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (312-341): CHC: Assertion violation happens here.\n// Warning 6328: (417-446): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/shifts/shr_unused.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tfixed x;\n\t\tassert(x >>> 6 == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// UnimplementedFeatureError 1834: (0-80): Not yet implemented - FixedPointType.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/slice.sol",
    "content": "contract C {\n\tfunction f(bytes calldata b) external pure {\n\t\trequire(b.length > 10);\n\t\trequire(b[10] == 0xff);\n\t\tassert(bytes(b[10:20]).length == 10);\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//assert(bytes(b[10:20])[0] == 0xff);\n\t\t// Disabled because of Spacer nondeterminism\n\t\t//assert(bytes(b[10:20])[5] == 0xff);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/slice_access.sol",
    "content": "contract C {\nfunction f(int[] calldata b) public pure {\n    require(b.length == 3);\n    require(b[0] == 0);\n    require(b[1] == 1);\n    require(b[2] == 2);\n    assert(b[1:3][0] == 1); // should hold\n    assert(b[1:3][1] == 1); // should fail\n}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (203-225): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb = [0, 1, 2]\\n\\nTransaction trace:\\nC.constructor()\\nC.f([0, 1, 2])\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/slice_bytes.sol",
    "content": "contract C {\n\tfunction f(bytes calldata b) external pure {\n\t\trequire(b.length > 10);\n\t\t((b[:])[5]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/slice_default_end.sol",
    "content": "contract C {\n\tfunction f(bytes calldata b) external pure {\n\t\trequire(b.length == 30);\n\t\trequire(b[10] == 0xff);\n\t\trequire(b[b.length - 1] == 0xaa);\n\t\tassert(bytes(b[10:]).length == 20); // should hold\n\t\t// Disabled because of Spacer's nondeterminism.\n\t\t//assert(bytes(b[10:])[0] == 0xff); // should hold\n\t\t//assert(bytes(b[10:])[5] == 0xff); // Removed because of Spacer's nondeterminism\n\t\t//assert(bytes(b[10:])[19] == 0xaa); // Removed because of Spacer nondeterminism\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/slice_default_start.sol",
    "content": "contract C {\n\tfunction f(bytes calldata b) external pure {\n\t\trequire(b.length > 20);\n\t\trequire(b[0] == 0xff);\n\t\tassert(bytes(b[:20]).length == 20);\n\t\tassert(bytes(b[:20])[0] == 0xff);\n\t\tassert(bytes(b[:20])[5] == 0xff);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (186-218): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/slices_1.sol",
    "content": "contract C {\n\tfunction f(bytes calldata x) external pure {\n\t\tx[:18726387213];\n\t\tx[18726387213:];\n\t\tx[18726387213:111111111111111111];\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/slices_2.sol",
    "content": "contract e {\n\tfunction f(uint[] calldata) internal {}\n\tfunction h(uint[] calldata c) external { f(c[:]); }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/slices_3.sol",
    "content": "contract C {\nint[] s;\nfunction f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n    s = b[start:end];\n    uint len = end - start;\n    assert(len == s.length);\n    for (uint i = 0; i < len; i++) {\n        // Removed because of Spacer nondeterminism.\n        //assert(b[start:end][i] == s[i]);\n    }\n    return s[0];\n}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/ternary_operator_1.sol",
    "content": "contract C {\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn x > 0 ? x - 1 : 0; // Underflow cannot happen\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/ternary_operator_2.sol",
    "content": "contract C {\n\n\tfunction decrement(uint x) private pure returns (uint) {\n\t\treturn x - 1; // No underflow, the method can be called only with positive value\n\t}\n\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn x > 0 ? decrement(x) : 0;\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/ternary_operator_3.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual returns (uint);\n}\n\ncontract C {\n\n\tD d;\n\tuint v;\n\tbool guard = true;\n\n\tfunction inc() public {\n\t\t++v;\n\t}\n\n\tfunction dec() public {\n\t\tif (guard) return;\n\t\t--v;\n\t}\n\n\tfunction f() public returns (uint) {\n\t\tguard = false;\n\t\tuint ret = v > 0 ? d.d() : 0;\n\t\tguard = true;\n\t\treturn ret;\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTTargets: underflow\n// ----\n// Warning 3944: (206-209): CHC: Underflow (resulting value less than 0) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/ternary_operator_double_function_call.sol",
    "content": "contract C { function decrement(uint x) private pure returns (uint) { return x - 1; } function decrement2(uint x) private pure returns (uint) { return x - 1; } function f(uint x) public pure returns (uint) { return x > 0 ? decrement(x) : decrement2(x); } }\n// ----\n// Warning 3944: (151-156): CHC: Underflow (resulting value less than 0) happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/ternary_operator_external_code_1.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual returns (uint);\n}\n\ncontract C {\n\n\tD d;\n\tuint v;\n\tbool guard = true;\n\n\tfunction inc() public {\n\t\t++v;\n\t}\n\n\tfunction dec() public {\n\t\tif (guard) return;\n\t\t--v;\n\t\tguard = true;\n\t}\n\n\tfunction f() public returns (uint) {\n\t\tguard = false;\n\t\tuint ret = v > 0 ? d.d() : 0;\n\t\tguard = true;\n\t\treturn ret;\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTTargets: underflow\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/ternary_operator_nested_1.sol",
    "content": "contract C {\n\n\tfunction unreachable() private pure returns (uint) {\n\t\tassert(false);\n\t\treturn 0;\n\t}\n\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn x <= 1 ? 0 : x < 2 ? unreachable() : 0;\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/ternary_operator_nested_2.sol",
    "content": "contract C {\n\n\tfunction decrement(uint x) private pure returns (uint) {\n\t\treturn x - 1;\n\t}\n\n\tfunction decrement2(uint x) private pure returns (uint) {\n\t\treturn x - 1;\n\t}\n\n\tfunction increment(uint x) private pure returns (uint) {\n\t\treturn x + 1;\n\t}\n\n\tfunction increment2(uint x) private pure returns (uint) {\n\t\treturn x + 1;\n\t}\n\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn x < 10 ? (x > 0 ? decrement(x) : increment(x)) : (x > 100 ? increment2(x) : decrement2(x));\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 4984: (317-322): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/ternary_operator_nested_3.sol",
    "content": "contract C {\n\n\tfunction increment(uint x) private pure returns (uint) {\n\t\treturn x + 1;\n\t}\n\n\tfunction increment2(uint x) private pure returns (uint) {\n\t\treturn x + 1;\n\t}\n\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn x < 10 ? (x > 0 ? 0 : increment(x)) : (x > 100 ? increment2(x) : 0);\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 4984: (160-165): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/ternary_operator_nested_4.sol",
    "content": "contract C {\n\n\tuint s = 1;\n\n\tfunction decrement() private returns (uint) {\n\t\treturn --s;\n\t}\n\n\tfunction increment() private returns (uint) {\n\t\treturn ++s;\n\t}\n\n\tfunction f(uint x) public returns (uint) {\n\t\trequire(s > 0 && s < 10);\n\t\tuint olds = s;\n\t\tuint ret = x < 1 ? increment() : decrement();\n\t\tassert(s != olds);\n\t\treturn ret;\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/ternary_operator_with_functions.sol",
    "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\n\tfunction test() public {\n\t\ttrue ? f() : g();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/ternary_operator_with_tuple.sol",
    "content": "contract C {\n\tfunction empty_tuple() public pure {\n\t\ttrue ? () : (); // bug fix test, proper handling of empty tuples\n\t}\n\n\tfunction non_empty_tuple() public pure {\n\t\ttrue ? (1, 2) : (3, 4);\n\t}\n\n\tfunction return_empty_tuple() public pure {\n\t\treturn true ? () : ();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (53-67): Statement has no effect.\n// Warning 6133: (166-188): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/tuple_rationals_conditional.sol",
    "content": "contract C {\n\tfunction f(bool x) public pure {\n\t\t(uint a, uint b) = x ? (10000000001, 2) : (3, 4);\n\t\tassert(a != 0);\n\t\tassert(b != 0);\n\t\tassert(a % 2 == 1);\n\t\tassert(b % 2 == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_add.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x = 2;\n\t\tuint a = ++x;\n\t\tassert(x == 3);\n\t\tassert(a == 3);\n\t\tuint b = x++;\n\t\tassert(x == 4);\n\t\t// Should fail.\n\t\tassert(b < 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (161-174): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 4\\na = 3\\nb = 3\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_add_array.sol",
    "content": "contract C\n{\n\tuint[] array;\n\tfunction p() public {\n\t\tarray.push();\n\t}\n\tfunction f(uint x) public {\n\t\trequire(x < array.length);\n\t\tarray[x] = 2;\n\t\tuint a = ++array[x];\n\t\tassert(array[x] == 3);\n\t\tassert(a == 3);\n\t\tuint b = array[x]++;\n\t\tassert(array[x] == 4);\n\t\t// Should fail.\n\t\tassert(b < 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (278-291): CHC: Assertion violation happens here.\n// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_add_array_push_1.sol",
    "content": "contract C {\n\tuint[] x;\n\tfunction f() public {\n\t\trequire(x.length == 0);\n\t\t++x.push();\n\t\tassert(x.length == 1);\n\t\tassert(x[0] == 1); // should hold\n\t\tassert(x[0] == 42); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (150-168): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_add_array_push_2.sol",
    "content": "contract C {\n\tstruct S {\n\t\tint[][] d;\n\t}\n\tS[] data;\n\tconstructor() {\n\t\tdata.push();\n\t\tdata.push();\n\t\tdata[1].d.push();\n\t\tdata[1].d.push();\n\t\tdata[1].d.push();\n\t\tdata[1].d.push();\n\t}\n\tfunction f() public {\n\t\t++data[1].d[3].push();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_add_mapping.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) map;\n\tfunction f(uint x) public {\n\t\tmap[x] = 2;\n\t\tuint a = ++map[x];\n\t\tassert(map[x] == 3);\n\t\tassert(a == 3);\n\t\tuint b = map[x]++;\n\t\tassert(map[x] == 4);\n\t\t// Should fail.\n\t\tassert(b < 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (211-224): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_add_minus_overflow_detected.sol",
    "content": "contract C {\n\tuint8 x;\n\n\tfunction inc_pre() public {\n\t\t++x;\n\t}\n\n\tfunction dec_pre() public {\n\t\t--x;\n\t}\n\n    /* Commented out because Spacer segfaults in Z3 4.8.9\n\tfunction inc_post() public {\n\t\tx++;\n\t}\n\n    function dec_post() public {\n\t\tx--;\n\t}\n    */\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (55-58): CHC: Overflow (resulting value larger than 255) might happen here.\n// Warning 3944: (95-98): CHC: Underflow (resulting value less than 0) happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.dec_pre()\n// Warning 2661: (55-58): BMC: Overflow (resulting value larger than 255) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_add_overflows_correctly.sol",
    "content": "contract C {\n\tuint8 x = 254;\n\n\tfunction inc_pre() public {\n\t\t++x;\n\t}\n\n\tfunction check() view public {\n\t\tuint y = x;\n\t\tassert(y < 256);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (61-64): CHC: Overflow (resulting value larger than 255) happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_add_overflows_correctly_struct.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint8 x;\n\t}\n\n\tS s;\n\n\tconstructor() {\n\t\ts.x = 254;\n\t}\n\n\tfunction inc_pre() public {\n\t\t++s.x;\n\t}\n\n\tfunction check() view public {\n\t\tuint y = s.x;\n\t\tassert(y < 256);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (112-117): CHC: Overflow (resulting value larger than 255) happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_minus_bmc.sol",
    "content": "contract C\n{\n\tfunction f(int x) public pure {\n\t\tassert(x == -x);\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (48-63): BMC: Assertion violation happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_minus_chc.sol",
    "content": "contract C\n{\n\tfunction f(int x) public pure {\n\t\tassert(x == -x);\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n//  Warning 6328: (48-63): CHC: Assertion violation happens here.\n//  Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_operators_tuple_1.sol",
    "content": "contract C {\n\tfunction f(bool b) public pure {\n\t\tuint x;\n\t\tif (b) ++(x);\n\t\tif (b) --(x);\n\t\tif (b) delete(b);\n\t\tassert(x == 0);\n\t\tassert(!b);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_operators_tuple_2.sol",
    "content": "contract C {\n\tfunction f(bool b) public pure {\n\t\tuint x;\n\t\tif (b) ++((((((x))))));\n\t\tif (b) --((((((x))))));\n\t\tif (b) delete((((((b))))));\n\t\tassert(x == 0);\n\t\tassert(!b);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_operators_tuple_3.sol",
    "content": "contract C {\n\tfunction f(bool b) public pure {\n\t\tuint x;\n\t\tif (b) ++(x);\n\t\telse x += 1;\n\t\tassert(x == 1);\n\t\tassert(!b);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (108-118): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_sub.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint x = 5;\n\t\tuint a = --x;\n\t\tassert(x == 4);\n\t\tassert(a == 4);\n\t\tuint b = x--;\n\t\tassert(x == 3);\n\t\t// Should fail.\n\t\tassert(b > 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (161-174): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 3\\na = 4\\nb = 4\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_sub_array.sol",
    "content": "contract C\n{\n\tuint[] array;\n\tfunction p() public { array.push(); }\n\tfunction f(uint x) public {\n\t\trequire(x < array.length);\n\t\tarray[x] = 5;\n\t\tuint a = --array[x];\n\t\tassert(array[x] == 4);\n\t\tassert(a == 4);\n\t\tuint b = array[x]--;\n\t\tassert(array[x] == 3);\n\t\t// Should fail.\n\t\tassert(b > 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (275-288): CHC: Assertion violation happens here.\n// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/unary_sub_mapping.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) map;\n\tfunction f(uint x) public {\n\t\tmap[x] = 5;\n\t\tuint a = --map[x];\n\t\tassert(map[x] == 4);\n\t\tassert(a == 4);\n\t\tuint b = map[x]--;\n\t\tassert(map[x] == 3);\n\t\t// Should fail.\n\t\tassert(b > 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (211-224): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_division_same_as_builtin.sol",
    "content": "type U is uint;\nusing {div as /} for U global;\n\nfunction div(U x, U y) pure returns (U) {\n    return U.wrap(U.unwrap(x) / U.unwrap(y)); // detects division by zero\n}\n\ncontract C {\n    function f(U x, U y) public pure returns (U) {\n        return x / y; // reports division by zero in the implementation\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4281: (108-133): CHC: Division by zero happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_division_with_safe_division_by_zero.sol",
    "content": "type U is uint;\nusing {div as /} for U global;\n\nfunction div(U x, U y) pure returns (U) {\n    if (U.unwrap(y) == 0)\n        return U.wrap(0);\n\n    return U.wrap(U.unwrap(x) / U.unwrap(y));\n}\n\ncontract C {\n    function f(U x, U y) public pure returns (U) {\n        return x / y; // no div by zero possible here\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol",
    "content": "type I16 is int16;\nusing {\n    bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n    add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n    eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for I16 global;\n\nfunction bitor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) | I16.unwrap(y)); }\nfunction bitand(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) & I16.unwrap(y)); }\nfunction bitxor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) ^ I16.unwrap(y)); }\nfunction bitnot(I16 x) pure returns (I16) { return I16.wrap(~I16.unwrap(x)); }\n\nfunction add(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) + I16.unwrap(y)); }\nfunction sub(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) - I16.unwrap(y)); }\nfunction unsub(I16 x) pure returns (I16) { return I16.wrap(-I16.unwrap(x)); }\nfunction mul(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) * I16.unwrap(y)); }\nfunction div(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) / I16.unwrap(y)); }\nfunction mod(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) % I16.unwrap(y)); }\n\nfunction eq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) == I16.unwrap(y); }\nfunction noteq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) != I16.unwrap(y); }\nfunction lt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) < I16.unwrap(y); }\nfunction gt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) > I16.unwrap(y); }\nfunction leq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) <= I16.unwrap(y); }\nfunction geq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) >= I16.unwrap(y); }\n\ncontract C {\n    I16 constant MINUS_TWO = I16.wrap(-2);\n    I16 constant ZERO = I16.wrap(0);\n    I16 constant ONE = I16.wrap(1);\n    I16 constant TWO = I16.wrap(2);\n    I16 constant THREE = I16.wrap(3);\n    I16 constant FOUR = I16.wrap(4);\n\n    function testBitwise() public pure {\n        assert(ONE | TWO == THREE);\n        assert(ONE & THREE == ONE);\n        assert(TWO ^ TWO == ZERO);\n        assert(~ONE == MINUS_TWO);\n    }\n\n    function testArithmetic() public pure {\n        assert(TWO + TWO == FOUR);\n        assert(TWO - TWO == ZERO);\n        assert(-TWO == MINUS_TWO);\n        assert(TWO * TWO == FOUR);\n        assert(TWO / TWO == ONE);\n        assert(TWO % TWO == ZERO);\n    }\n\n    function testComparison() public pure {\n        assert(TWO == TWO);\n        assert(!(TWO != TWO));\n        assert(!(TWO < TWO));\n        assert(!(TWO > TWO));\n        assert(TWO <= TWO);\n        assert(TWO >= TWO);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 27 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol",
    "content": "type I16 is int16;\nusing {\n    bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n    add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n    eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for I16 global;\n\nfunction bitor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) | I16.unwrap(y)); }\nfunction bitand(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) & I16.unwrap(y)); }\nfunction bitxor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) ^ I16.unwrap(y)); }\nfunction bitnot(I16 x) pure returns (I16) { return I16.wrap(~I16.unwrap(x)); }\n\nfunction add(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) + I16.unwrap(y)); }\nfunction sub(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) - I16.unwrap(y)); }\nfunction unsub(I16 x) pure returns (I16) { return I16.wrap(-I16.unwrap(x)); }\nfunction mul(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) * I16.unwrap(y)); }\nfunction div(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) / I16.unwrap(y)); }\nfunction mod(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) % I16.unwrap(y)); }\n\nfunction eq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) == I16.unwrap(y); }\nfunction noteq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) != I16.unwrap(y); }\nfunction lt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) < I16.unwrap(y); }\nfunction gt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) > I16.unwrap(y); }\nfunction leq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) <= I16.unwrap(y); }\nfunction geq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) >= I16.unwrap(y); }\n\ncontract C {\n    I16 constant MINUS_TWO = I16.wrap(-2);\n    I16 constant ZERO = I16.wrap(0);\n    I16 constant ONE = I16.wrap(1);\n    I16 constant TWO = I16.wrap(2);\n    I16 constant THREE = I16.wrap(3);\n    I16 constant FOUR = I16.wrap(4);\n\n    function testBitwise() public pure {\n        assert(ONE | TWO == FOUR); // should fail\n        assert(ONE & THREE == FOUR); // should fail\n        assert(TWO ^ TWO == FOUR); // should fail\n        assert(~ONE == FOUR); // should fail\n    }\n\n    function testArithmetic() public pure {\n        assert(TWO + THREE == FOUR); // should fail\n        assert(TWO - TWO == FOUR); // should fail\n        assert(-TWO == FOUR); // should fail\n        assert(TWO * THREE == FOUR); // should fail\n        assert(TWO / TWO == FOUR); // should fail\n        assert(TWO % TWO == FOUR); // should fail\n    }\n\n    function testComparison() public pure {\n        assert(!(TWO == TWO)); // should fail\n        assert(TWO != TWO); // should fail\n        assert(TWO < TWO); // should fail\n        assert(TWO > TWO); // should fail\n        assert(!(TWO <= TWO)); // should fail\n        assert(!(TWO >= TWO)); // should fail\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (2012-2037): CHC: Assertion violation happens here.\n// Warning 6328: (2062-2089): CHC: Assertion violation happens here.\n// Warning 6328: (2114-2139): CHC: Assertion violation happens here.\n// Warning 6328: (2164-2184): CHC: Assertion violation happens here.\n// Warning 6328: (2260-2287): CHC: Assertion violation happens here.\n// Warning 6328: (2312-2337): CHC: Assertion violation happens here.\n// Warning 6328: (2362-2382): CHC: Assertion violation happens here.\n// Warning 6328: (2407-2434): CHC: Assertion violation happens here.\n// Warning 6328: (2459-2484): CHC: Assertion violation happens here.\n// Warning 6328: (2509-2534): CHC: Assertion violation happens here.\n// Warning 6328: (2610-2631): CHC: Assertion violation happens here.\n// Warning 6328: (2656-2674): CHC: Assertion violation happens here.\n// Warning 6328: (2699-2716): CHC: Assertion violation happens here.\n// Warning 6328: (2741-2758): CHC: Assertion violation happens here.\n// Warning 6328: (2783-2804): CHC: Assertion violation happens here.\n// Warning 6328: (2829-2850): CHC: Assertion violation happens here.\n// Info 1391: CHC: 11 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol",
    "content": "type I16 is int16;\nusing {\n    bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n    add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n    eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for I16 global;\n\nfunction bitor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) | I16.unwrap(y)); }\nfunction bitand(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) & I16.unwrap(y)); }\nfunction bitxor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) ^ I16.unwrap(y)); }\nfunction bitnot(I16 x) pure returns (I16) { return I16.wrap(~I16.unwrap(x)); }\n\nfunction add(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) + I16.unwrap(y)); }\nfunction sub(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) - I16.unwrap(y)); }\nfunction unsub(I16 x) pure returns (I16) { return I16.wrap(-I16.unwrap(x)); }\nfunction mul(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) * I16.unwrap(y)); }\nfunction div(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) / I16.unwrap(y)); }\nfunction mod(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) % I16.unwrap(y)); }\n\n\nfunction eq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) == I16.unwrap(y); }\nfunction noteq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) != I16.unwrap(y); }\nfunction lt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) < I16.unwrap(y); }\nfunction gt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) > I16.unwrap(y); }\nfunction leq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) <= I16.unwrap(y); }\nfunction geq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) >= I16.unwrap(y); }\n\ncontract C {\n    function testBitwise(I16 x, I16 y) public pure {\n        assert(x | y == bitor(x, y)); // should hold\n        assert(x & y == bitand(x, y)); // should hold\n        assert(x ^ y == bitxor(x, y)); // should hold\n        assert(~x == bitnot(x)); // should hold\n    }\n\n    function testArithmetic(I16 x, I16 y) public pure {\n        assert(x + y == add(x, y));\n        assert(x - y == sub(x, y));\n        assert(-x == unsub(x));\n        assert(x * y == mul(x, y));\n        assert(x / y == div(x, y));\n        assert(x % y == mod(x, y));\n    }\n\n    function testComparison(I16 x, I16 y) public pure {\n        assert((x == y) == eq(x, y)); // should hold\n        assert((x != y) == noteq(x, y)); // should hold\n        assert((x < y) == lt(x, y)); // should hold\n        assert((x > y) == gt(x, y)); // should hold\n        assert((x <= y) == leq(x, y)); // should hold\n        assert((x >= y) == geq(x, y)); // should hold\n    }\n}\n// ====\n// SMTEngine: chc\n// SMTTargets: assert\n// ----\n// Warning 6328: (2209-2235): CHC: Assertion violation might happen here.\n// Warning 6328: (2245-2271): CHC: Assertion violation might happen here.\n// Info 1391: CHC: 14 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_overflow.sol",
    "content": "type U8 is uint8;\nusing {add as +} for U8 global;\n\nfunction add(U8 x, U8 y) pure returns (U8) {\n    return U8.wrap(U8.unwrap(x) + U8.unwrap(y)); // overflow detected\n}\n\ncontract C {\n    U8 x = U8.wrap(255);\n\n    function inc() public {\n        x = x + U8.wrap(1);\n    }\n\n    function check() view public {\n        U8 y = x;\n        assert(U8.unwrap(y) < 256);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (115-142): CHC: Overflow (resulting value larger than 255) happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/options/engine_none.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        assert(x > 0);\n    }\n}\n// ====\n// SMTEngine: none\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/options/pragma.sol",
    "content": "pragma experimental SMTChecker;\ncontract C {\n    function f(uint x) public pure {\n        assert(x > 0);\n    }\n}\n// ----\n// Warning 5523: (0-31): The SMTChecker pragma has been deprecated and will be removed in the future. Please use the \"model checker engine\" compiler setting to activate the SMTChecker instead. If the pragma is enabled, all engines will be used.\n// Warning 6328: (90-103): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/array_1.sol",
    "content": "contract C {\n\tuint[] a;\n\tuint l;\n\tfunction p() public {\n\t\trequire(a.length < type(uint).max - 1);\n\t\ta.push();\n\t\t++l;\n\t}\n\tfunction q() public {\n\t\trequire(a.length > 0);\n\t\ta.pop();\n\t\t--l;\n\t}\n\tfunction r() public view returns (uint) {\n\t\trequire(l > 0);\n\t\treturn a[l]; // oob access\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTTargets: outOfBounds\n// ----\n// Warning 6368: (259-263): CHC: Out of bounds access happens here.\\nCounterexample:\\na = [0], l = 1\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: a = [], l = 0\\nC.p()\\nState: a = [0], l = 1\\nC.r()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/array_2.sol",
    "content": "contract C {\n\tuint[] a;\n\tuint l;\n\tfunction p() public {\n\t\trequire(a.length < type(uint).max - 1);\n\t\trequire(l < type(uint).max - 1);\n\t\ta.push();\n\t\t++l;\n\t}\n\tfunction q() public {\n\t\trequire(a.length > 0);\n\t\trequire(l > 0);\n\t\ta.pop();\n\t\t--l;\n\t}\n\tfunction r() public view returns (uint) {\n\t\trequire(l > 0);\n\t\treturn a[l - 1]; // safe access\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/array_2d_1.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction p() public { a.push(); }\n\tfunction q(uint i) public {\n\t\trequire(i < a.length);\n\t\ta[i].push();\n\t}\n\tfunction r(uint i, uint j) public view returns (uint) {\n\t\trequire(i < a.length);\n\t\trequire(j < a[i].length);\n\t\treturn a[i][j]; // safe access\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/array_2d_2.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction p() public { a.push(); }\n\tfunction q(uint i) public {\n\t\trequire(i < a.length);\n\t\ta[i].push();\n\t}\n\tfunction r(uint i, uint j) public view returns (uint) {\n\t\trequire(i < a.length);\n\t\treturn a[i][j]; // unsafe access\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6368: (224-231): CHC: Out of bounds access happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/array_2d_3.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction p() public { a.push(); }\n\tfunction q(uint i) public {\n\t\trequire(i < a.length);\n\t\ta[i].push();\n\t}\n\tfunction r() public view {\n\t\tfor (uint i = 0; i < a.length; ++i)\n\t\t\tfor (uint j = 0; j < a[i].length; ++j)\n\t\t\t\ta[i][j]; // safe access\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/array_2d_4.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction p() public { a.push(); }\n\tfunction q(uint i) public {\n\t\trequire(i < a.length);\n\t\ta[i].push();\n\t}\n\tfunction r() public view {\n\t\tfor (uint i = 0; i < a.length + 10; ++i)\n\t\t\tfor (uint j = 0; j < a[i].length + 20; ++j)\n\t\t\t\ta[i][j]; // oob access\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (184-197): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here.\n// Warning 6368: (228-232): CHC: Out of bounds access happens here.\\nCounterexample:\\na = []\\ni = 0\\nj = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.r()\n// Warning 4984: (228-244): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here.\n// Warning 6368: (255-259): CHC: Out of bounds access happens here.\\nCounterexample:\\na = []\\ni = 0\\nj = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.r()\n// Warning 6368: (255-262): CHC: Out of bounds access happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 2661: (184-197): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 2661: (228-244): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/array_3.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction r(uint i) public view returns (uint) {\n\t\treturn a[i]; // oob access\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6368: (82-86): CHC: Out of bounds access happens here.\\nCounterexample:\\na = []\\ni = 0\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.r(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/array_4.sol",
    "content": "contract C {\n\tuint[] a;\n\tfunction p() public { a.push(); }\n\tfunction r(uint i) public view returns (uint) {\n\t\trequire(i < a.length);\n\t\treturn a[i]; // safe access\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/fixed_bytes_1.sol",
    "content": "contract C {\n\tfunction r(bytes4 x) public pure returns (bytes1) {\n\t\treturn x[0]; // safe access\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/fixed_bytes_2.sol",
    "content": "contract C {\n\tfunction r(bytes4 x, uint y) public pure returns (bytes1) {\n\t\treturn x[y]; // oob access\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6368: (83-87): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\nx = 0x0\\ny = 4\\n = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nC.r(0x0, 4)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/fixed_bytes_3.sol",
    "content": "contract C {\n\tfunction r(bytes32 x, uint y) public pure {\n\t\trequire(y <= 31);\n\t\tx[0]; // safe access\n\t\tx[y]; // safe access\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/out_of_bounds/fixed_bytes_4.sol",
    "content": "contract C {\n\tfunction r(bytes32 x, uint y) public pure {\n\t\tx[0]; // safe access\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//x[y]; // oob access\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (36-42): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_bmc.sol",
    "content": "contract C {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\trequire(x == 0);\n\t\trequire(y == 0);\n\t\treturn x + y;\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Info 6002: BMC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_bmc_show_proved.sol",
    "content": "contract C {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\trequire(x == 0);\n\t\trequire(y == 0);\n\t\treturn x + y;\n\t}\n}\n// ====\n// SMTEngine: bmc\n// SMTShowProvedSafe: yes\n// ----\n// Info 2961: (114-119): BMC: Underflow (resulting value less than -2**255) check is safe!\n// Info 2961: (114-119): BMC: Overflow (resulting value larger than 2**255 - 1) check is safe!\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/overflow_and_underflow_chc.sol",
    "content": "contract C {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\trequire(x == 0);\n\t\trequire(y == 0);\n\t\treturn x + y;\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/overflow_constant_bound.sol",
    "content": "contract DepositContract {\n    uint constant MAX_DEPOSIT_COUNT = 2**32 - 1;\n\n    uint256 deposit_count;\n    uint256 deposit_count_2;\n\n    function deposit() external {\n        require(deposit_count < MAX_DEPOSIT_COUNT);\n        deposit_count += 1;\n        deposit_count_2 += 10; // should fail\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (256-277): CHC: Overflow (resulting value larger than 2**256 - 1) might happen here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 2661: (256-277): BMC: Overflow (resulting value larger than 2**256 - 1) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/overflow_mul.sol",
    "content": "contract C\n{\n\tfunction f(uint8 x) public pure returns (uint8) {\n\t\tx = 100;\n\t\tuint8 y = x * 3;\n\t\tassert(y == 44);\n\t\tx = 128;\n\t\ty = x * 4;\n\t\tassert(y == 0);\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (87-92): CHC: Overflow (resulting value larger than 255) happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/overflow_mul_cex_with_array.sol",
    "content": "contract C {\n\tfunction f(bytes calldata x, uint y) external pure {\n\t\trequire(x.length > 10);\n\t\tx[8][0];\n\t\tx[8][5*y];\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (111-114): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6368: (106-115): CHC: Out of bounds access happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/overflow_mul_signed.sol",
    "content": "contract C\n{\n\tfunction f(int8 x) public pure returns (int8) {\n\t\tx = 100;\n\t\tint8 y;\n\t\tunchecked { y = x * 2; }\n\t\tassert(y == -56);\n\t\ty = x * 100;\n\t\tassert(y == 16);\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (136-143): CHC: Overflow (resulting value larger than 127) happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/overflow_sum.sol",
    "content": "contract C\n{\n\tfunction f(uint8 x) public pure returns (uint8) {\n\t\tuint8 y;\n\t\tunchecked { y = x + 255; }\n\t\trequire(y >= x);\n\t\tx = 255;\n\t\tunchecked { y = x + 1; }\n\t\tassert(y == 0);\n\t\ty = x + 255;\n\t\tassert(y == 254);\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (185-192): CHC: Overflow (resulting value larger than 255) happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/overflow_sum_signed.sol",
    "content": "contract C\n{\n\tfunction f(int8 x) public pure {\n\t\tx = 127;\n\t\tint8 y;\n\t\tunchecked { y = x + 1; }\n\t\tassert(y == -128);\n\t\tunchecked { y = x + 127; }\n\t\tassert(y == -2);\n\t\tx = -127;\n\t\tunchecked { y = x + -127; }\n\t\tassert(y == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/safe_sub_1.sol",
    "content": "contract C\n{\n\tfunction sub(uint256 a, uint256 b) internal pure returns (uint256) {\n\t\trequire(b <= a);\n\t\tuint256 c = a - b;\n\t\treturn c;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/signed_div_overflow.sol",
    "content": "contract C  {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\treturn x / y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (77-82): CHC: Overflow (resulting value larger than 2**255 - 1) happens here.\n// Warning 4281: (77-82): CHC: Division by zero happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/signed_guard_sub_overflow.sol",
    "content": "contract C  {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\trequire(x >= y);\n\t\treturn x - y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 4984: (96-101): CHC: Overflow (resulting value larger than 2**255 - 1) happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/signed_guard_sum_overflow.sol",
    "content": "contract C  {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\trequire(x + y >= x);\n\t\treturn x + y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 3944: (78-83): CHC: Underflow (resulting value less than -2**255) happens here.\n// Warning 4984: (78-83): CHC: Overflow (resulting value larger than 2**255 - 1) happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/signed_mod_overflow.sol",
    "content": "contract C  {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\treturn x % y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4281: (77-82): CHC: Division by zero happens here.\\nCounterexample:\\n\\nx = 0\\ny = 0\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0, 0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/signed_mul_overflow.sol",
    "content": "contract C  {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\treturn x * y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 3944: (77-82): CHC: Underflow (resulting value less than -2**255) happens here.\n// Warning 4984: (77-82): CHC: Overflow (resulting value larger than 2**255 - 1) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/signed_sub_overflow.sol",
    "content": "contract C  {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\treturn x - y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 3944: (77-82): CHC: Underflow (resulting value less than -2**255) happens here.\n// Warning 4984: (77-82): CHC: Overflow (resulting value larger than 2**255 - 1) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/signed_sum_overflow.sol",
    "content": "contract C  {\n\tfunction f(int x, int y) public pure returns (int) {\n\t\treturn x + y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 3944: (77-82): CHC: Underflow (resulting value less than -2**255) happens here.\n// Warning 4984: (77-82): CHC: Overflow (resulting value larger than 2**255 - 1) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/simple_overflow.sol",
    "content": "contract C {\n    function f(uint a, uint b) public pure returns (uint) { return a + b; }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (80-85): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\\nCounterexample:\\n\\na = 1\\nb = 115792089237316195423570985008687907853269984665640564039457584007913129639935\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/underflow_sub.sol",
    "content": "contract C\n{\n\tfunction f(uint8 x) public pure returns (uint) {\n\t\tx = 0;\n\t\tuint8 y;\n\t\tunchecked { y = x - 1; }\n\t\tassert(y == 255);\n\t\tunchecked { y = x - 255; }\n\t\tassert(y == 1);\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/underflow_sub_signed.sol",
    "content": "contract C\n{\n\tfunction f(int8 x) public pure returns (int8) {\n\t\tx = -2;\n\t\tint8 y;\n\t\tunchecked { y = x - 127; }\n\t\tassert(y == 127);\n\t\tx = -128;\n\t\tunchecked { y = x - 127; }\n\t\tassert(y == 1);\n\t\tx = 127;\n\t\tunchecked { y = x - (-127); }\n\t\tassert(y == -2);\n\t\treturn y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/unsigned_div_overflow.sol",
    "content": "contract C  {\n\tfunction f(uint x, uint y) public pure returns (uint) {\n\t\treturn x / y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4281: (80-85): CHC: Division by zero happens here.\\nCounterexample:\\n\\nx = 0\\ny = 0\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0, 0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/unsigned_guard_sub_overflow.sol",
    "content": "contract C  {\n\tfunction f(uint x, uint y) public pure returns (uint) {\n\t\trequire(x >= y);\n\t\treturn x - y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/unsigned_guard_sum_overflow.sol",
    "content": "contract C  {\n\tfunction f(uint x, uint y) public pure returns (uint) {\n\t\treturn x + y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (80-85): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/unsigned_mod_overflow.sol",
    "content": "contract C  {\n\tfunction f(uint x, uint y) public pure returns (uint) {\n\t\treturn x % y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4281: (80-85): CHC: Division by zero happens here.\\nCounterexample:\\n\\nx = 0\\ny = 0\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0, 0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/unsigned_mul_overflow.sol",
    "content": "contract C  {\n\tfunction f(uint x, uint y) public pure returns (uint) {\n\t\treturn x * y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (80-85): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/unsigned_sub_overflow.sol",
    "content": "contract C  {\n\tfunction f(uint x, uint y) public pure returns (uint) {\n\t\treturn x - y;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 3944: (80-85): CHC: Underflow (resulting value less than 0) happens here.\\nCounterexample:\\n\\nx = 0\\ny = 1\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0, 1)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/overflow/unsigned_sum_overflow.sol",
    "content": "contract C  {\n\tfunction f(uint x, uint y) public pure returns (uint) {\n\t\treturn x + y;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (80-85): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/simple/cex_smoke_test.sol",
    "content": "contract C {\n\n    function f() public pure {\n        uint x = 1;\n        assert(x == 2);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (73-87): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 1\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/simple/smoke_test.sol",
    "content": "contract C {\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/simple/static_array.sol",
    "content": "contract C\n{\n\t// Used to crash because Literal had no type\n\tint[3] d;\n\t// Used to crash because Literal had no type\n\tint[3*1] x;\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/abi_decode_memory_v2.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint x; uint[] b; }\n\tfunction f() public pure returns (S memory, bytes memory, uint[][2] memory) {\n\t\treturn abi.decode(\"abc\", (S, bytes, uint[][2]));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/abi_decode_memory_v2_value_types.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bytes memory data) public pure {\n\t\t(uint x1, bool b1) = abi.decode(data, (uint, bool));\n\t\t(uint x2, bool b2) = abi.decode(data, (uint, bool));\n\t\tassert(x1 == x2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2072: (91-98): Unused local variable.\n// Warning 2072: (146-153): Unused local variable.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/abi_decode_simple.sol",
    "content": "contract C {\n\tfunction f(bytes memory data) public pure {\n\t\t(uint a1, bytes32 b1, C c1) = abi.decode(data, (uint, bytes32, C));\n\t\t(uint a2, bytes32 b2, C c2) = abi.decode(data, (uint, bytes32, C));\n\t\tassert(a1 == a2);\n\t\tassert(a1 != a2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2072: (70-80): Unused local variable.\n// Warning 2072: (82-86): Unused local variable.\n// Warning 2072: (140-150): Unused local variable.\n// Warning 2072: (152-156): Unused local variable.\n// Warning 6328: (220-236): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/abi_encode_slice.sol",
    "content": "contract C {\n\tfunction f(bytes calldata data) external pure returns (bytes memory) {\n\t\treturn abi.encode(bytes(data[:32]));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/blobhash_beyond_limit.sol",
    "content": "contract C {\n\tfunction f(uint index) public view {\n\t\tuint limit = 9; // Since PECTRA\n\t\trequire(index >= limit);\n\t\tassert(blobhash(index) == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/block_vars_bmc_internal.sol",
    "content": "contract C {\n\taddress coin;\n\tuint dif;\n\tuint prevrandao;\n\tuint gas;\n\tuint number;\n\tuint timestamp;\n\tfunction f() public {\n\t\tcoin = block.coinbase;\n\t\tdif = block.difficulty;\n\t\tprevrandao = block.prevrandao;\n\t\tgas = block.gaslimit;\n\t\tnumber = block.number;\n\t\ttimestamp = block.timestamp;\n\n\t\tg();\n\t}\n\tfunction g() internal view {\n\t\tassert(uint160(coin) >= 0); // should hold\n\t\tassert(dif >= 0); // should hold\n\t\tassert(prevrandao > 2**64); // should hold\n\t\tassert(gas >= 0); // should hold\n\t\tassert(number >= 0); // should hold\n\t\tassert(timestamp >= 0); // should hold\n\n\t\tassert(coin == block.coinbase); // should fail with BMC\n\t\tassert(dif == block.difficulty); // should fail with BMC\n\t\tassert(prevrandao == block.prevrandao); // should fail with BMC\n\t\tassert(gas == block.gaslimit); // should fail with BMC\n\t\tassert(number == block.number); // should fail with BMC\n\t\tassert(timestamp == block.timestamp); // should fail with BMC\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 8417: (155-171): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (641-657): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 4661: (409-435): BMC: Assertion violation happens here.\n// Warning 4661: (569-599): BMC: Assertion violation happens here.\n// Warning 4661: (627-658): BMC: Assertion violation happens here.\n// Warning 4661: (686-724): BMC: Assertion violation happens here.\n// Warning 4661: (752-781): BMC: Assertion violation happens here.\n// Warning 4661: (809-839): BMC: Assertion violation happens here.\n// Warning 4661: (867-903): BMC: Assertion violation happens here.\n// Info 6002: BMC: 12 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/block_vars_chc_internal.sol",
    "content": "contract C {\n\taddress coin;\n\tuint dif;\n\tuint prevrandao;\n\tuint gas;\n\tuint number;\n\tuint timestamp;\n\tfunction f() public {\n\t\tcoin = block.coinbase;\n\t\tdif = block.difficulty;\n\t\tprevrandao = block.prevrandao;\n\t\tgas = block.gaslimit;\n\t\tnumber = block.number;\n\t\ttimestamp = block.timestamp;\n\n\t\tg();\n\t}\n\tfunction g() internal view {\n\t\tassert(uint160(coin) >= 0); // should hold\n\t\tassert(dif >= 0); // should hold\n\t\tassert(prevrandao > 2**64); // should hold\n\t\tassert(gas >= 0); // should hold\n\t\tassert(number >= 0); // should hold\n\t\tassert(timestamp >= 0); // should hold\n\n\t\tassert(coin == block.coinbase); // should hold with CHC\n\t\tassert(dif == block.difficulty); // should hold with CHC\n\t\tassert(prevrandao == block.prevrandao); // should hold with CHC\n\t\tassert(gas == block.gaslimit); // should hold with CHC\n\t\tassert(number == block.number); // should hold with CHC\n\t\tassert(timestamp == block.timestamp); // should hold with CHC\n\n\t\tassert(coin == address(this)); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreOS: macos\n// ----\n// Warning 8417: (155-171): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (641-657): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 6328: (932-961): CHC: Assertion violation happens here.\n// Info 1391: CHC: 12 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/blockhash.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public payable {\n\t\tassert(blockhash(x) > 0);\n\t\tassert(blockhash(2) > 0);\n\t\tuint y = x;\n\t\tassert(blockhash(x) == blockhash(y));\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (52-76): CHC: Assertion violation happens here.\n// Warning 6328: (80-104): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/chainid.sol",
    "content": "contract C {\n    function f() public view returns (uint) {\n        return block.chainid + 0; // Overflow not possible!\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/ether_units.sol",
    "content": "contract D {\n\tfunction f() public pure {\n\t\tassert(1000000000000000000 wei == 1 ether);\n\t\tassert(100000000000000000 wei == 1 ether);\n\t\tassert(1000000000 wei == 1 gwei);\n\t\tassert(100000000 wei == 1 gwei);\n\t\tassert(1000000000 gwei == 1 ether);\n\t\tassert(100000000 gwei == 1 ether);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (89-130): CHC: Assertion violation happens here.\n// Warning 6328: (170-201): CHC: Assertion violation happens here.\n// Warning 6328: (243-276): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/event.sol",
    "content": "contract C {\n\tevent Nudge();\n\tevent SomeArgs(uint, uint);\n\tevent Caller(address, uint);\n\tfunction f() payable external {\n\t\temit Nudge();\n\t\temit SomeArgs(134, 567);\n\t\temit Caller(msg.sender, msg.value);\n\t}\n\tfunction g_data() pure internal returns (uint) {\n\t\tassert(true);\n\t}\n\tfunction g() external {\n\t\temit SomeArgs(g_data(), g_data());\n\t}\n\tbool x = true;\n\tfunction h_data() view internal returns (uint) {\n\t\tassert(x);\n\t}\n\tfunction h() external {\n\t\tx = false;\n\t\temit SomeArgs(h_data(), h_data());\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (247-251): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (397-401): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6328: (407-416): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/gasleft.sol",
    "content": "contract C\n{\n\tfunction f() public view {\n\t\tassert(gasleft() > 0);\n\t\tuint g = gasleft();\n\t\tassert(g < gasleft());\n\t\tassert(g >= gasleft());\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (43-64): CHC: Assertion violation happens here.\n// Warning 6328: (90-111): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/many.sol",
    "content": "contract C\n{\n\tfunction f() public payable {\n\t\tassert(msg.sender == block.coinbase);\n\t\tassert(block.difficulty == block.gaslimit);\n\t\tassert(block.prevrandao == block.gaslimit);\n\t\tassert(block.number == block.timestamp);\n\t\tassert(tx.gasprice == msg.value);\n\t\tassert(tx.origin == msg.sender);\n\t\tuint x = block.number;\n\t\tunchecked { x += 2; }\n\t\tassert(x > block.number);\n\t\tassert(block.timestamp > 10);\n\t\tassert(gasleft() > 100);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 8417: (93-109): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 6328: (46-82): CHC: Assertion violation happens here.\n// Warning 6328: (86-128): CHC: Assertion violation happens here.\n// Warning 6328: (132-174): CHC: Assertion violation happens here.\n// Warning 6328: (178-217): CHC: Assertion violation happens here.\n// Warning 6328: (221-253): CHC: Assertion violation happens here.\n// Warning 6328: (257-288): CHC: Assertion violation happens here.\n// Warning 6328: (341-365): CHC: Assertion violation happens here.\n// Warning 6328: (369-397): CHC: Assertion violation happens here.\n// Warning 6328: (401-424): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/many_internal.sol",
    "content": "contract C\n{\n\tfunction f() public payable {\n\t\tg();\n\t}\n\tfunction g() internal {\n\t\tassert(msg.sender == block.coinbase);\n\t\tassert(block.difficulty == block.gaslimit);\n\t\tassert(block.prevrandao == block.gaslimit);\n\t\tassert(block.number == block.timestamp);\n\t\tassert(tx.gasprice == msg.value);\n\t\tassert(tx.origin == msg.sender);\n\t\tuint x = block.number;\n\t\tunchecked { x += 2; }\n\t\tassert(x > block.number);\n\t\tassert(block.timestamp > 10);\n\t\tassert(gasleft() > 100);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 8417: (128-144): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 6328: (81-117): CHC: Assertion violation happens here.\n// Warning 6328: (121-163): CHC: Assertion violation happens here.\n// Warning 6328: (167-209): CHC: Assertion violation happens here.\n// Warning 6328: (213-252): CHC: Assertion violation happens here.\n// Warning 6328: (256-288): CHC: Assertion violation happens here.\n// Warning 6328: (292-323): CHC: Assertion violation happens here.\n// Warning 6328: (376-400): CHC: Assertion violation happens here.\n// Warning 6328: (404-432): CHC: Assertion violation happens here.\n// Warning 6328: (436-459): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_data.sol",
    "content": "contract C\n{\n\tfunction f() public payable {\n\t\tassert(msg.data.length > 0);\n\t\t// Fails since calldata size should be 4\n\t\tassert(msg.data.length > 4);\n\t\t// f's sig is 0x26121ff0\n\t\tassert(msg.data[0] == 0x26);\n\t\tassert(msg.data[1] == 0x12);\n\t\tassert(msg.data[2] == 0x1f);\n\t\tassert(msg.data[3] == 0xf0);\n\t}\n\tfunction g() public payable {\n\t\t// g's sig is 0xe2179b8e\n\t\tassert(msg.data[0] == 0xe2);\n\t\tassert(msg.data[1] == 0x17);\n\t\tassert(msg.data[2] == 0x9b);\n\t\t// Fails\n\t\tassert(msg.data[3] == 0x8f);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (120-147): CHC: Assertion violation happens here.\n// Warning 6328: (467-494): CHC: Assertion violation happens here.\n// Info 1391: CHC: 16 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_parens_1.sol",
    "content": "contract C {\n\tfunction f() public payable {\n\t\tassert((msg).value == 10);\n\t\tassert((true ? msg : msg).value == 12);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// SMTIgnoreCex: yes\n// ----\n// TypeError 9717: (90-93): Invalid mobile type in true expression.\n// TypeError 3703: (96-99): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_sender_1.sol",
    "content": "contract C\n{\n\tfunction f() public view {\n\t\taddress a = msg.sender;\n\t\taddress b = msg.sender;\n\t\tassert(a == b);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_sender_2.sol",
    "content": "contract C\n{\n\tfunction f() public view {\n\t\trequire(msg.sender != address(0));\n\t\taddress a = msg.sender;\n\t\taddress b = msg.sender;\n\t\tassert(a == b);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_sender_3.sol",
    "content": "contract C {\n\taddress owner;\n\n\tconstructor() {\n\t\towner = msg.sender;\n\t\tassert(owner >= address(0)); // should hold\n\t}\n}\n\ncontract D {\n\taddress owner;\n\n\tconstructor() {\n\t\tunchecked {\n\t\t\towner = msg.sender;\n\t\t\tassert(owner >= address(0)); // should hold\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_sender_fail_1.sol",
    "content": "contract C\n{\n\tfunction f(address c) public view {\n\t\taddress a = msg.sender;\n\t\taddress b = msg.sender;\n\t\tassert(a == b);\n\t\tassert(c == msg.sender);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (122-145): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_sender_range.sol",
    "content": "contract C {\n\n\tfunction f() public view {\n\t\tassert(msg.sender >= address(0)); // should hold\n\t\tassert(msg.sender <= address(2**160-1)); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_sig.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tassert(msg.sig == 0x00000000);\n\t\tassert(msg.sig == 0x26121ff0);\n\t\tfi();\n\t\tgi();\n\t}\n\tfunction fi() internal pure {\n\t\tassert(msg.sig == 0x26121ff0);\n\t}\n\tfunction g() public pure {\n\t\tassert(msg.sig == 0xe2179b8e);\n\t\tgi();\n\t}\n\tfunction gi() internal pure {\n\t\t// Fails since f can also call gi in which case msg.sig == 0x26121ff0\n\t\tassert(msg.sig == 0xe2179b8e);\n\t}\n\tfunction h() public pure {\n\t\t// Fails since gi can also call h in which case msg.sig can be f() or g()\n\t\tassert(msg.sig == 0xe2179b8e);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (43-72): CHC: Assertion violation happens here.\n// Warning 6328: (370-399): CHC: Assertion violation happens here.\n// Warning 6328: (510-539): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_value_1.sol",
    "content": "contract C {\n\tfunction f() public payable {\n\t\tassert ((5 + msg.value + msg.value) - (4 + msg.value) > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (55-68): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 4984: (55-80): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_value_2.sol",
    "content": "contract C {\n\tfunction f() public payable {\n\t\tassert(msg.value > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (46-67): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f(){ msg.value: 0 }\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_value_3.sol",
    "content": "contract C {\n\tbool lock = true;\n\tfunction f() public {\n\t\tlock = false;\n\t\tg();\n\t\tlock = true;\n\t}\n\tfunction g() public payable {\n\t\trequire(lock == false);\n\t\tassert(msg.value == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_value_4.sol",
    "content": "contract A {\n    uint x = msg.value;\n    constructor() {\n        assert(x == 0); // should hold\n    }\n}\n\ncontract B {\n    constructor() payable {\n        assert(msg.value == 0); // should fail\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (154-176): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_value_inheritance_1.sol",
    "content": "contract A {\n\tuint public x = msg.value;\n\tconstructor() payable {\n\t\tassert(x == 0); // should fail, A can be constructed with any msg.value\n\t}\n}\n\ncontract C is A {\n\tuint public v = msg.value;\n\tconstructor() A() {\n\t\tassert(v == 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (68-82): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_value_inheritance_2.sol",
    "content": "contract A {\n\tuint public x = msg.value;\n\tconstructor() {\n\t\tassert(x == 0); // should fail, if A is constructed as part of C, it can have any msg.value\n\t}\n}\n\ncontract C is A {\n\tuint public v = msg.value; // 1\n\tconstructor() A() payable {\n\t\tassert(v == 0); // should fail, C can be constructed with any msg.value\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (60-74): CHC: Assertion violation happens here.\\nCounterexample:\\nv = 0, x = 115792089237316195423570985008687907853269984665640564039457584007913129637498\\n\\nTransaction trace:\\nC.constructor(){ msg.value: 115792089237316195423570985008687907853269984665640564039457584007913129637498 }\n// Warning 6328: (240-254): CHC: Assertion violation happens here.\\nCounterexample:\\nv = 115792089237316195423570985008687907853269984665640564039457584007913129637498, x = 115792089237316195423570985008687907853269984665640564039457584007913129637498\\n\\nTransaction trace:\\nC.constructor(){ msg.value: 115792089237316195423570985008687907853269984665640564039457584007913129637498 }\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_value_inheritance_3.sol",
    "content": "contract A {\n\tuint public x = msg.value;\n\tconstructor() {\n\t\tassert(x == 0); // can fail when A is constructed as part of C\n\t}\n}\n\ncontract B {\n\tconstructor() payable {\n\t\tassert(msg.value >= 0); // should hold\n\t}\n}\ncontract C is A, B {\n\tconstructor() A() B() payable {\n\t\tassert(msg.value >= 0); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (60-74): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 115792089237316195423570985008687907853269984665640564039457584007913129637498\\n\\nTransaction trace:\\nC.constructor(){ msg.value: 115792089237316195423570985008687907853269984665640564039457584007913129637498 }\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_vars_bmc_internal.sol",
    "content": "contract C {\n\tbytes data;\n\taddress sender;\n\tbytes4 sig;\n\tuint value;\n\tfunction f() public payable {\n\t\tdata = msg.data;\n\t\tsender = msg.sender;\n\t\tsig = msg.sig;\n\t\tvalue = msg.value;\n\n\t\tg();\n\t}\n\tfunction g() internal view {\n\t\tassert(data.length >= 0); // should hold\n\t\tassert(uint160(sender) >= 0); // should hold\n\t\tassert(uint32(sig) >= 0); // should hold\n\t\tassert(value >= 0); // should hold\n\n\t\tassert(data.length == msg.data.length); // should fail with BMC\n\t\tassert(sender == msg.sender); // should fail with BMC\n\t\tassert(sig == msg.sig); // should fail with BMC\n\t\tassert(value == msg.value); // should fail with BMC\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (394-432): BMC: Assertion violation happens here.\n// Warning 4661: (460-488): BMC: Assertion violation happens here.\n// Warning 4661: (516-538): BMC: Assertion violation happens here.\n// Warning 4661: (566-592): BMC: Assertion violation happens here.\n// Info 6002: BMC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/msg_vars_chc_internal.sol",
    "content": "contract C {\n\tbytes data;\n\taddress sender;\n\tbytes4 sig;\n\tuint value;\n\tfunction f() public payable {\n\t\tdata = msg.data;\n\t\tsender = msg.sender;\n\t\tsig = msg.sig;\n\t\tvalue = msg.value;\n\t\trequire(value == 42);\n\n\t\tg();\n\t}\n\tfunction g() internal view {\n\t\tassert(data.length >= 0); // should hold\n\t\tassert(uint160(sender) >= 0); // should hold\n\t\tassert(uint32(sig) >= 0); // should hold\n\t\tassert(value >= 0); // should hold\n\n\t\tassert(data.length == msg.data.length); // should hold with CHC\n\t\tassert(sender == msg.sender); // should hold with CHC\n\t\tassert(sig == msg.sig); // should hold with CHC\n\t\tassert(value == msg.value); // should hold with CHC\n\n\t\tassert(msg.value == 10); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 6328: (645-668): CHC: Assertion violation happens here.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/prevrandao.sol",
    "content": "contract C\n{\n\tfunction f(uint prevrandao) public view {\n\t\tassert(block.prevrandao == prevrandao); // should fail\n\t\tassert(block.difficulty == prevrandao); // should fail\n\t\tassert(block.difficulty == block.prevrandao); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 8417: (122-138): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (179-195): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 6328: (58-96): CHC: Assertion violation happens here.\n// Warning 6328: (115-153): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/range_check.sol",
    "content": "contract C {\n\tconstructor() payable {\n\t\tassert(tx.origin >= address(0));\n\t\tassert(tx.origin <= address(2**160 - 1));\n\t\tassert(tx.gasprice >= 0);\n\t\tassert(tx.gasprice <= 2**256 - 1);\n\t\tassert(msg.sender >= address(0));\n\t\tassert(msg.sender <= address(2**160 - 1));\n\t\tassert(msg.value >= 0);\n\t\tassert(msg.value <= 2**256 - 1);\n\n\t\tassert(block.coinbase >= address(0));\n\t\tassert(block.coinbase <= address(2**160 - 1));\n\t\tassert(block.timestamp >= 0);\n\t\tassert(block.timestamp <= 2**256 - 1);\n\t\tassert(block.chainid >= 0);\n\t\tassert(block.chainid <= 2**256 - 1);\n\t\tassert(block.difficulty >= 0);\n\t\tassert(block.difficulty <= 2**256 - 1);\n\t\tassert(block.prevrandao > 2**64);\n\t\tassert(block.prevrandao <= 2**256 - 1);\n\t\tassert(block.gaslimit >= 0);\n\t\tassert(block.gaslimit <= 2**256 - 1);\n\t\tassert(block.number >= 0);\n\t\tassert(block.number <= 2**256 - 1);\n\t}\n}\n\ncontract D {\n\tconstructor() payable {\n\t\tunchecked {\n\t\t\tassert(tx.origin >= address(0));\n\t\t\tassert(tx.origin <= address(2**160 - 1));\n\t\t\tassert(tx.gasprice >= 0);\n\t\t\tassert(tx.gasprice <= 2**256 - 1);\n\t\t\tassert(msg.sender >= address(0));\n\t\t\tassert(msg.sender <= address(2**160 - 1));\n\t\t\tassert(msg.value >= 0);\n\t\t\tassert(msg.value <= 2**256 - 1);\n\n\t\t\tassert(block.coinbase >= address(0));\n\t\t\tassert(block.coinbase <= address(2**160 - 1));\n\t\t\tassert(block.timestamp >= 0);\n\t\t\tassert(block.timestamp <= 2**256 - 1);\n\t\t\tassert(block.chainid >= 0);\n\t\t\tassert(block.chainid <= 2**256 - 1);\n\t\t\tassert(block.difficulty >= 0);\n\t\t\tassert(block.difficulty <= 2**256 - 1);\n\t\t\tassert(block.prevrandao > 2**64);\n\t\t\tassert(block.prevrandao <= 2**256 - 1);\n\t\t\tassert(block.gaslimit >= 0);\n\t\t\tassert(block.gaslimit <= 2**256 - 1);\n\t\t\tassert(block.number >= 0);\n\t\t\tassert(block.number <= 2**256 - 1);\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8417: (565-581): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (598-614): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (1447-1463): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (1481-1497): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Info 1391: CHC: 44 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/shadowing_1.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint value;\n\t\taddress origin;\n\t\tuint number;\n\t}\n\tfunction f() public payable {\n\t\tS memory msg = S(42, address(0), 666);\n\t\tS memory tx = S(42, address(0), 666);\n\t\tS memory block = S(42, address(0), 666);\n\t\tassert(msg.value == 42); // should hold\n\t\tassert(msg.value == 41); // should fail\n\t\tassert(tx.origin == address(0)); // should hold\n\t\tassert(block.number == 666); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2319: (108-120): This declaration shadows a builtin symbol.\n// Warning 2319: (149-160): This declaration shadows a builtin symbol.\n// Warning 2319: (189-203): This declaration shadows a builtin symbol.\n// Warning 6328: (274-297): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/this.sol",
    "content": "contract C\n{\n\tfunction f(address a) public view {\n\t\tassert(a == address(this));\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (52-78): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/this_state.sol",
    "content": "contract C\n{\n\taddress thisAddr;\n\tfunction f(address a) public {\n\t\trequire(a == address(this));\n\t\tthisAddr = a;\n\t\tassert(thisAddr == address(this));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/time_units.sol",
    "content": "contract D {\n\tfunction f() public pure {\n\t\tassert(1 == 1 seconds);\n\t\tassert(2 == 1 seconds);\n\t\tassert(2 minutes == 120 seconds);\n\t\tassert(3 minutes == 120 seconds);\n\t\tassert(2 hours == 120 minutes);\n\t\tassert(3 hours == 120 minutes);\n\t\tassert(2 days == 48 hours);\n\t\tassert(4 days == 48 hours);\n\t\tassert(2 weeks == 14 days);\n\t\tassert(25 weeks == 14 days);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (69-91): CHC: Assertion violation happens here.\n// Warning 6328: (131-163): CHC: Assertion violation happens here.\n// Warning 6328: (201-231): CHC: Assertion violation happens here.\n// Warning 6328: (265-291): CHC: Assertion violation happens here.\n// Warning 6328: (325-352): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/timestamp.sol",
    "content": "contract C {\n    function f() public view returns (uint) {\n        uint b = block.timestamp;\n        uint a = b + 0; // Overflow not possible!\n        return a;\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/timestamp_2.sol",
    "content": "contract C {\n\tuint x;\n\n\tconstructor() {\n\t\tx = block.timestamp + 0; // No overflow should be reported\n\t\tx = block.timestamp + 1; // Overflow should be reported here\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (107-126): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/tx_data_gasleft_changes.sol",
    "content": "contract C {\n\tuint gleft;\n\n\tfunction f() public payable {\n\t\tgleft = gasleft();\n\n\t\tfi();\n\n\t\tassert(gleft == gasleft());\n\t\tassert(gleft >= gasleft());\n\t}\n\n\tfunction fi() internal view {\n\t\tassert(gleft == gasleft());\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (91-117): CHC: Assertion violation happens here.\n// Warning 6328: (186-212): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/tx_data_immutable.sol",
    "content": "contract C {\n\tbytes32 blob_hash;\n\tbytes32 block_hash;\n\tuint bfee;\n\tuint blobfee;\n\taddress coin;\n\tuint dif;\n\tuint prevrandao;\n\tuint glimit;\n\tuint number;\n\tuint tstamp;\n\tbytes mdata;\n\taddress sender;\n\tbytes4 sig;\n\tuint value;\n\tuint gprice;\n\taddress origin;\n\n\tfunction f() public payable {\n\t\tblob_hash = blobhash(1);\n\t\tblock_hash = blockhash(12);\n\t\tbfee = block.basefee;\n\t\tblobfee = block.blobbasefee;\n\t\tcoin = block.coinbase;\n\t\tdif = block.difficulty;\n\t\tprevrandao = block.prevrandao;\n\t\tglimit = block.gaslimit;\n\t\tnumber = block.number;\n\t\ttstamp = block.timestamp;\n\t\tmdata = msg.data;\n\t\tsender = msg.sender;\n\t\tsig = msg.sig;\n\t\tvalue = msg.value;\n\t\tgprice = tx.gasprice;\n\t\torigin = tx.origin;\n\n\t\tfi();\n\n\t\tassert(blob_hash == blobhash(1));\n\t\tassert(block_hash == blockhash(12));\n\t\tassert(bfee == block.basefee);\n\t\tassert(blobfee == block.blobbasefee);\n\t\tassert(coin == block.coinbase);\n\t\tassert(dif == block.difficulty);\n\t\tassert(prevrandao == block.prevrandao);\n\t\tassert(glimit == block.gaslimit);\n\t\tassert(number == block.number);\n\t\tassert(tstamp == block.timestamp);\n\t\tassert(mdata.length == msg.data.length);\n\t\tassert(sender == msg.sender);\n\t\tassert(sig == msg.sig);\n\t\tassert(value == msg.value);\n\t\tassert(gprice == tx.gasprice);\n\t\tassert(origin == tx.origin);\n\t}\n\n\tfunction fi() internal view {\n\t\tassert(blob_hash == blobhash(1));\n\t\tassert(block_hash == blockhash(12));\n\t\tassert(bfee == block.basefee);\n\t\tassert(blobfee == block.blobbasefee);\n\t\tassert(coin == block.coinbase);\n\t\tassert(dif == block.difficulty);\n\t\tassert(prevrandao == block.prevrandao);\n\t\tassert(glimit == block.gaslimit);\n\t\tassert(number == block.number);\n\t\tassert(tstamp == block.timestamp);\n\t\tassert(mdata.length == msg.data.length);\n\t\tassert(sender == msg.sender);\n\t\tassert(sig == msg.sig);\n\t\tassert(value == msg.value);\n\t\tassert(gprice == tx.gasprice);\n\t\tassert(origin == tx.origin);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8417: (432-448): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (898-914): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (1494-1510): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Info 1391: CHC: 32 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/tx_data_immutable_fail.sol",
    "content": "contract C {\n\tbytes32 blob_hash;\n\tbytes32 block_hash;\n        uint bfee;\n        uint blobfee;\n\taddress coin;\n\tuint dif;\n\tuint prevrandao;\n\tuint glimit;\n\tuint number;\n\tuint tstamp;\n\tbytes mdata;\n\taddress sender;\n\tbytes4 sig;\n\tuint value;\n\tuint gprice;\n\taddress origin;\n\n\tfunction f() public payable {\n\t\tblob_hash = blobhash(1);\n\t\tblock_hash = blockhash(12);\n                bfee = block.basefee;\n                blobfee = block.blobbasefee;\n\t\tcoin = block.coinbase;\n\t\tdif = block.difficulty;\n\t\tprevrandao = block.prevrandao;\n\t\tglimit = block.gaslimit;\n\t\tnumber = block.number;\n\t\ttstamp = block.timestamp;\n\t\tmdata = msg.data;\n\t\tsender = msg.sender;\n\t\tsig = msg.sig;\n\t\tvalue = msg.value;\n\t\tgprice = tx.gasprice;\n\t\torigin = tx.origin;\n\n\t\tfi();\n\n\t\tassert(blob_hash == blobhash(2));\n\t\tassert(block_hash == blockhash(122));\n\t\tassert(bfee != block.basefee);\n                assert(blobfee != block.blobbasefee);\n                assert(coin != block.coinbase);\n\t\tassert(dif != block.difficulty);\n\t\tassert(prevrandao != block.prevrandao);\n\t\tassert(glimit != block.gaslimit);\n\t\tassert(number != block.number);\n\t\tassert(tstamp != block.timestamp);\n\t\tassert(mdata.length != msg.data.length);\n\t\tassert(sender != msg.sender);\n\t\tassert(sig != msg.sig);\n\t\tassert(value != msg.value);\n\t\tassert(gprice != tx.gasprice);\n\t\tassert(origin != tx.origin);\n\t}\n\n\tfunction fi() internal view {\n\t\tassert(blob_hash == blobhash(2));\n\t\tassert(block_hash == blockhash(122));\n\t\tassert(bfee != block.basefee);\n                assert(blobfee != block.blobbasefee);\n\t\tassert(coin != block.coinbase);\n\t\tassert(dif != block.difficulty);\n\t\tassert(prevrandao != block.prevrandao);\n\t\tassert(glimit != block.gaslimit);\n\t\tassert(number != block.number);\n\t\tassert(tstamp != block.timestamp);\n\t\tassert(mdata.length != msg.data.length);\n\t\tassert(sender != msg.sender);\n\t\tassert(sig != msg.sig);\n\t\tassert(value != msg.value);\n\t\tassert(gprice != tx.gasprice);\n\t\tassert(origin != tx.origin);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 8417: (474-490): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (969-985): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 8417: (1580-1596): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// Warning 6328: (744-776): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (780-816): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (820-849): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x2e16, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (867-903): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (921-951): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (955-986): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (990-1028): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1032-1064): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1068-1098): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1102-1135): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1139-1178): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1182-1210): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1214-1236): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1240-1266): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1270-1299): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x2298, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1303-1330): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1369-1401): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1405-1441): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0986, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1445-1474): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1492-1528): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1532-1562): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1566-1597): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0986, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1601-1639): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x2298, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1643-1675): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1679-1709): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1713-1746): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1750-1789): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0986, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1793-1821): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x2298, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1825-1847): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1851-1877): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0986, block_hash = 0x2298, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1881-1910): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0986, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n// Warning 6328: (1914-1941): CHC: Assertion violation happens here.\\nCounterexample:\\nblob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 18446744073709551617, prevrandao = 18446744073709551617, glimit = 0, number = 0, tstamp = 0, mdata = [0x26, 0x12, 0x1f, 0xf0], sender = 0x0, sig = 0x26121ff0, value = 0, gprice = 0, origin = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nState: blob_hash = 0x0, block_hash = 0x0, bfee = 0, blobfee = 0, coin = 0x0, dif = 0, prevrandao = 0, glimit = 0, number = 0, tstamp = 0, mdata = [], sender = 0x0, sig = 0x0, value = 0, gprice = 0, origin = 0x0\\nC.f(){ block.basefee: 0, block.blobbasefee: 0, block.coinbase: 0x0, block.gaslimit: 0, block.number: 0, block.prevrandao: 18446744073709551617, block.timestamp: 0, msg.data: [0x26, 0x12, 0x1f, 0xf0], msg.sender: 0x0, msg.sig: 0x26121ff0, msg.value: 0, tx.gasprice: 0, tx.origin: 0x0 }\\n    C.fi() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/tx_vars_bmc_internal.sol",
    "content": "contract C {\n\tuint gas;\n\taddress origin;\n\tfunction f() public {\n\t\tgas = tx.gasprice;\n\t\torigin = tx.origin;\n\n\t\tg();\n\t}\n\tfunction g() internal view {\n\t\tassert(gas >= 0); // should hold\n\t\tassert(uint160(origin) >= 0); // should hold\n\n\t\tassert(gas == tx.gasprice); // should fail with BMC\n\t\tassert(origin == tx.origin); // should fail with BMC\n\t}\n}\n// ====\n// SMTEngine: bmc\n// ----\n// Warning 4661: (233-259): BMC: Assertion violation happens here.\n// Warning 4661: (287-314): BMC: Assertion violation happens here.\n// Info 6002: BMC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/tx_vars_chc_internal.sol",
    "content": "contract C {\n\tuint gas;\n\taddress origin;\n\tfunction f() public {\n\t\tgas = tx.gasprice;\n\t\torigin = tx.origin;\n\n\t\tg();\n\t}\n\tfunction g() internal view {\n\t\tassert(gas >= 0); // should hold\n\t\tassert(uint160(origin) >= 0); // should hold\n\n\t\tassert(gas == tx.gasprice); // should hold with CHC\n\t\tassert(origin == tx.origin); // should hold with CHC\n\n\t\tassert(tx.origin == address(this)); // should fail\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (343-377): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/tx_vars_reentrancy_1.sol",
    "content": "interface I {\n\tfunction f() external;\n}\n\ncontract C {\n\tfunction g(I _i) public payable {\n\t\tuint x = address(this).balance;\n\t\t_i.f();\n\t\tassert(x == address(this).balance); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (135-169): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n_i = 0\\nx = 5892\\n\\nTransaction trace:\\nC.constructor()\\nC.g(0){ msg.value: 11 }\\n    _i.f() -- untrusted external call, synthesized as:\\n        C.g(0){ msg.value: 32278 } -- reentrant call\\n            _i.f() -- untrusted external call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/special/tx_vars_reentrancy_2.sol",
    "content": "interface I {\n\tfunction f() external payable;\n}\n\ncontract C {\n\tfunction g(I _i) public payable {\n\t\tuint x = address(this).balance;\n\t\t_i.f{ value: 100 }();\n\t\tassert(x == address(this).balance); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (157-191): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n_i = 0\\nx = 101\\n\\nTransaction trace:\\nC.constructor()\\nC.g(0){ msg.value: 83 }\\n    _i.f{ value: 100 }() -- untrusted external call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_1.sol",
    "content": "contract C {\n\tint x;\n\n\tfunction g() public  {\n\t\tx = 42;\n\t}\n\n\tfunction f() public {\n\t\tx = 0;\n\t\tbool success = false;\n\t\ttry this.g() {\n\t\t\tsuccess = true;\n\t\t} catch (bytes memory s) {\n\t\t\tassert(x == 0); // should hold\n\t\t}\n\t\tassert(success); // fails for now, since external call is over-approximated (both success and fail are considered possible) for now even for known code\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (163-177): Unused try/catch parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (221-236): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_2.sol",
    "content": "contract C {\n\tint x;\n\n\tfunction g() public  {\n\t\tx = 42;\n\t}\n\n\tfunction f() public {\n\t\tx = 0;\n\t\ttry this.g() {\n\t\t\tassert(x == 42); // should hold\n\t\t} catch (bytes memory s) {\n\t\t\tassert(x == 0); // should hold\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (155-169): Unused try/catch parameter. Remove or comment out the variable name to silence this warning.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_3.sol",
    "content": "contract C {\n\tint x;\n\n\tfunction g(int y) public pure returns (int) {\n\t\treturn y;\n\t}\n\n\tfunction postinc() internal returns (int) {\n\t\tx += 1;\n\t\treturn x;\n\t}\n\n\tfunction f() public {\n\t\tx = 0;\n\t\ttry this.g(postinc()) {\n\t\t\tassert(x == 1); // should hold\n\t\t} catch (bytes memory s) {\n\t\t\tassert(x == 0); // should fail - state is reverted to the state after postinc(), but before the call to this.g()\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 5667: (259-273): Unused try/catch parameter. Remove or comment out the variable name to silence this warning.\n// Warning 6328: (280-294): CHC: Assertion violation happens here.\\nCounterexample:\\nx = 1\\ns = []\\n\\nTransaction trace:\\nC.constructor()\\nState: x = 0\\nC.f()\\n    C.postinc() -- internal call\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_4.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual;\n}\n\ncontract C {\n\n\tint x;\n\tD d;\n\n\tfunction set(int n) public {\n\t\tx = n;\n\t}\n\n\tfunction f() public {\n\t\tx = 0;\n\t\ttry d.d() {\n\t\t\t//assert(x == 0); // should fail, x can be anything here\n\t\t} catch {\n\t\t\tassert(x == 0); // should hold, all changes to x has been reverted\n\t\t\tassert(x == 1); // should fail\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (320-334): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_5.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual;\n}\n\ncontract C {\n\n\tint x;\n\tD d;\n\n\tfunction set(int n) public {\n\t\trequire(n < 100);\n\t\tx = n;\n\t}\n\n\tfunction f() public {\n\t\tx = 0;\n\t\ttry d.d() {\n\t\t\tassert(x < 100); // should hold\n\t\t} catch {\n\t\t\tassert(x == 0); // should hold, all changes to x has been reverted\n\t\t\tassert(x == 1); // should fail\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (315-329): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_call_in_catch_1.sol",
    "content": "contract C {\n    function f() public returns (uint) {\n        try this.f() {\n        } catch Error(string memory) {\n\t\t\tg();\n\t\t}\n\t}\n\tfunction g() public pure returns (address) {\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (46-50): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_call_in_catch_2.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n        } catch Error(string memory) {\n\t\t\tg();\n\t\t}\n\t}\n\tfunction g() public pure {\n\t\tint test = 1;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (46-50): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (52-56): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 2072: (167-175): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_inside_if.sol",
    "content": "contract C {\n  function g(bool b) public {}\n  function f(bool b) public returns (bytes memory txt) {\n    if (0==1)\n      try this.g(b) {}\n      catch (bytes memory s) {\n        txt = s;\n      }\n  }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (109-113): BMC: Condition is always false.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_inside_while.sol",
    "content": "contract C {\n\tfunction f() public returns (uint) {\n\t\twhile(1==1)\n\t\t\ttry this.f() returns (uint b) {\n\t\t\t\tb = 2;\n\t\t\t} catch {\n\t\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (43-47): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_multiple_catch_clauses.sol",
    "content": "contract C {\n\tint x;\n\n\tfunction g() public  {\n\t\tx = 42;\n\t}\n\n\tfunction f() public {\n\t\tx = 1;\n\t\tbool success = false;\n\t\ttry this.g() {\n\t\t\tsuccess = true;\n\t\t\tassert(x == 42); // should hold\n\t\t} catch Error (string memory /*reason*/) {\n\t\t\tassert(x == 1); // should hold\n\t\t} catch (bytes memory /*reason*/) {\n\t\t\tassert(x == 1); // should hold\n\t\t}\n\t\tassert((success && x == 42) || (!success && x == 1)); // should hold\n\t\tassert(success); // can fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (415-430): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_multiple_catch_clauses_2.sol",
    "content": "contract C {\n\n\tfunction g() public pure {}\n\n\tfunction f() public view {\n\t\tuint x = 0;\n\t\tbool success = false;\n\t\ttry this.g() {\n\t\t\tsuccess = true;\n\t\t\tx = 1;\n\t\t} catch Error (string memory /*reason*/) {\n\t\t\tx = 2;\n\t\t} catch (bytes memory /*reason*/) {\n\t\t\tx = 3;\n\t\t}\n\t\tassert(x > 0 && x < 4); // should hold\n\t\tassert(x == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (306-320): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_multiple_returned_values.sol",
    "content": "abstract contract D {\n\tfunction d() external virtual returns (uint x, bool b);\n}\n\ncontract C {\n\n\tint x;\n\tD d;\n\n\tfunction f() public {\n\t\tx = 0;\n\t\ttry d.d() returns (uint x, bool c) {\n\t\t\tassert(x == 0); // should fail, x is the local variable shadowing the state variable\n\t\t\tassert(!c); // should fail, c can be anything\n\t\t} catch {\n\t\t\tassert(x == 0); // should hold, x is the state variable\n\t\t\tassert(x == 1); // should fail\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2519: (164-170): This declaration shadows an existing declaration.\n// Warning 6328: (185-199): CHC: Assertion violation happens here.\n// Warning 6328: (273-283): CHC: Assertion violation happens here.\n// Warning 6328: (393-407): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_multiple_returned_values_with_tuple.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t\tint y;\n\t}\n\n\tfunction g() public pure returns (bool b, S memory s) {\n\t\tb = true;\n\t\ts.x = 42;\n\t\ts.y = -1;\n\t}\n\n\tfunction f() public view {\n\t\tbool success = false;\n\t\ttry this.g() returns (bool b, S memory s) {\n\t\t\tsuccess = true;\n\t\t\tassert(b && s.x == 42 && s.y == -1);\n\t\t} catch {\n\t\t}\n\t\tassert(success); // fails, not guaranteed that there will be no error\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (321-336): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_nested_1.sol",
    "content": "contract C {\n\tint public x;\n\n\tfunction f() public view {\n\t\tint y = 42;\n\t\tbool success = false;\n\t\ttry this.x() returns (int v) {\n\t\t\ty = v;\n\t\t\ttry this.x() returns (int w) {\n\t\t\t\tsuccess = true;\n\t\t\t\ty = w;\n\t\t\t}\n\t\t\tcatch {}\n\t\t} catch {}\n\t\tassert(!success || y == x); // should hold\n\t\tassert(y == 42); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (280-295): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_nested_2.sol",
    "content": "contract C {\n\tfunction g() public pure returns (uint, uint) {\n\t}\n\tfunction f() public view {\n\t\tuint choice = 42;\n\t\ttry this.g() returns (uint, uint) {\n\t\t\tchoice = 10;\n\t\t\ttry this.g() returns (uint, uint) {\n\t\t\t\tchoice = 1;\n\t\t\t} catch {\n\t\t\t\tchoice = 2;\n\t\t\t}\n\t\t} catch {\n\t\t\tchoice = 3;\n\t\t}\n\t\tassert(choice >= 1 && choice <= 3); // should hold\n\t\tassert(choice == 42); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (342-362): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_nested_3.sol",
    "content": "contract C {\n\tfunction g() public pure returns (uint) {\n\t}\n\tfunction f() public view {\n\t\tuint choice = 42;\n\t\ttry this.g() returns (uint) {\n\t\t\tchoice = 1;\n\t\t} catch{\n\t\t\tchoice = 10;\n\t\t\ttry this.g() returns (uint) {\n\t\t\t\tchoice = 2;\n\t\t\t} catch {\n\t\t\t\tchoice = 3;\n\t\t\t}\n\t\t}\n\t\tassert(choice >= 1 && choice <= 3); // should hold\n\t\tassert(choice == 42); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (323-343): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_new.sol",
    "content": "contract Reverts {\n    constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n    constructor(uint) { }\n}\n\ncontract C {\n    function f() public returns (Reverts x, string memory txt) {\n        uint i = 3;\n        try new Reverts(i) returns (Reverts r) {\n            x = r;\n            txt = \"success\";\n        } catch Error(string memory s) {\n            txt = s;\n        }\n    }\n    function g() public returns (Succeeds x, string memory txt) {\n        uint i = 8;\n        try new Succeeds(i) returns (Succeeds r) {\n            x = r;\n            txt = \"success\";\n        } catch Error(string memory s) {\n            txt = s;\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8729: (231-245): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n// Warning 8729: (492-507): Contract deployment is only supported in the trusted mode for external calls with the CHC engine.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_public_var.sol",
    "content": "contract C {\n\tint public x;\n\n\tfunction f() public view {\n\t\ttry this.x() returns (int v) {\n\t\t\tassert(x == v); // should hold\n\t\t} catch {\n\t\t\tassert(false); // this fails, because we over-approximate every external call in the way that it can both succeed and fail\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (139-152): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_public_var_mapping.sol",
    "content": "contract C {\n\tmapping (uint => uint[]) public m;\n\n\tconstructor() {\n\t\tm[0].push();\n\t\tm[0].push();\n\t\tm[0][1] = 42;\n\t}\n\n\tfunction f() public view {\n\t\ttry this.m(0,1) returns (uint y) {\n\t\t\tassert(y == m[0][1]); // should hold\n\t\t}\n\t\tcatch {\n\t\t\tassert(m[0][1] == 42); // should hold\n\t\t\tassert(m[0][1] == 1); // should fail\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (280-300): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_string_literal_to_bytes_array.sol",
    "content": "contract C {\n\n\tfunction g() public pure returns (bytes memory) {\n\t\treturn hex\"ffff\";\n\t}\n\n\tfunction f() public view {\n\t\ttry this.g() returns (bytes memory b) {\n\t\t\tassert(b[0] == bytes1(uint8(255)) && b[1] == bytes1(uint8(255))); // should hold\n\t\t\t// Disabled because of Spacer seg fault\n\t\t\t//assert(b[0] == bytes1(uint8(0)) || b[1] == bytes1(uint8(0))); // should fail\n\t\t} catch {\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/try_catch/try_string_literal_to_fixed_bytes.sol",
    "content": "contract C {\n\n\tfunction g() public pure returns (bytes2) {\n\t\treturn hex\"ffff\";\n\t}\n\n\tfunction f() public view {\n\t\ttry this.g() returns (bytes2 b) {\n\t\t\tassert(uint8(b[0]) == 255 && uint8(b[1]) == 255); // should hold\n\t\t\tassert(uint8(b[0]) == 0 || uint8(b[1]) == 0); // should fail\n\t\t} catch {\n\t\t}\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (218-262): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/address_literal.sol",
    "content": "contract C {\n  address x; // We know that this is \"zero initialised\".\n  function f() public view {\n    address a = address(0);\n    assert(x == address(0));\n    assert(x == a);\n  }\n\n  function g() public pure {\n    address a = address(0);\n    address b = address(1);\n    address c = address(0);\n    address d = a;\n    address e = address(0x12345678);\n    assert(c == d);\n    assert(a == c);\n    assert(e == address(305419896));\n    // This is untrue.\n    assert(a == b);\n  }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (454-468): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/bytes_to_fixed_bytes_1.sol",
    "content": "contract C {\n\tfunction f() external pure {\n\t\tbytes memory b = hex\"00010203040506070809000102030405060708090001020304050607080900010203040506070809\";\n\t\tbytes8 c = bytes8(b);\n\t\tassert(c == 0x0001020304050607); // should hold\n\t\tbytes16 d = bytes16(b);\n\t\tassert(d == 0x00010203040506070809000102030405);\n\t\tbytes24 e = bytes24(b);\n\t\tassert(e == 0x000102030405060708090001020304050607080900010203); // should hold\n\t\tbytes32 g = bytes32(b);\n\t\tassert(g == 0x0001020304050607080900010203040506070809000102030405060708090001); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/bytes_to_fixed_bytes_1_fail.sol",
    "content": "contract C {\n\tfunction f() external pure {\n\t\tbytes memory b = hex\"00010203040506070809000102030405060708090001020304050607080900010203040506070809\";\n\t\tbytes8 c = bytes8(b);\n\t\t//assert(c == 0x0001020304050607); // should hold\n\t\tassert(c == 0x0001020304050608); // should fail\n\t\tbytes16 d = bytes16(b);\n\t\t//assert(d == 0x00010203040506070809000102030405);\n\t\tassert(d == 0x00010203040506070809000102030406); // should fail\n\t\tbytes24 e = bytes24(b);\n\t\t//assert(e == 0x000102030405060708090001020304050607080900010203); // should hold\n\t\tassert(e == 0x000102030405060708090001020304050607080900010204); // should fail\n\t\tbytes32 g = bytes32(b);\n\t\t//assert(g == 0x0001020304050607080900010203040506070809000102030405060708090001); // should hold\n\t\tassert(g == 0x0001020304050607080900010203040506070809000102030405060708090002); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (227-258): CHC: Assertion violation happens here.\n// Warning 6328: (356-403): CHC: Assertion violation happens here.\n// Warning 6328: (532-595): CHC: Assertion violation happens here.\n// Warning 6328: (740-819): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/cast_address_1.sol",
    "content": "contract C\n{\n\tfunction f(address a) public pure {\n\t\trequire(a != address(0));\n\t\tassert(a != address(0));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/cast_different_size_1.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tbytes2 a = 0x1234;\n\t\tuint32 b = uint16(a); // b will be 0x00001234\n\t\tassert(b == 0x1234);\n\t\tuint32 c = uint32(bytes4(a)); // c will be 0x12340000\n\t\tassert(c == 0x12340000);\n\t\tuint8 d = uint8(uint16(a)); // d will be 0x34\n\t\tassert(d == 0x34);\n\t\tuint8 e = uint8(bytes1(a)); // e will be 0x12\n\t\tassert(e == 0x12);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/cast_larger_1.sol",
    "content": "contract C\n{\n\tfunction f(uint8 x) public pure {\n\t\tuint16 y = uint16(x);\n\t\t// True because of x's type\n\t\tassert(y < 300);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/cast_larger_2.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint16 a = 0x1234;\n\t\tuint32 b = uint32(a); // b will be 0x00001234 now\n\t\t// This is correct (left padding).\n\t\tassert(a == b);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/cast_larger_2_fail.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint16 a = 0x1234;\n\t\tuint32 b = uint32(a); // b will be 0x00001234 now\n\t\tassert(a != b);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (116-130): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = 4660\\nb = 4660\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/cast_larger_3.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tbytes2 a = 0x1234;\n\t\tbytes4 b = bytes4(a); // b will be 0x12340000\n\t\t// False positive since right padding is not supported yet.\n\t\tassert(b == 0x12340000);\n\t\t// This should fail (right padding).\n\t\tassert(a == b);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (240-254): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/cast_smaller_1.sol",
    "content": "contract C\n{\n\tfunction f(uint16 x) public pure {\n\t\tuint8 y = uint8(x);\n\t\t// True because of y's type\n\t\tassert(y < 300);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/cast_smaller_2.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint32 a = 0x12345678;\n\t\tuint16 b = uint16(a); // b will be 0x5678 now\n\t\tassert(b == 0x5678);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/cast_smaller_3.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tbytes2 a = 0x1234;\n\t\tbytes1 b = bytes1(a); // b will be 0x12\n\t\tassert(b == 0x12);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/downcast.sol",
    "content": "contract C {\n\tfunction f1() public pure {\n\t\t// signed <- signed\n\t\tint8 z = int8(-1);\n\t\tassert(z == -1);\n\t\tz = int8(int(0) - 1);\n\t\tassert(z == -1);\n\t\tz = int8(int(0) - 1);\n\t\tassert(z == -1);\n\t\tz = int8(int(0) - 2);\n\t\tassert(z == -2);\n\t\tz = int8(int(0) - 1);\n\t\tassert(z == -1);\n\n\t\t// unsigned <= unsigned\n\t\tuint8 x = uint8(type(uint256).max);\n\t\tassert(x == 255);\n\t\tx = uint8(type(uint256).max);\n\t\tassert(x == 255);\n\n\t\t// signed <- unsigned\n\t\tint8 y = int8(uint8(type(uint16).max));\n\t\tassert(y == -1);\n\t\ty = int8(uint8(uint16(100)));\n\t\tassert(y == 100);\n\t\ty = int8(uint8(uint16(200)));\n\t\tassert(y == -56);\n\n\t\t// unsigned <- signed\n\t\tuint8 v = uint8(type(uint16).max);\n\t\tassert(v == 255);\n\t\tv = uint8(int8(int16(300)));\n\t\tassert(v == 44);\n\t\tv = uint8(int8(int16(200)));\n\t\tassert(v == 200);\n\n\t\t// fixed bytes\n\t\tbytes2 b = bytes2(bytes4(0xcafeffff));\n\t\tassert(b == 0xcafe);\n\t\tb = bytes2(bytes4(bytes8(0xaaaabbbbccccdddd)));\n\t\tassert(b == 0xaaaa);\n\t\tb = bytes2(bytes8(0xaaaabbbbccccdddd));\n\t\tassert(b == 0xaaaa);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 24 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/enum_from_uint.sol",
    "content": "contract C\n{\n\tenum D { Left, Right }\n\tfunction f(uint x) public pure {\n\t\trequire(x == 0);\n\t\tD _a = D(x);\n\t\tassert(_a == D.Left);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/enum_to_uint_max_value.sol",
    "content": "contract C\n{\n\tenum D { Left, Right }\n\tfunction f(D _a) public pure {\n\t\tuint x = uint(_a);\n\t\tassert(x < 10);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/fixed_bytes_array_from_strig_inline_array.sol",
    "content": "contract D {\n    function test() public pure {\n        bytes7[2] memory dummyBytes = [bytes7(\"A\"), \"B\"];\n        assert(uint56(dummyBytes[0]) == 0x41000000000000);\n        assert(uint56(dummyBytes[1]) == 0x42000000000000);\n        assert(uint56(dummyBytes[1]) == 0x41000000000000); // Should fail\n    }\n}\n// ====\n// SMTEngine: chc\n// SMTTargets: assert\n// ----\n// Warning 6328: (231-280): CHC: Assertion violation happens here.\\nCounterexample:\\n\\ndummyBytes = [0x41000000000000, 0x42000000000000]\\n\\nTransaction trace:\\nD.constructor()\\nD.test()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/function_type_to_function_type_external.sol",
    "content": "contract C {\n    function f(function(uint) external returns (uint) g, function(uint) external returns (uint) h) public {\n\t\tassert(g(2) == h(2));\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (123-143): CHC: Assertion violation happens here.\\nCounterexample:\\n\\ng = 0\\nh = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0, 0)\\n    g(2) -- untrusted external call\\n    h(2) -- untrusted external call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/function_type_to_function_type_internal.sol",
    "content": "contract C {\n\tfunction(uint) returns (uint) a;\n\tfunction(uint) returns (uint) b;\n\tfunction f(function(uint) returns (uint) g, function(uint) returns (uint) h) internal {\n\t\tassert(g(2) == h(2));\n\t\tassert(g == h);\n\t}\n\tfunction g() public {\n\t\tf(a, b);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2519: (93-124): This declaration shadows an existing declaration.\n// Warning 3075: (203-209): Comparison of internal function pointers can yield unexpected results in the legacy pipeline with the optimizer enabled, and will be disallowed entirely in the next breaking release.\n// Warning 6031: (179-183): Internal error: Expression undefined for SMT solver.\n// Warning 6031: (187-191): Internal error: Expression undefined for SMT solver.\n// Warning 7229: (203-209): Assertion checker does not yet implement the type function (uint256) returns (uint256) for comparisons\n// Warning 5729: (179-183): BMC does not yet implement this type of function call.\n// Warning 5729: (187-191): BMC does not yet implement this type of function call.\n// Warning 6328: (172-192): CHC: Assertion violation happens here.\\nCounterexample:\\na = 0, b = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: a = 0, b = 0\\nC.g()\\n    C.f(0, 0) -- internal call\n// Warning 6328: (196-210): CHC: Assertion violation happens here.\\nCounterexample:\\na = 0, b = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: a = 0, b = 0\\nC.g()\\n    C.f(0, 0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/implicit_cast_string_literal_byte.sol",
    "content": "contract C {\n\tmapping (bytes1 => uint) map;\n\tfunction f() public {\n\t\tmap[\"\"] = 2;\n\t\tuint x = map[\"\"];\n\t\tg(\"\");\n\t\tbytes1 b = \"\";\n\t\tassert(x == map[b]);\n\t\tassert(x == map[\"x\"]);\n\t}\n\tfunction g(bytes1 b) internal pure {}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (153-174): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/number_literal.sol",
    "content": "contract C {\n  function f() public pure {\n    uint x = 1234;\n    uint y = 0;\n    assert(x != y);\n    assert(x == uint(1234));\n    assert(y == uint(0));\n  }\n  function g() public pure {\n    uint a = uint(0);\n    uint b = type(uint256).max;\n    uint c = 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n    int d = -1;\n    uint e = uint(d);\n    assert(a != b);\n    assert(b == c);\n    assert(b == e);\n  }\n  function h() public pure {\n    uint32 a = uint32(0);\n    uint32 b = type(uint32).max;\n    uint32 c = 4294967295;\n    int32 d = -1;\n    uint32 e = uint32(d);\n    assert(a != b);\n    assert(b == c);\n    assert(b == e);\n  }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/same_size.sol",
    "content": "abstract contract D {}\n\nenum E {A, B}\n\ncontract C {\n\tfunction f1() public pure {\n\t\t// signed <- unsigned\n\t\tint8 x = int8(uint8(200));\n\t\tassert(x == -56);\n\t\tint256 y = int256(uint256(2**255 + 10));\n\t\tassert(y == -(2**255) + 10);\n\t\tint256 z = int256(uint(2**255 + 10));\n\t\tassert(z == -(2**255) + 10);\n\t\tint256 t = int256(uint256(bytes32(uint256(200))));\n\t\tassert(t == 200);\n\t\tint256 v = int256(uint256(bytes32(uint256(2**255 + 10))));\n\t\tassert(v == -(2**255) + 10);\n\t\tint160 a = int160(uint160(address(type(uint160).max)));\n\t\tassert(a == -1);\n\t\tint160 b = int160(uint160(address(uint160(uint(2**159 + 10)))));\n\t\tassert(b == -(2**159) + 10);\n\t\tD d;\n\t\tint160 e = int160(uint160(address(d)));\n\t\tassert(e == 0);\n\t}\n\n\tfunction f2() public pure {\n\t\t// unsigned <- signed\n\t\tuint8 x = uint8(int8(100));\n\t\tassert(x == 100);\n\t\tuint16 y = uint16(int16(200));\n\t\tassert(y == 200);\n\t\tuint8 z = uint8(int8(-100));\n\t\tassert(z == 156);\n\t\tuint16 t = uint16(int16(-200));\n\t\tassert(t == type(uint16).max - 200 + 1);\n\t\tuint256 v = uint256(int256(-200));\n\t\tassert(v == 2**256 - 200);\n\t\tuint256 w = uint256(type(uint256).max - 1);\n\t\tassert(w == 2**256 - 2);\n\t\tbytes4 b = bytes4(uint32(type(uint256).max - 1));\n\t\tassert(uint32(b) == uint32(2**32 - 2));\n\t\taddress a = address(type(uint160).max);\n\t\tassert(uint160(a) == uint160(2**160 - 1));\n\t\taddress c = address(0);\n\t\tassert(uint160(c) == 0);\n\t\tD d;\n\t\taddress e = address(d);\n\t\tassert(uint160(e) == 0);\n\t\tE f = E(1);\n\t\tassert(uint(f) == 1);\n\t}\n\n\tfunction f3() public pure {\n\t\t// unsigned <- unsigned\n\t\tuint8 x = uint8(bytes1(uint8(100)));\n\t\tassert(x == 100);\n\t\taddress a = address(0);\n\t\tassert(a == address(uint160(0)));\n\t\tD d;\n\t\tassert(a == address(d));\n\t}\n\n\tfunction f4() public pure {\n\t\t// signed <- signed\n\t\tint8 x = -10;\n\t\tint8 y = int8(x);\n\t\tassert(y == -10);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 27 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/slice_to_bytes.sol",
    "content": "contract C {\n\tfunction f(bytes calldata x) external pure {\n\t\tbytes(x[:18726387213]);\n\t\tbytes(x[18726387213:]);\n\t\tbytes(x[18726387213:111111111111111111]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/slice_to_fixed_bytes_1.sol",
    "content": "contract C {\n\tfunction fromSlice(bytes calldata c) external pure returns (bytes32) {\n\t\treturn bytes32(c[0:33]);\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_literal_to_dynamic_bytes.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tbytes memory b = bytes(hex\"ffff\");\n\t\tassert(b.length == 2); // should hold\n\t\tassert(b[0] == bytes1(uint8(255))); // should hold\n\t\tassert(b[1] == bytes1(uint8(100))); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (173-207): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_constant_initialization_1.sol",
    "content": "contract MockContract {\n\tbytes4 public constant SENTINEL_ANY_MOCKS = hex\"01\";\n\tmapping(bytes4 => bytes4) methodIdMocks;\n\n\tconstructor() {\n\t\tmethodIdMocks[SENTINEL_ANY_MOCKS] = 0;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_constant_initialization_2.sol",
    "content": "contract MockContract {\n\tbytes4 public constant SENTINEL_ANY_MOCKS = hex\"01\";\n\n\tconstructor() {\n\t\tassert(SENTINEL_ANY_MOCKS >= 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_constructor_for_deployment.sol",
    "content": "contract A {\n    bytes3 public a;\n\n    constructor(bytes3 _a) payable {\n        a = _a;\n    }\n}\n\ncontract B {\n    A a;\n\n    constructor() payable {\n        a = (new A){value: 10}(\"abc\");\n        assert(a.a() == 0x616263);\n    }\n}\n// ====\n// SMTEngine: chc\n// SMTExtCalls: trusted\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_explicit.sol",
    "content": "contract SMT {\n\tbytes32 constant internal NULL_BYTES32 = bytes32('');\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_function_call.sol",
    "content": "contract B {\n    function f() pure public {\n\t\tg(\"0123456\");\n\t}\n    function g(bytes7 a) pure public {\n\t\tassert(a == \"0123456\");\n\t\tassert(a == \"1234567\");\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (104-126): CHC: Assertion violation happens here.\n// Warning 6328: (130-152): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_modifier.sol",
    "content": "contract B {\n    function f() mod2(\"0123456\") pure public { }\n    modifier mod2(bytes7 a) {\n\t\tassert(a == \"0123456\");\n\t\tassert(a == \"1234567\");\n\t\t_;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (120-142): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_return.sol",
    "content": "contract C {\n    function g() public pure returns (bytes32 val) { return \"abc\"; }\n    function f1() public pure returns (bytes32 val) { return g(); }\n\n\tfunction a() public pure {\n\t\tassert(f1() == \"abc\");\n\t\tassert(f1() == \"cde\");\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (206-227): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_return_multi.sol",
    "content": "contract C {\n    function h() public pure returns (bytes32 val, bytes3 val2) { return (\"abc\", \"def\"); }\n    function g() public pure returns (bytes32 val) { return \"abc\"; }\n    function f1() public pure returns (bytes32 val) { return g(); }\n    function f2() public pure returns (bytes32 val, bytes3 val2) { return h(); }\n\n\tfunction a() public pure {\n\t\t(bytes32 v1, bytes3 v2) = f2();\n\t\tassert(v1 == \"abc\");\n\t\tassert(v2 == \"cde\");\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (410-429): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_literal_to_fixed_bytes_upcast.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tassert(bytes4(hex\"0000ffff\") == bytes4(hex\"ffff\")); // should fail\n\t\tassert(bytes4(hex\"ffff0000\") == bytes4(hex\"ffff\")); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (43-93): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_to_bytes_push_1.sol",
    "content": "contract C {\n\tstring x;\n\n\tfunction s() public {\n\t\tx = \"abc\";\n\t\tbytes(x).push(\"a\");\n\t\tassert(bytes(x).length == 4); // should hold\n\t\tassert(bytes(x).length == 3); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (132-160): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/string_to_bytes_push_2.sol",
    "content": "contract C {\n\tstring x;\n\n\tfunction s() public {\n\t\tx = \"abc\";\n\t\t((bytes(((x))))).push(\"a\");\n\t\tassert(bytes(x).length == 4); // should hold\n\t\tassert(bytes(x).length == 3); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (140-168): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/typecast/upcast.sol",
    "content": "abstract contract D {}\n\ncontract C {\n\tfunction f1() public pure {\n\t\t// unsigned <- signed\n\t\tuint16 x = type(uint16).max;\n\t\tassert(x == 65535);\n\t\tint8 i = int8(-1);\n\t\tassert(i == -1);\n\t\tx = uint16(uint8(int8(-1)));\n\t\tassert(x == 255);\n\t\tx = uint16(int16(i));\n\t\tassert(x == 65535);\n\t\tuint z = uint(uint8(i));\n\t\tassert(z == 255);\n\t}\n\n\tfunction f2() public pure {\n\t\t// signed <- unsigned\n\t\tint16 y = int16(uint16(uint8(uint(65535))));\n\t\tassert(y == 255);\n\t\tint z = int(uint(uint8(type(uint).max)));\n\t\tassert(z == 255);\n\t\tz = int(uint(uint8(255)));\n\t\tassert(z == 255);\n\t}\n\n\tfunction f3() public pure {\n\t\t// signed <- signed\n\t\tint16 y = int16(uint16(uint8(int8(int(uint(65535))))));\n\t\tassert(y == 255);\n\t\tint z = int(int8(-1));\n\t\tassert(z == -1);\n\t\tz = int(int8(int(255)));\n\t\tassert(z == -1);\n\t\tz = int(int16(5000));\n\t\tassert(z == 5000);\n\t}\n\n\tfunction f4() public pure {\n\t\t// unsigned <- unsigned\n\t\tuint x = uint(uint8(type(uint).max));\n\t\tassert(x == 255);\n\t\tx = uint(uint16(type(uint).max));\n\t\tassert(x == 65535);\n\t\tx = uint(uint16(5000));\n\t\tassert(x == 5000);\n\t\tuint16 y = uint16(type(uint).max);\n\t\tassert(y == 65535);\n\t\ty = uint16(uint8(type(uint16).max));\n\t\tassert(y == 255);\n\t\taddress a = address(uint160(uint8(0)));\n\t\tassert(a == address(0));\n\t\tD d = D(address(uint160(uint8(0))));\n\t\tassert(a == address(d));\n\t\tbytes2 b1 = 0xcafe;\n\t\tbytes4 b2 = bytes4(b1);\n\t\tassert(b2 == 0xcafe0000);\n\t\tbytes16 b3 = bytes16(b1);\n\t\tassert(b3 == 0xcafe0000000000000000000000000000);\n\t\tbytes4 b4 = bytes4(uint32(0xcafe));\n\t\tassert(b4 == 0x0000cafe);\n\t\tbytes4 b5 = bytes4(uint32(0xcafe0000));\n\t\tassert(b5 == 0xcafe0000);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 23 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/abi_type_type_1.sol",
    "content": "contract C {\n\tfunction f(bytes memory d) public pure {\n\t\t(bool a, uint x) = abi.decode(d, (bool, uint));\n\t\tassert(a == (x == 2)); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (107-128): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = false\\nx = 2\\n\\nTransaction trace:\\nC.constructor()\\nC.f(d)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/abi_type_type_2.sol",
    "content": "contract C {\n\tfunction f(bytes memory d) public pure {\n\t\tassert(abi.decode(d, (bool))); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (57-86): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f(d)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/address_balance.sol",
    "content": "contract C\n{\n\tfunction f(address a, address b) public view {\n\t\tuint x = b.balance + 1000 ether;\n\t\tassert(a.balance > b.balance);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (63-69): Unused local variable.\n// Warning 4984: (72-94): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\n// Warning 6328: (98-127): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/address_call.sol",
    "content": "contract C\n{\n\tuint x;\n\tmapping (uint => uint) map;\n\tfunction f(address a, bytes memory data) public {\n\t\tx = 0;\n\t\tmap[0] = 0;\n\t\tmapping (uint => uint) storage localMap = map;\n\t\t(bool success, bytes memory ret) = a.call(data);\n\t\tassert(success);\n\t\tassert(x == 0);\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//assert(map[0] == 0);\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//assert(localMap[0] == 0);\n\t}\n}\n// ====\n// EVMVersion: >spuriousDragon\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreInv: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 2072: (127-166): Unused local variable.\n// Warning 2072: (191-207): Unused local variable.\n// Warning 6328: (227-242): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/address_delegatecall.sol",
    "content": "contract C\n{\n\tuint x;\n\tmapping (uint => uint) map;\n\tfunction f(address a, bytes memory data) public {\n\t\tx = 0;\n\t\tmap[0] = 0;\n\t\tmapping (uint => uint) storage localMap = map;\n\t\t(bool success, bytes memory ret) = a.delegatecall(data);\n\t\tassert(success);\n\t\tassert(x == 0);\n\t\tassert(map[0] == 0);\n\t\tassert(localMap[0] == 0);\n\t}\n}\n// ====\n// EVMVersion: >spuriousDragon\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (191-207): Unused local variable.\n// Warning 4588: (211-231): Assertion checker does not yet implement this type of function call.\n// Warning 6328: (235-250): CHC: Assertion violation happens here.\n// Warning 6328: (254-268): CHC: Assertion violation happens here.\n// Warning 6328: (272-291): CHC: Assertion violation happens here.\n// Warning 6328: (295-319): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/address_staticcall.sol",
    "content": "contract C\n{\n\tuint x;\n\tmapping (uint => uint) map;\n\tfunction f(address a, bytes memory data) public {\n\t\tx = 0;\n\t\tmap[0] = 0;\n\t\tmapping (uint => uint) storage localMap = map;\n\t\t(bool success, bytes memory ret) = a.staticcall(data);\n\t\tassert(success);\n\t\tassert(x == 0);\n\t\tassert(map[0] == 0);\n\t\t// Disabled because of Spacer's seg fault\n\t\t//assert(localMap[0] == 0);\n\t}\n}\n// ====\n// EVMVersion: >spuriousDragon\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (127-166): Unused local variable.\n// Warning 2072: (191-207): Unused local variable.\n// Warning 6328: (233-248): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/address_transfer.sol",
    "content": "contract C\n{\n\tfunction f(address payable a) public {\n\t\tuint x = 100;\n\t\trequire(x == a.balance);\n\t\ta.transfer(600);\n\t\t// This fails since a == this is possible.\n\t\tassert(a.balance == 700);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9207: (98-108): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 8656: (98-113): CHC: Insufficient funds happens here.\\nCounterexample:\\n\\na = 0x51f0\\nx = 100\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0x51f0)\n// Warning 6328: (162-186): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = 0x0\\nx = 100\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0x0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/address_transfer_2.sol",
    "content": "contract C\n{\n\tfunction f(uint x, address payable a, address payable b) public {\n\t\trequire(a != b);\n\t\trequire(x == 100);\n\t\trequire(x == a.balance);\n\t\trequire(a.balance == b.balance);\n\t\ta.transfer(600);\n\t\tb.transfer(100);\n\t\t// Fails since a == this is possible.\n\t\tassert(a.balance > b.balance);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 9207: (184-194): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 9207: (203-213): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 8656: (184-199): CHC: Insufficient funds happens here.\\nCounterexample:\\n\\nx = 100\\na = 0x6532\\nb = 0xffffffffffffffffffffffffffffffffffffed9d\\n\\nTransaction trace:\\nC.constructor()\\nC.f(100, 0x6532, 0xffffffffffffffffffffffffffffffffffffed9d)\n// Warning 8656: (203-218): CHC: Insufficient funds happens here.\\nCounterexample:\\n\\nx = 100\\na = 0x08c0\\nb = 0x7992\\n\\nTransaction trace:\\nC.constructor()\\nC.f(100, 0x08c0, 0x7992)\n// Warning 6328: (262-291): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 100\\na = 0x08c1\\nb = 0x08c0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(100, 0x08c1, 0x08c0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/address_transfer_3.sol",
    "content": "contract C\n{\n\tfunction f(address payable a) public {\n\t\trequire(1000 == address(this).balance);\n\t\trequire(100 == a.balance);\n\t\ta.transfer(600);\n\t\t// a == this is not possible because address(this).balance == 1000\n\t\t// and a.balance == 100,\n\t\t// so this should hold in CHC, ignoring the transfer revert.\n\t\tassert(a.balance == 700);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9207: (126-136): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/address_transfer_insufficient.sol",
    "content": "contract C\n{\n\tfunction f(address payable a, address payable b) public {\n\t\trequire(a.balance == 0);\n\t\ta.transfer(600);\n\t\tb.transfer(1000);\n\t\t// Fails since a == this is possible.\n\t\tassert(a.balance == 600);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 9207: (101-111): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 9207: (120-130): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 8656: (101-116): CHC: Insufficient funds happens here.\\nCounterexample:\\n\\na = 0x0\\nb = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0x0, 0x0)\n// Warning 8656: (120-136): CHC: Insufficient funds happens here.\\nCounterexample:\\n\\na = 0x0\\nb = 0x0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0x0, 0x0)\n// Warning 6328: (180-204): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = 0x0476\\nb = 0x0476\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0x0476, 0x0476)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_aliasing_memory_1.sol",
    "content": "pragma abicoder               v2;\n\ncontract C\n{\n\tfunction f(\n\t\tuint[] memory a,\n\t\tuint[] memory b,\n\t\tuint[][] memory cc,\n\t\tuint8[][] memory dd,\n\t\tuint[][][] memory eee\n\t) public pure {\n\t\trequire(a.length > 0);\n\t\trequire(b.length > 0);\n\t\trequire(cc.length > 0);\n\t\trequire(cc[0].length > 0);\n\t\trequire(dd.length > 0);\n\t\trequire(dd[0].length > 0);\n\t\trequire(eee.length > 0);\n\t\trequire(eee[0].length > 0);\n\t\trequire(eee[0][0].length > 0);\n\t\ta[0] = 2;\n\t\t// The accesses below are safe but oob is reported because of aliasing.\n\t\tcc[0][0] = 50;\n\t\tdd[0][0] = 10;\n\t\teee[0][0][0] = 50;\n\t\tb[0] = 1;\n\t\t// Fails because\n\t\t// b == a is possible\n\t\t// b == cc[0] is possible\n\t\t// b == ee[0][0] is possible\n\t\tassert(a[0] == 2 || cc[0][0] == 50 || eee[0][0][0] == 50);\n\t\t// Should not fail since knowledge is erased only for uint[].\n\t\tassert(dd[0][0] == 10);\n\t\tassert(b[0] == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6368: (523-528): CHC: Out of bounds access happens here.\n// Warning 6368: (523-531): CHC: Out of bounds access happens here.\n// Warning 6368: (557-563): CHC: Out of bounds access happens here.\n// Warning 6368: (557-566): CHC: Out of bounds access happens here.\n// Warning 6368: (557-569): CHC: Out of bounds access happens here.\n// Warning 6368: (578-582): CHC: Out of bounds access happens here.\n// Warning 6368: (699-703): CHC: Out of bounds access happens here.\n// Warning 6368: (712-717): CHC: Out of bounds access happens here.\n// Warning 6368: (712-720): CHC: Out of bounds access happens here.\n// Warning 6368: (730-736): CHC: Out of bounds access happens here.\n// Warning 6368: (730-739): CHC: Out of bounds access happens here.\n// Warning 6368: (730-742): CHC: Out of bounds access happens here.\n// Warning 6328: (692-749): CHC: Assertion violation happens here.\n// Warning 6368: (850-854): CHC: Out of bounds access happens here.\n// Info 1391: CHC: 12 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_aliasing_memory_2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C\n{\n\tuint[] array;\n\tfunction p() public {\n\t\tarray.push();\n\t}\n\tfunction f(uint[] memory a, uint[] memory b) public {\n\t\trequire(a.length > 0);\n\t\trequire(b.length > 0);\n\t\trequire(array.length > 0);\n\t\tarray[0] = 42;\n\t\ta[0] = 2;\n\t\t// Access is safe but oob is reported due of aliasing.\n\t\tb[0] = 1;\n\t\t// Erasing knowledge about memory references should not\n\t\t// erase knowledge about state variables.\n\t\t// Removed because current Spacer seg faults.\n\t\t//assert(array[0] == 42);\n\t\t// Accesses are safe but oob is reported due of aliasing.\n\t\tassert(a[0] == 2);\n\t\tassert(b[0] == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6368: (327-331): CHC: Out of bounds access happens here.\n// Warning 6368: (584-588): CHC: Out of bounds access happens here.\n// Warning 6328: (577-594): CHC: Assertion violation happens here.\n// Warning 6368: (605-609): CHC: Out of bounds access happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_aliasing_memory_3.sol",
    "content": "pragma abicoder               v2;\n\ncontract C\n{\n\tuint[] array;\n\tconstructor() {\n\t\tarray.push();\n\t}\n\tfunction f(uint[] memory a, uint[] memory b) public {\n\t\trequire(a.length > 0);\n\t\tarray[0] = 42;\n\t\tuint[] storage c = array;\n\t\ta[0] = 2;\n\t\trequire(b.length > 0);\n\t\tb[0] = 1;\n\t\t// Erasing knowledge about memory references should not\n\t\t// erase knowledge about state variables.\n\t\tassert(array[0] == 42);\n\t\t// Erasing knowledge about memory references should not\n\t\t// erase knowledge about storage references.\n\t\tassert(c[0] == 42);\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(a[0] == 2);\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(b[0] == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_aliasing_storage_1.sol",
    "content": "contract C\n{\n\tuint[] array;\n\tuint[][] array2d;\n\tuint[][][][] array4d;\n\tuint8[] tinyArray;\n\tuint8[][][] tinyArray3d;\n\tfunction f(\n\t\tuint[] storage a,\n\t\tuint[] storage b,\n\t\tuint[][] storage cc,\n\t\tuint8[][] storage dd,\n\t\tuint[][][] storage eee\n\t) internal {\n\t\ta[0] = 2;\n\t\tarray[0] = 42;\n\t\tarray2d[0][0] = 42;\n\t\ttinyArray[0] = 42;\n\t\tcc[0][0] = 42;\n\t\tdd[0][0] = 42;\n\t\teee[0][0][0] = 42;\n\t\tb[0] = 1;\n\t\t// Fails because b == a is possible.\n\t\tassert(a[0] == 2);\n\t\t// Fails because b == array is possible.\n\t\tassert(array[0] == 42);\n\t\t// Fails because b == array2d[0] is possible.\n\t\tassert(array2d[0][0] == 42);\n\t\t// Should not fail since knowledge is erased only for uint[].\n\t\tassert(tinyArray[0] == 42);\n\t\t// Fails because b == cc[0] is possible.\n\t\tassert(cc[0][0] == 42);\n\t\t// Should not fail since knowledge is erased only for uint[].\n\t\tassert(dd[0][0] == 42);\n\t\t// Fails because b == ee[0][0] is possible.\n\t\tassert(eee[0][0][0] == 42);\n\t\tassert(b[0] == 1);\n\t}\n\n\tfunction g(uint a, uint b, uint c, uint d, uint e) public {\n\t\trequire(a < array2d.length);\n\t\trequire(b < array2d.length);\n\t\trequire(c < array4d.length);\n\t\trequire(c < array4d[c].length);\n\t\trequire(d < tinyArray3d.length);\n\t\trequire(e < array4d.length);\n\t\t// Disabled because of Spacer seg fault.\n\t\t//f(array2d[a], array2d[b], array4d[c][c], tinyArray3d[d], array4d[e]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2018: (957-1329): Function state mutability can be restricted to view\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_aliasing_storage_2.sol",
    "content": "contract C\n{\n\tuint[][] array2d;\n\tfunction p() public {\n\t\tarray2d.push().push();\n\t}\n\tfunction g(uint x, uint y, uint[] memory c) public {\n\t\trequire(x < array2d.length);\n\t\trequire(y < array2d.length);\n\t\tf(array2d[x], array2d[y], c);\n\t}\n\n\tfunction f(uint[] storage a, uint[] storage b, uint[] memory c) internal {\n\t\trequire(a.length > 0);\n\t\trequire(b.length > 0);\n\t\trequire(c.length > 0);\n\t\tc[0] = 42;\n\t\ta[0] = 2;\n\t\t// Access is safe but oob is reported because of aliasing.\n\t\tb[0] = 1;\n\t\t// Erasing knowledge about storage references should not\n\t\t// erase knowledge about memory references.\n\t\tassert(c[0] == 42);\n\t\t// Fails because b == a is possible.\n\t\tassert(a[0] == 2);\n\t\t// Access is safe but oob is reported because of aliasing.\n\t\tassert(b[0] == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6368: (474-478): CHC: Out of bounds access happens here.\n// Warning 6368: (659-663): CHC: Out of bounds access happens here.\n// Warning 6328: (652-669): CHC: Assertion violation happens here.\n// Warning 6368: (741-745): CHC: Out of bounds access happens here.\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_aliasing_storage_3.sol",
    "content": "contract C\n{\n\tuint[][] array2d;\n\tfunction p() public { array2d.push().push(); }\n\tfunction g(uint x, uint y, uint[] memory c) public {\n\t\trequire(x < array2d.length);\n\t\trequire(y < array2d.length);\n\t\tf(array2d[x], array2d[y], c);\n\t}\n\tfunction f(uint[] storage a, uint[] storage b, uint[] memory c) internal {\n\t\trequire(a.length > 0);\n\t\trequire(b.length > 0);\n\t\trequire(c.length > 0);\n\t\tuint[] memory d = c;\n\t\tc[0] = 42;\n\t\ta[0] = 2;\n\t\t// Access is safe but oob is reported due of aliasing.\n\t\tb[0] = 1;\n\t\t// Erasing knowledge about storage references should not\n\t\t// erase knowledge about memory references.\n\t\t// Disabled because of Spacer's seg fault.\n\t\t//assert(c[0] == 42);\n\t\t// Erasing knowledge about storage references should not\n\t\t// erase knowledge about memory references.\n\t\t// Disabled because of Spacer's seg fault.\n\t\t//assert(d[0] == 42);\n\t\t// Fails because b == a is possible.\n\t\t// Accesses are safe but oob is reported due of aliasing.\n\t\tassert(a[0] == 2);\n\t\tassert(b[0] == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2072: (384-399): Unused local variable.\n// Warning 6368: (489-493): CHC: Out of bounds access happens here.\n// Warning 6368: (955-959): CHC: Out of bounds access happens here.\n// Warning 6328: (948-965): CHC: Assertion violation happens here.\n// Warning 6368: (976-980): CHC: Out of bounds access happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_aliasing_storage_4.sol",
    "content": "contract C\n{\n\tuint[] array;\n\tuint[][] array2d;\n\tfunction p() public {\n\t\tarray.push();\n\t\tarray2d.push().push();\n\t}\n\tfunction f(uint[] storage a, uint[] storage b) internal {\n\t\trequire(a.length > 0);\n\t\trequire(b.length > 0);\n\t\ta[0] = 2;\n\t\t// Accesses are safe but oob is reported because of aliasing.\n\t\tb[0] = 42;\n\t\tarray[0] = 1;\n\t\t// Fails because array == a is possible.\n\t\tassert(a[0] == 2);\n\t\t// Fails because array == b is possible.\n\t\tassert(b[0] == 42);\n\t\tassert(array[0] == 1);\n\t}\n\tfunction g(uint x, uint y) public {\n\t\trequire(x < array2d.length);\n\t\trequire(y < array2d.length);\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//f(array2d[x], array2d[y]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2018: (486-665): Function state mutability can be restricted to view\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_aliasing_storage_5.sol",
    "content": "contract C\n{\n\tuint[] b;\n\tuint[] d;\n\tuint[][] array2d;\n\tfunction p() public {\n\t\tarray2d.push().push();\n\t}\n\tfunction g(uint x, uint[] memory c) public {\n\t\trequire(x < array2d.length);\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//f(array2d[0], c);\n\t}\n\tfunction f(uint[] storage a, uint[] memory c) internal {\n\t\t// Accesses are safe but oob is reported because of aliasing.\n\t\td[0] = 42;\n\t\tc[0] = 42;\n\t\ta[0] = 2;\n\t\tb[0] = 1;\n\t\t// Erasing knowledge about storage variables should not\n\t\t// erase knowledge about memory references.\n\t\tassert(c[0] == 42);\n\t\t// Fails because d == a is possible.\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(d[0] == 42);\n\t\t// Fails because b == a and d == a are possible.\n\t\tassert(a[0] == 2);\n\t\t// b == a is possible, but does not fail because b\n\t\t// was the last assignment.\n\t\tassert(b[0] == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 5667: (125-140): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 2018: (106-254): Function state mutability can be restricted to view\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_branch_1d.sol",
    "content": "contract C\n{\n\tfunction f(bool b, uint[] memory c) public pure {\n\t\trequire(c.length >= 1 && c.length <= 2);\n\t\tc[0] = 0;\n\t\tif (b)\n\t\t\tc[0] = 1;\n\t\tassert(c[0] > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (143-159): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_branch_2d.sol",
    "content": "contract C\n{\n\tuint[][] c;\n\tconstructor() {\n\t\tc.push().push();\n\t}\n\tfunction f(bool b) public {\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t/*\n\t\tc[0][0] = 0;\n\t\tif (b)\n\t\t\tc[0][0] = 1;\n\t\tassert(c[0][0] > 0);\n\t\t*/\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_branch_3d.sol",
    "content": "contract C\n{\n\tuint[][][] c;\n\tconstructor() {\n\t\tc.push();\n\t\tc[0].push();\n\t\tc[0][0].push();\n\t}\n\tfunction f(bool b) public {\n\t\tif (b)\n\t\t\tc[0][0][0] = 1;\n\t\tassert(c[0][0][0] > 0);\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTSolvers: eld\n// SMTTargets: assert\n// ----\n// Warning 6328: (152-174): CHC: Assertion violation happens here.\\nCounterexample:\\nc = [[[0]]]\\nb = false\\n\\nTransaction trace:\\nC.constructor()\\nState: c = [[[0]]]\\nC.f(false)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_branches_1d.sol",
    "content": "contract C\n{\n\tfunction f(bool b, uint[] memory c) public pure {\n\t\trequire(c.length > 0);\n\t\tc[0] = 0;\n\t\tif (b)\n\t\t\tc[0] = 1;\n\t\telse\n\t\t\tc[0] = 2;\n\t\tassert(c[0] > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_branches_2d.sol",
    "content": "contract C\n{\n\tuint[][] c;\n\tfunction p() public {\n\t\tc.push().push();\n\t}\n\tfunction f(bool b) public {\n\t\trequire(c.length > 0);\n\t\trequire(c[0].length > 0);\n\t\tc[0][0] = 0;\n\t\tif (b)\n\t\t\tc[0][0] = 1;\n\t\telse\n\t\t\tc[0][0] = 2;\n\t\tassert(c[0][0] > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_branches_3d.sol",
    "content": "contract C\n{\n\tuint[][][] c;\n\tconstructor() {\n\t\tc.push();\n\t\tc[0].push();\n\t\tc[0][0].push();\n\t}\n\tfunction f(bool b) public {\n\t\tc[0][0][0] = 0;\n\t\tif (b)\n\t\t\tc[0][0][0] = 1;\n\t\tassert(c[0][0][0] < 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTTargets: assert\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_dynamic_1.sol",
    "content": "contract C\n{\n\tuint[] array;\n\tconstructor() {\n\t\tarray.push();\n\t\tarray.push();\n\t\tarray.push();\n\t\tarray.push();\n\t}\n\tfunction f(uint x, uint y) public {\n\t\trequire(x < array.length);\n\t\tarray[x] = 200;\n\t\trequire(x == y);\n\t\tassert(array[y] > 100);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_dynamic_1_fail.sol",
    "content": "contract C\n{\n\tuint[] array;\n\tfunction p() public { array.push(); }\n\tfunction f(uint x, uint y) public {\n\t\trequire(x < array.length);\n\t\tarray[x] = 200;\n\t\trequire(x == y);\n\t\tassert(array[y] > 300);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (172-194): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_dynamic_2.sol",
    "content": "contract C\n{\n\tuint[][] array;\n\tfunction f(uint x, uint y, uint z, uint t) public view {\n\t\trequire(array[x][y] == 200);\n\t\trequire(x == z && y == t);\n\t\tassert(array[z][t] > 100);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6368: (98-106): CHC: Out of bounds access happens here.\n// Warning 6368: (98-109): CHC: Out of bounds access happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_dynamic_2_fail.sol",
    "content": "contract C\n{\n\tuint[][] array;\n\tfunction a() public {\n\t\tarray.push().push();\n\t}\n\tfunction f(uint x, uint y, uint z, uint t) public {\n\t\trequire(x < array.length);\n\t\trequire(y < array[x].length);\n\t\tarray[x][y] = 200;\n\t\trequire(x == z && y == t);\n\t\tassert(array[z][t] > 300);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (245-270): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_dynamic_3.sol",
    "content": "contract C\n{\n\tuint[][][] array;\n\tfunction f(uint x, uint y, uint z, uint t, uint w, uint v) public view {\n\t\trequire(x < array.length);\n\t\trequire(y < array[x].length);\n\t\trequire(z < array[x][y].length);\n\t\trequire(array[x][y][z] == 200);\n\t\trequire(x == t && y == w && z == v);\n\t\tassert(array[t][w][v] > 100);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_dynamic_3_fail.sol",
    "content": "contract C\n{\n\tuint[][][] array;\n\tfunction p() public {\n\t\tarray.push().push().push();\n\t}\n\tfunction f(uint x, uint y, uint z, uint t, uint w, uint v) public {\n\t\trequire(x < array.length);\n\t\trequire(y < array[x].length);\n\t\trequire(z < array[x][y].length);\n\t\tarray[x][y][z] = 200;\n\t\trequire(x == t && y == w && z == v);\n\t\tassert(array[t][w][v] > 300);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (318-346): CHC: Assertion violation happens here.\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_dynamic_parameter_1.sol",
    "content": "contract C\n{\n\tfunction f(uint[] memory array, uint x, uint y) public pure {\n\t\trequire(x < array.length);\n\t\tarray[x] = 200;\n\t\trequire(x == y);\n\t\tassert(array[y] > 100);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_dynamic_parameter_1_fail.sol",
    "content": "contract C\n{\n\tfunction f(uint[] memory array, uint x, uint y) public pure {\n\t\trequire(x < array.length);\n\t\tarray[x] = 200;\n\t\trequire(x == y);\n\t\tassert(array[y] > 300);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (144-166): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_literal_1.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint[3] memory array = [uint(1), 2, 3];\n\t\tassert(array[0] == 1);\n\t\tassert(array[1] == 2);\n\t\tassert(array[2] == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_literal_2.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint[3] memory a = [uint(1), 2, 3];\n\t\tuint[3] memory b = [uint(1), 2, 4];\n\t\tassert(a[0] == b[0]);\n\t\tassert(a[1] == b[1]);\n\t\tassert(a[2] == b[2]); // fails\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (167-187): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = [1, 2, 3]\\nb = [1, 2, 4]\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_literal_3.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\t(uint[3] memory a, uint[3] memory b) = ([uint(1), 2, 3], [uint(1), 2, 4]);\n\t\tassert(a[0] == b[0]);\n\t\tassert(a[1] == b[1]);\n\t\tassert(a[2] == b[2]); // fails\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (168-188): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = [1, 2, 3]\\nb = [1, 2, 4]\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_literal_4.sol",
    "content": "contract C\n{\n\tfunction f(bool c) public pure {\n\t\tuint[3] memory a = c ? [uint(1), 2, 3] : [uint(1), 2, 4];\n\t\tuint[3] memory b = [uint(1), 2, c ? 3 : 4];\n\t\tassert(a[0] == b[0]);\n\t\tassert(a[1] == b[1]);\n\t\tassert(a[2] == b[2]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_literal_5.sol",
    "content": "contract C\n{\n\tuint[] s;\n\tfunction f() public {\n\t\tuint[3] memory a = [uint(1), 2, 3];\n\t\ts = a;\n\t\tassert(s.length == a.length);\n\t\tassert(s[0] == a[0]);\n\t\tassert(s[1] == a[1]);\n\t\tassert(s[2] != a[2]); // fails\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (176-196): CHC: Assertion violation happens here.\\nCounterexample:\\ns = [1, 2, 3]\\na = [1, 2, 3]\\n\\nTransaction trace:\\nC.constructor()\\nState: s = []\\nC.f()\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_literal_6.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint[3] memory a = [uint(1), 2, 3];\n\t\tuint[4] memory b = [uint(1), 2, 4, 3];\n\t\tuint[4] memory c = b;\n\t\tassert(a.length == c.length); // fails\n\t\tassert(a[0] == c[0]);\n\t\tassert(a[1] == c[1]);\n\t\tassert(a[2] == c[2]); // fails\n\t\tassert(a[2] == c[3]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (146-174): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = [1, 2, 3]\\nb = [1, 2, 4, 3]\\nc = [1, 2, 4, 3]\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (235-255): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = [1, 2, 3]\\nb = [1, 2, 4, 3]\\nc = [1, 2, 4, 3]\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Info 1391: CHC: 11 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_literal_7.sol",
    "content": "contract C\n{\n\tuint[] s;\n\tfunction f() public {\n\t\tuint[3] memory a = [uint(1), 2, 3];\n\t\tuint[4] memory b = [uint(1), 2, 4, 3];\n\t\tuint[4] memory c = b;\n\t\tassert(c.length == b.length);\n\t\ts = a;\n\t\tassert(s.length == a.length);\n\n\t\tassert(s.length == c.length); // fails\n\t\tassert(s[0] == c[0]);\n\t\tassert(s[1] == c[1]);\n\t\tassert(s[2] == c[2]); // fails\n\t\tassert(s[2] == c[3]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (226-254): CHC: Assertion violation happens here.\n// Warning 6328: (315-335): CHC: Assertion violation happens here.\n// Info 1391: CHC: 13 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_mapping_aliasing_1.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) singleMap;\n\tmapping (uint => uint)[] severalMaps;\n\tmapping (uint => uint8)[] severalMaps8;\n\tmapping (uint => uint)[][] severalMaps3d;\n\tfunction p() public {\n\t\tseveralMaps.push();\n\t\tseveralMaps8.push();\n\t\tseveralMaps3d.push().push();\n\t}\n\tfunction f(mapping (uint => uint) storage map) internal {\n\t\trequire(severalMaps.length > 0);\n\t\trequire(severalMaps8.length > 0);\n\t\trequire(severalMaps3d.length > 0);\n\t\trequire(severalMaps3d[0].length > 0);\n\t\tseveralMaps[0][0] = 42;\n\t\tseveralMaps8[0][0] = 42;\n\t\tseveralMaps3d[0][0][0] = 42;\n\t\tmap[0] = 2;\n\t\t// Should fail since map == severalMaps[0] is possible.\n\t\t// Access is safe but oob is reported because of aliasing.\n\t\tassert(severalMaps[0][0] == 42);\n\t\t// Should not fail since knowledge is erased only for mapping (uint => uint).\n\t\tassert(severalMaps8[0][0] == 42);\n\t\t// Should fail since map == severalMaps3d[0][0] is possible.\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(severalMaps3d[0][0][0] == 42);\n\t}\n\tfunction g(uint x) public {\n\t\trequire(x < severalMaps.length);\n\t\tf(severalMaps[x]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6368: (706-720): CHC: Out of bounds access happens here.\n// Warning 6328: (699-730): CHC: Assertion violation happens here.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_mapping_aliasing_2.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) singleMap;\n\tmapping (uint => uint)[] severalMaps;\n\tmapping (uint => uint8)[] severalMaps8;\n\tmapping (uint => uint)[][] severalMaps3d;\n\tconstructor() {\n\t\tseveralMaps.push();\n\t\tseveralMaps8.push();\n\t\tseveralMaps3d.push().push();\n\t}\n\tfunction f(mapping (uint => uint) storage map) internal {\n\t\tmap[0] = 42;\n\t\t// Index accesses are safe but the assignment above makes\n\t\t// them fail because of aliasing.\n\t\tseveralMaps[0][0] = 42;\n\t\tseveralMaps8[0][0] = 42;\n\t\tseveralMaps3d[0][0][0] = 42;\n\t\tsingleMap[0] = 2;\n\t\t// Should not fail since singleMap == severalMaps[0] is not possible.\n\t\tassert(severalMaps[0][0] == 42);\n\t\t// Should not fail since knowledge is erased only for mapping (uint => uint).\n\t\tassert(severalMaps8[0][0] == 42);\n\t\t// Should not fail since singleMap == severalMaps3d[0][0] is not possible.\n\t\tassert(severalMaps3d[0][0][0] == 42);\n\t\t// Should fail since singleMap == map is possible.\n\t\tassert(map[0] == 42);\n\t}\n\tfunction g(uint x) public {\n\t\trequire(x < severalMaps.length);\n\t\tf(severalMaps[x]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTTargets: assert\n// ----\n// Warning 6328: (936-956): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.g(0)\\n    C.f(map) -- counterexample incomplete; parameter name used instead of value -- internal call\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_of_addresses.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.0.0;\ncontract C {\n\taddress[10] a;\n\taddress payable[10] b;\n\n\tfunction f() public {\n\t\ta = b;\n\t\tassert(a[0] == b[0]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_of_contracts.sol",
    "content": "contract A {}\n\ncontract B is A {}\n\ncontract C {\n\tA[10] a;\n\tB[10] b;\n\n\tfunction f() public returns(address) {\n\t\ta = b;\n\t\treturn address(a[0]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_of_functions.sol",
    "content": "contract C {\n\tfunction() external returns(uint)[1] a;\n\n\tfunction b() external pure returns(uint) {\n\t\treturn 1;\n\t}\n\n\tfunction test() public returns(uint) {\n\t\ta = [this.b];\n\t\treturn a[0]();\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_static_1.sol",
    "content": "contract C\n{\n\tuint[10] array;\n\tfunction f(uint x, uint y) public {\n\t\trequire(x < array.length);\n\t\tarray[x] = 200;\n\t\trequire(x == y);\n\t\tassert(array[y] > 100);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_static_1_fail.sol",
    "content": "contract C\n{\n\tuint[10] array;\n\tfunction f(uint x, uint y) public {\n\t\trequire(x < array.length);\n\t\tarray[x] = 200;\n\t\trequire(x == y);\n\t\tassert(array[y] > 300);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (135-157): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_static_2.sol",
    "content": "contract C\n{\n\tuint[10][20] array;\n\tfunction f(uint x, uint y, uint z, uint t) public view {\n\t\trequire(x < array.length);\n\t\trequire(y < array[x].length);\n\t\trequire(array[x][y] == 200);\n\t\trequire(x == z && y == t);\n\t\tassert(array[z][t] > 100);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_static_2_fail.sol",
    "content": "contract C\n{\n\tuint[10][20] array;\n\tfunction f(uint x, uint y, uint z, uint t) public view {\n\t\trequire(x < array.length);\n\t\trequire(y < array[x].length);\n\t\trequire(array[x][y] < 200);\n\t\trequire(x == z && y == t);\n\t\tassert(array[z][t] > 300);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (214-239): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_static_3.sol",
    "content": "contract C\n{\n\tuint[10][20][30] array;\n\tfunction f(uint x, uint y, uint z, uint t, uint w, uint v) public view {\n\t\trequire(x < array.length);\n\t\trequire(y < array[x].length);\n\t\trequire(z < array[x][y].length);\n\t\trequire(array[x][y][z] == 200);\n\t\trequire(x == t && y == w && z == v);\n\t\tassert(array[t][w][v] > 100);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_static_3_fail.sol",
    "content": "contract C\n{\n\tuint[10][20][30] array;\n\tfunction f(uint x, uint y, uint z, uint t, uint w, uint v) public {\n\t\trequire(x < array.length);\n\t\trequire(y < array[x].length);\n\t\trequire(z < array[x][y].length);\n\t\tarray[x][y][z] = 200;\n\t\trequire(x == t && y == w && z == v);\n\t\tassert(array[t][w][v] > 300);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (268-296): CHC: Assertion violation happens here.\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_static_aliasing_memory_5.sol",
    "content": "contract C\n{\n\tfunction f(uint[2] memory a, uint[2] memory b, uint[2] memory c) public pure {\n\t\trequire(c[0] == 42);\n\t\trequire(a[0] == 2);\n\t\tb[0] = 1;\n\t\t// Should fail since b == c is possible.\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(c[0] == 42);\n\t\t// Should fail since b == a is possible.\n\t\t// Access is safe but oob is reported due of aliasing.\n\t\tassert(a[0] == 2);\n\t\tassert(b[0] == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (385-402): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_static_aliasing_storage_5.sol",
    "content": "contract C\n{\n\tuint[2] b1;\n\tuint[2] b2;\n\tfunction f(uint[2] storage a, uint[2] memory c) internal {\n\t\t// Accesses are safe but oob is reported because of aliasing.\n\t\tc[0] = 42;\n\t\ta[0] = 2;\n\t\tb1[0] = 1;\n\t\t// Erasing knowledge about storage variables should not\n\t\t// erase knowledge about memory references.\n\t\tassert(c[0] == 42);\n\t\t// Fails because b1 == a is possible.\n\t\t// Disabled because Spacer seg faults.\n\t\t//assert(a[0] == 2);\n\t\tassert(b1[0] == 1);\n\t}\n\tfunction g(bool x, uint[2] memory c) public {\n\t\tif (x) f(b1, c);\n\t\telse f(b2, c);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_1.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) singleMap;\n\tmapping (uint => uint)[2] severalMaps;\n\tmapping (uint => uint8)[2] severalMaps8;\n\tmapping (uint => uint)[2][2] severalMaps3d;\n\tfunction f(mapping (uint => uint) storage map) internal {\n\t\tseveralMaps[0][0] = 42;\n\t\tseveralMaps8[0][0] = 42;\n\t\tseveralMaps3d[0][0][0] = 42;\n\t\tmap[0] = 2;\n\t\t// Should fail since map == severalMaps[0] is possible.\n\t\tassert(severalMaps[0][0] == 42);\n\t\t// Should not fail since knowledge is erased only for mapping (uint => uint).\n\t\tassert(severalMaps8[0][0] == 42);\n\t\t// Should fail since map == severalMaps3d[0][0] is possible.\n\t\tassert(severalMaps3d[0][0][0] == 42);\n\t}\n\tfunction g(uint x) public {\n\t\trequire(x < severalMaps.length);\n\t\tf(severalMaps[x]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTTargets: assert\n// ----\n// Warning 6328: (392-423): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.g(0)\\n    C.f(map) -- counterexample incomplete; parameter name used instead of value -- internal call\n// Warning 6328: (606-642): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.g(0)\\n    C.f(map) -- counterexample incomplete; parameter name used instead of value -- internal call\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_static_mapping_aliasing_2.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) singleMap;\n\tmapping (uint => uint)[2] severalMaps;\n\tmapping (uint => uint8)[2] severalMaps8;\n\tmapping (uint => uint)[2][2] severalMaps3d;\n\tfunction f(mapping (uint => uint) storage map) internal {\n\t\tmap[0] = 42;\n\t\tseveralMaps[0][0] = 42;\n\t\tseveralMaps8[0][0] = 42;\n\t\tseveralMaps3d[0][0][0] = 42;\n\t\tsingleMap[0] = 2;\n\t\t// Should not fail since singleMap == severalMaps[0] is not possible.\n\t\tassert(severalMaps[0][0] == 42);\n\t\t// Should not fail since knowledge is erased only for mapping (uint => uint).\n\t\tassert(severalMaps8[0][0] == 42);\n\t\t// Should not fail since singleMap == severalMaps3d[0][0] is not possible.\n\t\tassert(severalMaps3d[0][0][0] == 42);\n\t\t// Should fail since singleMap == map is possible.\n\t\tassert(map[0] == 42);\n\t}\n\tfunction g(uint x) public {\n\t\trequire(x < 2);\n\t\tf(severalMaps3d[x][0]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTTargets: assert\n// ----\n// Warning 6328: (748-768): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.g(0)\\n    C.f(map) -- counterexample incomplete; parameter name used instead of value -- internal call\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/array_struct_array_branches_2d.sol",
    "content": "contract C\n{\n\tstruct S { uint[][] a; }\n\tfunction f(bool b) public pure {\n\t\tS[] memory c = new S[](1);\n\t\t// Disabled because of Spacer nondetemrinism.\n\t\t/*\n\t\tc[0].a = new uint[][](1);\n\t\tc[0].a[0] = new uint[](1);\n\t\tc[0].a[0][0] = 0;\n\t\tif (b)\n\t\t\tc[0].a[0][0] = 1;\n\t\telse\n\t\t\tc[0].a[0][0] = 2;\n\t\tassert(c[0].a[0][0] > 0);\n\t\t*/\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (51-57): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 2072: (75-87): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bool_int_mixed_1.sol",
    "content": "contract C {\n    function f(bool x) public pure {\n        uint a;\n        if(x)\n            a = 1;\n        assert(!x || a > 0);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bool_int_mixed_2.sol",
    "content": "contract C {\n    function f(bool x, uint a) public pure {\n        require(!x || a > 0);\n        uint b = a;\n        assert(!x || b > 0);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bool_int_mixed_3.sol",
    "content": "contract C {\n    function f(bool x, bool y) public pure {\n        uint a;\n        if (x) {\n            if (y) {\n                a = 0;\n            } else {\n                a = 1;\n            }\n        } else {\n            if (y) {\n                a = 1;\n            } else {\n                a = 0;\n            }\n        }\n        bool xor_x_y = (x && !y) || (!x && y);\n        assert(!xor_x_y || a > 0);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bool_simple_1.sol",
    "content": "contract C {\n    function f(bool x) public pure {\n        assert(x);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (58-67): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = false\\n\\nTransaction trace:\\nC.constructor()\\nC.f(false)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bool_simple_2.sol",
    "content": "contract C {\n    function f(bool x, bool y) public pure {\n        assert(x == y);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (66-80): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = true\\ny = false\\n\\nTransaction trace:\\nC.constructor()\\nC.f(true, false)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bool_simple_3.sol",
    "content": "contract C {\n    function f(bool x, bool y) public pure {\n        bool z = x || y;\n        assert(!(x && y) || z);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bool_simple_4.sol",
    "content": "contract C {\n    function f(bool x) public pure {\n        if(x) {\n            assert(x);\n        } else {\n            assert(!x);\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bool_simple_5.sol",
    "content": "contract C {\n    function f(bool x) public pure {\n        bool y = x;\n        assert(x == y);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bool_simple_6.sol",
    "content": "contract C {\n    function f(bool x) public pure {\n        require(x);\n        bool y;\n        y = false;\n        assert(x || y);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bytes_1.sol",
    "content": "contract C\n{\n\tfunction f(bytes memory b) public pure returns (bytes memory) {\n\t\tbytes memory c = b;\n\t\treturn b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2072: (80-94): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bytes_2.sol",
    "content": "contract C\n{\n\tfunction f(bytes memory b1, bytes memory b2) public pure {\n\t\trequire(b2.length > 2);\n\t\tb1 = b2;\n\t\t// Knowledge about b2 is lost because of potential aliasing, so we re-add the length constraint.\n\t\trequire(b2.length > 2);\n\t\tassert(b1[1] == b2[1]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (237-259): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bytes_2_fail.sol",
    "content": "contract C\n{\n\tfunction f(bytes memory b1, bytes memory b2) public pure {\n\t\tb1 = b2;\n\t\trequire(b1.length > 2 && b2.length > 2);\n\t\tassert(b1[1] == b2[2]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (129-151): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/bytes_length.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tbytes memory x = hex\"0123\";\n\t\tassert(x.length == 2);\n\t}\n\tfunction g() public pure {\n\t\tbytes memory x = bytes(hex\"0123\");\n\t\tassert(x.length == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/contract.sol",
    "content": "contract C\n{\n\tfunction f(C c, C d) public pure {\n\t\tassert(c == d);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 9170: (58-64): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// Warning 6328: (51-65): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nc = 0\\nd = 1\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0, 1)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/contract_2.sol",
    "content": "contract D\n{\n\tuint x;\n}\n\ncontract C\n{\n\tfunction f(D c, D d) public pure {\n\t\tassert(c == d);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 9170: (83-89): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// Warning 6328: (76-90): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nc = 0\\nd = 1\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0, 1)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/contract_3.sol",
    "content": "contract C\n{\n\tfunction f(C c, C d, C e) public pure {\n\t\trequire(c == d);\n\t\trequire(d == e);\n\t\tassert(c == e);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9170: (64-70): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// Warning 9170: (83-89): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// Warning 9170: (101-107): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/contract_address_conversion.sol",
    "content": "contract C\n{\n\tfunction f(C c, address a) public pure {\n\t\tassert(address(c) == a);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (57-80): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/contract_address_conversion_2.sol",
    "content": "contract C\n{\n\tfunction f(C c, C d) public pure {\n\t\tassert(address(c) == address(c));\n\t\taddress a = address(c);\n\t\trequire(c == d);\n\t\tassert(a == address(d));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 9170: (121-127): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/data_location_in_function_type.sol",
    "content": "library L {\n    struct Nested { uint y; }\n    function c(function(Nested memory) external returns (uint)[] storage) external pure {}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/enum_explicit_values.sol",
    "content": "contract C\n{\n\tenum D { Left, Right }\n\tD d;\n\tfunction f(D _a) public {\n\t\trequire(_a == D.Left);\n\t\td = D.Right;\n\t\tassert(d != _a);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/enum_explicit_values_2.sol",
    "content": "contract C\n{\n\tenum D { Left, Right }\n\tD d;\n\tfunction f(D _a) public {\n\t\trequire(_a == D.Left);\n\t\td = D.Left;\n\t\tassert(d != _a);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (111-126): CHC: Assertion violation happens here.\\nCounterexample:\\nd = 0\\n_a = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: d = 0\\nC.f(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/enum_in_library.sol",
    "content": "library L\n{\n\tenum D { Left, Right }\n}\n\ncontract C\n{\n\tenum E { Left, Right }\n\tfunction f(E _d) public pure {\n\t\t_d = E.Left;\n\t\tassert(_d == E.Left);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/enum_in_library_2.sol",
    "content": "library L\n{\n\tenum D { Left, Right }\n}\n\ncontract C\n{\n\tenum E { Left, Right }\n\tfunction f(E _d) public pure {\n\t\t_d = E.Right;\n\t\tassert(_d == E.Left);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (126-146): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n_d = 1\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/enum_in_struct.sol",
    "content": "pragma abicoder               v2;\n\ncontract C\n{\n\tenum D { Left, Right }\n\tstruct S { uint x; D d; }\n\tfunction f(S memory s) public pure {\n\t\ts.d = D.Left;\n\t\tassert(s.d == D.Left);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/enum_range.sol",
    "content": "contract C\n{\n\tenum D { Left, Right }\n\tfunction f(D a) public pure {\n\t\tassert(a == D.Left || a == D.Right);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/enum_storage_eq.sol",
    "content": "contract C\n{\n\tenum D { Left, Right }\n\tD d;\n\tfunction f(D _d) public {\n\t\td = _d;\n\t\tassert(d != _d);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (82-97): CHC: Assertion violation happens here.\\nCounterexample:\\nd = 0\\n_d = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: d = 0\\nC.f(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/enum_transitivity.sol",
    "content": "contract C\n{\n\tenum D { Left, Right }\n\tD d;\n\tfunction f(D _a, D _b) public view {\n\t\trequire(_a == _b);\n\t\trequire(_a == d);\n\t\tassert(d == _b);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/event_with_rational_size_array.sol",
    "content": "contract a { event b(uint[(1 / 1)]); }\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/fixed_bytes_1.sol",
    "content": "contract C\n{\n\tbytes32 x;\n\tfunction f(bytes8 y) public view {\n\t\tassert(x != y);\n\t\tassert(x != g());\n\t}\n\tfunction g() public view returns (bytes32) {\n\t\treturn x;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (63-77): CHC: Assertion violation happens here.\n// Warning 6328: (81-97): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/fixed_bytes_2.sol",
    "content": "contract C\n{\n\tbytes32 x;\n\tfunction f(bytes8 y) public view {\n\t\tassert(x == g());\n\t\tassert(x != y);\n\t}\n\tfunction g() public view returns (bytes32) {\n\t\treturn x;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (83-97): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/fixed_bytes_access_1.sol",
    "content": "contract c {\n\tbytes10[6] data2;\n\tfunction test() public view returns (bytes10 r2) {\n\t\tr2 = data2[4][5];\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/fixed_bytes_access_2.sol",
    "content": "contract C {\n\tfunction f(bytes calldata x, uint y) external pure {\n\t\trequire(x.length > 10);\n\t\tx[8][0];\n\t\t// Disabled because of Spacer nondeterminism.\n\t\t//x[8][5%y];\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 5667: (43-49): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/fixed_bytes_access_3.sol",
    "content": "contract C {\n\tbytes16[][] a;\n\tconstructor() {\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t\ta.push();\n\t\ta[2].push();\n\t\ta[2].push();\n\t\ta[2].push();\n\t\ta[3].push();\n\t\ta[3].push();\n\t\ta[3].push();\n\t\ta[3].push();\n\t\ta[3].push();\n\t}\n\tfunction g() internal view returns (bytes16[] storage) {\n\t\treturn a[2];\n\t}\n\tfunction h() internal view returns (bytes16) {\n\t\treturn a[2][2];\n\t}\n\tfunction f() external view {\n\t\t// Reports oob because of aliasing.\n\t\tg()[3][4];\n\t\th()[5];\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreOS: macos\n// ----\n// Warning 6368: (456-462): CHC: Out of bounds access happens here.\n// Info 1391: CHC: 13 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/fixed_bytes_access_4.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tbytes32 x = 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff;\n\t\tbytes1 z = 0x00;\n\t\tbytes1 o = 0xff;\n\t\tassert(x[0] == z);\n\t\tassert(x[31] == o);\n\t\tassert(x[0] == x[22]);\n\t\tassert(x[0] == x[23]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (231-252): CHC: Assertion violation happens here.\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/fixed_bytes_access_5.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tbytes4 x = 0x01020304;\n\t\tbytes1 b = 0x02;\n\t\tassert(x[0] == b); // fails\n\t\tassert(x[1] == b);\n\t\tassert(x[2] == b); // fails\n\t\tassert(x[3] == b); // fails\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (87-104): CHC: Assertion violation happens here.\n// Warning 6328: (138-155): CHC: Assertion violation happens here.\n// Warning 6328: (168-185): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/fixed_bytes_access_6.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tbytes4 x = 0x01020304;\n\t\tbytes1 b = x[3];\n\t\tassert(b == b[0]);\n\t\tassert(b == b[0][0]);\n\t\tassert(b == b[0][0][0][0][0][0][0][0][0][0][0]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 18 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/fixed_bytes_access_7.sol",
    "content": "contract C {\n\tfunction f(uint i) public pure {\n\t\tbytes4 x = 0x01020304;\n\t\trequire(i > 3);\n\t\tassert(x[i] == 0x00);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6368: (99-103): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\ni = 4\\nx = 0x01020304\\n\\nTransaction trace:\\nC.constructor()\\nC.f(4)\n// Warning 6328: (92-112): CHC: Assertion violation happens here.\\nCounterexample:\\n\\ni = 4\\nx = 0x01020304\\n\\nTransaction trace:\\nC.constructor()\\nC.f(4)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/fixed_bytes_range.sol",
    "content": "contract C {\n\n\tfunction f(bytes1 b) public pure {\n\t\tbytes1 c = hex\"7f\";\n\t\trequire(b > c);\n\t\tassert(uint8(b) > 127); // should hold\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/function_in_tuple_1.sol",
    "content": "contract K {\n\tfunction f() public pure {\n\t\t(abi.encode, 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (43-58): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/function_in_tuple_2.sol",
    "content": "contract K {\n\tfunction f() public pure {\n\t\t(abi.encode, \"\");\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (43-59): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/function_type_array_as_reference_type.sol",
    "content": "contract C {\n    struct Nested { uint y; }\n    // ensure that we consider array of function pointers as reference type\n    function b(function(Nested memory) external returns (uint)[] storage) internal pure {}\n    function c(function(Nested memory) external returns (uint)[] memory) public pure {}\n    function d(function(Nested memory) external returns (uint)[] calldata) external pure {}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/function_type_arrays.sol",
    "content": "contract C {\n    function(uint) external returns (uint)[] public x;\n    function(uint) internal returns (uint)[10] y;\n    function f() view public {\n        function(uint) returns (uint)[10] memory a;\n        function(uint) returns (uint)[10] storage b = y;\n        function(uint) external returns (uint)[] memory c;\n        c = new function(uint) external returns (uint)[](200);\n        assert(c.length == 200);\n        a; b;\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/function_type_as_argument.sol",
    "content": "contract C {\n    function f(function(uint) external g) public {\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/function_type_call.sol",
    "content": "contract C {\n\tfunction(uint) m_g;\n    function f(function(uint) internal g) internal {\n\t\tg(2);\n    }\n\tfunction h() public {\n\t\tf(m_g);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5729: (89-93): BMC does not yet implement this type of function call.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/function_type_external_address.sol",
    "content": "contract C {\n    function f(address a, function(uint) external g) internal pure {\n\t\taddress b = g.address;\n\t\tassert(a == b);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7650: (96-105): Assertion checker does not yet support this expression.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/function_type_members.sol",
    "content": "contract C {\n    function f(function(uint) external payable g) internal {\n\t\tg.selector;\n\t\tg{gas: 2, value: 3}(4);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7650: (76-86): Assertion checker does not yet support this expression.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/function_type_nested.sol",
    "content": "contract C {\n\tfunction(uint) m_g;\n    function f1(function(uint) internal g1) internal {\n\t\tg1(2);\n    }\n    function f2(function(function(uint) internal) internal g2) internal {\n\t\tg2(m_g);\n    }\n\tfunction h() public {\n\t\tf2(f1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8115: (120-165): Assertion checker does not yet support the type of this variable.\n// Warning 8364: (180-182): Assertion checker does not yet implement type function (function (uint256))\n// Warning 6031: (223-225): Internal error: Expression undefined for SMT solver.\n// Warning 8364: (223-225): Assertion checker does not yet implement type function (function (uint256))\n// Warning 5729: (91-96): BMC does not yet implement this type of function call.\n// Warning 5729: (180-187): BMC does not yet implement this type of function call.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/function_type_nested_return.sol",
    "content": "contract C {\n\tfunction(uint) m_g;\n\tfunction r() internal view returns (function(uint)) {\n\t\treturn m_g;\n\t}\n    function f1(function(uint) internal g1) internal {\n\t\tg1(2);\n    }\n    function f2(function(function(uint) internal) internal g2) internal {\n\t\tg2(r());\n    }\n\tfunction h() public {\n\t\tf2(f1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8115: (192-237): Assertion checker does not yet support the type of this variable.\n// Warning 8364: (252-254): Assertion checker does not yet implement type function (function (uint256))\n// Warning 1695: (255-256): Assertion checker does not yet support this global variable.\n// Warning 6031: (295-297): Internal error: Expression undefined for SMT solver.\n// Warning 8364: (295-297): Assertion checker does not yet implement type function (function (uint256))\n// Warning 5729: (163-168): BMC does not yet implement this type of function call.\n// Warning 5729: (252-259): BMC does not yet implement this type of function call.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_1.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) map;\n\tfunction f(uint x) public {\n\t\tmap[2] = x;\n\t\tassert(x == map[2]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_1_fail.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) map;\n\tfunction f(uint x) public {\n\t\tmap[2] = x;\n\t\tmap[2] = 3;\n\t\tassert(x != map[2]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (101-120): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 3\\n\\nTransaction trace:\\nC.constructor()\\nC.f(3)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_2.sol",
    "content": "contract C\n{\n\tmapping (uint => bool) map;\n\tfunction f(bool x) public view {\n\t\tassert(x != map[2]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (78-97): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = false\\n\\nTransaction trace:\\nC.constructor()\\nC.f(false)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_2d_1.sol",
    "content": "contract C\n{\n\tmapping (uint => mapping (uint => uint)) map;\n\tfunction f(uint x) public {\n\t\tx = 42;\n\t\tmap[13][14] = 42;\n\t\tassert(x == map[13][14]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_2d_1_fail.sol",
    "content": "contract C\n{\n\tmapping (uint => mapping (uint => uint)) map;\n\tfunction f(uint x) public {\n\t\tx = 41;\n\t\tmap[13][14] = 42;\n\t\tassert(x == map[13][14]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (121-145): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 41\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_3.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) map;\n\tfunction f() public {\n\t\tmap[1] = 111;\n\t\tuint x = map[2];\n\t\tmap[1] = 112;\n\t\tassert(map[2] == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_3d_1.sol",
    "content": "contract C\n{\n\tmapping (uint => mapping (uint => mapping (uint => uint))) map;\n\tfunction f(uint x) public {\n\t\tx = 42;\n\t\tmap[13][14][15] = 42;\n\t\tassert(x == map[13][14][15]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_3d_1_fail.sol",
    "content": "contract C\n{\n\tmapping (uint => mapping (uint => mapping (uint => uint))) map;\n\tfunction f(uint x) public {\n\t\tx = 41;\n\t\tmap[13][14][15] = 42;\n\t\tassert(x == map[13][14][15]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (143-171): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 41\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_4.sol",
    "content": "contract C\n{\n\tmapping (bool => bool) map;\n\tfunction f(bool x) public view {\n\t\trequire(x);\n\t\tassert(x != map[x]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTSolvers: z3\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_5.sol",
    "content": "contract C\n{\n\tmapping (address => uint) map;\n\tfunction f(address a, uint x) public view {\n\t\tassert(x != map[a]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (92-111): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = 0x0\\nx = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(0x0, 0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_6.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\n\n\n// Regression for handling signedness, see issues #14791 and #14792\ncontract C {\n    mapping(bool => int240) internal v1;\n    mapping(bytes14 => bytes15) internal v;\n\n    function f() public payable {\n        delete v[\"A\"];\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_aliasing_1.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) a;\n\tmapping (uint => uint) b;\n\n\tfunction f(uint x) public {\n\t\ta[1] = x;\n\t\tb[1] = x;\n\t\ta[1] = 2;\n\t\tmapping (uint => uint) storage c = a;\n\t\tassert(c[1] == 2);\n\t\t// False negative! Needs aliasing.\n\t\tassert(a[1] == b[1]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (233-253): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_aliasing_2.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) a;\n\tmapping (uint => mapping (uint => uint)) maps;\n\tmapping (uint => mapping (uint => uint8)) maps8;\n\tfunction f(mapping (uint => uint) storage map1, mapping (uint => uint) storage map2) internal {\n\t\tmap1[0] = 2;\n\t\ta[0] = 42;\n\t\tmaps[0][0] = 42;\n\t\tmaps8[0][0] = 42;\n\t\tmap2[0] = 1;\n\t\t// Fails because map2 == map1 is possible.\n\t\tassert(map1[0] == 2);\n\t\t// Fails because map2 == a is possible.\n\t\tassert(a[0] == 42);\n\t\t// Fails because map2 == maps[0] is possible.\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(maps[0][0] == 42);\n\t\t// Should not fail since knowledge is erased only for mapping (uint => uint).\n\t\tassert(maps8[0][0] == 42);\n\t\tassert(map2[0] == 1);\n\t}\n\n\tfunction g(bool b, uint x, uint y) public {\n\t\tif (b)\n\t\t\tf(a, maps[y]);\n\t\telse\n\t\t\tf(maps[x], maps[y]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (364-384): CHC: Assertion violation happens here.\n// Warning 6328: (430-448): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_and_array_of_functions.sol",
    "content": "contract test {\n    mapping (address => function() internal returns (uint)) a;\n    mapping (address => function() external) b;\n    mapping (address => function() external[]) c;\n    function() external[] d;\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_as_local_var_1.sol",
    "content": "contract c {\n\tmapping(uint => uint) x;\n\tmapping(uint => uint) y;\n\tfunction f(bool cond) public {\n\t\tmapping(uint => uint) storage a = cond ? x : y;\n\t\tx[2] = 1;\n\t\ty[2] = 2;\n\t\ta[2] = 3;\n\t\t// False positive since aliasing is not yet supported.\n\t\tif (cond)\n\t\t\tassert(a[2] == x[2] && a[2] != y[2]);\n\t\telse\n\t\t\tassert(a[2] == y[2] && a[2] != x[2]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (255-291): CHC: Assertion violation happens here.\n// Warning 6328: (303-339): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_as_parameter_1.sol",
    "content": "contract c {\n\tmapping(uint => uint) x;\n\tfunction f(mapping(uint => uint) storage map, uint index, uint value) internal {\n\t\tmap[index] = value;\n\t}\n\tfunction g(uint a, uint b) public {\n\t\tf(x, a, b);\n\t\t// False positive since aliasing is not yet supported.\n\t\tassert(x[a] == b);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (256-273): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_equal_keys_1.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) map;\n\tfunction f(uint x, uint y) public view {\n\t\trequire(x == y);\n\t\tassert(map[x] == map[y]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_equal_keys_2.sol",
    "content": "contract C\n{\n\tmapping (uint => uint) map;\n\tfunction f(uint x, uint y) public view {\n\t\tassert(x == y);\n\t\tassert(map[x] == map[y]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (86-100): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_integer_signedness_compatibility.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\n\n\n// Regression for handling signedness, see issue #14792\ncontract C {\n    mapping(int => int) v1;\n    mapping(int => uint) v2;\n    mapping(uint => int) v3;\n    mapping(uint => uint) v4;\n    mapping(bytes12 => int) v5;\n    uint[5] a1;\n    int[5] a2;\n\n    function f() public {\n        delete v1[0];\n        delete v2[0];\n        delete v3[0];\n        delete v4[0];\n        delete v5[0];\n        delete a1[0];\n        delete a2[0];\n    }\n}\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_struct_assignment.sol",
    "content": "contract C\n{\n\tstruct S {\n\t\tuint x;\n\t}\n\tmapping (uint => S) smap;\n\tfunction f(uint y, uint v) public {\n\t\tif (0==1)\n\t\t\tsmap[y] = S(v);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (108-112): BMC: Condition is always false.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/mapping_unsupported_key_type_1.sol",
    "content": "contract C\n{\n\tmapping (string => uint) map;\n\tfunction f(string memory s, uint x) public {\n\t\tmap[s] = x;\n\t\tassert(x == map[s]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/no_effect_statements.sol",
    "content": "contract test {\n    struct s { uint a; uint b;}\n    function f() pure public returns (bytes1) {\n\t\ts;\n\t\ts(1,2);\n\t\ts[7];\n\t\tuint;\n\t\tuint[7];\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (86-92): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6133: (98-99): Statement has no effect.\n// Warning 6133: (103-109): Statement has no effect.\n// Warning 6133: (113-117): Statement has no effect.\n// Warning 6133: (121-125): Statement has no effect.\n// Warning 6133: (129-136): Statement has no effect.\n// Warning 8364: (113-117): Assertion checker does not yet implement type type(struct test.s memory[7] memory)\n// Warning 8364: (129-136): Assertion checker does not yet implement type type(uint256[7] memory)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/rational_large_1.sol",
    "content": "contract c {\n\tfunction f() public pure returns (uint) {\n\t\tuint x = 8e130%9;\n\t\tassert(x == 8);\n\t\tassert(x != 8);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (48-52): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6328: (96-110): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/static_array_implicit_push_1.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction f(uint[1] memory x) public {\n\t\ta.push(x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/static_array_implicit_push_2.sol",
    "content": "contract C {\n\tuint[][] a;\n\tfunction f(uint[1][] memory x) public {\n\t\trequire(x.length > 2);\n\t\ta.push(x[2]);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/static_array_implicit_push_3.sol",
    "content": "contract D {\n\tbytes16[] inner;\n\tbytes32[][] data;\n\tfunction t() public {\n\t\tdata.push(inner);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/static_array_implicit_push_4.sol",
    "content": "contract D {\n\tint16[] inner;\n\tint[][] data;\n\tfunction t() public {\n\t\tdata.push(inner);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/static_array_length_1.sol",
    "content": "contract C {\n\tfunction f(address[2] memory a) public pure {\n\t\tassert(a.length == 2); // should hold\n\t\tassert(a.length < 2); // should fail\n\t\tassert(a.length > 2); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (102-122): CHC: Assertion violation happens here.\n// Warning 6328: (141-161): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/static_array_length_2.sol",
    "content": "contract C {\n\tfunction f() public pure returns (address[2] memory a) {\n\t\tassert(a.length == 2); // should hold\n\t\tassert(a.length < 2); // should fail\n\t\tassert(a.length > 2); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (113-133): CHC: Assertion violation happens here.\n// Warning 6328: (152-172): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/static_array_length_3.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\taddress[2] memory a;\n\t\tassert(a.length == 2); // should hold\n\t\tassert(a.length < 2); // should fail\n\t\tassert(a.length > 2); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (106-126): CHC: Assertion violation happens here.\n// Warning 6328: (145-165): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/static_array_length_4.sol",
    "content": "contract C {\n\tuint[2] a;\n\tuint x = f();\n\tconstructor() {\n\t\tassert(a.length == 2); // should hold\n\t\tassert(x == 2); // should hold\n\t\tassert(a.length < 2); // should fail\n\t\tassert(a.length > 2); // should fail\n\t}\n\tfunction f() internal view returns (uint) {\n\t\tassert(a.length == 2); // should hold\n\t\tassert(a.length < 2); // should fail\n\t\tassert(a.length > 2); // should fail\n\t\treturn a.length;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (132-152): CHC: Assertion violation happens here.\n// Warning 6328: (171-191): CHC: Assertion violation happens here.\n// Warning 6328: (298-318): CHC: Assertion violation happens here.\n// Warning 6328: (337-357): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/static_array_length_5.sol",
    "content": "contract C {\n\tuint[2] a;\n\tfunction f() public view {\n\t\tassert(a.length == 2); // should hold\n\t\tassert(a.length < 2); // should fail\n\t\tassert(a.length > 2); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (95-115): CHC: Assertion violation happens here.\n// Warning 6328: (134-154): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/storage_value_vars_1.sol",
    "content": "contract C\n{\n    address a;\n    bool b;\n    uint c;\n    function f(uint x) public {\n        if (x == 0)\n        {\n            a = 0x0000000000000000000000000000000000000100;\n            b = true;\n        }\n        else\n        {\n            a = 0x0000000000000000000000000000000000000200;\n            b = false;\n        }\n        assert(a > 0x0000000000000000000000000000000000000000 && b);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (330-389): CHC: Assertion violation happens here.\\nCounterexample:\\na = 0x0200, b = false, c = 0\\nx = 1\\n\\nTransaction trace:\\nC.constructor()\\nState: a = 0x0, b = false, c = 0\\nC.f(1)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/storage_value_vars_2.sol",
    "content": "contract C\n{\n    address a;\n    bool b;\n    uint c;\n    function f() public view {\n        assert(c > 0);\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (91-104): CHC: Assertion violation happens here.\\nCounterexample:\\na = 0x0, b = false, c = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: a = 0x0, b = false, c = 0\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/storage_value_vars_3.sol",
    "content": "contract C\n{\n    function f(uint x) public {\n        if (x == 0)\n        {\n            a = 0x0000000000000000000000000000000000000100;\n            b = true;\n        }\n        else\n        {\n            a = 0x0000000000000000000000000000000000000200;\n            b = false;\n        }\n        assert(b == (a < 0x0000000000000000000000000000000000000200));\n    }\n\n    function g() public view {\n        require(a < 0x0000000000000000000000000000000000000100);\n        assert(c >= 0);\n    }\n    address a;\n    bool b;\n    uint c;\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/storage_value_vars_4.sol",
    "content": "contract C\n{\n    function f() public view {\n        assert(c > 0);\n    }\n    uint c;\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (52-65): CHC: Assertion violation happens here.\\nCounterexample:\\nc = 0\\n\\nTransaction trace:\\nC.constructor()\\nState: c = 0\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/string_1.sol",
    "content": "contract C\n{\n\tfunction f(string memory s1, string memory s2) public pure {\n\t\tassert(bytes(s1).length == bytes(s2).length);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (77-121): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f(s1, s2) -- counterexample incomplete; parameter name used instead of value\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/string_2.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tstring memory s = \"Hello World\";\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2072: (43-58): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/string_length.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tstring memory x = \"Hello World\";\n\t\tassert(bytes(x).length == 11);\n\t}\n\tfunction g() public pure {\n\t\tstring memory x = unicode\"Hello World\";\n\t\tassert(bytes(x).length == 11);\n\t}\n\tfunction h() public pure {\n\t\tbytes memory x = unicode\"Hello World\";\n\t\tstring memory y = string(x);\n\t\tassert(bytes(y).length == 11);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/string_literal_assignment_1.sol",
    "content": "contract C {\n\tfunction f(bytes32 _x) public pure {\n\t\trequire(_x == \"test\");\n\t\tbytes32 y = \"test\";\n\t\tbytes16 z = \"testz\";\n\t\tassert(_x == y);\n\t\tassert(_x == z);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (142-157): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/string_literal_assignment_2.sol",
    "content": "contract C {\n\tfunction f(bytes32 _x) public pure {\n\t\trequire(_x == \"test\");\n\t\t(bytes32 y, bytes16 z) = (\"test\", \"testz\");\n\t\tassert(_x == y);\n\t\tassert(_x == z);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (143-158): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/string_literal_assignment_3.sol",
    "content": "contract C {\n\tfunction f(bytes32 _x) public pure {\n\t\trequire(_x == \"test\");\n\t\tbytes32 y;\n\t\tbytes16 z;\n\t\t(y, z) = (\"test\", \"testz\");\n\t\tassert(_x == y);\n\t\tassert(_x == z);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (153-168): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/string_literal_assignment_4.sol",
    "content": "contract C {\n\tfunction g() internal pure returns (bytes32, bytes16) {\n\t\treturn (\"test\", \"testz\");\n\t}\n\n\tfunction f(bytes32 _x) public pure {\n\t\trequire(_x == \"test\");\n\t\tbytes32 y;\n\t\tbytes16 z;\n\t\t(y, z) = g();\n\t\tassert(_x == y);\n\t\tassert(_x == z);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (228-243): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/string_literal_assignment_5.sol",
    "content": "contract C {\n\tfunction g() internal pure returns (bytes32, bytes16) {\n\t\treturn (\"test\", \"testz\");\n\t}\n\n\tfunction f(bytes32 _x) public pure {\n\t\trequire(_x == \"test\");\n\t\t(bytes32 y, bytes16 z) = g();\n\t\tassert(_x == y);\n\t\tassert(_x == z);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (218-233): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/string_literal_comparison_1.sol",
    "content": "contract C {\n\tfunction f(bytes32 _x) public pure {\n\t\trequire(_x == \"test\");\n\t\tbytes32 y = _x;\n\t\tbytes32 z = _x;\n\t\tassert(z == \"test\");\n\t\tassert(y == \"testx\");\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (137-157): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/string_literal_comparison_2.sol",
    "content": "contract C {\n\tfunction f(bytes32 _x) public pure {\n\t\trequire(_x != \"test\");\n\t\tbytes32 y = _x;\n\t\tbytes32 z = _x;\n\t\tassert(z == \"test\");\n\t\tassert(y != \"testx\");\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (114-133): CHC: Assertion violation happens here.\n// Warning 6328: (137-157): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/array_struct_array_struct_memory_safe.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct T {\n\t\tuint y;\n\t\tuint[] a;\n\t}\n\tstruct S {\n\t\tuint x;\n\t\tT t;\n\t\tuint[] a;\n\t\tT[] ts;\n\t}\n\tfunction f() public pure {\n\t\tS[] memory s1 = new S[](3);\n\t\tassert(s1.length == 3);\n\t\ts1[0].x = 2;\n\t\tassert(s1[0].x == 2);\n\t\ts1[1].t.y = 3;\n\t\tassert(s1[1].t.y == 3);\n\t\ts1[2].a = new uint[](3);\n\t\ts1[2].a[2] = 4;\n\t\tassert(s1[2].a[2] == 4);\n\t\ts1[0].ts = new T[](6);\n\t\ts1[0].ts[3].y = 5;\n\t\tassert(s1[0].ts[3].y == 5);\n\t\ts1[1].ts = new T[](6);\n\t\ts1[1].ts[4].a = new uint[](6);\n\t\ts1[1].ts[4].a[5] = 6;\n\t\tassert(s1[1].ts[4].a[5] == 6);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTTargets: assert\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/array_struct_array_struct_memory_unsafe.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct T {\n\t\tuint y;\n\t\tuint[] a;\n\t}\n\tstruct S {\n\t\tuint x;\n\t\tT t;\n\t\tuint[] a;\n\t\tT[] ts;\n\t}\n\tfunction f(S memory s2) public pure {\n\t\tS[] memory s1 = new S[](3);\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(s1.length == 3);\n\t\ts1[0].x = 2;\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(s1[0].x == s2.x);\n\t\ts1[1].t.y = 3;\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(s1[1].t.y == s2.t.y);\n\t\ts1[2].a = new uint[](3);\n\t\ts1[2].a[2] = 4;\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(s1[2].a[2] == s2.a[2]);\n\t\ts1[0].ts = new T[](4);\n\t\ts1[0].ts[3].y = 5;\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(s1[0].ts[3].y == s2.ts[3].y);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (151-162): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Info 1391: CHC: 8 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/array_struct_array_struct_storage_safe.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct T {\n\t\tuint y;\n\t\tuint[] a;\n\t}\n\tstruct S {\n\t\tuint x;\n\t\tT t;\n\t\tuint[] a;\n\t\tT[] ts;\n\t}\n\tS[] s1;\n\tfunction f() public {\n\t\ts1.push();\n\t\ts1.push();\n\t\ts1.push();\n\t\ts1[0].x = 2;\n\t\tassert(s1[0].x == 2);\n\t\ts1[1].t.y = 3;\n\t\tassert(s1[1].t.y == 3);\n\t\ts1[2].a.push();\n\t\ts1[2].a.push();\n\t\ts1[2].a.push();\n\t\ts1[2].a[2] = 4;\n\t\tassert(s1[2].a[2] == 4);\n\t\ts1[0].ts.push();\n\t\ts1[0].ts.push();\n\t\ts1[0].ts.push();\n\t\ts1[0].ts.push();\n\t\ts1[0].ts.push();\n\t\ts1[0].ts[3].y = 5;\n\t\tassert(s1[0].ts[3].y == 5);\n\t\ts1[1].ts.push();\n\t\ts1[1].ts.push();\n\t\ts1[1].ts.push();\n\t\ts1[1].ts.push();\n\t\ts1[1].ts.push();\n\t\ts1[1].ts[4].a.push();\n\t\ts1[1].ts[4].a.push();\n\t\ts1[1].ts[4].a.push();\n\t\ts1[1].ts[4].a.push();\n\t\ts1[1].ts[4].a.push();\n\t\ts1[1].ts[4].a.push();\n\t\ts1[1].ts[4].a[5] = 6;\n\t\tassert(s1[1].ts[4].a[5] == 6);\n\t\ts1.pop();\n\t\ts1.pop();\n\t\ts1.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTTargets: assert\n// ----\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_memory.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct S {\n\t\tuint x;\n\t\tuint[] a;\n\t}\n\tfunction f(S memory s1, S memory s2, bool b) public pure {\n\t\tS memory s3 = b ? s1 : s2;\n\t\tassert(s3.x == s1.x);\n\t\tassert(s3.x == s2.x);\n\t\t// This is safe.\n\t\tassert(s3.x == s1.x || s3.x == s2.x);\n\t\t// This fails as false positive because of lack of support to aliasing.\n\t\ts3.x = 42;\n\t\tassert(s3.x == s1.x || s3.x == s2.x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (176-196): CHC: Assertion violation happens here.\n// Warning 6328: (200-220): CHC: Assertion violation happens here.\n// Warning 6328: (370-406): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_1.sol",
    "content": "contract C {\n    struct S {\n\t\tuint sum;\n\t\tuint[] a;\n    }\n\n\tfunction f(S memory m, uint v) internal pure {\n\t\tm.sum = v;\n\t\tm.a = new uint[](2);\n\t}\n\n\tconstructor(uint amt) {\n\t\tS memory s;\n\t\tf(s, amt);\n\t\tassert(s.a.length == 2); // should hold but no aliasing support means it fails for now\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (201-224): CHC: Assertion violation happens here.\\nCounterexample:\\n\\namt = 0\\ns = {sum: 0, a: []}\\n\\nTransaction trace:\\nC.constructor(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_2.sol",
    "content": "contract C {\n    struct S {\n\t\tuint sum;\n\t\tuint[] a;\n    }\n\n\tstruct T {\n\t\tS s;\n\t\tuint x;\n\t}\n\n\tfunction f(S memory m, uint v) internal pure {\n\t\tm.sum = v;\n\t\tm.a = new uint[](2);\n\t}\n\n\tconstructor(uint amt) {\n\t\tT memory t;\n\t\tf(t.s, amt);\n\t\tassert(t.s.a.length == 2); // should hold but no aliasing support means it fails for now\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (236-261): CHC: Assertion violation happens here.\\nCounterexample:\\n\\namt = 0\\nt = {s: {sum: 0, a: []}, x: 0}\\n\\nTransaction trace:\\nC.constructor(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_memory_3.sol",
    "content": "contract C {\n    struct S {\n\t\tuint sum;\n\t\tuint[] a;\n    }\n\n\tstruct T {\n\t\tS s;\n\t\tuint x;\n\t}\n\n\tfunction f(T memory m, uint v) internal pure {\n\t\tm.s.sum = v;\n\t\tm.s.a = new uint[](2);\n\t}\n\n\tconstructor(uint amt) {\n\t\tT memory t;\n\t\tf(t, amt);\n\t\tassert(t.s.a.length == 2); // should hold but no aliasing support means it fails for now\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (238-263): CHC: Assertion violation happens here.\\nCounterexample:\\n\\namt = 0\\nt = {s: {sum: 0, a: []}, x: 0}\\n\\nTransaction trace:\\nC.constructor(0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_1.sol",
    "content": "contract C {\n    struct S {\n        mapping(address => uint) innerM;\n\t\tuint sum;\n    }\n\n\tfunction f(S storage m, address i, uint v) internal {\n\t\tm.innerM[i] = v;\n\t\tm.sum += v;\n\t}\n\n\tS s;\n\n\tconstructor(uint amt) {\n\t\tf(s, msg.sender, amt);\n\t}\n\tfunction g() public view {\n\t\tassert(s.sum == 0); // should hold but no aliasing support means it fails for now\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (270-288): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_2.sol",
    "content": "contract C {\n    struct S {\n        mapping(address => uint) innerM;\n\t\tuint sum;\n    }\n\n\tfunction f(mapping(address => uint) storage innerM, address i, uint v) internal {\n\t\tinnerM[i] = v;\n\t}\n\n\tS s;\n\n\tconstructor(uint amt) {\n\t\tf(s.innerM, msg.sender, amt);\n\t}\n\tfunction g() public view {\n\t\tassert(s.innerM[msg.sender] == 0); // should hold but no aliasing support means it fails for now\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (289-322): CHC: Assertion violation happens here.\\nCounterexample:\\ns = {innerM, sum: 11}\\n\\nTransaction trace:\\nC.constructor(0){ msg.sender: 0x6dc4 }\\nState: s = {innerM, sum: 11}\\nC.g(){ msg.sender: 0x0985 }\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_3.sol",
    "content": "contract C {\n    struct S {\n        mapping(address => uint) innerM;\n\t\tuint sum;\n    }\n\n\tstruct T {\n\t\tuint x;\n\t\tS s;\n\t}\n\n\tfunction f(T storage m, address i, uint v) internal {\n\t\tm.s.innerM[i] = v;\n\t\tm.s.sum += v;\n\t}\n\n\tT t;\n\n\tconstructor(uint amt) {\n\t\tf(t, msg.sender, amt);\n\t}\n\tfunction g() public view {\n\t\tassert(t.s.sum == 0); // should hold but no aliasing support means it fails for now\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (307-327): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_parameter_storage_4.sol",
    "content": "contract C {\n    struct S {\n        mapping(address => uint) innerM;\n\t\tuint sum;\n    }\n\n\tstruct T {\n\t\tuint x;\n\t\tS s;\n\t}\n\n\tfunction f(S storage m, address i, uint v) internal {\n\t\tm.innerM[i] = v;\n\t\tm.sum += v;\n\t}\n\n\tT t;\n\n\tconstructor(uint amt) {\n\t\tf(t.s, msg.sender, amt);\n\t}\n\tfunction g() public view {\n\t\tassert(t.s.sum == 0); // should hold but no aliasing support means it fails for now\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (305-325): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_aliasing_storage.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tuint[] a;\n\t}\n\tS s1;\n\tS s2;\n\tfunction f(bool b) public {\n\t\tS storage s3 = b ? s1 : s2;\n\t\t// Disabled because Spacer 4.8.9 seg fauts.\n\t\t//assert(s3.x == s1.x);\n\t\t//assert(s3.x == s2.x);\n\t\t// This is safe.\n\t\tassert(s3.x == s1.x || s3.x == s2.x);\n\t\t// This fails as false positive because of lack of support to aliasing.\n\t\ts3.x = 42;\n\t\tassert(s3.x == s1.x || s3.x == s2.x);\n\t}\n\tfunction g(bool b, uint _x) public {\n\t\tif (b)\n\t\t\ts1.x = _x;\n\t\telse\n\t\t\ts2.x = _x;\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (369-405): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_array_struct_array_memory_safe.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct T {\n\t\tuint y;\n\t\tuint[] a;\n\t}\n\tstruct S {\n\t\tuint x;\n\t\tT t;\n\t\tuint[] a;\n\t\tT[] ts;\n\t}\n\tfunction f() public pure {\n\t\tS memory s1;\n\t\ts1.x = 2;\n\t\tassert(s1.x == 2);\n\t\ts1.t.y = 3;\n\t\tassert(s1.t.y == 3);\n\t\ts1.a = new uint[](3);\n\t\ts1.a[2] = 4;\n\t\tassert(s1.a[2] == 4);\n\t\ts1.ts = new T[](6);\n\t\ts1.ts[3].y = 5;\n\t\tassert(s1.ts[3].y == 5);\n\t\ts1.ts[4].a = new uint[](6);\n\t\ts1.ts[4].a[5] = 6;\n\t\tassert(s1.ts[4].a[5] == 6);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 14 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_array_struct_array_memory_unsafe_1.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct T {\n\t\tuint y;\n\t\tuint[] a;\n\t}\n\tstruct S {\n\t\tuint x;\n\t\tT t;\n\t\tuint[] a;\n\t\tT[] ts;\n\t}\n\tfunction f() public pure {\n\t\tS memory s1;\n\t\ts1.x = 2;\n\t\tassert(s1.x != 2);\n\t\ts1.t.y = 3;\n\t\tassert(s1.t.y != 3);\n\t\ts1.a = new uint[](3);\n\t\ts1.a[2] = 4;\n\t\tassert(s1.a[2] != 4);\n\t\ts1.ts = new T[](6);\n\t\ts1.ts[3].y = 5;\n\t\tassert(s1.ts[3].y != 5);\n\t\ts1.ts[4].a = new uint[](6);\n\t\ts1.ts[4].a[5] = 6;\n\t\tassert(s1.ts[4].a[5] != 6);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (196-213): CHC: Assertion violation happens here.\n// Warning 6328: (231-250): CHC: Assertion violation happens here.\n// Warning 6328: (293-313): CHC: Assertion violation happens here.\n// Warning 6328: (357-380): CHC: Assertion violation happens here.\n// Warning 6328: (435-461): CHC: Assertion violation happens here.\n// Info 1391: CHC: 9 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_array_struct_array_memory_unsafe_2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct T {\n\t\tuint y;\n\t\tuint[] a;\n\t}\n\tstruct S {\n\t\tuint x;\n\t\tT t;\n\t\tuint[] a;\n\t\tT[] ts;\n\t}\n\tfunction f(S memory s2) public pure {\n\t\tS memory s1;\n\t\ts1.x = 2;\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(s1.x == s2.x);\n\t\ts1.t.y = 3;\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(s1.t.y == s2.t.y);\n\t\ts1.a = new uint[](3);\n\t\ts1.a[2] = 4;\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(s1.a[2] == s2.a[2]);\n\t\ts1.ts = new T[](6);\n\t\ts1.ts[3].y = 5;\n\t\t// Removed because current Spacer seg faults in cex generation.\n\t\t//assert(s1.ts[3].y == s2.ts[3].y);\n\t\ts1.ts[4].a = new uint[](6);\n\t\ts1.ts[4].a[5] = 6;\n\t\trequire(s2.ts.length > 4);\n\t\trequire(s2.ts[4].a.length > 6);\n\t\tassert(s1.ts[4].a[5] == s2.ts[4].a[5]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (804-842): CHC: Assertion violation happens here.\n// Info 1391: CHC: 10 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_array_struct_array_storage_safe.sol",
    "content": "contract C {\n\tstruct T {\n\t\tuint y;\n\t\tuint[] a;\n\t}\n\tstruct S {\n\t\tuint x;\n\t\tT t;\n\t\tuint[] a;\n\t\tT[] ts;\n\t}\n\tS s1;\n\tfunction f() public {\n\t\ts1.x = 2;\n\t\tassert(s1.x == 2);\n\t\ts1.t.y = 3;\n\t\tassert(s1.t.y == 3);\n\t\ts1.a.push();\n\t\ts1.a.push();\n\t\ts1.a.push();\n\t\ts1.a[2] = 4;\n\t\tassert(s1.a[2] == 4);\n\t\ts1.ts.push();\n\t\ts1.ts.push();\n\t\ts1.ts.push();\n\t\ts1.ts.push();\n\t\ts1.ts.push();\n\t\ts1.ts[3].y = 5;\n\t\tassert(s1.ts[3].y == 5);\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a[5] = 6;\n\t\tassert(s1.ts[4].a[5] == 6);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 19 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_array_struct_array_storage_unsafe_1.sol",
    "content": "contract C {\n\tstruct T {\n\t\tuint y;\n\t\tuint[] a;\n\t}\n\tstruct S {\n\t\tuint x;\n\t\tT t;\n\t\tuint[] a;\n\t\tT[] ts;\n\t}\n\tS s1;\n\tfunction f() public {\n\t\ts1.x = 2;\n\t\tassert(s1.x != 2);\n\t\ts1.t.y = 3;\n\t\tassert(s1.t.y != 3);\n\t\ts1.a.push();\n\t\ts1.a.push();\n\t\ts1.a.push();\n\t\ts1.a[2] = 4;\n\t\tassert(s1.a[2] != 4);\n\t\ts1.ts.push();\n\t\ts1.ts.push();\n\t\ts1.ts.push();\n\t\ts1.ts.push();\n\t\ts1.ts.push();\n\t\ts1.ts.push();\n\t\ts1.ts[3].y = 5;\n\t\tassert(s1.ts[3].y != 5);\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a.push();\n\t\ts1.ts[4].a[5] = 6;\n\t\tassert(s1.ts[4].a[5] != 6);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (148-165): CHC: Assertion violation happens here.\n// Warning 6328: (183-202): CHC: Assertion violation happens here.\n// Warning 6328: (266-286): CHC: Assertion violation happens here.\n// Warning 6328: (404-427): CHC: Assertion violation happens here.\n// Warning 6328: (578-604): CHC: Assertion violation happens here.\n// Info 1391: CHC: 14 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_constructor_fixed_bytes_from_string_1.sol",
    "content": "contract C {\n  struct S {\n    int a;\n    bytes5 b;\n  }\n  function f() public pure {\n    assert(S({a:2, b:\"\"}).b == bytes5(0)); // should hold\n    assert(S({a:2, b:\"\"}).a == 0); // should fail\n  }\n}\n// ----\n// Warning 6328: (146-175): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_constructor_named_args.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tstruct T {\n\t\tS s;\n\t\tuint y;\n\t}\n\n\tfunction test() pure public {\n\t\tS memory inner = S({x: 43});\n\t\tT memory outer = T({y: 512, s: inner});\n\t\tassert(outer.y == 512);\n\t\tassert(outer.s.x == 43);\n\t\tassert(outer.s.x == 42);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (232-255): CHC: Assertion violation happens here.\\nCounterexample:\\n\\ninner = {x: 43}\\nouter = {s: {x: 43}, y: 512}\\n\\nTransaction trace:\\nC.constructor()\\nC.test()\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_constructor_named_args_2.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t\tuint y;\n\t\tuint z;\n\t}\n\n\tfunction test() pure public {\n\t\tS memory s = S({z: 1, y: 2, x: 3});\n\t\tassert(s.x == 3);\n\t\tassert(s.y == 2);\n\t\tassert(s.z == 1);\n\t\tassert(s.x == 0 || s.y == 0 || s.z == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (191-231): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_constructor_recursive_1.sol",
    "content": "contract Test {\n\tstruct RecursiveStruct {\n\t\tRecursiveStruct[] vals;\n\t}\n\tfunction func() public pure {\n\t\tRecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2072: (104-133): Unused local variable.\n// Warning 8364: (138-180): Assertion checker does not yet implement type struct Test.RecursiveStruct memory\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_constructor_recursive_2.sol",
    "content": "contract Test {\n\tstruct RecursiveStruct {\n\t\tuint x;\n\t\tRecursiveStruct[] vals;\n\t}\n\tfunction func() public pure {\n\t\tRecursiveStruct memory val = RecursiveStruct(1, new RecursiveStruct[](42));\n\t\tassert(val.x == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8115: (114-140): Assertion checker does not yet support the type of this variable.\n// Warning 8364: (143-188): Assertion checker does not yet implement type struct Test.RecursiveStruct memory\n// Warning 7650: (199-204): Assertion checker does not yet support this expression.\n// Warning 8364: (199-202): Assertion checker does not yet implement type struct Test.RecursiveStruct memory\n// Warning 6328: (192-210): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nTest.constructor()\\nTest.func()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_delete_memory.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct S {\n\t\tuint x;\n\t\tuint[] a;\n\t}\n\tfunction f(S memory s1, S memory s2) public pure {\n\t\tdelete s1;\n\t\tassert(s1.x == s2.x);\n\t\tassert(s1.a.length == s2.a.length);\n\t\tassert(s1.a.length == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (152-172): CHC: Assertion violation happens here.\n// Warning 6328: (176-210): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_delete_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct S {\n\t\tuint x;\n\t\tuint[] a;\n\t}\n\tS s1;\n\tfunction g(S memory s2) public {\n\t\ts1.x = s2.x;\n\t\ts1.a = s2.a;\n\t}\n\tfunction f(S memory s2) public {\n\t\tdelete s1;\n\t\tassert(s1.x == s2.x);\n\t\tassert(s1.a.length == s2.a.length);\n\t\tassert(s1.a.length == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (208-228): CHC: Assertion violation happens here.\n// Warning 6328: (232-266): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_external_function_pointer.sol",
    "content": "struct S {\n    function() external returns (uint) x;\n}\ncontract C {\n\n    function X() public pure returns (uint) {\n        return 1;\n    }\n\n    uint y;\n    uint z;\n\n    function setZ(uint _z) public {\n        z = _z;\n    }\n\n\n    function f() public returns (uint) {\n        S memory s;\n        s.x = this.X;\n        require(y == 0);\n        require(z == 0);\n        uint ret = s.x();\n        assert(y == 0); // should hold\n        assert(z == 0); // can report violation due to overapproximation after externall call s.x()\n        return ret;\n    }\n}\n\n\n// ----\n// Warning 6328: (431-445): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_mapping.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tmapping (uint => uint) m;\n\t}\n\tS s1;\n\tS s2;\n\tfunction f() public view {\n\t\t// Disabled because Spacer 4.8.9 seg faults.\n\t\t//assert(s1.m[0] == s2.m[0]);\n\t}\n\tfunction g(uint a, uint b) public {\n\t\ts1.m[a] = b;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_nested_constructor.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tstruct T {\n\t\tS s;\n\t\tuint y;\n\t}\n\n\tfunction test() pure public {\n\t\tS memory inner = S(43);\n\t\tT memory outer = T(inner, 512);\n\t\tassert(outer.y == 512);\n\t\tassert(outer.s.x == 43);\n\t\tassert(outer.s.x == 42);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (219-242): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_nested_constructor_named_args.sol",
    "content": "contract C {\n\tstruct B { uint b1; }\n\tstruct A { uint a1; B a2; }\n\tfunction f() public pure {\n\t\tA memory a = A({ a1: 1, a2: B({b1: 2}) });\n\t\tassert(a.a1 == 1 && a.a2.b1 == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_nested_temporary.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tstruct T {\n\t\tS s;\n\t\tuint y;\n\t}\n\n\tfunction test() pure public {\n\t\tassert(T(S(42), 1).s.x == 42);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_recursive_1.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tS[] a;\n\t}\n\tS s1;\n\tS s2;\n\tfunction f() public view {\n\t\tassert(s1.x == s2.x);\n\t\tassert(s1.a.length == s2.a.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8115: (48-52): Assertion checker does not yet support the type of this variable.\n// Warning 8115: (55-59): Assertion checker does not yet support the type of this variable.\n// Warning 7650: (98-102): Assertion checker does not yet support this expression.\n// Warning 8364: (98-100): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (106-110): Assertion checker does not yet support this expression.\n// Warning 8364: (106-108): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (122-126): Assertion checker does not yet support this expression.\n// Warning 8364: (122-124): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (137-141): Assertion checker does not yet support this expression.\n// Warning 8364: (137-139): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 6328: (91-111): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (115-149): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_recursive_2.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tS[] a;\n\t}\n\tS s1;\n\tS s2;\n\tfunction f() public view {\n\t\tassert(s1.x == s2.x);\n\t\tassert(s1.a.length == s2.a.length);\n\t\tassert(s1.a[0].x == s2.a[0].x);\n\t}\n\tfunction g() public {\n\t\ts1.x = 42;\n\t\ts2.x = 42;\n\t\ts1.a.push();\n\t\ts2.a.push();\n\t\ts1.a[0].x = 43;\n\t\ts2.a[0].x = 43;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8115: (48-52): Assertion checker does not yet support the type of this variable.\n// Warning 8115: (55-59): Assertion checker does not yet support the type of this variable.\n// Warning 7650: (98-102): Assertion checker does not yet support this expression.\n// Warning 8364: (98-100): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (106-110): Assertion checker does not yet support this expression.\n// Warning 8364: (106-108): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (122-126): Assertion checker does not yet support this expression.\n// Warning 8364: (122-124): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (137-141): Assertion checker does not yet support this expression.\n// Warning 8364: (137-139): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (160-169): Assertion checker does not yet support this expression.\n// Warning 7650: (160-164): Assertion checker does not yet support this expression.\n// Warning 8364: (160-162): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (160-167): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (173-182): Assertion checker does not yet support this expression.\n// Warning 7650: (173-177): Assertion checker does not yet support this expression.\n// Warning 8364: (173-175): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (173-180): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (213-217): Assertion checker does not yet support this expression.\n// Warning 8364: (213-215): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (213-217): Assertion checker does not support recursive structs.\n// Warning 7650: (226-230): Assertion checker does not yet support this expression.\n// Warning 8364: (226-228): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (226-230): Assertion checker does not support recursive structs.\n// Warning 7650: (239-243): Assertion checker does not yet support this expression.\n// Warning 8364: (239-241): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (239-250): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (239-243): Assertion checker does not support recursive structs.\n// Warning 7650: (254-258): Assertion checker does not yet support this expression.\n// Warning 8364: (254-256): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (254-265): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (254-258): Assertion checker does not support recursive structs.\n// Warning 7650: (269-278): Assertion checker does not yet support this expression.\n// Warning 7650: (269-273): Assertion checker does not yet support this expression.\n// Warning 8364: (269-271): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (269-276): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (269-278): Assertion checker does not support recursive structs.\n// Warning 7650: (287-296): Assertion checker does not yet support this expression.\n// Warning 7650: (287-291): Assertion checker does not yet support this expression.\n// Warning 8364: (287-289): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (287-294): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (287-296): Assertion checker does not support recursive structs.\n// Warning 6328: (91-111): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (115-149): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (160-167): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (173-180): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (153-183): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (269-276): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\n// Warning 6368: (287-294): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_recursive_3.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tS[] a;\n\t}\n\tS s1;\n\tS s2;\n\tfunction f() public view {\n\t\tassert(s1.x == s2.x);\n\t\tassert(s1.a.length == s2.a.length);\n\t\trequire(s1.a.length > 0);\n\t\trequire(s2.a.length > 0);\n\t\tassert(s1.a[0].x == s2.a[0].x);\n\t\trequire(s1.a[0].a.length > 0);\n\t\trequire(s2.a[0].a.length > 0);\n\t\tassert(s1.a[0].a.length == s2.a[0].a.length);\n\t\t// Disabled because of Spacer killed.\n\t\t//require(s1.a[0].a[0].a.length > 0);\n\t\t//require(s2.a[0].a[0].a.length > 0);\n\t\t//assert(s1.a[0].a[0].x == s2.a[0].a[0].x);\n\t}\n\tfunction g() public {\n\t\ts1.x = 42;\n\t\ts2.x = 42;\n\t\ts1.a.push();\n\t\ts2.a.push();\n\t\ts1.a[0].x = 43;\n\t\ts2.a[0].x = 43;\n\t\ts1.a[0].a.push();\n\t\ts2.a[0].a.push();\n\t\ts1.a[0].a[0].x = 44;\n\t\ts2.a[0].a[0].x = 44;\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8115: (48-52): Assertion checker does not yet support the type of this variable.\n// Warning 8115: (55-59): Assertion checker does not yet support the type of this variable.\n// Warning 7650: (98-102): Assertion checker does not yet support this expression.\n// Warning 8364: (98-100): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (106-110): Assertion checker does not yet support this expression.\n// Warning 8364: (106-108): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (122-126): Assertion checker does not yet support this expression.\n// Warning 8364: (122-124): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (137-141): Assertion checker does not yet support this expression.\n// Warning 8364: (137-139): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (161-165): Assertion checker does not yet support this expression.\n// Warning 8364: (161-163): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (189-193): Assertion checker does not yet support this expression.\n// Warning 8364: (189-191): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (216-225): Assertion checker does not yet support this expression.\n// Warning 7650: (216-220): Assertion checker does not yet support this expression.\n// Warning 8364: (216-218): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (216-223): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (229-238): Assertion checker does not yet support this expression.\n// Warning 7650: (229-233): Assertion checker does not yet support this expression.\n// Warning 8364: (229-231): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (229-236): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (251-260): Assertion checker does not yet support this expression.\n// Warning 7650: (251-255): Assertion checker does not yet support this expression.\n// Warning 8364: (251-253): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (251-258): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (284-293): Assertion checker does not yet support this expression.\n// Warning 7650: (284-288): Assertion checker does not yet support this expression.\n// Warning 8364: (284-286): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (284-291): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (316-325): Assertion checker does not yet support this expression.\n// Warning 7650: (316-320): Assertion checker does not yet support this expression.\n// Warning 8364: (316-318): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (316-323): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (336-345): Assertion checker does not yet support this expression.\n// Warning 7650: (336-340): Assertion checker does not yet support this expression.\n// Warning 8364: (336-338): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (336-343): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (549-553): Assertion checker does not yet support this expression.\n// Warning 8364: (549-551): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (549-553): Assertion checker does not support recursive structs.\n// Warning 7650: (562-566): Assertion checker does not yet support this expression.\n// Warning 8364: (562-564): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (562-566): Assertion checker does not support recursive structs.\n// Warning 7650: (575-579): Assertion checker does not yet support this expression.\n// Warning 8364: (575-577): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (575-586): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (575-579): Assertion checker does not support recursive structs.\n// Warning 7650: (590-594): Assertion checker does not yet support this expression.\n// Warning 8364: (590-592): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (590-601): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (590-594): Assertion checker does not support recursive structs.\n// Warning 7650: (605-614): Assertion checker does not yet support this expression.\n// Warning 7650: (605-609): Assertion checker does not yet support this expression.\n// Warning 8364: (605-607): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (605-612): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (605-614): Assertion checker does not support recursive structs.\n// Warning 7650: (623-632): Assertion checker does not yet support this expression.\n// Warning 7650: (623-627): Assertion checker does not yet support this expression.\n// Warning 8364: (623-625): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (623-630): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (623-632): Assertion checker does not support recursive structs.\n// Warning 7650: (641-650): Assertion checker does not yet support this expression.\n// Warning 7650: (641-645): Assertion checker does not yet support this expression.\n// Warning 8364: (641-643): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (641-648): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (641-657): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (641-650): Assertion checker does not support recursive structs.\n// Warning 7650: (661-670): Assertion checker does not yet support this expression.\n// Warning 7650: (661-665): Assertion checker does not yet support this expression.\n// Warning 8364: (661-663): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (661-668): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (661-677): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (661-670): Assertion checker does not support recursive structs.\n// Warning 7650: (681-695): Assertion checker does not yet support this expression.\n// Warning 7650: (681-690): Assertion checker does not yet support this expression.\n// Warning 7650: (681-685): Assertion checker does not yet support this expression.\n// Warning 8364: (681-683): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (681-688): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (681-693): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (681-695): Assertion checker does not support recursive structs.\n// Warning 7650: (704-718): Assertion checker does not yet support this expression.\n// Warning 7650: (704-713): Assertion checker does not yet support this expression.\n// Warning 7650: (704-708): Assertion checker does not yet support this expression.\n// Warning 8364: (704-706): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (704-711): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (704-716): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (704-718): Assertion checker does not support recursive structs.\n// Warning 6328: (91-111): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (115-149): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (216-223): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (229-236): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (209-239): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (251-258): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (284-291): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (316-323): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (336-343): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (309-353): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (605-612): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\n// Warning 6368: (623-630): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\n// Warning 6368: (641-648): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\n// Warning 6368: (661-668): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\n// Warning 6368: (681-688): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\n// Warning 6368: (681-693): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\n// Warning 6368: (704-711): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\n// Warning 6368: (704-716): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_recursive_4.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tS[] a;\n\t}\n\tS s1;\n\tS s2;\n\tfunction f(bool b1, bool b2) public {\n\t\tS storage s3 = b1 ? s1 : s2;\n\t\tS storage s4 = b2 ? s1 : s2;\n\t\tassert(s3.x == s1.x || s3.x == s2.x);\n\t\tassert(s4.x == s1.x || s4.x == s2.x);\n\t\ts3.x = 44;\n\t\t// Fails as false positive because of lack of support to aliasing.\n\t\tassert(s1.x == 44 || s2.x == 44);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 8115: (48-52): Assertion checker does not yet support the type of this variable.\n// Warning 8115: (55-59): Assertion checker does not yet support the type of this variable.\n// Warning 8115: (102-114): Assertion checker does not yet support the type of this variable.\n// Warning 8115: (133-145): Assertion checker does not yet support the type of this variable.\n// Warning 8364: (122-124): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (127-129): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (117-129): Assertion checker does not yet implement type struct C.S storage pointer\n// Warning 8364: (153-155): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (158-160): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (148-160): Assertion checker does not yet implement type struct C.S storage pointer\n// Warning 7650: (171-175): Assertion checker does not yet support this expression.\n// Warning 8364: (171-173): Assertion checker does not yet implement type struct C.S storage pointer\n// Warning 7650: (179-183): Assertion checker does not yet support this expression.\n// Warning 8364: (179-181): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (187-191): Assertion checker does not yet support this expression.\n// Warning 8364: (187-189): Assertion checker does not yet implement type struct C.S storage pointer\n// Warning 7650: (195-199): Assertion checker does not yet support this expression.\n// Warning 8364: (195-197): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (211-215): Assertion checker does not yet support this expression.\n// Warning 8364: (211-213): Assertion checker does not yet implement type struct C.S storage pointer\n// Warning 7650: (219-223): Assertion checker does not yet support this expression.\n// Warning 8364: (219-221): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (227-231): Assertion checker does not yet support this expression.\n// Warning 8364: (227-229): Assertion checker does not yet implement type struct C.S storage pointer\n// Warning 7650: (235-239): Assertion checker does not yet support this expression.\n// Warning 8364: (235-237): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (244-248): Assertion checker does not yet support this expression.\n// Warning 8364: (244-246): Assertion checker does not yet implement type struct C.S storage pointer\n// Warning 4375: (244-248): Assertion checker does not support recursive structs.\n// Warning 7650: (333-337): Assertion checker does not yet support this expression.\n// Warning 8364: (333-335): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (347-351): Assertion checker does not yet support this expression.\n// Warning 8364: (347-349): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 6328: (164-200): CHC: Assertion violation happens here.\n// Warning 6328: (204-240): CHC: Assertion violation happens here.\n// Warning 6328: (326-358): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_recursive_5.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tS[] a;\n\t}\n\tS[] sa;\n\tS[][] sa2;\n\tfunction f() public {\n\t\tsa.push();\n\t\tsa2.push();\n\t\tsa2[0].push();\n\t\tsa2[0][0].a.push();\n\t\tassert(sa2[0][0].a.length == sa[0].a.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8364: (93-102): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (120-133): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (137-148): Assertion checker does not yet support this expression.\n// Warning 8364: (137-146): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (137-155): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (137-148): Assertion checker does not support recursive structs.\n// Warning 7650: (166-177): Assertion checker does not yet support this expression.\n// Warning 8364: (166-175): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (188-195): Assertion checker does not yet support this expression.\n// Warning 8364: (188-193): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 6328: (159-203): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_recursive_6.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tS[] a;\n\t}\n\tS s1;\n\tS s2;\n\tfunction f() public {\n\t\ts1.x = 10;\n\t\t++s1.x;\n\t\ts1.x++;\n\t\ts2.x = 20;\n\t\t--s2.x;\n\t\ts2.x--;\n\t\tassert(s1.x == s2.x + 6);\n\t\tassert(s1.a.length == s2.a.length);\n\t\tdelete s1;\n\t\tassert(s1.x == 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8115: (48-52): Assertion checker does not yet support the type of this variable.\n// Warning 8115: (55-59): Assertion checker does not yet support the type of this variable.\n// Warning 7650: (86-90): Assertion checker does not yet support this expression.\n// Warning 8364: (86-88): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (86-90): Assertion checker does not support recursive structs.\n// Warning 7650: (101-105): Assertion checker does not yet support this expression.\n// Warning 8364: (101-103): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (101-105): Assertion checker does not support recursive structs.\n// Warning 7650: (109-113): Assertion checker does not yet support this expression.\n// Warning 8364: (109-111): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (109-113): Assertion checker does not support recursive structs.\n// Warning 7650: (119-123): Assertion checker does not yet support this expression.\n// Warning 8364: (119-121): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (119-123): Assertion checker does not support recursive structs.\n// Warning 7650: (134-138): Assertion checker does not yet support this expression.\n// Warning 8364: (134-136): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (134-138): Assertion checker does not support recursive structs.\n// Warning 7650: (142-146): Assertion checker does not yet support this expression.\n// Warning 8364: (142-144): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (142-146): Assertion checker does not support recursive structs.\n// Warning 7650: (159-163): Assertion checker does not yet support this expression.\n// Warning 8364: (159-161): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (167-171): Assertion checker does not yet support this expression.\n// Warning 8364: (167-169): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (187-191): Assertion checker does not yet support this expression.\n// Warning 8364: (187-189): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (202-206): Assertion checker does not yet support this expression.\n// Warning 8364: (202-204): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (225-227): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (238-242): Assertion checker does not yet support this expression.\n// Warning 8364: (238-240): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4984: (99-105): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 4984: (109-115): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 3944: (132-138): CHC: Underflow (resulting value less than 0) happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 3944: (142-148): CHC: Underflow (resulting value less than 0) happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 4984: (167-175): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (152-176): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (180-214): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (231-248): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_recursive_indirect_1.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tT[] a;\n\t}\n\tstruct T {\n\t\tuint y;\n\t\tS[] a;\n\t}\n\tS s1;\n\tS s2;\n\tfunction f() public view {\n\t\tassert(s1.x == s2.x);\n\t\tassert(s1.a.length == s2.a.length);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8115: (82-86): Assertion checker does not yet support the type of this variable.\n// Warning 8115: (89-93): Assertion checker does not yet support the type of this variable.\n// Warning 7650: (132-136): Assertion checker does not yet support this expression.\n// Warning 8364: (132-134): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (140-144): Assertion checker does not yet support this expression.\n// Warning 8364: (140-142): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (156-160): Assertion checker does not yet support this expression.\n// Warning 8364: (156-158): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (171-175): Assertion checker does not yet support this expression.\n// Warning 8364: (171-173): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 6328: (125-145): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (149-183): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_recursive_indirect_2.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tT[] a;\n\t}\n\tstruct T {\n\t\tuint y;\n\t\tS[] a;\n\t}\n\tS s1;\n\tS s2;\n\tfunction f() public {\n\t\ts1.a.push();\n\t\ts2.a.push();\n\t\ts1.a[0].a.push();\n\t\ts2.a[0].a.push();\n\t\tassert(s1.a[0].a[0].x == s2.a[0].a[0].x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 8115: (82-86): Assertion checker does not yet support the type of this variable.\n// Warning 8115: (89-93): Assertion checker does not yet support the type of this variable.\n// Warning 7650: (120-124): Assertion checker does not yet support this expression.\n// Warning 8364: (120-122): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (120-131): Assertion checker does not yet implement type struct C.T storage ref\n// Warning 4375: (120-124): Assertion checker does not support recursive structs.\n// Warning 7650: (135-139): Assertion checker does not yet support this expression.\n// Warning 8364: (135-137): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (135-146): Assertion checker does not yet implement type struct C.T storage ref\n// Warning 4375: (135-139): Assertion checker does not support recursive structs.\n// Warning 7650: (150-159): Assertion checker does not yet support this expression.\n// Warning 7650: (150-154): Assertion checker does not yet support this expression.\n// Warning 8364: (150-152): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (150-157): Assertion checker does not yet implement type struct C.T storage ref\n// Warning 8364: (150-166): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (150-159): Assertion checker does not support recursive structs.\n// Warning 7650: (170-179): Assertion checker does not yet support this expression.\n// Warning 7650: (170-174): Assertion checker does not yet support this expression.\n// Warning 8364: (170-172): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (170-177): Assertion checker does not yet implement type struct C.T storage ref\n// Warning 8364: (170-186): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 4375: (170-179): Assertion checker does not support recursive structs.\n// Warning 7650: (197-211): Assertion checker does not yet support this expression.\n// Warning 7650: (197-206): Assertion checker does not yet support this expression.\n// Warning 7650: (197-201): Assertion checker does not yet support this expression.\n// Warning 8364: (197-199): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (197-204): Assertion checker does not yet implement type struct C.T storage ref\n// Warning 8364: (197-209): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 7650: (215-229): Assertion checker does not yet support this expression.\n// Warning 7650: (215-224): Assertion checker does not yet support this expression.\n// Warning 7650: (215-219): Assertion checker does not yet support this expression.\n// Warning 8364: (215-217): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 8364: (215-222): Assertion checker does not yet implement type struct C.T storage ref\n// Warning 8364: (215-227): Assertion checker does not yet implement type struct C.S storage ref\n// Warning 6368: (150-157): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (170-177): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (197-204): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (197-209): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (215-222): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6368: (215-227): CHC: Out of bounds access happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (190-230): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_return.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tuint[] a;\n\t}\n\tfunction s() internal pure returns (S memory s1) {\n\t\ts1.x = 42;\n\t\ts1.a = new uint[](5);\n\t\ts1.a[2] = 43;\n\t}\n\tfunction f() public pure {\n\t\tS memory s2 = s();\n\t\tassert(s2.x == 42);\n\t\tassert(s2.a[2] == 43);\n\t\tassert(s2.a[3] == 43);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (256-277): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_state_constructor.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS s = S(42);\n\n\tfunction test() view public {\n\t\tassert(s.x == 42);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_state_var.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tuint[] a;\n\t}\n\tS s;\n\tfunction p() public { s.a.push(); }\n\tfunction f(uint _x) public {\n\t\trequire(s.a.length >= 2);\n\t\ts.x = _x;\n\t\ts.a[0] = _x;\n\t\tassert(s.a[1] == s.a[0]);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (180-204): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_state_var_array_pop_1.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tuint[] a;\n\t}\n\tS s;\n\tfunction f(uint _x) public {\n\t\ts.a.pop();\n\t\ts.a.length;\n\t\ts.a.push();\n\t\ts.x = _x;\n\t\ts.a.pop();\n\t\ts.a.push();\n\t\ts.a.push();\n\t\ts.a[0] = _x;\n\t\tassert(s.a[1] == s.a[0]);\n\t\ts.a.pop();\n\t\ts.a.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2529: (88-97): CHC: Empty array \"pop\" happens here.\n// Warning 6328: (197-221): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_state_var_array_pop_2.sol",
    "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t\tuint[] a;\n\t}\n\tS s;\n\tfunction f(uint _x) public {\n\t\ts.x = _x;\n\t\ts.a.pop();\n\t\ts.a.push();\n\t\ts.a.push();\n\t\ts.a[0] = _x;\n\t\tassert(s.a[1] == s.a[0]);\n\t\ts.a.pop();\n\t\ts.a.pop();\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 2529: (100-109): CHC: Empty array \"pop\" happens here.\n// Warning 6328: (156-180): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_temporary.sol",
    "content": "contract C {\n\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tfunction test() pure public {\n\t\tassert(S(42).x == 42);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_unary_add.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct S {\n\t\tuint x;\n\t\tuint[] a;\n\t}\n\tfunction f(S memory s1, S memory s2) public pure {\n\t\tdelete s1;\n\t\ts1.x++;\n\t\t++s1.x;\n\t\tassert(s1.x == 2);\n\t\tassert(s1.x == s2.x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (193-213): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct/struct_unary_sub.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n\tstruct S {\n\t\tuint x;\n\t\tuint[] a;\n\t}\n\tfunction f(S memory s1, S memory s2) public pure {\n\t\tdelete s1;\n\t\ts1.x = 100;\n\t\ts1.x--;\n\t\t--s1.x;\n\t\tassert(s1.x == 98);\n\t\tassert(s1.x == s2.x);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (208-228): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct_1.sol",
    "content": "contract C\n{\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tmapping (uint => S) smap;\n\n\tfunction f(uint y, uint v) public {\n\t\tsmap[y] = S(v);\n\t\tS memory smem = S(v);\n\t\tassert(smap[y].x == smem.x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct_array_branches_1d.sol",
    "content": "contract C\n{\n\tstruct S { uint[] a; }\n\tfunction f(bool b) public pure {\n\t\tS memory c;\n\t\tc.a = new uint[](2);\n\t\tc.a[0] = 0;\n\t\tif (b)\n\t\t\tc.a[0] = 1;\n\t\telse\n\t\t\tc.a[0] = 2;\n\t\tassert(c.a[0] > 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct_array_branches_2d.sol",
    "content": "contract C\n{\n\tstruct S { uint[][] a; }\n\tfunction f(bool b) public pure {\n\t\tS memory c;\n\t\tc.a = new uint[][](1);\n\t\tc.a[0] = new uint[](1);\n\t\tc.a[0][0] = 0;\n\t\tif (b)\n\t\t\tc.a[0][0] = 1;\n\t\telse\n\t\t\tc.a[0][0] = 2;\n\t\tassert(c.a[0][0] > 0);\n\t}\n}\n// ====\n// SMTEngine: chc\n// SMTTargets: assert\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/struct_array_branches_3d.sol",
    "content": "contract C\n{\n\tstruct S { uint[][][] a; }\n\tfunction f(bool b) public pure {\n\t\tS memory c;\n\t\tc.a = new uint[][][](2);\n\t\tassert(c.a.length == 2);\n\t\tassert(c.a[0].length == 0);\n\t\tc.a[0] = new uint[][](2);\n\t\tassert(c.a[0].length == 2);\n\t\tassert(c.a[0][0].length == 0);\n\t\tc.a[0][0] = new uint[](2);\n\t\t// Disabled because of Spacer's seg fault.\n\t\t/*\n\t\tif (b)\n\t\t\tc.a[0][0][0] = 1;\n\t\telse\n\t\t\tc.a[0][0][0] = 2;\n\t\tassert(c.a[0][0][0] > 0);\n\t\t*/\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 5667: (53-59): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Info 1391: CHC: 11 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_1_chain_1.sol",
    "content": "contract C {\n\tfunction i() public pure returns (uint d) {\n\t\tif (0==0)\n\t\t\t(d) = 13;\n\t\tassert(d == 13);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (64-68): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_1_chain_2.sol",
    "content": "contract C {\n\tfunction i() public pure returns (uint d) {\n\t\tif (0==0)\n\t\t\t((d)) = 13;\n\t\tassert(d == 13);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (64-68): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_1_chain_n.sol",
    "content": "contract C {\n\tfunction i() public pure returns (uint d) {\n\t\tif (0==0)\n\t\t\t(((((d))))) = 13;\n\t\tassert(d == 13);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 6838: (64-68): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_array_pop_1.sol",
    "content": "contract C {\n\tint[] a;\n\tfunction f() public { (a).pop();}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (46-55): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\na = []\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_array_pop_2.sol",
    "content": "contract C {\n\tint[] a;\n\tfunction f() public { (((((a))))).pop();}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 2529: (46-63): CHC: Empty array \"pop\" happens here.\\nCounterexample:\\na = []\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_assignment.sol",
    "content": "contract C\n{\n\tfunction g() public pure {\n\t\tuint x;\n\t\tuint y;\n\t\t(x, y) = (2, 4);\n\t\tassert(x == 2);\n\t\tassert(y == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_assignment_array.sol",
    "content": "contract C\n{\n\tuint[] a;\n\tfunction p() public { a.push(); }\n\tfunction g(uint x, uint y) public {\n\t\trequire(x < a.length);\n\t\trequire(y < a.length);\n\t\trequire(x != y);\n\t\t(a[x], a[y]) = (2, 4);\n\t\tassert(a[x] == 2);\n\t\tassert(a[y] == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_assignment_array_empty.sol",
    "content": "contract C\n{\n\tuint[] a;\n\tfunction f(uint x) public {\n\t\ta.push(x);\n\t}\n\tfunction g(uint x, uint y) public {\n\t\trequire(x < a.length);\n\t\trequire(y < a.length);\n\t\trequire(x != y);\n\t\t(, a[y]) = (2, 4);\n\t\tassert(a[x] == 2);\n\t\tassert(a[y] == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTTargets: assert\n// ----\n// Warning 6328: (198-215): CHC: Assertion violation happens here.\\nCounterexample:\\na = [3212, 4]\\nx = 0\\ny = 1\\n\\nTransaction trace:\\nC.constructor()\\nState: a = []\\nC.f(3212)\\nState: a = [3212]\\nC.f(1573)\\nState: a = [3212, 1573]\\nC.g(0, 1)\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_assignment_compound.sol",
    "content": "contract C\n{\n\tfunction f() public pure {\n\t\tuint a = 1;\n\t\tuint b = 3;\n\t\ta += ((((b))));\n\t\tassert(a == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (89-103): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_assignment_empty.sol",
    "content": "contract C\n{\n\tfunction g() public pure {\n\t\tuint x;\n\t\tuint y;\n\t\t(x, ) = (2, 4);\n\t\tassert(x == 2);\n\t\tassert(y == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (99-113): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_assignment_multiple_calls.sol",
    "content": "contract C\n{\n\tfunction f(uint x) public pure returns (uint, uint) {\n\t\treturn (x, x);\n\t}\n\n\tfunction g() public pure {\n\t\t(uint a, uint b) = f(0);\n\t\t(uint c, uint d) = f(0);\n\t\tassert(a == c && b == d);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_declarations.sol",
    "content": "contract C\n{\n\tfunction g() public pure {\n\t\t(uint x, uint y) = (2, 4);\n\t\tassert(x == 2);\n\t\tassert(y == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_declarations_empty.sol",
    "content": "contract C\n{\n\tfunction g() public pure {\n\t\t(uint x, ) = (2, 4);\n\t\tassert(x == 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_declarations_function.sol",
    "content": "contract C\n{\n\tfunction f() internal pure returns (uint, bool, uint) {\n\t\tuint x = 3;\n\t\tbool b = true;\n\t\tuint y = 999;\n\t\treturn (x, b, y);\n\t}\n\tfunction g() public pure {\n\t\t(uint x, bool b, uint y) = f();\n\t\tassert(x == 3);\n\t\tassert(b);\n\t\tassert(y == 999);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_declarations_function_2.sol",
    "content": "contract C\n{\n\tfunction f(uint x) internal pure returns (uint, bool, uint) {\n\t\tbool b = true;\n\t\tuint y = 999;\n\t\treturn (x * 2, b, y);\n\t}\n\tfunction g() public pure {\n\t\t(uint x, bool b, uint y) = f(7);\n\t\tassert(x == 14);\n\t\tassert(b);\n\t\tassert(y == 999);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_declarations_function_empty.sol",
    "content": "contract C\n{\n\tfunction f() internal pure returns (uint, bool, uint) {\n\t\tuint x = 3;\n\t\tbool b = true;\n\t\tuint y = 999;\n\t\treturn (x, b, y);\n\t}\n\tfunction g() public pure {\n\t\t(, bool b,) = f();\n\t\tassert(!b);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (191-201): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nb = true\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.f() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_different_count_assignment_1.sol",
    "content": "contract C {\n\tfunction f() public pure returns(int) {\n\t\tint a;\n\t\t(,, a) = ((((((1, 3, (((((2)))))))))));\n\t\tassert(a == 2);\n\t\tassert(a == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (47-50): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6328: (125-139): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_different_count_assignment_2.sol",
    "content": "contract C {\n\tfunction f() public pure returns(int) {\n\t\tint a;\n\t\t((,, a)) = ((((((1, 3, (((((2)))))))))));\n\t\tassert(a == 2);\n\t\tassert(a == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (47-50): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6328: (127-141): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_extra_parens_1.sol",
    "content": "contract C {\n\tfunction f2() public pure returns(int) {\n\t\tint a;\n\t\t((, a)) = (1, 2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (48-51): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_extra_parens_2.sol",
    "content": "contract C {\n\tfunction f2() public pure returns(int) {\n\t\tint a;\n\t\t(((, a),)) = ((1, 2), 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (48-51): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_extra_parens_3.sol",
    "content": "contract C {\n\tfunction f2() public pure returns(int) {\n\t\tint a;\n\t\t(((((((, a),)))))) = ((1, 2), 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (48-51): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_extra_parens_4.sol",
    "content": "contract C {\n\tfunction f2() public pure returns(int) {\n\t\tint a;\n\t\t((((((, a)))),)) = ((1, 2), 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (48-51): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_extra_parens_5.sol",
    "content": "contract C {\n\tfunction f2() public pure returns(int) {\n\t\tint a;\n\t\t((((((((((((, a))))))),))))) = ((1, 2), 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6321: (48-51): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_extra_parens_6.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\t(((,))) = ((2),3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_extra_parens_7.sol",
    "content": "contract C {\n\tfunction g() internal pure returns (uint, uint) {\n\t\treturn (2, 3);\n\t}\n\tfunction f() public {\n\t\t(address(1).call(\"\"));\n\t\t(uint x, uint y) = ((g()));\n\t\tassert(x == 2);\n\t\tassert(y == 3);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_function.sol",
    "content": "contract C\n{\n\tfunction f() internal pure returns (uint, uint) {\n\t\treturn (2, 3);\n\t}\n\tfunction g() public pure {\n\t\tuint x;\n\t\tuint y;\n\t\t(x,y) = f();\n\t\tassert(x == 1);\n\t\tassert(y == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (149-163): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 2\\ny = 3\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.f() -- internal call\n// Warning 6328: (167-181): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 2\\ny = 3\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.f() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_function_2.sol",
    "content": "contract C\n{\n\tfunction f() internal pure returns (uint, uint) {\n\t\treturn (2, 3);\n\t}\n\tfunction g() public pure {\n\t\tuint x;\n\t\tuint y;\n\t\t(x,) = f();\n\t\tassert(x == 2);\n\t\tassert(y == 4);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (166-180): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 2\\ny = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.f() -- internal call\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_function_3.sol",
    "content": "contract C\n{\n\tfunction f() internal pure returns (uint, bool, uint) {\n\t\treturn (2, false, 3);\n\t}\n\tfunction g() public pure {\n\t\tuint x;\n\t\tuint y;\n\t\tbool b;\n\t\t(,b,) = f();\n\t\tassert(x == 2);\n\t\tassert(y == 4);\n\t\tassert(!b);\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (172-186): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\ny = 0\\nb = false\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.f() -- internal call\n// Warning 6328: (190-204): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\ny = 0\\nb = false\\n\\nTransaction trace:\\nC.constructor()\\nC.g()\\n    C.f() -- internal call\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_return_branch.sol",
    "content": "contract C {\n\tstruct S { uint x; }\n\n\tfunction g() internal pure returns (uint, S memory) {\n\t\treturn (2, S(3));\n\t}\n\tfunction f(uint a) public pure {\n\t\tuint x;\n\t\tS memory y;\n\t\tif (a > 100) {\n\t\t\t(x, y) = g();\n\t\t\tassert(y.x == 3);\n\t\t }\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_single_element_1.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\t((\"\", 2));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (43-52): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_single_element_2.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\t((\"\", \"\"));\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (43-53): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_single_non_tuple_element.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\t(2);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (43-46): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/tuple_tuple.sol",
    "content": "contract C {\n\tfunction f3() public pure {\n\t\t((, ), ) = ((7, 8), 9);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/type_expression_array_2d.sol",
    "content": "contract C {\n\nfunction f() public pure { int[][]; }\n\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (41-48): Statement has no effect.\n// Warning 8364: (41-46): Assertion checker does not yet implement type type(int256[] memory)\n// Warning 8364: (41-48): Assertion checker does not yet implement type type(int256[] memory[] memory)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/type_expression_array_3d.sol",
    "content": "contract C {\n\nfunction f() public pure { int[][][]; }\n\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (41-50): Statement has no effect.\n// Warning 8364: (41-46): Assertion checker does not yet implement type type(int256[] memory)\n// Warning 8364: (41-48): Assertion checker does not yet implement type type(int256[] memory[] memory)\n// Warning 8364: (41-50): Assertion checker does not yet implement type type(int256[] memory[] memory[] memory)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/type_expression_tuple_array_2d.sol",
    "content": "contract C {\n\nfunction f() public pure { (int[][]); }\n\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (41-50): Statement has no effect.\n// Warning 8364: (42-47): Assertion checker does not yet implement type type(int256[] memory)\n// Warning 8364: (42-49): Assertion checker does not yet implement type type(int256[] memory[] memory)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/type_expression_tuple_array_3d.sol",
    "content": "contract C {\n\nfunction f() public pure { (int[][][]); }\n\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6133: (41-52): Statement has no effect.\n// Warning 8364: (42-47): Assertion checker does not yet implement type type(int256[] memory)\n// Warning 8364: (42-49): Assertion checker does not yet implement type type(int256[] memory[] memory)\n// Warning 8364: (42-51): Assertion checker does not yet implement type type(int256[] memory[] memory[] memory)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/type_interfaceid.sol",
    "content": "interface I1 {\n}\n\ninterface I2 {\n\tfunction f() external;\n}\n\ninterface I3 {\n\tfunction f() external;\n\tfunction g(uint, address) external;\n}\n\ncontract C {\n\tfunction f() public pure {\n\t\tassert(type(I1).interfaceId == 0);\n\t\tassert(type(I2).interfaceId != 0);\n\t\tassert(type(I2).interfaceId == 0x26121ff0);\n\t\tassert(type(I2).interfaceId != 0);\n\t\tassert(type(I3).interfaceId == 0x822b51c6);\n\t}\n\tfunction g() public pure {\n\t\tassert(type(I1).interfaceId == type(I2).interfaceId);\n\t}\n\tfunction h() public pure {\n\t\tassert(type(I2).interfaceId == type(I3).interfaceId);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (416-468): CHC: Assertion violation happens here.\n// Warning 6328: (503-555): CHC: Assertion violation happens here.\n// Info 1391: CHC: 5 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/type_meta_unsupported.sol",
    "content": "contract A {\n}\n\ncontract C {\n\tfunction f() public pure {\n\t\tassert(bytes(type(C).name).length != 0);\n\t\tassert(type(A).creationCode.length != 0);\n\t\tassert(type(A).runtimeCode.length != 0);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 7507: (72-84): Assertion checker does not yet support this expression.\n// Warning 7507: (109-129): Assertion checker does not yet support this expression.\n// Warning 7507: (153-172): Assertion checker does not yet support this expression.\n// Warning 6328: (59-98): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (102-142): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n// Warning 6328: (146-185): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/type_minmax.sol",
    "content": "contract C {\n\tfunction int_min() public pure {\n\t\tint8 int8_min = type(int8).min;\n\t\tassert(int8_min == -2**7);\n\n\t\tint16 int16_min = type(int16).min;\n\t\tassert(int16_min == -2**15);\n\n\t\tint24 int24_min = type(int24).min;\n\t\tassert(int24_min == -2**23);\n\n\t\tint32 int32_min = type(int32).min;\n\t\tassert(int32_min == -2**31);\n\n\t\tint64 int64_min = type(int64).min;\n\t\tassert(int64_min == -2**63);\n\n\t\tint256 int256_min = type(int256).min;\n\t\tassert(int256_min == -2**255);\n\t}\n\n\tfunction int_max() public pure {\n\t\tint8 int8_max = type(int8).max;\n\t\tassert(int8_max == 2**7-1);\n\n\t\tint16 int16_max = type(int16).max;\n\t\tassert(int16_max == 2**15-1);\n\n\t\tint24 int24_max = type(int24).max;\n\t\tassert(int24_max == 2**23-1);\n\n\t\tint32 int32_max = type(int32).max;\n\t\tassert(int32_max == 2**31-1);\n\n\t\tint256 int256_max = type(int256).max;\n\t\tassert(int256_max == 2**255-1);\n\t}\n\n\tfunction uint_min() public pure {\n\t\tuint8 uint8_min = type(uint8).min;\n\t\tassert(uint8_min == 0);\n\n\t\tuint16 uint16_min = type(uint16).min;\n\t\tassert(uint16_min == 0);\n\n\t\tuint24 uint24_min = type(uint24).min;\n\t\tassert(uint24_min == 0);\n\n\t\tuint32 uint32_min = type(uint32).min;\n\t\tassert(uint32_min == 0);\n\n\t\tuint256 uint256_min = type(uint256).min;\n\t\tassert(uint256_min == 0);\n\t}\n\n\tfunction uint_max() public pure {\n\t\tuint8 uint8_max = type(uint8).max;\n\t\tassert(uint8_max == 2**8-1);\n\n\t\tuint16 uint16_max = type(uint16).max;\n\t\tassert(uint16_max == 2**16-1);\n\n\t\tuint24 uint24_max = type(uint24).max;\n\t\tassert(uint24_max == 2**24-1);\n\n\t\tuint32 uint32_max = type(uint32).max;\n\t\tassert(uint32_max == 2**32-1);\n\n\t\tuint256 uint256_max = type(uint256).max;\n\t\tassert(uint256_max == 2**256-1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 21 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/type_simple_range.sol",
    "content": "contract C {\n\tfunction f(uint a) public pure {\n\t\tassert(a <= type(uint).max);\n\t\tassert(a >= type(uint).min);\n\t\trequire(a <= type(uint64).max);\n\t\tassert(a <= type(uint64).max);\n\t\tassert(a <= type(uint32).max); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (178-207): CHC: Assertion violation happens here.\\nCounterexample:\\n\\na = 4294967296\\n\\nTransaction trace:\\nC.constructor()\\nC.f(4294967296)\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/types/unused_mapping.sol",
    "content": "contract C {\n\tuint x;\n\tuint y;\n\tmapping (address => bool) public never_used;\n\n\tfunction inc() public {\n\t\trequire(x < 10);\n\t\trequire(y < 10);\n\n\t\tif(x == 0) x = 0; // noop state var read\n\t\tx++;\n\t\ty++;\n\t\t// Commented out because of nondeterminism in Spacer in Z3 4.8.9\n\t\t//assert(y == x);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unchecked/block_inside_unchecked.sol",
    "content": "contract C {\n  function f() public pure returns (uint y) {\n    unchecked{{\n        uint max = type(uint).max;\n        uint x = max + 1; // overflow not reported\n        y = x;\n    }}\n\tassert(y == 0);\n  }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unchecked/check_var_init.sol",
    "content": "contract C {\n    uint public x = msg.value - 10; // can underflow\n    constructor() payable {}\n}\n\ncontract D {\n\tfunction h() internal returns (uint) {\n\t\treturn msg.value - 10; // can underflow\n\t}\n    function f() public {\n        unchecked {\n            h(); // unchecked here does not mean h does not underflow\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 3944: (33-47): CHC: Underflow (resulting value less than 0) happens here.\\nCounterexample:\\nx = 0\\n\\nTransaction trace:\\nC.constructor(){ msg.value: 0 }\n// Warning 3944: (160-174): CHC: Underflow (resulting value less than 0) happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nD.constructor()\\nD.f()\\n    D.h() -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unchecked/checked_called_by_unchecked.sol",
    "content": "contract C {\n    function add(uint16 a, uint16 b) public pure returns (uint16) {\n        return a + b; // can overflow\n    }\n\n    function f(uint16 a, uint16 b, uint16 c) public pure returns (uint16) {\n        unchecked { return add(a, b) + c; } // add can still overflow, `+ c` can't\n    }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 4984: (96-101): CHC: Overflow (resulting value larger than 65535) happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unchecked/checked_modifier_called_by_unchecked.sol",
    "content": "contract C {\n    modifier add(uint16 a, uint16 b) {\n        unchecked { a + b; } // overflow not reported\n        _;\n    }\n\n    function f(uint16 a, uint16 b, uint16 c) public pure add(a, b) returns (uint16) {\n        return b + c; // can overflow\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (225-230): CHC: Overflow (resulting value larger than 65535) happens here.\\nCounterexample:\\n\\na = 65535\\nb = 1\\nc = 65535\\n = 0\\na = 65535\\nb = 1\\n\\nTransaction trace:\\nC.constructor()\\nC.f(65535, 1, 65535)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unchecked/flipping_sign_tests.sol",
    "content": "contract test {\n    function f() public pure returns (bool) {\n        int256 x = -2**255;\n        unchecked { assert(-x == x); }\n        assert(-x == x);\n        return true;\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (117-119): CHC: Overflow (resulting value larger than 2**255 - 1) happens here.\n// Warning 6328: (110-125): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unchecked/inc_dec.sol",
    "content": "contract C {\n\tfunction o() public pure {\n\t\tuint x = type(uint).max;\n\t\tunchecked { ++x; }\n\t\tassert(x == type(uint).min);\n\t}\n\n\tfunction u() public pure {\n\t\tuint x = type(uint).min;\n\t\tunchecked { --x; }\n\t\tassert(x == type(uint).max);\n\t}\n\n\tfunction o_int() public pure {\n\t\tint x = type(int).max;\n\t\tunchecked { ++x; }\n\t\tassert(x == type(int).min);\n\t}\n\n\tfunction u_int() public pure {\n\t\tint x = type(int).min;\n\t\tunchecked { --x; }\n\t\tassert(x == type(int).max);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unchecked/signed_mod.sol",
    "content": "contract C {\n    function f(int a, int b) public pure returns (int) {\n        return a % b; // can div by 0\n    }\n    function g(bool _check) public pure returns (int) {\n        int x = type(int).min;\n        if (_check) {\n            return x / -1; // can overflow\n        } else {\n            unchecked { return x / -1; } // overflow not reported\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4281: (85-90): CHC: Division by zero happens here.\n// Warning 4984: (242-248): CHC: Overflow (resulting value larger than 2**255 - 1) happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unchecked/unchecked_called_by_checked.sol",
    "content": "contract C {\n    function add(uint16 a, uint16 b) public pure returns (uint16) {\n        unchecked {\n            return a + b; // overflow not reported\n        }\n    }\n\n    function f(uint16 a) public pure returns (uint16) {\n        return add(a, 0x100) + 0x100; // should overflow on `+ 0x100`\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4984: (240-261): CHC: Overflow (resulting value larger than 65535) happens here.\\nCounterexample:\\n\\na = 65024\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.f(65024)\\n    C.add(65024, 256) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unchecked/unchecked_div_by_zero.sol",
    "content": "contract C {\n    function div(uint256 a, uint256 b) public pure returns (uint256) {\n        // Does not disable div by zero check\n        unchecked {\n            return a / b;\n        }\n    }\n\n    function mod(uint256 a, uint256 b) public pure returns (uint256) {\n        // Does not disable div by zero check\n        unchecked {\n            return a % b;\n        }\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 4281: (169-174): CHC: Division by zero happens here.\\nCounterexample:\\n\\na = 0\\nb = 0\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.div(0, 0)\n// Warning 4281: (349-354): CHC: Division by zero happens here.\\nCounterexample:\\n\\na = 0\\nb = 0\\n = 0\\n\\nTransaction trace:\\nC.constructor()\\nC.mod(0, 0)\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unchecked/unchecked_double_with_modifier.sol",
    "content": "contract C {\n\n\tmodifier m() {\n\t\tunchecked{}\n\t\t_;\n\t}\n\n\tfunction t() m internal pure {}\n\n\tfunction f() public pure {\n\t\tunchecked { t(); }\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unchecked/unchecked_function_call_with_unchecked_block.sol",
    "content": "contract C {\n\tfunction f(uint x) internal pure {\n\t\tunchecked {\n\t\t\tuint y = x - 1;\n\t\t\tassert(y < x); // should fail, underflow can happen, we are inside unchecked block\n\t\t}\n\t}\n\tfunction g(uint x) public pure {\n\t\tunchecked { f(x); }\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (85-98): CHC: Assertion violation happens here.\\nCounterexample:\\n\\nx = 0\\ny = 115792089237316195423570985008687907853269984665640564039457584007913129639935\\n\\nTransaction trace:\\nC.constructor()\\nC.g(0)\\n    C.f(0) -- internal call\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unsupported/assembly_1.sol",
    "content": "contract C {\n    function f(uint x, uint y) public pure {\n        assembly {}\n        assert(x < y);\n    }\n\n    function g(uint x, uint y) public pure {\n        assembly {}\n        assert(x < y);\n    }\n}\n// ====\n// SMTEngine: all\n// SMTShowUnsupported: no\n// ----\n// Warning 5724: SMTChecker: 2 unsupported language feature(s). Enable the model checker option \"show unsupported\" to see all of them.\n// Warning 6328: (86-99): CHC: Assertion violation happens here.\n// Warning 6328: (181-194): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol",
    "content": "contract C {\n    uint transient x;\n    function test() public view { assert(x == 0); }\n}\n// ====\n// SMTEngine: all\n// ----\n// UnimplementedFeatureError 1834: Transient storage variables are not supported.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/constant.sol",
    "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n\tT constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n\tT constant public t = s;\n\tint224 constant public u = T.unwrap(t);\n\n\tfunction f() public pure {\n\t\tassert(T.unwrap(s) == 165521356710917456517261742455526507355687727119203895813322792776);\n\t\tassert(T.unwrap(t) == 165521356710917456517261742455526507355687727119203895813322792776);\n\t\tassert(u == 165521356710917456517261742455526507355687727119203895813322792776);\n\t\tassert(T.unwrap(s) == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: no\n// ----\n// Warning 6328: (531-555): CHC: Assertion violation happens here.\\nCounterexample:\\nu = 165521356710917456517261742455526507355687727119203895813322792776\\n\\nTransaction trace:\\nC.constructor()\\nState: u = 165521356710917456517261742455526507355687727119203895813322792776\\nC.f()\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/conversion_1.sol",
    "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n\tfunction f(uint a) internal pure returns(MyUInt8) {\n\t\treturn MyUInt8.wrap(uint8(a));\n\t}\n\tfunction g(uint a) internal pure returns(MyInt8) {\n\t\treturn MyInt8.wrap(int8(int(a)));\n\t}\n\n\tfunction p() public pure {\n\t\tassert(MyUInt8.unwrap(f(1)) == 1);\n\t\tassert(MyUInt8.unwrap(f(2)) == 2);\n\t\tassert(MyUInt8.unwrap(f(257)) == 1);\n\t\tassert(MyUInt8.unwrap(f(257)) == 257); // should fail\n\t}\n\n\tfunction q() public pure {\n\t\tassert(MyInt8.unwrap(g(1)) == 1);\n\t\tassert(MyInt8.unwrap(g(2)) == 2);\n\t\tassert(MyInt8.unwrap(g(255)) == -1);\n\t\tassert(MyInt8.unwrap(g(257)) == 1);\n\t\tassert(MyInt8.unwrap(g(257)) == -1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (428-465): CHC: Assertion violation happens here.\n// Warning 6328: (665-700): CHC: Assertion violation happens here.\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/conversion_2.sol",
    "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n\tfunction h(MyUInt8 a) internal pure returns (MyInt8) {\n\t\treturn MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n\t}\n\tfunction i(MyUInt8 a) internal pure returns(MyUInt16) {\n\t\treturn MyUInt16.wrap(MyUInt8.unwrap(a));\n\t}\n\n\tfunction r() public pure {\n\t\tassert(MyInt8.unwrap(h(MyUInt8.wrap(1))) == 1);\n\t\tassert(MyInt8.unwrap(h(MyUInt8.wrap(2))) == 2);\n\t\tassert(MyInt8.unwrap(h(MyUInt8.wrap(255))) == -1);\n\t\tassert(MyInt8.unwrap(h(MyUInt8.wrap(255))) == 1); // should fail\n\t}\n\n\tfunction s() public pure {\n\t\tassert(MyUInt16.unwrap(i(MyUInt8.wrap(250))) == 250);\n\t\tassert(MyUInt16.unwrap(i(MyUInt8.wrap(250))) == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (497-545): CHC: Assertion violation happens here.\n// Warning 6328: (652-702): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/conversion_3.sol",
    "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n\tfunction j(MyUInt8 a) internal pure returns (uint) {\n\t\treturn MyUInt8.unwrap(a);\n\t}\n\tfunction k(MyUInt8 a) internal pure returns (MyUInt16) {\n\t\treturn MyUInt16.wrap(MyUInt8.unwrap(a));\n\t}\n\n\tfunction t() public pure {\n\t\tassert(j(MyUInt8.wrap(1)) == 1);\n\t\tassert(j(MyUInt8.wrap(2)) == 2);\n\t\tassert(j(MyUInt8.wrap(255)) == 0xff);\n\t\tassert(j(MyUInt8.wrap(255)) == 1); // should fail\n\t}\n\n\tfunction v() public pure {\n\t\tassert(MyUInt16.unwrap(k(MyUInt8.wrap(1))) == 1);\n\t\tassert(MyUInt16.unwrap(k(MyUInt8.wrap(2))) == 2);\n\t\tassert(MyUInt16.unwrap(k(MyUInt8.wrap(255))) == 0xff);\n\t\tassert(MyUInt16.unwrap(k(MyUInt8.wrap(255))) == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (434-467): CHC: Assertion violation happens here.\n// Warning 6328: (679-729): CHC: Assertion violation happens here.\n// Info 1391: CHC: 6 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/conversion_4.sol",
    "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n\tfunction m(MyUInt16 a) internal pure returns (MyUInt8) {\n\t\treturn MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n\t}\n\n\tfunction w() public pure {\n\t\tassert(MyUInt8.unwrap(m(MyUInt16.wrap(1))) == 1);\n\t\tassert(MyUInt8.unwrap(m(MyUInt16.wrap(2))) == 2);\n\t\tassert(MyUInt8.unwrap(m(MyUInt16.wrap(255))) == 0xff);\n\t\tassert(MyUInt8.unwrap(m(MyUInt16.wrap(255))) == 1); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (407-457): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/fixedpoint.sol",
    "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n\tuint constant multiplier = 10**18;\n\t/// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n\t/// uint256.\n\tfunction add(UFixed256x18 a, UFixed256x18 b) internal pure returns (UFixed256x18) {\n\t\treturn UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n\t}\n\t/// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n\t/// uint256.\n\tfunction mul(UFixed256x18 a, uint256 b) internal pure returns (UFixed256x18) {\n\t\treturn UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n\t}\n\t/// Take the floor of a UFixed256x18 number.\n\t/// @return the largest integer that does not exceed `a`.\n\tfunction floor(UFixed256x18 a) internal pure returns (uint256) {\n\t\treturn UFixed256x18.unwrap(a) / multiplier;\n\t}\n\t/// Turns a uint256 into a UFixed256x18 of the same value.\n\t/// Reverts if the integer is too large.\n\tfunction toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n\t\treturn UFixed256x18.wrap(a * multiplier);\n\t}\n}\n\ncontract TestFixedMath {\n\tfunction add(UFixed256x18 a, UFixed256x18 b) internal pure returns (UFixed256x18) {\n\t\treturn FixedMath.add(a, b);\n\t}\n\tfunction mul(UFixed256x18 a, uint256 b) internal pure returns (UFixed256x18) {\n\t\treturn FixedMath.mul(a, b);\n\t}\n\tfunction floor(UFixed256x18 a) internal pure returns (uint256) {\n\t\treturn FixedMath.floor(a);\n\t}\n\tfunction toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n\t\treturn FixedMath.toUFixed256x18(a);\n\t}\n\n\tfunction f() public pure {\n\t\tassert(UFixed256x18.unwrap(add(UFixed256x18.wrap(0), UFixed256x18.wrap(0))) == 0);\n\t\tassert(UFixed256x18.unwrap(add(UFixed256x18.wrap(25), UFixed256x18.wrap(45))) == 0x46);\n\t\tassert(UFixed256x18.unwrap(add(UFixed256x18.wrap(25), UFixed256x18.wrap(45))) == 46); // should fail\n\t}\n\n\tfunction g() public pure {\n\t\tassert(UFixed256x18.unwrap(mul(UFixed256x18.wrap(340282366920938463463374607431768211456), 20)) == 6805647338418769269267492148635364229120);\n\t\tassert(UFixed256x18.unwrap(mul(UFixed256x18.wrap(340282366920938463463374607431768211456), 20)) == 0); // should fail\n\t}\n\n\tfunction h() public pure {\n\t\tassert(floor(UFixed256x18.wrap(11579208923731619542357098500868790785326998665640564039457584007913129639930)) == 11579208923731619542357098500868790785326998665640564039457);\n\t\tassert(floor(UFixed256x18.wrap(115792089237316195423570985008687907853269984665640564039457584007913129639935)) == 115792089237316195423570985008687907853269984665640564039457);\n\t\tassert(floor(UFixed256x18.wrap(11579208923731619542357098500868790785326998665640564039457584007913129639930)) == 0); // should fail\n\t}\n\n\tfunction i() public pure {\n\t\tassert(UFixed256x18.unwrap(toUFixed256x18(0)) == 0);\n\t\tassert(UFixed256x18.unwrap(toUFixed256x18(5)) == 5000000000000000000);\n\t\tassert(UFixed256x18.unwrap(toUFixed256x18(115792089237316195423570985008687907853269984665640564039457)) == 115792089237316195423570985008687907853269984665640564039457000000000000000000);\n\t\tassert(UFixed256x18.unwrap(toUFixed256x18(5)) == 5); // should fail\n\t}\n\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (1886-1970): CHC: Assertion violation happens here.\n// Warning 6328: (2165-2266): CHC: Assertion violation happens here.\n// Warning 6328: (2675-2791): CHC: Assertion violation happens here.\n// Warning 6328: (3161-3212): CHC: Assertion violation happens here.\n// Info 1391: CHC: 12 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/in_parenthesis.sol",
    "content": "type MyInt is int;\ncontract C {\n\tfunction f() public pure returns (MyInt a) {\n\t\ta = MyInt.wrap(5);\n\t\tassert(MyInt.unwrap(a) == 5);\n\t\tassert(MyInt.unwrap(a) == 6); // should fail\n\t}\n\n\tfunction g() public pure {\n\t\tMyInt x = f();\n\t\tassert(MyInt.unwrap(x) == 5);\n\t\tassert(MyInt.unwrap(x) == 6); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (133-161): CHC: Assertion violation happens here.\n// Warning 6328: (261-289): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/in_parenthesis_2.sol",
    "content": "type MyInt is int;\ncontract C {\n\tfunction f() public pure returns (MyInt a, int b) {\n\t\t(MyInt).wrap;\n\t\ta = (MyInt).wrap(5);\n\t\t(MyInt).unwrap;\n\t\tb = (MyInt).unwrap((MyInt).wrap(10));\n\t}\n\n\tfunction g() public pure {\n\t\t(MyInt x, int y) = f();\n\t\tassert(MyInt.unwrap(x) == 5);\n\t\tassert(MyInt.unwrap(x) == 6); // should fail\n\t\tassert(y == 10);\n\t\tassert(y == 11); // should fail\n\t}\n\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6133: (87-99): Statement has no effect.\n// Warning 6133: (126-140): Statement has no effect.\n// Warning 6328: (274-302): CHC: Assertion violation happens here.\n// Warning 6328: (340-355): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/mapping_1.sol",
    "content": "type MyInt is int;\ncontract C {\n    mapping(MyInt => int) m;\n\tfunction f(MyInt a) public view {\n\t\tassert(m[a] == 0); // should hold\n\t\tassert(m[a] != 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreInv: yes\n// ----\n// Warning 6328: (134-151): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/modifier_1.sol",
    "content": "type T1 is uint;\ntype T2 is uint;\n\ncontract C {\n\tmodifier m(T1 x, T2 y) {\n\t\trequire(T1.unwrap(x) == T2.unwrap(y));\n\t\t_;\n\t}\n\n\tfunction f(uint x, uint y) m(T1.wrap(x), T2.wrap(y)) public pure {\n\t\tassert(x == y);\n\t\tassert(x != y); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (212-226): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/multisource.sol",
    "content": "==== Source: A ====\ntype MyInt is int;\ntype MyAddress is address;\n==== Source: B ====\nimport {MyInt, MyAddress as OurAddress} from \"A\";\ncontract A {\n\tfunction f(int x) internal pure returns(MyInt) { return MyInt.wrap(x); }\n\tfunction f(address x) internal pure returns(OurAddress) { return OurAddress.wrap(x); }\n\n\tfunction g() public pure {\n\t\tassert(MyInt.unwrap(f(int(5))) == 5);\n\t\tassert(MyInt.unwrap(f(int(5))) == 0); // should fail\n\t\tassert(OurAddress.unwrap(f(address(5))) == address(5));\n\t\tassert(OurAddress.unwrap(f(address(5))) == address(0)); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (B:296-332): CHC: Assertion violation happens here.\n// Warning 6328: (B:409-463): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/multisource_module.sol",
    "content": "==== Source: s1.sol ====\ntype MyInt is int;\n==== Source: s2.sol ====\nimport \"s1.sol\" as M;\ncontract C {\n\tfunction f(int x) public pure returns (M.MyInt) { return M.MyInt.wrap(x); }\n\tfunction g(M.MyInt x) public pure returns (int) { return M.MyInt.unwrap(x); }\n\n\tfunction h() public pure {\n\t\tassert(M.MyInt.unwrap(f(5)) == 5);\n\t\tassert(M.MyInt.unwrap(f(5)) == 6); // should fail\n\t\tassert(g(M.MyInt.wrap(1)) == 1);\n\t\tassert(g(M.MyInt.wrap(1)) == 0); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (s2.sol:259-292): CHC: Assertion violation happens here.\n// Warning 6328: (s2.sol:346-377): CHC: Assertion violation happens here.\n// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/simple.sol",
    "content": "type MyInt is int;\ncontract C {\n\tfunction f() internal pure returns (MyInt a) {\n\t}\n\tfunction g() internal pure returns (MyInt b, MyInt c) {\n\t\tb = MyInt.wrap(int(1));\n\t\tc = MyInt.wrap(1);\n\t}\n\n\tfunction h() public pure {\n\t\tassert(MyInt.unwrap(f()) == 0);\n\t\tassert(MyInt.unwrap(f()) == 1); // should fail\n\t\t(MyInt x, MyInt y) = g();\n\t\tassert(MyInt.unwrap(x) == 1);\n\t\tassert(MyInt.unwrap(x) == 0); // should fail\n\t\tassert(MyInt.unwrap(y) == 1);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (255-285): CHC: Assertion violation happens here.\n// Warning 6328: (364-392): CHC: Assertion violation happens here.\n// Info 1391: CHC: 3 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/user_abi_1.sol",
    "content": "type T is uint;\n\ncontract C {\n\tfunction f(bytes memory data) public pure {\n\t\tT x = abi.decode(data, (T));\n\t\tuint y = abi.decode(data, (uint));\n\t\tassert(T.unwrap(x) == y); // should hold\n\t\tassert(T.unwrap(x) != y); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (188-212): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/user_abi_2.sol",
    "content": "type T is uint;\n\ncontract C {\n\tfunction f(bytes memory data) public pure {\n\t\tT x = abi.decode(data, (T));\n\t\tT y = abi.decode(data, (T));\n\t\tassert(T.unwrap(x) == T.unwrap(y)); // should hold\n\t\tassert(T.unwrap(x) != T.unwrap(y)); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6328: (192-226): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/user_type_as_array_elem_1.sol",
    "content": "contract C {\n    type T is address;\n    T[] arr;\n\n    function p() public {\n        arr.push(T.wrap(address(42)));\n    }\n\n    function inv(uint i) external view {\n        require(i < arr.length);\n        assert(T.unwrap(arr[i]) == address(42)); // should hold\n    }\n}\n// ====\n// SMTIgnoreOS: macos\n// ----\n// Warning 6328: (204-243): CHC: Assertion violation might happen here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n// Warning 4661: (204-243): BMC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/user_type_as_array_elem_2.sol",
    "content": "contract C {\n    type T is address;\n    T[] arr;\n\n    function p() public {\n        arr.push(T.wrap(address(42)));\n    }\n\n    function inv2() external view {\n        if (arr.length > 0) {\n            assert(T.unwrap(arr[0]) == address(0)); // should fail\n        }\n    }\n}\n// ----\n// Warning 6328: (200-238): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/user_type_as_library_constant_1.sol",
    "content": "type T is bool;\nlibrary L{\n    T constant c = T.wrap(true);\n    uint constant z = 42;\n}\nT constant g = T.wrap(true);\n\ncontract C {\n    T constant b = T.wrap(true);\n    uint constant X = 42;\n\n    function f() external pure {\n        T x = T.wrap(true);\n        assert(T.unwrap(x)); // should hold\n\n        assert(L.z == 42); // should hold\n        assert(T.unwrap(L.c)); // should hold\n\n        assert(T.unwrap(g)); // should hold\n\n        assert(C.X == 42); // should hold\n        assert(T.unwrap(b)); // should hold\n        assert(T.unwrap(C.b)); // should hold\n    }\n}\n// ----\n// Info 1391: CHC: 7 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/user_type_as_library_constant_2.sol",
    "content": "type T is bool;\nlibrary L{\n    T constant c = T.wrap(false);\n    uint constant z = 43;\n}\nT constant g = T.wrap(false);\n\ncontract C {\n    T constant b = T.wrap(false);\n    uint constant X = 43;\n\n    function f() external pure {\n        T x = T.wrap(false);\n        assert(T.unwrap(x)); // should fail\n\n        assert(L.z == 42); // should fail\n        assert(T.unwrap(L.c)); // should fail\n\n        assert(T.unwrap(g)); // should fail\n\n        assert(C.X == 42); // should fail\n        assert(T.unwrap(b)); // should fail\n        assert(T.unwrap(C.b)); // should fail\n    }\n}\n// ----\n// Warning 6328: (264-283): CHC: Assertion violation happens here.\\nCounterexample:\\nX = 43\\n\\nTransaction trace:\\nC.constructor()\\nState: X = 43\\nC.f()\n// Warning 6328: (309-326): CHC: Assertion violation happens here.\\nCounterexample:\\nX = 43\\n\\nTransaction trace:\\nC.constructor()\\nState: X = 43\\nC.f()\n// Warning 6328: (351-372): CHC: Assertion violation happens here.\\nCounterexample:\\nX = 43\\n\\nTransaction trace:\\nC.constructor()\\nState: X = 43\\nC.f()\n// Warning 6328: (398-417): CHC: Assertion violation happens here.\\nCounterexample:\\nX = 43\\n\\nTransaction trace:\\nC.constructor()\\nState: X = 43\\nC.f()\n// Warning 6328: (443-460): CHC: Assertion violation happens here.\\nCounterexample:\\nX = 43\\n\\nTransaction trace:\\nC.constructor()\\nState: X = 43\\nC.f()\n// Warning 6328: (485-504): CHC: Assertion violation happens here.\\nCounterexample:\\nX = 43\\n\\nTransaction trace:\\nC.constructor()\\nState: X = 43\\nC.f()\n// Warning 6328: (529-550): CHC: Assertion violation happens here.\\nCounterexample:\\nX = 43\\n\\nTransaction trace:\\nC.constructor()\\nState: X = 43\\nC.f()\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/user_type_as_mapping_index_1.sol",
    "content": "contract C {\n    type T is bool;\n    mapping (T => uint) s;\n\n    constructor() {\n        s[C.T.wrap(true)] = 42;\n        s[C.T.wrap(false)] = 2;\n    }\n\n    function f(bool b) external view {\n        assert(s[C.T.wrap(b)] > 0); // should hold\n    }\n\n    function g(T b) external view {\n        require(C.T.unwrap(b));\n        assert(s[b] == 2); // should fail\n    }\n}\n// ----\n// Warning 6328: (325-342): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/user_type_as_mapping_index_2.sol",
    "content": "contract C {\n    type T is address;\n    mapping (T => uint) s;\n\n    constructor() {\n        s[T.wrap(address(0))] = 42;\n    }\n\n    function f(address a) external view {\n        require(a != address(0));\n        assert(s[C.T.wrap(a)] == 0); // should hold\n    }\n\n    function g(T a) external view {\n        require(C.T.unwrap(a) == address(0));\n        assert(s[a] != 42); // should fail\n    }\n}\n// ----\n// Warning 6328: (352-370): CHC: Assertion violation happens here.\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/user_type_as_struct_member_1.sol",
    "content": "contract C {\n    type T is address;\n\n    struct S {\n        T a;\n        uint x;\n    }\n\n    mapping (T => S) m;\n\n    constructor() {\n        m[T.wrap(address(0))] = S(T.wrap(address(0)), 0);\n    }\n\n    function set(address _a) external {\n        m[T.wrap(_a)] = S(T.wrap(_a), 0);\n    }\n\n    function inv(T t) external view {\n        assert( // should hold\n            T.unwrap(m[t].a) == T.unwrap(t) ||\n            T.unwrap(m[t].a) == address(0)\n        );\n    }\n}\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/user_type_over_fixed_bytes_can_be_initialized_from_string_literal.sol",
    "content": "type MyBytes is bytes2;\n\ncontract C {\n    MyBytes b = MyBytes.wrap(\"ab\");\n\n    function check() view public {\n        assert(MyBytes.unwrap(b) == 0); // should fail\n        assert(MyBytes.unwrap(b) == 0x6162); // should hold\n    }\n}\n// ====\n// SMTEngine: chc\n// ----\n// Warning 6328: (118-148): CHC: Assertion violation happens here.\\nCounterexample:\\n\\n\\nTransaction trace:\\nC.constructor()\\nC.check()\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/userTypes/wrap_unwrap_via_contract_name.sol",
    "content": "contract C {\n\ttype T is uint;\n}\ncontract D {\n\tfunction f(C.T x) internal pure returns(uint) {\n\t\treturn C.T.unwrap(x);\n\t}\n\tfunction g(uint x) internal pure returns(C.T) {\n\t\treturn C.T.wrap(x);\n\t}\n\tfunction h(uint x) internal pure returns(uint) {\n\t\treturn f(g(x));\n\t}\n\tfunction i(C.T x) internal pure returns(C.T) {\n\t\treturn g(f(x));\n\t}\n\n\tfunction m() public pure {\n\t\tassert(f(C.T.wrap(0x42)) == 0x42);\n\t\tassert(f(C.T.wrap(0x42)) == 0x43); // should fail\n\t\tassert(C.T.unwrap(g(0x42)) == 0x42);\n\t\tassert(C.T.unwrap(g(0x42)) == 0x43); // should fail\n\t\tassert(h(0x42) == 0x42);\n\t\tassert(h(0x42) == 0x43); // should fail\n\t\tassert(C.T.unwrap(i(C.T.wrap(0x42))) == 0x42);\n\t\tassert(C.T.unwrap(i(C.T.wrap(0x42))) == 0x43); // should fail\n\t}\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (403-436): CHC: Assertion violation happens here.\n// Warning 6328: (494-529): CHC: Assertion violation happens here.\n// Warning 6328: (575-598): CHC: Assertion violation happens here.\n// Warning 6328: (666-711): CHC: Assertion violation happens here.\n// Info 1391: CHC: 4 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/verification_target/constant_condition_1.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        if (x >= 0) { revert(); }\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (62-68): BMC: Condition is always true.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/verification_target/constant_condition_2.sol",
    "content": "contract C {\n    function f(uint x) public pure {\n        if (x >= 10) { if (x < 10) { revert(); } }\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n// Warning 6838: (77-83): BMC: Condition is always false.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/verification_target/constant_condition_3.sol",
    "content": "// a plain literal constant is fine\ncontract C {\n    function f(uint) public pure {\n        if (true) { revert(); }\n    }\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/verification_target/no_target_for_abstract_constract.sol",
    "content": "abstract contract A {\n\tfunction f() public pure {\n\t\tassert(false); // A cannot be deployed so this should not be reported\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/verification_target/no_target_for_constructor_of_abstract_constract.sol",
    "content": "abstract contract A {\n\tconstructor() {\n\t\tassert(false); // A cannot be deployed, so this should not be reported\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/verification_target/simple_assert.sol",
    "content": "contract C {\n    function f(uint a) public pure { assert(a == 2); }\n}\n// ====\n// SMTEngine: all\n// SMTIgnoreCex: yes\n// ----\n// Warning 6328: (50-64): CHC: Assertion violation happens here.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/verification_target/simple_assert_with_require.sol",
    "content": "contract C {\n    function f(uint a) public pure { require(a < 10); assert(a < 20); }\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/verification_target/simple_assert_with_require_message.sol",
    "content": "contract C {\n\tfunction f(uint a) public pure {\n\t\trequire(a < 10, \"Input number is too large.\");\n\t\tassert(a < 20);\n\t}\n}\n// ====\n// SMTEngine: all\n// ----\n// Info 1391: CHC: 1 verification condition(s) proved safe! Enable the model checker option \"show proved safe\" to see all of them.\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/verification_target/target_in_constructor_of_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol",
    "content": "contract B {\n    constructor() { fail(); }\n\n    function fail() pure internal { assert(false); }\n}\n\ncontract A {\n    function safe() pure public { }\n}\n// ====\n// SMTContract: A\n// SMTEngine: chc\n// ----\n"
  },
  {
    "path": "test/libsolidity/smtCheckerTests/verification_target/target_in_same_source_contract_not_analyzed_when_not_selected_and_not_called_from_selection.sol",
    "content": "contract B {\n    function fail() pure public { assert(false); }\n}\n\ncontract A {\n    function safe() pure public { }\n}\n// ====\n// SMTContract: A\n// SMTEngine: chc\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_error_free_function.sol",
    "content": "error E(uint);\n\nfunction f() {\n    abi.encodeCall(E, (1));\n}\n// ----\n// TypeError 3509: (50-51): Expected regular external function type, or external view on public function. Cannot use errors for abi.encodeCall.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_event_free_function.sol",
    "content": "library L {\n    event E(uint);\n}\n\nfunction f() {\n    abi.encodeCall(L.E, (1));\n}\n// ----\n// TypeError 3509: (68-71): Expected regular external function type, or external view on public function. Cannot use events for abi.encodeCall.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_free_func.sol",
    "content": "function g(uint) {}\n\nfunction f() {\n    abi.encodeCall(g, (1));\n}\n// ----\n// TypeError 3509: (55-56): Expected regular external function type, or external view on public function. Provided internal function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_on_lib_func_in_free_func.sol",
    "content": "library L {\n    function g() external {}\n}\n\nfunction f() {\n    abi.encodeCall(L.g, (1));\n}\n// ----\n// TypeError 3509: (78-81): Expected regular external function type, or external view on public function. Cannot use library functions for abi.encodeCall.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_assignment_expression.sol",
    "content": "contract C {\n    function g0() internal pure {}\n    function g2() internal pure returns (uint, uint) { return (2, 3); }\n\n    function f0() public {}\n    function f2(uint, uint) public {}\n\n    function h() public view {\n        uint a;\n        uint b;\n\n        abi.encodeCall(this.f0, () = g0());\n        abi.encodeCall(this.f0, () = ());\n        abi.encodeCall(this.f2, (a, b) = g2());\n        abi.encodeCall(this.f2, (a, b) = (2, 3));\n    }\n}\n// ----\n// TypeError 5547: (284-286): Empty tuple on the left hand side.\n// TypeError 9062: (284-293): Expected an inline tuple, not an expression of a tuple type.\n// TypeError 5547: (328-330): Empty tuple on the left hand side.\n// TypeError 9062: (328-335): Expected an inline tuple, not an expression of a tuple type.\n// TypeError 9062: (370-383): Expected an inline tuple, not an expression of a tuple type.\n// TypeError 9062: (418-433): Expected an inline tuple, not an expression of a tuple type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_conditional_ternary_expression.sol",
    "content": "contract C {\n    function g0() internal pure {}\n    function g2() internal pure returns (uint, uint) { return (2, 3); }\n\n    function f0() public {}\n    function f2(uint, uint) public {}\n\n    function h() public view {\n        abi.encodeCall(this.f0, true ? g0() : g0());\n        abi.encodeCall(this.f2, true ? g2() : g2());\n        abi.encodeCall(this.f2, true ? (1, 2) : (3, 4));\n    }\n}\n// ----\n// TypeError 9062: (251-269): Expected an inline tuple, not an expression of a tuple type.\n// TypeError 9062: (304-322): Expected an inline tuple, not an expression of a tuple type.\n// TypeError 9062: (357-379): Expected an inline tuple, not an expression of a tuple type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_error_event.sol",
    "content": "contract C {\n    event Ev();\n    error Er();\n\n    function f0() public {}\n\n    function h() public view {\n        abi.encodeCall(this.f0, Ev());\n        abi.encodeCall(this.f0, Er());\n        abi.encodeCall(this.f0, revert());\n    }\n}\n// ----\n// TypeError 9062: (138-142): Expected an inline tuple, not an expression of a tuple type.\n// TypeError 7515: (153-182): Expected a tuple with 0 components instead of a single non-tuple parameter.\n// TypeError 9062: (216-224): Expected an inline tuple, not an expression of a tuple type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_from_invalid_operator.sol",
    "content": "contract C {\n    event Ev();\n    error Er();\n\n    function g0() internal pure {}\n    function g2() internal pure returns (uint, uint) { return (2, 3); }\n\n    function f0() public {}\n    function f2(uint, uint) public {}\n\n    function h() public view {\n        abi.encodeCall(this.f2, (1, 1) + (2, 2));\n        abi.encodeCall(this.f0, Ev() / Er());\n        abi.encodeCall(this.f0, !());\n    }\n}\n// ----\n// TypeError 2271: (284-299): Built-in binary operator + cannot be applied to types tuple(int_const 1,int_const 1) and tuple(int_const 2,int_const 2).\n// TypeError 9062: (284-299): Expected an inline tuple, not an expression of a tuple type.\n// TypeError 2271: (334-345): Built-in binary operator / cannot be applied to types tuple() and error.\n// TypeError 9062: (334-345): Expected an inline tuple, not an expression of a tuple type.\n// TypeError 4907: (380-383): Built-in unary operator ! cannot be applied to type tuple().\n// TypeError 9062: (380-383): Expected an inline tuple, not an expression of a tuple type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_tuple_returned_from_function.sol",
    "content": "contract C {\n    function g0() internal pure {}\n    function g2() internal pure returns (uint, uint) { return (2, 3); }\n\n    function f0() public {}\n    function f2(uint, uint) public {}\n\n    function h() public view {\n        abi.encodeCall(this.f0, g0());\n        abi.encodeCall(this.f2, g2());\n\n        abi.encodeCall(this.f0, (g0()));\n        abi.encodeCall(this.f2, (g2()));\n    }\n}\n// ----\n// TypeError 9062: (251-255): Expected an inline tuple, not an expression of a tuple type.\n// TypeError 9062: (290-294): Expected an inline tuple, not an expression of a tuple type.\n// TypeError 6473: (331-335): Tuple component cannot be empty.\n// TypeError 7788: (306-337): Expected 0 instead of 1 components for the tuple parameter.\n// TypeError 7788: (347-378): Expected 2 instead of 1 components for the tuple parameter.\n// TypeError 5407: (372-376): Cannot implicitly convert component at position 0 from \"tuple(uint256,uint256)\" to \"uint256\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_unitary_tuple_from_assignment_expression.sol",
    "content": "contract C {\n    function g1() internal pure returns (uint) { return (1); }\n\n    function f1(uint) public {}\n\n    function h() public view {\n        uint a;\n\n        abi.encodeCall(this.f1, (a) = g1());\n        abi.encodeCall(this.f1, (a) = (1));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_unitary_tuple_from_conditional_ternary_expression.sol",
    "content": "contract C {\n    function g1() internal pure returns (uint) { return (1); }\n\n    function f1(uint) public {}\n\n    function h() public view {\n        abi.encodeCall(this.f1, true ? (1) : (2));\n        abi.encodeCall(this.f1, true ? g1() : g1());\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_unitary_tuple_returned_from_function.sol",
    "content": "contract C {\n    function g1() internal pure returns (uint) { return (1); }\n    function g2() internal pure returns (uint, uint) { return (2, 3); }\n\n    function f1(uint) public {}\n    function f2(uint, uint) public {}\n\n    function h() public view {\n        abi.encodeCall(this.f1, g1());\n        abi.encodeCall(this.f1, (g1()));\n        abi.encodeCall(this.f2, (g1(), g1()));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encode_conversions.sol",
    "content": "interface testInterface {\n    function C(function (string memory) external) external;\n    function D(string calldata) external;\n    function E(string memory) external;\n    function F(address) external;\n}\n\ncontract testContract {\n    function g(string calldata) external {}\n    function h(string memory) external {}\n    function i(string calldata str) external {\n        this.h(str);\n        this.g(str);\n    }\n    function j(string memory str) external {\n        this.h(str);\n        this.g(str);\n    }\n    function k(string memory str) external pure {\n        abi.encodeCall(testInterface.D, (str));\n    }\n    string s;\n\n    function main() external view {\n        abi.encodeCall(testInterface.C, (this.g));\n        abi.encodeCall(testInterface.C, (this.h));\n        abi.encodeCall(testInterface.D, (s));\n        abi.encodeCall(testInterface.E, (s));\n        abi.encodeCall(testInterface.F, (payable(address(0))));\n        abi.encodeCall(this.i, (s));\n        abi.encodeCall(this.j, (s));\n    }\n}\n// ----\n// Warning 6133: (860-914): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encode_conversions_address.sol",
    "content": "interface testInterface {\n    function A(address payable) external;\n}\n\ncontract testContract {\n    function main() external view {\n        abi.encodeCall(testInterface.A, (address(0)));\n    }\n}\n// ----\n// TypeError 5407: (171-183): Cannot implicitly convert component at position 0 from \"address\" to \"address payable\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/abi_encode_conversions_function_pointers.sol",
    "content": "interface testInterface {\n    function B(function (string calldata) external) external;\n}\n\ncontract testContract {\n    function g(string calldata) external {}\n    function h(string memory) external {}\n\n    function main() external view {\n        abi.encodeCall(testInterface.B, (this.g));\n        abi.encodeCall(testInterface.B, (this.h));\n    }\n}\n// ----\n// TypeError 5407: (278-286): Cannot implicitly convert component at position 0 from \"function (string memory) external\" to \"function (string calldata) external\".\n// TypeError 5407: (329-337): Cannot implicitly convert component at position 0 from \"function (string memory) external\" to \"function (string calldata) external\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/conflicting_settings.sol",
    "content": "pragma abicoder               v2;\npragma abicoder v1;\n// ----\n// SyntaxError 3845: (34-53): ABI coder has already been selected for this source unit.\n// Warning 9511: (34-53): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/conflicting_settings_reverse.sol",
    "content": "pragma abicoder v1;\npragma abicoder v2;\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// SyntaxError 3845: (20-39): ABI coder has already been selected for this source unit.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/conflicting_settings_reverse_experimental.sol",
    "content": "pragma abicoder v1;\npragma experimental ABIEncoderV2;\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// SyntaxError 8273: (20-53): ABI coder v1 has already been selected through \"pragma abicoder v1\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_nested_struct_with_mapping.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct T { mapping(uint => uint) a; }\n    struct S { T[][2] b; }\n    function f(S memory) public {}\n}\n// ----\n// TypeError 4103: (132-140): Types containing (nested) mappings can only be parameters or return variables of internal or library functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_struct_array_with_function_type.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S { function() internal a; }\n    function f(S[2] memory) public {}\n}\n// ----\n// TypeError 4103: (89-100): Internal type is not allowed for public or external functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_struct_with_array_of_function_types.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    struct S { function() internal[2] a; }\n    function f(S memory) public {}\n}\n// ----\n// TypeError 4103: (92-100): Internal type is not allowed for public or external functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_struct_with_function_type.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { function() internal a; }\n    function f(S memory) public {}\n}\n// ----\n// TypeError 4103: (103-111): Internal type is not allowed for public or external functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/external_functions_taking_internal_types_struct_with_mapping.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { mapping(uint => uint) a; }\n    function f(S memory) public {}\n}\n// ----\n// TypeError 4103: (105-113): Types containing (nested) mappings can only be parameters or return variables of internal or library functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/invalid_pragma_value.sol",
    "content": "pragma abicoder something;\n// ----\n// SyntaxError 2745: (0-26): Expected either \"pragma abicoder v1\" or \"pragma abicoder v2\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/overloaded_external_functions_taking_different_structs.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S1 { function() external a; }\n    struct S2 { bytes24 a; }\n    function f(S1 memory) public pure {}\n    function f(S2 memory) public pure {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/overloaded_external_functions_taking_identical_structs.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S1 { int i; }\n    struct S2 { int i; }\n    function f(S1 memory) public pure {}\n    function f(S2 memory) public pure {}\n}\n// ----\n// TypeError 9914: (143-179): Function overload clash during conversion to external types for arguments.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/same_setting_twice.sol",
    "content": "pragma experimental ABIEncoderV2;\npragma abicoder v2;\n// ----\n// SyntaxError 3845: (34-53): ABI coder has already been selected for this source unit.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/select_v1.sol",
    "content": "pragma abicoder v1;\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/select_v1_quoted_string.sol",
    "content": "pragma abicoder \"v1\";\n// ----\n// Warning 9511: (0-21): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/select_v2_quoted_string.sol",
    "content": "pragma abicoder \"v2\";\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/selected_twice.sol",
    "content": "pragma abicoder v1;\npragma abicoder v1;\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// SyntaxError 3845: (20-39): ABI coder has already been selected for this source unit.\n// Warning 9511: (20-39): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/selected_twice_v2.sol",
    "content": "pragma abicoder v2;\npragma experimental ABIEncoderV2;\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/tight_packing_literals.sol",
    "content": "contract C {\n    function k() pure public returns (bytes memory) {\n        return abi.encodePacked(1);\n    }\n}\n\n// ----\n// TypeError 7279: (99-100): Cannot perform packed encoding for a literal. Please convert it to an explicit type first.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/tight_packing_literals_fine.sol",
    "content": "contract C {\n    function k() pure public returns (bytes memory) {\n        return abi.encodePacked(uint8(1));\n    }\n    function l() pure public returns (bytes memory) {\n        return abi.encode(1);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_accessing_public_state_variable_via_v1_type.sol",
    "content": "pragma abicoder v1;\nstruct Item {\n    uint x;\n    uint y;\n}\n\ncontract D {\n    Item[][][] public items;\n\n    function test() public view returns (uint) {\n        // The autogenerated getters to not use ABI encoder.\n        (uint a, uint b) = this.items(1, 2, 3);\n        return a + b;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_accessing_public_state_variable_via_v2_type.sol",
    "content": "pragma abicoder v1;\nstruct Item {\n    uint x;\n    uint y;\n}\n\ncontract D {\n    Item[][][] public items;\n\n    function test() public view returns (uint) {\n        // The autogenerated getters to not use ABI encoder.\n        Item memory item = this.items(1, 2, 3);\n        return item.x + item.y;\n    }\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 7364: (222-260): Different number of components on the left hand side (1) than on the right hand side (2).\n// TypeError 9574: (222-260): Type uint256 is not implicitly convertible to expected type struct Item memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v1_library_function_accepting_storage_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nlibrary L {\n    struct Item {\n        uint x;\n    }\n\n    function set(Item storage _item) external view {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract Test {\n    L.Item item;\n\n    function foo() public view {\n        L.set(item);\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_constructor_accepting_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    struct Item {\n        uint x;\n    }\n\n    constructor(Item memory _item) {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract Test {\n    function foo() public {\n        new C(C.Item(5));\n    }\n}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2443: (B:91-100): The type of this parameter, struct C.Item memory, is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_contract_function_accepting_struct_via_named_argument.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    struct Item {\n        uint x;\n    }\n\n    function set(uint _x, string memory _y, Item memory _item, bool _z) external view {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract Test {\n    function foo() public view {\n        C(address(0x00)).set({_item: C.Item(50), _z: false, _y: \"abc\", _x: 30});\n    }\n}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2443: (B:119-129): The type of this parameter, struct C.Item memory, is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_contract_function_pointer_accepting_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    struct Item {\n        uint x;\n    }\n\n    function get(Item memory _item) external {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract Test {\n    function foo() public {\n        C c = new C();\n        function(C.Item memory) external ptr = c.get;\n        ptr(C.Item(5));\n    }\n}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2443: (B:166-175): The type of this parameter, struct C.Item memory, is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_contract_function_returning_dynamic_string_array.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    function f() external view returns (string[] memory) {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract D {\n    function g() public view {\n        C(address(0x00)).f();\n    }\n}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2428: (B:85-105): The type of return parameter 1, string[] memory, is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_contract_function_returning_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    struct Item {\n        uint x;\n    }\n\n    function get() external view returns(Item memory) {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract Test {\n    function foo() public view {\n        C(address(0x00)).get();\n    }\n}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2428: (B:90-112): The type of return parameter 1, struct C.Item memory, is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_contract_function_returning_struct_with_dynamic_array.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    struct Item {\n        uint[] y;\n    }\n\n    function get() external view returns(Item memory) {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract Test {\n    function foo() public view {\n        C(address(0x00)).get();\n    }\n}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2428: (B:90-112): The type of return parameter 1, struct C.Item memory, is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_event_accepting_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nlibrary L {\n    struct Item {\n        uint x;\n    }\n    event E(Item _value);\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract Test {\n    function foo() public {\n        emit L.E(L.Item(42));\n    }\n}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2443: (B:94-104): The type of this parameter, struct L.Item memory, is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_library_attached_function_returning_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nlibrary L {\n    struct Item {\n        uint x;\n    }\n\n    function f(uint) external view returns (Item memory) {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract D {\n    using L for uint;\n\n    function test() public {\n        uint(1).f();\n    }\n}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2428: (B:106-117): The type of return parameter 1, struct L.Item memory, is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_library_function_accepting_storage_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nlibrary L {\n    struct Item {\n        uint x;\n    }\n\n    function get(Item storage _item) external view {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract Test {\n    L.Item item;\n\n    function foo() public view {\n        L.get(item);\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_library_function_returning_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nlibrary L {\n    struct Item {\n        uint x;\n    }\n\n    function get() external view returns(Item memory) {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract Test {\n    function foo() public view {\n        L.get();\n    }\n}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2428: (B:90-97): The type of return parameter 1, struct L.Item memory, is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_call_to_v2_modifier.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nstruct Data {\n    bool flag;\n}\n\ncontract A {\n    function get() public view returns (Data memory) {}\n}\n\ncontract B {\n    modifier validate() {\n        A(address(0x00)).get();\n        _;\n    }\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract C is B {\n    function foo()\n        public\n        validate()\n    {}\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_constructor_with_v2_modifier.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nstruct Data {\n    bool flag;\n}\n\ncontract A {\n    function get() public view returns (Data memory) {}\n}\n\ncontract B {\n    constructor() validate {\n        A(address(0x00)).get();\n    }\n\n    modifier validate() {\n        A(address(0x00)).get();\n        _;\n    }\n}\n\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract C is B {}\n==== Source: C ====\npragma abicoder v1;\nimport \"B\";\n\ncontract D is C {\n    constructor() validate B() validate C() validate {}\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// Warning 9511: (C:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_calling_v2_function.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nstruct Data {\n    bool flag;\n}\n\ncontract A {\n    function get() public view returns (Data memory) {}\n}\n\ncontract B {\n    constructor() {\n        A(address(0x00)).get();\n    }\n\n    function foo() public view {\n        A(address(0x00)).get();\n    }\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract C is B {}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_defining_v2_event.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nstruct Item {\n    uint x;\n}\n\ncontract C {\n    event Ev(Item);\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract D is C {}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_defining_v2_function_accepting_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    struct Item {\n        uint x;\n    }\n\n    function get(Item memory) external view {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract D is C {}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 6594: (B:33-51): Contract \"D\" does not use ABI coder v2 but wants to inherit from a contract which uses types that require it. Use \"pragma abicoder v2;\" for the inheriting contract as well to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_defining_v2_function_returning_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    struct Item {\n        uint x;\n    }\n\n    function get() external view returns(Item memory) {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract D is C {}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 6594: (B:33-51): Contract \"D\" does not use ABI coder v2 but wants to inherit from a contract which uses types that require it. Use \"pragma abicoder v2;\" for the inheriting contract as well to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_inheritance_from_contract_emitting_v2_event.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nstruct Item {\n    uint x;\n}\n\nlibrary L {\n    event Ev(Item);\n}\n\ncontract C {\n    function foo() public {\n        emit L.Ev(Item(1));\n    }\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract D is C {}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_modifier_overriding_v2_modifier.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nstruct Data {\n    bool flag;\n}\n\ncontract A {\n    function get() public view returns (Data memory) {}\n}\n\ncontract B {\n    modifier validate() virtual {\n        A(address(0x00)).get();\n        _;\n    }\n}\n\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract C is B {\n    function foo() public pure validate {}\n\n    modifier validate() override {\n        _;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 8429: (A:156-234): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v1_v2_v1_modifier_mix.sol",
    "content": "==== Source: C ====\npragma abicoder v1;\nimport \"X\";\nimport \"V1A\";\nimport \"V2A\";\nimport \"V1B\";\n\ncontract C is V1A, V2A, V1B {\n    function foo()\n        public\n        modV1A\n        modV2A // There should be no error for modV2A (it uses ABIEncoderV2)\n        modV1B\n    {\n    }\n}\n==== Source: V1A ====\npragma abicoder v1;\nimport \"X\";\n\ncontract V1A {\n    modifier modV1A() {\n        _;\n    }\n}\n==== Source: V1B ====\npragma abicoder v1;\nimport \"X\";\n\ncontract V1B {\n    modifier modV1B() {\n        _;\n    }\n}\n==== Source: V2A ====\npragma abicoder               v2;\nimport \"X\";\n\ncontract V2A {\n    modifier modV2A() {\n        X(address(0x00)).get();\n        _;\n    }\n}\n==== Source: X ====\npragma abicoder               v2;\n\nstruct Data {\n    bool flag;\n}\n\ncontract X {\n    function get() public view returns (Data memory) {}\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 9511: (V1A:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// Warning 9511: (V1B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// Warning 9511: (C:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_accessing_returned_dynamic_array_with_returndata_support.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function get() public view returns (uint[][] memory) {}\n\n    function test() public view returns (bool) {\n        uint[][] memory x = this.get();\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// Warning 6321: (150-154): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 2072: (166-183): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_accessing_returned_dynamic_array_without_returndata_support.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function get() public view returns (uint[][] memory) {}\n\n    function test() public view returns (bool) {\n        uint[][] memory x = this.get();\n    }\n}\n// ====\n// EVMVersion: <byzantium\n// ----\n// TypeError 9574: (166-196): Type inaccessible dynamic type is not implicitly convertible to expected type uint256[][] memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_constructor_accepting_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    struct Item {\n        uint x;\n    }\n\n    constructor(Item memory _item) {}\n}\n==== Source: B ====\npragma abicoder               v2;\n\nimport \"A\";\n\ncontract Test {\n    function foo() public {\n        new C(C.Item(5));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_contract_function_pointer_accepting_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    struct Item {\n        uint x;\n    }\n\n    function get(Item memory _item) external {}\n}\n==== Source: B ====\npragma abicoder               v2;\n\nimport \"A\";\n\ncontract Test {\n    function foo() public {\n        C c = new C();\n        function(C.Item memory) external ptr = c.get;\n        ptr(C.Item(5));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_contract_function_returning_dynamic_string_array.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    function f() external view returns (string[] memory) {}\n}\n==== Source: B ====\npragma abicoder               v2;\n\nimport \"A\";\n\ncontract D {\n    function g() public view {\n        C(address(0x00)).f();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_contract_function_returning_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    struct Item {\n        uint x;\n    }\n\n    function get() external view returns(Item memory) {}\n}\n==== Source: B ====\npragma abicoder               v2;\n\nimport \"A\";\n\ncontract Test {\n    function foo() public view {\n        C(address(0x00)).get();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_contract_function_returning_struct_with_dynamic_array.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\ncontract C {\n    struct Item {\n        uint[] y;\n    }\n\n    function get() external view returns(Item memory) {}\n}\n==== Source: B ====\npragma abicoder               v2;\n\nimport \"A\";\n\ncontract Test {\n    function foo() public view {\n        C(address(0x00)).get();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_event_accepting_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nlibrary L {\n    struct Item {\n        uint x;\n    }\n    event E(Item _value);\n}\n==== Source: B ====\npragma abicoder               v2;\n\nimport \"A\";\n\ncontract Test {\n    function foo() public {\n        emit L.E(L.Item(42));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_library_function_pointer_accepting_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nlibrary L {\n    struct Item {\n        uint x;\n    }\n\n    function get(Item memory _item) external {}\n}\n==== Source: B ====\npragma abicoder               v2;\n\nimport \"A\";\n\ncontract Test {\n    function foo() public {\n        // NOTE: This test checks a case that is currently not possible (pointer to an external\n        // library function) but it might become possible in the future.\n        function(L.Item memory) external ptr = L.get;\n        ptr(L.Item(5));\n    }\n}\n// ----\n// TypeError 9574: (B:269-313): Type function (struct L.Item memory) is not implicitly convertible to expected type function (struct L.Item memory) external. Special functions cannot be converted to function types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_call_to_v2_library_function_returning_struct.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nlibrary L {\n    struct Item {\n        uint x;\n    }\n\n    function get() external view returns(Item memory) {}\n}\n==== Source: B ====\npragma abicoder               v2;\n\nimport \"A\";\n\ncontract Test {\n    function foo() public view {\n        L.get();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_v1_v1_modifier_sandwich.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nstruct Data {\n    bool flag;\n}\n\ncontract A {\n    function get() public view returns (Data memory) {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract B {\n    modifier validate() {\n        A(address(0x00)).get();\n        _;\n    }\n}\n==== Source: C ====\npragma abicoder v1;\nimport \"B\";\n\ncontract C is B {\n    function foo()\n        public\n        validate()\n    {}\n}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// Warning 9511: (C:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2428: (B:80-102): The type of return parameter 1, struct Data memory, is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abiEncoder/v2_v1_v2_modifier_sandwich.sol",
    "content": "==== Source: A ====\npragma abicoder               v2;\n\nstruct Data {\n    bool flag;\n}\n\ncontract A {\n    function get() public view returns (Data memory) {}\n}\n==== Source: B ====\npragma abicoder v1;\nimport \"A\";\n\ncontract B {\n    modifier validate() {\n        A(address(0x00)).get();\n        _;\n    }\n}\n==== Source: C ====\npragma abicoder               v2;\n\nimport \"B\";\n\ncontract C is B {\n    function foo()\n        public\n        validate()\n    {}\n}\n// ----\n// Warning 9511: (B:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2428: (B:80-102): The type of return parameter 1, struct Data memory, is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abstract/abstract_contract_because_of_interface.sol",
    "content": "interface A {\n    function utterance() external returns (bytes32);\n}\ncontract B is A {\n}\n// ----\n// TypeError 3656: (69-88): Contract \"B\" should be marked as abstract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abstract/abstract_contract_instantiation.sol",
    "content": "abstract contract AbstractContract {\n    constructor() { }\n    function utterance() public returns (bytes32) { return \"miaow\"; }\n}\n\ncontract Test {\n    function create() public {\n       AbstractContract ac = new AbstractContract();\n    }\n}\n// ----\n// TypeError 4614: (208-228): Cannot instantiate an abstract contract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abstract/abstract_only.sol",
    "content": "abstract\n// ----\n// ParserError 3515: (9-9): Expected keyword \"contract\", \"interface\" or \"library\".\n// ParserError 2314: (9-9): Expected identifier but got end of source\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abstract/abstract_without_contract.sol",
    "content": "abstract A { }\n// ----\n// ParserError 3515: (9-10): Expected keyword \"contract\", \"interface\" or \"library\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abstract/contract.sol",
    "content": "abstract contract A { constructor() {} }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abstract/interface.sol",
    "content": "interface B { }\nabstract interface A { }\n// ----\n// TypeError 9348: (16-40): Interfaces do not need the \"abstract\" keyword, they are abstract implicitly.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abstract/library.sol",
    "content": "abstract library A { }\n// ----\n// TypeError 9571: (0-22): Libraries cannot be abstract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abstract/unimplemented_functions.sol",
    "content": "contract A {\n    function a() public virtual;\n}\n// ----\n// TypeError 3656: (0-47): Contract \"A\" should be marked as abstract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/abstract/unimplemented_functions_inherited.sol",
    "content": "abstract contract A {\n    function a() public virtual;\n}\ncontract B is A {\n}\n// ----\n// TypeError 3656: (57-76): Contract \"B\" should be marked as abstract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/array_pop.sol",
    "content": "contract C {\n    uint[] data;\n    function test() public {\n      data.pop();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/array_pop_arg.sol",
    "content": "contract C {\n    uint[] data;\n    function test() public {\n      data.pop(5);\n    }\n}\n// ----\n// TypeError 6160: (65-76): Wrong argument count for function call: 1 arguments given but expected 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/bytes1_array_push_assign_multi.sol",
    "content": "contract C {\n    bytes1[] x;\n    bytes1[] z;\n    function f() public {\n        (x.push(), x.push()) = (0, 0);\n        (((x.push())), (x.push())) = (0, 0);\n        ((x.push(), x.push()), x.push()) = ((0, 0), 0);\n        (x.push(), x[0]) = (0, 0);\n        bytes1[] storage y = x;\n        (x.push(), y.push()) = (0, 0);\n        (x.push(), z.push()) = (0, 0);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/bytes_assign_multi_fine.sol",
    "content": "contract C {\n\tbytes x;\n\tfunction f() public {\n\t\t(x[0], x[1]) = (0, 0);\n\t\t(x[0], x[1]) = (x[1], x[0]);\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/bytes_pop.sol",
    "content": "contract C {\n    bytes data;\n    function test() public {\n      data.pop();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/bytes_push_assign_multi.sol",
    "content": "contract C {\n    bytes x;\n    bytes z;\n    function f() public {\n        (x.push(), x.push()) = (0, 0);\n        (((x.push())), (x.push())) = (0, 0);\n        ((x.push(), x.push()), x.push()) = ((0, 0), 0);\n        (x.push(), x[0]) = (0, 0);\n        bytes storage y = x;\n        (x.push(), y.push()) = (0, 0);\n        // The following is a false positive.\n        (x.push(), z.push()) = (0, 0);\n    }\n}\n// ----\n// Warning 7239: (73-102): This assignment involves multiple accesses to a bytes array in storage while simultaneously enlarging it. When a bytes array is enlarged, it may transition from short storage layout to long storage layout, which invalidates all references to its elements. It is safer to only enlarge byte arrays in a single operation, one element at a time.\n// Warning 7239: (112-147): This assignment involves multiple accesses to a bytes array in storage while simultaneously enlarging it. When a bytes array is enlarged, it may transition from short storage layout to long storage layout, which invalidates all references to its elements. It is safer to only enlarge byte arrays in a single operation, one element at a time.\n// Warning 7239: (157-203): This assignment involves multiple accesses to a bytes array in storage while simultaneously enlarging it. When a bytes array is enlarged, it may transition from short storage layout to long storage layout, which invalidates all references to its elements. It is safer to only enlarge byte arrays in a single operation, one element at a time.\n// Warning 7239: (213-238): This assignment involves multiple accesses to a bytes array in storage while simultaneously enlarging it. When a bytes array is enlarged, it may transition from short storage layout to long storage layout, which invalidates all references to its elements. It is safer to only enlarge byte arrays in a single operation, one element at a time.\n// Warning 7239: (277-306): This assignment involves multiple accesses to a bytes array in storage while simultaneously enlarging it. When a bytes array is enlarged, it may transition from short storage layout to long storage layout, which invalidates all references to its elements. It is safer to only enlarge byte arrays in a single operation, one element at a time.\n// Warning 7239: (362-391): This assignment involves multiple accesses to a bytes array in storage while simultaneously enlarging it. When a bytes array is enlarged, it may transition from short storage layout to long storage layout, which invalidates all references to its elements. It is safer to only enlarge byte arrays in a single operation, one element at a time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/bytes_to_fixed_bytes.sol",
    "content": "contract C {\n    bytes s;\n    function f(bytes calldata c, string memory m) public view returns (bytes3, bytes8, bytes16, bytes32) {\n        return (bytes3(c[0:3]), bytes8(s), bytes16(c), bytes32(bytes(m)));\n    }\n}\n// ----"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/calldata.sol",
    "content": "pragma abicoder               v2;\ncontract Test {\n    function f(uint[3] calldata) external { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/calldata_assign.sol",
    "content": "pragma abicoder               v2;\ncontract Test {\n    function f(uint256[] calldata s) external { s[0] = 4; }\n}\n// ----\n// TypeError 6182: (98-102): Calldata arrays are read-only.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/calldata_dynamic.sol",
    "content": "pragma abicoder               v2;\ncontract Test {\n    function f(uint[] calldata) external { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/calldata_multi.sol",
    "content": "pragma abicoder               v2;\ncontract Test {\n    function f(uint[3][4] calldata) external { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/calldata_multi_dynamic.sol",
    "content": "pragma abicoder               v2;\ncontract Test {\n    function f(uint[][] calldata) external { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/calldata_multi_dynamic_V1.sol",
    "content": "pragma abicoder v1;\ncontract Test {\n    function f(uint[][] calldata) external { }\n    function g(uint[][1] calldata) external { }\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 4957: (51-68): This type is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n// TypeError 4957: (98-116): This type is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/calldata_resize.sol",
    "content": "contract C {\n    function f (uint256[] calldata x) external pure {\n        x.length = 42;\n    }\n}\n// ----\n// TypeError 7567: (75-83): Member \"length\" is read-only and cannot be used to resize arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/concat/bytes_concat_empty_invalid.sol",
    "content": "contract C {\n    function g() public pure returns (bytes memory) {\n        return bytes.concat;\n    }\n}\n// ----\n// TypeError 6359: (82-94): Return argument type function () pure returns (bytes memory) is not implicitly convertible to expected type (type of first return variable) bytes memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/concat/bytes_concat_on_type_info.sol",
    "content": "contract C {\n    function f() public {\n        bytes memory a;\n        bytes memory b = type(bytes).concat(a);\n    }\n}\n// ----\n// TypeError 4259: (93-98): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(bytes storage pointer) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/concat/bytes_concat_on_variable.sol",
    "content": "contract C {\n    function f() public {\n        bytes memory a;\n        bytes memory b = a.concat();\n    }\n}\n// ----\n// TypeError 9582: (88-96): Member \"concat\" not found or not visible after argument-dependent lookup in bytes memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/concat/bytes_concat_valid_type_literal.sol",
    "content": "contract C {\n    function f() public pure returns (bytes memory) {\n        return bytes.concat(\n            hex\"00\",\n            hex\"aabbcc\",\n            unicode\"abc\",\n            \"123\",\n            \"abc\"\n            \"123456789012345678901234567890123456789012345678901234567890\" // Longer than 32 bytes\n        );\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_bytes_and_strings.sol",
    "content": "contract C {\n    bytes s;\n    function f(bytes calldata c, string calldata c1) public {\n        bytes memory a;\n        bytes16 b;\n        uint8[] memory num;\n        bytes1[] memory m;\n        bytes memory d = bytes.concat(a, b, c, num, s, \"abc\", m, c1, bytes(c1));\n    }\n}\n// ----\n// TypeError 8015: (233-236): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[] memory provided.\n// TypeError 8015: (248-249): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bytes1[] memory provided.\n// TypeError 8015: (251-253): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but string calldata provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_array_literal.sol",
    "content": "contract C {\n    function f() public {\n        bytes.concat([], [], []);\n    }\n}\n// ----\n// TypeError 6378: (60-62): Unable to deduce common type for array elements.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol",
    "content": "contract C {\n    function f() public pure returns (bytes memory) {\n        return bytes.concat(hex\"\", unicode\"\", \"\");\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_misc.sol",
    "content": "contract C {\n    struct S {\n        uint x;\n    }\n\n    enum E {A, B, C}\n\n    mapping(uint => E) m;\n\n    function f() public {\n        bool b;\n        uint u;\n        uint8 u8;\n        address a;\n        address payable ap;\n        function () external fext;\n        function () internal fint;\n        uint[] memory uDynamic;\n        uint[2] memory uStatic;\n        C c;\n        S memory s;\n        E e;\n\n        bytes.concat(b, u, u8, a, ap, fext, fint, uDynamic, uStatic, c, s, e, m);\n    }\n}\n// ----\n// TypeError 8015: (425-426): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bool provided.\n// TypeError 8015: (428-429): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint256 provided.\n// TypeError 8015: (431-433): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8 provided.\n// TypeError 8015: (435-436): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but address provided.\n// TypeError 8015: (438-440): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but address payable provided.\n// TypeError 8015: (442-446): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () external provided.\n// TypeError 8015: (448-452): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () provided.\n// TypeError 8015: (454-462): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint256[] memory provided.\n// TypeError 8015: (464-471): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint256[2] memory provided.\n// TypeError 8015: (473-474): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but contract C provided.\n// TypeError 8015: (476-477): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but struct C.S memory provided.\n// TypeError 8015: (479-480): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but enum C.E provided.\n// TypeError 8015: (482-483): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but mapping(uint256 => enum C.E) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_misc_literals_and_expressions.sol",
    "content": "contract C {\n    struct S {\n        uint x;\n    }\n\n    enum E {A, B, C}\n\n    function f() public {\n        bytes.concat(\n            false,\n            1,\n            1e10,\n            1e-10,\n            0.1,\n            0x1234567,\n            0x11112222333344445555666677778888999900,     // One byte less than an address\n            0x1111222233334444555566667777888899990000,   // Address\n            0x111122223333444455556666777788889999000011, // One byte more than an address\n            0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff,  // exactly 32 bytes\n            -0x0000000000000000000000000000000000000000000000000000000000000001, // exactly 32 bytes\n            bytes(bytes32(0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff))[:],\n            f,\n            (),\n            (0, 0),\n            [0],\n            [0][:],\n            [0][0],\n            new C(),\n            S(0),\n            E.A\n        );\n    }\n}\n// ----\n// TypeError 9640: (697-779): Explicit type conversion not allowed from \"bytes32\" to \"bytes memory\".\n// TypeError 1227: (697-782): Index range access is only supported for dynamic calldata arrays.\n// TypeError 1227: (864-870): Index range access is only supported for dynamic calldata arrays.\n// TypeError 8015: (133-138): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bool provided.\n// TypeError 8015: (152-153): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 1 provided.\n// TypeError 8015: (167-171): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 10000000000 provided.\n// TypeError 8015: (185-190): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but rational_const 1 / 10000000000 provided.\n// TypeError 8015: (204-207): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but rational_const 1 / 10 provided.\n// TypeError 8015: (221-230): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 19088743 provided.\n// TypeError 8015: (244-284): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 3806...(37 digits omitted)...1680 provided.\n// TypeError 8015: (335-377): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but address provided.\n// TypeError 8015: (404-448): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 2494...(42 digits omitted)...0497 provided.\n// TypeError 8015: (495-561): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 3027...(66 digits omitted)...5855 provided.\n// TypeError 8015: (596-663): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const -1 provided.\n// TypeError 8015: (697-782): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but bytes memory slice provided.\n// TypeError 8015: (796-797): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but function () provided.\n// TypeError 8015: (811-813): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but tuple() provided.\n// TypeError 8015: (827-833): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but tuple(int_const 0,int_const 0) provided.\n// TypeError 8015: (847-850): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[1] memory provided.\n// TypeError 8015: (864-870): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8[1] memory slice provided.\n// TypeError 8015: (884-890): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but uint8 provided.\n// TypeError 8015: (904-911): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but contract C provided.\n// TypeError 8015: (925-929): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but struct C.S memory provided.\n// TypeError 8015: (943-946): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but enum C.E provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_zero_literal.sol",
    "content": "contract C {\n    function f() public pure {\n        bytes.concat(\n            0,\n            -0,\n            0.0,\n            -0.0,\n            0e10,\n            -0e10,\n            0e-10,\n            -0e-10,\n            (0),\n            0x00,\n            -0x00,\n            0x0000000000000000000000000000000000000000000000000000000000000000, // exactly 32 bytes\n            -0x0000000000000000000000000000000000000000000000000000000000000000 // exactly 32 bytes\n        );\n    }\n}\n// ----\n// TypeError 8015: (78-79): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (93-95): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (109-112): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (126-130): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (144-148): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (162-167): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (181-186): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (200-206): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (220-223): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (237-241): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (255-260): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (274-340): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n// TypeError 8015: (374-441): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but int_const 0 provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/contract_array.sol",
    "content": "contract C {\n    C[] y = new C[](3);\n    C[3] x;\n    function f() public {\n        C[3] memory z;\n        y.push(this);\n        x[0] = this;\n        z[0] = this;\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/contract_index_access.sol",
    "content": "contract C {\n    function f() view public {\n        C[0];\n    }\n}\n// ----\n// Warning 6133: (52-56): Statement has no effect.\n// Warning 2018: (17-63): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/copy_calldata_struct_array_to_storage_legacy.sol",
    "content": "contract C {\n    struct S {\n        uint256 a;\n        uint256 b;\n    }\n\n    S[] storageArray;\n\n    function copyFromCalldata(S[] calldata calldataArray) public {\n        storageArray = calldataArray;\n    }\n}\n// ====\n// compileViaYul: false\n// ----\n// 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).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/copy_from_function_type.sol",
    "content": "// Example from https://github.com/argotorg/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n  function() external[1][] s0;\n  constructor(function() external[1][] memory i0)\n  {\n    i0[0] = s0[1];\n  }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/copy_memory_struct_array_to_storage_legacy.sol",
    "content": "contract C {\n    struct S {\n        uint256 a;\n        uint256 b;\n    }\n\n    S[] storageArray;\n\n    function copyFromMemory() public {\n        S[] memory memArray = new S[](3);\n        storageArray = memArray;\n    }\n}\n// ====\n// compileViaYul: false\n// ----\n// 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).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/copy_storage_arrays_of_function_type.sol",
    "content": "contract C {\n    function() external [] s0;\n    function() external view [] s1;\n    function copyStorageArrayOfFunctionType() public {\n        s1 = s0;\n    }\n}\n// ----\n// TypeError 7407: (148-150): Type function () external[] storage ref is not implicitly convertible to expected type function () view external[] storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/dynamic_memory_array_pop.sol",
    "content": "contract C {\n    function test() public {\n      uint[] memory data;\n      data.pop();\n    }\n}\n// ----\n// TypeError 4994: (74-82): Member \"pop\" is not available in uint256[] memory outside of storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/function_mapping.sol",
    "content": "pragma abicoder               v2;\n\ncontract Test {\n    function f(mapping(uint => uint)[] memory x) public pure {}\n}\n// ----\n// TypeError 4103: (66-98): Types containing (nested) mappings can only be parameters or return variables of internal or library functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/function_mapping_library.sol",
    "content": "pragma abicoder               v2;\nlibrary L {\n    function f(mapping(uint => uint)[2] memory a) external pure returns (mapping(uint => uint)[2] memory) {}\n}\n// ----\n// TypeError 4061: (61-94): Type mapping(uint256 => uint256)[2] memory is only valid in storage because it contains a (nested) mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/invalid/bytes_to_fixed_bytes.sol",
    "content": "contract C {\n    bytes s;\n    function f(bytes calldata c, string memory m) public view returns (bytes3 r1, bytes16 r2, bytes32 r3) {\n        require(c.length >= 3, \"\");\n        r2 = s;\n        r1 = c[0:3];\n        r3 = bytes32(m);\n        r3 = m;\n    }\n}\n// ----\n// TypeError 7407: (183-184): Type bytes storage ref is not implicitly convertible to expected type bytes16.\n// TypeError 7407: (199-205): Type bytes calldata slice is not implicitly convertible to expected type bytes3.\n// TypeError 9640: (220-230): Explicit type conversion not allowed from \"string memory\" to \"bytes32\".\n// TypeError 7407: (245-246): Type string memory is not implicitly convertible to expected type bytes32.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/invalid/library_array.sol",
    "content": "library L {}\ncontract C {\n\tfunction f() public {\n\t\tL[] memory x;\n\t}\n}\n// ----\n// TypeError 1130: (51-52): Invalid use of a library name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/invalid/library_index_access.sol",
    "content": "library C {\n    function f() view public {\n        C[0];\n    }\n}\n// ----\n// TypeError 2876: (51-55): Index access for library types and arrays of libraries are not possible.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/invalidCopy/calldata_to_memory_different_base.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n        bytes10[] memory m = c;\n        return (m.length, m[0], m[1], m[2]);\n    }\n}\n// ----\n// TypeError 9574: (134-156): Type bytes8[] calldata is not implicitly convertible to expected type bytes10[] memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/invalidCopy/storage_to_memory_different_base.sol",
    "content": "pragma abicoder v2;\n\ncontract C {\n    bytes8[] s;\n    function f() external returns (uint256, bytes10, bytes10, bytes10) {\n        s.push(\"abcd\");\n        s.push(\"bcde\");\n        s.push(\"cdef\");\n        bytes10[] memory m = s;\n        return (m.length, m[0], m[1], m[2]);\n    }\n}\n// ----\n// TypeError 9574: (203-225): Type bytes8[] storage ref is not implicitly convertible to expected type bytes10[] memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/invalidCopy/storage_to_storage_different_base.sol",
    "content": "contract C {\n    bytes1[32] data1;\n    bytes2[10] data2;\n    function f() external {\n        data1 = data2;\n    }\n}\n// ----\n// TypeError 7407: (101-106): Type bytes2[10] storage ref is not implicitly convertible to expected type bytes1[32] storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/invalidCopy/storage_to_storage_different_base_2.sol",
    "content": "contract C {\n    uint64[32] data1;\n    uint256[10] data2;\n    function f() external {\n        data1 = data2;\n    }\n}\n// ----\n// TypeError 7407: (102-107): Type uint256[10] storage ref is not implicitly convertible to expected type uint64[32] storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/invalidCopy/storage_to_storage_different_sign.sol",
    "content": "contract C {\n    int256[32] data1;\n    uint256[10] data2;\n    function f() external {\n        data1 = data2;\n    }\n    function g() external {\n        data2 = data1;\n    }\n}\n// ----\n// TypeError 7407: (102-107): Type uint256[10] storage ref is not implicitly convertible to expected type int256[32] storage ref.\n// TypeError 7407: (159-164): Type int256[32] storage ref is not implicitly convertible to expected type uint256[10] storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/invalidCopy/storage_to_storage_dynamic_to_static.sol",
    "content": "contract C {\n    uint256[10] data1;\n    uint256[] data2;\n    function f() external {\n        data1 = data2;\n    }\n}\n// ----\n// TypeError 7407: (101-106): Type uint256[] storage ref is not implicitly convertible to expected type uint256[10] storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/invalidCopy/storage_to_storage_static_longer_to_shorter.sol",
    "content": "contract C {\n    uint256[10] data1;\n    uint256[18] data2;\n    function f() external {\n        data1 = data2;\n    }\n}\n// ----\n// TypeError 7407: (103-108): Type uint256[18] storage ref is not implicitly convertible to expected type uint256[10] storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/abi_decode_length_too_large.sol",
    "content": "// Used to cause ICE\ncontract C {\n\tfunction f() public {\n\t\tabi.decode(\"\", (bytes1[999999999]));\n\t}\n}\n// ----\n// TypeError 6118: (75-92): Type too large for memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/array_length_cannot_be_constant_function_parameter.sol",
    "content": "contract C {\n    function f(uint constant LEN) public {\n        uint[LEN] a;\n    }\n}\n// ----\n// DeclarationError 1788: (28-45): The \"constant\" keyword can only be used for state variables or variables at file level.\n// TypeError 5462: (69-72): Invalid array length, expected integer literal or constant expression.\n// TypeError 6651: (64-75): Data location must be \"storage\", \"memory\" or \"calldata\" for variable, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/builtin_erc7201_comptime.sol",
    "content": "contract C {\n    uint[erc7201(\"length\")] array;\n}\n// ----\n// Warning 7325: (17-40): Type uint256[91485909057496517105622548919236807895873764128784270125752891283919605191424] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/bytes32_too_large.sol",
    "content": "contract C {\n    bytes32[8**90] ids;\n}\n// ----\n// TypeError 1847: (25-30): Array length too large, maximum is 2**256 - 1.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/bytes32_too_large_multidim.sol",
    "content": "contract C {\n    bytes32[8**90][500] ids;\n}\n// ----\n// TypeError 1847: (25-30): Array length too large, maximum is 2**256 - 1.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/can_be_constant_in_function.sol",
    "content": "contract C {\n    uint constant LEN = 10;\n    function f() public pure {\n        uint[LEN] memory a;\n        a;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/can_be_constant_in_struct.sol",
    "content": "contract C {\n    uint constant LEN = 10;\n    struct Test {\n        uint[LEN] ids;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/can_be_recursive_constant.sol",
    "content": "contract C {\n    uint constant L = 5;\n    uint constant LEN = L + 4 * L;\n    uint[LEN] ids;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/cannot_be_assigned.sol",
    "content": "contract c {\n    uint[] storageArray;\n    function f() public {\n        storageArray.length = 3;\n    }\n}\n// ----\n// TypeError 7567: (72-91): Member \"length\" is read-only and cannot be used to resize arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/cannot_be_assigned_mapping.sol",
    "content": "contract C {\n    mapping(uint => uint[]) map;\n    function f() public {\n        map[0].length = 4;\n    }\n}\n// ----\n// TypeError 7567: (80-93): Member \"length\" is read-only and cannot be used to resize arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/cannot_be_assigned_struct.sol",
    "content": "contract C {\n    struct S {\n        uint[] a;\n    }\n    S s;\n    function f() public {\n        s.a.length = 4;\n    }\n}\n// ----\n// TypeError 7567: (95-105): Member \"length\" is read-only and cannot be used to resize arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/cannot_be_function.sol",
    "content": "contract C {\n    function f() public {}\n    uint[f] ids;\n}\n// ----\n// TypeError 5462: (49-50): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/cannot_be_function_call.sol",
    "content": "contract C {\n    function f(uint x) public {}\n    uint constant LEN = f();\n    uint[LEN] ids;\n}\n// ----\n// TypeError 5462: (84-87): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/complex_cyclic_constant.sol",
    "content": "contract C {\n    uint constant L2 = LEN - 10;\n    uint constant L1 = L2 / 10;\n    uint constant LEN = 10 + L1 * 5;\n    function f() public {\n        uint[LEN] a;\n    }\n}\n// ----\n// TypeError 5210: (17-44): Cyclic constant definition (or maximum recursion depth exhausted).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/const_cannot_be_fractional.sol",
    "content": "contract C {\n    fixed constant L = 10.5;\n    uint[L] ids;\n}\n// ----\n// TypeError 5462: (51-52): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/constant_var.sol",
    "content": "contract C {\n    uint constant LEN = 10;\n    uint[LEN] ids;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/cyclic_constant.sol",
    "content": "contract C {\n    uint constant LEN = LEN;\n    function f() public {\n        uint[LEN] a;\n    }\n}\n// ----\n// TypeError 5210: (17-40): Cyclic constant definition (or maximum recursion depth exhausted).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/fixed_size_multidim_zero_length.sol",
    "content": "contract C {\n  function a() public pure returns(int[0][500] memory) {}\n  function b() public pure returns(uint[0][500] memory) {}\n  function c() public pure returns(bytes1[0][500] memory) {}\n  function d() public pure returns(bytes32[0][500] memory) {}\n  function e() public pure returns(bytes[0][500] memory) {}\n  function e() public pure returns(string[0][500] memory) {}\n}\n// ----\n// TypeError 1406: (52-53): Array with zero length specified.\n// TypeError 1406: (111-112): Array with zero length specified.\n// TypeError 1406: (172-173): Array with zero length specified.\n// TypeError 1406: (234-235): Array with zero length specified.\n// TypeError 1406: (294-295): Array with zero length specified.\n// TypeError 1406: (355-356): Array with zero length specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/fixed_size_zero_length.sol",
    "content": "contract C {\n  int[0] a;\n  uint[0] b;\n  bytes1[0] c;\n  bytes32[0] d;\n  bytes[0] e;\n  string[0] f;\n}\n// ----\n// TypeError 1406: (19-20): Array with zero length specified.\n// TypeError 1406: (32-33): Array with zero length specified.\n// TypeError 1406: (47-48): Array with zero length specified.\n// TypeError 1406: (63-64): Array with zero length specified.\n// TypeError 1406: (77-78): Array with zero length specified.\n// TypeError 1406: (92-93): Array with zero length specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/inline_array.sol",
    "content": "contract C {\n    uint[[2]] a15;\n}\n// ----\n// TypeError 5462: (22-25): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/invalid_expression_1.sol",
    "content": "contract C {\n    uint[-true] ids;\n}\n// ----\n// TypeError 5462: (22-27): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/invalid_expression_2.sol",
    "content": "contract C {\n    uint[true/1] ids;\n}\n// ----\n// TypeError 5462: (22-28): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/invalid_expression_3.sol",
    "content": "contract C {\n    uint[1/true] ids;\n}\n// ----\n// TypeError 5462: (22-28): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/invalid_expression_4.sol",
    "content": "contract C {\n    uint[1.111111E1111111111111] ids;\n}\n// ----\n// TypeError 5462: (22-44): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/invalid_expression_5.sol",
    "content": "contract C {\n    uint[3/0] ids;\n}\n// ----\n// TypeError 6020: (22-25): Operator / not compatible with types int_const 3 and int_const 0\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/literal_conversion.sol",
    "content": "contract C {\n    uint[uint(1)] valid_size_invalid_expr1;\n    uint[uint(2**256-1)] valid_size_invalid_expr2;\n    uint[uint(2**256)] invalid_size_invalid_expr3;\n\n    uint[int(1)] valid_size_invalid_expr4;\n    uint[int(2**256-1)] valid_size_invalid_expr5;\n    uint[int(2**256)] invalid_size_invalid_expr6;\n}\n// ----\n// TypeError 5462: (22-29): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (66-80): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (117-129): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (169-175): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (212-225): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (262-273): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/local_memory_too_large.sol",
    "content": "contract C {\n  function f() public pure\n  {\n    bytes32[1263941234127518272][500] memory x;\n    uint[2**30][] memory y;\n    uint[2**30][2**30][] memory z;\n    uint[2**16][2**16][] memory w;\n  }\n}\n// ----\n// TypeError 1534: (48-90): Type too large for memory.\n// TypeError 1534: (96-118): Type too large for memory.\n// TypeError 1534: (124-153): Type too large for memory.\n// TypeError 1534: (159-188): Type too large for memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/non_integer_constant_var.sol",
    "content": "contract C {\n    bool constant LEN = true;\n    uint[LEN] ids;\n}\n// ----\n// TypeError 5462: (52-55): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/not_convertible_to_integer.sol",
    "content": "contract C {\n    uint[true] ids;\n}\n// ----\n// TypeError 5462: (22-26): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/parameter_too_large.sol",
    "content": "contract C {\n  function f(bytes32[1263941234127518272] memory) public pure {}\n}\n// ----\n// TypeError 1534: (26-61): Type too large for memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/parameter_too_large_multidim.sol",
    "content": "contract C {\n  function f(bytes32[1263941234127518272][500] memory) public pure {}\n  function f(uint[2**30][] memory) public pure {}\n  function f(uint[2**30][2**30][] memory) public pure {}\n  function f(uint[2**16][2**16][] memory) public pure {}\n}\n// ----\n// TypeError 1534: (26-66): Type too large for memory.\n// TypeError 1534: (96-116): Type too large for memory.\n// TypeError 1534: (146-173): Type too large for memory.\n// TypeError 1534: (203-230): Type too large for memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/parameter_too_large_multidim_ABIv2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n  function f(bytes32[1263941234127518272][500] memory) public pure {}\n  function f(uint[2**30][2**30][][] memory) public pure {}\n}\n// ----\n// TypeError 1534: (61-101): Type too large for memory.\n// TypeError 1534: (131-160): Type too large for memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/parentheses.sol",
    "content": "contract C {\n    uint constant L1 = (2);\n    uint constant L2 = ((2));\n    uint constant L3 = ((((2))));\n    uint constant L4 = (2 + 1);\n    uint constant L5 = ((2 + 1));\n    uint constant L6 = (((2) + ((1))));\n    uint constant L7 = (2 + 1) / 1;\n    uint constant L8 = (2 + ((1))) / (1);\n    uint[L1] a1;\n    uint[L2] a2;\n    uint[L3] a3;\n    uint[L4] a4;\n    uint[L5] a5;\n    uint[L6] a6;\n    uint[L7] a7;\n    uint[L8] a8;\n    uint[(2)] a9;\n    uint[(2 + 1)] a10;\n    uint[(2 + 1) + 1] a11;\n    uint[((2) + 1) + 1] a12;\n    uint[(2 + 1) + ((1))] a13;\n    uint[(((2) + 1)) + (((1)))] a14;\n    uint[((((3) + 1)) + (((1))))%2] a15;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/pure_functions.sol",
    "content": "contract C {\n    uint constant LEN = keccak256(ripemd160(33));\n    uint[LEN] ids;\n}\n// ----\n// TypeError 5462: (72-75): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/string_as_array_length.sol",
    "content": "contract C {\n    string constant length = \"length\";\n    uint[\"length\"] literalString;\n    uint[length] variableString;\n}\n// ----\n// TypeError 5462: (61-69): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (95-101): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/too_large.sol",
    "content": "contract C {\n    uint[8**90] ids;\n    uint[2**256-1] okay;\n    uint[2**256] tooLarge;\n}\n// ----\n// TypeError 1847: (22-27): Array length too large, maximum is 2**256 - 1.\n// TypeError 1847: (68-74): Array length too large, maximum is 2**256 - 1.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/tuples.sol",
    "content": "contract C {\n    uint[(1,2)] a15;\n}\n// ----\n// TypeError 5462: (22-27): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/length/uint_too_large_multidim.sol",
    "content": "contract C {\n    uint[8**90][500] ids;\n}\n// ----\n// TypeError 1847: (22-27): Array length too large, maximum is 2**256 - 1.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/library_array.sol",
    "content": "library L {}\ncontract C {\n  function f() public pure {\n    new L[](2);\n  }\n}\n// ----\n// TypeError 1130: (63-64): Invalid use of a library name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/nested_calldata_memory.sol",
    "content": "pragma abicoder               v2;\n\ncontract Test {\n    struct shouldBug {\n        bytes[2] deadly;\n    }\n    function killer(bytes[2] calldata weapon) pure external {\n      shouldBug(weapon);\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/nested_calldata_memory2.sol",
    "content": "pragma abicoder               v2;\n\ncontract Test {\n    struct shouldBug {\n        uint256[][2] deadly;\n    }\n    function killer(uint256[][2] calldata weapon) pure external {\n      shouldBug(weapon);\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/nested_calldata_memory3.sol",
    "content": "pragma abicoder               v2;\n\ncontract Test {\n    struct shouldBug {\n        uint256[][] deadly;\n    }\n    function killer(uint256[][] calldata weapon) pure external {\n      shouldBug(weapon);\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/nested_calldata_storage.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n  uint[][2] tmp_i;\n  function i(uint[][2] calldata s) external { tmp_i = s; }\n}\n\n// ====\n// compileViaYul: false\n// ----\n// UnimplementedFeatureError 1834: (35-127): Copying nested calldata dynamic arrays to storage is not implemented in the old code generator.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n  uint[][] tmp_i;\n  function i(uint[][] calldata s) external { tmp_i = s; }\n}\n\n// ====\n// compileViaYul: false\n// ----\n// UnimplementedFeatureError 1834: (35-125): Copying nested calldata dynamic arrays to storage is not implemented in the old code generator.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/new_no_parentheses.sol",
    "content": "contract C {\n    function f(uint size) public {\n        new uint[1];\n    }\n}\n// ----\n// TypeError 3904: (60-67): Length has to be placed in parentheses after the array type for new expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/no_array_pop.sol",
    "content": "contract C {\n    uint data;\n    function test() public {\n      data.pop();\n    }\n}\n// ----\n// TypeError 9582: (63-71): Member \"pop\" not found or not visible after argument-dependent lookup in uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/pop/calldata_pop.sol",
    "content": "contract C {\n    function f(uint[] calldata x) external {\n        x.pop();\n    }\n}\n// ----\n// TypeError 4994: (66-71): Member \"pop\" is not available in uint256[] calldata outside of storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/pop/memory_pop.sol",
    "content": "contract C {\n    function f() public {\n        uint[] memory x;\n        x.pop();\n    }\n}\n// ----\n// TypeError 4994: (72-77): Member \"pop\" is not available in uint256[] memory outside of storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/pop/storage_with_mapping_pop.sol",
    "content": "contract C {\n    mapping(uint=>uint)[] array;\n    mapping(uint=>uint) map;\n    function f() public {\n        array.pop();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/push/calldata_push.sol",
    "content": "contract C {\n    function f(uint[] calldata x) external {\n        x.push();\n    }\n}\n// ----\n// TypeError 4994: (66-72): Member \"push\" is not available in uint256[] calldata outside of storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/push/memory_push.sol",
    "content": "contract C {\n    function f() public {\n        uint[] memory x;\n        x.push();\n    }\n}\n// ----\n// TypeError 4994: (72-78): Member \"push\" is not available in uint256[] memory outside of storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/push/storage_with_mapping_push.sol",
    "content": "contract C {\n    mapping(uint=>uint)[] array;\n    mapping(uint=>uint) map;\n    function f() public {\n        array.push();\n        array.push(map);\n    }\n}\n// ----\n// TypeError 8871: (131-141): Storage arrays with nested mappings do not support .push(<arg>).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/assign_to_storage.sol",
    "content": "contract c {\n  bytes public b;\n  function f() public {\n    b = msg.data[:];\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/bytes_calldata.sol",
    "content": "contract C {\n    function f(bytes calldata x) external pure {\n        x[1:2];\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/bytes_memory.sol",
    "content": "contract C {\n    function f(bytes memory x) public pure {\n        x[1:2];\n    }\n}\n// ----\n// TypeError 1227: (66-72): Index range access is only supported for dynamic calldata arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/bytes_storage.sol",
    "content": "contract C {\n    bytes x;\n    function f() public view {\n        x[1:2];\n    }\n}\n// ----\n// TypeError 1227: (65-71): Index range access is only supported for dynamic calldata arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/calldata_dynamic.sol",
    "content": "contract C {\n    function f(uint256[] calldata x) external pure {\n        x[1:2];\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/calldata_dynamic_access.sol",
    "content": "contract C {\n    function f(uint256[] calldata x) external pure {\n        x[1:2][0];\n        x[1:][0];\n        x[1:][1:2][0];\n        x[1:2][1:][0];\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/calldata_dynamic_convert_to_memory.sol",
    "content": "contract C {\n    function f(bytes calldata x) external pure returns (bytes memory) {\n        return x[1:2];\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/calldata_dynamic_encode.sol",
    "content": "contract C {\n    function f(uint256[] calldata x) external pure {\n        abi.encode(x[1:2]);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/calldata_dynamic_forward.sol",
    "content": "contract C {\n    function f(bytes calldata x) external {\n        return this.f(x[1:2]);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/calldata_static.sol",
    "content": "contract C {\n    function f(uint256[42] calldata x) external pure {\n        x[1:2];\n    }\n}\n// ----\n// TypeError 1227: (76-82): Index range access is only supported for dynamic calldata arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/member_access.sol",
    "content": "// Used to cause ICE\ncontract C {\n    function f(uint[] calldata x) external pure {\n        x[1:2].a;\n    }\n}\n// ----\n// TypeError 9582: (92-100): Member \"a\" not found or not visible after argument-dependent lookup in uint256[] calldata slice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/memory_dynamic.sol",
    "content": "contract C {\n    function f(uint256[] memory x) public pure {\n        x[1:2];\n    }\n}\n// ----\n// TypeError 1227: (70-76): Index range access is only supported for dynamic calldata arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/memory_static.sol",
    "content": "contract C {\n    function f(uint256[42] memory x) public pure {\n        x[1:2];\n    }\n}\n// ----\n// TypeError 1227: (72-78): Index range access is only supported for dynamic calldata arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/slice_literal.sol",
    "content": "contract C {\n    function f() public pure {\n        1[1:];\n    }\n}\n// ----\n// TypeError 4781: (52-57): Index range access is only possible for arrays and array slices.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/slice_memory_bytes.sol",
    "content": "contract C {\n    function f() public pure {\n        bytes memory y;\n        y[1:2];\n    }\n}\n// ----\n// TypeError 1227: (76-82): Index range access is only supported for dynamic calldata arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/slice_memory_string.sol",
    "content": "contract C {\n    function f() public pure {\n        string memory y;\n        y[1:2];\n    }\n}\n// ----\n// TypeError 1227: (77-83): Index range access is only supported for dynamic calldata arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/slice_string.sol",
    "content": "contract C {\n    function f() public pure {\n        \"\"[1:];\n    }\n}\n// ----\n// TypeError 4781: (52-58): Index range access is only possible for arrays and array slices.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/storage_dynamic.sol",
    "content": "contract C {\n    uint256[] x;\n    function f() public view {\n        x[1:2];\n    }\n}\n// ----\n// TypeError 1227: (69-75): Index range access is only supported for dynamic calldata arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/slice/storage_static.sol",
    "content": "contract C {\n    uint256[42] x;\n    function f() public view {\n        x[1:2];\n    }\n}\n// ----\n// TypeError 1227: (71-77): Index range access is only supported for dynamic calldata arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/static_storage_array_pop.sol",
    "content": "contract C {\n    uint[3] data;\n    function test() public {\n      data.pop();\n    }\n}\n// ----\n// TypeError 9582: (66-74): Member \"pop\" not found or not visible after argument-dependent lookup in uint256[3] storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/string_pop.sol",
    "content": "contract C {\n    string data;\n    function test() public {\n      data.pop();\n    }\n}\n// ----\n// TypeError 9582: (65-73): Member \"pop\" not found or not visible after argument-dependent lookup in string storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/array/uninitialized_storage_var.sol",
    "content": "contract C {\n\tfunction f() public {\n\t\tuint[] storage x;\n\t\tuint[10] storage y;\n\t\tx;\n\t\ty;\n\t}\n}\n// ----\n// TypeError 3464: (80-81): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (85-86): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_complex.sol",
    "content": "contract D {}\ncontract C is D {}\ncontract E is D\n{\n\tfunction foo() public { new C(); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_complex1.sol",
    "content": "contract A { function foo() public { new D(); } }\ncontract C { function foo() public { new A(); } }\ncontract D is C {}\n// ----\n// TypeError 7813: (37-42): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (87-92): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_free_function.sol",
    "content": "function f()\n{\n\tnew D();\n}\n\ncontract D\n{\n\treceive() external payable { f; }\n}\n// ----\n// TypeError 7813: (16-21): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_function_parameters.sol",
    "content": "contract C { function foo(D _d) public { _d.foo(this); } }\ncontract D { function foo(C _c) public { _c.foo(this); } }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_function.sol",
    "content": "contract C\n{\n\t// Internal uncalled function should not cause a cyclic dep. error\n\tfunction foo() internal { new D(); }\n\tfunction callFoo() virtual public { foo(); }\n}\n\ncontract D is C\n{\n\tfunction callFoo() override public {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_internal_functions.sol",
    "content": "contract C { function foo() internal { new D(); } }\ncontract D { function foo() internal { new C(); } }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_libraries.sol",
    "content": "library L1 { function foo() internal { L2.foo(); } }\nlibrary L2 { function foo() internal { L1.foo(); } }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_mention_only.sol",
    "content": "contract C {\n\tfunction foo() public pure { D; }\n}\ncontract D {\n\tfunction foo() public pure { C; }\n}\n// ----\n// Warning 6133: (43-44): Statement has no effect.\n// Warning 6133: (93-94): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_new_in_ctor.sol",
    "content": "contract C {\n\tconstructor() { new C(); }\n}\n// ----\n// TypeError 7813: (30-35): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_report_first_in_cycle.sol",
    "content": "contract A { B x = new B(); }\ncontract B { C x = new C(); }\ncontract C { D x = new D(); }\ncontract D { E x = new E(); }\ncontract E { F x = new F(); }\ncontract F { E x = new E(); }\n// ----\n// TypeError 7813: (19-24): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (49-54): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (79-84): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (109-114): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (139-144): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (169-174): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/circular_reference_type_mention_only.sol",
    "content": "contract C {\n\tfunction foo() public pure { type(D); }\n}\ncontract D {\n\tfunction foo() public pure { type(C); }\n}\n// ----\n// Warning 6133: (43-50): Statement has no effect.\n// Warning 6133: (99-106): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/cyclic_dep_exhaustion.sol",
    "content": "contract D {\n    function f() public {\n        new C();\n    }\n}\ncontract C {\n    constructor() { new C2(); }\n}\ncontract C2 {\n    constructor() { new C3(); }\n}\ncontract C3 {\n    constructor() { new C4(); }\n}\ncontract C4 {\n    constructor() { new C5(); }\n}\ncontract C5 {\n    constructor() { new C6(); }\n}\ncontract C6 {\n    constructor() { new C7(); }\n}\ncontract C7 {\n    constructor() { new C8(); }\n}\ncontract C8 {\n    constructor() { new C9(); }\n}\ncontract C9 {\n    constructor() { new C10(); }\n}\ncontract C10 {\n    constructor() { new C11(); }\n}\ncontract C11 {\n    constructor() { new C12(); }\n}\ncontract C12 {\n    constructor() { new C13(); }\n}\ncontract C13 {\n    constructor() { new C14(); }\n}\ncontract C14 {\n    constructor() { new C15(); }\n}\ncontract C15 {\n    constructor() { new C16(); }\n}\ncontract C16 {\n    constructor() { new C17(); }\n}\ncontract C17 {\n    constructor() { new C18(); }\n}\ncontract C18 {\n    constructor() { new C19(); }\n}\ncontract C19 {\n    constructor() { new C20(); }\n}\ncontract C20 {\n    constructor() { new C21(); }\n}\ncontract C21 {\n    constructor() { new C22(); }\n}\ncontract C22 {\n    constructor() { new C23(); }\n}\ncontract C23 {\n    constructor() { new C24(); }\n}\ncontract C24 {\n    constructor() { new C25(); }\n}\ncontract C25 {\n    constructor() { new C26(); }\n}\ncontract C26 {\n    constructor() { new C27(); }\n}\ncontract C27 {\n    constructor() { new C28(); }\n}\ncontract C28 {\n    constructor() { new C29(); }\n}\ncontract C29 {\n    constructor() { new C30(); }\n}\ncontract C30 {\n    constructor() { new C31(); }\n}\ncontract C31 {\n    constructor() { new C32(); }\n}\ncontract C32 {\n    constructor() { new C33(); }\n}\ncontract C33 {\n    constructor() { new C34(); }\n}\ncontract C34 {\n    constructor() { new C35(); }\n}\ncontract C35 {\n    constructor() { new C36(); }\n}\ncontract C36 {\n    constructor() { new C37(); }\n}\ncontract C37 {\n    constructor() { new C38(); }\n}\ncontract C38 {\n    constructor() { new C39(); }\n}\ncontract C39 {\n    constructor() { new C40(); }\n}\ncontract C40 {\n    constructor() { new C41(); }\n}\ncontract C41 {\n    constructor() { new C42(); }\n}\ncontract C42 {\n    constructor() { new C43(); }\n}\ncontract C43 {\n    constructor() { new C44(); }\n}\ncontract C44 {\n    constructor() { new C45(); }\n}\ncontract C45 {\n    constructor() { new C46(); }\n}\ncontract C46 {\n    constructor() { new C47(); }\n}\ncontract C47 {\n    constructor() { new C48(); }\n}\ncontract C48 {\n    constructor() { new C49(); }\n}\ncontract C49 {\n    constructor() { new C50(); }\n}\ncontract C50 {\n    constructor() { new C51(); }\n}\ncontract C51 {\n    constructor() { new C52(); }\n}\ncontract C52 {\n    constructor() { new C53(); }\n}\ncontract C53 {\n    constructor() { new C54(); }\n}\ncontract C54 {\n    constructor() { new C55(); }\n}\ncontract C55 {\n    constructor() { new C56(); }\n}\ncontract C56 {\n    constructor() { new C57(); }\n}\ncontract C57 {\n    constructor() { new C58(); }\n}\ncontract C58 {\n    constructor() { new C59(); }\n}\ncontract C59 {\n    constructor() { new C60(); }\n}\ncontract C60 {\n    constructor() { new C61(); }\n}\ncontract C61 {\n    constructor() { new C62(); }\n}\ncontract C62 {\n    constructor() { new C63(); }\n}\ncontract C63 {\n    constructor() { new C64(); }\n}\ncontract C64 {\n    constructor() { new C65(); }\n}\ncontract C65 {\n    constructor() { new C66(); }\n}\ncontract C66 {\n    constructor() { new C67(); }\n}\ncontract C67 {\n    constructor() { new C68(); }\n}\ncontract C68 {\n    constructor() { new C69(); }\n}\ncontract C69 {\n    constructor() { new C70(); }\n}\ncontract C70 {\n    constructor() { new C71(); }\n}\ncontract C71 {\n    constructor() { new C72(); }\n}\ncontract C72 {\n    constructor() { new C73(); }\n}\ncontract C73 {\n    constructor() { new C74(); }\n}\ncontract C74 {\n    constructor() { new C75(); }\n}\ncontract C75 {\n    constructor() { new C76(); }\n}\ncontract C76 {\n    constructor() { new C77(); }\n}\ncontract C77 {\n    constructor() { new C78(); }\n}\ncontract C78 {\n    constructor() { new C79(); }\n}\ncontract C79 {\n    constructor() { new C80(); }\n}\ncontract C80 {\n    constructor() { new C81(); }\n}\ncontract C81 {\n    constructor() { new C82(); }\n}\ncontract C82 {\n    constructor() { new C83(); }\n}\ncontract C83 {\n    constructor() { new C84(); }\n}\ncontract C84 {\n    constructor() { new C85(); }\n}\ncontract C85 {\n    constructor() { new C86(); }\n}\ncontract C86 {\n    constructor() { new C87(); }\n}\ncontract C87 {\n    constructor() { new C88(); }\n}\ncontract C88 {\n    constructor() { new C89(); }\n}\ncontract C89 {\n    constructor() { new C90(); }\n}\ncontract C90 {\n    constructor() { new C91(); }\n}\ncontract C91 {\n    constructor() { new C92(); }\n}\ncontract C92 {\n    constructor() { new C93(); }\n}\ncontract C93 {\n    constructor() { new C94(); }\n}\ncontract C94 {\n    constructor() { new C95(); }\n}\ncontract C95 {\n    constructor() { new C96(); }\n}\ncontract C96 {\n    constructor() { new C97(); }\n}\ncontract C97 {\n    constructor() { new C98(); }\n}\ncontract C98 {\n    constructor() { new C99(); }\n}\ncontract C99 {\n    constructor() { new C100(); }\n}\ncontract C100 {\n    constructor() { new C101(); }\n}\ncontract C101 {\n    constructor() { new C102(); }\n}\ncontract C102 {\n    constructor() { new C103(); }\n}\ncontract C103 {\n    constructor() { new C104(); }\n}\ncontract C104 {\n    constructor() { new C105(); }\n}\ncontract C105 {\n    constructor() { new C106(); }\n}\ncontract C106 {\n    constructor() { new C107(); }\n}\ncontract C107 {\n    constructor() { new C108(); }\n}\ncontract C108 {\n    constructor() { new C109(); }\n}\ncontract C109 {\n    constructor() { new C110(); }\n}\ncontract C110 {\n    constructor() { new C111(); }\n}\ncontract C111 {\n    constructor() { new C112(); }\n}\ncontract C112 {\n    constructor() { new C113(); }\n}\ncontract C113 {\n    constructor() { new C114(); }\n}\ncontract C114 {\n    constructor() { new C115(); }\n}\ncontract C115 {\n    constructor() { new C116(); }\n}\ncontract C116 {\n    constructor() { new C117(); }\n}\ncontract C117 {\n    constructor() { new C118(); }\n}\ncontract C118 {\n    constructor() { new C119(); }\n}\ncontract C119 {\n    constructor() { new C120(); }\n}\ncontract C120 {\n    constructor() { new C121(); }\n}\ncontract C121 {\n    constructor() { new C122(); }\n}\ncontract C122 {\n    constructor() { new C123(); }\n}\ncontract C123 {\n    constructor() { new C124(); }\n}\ncontract C124 {\n    constructor() { new C125(); }\n}\ncontract C125 {\n    constructor() { new C126(); }\n}\ncontract C126 {\n    constructor() { new C127(); }\n}\ncontract C127 {\n    constructor() { new C128(); }\n}\ncontract C128 {\n    constructor() { new C129(); }\n}\ncontract C129 {\n    constructor() { new C130(); }\n}\ncontract C130 {\n    constructor() { new C131(); }\n}\ncontract C131 {\n    constructor() { new C132(); }\n}\ncontract C132 {\n    constructor() { new C133(); }\n}\ncontract C133 {\n    constructor() { new C134(); }\n}\ncontract C134 {\n    constructor() { new C135(); }\n}\ncontract C135 {\n    constructor() { new C136(); }\n}\ncontract C136 {\n    constructor() { new C137(); }\n}\ncontract C137 {\n    constructor() { new C138(); }\n}\ncontract C138 {\n    constructor() { new C139(); }\n}\ncontract C139 {\n    constructor() { new C140(); }\n}\ncontract C140 {\n    constructor() { new C141(); }\n}\ncontract C141 {\n    constructor() { new C142(); }\n}\ncontract C142 {\n    constructor() { new C143(); }\n}\ncontract C143 {\n    constructor() { new C144(); }\n}\ncontract C144 {\n    constructor() { new C145(); }\n}\ncontract C145 {\n    constructor() { new C146(); }\n}\ncontract C146 {\n    constructor() { new C147(); }\n}\ncontract C147 {\n    constructor() { new C148(); }\n}\ncontract C148 {\n    constructor() { new C149(); }\n}\ncontract C149 {\n    constructor() { new C150(); }\n}\ncontract C150 {\n    constructor() { new C151(); }\n}\ncontract C151 {\n    constructor() { new C152(); }\n}\ncontract C152 {\n    constructor() { new C153(); }\n}\ncontract C153 {\n    constructor() { new C154(); }\n}\ncontract C154 {\n    constructor() { new C155(); }\n}\ncontract C155 {\n    constructor() { new C156(); }\n}\ncontract C156 {\n    constructor() { new C157(); }\n}\ncontract C157 {\n    constructor() { new C158(); }\n}\ncontract C158 {\n    constructor() { new C159(); }\n}\ncontract C159 {\n    constructor() { new C160(); }\n}\ncontract C160 {\n    constructor() { new C161(); }\n}\ncontract C161 {\n    constructor() { new C162(); }\n}\ncontract C162 {\n    constructor() { new C163(); }\n}\ncontract C163 {\n    constructor() { new C164(); }\n}\ncontract C164 {\n    constructor() { new C165(); }\n}\ncontract C165 {\n    constructor() { new C166(); }\n}\ncontract C166 {\n    constructor() { new C167(); }\n}\ncontract C167 {\n    constructor() { new C168(); }\n}\ncontract C168 {\n    constructor() { new C169(); }\n}\ncontract C169 {\n    constructor() { new C170(); }\n}\ncontract C170 {\n    constructor() { new C171(); }\n}\ncontract C171 {\n    constructor() { new C172(); }\n}\ncontract C172 {\n    constructor() { new C173(); }\n}\ncontract C173 {\n    constructor() { new C174(); }\n}\ncontract C174 {\n    constructor() { new C175(); }\n}\ncontract C175 {\n    constructor() { new C176(); }\n}\ncontract C176 {\n    constructor() { new C177(); }\n}\ncontract C177 {\n    constructor() { new C178(); }\n}\ncontract C178 {\n    constructor() { new C179(); }\n}\ncontract C179 {\n    constructor() { new C180(); }\n}\ncontract C180 {\n    constructor() { new C181(); }\n}\ncontract C181 {\n    constructor() { new C182(); }\n}\ncontract C182 {\n    constructor() { new C183(); }\n}\ncontract C183 {\n    constructor() { new C184(); }\n}\ncontract C184 {\n    constructor() { new C185(); }\n}\ncontract C185 {\n    constructor() { new C186(); }\n}\ncontract C186 {\n    constructor() { new C187(); }\n}\ncontract C187 {\n    constructor() { new C188(); }\n}\ncontract C188 {\n    constructor() { new C189(); }\n}\ncontract C189 {\n    constructor() { new C190(); }\n}\ncontract C190 {\n    constructor() { new C191(); }\n}\ncontract C191 {\n    constructor() { new C192(); }\n}\ncontract C192 {\n    constructor() { new C193(); }\n}\ncontract C193 {\n    constructor() { new C194(); }\n}\ncontract C194 {\n    constructor() { new C195(); }\n}\ncontract C195 {\n    constructor() { new C196(); }\n}\ncontract C196 {\n    constructor() { new C197(); }\n}\ncontract C197 {\n    constructor() { new C198(); }\n}\ncontract C198 {\n    constructor() { new C199(); }\n}\ncontract C199 {\n    constructor() { new C200(); }\n}\ncontract C200 {\n    constructor() { new C201(); }\n}\ncontract C201 {\n    constructor() { new C202(); }\n}\ncontract C202 {\n    constructor() { new C203(); }\n}\ncontract C203 {\n    constructor() { new C204(); }\n}\ncontract C204 {\n    constructor() { new C205(); }\n}\ncontract C205 {\n    constructor() { new C206(); }\n}\ncontract C206 {\n    constructor() { new C207(); }\n}\ncontract C207 {\n    constructor() { new C208(); }\n}\ncontract C208 {\n    constructor() { new C209(); }\n}\ncontract C209 {\n    constructor() { new C210(); }\n}\ncontract C210 {\n    constructor() { new C211(); }\n}\ncontract C211 {\n    constructor() { new C212(); }\n}\ncontract C212 {\n    constructor() { new C213(); }\n}\ncontract C213 {\n    constructor() { new C214(); }\n}\ncontract C214 {\n    constructor() { new C215(); }\n}\ncontract C215 {\n    constructor() { new C216(); }\n}\ncontract C216 {\n    constructor() { new C217(); }\n}\ncontract C217 {\n    constructor() { new C218(); }\n}\ncontract C218 {\n    constructor() { new C219(); }\n}\ncontract C219 {\n    constructor() { new C220(); }\n}\ncontract C220 {\n    constructor() { new C221(); }\n}\ncontract C221 {\n    constructor() { new C222(); }\n}\ncontract C222 {\n    constructor() { new C223(); }\n}\ncontract C223 {\n    constructor() { new C224(); }\n}\ncontract C224 {\n    constructor() { new C225(); }\n}\ncontract C225 {\n    constructor() { new C226(); }\n}\ncontract C226 {\n    constructor() { new C227(); }\n}\ncontract C227 {\n    constructor() { new C228(); }\n}\ncontract C228 {\n    constructor() { new C229(); }\n}\ncontract C229 {\n    constructor() { new C230(); }\n}\ncontract C230 {\n    constructor() { new C231(); }\n}\ncontract C231 {\n    constructor() { new C232(); }\n}\ncontract C232 {\n    constructor() { new C233(); }\n}\ncontract C233 {\n    constructor() { new C234(); }\n}\ncontract C234 {\n    constructor() { new C235(); }\n}\ncontract C235 {\n    constructor() { new C236(); }\n}\ncontract C236 {\n    constructor() { new C237(); }\n}\ncontract C237 {\n    constructor() { new C238(); }\n}\ncontract C238 {\n    constructor() { new C239(); }\n}\ncontract C239 {\n    constructor() { new C240(); }\n}\ncontract C240 {\n    constructor() { new C241(); }\n}\ncontract C241 {\n    constructor() { new C242(); }\n}\ncontract C242 {\n    constructor() { new C243(); }\n}\ncontract C243 {\n    constructor() { new C244(); }\n}\ncontract C244 {\n    constructor() { new C245(); }\n}\ncontract C245 {\n    constructor() { new C246(); }\n}\ncontract C246 {\n    constructor() { new C247(); }\n}\ncontract C247 {\n    constructor() { new C248(); }\n}\ncontract C248 {\n    constructor() { new C249(); }\n}\ncontract C249 {\n    constructor() { new C250(); }\n}\ncontract C250 {\n    constructor() { new C251(); }\n}\ncontract C251 {\n    constructor() { new C252(); }\n}\ncontract C252 {\n    constructor() { new C253(); }\n}\ncontract C253 {\n    constructor() { new C254(); }\n}\ncontract C254 {\n    constructor() { new C255(); }\n}\ncontract C255 {\n    constructor() { new C(); }\n}\n\n// ----\n// TypeError 7864: (13057-13105): Contract dependencies exhausting cyclic dependency validator\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/library_called.sol",
    "content": "library L1 {\n    function foo() internal { new A(); }\n}\nlibrary L2 {\n    function foo() internal { L1.foo(); }\n}\ncontract A {\n    function f() public pure { L2.foo(); }\n}\n// ----\n// TypeError 7813: (43-48): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/library_function_circular_reference.sol",
    "content": "library L {\n    function f() internal {\n        new C();\n    }\n}\n\ncontract D {\n    function f() public {\n        L.f();\n    }\n}\ncontract C {\n    constructor() { new D(); }\n}\n\n// ----\n// TypeError 7813: (48-53): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (161-166): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/library_non_called.sol",
    "content": "library L1 {\n    function foo() internal { new A(); }\n}\nlibrary L2 {\n    function foo() internal { L1.foo(); }\n}\ncontract A {\n    function f() public pure { type(L2).creationCode; }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 6133: (157-178): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/library_public_called.sol",
    "content": "library L1 {\n    function foo() internal { new A(); }\n}\nlibrary L2 {\n    function foo() public { L1.foo(); }\n}\ncontract A {\n    function f() public { L2.foo(); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/bytecodeReferences/library_public_without_contract.sol",
    "content": "library L1 {\n    function foo() public { L2.foo(); }\n\n}\nlibrary L2 {\n    function foo() internal { type(L1).creationCode; }\n}\n// ----\n// TypeError 7813: (99-120): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/multiline_comments.sol",
    "content": "/*\n * This is a multi-line comment\n * it should create no problems\n *\n*/\n\ncontract test {\n    /*\n    * this is another multi-line comment\n    *\n    */\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/multiline_unicode_direction_override_1.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // PDF\n        /*underflow ‬*/\n    }\n}\n// ----\n// ParserError 8936: (71-83): Unicode direction override underflow in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/multiline_unicode_direction_override_2.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // PDF PDF\n        /*underflow ‬‬*/\n    }\n}\n// ----\n// ParserError 8936: (75-87): Unicode direction override underflow in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/multiline_unicode_direction_override_3.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // RLO\n        /*overflow ‮*/\n    }\n}\n// ----\n// ParserError 8936: (71-86): Mismatching directional override markers in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/multiline_unicode_direction_override_4.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // RLO RLO\n        /*overflow ‮‮*/\n    }\n}\n// ----\n// ParserError 8936: (75-93): Mismatching directional override markers in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/multiline_unicode_direction_override_5.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // RLO PDF\n        /*ok ‮‬*/\n\n        // RLO RLO PDF PDF\n        /*ok ‮‮‬‬*/\n\n        // RLO RLO RLO PDF PDF PDF\n        /*ok ‮‮‮‬‬‬*/\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/multiline_unicode_direction_override_6.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // PDF RLO\n        /*overflow ‬‮*/\n    }\n}\n// ----\n// ParserError 8936: (75-86): Unicode direction override underflow in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/multiline_unicode_direction_override_7.sol",
    "content": "contract C {\n    function f() public pure {\n        /* LRO‭ LRE‪ RLE ‫  PDF‬ RLO‮ PDF ‬ PDF‬\n    }\n}\n// ----\n// ParserError 8936: (52-115): Expected multi-line comment-terminator.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/singleline_unicode_direction_override_1.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // PDF\n        // underflow ‬\n    }\n}\n// ----\n// ParserError 8936: (71-84): Unicode direction override underflow in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/singleline_unicode_direction_override_2.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // PDF PDF\n        // underflow ‬‬\n    }\n}\n// ----\n// ParserError 8936: (75-88): Unicode direction override underflow in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/singleline_unicode_direction_override_3.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // RLO\n        // overflow ‮\n    }\n}\n// ----\n// ParserError 8936: (71-86): Mismatching directional override markers in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/singleline_unicode_direction_override_4.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // RLO RLO\n        // overflow ‮‮\n    }\n}\n// ----\n// ParserError 8936: (75-93): Mismatching directional override markers in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/singleline_unicode_direction_override_5.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // RLO PDF\n        // ok ‮‬\n\n        // RLO RLO PDF PDF\n        // ok ‮‮‬‬\n\n        // RLO RLO RLO PDF PDF PDF\n        // ok ‮‮‮‬‬‬\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/singleline_unicode_direction_override_6.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // PDF RLO\n        // underflow ‬‮\n    }\n}\n// ----\n// ParserError 8936: (75-88): Unicode direction override underflow in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/unicode_direction_in_source_1.sol",
    "content": "contract C {\n    function f(bool b) public pure\n    {\n        if ‬(b) { return; }\n    }\n}\n// ----\n// ParserError 2314: (65-66): Expected '(' but got 'ILLEGAL'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/unicode_direction_in_source_2.sol",
    "content": "contract C {\n    function f(bool b) public pure\n    {\n        uint a = 10; ‬\n    }\n}\n// ----\n// ParserError 8936: (75-76): Invalid token.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/comments/unicode_direction_override_1.sol",
    "content": "contract TimelockUpgrade {\n    function confirmUpgrade() external {\n        uint256 m;\n        uint256 d;\n        (/*year*/,/*month‮*/,d/*yad*/,m/*‬‬hour*/,/*minute*/,/*second*/) = BokkyDateTime.timestampToDateTime(block.timestamp);\n    }\n}\n\n// ----\n// ParserError 8936: (124-135): Mismatching directional override markers in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constantEvaluator/erc7201_builtin.sol",
    "content": "contract C {\n    uint constant x = erc7201(\"A\");\n    uint[x] array;\n}\n// ----\n// Warning 7325: (53-60): Type uint256[36579005187129934694193755934841191771209741707776365283473783080460440925696] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constantEvaluator/overflow.sol",
    "content": "contract C {\n    uint8 constant a = 255;\n    uint16 constant b = a + 2;\n    function f() public pure {\n        uint[b] memory x;\n    }\n}\n// ----\n// TypeError 2643: (65-70): Arithmetic error when computing constant value.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constantEvaluator/type_reference.sol",
    "content": "int[L] constant L = 6;\n// ----\n// TypeError 5462: (4-5): Invalid array length, expected integer literal or constant expression.\n// TypeError 9259: (0-21): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constantEvaluator/type_reference_in_contract.sol",
    "content": "contract C {\n    int[L] constant L = 6;\n}\n// ----\n// TypeError 5462: (21-22): Invalid array length, expected integer literal or constant expression.\n// TypeError 9259: (17-38): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constantEvaluator/unary_fine.sol",
    "content": "contract C {\n    int8 constant a = -7;\n    function f() public pure {\n        uint[-a] memory x;\n        x[0] = 2;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constantEvaluator/underflow.sol",
    "content": "contract C {\n    uint8 constant a = 0;\n    function f() public pure {\n        uint[a - 1] memory x;\n    }\n}\n// ----\n// TypeError 2643: (83-88): Arithmetic error when computing constant value.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constantEvaluator/underflow_unary.sol",
    "content": "contract C {\n    int8 constant a = -128;\n    function f() public pure {\n        uint[-a] memory x;\n    }\n}\n// ----\n// TypeError 3667: (85-87): Arithmetic error when computing constant value.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/access_via_getter.sol",
    "content": "contract Counter {\n    uint256 public constant MIN_LIQUIDITY = 1000;\n\n    function run() view public {\n        this.MIN_LIQUIDITY();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_cyclic_via_user_operators.sol",
    "content": "type Type is uint;\nusing {f as +} for Type global;\nfunction f(Type, Type) pure returns (Type) {}\n\nType constant t = Type.wrap(1);\nType constant u = v + t;\nType constant v = u + t;\n// ----\n// TypeError 8349: (148-153): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (173-178): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_natspec.sol",
    "content": "/// @dev Documentation\nuint constant x = 8;\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_natspec_user.sol",
    "content": "/// Documentation\nuint constant x = 8;\n// ----\n// DocstringParsingError 6546: (0-18): Documentation tag @notice not valid for file-level variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_override.sol",
    "content": "uint constant override x = 2;\n// ----\n// ParserError 2314: (14-22): Expected identifier but got 'override'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_state_variable_named_transient.sol",
    "content": "contract C {\n    int constant public transient = 0;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol",
    "content": "contract C {\n    int constant public transient x = 0;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// DeclarationError 2197: (17-52): Transient cannot be used as data location for constant or immutable variables.\n// DeclarationError 9825: (17-52): Initialization of transient storage state variables is not supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_unassigned.sol",
    "content": "uint constant x;\n// ----\n// TypeError 4266: (0-15): Uninitialized \"constant\" variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_variables_as_static_array_length.sol",
    "content": "uint256 constant MAX = 1;\n\nlibrary L1 {\n    uint256 internal constant INT = 100;\n}\n\ncontract C1 {\n    uint256 internal constant CONST1 = L1.INT;\n\n    uint256[L1.INT] internal arr1; // error, backward reference\n    uint256[L2.INT] internal arr2; // error, forward reference\n}\n\ncontract C2 is C1 {\n    uint256 internal constant CONST2 = CONST1;\n\n    uint256[CONST1] internal arr3; // error, inherited constants\n    uint256[CONST2] internal arr4; // error, same contract constant\n}\n\nlibrary L2 {\n    uint256 internal constant INT = 100;\n}\n\n// ----\n// TypeError 5462: (158-164): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (222-228): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (356-362): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (421-427): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_virtual.sol",
    "content": "uint constant virtual x;\n// ----\n// ParserError 2314: (14-21): Expected identifier but got 'virtual'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_with_dependencies_as_array_sizes.sol",
    "content": "uint256 constant MAX = 1;\n\nlibrary L1 {\n    uint256 internal constant INT = 100;\n}\n\ncontract C1 {\n    uint256 internal constant CONST = 20 + L2.INT; // forward reference\n    uint256 internal constant LIMIT = MAX * L1.INT;  // same file & external library constant\n    uint256 internal constant NESTED = LIMIT + CONST; // nested & same contract constant\n\n    uint256[L1.INT] internal arr1; // error, backward reference\n    uint256[L2.INT] internal arr2; // error, forward reference\n}\n\ncontract C2 is C1 {\n    uint256 internal constant INHERITED = NESTED + CONST * LIMIT; // inherited constants\n}\n\ncontract C3 is C2 {\n    uint256 internal constant NESTED_INHERITED = INHERITED + NESTED + CONST * LIMIT; // nest-inherited constants\n\n    uint256[CONST] internal arr3;            // error, nest-inherited constants\n    uint256[NESTED_INHERITED] internal arr4; // error, same contract constant\n}\n\nlibrary L2 {\n    uint256 internal constant INT = 100;\n}\n\n// ----\n// TypeError 5462: (366-372): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (430-436): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (742-747): Invalid array length, expected integer literal or constant expression.\n// TypeError 5462: (822-838): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_with_dependencies_on_constants.sol",
    "content": "uint256 constant MAX = 1;\n\nlibrary L1 {\n    uint256 internal constant INT = 100;\n}\n\ncontract C1 {\n    uint256 internal constant CONST = 20 + L2.INT; // forward reference\n    uint256 internal constant LIMIT = MAX * L1.INT;  // same file & external library constant\n    uint256 internal constant NESTED = LIMIT + CONST; // nested & same contract constant\n}\n\ncontract C2 is C1 {\n    uint256 internal constant INHERITED = NESTED + CONST * LIMIT; // inherited constants\n}\n\ncontract C3 is C2 {\n    uint256 internal constant NESTED_INHERITED = INHERITED + NESTED + CONST * LIMIT; // nest-inherited constants\n}\n\nlibrary L2 {\n    uint256 internal constant INT = 100;\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_with_dependencies_on_file_level_constants.sol",
    "content": "==== Source: A.sol ====\nimport \"B.sol\" as B;\n\nuint constant X = 1;\nuint constant Y = B.Y;\n\n==== Source: B.sol ====\nimport \"A.sol\" as A;\n\nuint constant X = A.X;\nuint constant Y = 2;\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_with_visibility.sol",
    "content": "uint public constant x = 7;\n// ----\n// ParserError 2314: (5-11): Expected identifier but got 'public'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constant_with_visibility_inverted.sol",
    "content": "uint constant public y = 7;\n// ----\n// ParserError 2314: (14-20): Expected identifier but got 'public'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/constants_with_dependencies_on_library_constants_multi_file.sol",
    "content": "==== Source: A.sol ====\nimport \"B.sol\";\n\nlibrary L {\n    uint constant X = 1;\n    uint constant Y = K.Y;\n}\n\n==== Source: B.sol ====\nimport \"A.sol\";\n\nlibrary K {\n    uint constant X = L.X;\n    uint constant Y = 2;\n}\n\n// ====\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/cross_file_cyclic.sol",
    "content": "==== Source: a ====\nimport \"b\";\nuint constant c = d;\n==== Source: b ====\nimport \"a\";\nuint constant b = c;\nuint constant d = b;\ncontract C {\n    uint constant a = b;\n}\n// ----\n// TypeError 6161: (b:12-31): The value of the constant b has a cyclic dependency via c.\n// TypeError 6161: (b:33-52): The value of the constant d has a cyclic dependency via b.\n// TypeError 6161: (b:71-90): The value of the constant a has a cyclic dependency via b.\n// TypeError 6161: (a:12-31): The value of the constant c has a cyclic dependency via d.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/cross_file_cyclic_modules.sol",
    "content": "==== Source: a ====\nimport \"b\";\nuint constant c = d;\n==== Source: b ====\nimport \"a\" as M;\nuint constant b = M.c;\nuint constant d = b;\ncontract C {\n    uint constant a = b;\n}\n// ----\n// TypeError 6161: (b:17-38): The value of the constant b has a cyclic dependency via c.\n// TypeError 6161: (b:40-59): The value of the constant d has a cyclic dependency via b.\n// TypeError 6161: (b:78-97): The value of the constant a has a cyclic dependency via b.\n// TypeError 6161: (a:12-31): The value of the constant c has a cyclic dependency via d.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/file_level_memory.sol",
    "content": "uint[] memory constant x = 2;\n// ----\n// ParserError 2314: (7-13): Expected identifier but got 'memory'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/file_level_memory_inverted.sol",
    "content": "uint[] constant memory x = 2;\n// ----\n// ParserError 2314: (16-22): Expected identifier but got 'memory'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/file_level_multiple_constant_keywords.sol",
    "content": "uint constant constant x;\n// ----\n// ParserError 3109: (14-22): Mutability already set to \"constant\"\n\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/immutable_at_file_level.sol",
    "content": "uint immutable x = 7;\n// ----\n// DeclarationError 8342: (0-20): Only constant variables are allowed at file level.\n// DeclarationError 8297: (0-20): The \"immutable\" keyword can only be used for state variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/abi_decode_const_args.sol",
    "content": "bytes constant aEncoded = abi.encode(\n    hex\"aaaa\"\n);\n\ncontract A {\n    bytes constant a = abi.decode(aEncoded, (bytes));\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/abi_decode_non_const_args.sol",
    "content": "contract A {\n    function encoded() private view returns (bytes memory) {\n        return abi.encode(hex\"aaaa\");\n    }\n\n    bytes constant a = abi.decode(encoded(), (bytes));\n}\n// ----\n// TypeError 8349: (142-172): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_const_args.sol",
    "content": "contract A {\n    bool constant FLAG = true;\n    function f(uint, bool) external {}\n    bytes constant fCallA = abi.encodeCall(A.f, (123, FLAG));\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/abi_encode_call_non_const_args.sol",
    "content": "contract A {\n    function f(uint a) external {}\n\n    function getA() private view returns(uint) {\n        return 1;\n    }\n\n    bytes constant fCallA = abi.encodeCall(A.f, (getA()));\n}\n// ----\n// TypeError 8349: (151-180): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_const_args.sol",
    "content": "contract C {\n    bytes32 constant a = keccak256(abi.encode(1, 2));\n    bytes32 constant b = keccak256(abi.encodePacked(uint(1), a));\n    bytes32 constant c = keccak256(abi.encodeWithSelector(0x12345678, b, 2));\n    bytes32 constant d = keccak256(abi.encodeWithSignature(\"f()\", 1, 2));\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/abi_encoding_builtin_non_const_args.sol",
    "content": "contract C {\n    uint k = 1;\n\n    bytes32 constant a = keccak256(abi.encode(1, k));\n    bytes32 constant b = keccak256(abi.encodePacked(uint(1), k));\n    bytes32 constant c = keccak256(abi.encodeWithSelector(0x12345678, k, 2));\n    bytes32 constant d = keccak256(abi.encodeWithSignature(\"f()\", 1, k));\n}\n// ----\n// TypeError 8349: (55-82): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (109-148): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (175-226): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (253-300): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/addmod_by_zero.sol",
    "content": "contract c {\n    uint constant a1 = 0;\n    uint constant a2 = 1;\n    uint constant b1 = addmod(3, 4, 0);\n    uint constant b2 = addmod(3, 4, a1);\n    uint constant b3 = addmod(3, 4, a2 - 1);\n}\n// ----\n// TypeError 4195: (88-103): Arithmetic modulo zero.\n// TypeError 4195: (128-144): Arithmetic modulo zero.\n// TypeError 4195: (169-189): Arithmetic modulo zero.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/addmod_mulmod_rational_arg.sol",
    "content": "contract C {\n    uint constant a = addmod(3, 4, 0.1);\n    uint constant b = mulmod(3, 4, 0.1);\n}\n// ----\n// TypeError 9553: (48-51): Invalid type for argument in function call. Invalid implicit conversion from rational_const 1 / 10 to uint256 requested.\n// TypeError 9553: (89-92): Invalid type for argument in function call. Invalid implicit conversion from rational_const 1 / 10 to uint256 requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/block_tx_msg_property.sol",
    "content": "bytes32 constant blockhGlobal = blockhash(1);\nbytes32 constant blobhGlobal = blobhash(1);\nuint constant bfGlobal = block.basefee;\nuint constant blobbfGlobal = block.blobbasefee;\nuint constant chainIdGlobal = block.chainid;\naddress constant coinbaseGlobal = block.coinbase;\nuint constant diffGlobal = block.difficulty;\nuint constant gaslimitGlobal = block.gaslimit;\nuint constant numberGlobal = block.number;\nuint constant prevrandaoGlobal = block.prevrandao;\nuint constant timestampGlobal = block.timestamp;\nuint constant gGlobal = gasleft();\nbytes constant dataGlobal = msg.data;\naddress constant senderGlobal = msg.sender;\nbytes4 constant sigGlobal = msg.sig;\nuint constant valueGlobal = msg.value;\nuint constant gaspriceGlobal = tx.gasprice;\naddress constant originGlobal = tx.origin;\n\ncontract A {\n    bytes32 constant blockh = blockhash(1);\n    bytes32 constant blobh = blobhash(1);\n    uint constant bf = block.basefee;\n    uint constant blobbf = block.blobbasefee;\n    uint constant chainId = block.chainid;\n    address constant coinbase = block.coinbase;\n    uint constant diff = block.difficulty;\n    uint constant gaslimit = block.gaslimit;\n    uint constant number = block.number;\n    uint constant prevrandao = block.prevrandao;\n    uint constant timestamp = block.timestamp;\n    uint constant g = gasleft();\n    bytes constant data = msg.data;\n    address constant sender = msg.sender;\n    bytes4 constant sig = msg.sig;\n    uint constant value = msg.value;\n    uint constant gasprice = tx.gasprice;\n    address constant origin = tx.origin;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// TypeError 8349: (32-44): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (77-88): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (115-128): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (159-176): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (208-221): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (257-271): Initial value for constant variable has to be compile-time constant.\n// Warning 8417: (300-316): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// TypeError 8349: (300-316): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (349-363): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (394-406): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (441-457): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (491-506): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (532-541): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (571-579): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (613-623): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (653-660): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (690-699): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (732-743): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (777-786): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (832-844): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (875-886): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (911-924): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (953-970): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1000-1013): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1047-1061): Initial value for constant variable has to be compile-time constant.\n// Warning 8417: (1088-1104): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n// TypeError 8349: (1088-1104): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1135-1149): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1178-1190): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1223-1239): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1271-1286): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1310-1319): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1347-1355): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1387-1397): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1425-1432): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1460-1469): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1500-1511): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (1543-1552): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/bytes_concat_const_args.sol",
    "content": "bytes constant aaaa = hex\"aaaa\";\n\nbytes constant abcGlobal = bytes.concat(aaaa, hex\"bbbb\", hex\"cccc\");\n\ncontract A {\n    bytes public constant abc = bytes.concat(aaaa, hex\"bbbb\", hex\"cccc\");\n\n    bytes public constant abcCopy = abc;\n    bytes public constant abcGlobalCopy = abcGlobal;\n    bytes public constant abcabc = bytes.concat(abc, abcGlobal);\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/bytes_concat_non_const_args.sol",
    "content": "contract A {\n    function getData() public view returns (bytes memory) {\n        return msg.data;\n    }\n\n    function getDataPure() public pure returns (bytes memory) {\n        return hex\"ffff\";\n    }\n\n    bytes constant abData = bytes.concat(hex\"aaaa\", hex\"bbbb\", msg.data);\n    bytes constant abgetData = bytes.concat(hex\"aaaa\", hex\"bbbb\", getData());\n    bytes constant abgetDataPure = bytes.concat(hex\"aaaa\", hex\"bbbb\", getDataPure());\n}\n// ----\n// TypeError 8349: (230-274): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (307-352): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (389-438): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_1.sol",
    "content": "contract C {\n    uint constant a = a;\n}\n// ----\n// TypeError 6161: (17-36): The value of the constant a has a cyclic dependency via a.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_2.sol",
    "content": "contract C {\n    uint constant a = b * c;\n    uint constant b = 7;\n    uint constant c = b + uint(keccak256(abi.encodePacked(d)));\n    uint constant d = 2 + a;\n}\n// ----\n// TypeError 6161: (17-40): The value of the constant a has a cyclic dependency via c.\n// TypeError 6161: (71-129): The value of the constant c has a cyclic dependency via d.\n// TypeError 6161: (135-158): The value of the constant d has a cyclic dependency via a.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_3.sol",
    "content": "contract C {\n    uint constant x = a;\n    uint constant a = b * c;\n    uint constant b = c;\n    uint constant c = b;\n}\n// ----\n// TypeError 6161: (17-36): The value of the constant x has a cyclic dependency via a.\n// TypeError 6161: (42-65): The value of the constant a has a cyclic dependency via b.\n// TypeError 6161: (71-90): The value of the constant b has a cyclic dependency via c.\n// TypeError 6161: (96-115): The value of the constant c has a cyclic dependency via b.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_4.sol",
    "content": "contract C {\n    uint constant a = b * c;\n    uint constant b = 7;\n    uint constant c = 4 + uint(keccak256(abi.encode(d)));\n    uint constant d = 2 + b;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_5.sol",
    "content": "contract C {\n  uint constant a = uint(keccak256(abi.encode(d)));\n  uint c = uint(keccak256(abi.encode(d)));\n  uint constant d = a;\n}\n// ----\n// TypeError 6161: (15-63): The value of the constant a has a cyclic dependency via d.\n// TypeError 6161: (110-129): The value of the constant d has a cyclic dependency via a.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_file.sol",
    "content": "==== Source: A.sol ====\nimport \"B.sol\";\n\nuint256 constant A = B + 1;\n\n==== Source: B.sol ====\nimport \"A.sol\";\n\nuint256 constant B = A + 1;\n\n// ----\n// TypeError 6161: (B.sol:17-43): The value of the constant B has a cyclic dependency via A.\n// TypeError 6161: (A.sol:17-43): The value of the constant A has a cyclic dependency via B.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_file_and_library.sol",
    "content": "==== Source: A.sol ====\nimport \"B.sol\";\n\nuint256 constant A = B.VAL + 1;\n\n==== Source: B.sol ====\nimport \"A.sol\";\n\nlibrary B {\n    uint256 constant VAL = A + 1;\n}\n\n// ----\n// TypeError 6161: (B.sol:33-61): The value of the constant VAL has a cyclic dependency via A.\n// TypeError 6161: (A.sol:17-47): The value of the constant A has a cyclic dependency via VAL.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/constant_with_cyclic_dependency_library.sol",
    "content": "library A {\n    uint256 constant VAL = B.VAL + 1;\n}\n\nlibrary B {\n    uint256 constant VAL = A.VAL + 1;\n}\n\n// ----\n// TypeError 6161: (16-48): The value of the constant VAL has a cyclic dependency via VAL.\n// TypeError 6161: (69-101): The value of the constant VAL has a cyclic dependency via VAL.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/division_by_zero.sol",
    "content": "contract c {\n    uint constant a1 = 0;\n    uint constant a2 = 1;\n    uint constant b1 = 7 / a1;\n    uint constant b2 = 7 / (a2 - 1);\n}\n// ----\n// TypeError 1211: (88-94): Division by zero.\n// TypeError 1211: (119-131): Division by zero.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/function_pointer_call.sol",
    "content": "contract C {\n    function () pure returns (uint) x;\n    uint constant y = x();\n}\n// ----\n// TypeError 8349: (74-77): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_const_args.sol",
    "content": "uint256 constant k = 7;\nbytes constant data = hex\"ffff\";\n\nuint256 constant amodGlobal = addmod(1, 8, k);\nuint256 constant mmodGlobal = mulmod(1, 8, k);\nbytes32 constant keccakGlobal = keccak256(hex\"ffff\");\nbytes32 constant keccakConstArgGlobal = keccak256(data);\n\ncontract A {\n    uint256 constant amod = addmod(1, 8, k);\n    uint256 constant mmod = mulmod(1, 8, k);\n    bytes32 constant keccak = keccak256(hex\"ffff\");\n    bytes32 constant keccakConstArg = keccak256(data);\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/math_builtin_opcode_based_non_const_args.sol",
    "content": "contract A {\n    uint256 k = 7;\n    uint256 constant amod = addmod(1, 8, k);\n    uint256 constant mmod = mulmod(1, 8, k);\n\n    bytes data = hex\"ffff\";\n    bytes32 constant keccak = keccak256(data);\n}\n// ----\n// TypeError 8349: (60-75): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (105-120): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (181-196): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_const_args.sol",
    "content": "uint8 constant k = 1;\nbytes constant data = hex\"ffff\";\n\nbytes32 constant sGlobal = sha256(hex\"ffff\");\nbytes32 constant sConstArgGlobal = sha256(data);\naddress constant addrGlobal = ecrecover(\"1234\", k, \"0\", abi.decode(\"\", (bytes2)));\nbytes20 constant ripemdGlobal = ripemd160(hex\"ffff\");\nbytes20 constant ripemdConstArgGlobal = ripemd160(data);\n\ncontract A {\n    bytes32 constant s = sha256(hex\"ffff\");\n    bytes32 constant sConstArg = sha256(data);\n    address constant addr = ecrecover(\"1234\", k, \"0\", abi.decode(\"\", (bytes2)));\n    bytes20 constant ripemd = ripemd160(hex\"ffff\");\n    bytes20 constant ripemdConstArg = ripemd160(data);\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/math_builtin_precompile_based_non_const_args.sol",
    "content": "contract A {\n    bytes data = hex\"ffff\";\n    bytes32 constant sha = sha256(data);\n    bytes20 constant ripemd = ripemd160(data);\n    address constant addr = ecrecover(\"1234\", 1, \"0\", abi.decode(data, (bytes2)));\n}\n// ----\n// TypeError 8349: (68-80): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (112-127): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (157-210): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/modulo_by_zero.sol",
    "content": "contract c {\n    uint constant a1 = 0;\n    uint constant a2 = 1;\n    uint constant b1 = 3 % a1;\n    uint constant b2 = 3 % (a2 - 1);\n}\n// ----\n// TypeError 1211: (88-94): Modulo zero.\n// TypeError 1211: (119-131): Modulo zero.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/mulmod_by_zero.sol",
    "content": "contract c {\n    uint constant a1 = 0;\n    uint constant a2 = 1;\n    uint constant b1 = mulmod(3, 4, 0);\n    uint constant b2 = mulmod(3, 4, a1);\n    uint constant b3 = mulmod(3, 4, a2 - 1);\n}\n// ----\n// TypeError 4195: (88-103): Arithmetic modulo zero.\n// TypeError 4195: (128-144): Arithmetic modulo zero.\n// TypeError 4195: (169-189): Arithmetic modulo zero.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/string_concat_const_args.sol",
    "content": "string constant abcGlobal = string.concat(\"aaaa\", \"bbbb\", \"cccc\");\n\ncontract A {\n    string public constant abc = string.concat(\"aaaa\", \"bbbb\",\"cccc\");\n\n    string public constant abcCopy = abc;\n    string public constant abcGlobalCopy = abcGlobal;\n    string public constant abcabc = string.concat(abc, abcGlobal);\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/string_concat_non_const_args.sol",
    "content": "contract A {\n    string name = \"name\";\n\n    function getName() public view returns (string memory) {\n        return name;\n    }\n\n    string public constant abName = string.concat(\"aaaa\", \"bbbb\", name);\n\n    string public constant abgetName = string.concat(\"aaaa\", \"bbbb\",getName());\n}\n// ----\n// TypeError 8349: (165-200): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (242-281): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/initialization/type_info.sol",
    "content": "string constant aNameGlobal = type(A).name;\nbytes4 constant iNameGlobal = type(I).interfaceId;\nuint256 constant minGlobal = type(uint256).min;\nuint256 constant maxGlobal = type(uint256).max;\nbytes constant creationCodeBGlobal = type(B).creationCode;\nbytes constant runtimeCodeBGlobal = type(B).runtimeCode;\n\ncontract B {\n}\n\ninterface I {\n    function hello() external pure;\n    function world(int) external pure;\n}\n\ncontract A {\n    string constant aName = type(A).name;\n    bytes4 constant iName = type(I).interfaceId;\n    uint256 constant min = type(uint256).min;\n    uint256 constant max = type(uint256).max;\n    bytes constant creationCodeB = type(B).creationCode;\n    bytes constant runtimeCodeB = type(B).runtimeCode;\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/mapping_constant.sol",
    "content": "mapping(uint => uint) constant b = b;\n// ----\n// TypeError 9259: (0-36): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/mod_div_rational.sol",
    "content": "contract C {\n    fixed a1 = 0.1 % -0.4271087646484375;\n    fixed a2 = 0.1 % 0.4271087646484375;\n    fixed a3 = 0 / 0.123;\n    fixed a4 = 0 / -0.123;\n}\n// ====\n// compileViaYul: true\n// ----\n// UnimplementedFeatureError 1834: (28-53): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/name_clash_via_import.sol",
    "content": "==== Source: a ====\nuint constant c = 7;\n==== Source: b ====\nimport {c as d} from \"a\";\nuint constant d = 7;\n// ----\n// DeclarationError 2333: (b:26-45): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/non_constant.sol",
    "content": "uint x = 7;\n// ----\n// DeclarationError 8342: (0-10): Only constant variables are allowed at file level.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/pure_non_rational.sol",
    "content": "// Tests that the ConstantEvaluator does not crash for pure non-rational functions.\n// Currently it does not evaluate such functions, but this may change in the future\n// causing a division by zero error for a.\ncontract C {\n\tuint constant a = 1 / (uint(keccak256([0])[0]) - uint(keccak256([0])[0]));\n\tuint constant b = 1 / uint(keccak256([0]));\n\tuint constant c = uint(keccak256([0]));\n\tuint[c] mem;\n}\n// ----\n// TypeError 5462: (392-393): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/redefinition_cross_file.sol",
    "content": "==== Source: a ====\nimport \"b\";\nuint constant c = 7;\n==== Source: b ====\nimport \"a\";\nuint constant c = 7;\n// ----\n// DeclarationError 2333: (b:12-31): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/redefinition_public_constant.sol",
    "content": "uint constant c = 7;\nuint constant c = 8;\n// ----\n// DeclarationError 2333: (21-40): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constants/struct_constant.sol",
    "content": "struct S { uint x; }\nS constant s;\n// ----\n// TypeError 9259: (21-33): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/abstract_creation_forward_reference.sol",
    "content": "// This used to cause an internal error because of the visitation order.\ncontract Test {\n    function createChild() public {\n       Child asset = new Child();\n    }\n}\n\ncontract Parent {\n    constructor(address _address) {}\n}\n\ncontract Child is Parent {\n}\n// ----\n// TypeError 3415: (226-254): No arguments passed to the base constructor. Specify the arguments or mark \"Child\" as abstract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/base_constructor_missing_arguments.sol",
    "content": "contract C {\n    constructor(uint, bool) {}\n}\n\ncontract D is C() {}\ncontract E is C() { constructor() {} }\ncontract F is C() { constructor() C {} }\ncontract G is C() { constructor() C() {} }\n\ncontract H is C {}\ncontract I is C { constructor() {} }\ncontract J is C { constructor() C {} }\ncontract K is C { constructor() C() {} }\n// ----\n// TypeError 3415: (47-67): No arguments passed to the base constructor. Specify the arguments or mark \"D\" as abstract.\n// TypeError 3415: (68-106): No arguments passed to the base constructor. Specify the arguments or mark \"E\" as abstract.\n// DeclarationError 1563: (141-142): Modifier-style base constructor call without arguments.\n// TypeError 3415: (107-147): No arguments passed to the base constructor. Specify the arguments or mark \"F\" as abstract.\n// TypeError 3415: (192-210): No arguments passed to the base constructor. Specify the arguments or mark \"H\" as abstract.\n// TypeError 3415: (211-247): No arguments passed to the base constructor. Specify the arguments or mark \"I\" as abstract.\n// DeclarationError 1563: (280-281): Modifier-style base constructor call without arguments.\n// TypeError 3415: (248-286): No arguments passed to the base constructor. Specify the arguments or mark \"J\" as abstract.\n// TypeError 7927: (61-64): Wrong argument count for constructor call: 0 arguments given but expected 2. Remove parentheses if you do not want to provide arguments here.\n// TypeError 7927: (82-85): Wrong argument count for constructor call: 0 arguments given but expected 2. Remove parentheses if you do not want to provide arguments here.\n// TypeError 7927: (121-124): Wrong argument count for constructor call: 0 arguments given but expected 2. Remove parentheses if you do not want to provide arguments here.\n// TypeError 2973: (141-142): Wrong argument count for modifier invocation: 0 arguments given but expected 2.\n// TypeError 7927: (162-165): Wrong argument count for constructor call: 0 arguments given but expected 2. Remove parentheses if you do not want to provide arguments here.\n// TypeError 2973: (182-185): Wrong argument count for modifier invocation: 0 arguments given but expected 2.\n// TypeError 2973: (280-281): Wrong argument count for modifier invocation: 0 arguments given but expected 2.\n// TypeError 2973: (319-322): Wrong argument count for modifier invocation: 0 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/base_constructor_missing_arguments_abstract_inheritance_list_empty_parens.sol",
    "content": "abstract contract C {\n    constructor(uint, bool) {}\n}\n\nabstract contract D is C() {}\nabstract contract E is C() { constructor() {} }\nabstract contract F is C() { constructor() C {} }\nabstract contract G is C() { constructor() C() {} }\n// ----\n// DeclarationError 1563: (177-178): Modifier-style base constructor call without arguments.\n// TypeError 7927: (79-82): Wrong argument count for constructor call: 0 arguments given but expected 2. Remove parentheses if you do not want to provide arguments here.\n// TypeError 7927: (109-112): Wrong argument count for constructor call: 0 arguments given but expected 2. Remove parentheses if you do not want to provide arguments here.\n// TypeError 7927: (157-160): Wrong argument count for constructor call: 0 arguments given but expected 2. Remove parentheses if you do not want to provide arguments here.\n// TypeError 2973: (177-178): Wrong argument count for modifier invocation: 0 arguments given but expected 2.\n// TypeError 7927: (207-210): Wrong argument count for constructor call: 0 arguments given but expected 2. Remove parentheses if you do not want to provide arguments here.\n// TypeError 2973: (227-230): Wrong argument count for modifier invocation: 0 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/base_constructor_missing_arguments_abstract_lists_omitted.sol",
    "content": "abstract contract C {\n    constructor(uint, bool) {}\n}\n\nabstract contract D is C {}\nabstract contract E is C { constructor() {} }\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/base_constructor_missing_arguments_abstract_modifier_init.sol",
    "content": "abstract contract C {\n    constructor(uint, bool) {}\n}\n\nabstract contract D is C { constructor() C {} }\n// ----\n// DeclarationError 1563: (97-98): Modifier-style base constructor call without arguments.\n// TypeError 2973: (97-98): Wrong argument count for modifier invocation: 0 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/base_constructor_missing_arguments_abstract_modifier_init_empty_list.sol",
    "content": "abstract contract C {\n    constructor(uint, bool) {}\n}\n\nabstract contract D is C { constructor() C() {} }\n// ----\n// TypeError 2973: (97-100): Wrong argument count for modifier invocation: 0 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/base_constructor_wrong_arg_count_inheritance_and_modifier_lists.sol",
    "content": "contract C {\n    constructor(uint, bool) {}\n}\n\ncontract D is C(1, true, \"a\") { constructor() C(1, true, \"a\") {} }\ncontract E is C(1) { constructor() C(1) {} }\n// ----\n// DeclarationError 3364: (93-108): Base constructor arguments given twice.\n// DeclarationError 3364: (149-153): Base constructor arguments given twice.\n// TypeError 7927: (61-76): Wrong argument count for constructor call: 3 arguments given but expected 2\n// TypeError 2973: (93-108): Wrong argument count for modifier invocation: 3 arguments given but expected 2.\n// TypeError 7927: (128-132): Wrong argument count for constructor call: 1 arguments given but expected 2\n// TypeError 2973: (149-153): Wrong argument count for modifier invocation: 1 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/base_constructor_wrong_arg_count_inheritance_list.sol",
    "content": "contract C {\n    constructor(uint, bool) {}\n}\n\ncontract D is C(1, true, \"a\") {}\ncontract E is C(1) {}\n// ----\n// TypeError 7927: (61-76): Wrong argument count for constructor call: 3 arguments given but expected 2\n// TypeError 7927: (94-98): Wrong argument count for constructor call: 1 arguments given but expected 2\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/base_constructor_wrong_arg_count_inheritance_list_abstract.sol",
    "content": "abstract contract C {\n    constructor(uint, bool) {}\n}\n\nabstract contract D is C(1, true, \"a\") {}\nabstract contract E is C(1) {}\n// ----\n// TypeError 7927: (79-94): Wrong argument count for constructor call: 3 arguments given but expected 2\n// TypeError 7927: (121-125): Wrong argument count for constructor call: 1 arguments given but expected 2\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/base_constructor_wrong_arg_count_inheritance_list_empty_parens_and_modifier_list.sol",
    "content": "contract C {\n    constructor(uint, bool) {}\n}\n\ncontract D is C() { constructor() C(1, true, \"a\") {} }\ncontract E is C() { constructor() C(1) {} }\n// ----\n// TypeError 7927: (61-64): Wrong argument count for constructor call: 0 arguments given but expected 2. Remove parentheses if you do not want to provide arguments here.\n// TypeError 2973: (81-96): Wrong argument count for modifier invocation: 3 arguments given but expected 2.\n// TypeError 7927: (116-119): Wrong argument count for constructor call: 0 arguments given but expected 2. Remove parentheses if you do not want to provide arguments here.\n// TypeError 2973: (136-140): Wrong argument count for modifier invocation: 1 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/base_constructor_wrong_arg_count_inheritance_list_with_derived_constructor.sol",
    "content": "contract C {\n    constructor(uint, bool) {}\n}\n\ncontract D is C(1, true, \"a\") { constructor() {} }\ncontract E is C(1) { constructor() {} }\n// ----\n// TypeError 7927: (61-76): Wrong argument count for constructor call: 3 arguments given but expected 2\n// TypeError 7927: (112-116): Wrong argument count for constructor call: 1 arguments given but expected 2\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/base_constructor_wrong_arg_count_modifier_list.sol",
    "content": "contract C {\n    constructor(uint, bool) {}\n}\n\ncontract D is C { constructor() C(1, true, \"a\") {} }\ncontract E is C { constructor() C(1) {} }\n// ----\n// TypeError 2973: (79-94): Wrong argument count for modifier invocation: 3 arguments given but expected 2.\n// TypeError 2973: (132-136): Wrong argument count for modifier invocation: 1 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/calldata_constructor_args.sol",
    "content": "contract C {\n    constructor(uint[] calldata) public {}\n}\n// ----\n// TypeError 6651: (29-44): Data location must be \"storage\" or \"memory\" for constructor parameter, but \"calldata\" was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructible_abstract_base.sol",
    "content": "abstract contract C {\n\tconstructor() {}\n}\ncontract D is C {\n\tconstructor() { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructible_internal_constructor.sol",
    "content": "abstract contract C {\n\tconstructor() internal {}\n}\ncontract D is C {\n\tconstructor() { }\n}\n// ----\n// Warning 2462: (23-48): Visibility for constructor is ignored. If you want the contract to be non-deployable, making it \"abstract\" is sufficient.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor.sol",
    "content": "contract A { constructor() {} }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_function_parameter_disallowed_conversion.sol",
    "content": "contract D {\n    constructor(function() external pure returns (uint) ) {\n    }\n}\n\nlibrary L {\n    function f() public pure returns (uint) {\n        return 5;\n    }\n}\n\ncontract C {\n    function f() public returns (uint r) {\n        // An assert used to fail if the function types are not exactly equal (pure, view) v/s\n        // default\n        // ok\n        new D(this.testPure);\n        // not okay\n        new D(this.testView);\n        // not okay\n        new D(this.testDefault);\n        // not okay\n        new D(this.testDifferentSignature);\n        // not okay\n        new D(gasleft);\n        // not okay\n        new D(L.f);\n        // not okay\n        new D(testInternalFunction);\n        // not okay\n        new D(this.testInternalFunction);\n    }\n\n    function testPure() public pure returns (uint) {\n    }\n\n    function testView() public view returns (uint) {\n        block.timestamp;\n    }\n\n    function testDefault() public returns (uint) {\n        selfdestruct(payable(address(this)));\n    }\n\n    function testDifferentSignature(uint a) public pure returns (uint) {\n    }\n\n    function testInternalFunction() internal pure returns (uint) {\n        return 10;\n    }\n}\n// ----\n// TypeError 9553: (415-428): Invalid type for argument in function call. Invalid implicit conversion from function () view external returns (uint256) to function () pure external returns (uint256) requested.\n// TypeError 9553: (465-481): Invalid type for argument in function call. Invalid implicit conversion from function () external returns (uint256) to function () pure external returns (uint256) requested.\n// TypeError 9553: (518-545): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) pure external returns (uint256) to function () pure external returns (uint256) requested.\n// TypeError 9553: (582-589): Invalid type for argument in function call. Invalid implicit conversion from function () view returns (uint256) to function () pure external returns (uint256) requested. Special functions cannot be converted to function types.\n// TypeError 9553: (626-629): Invalid type for argument in function call. Invalid implicit conversion from function () pure returns (uint256) to function () pure external returns (uint256) requested. Special functions cannot be converted to function types.\n// TypeError 9553: (666-686): Invalid type for argument in function call. Invalid implicit conversion from function () pure returns (uint256) to function () pure external returns (uint256) requested. Special functions cannot be converted to function types.\n// TypeError 9582: (723-748): Member \"testInternalFunction\" not found or not visible after argument-dependent lookup in contract C.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_internal_function.sol",
    "content": "contract A {\n    constructor(function() internal) {}\n}\n// ----\n// TypeError 4103: (29-49): Internal type is not allowed for public or external functions. You can make the contract abstract to avoid this problem.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_internal_function_abstract.sol",
    "content": "abstract contract A {\n    constructor(function() internal) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_mapping_memory.sol",
    "content": "contract A {\n    constructor(mapping(uint => uint) memory a) {}\n}\n// ----\n// TypeError 4103: (29-59): Types containing (nested) mappings can only be parameters or return variables of internal or library functions. You can make the contract abstract to avoid this problem.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_mapping_memory_abstract.sol",
    "content": "abstract contract A {\n    constructor(mapping(uint => uint) memory a) {}\n}\n// ----\n// TypeError 4061: (38-68): Type mapping(uint256 => uint256) is only valid in storage because it contains a (nested) mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_old.sol",
    "content": "contract A { function A() public {} }\n// ----\n// SyntaxError 5796: (13-35): Functions are not allowed to have the same name as the contract. If you intend this to be a constructor, use \"constructor(...) { ... }\" to define it.\n// Warning 2519: (13-35): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_override.sol",
    "content": "contract C {\n    constructor() override {}\n}\n// ----\n// TypeError 1209: (17-42): Constructors cannot override.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_payable.sol",
    "content": "contract C {\n    constructor() payable { }\n}\n\ncontract D {\n    function createC() public returns (C) {\n       C c = (new C){value: 1}();\n       return c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_state_mutability.sol",
    "content": "contract test1 {\n  constructor() view {}\n}\ncontract test2 {\n  constructor() pure {}\n}\n// ----\n// TypeError 1558: (19-40): Constructor must be payable or non-payable, but is \"view\".\n// TypeError 1558: (62-83): Constructor must be payable or non-payable, but is \"pure\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_storage.sol",
    "content": "contract A {\n    constructor(uint[] storage a) {}\n}\n// ----\n// TypeError 3644: (29-45): This parameter has a type that can only be used internally. You can make the contract abstract to avoid this problem.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_storage_abstract.sol",
    "content": "abstract contract A {\n    constructor(uint[] storage a) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_this.sol",
    "content": "contract C {\n    function f() public pure {}\n    constructor() {\n        C c = this;\n        c.f(); // this does not warn now, but should warn in the future\n        this.f();\n        (this).f();\n    }\n}\n// ----\n// Warning 5805: (165-169): \"this\" used in constructor. Note that external functions of a contract cannot be called while it is being constructed.\n// Warning 5805: (184-188): \"this\" used in constructor. Note that external functions of a contract cannot be called while it is being constructed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_virtual.sol",
    "content": "contract C {\n    constructor() virtual {}\n}\n// ----\n// TypeError 7001: (17-41): Constructors cannot be virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_visibility.sol",
    "content": "// The constructor of a base class should not be visible in the derived class\ncontract A { constructor(string memory) { } }\ncontract B is A {\n  function f() pure public {\n    A x = A(address(0)); // convert from address\n    string memory y = \"ab\";\n    A(y); // call as a function is invalid\n    x;\n  }\n}\n// ----\n// TypeError 3415: (124-303): No arguments passed to the base constructor. Specify the arguments or mark \"B\" as abstract.\n// TypeError 9640: (252-256): Explicit type conversion not allowed from \"string memory\" to \"contract A\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/constructor_without_implementation.sol",
    "content": "contract C {\n\tconstructor();\n}\n// ----\n// TypeError 5700: (14-28): Constructor must be implemented if declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/external_constructor.sol",
    "content": "contract test {\n\tconstructor() external {}\n}\n// ----\n// TypeError 9239: (17-42): Constructor cannot have visibility.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/function_named_constructor.sol",
    "content": "contract C {\n    function constructor();\n}\n// ----\n// ParserError 3323: (26-37): This function is named \"constructor\" but is not the constructor of the contract. If you intend this to be a constructor, use \"constructor(...) { ... }\" without the \"function\" keyword to define it.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/inconstructible_abstract_contract.sol",
    "content": "abstract contract C {\n\tconstructor() {}\n}\ncontract D {\n\tfunction f() public { C c = new C(); c; }\n}\n// ----\n// TypeError 4614: (84-89): Cannot instantiate an abstract contract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/inconstructible_abstract_contract_inverted.sol",
    "content": "// Previously, the type information for A was not yet available at the point of\n// \"new A\".\ncontract B {\n\tA a;\n\tconstructor() {\n\t\ta = new A(address(this));\n\t}\n}\nabstract contract A {\n\tconstructor(address) {}\n}\n// ----\n// TypeError 4614: (134-139): Cannot instantiate an abstract contract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor.sol",
    "content": "contract C {\n\tconstructor() internal {}\n}\ncontract D {\n\tfunction f() public { C c = new C(); c; }\n}\n// ----\n// DeclarationError 1845: (14-39): Non-abstract contracts cannot have internal constructors. Remove the \"internal\" keyword and make the contract abstract to fix this.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted.sol",
    "content": "// Previously, the type information for A was not yet available at the point of\n// \"new A\".\ncontract B {\n\tA a;\n\tconstructor() {\n\t\ta = new A(address(this));\n\t}\n}\ncontract A {\n\tconstructor(address) internal {}\n}\n// ----\n// DeclarationError 1845: (175-207): Non-abstract contracts cannot have internal constructors. Remove the \"internal\" keyword and make the contract abstract to fix this.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/interface_constructor.sol",
    "content": "interface I {\n\tconstructor();\n}\n// ----\n// TypeError 6482: (15-29): Constructor cannot be defined in interfaces.\n// TypeError 5700: (15-29): Constructor must be implemented if declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/internal_constructor_non_abstract.sol",
    "content": "contract C {\n\tconstructor() internal {}\n}\n// ----\n// DeclarationError 1845: (14-39): Non-abstract contracts cannot have internal constructors. Remove the \"internal\" keyword and make the contract abstract to fix this.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/library_constructor.sol",
    "content": "library Lib {\n\tconstructor();\n}\n// ----\n// TypeError 7634: (15-29): Constructor cannot be defined in libraries.\n// TypeError 5700: (15-29): Constructor must be implemented if declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/msg_value_non_payable.sol",
    "content": "contract C {\n    uint256 value;\n    constructor() {\n        value = msg.value;\n    }\n}\n// ----\n// TypeError 5887: (68-77): \"msg.value\" and \"callvalue()\" can only be used in payable constructors. Make the constructor \"payable\" to avoid this error.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/nonabiv2_type.sol",
    "content": "pragma abicoder v1;\ncontract C {\n\tconstructor(uint[][][] memory t) {}\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 4957: (46-65): This type is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature. Alternatively, make the contract abstract and supply the constructor arguments from a derived contract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/nonabiv2_type_abstract.sol",
    "content": "pragma abicoder v1;\nabstract contract C {\n\tconstructor(uint[][][] memory t) {}\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/nonpayable_new.sol",
    "content": "contract A1 { constructor() {} }\ncontract B1 is A1 {}\n\ncontract A2 { constructor() payable {} }\ncontract B2 is A2 {}\n\ncontract B3 {}\n\ncontract B4 { constructor() {} }\n\ncontract C {\n\tfunction f() public payable {\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\tnew B4{value: 10}();\n\t}\n}\n// ----\n// TypeError 7006: (214-231): Cannot set option \"value\", since the constructor of contract B1 is not payable.\n// TypeError 7006: (237-254): Cannot set option \"value\", since the constructor of contract B2 is not payable.\n// TypeError 7006: (260-277): Cannot set option \"value\", since the constructor of contract B3 is not payable.\n// TypeError 7006: (283-300): Cannot set option \"value\", since the constructor of contract B4 is not payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/not_a_contract.sol",
    "content": "// This used to cause an internal error because of the visitation order.\ncontract Test {\n    struct S { uint a; }\n    function f() public {\n       new S();\n    }\n}\n// ----\n// TypeError 5540: (147-152): Identifier is not a contract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/overriding_constructor.sol",
    "content": "contract A { function f() public {} }\ncontract B is A {\n  function A() public pure returns (uint8) {}\n  function g() public {\n    A.f();\n  }\n}\n// ----\n// Warning 2519: (58-101): This declaration shadows an existing declaration.\n// TypeError 9582: (130-133): Member \"f\" not found or not visible after argument-dependent lookup in function () pure returns (uint8).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/payable_new.sol",
    "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable {\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/public_constructor_abstract.sol",
    "content": "abstract contract C {\n\tconstructor() public {}\n}\n// ----\n// DeclarationError 8295: (23-46): Abstract contracts cannot have public constructors. Remove the \"public\" keyword to fix this.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/public_constructor_non_abstract.sol",
    "content": "contract C {\n\tconstructor() public {}\n}\n// ----\n// Warning 2462: (14-37): Visibility for constructor is ignored. If you want the contract to be non-deployable, making it \"abstract\" is sufficient.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/returns_in_constructor.sol",
    "content": "contract test {\n\tconstructor() returns (uint a) { }\n}\n// ----\n// TypeError 9712: (39-47): Non-empty \"returns\" directive for constructor.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/constructor/two_constructors.sol",
    "content": "contract test {\n\tconstructor(uint) { }\n\tconstructor() {}\n}\n// ----\n// DeclarationError 7997: (40-56): More than one constructor defined.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/calldataReturn/calldata_return_dynamic_array.sol",
    "content": "contract C {\n    function f() internal returns (uint256[] calldata) {}\n}\n// ----\n// TypeError 3464: (48-66): This variable is of calldata pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/calldataReturn/calldata_return_static_array.sol",
    "content": "contract C {\n    function f() internal returns (uint256[1] calldata) {}\n}\n// ----\n// TypeError 3464: (48-67): This variable is of calldata pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/calldataReturn/calldata_return_struct.sol",
    "content": "contract C {\n    struct S { uint256 x; }\n    function f() internal returns (S calldata) {}\n}\n// ----\n// TypeError 3464: (76-86): This variable is of calldata pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/free_function_crash.sol",
    "content": "contract C0 {\n  function f() external {}\n  function f(int) external {}\n  function f2() external {}\n}\nfunction f() {}\ncontract C {\n  function f() external {}\n}\ncontract C2 is C0 {}\n// ----\n// Warning 2519: (16-40): This declaration shadows an existing declaration.\n// Warning 2519: (43-70): This declaration shadows an existing declaration.\n// Warning 2519: (132-156): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/leave_inside_function.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            function f() {\n                // Make sure this doesn't trigger the unimplemented assertion in the control flow builder.\n                leave\n            }\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/leave_outside_function.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            // Make sure this doesn't trigger the unimplemented assertion in the control flow builder.\n            leave\n        }\n    }\n}\n// ----\n// SyntaxError 8149: (178-183): Keyword \"leave\" can only be used inside a function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localCalldataVariables/if_declaration_err.sol",
    "content": "contract C {\n    function f(uint[] calldata _c) public pure {\n        uint[] calldata c;\n        if (_c[2] > 10)\n            c = _c;\n        c[2];\n    }\n}\n// ----\n// TypeError 3464: (141-142): This variable is of calldata pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localCalldataVariables/if_declaration_fine.sol",
    "content": "contract C {\n    function f(uint[] calldata _c) public pure {\n        uint[] calldata c;\n        if (_c[2] > 10)\n            c = _c;\n        else\n            c = _c;\n        c[2];\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localCalldataVariables/smoke_declaration.sol",
    "content": "contract C {\n    function g() internal pure returns (bytes calldata) {\n        return msg.data;\n    }\n    function h(uint[] calldata _c) internal pure {\n        uint[] calldata c;\n        c = _c;\n        c[2];\n    }\n    function i(uint[] calldata _c) internal pure {\n        uint[] calldata c;\n        (c) = _c;\n        c[2];\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/assembly/for_declaration_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure {\n        S storage c;\n        assembly {\n            for {} eq(0,0) { c.slot := s.slot } {}\n        }\n        c;\n    }\n    function g() internal pure {\n        S storage c;\n        assembly {\n            for {} eq(0,1) { c.slot := s.slot } {}\n        }\n        c;\n    }\n    function h() internal pure {\n        S storage c;\n        assembly {\n            for {} eq(0,0) {} { c.slot := s.slot }\n        }\n        c;\n    }\n    function i() internal pure {\n        S storage c;\n        assembly {\n            for {} eq(0,1) {} { c.slot := s.slot }\n        }\n        c;\n    }\n}\n// ----\n// TypeError 3464: (189-190): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (340-341): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (491-492): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (642-643): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/assembly/for_declaration_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure {\n        S storage c;\n        assembly {\n            for { c.slot := s.slot } iszero(0) {} {}\n        }\n        c;\n    }\n    function g() internal pure {\n        S storage c;\n        assembly {\n            for { c.slot := s.slot } iszero(1) {} {}\n        }\n        c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/assembly/if_declaration_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal pure {\n        S storage c;\n        assembly {\n            if flag { c.slot := s.slot }\n        }\n        c;\n    }\n}\n// ----\n// TypeError 3464: (188-189): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/assembly/returning_function_declaration.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure {\n        S storage c;\n        // this should warn about unreachable code, but currently function flow is ignored\n        assembly {\n            function f() { return(0, 0) }\n            f()\n            c.slot := s.slot\n        }\n        c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/assembly/reverting_function_declaration.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure {\n        S storage c;\n        // this could be allowed, but currently control flow for functions is not analysed\n        assembly {\n            function f() { revert(0, 0) }\n            f()\n        }\n        c;\n    }\n}\n// ----\n// TypeError 3464: (287-288): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/assembly/stub_declaration.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure {\n        S storage c;\n        assembly {\n            c.slot := s.slot\n        }\n        c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/assembly/switch_declaration_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(uint256 a) internal pure {\n        S storage c;\n        assembly {\n            switch a\n            case 0 { c.slot := s.slot }\n        }\n        c;\n    }\n    function g(bool flag) internal pure {\n        S storage c;\n        assembly {\n            switch flag\n            case 0 { c.slot := s.slot }\n            case 1 { c.slot := s.slot }\n        }\n        c;\n    }\n    function h(uint256 a) internal pure {\n        S storage c;\n        assembly {\n            switch a\n            case 0 { c.slot := s.slot }\n            default { return(0,0) }\n        }\n        c;\n    }\n}\n// ----\n// TypeError 3464: (208-209): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (421-422): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/assembly/switch_declaration_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal pure {\n        S storage c;\n        assembly {\n            switch flag\n            case 0 { c.slot := s.slot }\n            default { c.slot := s.slot }\n        }\n        c;\n    }\n    function g(uint256 a) internal pure {\n        S storage c;\n        assembly {\n            switch a\n            case 0 { revert(0, 0) }\n            default { c.slot := s.slot }\n        }\n        c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/dowhile_declaration_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view {\n        S storage c;\n        do {\n            break;\n            c = s;\n        } while(false);\n        c;\n    }\n    function g() internal view {\n        S storage c;\n        do {\n            if (s.f) {\n                continue;\n                c = s;\n            }\n            else {\n            }\n        } while(false);\n        c;\n    }\n    function h() internal view {\n        S storage c;\n        do {\n            if (s.f) {\n                break;\n            }\n            else {\n                c = s;\n            }\n        } while(false);\n        c;\n    }\n    function i() internal view {\n        S storage c;\n        do {\n            if (s.f) {\n                continue;\n            }\n            else {\n                c = s;\n            }\n        } while(false);\n        c;\n    }\n    function j() internal view {\n        S storage c;\n        do {\n            continue;\n            c = s;\n        } while(false);\n        c;\n    }\n}\n// ----\n// TypeError 3464: (184-185): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// Warning 5740: (145-150): Unreachable code.\n// Warning 5740: (168-173): Unreachable code.\n// TypeError 3464: (411-412): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// Warning 5740: (325-330): Unreachable code.\n// TypeError 3464: (635-636): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (862-863): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (1011-1012): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// Warning 5740: (972-977): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/dowhile_declaration_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view {\n        S storage c;\n        do {} while((c = s).f);\n        c;\n    }\n    function g() internal view {\n        S storage c;\n        do { c = s; } while(false);\n        c;\n    }\n    function h() internal view {\n        S storage c;\n        c = s;\n        do {} while(false);\n        c;\n    }\n    function i() internal view {\n        S storage c;\n        do {} while(false);\n        c = s;\n        c;\n    }\n    function j() internal view {\n        S storage c;\n        do {\n            c = s;\n            break;\n        } while(false);\n        c;\n    }\n    function k() internal view {\n        S storage c;\n        do {\n            c = s;\n            continue;\n        } while(false);\n        c;\n    }\n}\n// ----\n// Warning 5740: (606-611): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/for_declaration_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view {\n        S storage c;\n        for(;; c = s) {\n        }\n        c;\n    }\n    function g() internal view {\n        S storage c;\n        for(;;) {\n            c = s;\n        }\n        c;\n    }\n}\n// ----\n// TypeError 3464: (143-144): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (261-262): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/for_declaration_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view {\n        S storage c;\n        for(c = s;;) {\n        }\n        c;\n    }\n    function g() internal view {\n        S storage c;\n        for(; (c = s).f;) {\n        }\n        c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/if_declaration_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal {\n        S storage c;\n        if (flag) c = s;\n        c;\n    }\n    function g(bool flag) internal {\n        S storage c;\n        if (flag) c = s;\n        else\n        {\n            if (!flag) c = s;\n            else s.f = true;\n        }\n        c;\n    }\n}\n// ----\n// TypeError 3464: (138-139): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (330-331): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/if_declaration_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal view {\n        S storage c;\n        if (flag) c = s;\n        else c = s;\n        c;\n    }\n    function g(bool flag) internal view {\n        S storage c;\n        if (flag) c = s;\n        else { c = s; }\n        c;\n    }\n    function h(bool flag) internal view {\n        S storage c;\n        if (flag) c = s;\n        else\n        {\n            if (!flag) c = s;\n            else c = s;\n        }\n        c;\n    }\n    function i() internal view {\n        S storage c;\n        if ((c = s).f) {\n        }\n        c;\n    }\n    function j() internal view {\n        S storage c;\n        if ((c = s).f && !(c = s).f) {\n        }\n        c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/modifier_declaration_fine.sol",
    "content": "contract C {\n    modifier alwaysRevert() {\n        _;\n        revert();\n    }\n    modifier ifFlag(bool flag) {\n        if (flag)\n            _;\n    }\n    struct S { uint a; }\n    S s;\n    function f(bool flag) alwaysRevert() internal view {\n        if (flag) s;\n    }\n    function g(bool flag) alwaysRevert() ifFlag(flag) internal view {\n        s;\n    }\n\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/revert_declaration_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function g(bool flag) internal view {\n        S storage c;\n        if (flag) c = s;\n        else revert();\n        s;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/short_circuit_declaration_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view {\n        S storage c;\n        false && (c = s).f;\n        c;\n    }\n    function g() internal view {\n        S storage c;\n        true || (c = s).f;\n        c;\n    }\n    function h() internal view {\n        S storage c;\n        // expect error, although this is always fine\n        true && (false || (c = s).f);\n        c;\n    }\n}\n// ----\n// TypeError 3464: (137-138): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (235-236): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (398-399): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/short_circuit_declaration_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view {\n        S storage c;\n        (c = s).f && false;\n        c;\n    }\n    function g() internal view {\n        S storage c;\n        (c = s).f || true;\n        c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/smoke_declaration.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure {}\n    function g() internal view { s; }\n    function h() internal view {\n        S storage c;\n        c = s;\n        c;\n    }\n    function i() internal view {\n        S storage c;\n        (c) = s;\n        c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/ternary_assignment_err.sol",
    "content": "contract C {\n    uint256[] s;\n    function f() public {\n        bool d;\n        uint256[] storage x;\n        uint256[] storage y = d ? (x = s) : x;\n        y;\n    }\n}\n// ----\n// TypeError 3464: (145-146): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/ternary_assignment_fine.sol",
    "content": "contract C {\n    uint256[] s;\n    function f() public view {\n        uint256[] storage x;\n        uint256[] storage y = (x = s)[0] > 0 ? x : x;\n        y;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/ternary_declaration_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal view {\n        S storage c;\n        flag ? (c = s).f : false;\n        c;\n    }\n    function g(bool flag) internal view {\n        S storage c;\n        flag ? false : (c = s).f;\n        c;\n    }\n}\n// ----\n// TypeError 3464: (152-153): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (266-267): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/ternary_declaration_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal view {\n        S storage c;\n        flag ? c = s : c = s;\n        c;\n    }\n    function g(bool flag) internal view {\n        S storage c;\n        flag ? c = s : (c = s);\n        c;\n    }\n    function h(bool flag) internal view {\n        S storage c;\n        flag ? (c = s).f : (c = s).f;\n        c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/try_declaration_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function ext() external {}\n    function f() internal\n    {\n        S storage r;\n        try this.ext() { }\n        catch (bytes memory) { r = s; }\n        r;\n    }\n    function g() internal\n    {\n        S storage r;\n        try this.ext() { r = s; }\n        catch (bytes memory) { }\n        r;\n    }\n    function h() internal\n    {\n        S storage r;\n        try this.ext() {}\n        catch Error (string memory) { r = s; }\n        catch (bytes memory) { r = s; }\n        r;\n    }\n    function i() internal\n    {\n        S storage r;\n        try this.ext() { r = s; }\n        catch (bytes memory) { r; }\n        r = s;\n        r;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// TypeError 3464: (206-207): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (343-344): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (526-527): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (653-654): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/try_declaration_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function ext() external { }\n    function f() internal\n    {\n        S storage r;\n        try this.ext() { r = s; }\n        catch (bytes memory) { r = s; }\n        r;\n    }\n    function g() internal\n    {\n        S storage r;\n        try this.ext() { r = s; }\n        catch Error (string memory) { r = s; }\n        catch (bytes memory) { r = s; }\n        r;\n    }\n    function h() internal\n    {\n        S storage r;\n        try this.ext() { }\n        catch (bytes memory) { }\n        r = s;\n        r;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/tuple_declaration_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view returns (S storage, uint) {\n      return (s,2);\n    }\n    function g() internal view {\n        uint a;\n        S storage c;\n        (c, a) = f();\n        c;\n    }\n    function h() internal view {\n        (s, s);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/while_declaration_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view {\n        S storage c;\n        while(false) {\n            c = s;\n        }\n        c;\n    }\n}\n// ----\n// TypeError 3464: (161-162): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/localStorageVariables/while_declaration_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view {\n        S storage c;\n        while((c = s).f) {\n        }\n        c;\n    }\n    function g() internal view {\n        S storage c;\n        c = s;\n        while(false) {\n        }\n        c;\n    }\n    function h() internal view {\n        S storage c;\n        while(false) {\n        }\n        c = s;\n        c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/mappingReturn/named_err.sol",
    "content": "contract C {\n    function f() internal pure returns (mapping(uint=>uint) storage r) { }\n}\n// ----\n// TypeError 3464: (53-82): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/mappingReturn/named_fine.sol",
    "content": "contract C {\n    mapping(uint=>uint) m;\n    function f() internal view returns (mapping(uint=>uint) storage r) { r = m; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/mappingReturn/unnamed_err.sol",
    "content": "contract C {\n    function f() internal pure returns (mapping(uint=>uint) storage) {}\n}\n// ----\n// TypeError 3464: (53-80): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/mappingReturn/unnamed_fine.sol",
    "content": "contract C {\n    mapping(uint=>uint) m;\n    function f() internal view returns (mapping(uint=>uint) storage) { return m; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/modifiers/implemented_without_placeholder.sol",
    "content": "abstract contract A {\n    function f() public view mod {\n        require(block.timestamp > 10);\n    }\n    modifier mod() virtual { }\n}\n// ----\n// SyntaxError 2883: (129-132): Modifier body does not contain '_'.\n// Warning 8429: (106-132): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/modifiers/modifier_different_functions.sol",
    "content": "contract A {\n\tfunction f() mod internal returns (uint[] storage) {\n\t\trevert();\n\t}\n\tfunction g() mod internal returns (uint[] storage) {\n\t}\n\tmodifier mod() virtual {\n\t\t_;\n\t}\n}\n// ----\n// Warning 8429: (140-172): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 3464: (118-132): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/modifiers/modifier_override.sol",
    "content": "contract A {\n\tfunction f() mod internal returns (uint[] storage) {\n\t}\n\tmodifier mod() virtual {\n\t\trevert();\n\t\t_;\n\t}\n}\ncontract B is A {\n\tmodifier mod() override { _; }\n\tfunction g() public {\n\t\tf()[0] = 42;\n\t}\n}\n// ----\n// Warning 8429: (71-115): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 5740: (65-69): Unreachable code.\n// TypeError 3464: (49-63): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/modifiers/non_implemented_modifier.sol",
    "content": "abstract contract A {\n    function f() public view mod {\n        require(block.timestamp > 10);\n    }\n    modifier mod() virtual;\n}\n// ----\n// Warning 8429: (106-129): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly/for_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure returns (S storage c) {\n        assembly {\n            for {} eq(0,0) { c.slot := s.slot } {}\n        }\n    }\n    function g() internal pure returns (S storage c) {\n        assembly {\n            for {} eq(0,1) { c.slot := s.slot } {}\n        }\n    }\n    function h() internal pure returns (S storage c) {\n        assembly {\n            for {} eq(0,0) {} { c.slot := s.slot }\n        }\n    }\n    function i() internal pure returns (S storage c) {\n        assembly {\n            for {} eq(0,1) {} { c.slot := s.slot }\n        }\n    }\n}\n// ----\n// TypeError 3464: (87-98): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (228-239): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (369-380): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (510-521): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly/for_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure returns (S storage c) {\n        assembly {\n            for { c.slot := s.slot } iszero(0) {} {}\n        }\n    }\n    function g() internal pure returns (S storage c) {\n        assembly {\n            for { c.slot := s.slot } iszero(1) {} {}\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly/if_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal pure returns (S storage c) {\n        assembly {\n            if flag { c.slot := s.slot }\n        }\n    }\n}\n// ----\n// TypeError 3464: (96-107): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly/returning_function.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure returns (S storage c) {\n        // this should warn about unreachable code, but currently function flow is ignored\n        assembly {\n            function f() { return(0, 0) }\n            f()\n            c.slot := s.slot\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly/reverting_function.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure returns (S storage c) {\n        // this could be allowed, but currently control flow for functions is not analysed\n        assembly {\n            function f() { revert(0, 0) }\n            f()\n        }\n    }\n}\n// ----\n// TypeError 3464: (87-98): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly/stub.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure returns (S storage c) {\n        assembly {\n            c.slot := s.slot\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly/switch_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(uint256 a) internal pure returns (S storage c) {\n        assembly {\n            switch a\n            case 0 { c.slot := s.slot }\n        }\n    }\n    function g(bool flag) internal pure returns (S storage c) {\n        assembly {\n            switch flag\n            case 0 { c.slot := s.slot }\n            case 1 { c.slot := s.slot }\n        }\n    }\n    function h(uint256 a) internal pure returns (S storage c) {\n        assembly {\n            switch a\n            case 0 { c.slot := s.slot }\n            default { return(0,0) }\n        }\n    }\n}\n// ----\n// TypeError 3464: (96-107): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (256-267): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly/switch_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal pure returns (S storage c) {\n        assembly {\n            switch flag\n            case 0 { c.slot := s.slot }\n            default { c.slot := s.slot }\n        }\n    }\n    function g(uint256 a) internal pure returns (S storage c) {\n        assembly {\n            switch a\n            case 0 { revert(0, 0) }\n            default { c.slot := s.slot }\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly/switch_only_default_warn.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(uint256 a) internal pure returns (S storage c) {\n        assembly {\n            switch a\n                default { c.slot := s.slot }\n        }\n    }\n}\n// ----\n// Warning 9592: (142-195): \"switch\" statement with only a default case.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/assembly_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure returns (S storage) {\n        assembly {\n        }\n    }\n}\n// ----\n// TypeError 3464: (87-96): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/default_location.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view returns (S memory c) {\n        c = s;\n    }\n    function g() internal view returns (S memory) {\n        return s;\n    }\n    function h() internal pure returns (S memory) {\n    }\n    function i(bool flag) internal view returns (S memory c) {\n        if (flag) c = s;\n    }\n    function j(bool flag) internal view returns (S memory) {\n        if (flag) return s;\n    }\n}\n// ----\n// Warning 6321: (399-407): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/dowhile_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view returns (S storage c) {\n        do {\n            break;\n            c = s;\n        } while(false);\n    }\n    function g() internal view returns (S storage c) {\n        do {\n            if (s.f) {\n                continue;\n                c = s;\n            }\n            else {\n            }\n        } while(false);\n    }\n    function h() internal view returns (S storage c) {\n        do {\n            if (s.f) {\n                break;\n            }\n            else {\n                c = s;\n            }\n        } while(false);\n    }\n    function i() internal view returns (S storage c) {\n        do {\n            if (s.f) {\n                continue;\n            }\n            else {\n                c = s;\n            }\n        } while(false);\n    }\n    function j() internal view returns (S storage c) {\n        do {\n            continue;\n            c = s;\n        } while(false);\n    }\n}\n// ----\n// TypeError 3464: (87-98): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// Warning 5740: (146-151): Unreachable code.\n// Warning 5740: (169-174): Unreachable code.\n// TypeError 3464: (223-234): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// Warning 5740: (316-321): Unreachable code.\n// TypeError 3464: (440-451): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (654-665): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (871-882): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// Warning 5740: (933-938): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/dowhile_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view returns (S storage c) {\n        do {} while((c = s).f);\n    }\n    function g() internal view returns (S storage c) {\n        do { c = s; } while(false);\n    }\n    function h() internal view returns (S storage c) {\n        c = s;\n        do {} while(false);\n    }\n    function i() internal view returns (S storage c) {\n        do {} while(false);\n        c = s;\n    }\n    function j() internal view returns (S storage c) {\n        do {\n            c = s;\n            break;\n        } while(false);\n    }\n    function k() internal view returns (S storage c) {\n        do {\n            c = s;\n            continue;\n        } while(false);\n    }\n}\n// ----\n// Warning 5740: (567-572): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/for_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view returns (S storage c) {\n        for(;; c = s) {\n        }\n    }\n    function g() internal view returns (S storage c) {\n        for(;;) {\n            c = s;\n        }\n    }\n}\n// ----\n// TypeError 3464: (87-98): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (182-193): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/for_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view returns (S storage c) {\n        for(c = s;;) {\n        }\n    }\n    function g() internal view returns (S storage c) {\n        for(; (c = s).f;) {\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/if_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal view returns (S storage c) {\n        if (flag) c = s;\n    }\n    function g(bool flag) internal returns (S storage c) {\n        if (flag) c = s;\n        else\n        {\n            if (!flag) c = s;\n            else s.f = true;\n        }\n    }\n}\n// ----\n// TypeError 3464: (96-107): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (186-197): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/if_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal view returns (S storage c) {\n        if (flag) c = s;\n        else c = s;\n    }\n    function g(bool flag) internal view returns (S storage c) {\n        if (flag) c = s;\n        else { c = s; }\n    }\n    function h(bool flag) internal view returns (S storage c) {\n        if (flag) c = s;\n        else\n        {\n            if (!flag) c = s;\n            else c = s;\n        }\n    }\n    function i() internal view returns (S storage c) {\n        if ((c = s).f) {\n        }\n    }\n    function j() internal view returns (S storage c) {\n        if ((c = s).f && !(c = s).f) {\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/modifier_err.sol",
    "content": "contract C {\n    modifier callAndRevert() {\n        _;\n        revert();\n    }\n    modifier ifFlag(bool flag) {\n        if (flag)\n            _;\n    }\n    struct S { uint a; }\n    S s;\n    function f(bool flag) ifFlag(flag) internal view returns(S storage) {\n        return s;\n    }\n\n    function g(bool flag) ifFlag(flag) callAndRevert() internal view returns(S storage) {\n        return s;\n    }\n}\n// ----\n// TypeError 3464: (246-255): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (361-370): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/modifier_fine.sol",
    "content": "contract C {\n    modifier callAndRevert() {\n        _;\n        revert();\n    }\n    modifier ifFlag(bool flag) {\n        if (flag)\n            _;\n    }\n    struct S { uint a; }\n    S s;\n    function f(bool flag) callAndRevert() internal view returns(S storage) {\n        if (flag) return s;\n    }\n    function g(bool flag) callAndRevert() ifFlag(flag) internal view returns(S storage) {\n        return s;\n    }\n\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/revert_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure returns (S storage) {\n        revert();\n    }\n    function g(bool flag) internal view returns (S storage c) {\n        if (flag) c = s;\n        else revert();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/short_circuit_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view returns (S storage c) {\n        false && (c = s).f;\n    }\n    function g() internal view returns (S storage c) {\n        true || (c = s).f;\n    }\n    function h() internal view returns (S storage c) {\n        // expect error, although this is always fine\n        true && (false || (c = s).f);\n    }\n}\n// ----\n// TypeError 3464: (87-98): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (176-187): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (264-275): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/short_circuit_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view returns (S storage c) {\n        (c = s).f && false;\n    }\n    function g() internal view returns (S storage c) {\n        (c = s).f || true;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/smoke.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal pure {}\n    function g() internal view returns (S storage) { return s; }\n    function h() internal view returns (S storage c) { return s; }\n    function i() internal view returns (S storage c) { c = s; }\n    function j() internal view returns (S storage c) { (c) = s; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/ternary_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal view returns (S storage c) {\n        flag ? (c = s).f : false;\n    }\n    function g(bool flag) internal view returns (S storage c) {\n        flag ? false : (c = s).f;\n    }\n}\n// ----\n// TypeError 3464: (96-107): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (200-211): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/ternary_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f(bool flag) internal view returns (S storage c) {\n        flag ? c = s : c = s;\n    }\n    function g(bool flag) internal view returns (S storage c) {\n        flag ? c = s : (c = s);\n    }\n    function h(bool flag) internal view returns (S storage c) {\n        flag ? (c = s).f : (c = s).f;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/try_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function ext() external {}\n    function f() internal returns (S storage r)\n    {\n        try this.ext() { }\n        catch (bytes memory) { r = s; }\n    }\n    function g() internal returns (S storage r)\n    {\n        try this.ext() { r = s; }\n        catch (bytes memory) { }\n    }\n    function h() internal returns (S storage r)\n    {\n        try this.ext() {}\n        catch Error (string memory) { r = s; }\n        catch (bytes memory) { r = s; }\n    }\n    function i() internal returns (S storage r)\n    {\n        try this.ext() { r = s; }\n        catch (bytes memory) { return r; }\n        r = s;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// TypeError 3464: (113-124): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (240-251): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (367-378): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (631-632): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/try_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function ext() external { }\n    function f() internal returns (S storage r)\n    {\n        try this.ext() { r = s; }\n        catch (bytes memory) { r = s; }\n    }\n    function g() internal returns (S storage r)\n    {\n        try this.ext() { r = s; }\n        catch Error (string memory) { r = s; }\n        catch (bytes memory) { r = s; }\n    }\n    function h() internal returns (S storage r)\n    {\n        try this.ext() { }\n        catch (bytes memory) { }\n        r = s;\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/tuple_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view returns (S storage, uint) {\n        return (s,2);\n    }\n    function g() internal view returns (S storage c) {\n        uint a;\n        (c, a) = f();\n    }\n    function h() internal view returns (S storage, S storage) {\n        return (s,s);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/unimplemented_internal.sol",
    "content": "abstract contract C {\n    function f() internal virtual returns(uint[] storage);\n    function g() internal virtual returns(uint[] storage s);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/unimplemented_library.sol",
    "content": "// This used to work pre-0.6.0.\nlibrary L {\n    function f() public returns(uint[] storage);\n    function g() public returns(uint[] storage s);\n}\nabstract library T {\n    function f() public returns(uint[] storage);\n    function g() public returns(uint[] storage s);\n}\n// ----\n// TypeError 9571: (146-268): Libraries cannot be abstract.\n// TypeError 9231: (48-92): Library functions must be implemented if declared.\n// TypeError 9231: (97-143): Library functions must be implemented if declared.\n// TypeError 9231: (171-215): Library functions must be implemented if declared.\n// TypeError 9231: (220-266): Library functions must be implemented if declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/while_err.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view returns (S storage c) {\n        while(false) {\n            c = s;\n        }\n    }\n}\n// ----\n// TypeError 3464: (87-98): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/storageReturn/while_fine.sol",
    "content": "contract C {\n    struct S { bool f; }\n    S s;\n    function f() internal view returns (S storage c) {\n        while((c = s).f) {\n        }\n    }\n    function g() internal view returns (S storage c) {\n        c = s;\n        while(false) {\n        }\n    }\n    function h() internal view returns (S storage c) {\n        while(false) {\n        }\n        c = s;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/always_revert.sol",
    "content": "contract C {\n    function f() internal view returns(uint[] storage a)\n    {\n        uint b = a[0];\n        revert();\n        b;\n    }\n}\n// ----\n// Warning 5740: (125-126): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/assembly.sol",
    "content": "contract C {\n\tuint[] r;\n    function f() internal view returns (uint[] storage s) {\n        assembly { pop(s.slot) }\n        s = r;\n    }\n}\n// ----\n// TypeError 3464: (107-113): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/bug10821-for.sol",
    "content": "contract Test {\n\tfunction testFunc() external {\n\t\tfor (;;) {}\n\t\tbytes storage b;\n\t\tb[0] = 0x42;\n\t}\n}\n// ----\n// TypeError 3464: (83-84): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/bug10821-if.sol",
    "content": "contract Test {\n\n  struct Sample { bool flag; }\n  Sample public s;\n\n   function testFunc() external {\n        if(true){}\n        Sample storage t;\n        t.flag=true;\n    }\n}\n// ----\n// TypeError 3464: (155-156): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/bug10821-modifier.sol",
    "content": "contract Test {\n\n  struct Sample { bool flag; }\n  Sample public s;\n\n  modifier checkAddr(address _a){\n      require(_a!=address(0));\n      _;\n  }\n  function testFunc(address _a) external checkAddr(_a) {\n        Sample storage t;\n        t.flag=true;\n    }\n}\n// ----\n// TypeError 3464: (237-238): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/bug10821-require.sol",
    "content": "contract Test {\n\tfunction testFunc() external {\n\t\trequire(true);\n\t\tbytes storage b;\n\t\tb[0] = 0x42;\n\t}\n}\n// ----\n// TypeError 3464: (86-87): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/bug10821-while.sol",
    "content": "contract Test {\n\tfunction testFunc() external {\n\t\twhile (true) {}\n\t\tbytes storage b;\n\t\tb[0] = 0x42;\n\t}\n}\n// ----\n// TypeError 3464: (87-88): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/functionType.sol",
    "content": "contract C {\n    // Make sure function parameters and return values are not considered\n    // for uninitialized return detection in the control flow analysis.\n    function f(function(uint[] storage) internal returns (uint[] storage)) internal pure\n    returns (function(uint[] storage) internal returns (uint[] storage))\n    {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/modifier_order_fail.sol",
    "content": "contract C {\n    modifier m1(uint[] storage a) { _; }\n    modifier m2(uint[] storage a) { _; }\n    uint[] s;\n    function f() m1(b) m2(b = s) internal view returns (uint[] storage b) {}\n}\n// ----\n// TypeError 3464: (129-130): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/modifier_order_fine.sol",
    "content": "contract C {\n    modifier m1(uint[] storage a) { _; }\n    modifier m2(uint[] storage a) { _; }\n    uint[] s;\n    function f() m1(b = s) m2(b) internal view returns (uint[] storage b) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/modifier_post_access.sol",
    "content": "contract C {\n    uint[] s;\n    modifier mod(uint[] storage b) {\n        _;\n        b[0] = 0;\n    }\n    function f() mod(a) internal returns (uint[] storage a)\n    {\n\t\ta = s;\n    }\n}\n// ----\n// TypeError 3464: (120-121): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/modifier_pre_access.sol",
    "content": "contract C {\n    uint[] s;\n    modifier mod(uint[] storage b) {\n        b[0] = 0;\n        _;\n    }\n    function f() mod(a) internal returns (uint[] storage a)\n    {\n\t\ta = s;\n    }\n}\n// ----\n// TypeError 3464: (120-121): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call.sol",
    "content": "contract C\n{\n        function iWillRevert() pure public { revert(); }\n\n        function test(bool _param) pure external returns(uint256)\n        {\n                if (_param) return 1;\n\n                iWillRevert();\n        }\n}\n\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_free_function.sol",
    "content": "function iWillRevert() pure { revert(); }\n\ncontract C {\n\tfunction test(bool _param) pure external returns(uint256) {\n\t\tif (_param)\n\t\t\treturn 1;\n\n\t\tiWillRevert();\n\t}\n}\n\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_library.sol",
    "content": "library L\n{\n\tfunction iWillRevert() public pure { revert(); }\n}\n\ncontract C\n{\n\tfunction test(bool _param) pure external returns(uint256)\n\t{\n\t\tif (_param) return 1;\n\n\t\tL.iWillRevert();\n\t}\n}\n\n// ----\n// Warning 6321: (128-135): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_nested.sol",
    "content": "contract C\n{\n        function iWillRevertLevel1() pure public { revert(); }\n        function iWillRevert() pure public { iWillRevertLevel1(); }\n\n        function test(bool _param) pure external returns(uint256)\n        {\n                if (_param) return 1;\n\n                iWillRevert();\n        }\n}\n\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_nested1.sol",
    "content": "contract C\n{\n        function iWillRevertLevel2() pure public { revert(); }\n        function iWillRevertLevel1() pure public { iWillRevertLevel2(); }\n        function iWillRevert() pure public { iWillRevertLevel1(); }\n\n        function test(bool _param) pure external returns(uint256)\n        {\n                if (_param) return 1;\n\n                iWillRevert();\n        }\n}\n\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_recursive.sol",
    "content": "contract C\n{\n\tfunction iWillRevertLevel2(bool _recurse) pure public\n\t{\n\t\tif (_recurse)\n\t\t\tiWillRevertLevel1();\n\t\telse\n\t\t\trevert();\n\t}\n\n\tfunction iWillRevertLevel1() pure public { iWillRevertLevel2(true); }\n\tfunction iWillRevert() pure public { iWillRevertLevel1(); }\n\n\tfunction test(bool _param) pure external returns(uint256)\n\t{\n\t\tif (_param) return 1;\n\n\t\tiWillRevert();\n\t}\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_static.sol",
    "content": "abstract contract B\n{\n        function iWillRevert() pure public virtual { revert(); }\n}\n\nabstract contract X\n{\n        function iWillRevert() pure public virtual { revert(); }\n}\n\ncontract C is B, X\n{\n        function iWillRevert() pure public override(B, X) {  }\n\n        function test(bool _param) pure external returns(uint256)\n        {\n                if (_param) return 1;\n\n                B.iWillRevert();\n        }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_super.sol",
    "content": "abstract contract B\n{\n        function iWillRevert() pure public virtual { revert(); }\n}\n\ncontract C is B\n{\n        function iWillRevert() pure public override {  }\n\n        function test(bool _param) pure external returns(uint256)\n        {\n                if (_param) return 1;\n\n                super.iWillRevert();\n        }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_virtual.sol",
    "content": "abstract contract B\n{\n        function iWillRevert() pure public virtual { revert(); }\n\n        function test2(bool _param) pure external returns(uint256)\n        {\n                if (_param) return 1;\n\n                iWillRevert();\n        }\n}\n\ncontract C is B\n{\n        function iWillRevert() pure public override {  }\n\n        function test(bool _param) pure external returns(uint256)\n        {\n                if (_param) return 1;\n\n                iWillRevert();\n        }\n}\n\n// ----\n// Warning 6321: (146-153): Unnamed return variable can remain unassigned when the function is called when \"C\" is the most derived contract. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (381-388): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_virtual1.sol",
    "content": "abstract contract B\n{\n        function iWillRevert() pure public virtual { }\n}\n\ncontract C is B\n{\n        function iWillRevert() pure public override { revert(); }\n\n        function test(bool _param) pure external returns(uint256)\n        {\n                if (_param) return 1;\n\n                iWillRevert();\n        }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_virtual2.sol",
    "content": "abstract contract B\n{\n        function iWillRevert() pure public virtual { }\n\n        function test(bool _param) pure external returns(uint256)\n        {\n                if (_param) return 1;\n\n                iWillRevert();\n        }\n}\n\ncontract C is B\n{\n        function iWillRevert() pure public override { revert(); }\n}\n\n// ----\n// Warning 6321: (135-142): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_virtual3.sol",
    "content": "contract A {\n  function f() public virtual returns (uint) { g(); }\n  function g() internal virtual { revert(); }\n}\ncontract B is A {\n  function f() public override returns (uint) { A.f(); }\n  function g() internal override {}\n}\n// ----\n// Warning 6321: (52-56): Unnamed return variable can remain unassigned when the function is called when \"B\" is the most derived contract. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (173-177): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/reverting_call_virtual4.sol",
    "content": "contract A {\n  function f() public virtual returns (uint) { g(); }\n  function g() internal virtual { revert(); }\n}\ncontract B is A {\n  function f() public virtual override returns (uint) { A.f(); }\n  function g() internal virtual override { A.g(); }\n}\ncontract C is B {\n  function f() public virtual override returns (uint) { A.f(); }\n  function g() internal virtual override { }\n}\n// ----\n// Warning 6321: (52-56): Unnamed return variable can remain unassigned when the function is called when \"C\" is the most derived contract. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (181-185): Unnamed return variable can remain unassigned when the function is called when \"C\" is the most derived contract. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (318-322): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/smoke.sol",
    "content": "contract C {\n    uint[] s;\n    function f() internal returns (uint[] storage a)\n    {\n        a[0] = 0;\n        a = s;\n    }\n}\n// ----\n// TypeError 3464: (94-95): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/struct.sol",
    "content": "contract C {\n    struct S { uint a; }\n    S s;\n    function f() internal returns (S storage r)\n    {\n        r.a = 0;\n        r = s;\n    }\n}\n// ----\n// TypeError 3464: (109-110): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/uninitializedAccess/unreachable.sol",
    "content": "contract C {\n    uint[] s;\n    function f() internal returns (uint[] storage a)\n    {\n        revert();\n        a[0] = 0;\n        a = s;\n    }\n}\n// ----\n// Warning 5740: (112-135): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/assembly/double_revert.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            revert(0, 0)\n            revert(0, 0)\n        }\n    }\n    function g() public pure {\n        assembly {\n            revert(0, 0)\n        }\n        revert();\n    }\n}\n// ----\n// Warning 5740: (100-112): Unreachable code.\n// Warning 5740: (222-230): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/assembly/for_break.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            for { let a := 0} lt(a,1) { a := add(a, 1) } {\n                break\n                let b := 42\n            }\n        }\n    }\n}\n// ----\n// Warning 5740: (103-117): Unreachable code.\n// Warning 5740: (160-171): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/assembly/for_continue.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            for { let a := 0} lt(a,1) { a := add(a, 1) } {\n                continue\n                let b := 42\n            }\n        }\n    }\n}\n// ----\n// Warning 5740: (163-174): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/assembly/return.sol",
    "content": "contract C {\n    function f(uint256 y) public pure returns (uint256 x) {\n        assembly {\n            return(0, 0)\n            x := y\n        }\n    }\n    function g(uint256 y) public pure returns (uint256 x) {\n        assembly {\n            return(0, 0)\n        }\n        x = y;\n    }\n}\n// ----\n// Warning 5740: (129-135): Unreachable code.\n// Warning 5740: (274-279): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/assembly/revert.sol",
    "content": "contract C {\n    function f(uint256 y) public pure returns (uint256 x) {\n        assembly {\n            revert(0, 0)\n            x := y\n        }\n    }\n    function g(uint256 y) public pure returns (uint256 x) {\n        assembly {\n            revert(0, 0)\n        }\n        x = y;\n    }\n}\n// ----\n// Warning 5740: (129-135): Unreachable code.\n// Warning 5740: (274-279): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/comment_fine.sol",
    "content": "contract C {\n    function f() public pure {\n        return;\n        // unreachable comment\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/constant_condition.sol",
    "content": "contract C {\n    function f() public pure {\n        if (false) {\n            return; // unreachable, but not yet detected\n        }\n        return;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/do_while_continue.sol",
    "content": "contract C {\n    function f() public pure {\n        do {\n            uint a = 42; a;\n            continue;\n            return; // this is unreachable\n        } while(false);\n        return; // this is still reachable\n    }\n}\n// ----\n// Warning 5740: (119-126): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/double_return.sol",
    "content": "contract C {\n    function f() public pure returns (uint) {\n        return 0;\n        return 0;\n    }\n}\n// ----\n// Warning 5740: (85-93): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/double_revert.sol",
    "content": "contract C {\n    function f() public pure {\n        revert();\n        revert();\n    }\n}\n// ----\n// Warning 5740: (70-78): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/for_break.sol",
    "content": "contract C {\n    function f() public pure {\n        for (uint a = 0; a < 1; a++) {\n            break;\n            uint b = 42; b;\n        }\n        return;\n    }\n}\n// ----\n// Warning 5740: (76-79): Unreachable code.\n// Warning 5740: (114-128): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/if_both_return.sol",
    "content": "contract C {\n    function f(bool c) public pure {\n        if (c) {\n            return;\n        } else {\n            return;\n        }\n        return; // unreachable\n    }\n}\n// ----\n// Warning 5740: (142-149): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/library_function_import_bug.sol",
    "content": "==== Source: a ====\nimport \"b\";\ncontract Test is Bar {}\n==== Source: b ====\nlibrary Foo {\n    function nop() internal {}\n}\n\ncontract Bar {\n    function example() public returns (uint256) {\n        foo();\n        return 0;\n    }\n\n    function foo() public {\n        Foo.nop();\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/library_function_nonimport_bug.sol",
    "content": "contract Bar {\n    function example() public {\n        foo();\n        return;\n    }\n\n    function foo() internal {\n        Foo.nop();\n    }\n}\n\ncontract Y is Bar {}\n\nlibrary Foo {\n    function nop() internal {}\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/revert.sol",
    "content": "contract C {\n    function f() public pure {\n        revert();\n        uint a = 0; a;\n    }\n}\n// ----\n// Warning 5740: (70-83): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/revert_empty.sol",
    "content": "contract C {\n    function f() public pure {\n        revert();\n        for(int i = 0; i < 3; i++) { f(); }\n    }\n}\n// ----\n// Warning 5740: (70-105): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/while_break.sol",
    "content": "contract C {\n    function f() public pure {\n        uint a = 0;\n        while (a < 100) {\n            a++;\n            break;\n            a--;\n        }\n    }\n}\n// ----\n// Warning 5740: (138-141): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/unreachableCode/while_continue.sol",
    "content": "contract C {\n    function f() public pure {\n        while(true) {\n            continue;\n            return;\n        }\n        return; // this is unreachable as well, but currently undetected (needs to consider constant condition \"true\")\n    }\n}\n// ----\n// Warning 5740: (100-107): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/userDefinedOperators/binary_operator_udvt.sol",
    "content": "type X is uint24;\ntype Y is uint16;\n\nusing {addX as +} for X global;\nusing {addY as +} for Y global;\n\nfunction addX(X, X) pure returns (X) {}\nfunction addY(Y, Y) pure returns (Y) { revert(); }\n\ncontract C {\n    function f() public pure {\n        X.wrap(1) + X.wrap(Y.unwrap(Y.wrap(2) + Y.wrap(3)));\n        X.wrap(4) + X.wrap(5); // Unreachable\n    }\n}\n// ----\n// Warning 5740: (307-328): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/controlFlow/userDefinedOperators/unary_operator_udvt.sol",
    "content": "type X is uint24;\ntype Y is uint16;\n\nusing {unsubX as -} for X global;\nusing {unsubY as -} for Y global;\n\nfunction unsubX(X) pure returns (X) {}\nfunction unsubY(Y) pure returns (Y) { revert(); }\n\ncontract C {\n    function f() public pure {\n        -X.wrap(Y.unwrap(-Y.wrap(1)));\n        -X.wrap(Y.unwrap(Y.wrap(2))); // Unreachable\n    }\n}\n// ----\n// Warning 5740: (287-315): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/allowed_conversion_to_bytes_array.sol",
    "content": "contract C {\n\tbytes a;\n\tbytes b;\n\tfunction f() public view {\n\t\tbytes storage c = a;\n\t\tbytes memory d = b;\n\t\td = bytes(c);\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/allowed_conversion_to_string.sol",
    "content": "contract C {\n\tstring a;\n\tstring b;\n\tfunction f() public view {\n\t\tstring storage c = a;\n\t\tstring memory d = b;\n\t\td = string(c);\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/conversion_to_bytes.sol",
    "content": "contract test {\n  function f() public pure returns (bytes memory) {\n    return bytes(\"abc\");\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/convert_to_super_empty.sol",
    "content": "contract C {\n    function f() public pure {\n        super().x;\n    }\n}\n// ----\n// TypeError 1744: (52-59): Cannot convert to the super type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/convert_to_super_nonempty.sol",
    "content": "contract C {\n    function f() public pure {\n        super(this).f();\n    }\n}\n// ----\n// TypeError 1744: (52-63): Cannot convert to the super type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/explicit_conversion_address_to_payable.sol",
    "content": "contract C {\n\tfunction g(address payable _p) internal pure returns (uint) {\n\t\treturn 1;\n\t}\n\tfunction f(address _a) public pure {\n\t\tuint x = g(payable(_a));\n\t\tuint y = g(_a);\n\t}\n}\n// ----\n// TypeError 9553: (169-171): Invalid type for argument in function call. Invalid implicit conversion from address to address payable requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/explicit_conversion_error_to_bytes4.sol",
    "content": "interface MyInterface {\n    error MyCustomError(uint256, bool);\n}\n\ncontract Test {\n    function test() public returns(bytes4) {\n        return bytes4(MyInterface.MyCustomError);\n    }\n}\n// ----\n// TypeError 9640: (143-176): Explicit type conversion not allowed from \"error MyCustomError(uint256,bool)\" to \"bytes4\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/explicit_conversion_event_to_bytes4.sol",
    "content": "contract Test {\n    event MyCustomEvent(uint256);\n\n    function test() public returns(bytes4) {\n        return bytes4(MyCustomEvent);\n    }\n}\n// ----\n// TypeError 9640: (111-132): Explicit type conversion not allowed from \"event MyCustomEvent(uint256)\" to \"bytes4\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/explicit_conversion_from_error.sol",
    "content": "interface MyInterface {\n    enum MyEnum { E1, E2 }\n    error CustomError1(\n        uint256,\n        bool,\n        bool[],\n        address payable,\n        MyInterface,\n        MyEnum,\n        function (string memory) external returns (uint)\n    );\n}\n\ncontract Test {\n    function testFunction(string memory) external returns (uint) {}\n\n    function test() public {\n        MyInterface instance = MyInterface(msg.sender);\n        bool[] calldata arr;\n        address payable addr;\n        bytes4(MyInterface.CustomEror1);\n        bytes4(MyInterface.CustomError1());\n        bytes4(MyInterface.CustomError1(1, true, arr, addr, instance, MyInterface.MyEnum.E1, this.testFunction));\n        address(MyInterface.CustomError1);\n    }\n}\n// ----\n// TypeError 9582: (495-518): Member \"CustomEror1\" not found or not visible after argument-dependent lookup in type(contract MyInterface).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/explicit_conversion_from_event.sol",
    "content": "interface MyInterface {\n    enum MyEnum { E1, E2 }\n}\n\ncontract Test {\n    function testFunction(string memory) external returns (uint) {}\n\n    event CustomEvent1(\n        uint256,\n        bool,\n        bool[],\n        address payable,\n        MyInterface,\n        MyInterface.MyEnum,\n        function (string memory) external returns (uint)\n    );\n\n\n    function test() public {\n        MyInterface instance = MyInterface(msg.sender);\n        bool[] calldata arr;\n        address payable addr;\n        bytes4(CustomEvent1);\n        bytes4(CustomEvent1());\n        bytes4(CustomEvent1(1, true, arr, addr, instance, MyInterface.MyEnum.E1, this.testFunction));\n        address(CustomEvent1);\n    }\n}\n// ----\n// TypeError 9640: (502-522): Explicit type conversion not allowed from \"event CustomEvent1(uint256,bool,bool[],address payable,contract MyInterface,enum MyInterface.MyEnum,function (string) external returns (uint256))\" to \"bytes4\".\n// TypeError 6160: (539-553): Wrong argument count for function call: 0 arguments given but expected 7.\n// TypeError 9640: (532-554): Explicit type conversion not allowed from \"tuple()\" to \"bytes4\".\n// TypeError 9640: (564-656): Explicit type conversion not allowed from \"tuple()\" to \"bytes4\".\n// TypeError 9640: (666-687): Explicit type conversion not allowed from \"event CustomEvent1(uint256,bool,bool[],address payable,contract MyInterface,enum MyInterface.MyEnum,function (string) external returns (uint256))\" to \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/explicit_conversion_from_storage_array_ref.sol",
    "content": "contract C {\n\tint[10] x;\n\tfunction f() public view {\n\t\tint[](x);\n\t\tint(x);\n\t}\n}\n// ----\n// TypeError 9640: (55-63): Explicit type conversion not allowed from \"int256[10] storage ref\" to \"int256[] storage pointer\".\n// TypeError 9640: (67-73): Explicit type conversion not allowed from \"int256[10] storage ref\" to \"int256\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/explicit_conversion_sender_to_payable.sol",
    "content": "contract C {\n\tfunction f() public view {\n\t\taddress payable p = payable(msg.sender);\n\t\taddress payable q = payable(address(msg.sender));\n\t}\n}\n// ----\n// Warning 2072: (43-60): Unused local variable.\n// Warning 2072: (86-103): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/explicit_conversion_this_to_payable.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\taddress payable p = payable(this);\n\t\taddress payable q = payable(address(this));\n\t}\n}\n// ----\n// TypeError 9640: (63-76): Explicit type conversion not allowed from \"contract C\" to \"address payable\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_cast_value_set.sol",
    "content": "contract C {\n\tfunction f() public payable {\n\t\tfunction() external payable x = this.f{value: 7};\n\t}\n}\n// ----\n// TypeError 9574: (46-94): Type function () payable external is not implicitly convertible to expected type function () payable external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_array_to_memory.sol",
    "content": "contract C {\n    function externalDefault() external returns(uint) { return 11; }\n    function externalView() external view returns(uint) { return 12; }\n    function externalPure() external pure returns(uint) { return 13; }\n\n    function internalDefault() internal returns(uint) { return 21; }\n    function internalView() internal view returns(uint) { return 22; }\n    function internalPure() internal pure returns(uint) { return 23; }\n\n    function testViewToDefault() public returns (uint, uint) {\n        function () external returns(uint)[1] memory externalDefaultArray;\n        function () internal returns(uint)[1] memory internalDefaultArray;\n\n        // This would work if we were assigning to storage rather than memory\n        externalDefaultArray = [this.externalView];\n        internalDefaultArray = [internalView];\n\n        return (externalDefaultArray[0](), internalDefaultArray[0]());\n    }\n\n    function testPureToDefault() public returns (uint, uint) {\n        function () external returns(uint)[1] memory externalDefaultArray;\n        function () internal returns(uint)[1] memory internalDefaultArray;\n\n        // This would work if we were assigning to storage rather than memory\n        externalDefaultArray = [this.externalPure];\n        internalDefaultArray = [internalPure];\n\n        return (externalDefaultArray[0](), internalDefaultArray[0]());\n    }\n\n    function testPureToView() public returns (uint, uint) {\n        function () external returns(uint)[1] memory externalViewArray;\n        function () internal returns(uint)[1] memory internalViewArray;\n\n        // This would work if we were assigning to storage rather than memory\n        externalViewArray = [this.externalPure];\n        internalViewArray = [internalPure];\n\n        return (externalViewArray[0](), internalViewArray[0]());\n    }\n}\n// ----\n// TypeError 7407: (760-779): Type function () view external returns (uint256)[1] memory is not implicitly convertible to expected type function () external returns (uint256)[1] memory.\n// TypeError 7407: (812-826): Type function () view returns (uint256)[1] memory is not implicitly convertible to expected type function () returns (uint256)[1] memory.\n// TypeError 7407: (1230-1249): Type function () pure external returns (uint256)[1] memory is not implicitly convertible to expected type function () external returns (uint256)[1] memory.\n// TypeError 7407: (1282-1296): Type function () pure returns (uint256)[1] memory is not implicitly convertible to expected type function () returns (uint256)[1] memory.\n// TypeError 7407: (1688-1707): Type function () pure external returns (uint256)[1] memory is not implicitly convertible to expected type function () external returns (uint256)[1] memory.\n// TypeError 7407: (1737-1751): Type function () pure returns (uint256)[1] memory is not implicitly convertible to expected type function () returns (uint256)[1] memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_nonpayable_payable.sol",
    "content": "contract C {\n    function h() external {\n    }\n    function f() view external returns (bytes4) {\n        function () payable external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n// TypeError 9574: (105-144): Type function () external is not implicitly convertible to expected type function () payable external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_nonpayable_pure.sol",
    "content": "contract C {\n    function h() external {\n    }\n    function f() view external returns (bytes4) {\n        function () pure external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n// TypeError 9574: (105-141): Type function () external is not implicitly convertible to expected type function () pure external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_nonpayable_view.sol",
    "content": "contract C {\n    function h() external {\n    }\n    function f() view external returns (bytes4) {\n        function () view external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n// TypeError 9574: (105-141): Type function () external is not implicitly convertible to expected type function () view external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_payable_nonpayable.sol",
    "content": "contract C {\n    function h() payable external {\n    }\n    function f() view external returns (bytes4) {\n        function () external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_payable_pure.sol",
    "content": "contract C {\n    function h() payable external {\n    }\n    function f() view external returns (bytes4) {\n        function () pure external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n// TypeError 9574: (113-149): Type function () payable external is not implicitly convertible to expected type function () pure external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_payable_view.sol",
    "content": "contract C {\n    function h() payable external {\n    }\n    function f() view external returns (bytes4) {\n        function () view external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n// TypeError 9574: (113-149): Type function () payable external is not implicitly convertible to expected type function () view external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_pure_nonpayable.sol",
    "content": "contract C {\n    function h() pure external {\n    }\n    function f() view external returns (bytes4) {\n        function () external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_pure_payable.sol",
    "content": "contract C {\n    function h() pure external {\n    }\n    function f() view external returns (bytes4) {\n        function () payable external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n// TypeError 9574: (110-149): Type function () pure external is not implicitly convertible to expected type function () payable external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_pure_view.sol",
    "content": "contract C {\n    function h() pure external {\n    }\n    function f() view external returns (bytes4) {\n        function () view external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_same.sol",
    "content": "contract C {\n\tint dummy;\n    function h_nonpayable() external { dummy = 1; }\n    function h_payable() payable external {}\n    function h_view() view external { dummy; }\n    function h_pure() pure external {}\n    function f() view external {\n        function () external g_nonpayable = this.h_nonpayable; g_nonpayable;\n        function () payable external g_payable = this.h_payable; g_payable;\n        function () view external g_view = this.h_view; g_view;\n        function () pure external g_pure = this.h_pure; g_pure;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_view_nonpayable.sol",
    "content": "contract C {\n\tint dummy;\n    function h() view external {\n\t\tdummy;\n    }\n    function f() view external returns (bytes4) {\n        function () external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_view_payable.sol",
    "content": "contract C {\n    function h() view external {\n    }\n    function f() view external returns (bytes4) {\n        function () payable external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n// TypeError 9574: (110-149): Type function () view external is not implicitly convertible to expected type function () payable external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/function_type_view_pure.sol",
    "content": "contract C {\n    function h() view external {\n    }\n    function f() view external returns (bytes4) {\n        function () pure external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n// TypeError 9574: (110-146): Type function () view external is not implicitly convertible to expected type function () pure external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/implicit_conversion_error_to_bytes4_function_argument.sol",
    "content": "interface MyInterface {\n    error MyCustomError(uint256, bool);\n}\n\ncontract MyContract {\n    function f(bytes4 arg) public {}\n    function test() public {\n        f(MyInterface.MyCustomError);\n    }\n}\n// ----\n//  TypeError 9553: (165-190): Invalid type for argument in function call. Invalid implicit conversion from error MyCustomError(uint256,bool) to bytes4 requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/implicit_conversion_error_to_bytes4_return_value.sol",
    "content": "interface MyInterface {\n    error MyCustomError(uint256, bool);\n}\n\ncontract Test {\n    function test() public returns(bytes4) {\n        return (MyInterface.MyCustomError);\n    }\n}\n// ----\n// TypeError 6359: (143-170): Return argument type error MyCustomError(uint256,bool) is not implicitly convertible to expected type (type of first return variable) bytes4.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/implicit_conversion_event_to_bytes4_function_argument.sol",
    "content": "contract MyContract {\n    event MyCustomEvent(uint256);\n    function f(bytes4 arg) public {}\n    function test() public {\n        f(MyCustomEvent);\n    }\n}\n// ----\n// TypeError 9553: (132-145): Invalid type for argument in function call. Invalid implicit conversion from event MyCustomEvent(uint256) to bytes4 requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/implicit_conversion_event_to_bytes4_return_value.sol",
    "content": "contract Test {\n    event MyCustomEvent(uint256);\n\n    function test() public returns(bytes4) {\n        return (MyCustomEvent);\n    }\n}\n// ----\n// TypeError 6359: (111-126): Return argument type event MyCustomEvent(uint256) is not implicitly convertible to expected type (type of first return variable) bytes4.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/implicit_conversion_from_array_of_string_literals_to_calldata_string.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f() public pure returns(string[5] calldata) {\n        return [\"h\", \"e\", \"l\", \"l\", \"o\"];\n    }\n}\n// ----\n// TypeError 6359: (122-147): Return argument type string[5] memory is not implicitly convertible to expected type (type of first return variable) string[5] calldata.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/implicit_conversion_from_storage_array_ref.sol",
    "content": "contract C {\n\tint[10] x;\n\tint[] y;\n\tfunction f() public {\n\t\ty = x;\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/implicit_conversion_from_string_literal_to_calldata_string.sol",
    "content": "contract C {\n    function f1() public pure returns(string calldata) {\n        return \"hello\";\n    }\n\n    function f2() public pure returns(string calldata) {\n        return unicode\"hello\";\n    }\n\n    function f3() public pure returns(bytes calldata) {\n        return hex\"68656c6c6f\";\n    }\n}\n// ----\n// TypeError 6359: (85-92): Return argument type literal_string \"hello\" is not implicitly convertible to expected type (type of first return variable) string calldata.\n// TypeError 6359: (173-187): Return argument type literal_string \"hello\" is not implicitly convertible to expected type (type of first return variable) string calldata.\n// TypeError 6359: (267-282): Return argument type literal_string \"hello\" is not implicitly convertible to expected type (type of first return variable) bytes calldata.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/implicit_conversion_from_string_literal_to_calldata_string_in_function_parameter.sol",
    "content": "contract C {\n    function g(string calldata _s) public {}\n    function h(bytes calldata _b) public {}\n\n    function f() public {\n        g(\"hello\");\n        g(unicode\"hello\");\n        h(hex\"68656c6c6f\");\n    }\n}\n// ----\n// TypeError 9553: (139-146): Invalid type for argument in function call. Invalid implicit conversion from literal_string \"hello\" to string calldata requested.\n// TypeError 9553: (159-173): Invalid type for argument in function call. Invalid implicit conversion from literal_string \"hello\" to string calldata requested.\n// TypeError 9553: (186-201): Invalid type for argument in function call. Invalid implicit conversion from literal_string \"hello\" to bytes calldata requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/implicit_conversion_of_super_in_comparison.sol",
    "content": "contract D {}\n\ncontract C {\n    C c;\n    D d;\n\n    function foo() public {\n        // Current instance of the current contract vs super\n        super != this;\n        this != super;\n\n        // Different instance of the current contract vs super\n        super != c;\n        c != super;\n\n        // Instance of an unrelated contract vs super\n        super != d;\n        d != super;\n    }\n}\n// ----\n// TypeError 2271: (144-157): Built-in binary operator != cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (167-180): Built-in binary operator != cannot be applied to types contract C and type(contract super C).\n// Warning 9170: (167-180): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// TypeError 2271: (254-264): Built-in binary operator != cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (274-284): Built-in binary operator != cannot be applied to types contract C and type(contract super C).\n// Warning 9170: (274-284): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n// TypeError 2271: (349-359): Built-in binary operator != cannot be applied to types type(contract super C) and contract D.\n// TypeError 2271: (369-379): Built-in binary operator != cannot be applied to types contract D and type(contract super C).\n// Warning 9170: (369-379): Comparison of variables of contract type is deprecated and scheduled for removal. Use an explicit cast to address type and compare the addresses instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/implicit_conversion_of_super_in_operators.sol",
    "content": "contract C {\n    function foo() public {\n        super << this;\n        super >> this;\n        super ^ this;\n        super | this;\n        super & this;\n\n        super * this;\n        super / this;\n        super % this;\n        super - this;\n        super + this;\n        super ** this;\n\n        super == this;\n        super != this;\n        super >= this;\n        super <= this;\n        super < this;\n        super > this;\n\n        super || this;\n        super && this;\n\n        super -= this;\n        super += this;\n\n        true ? super : this;\n    }\n}\n// ----\n// TypeError 2271: (49-62): Built-in binary operator << cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (72-85): Built-in binary operator >> cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (95-107): Built-in binary operator ^ cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (117-129): Built-in binary operator | cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (139-151): Built-in binary operator & cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (162-174): Built-in binary operator * cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (184-196): Built-in binary operator / cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (206-218): Built-in binary operator % cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (228-240): Built-in binary operator - cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (250-262): Built-in binary operator + cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (272-285): Built-in binary operator ** cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (296-309): Built-in binary operator == cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (319-332): Built-in binary operator != cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (342-355): Built-in binary operator >= cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (365-378): Built-in binary operator <= cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (388-400): Built-in binary operator < cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (410-422): Built-in binary operator > cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (433-446): Built-in binary operator || cannot be applied to types type(contract super C) and contract C.\n// TypeError 2271: (456-469): Built-in binary operator && cannot be applied to types type(contract super C) and contract C.\n// TypeError 4247: (480-485): Expression has to be an lvalue.\n// TypeError 7366: (480-493): Operator -= not compatible with types type(contract super C) and contract C.\n// TypeError 4247: (503-508): Expression has to be an lvalue.\n// TypeError 7366: (503-516): Operator += not compatible with types type(contract super C) and contract C.\n// TypeError 9717: (534-539): Invalid mobile type in true expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/not_allowed_conversion_from_super.sol",
    "content": "contract S\n{\n\tint o;\n\tfunction foo() public returns (int) { return o = 3; }\n}\n\ncontract B is S\n{\n\tfunction fii() public\n\t{\n\t\to = S(super).foo();\n\t}\n}\n// ----\n// TypeError 9640: (129-137): Explicit type conversion not allowed from \"type(contract super B)\" to \"contract S\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/not_allowed_conversion_to_int_array_pointer1.sol",
    "content": "contract C {\n\tuint[] a;\n\tuint[] b;\n\tfunction f() public view {\n\t\tuint[] storage c = a;\n\t\tuint[] storage d = b;\n\t\td = uint[](c);\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/conversion/not_allowed_conversion_to_int_array_pointer2.sol",
    "content": "contract C {\n\tuint[] a;\n\tuint[] b;\n\tfunction f() public view {\n\t\tuint[] storage c = a;\n\t\tuint[] memory d = b;\n\t\td = uint[](c);\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type.sol",
    "content": "library L {\n    struct Nested { uint y; }\n    function c(function(Nested memory) external returns (uint)[] storage) external pure {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol",
    "content": "library L {\n    struct Nested { uint y; }\n    function b(function(Nested calldata) external returns (uint)[] storage) external pure {}\n    function d(function(Nested storage) external returns (uint)[] storage) external pure {}\n    function f(function(Nested transient) external returns (uint)[] storage) external pure {}\n}\n\n// ----\n// Warning 6162: (251-267): Naming function type parameters is deprecated.\n// TypeError 6651: (159-173): Data location must be \"memory\" or \"calldata\" for parameter in function, but \"storage\" was given.\n// TypeError 6651: (251-267): Data location must be \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/externalFunction/external_function_return_parameters_no_data_location.sol",
    "content": "contract C {\n    function i() external pure returns(uint[]) {}\n}\n// ----\n// TypeError 6651: (52-58): Data location must be \"memory\" or \"calldata\" for return parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_calldata.sol",
    "content": "contract test {\n    function f(bytes calldata) external {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_memory.sol",
    "content": "contract test {\n    function f(bytes memory) external;\n}\n// ----\n// TypeError 3656: (0-56): Contract \"test\" should be marked as abstract.\n// TypeError 5424: (20-54): Functions without implementation must be marked virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_storage.sol",
    "content": "contract test {\n    function f(bytes storage) external;\n}\n// ----\n// TypeError 6651: (31-44): Data location must be \"memory\" or \"calldata\" for parameter in external function, but \"storage\" was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_transient.sol",
    "content": "contract test {\n    function f(bytes transient) external;\n}\n// ----\n// TypeError 6651: (31-46): Data location must be \"memory\" or \"calldata\" for parameter in external function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/function_argument_location_specifier_test_non_reference_type.sol",
    "content": "contract test {\n    function f(bytes4 memory) public;\n}\n// ----\n// TypeError 6651: (31-44): Data location can only be specified for array, struct or mapping types, but \"memory\" was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/function_parameters_with_data_location_fine.sol",
    "content": "contract C {\n    function f(uint[] memory, uint[] storage) private pure {}\n    function g(uint[] memory, uint[] storage) internal pure {}\n    function h(uint[] memory) public pure {}\n    function i(uint[] calldata) external pure {}\n    // No data location for events.\n    event e(uint[]);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/function_return_parameters_with_data_location_fine.sol",
    "content": "contract C {\n    function f() private pure returns(uint[] memory, uint[] storage b) { b = b; }\n    function g() internal pure returns(uint[] memory, uint[] storage b) { b = b; }\n    function h() public pure returns(uint[] memory) {}\n    function i() external pure returns(uint[] memory) {}\n}\n// ----\n// Warning 6321: (51-64): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (134-147): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/function_type_array_as_reference_type.sol",
    "content": "contract C {\n    struct Nested { uint y; }\n    // ensure that we consider array of function pointers as reference type\n    function b(function(Nested memory) external returns (uint)[] storage) internal pure {}\n    function c(function(Nested memory) external returns (uint)[] memory) public pure {}\n    function d(function(Nested memory) external returns (uint)[] calldata) external pure {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_calldata.sol",
    "content": "contract test {\n    function f(bytes calldata) internal;\n}\n// ----\n// TypeError 3656: (0-58): Contract \"test\" should be marked as abstract.\n// TypeError 5424: (20-56): Functions without implementation must be marked virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_memory.sol",
    "content": "contract test {\n    function f(bytes memory) internal {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_storage.sol",
    "content": "contract test {\n    function f(bytes storage) internal {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_transient.sol",
    "content": "contract test {\n    function f(bytes transient) internal {}\n}\n// ----\n// TypeError 6651: (31-46): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/internalFunction/internal_function_parameters_no_data_location.sol",
    "content": "contract C {\n    function g(uint[]) internal pure {}\n}\n// ----\n// TypeError 6651: (28-34): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/internalFunction/internal_function_return_parameters_no_data_location.sol",
    "content": "contract C {\n    function g() internal pure returns(uint[]) {}\n}\n// ----\n// TypeError 6651: (52-58): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraries/library_external_function_params_no_data_location.sol",
    "content": "library L {\n    struct S { uint x; }\n    function g(uint[2]) external pure {}\n    function h(uint[]) external pure {}\n    function i(S) external pure {}\n    function j(mapping(uint => uint)) external pure {}\n}\n// ----\n// TypeError 6651: (52-59): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in external function, but none was given.\n// TypeError 6651: (93-99): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in external function, but none was given.\n// TypeError 6651: (133-134): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in external function, but none was given.\n// TypeError 6651: (168-189): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in external function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraries/library_external_function_return_no_data_location.sol",
    "content": "library L {\n    struct S { uint x; }\n    function g() external pure returns (uint[2]) {}\n    function h() external pure returns (uint[]) {}\n    function i() external pure returns (S) {}\n    function j() external pure returns (mapping(uint => uint)) {}\n}\n// ----\n// TypeError 6651: (77-84): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (129-135): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (180-181): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (226-247): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_fine.sol",
    "content": "library L {\n    struct S { uint x; }\n    function f(uint[] memory, uint[] storage, S storage) private pure\n        returns (mapping(uint => uint) storage a, S memory b, uint[] storage c) { return (a, b, c); }\n    function g(uint[] memory, uint[] storage) internal pure\n        returns (mapping(uint => uint) storage a, S memory b, uint[] storage c) { return (a, b, c); }\n    function h(uint[] memory, uint[] storage) public pure returns (S storage x) { return x; }\n    function i(uint[] calldata, uint[] storage) external pure returns (S storage x) {return x; }\n}\n// ----\n// TypeError 3464: (197-198): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (203-204): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (359-360): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (365-366): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (460-461): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n// TypeError 3464: (557-558): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_transient.sol",
    "content": "library L {\n    function f1(uint[] transient) private pure { }\n    function f2() private pure returns (uint[] transient) { }\n    function g1(uint[] transient) internal pure { }\n    function g2() internal pure returns (uint[] transient) { }\n    function h1(uint[] transient) public pure { }\n    function h2() public pure returns (uint[] transient) { }\n    function i1(uint[] transient) external pure { }\n    function i2() external pure returns (uint[] transient) { }\n}\n// ----\n// TypeError 6651: (28-44): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (103-119): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (141-157): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (218-234): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (256-272): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (329-345): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (367-383): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in external function, but none was given.\n// TypeError 6651: (444-460): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraries/library_internal_function_no_data_location.sol",
    "content": "library L {\n    struct S { uint x; }\n    function g() internal pure returns (uint[2]) {}\n    function h() internal pure returns (uint[]) {}\n    function i() internal pure returns (S) {}\n    function j() internal pure returns (mapping(uint => uint)) {}\n    function gp(uint[2]) internal pure {}\n    function hp(uint[]) internal pure {}\n    function ip(S) internal pure {}\n    function jp(mapping(uint => uint)) internal pure {}\n}\n// ----\n// TypeError 6651: (77-84): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (129-135): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (180-181): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (226-247): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (268-275): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (310-316): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (351-352): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (387-408): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraries/library_private_function_no_data_location.sol",
    "content": "library L {\n    struct S { uint x; }\n    function g() private pure returns (uint[2]) {}\n    function h() private pure returns (uint[]) {}\n    function i() private pure returns (S) {}\n    function j() private pure returns (mapping(uint => uint)) {}\n    function gp(uint[2]) private pure {}\n    function hp(uint[]) private pure {}\n    function ip(S) private pure {}\n    function jp(mapping(uint => uint)) private pure {}\n}\n// ----\n// TypeError 6651: (76-83): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (127-133): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (177-178): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (222-243): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (264-271): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (305-311): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (345-346): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (380-401): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraries/library_public_function_no_data_location.sol",
    "content": "library L {\n    struct S { uint x; }\n    function g() private pure returns (uint[2]) {}\n    function h() private pure returns (uint[]) {}\n    function i() private pure returns (S) {}\n    function j() private pure returns (mapping(uint => uint)) {}\n    function gp(uint[2]) private pure {}\n    function hp(uint[]) private pure {}\n    function ip(S) private pure {}\n    function jp(mapping(uint => uint)) private pure {}}\n// ----\n// TypeError 6651: (76-83): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (127-133): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (177-178): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (222-243): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n// TypeError 6651: (264-271): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (305-311): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (345-346): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n// TypeError 6651: (380-401): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_calldata.sol",
    "content": "library test {\n    function f(bytes calldata) external {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_memory.sol",
    "content": "library test {\n    function f(bytes memory) external {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_storage.sol",
    "content": "library test {\n    function f(bytes storage) external {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_transient.sol",
    "content": "library test {\n    function f(bytes transient) external {}\n}\n// ----\n// TypeError 6651: (30-45): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in external function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_calldata.sol",
    "content": "library test {\n    function f(bytes calldata) internal pure {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_memory.sol",
    "content": "library test {\n    function f(bytes memory) internal pure {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_storage.sol",
    "content": "library test {\n    function f(bytes storage) internal pure {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_transient.sol",
    "content": "library test {\n    function f(bytes transient) internal pure {}\n}\n// ----\n// TypeError 6651: (30-45): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/memory_storage_data_location.sol",
    "content": "contract C {\n\tint[] x;\n\tfunction f() public {\n\t\tint[] storage a = x;\n\t\tint[] memory b;\n\t\ta = b;\n\t\ta = int[](b);\n\t}\n}\n// ----\n// TypeError 7407: (93-94): Type int256[] memory is not implicitly convertible to expected type int256[] storage pointer.\n// TypeError 7407: (102-110): Type int256[] memory is not implicitly convertible to expected type int256[] storage pointer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/multiple_transient_data_location_function_parameter.sol",
    "content": "contract C {\n    function f(uint[] transient transient x) public pure { }\n}\n\n// ----\n// ParserError 2314: (45-54): Expected ',' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_location_transient.sol",
    "content": "contract C {\n    function f(uint[] transient) private pure {}\n}\n// ----\n// TypeError 6651: (28-44): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_no_data_location.sol",
    "content": "contract C {\n    function f(uint[]) private pure {}\n}\n// ----\n// TypeError 6651: (28-34): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_location_transient.sol",
    "content": "contract C {\n    function f() private pure returns (uint[] transient) {}\n}\n// ----\n// TypeError 6651: (52-68): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_no_data_location.sol",
    "content": "contract C {\n    function f() private pure returns(uint[]) {}\n}\n// ----\n// TypeError 6651: (51-57): Data location must be \"storage\", \"memory\" or \"calldata\" for return parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_calldata.sol",
    "content": "contract test {\n    function f(bytes calldata) public;\n}\n// ----\n// TypeError 3656: (0-56): Contract \"test\" should be marked as abstract.\n// TypeError 5424: (20-54): Functions without implementation must be marked virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_memory.sol",
    "content": "contract test {\n    function f(bytes memory) public {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_storage.sol",
    "content": "contract test {\n    function f(bytes storage) public;\n}\n// ----\n// TypeError 6651: (31-44): Data location must be \"memory\" or \"calldata\" for parameter in function, but \"storage\" was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_transient.sol",
    "content": "contract test {\n    function f(bytes transient) public;\n}\n// ----\n// TypeError 6651: (31-46): Data location must be \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_parameters_no_data_location.sol",
    "content": "contract C {\n    function h(uint[]) public pure {}\n}\n// ----\n// TypeError 6651: (28-34): Data location must be \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_location_transient.sol",
    "content": "contract C {\n    function h() public pure returns(uint[] transient) {}\n}\n// ----\n// TypeError 6651: (50-66): Data location must be \"memory\" or \"calldata\" for return parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_no_data_location.sol",
    "content": "contract C {\n    function h() public pure returns(uint[]) {}\n}\n// ----\n// TypeError 6651: (50-56): Data location must be \"memory\" or \"calldata\" for return parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/state_variable_storage_named_transient.sol",
    "content": "contract C {\n    uint storage transient;\n}\n// ----\n// ParserError 2314: (22-29): Expected identifier but got 'storage'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/state_variable_storage_transient.sol",
    "content": "contract C {\n    uint storage transient x;\n}\n// ----\n// ParserError 2314: (22-29): Expected identifier but got 'storage'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/state_variable_transient_storage.sol",
    "content": "contract C {\n    uint transient storage x;\n}\n// ----\n// ParserError 2314: (32-39): Expected identifier but got 'storage'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol",
    "content": "contract C {\n\tuint[] transient x;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// UnimplementedFeatureError 1834: Transient data location is only supported for value types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol",
    "content": "contract C {\n\tuint[3] transient x;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// UnimplementedFeatureError 1834: Transient data location is only supported for value types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol",
    "content": "contract C {\n    function () transient f;\n    function (uint) external transient y;\n    function () transient internal fti;\n    function () internal transient fit;\n    function () internal transient internal fiti;\n    function () internal internal transient fiit;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/transient_function_type_parameter.sol",
    "content": "contract C {\n    function (uint transient) external y;\n}\n// ----\n// Warning 6162: (27-41): Naming function type parameters is deprecated.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/transient_local_variable.sol",
    "content": "contract C {\n    function f() public pure {\n        uint transient x = 0;\n    }\n}\n// ----\n// ParserError 2314: (67-68): Expected ';' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol",
    "content": "contract C {\n\tmapping(uint => uint) transient y;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// UnimplementedFeatureError 1834: Transient data location is only supported for value types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol",
    "content": "contract C {\n    uint public transient pubt;\n    uint internal transient it;\n    uint private transient prvt;\n\n    uint transient public tpub;\n    uint transient internal ti;\n    uint transient private tprv;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/transient_storage_variable_pre_cancun.sol",
    "content": "contract C {\n    uint transient x;\n}\n// ====\n// EVMVersion: <cancun\n// ----\n// DeclarationError 7985: (17-33): Transient storage is not supported by EVM versions older than cancun.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol",
    "content": "struct S {\n\tuint x;\n\taddress a;\n}\n\ncontract C {\n\tS transient s;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// UnimplementedFeatureError 1834: Transient data location is only supported for value types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol",
    "content": "contract D { }\n\ncontract C {\n\taddress transient a;\n\tbool transient b;\n\tD transient d;\n\tuint transient x;\n\tbytes32 transient y;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_initialization.sol",
    "content": "contract D { }\n\ncontract C {\n\tint transient x = -99;\n\taddress transient a = address(0xABC);\n\tbool transient b = x > 0 ? false : true;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// DeclarationError 9825: (30-51): Initialization of transient storage state variables is not supported.\n// DeclarationError 9825: (54-90): Initialization of transient storage state variables is not supported.\n// DeclarationError 9825: (93-132): Initialization of transient storage state variables is not supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/unspecified_constructor.sol",
    "content": "contract C {\n  struct S {uint x;}\n  constructor(S) {}\n}\n// ----\n// TypeError 6651: (48-49): Data location must be \"storage\" or \"memory\" for constructor parameter, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/variable_declaration_location_specifier_test_non_reference_type.sol",
    "content": "contract test {\n    function f() public {\n      uint storage a1;\n      bytes16 storage b1;\n      uint memory a2;\n      bytes16 memory b2;\n    }\n}\n// ----\n// TypeError 6651: (48-63): Data location can only be specified for array, struct or mapping types, but \"storage\" was given.\n// TypeError 6651: (71-89): Data location can only be specified for array, struct or mapping types, but \"storage\" was given.\n// TypeError 6651: (97-111): Data location can only be specified for array, struct or mapping types, but \"memory\" was given.\n// TypeError 6651: (119-136): Data location can only be specified for array, struct or mapping types, but \"memory\" was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/dataLocations/variable_declaration_location_specifier_test_reference_type.sol",
    "content": "contract test {\n    uint[] a;\n    uint[]  b;\n    function f() public {\n      uint[] storage s1 = a;\n      uint[] memory s2 = new uint[](42);\n      uint[] storage s3 = b;\n      s1.push(42);\n      s2[3] = 12;\n      s3.push(42);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol",
    "content": "contract C {\n\tuint constant x = 0x01 wei;\n}\n// ----\n// TypeError 5145: (32-40): Hexadecimal numbers cannot be used with unit denominations. You can use an expression of the form \"0x1234 * 1 days\" instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/denominations.sol",
    "content": "contract C {\n\tuint constant a = 1 wei + 4 ether;\n\tuint constant b = 1 seconds + 2 minutes + 3 hours + 4 days + 5 weeks;\n\tuint constant c = 2 ether / 1 seconds + 3 gwei * 3 hours;\n\tuint constant d = 2 gwei / 1 seconds + 3 minutes * 3 hours;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/denominations_in_array_sizes.sol",
    "content": "contract C {\n    uint[42 wei] a;\n    uint[42 gwei] b;\n    uint[42 ether] c;\n    uint[42 seconds] d;\n    uint[42 minutes] e;\n    uint[42 hours] f;\n    uint[42 days] g;\n    uint[42 weeks] h;\n}\n// ----\n// Warning 7325: (58-72): Type uint256[42000000000000000000] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/deprecated_year.sol",
    "content": "contract C {\n\tuint constant a = 3 years;\n}\n// ----\n// TypeError 4820: (32-39): Using \"years\" as a unit denomination is deprecated.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/finney_invalid.sol",
    "content": "contract C {\n    function f() public {\n        uint x = 1 finney;\n    }\n}\n// ----\n// ParserError 2314: (58-64): Expected ';' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/fixed_point_division.sol",
    "content": "contract C {\n\tuint constant a = 4 ether / 3 hours;\n\tufixed constant b = ufixed(4 ether / 3 hours);\n}\n// ----\n// TypeError 2326: (32-49): Type rational_const 10000000000000000 / 27 is not implicitly convertible to expected type uint256. Try converting to type ufixed256x62 or use an explicit conversion.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/gwei_as_identifier.sol",
    "content": "contract C {\n\tuint constant gwei = 1;\n}\n// ----\n// ParserError 2314: (28-32): Expected identifier but got 'gwei'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/invalid_denomination_address.sol",
    "content": "contract C {\n\taddress a = 0x11111122222333334444455555666667777788888 wei;\n}\n// ----\n// TypeError 5145: (26-73): Hexadecimal numbers cannot be used with unit denominations. You can use an expression of the form \"0x1234 * 1 days\" instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/invalid_denomination_no_whitespace.sol",
    "content": "contract C {\n\tuint constant y = 1wei;\n}\n// ----\n// ParserError 8936: (32-33): Identifier-start is not allowed at end of a number.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/invalid_denomination_on_bool.sol",
    "content": "contract C {\n\tbool constant x = true ether;\n}\n// ----\n// ParserError 2314: (37-42): Expected ';' but got 'ether'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/invalid_denomination_on_string.sol",
    "content": "contract C {\n\tstring s = \"abc\" ether;\n}\n// ----\n// ParserError 2314: (31-36): Expected ';' but got 'ether'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/szabo_finney_identifiers.sol",
    "content": "contract C {\n  function f(uint finney) public pure returns (uint szabo) {\n    // These used to be denominations.\n    szabo = finney;\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/szabo_invalid.sol",
    "content": "contract C {\n    function f() public {\n        uint x = 1 szabo;\n    }\n}\n// ----\n// ParserError 2314: (58-63): Expected ';' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/denominations/two_denominations_same_literal.sol",
    "content": "contract C {\n\tuint constant y = 8 gwei ether;\n}\n// ----\n// ParserError 2314: (39-44): Expected ';' but got 'ether'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/duplicateFunctions/fallback_function_twice.sol",
    "content": "contract C {\n    uint x;\n    fallback() external { x = 2; }\n    fallback() external { x = 3; }\n}\n// ----\n// DeclarationError 7301: (64-94): Only one fallback function is allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/duplicateFunctions/illegal_names_exception.sol",
    "content": "// Exception for the rule about illegal names.\ncontract C {\n\tfunction this() public {\n\t}\n\tfunction super() public {\n\t}\n\tfunction _() public {\n\t}\n}\n// ----\n// Warning 2319: (61-88): This declaration shadows a builtin symbol.\n// Warning 2319: (90-118): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/duplicateFunctions/illegal_names_functions.sol",
    "content": "contract C {\n    function _() internal returns(uint) {\n        return 1;\n    }\n\n    function super() internal {\n    }\n\n    function this() internal {\n    }\n}\n// ----\n// DeclarationError 3726: (17-78): The name \"_\" is reserved.\n// DeclarationError 3726: (84-117): The name \"super\" is reserved.\n// DeclarationError 3726: (123-155): The name \"this\" is reserved.\n// Warning 2319: (84-117): This declaration shadows a builtin symbol.\n// Warning 2319: (123-155): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/duplicateFunctions/receive_function_thrice.sol",
    "content": "contract C {\n    receive() external payable { }\n    receive() external payable { }\n    receive() external payable { }\n}\n// ----\n// DeclarationError 4046: (52-82): Only one receive function is allowed.\n// DeclarationError 4046: (87-117): Only one receive function is allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/emit/emit_empty.sol",
    "content": "contract C {\n  function f() public {\n    emit;\n  }\n}\n// ----\n// ParserError 5620: (45-46): Expected event name or path.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/emit/emit_non_event.sol",
    "content": "contract C {\n  function() Test;\n\n  function f() public {\n    emit Test();\n  }\n}\n// ----\n// TypeError 9292: (66-70): Expression has to be an event invocation.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/enums/enum_member_shadowing.sol",
    "content": "contract C {\n    struct S {\n        uint x;\n    }\n\n    enum E {E, S, C, a, f}\n\n    uint a;\n\n    function f() public pure {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/enums/enum_with_too_many_members.sol",
    "content": "enum E {\n    E000, E001, E002, E003, E004, E005, E006, E007, E008, E009,\n    E010, E011, E012, E013, E014, E015, E016, E017, E018, E019,\n    E020, E021, E022, E023, E024, E025, E026, E027, E028, E029,\n    E030, E031, E032, E033, E034, E035, E036, E037, E038, E039,\n    E040, E041, E042, E043, E044, E045, E046, E047, E048, E049,\n    E050, E051, E052, E053, E054, E055, E056, E057, E058, E059,\n    E060, E061, E062, E063, E064, E065, E066, E067, E068, E069,\n    E070, E071, E072, E073, E074, E075, E076, E077, E078, E079,\n    E080, E081, E082, E083, E084, E085, E086, E087, E088, E089,\n    E090, E091, E092, E093, E094, E095, E096, E097, E098, E099,\n    E100, E101, E102, E103, E104, E105, E106, E107, E108, E109,\n    E110, E111, E112, E113, E114, E115, E116, E117, E118, E119,\n    E120, E121, E122, E123, E124, E125, E126, E127, E128, E129,\n    E130, E131, E132, E133, E134, E135, E136, E137, E138, E139,\n    E140, E141, E142, E143, E144, E145, E146, E147, E148, E149,\n    E150, E151, E152, E153, E154, E155, E156, E157, E158, E159,\n    E160, E161, E162, E163, E164, E165, E166, E167, E168, E169,\n    E170, E171, E172, E173, E174, E175, E176, E177, E178, E179,\n    E180, E181, E182, E183, E184, E185, E186, E187, E188, E189,\n    E190, E191, E192, E193, E194, E195, E196, E197, E198, E199,\n    E200, E201, E202, E203, E204, E205, E206, E207, E208, E209,\n    E210, E211, E212, E213, E214, E215, E216, E217, E218, E219,\n    E220, E221, E222, E223, E224, E225, E226, E227, E228, E229,\n    E230, E231, E232, E233, E234, E235, E236, E237, E238, E239,\n    E240, E241, E242, E243, E244, E245, E246, E247, E248, E249,\n    E250, E251, E252, E253, E254, E255, E256\n}\n// ----\n// DeclarationError 1611: (0-1655): Enum with more than 256 members is not allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/enums/global_enum.sol",
    "content": "enum E { A }\ncontract C {\n    function f() public pure {\n        E e = E.A;\n        e;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/enums/global_enum_contract_name_clash.sol",
    "content": "enum E { A }\ncontract E {}\n// ----\n// DeclarationError 2333: (13-26): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/enums/global_enum_name_clash.sol",
    "content": "enum E { A }\nenum E { A }\n// ----\n// DeclarationError 2333: (13-25): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/enums/global_enum_shadowing.sol",
    "content": "enum E { A }\ncontract C {\n    enum E { A }\n    function f() public pure {\n        E e = E.A;\n        e;\n    }\n}\n// ----\n// Warning 2519: (30-42): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/enums/illegal_names.sol",
    "content": "enum this {\n    a\n}\nenum super {\n    b\n}\nenum _ {\n    c\n}\n\nenum E {\n    this,\n    super,\n    _\n}\n\ncontract C {\n    this a;\n    super b;\n    _ c;\n    E e;\n}\n// ----\n// DeclarationError 3726: (0-19): The name \"this\" is reserved.\n// DeclarationError 3726: (20-40): The name \"super\" is reserved.\n// DeclarationError 3726: (41-57): The name \"_\" is reserved.\n// DeclarationError 3726: (72-76): The name \"this\" is reserved.\n// DeclarationError 3726: (82-87): The name \"super\" is reserved.\n// DeclarationError 3726: (93-94): The name \"_\" is reserved.\n// Warning 2319: (0-19): This declaration shadows a builtin symbol.\n// Warning 2319: (20-40): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/enums/literal_conversion.sol",
    "content": "contract C {\n    enum Test { One, Two }\n    function f() public pure {\n        Test a = Test(0);\n        Test b = Test(1);\n        Test c = Test(type(uint).max);\n        a; b; c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/enums/literal_conversion_error.sol",
    "content": "contract C {\n    enum Test { One, Two }\n    function f() public {\n        Test(-1);\n        Test(2);\n        Test(13);\n        Test(5/3);\n        Test(0.5);\n    }\n}\n// ----\n// TypeError 9640: (74-82): Explicit type conversion not allowed from \"int_const -1\" to \"enum C.Test\".\n// TypeError 9640: (92-99): Explicit type conversion not allowed from \"int_const 2\" to \"enum C.Test\".\n// TypeError 9640: (109-117): Explicit type conversion not allowed from \"int_const 13\" to \"enum C.Test\".\n// TypeError 9640: (127-136): Explicit type conversion not allowed from \"rational_const 5 / 3\" to \"enum C.Test\".\n// TypeError 9640: (146-155): Explicit type conversion not allowed from \"rational_const 1 / 2\" to \"enum C.Test\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/abi_decode_error.sol",
    "content": "error E(uint);\ncontract C {\n    function f() public pure returns (bytes memory) {\n        return abi.decode(msg.data, (E));\n    }\n}\n// ----\n// TypeError 1039: (119-120): Argument has to be a type name.\n// TypeError 5132: (90-122): Different number of arguments in return statement than in returns declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/abi_decode_error_constructor.sol",
    "content": "error E(uint);\ncontract C {\n    function f() public pure returns (bytes memory) {\n        return abi.decode(msg.data, (E(1)));\n    }\n}\n// ----\n// TypeError 1039: (119-123): Argument has to be a type name.\n// TypeError 5132: (90-125): Different number of arguments in return statement than in returns declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/abi_encode_error.sol",
    "content": "error E(uint);\ncontract C {\n    function f() public pure returns (bytes memory) {\n        return abi.encode(E);\n    }\n}\n// ----\n// TypeError 2056: (108-109): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/abi_encode_error_constructor.sol",
    "content": "error E(uint);\ncontract C {\n    function f() public pure returns (bytes memory) {\n        return abi.encode(E(1));\n    }\n}\n// ----\n// TypeError 2056: (108-112): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/abi_encode_error_instance.sol",
    "content": "error E(uint);\ncontract C {\n    function f() public pure returns (bytes memory) {\n        return abi.encode(E(2));\n    }\n}\n// ----\n// TypeError 2056: (108-112): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/all_ones_signature.sol",
    "content": "error test266151307();\ncontract C {\n    error test266151307();\n}\n// ----\n// Warning 2519: (40-62): This declaration shadows an existing declaration.\n// SyntaxError 2855: (0-22): The selector 0xffffffff is reserved. Please rename the error to avoid the collision.\n// SyntaxError 2855: (40-62): The selector 0xffffffff is reserved. Please rename the error to avoid the collision.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/anonymous.sol",
    "content": "error E() anonymous;\n// ----\n// ParserError 2314: (10-19): Expected ';' but got 'anonymous'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/assert_with_cond_and_error.sol",
    "content": "error E();\nfunction f(bool x) pure {\n    assert(x, E());\n}\n// ----\n// TypeError 6160: (41-55): Wrong argument count for function call: 2 arguments given but expected 1.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/assert_with_error.sol",
    "content": "error E();\nfunction f() pure {\n    assert(E());\n}\n// ----\n// TypeError 9553: (42-45): Invalid type for argument in function call. Invalid implicit conversion from error to bool requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/basic.sol",
    "content": "contract C {\n    error MyError();\n    error MyError2(uint x);\n    error MyError3(uint x, bytes);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/bytes_concat_on_error_type_info.sol",
    "content": "error MyCustomError(uint, bool);\ncontract C {\n    function f() public {\n        bytes memory a;\n        bytes memory b = type(MyCustomError).concat(a);\n    }\n}\n// ----\n// TypeError 4259: (126-139): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but error MyCustomError(uint256,bool) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/clash_function_error.sol",
    "content": "function Err() pure {}\nerror Err();\n// ----\n// DeclarationError 2333: (23-35): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/clash_function_error_inheritance.sol",
    "content": "contract A { function Err() public pure {} }\ncontract B is A { error Err(); }\n// ----\n// DeclarationError 9097: (63-75): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/clash_function_error_inheritance_2.sol",
    "content": "contract A { function Err() public pure {} }\ncontract B { error Err(); }\ncontract C is A, B {}\n// ----\n// DeclarationError 9097: (58-70): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/duplicate.sol",
    "content": "==== Source: A ====\n\nerror E();\n\n==== Source: B ====\n\nerror E();\n\n==== Source: C ====\n\nimport \"A\" as A;\nimport \"B\" as B;\n\ncontract Test {\n    function f() public pure {\n        revert A.E();\n    }\n    function g() public pure {\n        revert B.E();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/elementary_non_address_state_mutability_error_argument.sol",
    "content": "contract C {\n    error a(bool payable);\n    error b(string payable);\n    error c(int payable);\n    error d(int256 payable);\n    error e(uint payable);\n    error f(uint256 payable);\n    error g(bytes1 payable);\n    error h(bytes payable);\n    error i(bytes32 payable);\n    error j(fixed payable);\n    error k(fixed80x80 payable);\n    error l(ufixed payable);\n    error m(ufixed80x80 payable);\n}\ncontract C2 {\n    error a(bool view);\n    error b(string view);\n    error c(int view);\n    error d(int256 view);\n    error e(uint view);\n    error f(uint256 view);\n    error g(bytes1 view);\n    error h(bytes view);\n    error i(bytes32 view);\n    error j(fixed view);\n    error k(fixed80x80 view);\n    error l(ufixed view);\n    error m(ufixed80x80 view);\n}\ncontract C3 {\n    error a(bool pure);\n    error b(string pure);\n    error c(int pure);\n    error d(int256 pure);\n    error e(uint pure);\n    error f(uint256 pure);\n    error g(bytes1 pure);\n    error h(bytes pure);\n    error i(bytes32 pure);\n    error j(fixed pure);\n    error k(fixed80x80 pure);\n    error l(ufixed pure);\n    error m(ufixed80x80 pure);\n}\n// ----\n// ParserError 9106: (30-37): State mutability can only be specified for address types.\n// ParserError 9106: (59-66): State mutability can only be specified for address types.\n// ParserError 9106: (85-92): State mutability can only be specified for address types.\n// ParserError 9106: (114-121): State mutability can only be specified for address types.\n// ParserError 9106: (141-148): State mutability can only be specified for address types.\n// ParserError 9106: (171-178): State mutability can only be specified for address types.\n// ParserError 9106: (200-207): State mutability can only be specified for address types.\n// ParserError 9106: (228-235): State mutability can only be specified for address types.\n// ParserError 9106: (258-265): State mutability can only be specified for address types.\n// ParserError 9106: (286-293): State mutability can only be specified for address types.\n// ParserError 9106: (319-326): State mutability can only be specified for address types.\n// ParserError 9106: (348-355): State mutability can only be specified for address types.\n// ParserError 9106: (382-389): State mutability can only be specified for address types.\n// ParserError 9106: (425-429): State mutability can only be specified for address types.\n// ParserError 9106: (451-455): State mutability can only be specified for address types.\n// ParserError 9106: (474-478): State mutability can only be specified for address types.\n// ParserError 9106: (500-504): State mutability can only be specified for address types.\n// ParserError 9106: (524-528): State mutability can only be specified for address types.\n// ParserError 9106: (551-555): State mutability can only be specified for address types.\n// ParserError 9106: (577-581): State mutability can only be specified for address types.\n// ParserError 9106: (602-606): State mutability can only be specified for address types.\n// ParserError 9106: (629-633): State mutability can only be specified for address types.\n// ParserError 9106: (654-658): State mutability can only be specified for address types.\n// ParserError 9106: (684-688): State mutability can only be specified for address types.\n// ParserError 9106: (710-714): State mutability can only be specified for address types.\n// ParserError 9106: (741-745): State mutability can only be specified for address types.\n// ParserError 9106: (781-785): State mutability can only be specified for address types.\n// ParserError 9106: (807-811): State mutability can only be specified for address types.\n// ParserError 9106: (830-834): State mutability can only be specified for address types.\n// ParserError 9106: (856-860): State mutability can only be specified for address types.\n// ParserError 9106: (880-884): State mutability can only be specified for address types.\n// ParserError 9106: (907-911): State mutability can only be specified for address types.\n// ParserError 9106: (933-937): State mutability can only be specified for address types.\n// ParserError 9106: (958-962): State mutability can only be specified for address types.\n// ParserError 9106: (985-989): State mutability can only be specified for address types.\n// ParserError 9106: (1010-1014): State mutability can only be specified for address types.\n// ParserError 9106: (1040-1044): State mutability can only be specified for address types.\n// ParserError 9106: (1066-1070): State mutability can only be specified for address types.\n// ParserError 9106: (1097-1101): State mutability can only be specified for address types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_abi_decode.sol",
    "content": "error MyCustomError(uint, bool);\ncontract Test {\n    function f() public {\n        abi.decode(MyCustomError, (bool));\n    }\n}\n// ----\n// TypeError 1956: (94-107): The first argument to \"abi.decode\" must be implicitly convertible to bytes memory or bytes calldata, but is of type error MyCustomError(uint256,bool).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_address_payable.sol",
    "content": "error E(address payable x);\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_as_function_param.sol",
    "content": "error E(uint);\nfunction f(E x) pure returns (uint) {}\n// ----\n// TypeError 5172: (26-27): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_bytes_concat_wrong_type.sol",
    "content": "error MyCustomError(uint, bool);\n\ncontract C {\n    function f() pure public {\n        bytes.concat(MyCustomError, MyCustomError);\n    }\n}\n// ----\n// TypeError 8015: (99-112): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but error MyCustomError(uint256,bool) provided.\n// TypeError 8015: (114-127): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but error MyCustomError(uint256,bool) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_encodecall_fail_args.sol",
    "content": "error MyCustomError(uint, bool);\ncontract C {\n    enum testEnum { choice1, choice2, choice3 }\n\n    function f1(uint8, uint8) external {}\n    function f2(uint32) external {}\n    function f3(uint) external {}\n    function g1(bytes memory) external {}\n    function g2(bytes32) external {}\n    function h(string memory) external {}\n    function i(bool) external {}\n    function j(address) external {}\n    function k(address payable) external {}\n    function l(testEnum) external {}\n\n    function f() pure public {\n        abi.encodeCall(this.f1, (MyCustomError, MyCustomError));\n        abi.encodeCall(this.f2, (MyCustomError));\n        abi.encodeCall(this.f3, (MyCustomError));\n        abi.encodeCall(this.g1, (MyCustomError));\n        abi.encodeCall(this.g2, (MyCustomError));\n        abi.encodeCall(this.h, (MyCustomError));\n        abi.encodeCall(this.i, (MyCustomError));\n        abi.encodeCall(this.j, (MyCustomError));\n        abi.encodeCall(this.k, (MyCustomError));\n        abi.encodeCall(this.l, (MyCustomError));\n    }\n}\n// ----\n// TypeError 5407: (543-556): Cannot implicitly convert component at position 0 from \"error MyCustomError(uint256,bool)\" to \"uint8\".\n// TypeError 5407: (558-571): Cannot implicitly convert component at position 1 from \"error MyCustomError(uint256,bool)\" to \"uint8\".\n// TypeError 5407: (607-622): Cannot implicitly convert component at position 0 from \"error MyCustomError(uint256,bool)\" to \"uint32\".\n// TypeError 5407: (657-672): Cannot implicitly convert component at position 0 from \"error MyCustomError(uint256,bool)\" to \"uint256\".\n// TypeError 5407: (707-722): Cannot implicitly convert component at position 0 from \"error MyCustomError(uint256,bool)\" to \"bytes memory\".\n// TypeError 5407: (757-772): Cannot implicitly convert component at position 0 from \"error MyCustomError(uint256,bool)\" to \"bytes32\".\n// TypeError 5407: (806-821): Cannot implicitly convert component at position 0 from \"error MyCustomError(uint256,bool)\" to \"string memory\".\n// TypeError 5407: (855-870): Cannot implicitly convert component at position 0 from \"error MyCustomError(uint256,bool)\" to \"bool\".\n// TypeError 5407: (904-919): Cannot implicitly convert component at position 0 from \"error MyCustomError(uint256,bool)\" to \"address\".\n// TypeError 5407: (953-968): Cannot implicitly convert component at position 0 from \"error MyCustomError(uint256,bool)\" to \"address payable\".\n// TypeError 5407: (1002-1017): Cannot implicitly convert component at position 0 from \"error MyCustomError(uint256,bool)\" to \"enum C.testEnum\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_in_interface.sol",
    "content": "interface C {\n    error E(uint);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_in_library.sol",
    "content": "library L {\n    error E(uint);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_incompatible_binary_ops.sol",
    "content": "error MyCustomError(uint, bool);\n\ncontract C {\n    function f() pure public {\n        MyCustomError << MyCustomError;\n        MyCustomError >> MyCustomError;\n        MyCustomError ^ MyCustomError;\n        MyCustomError | MyCustomError;\n        MyCustomError & MyCustomError;\n\n        MyCustomError * MyCustomError;\n        MyCustomError / MyCustomError;\n        MyCustomError % MyCustomError;\n        MyCustomError + MyCustomError;\n        MyCustomError - MyCustomError;\n\n        MyCustomError == MyCustomError;\n        MyCustomError != MyCustomError;\n        MyCustomError >= MyCustomError;\n        MyCustomError <= MyCustomError;\n        MyCustomError < MyCustomError;\n        MyCustomError > MyCustomError;\n\n        MyCustomError || MyCustomError;\n        MyCustomError && MyCustomError;\n    }\n}\n\n// ----\n// TypeError 2271: (86-116): Built-in binary operator << cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (126-156): Built-in binary operator >> cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (166-195): Built-in binary operator ^ cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (205-234): Built-in binary operator | cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (244-273): Built-in binary operator & cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (284-313): Built-in binary operator * cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (323-352): Built-in binary operator / cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (362-391): Built-in binary operator % cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (401-430): Built-in binary operator + cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (440-469): Built-in binary operator - cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (480-510): Built-in binary operator == cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (520-550): Built-in binary operator != cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (560-590): Built-in binary operator >= cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (600-630): Built-in binary operator <= cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (640-669): Built-in binary operator < cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (679-708): Built-in binary operator > cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (719-749): Built-in binary operator || cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n// TypeError 2271: (759-789): Built-in binary operator && cannot be applied to types error MyCustomError(uint256,bool) and error MyCustomError(uint256,bool).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_incompatible_operator_for_type.sol",
    "content": "error MyCustomError(uint, bool);\n\ncontract C {\n    function f() pure public {\n        uint a;\n        MyCustomError += 1;\n        MyCustomError -= 1;\n        a += MyCustomError;\n        a -= MyCustomError;\n    }\n}\n\n// ----\n// TypeError 4247: (102-115): Expression has to be an lvalue.\n// TypeError 7366: (102-120): Operator += not compatible with types error MyCustomError(uint256,bool) and int_const 1.\n// TypeError 4247: (130-143): Expression has to be an lvalue.\n// TypeError 7366: (130-148): Operator -= not compatible with types error MyCustomError(uint256,bool) and int_const 1.\n// TypeError 7366: (158-176): Operator += not compatible with types uint256 and error MyCustomError(uint256,bool).\n// TypeError 7366: (186-204): Operator -= not compatible with types uint256 and error MyCustomError(uint256,bool).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_incompatible_unary_operator.sol",
    "content": "error MyCustomError(uint, bool);\n\ncontract C {\n    function f() pure public {\n        MyCustomError++;\n    }\n}\n\n// ----\n// TypeError 4247: (86-99): Expression has to be an lvalue.\n// TypeError 9767: (86-101): Built-in unary operator ++ cannot be applied to type error MyCustomError(uint256,bool).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_invalid_function_modifier_type.sol",
    "content": "error MyCustomError(uint, bool);\n\ncontract B {\n    function f() mod1(MyCustomError) public { }\n    modifier mod1(uint a) { if (a > 0) _; }\n}\n\n// ----\n// TypeError 4649: (69-82): Invalid type for argument in modifier invocation. Invalid implicit conversion from error MyCustomError(uint256,bool) to uint256 requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_location_memory.sol",
    "content": "error E(uint[] memory);\n// ----\n// ParserError 2314: (15-21): Expected ',' but got 'memory'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_location_specifier.sol",
    "content": "error E(uint[] calldata);\n// ----\n// ParserError 2314: (15-23): Expected ',' but got 'calldata'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_param_type_shadowed_by_builtin_type_used_as_param_name.sol",
    "content": "contract C {\n    error E(int bytes, bytes x);\n}\n// ----\n// ParserError 2314: (29-34): Expected ',' but got 'bytes'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_param_type_shadowed_by_param_name.sol",
    "content": "contract C {\n    enum EnumType {A, B, C}\n\n    struct StructType {\n        uint x;\n    }\n\n    error E1(StructType StructType);\n    error E2(EnumType EnumType);\n    error E3(EnumType StructType, StructType EnumType);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_reserved_name.sol",
    "content": "error Error(uint);\n// ----\n// SyntaxError 1855: (0-18): The built-in errors \"Error\" and \"Panic\" cannot be re-defined.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_return_tuple_not_convertible.sol",
    "content": "error MyCustomError(uint, bool);\n\ncontract C {\n    function f() public returns (uint8, uint8, int) {\n        return ((MyCustomError, 8, MyCustomError));\n    }\n}\n\n// ----\n// TypeError 5992: (116-151): Return argument type tuple(error MyCustomError(uint256,bool),int_const 8,error MyCustomError(uint256,bool)) is not implicitly convertible to expected type tuple(uint8,uint8,int256).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_selector_syntax.sol",
    "content": "library L {\n    error E(bytes4, bool, bytes);\n}\n\nerror E(bytes4, bool, bytes);\n\ninterface I {\n    error E(bytes4, bool, bytes);\n}\n\ncontract B {\n    error E(bytes4, bool, bytes);\n}\n\ncontract C is B {\n    bytes4 public librarySelector = L.E.selector;\n    bytes4 internal freeSelector = E.selector;\n    bytes4 internal contractSelector = B.E.selector;\n    bytes4 private interfaceSelector = I.E.selector;\n\n    function f(bool condition) public view {\n        assert(librarySelector == L.E.selector);\n        assert(E.selector == B.E.selector);\n\n        if (condition)\n            revert E(E.selector, true, \"123\");\n        else\n            revert L.E((B.E.selector), true, \"123\");\n    }\n}\n// ----\n// Warning 2519: (16-45): This declaration shadows an existing declaration.\n// Warning 2519: (98-127): This declaration shadows an existing declaration.\n// Warning 2519: (148-177): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_ternary_operator.sol",
    "content": "error MyCustomError(uint, bool);\n\ncontract C {\n    function f() pure public {\n        true ? MyCustomError : MyCustomError;\n    }\n}\n\n// ----\n// TypeError 9717: (93-106): Invalid mobile type in true expression.\n// TypeError 3703: (109-122): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_to_function_conversion.sol",
    "content": "error E();\n\ncontract C {\n    function() internal pure x = E;\n}\n// ----\n// TypeError 7407: (58-59): Type error E() is not implicitly convertible to expected type function () pure. Special functions cannot be converted to function types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_variable_declaration_implicit_conversion.sol",
    "content": "error MyCustomError(uint, bool);\n\ncontract C {\n    function f() public {\n        bytes4 a = MyCustomError;\n    }\n}\n\n// ----\n// TypeError 9574: (81-105): Type error MyCustomError(uint256,bool) is not implicitly convertible to expected type bytes4.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/error_wrong_type_base_arg.sol",
    "content": "error MyCustomError(uint, bool);\n\ncontract Base {\n    constructor(uint8) {}\n}\n\ncontract Derived is Base(MyCustomError) {}\n\n// ----\n// TypeError 9827: (104-117): Invalid type for argument in constructor call. Invalid implicit conversion from error MyCustomError(uint256,bool) to uint8 requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/file_level.sol",
    "content": "error MyError();\nerror MyError2(uint x);\ncontract C {\n    error MyError3(uint x, bytes);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/hash_collision.sol",
    "content": "contract test {\n    error gsf();\n    error tgeo();\n}\n// ----\n// TypeError 4883: (43-47): Error signature hash collision for tgeo()\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/hash_collision_external.sol",
    "content": "library L {\n    error gsf();\n}\ncontract test {\n    error tgeo();\n    function f(bool a) public {\n        if (a)\n            revert L.gsf();\n        else\n            revert tgeo();\n    }\n}\n// ----\n// TypeError 4883: (57-61): Error signature hash collision for tgeo()\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/indexed_error.sol",
    "content": "error E(uint indexed);\n// ----\n// ParserError 2314: (13-20): Expected ',' but got 'indexed'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/internal_type.sol",
    "content": "error E1(function() internal);\nerror E2(S);\n\nstruct S {\n    S[] ss;\n}\n// ----\n// TypeError 3417: (9-29): Internal or recursive type is not allowed as error parameter type.\n// TypeError 3417: (40-41): Internal or recursive type is not allowed as error parameter type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/invalid_parameter_indexed.sol",
    "content": "contract C {\n    error e1(uint indexed x);\n}\n// ----\n// ParserError 2314: (31-38): Expected ',' but got 'indexed'"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/invalid_parameter_location.sol",
    "content": "==== Source: A ====\ncontract test {\n    error e1(string storage a);\n}\n==== Source: B ====\ncontract test {\n    error e1(string memory a);\n}\n==== Source: C ====\ncontract test {\n    error e1(string calldata a);\n}\n==== Source: D ====\ncontract test {\n    error e1(string transient a);\n}\n// ----\n// ParserError 2314: (A:36-43): Expected ',' but got 'storage'\n// ParserError 2314: (B:36-42): Expected ',' but got 'memory'\n// ParserError 2314: (C:36-44): Expected ',' but got 'calldata'\n// ParserError 2314: (D:46-47): Expected ',' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/invalid_parameter_mutability.sol",
    "content": "contract C {\n    error e1(uint constant x);\n    error e2(uint immutable x);\n}\n// ----\n// DeclarationError 1788: (26-41): The \"constant\" keyword can only be used for state variables or variables at file level.\n// DeclarationError 8297: (57-73): The \"immutable\" keyword can only be used for state variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/invalid_parameter_visibility.sol",
    "content": "==== Source: A ====\ncontract C {\n    error e1(uint external x);\n}\n==== Source: B ====\ncontract C {\n    error e1(uint internal x);\n}\n==== Source: C ====\ncontract C {\n    error e1(uint public x);\n}\n==== Source: D ====\ncontract C {\n    error e1(uint private x);\n}\n// ----\n// ParserError 2314: (A:31-39): Expected ',' but got 'external'\n// ParserError 2314: (B:31-39): Expected ',' but got 'internal'\n// ParserError 2314: (C:31-37): Expected ',' but got 'public'\n// ParserError 2314: (D:31-38): Expected ',' but got 'private'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/no_mappings.sol",
    "content": "error MyError(mapping(uint => uint));\ncontract C {\n    error MyError2(mapping(uint => uint));\n}\n// ----\n// TypeError 3448: (14-35): Type containing a (nested) mapping is not allowed as error parameter type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/no_overloading.sol",
    "content": "error Err(uint);\nerror Err(bytes32);\n// ----\n// DeclarationError 2333: (17-36): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/no_overloading_inheritance.sol",
    "content": "contract A {\n    error Err(uint);\n}\ncontract B is A {\n    error Err(bytes32);\n}\n// ----\n// DeclarationError 9097: (58-77): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/no_structs_in_abiv1.sol",
    "content": "pragma abicoder v1;\nstruct S {uint a;}\ncontract C {\n    error MyError(S);\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 3061: (70-71): This type is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/panic_reserved_name.sol",
    "content": "error Panic(bytes2);\n// ----\n// SyntaxError 1855: (0-20): The built-in errors \"Error\" and \"Panic\" cannot be re-defined.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/require_custom.sol",
    "content": "error E(uint a, uint b);\ncontract C {\n    function f(bool c) public pure {\n        require(c, E(2, 7));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/require_nested.sol",
    "content": "error CustomError(uint256);\n\ncontract C\n{\n    function f() public pure returns (uint256)\n    {\n        require(false, require(CustomError(1)));\n        return 2;\n    }\n}\n\n// ----\n// TypeError 9322: (118-125): No matching declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/revert_parentheses.sol",
    "content": "error E(uint a, uint b);\ncontract C {\n    function f() public pure {\n        revert(E(2, 7));\n    }\n}\n// ----\n// TypeError 9322: (77-83): No matching declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/selector.sol",
    "content": "error E();\n\ncontract C {\n    bytes4 t = E.selector;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/selector_on_instance.sol",
    "content": "error E();\n\ncontract C {\n    bytes4 t = E().selector;\n}\n// ----\n// TypeError 9582: (40-52): Member \"selector\" not found or not visible after argument-dependent lookup in error.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/struct_named_error.sol",
    "content": "// Test that the parser workaround is not breaking.\nstruct error {uint a;}\ncontract C {\n    error x;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/unreachable.sol",
    "content": "contract C {\n    error E();\n    uint x = 2;\n    function f() public {\n        revert E();\n        x = 4;\n    }\n}\n// ----\n// Warning 5740: (98-103): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/using.sol",
    "content": "error E(uint);\nlibrary L {\n    function f(uint) internal {}\n}\ncontract C {\n    using L for *;\n    function f() public pure {\n        E.f();\n    }\n}\n// ----\n// TypeError 9582: (133-136): Member \"f\" not found or not visible after argument-dependent lookup in error E(uint256).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/using_2.sol",
    "content": "error E(uint);\nlibrary L {\n    function f(uint) internal {}\n}\ncontract C {\n    using L for E;\n    function f() public pure {\n        E.f();\n    }\n}\n// ----\n// TypeError 5172: (91-92): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/using_structs.sol",
    "content": "struct S {uint a;}\ncontract C {\n    error MyError(S);\n    error MyError2(S t);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/weird3.sol",
    "content": "error E();\n\ncontract C {\n    E x;\n}\n// ----\n// TypeError 5172: (29-30): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/weird4.sol",
    "content": "error E();\n\ncontract C {\n    function f() public pure {\n        E x;\n    }\n}\n// ----\n// TypeError 5172: (64-65): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/errors/zero_signature.sol",
    "content": "error buyAndFree22457070633(uint256);\ncontract C {\n    error buyAndFree22457070633(uint256);\n}\n// ----\n// Warning 2519: (55-92): This declaration shadows an existing declaration.\n// SyntaxError 2855: (0-37): The selector 0x00000000 is reserved. Please rename the error to avoid the collision.\n// SyntaxError 2855: (55-92): The selector 0x00000000 is reserved. Please rename the error to avoid the collision.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/anonymous_event_four_indexed.sol",
    "content": "contract c {\n    event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d) anonymous;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/anonymous_event_multiple_anonymous_specifiers.sol",
    "content": "contract c {\n    event e(uint a) anonymous anonymous;\n}\n// ----\n// ParserError 2314: (43-52): Expected ';' but got 'anonymous'"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/anonymous_event_too_many_indexed.sol",
    "content": "contract c {\n    event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d, uint indexed e) anonymous;\n}\n// ----\n// TypeError 8598: (17-117): More than 4 indexed arguments for anonymous event.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/bytes_concat_on_event_type_info.sol",
    "content": "contract C {\n    event MyCustomEvent(uint);\n    function f() public {\n        bytes memory a;\n        bytes memory b = type(MyCustomEvent).concat(a);\n    }\n}\n// ----\n//  TypeError 4259: (124-137): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but event MyCustomEvent(uint256) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/double_event_declaration.sol",
    "content": "contract test {\n    event A(uint i);\n    event A(uint i);\n}\n// ----\n// DeclarationError 5883: (20-36): Event with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/double_event_declaration_ignores_anonymous.sol",
    "content": "contract test {\n    event A(uint i);\n    event A(uint i) anonymous;\n}\n// ----\n// DeclarationError 5883: (20-36): Event with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/double_event_declaration_ignores_indexed.sol",
    "content": "contract test {\n    event A(uint i);\n    event A(uint indexed i);\n}\n// ----\n// DeclarationError 5883: (20-36): Event with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/elementary_non_address_state_mutability_event_argument.sol",
    "content": "contract C {\n    event a(bool payable);\n    event b(string payable);\n    event c(int payable);\n    event d(int256 payable);\n    event e(uint payable);\n    event f(uint256 payable);\n    event g(bytes1 payable);\n    event h(bytes payable);\n    event i(bytes32 payable);\n    event j(fixed payable);\n    event k(fixed80x80 payable);\n    event l(ufixed payable);\n    event m(ufixed80x80 payable);\n}\ncontract C2 {\n    event a(bool view);\n    event b(string view);\n    event c(int view);\n    event d(int256 view);\n    event e(uint view);\n    event f(uint256 view);\n    event g(bytes1 view);\n    event h(bytes view);\n    event i(bytes32 view);\n    event j(fixed view);\n    event k(fixed80x80 view);\n    event l(ufixed view);\n    event m(ufixed80x80 view);\n}\ncontract C3 {\n    event a(bool pure);\n    event b(string pure);\n    event c(int pure);\n    event d(int256 pure);\n    event e(uint pure);\n    event f(uint256 pure);\n    event g(bytes1 pure);\n    event h(bytes pure);\n    event i(bytes32 pure);\n    event j(fixed pure);\n    event k(fixed80x80 pure);\n    event l(ufixed pure);\n    event m(ufixed80x80 pure);\n}\n// ----\n// ParserError 9106: (30-37): State mutability can only be specified for address types.\n// ParserError 9106: (59-66): State mutability can only be specified for address types.\n// ParserError 9106: (85-92): State mutability can only be specified for address types.\n// ParserError 9106: (114-121): State mutability can only be specified for address types.\n// ParserError 9106: (141-148): State mutability can only be specified for address types.\n// ParserError 9106: (171-178): State mutability can only be specified for address types.\n// ParserError 9106: (200-207): State mutability can only be specified for address types.\n// ParserError 9106: (228-235): State mutability can only be specified for address types.\n// ParserError 9106: (258-265): State mutability can only be specified for address types.\n// ParserError 9106: (286-293): State mutability can only be specified for address types.\n// ParserError 9106: (319-326): State mutability can only be specified for address types.\n// ParserError 9106: (348-355): State mutability can only be specified for address types.\n// ParserError 9106: (382-389): State mutability can only be specified for address types.\n// ParserError 9106: (425-429): State mutability can only be specified for address types.\n// ParserError 9106: (451-455): State mutability can only be specified for address types.\n// ParserError 9106: (474-478): State mutability can only be specified for address types.\n// ParserError 9106: (500-504): State mutability can only be specified for address types.\n// ParserError 9106: (524-528): State mutability can only be specified for address types.\n// ParserError 9106: (551-555): State mutability can only be specified for address types.\n// ParserError 9106: (577-581): State mutability can only be specified for address types.\n// ParserError 9106: (602-606): State mutability can only be specified for address types.\n// ParserError 9106: (629-633): State mutability can only be specified for address types.\n// ParserError 9106: (654-658): State mutability can only be specified for address types.\n// ParserError 9106: (684-688): State mutability can only be specified for address types.\n// ParserError 9106: (710-714): State mutability can only be specified for address types.\n// ParserError 9106: (741-745): State mutability can only be specified for address types.\n// ParserError 9106: (781-785): State mutability can only be specified for address types.\n// ParserError 9106: (807-811): State mutability can only be specified for address types.\n// ParserError 9106: (830-834): State mutability can only be specified for address types.\n// ParserError 9106: (856-860): State mutability can only be specified for address types.\n// ParserError 9106: (880-884): State mutability can only be specified for address types.\n// ParserError 9106: (907-911): State mutability can only be specified for address types.\n// ParserError 9106: (933-937): State mutability can only be specified for address types.\n// ParserError 9106: (958-962): State mutability can only be specified for address types.\n// ParserError 9106: (985-989): State mutability can only be specified for address types.\n// ParserError 9106: (1010-1014): State mutability can only be specified for address types.\n// ParserError 9106: (1040-1044): State mutability can only be specified for address types.\n// ParserError 9106: (1066-1070): State mutability can only be specified for address types.\n// ParserError 9106: (1097-1101): State mutability can only be specified for address types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event.sol",
    "content": "contract c {\n    event e(uint indexed a, bytes3 indexed s, bool indexed b);\n    function f() public { emit e(2, \"abc\", true); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_abi_decode.sol",
    "content": "contract Test {\n    event E(uint);\n    function f() public {\n        abi.decode(E, (bool));\n    }\n}\n// ----\n// TypeError 1956: (80-81): The first argument to \"abi.decode\" must be implicitly convertible to bytes memory or bytes calldata, but is of type event E(uint256).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_array_indexed_v2.sol",
    "content": "pragma abicoder               v2;\ncontract c {\n    event E(uint[] indexed);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_array_v2.sol",
    "content": "pragma abicoder               v2;\ncontract c {\n    event E(uint[]);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_bytes_concat_wrong_type.sol",
    "content": "contract C {\n    event MyCustomEvent(uint);\n    function f() pure public {\n        bytes.concat(MyCustomEvent, MyCustomEvent);\n    }\n}\n// ----\n// TypeError 8015: (96-109): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but event MyCustomEvent(uint256) provided.\n// TypeError 8015: (111-124): Invalid type for argument in the bytes.concat function call. bytes or fixed bytes type is required, but event MyCustomEvent(uint256) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_call.sol",
    "content": "contract c {\n    event e(uint a, bytes3 indexed s, bool indexed b);\n    function f() public { emit e(2, \"abc\", true); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_emit_complex.sol",
    "content": "contract C {\n    event e(uint a, string b);\n    function f() public {\n        emit e(2, \"abc\");\n        emit e({b: \"abc\", a: 8});\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_emit_foreign_class.sol",
    "content": "contract A { event e(uint a, string b); }\ncontract C is A {\n    function f() public {\n        emit A.e(2, \"abc\");\n        emit A.e({b: \"abc\", a: 8});\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_emit_qualified_file_level.sol",
    "content": "==== Source: M.sol ====\nevent E();\n==== Source: A.sol ====\nimport \"M.sol\" as M;\n\nfunction f() {\n    emit M.E();\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_emit_simple.sol",
    "content": "contract C {\n    event e();\n    function f() public {\n        emit e();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_emit_simple_file_level.sol",
    "content": "event E();\n\ncontract C {\n    function f() public {\n        emit E();\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_encodecall_fail_args.sol",
    "content": "contract C {\n    event MyCustomEvent(uint);\n\n    enum testEnum { choice1, choice2, choice3 }\n\n    function f1(uint8, uint8) external {}\n    function f2(uint32) external {}\n    function f3(uint) external {}\n    function g1(bytes memory) external {}\n    function g2(bytes32) external {}\n    function h(string memory) external {}\n    function i(bool) external {}\n    function j(address) external {}\n    function k(address payable) external {}\n    function l(testEnum) external {}\n\n    function f() pure public {\n        abi.encodeCall(this.f1, (MyCustomEvent, MyCustomEvent));\n        abi.encodeCall(this.f2, (MyCustomEvent));\n        abi.encodeCall(this.f3, (MyCustomEvent));\n        abi.encodeCall(this.g1, (MyCustomEvent));\n        abi.encodeCall(this.g2, (MyCustomEvent));\n        abi.encodeCall(this.h, (MyCustomEvent));\n        abi.encodeCall(this.i, (MyCustomEvent));\n        abi.encodeCall(this.j, (MyCustomEvent));\n        abi.encodeCall(this.k, (MyCustomEvent));\n        abi.encodeCall(this.l, (MyCustomEvent));\n    }\n}\n// ----\n// TypeError 5407: (542-555): Cannot implicitly convert component at position 0 from \"event MyCustomEvent(uint256)\" to \"uint8\".\n// TypeError 5407: (557-570): Cannot implicitly convert component at position 1 from \"event MyCustomEvent(uint256)\" to \"uint8\".\n// TypeError 5407: (606-621): Cannot implicitly convert component at position 0 from \"event MyCustomEvent(uint256)\" to \"uint32\".\n// TypeError 5407: (656-671): Cannot implicitly convert component at position 0 from \"event MyCustomEvent(uint256)\" to \"uint256\".\n// TypeError 5407: (706-721): Cannot implicitly convert component at position 0 from \"event MyCustomEvent(uint256)\" to \"bytes memory\".\n// TypeError 5407: (756-771): Cannot implicitly convert component at position 0 from \"event MyCustomEvent(uint256)\" to \"bytes32\".\n// TypeError 5407: (805-820): Cannot implicitly convert component at position 0 from \"event MyCustomEvent(uint256)\" to \"string memory\".\n// TypeError 5407: (854-869): Cannot implicitly convert component at position 0 from \"event MyCustomEvent(uint256)\" to \"bool\".\n// TypeError 5407: (903-918): Cannot implicitly convert component at position 0 from \"event MyCustomEvent(uint256)\" to \"address\".\n// TypeError 5407: (952-967): Cannot implicitly convert component at position 0 from \"event MyCustomEvent(uint256)\" to \"address payable\".\n// TypeError 5407: (1001-1016): Cannot implicitly convert component at position 0 from \"event MyCustomEvent(uint256)\" to \"enum C.testEnum\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_function_inheritance_clash.sol",
    "content": "contract A {\n    function dup() public returns (uint) {\n        return 1;\n    }\n}\ncontract B {\n    event dup();\n}\ncontract C is A, B {\n}\n// ----\n// DeclarationError 9097: (99-111): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_function_type_indexed.sol",
    "content": "contract C {\n\tevent Test(function() external indexed);\n\tfunction f() public {\n\t\temit Test(this.f);\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_incompatible_binary_ops.sol",
    "content": "contract C {\n    event MyCustomEvent(uint);\n    function f() pure public {\n        MyCustomEvent << MyCustomEvent;\n        MyCustomEvent >> MyCustomEvent;\n        MyCustomEvent ^ MyCustomEvent;\n        MyCustomEvent | MyCustomEvent;\n        MyCustomEvent & MyCustomEvent;\n\n        MyCustomEvent * MyCustomEvent;\n        MyCustomEvent / MyCustomEvent;\n        MyCustomEvent % MyCustomEvent;\n        MyCustomEvent + MyCustomEvent;\n        MyCustomEvent - MyCustomEvent;\n\n        MyCustomEvent == MyCustomEvent;\n        MyCustomEvent != MyCustomEvent;\n        MyCustomEvent >= MyCustomEvent;\n        MyCustomEvent <= MyCustomEvent;\n        MyCustomEvent < MyCustomEvent;\n        MyCustomEvent > MyCustomEvent;\n\n        MyCustomEvent || MyCustomEvent;\n        MyCustomEvent && MyCustomEvent;\n    }\n}\n\n// ----\n// TypeError 2271: (83-113): Built-in binary operator << cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (123-153): Built-in binary operator >> cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (163-192): Built-in binary operator ^ cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (202-231): Built-in binary operator | cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (241-270): Built-in binary operator & cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (281-310): Built-in binary operator * cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (320-349): Built-in binary operator / cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (359-388): Built-in binary operator % cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (398-427): Built-in binary operator + cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (437-466): Built-in binary operator - cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (477-507): Built-in binary operator == cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (517-547): Built-in binary operator != cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (557-587): Built-in binary operator >= cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (597-627): Built-in binary operator <= cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (637-666): Built-in binary operator < cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (676-705): Built-in binary operator > cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (716-746): Built-in binary operator || cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n// TypeError 2271: (756-786): Built-in binary operator && cannot be applied to types event MyCustomEvent(uint256) and event MyCustomEvent(uint256).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_incompatible_operator_for_type.sol",
    "content": "contract C {\n    event MyCustomEvent(uint);\n    function f() pure public {\n        uint a;\n        MyCustomEvent += 1;\n        MyCustomEvent -= 1;\n        a += MyCustomEvent;\n        a -= MyCustomEvent;\n    }\n}\n\n// ----\n// TypeError 4247: (99-112): Expression has to be an lvalue.\n// TypeError 7366: (99-117): Operator += not compatible with types event MyCustomEvent(uint256) and int_const 1.\n// TypeError 4247: (127-140): Expression has to be an lvalue.\n// TypeError 7366: (127-145): Operator -= not compatible with types event MyCustomEvent(uint256) and int_const 1.\n// TypeError 7366: (155-173): Operator += not compatible with types uint256 and event MyCustomEvent(uint256).\n// TypeError 7366: (183-201): Operator -= not compatible with types uint256 and event MyCustomEvent(uint256).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_incompatible_unary_operator.sol",
    "content": "contract C {\n    event MyCustomEvent(uint);\n    function f() pure public {\n        MyCustomEvent++;\n    }\n}\n\n// ----\n// TypeError 4247: (83-96): Expression has to be an lvalue.\n// TypeError 9767: (83-98): Built-in unary operator ++ cannot be applied to type event MyCustomEvent(uint256).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_inheritance.sol",
    "content": "contract base {\n    event e(uint a, bytes3 indexed s, bool indexed b);\n}\ncontract c is base {\n    function f() public { emit e(2, \"abc\", true); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_invalid_function_modifier_type.sol",
    "content": "contract B {\n    event MyCustomEvent(uint);\n    function f() mod1(MyCustomEvent) public { }\n    modifier mod1(uint a) { if (a > 0) _; }\n}\n\n// ----\n// TypeError 4649: (66-79): Invalid type for argument in modifier invocation. Invalid implicit conversion from event MyCustomEvent(uint256) to uint256 requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_library_function.sol",
    "content": "library L {\n\tfunction f() public {\n\t\tint x = 1;\n\t}\n}\n\ncontract C {\n\tevent Test(function() external indexed);\n\n\tfunction g() public {\n\t\tTest(L.f);\n\t}\n}\n\ncontract D {\n\tevent Test(function() external);\n\n\tfunction f() public {\n\t\tTest(L.f);\n\t}\n}\n\ncontract E {\n\tevent Test(function() external indexed);\n\n\tusing L for D;\n\n\tfunction k() public {\n\t\tTest(D.f);\n\t}\n}\n// ----\n// TypeError 9553: (140-143): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested. Special functions cannot be converted to function types.\n// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function () to function () external requested. Special functions cannot be converted to function types.\n// TypeError 9553: (345-348): Invalid type for argument in function call. Invalid implicit conversion from function D.f() to function () external requested. Special functions cannot be converted to function types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_multiple_indexed_of_one_parameter.sol",
    "content": "contract c {\n    event e(uint indexed a, bytes3 indexed indexed s, bool indexed indexed indexed b);\n    event e2(uint indexed indexed a, bytes3 indexed s);\n}\n// ----\n// ParserError 5399: (56-63): Indexed already specified.\n// ParserError 5399: (80-87): Indexed already specified.\n// ParserError 5399: (88-95): Indexed already specified.\n// ParserError 5399: (126-133): Indexed already specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_named_arguments_in_any_order.sol",
    "content": "contract C {\n    event e(uint u, string s, bool b);\n\n    function call() public {\n        emit e({s: \"abc\", u: 1,     b: true});\n        emit e({s: \"abc\", b: true,  u: 1});\n        emit e({u: 1,     s: \"abc\", b: true});\n        emit e({b: true,  s: \"abc\", u: 1});\n        emit e({u: 1,     b: true,  s: \"abc\"});\n        emit e({b: true,  u: 1,     s: \"abc\"});\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_nested_array.sol",
    "content": "pragma abicoder v1;\ncontract c {\n    event E(uint[][]);\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 3061: (45-53): This type is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_nested_array_2.sol",
    "content": "contract c {\n    event E(uint[2][]);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_nested_array_in_struct.sol",
    "content": "pragma abicoder v1;\ncontract c {\n\tstruct S { uint x; uint[][] arr; }\n    event E(S);\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 3061: (81-82): This type is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_nested_array_indexed_v2.sol",
    "content": "pragma abicoder               v2;\ncontract c {\n    event E(uint[][] indexed);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_nested_array_v2.sol",
    "content": "pragma abicoder               v2;\ncontract c {\n    event E(uint[][]);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_overload_named_arguments_ambiguous.sol",
    "content": "contract C {\n    event e(uint u, string s);\n    event e(string s, uint u);\n\n    function call() public {\n        emit e({u: 2, s: \"abc\"});\n    }\n}\n// ----\n// TypeError 4487: (118-119): No unique declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_overload_named_arguments_ambiguous_implicit_conversion.sol",
    "content": "contract C {\n    event e(uint u, string s);\n    event e(bytes s, int u);\n\n    function call() public {\n        emit e({u: 2, s: \"abc\"});\n    }\n}\n// ----\n// TypeError 4487: (116-117): No unique declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_overload_named_arguments_in_any_order.sol",
    "content": "contract C {\n    event e(uint u, string s, bool b);\n    event e(uint u, uint s, uint b);\n\n    function call() public {\n        emit e({s: \"abc\", u: 1,     b: true});\n        emit e({s: \"abc\", b: true,  u: 1});\n        emit e({u: 1,     s: \"abc\", b: true});\n        emit e({b: true,  s: \"abc\", u: 1});\n        emit e({u: 1,     b: true,  s: \"abc\"});\n        emit e({b: true,  u: 1,     s: \"abc\"});\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_overload_named_arguments_wrong_types.sol",
    "content": "contract C {\n    event e(uint u, string s);\n    event e(string s, uint u);\n\n    function call() public {\n        emit e({s: 2, u: \"abc\"});\n    }\n}\n// ----\n// TypeError 9322: (118-119): No matching declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_param_type_outside_storage.sol",
    "content": "contract c {\n    event e(uint indexed a, mapping(uint => uint) indexed b, bool indexed c, uint indexed d, uint indexed e) anonymous;\n}\n// ----\n// TypeError 3448: (41-72): Type containing a (nested) mapping is not allowed as event parameter type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_param_type_shadowed_by_param_name.sol",
    "content": "contract C {\n    enum EnumType {A, B, C}\n\n    struct StructType {\n        uint x;\n    }\n\n    event E1(StructType StructType);\n    event E2(EnumType EnumType);\n    event E3(EnumType StructType, StructType EnumType);\n    event E4(StructType indexed StructType) anonymous;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_return_tuple_not_convertible.sol",
    "content": "contract C {\n    event MyCustomEvent(uint);\n    function f() public returns (uint8, uint8, int) {\n        return ((MyCustomEvent, 8, MyCustomEvent));\n    }\n}\n\n// ----\n// TypeError 5992: (113-148): Return argument type tuple(event MyCustomEvent(uint256),int_const 8,event MyCustomEvent(uint256)) is not implicitly convertible to expected type tuple(uint8,uint8,int256).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_selector_access_file_level.sol",
    "content": "event E();\n\ncontract C {\n    function f() external pure returns (bytes32) {\n        return E.selector;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_selector_access_foreign_contract.sol",
    "content": "contract D {\n    event E();\n}\n\ncontract C {\n    function f() external pure returns (bytes32) {\n        return D.E.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_selector_access_interface.sol",
    "content": "interface I {\n    event E();\n}\n\ncontract C {\n    function f() external pure returns (bytes32) {\n        return I.E.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_selector_access_library.sol",
    "content": "library L {\n    event E();\n}\n\ncontract C {\n    function f() external pure returns (bytes32) {\n        return L.E.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_selector_library_called_inside_function.sol",
    "content": "library Y {\n    event E() anonymous;\n}\n\ncontract D {\n    function test1() external pure returns (bytes32) {\n        return Y.E.selector;\n    }\n}\n// ----\n// TypeError 9582: (123-135): Member \"selector\" not found or not visible after argument-dependent lookup in event E().\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_selector_library_declared_outside_but_called_inside_function.sol",
    "content": "library Y {\n    event E() anonymous;\n}\n\ncontract C {\n    bytes32 s5 = Y.E.selector;\n\n    function test2() view external returns (bytes32) {\n        return s5;\n    }\n}\n// ----\n// TypeError 9582: (70-82): Member \"selector\" not found or not visible after argument-dependent lookup in event E().\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_selector_syntax.sol",
    "content": "library L {\n    event E(bytes32, bool, bytes indexed);\n}\n\ninterface I {\n    event E(bytes32, bool, bytes indexed);\n}\n\ncontract A {\n    event E(bytes32, bool, bytes indexed);\n}\n\ncontract B {\n    event E(bytes32, bool, bytes indexed);\n}\n\ncontract C is B {\n    bytes32 public librarySelector = L.E.selector;\n    bytes32 public interfaceSelector = I.E.selector;\n    bytes32 public foreignContractSelector = A.E.selector;\n    bytes32 inheritedSelector = E.selector;\n\n    function f() public {\n        assert(librarySelector == L.E.selector);\n        assert(interfaceSelector == I.E.selector);\n        assert(foreignContractSelector == A.E.selector);\n        assert(E.selector == B.E.selector);\n\n        emit E(E.selector, true, \"123\");\n        emit I.E((B.E.selector), true, \"123\");\n        emit A.E((B.E.selector), true, \"123\");\n        emit L.E((B.E.selector), true, \"123\");\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_struct.sol",
    "content": "pragma abicoder v1;\ncontract c {\n    struct S { uint a ; }\n    event E(S);\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 3061: (71-72): This type is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_struct_indexed.sol",
    "content": "pragma abicoder v1;\ncontract c {\n    struct S { uint a ; }\n    event E(S indexed);\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 3061: (71-80): This type is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_struct_indexed_v2.sol",
    "content": "pragma abicoder               v2;\ncontract c {\n    struct S { uint a ; }\n    event E(S indexed);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_struct_v2.sol",
    "content": "pragma abicoder               v2;\ncontract c {\n    struct S { uint a ; }\n    event E(S);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_ternary_operator.sol",
    "content": "contract C {\n    event MyCustomEvent(uint);\n    function f() pure public {\n        true ? MyCustomEvent : MyCustomEvent;\n    }\n}\n\n// ----\n// TypeError 9717: (90-103): Invalid mobile type in true expression.\n// TypeError 3703: (106-119): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_to_function_conversion.sol",
    "content": "\ncontract C {\n    event E(uint);\n    function() internal pure x = E;\n}\n// ----\n// TypeError 7407: (66-67): Type event E(uint256) is not implicitly convertible to expected type function () pure. Special functions cannot be converted to function types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_too_many_indexed.sol",
    "content": "contract c {\n    event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d);\n}\n// ----\n// TypeError 7249: (17-91): More than 3 indexed arguments for event.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_variable_declaration_implicit_conversion.sol",
    "content": "contract C {\n    event MyCustomEvent(uint);\n    function f() public {\n        bytes4 a = MyCustomEvent;\n    }\n}\n\n// ----\n// TypeError 9574: (78-102): Type event MyCustomEvent(uint256) is not implicitly convertible to expected type bytes4.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_without_emit_deprecated.sol",
    "content": "contract C {\n    event e();\n    function f() public {\n        e();\n    }\n}\n// ----\n// TypeError 3132: (62-65): Event invocations have to be prefixed by \"emit\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/event_wrong_type_base_arg.sol",
    "content": "contract Base {\n    event MyCustomEvent(uint);\n    constructor(uint8) {}\n}\n\ncontract Derived is Base(Base.MyCustomEvent) {}\n\n// ----\n// TypeError 9827: (101-119): Invalid type for argument in constructor call. Invalid implicit conversion from event MyCustomEvent(uint256) to uint8 requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/events_with_same_name.sol",
    "content": "contract TestIt {\n    event A();\n    event A(uint i);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/events_with_same_name_different_types.sol",
    "content": "contract test {\n    event A(uint);\n    event A(bytes);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/events_with_same_name_unnamed_arguments.sol",
    "content": "contract test {\n    event A(uint);\n    event A(uint, uint);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/file_level_event.sol",
    "content": "event E1();\nevent E2(uint);\nevent E3(uint, string indexed, bytes, bool);\nevent E4(int, int, int) anonymous;\n\nfunction f() {\n    emit E1();\n    emit E2(1);\n    emit E3(1, \"abc\", \"abc\", true);\n    emit E4(1, 2, 3);\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/file_level_event_duplicate_definition.sol",
    "content": "event E();\nevent E();\n// ----\n// DeclarationError 5883: (0-10): Event with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/file_level_event_duplicate_definition_via_import.sol",
    "content": "==== Source: A.sol ====\nevent E();\n==== Source: B.sol ====\nimport \"A.sol\";\n\nevent E();\n// ----\n// DeclarationError 5883: (B.sol:17-27): Event with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/file_level_event_import.sol",
    "content": "==== Source: A.sol ====\nevent EA();\n==== Source: B.sol ====\nevent EB();\n==== Source: C.sol ====\nimport \"A.sol\";\nimport {EB} from \"B.sol\";\n\nfunction f() {\n    emit EA();\n    emit EB();\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/file_level_event_overloading.sol",
    "content": "event E();\nevent E(uint);\nevent E(uint, string indexed, bytes, bool);\nevent E(int, int, int) anonymous;\n\nfunction f() {\n    emit E();\n    emit E(1);\n    emit E(1, \"abc\", \"abc\", true);\n    emit E(1, 2, 3);\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/file_level_event_overloading_vs_shadowing.sol",
    "content": "event E();\n\ncontract C {\n    event E(uint);\n\n    function f() public {\n        emit E();\n        emit E(1);\n    }\n}\n// ----\n// Warning 2519: (29-43): This declaration shadows an existing declaration.\n// TypeError 6160: (84-87): Wrong argument count for function call: 0 arguments given but expected 1.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/file_level_event_shadowed_inside_contract.sol",
    "content": "event E();\n\ncontract C {\n    event E();\n}\n\nlibrary L {\n    event E();\n}\n\ninterface I {\n    event E();\n}\n// ----\n// Warning 2519: (29-39): This declaration shadows an existing declaration.\n// Warning 2519: (59-69): This declaration shadows an existing declaration.\n// Warning 2519: (91-101): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/file_level_event_shadowed_inside_contract_adds_anonymous.sol",
    "content": "event E();\n\ncontract C {\n    event E() anonymous;\n}\n\nlibrary L {\n    event E() anonymous;\n}\n\ninterface I {\n    event E() anonymous;\n}\n// ----\n// Warning 2519: (29-49): This declaration shadows an existing declaration.\n// Warning 2519: (69-89): This declaration shadows an existing declaration.\n// Warning 2519: (111-131): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/file_level_event_shadowing_contract.sol",
    "content": "event E();\ncontract E {}\n// ----\n// DeclarationError 2333: (11-24): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/file_level_event_shadowing_error.sol",
    "content": "event E();\nerror E();\n// ----\n// DeclarationError 2333: (11-21): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/file_level_event_using.sol",
    "content": "event E();\n\ntype T is uint;\nusing {E} for T;\n// ----\n// TypeError 8187: (35-36): Expected function name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/function_event_in_contract_clash.sol",
    "content": "contract A {\n    event dup();\n    function dup() public returns (uint) {\n        return 1;\n    }\n}\n// ----\n// DeclarationError 2333: (34-96): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/function_event_inheritance_clash.sol",
    "content": "contract B {\n    event dup();\n}\ncontract A {\n    function dup() public returns (uint) {\n        return 1;\n    }\n}\ncontract C is B, A {\n}\n// ----\n// DeclarationError 9097: (49-111): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/illegal_names_exception.sol",
    "content": "// Exception for the illegal name list. External interface events\ncontract C {\n\tevent this();\n\tevent super();\n\tevent _();\n}\n// ----\n// Warning 2319: (80-93): This declaration shadows a builtin symbol.\n// Warning 2319: (95-109): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/illegal_names_exception_file_level.sol",
    "content": "// Exception for the illegal name list. External interface events\nevent this();\nevent super();\nevent _();\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/inheritance_adds_anonymous.sol",
    "content": "contract A {\n    event X();\n}\ncontract B is A {\n    event X() anonymous;\n}\n// ----\n// DeclarationError 5883: (52-72): Event with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/inheritance_adds_indexed.sol",
    "content": "contract A {\n    event X(uint);\n}\ncontract B is A {\n    event X(uint indexed);\n}\n// ----\n// DeclarationError 5883: (56-78): Event with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/inheritance_adds_parameter.sol",
    "content": "contract A {\n    event X();\n}\ncontract B is A {\n    event X(uint);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/inheritance_event_repeated.sol",
    "content": "contract A {\n    event X(uint);\n}\ncontract B is A {\n    event X(uint);\n}\n// ----\n// DeclarationError 5883: (56-70): Event with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/inheritance_multi_parent.sol",
    "content": "contract A {\n    event X(uint, uint indexed);\n}\ncontract B {\n    event X(uint, uint);\n}\ncontract C is A, B {\n}\n// ----\n// DeclarationError 5883: (65-85): Event with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/inheritance_removes_indexed.sol",
    "content": "contract A {\n    event X(uint, uint indexed);\n}\ncontract B is A {\n    event X(uint, uint);\n}\n// ----\n// DeclarationError 5883: (70-90): Event with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/internal_type.sol",
    "content": "struct S {\n    S[] ss;\n}\n\ncontract C {\n    event E1(function() internal);\n    event E2(S);\n}\n// ----\n// TypeError 3417: (52-72): Internal or recursive type is not allowed as event parameter type.\n// TypeError 3417: (87-88): Internal or recursive type is not allowed as event parameter type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/invalid_parameter_location.sol",
    "content": "==== Source: A ====\ncontract test {\n    event e1(string storage a);\n}\n==== Source: B ====\ncontract test {\n    event e1(string memory a);\n}\n==== Source: C ====\ncontract test {\n    event e1(string calldata a);\n}\n==== Source: D ====\ncontract test {\n    event e1(string transient a);\n}\n// ----\n// ParserError 2314: (A:36-43): Expected ',' but got 'storage'\n// ParserError 2314: (B:36-42): Expected ',' but got 'memory'\n// ParserError 2314: (C:36-44): Expected ',' but got 'calldata'\n// ParserError 2314: (D:46-47): Expected ',' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/invalid_parameter_mutability.sol",
    "content": "contract test {\n    event e1(uint constant a);\n    event e2(uint immutable a);\n}\n// ----\n// DeclarationError 1788: (29-44): The \"constant\" keyword can only be used for state variables or variables at file level.\n// DeclarationError 8297: (60-76): The \"immutable\" keyword can only be used for state variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/invalid_parameter_visibility.sol",
    "content": "==== Source: A ====\ncontract test {\n    event e1(uint external a);\n}\n==== Source: B ====\ncontract test {\n    event e1(uint internal a);\n}\n==== Source: C ====\ncontract test {\n    event e1(uint public a);\n}\n==== Source: D ====\ncontract test {\n    event e1(uint private a);\n}\n// ----\n// ParserError 2314: (A:34-42): Expected ',' but got 'external'\n// ParserError 2314: (B:34-42): Expected ',' but got 'internal'\n// ParserError 2314: (C:34-40): Expected ',' but got 'public'\n// ParserError 2314: (D:34-41): Expected ',' but got 'private'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/multiple_event_without_emit.sol",
    "content": "contract test {\n    event SetFirstElem(uint indexed elem);\n    event SetSecondElem(uint indexed elem);\n    function setVal() external  {\n        emit SetFirstElem(0);\n    }\n    function setValX() external  {\n        // There was a missing error for this case.\n        // Whenever there was a proper invocation of events,\n        // the compiler assumed that all the subsequent invocations\n        // were proper.\n        SetFirstElem(1);\n    }\n}\n// ----\n// TypeError 3132: (421-436): Event invocations have to be prefixed by \"emit\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/multiple_events_argument_clash.sol",
    "content": "contract c {\n    event e1(uint a, uint e1, uint e2);\n    event e2(uint a, uint e1, uint e2);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/multiple_inheritance.sol",
    "content": "contract A { event X(uint); }\ncontract B is A {}\ncontract C is A {}\ncontract D is B, C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/overloading_in_contract.sol",
    "content": "contract A {\n    event X();\n    event X(uint);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/events/transient_indexed_parameter.sol",
    "content": "contract C {\n    event e(string indexed transient a);\n}\n// ----\n// ParserError 2314: (50-51): Expected ',' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol",
    "content": "pragma experimental solidity;\n\ntype void = __builtin(\"void\");\n\ntype bool = __builtin(\"bool\");\ntype word = __builtin(\"word\");\ntype integer = __builtin(\"integer\");\ntype unit = __builtin(\"unit\");\n\ntype fun(T, U) = __builtin(\"fun\");\ntype pair(T, U) = __builtin(\"pair\");\n\ncontract C {\n    fallback() external {\n        let v: void;\n\n        let b: bool;\n        bool.abs(bool.rep(b));\n\n        let w: word;\n        let i: integer;\n        let u: unit;\n\n        let f: fun(word, bool);\n        b = f(w);\n\n        let p: pair(bool, word);\n        pair.first(p);\n        pair.second(p);\n    }\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// bytecodeFormat: legacy\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (31-61): Inferred type: void\n// Info 4164: (63-93): Inferred type: bool\n// Info 4164: (94-124): Inferred type: word\n// Info 4164: (125-161): Inferred type: integer\n// Info 4164: (162-192): Inferred type: ()\n// Info 4164: (194-228): Inferred type: tfun(('s:type, 't:type), 's:type -> 't:type)\n// Info 4164: (202-208): Inferred type: ('s:type, 't:type)\n// Info 4164: (203-204): Inferred type: 's:type\n// Info 4164: (206-207): Inferred type: 't:type\n// Info 4164: (229-265): Inferred type: tfun(('u:type, 'v:type), ('u:type, 'v:type))\n// Info 4164: (238-244): Inferred type: ('u:type, 'v:type)\n// Info 4164: (239-240): Inferred type: 'u:type\n// Info 4164: (242-243): Inferred type: 'v:type\n// Info 4164: (284-584): Inferred type: () -> ()\n// Info 4164: (292-294): Inferred type: ()\n// Info 4164: (318-325): Inferred type: void\n// Info 4164: (321-325): Inferred type: void\n// Info 4164: (340-347): Inferred type: bool\n// Info 4164: (343-347): Inferred type: bool\n// Info 4164: (357-378): Inferred type: bool\n// Info 4164: (357-365): Inferred type: word -> bool\n// Info 4164: (357-361): Inferred type: bool\n// Info 4164: (366-377): Inferred type: word\n// Info 4164: (366-374): Inferred type: bool -> word\n// Info 4164: (366-370): Inferred type: bool\n// Info 4164: (375-376): Inferred type: bool\n// Info 4164: (393-400): Inferred type: word\n// Info 4164: (396-400): Inferred type: word\n// Info 4164: (414-424): Inferred type: integer\n// Info 4164: (417-424): Inferred type: integer\n// Info 4164: (438-445): Inferred type: ()\n// Info 4164: (441-445): Inferred type: ()\n// Info 4164: (460-478): Inferred type: word -> bool\n// Info 4164: (463-478): Inferred type: word -> bool\n// Info 4164: (463-466): Inferred type: tfun((word, bool), word -> bool)\n// Info 4164: (467-471): Inferred type: word\n// Info 4164: (473-477): Inferred type: bool\n// Info 4164: (488-496): Inferred type: bool\n// Info 4164: (488-489): Inferred type: bool\n// Info 4164: (492-496): Inferred type: bool\n// Info 4164: (492-493): Inferred type: word -> bool\n// Info 4164: (494-495): Inferred type: word\n// Info 4164: (511-530): Inferred type: (bool, word)\n// Info 4164: (514-530): Inferred type: (bool, word)\n// Info 4164: (514-518): Inferred type: tfun((bool, word), (bool, word))\n// Info 4164: (519-523): Inferred type: bool\n// Info 4164: (525-529): Inferred type: word\n// Info 4164: (540-553): Inferred type: bool\n// Info 4164: (540-550): Inferred type: (bool, word) -> bool\n// Info 4164: (540-544): Inferred type: (?bh:type, ?bi:type)\n// Info 4164: (551-552): Inferred type: (bool, word)\n// Info 4164: (563-577): Inferred type: word\n// Info 4164: (563-574): Inferred type: (bool, word) -> word\n// Info 4164: (563-567): Inferred type: (?bm:type, ?bn:type)\n// Info 4164: (575-576): Inferred type: (bool, word)\n// UnimplementedFeatureError 1834: (267-586): No support for calling functions pointers yet.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition_duplicate.sol",
    "content": "pragma experimental solidity;\n\ntype void1 = __builtin(\"void\");\ntype void2 = __builtin(\"void\");\n\ntype word1 = __builtin(\"word\");\ntype word2 = __builtin(\"word\");\n\ntype fun1(T, U) = __builtin(\"fun\");\ntype fun2(T, U) = __builtin(\"fun\");\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 9609: (63-94): Duplicate builtin type definition.\n// TypeError 9609: (128-159): Duplicate builtin type definition.\n// TypeError 9609: (197-232): Duplicate builtin type definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition_unknown.sol",
    "content": "pragma experimental solidity;\n\ntype someUnknownType = __builtin(\"someUnknownType\");\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 7758: (31-81): Expected the name of a built-in primitive type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_function.sol",
    "content": "pragma experimental solidity;\n\ntype T(X);\n\nfunction f(p: P, q: T(Q)) {\n    let r: (R, S);\n    let s: S;\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 5934: (57-58): Undeclared type variable.\n// TypeError 5934: (65-66): Undeclared type variable.\n// TypeError 5934: (83-84): Undeclared type variable.\n// TypeError 5934: (86-87): Undeclared type variable.\n// TypeError 5934: (101-102): Undeclared type variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_quantified_function.sol",
    "content": "pragma experimental solidity;\n\nforall A\nfunction f(b: B) {\n    let c: C;\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 5934: (54-55): Undeclared type variable.\n// TypeError 5934: (70-71): Undeclared type variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/forall/undeclared_type_variable_in_type_class.sol",
    "content": "pragma experimental solidity;\n\ntype T(X);\n\nclass Self: C {\n    function f(self: Self);\n}\n\ninstantiation T(Y): C {\n    function f(self: T(Z)) {}\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 5934: (137-138): Undeclared type variable.\n// TypeError 7428: (90-145): Instantiation function 'f' does not match the declaration in the type class (T('bc:type) -> () != T('y:type) -> ()).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/import/experimental_solidity.sol",
    "content": "pragma experimental solidity;\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/import/experimental_solidity_multisource_not_all_enable.sol",
    "content": "==== Source: A.sol ====\ncontract A {}\n==== Source: B.sol ====\npragma experimental solidity;\nimport \"A.sol\";\ncontract B {\n    A a;\n}\n==== Source: C.sol ====\npragma experimental solidity;\nimport \"A.sol\";\ncontract C {\n    A a;\n}\n==== Source: D.sol ====\npragma experimental solidity;\nimport \"A.sol\";\ncontract D {\n    A a;\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// ParserError 2141: (B.sol:0-29): File declares \"pragma experimental solidity\". If you want to enable the experimental mode, all source units must include the pragma.\n// ParserError 2141: (C.sol:0-29): File declares \"pragma experimental solidity\". If you want to enable the experimental mode, all source units must include the pragma.\n// ParserError 2141: (D.sol:0-29): File declares \"pragma experimental solidity\". If you want to enable the experimental mode, all source units must include the pragma.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/import/experimental_solidity_out_of_order_1.sol",
    "content": "contract A {}\n\npragma experimental solidity;\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// ParserError 8185: (45-45): Experimental pragma \"solidity\" can only be set at the beginning of the source unit.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/import/experimental_solidity_out_of_order_2.sol",
    "content": "function f() pure returns (uint)\n{\n    return 1;\n}\n\npragma experimental solidity;\n\nstruct A\n{\n    uint256 x;\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// ParserError 8185: (83-89): Experimental pragma \"solidity\" can only be set at the beginning of the source unit.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/import/experimental_solidity_wrong_evm_version.sol",
    "content": "pragma experimental solidity;\n\ncontract C {}\n\n// ====\n// experimental: true\n// EVMVersion: <constantinople\n// ----\n// ParserError 7637: (31-39): Experimental solidity requires Constantinople EVM version at the minimum.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/import/parsing_stdlib_import_1.sol",
    "content": "pragma experimental solidity;\n\nimport std.stub;\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (std.stub:63-92): Experimental features are turned on. Do not use experimental features on live deployments.\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (std.stub:94-117): Inferred type: () -> ()\n// Info 4164: (std.stub:111-113): Inferred type: ()\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/import/parsing_stdlib_import_2.sol",
    "content": "pragma experimental solidity;\n\nimport std.stub as stub;\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (std.stub:63-92): Experimental features are turned on. Do not use experimental features on live deployments.\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (std.stub:94-117): Inferred type: () -> ()\n// Info 4164: (std.stub:111-113): Inferred type: ()\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/import/parsing_stdlib_import_3.sol",
    "content": "pragma experimental solidity;\n\nimport { identity } from std.stub;\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (std.stub:63-92): Experimental features are turned on. Do not use experimental features on live deployments.\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (std.stub:94-117): Inferred type: () -> ()\n// Info 4164: (std.stub:111-113): Inferred type: ()\n// Info 4164: (40-48): Inferred type: () -> ()\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/import/parsing_stdlib_import_4.sol",
    "content": "pragma experimental solidity;\n\nimport * as stub from std.stub;\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (std.stub:63-92): Experimental features are turned on. Do not use experimental features on live deployments.\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (std.stub:94-117): Inferred type: () -> ()\n// Info 4164: (std.stub:111-113): Inferred type: ()\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/import/parsing_stdlib_import_without_pragma_1.sol",
    "content": "import std.stub;\n// ----\n// ParserError 9478: (7-10): Expected string literal (path), \"*\" or alias list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/import/parsing_stdlib_import_without_pragma_2.sol",
    "content": "import { identity } from std.stub;\n// ----\n// ParserError 6845: (25-28): Expected import path.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/experimental_keywords.sol",
    "content": "function f() pure {\n\tuint word; word;\n\tuint static_assert; static_assert;\n}"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/import_and_call_stdlib_function.sol",
    "content": "pragma experimental solidity;\n\nimport { identity as id } from std.stub;\n\ncontract C\n{\n    fallback() external\n    {\n        id();\n    }\n}\n\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// bytecodeFormat: legacy\n// ----\n// Warning 2264: (std.stub:63-92): Experimental features are turned on. Do not use experimental features on live deployments.\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (std.stub:94-117): Inferred type: () -> ()\n// Info 4164: (std.stub:111-113): Inferred type: ()\n// Info 4164: (40-48): Inferred type: () -> ()\n// Info 4164: (90-135): Inferred type: () -> ()\n// Info 4164: (98-100): Inferred type: ()\n// Info 4164: (124-128): Inferred type: ()\n// Info 4164: (124-126): Inferred type: () -> ()\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/instantiation_invalid_type_constructor.sol",
    "content": "pragma experimental solidity;\n\nclass Self: C {}\n\nfunction f() {}\n\ninstantiation f: C {}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 9831: (80-81): Expected type declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/instantiation_member_type_does_not_match_declaration.sol",
    "content": "pragma experimental solidity;\n\ntype T;\ntype U;\n\nclass Self: C {\n    function f(self: Self);\n}\n\ninstantiation T: C {\n    function f(self: U) {}\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 7428: (95-144): Instantiation function 'f' does not match the declaration in the type class (U -> () != T -> ()).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/instantiation_not_for_class.sol",
    "content": "pragma experimental solidity;\n\ntype T;\ntype U;\n\ninstantiation T: U {}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 3570: (65-66): Expected a type class.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/invalid_type_referenced.sol",
    "content": "pragma experimental solidity;\n\nfunction f() {}\n\nclass Self: C\n{\n    function g(self: Self, x: f);\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 2217: (94-95): Attempt to type identifier referring to unexpected node.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/monomorphic_function_call_type_mismatch.sol",
    "content": "pragma experimental solidity;\n\ntype T;\ntype U;\n\nfunction f(x: T, y: U) {}\n\nfunction run(a: U, b: T) {\n    f(a, b);\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 8456: (106-113): Cannot unify T and U.\n// TypeError 8456: (106-113): Cannot unify U and T.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call.sol",
    "content": "pragma experimental solidity;\n\ntype T;\ntype U(A);\n\nforall (X, Y)\nfunction f(x, y: X, z: U(Y)) {}\n\nfunction run(a: T, b: U(T), c: U(U(T))) {\n    f(a, a, b);\n    f(b, b, c);\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (31-38): Inferred type: T\n// Info 4164: (39-49): Inferred type: tfun('t:type, U('t:type))\n// Info 4164: (45-48): Inferred type: 't:type\n// Info 4164: (46-47): Inferred type: 't:type\n// Info 4164: (58-64): Inferred type: ('u:type, 'v:type)\n// Info 4164: (59-60): Inferred type: 'u:type\n// Info 4164: (62-63): Inferred type: 'v:type\n// Info 4164: (65-96): Inferred type: ('y:type, 'u:type, U('v:type)) -> ()\n// Info 4164: (75-93): Inferred type: ('y:type, 'u:type, U('v:type))\n// Info 4164: (76-77): Inferred type: 'y:type\n// Info 4164: (79-83): Inferred type: 'u:type\n// Info 4164: (82-83): Inferred type: 'u:type\n// Info 4164: (85-92): Inferred type: U('v:type)\n// Info 4164: (88-92): Inferred type: U('v:type)\n// Info 4164: (88-89): Inferred type: tfun('v:type, U('v:type))\n// Info 4164: (90-91): Inferred type: 'v:type\n// Info 4164: (98-173): Inferred type: (T, U(T), U(U(T))) -> ()\n// Info 4164: (110-137): Inferred type: (T, U(T), U(U(T)))\n// Info 4164: (111-115): Inferred type: T\n// Info 4164: (114-115): Inferred type: T\n// Info 4164: (117-124): Inferred type: U(T)\n// Info 4164: (120-124): Inferred type: U(T)\n// Info 4164: (120-121): Inferred type: tfun(T, U(T))\n// Info 4164: (122-123): Inferred type: T\n// Info 4164: (126-136): Inferred type: U(U(T))\n// Info 4164: (129-136): Inferred type: U(U(T))\n// Info 4164: (129-130): Inferred type: tfun(U(T), U(U(T)))\n// Info 4164: (131-135): Inferred type: U(T)\n// Info 4164: (131-132): Inferred type: tfun(T, U(T))\n// Info 4164: (133-134): Inferred type: T\n// Info 4164: (144-154): Inferred type: ()\n// Info 4164: (144-145): Inferred type: (T, T, U(T)) -> ()\n// Info 4164: (146-147): Inferred type: T\n// Info 4164: (149-150): Inferred type: T\n// Info 4164: (152-153): Inferred type: U(T)\n// Info 4164: (160-170): Inferred type: ()\n// Info 4164: (160-161): Inferred type: (U(T), U(T), U(U(T))) -> ()\n// Info 4164: (162-163): Inferred type: U(T)\n// Info 4164: (165-166): Inferred type: U(T)\n// Info 4164: (168-169): Inferred type: U(U(T))\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call_let_polymorphism.sol",
    "content": "pragma experimental solidity;\n\ntype T;\ntype U;\n\nfunction f(x) {}\n\nfunction run(a: T, b: U) {\n    // NOTE: The type of f is polymorphic but the inferred type of g is not - this would be\n    // let-polymorphism, which we decided not to support.\n    let g = f;\n    g(a);\n    g(b);\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 8456: (272-276): Cannot unify T and U.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/polymorphic_function_call_type_mismatch.sol",
    "content": "pragma experimental solidity;\n\ntype T(A);\ntype U;\ntype V;\n\nfunction f(x: T(U)) {}\n\nfunction run(a: T(V)) {\n    f(a);\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 8456: (111-115): Cannot unify U and V.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/polymorphic_type.sol",
    "content": "pragma experimental solidity;\n\ntype T(P, Q, R);\ntype U;\ntype V;\n\nclass Self: C {}\nclass Self: D {}\n\nforall (X, Y, Z)\nfunction run() {\n    let x: T(U, X, Z: C);\n    let y: T(V, Y, Z: D);\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (31-47): Inferred type: tfun(('x:type, 'y:type, 'z:type), T('x:type, 'y:type, 'z:type))\n// Info 4164: (37-46): Inferred type: ('x:type, 'y:type, 'z:type)\n// Info 4164: (38-39): Inferred type: 'x:type\n// Info 4164: (41-42): Inferred type: 'y:type\n// Info 4164: (44-45): Inferred type: 'z:type\n// Info 4164: (48-55): Inferred type: U\n// Info 4164: (56-63): Inferred type: V\n// Info 4164: (65-81): Inferred type: C\n// Info 4164: (71-75): Inferred type: 'k:(type, C)\n// Info 4164: (82-98): Inferred type: D\n// Info 4164: (88-92): Inferred type: 'l:(type, D)\n// Info 4164: (107-116): Inferred type: (?bc:type, ?bd:type, ?bq:(type, C, D))\n// Info 4164: (108-109): Inferred type: ?bc:type\n// Info 4164: (111-112): Inferred type: ?bd:type\n// Info 4164: (114-115): Inferred type: ?bq:(type, C, D)\n// Info 4164: (117-187): Inferred type: () -> ()\n// Info 4164: (129-131): Inferred type: ()\n// Info 4164: (142-158): Inferred type: T(U, ?bc:type, ?bq:(type, C, D))\n// Info 4164: (145-158): Inferred type: T(U, ?bc:type, ?bq:(type, C, D))\n// Info 4164: (145-146): Inferred type: tfun((U, ?bc:type, ?bq:(type, C, D)), T(U, ?bc:type, ?bq:(type, C, D)))\n// Info 4164: (147-148): Inferred type: U\n// Info 4164: (150-151): Inferred type: ?bc:type\n// Info 4164: (153-157): Inferred type: ?bq:(type, C, D)\n// Info 4164: (153-154): Inferred type: ?bq:(type, C, D)\n// Info 4164: (156-157): Inferred type: ?bq:(type, C, D)\n// Info 4164: (168-184): Inferred type: T(V, ?bd:type, ?bq:(type, C, D))\n// Info 4164: (171-184): Inferred type: T(V, ?bd:type, ?bq:(type, C, D))\n// Info 4164: (171-172): Inferred type: tfun((V, ?bd:type, ?bq:(type, C, D)), T(V, ?bd:type, ?bq:(type, C, D)))\n// Info 4164: (173-174): Inferred type: V\n// Info 4164: (176-177): Inferred type: ?bd:type\n// Info 4164: (179-183): Inferred type: ?bq:(type, C, D)\n// Info 4164: (179-180): Inferred type: ?bq:(type, C, D)\n// Info 4164: (182-183): Inferred type: ?bq:(type, C, D)\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_abs_and_rep.sol",
    "content": "pragma experimental solidity;\n\ntype uint;\ntype string;\n\ntype T(A);\ntype U(B) = T(B);\n\nfunction fun() {\n    let w: U(uint);\n    let v: T(uint);\n    U.rep(w);\n    U.abs(v);\n\n    let s: U(string);\n    let t: T(string);\n    U.rep(s);\n    U.abs(t);\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (31-41): Inferred type: uint\n// Info 4164: (42-54): Inferred type: string\n// Info 4164: (56-66): Inferred type: tfun('u:type, T('u:type))\n// Info 4164: (62-65): Inferred type: 'u:type\n// Info 4164: (63-64): Inferred type: 'u:type\n// Info 4164: (67-84): Inferred type: tfun('v:type, U('v:type))\n// Info 4164: (73-76): Inferred type: 'v:type\n// Info 4164: (74-75): Inferred type: 'v:type\n// Info 4164: (79-83): Inferred type: T('v:type)\n// Info 4164: (79-80): Inferred type: tfun('v:type, T('v:type))\n// Info 4164: (81-82): Inferred type: 'v:type\n// Info 4164: (86-245): Inferred type: () -> ()\n// Info 4164: (98-100): Inferred type: ()\n// Info 4164: (111-121): Inferred type: U(uint)\n// Info 4164: (114-121): Inferred type: U(uint)\n// Info 4164: (114-115): Inferred type: tfun(uint, U(uint))\n// Info 4164: (116-120): Inferred type: uint\n// Info 4164: (131-141): Inferred type: T(uint)\n// Info 4164: (134-141): Inferred type: T(uint)\n// Info 4164: (134-135): Inferred type: tfun(uint, T(uint))\n// Info 4164: (136-140): Inferred type: uint\n// Info 4164: (147-155): Inferred type: T(uint)\n// Info 4164: (147-152): Inferred type: U(uint) -> T(uint)\n// Info 4164: (147-148): Inferred type: U(?be:type)\n// Info 4164: (153-154): Inferred type: U(uint)\n// Info 4164: (161-169): Inferred type: U(uint)\n// Info 4164: (161-166): Inferred type: T(uint) -> U(uint)\n// Info 4164: (161-162): Inferred type: U(?bh:type)\n// Info 4164: (167-168): Inferred type: T(uint)\n// Info 4164: (180-192): Inferred type: U(string)\n// Info 4164: (183-192): Inferred type: U(string)\n// Info 4164: (183-184): Inferred type: tfun(string, U(string))\n// Info 4164: (185-191): Inferred type: string\n// Info 4164: (202-214): Inferred type: T(string)\n// Info 4164: (205-214): Inferred type: T(string)\n// Info 4164: (205-206): Inferred type: tfun(string, T(string))\n// Info 4164: (207-213): Inferred type: string\n// Info 4164: (220-228): Inferred type: T(string)\n// Info 4164: (220-225): Inferred type: U(string) -> T(string)\n// Info 4164: (220-221): Inferred type: U(?bo:type)\n// Info 4164: (226-227): Inferred type: U(string)\n// Info 4164: (234-242): Inferred type: U(string)\n// Info 4164: (234-239): Inferred type: T(string) -> U(string)\n// Info 4164: (234-235): Inferred type: U(?br:type)\n// Info 4164: (240-241): Inferred type: T(string)\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/polymorphic_type_instantiation_and_operators.sol",
    "content": "pragma experimental solidity;\n\ntype bool = __builtin(\"bool\");\n\ntype T(A);\ntype int;\ntype str;\n\nclass Self: C {\n    function foo(a: Self, b: Self) -> Self;\n}\n\nclass Self: P1 {}\nclass Self: P2 {}\nclass Self: P3 {}\nclass Self: P4 {}\n\ninstantiation int: P1 {}\ninstantiation int: P2 {}\ninstantiation int: P3 {}\n\ninstantiation str: P1 {}\ninstantiation str: P2 {}\ninstantiation str: P4 {}\n\ninstantiation T(A: P1): + {\n    function add(x: T(A), y: T(A)) -> T(A) {}\n}\n\ninstantiation T(A: P2): == {\n    function eq(x: T(A), y: T(A)) -> bool {}\n}\n\ninstantiation T(A: (P1, P2)): C {\n    function foo(x: T(A), y: T(A)) -> T(A) {}\n}\n\nfunction fun(a: T(int: P3), b: T(str: P4)) {\n    a + a;\n    b + b;\n\n    a == a;\n    b == b;\n\n    C.foo(a, a);\n    C.foo(b, b);\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (31-61): Inferred type: bool\n// Info 4164: (63-73): Inferred type: tfun('y:type, T('y:type))\n// Info 4164: (69-72): Inferred type: 'y:type\n// Info 4164: (70-71): Inferred type: 'y:type\n// Info 4164: (74-83): Inferred type: int\n// Info 4164: (84-93): Inferred type: str\n// Info 4164: (95-156): Inferred type: C\n// Info 4164: (101-105): Inferred type: 'k:(type, C)\n// Info 4164: (115-154): Inferred type: ('k:(type, C), 'k:(type, C)) -> 'k:(type, C)\n// Info 4164: (127-145): Inferred type: ('k:(type, C), 'k:(type, C))\n// Info 4164: (128-135): Inferred type: 'k:(type, C)\n// Info 4164: (131-135): Inferred type: 'k:(type, C)\n// Info 4164: (137-144): Inferred type: 'k:(type, C)\n// Info 4164: (140-144): Inferred type: 'k:(type, C)\n// Info 4164: (149-153): Inferred type: 'k:(type, C)\n// Info 4164: (158-175): Inferred type: P1\n// Info 4164: (164-168): Inferred type: 'l:(type, P1)\n// Info 4164: (176-193): Inferred type: P2\n// Info 4164: (182-186): Inferred type: 'm:(type, P2)\n// Info 4164: (194-211): Inferred type: P3\n// Info 4164: (200-204): Inferred type: 'n:(type, P3)\n// Info 4164: (212-229): Inferred type: P4\n// Info 4164: (218-222): Inferred type: 'o:(type, P4)\n// Info 4164: (231-255): Inferred type: void\n// Info 4164: (256-280): Inferred type: void\n// Info 4164: (281-305): Inferred type: void\n// Info 4164: (307-331): Inferred type: void\n// Info 4164: (332-356): Inferred type: void\n// Info 4164: (357-381): Inferred type: void\n// Info 4164: (383-458): Inferred type: void\n// Info 4164: (398-405): Inferred type: 'bu:(type, P1)\n// Info 4164: (399-404): Inferred type: 'bu:(type, P1)\n// Info 4164: (402-404): Inferred type: 'bu:(type, P1)\n// Info 4164: (415-456): Inferred type: (T('bu:(type, P1)), T('bu:(type, P1))) -> T('bu:(type, P1))\n// Info 4164: (427-445): Inferred type: (T('bu:(type, P1)), T('bu:(type, P1)))\n// Info 4164: (428-435): Inferred type: T('bu:(type, P1))\n// Info 4164: (431-435): Inferred type: T('bu:(type, P1))\n// Info 4164: (431-432): Inferred type: tfun('bu:(type, P1), T('bu:(type, P1)))\n// Info 4164: (433-434): Inferred type: 'bu:(type, P1)\n// Info 4164: (437-444): Inferred type: T('bu:(type, P1))\n// Info 4164: (440-444): Inferred type: T('bu:(type, P1))\n// Info 4164: (440-441): Inferred type: tfun('bu:(type, P1), T('bu:(type, P1)))\n// Info 4164: (442-443): Inferred type: 'bu:(type, P1)\n// Info 4164: (449-453): Inferred type: T('bu:(type, P1))\n// Info 4164: (449-450): Inferred type: tfun('bu:(type, P1), T('bu:(type, P1)))\n// Info 4164: (451-452): Inferred type: 'bu:(type, P1)\n// Info 4164: (460-535): Inferred type: void\n// Info 4164: (475-482): Inferred type: 'ce:(type, P2)\n// Info 4164: (476-481): Inferred type: 'ce:(type, P2)\n// Info 4164: (479-481): Inferred type: 'ce:(type, P2)\n// Info 4164: (493-533): Inferred type: (T('ce:(type, P2)), T('ce:(type, P2))) -> bool\n// Info 4164: (504-522): Inferred type: (T('ce:(type, P2)), T('ce:(type, P2)))\n// Info 4164: (505-512): Inferred type: T('ce:(type, P2))\n// Info 4164: (508-512): Inferred type: T('ce:(type, P2))\n// Info 4164: (508-509): Inferred type: tfun('ce:(type, P2), T('ce:(type, P2)))\n// Info 4164: (510-511): Inferred type: 'ce:(type, P2)\n// Info 4164: (514-521): Inferred type: T('ce:(type, P2))\n// Info 4164: (517-521): Inferred type: T('ce:(type, P2))\n// Info 4164: (517-518): Inferred type: tfun('ce:(type, P2), T('ce:(type, P2)))\n// Info 4164: (519-520): Inferred type: 'ce:(type, P2)\n// Info 4164: (526-530): Inferred type: bool\n// Info 4164: (537-618): Inferred type: void\n// Info 4164: (552-565): Inferred type: 'bi:(type, P1, P2)\n// Info 4164: (553-564): Inferred type: 'bi:(type, P1, P2)\n// Info 4164: (556-564): Inferred type: 'bi:(type, P1, P2)\n// Info 4164: (557-559): Inferred type: 'bi:(type, P1, P2)\n// Info 4164: (561-563): Inferred type: 'bi:(type, P1, P2)\n// Info 4164: (575-616): Inferred type: (T('bi:(type, P1, P2)), T('bi:(type, P1, P2))) -> T('bi:(type, P1, P2))\n// Info 4164: (587-605): Inferred type: (T('bi:(type, P1, P2)), T('bi:(type, P1, P2)))\n// Info 4164: (588-595): Inferred type: T('bi:(type, P1, P2))\n// Info 4164: (591-595): Inferred type: T('bi:(type, P1, P2))\n// Info 4164: (591-592): Inferred type: tfun('bi:(type, P1, P2), T('bi:(type, P1, P2)))\n// Info 4164: (593-594): Inferred type: 'bi:(type, P1, P2)\n// Info 4164: (597-604): Inferred type: T('bi:(type, P1, P2))\n// Info 4164: (600-604): Inferred type: T('bi:(type, P1, P2))\n// Info 4164: (600-601): Inferred type: tfun('bi:(type, P1, P2), T('bi:(type, P1, P2)))\n// Info 4164: (602-603): Inferred type: 'bi:(type, P1, P2)\n// Info 4164: (609-613): Inferred type: T('bi:(type, P1, P2))\n// Info 4164: (609-610): Inferred type: tfun('bi:(type, P1, P2), T('bi:(type, P1, P2)))\n// Info 4164: (611-612): Inferred type: 'bi:(type, P1, P2)\n// Info 4164: (620-748): Inferred type: (T(int), T(str)) -> ()\n// Info 4164: (632-662): Inferred type: (T(int), T(str))\n// Info 4164: (633-646): Inferred type: T(int)\n// Info 4164: (636-646): Inferred type: T(int)\n// Info 4164: (636-637): Inferred type: tfun(int, T(int))\n// Info 4164: (638-645): Inferred type: int\n// Info 4164: (638-641): Inferred type: int\n// Info 4164: (643-645): Inferred type: int\n// Info 4164: (648-661): Inferred type: T(str)\n// Info 4164: (651-661): Inferred type: T(str)\n// Info 4164: (651-652): Inferred type: tfun(str, T(str))\n// Info 4164: (653-660): Inferred type: str\n// Info 4164: (653-656): Inferred type: str\n// Info 4164: (658-660): Inferred type: str\n// Info 4164: (669-674): Inferred type: T(int)\n// Info 4164: (669-670): Inferred type: T(int)\n// Info 4164: (673-674): Inferred type: T(int)\n// Info 4164: (680-685): Inferred type: T(str)\n// Info 4164: (680-681): Inferred type: T(str)\n// Info 4164: (684-685): Inferred type: T(str)\n// Info 4164: (692-698): Inferred type: bool\n// Info 4164: (692-693): Inferred type: T(int)\n// Info 4164: (697-698): Inferred type: T(int)\n// Info 4164: (704-710): Inferred type: bool\n// Info 4164: (704-705): Inferred type: T(str)\n// Info 4164: (709-710): Inferred type: T(str)\n// Info 4164: (717-728): Inferred type: T(int)\n// Info 4164: (717-722): Inferred type: (T(int), T(int)) -> T(int)\n// Info 4164: (717-718): Inferred type: C\n// Info 4164: (723-724): Inferred type: T(int)\n// Info 4164: (726-727): Inferred type: T(int)\n// Info 4164: (734-745): Inferred type: T(str)\n// Info 4164: (734-739): Inferred type: (T(str), T(str)) -> T(str)\n// Info 4164: (734-735): Inferred type: C\n// Info 4164: (740-741): Inferred type: T(str)\n// Info 4164: (743-744): Inferred type: T(str)\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/type_variable_multi_use_function_parameter_and_return.sol",
    "content": "pragma experimental solidity;\n\ntype T;\ntype U;\n\nforall X\nfunction f(x: X) -> X {}\n\nfunction test(t: T, u: U) {\n    t = f(u);\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 8456: (115-123): Cannot unify T and U.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/inference/type_variable_multi_use_function_parameters.sol",
    "content": "pragma experimental solidity;\n\ntype T;\ntype U;\n\nforall X\nfunction f(x: X, y: X) {}\n\nfunction test(t: T, u: U) {\n    f(t, u);\n}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// TypeError 8456: (116-123): Cannot unify T and U.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/parsing/forall_free_function.sol",
    "content": "pragma experimental solidity;\n\nforall (A)\nfunction f(a: A) {}\n\nforall (A, B)\nfunction g(a: A, b: B) {}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (38-41): Inferred type: 's:type\n// Info 4164: (39-40): Inferred type: 's:type\n// Info 4164: (42-61): Inferred type: 's:type -> ()\n// Info 4164: (52-58): Inferred type: 's:type\n// Info 4164: (53-57): Inferred type: 's:type\n// Info 4164: (56-57): Inferred type: 's:type\n// Info 4164: (70-76): Inferred type: ('v:type, 'w:type)\n// Info 4164: (71-72): Inferred type: 'v:type\n// Info 4164: (74-75): Inferred type: 'w:type\n// Info 4164: (77-102): Inferred type: ('v:type, 'w:type) -> ()\n// Info 4164: (87-99): Inferred type: ('v:type, 'w:type)\n// Info 4164: (88-92): Inferred type: 'v:type\n// Info 4164: (91-92): Inferred type: 'v:type\n// Info 4164: (94-98): Inferred type: 'w:type\n// Info 4164: (97-98): Inferred type: 'w:type\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/parsing/forall_free_function_no_type_var.sol",
    "content": "pragma experimental solidity;\n\nforall ()\nfunction f(x: ()) {}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (38-40): Inferred type: ()\n// Info 4164: (41-61): Inferred type: () -> ()\n// Info 4164: (51-58): Inferred type: ()\n// Info 4164: (52-57): Inferred type: ()\n// Info 4164: (55-57): Inferred type: ()\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/parsing/forall_free_function_with_sorts.sol",
    "content": "pragma experimental solidity;\n\nclass Self: Class1 {}\nclass Self: Class2 {}\n\nforall (A: (Class1, Class2), B: Class1)\nfunction f(a: A: Class1, b: B: Class1) {}\n\nforall A: Class1\nfunction g(a: A) {}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.\n// Info 4164: (31-52): Inferred type: Class1\n// Info 4164: (37-41): Inferred type: 'k:(type, Class1)\n// Info 4164: (53-74): Inferred type: Class2\n// Info 4164: (59-63): Inferred type: 'l:(type, Class2)\n// Info 4164: (83-115): Inferred type: ('ba:(type, Class1, Class2), 'bg:(type, Class1))\n// Info 4164: (84-103): Inferred type: 'ba:(type, Class1, Class2)\n// Info 4164: (87-103): Inferred type: 'ba:(type, Class1, Class2)\n// Info 4164: (88-94): Inferred type: 'ba:(type, Class1, Class2)\n// Info 4164: (96-102): Inferred type: 'ba:(type, Class1, Class2)\n// Info 4164: (105-114): Inferred type: 'bg:(type, Class1)\n// Info 4164: (108-114): Inferred type: 'bg:(type, Class1)\n// Info 4164: (116-157): Inferred type: ('ba:(type, Class1, Class2), 'bg:(type, Class1)) -> ()\n// Info 4164: (126-154): Inferred type: ('ba:(type, Class1, Class2), 'bg:(type, Class1))\n// Info 4164: (127-139): Inferred type: 'ba:(type, Class1, Class2)\n// Info 4164: (130-139): Inferred type: 'ba:(type, Class1, Class2)\n// Info 4164: (130-131): Inferred type: 'ba:(type, Class1, Class2)\n// Info 4164: (133-139): Inferred type: 'ba:(type, Class1, Class2)\n// Info 4164: (141-153): Inferred type: 'bg:(type, Class1)\n// Info 4164: (144-153): Inferred type: 'bg:(type, Class1)\n// Info 4164: (144-145): Inferred type: 'bg:(type, Class1)\n// Info 4164: (147-153): Inferred type: 'bg:(type, Class1)\n// Info 4164: (166-175): Inferred type: 'bi:(type, Class1)\n// Info 4164: (166-175): Inferred type: 'bi:(type, Class1)\n// Info 4164: (169-175): Inferred type: 'bi:(type, Class1)\n// Info 4164: (176-195): Inferred type: 'bi:(type, Class1) -> ()\n// Info 4164: (186-192): Inferred type: 'bi:(type, Class1)\n// Info 4164: (187-191): Inferred type: 'bi:(type, Class1)\n// Info 4164: (190-191): Inferred type: 'bi:(type, Class1)\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/parsing/forall_type_class.sol",
    "content": "pragma experimental solidity;\n\nforall (A, B)\nclass Self: C {}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// ParserError 5709: (45-50): Expected a function definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/experimental/parsing/forall_type_class_instantiation.sol",
    "content": "pragma experimental solidity;\n\ntype T;\n\nclass Self: C {}\n\nforall (A, B)\ninstantiation T: C {}\n// ====\n// experimental: true\n// EVMVersion: >=constantinople\n// ----\n// ParserError 5709: (72-85): Expected a function definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/arguments.sol",
    "content": "contract C {\n    fallback(uint256) external {}\n}\n// ----\n// TypeError 5570: (44-44): Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/default_visibility.sol",
    "content": "contract C {\n    // Check that visibility is also enforced for the fallback function.\n    fallback() {}\n}\n// ----\n// SyntaxError 4937: (90-103): No visibility specified. Did you intend to add \"external\"?\n// TypeError 1159: (90-103): Fallback function must be defined as \"external\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/fallback_as_function_name.sol",
    "content": "contract C {\n    function fallback() external pure {}\n}\n// ----\n// Warning 3445: (26-34): This function is named \"fallback\" but is not the fallback function of the contract. If you intend this to be a fallback function, use \"fallback(...) { ... }\" without the \"function\" keyword to define it.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/fallback_duplicate_returns.sol",
    "content": "contract C {\n    fallback(bytes calldata _input) external returns (bytes memory _output) {}\n    fallback() external {}\n}\n// ----\n// DeclarationError 7301: (96-118): Only one fallback function is allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/fallback_duplicate_returns_inheritance.sol",
    "content": "contract C {\n    fallback(bytes calldata _input) external returns (bytes memory _output) {}\n}\ncontract D is C {\n    fallback() external {}\n}\n// ----\n// TypeError 9456: (116-138): Overriding function is missing \"override\" specifier.\n// TypeError 4334: (17-91): Trying to override non-virtual function. Did you forget to add \"virtual\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/fallback_duplicate_returns_override.sol",
    "content": "contract C {\n    fallback(bytes calldata _input) external virtual returns (bytes memory _output) {}\n}\ncontract D is C {\n    fallback() external override {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/fallback_wrong_data_location.sol",
    "content": "contract D {\n    fallback(bytes memory) external returns (bytes memory) {}\n}\ncontract E {\n    fallback(bytes memory) external returns (bytes calldata) {}\n}\ncontract F {\n    fallback(bytes calldata) external returns (bytes calldata) {}\n}\n// ----\n// TypeError 5570: (57-71): Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\".\n// TypeError 5570: (134-150): Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\".\n// TypeError 5570: (215-231): Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/inheritance_multi_base.sol",
    "content": "contract A {\n    fallback (bytes calldata _input) external returns (bytes memory) {\n        return _input;\n    }\n}\ncontract B {\n    fallback (bytes calldata _input) external returns (bytes memory) {\n        return \"xyz\";\n    }\n}\ncontract C is B, A {\n     function f() public returns (bool, bytes memory) {\n        (bool success, bytes memory retval) = address(this).call(\"abc\");\n        return (success, retval);\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// TypeError 6480: (229-420): Derived contract must override function \"\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/no_input_no_output.sol",
    "content": "contract C {\n    fallback() external returns (bytes memory _output) {}\n}\ncontract D {\n    fallback(bytes calldata _input) external {}\n}\n// ----\n// TypeError 5570: (45-67): Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\".\n// TypeError 5570: (131-131): Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/old_syntax.sol",
    "content": "contract C {\n    function() external {}\n}\n// ----\n// ParserError 2915: (37-38): Expected a state variable declaration. If you intended this as a fallback function or a function to handle plain ether transactions, use the \"fallback\" keyword or the \"receive\" keyword instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/payable_fallback_with_inherited_receive.sol",
    "content": "contract A {\n    receive() external payable { }\n}\ncontract C is A {\n    fallback() external payable { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/payable_fallback_without_receive_empty.sol",
    "content": "contract C {\n    fallback() external payable { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/payable_fallback_without_receive_nonempty.sol",
    "content": "contract C {\n    fallback() external payable { }\n    function f() public pure { }\n}\n// ----\n// Warning 3628: (0-83): This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/payable_fallback_without_receive_nonempty_by_inheritance.sol",
    "content": "contract A {\n    function f() external pure {}\n}\ncontract C is A {\n    fallback() external payable { }\n}\n// ----\n// Warning 3628: (49-104): This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/payable_fallback_without_receive_only_internal.sol",
    "content": "contract C {\n    fallback() external payable { }\n    function f() internal pure { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/pure_modifier.sol",
    "content": "contract C {\n    uint x;\n    fallback() external pure { x = 2; }\n}\n// ----\n// TypeError 4575: (29-64): Fallback function must be payable or non-payable, but is \"pure\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/return_value_number.sol",
    "content": "contract C {\n    fallback() external returns (bytes memory, bytes memory) {}\n}\n// ----\n// TypeError 5570: (45-73): Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/return_value_type.sol",
    "content": "contract C {\n    fallback() external returns (uint256) {}\n}\n// ----\n// TypeError 5570: (45-54): Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/return_value_unsupported.sol",
    "content": "contract C {\n    fallback() external returns (bytes memory) {}\n}\n// ----\n// TypeError 5570: (45-59): Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/returns.sol",
    "content": "contract C {\n    fallback(bytes calldata _input) external returns (bytes memory _output) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/fallback/view_modifier.sol",
    "content": "contract C {\n    uint x;\n    fallback() external view { x = 2; }\n}\n// ----\n// TypeError 4575: (29-64): Fallback function must be payable or non-payable, but is \"view\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/circular_reference1functions_first.sol",
    "content": "// Checks that error is triggered no matter which order\nfunction l() {\n    s();\n}\nfunction s() {\n\tnew C();\n}\ncontract D {\n\tfunction f() public {\n\t\tl();\n\t}\n}\ncontract C {\n\tconstructor() { new D(); }\n}\n// ----\n// TypeError 7813: (98-103): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (187-192): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/circular_referencecontracts_first.sol",
    "content": "// Checks that error is triggered no matter which order\ncontract D {\n    function f() public {\n        l();\n    }\n}\ncontract C {\n    constructor() { new D(); }\n}\nfunction l() {\n    s();\n}\nfunction s() {\n    new C();\n}\n// ----\n// TypeError 7813: (207-212): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (149-154): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_call_via_contract_type.sol",
    "content": "contract C {\n    function f() public pure {}\n}\nfunction fun() {\n    C.f();\n}\n// ----\n// TypeError 3419: (68-73): Cannot call function via contract type name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_constructor.sol",
    "content": "constructor() {}\n// ----\n// ParserError 7858: (0-11): Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_different_integer_types.sol",
    "content": "function f(uint24) {}\nfunction f(uint16) {}\nfunction f(int24) {}\nfunction f(bool) {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_fallback.sol",
    "content": "fallback(){}\n// ----\n// ParserError 7858: (0-8): Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_function_modifier.sol",
    "content": "function fun() someModifier {\n}\n// ----\n// DeclarationError 7920: (15-27): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_function_namesake_different_parameter_types.sol",
    "content": "function g() pure returns (uint) { return 1; }\nfunction g() pure returns (string memory) { return \"1\"; }\ncontract C {\n  function foo() public pure returns (uint) {\n    string memory s = g();\n    return 100/g();\n  }\n}\n// ----\n// DeclarationError 1686: (0-46): Function with same name and parameter types defined twice.\n// TypeError 9574: (168-189): Type uint256 is not implicitly convertible to expected type string memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_function_qualified_modifier.sol",
    "content": "contract C {\n  modifier someModifier() { _; }\n}\n\nfunction fun() C.someModifier {\n\n}\n// ----\n// SyntaxError 5811: (49-83): Free functions cannot have modifiers.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_function_shadowing.sol",
    "content": "function f() {}\ncontract C {\n  function f() public {}\n  function g() public {\n    f();\n  }\n}\n// ----\n// Warning 2519: (31-53): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_function_visibility.sol",
    "content": "function fun1() public { }\nfunction fun2() internal { }\n// ----\n// SyntaxError 4126: (0-26): Free functions cannot have visibility.\n// SyntaxError 4126: (27-55): Free functions cannot have visibility.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_function_without_body.sol",
    "content": "function f();\n// ----\n// TypeError 4668: (0-13): Free functions must be implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_functions.sol",
    "content": "function fun(uint256, uint[] calldata _x, uint[] storage _y) view  returns (uint, uint[] calldata) {\n\treturn (_y[0], _x);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_identical.sol",
    "content": "function f() pure returns (uint) { return 1337; }\nfunction f() pure returns (uint) { return 42; }\n// ----\n// DeclarationError 1686: (0-49): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_identical_multiple.sol",
    "content": "function f() pure returns (uint) { return 1337; }\nfunction f() pure returns (uint) { return 42; }\nfunction f() pure returns (uint) { return 1; }\n// ----\n// DeclarationError 1686: (0-49): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_mutability.sol",
    "content": "function f() {\n    uint x = 2;\n    x;\n}\nfunction g(uint[] storage x) pure { x[0] = 1; }\n// ----\n// Warning 2018: (0-39): Function state mutability can be restricted to pure\n// TypeError 8961: (76-80): Function cannot be declared as pure because this expression (potentially) modifies the state.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_namesake_contract_function.sol",
    "content": "function f() pure returns (uint) { return 1337; }\ncontract C {\n  function f() public pure returns (uint) {\n    return f();\n  }\n}\n// ----\n// Warning 2519: (65-126): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_overload.sol",
    "content": "function f(uint) returns (bytes memory) {}\nfunction f(uint[] memory x) returns (bytes memory) { return f(x[0]); }\nfunction g(uint8) {}\nfunction g(uint16) {}\nfunction t() {\n    g(2);\n}\n// ----\n// TypeError 4487: (176-177): No unique declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_override.sol",
    "content": "function fun() override {\n}\n// ----\n// SyntaxError 1750: (0-27): Free functions cannot override.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_payable.sol",
    "content": "function fun() payable {\n}\n// ----\n// TypeError 9559: (0-26): Free functions cannot be payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_receive.sol",
    "content": "receive() {}\n// ----\n// ParserError 7858: (0-7): Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_redefinition.sol",
    "content": "function f() pure returns (uint) { return 1337; }\nfunction f() view returns (uint) { return 42; }\ncontract C {\n  function g() public pure virtual returns (uint) {\n    return f();\n  }\n}\n// ----\n// DeclarationError 1686: (0-49): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_storage.sol",
    "content": "struct S { uint x; }\nfunction fun(S storage) {\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/free_virtual.sol",
    "content": "function fun() virtual {\n}\n// ----\n// SyntaxError 4493: (0-26): Free functions cannot be virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/function_same_name_as_contract.sol",
    "content": "contract C {}\nfunction C() {}\n// ----\n// DeclarationError 2333: (14-29): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/function_using_struct_after_contract.sol",
    "content": "contract C {\n    struct S { uint x; }\n}\nfunction f() returns (uint) { S storage t; }\n// ----\n// DeclarationError 7920: (70-71): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/gas_value.sol",
    "content": "function fun() {\n    fun{gas: 1}();\n    fun{value: 1}();\n}\n// ----\n// TypeError 2193: (21-32): Function call options can only be set on external function calls or contract creations.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/illegal_names.sol",
    "content": "function this() {}\nfunction super() {}\nfunction _() {}\n\ncontract C {\n\tfunction test() public {\n\t\tthis();\n\t\tsuper();\n\t\t_();\n\t}\n}\n// ----\n// DeclarationError 3726: (0-18): The name \"this\" is reserved.\n// DeclarationError 3726: (19-38): The name \"super\" is reserved.\n// DeclarationError 3726: (39-54): The name \"_\" is reserved.\n// Warning 2319: (0-18): This declaration shadows a builtin symbol.\n// Warning 2319: (19-38): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/invalid_function_named_unicode.sol",
    "content": "function unicode() returns {}\n\n// ----\n// ParserError 2314: (9-16): Expected identifier but got 'ILLEGAL'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/named_fallback_warning.sol",
    "content": "function fallback() {}\n// ----\n// Warning 3445: (9-17): This function is named \"fallback\" but is not the fallback function of the contract. If you intend this to be a fallback function, use \"fallback(...) { ... }\" without the \"function\" keyword to define it.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/named_receive_warning.sol",
    "content": "function receive() {}\n// ----\n// Warning 3445: (9-16): This function is named \"receive\" but is not the receive function of the contract. If you intend this to be a receive function, use \"receive(...) { ... }\" without the \"function\" keyword to define it.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/qualified_struct_access.sol",
    "content": "function f() returns (uint) { C.S storage t; t.x; }\n\ncontract C {\n    struct S { uint x; }\n}\n// ----\n// Warning 6321: (22-26): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// TypeError 3464: (45-46): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/struct_after_function.sol",
    "content": "function f(S storage g) view returns (uint) { S storage t = g; return t.x; }\nstruct S { uint x; }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/super_in_free_function.sol",
    "content": "contract C {}\nfunction f() {\n    super;\n}\n// ----\n// DeclarationError 7576: (33-38): Undeclared identifier. \"super\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/freeFunctions/this_in_free_function.sol",
    "content": "contract C {}\nfunction f() {\n    this;\n}\n// ----\n// DeclarationError 7576: (33-37): Undeclared identifier. \"this\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/arbitrary_parameters_but_restricted_first_type.sol",
    "content": "contract C {\n    function f() pure public {\n        abi.encodeWithSelector();\n        abi.encodeWithSignature();\n        abi.encodeWithSelector(uint(2), 2);\n        abi.encodeWithSignature(uint(2), 2);\n    }\n}\n// ----\n// TypeError 9308: (52-76): Need at least 1 arguments for function call, but provided only 0.\n// TypeError 9308: (86-111): Need at least 1 arguments for function call, but provided only 0.\n// TypeError 9553: (144-151): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes4 requested.\n// TypeError 9553: (189-196): Invalid type for argument in function call. Invalid implicit conversion from uint256 to string memory requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/call_unimplemented_base.sol",
    "content": "abstract contract I\n{\n    function a() internal view virtual returns(uint256);\n}\nabstract contract V is I\n{\n    function b() public view returns(uint256) { return a(); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/call_unimplemented_base_via_super.sol",
    "content": "abstract contract I {\n    function a() internal view virtual returns(uint256);\n}\n\nabstract contract C is I {\n    function f() public view returns(uint256) {\n        return I.a();\n    }\n}\n\nabstract contract D is I {\n    function f() public view returns(uint256) {\n        return super.a();\n    }\n}\n// ----\n// TypeError 7501: (172-177): Cannot call unimplemented base function.\n// TypeError 9582: (278-285): Member \"a\" not found or not visible after argument-dependent lookup in type(contract super D).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/calldata_struct_argument_with_internal_data_type_inside.sol",
    "content": "contract C {\n\tstruct S {\n\t\tfunction() a;\n\t}\n\tfunction f(S calldata) public {}\n}\n// ----\n// TypeError 4103: (56-66): Internal type is not allowed for public or external functions."
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/calldata_struct_array_argument_with_internal_data_type_inside.sol",
    "content": "contract C {\n\tstruct S {\n\t\tfunction() a;\n\t}\n\tfunction f(S[2] calldata) public {}\n}\n// ----\n// TypeError 4103: (56-69): Internal type is not allowed for public or external functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/calldata_struct_array_argument_with_internal_data_type_inside_as_constructor_parameter.sol",
    "content": "contract C {\n\tstruct S {\n\t\tfunction() a;\n\t}\n\tconstructor (S[2] storage) public {}\n}\n// ----\n// TypeError 3644: (58-70): This parameter has a type that can only be used internally. You can make the contract abstract to avoid this problem.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/calloptions_duplicated.sol",
    "content": "contract D {}\ncontract C {\n    function foo(int a) payable external {\n        this.foo{gas:2, gas: 5};\n        this.foo{value:2, value: 5};\n        this.foo{gas:2, value: 5, gas:2, value:3};\n        new D{salt:\"abc\", salt:\"efg\"}();\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ====\n// EVMVersion: >=constantinople\n// ----\n// TypeError 9886: (78-101): Duplicate option \"gas\".\n// TypeError 9886: (111-138): Duplicate option \"value\".\n// TypeError 9886: (148-189): Duplicate option \"gas\".\n// TypeError 9886: (148-189): Duplicate option \"value\".\n// TypeError 9886: (199-228): Duplicate option \"salt\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/calloptions_on_delegatecall.sol",
    "content": "contract C {\n    function foo() pure internal {\n        address(10).delegatecall{value: 7, gas: 3}(\"\");\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// TypeError 6189: (56-98): Cannot set option \"value\" for delegatecall.\n// Warning 9302: (56-102): Return value of low-level calls not used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/calloptions_on_internal_function.sol",
    "content": "contract D {}\ncontract C {\n    function foo(int a) pure internal {\n        foo{gas: 5};\n    }\n}\n// ----\n// TypeError 2193: (75-86): Function call options can only be set on external function calls or contract creations.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/calloptions_on_staticcall.sol",
    "content": "contract C {\n    function foo() pure internal {\n        address(10).staticcall{value: 7, gas: 3}(\"\");\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// bytecodeFormat: legacy\n// ----\n// TypeError 2842: (56-96): Cannot set option \"value\" for staticcall.\n// Warning 9302: (56-100): Return value of low-level calls not used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/calloptions_repeated.sol",
    "content": "contract D {}\ncontract C {\n    function foo(int a) payable external {\n        this.foo{value:2, gas: 5}{gas:2};\n        (this.foo{value:2, gas: 5}){gas:2};\n        this.foo{value:2, gas: 5}{value:6};\n        this.foo{gas:2, value: 5}{value:2, gas:5};\n        new D{salt:\"abc\"}{salt:\"a\"}();\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// bytecodeFormat: legacy\n// ----\n// TypeError 1645: (78-110): Function call options have already been set, you have to combine them into a single {...}-option.\n// TypeError 1645: (120-154): Function call options have already been set, you have to combine them into a single {...}-option.\n// TypeError 1645: (164-198): Function call options have already been set, you have to combine them into a single {...}-option.\n// TypeError 1645: (208-249): Function call options have already been set, you have to combine them into a single {...}-option.\n// TypeError 1645: (259-286): Function call options have already been set, you have to combine them into a single {...}-option.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/empty_call_options.sol",
    "content": "contract C {\n    function f() external payable returns (uint) { return 1; }\n    function g() public {\n        this.f{}();\n    }\n}\n// ----\n// ParserError 2314: (116-117): Expected ';' but got '{'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/enum_value_not_callable.sol",
    "content": "enum E { A, B, C }\n\ncontract C {\n    uint a = E.B(1000);\n}\n// ----\n// TypeError 5704: (46-55): This expression is not callable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_delegatecall.sol",
    "content": "contract C {\n    function foo() pure internal {\n        address(10).delegatecall{value: 7, gas: 3}(\"\");\n    }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// TypeError 6189: (56-98): Cannot set option \"value\" for delegatecall.\n// TypeError 3765: (56-98): Function call option \"gas\" cannot be used when compiling to EOF.\n// Warning 9302: (56-102): Return value of low-level calls not used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/eof/calloptions_on_staticcall.sol",
    "content": "contract C {\n    function foo() pure internal {\n        address(10).staticcall{value: 7, gas: 3}(\"\");\n    }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// TypeError 2842: (56-96): Cannot set option \"value\" for staticcall.\n// TypeError 3765: (56-96): Function call option \"gas\" cannot be used when compiling to EOF.\n// Warning 9302: (56-100): Return value of low-level calls not used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/eof/external_call_with_gas_option.sol",
    "content": "contract C {\n    function g(bool x) public pure {\n        require(x);\n    }\n    function f(bool x) public returns (uint) {\n        this.g{gas: 8000}(x);\n    }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// TypeError 3765: (131-148): Function call option \"gas\" cannot be used when compiling to EOF.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/eof/lowlevel_call_options.sol",
    "content": "contract C {\n    function foo() internal {\n        (bool success, ) = address(10).call{value: 7}(\"\");\n        success;\n    }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/int_not_callable.sol",
    "content": "contract C\n{\n    function f ( ) public {\n        ( ( 1 ( 3 ) ) , 2 );\n    }\n}\n// ----\n// TypeError 5704: (53-60): This expression is not callable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/invalid_expressions_with_calloptions1.sol",
    "content": "contract D {}\ncontract C {\n    function foo(int a) pure internal {\n\t\t  a{val:5};\n    }\n}\n// ----\n// TypeError 2622: (71-79): Expected callable expression before call options.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/invalid_expressions_with_calloptions2.sol",
    "content": "contract D {}\ncontract C {\n    function foo(int a) pure external {\n      this.foo{random:5+5};\n    }\n}\n// ----\n// TypeError 9318: (73-93): Unknown call option \"random\". Valid options are \"salt\", \"value\" and \"gas\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/invalid_expressions_with_calloptions3.sol",
    "content": "contract D {}\ncontract C {\n  function foo(int a) external {\n    this.foo{slt:5, value:3, salt: 8};\n  }\n}\n// ----\n// TypeError 9318: (64-97): Unknown call option \"slt\". Valid options are \"salt\", \"value\" and \"gas\".\n// TypeError 7006: (64-97): Cannot set option \"value\" on a non-payable function type.\n// TypeError 2721: (64-97): Function call option \"salt\" can only be used with \"new\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/invalid_named_arguments_conditional.sol",
    "content": "contract C {\n    function g(int x, int y) public pure returns (int) { return x - y; }\n    function h(int y, int x) public pure returns (int) { return y - x; }\n\n    function f() public pure {\n        (true ? g : h)({x : 1, y : 2});\n        [g, h][1]({x : 1, y : 2});\n    }\n}\n// ----\n// TypeError 4974: (199-229): Named argument \"x\" does not match function declaration.\n// TypeError 4974: (199-229): Named argument \"y\" does not match function declaration.\n// TypeError 4974: (239-264): Named argument \"x\" does not match function declaration.\n// TypeError 4974: (239-264): Named argument \"y\" does not match function declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/lowlevel_call_options.sol",
    "content": "contract C {\n    function foo() internal {\n        (bool success, ) = address(10).call{value: 7, gas: 3}(\"\");\n        success;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/magic_not_callable.sol",
    "content": "contract C {\n    uint a = msg(1000);\n}\n// ----\n// TypeError 5704: (26-35): This expression is not callable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/mapping_not_callable.sol",
    "content": "contract C {\n    mapping (uint => uint) m;\n    uint a = m(1000);\n}\n// ----\n// TypeError 5704: (56-63): This expression is not callable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/modifier_not_callable.sol",
    "content": "contract C {\n    uint a = m(1000);\n\n    modifier m(uint) { _; }\n}\n// ----\n// TypeError 5704: (26-33): This expression is not callable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/module_not_callable.sol",
    "content": "==== Source: A.sol ====\n==== Source: B.sol ====\nimport \"A.sol\" as A;\n\ncontract C {\n    uint a = A(1000);\n}\n// ----\n// TypeError 5704: (B.sol:48-55): This expression is not callable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/msg_value_non_payable.sol",
    "content": "contract C {\n    function get() public view returns(uint256) {\n        return msg.value;\n    }\n}\n// ----\n// TypeError 5887: (78-87): \"msg.value\" and \"callvalue()\" can only be used in payable public functions. Make the function \"payable\" or use an internal function to avoid this error.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_duplicate_parameter.sol",
    "content": "contract test {\n    function a(uint a, uint b) public returns (uint r) {\n        r = a + b;\n    }\n    function b() public returns (uint r) {\n        r = a({a: 1, a: 2});\n    }\n}\n// ----\n// Warning 2519: (31-37): This declaration shadows an existing declaration.\n// Warning 2519: (39-45): This declaration shadows an existing declaration.\n// TypeError 6995: (159-160): Duplicate named argument \"a\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_empty.sol",
    "content": "contract test {\n    function a(uint a, uint b) public returns (uint r) {\n        r = a + b;\n    }\n    function b() public returns (uint r) {\n        r = a({});\n    }\n}\n// ----\n// Warning 2519: (31-37): This declaration shadows an existing declaration.\n// Warning 2519: (39-45): This declaration shadows an existing declaration.\n// TypeError 6160: (153-158): Wrong argument count for function call: 0 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_for_functions_that_take_arbitrary_parameters.sol",
    "content": "contract C {\n    function f() pure public {\n        abi.encodeWithSelector({selector:\"abc\"});\n    }\n}\n// ----\n// TypeError 2627: (52-92): Named arguments cannot be used for functions that take arbitrary parameters.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_in_any_order.sol",
    "content": "contract C {\n    function f(uint u, string memory s, bool b) internal {}\n\n    function call() public {\n        f({s: \"abc\", u: 1,     b: true});\n        f({s: \"abc\", b: true,  u: 1});\n        f({u: 1,     s: \"abc\", b: true});\n        f({b: true,  s: \"abc\", u: 1});\n        f({u: 1,     b: true,  s: \"abc\"});\n        f({b: true,  u: 1,     s: \"abc\"});\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_invalid_name.sol",
    "content": "contract test {\n    function f(uint a, bool b, bytes memory c, uint d, bool e) public returns (uint r) {\n        if (b && !e)\n            r = a + d;\n        else\n            r = c.length;\n    }\n    function g() public returns (uint r) {\n        r = f({c: \"abc\", x: 1, e: 2, a: 11, b: 12});\n    }\n}\n// ----\n// TypeError 4974: (249-288): Named argument \"x\" does not match function declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_overload.sol",
    "content": "contract C {\n    function f(uint x) internal { }\n    function f(uint x, uint y) internal { }\n    function f(uint x, uint y, uint z) internal { }\n    function call() internal {\n        f({x: 1});\n        f({x: 1, y: 2});\n        f({y: 2, x: 1});\n        f({x: 1, y: 2, z: 3});\n        f({z: 3, x: 1, y: 2});\n        f({y: 2, z: 3, x: 1});\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_overload_failing1.sol",
    "content": "contract C {\n    function f(uint x) internal { }\n    function f(uint x, uint y) internal { }\n    function f(uint x, uint y, uint z) internal { }\n    function call() internal {\n        f(1, 2);\n        f(1);\n\n        f({x: 1, y: 2});\n        f({y: 2});\n    }\n}\n// ----\n// TypeError 9322: (241-242): No matching declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_overload_failing2.sol",
    "content": "contract C {\n    function f(uint x) internal { }\n    function f(uint x, uint y) internal { }\n    function f(uint x, uint y, uint z) internal { }\n    function call() internal {\n\n        f({x:1, y: 2});\n        f({x:1, z: 3});\n    }\n}\n// ----\n// TypeError 9322: (209-210): No matching declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_overload_failing3.sol",
    "content": "contract C {\n    function f(uint x) internal { }\n    function f(uint x, uint y) internal { }\n    function f(uint x, uint y, uint z) internal { }\n    function call() internal {\n        f({x:1, y: 2, z: 3});\n        f({y:2, v: 10, z: 3});\n    }\n}\n// ----\n// TypeError 9322: (214-215): No matching declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_overload_failing_ambiguous.sol",
    "content": "contract C {\n    function f(uint x, string memory y, bool z) internal {}\n    function f(string memory y, uint x, bool z) internal {}\n    function f(bool z, string memory y, uint x) internal {}\n\n    function call() internal {\n        f({x: 1, y: \"abc\", z: true});\n    }\n}\n// ----\n// TypeError 4487: (233-234): No unique declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_overload_failing_ambiguous_implicit_conversion.sol",
    "content": "contract C {\n    function f(uint x, string memory y) internal {}\n    function f(bytes memory y, int x) internal {}\n\n    function call() internal {\n        f({x: 1, y: \"abc\"});\n    }\n}\n// ----\n// TypeError 4487: (155-156): No unique declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_overload_failing_right_names_wrong_order.sol",
    "content": "contract C {\n    function f(uint x, string memory y, bool z) internal {}\n    function f(uint x, uint y, uint z) internal {}\n\n    function call() internal {\n        f({y: 1, x: \"abc\", z: true});\n    }\n}\n// ----\n// TypeError 9322: (164-165): No matching declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_overload_failing_wrong_names.sol",
    "content": "contract C {\n    function f(uint x, string memory y, bool z) internal {}\n    function f(uint x, uint y, uint z) internal {}\n\n    function call() internal {\n        f({a: 1, b: \"abc\", c: true});\n    }\n}\n// ----\n// TypeError 9322: (164-165): No matching declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_overload_in_any_order.sol",
    "content": "contract C {\n    function f(uint u, string memory s, bool b) internal {}\n    function f(uint u, uint s, uint b) internal {}\n\n    function call() public {\n        f({s: \"abc\", u: 1,     b: true});\n        f({s: \"abc\", b: true,  u: 1});\n        f({u: 1,     s: \"abc\", b: true});\n        f({b: true,  s: \"abc\", u: 1});\n        f({u: 1,     b: true,  s: \"abc\"});\n        f({b: true,  u: 1,     s: \"abc\"});\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/named_arguments_wrong_count.sol",
    "content": "contract test {\n    function a(uint a, uint b) public returns (uint r) {\n        r = a + b;\n    }\n    function b() public returns (uint r) {\n        r = a({a: 1});\n    }\n}\n// ----\n// Warning 2519: (31-37): This declaration shadows an existing declaration.\n// Warning 2519: (39-45): This declaration shadows an existing declaration.\n// TypeError 6160: (153-162): Wrong argument count for function call: 1 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/new_library.sol",
    "content": "library L {}\ncontract C {\n  function f() public pure {\n    new L();\n  }\n}\n// ----\n// TypeError 1130: (63-64): Invalid use of a library name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/new_with_calloptions.sol",
    "content": "contract D { constructor() payable {} }\ncontract C {\n    function foo() pure internal {\n\t\tnew D{salt:\"abc\", value:3};\n\t\tnew D{salt:\"abc\"};\n\t\tnew D{value:5+5};\n\t\tnew D{salt:\"aabbcc\"};\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/new_with_calloptions_unsupported.sol",
    "content": "contract D { constructor() payable {} }\ncontract C {\n    function foo() pure internal {\n\t\tnew D{salt:\"abc\", value:3};\n\t\tnew D{salt:\"abc\"};\n\t\tnew D{value:5+5};\n\t\tnew D{salt:\"aabbcc\"};\n    }\n}\n// ====\n// EVMVersion: <constantinople\n// ----\n// TypeError 5189: (90-116): Unsupported call option \"salt\" (requires Constantinople-compatible VMs).\n// TypeError 5189: (120-137): Unsupported call option \"salt\" (requires Constantinople-compatible VMs).\n// TypeError 5189: (161-181): Unsupported call option \"salt\" (requires Constantinople-compatible VMs).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/new_with_invalid_calloptions.sol",
    "content": "contract D {}\ncontract C {\n    function foo() pure internal {\n\t\tnew D{salt:\"abc\", value:3, gas: 4};\n\t\tnew D{slt:5, value:3};\n\t\tnew D{val:5};\n\t\tnew D{salt:\"xyz\", salt:\"aaf\"};\n\t\tnew D{value:3, value:4};\n\t\tnew D{random:5+5};\n\t\tnew D{what:2130+5};\n\t\tnew D{gas: 2};\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// TypeError 7006: (64-98): Cannot set option \"value\", since the constructor of contract D is not payable.\n// TypeError 9903: (64-98): Function call option \"gas\" cannot be used with \"new\".\n// TypeError 9318: (102-123): Unknown call option \"slt\". Valid options are \"salt\", \"value\" and \"gas\".\n// TypeError 7006: (102-123): Cannot set option \"value\", since the constructor of contract D is not payable.\n// TypeError 9318: (127-139): Unknown call option \"val\". Valid options are \"salt\", \"value\" and \"gas\".\n// TypeError 9886: (143-172): Duplicate option \"salt\".\n// TypeError 7006: (176-199): Cannot set option \"value\", since the constructor of contract D is not payable.\n// TypeError 7006: (176-199): Cannot set option \"value\", since the constructor of contract D is not payable.\n// TypeError 9318: (203-220): Unknown call option \"random\". Valid options are \"salt\", \"value\" and \"gas\".\n// TypeError 9318: (224-242): Unknown call option \"what\". Valid options are \"salt\", \"value\" and \"gas\".\n// TypeError 9903: (246-259): Function call option \"gas\" cannot be used with \"new\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/staticcall_on_homestead.sol",
    "content": "contract C {\n    function f() public {\n        (bool success, ) = address(10).staticcall{gas: 3}(\"\");\n        success;\n    }\n}\n// ====\n// EVMVersion: <byzantium\n// ----\n// TypeError 5052: (66-100): \"staticcall\" is not supported by the VM version.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionCalls/this_not_callable.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this() {\n        } catch Error(string memory) {\n        }\n    }\n}\n// ----\n// TypeError 5704: (72-78): This expression is not callable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/assign_attached_library_function.sol",
    "content": "library L {\n    function foo(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a + b;\n    }\n}\ncontract C {\n    using L for uint256;\n\n    function bar() public {\n        uint256 x;\n        function (uint256, uint256) internal pure returns (uint256) ptr = x.foo;\n    }\n}\n// ----\n// TypeError 9574: (209-280): Type function (uint256,uint256) pure returns (uint256) is not implicitly convertible to expected type function (uint256,uint256) pure returns (uint256). Attached functions cannot be converted into unattached functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/assign_attached_library_function_storage_arg.sol",
    "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n    using D for D.s;\n    D.s x;\n    function f(uint a) public returns (uint) {\n        function (D.s storage, uint) returns (uint) g = x.mul;\n        g(x, a);\n        g(a);\n    }\n}\n// ----\n// TypeError 9574: (218-271): Type function (struct D.s storage pointer,uint256) returns (uint256) is not implicitly convertible to expected type function (struct D.s storage pointer,uint256) returns (uint256). Attached functions cannot be converted into unattached functions.\n// TypeError 6160: (298-302): Wrong argument count for function call: 1 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/assign_builtin.sol",
    "content": "contract C {\n  function f() public {\n     function (uint) view returns (bytes32) _blockhash = blockhash;\n  }\n}\n// ----\n// TypeError 9574: (42-103): Type function (uint256) view returns (bytes32) is not implicitly convertible to expected type function (uint256) view returns (bytes32). Special functions cannot be converted to function types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/call_gas_on_function.sol",
    "content": "contract C {\n    function (uint) external returns (uint) x;\n    function f() public {\n        x{gas: 2}(1);\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/call_value_library_function.sol",
    "content": "library L {\n    function value(function()internal a, uint256 b) internal {}\n}\ncontract C {\n    using L for function()internal;\n    function f() public {\n        function()internal x;\n        x.value(42);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/call_value_on_non_constructor.sol",
    "content": "contract C {\n  // Tests that we don't get a wrong error about constructors\n  function f() public view returns (C) { return this; }\n  function g() public { this.f.value(); }\n}\n// ----\n// TypeError 8820: (155-167): Member \"value\" is only available for payable functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol",
    "content": "contract C {\n    function (uint) external returns (uint) x;\n    function f() public {\n        x{value: 2}(1);\n    }\n}\n// ----\n// TypeError 7006: (94-105): Cannot set option \"value\" on a non-payable function type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol",
    "content": "contract C {\n    function (uint) external payable returns (uint) x;\n    function f() public {\n        x{value: 2}(1);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/call_value_options_on_non_payable_function_type.sol",
    "content": "contract C {\n    function (uint) external returns (uint) x;\n    function g() public {\n        x{value: 2}(1);\n    }\n}\n// ----\n// TypeError 7006: (94-105): Cannot set option \"value\" on a non-payable function type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/comparison_of_function_types_external_eq.sol",
    "content": "contract C {\n    function f() public view returns (bool ret) {\n        return this.f == this.f;\n    }\n    function g() public view returns (bool ret) {\n        return this.f != this.f;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/comparison_of_function_types_gt_1.sol",
    "content": "contract C {\n    function f() public returns (bool ret) {\n        return this.f > this.f;\n    }\n}\n// ----\n// TypeError 2271: (73-88): Built-in binary operator > cannot be applied to types function () external returns (bool) and function () external returns (bool).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/comparison_of_function_types_gt_2.sol",
    "content": "contract C {\n    function f() public returns (bool ret) {\n        return f > f;\n    }\n}\n// ----\n// TypeError 2271: (73-78): Built-in binary operator > cannot be applied to types function () returns (bool) and function () returns (bool).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/comparison_of_function_types_internal_eq_1.sol",
    "content": "contract C {\n    function f() public pure returns (bool ret) {\n        return f == f;\n    }\n    function g() public pure returns (bool ret) {\n        return f != f;\n    }\n}\n// ----\n// Warning 3075: (78-84): Comparison of internal function pointers can yield unexpected results in the legacy pipeline with the optimizer enabled, and will be disallowed entirely in the next breaking release.\n// Warning 3075: (157-163): Comparison of internal function pointers can yield unexpected results in the legacy pipeline with the optimizer enabled, and will be disallowed entirely in the next breaking release.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/comparison_of_function_types_internal_eq_2.sol",
    "content": "contract C {\n    function f() internal {}\n    function g() internal {}\n\n    function test() public pure returns (bool) {\n        function () internal ptr = C.f;\n        return ptr == C.g;\n    }\n}\n// ----\n// Warning 3075: (176-186): Comparison of internal function pointers can yield unexpected results in the legacy pipeline with the optimizer enabled, and will be disallowed entirely in the next breaking release.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/comparison_of_function_types_lt_1.sol",
    "content": "contract C {\n    function f() public returns (bool ret) {\n        return this.f < this.f;\n    }\n}\n// ----\n// TypeError 2271: (73-88): Built-in binary operator < cannot be applied to types function () external returns (bool) and function () external returns (bool).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/comparison_of_function_types_lt_2.sol",
    "content": "contract C {\n    function f() public returns (bool ret) {\n        return f < f;\n    }\n}\n// ----\n// TypeError 2271: (73-78): Built-in binary operator < cannot be applied to types function () returns (bool) and function () returns (bool).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/comparison_operator_for_external_functions_with_call_options.sol",
    "content": "contract C {\n    function external_test_function() payable external {}\n    function comparison_operator_for_external_function_with_extra_slots() external returns (bool) {\n        return (\n            (this.external_test_function{value: 4} == this.external_test_function) &&\n            (this.external_test_function{value: 4} == this.external_test_function{value: 4})\n        );\n    }\n}\n// ----\n// TypeError 2271: (201-269): Built-in binary operator == cannot be applied to types function () payable external and function () payable external.\n// TypeError 2271: (287-365): Built-in binary operator == cannot be applied to types function () payable external and function () payable external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/comparison_operators_between_internal_and_external_function_pointers.sol",
    "content": "contract C {\n    function external_test_function() external {}\n    function internal_test_function() internal {}\n\n    function comparison_operator_between_internal_and_external_function_pointers() external returns (bool) {\n        function () external external_function_pointer_local = this.external_test_function;\n        function () internal internal_function_pointer_local = internal_test_function;\n\n        assert(\n            this.external_test_function == external_function_pointer_local &&\n            internal_function_pointer_local == internal_test_function\n        );\n        assert(\n            internal_function_pointer_local != external_function_pointer_local &&\n            internal_test_function != this.external_test_function\n        );\n\n        return true;\n    }\n}\n// ----\n// Warning 3075: (509-566): Comparison of internal function pointers can yield unexpected results in the legacy pipeline with the optimizer enabled, and will be disallowed entirely in the next breaking release.\n// TypeError 2271: (606-672): Built-in binary operator != cannot be applied to types function () and function () external.\n// TypeError 2271: (688-741): Built-in binary operator != cannot be applied to types function () and function () external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/comparison_operators_external_functions_with_different_parameters.sol",
    "content": "contract C {\n    function external_test_function1(uint num) external {}\n    function external_test_function2(bool val) external {}\n\n    function comparison_operator_between_internal_and_external_function_pointers() external returns (bool) {\n        function () external external_function_pointer_local1 = this.external_test_function1;\n        function () external external_function_pointer_local2 = this.external_test_function2;\n\n        assert(\n            this.external_test_function1 == external_function_pointer_local1 &&\n            this.external_test_function2 == external_function_pointer_local2\n        );\n        assert(\n            external_function_pointer_local2 != external_function_pointer_local1 &&\n            this.external_test_function2 != this.external_test_function1\n        );\n\n        return true;\n    }\n}\n// ----\n// TypeError 9574: (249-333): Type function (uint256) external is not implicitly convertible to expected type function () external.\n// TypeError 9574: (343-427): Type function (bool) external is not implicitly convertible to expected type function () external.\n// TypeError 2271: (458-522): Built-in binary operator == cannot be applied to types function (uint256) external and function () external.\n// TypeError 2271: (538-602): Built-in binary operator == cannot be applied to types function (bool) external and function () external.\n// TypeError 2271: (726-786): Built-in binary operator != cannot be applied to types function (bool) external and function (uint256) external.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/conversion_to_address.sol",
    "content": "contract C {\n    function f() public view returns (address) {\n        return address(this.f);\n    }\n}\n// ----\n// TypeError 5030: (77-92): Explicit type conversion not allowed from \"function () view external returns (address)\" to \"address\". To obtain the address of the contract of the function, you can use the .address member of the function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/declaration_type_conversion.sol",
    "content": "contract D {\n\tfunction f() external {}\n\tfunction g() external {}\n}\ncontract C {\n\tfunction f(bool c) public pure {\n\t\t(c ? D.f : D.g);\n\t}\n}\n// ----\n// TypeError 9717: (121-124): Invalid mobile type in true expression.\n// TypeError 3703: (127-130): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/declaration_type_conversion_internal_base.sol",
    "content": "contract C {\n    function f() internal {}\n    function g() internal {}\n}\n\ncontract D is C {\n    function h(bool b) public pure {\n        (b ? C.f : C.g);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol",
    "content": "contract C {\n    function f() public {\n        delete this.f;\n    }\n}\n// ----\n// TypeError 4247: (54-60): Expression has to be an lvalue.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol",
    "content": "contract C {\n    function(uint) external returns (uint) x;\n    function(uint) internal returns (uint) y;\n    function f() public {\n        delete x;\n        function(uint) internal returns (uint) a = y;\n        delete a;\n        delete y;\n        function() internal c = f;\n        delete c;\n        function(uint) internal returns (uint) g;\n        delete g;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol",
    "content": "contract C {\n    function f() public {\n        delete f;\n    }\n}\n// ----\n// TypeError 4247: (54-55): Expression has to be an lvalue.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/eof/call_gas_on_function.sol",
    "content": "contract C {\n    function (uint) external returns (uint) x;\n    function f() public {\n        x{gas: 2}(1);\n    }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// TypeError 3765: (94-103): Function call option \"gas\" cannot be used when compiling to EOF.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/error_deprecate_gas_function.sol",
    "content": "contract C {\n    function (uint) external payable returns (uint) x;\n    function f() public {\n        x.gas(2)(1);\n    }\n}\n// ----\n// TypeError 1621: (102-107): Using \".gas(...)\" is deprecated. Use \"{gas: ...}\" instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/error_deprecate_value_constructor.sol",
    "content": "contract C {\n    constructor() payable {}\n}\ncontract D {\n    function createC() public returns (C) {\n        C c = (new C).value(2)();\n        return c;\n    }\n}\n// ----\n// TypeError 1621: (115-128): Using \".value(...)\" is deprecated. Use \"{value: ...}\" instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/error_deprecate_value_constructor_nonpayable.sol",
    "content": "contract C {\n    constructor() {}\n}\ncontract D {\n    function createC() public returns (C) {\n        C c = (new C).value(2)();\n        return c;\n    }\n}\n// ----\n// TypeError 8827: (107-120): Constructor for contract C must be payable for member \"value\" to be available.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/error_deprecate_value_function.sol",
    "content": "contract C {\n    function (uint) external payable returns (uint) x;\n    function f() public {\n        x.value(2)(1);\n    }\n}\n// ----\n// TypeError 1621: (102-109): Using \".value(...)\" is deprecated. Use \"{value: ...}\" instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol",
    "content": "// This is a test that checks that the type of the `bytes` parameter is\n// correctly changed from its own type `bytes calldata` to `bytes memory`\n// when converting to a function type.\ncontract C {\n    function f(function(bytes memory) pure external /*g*/) pure public { }\n    function callback(bytes calldata) pure external {}\n    function g() view public {\n        f(this.callback);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/external_function_type_public_variable.sol",
    "content": "contract C {\n    function (uint) external public x;\n\n    function g(uint) public {\n        x = this.g;\n    }\n    function f() public view returns (function(uint) external) {\n        return this.x();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol",
    "content": "contract C {\n    function() external returns (function () internal) x;\n}\n// ----\n// TypeError 2582: (46-67): Internal type cannot be used for external function type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol",
    "content": "contract C {\n    function(function () internal) external x;\n}\n// ----\n// TypeError 2582: (26-47): Internal type cannot be used for external function type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol",
    "content": "contract C {\n    function f() public view returns (address) {\n        return this.f.address;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address_payable.sol",
    "content": "contract C {\n    function f() public view returns (address payable) {\n        return this.f.address;\n    }\n}\n// ----\n// TypeError 6359: (85-99): Return argument type address is not implicitly convertible to expected type (type of first return variable) address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol",
    "content": "contract C {\n    function f() public returns (uint) {\n        return uint(this.f);\n    }\n}\n// ----\n// TypeError 9640: (69-81): Explicit type conversion not allowed from \"function () external returns (uint256)\" to \"uint256\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/external_functions_with_calldata_args_assigned_to_function_pointers_of_same_type.sol",
    "content": "contract C {\n    function f(function (string calldata) external) external {}\n    function g(string calldata) external {}\n\n    function main() external {\n        function (string calldata) external ptr = this.g;\n        abi.encodeCall(this.f, (this.g));\n        this.f(this.g);\n    }\n}\n// ----\n// TypeError 9574: (161-209): Type function (string memory) external is not implicitly convertible to expected type function (string calldata) external.\n// TypeError 5407: (242-250): Cannot implicitly convert component at position 0 from \"function (string memory) external\" to \"function (string calldata) external\".\n// TypeError 9553: (268-274): Invalid type for argument in function call. Invalid implicit conversion from function (string memory) external to function (string calldata) external requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type.sol",
    "content": "contract C {\n    function g(string calldata) external {}\n\n    function main() view external {\n        function (string memory) external ptr = this.g;\n        ptr;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/external_functions_with_variable_number_of_stack_slots.sol",
    "content": "contract C {\n    function f (address) payable external returns (bool) {\n        this.f{value: 42}.address;\n    }\n}\n// ----\n// Warning 6321: (64-68): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/external_library_function_to_external_function_type.sol",
    "content": "library L {\n    function f(uint256 _a) external returns (uint256) {}\n}\n\ncontract C {\n    function run(function(uint256) external returns (uint256) _operation) internal returns (uint256) {}\n    function test() public {\n        run(L.f);\n        function(uint256) external returns (uint256) _operation = L.f;\n    }\n}\n// ----\n// TypeError 9553: (230-233): Invalid type for argument in function call. Invalid implicit conversion from function (uint256) returns (uint256) to function (uint256) external returns (uint256) requested. Special functions cannot be converted to function types.\n// TypeError 9574: (244-305): Type function (uint256) returns (uint256) is not implicitly convertible to expected type function (uint256) external returns (uint256). Special functions cannot be converted to function types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/from_ternary_expression.sol",
    "content": "contract C {\n    function f() public pure returns (uint x) {\n        x = (true ? addmod : addmod)(3, 4, 5);\n    }\n}\n// ----\n// TypeError 9717: (81-87): Invalid mobile type in true expression.\n// TypeError 3703: (90-96): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_parameter_allowed_conversions.sol",
    "content": "contract D {\n    constructor(function() external returns (uint)) {\n    }\n}\n\ncontract E {\n    function test(function() external returns(uint) f) public returns (uint) {\n        return f();\n    }\n}\n\nlibrary L {\n    function test(function() external returns(uint) f) public returns (uint) {\n        return f();\n    }\n}\n\ncontract C {\n    uint x;\n    // tests for usage as constructor parameter\n    function f() public {\n        // An assert used to fail in ABIFunction.cpp that the function types are not exactly equal\n        // that is pure or view v/s default even though they could be converted.\n        new D(this.testPure);\n        new D(this.testView);\n        new D(this.testDefault);\n    }\n\n    // tests for usage as contract function parameter\n    function g() public {\n        E e = E(address(0));\n\n        e.test(this.testPure);\n        e.test(this.testView);\n        e.test(this.testDefault);\n    }\n\n    // tests for usage as library function parameter\n    function h() public {\n        L.test(this.testPure);\n        L.test(this.testView);\n        L.test(this.testDefault);\n    }\n\n    // tests for usage as return parameter\n    function i() public view returns (function() external returns(uint)) {\n        uint value = block.number % 3;\n\n        if (value == 0) {\n            return this.testPure;\n        }\n        else if (value == 1) {\n            return this.testView;\n        }\n        else {\n            return this.testDefault;\n        }\n    }\n\n    modifier mod(function() external returns(uint) fun) {\n        if (fun() == 0) {\n            _;\n        }\n    }\n\n    // tests for usage as modifier parameter\n    function j(function() external pure returns(uint) fun) mod(fun) public {\n    }\n\n    function testPure() public pure returns (uint) {\n        return 0;\n    }\n\n    function testView() public view returns (uint) {\n        return x;\n    }\n\n    function testDefault() public returns (uint) {\n        x = 5;\n        return x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type.sol",
    "content": "contract C {\n    function f() pure public {\n        function(uint) returns (uint) x;\n        x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol",
    "content": "contract C {\n    function(uint) external returns (uint)[] public x;\n    function(uint) internal returns (uint)[10] y;\n    function f() view public {\n        function(uint) returns (uint)[10] memory a;\n        function(uint) returns (uint)[10] storage b = y;\n        function(uint) external returns (uint)[] memory c;\n        c = new function(uint) external returns (uint)[](200);\n        a; b;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol",
    "content": "contract C {\n    // Fool parser into parsing a constructor as a function type.\n    constructor() x;\n}\n// ----\n// SyntaxError 2668: (83-99): Functions without implementation cannot have modifiers.\n// DeclarationError 7920: (97-98): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol",
    "content": "contract C {\n    // Fool parser into parsing a constructor as a function type.\n    function f() {\n      constructor() x;\n    }\n}\n// ----\n// ParserError 6933: (104-115): Expected primary expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_internal_public_variable.sol",
    "content": "contract C {\n    function(bytes memory) internal public a;\n}\n// ----\n// TypeError 6744: (17-57): Internal or recursive type is not allowed for public state variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_named_call.sol",
    "content": "contract C {\n    function f() pure public {\n        function(uint a) returns (uint) x;\n        x({a:2});\n    }\n}\n// ----\n// Warning 6162: (61-67): Naming function type parameters is deprecated.\n// TypeError 4974: (95-103): Named argument \"a\" does not match function declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol",
    "content": "contract C {\n    uint x;\n    function f(function(uint) external returns (uint) g) public returns (function(uint) external returns (uint)) {\n        x = 2;\n        return g;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_return_parameters_with_names.sol",
    "content": "contract C {\n    function(uint) returns (bool ret) f;\n}\n// ----\n// SyntaxError 7304: (41-49): Return parameters in function types may not be named.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol",
    "content": "contract C {\n    function f() public pure returns (function(uint) pure external returns (uint) g) {\n        return g;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_struct.sol",
    "content": "library L\n{\n\tstruct Nested\n\t{\n\t\tuint y;\n\t}\n\tfunction f(function(Nested memory) external) external pure {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_struct_undefined_member.sol",
    "content": "library L\n{\n\tstruct Nested\n\t{\n\t\tNon y;\n\t}\n\tfunction f(function(Nested memory) external) external pure {}\n}\n// ----\n// DeclarationError 7920: (32-35): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol",
    "content": "contract test {\n    function fa(bytes memory) public { }\n    function(bytes memory) external internal a = fa;\n}\n// ----\n// TypeError 7407: (106-108): Type function (bytes memory) is not implicitly convertible to expected type function (bytes memory) external. Special functions cannot be converted to function types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_type_with_transient_param.sol",
    "content": "contract C {\n    function (uint transient) external y;\n    function (uint[] transient) external z;\n}\n// ----\n// Warning 6162: (27-41): Naming function type parameters is deprecated.\n// Warning 6162: (69-85): Naming function type parameters is deprecated.\n// TypeError 6651: (69-85): Data location must be \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_types_internal_visibility_error.sol",
    "content": "contract C {\n    // This is an error, you should explicitly use\n    // `external public` to fix it - `internal public` does not exist.\n    function(bytes memory) public a;\n}\n// ----\n// TypeError 6012: (139-170): Invalid visibility, can only be \"external\" or \"internal\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/function_types_variable_visibility.sol",
    "content": "contract C {\n    function(bytes memory) a1;\n    function(bytes memory) internal b1;\n    function(bytes memory) internal internal b2;\n    function(bytes memory) external c1;\n    function(bytes memory) external internal c2;\n    function(bytes memory) external public c3;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/inline_array_with_attached_function.sol",
    "content": "library L {\n    function f(uint a) internal pure {}\n    function g(uint a) internal pure {}\n}\ncontract C {\n    using L for *;\n    function f() pure public {\n        uint t = 8;\n        [t.f, t.g][0]();\n    }\n}\n// ----\n// TypeError 9563: (186-189): Invalid mobile type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/inline_array_with_attached_function_mixed.sol",
    "content": "library L {\n    function f(uint a) internal pure {}\n}\ncontract C {\n    using L for *;\n    function f() pure public {\n        uint t;\n        function() pure x;\n        [t.f, x][0]({a: 8});\n    }\n}\n// ----\n// TypeError 9563: (169-172): Invalid mobile type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/inline_array_with_payable_function.sol",
    "content": "contract D {\n    function f(uint a) external payable {}\n    function g(uint a) external {}\n}\n\ncontract C {\n    function f() public {\n        D d;\n        [d.f{value: 1}, d.g][0](8);\n    }\n}\n// ----\n// TypeError 9563: (155-168): Invalid mobile type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/internal_function_array_memory_as_external_parameter_in_library_external.sol",
    "content": "library L {\n    // Used to cause internal error\n    function f(function(uint) internal returns (uint)[] memory x) public { }\n}\n// ----\n// TypeError 4103: (63-112): Internal type is not allowed for public or external functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/internal_function_array_storage_as_external_parameter_in_library_external.sol",
    "content": "library L {\n    // Used to cause internal error\n    function g(function(uint) internal returns (uint)[] storage x) public { }\n}\n// ----\n// TypeError 4103: (63-113): Internal type is not allowed for public or external functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol",
    "content": "// It should not be possible to give internal functions\n// as parameters to external functions.\ncontract C {\n    function f(function(uint) internal returns (uint) x) public {\n    }\n}\n// ----\n// TypeError 4103: (124-164): Internal type is not allowed for public or external functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol",
    "content": "library L {\n    function f(function(uint) internal returns (uint) x) public {\n    }\n}\n// ----\n// TypeError 4103: (27-67): Internal type is not allowed for public or external functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol",
    "content": "library L {\n    function f(function(uint) internal returns (uint) /*x*/) pure internal {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol",
    "content": "// It should not be possible to return internal functions from external functions.\ncontract C {\n    function f() public returns (function(uint) internal returns (uint) x) {\n    }\n}\n// ----\n// TypeError 4103: (129-169): Internal type is not allowed for public or external functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/internal_function_struct_as_external_parameter_in_library_external.sol",
    "content": "library L {\n    struct S\n    {\n        function(uint) internal returns (uint)[] x;\n    }\n    function f(S storage s) public { }\n}\n// ----\n// TypeError 4103: (104-115): Internal type is not allowed for public or external functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol",
    "content": "contract C {\n    function f() public returns (address) {\n        return address(f);\n    }\n}\n// ----\n// TypeError 9640: (72-82): Explicit type conversion not allowed from \"function () returns (address)\" to \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/internal_functions_with_calldata_args_assigned_to_function_pointers_of_same_type.sol",
    "content": "contract C {\n    function g(bytes calldata b) pure internal {}\n\n    function main() pure external {\n        function (bytes calldata) internal ptr = g;\n        ptr;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol",
    "content": "contract C {\n    function (uint) internal payable returns (uint) x;\n}\n// ----\n// TypeError 7415: (17-66): Only external function types can be payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol",
    "content": "contract C {\n    function (uint) internal payable returns (uint) x;\n\n    function g() public {\n        x = g;\n    }\n}\n// ----\n// TypeError 7415: (17-66): Only external function types can be payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/private_function_type.sol",
    "content": "contract C {\n    function f() public {\n        function(uint) private returns (uint) x;\n    }\n}\n// ----\n// TypeError 6012: (47-86): Invalid visibility, can only be \"external\" or \"internal\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/public_function_type.sol",
    "content": "contract C {\n    function f() public {\n        function(uint) public returns (uint) x;\n    }\n}\n// ----\n// TypeError 6012: (47-85): Invalid visibility, can only be \"external\" or \"internal\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/selector_ternary_contract_external_function.sol",
    "content": "contract C {\n    function f() external pure { }\n    function g() external pure { }\n    function test(bool b) public returns(bytes4) {\n        (b ? C.f : C.g).selector;\n    }\n}\n// ----\n// TypeError 9717: (147-150): Invalid mobile type in true expression.\n// TypeError 3703: (153-156): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/selector_ternary_different_contract_public_function.sol",
    "content": "contract C {\n    function f() public pure { }\n    function g() public pure { }\n}\n\ncontract A {\n    function test(bool b) public returns(bytes4) {\n        (b ? C.f : C.g).selector;\n    }\n}\n// ----\n// TypeError 9717: (159-162): Invalid mobile type in true expression.\n// TypeError 3703: (165-168): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/selector_ternary_different_contracts_external_function.sol",
    "content": "contract C {\n    function f() external pure { }\n}\n\ncontract D {\n    function g() external pure { }\n}\n\ncontract A {\n    function test(bool b) public returns(bytes4) {\n        (b ? C.f : D.g).selector;\n    }\n}\n// ----\n// TypeError 9717: (179-182): Invalid mobile type in true expression.\n// TypeError 3703: (185-188): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/selector_ternary_different_interface_external_function.sol",
    "content": "interface I1 {\n    function f() external pure;\n}\n\ninterface I2 {\n    function g() external pure;\n}\n\ncontract C {\n    function test(bool b) public returns(bytes4) {\n        (b ? I1.f : I2.g).selector;\n    }\n}\n// ----\n// TypeError 9717: (177-181): Invalid mobile type in true expression.\n// TypeError 3703: (184-188): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/selectors.sol",
    "content": "contract B {\n    function ext() external {}\n    function pub() public {}\n}\n\ncontract C is B {\n    function test() public pure {\n        B.ext.selector;\n        B.pub.selector;\n        this.ext.selector;\n        pub.selector;\n    }\n}\n\ncontract D {\n    function test() public pure {\n        B.ext.selector;\n        B.pub.selector;\n    }\n}\n// ----\n// Warning 6133: (136-150): Statement has no effect.\n// Warning 6133: (160-174): Statement has no effect.\n// Warning 6133: (184-201): Statement has no effect.\n// Warning 6133: (289-303): Statement has no effect.\n// Warning 6133: (313-327): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/ternary_contract_delegate_function.sol",
    "content": "library L {\n    function f() external {}\n}\n\ncontract C {\n    function test() public {\n        (true ? L.f : L.f).selector;\n    }\n}\n\n// ----\n// TypeError 9582: (94-121): Member \"selector\" not found or not visible after argument-dependent lookup in function ().\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/ternary_with_attached_functions.sol",
    "content": "library L {\n    function f(uint a) internal pure {}\n    function g(uint a) internal pure {}\n}\ncontract C {\n    using L for *;\n    function f(bool x) pure public {\n        uint t = 8;\n        (x ? t.f : t.g)();\n    }\n}\n// ----\n// TypeError 9717: (196-199): Invalid mobile type in true expression.\n// TypeError 3703: (202-205): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_param_named_transient.sol",
    "content": "contract C {\n    function (uint transient) external transient y;\n}\n// ====\n// stopAfter: parsing\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_transient_param.sol",
    "content": "contract C {\n    function (uint transient x) external transient y;\n}\n// ----\n// ParserError 2314: (42-43): Expected ',' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol",
    "content": "contract test {\n    function fa(uint) public {}\n    function fb(uint) internal {}\n    function fc(uint) internal {}\n    function fd(uint) external {}\n    function fe(uint) external {}\n    function ff(uint) internal {}\n    function fg(uint) internal pure {}\n    function fh(uint) pure internal {}\n\n    function(uint) a = fa;\n    function(uint) internal b = fb; // (explicit internal applies to the function type)\n    function(uint) internal internal c = fc;\n    function(uint) external d = this.fd;\n    function(uint) external internal e = this.fe;\n    function(uint) internal f = ff;\n    function(uint) internal pure g = fg;\n    function(uint) pure internal h = fh;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol",
    "content": "contract C {\n    function(uint a) f;\n}\n// ----\n// Warning 6162: (26-32): Naming function type parameters is deprecated.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/getter/complex_struct.sol",
    "content": "contract C {\n    struct Y {\n        uint a;\n        uint b;\n    }\n    mapping(uint256 => Y) public m;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/getter/nested_structs.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    struct Y {\n        uint b;\n    }\n    struct X {\n        Y a;\n    }\n    mapping(uint256 => X) public m;\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2763: (108-138): The following types are only supported for getters in ABI coder v2: struct C.Y memory. Either remove \"public\" or use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/getter/recursive_struct.sol",
    "content": "contract C {\n    struct Y {\n        Y[] x;\n    }\n    mapping(uint256 => Y) public m;\n}\n// ----\n// TypeError 6744: (53-83): Internal or recursive type is not allowed for public state variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/getter/simple_struct.sol",
    "content": "contract C {\n    struct Y {\n        uint b;\n    }\n    mapping(uint256 => Y) public m;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/blobhash_function_pre_cancun.sol",
    "content": "contract C {\n    function blobhash(uint256 index) public pure returns(bytes32) {\n        return bytes32(index);\n    }\n    function f() public pure returns(bytes32) {\n        return blobhash(2);\n    }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/blobhash_function_shadow_warning.sol",
    "content": "contract C {\n    function blobhash(uint256 index) public pure returns(bytes32) {\n        return bytes32(index);\n    }\n    function f() public pure returns(bytes32) {\n        return blobhash(2);\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// Warning 2319: (17-117): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/blobhash_no_call.sol",
    "content": "contract C\n{\n    function f() public pure {\n        blobhash;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// Warning 6133: (52-60): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/blobhash_not_declared_pre_cancun.sol",
    "content": "contract C\n{\n    function f() public pure {\n        blobhash;\n    }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// DeclarationError 7576: (52-60): Undeclared identifier. Did you mean \"blockhash\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/blobhash_var_pre_cancun.sol",
    "content": "contract C {\n    function f() public pure returns (bool) {\n        bool blobhash = true;\n        return blobhash;\n    }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/blobhash_var_shadow_warning.sol",
    "content": "contract C\n{\n    function f() public pure returns (bool) {\n        bool blobhash = true;\n        return blobhash;\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// Warning 2319: (67-80): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/call_with_wrong_arg_count.sol",
    "content": "contract C {\n    function f() public {\n        (bool success,) = address(this).call();\n        require(success);\n        (success,) = address(this).call(bytes4(0x12345678));\n        require(success);\n        (success,) = address(this).call(uint(1));\n        require(success);\n        (success,) = address(this).call(uint(1), uint(2));\n        require(success);\n    }\n}\n// ----\n// TypeError 6138: (65-85): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use \"\" as argument to provide empty calldata.\n// TypeError 8051: (153-171): Invalid type for argument in function call. Invalid implicit conversion from bytes4 to bytes memory requested. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.\n// TypeError 8051: (240-247): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.\n// TypeError 8922: (297-333): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/callcode_with_wrong_arg_count.sol",
    "content": "contract C {\n    function f() public {\n        (bool success,) = address(this).callcode();\n        require(success);\n        (success,) = address(this).callcode(uint(1));\n        require(success);\n        (success,) = address(this).callcode(uint(1), uint(2));\n        require(success);\n    }\n}\n// ----\n// TypeError 6138: (65-89): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use \"\" as argument to provide empty calldata.\n// TypeError 8051: (161-168): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.\n// TypeError 8922: (218-258): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/delegatecall_with_wrong_arg_count.sol",
    "content": "contract C {\n    function f() public {\n        (bool success,) = address(this).delegatecall();\n        require(success);\n        (success,) = address(this).delegatecall(uint(1));\n        require(success);\n        (success,) = address(this).delegatecall(uint(1), uint(2));\n        require(success);\n    }\n}\n// ----\n// TypeError 6138: (65-93): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use \"\" as argument to provide empty calldata.\n// TypeError 8051: (169-176): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.\n// TypeError 8922: (226-270): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/deprecated_functions.sol",
    "content": "contract test {\n\tfunction f() pure public {\n\t\tbytes32 x = sha3(\"\");\n\t\tx;\n\t}\n\tfunction g() public {\n\t\tsuicide(payable(0x0000000000000000000000000000000000000001));\n\t}\n}\n// ----\n// TypeError 3557: (58-62): \"sha3\" has been deprecated in favour of \"keccak256\".\n// TypeError 8050: (101-108): \"suicide\" has been deprecated in favour of \"selfdestruct\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_abi_encode_comptime.sol",
    "content": "contract C layout at erc7201(string(abi.encodePacked(bytes32(uint256(2))))) {}\n// ----\n// TypeError 1505: (21-75): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_function_pointer_assignment.sol",
    "content": "contract C {\n    function (string memory) pure returns (uint256) functionPointer;\n    function f() public pure {\n        functionPointer = erc7201;\n    }\n}\n// ----\n// TypeError 7407: (139-146): Type function (string memory) pure returns (uint256) is not implicitly convertible to expected type function (string memory) pure returns (uint256). Special functions cannot be converted to function types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_function_shadow_warning.sol",
    "content": "function erc7201() pure returns (uint) {\n    return 42;\n}\n// ----\n// Warning 2319: (0-57): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_invalid_gas_function_option.sol",
    "content": "contract C {\n    function f() public pure returns (uint) {\n        return erc7201{gas: 10}(\"x\");\n    }\n}\n// ----\n// TypeError 2193: (74-90): Function call options can only be set on external function calls or contract creations.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_no_call.sol",
    "content": "contract C {\n    function f() public pure {\n        erc7201;\n    }\n}\n// ----\n// Warning 6133: (52-59): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_overflow_expression_comptime.sol",
    "content": "contract C {\n    uint[erc7201(\"main:example\") + erc7201(\"main:example\")] array;\n}\n// ----\n// TypeError 2643: (22-71): Arithmetic error when computing constant value.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_bytes_converted_to_string.sol",
    "content": "bytes constant bytesParam = \"abcdef\";\ncontract C {\n    function f() public pure returns (uint256) {\n        uint256 x = erc7201(string(bytesParam));\n        return x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_constant_string_unitary_tuple.sol",
    "content": "contract C {\n    string constant const = (\"x\");\n    function constArg() public pure returns (uint) {\n        return erc7201(const);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_invalid_bytes.sol",
    "content": "bytes constant bytesArg = \"abcdef\";\ncontract C {\n    function f() public pure returns (uint256) {\n        return erc7201(bytesArg);\n    }\n}\n// ----\n// TypeError 6896: (121-129): The argument to erc7201 builtin must be a string. The supplied argument has type bytes.\n// TypeError 9553: (121-129): Invalid type for argument in function call. Invalid implicit conversion from bytes memory to string memory requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_invalid_hex_literal.sol",
    "content": "contract C {\n    function f() public pure returns (uint) {\n        return erc7201(hex\"001122FF\");\n    }\n}\n// ----\n// TypeError 9553: (82-95): Invalid type for argument in function call. Invalid implicit conversion from literal_string hex\"001122ff\" to string memory requested. Contains invalid UTF-8 sequence at position 3.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_invalid_number_literal.sol",
    "content": "contract C {\n    function f() public pure returns (uint) {\n        return erc7201(123);\n    }\n}\n// ----\n// TypeError 6896: (82-85): The argument to erc7201 builtin must be a string.\n// TypeError 9553: (82-85): Invalid type for argument in function call. Invalid implicit conversion from int_const 123 to string memory requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_named.sol",
    "content": "contract C {\n    uint x = erc7201({namespaceID: \"example.main\"});\n}\n// ----\n// TypeError 4974: (26-64): Named argument \"namespaceID\" does not match function declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_string_unitary_tuple_comptime.sol",
    "content": "contract C layout at erc7201((\"example.main\")) {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_string_var_with_escaped_chars_comptime.sol",
    "content": "contract C layout at erc7201(\"\\n\\\"\\'\\\\abc\\\ndef\") {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_string_variable.sol",
    "content": "string constant fileLevelStr = \"test.file\";\ncontract C {\n    string constant stateVarStr = \"example.contract\";\n    function fileLevel() public pure returns (uint) {\n        return erc7201(fileLevelStr);\n    }\n    function stateVar() public pure returns (uint) {\n        return erc7201(stateVarStr);\n    }\n    function localVar() public pure returns (uint) {\n        string memory localVarStr = \"example.main\";\n        return erc7201(localVarStr);\n    }\n    function funcMemParam(string memory paramStr) public pure returns (uint) {\n        return erc7201(paramStr);\n    }\n    function funcCallDataParam(string calldata paramStr) public pure returns (uint) {\n        return erc7201(paramStr);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_string_variable_comptime.sol",
    "content": "string constant CONST = \"test.file\";\ncontract C {\n    uint8[erc7201(CONST)] array;\n}\n// ----\n// Warning 7325: (54-75): Type uint8[5237610212305498718603509572682216073844539971870822423088087032295879652864] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_string_with_whitespaces_comptime.sol",
    "content": "contract C {\n    function f() public pure returns (uint) {\n        return erc7201(\"\\tstring with spaces\\n\\r\");\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_unicode_literal.sol",
    "content": "contract C {\n    function f() public pure returns (uint) {\n        return erc7201(unicode\"Hello 😃\");\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_param_wrong_count.sol",
    "content": "contract C {\n    uint x = erc7201();\n    uint y = erc7201(\"12\", \"34\");\n    uint z = erc7201(\"A\", \"BC\", \"D\");\n}\n// ----\n// TypeError 6160: (26-35): Wrong argument count for function call: 0 arguments given but expected 1.\n// TypeError 6160: (50-69): Wrong argument count for function call: 2 arguments given but expected 1.\n// TypeError 6160: (84-107): Wrong argument count for function call: 3 arguments given but expected 1.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/erc7201_builtin_variable_name_shadow_warning.sol",
    "content": "contract C {\n    uint erc7201;\n}\n// ----\n// Warning 2319: (17-29): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/keccak256_with_wrong_arg_count.sol",
    "content": "contract C {\n    function f() public {\n        require(keccak256() != 0);\n        require(keccak256(uint(1)) != 0);\n        require(keccak256(uint(1), uint(2)) != 0);\n    }\n}\n// ----\n// TypeError 4323: (55-66): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n// TypeError 7556: (100-107): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n// TypeError 4323: (132-159): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/log_deprecate.sol",
    "content": "contract C {\n\tfunction f() public {\n\t\tlog0;\n\t\tlog1;\n\t\tlog2;\n\t\tlog3;\n\t\tlog4;\n\t}\n}\n// ----\n// DeclarationError 7576: (38-42): Undeclared identifier.\n// DeclarationError 7576: (46-50): Undeclared identifier.\n// DeclarationError 7576: (54-58): Undeclared identifier.\n// DeclarationError 7576: (62-66): Undeclared identifier.\n// DeclarationError 7576: (70-74): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/now_deprecate.sol",
    "content": "contract C {\n\tfunction f() public {\n\t\tnow;\n\t}\n}\n// ----\n// TypeError 7359: (38-41): \"now\" has been deprecated. Use \"block.timestamp\" instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/now_override.sol",
    "content": "contract C {\n\tfunction f() public view {\n\t\tuint now = block.timestamp;\n\t\tnow;\n\t}\n}\n// ----\n// Warning 2319: (43-51): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/ripemd160_with_wrong_arg_count.sol",
    "content": "contract C {\n    function f() public {\n        require(ripemd160() != 0);\n        require(ripemd160(uint(1)) != 0);\n        require(ripemd160(uint(1), uint(2)) != 0);\n    }\n}\n// ----\n// TypeError 4323: (55-66): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n// TypeError 7556: (100-107): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n// TypeError 4323: (132-159): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/selfdestruct_no_call.sol",
    "content": "contract C {\n    function f() pure public { selfdestruct; }\n}\n// ----\n// Warning 5159: (44-56): \"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.\n// Warning 6133: (44-56): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/sha256_with_wrong_arg_count.sol",
    "content": "contract C {\n    function f() public {\n        require(sha256() != 0);\n        require(sha256(uint(1)) != 0);\n        require(sha256(uint(1), uint(2)) != 0);\n    }\n}\n// ----\n// TypeError 4323: (55-63): Wrong argument count for function call: 0 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n// TypeError 7556: (94-101): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n// TypeError 4323: (126-150): Wrong argument count for function call: 2 arguments given but expected 1. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/sha3_no_call.sol",
    "content": "contract C\n{\n\tfunction f(bytes memory data) public pure {\n\t\tsha3;\n\t}\n}\n// ----\n// TypeError 3557: (60-64): \"sha3\" has been deprecated in favour of \"keccak256\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/sha3_override.sol",
    "content": "contract C\n{\n\tfunction sha3() public pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction f() public pure returns (bool) {\n\t\treturn sha3();\n\t}\n}\n// ----\n// Warning 2319: (14-76): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/sha3_var.sol",
    "content": "contract C\n{\n\tfunction f() public pure returns (bool) {\n\t\tbool sha3 = true;\n\t\treturn sha3;\n\t}\n}\n// ----\n// Warning 2319: (58-67): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/suicide_no_call.sol",
    "content": "contract C\n{\n\tfunction f(bytes memory data) public pure {\n\t\tsuicide;\n\t}\n}\n// ----\n// TypeError 8050: (60-67): \"suicide\" has been deprecated in favour of \"selfdestruct\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/suicide_override.sol",
    "content": "contract C\n{\n\tfunction suicide() public pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction f() public pure returns (bool) {\n\t\treturn suicide();\n\t}\n}\n// ----\n// Warning 2319: (14-79): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/globalFunctions/suicide_var.sol",
    "content": "contract C\n{\n\tfunction f() public pure returns (bool) {\n\t\tbool suicide = true;\n\t\treturn suicide;\n\t}\n}\n// ----\n// Warning 2319: (58-70): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/calling_external_function_via_local_variable_with_invalid_type.sol",
    "content": "contract C {\n    function f() public {\n        function() external returns (function() internal) getCallback;\n        getCallback();\n    }\n}\n// ----\n// TypeError 2582: (76-96): Internal type cannot be used for external function type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/calling_external_function_via_parameter_with_invalid_type.sol",
    "content": "contract C {\n    function f(\n        function() external returns (function() internal) getCallback\n    ) public {\n        getCallback();\n    }\n}\n// ----\n// TypeError 2582: (66-86): Internal type cannot be used for external function type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/const_struct_with_mapping.sol",
    "content": "contract C {\n    struct S {\n        mapping(uint => uint) c;\n    }\n    S public constant e = 0x1212121212121212121212121212121212121212;\n}\n// ----\n// TypeError 9259: (71-135): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/cycle_checker_function_type.sol",
    "content": "// Used to cause ICE.\ncontract C {\n        function ( ) internal returns ( bytes [ ] storage , mapping ( bytes => mapping ( bytes => mapping ( uint => mapping ( bytes => mapping ( string => mapping ( uint => mapping ( uint => mapping ( uint => mapping ( uint => mapping ( string => mapping ( string => mapping ( uint => mapping ( bytes => mapping ( uint => mapping ( uint => mapping ( uint => mapping ( uint => mapping ( uint => mapping ( bytes => mapping ( uint => mapping ( uint => mapping ( uint => mapping ( uint => mapping ( string => mapping ( uint => string ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) [ ] storage ) constant c = c ;\n}\n// ----\n// TypeError 6161: (43-643): The value of the constant c has a cyclic dependency via c.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_bitnot_tuple.sol",
    "content": "contract C\n{\n    function f() public\n    {\n        int x = ~(0,);\n    }\n}\n// ----\n// TypeError 8381: (60-64): Tuple component cannot be empty.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_dec_tuple.sol",
    "content": "contract C\n{\n    function f() public\n    {\n        int x = --(,);\n    }\n}\n// ----\n// TypeError 9767: (59-64): Built-in unary operator -- cannot be applied to type tuple(,).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_delete_tuple.sol",
    "content": "contract C\n{\n    function f() public\n    {\n        int x = delete (,0);\n    }\n}\n// ----\n// TypeError 4247: (68-69): Expression has to be an lvalue.\n// TypeError 9767: (59-70): Built-in unary operator delete cannot be applied to type tuple(,int_const 0).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_inc_tuple.sol",
    "content": "contract C\n{\n    function f() public\n    {\n        (int x) = ++(,);\n    }\n}\n// ----\n// TypeError 9767: (61-66): Built-in unary operator ++ cannot be applied to type tuple(,).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_unary_plus_tuple.sol",
    "content": "contract C\n{\n    function f() public\n    {\n        int x = +(0, 0);\n    }\n}\n// ----\n// ParserError 9636: (59-60): Use of unary + is disallowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_unary_plus_tuple_compound_assign.sol",
    "content": "contract C\n{\n    function f(int x) public\n    {\n        (x /= 1) + +(1,1);\n    }\n}\n// ----\n// ParserError 9636: (67-68): Use of unary + is disallowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/declarationUnaryTuple/declaration_unary_tuple.sol",
    "content": "contract C\n{\n    function f() public\n    {\n        int y = -(0, 0);\n        (int z) = ~(0, 0);\n        (int t) = !(0, 0);\n    }\n}\n// ----\n// TypeError 4907: (59-66): Built-in unary operator - cannot be applied to type tuple(int_const 0,int_const 0).\n// TypeError 7364: (51-66): Different number of components on the left hand side (1) than on the right hand side (2).\n// TypeError 4907: (86-93): Built-in unary operator ~ cannot be applied to type tuple(int_const 0,int_const 0).\n// TypeError 7364: (76-93): Different number of components on the left hand side (1) than on the right hand side (2).\n// TypeError 4907: (113-120): Built-in unary operator ! cannot be applied to type tuple(int_const 0,int_const 0).\n// TypeError 7364: (103-120): Different number of components on the left hand side (1) than on the right hand side (2).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/identifier_collision_return_declare.sol",
    "content": "contract C {\n        function ( uint ) external returns ( a [ ] calldata ) public a = ( 1 / 2 ) ;\n}\n// ----\n// TypeError 5172: (58-59): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/large_array_in_memory_struct.sol",
    "content": "contract C {\n        struct X { bytes31 [ 3 ] x1 ;\n                uint x2 ;\n        }\n        struct S { uint256 [ ] [ 0.425781 ether ] s1 ;\n                uint [ 2 ** 0xFF ] [ 2 ** 0x42 ] s2 ;\n                X s3 ;\n                uint [ 9 hours ** 16 ] d ;\n                string s ;\n        }\n        function f ( ) public { function ( function ( bytes9 , uint ) external pure returns ( uint ) , uint ) external pure returns ( uint ) [ 3 ] memory s2 ;\n                S memory s ;\n        }\n}\n// ----\n// TypeError 1534: (474-484): Type too large for memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/large_array_in_memory_struct_2.sol",
    "content": "contract C {\n    struct R { uint[10][10] y; }\n    struct S { uint a; uint b; R d; uint[20][20][2999999999999999999999999990] c; }\n    function f() public pure {\n        C.S memory y;\n        C.S[10] memory z;\n        y.a < 2;\n        z; y;\n    }\n}\n// ----\n// TypeError 1534: (169-181): Type too large for memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/large_struct_array.sol",
    "content": "// Used to cause ICE because of a too strict assert\npragma abicoder               v2;\ncontract C {\n    struct S { uint a; T[222222222222222222222222222] sub; }\n    struct T { uint[] x; }\n    function f() public returns (uint, S memory) {\n    }\n}\n// ----\n// TypeError 1534: (226-234): Type too large for memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/memory_mapping_array.sol",
    "content": " contract C {\n        function h ( bool flag ) public returns ( bool c ) {\n                mapping ( string => uint24 ) [ 1 ] memory val ;\n        }\n}\n// ----\n// TypeError 4061: (91-136): Type mapping(string => uint24)[1] memory is only valid in storage because it contains a (nested) mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/missing_functions_duplicate_bug.sol",
    "content": "pragma abicoder               v2;\n\ncontract Ownable {\n    address private _owner;\n\n    modifier onlyOwner() {\n        require(msg.sender == _owner, \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    function renounceOwnership() public onlyOwner { }\n}\n\nlibrary VoteTiming {\n    function init(uint phaseLength) internal pure {\n        require(true, \"\");\n    }\n}\n\ncontract Voting is Ownable {\n    constructor() {\n        VoteTiming.init(1);\n    }\n}\n// ----\n// Warning 5667: (299-315): Unused function parameter. Remove or comment out the variable name to silence this warning.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/oversized_var.sol",
    "content": "contract b {\n    struct c {\n        uint [2 ** 253] a;\n    }\n\n    c d;\n\n    function e() public view {\n        c storage x = d;\n        x.a[0];\n        function()[3**44] storage fs;\n    }\n}\n// ----\n// Warning 7325: (66-67): Type struct b.c covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (66-67): Type uint256[14474011154664524427946373126085988481658748083205070504932198000989141204992] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (111-112): Type struct b.c covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (111-112): Type uint256[14474011154664524427946373126085988481658748083205070504932198000989141204992] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (152-169): Type function ()[984770902183611232881] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 2072: (152-180): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/iceRegressionTests/recursive_struct_memory.sol",
    "content": "contract Test {\n        struct RecursiveStruct {\n                address payable d ;\n                mapping ( uint => address payable ) c ;\n                mapping ( uint => address payable [ ] ) d ;\n        }\n        function func ( ) private pure {\n                RecursiveStruct [ 1 ] memory val ;\n                val ;\n        }\n}\n// ----\n// DeclarationError 2333: (157-198): Identifier already declared.\n// TypeError 4061: (268-300): Type struct Test.RecursiveStruct[1] memory is only valid in storage because it contains a (nested) mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/access_via_getter.sol",
    "content": "contract Counter {\n    uint256 public immutable MIN_LIQUIDITY = 1000;\n\n    function run() view public {\n        this.MIN_LIQUIDITY();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/as_function_param.sol",
    "content": "contract C {\n    function f(uint immutable) public pure {}\n}\n// ----\n// DeclarationError 8297: (28-42): The \"immutable\" keyword can only be used for state variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/assembly.sol",
    "content": "contract C {\n    uint immutable x;\n    function f() public view {\n        uint t;\n        assembly {\n            t := x\n        }\n    }\n}\n// ----\n// TypeError 3773: (118-119): Assembly access to immutable variables is not supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/base_ctor_return_no_immutables.sol",
    "content": "contract Parent {\n    constructor() {\n        return;\n    }\n}\n\ncontract Child is Parent {\n    uint public immutable baked = 123;\n}\n\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/complex.sol",
    "content": "contract A {\n  int immutable a;\n  constructor() { a = 5; }\n  function f() public { a += 7; }\n}\n\n// ----\n// TypeError 1581: (83-84): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/conditional_return_uninitialized.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        if (false)\n            return;\n\n        x = 1;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/conditionally_initialized.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        if (false)\n            x = 1;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/creationCode.sol",
    "content": "contract A {\n    address public immutable user = address(0x0);\n}\n\ncontract Test {\n    function test() public pure returns(bytes memory) {\n        return type(A).creationCode;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/ctor_indirect_initialization.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        initX();\n    }\n\n    function initX() internal {\n        x = 3;\n    }\n}\n// ----\n// TypeError 1581: (119-120): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/ctor_initialization_indirect_reading.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        x = f();\n    }\n\n    function f() public view returns (uint) { return 3 + x; }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/ctor_initialization_reading.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        x = 3 + x;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/ctor_initialization_tuple.sol",
    "content": "contract C {\n    uint immutable x;\n    uint immutable y;\n    constructor() {\n        (x, y) = f();\n    }\n\n    function f() internal pure returns(uint _x, uint _y) {\n        _x = 3;\n        _y = 4;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/ctor_modifier_args.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() readX(x = 3) { }\n\n    modifier readX(uint _x) {\n        _; f(_x);\n    }\n\n    function f(uint a) internal pure {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/ctor_modifier_initialization.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() initX {\n    }\n\n    modifier initX() {\n        _; x = 23;\n    }\n}\n// ----\n// TypeError 1581: (102-103): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/ctor_modifier_reading.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() readX {\n        x = 3;\n    }\n\n    modifier readX() {\n        _; f(x);\n    }\n\n    function f(uint a) internal pure {}\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/decrement.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        x--;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/double_specifier.sol",
    "content": "contract C {\n    uint immutable immutable x;\n    uint immutable constant x;\n}\n// ----\n// ParserError 3109: (32-41): Mutability already set to \"immutable\"\n// ParserError 3109: (64-72): Mutability already set to \"immutable\"\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/external_function_pointer.sol",
    "content": "contract C {\n    function() external immutable f;\n}\n// ----\n// TypeError 3366: (17-48): Immutable variables of external function type are not yet supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/function_initialization.sol",
    "content": "contract C {\n    uint immutable x = f();\n\n    function f() public pure returns (uint) { return 3; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/function_initialization_reading.sol",
    "content": "contract C {\n    uint immutable x = f();\n\n    function f() public view returns (uint) { return 3 + x; }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/function_pointer_initializing.sol",
    "content": "abstract contract B {\n    uint immutable x;\n\n    constructor(function() internal returns(uint) fp) {\n        x = fp();\n    }\n}\n\ncontract C is B(C.f) {\n    function f() internal returns(uint) { return x = 2; }\n}\n// ----\n// TypeError 1581: (200-201): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/function_pointer_reading.sol",
    "content": "abstract contract B {\n    uint immutable x;\n\n    constructor(function() internal returns(uint) fp) {\n        x = fp();\n    }\n}\n\ncontract C is B(C.f) {\n    function f() internal view returns(uint) { return x + 2; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/illegal_names.sol",
    "content": "contract C {\n    uint immutable super;\n    uint immutable _;\n    uint immutable this;\n}\n// ----\n// DeclarationError 3726: (17-37): The name \"super\" is reserved.\n// DeclarationError 3726: (43-59): The name \"_\" is reserved.\n// DeclarationError 3726: (65-84): The name \"this\" is reserved.\n// Warning 2319: (17-37): This declaration shadows a builtin symbol.\n// Warning 2319: (65-84): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/immutable_basic.sol",
    "content": "contract C {\n    uint immutable x = 0;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/immutable_state_var_named_transient.sol",
    "content": "contract C {\n    address public immutable transient;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/increment.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        x++;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/indirect_reading_during_statevar_init.sol",
    "content": "contract C {\n    uint immutable x = 0;\n    uint y = f();\n\n    function f() internal pure returns(uint) { return x; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/inheritance_ctor.sol",
    "content": "contract B {\n    uint immutable x;\n\n    constructor() {\n        x = 3;\n    }\n}\n\ncontract C is B {\n    uint immutable y;\n    constructor() {\n        y = 3;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/inheritance_ctor_argument.sol",
    "content": "contract B {\n    uint immutable x;\n\n    constructor(uint _x) {\n        x = _x;\n    }\n}\n\ncontract C is B {\n    uint immutable y;\n    constructor() B(y = 3) { }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/inheritance_ctor_inherit_specifier_argument_init.sol",
    "content": "contract B {\n    uint immutable x;\n\n    constructor(uint _x) {\n        x = _x;\n    }\n}\n\ncontract C is B(C.y = 3) {\n    uint immutable y;\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/inheritance_ctor_inherit_specifier_argument_reading.sol",
    "content": "contract B {\n    uint immutable x;\n\n    constructor(uint _x) {\n        x = _x;\n    }\n}\n\ncontract C is B(C.y) {\n    uint immutable y;\n    constructor() {\n        y = 3;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/inheritance_virtual_functions.sol",
    "content": "contract B {\n    uint immutable x;\n\n    constructor() {\n        x = xInit();\n    }\n\n    function xInit() internal view virtual returns(uint) {\n        return 3;\n    }\n}\n\ncontract C is B {\n    function xInit() internal view override returns(uint) {\n        return x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/inheritance_virtual_functions_direct_call.sol",
    "content": "contract B {\n    uint immutable x = 3;\n\n    function readX() internal virtual returns(uint) {\n        return x;\n    }\n}\n\ncontract C is B {\n    constructor() {\n        B.readX;\n    }\n\n    function readX() internal pure override returns(uint) {\n        return 3;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/inheritance_virtual_functions_super.sol",
    "content": "contract B {\n    uint immutable x = 3;\n\n    function readX() internal view virtual returns(uint) {\n        return x;\n    }\n}\n\ncontract C is B {\n    constructor() {\n        super.readX();\n    }\n\n    function readX() internal pure override returns(uint) {\n        return 1;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/inheritance_virtual_modifiers.sol",
    "content": "contract B {\n    uint immutable x;\n\n    constructor() readX {\n        x = 3;\n    }\n\n    modifier readX() virtual {\n        _; f(3);\n    }\n\n    function f(uint a) internal pure {}\n}\n\ncontract C is B {\n    modifier readX() override {\n        _; f(x);\n    }\n}\n// ----\n// Warning 8429: (88-137): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/inheritance_wrong_ctor.sol",
    "content": "contract B {\n    uint immutable x = 4;\n}\n\ncontract C is B {\n    constructor() {\n        x = 3;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/init_in_constructor_modifier_param.sol",
    "content": "contract D {\n    uint immutable t;\n    modifier m(uint) { _; }\n    constructor() m(t = 2) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/init_in_ctor_param.sol",
    "content": "contract C { constructor(uint) {} }\ncontract D is C {\n  uint immutable t;\n  constructor() C(t=2) {}\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/init_in_function_modifier_param.sol",
    "content": "contract D {\n    uint immutable t;\n    modifier m(uint) { _; }\n    function f() public m(t = 2) {}\n}\n// ----\n// TypeError 1581: (89-90): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/init_in_function_via_contract_name.sol",
    "content": "contract B {\n    uint immutable x;\n}\n\ncontract C is B {\n    function f() public {\n        B.x = 42;\n    }\n}\n// ----\n// TypeError 1581: (90-93): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/init_in_function_via_super.sol",
    "content": "contract B {\n    uint immutable x;\n\n    function g() public {}\n}\n\ncontract C is B {\n    function f() public {\n        super.x = 42;\n    }\n}\n// ----\n// TypeError 9582: (118-125): Member \"x\" not found or not visible after argument-dependent lookup in type(contract super C).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/init_in_inheritance_specifier_param.sol",
    "content": "contract C { constructor(uint) {} }\ncontract D is C(D.t = 2) {\n    uint immutable t;\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/initialized_after_ctor.sol",
    "content": "contract C {\n    constructor() {\n        return;\n    }\n\n    uint immutable x = 3;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/long_name.sol",
    "content": "contract C {\n    uint immutable long___name___that___definitely___exceeds___the___thirty___two___byte___limit = 0;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/loop_initialized.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        while (true)\n            x = 1;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/multiple_inheritance_virtual_functions.sol",
    "content": "contract A {\n    function f() internal virtual returns(uint) { return 3; }\n}\n\ncontract B {\n    uint immutable x;\n\n    constructor() {\n        x = xInit();\n    }\n\n    function xInit() internal virtual returns(uint) {\n        return f();\n    }\n\n    function f() internal view virtual returns(uint) { return 3; }\n}\n\ncontract C is A, B {\n    function xInit() internal override returns(uint) {\n        return B.xInit();\n    }\n\n    function f() internal view override(A, B) returns(uint) {\n        return x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/multiple_inheritance_virtual_functions_with_super.sol",
    "content": "contract A {\n    function f() internal virtual returns(uint) { return 3; }\n}\n\ncontract B {\n    uint immutable x;\n\n    constructor() {\n        x = xInit();\n    }\n\n    function xInit() internal virtual returns(uint) {\n        return f();\n    }\n\n    function f() internal view virtual returns(uint) { return 3; }\n}\n\ncontract C is A, B {\n    function xInit() internal override returns(uint) {\n        return super.xInit();\n    }\n\n    function f() internal view override(A, B) returns(uint) {\n        return x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/multiple_initializations.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        x = 1;\n        x = 4;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/no_assignments.sol",
    "content": "// TODO: This test case should work the same way for EOF but EOF immutables support is not in its final state yet.\ncontract C {\n    uint immutable x;\n    constructor() {\n        x = 0;\n        while (true)\n        {}\n    }\n    function f() external view returns(uint) { return x; }\n}\n// ====\n// bytecodeFormat: legacy\n// optimize-yul: true\n// ----\n// CodeGenerationError 1284: (115-283): Some immutables were read from but never assigned, possibly because of optimization.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/non-value_type.sol",
    "content": "contract C {\n    uint[] immutable x;\n}\n// ----\n// TypeError 6377: (17-35): Immutable variables cannot have a non-value type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/non-value_type_struct.sol",
    "content": "contract Contract {\n    struct S {\n        int k;\n    }\n\n    S immutable s;\n}\n// ----\n// TypeError 6377: (61-74): Immutable variables cannot have a non-value type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/non-value_type_struct_with_mapping.sol",
    "content": "contract Contract {\n    struct S {\n        mapping(uint => address) map;\n    }\n\n    S immutable s;\n}\n// ----\n// TypeError 6377: (84-97): Immutable variables cannot have a non-value type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/private_state_var.sol",
    "content": "contract B {\n    uint immutable private x = f();\n\n    constructor() {\n    }\n\n    function f() internal view virtual returns(uint) { return 1; }\n    function readX() internal view returns(uint) { return x; }\n}\n\ncontract C is B {\n    uint immutable y;\n    constructor() {\n        y = 3;\n    }\n    function f() internal view override returns(uint) { return readX(); }\n\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/read_in_function_before_init.sol",
    "content": "abstract contract A {\n\tuint public t;\n\tconstructor() { t = f(); }\n\n\tfunction f() virtual pure internal returns (uint);\n}\ncontract B is A {\n\tuint immutable x = 2;\n\tfunction f() override pure internal returns (uint) { return x; }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/read_in_function_before_init2.sol",
    "content": "contract C {\n  uint immutable t = 2;\n  uint x = f();\n  function f() internal pure returns (uint) { return t; }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/reading_after_initialization.sol",
    "content": "contract C {\n    uint immutable x = 0;\n    uint y = 0;\n\n    function f() internal {\n        y = x + 1;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/reading_after_initialization_function.sol",
    "content": "contract C {\n\tuint immutable x;\n\n\tconstructor()\n\t{\n\t\treadX();\n\t\tx = 3;\n\t\treadX();\n\t}\n\n\tfunction readX() public view returns(uint) {\n\t\treturn x;\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/reading_after_initialization_modifier.sol",
    "content": "contract C {\n    uint immutable x = 0;\n    uint y = 0;\n\n    function f() readX internal {\n    }\n\n    modifier readX() {\n        _;\n        y = x + 1;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/reading_during_statevar_init.sol",
    "content": "contract C {\n    uint immutable x = 0;\n    uint y = x;\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/return_uninitialized.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        return;\n\n        x = 1;\n    }\n}\n// ----\n// Warning 5740: (80-85): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/runtimeCode.sol",
    "content": "contract A {\n    address public immutable user = address(0x0);\n}\n\ncontract Test {\n    function test() public pure returns(bytes memory) {\n        return type(A).runtimeCode;\n    }\n}\n// ----\n// TypeError 9274: (153-172): \"runtimeCode\" is not available for contracts containing immutable variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/runtimeCodeInheritance.sol",
    "content": "contract Base {\n    address public immutable user = address(0x0);\n}\n\ncontract Derived is Base {}\n\ncontract Test {\n    function test() public pure returns(bytes memory) {\n        return type(Derived).runtimeCode;\n    }\n}\n// ----\n// TypeError 9274: (185-210): \"runtimeCode\" is not available for contracts containing immutable variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/selector.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        x = 3;\n        this.readX.selector;\n    }\n\n    function readX() external view returns(uint) { return x; }\n}\n// ----\n// Warning 6133: (78-97): Statement has no effect.\n// Warning 5805: (78-82): \"this\" used in constructor. Note that external functions of a contract cannot be called while it is being constructed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/selector_function_name.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        x = 3;\n        C.selector.selector;\n        C.selector;\n    }\n\n    function selector() external view returns(uint) { return x; }\n}\n// ----\n// Warning 6133: (78-97): Statement has no effect.\n// Warning 6133: (107-117): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/selector_function_pointer.sol",
    "content": "contract C {\n    uint immutable x;\n    constructor() {\n        x = 3;\n        readX().selector;\n    }\n\n    function f() external view returns(uint)  {\n        return x;\n    }\n\n    function readX() public view returns(function() external view returns(uint) _f) {\n        _f = this.f;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/state_var_external_access_read.sol",
    "content": "contract C {\n    uint immutable public x = 42;\n\n    function g() external view returns (uint) {}\n\n    function f() public view returns (uint) {\n        return this.x();\n    }\n\n    function h() public view returns (function () external view returns (uint)) {\n        return this.x;\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/state_var_external_access_write.sol",
    "content": "contract C {\n    uint immutable public x = 42;\n\n    function g() external view returns (uint) {}\n\n    function f() public view {\n        this.x = this.g;\n    }\n}\n// ----\n// TypeError 4247: (137-143): Expression has to be an lvalue.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol",
    "content": "contract C {\n    uint public immutable transient x;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// DeclarationError 2197: (17-50): Transient cannot be used as data location for constant or immutable variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/try_catch_initialized.sol",
    "content": "contract A\n{\n    uint256 public immutable variable;\n\n    constructor()\n    {\n        B b;\n        try b.foo(variable = 1)\n        {\n            variable = 2;\n        }\n        catch Panic(uint)\n        {\n            variable = 3;\n        }\n        catch Error(string memory)\n        {\n            variable = 4;\n        }\n        catch\n        {\n            variable = 5;\n        }\n    }\n}\n\ncontract B\n{\n    function foo(uint256) external pure\n    {\n        revert();\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/unary.sol",
    "content": "contract A {\n  int immutable a;\n  constructor() { a = 5; }\n  function f() public { --a; }\n}\n\n// ----\n// TypeError 1581: (85-86): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/uninitialized.sol",
    "content": "contract C {\n    uint immutable x;\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/uninitialized_private_state_var.sol",
    "content": "contract B {\n    uint immutable private x;\n\n    constructor() {\n    }\n\n    function f() internal view virtual returns(uint) { return 1; }\n    function readX() internal view returns(uint) { return x; }\n}\n\ncontract C is B {\n    uint immutable y;\n    constructor() {\n        y = 3;\n    }\n    function f() internal view override returns(uint) { return readX(); }\n\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/unrelated_reading.sol",
    "content": "contract C {\n    uint immutable x = 1;\n\n    function readX() internal pure returns(uint) {\n        return x + 3;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/variable_declaration_already.sol",
    "content": "contract C {\n    uint immutable z = 2;\n    uint immutable x = z = y = 3;\n    uint immutable y = 5;\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/variable_declaration_value.sol",
    "content": "contract C {\n    int immutable x = x = 5;\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/writing_after_initialization.sol",
    "content": "contract C {\n    uint immutable x = 0;\n\n    function f() internal {\n        x = 1;\n    }\n}\n// ----\n// TypeError 1581: (76-77): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/immutable/writing_after_initialization_modifier.sol",
    "content": "contract C {\n    uint immutable x = 0;\n\n    function f() readX internal { }\n\n    modifier readX() {\n        _; x = 1;\n    }\n}\n// ----\n// TypeError 1581: (111-112): Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/alias_import_not_forwarded.sol",
    "content": "==== Source: dummy ====\ncontract Dummy { string public constant FOO = \"FOO\"; }\n==== Source: hasAlias ====\nimport {Dummy as AliasedDummy} from \"dummy\";\n==== Source: Main ====\nimport {AliasedDummy} from \"hasAlias\";\ncontract TestAlias is AliasedDummy {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/circular_import.sol",
    "content": "==== Source: a ====\nimport \"b\"; contract C { D d; }\n==== Source: b ====\nimport \"a\"; contract D { C c; }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/complex_import.sol",
    "content": "==== Source: a ====\ncontract A {} contract B {} contract C { struct S { uint a; } }\n==== Source: b ====\nimport \"a\" as x; import {B as b, C as c, C} from \"a\";\ncontract D is b { function f(c.S memory var1, x.C.S memory var2, C.S memory var3) internal {} }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/declaration_not_found.sol",
    "content": "==== Source: a ====\ncontract A { }\n==== Source: b ====\nimport {C} from \"a\";\ncontract B { }\n// ----\n// DeclarationError 2904: (b:0-20): Declaration \"C\" not found in \"a\" (referenced as \"a\").\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/filename_with_period.sol",
    "content": "==== Source: a/.b.sol ====\ncontract B {}\n==== Source: a/a.sol ====\nimport \".b.sol\"; contract A is B {}\n// ----\n// ParserError 6275: (a/a.sol:0-16): Source \".b.sol\" not found: File not supplied initially.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/import_access_struct.sol",
    "content": "==== Source: a ====\nstruct S { uint x; }\n==== Source: b ====\nimport \"a\" as A;\nstruct T { uint x; }\ncontract C {\n    function f() public pure {\n        T;\n        A.S;\n    }\n}\n// ----\n// Warning 6133: (b:90-91): Statement has no effect.\n// Warning 6133: (b:101-104): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/import_does_not_clutter_importee.sol",
    "content": "==== Source: a ====\ncontract C { D d; }\n==== Source: b ====\nimport \"a\"; contract D is C {}\n// ----\n// DeclarationError 7920: (a:13-14): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/import_is_transitive.sol",
    "content": "==== Source: a ====\ncontract C { }\n==== Source: b ====\nimport \"a\";\n==== Source: c ====\nimport \"b\";\ncontract D is C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/importing_free_functions.sol",
    "content": "==== Source: a ====\nfunction f(uint x) pure returns (uint) { return x * 3; }\n==== Source: b ====\nimport \"a\" as A;\nfunction g(uint x) pure returns (uint) { return A.f(x) * 3; }\n==== Source: c ====\nimport \"b\" as B;\ncontract C {\n    function f() public pure {\n        B.g(2);\n        B.A.f(3);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_match.sol",
    "content": "==== Source: A.sol ====\npragma abicoder               v2;\n\ncontract A\n{\n    struct S { uint a; }\n    S public s;\n    function f(S memory _s) public returns (S memory,S memory) { }\n}\n==== Source: B.sol ====\npragma abicoder               v2;\n\nimport \"./A.sol\";\ncontract B is A { }\n==== Source: C.sol ====\npragma abicoder               v2;\n\nimport \"./B.sol\";\ncontract C is B { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_mismatch_1.sol",
    "content": "==== Source: A.sol ====\npragma abicoder               v2;\n\ncontract A\n{\n    struct S { uint a; }\n    S public s;\n    function f(S memory _s) public returns (S memory,S memory) { }\n}\n==== Source: B.sol ====\npragma abicoder               v2;\n\nimport \"./A.sol\";\ncontract B is A { }\n==== Source: C.sol ====\npragma abicoder v1;\nimport \"./B.sol\";\ncontract C is B { }\n// ----\n// Warning 9511: (C.sol:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 6594: (C.sol:38-57): Contract \"C\" does not use ABI coder v2 but wants to inherit from a contract which uses types that require it. Use \"pragma abicoder v2;\" for the inheriting contract as well to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_mismatch_2.sol",
    "content": "==== Source: A.sol ====\npragma abicoder               v2;\n\ncontract A\n{\n    struct S { uint a; }\n    S public s;\n    function f(S memory _s) public returns (S memory,S memory) { }\n}\n==== Source: B.sol ====\npragma abicoder v1;\nimport \"./A.sol\";\ncontract B is A { }\n==== Source: C.sol ====\npragma abicoder v1;\nimport \"./B.sol\";\ncontract C is B { }\n// ----\n// Warning 9511: (B.sol:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// Warning 9511: (C.sol:0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 6594: (B.sol:38-57): Contract \"B\" does not use ABI coder v2 but wants to inherit from a contract which uses types that require it. Use \"pragma abicoder v2;\" for the inheriting contract as well to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/library_name_clash.sol",
    "content": "==== Source: a ====\nlibrary A {}\n==== Source: b ====\nlibrary A {}\n==== Source: c ====\nimport {A} from \"./a\"; import {A} from \"./b\";\n// ----\n// DeclarationError 2333: (c:31-32): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/library_name_clash_with_contract.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: b ====\nlibrary A {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/module_function_from_ternary_expression.sol",
    "content": "==== Source: A ====\nfunction f() pure returns (uint) {\n    return 42;\n}\n==== Source: B ====\nfunction f() pure returns (uint) {\n    return 24;\n}\n==== Source: C ====\nimport \"A\" as A;\nimport \"B\" as B;\n\ncontract C {\n    function f(bool b) public pure returns (uint) {\n        return (b ? A : B).f();\n    }\n}\n// ----\n// TypeError 1080: (C:116-125): True expression's type module \"A\" does not match false expression's type module \"B\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/multiple_non_existent_file_names.sol",
    "content": "import \"~~~some-long-unlikely-file-name-12\";\nimport \"~~~some-long-unlikely-file-name-456\";\nimport \"~~~some-long-unlikely-file-name-7890\";\n// This test is here to verify that the license/pragma preamble added by the test suite does not\n// affect source locations in error messages. Positions in messages below should start at 0 and\n// there should be no gaps between the ranges.\n// ----\n// ParserError 6275: (0-44): Source \"~~~some-long-unlikely-file-name-12\" not found: File not supplied initially.\n// ParserError 6275: (45-90): Source \"~~~some-long-unlikely-file-name-456\" not found: File not supplied initially.\n// ParserError 6275: (91-137): Source \"~~~some-long-unlikely-file-name-7890\" not found: File not supplied initially.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_1.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: b ====\nimport \"a\"; contract A {}\n// ----\n// DeclarationError 2333: (b:12-25): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_2.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: b ====\nimport \"a\" as A; contract A {}\n// ----\n// DeclarationError 2333: (b:17-30): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_3.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: b ====\nimport {A as b} from \"a\"; contract b {}\n// ----\n// DeclarationError 2333: (b:26-39): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_4.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: b ====\nimport {A} from \"a\"; contract A {}\n// ----\n// DeclarationError 2333: (b:21-34): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_5.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: b ====\nimport {A} from \"a\"; contract B {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_1.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: b ====\nimport \"a\";\nstruct A { uint256 a; }\n// ----\n// DeclarationError 2333: (b:12-35): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_2.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: b ====\nimport \"a\" as A;\nstruct A { uint256 a; }\n// ----\n// DeclarationError 2333: (b:17-40): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_3.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: b ====\nimport {A as b} from \"a\";\nstruct b { uint256 a; }\n// ----\n// DeclarationError 2333: (b:26-49): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_4.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: b ====\nimport {A} from \"a\";\nstruct A { uint256 a; }\n// ----\n// DeclarationError 2333: (b:21-44): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_5.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: b ====\nimport {A} from \"a\";\nstruct B { uint256 a; }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_enum.sol",
    "content": "==== Source: a ====\nenum E { A }\n==== Source: b ====\nimport \"a\";\nenum E { A }\n// ----\n// DeclarationError 2333: (b:12-24): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_enum_contract.sol",
    "content": "==== Source: a ====\nenum E { A }\n==== Source: b ====\nimport \"a\";\ncontract E { }\n// ----\n// DeclarationError 2333: (b:12-26): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_enum_struct.sol",
    "content": "==== Source: a ====\nenum E { A }\n==== Source: b ====\nimport \"a\";\nstruct E { uint256 a; }\n// ----\n// DeclarationError 2333: (b:12-35): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_1.sol",
    "content": "==== Source: a ====\nstruct A { uint256 a; }\n==== Source: b ====\nimport \"a\";\nstruct A { uint256 a; }\n// ----\n// DeclarationError 2333: (b:12-35): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_2.sol",
    "content": "==== Source: a ====\nstruct A { uint256 a; }\n==== Source: b ====\nimport \"a\" as A;\nstruct A { uint256 a; }\n// ----\n// DeclarationError 2333: (b:17-40): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_3.sol",
    "content": "==== Source: a ====\nstruct A { uint256 a; }\n==== Source: b ====\nimport {A as b} from \"a\";\nstruct b { uint256 a; }\n// ----\n// DeclarationError 2333: (b:26-49): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_4.sol",
    "content": "==== Source: a ====\nstruct A { uint256 a; }\n==== Source: b ====\nimport {A} from \"a\";\nstruct A { uint256 a; }\n// ----\n// DeclarationError 2333: (b:21-44): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_5.sol",
    "content": "==== Source: a ====\nstruct A { uint256 a; }\n==== Source: b ====\nimport {A} from \"a\";\nstruct B { uint256 a; }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_1.sol",
    "content": "==== Source: a ====\nstruct A { uint256 a; }\n==== Source: b ====\nimport \"a\";\ncontract A {}\n// ----\n// DeclarationError 2333: (b:12-25): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_2.sol",
    "content": "==== Source: a ====\nstruct A { uint256 a; }\n==== Source: b ====\nimport \"a\" as A;\ncontract A {}\n// ----\n// DeclarationError 2333: (b:17-30): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_3.sol",
    "content": "==== Source: a ====\nstruct A { uint256 a; }\n==== Source: b ====\nimport {A as b} from \"a\";\ncontract b {}\n// ----\n// DeclarationError 2333: (b:26-39): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_4.sol",
    "content": "==== Source: a ====\nstruct A { uint256 a; }\n==== Source: b ====\nimport {A} from \"a\";\ncontract A {}\n// ----\n// DeclarationError 2333: (b:21-34): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_5.sol",
    "content": "==== Source: a ====\nstruct A { uint256 a; }\n==== Source: b ====\nimport {A} from \"a\";\ncontract B {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/regular_import.sol",
    "content": "==== Source: a ====\ncontract C {}\n==== Source: b ====\nimport \"a\"; contract D is C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/relative_import.sol",
    "content": "==== Source: a ====\nimport \"./dir/b\"; contract A is B {}\n==== Source: dir/b ====\ncontract B {}\n==== Source: dir/c ====\nimport \"../a\"; contract C is A {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/relative_import_multiplex.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: dir/a/b/c ====\nimport \"../../.././a\"; contract B is A {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/shadowing_builtins_with_alias.sol",
    "content": "==== Source: B.sol ====\ncontract C {}\n==== Source: b ====\nimport {C as msg} from \"B.sol\";\n// ----\n// Warning 2319: (b:13-16): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/shadowing_builtins_with_imports.sol",
    "content": "==== Source: B.sol ====\ncontract X {}\n==== Source: b ====\nimport * as msg from \"B.sol\";\ncontract C {\n}\n// ----\n// Warning 2319: (b:0-29): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/shadowing_builtins_with_multiple_imports.sol",
    "content": "==== Source: B.sol ====\ncontract msg {} contract block{}\n==== Source: b ====\nimport {msg, block} from \"B.sol\";\ncontract C {\n}\n// ----\n// Warning 2319: (B.sol:0-15): This declaration shadows a builtin symbol.\n// Warning 2319: (B.sol:16-32): This declaration shadows a builtin symbol.\n// Warning 2319: (b:8-11): This declaration shadows a builtin symbol.\n// Warning 2319: (b:13-18): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/shadowing_via_import.sol",
    "content": "==== Source: a ====\nlibrary A {}\n==== Source: b ====\nlibrary A {}\n==== Source: c ====\nimport {A} from \"./a\"; import {A} from \"./b\";\n// ----\n// DeclarationError 2333: (c:31-32): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/simple_alias.sol",
    "content": "==== Source: a ====\ncontract A {}\n==== Source: dir/a/b/c ====\nimport \"../../.././a\" as x; contract B is x.A { fallback() external { x.A r = x.A(address(20)); r; } }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/smoke_test.sol",
    "content": "==== Source: a ====\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/imports/transitive.sol",
    "content": "==== Source: a ====\nstruct S { uint[2] mS; }\n==== Source: b ====\nimport \"a\" as A;\nstruct T { A.S[2] mT; }\n==== Source: c ====\npragma abicoder               v2;\nimport \"b\" as B;\ncontract C {\n    function f(B.T memory y, B.A.S memory z) public pure returns (uint, uint) {\n        z = B.A.S([uint(2), 3]);\n        y = B.T([z, z]);\n        return (y.mT[0].mS[0], z.mS[0]);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/array_multidim_rational.sol",
    "content": "contract C {\n  function f() public {\n    bytes[32] memory a;\n    a[8**90][8**90][8**90*0.1];\n  }\n}\n// ----\n// TypeError 7407: (67-72): Type int_const 1897...(74 digits omitted)...1424 is not implicitly convertible to expected type uint256. Literal is too large to fit in uint256.\n// TypeError 7407: (74-79): Type int_const 1897...(74 digits omitted)...1424 is not implicitly convertible to expected type uint256. Literal is too large to fit in uint256.\n// TypeError 7407: (81-90): Type rational_const 9485...(73 digits omitted)...5712 / 5 is not implicitly convertible to expected type uint256.\n// TypeError 6318: (65-91): Index expression cannot be represented as an unsigned integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/array_multim_overflow_index.sol",
    "content": "contract C {\n  function f() public {\n    bytes[32] memory a;\n    a[8**90][8**90][1 - 8**90];\n  }\n}\n// ----\n// TypeError 7407: (67-72): Type int_const 1897...(74 digits omitted)...1424 is not implicitly convertible to expected type uint256. Literal is too large to fit in uint256.\n// TypeError 7407: (74-79): Type int_const 1897...(74 digits omitted)...1424 is not implicitly convertible to expected type uint256. Literal is too large to fit in uint256.\n// TypeError 7407: (81-90): Type int_const -189...(75 digits omitted)...1423 is not implicitly convertible to expected type uint256. Cannot implicitly convert signed literal to unsigned type.\n// TypeError 6318: (65-91): Index expression cannot be represented as an unsigned integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/array_negative_index.sol",
    "content": "contract C {\n  function f() public {\n    bytes[32] memory a;\n    a[-1];\n  }\n}\n// ----\n// TypeError 7407: (67-69): Type int_const -1 is not implicitly convertible to expected type uint256. Cannot implicitly convert signed literal to unsigned type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/array_noninteger_index.sol",
    "content": "contract C {\n  function f() public {\n    bytes[32] memory a;\n    a[888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888];\n  }\n}\n// ----\n// TypeError 7407: (67-178): Type int_const 8888...(103 digits omitted)...8888 is not implicitly convertible to expected type uint256. Literal is too large to fit in uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/array_out_of_bounds_index.sol",
    "content": "contract C {\n  function f() public {\n    bytes[32] memory a;\n    a[64];\n  }\n}\n// ----\n// TypeError 3383: (65-70): Out of bounds array access.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/array_without_index.sol",
    "content": "contract C {\n  function f() public {\n    bytes memory a;\n    a[];\n  }\n}\n// ----\n// TypeError 9689: (61-64): Index expression cannot be omitted.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/error_type_without_index.sol",
    "content": "interface MyInterface {\n    error MyCustomError(uint256, bool);\n}\n\ncontract MyContract {\n    function test() public {\n        MyInterface.MyCustomError[];\n    }\n}\n// ----\n// TypeError 2614: (126-151): Indexed expression has to be a type, mapping or array (is error MyCustomError(uint256,bool))\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/event_type_without_index.sol",
    "content": "contract MyContract {\n    event MyCustomEvent(uint256);\n    function test() public {\n        MyCustomEvent[];\n    }\n}\n// ----\n// TypeError 2614: (93-106): Indexed expression has to be a type, mapping or array (is event MyCustomEvent(uint256))\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/fixedbytes_negative_index.sol",
    "content": "contract C {\n  function f() public {\n    bytes32 b;\n    b[-1];\n  }\n}\n// ----\n// TypeError 7407: (58-60): Type int_const -1 is not implicitly convertible to expected type uint256. Cannot implicitly convert signed literal to unsigned type.\n// TypeError 6318: (56-61): Index expression cannot be represented as an unsigned integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/fixedbytes_noninteger_index.sol",
    "content": "contract C {\n  function f() public {\n    bytes32 b;\n    b[888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888];\n  }\n}\n// ----\n// TypeError 7407: (58-169): Type int_const 8888...(103 digits omitted)...8888 is not implicitly convertible to expected type uint256. Literal is too large to fit in uint256.\n// TypeError 6318: (56-170): Index expression cannot be represented as an unsigned integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/fixedbytes_out_of_bounds_index.sol",
    "content": "contract C {\n  function f() public {\n    bytes32 b;\n    b[64];\n  }\n}\n// ----\n// TypeError 1859: (56-61): Out of bounds array access.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/fixedbytes_without_index.sol",
    "content": "contract C {\n  function f() public {\n    bytes32 b;\n    b[];\n  }\n}\n// ----\n// TypeError 8830: (56-59): Index expression cannot be omitted.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/function_type.sol",
    "content": "contract C {\n  function f() public {\n    f[0];\n  }\n}\n// ----\n// TypeError 2614: (41-42): Indexed expression has to be a type, mapping or array (is function ())\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/function_type_without_index.sol",
    "content": "contract C {\n  function f() public {\n    f[];\n  }\n}\n// ----\n// TypeError 2614: (41-42): Indexed expression has to be a type, mapping or array (is function ())\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/index_range_access_assert.sol",
    "content": "// Used to trigger assert\ncontract s{}\nfunction f() {s[:][];}\n// ----\n// TypeError 1760: (53-57): Types cannot be sliced.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/indexing/struct_array_noninteger_index.sol",
    "content": "contract test {\n    struct s { uint a; uint b;}\n    function f() pure public returns (bytes1) {\n        s[75555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555];\n        s[7];\n    }\n}\n\n// ----\n// TypeError 7407: (106-246): Type int_const 7555...(132 digits omitted)...5555 is not implicitly convertible to expected type uint256. Literal is too large to fit in uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/allow_empty_duplicated_super_constructor_call.sol",
    "content": "contract A { constructor() { } }\ncontract B is A { constructor() A() {  } }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses.sol",
    "content": "contract Base {\n  constructor(uint) {}\n}\ncontract Derived is Base(2) { }\ncontract Derived2 is Base(), Derived() { }\n// ----\n// TypeError 7927: (94-100): Wrong argument count for constructor call: 0 arguments given but expected 1. Remove parentheses if you do not want to provide arguments here.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/base_arguments_multiple_inheritance.sol",
    "content": "contract Base {\n    constructor(uint) { }\n}\ncontract Base1 is Base(3) {}\ncontract Derived is Base, Base1 {\n    constructor(uint i) Base(i) {}\n}\n// ----\n// DeclarationError 3364: (131-138): Base constructor arguments given twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/base_arguments_no_parentheses.sol",
    "content": "contract Base {\n  constructor(uint) {}\n}\ncontract Derived is Base(2) { }\ncontract Derived2 is Base, Derived {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/base_not_contract.sol",
    "content": "function fun() {}\n\ncontract C is fun {}\n// ----\n// TypeError 8758: (33-36): Contract expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/dataLocation/external_overriding_external.sol",
    "content": "abstract contract A {\n    function f(uint256[1] memory a) external virtual returns (uint256);\n}\ncontract B is A {\n    function f(uint256[1] calldata a) external pure virtual override returns (uint256) {\n        return a[0];\n    }\n}\ncontract C is A, B {\n    function f(uint256[1] memory a) external pure override(B, A) returns (uint256) {\n        return a[0];\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/dataLocation/modifier_parameter_data_location_change_illegal_internal.sol",
    "content": "abstract contract A {\n    modifier m(uint256[1] memory a) virtual;\n    function test(uint256[1] memory a) m(a) external {\n    }\n}\n\ncontract B is A {\n    modifier m(uint256[1] calldata a) override {\n        _;\n    }\n}\n// ----\n// Warning 8429: (26-66): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 1078: (153-214): Override changes modifier signature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/dataLocation/parameter_data_location_change_calldata_memory_illegal_public.sol",
    "content": "abstract contract A {\n    function f(uint256[1] calldata a) public virtual returns (uint256);\n}\n\ncontract B is A {\n    function f(uint256[1] memory a) public override returns (uint256) {\n        return a[0];\n    }\n}\n// ----\n// TypeError 7723: (119-213): Data locations of parameters have to be the same when overriding non-external functions, but they differ.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/dataLocation/parameter_data_location_change_illegal_internal.sol",
    "content": "abstract contract A {\n    function f(uint256[1] memory a) internal virtual returns (uint256);\n    function test() external returns (uint) {\n        uint[1] memory t;\n        t[0] = 7;\n        return f(t);\n    }\n}\n\ncontract B is A {\n    function f(uint256[1] calldata a) internal override returns (uint256) {\n        return a[0];\n    }\n}\n// ----\n// TypeError 7723: (236-334): Data locations of parameters have to be the same when overriding non-external functions, but they differ.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/dataLocation/parameter_data_location_change_illegal_public.sol",
    "content": "abstract contract A {\n    function f(uint256[1] memory a) public virtual returns (uint256);\n    function test() external returns (uint) {\n        uint[1] memory t;\n        t[0] = 7;\n        return f(t);\n    }\n}\n\ncontract B is A {\n    function f(uint256[1] calldata a) public override returns (uint256) {\n        return a[0];\n    }\n}\n// ----\n// TypeError 7723: (234-330): Data locations of parameters have to be the same when overriding non-external functions, but they differ.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/dataLocation/return_type_data_location.sol",
    "content": "abstract contract A {\n\tfunction foo() external virtual view returns(uint[] calldata);\n}\ncontract X is A {\n\tfunction foo() public view override returns(uint[] memory) {  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/dataLocation/return_type_data_location_change_illegal.sol",
    "content": "abstract contract A {\n\tfunction foo() public virtual view returns(uint[] calldata);\n}\ncontract X is A {\n\tfunction foo() public view override returns(uint[] memory) {  }\n}\n// ----\n// TypeError 1443: (105-168): Data locations of return variables have to be the same when overriding non-external functions, but they differ.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/disallow_modifier_style_without_parentheses.sol",
    "content": "contract A { constructor() { } }\ncontract B is A { constructor() A {  } }\n// ----\n// DeclarationError 1563: (65-66): Modifier-style base constructor call without arguments.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/ancestor.sol",
    "content": "contract A { constructor(uint) { } }\ncontract B is A(2) { constructor() {  } }\ncontract C is B { constructor() A(3) {  } }\n// ----\n// DeclarationError 3364: (111-115): Base constructor arguments given twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base.sol",
    "content": "contract A { constructor(uint) { } }\ncontract B is A(2) { constructor() A(3) {  } }\n// ----\n// DeclarationError 3364: (72-76): Base constructor arguments given twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base_multi.sol",
    "content": "contract C { constructor(uint) {} }\ncontract A is C(2) {}\ncontract B is C(2) {}\ncontract D is A, B { constructor() C(3) {} }\n// ----\n// DeclarationError 3364: (115-119): Base constructor arguments given twice.\n// DeclarationError 3364: (115-119): Base constructor arguments given twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base_multi_no_constructor.sol",
    "content": "contract C { constructor(uint) {} }\ncontract A is C(2) {}\ncontract B is C(2) {}\ncontract D is A, B {}\n// ----\n// DeclarationError 3364: (80-101): Base constructor arguments given twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/duplicatedConstructorCall/base_multi_no_constructor_modifier_style.sol",
    "content": "contract C { constructor(uint) {} }\ncontract A is C { constructor() C(2) {} }\ncontract B is C { constructor() C(2) {} }\ncontract D is A, B { }\n// ----\n// DeclarationError 3364: (120-142): Base constructor arguments given twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/duplicated_inheritance_definition.sol",
    "content": "contract A {}\ncontract B {}\ncontract C is A, B is B{ }\n// ----\n// ParserError 6668: (47-49): More than one inheritance list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_overrides_receive.sol",
    "content": "contract C {\n\treceive() external payable {}\n}\ncontract D is C {\n\tfallback() override external {}\n}\n// ----\n// TypeError 7792: (76-84): Function has override specified but does not override anything.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_with_override.sol",
    "content": "contract C {\n\tfallback() virtual external {}\n}\ncontract D is C {\n\tfallback() override external {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_with_override_intermediate.sol",
    "content": "contract C {\n\tfallback() virtual external {}\n}\ncontract D is C {\n}\ncontract E is D {\n\tfallback() override external {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_without_override.sol",
    "content": "contract C {\n\tfallback() virtual external {}\n}\ncontract D is C {\n\tfallback() external {}\n}\n// ----\n// TypeError 9456: (66-88): Overriding function is missing \"override\" specifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/fallback_without_override_intermediate.sol",
    "content": "contract C {\n\tfallback() virtual external {}\n}\ncontract D is C {\n}\ncontract E is D {\n\tfallback() external {}\n}\n// ----\n// TypeError 9456: (86-108): Overriding function is missing \"override\" specifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_overrides_fallback.sol",
    "content": "contract C {\n\tfallback() external {}\n}\ncontract D is C {\n\treceive() override external payable {}\n}\n// ----\n// TypeError 7792: (68-76): Function has override specified but does not override anything.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_parameter.sol",
    "content": "contract C {\n    receive(bytes2) {}\n}\ncontract D is C {\n    receive() {}\n}\n// ----\n// SyntaxError 4937: (17-35): No visibility specified. Did you intend to add \"external\"?\n// SyntaxError 4937: (60-72): No visibility specified. Did you intend to add \"external\"?\n// DeclarationError 7793: (17-35): Receive ether function must be payable, but is \"nonpayable\".\n// DeclarationError 4095: (17-35): Receive ether function must be defined as \"external\".\n// DeclarationError 6857: (24-32): Receive ether function cannot take parameters.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_return_parameter.sol",
    "content": "contract C {\n    receive() external payable virtual returns(uint) {}\n}\ncontract D is C {\n    receive() external payable override {}\n}\n// ----\n// DeclarationError 6899: (59-65): Receive ether function cannot return values.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_unimplemented.sol",
    "content": "interface I {\n    receive(bytes2) external payable;\n}\n\ninterface J is I {\n    receive() external payable override;\n}\n\ncontract C is J {\n    receive() external payable override {}\n}\n// ----\n// DeclarationError 6857: (25-33): Receive ether function cannot take parameters.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_with_override.sol",
    "content": "contract C {\n\treceive() virtual external payable {}\n}\ncontract D is C {\n\treceive() override external payable {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_with_override_intermediate.sol",
    "content": "contract C {\n\treceive() virtual external payable {}\n}\ncontract D is C {\n}\ncontract E is D {\n\treceive() override external payable {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_without_override.sol",
    "content": "contract C {\n\treceive() virtual external payable {}\n}\ncontract D is C {\n\treceive() external payable {}\n}\n// ----\n// TypeError 9456: (73-102): Overriding function is missing \"override\" specifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/fallbackReceive/receive_without_override_intermediate.sol",
    "content": "contract C {\n\treceive() virtual external payable {}\n}\ncontract D is C {\n}\ncontract E is D {\n\treceive() external payable {}\n}\n// ----\n// TypeError 9456: (93-122): Overriding function is missing \"override\" specifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/contract_base.sol",
    "content": "contract C {}\ninterface I is C {}\n\n// ----\n// TypeError 6536: (29-30): Interfaces can only inherit from other interfaces.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/diamond/diamond_no_relist.sol",
    "content": "interface Parent {\n    function test() external pure returns (uint256);\n}\n\ninterface SubA is Parent {}\ninterface SubB is Parent {}\n\ncontract C is SubA, SubB {\n    function test() external override pure returns (uint256) { return 42; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/diamond/diamond_with_relist.sol",
    "content": "interface Parent {\n    function test() external pure returns (uint256);\n}\n\ninterface SubA is Parent {\n    function test() external pure override returns (uint256);\n}\n\ninterface SubB is Parent {\n    function test() external pure override returns (uint256);\n}\n\ncontract C is SubA, SubB {\n    function test() external pure override(SubA, SubB) returns (uint256) { return 42; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/implementation/complete.sol",
    "content": "interface ParentA {\n    function testA() external pure returns (uint256);\n}\n\ninterface ParentB {\n    function testB() external pure returns (uint256);\n}\n\ninterface Sub is ParentA, ParentB {\n    function testSub() external pure returns (uint256);\n}\n\ncontract SubImpl is Sub {\n    function testA() external pure override returns (uint256) { return 12; }\n    function testB() external pure override(ParentB) returns (uint256) { return 42; }\n    function testSub() external pure override returns (uint256) { return 99; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/implementation/partial.sol",
    "content": "interface ParentA {\n    function testA() external returns (uint256);\n}\n\ninterface ParentB {\n    function testB() external returns (uint256);\n}\n\ninterface Sub is ParentA, ParentB {\n    function testSub() external returns (uint256);\n}\n\ncontract SubImpl is Sub {\n    function testA() external override returns (uint256) { return 12; }\n    function testSub() external override returns (uint256) { return 99; }\n}\n\n// ----\n// TypeError 3656: (234-407): Contract \"SubImpl\" should be marked as abstract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/linearization/invalid/lists_a.sol",
    "content": "interface ParentA {}\ninterface ParentB {}\ninterface Sub is ParentA, ParentB {}\n\ncontract ListsA is Sub, ParentA {}\n\n// ----\n// TypeError 5005: (80-114): Linearization of inheritance graph impossible\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/linearization/invalid/lists_b.sol",
    "content": "interface ParentA {}\ninterface ParentB {}\ninterface Sub is ParentA, ParentB {}\n\ncontract ListsB is Sub, ParentB {}\n\n// ----\n// TypeError 5005: (80-114): Linearization of inheritance graph impossible\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/linearization/invalid/lists_both.sol",
    "content": "interface ParentA {}\ninterface ParentB {}\ninterface Sub is ParentA, ParentB {}\n\ncontract ListsBoth is Sub, ParentA, ParentB {}\n\n// ----\n// TypeError 5005: (80-126): Linearization of inheritance graph impossible\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/linearization/valid.sol",
    "content": "interface ParentA {}\ninterface ParentB {}\ninterface Sub is ParentA, ParentB {}\n\ncontract ListsA is ParentA, Sub {}\ncontract ListsB is ParentB, Sub {}\ncontract ListsBoth is ParentA, ParentB, Sub {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/multiple_parents.sol",
    "content": "interface SuperA {\n    function test() external returns (uint256);\n    function testA() external returns (int128);\n}\n\ninterface SuperB {\n    function test() external returns (uint256);\n    function testB() external returns (int256);\n}\n\ninterface Sub is SuperA, SuperB {\n}\n\n// ----\n// TypeError 6480: (236-271): Derived contract must override function \"test\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/overrides_multiple.sol",
    "content": "interface SuperA {\n    function test1() external returns (uint256);\n    function test2() external returns (uint256);\n    function test3() external returns (uint256);\n    function test4() external returns (uint256);\n    function test5() external returns (uint256);\n}\n\ninterface SuperB {\n    function test1() external returns (uint256);\n    function test2() external returns (uint256);\n    function test3() external returns (uint256);\n    function test4() external returns (uint256);\n    function test5() external returns (uint256);\n}\n\ninterface Sub is SuperA, SuperB {\n    function test1() external returns (uint256);\n    function test2() external override returns (uint256);\n    function test3() external override(SuperA) returns (uint256);\n    function test4() external override(SuperB) returns (uint256);\n    function test5() external override(SuperA, SuperB) returns (uint256);\n}\n\n// ----\n// TypeError 4327: (572-616): Function needs to specify overridden contracts \"SuperA\" and \"SuperB\".\n// TypeError 4327: (647-655): Function needs to specify overridden contracts \"SuperA\" and \"SuperB\".\n// TypeError 4327: (705-721): Function needs to specify overridden contract \"SuperB\".\n// TypeError 4327: (771-787): Function needs to specify overridden contract \"SuperA\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/overrides_single.sol",
    "content": "interface Super {\n    function test1() external returns (uint256);\n    function test2() external returns (uint256);\n    function test3() external returns (uint256);\n}\n\ninterface Sub is Super {\n    function test1() external returns (uint256);\n    function test2() external override returns (uint256);\n    function test3() external override(Super) returns (uint256);\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface/single_parent.sol",
    "content": "interface Super {\n    function test() external returns (uint256);\n}\n\ninterface Sub is Super {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/interface_virtual_warning.sol",
    "content": "interface I {\n\tfunction foo() virtual external;\n}\n// ----\n// Warning 5815: (15-47): Interface functions are implicitly \"virtual\"\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/modifiers_in_constructor_context.sol",
    "content": "// This generated an invalid warning on m1 in some compiler versions.\ncontract A {\n  constructor() m1 { }\n  modifier m1 { _; }\n}\ncontract B is A {\n  modifier m2 { _; }\n  constructor() A() m1 m2 {  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/add_view.sol",
    "content": "contract B { function f() virtual public {} }\ncontract C is B { function f() override public view {} }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/ambiguous_base_and_unique_implementation.sol",
    "content": "interface I {\n    function f() external;\n    function g() external;\n}\ninterface J {\n\tfunction f() external;\n}\nabstract contract A is I, J {\n    function f() external override (I, J) {}\n    function g() external override virtual;\n}\nabstract contract B is I {\n    function f() external override virtual;\n    function g() external override {}\n}\ncontract C is A, B {\n}\n// ----\n// TypeError 6480: (342-364): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types.\n// TypeError 6480: (342-364): Derived contract must override function \"g\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/ambiguous_base_and_unique_mention.sol",
    "content": "interface I {\n    function f() external;\n    function g() external;\n}\ninterface J {\n\tfunction f() external;\n}\nabstract contract A is I, J {\n    function f() external override (I, J) {}\n}\nabstract contract B is I {\n    function g() external override {}\n}\ncontract C is A, B {\n}\n// ----\n// TypeError 6480: (254-276): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/ambiguous_base_functions_overridden_in_intermediate_base.sol",
    "content": "contract A {\n\tfunction f() external virtual {}\n}\ncontract B {\n\tfunction f() external virtual {}\n}\ncontract C is A, B {\n\tfunction f() external override (A, B) {}\n}\ncontract X is C {\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/ambiguous_base_functions_overridden_in_intermediate_base_unimplemented.sol",
    "content": "contract A {\n\tfunction f() external virtual {}\n}\ncontract B {\n\tfunction f() external virtual {}\n}\ncontract C is A, B {\n\tfunction f() external override (A, B);\n}\ncontract X is C {\n}\n// ----\n// TypeError 4593: (120-158): Overriding an implemented function with an unimplemented function is not allowed.\n// TypeError 4593: (120-158): Overriding an implemented function with an unimplemented function is not allowed.\n// TypeError 5424: (120-158): Functions without implementation must be marked virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/calldata_memory.sol",
    "content": "contract A {\n    uint dummy;\n    function f(uint[] calldata) external virtual pure {}\n    function g(uint[] calldata) external virtual view { dummy; }\n    function h(uint[] calldata) external virtual { dummy = 42; }\n    function i(uint[] calldata) external virtual payable {}\n}\ncontract B is A {\n    function f(uint[] memory) public override pure {}\n    function g(uint[] memory) public override view { dummy; }\n    function h(uint[] memory) public override { dummy = 42; }\n    function i(uint[] memory) public override payable {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/calldata_memory_conflict.sol",
    "content": "contract A {\n    uint dummy;\n    function f(uint[] calldata) external virtual pure {}\n    function g(uint[] calldata) external virtual view { dummy; }\n    function h(uint[] calldata) external virtual { dummy = 42; }\n    function i(uint[] calldata) external virtual payable {}\n}\ncontract B is A {\n    function f(uint[] calldata) external override pure {}\n    function g(uint[] calldata) external override view { dummy; }\n    function h(uint[] calldata) external override { dummy = 42; }\n    function i(uint[] calldata) external override payable {}\n    function f(uint[] memory) public override pure {}\n    function g(uint[] memory) public override view { dummy; }\n    function h(uint[] memory) public override { dummy = 42; }\n    function i(uint[] memory) public override payable {}\n}\n// ----\n// DeclarationError 1686: (300-353): Function with same name and parameter types defined twice.\n// DeclarationError 1686: (358-419): Function with same name and parameter types defined twice.\n// DeclarationError 1686: (424-485): Function with same name and parameter types defined twice.\n// DeclarationError 1686: (490-546): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/calldata_memory_interface.sol",
    "content": "interface I {\n    function f(uint[] calldata) external pure;\n    function g(uint[] calldata) external view;\n    function h(uint[] calldata) external;\n    function i(uint[] calldata) external payable;\n}\ncontract C is I {\n    uint dummy;\n    function f(uint[] memory) public pure {}\n    function g(uint[] memory) public view { dummy; }\n    function h(uint[] memory) public { dummy = 42; }\n    function i(uint[] memory) public payable {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/calldata_memory_interface_instantiate.sol",
    "content": "interface I {\n    function f(uint[] calldata) external pure;\n}\ncontract A is I {\n    function f(uint[] memory) public pure {}\n}\ncontract C {\n    function f() public {\n        I i = I(new A());\n        i.f(new uint[](1));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/calldata_memory_interface_struct.sol",
    "content": "pragma abicoder               v2;\ninterface I {\n    struct S { int a; }\n    function f(S calldata) external pure;\n    function g(S calldata) external view;\n    function h(S calldata) external;\n    function i(S calldata) external payable;\n}\ncontract C is I {\n    uint dummy;\n    function f(S memory) public override pure {}\n    function g(S memory) public view { dummy; }\n    function h(S memory) public override { dummy = 42; }\n    function i(S memory) public payable {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/calldata_memory_struct.sol",
    "content": "pragma abicoder               v2;\ncontract A {\n    uint dummy;\n    struct S { int a; }\n    function f(S calldata) external virtual pure {}\n    function g(S calldata) external virtual view { dummy; }\n    function h(S calldata) external virtual { dummy = 42; }\n    function i(S calldata) external virtual payable {}\n}\ncontract B is A {\n    function f(S memory) public override pure {}\n    function g(S memory) public override view { dummy; }\n    function h(S memory) public override { dummy = 42; }\n    function i(S memory) public override payable {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/change_return_types_in_interface.sol",
    "content": "interface I {\n  function f() external pure returns (uint);\n}\ncontract B is I {\n  // The compiler used to have a bug where changing\n  // the return type was fine in this situation.\n  function f() public pure returns (uint, uint) {}\n}\n// ----\n// TypeError 4822: (182-230): Overriding function return types differ.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/common_base_and_unique_implementation.sol",
    "content": "interface I {\n    function f() external;\n    function g() external;\n}\nabstract contract A is I {\n    function f() external {}\n    function g() external virtual;\n}\nabstract contract B is I {\n    function g() external {}\n    function f() external virtual;\n}\ncontract C is A, B {\n}\n// ----\n// TypeError 6480: (256-278): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types.\n// TypeError 6480: (256-278): Derived contract must override function \"g\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/common_base_and_unique_mention.sol",
    "content": "interface I {\n    function f() external;\n    function g() external;\n}\nabstract contract A is I {\n    function f() external {}\n}\nabstract contract B is I {\n    function g() external {}\n}\ncontract C is A, B {\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/correct_choice_for_base_function.sol",
    "content": "interface IBase {\n    function foo() external view;\n}\n\ncontract Base is IBase {\n    function foo() public virtual view {}\n}\n\ninterface IExt is IBase {}\n\ncontract Ext is IExt, Base {}\n\ncontract T { function foo() public virtual view {} }\n\ncontract Impl is Ext, T {\n    function foo() public view override(IBase, Base, T) {}\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/correct_choice_for_base_function_abstract_contract.sol",
    "content": "abstract contract IBase {\n    function foo() external view virtual;\n}\n\ncontract Base is IBase {\n    function foo() public virtual override view {}\n}\n\nabstract contract IExt is IBase {}\n\ncontract Ext is IExt, Base {}\n\ncontract T { function foo() public virtual view {} }\n\ncontract Impl is Ext, T {\n    function foo() public view override(IBase, Base, T) {}\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/detect_double_override.sol",
    "content": "contract X {\n\tint public override override testvar;\n\tfunction test() internal override override returns (uint256);\n}\n// ----\n// ParserError 9125: (34-42): Override already specified.\n// ParserError 1827: (87-95): Override already specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/diamond_interface_empty_intermediate_public_state_variable_and_function.sol",
    "content": "interface I {\n}\ncontract A is I\n{\n\tuint public f;\n}\nabstract contract B is I\n{\n\tfunction f() external virtual returns (uint);\n}\nabstract contract C is A, B {}\n// ----\n// TypeError 6480: (128-158): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/diamond_interface_intermediate_public_state_variable.sol",
    "content": "interface I {\n\tfunction f() external returns (uint);\n}\nabstract contract A is I\n{\n\tuint public f;\n}\nabstract contract B is I\n{\n}\n// This is fine because `f` is not implemented in `I` and `A.f` is the only mention below `I`.\nabstract contract C is A, B {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/diamond_interface_intermediate_public_state_variable_and_function.sol",
    "content": "interface I {\n\tfunction f() external returns (uint);\n}\ncontract A is I\n{\n\tuint public f;\n}\nabstract contract B is I\n{\n\tfunction f() external virtual returns (uint);\n}\nabstract contract C is A, B {}\n// ----\n// TypeError 6480: (167-197): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/diamond_interface_intermediate_public_state_variable_and_function_implemented.sol",
    "content": "interface I {\n\tfunction f() external returns (uint);\n}\ncontract A is I\n{\n\tuint public f;\n}\nabstract contract B is I\n{\n\tfunction f() external virtual returns (uint) { return 2; }\n}\nabstract contract C is A, B {}\n// ----\n// TypeError 6480: (180-210): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/diamond_top_implemented_intermediate_empty_bottom_public_state_variable.sol",
    "content": "contract I {\n\tfunction f() external view virtual returns (uint) { return 1; }\n}\ncontract A is I\n{\n}\ncontract B is I\n{\n}\ncontract C is A, B\n{\n\tuint public override f;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/diamond_top_implemented_intermediate_implemented_public_state_variable.sol",
    "content": "contract I {\n\tfunction f() external view virtual returns (uint) { return 1; }\n}\ncontract A is I\n{\n\tuint public override f;\n}\ncontract B is I\n{\n\tfunction f() external pure virtual override returns (uint) { return 2; }\n}\ncontract C is A, B {}\n// ----\n// TypeError 6480: (219-240): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/diamond_top_implemented_intermediate_public_state_variable.sol",
    "content": "contract I {\n\tfunction f() external view virtual returns (uint) { return 1; }\n}\ncontract A is I\n{\n\tuint public override f;\n}\ncontract B is I\n{\n}\ncontract C is A, B {}\n// ----\n// TypeError 6480: (145-166): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/external_turns_public_no_params.sol",
    "content": "contract A {\n    function f() external virtual pure {}\n}\ncontract B is A {\n    function f() public override pure {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/function_pointer.sol",
    "content": "contract C {\n\tfunction() external virtual fp;\n\tfunction() external override fp2;\n\tfunction() external override virtual fp3;\n}\n// ----\n// ParserError 2314: (34-41): Expected identifier but got 'virtual'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/function_state_variable.sol",
    "content": "interface ERC20 { function x() external returns (uint); }\ncontract C is ERC20 { uint public x; }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/implement_interface_by_public_variable.sol",
    "content": "interface X { function test() external returns (uint256); }\ncontract Y is X {\n    uint256 public test = 42;\n}\ncontract T {\n    constructor() { new Y(); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/implement_internal_function_by_public_variable.sol",
    "content": "abstract contract X { function test() internal virtual returns (uint256); }\ncontract Y is X {\n    uint256 public override test = 42;\n}\ncontract T {\n    constructor() { new Y(); }\n}\n// ----\n// TypeError 5225: (98-131): Public state variables can only override functions with external visibility.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/implement_private_function_by_public_variable.sol",
    "content": "abstract contract X { function test() private virtual returns (uint256); }\ncontract Y is X {\n    uint256 public override test = 42;\n}\ncontract T {\n    constructor() { new Y(); }\n}\n// ----\n// TypeError 5225: (97-130): Public state variables can only override functions with external visibility.\n// TypeError 3942: (22-72): \"virtual\" and \"private\" cannot be used together.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/implement_public_function_by_public_variable.sol",
    "content": "abstract contract X { function test() external virtual returns (uint256); }\ncontract Y is X {\n    uint256 public override test = 42;\n}\ncontract T {\n    constructor() { new Y(); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/interfaceException/abstract_needed.sol",
    "content": "abstract contract I {\n\tfunction f() external virtual;\n}\ncontract C is I {\n\tfunction f() external {}\n}\n// ----\n// TypeError 9456: (75-99): Overriding function is missing \"override\" specifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/interfaceException/diamond_needed.sol",
    "content": "interface I {\n\tfunction f() external;\n\tfunction g() external;\n\tfunction h() external;\n}\ninterface J {\n\tfunction f() external;\n\tfunction g() external;\n\tfunction h() external;\n}\ncontract C is I, J {\n\tfunction f() external {}\n\tfunction g() external override {}\n\tfunction h() external override(I) {}\n}\n// ----\n// TypeError 4327: (198-222): Function needs to specify overridden contracts \"I\" and \"J\".\n// TypeError 4327: (246-254): Function needs to specify overridden contracts \"I\" and \"J\".\n// TypeError 4327: (281-292): Function needs to specify overridden contract \"J\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/interfaceException/regular_optional.sol",
    "content": "interface I {\n\tfunction f() external;\n\tfunction g() external;\n\tfunction h() external;\n}\ncontract C is I {\n\tfunction f() external {}\n\tfunction g() external override {}\n\tfunction h() external override(I) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/interface_and_base_override_err.sol",
    "content": "interface IBase {\n    function foo() external view;\n}\n\ncontract Base is IBase {\n    function foo() public virtual view {}\n}\n\ninterface IExt is IBase {}\n\ncontract Ext is IExt, Base {}\n\ncontract Impl is Ext {\n    function foo() public view {}\n}\n// ----\n// TypeError 9456: (211-240): Overriding function is missing \"override\" specifier.\n// TypeError 4327: (211-240): Function needs to specify overridden contracts \"Base\" and \"IBase\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/interface_and_base_override_fine.sol",
    "content": "interface IBase {\n    function foo() external view;\n}\n\ncontract Base is IBase {\n    function foo() public virtual view {}\n}\n\ninterface IExt is IBase {}\n\ncontract Ext is IExt, Base {}\n\ncontract Impl is Ext {\n    function foo() public view override (IBase, Base) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/internal_external.sol",
    "content": "contract A {\n    function f(uint[] calldata) external pure {}\n    function f(uint[] memory) internal pure {}\n}\n// ----\n// DeclarationError 1686: (17-61): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/internal_external_inheritance.sol",
    "content": "contract A {\n    function f(uint[] calldata) external pure {}\n}\ncontract B {\n    function f(uint[] memory) internal pure {}\n}\ncontract C is A, B {}\n// ----\n// TypeError 6480: (126-147): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/modifier_ambiguous.sol",
    "content": "contract A {\n    modifier f() virtual { _; }\n}\ncontract B {\n    modifier f() virtual { _; }\n}\ncontract C is A, B {\n    modifier f() override(A,B) { _; }\n}\n// ----\n// Warning 8429: (17-44): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (64-91): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/modifier_ambiguous_fail.sol",
    "content": "contract A {\n    modifier f() virtual { _; }\n}\ncontract B {\n    modifier f() virtual { _; }\n}\ncontract C is A, B {\n}\n// ----\n// Warning 8429: (17-44): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (64-91): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 6480: (94-116): Derived contract must override modifier \"f\". Two or more base classes define modifier with same name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/modifier_inherited_different_signature.sol",
    "content": "contract A {\n    modifier f(uint a) virtual { _; }\n}\ncontract B {\n    modifier f() virtual { _; }\n}\ncontract C is A, B {\n}\n// ----\n// Warning 8429: (17-50): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (70-97): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 6480: (100-122): Derived contract must override modifier \"f\". Two or more base classes define modifier with same name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/modifier_inherited_different_signature_override.sol",
    "content": "contract A {\n    modifier f(uint a) virtual { _; }\n}\ncontract B {\n    modifier f() virtual { _; }\n}\ncontract C is A, B {\n    modifier f() virtual override(A, B) { _; }\n}\n// ----\n// Warning 8429: (17-50): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (70-97): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (125-167): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 1078: (125-167): Override changes modifier signature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/no_common_base_and_unique_implementation.sol",
    "content": "abstract contract A {\n    function f() external {}\n    function g() external virtual;\n}\nabstract contract B {\n    function g() external {}\n    function f() external virtual;\n}\ncontract C is A, B {\n}\n// ----\n// TypeError 6480: (176-198): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types.\n// TypeError 6480: (176-198): Derived contract must override function \"g\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/no_matching_resolution.sol",
    "content": "contract A {\n    function f() virtual internal {}\n}\ncontract B is A {\n    function f() virtual override internal {}\n    function h() pure internal { f; }\n}\ncontract C is B {\n    function f() override internal {}\n    function i() pure internal { f; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/nonintermediate_common_base_and_unique_implementation.sol",
    "content": "interface I {\n\tfunction f() external;\n\tfunction g() external;\n}\ninterface J {\n\tfunction f() external;\n}\nabstract contract IJ is I, J {\n\tfunction f() external virtual override (I, J);\n}\nabstract contract A is IJ\n{\n\tfunction f() external override {}\n}\nabstract contract B is IJ\n{\n\tfunction g() external override {}\n}\ncontract C is A, B {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/nonintermediate_common_base_and_unique_implementation_modifier.sol",
    "content": "contract I {\n\tmodifier f() virtual { _; }\n}\ncontract J {\n\tmodifier f() virtual { _; }\n}\ncontract IJ is I, J {\n\tmodifier f() virtual override (I, J) { _; }\n}\ncontract A is IJ\n{\n\tmodifier f() override { _; }\n}\ncontract B is IJ\n{\n}\ncontract C is A, B {}\n// ----\n// Warning 8429: (14-41): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (58-85): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (111-154): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 6480: (229-250): Derived contract must override modifier \"f\". Two or more base classes define modifier with same name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/nonintermediate_common_base_and_unique_implementation_unimplemented.sol",
    "content": "interface I {\n\tfunction f() external;\n\tfunction g() external;\n}\ninterface J {\n\tfunction f() external;\n}\nabstract contract IJ is I, J {\n\tfunction f() external virtual override (I, J);\n}\nabstract contract A is IJ\n{\n\tfunction f() external virtual override;\n}\nabstract contract B is IJ\n{\n\tfunction g() external override {}\n}\nabstract contract C is A, B {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override.sol",
    "content": "abstract contract A {\n\tfunction test() internal virtual returns (uint256);\n\tfunction test2() internal virtual returns (uint256);\n}\ncontract X is A {\n\tfunction test() internal override returns (uint256) {}\n\tfunction test2() internal override(A) returns (uint256) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_ambiguous.sol",
    "content": "abstract contract A {\n\tfunction foo() internal virtual returns (uint256);\n}\nabstract contract B {\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test() internal virtual returns (uint256);\n}\nabstract contract X is A, B {\n\tfunction test() internal override returns (uint256) {}\n}\n// ----\n// TypeError 6480: (205-292): Derived contract must override function \"foo\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_base_base.sol",
    "content": "abstract contract A {\n\tfunction foo() internal virtual returns (uint256);\n}\n\nabstract contract B is A {\n\tfunction foo() internal override virtual returns (uint256);\n}\n\nabstract contract C is B {\n\tfunction foo() internal override virtual returns (uint256);\n}\n\nabstract contract D is C {\n\tfunction foo() internal override virtual returns (uint256);\n}\n\ncontract X is D {\n\tfunction foo() internal override returns (uint256) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_empty_list.sol",
    "content": "contract A {\n\tint public testvar;\n\tfunction test() internal returns (uint256);\n}\ncontract X is A {\n\tint public override testvar;\n\tfunction test() internal override() returns (uint256);\n}\n// ----\n// ParserError 2314: (164-165): Expected identifier but got ')'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_implemented_and_unimplemented_with_implemented_call_via_contract.sol",
    "content": "contract A {\n    function f() public virtual {}\n}\nabstract contract B {\n    function f() public virtual;\n}\ncontract C is A, B {\n    function f() public virtual override(A, B) {\n        B.f(); // Should not skip over to A.f() just because B.f() has no implementation.\n    }\n}\n// ----\n// TypeError 7501: (185-190): Cannot call unimplemented base function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_implemented_and_unimplemented_with_implemented_call_via_super.sol",
    "content": "contract A {\n    function f() public virtual {}\n}\nabstract contract B {\n    function f() public virtual;\n}\ncontract C is A, B {\n    function f() public override(A, B) {\n        super.f(); // super should skip the unimplemented B.f() and call A.f() instead.\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_implemented_and_unimplemented_with_implemented_no_call.sol",
    "content": "contract A {\n    function f() public virtual {}\n}\nabstract contract B {\n    function f() public virtual;\n}\ncontract C is A, B {\n    function f() public override(A, B) {\n        // This is fine. The unimplemented B.f() is not used.\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_implemented_and_unimplemented_with_implemented_virtual_call_into_base_contract.sol",
    "content": "contract A {\n    function f() public virtual {}\n}\nabstract contract B {\n    function f() public virtual;\n}\nabstract contract C is A, B {\n    function g() public {\n        f(); // Would call B.f() if we did not require an override in C.\n    }\n}\n// ----\n// TypeError 6480: (107-243): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_implemented_with_unimplemented_then_implemented.sol",
    "content": "contract A {\n    function f() public virtual {}\n}\nabstract contract B is A {\n    function f() public virtual override;\n}\ncontract C is B {\n    function f() public virtual override {}\n}\n// ----\n// TypeError 4593: (81-118): Overriding an implemented function with an unimplemented function is not allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_interface.sol",
    "content": "interface A {\n\tfunction test() external returns (uint256);\n\tfunction test2() external returns (uint256);\n\tfunction test3() external returns (uint256);\n}\ncontract X is A {\n\tfunction test() external override returns (uint256) {}\n\tfunction test2() external override(A) returns (uint256) {}\n\tfunction test3() external returns (uint256) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_interface_multiple.sol",
    "content": "interface A {\n\tfunction test() external returns (uint256);\n\tfunction test2() external returns (uint256);\n}\n\ninterface B {\n\tfunction test() external returns (uint256);\n\tfunction test2() external returns (uint256);\n}\ncontract X is A, B {\n\tfunction test() external override(A, B) returns (uint256) {}\n\tfunction test2() external override(B, A) returns (uint256) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_less_strict_mutability.sol",
    "content": "contract A {\n\tfunction foo() external pure virtual returns (uint256) {}\n}\ncontract B is A {\n\tfunction foo() external pure override virtual returns (uint256) {}\n}\ncontract C is A {\n\tfunction foo() external view override virtual returns (uint256) {}\n}\ncontract D is B, C {\n\tfunction foo() external override(B, C) virtual returns (uint256) {}\n}\ncontract E is C, B {\n\tfunction foo() external pure override(B, C) virtual returns (uint256) {}\n}\ncontract F is C, B {\n\tfunction foo() external payable override(B, C) virtual returns (uint256) {}\n}\n// ----\n// TypeError 6959: (181-247): Overriding function changes state mutability from \"pure\" to \"view\".\n// TypeError 6959: (272-339): Overriding function changes state mutability from \"pure\" to \"nonpayable\".\n// TypeError 6959: (272-339): Overriding function changes state mutability from \"view\" to \"nonpayable\".\n// TypeError 6959: (461-536): Overriding function changes state mutability from \"view\" to \"payable\".\n// TypeError 6959: (461-536): Overriding function changes state mutability from \"pure\" to \"payable\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_library.sol",
    "content": "library L {}\ncontract C {\n\tfunction f() public override (L) {}\n}\n// ----\n// TypeError 1130: (57-58): Invalid use of a library name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_missing_virtual.sol",
    "content": "abstract contract A {\n\tfunction test() external virtual returns (uint256);\n\tfunction test2() external returns (uint256) {}\n}\nabstract contract X is A {\n\tfunction test() external returns (uint256) {}\n\tfunction test2() external override(A) returns (uint256) {}\n}\n// ----\n// TypeError 9456: (153-198): Overriding function is missing \"override\" specifier.\n// TypeError 4334: (76-122): Trying to override non-virtual function. Did you forget to add \"virtual\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_modifier_no_override.sol",
    "content": "abstract contract A {\n}\nabstract contract X is A {\n\tmodifier f() override { _; }\n}\n// ----\n// TypeError 7792: (65-73): Modifier has override specified but does not override anything.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multi_layered_error.sol",
    "content": "interface IBase {\n    function foo() external view;\n}\n\ncontract Base1 is IBase { function foo() public virtual view {} }\ncontract Base2 is IBase { function foo() public virtual view {} }\n\ninterface IExt1a is IBase {}\ninterface IExt1b is IBase {}\ninterface IExt2a is IBase {}\ninterface IExt2b is IBase {}\n\ncontract Ext1 is IExt1a, IExt1b, Base1 {}\ncontract Ext2 is IExt2a, IExt2b, Base2 {}\n\ncontract Impl is Ext1, Ext2 {\n    function foo() public view {}\n}\n// ----\n// TypeError 9456: (424-453): Overriding function is missing \"override\" specifier.\n// TypeError 9456: (424-453): Overriding function is missing \"override\" specifier.\n// TypeError 4327: (424-453): Function needs to specify overridden contracts \"Base1\", \"Base2\" and \"IBase\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multi_layered_fine.sol",
    "content": "interface IBase {\n    function foo() external view;\n}\n\ncontract Base1 is IBase { function foo() public virtual view {} }\ncontract Base2 is IBase { function foo() public virtual view {} }\n\ninterface IExt1a is IBase {}\ninterface IExt1b is IBase {}\ninterface IExt2a is IBase {}\ninterface IExt2b is IBase {}\n\ncontract Ext1 is IExt1a, IExt1b, Base1 {}\ncontract Ext2 is IExt2a, IExt2b, Base2 {}\n\ncontract Impl is Ext1, Ext2 {\n    function foo() public view override (IBase, Base1, Base2) {}\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multi_layered_fine_abstract.sol",
    "content": "interface IBase {\n    function foo() external view;\n}\n\ncontract Base1 is IBase { function foo() public virtual view {} }\ncontract Base2 is IBase { function foo() public virtual view {} }\n\ninterface IExt1a is IBase {}\nabstract contract IExt1b is IBase {}\nabstract contract IExt2a is IBase {}\ninterface IExt2b is IBase {}\n\ncontract Ext1 is IExt1a, IExt1b, Base1 {}\ncontract Ext2 is IExt2a, IExt2b, Base2 {}\n\ncontract Impl is Ext1, Ext2 {\n    function foo() public view override (IBase, Base1, Base2) {}\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multiple.sol",
    "content": "abstract contract A {\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test(uint8 _a) internal virtual returns (uint256) {}\n}\nabstract contract B {\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test() internal virtual returns (uint256);\n}\nabstract contract C {\n\tfunction foo() internal virtual returns (uint256);\n}\nabstract contract D {\n\tfunction foo() internal virtual returns (uint256);\n}\ncontract X is A, B, C, D {\n\tfunction test() internal override returns (uint256) {}\n\tfunction foo() internal override(A, B, C, D) returns (uint256) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multiple2.sol",
    "content": "abstract contract A {\n\tint public testvar;\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test(uint8 _a) internal virtual returns (uint256);\n}\nabstract contract B {\n\tfunction foo() internal virtual returns (uint256);\n}\n\nabstract contract C is A {\n}\nabstract contract D is A, B, C {\n\tfunction foo() internal override(A, B) virtual returns (uint256);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multiple_duplicated.sol",
    "content": "abstract contract A {\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test(uint8 _a) internal virtual returns (uint256);\n}\nabstract contract B {\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test() internal virtual returns (uint256);\n}\nabstract contract C {\n\tfunction foo() internal virtual returns (uint256);\n}\nabstract contract D {\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test() internal virtual returns (uint256);\n}\nabstract contract X is A, B, C, D {\n\tfunction test() internal override(B, D, D) virtual returns (uint256);\n\tfunction foo() internal override(A, C, B, B, B, D ,D) virtual returns (uint256);\n}\n// ----\n// TypeError 4520: (548-549): Duplicate contract \"D\" found in override list of \"test\".\n// TypeError 4520: (621-622): Duplicate contract \"B\" found in override list of \"foo\".\n// TypeError 4520: (624-625): Duplicate contract \"B\" found in override list of \"foo\".\n// TypeError 4520: (630-631): Duplicate contract \"D\" found in override list of \"foo\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail1.sol",
    "content": "contract A {\n\tfunction foo() internal returns (uint256);\n}\ncontract X {\n\tint public override(A,) testvar;\n}\n// ----\n// ParserError 2314: (95-96): Expected identifier but got ')'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail2.sol",
    "content": "contract A {\n\tfunction foo() internal returns (uint256);\n}\ncontract X {\n\tfunction test() internal override(,) returns (uint256);\n}\n// ----\n// ParserError 2314: (107-108): Expected identifier but got ','\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail3.sol",
    "content": "contract A {\n\tfunction foo() internal returns (uint256);\n}\ncontract X {\n\tfunction foo() internal override(X, address) returns (uint256);\n}\n// ----\n// ParserError 2314: (109-116): Expected identifier but got 'address'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail4.sol",
    "content": "contract A {\n\tfunction foo() internal returns (uint256);\n}\ncontract X {\n\tint public override() testvar;\n}\n// ----\n// ParserError 2314: (93-94): Expected identifier but got ')'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multiple_missing.sol",
    "content": "abstract contract A {\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test(uint8 _a) virtual internal returns (uint256);\n}\nabstract contract B {\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test() internal virtual returns (uint256);\n}\nabstract contract C {\n\tfunction foo() internal virtual returns (uint256);\n}\nabstract contract D {\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test() internal virtual returns (uint256);\n}\nabstract contract X is A, B, C, D {\n\tfunction test() internal override(B, D, C) virtual returns (uint256);\n\tfunction foo() internal override(A, C) virtual returns (uint256);\n}\n// ----\n// TypeError 2353: (533-550): Invalid contract specified in override list: \"C\".\n// TypeError 4327: (603-617): Function needs to specify overridden contracts \"B\" and \"D\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multiple_no_virtual.sol",
    "content": "contract A\n{\n\tfunction foo() virtual internal {}\n}\ncontract B\n{\n\tfunction foo() internal {}\n}\ncontract C is A, B\n{\n\tfunction foo() internal override(A, B) {}\n}\n// ----\n// TypeError 4334: (65-91): Trying to override non-virtual function. Did you forget to add \"virtual\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multiple_no_virtual2.sol",
    "content": "contract A\n{\n\tfunction foo() virtual internal {}\n}\ncontract B\n{\n\tfunction foo() internal {}\n}\ncontract C is A, B\n{\n}\n// ----\n// TypeError 6480: (94-116): Derived contract must override function \"foo\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_multiple_unresolved.sol",
    "content": "contract A {\n\tint public testvar;\n\tfunction foo() internal override(N, Z) returns (uint256);\n}\n// ----\n// DeclarationError 7920: (68-69): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_public_vars.sol",
    "content": "abstract contract A {\n\tint public testvar;\n}\nabstract contract X is A {\n\tint public override testvar;\n}\n// ----\n// DeclarationError 9097: (73-100): Identifier already declared.\n// TypeError 1452: (23-41): Cannot override public state variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_return_mismatch.sol",
    "content": "abstract contract A {\n\tfunction foo() internal virtual returns (uint256);\n}\nabstract contract B {\n\tfunction foo() internal virtual returns (uint8);\n\tfunction test() internal virtual returns (uint256);\n}\nabstract contract X is A, B {\n\tfunction test() internal override virtual returns (uint256);\n}\n// ----\n// TypeError 6480: (203-296): Derived contract must override function \"foo\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_shared_base.sol",
    "content": "contract I {\n\tfunction set() public virtual {}\n}\ncontract A is I {\n\tuint a;\n\tfunction set() public virtual override { a = 1; super.set(); a = 2; }\n}\ncontract B is I {\n\tuint b;\n\tfunction set() public virtual override { b = 1; super.set(); b = 2; }\n\n}\ncontract X is A, B {\n\tfunction set() public override(A, B) { super.set(); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_shared_base_partial.sol",
    "content": "contract I {\n  function f() external virtual {}\n}\ncontract A is I {\n  function f() external virtual override {}\n}\ncontract B is I {}\ncontract C is A, B {\n  function f() external override(A, I) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_shared_base_simple.sol",
    "content": "contract I {\n  function f() external {}\n}\ncontract A is I {}\ncontract B is I {}\ncontract C is A, B {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_stricter_mutability.sol",
    "content": "contract A {\n\tfunction foo() internal view virtual returns (uint256) {}\n}\ncontract B is A {\n\tfunction foo() internal pure override virtual returns (uint256) {}\n}\ncontract C is A {\n\tfunction foo() internal view override virtual returns (uint256) {}\n}\ncontract D is B, C {\n\tfunction foo() internal pure override(B, C) virtual returns (uint256) {}\n}\ncontract E is C, B {\n\tfunction foo() internal pure override(B, C) virtual returns (uint256) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_stricter_mutability1.sol",
    "content": "contract A {\n\tfunction foo() public payable virtual returns (uint256) {}\n}\ncontract B is A {\n\tfunction foo() public override virtual returns (uint256) {}\n}\n// ----\n// TypeError 6959: (94-153): Overriding function changes state mutability from \"payable\" to \"nonpayable\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_stricter_mutability2.sol",
    "content": "contract A {\n\tfunction foo() internal virtual returns (uint256) {}\n}\ncontract B is A {\n\tfunction foo() internal view override virtual returns (uint256) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_stricter_mutability3.sol",
    "content": "contract A {\n\tfunction foo() internal view virtual returns (uint256) {}\n}\ncontract B is A {\n\tfunction foo() internal pure override virtual returns (uint256) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_stricter_mutability4.sol",
    "content": "contract A {\n\tfunction foo() public payable virtual returns (uint256) {}\n}\ncontract B is A {\n\tfunction foo() public view override virtual returns (uint256) {}\n}\n// ----\n// TypeError 6959: (94-158): Overriding function changes state mutability from \"payable\" to \"view\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_stricter_mutability5.sol",
    "content": "contract A {\n\tfunction foo() public payable virtual returns (uint256) {}\n}\ncontract B is A {\n\tfunction foo() public pure override virtual returns (uint256) {}\n}\n// ----\n// TypeError 6959: (94-158): Overriding function changes state mutability from \"payable\" to \"pure\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_stricter_mutability6.sol",
    "content": "contract A {\n\tfunction foo() public virtual returns (uint256) {}\n}\ncontract B is A {\n\tfunction foo() public payable override virtual returns (uint256) {}\n}\n// ----\n// TypeError 6959: (86-153): Overriding function changes state mutability from \"nonpayable\" to \"payable\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_stricter_mutability7.sol",
    "content": "contract A {\n\tfunction foo() public view virtual returns (uint256) {}\n}\ncontract B is A {\n\tfunction foo() public payable override virtual returns (uint256) {}\n}\n// ----\n// TypeError 6959: (91-158): Overriding function changes state mutability from \"view\" to \"payable\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_type_mismatch.sol",
    "content": "abstract contract A {\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test(uint8 _a) internal virtual returns (uint256);\n}\nabstract contract B {\n\tfunction foo() internal virtual returns (uint256);\n\tfunction test() internal virtual returns (uint256);\n}\nabstract contract C {\n\tfunction foo() internal virtual returns (uint256);\n}\nabstract contract D {\n\tfunction foo() internal virtual returns (uint256);\n}\nabstract contract X is A, B, C, D {\n\tstruct MyStruct { int abc; }\n\tenum ENUM { F,G,H }\n\n\tfunction test() internal override virtual returns (uint256);\n\tfunction foo() internal override(MyStruct, ENUM, A, B, C, D) virtual returns (uint256);\n}\n// ----\n// TypeError 9301: (602-610): Expected contract but got struct X.MyStruct.\n// TypeError 9301: (612-616): Expected contract but got enum X.ENUM.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_type_mismatch2.sol",
    "content": "contract A {\n  function f() public virtual {}\n}\ncontract B {\n  function g() public {}\n}\ncontract C is A,B {\n  function f() public override (g) {}\n}\n\n// ----\n// TypeError 9301: (140-141): Expected contract but got function ().\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_unimplemented_and_implemented_with_unimplemented.sol",
    "content": "abstract contract A {\n    function f() external virtual;\n}\nabstract contract B {\n    function f() external virtual {}\n}\nabstract contract C is A, B {\n    function f() external virtual override(A, B);\n}\nabstract contract D is B, A {\n    function f() external virtual override(A, B);\n}\n// ----\n// TypeError 4593: (154-199): Overriding an implemented function with an unimplemented function is not allowed.\n// TypeError 4593: (236-281): Overriding an implemented function with an unimplemented function is not allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/override_unimplemented_and_unimplemented_with_unimplemented.sol",
    "content": "interface A {\n    function f() external;\n}\ninterface B {\n    function f() external;\n}\nabstract contract C is A, B {\n    function f() external virtual override(A, B);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/private_state_variable.sol",
    "content": "contract C1 {\n  function f() external pure returns(int) { return 42; }\n}\n\ncontract C is C1 {\n   int override f;\n}\n// ----\n// TypeError 8022: (96-110): Override can only be used with public state variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_constant_var_overrides_pure.sol",
    "content": "abstract contract C {\n    function foo() external pure virtual returns (uint);\n}\ncontract X is C {\n\tuint public constant override foo = 7;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_immutable_var_overrides_pure.sol",
    "content": "abstract contract C {\n    function foo() external pure virtual returns (uint);\n}\ncontract X is C {\n\tuint public immutable override foo = 7;\n}\n// ----\n// TypeError 6959: (100-138): Overriding public state variable changes state mutability from \"pure\" to \"view\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_implements_parallel_interface.sol",
    "content": "interface A {\n    function foo() external returns (uint);\n    function goo() external returns (uint);\n}\ninterface B {\n    function foo() external returns (uint);\n    function goo() external returns (uint);\n}\ncontract X is A, B {\n\tuint public override(A, B) foo;\n    function goo() external virtual override(A, B) returns (uint) {}\n}\nabstract contract T is A {\n    function foo() external virtual returns (uint);\n    function goo() external virtual returns (uint);\n}\ncontract Y is X, T {\n}\n// ----\n// TypeError 6480: (466-488): Derived contract must override function \"foo\". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.\n// TypeError 6480: (466-488): Derived contract must override function \"goo\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_missing_override.sol",
    "content": "interface A {\n    function foo() external returns (uint);\n}\ninterface B {\n    function foo() external returns (uint);\n}\ncontract X is A, B {\n\tuint public override(A) foo;\n}\n// ----\n// TypeError 4327: (154-165): Public state variable needs to specify overridden contract \"B\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_no_override_but_function.sol",
    "content": "contract A {\n\tfunction foo() internal virtual view returns(uint) { return 5; }\n}\ncontract X is A {\n\tuint public foo;\n}\n// ----\n// TypeError 9456: (100-115): Overriding public state variable is missing \"override\" specifier.\n// TypeError 5225: (100-115): Public state variables can only override functions with external visibility.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_override_mapping_to_dynamic_struct.sol",
    "content": "pragma abicoder               v2;\n\nabstract contract C {\n\tstruct S {\n\tuint256 x;\n\tstring y;\n\t}\n\tfunction f(address x) external virtual returns (uint256, string memory);\n}\ncontract D is C {\n\tmapping(address => S) public override f;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_override_struct_with_memory_element.sol",
    "content": "pragma abicoder               v2;\n\nabstract contract C {\n\tstruct S {\n\t\tuint256 x;\n\t\tstring y;\n\t}\n\n\tfunction f() external virtual returns (uint256, string memory);\n}\ncontract D is C {\n\tS public override f;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_overrides_public_var.sol",
    "content": "contract A {\n    uint public foo;\n}\ncontract X is A {\n\tuint public override foo;\n}\n// ----\n// DeclarationError 9097: (55-79): Identifier already declared.\n// TypeError 1452: (17-32): Cannot override public state variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_overrides_pure.sol",
    "content": "abstract contract C {\n    function foo() external pure virtual returns (uint);\n}\ncontract X is C {\n\tuint public override foo;\n}\n// ----\n// TypeError 6959: (100-124): Overriding public state variable changes state mutability from \"pure\" to \"view\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_overriding_multiple.sol",
    "content": "interface A {\n    function foo() external returns (uint);\n}\ninterface B {\n    function foo() external returns (uint);\n}\ncontract X is A, B {\n\tuint public override(A, B) foo;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_overriding_multiple_derived.sol",
    "content": "interface A {\n    function foo() external returns (uint);\n}\ninterface B {\n    function foo() external returns (uint);\n}\ncontract X is A, B {\n\tuint public override(A, B) foo;\n}\ncontract Y is X {\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_parallel_function.sol",
    "content": "interface A {\n    function foo() external returns (uint);\n}\ncontract B {\n    uint public foo;\n}\ncontract X is A, B {\n}\n// ----\n// TypeError 6480: (96-118): Derived contract must override function \"foo\". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_same_name_but_different_args.sol",
    "content": "contract A {\n\tfunction foo(uint) internal virtual pure returns(uint) { return 5; }\n}\ncontract X is A {\n\tuint public foo;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_var_surplus_override.sol",
    "content": "interface A {\n    function foo() external returns (uint);\n}\ninterface B {}\ncontract X is A {\n\tuint public override(A, B) foo;\n}\n// ----\n// TypeError 2353: (106-120): Invalid contract specified in override list: \"B\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_vars_multiple.sol",
    "content": "contract A {\n\tfunction foo() external virtual view returns(uint) { return 5; }\n}\ncontract B {\n\tfunction foo() external virtual view returns(uint) { return 5; }\n}\ncontract X is A, B {\n\tuint public override foo;\n}\n// ----\n// TypeError 4327: (196-204): Public state variable needs to specify overridden contracts \"A\" and \"B\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_vars_multiple1.sol",
    "content": "contract A {\n\tuint public foo;\n}\ncontract B {\n\tfunction foo() external virtual view returns(uint) { return 5; }\n}\ncontract X is A, B {\n\tuint public override foo;\n}\n// ----\n// DeclarationError 9097: (136-160): Identifier already declared.\n// TypeError 1452: (14-29): Cannot override public state variable.\n// TypeError 4327: (148-156): Public state variable needs to specify overridden contracts \"A\" and \"B\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_vars_multiple2.sol",
    "content": "contract A {\n\tfunction foo() external virtual view returns(uint) { return 4; }\n\tfunction foo(uint ) external virtual view returns(uint) { return 4; }\n\tfunction foo(uint , uint ) external view virtual returns(A) {  }\n}\ncontract X is A {\n\tuint public override foo;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_vars_multiple3.sol",
    "content": "contract A {\n\tfunction foo() external virtual view returns(A) {  }\n\tfunction foo(uint ) external virtual view returns(uint) { return 4; }\n\tfunction foo(uint , uint ) external view virtual returns(A) {  }\n}\ncontract X is A {\n\tuint public override foo;\n}\n// ----\n// TypeError 4822: (225-249): Overriding public state variable return types differ.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_vars_multiple4.sol",
    "content": "contract ERC20 {\n  function balanceOf(address) external virtual view returns (uint) {}\n  function balanceOf(uint) external virtual view returns (uint) {}\n  function balanceOf() external virtual view returns (uint) {}\n}\ncontract C is ERC20 {\n  mapping(address => uint) public override balanceOf;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_vars_multiple5.sol",
    "content": "contract ERC20 {\n  function balanceOf(address, uint) external virtual view returns (uint) {}\n  function balanceOf(uint) external virtual view returns (uint) {}\n  function balanceOf() external virtual view returns (uint) {}\n}\ncontract C is ERC20 {\n  mapping(address => uint) public override balanceOf;\n}\n// ----\n// TypeError 7792: (281-289): Public state variable has override specified but does not override anything.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_vars_multiple_diamond.sol",
    "content": "contract A {\n\tfunction foo() external virtual view returns(uint) { return 5; }\n}\ncontract B is A {\n\tfunction foo() external virtual override view returns(uint) { return 5; }\n}\ncontract C is A {\n\tfunction foo() external virtual override view returns(uint) { return 5; }\n}\ncontract X is B, C {\n\tuint public override foo;\n}\n// ----\n// TypeError 4327: (305-313): Public state variable needs to specify overridden contracts \"B\" and \"C\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_vars_multiple_diamond1.sol",
    "content": "contract A {\n\tfunction foo() external virtual view returns(uint) { return 5; }\n}\ncontract B is A {\n\tuint public override foo;\n}\ncontract C is A {\n\tfunction foo() external virtual override view returns(uint) { return 5; }\n}\ncontract X is B, C {\n\tuint public override foo;\n}\n// ----\n// DeclarationError 9097: (245-269): Identifier already declared.\n// TypeError 1452: (100-124): Cannot override public state variable.\n// TypeError 4327: (257-265): Public state variable needs to specify overridden contracts \"B\" and \"C\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_vars_multiple_diamond2.sol",
    "content": "contract A {\n\tfunction foo() external virtual view returns(uint) { return 5; }\n}\ncontract B is A {\n\tuint public override foo;\n}\ncontract C is A {\n\tfunction foo() external virtual override view returns(uint) { return 5; }\n}\ncontract X is B, C {\n\tuint public override(A, C) foo;\n}\n// ----\n// DeclarationError 9097: (245-275): Identifier already declared.\n// TypeError 1452: (100-124): Cannot override public state variable.\n// TypeError 4327: (257-271): Public state variable needs to specify overridden contract \"B\".\n// TypeError 2353: (257-271): Invalid contract specified in override list: \"A\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_vars_multiple_explicit_override.sol",
    "content": "contract A {\n\tfunction foo() external virtual view returns(uint) { return 5; }\n}\ncontract B {\n\tfunction foo() external virtual view returns(uint) { return 5; }\n}\ncontract X is A, B {\n\tuint public override(A, B) foo;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/public_vars_wrong_override.sol",
    "content": "contract X {\n\tuint public override foo;\n}\n// ----\n// TypeError 7792: (26-34): Public state variable has override specified but does not override anything.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/remove_view.sol",
    "content": "contract B { function f() virtual public view {} }\ncontract C is B { function f() public {} }\n// ----\n// TypeError 9456: (69-91): Overriding function is missing \"override\" specifier.\n// TypeError 6959: (69-91): Overriding function changes state mutability from \"view\" to \"nonpayable\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/restrict_mutability_for_override_only.sol",
    "content": "contract A {\n    // no \"state mutability can be restricted\"-warning here\n    function foo() external virtual returns (uint) { return 1; }\n}\ncontract B is A {\n    // no \"state mutability can be restricted\"-warning here\n    function foo() external virtual override returns (uint) { return 2; }\n}\ncontract C is B {\n    // warning is here\n    function foo() external override returns (uint) { return 3; }\n}\n// ----\n// Warning 2018: (339-400): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/state_variable_function.sol",
    "content": "contract A {\n\tuint public x;\n}\ncontract C is A {\n\tfunction x() public returns (uint) {}\n}\n// ----\n// DeclarationError 9097: (50-87): Identifier already declared.\n// TypeError 9456: (50-87): Overriding function is missing \"override\" specifier.\n// TypeError 1452: (14-27): Cannot override public state variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/triangle_impl.sol",
    "content": "contract A { function f() public pure virtual {} }\ncontract B is A { function f() public pure virtual override {} }\ncontract C is A, B { }\ncontract D is A, B { function f() public pure override(A, B) {} }\n// ----\n// TypeError 6480: (116-138): Derived contract must override function \"f\". Two or more base classes define function with same name and parameter types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/triangle_no_impl.sol",
    "content": "abstract contract A { function f() public pure virtual; }\ncontract B is A { function f() public pure virtual override {} }\ncontract C is A, B { }\ncontract D is A, B { function f() public pure override(A, B) {} }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/override/virtual_private.sol",
    "content": "abstract contract A {\n\tfunction test() private virtual returns (uint256);\n}\nabstract contract X is A {\n\tfunction test() private override returns (uint256) {}\n}\n// ----\n// TypeError 3942: (23-73): \"virtual\" and \"private\" cannot be used together.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/reference_non_base_ctor.sol",
    "content": "contract X {}\ncontract D {\n    constructor() X(5) {}\n}\n// ----\n// TypeError 4659: (45-49): Referenced declaration is neither modifier nor base class.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/repeated_inheritance_definition.sol",
    "content": "contract A {}\ncontract B {}\ncontract C is A is B is B is A{ }\n// ----\n// ParserError 6668: (44-46): More than one inheritance list.\n// ParserError 6668: (49-51): More than one inheritance list.\n// ParserError 6668: (54-56): More than one inheritance list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/shadowing_base_state_vars.sol",
    "content": "contract A {\n\tuint i;\n}\ncontract B is A {\n\tuint i;\n}\n// ----\n// DeclarationError 9097: (43-49): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/shadowing_private_base_state_vars.sol",
    "content": "contract A {\n\tuint private i;\n}\ncontract B is A {\n\tuint i;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/super_on_external.sol",
    "content": "contract A {\n    function f() external virtual pure {}\n}\ncontract B is A {\n    function f() public override pure {\n        super.f();\n    }\n}\n// ----\n// TypeError 9582: (123-130): Member \"f\" not found or not visible after argument-dependent lookup in type(contract super B).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/too_few_base_arguments.sol",
    "content": "contract Base {\n  constructor(uint, uint) {}\n}\ncontract Derived is Base(2) { }\ncontract Derived2 is Base {\n  constructor() Base(2) { }\n}\n// ----\n// TypeError 7927: (67-74): Wrong argument count for constructor call: 1 arguments given but expected 2\n// TypeError 2973: (123-130): Wrong argument count for modifier invocation: 1 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/unimplemented_without_virtual.sol",
    "content": "abstract contract C {\n\tfunction f() external;\n}\n// ----\n// TypeError 5424: (23-45): Functions without implementation must be marked virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/virtual/duplicate.sol",
    "content": "contract C\n{\n\tfunction foo() virtual public virtual {}\n\tmodifier modi() virtual virtual {_;}\n}\n// ----\n// ParserError 6879: (44-51): Virtual already specified.\n// ParserError 2662: (80-87): Virtual already specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/virtual/library_err.sol",
    "content": "library L {\n    function f() internal pure virtual returns (uint) { return 0; }\n}\n// ----\n// TypeError 7801: (16-79): Library functions cannot be \"virtual\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/virtual/modifier_virtual_err.sol",
    "content": "library test {\n    modifier m virtual;\n    function f() m public {\n    }\n}\n// ----\n// Warning 8429: (19-38): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 3275: (19-38): Modifiers in a library cannot be virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/virtual/simple.sol",
    "content": "contract C\n{\n\tfunction foo() public virtual {}\n\tfunction foo2() virtual public {}\n\tmodifier modi() virtual {_;}\n}\n// ----\n// Warning 8429: (83-111): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inheritance/wrong_type_base_arguments.sol",
    "content": "contract Base {\n  constructor(uint8) {}\n}\ncontract Derived is Base(300) { }\ncontract Derived2 is Base {\n  constructor() Base(2) { }\n}\n// ----\n// TypeError 9827: (67-70): Invalid type for argument in constructor call. Invalid implicit conversion from int_const 300 to uint8 requested. Literal is too large to fit in uint8.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/dynamic_inline_array.sol",
    "content": "contract C {\n    function f() public {\n        uint8[4][4] memory dyn = [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]];\n    }\n}\n// ----\n// Warning 2072: (47-69): Unused local variable.\n// Warning 2018: (17-135): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_and_passing_implicit_conversion.sol",
    "content": "    contract C {\n        function f() public returns (uint) {\n            uint8 x = 7;\n            uint16 y = 8;\n            uint32 z = 9;\n            uint32[3] memory ending = [x, y, z];\n            return (ending[1]);\n        }\n    }\n// ----\n// Warning 2018: (25-229): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_and_passing_implicit_conversion_strings.sol",
    "content": "contract C {\n    function f() public returns (string memory) {\n        string memory x = \"Hello\";\n        string memory y = \"World\";\n        string[2] memory z = [x, y];\n        return (z[0]);\n    }\n}\n// ----\n// Warning 2018: (17-198): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_const_int_conversion.sol",
    "content": "contract C {\n    function f() public returns (uint) {\n        uint8[4] memory z = [1,2,3,5];\n        return (z[0]);\n    }\n}\n// ----\n// Warning 2018: (17-121): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_const_string_conversion.sol",
    "content": "contract C {\n    function f() public returns (string memory) {\n        string[2] memory z = [\"Hello\", \"World\"];\n        return (z[0]);\n    }\n}\n// ----\n// Warning 2018: (17-140): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_no_type.sol",
    "content": "contract C {\n    function f() public returns (uint) {\n        return ([4,5,6][1]);\n    }\n}\n// ----\n// Warning 2018: (17-88): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/inline_array_declaration_no_type_strings.sol",
    "content": "contract C {\n    function f() public returns (string memory) {\n        return ([\"foo\", \"man\", \"choo\"][1]);\n    }\n}\n// ----\n// Warning 2018: (17-112): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/inline_array_fixed_types.sol",
    "content": "contract test {\n    function f() public {\n        fixed[3] memory a = [fixed(3.5), fixed(-4.25), fixed(967.125)];\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// Warning 2072: (50-67): Unused local variable.\n// Warning 2018: (20-119): Function state mutability can be restricted to pure\n// UnimplementedFeatureError 1834: (71-81): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/inline_array_of_mapping_type.sol",
    "content": "contract C {\n  mapping(int => int) a;\n  function f() public {\n    [a];\n  }\n}\n// ----\n// TypeError 1545: (66-69): Type mapping(int256 => int256) is only valid in storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/inline_array_rationals.sol",
    "content": "contract test {\n    function f() public {\n        ufixed128x3[4] memory a = [ufixed128x3(3.5), 4.125, 2.5, 4.0];\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// Warning 2072: (50-73): Unused local variable.\n// Warning 2018: (20-118): Function state mutability can be restricted to pure\n// UnimplementedFeatureError 1834: (77-93): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/invalid_types_in_inline_array.sol",
    "content": "contract C {\n    function f() public {\n        uint[3] memory x = [45, 'foo', true];\n    }\n}\n// ----\n// TypeError 6378: (66-83): Unable to deduce common type for array elements.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/lvalues_as_inline_array.sol",
    "content": "contract C {\n    function f() public {\n        [1, 2, 3]++;\n        [1, 2, 3] = [4, 5, 6];\n    }\n}\n// ----\n// TypeError 3025: (47-56): Inline array type cannot be declared as LValue.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/unnamed_type_tuple_in_inline_array.sol",
    "content": "contract C {\n    function f() public {\n        [(1, 2, 3), (4, 5, 6)];\n    }\n}\n// ----\n// TypeError 9656: (47-69): Unable to deduce nameable type for array elements. Try adding explicit type conversion for the first element.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/unnamed_types_in_inline_array_1.sol",
    "content": "contract C {\n    function f() public {\n        [msg];\n    }\n}\n// ----\n// TypeError 9563: (48-51): Invalid mobile type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/unnamed_types_in_inline_array_2.sol",
    "content": "contract C {\n    function f() public {\n        [type(C)];\n    }\n}\n// ----\n// TypeError 9563: (48-55): Invalid mobile type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineArrays/unnamed_types_in_inline_array_3.sol",
    "content": "contract C {\n    function f() public pure {\n        [uint];\n    }\n}\n// ----\n// TypeError 9563: (53-57): Invalid mobile type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assembly_dialect_duplicate_option.sol",
    "content": "function f() pure {\n    assembly \"evmasm\" (\"memory-safe\", \"memory-safe\") {}\n}\n// ----\n// SyntaxError 7026: (24-75): Inline assembly marked memory-safe multiple times.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assembly_dialect_invalid_options.sol",
    "content": "function f() pure {\n    assembly \"evmasm\" (\"a\", \"b\", \"c\", \"c\") {}\n}\n// ----\n// Warning 4430: (24-65): Unknown inline assembly flag: \"a\"\n// Warning 4430: (24-65): Unknown inline assembly flag: \"b\"\n// Warning 4430: (24-65): Unknown inline assembly flag: \"c\"\n// Warning 4430: (24-65): Unknown inline assembly flag: \"c\"\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assembly_dialect_leading_space.sol",
    "content": "function f() pure {\n    assembly \" evmasm\" {}\n}\n// ----\n// ParserError 4531: (33-42): Only \"evmasm\" supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assembly_duplicate_option.sol",
    "content": "function f() pure {\n    assembly (\"memory-safe\", \"memory-safe\") {}\n}\n// ----\n// SyntaxError 7026: (24-66): Inline assembly marked memory-safe multiple times.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assembly_empty_option_list.sol",
    "content": "function f() pure {\n    assembly () {}\n}\n// ----\n// ParserError 2314: (34-35): Expected 'StringLiteral' but got ')'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assembly_empty_option_list_dialect.sol",
    "content": "function f() pure {\n    assembly \"evmasm\" () {}\n}\n// ----\n// ParserError 2314: (43-44): Expected 'StringLiteral' but got ')'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assembly_flags_delimiter.sol",
    "content": "function f() pure {\n\tassembly (\"a\" \"b\") {}\n}\n// ----\n// ParserError 2314: (35-38): Expected ')' but got 'StringLiteral'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assembly_invalid_options.sol",
    "content": "function f() pure {\n    assembly (\"a\", \"b\", \"c\", \"c\") {}\n}\n// ----\n// Warning 4430: (24-56): Unknown inline assembly flag: \"a\"\n// Warning 4430: (24-56): Unknown inline assembly flag: \"b\"\n// Warning 4430: (24-56): Unknown inline assembly flag: \"c\"\n// Warning 4430: (24-56): Unknown inline assembly flag: \"c\"\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assignment_from_contract.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let x := C\n    }\n  }\n}\n// ----\n// TypeError 4977: (72-73): Expected a library.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assignment_from_functiontype.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let x := f\n    }\n  }\n}\n// ----\n// DeclarationError 2025: (72-73): Access to functions is not allowed in inline assembly.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assignment_from_functiontype2.sol",
    "content": "contract C {\n    function f() public pure {}\n    constructor() {\n        assembly {\n            let x := f\n        }\n    }\n}\n// ----\n// DeclarationError 2025: (105-106): Access to functions is not allowed in inline assembly.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assignment_from_functiontype3.sol",
    "content": "function ff() {}\n\ncontract C {\n  function f() public pure {\n    assembly {\n      let x := ff\n    }\n  }\n}\n// ----\n// DeclarationError 2025: (90-92): Access to functions is not allowed in inline assembly.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assignment_from_library.sol",
    "content": "library L {\n}\n\ncontract C {\n  function f() public pure {\n    assembly {\n      let x := L\n    }\n  }\n}\n// ====\n// compileViaYul: false\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assignment_from_opcode_like.sol",
    "content": "contract C {\n    function f() public pure {\n        uint mload;\n        assembly {\n            let x := mload\n        }\n    }\n}\n// ----\n// ParserError 7104: (104-109): Builtin function \"mload\" must be called.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assignment_from_super.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let x := super\n    }\n  }\n}\n// ----\n// DeclarationError 8198: (72-77): Identifier \"super\" not found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assignment_location.sol",
    "content": "contract C {\n    function f() pure public {\n        uint x; uint y;\n        assembly { x, y := 7 }\n    }\n}\n// ----\n// DeclarationError 8678: (87-96): Variable count for assignment to \"x, y\" does not match number of values (2 vs. 1)\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assignment_to_function_pointer.sol",
    "content": "contract C {\n    function f() public pure {\n        function() external g;\n        assembly {\n            g.address := 0x42\n            g.selector := 0x23\n        }\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assignment_to_opcode_like.sol",
    "content": "contract C {\n    function f() public pure {\n        uint mload;\n        assembly {\n            mload := 1\n        }\n    }\n}\n// ----\n// ParserError 6272: (101-103): Cannot assign to builtin function \"mload\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/assignment_to_special.sol",
    "content": "contract C {\n  function f() public {\n    assembly {\n      super := 1\n      this := 1\n      msg := 1\n      block := 1\n      f := 1\n      C := 1\n    }\n  }\n}\n// ----\n// DeclarationError 4634: (58-63): Variable not found or variable not lvalue.\n// DeclarationError 4634: (75-79): Variable not found or variable not lvalue.\n// DeclarationError 4634: (91-94): Variable not found or variable not lvalue.\n// DeclarationError 4634: (106-111): Variable not found or variable not lvalue.\n// TypeError 1990: (123-124): Only local variables can be assigned to in inline assembly.\n// TypeError 1990: (136-137): Only local variables can be assigned to in inline assembly.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/basefee_reserved_london.sol",
    "content": "contract C {\n    function f() public view returns (uint ret) {\n        assembly {\n            let basefee := sload(0)\n            ret := basefee\n        }\n    }\n}\n// ====\n// EVMVersion: =london\n// ----\n// ParserError 5568: (98-105): Cannot use builtin function name \"basefee\" as identifier name.\n// ParserError 7104: (137-144): Builtin function \"basefee\" must be called.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/blobbasefee_reserved_cancun.sol",
    "content": "contract C {\n    function f() public view returns (uint ret) {\n        assembly {\n            let blobbasefee := sload(0)\n            ret := blobbasefee\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// ParserError 5568: (98-109): Cannot use builtin function name \"blobbasefee\" as identifier name.\n// ParserError 7104: (141-152): Builtin function \"blobbasefee\" must be called.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/blobhash.sol",
    "content": "contract C {\n    function f() public view returns (bytes32 ret) {\n        assembly {\n            ret := blobhash(1)\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/blobhash_pre_cancun_not_declared.sol",
    "content": "contract C {\n    function f() pure external returns (bytes32 ret) {\n        assembly {\n            ret := blobhash()\n        }\n    }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// TypeError 8314: (106-114): The \"blobhash\" instruction is only available for Cancun-compatible VMs (you are currently compiling for \"shanghai\").\n// DeclarationError 8678: (99-116): Variable count for assignment to \"ret\" does not match number of values (1 vs. 0)\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/blobhash_pre_cancun_not_reserved.sol",
    "content": "contract C {\n    function f() public pure returns (uint ret) {\n        assembly {\n            let blobhash := 1\n            ret := blobhash\n        }\n    }\n    function g() public pure returns (uint ret) {\n        assembly {\n            function blobhash() -> r {\n                r := 1000\n            }\n            ret := blobhash()\n        }\n    }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/blobhash_reserved_cancun.sol",
    "content": "contract C {\n    function f() public pure returns (uint ret) {\n        assembly {\n            function blobhash() -> r {\n                r := 1000\n            }\n            ret := blobhash()\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// ParserError 5568: (103-111): Cannot use builtin function name \"blobhash\" as identifier name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/circular_constant_access_err.sol",
    "content": "contract C {\n    bytes32 constant x = x;\n    function f() public pure returns (uint t) {\n        assembly {\n            // Reference to a circular member\n            t := x\n        }\n    }\n}\n// ----\n// TypeError 3558: (171-172): Constant variable is circular.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/circular_constant_access_module_err.sol",
    "content": "==== Source: a ====\nimport \"b\";\nuint constant c = d;\n==== Source: b ====\nimport \"a\" as M;\nuint constant b = M.c;\nuint constant d = b;\ncontract C {\n    uint constant a = b;\n    function f() public returns (uint t) {\n        assembly {\n            t := a\n        }\n    }\n}\n// ----\n// TypeError 3558: (b:178-179): Constant variable is circular.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/circular_module_access_err.sol",
    "content": "==== Source: a ====\nbytes32 constant x = x;\n==== Source: b ====\nimport \"a\";\ncontract C {\n    function f() public pure returns (uint t) {\n        assembly {\n            // Reference to a circular member\n            t := x\n        }\n    }\n}\n// ----\n// TypeError 3558: (b:155-156): Constant variable is circular.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/clash_with_non_reserved_pure_yul_builtin.sol",
    "content": "contract C {\n    function f() public pure {\n        // NOTE: memoryguard is a builtin but only in pure Yul, not inline assembly.\n        // NOTE: memoryguard is not a reserved identifier.\n        assembly { function memoryguard() {} }\n        assembly { function f(memoryguard) {} }\n        assembly { function f() -> memoryguard {} }\n        assembly { let memoryguard }\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_builtin.sol",
    "content": "contract C {\n    function f() public view {\n        assembly {\n            // NOTE: All EVM instruction names are reserved identifiers in Yul.\n            // NOTE: We do provide builtins corresponding to these instructions.\n            function add(mstore) -> sstore {}\n            let coinbase\n        }\n    }\n}\n// ----\n// ParserError 5568: (245-248): Cannot use builtin function name \"add\" as identifier name.\n// ParserError 5568: (249-255): Cannot use builtin function name \"mstore\" as identifier name.\n// ParserError 5568: (260-266): Cannot use builtin function name \"sstore\" as identifier name.\n// ParserError 5568: (286-294): Cannot use builtin function name \"coinbase\" as identifier name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_non_builtin.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            // NOTE: All EVM instruction names are reserved identifiers in Yul.\n            // NOTE: We don't provide builtins corresponding to these instructions.\n            function dup1(dup2) -> dup3 {}\n            let dup4\n        }\n    }\n}\n// ----\n// DeclarationError 5017: (239-269): The identifier \"dup1\" is reserved and can not be used.\n// DeclarationError 5017: (253-257): The identifier \"dup2\" is reserved and can not be used.\n// DeclarationError 5017: (262-266): The identifier \"dup3\" is reserved and can not be used.\n// DeclarationError 5017: (286-290): The identifier \"dup4\" is reserved and can not be used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/clash_with_reserved_pure_yul_builtin.sol",
    "content": "contract C {\n    function f() public view {\n        assembly {\n            // NOTE: These are builtins but only in pure Yul, not inline assembly.\n            // NOTE: Names of these builtins are also reserved identifiers.\n            function loadimmutable(setimmutable) -> datasize {}\n            let dataoffset\n        }\n    }\n}\n// ----\n// DeclarationError 5017: (234-285): The identifier \"loadimmutable\" is reserved and can not be used.\n// DeclarationError 5017: (257-269): The identifier \"setimmutable\" is reserved and can not be used.\n// DeclarationError 5017: (274-282): The identifier \"datasize\" is reserved and can not be used.\n// DeclarationError 5017: (302-312): The identifier \"dataoffset\" is reserved and can not be used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/clz.sol",
    "content": "contract C {\n    function f(uint256 x) public pure returns (bytes32 ret) {\n        assembly {\n            ret := clz(x)\n        }\n    }\n}\n// ====\n// EVMVersion: >=osaka\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/clz_pre_osaka.sol",
    "content": "contract C {\n    function f(uint256 x) public pure returns (bytes32 ret) {\n        assembly {\n            ret := clz(x)\n        }\n    }\n}\n// ====\n// EVMVersion: =prague\n// ----\n// TypeError 4948: (113-116): The \"clz\" instruction is only available for Osaka-compatible VMs (you are currently compiling for \"prague\").\n// DeclarationError 8678: (106-119): Variable count for assignment to \"ret\" does not match number of values (1 vs. 0)\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/clz_reserved_osaka.sol",
    "content": "contract C {\n    function f() public pure returns (uint ret) {\n        assembly {\n            function clz() -> r {\n                r := 1000\n            }\n            ret := clz()\n        }\n    }\n}\n// ====\n// EVMVersion: >=osaka\n// ----\n// ParserError 5568: (103-106): Cannot use builtin function name \"clz\" as identifier name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/const_forward_reference.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      pop(add(add(1, 2), c))\n    }\n  }\n  int constant c = 1;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/const_from_non_const.sol",
    "content": "contract C {\n  bool nc = false;\n  bool constant c = nc;\n  function f() public {\n    assembly {\n        let t := c\n    }\n  }\n}\n// ----\n// TypeError 8349: (52-54): Initial value for constant variable has to be compile-time constant.\n// TypeError 7615: (112-113): Only direct number constants and references to such constants are supported by inline assembly.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/const_from_this.sol",
    "content": "contract C {\n  bool constant c = this;\n  function f() public {\n    assembly {\n        let t := c\n    }\n  }\n}\n// ----\n// TypeError 7407: (33-37): Type contract C is not implicitly convertible to expected type bool.\n// TypeError 8349: (33-37): Initial value for constant variable has to be compile-time constant.\n// TypeError 7615: (95-96): Only direct number constants and references to such constants are supported by inline assembly.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/constant_access.sol",
    "content": "contract C {\n    uint constant x = 2**20;\n    bool constant b = true;\n    bytes4 constant s = \"ab\";\n    function f() public pure {\n        assembly {\n            let c1 := x\n            let c2 := b\n            let c3 := s\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/constant_access_non_initialized.sol",
    "content": "contract C {\n    uint constant x;\n    function f() public pure {\n        assembly {\n            let c1 := x\n        }\n    }\n}\n// ----\n// TypeError 4266: (17-32): Uninitialized \"constant\" variable.\n// TypeError 3224: (106-107): Constant has no value.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/constant_array.sol",
    "content": "contract C {\n    string constant x = \"abc\";\n    function f() public pure {\n        assembly {\n            let a := x\n        }\n    }\n}\n// ----\n// TypeError 7615: (115-116): Only direct number constants and references to such constants are supported by inline assembly.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/constant_bytes_ref.sol",
    "content": "contract C {\n    bytes32 constant x = keccak256(\"abc\");\n    bytes32 constant y = x;\n    function f() public pure returns (uint t) {\n        assembly {\n            t := y\n        }\n    }\n}\n// ----\n// TypeError 7615: (168-169): Only direct number constants and references to such constants are supported by inline assembly.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/constant_computation.sol",
    "content": "contract C {\n    uint constant x = 2**20;\n    function f() public pure {\n        assembly {\n            let a := x\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/constant_ref.sol",
    "content": "contract C {\n    uint constant a = 2;\n    uint constant b = a;\n    function f() public pure {\n        assembly {\n            let x := b\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/create2_as_variable_post_istanbul.sol",
    "content": "contract c {\n\tfunction f() public {\n\t\tuint create2; create2;\n\t\tassembly { pop(create2(0, 0, 0, 0)) }\n\t}\n}\n// ====\n// EVMVersion: >=constantinople\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/create2_as_variable_pre_istanbul.sol",
    "content": "contract c {\n\tfunction f() public {\n\t\tuint create2; create2;\n\t\tassembly { pop(create2(0, 0, 0, 0)) }\n\t}\n}\n// ====\n// EVMVersion: =byzantium\n// ----\n// TypeError 6166: (78-85): The \"create2\" instruction is only available for Constantinople-compatible VMs (you are currently compiling for \"byzantium\").\n// TypeError 3950: (78-97): Expected expression to evaluate to one value, but got 0 values instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/difficulty_builtin_pre_paris.sol",
    "content": "contract C {\n    function f() public view returns (uint256) {\n        return block.difficulty;\n    }\n\n    function g() public view returns (uint256 ret) {\n        assembly {\n            ret := difficulty()\n        }\n    }\n}\n// ====\n// EVMVersion: <paris\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/difficulty_disallowed_function_pre_paris.sol",
    "content": "contract C {\n    function f() public view returns (uint256 ret) {\n        assembly {\n            let difficulty := sload(0)\n            ret := difficulty\n        }\n    }\n\n    function g() public pure returns (uint256 ret) {\n        assembly {\n            function difficulty() -> r {\n                r := 1000\n            }\n            ret := difficulty()\n        }\n    }\n}\n// ====\n// EVMVersion: <paris\n// ----\n// ParserError 5568: (101-111): Cannot use builtin function name \"difficulty\" as identifier name.\n// ParserError 7104: (143-153): Builtin function \"difficulty\" must be called.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/difficulty_magic_block_warn_post_paris.sol",
    "content": "contract C {\n    function f() public view returns (uint256) {\n        return block.difficulty;\n    }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// Warning 8417: (77-93): Since the VM version paris, \"difficulty\" was replaced by \"prevrandao\", which now returns a random number based on the beacon chain.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/difficulty_nobuiltin_post_paris.sol",
    "content": "contract C {\n    function f() public {\n        assembly {\n            pop(difficulty())\n        }\n    }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// DeclarationError 4619: (74-84): Function \"difficulty\" not found.\n// TypeError 3950: (74-86): Expected expression to evaluate to one value, but got 0 values instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/difficulty_reserved_post_paris.sol",
    "content": "contract C {\n    function f() public view returns (uint256 ret) {\n        assembly {\n            let difficulty := sload(0)\n            ret := difficulty\n        }\n    }\n\n    function g() public pure returns (uint256 ret) {\n        assembly {\n            function difficulty() -> r {\n                r := 1000\n            }\n            ret := difficulty()\n        }\n    }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// DeclarationError 5017: (101-111): The identifier \"difficulty\" is reserved and can not be used.\n// DeclarationError 5017: (255-323): The identifier \"difficulty\" is reserved and can not be used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/evm_byzantium.sol",
    "content": "contract C {\n    function f() pure external {\n        assembly {\n            let s := returndatasize()\n            returndatacopy(0, 0, s)\n        }\n    }\n    function g() view external returns (uint ret) {\n        assembly {\n            ret := staticcall(0, gas(), 0, 0, 0, 0)\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/evm_byzantium_on_homestead.sol",
    "content": "contract C {\n    function f() pure external {\n        assembly {\n            let s := returndatasize()\n            returndatacopy(0, 0, s)\n        }\n    }\n    function g() view external returns (uint ret) {\n        assembly {\n            ret := staticcall(0, gas(), 0, 0, 0, 0)\n        }\n    }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// TypeError 4778: (86-100): The \"returndatasize\" instruction is only available for Byzantium-compatible VMs (you are currently compiling for \"homestead\").\n// DeclarationError 3812: (77-102): Variable count mismatch for declaration of \"s\": 1 variables and 0 values.\n// TypeError 7756: (115-129): The \"returndatacopy\" instruction is only available for Byzantium-compatible VMs (you are currently compiling for \"homestead\").\n// TypeError 1503: (245-255): The \"staticcall\" instruction is only available for Byzantium-compatible VMs (you are currently compiling for \"homestead\").\n// DeclarationError 8678: (238-277): Variable count for assignment to \"ret\" does not match number of values (1 vs. 0)\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/evm_constantinople.sol",
    "content": "contract C {\n    function f() view external returns (uint ret) {\n        assembly {\n            ret := shl(gas(), 5)\n            ret := shr(ret, 2)\n            ret := sar(ret, 2)\n        }\n    }\n    function g() external returns (address ret) {\n        assembly {\n            ret := create2(0, 0, 0, 0)\n        }\n    }\n    function h() view external returns (bytes32 ret) {\n        assembly {\n            ret := extcodehash(address())\n        }\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/evm_constantinople_on_byzantium.sol",
    "content": "contract C {\n    function f() view external returns (uint ret) {\n        assembly {\n            ret := shl(gas(), 5)\n            ret := shr(ret, 2)\n            ret := sar(ret, 2)\n        }\n    }\n    function g() external returns (address ret) {\n        assembly {\n            ret := create2(0, 0, 0, 0)\n        }\n    }\n    function h() view external returns (bytes32 ret) {\n        assembly {\n            ret := extcodehash(address())\n        }\n    }\n}\n// ====\n// EVMVersion: =byzantium\n// ----\n// TypeError 6612: (103-106): The \"shl\" instruction is only available for Constantinople-compatible VMs (you are currently compiling for \"byzantium\").\n// DeclarationError 8678: (96-116): Variable count for assignment to \"ret\" does not match number of values (1 vs. 0)\n// TypeError 7458: (136-139): The \"shr\" instruction is only available for Constantinople-compatible VMs (you are currently compiling for \"byzantium\").\n// DeclarationError 8678: (129-147): Variable count for assignment to \"ret\" does not match number of values (1 vs. 0)\n// TypeError 2054: (167-170): The \"sar\" instruction is only available for Constantinople-compatible VMs (you are currently compiling for \"byzantium\").\n// DeclarationError 8678: (160-178): Variable count for assignment to \"ret\" does not match number of values (1 vs. 0)\n// TypeError 6166: (283-290): The \"create2\" instruction is only available for Constantinople-compatible VMs (you are currently compiling for \"byzantium\").\n// DeclarationError 8678: (276-302): Variable count for assignment to \"ret\" does not match number of values (1 vs. 0)\n// TypeError 7110: (412-423): The \"extcodehash\" instruction is only available for Constantinople-compatible VMs (you are currently compiling for \"byzantium\").\n// DeclarationError 8678: (405-434): Variable count for assignment to \"ret\" does not match number of values (1 vs. 0)\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/evm_istanbul.sol",
    "content": "contract C {\n    function f() view external returns (uint id) {\n        assembly {\n            id := chainid()\n        }\n    }\n    function g() view external returns (uint sb) {\n        assembly {\n            sb := selfbalance()\n        }\n    }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/evm_istanbul_on_petersburg.sol",
    "content": "contract C {\n    function f() pure external returns (uint id) {\n        assembly {\n            id := chainid()\n        }\n    }\n    function g() view external returns (uint sb) {\n        assembly {\n            sb := selfbalance()\n        }\n    }\n}\n// ====\n// EVMVersion: =petersburg\n// ----\n// TypeError 1561: (101-108): The \"chainid\" instruction is only available for Istanbul-compatible VMs (you are currently compiling for \"petersburg\").\n//  DeclarationError 8678: (95-110): Variable count for assignment to \"id\" does not match number of values (1 vs. 0)\n// TypeError 7721: (215-226): The \"selfbalance\" instruction is only available for Istanbul-compatible VMs (you are currently compiling for \"petersburg\").\n// DeclarationError 8678: (209-228): Variable count for assignment to \"sb\" does not match number of values (1 vs. 0)\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/extcodehash_as_variable_post_constantinople.sol",
    "content": "contract c {\n\tfunction f() public view {\n\t\tuint extcodehash;\n\t\textcodehash;\n\t\tassembly { pop(extcodehash(0)) }\n\t}\n}\n// ====\n// EVMVersion: >=constantinople\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/extcodehash_as_variable_pre_constantinople.sol",
    "content": "contract c {\n\tfunction f() public view {\n\t\tuint extcodehash;\n\t\textcodehash;\n\t\tassembly { pop(extcodehash(0)) }\n\t}\n}\n// ====\n// EVMVersion: =byzantium\n// ----\n// TypeError 7110: (93-104): The \"extcodehash\" instruction is only available for Constantinople-compatible VMs (you are currently compiling for \"byzantium\").\n// TypeError 3950: (93-107): Expected expression to evaluate to one value, but got 0 values instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/external_identifier_access_shadowing.sol",
    "content": "contract C {\n    function f() public returns (uint x) {\n        assembly {\n            function g() -> x {\n                x := 42\n            }\n            x := g()\n        }\n    }\n}\n// ----\n// DeclarationError 6578: (123-124): Cannot access local Solidity variables from inside an inline assembly function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/function_call_invalid_argument_count.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function f(a) {}\n\n      f()\n      f(1)\n      f(1, 2)\n    }\n  }\n}\n// ----\n// TypeError 7000: (87-88): Function \"f\" expects 1 arguments but got 0.\n// TypeError 7000: (108-109): Function \"f\" expects 1 arguments but got 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/function_call_not_found.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      k()\n    }\n  }\n}\n// ----\n// DeclarationError 4619: (63-64): Function \"k\" not found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/function_call_to_variable.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let x := 1\n\n      x()\n    }\n  }\n}\n// ----\n// TypeError 4202: (81-82): Attempt to call variable instead of function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/function_definition.sol",
    "content": "contract C {\n  function f() pure public {\n    assembly {\n      function f (a, b  , c ) ->    y,x,z {\n      }\n    }\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/function_definition_whitespace.sol",
    "content": "contract C {\n  function f() pure public {\n    assembly {\n      function f (a, b  , c ) -     >    y,x,z {\n      }\n    }\n  }\n}\n// ----\n// ParserError 2314: (87-88): Expected '{' but got '-'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/function_without_call.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function k() {}\n\n      k\n    }\n  }\n}\n// ----\n// ParserError 6913: (92-93): Call or assignment expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/hex_assignment.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let x := hex\"0011\"\n    }\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/hex_expression.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      pop(hex\"2233\")\n    }\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/hex_switch_case.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      switch calldataload(0)\n      case hex\"00\" {}\n      case hex\"1122\" {}\n    }\n  }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/immutables.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      setimmutable(\"abc\", 0)\n      loadimmutable(\"abc\")\n    }\n  }\n}\n// ----\n// DeclarationError 4619: (63-75): Function \"setimmutable\" not found.\n// DeclarationError 4619: (92-105): Function \"loadimmutable\" not found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/in_modifier.sol",
    "content": "contract test {\n    modifier m {\n        uint a = 1;\n        assembly {\n            a := 2\n        }\n        _;\n    }\n    function f() public m {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/assign_to_instruction.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let mod := 2\n    }\n  }\n}\n// ----\n// ParserError 5568: (67-70): Cannot use builtin function name \"mod\" as identifier name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/assignment_to_function.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            function f() {}\n            f := 1\n        }\n    }\n}\n// ----\n// TypeError 2657: (103-104): Assignment requires variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/bare_instructions_disallowed.sol",
    "content": "contract C {\n    function f() view public {\n        assembly {\n            address\n            pop\n        }\n    }\n}\n// ----\n// ParserError 6913: (95-98): Call or assignment expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/calldata_array.sol",
    "content": "contract C {\n    function f(uint[] calldata bytesAsCalldata) external {\n        assembly {\n            let x := bytesAsCalldata\n        }\n    }\n}\n// ----\n// TypeError 1397: (112-127): Call data elements cannot be accessed directly. Use \".offset\" and \".length\" to access the calldata offset and length of this array and then use \"calldatacopy\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/calldata_array_offset.sol",
    "content": "contract C {\n    function f(uint[] calldata bytesAsCalldata) external pure {\n        assembly {\n            let x := bytesAsCalldata.offset\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/calldata_slot.sol",
    "content": "contract C {\n    function f(bytes calldata bytesAsCalldata) external {\n        assembly {\n            let x := bytesAsCalldata.slot\n        }\n    }\n}\n// ----\n// TypeError 1536: (111-131): Calldata variables only support \".offset\" and \".length\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/calldata_variables.sol",
    "content": "contract C {\n    function f(bytes calldata bytesAsCalldata) external {\n        assembly {\n            let x := bytesAsCalldata\n        }\n    }\n}\n// ----\n// TypeError 1397: (111-126): Call data elements cannot be accessed directly. Use \".offset\" and \".length\" to access the calldata offset and length of this array and then use \"calldatacopy\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/const_forward_reference.sol",
    "content": "contract C {\n  function f() {\n    assembly {\n      c := add(add(1, 2), c)\n    }\n  }\n  int constant c = 0 + 1;\n}\n// ----\n// SyntaxError 4937: (15-83): No visibility specified. Did you intend to add \"public\"?\n// TypeError 2249: (71-72): Constant variables with non-literal values cannot be forward referenced from inline assembly.\n// TypeError 6252: (51-52): Constant variables cannot be assigned to.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/constant_access.sol",
    "content": "contract test {\n    uint constant x = 1;\n    function f() public pure {\n        assembly {\n            let y := x\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/constant_assignment.sol",
    "content": "contract test {\n    uint constant x = 1;\n    function f() public {\n        assembly {\n            x := 2\n        }\n    }\n}\n// ----\n// TypeError 6252: (98-99): Constant variables cannot be assigned to.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/constant_length_access.sol",
    "content": "contract Test {\n\tuint constant x = 2;\n\tfunction f() public pure {\n\t\tassembly {\n\t\t\tlet y := x.length\n\t\t}\n\t}\n}\n// ----\n// TypeError 3622: (91-99): The suffix \".length\" is not supported by this variable or type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/constant_variable_via_offset.sol",
    "content": "contract test {\n    uint constant x = 2;\n    function f() pure public {\n        assembly {\n            let r := x.offset\n        }\n    }\n}\n// ----\n// TypeError 6617: (112-120): The suffixes .offset and .slot can only be used on non-constant storage or transient storage variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/dot_in_fun_param.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function f(a., x.b) -> t.b, b.. {}\n    }\n  }\n}\n// ----\n// DeclarationError 3927: (74-76): User-defined identifiers in inline assembly cannot contain '.'.\n// DeclarationError 3927: (78-81): User-defined identifiers in inline assembly cannot contain '.'.\n// DeclarationError 3927: (86-89): User-defined identifiers in inline assembly cannot contain '.'.\n// DeclarationError 3927: (91-94): User-defined identifiers in inline assembly cannot contain '.'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/dot_in_fundecl.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function f.() {}\n      function g.f() {}\n    }\n  }\n}\n// ----\n// DeclarationError 3927: (63-79): User-defined identifiers in inline assembly cannot contain '.'.\n// DeclarationError 3927: (86-103): User-defined identifiers in inline assembly cannot contain '.'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/dot_in_multi_vardecl.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function f() -> x, y, z {}\n      let a., aa.b := f()\n    }\n  }\n}\n// ----\n// DeclarationError 3927: (100-102): User-defined identifiers in inline assembly cannot contain '.'.\n// DeclarationError 3927: (104-108): User-defined identifiers in inline assembly cannot contain '.'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/dot_in_vardecl.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let a. := 2\n      let a.. := 2\n      let a.b := 2\n      let a..b := 2\n    }\n  }\n}\n// ----\n// DeclarationError 3927: (67-69): User-defined identifiers in inline assembly cannot contain '.'.\n// DeclarationError 3927: (85-88): User-defined identifiers in inline assembly cannot contain '.'.\n// DeclarationError 3927: (104-107): User-defined identifiers in inline assembly cannot contain '.'.\n// DeclarationError 3927: (123-127): User-defined identifiers in inline assembly cannot contain '.'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/dup_disallowed.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            dup0()\n            dup1()\n            dup2()\n            dup3()\n            dup4()\n            dup5()\n            dup6()\n            dup7()\n            dup8()\n            dup9()\n            dup10()\n            dup11()\n            dup12()\n            dup13()\n            dup14()\n            dup15()\n            dup16()\n            dup32()\n        }\n    }\n}\n// ----\n// DeclarationError 4619: (75-79): Function \"dup0\" not found.\n// DeclarationError 4619: (94-98): Function \"dup1\" not found.\n// DeclarationError 4619: (113-117): Function \"dup2\" not found.\n// DeclarationError 4619: (132-136): Function \"dup3\" not found.\n// DeclarationError 4619: (151-155): Function \"dup4\" not found.\n// DeclarationError 4619: (170-174): Function \"dup5\" not found.\n// DeclarationError 4619: (189-193): Function \"dup6\" not found.\n// DeclarationError 4619: (208-212): Function \"dup7\" not found.\n// DeclarationError 4619: (227-231): Function \"dup8\" not found.\n// DeclarationError 4619: (246-250): Function \"dup9\" not found.\n// DeclarationError 4619: (265-270): Function \"dup10\" not found.\n// DeclarationError 4619: (285-290): Function \"dup11\" not found.\n// DeclarationError 4619: (305-310): Function \"dup12\" not found.\n// DeclarationError 4619: (325-330): Function \"dup13\" not found.\n// DeclarationError 4619: (345-350): Function \"dup14\" not found.\n// DeclarationError 4619: (365-370): Function \"dup15\" not found.\n// DeclarationError 4619: (385-390): Function \"dup16\" not found.\n// DeclarationError 4619: (405-410): Function \"dup32\" not found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/empty_fun_arg_beginning.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function f(a, b) {}\n      f()\n      f(,1)\n    }\n  }\n}\n// ----\n// ParserError 1856: (101-102): Literal or identifier expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/empty_fun_arg_end.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function f(a, b) {}\n      f()\n      f(1,)\n    }\n  }\n}\n// ----\n// ParserError 1856: (103-104): Literal or identifier expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/empty_fun_arg_middle.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function f(a, b, c) {}\n      f(1,,1)\n    }\n  }\n}\n// ----\n// ParserError 1856: (96-97): Literal or identifier expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/empty_function_name.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function (a, b) {}\n    }\n  }\n}\n// ----\n// ParserError 2314: (72-73): Expected identifier but got '('\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/eof/eof_builtins_disallowed.sol",
    "content": "contract C {\n    function f() view public {\n        assembly {\n            eofcreate(\"a\", 0, 0, 0, 0)\n            returncontract(\"a\", 0)\n            auxdataloadn(0)\n        }\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// DeclarationError 7223: (75-84): Builtin function \"eofcreate\" is only available in EOF.\n// DeclarationError 7223: (114-128): Builtin function \"returncontract\" is only available in EOF.\n// DeclarationError 7223: (149-161): Builtin function \"auxdataloadn\" is only available in EOF.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/eof/eof_builtins_disallowed_in_inline_assembly.sol",
    "content": "// TODO: They should be available in some way in the context of inline assembly. For now it's disallowed them.\ncontract C {\n    function f() view public {\n        assembly {\n            eofcreate(\"a\", 0, 0, 0, 0)\n            returncontract(\"a\", 0)\n            auxdataloadn(0)\n        }\n    }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n// DeclarationError 4619: (186-195): Function \"eofcreate\" not found.\n// DeclarationError 4619: (225-239): Function \"returncontract\" not found.\n// DeclarationError 4619: (260-272): Function \"auxdataloadn\" not found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/external_function_pointer_offset.sol",
    "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tuint myOffset;\n\n\t\tassembly {\n\t\t\tmyOffset := fp.offset\n\t\t}\n\t}\n}\n// ----\n// TypeError 9272: (173-182): Variables of type function pointer only support \".selector\" and \".address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/identifier_starting_with_dot.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let a, .a, aa.b := f()\n    }\n  }\n}\n// ----\n// ParserError 2314: (70-71): Expected identifier but got '.'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/illegal_names.sol",
    "content": "contract C {\n    function f() public {\n        // reserved function names\n        assembly {\n            function this() {\n            }\n            function super() {\n            }\n            function _() {\n            }\n        }\n\n        // reserved names as function argument\n        assembly {\n            function a(this) {\n            }\n            function b(super) {\n            }\n            function c(_) {\n            }\n        }\n\n        // reserved names as function return parameter\n        assembly {\n            function d() -> this {\n            }\n            function g() -> super {\n            }\n            function c() -> _ {\n            }\n        }\n\n        // reserved names as variable declaration\n        assembly {\n            let this := 1\n            let super := 1\n            let _ := 1\n        }\n    }\n}\n// ----\n// DeclarationError 4113: (105-136): The identifier name \"this\" is reserved.\n// DeclarationError 4113: (149-181): The identifier name \"super\" is reserved.\n// DeclarationError 4113: (194-222): The identifier name \"_\" is reserved.\n// DeclarationError 4113: (323-327): The identifier name \"this\" is reserved.\n// DeclarationError 4113: (368-373): The identifier name \"super\" is reserved.\n// DeclarationError 4113: (414-415): The identifier name \"_\" is reserved.\n// DeclarationError 4113: (546-550): The identifier name \"this\" is reserved.\n// DeclarationError 4113: (595-600): The identifier name \"super\" is reserved.\n// DeclarationError 4113: (645-646): The identifier name \"_\" is reserved.\n// DeclarationError 4113: (759-763): The identifier name \"this\" is reserved.\n// DeclarationError 3859: (759-763): This declaration shadows a declaration outside the inline assembly block.\n// DeclarationError 4113: (785-790): The identifier name \"super\" is reserved.\n// DeclarationError 3859: (785-790): This declaration shadows a declaration outside the inline assembly block.\n// DeclarationError 4113: (812-813): The identifier name \"_\" is reserved.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/internal_function_pointer_address.sol",
    "content": "contract C {\n\tfunction testFunction() internal {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() internal fp = testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn testFunction.address;\n\t}\n}\n// ----\n// TypeError 8533: (193-203): Only Variables of type external function pointer support \".selector\" and \".address\".\n// TypeError 9582: (267-287): Member \"address\" not found or not visible after argument-dependent lookup in function ().\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/internal_function_pointer_selector.sol",
    "content": "contract C {\n\tfunction testFunction() internal {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() internal fp = testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\treturn uint32(bytes4(bytes32(selectorValue)));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(testFunction.selector);\n\t}\n}\n// ----\n// TypeError 8533: (198-209): Only Variables of type external function pointer support \".selector\" and \".address\".\n// TypeError 9582: (329-350): Member \"selector\" not found or not visible after argument-dependent lookup in function ().\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/invalid_number.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let x := 0100\n    }\n  }\n}\n// ----\n// ParserError 1465: (72-73): Illegal token: Octal numbers not allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/jump_disallowed.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            jump(2)\n        }\n    }\n}\n// ----\n// DeclarationError 4619: (75-79): Function \"jump\" not found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/jumpdest_disallowed.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            jumpdest()\n        }\n    }\n}\n// ----\n// DeclarationError 4619: (75-83): Function \"jumpdest\" not found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/jumpi_disallowed.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            jumpi(2, 1)\n        }\n    }\n}\n// ----\n// DeclarationError 4619: (75-80): Function \"jumpi\" not found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/label_disallowed.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            label:\n        }\n    }\n}\n// ----\n// ParserError 6913: (80-81): Call or assignment expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/leave_items_on_stack.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            mload(0)\n        }\n    }\n}\n// ----\n// TypeError 3083: (75-83): Top-level expressions are not supposed to return values (this expression returns 1 value). Use ``pop()`` or assign them.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/literals_on_stack_disallowed.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            1\n        }\n    }\n}\n// ----\n// ParserError 6913: (85-86): Call or assignment expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/local_variable_access_out_of_functions.sol",
    "content": "contract test {\n    function f() public {\n        uint a;\n        assembly {\n            function g() -> x { x := a }\n        }\n    }\n}\n// ----\n// DeclarationError 6578: (114-115): Cannot access local Solidity variables from inside an inline assembly function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/local_variable_access_out_of_functions_storage_ptr.sol",
    "content": "contract test {\n    uint[] r;\n    function f() public {\n        uint[] storage a = r;\n        assembly {\n            function g() -> x { x := a.offset }\n        }\n    }\n}\n// ----\n// DeclarationError 6578: (142-150): Cannot access local Solidity variables from inside an inline assembly function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/missing_variable.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      x := 1\n    }\n  }\n}\n// ----\n// DeclarationError 4634: (63-64): Variable not found or variable not lvalue.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/missing_variable_in_assign.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let x := mload(0)\n      := 1\n    }\n  }\n}\n// ----\n// ParserError 1856: (87-89): Literal or identifier expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/multiple_assign_to_instruction.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function g() -> a,b, c {}\n      let a, sub, mov := g()\n    }\n  }\n}\n// ----\n// ParserError 5568: (102-105): Cannot use builtin function name \"sub\" as identifier name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/nested_function_local_access.sol",
    "content": "contract C {\n  function f() public pure returns (uint x) {\n    assembly {\n      function f1() {\n        function f2() { }\n        x := 2\n      }\n    }\n  }\n}\n// ----\n// DeclarationError 6578: (130-131): Cannot access local Solidity variables from inside an inline assembly function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/pc_disallowed.sol",
    "content": "contract C {\n\tfunction f() pure public {\n\t\tassembly {\n\t\t\tpop(pc())\n\t\t}\n\t}\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// SyntaxError 2450: (61-63): PC instruction is a low-level EVM feature. Because of that PC is disallowed in strict assembly.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/push_disallowed.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            push0()\n            push1()\n            push2()\n            push3()\n            push4()\n            push5()\n            push6()\n            push7()\n            push8()\n            push9()\n            push10()\n            push11()\n            push12()\n            push13()\n            push14()\n            push15()\n            push16()\n            push17()\n            push18()\n            push19()\n            push20()\n            push21()\n            push22()\n            push23()\n            push24()\n            push25()\n            push26()\n            push27()\n            push28()\n            push29()\n            push30()\n            push31()\n            push32()\n        }\n    }\n}\n// ----\n// DeclarationError 4619: (75-80): Function \"push0\" not found.\n// DeclarationError 4619: (95-100): Function \"push1\" not found.\n// DeclarationError 4619: (115-120): Function \"push2\" not found.\n// DeclarationError 4619: (135-140): Function \"push3\" not found.\n// DeclarationError 4619: (155-160): Function \"push4\" not found.\n// DeclarationError 4619: (175-180): Function \"push5\" not found.\n// DeclarationError 4619: (195-200): Function \"push6\" not found.\n// DeclarationError 4619: (215-220): Function \"push7\" not found.\n// DeclarationError 4619: (235-240): Function \"push8\" not found.\n// DeclarationError 4619: (255-260): Function \"push9\" not found.\n// DeclarationError 4619: (275-281): Function \"push10\" not found.\n// DeclarationError 4619: (296-302): Function \"push11\" not found.\n// DeclarationError 4619: (317-323): Function \"push12\" not found.\n// DeclarationError 4619: (338-344): Function \"push13\" not found.\n// DeclarationError 4619: (359-365): Function \"push14\" not found.\n// DeclarationError 4619: (380-386): Function \"push15\" not found.\n// DeclarationError 4619: (401-407): Function \"push16\" not found.\n// DeclarationError 4619: (422-428): Function \"push17\" not found.\n// DeclarationError 4619: (443-449): Function \"push18\" not found.\n// DeclarationError 4619: (464-470): Function \"push19\" not found.\n// DeclarationError 4619: (485-491): Function \"push20\" not found.\n// DeclarationError 4619: (506-512): Function \"push21\" not found.\n// DeclarationError 4619: (527-533): Function \"push22\" not found.\n// DeclarationError 4619: (548-554): Function \"push23\" not found.\n// DeclarationError 4619: (569-575): Function \"push24\" not found.\n// DeclarationError 4619: (590-596): Function \"push25\" not found.\n// DeclarationError 4619: (611-617): Function \"push26\" not found.\n// DeclarationError 4619: (632-638): Function \"push27\" not found.\n// DeclarationError 4619: (653-659): Function \"push28\" not found.\n// DeclarationError 4619: (674-680): Function \"push29\" not found.\n// DeclarationError 4619: (695-701): Function \"push30\" not found.\n// DeclarationError 4619: (716-722): Function \"push31\" not found.\n// DeclarationError 4619: (737-743): Function \"push32\" not found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_assignment.sol",
    "content": "contract test {\n    uint x = 1;\n    function f() public {\n        assembly {\n            x := 2\n        }\n    }\n}\n// ----\n// TypeError 1408: (89-90): Only local variables are supported. To access state variables, use the \".slot\" and \".offset\" suffixes.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_assignment_in_modifier.sol",
    "content": "contract test {\n    uint x = 1;\n    modifier m {\n        assembly {\n            x := 2\n        }\n        _;\n    }\n    function f() public m {\n    }\n}\n// ----\n// TypeError 1408: (80-81): Only local variables are supported. To access state variables, use the \".slot\" and \".offset\" suffixes.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_nonslot.sol",
    "content": "contract test {\n    uint x = 1;\n    function f() public {\n        assembly {\n            let t := x.length\n            x.length := 2\n        }\n    }\n}\n// ----\n// TypeError 4656: (98-106): State variables only support \".slot\" and \".offset\".\n// TypeError 4656: (119-127): State variables only support \".slot\" and \".offset\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/storage_variable_access_out_of_functions.sol",
    "content": "contract test {\n    uint a;\n    function f() pure public {\n        assembly {\n            function g() -> x { x := a.slot }\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/swap_disallowed.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            swap0()\n            swap1()\n            swap2()\n            swap3()\n            swap4()\n            swap5()\n            swap6()\n            swap7()\n            swap8()\n            swap9()\n            swap10()\n            swap11()\n            swap12()\n            swap13()\n            swap14()\n            swap15()\n            swap16()\n            swap32()\n        }\n    }\n}\n// ----\n// DeclarationError 4619: (75-80): Function \"swap0\" not found.\n// DeclarationError 4619: (95-100): Function \"swap1\" not found.\n// DeclarationError 4619: (115-120): Function \"swap2\" not found.\n// DeclarationError 4619: (135-140): Function \"swap3\" not found.\n// DeclarationError 4619: (155-160): Function \"swap4\" not found.\n// DeclarationError 4619: (175-180): Function \"swap5\" not found.\n// DeclarationError 4619: (195-200): Function \"swap6\" not found.\n// DeclarationError 4619: (215-220): Function \"swap7\" not found.\n// DeclarationError 4619: (235-240): Function \"swap8\" not found.\n// DeclarationError 4619: (255-260): Function \"swap9\" not found.\n// DeclarationError 4619: (275-281): Function \"swap10\" not found.\n// DeclarationError 4619: (296-302): Function \"swap11\" not found.\n// DeclarationError 4619: (317-323): Function \"swap12\" not found.\n// DeclarationError 4619: (338-344): Function \"swap13\" not found.\n// DeclarationError 4619: (359-365): Function \"swap14\" not found.\n// DeclarationError 4619: (380-386): Function \"swap15\" not found.\n// DeclarationError 4619: (401-407): Function \"swap16\" not found.\n// DeclarationError 4619: (422-428): Function \"swap32\" not found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/transient_storage_assignment.sol",
    "content": "contract test {\n    uint transient x;\n    function f() public {\n        assembly {\n            x := 2\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// TypeError 1408: (95-96): Only local variables are supported. To access state variables, use the \".slot\" and \".offset\" suffixes.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_negative_stack.sol",
    "content": "contract test {\n    function f() public {\n        assembly {\n            pop\n        }\n    }\n}\n// ----\n// ParserError 6913: (85-86): Call or assignment expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_positive_stack.sol",
    "content": "contract test {\n    function f() public {\n        assembly {\n            1\n        }\n    }\n}\n// ----\n// ParserError 6913: (83-84): Call or assignment expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_two_stack_load.sol",
    "content": "contract c {\n    uint8 x;\n    function f() public {\n        assembly { pop(x) }\n    }\n}\n// ----\n// TypeError 1408: (75-76): Only local variables are supported. To access state variables, use the \".slot\" and \".offset\" suffixes.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/variable_declaration_suffix_offset.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            let x.offset := 1\n            let x.slot := 1\n        }\n    }\n}\n// ----\n// DeclarationError 3927: (79-87): User-defined identifiers in inline assembly cannot contain '.'.\n// DeclarationError 3927: (109-115): User-defined identifiers in inline assembly cannot contain '.'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/whitespace_in_assignment.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let x : = mload(0)\n    }\n  }\n}\n// ----\n// ParserError 2314: (71-72): Expected identifier but got '='\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid/whitespace_in_multiple_assignment.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function g() -> a,b, c {}\n      let x, y ,z : = g()\n    }\n  }\n}\n// ----\n// ParserError 2314: (109-110): Expected identifier but got '='\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/invalid_natspec.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\t/// @test test\n\t\tassembly {}\n\t\t/// @solidity test\n\t\tassembly {}\n\t\t/// @param\n\t\tassembly {}\n\t}\n}\n// ----\n// Warning 6269: (60-71): Unexpected NatSpec tag \"test\" with value \"test\" in inline assembly.\n// Warning 8787: (95-106): Unexpected value for @solidity tag in inline assembly: test\n// Warning 7828: (122-133): Inline assembly has invalid NatSpec documentation.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/leave.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function f() {\n        leave\n      }\n    }\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/leave_invalid.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      leave\n    }\n  }\n}\n// ----\n// SyntaxError 8149: (63-68): Keyword \"leave\" can only be used inside a function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/linkersymbol_builtin.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      pop(linkersymbol(\"contract/library.sol:L\"))\n    }\n  }\n}\n// ----\n// DeclarationError 4619: (67-79): Function \"linkersymbol\" not found.\n// TypeError 3950: (67-105): Expected expression to evaluate to one value, but got 0 values instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/linkersymbol_function.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      function linkersymbol(a) {}\n\n      linkersymbol(\"contract/library.sol:L\")\n    }\n  }\n}\n// ----\n// DeclarationError 5017: (63-90): The identifier \"linkersymbol\" is reserved and can not be used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/mcopy.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            mcopy(0, 0, 0)\n            mcopy(0x1000, 0x2000, 100)\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/mcopy_pre_cancun.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            mcopy()\n        }\n    }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// TypeError 7755: (75-80): The \"mcopy\" instruction is only available for Cancun-compatible VMs (you are currently compiling for \"shanghai\").\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/mcopy_reserved_cancun.sol",
    "content": "contract C {\n    function f() public pure returns (uint result) {\n        assembly {\n            let mcopy := 1\n            result := mcopy\n        }\n    }\n\n    function g() public pure returns (uint result) {\n        assembly {\n            function mcopy() -> r {\n                r := 1000\n            }\n            result := mcopy()\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// ParserError 5568: (101-106): Cannot use builtin function name \"mcopy\" as identifier name.\n// ParserError 7104: (134-139): Builtin function \"mcopy\" must be called.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/memory_safe_dialect_string_and_comment.sol",
    "content": "function f() pure {\n    /// @solidity memory-safe-assembly\n    assembly \"evmasm\" (\"memory-safe\") {\n    }\n}\n// ----\n// Warning 8544: (63-104): Inline assembly marked as memory safe using both a NatSpec tag and an assembly block annotation. If you are not concerned with backwards compatibility, only use the assembly block annotation, otherwise only use the NatSpec tag.\n// Warning 2424: (63-104): Natspec memory-safe-assembly special comment for inline assembly is deprecated and scheduled for removal. Use the memory-safe block annotation instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/memory_safe_in_dialect_string.sol",
    "content": "function f() pure {\n    assembly \"evmasm\" (\"memory-safe\") {}\n}"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/natspec_memory_safe.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\t// @solidity memory-safe-assembly\n\t\tassembly {}\n\t}\n}"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/natspec_multi.sol",
    "content": "function f() pure {\n    /// @unrelated bogus-value\n\n    /// @before bogus-value\n    ///\n    /// @solidity a   memory-safe-assembly b    c\n    ///           d\n    /// @after bogus-value\n    assembly {}\n    /// @solidity memory-safe-assembly a a a\n    ///           memory-safe-assembly\n    assembly {}\n}\n// ----\n// Warning 6269: (189-200): Unexpected NatSpec tag \"after\" with value \"bogus-value\" in inline assembly.\n// Warning 6269: (189-200): Unexpected NatSpec tag \"before\" with value \"bogus-value\" in inline assembly.\n// Warning 8787: (189-200): Unexpected value for @solidity tag in inline assembly: a\n// Warning 2424: (189-200): Natspec memory-safe-assembly special comment for inline assembly is deprecated and scheduled for removal. Use the memory-safe block annotation instead.\n// Warning 8787: (189-200): Unexpected value for @solidity tag in inline assembly: b\n// Warning 8787: (189-200): Unexpected value for @solidity tag in inline assembly: c\n// Warning 8787: (189-200): Unexpected value for @solidity tag in inline assembly: d\n// Warning 2424: (289-300): Natspec memory-safe-assembly special comment for inline assembly is deprecated and scheduled for removal. Use the memory-safe block annotation instead.\n// Warning 8787: (289-300): Unexpected value for @solidity tag in inline assembly: a\n// Warning 4377: (289-300): Value for @solidity tag in inline assembly specified multiple times: a\n// Warning 4377: (289-300): Value for @solidity tag in inline assembly specified multiple times: memory-safe-assembly\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/natspec_multi_swallowed.sol",
    "content": "function f() pure {\n    /// @unrelated bogus-value\n\n    /// @before\n    ///\n    /// @solidity a   memory-safe-assembly b    c\n    ///           d\n    /// @after bogus-value\n    assembly {}\n    /// @solidity memory-safe-assembly a a a\n    ///           memory-safe-assembly\n    assembly {}\n}\n// ----\n// Warning 6269: (177-188): Unexpected NatSpec tag \"after\" with value \"bogus-value\" in inline assembly.\n// Warning 6269: (177-188): Unexpected NatSpec tag \"before\" with value \"@solidity a   memory-safe-assembly b    c           d\" in inline assembly.\n// Warning 2424: (277-288): Natspec memory-safe-assembly special comment for inline assembly is deprecated and scheduled for removal. Use the memory-safe block annotation instead.\n// Warning 8787: (277-288): Unexpected value for @solidity tag in inline assembly: a\n// Warning 4377: (277-288): Value for @solidity tag in inline assembly specified multiple times: a\n// Warning 4377: (277-288): Value for @solidity tag in inline assembly specified multiple times: memory-safe-assembly\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/no_unused_variable_warning.sol",
    "content": "contract C {\n    function f() pure public {\n        uint a;\n        assembly {\n            a := 1\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/overloaded_reference.sol",
    "content": "contract C {\n    function f() pure public {}\n    function f(address) pure public {}\n    function g() pure public {\n        assembly {\n            let x := f\n        }\n    }\n}\n// ----\n// DeclarationError 4718: (155-156): Multiple matching identifiers. Resolving overloaded identifiers is not supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/period_in_identifer.sol",
    "content": "contract C {\n    function f() pure public {\n        // Periods are part of identifiers in assembly,\n        // but not in Solidity. This tests that this scanner\n        // setting is properly reset early enough.\n        assembly { }\n        C.f();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/prevrandao_allowed_function_pre_paris.sol",
    "content": "contract C {\n    function f() public view returns (uint256 ret) {\n        assembly {\n            let prevrandao := sload(0)\n            ret := prevrandao\n        }\n    }\n\n    function g() public pure returns (uint256 ret) {\n        assembly {\n            function prevrandao() -> r {\n                r := 1000\n            }\n            ret := prevrandao()\n        }\n    }\n}\n// ====\n// EVMVersion: <paris\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/prevrandao_builtin_post_paris.sol",
    "content": "contract C {\n    function f() public view returns (uint256) {\n        return block.prevrandao;\n    }\n\n    function g() public view returns (uint256 ret) {\n        assembly {\n            ret := prevrandao()\n        }\n    }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/prevrandao_disallowed_function_post_paris.sol",
    "content": "contract C {\n    function f() public view returns (uint256 ret) {\n        assembly {\n            let prevrandao := sload(0)\n            ret := prevrandao\n        }\n    }\n\n    function g() public pure returns (uint256 ret) {\n        assembly {\n            function prevrandao() -> r {\n                r := 1000\n            }\n            ret := prevrandao()\n        }\n    }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// ParserError 5568: (101-111): Cannot use builtin function name \"prevrandao\" as identifier name.\n// ParserError 7104: (143-153): Builtin function \"prevrandao\" must be called.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/prevrandao_magic_block_warn_pre_paris.sol",
    "content": "contract C {\n    function f() public view returns (uint256) {\n        return block.prevrandao;\n    }\n}\n// ====\n// EVMVersion: <paris\n// ----\n// Warning 9432: (77-93): \"prevrandao\" is not supported by the VM version and will be treated as \"difficulty\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/prevrandao_nobuitin_pre_paris.sol",
    "content": "contract C {\n    function f() public {\n        assembly {\n            pop(prevrandao())\n        }\n    }\n}\n// ====\n// EVMVersion: <paris\n// ----\n// DeclarationError 4619: (74-84): Function \"prevrandao\" not found.\n// TypeError 3950: (74-86): Expected expression to evaluate to one value, but got 0 values instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/push0_disallowed.sol",
    "content": "// Ok\ncontract push0 {}\n\ncontract A {\n    // Ok, warning about shadowing\n    function push0() external {}\n}\n\ncontract C {\n    function f() external {\n        assembly {\n            // Not okay\n            push0()\n        }\n    }\n}\n// ----\n// Warning 2519: (77-105): This declaration shadows an existing declaration.\n// DeclarationError 4619: (205-210): Function \"push0\" not found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/reserved_identifiers.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let linkersymbol := 1\n      let datacopy := 1\n      let swap16 := 1\n    }\n  }\n}\n// ----\n// DeclarationError 5017: (67-79): The identifier \"linkersymbol\" is reserved and can not be used.\n// DeclarationError 5017: (95-103): The identifier \"datacopy\" is reserved and can not be used.\n// DeclarationError 5017: (119-125): The identifier \"swap16\" is reserved and can not be used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/reserved_identifiers_byzantium.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let shl := 1\n    }\n    assembly {\n      pop(shl(1, 2))\n    }\n  }\n}\n// ====\n// EVMVersion: =byzantium\n// ----\n// DeclarationError 5017: (67-70): The identifier \"shl\" is reserved and can not be used.\n// TypeError 6612: (107-110): The \"shl\" instruction is only available for Constantinople-compatible VMs (you are currently compiling for \"byzantium\").\n// TypeError 3950: (107-116): Expected expression to evaluate to one value, but got 0 values instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/reserved_identifiers_constantinople.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      let shl := 1\n    }\n    assembly {\n      pop(shl(1, 2))\n    }\n  }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// ParserError 5568: (67-70): Cannot use builtin function name \"shl\" as identifier name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/returndatasize_as_variable_call_post_byzantium.sol.sol",
    "content": "contract C {\n    function f() public pure {\n        uint returndatasize;\n        returndatasize;\n        assembly {\n            let x := returndatasize()\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/returndatasize_as_variable_post_byzantium.sol",
    "content": "contract C {\n    function f() public pure {\n        uint returndatasize;\n        returndatasize;\n        assembly {\n            returndatasize := 2\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// ParserError 6272: (143-145): Cannot assign to builtin function \"returndatasize\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/returndatasize_as_variable_pre_byzantium.sol",
    "content": "contract C { function f() public pure { uint returndatasize; returndatasize; assembly { pop(returndatasize()) }}}\n// ====\n// EVMVersion: =homestead\n// ----\n// TypeError 4778: (92-106): The \"returndatasize\" instruction is only available for Byzantium-compatible VMs (you are currently compiling for \"homestead\").\n// TypeError 3950: (92-108): Expected expression to evaluate to one value, but got 0 values instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/returndatasize_as_variable_read_post_byzantium.sol.sol",
    "content": "contract C {\n    function f() public pure {\n        uint returndatasize;\n        returndatasize;\n        assembly {\n            let x := returndatasize\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// ParserError 7104: (137-151): Builtin function \"returndatasize\" must be called.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/argument.sol",
    "content": "contract C {\n    function f(uint a) public pure {\n        assembly {\n            let a := 1\n        }\n    }\n}\n// ----\n// DeclarationError 3859: (85-86): This declaration shadows a declaration outside the inline assembly block.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/constant.sol",
    "content": "contract C {\n    uint constant a;\n    function f() public pure {\n        assembly {\n            let a := 1\n        }\n    }\n}\n// ----\n// DeclarationError 3859: (100-101): This declaration shadows a declaration outside the inline assembly block.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/contract.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            let C := 1\n        }\n    }\n}\n// ----\n// DeclarationError 3859: (79-80): This declaration shadows a declaration outside the inline assembly block.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/function.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            let f := 1\n        }\n    }\n}\n// ----\n// DeclarationError 3859: (79-80): This declaration shadows a declaration outside the inline assembly block.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/global_function_by_opcode.sol",
    "content": "function mload() pure {}\ncontract C {\n    function g() public pure {\n        assembly {\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/local_function_by_opcode.sol",
    "content": "contract C {\n    function add(uint, uint) public pure returns (uint) { return 7; }\n    function g() public pure returns (uint x, uint y) {\n        x = add(1, 2);\n        assembly {\n            y := add(1, 2)\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/local_variable.sol",
    "content": "contract C {\n    function f() public pure {\n        uint a;\n        assembly {\n            let a := 1\n        }\n    }\n}\n// ----\n// DeclarationError 3859: (95-96): This declaration shadows a declaration outside the inline assembly block.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/name_clash_in_import.sol",
    "content": "==== Source: a ====\ncontract A\n{\n\tuint constant a = 42;\n}\n==== Source: b ====\nimport {A as b} from \"a\";\ncontract B {\n    function f() public pure {\n        assembly {\n            let b := 3\n            let b.a := 4\n        }\n    }\n}\n// ----\n// DeclarationError 3859: (b:105-106): This declaration shadows a declaration outside the inline assembly block.\n// DeclarationError 3927: (b:128-131): User-defined identifiers in inline assembly cannot contain '.'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/no_name_clash_in_import.sol",
    "content": "==== Source: a ====\ncontract A\n{\n\tuint constant a = 42;\n}\n==== Source: b ====\nimport {A as b} from \"a\";\ncontract B {\n    function f() public pure {\n        assembly {\n            let A := 1\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/qualified_names.sol",
    "content": "contract D {\n    uint constant a;\n}\ncontract C {\n    function f() public pure {\n        assembly {\n            let D.a := 1\n            let D.b := 1 // shadowing the prefix only is also an error\n        }\n    }\n}\n// ----\n// DeclarationError 3927: (115-118): User-defined identifiers in inline assembly cannot contain '.'.\n// DeclarationError 3927: (140-143): User-defined identifiers in inline assembly cannot contain '.'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/state_variable_by_opcode.sol",
    "content": "contract C {\n    uint mload;\n    function g() public pure {\n        assembly {\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/shadowing/variable_by_opcode.sol",
    "content": "contract C {\n    function f() public pure {\n        uint mload;\n    }\n    function g() public pure {\n        uint mload;\n        assembly {\n        }\n    }\n}\n// ----\n// Warning 2072: (52-62): Unused local variable.\n// Warning 2072: (109-119): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/solidity_keywords.sol",
    "content": "contract C {\n  function f() view public {\n    assembly {\n  // These are keywords of Solidity -- a copy from liblangutil/Token.h.\n  let abstract := 1\n  let anonymous := 1\n  let as := 1\n  let assembly := 1\n  // break is Yul keyword\n  let catch := 1\n  let constant := 1\n  let constructor := 1\n  // continue is Yul keyword\n  let contract := 1\n  let do := 1\n  let else := 1\n  let enum := 1\n  let emit := 1\n  let event := 1\n  let external := 1\n  let fallback := 1\n  // for is a Yul keyword\n  // function is a Yul keyword\n  // hex is a Yul keyword\n  // if is a Yul keyword\n  let indexed := 1\n  let interface := 1\n  let internal := 1\n  let immutable := 1\n  let import := 1\n  let is := 1\n  let library := 1\n  let mapping := 1\n  let memory := 1\n  let modifier := 1\n  let new := 1\n  let override := 1\n  let payable := 1\n  let public := 1\n  let pragma := 1\n  let private := 1\n  let pure := 1\n  let receive := 1\n  // return is a builtin in EVMDialect\n  return(0, 0)\n  let returns := 1\n  let storage := 1\n  let calldata := 1\n  let struct := 1\n  let throw := 1\n  let try := 1\n  // type shadows the Solidity function\n  let unicode := 1\n  let using := 1\n  let view := 1\n  let virtual := 1\n  let while := 1\n  let wei := 1\n  let gwei := 1\n  let ether := 1\n  let seconds := 1\n  let minutes := 1\n  let hours := 1\n  let days := 1\n  let weeks := 1\n  let years := 1\n  let int := 1\n  let uint := 1\n  let bytes := 1\n  // byte is a builtin in EVMDialect\n  pop(byte(1, 1))\n  let string := 1\n  // address is a builtin in EVMDialect\n  pop(address())\n  let bool := 1\n  let fixed := 1\n  let ufixed := 1\n  let after := 1\n  let alias := 1\n  let apply := 1\n  let auto := 1\n  // case is a Yul keyword\n  let copyof := 1\n  // default is a Yul keyword\n  let define := 1\n  let final := 1\n  let implements := 1\n  let in := 1\n  let inline := 1\n  // let is a Yul keyword\n  let macro := 1\n  let match := 1\n  let mutable := 1\n  let null := 1\n  let of := 1\n  let partial := 1\n  let promise := 1\n  let reference := 1\n  let relocatable := 1\n  let sealed := 1\n  let sizeof := 1\n  let static := 1\n  let supports := 1\n  // switch is a Yul keyword\n  let typedef := 1\n  let typeof := 1\n  let unchecked := 1\n  let var := 1\n    }\n  }\n}\n// ----\n// Warning 5740: (955-2168): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/storage_reference.sol",
    "content": "contract C {\n    uint[] x;\n    fallback() external {\n        uint[] storage y = x;\n        assembly {\n            pop(y)\n        }\n    }\n}\n// ----\n// TypeError 9068: (118-119): You have to use the \".slot\" or \".offset\" suffix to access storage reference variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/storage_reference_assignment.sol",
    "content": "contract C {\n    uint[] x;\n    fallback() external {\n        uint[] storage y = x;\n        assembly {\n            y.slot := 1\n            y.offset := 2\n        }\n    }\n}\n// ----\n// TypeError 9739: (138-146): Only .slot can be assigned to.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/storage_reference_assignment_statevar.sol",
    "content": "contract C {\n    uint[] x;\n    fallback() external {\n        assembly {\n            x.slot := 1\n            x.offset := 2\n        }\n    }\n}\n// ----\n// TypeError 4713: (84-90): State variables cannot be assigned to - you have to use \"sstore()\" or \"tstore()\".\n// TypeError 4713: (108-116): State variables cannot be assigned to - you have to use \"sstore()\" or \"tstore()\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/storage_reference_empty_offset.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            let x := .offset\n        }\n    }\n}\n// ----\n// ParserError 1856: (84-85): Literal or identifier expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/storage_reference_empty_slot.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            let x := .slot\n        }\n    }\n}\n// ----\n// ParserError 1856: (84-85): Literal or identifier expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/storage_reference_fine.sol",
    "content": "contract C {\n    uint[] x;\n    fallback() external {\n        uint[] storage y = x;\n        assembly {\n            pop(y.slot)\n            pop(y.offset)\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/storage_reference_old.sol",
    "content": "contract C {\n    uint[] x;\n    fallback() external {\n        uint[] storage y = x;\n        assembly {\n            pop(y_slot)\n            pop(y_offset)\n        }\n    }\n}\n// ----\n// DeclarationError 9467: (118-124): Identifier not found. Use \".slot\" and \".offset\" to access storage or transient storage variables.\n// DeclarationError 9467: (142-150): Identifier not found. Use \".slot\" and \".offset\" to access storage or transient storage variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/storage_reference_old_shadow.sol",
    "content": "contract C {\n    uint[] x;\n    fallback() external {\n        uint y_slot = 2;\n        uint y_offset = 3;\n        uint[] storage y = x;\n        assembly {\n            pop(y_slot)\n            pop(y_offset)\n        }\n        y[0] = 2;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/storage_reference_on_function.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            let x := f.slot\n        }\n    }\n}\n// ----\n// TypeError 7944: (84-90): The suffixes \".offset\", \".slot\" and \".length\" can only be used with variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/storage_reference_on_memory.sol",
    "content": "contract C {\n    uint[] x;\n    fallback() external {\n        uint[] memory y = x;\n        assembly {\n            pop(y.slot)\n            pop(y.offset)\n        }\n    }\n}\n// ----\n// TypeError 3622: (117-123): The suffix \".slot\" is not supported by this variable or type.\n// TypeError 3622: (141-149): The suffix \".offset\" is not supported by this variable or type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/storage_slot_assign.sol",
    "content": "contract C {\n    uint[] x;\n    fallback() external {\n        uint[] storage y = x;\n        assembly {\n            y.slot := 1\n            y.offset := 2\n        }\n    }\n}\n// ----\n// TypeError 9739: (138-146): Only .slot can be assigned to.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/string_literal_switch_case.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly {\n      switch calldataload(0)\n      case \"1\" {}\n      case \"2\" {}\n    }\n  }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/tload_reserved_cancun.sol",
    "content": "contract C {\n    function f() public view returns (uint ret) {\n        assembly {\n            let tload := sload(0)\n            ret := tload\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// ParserError 5568: (98-103): Cannot use builtin function name \"tload\" as identifier name.\n// ParserError 7104: (135-140): Builtin function \"tload\" must be called.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/transient_storage_invalid_pre_cancun.sol",
    "content": "contract C {\n    function f() public {\n        assembly {\n            tstore(0, 13)\n            tload(0)\n        }\n    }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// TypeError 6243: (70-76): The \"tstore\" instruction is only available for Cancun-compatible VMs (you are currently compiling for \"shanghai\").\n// TypeError 6243: (96-101): The \"tload\" instruction is only available for Cancun-compatible VMs (you are currently compiling for \"shanghai\").\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/transient_storage_opcodes.sol",
    "content": "contract C {\n    function f() external returns(uint a) {\n        assembly {\n            tstore(0, 13)\n            a := tload(0)\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// Warning 2394: (88-94): 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.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/transient_storage_value_assignment_statevar.sol",
    "content": "contract C {\n    uint transient x;\n    fallback() external {\n        assembly {\n            x.slot := 1\n            x.offset := 2\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// TypeError 4713: (92-98): State variables cannot be assigned to - you have to use \"sstore()\" or \"tstore()\".\n// TypeError 4713: (116-124): State variables cannot be assigned to - you have to use \"sstore()\" or \"tstore()\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/tstore_reserved_cancun.sol",
    "content": "contract C {\n    function f() public view returns (uint ret) {\n        assembly {\n            let tstore := sload(0)\n            ret := tstore\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// ParserError 5568: (98-104): Cannot use builtin function name \"tstore\" as identifier name.\n// ParserError 7104: (136-142): Builtin function \"tstore\" must be called.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/tstore_warning_only_once_multiple_contracts.sol",
    "content": "contract C {\n    function f() external {\n        assembly {\n            tstore(0, 0)\n            let a := tload(0)\n            tstore(0, 1)\n            tstore(1, a)\n        }\n    }\n}\n\ncontract D {\n    function g() external {\n        assembly {\n            tstore(0, 0)\n            tstore(0, 1)\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// Warning 2394: (72-78): 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.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/tstore_warning_only_once_multiple_sources.sol",
    "content": "==== Source: A ====\ncontract C {\n    function f() external {\n        assembly {\n            tstore(0, 0)\n            let a := tload(0)\n            tstore(0, 1)\n            tstore(1, a)\n        }\n    }\n}\n==== Source: B ====\nimport {C as C} from \"A\";\ncontract D {\n    function g() external {\n        assembly {\n            tstore(0, 0)\n            tstore(0, 1)\n        }\n    }\n}\n==== Source: C ====\ncontract X {\n    function h() external {\n        assembly {\n            tstore(0, 0)\n            tstore(0, 0)\n        }\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// Warning 2394: (A:72-78): 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.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/two_stack_slot_access.sol",
    "content": "contract C {\n    function f() pure external {\n        function() external two_stack_slots;\n        assembly {\n            let x :=  two_stack_slots\n        }\n    }\n}\n// ----\n// TypeError 9857: (132-147): Only types that use one stack slot are supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/two_stack_slots.sol",
    "content": "contract C {\n    function f() pure external {\n        function() external two_stack_slots;\n        assembly {\n            let x :=  two_stack_slots\n        }\n    }\n}\n// ----\n// TypeError 9857: (132-147): Only types that use one stack slot are supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/use_msize_with_optimizer.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            let x := msize()\n        }\n    }\n}\n// ====\n// optimize-yul: true\n// ----\n// SyntaxError 6553: (52-101): The msize instruction cannot be used when the Yul optimizer is activated because it can change its semantics. Either disable the Yul optimizer or do not use the instruction.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/use_msize_without_optimizer.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            let x := msize()\n        }\n    }\n}\n// ====\n// optimize-yul: false\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/inlineAssembly/verbatim_disallowed.sol",
    "content": "contract C {\n    function f() pure public {\n        assembly {\n            let x := verbatim_1o(hex\"6001\")\n        }\n    }\n}\n// ====\n// optimize-yul: true\n// ----\n// DeclarationError 4619: (84-95): Function \"verbatim_1o\" not found.\n// DeclarationError 3812: (75-106): Variable count mismatch for declaration of \"x\": 1 variables and 0 values.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/isoltestTesting/stopAfterAnalysisError.sol",
    "content": "contract C {\n    function f(uint[] x) public pure {\n    }\n}\n// ====\n// stopAfter: analysis\n// ----\n// TypeError 6651: (28-36): Data location must be \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/isoltestTesting/stopAfterParsingAnalysisErrorNotShowing.sol",
    "content": "contract C {\n    uint x = address(0xabc);\n}\n// ====\n// stopAfter: parsing\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/isoltestTesting/stopAfterParsingError.sol",
    "content": "contract C {\n    uint storage x;\n}\n// ====\n// stopAfter:parsing\n// ----\n// ParserError 2314: (22-29): Expected identifier but got 'storage'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/large_storage_array_fine.sol",
    "content": "contract C {\n    uint[2**64 - 1] x;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/large_storage_array_mapping.sol",
    "content": "contract C {\n    mapping(uint => uint[2**100]) x;\n}\n// ----\n// Warning 7325: (17-46): Type uint256[1267650600228229401496703205376] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/large_storage_array_simple.sol",
    "content": "contract C {\n    uint[2**64] x;\n}\n// ----\n// Warning 7325: (17-28): Type uint256[18446744073709551616] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/large_storage_arrays_combined.sol",
    "content": "contract C {\n    uint[200][200][2**30][][2**30] x;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/large_storage_arrays_struct.sol",
    "content": "contract C {\n    struct S { uint[2**30] x; uint[2**50] y; }\n    S[2**20] x;\n}\n// ----\n// Warning 7325: (64-72): Type struct C.S[1048576] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/large_storage_structs.sol",
    "content": "contract C {\n    struct P { uint256[2**63] x; }\n\n    struct S0 {\n        P[101] x;\n        P y;\n    }\n    S0 s0;\n\n    struct S1 {\n        P x;\n        P[102] y;\n    }\n    S1 s1;\n\n    struct S2 {\n        mapping(uint => P[103]) x;\n        mapping(uint => P[103]) y;\n        mapping(uint => P[104]) z;\n        mapping(uint => S2) t;\n    }\n    S2 s2;\n\n    struct Q0\n    {\n        uint[1][][10**20 + 1] x;\n        uint[10**20 + 2][][1] y;\n        uint[][10**20 + 3] z;\n        uint[10**20 + 4][] t;\n    }\n    Q0 q0;\n\n    struct Q1\n    {\n        uint[1][][10**20 + 5] x;\n    }\n    Q1 q1;\n\n    struct Q2\n    {\n        uint[10**20 + 6][][1] y;\n    }\n    Q2 q2;\n\n    struct Q3\n    {\n        uint[][10**20 + 7] x;\n    }\n    Q3 q3;\n\n    struct Q4\n    {\n        uint[10**20 + 8][] y;\n    }\n    Q4 q4;\n}\n// ----\n// Warning 7325: (106-108): Type struct C.S0 covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (106-108): Type struct C.P[101] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (171-173): Type struct C.S1 covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (171-173): Type struct C.P[102] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (341-343): Type struct C.P[103] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (341-343): Type struct C.P[104] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (505-507): Type struct C.Q0 covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (505-507): Type uint256[1][][100000000000000000001] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (505-507): Type uint256[][100000000000000000003] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (505-507): Type uint256[100000000000000000004] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (505-507): Type uint256[100000000000000000002] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (576-578): Type struct C.Q1 covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (576-578): Type uint256[1][][100000000000000000005] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (647-649): Type uint256[100000000000000000006] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (715-717): Type struct C.Q3 covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (715-717): Type uint256[][100000000000000000007] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (783-785): Type uint256[100000000000000000008] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/max_size_array_with_transient_state_variables.sol",
    "content": "contract C {\n    uint[2**256 - 1] x;\n    uint transient y;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// Warning 3495: (0-60): This contract is very close to the end of storage. This limits its future upgradability.\n// Warning 7325: (17-33): Type uint256[115792089237316195423570985008687907853269984665640564039457584007913129639935] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/oversized_array_1d.sol",
    "content": "contract C {\n    uint[2**256] x;\n}\n// ----\n// TypeError 1847: (22-28): Array length too large, maximum is 2**256 - 1.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/oversized_array_2d.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >= 0.0;\ncontract C {\n    uint[2**255][2] a;\n}\n// ----\n// TypeError 7676: (60-97): Contract requires too much storage.\n// TypeError 1534: (77-94): Type too large for storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/oversized_contract.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >= 0.0;\ncontract C {\n    uint[2**255] a;\n    uint[2**255] b;\n}\n// ----\n// TypeError 7676: (60-114): Contract requires too much storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/oversized_contract_inheritance.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >= 0.0;\ncontract C {\n    uint[2**255] a;\n}\ncontract D is C {\n    uint[2**255] b;\n}\n// ----\n// TypeError 7676: (95-134): Contract requires too much storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/oversized_struct.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >= 0.0;\ncontract C {\n    struct S {\n        uint[2**255] a;\n        uint[2**255] b;\n    }\n    S s;\n}\n// ----\n// TypeError 7676: (60-152): Contract requires too much storage.\n// TypeError 1534: (146-149): Type too large for storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/largeTypes/storage_parameter.sol",
    "content": "contract C {\n    struct S { uint256[2**255] x; }\n    function f(S storage) internal {}\n}\n// ----\n// Warning 7325: (64-65): Type struct C.S covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n// Warning 7325: (64-65): Type uint256[57896044618658097711785492504343953926634992332820282019728792003956564819968] covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_AND.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0 AND GPL-2.0\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_OR.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0 OR GPL-2.0\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_bidi_marks.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\n// ‮0.3-LPG :reifitnedI-esneciL-XDPS‬\n// NOTE: The text above is reversed using Unicode directional marks. In raw form it would look like this:\n// <LRO>0.3-LPG :reifitnedI-esneciL-XDPS<PDF>\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_bottom.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\ncontract C {}\n// SPDX-License-Identifier: GPL-3.0\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_cr_endings.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\r// SPDX-License-Identifier: GPL-3.0\rcontract C {}\r"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_crlf_endings.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\r\n// SPDX-License-Identifier: GPL-3.0\r\ncontract C {}\r\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_double.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {}\n// SPDX-License-Identifier: MIT\n// ----\n// ParserError 3716: Multiple SPDX license identifiers found in source file. Use \"AND\" or \"OR\" to combine multiple licenses. Please see https://spdx.org for more information.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_double2.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\n// SPDX-License-Identifier: MIT\ncontract C {}\n// ----\n// ParserError 3716: Multiple SPDX license identifiers found in source file. Use \"AND\" or \"OR\" to combine multiple licenses. Please see https://spdx.org for more information.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_double3.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\n// SPDX-License-Identifier: GPL-3.0\ncontract C {}\n// ----\n// ParserError 3716: Multiple SPDX license identifiers found in source file. Use \"AND\" or \"OR\" to combine multiple licenses. Please see https://spdx.org for more information.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_double4.sol",
    "content": "/* SPDX-License-Identifier: GPL-3.0 OR GPL-2.0\nSPDX-License-Identifier: GPL-3.0 OR GPL-2.0 */\ncontract C {}\n// ----\n// ParserError 3716: Multiple SPDX license identifiers found in source file. Use \"AND\" or \"OR\" to combine multiple licenses. Please see https://spdx.org for more information.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_double5.sol",
    "content": "/* SPDX-License-Identifier: GPL-3.0 OR GPL-2.0 */ /* SPDX-License-Identifier: GPL-3.0 OR GPL-2.0 */\ncontract C {}\n// ----\n// ParserError 3716: Multiple SPDX license identifiers found in source file. Use \"AND\" or \"OR\" to combine multiple licenses. Please see https://spdx.org for more information.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_hidden_unicode.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0 ⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒\ncontract C {}\n// ----\n// ParserError 1114: Invalid SPDX license identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_in_contract.sol",
    "content": "contract C {\n// SPDX-License-Identifier: GPL-3.0\n}\n// ----\n// Warning 1878: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_in_import.sol",
    "content": "import \"// SPDX-License-Identifier: GPL-3.0\";\ncontract C {}\n// ----\n// Warning 1878: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n// ParserError 6275: (0-45): Source \"// SPDX-License-Identifier: GPL-3.0\" not found: File not supplied initially.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_in_string.sol",
    "content": "contract C {\n    bytes license = \"// SPDX-License-Identifier: GPL-3.0\";\n}\n// ----\n// Warning 1878: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing \"SPDX-License-Identifier: <SPDX-License>\" to each source file. Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. Please see https://spdx.org for more information.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_missing.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_missing_colon.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\n// SPDX-License-Identifier GPL-3.0\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_multiline.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\n/* SPDX-License-Identifier: GPL-3.0 */\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_natspec.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\n/// SPDX-License-Identifier: GPL-3.0\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_natspec_multiline.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\n/** SPDX-License-Identifier: GPL-3.0 */\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_no_whitespace.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\n//SPDX-License-Identifier:GPL-3.0\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_no_whitespace_multiline.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\n/*SPDX-License-Identifier:GPL-3.0*/\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_nonempty_line.sol",
    "content": "// This test is actually useless, as the test suite adds the automatic preamble.\npragma solidity >= 0.0; // SPDX-License-Identifier: GPL-3.0\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_unicode.sol",
    "content": "// SPDX-License-Identifier: ⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒\ncontract C {}\n// ----\n// ParserError 1114: Invalid SPDX license identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_whitespace_after_colon.sol",
    "content": "// SPDX-License-Identifier:    GPL-3.0\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_whitespace_before_spdx.sol",
    "content": "//     SPDX-License-Identifier: GPL-3.0\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/license/license_whitespace_trailing.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0   \n// NOTE: Trailing space at the end of the line above is intentional.\ncontract C {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/division_by_zero.sol",
    "content": "contract C {\n    uint constant a = 1 / 0;\n}\n// ----\n// TypeError 2271: (35-40): Built-in binary operator / cannot be applied to types int_const 1 and int_const 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex.sol",
    "content": "contract C {\n    uint constant a = 1 / ((1+3)-4);\n}\n// ----\n// TypeError 2271: (35-48): Built-in binary operator / cannot be applied to types int_const 1 and int_const 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex_compound.sol",
    "content": "contract A {\n    uint a;\n    constructor() { a /= (((2)*2)%4); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/division_by_zero_compound.sol",
    "content": "contract A {\n    uint a = 5;\n    constructor() { a /= uint(0); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/division_by_zero_nonliteral.sol",
    "content": "contract A {\n    constructor() { uint a; a / 0; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/exponent.sol",
    "content": "contract C {\n    function g() public pure {\n        int a;\n        a ** 1E1233;\n        a ** (1/2);\n    }\n}\n// ----\n// TypeError 2271: (67-78): Built-in binary operator ** cannot be applied to types int256 and int_const 1000...(1226 digits omitted)...0000. Exponent too large.\n// TypeError 2271: (88-98): Built-in binary operator ** cannot be applied to types int256 and rational_const 1 / 2. Exponent is fractional.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/exponent_fine.sol",
    "content": "contract C {\n    function f() public pure {\n        uint a;\n        a = a ** 1E5;\n        a = 0 ** 1E1233;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/literal_comparisons.sol",
    "content": "contract test {\n    function f(int8 x) public pure {\n        if (x == 1) {}\n        if (1 == x) {}\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/mod_zero.sol",
    "content": "contract C {\n    uint constant b3 = 1 % 0;\n}\n// ----\n// TypeError 2271: (36-41): Built-in binary operator % cannot be applied to types int_const 1 and int_const 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/mod_zero_complex.sol",
    "content": "contract C {\n    uint constant b3 = 1 % (-4+((2)*2));\n}\n// ----\n// TypeError 2271: (36-52): Built-in binary operator % cannot be applied to types int_const 1 and int_const 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/mod_zero_complex_compound.sol",
    "content": "contract A {\n    uint a = 5;\n    constructor() { a %= uint(((2)*2)%4); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/mod_zero_compound.sol",
    "content": "contract A {\n    uint a;\n    constructor() { a = 5; a %= 0; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literalOperations/mod_zero_nonliteral.sol",
    "content": "contract A {\n    constructor() { uint a; a % 0; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/hex_string_duplicate_underscore.sol",
    "content": "contract C {\n    function f() public pure {\n        hex\"12__34\";\n    }\n}\n// ----\n// ParserError 8936: (52-60): Invalid use of number separator '_'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/hex_string_duplicate_underscore_yul.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            let x := hex\"12__34\";\n        }\n    }\n}\n// ----\n// ParserError 1465: (84-92): Illegal token: Invalid use of number separator '_'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/hex_string_invalid_characters_yul.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            let x := hex\"abxy\";\n        }\n    }\n}\n// ----\n// ParserError 1465: (84-90): Illegal token: Expected even number of hex-nibbles.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/hex_string_leading_underscore.sol",
    "content": "contract C {\n    function f() public pure {\n        hex\"_1234\";\n    }\n}\n// ----\n// ParserError 8936: (52-57): Invalid use of number separator '_'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/hex_string_misaligned_underscore.sol",
    "content": "contract C {\n    function f() public pure {\n        hex\"1_234\";\n    }\n}\n// ----\n// ParserError 8936: (52-56): Expected even number of hex-nibbles.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/hex_string_trailing_underscore.sol",
    "content": "contract C {\n    function f() public pure {\n        hex\"1234_\";\n    }\n}\n// ----\n// ParserError 8936: (52-61): Invalid use of number separator '_'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/hex_string_underscores_valid.sol",
    "content": "contract C {\n    bytes constant c = hex\"12_3456_789012\";\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/invalid_hex_number.sol",
    "content": "contract C {\n    uint x = 0x1000abcdefgh;\n}\n// ----\n// ParserError 8936: (26-38): Identifier-start is not allowed at end of a number.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/invalid_octal_denomination_no_whitespace.sol",
    "content": "contract C {\n    uint y = 01gwei;\n}\n// ----\n// ParserError 8936: (26-27): Octal numbers not allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/invalid_octal_digits.sol",
    "content": "contract C {\n    uint y = 098;\n}\n// ----\n// ParserError 8936: (26-27): Octal numbers not allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/invalid_octal_number.sol",
    "content": "contract C {\n    uint x = 0100;\n}\n// ----\n// ParserError 8936: (26-27): Octal numbers not allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/ternary_operator_return_type_with_literal_arguments.sol",
    "content": "contract TestTernary\n{\n    function g() pure public\n    {\n        bool t = true;\n        bool f = false;\n        uint8 v255 = 255;\n        uint8 v63 = 63;\n        uint8 a;\n\n        // Currently none of these should produce errors or warnings.\n        // The result of the operator is always a limited-precision integer, even if all arguments are literals.\n\n        a = (t ? 63 : 255) + (f ? 63 : 255);\n        a = (t ? 0x3f : 0xff) + (f ? 0x3f : 0xff);\n        a = (t ? uint8(63) : 255) + (f ? 63 : uint8(255));\n        a = (t ? v63 : 255) + (f ? 63 : v255);\n\n        a = (true ? 63 : 255) + (false ? 63 : 255);\n        a = (true ? 0x3f : 0xff) + (false ? 0x3f : 0xff);\n        a = (true ? uint8(63) : 255) + (false ? 63 : uint8(255));\n        a = (true ? v63 : 255) + (false ? 63 : v255);\n\n        a = (t ? 63 : 255) - (f ? 63 : 255);\n        a = (t ? 63 : 255) * (f ? 63 : 255);\n        a = (t ? 63 : 255) / (f ? 63 : 255);\n\n        a = (t ? (true ? 63 : 255) : (false ? 63 : 255)) + (f ? (t ? 63 : 255) : (f ? 63 : 255));\n        a = uint8(t ? 63 : 255) + uint8(f ? 63 : 255);\n\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/unicode_string_direction_override_1.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // PDF\n        bytes memory s = unicode\"underflow ‬\";\n    }\n}\n// ----\n// ParserError 8936: (88-106): Unicode direction override underflow in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/unicode_string_direction_override_2.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // PDF PDF\n        bytes memory m = unicode\"underflow ‬‬\";\n    }\n}\n// ----\n// ParserError 8936: (92-110): Unicode direction override underflow in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/unicode_string_direction_override_3.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // RLO\n        bytes memory m = unicode\"overflow ‮\";\n    }\n}\n// ----\n// ParserError 8936: (88-108): Mismatching directional override markers in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/unicode_string_direction_override_4.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // RLO RLO\n        bytes memory m = unicode\"overflow ‮‮\";\n    }\n}\n// ----\n// ParserError 8936: (92-115): Mismatching directional override markers in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/unicode_string_direction_override_5.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // RLO PDF\n        bytes memory m = unicode\" ok ‮‬\";\n\n        // RLO RLO PDF PDF\n        m = unicode\" ok ‮‮‬‬\";\n\n        // RLO RLO RLO PDF PDF PDF\n        m = unicode\" ok ‮‮‮‬‬‬\";\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/unicode_string_direction_override_6.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // PDF RLO\n        bytes memory m = unicode\" underflow ‬‮\";\n    }\n}\n// ----\n// ParserError 8936: (92-111): Unicode direction override underflow in comment or string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/unicode_string_direction_override_7.sol",
    "content": "contract C {\n    function f() public pure\n    {\n        // LRO PDF RLO PDF\n        bytes memory m = unicode\"‭ ok ‬‮‬\";\n\n        // lre rle pdf pdf\n        m = unicode\"lre‪ rle‫ pdf‬ pdf‬\";\n        // lre lro pdf pdf\n        m = unicode\"lre‪ lro‭ pdf‬ pdf‬\";\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/literals/upper_case_hex_literals.sol",
    "content": "contract test {\n\n    function f() public pure returns (uint256) {\n        uint256 a = 0x1234aAbcC;\n        uint256 b = 0x1234ABCDEF;\n        return a + b;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/lvalues/calldata_index_access.sol",
    "content": "contract C {\n    function f(uint256[] calldata x) external pure {\n        x[0] = 42;\n    }\n}\n// ----\n// TypeError 6182: (74-78): Calldata arrays are read-only.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/lvalues/calldata_member_access.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    struct S { uint256 x; }\n    function f(S calldata s) external pure {\n        s.x = 42;\n    }\n}\n// ----\n// TypeError 4156: (128-131): Calldata structs are read-only.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/lvalues/external_reference_argument.sol",
    "content": "contract C {\n    function f(uint256[] calldata x, uint256[] calldata y) external pure {\n        x = y;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/lvalues/functions.sol",
    "content": "contract C {\n    function f() internal {\n    }\n    function g() internal {\n        g = f;\n    }\n    function h() external {\n    }\n    function i() external {\n        this.i = this.h;\n    }\n}\n// ----\n// TypeError 4247: (83-84): Expression has to be an lvalue.\n// TypeError 4247: (166-172): Expression has to be an lvalue.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/lvalues/library_mapping.sol",
    "content": "library L {\n    function f(mapping(uint=>uint) storage x, mapping(uint=>uint) storage y) external {\n        x = y;\n    }\n}\n// ----\n// TypeError 9214: (108-109): Types in storage containing (nested) mappings cannot be assigned to.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/lvalues/lvalue_not_set.sol",
    "content": "contract C {\n    function foo(uint x) public\n    {\n        // Used to cause an ICE\n        uint p = new uint[] = x;\n    }\n}\n// ----\n// TypeError 4247: (100-110): Expression has to be an lvalue.\n// TypeError 7407: (113-114): Type uint256 is not implicitly convertible to expected type function (uint256) pure returns (uint256[] memory).\n// TypeError 9574: (91-114): Type function (uint256) pure returns (uint256[] memory) is not implicitly convertible to expected type uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/lvalues/valid_lvalues.sol",
    "content": "contract C {\n    struct S { uint256 x; }\n\tfunction i() internal pure {}\n\tfunction e() external pure {}\n\tuint[] s1;\n    function f(uint x, bytes32 y) external {\n        x = 42;\n        y = bytes32(0);\n        (x, y) = (23, bytes32(0));\n        S memory ms1;\n        S memory ms2;\n        ms1 = ms2;\n        ms1.x = x;\n        uint256[] memory a = new uint256[](2);\n        uint256[] memory b = new uint256[](3);\n        a = b;\n        a[0] = x;\n        s1[0] = x;\n        s1 = a;\n    }\n    function g(function() internal pure x) internal view {\n        x = i;\n        function(uint, bytes32) external y;\n        y = this.f;\n    }\n    function g(function() external pure x) external view {\n        x = this.e;\n        function(function() internal pure) internal view y;\n        y = g;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/constructor_as_potential_library_member.sol",
    "content": "library L{ constructor() { L.x; } }\n// ----\n// TypeError 7634: (11-33): Constructor cannot be defined in libraries.\n// TypeError 9582: (27-30): Member \"x\" not found or not visible after argument-dependent lookup in type(library L).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/contract_not_payable_send.sol",
    "content": "contract C {\n    function f() public {\n        address(this).send(10);\n    }\n}\n\n// ----\n// TypeError 9862: (47-65): \"send\" and \"transfer\" are only available for objects of type \"address payable\", not \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/contract_not_payable_transfer.sol",
    "content": "contract C {\n    function f() public {\n        address(this).transfer(10);\n    }\n}\n\n// ----\n// TypeError 9862: (47-69): \"send\" and \"transfer\" are only available for objects of type \"address payable\", not \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/failed_function_lookup.sol",
    "content": "contract C {\n  function f(uint, uint) public {}\n  function f(uint) public {}\n  function g() public { f(1, 2, 3); }\n}\n// ----\n// TypeError 9322: (101-102): No matching declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/failed_function_lookup_in_library.sol",
    "content": "library L {\n  function f(uint, uint) public {}\n  function f(uint) public {}\n}\ncontract C {\n  function g() public { L.f(1, 2, 3); }\n}\n// ----\n// TypeError 9582: (115-118): Member \"f\" not found or not visible after argument-dependent lookup in type(library L).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/internal_function_type.sol",
    "content": "contract C {\n    function () internal returns (uint) x;\n    constructor() {\n        C.x = g;\n    }\n    function g() public pure returns (uint) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/member_not_unique.sol",
    "content": "contract C {\n    function a(uint256) public returns (uint) { return 1; }\n    function a(uint8) public returns (uint) { return 1; }\n\n    function f() public returns (C) { return this; }\n\n    function g() internal returns (function(uint8) internal returns(uint))\n    {\n        return f().a;\n    }\n}\n// ----\n// TypeError 6675: (282-287): Member \"a\" not unique after argument-dependent lookup in contract C.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/member_value_not_unique.sol",
    "content": "contract C {\n    function value(uint256) public returns (uint) { return 1; }\n    function value(uint8) public returns (uint) { return 1; }\n\n    function f() public returns (C) { return this; }\n\n    function g() internal returns (function(uint8) internal returns(uint))\n    {\n        return f().value;\n    }\n}\n// ----\n// TypeError 6675: (290-299): Member \"value\" not unique after argument-dependent lookup in contract C - did you forget the \"payable\" modifier?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/memory_structs_with_mapping_array_struct_array.sol",
    "content": "contract Test {\n\tstruct S1 { uint8 a; mapping(uint => uint)[] b1; uint8 c; }\n\tstruct S2 { uint8 a; S1[] b2; uint8 c; }\n\tS2 s2;\n    function f() public {\n        S2 memory x = s2;\n        x.b2.length;\n        x.b2[1].b1[2][3];\n    }\n}\n// ----\n// TypeError 4061: (161-172): Type struct Test.S2 memory is only valid in storage because it contains a (nested) mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/memory_structs_with_mappings.sol",
    "content": "contract Test {\n\tstruct S { uint8 a; mapping(uint => uint) b; uint8 c; }\n\tS s;\n\tfunction f() public {\n\t\tS memory x;\n\t}\n}\n// ----\n// TypeError 4061: (104-114): Type struct Test.S memory is only valid in storage because it contains a (nested) mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/msg_sender_non_payable_send.sol",
    "content": "contract C {\n    function f() public {\n        (msg.sender).send(10);\n    }\n}\n// ----\n// TypeError 9862: (47-64): \"send\" and \"transfer\" are only available for objects of type \"address payable\", not \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/msg_sender_non_payable_transfer.sol",
    "content": "contract C {\n    function f() public {\n        (msg.sender).transfer(10);\n    }\n}\n// ----\n// TypeError 9862: (47-68): \"send\" and \"transfer\" are only available for objects of type \"address payable\", not \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/msg_value_modifier_payable.sol",
    "content": "contract C {\n    modifier costs(uint _amount) { require(msg.value >= _amount); _; }\n    function f() costs(1 ether) public payable {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/msg_value_modifier_pure.sol",
    "content": "contract C {\n    modifier costs(uint _amount) { require(msg.value >= _amount); _; }\n    function f() costs(1 ether) public pure {}\n}\n// ----\n// TypeError 2527: (101-115): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires \"view\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/msg_value_modifier_view.sol",
    "content": "contract C {\n    modifier costs(uint _amount) { require(msg.value >= _amount); _; }\n    function f() costs(1 ether) public view {}\n}\n// ----\n// TypeError 4006: (101-115): This modifier uses \"msg.value\" or \"callvalue()\" and thus the function has to be payable or internal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/push_on_memory_types.sol",
    "content": "contract Test {\n\tfunction f() public pure {\n        uint[] memory x;\n        x.push(1);\n\t}\n}\n// ----\n// TypeError 4994: (77-83): Member \"push\" is not available in uint256[] memory outside of storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/tx_origin_non_payable_send.sol",
    "content": "contract C {\n    function f() public {\n        (tx.origin).send(10);\n    }\n}\n// ----\n// TypeError 9862: (47-63): \"send\" and \"transfer\" are only available for objects of type \"address payable\", not \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/tx_origin_non_payable_transfer.sol",
    "content": "contract C {\n    function f() public {\n        (tx.origin).transfer(10);\n    }\n}\n// ----\n// TypeError 9862: (47-67): \"send\" and \"transfer\" are only available for objects of type \"address payable\", not \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/memberLookup/unused_module_member_reference.sol",
    "content": "==== Source: s1.sol ====\nimport \"s1.sol\" as A;\n\nlibrary L {\n    function f() internal pure {}\n}\n\ncontract C\n{\n    function test() public pure {\n        A.L;\n    }\n}\n// ----\n// Warning 6133: (s1.sol:127-130): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/array_type_from_ternary.sol",
    "content": "contract C {\n    function f(bool c) public {\n        (c ? uint[2] : uint[2])[3];\n    }\n}\n// ----\n// TypeError 9717: (58-65): Invalid mobile type in true expression.\n// TypeError 3703: (68-75): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/codeAccess.sol",
    "content": "contract Test {\n    function creationOther() public pure returns (bytes memory) {\n        return type(Other).creationCode;\n    }\n    function runtimeOther() public pure returns (bytes memory) {\n        return type(Other).runtimeCode;\n    }\n}\ncontract Other {\n    function f(uint) public pure returns (uint) {}\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/codeAccessAbstractCreation.sol",
    "content": "contract Test {\n    function creationOther() public pure returns (bytes memory) {\n        return type(Other).creationCode;\n    }\n}\nabstract contract Other {\n    function f(uint) public returns (uint);\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// TypeError 9582: (97-121): Member \"creationCode\" not found or not visible after argument-dependent lookup in type(contract Other).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/codeAccessAbstractRuntime.sol",
    "content": "contract Test {\n    function runtime() public pure returns (bytes memory) {\n        return type(Other).runtimeCode;\n    }\n}\nabstract contract Other {\n    function f(uint) public returns (uint);\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// TypeError 9582: (91-114): Member \"runtimeCode\" not found or not visible after argument-dependent lookup in type(contract Other).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/codeAccessBase.sol",
    "content": "contract Base {\n    function f() public pure returns (uint) {}\n}\ncontract Test1 is Base {\n    function creation() public pure returns (bytes memory) {\n        return type(Test1).creationCode;\n    }\n}\ncontract Test2 is Base {\n    function runtime() public pure returns (bytes memory) {\n        return type(Test2).runtimeCode;\n    }\n}\ncontract Test3 is Base {\n    function creationBase() public pure returns (bytes memory) {\n        return type(Base).creationCode;\n    }\n}\ncontract Test4 is Base {\n    function runtimeBase() public pure returns (bytes memory) {\n        return type(Base).runtimeCode;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// TypeError 7813: (166-190): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (300-323): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/codeAccessCyclic.sol",
    "content": "contract A {\n    function f() public pure {\n        type(B).runtimeCode;\n    }\n}\ncontract B {\n    function f() public pure {\n        type(A).runtimeCode;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// TypeError 7813: (52-71): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (133-152): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/codeAccessIsConstant.sol",
    "content": "contract Test {\n    bytes constant c = type(B).creationCode;\n    bytes constant r = type(B).runtimeCode;\n\n}\ncontract B { function f() public pure {} }\n// ====\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/codeAccessLibrary.sol",
    "content": "contract Test {\n    function creationOther() public pure returns (bytes memory) {\n        return type(Library).creationCode;\n    }\n    function runtime() public pure returns (bytes memory) {\n        return type(Library).runtimeCode;\n    }\n}\ncontract Library {\n    function f(uint) public pure returns (uint) {}\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/codeAccess_super.sol",
    "content": "contract Other {\n    function f(uint) public pure returns (uint) {}\n}\ncontract SuperTest is Other {\n\tfunction creationSuper() public pure returns (bytes memory) {\n\t\treturn type(super).creationCode;\n\t}\n\tfunction runtimeOther() public pure returns (bytes memory) {\n\t\treturn type(super).runtimeCode;\n\t}\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// TypeError 4259: (177-182): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(contract super SuperTest) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/codeIsNoLValue.sol",
    "content": "contract Test {\n    function f() public pure {\n        type(C).creationCode = new bytes(6);\n        type(C).runtimeCode = new bytes(6);\n    }\n}\ncontract C {}\n// ====\n// bytecodeFormat: legacy\n// ----\n// TypeError 4247: (55-75): Expression has to be an lvalue.\n// TypeError 4247: (100-119): Expression has to be an lvalue.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/contract_from_ternary.sol",
    "content": "contract C {\n    function f() public pure { }\n    function g(bool c) public {\n        (c ? C : C).f();\n    }\n}\n// ----\n// TypeError 9717: (91-92): Invalid mobile type in true expression.\n// TypeError 3703: (95-96): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/contract_min.sol",
    "content": "contract Min {\n\tfunction contractMin() public {\n\t\ttype(Min).min;\n\t}\n}\n// ----\n// TypeError 9582: (50-63): Member \"min\" not found or not visible after argument-dependent lookup in type(contract Min).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/explicit_type_conversion.sol",
    "content": "contract C {\n    function f(bool c) pure public returns (int) {\n        return (c ? int : int)(0);\n    }\n}\n// ----\n// TypeError 9717: (84-87): Invalid mobile type in true expression.\n// TypeError 3703: (90-93): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/int_name.sol",
    "content": "contract test {\n\tfunction intName() public {\n\t\ttype(int).name;\n\t}\n}\n// ----\n// TypeError 9582: (47-61): Member \"name\" not found or not visible after argument-dependent lookup in type(int256).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/integer.sol",
    "content": "contract Test {\n    function basic() public pure {\n        uint uintMax = type(uint).max;\n        uintMax;\n        int intMax = type(int).max;\n        intMax;\n        uint uintMin = type(uint).min;\n        uintMin;\n        int intMin = type(int).min;\n        intMin;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/integer_err.sol",
    "content": "contract Test {\n    function assignment() public {\n        uint8 uint8Min = type(int).min;\n        uint uintMin = type(int).min;\n\n        if (type(int).min == 2**256 - 1) {\n            uintMin;\n        }\n\n    }\n}\n// ----\n// TypeError 9574: (59-89): Type int256 is not implicitly convertible to expected type uint8.\n// TypeError 9574: (99-127): Type int256 is not implicitly convertible to expected type uint256.\n// TypeError 2271: (142-169): Built-in binary operator == cannot be applied to types int256 and int_const 1157...(70 digits omitted)...9935.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/integer_pure.sol",
    "content": "contract test {\n\n    function viewAssignment() public view {\n        int min = type(int).min;\n        min;\n    }\n\n    function assignment() public {\n        int max = type(int).max;\n        max;\n    }\n\n}\n// ----\n// Warning 2018: (21-112): Function state mutability can be restricted to pure\n// Warning 2018: (118-200): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/interfaceid_super.sol",
    "content": "interface ERC165 {\n    /// @notice Query if a contract implements an interface\n    /// @param interfaceID The interface identifier, as specified in ERC-165\n    /// @dev Interface identification is specified in ERC-165. This function\n    ///  uses less than 30,000 gas.\n    /// @return `true` if the contract implements `interfaceID` and\n    ///  `interfaceID` is not 0xffffffff, `false` otherwise\n    function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract Test is ERC165 {\n    function hello() public pure returns (bytes4 data){\n        return type(super).interfaceID;\n    }\n}\n// ----\n// TypeError 4259: (592-597): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(contract super Test) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/library_from_ternary.sol",
    "content": "library L {\n    function f() public pure { }\n}\n\ncontract C {\n    function g(bool c) public {\n        (c ? L : L).f();\n    }\n}\n// ----\n// TypeError 9717: (106-107): Invalid mobile type in true expression.\n// TypeError 3703: (110-111): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/max_keyword_from_ternary_with_type_expression.sol",
    "content": "contract C {\n    function max(bool isUint) pure public returns (uint8) {\n        return (isUint ? type(uint8) : type(int8)).max;\n    }\n}\n// ----\n// TypeError 9717: (98-109): Invalid mobile type in true expression.\n// TypeError 3703: (112-122): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/name.sol",
    "content": "contract Test {\n    function f() public pure returns (string memory) {\n        return type(Test).name;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/name_constant.sol",
    "content": "contract C {\n  string public constant name = type(C).name;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/name_other_contract.sol",
    "content": "contract Test {\n    function f() public pure returns (string memory) {\n        return type(C).name;\n    }\n    function g() public pure returns (string memory) {\n        return type(A).name;\n    }\n    function h() public pure returns (string memory) {\n        return type(I).name;\n    }\n}\n\nabstract contract A {\n\tfunction f() virtual public pure;\n}\n\ninterface I {\n\tfunction f() external pure;\n}\n\ncontract C {\n    function f() pure public {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/noArgForType.sol",
    "content": "contract Test {\n    function creation() public pure returns (bytes memory) {\n        type();\n    }\n}\n// ----\n// TypeError 8885: (85-91): This function takes one argument, but 0 were provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/runtimeCodeWarningAssembly.sol",
    "content": "contract Test {\n    function f() public pure returns (uint) {\n        return type(C).runtimeCode.length +\n            type(D).runtimeCode.length +\n            type(C).creationCode.length +\n            type(D).creationCode.length;\n    }\n}\ncontract C {\n    constructor() { assembly {} }\n}\ncontract D is C {\n    constructor() {}\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 6417: (77-96): The constructor of the contract (or its base) uses inline assembly. Because of that, it might be that the deployed bytecode is different from type(...).runtimeCode.\n// Warning 6417: (118-137): The constructor of the contract (or its base) uses inline assembly. Because of that, it might be that the deployed bytecode is different from type(...).runtimeCode.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/runtimeCode_from_ternary_with_type_expression.sol",
    "content": "contract A {\n    function f() public {}\n}\n\ncontract B {\n    function g() public {}\n}\n\ncontract C {\n    function ab(bool getA) pure public returns (bytes memory) {\n        return (getA ? type(A) : type(B)).runtimeCode;\n    }\n}\n// ----\n// TypeError 9717: (186-193): Invalid mobile type in true expression.\n// TypeError 3703: (196-203): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/struct_from_ternary.sol",
    "content": "struct S {\n    uint x;\n    uint y;\n    uint z;\n}\n\ncontract C {\n    function f(bool c) public pure {\n        S memory s = (c ? S : S)(0, 1, 2);\n    }\n}\n// ----\n// TypeError 9717: (126-127): Invalid mobile type in true expression.\n// TypeError 3703: (130-131): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/super_name.sol",
    "content": "pragma abicoder v2;\n\nfunction compareStrings(string memory s1, string memory s2) returns (bool) {\n    return keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2));\n}\n\ncontract A {\n    string[] r;\n    function f() public virtual returns (bool) {\n        r.push(\"\");\n\n        return false;\n    }\n}\n\n\ncontract B is A {\n    function f() public virtual override returns (bool) {\n        super.f();\n        r.push(type(super).name);\n\n        return false;\n    }\n}\n\n\ncontract C is A {\n    function f() public virtual override returns (bool) {\n        super.f();\n        r.push(type(super).name);\n\n        return false;\n    }\n}\n\n\ncontract D is B, C {\n    function f() public override(B, C) returns (bool) {\n        super.f();\n        r.push(type(super).name);\n        // Order of calls: D.f, C.f, B.f, A.f\n        // r contains \"\", \"A\", \"B\", \"C\"\n        assert(r.length == 4);\n        assert(compareStrings(r[0], \"\"));\n        assert(compareStrings(r[1], \"A\"));\n        assert(compareStrings(r[2], \"B\"));\n        assert(compareStrings(r[3], \"C\"));\n\n        return true;\n    }\n}\n// ----\n// TypeError 4259: (426-431): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(contract super B) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/tooManyArgsForType.sol",
    "content": "contract Test {\n    function creation() public pure returns (bytes memory) {\n        type(1, 2);\n    }\n}\n// ----\n// TypeError 8885: (85-95): This function takes one argument, but 2 were provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/typeNotRegularIdentifierContractName.sol",
    "content": "contract type { }\n// ----\n// ParserError 2314: (9-13): Expected identifier but got 'type'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/typeNotRegularIdentifierFunction.sol",
    "content": "contract Test {\n    function type() public pure {\n    }\n}\n// ----\n// ParserError 2314: (29-33): Expected identifier but got 'type'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/typeNotRegularIdentifierParameter.sol",
    "content": "contract Test {\n    function f(uint type) public pure {\n    }\n}\n// ----\n// ParserError 2314: (36-40): Expected ',' but got 'type'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/typeNotRegularIdentifierStateVariable.sol",
    "content": "contract Test {\n    uint type;\n}\n// ----\n// ParserError 2314: (25-29): Expected identifier but got 'type'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/typeNotRegularIdentifierVariable.sol",
    "content": "contract Test {\n    function f() public pure {\n        uint type;\n    }\n}\n// ----\n// ParserError 2314: (60-64): Expected ';' but got 'type'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/typeOfContract.sol",
    "content": "contract Test {\n    function f() public pure returns (bytes memory) {\n        type(Test);\n    }\n}\n// ----\n// Warning 6321: (54-66): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6133: (78-88): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/typeRecursive.sol",
    "content": "contract Test {\n    function f() public pure {\n        type(type(type(Test)));\n    }\n}\n// ----\n// TypeError 4259: (65-75): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(contract Test) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/type_expression_nested_ternary_max_keyword.sol",
    "content": "contract C {\n    function f(bool b) public pure returns (uint) {\n        return type(b ? uint : uint).max;\n    }\n}\n// ----\n// TypeError 9717: (89-93): Invalid mobile type in true expression.\n// TypeError 3703: (96-100): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/type_expression_tuple_max.sol",
    "content": "contract C {\n    function max() public pure returns (uint8) {\n        return (type(uint8)).max;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/type_from_ternary_condition.sol",
    "content": "contract C {\n    function f(bool c) pure public {\n        type(c ? uint : uint);\n    }\n}\n// ----\n// TypeError 9717: (67-71): Invalid mobile type in true expression.\n// TypeError 3703: (74-78): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/type_max.sol",
    "content": "contract C {\n    function max() public pure returns (uint8) {\n        return type(uint8).max;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/type_max_from_ternary_expression.sol",
    "content": "contract C {\n    function max(bool isUint) public returns (uint8) {\n        return (isUint ? type(uint8) : type(int8)).max;\n    }\n}\n// ----\n// TypeError 9717: (93-104): Invalid mobile type in true expression.\n// TypeError 3703: (107-117): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/type_runtimecode.sol",
    "content": "contract A {\n}\n\ncontract C {\n    function f() public pure returns (bytes memory) {\n        return type(A).runtimeCode;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/type_runtimecode_from_ternary_expression_.sol",
    "content": "contract A {\n}\n\ncontract B {\n}\n\ncontract C {\n    function f(bool getA) public returns (bytes memory) {\n        return (getA ? type(A) : type(B)).runtimeCode;\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// TypeError 9717: (126-133): Invalid mobile type in true expression.\n// TypeError 3703: (136-143): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/metaTypes/unsupported_arg_for_type.sol",
    "content": "contract Test {\n    struct S { uint x; }\n    function f() public pure {\n        // Unsupported for now, but might be supported in the future\n        type(S);\n    }\n}\n// ----\n// TypeError 4259: (154-155): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(struct Test.S storage pointer) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/access_in_library.sol",
    "content": "library L {\n    modifier m() { _; }\n}\ncontract C {\n    function f() L.m public {\n    }\n}\n// ----\n// TypeError 9428: (68-71): Can only use modifiers defined in the current contract or in base contracts.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/base_constructor_double_invocation.sol",
    "content": "contract C { constructor(uint a) {} }\ncontract B is C {\n    constructor() C(2) C(2) {}\n}\n// ----\n// DeclarationError 3364: (74-78): Base constructor arguments given twice.\n// DeclarationError 1697: (79-83): Base constructor already provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/constructor_as_modifier.sol",
    "content": "contract C {\n    constructor() C() {}\n}\n// ----\n// TypeError 4659: (31-34): Referenced declaration is neither modifier nor base class.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/constructor_call_invalid_arg_count.sol",
    "content": "// This caused a segfault in an earlier version\ncontract C {\n    constructor() {}\n}\ncontract D is C {\n    constructor() C(5) {}\n}\n// ----\n// TypeError 2973: (120-124): Wrong argument count for modifier invocation: 1 arguments given but expected 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/cross_contract_access.sol",
    "content": "contract C {\n    modifier m() { _; }\n}\ncontract D {\n    function f() C.m public {\n    }\n}\n// ----\n// TypeError 9428: (69-72): Can only use modifiers defined in the current contract or in base contracts.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/cross_contract_base.sol",
    "content": "contract C {\n    modifier m() { _; }\n}\ncontract D is C {\n    function f() C.m public {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/cross_contract_super.sol",
    "content": "contract C {\n    modifier m() { _; }\n}\ncontract D is C {\n    function f() super.m public {\n    }\n}\n// ----\n// DeclarationError 7920: (74-81): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/cross_contract_unrelated.sol",
    "content": "contract A {}\ncontract C is A {\n    modifier m() { _; }\n}\ncontract D is A {\n    function f() C.m public {\n    }\n}\ncontract T is D, C {}\n// ----\n// TypeError 9428: (93-96): Can only use modifiers defined in the current contract or in base contracts.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/definition_in_contract.sol",
    "content": "contract C {\n    modifier m { _; }\n    modifier mv virtual { _; }\n}\n\nabstract contract A {\n    modifier m { _; }\n    modifier mv virtual { _; }\n    modifier muv virtual;\n}\n// ----\n// Warning 8429: (39-65): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (117-143): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (148-169): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/definition_in_contract_unimplemented.sol",
    "content": "contract C {\n    modifier mu;\n    modifier muv virtual;\n}\n// ----\n// Warning 8429: (34-55): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 3656: (0-57): Contract \"C\" should be marked as abstract.\n// TypeError 8063: (17-29): Modifiers without implementation must be marked virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/definition_in_interface.sol",
    "content": "interface I {\n    modifier m { _; }\n    modifier mu;\n    modifier mv virtual { _; }\n    modifier muv virtual;\n}\n// ----\n// Warning 8429: (57-83): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (88-109): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 6408: (18-35): Modifiers cannot be defined or declared in interfaces.\n// TypeError 6408: (40-52): Modifiers cannot be defined or declared in interfaces.\n// TypeError 8063: (40-52): Modifiers without implementation must be marked virtual.\n// TypeError 6408: (57-83): Modifiers cannot be defined or declared in interfaces.\n// TypeError 6408: (88-109): Modifiers cannot be defined or declared in interfaces.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/definition_in_library.sol",
    "content": "library L {\n    modifier mv virtual { _; }\n}\n// ----\n// Warning 8429: (16-42): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 3275: (16-42): Modifiers in a library cannot be virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/definition_in_library_unimplemented.sol",
    "content": "library L {\n    modifier mu;\n    modifier muv virtual;\n}\n// ----\n// Warning 8429: (33-54): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 8063: (16-28): Modifiers without implementation must be marked virtual.\n// TypeError 3275: (33-54): Modifiers in a library cannot be virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/definition_in_library_virtual.sol",
    "content": "library L {\n    modifier m { _; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/elementary_non_address_state_mutability_modifier_argument.sol",
    "content": "contract C {\n    modifier a(bool payable) {}\n    modifier b(string payable) {}\n    modifier c(int payable) {}\n    modifier d(int256 payable) {}\n    modifier e(uint payable) {}\n    modifier f(uint256 payable) {}\n    modifier g(bytes1 payable) {}\n    modifier h(bytes payable) {}\n    modifier i(bytes32 payable) {}\n    modifier j(fixed payable) {}\n    modifier k(fixed80x80 payable) {}\n    modifier l(ufixed payable) {}\n    modifier m(ufixed80x80 payable) {}\n}\ncontract C2 {\n    modifier a(bool view) {}\n    modifier b(string view) {}\n    modifier c(int view) {}\n    modifier d(int256 view) {}\n    modifier e(uint view) {}\n    modifier f(uint256 view) {}\n    modifier g(bytes1 view) {}\n    modifier h(bytes view) {}\n    modifier i(bytes32 view) {}\n    modifier j(fixed view) {}\n    modifier k(fixed80x80 view) {}\n    modifier l(ufixed view) {}\n    modifier m(ufixed80x80 view) {}\n}\ncontract C3 {\n    modifier a(bool pure) {}\n    modifier b(string pure) {}\n    modifier c(int pure) {}\n    modifier d(int256 pure) {}\n    modifier e(uint pure) {}\n    modifier f(uint256 pure) {}\n    modifier g(bytes1 pure) {}\n    modifier h(bytes pure) {}\n    modifier i(bytes32 pure) {}\n    modifier j(fixed pure) {}\n    modifier k(fixed80x80 pure) {}\n    modifier l(ufixed pure) {}\n    modifier m(ufixed80x80 pure) {}\n}\n// ----\n// ParserError 9106: (33-40): State mutability can only be specified for address types.\n// ParserError 9106: (67-74): State mutability can only be specified for address types.\n// ParserError 9106: (98-105): State mutability can only be specified for address types.\n// ParserError 9106: (132-139): State mutability can only be specified for address types.\n// ParserError 9106: (164-171): State mutability can only be specified for address types.\n// ParserError 9106: (199-206): State mutability can only be specified for address types.\n// ParserError 9106: (233-240): State mutability can only be specified for address types.\n// ParserError 9106: (266-273): State mutability can only be specified for address types.\n// ParserError 9106: (301-308): State mutability can only be specified for address types.\n// ParserError 9106: (334-341): State mutability can only be specified for address types.\n// ParserError 9106: (372-379): State mutability can only be specified for address types.\n// ParserError 9106: (406-413): State mutability can only be specified for address types.\n// ParserError 9106: (445-452): State mutability can only be specified for address types.\n// ParserError 9106: (493-497): State mutability can only be specified for address types.\n// ParserError 9106: (524-528): State mutability can only be specified for address types.\n// ParserError 9106: (552-556): State mutability can only be specified for address types.\n// ParserError 9106: (583-587): State mutability can only be specified for address types.\n// ParserError 9106: (612-616): State mutability can only be specified for address types.\n// ParserError 9106: (644-648): State mutability can only be specified for address types.\n// ParserError 9106: (675-679): State mutability can only be specified for address types.\n// ParserError 9106: (705-709): State mutability can only be specified for address types.\n// ParserError 9106: (737-741): State mutability can only be specified for address types.\n// ParserError 9106: (767-771): State mutability can only be specified for address types.\n// ParserError 9106: (802-806): State mutability can only be specified for address types.\n// ParserError 9106: (833-837): State mutability can only be specified for address types.\n// ParserError 9106: (869-873): State mutability can only be specified for address types.\n// ParserError 9106: (914-918): State mutability can only be specified for address types.\n// ParserError 9106: (945-949): State mutability can only be specified for address types.\n// ParserError 9106: (973-977): State mutability can only be specified for address types.\n// ParserError 9106: (1004-1008): State mutability can only be specified for address types.\n// ParserError 9106: (1033-1037): State mutability can only be specified for address types.\n// ParserError 9106: (1065-1069): State mutability can only be specified for address types.\n// ParserError 9106: (1096-1100): State mutability can only be specified for address types.\n// ParserError 9106: (1126-1130): State mutability can only be specified for address types.\n// ParserError 9106: (1158-1162): State mutability can only be specified for address types.\n// ParserError 9106: (1188-1192): State mutability can only be specified for address types.\n// ParserError 9106: (1223-1227): State mutability can only be specified for address types.\n// ParserError 9106: (1254-1258): State mutability can only be specified for address types.\n// ParserError 9106: (1290-1294): State mutability can only be specified for address types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/empty_modifier_body.sol",
    "content": "abstract contract A { modifier mod(uint a) virtual;}\ncontract B is A { modifier mod(uint a) override { _; } }\n\nabstract contract C {\n\tmodifier m virtual;\n\tfunction f() m public {\n\n\t}\n}\ncontract D is C {\n\tmodifier m override {\n\t\t_;\n\t}\n}\n// ----\n// Warning 8429: (22-51): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (134-153): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/empty_modifier_err.sol",
    "content": "contract A {modifier m virtual;}\n\nabstract contract B {modifier m virtual;}\ncontract C is B { }\n\nabstract contract D {modifier m;}\n// ----\n// Warning 8429: (12-31): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (55-74): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 3656: (0-32): Contract \"A\" should be marked as abstract.\n// TypeError 3656: (76-95): Contract \"C\" should be marked as abstract.\n// TypeError 8063: (118-129): Modifiers without implementation must be marked virtual.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/function_modifier_double_invocation.sol",
    "content": "contract B {\n    function f(uint x) mod(x) mod(2) public pure { }\n    modifier mod(uint a) { if (a > 0) _; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/function_modifier_invocation.sol",
    "content": "contract B {\n    function f() mod1(2, true) mod2(\"0123456\") pure public { }\n    modifier mod1(uint a, bool b) { if (b) _; }\n    modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol",
    "content": "contract B {\n    function f() mod(x) pure public { uint x = 7; }\n    modifier mod(uint a) { if (a > 0) _; }\n}\n// ----\n// DeclarationError 7576: (34-35): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_parameters.sol",
    "content": "contract B {\n    function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n    modifier mod1(uint a, bool b) { if (b) _; }\n    modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/function_overrides_modifier.sol",
    "content": "contract A { function mod(uint a) public { } }\ncontract B is A { modifier mod(uint a) { _; } }\n// ----\n// DeclarationError 9097: (65-92): Identifier already declared.\n// TypeError 5631: (65-92): Override changes function or public state variable to modifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/illegal_modifier_override.sol",
    "content": "contract A { modifier mod(uint a) { _; } }\ncontract B is A { modifier mod(uint8 a) { _; } }\n// ----\n// TypeError 1078: (61-89): Override changes modifier signature.\n// TypeError 9456: (61-89): Overriding modifier is missing \"override\" specifier.\n// TypeError 4334: (13-40): Trying to override non-virtual modifier. Did you forget to add \"virtual\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/illegal_name.sol",
    "content": "contract C {\n\tmodifier this { _; }\n\tmodifier super { _; }\n\tmodifier _ { _; }\n}\n// ----\n// DeclarationError 3726: (14-34): The name \"this\" is reserved.\n// DeclarationError 3726: (36-57): The name \"super\" is reserved.\n// DeclarationError 3726: (59-76): The name \"_\" is reserved.\n// Warning 2319: (14-34): This declaration shadows a builtin symbol.\n// Warning 2319: (36-57): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/invalid_function_modifier_type.sol",
    "content": "contract B {\n    function f() mod1(true) public { }\n    modifier mod1(uint a) { if (a > 0) _; }\n}\n// ----\n// TypeError 4649: (35-39): Invalid type for argument in modifier invocation. Invalid implicit conversion from bool to uint256 requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/invalid_parameter_indexed.sol",
    "content": "contract B {\n    modifier mod1(uint indexed a) { _; }\n}\n// ----\n// ParserError 2314: (36-43): Expected ',' but got 'indexed'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/invalid_parameter_mutability.sol",
    "content": "contract A {\n    modifier mod1(uint constant a) { _; }\n    modifier mod2(uint immutable a) { _; }\n}\n// ----\n// DeclarationError 1788: (31-46): The \"constant\" keyword can only be used for state variables or variables at file level.\n// DeclarationError 8297: (73-89): The \"immutable\" keyword can only be used for state variables."
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/invalid_parameter_visibility.sol",
    "content": "==== Source: A ====\ncontract A {\n    modifier mod(uint internal a) { _; }\n}\n==== Source: B ====\ncontract A {\n    modifier mod(uint external a) { _; }\n}\n==== Source: C ====\ncontract A {\n    modifier mod(uint public a) { _; }\n}\n==== Source: D ====\ncontract A {\n    modifier mod(uint private a) { _; }\n}\n// ----\n// ParserError 2314: (A:35-43): Expected ',' but got 'internal'\n// ParserError 2314: (B:35-43): Expected ',' but got 'external'\n// ParserError 2314: (C:35-41): Expected ',' but got 'public'\n// ParserError 2314: (D:35-42): Expected ',' but got 'private'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/legal_modifier_override.sol",
    "content": "contract A { modifier mod(uint a) virtual { _; } }\ncontract B is A { modifier mod(uint a) override { _; } }\n// ----\n// Warning 8429: (13-48): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/library_via_using.sol",
    "content": "library L {\n    modifier m() { _; }\n}\ncontract C {\n    using L for *;\n    function f() L.m public {\n    }\n}\n// ----\n// TypeError 9428: (87-90): Can only use modifiers defined in the current contract or in base contracts.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/modifier_abstract_override.sol",
    "content": "contract A {\n    modifier m() virtual { _; }\n}\nabstract contract B is A {\n    modifier m() virtual override;\n}\ncontract C is B {\n    function f() m public {}\n}\n// ----\n// Warning 8429: (17-44): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (78-108): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 4593: (78-108): Overriding an implemented modifier with an unimplemented modifier is not allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/modifier_overrides_function.sol",
    "content": "contract A { modifier mod(uint a) { _; } }\ncontract B is A { function mod(uint a) public { } }\n// ----\n// DeclarationError 9097: (61-92): Identifier already declared.\n// TypeError 1469: (61-92): Override changes modifier to function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/modifier_overrides_variable.sol",
    "content": "contract A { modifier mod(uint a) { _; } }\ncontract B is A { uint public mod; }\n// ----\n// DeclarationError 9097: (61-76): Identifier already declared.\n// TypeError 1456: (61-76): Override changes modifier to public state variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/modifier_returns_value.sol",
    "content": "contract A {\n    function f(uint a) mod(2) public returns (uint r) { }\n    modifier mod(uint a) { _; return 7; }\n}\n// ----\n// TypeError 7552: (101-109): Return arguments not allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/modifier_without_underscore.sol",
    "content": "contract test {\n    modifier m() {}\n}\n// ----\n// SyntaxError 2883: (33-35): Modifier body does not contain '_'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_no_parser_error.sol",
    "content": "// Previous versions of Solidity turned this\n// into a parser error (they wrongly recognized\n// these functions as state variables of\n// function type).\nabstract contract C\n{\n    modifier only_owner() { _; }\n    function foo() only_owner public virtual;\n    function bar() public only_owner virtual;\n}\n// ----\n// SyntaxError 2668: (212-253): Functions without implementation cannot have modifiers.\n// SyntaxError 2668: (258-299): Functions without implementation cannot have modifiers.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/multiple_inheritance_unimplemented_override.sol",
    "content": "contract A {\n    modifier m() virtual { _; }\n}\nabstract contract B {\n    modifier m() virtual;\n}\ncontract C is A, B {\n    modifier m() override(A, B) { _; }\n    function f() m public {}\n}\n// ----\n// Warning 8429: (17-44): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (73-94): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/multiple_parameter_location.sol",
    "content": "contract A {\n    modifier mod1(string storage storage a) { _; }\n    modifier mod2(string storage memory a) { _; }\n    modifier mod3(string storage calldata a) { _; }\n    modifier mod4(string memory storage a) { _; }\n    modifier mod5(string memory memory a) { _; }\n    modifier mod6(string memory calldata a) { _; }\n    modifier mod7(string calldata storage a) { _; }\n    modifier mod8(string calldata memory a) { _; }\n    modifier mod9(string calldata calldata a) { _; }\n    modifier modA(string transient storage a) { _; }\n    modifier modB(string transient memory a) { _; }\n    modifier modC(string transient calldata a) { _; }\n    modifier modD(string storage transient a) { _; }\n    modifier modE(string memory transient a) { _; }\n    modifier modF(string calldata transient a) { _; }\n}\n// ----\n// ParserError 3548: (46-53): Location already specified.\n// ParserError 3548: (97-103): Location already specified.\n// ParserError 3548: (147-155): Location already specified.\n// ParserError 3548: (198-205): Location already specified.\n// ParserError 3548: (248-254): Location already specified.\n// ParserError 3548: (297-305): Location already specified.\n// ParserError 3548: (350-357): Location already specified.\n// ParserError 3548: (402-408): Location already specified.\n// ParserError 3548: (453-461): Location already specified.\n// ParserError 2314: (507-514): Expected ',' but got 'storage'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/non-virtual_modifier_override.sol",
    "content": "contract A { modifier mod(uint a) { _; } }\ncontract B is A { modifier mod(uint a) override { _; } }\n// ----\n// TypeError 4334: (13-40): Trying to override non-virtual modifier. Did you forget to add \"virtual\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/transient_parameter.sol",
    "content": "contract A {\n    modifier mod2(uint[] transient) { _; }\n}\n// ----\n// TypeError 6651: (31-47): Data location must be \"storage\", \"memory\" or \"calldata\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/unimplemented_function_and_modifier.sol",
    "content": "abstract contract A {\n  function foo() public virtual;\n  function foo(uint x) virtual public returns(uint);\n  modifier mod() virtual;\n}\n\ncontract B is A {\n  function foo(uint x) override public returns(uint) {return x;}\n  modifier mod() override { _; }\n}\n\ncontract C is A {\n  function foo() public override {}\n  modifier mod() override { _; }\n}\n\ncontract D is A {\n  function foo() public override {}\n  function foo(uint x) override public returns(uint) {return x;}\n}\n\n/* No errors */\ncontract E is A {\n  function foo() public override {}\n  function foo(uint x) override public returns(uint) {return x;}\n  modifier mod() override { _;}\n}\n// ----\n// Warning 8429: (110-133): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 3656: (137-254): Contract \"B\" should be marked as abstract.\n// TypeError 3656: (256-344): Contract \"C\" should be marked as abstract.\n// TypeError 3656: (346-466): Contract \"D\" should be marked as abstract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/unimplemented_override_unimplemented.sol",
    "content": "abstract contract A {\n    modifier m() virtual;\n}\nabstract contract B is A {\n    modifier m() virtual override;\n}\nabstract contract C is B {\n    modifier m() virtual override;\n    function f() m public {}\n}\n// ----\n// Warning 8429: (26-47): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (81-111): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (145-175): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/use_in_invalid_context.sol",
    "content": "contract test {\n    modifier mod() { _; }\n\n    function f() public {\n        mod  ;\n    }\n}\n// ----\n// TypeError 3112: (77-80): Modifier can only be referenced in function headers.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/use_on_interface_function.sol",
    "content": "interface I {\n  function f() external m pure returns (uint);\n  modifier m() { _; }\n}\n// ----\n// SyntaxError 5842: (16-60): Functions in interfaces cannot have modifiers.\n// TypeError 6408: (63-82): Modifiers cannot be defined or declared in interfaces.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/use_unimplemented_from_base.sol",
    "content": "abstract contract A {\n    modifier m() virtual;\n    function f() m public {}\n}\ncontract B is A {\n    modifier m() virtual override { _; }\n}\n// ----\n// Warning 8429: (26-47): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (101-137): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/use_unimplemented_on_overridden_func.sol",
    "content": "abstract contract A {\n    modifier m() virtual;\n    function f() m public virtual {}\n}\nabstract contract B is A {\n    function f() public override {}\n}\n// ----\n// Warning 8429: (26-47): Virtual modifiers are deprecated and scheduled for removal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/modifiers/use_unimplemented_static.sol",
    "content": "contract A {\n    modifier m() virtual { _; }\n}\nabstract contract B {\n    modifier m() virtual;\n}\ncontract C is A, B {\n    modifier m() override(A, B) { _; }\n    function f() B.m public {}\n}\n// ----\n// Warning 8429: (17-44): Virtual modifiers are deprecated and scheduled for removal.\n// Warning 8429: (73-94): Virtual modifiers are deprecated and scheduled for removal.\n// TypeError 1835: (174-177): Cannot call unimplemented modifier. The modifier has no implementation in the referenced contract. Refer to it by its unqualified name if you want to call the implementation from the most derived contract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/alias_shadows_another_alias.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\nfunction g() pure returns (uint) { return 42; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\n==== Source: s3.sol ====\n// imports f()->1337 as g()\nimport \"s2.sol\";\n// imports f()->1337 as f() and\n// g()->42 as g\nimport {f as f, g as g} from \"s1.sol\";\ncontract C {\n  function foo() public pure returns (uint) {\n    // calls f()->1337 / f()->1337\n    return f() / g();\n  }\n}\n// ----\n// DeclarationError 1686: (s1.sol:0-49): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/alias_shadows_function.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\nfunction g() pure returns (uint) { return 42; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\n==== Source: s3.sol ====\n// imports f()->1337 as g()\nimport \"s2.sol\";\n// imports f()->1337 as f() and\n// g()->42 as g\nimport \"s1.sol\";\ncontract C {\n  function foo() public pure returns (uint) {\n    // calls f()->1337 / f()->1337\n    return f() / g();\n  }\n}\n// ----\n// DeclarationError 1686: (s1.sol:0-49): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/circular_import.sol",
    "content": "==== Source: s1.sol ====\nimport {f as g} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/circular_import_2.sol",
    "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/circular_import_3.sol",
    "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\nimport \"s2.sol\";\n// ----\n// DeclarationError 1686: (s1.sol:39-93): Function with same name and parameter types defined twice.\n// DeclarationError 1686: (s2.sol:31-77): Function with same name and parameter types defined twice.\n// DeclarationError 1686: (s2.sol:78-124): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/circular_import_4.sol",
    "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/circular_import_5.sol",
    "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s2.sol\";\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/duplicate_import_statement.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as f} from \"s1.sol\";\nimport {f as f} from \"s1.sol\";\ncontract C {\n  function g() public pure returns (uint) {\n    return f();\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/error_in_first.sol",
    "content": "==== Source: A ====\ncontract A {\n\tfunction g() public { x; }\n}\n==== Source: B ====\ncontract B {\n\tfunction f() public { }\n}\n// ----\n// DeclarationError 7576: (A:36-37): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/free_different_interger_types.sol",
    "content": "==== Source: s1.sol ====\nfunction f(uint) pure returns (uint) { return 24; }\nfunction g() pure returns (bool) { return true; }\n==== Source: s2.sol ====\nimport {f as g, g as g} from \"s1.sol\";\ncontract C {\n  function foo() public pure returns (uint, bool) {\n    return (g(2), g());\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/free_function_alias_different_parameter_types.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint16) { return 1337; }\nfunction g() pure returns (uint8) { return 42; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\n==== Source: s3.sol ====\n// imports f(uint16)->1337 as g(uint16)\nimport \"s2.sol\";\n// imports f(uint16)->1337 as f(uint16) and\n// g(uint8)->42 as g(uint8)\nimport {f as f, g as g} from \"s1.sol\";\ncontract C {\n  function foo() public pure returns (uint) {\n    // calls f()->1337 / f()->1337\n    return f() / g();\n  }\n}\n// ----\n// DeclarationError 1686: (s1.sol:0-51): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/free_function_control_flow_analysis.sol",
    "content": "==== Source: s1.sol ====\nfunction normal() pure returns (uint) { return 1337; }\nfunction reverting() pure returns (uint) { revert(); }\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract C\n{\n\tfunction foo() public pure returns (uint) { normal(); }\n\tfunction bar() public pure returns (uint) { reverting(); }\n}\n// ----\n// Warning 6321: (s2.sol:67-71): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/free_function_redefinition_base_derived.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {}\n==== Source: s2.sol ====\nimport \"s1.sol\";\nfunction f() pure returns (uint) { return 42; }\ncontract D is C {}\n// ----\n// DeclarationError 1686: (s2.sol:17-64): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/free_function_redefinition_transitive.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nfunction f() pure returns (uint) { return 42; }\ncontract E is D {}\n// ----\n// DeclarationError 1686: (s3.sol:17-64): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/free_function_resolution_override_virtual.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n  function f() public pure virtual returns (uint) {\n    return f();\n  }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\nfunction f() pure returns (uint) { return 42; }\ncontract D is C {\n  function f() public pure override returns (uint) {\n    return f();\n  }\n}\n// ----\n// Warning 2519: (s1.sol:65-134): This declaration shadows an existing declaration.\n// Warning 2519: (s2.sol:85-155): This declaration shadows an existing declaration.\n// DeclarationError 1686: (s2.sol:17-64): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/import.sol",
    "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// Warning 2018: (A:14-78): Function state mutability can be restricted to pure\n// Warning 2018: (B:31-95): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/import_alias.sol",
    "content": "==== Source: s1.sol ====\nint constant a = 2;\n==== Source: s2.sol ====\nimport {a as e} from \"s1.sol\";\nimport \"s2.sol\" as M;\ncontract C {\n  function f() public pure returns (int) { return M.e; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/import_alias_mismatch.sol",
    "content": "==== Source: s1.sol ====\nint constant a = 2;\n==== Source: s2.sol ====\nimport {a as e} from \"s1.sol\";\nimport \"s2.sol\" as M;\ncontract C {\n  function f() public pure returns (int) { return M.a; }\n}\n// ----\n// TypeError 9582: (s2.sol:116-119): Member \"a\" not found or not visible after argument-dependent lookup in module \"s2.sol\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/import_contract_function_error.sol",
    "content": "==== Source: s1.sol ====\ncontract C {\n  function f() public pure returns (uint) {\n    return 1337;\n  }\n}\n==== Source: s2.sol ====\nimport {C.f as g} from \"s1.sol\";\n// ----\n// ParserError 2314: (s2.sol:9-10): Expected '}' but got '.'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/import_not_found.sol",
    "content": "==== Source: a ====\nimport \"b\";\ncontract C {}\n// ----\n// ParserError 6275: (a:0-11): Source \"b\" not found: File not supplied initially.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/imported_free_function.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract C {\n  function g() public pure returns (uint) {\n    return f();\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/libraries_control_flow_analysis.sol",
    "content": "==== Source: s1.sol ====\nlibrary L\n{\n\tfunction normal() public pure returns (uint) { return 1337; }\n\tfunction reverting() public pure returns (uint) { revert(); }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract C\n{\n\tfunction foo() public pure returns (uint) { L.normal(); }\n\tfunction bar() public pure returns (uint) { L.reverting(); }\n}\n// ----\n// Warning 6321: (s2.sol:67-71): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (s2.sol:126-130): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/multiple_imports_same_function.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as f, f as f, f as f} from \"s1.sol\";\ncontract C {\n  function g() public pure returns (uint) {\n    return f();\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/no_import.sol",
    "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x; }\n}\n==== Source: B ====\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// DeclarationError 7920: (B:14-15): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/one_source.sol",
    "content": "==== Source: SourceName ====\ncontract A {\n\tuint256 x;\n\tfunction f() public pure { x = 42; }\n}\n// ----\n// TypeError 8961: (SourceName:53-54): Function cannot be declared as pure because this expression (potentially) modifies the state.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/reimport_imported_function.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\n==== Source: s3.sol ====\nimport {g as h} from \"s2.sol\";\ncontract C {\n  function foo() public pure returns (uint) {\n    return h();\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/split_contract_hierarchy_control_flow_analysis.sol",
    "content": "==== Source: s1.sol ====\ncontract C\n{\n\tfunction normal() public pure returns (uint) { return 1337; }\n\tfunction reverting() public pure returns (uint) { revert(); }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C\n{\n\tfunction foo() public pure returns (uint) { normal(); }\n\tfunction bar() public pure returns (uint) { reverting(); }\n}\n// ----\n// Warning 6321: (s2.sol:72-76): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/split_contract_hierarchy_control_flow_analysis_complex.sol",
    "content": "==== Source: s1.sol ====\ncontract C\n{\n\tfunction normal(bool x) public pure returns (uint)\n\t{\n\t\tif (x)\n\t\t\treturn xxx();\n\t\telse\n\t\t\treturn yyy();\n\t}\n\tfunction yyy() public pure returns (uint) { revert(); }\n\tfunction bar() public pure returns (uint) { normal(true); }\n\n\tfunction xxx() public virtual pure returns (uint) { return 1; }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C\n{\n\tfunction foo() public pure returns (uint) { normal(false); }\n\tfunction xxx() public override pure returns(uint) { revert(); }\n}\n// ----\n// Warning 6321: (s1.sol:215-219): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/two_imports_same_function.sol",
    "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as f, f as f} from \"s1.sol\";\ncontract C {\n  function g() public pure returns (uint) {\n    return f();\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiSource/warning_in_both.sol",
    "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x; }\n}\n==== Source: B ====\ncontract B {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// Warning 2018: (A:14-78): Function state mutability can be restricted to pure\n// Warning 2018: (B:14-78): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/differentNumberOfComponents.sol",
    "content": "contract C {\n    function f() public {\n        uint a = (1,2);\n        uint b = (1,2,3);\n        uint c = (1,2,3,4);\n    }\n    function g() public {\n        (uint a1, uint b1, uint c1, uint d1) = 1;\n        (uint a2, uint b2, uint c2) = 1;\n        (uint a3, uint b3) = 1;\n    }\n    function h() public {\n        (uint a1, uint b1, uint c1, uint d1) = (1,2,3);\n        (uint a2, uint b2, uint c2) = (1,2,3,4);\n    }\n}\n// ----\n// TypeError 7364: (47-61): Different number of components on the left hand side (1) than on the right hand side (2).\n// TypeError 7364: (71-87): Different number of components on the left hand side (1) than on the right hand side (3).\n// TypeError 7364: (97-115): Different number of components on the left hand side (1) than on the right hand side (4).\n// TypeError 7364: (157-197): Different number of components on the left hand side (4) than on the right hand side (1).\n// TypeError 7364: (207-238): Different number of components on the left hand side (3) than on the right hand side (1).\n// TypeError 7364: (248-270): Different number of components on the left hand side (2) than on the right hand side (1).\n// TypeError 7364: (312-358): Different number of components on the left hand side (4) than on the right hand side (3).\n// TypeError 7364: (368-407): Different number of components on the left hand side (3) than on the right hand side (4).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/differentNumberOfComponentsFromReturn.sol",
    "content": "contract C {\n    function f() public {\n        uint a = two();\n        uint b = three();\n        uint c = four();\n    }\n    function g() public {\n        (uint a1, uint b1, uint c1, uint d1) = one();\n        (uint a2, uint b2, uint c2) = one();\n        (uint a3, uint b3) = one();\n    }\n    function h() public {\n        (uint a1, uint b1, uint c1, uint d1) = three();\n        (uint a2, uint b2, uint c2) = four();\n    }\n    function one() public pure returns (uint) {}\n    function two() public pure returns (uint, uint) {}\n    function three() public pure returns (uint, uint, uint) {}\n    function four() public pure returns (uint, uint, uint, uint) {}\n}\n// ----\n// TypeError 7364: (47-61): Different number of components on the left hand side (1) than on the right hand side (2).\n// TypeError 7364: (71-87): Different number of components on the left hand side (1) than on the right hand side (3).\n// TypeError 7364: (97-112): Different number of components on the left hand side (1) than on the right hand side (4).\n// TypeError 7364: (154-198): Different number of components on the left hand side (4) than on the right hand side (1).\n// TypeError 7364: (208-243): Different number of components on the left hand side (3) than on the right hand side (1).\n// TypeError 7364: (253-279): Different number of components on the left hand side (2) than on the right hand side (1).\n// TypeError 7364: (321-367): Different number of components on the left hand side (4) than on the right hand side (3).\n// TypeError 7364: (377-413): Different number of components on the left hand side (3) than on the right hand side (4).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/disallowWildcards.sol",
    "content": "contract C {\n    function fn() public pure {\n        (uint a,) = (1,2,3);\n        (,uint b) = (1,2,3);\n        (,uint c,) = (1,2,3,4,5);\n        (uint d, uint e,) = (1,2,3,4);\n        (,uint f, uint g) = (1,2,3,4);\n        (,uint h, uint i,) = (1,2,3);\n        (uint j,) = 1;\n        (,uint k) = 1;\n        (,uint l,) = 1;\n        a;b;c;d;e;f;g;h;i;j;k;l;\n    }\n}\n// ----\n// TypeError 7364: (53-72): Different number of components on the left hand side (2) than on the right hand side (3).\n// TypeError 7364: (82-101): Different number of components on the left hand side (2) than on the right hand side (3).\n// TypeError 7364: (111-135): Different number of components on the left hand side (3) than on the right hand side (5).\n// TypeError 7364: (145-174): Different number of components on the left hand side (3) than on the right hand side (4).\n// TypeError 7364: (184-213): Different number of components on the left hand side (3) than on the right hand side (4).\n// TypeError 7364: (223-251): Different number of components on the left hand side (4) than on the right hand side (3).\n// TypeError 7364: (261-274): Different number of components on the left hand side (2) than on the right hand side (1).\n// TypeError 7364: (284-297): Different number of components on the left hand side (2) than on the right hand side (1).\n// TypeError 7364: (307-321): Different number of components on the left hand side (3) than on the right hand side (1).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/disallowWildcardsFromReturn.sol",
    "content": "abstract contract C {\n    function fn() public pure {\n        (uint a,) = three();\n        (,uint b) = three();\n        (,uint c,) = five();\n        (uint d, uint e,) = four();\n        (,uint f, uint g) = four();\n        (,uint h, uint i,) = three();\n        (uint j,) = one();\n        (,uint k) = one();\n        (,uint l,) = one();\n        (,uint m, uint n,) = five();\n        a;b;c;d;e;f;g;h;i;j;k;l;m;n;\n    }\n    function one() public pure returns (uint) {}\n    function two() public pure returns (uint, uint) {}\n    function three() public pure returns (uint, uint, uint) {}\n    function four() public pure returns (uint, uint, uint, uint) {}\n    function five() public pure returns (uint, uint, uint, uint, uint) {}\n}\n// ----\n// TypeError 7364: (62-81): Different number of components on the left hand side (2) than on the right hand side (3).\n// TypeError 7364: (91-110): Different number of components on the left hand side (2) than on the right hand side (3).\n// TypeError 7364: (120-139): Different number of components on the left hand side (3) than on the right hand side (5).\n// TypeError 7364: (149-175): Different number of components on the left hand side (3) than on the right hand side (4).\n// TypeError 7364: (185-211): Different number of components on the left hand side (3) than on the right hand side (4).\n// TypeError 7364: (221-249): Different number of components on the left hand side (4) than on the right hand side (3).\n// TypeError 7364: (259-276): Different number of components on the left hand side (2) than on the right hand side (1).\n// TypeError 7364: (286-303): Different number of components on the left hand side (2) than on the right hand side (1).\n// TypeError 7364: (313-331): Different number of components on the left hand side (3) than on the right hand side (1).\n// TypeError 7364: (341-368): Different number of components on the left hand side (4) than on the right hand side (5).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/multiSingleVariableDeclaration.sol",
    "content": "contract C {\n  function f() internal returns (uint) {\n    (uint a) = f();\n    a;\n  }\n}\n// ----\n// Warning 5740: (78-79): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationComplex.sol",
    "content": "contract D {\n  struct S { uint a; uint b; }\n}\ncontract C {\n  function f() internal pure {\n    (,,,D.S[10*2] storage x,) = g();\n    x;\n  }\n  function g() internal pure returns (uint, uint, uint, D.S[20] storage x, uint) { x = x; }\n}\n// ----\n// Warning 6321: (176-180): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (182-186): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (188-192): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (213-217): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationEmpty.sol",
    "content": "contract C {\n    function f() public pure {\n        (uint a, uint b) = f();\n        (uint c) = f();\n        uint d = f();\n    }\n}\n// ----\n// TypeError 7364: (52-74): Different number of components on the left hand side (2) than on the right hand side (0).\n// TypeError 7364: (84-98): Different number of components on the left hand side (1) than on the right hand side (0).\n// TypeError 7364: (108-120): Different number of components on the left hand side (1) than on the right hand side (0).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationInvalidType.sol",
    "content": "contract C {\n  function f() internal returns (string memory, uint, uint, uint) {\n    (uint a, string memory b,,) = f();\n    a; b;\n  }\n}\n// ----\n// TypeError 9574: (85-118): Type string memory is not implicitly convertible to expected type uint256.\n// TypeError 9574: (85-118): Type uint256 is not implicitly convertible to expected type string memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping.sol",
    "content": "contract C {\n  function f() internal {\n    {\n      (uint a, uint b, uint c) = (1, 2, 3);\n    }\n    a;\n  }\n}\n// ----\n// DeclarationError 7576: (99-100): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationScoping2.sol",
    "content": "contract C {\n  function f() internal {\n    {\n      (uint a, uint b, uint c) = (a, b, c);\n    }\n  }\n}\n// ----\n// DeclarationError 7576: (79-80): Undeclared identifier. \"a\" is not (or not yet) visible at this point.\n// DeclarationError 7576: (82-83): Undeclared identifier. \"b\" is not (or not yet) visible at this point.\n// DeclarationError 7576: (85-86): Undeclared identifier. \"c\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationSimple.sol",
    "content": "contract C {\n  function f() internal pure returns (uint, uint, uint, uint) {\n    (uint a, uint b,,) = f();\n    a; b;\n  }\n  function g() internal pure {\n    (bytes memory a, string storage b) = h();\n    a; b;\n  }\n  function h() internal pure returns (bytes memory, string storage s) { s = s; }\n}\n// ----\n// Warning 5740: (111-115): Unreachable code.\n// Warning 6321: (250-262): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationThatIsExpression.sol",
    "content": "contract C {\n  struct S { function() returns (S storage)[] x; }\n  S s;\n  function f() internal pure returns (uint, uint, uint, S storage, uint, uint) {\n    (,,,s.x[2](),,) = f();\n  }\n}\n// ----\n// TypeError 4247: (160-168): Expression has to be an lvalue.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/oneElementTuple.sol",
    "content": "contract C {\n    function f() public {\n        (uint a,) = (1,);\n        a;\n    }\n}\n// ----\n// TypeError 8381: (59-63): Tuple component cannot be empty.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/multiVariableDeclaration/sameNumberOfComponents.sol",
    "content": "contract C {\n    function f() public pure {\n        (uint a1, uint b1, uint c1, uint d1) = (1,2,3,4);\n        (uint a2, uint b2, uint c2) = (1,2,3);\n        (uint a3, uint b3) = (1,2);\n        a1; b1; c1; d1; a2; b2; c2; a3; b3;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/001_name_references.sol",
    "content": "contract test {\n    uint256 variable;\n    function f(uint256) public returns (uint out) { f(variable); test; out; }\n}\n// ----\n// Warning 5740: (103-112): Unreachable code.\n// Warning 6133: (103-107): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/002_undeclared_name.sol",
    "content": "contract test {\n    uint256 variable;\n    function f(uint256 arg) public {\n        f(notfound);\n    }\n}\n// ----\n// DeclarationError 7576: (85-93): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/003_undeclared_name_is_not_fatal.sol",
    "content": "contract test {\n    uint256 variable;\n    function f(uint256 arg) public {\n        f(notfound);\n        f(notfound);\n    }\n}\n// ----\n// DeclarationError 7576: (85-93): Undeclared identifier.\n// DeclarationError 7576: (106-114): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/004_reference_to_later_declaration.sol",
    "content": "contract test {\n    function g() public { f(); }\n    function f() public {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/010_type_conversion_for_comparison.sol",
    "content": "contract test {\n    function f() public { uint32(2) == uint64(2); }\n}\n// ----\n// Warning 6133: (42-64): Statement has no effect.\n// Warning 2018: (20-67): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/011_type_conversion_for_comparison_invalid.sol",
    "content": "contract test {\n    function f() public { int32(2) == uint64(2); }\n}\n// ----\n// TypeError 2271: (42-63): Built-in binary operator == cannot be applied to types int32 and uint64.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/013_large_string_literal.sol",
    "content": "contract test {\n    function f() public { string memory x = \"123456789012345678901234567890123\"; }\n}\n// ----\n// Warning 2072: (42-57): Unused local variable.\n// Warning 2018: (20-98): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/014_balance.sol",
    "content": "contract test {\n    function fun() public {\n        uint256 x = address(0).balance;\n    }\n}\n// ----\n// Warning 2072: (52-61): Unused local variable.\n// Warning 2018: (20-89): Function state mutability can be restricted to view\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/015_balance_invalid.sol",
    "content": "contract test {\n    function fun() public {\n        address(0).balance = 7;\n    }\n}\n// ----\n// TypeError 4247: (52-70): Expression has to be an lvalue.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/017_assignment_to_struct.sol",
    "content": "contract test {\n    struct str {\n        mapping(uint=>uint) map;\n    }\n    str data;\n    function fun() public {\n        str storage a = data;\n        data = a;\n    }\n}\n// ----\n// TypeError 9214: (152-156): Types in storage containing (nested) mappings cannot be assigned to.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/018_forward_function_reference.sol",
    "content": "contract First {\n    function fun() public returns (bool) {\n        return Second(address(1)).fun(1, true, 3) > 0;\n    }\n}\ncontract Second {\n    function fun(uint, bool, uint) public returns (uint) {\n        if (First(address(2)).fun() == true) return 1;\n    }\n}\n// ----\n// Warning 6321: (192-196): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/019_comparison_bitop_precedence.sol",
    "content": "contract First {\n    function fun() public returns (bool ret) {\n        return 1 & 2 == 8 & 9 && 1 ^ 2 < 4 | 6;\n    }\n}\n// ----\n// Warning 2018: (21-117): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/025_comparison_of_mapping_types.sol",
    "content": "contract C {\n    mapping(uint => uint) x;\n    function f() public returns (bool ret) {\n        mapping(uint => uint) storage y = x;\n        return x == y;\n    }\n}\n// ----\n// TypeError 2271: (147-153): Built-in binary operator == cannot be applied to types mapping(uint256 => uint256) and mapping(uint256 => uint256).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/029_create_abstract_contract.sol",
    "content": "contract base { function foo() public virtual; }\ncontract derived {\n    base b;\n    function foo() public { b = new base(); }\n}\n// ----\n// TypeError 3656: (0-48): Contract \"base\" should be marked as abstract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/030_redeclare_implemented_abstract_function_as_abstract.sol",
    "content": "abstract contract base { function foo() public virtual; }\ncontract derived is base { function foo() public virtual override {} }\ncontract wrong is derived { function foo() public virtual override; }\n// ----\n// TypeError 4593: (157-196): Overriding an implemented function with an unimplemented function is not allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/044_returning_multi_dimensional_arrays_new_abi.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f() public pure returns (string[][] memory) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/045_returning_multi_dimensional_arrays.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f() public pure returns (string[][] memory) {}\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 4957: (71-88): This type is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/046_returning_multi_dimensional_static_arrays.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f() public pure returns (uint[][2] memory) {}\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 4957: (71-87): This type is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/047_returning_arrays_in_structs_new_abi.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { string[] s; }\n    function f() public pure returns (S memory) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/048_returning_arrays_in_structs_arrays.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    struct S { string[] s; }\n    function f() public pure returns (S memory x) {}\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 4957: (100-110): This type is only supported in ABI coder v2. Use \"pragma abicoder v2;\" to enable the feature.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/049_function_external_call_allowed_conversion.sol",
    "content": "contract C {}\ncontract Test {\n    function externalCall() public {\n        C arg;\n        this.g(arg);\n    }\n    function g (C c) external {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/050_function_external_call_not_allowed_conversion.sol",
    "content": "contract C {}\ncontract Test {\n    function externalCall() public {\n        address arg;\n        this.g(arg);\n    }\n    function g (C c) external {}\n}\n// ----\n// TypeError 9553: (103-106): Invalid type for argument in function call. Invalid implicit conversion from address to contract C requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/051_function_internal_allowed_conversion.sol",
    "content": "contract C {\n    uint a;\n}\ncontract Test {\n    C a;\n    function g (C c) public {}\n    function internalCall() public {\n        g(a);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/052_function_internal_not_allowed_conversion.sol",
    "content": "contract C {\n    uint a;\n}\ncontract Test {\n    address a;\n    function g (C c) public {}\n    function internalCall() public {\n        g(a);\n    }\n}\n// ----\n// TypeError 9553: (136-137): Invalid type for argument in function call. Invalid implicit conversion from address to contract C requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/053_hash_collision_in_interface.sol",
    "content": "contract test {\n    function gsf() public { }\n    function tgeo() public { }\n}\n// ----\n// TypeError 1860: (0-78): Function signature hash collision for tgeo()\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/054_inheritance_basic.sol",
    "content": "contract base { uint baseMember; struct BaseType { uint element; } }\ncontract derived is base {\n    BaseType data;\n    function f() public { baseMember = 7; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/055_inheritance_diamond_basic.sol",
    "content": "contract root { function rootFunction() public {} }\ncontract inter1 is root { function f() public virtual {} }\ncontract inter2 is root { function f() public virtual {} }\ncontract derived is root, inter2, inter1 {\n\tfunction g() public { f(); rootFunction(); }\n\tfunction f() override(inter1, inter2) public {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/056_cyclic_inheritance.sol",
    "content": "contract A is B { }\ncontract B is A { }\n// ----\n// TypeError 2449: (14-15): Definition of base has to precede definition of derived contract\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/057_legal_override_direct.sol",
    "content": "contract B { function f() public {} }\ncontract C is B { function f(uint i) public {} }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/058_legal_override_indirect.sol",
    "content": "contract A { function f(uint a) public {} }\ncontract B { function f() public {} }\ncontract C is A, B { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/059_illegal_override_visibility.sol",
    "content": "contract B { function f() virtual internal {} }\ncontract C is B { function f() public {} }\n// ----\n// TypeError 9456: (66-88): Overriding function is missing \"override\" specifier.\n// TypeError 9098: (66-88): Overriding function visibility differs.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/060_complex_inheritance.sol",
    "content": "contract A { function f() public virtual { uint8 x = C(address(0)).g(); } }\ncontract B { function f() public virtual {} function g() public returns (uint8) {} }\ncontract C is A, B { function f() public override (A, B) { A.f(); } }\n// ----\n// Warning 2072: (43-50): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/061_missing_base_constructor_arguments.sol",
    "content": "contract A { constructor(uint a) { } }\ncontract B is A { }\n// ----\n// TypeError 3415: (39-58): No arguments passed to the base constructor. Specify the arguments or mark \"B\" as abstract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/062_base_constructor_arguments_override.sol",
    "content": "contract A { constructor(uint a) { } }\ncontract B is A { constructor(bytes4 a, bytes28 b) { } }\n// ----\n// TypeError 3415: (39-95): No arguments passed to the base constructor. Specify the arguments or mark \"B\" as abstract.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/063_implicit_derived_to_base_conversion.sol",
    "content": "contract A { }\ncontract B is A {\n    function f() public { A a = B(address(1)); }\n}\n// ----\n// Warning 2072: (59-62): Unused local variable.\n// Warning 2018: (37-81): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/064_implicit_base_to_derived_conversion.sol",
    "content": "contract A { }\ncontract B is A {\n    function f() public { B b = A(address(1)); }\n}\n// ----\n// TypeError 9574: (59-78): Type contract A is not implicitly convertible to expected type contract B.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/065_super_excludes_current_contract.sol",
    "content": "contract A {\n    function b() public {}\n}\n\ncontract B is A {\n    function f() public {\n        super.f();\n    }\n}\n// ----\n// TypeError 9582: (95-102): Member \"f\" not found or not visible after argument-dependent lookup in type(contract super B).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/067_function_clash_with_state_variable_accessor.sol",
    "content": "contract test {\n    function fun() public {\n        uint64(2);\n    }\n    uint256 foo;\n    function foo() public {}\n}\n// ----\n// DeclarationError 2333: (90-114): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/069_base_class_state_variable_accessor.sol",
    "content": "// test for issue #1126 https://github.com/ethereum/cpp-ethereum/issues/1126\ncontract Parent {\n    uint256 public m_aMember;\n}\ncontract Child is Parent {\n    function foo() public returns (uint256) { return Parent.m_aMember; }\n}\n// ----\n// Warning 2018: (158-226): Function state mutability can be restricted to view\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/070_struct_accessor_one_array_only.sol",
    "content": "contract test {\n    struct Data { uint[15] m_array; }\n    Data public data;\n}\n// ----\n// TypeError 5359: (58-74): The struct has all its members omitted, therefore the getter cannot return any values.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/071_base_class_state_variable_internal_member.sol",
    "content": "contract Parent {\n    uint256 internal m_aMember;\n}\ncontract Child is Parent {\n    function foo() public returns (uint256) { return Parent.m_aMember; }\n}\n// ----\n// Warning 2018: (83-151): Function state mutability can be restricted to view\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/072_state_variable_member_of_wrong_class1.sol",
    "content": "contract Parent1 {\n    uint256 internal m_aMember1;\n}\ncontract Parent2 is Parent1 {\n    uint256 internal m_aMember2;\n}\ncontract Child is Parent2 {\n    function foo() public returns (uint256) { return Parent2.m_aMember1; }\n}\n// ----\n// TypeError 9582: (200-218): Member \"m_aMember1\" not found or not visible after argument-dependent lookup in type(contract Parent2).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/073_state_variable_member_of_wrong_class2.sol",
    "content": "contract Parent1 {\n    uint256 internal m_aMember1;\n}\ncontract Parent2 is Parent1 {\n    uint256 internal m_aMember2;\n}\ncontract Child is Parent2 {\n    function foo() public returns (uint256) { return Child.m_aMember2; }\n    uint256 public m_aMember3;\n}\n// ----\n// TypeError 9582: (200-216): Member \"m_aMember2\" not found or not visible after argument-dependent lookup in type(contract Child).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/074_fallback_function.sol",
    "content": "contract C {\n    uint x;\n    fallback() external { x = 2; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/075_fallback_function_with_arguments.sol",
    "content": "contract C {\n    uint x;\n    fallback(uint a) external { x = 2; }\n}\n// ----\n// TypeError 5570: (55-55): Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/076_fallback_function_in_library.sol",
    "content": "library C {\n    fallback() external {}\n}\n// ----\n// TypeError 5982: (16-38): Libraries cannot have fallback functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/076_receive_function_in_library.sol",
    "content": "library C {\n    receive() external payable {}\n}\n// ----\n// DeclarationError 4549: (16-45): Libraries cannot have receive ether functions.\n// TypeError 7708: (16-45): Library functions cannot be payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/077_fallback_function_with_return_parameters.sol",
    "content": "contract C {\n    fallback() external returns (uint) { }\n}\n// ----\n// TypeError 5570: (45-51): Fallback function either has to have the signature \"fallback()\" or \"fallback(bytes calldata) returns (bytes memory)\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/079_fallback_function_inheritance.sol",
    "content": "contract A {\n    uint x;\n    fallback() virtual external { x = 1; }\n}\ncontract C is A {\n    fallback() override external { x = 2; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/096_access_to_default_function_visibility.sol",
    "content": "contract c {\n    function f() public {}\n}\ncontract d {\n    function g() public { c(address(0)).f(); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/097_access_to_internal_function.sol",
    "content": "contract c {\n    function f() internal {}\n}\ncontract d {\n    function g() public { c(address(0)).f(); }\n}\n// ----\n// TypeError 9582: (83-98): Member \"f\" not found or not visible after argument-dependent lookup in contract c.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/098_access_to_default_state_variable_visibility.sol",
    "content": "contract c {\n    uint a;\n}\ncontract d {\n    function g() public { c(address(0)).a(); }\n}\n// ----\n// TypeError 9582: (66-81): Member \"a\" not found or not visible after argument-dependent lookup in contract c.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/099_access_to_internal_state_variable.sol",
    "content": "contract c {\n    uint public a;\n}\ncontract d {\n    function g() public { c(address(0)).a(); }\n}\n// ----\n// Warning 2018: (51-93): Function state mutability can be restricted to view\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/104_empty_name_input_parameter.sol",
    "content": "contract test {\n    function f(uint) public { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol",
    "content": "contract test {\n    function f(uint[] memory constant a) public { }\n}\n// ----\n// DeclarationError 1788: (31-55): The \"constant\" keyword can only be used for state variables or variables at file level.\n// TypeError 9259: (31-55): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/106_empty_name_return_parameter.sol",
    "content": "contract test {\n    function f() public returns (bool) { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/107_empty_name_input_parameter_with_named_one.sol",
    "content": "contract test {\n    function f(uint, uint k) public returns (uint ret_k) {\n        return k;\n    }\n}\n// ----\n// Warning 2018: (20-98): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/108_empty_name_return_parameter_with_named_one.sol",
    "content": "contract test {\n    function f() public returns (uint ret_k, uint) {\n        return 5;\n    }\n}\n// ----\n// TypeError 8863: (77-85): Different number of arguments in return statement than in returns declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/110_no_overflow_with_large_literal.sol",
    "content": "contract c {\n    constructor() {\n        a = 115792089237316195423570985008687907853269984665640564039458;\n    }\n    uint256 a;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/111_overflow_caused_by_ether_units.sol",
    "content": "contract c {\n    constructor() {\n        a = 115792089237316195423570985008687907853269984665640564039458 ether;\n    }\n    uint256 a;\n}\n// ----\n// TypeError 7407: (45-111): Type int_const 1157...(70 digits omitted)...0000 is not implicitly convertible to expected type uint256. Literal is too large to fit in uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/112_exp_operator_exponent_too_big.sol",
    "content": "contract test {\n    function f() public returns (uint d) { return 2 ** 10000000000; }\n}\n// ----\n// TypeError 2271: (66-82): Built-in binary operator ** cannot be applied to types int_const 2 and int_const 10000000000.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/113_exp_warn_literal_base_1.sol",
    "content": "contract test {\n    function f() pure public returns(uint) {\n        uint8 x = 100;\n        return 10**x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/114_exp_warn_literal_base_2.sol",
    "content": "contract test {\n    function f() pure public returns(uint) {\n        uint8 x = 100;\n        return uint8(10)**x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/115_exp_warn_literal_base_3.sol",
    "content": "contract test {\n    function f() pure public returns(uint) {\n        return 2**80;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/116_shift_warn_literal_base_1.sol",
    "content": "contract test {\n    function f() pure public returns(uint) {\n        uint8 x = 100;\n        return 10 << x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/117_shift_warn_literal_base_2.sol",
    "content": "contract test {\n    function f() pure public returns(uint) {\n        uint8 x = 100;\n        return uint8(10) << x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/118_shift_warn_literal_base_3.sol",
    "content": "contract test {\n    function f() pure public returns(uint) {\n        return 2 << 80;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/119_shift_warn_literal_base_4.sol",
    "content": "contract test {\n    function f() pure public returns(uint) {\n         uint8 x = 100;\n         return 10 >> x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/124_enum_member_access.sol",
    "content": "contract test {\n    enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }\n    constructor()\n    {\n        choices = ActionChoices.GoStraight;\n    }\n    ActionChoices choices;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/125_enum_member_access_accross_contracts.sol",
    "content": "contract Interface {\n    enum MyEnum { One, Two }\n}\ncontract Impl {\n    function test() public returns (Interface.MyEnum) {\n        return Interface.MyEnum.One;\n    }\n}\n// ----\n// Warning 2018: (72-166): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/126_enum_invalid_member_access.sol",
    "content": "contract test {\n    enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }\n    constructor() {\n        choices = ActionChoices.RunAroundWavingYourHands;\n    }\n    ActionChoices choices;\n}\n// ----\n// TypeError 9582: (114-152): Member \"RunAroundWavingYourHands\" not found or not visible after argument-dependent lookup in type(enum test.ActionChoices).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/127_enum_invalid_direct_member_access.sol",
    "content": "contract test {\n    enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }\n    constructor() {\n        choices = Sit;\n    }\n    ActionChoices choices;\n}\n// ----\n// DeclarationError 7576: (114-117): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/128_enum_explicit_conversion_is_okay.sol",
    "content": "contract test {\n    enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }\n    constructor() {\n        a = uint256(ActionChoices.GoStraight);\n        b = uint64(ActionChoices.Sit);\n    }\n    uint256 a;\n    uint64 b;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/129_int_to_enum_explicit_conversion_is_okay.sol",
    "content": "contract test {\n    enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }\n    constructor() {\n        a = 2;\n        b = ActionChoices(a);\n    }\n    uint256 a;\n    ActionChoices b;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/130_enum_implicit_conversion_is_not_okay_256.sol",
    "content": "contract test {\n    enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }\n    constructor() {\n        a = ActionChoices.GoStraight;\n    }\n    uint256 a;\n}\n// ----\n// TypeError 7407: (108-132): Type enum test.ActionChoices is not implicitly convertible to expected type uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/131_enum_implicit_conversion_is_not_okay_64.sol",
    "content": "contract test {\n    enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }\n    constructor() {\n        b = ActionChoices.Sit;\n    }\n    uint64 b;\n}\n// ----\n// TypeError 7407: (108-125): Type enum test.ActionChoices is not implicitly convertible to expected type uint64.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/132_enum_to_enum_conversion_is_not_okay.sol",
    "content": "contract test {\n    enum Paper { Up, Down, Left, Right }\n    enum Ground { North, South, West, East }\n    constructor() {\n        Ground(Paper.Up);\n    }\n}\n// ----\n// TypeError 9640: (130-146): Explicit type conversion not allowed from \"enum test.Paper\" to \"enum test.Ground\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/133_enum_duplicate_values.sol",
    "content": "    contract test {\n        enum ActionChoices { GoLeft, GoRight, GoLeft, Sit }\n    }\n// ----\n// DeclarationError 2333: (66-72): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/134_enum_name_resolution_under_current_contract_name.sol",
    "content": "contract A {\n    enum Foo {\n        First,\n        Second\n    }\n\n    function a() public {\n        A.Foo;\n    }\n}\n// ----\n// Warning 2018: (69-111): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/135_private_visibility.sol",
    "content": "contract base {\n    function f() private {}\n}\ncontract derived is base {\n    function g() public { f(); }\n}\n// ----\n// DeclarationError 7576: (99-100): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/136_private_visibility_via_explicit_base_access.sol",
    "content": "contract base {\n    function f() private {}\n}\ncontract derived is base {\n    function g() public { base.f(); }\n}\n// ----\n// TypeError 9582: (99-105): Member \"f\" not found or not visible after argument-dependent lookup in type(contract base).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/137_external_visibility.sol",
    "content": "contract c {\n    function f() external {}\n    function g() public { f(); }\n}\n// ----\n// DeclarationError 7576: (68-69): Undeclared identifier. \"f\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/138_similar_name_suggestions_expected.sol",
    "content": "contract c {\n    function func() public {}\n    function g() public { fun(); }\n}\n// ----\n// DeclarationError 7576: (69-72): Undeclared identifier. Did you mean \"func\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/139_no_name_suggestion.sol",
    "content": "contract c {\n    function g() public { fun(); }\n}\n// ----\n// DeclarationError 7576: (39-42): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/140_multiple_similar_suggestions.sol",
    "content": "contract c {\n    function g() public {\n        uint var1 = 1;\n        uint var2 = 1;\n        uint var3 = 1;\n        uint var4 = 1;\n        uint var5 = varx;\n    }\n}\n// ----\n// DeclarationError 7576: (151-155): Undeclared identifier. Did you mean \"var1\", \"var2\", \"var3\", \"var4\" or \"var5\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/141_multiple_scopes_suggestions.sol",
    "content": "contract c {\n    uint log9 = 2;\n    function g() public {\n        uint log8 = 3;\n        uint var1 = lgox;\n    }\n}\n// ----\n// DeclarationError 7576: (101-105): Undeclared identifier. Did you mean \"log8\" or \"log9\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/142_inheritence_suggestions.sol",
    "content": "contract a { function func() public {} }\ncontract c is a {\n    function g() public {\n        uint var1 = fun();\n    }\n}\n// ----\n// DeclarationError 7576: (105-108): Undeclared identifier. Did you mean \"func\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/143_no_spurious_identifier_suggestions_with_submatch.sol",
    "content": "contract c {\n    function g() public {\n        uint va = 1;\n        uint vb = vaxyz;\n     }\n}\n// ----\n// DeclarationError 7576: (78-83): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/144_no_spurious_identifier_suggestions.sol",
    "content": "contract c {\n    function g() public {\n        uint va = 1;\n        uint vb = x;\n     }\n}\n// ----\n// DeclarationError 7576: (78-79): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/145_external_base_visibility.sol",
    "content": "contract base {\n    function f() external {}\n}\ncontract derived is base {\n    function g() public { base.f(); }\n}\n// ----\n// TypeError 3419: (100-108): Cannot call function via contract type name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/146_external_argument_assign.sol",
    "content": "contract c {\n    function f(uint a) external pure { a = 1; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/147_external_argument_increment.sol",
    "content": "contract c {\n    function f(uint a) external pure { a++; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/148_external_argument_delete.sol",
    "content": "contract c {\n    function f(uint a) external { delete a; }\n}\n// ----\n// Warning 2018: (17-58): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/149_test_for_bug_override_function_with_bytearray_type.sol",
    "content": "contract Vehicle {\n    function f(bytes calldata) external virtual returns (uint256 r) {r = 1;}\n}\ncontract Bike is Vehicle {\n    function f(bytes calldata) override external returns (uint256 r) {r = 42;}\n}\n// ----\n// Warning 2018: (129-203): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/150_array_with_nonconstant_length.sol",
    "content": "contract c {\n    function f(uint a) public { uint8[a] x; }\n}\n// ----\n// TypeError 5462: (51-52): Invalid array length, expected integer literal or constant expression.\n// TypeError 6651: (45-55): Data location must be \"storage\", \"memory\" or \"calldata\" for variable, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/151_array_with_negative_length.sol",
    "content": "contract c {\n    function f(uint a) public { uint8[-1] x; }\n}\n// ----\n// TypeError 3658: (51-53): Array with negative length specified.\n// TypeError 6651: (45-56): Data location must be \"storage\", \"memory\" or \"calldata\" for variable, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/152_array_copy_with_different_types1.sol",
    "content": "contract c {\n    bytes a;\n    uint[] b;\n    function f() public { b = a; }\n}\n// ----\n// TypeError 7407: (70-71): Type bytes storage ref is not implicitly convertible to expected type uint256[] storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/153_array_copy_with_different_types2.sol",
    "content": "contract c {\n    uint32[] a;\n    uint8[] b;\n    function f() public { b = a; }\n}\n// ----\n// TypeError 7407: (74-75): Type uint32[] storage ref is not implicitly convertible to expected type uint8[] storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/154_array_copy_with_different_types_conversion_possible.sol",
    "content": "contract c {\n    uint32[] a;\n    uint8[] b;\n    function f() public { a = b; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/155_array_copy_with_different_types_static_dynamic.sol",
    "content": "contract c {\n    uint32[] a;\n    uint8[80] b;\n    function f() public { a = b; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/156_array_copy_with_different_types_dynamic_static.sol",
    "content": "contract c {\n    uint[] a;\n    uint[80] b;\n    function f() public { b = a; }\n}\n// ----\n// TypeError 7407: (73-74): Type uint256[] storage ref is not implicitly convertible to expected type uint256[80] storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/157_array_of_undeclared_type.sol",
    "content": "contract c {\n    a[] public foo;\n}\n// ----\n// DeclarationError 7920: (17-18): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/158_storage_variable_initialization_with_incorrect_type_int.sol",
    "content": "contract c {\n    uint8 a = 1000;\n}\n// ----\n// TypeError 7407: (27-31): Type int_const 1000 is not implicitly convertible to expected type uint8. Literal is too large to fit in uint8.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/159_storage_variable_initialization_with_incorrect_type_string.sol",
    "content": "contract c {\n    uint a = \"abc\";\n}\n// ----\n// TypeError 7407: (26-31): Type literal_string \"abc\" is not implicitly convertible to expected type uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/160_test_byte_is_alias_of_byte1.sol",
    "content": "contract c {\n    bytes arr;\n    function f() public { bytes1 a = arr[0];}\n}\n// ----\n// Warning 2072: (54-62): Unused local variable.\n// Warning 2018: (32-73): Function state mutability can be restricted to view\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/164_assigning_value_to_const_variable.sol",
    "content": "contract Foo {\n    function changeIt() public { x = 9; }\n    uint constant x = 56;\n}\n// ----\n// TypeError 6520: (48-49): Cannot assign to a constant variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/165_assigning_state_to_const_variable.sol",
    "content": "contract C {\n    address constant x = msg.sender;\n}\n// ----\n// TypeError 8349: (38-48): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/167_constant_string_literal_disallows_assignment.sol",
    "content": "contract Test {\n    string constant x = \"abefghijklmnopqabcdefghijklmnopqabcdefghijklmnopqabca\";\n    function f() public {\n        // Even if this is made possible in the future, we should not allow assignment\n        // to elements of constant arrays.\n        x[0] = \"f\";\n    }\n}\n// ----\n// TypeError 9961: (261-265): Index access for string is not possible.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/168_assignment_to_const_var_involving_conversion.sol",
    "content": "contract C {\n    C constant x = C(address(0x123));\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/169_assignment_to_const_var_involving_expression.sol",
    "content": "contract C {\n    uint constant x = 0x123 + 0x456;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/170_assignment_to_const_var_involving_keccak.sol",
    "content": "contract C {\n    bytes32 constant x = keccak256(\"abc\");\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/171_assignment_to_const_array_vars.sol",
    "content": "contract C {\n    uint[3] constant x = [uint(1), 2, 3];\n}\n// ----\n// TypeError 9259: (17-53): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/172_assignment_to_const_string_bytes.sol",
    "content": "contract C {\n    bytes constant a = \"\\x00\\x01\\x02\";\n    bytes constant b = hex\"000102\";\n    string constant c = \"hello\";\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/173_constant_struct.sol",
    "content": "contract C {\n    struct S { uint x; uint[] y; }\n    S constant x = S(5, new uint[](4));\n}\n// ----\n// TypeError 9259: (52-86): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/174_address_is_constant.sol",
    "content": "contract C {\n    address constant x = 0x1212121212121212121212121212121212121212;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/175_uninitialized_const_variable.sol",
    "content": "contract Foo {\n    uint constant y;\n}\n// ----\n// TypeError 4266: (19-34): Uninitialized \"constant\" variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/176_overloaded_function_cannot_resolve.sol",
    "content": "contract test {\n    function f() public returns (uint) { return 1; }\n    function f(uint a) public returns (uint) { return a; }\n    function g() public returns (uint) { return f(3, 5); }\n}\n// ----\n// TypeError 9322: (176-177): No matching declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/177_ambiguous_overloaded_function.sol",
    "content": "contract test {\n    function f(uint8 a) public returns (uint) { return a; }\n    function f(uint a) public returns (uint) { return 2 * a; }\n    // literal 1 can be both converted to uint and uint8, so the call is ambiguous.\n    function g() public returns (uint) { return f(1); }\n}\n// ----\n// TypeError 4487: (271-272): No unique declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/178_assignment_of_nonoverloaded_function.sol",
    "content": "contract test {\n    function f(uint a) public returns (uint) { return 2 * a; }\n    function g() public returns (uint) { function (uint) returns (uint) x = f; return x(7); }\n}\n// ----\n// Warning 2018: (20-78): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/179_assignment_of_overloaded_function.sol",
    "content": "contract test {\n    function f() public returns (uint) { return 1; }\n    function f(uint a) public returns (uint) { return 2 * a; }\n    function g() public returns (uint) { function (uint) returns (uint) x = f; return x(7); }\n}\n// ----\n// TypeError 2144: (208-209): No matching declaration found after variable lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/180_external_types_clash.sol",
    "content": "contract base {\n    enum a { X }\n    function f(a) public { }\n}\ncontract test is base {\n    function f(uint8 a) public { }\n}\n// ----\n// TypeError 9914: (37-61): Function overload clash during conversion to external types for arguments.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/181_override_changes_return_types.sol",
    "content": "contract base {\n    function f(uint a) public virtual returns (uint) { }\n}\ncontract test is base {\n    function f(uint a) public override returns (uint8) { }\n}\n// ----\n// TypeError 4822: (103-157): Overriding function return types differ.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/182_equal_overload.sol",
    "content": "contract C {\n    function test(uint a) public returns (uint b) { }\n    function test(uint a) external {}\n}\n// ----\n// DeclarationError 1686: (17-66): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/188_string_index.sol",
    "content": "contract C {\n    string s;\n    function f() public { bytes1 a = s[2]; }\n}\n// ----\n// TypeError 9961: (64-68): Index access for string is not possible.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/189_string_length.sol",
    "content": "contract C {\n    string s;\n    function f() public { uint a = s.length; }\n}\n// ----\n// TypeError 9582: (62-70): Member \"length\" not found or not visible after argument-dependent lookup in string storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/190_negative_integers_to_signed_out_of_bound.sol",
    "content": "contract test {\n    int8 public i = -129;\n}\n// ----\n// TypeError 7407: (36-40): Type int_const -129 is not implicitly convertible to expected type int8. Literal is too large to fit in int8.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/191_negative_integers_to_signed_min.sol",
    "content": "contract test {\n    int8 public i = -128;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/192_positive_integers_to_signed_out_of_bound.sol",
    "content": "contract test {\n    int8 public j = 128;\n}\n// ----\n// TypeError 7407: (36-39): Type int_const 128 is not implicitly convertible to expected type int8. Literal is too large to fit in int8.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/193_positive_integers_to_signed_out_of_bound_max.sol",
    "content": "contract test {\n    int8 public j = 127;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/194_negative_integers_to_unsigned.sol",
    "content": "contract test {\n    uint8 public x = -1;\n}\n// ----\n// TypeError 7407: (37-39): Type int_const -1 is not implicitly convertible to expected type uint8. Cannot implicitly convert signed literal to unsigned type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/195_positive_integers_to_unsigned_out_of_bound.sol",
    "content": "contract test {\n    uint8 public x = 700;\n}\n// ----\n// TypeError 7407: (37-40): Type int_const 700 is not implicitly convertible to expected type uint8. Literal is too large to fit in uint8.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/196_integer_boolean_or.sol",
    "content": "contract test { fallback() external { uint x = 1; uint y = 2; x || y; } }\n// ----\n// TypeError 2271: (62-68): Built-in binary operator || cannot be applied to types uint256 and uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/197_integer_boolean_and.sol",
    "content": "contract test { fallback() external { uint x = 1; uint y = 2; x && y; } }\n// ----\n// TypeError 2271: (62-68): Built-in binary operator && cannot be applied to types uint256 and uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/198_integer_boolean_not.sol",
    "content": "contract test { fallback() external { uint x = 1; !x; } }\n// ----\n// TypeError 4907: (50-52): Built-in unary operator ! cannot be applied to type uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/199_integer_unsigned_exp_signed.sol",
    "content": "contract test { fallback() external { uint x = 3; int y = -4; x ** y; } }\n// ----\n// TypeError 2271: (62-68): Built-in binary operator ** cannot be applied to types uint256 and int256. Exponentiation power is not allowed to be a signed integer type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/200_integer_signed_exp_unsigned.sol",
    "content": "contract test {\n    fallback() external { uint x = 3; int y = -4; y ** x; }\n    function f() public pure { int16 x = 3; uint8 y = 4; x ** y; }\n    function g() public pure { int16 x = 3; uint16 y = 4; x ** y; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/201_integer_signed_exp_signed.sol",
    "content": "contract test {\n    function f() public { int x = 3; int y = 4; x ** y; }\n    function h() public { uint8 x = 3; int16 y = 4; x ** y; }\n    function i() public { int16 x = 4; x ** -3; }\n}\n// ----\n// TypeError 2271: (64-70): Built-in binary operator ** cannot be applied to types int256 and int256. Exponentiation power is not allowed to be a signed integer type.\n// TypeError 2271: (126-132): Built-in binary operator ** cannot be applied to types uint8 and int16. Exponentiation power is not allowed to be a signed integer type.\n// Warning 3149: (126-132): The result type of the exponentiation operation is equal to the type of the first operand (uint8) ignoring the (larger) type of the second operand (int16) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n// TypeError 2271: (175-182): Built-in binary operator ** cannot be applied to types int16 and int_const -3. Exponentiation power is not allowed to be a negative integer literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/202_bytes_reference_compare_operators.sol",
    "content": "contract test { bytes a; bytes b; fallback() external { a == b; } }\n// ----\n// TypeError 2271: (56-62): Built-in binary operator == cannot be applied to types bytes storage ref and bytes storage ref.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/203_struct_reference_compare_operators.sol",
    "content": "contract test {\n  struct s {uint a;}\n  s x;\n  s y;\n  fallback() external {\n    x == y;\n  }\n}\n// ----\n// TypeError 2271: (79-85): Built-in binary operator == cannot be applied to types struct test.s storage ref and struct test.s storage ref. No matching user-defined operator found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/204_overwrite_memory_location_external.sol",
    "content": "contract C {\n    function f(uint[] memory a) external {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/205_overwrite_storage_location_external.sol",
    "content": "contract C {\n    function f(uint[] storage a) external {}\n}\n// ----\n// TypeError 6651: (28-44): Data location must be \"memory\" or \"calldata\" for parameter in external function, but \"storage\" was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/206_storage_location_local_variables.sol",
    "content": "contract C {\n    uint[] m_x;\n    function f() public view {\n        uint[] storage x = m_x;\n        uint[] memory y;\n        x;y;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/207_no_mappings_in_memory_array.sol",
    "content": "contract C {\n    function f() public {\n        mapping(uint=>uint)[] memory x;\n    }\n}\n// ----\n// TypeError 4061: (47-77): Type mapping(uint256 => uint256)[] memory is only valid in storage because it contains a (nested) mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/208_assignment_mem_to_local_storage_variable.sol",
    "content": "contract C {\n    uint[] data;\n    function f(uint[] memory x) public {\n        uint[] storage dataRef = data;\n        dataRef = x;\n    }\n}\n// ----\n// TypeError 7407: (128-129): Type uint256[] memory is not implicitly convertible to expected type uint256[] storage pointer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/209_storage_assign_to_different_local_variable.sol",
    "content": "contract C {\n    uint[] data;\n    uint8[] otherData;\n    function f() public {\n        uint8[] storage x = otherData;\n        uint[] storage y = data;\n        y = x;\n        // note that data = otherData works\n    }\n}\n// ----\n// TypeError 7407: (163-164): Type uint8[] storage pointer is not implicitly convertible to expected type uint256[] storage pointer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/210_uninitialized_mapping_variable.sol",
    "content": "contract C {\n    function f() public {\n        mapping(uint => uint) storage x;\n        x;\n    }\n}\n// ----\n// TypeError 4182: (47-78): Uninitialized mapping. Mappings cannot be created dynamically, you have to assign them from a state variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/211_uninitialized_mapping_array_variable.sol",
    "content": "contract C {\n    function f() pure public {\n        mapping(uint => uint)[] storage x;\n        x;\n    }\n}\n// ----\n// TypeError 3464: (95-96): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/213_no_delete_on_storage_pointers.sol",
    "content": "contract C {\n    uint[] data;\n    function f() public {\n        uint[] storage x = data;\n        delete x;\n    }\n}\n// ----\n// TypeError 9767: (97-105): Built-in unary operator delete cannot be applied to type uint256[] storage pointer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/214_assignment_mem_storage_variable_directly.sol",
    "content": "contract C {\n    uint[] data;\n    function f(uint[] memory x) public {\n        data = x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/215_function_argument_mem_to_storage.sol",
    "content": "contract C {\n    function f(uint[] storage x) private {\n    }\n    function g(uint[] memory x) public {\n        f(x);\n    }\n}\n// ----\n// TypeError 9553: (113-114): Invalid type for argument in function call. Invalid implicit conversion from uint256[] memory to uint256[] storage pointer requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/216_function_argument_storage_to_mem.sol",
    "content": "contract C {\n    function f(uint[] storage x) private {\n        g(x);\n    }\n    function g(uint[] memory x) public {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/217_mem_array_assignment_changes_base_type.sol",
    "content": "contract C {\n    function f(uint8[] memory x) private {\n        // Such an assignment is possible in storage, but not in memory\n        // (because it would incur an otherwise unnecessary copy).\n        // This requirement might be lifted, though.\n        uint[] memory y = x;\n    }\n}\n// ----\n// TypeError 9574: (256-275): Type uint8[] memory is not implicitly convertible to expected type uint256[] memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/219_memory_arrays_not_resizeable.sol",
    "content": "contract C {\n    function f() public {\n        uint[] memory x;\n        x.length = 2;\n    }\n}\n// ----\n// TypeError 7567: (72-80): Member \"length\" is read-only and cannot be used to resize arrays.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/220_struct_constructor.sol",
    "content": "contract C {\n    struct S { uint a; bool x; }\n    function f() public {\n        S memory s = S(1, true);\n    }\n}\n// ----\n// Warning 2072: (80-90): Unused local variable.\n// Warning 2018: (50-110): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/221_struct_constructor_nested.sol",
    "content": "contract C {\n    struct X { uint x1; uint x2; }\n    struct S { uint s1; uint[3] s2; X s3; }\n    function f() public {\n        uint[3] memory s2;\n        S memory s = S(1, s2, X(4, 5));\n    }\n}\n// ----\n// Warning 2072: (153-163): Unused local variable.\n// Warning 2018: (96-190): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/222_struct_named_constructor.sol",
    "content": "contract C {\n    struct S { uint a; bool x; }\n    function f() public {\n        S memory s = S({a: 1, x: true});\n    }\n}\n// ----\n// Warning 2072: (80-90): Unused local variable.\n// Warning 2018: (50-118): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/223_literal_strings.sol",
    "content": "contract Foo {\n    function f() public {\n        string memory long = \"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n        string memory short = \"123\";\n        long; short;\n    }\n}\n// ----\n// Warning 2018: (19-238): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/224_string_bytes_conversion.sol",
    "content": "contract Test {\n    string s;\n    bytes b;\n    function h(string calldata _s) pure external { bytes(_s).length; }\n    function i(string memory _s) pure internal { bytes(_s).length; }\n    function j() view internal { bytes(s).length; }\n    function k(bytes calldata _b) pure external { string(_b); }\n    function l(bytes memory _b) pure internal { string(_b); }\n    function m() view internal { string(b); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/225_inheriting_from_library.sol",
    "content": "library Lib {}\ncontract Test is Lib {}\n// ----\n// TypeError 2571: (32-35): Libraries cannot be inherited from.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/226_inheriting_library.sol",
    "content": "contract Test {}\nlibrary Lib is Test {}\n// ----\n// TypeError 9469: (17-39): Library is not allowed to inherit.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/227_library_having_variables.sol",
    "content": "library Lib { uint x; }\n// ----\n// TypeError 9957: (14-20): Library cannot have non-constant state variables\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/228_valid_library.sol",
    "content": "library Lib { uint constant x = 9; }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/229_call_to_library_function.sol",
    "content": "// This used to work in pre-0.6.0.\nlibrary Lib {\n    function min(uint, uint) public returns (uint);\n}\ncontract Test {\n    function f() public {\n        uint t = Lib.min(12, 7);\n    }\n}\n// ----\n// TypeError 9231: (53-100): Library functions must be implemented if declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/230_creating_contract_within_the_contract.sol",
    "content": "contract Test {\n    function f() public { Test x = new Test(); }\n}\n// ----\n// TypeError 7813: (51-59): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/231_array_out_of_bound_access.sol",
    "content": "contract c {\n    uint[2] dataArray;\n    function set5th() public returns (bool) {\n        dataArray[5] = 2;\n        return true;\n    }\n}\n// ----\n// TypeError 3383: (90-102): Out of bounds array access.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/232_literal_string_to_storage_pointer.sol",
    "content": "contract C {\n    function f() public { string storage x = \"abc\"; }\n}\n// ----\n// TypeError 9574: (39-63): Type literal_string \"abc\" is not implicitly convertible to expected type string storage pointer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/233_non_initialized_references.sol",
    "content": "contract C {\n    struct s {\n        uint a;\n    }\n    function f() public {\n        s storage x;\n        x.a = 2;\n    }\n}\n// ----\n// TypeError 3464: (105-106): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/235_abi_encode_with_large_integer_constant.sol",
    "content": "contract C {\n    function f() pure public { abi.encode(2**500); }\n}\n// ----\n// TypeError 8009: (55-61): Invalid rational number (too large or division by zero).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/236_cyclic_binary_dependency.sol",
    "content": "contract A { function f() public { new B(); } }\ncontract B { function f() public { new C(); } }\ncontract C { function f() public { new A(); } }\n// ----\n// TypeError 7813: (35-40): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (83-88): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n// TypeError 7813: (131-136): Circular reference to contract bytecode either via \"new\" or \"type(...).creationCode\" / \"type(...).runtimeCode\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/237_cyclic_binary_dependency_via_inheritance.sol",
    "content": "contract A is B { }\ncontract B { function f() public { new C(); } }\ncontract C { function f() public { new A(); } }\n// ----\n// TypeError 2449: (14-15): Definition of base has to precede definition of derived contract\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/244_tuples.sol",
    "content": "contract C {\n    function f() public pure {\n        uint a = (1);\n        (uint b,) = (uint8(1),2);\n        (uint c, uint d) = (uint32(1), 2 + a);\n        (uint e, ,) = (uint64(1), 2, b);\n        a;b;c;d;e;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/245_tuples_empty_components.sol",
    "content": "contract C {\n    function f() public {\n        (1,,2);\n    }\n}\n// ----\n// TypeError 8381: (47-53): Tuple component cannot be empty.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/250_member_access_parser_ambiguity.sol",
    "content": "contract C {\n    struct R { uint[10][10] y; }\n    struct S { uint a; uint b; uint[20][20][20] c; R d; }\n    S data;\n    function f() public {\n        C.S storage x = data;\n        C.S memory y;\n        C.S[10] memory z;\n        C.S[10];\n        y.a = 2;\n        x.c[1][2][3] = 9;\n        x.d.y[2][2] = 3;\n        z;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/251_using_for_library.sol",
    "content": "library D { }\ncontract C {\n    using D for uint;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/252_using_for_not_library.sol",
    "content": "contract D { }\ncontract C {\n    using D for uint;\n}\n// ----\n// TypeError 4357: (38-39): Library name expected. If you want to attach a function, use '{...}'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/253_using_for_function_exists.sol",
    "content": "library D { function double(uint self) public returns (uint) { return 2*self; } }\ncontract C {\n    using D for uint;\n    function f(uint a) public {\n        a.double;\n    }\n}\n// ----\n// Warning 2018: (12-79): Function state mutability can be restricted to pure\n// Warning 2018: (121-172): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/254_using_for_function_on_int.sol",
    "content": "library D { function double(uint self) public returns (uint) { return 2*self; } }\ncontract C {\n    using D for uint;\n    function f(uint a) public returns (uint) {\n        return a.double();\n    }\n}\n// ----\n// Warning 2018: (12-79): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/255_using_for_function_on_struct.sol",
    "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n    using D for D.s;\n    D.s x;\n    function f(uint a) public returns (uint) {\n        return x.mul(a);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/256_using_for_overload.sol",
    "content": "library D {\n    struct s { uint a; }\n    function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n    function mul(s storage, bytes32) public returns (bytes32) { }\n}\ncontract C {\n    using D for D.s;\n    D.s x;\n    function f(uint a) public returns (uint) {\n        return x.mul(a);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/257_using_for_by_name.sol",
    "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n    using D for D.s;\n    D.s x;\n    function f(uint a) public returns (uint) {\n        return x.mul({x: a});\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/258_using_for_mismatch.sol",
    "content": "library D { function double(bytes32 self) public returns (uint) { return 2; } }\ncontract C {\n    using D for uint;\n    function f(uint a) public returns (uint) {\n        return a.double();\n    }\n}\n// ----\n// TypeError 9582: (177-185): Member \"double\" not found or not visible after argument-dependent lookup in uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/259_using_for_not_used.sol",
    "content": "library D { function double(uint self) public returns (uint) { return 2; } }\ncontract C {\n    using D for uint;\n    function f(uint16 a) public returns (uint) {\n        // This is an error because the function is only attached to uint.\n        // Had it been attached to *, it would have worked.\n        return a.double();\n    }\n}\n// ----\n// TypeError 9582: (311-319): Member \"double\" not found or not visible after argument-dependent lookup in uint16.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/260_library_memory_struct.sol",
    "content": "pragma abicoder               v2;\nlibrary c {\n    struct S { uint x; }\n    function f() public returns (S memory) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/261_using_for_arbitrary_mismatch.sol",
    "content": "library D { function double(bytes32 self) public returns (uint) { return 2; } }\ncontract C {\n    using D for *;\n    function f(uint a) public returns (uint) {\n        // Attached to a, but self type does not match.\n        return a.double();\n    }\n}\n// ----\n// TypeError 9582: (230-238): Member \"double\" not found or not visible after argument-dependent lookup in uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/263_create_memory_arrays.sol",
    "content": "library L {\n    struct R { uint[10][10] y; }\n    struct S { uint a; uint b; uint[20][20][20] c; R d; }\n}\ncontract C {\n    function f(uint size) public {\n        L.S[][] memory x = new L.S[][](10);\n        uint[] memory y = new uint[](20);\n        bytes memory z = new bytes(size);\n        x;y;z;\n    }\n}\n// ----\n// Warning 2018: (122-301): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/264_mapping_in_memory_array.sol",
    "content": "contract C {\n    function f(uint size) public {\n        mapping(uint => uint) storage x = new mapping(uint => uint)[](4);\n    }\n}\n// ----\n// TypeError 1164: (94-117): Array containing a (nested) mapping cannot be constructed in memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/265_new_for_non_array.sol",
    "content": "contract C {\n    function f(uint size) public {\n        uint x = new uint(7);\n    }\n}\n// ----\n// TypeError 8807: (65-73): Contract or array type expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/268_function_overload_array_type.sol",
    "content": "abstract contract M {\n    function f(uint[] memory) public virtual;\n    function f(int[] memory) public virtual;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/275_inline_struct_declaration_arrays.sol",
    "content": "contract C {\n    struct S {\n        uint a;\n        string b;\n    }\n    function f() public {\n        S[2] memory x = [S({a: 1, b: \"fish\"}), S({a: 2, b: \"fish\"})];\n    }\n}\n// ----\n// Warning 2072: (102-115): Unused local variable.\n// Warning 2018: (72-169): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/279_break_not_in_loop.sol",
    "content": "contract C {\n    function f() public {\n        if (true)\n            break;\n    }\n}\n// ----\n// SyntaxError 6102: (69-74): \"break\" has to be in a \"for\" or \"while\" loop.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/280_continue_not_in_loop.sol",
    "content": "contract C {\n    function f() public {\n        if (true)\n            continue;\n    }\n}\n// ----\n// SyntaxError 4123: (69-77): \"continue\" has to be in a \"for\" or \"while\" loop.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/281_continue_not_in_loop_2.sol",
    "content": "contract C {\n    function f() public {\n        while (true)\n        {\n        }\n        continue;\n    }\n}\n// ----\n// SyntaxError 4123: (88-96): \"continue\" has to be in a \"for\" or \"while\" loop.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/282_invalid_different_types_for_conditional_expression.sol",
    "content": "contract C {\n    function f() public {\n        true ? true : 2;\n    }\n}\n// ----\n// TypeError 1080: (47-62): True expression's type bool does not match false expression's type uint8.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/283_left_value_in_conditional_expression_not_supported_yet.sol",
    "content": "contract C {\n    function f() public {\n        uint x;\n        uint y;\n        (true ? x : y) = 1;\n    }\n}\n// ----\n// TypeError 2212: (80-92): Conditional expression as left value is not supported yet.\n// TypeError 4247: (80-92): Expression has to be an lvalue.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/284_conditional_expression_with_different_struct.sol",
    "content": "contract C {\n    struct s1 {\n        uint x;\n    }\n    struct s2 {\n        uint x;\n    }\n    function f() public {\n        s1 memory x;\n        s2 memory y;\n        true ? x : y;\n    }\n}\n// ----\n// TypeError 1080: (165-177): True expression's type struct C.s1 memory does not match false expression's type struct C.s2 memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/285_conditional_expression_with_different_function_type.sol",
    "content": "contract C {\n    function x(bool) public {}\n    function y() public {}\n\n    function f() public {\n        true ? x : y;\n    }\n}\n// ----\n// TypeError 1080: (106-118): True expression's type function (bool) does not match false expression's type function ().\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/286_conditional_expression_with_different_enum.sol",
    "content": "contract C {\n    enum small { A, B, C, D }\n    enum big { A, B, C, D }\n\n    function f() public {\n        small x;\n        big y;\n\n        true ? x : y;\n    }\n}\n// ----\n// TypeError 1080: (139-151): True expression's type enum C.small does not match false expression's type enum C.big.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/287_conditional_expression_with_different_mapping.sol",
    "content": "contract C {\n    mapping(uint8 => uint8) table1;\n    mapping(uint32 => uint8) table2;\n\n    function f() public {\n        true ? table1 : table2;\n    }\n}\n// ----\n// TypeError 1080: (121-143): True expression's type mapping(uint8 => uint8) does not match false expression's type mapping(uint32 => uint8).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/288_conditional_with_all_types.sol",
    "content": "contract C {\n    struct s1 {\n        uint x;\n    }\n    s1 struct_x;\n    s1 struct_y;\n\n    function fun_x() public {}\n    function fun_y() public {}\n\n    enum small { A, B, C, D }\n\n    mapping(uint8 => uint8) table1;\n    mapping(uint8 => uint8) table2;\n\n    function f() public {\n        // integers\n        uint x;\n        uint y;\n        uint g = true ? x : y;\n        g += 1; // Avoid unused var warning\n\n        // integer constants\n        uint h = true ? 1 : 3;\n        h += 1; // Avoid unused var warning\n\n        // string literal\n        string memory i = true ? \"hello\" : \"world\";\n        i = \"used\"; //Avoid unused var warning\n    }\n    function f2() public {\n        // bool\n        bool j = true ? true : false;\n        j = j && true; // Avoid unused var warning\n\n        // real is not there yet.\n\n        // array\n        bytes1[2] memory a;\n        bytes1[2] memory b;\n        bytes1[2] memory k = true ? a : b;\n        k[0] = bytes1(0); //Avoid unused var warning\n\n        bytes memory e;\n        bytes memory f;\n        bytes memory l = true ? e : f;\n        l[0] = bytes1(0); // Avoid unused var warning\n\n        // fixed bytes\n        bytes2 c;\n        bytes2 d;\n        bytes2 m = true ? c : d;\n        m &= m;\n\n    }\n    function f3() public {\n        // contract doesn't fit in here\n\n        // struct\n        struct_x = true ? struct_x : struct_y;\n\n        // function\n        function () r = true ? fun_x : fun_y;\n        r(); // Avoid unused var warning\n        // enum\n        small enum_x;\n        small enum_y;\n        enum_x = true ? enum_x : enum_y;\n\n        // tuple\n        (uint n, uint o) = true ? (1, 2) : (3, 4);\n        (n, o) = (o, n); // Avoid unused var warning\n        // mapping\n        mapping(uint8 => uint8) storage p = true ? table1 : table2;\n        p[0] = 0; // Avoid unused var warning\n        // typetype\n        uint32 q = true ? uint32(1) : uint32(2);\n        q += 1; // Avoid unused var warning\n        // modifier doesn't fit in here\n\n        // magic doesn't fit in here\n\n        // module doesn't fit in here\n    }\n}\n// ----\n// Warning 2519: (1013-1027): This declaration shadows an existing declaration.\n// Warning 2018: (257-642): Function state mutability can be restricted to pure\n// Warning 2018: (647-1237): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/289_uint7_and_uintM_as_identifier.sol",
    "content": "contract test {\nstring uintM = \"Hello 4 you\";\n    function f() public {\n        uint8 uint7 = 3;\n        uint7 = 5;\n        string memory intM;\n        uint bytesM = 21;\n        intM; bytesM;\n    }\n}\n// ----\n// Warning 2018: (50-197): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/290_varM_disqualified_as_keyword_1.sol",
    "content": "contract test {\n    function f() public {\n        uintM something = 3;\n    }\n}\n// ----\n// DeclarationError 7920: (50-55): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/290_varM_disqualified_as_keyword_2.sol",
    "content": "contract test {\n    function f() public {\n        intM should = 4;\n    }\n}\n// ----\n// DeclarationError 7920: (50-54): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/290_varM_disqualified_as_keyword_3.sol",
    "content": "contract test {\n    function f() public {\n        bytesM fail = \"now\";\n    }\n}\n// ----\n// DeclarationError 7920: (50-56): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/291_modifier_is_not_a_valid_typename.sol",
    "content": "contract test {\n    modifier mod() { _; }\n\n    function f() public {\n        mod g;\n    }\n}\n// ----\n// TypeError 5172: (77-80): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/292_modifier_is_not_a_valid_typename_is_not_fatal.sol",
    "content": "contract test {\n    modifier mod() { _; }\n\n    function f() public {\n        mod g;\n        g = f;\n    }\n}\n// ----\n// TypeError 5172: (77-80): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/293_function_is_not_a_valid_typename.sol",
    "content": "contract test {\n    function foo() public {\n    }\n\n    function f() public {\n        foo g;\n    }\n}\n// ----\n// TypeError 5172: (85-88): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/294_long_uint_variable_fails.sol",
    "content": "contract test {\n    function f() public {\n        uint99999999999999999999999999 something = 3;\n    }\n}\n// ----\n// DeclarationError 7920: (50-80): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/295_bytes10abc_is_identifier.sol",
    "content": "contract test {\n    function f() public {\n        bytes32 bytes10abc = \"abc\";\n    }\n}\n// ----\n// Warning 2072: (50-68): Unused local variable.\n// Warning 2018: (20-83): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/296_int10abc_is_identifier.sol",
    "content": "contract test {\n    function f() public {\n        uint uint10abc = 3;\n        int int10abc = 4;\n        uint10abc; int10abc;\n    }\n}\n// ----\n// Warning 2018: (20-130): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/297_library_functions_do_not_have_value.sol",
    "content": "library L { function l() public {} }\ncontract test {\n    function f() public {\n        L.l.value;\n    }\n}\n// ----\n// TypeError 8477: (87-96): Member \"value\" is not allowed in delegated calls due to \"msg.value\" persisting.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/298_invalid_fixed_types_0x7_mxn.sol",
    "content": "contract test {\n    fixed0x7 a = .3;\n}\n// ----\n// DeclarationError 7920: (20-28): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/299_invalid_fixed_types_long_invalid_identifier.sol",
    "content": "contract test {\n    fixed99999999999999999999999999999999999999x7 b = 9.5;\n}\n// ----\n// DeclarationError 7920: (20-65): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/300_invalid_fixed_types_7x8_mxn.sol",
    "content": "contract test {\n    fixed7x8 c = 3.12345678;\n}\n// ----\n// DeclarationError 7920: (20-28): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/301_library_instances_cannot_be_used.sol",
    "content": "library L { function l() public {} }\ncontract test {\n    function f() public {\n        L x;\n        x.l();\n    }\n}\n// ----\n// TypeError 1130: (87-88): Invalid use of a library name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/302_invalid_fixed_type_long.sol",
    "content": "contract test {\n    function f() public {\n        fixed8x888888888888888888888888888888888888888888888888888 b;\n    }\n}\n// ----\n// DeclarationError 7920: (50-108): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/303_fixed_type_int_conversion.sol",
    "content": "contract test {\n    function f() public {\n        uint64 a = 3;\n        int64 b = 4;\n        fixed c = b;\n        ufixed d = a;\n        c; d;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// Warning 2018: (20-147): Function state mutability can be restricted to pure\n// UnimplementedFeatureError 1834: (93-104): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/304_fixed_type_rational_int_conversion.sol",
    "content": "contract test {\n    function f() public {\n        fixed c = 3;\n        ufixed d = 4;\n        c; d;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// Warning 2018: (20-104): Function state mutability can be restricted to pure\n// UnimplementedFeatureError 1834: (50-61): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/305_fixed_type_rational_fraction_conversion.sol",
    "content": "contract test {\n    function f() public {\n        fixed a = 4.5;\n        ufixed d = 2.5;\n        a; d;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// Warning 2018: (20-108): Function state mutability can be restricted to pure\n// UnimplementedFeatureError 1834: (50-63): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/306_invalid_int_implicit_conversion_from_fixed.sol",
    "content": "contract test {\n    function f() public {\n        fixed a = 4.5;\n        int b = a;\n        a; b;\n    }\n}\n// ----\n// TypeError 9574: (73-82): Type fixed128x18 is not implicitly convertible to expected type int256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/307_rational_unary_minus_operation.sol",
    "content": "contract test {\n    function f() pure public {\n        ufixed16x2 a = 3.25;\n        fixed16x2 b = -3.25;\n        a; b;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// UnimplementedFeatureError 1834: (55-74): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/308_rational_unary_plus_operation.sol",
    "content": "contract test {\n    function f() pure public {\n        ufixed16x2 a = +3.25;\n        fixed16x2 b = -3.25;\n        a; b;\n    }\n}\n// ----\n// ParserError 9636: (70-71): Use of unary + is disallowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/312_leading_zero_rationals_convert.sol",
    "content": "contract A {\n    function f() pure public {\n        ufixed16x2 a = 0.5;\n        ufixed256x52 b = 0.0000000000000006661338147750939242541790008544921875;\n        fixed16x2 c = -0.5;\n        fixed256x52 d = -0.0000000000000006661338147750939242541790008544921875;\n        a; b; c; d;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// UnimplementedFeatureError 1834: (52-70): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/313_fixed_type_size_capabilities.sol",
    "content": "contract test {\n    function f() public {\n        ufixed256x1 a = 123456781234567979695948382928485849359686494864095409282048094275023098123.5;\n        ufixed256x77 b = 0.920890746623327805482905058466021565416131529487595827354393978494366605267637;\n        ufixed224x78 c = 0.000000000001519884736399797998492268541131529487595827354393978494366605267646;\n        fixed256x1 d = -123456781234567979695948382928485849359686494864095409282048094275023098123.5;\n        fixed256x76 e = -0.93322335481643744342575580035176794825198893968114429702091846411734101080123;\n        fixed256x79 g = -0.0001178860664374434257558003517679482519889396811442970209184641173410108012309;\n        a; b; c; d; e; g;\n    }\n}\n// ----\n// TypeError 5107: (153-250): Type rational_const 9208...(70 digits omitted)...7637 / 1000...(71 digits omitted)...0000 is not implicitly convertible to expected type ufixed256x77, but it can be explicitly converted.\n// TypeError 5107: (470-566): Type rational_const -933...(70 digits omitted)...0123 / 1000...(70 digits omitted)...0000 is not implicitly convertible to expected type fixed256x76, but it can be explicitly converted.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/314_fixed_type_zero_handling.sol",
    "content": "contract test {\n    function f() public {\n        fixed16x2 a = 0; a;\n        ufixed32x1 b = 0; b;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// Warning 2018: (20-104): Function state mutability can be restricted to pure\n// UnimplementedFeatureError 1834: (50-65): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/315_fixed_type_invalid_implicit_conversion_size.sol",
    "content": "contract test {\n    function f() public {\n        ufixed a = 11/4;\n        ufixed248x8 b = a; b;\n    }\n}\n// ----\n// TypeError 9574: (75-92): Type ufixed128x18 is not implicitly convertible to expected type ufixed248x8. Too many fractional digits.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/316_fixed_type_invalid_implicit_conversion_lost_data.sol",
    "content": "contract test {\n    function f() public {\n        ufixed256x1 a = 1/3; a;\n    }\n}\n// ----\n// TypeError 4486: (50-69): Type rational_const 1 / 3 is not implicitly convertible to expected type ufixed256x1. Try converting to type ufixed256x77 or use an explicit conversion.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/317_fixed_type_valid_explicit_conversions.sol",
    "content": "contract test {\n    function f() public {\n        ufixed256x80 a = ufixed256x80(1/3); a;\n        ufixed248x80 b = ufixed248x80(1/3); b;\n        ufixed8x1 c = ufixed8x1(1/3); c;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// Warning 2018: (20-182): Function state mutability can be restricted to pure\n// UnimplementedFeatureError 1834: (67-84): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/318_invalid_array_declaration_with_rational.sol",
    "content": "contract test {\n    function f() public {\n        uint[3.5] a; a;\n    }\n}\n// ----\n// TypeError 3208: (55-58): Array with fractional length specified.\n// TypeError 6651: (50-61): Data location must be \"storage\", \"memory\" or \"calldata\" for variable, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/319_invalid_array_declaration_with_signed_fixed_type.sol",
    "content": "contract test {\n    function f() public {\n        uint[fixed(3.5)] a; a;\n    }\n}\n// ----\n// TypeError 5462: (55-65): Invalid array length, expected integer literal or constant expression.\n// TypeError 6651: (50-68): Data location must be \"storage\", \"memory\" or \"calldata\" for variable, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/320_invalid_array_declaration_with_unsigned_fixed_type.sol",
    "content": "contract test {\n    function f() public {\n        uint[ufixed(3.5)] a; a;\n    }\n}\n// ----\n// TypeError 5462: (55-66): Invalid array length, expected integer literal or constant expression.\n// TypeError 6651: (50-69): Data location must be \"storage\", \"memory\" or \"calldata\" for variable, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/321_rational_to_bytes_implicit_conversion.sol",
    "content": "contract test {\n    function f() public {\n        bytes32 c = 3.2; c;\n    }\n}\n// ----\n// TypeError 4486: (50-65): Type rational_const 16 / 5 is not implicitly convertible to expected type bytes32. Try converting to type ufixed8x1 or use an explicit conversion.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/322_fixed_to_bytes_implicit_conversion.sol",
    "content": "contract test {\n    function f() public {\n        fixed a = 3.25;\n        bytes32 c = a; c;\n    }\n}\n// ----\n// TypeError 9574: (74-87): Type fixed128x18 is not implicitly convertible to expected type bytes32.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/323_mapping_with_fixed_literal.sol",
    "content": "contract test {\n    mapping(ufixed8x1 => string) fixedString;\n    function f() public {\n        fixedString[0.5] = \"Half\";\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// UnimplementedFeatureError 1834: (96-112): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/324_fixed_points_inside_structs.sol",
    "content": "contract test {\n    struct myStruct {\n        ufixed a;\n        int b;\n    }\n    myStruct a = myStruct(3.125, 3);\n}\n// ====\n// compileViaYul: true\n// ----\n// UnimplementedFeatureError 1834: (94-112): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/327_rational_index_access.sol",
    "content": "contract test {\n    function f() public {\n        uint[] memory a;\n        a[.5];\n    }\n}\n// ----\n// TypeError 2326: (77-79): Type rational_const 1 / 2 is not implicitly convertible to expected type uint256. Try converting to type ufixed8x1 or use an explicit conversion.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/328_rational_to_fixed_literal_expression.sol",
    "content": "contract test {\n    function f() public {\n        ufixed64x8 a = 3.5 * 3;\n        ufixed64x8 b = 4 - 2.5;\n        ufixed64x8 c = 11 / 4;\n        ufixed240x5 d = 599 + 0.21875;\n        ufixed256x80 e = ufixed256x80(35.245 % 12.9);\n        ufixed256x80 f = ufixed256x80(1.2 % 2);\n        fixed g = 2 ** -2;\n        a; b; c; d; e; f; g;\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// Warning 2519: (238-252): This declaration shadows an existing declaration.\n// Warning 2018: (20-339): Function state mutability can be restricted to pure\n// UnimplementedFeatureError 1834: (50-72): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/329_rational_as_exponent_value_signed.sol",
    "content": "contract test {\n    function f() public {\n        fixed g = 2 ** -2.2;\n    }\n}\n// ----\n// TypeError 2271: (60-69): Built-in binary operator ** cannot be applied to types int_const 2 and rational_const -11 / 5.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/330_rational_as_exponent_value_unsigned.sol",
    "content": "contract test {\n    function f() public {\n        ufixed b = 3 ** 2.5;\n    }\n}\n// ----\n// TypeError 2271: (61-69): Built-in binary operator ** cannot be applied to types int_const 3 and rational_const 5 / 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/331_rational_as_exponent_half.sol",
    "content": "contract test {\n    function f() public {\n        2 ** (1/2);\n    }\n}\n// ----\n// TypeError 2271: (50-60): Built-in binary operator ** cannot be applied to types int_const 2 and rational_const 1 / 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/332_rational_as_exponent_value_neg_quarter.sol",
    "content": "contract test {\n    function f() public {\n        42 ** (-1/4);\n    }\n}\n// ----\n// TypeError 2271: (50-62): Built-in binary operator ** cannot be applied to types int_const 42 and rational_const -1 / 4.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/333_fixed_point_casting_exponents_15.sol",
    "content": "contract test {\n    function f() public {\n        ufixed a = 3 ** ufixed(1.5);\n    }\n}\n// ----\n// TypeError 2271: (61-77): Built-in binary operator ** cannot be applied to types int_const 3 and ufixed128x18. Exponent is fractional.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/334_fixed_point_casting_exponents_neg.sol",
    "content": "contract test {\n    function f() public {\n        ufixed c = 42 ** fixed(-1/4);\n    }\n}\n// ----\n// TypeError 2271: (61-78): Built-in binary operator ** cannot be applied to types int_const 42 and fixed128x18. Exponent is fractional.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/338_rational_bitnot_unary_operation.sol",
    "content": "contract test {\n    function f() public {\n        ~fixed(3.5);\n    }\n}\n// ----\n// TypeError 4907: (50-61): Built-in unary operator ~ cannot be applied to type fixed128x18.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/339_rational_bitor_binary_operation.sol",
    "content": "contract test {\n    function f() public {\n        fixed(1.5) | 3;\n    }\n}\n// ----\n// TypeError 2271: (50-64): Built-in binary operator | cannot be applied to types fixed128x18 and int_const 3.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/340_rational_bitxor_binary_operation.sol",
    "content": "contract test {\n    function f() public {\n        fixed(1.75) ^ 3;\n    }\n}\n// ----\n// TypeError 2271: (50-65): Built-in binary operator ^ cannot be applied to types fixed128x18 and int_const 3.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/341_rational_bitand_binary_operation.sol",
    "content": "contract test {\n    function f() public {\n        fixed(1.75) & 3;\n    }\n}\n// ----\n// TypeError 2271: (50-65): Built-in binary operator & cannot be applied to types fixed128x18 and int_const 3.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/342_missing_bool_conversion.sol",
    "content": "contract test {\n    function b(uint a) public {\n        bool(a == 1);\n    }\n}\n// ----\n// Warning 2018: (20-75): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/343_integer_and_fixed_interaction.sol",
    "content": "contract test {\n    function f() public {\n        ufixed a = uint64(1) + ufixed(2);\n    }\n}\n// ====\n// compileViaYul: true\n// ----\n// Warning 2072: (50-58): Unused local variable.\n// Warning 2018: (20-89): Function state mutability can be restricted to pure\n// UnimplementedFeatureError 1834: (73-82): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/344_one_divided_by_three_integer_conversion.sol",
    "content": "contract test {\n    function f() public {\n        uint a = 1/3;\n    }\n}\n// ----\n// TypeError 4486: (50-62): Type rational_const 1 / 3 is not implicitly convertible to expected type uint256. Try converting to type ufixed256x77 or use an explicit conversion.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/345_unused_return_value.sol",
    "content": "contract test {\n    function g() public returns (uint) {}\n    function f() public {\n        g();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/346_unused_return_value_send.sol",
    "content": "contract test {\n    function f() public {\n        payable(address(0x12)).send(1);\n    }\n}\n// ----\n// Warning 9207: (50-77): 'send' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 5878: (50-80): Failure condition of 'send' ignored. Consider using 'transfer' instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/347_unused_return_value_call.sol",
    "content": "contract test {\n    function f() public {\n        address(0x12).call(\"abc\");\n    }\n}\n// ----\n// Warning 9302: (50-75): Return value of low-level calls not used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/348_unused_return_value_call_value.sol",
    "content": "contract test {\n    function f() public {\n        address(0x12).call{value: 2}(\"abc\");\n    }\n}\n// ----\n// Warning 9302: (50-85): Return value of low-level calls not used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/350_unused_return_value_delegatecall.sol",
    "content": "contract test {\n    function f() public {\n        address(0x12).delegatecall(\"abc\");\n    }\n}\n// ----\n// Warning 9302: (50-83): Return value of low-level calls not used.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/351_callcode_deprecated.sol",
    "content": "contract test {\n    function f() pure public {\n        address(0x12).callcode;\n    }\n}\n// ----\n// TypeError 2256: (55-77): \"callcode\" has been deprecated in favour of \"delegatecall\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/353_callcode_not_deprecated_as_function.sol",
    "content": "contract test {\n    function callcode() pure public {\n        test.callcode();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/354_payable_in_library.sol",
    "content": "library test {\n    function f() payable public {}\n}\n// ----\n// TypeError 7708: (19-49): Library functions cannot be payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/355_payable_external.sol",
    "content": "contract test {\n    function f() payable external {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/356_payable_internal.sol",
    "content": "contract test {\n    function f() payable internal {}\n}\n// ----\n// TypeError 5587: (20-52): \"internal\" and \"private\" functions cannot be payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/357_payable_private.sol",
    "content": "contract test {\n    function f() payable private {}\n}\n// ----\n// TypeError 5587: (20-51): \"internal\" and \"private\" functions cannot be payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/358_illegal_override_payable.sol",
    "content": "contract B { function f() payable virtual public {} }\ncontract C is B { function f() public {} }\n// ----\n// TypeError 9456: (72-94): Overriding function is missing \"override\" specifier.\n// TypeError 6959: (72-94): Overriding function changes state mutability from \"payable\" to \"nonpayable\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/359_illegal_override_payable_nonpayable.sol",
    "content": "contract B { function f() virtual public {} }\ncontract C is B { function f() payable public {} }\n// ----\n// TypeError 9456: (64-94): Overriding function is missing \"override\" specifier.\n// TypeError 6959: (64-94): Overriding function changes state mutability from \"nonpayable\" to \"payable\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/360_function_variable_mixin.sol",
    "content": "// bug #1798 (cpp-ethereum), related to #1286 (solidity)\ncontract attribute {\n    bool ok = false;\n}\ncontract func {\n    function ok() public returns (bool) { return true; }\n}\ncontract attr_func is attribute, func {\n    function checkOk() public returns (bool) { return ok(); }\n}\n// ----\n// DeclarationError 9097: (121-173): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/361_calling_payable.sol",
    "content": "contract receiver { function pay() payable public {} }\ncontract test {\n    function f() public { (new receiver()).pay{value: 10}(); }\n    receiver r = new receiver();\n    function h() public { r.pay{value: 10}(); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/362_calling_nonpayable.sol",
    "content": "contract receiver { function nopay() public {} }\ncontract test {\n    function f() public { (new receiver()).nopay{value: 10}(); }\n    function g() public { (new receiver()).nopay.value(10)(); }\n}\n// ----\n// TypeError 7006: (91-124): Cannot set option \"value\" on a non-payable function type.\n// TypeError 8820: (156-184): Member \"value\" is only available for payable functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/363_non_payable_constructor.sol",
    "content": "contract C {\n    constructor() { }\n}\ncontract D {\n    function f() public returns (uint) {\n        (new C){value: 2}();\n        return 2;\n    }\n}\n// ----\n// TypeError 7006: (99-116): Cannot set option \"value\", since the constructor of contract C is not payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/366_invalid_array_as_statement.sol",
    "content": "contract test {\n    struct S { uint x; }\n    constructor(uint k) { S[k]; }\n}\n// ----\n// TypeError 3940: (69-70): Integer constant expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/367_using_directive_for_missing_selftype.sol",
    "content": "library B {\n    function b() public {}\n}\n\ncontract A {\n    using B for bytes;\n\n    function a() public {\n        bytes memory x;\n        x.b();\n    }\n}\n// ----\n// TypeError 9582: (137-140): Member \"b\" not found or not visible after argument-dependent lookup in bytes memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/368_shift_constant_left_negative_rvalue.sol",
    "content": "contract C {\n    uint public a = 0x42 << -8;\n}\n// ----\n// TypeError 2271: (33-43): Built-in binary operator << cannot be applied to types int_const 66 and int_const -8.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/369_shift_constant_right_negative_rvalue.sol",
    "content": "contract C {\n    uint public a = 0x42 >> -8;\n}\n// ----\n// TypeError 2271: (33-43): Built-in binary operator >> cannot be applied to types int_const 66 and int_const -8.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/370_shift_constant_left_excessive_rvalue.sol",
    "content": "contract C {\n    uint public a = 0x42 << 0x100000000;\n}\n// ----\n// TypeError 2271: (33-52): Built-in binary operator << cannot be applied to types int_const 66 and int_const 4294967296.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/371_shift_constant_right_excessive_rvalue.sol",
    "content": "contract C {\n    uint public a = 0x42 >> 0x100000000;\n}\n// ----\n// TypeError 2271: (33-52): Built-in binary operator >> cannot be applied to types int_const 66 and int_const 4294967296.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/372_shift_constant_right_fractional.sol",
    "content": "contract C {\n    uint public a = 0x42 >> (1 / 2);\n}\n// ----\n// TypeError 2271: (33-48): Built-in binary operator >> cannot be applied to types int_const 66 and rational_const 1 / 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/396_invalid_mobile_type.sol",
    "content": "    contract C {\n        function f() public {\n            // Invalid number\n            78901234567890123456789012345678901234567890123456789345678901234567890012345678012345678901234567;\n            [1, 78901234567890123456789012345678901234567890123456789345678901234567890012345678012345678901234567];\n        }\n    }\n// ----\n// TypeError 3757: (89-187): Invalid rational number.\n// TypeError 3390: (205-303): Invalid rational number.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/397_warns_msg_value_in_non_payable_public_function.sol",
    "content": "contract C {\n    function f() view public {\n        msg.value;\n    }\n}\n// ----\n// TypeError 5887: (52-61): \"msg.value\" and \"callvalue()\" can only be used in payable public functions. Make the function \"payable\" or use an internal function to avoid this error.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/398_does_not_warn_msg_value_in_payable_function.sol",
    "content": "contract C {\n    function f() payable public {\n        msg.value;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/399_does_not_warn_msg_value_in_internal_function.sol",
    "content": "contract C {\n    function f() view internal {\n        msg.value;\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/400_does_not_warn_msg_value_in_library.sol",
    "content": "library C {\n    function f() view public {\n        msg.value;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/401_does_not_warn_msg_value_in_modifier_following_non_payable_public_function.sol",
    "content": "contract c {\n    function f() pure public { }\n    modifier m() { msg.value; _; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/402_assignment_to_constant.sol",
    "content": "contract c {\n    uint constant a = 1;\n    function f() public { a = 2; }\n}\n// ----\n// TypeError 6520: (64-65): Cannot assign to a constant variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/403_return_structs.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    struct S { uint a; T[] sub; }\n    struct T { uint[] x; }\n    function f() public returns (uint, S memory) {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/404_read_returned_struct.sol",
    "content": "pragma abicoder               v2;\ncontract A {\n    struct T {\n        int x;\n        int y;\n    }\n    function g() public returns (T memory) {\n        return this.g();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/405_address_checksum_type_deduction.sol",
    "content": "contract C {\n    function f() public {\n        payable(0xfA0bFc97E48458494Ccd857e1A85DC91F7F0046E).transfer(2);\n    }\n}\n// ----\n// Warning 9207: (47-107): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/406_invalid_address_checksum.sol",
    "content": "contract C {\n    function f() pure public {\n        address x = 0xFA0bFc97E48458494Ccd857e1A85DC91F7F0046E;\n        x;\n    }\n}\n// ----\n// SyntaxError 9429: (64-106): This looks like an address but has an invalid checksum. Correct checksummed address: \"0xfA0bFc97E48458494Ccd857e1A85DC91F7F0046E\". If this is not used as an address, please prepend '00'. For more information please see https://docs.soliditylang.org/en/develop/types.html#address-literals\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/407_invalid_address_no_checksum.sol",
    "content": "contract C {\n    function f() pure public {\n        address x = 0xfa0bfc97e48458494ccd857e1a85dc91f7f0046e;\n        x;\n    }\n}\n// ----\n// SyntaxError 9429: (64-106): This looks like an address but has an invalid checksum. Correct checksummed address: \"0xfA0bFc97E48458494Ccd857e1A85DC91F7F0046E\". If this is not used as an address, please prepend '00'. For more information please see https://docs.soliditylang.org/en/develop/types.html#address-literals\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/408_invalid_address_length_short.sol",
    "content": "contract C {\n    function f() pure public {\n        address x = 0xA0bFc97E48458494Ccd857e1A85DC91F7F0046E;\n        x;\n    }\n}\n// ----\n// SyntaxError 9429: (64-105): This looks like an address but is not exactly 40 hex digits. It is 39 hex digits. If this is not used as an address, please prepend '00'. For more information please see https://docs.soliditylang.org/en/develop/types.html#address-literals\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/409_invalid_address_length_long.sol",
    "content": "contract C {\n    function f() pure public {\n        address x = 0xFA0bFc97E48458494Ccd857e1A85DC91F7F0046E0;\n        x;\n    }\n}\n// ----\n// SyntaxError 9429: (64-107): This looks like an address but is not exactly 40 hex digits. It is 41 hex digits. If this is not used as an address, please prepend '00'. For more information please see https://docs.soliditylang.org/en/develop/types.html#address-literals\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/410_string_literal_not_convertible_to_address_as_assignment.sol",
    "content": "// A previous implementation claimed the string would be an address\ncontract AddrString {\n    address public test = \"0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c\";\n}\n// ----\n// TypeError 7407: (116-160): Type literal_string \"0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c\" is not implicitly convertible to expected type address.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/411_string_literal_not_convertible_to_address_as_return_value.sol",
    "content": "// A previous implementation claimed the string would be an address\ncontract AddrString {\n    function f() public returns (address) {\n        return \"0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c\";\n   }\n}\n// ----\n// TypeError 6359: (149-193): Return argument type literal_string \"0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c\" is not implicitly convertible to expected type (type of first return variable) address.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/412_early_exit_on_fatal_errors.sol",
    "content": "// This tests a crash that occurred because we did not stop for fatal errors.\ncontract C {\n    struct S {\n        ftring a;\n    }\n    S public s;\n    function s() public s {\n    }\n}\n// ----\n// DeclarationError 2333: (150-179): Identifier already declared.\n// DeclarationError 7920: (114-120): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/413_address_methods.sol",
    "content": "contract C {\n    function f() public {\n        address payable addr;\n        uint balance = addr.balance;\n        (bool callSuc,) = addr.call(\"\");\n        (bool delegatecallSuc,) = addr.delegatecall(\"\");\n        bool sendRet = addr.send(1);\n        addr.transfer(1);\n        balance; callSuc; delegatecallSuc; sendRet;\n    }\n}\n// ----\n// Warning 9207: (227-236): 'send' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 9207: (249-262): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/414_interface.sol",
    "content": "interface I {\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/415_interface_functions.sol",
    "content": "interface I {\n    fallback() external;\n    function f() external;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/416_interface_function_bodies.sol",
    "content": "interface I {\n    function f() external pure {\n    }\n}\n// ----\n// TypeError 4726: (18-52): Functions in interfaces cannot have an implementation.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/417_interface_events.sol",
    "content": "interface I {\n    event E();\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/418_interface_inheritance.sol",
    "content": "interface A {\n}\ninterface I is A {\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/419_interface_structs.sol",
    "content": "interface I {\n    struct A {\n        int dummy;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/420_interface_variables.sol",
    "content": "interface I {\n    uint a;\n}\n// ----\n// TypeError 8274: (18-24): Variables cannot be declared in interfaces.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/421_interface_function_parameters.sol",
    "content": "interface I {\n    function f(uint a) external returns (bool);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/422_interface_enums.sol",
    "content": "interface I {\n    enum A { B, C }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/423_using_interface.sol",
    "content": "interface I {\n    function f() external;\n}\ncontract C is I {\n    function f() public override {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/424_using_interface_complex.sol",
    "content": "interface I {\n    event A();\n    function f() external;\n    function g() external;\n    fallback() external;\n}\nabstract contract C is I {\n    function f() public override {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/425_interface_implement_public_contract.sol",
    "content": "interface I {\n    function f() external;\n}\ncontract C is I {\n    function f() public override {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/426_throw_is_deprecated.sol",
    "content": "contract C {\n    function f() pure public {\n        throw;\n    }\n}\n// ----\n// SyntaxError 4538: (52-57): \"throw\" is deprecated in favour of \"revert()\", \"require()\" and \"assert()\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/428_bare_revert.sol",
    "content": "contract C {\n    function f(uint x) pure public {\n        if (x > 7)\n            revert;\n    }\n}\n// ----\n// TypeError 2144: (81-87): No matching declaration found after variable lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/429_revert_with_reason.sol",
    "content": "contract C {\n    function f(uint x) pure public {\n        if (x > 7)\n            revert(\"abc\");\n        else\n            revert();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/431_bare_assert.sol",
    "content": "contract C {\n    function f() pure public { assert; }\n}\n// ----\n// Warning 6133: (44-50): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/432_bare_require.sol",
    "content": "contract C {\n    // This is different because it does have overloads.\n    function f() pure public { require; }\n}\n// ----\n// TypeError 2144: (101-108): No matching declaration found after variable lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/433_pure_statement_in_for_loop.sol",
    "content": "contract C {\n    function f() pure public {\n        for (uint x = 0; x < 10; true)\n            x++;\n    }\n}\n// ----\n// Warning 6133: (77-81): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/434_pure_statement_check_for_regular_for_loop.sol",
    "content": "contract C {\n    function f() pure public {\n        for (uint x = 0; true; x++)\n        {}\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/438_unused_unnamed_function_parameter.sol",
    "content": "contract C {\n    function f(uint) pure public {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/441_unused_unnamed_return_parameter.sol",
    "content": "contract C {\n    function f() pure public returns (uint) {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/442_named_return_parameter.sol",
    "content": "contract C {\n    function f() pure public returns (uint a) {\n        a = 1;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/443_named_return_parameter_with_explicit_return.sol",
    "content": "contract C {\n    function f() pure public returns (uint a) {\n        return 1;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/444_unnamed_return_parameter_with_explicit_return.sol",
    "content": "contract C {\n    function f() pure public returns (uint) {\n        return 1;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/445_no_unused_warning_interface_arguments.sol",
    "content": "interface I {\n    function f(uint a) pure external returns (uint b);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/446_no_unused_warning_abstract_arguments.sol",
    "content": "abstract contract C {\n    function f(uint a) pure public virtual returns (uint b);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/447_no_unused_warnings.sol",
    "content": "contract C {\n    function f(uint a) pure public returns (uint b) {\n        uint c = 1;\n        b = a + c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/459_function_overload_is_not_shadowing.sol",
    "content": "contract C {\n    function f() pure public {}\n    function f(uint) pure public {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/460_function_override_is_not_shadowing.sol",
    "content": "contract D { function f() pure public {} }\ncontract C is D {\n    function f(uint) pure public {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/461_event_parameter_cannot_shadow_state_variable.sol",
    "content": "contract C {\n    address a;\n    event E(address a);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/462_callable_crash.sol",
    "content": "contract C {\n    struct S { uint a; bool x; }\n    S public s;\n    constructor() {\n        3({a: 1, x: true});\n    }\n}\n// ----\n// TypeError 5704: (90-108): This expression is not callable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/466_does_not_error_transfer_payable_fallback.sol",
    "content": "// This used to be a test for a.transfer to generate a warning\n// because A does not have a payable fallback function.\n\ncontract A {\n    receive() payable external {}\n}\n\ncontract B {\n    A a;\n\n    fallback() external {\n        payable(a).transfer(100);\n    }\n}\n// ----\n// Warning 9207: (227-246): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/467_does_not_error_transfer_regular_function.sol",
    "content": "contract A {\n    function transfer() pure public {}\n}\n\ncontract B {\n    A a;\n\n    fallback() external {\n        a.transfer();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/470_specified_storage_no_warn.sol",
    "content": "contract C {\n    struct S { uint a; string b; }\n    S x;\n    function f() view public {\n        S storage y = x;\n        y;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_fail.sol",
    "content": "contract C {\n    struct S { uint a; }\n    S m_x;\n    uint[] m_y;\n    function f() view public {\n        S x = m_x;\n        uint[] y = m_y;\n        x; y;\n    }\n}\n// ----\n// TypeError 6651: (104-107): Data location must be \"storage\", \"memory\" or \"calldata\" for variable, but none was given.\n// TypeError 6651: (123-131): Data location must be \"storage\", \"memory\" or \"calldata\" for variable, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/473_storage_location_non_array_or_struct_disallowed.sol",
    "content": "contract C {\n    function f(uint storage a) public { }\n}\n// ----\n// TypeError 6651: (28-42): Data location can only be specified for array, struct or mapping types, but \"storage\" was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/474_storage_location_non_array_or_struct_disallowed_is_not_fatal.sol",
    "content": "contract C {\n    function f(uint storage a) public {\n        a = f;\n    }\n}\n// ----\n// TypeError 6651: (28-42): Data location can only be specified for array, struct or mapping types, but \"storage\" was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/475_implicit_conversion_disallowed.sol",
    "content": "contract C {\n    function f() public returns (bytes4) {\n        uint32 tmp = 1;\n        return tmp;\n    }\n}\n// ----\n// TypeError 6359: (95-98): Return argument type uint32 is not implicitly convertible to expected type (type of first return variable) bytes4.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/476_too_large_arrays_for_calldata_external.sol",
    "content": "contract C {\n    function f(uint[85678901234] calldata a) pure external {\n    }\n}\n// ----\n// TypeError 1534: (28-56): Type too large for calldata.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/477_too_large_arrays_for_calldata_internal.sol",
    "content": "contract C {\n    function f(uint[85678901234] memory a) pure internal {\n    }\n}\n// ----\n// TypeError 1534: (28-54): Type too large for memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/478_too_large_arrays_for_calldata_public.sol",
    "content": "contract C {\n    function f(uint[85678901234] memory a) pure public {\n    }\n}\n// ----\n// TypeError 1534: (28-54): Type too large for memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/479_explicit_literal_to_memory_string_assignment.sol",
    "content": "contract C {\n    function f() pure public {\n        string memory x = \"abc\";\n        x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/480_explicit_literal_to_storage_string_assignment.sol",
    "content": "contract C {\n    function f() pure public {\n        string storage x = \"abc\";\n    }\n}\n// ----\n// TypeError 9574: (52-76): Type literal_string \"abc\" is not implicitly convertible to expected type string storage pointer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/481_explicit_literal_to_unspecified_string_assignment.sol",
    "content": "contract C {\n    function f() pure public {\n        string storage x = \"abc\";\n    }\n}\n// ----\n// TypeError 9574: (52-76): Type literal_string \"abc\" is not implicitly convertible to expected type string storage pointer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/482_explicit_literal_to_unspecified_string.sol",
    "content": "contract C {\n    function f() pure public {\n        string(\"abc\");\n    }\n}\n// ----\n// Warning 6133: (52-65): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/483_modifiers_access_storage_pointer.sol",
    "content": "contract C {\n    struct S { uint a; }\n    modifier m(S storage x) {\n        x;\n        _;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/484_function_types_selector_1.sol",
    "content": "contract C {\n    function f() public view returns (bytes4) {\n        return f.selector;\n    }\n}\n// ----\n// TypeError 9582: (76-86): Member \"selector\" not found or not visible after argument-dependent lookup in function () view returns (bytes4).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/485_function_types_selector_2.sol",
    "content": "contract C {\n    function g() pure internal {\n    }\n    function f() public view returns (bytes4) {\n        return g.selector;\n    }\n}\n// ----\n// TypeError 9582: (115-125): Member \"selector\" not found or not visible after argument-dependent lookup in function () pure.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/486_function_types_selector_3.sol",
    "content": "contract C {\n    function f() public view returns (bytes4) {\n        function () g;\n        return g.selector;\n    }\n}\n// ----\n// TypeError 9582: (99-109): Member \"selector\" not found or not visible after argument-dependent lookup in function ().\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/487_function_types_selector_4.sol",
    "content": "contract C {\n    function f() pure external returns (bytes4) {\n        return this.f.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/488_function_types_selector_5.sol",
    "content": "contract C {\n    function h() pure external {\n    }\n    function f() pure external returns (bytes4) {\n        return this.h.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/489_function_types_selector_6.sol",
    "content": "contract C {\n    function h() pure external {\n    }\n    function f() view external returns (bytes4) {\n        function () pure external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/490_function_types_selector_7.sol",
    "content": "contract C {\n    function h() pure external {\n    }\n    function f() view external returns (bytes4) {\n        function () pure external g = this.h;\n        return g.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/491_using_this_in_constructor.sol",
    "content": "contract C {\n    constructor() {\n        this.f();\n    }\n    function f() pure public {\n    }\n}\n// ----\n// Warning 5805: (41-45): \"this\" used in constructor. Note that external functions of a contract cannot be called while it is being constructed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/492_do_not_crash_on_not_lvalue.sol",
    "content": "// This checks for a bug that caused a crash because of continued analysis.\ncontract C {\n    mapping (uint => uint) m;\n    function f() public {\n        m(1) = 2;\n    }\n}\n// ----\n// TypeError 5704: (153-157): This expression is not callable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/493_builtin_keccak256_reject_gas.sol",
    "content": "contract C {\n    function f() public {\n        keccak256.gas();\n    }\n}\n// ----\n// TypeError 9582: (47-60): Member \"gas\" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes32).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/494_builtin_sha256_reject_gas.sol",
    "content": "contract C {\n    function f() public {\n        sha256.gas();\n    }\n}\n// ----\n// TypeError 9582: (47-57): Member \"gas\" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes32).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/495_builtin_ripemd160_reject_gas.sol",
    "content": "contract C {\n    function f() public {\n        ripemd160.gas();\n    }\n}\n// ----\n// TypeError 9582: (47-60): Member \"gas\" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes20).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/496_builtin_ecrecover_reject_gas.sol",
    "content": "contract C {\n    function f() public {\n        ecrecover.gas();\n    }\n}\n// ----\n// TypeError 9582: (47-60): Member \"gas\" not found or not visible after argument-dependent lookup in function (bytes32,uint8,bytes32,bytes32) pure returns (address).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/497_gasleft.sol",
    "content": "contract C {\n    function f() public view returns (uint256 val) { return gasleft(); }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/498_msg_gas_deprecated.sol",
    "content": "contract C {\n    function f() public view returns (uint256 val) { return msg.gas; }\n}\n// ----\n// TypeError 1400: (73-80): \"msg.gas\" has been deprecated in favor of \"gasleft()\"\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/500_gasleft_shadowing_1.sol",
    "content": "contract C {\n    function gasleft() public pure returns (bytes32 val) { return \"abc\"; }\n    function f() public pure returns (bytes32 val) { return gasleft(); }\n}\n// ----\n// Warning 2319: (17-87): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/501_gasleft_shadowing_2.sol",
    "content": "contract C {\n    uint gasleft;\n    function f() public { gasleft = 42; }\n}\n// ----\n// Warning 2319: (17-29): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/502_builtin_keccak256_reject_value.sol",
    "content": "contract C {\n    function f() public {\n        keccak256.value();\n    }\n}\n// ----\n// TypeError 8820: (47-62): Member \"value\" is only available for payable functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/503_builtin_sha256_reject_value.sol",
    "content": "contract C {\n    function f() public {\n        sha256.value();\n    }\n}\n// ----\n// TypeError 8820: (47-59): Member \"value\" is only available for payable functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/504_builtin_ripemd160_reject_value.sol",
    "content": "contract C {\n    function f() public {\n        ripemd160.value();\n    }\n}\n// ----\n// TypeError 8820: (47-62): Member \"value\" is only available for payable functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/505_builtin_ecrecover_reject_value.sol",
    "content": "contract C {\n    function f() public {\n        ecrecover.value();\n    }\n}\n// ----\n// TypeError 8820: (47-62): Member \"value\" is only available for payable functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/511_library_function_without_implementation_public.sol",
    "content": "// This used to work pre-0.6.0.\nlibrary L {\n    // This can be used as an \"interface\", hence it is allowed.\n    function f() public;\n}\n// ----\n// TypeError 9231: (112-132): Library functions must be implemented if declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/512_library_function_without_implementation_internal.sol",
    "content": "library L {\n    function f() internal;\n}\n// ----\n// TypeError 9231: (16-38): Library functions must be implemented if declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/513_library_function_without_implementation_private.sol",
    "content": "library L {\n    function f() private;\n}\n// ----\n// TypeError 9231: (16-37): Library functions must be implemented if declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/514_using_for_with_non_library.sol",
    "content": "// This tests a crash that was resolved by making the first error fatal.\nlibrary L {\n    struct S { uint d; }\n    using S for S;\n    function f(S memory _s) internal {\n        _s.d = 1;\n    }\n}\n// ----\n// TypeError 4357: (120-121): Library name expected. If you want to attach a function, use '{...}'.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/523_reject_interface_creation.sol",
    "content": "interface I {}\ncontract C {\n    function f() public {\n        new I();\n    }\n}\n// ----\n// TypeError 2971: (62-67): Cannot instantiate an interface.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/525_reject_interface_constructors.sol",
    "content": "interface I {}\ncontract C is I(2) {}\n// ----\n// TypeError 7927: (29-33): Wrong argument count for constructor call: 1 arguments given but expected 0\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/526_fallback_marked_external.sol",
    "content": "contract C {\n    fallback () external { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/527_fallback_marked_internal.sol",
    "content": "contract C {\n    fallback () internal { }\n}\n// ----\n// TypeError 1159: (17-41): Fallback function must be defined as \"external\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/528_fallback_marked_private.sol",
    "content": "contract C {\n    fallback () private { }\n}\n// ----\n// TypeError 1159: (17-40): Fallback function must be defined as \"external\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/529_fallback_marked_public.sol",
    "content": "contract C {\n    fallback () public { }\n}\n// ----\n// TypeError 1159: (17-39): Fallback function must be defined as \"external\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/530_tuple_invalid_literal_too_large_for_uint.sol",
    "content": "contract C {\n    function f() pure public {\n        uint x;\n        (x, ) = (1E111);\n    }\n}\n// ----\n// TypeError 7407: (76-83): Type int_const 1000...(104 digits omitted)...0000 is not implicitly convertible to expected type tuple(uint256,).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/531_tuple_invalid_literal_too_large_unassigned.sol",
    "content": "contract C {\n    function f() pure public {\n        uint x;\n        (x, ) = (1, 1E111);\n    }\n}\n// ----\n// TypeError 3390: (80-85): Invalid rational number.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/532_tuple_invalid_literal_too_large_for_uint_multi.sol",
    "content": "contract C {\n    function f() pure public {\n        uint x;\n        (x, ) = (1E111, 1);\n    }\n}\n// ----\n// TypeError 3390: (77-82): Invalid rational number.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/533_tuple_invalid_literal_too_large_exp.sol",
    "content": "contract C {\n    function f() pure public {\n        (2**270, 1);\n    }\n}\n// ----\n// TypeError 3390: (53-59): Invalid rational number.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/534_tuple_invalid_literal_too_large_expression.sol",
    "content": "contract C {\n    function f() pure public {\n        ((2**270) / 2**100, 1);\n    }\n}\n// ----\n// Warning 6133: (52-74): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/535_address_overload_resolution.sol",
    "content": "contract C {\n    function balance() public returns (uint) {\n        this.balance; // to avoid pureness warning\n        return 1;\n    }\n    function transfer(uint amount) public {\n        payable(this).transfer(amount); // to avoid pureness warning\n    }\n    receive() payable external {\n    }\n}\ncontract D {\n    function f() public {\n        uint x = (new C()).balance();\n        x;\n        (new C()).transfer(5);\n    }\n}\n// ----\n// Warning 9207: (187-209): 'transfer' is deprecated and scheduled for removal. Use 'call{value: <amount>}(\"\")' instead.\n// Warning 2018: (17-134): Function state mutability can be restricted to view\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/536_array_length_invalid_expression_negative_bool.sol",
    "content": "contract C {\n    uint[-true] ids;\n}\n// ----\n// TypeError 5462: (22-27): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/537_array_length_invalid_expression_int_divides_bool.sol",
    "content": "contract C {\n    uint[true/1] ids;\n}\n// ----\n// TypeError 5462: (22-28): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/538_array_length_invalid_expression_bool_divides_int.sol",
    "content": "contract C {\n    uint[1/true] ids;\n}\n// ----\n// TypeError 5462: (22-28): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/539_array_length_invalid_expression_scientific_literal.sol",
    "content": "contract C {\n    uint[1.111111E1111111111111] ids;\n}\n// ----\n// TypeError 5462: (22-44): Invalid array length, expected integer literal or constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/540_array_length_invalid_expression_division_by_zero.sol",
    "content": "contract C {\n    uint[3/0] ids;\n}\n// ----\n// TypeError 6020: (22-25): Operator / not compatible with types int_const 3 and int_const 0\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/541_warn_about_address_members_on_contract_balance.sol",
    "content": "contract C {\n    function f() view public {\n        this.balance;\n    }\n}\n// ----\n// TypeError 3125: (52-64): Member \"balance\" not found or not visible after argument-dependent lookup in contract C. Use \"address(this).balance\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/542_warn_about_address_members_on_contract_transfer.sol",
    "content": "contract C {\n    function f() view public {\n        this.transfer;\n    }\n}\n// ----\n// TypeError 3125: (52-65): Member \"transfer\" not found or not visible after argument-dependent lookup in contract C. Use \"address(this).transfer\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/543_warn_about_address_members_on_contract_send.sol",
    "content": "contract C {\n    function f() view public {\n        this.send;\n    }\n}\n// ----\n// TypeError 3125: (52-61): Member \"send\" not found or not visible after argument-dependent lookup in contract C. Use \"address(this).send\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/544_warn_about_address_members_on_contract_call.sol",
    "content": "contract C {\n    function f() view public {\n        this.call;\n    }\n}\n// ----\n// TypeError 3125: (52-61): Member \"call\" not found or not visible after argument-dependent lookup in contract C. Use \"address(this).call\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/545_warn_about_address_members_on_contract_callcode.sol",
    "content": "contract C {\n    function f() view public {\n        this.callcode;\n    }\n}\n// ----\n// TypeError 3125: (52-65): Member \"callcode\" not found or not visible after argument-dependent lookup in contract C. Use \"address(this).callcode\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/546_warn_about_address_members_on_contract_delegatecall.sol",
    "content": "contract C {\n    function f() view public {\n        this.delegatecall;\n    }\n}\n// ----\n// TypeError 3125: (52-69): Member \"delegatecall\" not found or not visible after argument-dependent lookup in contract C. Use \"address(this).delegatecall\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/547_warn_about_address_members_on_non_this_contract_balance.sol",
    "content": "contract C {\n    function f() view public {\n        C c;\n        c.balance;\n    }\n}\n// ----\n// TypeError 3125: (65-74): Member \"balance\" not found or not visible after argument-dependent lookup in contract C. Use \"address(c).balance\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/548_warn_about_address_members_on_non_this_contract_transfer.sol",
    "content": "contract C {\n    function f() view public {\n        C c;\n        c.transfer;\n    }\n}\n// ----\n// TypeError 3125: (65-75): Member \"transfer\" not found or not visible after argument-dependent lookup in contract C. Use \"address(c).transfer\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/549_warn_about_address_members_on_non_this_contract_send.sol",
    "content": "contract C {\n    function f() view public {\n        C c;\n        c.send;\n    }\n}\n// ----\n// TypeError 3125: (65-71): Member \"send\" not found or not visible after argument-dependent lookup in contract C. Use \"address(c).send\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/550_warn_about_address_members_on_non_this_contract_call.sol",
    "content": "contract C {\n    function f() pure public {\n        C c;\n        c.call;\n    }\n}\n// ----\n// TypeError 3125: (65-71): Member \"call\" not found or not visible after argument-dependent lookup in contract C. Use \"address(c).call\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/551_warn_about_address_members_on_non_this_contract_callcode.sol",
    "content": "contract C {\n    function f() pure public {\n        C c;\n        c.callcode;\n    }\n}\n// ----\n// TypeError 3125: (65-75): Member \"callcode\" not found or not visible after argument-dependent lookup in contract C. Use \"address(c).callcode\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/552_warn_about_address_members_on_non_this_contract_delegatecall.sol",
    "content": "contract C {\n    function f() pure public {\n        C c;\n        c.delegatecall;\n    }\n}\n// ----\n// TypeError 3125: (65-79): Member \"delegatecall\" not found or not visible after argument-dependent lookup in contract C. Use \"address(c).delegatecall\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/559_no_warning_for_using_members_that_look_like_address_members.sol",
    "content": "abstract contract C {\n    function transfer(uint) public virtual;\n    function f() public {\n        this.transfer(10);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/568_blockhash.sol",
    "content": "contract C {\n    function f() public view returns (bytes32) { return blockhash(3); }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/569_block_blockhash_deprecated.sol",
    "content": "contract C {\n    function f() public view returns (bytes32) {\n        return block.blockhash(3);\n    }\n}\n// ----\n// TypeError 8113: (77-92): \"block.blockhash()\" has been deprecated in favor of \"blockhash()\"\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/570_function_type_undeclared_type.sol",
    "content": "contract C {\n    function a(function(Nested)) external pure {}\n}\n// ----\n// DeclarationError 7920: (37-43): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/571_function_type_undeclared_type_external.sol",
    "content": "contract C {\n    function a(function(Nested) external) external pure {}\n}\n// ----\n// DeclarationError 7920: (37-43): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/572_function_type_undeclared_type_multi_nested.sol",
    "content": "contract C {\n    function a(function(function(function(Nested)))) external pure {}\n}\n// ----\n// DeclarationError 7920: (55-61): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/573_similar_name_longer_than_80_not_suggested.sol",
    "content": "contract test {\n    function f() public {\n        int YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY = YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY;\n    }\n}\n// ----\n// DeclarationError 7576: (146-236): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/574_similar_name_shorter_than_80_suggested.sol",
    "content": "contract test {\n    function f() public {\n        int YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY = YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY;\n    }\n}\n// ----\n// DeclarationError 7576: (137-216): Undeclared identifier. Did you mean \"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/575_member_member_getter_call_without_parentheses.sol",
    "content": "contract A{\n    function f() public pure{\n\n    }\n}\ncontract B{\n    A public a;\n}\ncontract C{\n    B public b;\n}\ncontract D{\n    C c;\n    function f() public view{\n        c.b.a.f();\n    }\n}\n// ----\n// TypeError 6005: (170-175): Member \"a\" not found or not visible after argument-dependent lookup in function () view external returns (contract B). Did you intend to call the function?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/576_member_getter_call_without_parentheses.sol",
    "content": "contract A{\n    function f() public pure{\n\n    }\n}\ncontract B{\n    A public a;\n}\ncontract C{\n    B b;\n    function f() public view{\n        b.a.f();\n    }\n}\n\n// ----\n// TypeError 6005: (140-145): Member \"f\" not found or not visible after argument-dependent lookup in function () view external returns (contract A). Did you intend to call the function?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/577_member_getter_call_without_parentheses_missing_function.sol",
    "content": "contract A{\n\n}\ncontract B{\n    A public a;\n}\ncontract C{\n    B b;\n    function f() public view{\n        b.a.f();\n    }\n}\n\n// ----\n// TypeError 6005: (104-109): Member \"f\" not found or not visible after argument-dependent lookup in function () view external returns (contract A). Did you intend to call the function?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/578_private_member_getter_call_without_parentheses.sol",
    "content": "contract A{\n    function f() public pure{\n\n    }\n}\ncontract B{\n    A private a;\n}\ncontract C{\n    B b;\n    function f() public view{\n        b.a.f();\n    }\n}\n\n// ----\n// TypeError 9582: (141-144): Member \"a\" not found or not visible after argument-dependent lookup in contract B.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/579_member_getter_call_without_parentheses_private_function.sol",
    "content": "contract A{\n    function f() private pure{\n\n    }\n}\ncontract B{\n    A public a;\n}\ncontract C{\n    B b;\n    function f() public view{\n        b.a.f();\n    }\n}\n\n// ----\n// TypeError 6005: (141-146): Member \"f\" not found or not visible after argument-dependent lookup in function () view external returns (contract A). Did you intend to call the function?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/580_improve_name_suggestion_one_and_two_letters.sol",
    "content": "contract c {\n    function f () public\n    {\n        a = ac;\n        a = cd;\n        a = b;\n    }\n    uint256 a;\n    uint256 ab;\n}\n// ----\n// DeclarationError 7576: (56-58): Undeclared identifier. Did you mean \"ab\"?\n// DeclarationError 7576: (72-74): Undeclared identifier.\n// DeclarationError 7576: (88-89): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/581_improve_name_suggestion_three_letters.sol",
    "content": "contract c {\n    function f () public\n    {\n        a = abd;\n        a = ade;\n    }\n    uint256 a;\n    uint256 abc;\n}\n// ----\n// DeclarationError 7576: (56-59): Undeclared identifier. Did you mean \"abc\" or \"abi\"?\n// DeclarationError 7576: (73-76): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/582_improve_name_suggestion_four_letters.sol",
    "content": "contract c {\n    function f () public\n    {\n        a = land;\n        a = lost;\n        a = lang;\n    }\n    uint256 long;\n    uint256 abc;\n}\n// ----\n// DeclarationError 7576: (52-53): Undeclared identifier.\n// DeclarationError 7576: (56-60): Undeclared identifier. Did you mean \"long\"?\n// DeclarationError 7576: (70-71): Undeclared identifier.\n// DeclarationError 7576: (74-78): Undeclared identifier. Did you mean \"long\"?\n// DeclarationError 7576: (88-89): Undeclared identifier.\n// DeclarationError 7576: (92-96): Undeclared identifier. Did you mean \"long\"?\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/583_abi_encode_packed_with_rational_number_constant.sol",
    "content": "contract C {\n    function f() pure public { abi.encodePacked(0/1); }\n}\n// ----\n// TypeError 7279: (61-64): Cannot perform packed encoding for a literal. Please convert it to an explicit type first.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/584_abi_decode_with_tuple_of_other_than_types.sol",
    "content": "contract C {\n    function f() pure public { abi.decode(\"\", (0)); }\n}\n// ----\n// TypeError 1039: (60-61): Argument has to be a type name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/585_abi_decode_with_unsupported_types.sol",
    "content": "pragma abicoder v1;\ncontract C {\n\tstruct s { uint a; uint b; }\n    function f() pure public {\n        abi.decode(\"\", (s));\n    }\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 9611: (118-119): Decoding type struct C.s memory not supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/589_error_index_access.sol",
    "content": "error MyCustomError(uint, bool);\ncontract Test {\n    function f() public {\n        uint[] memory a;\n        a[MyCustomError];\n    }\n}\n// ----\n// TypeError 7407: (110-123): Type error MyCustomError(uint256,bool) is not implicitly convertible to expected type uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/590_event_index_access.sol",
    "content": "contract Test {\n    event MyCustomEvent(uint);\n    function f() public {\n        uint[] memory a;\n        a[MyCustomEvent];\n    }\n}\n// ----\n// TypeError 7407: (108-121): Type event MyCustomEvent(uint256) is not implicitly convertible to expected type uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/591_access_to_internal_variable.sol",
    "content": "contract C {\n    function f(int32 x) external pure returns (int32)\n    {\n        this.x + 1;\n        return x;\n    }\n}\n// ----\n// TypeError 9582: (81-87): Member \"x\" not found or not visible after argument-dependent lookup in contract C.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/array_length_fractional_computed.sol",
    "content": "contract test {\n    uint constant a = 7;\n    uint constant b = 3;\n    function f() public {\n        uint[a / b] memory x; x[0];\n        uint[7 / 3] memory y; y[0];\n    }\n}\n// ----\n// TypeError 3208: (141-146): Array with fractional length specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/call_option_value_on_library_function.sol",
    "content": "library L { function l() public {} }\ncontract test {\n    function f() public {\n        L.l{value: 1}();\n    }\n}\n// ----\n// TypeError 2193: (87-100): Function call options can only be set on external function calls or contract creations.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/compoundAssignment/incomp_types.sol",
    "content": "contract C {\n    function f() public returns (uint a, uint b) {\n        a += (1, 1);\n    }\n}\n// ----\n// TypeError 7366: (72-83): Operator += not compatible with types uint256 and tuple(int_const 1,int_const 1).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/compoundAssignment/tuple.sol",
    "content": "contract C {\n    function f() public returns (uint a, uint b) {\n        (a, b) += (1, 1);\n    }\n}\n// ----\n// TypeError 4289: (72-88): Compound assignment is not allowed for tuple types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/compoundAssignment/tuple_invalid_inline_array_type.sol",
    "content": "contract C {\n    function f() pure public {\n        uint x;\n        (x, ) = ([100e100]);\n    }\n}\n// ----\n// TypeError 9563: (78-85): Invalid mobile type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/constant_forward_reference_struct.sol",
    "content": "S constant x;\nstruct S { int y; }\n// ----\n// TypeError 9259: (0-12): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/constant_mapping.sol",
    "content": "contract C {\n    mapping(uint => uint) constant x;\n}\n// ----\n// TypeError 9259: (17-49): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/constant_nested_mapping.sol",
    "content": "contract C {\n    struct S {\n        mapping(uint => uint) x;\n    }\n    S public constant c;\n}\n// ----\n// TypeError 9259: (71-90): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/erc7201_builtin_const_var_assignment.sol",
    "content": "contract C {\n    uint constant x = erc7201(\"abc\");\n    function f() public pure returns(uint) {\n        return mulmod(x, 10, 37);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/erc7201_builtin_invalid_member_gas.sol",
    "content": "contract C {\n    function f() public {\n        erc7201.gas();\n    }\n}\n// ----\n// TypeError 9582: (47-58): Member \"gas\" not found or not visible after argument-dependent lookup in function (string memory) pure returns (uint256).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/erc7201_builtin_invalid_member_value.sol",
    "content": "contract C {\n    function f() public {\n        erc7201.value();\n    }\n}\n// ----\n// TypeError 8820: (47-60): Member \"value\" is only available for payable functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/free_and_constant.sol",
    "content": "uint constant c = 7;\nfunction c() returns (uint) {}\n// ----\n// DeclarationError 2333: (21-51): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/hash_collision_in_abstract_contract.sol",
    "content": "// This contract used to throw\nabstract contract D {\n    function gsf() public {}\n    function tgeo() public {}\n}\ncontract C {\n    D d;\n    function g() public returns (uint) {\n        d.d;\n    }\n}\n// ----\n// TypeError 1860: (31-113): Function signature hash collision for tgeo()\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/invalidArgs/creating_memory_array.sol",
    "content": "contract C {\n    function f(uint size) public {\n        uint[] memory x = new uint[]();\n    }\n}\n// ----\n// TypeError 6160: (74-86): Wrong argument count for function call: 0 arguments given but expected 1.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/invalidArgs/creating_struct.sol",
    "content": "contract C {\n    struct S { uint a; uint b; }\n\n    function f() public {\n        S memory s = S({a: 1});\n    }\n}\n// ----\n// TypeError 9755: (94-103): Wrong argument count for struct constructor: 1 arguments given but expected 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/invalidArgs/creating_struct_members_skipped.sol",
    "content": "contract C {\n    struct S { uint a; uint b; mapping(uint=>uint) c; }\n\n    function f() public {\n        S({a: 1});\n    }\n}\n// ----\n// TypeError 9515: (104-113): Struct containing a (nested) mapping cannot be constructed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/invalidArgs/explicit_conversions.sol",
    "content": "contract test {\n    function f() public {\n        uint(1, 1);\n        uint({arg:1});\n    }\n}\n// ----\n// TypeError 2558: (50-60): Exactly one argument expected for explicit type conversion.\n// TypeError 5153: (70-83): Type conversion cannot allow named arguments.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/invalidTypes/conditional_expression.sol",
    "content": "contract C {\n    function o(bytes1) public pure {}\n    function f() public {\n        o(true ? 99**99 : 99);\n        o(true ? 99 : 99**99);\n\n        o(true ? 99**99 : 99**99);\n    }\n}\n// ----\n// TypeError 9717: (94-100): Invalid mobile type in true expression.\n// TypeError 9553: (87-105): Invalid type for argument in function call. Invalid implicit conversion from uint8 to bytes1 requested.\n// TypeError 3703: (130-136): Invalid mobile type in false expression.\n// TypeError 9553: (118-136): Invalid type for argument in function call. Invalid implicit conversion from uint8 to bytes1 requested.\n// TypeError 9717: (157-163): Invalid mobile type in true expression.\n// TypeError 3703: (166-172): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/invalidTypes/constructor_call.sol",
    "content": "contract C {\n    constructor(bytes32 _arg) {\n    }\n}\n\ncontract A {\n    function f() public {\n        new  C((1234));\n    }\n}\n// ----\n// TypeError 9553: (108-114): Invalid type for argument in function call. Invalid implicit conversion from int_const 1234 to bytes32 requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/no_effect_statements.sol",
    "content": "contract test {\n struct s { uint a; uint b;}\n    function f() pure public returns (bytes1) {\n\t\ts;\n\t\ts(1,2);\n\t\ts[7];\n\t\tuint;\n\t\tuint[7];\n    }\n}\n// ----\n// Warning 6321: (83-89): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6133: (95-96): Statement has no effect.\n// Warning 6133: (100-106): Statement has no effect.\n// Warning 6133: (110-114): Statement has no effect.\n// Warning 6133: (118-122): Statement has no effect.\n// Warning 6133: (126-133): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/events.sol",
    "content": "contract C {\n    event keccak256();\n}\n// ----\n// Warning 2319: (17-35): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/functions.sol",
    "content": "contract C {\n    function keccak256() pure public {}\n}\n// ----\n// Warning 2319: (17-52): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/global_scope.sol",
    "content": "contract msg {\n}\n// ----\n// Warning 2319: (0-16): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/ignores_constructor.sol",
    "content": "contract C {\n    constructor() {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/ignores_struct.sol",
    "content": "contract C {\n    struct a {\n        uint msg;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/illegal_names_assembly_functions.sol",
    "content": "contract C {\n    function f() public pure {\n        assembly {\n            function this() {\n            }\n            function super() {\n            }\n            function _() {\n            }\n        }\n    }\n}\n// ----\n// DeclarationError 4113: (75-106): The identifier name \"this\" is reserved.\n// DeclarationError 4113: (119-151): The identifier name \"super\" is reserved.\n// DeclarationError 4113: (164-192): The identifier name \"_\" is reserved.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/illegal_names_assembly_identifier.sol",
    "content": "contract C {\n    function f() public {\n        assembly {\n            let super := 1\n            let this := 1\n            let _ := 1\n        }\n    }\n}\n// ----\n// DeclarationError 4113: (74-79): The identifier name \"super\" is reserved.\n// DeclarationError 3859: (74-79): This declaration shadows a declaration outside the inline assembly block.\n// DeclarationError 4113: (101-105): The identifier name \"this\" is reserved.\n// DeclarationError 3859: (101-105): This declaration shadows a declaration outside the inline assembly block.\n// DeclarationError 4113: (127-128): The identifier name \"_\" is reserved.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/illegal_names_function_parameters.sol",
    "content": "contract C {\n    function f(uint super) public {\n    }\n    function g(uint this) public {\n    }\n    function h(uint _) public {\n    }\n    function i() public returns (uint super) {\n        return 1;\n    }\n    function j() public returns (uint this) {\n        return 1;\n    }\n    function k() public returns (uint _) {\n        return 1;\n    }\n}\n// ----\n// DeclarationError 3726: (28-38): The name \"super\" is reserved.\n// DeclarationError 3726: (70-79): The name \"this\" is reserved.\n// DeclarationError 3726: (111-117): The name \"_\" is reserved.\n// DeclarationError 3726: (167-177): The name \"super\" is reserved.\n// DeclarationError 3726: (238-247): The name \"this\" is reserved.\n// DeclarationError 3726: (308-314): The name \"_\" is reserved.\n// Warning 2319: (28-38): This declaration shadows a builtin symbol.\n// Warning 2319: (70-79): This declaration shadows a builtin symbol.\n// Warning 2319: (167-177): This declaration shadows a builtin symbol.\n// Warning 2319: (238-247): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/illegal_names_library_using_for.sol",
    "content": "library super {\n    function f() public {\n    }\n}\n\nlibrary this {\n    function f() public {\n    }\n}\nlibrary _ {\n    function f() public {\n    }\n}\n\ncontract C {\n    // These are not errors\n    using super for uint;\n    using this for uint16;\n    using _ for int;\n}\n// ----\n// DeclarationError 3726: (0-49): The name \"super\" is reserved.\n// DeclarationError 3726: (51-99): The name \"this\" is reserved.\n// DeclarationError 3726: (100-145): The name \"_\" is reserved.\n// Warning 2319: (0-49): This declaration shadows a builtin symbol.\n// Warning 2319: (51-99): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/illegal_names_using_for.sol",
    "content": "library L {\n    function f() public {\n    }\n}\n\n// error\nstruct super {\n    uint a;\n}\n\n// error\nstruct this {\n    uint a;\n}\n\n// error\nstruct _ {\n    uint a;\n}\n\ncontract C {\n    // These are not errors\n    using L for super;\n    using L for _;\n    using L for this;\n}\n// ----\n// DeclarationError 3726: (56-84): The name \"super\" is reserved.\n// DeclarationError 3726: (95-122): The name \"this\" is reserved.\n// DeclarationError 3726: (133-157): The name \"_\" is reserved.\n// Warning 2319: (56-84): This declaration shadows a builtin symbol.\n// Warning 2319: (95-122): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/parameters.sol",
    "content": "contract C {\n    function f(uint require) pure public {\n        require = 2;\n    }\n}\n// ----\n// Warning 2319: (28-40): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/return_parameters.sol",
    "content": "contract C {\n    function f() pure public returns (uint require) {\n        require = 2;\n    }\n}\n// ----\n// Warning 2319: (51-63): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/storage_variables.sol",
    "content": "contract C {\n    uint msg;\n}\n// ----\n// Warning 2319: (17-25): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/this_super.sol",
    "content": "contract C {\n    function f() pure public {\n        uint super = 3;\n        uint this = 4;\n    }\n}\n// ----\n// DeclarationError 3726: (52-62): The name \"super\" is reserved.\n// DeclarationError 3726: (76-85): The name \"this\" is reserved.\n// Warning 2319: (52-62): This declaration shadows a builtin symbol.\n// Warning 2319: (76-85): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shadowsBuiltin/variables.sol",
    "content": "contract C {\n    function f() pure public {\n        uint msg;\n        msg;\n    }\n}\n// ----\n// Warning 2319: (52-60): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/shift_warn_literal_large_shift_amount.sol",
    "content": "contract test {\n    function f() pure public returns(uint) {\n        uint x = 100;\n        return 10 << x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/typeChecking/function_call.sol",
    "content": "contract test {\n    function f() public returns (bool) { return g(12, true) == 3; }\n    function g(uint256, bool) public returns (uint256) { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/typeChecking/library_instances.sol",
    "content": "library X { }\n\ncontract Y {\n\tX abc;\n\tfunction foo(X param) private view\n\t{\n\t\tX ofg;\n\t\tofg = abc;\n\t}\n}\n// ----\n// TypeError 1130: (29-30): Invalid use of a library name.\n// TypeError 1130: (50-51): Invalid use of a library name.\n// TypeError 1130: (77-78): Invalid use of a library name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/typeChecking/return.sol",
    "content": "contract test {\n    function f() public returns (bool r) { return 1 >= 2; }\n}\n// ----\n// Warning 2018: (20-75): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/typeChecking/return_tuple_not_convertible.sol",
    "content": "contract test {\n    function f() public returns (uint256 r, uint8) { return ((12, \"\")); }\n}\n// ----\n// TypeError 5992: (76-86): Return argument type tuple(int_const 12,literal_string \"\") is not implicitly convertible to expected type tuple(uint256,uint8).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/typeChecking/return_wrong_number.sol",
    "content": "contract test {\n    function f() public returns (bool r1, bool r2) { return 1 >= 2; }\n}\n// ----\n// TypeError 8863: (69-82): Different number of arguments in return statement than in returns declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/typeChecking/return_wrong_type.sol",
    "content": "contract test {\n    function f() public returns (uint256 r) { return 1 >= 2; }\n}\n// ----\n// TypeError 6359: (69-75): Return argument type bool is not implicitly convertible to expected type (type of first return variable) uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/warnUnused/function_parameter.sol",
    "content": "contract C {\n    function f(uint a) pure public {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/warnUnused/local.sol",
    "content": "contract C {\n    function f() pure public {\n        uint a;\n    }\n}\n// ----\n// Warning 2072: (52-58): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/warnUnused/local_assignment.sol",
    "content": "contract C {\n    function f() pure public {\n        uint a = 1;\n    }\n}\n// ----\n// Warning 2072: (52-58): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/nameAndTypeResolution/warnUnused/return_parameter.sol",
    "content": "contract C {\n    function f() pure public returns (uint a) {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/calling_operator_binary_user_defined_not_available.sol",
    "content": "type Int is int256;\n\nfunction f() pure {\n    Int a = Int.wrap(0);\n    a + a;\n    a >>> a;\n}\n\n// ----\n// TypeError 2271: (70-75): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found.\n// TypeError 2271: (81-88): Built-in binary operator >>> cannot be applied to types Int and Int.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/calling_operator_unary_user_defined_not_available.sol",
    "content": "type Int is int256;\n\nfunction f() pure {\n    Int a = Int.wrap(0);\n    -a;\n    a++;\n}\n\n// ----\n// TypeError 4907: (70-72): Built-in unary operator - cannot be applied to type Int. No matching user-defined operator found.\n// TypeError 9767: (78-81): Built-in unary operator ++ cannot be applied to type Int.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/negation.sol",
    "content": "contract test {\n    function f() public pure {\n        int x;\n        uint y = uint(-x);\n        -y;\n    }\n}\n// ----\n// TypeError 4907: (97-99): Built-in unary operator - cannot be applied to type uint256. Unary negation is only allowed for signed integers.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/signed_rational_modulus.sol",
    "content": "contract test {\n    function f() public pure {\n        fixed a = 0.42578125 % -0.4271087646484375;\n        fixed b = .5 % a;\n        fixed c = a % b;\n        a; b; c;\n    }\n}\n// ----\n// TypeError 2271: (117-123): Built-in binary operator % cannot be applied to types rational_const 1 / 2 and fixed128x18. Fractional literals not supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/transient_value_type.sol",
    "content": "contract C {\n    int transient x;\n    function f() public view returns (int) {\n        int y = x;\n        int w = -x;\n        return (x + w) * (y / x);\n    }\n}\n// ====\n// stopAfter: parsing\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator.sol",
    "content": "type Int is int;\nusing {add as +} for Int global;\nusing {unsub as -} for Int global;\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction unsub(Int) pure returns (Int) {}\n\nfunction f() pure {\n    Int.wrap(0) + Int.wrap(0);\n    -Int.wrap(0);\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_as_attached_function_via_function_name.sol",
    "content": "type Int is int16;\n\nusing {add as +} for Int global;\n\nfunction add(Int, Int) pure returns (Int) {}\n\nfunction f() {\n    Int a;\n    a.add(a);\n}\n// ----\n// TypeError 9582: (130-135): Member \"add\" not found or not visible after argument-dependent lookup in Int.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_as_attached_function_via_operator_name.sol",
    "content": "type Int is int16;\n\nusing {add as +} for Int global;\n\nfunction add(Int, Int) pure returns (Int) {}\n\nfunction f() {\n    Int a;\n    a.+(a);\n}\n// ----\n// ParserError 2314: (132-133): Expected identifier but got '+'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_defined_separately_from_type.sol",
    "content": "==== Source: definition.sol ====\nimport \"type-and-binding.sol\";\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction unsub(Int) pure returns (Int) {}\n\n==== Source: type-and-binding.sol ====\nimport \"definition.sol\";\n\ntype Int is int;\n\nusing {add as +} for Int global;\nusing {unsub as -} for Int global;\n\n==== Source: use.sol ====\nimport \"type-and-binding.sol\";\n\ncontract C {\n    function f() pure public {\n        Int.wrap(0) + Int.wrap(0);\n        -Int.wrap(0);\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_defined_separately_from_type_and_binding.sol",
    "content": "==== Source: binding.sol ====\nimport \"definition.sol\";\nimport \"type.sol\";\n\nusing {add as +} for Int global;\nusing {unsub as -} for Int global;\n\n==== Source: definition.sol ====\nimport \"type.sol\";\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction unsub(Int) pure returns (Int) {}\n\n==== Source: type.sol ====\ntype Int is int;\n\n==== Source: use.sol ====\nimport \"type.sol\";\n\ncontract C {\n    function f() pure public {\n        Int.wrap(0) + Int.wrap(0);\n        -Int.wrap(0);\n    }\n}\n// ----\n// TypeError 4117: (binding.sol:45-77): Can only use \"global\" with types defined in the same source unit at file level.\n// TypeError 4117: (binding.sol:78-112): Can only use \"global\" with types defined in the same source unit at file level.\n// TypeError 2271: (use.sol:72-97): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found.\n// TypeError 4907: (use.sol:107-119): Built-in unary operator - cannot be applied to type Int. No matching user-defined operator found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported.sol",
    "content": "==== Source: s1.sol ====\ntype Int is int;\nusing {add as +} for Int global;\nusing {unsub as -} for Int global;\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction unsub(Int) pure returns (Int) {}\n\n==== Source: s2.sol ====\nimport \"s1.sol\";\n\ncontract C {\n    function f() pure public {\n        Int.wrap(0) + Int.wrap(0);\n        -Int.wrap(0);\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_non_global.sol",
    "content": "==== Source: s1.sol ====\ntype Int is int;\nusing {add as +} for Int;\nusing {unsub as -} for Int;\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction unsub(Int) pure returns (Int) {}\n\n==== Source: s2.sol ====\nimport \"s1.sol\";\n\ncontract C {\n    function f() pure public {\n        Int.wrap(0) + Int.wrap(0);\n        -Int.wrap(0);\n    }\n}\n// ----\n// TypeError 3320: (s1.sol:24-27): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (s1.sol:50-55): Operators can only be defined in a global 'using for' directive.\n// TypeError 2271: (s2.sol:70-95): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found.\n// TypeError 4907: (s2.sol:105-117): Built-in unary operator - cannot be applied to type Int. No matching user-defined operator found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_transitively.sol",
    "content": "==== Source: s0.sol ====\ntype Int is int;\n\n==== Source: s1.sol ====\nimport \"s0.sol\";\nusing {add1 as +} for Int global;\nusing {unsub1 as -} for Int global;\n\nfunction add1(Int, Int) pure returns (Int) {}\nfunction unsub1(Int) pure returns (Int) {}\n\n==== Source: s2.sol ====\nimport \"s0.sol\";\nusing {add2 as +} for Int global;\nusing {unsub2 as -} for Int global;\n\nfunction add2(Int, Int) pure returns (Int) {}\nfunction unsub2(Int) pure returns (Int) {}\n\n==== Source: s3.sol ====\nimport \"s1.sol\";\nimport \"s2.sol\";\ncontract C {\n    function f() public {\n        Int.wrap(0) + Int.wrap(0);\n        -Int.wrap(0);\n    }\n}\n// ----\n// TypeError 4117: (s1.sol:17-50): Can only use \"global\" with types defined in the same source unit at file level.\n// TypeError 4117: (s1.sol:51-86): Can only use \"global\" with types defined in the same source unit at file level.\n// TypeError 4117: (s2.sol:17-50): Can only use \"global\" with types defined in the same source unit at file level.\n// TypeError 4117: (s2.sol:51-86): Can only use \"global\" with types defined in the same source unit at file level.\n// TypeError 2271: (s3.sol:81-106): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found.\n// TypeError 4907: (s3.sol:116-128): Built-in unary operator - cannot be applied to type Int. No matching user-defined operator found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_transitively_non_global.sol",
    "content": "==== Source: s0.sol ====\ntype Int is int;\n\n==== Source: s1.sol ====\nimport \"s0.sol\";\nusing {add1 as +} for Int;\nusing {unsub1 as -} for Int;\n\nfunction add1(Int, Int) pure returns (Int) {}\nfunction unsub1(Int) pure returns (Int) {}\n\n==== Source: s2.sol ====\nimport \"s0.sol\";\nusing {add2 as +} for Int;\nusing {unsub2 as -} for Int;\n\nfunction add2(Int, Int) pure returns (Int) {}\nfunction unsub2(Int) pure returns (Int) {}\n\n==== Source: s3.sol ====\nimport \"s1.sol\";\nimport \"s2.sol\";\ncontract C {\n    function f() public {\n        Int.wrap(0) + Int.wrap(0);\n        -Int.wrap(0);\n    }\n}\n// ----\n// TypeError 3320: (s1.sol:24-28): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (s1.sol:51-57): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (s2.sol:24-28): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (s2.sol:51-57): Operators can only be defined in a global 'using for' directive.\n// TypeError 2271: (s3.sol:81-106): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found.\n// TypeError 4907: (s3.sol:116-128): Built-in unary operator - cannot be applied to type Int. No matching user-defined operator found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_in_constant_initialization.sol",
    "content": "type B4 is bytes4;\nusing {bitor as |, bitnot as ~} for B4 global;\n\nfunction bitor(B4, B4) pure returns (B4) {}\nfunction bitnot(B4) pure returns (B4) {}\n\nB4 constant X = B4.wrap(0x12345678) | B4.wrap(0xaabbccdd);\n\ncontract C {\n    B4 constant Y = B4.wrap(0x12345678) | B4.wrap(0xaabbccdd);\n}\n\nlibrary L {\n    B4 constant Z = ~B4.wrap(0x12345678);\n}\n\ninterface I {\n    B4 constant W = ~B4.wrap(0x12345678);\n}\n// ----\n// TypeError 8349: (169-210): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (246-287): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (324-344): Initial value for constant variable has to be compile-time constant.\n// TypeError 8349: (383-403): Initial value for constant variable has to be compile-time constant.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_non_global.sol",
    "content": "type Int is int;\nusing {add as +} for Int;\nusing {unsub as -} for Int;\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction unsub(Int) pure returns (Int) {}\n\nfunction f() pure {\n    Int.wrap(0) + Int.wrap(0);\n    -Int.wrap(0);\n}\n// ----\n// TypeError 3320: (24-27): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (50-55): Operators can only be defined in a global 'using for' directive.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_deploys_contract.sol",
    "content": "type Int is int16;\n\nusing {add as +} for Int global;\n\nfunction add(Int, Int) returns (Int) {\n    B b = new B();\n    return b.f();\n}\n\ncontract B {\n    Int s;\n    function f() external returns (Int) {\n        s = Int.wrap(3);\n        return s;\n    }\n}\n\ncontract C {\n    function test() public returns (Int) {\n        return Int.wrap(0) + Int.wrap(0);\n    }\n}\n// ----\n// TypeError 7775: (27-30): Only pure free functions can be used to define operators.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_external_call.sol",
    "content": "type Int is int16;\nusing {add as +, unsub as -} for Int global;\n\nIAdder constant ADDER = IAdder(address(0));\n\nfunction add(Int x, Int y) pure returns (Int) {\n    return ADDER.mul(x, y);\n}\n\nfunction unsub(Int x) pure returns (Int) {\n    return ADDER.inc(x);\n}\n\ninterface IAdder {\n    function mul(Int, Int) external returns (Int);\n    function inc(Int) external returns (Int);\n}\n// ----\n// TypeError 8961: (169-184): Function cannot be declared as pure because this expression (potentially) modifies the state.\n// TypeError 8961: (243-255): Function cannot be declared as pure because this expression (potentially) modifies the state.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_pure_external_call.sol",
    "content": "type Int is int16;\nusing {add as +, unsub as -} for Int global;\n\nIAdder constant ADDER = IAdder(address(0));\n\nfunction add(Int x, Int y) pure returns (Int) {\n    return ADDER.mul(x, y);\n}\n\nfunction unsub(Int x) pure returns (Int) {\n    return ADDER.inc(x);\n}\n\ninterface IAdder {\n    function mul(Int, Int) external pure returns (Int);\n    function inc(Int) external pure returns (Int);\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_view_external_call.sol",
    "content": "type Int is int16;\nusing {add as +, unsub as -} for Int global;\n\nIAdder constant ADDER = IAdder(address(0));\n\nfunction add(Int x, Int y) pure returns (Int) {\n    return ADDER.mul(x, y);\n}\n\nfunction unsub(Int x) pure returns (Int) {\n    return ADDER.inc(x);\n}\n\ninterface IAdder {\n    function mul(Int, Int) external view returns (Int);\n    function inc(Int) external view returns (Int);\n}\n// ----\n// TypeError 2527: (169-184): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires \"view\".\n// TypeError 2527: (243-255): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires \"view\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/calling_operator_with_implicit_conversion.sol",
    "content": "using {add as +, unsub as -} for U global;\n\ntype U is uint;\n\nfunction add(U, U) pure returns (U) {}\nfunction unsub(U) pure returns (U) {}\n\ncontract C {\n    function fromBool() public {\n        U u;\n\n        u + true;\n        true + u;\n        -true;\n    }\n\n    function fromUint() public {\n        U u;\n        uint32 u32;\n\n        u + u32;\n        u32 + u;\n        -u32;\n    }\n}\n// ----\n// TypeError 5653: (207-215): The type of the second operand of this user-defined binary operator + does not match the type of the first operand, which is U.\n// TypeError 2271: (225-233): Built-in binary operator + cannot be applied to types bool and U.\n// TypeError 4907: (243-248): Built-in unary operator - cannot be applied to type bool.\n// TypeError 5653: (332-339): The type of the second operand of this user-defined binary operator + does not match the type of the first operand, which is U.\n// TypeError 2271: (349-356): Built-in binary operator + cannot be applied to types uint32 and U.\n// TypeError 4907: (366-370): Built-in unary operator - cannot be applied to type uint32. Unary negation is only allowed for signed integers.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_builtin_types.sol",
    "content": "using {f as +} for uint global;\nusing {f as +} for uint[2] global;\nusing {f as +} for mapping(uint => uint) global;\nusing {f as +} for function (uint) pure returns (uint) global;\nusing {f as +} for string global;\n\nfunction f(uint, uint) pure returns (uint) {}\n// ----\n// TypeError 8841: (0-31): Can only use \"global\" with user-defined types.\n// TypeError 5332: (7-8): Operators can only be implemented for user-defined value types.\n// TypeError 8841: (32-66): Can only use \"global\" with user-defined types.\n// TypeError 5332: (39-40): Operators can only be implemented for user-defined value types.\n// TypeError 8841: (67-115): Can only use \"global\" with user-defined types.\n// TypeError 5332: (74-75): Operators can only be implemented for user-defined value types.\n// TypeError 8841: (116-178): Can only use \"global\" with user-defined types.\n// TypeError 5332: (123-124): Operators can only be implemented for user-defined value types.\n// TypeError 8841: (179-212): Can only use \"global\" with user-defined types.\n// TypeError 5332: (186-187): Operators can only be implemented for user-defined value types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_contract.sol",
    "content": "using {fc as +} for C global;\nusing {fa as +} for A global;\n\nfunction fc(C, C) pure returns (C) {}\nfunction fa(A, A) pure returns (A) {}\n\ncontract C {}\nabstract contract A {}\n// ----\n// TypeError 8841: (0-29): Can only use \"global\" with user-defined types.\n// TypeError 5332: (7-9): Operators can only be implemented for user-defined value types.\n// TypeError 8841: (30-59): Can only use \"global\" with user-defined types.\n// TypeError 5332: (37-39): Operators can only be implemented for user-defined value types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_enum.sol",
    "content": "using {add as +} for E global;\n\nenum E {\n    E1,\n    E2\n}\n\nfunction add(E, E) pure returns (E) {}\n// ----\n// TypeError 5332: (7-10): Operators can only be implemented for user-defined value types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_error.sol",
    "content": "using {add as +} for E global;\n\nerror E();\n\nfunction add(E, E) pure returns (E) {\n    return E.E1;\n}\n\n// ----\n// TypeError 5172: (21-22): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_event.sol",
    "content": "using {add as +} for C.Event global;\n\ncontract C {\n    event Event();\n}\n\nfunction add(C.Event, C.Event) pure returns (C.Event) {}\n\n// ----\n// TypeError 5172: (21-28): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_interface.sol",
    "content": "using {f as +} for I global;\n\nfunction f(I, I) pure returns (I) {}\n\ninterface I {}\n// ----\n// TypeError 8841: (0-28): Can only use \"global\" with user-defined types.\n// TypeError 5332: (7-8): Operators can only be implemented for user-defined value types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_library.sol",
    "content": "using {f as +} for L global;\n\nfunction f() pure {}\nlibrary L {}\n// ----\n// TypeError 1130: (19-20): Invalid use of a library name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_struct.sol",
    "content": "using {add as +} for S global;\n\nstruct S {\n    uint x;\n}\n\nfunction add(S memory, S memory) pure returns (S memory) {}\n// ----\n// TypeError 5332: (7-10): Operators can only be implemented for user-defined value types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_wildcard_type_at_contract_level.sol",
    "content": "type Int is int;\n\nfunction add(Int, Int) pure returns (Int) {}\n\ncontract C {\n    using {add as +} for *;\n}\n\ncontract D {\n    using {add as +} for * global;\n}\n// ----\n// SyntaxError 3349: (81-104): The type has to be specified explicitly when attaching specific functions.\n// SyntaxError 3349: (125-155): The type has to be specified explicitly when attaching specific functions.\n// SyntaxError 2854: (125-155): Can only globally attach functions to specific types.\n// SyntaxError 3367: (125-155): \"global\" can only be used at file level.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_wildcard_type_at_file_level.sol",
    "content": "using {add as +} for * global;\n\nfunction add(int, int) returns (int) {}\n// ----\n// SyntaxError 8118: (0-30): The type has to be specified explicitly at file level (cannot use '*').\n// SyntaxError 2854: (0-30): Can only globally attach functions to specific types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_attached_free_function.sol",
    "content": "type Int is uint;\nusing {f} for Int;\n\nInt constant v;\nusing {v.f as +} for Int global;\n\nfunction f(Int) pure returns (Int) {}\n// ----\n// DeclarationError 9589: (61-64): Identifier is not a function name or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_abi_encode.sol",
    "content": "type Int is int16;\n\nusing {abi.encode as +} for Int global;\n\nfunction f(Int, Int) pure returns (Int) {}\n\n// ----\n// DeclarationError 9589: (27-37): Identifier is not a function name or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_keccak256.sol",
    "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n// ----\n// TypeError 8187: (27-36): Expected function name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_revert.sol",
    "content": "type Int is int16;\n\nusing {revert as +} for Int global;\n// ----\n// DeclarationError 9589: (27-33): Identifier is not a function name or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_contract_function_at_contract_level.sol",
    "content": "type Int is int;\n\ncontract C {\n    using {add as +} for Int;\n\n    function add(Int, Int) public pure returns (Int) {}\n}\n// ----\n// TypeError 4167: (42-45): Only file-level functions and library functions can be attached to a type in a \"using\" statement\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_contract_function_at_file_level.sol",
    "content": "type Int is int;\n\nusing {C.add as +} for Int global;\n\ncontract C {\n    function add(Int, Int) public pure returns (Int) {\n        return 0;\n    }\n}\n// ----\n// TypeError 4167: (25-30): Only file-level functions and library functions can be attached to a type in a \"using\" statement\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_error.sol",
    "content": "type Int is int16;\n\nusing {IntError as +} for Int global;\n\nerror IntError(Int a, Int b);\n// ----\n// TypeError 8187: (27-35): Expected function name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_event.sol",
    "content": "type Int is int16;\n\nusing {C.IntEvent as +} for Int global;\n\ncontract C {\n    event IntEvent(Int a, Int b);\n}\n// ----\n// TypeError 8187: (27-37): Expected function name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_function_pointer.sol",
    "content": "type Int is int8;\n\ncontract C {\n    function(Int, Int) external pure returns (Int) ptr;\n    using {ptr as +} for Int;\n}\n// ----\n// TypeError 8187: (99-102): Expected function name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_function_shadowing_builtin_keccak256.sol",
    "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int, Int) pure returns (Int) {\n    return Int.wrap(0);\n}\n// ----\n// Warning 2319: (60-135): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library.sol",
    "content": "type Int is int16;\n\nusing {L as +} for Int global;\n\nlibrary L {}\n// ----\n// TypeError 8187: (27-28): Expected function name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_at_contract_level.sol",
    "content": "==== Source: external.sol ====\ntype Int is int128;\n\nlibrary L {\n    function binaryOperator(Int, Int) external pure returns (Int) {}\n    function unaryOperator(Int) external pure returns (Int) {}\n\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n\ncontract C {\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n\nlibrary X {\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n\n==== Source: internal.sol ====\ntype Int is int128;\n\nlibrary L {\n    function binaryOperator(Int, Int) internal pure returns (Int) {}\n    function unaryOperator(Int) internal pure returns (Int) {}\n\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n\ncontract C {\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n\nlibrary X {\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n\n==== Source: private.sol ====\ntype Int is int128;\n\nlibrary L {\n    function binaryOperator(Int, Int) private pure returns (Int) {}\n    function unaryOperator(Int) private pure returns (Int) {}\n\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n==== Source: public.sol ====\ntype Int is int128;\n\nlibrary L {\n    function binaryOperator(Int, Int) public pure returns (Int) {}\n    function unaryOperator(Int) public pure returns (Int) {}\n\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n\ncontract C {\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n\nlibrary X {\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n// ----\n// TypeError 3320: (external.sol:177-193): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (external.sol:177-193): Only pure free functions can be used to define operators.\n// TypeError 3320: (external.sol:220-235): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (external.sol:220-235): Only pure free functions can be used to define operators.\n// TypeError 3320: (external.sol:278-294): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (external.sol:278-294): Only pure free functions can be used to define operators.\n// TypeError 3320: (external.sol:321-336): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (external.sol:321-336): Only pure free functions can be used to define operators.\n// TypeError 3320: (external.sol:378-394): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (external.sol:378-394): Only pure free functions can be used to define operators.\n// TypeError 3320: (external.sol:421-436): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (external.sol:421-436): Only pure free functions can be used to define operators.\n// TypeError 3320: (internal.sol:177-193): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (internal.sol:177-193): Only pure free functions can be used to define operators.\n// TypeError 3320: (internal.sol:220-235): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (internal.sol:220-235): Only pure free functions can be used to define operators.\n// TypeError 3320: (internal.sol:278-294): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (internal.sol:278-294): Only pure free functions can be used to define operators.\n// TypeError 3320: (internal.sol:321-336): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (internal.sol:321-336): Only pure free functions can be used to define operators.\n// TypeError 3320: (internal.sol:378-394): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (internal.sol:378-394): Only pure free functions can be used to define operators.\n// TypeError 3320: (internal.sol:421-436): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (internal.sol:421-436): Only pure free functions can be used to define operators.\n// TypeError 3320: (private.sol:175-191): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (private.sol:175-191): Only pure free functions can be used to define operators.\n// TypeError 3320: (private.sol:218-233): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (private.sol:218-233): Only pure free functions can be used to define operators.\n// TypeError 3320: (public.sol:173-189): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (public.sol:173-189): Only pure free functions can be used to define operators.\n// TypeError 3320: (public.sol:216-231): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (public.sol:216-231): Only pure free functions can be used to define operators.\n// TypeError 3320: (public.sol:274-290): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (public.sol:274-290): Only pure free functions can be used to define operators.\n// TypeError 3320: (public.sol:317-332): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (public.sol:317-332): Only pure free functions can be used to define operators.\n// TypeError 3320: (public.sol:374-390): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (public.sol:374-390): Only pure free functions can be used to define operators.\n// TypeError 3320: (public.sol:417-432): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (public.sol:417-432): Only pure free functions can be used to define operators.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_at_file_level.sol",
    "content": "==== Source: external.sol ====\ntype Int is int128;\n\nlibrary L {\n    function binaryOperator(Int, Int) external pure returns (Int) {}\n    function unaryOperator(Int) external pure returns (Int) {}\n}\n\nusing {L.binaryOperator as +} for Int global;\nusing {L.unaryOperator as -} for Int global;\n\n==== Source: internal.sol ====\ntype Int is int128;\n\nlibrary L {\n    function binaryOperator(Int, Int) internal pure returns (Int) {}\n    function unaryOperator(Int) internal pure returns (Int) {}\n}\n\nusing {L.binaryOperator as +} for Int global;\nusing {L.unaryOperator as -} for Int global;\n\n==== Source: public.sol ====\ntype Int is int128;\n\nlibrary L {\n    function binaryOperator(Int, Int) public pure returns (Int) {}\n    function unaryOperator(Int) public pure returns (Int) {}\n}\n\nusing {L.binaryOperator as +} for Int global;\nusing {L.unaryOperator as -} for Int global;\n// ----\n// TypeError 7775: (external.sol:175-191): Only pure free functions can be used to define operators.\n// TypeError 7775: (external.sol:221-236): Only pure free functions can be used to define operators.\n// TypeError 7775: (internal.sol:175-191): Only pure free functions can be used to define operators.\n// TypeError 7775: (internal.sol:221-236): Only pure free functions can be used to define operators.\n// TypeError 7775: (public.sol:171-187): Only pure free functions can be used to define operators.\n// TypeError 7775: (public.sol:217-232): Only pure free functions can be used to define operators.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_private_outside_of_library.sol",
    "content": "type Int is int128;\n\nlibrary L {\n    function binaryOperator(Int, Int) private pure returns (Int) {}\n    function unaryOperator(Int) private pure returns (Int) {}\n}\n\nusing {L.binaryOperator as +} for Int global;\nusing {L.unaryOperator as -} for Int global;\n\ncontract C {\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n\nlibrary X {\n    using {L.binaryOperator as *} for Int;\n    using {L.unaryOperator as ~} for Int;\n}\n// ----\n// TypeError 6772: (173-189): Function \"L.binaryOperator\" is private and therefore cannot be attached to a type outside of the library where it is defined.\n// TypeError 7775: (173-189): Only pure free functions can be used to define operators.\n// TypeError 6772: (219-234): Function \"L.unaryOperator\" is private and therefore cannot be attached to a type outside of the library where it is defined.\n// TypeError 7775: (219-234): Only pure free functions can be used to define operators.\n// TypeError 6772: (282-298): Function \"L.binaryOperator\" is private and therefore cannot be attached to a type outside of the library where it is defined.\n// TypeError 3320: (282-298): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (282-298): Only pure free functions can be used to define operators.\n// TypeError 6772: (325-340): Function \"L.unaryOperator\" is private and therefore cannot be attached to a type outside of the library where it is defined.\n// TypeError 3320: (325-340): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (325-340): Only pure free functions can be used to define operators.\n// TypeError 6772: (382-398): Function \"L.binaryOperator\" is private and therefore cannot be attached to a type outside of the library where it is defined.\n// TypeError 3320: (382-398): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (382-398): Only pure free functions can be used to define operators.\n// TypeError 6772: (425-440): Function \"L.unaryOperator\" is private and therefore cannot be attached to a type outside of the library where it is defined.\n// TypeError 3320: (425-440): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (425-440): Only pure free functions can be used to define operators.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_non_pure_function.sol",
    "content": "using {add as +, sub as -, mul as *} for A global;\n\nfunction add(A, A) view returns (A) {}\nfunction sub(A, A) returns (A) {}\nfunction mul(A, A) payable returns (A) {}\n\ntype A is address payable;\n// ----\n// TypeError 7775: (7-10): Only pure free functions can be used to define operators.\n// TypeError 7775: (17-20): Only pure free functions can be used to define operators.\n// TypeError 7775: (27-30): Only pure free functions can be used to define operators.\n// TypeError 9559: (125-166): Free functions cannot be payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_non_pure_function_on_built_in_type_non_global.sol",
    "content": "// This should point out all 3 errors, rather than give up after the first one.\nusing {add as +} for address;\n\nfunction add(address, address) view returns (address) {}\n// ----\n// TypeError 3320: (87-90): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (87-90): Only pure free functions can be used to define operators.\n// TypeError 5332: (87-90): Operators can only be implemented for user-defined value types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_overloaded_function.sol",
    "content": "using {add as +} for A global;\nusing {add as +} for AP global;\n\nfunction add(A, A) pure returns (A) {}\nfunction add(AP, AP) pure returns (AP) {}\n\ntype A is address;\ntype AP is address payable;\n// ----\n// DeclarationError 9589: (7-10): Identifier is not a function name or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_privately_overloaded_function.sol",
    "content": "using {L.add as +} for A global;\nusing {L.add as +} for AP global;\n\nlibrary L {\n    function add(A, A) private pure returns (A) {}\n    function add(AP, AP) internal pure returns (AP) {}\n}\n\ntype A is address;\ntype AP is address payable;\n// ----\n// DeclarationError 9589: (7-12): Identifier is not a function name or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_unqualified_library_function_at_file_level.sol",
    "content": "type B32 is bytes32;\n\nlibrary L {\n    function publicOperator(B32, B32) public pure returns (B32) {}\n}\n\nusing {publicOperator as +} for B32 global;\n// ----\n// DeclarationError 9589: (111-125): Identifier is not a function name or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_unqualified_library_function_in_library.sol",
    "content": "type B32 is bytes32;\n\nlibrary L {\n    using {externalOperator as +} for B32;\n    using {publicOperator as -} for B32;\n    using {internalOperator as *} for B32;\n    using {privateOperator as /} for B32;\n\n    function externalOperator(B32, B32) external pure returns (B32) {}\n    function publicOperator(B32, B32) public pure returns (B32) {}\n    function internalOperator(B32, B32) internal pure returns (B32) {}\n    function privateOperator(B32, B32) private pure returns (B32) {}\n}\n// ----\n// TypeError 3320: (45-61): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (45-61): Only pure free functions can be used to define operators.\n// TypeError 3320: (88-102): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (88-102): Only pure free functions can be used to define operators.\n// TypeError 3320: (129-145): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (129-145): Only pure free functions can be used to define operators.\n// TypeError 3320: (172-187): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (172-187): Only pure free functions can be used to define operators.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_global_and_non_global_different_files.sol",
    "content": "==== Source: Int.sol ====\ntype Int is int;\n\nusing {add as +} for Int global;\n\nfunction add(Int, Int) pure returns (Int) {}\n\n==== Source: test.sol ====\nimport \"Int.sol\";\n\nusing {anotherAdd as +} for Int;\n\nfunction anotherAdd(Int, Int) pure returns (Int) {}\n\nfunction test() pure returns (Int) {\n    return Int.wrap(0) + Int.wrap(0);\n}\n// ----\n// TypeError 3320: (test.sol:26-36): Operators can only be defined in a global 'using for' directive.\n// TypeError 4705: (test.sol:26-36): User-defined binary operator + has more than one definition matching the operand type visible in the current scope.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_global_non_global.sol",
    "content": "type Int is int;\n\nusing {add as +} for Int global;\nusing {add2 as +} for Int;\nusing {unsub as -} for Int global;\nusing {unsub2 as -} for Int;\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction add2(Int, Int) pure returns (Int) {}\nfunction unsub(Int) pure returns (Int) {}\nfunction unsub2(Int) pure returns (Int) {}\n\nfunction testBinary() pure returns (Int) {\n    return Int.wrap(1) + Int.wrap(2);\n}\n\nfunction testUnary() pure returns (Int) {\n    return -Int.wrap(2);\n}\n// ----\n// TypeError 4705: (25-28): User-defined binary operator + has more than one definition matching the operand type visible in the current scope.\n// TypeError 3320: (58-62): Operators can only be defined in a global 'using for' directive.\n// TypeError 4705: (58-62): User-defined binary operator + has more than one definition matching the operand type visible in the current scope.\n// TypeError 4705: (85-90): User-defined unary operator - has more than one definition matching the operand type visible in the current scope.\n// TypeError 3320: (120-126): Operators can only be defined in a global 'using for' directive.\n// TypeError 4705: (120-126): User-defined unary operator - has more than one definition matching the operand type visible in the current scope.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_non_global_and_global_different_files.sol",
    "content": "==== Source: Int.sol ====\ntype Int is int;\n\nusing {add as +} for Int;\n\nfunction add(Int, Int) pure returns (Int) {}\n\n==== Source: test.sol ====\nimport \"Int.sol\";\n\nusing {anotherAdd as +} for Int global;\n\nfunction anotherAdd(Int, Int) pure returns (Int) {}\n\nfunction test() pure returns (Int) {\n    return Int.wrap(0) + Int.wrap(0);\n}\n// ----\n// TypeError 3320: (Int.sol:25-28): Operators can only be defined in a global 'using for' directive.\n// TypeError 4117: (test.sol:19-58): Can only use \"global\" with types defined in the same source unit at file level.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_same_directive.sol",
    "content": "type Int is uint128;\n\nusing {add as +, sub as +} for Int global;\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction sub(Int, Int) pure returns (Int) {}\n\nfunction test() {\n    Int.wrap(0) + Int.wrap(1);\n}\n// ----\n// TypeError 4705: (29-32): User-defined binary operator + has more than one definition matching the operand type visible in the current scope.\n// TypeError 4705: (39-42): User-defined binary operator + has more than one definition matching the operand type visible in the current scope.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_same_directive_operator_not_used.sol",
    "content": "type Int is uint128;\n\n// Still an error, even if the operator is not actually used\nusing {add1 as +, add2 as +} for Int global;\nusing {unsub1 as -, unsub2 as -} for Int global;\n\nfunction add1(Int, Int) pure returns (Int) {}\nfunction add2(Int, Int) pure returns (Int) {}\nfunction unsub1(Int) pure returns (Int) {}\nfunction unsub2(Int) pure returns (Int) {}\n// ----\n// TypeError 4705: (90-94): User-defined binary operator + has more than one definition matching the operand type visible in the current scope.\n// TypeError 4705: (101-105): User-defined binary operator + has more than one definition matching the operand type visible in the current scope.\n// TypeError 4705: (135-141): User-defined unary operator - has more than one definition matching the operand type visible in the current scope.\n// TypeError 4705: (148-154): User-defined unary operator - has more than one definition matching the operand type visible in the current scope.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_on_file_and_contract_level.sol",
    "content": "type Int is int;\n\nusing {add as +} for Int global;\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction another_add(Int, Int) pure returns (Int) {}\n\ncontract B {\n    using {another_add as +} for Int;\n\n    function f() public {\n        Int.wrap(0) + Int.wrap(0);\n    }\n}\n\ncontract C is B {\n    function g() public {\n        Int.wrap(0) + Int.wrap(0);\n    }\n}\n// ----\n// TypeError 3320: (175-186): Operators can only be defined in a global 'using for' directive.\n// TypeError 4705: (175-186): User-defined binary operator + has more than one definition matching the operand type visible in the current scope.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_different_levels_free_function.sol",
    "content": "type Int is int;\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction unsub(Int) pure returns (Int) {}\n\nusing {add as +, unsub as -} for Int global;\n\ncontract C {\n    using {add as +, unsub as -} for Int;\n}\n\nlibrary X {\n    using {add as +, unsub as -} for Int;\n}\n// ----\n// TypeError 3320: (176-179): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (186-191): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (233-236): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (243-248): Operators can only be defined in a global 'using for' directive.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_different_levels_library_function.sol",
    "content": "type Int is int;\n\nlibrary L {\n    using {add as +, unsub as -} for Int;\n    using {L.add as +, L.unsub as -} for Int;\n\n    function add(Int, Int) internal pure returns (Int) {}\n    function unsub(Int) internal pure returns (Int) {}\n}\n\nusing {L.add as +, L.unsub as -} for Int global;\n\ncontract C {\n    using {L.add as +, L.unsub as -} for Int;\n}\n\nlibrary X {\n    using {L.add as +, L.unsub as -} for Int;\n}\n// ----\n// TypeError 3320: (41-44): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (41-44): Only pure free functions can be used to define operators.\n// TypeError 3320: (51-56): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (51-56): Only pure free functions can be used to define operators.\n// TypeError 3320: (83-88): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (83-88): Only pure free functions can be used to define operators.\n// TypeError 3320: (95-102): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (95-102): Only pure free functions can be used to define operators.\n// TypeError 7775: (242-247): Only pure free functions can be used to define operators.\n// TypeError 7775: (254-261): Only pure free functions can be used to define operators.\n// TypeError 3320: (309-314): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (309-314): Only pure free functions can be used to define operators.\n// TypeError 3320: (321-328): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (321-328): Only pure free functions can be used to define operators.\n// TypeError 3320: (370-375): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (370-375): Only pure free functions can be used to define operators.\n// TypeError 3320: (382-389): Operators can only be defined in a global 'using for' directive.\n// TypeError 7775: (382-389): Only pure free functions can be used to define operators.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_same_directive.sol",
    "content": "type Int is int32;\n\nusing {add as +, add as +} for Int global;\n\nfunction add(Int, Int) pure returns(Int) {}\n\nfunction f(int32 a, int32 b) pure {\n    Int.wrap(a) + Int.wrap(b);\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_separate_directives.sol",
    "content": "type Int is int32;\n\nusing {add as +} for Int global;\nusing {add as +} for Int global;\n\nfunction add(Int, Int) pure returns(Int) {}\n\nfunction f(int32 a, int32 b) pure {\n    Int.wrap(a) + Int.wrap(b);\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_overloading.sol",
    "content": "type Int is uint128;\n\nusing {add as +, add128 as +} for Int global;\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction add128(Int, int128) pure returns (Int) {}\n\nfunction test() {\n    Int.wrap(0) + Int.wrap(1);\n}\n// ----\n// TypeError 4705: (29-32): User-defined binary operator + has more than one definition matching the operand type visible in the current scope.\n// TypeError 1884: (129-142): Wrong parameters in operator definition. The function \"add128\" needs to have two parameters of type Int and the same data location to be used for the operator +.\n// TypeError 4705: (39-45): User-defined binary operator + has more than one definition matching the operand type visible in the current scope.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_function_name_missing.sol",
    "content": "using {as -} for uint global;\n// ----\n// ParserError 2314: (7-9): Expected identifier but got 'as'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_no_brace.sol",
    "content": "using f as - for uint global;\n// ----\n// ParserError 2314: (8-10): Expected 'for' but got 'as'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_non_user_definable.sol",
    "content": "using {\n    f as new,\n    f as delete,\n    f as **,\n    f as <<,\n    f as >>,\n    f as &&,\n    f as ||,\n    f as !,\n    f as =,\n    f as |=,\n    f as ^=,\n    f as &=,\n    f as <<=,\n    f as >>=,\n    f as +=,\n    f as -=,\n    f as *=,\n    f as /=,\n    f as %=,\n    f as ++,\n    f as --\n} for int256 global;\n// ----\n// ParserError 4403: (17-20): Not a user-definable operator: new. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (31-37): Not a user-definable operator: delete. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (48-50): Not a user-definable operator: **. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (61-63): Not a user-definable operator: <<. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (74-76): Not a user-definable operator: >>. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (87-89): Not a user-definable operator: &&. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (100-102): Not a user-definable operator: ||. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (113-114): Not a user-definable operator: !. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (125-126): Not a user-definable operator: =. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (137-139): Not a user-definable operator: |=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (150-152): Not a user-definable operator: ^=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (163-165): Not a user-definable operator: &=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (176-179): Not a user-definable operator: <<=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (190-193): Not a user-definable operator: >>=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (204-206): Not a user-definable operator: +=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (217-219): Not a user-definable operator: -=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (230-232): Not a user-definable operator: *=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (243-245): Not a user-definable operator: /=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (256-258): Not a user-definable operator: %=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (269-271): Not a user-definable operator: ++. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (282-284): Not a user-definable operator: --. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_not_an_operator.sol",
    "content": "using {\n    f as x,\n    f as operator,\n    f as as,\n    f as 123,\n    f as ()\n} for int256 global;\n// ----\n// ParserError 4403: (17-18): Not a user-definable operator: x. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (29-37): Not a user-definable operator: operator. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (48-50): Not a user-definable operator: as. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (61-64): Not a user-definable operator: 123. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (75-76): Not a user-definable operator: (. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 2314: (76-77): Expected '}' but got ')'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_operator_name_empty_string.sol",
    "content": "using {f as ''} for uint;\nusing {f as \"\"} for int;\nusing {f as hex\"\"} for address;\n// ----\n// ParserError 4403: (12-14): Not a user-definable operator: . Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (38-40): Not a user-definable operator: . Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 4403: (63-68): Not a user-definable operator: . Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_operator_name_missing.sol",
    "content": "using {f as} for uint global;\n// ----\n// ParserError 4403: (11-12): Not a user-definable operator: }. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n// ParserError 2314: (13-16): Expected '}' but got 'for'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_operator_named_as.sol",
    "content": "using {f as as} for uint global;\n// ----\n// ParserError 4403: (12-14): Not a user-definable operator: as. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >=\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_returning_wrong_types.sol",
    "content": "type Int is int256;\n\nusing {\n    add as +,\n    div as /,\n    unsub as -,\n    bitnot as ~,\n    gt as >,\n    lt as <\n} for Int global;\n\nfunction add(Int x, Int y) pure returns (int256) {}\nfunction div(Int x, Int y) pure {}\nfunction unsub(Int) pure returns (Int, Int) {}\nfunction bitnot(Int) pure returns (int256) {}\nfunction gt(Int, Int) pure returns (Int) {}\nfunction lt(Int, Int) pure returns (bool, Int) {}\n\nfunction f() pure {\n    Int.wrap(0) + Int.wrap(1);\n    Int.wrap(0) / Int.wrap(0);\n    -Int.wrap(0);\n    ~Int.wrap(0);\n    Int.wrap(0) < Int.wrap(0);\n    Int.wrap(0) > Int.wrap(0);\n}\n// ----\n// TypeError 7743: (174-182): Wrong return parameters in operator definition. The function \"add\" needs to return exactly one value of type Int to be used for the operator +.\n// TypeError 7743: (218-218): Wrong return parameters in operator definition. The function \"div\" needs to return exactly one value of type Int to be used for the operator /.\n// TypeError 7743: (254-264): Wrong return parameters in operator definition. The function \"unsub\" needs to return exactly one value of type Int to be used for the operator -.\n// TypeError 7743: (302-310): Wrong return parameters in operator definition. The function \"bitnot\" needs to return exactly one value of type Int to be used for the operator ~.\n// TypeError 7743: (349-354): Wrong return parameters in operator definition. The function \"gt\" needs to return exactly one value of type bool to be used for the operator >.\n// TypeError 7743: (393-404): Wrong return parameters in operator definition. The function \"lt\" needs to return exactly one value of type bool to be used for the operator <.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_taking_and_returning_types_not_matching_using_for.sol",
    "content": "type Int is int256;\n\nusing {\n    add as +,\n    sub as -,\n    div as /\n} for Int global;\n\nfunction add(Int) pure returns (Int) {}\nfunction sub(Int, Int, Int) pure returns (Int) {}\nfunction div(int256, int256) pure returns (Int) {}\n\nfunction f() pure {\n    Int.wrap(0) + Int.wrap(1);\n    Int.wrap(0) - Int.wrap(0);\n    Int.wrap(0) / Int.wrap(0);\n}\n\n// ----\n// TypeError 1884: (101-106): Wrong parameters in operator definition. The function \"add\" needs to have two parameters of type Int and the same data location to be used for the operator +.\n// TypeError 1884: (141-156): Wrong parameters in operator definition. The function \"sub\" needs to have one or two parameters of type Int and the same data location to be used for the operator -.\n// TypeError 1884: (191-207): Wrong parameters in operator definition. The function \"div\" needs to have one or two parameters of type Int and the same data location to be used for the operator /.\n// TypeError 7743: (221-226): Wrong return parameters in operator definition. The function \"div\" needs to return a value of the same type and data location as its parameters to be used for the operator /.\n// TypeError 2271: (255-280): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found.\n// TypeError 2271: (286-311): Built-in binary operator - cannot be applied to types Int and Int. No matching user-defined operator found.\n// TypeError 2271: (317-342): Built-in binary operator / cannot be applied to types Int and Int. No matching user-defined operator found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_taking_no_parameters_binary.sol",
    "content": "type Int is int;\n\nusing {\n    f as +\n} for Int global;\n\nfunction f() returns (Int) {\n    return Int.wrap(0);\n}\n// ----\n// TypeError 4731: (30-31): The function \"f\" does not have any parameters, and therefore cannot be attached to the type \"Int\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_taking_no_parameters_unary.sol",
    "content": "type Int is int;\n\nusing {\n    f as ~\n} for Int global;\n\nfunction f() returns (Int) {\n    return Int.wrap(0);\n}\n// ----\n// TypeError 4731: (30-31): The function \"f\" does not have any parameters, and therefore cannot be attached to the type \"Int\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_taking_or_returning_different_types.sol",
    "content": "type Int is int128;\n\nusing {\n    add as +,\n    sub as -,\n    mul as *,\n    div as /\n} for Int global;\n\nfunction add(Int, int128) pure returns (Int) {}\nfunction sub(int128, Int) pure returns (int128) {}\nfunction mul(int128, int256) pure returns (Int) {}\nfunction div(Int, Int) pure returns (int256) {}\n// ----\n// TypeError 1884: (115-128): Wrong parameters in operator definition. The function \"add\" needs to have two parameters of type Int and the same data location to be used for the operator +.\n// TypeError 1884: (163-176): Wrong parameters in operator definition. The function \"sub\" needs to have one or two parameters of type Int and the same data location to be used for the operator -.\n// TypeError 7743: (190-198): Wrong return parameters in operator definition. The function \"sub\" needs to return exactly one value of type Int to be used for the operator -.\n// TypeError 1884: (214-230): Wrong parameters in operator definition. The function \"mul\" needs to have two parameters of type Int and the same data location to be used for the operator *.\n// TypeError 7743: (244-249): Wrong return parameters in operator definition. The function \"mul\" needs to return a value of the same type and data location as its parameters to be used for the operator *.\n// TypeError 7743: (289-297): Wrong return parameters in operator definition. The function \"div\" needs to return exactly one value of type Int to be used for the operator /.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/operator_taking_two_parameters_unary.sol",
    "content": "type Int is int128;\n\nusing {bitnot as ~} for Int global;\n\nfunction bitnot(Int, Int) pure returns (Int) {}\n\ncontract C {\n    function test() public pure {\n        ~Int.wrap(1);\n    }\n}\n// ----\n// TypeError 1884: (73-83): Wrong parameters in operator definition. The function \"bitnot\" needs to have exactly one parameter of type Int to be used for the operator ~.\n// TypeError 4907: (162-174): Built-in unary operator ~ cannot be applied to type Int. No matching user-defined operator found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/using_for_attaching_functions_and_defining_operators_same_directive.sol",
    "content": "type AP is address payable;\n\nfunction sub(AP, AP) pure returns (AP) {}\nfunction unsub(AP) pure returns (AP) {}\n\nfunction attachedPure(AP, uint, address) pure {}\nfunction attachedView(AP) view {}\nfunction attached(AP, function(AP)) {}\n\nusing {sub as -, attachedPure, attachedView, unsub as -, attached} for AP global;\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_for_contract_level_type.sol",
    "content": "library L {\n    type FixedBytes is bytes10;\n}\n\nfunction add(L.FixedBytes, L.FixedBytes) pure returns (L.FixedBytes) {}\nfunction unsub(L.FixedBytes, L.FixedBytes) pure returns (L.FixedBytes) {}\n\nlibrary LX {\n    using {add as +, unsub as -} for L.FixedBytes;\n}\n\ncontract CX {\n    using {add as +, unsub as -} for L.FixedBytes;\n}\n// ----\n// TypeError 3320: (218-221): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (228-233): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (286-289): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (296-301): Operators can only be defined in a global 'using for' directive.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_global.sol",
    "content": "type Int is int16;\n\nfunction add(Int, Int) pure returns (Int) {}\n\ncontract C {\n    using {add as +} for Int global;\n\n    function test() pure public {\n        Int.wrap(0) + Int.wrap(0);\n    }\n}\n// ----\n// SyntaxError 3367: (83-115): \"global\" can only be used at file level.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_global_different_file.sol",
    "content": "==== Source: s1.sol ====\ntype Int is int;\n\n==== Source: s2.sol ====\nimport \"s1.sol\";\n\nfunction bitnot(Int) pure returns (Int) {}\n\ncontract C {\n    using {bitnot as ~} for Int global;\n}\n// ----\n// SyntaxError 3367: (s2.sol:79-114): \"global\" can only be used at file level.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_in_base_contract.sol",
    "content": "type Int is int128;\n\nfunction add(Int, Int) pure returns (Int) {}\nfunction another_add(Int, Int) pure returns (Int) {}\n\ncontract B {\n    using {add as +} for Int;\n\n    function f() pure public returns (Int) {\n        return Int.wrap(0) + Int.wrap(0);\n    }\n}\n\ncontract C is B {\n    using {another_add as +} for Int;\n\n    function g() pure public returns (Int) {\n        return Int.wrap(0) + Int.wrap(0);\n    }\n}\n\ncontract D is B {\n    function h() pure public returns (Int) {\n        return Int.wrap(0) + Int.wrap(0);\n    }\n}\n// ----\n// TypeError 3320: (144-147): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (289-300): Operators can only be defined in a global 'using for' directive.\n// TypeError 2271: (491-516): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_in_interface.sol",
    "content": "type Int is int;\n\nfunction add(Int, Int) pure returns (Int) {}\n\ninterface I {\n    using {add as +} for Int;\n}\n// ----\n// SyntaxError 9088: (82-107): The \"using for\" directive is not allowed inside interfaces.\n// TypeError 3320: (89-92): Operators can only be defined in a global 'using for' directive.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_for_contract_level_type.sol",
    "content": "library L {\n    type FixedBytes is bytes1;\n}\n\ncontract C {\n    type FixedBytes is bytes2;\n}\n\ninterface I {\n    type FixedBytes is bytes3;\n}\n\nfunction addL(L.FixedBytes, L.FixedBytes) pure returns (L.FixedBytes) {}\nfunction addC(C.FixedBytes, C.FixedBytes) pure returns (C.FixedBytes) {}\nfunction addI(I.FixedBytes, I.FixedBytes) pure returns (I.FixedBytes) {}\n\nfunction unsubL(L.FixedBytes) pure returns (L.FixedBytes) {}\nfunction unsubC(C.FixedBytes) pure returns (C.FixedBytes) {}\nfunction unsubI(I.FixedBytes) pure returns (I.FixedBytes) {}\n\nusing {addL as +, unsubL as -} for L.FixedBytes global;\nusing {addC as +, unsubC as -} for C.FixedBytes global;\nusing {addI as +, unsubI as -} for I.FixedBytes global;\n// ----\n// TypeError 4117: (545-600): Can only use \"global\" with types defined in the same source unit at file level.\n// TypeError 4117: (601-656): Can only use \"global\" with types defined in the same source unit at file level.\n// TypeError 4117: (657-712): Can only use \"global\" with types defined in the same source unit at file level.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_for_contract_level_type_non_global.sol",
    "content": "library L {\n    type FixedBytes is bytes1;\n}\n\ncontract C {\n    type FixedBytes is bytes2;\n}\n\ninterface I {\n    type FixedBytes is bytes3;\n}\n\nfunction addL(L.FixedBytes, L.FixedBytes) pure returns (L.FixedBytes) {}\nfunction addC(C.FixedBytes, C.FixedBytes) pure returns (C.FixedBytes) {}\nfunction addI(I.FixedBytes, I.FixedBytes) pure returns (I.FixedBytes) {}\n\nfunction unsubL(L.FixedBytes) pure returns (L.FixedBytes) {}\nfunction unsubC(C.FixedBytes) pure returns (C.FixedBytes) {}\nfunction unsubI(I.FixedBytes) pure returns (I.FixedBytes) {}\n\nusing {addL as +, unsubL as -} for L.FixedBytes;\nusing {addC as +, unsubC as -} for C.FixedBytes;\nusing {addI as +, unsubI as -} for I.FixedBytes;\n// ----\n// TypeError 3320: (552-556): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (563-569): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (601-605): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (612-618): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (650-654): Operators can only be defined in a global 'using for' directive.\n// TypeError 3320: (661-667): Operators can only be defined in a global 'using for' directive.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_and_non_global.sol",
    "content": "==== Source: s1.sol ====\ntype Int is int;\n\nusing {add as +} for Int global;\nusing {add as +} for Int;\n\nfunction add(Int a, Int b) pure returns (Int) {}\nfunction test_add() pure returns (Int) {}\n\n==== Source: s2.sol ====\nimport \"s1.sol\";\n\ncontract C2 {\n    function test1() pure public returns (Int) {\n        return test_add();\n    }\n\n    function test2() pure public returns (Int) {\n        return Int.wrap(3) + Int.wrap(4);\n    }\n}\n// ----\n// TypeError 3320: (s1.sol:58-61): Operators can only be defined in a global 'using for' directive.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_different_file.sol",
    "content": "==== Source: s1.sol ====\ntype Int is int;\n\n==== Source: s2.sol ====\nimport \"s1.sol\";\n\nfunction bitnot(Int) pure returns (Int) {}\n\nusing {bitnot as ~} for Int global;\n// ----\n// TypeError 4117: (s2.sol:62-97): Can only use \"global\" with types defined in the same source unit at file level.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_unary_and_non_global_binary_same_file.sol",
    "content": "type Int is int16;\n\nusing {unsub as -} for Int global;\nusing {sub as -} for Int;\n\nfunction sub(Int a, Int b) pure returns (Int) {}\n\nfunction unsub(Int a) pure returns (Int) {}\n\ncontract C {\n    function test_sub() public pure returns (Int) {\n        return Int.wrap(7) - Int.wrap(2);\n    }\n\n    function test_unsub() public pure returns (Int) {\n        return -Int.wrap(4);\n    }\n}\n// ----\n// TypeError 3320: (62-65): Operators can only be defined in a global 'using for' directive.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_constant_payable.sol",
    "content": "contract C {\n    address constant payable b = address(0);\n}\n// ----\n// ParserError 2314: (34-41): Expected identifier but got 'payable'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_function_arguments_and_returns.sol",
    "content": "contract C {\n    function f(address) public pure returns (address) {}\n    function g(address payable) public pure returns (address payable) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_in_struct.sol",
    "content": "contract C {\n    struct S {\n        address payable a;\n        address b;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_invalid_state_mutability.sol",
    "content": "contract C {\n    address view m_a;\n    address pure m_b;\n    address view[] m_c;\n    mapping(uint => address view) m_d;\n    function f() public pure {\n        address view a;\n        address pure b;\n        a; b;\n    }\n    function g(address view) public pure {}\n    function h(address pure) public pure {}\n    function i() public pure returns (address view) {}\n    function j() public pure returns (address pure) {}\n    modifier m1(address view) {_;}\n    modifier m2(address pure) {_;}\n    event e1(address view);\n    event e2(address pure);\n    error err1(address view);\n    error err2(address pure);\n    function f2() public pure returns (address) {\n        try this.f2() returns (address view res) {} catch {}\n    }\n    function f3() public pure returns (address) {\n        try this.f3() returns (address pure res) {} catch {}\n    }\n}\naddress view constant f_a;\naddress pure constant f_b;\n// ----\n// TypeError 2311: (17-29): Address types can only be payable or non-payable.\n// TypeError 2311: (39-51): Address types can only be payable or non-payable.\n// TypeError 2311: (61-73): Address types can only be payable or non-payable.\n// TypeError 2311: (101-113): Address types can only be payable or non-payable.\n// TypeError 2311: (159-171): Address types can only be payable or non-payable.\n// TypeError 2311: (183-195): Address types can only be payable or non-payable.\n// TypeError 2311: (234-246): Address types can only be payable or non-payable.\n// TypeError 2311: (278-290): Address types can only be payable or non-payable.\n// TypeError 2311: (345-357): Address types can only be payable or non-payable.\n// TypeError 2311: (400-412): Address types can only be payable or non-payable.\n// TypeError 2311: (433-445): Address types can only be payable or non-payable.\n// TypeError 2311: (468-480): Address types can only be payable or non-payable.\n// TypeError 2311: (500-512): Address types can only be payable or non-payable.\n// TypeError 2311: (528-540): Address types can only be payable or non-payable.\n// TypeError 2311: (558-570): Address types can only be payable or non-payable.\n// TypeError 2311: (588-600): Address types can only be payable or non-payable.\n// TypeError 2311: (684-696): Address types can only be payable or non-payable.\n// TypeError 2311: (801-813): Address types can only be payable or non-payable.\n// TypeError 2311: (839-851): Address types can only be payable or non-payable.\n// TypeError 2311: (866-878): Address types can only be payable or non-payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_nonpayable.sol",
    "content": "contract C {\n    address a;\n    function f(address b) public pure returns (address c) {\n        address d = b;\n        return d;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_payable.sol",
    "content": "contract C {\n    address payable a;\n    function f(address payable b) public pure returns (address payable c) {\n        address payable d = b;\n        return d;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_payable_constant.sol",
    "content": "contract C {\n    address payable constant a = payable(0);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_payable_conversion.sol",
    "content": "contract C {\n    function f() public pure {\n        address payable a = address payable(this);\n    }\n}\n// ----\n// ParserError 2314: (80-87): Expected ';' but got 'payable'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_payable_function_type.sol",
    "content": "contract C {\n    function (address payable) view internal returns (address payable) f;\n    function g(function (address payable) payable external returns (address payable)) public payable returns (function (address payable) payable external returns (address payable)) {\n        function (address payable) payable external returns (address payable) h; h;\n    }\n}\n// ----\n// Warning 6321: (197-267): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_payable_library.sol",
    "content": "library L {\n}\ncontract C {\n    using L for address payable;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_payable_local.sol",
    "content": "contract C {\n    mapping(uint => address payable) m;\n    mapping(uint => address payable[]) n;\n    function f() public view {\n        address payable a;\n        address payable[] memory b;\n        mapping(uint => address payable) storage c = m;\n        mapping(uint => address payable[]) storage d = n;\n        a; b; c; d;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_payable_state_variable.sol",
    "content": "contract C {\n    address payable a;\n    address payable public b;\n    address payable[] c;\n    address payable[] public d;\n    mapping(uint => address payable) e;\n    mapping(uint => address payable[]) f;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_payable_struct.sol",
    "content": "contract C {\n    struct S {\n        address payable a;\n        address payable[] b;\n        mapping(uint => address payable) c;\n        mapping(uint => address payable[]) d;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_payable_type_expression.sol",
    "content": "contract C {\n    function f() public pure {\n        address payable;\n    }\n}\n// ----\n// ParserError 2314: (67-68): Expected identifier but got ';'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/address_public_payable_error.sol",
    "content": "contract C {\n    address public payable a;\n}\n// ----\n// ParserError 2314: (32-39): Expected identifier but got 'payable'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/array_range_and_ternary.sol",
    "content": "contract C {\n    function f(bool cond, bytes calldata x) external pure {\n        bytes1 a = x[cond ? 1 : 2]; a;\n        abi.decode(x[cond ? 1 : 2 : ], (uint256));\n        abi.decode(x[cond ? 1 : 2 : cond ? 3 : 4], (uint256));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/array_range_conversion.sol",
    "content": "contract C {\n    function f() public pure {\n        uint[] memory x;\n        uint[1:](x);\n        uint[1:2](x);\n        uint[][1:](x);\n    }\n}\n// ----\n// TypeError 1760: (77-85): Types cannot be sliced.\n// TypeError 9640: (77-88): Explicit type conversion not allowed from \"uint256[] memory\" to \"uint256\".\n// TypeError 1760: (98-107): Types cannot be sliced.\n// TypeError 9640: (98-110): Explicit type conversion not allowed from \"uint256[] memory\" to \"uint256\".\n// TypeError 1760: (120-130): Types cannot be sliced.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/array_range_nested.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(uint256[][] calldata x) external pure {\n        x[0][1:2];\n        uint256 a = x[0][1:2][1:2][1:][3:][0];\n        uint256 b = x[1][1:][3:4][1:][2:3][0];\n        a; b;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/array_range_nested_invalid.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    function f(uint256[][] calldata x) external pure {\n        x[1:2];\n        x[:];\n        x[1:];\n        x[:2];\n    }\n}\n// ----\n// TypeError 2148: (110-116): Index range access is not supported for arrays with dynamically encoded base types.\n// TypeError 2148: (126-130): Index range access is not supported for arrays with dynamically encoded base types.\n// TypeError 2148: (140-145): Index range access is not supported for arrays with dynamically encoded base types.\n// TypeError 2148: (155-160): Index range access is not supported for arrays with dynamically encoded base types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/array_range_no_start.sol",
    "content": "contract C {\n    function f(uint256[] calldata x) external pure {\n        x[:][:10];\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/array_type_range.sol",
    "content": "contract C {\n    function f() public pure {\n        uint[][1:] memory x;\n        uint[][1:2] memory x;\n        uint[1:] memory x;\n        uint[1:2] memory x;\n    }\n}\n\n// ----\n// ParserError 5464: (52-62): Expected array length expression.\n// ParserError 5464: (81-92): Expected array length expression.\n// ParserError 5464: (111-119): Expected array length expression.\n// ParserError 5464: (138-147): Expected array length expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/arrays_in_events.sol",
    "content": "contract c {\n    event e(uint[10] a, bytes7[8] indexed b, c[3] x);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/arrays_in_expressions.sol",
    "content": "contract c {\n    function f() public { c[10] storage a = 7; uint8[10 * 2] storage x; }\n}\n// ----\n// TypeError 9574: (39-58): Type int_const 7 is not implicitly convertible to expected type contract c[10] storage pointer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/arrays_in_storage.sol",
    "content": "contract c {\n    uint[10] a;\n    uint[] a2;\n    struct x { uint[2**20] b; y[1] c; }\n    struct y { uint d; mapping(uint=>x)[] e; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/assembly_evmasm_type.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly \"evmasm\" {}\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/assembly_invalid_type.sol",
    "content": "contract C {\n  function f() public pure {\n    assembly \"failasm\" {}\n  }\n}\n// ----\n// ParserError 4531: (55-64): Only \"evmasm\" supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/calling_function.sol",
    "content": "contract test {\n    function f() public {\n        function() returns(function() returns(function() returns(function() returns(uint)))) x;\n        uint y;\n        y = x()()()();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/comment_end_with_double_star.sol",
    "content": "contract C1 {\n/**\n **/\n}\ncontract C2 {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/conditional_multiple.sol",
    "content": "contract A {\n    function f() public {\n        uint x = 3 < 0 ? 2 > 1 ? 2 : 1 : 7 > 2 ? 7 : 6;\n    }\n}\n// ----\n// Warning 2072: (47-53): Unused local variable.\n// Warning 2018: (17-100): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/conditional_true_false_literal.sol",
    "content": "contract A {\n    function f() public {\n        uint x = true ? 1 : 0;\n        uint y = false ? 0 : 1;\n    }\n}\n// ----\n// Warning 2072: (47-53): Unused local variable.\n// Warning 2072: (78-84): Unused local variable.\n// Warning 2018: (17-107): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/conditional_with_assignment.sol",
    "content": "contract A {\n    function f() public pure {\n        uint y = 1;\n        uint x = 3 < 0 ? y = 3 : 6;\n        true ? x = 3 : 4;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/conditional_with_constants.sol",
    "content": "contract A {\n    function f() public {\n        uint x = 3 > 0 ? 3 : 0;\n        uint y = (3 > 0) ? 3 : 0;\n    }\n}\n// ----\n// Warning 2072: (47-53): Unused local variable.\n// Warning 2072: (79-85): Unused local variable.\n// Warning 2018: (17-110): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/conditional_with_variables.sol",
    "content": "contract A {\n    function f() public {\n        uint x = 3;\n        uint y = 1;\n        uint z = (x > y) ? x : y;\n        uint w = x > y ? x : y;\n    }\n}\n// ----\n// Warning 2072: (87-93): Unused local variable.\n// Warning 2072: (121-127): Unused local variable.\n// Warning 2018: (17-150): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/constant_is_keyword.sol",
    "content": "contract Foo {\n\tuint constant = 4;\n}\n// ----\n// ParserError 2314: (30-31): Expected identifier but got '='\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/constant_state_modifier.sol",
    "content": "contract C {\n\tuint s;\n\tfunction f() public constant returns (uint) {\n\t\treturn s;\n\t}\n}\n// ----\n// ParserError 2314: (43-51): Expected '{' but got 'constant'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol",
    "content": "contract A {\n    function a() public pure {\n    }\n}\ncontract B {\n    constructor(C) {\n    }\n    function b(C) public returns (A) {\n        return new A();\n    }\n}\ncontract C {\n    B m_b;\n    C m_c;\n    constructor(C other_c) {\n        m_c = other_c;\n        m_b = new B(this);\n        m_b.b(this).a();\n        g(this).f();\n        other_c.f();\n        m_c.f();\n    }\n    function f() public pure {\n    }\n    function g(C) public view returns (C) {\n        return m_c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/constructor_internal_internal.sol",
    "content": "contract C {\n  constructor() internal internal {}\n}\n// ----\n// ParserError 9439: (38-46): Visibility already specified as \"internal\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/constructor_internal_public.sol",
    "content": "contract C {\n  constructor() internal public {}\n}\n// ----\n// ParserError 9439: (38-44): Visibility already specified as \"internal\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/constructor_payable_payable.sol",
    "content": "contract C {\n  constructor() payable payable {}\n}\n// ----\n// ParserError 9680: (37-44): State mutability already specified as \"payable\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/constructor_public_internal.sol",
    "content": "contract C {\n  constructor() public internal {}\n}\n// ----\n// ParserError 9439: (36-44): Visibility already specified as \"public\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/constructor_public_public.sol",
    "content": "contract C {\n  constructor() public public {}\n}\n// ----\n// ParserError 9439: (36-42): Visibility already specified as \"public\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/constructor_super.sol",
    "content": "contract A {\n  function x() pure internal {}\n}\n\ncontract B is A {\n  constructor() {\n    // used to trigger warning about using ``this`` in constructor\n    super.x();\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/contract_named_transient.sol",
    "content": "contract transient {}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/declaring_fixed_and_ufixed_variables.sol",
    "content": "contract A {\n    fixed40x40 storeMe;\n    function f(ufixed x, fixed32x32 y) public {\n        ufixed8x8 a;\n        fixed b;\n    }\n}\n// ----\n// Warning 5667: (52-60): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 5667: (62-74): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 2072: (93-104): Unused local variable.\n// Warning 2072: (114-121): Unused local variable.\n// Warning 2018: (41-128): Function state mutability can be restricted to pure\n// UnimplementedFeatureError 1834: (0-130): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/declaring_fixed_literal_variables.sol",
    "content": "contract A {\n    fixed40x40 pi = 3.14;\n}\n// ----\n// TypeError 2326: (33-37): Type rational_const 157 / 50 is not implicitly convertible to expected type fixed40x40. Try converting to type ufixed16x2 or use an explicit conversion.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/elementary_non_address_state_mutability_argument.sol",
    "content": "contract C {\n    function a(bool payable) public pure {}\n    function b(string payable) public pure {}\n    function c(int payable) public pure {}\n    function d(int256 payable) public pure {}\n    function e(uint payable) public pure {}\n    function f(uint256 payable) public pure {}\n    function g(bytes1 payable) public pure {}\n    function h(bytes payable) public pure {}\n    function i(bytes32 payable) public pure {}\n    function j(fixed payable) public pure {}\n    function k(fixed80x80 payable) public pure {}\n    function l(ufixed payable) public pure {}\n    function m(ufixed80x80 payable) public pure {}\n}\ncontract C1 {\n    function a(bool view) public pure {}\n    function b(string view) public pure {}\n    function c(int view) public pure {}\n    function d(int256 view) public pure {}\n    function e(uint view) public pure {}\n    function f(uint256 view) public pure {}\n    function g(bytes1 view) public pure {}\n    function h(bytes view) public pure {}\n    function i(bytes32 view) public pure {}\n    function j(fixed view) public pure {}\n    function k(fixed80x80 view) public pure {}\n    function l(ufixed view) public pure {}\n    function m(ufixed80x80 view) public pure {}\n}\ncontract C2 {\n    function a(bool pure) public pure {}\n    function b(string pure) public pure {}\n    function c(int pure) public pure {}\n    function d(int256 pure) public pure {}\n    function e(uint pure) public pure {}\n    function f(uint256 pure) public pure {}\n    function g(bytes1 pure) public pure {}\n    function h(bytes pure) public pure {}\n    function i(bytes32 pure) public pure {}\n    function j(fixed pure) public pure {}\n    function k(fixed80x80 pure) public pure {}\n    function l(ufixed pure) public pure {}\n    function m(ufixed80x80 pure) public pure {}\n}\n// ----\n// ParserError 9106: (33-40): State mutability can only be specified for address types.\n// ParserError 9106: (79-86): State mutability can only be specified for address types.\n// ParserError 9106: (122-129): State mutability can only be specified for address types.\n// ParserError 9106: (168-175): State mutability can only be specified for address types.\n// ParserError 9106: (212-219): State mutability can only be specified for address types.\n// ParserError 9106: (259-266): State mutability can only be specified for address types.\n// ParserError 9106: (305-312): State mutability can only be specified for address types.\n// ParserError 9106: (350-357): State mutability can only be specified for address types.\n// ParserError 9106: (397-404): State mutability can only be specified for address types.\n// ParserError 9106: (442-449): State mutability can only be specified for address types.\n// ParserError 9106: (492-499): State mutability can only be specified for address types.\n// ParserError 9106: (538-545): State mutability can only be specified for address types.\n// ParserError 9106: (589-596): State mutability can only be specified for address types.\n// ParserError 9106: (649-653): State mutability can only be specified for address types.\n// ParserError 9106: (692-696): State mutability can only be specified for address types.\n// ParserError 9106: (732-736): State mutability can only be specified for address types.\n// ParserError 9106: (775-779): State mutability can only be specified for address types.\n// ParserError 9106: (816-820): State mutability can only be specified for address types.\n// ParserError 9106: (860-864): State mutability can only be specified for address types.\n// ParserError 9106: (903-907): State mutability can only be specified for address types.\n// ParserError 9106: (945-949): State mutability can only be specified for address types.\n// ParserError 9106: (989-993): State mutability can only be specified for address types.\n// ParserError 9106: (1031-1035): State mutability can only be specified for address types.\n// ParserError 9106: (1078-1082): State mutability can only be specified for address types.\n// ParserError 9106: (1121-1125): State mutability can only be specified for address types.\n// ParserError 9106: (1169-1173): State mutability can only be specified for address types.\n// ParserError 9106: (1226-1230): State mutability can only be specified for address types.\n// ParserError 9106: (1269-1273): State mutability can only be specified for address types.\n// ParserError 9106: (1309-1313): State mutability can only be specified for address types.\n// ParserError 9106: (1352-1356): State mutability can only be specified for address types.\n// ParserError 9106: (1393-1397): State mutability can only be specified for address types.\n// ParserError 9106: (1437-1441): State mutability can only be specified for address types.\n// ParserError 9106: (1480-1484): State mutability can only be specified for address types.\n// ParserError 9106: (1522-1526): State mutability can only be specified for address types.\n// ParserError 9106: (1566-1570): State mutability can only be specified for address types.\n// ParserError 9106: (1608-1612): State mutability can only be specified for address types.\n// ParserError 9106: (1655-1659): State mutability can only be specified for address types.\n// ParserError 9106: (1698-1702): State mutability can only be specified for address types.\n// ParserError 9106: (1746-1750): State mutability can only be specified for address types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/elementary_non_address_state_mutability_file_var.sol",
    "content": "bool payable a;\nstring payable b;\nint payable c;\nint256 payable d;\nuint payable e;\nuint256 payable f;\nbytes1 payable g;\nbytes payable h;\nbytes32 payable i;\nfixed payable j;\nfixed80x80 payable k;\nufixed payable l;\nufixed80x80 payable m;\n\nbool view a2;\nstring view b2;\nint view c2;\nint256 view d2;\nuint view e2;\nuint256 view f2;\nbytes1 view g2;\nbytes view h2;\nbytes32 view i2;\nfixed view j2;\nfixed80x80 view k2;\nufixed view l2;\nufixed80x80 view m2;\n\nbool pure a3;\nstring pure b3;\nint pure c3;\nint256 pure d3;\nuint pure e3;\nuint256 pure f3;\nbytes1 pure g3;\nbytes pure h3;\nbytes32 pure i3;\nfixed pure j3;\nfixed80x80 pure k3;\nufixed pure l3;\nufixed80x80 pure m3;\n// ----\n// ParserError 9106: (5-12): State mutability can only be specified for address types.\n// ParserError 9106: (23-30): State mutability can only be specified for address types.\n// ParserError 9106: (38-45): State mutability can only be specified for address types.\n// ParserError 9106: (56-63): State mutability can only be specified for address types.\n// ParserError 9106: (72-79): State mutability can only be specified for address types.\n// ParserError 9106: (91-98): State mutability can only be specified for address types.\n// ParserError 9106: (109-116): State mutability can only be specified for address types.\n// ParserError 9106: (126-133): State mutability can only be specified for address types.\n// ParserError 9106: (145-152): State mutability can only be specified for address types.\n// ParserError 9106: (162-169): State mutability can only be specified for address types.\n// ParserError 9106: (184-191): State mutability can only be specified for address types.\n// ParserError 9106: (202-209): State mutability can only be specified for address types.\n// ParserError 9106: (225-232): State mutability can only be specified for address types.\n// ParserError 9106: (242-246): State mutability can only be specified for address types.\n// ParserError 9106: (258-262): State mutability can only be specified for address types.\n// ParserError 9106: (271-275): State mutability can only be specified for address types.\n// ParserError 9106: (287-291): State mutability can only be specified for address types.\n// ParserError 9106: (301-305): State mutability can only be specified for address types.\n// ParserError 9106: (318-322): State mutability can only be specified for address types.\n// ParserError 9106: (334-338): State mutability can only be specified for address types.\n// ParserError 9106: (349-353): State mutability can only be specified for address types.\n// ParserError 9106: (366-370): State mutability can only be specified for address types.\n// ParserError 9106: (381-385): State mutability can only be specified for address types.\n// ParserError 9106: (401-405): State mutability can only be specified for address types.\n// ParserError 9106: (417-421): State mutability can only be specified for address types.\n// ParserError 9106: (438-442): State mutability can only be specified for address types.\n// ParserError 9106: (453-457): State mutability can only be specified for address types.\n// ParserError 9106: (469-473): State mutability can only be specified for address types.\n// ParserError 9106: (482-486): State mutability can only be specified for address types.\n// ParserError 9106: (498-502): State mutability can only be specified for address types.\n// ParserError 9106: (512-516): State mutability can only be specified for address types.\n// ParserError 9106: (529-533): State mutability can only be specified for address types.\n// ParserError 9106: (545-549): State mutability can only be specified for address types.\n// ParserError 9106: (560-564): State mutability can only be specified for address types.\n// ParserError 9106: (577-581): State mutability can only be specified for address types.\n// ParserError 9106: (592-596): State mutability can only be specified for address types.\n// ParserError 9106: (612-616): State mutability can only be specified for address types.\n// ParserError 9106: (628-632): State mutability can only be specified for address types.\n// ParserError 9106: (649-653): State mutability can only be specified for address types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/elementary_non_address_state_mutability_local.sol",
    "content": "contract C {\n    function f() public pure {\n        bool payable a;\n        string payable b;\n        int payable c;\n        int256 payable d;\n        uint payable e;\n        uint256 payable f;\n        bytes1 payable g;\n        bytes payable h;\n        bytes32 payable i;\n        fixed payable j;\n        fixed80x80 payable k;\n        ufixed payable l;\n        ufixed80x80 payable m;\n    }\n}\ncontract C2 {\n    function f() public pure {\n        bool view a;\n        string view b;\n        int view c;\n        int256 view d;\n        uint view e;\n        uint256 view f;\n        bytes1 view g;\n        bytes view h;\n        bytes32 view i;\n        fixed view j;\n        fixed80x80 view k;\n        ufixed view l;\n        ufixed80x80 view m;\n    }\n}\ncontract C3 {\n    function f() public pure {\n        bool pure a;\n        string pure b;\n        int pure c;\n        int256 pure d;\n        uint pure e;\n        uint256 pure f;\n        bytes1 pure g;\n        bytes pure h;\n        bytes32 pure i;\n        fixed pure j;\n        fixed80x80 pure k;\n        ufixed pure l;\n        ufixed80x80 pure m;\n    }\n}\n// ----\n// ParserError 9106: (57-64): State mutability can only be specified for address types.\n// ParserError 9106: (83-90): State mutability can only be specified for address types.\n// ParserError 9106: (106-113): State mutability can only be specified for address types.\n// ParserError 9106: (132-139): State mutability can only be specified for address types.\n// ParserError 9106: (156-163): State mutability can only be specified for address types.\n// ParserError 9106: (183-190): State mutability can only be specified for address types.\n// ParserError 9106: (209-216): State mutability can only be specified for address types.\n// ParserError 9106: (234-241): State mutability can only be specified for address types.\n// ParserError 9106: (261-268): State mutability can only be specified for address types.\n// ParserError 9106: (286-293): State mutability can only be specified for address types.\n// ParserError 9106: (316-323): State mutability can only be specified for address types.\n// ParserError 9106: (342-349): State mutability can only be specified for address types.\n// ParserError 9106: (373-380): State mutability can only be specified for address types.\n// ParserError 9106: (450-454): State mutability can only be specified for address types.\n// ParserError 9106: (473-477): State mutability can only be specified for address types.\n// ParserError 9106: (493-497): State mutability can only be specified for address types.\n// ParserError 9106: (516-520): State mutability can only be specified for address types.\n// ParserError 9106: (537-541): State mutability can only be specified for address types.\n// ParserError 9106: (561-565): State mutability can only be specified for address types.\n// ParserError 9106: (584-588): State mutability can only be specified for address types.\n// ParserError 9106: (606-610): State mutability can only be specified for address types.\n// ParserError 9106: (630-634): State mutability can only be specified for address types.\n// ParserError 9106: (652-656): State mutability can only be specified for address types.\n// ParserError 9106: (679-683): State mutability can only be specified for address types.\n// ParserError 9106: (702-706): State mutability can only be specified for address types.\n// ParserError 9106: (730-734): State mutability can only be specified for address types.\n// ParserError 9106: (804-808): State mutability can only be specified for address types.\n// ParserError 9106: (827-831): State mutability can only be specified for address types.\n// ParserError 9106: (847-851): State mutability can only be specified for address types.\n// ParserError 9106: (870-874): State mutability can only be specified for address types.\n// ParserError 9106: (891-895): State mutability can only be specified for address types.\n// ParserError 9106: (915-919): State mutability can only be specified for address types.\n// ParserError 9106: (938-942): State mutability can only be specified for address types.\n// ParserError 9106: (960-964): State mutability can only be specified for address types.\n// ParserError 9106: (984-988): State mutability can only be specified for address types.\n// ParserError 9106: (1006-1010): State mutability can only be specified for address types.\n// ParserError 9106: (1033-1037): State mutability can only be specified for address types.\n// ParserError 9106: (1056-1060): State mutability can only be specified for address types.\n// ParserError 9106: (1084-1088): State mutability can only be specified for address types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/elementary_non_address_state_mutability_return.sol",
    "content": "contract C {\n    function a() public pure returns (bool payable) {}\n    function b() public pure returns (string payable) {}\n    function c() public pure returns (int payable) {}\n    function d() public pure returns (int256 payable) {}\n    function e() public pure returns (uint payable) {}\n    function f() public pure returns (uint256 payable) {}\n    function g() public pure returns (bytes1 payable) {}\n    function h() public pure returns (bytes payable) {}\n    function i() public pure returns (bytes32 payable) {}\n    function j() public pure returns (fixed payable) {}\n    function k() public pure returns (fixed80x80 payable) {}\n    function l() public pure returns (ufixed payable) {}\n    function m() public pure returns (ufixed80x80 payable) {}\n}\ncontract C1 {\n    function a() public pure returns (bool view) {}\n    function b() public pure returns (string view) {}\n    function c() public pure returns (int view) {}\n    function d() public pure returns (int256 view) {}\n    function e() public pure returns (uint view) {}\n    function f() public pure returns (uint256 view) {}\n    function g() public pure returns (bytes1 view) {}\n    function h() public pure returns (bytes view) {}\n    function i() public pure returns (bytes32 view) {}\n    function j() public pure returns (fixed view) {}\n    function k() public pure returns (fixed80x80 view) {}\n    function l() public pure returns (ufixed view) {}\n    function m() public pure returns (ufixed80x80 view) {}\n}\ncontract C2 {\n    function a() public pure returns (bool pure) {}\n    function b() public pure returns (string pure) {}\n    function c() public pure returns (int pure) {}\n    function d() public pure returns (int256 pure) {}\n    function e() public pure returns (uint pure) {}\n    function f() public pure returns (uint256 pure) {}\n    function g() public pure returns (bytes1 pure) {}\n    function h() public pure returns (bytes pure) {}\n    function i() public pure returns (bytes32 pure) {}\n    function j() public pure returns (fixed pure) {}\n    function k() public pure returns (fixed80x80 pure) {}\n    function l() public pure returns (ufixed pure) {}\n    function m() public pure returns (ufixed80x80 pure) {}\n}\n// ----\n// ParserError 9106: (56-63): State mutability can only be specified for address types.\n// ParserError 9106: (113-120): State mutability can only be specified for address types.\n// ParserError 9106: (167-174): State mutability can only be specified for address types.\n// ParserError 9106: (224-231): State mutability can only be specified for address types.\n// ParserError 9106: (279-286): State mutability can only be specified for address types.\n// ParserError 9106: (337-344): State mutability can only be specified for address types.\n// ParserError 9106: (394-401): State mutability can only be specified for address types.\n// ParserError 9106: (450-457): State mutability can only be specified for address types.\n// ParserError 9106: (508-515): State mutability can only be specified for address types.\n// ParserError 9106: (564-571): State mutability can only be specified for address types.\n// ParserError 9106: (625-632): State mutability can only be specified for address types.\n// ParserError 9106: (682-689): State mutability can only be specified for address types.\n// ParserError 9106: (744-751): State mutability can only be specified for address types.\n// ParserError 9106: (815-819): State mutability can only be specified for address types.\n// ParserError 9106: (869-873): State mutability can only be specified for address types.\n// ParserError 9106: (920-924): State mutability can only be specified for address types.\n// ParserError 9106: (974-978): State mutability can only be specified for address types.\n// ParserError 9106: (1026-1030): State mutability can only be specified for address types.\n// ParserError 9106: (1081-1085): State mutability can only be specified for address types.\n// ParserError 9106: (1135-1139): State mutability can only be specified for address types.\n// ParserError 9106: (1188-1192): State mutability can only be specified for address types.\n// ParserError 9106: (1243-1247): State mutability can only be specified for address types.\n// ParserError 9106: (1296-1300): State mutability can only be specified for address types.\n// ParserError 9106: (1354-1358): State mutability can only be specified for address types.\n// ParserError 9106: (1408-1412): State mutability can only be specified for address types.\n// ParserError 9106: (1467-1471): State mutability can only be specified for address types.\n// ParserError 9106: (1535-1539): State mutability can only be specified for address types.\n// ParserError 9106: (1589-1593): State mutability can only be specified for address types.\n// ParserError 9106: (1640-1644): State mutability can only be specified for address types.\n// ParserError 9106: (1694-1698): State mutability can only be specified for address types.\n// ParserError 9106: (1746-1750): State mutability can only be specified for address types.\n// ParserError 9106: (1801-1805): State mutability can only be specified for address types.\n// ParserError 9106: (1855-1859): State mutability can only be specified for address types.\n// ParserError 9106: (1908-1912): State mutability can only be specified for address types.\n// ParserError 9106: (1963-1967): State mutability can only be specified for address types.\n// ParserError 9106: (2016-2020): State mutability can only be specified for address types.\n// ParserError 9106: (2074-2078): State mutability can only be specified for address types.\n// ParserError 9106: (2128-2132): State mutability can only be specified for address types.\n// ParserError 9106: (2187-2191): State mutability can only be specified for address types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/elementary_non_address_state_mutability_state_variable.sol",
    "content": "contract C {\n    bool payable a;\n    string payable b;\n    int payable c;\n    int256 payable d;\n    uint payable e;\n    uint256 payable f;\n    bytes1 payable g;\n    bytes payable h;\n    bytes32 payable i;\n    fixed payable j;\n    fixed80x80 payable k;\n    ufixed payable l;\n    ufixed80x80 payable m;\n}\ncontract C2 {\n    bool view a;\n    string view b;\n    int view c;\n    int256 view d;\n    uint view e;\n    uint256 view f;\n    bytes1 view g;\n    bytes view h;\n    bytes32 view i;\n    fixed view j;\n    fixed80x80 view k;\n    ufixed view l;\n    ufixed80x80 view m;\n}\ncontract C3 {\n    bool pure a;\n    string pure b;\n    int pure c;\n    int256 pure d;\n    uint pure e;\n    uint256 pure f;\n    bytes1 pure g;\n    bytes pure h;\n    bytes32 pure i;\n    fixed pure j;\n    fixed80x80 pure k;\n    ufixed pure l;\n    ufixed80x80 pure m;\n}\n// ----\n// ParserError 9106: (22-29): State mutability can only be specified for address types.\n// ParserError 9106: (44-51): State mutability can only be specified for address types.\n// ParserError 9106: (63-70): State mutability can only be specified for address types.\n// ParserError 9106: (85-92): State mutability can only be specified for address types.\n// ParserError 9106: (105-112): State mutability can only be specified for address types.\n// ParserError 9106: (128-135): State mutability can only be specified for address types.\n// ParserError 9106: (150-157): State mutability can only be specified for address types.\n// ParserError 9106: (171-178): State mutability can only be specified for address types.\n// ParserError 9106: (194-201): State mutability can only be specified for address types.\n// ParserError 9106: (215-222): State mutability can only be specified for address types.\n// ParserError 9106: (241-248): State mutability can only be specified for address types.\n// ParserError 9106: (263-270): State mutability can only be specified for address types.\n// ParserError 9106: (290-297): State mutability can only be specified for address types.\n// ParserError 9106: (326-330): State mutability can only be specified for address types.\n// ParserError 9106: (345-349): State mutability can only be specified for address types.\n// ParserError 9106: (361-365): State mutability can only be specified for address types.\n// ParserError 9106: (380-384): State mutability can only be specified for address types.\n// ParserError 9106: (397-401): State mutability can only be specified for address types.\n// ParserError 9106: (417-421): State mutability can only be specified for address types.\n// ParserError 9106: (436-440): State mutability can only be specified for address types.\n// ParserError 9106: (454-458): State mutability can only be specified for address types.\n// ParserError 9106: (474-478): State mutability can only be specified for address types.\n// ParserError 9106: (492-496): State mutability can only be specified for address types.\n// ParserError 9106: (515-519): State mutability can only be specified for address types.\n// ParserError 9106: (534-538): State mutability can only be specified for address types.\n// ParserError 9106: (558-562): State mutability can only be specified for address types.\n// ParserError 9106: (591-595): State mutability can only be specified for address types.\n// ParserError 9106: (610-614): State mutability can only be specified for address types.\n// ParserError 9106: (626-630): State mutability can only be specified for address types.\n// ParserError 9106: (645-649): State mutability can only be specified for address types.\n// ParserError 9106: (662-666): State mutability can only be specified for address types.\n// ParserError 9106: (682-686): State mutability can only be specified for address types.\n// ParserError 9106: (701-705): State mutability can only be specified for address types.\n// ParserError 9106: (719-723): State mutability can only be specified for address types.\n// ParserError 9106: (739-743): State mutability can only be specified for address types.\n// ParserError 9106: (757-761): State mutability can only be specified for address types.\n// ParserError 9106: (780-784): State mutability can only be specified for address types.\n// ParserError 9106: (799-803): State mutability can only be specified for address types.\n// ParserError 9106: (823-827): State mutability can only be specified for address types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/else_if_statement.sol",
    "content": "contract test {\n    function fun(uint256 a) public returns (uint8 b) {\n        if (a < 0) b = 0x67; else if (a == 0) b = 0x12; else b = 0x78;\n    }\n}\n// ----\n// Warning 2018: (20-147): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/emit_without_event.sol",
    "content": "contract C {\n\tevent A();\n\tfunction f() {\n\t\temit A;\n\t}\n}\n// ----\n// ParserError 2314: (49-50): Expected '(' but got ';'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/empty_comment.sol",
    "content": "//\ncontract test\n{}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/empty_enum.sol",
    "content": "contract c {\n\tenum foo { }\n}\n// ----\n// ParserError 3147: (25-26): Enum with no members is not allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/empty_function.sol",
    "content": "contract test {\n\tuint256 stateVar;\n\tfunction functionName(bytes20 arg1, address addr) public view returns (int id) { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/enum_from_interface.sol",
    "content": "interface I {\n    enum Direction { Left, Right }\n}\n\ncontract D {\n    function f() public pure returns (I.Direction) {\n      return I.Direction.Left;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/enum_from_interface_in_library.sol",
    "content": "interface I {\n    enum Direction { Left, Right }\n}\n\nlibrary L {\n    function f() public pure returns (I.Direction) {\n      return I.Direction.Left;\n    }\n    function g() internal pure returns (I.Direction) {\n      return I.Direction.Left;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/enum_from_library.sol",
    "content": "library L {\n    enum Direction { Left, Right }\n}\n\ncontract D {\n    function f() public pure returns (L.Direction) {\n      return L.Direction.Left;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/enum_inheritance_contract.sol",
    "content": "contract C {\n    enum Direction { Left, Right }\n}\n\ncontract D is C {\n    function f() public pure returns (Direction) {\n      return Direction.Left;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/enum_inheritance_interface.sol",
    "content": "interface I {\n    enum Direction { Left, Right }\n}\n\ncontract D is I {\n    function f() public pure returns (Direction) {\n      return Direction.Left;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/enum_valid_declaration.sol",
    "content": "contract c {\n    enum validEnum { Value1, Value2, Value3, Value4 }\n    constructor() {\n        a = validEnum.Value3;\n    }\n    validEnum a;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/event.sol",
    "content": "contract c {\n    event e();\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/event_arguments.sol",
    "content": "contract c {\n    event e(uint a, bytes32 s);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/event_arguments_indexed.sol",
    "content": "contract c {\n    event e(uint a, bytes32 indexed s, bool indexed b);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/event_with_no_argument_list.sol",
    "content": "contract c {\n\tevent e;\n}\n// ----\n// ParserError 2314: (21-22): Expected '(' but got ';'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/exp_expression.sol",
    "content": "contract test {\n    function fun(uint256 a) public {\n        uint256 x = 3 ** a;\n    }\n}\n// ----\n// Warning 2072: (61-70): Unused local variable.\n// Warning 2018: (20-86): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/external_function.sol",
    "content": "contract c {\n    function x() external {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/external_variable.sol",
    "content": "contract c {\n\tuint external x;\n}\n// ----\n// ParserError 2314: (19-27): Expected identifier but got 'external'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/fallback_function.sol",
    "content": "contract c {\n    fallback() external { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/fixed_literal_with_double_radix.sol",
    "content": "contract A {\n\tfixed40x40 pi = 3.14.15;\n}\n// ----\n// ParserError 2314: (34-37): Expected ';' but got 'Number'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/for_loop_simple_initexpr.sol",
    "content": "contract test {\n    function fun(uint256 a) public {\n        uint256 i =0;\n        for (i = 0; i < 10; i++) {\n            uint256 x = i; break; continue;\n        }\n    }\n}\n// ----\n// Warning 5740: (103-106): Unreachable code.\n// Warning 5740: (144-152): Unreachable code.\n// Warning 5667: (33-42): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 2072: (122-131): Unused local variable.\n// Warning 2018: (20-169): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/for_loop_simple_noexpr.sol",
    "content": "contract test {\n        function fun(uint256 a) public {\n            uint256 i =0;\n            for (;;) {\n                uint256 x = i; break; continue;\n            }\n        }\n    }\n// ----\n// Warning 5740: (144-152): Unreachable code.\n// Warning 5667: (37-46): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 2072: (122-131): Unused local variable.\n// Warning 2018: (24-177): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/for_loop_single_stmt_body.sol",
    "content": "contract test {\n    function fun(uint256 a) public {\n        uint256 i = 0;\n        for (i = 0; i < 10; i++)\n            continue;\n    }\n}\n// ----\n// Warning 5667: (33-42): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 2018: (20-136): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/for_loop_vardef_initexpr.sol",
    "content": "contract test {\n    function fun(uint256 a) public {\n        for (uint256 i = 0; i < 10; i++) {\n            uint256 x = i; break; continue;\n        }\n    }\n}\n// ----\n// Warning 5740: (89-92): Unreachable code.\n// Warning 5740: (130-138): Unreachable code.\n// Warning 5667: (33-42): Unused function parameter. Remove or comment out the variable name to silence this warning.\n// Warning 2072: (108-117): Unused local variable.\n// Warning 2018: (20-155): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/from_is_not_keyword.sol",
    "content": "// \"from\" is not a keyword although it is used as a keyword in import directives.\ncontract from {\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/function_no_body.sol",
    "content": "abstract contract test {\n\tfunction functionName(bytes32 input) public virtual returns (bytes32 out);\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/function_normal_comments.sol",
    "content": "contract test {\n    uint256 stateVar;\n    // We won't see this comment\n    function functionName(bytes32 input) public returns (bytes32 out) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/function_type_as_parameter.sol",
    "content": "contract test {\n    function f(function(uint) external returns (uint) g) internal returns (uint a) {\n        return g(1);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/function_type_as_storage_variable.sol",
    "content": "contract test {\n    function (uint, uint) internal returns (uint) f1;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/function_type_as_storage_variable_with_assignment.sol",
    "content": "contract test {\n    function f(uint x, uint y) public returns (uint a) {}\n    function (uint, uint) internal returns (uint) f1 = f;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/function_type_as_storage_variable_with_modifiers.sol",
    "content": "contract test {\n\tfunction (uint, uint) modifier1() returns (uint) f1;\n}\n// ----\n// ParserError 2314: (48-49): Expected ';' but got '('\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/function_type_in_expression.sol",
    "content": "contract test {\n    function f(uint x, uint y) public returns (uint a) {}\n    function g() public {\n        function (uint, uint) internal returns (uint) f1 = f;\n    }\n}\n// ----\n// Warning 2072: (108-156): Unused local variable.\n// Warning 2018: (78-167): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/function_type_in_struct.sol",
    "content": "contract test {\n    struct S {\n        function (uint x, uint y) internal returns (uint) f;\n        function (uint, uint) external returns (uint) g;\n        uint d;\n    }\n}\n// ----\n// Warning 6162: (49-55): Naming function type parameters is deprecated.\n// Warning 6162: (57-63): Naming function type parameters is deprecated.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/function_type_multiple_mutability.sol",
    "content": "contract C {\n  function f() public pure {\n    function() pure pure g;\n  }\n}\n// ----\n// ParserError 9680: (62-66): State mutability already specified as \"pure\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/function_type_multiple_visibility.sol",
    "content": "contract C {\n  function f() public pure {\n    function() public public g;\n  }\n}\n// ----\n// ParserError 9439: (64-70): Visibility already specified as \"public\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/function_type_state_variable.sol",
    "content": "contract test {\n\tfunction() x;\n\tfunction() y = x;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/if_statement.sol",
    "content": "contract test {\n    function fun(uint256 a) public returns (uint) {\n        if (a >= 8) { return 2; } else { uint b = 7; }\n    }\n}\n// ----\n// Warning 6321: (60-64): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 2072: (109-115): Unused local variable.\n// Warning 2018: (20-128): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/import_complex.sol",
    "content": "import {hello, world} from \"hello\";\n// ----\n// ParserError 6275: (0-35): Source \"hello\" not found: File not supplied initially.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/import_complex_invalid_from.sol",
    "content": "import {hello, world} from function;\n// ----\n// ParserError 6845: (27-35): Expected import path.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/import_complex_without_from.sol",
    "content": "import {hello, world};\n// ----\n// ParserError 8208: (21-22): Expected \"from\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/import_empty.sol",
    "content": "import \"\";\n// ----\n// ParserError 6326: (9-10): Import path cannot be empty.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/import_invalid_token.sol",
    "content": "import function;\n// ----\n// ParserError 9478: (7-15): Expected string literal (path), \"*\" or alias list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/import_simple.sol",
    "content": "import \"hello\";\n// ----\n// ParserError 6275: (0-15): Source \"hello\" not found: File not supplied initially.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/inline_array_declaration.sol",
    "content": "contract c {\n    uint[] a;\n    function f() public returns (uint, uint) {\n        a = [1,2,3];\n        return (a[3], [2,3,4][0]);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_lvalue.sol",
    "content": "contract c {\n\tuint[] a;\n\tfunction f() returns (uint) {\n\t\ta = [,2,3];\n\t\treturn (a[0]);\n\t}\n}\n// ----\n// ParserError 4799: (62-63): Expected expression (inline array elements cannot be omitted).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_without_lvalue.sol",
    "content": "contract c {\n\tuint[] a;\n\tfunction f() returns (uint, uint) {\n\t\treturn ([3, ,4][0]);\n\t}\n}\n// ----\n// ParserError 4799: (75-76): Expected expression (inline array elements cannot be omitted).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/interface_basic.sol",
    "content": "interface Interface {\n\tfunction f() external;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol",
    "content": "contract test {\n\tfunction f() {\n\t\tfixed a = 1.0x2;\n\t}\n}\n// ----\n// ParserError 8936: (44-47): Identifier-start is not allowed at end of a number.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/invalid_function_parameter_and_return_var_indexed.sol",
    "content": "==== Source: A ====\ncontract test {\n    function f1(uint indexed a) public returns (uint) { }\n}\n==== Source: B ====\ncontract test {\n    function f1(uint a) public returns (uint indexed) { }\n}\n// ----\n// ParserError 2314: (A:37-44): Expected ',' but got 'indexed'\n// ParserError 2314: (B:61-68): Expected ',' but got 'indexed'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/invalid_function_parameter_and_return_var_mutability.sol",
    "content": "contract test {\n    function f1(uint immutable a) public returns (uint immutable) { }\n    function f2(uint constant a) public returns (uint constant) { }\n}\n// ----\n// DeclarationError 8297: (32-48): The \"immutable\" keyword can only be used for state variables.\n// DeclarationError 8297: (66-80): The \"immutable\" keyword can only be used for state variables.\n// DeclarationError 1788: (102-117): The \"constant\" keyword can only be used for state variables or variables at file level.\n// DeclarationError 1788: (135-148): The \"constant\" keyword can only be used for state variables or variables at file level.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/invalid_state_variable_location.sol",
    "content": "==== Source: A ====\ncontract test {\n    string memory a;\n}\n==== Source: B ====\ncontract test {\n    string calldata a;\n}\n// ----\n// ParserError 2314: (A:27-33): Expected identifier but got 'memory'\n// ParserError 2314: (B:27-35): Expected identifier but got 'calldata'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/invalid_variable_indexed.sol",
    "content": "==== Source: A ====\nuint indexed a;\n==== Source: B ====\ncontract test {\n    function f(uint a) public {\n        uint indexed a;\n    }\n}\n==== Source: C ====\ncontract test {\n    uint indexed a;\n}\n// ----\n// ParserError 2314: (A:5-12): Expected identifier but got 'indexed'\n// ParserError 2314: (B:61-68): Expected ';' but got 'indexed'\n// ParserError 2314: (C:25-32): Expected identifier but got 'indexed'"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/invalid_variable_mutability.sol",
    "content": "==== Source: A ====\ncontract test {\n    function f(uint a) public {\n        uint constant a;\n    }\n}\n==== Source: B ====\ncontract test {\n    function f(uint a) public {\n        uint immutable a;\n    }\n}\n// ----\n// ParserError 2314: (A:61-69): Expected ';' but got 'constant'\n// ParserError 2314: (B:61-70): Expected ';' but got 'immutable'"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/invalid_variable_named_unicode.sol",
    "content": "contract C\n{\n    string unicode = \"abc\";\n}\n// ----\n// ParserError 2314: (24-31): Expected identifier but got 'ILLEGAL'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_decimal.sol",
    "content": "contract C {\n  function f() public pure {\n    uint d1 = 654_321;\n    uint d2 =  54_321;\n    uint d3 =   4_321;\n    uint d4 = 5_43_21;\n    uint d5 = 1_2e10;\n    uint d6 = 12e1_0;\n\n    d1; d2; d3; d4; d5; d6;\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_decimal_fail.sol",
    "content": "contract C {\n  function f() public pure {\n    uint D1 = 1234_;\n    uint D2 = 12__34;\n    uint D3 = 12_e34;\n    uint D4 = 12e_34;\n  }\n}\n// ----\n// SyntaxError 2090: (56-61): Invalid use of underscores in number literal. No trailing underscores allowed.\n// SyntaxError 2990: (77-83): Invalid use of underscores in number literal. Only one consecutive underscore between digits is allowed.\n// SyntaxError 6415: (99-105): Invalid use of underscores in number literal. No underscore at the end of the mantissa allowed.\n// SyntaxError 6165: (121-127): Invalid use of underscores in number literal. No underscore in front of exponent allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed.sol",
    "content": "contract C {\n  function f() public pure {\n    fixed f1 = 3.14_15;\n    fixed f2 = 3_1.4_15;\n\n    f1; f2;\n  }\n}\n// ====\n// compileViaYul: true\n// ----\n// UnimplementedFeatureError 1834: (46-64): Fixed point types not implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_fixed_fail.sol",
    "content": "contract C {\n  function f() public pure {\n    fixed F1 = 3.1415_;\n    fixed F2 = 3__1.4__15;\n    fixed F3 = 1_.2;\n    fixed F4 = 1._2;\n    fixed F5 = 1.2e_12;\n    fixed F6 = 1._;\n  }\n}\n// ----\n// SyntaxError 2090: (57-64): Invalid use of underscores in number literal. No trailing underscores allowed.\n// SyntaxError 2990: (81-91): Invalid use of underscores in number literal. Only one consecutive underscore between digits is allowed.\n// SyntaxError 1023: (108-112): Invalid use of underscores in number literal. No underscores in front of the fraction part allowed.\n// SyntaxError 3891: (129-133): Invalid use of underscores in number literal. No underscores in front of the fraction part allowed.\n// SyntaxError 6165: (150-157): Invalid use of underscores in number literal. No underscore in front of exponent allowed.\n// SyntaxError 2090: (174-177): Invalid use of underscores in number literal. No trailing underscores allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_hex.sol",
    "content": "contract C {\n  function f() public pure {\n    uint x1 = 0x8765_4321;\n    uint x2 = 0x765_4321;\n    uint x3 = 0x65_4321;\n    uint x4 = 0x5_4321;\n    uint x5 = 0x123_1234_1234_1234;\n    uint x6 = 0x123456_1234_1234;\n\n    x1; x2; x3; x4; x5; x6;\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/lexer_numbers_with_underscores_hex_fail.sol",
    "content": "contract C {\n  function f() public pure {\n    uint X1 = 0x1234__1234__1234__123;\n  }\n}\n// ----\n// SyntaxError 2990: (56-79): Invalid use of underscores in number literal. Only one consecutive underscore between digits is allowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/library_simple.sol",
    "content": "library Lib {\n    function f() public { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/literal_constants_with_ether_subdenominations.sol",
    "content": "contract C {\n    function f() public\n    {\n         a = 1 wei;\n         b = 2 ether;\n         c = 3 gwei;\n    }\n    uint256 a;\n    uint256 b;\n    uint256 c;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/literal_constants_with_ether_subdenominations_in_expressions.sol",
    "content": "contract c {\n    constructor()\n    {\n         a = 1 wei * 100 wei + 7 gwei - 3;\n    }\n    uint256 a;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/local_const_variable.sol",
    "content": "contract Foo {\n\tfunction localConst() returns (uint ret)\n\t{\n\t\tuint constant local = 4;\n\t\treturn local;\n\t}\n}\n// ----\n// ParserError 2314: (67-75): Expected ';' but got 'constant'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/location_specifiers_for_file_level_var.sol",
    "content": "==== Source: A ====\nuint[] storage a;\n==== Source: B ====\nuint[] memory b;\n==== Source: C ====\nuint[] calldata c;\n// ----\n// ParserError 2314: (A:7-14): Expected identifier but got 'storage'\n// ParserError 2314: (B:7-13): Expected identifier but got 'memory'\n// ParserError 2314: (C:7-15): Expected identifier but got 'calldata'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/location_specifiers_for_fn_returns_multi.sol",
    "content": "contract Foo {\n    function f1() returns (string calldata calldata) {}\n    function f2() returns (string calldata memory) {}\n    function f3() returns (string calldata storage) {}\n    function f4() returns (string memory calldata) {}\n    function f5() returns (string memory memory) {}\n    function f6() returns (string memory storage) {}\n    function f7() returns (string storage calldata) {}\n    function f8() returns (string storage memory) {}\n    function f9() returns (string storage storage) {}\n}\n// ----\n// ParserError 3548: (58-66): Location already specified.\n// ParserError 3548: (114-120): Location already specified.\n// ParserError 3548: (168-175): Location already specified.\n// ParserError 3548: (221-229): Location already specified.\n// ParserError 3548: (275-281): Location already specified.\n// ParserError 3548: (327-334): Location already specified.\n// ParserError 3548: (381-389): Location already specified.\n// ParserError 3548: (436-442): Location already specified.\n// ParserError 3548: (489-496): Location already specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/location_specifiers_for_locals.sol",
    "content": "contract Foo {\n    uint[] m_x;\n    function f() public view {\n        uint[] storage x = m_x;\n        uint[] memory y;\n        x; y;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/location_specifiers_for_locals_multi.sol",
    "content": "contract Foo {\n    uint[] m_x;\n    function f() public view {\n        uint[] storage memory x = m_x;\n        uint[] memory storage calldata y;\n        uint[] storage calldata x2;\n        uint[] storage storage x3;\n        uint[] calldata memory x4;\n        uint[] calldata calldata x5;\n        uint[] calldata storage x6;\n        uint[] storage memory x4;\n        uint[] storage calldata x5;\n        uint[] storage storage x6;\n        x; y;\n    }\n}\n// ----\n// ParserError 3548: (85-91): Location already specified.\n// ParserError 3548: (123-130): Location already specified.\n// ParserError 3548: (131-139): Location already specified.\n// ParserError 3548: (166-174): Location already specified.\n// ParserError 3548: (202-209): Location already specified.\n// ParserError 3548: (238-244): Location already specified.\n// ParserError 3548: (273-281): Location already specified.\n// ParserError 3548: (310-317): Location already specified.\n// ParserError 3548: (345-351): Location already specified.\n// ParserError 3548: (379-387): Location already specified.\n// ParserError 3548: (415-422): Location already specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/location_specifiers_for_params.sol",
    "content": "contract Foo {\n    function f(uint[] storage constant x, uint[] memory y) internal { }\n}\n// ----\n// DeclarationError 1788: (30-55): The \"constant\" keyword can only be used for state variables or variables at file level.\n// TypeError 9259: (30-55): Only constants of value type and byte array type are implemented.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/location_specifiers_for_params_multi.sol",
    "content": "contract Foo {\n    function f(uint[] storage memory constant x, uint[] memory calldata y) internal { }\n    function f2(uint[] storage storage x) internal { }\n    function f3(uint[] storage calldata x) internal { }\n    function f4(uint[] memory storage x) internal { }\n    function f5(uint[] memory memory x) internal { }\n    function f6(uint[] calldata storage x) internal { }\n    function f7(uint[] calldata memory x) internal { }\n    function f8(uint[] calldata calldata x) internal { }\n}\n// ----\n// ParserError 3548: (45-51): Location already specified.\n// ParserError 3548: (78-86): Location already specified.\n// ParserError 3548: (134-141): Location already specified.\n// ParserError 3548: (189-197): Location already specified.\n// ParserError 3548: (244-251): Location already specified.\n// ParserError 3548: (298-304): Location already specified.\n// ParserError 3548: (353-360): Location already specified.\n// ParserError 3548: (409-415): Location already specified.\n// ParserError 3548: (464-472): Location already specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/location_specifiers_for_state_variables.sol",
    "content": "contract Foo {\n\tuint[] memory x;\n}\n// ----\n// ParserError 2314: (23-29): Expected identifier but got 'memory'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/location_specifiers_for_state_variables_multi.sol",
    "content": "==== Source: A ====\ncontract Foo {\n\tuint[] memory storage calldata x;\n}\n==== Source: B ====\ncontract Foo {\n\tuint[] storage storage x;\n}\n// ----\n// ParserError 2314: (A:23-29): Expected identifier but got 'memory'\n// ParserError 2314: (B:23-30): Expected identifier but got 'storage'"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/location_specifiers_with_var.sol",
    "content": "contract Foo {\n\tfunction f() { var memory x; }\n}\n// ----\n// ParserError 6933: (31-34): Expected primary expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/malformed_enum_declaration.sol",
    "content": "contract c {\n\tenum foo { WARNING,}\n}\n// ----\n// ParserError 1612: (33-34): Expected identifier after ','\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping.sol",
    "content": "contract test {\n    mapping(address => bytes32) names;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_and_array_of_functions.sol",
    "content": "contract test {\n    mapping (address => function() internal returns (uint)) a;\n    mapping (address => function() external) b;\n    mapping (address => function() external[]) c;\n    function() external[] d;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_from_address_payable.sol",
    "content": "contract C {\n    mapping(address payable => uint) m;\n}\n// ----\n// ParserError 2314: (33-40): Expected '=>' but got 'payable'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_in_struct.sol",
    "content": "contract test {\n    struct test_struct {\n        address addr;\n        uint256 count;\n        mapping(bytes32 => test_struct) self_reference;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_1.sol",
    "content": "contract c {\n\tmapping(uint[] => uint) data;\n}\n// ----\n// ParserError 2314: (26-27): Expected '=>' but got '['\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_2.sol",
    "content": "contract c {\n\tstruct S {\n\t\tuint x;\n\t}\n\tmapping(S => uint) data;\n}\n// ----\n// TypeError 7804: (47-48): Only elementary types, user defined value types, contract types or enums are allowed as mapping keys.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_3.sol",
    "content": "contract c {\n\tstruct S {\n\t\tstring s;\n\t}\n\tmapping(S => uint) data;\n}\n// ----\n// TypeError 7804: (49-50): Only elementary types, user defined value types, contract types or enums are allowed as mapping keys.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_nonelementary_key_4.sol",
    "content": "contract c {\n\tmapping(string[] => uint) data;\n}\n// ----\n// ParserError 2314: (28-29): Expected '=>' but got '['\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_to_mapping_in_struct.sol",
    "content": "contract test {\n    struct test_struct {\n        address addr;\n        mapping (uint64 => mapping (bytes32 => uint)) complex_mapping;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_1.sol",
    "content": "contract test {\n    mapping(address user => bytes32 ipfs) names;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_2.sol",
    "content": "contract test {\n    mapping(address => bytes32 ipfs) names;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_3.sol",
    "content": "contract test {\n    mapping(address user => bytes32) names;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_5.sol",
    "content": "contract test {\n    mapping(address owner => mapping(address spender => bytes32[] notes)) names;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_6.sol",
    "content": "contract test {\n    mapping(address uint => bytes32 ipfs) names;\n}\n// ----\n// ParserError 2314: (36-40): Expected '=>' but got 'uint'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_7.sol",
    "content": "contract test {\n    mapping(address owner => bytes32[] note) notes;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_8.sol",
    "content": "contract test {\n    mapping(address => mapping(address => address) hello) world;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_conflict_1.sol",
    "content": "contract test {\n    address owner;\n    mapping(address owner => bytes32 ipfs) names;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_conflict_2.sol",
    "content": "contract test {\n    mapping(address owner => address owner) owner;\n}\n// ----\n// DeclarationError 1809: (20-59): Conflicting parameter name \"owner\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_conflict_3.sol",
    "content": "contract test {\n    mapping(address owner => mapping(address owner => address owner)) owner;\n}\n// ----\n// DeclarationError 1809: (45-84): Conflicting parameter name \"owner\" in mapping.\n// DeclarationError 1809: (20-85): Conflicting parameter name \"owner\" in mapping.\n// DeclarationError 1809: (20-85): Conflicting parameter name \"owner\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_conflict_4.sol",
    "content": "contract test {\n    mapping(address owner => mapping(address owner => address hello)) world;\n}\n// ----\n// DeclarationError 1809: (20-85): Conflicting parameter name \"owner\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_conflict_5.sol",
    "content": "contract test {\n    mapping(address owner => mapping(address hello => address owner)) world;\n}\n// ----\n// DeclarationError 1809: (20-85): Conflicting parameter name \"owner\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_conflict_6.sol",
    "content": "contract test {\n    mapping(address hello => mapping(address owner => address owner)) world;\n}\n// ----\n// DeclarationError 1809: (45-84): Conflicting parameter name \"owner\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_param_1.sol",
    "content": "contract test {\n    function _main(mapping(uint name1 => uint name2) storage map) internal {\n        map[1] = 2;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_param_2.sol",
    "content": "contract test {\n    function _main(mapping(uint name1 => uint) storage map) internal {\n        map[1] = 2;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_param_3.sol",
    "content": "contract test {\n    function _main(mapping(uint => uint name2) storage map) internal {\n        map[1] = 2;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_param_4.sol",
    "content": "contract test {\n    function _main(mapping(uint name1 => mapping(uint name2 => uint name3) name4) storage map) internal {\n        map[1][2] = 3;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_param_5.sol",
    "content": "contract test {\n    function _main(mapping(uint name1 => uint[] name2) storage map) internal {\n        map[1].push(2);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_param_6.sol",
    "content": "contract test {\n    function _main(mapping(uint nameSame => mapping(uint name2 => mapping(uint nameSame => uint name3) name4) name5) storage map) internal {\n        map[1][2][3] = 4;\n    }\n}\n// ----\n// DeclarationError 1809: (35-132): Conflicting parameter name \"nameSame\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_param_7.sol",
    "content": "contract test {\n    function _main(mapping(uint name1 => mapping(uint name2 => mapping(uint name3 => uint name4) name5) name6) storage map) internal {\n        map[1][2][3] = 4;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_type_param_1.sol",
    "content": "contract test {\n    function(mapping(uint name1 => uint name2) storage) internal stateVariableName;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_type_param_2.sol",
    "content": "contract test {\n    function(mapping(uint name1 => uint) storage) internal stateVariableName;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_type_param_3.sol",
    "content": "contract test {\n    function(mapping(uint => uint name2) storage) internal stateVariableName;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_type_param_4.sol",
    "content": "contract test {\n    function(mapping(uint name1 => mapping(uint name2 => uint name3) name4) storage) internal stateVariableName;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_type_param_5.sol",
    "content": "contract test {\n    function(mapping(uint name1 => uint[] name2) storage) internal stateVariableName;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_type_param_6.sol",
    "content": "contract test {\n    function(mapping(uint nameSame => mapping(uint name2 => mapping(uint nameSame => uint name3) name4) name5) storage) internal stateVariableName;\n}\n// ----\n// DeclarationError 1809: (29-126): Conflicting parameter name \"nameSame\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_func_type_param_7.sol",
    "content": "contract test {\n    function(mapping(uint name1 => mapping(uint name2 => mapping(uint name3 => uint name4) name5) name6) storage) internal stateVariableName;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_local_1.sol",
    "content": "contract test {\n    mapping(uint name1 => uint name2) map;\n\n    function main() external {\n        mapping(uint name3 => uint name4) storage _map = map;\n        _map[1] = 2;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_local_2.sol",
    "content": "contract test {\n    mapping(uint name1 => uint) map;\n\n    function main() external {\n        mapping(uint => uint name4) storage _map = map;\n        _map[1] = 2;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_local_3.sol",
    "content": "contract test {\n    mapping(uint => uint name2) map;\n\n    function main() external {\n        mapping(uint name3 => uint) storage _map = map;\n        _map[1] = 2;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_local_4.sol",
    "content": "contract test {\n    mapping(uint name1 => mapping(uint name2 => uint name3) name4) map;\n\n    function main() external {\n        mapping(uint name5 => uint name6) storage _map = map[1];\n        _map[1] = 2;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_local_5.sol",
    "content": "contract test {\n    mapping(uint name1 => uint[] name4) map;\n\n    function main() external {\n        mapping(uint name5 => uint[] name6) storage _map = map;\n        _map[1].push(2);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_local_6.sol",
    "content": "contract test {\n    mapping(uint name1 => mapping(uint name2 => uint name3) name4) map;\n\n    function main() external {\n        mapping(uint nameSame => mapping(uint name2 => uint nameSame) name4) storage _map = map;\n        _map[1][2] = 3;\n    }\n}\n// ----\n// DeclarationError 1809: (128-196): Conflicting parameter name \"nameSame\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_local_7.sol",
    "content": "contract test {\n    mapping(uint nameSame => mapping(uint name1 => mapping(uint nameSame => uint name3) name6) name4) map;\n\n    function main() external {\n        mapping(uint nameSame => mapping(uint name1 => mapping(uint nameSame => uint name3) name6) name4) storage _map = map;\n        _map[1][2][3] = 4;\n    }\n}\n// ----\n// DeclarationError 1809: (20-117): Conflicting parameter name \"nameSame\" in mapping.\n// DeclarationError 1809: (163-260): Conflicting parameter name \"nameSame\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_local_8.sol",
    "content": "contract test {\n    mapping(uint name1 => mapping(uint name2 => mapping(uint name3 => uint name4) name5) name6) map;\n\n    function main() external {\n        mapping(uint name1 => mapping(uint name2 => mapping(uint name3 => uint name4) name5) name6) storage _map = map;\n        _map[1][2][3] = 4;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_nested_1.sol",
    "content": "contract test {\n    mapping(address owner => mapping(address spender => bytes32 note)) names;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_nested_2.sol",
    "content": "contract test {\n    mapping(address => mapping(address spender => bytes32 note)) names;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_nested_3.sol",
    "content": "contract test {\n    mapping(address owner => mapping(address => bytes32 note)) names;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_nested_4.sol",
    "content": "contract test {\n    mapping(address owner => mapping(address spender => bytes32)) names;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_nested_5.sol",
    "content": "contract test {\n    mapping(address owner => mapping(address spender => bytes32 note));\n}\n// ----\n// ParserError 2314: (86-87): Expected identifier but got ';'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_nested_6.sol",
    "content": "contract test {\n    mapping(uint nameSame => mapping(uint name1 => mapping(uint nameSame => uint name2) name3) name4) name5;\n}\n// ----\n// DeclarationError 1809: (20-117): Conflicting parameter name \"nameSame\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_nested_7.sol",
    "content": "contract test {\n    mapping(uint nameSame => mapping(uint name1 => mapping(uint nameSame => uint name3) name6) name4) public name5;\n}\n// ----\n// DeclarationError 1809: (20-117): Conflicting parameter name \"nameSame\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_nested_8.sol",
    "content": "contract test {\n    mapping(uint name1 => mapping(uint name2 => mapping(uint name3 => uint name4) name5) name6) public name7;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_struct_member_1.sol",
    "content": "contract test {\n    struct Person {\n        mapping(uint phone => uint calls) friends;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_struct_member_2.sol",
    "content": "contract test {\n    struct Person {\n        mapping(uint phone => uint) friends;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_struct_member_3.sol",
    "content": "contract test {\n    struct Person {\n        mapping(uint => uint calls) friends;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_struct_member_4.sol",
    "content": "contract test {\n    struct Person {\n        mapping(uint phone => mapping(uint call => uint time) callTimes) friends;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_struct_member_5.sol",
    "content": "contract test {\n    struct Person {\n        mapping(uint phone => uint[] calls) friends;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_struct_member_6.sol",
    "content": "contract test {\n    struct Person {\n        mapping(uint nameSame => mapping(uint name1 => mapping(uint nameSame => uint name2) name3) name4) name5;\n    }\n}\n// ----\n// DeclarationError 1809: (44-141): Conflicting parameter name \"nameSame\" in mapping.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/mapping_with_names_struct_member_7.sol",
    "content": "contract test {\n    struct Person {\n        mapping(uint name1 => mapping(uint name2 => mapping(uint name3 => uint name4) name5) name6) name7;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/max_depth_reached_1.sol",
    "content": "contract C {\n    bytes\n    [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ // 100*[\n    [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n    [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [\n....\n// ----\n// ParserError 7319: (287-288): Maximum recursion depth reached during parsing.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/max_depth_reached_2.sol",
    "content": "contract C {\n    function f() {\n        {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ // 100*{\n        {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{\n        {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{\n        {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{\n        {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{\n        {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ {\n....\n// ----\n// ParserError 7319: (693-694): Maximum recursion depth reached during parsing.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/max_depth_reached_3.sol",
    "content": "contract C {\n    function f() {\n        uint x = f\n        (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( // 100*(\n        ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((\n        (((((((((((((((((((((((((((((((((((((( (\n....\n// ----\n// ParserError 7319: (325-326): Maximum recursion depth reached during parsing.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/max_depth_reached_4.sol",
    "content": "contract C {\n    function f() public pure {\n        uint ok = 0;\n        uint nok = 0;\n\n        (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-(\n        ( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (\n        (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-(\n        ( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (\n        (-( (-( (-( (-( (-( (-( (-( (-( (\n        ok++\n        )))))))))))))))))\n        ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))\n        ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));\n\n        ( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (\n        (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-(\n        ( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (\n        (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-( (-(\n        ( (-( (-( (-( (-( (-( (-( (-( (-( (\n        nok++\n        ))))))))))))))))))\n        ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))\n        ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));\n    }\n}\n// ----\n// ParserError 7319: (1305-1308): Maximum recursion depth reached during parsing.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/missing_argument_in_named_args.sol",
    "content": "contract test {\n\tfunction a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n\tfunction b() returns (uint r) { r = a({a: , b: , c: }); }\n}\n// ----\n// ParserError 6933: (146-147): Expected primary expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/missing_parameter_name_in_named_args.sol",
    "content": "contract test {\n\tfunction a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n\tfunction b() returns (uint r) { r = a({: 1, : 2, : 3}); }\n}\n// ----\n// ParserError 2314: (143-144): Expected identifier but got ':'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol",
    "content": "contract test {\n    uint256 ;\n}\n// ----\n// ParserError 2314: (28-29): Expected identifier but got ';'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/modifier.sol",
    "content": "contract c {\n    modifier mod { if (msg.sender == 0x0000000000000000000000000000000000000000) _; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/modifier_arguments.sol",
    "content": "contract c {\n    modifier mod(address a) { if (msg.sender == a) _; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/modifier_invocation.sol",
    "content": "contract c {\n    modifier mod1(uint a) { if (msg.sender == address(uint160(a))) _; }\n    modifier mod2 { if (msg.sender == address(2)) _; }\n    function f() public mod1(7) mod2 { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/modifier_without_semicolon.sol",
    "content": "contract c {\n\tmodifier mod { if (msg.sender == 0) _ }\n}\n// ----\n// ParserError 2314: (52-53): Expected ';' but got '}'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/multi_arrays.sol",
    "content": "contract c {\n    mapping(uint => mapping(uint => int8)[8][][9])[] x;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/multi_variable_declarations.sol",
    "content": "contract C {\n\tfunction f() pure public {\n\t\t(uint a, uint b, uint c) = g();\n\t\t(uint d) = 2;\n\t\t(, uint e) = (3,4);\n\t\t(uint h,) = (4,5);\n\t\t(uint x,,) = g();\n\t\t(, uint y,) = g();\n        a; b; c; d; e; h; x; y;\n\t}\n\tfunction g() pure public returns (uint, uint, uint) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/multiple_event_arg_trailing_comma.sol",
    "content": "contract test {\n    event Test(uint a, uint b,);\n    function(uint a) {}\n}\n// ----\n// ParserError 7591: (45-46): Unexpected trailing comma in parameter list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/multiple_function_param_trailing_comma.sol",
    "content": "contract test {\n\tfunction(uint a, uint b,) {}\n}\n// ----\n// ParserError 7591: (40-41): Unexpected trailing comma in parameter list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/multiple_functions_natspec_documentation.sol",
    "content": "contract test {\n    uint256 stateVar;\n    /// This is test function 1\n    function functionName1(bytes32 input) public returns (bytes32 out) {}\n    /// This is test function 2\n    function functionName2(bytes32 input) public returns (bytes32 out) {}\n    // nothing to see here\n    function functionName3(bytes32 input) public returns (bytes32 out) {}\n    /// This is test function 4\n    function functionName4(bytes32 input) public returns (bytes32 out) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/multiple_modifier_arg_trailing_comma.sol",
    "content": "contract test {\n    modifier modTest(uint a, uint b,) { _; }\n    function(uint a) {}\n}\n// ----\n// ParserError 7591: (51-52): Unexpected trailing comma in parameter list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/multiple_modifier_overrides.sol",
    "content": "contract C {\n    modifier f() override override {}\n}\n// ----\n// ParserError 9102: (39-47): Override already specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/multiple_mutability_specifiers.sol",
    "content": "contract C {\n    uint constant constant a;\n    uint immutable immutable b;\n    uint constant immutable c;\n    uint immutable constant d;\n}\n// ----\n// ParserError 3109: (31-39): Mutability already set to \"constant\"\n// ParserError 3109: (62-71): Mutability already set to \"immutable\"\n// ParserError 3109: (93-102): Mutability already set to \"constant\"\n// ParserError 3109: (125-133): Mutability already set to \"immutable\"\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/multiple_return_param_trailing_comma.sol",
    "content": "contract test {\n    function() returns (uint a, uint b,) {}\n}\n// ----\n// ParserError 7591: (54-55): Unexpected trailing comma in parameter list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/multiple_state_mutability_specifiers.sol",
    "content": "==== Source: A ====\ncontract c1 {\n    function f() payable payable {}\n}\ncontract c2 {\n    function f() view view {}\n}\ncontract c3 {\n    function f() pure pure {}\n}\ncontract c4 {\n    function f() pure view {}\n}\ncontract c5 {\n    function f() payable view {}\n}\ncontract c6 {\n    function f() pure payable {}\n}\ncontract c7 {\n    function f() view payable {}\n}\ncontract c8 {\n    function f() payable pure {}\n}\ncontract c9 {\n    function f() view pure {}\n}\n==== Source: B ====\ncontract c {\n    address payable payable v;\n}\n==== Source: C ====\ncontract c {\n    function fn(address payable payable) public { }\n}\n==== Source: D ====\ncontract c {\n    function fn() public returns (address payable payable) { }\n}\n==== Source: E ====\ncontract c {\n    function fn() public {\n        address payable payable v;\n    }\n}\n==== Source: F ====\ncontract c {\n    function fn(address payable payable v) public { }\n}\n==== Source: G ====\ncontract c {\n    function fn() public returns (address payable payable res) { }\n}\n==== Source: H ====\naddress payable payable v;\n==== Source: I ====\ncontract c {\n    modifier m(address payable payable x)  { _; }\n}\n==== Source: J ====\ncontract c {\n    event e(address payable payable x);\n}\n==== Source: K ====\ncontract c {\n    error e1(address payable payable x);\n}\n==== Source: L ====\ncontract c {\n    function f() public returns (address payable) {\n        try this.f() returns (address payable payable) { } catch { }\n    }\n}\n==== Source: M ====\ncontract c {\n    function f() public returns (address payable) {\n        try this.f() returns (address payable) { } catch Error(address payable payable) { }\n    }\n}\n// ----\n// ParserError 9680: (A:39-46): State mutability already specified as \"payable\".\n// ParserError 9680: (A:88-92): State mutability already specified as \"view\".\n// ParserError 9680: (A:134-138): State mutability already specified as \"pure\".\n// ParserError 9680: (A:180-184): State mutability already specified as \"pure\".\n// ParserError 9680: (A:229-233): State mutability already specified as \"payable\".\n// ParserError 9680: (A:275-282): State mutability already specified as \"pure\".\n// ParserError 9680: (A:324-331): State mutability already specified as \"view\".\n// ParserError 9680: (A:376-380): State mutability already specified as \"payable\".\n// ParserError 9680: (A:422-426): State mutability already specified as \"view\".\n// ParserError 2314: (B:33-40): Expected identifier but got 'payable'\n// ParserError 2314: (C:45-52): Expected ',' but got 'payable'\n// ParserError 2314: (D:63-70): Expected ',' but got 'payable'\n// ParserError 2314: (E:64-71): Expected identifier but got 'payable'\n// ParserError 2314: (F:45-52): Expected ',' but got 'payable'\n// ParserError 2314: (G:63-70): Expected ',' but got 'payable'\n// ParserError 2314: (H:16-23): Expected identifier but got 'payable'\n// ParserError 2314: (I:44-51): Expected ',' but got 'payable'\n// ParserError 2314: (J:41-48): Expected ',' but got 'payable'\n// ParserError 2314: (K:42-49): Expected ',' but got 'payable'\n// ParserError 2314: (L:111-118): Expected ',' but got 'payable'\n// ParserError 2314: (M:144-151): Expected ',' but got 'payable'\n\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/new_address_payable.sol",
    "content": "contract C {\n    function f() public pure returns(address payable[] memory m) {\n        m = new address payable[](10);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/new_invalid_type_name.sol",
    "content": "contract C {\n\tfunction f() {\n\t\tnew var;\n\t}\n}\n// ----\n// ParserError 3546: (35-38): Expected type name\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/no_function_params.sol",
    "content": "contract test {\n\tuint256 stateVar;\n\tfunction functionName() public {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/overloaded_functions.sol",
    "content": "contract test {\n\tfunction fun(uint a) public returns(uint r) { return a; }\n\tfunction fun(uint a, uint b) public returns(uint r) { return a + b; }\n}\n// ----\n// Warning 2018: (17-74): Function state mutability can be restricted to pure\n// Warning 2018: (76-145): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/payable_without_arguments.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\taddress payable q = payable;\n\t}\n}\n// ----\n// ParserError 2314: (70-71): Expected '(' but got ';'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/placeholder_in_function_context.sol",
    "content": "contract c {\n    function fun() public returns (uint r) {\n        uint _ = 8;\n        return _ + 1;\n    }\n}\n// ----\n// DeclarationError 3726: (66-72): The name \"_\" is reserved.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/pragma_illegal.sol",
    "content": "pragma ``;\n// ----\n// ParserError 6281: (7-8): Token incompatible with Solidity parser as part of pragma directive.\n// ParserError 6281: (8-9): Token incompatible with Solidity parser as part of pragma directive.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/scientific_notation.sol",
    "content": "contract test {\n\tuint256 a = 2e10;\n\tuint256 b = 2E10;\n\tuint256 c = 200e-2;\n\tuint256 d = 2E10 wei;\n\tuint256 e = 2.5e10;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/single_event_arg_trailing_comma.sol",
    "content": "contract test {\n\tevent Test(uint a,);\n\tfunction(uint a) {}\n}\n// ----\n// ParserError 7591: (34-35): Unexpected trailing comma in parameter list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/single_function_param.sol",
    "content": "contract test {\n\tuint256 stateVar;\n\tfunction functionName(bytes32 input) public returns (bytes32 out) {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/single_function_param_trailing_comma.sol",
    "content": "contract test {\n\tfunction(uint a,) {}\n}\n// ----\n// ParserError 7591: (32-33): Unexpected trailing comma in parameter list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/single_modifier_arg_trailing_comma.sol",
    "content": "contract test {\n\tmodifier modTest(uint a,) { _; }\n\tfunction(uint a) {}\n}\n// ----\n// ParserError 7591: (40-41): Unexpected trailing comma in parameter list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/single_return_param_trailing_comma.sol",
    "content": "contract test {\n\tfunction() returns (uint a,) {}\n}\n// ----\n// ParserError 7591: (43-44): Unexpected trailing comma in parameter list.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/smoke_test.sol",
    "content": "contract test {\n    uint256 stateVariable1;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/struct_definition.sol",
    "content": "contract test {\n    uint256 stateVar;\n    struct MyStructName {\n        address addr;\n        uint256 count;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/trailing_comma_in_named_args.sol",
    "content": "contract test {\n\tfunction a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n\tfunction b() returns (uint r) { r = a({a: 1, b: 2, c: 3, }); }\n}\n// ----\n// ParserError 2074: (159-160): Unexpected trailing comma.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/trailing_dot1.sol",
    "content": "contract test {\n\tuint256 a = 2.2e10;\n\tuint256 b = .5E10;\n\tuint256 c = 4.e-2;\n}\n// ----\n// TypeError 9582: (70-73): Member \"e\" not found or not visible after argument-dependent lookup in int_const 4.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/trailing_dot2.sol",
    "content": "contract test {\n\tuint256 a = 2.2e10;\n\tuint256 b = .5E10;\n\tuint256 c = 2 + 2.;\n}\n// ----\n// ParserError 2314: (76-77): Expected identifier but got ';'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/trailing_dot3.sol",
    "content": "contract test {\n\tuint a = 2.\n// ----\n// ParserError 2314: (29-29): Expected identifier but got end of source\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/tuples.sol",
    "content": "contract C {\n\tfunction f() public pure {\n\t\tuint a = (1);\n\t\t(uint b,) = (1,2);\n\t\t(uint c, uint d) = (1, 2 + a);\n\t\t(uint e,) = (1, b);\n\t\t(a) = 3;\n\t\ta;b;c;d;e;\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/tuples_decl_without_rhs.sol",
    "content": "contract C {\n    function f() public pure {\n        (uint a, uint b, uint c);\n    }\n}\n// ----\n// ParserError 2314: (76-77): Expected '=' but got ';'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/tuples_without_commas.sol",
    "content": "contract C {\n\tfunction f() {\n\t\tuint a = (2 2);\n\t}\n}\n// ----\n// ParserError 2314: (43-44): Expected ',' but got 'Number'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/two_exact_functions.sol",
    "content": "// with support of overloaded functions, during parsing,\n// we can't determine whether they match exactly, however\n// it will throw DeclarationError in following stage.\ncontract test {\n    function fun(uint a) public returns(uint r) { return a; }\n    function fun(uint a) public returns(uint r) { return a; }\n}\n// ----\n// DeclarationError 1686: (189-246): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/unary_plus_expression.sol",
    "content": "contract test {\n    function f(uint x) pure public {\n        uint y = +x;\n        y;\n    }\n}\n// ----\n// ParserError 9636: (70-71): Use of unary + is disallowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/unexpected.sol",
    "content": "unexpected\n// ----\n// ParserError 7858: (0-10): Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/user_defined_value_type.sol",
    "content": "type MyInt is uint;\n\ncontract C {\n    type MyAddress is address;\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/user_defined_value_type_err.sol",
    "content": "type(MyInt) is uint256;\n// ----\n// ParserError 2314: (4-5): Expected identifier but got '('\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/user_defined_value_type_in_function_err.sol",
    "content": "function f() {\n    type(uint).max;\n    type MyInt is int;\n}\n// ----\n// ParserError 2314: (44-49): Expected ';' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/var_array.sol",
    "content": "contract Foo {\n\tfunction f() { var[] a; }\n}\n// ----\n// ParserError 6933: (31-34): Expected primary expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/var_storage_var.sol",
    "content": "contract C {\n    var a;\n}\n// ----\n// ParserError 9182: (17-20): Function, variable, struct or modifier declaration expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/variable_definition_in_mapping.sol",
    "content": "contract test {\n\tfunction fun() {\n\t\tmapping(var=>bytes32) d;\n\t}\n}\n// ----\n// ParserError 1005: (44-47): Expected elementary type name or identifier for mapping key type\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/visibility_specifiers.sol",
    "content": "contract c {\n    uint private a;\n    uint internal b;\n    uint public c;\n    uint d;\n    function f() public {}\n    function f_priv() private {}\n    function f_internal() internal {}\n}\n// ----\n// Warning 2519: (58-71): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/while_loop.sol",
    "content": "contract test {\n    function fun() public pure {\n        uint256 x;\n        while (true) { x = 1; break; continue; } x = 9;\n    }\n}\n// ----\n// Warning 5740: (105-113): Unreachable code.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/wrong_compiler_1.sol",
    "content": "pragma solidity ^99.99.0;\n// ----\n// ParserError 5333: (0-25): Source file requires different compiler version (current compiler is ....\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/wrong_compiler_2.sol",
    "content": "pragma solidity ^99.99.0;\nthis is surely invalid\n// ----\n// ParserError 5333: (0-25): Source file requires different compiler version (current compiler is ....\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/wrong_compiler_3.sol",
    "content": "pragma solidity ^99.99.0;\ncontract C {\n    uint ;\n}\n// ----\n// ParserError 5333: (0-25): Source file requires different compiler version (current compiler is ....\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/parsing/wrong_compiler_4.sol",
    "content": "pragma solidity ^99.99.0;\ncontract C {\n    function f() {}\n}\n// ----\n// ParserError 5333: (0-25): Source file requires different compiler version (current compiler is ....\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/blank_space_version.sol",
    "content": "pragma solidity ;\n// ----\n// ParserError 1684: (0-17): Invalid version pragma. Empty version pragma.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/broken_version_1.sol",
    "content": "pragma solidity ^0^1;\n// ----\n// ParserError 5333: (0-21): Source file requires different compiler version (current compiler is ....\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/broken_version_2.sol",
    "content": "pragma solidity pragma;\n// ----\n// ParserError 1684: (0-23): Invalid version pragma. Expected the start of a version number but instead found character 'p'. Version number is invalid or the pragma is not terminated with a semicolon.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/broken_version_3.sol",
    "content": "pragma solidity #8.0.0;\n// ----\n// ParserError 6281: (16-17): Token incompatible with Solidity parser as part of pragma directive.\n// ParserError 5333: (0-23): Source file requires different compiler version (current compiler is ....\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/broken_version_4.sol",
    "content": "pragma solidity (8.0.0);\n// ----\n// ParserError 1684: (0-24): Invalid version pragma. Expected the start of a version number but instead found character '('. Version number is invalid or the pragma is not terminated with a semicolon.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/broken_version_5.sol",
    "content": "pragma solidity 88_;\n// ----\n// ParserError 1684: (0-20): Invalid version pragma. Expected the start of a version number but instead found character '_'. Version number is invalid or the pragma is not terminated with a semicolon.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/broken_version_6.sol",
    "content": "pragma solidity v1.2.3;\n// ----\n// ParserError 1684: (0-23): Invalid version pragma. Expected the start of a version number but instead found character 'v'. Version number is invalid or the pragma is not terminated with a semicolon.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/broken_version_7.sol",
    "content": "pragma solidity >0.5.0<;\n// ----\n// ParserError 1684: (0-24): Invalid version pragma. Expected version number but reached end of pragma.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/empty_version.sol",
    "content": "pragma solidity;\n// ----\n// ParserError 1684: (0-16): Invalid version pragma. Empty version pragma.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/experimental_empty_string_literal.sol",
    "content": "pragma experimental \"\";\n// ----\n// SyntaxError 3250: (0-23): Empty experimental feature name is invalid.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/experimental_multiple_experimental.sol",
    "content": "pragma experimental experimental __test;\n// ----\n// SyntaxError 6022: (0-40): Stray arguments.\n\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/experimental_multiple_same_line.sol",
    "content": "pragma experimental unsupportedName unsupportedName;\n// ----\n// SyntaxError 6022: (0-52): Stray arguments.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/experimental_pragma_duplicate.sol",
    "content": "pragma experimental __test;\npragma experimental __test;\n// ====\n// experimental: true\n// ----\n// Warning 2264: (0-27): Experimental features are turned on. Do not use experimental features on live deployments.\n// SyntaxError 1231: (28-55): Duplicate experimental feature name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/experimental_pragma_empty.sol",
    "content": "pragma experimental;\n// ----\n// SyntaxError 9679: (0-20): Experimental feature name is missing.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/experimental_pragma_unknown_string_literal.sol",
    "content": "pragma experimental unsupportedName;\n// ----\n// SyntaxError 8491: (0-36): Unsupported experimental feature name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/experimental_pragma_without_experimental_mode.sol",
    "content": "pragma experimental __test;\npragma experimental solidity;\n// ====\n// EVMVersion: >=constantinople\n// ----\n// SyntaxError 2816: (0-27): Experimental pragmas can only be used if experimental mode is enabled. To enable experimental mode, use the --experimental flag.\n// SyntaxError 2816: (28-57): Experimental pragmas can only be used if experimental mode is enabled. To enable experimental mode, use the --experimental flag.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/experimental_test_warning.sol",
    "content": "pragma experimental __test;\n// ====\n// experimental: true\n// ----\n// Warning 2264: (0-27): Experimental features are turned on. Do not use experimental features on live deployments.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/experimental_unknown_number_literal.sol",
    "content": "pragma experimental 123;\n// ----\n// SyntaxError 8491: (0-24): Unsupported experimental feature name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/experimental_unknown_quoted_string_literal.sol",
    "content": "pragma experimental \"unsupportedName\";\n// ----\n// SyntaxError 8491: (0-38): Unsupported experimental feature name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/invalid_pragma.sol",
    "content": "pragma 0;\n// ----\n// SyntaxError 5226: (0-9): Invalid pragma \"0\"\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/invalid_range_conjunction_range_first.sol",
    "content": "pragma solidity 0.4.1 - 0.6.2 0.8.17;\n// ----\n// ParserError 1684: (0-37): Invalid version pragma. You can only combine version ranges using the || operator.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/invalid_range_conjunction_range_second.sol",
    "content": "pragma solidity 0.8.17 0.4.1 - 0.6.2;\n// ----\n// ParserError 1684: (0-37): Invalid version pragma. Expected the start of a version number but instead found character '-'. Version number is invalid or the pragma is not terminated with a semicolon.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/invalid_range_conjunction_two_ranges.sol",
    "content": "pragma solidity 0.4.0 - 0.4.1 0.4.1 - 0.6.2;\n// ----\n// ParserError 1684: (0-44): Invalid version pragma. You can only combine version ranges using the || operator.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/unknown_pragma.sol",
    "content": "pragma thisdoesntexist;\n// ----\n// SyntaxError 4936: (0-23): Unknown pragma \"thisdoesntexist\"\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/unterminated_pragma.sol",
    "content": "pragma solidity 0.4.3\n// ----\n// ParserError 2314: (22-22): Expected ';' but got end of source\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/unterminated_version.sol",
    "content": "pragma solidity 0.4.3\npragma abicoder v2;\n// ----\n// ParserError 1684: (0-41): Invalid version pragma. Expected the start of a version number but instead found character 'p'. Version number is invalid or the pragma is not terminated with a semicolon.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/valid_range_disjunction_range_second.sol",
    "content": "pragma solidity 0.8.17 || 0.4.1 - 0.9.0;\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/valid_range_disjunction_two_ranges.sol",
    "content": "pragma solidity 0.4.0 - 0.9.0 || 0.4.1 - 0.6.2;\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/version_check.sol",
    "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity < 142857;\npragma solidity >= 0.0;\npragma solidity >= 0.0.0;\n\ncontract C {\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/version_number_too_large.sol",
    "content": "pragma solidity 4294967296;\n// ----\n// ParserError 1684: (0-27): Invalid version pragma. Integer too large to be used in a version number.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/pragma/version_range.sol",
    "content": "pragma solidity >=0.4.0 <0.9.0;\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/receiveEther/arguments.sol",
    "content": "contract C {\n    receive(uint256) external payable {}\n}\n// ----\n// DeclarationError 6857: (24-33): Receive ether function cannot take parameters.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/receiveEther/default_visibility.sol",
    "content": "contract C {\n    // Check that visibility is also enforced for the receive ether function.\n    receive() {}\n}\n// ----\n// SyntaxError 4937: (95-107): No visibility specified. Did you intend to add \"external\"?\n// DeclarationError 7793: (95-107): Receive ether function must be payable, but is \"nonpayable\".\n// DeclarationError 4095: (95-107): Receive ether function must be defined as \"external\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/receiveEther/msg_data_in_receive.sol",
    "content": "contract C {\n    receive() external payable { msg.data; }\n}\n// ----\n// TypeError 7139: (46-54): \"msg.data\" cannot be used inside of \"receive\" function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/receiveEther/old_syntax.sol",
    "content": "contract C {\n    function() external payable {}\n}\n// ----\n// ParserError 2915: (45-46): Expected a state variable declaration. If you intended this as a fallback function or a function to handle plain ether transactions, use the \"fallback\" keyword or the \"receive\" keyword instead.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/receiveEther/pure_modifier.sol",
    "content": "contract C {\n    uint x;\n    receive() external pure { x = 2; }\n}\n// ----\n// DeclarationError 7793: (29-63): Receive ether function must be payable, but is \"pure\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/receiveEther/receive_as_function_name.sol",
    "content": "contract C {\n    function receive() external pure {}\n}\n// ----\n// Warning 3445: (26-33): This function is named \"receive\" but is not the receive function of the contract. If you intend this to be a receive function, use \"receive(...) { ... }\" without the \"function\" keyword to define it.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/receiveEther/return_value.sol",
    "content": "contract C {\n    receive() external returns (uint256) {}\n}\n// ----\n// DeclarationError 7793: (17-56): Receive ether function must be payable, but is \"nonpayable\".\n// DeclarationError 6899: (44-53): Receive ether function cannot return values.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/receiveEther/view_modifier.sol",
    "content": "contract C {\n    uint x;\n    receive() external view { x = 2; }\n}\n// ----\n// DeclarationError 7793: (29-63): Receive ether function must be payable, but is \"view\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/returnExpressions/single_return_mismatching_number.sol",
    "content": "contract C\n{\n    function f() public pure returns (uint)\n    {\n        return;\n    }\n    function g() public pure returns (uint)\n    {\n        return (1, 2);\n    }\n}\n// ----\n// TypeError 6777: (71-78): Return arguments required.\n// TypeError 5132: (143-156): Different number of arguments in return statement than in returns declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/returnExpressions/single_return_mismatching_number_named.sol",
    "content": "contract C\n{\n    function f() public pure returns (uint a)\n    {\n        return;\n    }\n    function g() public pure returns (uint a)\n    {\n        return (1, 2);\n    }\n}\n// ----\n// TypeError 6777: (73-80): Return arguments required.\n// TypeError 5132: (147-160): Different number of arguments in return statement than in returns declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/returnExpressions/single_return_mismatching_type.sol",
    "content": "contract C\n{\n    function g() public pure returns (uint)\n    {\n        return \"string\";\n    }\n}\n// ----\n// TypeError 6359: (78-86): Return argument type literal_string \"string\" is not implicitly convertible to expected type (type of first return variable) uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/returnExpressions/tuple_return_mismatching_number.sol",
    "content": "contract C\n{\n    function f() public pure returns (uint, uint)\n    {\n        return 1;\n    }\n    function g() public pure returns (uint, uint)\n    {\n        return (1, 2, 3);\n    }\n    function h() public pure returns (uint, uint)\n    {\n        return;\n    }\n}\n// ----\n// TypeError 8863: (77-85): Different number of arguments in return statement than in returns declaration.\n// TypeError 5132: (157-173): Different number of arguments in return statement than in returns declaration.\n// TypeError 6777: (245-252): Return arguments required.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/returnExpressions/tuple_return_mismatching_number_named.sol",
    "content": "contract C\n{\n    function f() public pure returns (uint a, uint b)\n    {\n        return 1;\n    }\n    function g() public pure returns (uint a, uint b)\n    {\n        return (1, 2, 3);\n    }\n    function h() public pure returns (uint a, uint b)\n    {\n        return;\n    }\n}\n// ----\n// TypeError 8863: (81-89): Different number of arguments in return statement than in returns declaration.\n// TypeError 5132: (165-181): Different number of arguments in return statement than in returns declaration.\n// TypeError 6777: (257-264): Return arguments required.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/returnExpressions/valid_returns.sol",
    "content": "contract C\n{\n    function f() public pure {\n        return;\n    }\n    function g() public pure returns (uint) {\n        return 1;\n    }\n    function h() public pure returns (uint a) {\n        return 1;\n    }\n    function i() public pure returns (uint, uint) {\n        return (1, 2);\n    }\n    function j() public pure returns (uint a, uint b) {\n        return (1, 2);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/at_file_level.sol",
    "content": "revert X();\n// ----\n// ParserError 2314: (8-9): Expected ';' but got '('\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/error_used_elsewhere.sol",
    "content": "error E();\nfunction f() pure {\n    E();\n}\n// ----\n// TypeError 7757: (35-38): Errors can only be used with revert statements: \"revert MyError(args);\", or require functions: \"require(condition, MyError(args))\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/in_global_function.sol",
    "content": "error E();\nfunction f() pure {\n    revert E();\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/non_called.sol",
    "content": "error E();\nfunction f() public pure {\n    revert E;\n}\n// ----\n// ParserError 2314: (50-51): Expected '(' but got ';'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/non_error.sol",
    "content": "function f() public pure {\n    revert 1;\n}\n// ----\n// ParserError 2314: (38-39): Expected ';' but got 'Number'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/regular.sol",
    "content": "error E();\ncontract C {\n    function f() public pure {\n        revert E();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/require_nested.sol",
    "content": "error Error(uint256);\n\ncontract C\n{\n    error OtherError(uint256);\n\n    function f() external pure\n    {\n        revert Error(require(false, OtherError(1)));\n    }\n}\n// ----\n// TypeError 9553: (126-155): Invalid type for argument in function call. Invalid implicit conversion from tuple() to uint256 requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/revert_event.sol",
    "content": "contract C {\n    event E();\n    function f() public pure {\n        revert E();\n    }\n}\n// ----\n// TypeError 1885: (74-75): Expression has to be an error.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/revert_revert.sol",
    "content": "error revert();\ncontract C {\n    function f() public pure {\n        revert revert();\n    }\n}\n// ----\n// Warning 2319: (0-15): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/scoped.sol",
    "content": "contract A {\n    error E();\n}\ncontract C {\n    function f() public pure {\n        revert A.E();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/using_function.sol",
    "content": "error f(uint, uint);\ncontract C {\n    function f(uint) public {\n        revert f(10);\n    }\n}\n// ----\n// Warning 2519: (38-91): This declaration shadows an existing declaration.\n// TypeError 1885: (79-80): Expression has to be an error.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/revertStatement/using_struct.sol",
    "content": "struct S { uint x; }\ncontract C {\n    function f() public {\n        revert S(10);\n    }\n}\n// ----\n// TypeError 1885: (75-76): Expression has to be an error.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/access_in_assignment_dynamic_array.sol",
    "content": "contract C {\n    function f() public pure {\n        uint[] memory x = x[0];\n    }\n}\n// ----\n// DeclarationError 7576: (70-71): Undeclared identifier. \"x\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/access_in_assignment_struct.sol",
    "content": "contract C {\n    struct S { uint y; }\n    function f() public pure {\n        S memory x = x.y;\n    }\n}\n// ----\n// DeclarationError 7576: (90-91): Undeclared identifier. \"x\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/double_function_declaration.sol",
    "content": "contract test {\n    function fun() public { }\n    function fun() public { }\n}\n// ----\n// DeclarationError 1686: (20-45): Function with same name and parameter types defined twice.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/double_stateVariable_declaration.sol",
    "content": "contract test {\n\tuint256 variable;\n\tuint128 variable;\n}\n// ----\n// DeclarationError 2333: (36-52): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/double_variable_declaration.sol",
    "content": "contract test {\n\tfunction f() pure public {\n\t\tuint256 x;\n\t\tx = 1;\n\t\tif (true) { uint256 x; x = 2; }\n\t}\n}\n// ----\n// Warning 2519: (80-89): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol",
    "content": "contract test {\n    function f() pure public {\n        { uint x; }\n        { uint x; }\n    }\n}\n// ----\n// Warning 2072: (57-63): Unused local variable.\n// Warning 2072: (77-83): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol",
    "content": "contract test {\n    function f() pure public {\n        { uint x; }\n        uint x;\n    }\n}\n// ----\n// Warning 2519: (57-63): This declaration shadows an existing declaration.\n// Warning 2072: (57-63): Unused local variable.\n// Warning 2072: (75-81): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_and_disjoint_scope.sol",
    "content": "contract test {\n    function f() pure public {\n        uint x;\n        { uint x; }\n        uint x;\n    }\n}\n// ----\n// DeclarationError 2333: (91-97): Identifier already declared.\n// Warning 2519: (73-79): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_scope.sol",
    "content": "contract test {\n    function f() pure public {\n        uint x;\n        uint x;\n    }\n}\n// ----\n// DeclarationError 2333: (71-77): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/duplicate_contract.sol",
    "content": "contract X {}\ncontract X {}\n// ----\n// DeclarationError 2333: (14-27): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/external_library_function_inside_scope.sol",
    "content": "library L {\n    function externalFunction(uint) external pure {}\n    function f() public pure {\n        uint x;\n        externalFunction(x);\n    }\n}\n// ----\n// DeclarationError 7576: (120-136): Undeclared identifier. \"externalFunction\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/function_state_variable_conflict.sol",
    "content": "contract C {\n    function f(uint) public pure {}\n    uint public f = 0;\n}\n// ----\n// DeclarationError 2333: (53-70): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/library_inherited.sol",
    "content": "library Lib {\n    function foo(uint256 value) internal returns (uint256) {\n        return value + 42;\n    }\n}\n\ncontract A {\n    using Lib for uint256;\n}\n\ncontract B is A {\n    function bar(uint256 value) public returns (uint256) {\n        return value.foo(); // Usage of Lib\n    }\n}\n// ----\n// TypeError 9582: (246-255): Member \"foo\" not found or not visible after argument-dependent lookup in uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/library_inherited2.sol",
    "content": "library Lib {\n    function foo(uint256 value) internal pure returns (uint256) {\n        return value + 42;\n    }\n}\n\ncontract A {\n    using Lib for uint256;\n}\n\ncontract B is A {\n    using Lib for uint256;\n    function bar(uint256 value) public pure returns (uint256) {\n        return value.foo(); // Usage of Lib\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/missing_state_variable.sol",
    "content": "contract Scope {\n    function getStateVar() view public returns (uint stateVar) {\n        stateVar = Scope.stateVar; // should fail.\n    }\n}\n// ----\n// TypeError 9582: (101-115): Member \"stateVar\" not found or not visible after argument-dependent lookup in type(contract Scope).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_pseudo_shadowing.sol",
    "content": "contract test {\n    function e() external { }\n    function f() public pure { uint e; e = 0; }\n}\n// ----\n// Warning 8760: (77-83): This declaration has the same name as another declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_pseudo_shadowing2.sol",
    "content": "contract test {\n    function e() external { }\n    function f() public pure { uint e; e = 0; }\n    function e(int) external { }\n}\n// ----\n// Warning 8760: (77-83): This declaration has the same name as another declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_shadowing_function_parameter_name_vs_contract.sol",
    "content": "interface I {\n    function f(uint I) external;         // OK\n}\n\nlibrary L {\n    function f(uint L) public pure {}    // warning\n}\n\nabstract contract A {\n    function f(uint A) public pure {}    // warning\n    function g(uint A) public virtual;   // OK\n}\n\ncontract C {\n    function f(uint C) public pure {}    // warning\n}\n// ----\n// Warning 2519: (91-97): This declaration shadows an existing declaration.\n// Warning 2519: (168-174): This declaration shadows an existing declaration.\n// Warning 2519: (283-289): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_shadowing_function_parameter_vs_its_function.sol",
    "content": "contract C {\n    function f(uint f) pure public {}\n}\n// ----\n// Warning 2519: (28-34): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_shadowing_function_parameter_vs_struct_enum.sol",
    "content": "contract C {\n    enum EnumType {A, B, C}\n\n    struct StructType {\n        uint x;\n    }\n\n    function f(StructType memory StructType) external {}\n    function g(EnumType EnumType) external {}\n    function h(EnumType StructType, StructType memory EnumType) external {}\n\n    function z(EnumType e) external returns (uint EnumType) {}\n}\n// ----\n// Warning 2519: (104-132): This declaration shadows an existing declaration.\n// Warning 2519: (161-178): This declaration shadows an existing declaration.\n// Warning 2519: (207-226): This declaration shadows an existing declaration.\n// Warning 2519: (228-254): This declaration shadows an existing declaration.\n// Warning 2519: (314-327): This declaration shadows an existing declaration.\n// TypeError 5172: (104-114): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_shadowing_function_parameters_parameter_vs_struct_enum.sol",
    "content": "library C {\n    enum EnumType {A, B, C}\n\n    struct StructType {\n        uint x;\n    }\n\n    function f1(function (StructType memory StructType) external f) external {}\n    function f2(function (EnumType EnumType) external f) external {}\n    function f3(function (EnumType StructType, StructType memory EnumType) external f) external {}\n}\n// ----\n// Warning 6162: (114-142): Naming function type parameters is deprecated.\n// Warning 6162: (194-211): Naming function type parameters is deprecated.\n// Warning 6162: (263-282): Naming function type parameters is deprecated.\n// Warning 6162: (284-310): Naming function type parameters is deprecated.\n// Warning 2519: (114-142): This declaration shadows an existing declaration.\n// Warning 2519: (194-211): This declaration shadows an existing declaration.\n// Warning 2519: (263-282): This declaration shadows an existing declaration.\n// Warning 2519: (284-310): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_shadowing_function_return_parameter_vs_struct_enum.sol",
    "content": "contract C {\n    enum EnumType {A, B, C}\n\n    struct StructType {\n        uint x;\n    }\n\n    function f() external returns (StructType memory StructType) {}\n    function g() external returns (EnumType EnumType) {}\n    function h() external returns (EnumType StructType, StructType memory EnumType) {}\n\n    function z(uint EnumType) external returns (EnumType e) {}\n}\n// ----\n// Warning 2519: (124-152): This declaration shadows an existing declaration.\n// Warning 2519: (192-209): This declaration shadows an existing declaration.\n// Warning 2519: (249-268): This declaration shadows an existing declaration.\n// Warning 2519: (270-296): This declaration shadows an existing declaration.\n// Warning 2519: (317-330): This declaration shadows an existing declaration.\n// TypeError 5172: (124-134): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_shadowing_function_type_parameter.sol",
    "content": "contract C {\n    enum EnumType {A, B, C}\n\n    struct StructType {\n        uint x;\n    }\n\n    function (StructType memory StructType) external ext1;\n    function (EnumType EnumType) external ext2;\n    function (EnumType StructType, StructType memory EnumType) external ext3;\n}\n// ----\n// Warning 6162: (103-131): Naming function type parameters is deprecated.\n// Warning 6162: (162-179): Naming function type parameters is deprecated.\n// Warning 6162: (210-229): Naming function type parameters is deprecated.\n// Warning 6162: (231-257): Naming function type parameters is deprecated.\n// Warning 2519: (103-131): This declaration shadows an existing declaration.\n// Warning 2519: (162-179): This declaration shadows an existing declaration.\n// Warning 2519: (210-229): This declaration shadows an existing declaration.\n// Warning 2519: (231-257): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_shadowing_function_type_return_parameter.sol",
    "content": "contract C {\n    enum EnumType {A, B, C}\n\n    struct StructType {\n        uint x;\n    }\n\n    function () external returns (StructType memory StructType) ext1;\n    function () external returns (EnumType EnumType) ext2;\n    function () external returns (EnumType StructType, StructType memory EnumType) ext3;\n}\n// ----\n// SyntaxError 7304: (123-151): Return parameters in function types may not be named.\n// SyntaxError 7304: (193-210): Return parameters in function types may not be named.\n// SyntaxError 7304: (252-271): Return parameters in function types may not be named.\n// SyntaxError 7304: (273-299): Return parameters in function types may not be named.\n// Warning 2519: (123-151): This declaration shadows an existing declaration.\n// Warning 2519: (193-210): This declaration shadows an existing declaration.\n// Warning 2519: (252-271): This declaration shadows an existing declaration.\n// Warning 2519: (273-299): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_shadowing_local_variable_vs_free_function.sol",
    "content": "function e() {}\ncontract test {\n    function f() pure public { uint e; e = 0; }\n}\n// ----\n// Warning 2519: (63-69): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_shadowing_local_variable_vs_functions.sol",
    "content": "function e() {}\ncontract test {\n    function f() pure public { uint e; uint g; uint h; e = g = h = 0; }\n    function g() pure public {}\n}\nfunction h() {}\n// ----\n// Warning 2519: (63-69): This declaration shadows an existing declaration.\n// Warning 2519: (71-77): This declaration shadows an existing declaration.\n// Warning 2519: (79-85): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/name_shadowing_local_variable_vs_state_variable.sol",
    "content": "contract test {\n    uint256 variable;\n    function f() pure public { uint32 variable; variable = 2; }\n}\n// ----\n// Warning 2519: (69-84): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/poly_variable_declaration_same_scope.sol",
    "content": "contract test {\n    function f() pure public {\n        uint x;\n        uint x;\n        uint x;\n        uint x;\n        uint x;\n        uint x;\n    }\n}\n// ----\n// DeclarationError 2333: (71-77): Identifier already declared.\n// DeclarationError 2333: (87-93): Identifier already declared.\n// DeclarationError 2333: (103-109): Identifier already declared.\n// DeclarationError 2333: (119-125): Identifier already declared.\n// DeclarationError 2333: (135-141): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/scoping.sol",
    "content": "contract test {\n    function f() public {\n        {\n            uint256 x;\n        }\n        x = 2;\n    }\n}\n// ----\n// DeclarationError 7576: (93-94): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/scoping_activation.sol",
    "content": "contract test {\n    function f() pure public {\n        x = 3;\n        uint x;\n    }\n}\n// ----\n// DeclarationError 7576: (55-56): Undeclared identifier. \"x\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol",
    "content": "contract test {\n    function f() pure public {\n        x = 3;\n        uint x;\n    }\n}\n// ----\n// DeclarationError 7576: (55-56): Undeclared identifier. \"x\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/scoping_for.sol",
    "content": "contract test {\n    function f() pure public {\n        for (uint x = 0; x < 10; x ++){\n            x = 2;\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/scoping_for2.sol",
    "content": "contract test {\n    function f() pure public {\n        for (uint x = 0; x < 10; x ++)\n            x = 2;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/scoping_for3.sol",
    "content": "contract test {\n    function f() pure public {\n        for (uint x = 0; x < 10; x ++){\n            x = 2;\n        }\n        x = 4;\n    }\n}\n// ----\n// DeclarationError 7576: (124-125): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol",
    "content": "contract test {\n    function f() pure public {\n        for (;; y++){\n            uint y = 3;\n        }\n    }\n}\n// ----\n// DeclarationError 7576: (63-64): Undeclared identifier.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/scoping_old.sol",
    "content": "contract test {\n    function f() pure public {\n        x = 4;\n        uint256 x = 2;\n    }\n}\n// ----\n// DeclarationError 7576: (55-56): Undeclared identifier. \"x\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/scoping_self_use.sol",
    "content": "contract test {\n    function f() pure public {\n        uint a = a;\n    }\n}\n// ----\n// DeclarationError 7576: (64-65): Undeclared identifier. \"a\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/state_variable_function_conflict.sol",
    "content": "contract C {\n    uint public f = 0;\n    function f(uint) public pure {}\n}\n// ----\n// DeclarationError 2333: (40-71): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/scoping/state_variable_function_conflict_former_crash.sol",
    "content": "// This used to crash with some compiler versions.\ncontract SomeContract {\n\n  uint public balance = 0;\n\n  function balance(uint number) public {}\n\n  function doSomething() public {\n    balance(3);\n  }\n}\n// ----\n// DeclarationError 2333: (106-145): Identifier already declared.\n// TypeError 5704: (185-195): This expression is not callable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/shifts/shift_signed_rvalue.sol",
    "content": "contract C {\n    function f(int256 a, int256 b) public returns (int256) {\n        return a >> b;\n    }\n    function g(int256 a, int256 b) public returns (int256) {\n        return a >> (256 - b);\n    }\n}\n// ----\n// TypeError 2271: (89-95): Built-in binary operator >> cannot be applied to types int256 and int256.\n// TypeError 2271: (179-193): Built-in binary operator >> cannot be applied to types int256 and int256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large.sol",
    "content": "pragma abicoder v2;\n\ncontract test {\n    function f() public pure returns (string memory ret) {\n        // 27000 bytes long data\n        ret = \"........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................\";\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// bytecodeFormat: legacy\n// ----\n// Warning 5574: (21-27154): Contract code size is 27164 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low \"runs\" value!), turning off revert strings, or using libraries.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large_abiencoder_v1.sol",
    "content": "pragma abicoder v1;\n\ncontract test {\n    function f() public pure returns (string memory ret) {\n        // 27000 bytes long data\n        ret = \"........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................\";\n    }\n}\n// ====\n// EVMVersion: >=shanghai\n// bytecodeFormat: legacy\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// Warning 5574: (21-27154): Contract code size is 27205 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low \"runs\" value!), turning off revert strings, or using libraries.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large_byzantium.sol",
    "content": "contract test {\n    function f() public pure returns (string memory ret) {\n        // 27000 bytes long data\n        ret = \"........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................\";\n    }\n}\n// ====\n// EVMVersion: =byzantium\n// ----\n// Warning 5574: (0-27133): Contract code size is 27220 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low \"runs\" value!), turning off revert strings, or using libraries.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/bytecode_too_large_homestead.sol",
    "content": "contract test {\n    function f() public pure returns (string memory ret) {\n        // 27000 bytes long data\n        ret = \"........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................\";\n    }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/combined_too_large_paris.sol",
    "content": "contract A {\n    function f() public pure returns (string memory ret) {\n        // 27000 bytes long data\n        ret = \"........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................\";\n    }\n}\n\ncontract B is A {\n    function g() public pure returns (bool) {\n        return true;\n    }\n}\n\ncontract C is A {\n    function g() public pure returns (bool) {\n        return false;\n    }\n}\n\ncontract test {\n    constructor() {\n        new B();\n        new C();\n    }\n}\n// ====\n// EVMVersion: =paris\n// ----\n// Warning 5574: (0-27130): Contract code size is 27192 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low \"runs\" value!), turning off revert strings, or using libraries.\n// Warning 5574: (27132-27224): Contract code size is 27218 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low \"runs\" value!), turning off revert strings, or using libraries.\n// Warning 5574: (27226-27319): Contract code size is 27218 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low \"runs\" value!), turning off revert strings, or using libraries.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/combined_too_large_shanghai.sol",
    "content": "contract A {\n    function f() public pure returns (string memory ret) {\n        // 27000 bytes long data\n        ret = \"........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................\";\n    }\n}\n\ncontract B is A {\n    function g() public pure returns (bool) {\n        return true;\n    }\n}\n\ncontract C is A {\n    function g() public pure returns (bool) {\n        return false;\n    }\n}\n\ncontract test {\n    constructor() {\n        new B();\n        new C();\n    }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// Warning 5574: (0-27130): Contract code size is 27186 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low \"runs\" value!), turning off revert strings, or using libraries.\n// Warning 5574: (27132-27224): Contract code size is 27212 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low \"runs\" value!), turning off revert strings, or using libraries.\n// Warning 5574: (27226-27319): Contract code size is 27211 bytes and exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low \"runs\" value!), turning off revert strings, or using libraries.\n// Warning 3860: (27321-27398): Contract initcode size is 54616 bytes and exceeds 49152 bytes (a limit introduced in Shanghai). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low \"runs\" value!), turning off revert strings, or using libraries.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/eof/bytecode_too_large.sol",
    "content": "// TODO: Change to proper error when all optimizations implemented for EOF\npragma abicoder v2;\n\ncontract test {\n    function f() public pure returns (string memory ret) {\n        // 27000 bytes long data\n        ret = \"........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................\";\n    }\n}\n// ====\n// EVMVersion: >=cancun\n// bytecodeFormat: >=EOFv1\n// ----\n// CodeGenerationError 2703: (96-27229): Relative jump too far\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/initcode_too_large_paris.sol",
    "content": "contract A {\n    function f() public pure returns (string memory ret) {\n        // 20000 bytes long data\n        ret = \"................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................\";\n    }\n}\n\ncontract B is A {\n    function g() public pure returns (bool) {\n        return true;\n    }\n}\n\ncontract C is A {\n    function g() public pure returns (bool) {\n        return false;\n    }\n}\n\ncontract test {\n    constructor() {\n        new A();\n        new B();\n        new C();\n    }\n}\n// ====\n// EVMVersion: =paris\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/initcode_too_large_shanghai.sol",
    "content": "contract A {\n    function f() public pure returns (string memory ret) {\n        // 20000 bytes long data\n        ret = \"................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................\";\n    }\n}\n\ncontract B is A {\n    function g() public pure returns (bool) {\n        return true;\n    }\n}\n\ncontract C is A {\n    function g() public pure returns (bool) {\n        return false;\n    }\n}\n\ncontract test {\n    constructor() {\n        new A();\n        new B();\n        new C();\n    }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// Warning 3860: (20321-20415): Contract initcode size is 60879 bytes and exceeds 49152 bytes (a limit introduced in Shanghai). This contract may not be deployable on Mainnet. Consider enabling the optimizer (with a low \"runs\" value!), turning off revert strings, or using libraries.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/more_than_256_declarationerrors.sol",
    "content": "contract C {\n  function f() public {\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n    b = 5;\n  }\n}\n// ----\n// DeclarationError 7576: (41-42): Undeclared identifier.\n// DeclarationError 7576: (52-53): Undeclared identifier.\n// DeclarationError 7576: (63-64): Undeclared identifier.\n// DeclarationError 7576: (74-75): Undeclared identifier.\n// DeclarationError 7576: (85-86): Undeclared identifier.\n// DeclarationError 7576: (96-97): Undeclared identifier.\n// DeclarationError 7576: (107-108): Undeclared identifier.\n// DeclarationError 7576: (118-119): Undeclared identifier.\n// DeclarationError 7576: (129-130): Undeclared identifier.\n// DeclarationError 7576: (140-141): Undeclared identifier.\n// DeclarationError 7576: (151-152): Undeclared identifier.\n// DeclarationError 7576: (162-163): Undeclared identifier.\n// DeclarationError 7576: (173-174): Undeclared identifier.\n// DeclarationError 7576: (184-185): Undeclared identifier.\n// DeclarationError 7576: (195-196): Undeclared identifier.\n// DeclarationError 7576: (206-207): Undeclared identifier.\n// DeclarationError 7576: (217-218): Undeclared identifier.\n// DeclarationError 7576: (228-229): Undeclared identifier.\n// DeclarationError 7576: (239-240): Undeclared identifier.\n// DeclarationError 7576: (250-251): Undeclared identifier.\n// DeclarationError 7576: (261-262): Undeclared identifier.\n// DeclarationError 7576: (272-273): Undeclared identifier.\n// DeclarationError 7576: (283-284): Undeclared identifier.\n// DeclarationError 7576: (294-295): Undeclared identifier.\n// DeclarationError 7576: (305-306): Undeclared identifier.\n// DeclarationError 7576: (316-317): Undeclared identifier.\n// DeclarationError 7576: (327-328): Undeclared identifier.\n// DeclarationError 7576: (338-339): Undeclared identifier.\n// DeclarationError 7576: (349-350): Undeclared identifier.\n// DeclarationError 7576: (360-361): Undeclared identifier.\n// DeclarationError 7576: (371-372): Undeclared identifier.\n// DeclarationError 7576: (382-383): Undeclared identifier.\n// DeclarationError 7576: (393-394): Undeclared identifier.\n// DeclarationError 7576: (404-405): Undeclared identifier.\n// DeclarationError 7576: (415-416): Undeclared identifier.\n// DeclarationError 7576: (426-427): Undeclared identifier.\n// DeclarationError 7576: (437-438): Undeclared identifier.\n// DeclarationError 7576: (448-449): Undeclared identifier.\n// DeclarationError 7576: (459-460): Undeclared identifier.\n// DeclarationError 7576: (470-471): Undeclared identifier.\n// DeclarationError 7576: (481-482): Undeclared identifier.\n// DeclarationError 7576: (492-493): Undeclared identifier.\n// DeclarationError 7576: (503-504): Undeclared identifier.\n// DeclarationError 7576: (514-515): Undeclared identifier.\n// DeclarationError 7576: (525-526): Undeclared identifier.\n// DeclarationError 7576: (536-537): Undeclared identifier.\n// DeclarationError 7576: (547-548): Undeclared identifier.\n// DeclarationError 7576: (558-559): Undeclared identifier.\n// DeclarationError 7576: (569-570): Undeclared identifier.\n// DeclarationError 7576: (580-581): Undeclared identifier.\n// DeclarationError 7576: (591-592): Undeclared identifier.\n// DeclarationError 7576: (602-603): Undeclared identifier.\n// DeclarationError 7576: (613-614): Undeclared identifier.\n// DeclarationError 7576: (624-625): Undeclared identifier.\n// DeclarationError 7576: (635-636): Undeclared identifier.\n// DeclarationError 7576: (646-647): Undeclared identifier.\n// DeclarationError 7576: (657-658): Undeclared identifier.\n// DeclarationError 7576: (668-669): Undeclared identifier.\n// DeclarationError 7576: (679-680): Undeclared identifier.\n// DeclarationError 7576: (690-691): Undeclared identifier.\n// DeclarationError 7576: (701-702): Undeclared identifier.\n// DeclarationError 7576: (712-713): Undeclared identifier.\n// DeclarationError 7576: (723-724): Undeclared identifier.\n// DeclarationError 7576: (734-735): Undeclared identifier.\n// DeclarationError 7576: (745-746): Undeclared identifier.\n// DeclarationError 7576: (756-757): Undeclared identifier.\n// DeclarationError 7576: (767-768): Undeclared identifier.\n// DeclarationError 7576: (778-779): Undeclared identifier.\n// DeclarationError 7576: (789-790): Undeclared identifier.\n// DeclarationError 7576: (800-801): Undeclared identifier.\n// DeclarationError 7576: (811-812): Undeclared identifier.\n// DeclarationError 7576: (822-823): Undeclared identifier.\n// DeclarationError 7576: (833-834): Undeclared identifier.\n// DeclarationError 7576: (844-845): Undeclared identifier.\n// DeclarationError 7576: (855-856): Undeclared identifier.\n// DeclarationError 7576: (866-867): Undeclared identifier.\n// DeclarationError 7576: (877-878): Undeclared identifier.\n// DeclarationError 7576: (888-889): Undeclared identifier.\n// DeclarationError 7576: (899-900): Undeclared identifier.\n// DeclarationError 7576: (910-911): Undeclared identifier.\n// DeclarationError 7576: (921-922): Undeclared identifier.\n// DeclarationError 7576: (932-933): Undeclared identifier.\n// DeclarationError 7576: (943-944): Undeclared identifier.\n// DeclarationError 7576: (954-955): Undeclared identifier.\n// DeclarationError 7576: (965-966): Undeclared identifier.\n// DeclarationError 7576: (976-977): Undeclared identifier.\n// DeclarationError 7576: (987-988): Undeclared identifier.\n// DeclarationError 7576: (998-999): Undeclared identifier.\n// DeclarationError 7576: (1009-1010): Undeclared identifier.\n// DeclarationError 7576: (1020-1021): Undeclared identifier.\n// DeclarationError 7576: (1031-1032): Undeclared identifier.\n// DeclarationError 7576: (1042-1043): Undeclared identifier.\n// DeclarationError 7576: (1053-1054): Undeclared identifier.\n// DeclarationError 7576: (1064-1065): Undeclared identifier.\n// DeclarationError 7576: (1075-1076): Undeclared identifier.\n// DeclarationError 7576: (1086-1087): Undeclared identifier.\n// DeclarationError 7576: (1097-1098): Undeclared identifier.\n// DeclarationError 7576: (1108-1109): Undeclared identifier.\n// DeclarationError 7576: (1119-1120): Undeclared identifier.\n// DeclarationError 7576: (1130-1131): Undeclared identifier.\n// DeclarationError 7576: (1141-1142): Undeclared identifier.\n// DeclarationError 7576: (1152-1153): Undeclared identifier.\n// DeclarationError 7576: (1163-1164): Undeclared identifier.\n// DeclarationError 7576: (1174-1175): Undeclared identifier.\n// DeclarationError 7576: (1185-1186): Undeclared identifier.\n// DeclarationError 7576: (1196-1197): Undeclared identifier.\n// DeclarationError 7576: (1207-1208): Undeclared identifier.\n// DeclarationError 7576: (1218-1219): Undeclared identifier.\n// DeclarationError 7576: (1229-1230): Undeclared identifier.\n// DeclarationError 7576: (1240-1241): Undeclared identifier.\n// DeclarationError 7576: (1251-1252): Undeclared identifier.\n// DeclarationError 7576: (1262-1263): Undeclared identifier.\n// DeclarationError 7576: (1273-1274): Undeclared identifier.\n// DeclarationError 7576: (1284-1285): Undeclared identifier.\n// DeclarationError 7576: (1295-1296): Undeclared identifier.\n// DeclarationError 7576: (1306-1307): Undeclared identifier.\n// DeclarationError 7576: (1317-1318): Undeclared identifier.\n// DeclarationError 7576: (1328-1329): Undeclared identifier.\n// DeclarationError 7576: (1339-1340): Undeclared identifier.\n// DeclarationError 7576: (1350-1351): Undeclared identifier.\n// DeclarationError 7576: (1361-1362): Undeclared identifier.\n// DeclarationError 7576: (1372-1373): Undeclared identifier.\n// DeclarationError 7576: (1383-1384): Undeclared identifier.\n// DeclarationError 7576: (1394-1395): Undeclared identifier.\n// DeclarationError 7576: (1405-1406): Undeclared identifier.\n// DeclarationError 7576: (1416-1417): Undeclared identifier.\n// DeclarationError 7576: (1427-1428): Undeclared identifier.\n// DeclarationError 7576: (1438-1439): Undeclared identifier.\n// DeclarationError 7576: (1449-1450): Undeclared identifier.\n// DeclarationError 7576: (1460-1461): Undeclared identifier.\n// DeclarationError 7576: (1471-1472): Undeclared identifier.\n// DeclarationError 7576: (1482-1483): Undeclared identifier.\n// DeclarationError 7576: (1493-1494): Undeclared identifier.\n// DeclarationError 7576: (1504-1505): Undeclared identifier.\n// DeclarationError 7576: (1515-1516): Undeclared identifier.\n// DeclarationError 7576: (1526-1527): Undeclared identifier.\n// DeclarationError 7576: (1537-1538): Undeclared identifier.\n// DeclarationError 7576: (1548-1549): Undeclared identifier.\n// DeclarationError 7576: (1559-1560): Undeclared identifier.\n// DeclarationError 7576: (1570-1571): Undeclared identifier.\n// DeclarationError 7576: (1581-1582): Undeclared identifier.\n// DeclarationError 7576: (1592-1593): Undeclared identifier.\n// DeclarationError 7576: (1603-1604): Undeclared identifier.\n// DeclarationError 7576: (1614-1615): Undeclared identifier.\n// DeclarationError 7576: (1625-1626): Undeclared identifier.\n// DeclarationError 7576: (1636-1637): Undeclared identifier.\n// DeclarationError 7576: (1647-1648): Undeclared identifier.\n// DeclarationError 7576: (1658-1659): Undeclared identifier.\n// DeclarationError 7576: (1669-1670): Undeclared identifier.\n// DeclarationError 7576: (1680-1681): Undeclared identifier.\n// DeclarationError 7576: (1691-1692): Undeclared identifier.\n// DeclarationError 7576: (1702-1703): Undeclared identifier.\n// DeclarationError 7576: (1713-1714): Undeclared identifier.\n// DeclarationError 7576: (1724-1725): Undeclared identifier.\n// DeclarationError 7576: (1735-1736): Undeclared identifier.\n// DeclarationError 7576: (1746-1747): Undeclared identifier.\n// DeclarationError 7576: (1757-1758): Undeclared identifier.\n// DeclarationError 7576: (1768-1769): Undeclared identifier.\n// DeclarationError 7576: (1779-1780): Undeclared identifier.\n// DeclarationError 7576: (1790-1791): Undeclared identifier.\n// DeclarationError 7576: (1801-1802): Undeclared identifier.\n// DeclarationError 7576: (1812-1813): Undeclared identifier.\n// DeclarationError 7576: (1823-1824): Undeclared identifier.\n// DeclarationError 7576: (1834-1835): Undeclared identifier.\n// DeclarationError 7576: (1845-1846): Undeclared identifier.\n// DeclarationError 7576: (1856-1857): Undeclared identifier.\n// DeclarationError 7576: (1867-1868): Undeclared identifier.\n// DeclarationError 7576: (1878-1879): Undeclared identifier.\n// DeclarationError 7576: (1889-1890): Undeclared identifier.\n// DeclarationError 7576: (1900-1901): Undeclared identifier.\n// DeclarationError 7576: (1911-1912): Undeclared identifier.\n// DeclarationError 7576: (1922-1923): Undeclared identifier.\n// DeclarationError 7576: (1933-1934): Undeclared identifier.\n// DeclarationError 7576: (1944-1945): Undeclared identifier.\n// DeclarationError 7576: (1955-1956): Undeclared identifier.\n// DeclarationError 7576: (1966-1967): Undeclared identifier.\n// DeclarationError 7576: (1977-1978): Undeclared identifier.\n// DeclarationError 7576: (1988-1989): Undeclared identifier.\n// DeclarationError 7576: (1999-2000): Undeclared identifier.\n// DeclarationError 7576: (2010-2011): Undeclared identifier.\n// DeclarationError 7576: (2021-2022): Undeclared identifier.\n// DeclarationError 7576: (2032-2033): Undeclared identifier.\n// DeclarationError 7576: (2043-2044): Undeclared identifier.\n// DeclarationError 7576: (2054-2055): Undeclared identifier.\n// DeclarationError 7576: (2065-2066): Undeclared identifier.\n// DeclarationError 7576: (2076-2077): Undeclared identifier.\n// DeclarationError 7576: (2087-2088): Undeclared identifier.\n// DeclarationError 7576: (2098-2099): Undeclared identifier.\n// DeclarationError 7576: (2109-2110): Undeclared identifier.\n// DeclarationError 7576: (2120-2121): Undeclared identifier.\n// DeclarationError 7576: (2131-2132): Undeclared identifier.\n// DeclarationError 7576: (2142-2143): Undeclared identifier.\n// DeclarationError 7576: (2153-2154): Undeclared identifier.\n// DeclarationError 7576: (2164-2165): Undeclared identifier.\n// DeclarationError 7576: (2175-2176): Undeclared identifier.\n// DeclarationError 7576: (2186-2187): Undeclared identifier.\n// DeclarationError 7576: (2197-2198): Undeclared identifier.\n// DeclarationError 7576: (2208-2209): Undeclared identifier.\n// DeclarationError 7576: (2219-2220): Undeclared identifier.\n// DeclarationError 7576: (2230-2231): Undeclared identifier.\n// DeclarationError 7576: (2241-2242): Undeclared identifier.\n// DeclarationError 7576: (2252-2253): Undeclared identifier.\n// DeclarationError 7576: (2263-2264): Undeclared identifier.\n// DeclarationError 7576: (2274-2275): Undeclared identifier.\n// DeclarationError 7576: (2285-2286): Undeclared identifier.\n// DeclarationError 7576: (2296-2297): Undeclared identifier.\n// DeclarationError 7576: (2307-2308): Undeclared identifier.\n// DeclarationError 7576: (2318-2319): Undeclared identifier.\n// DeclarationError 7576: (2329-2330): Undeclared identifier.\n// DeclarationError 7576: (2340-2341): Undeclared identifier.\n// DeclarationError 7576: (2351-2352): Undeclared identifier.\n// DeclarationError 7576: (2362-2363): Undeclared identifier.\n// DeclarationError 7576: (2373-2374): Undeclared identifier.\n// DeclarationError 7576: (2384-2385): Undeclared identifier.\n// DeclarationError 7576: (2395-2396): Undeclared identifier.\n// DeclarationError 7576: (2406-2407): Undeclared identifier.\n// DeclarationError 7576: (2417-2418): Undeclared identifier.\n// DeclarationError 7576: (2428-2429): Undeclared identifier.\n// DeclarationError 7576: (2439-2440): Undeclared identifier.\n// DeclarationError 7576: (2450-2451): Undeclared identifier.\n// DeclarationError 7576: (2461-2462): Undeclared identifier.\n// DeclarationError 7576: (2472-2473): Undeclared identifier.\n// DeclarationError 7576: (2483-2484): Undeclared identifier.\n// DeclarationError 7576: (2494-2495): Undeclared identifier.\n// DeclarationError 7576: (2505-2506): Undeclared identifier.\n// DeclarationError 7576: (2516-2517): Undeclared identifier.\n// DeclarationError 7576: (2527-2528): Undeclared identifier.\n// DeclarationError 7576: (2538-2539): Undeclared identifier.\n// DeclarationError 7576: (2549-2550): Undeclared identifier.\n// DeclarationError 7576: (2560-2561): Undeclared identifier.\n// DeclarationError 7576: (2571-2572): Undeclared identifier.\n// DeclarationError 7576: (2582-2583): Undeclared identifier.\n// DeclarationError 7576: (2593-2594): Undeclared identifier.\n// DeclarationError 7576: (2604-2605): Undeclared identifier.\n// DeclarationError 7576: (2615-2616): Undeclared identifier.\n// DeclarationError 7576: (2626-2627): Undeclared identifier.\n// DeclarationError 7576: (2637-2638): Undeclared identifier.\n// DeclarationError 7576: (2648-2649): Undeclared identifier.\n// DeclarationError 7576: (2659-2660): Undeclared identifier.\n// DeclarationError 7576: (2670-2671): Undeclared identifier.\n// DeclarationError 7576: (2681-2682): Undeclared identifier.\n// DeclarationError 7576: (2692-2693): Undeclared identifier.\n// DeclarationError 7576: (2703-2704): Undeclared identifier.\n// DeclarationError 7576: (2714-2715): Undeclared identifier.\n// DeclarationError 7576: (2725-2726): Undeclared identifier.\n// DeclarationError 7576: (2736-2737): Undeclared identifier.\n// DeclarationError 7576: (2747-2748): Undeclared identifier.\n// DeclarationError 7576: (2758-2759): Undeclared identifier.\n// DeclarationError 7576: (2769-2770): Undeclared identifier.\n// DeclarationError 7576: (2780-2781): Undeclared identifier.\n// DeclarationError 7576: (2791-2792): Undeclared identifier.\n// DeclarationError 7576: (2802-2803): Undeclared identifier.\n// DeclarationError 7576: (2813-2814): Undeclared identifier.\n// DeclarationError 7576: (2824-2825): Undeclared identifier.\n// DeclarationError 7576: (2835-2836): Undeclared identifier.\n// DeclarationError 7576: (2846-2847): Undeclared identifier.\n// Warning 4013: There are more than 256 errors. Aborting.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/more_than_256_importerrors.sol",
    "content": "import \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\nimport \"a.sol\";\n\ncontract C {\n  function f() public {\n  }\n}\n// ----\n// ParserError 6275: (0-15): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (16-31): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (32-47): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (48-63): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (64-79): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (80-95): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (96-111): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (112-127): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (128-143): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (144-159): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (160-175): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (176-191): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (192-207): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (208-223): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (224-239): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (240-255): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (256-271): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (272-287): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (288-303): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (304-319): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (320-335): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (336-351): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (352-367): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (368-383): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (384-399): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (400-415): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (416-431): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (432-447): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (448-463): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (464-479): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (480-495): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (496-511): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (512-527): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (528-543): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (544-559): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (560-575): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (576-591): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (592-607): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (608-623): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (624-639): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (640-655): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (656-671): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (672-687): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (688-703): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (704-719): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (720-735): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (736-751): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (752-767): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (768-783): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (784-799): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (800-815): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (816-831): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (832-847): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (848-863): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (864-879): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (880-895): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (896-911): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (912-927): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (928-943): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (944-959): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (960-975): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (976-991): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (992-1007): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1008-1023): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1024-1039): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1040-1055): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1056-1071): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1072-1087): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1088-1103): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1104-1119): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1120-1135): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1136-1151): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1152-1167): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1168-1183): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1184-1199): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1200-1215): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1216-1231): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1232-1247): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1248-1263): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1264-1279): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1280-1295): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1296-1311): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1312-1327): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1328-1343): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1344-1359): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1360-1375): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1376-1391): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1392-1407): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1408-1423): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1424-1439): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1440-1455): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1456-1471): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1472-1487): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1488-1503): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1504-1519): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1520-1535): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1536-1551): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1552-1567): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1568-1583): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1584-1599): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1600-1615): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1616-1631): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1632-1647): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1648-1663): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1664-1679): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1680-1695): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1696-1711): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1712-1727): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1728-1743): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1744-1759): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1760-1775): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1776-1791): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1792-1807): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1808-1823): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1824-1839): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1840-1855): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1856-1871): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1872-1887): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1888-1903): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1904-1919): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1920-1935): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1936-1951): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1952-1967): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1968-1983): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (1984-1999): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2000-2015): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2016-2031): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2032-2047): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2048-2063): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2064-2079): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2080-2095): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2096-2111): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2112-2127): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2128-2143): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2144-2159): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2160-2175): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2176-2191): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2192-2207): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2208-2223): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2224-2239): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2240-2255): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2256-2271): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2272-2287): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2288-2303): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2304-2319): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2320-2335): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2336-2351): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2352-2367): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2368-2383): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2384-2399): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2400-2415): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2416-2431): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2432-2447): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2448-2463): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2464-2479): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2480-2495): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2496-2511): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2512-2527): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2528-2543): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2544-2559): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2560-2575): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2576-2591): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2592-2607): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2608-2623): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2624-2639): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2640-2655): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2656-2671): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2672-2687): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2688-2703): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2704-2719): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2720-2735): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2736-2751): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2752-2767): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2768-2783): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2784-2799): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2800-2815): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2816-2831): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2832-2847): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2848-2863): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2864-2879): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2880-2895): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2896-2911): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2912-2927): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2928-2943): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2944-2959): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2960-2975): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2976-2991): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (2992-3007): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3008-3023): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3024-3039): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3040-3055): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3056-3071): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3072-3087): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3088-3103): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3104-3119): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3120-3135): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3136-3151): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3152-3167): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3168-3183): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3184-3199): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3200-3215): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3216-3231): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3232-3247): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3248-3263): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3264-3279): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3280-3295): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3296-3311): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3312-3327): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3328-3343): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3344-3359): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3360-3375): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3376-3391): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3392-3407): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3408-3423): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3424-3439): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3440-3455): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3456-3471): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3472-3487): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3488-3503): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3504-3519): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3520-3535): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3536-3551): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3552-3567): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3568-3583): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3584-3599): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3600-3615): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3616-3631): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3632-3647): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3648-3663): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3664-3679): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3680-3695): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3696-3711): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3712-3727): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3728-3743): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3744-3759): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3760-3775): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3776-3791): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3792-3807): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3808-3823): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3824-3839): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3840-3855): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3856-3871): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3872-3887): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3888-3903): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3904-3919): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3920-3935): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3936-3951): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3952-3967): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3968-3983): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (3984-3999): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (4000-4015): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (4016-4031): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (4032-4047): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (4048-4063): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (4064-4079): Source \"a.sol\" not found: File not supplied initially.\n// ParserError 6275: (4080-4095): Source \"a.sol\" not found: File not supplied initially.\n// Warning 4013: There are more than 256 errors. Aborting.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/sizeLimits/more_than_256_syntaxerrors.sol",
    "content": "contract C {\n  function f() public {\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n    continue;\n  }\n}\n// ----\n// SyntaxError 4123: (41-49): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (55-63): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (69-77): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (83-91): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (97-105): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (111-119): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (125-133): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (139-147): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (153-161): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (167-175): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (181-189): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (195-203): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (209-217): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (223-231): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (237-245): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (251-259): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (265-273): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (279-287): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (293-301): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (307-315): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (321-329): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (335-343): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (349-357): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (363-371): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (377-385): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (391-399): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (405-413): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (419-427): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (433-441): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (447-455): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (461-469): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (475-483): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (489-497): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (503-511): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (517-525): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (531-539): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (545-553): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (559-567): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (573-581): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (587-595): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (601-609): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (615-623): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (629-637): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (643-651): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (657-665): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (671-679): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (685-693): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (699-707): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (713-721): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (727-735): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (741-749): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (755-763): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (769-777): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (783-791): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (797-805): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (811-819): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (825-833): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (839-847): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (853-861): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (867-875): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (881-889): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (895-903): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (909-917): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (923-931): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (937-945): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (951-959): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (965-973): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (979-987): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (993-1001): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1007-1015): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1021-1029): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1035-1043): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1049-1057): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1063-1071): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1077-1085): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1091-1099): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1105-1113): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1119-1127): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1133-1141): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1147-1155): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1161-1169): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1175-1183): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1189-1197): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1203-1211): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1217-1225): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1231-1239): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1245-1253): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1259-1267): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1273-1281): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1287-1295): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1301-1309): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1315-1323): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1329-1337): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1343-1351): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1357-1365): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1371-1379): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1385-1393): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1399-1407): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1413-1421): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1427-1435): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1441-1449): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1455-1463): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1469-1477): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1483-1491): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1497-1505): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1511-1519): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1525-1533): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1539-1547): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1553-1561): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1567-1575): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1581-1589): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1595-1603): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1609-1617): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1623-1631): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1637-1645): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1651-1659): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1665-1673): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1679-1687): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1693-1701): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1707-1715): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1721-1729): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1735-1743): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1749-1757): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1763-1771): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1777-1785): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1791-1799): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1805-1813): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1819-1827): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1833-1841): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1847-1855): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1861-1869): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1875-1883): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1889-1897): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1903-1911): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1917-1925): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1931-1939): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1945-1953): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1959-1967): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1973-1981): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (1987-1995): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2001-2009): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2015-2023): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2029-2037): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2043-2051): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2057-2065): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2071-2079): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2085-2093): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2099-2107): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2113-2121): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2127-2135): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2141-2149): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2155-2163): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2169-2177): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2183-2191): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2197-2205): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2211-2219): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2225-2233): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2239-2247): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2253-2261): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2267-2275): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2281-2289): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2295-2303): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2309-2317): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2323-2331): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2337-2345): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2351-2359): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2365-2373): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2379-2387): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2393-2401): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2407-2415): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2421-2429): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2435-2443): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2449-2457): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2463-2471): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2477-2485): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2491-2499): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2505-2513): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2519-2527): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2533-2541): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2547-2555): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2561-2569): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2575-2583): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2589-2597): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2603-2611): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2617-2625): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2631-2639): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2645-2653): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2659-2667): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2673-2681): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2687-2695): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2701-2709): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2715-2723): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2729-2737): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2743-2751): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2757-2765): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2771-2779): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2785-2793): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2799-2807): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2813-2821): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2827-2835): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2841-2849): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2855-2863): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2869-2877): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2883-2891): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2897-2905): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2911-2919): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2925-2933): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2939-2947): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2953-2961): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2967-2975): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2981-2989): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (2995-3003): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3009-3017): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3023-3031): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3037-3045): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3051-3059): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3065-3073): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3079-3087): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3093-3101): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3107-3115): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3121-3129): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3135-3143): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3149-3157): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3163-3171): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3177-3185): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3191-3199): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3205-3213): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3219-3227): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3233-3241): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3247-3255): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3261-3269): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3275-3283): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3289-3297): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3303-3311): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3317-3325): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3331-3339): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3345-3353): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3359-3367): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3373-3381): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3387-3395): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3401-3409): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3415-3423): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3429-3437): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3443-3451): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3457-3465): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3471-3479): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3485-3493): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3499-3507): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3513-3521): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3527-3535): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3541-3549): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3555-3563): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3569-3577): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3583-3591): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3597-3605): \"continue\" has to be in a \"for\" or \"while\" loop.\n// SyntaxError 4123: (3611-3619): \"continue\" has to be in a \"for\" or \"while\" loop.\n// Warning 4013: There are more than 256 errors. Aborting.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/smoke/smoke_test.sol",
    "content": "contract test {\n\tuint256 stateVariable1;\n\tfunction fun(uint256 arg1) public { uint256 y; y = arg1; }\n}\n// ----\n// Warning 2018: (42-100): Function state mutability can be restricted to pure\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_nested_dynamic_array.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f() public pure {\n        abi.encodePacked([new uint[](5), new uint[](7)]);\n    }\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 9578: (89-119): Type not supported in packed mode.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_nested_dynamic_array_v2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f() public pure {\n        abi.encodePacked([new uint[](5), new uint[](7)]);\n    }\n}\n// ----\n// TypeError 9578: (104-134): Type not supported in packed mode.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_structs_v2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { uint x; }\n    S s;\n    struct T { uint y; }\n    T t;\n    function f() public view {\n        bytes32 a = sha256(abi.encodePacked(s, t));\n        a;\n    }\n}\n// ----\n// TypeError 9578: (191-192): Type not supported in packed mode.\n// TypeError 9578: (194-195): Type not supported in packed mode.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_tuple_returned_from_function.sol",
    "content": "contract C {\n    function g0() internal pure {}\n    function g1() internal pure returns (uint) { return (1); }\n    function g2() internal pure returns (uint, uint) { return (2, 3); }\n\n    function h() public pure {\n        abi.encodePacked(g0());\n        abi.encodePacked(g2());\n        abi.encodePacked((g1(), g1()));\n    }\n}\n// ----\n// TypeError 2056: (240-244): This type cannot be encoded.\n// TypeError 2056: (272-276): This type cannot be encoded.\n// TypeError 2056: (304-316): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_unitary_tuple_returned_from_function.sol",
    "content": "contract C {\n    function g1() internal pure returns (uint) { return (1); }\n\n    function h() public pure {\n        abi.encodePacked(g1());\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encodeWithSelector_tuple_returned_from_function.sol",
    "content": "contract C {\n    function g0() internal pure {}\n    function g1() internal pure returns (uint) { return (1); }\n    function g2() internal pure returns (uint, uint) { return (2, 3); }\n\n    function f0() public {}\n    function f1(uint) public {}\n    function f2(uint, uint) public {}\n\n    function h() public pure {\n        abi.encodeWithSelector(this.f0.selector, g0());\n        abi.encodeWithSelector(this.f0.selector, g2());\n        abi.encodeWithSelector(this.f0.selector, (g1(), g1()));\n    }\n}\n// ----\n// TypeError 2056: (363-367): This type cannot be encoded.\n// TypeError 2056: (419-423): This type cannot be encoded.\n// TypeError 2056: (475-487): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encodeWithSelector_unitary_tuple_returned_from_function.sol",
    "content": "contract C {\n    function g1() internal pure returns (uint) { return (1); }\n\n    function f0() public {}\n\n    function h() public pure {\n        abi.encodeWithSelector(this.f0.selector, g1());\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encodeWithSignature_tuple_returned_from_function.sol",
    "content": "contract C {\n    function g0() internal pure {}\n    function g1() internal pure returns (uint) { return (1); }\n    function g2() internal pure returns (uint, uint) { return (2, 3); }\n\n    function h() public pure {\n        abi.encodeWithSignature(\"f0()\", g0());\n        abi.encodeWithSignature(\"f()\", g2());\n        abi.encodeWithSignature(\"f()\", (g1(), g1()));\n    }\n}\n// ----\n// TypeError 2056: (255-259): This type cannot be encoded.\n// TypeError 2056: (301-305): This type cannot be encoded.\n// TypeError 2056: (347-359): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encodeWithSignature_unitary_tuple_from_function.sol",
    "content": "contract C {\n    function g1() internal pure returns (uint) { return (1); }\n\n    function h() public pure {\n        abi.encodeWithSignature(\"f()\", g1());\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encode_nested_dynamic_array.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function test() public pure {\n        abi.encode([new uint[](5), new uint[](7)]);\n    }\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2056: (86-116): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encode_nested_dynamic_array_v2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f() public pure {\n        abi.encode([new uint[](5), new uint[](7)]);\n    }\n}\n// ----\n// Warning 6133: (87-129): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encode_structs.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    struct S { uint x; }\n    S s;\n    struct T { uint y; }\n    T t;\n    function f() public view {\n        abi.encode(s, t);\n    }\n    function g() public view {\n        abi.encodePacked(s, t);\n    }\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 2056: (151-152): This type cannot be encoded.\n// TypeError 2056: (154-155): This type cannot be encoded.\n// TypeError 9578: (220-221): Type not supported in packed mode.\n// TypeError 9578: (223-224): Type not supported in packed mode.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encode_structs_abiv2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { uint x; }\n    S s;\n    struct T { uint y; }\n    T t;\n    function e() public view {\n        S memory st;\n        abi.encodePacked(st);\n    }\n    function f() public view {\n        abi.encode(s, t);\n    }\n    function g() public view {\n        abi.encodePacked(s, t);\n    }\n}\n// ----\n// TypeError 9578: (193-195): Type not supported in packed mode.\n// TypeError 9578: (323-324): Type not supported in packed mode.\n// TypeError 9578: (326-327): Type not supported in packed mode.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encode_tuple_returned_from_function.sol",
    "content": "contract C {\n    function g0() internal pure {}\n    function g1() internal pure returns (uint) { return (1); }\n    function g2() internal pure returns (uint, uint) { return (2, 3); }\n\n    function h() public pure {\n        abi.encode(g0());\n        abi.encode(g2());\n        abi.encode((g1(), g1()));\n    }\n}\n// ----\n// TypeError 2056: (234-238): This type cannot be encoded.\n// TypeError 2056: (260-264): This type cannot be encoded.\n// TypeError 2056: (286-298): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_encode_unitary_tuple_returned_from_function.sol",
    "content": "contract C {\n    function g1() internal pure returns (uint) { return (1); }\n\n    function h() public pure {\n        abi.encode(g1());\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abi_functions_member_access.sol",
    "content": "contract C {\n    function f() public pure {\n        abi.encode;\n        abi.encodePacked;\n        abi.encodeWithSelector;\n        abi.encodeWithSignature;\n        abi.decode;\n    }\n}\n// ----\n// Warning 6133: (52-62): Statement has no effect.\n// Warning 6133: (72-88): Statement has no effect.\n// Warning 6133: (98-120): Statement has no effect.\n// Warning 6133: (130-153): Statement has no effect.\n// Warning 6133: (163-173): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_array_of_unitary_tuples.sol",
    "content": "contract C {\n    function f() pure public {\n        abi.decode(\"\", ((uint)[2]));\n        abi.decode(\"\", ((uint)[]));\n        abi.decode(\"\", ((uint)[][3]));\n        abi.decode(\"\", ((uint)[4][]));\n        abi.decode(\"\", ((uint)[5][6]));\n        abi.decode(\"\", (((uint))[5][6]));\n    }\n}\n// ----\n// Warning 6133: (52-79): Statement has no effect.\n// Warning 6133: (89-115): Statement has no effect.\n// Warning 6133: (125-154): Statement has no effect.\n// Warning 6133: (164-193): Statement has no effect.\n// Warning 6133: (203-233): Statement has no effect.\n// Warning 6133: (243-275): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_calldata.sol",
    "content": "// This restriction might be lifted in the future\ncontract C {\n  function f() public pure {\n    abi.decode(\"abc\", (bytes calldata));\n  }\n}\n// ----\n// ParserError 2314: (121-129): Expected ',' but got 'calldata'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_empty.sol",
    "content": "contract C {\n    function f() public pure {\n        abi.decode(\"abc\", ());\n    }\n}\n// ----\n// Warning 6133: (52-73): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_enum.sol",
    "content": "contract C {\n    enum Color { red, green, blue }\n    function f() pure public {\n        abi.decode(\"\", (Color));\n    }\n}\n// ----\n// Warning 6133: (88-111): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_arg_count.sol",
    "content": "contract C {\n  function f() public pure {\n    abi.decode();\n    abi.decode(msg.data);\n    abi.decode(msg.data, uint, uint);\n  }\n}\n// ----\n// TypeError 5782: (46-58): This function takes two arguments, but 0 were provided.\n// TypeError 5782: (64-84): This function takes two arguments, but 1 were provided.\n// TypeError 5782: (90-122): This function takes two arguments, but 3 were provided.\n// TypeError 6444: (111-115): The second argument to \"abi.decode\" has to be a tuple of types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_arg_type.sol",
    "content": "contract C {\n  function f() public pure {\n    abi.decode(uint, uint);\n  }\n}\n// ----\n// TypeError 1956: (57-61): The first argument to \"abi.decode\" must be implicitly convertible to bytes memory or bytes calldata, but is of type type(uint256).\n// TypeError 6444: (63-67): The second argument to \"abi.decode\" has to be a tuple of types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_array_length_ternary_with_max_keyword.sol",
    "content": "contract C {\n    function f() pure public {\n        bool x;\n        abi.decode(\"\", (uint[type(x = true ? uint8 : uint8).max]));\n    }\n}\n// ----\n// TypeError 9717: (105-110): Invalid mobile type in true expression.\n// TypeError 3703: (113-118): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_array_of_tuples.sol",
    "content": "contract C {\n    function f() pure public {\n        abi.decode(\"\", ((uint, int)[5][6]));\n    }\n}\n// ----\n// TypeError 2614: (68-79): Indexed expression has to be a type, mapping or array (is tuple(type(uint256),type(int256)))\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_indexed_array_literal.sol",
    "content": "contract C {\n    function f() pure public {\n        abi.decode(\"\", ([uint][2]));\n    }\n}\n// ----\n// TypeError 9563: (69-73): Invalid mobile type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_indexed_ternary_expression.sol",
    "content": "contract C {\n    function f() pure public {\n        bool x;\n        abi.decode(\"\", ((x = true ? uint : uint)[0]));\n    }\n}\n// ----\n// TypeError 9717: (96-100): Invalid mobile type in true expression.\n// TypeError 3703: (103-107): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_ternary_condition_expression.sol",
    "content": "contract C {\n    function f() pure public {\n        abi.decode(\"\", (true ? uint : uint));\n    }\n}\n// ----\n// TypeError 9717: (75-79): Invalid mobile type in true expression.\n// TypeError 3703: (82-86): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_ternary_expression_inside_parentheses.sol",
    "content": "contract C {\n    function f() pure public {\n        abi.decode(\"\", ((true ? uint : uint)));\n    }\n}\n// ----\n// TypeError 9717: (76-80): Invalid mobile type in true expression.\n// TypeError 3703: (83-87): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_ternary_with_side_effect.sol",
    "content": "contract C {\n    function f() pure public {\n        int x;\n        abi.decode(\"\", ((x = 1) > 0 ? int : int));\n    }\n}\n// ----\n// TypeError 9717: (97-100): Invalid mobile type in true expression.\n// TypeError 3703: (103-106): Invalid mobile type in false expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_tuple_type.sol",
    "content": "contract C {\n    function f() pure public {\n        abi.decode(\"\", ((uint, int)));\n    }\n}\n// ----\n// TypeError 1039: (68-79): Argument has to be a type name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_type_expression.sol",
    "content": "contract C {\n    function f() pure public {\n        abi.decode(\"\", (type(uint)));\n    }\n}\n// ----\n// TypeError 1039: (68-78): Argument has to be a type name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_member_acess.sol",
    "content": "library L {\n    struct S { int a; }\n    enum State { idle, running, blocked }\n}\n\ncontract D {\n    struct X { uint b; }\n    enum Color { red, green, blue }\n}\n\ncontract C {\n    function f() pure public {\n        abi.decode(\"\", (L.S));\n        abi.decode(\"\", (L.State));\n        abi.decode(\"\", (D.X));\n        abi.decode(\"\", (D.Color));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_memory.sol",
    "content": "contract C {\n  function f() public pure {\n    abi.decode(\"abc\", (bytes memory, uint[][2] memory));\n  }\n}\n// ----\n// ParserError 2314: (71-77): Expected ',' but got 'memory'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_memory_v2.sol",
    "content": "pragma abicoder v2;\ncontract C {\n  struct S { uint x; uint[] b; }\n  function f() public pure returns (S memory, bytes memory, uint[][2] memory) {\n    return abi.decode(\"abc\", (S, bytes, uint[][2]));\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_nested_dynamic_array.sol",
    "content": "pragma abicoder v1;\ncontract C {\n    function f() public pure {\n        abi.decode(\"1234\", (uint[][3]));\n    }\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 9611: (92-101): Decoding type uint256[][3] memory not supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_nested_dynamic_array_v2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f() public pure {\n        abi.decode(\"1234\", (uint[][3]));\n    }\n}\n// ----\n// Warning 6133: (87-118): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_nontuple.sol",
    "content": "contract C {\n  function f() public pure {\n    abi.decode(\"abc\", uint);\n    abi.decode(\"abc\", this);\n    abi.decode(\"abc\", f());\n  }\n}\n// ----\n// TypeError 6444: (64-68): The second argument to \"abi.decode\" has to be a tuple of types.\n// TypeError 6444: (93-97): The second argument to \"abi.decode\" has to be a tuple of types.\n// TypeError 6444: (122-125): The second argument to \"abi.decode\" has to be a tuple of types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_simple.sol",
    "content": "contract C {\n  function f() public pure returns (uint, bytes32, C) {\n    return abi.decode(\"abc\", (uint, bytes32, C));\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_single_return.sol",
    "content": "contract C {\n    function f() public pure returns (bool) {\n        return abi.decode(\"abc\", (uint)) == 2;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_singletontuple.sol",
    "content": "contract C {\n  function f() public pure returns (uint) {\n    return abi.decode(\"abc\", (uint));\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_storage.sol",
    "content": "// This restriction might be lifted in the future\ncontract C {\n  function f() {\n    abi.decode(\"abc\", (bytes storage));\n  }\n}\n// ----\n// ParserError 2314: (109-116): Expected ',' but got 'storage'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_struct.sol",
    "content": "pragma abicoder v1;\nstruct S {\n    uint x;\n}\n\ncontract C {\n    function f() public pure {\n        abi.decode(\"1234\", (S));\n    }\n}\n// ----\n// Warning 9511: (0-19): ABI coder v1 is deprecated and scheduled for removal. Use ABI coder v2 instead.\n// TypeError 9611: (118-119): Decoding type struct S memory not supported.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_struct_v2.sol",
    "content": "pragma abicoder               v2;\n\nstruct S {\n    uint x;\n}\n\ncontract C {\n    function f() public pure {\n        abi.decode(\"1234\", (S));\n    }\n}\n// ----\n// Warning 6133: (113-136): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_unitary_nested_tuple.sol",
    "content": "struct S { int a; }\n\ncontract C {\n    function f() pure public {\n        abi.decode(\"\", (((uint))));\n        abi.decode(\"\", ((((uint)))));\n        abi.decode(\"\", (((S))));\n    }\n}\n// ----\n// Warning 6133: (73-99): Statement has no effect.\n// Warning 6133: (109-137): Statement has no effect.\n// Warning 6133: (147-170): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/abidecode/contract_array.sol",
    "content": "contract C {\n\tfunction f(bytes calldata x) public pure returns (C[] memory c) {\n\t\tc = abi.decode(x, (C[]));\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/encodeCall.sol",
    "content": "interface I {\n\tfunction fExternal(uint256 p, string memory t) external;\n}\n\ncontract Other {\n\tfunction fExternal(uint) external pure {}\n\tfunction fPublic(uint) public pure {}\n\tfunction fInternal(uint) internal pure {}\n}\n\nlibrary L {\n\tfunction fExternal(uint256 p, string memory t) external {}\n\tfunction fInternal(uint256 p, string memory t) internal {}\n}\n\ncontract Base {\n\tfunction baseFunctionExternal(uint) external pure {}\n}\n\ncontract C is Base {\n\tfunction f(int a) public {}\n\tfunction f2(int a, string memory b) public {}\n\tfunction f4() public {}\n\n\tfunction successFunctionArgsIntLiteralTuple() public view returns(bytes memory) {\n\t\treturn abi.encodeCall(this.f, (1));\n\t}\n\tfunction successFunctionArgsIntLiteral() public view returns(bytes memory) {\n\t\treturn abi.encodeCall(this.f, 1);\n\t}\n\tfunction successFunctionArgsLiteralTuple() public view returns(bytes memory) {\n\t\treturn abi.encodeCall(this.f2, (1, \"test\"));\n\t}\n\tfunction successFunctionArgsEmptyTuple() public view returns(bytes memory) {\n\t\treturn abi.encodeCall(this.f4, ());\n\t}\n\tfunction viaDeclaration() public pure returns (bytes memory) {\n\t\treturn bytes.concat(\n\t\t\tabi.encodeCall(Other.fExternal, (1)),\n\t\t\tabi.encodeCall(Other.fPublic, (1)),\n\t\t\tabi.encodeCall(I.fExternal, (1, \"123\"))\n\t\t);\n\t}\n\tfunction viaBaseDeclaration() public pure returns (bytes memory) {\n\t\treturn abi.encodeCall(Base.baseFunctionExternal, (1));\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/encodeCall_fail_args.sol",
    "content": "contract C {\n\tfunction f(int a) public {}\n\tfunction f3(int a, int b) public {}\n\n\tfunction failFunctionArgsWrongType() public returns(bytes memory) {\n\t\treturn abi.encodeCall(this.f, (\"test\"));\n\t}\n\tfunction failFunctionArgsTooMany() public returns(bytes memory) {\n\t\treturn abi.encodeCall(this.f, (1, 2));\n\t}\n\tfunction failFunctionArgsTooFew0() public returns(bytes memory) {\n\t\treturn abi.encodeCall(this.f, ());\n\t}\n\tfunction failFunctionArgsTooFew1() public returns(bytes memory) {\n\t\treturn abi.encodeCall(this.f);\n\t}\n\tfunction failFunctionArgsArrayLiteral() public returns(bytes memory) {\n\t\treturn abi.encodeCall(this.f3, [1, 2]);\n\t}\n}\n// ----\n// TypeError 5407: (181-189): Cannot implicitly convert component at position 0 from \"literal_string \"test\"\" to \"int256\".\n// TypeError 7788: (271-301): Expected 1 instead of 2 components for the tuple parameter.\n// TypeError 7788: (382-408): Expected 1 instead of 0 components for the tuple parameter.\n// TypeError 6219: (489-511): Expected two arguments: a function pointer followed by a tuple.\n// TypeError 7515: (597-628): Expected a tuple with 2 components instead of a single non-tuple parameter.\n// TypeError 5407: (621-627): Cannot implicitly convert component at position 0 from \"uint8[2] memory\" to \"int256\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/encodeCall_fail_args_internal_function_pointer_for_uint.sol",
    "content": "contract C {\n    function f(uint) external {}\n\n    function main() external view {\n        function () h;\n        abi.encodeCall(this.f, (h));\n    }\n}\n// ----\n// TypeError 5407: (137-140): Cannot implicitly convert component at position 0 from \"function ()\" to \"uint256\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/encodeCall_fail_funType.sol",
    "content": "interface I {\n\tfunction fExternal(uint256 p, string memory t) external;\n}\n\ncontract Other {\n\tfunction fExternal(uint) external pure {}\n\tfunction fPublic(uint) public pure {}\n\tfunction fInternal(uint) internal pure {}\n}\n\nlibrary L {\n\tfunction fExternal(uint256 p, string memory t) external {}\n\tfunction fInternal(uint256 p, string memory t) internal {}\n}\n\ncontract Base {\n\tfunction baseFunctionInternal(uint) internal pure {}\n\tfunction baseFunctionPublic(uint) public pure {}\n}\n\nfunction fileLevel(uint) pure {}\n\ncontract C is Base {\n\tusing L for uint256;\n\n\tfunction fPublic(int a) public {}\n\tfunction fInternal(uint256 p, string memory t) internal {}\n\n\tfunction failFunctionPtrMissing() public returns(bytes memory) {\n\t\treturn abi.encodeCall(1, this.fPublic);\n\t}\n\tfunction failFunctionPtrWrongType() public returns(bytes memory) {\n\t\treturn abi.encodeCall(abi.encodeCall, (1, 2, 3, \"test\"));\n\t}\n\tfunction failFunctionInternal() public returns(bytes memory) {\n\t\treturn abi.encodeCall(fInternal, (1, \"123\"));\n\t}\n\tfunction failFunctionInternalFromVariable() public returns(bytes memory) {\n\t\tfunction(uint256, string memory) internal localFunctionPointer = fInternal;\n\t\treturn abi.encodeCall(localFunctionPointer, (1, \"123\"));\n\t}\n\tfunction failLibraryPointerCall() public {\n\t\tabi.encodeCall(L.fInternal, (1, \"123\"));\n\t\tabi.encodeCall(L.fExternal, (1, \"123\"));\n\t}\n\tfunction failAttachedLibraryPointerCall() public returns (bytes memory) {\n\t\tuint256 x = 1;\n\t\treturn abi.encodeCall(x.fExternal, (1, \"123\"));\n\t}\n\tfunction viaBaseDeclaration() public pure returns (bytes memory) {\n\t\treturn abi.encodeCall(C.fPublic, (2));\n\t}\n\tfunction viaBaseDeclaration2() public pure returns (bytes memory) {\n\t\treturn bytes.concat(\n\t\t\tabi.encodeCall(Base.baseFunctionPublic, (1)),\n\t\t\tabi.encodeCall(Base.baseFunctionInternal, (1))\n\t\t);\n\t}\n\tfunction fileLevelFunction() public pure returns (bytes memory) {\n\t\treturn abi.encodeCall(fileLevel, (2));\n\t}\n\tfunction createFunction() public pure returns (bytes memory) {\n\t\treturn abi.encodeCall(new Other, (2));\n\t}\n}\n// ----\n// TypeError 5511: (742-743): Expected first argument to be a function pointer, not \"int_const 1\".\n// TypeError 3509: (855-869): Expected regular external function type, or external view on public function. Cannot use special function.\n// TypeError 3509: (982-991): Expected regular external function type, or external view on public function. Provided internal function.\n// TypeError 3509: (1187-1207): Expected regular external function type, or external view on public function. Provided internal function.\n// TypeError 3509: (1286-1297): Expected regular external function type, or external view on public function. Provided internal function.\n// TypeError 3509: (1329-1340): Expected regular external function type, or external view on public function. Cannot use library functions for abi.encodeCall.\n// TypeError 3509: (1474-1485): Expected regular external function type, or external view on public function. Cannot use library functions for abi.encodeCall.\n// TypeError 3509: (1595-1604): Expected regular external function type, or external view on public function. Provided internal function. Did you forget to prefix \"this.\"?\n// TypeError 3509: (1725-1748): Expected regular external function type, or external view on public function. Provided internal function. Functions from base contracts have to be external.\n// TypeError 3509: (1774-1799): Expected regular external function type, or external view on public function. Provided internal function. Functions from base contracts have to be external.\n// TypeError 3509: (1905-1914): Expected regular external function type, or external view on public function. Provided internal function.\n// TypeError 3509: (2013-2022): Expected regular external function type, or external view on public function. Provided creation function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/encodeCall_nested_tuple.sol",
    "content": "contract C {\n\tfunction f(int a, int b) public {}\n\tfunction failFunctionArgsIntLiteralNestedTuple() public returns(bytes memory) {\n\t\treturn abi.encodeCall(this.f, ((1,2)));\n\t}\n}\n// ----\n// TypeError 7788: (139-170): Expected 2 instead of 1 components for the tuple parameter.\n// TypeError 5407: (163-168): Cannot implicitly convert component at position 0 from \"tuple(int_const 1,int_const 2)\" to \"int256\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/encodeCall_tuple_incomplete.sol",
    "content": "contract C {\n\tfunction f(int a) public {}\n\tfunction failFunctionArgsIntLiteralTuple() public returns(bytes memory) {\n\t\treturn abi.encodeCall(this.f, (1,));\n\t}\n}\n// ----\n// TypeError 8381: (149-153): Tuple component cannot be empty.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/encodePacked_array_of_structs.sol",
    "content": "contract C {\n    struct S { uint x; }\n    function f() public pure {\n        S[] memory s;\n        abi.encodePacked(s);\n    }\n}\n// ----\n// TypeError 9578: (116-117): Type not supported in packed mode.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/encodePacked_dynamic_string_array_v2.sol",
    "content": "contract C {\n    string[] s;\n    function f() public pure {\n        string[] memory m;\n        abi.encodePacked(m);\n    }\n    function g() public pure {\n        abi.encodePacked(s);\n    }\n}\n// ----\n// TypeError 9578: (112-113): Type not supported in packed mode.\n// TypeError 9578: (178-179): Type not supported in packed mode.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/encode_array_of_struct.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    struct S { uint x; }\n    function f() public pure {\n        S[] memory s;\n        abi.encode(s);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/encodecall_fail_args_internal_struct_for_uint.sol",
    "content": "struct S {\n    function () f;\n}\n\ncontract C {\n    enum testEnum { choice1, choice2, choice3 }\n\n    function f1(uint8) external {}\n    function f2(uint32) external {}\n    function f3(uint) external {}\n    function g1(bytes memory) external {}\n    function g2(bytes32) external {}\n    function h(string memory) external {}\n    function i(bool) external {}\n    function j(address) external {}\n    function k(address payable) external {}\n    function l(testEnum) external {}\n\n    function main() external view {\n        S memory s;\n        abi.encodeCall(this.f1, (s));\n        abi.encodeCall(this.f2, (s));\n        abi.encodeCall(this.f3, (s));\n        abi.encodeCall(this.g1, (s));\n        abi.encodeCall(this.g2, (s));\n        abi.encodeCall(this.h, (s));\n        abi.encodeCall(this.i, (s));\n        abi.encodeCall(this.j, (s));\n        abi.encodeCall(this.k, (s));\n        abi.encodeCall(this.l, (s));\n    }\n}\n// ----\n// TypeError 5407: (560-563): Cannot implicitly convert component at position 0 from \"struct S memory\" to \"uint8\".\n// TypeError 5407: (598-601): Cannot implicitly convert component at position 0 from \"struct S memory\" to \"uint32\".\n// TypeError 5407: (636-639): Cannot implicitly convert component at position 0 from \"struct S memory\" to \"uint256\".\n// TypeError 5407: (674-677): Cannot implicitly convert component at position 0 from \"struct S memory\" to \"bytes memory\".\n// TypeError 5407: (712-715): Cannot implicitly convert component at position 0 from \"struct S memory\" to \"bytes32\".\n// TypeError 5407: (749-752): Cannot implicitly convert component at position 0 from \"struct S memory\" to \"string memory\".\n// TypeError 5407: (786-789): Cannot implicitly convert component at position 0 from \"struct S memory\" to \"bool\".\n// TypeError 5407: (823-826): Cannot implicitly convert component at position 0 from \"struct S memory\" to \"address\".\n// TypeError 5407: (860-863): Cannot implicitly convert component at position 0 from \"struct S memory\" to \"address payable\".\n// TypeError 5407: (897-900): Cannot implicitly convert component at position 0 from \"struct S memory\" to \"enum C.testEnum\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/functionCallOptions_err.sol",
    "content": "contract C {\n    function f() public payable {\n\t\tabi.encode(this.f{value: 2});\n\t\tabi.encode(this.f{gas: 2});\n\t\tabi.encode(this.f{value: 2, gas: 1});\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// TypeError 2056: (60-76): This type cannot be encoded.\n// TypeError 2056: (92-106): This type cannot be encoded.\n// TypeError 2056: (122-146): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/single_non_bytes_arg.sol",
    "content": "contract C {\n    function f() pure public {\n        g(keccak256(uint(2)));\n        g(sha256(uint(2)));\n        g(ripemd160(uint(2)));\n    }\n    function g(bytes32) pure internal {}\n}\n// ----\n// TypeError 7556: (64-71): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n// TypeError 7556: (92-99): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n// TypeError 7556: (123-130): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes memory requested. This function requires a single bytes argument. Use abi.encodePacked(...) to obtain the pre-0.5.0 behaviour or abi.encode(...) to use ABI encoding.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol",
    "content": "contract C {\n    function f() payable public {\n        bytes32 h = keccak256(abi.encodePacked(keccak256, f, this.f{value: 2}, blockhash));\n        h;\n    }\n}\n// ----\n// TypeError 2056: (94-103): This type cannot be encoded.\n// TypeError 2056: (105-106): This type cannot be encoded.\n// TypeError 2056: (108-124): This type cannot be encoded.\n// TypeError 2056: (126-135): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_special_types.sol",
    "content": "contract C {\n    function f() public pure {\n        (bool a,) = address(this).call(abi.encode(address(this).delegatecall, super));\n        (a,) = address(this).delegatecall(abi.encode(block, tx, mulmod));\n        a;\n    }\n}\n// ----\n// TypeError 2056: (94-120): This type cannot be encoded.\n// TypeError 2056: (122-127): This type cannot be encoded.\n// TypeError 2056: (184-189): This type cannot be encoded.\n// TypeError 2056: (191-193): This type cannot be encoded.\n// TypeError 2056: (195-201): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_structs.sol",
    "content": "contract C {\n    struct S { uint x; }\n    S s;\n    struct T { uint y; }\n    T t;\n    function f() public view {\n        bytes32 a = sha256(abi.encodePacked(s, t));\n        a;\n    }\n}\n// ----\n// TypeError 9578: (156-157): Type not supported in packed mode.\n// TypeError 9578: (159-160): Type not supported in packed mode.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_types.sol",
    "content": "contract C {\n    struct S { uint x; }\n    S s;\n    struct T { uint y; }\n    T t;\n    enum A { X, Y }\n    function f() public pure {\n        bytes memory a = abi.encodePacked(S, A, A.X, T, uint, uint[]);\n        a;\n    }\n}\n// ----\n// TypeError 2056: (174-175): This type cannot be encoded.\n// TypeError 2056: (177-178): This type cannot be encoded.\n// TypeError 2056: (185-186): This type cannot be encoded.\n// TypeError 2056: (188-192): This type cannot be encoded.\n// TypeError 2056: (194-200): This type cannot be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/specialFunctions/types_without_encoding_problems.sol",
    "content": "contract C {\n    uint[3] sarr;\n    function f() view public {\n        uint[3] memory arr;\n        bytes32 h = keccak256(abi.encodePacked(this.f, arr, sarr));\n        h;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/abi_decode.sol",
    "content": "contract C layout at abi.decode(abi.encode(42), (uint)) {}\n// ----\n// TypeError 1505: (21-55): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract.sol",
    "content": "abstract contract C layout at 42 { }\n// ----\n// TypeError 7587: (20-32): Storage layout cannot be specified for abstract contracts.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/abstract_contract_inheriting_from_non_abstract.sol",
    "content": "contract A layout at 0x1234 {}\nabstract contract C is A { }\n// ----\n// TypeError 8894: (54-55): Cannot inherit from a contract with a custom storage layout.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/address.sol",
    "content": "contract C layout at address(0x1234) {}\n// ----\n// TypeError 1763: (21-36): The base slot of the storage layout must evaluate to an integer (the type is 'address' instead).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/address_constant.sol",
    "content": "address constant x = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF;\ncontract C layout at x {}\n// ----\n// TypeError 1763: (86-87): The base slot of the storage layout must evaluate to an integer (the type is 'address' instead).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/address_non_constant.sol",
    "content": "contract A {}\n\ncontract C layout at address(new A()) {}\ncontract D layout at uint160(address(this)) {}\n// ----\n// TypeError 1139: (36-52): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (77-99): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/array_literal.sol",
    "content": "contract C layout at [1, 2, 3] {}\n// ----\n// TypeError 1763: (21-30): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/assignment.sol",
    "content": "contract C layout at 1 = 2 { }\n// ----\n// TypeError 4247: (21-22): Expression has to be an lvalue.\n// TypeError 7407: (25-26): Type int_const 2 is not implicitly convertible to expected type int_const 1.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/at_before_layout.sol",
    "content": "contract C at layout 0x1234ABC { }\n// ----\n// ParserError 2314: (11-13): Expected '{' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/bitwise_negation_after_cast.sol",
    "content": "contract C layout at ~uint(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {}\n// ----\n// TypeError 1505: (21-94): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/bool_constant.sol",
    "content": "bool constant x = false;\ncontract C layout at x {}\n// ----\n// TypeError 1763: (46-47): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/boolean.sol",
    "content": "contract C layout at true {}\n// ----\n// TypeError 1763: (21-25): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/builtin_functions.sol",
    "content": "contract A layout at block.basefee { }\ncontract B layout at block.chainid { }\ncontract C layout at block.number { }\ncontract D layout at uint160(address(block.coinbase)) { }\ncontract E layout at block.prevrandao { }\ncontract F layout at uint(blockhash(0)) { }\ncontract G layout at msg.value { }\ncontract H layout at msg.sender { }\ncontract I layout at msg.data { }\ncontract J layout at tx.gasprice { }\ncontract K layout at uint160(tx.origin) { }\ncontract L layout at address(this).balance { }\ncontract M layout at uint(address(this).codehash) { }\n\n// ====\n// EVMVersion: >=paris\n// ----\n// TypeError 1139: (21-34): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (60-73): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (99-111): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (137-169): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (195-211): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (237-255): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (281-290): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (316-326): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (352-360): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (386-397): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (423-441): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (467-488): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (514-542): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/bytes_constant.sol",
    "content": "bytes32 constant CONST1 = \"12345\";\ncontract A layout at CONST1 {}\ncontract C layout at CONST1[1] {}\n// ----\n// TypeError 1763: (56-62): The base slot of the storage layout must evaluate to an integer (the type is 'bytes32' instead).\n// TypeError 1763: (87-96): The base slot of the storage layout must evaluate to an integer (the type is 'bytes1' instead).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/bytes_length_member.sol",
    "content": "contract C layout at bytes(\"ABCD\").length {}\n// ----\n// TypeError 1139: (21-41): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_its_negation.sol",
    "content": "uint constant N = 100;\ncontract C layout at N / ~N {}\n// ----\n// TypeError 3667: (48-50): Arithmetic error when computing constant value.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_divided_by_zero.sol",
    "content": "uint constant N = 100;\ncontract C layout at N / 0 {}\n// ----\n// TypeError 1505: (44-49): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_from_base_contract.sol",
    "content": "contract A {\n    uint constant x = 10;\n}\n\ncontract C is A layout at A.x { }\n// ----\n// TypeError 1505: (68-71): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_from_module.sol",
    "content": "==== Source: A ====\nuint constant x = 77;\n\n==== Source: B ====\nimport \"A\" as M;\ncontract C layout at M.x{ }\n// ----\n// TypeError 1505: (B:38-41): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_initialized_from_builtin.sol",
    "content": "uint constant x = addmod(10, 2, 8);\nuint constant y = mulmod(10, 2, 8);\ncontract C layout at x {}\ncontract D layout at y {}\n// ----\n// TypeError 1505: (93-94): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n// TypeError 1505: (119-120): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_initialized_from_cast.sol",
    "content": "uint constant x = uint(42);\ncontract C layout at x {}\n// ----\n// TypeError 1505: (49-50): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_initialized_from_other_constant.sol",
    "content": "uint constant x = 42;\nuint constant y = x * 2;\ncontract C layout at y {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_initialized_with_literal_expression.sol",
    "content": "uint constant x = ((2**5 + 2**5) * (2 ** 10 + 1 << 1)) % 2**256 - 1;\ncontract C layout at x {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/constant_initialized_with_unlimited_arithmetic_expression.sol",
    "content": "uint constant CONST1 = 1.23e100 / 2e50;\ncontract C layout at CONST1 {}\nuint constant CONST2 = 2**256 * (500e-3);\ncontract D layout at CONST2 {}\nuint constant CONST3 = (2**255 * 2) - (2**256 + 1) + 1;\ncontract E layout at CONST3 {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end.sol",
    "content": "contract C layout at 2**256 - 1 {\n}\n// ----\n// Warning 3495: (11-31): This contract is very close to the end of storage. This limits its future upgradability.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_at_storage_end_with_transient_state_variables.sol",
    "content": "contract C layout at 2**256 - 1 {\n    uint transient x;\n    uint transient y;\n    uint transient z;\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// Warning 3495: (11-31): This contract is very close to the end of storage. This limits its future upgradability.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_extends_past_storage_end.sol",
    "content": "contract C layout at 2**256 - 2 {\n    uint x;\n    bool b;\n}\n// ----\n// TypeError 5015: (21-31): Contract extends past the end of storage when this base slot value is specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_at.sol",
    "content": "contract at layout at 0x1234ABC { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_named_layout.sol",
    "content": "contract layout layout at 0x1234ABC { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_too_large_for_storage.sol",
    "content": "contract C layout at 1 {\n    uint[2**256 - 1] x;\n    uint y;\n}\n// ----\n// TypeError 7676: (0-62): Contract requires too much storage.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/contract_with_members_named_layout_and_at.sol",
    "content": "contract C layout at 0x1234 {\n    uint layout;\n    function at() public pure { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/delete.sol",
    "content": "contract C layout at delete 2 { }\n// ----\n// TypeError 4247: (28-29): Expression has to be an lvalue.\n// TypeError 9767: (21-29): Built-in unary operator delete cannot be applied to type int_const 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/division_by_zero.sol",
    "content": "contract A layout at 1 / 0 {}\n// ----\n// TypeError 2271: (21-26): Built-in binary operator / cannot be applied to types int_const 1 and int_const 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/duplicated_layout_definition.sol",
    "content": "contract C layout at 0x1234 is A, B layout at 0xABC { }\n// ----\n// ParserError 8714: (36-42): More than one storage layout definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/duplicated_layout_keyword.sol",
    "content": "contract C layout layout at 0x1234ABC { }\n// ----\n// ParserError 1994: (18-24): Expected 'at' but got identifier\n// ParserError 2314: (28-37): Expected '{' but got 'Number'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/enum.sol",
    "content": "enum Color {Red, Green, Blue}\n\ncontract C layout at Color.Red {}\n// ----\n// TypeError 1763: (52-61): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/erc7201_builtin_param_constant_variable_comptime.sol",
    "content": "string constant storageBase = \"myStorageBase\";\ncontract C layout at erc7201(storageBase) { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/erc7201_builtin_param_imported_constant_variable_comptime.sol",
    "content": "==== Source: A ====\nstring constant storageBase = \"myStorageBase\";\n==== Source: B ====\nimport \"A\";\ncontract C layout at erc7201(storageBase) {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/erc7201_builtin_param_string_literal_comptime.sol",
    "content": "contract C layout at erc7201(\"storageBase\") { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/function_address.sol",
    "content": "contract A {\n    function f() public pure {}\n}\n\ncontract C is A layout at this.f.address {}\n// ----\n// TypeError 1139: (74-88): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/function_declaration_layout_specified.sol",
    "content": "contract C {\n    function f() public pure layout at 32 { }\n}\n// ----\n// ParserError 2314: (52-54): Expected '{' but got 'Number'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/function_declaration_layout_with_no_expression.sol",
    "content": "contract C {\n    function f() public pure layout at { }\n}\n// ====\n// stopAfter: parsing\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/function_defined_in_other_contract.sol",
    "content": "contract A {\n    function f() external pure {}\n}\n\ncontract C layout at A.f { }\n// ----\n// TypeError 1763: (71-74): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/function_selector.sol",
    "content": "contract A {\n    function f() public {}\n}\ncontract C is A layout at uint32(this.f.selector) {}\n// ----\n// TypeError 1505: (68-91): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_address.sol",
    "content": "contract C layout at 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF {}\n// ----\n// TypeError 1763: (21-63): The base slot of the storage layout must evaluate to an integer (the type is 'address' instead).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string.sol",
    "content": "contract C layout at hex\"616263\" {}\n// ----\n// TypeError 1763: (21-32): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/hex_string_cast.sol",
    "content": "contract at layout at uint40(bytes5(hex\"0011223344\")) { }\n// ----\n// TypeError 1505: (22-53): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/immutables.sol",
    "content": "function f() returns (uint) {\n    return 2;\n}\n\ncontract A {\n    address immutable a = 0x0000000000000000000000000000000000000001;\n    uint immutable x = 1; // considered pure by the compiler (initialized with a literal)\n    uint immutable y = f(); // considered not pure by the compiler (initialized with a function)\n}\n\ncontract B is A layout at A.a { }\ncontract C is A layout at A.x { }\ncontract D is A layout at A.y { }\n// ----\n// TypeError 1139: (346-349): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (380-383): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (414-417): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/increment_operator.sol",
    "content": "contract C layout at ++2 { }\n// ----\n// TypeError 4247: (23-24): Expression has to be an lvalue.\n// TypeError 9767: (21-24): Built-in unary operator ++ cannot be applied to type int_const 2.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_abstract_contract.sol",
    "content": "abstract contract A { }\n\ncontract C layout at 42 is A { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_interface.sol",
    "content": "interface I { }\n\ncontract C layout at 42 is I { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/inheriting_from_itself.sol",
    "content": "contract C layout at 42 is C { }\n// ----\n// TypeError 2449: (27-28): Definition of base has to precede definition of derived contract\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/int_constant.sol",
    "content": "int constant x = -42;\nint constant y = 64;\ncontract C layout at x {}\ncontract D layout at y {}\n// ----\n// TypeError 6753: (64-65): The base slot of the storage layout evaluates to -42, which is outside the range of type uint256.\n// TypeError 1481: (90-91): Base slot expression of type 'int256' is not convertible to uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/interface.sol",
    "content": "interface I layout at 42 { }\n// ----\n// ParserError 2314: (12-18): Expected '{' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/intermediate_operation_out_of_range.sol",
    "content": "contract A layout at (2**256 + 1) * 2  - 2**256 - 3 {}\ncontract B layout at (2**2 - 2**3) * (2**5 - 2**8) {}\n// ----\n// Warning 3495: (11-51): This contract is very close to the end of storage. This limits its future upgradability.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_already_specified_in_ancestor_contract.sol",
    "content": "contract A layout at 0x1234 {}\n\ncontract B is A {}\n\ncontract C is B layout at 0xABCD {}\n// ----\n// TypeError 8894: (46-47): Cannot inherit from a contract with a custom storage layout.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_bitwise_negation_literal.sol",
    "content": "contract C layout at ~0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE {}\n// ----\n// TypeError 6753: (21-88): The base slot of the storage layout evaluates to -2**256 + 1, which is outside the range of type uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_fractional_number.sol",
    "content": "contract A layout at 3/2 {}\ncontract B layout at 4.2 {}\ncontract C layout at .1 {}\ncontract D layout at 42e-10 {}\ncontract E layout at 1_7e-10 {}\n// ----\n// TypeError 1763: (21-24): The base slot of the storage layout must evaluate to an integer.\n// TypeError 1763: (49-52): The base slot of the storage layout must evaluate to an integer.\n// TypeError 1763: (77-79): The base slot of the storage layout must evaluate to an integer.\n// TypeError 1763: (104-110): The base slot of the storage layout must evaluate to an integer.\n// TypeError 1763: (135-142): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_binary_expression.sol",
    "content": "contract C layout at 0xffff * (0x123 + 0xABC) { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_by_function.sol",
    "content": "function f() pure returns (uint256) {\n    return 128;\n}\ncontract C layout at f() { }\n// ----\n// TypeError 1139: (77-80): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_bytes.sol",
    "content": "bytes32 constant b = \"bytes\";\ncontract A layout at b[1] {}\n// ----\n// TypeError 1763: (51-55): The base slot of the storage layout must evaluate to an integer (the type is 'bytes1' instead).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_constant_in_expression.sol",
    "content": "uint constant X = 42;\ncontract C layout at 0xffff * (50 - X) { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_max_value.sol",
    "content": "contract C layout at 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF {}\n// ----\n// Warning 3495: (11-87): This contract is very close to the end of storage. This limits its future upgradability.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_no_expression.sol",
    "content": "contract C layout at { }\n// ----\n// ParserError 6933: (21-22): Expected primary expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_overflow_value.sol",
    "content": "contract A layout at 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 1 {}\ncontract B layout at 2**256 {}\n// ----\n// TypeError 6753: (21-91): The base slot of the storage layout evaluates to 2**256, which is outside the range of type uint256.\n// TypeError 6753: (116-122): The base slot of the storage layout evaluates to 2**256, which is outside the range of type uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specification_underflow_value.sol",
    "content": "contract A layout at 0 - 1 {}\ncontract B layout at 2**8 - 2**16 {}\n// ----\n// TypeError 6753: (21-26): The base slot of the storage layout evaluates to -1, which is outside the range of type uint256.\n// TypeError 6753: (51-63): The base slot of the storage layout evaluates to -65280, which is outside the range of type uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_ancestor_contract_module.sol",
    "content": "==== Source: C ====\nimport \"M\" as M;\nimport \"N\" as N;\n\ncontract C is M.A, N.A layout at 0xABCD {}\n==== Source: M ====\ncontract A layout at 0x1234 {}\n\n==== Source: N ====\ncontract A {}\n\n// ----\n// TypeError 8894: (C:49-52): Cannot inherit from a contract with a custom storage layout.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_ancestor_contract_multiple_inheritance.sol",
    "content": "contract A layout at 1 {}\ncontract B is A layout at 2 {}\n\ncontract C1 is B {}\ncontract C2 is A, B {}\ncontract C3 is B {}\n\ncontract D1 is C1 {}\ncontract D2 is C2 {}\ncontract D3 is C3 {}\n// ----\n// TypeError 8894: (40-41): Cannot inherit from a contract with a custom storage layout.\n// TypeError 8894: (73-74): Cannot inherit from a contract with a custom storage layout.\n// TypeError 8894: (93-94): Cannot inherit from a contract with a custom storage layout.\n// TypeError 8894: (96-97): Cannot inherit from a contract with a custom storage layout.\n// TypeError 8894: (116-117): Cannot inherit from a contract with a custom storage layout.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_attached_library_function.sol",
    "content": "library L {\n    function f(uint x) public pure returns (uint) {\n        return x * 2;\n    }\n}\n\n\ncontract C layout at 2.f() {\n    using L for *;\n}\n// ----\n// TypeError 1139: (117-122): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_bytes_concat.sol",
    "content": "contract C layout at uint64(bytes8(bytes.concat(\"ABCD\", \"EFGH\"))) {}\n// ----\n// TypeError 1505: (21-65): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_empty_braces.sol",
    "content": "contract C layout at { } { }\n// ----\n// ParserError 6933: (21-22): Expected primary expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_error.sol",
    "content": "error MyError();\ncontract C layout at MyError() {}\n// ----\n// TypeError 7757: (38-47): Errors can only be used with revert statements: \"revert MyError(args);\", or require functions: \"require(condition, MyError(args))\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_event.sol",
    "content": "event MyEvent();\ncontract C layout at MyEvent() {}\n// ----\n// TypeError 3132: (38-47): Event invocations have to be prefixed by \"emit\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_expression_not_pure.sol",
    "content": "function f(uint x) returns (uint) { return x + 1; }\ncontract A layout at f(2) {}\n// ----\n// TypeError 1139: (73-77): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_first_ancestor_contract.sol",
    "content": "contract A layout at 42 {}\ncontract B is A {}\ncontract C is B {}\ncontract D is C {}\n// ----\n// TypeError 8894: (41-42): Cannot inherit from a contract with a custom storage layout.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_empty_call_options.sol",
    "content": "contract A {\n    function f() external pure returns (uint) {}\n}\ncontract C is A layout at this.f{}() {}\n// ----\n// ParserError 7858: (98-99): Expected pragma, import directive or contract/interface/library/user-defined type/constant/function/error/event definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_function_with_call_options.sol",
    "content": "contract A {\n    function f() external payable returns (uint) {}\n}\ncontract C is A layout at this.f{value:123}() {}\n// ----\n// TypeError 1139: (93-112): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_interface_id.sol",
    "content": "interface I {}\n\ncontract C layout at uint(bytes32(type(I).interfaceId)) { }\n// ----\n// TypeError 1505: (37-71): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_kecak256.sol",
    "content": "contract C layout at uint(keccak256(bytes.concat(\"ABCD\"))) {}\n// ----\n// TypeError 1505: (21-58): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_last_ancestor_contract.sol",
    "content": "contract A {}\ncontract B is A {}\ncontract C is B layout at 42 {}\ncontract D is C {}\n// ----\n// TypeError 8894: (79-80): Cannot inherit from a contract with a custom storage layout.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_module.sol",
    "content": "==== Source: A ====\nfunction f() pure {}\n\n==== Source: B ====\nimport \"A\" as MyModule;\n\ncontract C layout at MyModule {}\n// ----\n// TypeError 1763: (B:46-54): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_other_contract.sol",
    "content": "contract A {}\ncontract C layout at A(address(0x1234)) {}\n// ----\n// TypeError 1763: (35-53): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_specified_by_type.sol",
    "content": "contract A layout at uint {}\n// ----\n// TypeError 1763: (21-25): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_statement_without_at.sol",
    "content": "contract C layout { }\n// ----\n// ParserError 1994: (18-19): Expected 'at' but got '{'\n// ParserError 6933: (20-21): Expected primary expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/layout_with_inheritance.sol",
    "content": "contract A { }\ncontract B { }\ncontract C is A, B layout at 0x1234 { }\ncontract D layout at 0xABCD is A, B { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/library.sol",
    "content": "library L layout at 42 { }\n// ----\n// ParserError 2314: (10-16): Expected '{' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_cast.sol",
    "content": "contract at layout at uint(42) { }\n// ----\n// TypeError 1505: (22-30): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/literal_with_underscore.sol",
    "content": "contract A layout at 42_0e10 {}\ncontract B layout at 0x1234_ABCD {}\ncontract C layout at 1234_000 {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/magic_variables.sol",
    "content": "contract A layout at this {}\ncontract B layout at super {}\ncontract C layout at msg {}\ncontract D layout at tx {}\ncontract E layout at block {}\n// ----\n// TypeError 1139: (21-25): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (50-55): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (80-83): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (108-110): The base slot of the storage layout must be a compile-time constant expression.\n// TypeError 1139: (135-140): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/multi_token_expression.sol",
    "content": "contract C layout at 5 minutes { }\ncontract D layout at 2 gwei { }\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/natspec.sol",
    "content": "contract C layout at\n    /**\n        @notice function f should return the value of the base slot for the contract's storage layout\n        @dev the value returned by f should be in the range of uint256\n    */\n    f()\n{ }\n// ====\n// stopAfter: parsing\n// ----"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/negative_number.sol",
    "content": "contract A layout at -1 {}\n// ----\n// TypeError 6753: (21-23): The base slot of the storage layout evaluates to -1, which is outside the range of type uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/precompiles.sol",
    "content": "contract A layout at addmod(1, 2, 3) {}\ncontract B layout at mulmod(3, 2, 1) {}\n// ----\n// TypeError 1505: (21-36): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n// TypeError 1505: (61-76): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/rational_number_without_fractional_part.sol",
    "content": "contract A layout at 42.0 {}\ncontract B layout at 2.5e10 {}\ncontract C layout at 12/3 {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/repeated_layout_definition.sol",
    "content": "contract C layout at 0x1234 layout at 0xABC layout at 0x4321 layout at 0xCBA { }\n// ----\n// ParserError 8714: (28-34): More than one storage layout definition.\n// ParserError 8714: (44-50): More than one storage layout definition.\n// ParserError 8714: (61-67): More than one storage layout definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/same_ancestor_two_contracts.sol",
    "content": "contract A {}\ncontract B is A layout at 64 {}\ncontract C is A layout at 42 {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/simple_layout.sol",
    "content": "contract A layout at 0x1234 {}\ncontract B layout at 1024 {}\ncontract C layout at 0 {}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_from_base_contract.sol",
    "content": "contract A {\n    uint public x = 10;\n}\n\ncontract C is A layout at A.x {}\n// ----\n// TypeError 1139: (66-69): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_getter_from_base_contract.sol",
    "content": "contract A {\n    uint public x = 10;\n}\n\ncontract C is A layout at this.x() {}\n// ----\n// TypeError 1139: (66-74): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/state_variable_layout_specifier.sol",
    "content": "contract C {\n    uint x layout at 0xF;\n}\n// ----\n// ParserError 2314: (24-30): Expected ';' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/string.sol",
    "content": "contract C layout at \"MyLayoutBase\" {}\n// ----\n// TypeError 1763: (21-35): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_defined_in_other_contract.sol",
    "content": "contract A {\n    struct SA {\n        uint x;\n        uint y;\n        bytes32 b;\n    }\n}\n\ncontract C is A layout at A.SA { }\n// ----\n// TypeError 1139: (115-119): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/struct_with_layout_specifier.sol",
    "content": "struct S layout at 23 { }\n// ----\n// ParserError 2314: (9-15): Expected '{' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/ternary_operator.sol",
    "content": "contract A layout at true ? 42 : 94 {}\ncontract B layout at 255 + (true ? 1 : 0) {}\n// ----\n// TypeError 1505: (21-35): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n// TypeError 1505: (60-80): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/tuple.sol",
    "content": "contract C layout at (1, 2, 3) {}\n// ----\n// TypeError 1763: (21-30): The base slot of the storage layout must evaluate to an integer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/type_uint_max.sol",
    "content": "contract at layout at type(uint).max { }\n// ----\n// TypeError 1505: (22-36): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_operators.sol",
    "content": "type MyUint is uint;\n\nusing {add as +} for MyUint global;\nfunction add(MyUint a, MyUint b) pure returns (MyUint) {\n    return MyUint.wrap(2);\n}\n\ncontract C layout at MyUint.wrap(1) + MyUint.wrap(2) {}\n// ----\n// TypeError 1139: (166-197): The base slot of the storage layout must be a compile-time constant expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type.sol",
    "content": "type MyUint is uint128;\nMyUint constant x = MyUint.wrap(42);\ncontract C layout at x {}\n// ----\n// TypeError 1763: (82-83): The base slot of the storage layout must evaluate to an integer (the type is 'MyUint' instead).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_unwrap.sol",
    "content": "type MyUint is uint128;\nMyUint constant x = MyUint.wrap(42);\ncontract C layout at MyUint.unwrap(x) {}\n// ----\n// TypeError 1505: (82-98): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/user_defined_value_type_wrap.sol",
    "content": "type MyUint is uint128;\ncontract C layout at MyUint.wrap(42) {}\n// ----\n// TypeError 1763: (45-60): The base slot of the storage layout must evaluate to an integer (the type is 'MyUint' instead).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_array_literal.sol",
    "content": "contract A layout at [1, 2, 3][0] {}\ncontract B layout at 255 + [1, 2, 3][0] {}\n// ----\n// TypeError 1505: (21-33): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n// TypeError 1505: (58-76): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/value_from_bytes.sol",
    "content": "bytes32 constant b = \"Solidity\";\ncontract C layout at uint8(b[1]) {}\n// ----\n// TypeError 1505: (54-65): The base slot expression contains elements that are not yet supported by the internal constant evaluator and therefore cannot be evaluated at compilation time.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/storageLayoutSpecifier/warning_near_the_storage_end.sol",
    "content": "contract A layout at 2**256 - 2**64 {}\ncontract C layout at 2**256 - 2**65 {\n    uint[2**63] x;\n    uint[2**63] y;\n}\n// ----\n// Warning 3495: (11-35): This contract is very close to the end of storage. This limits its future upgradability.\n// Warning 3495: (50-74): This contract is very close to the end of storage. This limits its future upgradability.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/concat/string_concat_empty_invalid.sol",
    "content": "contract C {\n    function g() public pure returns (string memory) {\n        return string.concat;\n    }\n}\n// ----\n// TypeError 6359: (83-96): Return argument type function () pure returns (string memory) is not implicitly convertible to expected type (type of first return variable) string memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/concat/string_concat_with_different_parameters.sol",
    "content": "contract C {\n    function j() external {\n        string memory a = \"hello\";\n        string memory b = \" world\";\n\n        string memory d = string.concat(bytes(a), bytes(b));\n        string memory e = string.concat(a, 0);\n    }\n}\n// ----\n// TypeError 9977: (153-161): Invalid type for argument in the string.concat function call. string type is required, but t_bytes_memory_ptr provided.\n// TypeError 9977: (163-171): Invalid type for argument in the string.concat function call. string type is required, but t_bytes_memory_ptr provided.\n// TypeError 9977: (217-218): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/concat/string_concat_wrong_type_bytes_and_strings.sol",
    "content": "contract C {\n    string s;\n    function f(string calldata c, string calldata c1) public {\n        string memory a;\n        bytes16 b;\n        uint8[] memory num;\n        bytes1[] memory m;\n        string memory d = string.concat(a, b, c, num, s, \"abc\", m, c1, bytes(c1));\n    }\n}\n// ----\n// TypeError 9977: (232-233): Invalid type for argument in the string.concat function call. string type is required, but t_bytes16 provided.\n// TypeError 9977: (238-241): Invalid type for argument in the string.concat function call. string type is required, but t_array$_t_uint8_$dyn_memory_ptr provided.\n// TypeError 9977: (253-254): Invalid type for argument in the string.concat function call. string type is required, but t_array$_t_bytes1_$dyn_memory_ptr provided.\n// TypeError 9977: (260-269): Invalid type for argument in the string.concat function call. string type is required, but t_bytes_calldata_ptr provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/concat/string_concat_wrong_type_empty_array_literal.sol",
    "content": "contract C {\n    function f() public {\n        string.concat([], [], []);\n    }\n}\n// ----\n// TypeError 6378: (61-63): Unable to deduce common type for array elements.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/concat/string_concat_wrong_type_misc.sol",
    "content": "contract C {\n    struct S {\n        uint x;\n    }\n\n    enum E {A, B, C}\n\n    mapping(uint => E) m;\n\n    function f() public {\n        bool b;\n        uint u;\n        uint8 u8;\n        address a;\n        address payable ap;\n        function () external fext;\n        function () internal fint;\n        uint[] memory uDynamic;\n        uint[2] memory uStatic;\n        C c;\n        S memory s;\n        E e;\n\n        string.concat(b, u, u8, a, ap, fext, fint, uDynamic, uStatic, c, s, e, m);\n    }\n}\n// ----\n// TypeError 9977: (426-427): Invalid type for argument in the string.concat function call. string type is required, but t_bool provided.\n// TypeError 9977: (429-430): Invalid type for argument in the string.concat function call. string type is required, but t_uint256 provided.\n// TypeError 9977: (432-434): Invalid type for argument in the string.concat function call. string type is required, but t_uint8 provided.\n// TypeError 9977: (436-437): Invalid type for argument in the string.concat function call. string type is required, but t_address provided.\n// TypeError 9977: (439-441): Invalid type for argument in the string.concat function call. string type is required, but t_address_payable provided.\n// TypeError 9977: (443-447): Invalid type for argument in the string.concat function call. string type is required, but t_function_external_nonpayable$__$returns$__$ provided.\n// TypeError 9977: (449-453): Invalid type for argument in the string.concat function call. string type is required, but t_function_internal_nonpayable$__$returns$__$ provided.\n// TypeError 9977: (455-463): Invalid type for argument in the string.concat function call. string type is required, but t_array$_t_uint256_$dyn_memory_ptr provided.\n// TypeError 9977: (465-472): Invalid type for argument in the string.concat function call. string type is required, but t_array$_t_uint256_$2_memory_ptr provided.\n// TypeError 9977: (474-475): Invalid type for argument in the string.concat function call. string type is required, but t_contract$_C_$86 provided.\n// TypeError 9977: (477-478): Invalid type for argument in the string.concat function call. string type is required, but t_struct$_S_$4_memory_ptr provided.\n// TypeError 9977: (480-481): Invalid type for argument in the string.concat function call. string type is required, but t_enum$_E_$8 provided.\n// TypeError 9977: (483-484): Invalid type for argument in the string.concat function call. string type is required, but t_mapping$_t_uint256_$_t_enum$_E_$8_$ provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/concat/string_concat_wrong_type_misc_literals_and_expressions.sol",
    "content": "contract C {\n    struct S {\n        uint x;\n    }\n\n    enum E {A, B, C}\n\n    function f() public {\n        string.concat(\n            false,\n            1,\n            1e10,\n            1e-10,\n            0.1,\n            0x1234567,\n            0x11112222333344445555666677778888999900,     // One byte less than an address\n            0x1111222233334444555566667777888899990000,   // Address\n            0x111122223333444455556666777788889999000011, // One byte more than an address\n            0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff,  // exactly 32 bytes\n            -0x0000000000000000000000000000000000000000000000000000000000000001, // exactly 32 bytes\n            bytes(bytes32(0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff))[:],\n            f,\n            (),\n            (0, 0),\n            [0],\n            [0][:],\n            [0][0],\n            new C(),\n            S(0),\n            E.A\n        );\n    }\n}\n// ----\n// TypeError 9640: (698-780): Explicit type conversion not allowed from \"bytes32\" to \"bytes memory\".\n// TypeError 1227: (698-783): Index range access is only supported for dynamic calldata arrays.\n// TypeError 1227: (865-871): Index range access is only supported for dynamic calldata arrays.\n// TypeError 9977: (134-139): Invalid type for argument in the string.concat function call. string type is required, but t_bool provided.\n// TypeError 9977: (153-154): Invalid type for argument in the string.concat function call. string type is required, but t_rational_1_by_1 provided.\n// TypeError 9977: (168-172): Invalid type for argument in the string.concat function call. string type is required, but t_rational_10000000000_by_1 provided.\n// TypeError 9977: (186-191): Invalid type for argument in the string.concat function call. string type is required, but t_rational_1_by_10000000000 provided.\n// TypeError 9977: (205-208): Invalid type for argument in the string.concat function call. string type is required, but t_rational_1_by_10 provided.\n// TypeError 9977: (222-231): Invalid type for argument in the string.concat function call. string type is required, but t_rational_19088743_by_1 provided.\n// TypeError 9977: (245-285): Invalid type for argument in the string.concat function call. string type is required, but t_rational_380605192295934637532253317235440047844071680_by_1 provided.\n// TypeError 9977: (336-378): Invalid type for argument in the string.concat function call. string type is required, but t_address provided.\n// TypeError 9977: (405-449): Invalid type for argument in the string.concat function call. string type is required, but t_rational_24943341882306372405313753398341798975509081620497_by_1 provided.\n// TypeError 9977: (496-562): Invalid type for argument in the string.concat function call. string type is required, but t_rational_30272441630670900764332283662402067049651745785153368133042924362431065855_by_1 provided.\n// TypeError 9977: (597-664): Invalid type for argument in the string.concat function call. string type is required, but t_rational_minus_1_by_1 provided.\n// TypeError 9977: (698-783): Invalid type for argument in the string.concat function call. string type is required, but t_bytes_memory_ptr_slice provided.\n// TypeError 9977: (797-798): Invalid type for argument in the string.concat function call. string type is required, but t_function_internal_nonpayable$__$returns$__$ provided.\n// TypeError 9977: (812-814): Invalid type for argument in the string.concat function call. string type is required, but t_tuple$__$ provided.\n// TypeError 9977: (828-834): Invalid type for argument in the string.concat function call. string type is required, but t_tuple$_t_rational_0_by_1_$_t_rational_0_by_1_$ provided.\n// TypeError 9977: (848-851): Invalid type for argument in the string.concat function call. string type is required, but t_array$_t_uint8_$1_memory_ptr provided.\n// TypeError 9977: (865-871): Invalid type for argument in the string.concat function call. string type is required, but t_array$_t_uint8_$1_memory_ptr_slice provided.\n// TypeError 9977: (885-891): Invalid type for argument in the string.concat function call. string type is required, but t_uint8 provided.\n// TypeError 9977: (905-912): Invalid type for argument in the string.concat function call. string type is required, but t_contract$_C_$61 provided.\n// TypeError 9977: (926-930): Invalid type for argument in the string.concat function call. string type is required, but t_struct$_S_$4_memory_ptr provided.\n// TypeError 9977: (944-947): Invalid type for argument in the string.concat function call. string type is required, but t_enum$_E_$8 provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/concat/string_concat_wrong_type_zero_literal.sol",
    "content": "contract C {\n    function f() public pure {\n        string.concat(\n            0,\n            -0,\n            0.0,\n            -0.0,\n            0e10,\n            -0e10,\n            0e-10,\n            -0e-10,\n            (0),\n            0x00,\n            -0x00,\n            0x0000000000000000000000000000000000000000000000000000000000000000, // exactly 32 bytes\n            -0x0000000000000000000000000000000000000000000000000000000000000000 // exactly 32 bytes\n        );\n    }\n}\n// ----\n// TypeError 9977: (79-80): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (94-96): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (110-113): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (127-131): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (145-149): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (163-168): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (182-187): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (201-207): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (221-224): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (238-242): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (256-261): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (275-341): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n// TypeError 9977: (375-442): Invalid type for argument in the string.concat function call. string type is required, but t_rational_0_by_1 provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/control_character_returned_in_string.sol",
    "content": "contract test {\n    function f() public pure returns (string memory) {\n        return \"\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b;\n    }\n}\n// ----\n// ParserError 8936: (86-88): Invalid character in string. If you are trying to use Unicode characters, use a unicode\"...\" string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/hex_as_identifier.sol",
    "content": "function g() pure {\n    assembly { let hex := 1 }\n}\n// ----\n// ParserError 2314: (39-42): Expected identifier but got 'ILLEGAL'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/invalid_legacy_escape.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = \"\\t\\b\\f\";\n        return escapeCharacters;\n    }\n}\n// ----\n// ParserError 8936: (100-105): Invalid escape sequence.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/invalid_utf8_explicit_string.sol",
    "content": "contract C {\n    string s = string(\"\\xa0\\x00\");\n}\n// ----\n// TypeError 9640: (28-46): Explicit type conversion not allowed from \"literal_string hex\"a000\"\" to \"string memory\". Contains invalid UTF-8 sequence at position 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/invalid_utf8_hex_string.sol",
    "content": "contract C {\n    string s = hex\"a000\";\n}\n// ----\n// TypeError 7407: (28-37): Type literal_string hex\"a000\" is not implicitly convertible to expected type string storage ref. Contains invalid UTF-8 sequence at position 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/invalid_utf8_implicit_string.sol",
    "content": "contract C {\n    string s = \"\\xa0\\x00\";\n}\n// ----\n// TypeError 7407: (28-38): Type literal_string hex\"a000\" is not implicitly convertible to expected type string storage ref. Contains invalid UTF-8 sequence at position 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/invalid_utf8_in_bytes.sol",
    "content": "contract C {\n    bytes b1 = \"\\xa0\\x00\";\n    bytes32 b2 = \"\\xa0\\x00\";\n    bytes b3 = hex\"a000\";\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/invalid_utf8_sequence.sol",
    "content": "contract C {\n    string s = unicode\"\";\n}\n// ----\n// SyntaxError 8452: (28-38): Contains invalid UTF-8 sequence at position 0.\n// TypeError 7407: (28-38): Type literal_string hex\"c0\" is not implicitly convertible to expected type string storage ref. Contains invalid UTF-8 sequence at position 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/large_utf8_codepoint.sol",
    "content": "contract C {\n    string s = \"\\xf0\\x9f\\xa6\\x84\";\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_ascii.sol",
    "content": "contract test {\n    function f() public pure returns (string memory) {\n        return \"hello world\";\n    }\n    function g() public pure returns (string memory) {\n        return unicode\"hello world\";\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_escapes.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = \"\\n\\r\\'\\\"\\\\\";\n        return escapeCharacters;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_multipart_hex_valid_parts.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = hex\"aa\" hex\"b\";\n        return escapeCharacters;\n    }\n}\n// ----\n// ParserError 5428: (108-112): Expected even number of hex-nibbles.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_multipart_newline_with_hex_prefix.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = hex\"0000\"\n        hex\"deaf\"\n        hex\"feed\";\n        return escapeCharacters;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_multipart_newline_without_hex_prefix.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = hex\"0000\"\n        \"deaf\"\n        \"feed\";\n        return escapeCharacters;\n    }\n}\n// ----\n// ParserError 2314: (118-124): Expected ';' but got 'StringLiteral'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_multipart_only_hex.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = hex\"aa\" hex\"bb\" \"cc\";\n        return escapeCharacters;\n    }\n}\n// ----\n// ParserError 2314: (116-120): Expected ';' but got 'StringLiteral'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_multipart_only_regular.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = \"foo\" \"bar\" hex\"aa\";\n        return escapeCharacters;\n    }\n}\n// ----\n// ParserError 2314: (112-119): Expected ';' but got 'HexStringLiteral'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_multipart_single_line.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = \"first\" \"second\" \"third\";\n        return escapeCharacters;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_multipart_unicode.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = unicode\"foo\" unicode\"😃, 😭, and 😈\" unicode\"!\";\n        return escapeCharacters;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_multipart_unicode_mixed.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = \"foo\" hex\"aa\" unicode\"😃, 😭, and 😈\" \"!\" hex\"00\";\n        return escapeCharacters;\n    }\n}\n// ----\n// ParserError 2314: (106-113): Expected ';' but got 'HexStringLiteral'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_new_line.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = \"This a test\n        \";\n        return escapeCharacters;\n    }\n}\n// ----\n// ParserError 8936: (100-112): Expected string end-quote.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_terminated_by_backslash.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = \"text \\\";\n        return escapeCharacters;\n    }\n}\n// ----\n// ParserError 8936: (100-109): Expected string end-quote.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_unicode.sol",
    "content": "contract test {\n    function f() public pure returns (string memory) {\n        return unicode\"😃, 😭, and 😈\";\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_unicode_without_prefix.sol",
    "content": "contract test {\n    function f() public pure returns (string memory) {\n        return \"😃, 😭, and 😈\";\n    }\n}\n// ----\n// ParserError 8936: (86-88): Invalid character in string. If you are trying to use Unicode characters, use a unicode\"...\" string literal.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_unterminated.sol",
    "content": "contract test {\n    function f() public pure returns (bytes32) {\n        bytes32 escapeCharacters = \"This a test\n    }\n}\n// ----\n// ParserError 8936: (100-112): Expected string end-quote.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/string_unterminated_no_new_line.sol",
    "content": "contract test {\n    function f() pure public { \"abc\\\n// ----\n// ParserError 8936: (47-53): Expected string end-quote.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/unicode_escape_literals.sol",
    "content": "contract test {\n    function oneByteUTF8() public pure returns (bytes32) {\n        bytes32 usdollar = \"aaa\\u0024aaa\";\n        return usdollar;\n    }\n\n    function twoBytesUTF8() public pure returns (bytes32) {\n        bytes32 cent = \"aaa\\u00A2aaa\";\n        return cent;\n    }\n\n    function threeBytesUTF8() public pure returns (bytes32) {\n        bytes32 eur = \"aaa\\u20ACaaa\";\n        return  eur;\n    }\n\n    function combined() public pure returns (bytes32) {\n        bytes32 res = \"\\u0024\\u00A2\\u20AC\";\n        return res;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/unicode_escape_literals_invalid_codepoint.sol",
    "content": "contract test {\n    function f() public pure returns (string memory) {\n        return \"\\xc1\";\n    }\n}\n// ----\n// TypeError 6359: (86-92): Return argument type literal_string hex\"c1\" is not implicitly convertible to expected type (type of first return variable) string memory. Contains invalid UTF-8 sequence at position 0.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/string/unicode_escape_literals_invalid_format.sol",
    "content": "contract test {\n    // this function returns an invalid unicode character\n    function invalidLiteral() public pure returns (bytes32) {\n        bytes32 invalid = \"\\u00xx\";\n        return invalid;\n    }\n\n}\n// ----\n// ParserError 8936: (162-165): Invalid escape sequence.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/address_member_access.sol",
    "content": "contract C {\n    struct S { uint a; }\n    function f() public pure returns(address) {\n        S memory s = S(42);\n        return s.address;\n    }\n}\n// ----\n// TypeError 9582: (129-138): Member \"address\" not found or not visible after argument-dependent lookup in struct C.S memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/address_member_declaration.sol",
    "content": "contract C {\n    struct S { uint address; }\n}\n// ----\n// ParserError 2314: (33-40): Expected identifier but got 'address'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/array_calldata.sol",
    "content": "pragma abicoder               v2;\ncontract Test {\n    struct S { int a; }\n    function f(S[] calldata) external { }\n    function f(S[][] calldata) external { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/calldata.sol",
    "content": "pragma abicoder               v2;\ncontract Test {\n    struct S { int a; }\n    function f(S calldata) external { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/calldata_array_assign.sol",
    "content": "pragma abicoder               v2;\ncontract Test {\n    struct S { int[3] a; }\n    function f(S calldata s, int[3] calldata a) external {\n        s.a = a;\n    }\n}\n// ----\n// TypeError 4156: (144-147): Calldata structs are read-only.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/calldata_assign.sol",
    "content": "pragma abicoder               v2;\ncontract Test {\n    struct S { int a; }\n    function f(S calldata s) external { s.a = 4; }\n}\n// ----\n// TypeError 4156: (114-117): Calldata structs are read-only.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/calldata_dynamic.sol",
    "content": "pragma abicoder               v2;\ncontract Test {\n\tstruct S { int[] a; }\n\tfunction f(S calldata) external { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/calldata_struct_function_type.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    struct S { function (uint) external returns (uint) fn; }\n    function f(S calldata s) external returns (uint256 a) {\n        return s.fn(42);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/calldata_struct_mapping_function.sol",
    "content": "pragma abicoder               v2;\n\ncontract test {\n    struct S {\n        T t;\n    }\n    struct T {\n        mapping (uint => uint) k;\n    }\n    function f(S calldata b) external {\n    }\n}\n// ----\n// TypeError 4103: (155-167): Types containing (nested) mappings can only be parameters or return variables of internal or library functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/contract_global_struct_name_clash.sol",
    "content": "contract S {}\nstruct S { uint256 a; }\n// ----\n// DeclarationError 2333: (14-37): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/empty_struct.sol",
    "content": "contract test {\n\tstruct A {}\n}\n// ----\n// SyntaxError 5306: (17-28): Defining empty structs is disallowed.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/global_struct.sol",
    "content": "struct S { uint a; }\ncontract C {\n    function f() public pure {\n        S memory s = S(42);\n        s;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/global_struct_contract_name_clash.sol",
    "content": "struct S { uint256 a; }\ncontract S {}\n// ----\n// DeclarationError 2333: (24-37): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/global_struct_shadowing.sol",
    "content": "struct S { uint a; }\ncontract C {\n    struct S { address x; }\n    function f() public view {\n        S memory s = S(address(this));\n        s;\n    }\n}\n// ----\n// Warning 2519: (38-61): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/global_structs_name_clash.sol",
    "content": "struct S { uint256 a; }\nstruct S { uint256 a; }\n// ----\n// DeclarationError 2333: (24-47): Identifier already declared.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/illegal_names.sol",
    "content": "struct this { uint a; }\nstruct super { uint b; }\nstruct _ { uint c; }\n\ncontract C {\n\tthis a;\n\tsuper b;\n\t_ c;\n}\n// ----\n// DeclarationError 3726: (0-23): The name \"this\" is reserved.\n// DeclarationError 3726: (24-48): The name \"super\" is reserved.\n// DeclarationError 3726: (49-69): The name \"_\" is reserved.\n// Warning 2319: (0-23): This declaration shadows a builtin symbol.\n// Warning 2319: (24-48): This declaration shadows a builtin symbol.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/member_type_eq_name.sol",
    "content": "contract C {\n  struct S {t t;}\n  function f(function(S memory) external) public {}\n}\n// ----\n// DeclarationError 7920: (25-26): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/member_type_eq_name_2.sol",
    "content": "contract C {\n    enum E {a, b, c}\n    struct S {E X; uint E;}\n    struct T {E T; uint E;}\n    struct U {E E;}\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/member_type_eq_name_3.sol",
    "content": "contract C {\n    enum E {a, b, c}\n    struct S {function (E X) external f; uint E;}\n    struct T {function (E T) external f; uint E;}\n    struct U {function (E E) external f;}\n}\n// ----\n// Warning 6162: (58-61): Naming function type parameters is deprecated.\n// Warning 6162: (108-111): Naming function type parameters is deprecated.\n// Warning 6162: (158-161): Naming function type parameters is deprecated.\n// Warning 2519: (108-111): This declaration shadows an existing declaration.\n// Warning 2519: (158-161): This declaration shadows an existing declaration.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/member_type_func.sol",
    "content": "contract C {\n  function f() public {}\n  struct S {f x;}\n  function g(function(S memory) external) public {}\n}\n// ----\n// TypeError 5172: (50-51): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/memory_to_calldata.sol",
    "content": "pragma abicoder               v2;\ncontract Test {\n    struct S { int a; }\n    function f(S calldata s) external { s = S(2); }\n    function g(S calldata s) external { S memory m; s = m; }\n}\n// ----\n// TypeError 7407: (118-122): Type struct Test.S memory is not implicitly convertible to expected type struct Test.S calldata.\n// TypeError 7407: (182-183): Type struct Test.S memory is not implicitly convertible to expected type struct Test.S calldata.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/multi_struct_composition.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n  struct T { U u; V v; }\n\n  struct U { W w; }\n\n  struct V { W w; }\n\n  struct W { uint x; }\n\n  function f(T memory) public pure { }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/parallel_structs.sol",
    "content": "pragma abicoder               v2;\n\ncontract TestContract\n{\n    struct SubStruct {\n        uint256 id;\n    }\n    struct TestStruct {\n        SubStruct subStruct1;\n        SubStruct subStruct2;\n    }\n    function addTestStruct(TestStruct memory) public pure {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/recursive_struct_as_contract_function_parameter.sol",
    "content": "pragma abicoder               v2;\n\ncontract Test {\n    struct MyStructName {\n        address addr;\n        MyStructName[] x;\n    }\n\n    function f(MyStructName memory s) public {}\n}\n// ----\n// TypeError 4103: (147-168): Recursive type not allowed for public or external contract functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/recursive_struct_as_library_function_parameter.sol",
    "content": "library Test {\n    struct MyStructName {\n        address addr;\n        MyStructName[] x;\n    }\n\n    function f(MyStructName storage s) public {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/recursive_struct_as_memory_library_function_parameter.sol",
    "content": "pragma abicoder               v2;\n\nlibrary Test {\n    struct MyStructName {\n        address addr;\n        MyStructName[] x;\n    }\n\n    function f(MyStructName memory _x) public {\n    }\n}\n// ----\n// TypeError 4103: (146-168): Recursive structs can only be passed as storage pointers to libraries, not as memory objects to contract functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/recursive_struct_forward_reference.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    function f(Data.S memory a) public {}\n}\ncontract Data {\n    struct S { S[] x; }\n}\n// ----\n// TypeError 4103: (63-78): Recursive type not allowed for public or external contract functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/recursive_struct_function_pointer.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n    struct S {\n        uint a;\n        function() external returns (S memory) sub;\n    }\n    function f() public pure returns (S memory) {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/recursive_struct_nested_mapping_memory.sol",
    "content": "library a {\n    struct b {\n        mapping (uint => b) c ;\n    }\n    // Segfaults in https://github.com/argotorg/solidity/issues/9443\n    function d(b memory) public {}\n}\n// ----\n// TypeError 4103: (149-157): Recursive structs can only be passed as storage pointers to libraries, not as memory objects to contract functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/recursive_struct_nested_mapping_storage.sol",
    "content": "library a {\n    struct b {\n        mapping (uint => b) c ;\n    }\n    function d(b storage) public {}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/recursive_struct_with_internal_function_as_library_function_parameter.sol",
    "content": "library Test {\n    struct MyStructName {\n        address addr;\n        MyStructName[] x;\n        function() internal y;\n    }\n\n    function f(MyStructName storage s) public {}\n}\n// ----\n// TypeError 4103: (142-164): Internal type is not allowed for public or external functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { uint a; S[] sub; }\n    function f() public pure returns (uint, S memory) {\n    }\n}\n// ----\n// TypeError 4103: (126-134): Recursive type not allowed for public or external contract functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs2.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { uint a; S[2][] sub; }\n    function f() public pure returns (uint, S memory) {\n    }\n}\n// ----\n// TypeError 4103: (129-137): Recursive type not allowed for public or external contract functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs3.sol",
    "content": "pragma abicoder               v2;\n\ncontract C {\n    struct S { uint a; S[][][] sub; }\n    struct T { S s; }\n    function f() public pure returns (uint x, T memory t) {\n    }\n}\n// ----\n// TypeError 4103: (154-164): Recursive type not allowed for public or external contract functions.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/static_array_of_recursive_structs.sol",
    "content": "contract Test {\n    struct RecursiveStruct {\n        RecursiveStruct[] vals;\n    }\n\n    function func() private pure {\n        RecursiveStruct[1] memory val;\n        val;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive.sol",
    "content": "contract Test {\n    struct MyStructName {\n        address addr;\n        MyStructName x;\n    }\n}\n// ----\n// TypeError 2046: (20-93): Recursive struct definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive_dynamic_array.sol",
    "content": "contract Test {\n    struct MyStructName {\n        address addr;\n        MyStructName[] x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive_fixed_array.sol",
    "content": "contract Test {\n    struct MyStructName {\n        address addr;\n        MyStructName[1] x;\n    }\n}\n// ----\n// TypeError 2046: (20-96): Recursive struct definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive.sol",
    "content": "contract Test {\n    struct MyStructName1 {\n        address addr;\n        uint256 count;\n        MyStructName2 x;\n    }\n    struct MyStructName2 {\n        MyStructName1 x;\n    }\n}\n// ----\n// TypeError 2046: (20-118): Recursive struct definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_complex.sol",
    "content": "contract Test {\n    struct MyStructName1 {\n        address addr;\n        uint256 count;\n        MyStructName4[1] x;\n    }\n    struct MyStructName2 {\n        MyStructName1 x;\n    }\n    struct MyStructName3 {\n        MyStructName2[1] x;\n    }\n    struct MyStructName4 {\n        MyStructName3 x;\n    }\n}\n// ----\n// TypeError 2046: (20-121): Recursive struct definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array1.sol",
    "content": "contract Test {\n    struct MyStructName1 {\n        address addr;\n        uint256 count;\n        MyStructName2[] x;\n    }\n    struct MyStructName2 {\n        MyStructName1 x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array2.sol",
    "content": "contract Test {\n    struct MyStructName1 {\n        address addr;\n        uint256 count;\n        MyStructName2 x;\n    }\n    struct MyStructName2 {\n        MyStructName1[] x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array3.sol",
    "content": "contract Test {\n    struct MyStructName1 {\n        address addr;\n        uint256 count;\n        MyStructName2[] x;\n    }\n    struct MyStructName2 {\n        MyStructName1[] x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_multi_array.sol",
    "content": "contract Test {\n    struct S1 {\n        S2[1][] x;\n    }\n    struct S2 {\n        S1 x;\n    }\n    struct T1 {\n        T2[][1] x;\n    }\n    struct T2 {\n        T1 x;\n    }\n    struct R1 {\n        R2[][] x;\n    }\n    struct R2 {\n        R1 x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array1.sol",
    "content": "contract Test {\n    struct MyStructName1 {\n        address addr;\n        uint256 count;\n        MyStructName2[1] x;\n    }\n    struct MyStructName2 {\n        MyStructName1 x;\n    }\n}\n// ----\n// TypeError 2046: (20-121): Recursive struct definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array2.sol",
    "content": "contract Test {\n    struct MyStructName1 {\n        address addr;\n        uint256 count;\n        MyStructName2 x;\n    }\n    struct MyStructName2 {\n        MyStructName1[1] x;\n    }\n}\n// ----\n// TypeError 2046: (20-118): Recursive struct definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array3.sol",
    "content": "contract Test {\n    struct MyStructName1 {\n        address addr;\n        uint256 count;\n        MyStructName2[1] x;\n    }\n    struct MyStructName2 {\n        MyStructName1[1] x;\n    }\n}\n// ----\n// TypeError 2046: (20-121): Recursive struct definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_multi_array.sol",
    "content": "contract Test {\n    struct MyStructName1 {\n        address addr;\n        uint256 count;\n        MyStructName2[1][1] x;\n    }\n    struct MyStructName2 {\n        MyStructName1 x;\n    }\n}\n// ----\n// TypeError 2046: (20-124): Recursive struct definition.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_not_really_recursive.sol",
    "content": "contract Test {\n    struct S1 { uint a; }\n    struct S2 { S1 x; S1 y; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_not_really_recursive_array.sol",
    "content": "contract Test {\n    struct S1 { uint a; }\n    struct S2 { S1[1] x; S1[1] y; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/recursion/struct_definition_recursion_via_mapping.sol",
    "content": "contract Test {\n    struct MyStructName1 {\n        address addr;\n        uint256 count;\n        mapping(uint => MyStructName1) x;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/structs/transient_data_location_member.sol",
    "content": "struct S {\n    int transient x;\n}\n// ----\n// ParserError 2314: (29-30): Expected ';' but got identifier\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/super/super_in_function.sol",
    "content": "contract C {\n}\nfunction f() pure {\n    super;\n}\n// ----\n// DeclarationError 7576: (39-44): Undeclared identifier. \"super\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/super/super_in_library.sol",
    "content": "library L {\n  function f() public {\n    (super);\n  }\n}\n// ----\n// DeclarationError 7576: (41-46): Undeclared identifier. \"super\" is not (or not yet) visible at this point.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/super/unimplemented_super_function.sol",
    "content": "abstract contract a {\n    function f() virtual public;\n}\ncontract b is a {\n    function f() public override { super.f(); }\n}\n// ----\n// TypeError 9582: (110-117): Member \"f\" not found or not visible after argument-dependent lookup in type(contract super b).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/super/unimplemented_super_function_derived.sol",
    "content": "abstract contract a {\n    function f() virtual public;\n}\ncontract b is a {\n    function f() public virtual override { super.f(); }\n}\ncontract c is a,b {\n    // No error here.\n    function f() public override(a, b) { super.f(); }\n}\n// ----\n// TypeError 9582: (118-125): Member \"f\" not found or not visible after argument-dependent lookup in type(contract super b).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/almost_call_options.sol",
    "content": "contract C {\n    struct gas { uint a; }\n    function f() public returns (uint, uint) {\n        try this.f() {\n            gas memory x;\n        } catch Error(string memory) {\n\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// Warning 6321: (73-77): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (79-83): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 2072: (122-134): Unused local variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/catch_error.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n\n        } catch Error(string memory) {\n\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// Warning 6321: (46-50): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (52-56): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/catch_error_named.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n\n        } catch Error(string memory x) {\n            x;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// Warning 6321: (46-50): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (52-56): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/catch_low_level.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n\n        } catch (bytes memory x) {\n            x;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// Warning 6321: (46-50): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (52-56): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/creation.sol",
    "content": "contract D {\n}\ncontract C {\n    function f() public {\n        try new D() {\n        } catch (bytes memory x) {\n            x;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/data_location_error_message.sol",
    "content": "contract Foo {\n    function test() public {\n        try this.f() {}\n        catch Error(string reason) {}\n    }\n\n    function f() public {\n    }\n}\n// ----\n// TypeError 6651: (88-101): Data location must be \"memory\" for parameter in function, but none was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/double_panic.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n        } catch Panic(bytes memory) {\n        } catch Panic(uint) {\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// TypeError 1271: (72-109): Expected `catch Panic(uint ...) { ... }`.\n// TypeError 6732: (110-139): This try statement already has a \"Panic\" catch clause.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/double_panic_correct.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n        } catch Panic(uint) {\n        } catch Panic(uint) {\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// TypeError 6732: (102-131): This try statement already has a \"Panic\" catch clause.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/elementary_non_address_state_mutability_catch.sol",
    "content": "contract C {\n    function a() public pure {\n        try this.a() {} catch (string payable memory) {}\n    }\n    function c() public pure {\n        try this.c() {} catch (bytes payable memory) {}\n    }\n}\ncontract C2 {\n    function a() public pure {\n        try this.a() {} catch (string view memory) {}\n    }\n    function c() public pure {\n        try this.c() {} catch (bytes view memory) {}\n    }\n}\ncontract C3 {\n    function a() public pure {\n        try this.a() {} catch (string pure memory) {}\n    }\n    function c() public pure {\n        try this.c() {} catch (bytes pure memory) {}\n    }\n}\n// ----\n// ParserError 9106: (82-89): State mutability can only be specified for address types.\n// ParserError 9106: (175-182): State mutability can only be specified for address types.\n// ParserError 9106: (285-289): State mutability can only be specified for address types.\n// ParserError 9106: (375-379): State mutability can only be specified for address types.\n// ParserError 9106: (482-486): State mutability can only be specified for address types.\n// ParserError 9106: (572-576): State mutability can only be specified for address types."
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/elementary_non_address_state_mutability_try_returns.sol",
    "content": "contract C {\n    function a() public pure returns (bool) {\n        try this.a() returns (bool payable res) {} catch {}\n    }\n    function b() public pure returns (string) {\n        try this.b() returns (string payable res) {} catch {}\n    }\n    function c() public pure returns (int) {\n        try this.c() returns (int payable res) {} catch {}\n    }\n    function d() public pure returns (int256) {\n        try this.d() returns (int256 payable res) {} catch {}\n    }\n    function e() public pure returns (uint) {\n        try this.e() returns (uint payable res) {} catch {}\n    }\n    function f() public pure returns (uint256) {\n        try this.f() returns (uint256 payable res) {} catch {}\n    }\n    function g() public pure returns (bytes1) {\n        try this.g() returns (bytes1 payable res) {} catch {}\n    }\n    function h() public pure returns (bytes) {\n        try this.h() returns (bytes payable res) {} catch {}\n    }\n    function i() public pure returns (bytes32) {\n        try this.i() returns (bytes32 payable res) {} catch {}\n    }\n    function j() public pure returns (fixed) {\n        try this.j() returns (fixed payable res) {} catch {}\n    }\n    function k() public pure returns (fixed80x80) {\n        try this.k() returns (fixed80x80 payable res) {} catch {}\n    }\n    function l() public pure returns (ufixed) {\n        try this.l() returns (ufixed payable res) {} catch {}\n    }\n    function m() public pure returns (ufixed80x80) {\n        try this.m() returns (ufixed80x80 payable res) {} catch {}\n    }\n}\ncontract C1 {\n    function a() public pure returns (bool) {\n        try this.a() returns (bool view res) {} catch {}\n    }\n    function b() public pure returns (string) {\n        try this.b() returns (string view res) {} catch {}\n    }\n    function c() public pure returns (int) {\n        try this.c() returns (int view res) {} catch {}\n    }\n    function d() public pure returns (int256) {\n        try this.d() returns (int256 view res) {} catch {}\n    }\n    function e() public pure returns (uint) {\n        try this.e() returns (uint view res) {} catch {}\n    }\n    function f() public pure returns (uint256) {\n        try this.f() returns (uint256 view res) {} catch {}\n    }\n    function g() public pure returns (bytes1) {\n        try this.g() returns (bytes1 view res) {} catch {}\n    }\n    function h() public pure returns (bytes) {\n        try this.h() returns (bytes view res) {} catch {}\n    }\n    function i() public pure returns (bytes32) {\n        try this.i() returns (bytes32 view res) {} catch {}\n    }\n    function j() public pure returns (fixed) {\n        try this.j() returns (fixed view res) {} catch {}\n    }\n    function k() public pure returns (fixed80x80) {\n        try this.k() returns (fixed80x80 view res) {} catch {}\n    }\n    function l() public pure returns (ufixed) {\n        try this.l() returns (ufixed view res) {} catch {}\n    }\n    function m() public pure returns (ufixed80x80) {\n        try this.m() returns (ufixed80x80 view res) {} catch {}\n    }\n}\ncontract C2 {\n    function a() public pure returns (bool) {\n        try this.a() returns (bool pure res) {} catch {}\n    }\n    function b() public pure returns (string) {\n        try this.b() returns (string pure res) {} catch {}\n    }\n    function c() public pure returns (int) {\n        try this.c() returns (int pure res) {} catch {}\n    }\n    function d() public pure returns (int256) {\n        try this.d() returns (int256 pure res) {} catch {}\n    }\n    function e() public pure returns (uint) {\n        try this.e() returns (uint pure res) {} catch {}\n    }\n    function f() public pure returns (uint256) {\n        try this.f() returns (uint256 pure res) {} catch {}\n    }\n    function g() public pure returns (bytes1) {\n        try this.g() returns (bytes1 pure res) {} catch {}\n    }\n    function h() public pure returns (bytes) {\n        try this.h() returns (bytes pure res) {} catch {}\n    }\n    function i() public pure returns (bytes32) {\n        try this.i() returns (bytes32 pure res) {} catch {}\n    }\n    function j() public pure returns (fixed) {\n        try this.j() returns (fixed pure res) {} catch {}\n    }\n    function k() public pure returns (fixed80x80) {\n        try this.k() returns (fixed80x80 pure res) {} catch {}\n    }\n    function l() public pure returns (ufixed) {\n        try this.l() returns (ufixed pure res) {} catch {}\n    }\n    function m() public pure returns (ufixed80x80) {\n        try this.m() returns (ufixed80x80 pure res) {} catch {}\n    }\n}\n// ----\n// ParserError 9106: (94-101): State mutability can only be specified for address types.\n// ParserError 9106: (210-217): State mutability can only be specified for address types.\n// ParserError 9106: (320-327): State mutability can only be specified for address types.\n// ParserError 9106: (436-443): State mutability can only be specified for address types.\n// ParserError 9106: (548-555): State mutability can only be specified for address types.\n// ParserError 9106: (666-673): State mutability can only be specified for address types.\n// ParserError 9106: (782-789): State mutability can only be specified for address types.\n// ParserError 9106: (896-903): State mutability can only be specified for address types.\n// ParserError 9106: (1014-1021): State mutability can only be specified for address types.\n// ParserError 9106: (1128-1135): State mutability can only be specified for address types.\n// ParserError 9106: (1252-1259): State mutability can only be specified for address types.\n// ParserError 9106: (1368-1375): State mutability can only be specified for address types.\n// ParserError 9106: (1494-1501): State mutability can only be specified for address types.\n// ParserError 9106: (1622-1626): State mutability can only be specified for address types.\n// ParserError 9106: (1735-1739): State mutability can only be specified for address types.\n// ParserError 9106: (1842-1846): State mutability can only be specified for address types.\n// ParserError 9106: (1955-1959): State mutability can only be specified for address types.\n// ParserError 9106: (2064-2068): State mutability can only be specified for address types.\n// ParserError 9106: (2179-2183): State mutability can only be specified for address types.\n// ParserError 9106: (2292-2296): State mutability can only be specified for address types.\n// ParserError 9106: (2403-2407): State mutability can only be specified for address types.\n// ParserError 9106: (2518-2522): State mutability can only be specified for address types.\n// ParserError 9106: (2629-2633): State mutability can only be specified for address types.\n// ParserError 9106: (2750-2754): State mutability can only be specified for address types.\n// ParserError 9106: (2863-2867): State mutability can only be specified for address types.\n// ParserError 9106: (2986-2990): State mutability can only be specified for address types.\n// ParserError 9106: (3111-3115): State mutability can only be specified for address types.\n// ParserError 9106: (3224-3228): State mutability can only be specified for address types.\n// ParserError 9106: (3331-3335): State mutability can only be specified for address types.\n// ParserError 9106: (3444-3448): State mutability can only be specified for address types.\n// ParserError 9106: (3553-3557): State mutability can only be specified for address types.\n// ParserError 9106: (3668-3672): State mutability can only be specified for address types.\n// ParserError 9106: (3781-3785): State mutability can only be specified for address types.\n// ParserError 9106: (3892-3896): State mutability can only be specified for address types.\n// ParserError 9106: (4007-4011): State mutability can only be specified for address types.\n// ParserError 9106: (4118-4122): State mutability can only be specified for address types.\n// ParserError 9106: (4239-4243): State mutability can only be specified for address types.\n// ParserError 9106: (4352-4356): State mutability can only be specified for address types.\n// ParserError 9106: (4475-4479): State mutability can only be specified for address types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/empty_catch.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n\n        } catch () {\n\n        }\n    }\n}\n// ----\n// ParserError 3546: (101-102): Expected type name\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/empty_returns.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() returns () {\n\n        } catch {\n\n        }\n    }\n}\n// ----\n// ParserError 3546: (69-70): Expected type name\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/error_and_panic.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n        } catch Error(string memory) {\n        } catch Panic(uint) {\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/error_with_wrong_type.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n\n        } catch Error(uint) {\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// TypeError 2943: (94-123): Expected `catch Error(string memory ...) { ... }`.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/invalid_catch_parameter_location_calldata.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {} catch (string calldata a) { }\n    }\n}\n// ----\n// TypeError 6651: (70-87): Data location must be \"memory\" for parameter in function, but \"calldata\" was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/invalid_catch_parameter_location_storage.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {} catch (string storage a) { }\n    }\n}\n// ----\n// TypeError 6651: (70-86): Data location must be \"memory\" for parameter in function, but \"storage\" was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/invalid_error_name.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n        } catch Error2() {\n        } catch abc() {\n        }\n    }\n}\n// ----\n// TypeError 3542: (93-119): Invalid catch clause name. Expected either `catch (...)`, `catch Error(...)`, or `catch Panic(...)`.\n// TypeError 3542: (120-143): Invalid catch clause name. Expected either `catch (...)`, `catch Error(...)`, or `catch Panic(...)`.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/invalid_returns.sol",
    "content": "contract C {\n    function f() public returns (uint8, uint) {\n        // Implicitly convertible, but not exactly the same type.\n        try this.f() returns (uint, int x) {\n\n        } catch {\n\n        }\n    }\n}\n// ----\n// TypeError 6509: (157-161): Invalid type, expected uint8 but got uint256.\n// TypeError 6509: (163-168): Invalid type, expected uint256 but got int256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/invalid_returns_var_location.sol",
    "content": "contract C {\n    function f() public returns (string memory) {\n        try this.f() returns (string storage a) {} catch { }\n    }\n}\n// ----\n// TypeError 6651: (93-109): Data location must be \"memory\" for parameter in function, but \"storage\" was given.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/invalid_returns_vars_and_catch_parameter_indexed.sol",
    "content": "==== Source: A ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint indexed a) {\n        } catch { }\n    }\n}\n==== Source: E ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint) {\n        } catch Error(string memory indexed x) {\n        }\n    }\n}\n==== Source: I ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint) {\n        } catch (bytes memory indexed x) {\n        }\n    }\n}\n// ----\n// ParserError 2314: (A:89-96): Expected ',' but got 'indexed'\n// ParserError 2314: (E:128-135): Expected ',' but got 'indexed'\n// ParserError 2314: (I:122-129): Expected ',' but got 'indexed'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/invalid_returns_vars_and_catch_parameter_mutability.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() returns (uint constant a, uint immutable b) {\n        } catch Error(string memory immutable x) {\n            x;\n        }\n\n        try this.f() returns (uint a, uint b) {\n        } catch (bytes memory immutable x) {\n            x;\n        }\n\n        try this.f() returns (uint a, uint b) {\n        } catch Error(string memory constant x) {\n            x;\n        }\n\n        try this.f() returns (uint a, uint b) {\n        } catch (bytes memory constant x) {\n            x;\n        }\n    }\n}\n// ----\n// DeclarationError 1788: (90-105): The \"constant\" keyword can only be used for state variables or variables at file level.\n// DeclarationError 8297: (107-123): The \"immutable\" keyword can only be used for state variables.\n// DeclarationError 8297: (149-174): The \"immutable\" keyword can only be used for state variables.\n// DeclarationError 8297: (269-293): The \"immutable\" keyword can only be used for state variables.\n// DeclarationError 1788: (393-417): The \"constant\" keyword can only be used for state variables or variables at file level.\n// DeclarationError 1788: (512-535): The \"constant\" keyword can only be used for state variables or variables at file level.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/invalid_returns_vars_and_catch_parameter_visibility.sol",
    "content": "==== Source: A ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint public a) {\n        } catch { }\n    }\n}\n==== Source: B ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint private a) {\n        } catch { }\n    }\n}\n==== Source: C ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint external a) {\n        } catch { }\n    }\n}\n==== Source: D ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint internal a) {\n        } catch { }\n    }\n}\n==== Source: E ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint) {\n        } catch Error(string memory public x) {\n        }\n    }\n}\n==== Source: F ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint) {\n        } catch Error(string memory private x) {\n        }\n    }\n}\n==== Source: G ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint) {\n        } catch Error(string memory external x) {\n        }\n    }\n}\n==== Source: H ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint) {\n        } catch Error(string memory internal x) {\n        }\n    }\n}\n==== Source: I ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint) {\n        } catch (bytes memory public x) {\n        }\n    }\n}\n==== Source: J ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint) {\n        } catch (bytes memory private x) {\n        }\n    }\n}\n==== Source: K ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint) {\n        } catch (bytes memory external x) {\n        }\n    }\n}\n==== Source: L ====\ncontract C {\n    function f() public returns (uint) {\n        try this.f() returns (uint) {\n        } catch (bytes memory internal x) {\n        }\n    }\n}\n// ----\n// ParserError 2314: (A:89-95): Expected ',' but got 'public'\n// ParserError 2314: (B:89-96): Expected ',' but got 'private'\n// ParserError 2314: (C:89-97): Expected ',' but got 'external'\n// ParserError 2314: (D:89-97): Expected ',' but got 'internal'\n// ParserError 2314: (E:128-134): Expected ',' but got 'public'\n// ParserError 2314: (F:128-135): Expected ',' but got 'private'\n// ParserError 2314: (G:128-136): Expected ',' but got 'external'\n// ParserError 2314: (H:128-136): Expected ',' but got 'internal'\n// ParserError 2314: (I:122-128): Expected ',' but got 'public'\n// ParserError 2314: (J:122-129): Expected ',' but got 'private'\n// ParserError 2314: (K:122-130): Expected ',' but got 'external'\n// ParserError 2314: (L:122-130): Expected ',' but got 'internal'"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/library_call.sol",
    "content": "library L {\n    struct S { uint x; }\n    function integer(uint t, bool b) public pure returns (uint) {\n        if (b) {\n            return t;\n        } else {\n            revert(\"failure\");\n        }\n    }\n    function stru(S storage t, bool b) public view returns (uint) {\n        if (b) {\n            return t.x;\n        } else {\n            revert(\"failure\");\n        }\n    }\n}\ncontract C {\n    using L for L.S;\n    L.S t;\n    function f(bool b) public pure returns (uint, string memory) {\n        uint x = 8;\n        try L.integer(x, b) returns (uint _x) {\n            return (_x, \"\");\n        } catch Error(string memory message) {\n            return (18, message);\n        }\n    }\n    function g(bool b) public returns (uint, string memory) {\n        t.x = 9;\n        try t.stru(b) returns (uint x) {\n            return (x, \"\");\n        } catch Error(string memory message) {\n            return (19, message);\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/low_level_homestead.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n\n        } catch (bytes memory) {\n\n        }\n    }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// TypeError 9908: (73-106): This catch clause type cannot be used on the selected EVM version (homestead). You need at least a Byzantium-compatible EVM or use `catch { ... }`.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/low_level_spuriousDragon.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n\n        } catch (bytes memory) {\n\n        }\n    }\n}\n// ====\n// EVMVersion: =spuriousDragon\n// ----\n// TypeError 9908: (73-106): This catch clause type cannot be used on the selected EVM version (spuriousDragon). You need at least a Byzantium-compatible EVM or use `catch { ... }`.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/low_level_tangerineWhistle.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n\n        } catch (bytes memory) {\n\n        }\n    }\n}\n// ====\n// EVMVersion: =tangerineWhistle\n// ----\n// TypeError 9908: (73-106): This catch clause type cannot be used on the selected EVM version (tangerineWhistle). You need at least a Byzantium-compatible EVM or use `catch { ... }`.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/low_level_with_wrong_type.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n\n        } catch (uint) {\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// TypeError 6231: (94-118): Expected `catch (bytes memory ...) { ... }` or `catch { ... }`.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/multiple_returns_vars_and_catch_parameter_location.sol",
    "content": "==== Source: A1 ====\ncontract C {\n    function f() public returns (string memory) {\n        try this.f() returns (string memory memory a) { } catch { }\n    }\n}\n==== Source: A2 ====\ncontract C {\n    function f() public returns (string memory) {\n        try this.f() returns (string memory storage a) { } catch { }\n    }\n}\n==== Source: A3 ====\ncontract C {\n    function f() public returns (string memory) {\n        try this.f() returns (string memory calldata a) { } catch { }\n    }\n}\n\n==== Source: B1 ====\ncontract C {\n    function f() public returns (string memory) {\n        try this.f() returns (string calldata memory a) { } catch { }\n    }\n}\n==== Source: B2 ====\ncontract C {\n    function f() public returns (string memory) {\n        try this.f() returns (string calldata storage a) { } catch { }\n    }\n}\n==== Source: B3 ====\ncontract C {\n    function f() public returns (string memory) {\n        try this.f() returns (string calldata calldata a) { } catch { }\n    }\n}\n\n==== Source: C1 ====\ncontract C {\n    function f() public returns (string memory) {\n        try this.f() returns (string storage memory a) { } catch { }\n    }\n}\n==== Source: C2 ====\ncontract C {\n    function f() public returns (string memory) {\n        try this.f() returns (string storage storage a) { } catch { }\n    }\n}\n==== Source: C3 ====\ncontract C {\n    function f() public returns (string memory) {\n        try this.f() returns (string storage calldata a) { } catch { }\n    }\n}\n\n==== Source: D1 ====\ncontract C {\n    function f() public {\n        try this.f() {}  catch (string memory memory x) { }\n    }\n}\n==== Source: D2 ====\ncontract C {\n    function f() public {\n        try this.f() {}  catch (string memory calldata x) { }\n    }\n}\n==== Source: D3 ====\ncontract C {\n    function f() public {\n        try this.f() {}  catch (string memory storage x) { }\n    }\n}\n\n==== Source: E1 ====\ncontract C {\n    function f() public {\n        try this.f() {}  catch (string calldata memory x) { }\n    }\n}\n==== Source: E2 ====\ncontract C {\n    function f() public {\n        try this.f() {}  catch (string calldata calldata x) { }\n    }\n}\n==== Source: E3 ====\ncontract C {\n    function f() public {\n        try this.f() {}  catch (string calldata storage x) { }\n    }\n}\n\n==== Source: G1 ====\ncontract C {\n    function f() public {\n        try this.f() {}  catch (string storage memory x) { }\n    }\n}\n==== Source: G2 ====\ncontract C {\n    function f() public {\n        try this.f() {}  catch (string storage calldata x) { }\n    }\n}\n==== Source: G3 ====\ncontract C {\n    function f() public {\n        try this.f() {}  catch (string storage storage x) { }\n    }\n}\n// ----\n// ParserError 3548: (A1:107-113): Location already specified.\n// ParserError 3548: (A2:107-114): Location already specified.\n// ParserError 3548: (A3:107-115): Location already specified.\n// ParserError 3548: (B1:109-115): Location already specified.\n// ParserError 3548: (B2:109-116): Location already specified.\n// ParserError 3548: (B3:109-117): Location already specified.\n// ParserError 3548: (C1:108-114): Location already specified.\n// ParserError 3548: (C2:108-115): Location already specified.\n// ParserError 3548: (C3:108-116): Location already specified.\n// ParserError 3548: (D1:85-91): Location already specified.\n// ParserError 3548: (D2:85-93): Location already specified.\n// ParserError 3548: (D3:85-92): Location already specified.\n// ParserError 3548: (E1:87-93): Location already specified.\n// ParserError 3548: (E2:87-95): Location already specified.\n// ParserError 3548: (E3:87-94): Location already specified.\n// ParserError 3548: (G1:86-92): Location already specified.\n// ParserError 3548: (G2:86-94): Location already specified.\n// ParserError 3548: (G3:86-93): Location already specified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/no_catch.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n        }\n    }\n}\n// ----\n// ParserError 2314: (97-98): Expected 'catch' but got '}'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/no_external_call.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try f() {\n        } catch {\n        }\n    }\n}\n// ----\n// TypeError 2536: (72-75): Try can only be used with external function calls and contract creation calls.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/no_returns.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n\n        } catch {\n\n        }\n    }\n}\n// ----\n// Warning 6321: (46-50): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (52-56): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/no_special.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this {\n        } catch {\n        }\n        try gasleft() {\n        } catch {\n        }\n        try type(address) {\n        } catch {\n        }\n    }\n}\n// ----\n// TypeError 5347: (72-76): Try can only be used with external function calls and contract creation calls.\n// TypeError 2536: (119-128): Try can only be used with external function calls and contract creation calls.\n// TypeError 4259: (176-183): Invalid type for argument in the function call. An enum type, contract type or an integer type is required, but type(address) provided.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/returns.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() returns (uint a, uint b) {\n            a = 1;\n            b = 2;\n        } catch {\n\n        }\n    }\n}\n// ----\n// Warning 6321: (46-50): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (52-56): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/returns_memory.sol",
    "content": "contract C {\n    function f() public returns (uint[] memory, uint) {\n        try this.f() returns (uint[] memory x, uint y) {\n            return (x, y);\n        } catch {\n\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// Warning 6321: (46-59): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (61-65): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/returns_memory_anonymous.sol",
    "content": "contract C {\n    function f() public returns (uint[] memory, uint) {\n        try this.f() returns (uint[] memory, uint) {\n\n        } catch {\n\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// Warning 6321: (46-59): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (61-65): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/returns_mismatch.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() returns (uint a) {\n            a = 1;\n        } catch {\n\n        }\n    }\n}\n// ----\n// TypeError 2800: (81-128): Function returns 2 values, but returns clause has 1 variables.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/scoping.sol",
    "content": "contract Test {\n  // This checks a scoping error,\n  // the variable \"a\" was not visible\n  // at the assignment.\n  function test(address _ext) external {\n    try Test(_ext).test(_ext) {} catch {}\n    uint a = 1;\n    a = 3;\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/simple_catch.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n\n        } catch {\n\n        }\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/structured_homestead.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n\n        } catch Error(string memory) {\n\n        }\n    }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// TypeError 1812: (73-112): This catch clause type cannot be used on the selected EVM version (homestead). You need at least a Byzantium-compatible EVM or use `catch { ... }`.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/structured_spuriousDragon.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n\n        } catch Error(string memory) {\n\n        }\n    }\n}\n// ====\n// EVMVersion: =spuriousDragon\n// ----\n// TypeError 1812: (73-112): This catch clause type cannot be used on the selected EVM version (spuriousDragon). You need at least a Byzantium-compatible EVM or use `catch { ... }`.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/structured_tangerineWhistle.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n\n        } catch Error(string memory) {\n\n        }\n    }\n}\n// ====\n// EVMVersion: =tangerineWhistle\n// ----\n// TypeError 1812: (73-112): This catch clause type cannot be used on the selected EVM version (tangerineWhistle). You need at least a Byzantium-compatible EVM or use `catch { ... }`.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/two_catch_clauses.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n\n        } catch Error(string memory x) {\n            x;\n\n        } catch (bytes memory x) {\n            x;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// Warning 6321: (46-50): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (52-56): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/two_error_catch_clauses.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n\n        } catch Error(string memory x) {\n            x;\n        } catch Error(string memory y) {\n            y;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// TypeError 1036: (150-205): This try statement already has an \"Error\" catch clause.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/two_low_level_catch_clauses.sol",
    "content": "contract C {\n    function f() public returns (uint, uint) {\n        try this.f() {\n\n        } catch {\n        } catch (bytes memory y) {\n            y;\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// TypeError 5320: (112-161): This try statement already has a low-level catch clause.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/wrong_panic.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n        } catch Panic() {\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// TypeError 1271: (72-97): Expected `catch Panic(uint ...) { ... }`.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tryCatch/wrong_panic_2.sol",
    "content": "contract C {\n    function f() public {\n        try this.f() {\n        } catch Panic(bytes memory) {\n        }\n    }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// TypeError 1271: (72-109): Expected `catch Panic(uint ...) { ... }`.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/assignments_to_tuple_and_non_tuple_expressions_of_tuple_types.sol",
    "content": "contract C {\n\tuint[] public array;\n\n\tfunction f() public {\n\t\t// (f()) is not a tuple expression, but its value is a tuple.\n\t\t(f()) = ();\n\t}\n\n\tfunction g() public {\n\t\t// (revert()) is not a tuple expression, but its value is a tuple.\n\t\t(revert()) = ();\n\t}\n\n\tfunction h() internal returns (uint, uint) {}\n\n\tfunction i() public {\n\t\t// (h()) is not a tuple expression, but its value is a tuple (uint, uint).\n\t\t(h()) = (1, 1);\n\t}\n\n\tfunction j() public returns (uint, uint) {\n\t\t// (j()) is not a tuple expression, but its value is a tuple (uint, uint).\n\t\t(j()) = (1, 1);\n\t}\n\n\tfunction m() public {\n\t\t// (uint x, uint y) is a tuple expression, and its value is a tuple (uint, uint).\n\t\t(uint x, uint y) = (1, 1);\n\t}\n\n\tfunction n() public {\n\t\t// ((array.push(), array.push())) is not a tuple expression, but contains a tuple expression, and the value of both is a tuple (pointer uint, pointer uint).\n\t\t((array.push(), array.push())) = (1, 1);\n\t}\n}\n// ----\n// TypeError 4247: (126-129): Expression has to be an lvalue.\n// TypeError 4247: (236-244): Expression has to be an lvalue.\n// TypeError 4247: (407-410): Expression has to be an lvalue.\n// TypeError 4247: (550-553): Expression has to be an lvalue.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/double_storage_crash.sol",
    "content": "// This used to crash in certain compiler versions.\ncontract CrashContract {\n       struct S { uint a; }\n       S x;\n       function f() public {\n               (x, x) = 1(x, x);\n       }\n}\n// ----\n// TypeError 5704: (170-177): This expression is not callable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/empty_tuple_assignment.sol",
    "content": "function f() pure {\n    ((, ())) = (1, 3);\n}\n\nfunction g() pure {\n    ((, ((, ())))) = (1, 3);\n}\n\nfunction t() pure returns (int, int) {\n    return (4, 5);\n}\n\nfunction h() pure {\n    ((, ())) = t();\n}\n\nfunction ff() pure {\n    ((((, ())) , )) = ((1, 2), 3);\n}\n\nfunction fg() pure {\n    (((, ())) , ) = ((1, 2), 3);\n}\n\n// ----\n// TypeError 5547: (28-30): Empty tuple on the left hand side.\n// TypeError 7407: (35-41): Type tuple(int_const 1,int_const 3) is not implicitly convertible to expected type tuple(,tuple()).\n// TypeError 5547: (78-80): Empty tuple on the left hand side.\n// TypeError 7407: (87-93): Type tuple(int_const 1,int_const 3) is not implicitly convertible to expected type tuple(,tuple(,tuple())).\n// TypeError 5547: (187-189): Empty tuple on the left hand side.\n// TypeError 7407: (194-197): Type tuple(int256,int256) is not implicitly convertible to expected type tuple(,tuple()).\n// TypeError 5547: (233-235): Empty tuple on the left hand side.\n// TypeError 7407: (245-256): Type tuple(tuple(int_const 1,int_const 2),int_const 3) is not implicitly convertible to expected type tuple(tuple(,tuple()),).\n// TypeError 5547: (291-293): Empty tuple on the left hand side.\n// TypeError 7407: (302-313): Type tuple(tuple(int_const 1,int_const 2),int_const 3) is not implicitly convertible to expected type tuple(tuple(,tuple()),).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/empty_tuples_lhs.sol",
    "content": "contract C {\n    function f0() public { (()) = 2; }\n\n    function f1() public pure { (()) = (); }\n\n    //#8711\n    function f2() internal pure returns (uint, uint) { return () = f2(); }\n\n    //#8277\n    function f3()public{return()=();}\n\n    //#8277\n    function f4 ( bytes32 hash , uint8 v , bytes32 r , bytes32 s , uint blockExpired , bytes32 salt ) public returns ( address ) {\n        require ( ( ( ) ) |= keccak256 ( abi . encodePacked ( blockExpired , salt ) ) ) ;\n        return ecrecover ( hash , v , r , s ) ;\n    }\n}\n// ----\n// TypeError 5547: (41-43): Empty tuple on the left hand side.\n// TypeError 7407: (47-48): Type int_const 2 is not implicitly convertible to expected type tuple().\n// TypeError 5547: (86-88): Empty tuple on the left hand side.\n// TypeError 5547: (173-175): Empty tuple on the left hand side.\n// TypeError 7407: (178-182): Type tuple(uint256,uint256) is not implicitly convertible to expected type tuple().\n// TypeError 5132: (166-182): Different number of arguments in return statement than in returns declaration.\n// TypeError 5547: (229-231): Empty tuple on the left hand side.\n// TypeError 5547: (401-404): Empty tuple on the left hand side.\n// TypeError 4289: (399-466): Compound assignment is not allowed for tuple types.\n// TypeError 7407: (410-466): Type bytes32 is not implicitly convertible to expected type tuple().\n// TypeError 9322: (389-396): No matching declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/err_fill_assignment.sol",
    "content": "contract C {\n\tfunction f() public pure returns (uint, uint, bytes32) {\n\t\tuint a;\n\t\tbytes32 b;\n\t\t(a,) = f();\n\t\t(,b) = f();\n\t}\n}\n// ----\n// TypeError 7407: (103-106): Type tuple(uint256,uint256,bytes32) is not implicitly convertible to expected type tuple(uint256,).\n// TypeError 7407: (117-120): Type tuple(uint256,uint256,bytes32) is not implicitly convertible to expected type tuple(,bytes32).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/error_fill.sol",
    "content": "contract C {\n\tfunction f() public pure returns (uint, uint, bytes32) {\n\t\tuint a;\n\t\tbytes32 b;\n\t\t(a,) = f();\n\t\t(,b) = f();\n\t}\n}\n// ----\n// TypeError 7407: (103-106): Type tuple(uint256,uint256,bytes32) is not implicitly convertible to expected type tuple(uint256,).\n// TypeError 7407: (117-120): Type tuple(uint256,uint256,bytes32) is not implicitly convertible to expected type tuple(,bytes32).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/fixed_byte_array_assignment_in_tuple.sol",
    "content": "contract A {\n    function f() pure public {\n        bytes1 b;\n        bytes1 a;\n        (((, , b))) = (1, 2, a);\n    }\n}\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/large_component_count.sol",
    "content": "contract C {\n\tfunction g() public pure returns (\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint,\n\t\tuint\n\t) { }\n\tfunction f() public pure returns (uint, uint, bytes32) {\n\t\tuint a;\n\t\tuint b;\n\t\t(,,,,a,,,,b,,,,) = g();\n\t}\n}\n// ----\n// Warning 6321: (194-198): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (200-204): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n// Warning 6321: (206-213): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/nested_tuple_to_tuple_assignment.sol",
    "content": "contract C {\n    bool x;\n\n    function foo() external {\n        (((),x)&x) = ((), true);\n        (((),x)+x) = ((), true);\n        (((),x)-x) = ((), true);\n        (((),x)/x) = ((), true);\n        (((),x)*x) = ((), true);\n        (((),x)|x) = ((), true);\n    }\n}\n// ----\n// TypeError 6473: (66-68): Tuple component cannot be empty.\n// TypeError 2271: (65-73): Built-in binary operator & cannot be applied to types tuple(tuple(),bool) and bool.\n// TypeError 4247: (65-73): Expression has to be an lvalue.\n// TypeError 6473: (78-80): Tuple component cannot be empty.\n// TypeError 6473: (99-101): Tuple component cannot be empty.\n// TypeError 2271: (98-106): Built-in binary operator + cannot be applied to types tuple(tuple(),bool) and bool.\n// TypeError 4247: (98-106): Expression has to be an lvalue.\n// TypeError 6473: (111-113): Tuple component cannot be empty.\n// TypeError 6473: (132-134): Tuple component cannot be empty.\n// TypeError 2271: (131-139): Built-in binary operator - cannot be applied to types tuple(tuple(),bool) and bool.\n// TypeError 4247: (131-139): Expression has to be an lvalue.\n// TypeError 6473: (144-146): Tuple component cannot be empty.\n// TypeError 6473: (165-167): Tuple component cannot be empty.\n// TypeError 2271: (164-172): Built-in binary operator / cannot be applied to types tuple(tuple(),bool) and bool.\n// TypeError 4247: (164-172): Expression has to be an lvalue.\n// TypeError 6473: (177-179): Tuple component cannot be empty.\n// TypeError 6473: (198-200): Tuple component cannot be empty.\n// TypeError 2271: (197-205): Built-in binary operator * cannot be applied to types tuple(tuple(),bool) and bool.\n// TypeError 4247: (197-205): Expression has to be an lvalue.\n// TypeError 6473: (210-212): Tuple component cannot be empty.\n// TypeError 6473: (231-233): Tuple component cannot be empty.\n// TypeError 2271: (230-238): Built-in binary operator | cannot be applied to types tuple(tuple(),bool) and bool.\n// TypeError 4247: (230-238): Expression has to be an lvalue.\n// TypeError 6473: (243-245): Tuple component cannot be empty.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/nowarn_swap_memory.sol",
    "content": "contract C {\n\tstruct S { uint a; uint b; }\n\tfunction f() pure public {\n\t\tS memory x;\n\t\tS memory y;\n\t\t(x, y) = (y, x);\n\t}\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/nowarn_swap_storage_pointers.sol",
    "content": "\t\tcontract C {\n\t\t\tstruct S { uint a; uint b; }\n\t\t\tS x; S y;\n\t\t\tfunction f() public {\n\t\t\t\tS storage x_local = x;\n\t\t\t\tS storage y_local = y;\n\t\t\t\tS storage z_local = x;\n\t\t\t\t(x, y_local, x_local, z_local) = (y, x_local, y_local, y);\n\t\t\t}\n\t\t}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/tuple_in_tuple_long.sol",
    "content": "contract C {\n  function f() public {\n    (((((((((((,2),)),)),),))=4)));\n  }\n}\n// ----\n// TypeError 4247: (53-54): Expression has to be an lvalue.\n// TypeError 7407: (67-68): Type int_const 4 is not implicitly convertible to expected type tuple(tuple(tuple(tuple(tuple(,int_const 2),),),),).\n// TypeError 6473: (44-68): Tuple component cannot be empty.\n// TypeError 6473: (43-69): Tuple component cannot be empty.\n// TypeError 6473: (42-70): Tuple component cannot be empty.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/tuple_in_tuple_short.sol",
    "content": "contract C {\n  function f() public pure {\n    int a;\n    (((a,),)) = ((1,2),3);\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/tuple_to_function_assignment.sol",
    "content": "contract C {\n\tfunction f() internal pure {}\n\tfunction g() internal pure returns (uint256) {}\n\tfunction h() internal pure returns (uint256, uint256) {}\n\tfunction test() public pure {\n\t\tf() = ();\n\t\tg() = (uint256(1));\n\t\th() = (uint256(1), uint256(2));\n\t\th() = ();\n\t}\n}\n// ----\n// TypeError 4247: (184-187): Expression has to be an lvalue.\n// TypeError 4247: (196-199): Expression has to be an lvalue.\n// TypeError 4247: (218-221): Expression has to be an lvalue.\n// TypeError 4247: (252-255): Expression has to be an lvalue.\n// TypeError 7407: (258-260): Type tuple() is not implicitly convertible to expected type tuple(uint256,uint256).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies.sol",
    "content": "contract C {\n\tstruct S { uint a; uint b; }\n\tS x; S y;\n\tfunction f() public {\n\t\t(x, y) = (y, x);\n\t}\n\tfunction g() public {\n\t\tuint z;\n\t\t((x, y), z) = ((y, x), 0);\n\t}\n}\n// ----\n// Warning 7238: (79-94): This assignment performs two copies to storage. Since storage copies do not first copy to a temporary location, one of them might be overwritten before the second is executed and thus may have unexpected effects. It is safer to perform the copies separately or assign to storage pointers first.\n// Warning 7238: (134-159): This assignment performs two copies to storage. Since storage copies do not first copy to a temporary location, one of them might be overwritten before the second is executed and thus may have unexpected effects. It is safer to perform the copies separately or assign to storage pointers first.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_abi_decode.sol",
    "content": "contract C {\n    function f(bytes memory b) public pure returns (address payable) {\n        (address payable c) = abi.decode(b, (address));\n        return c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_binary_operators.sol",
    "content": "contract C {\n    address a;\n    function f() public pure returns(bool) {\n        a = address(0) + address(0);\n        a = address(0) - address(0);\n        a = address(0) * address(0);\n        a = address(0) / address(0);\n        return address(0) == address(0);\n    }\n}\n// ----\n// TypeError 2271: (85-108): Built-in binary operator + cannot be applied to types address and address. Arithmetic operations on addresses are not supported. Convert to integer first before using them.\n// TypeError 2271: (122-145): Built-in binary operator - cannot be applied to types address and address. Arithmetic operations on addresses are not supported. Convert to integer first before using them.\n// TypeError 2271: (159-182): Built-in binary operator * cannot be applied to types address and address. Arithmetic operations on addresses are not supported. Convert to integer first before using them.\n// TypeError 2271: (196-219): Built-in binary operator / cannot be applied to types address and address. Arithmetic operations on addresses are not supported. Convert to integer first before using them.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_constant.sol",
    "content": "contract C {\n    address constant a = address(0);\n    address payable constant b = payable(0);\n    function f() public pure returns (address, address) {\n        return (a,b);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_constant_assignment.sol",
    "content": "contract C {\n    address constant a = address(0);\n    address payable constant b = payable(0);\n    function f() public {\n        a = address(0);\n        b = payable(0);\n    }\n}\n// ----\n// TypeError 6520: (129-130): Cannot assign to a constant variable.\n// TypeError 6520: (153-154): Cannot assign to a constant variable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_in_struct_fail.sol",
    "content": "contract A {\n    struct S {\n        address payable a;\n    }\n    S s;\n    function f() public {\n        s.a = address(this);\n    }\n}\n// ----\n// TypeError 7407: (110-123): Type address is not implicitly convertible to expected type address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_in_struct_fine.sol",
    "content": "contract A {\n    struct S {\n        address a;\n    }\n    S s;\n    function f() public {\n        s.a = address(this);\n    }\n}\ncontract B {\n    struct S {\n        address payable a;\n    }\n    S s;\n    function f() public {\n        s.a = payable(this);\n    }\n    receive() external payable {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_literal_to_payable.sol",
    "content": "contract C {\n    function f() public pure {\n        address payable a = payable(address(0x00000000219ab540356cBB839Cbe05303d7705Fa));\n        address payable b = payable(0x00000000219ab540356cBB839Cbe05303d7705Fa);\n        a = b;\n        b = a;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_literal_to_payable_err.sol",
    "content": "contract C {\n    function f() public pure {\n        address payable a = address(0x00000000219ab540356cBB839Cbe05303d7705Fa);\n        address payable b = 0x00000000219ab540356cBB839Cbe05303d7705Fa;\n    }\n}\n// ----\n// TypeError 9574: (52-123): Type address is not implicitly convertible to expected type address payable.\n// TypeError 9574: (133-195): Type address is not implicitly convertible to expected type address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_members.sol",
    "content": "contract C {\n    function f() public view returns (address) { return address(this); }\n    function g() public view returns (uint) { return f().balance; }\n    function h() public view returns (bytes memory) { return f().code; }\n    function i() public view returns (uint) { return f().code.length; }\n    function j() public view returns (uint) { return h().length; }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_members_in_contract.sol",
    "content": "contract C {\n    function f() public returns (C) { return this; }\n    function g() public returns (uint) { return f().balance; }\n}\n// ----\n// TypeError 3125: (114-125): Member \"balance\" not found or not visible after argument-dependent lookup in contract C. Use \"address(...).balance\" to access this address member.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_nonpayable_selfdestruct.sol",
    "content": "contract C {\n    function f(address a) public {\n        selfdestruct(a);\n    }\n}\n// ----\n// Warning 5159: (56-68): \"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.\n// TypeError 9553: (69-70): Invalid type for argument in function call. Invalid implicit conversion from address to address payable requested.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_payable_external_overload.sol",
    "content": "contract C {\n    function f(address) external pure {}\n    function f(address payable) external pure {}\n\n}\n// ----\n// TypeError 9914: (58-102): Function overload clash during conversion to external types for arguments.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_payable_internal_overload_nonpayable.sol",
    "content": "contract C {\n    function f(address payable) internal pure {}\n    function f(address) internal pure returns (uint) {}\n    function g() internal pure {\n        address a = address(0);\n        uint b = f(a); // TODO: should this be valid?\n        b;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_payable_internal_overload_payable.sol",
    "content": "contract C {\n    function f(address payable) internal pure {}\n    function f(address) internal pure {}\n    function g() internal pure {\n        address payable a = payable(0);\n        f(a);\n    }\n}\n// ----\n// TypeError 4487: (184-185): No unique declaration found after argument-dependent lookup.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_payable_memory_array_conversion.sol",
    "content": "contract C {\n    function f() public pure {\n        address payable[] memory a = new address payable[](4);\n        address[] memory b = new address[](4);\n        a = b;\n        b = a;\n    }\n}\n// ----\n// TypeError 7407: (166-167): Type address[] memory is not implicitly convertible to expected type address payable[] memory.\n// TypeError 7407: (181-182): Type address payable[] memory is not implicitly convertible to expected type address[] memory.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_payable_public_overload.sol",
    "content": "contract C {\n    function f(address) public pure {}\n    function f(address payable) public pure {}\n\n}\n// ----\n// TypeError 9914: (56-98): Function overload clash during conversion to external types for arguments.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_payable_selfdestruct.sol",
    "content": "contract C {\n    function f(address payable a) public {\n        selfdestruct(a);\n    }\n}\n// ====\n// bytecodeFormat: legacy\n// ----\n// Warning 5159: (64-76): \"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.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_payable_storage_array_conversion.sol",
    "content": "contract C {\n    address payable[] a;\n    address[] b;\n    function f() public view {\n        address payable[] storage c = a;\n        address[] storage d = b;\n        d = c; // TODO: this could be allowed in the future\n    }\n}\n// ----\n// TypeError 7407: (172-173): Type address payable[] storage pointer is not implicitly convertible to expected type address[] storage pointer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_payable_storage_array_conversion_fail.sol",
    "content": "contract C {\n    address payable[] a;\n    address[] b;\n    function f() public view {\n        address payable[] storage c = a;\n        address[] storage d = b;\n        c = d;\n    }\n}\n// ----\n// TypeError 7407: (172-173): Type address[] storage pointer is not implicitly convertible to expected type address payable[] storage pointer.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_to_contract.sol",
    "content": "contract C {\n  function f() public pure returns (C c) {\n    c = C(address(2));\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_to_contract_implicitly.sol",
    "content": "contract C {\n  function f() public view {\n    C c = address(2);\n  }\n}\n// ----\n// TypeError 9574: (46-62): Type address is not implicitly convertible to expected type contract C.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_to_contract_payable_fallback.sol",
    "content": "contract C {\n  function f() public pure returns (C c) {\n    c = C(payable(address(2)));\n  }\n  fallback() external payable {\n  }\n}\n// ----\n// Warning 3628: (0-129): This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_to_contract_receive.sol",
    "content": "contract C {\n  function f() public pure returns (C c) {\n    c = C(payable(address(2)));\n  }\n  receive() external payable {\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_to_payable_address.sol",
    "content": "contract C {\n    function f(address a) public pure {\n        address b;\n        address payable c = a;\n        c = b;\n    }\n}\n// ----\n// TypeError 9574: (80-101): Type address is not implicitly convertible to expected type address payable.\n// TypeError 7407: (115-116): Type address is not implicitly convertible to expected type address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_to_payable_address_double.sol",
    "content": "contract C {\n    function f(address a) public pure returns (address payable) {\n        return address(address(a));\n    }\n}\n// ----\n// TypeError 6359: (94-113): Return argument type address is not implicitly convertible to expected type (type of first return variable) address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_tuple_fail.sol",
    "content": "contract C {\n    function f() public view returns (address payable a, address b) {\n        (address c, address payable d) = (address(this), payable(0));\n        (a,b) = (c,d);\n    }\n}\n// ----\n// TypeError 7407: (169-174): Type tuple(address,address payable) is not implicitly convertible to expected type tuple(address payable,address).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_tuple_fine.sol",
    "content": "contract C {\n    function f() public view returns (address payable a, address b) {\n        (address c, address payable d) = (address(this), payable(0));\n        (a,b) = (d,c);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_uint_bytes20_this.sol",
    "content": "contract C {\n    function f() public view {\n        address a1 = address(uint160(0));\n        address a2 = address(bytes20(0));\n        address a3 = address(this);\n\n        // Trivial conversions\n        address payable a4 = payable(address(uint160(0)));\n        address payable a5 = payable(address(bytes20(0)));\n        address payable a6 = payable(address(this));\n\n        a1; a2; a3; a4; a5; a6;\n    }\n\n    // to make payable(this) work\n    receive() payable external {\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_uint_bytes20_this_to_payable_err.sol",
    "content": "contract C {\n    function f() public pure {\n        address payable a = address(uint160(0));\n        address payable b = address(bytes20(0));\n        address payable c = address(this);\n    }\n}\n// ----\n// TypeError 9574: (52-91): Type address is not implicitly convertible to expected type address payable.\n// TypeError 9574: (101-140): Type address is not implicitly convertible to expected type address payable.\n// TypeError 9574: (150-183): Type address is not implicitly convertible to expected type address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/address_zero_to_payable_err.sol",
    "content": "contract C {\n    function f() public pure {\n        address payable a = address(0);\n    }\n}\n// ----\n// TypeError 9574: (52-82): Type address is not implicitly convertible to expected type address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/bytes_long_to_payable_address.sol",
    "content": "contract C {\n    function f(bytes32 x) public pure returns (address payable) {\n        return address(x);\n    }\n}\n// ----\n// TypeError 9640: (94-104): Explicit type conversion not allowed from \"bytes32\" to \"address\".\n// TypeError 6359: (94-104): Return argument type address is not implicitly convertible to expected type (type of first return variable) address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/bytes_short_to_payable_address.sol",
    "content": "contract C {\n    function f(bytes10 x) public pure returns (address payable) {\n        return address(x);\n    }\n}\n// ----\n// TypeError 9640: (94-104): Explicit type conversion not allowed from \"bytes10\" to \"address\".\n// TypeError 6359: (94-104): Return argument type address is not implicitly convertible to expected type (type of first return variable) address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/bytes_to_payable_address.sol",
    "content": "contract C {\n    function f(bytes20 x) public pure returns (address payable) {\n        return payable(address(x));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/codehash.sol",
    "content": "contract C {\n    function f() public view returns (bytes32) {\n        return address(this).codehash;\n    }\n}\n// ====\n// EVMVersion: >=constantinople\n// bytecodeFormat: legacy\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/codehash_before_constantinople.sol",
    "content": "contract C {\n    function f() public view returns (bytes32) {\n        return address(this).codehash;\n    }\n}\n// ====\n// EVMVersion: <constantinople\n// ----\n// TypeError 7598: (77-99): \"codehash\" is not supported by the VM version.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/contract_no_fallback_to_payable_address.sol",
    "content": "contract C {\n  function f() public view {\n    address payable a = address(this);\n    a;\n  }\n}\n// ----\n// TypeError 9574: (46-79): Type address is not implicitly convertible to expected type address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/contract_non_payable_fallback_to_payable_address.sol",
    "content": "contract C {\n  function f() public view {\n    address payable a = address(this);\n    a;\n  }\n  fallback() external {\n  }\n}\n// ----\n// TypeError 9574: (46-79): Type address is not implicitly convertible to expected type address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/contract_payable_fallback_to_payable_address.sol",
    "content": "contract C {\n  function f() public view {\n    address payable a = payable(this);\n    a;\n  }\n  fallback() external payable {\n  }\n}\n// ----\n// Warning 3628: (0-129): This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/contract_payable_fallback_to_payable_address_implicitly.sol",
    "content": "contract C {\n  function f() public view {\n    address payable a = this;\n    a;\n  }\n  fallback() external payable {\n  }\n}\n// ----\n// Warning 3628: (0-120): This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function.\n// TypeError 9574: (46-70): Type contract C is not implicitly convertible to expected type address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/contract_receive_to_payable_address.sol",
    "content": "contract C {\n  function f() public view {\n    address payable a = payable(this);\n    a;\n  }\n  receive() external payable {\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/contract_receive_to_payable_address_implicitly.sol",
    "content": "contract C {\n  function f() public view {\n    address payable a = this;\n    a;\n  }\n  receive() external payable {\n  }\n}\n// ----\n// TypeError 9574: (46-70): Type contract C is not implicitly convertible to expected type address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/contract_to_address.sol",
    "content": "contract C {\n  function f() public view {\n    address a = address(this);\n    a;\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/contract_to_address_implicitly.sol",
    "content": "contract C {\n  function f() public view {\n    address a = this;\n    a;\n  }\n}\n// ----\n// TypeError 9574: (46-62): Type contract C is not implicitly convertible to expected type address.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/contract_type_to_address.sol",
    "content": "interface I {}\n\nlibrary L {}\n\ncontract C {\n    function f() public pure {\n        address(C);\n        address(I);\n        address(L); // This one is allowed\n\n        address(type(C));\n        address(type(I));\n        address(type(L));\n    }\n}\n// ----\n// TypeError 9640: (82-92): Explicit type conversion not allowed from \"type(contract C)\" to \"address\".\n// TypeError 9640: (102-112): Explicit type conversion not allowed from \"type(contract I)\" to \"address\".\n// TypeError 9640: (166-182): Explicit type conversion not allowed from \"type(contract C)\" to \"address\".\n// TypeError 9640: (192-208): Explicit type conversion not allowed from \"type(contract I)\" to \"address\".\n// TypeError 9640: (218-234): Explicit type conversion not allowed from \"type(library L)\" to \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/conversion.sol",
    "content": "contract C {\n    function f() public pure returns (address) {\n        return address(2**160 -1);\n    }\n    function g() public pure returns (address) {\n        return address(type(uint160).max);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/conversion_error.sol",
    "content": "contract C {\n    function f() public pure returns (address) {\n        return address(-1);\n    }\n    function g() public pure returns (address) {\n        return -1;\n    }\n\tfunction h() public pure returns (address) {\n\t\treturn address(2**160);\n\t}\n}\n// ----\n// TypeError 9640: (77-88): Explicit type conversion not allowed from \"int_const -1\" to \"address\".\n// TypeError 6359: (160-162): Return argument type int_const -1 is not implicitly convertible to expected type (type of first return variable) address.\n// TypeError 9640: (225-240): Explicit type conversion not allowed from \"int_const 1461...(41 digits omitted)...2976\" to \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/eof/address_members.sol",
    "content": "contract C {\n    function f() public view returns (address) { return address(this); }\n    function g() public view returns (uint) { return f().balance; }\n    function h() public pure returns (bytes memory) { return msg.data; }\n    function j() public pure returns (uint) { return h().length; }\n}\n// ====\n// bytecodeFormat: >=EOFv1\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/literal_to_address.sol",
    "content": "contract C {\n    function f() public pure {\n        address a = address(0);\n        a = address(1);\n        address b = 0x0123456789012345678901234567890123456789;\n        b = 0x9876543210987654321098765432109876543210;\n        b = 0x9876_5432_1098_7654_3210_9876_5432_1098_7654_3210;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/literal_to_address_call.sol",
    "content": "contract C {\n    function f() public returns (bool success) {\n        (success, ) = (address(0)).call{value: 30}(\"\");\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/literal_to_address_oversized.sol",
    "content": "contract C {\n    function f() public pure {\n        address(0x11223345567aaaaaaaaaaaaaaaaaaaaaaaaaaaaa0112233445566778899001122);\n    }\n}\n// ----\n// TypeError 9640: (52-128): Explicit type conversion not allowed from \"int_const 1239...(70 digits omitted)...8130\" to \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/literal_to_payable_address.sol",
    "content": "contract C {\n    function f() public pure {\n        // We allow an exception for 0\n        address payable a = payable(0);\n        a = payable(address(1));\n        address payable b = payable(0x0123456789012345678901234567890123456789);\n        b = payable(0x9876543210987654321098765432109876543210);\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/literal_to_payable_address_err.sol",
    "content": "contract C {\n    function f() public pure {\n        address payable a = address(0);\n    }\n}\n// ----\n// TypeError 9574: (52-82): Type address is not implicitly convertible to expected type address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/nonpayable_address_to_contract_payable_fallback.sol",
    "content": "contract C {\n  function f() public pure returns (C c) {\n    address a = address(2);\n    c = C(a);\n  }\n  fallback() external payable {\n  }\n}\n// ----\n// Warning 3628: (0-139): This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function.\n// TypeError 7398: (92-96): Explicit type conversion not allowed from non-payable \"address\" to \"contract C\", which has a payable fallback function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/nonpayable_address_to_contract_receive.sol",
    "content": "contract C {\n  function f() public pure returns (C c) {\n    address a = address(2);\n    c = C(a);\n  }\n  receive() external payable {\n  }\n}\n// ----\n// TypeError 7398: (92-96): Explicit type conversion not allowed from non-payable \"address\" to \"contract C\", which has a payable fallback function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/payable_address_to_address.sol",
    "content": "contract C {\n    function f(address payable a) public pure {\n        address payable b;\n        address c = a;\n        c = b;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/payable_conversion.sol",
    "content": "contract C {\n    function f() public {\n        address payable a = payable(address(new D()));\n        address payable b = payable(new E());\n        address payable c = payable(new F());\n\n        a;\n        b;\n        c;\n    }\n}\n\n// A contract that cannot receive Ether\ncontract D {}\n\n// A contract that can receive Ether\ncontract E {\n    receive() external payable {\n    }\n}\n\n// A contract that can receive Ether using the fallback\ncontract F {\n    fallback() external payable {\n\n    }\n}\n\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/payable_conversion_err.sol",
    "content": "contract C {\n    function f() public {\n        address payable a = address(new D());\n\n        // This conversion makes no sense anyway.\n        address payable b = address(D);\n    }\n}\n\ncontract D {\n    receive() external payable {\n    }\n}\n// ----\n// TypeError 9574: (47-83): Type address is not implicitly convertible to expected type address payable.\n// TypeError 9640: (164-174): Explicit type conversion not allowed from \"type(contract D)\" to \"address\".\n// TypeError 9574: (144-174): Type address is not implicitly convertible to expected type address payable.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/payable_conversion_strict.sol",
    "content": "contract C {\n    function f() public pure {\n        address payable a = payable(address(uint160(0)));\n        address payable b = payable(address(bytes20(0)));\n        address payable c = payable(address(2));\n        // hex literal that is only 15 bytes long\n        address payable d = payable(address(0x002190356cBB839Cbe05303d7705Fa));\n\n        uint160 a1 = uint160(address(payable(0)));\n        bytes20 b1 = bytes20(address(payable(0)));\n\n        a; b; c; d; a1; b1;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/payable_conversion_strict_err.sol",
    "content": "contract C {\n    function f() public pure {\n        address payable a = payable(uint160(0));\n        address payable b = payable(bytes20(0));\n        address payable c = payable(2);\n        // hex literal that is only 15 bytes long\n        address payable d = payable(0x002190356cBB839Cbe05303d7705Fa);\n\n        // The opposite should also be disallowed\n        uint160 a1 = uint160(payable(0));\n        bytes20 b1 = bytes20(payable(0));\n    }\n}\n// ----\n// TypeError 9640: (72-91): Explicit type conversion not allowed from \"uint160\" to \"address payable\".\n// TypeError 9640: (121-140): Explicit type conversion not allowed from \"bytes20\" to \"address payable\".\n// TypeError 9640: (170-180): Explicit type conversion not allowed from \"int_const 2\" to \"address payable\".\n// TypeError 9640: (260-301): Explicit type conversion not allowed from \"int_const 6807...(25 digits omitted)...4970\" to \"address payable\".\n// TypeError 9640: (375-394): Explicit type conversion not allowed from \"address payable\" to \"uint160\".\n// TypeError 9640: (417-436): Explicit type conversion not allowed from \"address payable\" to \"bytes20\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/payable_conversions_literals.sol",
    "content": "contract C {\n    function f() public pure {\n        // 0 is okay, because it's an exception\n        address payable a = payable(0);\n\n        // address literals have type address\n        address payable b = payable(0x00000000219ab540356cBB839Cbe05303d7705Fa);\n\n        address payable c = payable(address(2));\n\n        a; b; c;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/payable_to_contract_receive.sol",
    "content": "contract C {\n  function f() public pure returns (C c) {\n    c = C(payable(address(2)));\n  }\n  receive() external payable {\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/state_variable_address_payable_transient.sol",
    "content": "contract C {\n    address payable transient a;\n}\n// ====\n// stopAfter: parsing\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/state_variable_address_transient_payable.sol",
    "content": "contract C {\n    address transient payable a;\n}\n// ----\n// ParserError 2314: (35-42): Expected identifier but got 'payable'\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/super_to_address.sol",
    "content": "contract C {\n    function f() public pure {\n        address(super);\n    }\n}\n// ----\n// TypeError 9640: (52-66): Explicit type conversion not allowed from \"type(contract super C)\" to \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/type_type_to_address.sol",
    "content": "struct S {\n    uint x;\n}\n\nenum E {A, B, C}\n\ncontract C {\n    function f() public pure {\n        address(uint);\n        address(bytes16);\n        address(bool);\n        address(address);\n        address(fixed);\n\n        address(S);\n        address(E);\n\n        address(uint[]);\n        address(uint[][]);\n        address(uint[5]);\n        address(string);\n        address(bytes);\n        address(S[]);\n        address(E[]);\n        address((uint, uint));\n\n        address(type(uint));\n    }\n}\n// ----\n// TypeError 9640: (96-109): Explicit type conversion not allowed from \"type(uint256)\" to \"address\".\n// TypeError 9640: (119-135): Explicit type conversion not allowed from \"type(bytes16)\" to \"address\".\n// TypeError 9640: (145-158): Explicit type conversion not allowed from \"type(bool)\" to \"address\".\n// TypeError 9640: (168-184): Explicit type conversion not allowed from \"type(address)\" to \"address\".\n// TypeError 9640: (194-208): Explicit type conversion not allowed from \"type(fixed128x18)\" to \"address\".\n// TypeError 9640: (219-229): Explicit type conversion not allowed from \"type(struct S storage pointer)\" to \"address\".\n// TypeError 9640: (239-249): Explicit type conversion not allowed from \"type(enum E)\" to \"address\".\n// TypeError 9640: (260-275): Explicit type conversion not allowed from \"type(uint256[] memory)\" to \"address\".\n// TypeError 9640: (285-302): Explicit type conversion not allowed from \"type(uint256[] memory[] memory)\" to \"address\".\n// TypeError 9640: (312-328): Explicit type conversion not allowed from \"type(uint256[5] memory)\" to \"address\".\n// TypeError 9640: (338-353): Explicit type conversion not allowed from \"type(string storage pointer)\" to \"address\".\n// TypeError 9640: (363-377): Explicit type conversion not allowed from \"type(bytes storage pointer)\" to \"address\".\n// TypeError 9640: (387-399): Explicit type conversion not allowed from \"type(struct S memory[] memory)\" to \"address\".\n// TypeError 9640: (409-421): Explicit type conversion not allowed from \"type(enum E[] memory)\" to \"address\".\n// TypeError 9640: (431-452): Explicit type conversion not allowed from \"tuple(type(uint256),type(uint256))\" to \"address\".\n// TypeError 9640: (463-482): Explicit type conversion not allowed from \"type(uint256)\" to \"address\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/address/uint_to_payable_address.sol",
    "content": "contract C {\n    function f(uint x) public pure returns (address payable) {\n        return payable(address(uint160(x)));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/array_index_too_large.sol",
    "content": "contract C {\n    function f() public returns (string memory) {\n        // this used to cause an internal error\n        return ([\"zeppelin\"][123456789012345678901234567890123456789012345678901234567890123456789012345678]);\n    }\n}\n// ----\n// TypeError 7407: (140-218): Type int_const 1234...(70 digits omitted)...5678 is not implicitly convertible to expected type uint256. Literal is too large to fit in uint256.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/binary_add_op.sol",
    "content": "contract C {\n    function f(int32 x) external pure returns (int32)\n    {\n        x = 1 + 1;\n        (x /= 1) + 1;\n        (x = ++x) + 1;\n        (0) + 1;\n        return x;\n    }\n}\n// ----\n// Warning 6133: (145-152): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bool_ops.sol",
    "content": "contract C {\n    function f(bool a, bool b) public pure {\n        bool c;\n        // OK\n        c = !a;\n        c = !b;\n        c = a == b;\n        c = a != b;\n        c = a || b;\n        c = a && b;\n\n        // Not OK\n        c = a > b;\n        c = a < b;\n        c = a >= b;\n        c = a <= b;\n        c = a & b;\n        c = a | b;\n        c = a ^ b;\n        c = ~a;\n        c = ~b;\n        c = a + b;\n        c = a - b;\n        c = -a;\n        c = -b;\n        c = a * b;\n        c = a / b;\n        c = a ** b;\n        c = a % b;\n        c = a << b;\n        c = a >> b;\n    }\n}\n// ----\n// TypeError 2271: (231-236): Built-in binary operator > cannot be applied to types bool and bool.\n// TypeError 2271: (250-255): Built-in binary operator < cannot be applied to types bool and bool.\n// TypeError 2271: (269-275): Built-in binary operator >= cannot be applied to types bool and bool.\n// TypeError 2271: (289-295): Built-in binary operator <= cannot be applied to types bool and bool.\n// TypeError 2271: (309-314): Built-in binary operator & cannot be applied to types bool and bool.\n// TypeError 2271: (328-333): Built-in binary operator | cannot be applied to types bool and bool.\n// TypeError 2271: (347-352): Built-in binary operator ^ cannot be applied to types bool and bool.\n// TypeError 4907: (366-368): Built-in unary operator ~ cannot be applied to type bool.\n// TypeError 4907: (382-384): Built-in unary operator ~ cannot be applied to type bool.\n// TypeError 2271: (398-403): Built-in binary operator + cannot be applied to types bool and bool.\n// TypeError 2271: (417-422): Built-in binary operator - cannot be applied to types bool and bool.\n// TypeError 4907: (436-438): Built-in unary operator - cannot be applied to type bool.\n// TypeError 4907: (452-454): Built-in unary operator - cannot be applied to type bool.\n// TypeError 2271: (468-473): Built-in binary operator * cannot be applied to types bool and bool.\n// TypeError 2271: (487-492): Built-in binary operator / cannot be applied to types bool and bool.\n// TypeError 2271: (506-512): Built-in binary operator ** cannot be applied to types bool and bool.\n// TypeError 2271: (526-531): Built-in binary operator % cannot be applied to types bool and bool.\n// TypeError 2271: (545-551): Built-in binary operator << cannot be applied to types bool and bool.\n// TypeError 2271: (565-571): Built-in binary operator >> cannot be applied to types bool and bool.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/byte.sol",
    "content": "contract C {\n    byte public a;\n}\n// ----\n// ParserError 9182: (17-21): Function, variable, struct or modifier declaration expected.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bytes0.sol",
    "content": "contract C {\n  bytes0 b0 = 1;\n}\n// ----\n// DeclarationError 7920: (15-21): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bytes1_to_uint256.sol",
    "content": "contract C {\n    function f() public pure returns(uint256) {\n        return uint256(bytes1(''));\n    }\n}\n// ----\n// TypeError 9640: (76-95): Explicit type conversion not allowed from \"bytes1\" to \"uint256\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bytes256.sol",
    "content": "contract C {\n  bytes256 b256 = 1;\n}\n// ----\n// DeclarationError 7920: (15-23): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bytes32_to_uint32.sol",
    "content": "contract C {\n    function f() public pure returns(uint32) {\n        return uint32(bytes32(''));\n    }\n}\n// ----\n// TypeError 9640: (75-94): Explicit type conversion not allowed from \"bytes32\" to \"uint32\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bytes33.sol",
    "content": "contract C {\n  bytes33 b33 = 1;\n}\n// ----\n// DeclarationError 7920: (15-22): Identifier not found or not unique.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bytesNN_bitnot.sol",
    "content": "contract C {\n  bytes32 b32 = ~bytes32(hex\"ff\");\n  bytes32 b25 = ~bytes25(hex\"ff\");\n  bytes25 b8 = ~bytes8(hex\"ff\");\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bytesNN_index_assign.sol",
    "content": "contract C {\n    function f() public pure {\n        bytes32 x;\n        x[0] = 0x42;\n    }\n}\n// ----\n// TypeError 4360: (71-75): Single bytes in fixed bytes arrays cannot be modified.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bytesNN_to_contract.sol",
    "content": "contract C {\n        function f() public pure {\n                C(bytes20(uint160(0x1234)));\n        }\n}\n// ----\n// TypeError 9640: (64-91): Explicit type conversion not allowed from \"bytes20\" to \"contract C\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bytesNN_to_uint_same_size.sol",
    "content": "contract C {\n    function f() public pure returns (uint256) {\n        return uint256(bytes32(uint256(0)));\n    }\n    function g() public pure returns (uint128) {\n        return uint128(bytes16(uint128(0)));\n    }\n    function h() public pure returns (uint64) {\n        return uint64(bytes8(uint64(0)));\n    }\n    function i() public pure returns (uint32) {\n        return uint32(bytes4(uint32(0)));\n    }\n    function j() public pure returns (uint16) {\n        return uint16(bytes2(uint16(0)));\n    }\n    function k() public pure returns (uint8) {\n        return uint8(bytes1(uint8(0)));\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bytesNN_upcasting.sol",
    "content": "contract C {\n  bytes1 b1 = bytes1(0x01);\n  bytes2 b2 = b1;\n  bytes3 b3 = b2;\n  bytes4 b4 = b3;\n  bytes5 b5 = b4;\n  bytes6 b6 = b5;\n  bytes7 b7 = b6;\n  bytes8 b8 = b7;\n  bytes9 b9 = b8;\n  bytes10 b10 = b9;\n  bytes11 b11 = b10;\n  bytes12 b12 = b11;\n  bytes13 b13 = b12;\n  bytes14 b14 = b13;\n  bytes15 b15 = b14;\n  bytes16 b16 = b15;\n  bytes17 b17 = b16;\n  bytes18 b18 = b17;\n  bytes19 b19 = b18;\n  bytes20 b20 = b19;\n  bytes21 b21 = b20;\n  bytes22 b22 = b21;\n  bytes23 b23 = b22;\n  bytes24 b24 = b23;\n  bytes25 b25 = b24;\n  bytes26 b26 = b25;\n  bytes27 b27 = b26;\n  bytes28 b28 = b27;\n  bytes29 b29 = b28;\n  bytes30 b30 = b29;\n  bytes31 b31 = b30;\n  bytes32 b32 = b31;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/bytesNN_with_oversized_hex_string.sol",
    "content": "contract C {\n    function f() public pure returns (bytes2) {\n        return bytes2(hex\"123456\");\n    }\n}\n// ----\n// TypeError 9640: (76-95): Explicit type conversion not allowed from \"literal_string hex\"123456\"\" to \"bytes2\". Literal is larger than the type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/call_unimplemented_internal_function.sol",
    "content": "abstract contract A {\n    function f() public virtual;\n    function g() public {\n        f();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/constant_of_invalid_function_type.sol",
    "content": "contract C {\n\t// Used to cause internal compiler error.\n\tfunction() returns (x) constant x = x;\n\n}\n// ----\n// TypeError 5172: (77-78): Name has to refer to a user-defined type.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_base_name_to_var.sol",
    "content": "contract A {\n    function f() external {}\n    function g() external pure {}\n}\n\ncontract B is A {\n    function h() external {\n        function() external f = A.f;\n        function() external pure g = A.g;\n    }\n}\n// ----\n// TypeError 9574: (133-160): Type function A.f() is not implicitly convertible to expected type function () external. Special functions cannot be converted to function types.\n// TypeError 9574: (170-202): Type function A.g() pure is not implicitly convertible to expected type function () pure external. Special functions cannot be converted to function types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/assign_function_via_contract_name_to_var.sol",
    "content": "contract A {\n    function f() external {}\n    function g() external pure {}\n}\n\ncontract B {\n    function h() external {\n        function() external f = A.f;\n        function() external pure g = A.g;\n    }\n}\n// ----\n// TypeError 9574: (128-155): Type function A.f() is not implicitly convertible to expected type function () external. Special functions cannot be converted to function types.\n// TypeError 9574: (165-197): Type function A.g() pure is not implicitly convertible to expected type function () pure external. Special functions cannot be converted to function types.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/base_contract.sol",
    "content": "contract B {\n    function f() external {}\n    function g() public {}\n}\ncontract C is B {\n    function h() public returns (bytes4 fs, bytes4 gs) {\n        fs = B.f.selector;\n        gs = B.g.selector;\n        B.g();\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/base_contract_invalid.sol",
    "content": "contract B {\n    function f() external {}\n    function g() internal {}\n}\ncontract C is B {\n    function i() public {\n        B.f();\n        B.g.selector;\n    }\n}\n// ----\n// TypeError 3419: (125-130): Cannot call function via contract type name.\n// TypeError 9582: (140-152): Member \"selector\" not found or not visible after argument-dependent lookup in function ().\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/call_function_via_contract_name.sol",
    "content": "contract A {\n    function f() external {}\n    function g() external pure {}\n    function h() public pure {}\n}\n\ncontract B {\n    function i() external {\n        A.f();\n        A.g();\n        A.h(); // might be allowed in the future\n    }\n}\n// ----\n// TypeError 3419: (160-165): Cannot call function via contract type name.\n// TypeError 3419: (175-180): Cannot call function via contract type name.\n// TypeError 3419: (190-195): Cannot call function via contract type name.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/call_unimplemented_base.sol",
    "content": "abstract contract B {\n    function f() public virtual;\n}\ncontract C is B {\n    function f() public override {\n        B.f();\n    }\n}\n// ----\n// TypeError 7501: (118-123): Cannot call unimplemented base function.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/function_selector_via_contract_name.sol",
    "content": "contract A {\n    function f() external {}\n}\n\ncontract B {\n    function g() external pure returns(bytes4) {\n        return A.f.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/function_selector_via_interface_name.sol",
    "content": "interface I {\n    function f() external;\n}\n\ncontract B {\n    function g() external pure returns(bytes4) {\n        return I.f.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/function_via_contract_name_internal.sol",
    "content": "contract A {\n    function f() internal {}\n}\n\ncontract B {\n    function g() external {\n        A.f;\n    }\n}\n// ----\n// TypeError 9582: (94-97): Member \"f\" not found or not visible after argument-dependent lookup in type(contract A).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/function_via_contract_name_overloaded.sol",
    "content": "contract A {\n    function f() external {}\n    function f(uint256) external {}\n}\n\ncontract B {\n    function g() external {\n        A.f;\n    }\n}\n// ----\n// TypeError 6675: (130-133): Member \"f\" not unique after argument-dependent lookup in type(contract A).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/function_via_contract_name_private.sol",
    "content": "contract A {\n    function f() private {}\n}\n\ncontract B {\n    function g() external {\n        A.f;\n    }\n}\n// ----\n// TypeError 9582: (93-96): Member \"f\" not found or not visible after argument-dependent lookup in type(contract A).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/function_via_contract_name_public.sol",
    "content": "contract A {\n    function f() public {}\n}\n\ncontract B {\n    function g() external pure returns(bytes4) {\n        return A.f.selector;\n    }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/modifier.sol",
    "content": "contract A {\n    modifier mod() { _; }\n}\ncontract B {\n    function f() public {\n        A.mod;\n    }\n}\n// ----\n// TypeError 9582: (88-93): Member \"mod\" not found or not visible after argument-dependent lookup in type(contract A).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/modifier_base.sol",
    "content": "contract A {\n    modifier mod() { _; }\n}\ncontract B is A {\n    function f() public {\n        A.mod;\n    }\n}\n// ----\n// TypeError 9582: (93-98): Member \"mod\" not found or not visible after argument-dependent lookup in type(contract A).\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contractTypeType/members/struct_enum.sol",
    "content": "contract A {\n    struct S { uint256 a; }\n    enum E { V }\n}\ncontract B {\n    A.S x;\n    A.E e;\n}\ncontract C is A {\n    A.S x;\n    S y;\n    A.E e;\n    E f;\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contract_to_base.sol",
    "content": "contract A {}\ncontract B is A {}\ncontract C {\n  function f() public {\n    A a = new B();\n    a;\n  }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contract_to_derived.sol",
    "content": "contract B {}\ncontract A is B {}\ncontract C {\n  function f() public pure {\n    A a = A(new B());\n  }\n}\n// ----\n// TypeError 9640: (85-95): Explicit type conversion not allowed from \"contract B\" to \"contract A\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/contract_to_unrelated_contract.sol",
    "content": "contract A {}\ncontract B {}\ncontract C {\n  function f() public pure {\n    B b = B(new A());\n  }\n}\n// ----\n// TypeError 9640: (80-90): Explicit type conversion not allowed from \"contract A\" to \"contract B\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/cyclic_dependency_check_on_consts_exhausted.sol",
    "content": "contract A {}\ncontract Main {\n    A constant B = C;\n    A constant C = D;\n    A constant D = E;\n    A constant E = F;\n    A constant F = G;\n    A constant G = H;\n    A constant H = I;\n    A constant I = J;\n    A constant J = K;\n    A constant K = L;\n    A constant L = M;\n    A constant M = N;\n    A constant N = O;\n    A constant O = P;\n    A constant P = Q;\n    A constant Q = R;\n    A constant R = S;\n    A constant S = T;\n    A constant T = U;\n    A constant U = V;\n    A constant V = W;\n    A constant W = X;\n    A constant X = Y;\n    A constant Y = Z;\n    A constant Z = BA;\n    A constant BA = BB;\n    A constant BB = BC;\n    A constant BC = BD;\n    A constant BD = BE;\n    A constant BE = BF;\n    A constant BF = BG;\n    A constant BG = BH;\n    A constant BH = BI;\n    A constant BI = BJ;\n    A constant BJ = BK;\n    A constant BK = BL;\n    A constant BL = BM;\n    A constant BM = BN;\n    A constant BN = BO;\n    A constant BO = BP;\n    A constant BP = BQ;\n    A constant BQ = BR;\n    A constant BR = BS;\n    A constant BS = BT;\n    A constant BT = BU;\n    A constant BU = BV;\n    A constant BV = BW;\n    A constant BW = BX;\n    A constant BX = BY;\n    A constant BY = BZ;\n    A constant BZ = CA;\n    A constant CA = CB;\n    A constant CB = CC;\n    A constant CC = CD;\n    A constant CD = CE;\n    A constant CE = CF;\n    A constant CF = CG;\n    A constant CG = CH;\n    A constant CH = CI;\n    A constant CI = CJ;\n    A constant CJ = CK;\n    A constant CK = CL;\n    A constant CL = CM;\n    A constant CM = CN;\n    A constant CN = CO;\n    A constant CO = CP;\n    A constant CP = CQ;\n    A constant CQ = CR;\n    A constant CR = CS;\n    A constant CS = CT;\n    A constant CT = CU;\n    A constant CU = CV;\n    A constant CV = CW;\n    A constant CW = CX;\n    A constant CX = CY;\n    A constant CY = CZ;\n    A constant CZ = DA;\n    A constant DA = DB;\n    A constant DB = DC;\n    A constant DC = DD;\n    A constant DD = DE;\n    A constant DE = DF;\n    A constant DF = DG;\n    A constant DG = DH;\n    A constant DH = DI;\n    A constant DI = DJ;\n    A constant DJ = DK;\n    A constant DK = DL;\n    A constant DL = DM;\n    A constant DM = DN;\n    A constant DN = DO;\n    A constant DO = DP;\n    A constant DP = DQ;\n    A constant DQ = DR;\n    A constant DR = DS;\n    A constant DS = DT;\n    A constant DT = DU;\n    A constant DU = DV;\n    A constant DV = DW;\n    A constant DW = DX;\n    A constant DX = DY;\n    A constant DY = DZ;\n    A constant DZ = EA;\n    A constant EA = EB;\n    A constant EB = EC;\n    A constant EC = ED;\n    A constant ED = EE;\n    A constant EE = EF;\n    A constant EF = EG;\n    A constant EG = EH;\n    A constant EH = EI;\n    A constant EI = EJ;\n    A constant EJ = EK;\n    A constant EK = EL;\n    A constant EL = EM;\n    A constant EM = EN;\n    A constant EN = EO;\n    A constant EO = EP;\n    A constant EP = EQ;\n    A constant EQ = ER;\n    A constant ER = ES;\n    A constant ES = ET;\n    A constant ET = EU;\n    A constant EU = EV;\n    A constant EV = EW;\n    A constant EW = EX;\n    A constant EX = EY;\n    A constant EY = EZ;\n    A constant EZ = FA;\n    A constant FA = FB;\n    A constant FB = FC;\n    A constant FC = FD;\n    A constant FD = FE;\n    A constant FE = FF;\n    A constant FF = FG;\n    A constant FG = FH;\n    A constant FH = FI;\n    A constant FI = FJ;\n    A constant FJ = FK;\n    A constant FK = FL;\n    A constant FL = FM;\n    A constant FM = FN;\n    A constant FN = FO;\n    A constant FO = FP;\n    A constant FP = FQ;\n    A constant FQ = FR;\n    A constant FR = FS;\n    A constant FS = FT;\n    A constant FT = FU;\n    A constant FU = FV;\n    A constant FV = FW;\n    A constant FW = FX;\n    A constant FX = FY;\n    A constant FY = FZ;\n    A constant FZ = GA;\n    A constant GA = GB;\n    A constant GB = GC;\n    A constant GC = GD;\n    A constant GD = GE;\n    A constant GE = GF;\n    A constant GF = GG;\n    A constant GG = GH;\n    A constant GH = GI;\n    A constant GI = GJ;\n    A constant GJ = GK;\n    A constant GK = GL;\n    A constant GL = GM;\n    A constant GM = GN;\n    A constant GN = GO;\n    A constant GO = GP;\n    A constant GP = GQ;\n    A constant GQ = GR;\n    A constant GR = GS;\n    A constant GS = GT;\n    A constant GT = GU;\n    A constant GU = GV;\n    A constant GV = GW;\n    A constant GW = GX;\n    A constant GX = GY;\n    A constant GY = GZ;\n    A constant GZ = HA;\n    A constant HA = HB;\n    A constant HB = HC;\n    A constant HC = HD;\n    A constant HD = HE;\n    A constant HE = HF;\n    A constant HF = HG;\n    A constant HG = HH;\n    A constant HH = HI;\n    A constant HI = HJ;\n    A constant HJ = HK;\n    A constant HK = HL;\n    A constant HL = HM;\n    A constant HM = HN;\n    A constant HN = HO;\n    A constant HO = HP;\n    A constant HP = HQ;\n    A constant HQ = HR;\n    A constant HR = HS;\n    A constant HS = HT;\n    A constant HT = HU;\n    A constant HU = HV;\n    A constant HV = HW;\n    A constant HW = HX;\n    A constant HX = HY;\n    A constant HY = HZ;\n    A constant HZ = IA;\n    A constant IA = IB;\n    A constant IB = IC;\n    A constant IC = ID;\n    A constant ID = IE;\n    A constant IE = IF;\n    A constant IF = IG;\n    A constant IG = IH;\n    A constant IH = II;\n    A constant II = IJ;\n    A constant IJ = IK;\n    A constant IK = IL;\n    A constant IL = IM;\n    A constant IM = IN;\n    A constant IN = IO;\n    A constant IO = IP;\n    A constant IP = IQ;\n    A constant IQ = IR;\n    A constant IR = IS;\n    A constant IS = IT;\n    A constant IT = IU;\n    A constant IU = IV;\n    A constant IV = IW;\n    A constant IW = IX;\n    A constant IX = IY;\n    A constant IY = IZ;\n    A constant IZ = JA;\n    A constant JA = JB;\n    A constant JB = JC;\n    A constant JC = JD;\n    A constant JD = JE;\n    A constant JE = JF;\n    A constant JF = JG;\n    A constant JG = JH;\n    A constant JH = JI;\n    A constant JI = JJ;\n    A constant JJ = JK;\n    A constant JK = JL;\n    A constant JL = JM;\n    A constant JM = JN;\n    A constant JN = JO;\n    A constant JO = JP;\n    A constant JP = JQ;\n    A constant JQ = JR;\n    A constant JR = JS;\n    A constant JS = JT;\n    A constant JT = JU;\n    A constant JU = JV;\n    A constant JV = JW;\n    A constant JW = JX;\n    A constant JX = A(address(0x00));\n}\n// ----\n// DeclarationError 7380: (6105-6123): Variable definition exhausting cyclic dependency validator.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/cyclic_dependency_check_on_struct_exhausted.sol",
    "content": "contract Main {\n    struct B { C m; }\n    struct C { D m; }\n    struct D { E m; }\n    struct E { F m; }\n    struct F { G m; }\n    struct G { H m; }\n    struct H { I m; }\n    struct I { J m; }\n    struct J { K m; }\n    struct K { L m; }\n    struct L { M m; }\n    struct M { N m; }\n    struct N { O m; }\n    struct O { P m; }\n    struct P { Q m; }\n    struct Q { R m; }\n    struct R { S m; }\n    struct S { T m; }\n    struct T { U m; }\n    struct U { V m; }\n    struct V { W m; }\n    struct W { X m; }\n    struct X { Y m; }\n    struct Y { Z m; }\n    struct Z { BA m; }\n    struct BA { BB m; }\n    struct BB { BC m; }\n    struct BC { BD m; }\n    struct BD { BE m; }\n    struct BE { BF m; }\n    struct BF { BG m; }\n    struct BG { BH m; }\n    struct BH { BI m; }\n    struct BI { BJ m; }\n    struct BJ { BK m; }\n    struct BK { BL m; }\n    struct BL { BM m; }\n    struct BM { BN m; }\n    struct BN { BO m; }\n    struct BO { BP m; }\n    struct BP { BQ m; }\n    struct BQ { BR m; }\n    struct BR { BS m; }\n    struct BS { BT m; }\n    struct BT { BU m; }\n    struct BU { BV m; }\n    struct BV { BW m; }\n    struct BW { BX m; }\n    struct BX { BY m; }\n    struct BY { BZ m; }\n    struct BZ { CA m; }\n    struct CA { CB m; }\n    struct CB { CC m; }\n    struct CC { CD m; }\n    struct CD { CE m; }\n    struct CE { CF m; }\n    struct CF { CG m; }\n    struct CG { CH m; }\n    struct CH { CI m; }\n    struct CI { CJ m; }\n    struct CJ { CK m; }\n    struct CK { CL m; }\n    struct CL { CM m; }\n    struct CM { CN m; }\n    struct CN { CO m; }\n    struct CO { CP m; }\n    struct CP { CQ m; }\n    struct CQ { CR m; }\n    struct CR { CS m; }\n    struct CS { CT m; }\n    struct CT { CU m; }\n    struct CU { CV m; }\n    struct CV { CW m; }\n    struct CW { CX m; }\n    struct CX { CY m; }\n    struct CY { CZ m; }\n    struct CZ { DA m; }\n    struct DA { DB m; }\n    struct DB { DC m; }\n    struct DC { DD m; }\n    struct DD { DE m; }\n    struct DE { DF m; }\n    struct DF { DG m; }\n    struct DG { DH m; }\n    struct DH { DI m; }\n    struct DI { DJ m; }\n    struct DJ { DK m; }\n    struct DK { DL m; }\n    struct DL { DM m; }\n    struct DM { DN m; }\n    struct DN { DO m; }\n    struct DO { DP m; }\n    struct DP { DQ m; }\n    struct DQ { DR m; }\n    struct DR { DS m; }\n    struct DS { DT m; }\n    struct DT { DU m; }\n    struct DU { DV m; }\n    struct DV { DW m; }\n    struct DW { DX m; }\n    struct DX { DY m; }\n    struct DY { DZ m; }\n    struct DZ { EA m; }\n    struct EA { EB m; }\n    struct EB { EC m; }\n    struct EC { ED m; }\n    struct ED { EE m; }\n    struct EE { EF m; }\n    struct EF { EG m; }\n    struct EG { EH m; }\n    struct EH { EI m; }\n    struct EI { EJ m; }\n    struct EJ { EK m; }\n    struct EK { EL m; }\n    struct EL { EM m; }\n    struct EM { EN m; }\n    struct EN { EO m; }\n    struct EO { EP m; }\n    struct EP { EQ m; }\n    struct EQ { ER m; }\n    struct ER { ES m; }\n    struct ES { ET m; }\n    struct ET { EU m; }\n    struct EU { EV m; }\n    struct EV { EW m; }\n    struct EW { EX m; }\n    struct EX { EY m; }\n    struct EY { EZ m; }\n    struct EZ { FA m; }\n    struct FA { FB m; }\n    struct FB { FC m; }\n    struct FC { FD m; }\n    struct FD { FE m; }\n    struct FE { FF m; }\n    struct FF { FG m; }\n    struct FG { FH m; }\n    struct FH { FI m; }\n    struct FI { FJ m; }\n    struct FJ { FK m; }\n    struct FK { FL m; }\n    struct FL { FM m; }\n    struct FM { FN m; }\n    struct FN { FO m; }\n    struct FO { FP m; }\n    struct FP { FQ m; }\n    struct FQ { FR m; }\n    struct FR { FS m; }\n    struct FS { FT m; }\n    struct FT { FU m; }\n    struct FU { FV m; }\n    struct FV { FW m; }\n    struct FW { FX m; }\n    struct FX { FY m; }\n    struct FY { FZ m; }\n    struct FZ { GA m; }\n    struct GA { GB m; }\n    struct GB { GC m; }\n    struct GC { GD m; }\n    struct GD { GE m; }\n    struct GE { GF m; }\n    struct GF { GG m; }\n    struct GG { GH m; }\n    struct GH { GI m; }\n    struct GI { GJ m; }\n    struct GJ { GK m; }\n    struct GK { GL m; }\n    struct GL { GM m; }\n    struct GM { GN m; }\n    struct GN { GO m; }\n    struct GO { GP m; }\n    struct GP { GQ m; }\n    struct GQ { GR m; }\n    struct GR { GS m; }\n    struct GS { GT m; }\n    struct GT { GU m; }\n    struct GU { GV m; }\n    struct GV { GW m; }\n    struct GW { GX m; }\n    struct GX { GY m; }\n    struct GY { GZ m; }\n    struct GZ { HA m; }\n    struct HA { HB m; }\n    struct HB { HC m; }\n    struct HC { HD m; }\n    struct HD { HE m; }\n    struct HE { HF m; }\n    struct HF { HG m; }\n    struct HG { HH m; }\n    struct HH { HI m; }\n    struct HI { HJ m; }\n    struct HJ { HK m; }\n    struct HK { HL m; }\n    struct HL { HM m; }\n    struct HM { HN m; }\n    struct HN { HO m; }\n    struct HO { HP m; }\n    struct HP { HQ m; }\n    struct HQ { HR m; }\n    struct HR { HS m; }\n    struct HS { HT m; }\n    struct HT { HU m; }\n    struct HU { HV m; }\n    struct HV { HW m; }\n    struct HW { HX m; }\n    struct HX { HY m; }\n    struct HY { HZ m; }\n    struct HZ { IA m; }\n    struct IA { IB m; }\n    struct IB { IC m; }\n    struct IC { ID m; }\n    struct ID { IE m; }\n    struct IE { IF m; }\n    struct IF { IG m; }\n    struct IG { IH m; }\n    struct IH { II m; }\n    struct II { IJ m; }\n    struct IJ { IK m; }\n    struct IK { IL m; }\n    struct IL { IM m; }\n    struct IM { IN m; }\n    struct IN { IO m; }\n    struct IO { IP m; }\n    struct IP { IQ m; }\n    struct IQ { IR m; }\n    struct IR { IS m; }\n    struct IS { IT m; }\n    struct IT { IU m; }\n    struct IU { IV m; }\n    struct IV { IW m; }\n    struct IW { IX m; }\n    struct IX { IY m; }\n    struct IY { IZ m; }\n    struct IZ { JA m; }\n    struct JA { JB m; }\n    struct JB { JC m; }\n    struct JC { JD m; }\n    struct JD { JE m; }\n    struct JE { JF m; }\n    struct JF { JG m; }\n    struct JG { JH m; }\n    struct JH { JI m; }\n    struct JI { JJ m; }\n    struct JJ { JK m; }\n    struct JK { JL m; }\n    struct JL { JM m; }\n    struct JM { JN m; }\n    struct JN { JO m; }\n    struct JO { JP m; }\n    struct JP { JQ m; }\n    struct JQ { JR m; }\n    struct JR { JS m; }\n    struct JS { JT m; }\n    struct JT { JU m; }\n    struct JU { JV m; }\n    struct JV { JW m; }\n    struct JW { int i; }\n}\n// ----\n// DeclarationError 5651: (6091-6111): Struct definition exhausts cyclic dependency validator.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/cyclic_dependency_check_on_struct_good.sol",
    "content": "contract Main {\n    struct B { C m; }\n    struct C { D m; }\n    struct D { E m; }\n    struct E { F m; }\n    struct F { G m; }\n    struct G { H m; }\n    struct H { I m; }\n    struct I { J m; }\n    struct J { K m; }\n    struct K { L m; }\n    struct L { M m; }\n    struct M { N m; }\n    struct N { O m; }\n    struct O { P m; }\n    struct P { Q m; }\n    struct Q { R m; }\n    struct R { S m; }\n    struct S { T m; }\n    struct T { U m; }\n    struct U { V m; }\n    struct V { W m; }\n    struct W { X m; }\n    struct X { Y m; }\n    struct Y { Z m; }\n    struct Z { BA m; }\n    struct BA { BB m; }\n    struct BB { BC m; }\n    struct BC { BD m; }\n    struct BD { BE m; }\n    struct BE { BF m; }\n    struct BF { BG m; }\n    struct BG { BH m; }\n    struct BH { BI m; }\n    struct BI { BJ m; }\n    struct BJ { BK m; }\n    struct BK { BL m; }\n    struct BL { BM m; }\n    struct BM { BN m; }\n    struct BN { BO m; }\n    struct BO { BP m; }\n    struct BP { BQ m; }\n    struct BQ { BR m; }\n    struct BR { BS m; }\n    struct BS { BT m; }\n    struct BT { BU m; }\n    struct BU { BV m; }\n    struct BV { BW m; }\n    struct BW { BX m; }\n    struct BX { BY m; }\n    struct BY { BZ m; }\n    struct BZ { CA m; }\n    struct CA { CB m; }\n    struct CB { CC m; }\n    struct CC { CD m; }\n    struct CD { CE m; }\n    struct CE { CF m; }\n    struct CF { CG m; }\n    struct CG { CH m; }\n    struct CH { CI m; }\n    struct CI { CJ m; }\n    struct CJ { CK m; }\n    struct CK { CL m; }\n    struct CL { CM m; }\n    struct CM { CN m; }\n    struct CN { CO m; }\n    struct CO { CP m; }\n    struct CP { CQ m; }\n    struct CQ { CR m; }\n    struct CR { CS m; }\n    struct CS { CT m; }\n    struct CT { CU m; }\n    struct CU { CV m; }\n    struct CV { CW m; }\n    struct CW { CX m; }\n    struct CX { CY m; }\n    struct CY { CZ m; }\n    struct CZ { DA m; }\n    struct DA { DB m; }\n    struct DB { DC m; }\n    struct DC { DD m; }\n    struct DD { DE m; }\n    struct DE { DF m; }\n    struct DF { DG m; }\n    struct DG { DH m; }\n    struct DH { DI m; }\n    struct DI { DJ m; }\n    struct DJ { DK m; }\n    struct DK { DL m; }\n    struct DL { DM m; }\n    struct DM { DN m; }\n    struct DN { DO m; }\n    struct DO { DP m; }\n    struct DP { DQ m; }\n    struct DQ { DR m; }\n    struct DR { DS m; }\n    struct DS { DT m; }\n    struct DT { DU m; }\n    struct DU { DV m; }\n    struct DV { DW m; }\n    struct DW { DX m; }\n    struct DX { DY m; }\n    struct DY { DZ m; }\n    struct DZ { EA m; }\n    struct EA { EB m; }\n    struct EB { EC m; }\n    struct EC { ED m; }\n    struct ED { EE m; }\n    struct EE { EF m; }\n    struct EF { EG m; }\n    struct EG { EH m; }\n    struct EH { EI m; }\n    struct EI { EJ m; }\n    struct EJ { EK m; }\n    struct EK { EL m; }\n    struct EL { EM m; }\n    struct EM { EN m; }\n    struct EN { EO m; }\n    struct EO { EP m; }\n    struct EP { EQ m; }\n    struct EQ { ER m; }\n    struct ER { ES m; }\n    struct ES { ET m; }\n    struct ET { EU m; }\n    struct EU { EV m; }\n    struct EV { EW m; }\n    struct EW { EX m; }\n    struct EX { EY m; }\n    struct EY { EZ m; }\n    struct EZ { FA m; }\n    struct FA { FB m; }\n    struct FB { FC m; }\n    struct FC { int i; }\n}\n// ----\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/decimal_literal_to_bytesNN_explicit.sol",
    "content": "contract C {\n   function f() public pure {\n     bytes1 b1 = bytes1(1);\n     bytes2 b2 = bytes2(1);\n     bytes2 b3 = bytes2(256);\n     bytes3 b4 = bytes3(1);\n     bytes3 b5 = bytes3(65536);\n     bytes4 b6 = bytes4(1);\n     bytes4 b7 = bytes4(16777216);\n     bytes16 b8 = bytes16(1);\n     bytes32 b9 = bytes32(1);\n   }\n}\n// ----\n// TypeError 9640: (60-69): Explicit type conversion not allowed from \"int_const 1\" to \"bytes1\".\n// TypeError 9640: (88-97): Explicit type conversion not allowed from \"int_const 1\" to \"bytes2\".\n// TypeError 9640: (116-127): Explicit type conversion not allowed from \"int_const 256\" to \"bytes2\".\n// TypeError 9640: (146-155): Explicit type conversion not allowed from \"int_const 1\" to \"bytes3\".\n// TypeError 9640: (174-187): Explicit type conversion not allowed from \"int_const 65536\" to \"bytes3\".\n// TypeError 9640: (206-215): Explicit type conversion not allowed from \"int_const 1\" to \"bytes4\".\n// TypeError 9640: (234-250): Explicit type conversion not allowed from \"int_const 16777216\" to \"bytes4\".\n// TypeError 9640: (270-280): Explicit type conversion not allowed from \"int_const 1\" to \"bytes16\".\n// TypeError 9640: (300-310): Explicit type conversion not allowed from \"int_const 1\" to \"bytes32\".\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/empty_tuple_event.sol",
    "content": "contract C {\n    event SomeEvent();\n    function a() public {\n        (emit SomeEvent(), 7);\n    }\n}\n// ----\n// ParserError 6933: (71-75): Expected primary expression.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/empty_tuple_function.sol",
    "content": "contract C {\n    function f() private pure {}\n    function a() public pure {\n        bool x = true;\n        bool y = true;\n        (x) ? (f(), y = false) : (f(), y = false);\n    }\n}\n// ----\n// TypeError 6473: (138-141): Tuple component cannot be empty.\n// TypeError 6473: (157-160): Tuple component cannot be empty.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/empty_tuple_lvalue_array.sol",
    "content": "contract C {\n    function f() private pure {}\n    function a() public {\n        uint x;\n        uint y;\n        (x, y) = [f(), f()];\n    }\n}\n// ----\n// TypeError 5604: (122-125): Array component cannot be empty.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/encoding_fractional.sol",
    "content": "contract C {\n   function f1() public pure returns (bytes memory) {\n       return abi.encode(0.1, 1);\n   }\n}\n// ----\n// TypeError 6090: (92-95): Fractional numbers cannot yet be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/encoding_fractional_abiencoderv2.sol",
    "content": "pragma abicoder               v2;\ncontract C {\n   function f1() public pure returns (bytes memory) {\n       return abi.encode(0.1, 1);\n   }\n}\n// ----\n// TypeError 6090: (126-129): Fractional numbers cannot yet be encoded.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/functionTypes/function_definition_expression.sol",
    "content": "interface Banana {\n    function transfer(address,uint256) external returns(bool);\n}\n\ncontract Apple {\n    function f() public pure {\n        Banana.transfer;\n    }\n}\n// ----\n// Warning 6133: (141-156): Statement has no effect.\n"
  },
  {
    "path": "test/libsolidity/syntaxTests/types/functionTypes/function_parameter_return_types_fail.sol",
    "content": "abstract contract Test\n{\n    function uint256_to_uint256(uint256 x) internal pure returns (uint256) { return x; }\n    function uint256_to_string(uint256 x) internal pure returns (string memory) { return x == 0 ? \"a\" : \"b\"; }\n    function uint256_to_string_storage(uint256) internal pure returns (string storage) {}\n    function string_to_uint256(string memory x) internal pure returns (uint256) { return bytes(x).length; }\n    function string_to_string(string memory x) internal pure returns (string memory) { return x; }\n\n    function uint256_uint256_to_uint256(uint256 x, uint256 y) internal pure returns (uint256) { return x + y; }\n    function uint256_uint256_to_string(uint256 x, uint256 y) internal pure returns (string memory) { return x == y ? \"a\" : \"b\"; }\n    function string_uint256_to_string(string memory x, uint256 y) internal pure returns (string memory) { return y == 0 ? \"a\" : x; }\n    function string_string_to_string(string memory x, string memory y) internal pure returns (string memory) { return bytes(x).length == 0 ? y : x; }\n    function uint256_string_to_string(uint256 x, string memory y) internal pure returns (string memory) { return x == 0 ? \"a\" : y; }\n\n    function tests() internal pure\n    {\n      function (uint256) internal pure returns (uint256) var_uint256_to_uint256 = uint256_to_string;\n      function (uint256) internal pure returns (string memory) var_uint256_to_string = uint256_to_string_storage;\n      function (string memory) internal pure returns (uint256) var_string_to_uint256 = uint256_to_string;\n      function (string memory) internal pure returns (string memory) var_string_to_string = var_uint256_to_string;\n\n      function (uint256, uint256) internal pure returns (uint256) var_uint256_uint256_to_uint256 = uint256_to_uint256;\n      function (string memory, uint256) internal pure returns (string memory) var_string_uint256_to_string = string_to_string;\n      function (string memory, string memory) internal pure returns (string memory) var_string_string_to_string = string_to_string;\n\n      var_uint256_to_uint256(1);\n      var_uint256_to_string(2);\n      var_string_to_uint256(\"a\");\n      var_string_to_string(\"b\");\n      var_uint256_uint256_to_uint256(3, 4);\n      var_string_uint256_to_string(\"c\", 7);\n      var_string_string_to_string(\"d\", \"e\");\n    }\n}\n// ----\n// TypeError 9574: (1229-1322): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (uint256) pure returns (uint256).\n// TypeError 9574: (1330-1436): Type function (uint256) pure returns (string storage pointer) is not implicitly convertible to expected type function (uint256) pure returns (string memory).\n// TypeError 9574: (1444-1542): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (string memory) pure returns (uint256).\n// TypeError 9574: (1550-1657): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (string memory) pure returns (string memory).\n// TypeError 9574: (1666-1777): Type function (uint256) pure returns (uint256) is not implicitly convertible to expected type function (uint256,uint256) pure returns (uint256).\n// TypeError 9574: (1785-1904): Type function (string memory) pure returns (string memory) is not implicitly convertible to expected type function (string memory,uint256) pure returns (string memory).\n// TypeError 9574: (1912-2036): Type function (string memory) pure returns (string memory) is not implicitly convertible to expected type function (string memory,string memory) pure returns (string memory).\n"
  }
]